From d3198a6f2e520dd7100184a03327ab08e3b38b68 Mon Sep 17 00:00:00 2001 From: frank zhu Date: Mon, 29 Jul 2024 22:05:09 +0200 Subject: [PATCH 001/432] chore: update dependabot config yaml (#13949) --- .github/dependabot.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index cdb1d4fe2f..19e008c8ce 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,7 +1,7 @@ version: 2 updates: - package-ecosystem: gomod - directory: '/' + directory: "/" schedule: interval: monthly open-pull-requests-limit: 10 @@ -11,7 +11,7 @@ updates: - dependency-name: github.com/libp2p/go-libp2p-peerstore - dependency-name: github.com/multiformats/go-multiaddr - package-ecosystem: npm - directory: '/' + directory: "/" schedule: interval: monthly open-pull-requests-limit: 0 @@ -24,7 +24,7 @@ updates: versions: - 4.17.21 - package-ecosystem: github-actions - directory: '/' + directory: "/" schedule: - interval: daily - open-pull-requests-limit: 10 + interval: monthly + open-pull-requests-limit: 0 From bf30e1d3a0eedabd7fb900bcd321b020bc252fb8 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:51:04 +0200 Subject: [PATCH 002/432] Refactor jira update script to use typescript (#13860) * Refactor jira update script to use typescript * Make use of TS 5.5 inferred type predicate * Add tests * Add dryrun capability * Add more logging * Address comments --- .github/scripts/jira/package.json | 11 +- .github/scripts/jira/pnpm-lock.yaml | 1060 ++++++++++++++++- .github/scripts/jira/tsconfig.json | 108 ++ .github/scripts/jira/update-jira-issue.js | 118 -- .../scripts/jira/update-jira-issue.test.ts | 36 + .github/scripts/jira/update-jira-issue.ts | 134 +++ .github/workflows/changeset.yml | 2 +- 7 files changed, 1328 insertions(+), 141 deletions(-) create mode 100644 .github/scripts/jira/tsconfig.json delete mode 100644 .github/scripts/jira/update-jira-issue.js create mode 100644 .github/scripts/jira/update-jira-issue.test.ts create mode 100644 .github/scripts/jira/update-jira-issue.ts diff --git a/.github/scripts/jira/package.json b/.github/scripts/jira/package.json index 2c57d35a64..9902b489ea 100644 --- a/.github/scripts/jira/package.json +++ b/.github/scripts/jira/package.json @@ -12,8 +12,17 @@ "node": ">=18", "pnpm": ">=9" }, + "scripts": { + "start": "tsx update-jira-issue.ts" + }, "dependencies": { "@actions/core": "^1.10.1", - "node-fetch": "^2.7.0" + "jira.js": "^4.0.1", + "tsx": "^4.16.2" + }, + "devDependencies": { + "@types/node": "^20.14.10", + "typescript": "^5.5.3", + "vitest": "^2.0.3" } } diff --git a/.github/scripts/jira/pnpm-lock.yaml b/.github/scripts/jira/pnpm-lock.yaml index 09ba8c749c..4deeef7f33 100644 --- a/.github/scripts/jira/pnpm-lock.yaml +++ b/.github/scripts/jira/pnpm-lock.yaml @@ -11,9 +11,22 @@ importers: '@actions/core': specifier: ^1.10.1 version: 1.10.1 - node-fetch: - specifier: ^2.7.0 - version: 2.7.0 + jira.js: + specifier: ^4.0.1 + version: 4.0.1 + tsx: + specifier: ^4.16.2 + version: 4.16.2 + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.14.10 + typescript: + specifier: ^5.5.3 + version: 5.5.3 + vitest: + specifier: ^2.0.3 + version: 2.0.3(@types/node@20.14.10) packages: @@ -23,26 +36,509 @@ packages: '@actions/http-client@2.2.1': resolution: {integrity: sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw==} + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@fastify/busboy@2.1.1': resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} engines: {node: '>=14'} - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@rollup/rollup-android-arm-eabi@4.18.1': + resolution: {integrity: sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.18.1': + resolution: {integrity: sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.18.1': + resolution: {integrity: sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.18.1': + resolution: {integrity: sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.18.1': + resolution: {integrity: sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.18.1': + resolution: {integrity: sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.18.1': + resolution: {integrity: sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.18.1': + resolution: {integrity: sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': + resolution: {integrity: sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.18.1': + resolution: {integrity: sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.18.1': + resolution: {integrity: sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.18.1': + resolution: {integrity: sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.18.1': + resolution: {integrity: sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.18.1': + resolution: {integrity: sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.18.1': + resolution: {integrity: sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.18.1': + resolution: {integrity: sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==} + cpu: [x64] + os: [win32] + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/node@20.14.10': + resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} + + '@vitest/expect@2.0.3': + resolution: {integrity: sha512-X6AepoOYePM0lDNUPsGXTxgXZAl3EXd0GYe/MZyVE4HzkUqyUVC6S3PrY5mClDJ6/7/7vALLMV3+xD/Ko60Hqg==} + + '@vitest/pretty-format@2.0.3': + resolution: {integrity: sha512-URM4GLsB2xD37nnTyvf6kfObFafxmycCL8un3OC9gaCs5cti2u+5rJdIflZ2fUJUen4NbvF6jCufwViAFLvz1g==} + + '@vitest/runner@2.0.3': + resolution: {integrity: sha512-EmSP4mcjYhAcuBWwqgpjR3FYVeiA4ROzRunqKltWjBfLNs1tnMLtF+qtgd5ClTwkDP6/DGlKJTNa6WxNK0bNYQ==} + + '@vitest/snapshot@2.0.3': + resolution: {integrity: sha512-6OyA6v65Oe3tTzoSuRPcU6kh9m+mPL1vQ2jDlPdn9IQoUxl8rXhBnfICNOC+vwxWY684Vt5UPgtcA2aPFBb6wg==} + + '@vitest/spy@2.0.3': + resolution: {integrity: sha512-sfqyAw/ypOXlaj4S+w8689qKM1OyPOqnonqOc9T91DsoHbfN5mU7FdifWWv3MtQFf0lEUstEwR9L/q/M390C+A==} + + '@vitest/utils@2.0.3': + resolution: {integrity: sha512-c/UdELMuHitQbbc/EVctlBaxoYAwQPQdSNwv7z/vHyBKy2edYZaFgptE27BRueZB7eW8po+cllotMNTDpL3HWg==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.7.2: + resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + chai@5.1.1: + resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} + engines: {node: '>=12'} + + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} peerDependencies: - encoding: ^0.1.0 + debug: '*' peerDependenciesMeta: - encoding: + debug: optional: true - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-tsconfig@4.7.5: + resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jira.js@4.0.1: + resolution: {integrity: sha512-2zf8LozW9rgx5wgTdGSJMhUXDK1g8a/ngm1xDWnREX/h8kuBhNkMro4XELA2XRVvaNTbRMIK3PBgOvWFDddhIw==} + + loupe@3.1.1: + resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + postcss@8.4.39: + resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==} + engines: {node: ^10 || ^12 || >=14} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + rollup@4.18.1: + resolution: {integrity: sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + tinybench@2.8.0: + resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} + + tinypool@1.0.0: + resolution: {integrity: sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.0: + resolution: {integrity: sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==} + engines: {node: '>=14.0.0'} + + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + + tsx@4.16.2: + resolution: {integrity: sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==} + engines: {node: '>=18.0.0'} + hasBin: true tunnel@0.0.6: resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + typescript@5.5.3: + resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici@5.28.4: resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} engines: {node: '>=14.0'} @@ -51,11 +547,73 @@ packages: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + vite-node@2.0.3: + resolution: {integrity: sha512-14jzwMx7XTcMB+9BhGQyoEAmSl0eOr3nrnn+Z12WNERtOvLN+d2scbRUvyni05rT3997Bg+rZb47NyP4IQPKXg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.3.3: + resolution: {integrity: sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.0.3: + resolution: {integrity: sha512-o3HRvU93q6qZK4rI2JrhKyZMMuxg/JRt30E6qeQs6ueaiz5hr1cPj+Sk2kATgQzMMqsa2DiNI0TIK++1ULx8Jw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.0.3 + '@vitest/ui': 2.0.3 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true snapshots: @@ -69,25 +627,485 @@ snapshots: tunnel: 0.0.6 undici: 5.28.4 + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + '@fastify/busboy@2.1.1': {} - node-fetch@2.7.0: + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@rollup/rollup-android-arm-eabi@4.18.1': + optional: true + + '@rollup/rollup-android-arm64@4.18.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.18.1': + optional: true + + '@rollup/rollup-darwin-x64@4.18.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.18.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.18.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.18.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.18.1': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.18.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.18.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.18.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.18.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.18.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.18.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.18.1': + optional: true + + '@types/estree@1.0.5': {} + + '@types/node@20.14.10': + dependencies: + undici-types: 5.26.5 + + '@vitest/expect@2.0.3': + dependencies: + '@vitest/spy': 2.0.3 + '@vitest/utils': 2.0.3 + chai: 5.1.1 + tinyrainbow: 1.2.0 + + '@vitest/pretty-format@2.0.3': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.0.3': + dependencies: + '@vitest/utils': 2.0.3 + pathe: 1.1.2 + + '@vitest/snapshot@2.0.3': + dependencies: + '@vitest/pretty-format': 2.0.3 + magic-string: 0.30.10 + pathe: 1.1.2 + + '@vitest/spy@2.0.3': + dependencies: + tinyspy: 3.0.0 + + '@vitest/utils@2.0.3': + dependencies: + '@vitest/pretty-format': 2.0.3 + estree-walker: 3.0.3 + loupe: 3.1.1 + tinyrainbow: 1.2.0 + + assertion-error@2.0.1: {} + + asynckit@0.4.0: {} + + axios@1.7.2: + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + cac@6.7.14: {} + + chai@5.1.1: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.1 + pathval: 2.0.0 + + check-error@2.1.1: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + cross-spawn@7.0.3: dependencies: - whatwg-url: 5.0.0 + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 - tr46@0.0.3: {} + debug@4.3.5: + dependencies: + ms: 2.1.2 + + deep-eql@5.0.2: {} + + delayed-stream@1.0.0: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + follow-redirects@1.15.6: {} + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fsevents@2.3.3: + optional: true + + get-func-name@2.0.2: {} + + get-stream@8.0.1: {} + + get-tsconfig@4.7.5: + dependencies: + resolve-pkg-maps: 1.0.0 + + human-signals@5.0.0: {} + + is-stream@3.0.0: {} + + isexe@2.0.0: {} + + jira.js@4.0.1: + dependencies: + axios: 1.7.2 + form-data: 4.0.0 + tslib: 2.6.3 + transitivePeerDependencies: + - debug + + loupe@3.1.1: + dependencies: + get-func-name: 2.0.2 + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + merge-stream@2.0.0: {} + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@4.0.0: {} + + ms@2.1.2: {} + + nanoid@3.3.7: {} + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + pathe@1.1.2: {} + + pathval@2.0.0: {} + + picocolors@1.0.1: {} + + postcss@8.4.39: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + proxy-from-env@1.1.0: {} + + resolve-pkg-maps@1.0.0: {} + + rollup@4.18.1: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.18.1 + '@rollup/rollup-android-arm64': 4.18.1 + '@rollup/rollup-darwin-arm64': 4.18.1 + '@rollup/rollup-darwin-x64': 4.18.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.18.1 + '@rollup/rollup-linux-arm-musleabihf': 4.18.1 + '@rollup/rollup-linux-arm64-gnu': 4.18.1 + '@rollup/rollup-linux-arm64-musl': 4.18.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.18.1 + '@rollup/rollup-linux-riscv64-gnu': 4.18.1 + '@rollup/rollup-linux-s390x-gnu': 4.18.1 + '@rollup/rollup-linux-x64-gnu': 4.18.1 + '@rollup/rollup-linux-x64-musl': 4.18.1 + '@rollup/rollup-win32-arm64-msvc': 4.18.1 + '@rollup/rollup-win32-ia32-msvc': 4.18.1 + '@rollup/rollup-win32-x64-msvc': 4.18.1 + fsevents: 2.3.3 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + source-map-js@1.2.0: {} + + stackback@0.0.2: {} + + std-env@3.7.0: {} + + strip-final-newline@3.0.0: {} + + tinybench@2.8.0: {} + + tinypool@1.0.0: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.0: {} + + tslib@2.6.3: {} + + tsx@4.16.2: + dependencies: + esbuild: 0.21.5 + get-tsconfig: 4.7.5 + optionalDependencies: + fsevents: 2.3.3 tunnel@0.0.6: {} + typescript@5.5.3: {} + + undici-types@5.26.5: {} + undici@5.28.4: dependencies: '@fastify/busboy': 2.1.1 uuid@8.3.2: {} - webidl-conversions@3.0.1: {} + vite-node@2.0.3(@types/node@20.14.10): + dependencies: + cac: 6.7.14 + debug: 4.3.5 + pathe: 1.1.2 + tinyrainbow: 1.2.0 + vite: 5.3.3(@types/node@20.14.10) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vite@5.3.3(@types/node@20.14.10): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.39 + rollup: 4.18.1 + optionalDependencies: + '@types/node': 20.14.10 + fsevents: 2.3.3 + + vitest@2.0.3(@types/node@20.14.10): + dependencies: + '@ampproject/remapping': 2.3.0 + '@vitest/expect': 2.0.3 + '@vitest/pretty-format': 2.0.3 + '@vitest/runner': 2.0.3 + '@vitest/snapshot': 2.0.3 + '@vitest/spy': 2.0.3 + '@vitest/utils': 2.0.3 + chai: 5.1.1 + debug: 4.3.5 + execa: 8.0.1 + magic-string: 0.30.10 + pathe: 1.1.2 + std-env: 3.7.0 + tinybench: 2.8.0 + tinypool: 1.0.0 + tinyrainbow: 1.2.0 + vite: 5.3.3(@types/node@20.14.10) + vite-node: 2.0.3(@types/node@20.14.10) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 20.14.10 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + which@2.0.2: + dependencies: + isexe: 2.0.0 - whatwg-url@5.0.0: + why-is-node-running@2.3.0: dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 + siginfo: 2.0.0 + stackback: 0.0.2 diff --git a/.github/scripts/jira/tsconfig.json b/.github/scripts/jira/tsconfig.json new file mode 100644 index 0000000000..746f76774b --- /dev/null +++ b/.github/scripts/jira/tsconfig.json @@ -0,0 +1,108 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/.github/scripts/jira/update-jira-issue.js b/.github/scripts/jira/update-jira-issue.js deleted file mode 100644 index 77d5b81bff..0000000000 --- a/.github/scripts/jira/update-jira-issue.js +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env node - -import * as core from "@actions/core"; -import fetch from "node-fetch"; - -function parseIssueNumber(prTitle, commitMessage, branchName) { - const jiraIssueRegex = /[A-Z]{2,}-\d+/; - if (!!branchName && jiraIssueRegex.test(branchName.toUpperCase())) { - return branchName.toUpperCase().match(jiraIssueRegex)[0]; - } else if ( - !!commitMessage && - jiraIssueRegex.test(commitMessage.toUpperCase()) - ) { - return commitMessage.toUpperCase().match(jiraIssueRegex)[0]; - } else if (!!prTitle && jiraIssueRegex.test(prTitle.toUpperCase())) { - return prTitle.toUpperCase().match(jiraIssueRegex)[0]; - } else { - return null; - } -} - -function getLabels(tags) { - const labelPrefix = "core-release"; - return tags.map((tag) => { - return { - add: `${labelPrefix}/${tag.substring(1)}`, - }; - }); -} - -async function updateJiraIssue( - jiraHost, - jiraUserName, - jiraApiToken, - issueNumber, - tags, - fixVersionName -) { - const token = Buffer.from(`${jiraUserName}:${jiraApiToken}`).toString( - "base64" - ); - const bodyData = { - update: { - labels: getLabels(tags), - fixVersions: [{ set: [{ name: fixVersionName }] }], - }, - }; - - fetch(`https://${jiraHost}/rest/api/3/issue/${issueNumber}`, { - method: "PUT", - headers: { - Authorization: `Basic ${token}`, - Accept: "application/json", - "Content-Type": "application/json", - }, - body: JSON.stringify(bodyData), - }) - .then((response) => { - console.log(`Response: ${JSON.stringify(response)}`); - return response.text(); - }) - .then((text) => console.log(text)) - .catch((err) => console.error(err)); -} - -async function run() { - try { - const jiraHost = process.env.JIRA_HOST; - const jiraUserName = process.env.JIRA_USERNAME; - const jiraApiToken = process.env.JIRA_API_TOKEN; - const chainlinkVersion = process.env.CHAINLINK_VERSION; - const prTitle = process.env.PR_TITLE; - const commitMessage = process.env.COMMIT_MESSAGE; - const branchName = process.env.BRANCH_NAME; - // tags are not getting used at the current moment so will always default to [] - const tags = process.env.FOUND_TAGS - ? process.env.FOUND_TAGS.split(",") - : []; - - // Check for the existence of JIRA_HOST and JIRA_USERNAME and JIRA_API_TOKEN - if (!jiraHost || !jiraUserName || !jiraApiToken) { - core.setFailed( - "Error: Missing required environment variables: JIRA_HOST and JIRA_USERNAME and JIRA_API_TOKEN." - ); - return; - } - - // Checks for the Jira issue number and exit if it can't find it - const issueNumber = parseIssueNumber(prTitle, commitMessage, branchName); - if (!issueNumber) { - core.info( - "No JIRA issue number found in: PR title, commit message, or branch name. Please include the issue ID in one of these." - ); - core.notice( - "No JIRA issue number found in: PR title, commit message, or branch name. Please include the issue ID in one of these." - ); - core.setOutput( - "jiraComment", - "> :medal_military: No JIRA issue number found - Please include it in the PR title or in a commit message." - ); - return; - } - const fixVersionName = `chainlink-v${chainlinkVersion}`; - await updateJiraIssue( - jiraHost, - jiraUserName, - jiraApiToken, - issueNumber, - tags, - fixVersionName - ); - core.setOutput("jiraComment", ""); - } catch (error) { - core.setFailed(error.message); - } -} - -run(); diff --git a/.github/scripts/jira/update-jira-issue.test.ts b/.github/scripts/jira/update-jira-issue.test.ts new file mode 100644 index 0000000000..c9efebc92d --- /dev/null +++ b/.github/scripts/jira/update-jira-issue.test.ts @@ -0,0 +1,36 @@ +import { expect, describe, it } from "vitest"; +import { parseIssueNumberFrom, tagsToLabels } from "./update-jira-issue"; + +describe("parseIssueNumberFrom", () => { + it("should return the first JIRA issue number found", () => { + let r = parseIssueNumberFrom("CORE-123", "CORE-456", "CORE-789"); + expect(r).to.equal("CORE-123"); + + r = parseIssueNumberFrom( + "2f3df5gf", + "chore/test-RE-78-branch", + "RE-78 Create new test branches" + ); + expect(r).to.equal("RE-78"); + + // handle lower case + r = parseIssueNumberFrom("core-123", "CORE-456", "CORE-789"); + expect(r).to.equal("CORE-123"); + }); + + it("should return undefined if no JIRA issue number is found", () => { + const result = parseIssueNumberFrom("No issue number"); + expect(result).to.be.undefined; + }); +}); + +describe("tagsToLabels", () => { + it("should convert an array of tags to an array of labels", () => { + const tags = ["v1.0.0", "v1.1.0"]; + const result = tagsToLabels(tags); + expect(result).to.deep.equal([ + { add: "core-release/1.0.0" }, + { add: "core-release/1.1.0" }, + ]); + }); +}); diff --git a/.github/scripts/jira/update-jira-issue.ts b/.github/scripts/jira/update-jira-issue.ts new file mode 100644 index 0000000000..2659f4e517 --- /dev/null +++ b/.github/scripts/jira/update-jira-issue.ts @@ -0,0 +1,134 @@ +import * as core from "@actions/core"; +import jira from "jira.js"; + +/** + * Given a list of strings, this function will return the first JIRA issue number it finds. + * + * @example parseIssueNumberFrom("CORE-123", "CORE-456", "CORE-789") => "CORE-123" + * @example parseIssueNumberFrom("2f3df5gf", "chore/test-RE-78-branch", "RE-78 Create new test branches") => "RE-78" + */ +export function parseIssueNumberFrom( + ...inputs: (string | undefined)[] +): string | undefined { + function parse(str?: string) { + const jiraIssueRegex = /[A-Z]{2,}-\d+/; + + return str?.toUpperCase().match(jiraIssueRegex)?.[0]; + } + + const parsed: string[] = inputs.map(parse).filter((x) => x !== undefined); + + return parsed[0]; +} + +/** + * Converts an array of tags to an array of labels. + * + * A label is a string that is formatted as `core-release/{tag}`, with the leading `v` removed from the tag. + * + * @example tagsToLabels(["v1.0.0", "v1.1.0"]) => [{ add: "core-release/1.0.0" }, { add: "core-release/1.1.0" }] + */ +export function tagsToLabels(tags: string[]) { + const labelPrefix = "core-release"; + + return tags.map((t) => ({ + add: `${labelPrefix}/${t.substring(1)}`, + })); +} + +function updateJiraIssue( + client: jira.Version3Client, + issueNumber: string, + tags: string[], + fixVersionName: string, + dryRun: boolean +) { + const payload = { + issueIdOrKey: issueNumber, + update: { + labels: tagsToLabels(tags), + fixVersions: [{ set: [{ name: fixVersionName }] }], + }, + }; + + core.info( + `Updating JIRA issue ${issueNumber} with fix version ${fixVersionName} and labels [${payload.update.labels.join( + ", " + )}]` + ); + if (dryRun) { + core.info("Dry run enabled, skipping JIRA issue update"); + return; + } + + return client.issues.editIssue(payload); +} + +function createJiraClient() { + const jiraHost = process.env.JIRA_HOST; + const jiraUserName = process.env.JIRA_USERNAME; + const jiraApiToken = process.env.JIRA_API_TOKEN; + + if (!jiraHost || !jiraUserName || !jiraApiToken) { + core.setFailed( + "Error: Missing required environment variables: JIRA_HOST and JIRA_USERNAME and JIRA_API_TOKEN." + ); + process.exit(1); + } + + return new jira.Version3Client({ + host: jiraHost, + authentication: { + basic: { + email: jiraUserName, + apiToken: jiraApiToken, + }, + }, + }); +} + +async function main() { + const prTitle = process.env.PR_TITLE; + const commitMessage = process.env.COMMIT_MESSAGE; + const branchName = process.env.BRANCH_NAME; + + const chainlinkVersion = process.env.CHAINLINK_VERSION; + const dryRun = !!process.env.DRY_RUN; + // tags are not getting used at the current moment so will always default to [] + const tags = process.env.FOUND_TAGS ? process.env.FOUND_TAGS.split(",") : []; + + const client = createJiraClient(); + + // Checks for the Jira issue number and exit if it can't find it + const issueNumber = parseIssueNumberFrom(prTitle, commitMessage, branchName); + if (!issueNumber) { + const msg = + "No JIRA issue number found in: PR title, commit message, or branch name. Please include the issue ID in one of these."; + + core.info(msg); + core.notice(msg); + core.setOutput("jiraComment", `> :medal_military: ${msg}`); + + return; + } + + const fixVersionName = `chainlink-v${chainlinkVersion}`; + await updateJiraIssue(client, issueNumber, tags, fixVersionName, dryRun); + + core.setOutput("jiraComment", ""); +} + +async function run() { + try { + await main(); + } catch (error) { + if (error instanceof Error) { + core.setFailed(error.message); + } + core.setFailed( + "Error: Failed to update JIRA issue with fix version and labels." + ); + } +} + +run(); diff --git a/.github/workflows/changeset.yml b/.github/workflows/changeset.yml index cfb4b322bf..01df70a20d 100644 --- a/.github/workflows/changeset.yml +++ b/.github/workflows/changeset.yml @@ -94,7 +94,7 @@ jobs: working-directory: ./.github/scripts/jira run: | echo "COMMIT_MESSAGE=$(git log -1 --pretty=format:'%s')" >> $GITHUB_ENV - pnpm install && node update-jira-issue.js + pnpm install && pnpm start env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} JIRA_HOST: ${{ secrets.JIRA_HOST }} From 7147653630cd24389e0a3ddab7c56f74a2f0c5b1 Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Mon, 29 Jul 2024 16:56:43 -0400 Subject: [PATCH 003/432] Fix syntax error in workflow (#13952) --- .github/workflows/build-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index d692285f68..1a3c6546a6 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -93,7 +93,7 @@ jobs: format( 'https://github.com/{0}/blob/{1}/CHANGELOG.md', github.repository, - github.ref_name, + github.ref_name ) || '' }} docker-image-name: >- From 1eaf5e087a5ac204e0b472e1c307722887104678 Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:24:52 +0200 Subject: [PATCH 004/432] No new finalized Heads Implementation (#13907) * No new finalized Heads Implementation * fixed tests * update defaults for NoNewFinalizedHeadsThreshold * Update common/client/node_lifecycle.go Co-authored-by: amit-momin <108959691+amit-momin@users.noreply.github.com> * Update common/client/node_lifecycle_test.go Co-authored-by: amit-momin <108959691+amit-momin@users.noreply.github.com> * Update common/client/node_lifecycle_test.go Co-authored-by: amit-momin <108959691+amit-momin@users.noreply.github.com> * rename HeadIsNotIncreasing to NoNewHead * move and add docs for syncIssue consts * rename syncIssue to syncStatus --------- Co-authored-by: amit-momin <108959691+amit-momin@users.noreply.github.com> --- .changeset/wild-seals-look.md | 5 + common/client/mock_node_client_test.go | 194 +++++-- common/client/mock_rpc_test.go | 138 ++++- common/client/mocks/config.go | 13 +- common/client/models.go | 45 ++ common/client/models_test.go | 34 ++ common/client/multi_node.go | 9 + common/client/node.go | 1 + common/client/node_fsm.go | 7 +- common/client/node_lifecycle.go | 363 ++++++++---- common/client/node_lifecycle_test.go | 524 ++++++++++++++---- common/client/types.go | 6 +- core/chains/evm/client/chain_client_test.go | 2 +- core/chains/evm/client/config_builder.go | 30 +- core/chains/evm/client/config_builder_test.go | 5 +- core/chains/evm/client/evm_client.go | 4 +- core/chains/evm/client/evm_client_test.go | 4 +- core/chains/evm/client/helpers_test.go | 4 +- core/chains/evm/client/mocks/rpc_client.go | 138 ++++- core/chains/evm/client/rpc_client.go | 65 ++- core/chains/evm/client/rpc_client_test.go | 16 +- core/chains/evm/config/chain_scoped.go | 4 + core/chains/evm/config/config.go | 1 + core/chains/evm/config/toml/config.go | 43 +- core/chains/evm/config/toml/defaults.go | 4 + .../config/toml/defaults/Avalanche_Fuji.toml | 1 + .../toml/defaults/Avalanche_Mainnet.toml | 1 + .../evm/config/toml/defaults/BSC_Mainnet.toml | 1 + .../evm/config/toml/defaults/BSC_Testnet.toml | 1 + .../config/toml/defaults/Base_Mainnet.toml | 1 + .../config/toml/defaults/Base_Sepolia.toml | 1 + .../config/toml/defaults/Celo_Mainnet.toml | 1 + .../config/toml/defaults/Celo_Testnet.toml | 1 + .../toml/defaults/Ethereum_Mainnet.toml | 1 + .../config/toml/defaults/Gnosis_Chiado.toml | 1 + .../config/toml/defaults/Gnosis_Mainnet.toml | 1 + .../toml/defaults/Optimism_Mainnet.toml | 1 + .../toml/defaults/Optimism_Sepolia.toml | 1 + .../config/toml/defaults/Polygon_Amoy.toml | 1 + .../config/toml/defaults/Polygon_Mainnet.toml | 1 + .../config/toml/defaults/WeMix_Mainnet.toml | 1 + .../config/toml/defaults/WeMix_Testnet.toml | 1 + .../evm/config/toml/defaults/fallback.toml | 1 + core/config/docs/chains-evm.toml | 5 + core/services/chainlink/config_test.go | 28 +- .../chainlink/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 3 + core/web/resolver/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 3 + docs/CONFIG.md | 68 +++ .../disk-based-logging-disabled.txtar | 1 + .../validate/disk-based-logging-no-dir.txtar | 1 + .../node/validate/disk-based-logging.txtar | 1 + testdata/scripts/node/validate/invalid.txtar | 1 + testdata/scripts/node/validate/valid.txtar | 1 + 55 files changed, 1452 insertions(+), 339 deletions(-) create mode 100644 .changeset/wild-seals-look.md diff --git a/.changeset/wild-seals-look.md b/.changeset/wild-seals-look.md new file mode 100644 index 0000000000..3cd854f0e6 --- /dev/null +++ b/.changeset/wild-seals-look.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Added new health check that ensures RPC provides new finalized heads at least every `NoNewFinalizedHeadsThreshold` #added diff --git a/common/client/mock_node_client_test.go b/common/client/mock_node_client_test.go index 5b7abe8212..5643dcde90 100644 --- a/common/client/mock_node_client_test.go +++ b/common/client/mock_node_client_test.go @@ -400,62 +400,6 @@ func (_c *mockNodeClient_IsSyncing_Call[CHAIN_ID, HEAD]) RunAndReturn(run func(c return _c } -// LatestFinalizedBlock provides a mock function with given fields: ctx -func (_m *mockNodeClient[CHAIN_ID, HEAD]) LatestFinalizedBlock(ctx context.Context) (HEAD, error) { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for LatestFinalizedBlock") - } - - var r0 HEAD - var r1 error - if rf, ok := ret.Get(0).(func(context.Context) (HEAD, error)); ok { - return rf(ctx) - } - if rf, ok := ret.Get(0).(func(context.Context) HEAD); ok { - r0 = rf(ctx) - } else { - r0 = ret.Get(0).(HEAD) - } - - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(ctx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// mockNodeClient_LatestFinalizedBlock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestFinalizedBlock' -type mockNodeClient_LatestFinalizedBlock_Call[CHAIN_ID types.ID, HEAD Head] struct { - *mock.Call -} - -// LatestFinalizedBlock is a helper method to define mock.On call -// - ctx context.Context -func (_e *mockNodeClient_Expecter[CHAIN_ID, HEAD]) LatestFinalizedBlock(ctx interface{}) *mockNodeClient_LatestFinalizedBlock_Call[CHAIN_ID, HEAD] { - return &mockNodeClient_LatestFinalizedBlock_Call[CHAIN_ID, HEAD]{Call: _e.mock.On("LatestFinalizedBlock", ctx)} -} - -func (_c *mockNodeClient_LatestFinalizedBlock_Call[CHAIN_ID, HEAD]) Run(run func(ctx context.Context)) *mockNodeClient_LatestFinalizedBlock_Call[CHAIN_ID, HEAD] { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *mockNodeClient_LatestFinalizedBlock_Call[CHAIN_ID, HEAD]) Return(_a0 HEAD, _a1 error) *mockNodeClient_LatestFinalizedBlock_Call[CHAIN_ID, HEAD] { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *mockNodeClient_LatestFinalizedBlock_Call[CHAIN_ID, HEAD]) RunAndReturn(run func(context.Context) (HEAD, error)) *mockNodeClient_LatestFinalizedBlock_Call[CHAIN_ID, HEAD] { - _c.Call.Return(run) - return _c -} - // SetAliveLoopSub provides a mock function with given fields: _a0 func (_m *mockNodeClient[CHAIN_ID, HEAD]) SetAliveLoopSub(_a0 types.Subscription) { _m.Called(_a0) @@ -538,8 +482,8 @@ func (_c *mockNodeClient_SubscribeNewHead_Call[CHAIN_ID, HEAD]) Run(run func(ctx return _c } -func (_c *mockNodeClient_SubscribeNewHead_Call[CHAIN_ID, HEAD]) Return(_a0 types.Subscription, _a1 error) *mockNodeClient_SubscribeNewHead_Call[CHAIN_ID, HEAD] { - _c.Call.Return(_a0, _a1) +func (_c *mockNodeClient_SubscribeNewHead_Call[CHAIN_ID, HEAD]) Return(s types.Subscription, err error) *mockNodeClient_SubscribeNewHead_Call[CHAIN_ID, HEAD] { + _c.Call.Return(s, err) return _c } @@ -548,6 +492,140 @@ func (_c *mockNodeClient_SubscribeNewHead_Call[CHAIN_ID, HEAD]) RunAndReturn(run return _c } +// SubscribeToFinalizedHeads provides a mock function with given fields: _a0 +func (_m *mockNodeClient[CHAIN_ID, HEAD]) SubscribeToFinalizedHeads(_a0 context.Context) (<-chan HEAD, types.Subscription, error) { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for SubscribeToFinalizedHeads") + } + + var r0 <-chan HEAD + var r1 types.Subscription + var r2 error + if rf, ok := ret.Get(0).(func(context.Context) (<-chan HEAD, types.Subscription, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) <-chan HEAD); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan HEAD) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) types.Subscription); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(types.Subscription) + } + } + + if rf, ok := ret.Get(2).(func(context.Context) error); ok { + r2 = rf(_a0) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// mockNodeClient_SubscribeToFinalizedHeads_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SubscribeToFinalizedHeads' +type mockNodeClient_SubscribeToFinalizedHeads_Call[CHAIN_ID types.ID, HEAD Head] struct { + *mock.Call +} + +// SubscribeToFinalizedHeads is a helper method to define mock.On call +// - _a0 context.Context +func (_e *mockNodeClient_Expecter[CHAIN_ID, HEAD]) SubscribeToFinalizedHeads(_a0 interface{}) *mockNodeClient_SubscribeToFinalizedHeads_Call[CHAIN_ID, HEAD] { + return &mockNodeClient_SubscribeToFinalizedHeads_Call[CHAIN_ID, HEAD]{Call: _e.mock.On("SubscribeToFinalizedHeads", _a0)} +} + +func (_c *mockNodeClient_SubscribeToFinalizedHeads_Call[CHAIN_ID, HEAD]) Run(run func(_a0 context.Context)) *mockNodeClient_SubscribeToFinalizedHeads_Call[CHAIN_ID, HEAD] { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *mockNodeClient_SubscribeToFinalizedHeads_Call[CHAIN_ID, HEAD]) Return(_a0 <-chan HEAD, _a1 types.Subscription, _a2 error) *mockNodeClient_SubscribeToFinalizedHeads_Call[CHAIN_ID, HEAD] { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *mockNodeClient_SubscribeToFinalizedHeads_Call[CHAIN_ID, HEAD]) RunAndReturn(run func(context.Context) (<-chan HEAD, types.Subscription, error)) *mockNodeClient_SubscribeToFinalizedHeads_Call[CHAIN_ID, HEAD] { + _c.Call.Return(run) + return _c +} + +// SubscribeToHeads provides a mock function with given fields: ctx +func (_m *mockNodeClient[CHAIN_ID, HEAD]) SubscribeToHeads(ctx context.Context) (<-chan HEAD, types.Subscription, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for SubscribeToHeads") + } + + var r0 <-chan HEAD + var r1 types.Subscription + var r2 error + if rf, ok := ret.Get(0).(func(context.Context) (<-chan HEAD, types.Subscription, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) <-chan HEAD); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan HEAD) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) types.Subscription); ok { + r1 = rf(ctx) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(types.Subscription) + } + } + + if rf, ok := ret.Get(2).(func(context.Context) error); ok { + r2 = rf(ctx) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// mockNodeClient_SubscribeToHeads_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SubscribeToHeads' +type mockNodeClient_SubscribeToHeads_Call[CHAIN_ID types.ID, HEAD Head] struct { + *mock.Call +} + +// SubscribeToHeads is a helper method to define mock.On call +// - ctx context.Context +func (_e *mockNodeClient_Expecter[CHAIN_ID, HEAD]) SubscribeToHeads(ctx interface{}) *mockNodeClient_SubscribeToHeads_Call[CHAIN_ID, HEAD] { + return &mockNodeClient_SubscribeToHeads_Call[CHAIN_ID, HEAD]{Call: _e.mock.On("SubscribeToHeads", ctx)} +} + +func (_c *mockNodeClient_SubscribeToHeads_Call[CHAIN_ID, HEAD]) Run(run func(ctx context.Context)) *mockNodeClient_SubscribeToHeads_Call[CHAIN_ID, HEAD] { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *mockNodeClient_SubscribeToHeads_Call[CHAIN_ID, HEAD]) Return(ch <-chan HEAD, sub types.Subscription, err error) *mockNodeClient_SubscribeToHeads_Call[CHAIN_ID, HEAD] { + _c.Call.Return(ch, sub, err) + return _c +} + +func (_c *mockNodeClient_SubscribeToHeads_Call[CHAIN_ID, HEAD]) RunAndReturn(run func(context.Context) (<-chan HEAD, types.Subscription, error)) *mockNodeClient_SubscribeToHeads_Call[CHAIN_ID, HEAD] { + _c.Call.Return(run) + return _c +} + // SubscribersCount provides a mock function with given fields: func (_m *mockNodeClient[CHAIN_ID, HEAD]) SubscribersCount() int32 { ret := _m.Called() diff --git a/common/client/mock_rpc_test.go b/common/client/mock_rpc_test.go index 36beae901c..00473c6636 100644 --- a/common/client/mock_rpc_test.go +++ b/common/client/mock_rpc_test.go @@ -1508,8 +1508,8 @@ func (_c *mockRPC_SubscribeNewHead_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_ return _c } -func (_c *mockRPC_SubscribeNewHead_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) Return(_a0 types.Subscription, _a1 error) *mockRPC_SubscribeNewHead_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM] { - _c.Call.Return(_a0, _a1) +func (_c *mockRPC_SubscribeNewHead_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) Return(s types.Subscription, err error) *mockRPC_SubscribeNewHead_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM] { + _c.Call.Return(s, err) return _c } @@ -1518,6 +1518,140 @@ func (_c *mockRPC_SubscribeNewHead_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_ return _c } +// SubscribeToFinalizedHeads provides a mock function with given fields: _a0 +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) SubscribeToFinalizedHeads(_a0 context.Context) (<-chan HEAD, types.Subscription, error) { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for SubscribeToFinalizedHeads") + } + + var r0 <-chan HEAD + var r1 types.Subscription + var r2 error + if rf, ok := ret.Get(0).(func(context.Context) (<-chan HEAD, types.Subscription, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) <-chan HEAD); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan HEAD) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) types.Subscription); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(types.Subscription) + } + } + + if rf, ok := ret.Get(2).(func(context.Context) error); ok { + r2 = rf(_a0) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// mockRPC_SubscribeToFinalizedHeads_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SubscribeToFinalizedHeads' +type mockRPC_SubscribeToFinalizedHeads_Call[CHAIN_ID types.ID, SEQ types.Sequence, ADDR types.Hashable, BLOCK_HASH types.Hashable, TX interface{}, TX_HASH types.Hashable, EVENT interface{}, EVENT_OPS interface{}, TX_RECEIPT types.Receipt[TX_HASH, BLOCK_HASH], FEE feetypes.Fee, HEAD types.Head[BLOCK_HASH], BATCH_ELEM interface{}] struct { + *mock.Call +} + +// SubscribeToFinalizedHeads is a helper method to define mock.On call +// - _a0 context.Context +func (_e *mockRPC_Expecter[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) SubscribeToFinalizedHeads(_a0 interface{}) *mockRPC_SubscribeToFinalizedHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM] { + return &mockRPC_SubscribeToFinalizedHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]{Call: _e.mock.On("SubscribeToFinalizedHeads", _a0)} +} + +func (_c *mockRPC_SubscribeToFinalizedHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) Run(run func(_a0 context.Context)) *mockRPC_SubscribeToFinalizedHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM] { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *mockRPC_SubscribeToFinalizedHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) Return(_a0 <-chan HEAD, _a1 types.Subscription, _a2 error) *mockRPC_SubscribeToFinalizedHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM] { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *mockRPC_SubscribeToFinalizedHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) RunAndReturn(run func(context.Context) (<-chan HEAD, types.Subscription, error)) *mockRPC_SubscribeToFinalizedHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM] { + _c.Call.Return(run) + return _c +} + +// SubscribeToHeads provides a mock function with given fields: ctx +func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) SubscribeToHeads(ctx context.Context) (<-chan HEAD, types.Subscription, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for SubscribeToHeads") + } + + var r0 <-chan HEAD + var r1 types.Subscription + var r2 error + if rf, ok := ret.Get(0).(func(context.Context) (<-chan HEAD, types.Subscription, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) <-chan HEAD); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan HEAD) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) types.Subscription); ok { + r1 = rf(ctx) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(types.Subscription) + } + } + + if rf, ok := ret.Get(2).(func(context.Context) error); ok { + r2 = rf(ctx) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// mockRPC_SubscribeToHeads_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SubscribeToHeads' +type mockRPC_SubscribeToHeads_Call[CHAIN_ID types.ID, SEQ types.Sequence, ADDR types.Hashable, BLOCK_HASH types.Hashable, TX interface{}, TX_HASH types.Hashable, EVENT interface{}, EVENT_OPS interface{}, TX_RECEIPT types.Receipt[TX_HASH, BLOCK_HASH], FEE feetypes.Fee, HEAD types.Head[BLOCK_HASH], BATCH_ELEM interface{}] struct { + *mock.Call +} + +// SubscribeToHeads is a helper method to define mock.On call +// - ctx context.Context +func (_e *mockRPC_Expecter[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) SubscribeToHeads(ctx interface{}) *mockRPC_SubscribeToHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM] { + return &mockRPC_SubscribeToHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]{Call: _e.mock.On("SubscribeToHeads", ctx)} +} + +func (_c *mockRPC_SubscribeToHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) Run(run func(ctx context.Context)) *mockRPC_SubscribeToHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM] { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *mockRPC_SubscribeToHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) Return(ch <-chan HEAD, sub types.Subscription, err error) *mockRPC_SubscribeToHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM] { + _c.Call.Return(ch, sub, err) + return _c +} + +func (_c *mockRPC_SubscribeToHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) RunAndReturn(run func(context.Context) (<-chan HEAD, types.Subscription, error)) *mockRPC_SubscribeToHeads_Call[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM] { + _c.Call.Return(run) + return _c +} + // SubscribersCount provides a mock function with given fields: func (_m *mockRPC[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, BATCH_ELEM]) SubscribersCount() int32 { ret := _m.Called() diff --git a/common/client/mocks/config.go b/common/client/mocks/config.go index d1007f39f0..95b57cce0c 100644 --- a/common/client/mocks/config.go +++ b/common/client/mocks/config.go @@ -3,10 +3,11 @@ package mocks import "time" type ChainConfig struct { - IsFinalityTagEnabled bool - FinalityDepthVal uint32 - NoNewHeadsThresholdVal time.Duration - FinalizedBlockOffsetVal uint32 + IsFinalityTagEnabled bool + FinalityDepthVal uint32 + NoNewHeadsThresholdVal time.Duration + FinalizedBlockOffsetVal uint32 + NoNewFinalizedHeadsThresholdVal time.Duration } func (t ChainConfig) NodeNoNewHeadsThreshold() time.Duration { @@ -24,3 +25,7 @@ func (t ChainConfig) FinalityTagEnabled() bool { func (t ChainConfig) FinalizedBlockOffset() uint32 { return t.FinalizedBlockOffsetVal } + +func (t ChainConfig) NoNewFinalizedHeadsThreshold() time.Duration { + return t.NoNewFinalizedHeadsThresholdVal +} diff --git a/common/client/models.go b/common/client/models.go index 8b61613766..526bb25c88 100644 --- a/common/client/models.go +++ b/common/client/models.go @@ -1,6 +1,7 @@ package client import ( + "bytes" "fmt" ) @@ -74,3 +75,47 @@ func (n NodeTier) String() string { return fmt.Sprintf("NodeTier(%d)", n) } } + +// syncStatus - defines problems related to RPC's state synchronization. Can be used as a bitmask to define multiple issues +type syncStatus int + +const ( + // syncStatusSynced - RPC is fully synced + syncStatusSynced = 0 + // syncStatusNotInSyncWithPool - RPC is lagging behind the highest block observed within the pool of RPCs + syncStatusNotInSyncWithPool syncStatus = 1 << iota + // syncStatusNoNewHead - RPC failed to produce a new head for too long + syncStatusNoNewHead + // syncStatusNoNewFinalizedHead - RPC failed to produce a new finalized head for too long + syncStatusNoNewFinalizedHead + syncStatusLen +) + +func (s syncStatus) String() string { + if s == syncStatusSynced { + return "Synced" + } + var result bytes.Buffer + for i := syncStatusNotInSyncWithPool; i < syncStatusLen; i = i << 1 { + if i&s == 0 { + continue + } + result.WriteString(i.string()) + result.WriteString(",") + } + result.Truncate(result.Len() - 1) + return result.String() +} + +func (s syncStatus) string() string { + switch s { + case syncStatusNotInSyncWithPool: + return "NotInSyncWithRPCPool" + case syncStatusNoNewHead: + return "NoNewHead" + case syncStatusNoNewFinalizedHead: + return "NoNewFinalizedHead" + default: + return fmt.Sprintf("syncStatus(%d)", s) + } +} diff --git a/common/client/models_test.go b/common/client/models_test.go index 2d5dc31b37..a10592c3b6 100644 --- a/common/client/models_test.go +++ b/common/client/models_test.go @@ -3,6 +3,8 @@ package client import ( "strings" "testing" + + "github.com/stretchr/testify/assert" ) func TestSendTxReturnCode_String(t *testing.T) { @@ -14,3 +16,35 @@ func TestSendTxReturnCode_String(t *testing.T) { } } } + +func TestSyncStatus_String(t *testing.T) { + t.Run("All of the statuses have proper string representation", func(t *testing.T) { + for i := syncStatusNotInSyncWithPool; i < syncStatusLen; i <<= 1 { + // ensure that i's string representation is not equal to `syncStatus(%d)` + assert.NotContains(t, i.String(), "syncStatus(") + } + }) + t.Run("Unwraps mask", func(t *testing.T) { + testCases := []struct { + Mask syncStatus + ExpectedStr string + }{ + { + ExpectedStr: "Synced", + }, + { + Mask: syncStatusNotInSyncWithPool | syncStatusNoNewHead, + ExpectedStr: "NotInSyncWithRPCPool,NoNewHead", + }, + { + Mask: syncStatusNotInSyncWithPool | syncStatusNoNewHead | syncStatusNoNewFinalizedHead, + ExpectedStr: "NotInSyncWithRPCPool,NoNewHead,NoNewFinalizedHead", + }, + } + for _, testCase := range testCases { + t.Run(testCase.ExpectedStr, func(t *testing.T) { + assert.Equal(t, testCase.ExpectedStr, testCase.Mask.String()) + }) + } + }) +} diff --git a/common/client/multi_node.go b/common/client/multi_node.go index 4d4ea925fe..c9250a1d62 100644 --- a/common/client/multi_node.go +++ b/common/client/multi_node.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/assets" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" + feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types" "github.com/smartcontractkit/chainlink/v2/common/types" ) @@ -821,6 +822,14 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().SubscribeNewHead(ctx, channel) } +func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) SubscribeToHeads(ctx context.Context) (ch <-chan HEAD, sub types.Subscription, err error) { + n, err := c.selectNode() + if err != nil { + return nil, nil, err + } + return n.RPC().SubscribeToHeads(ctx) +} + func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) TokenBalance(ctx context.Context, account ADDR, tokenAddr ADDR) (b *big.Int, err error) { n, err := c.selectNode() if err != nil { diff --git a/common/client/node.go b/common/client/node.go index 5ea31d6596..d6543c772a 100644 --- a/common/client/node.go +++ b/common/client/node.go @@ -49,6 +49,7 @@ type NodeConfig interface { type ChainConfig interface { NodeNoNewHeadsThreshold() time.Duration + NoNewFinalizedHeadsThreshold() time.Duration FinalityDepth() uint32 FinalityTagEnabled() bool FinalizedBlockOffset() uint32 diff --git a/common/client/node_fsm.go b/common/client/node_fsm.go index 5a5e255443..e58de071fb 100644 --- a/common/client/node_fsm.go +++ b/common/client/node_fsm.go @@ -2,7 +2,6 @@ package client import ( "fmt" - "math/big" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -240,11 +239,11 @@ func (n *node[CHAIN_ID, HEAD, RPC]) transitionToInSync(fn func()) { // declareOutOfSync puts a node into OutOfSync state, disconnecting all current // clients and making it unavailable for use until back in-sync. -func (n *node[CHAIN_ID, HEAD, RPC]) declareOutOfSync(isOutOfSync func(num int64, td *big.Int) bool) { +func (n *node[CHAIN_ID, HEAD, RPC]) declareOutOfSync(syncIssues syncStatus) { n.transitionToOutOfSync(func() { - n.lfcLog.Errorw("RPC Node is out of sync", "nodeState", n.state) + n.lfcLog.Errorw("RPC Node is out of sync", "nodeState", n.state, "syncIssues", syncIssues) n.wg.Add(1) - go n.outOfSyncLoop(isOutOfSync) + go n.outOfSyncLoop(syncIssues) }) } diff --git a/common/client/node_lifecycle.go b/common/client/node_lifecycle.go index 39e17bb497..40d9a9ef6e 100644 --- a/common/client/node_lifecycle.go +++ b/common/client/node_lifecycle.go @@ -7,6 +7,8 @@ import ( "math/big" "time" + "github.com/smartcontractkit/chainlink/v2/common/types" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -86,33 +88,37 @@ func (n *node[CHAIN_ID, HEAD, RPC]) aliveLoop() { } noNewHeadsTimeoutThreshold := n.chainCfg.NodeNoNewHeadsThreshold() + noNewFinalizedBlocksTimeoutThreshold := n.chainCfg.NoNewFinalizedHeadsThreshold() pollFailureThreshold := n.nodePoolCfg.PollFailureThreshold() pollInterval := n.nodePoolCfg.PollInterval() lggr := logger.Sugared(n.lfcLog).Named("Alive").With("noNewHeadsTimeoutThreshold", noNewHeadsTimeoutThreshold, "pollInterval", pollInterval, "pollFailureThreshold", pollFailureThreshold) lggr.Tracew("Alive loop starting", "nodeState", n.getCachedState()) - headsC := make(chan HEAD) - sub, err := n.rpc.SubscribeNewHead(ctx, headsC) + headsSub, err := n.registerNewSubscription(ctx, lggr.With("subscriptionType", "heads"), + n.chainCfg.NodeNoNewHeadsThreshold(), n.rpc.SubscribeToHeads) if err != nil { - lggr.Errorw("Initial subscribe for heads failed", "nodeState", n.getCachedState()) + lggr.Errorw("Initial subscribe for heads failed", "nodeState", n.getCachedState(), "err", err) n.declareUnreachable() return } - // TODO: nit fix. If multinode switches primary node before we set sub as AliveSub, sub will be closed and we'll - // falsely transition this node to unreachable state - n.rpc.SetAliveLoopSub(sub) - defer sub.Unsubscribe() - - var outOfSyncT *time.Ticker - var outOfSyncTC <-chan time.Time - if noNewHeadsTimeoutThreshold > 0 { - lggr.Debugw("Head liveness checking enabled", "nodeState", n.getCachedState()) - outOfSyncT = time.NewTicker(noNewHeadsTimeoutThreshold) - defer outOfSyncT.Stop() - outOfSyncTC = outOfSyncT.C - } else { - lggr.Debug("Head liveness checking disabled") + + // TODO: will be removed as part of merging effort with BCI-2875 + n.rpc.SetAliveLoopSub(headsSub.sub) + + defer headsSub.Unsubscribe() + + var finalizedHeadsSub headSubscription[HEAD] + if n.chainCfg.FinalityTagEnabled() { + finalizedHeadsSub, err = n.registerNewSubscription(ctx, lggr.With("subscriptionType", "finalizedHeads"), + n.chainCfg.NoNewFinalizedHeadsThreshold(), n.rpc.SubscribeToFinalizedHeads) + if err != nil { + lggr.Errorw("Failed to subscribe to finalized heads", "err", err) + n.declareUnreachable() + return + } + + defer finalizedHeadsSub.Unsubscribe() } var pollCh <-chan time.Time @@ -131,14 +137,6 @@ func (n *node[CHAIN_ID, HEAD, RPC]) aliveLoop() { lggr.Debug("Polling disabled") } - var pollFinalizedHeadCh <-chan time.Time - if n.chainCfg.FinalityTagEnabled() && n.nodePoolCfg.FinalizedBlockPollInterval() > 0 { - lggr.Debugw("Finalized block polling enabled") - pollT := time.NewTicker(n.nodePoolCfg.FinalizedBlockPollInterval()) - defer pollT.Stop() - pollFinalizedHeadCh = pollT.C - } - localHighestChainInfo, _ := n.rpc.GetInterceptedChainInfo() var pollFailures uint32 @@ -149,7 +147,8 @@ func (n *node[CHAIN_ID, HEAD, RPC]) aliveLoop() { case <-pollCh: promPoolRPCNodePolls.WithLabelValues(n.chainID.String(), n.name).Inc() lggr.Tracew("Polling for version", "nodeState", n.getCachedState(), "pollFailures", pollFailures) - version, err := func(ctx context.Context) (string, error) { + var version string + version, err = func(ctx context.Context) (string, error) { ctx, cancel := context.WithTimeout(ctx, pollInterval) defer cancel() return n.RPC().ClientVersion(ctx) @@ -177,47 +176,33 @@ func (n *node[CHAIN_ID, HEAD, RPC]) aliveLoop() { n.declareUnreachable() return } - _, ci := n.StateAndLatest() - if outOfSync, liveNodes := n.syncStatus(ci.BlockNumber, ci.TotalDifficulty); outOfSync { + _, latestChainInfo := n.StateAndLatest() + if outOfSync, liveNodes := n.isOutOfSyncWithPool(latestChainInfo); outOfSync { // note: there must be another live node for us to be out of sync - lggr.Errorw("RPC endpoint has fallen behind", "blockNumber", ci.BlockNumber, "totalDifficulty", ci.TotalDifficulty, "nodeState", n.getCachedState()) + lggr.Errorw("RPC endpoint has fallen behind", "blockNumber", latestChainInfo.BlockNumber, "totalDifficulty", latestChainInfo.TotalDifficulty, "nodeState", n.getCachedState()) if liveNodes < 2 { lggr.Criticalf("RPC endpoint has fallen behind; %s %s", msgCannotDisable, msgDegradedState) continue } - n.declareOutOfSync(n.isOutOfSync) + n.declareOutOfSync(syncStatusNotInSyncWithPool) return } - case bh, open := <-headsC: + case bh, open := <-headsSub.Heads: if !open { lggr.Errorw("Subscription channel unexpectedly closed", "nodeState", n.getCachedState()) n.declareUnreachable() return } - promPoolRPCNodeNumSeenBlocks.WithLabelValues(n.chainID.String(), n.name).Inc() - lggr.Tracew("Got head", "head", bh) - if bh.BlockNumber() > localHighestChainInfo.BlockNumber { - promPoolRPCNodeHighestSeenBlock.WithLabelValues(n.chainID.String(), n.name).Set(float64(bh.BlockNumber())) - lggr.Tracew("Got higher block number, resetting timer", "latestReceivedBlockNumber", localHighestChainInfo.BlockNumber, "blockNumber", bh.BlockNumber(), "nodeState", n.getCachedState()) - localHighestChainInfo.BlockNumber = bh.BlockNumber() - } else { - lggr.Tracew("Ignoring previously seen block number", "latestReceivedBlockNumber", localHighestChainInfo.BlockNumber, "blockNumber", bh.BlockNumber(), "nodeState", n.getCachedState()) - } - if outOfSyncT != nil { - outOfSyncT.Reset(noNewHeadsTimeoutThreshold) - } - if !n.chainCfg.FinalityTagEnabled() { - latestFinalizedBN := max(bh.BlockNumber()-int64(n.chainCfg.FinalityDepth()), 0) - if latestFinalizedBN > localHighestChainInfo.FinalizedBlockNumber { - promPoolRPCNodeHighestFinalizedBlock.WithLabelValues(n.chainID.String(), n.name).Set(float64(latestFinalizedBN)) - localHighestChainInfo.FinalizedBlockNumber = latestFinalizedBN - } + + receivedNewHead := n.onNewHead(lggr, &localHighestChainInfo, bh) + if receivedNewHead && noNewHeadsTimeoutThreshold > 0 { + headsSub.ResetTimer(noNewHeadsTimeoutThreshold) } - case err := <-sub.Err(): + case err = <-headsSub.Errors: lggr.Errorw("Subscription was terminated", "err", err, "nodeState", n.getCachedState()) n.declareUnreachable() return - case <-outOfSyncTC: + case <-headsSub.NoNewHeads: // We haven't received a head on the channel for at least the // threshold amount of time, mark it broken lggr.Errorw(fmt.Sprintf("RPC endpoint detected out of sync; no new heads received for %s (last head received was %v)", noNewHeadsTimeoutThreshold, localHighestChainInfo.BlockNumber), "nodeState", n.getCachedState(), "latestReceivedBlockNumber", localHighestChainInfo.BlockNumber, "noNewHeadsTimeoutThreshold", noNewHeadsTimeoutThreshold) @@ -226,47 +211,151 @@ func (n *node[CHAIN_ID, HEAD, RPC]) aliveLoop() { lggr.Criticalf("RPC endpoint detected out of sync; %s %s", msgCannotDisable, msgDegradedState) // We don't necessarily want to wait the full timeout to check again, we should // check regularly and log noisily in this state - outOfSyncT.Reset(zombieNodeCheckInterval(noNewHeadsTimeoutThreshold)) + headsSub.ResetTimer(zombieNodeCheckInterval(noNewHeadsTimeoutThreshold)) continue } } - n.declareOutOfSync(func(num int64, td *big.Int) bool { return num < localHighestChainInfo.BlockNumber }) + n.declareOutOfSync(syncStatusNoNewHead) return - case <-pollFinalizedHeadCh: - latestFinalized, err := func(ctx context.Context) (HEAD, error) { - ctx, cancel := context.WithTimeout(ctx, n.nodePoolCfg.FinalizedBlockPollInterval()) - defer cancel() - return n.RPC().LatestFinalizedBlock(ctx) - }(ctx) - if err != nil { - lggr.Warnw("Failed to fetch latest finalized block", "err", err) - continue + case latestFinalized, open := <-finalizedHeadsSub.Heads: + if !open { + lggr.Errorw("Finalized heads subscription channel unexpectedly closed", "nodeState", n.getCachedState()) + n.declareUnreachable() + return } - if !latestFinalized.IsValid() { - lggr.Warn("Latest finalized block is not valid") - continue + receivedNewHead := n.onNewFinalizedHead(lggr, &localHighestChainInfo, latestFinalized) + if receivedNewHead && noNewFinalizedBlocksTimeoutThreshold > 0 { + finalizedHeadsSub.ResetTimer(noNewFinalizedBlocksTimeoutThreshold) } - - latestFinalizedBN := latestFinalized.BlockNumber() - if latestFinalizedBN > localHighestChainInfo.FinalizedBlockNumber { - promPoolRPCNodeHighestFinalizedBlock.WithLabelValues(n.chainID.String(), n.name).Set(float64(latestFinalizedBN)) - localHighestChainInfo.FinalizedBlockNumber = latestFinalizedBN + case <-finalizedHeadsSub.NoNewHeads: + // We haven't received a finalized head on the channel for at least the + // threshold amount of time, mark it broken + lggr.Errorw(fmt.Sprintf("RPC's finalized state is out of sync; no new finalized heads received for %s (last finalized head received was %v)", noNewFinalizedBlocksTimeoutThreshold, localHighestChainInfo.FinalizedBlockNumber), "latestReceivedBlockNumber", localHighestChainInfo.BlockNumber) + if n.poolInfoProvider != nil { + if l, _ := n.poolInfoProvider.LatestChainInfo(); l < 2 { + lggr.Criticalf("RPC's finalized state is out of sync; %s %s", msgCannotDisable, msgDegradedState) + // We don't necessarily want to wait the full timeout to check again, we should + // check regularly and log noisily in this state + finalizedHeadsSub.ResetTimer(zombieNodeCheckInterval(noNewFinalizedBlocksTimeoutThreshold)) + continue + } } + n.declareOutOfSync(syncStatusNoNewFinalizedHead) + return + case <-finalizedHeadsSub.Errors: + lggr.Errorw("Finalized heads subscription was terminated", "err", err) + n.declareUnreachable() + return } } } -func (n *node[CHAIN_ID, HEAD, RPC]) isOutOfSync(num int64, td *big.Int) (outOfSync bool) { - outOfSync, _ = n.syncStatus(num, td) - return +type headSubscription[HEAD any] struct { + Heads <-chan HEAD + Errors <-chan error + NoNewHeads <-chan time.Time + + noNewHeadsTicker *time.Ticker + sub types.Subscription + cleanUpTasks []func() +} + +func (sub *headSubscription[HEAD]) ResetTimer(duration time.Duration) { + sub.noNewHeadsTicker.Reset(duration) +} + +func (sub *headSubscription[HEAD]) Unsubscribe() { + for _, doCleanUp := range sub.cleanUpTasks { + doCleanUp() + } +} + +func (n *node[CHAIN_ID, HEAD, PRC]) registerNewSubscription(ctx context.Context, lggr logger.SugaredLogger, + noNewDataThreshold time.Duration, newSub func(ctx context.Context) (<-chan HEAD, types.Subscription, error)) (headSubscription[HEAD], error) { + result := headSubscription[HEAD]{} + var err error + var sub types.Subscription + result.Heads, sub, err = newSub(ctx) + if err != nil { + return result, err + } + + result.Errors = sub.Err() + lggr.Debug("Successfully subscribed") + + // TODO: will be removed as part of merging effort with BCI-2875 + result.sub = sub + //n.stateMu.Lock() + //n.healthCheckSubs = append(n.healthCheckSubs, sub) + //n.stateMu.Unlock() + + result.cleanUpTasks = append(result.cleanUpTasks, sub.Unsubscribe) + + if noNewDataThreshold > 0 { + lggr.Debugw("Subscription liveness checking enabled") + result.noNewHeadsTicker = time.NewTicker(noNewDataThreshold) + result.NoNewHeads = result.noNewHeadsTicker.C + result.cleanUpTasks = append(result.cleanUpTasks, result.noNewHeadsTicker.Stop) + } else { + lggr.Debug("Subscription liveness checking disabled") + } + + return result, nil } -// syncStatus returns outOfSync true if num or td is more than SyncThresold behind the best node. +func (n *node[CHAIN_ID, HEAD, RPC]) onNewFinalizedHead(lggr logger.SugaredLogger, chainInfo *ChainInfo, latestFinalized HEAD) bool { + if !latestFinalized.IsValid() { + lggr.Warn("Latest finalized block is not valid") + return false + } + + latestFinalizedBN := latestFinalized.BlockNumber() + lggr.Tracew("Got latest finalized head", "latestFinalized", latestFinalized) + if latestFinalizedBN <= chainInfo.FinalizedBlockNumber { + lggr.Tracew("Ignoring previously seen finalized block number") + return false + } + + promPoolRPCNodeHighestFinalizedBlock.WithLabelValues(n.chainID.String(), n.name).Set(float64(latestFinalizedBN)) + chainInfo.FinalizedBlockNumber = latestFinalizedBN + return true +} + +func (n *node[CHAIN_ID, HEAD, RPC]) onNewHead(lggr logger.SugaredLogger, chainInfo *ChainInfo, head HEAD) bool { + if !head.IsValid() { + lggr.Warn("Latest head is not valid") + return false + } + + promPoolRPCNodeNumSeenBlocks.WithLabelValues(n.chainID.String(), n.name).Inc() + lggr.Tracew("Got head", "head", head) + lggr = lggr.With("latestReceivedBlockNumber", chainInfo.BlockNumber, "blockNumber", head.BlockNumber(), "nodeState", n.getCachedState()) + if head.BlockNumber() <= chainInfo.BlockNumber { + lggr.Tracew("Ignoring previously seen block number") + return false + } + + promPoolRPCNodeHighestSeenBlock.WithLabelValues(n.chainID.String(), n.name).Set(float64(head.BlockNumber())) + chainInfo.BlockNumber = head.BlockNumber() + + if !n.chainCfg.FinalityTagEnabled() { + latestFinalizedBN := max(head.BlockNumber()-int64(n.chainCfg.FinalityDepth()), 0) + if latestFinalizedBN > chainInfo.FinalizedBlockNumber { + promPoolRPCNodeHighestFinalizedBlock.WithLabelValues(n.chainID.String(), n.name).Set(float64(latestFinalizedBN)) + chainInfo.FinalizedBlockNumber = latestFinalizedBN + } + } + + return true +} + +// isOutOfSyncWithPool returns outOfSync true if num or td is more than SyncThresold behind the best node. // Always returns outOfSync false for SyncThreshold 0. // liveNodes is only included when outOfSync is true. -func (n *node[CHAIN_ID, HEAD, RPC]) syncStatus(num int64, td *big.Int) (outOfSync bool, liveNodes int) { +func (n *node[CHAIN_ID, HEAD, RPC]) isOutOfSyncWithPool(localState ChainInfo) (outOfSync bool, liveNodes int) { if n.poolInfoProvider == nil { + n.lfcLog.Warn("skipping sync state against the pool - should only occur in tests") return // skip for tests } threshold := n.nodePoolCfg.SyncThreshold() @@ -278,22 +367,23 @@ func (n *node[CHAIN_ID, HEAD, RPC]) syncStatus(num int64, td *big.Int) (outOfSyn mode := n.nodePoolCfg.SelectionMode() switch mode { case NodeSelectionModeHighestHead, NodeSelectionModeRoundRobin, NodeSelectionModePriorityLevel: - return num < ci.BlockNumber-int64(threshold), ln + return localState.BlockNumber < ci.BlockNumber-int64(threshold), ln case NodeSelectionModeTotalDifficulty: bigThreshold := big.NewInt(int64(threshold)) - return td.Cmp(bigmath.Sub(ci.TotalDifficulty, bigThreshold)) < 0, ln + return localState.TotalDifficulty.Cmp(bigmath.Sub(ci.TotalDifficulty, bigThreshold)) < 0, ln default: panic("unrecognized NodeSelectionMode: " + mode) } } const ( - msgReceivedBlock = "Received block for RPC node, waiting until back in-sync to mark as live again" - msgInSync = "RPC node back in sync" + msgReceivedBlock = "Received block for RPC node, waiting until back in-sync to mark as live again" + msgReceivedFinalizedBlock = "Received new finalized block for RPC node, waiting until back in-sync to mark as live again" + msgInSync = "RPC node back in sync" ) // outOfSyncLoop takes an OutOfSync node and waits until isOutOfSync returns false to go back to live status -func (n *node[CHAIN_ID, HEAD, RPC]) outOfSyncLoop(isOutOfSync func(num int64, td *big.Int) bool) { +func (n *node[CHAIN_ID, HEAD, RPC]) outOfSyncLoop(syncIssues syncStatus) { defer n.wg.Done() ctx, cancel := n.newCtx() defer cancel() @@ -312,8 +402,9 @@ func (n *node[CHAIN_ID, HEAD, RPC]) outOfSyncLoop(isOutOfSync func(num int64, td outOfSyncAt := time.Now() - lggr := logger.Sugared(logger.Named(n.lfcLog, "OutOfSync")) - lggr.Debugw("Trying to revive out-of-sync RPC node", "nodeState", n.getCachedState()) + // set logger name to OutOfSync or FinalizedBlockOutOfSync + lggr := logger.Sugared(logger.Named(n.lfcLog, n.getCachedState().String())).With("nodeState", n.getCachedState()) + lggr.Debugw("Trying to revive out-of-sync RPC node") // Need to redial since out-of-sync nodes are automatically disconnected state := n.createVerifiedConn(ctx, lggr) @@ -322,46 +413,118 @@ func (n *node[CHAIN_ID, HEAD, RPC]) outOfSyncLoop(isOutOfSync func(num int64, td return } - lggr.Tracew("Successfully subscribed to heads feed on out-of-sync RPC node", "nodeState", n.getCachedState()) - - ch := make(chan HEAD) - sub, err := n.rpc.SubscribeNewHead(ctx, ch) + noNewHeadsTimeoutThreshold := n.chainCfg.NodeNoNewHeadsThreshold() + headsSub, err := n.registerNewSubscription(ctx, lggr.With("subscriptionType", "heads"), + noNewHeadsTimeoutThreshold, n.rpc.SubscribeToHeads) if err != nil { - lggr.Errorw("Failed to subscribe heads on out-of-sync RPC node", "nodeState", n.getCachedState(), "err", err) + lggr.Errorw("Failed to subscribe heads on out-of-sync RPC node", "err", err) n.declareUnreachable() return } - defer sub.Unsubscribe() + lggr.Tracew("Successfully subscribed to heads feed on out-of-sync RPC node") + defer headsSub.Unsubscribe() + + noNewFinalizedBlocksTimeoutThreshold := n.chainCfg.NoNewFinalizedHeadsThreshold() + var finalizedHeadsSub headSubscription[HEAD] + if n.chainCfg.FinalityTagEnabled() { + finalizedHeadsSub, err = n.registerNewSubscription(ctx, lggr.With("subscriptionType", "finalizedHeads"), + noNewFinalizedBlocksTimeoutThreshold, n.rpc.SubscribeToFinalizedHeads) + if err != nil { + lggr.Errorw("Subscribe to finalized heads failed on out-of-sync RPC node", "err", err) + n.declareUnreachable() + return + } + + lggr.Tracew("Successfully subscribed to finalized heads feed on out-of-sync RPC node") + defer finalizedHeadsSub.Unsubscribe() + } + + _, localHighestChainInfo := n.rpc.GetInterceptedChainInfo() for { + if syncIssues == syncStatusSynced { + // back in-sync! flip back into alive loop + lggr.Infow(fmt.Sprintf("%s: %s. Node was out-of-sync for %s", msgInSync, n.String(), time.Since(outOfSyncAt))) + n.declareInSync() + return + } + select { case <-ctx.Done(): return - case head, open := <-ch: + case head, open := <-headsSub.Heads: if !open { - lggr.Error("Subscription channel unexpectedly closed", "nodeState", n.getCachedState()) + lggr.Errorw("Subscription channel unexpectedly closed", "nodeState", n.getCachedState()) n.declareUnreachable() return } - if !isOutOfSync(head.BlockNumber(), head.BlockDifficulty()) { - // back in-sync! flip back into alive loop - lggr.Infow(fmt.Sprintf("%s: %s. Node was out-of-sync for %s", msgInSync, n.String(), time.Since(outOfSyncAt)), "blockNumber", head.BlockNumber(), "blockDifficulty", head.BlockDifficulty(), "nodeState", n.getCachedState()) - n.declareInSync() - return + + if !n.onNewHead(lggr, &localHighestChainInfo, head) { + continue + } + + // received a new head - clear NoNewHead flag + syncIssues &= ^syncStatusNoNewHead + if outOfSync, _ := n.isOutOfSyncWithPool(localHighestChainInfo); !outOfSync { + // we caught up with the pool - clear NotInSyncWithPool flag + syncIssues &= ^syncStatusNotInSyncWithPool + } else { + // we've received new head, but lagging behind the pool, add NotInSyncWithPool flag to prevent false transition to alive + syncIssues |= syncStatusNotInSyncWithPool + } + + if noNewHeadsTimeoutThreshold > 0 { + headsSub.ResetTimer(noNewHeadsTimeoutThreshold) } - lggr.Debugw(msgReceivedBlock, "blockNumber", head.BlockNumber(), "blockDifficulty", head.BlockDifficulty(), "nodeState", n.getCachedState()) - case <-time.After(zombieNodeCheckInterval(n.chainCfg.NodeNoNewHeadsThreshold())): + + lggr.Debugw(msgReceivedBlock, "blockNumber", head.BlockNumber(), "blockDifficulty", head.BlockDifficulty(), "syncIssues", syncIssues) + case <-time.After(zombieNodeCheckInterval(noNewHeadsTimeoutThreshold)): if n.poolInfoProvider != nil { if l, _ := n.poolInfoProvider.LatestChainInfo(); l < 1 { - lggr.Critical("RPC endpoint is still out of sync, but there are no other available nodes. This RPC node will be forcibly moved back into the live pool in a degraded state") + lggr.Criticalw("RPC endpoint is still out of sync, but there are no other available nodes. This RPC node will be forcibly moved back into the live pool in a degraded state", "syncIssues", syncIssues) n.declareInSync() return } } - case err := <-sub.Err(): - lggr.Errorw("Subscription was terminated", "nodeState", n.getCachedState(), "err", err) + case err := <-headsSub.Errors: + lggr.Errorw("Subscription was terminated", "err", err) + n.declareUnreachable() + return + case <-headsSub.NoNewHeads: + // we are not resetting the timer, as there is no need to add syncStatusNoNewHead until it's removed on new head. + syncIssues |= syncStatusNoNewHead + lggr.Debugw(fmt.Sprintf("No new heads received for %s. Node stays out-of-sync due to sync issues: %s", noNewHeadsTimeoutThreshold, syncIssues)) + case latestFinalized, open := <-finalizedHeadsSub.Heads: + if !open { + lggr.Errorw("Finalized heads subscription channel unexpectedly closed") + n.declareUnreachable() + return + } + if !latestFinalized.IsValid() { + lggr.Warn("Latest finalized block is not valid") + continue + } + + receivedNewHead := n.onNewFinalizedHead(lggr, &localHighestChainInfo, latestFinalized) + if !receivedNewHead { + continue + } + + // on new finalized head remove NoNewFinalizedHead flag from the mask + syncIssues &= ^syncStatusNoNewFinalizedHead + if noNewFinalizedBlocksTimeoutThreshold > 0 { + finalizedHeadsSub.ResetTimer(noNewFinalizedBlocksTimeoutThreshold) + } + + lggr.Debugw(msgReceivedFinalizedBlock, "blockNumber", latestFinalized.BlockNumber(), "syncIssues", syncIssues) + case err := <-finalizedHeadsSub.Errors: + lggr.Errorw("Finalized head subscription was terminated", "err", err) n.declareUnreachable() return + case <-finalizedHeadsSub.NoNewHeads: + // we are not resetting the timer, as there is no need to add syncStatusNoNewFinalizedHead until it's removed on new finalized head. + syncIssues |= syncStatusNoNewFinalizedHead + lggr.Debugw(fmt.Sprintf("No new finalized heads received for %s. Node stays out-of-sync due to sync issues: %s", noNewFinalizedBlocksTimeoutThreshold, syncIssues)) } } } diff --git a/common/client/node_lifecycle_test.go b/common/client/node_lifecycle_test.go index 863a15a1fa..833bccf7f2 100644 --- a/common/client/node_lifecycle_test.go +++ b/common/client/node_lifecycle_test.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "math/big" + "sync" "sync/atomic" "testing" @@ -49,7 +50,7 @@ func TestUnit_NodeLifecycle_aliveLoop(t *testing.T) { expectedError := errors.New("failed to subscribe to rpc") rpc.On("DisconnectAll").Once() - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(nil, expectedError).Once() + rpc.On("SubscribeToHeads", mock.Anything).Return(nil, nil, expectedError).Once() // might be called in unreachable loop rpc.On("Dial", mock.Anything).Return(errors.New("failed to dial")).Maybe() node.declareAlive() @@ -74,7 +75,7 @@ func TestUnit_NodeLifecycle_aliveLoop(t *testing.T) { close(errChan) sub.On("Err").Return((<-chan error)(errChan)).Once() sub.On("Unsubscribe").Once() - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(sub, nil).Once() + rpc.On("SubscribeToHeads", mock.Anything).Return(nil, sub, nil).Once() rpc.On("SetAliveLoopSub", sub).Once() // disconnects all on transfer to unreachable rpc.On("DisconnectAll").Once() @@ -89,7 +90,7 @@ func TestUnit_NodeLifecycle_aliveLoop(t *testing.T) { sub := mocks.NewSubscription(t) sub.On("Err").Return((<-chan error)(nil)) sub.On("Unsubscribe").Once() - opts.rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(sub, nil).Once() + opts.rpc.On("SubscribeToHeads", mock.Anything).Return(make(<-chan Head), sub, nil) opts.rpc.On("SetAliveLoopSub", sub).Once() return newDialedNode(t, opts) } @@ -105,7 +106,7 @@ func TestUnit_NodeLifecycle_aliveLoop(t *testing.T) { }) defer func() { assert.NoError(t, node.close()) }() node.declareAlive() - tests.AssertLogEventually(t, observedLogs, "Head liveness checking disabled") + tests.AssertLogEventually(t, observedLogs, "Subscription liveness checking disabled") tests.AssertLogEventually(t, observedLogs, "Polling disabled") assert.Equal(t, nodeStateAlive, node.State()) }) @@ -340,18 +341,21 @@ func TestUnit_NodeLifecycle_aliveLoop(t *testing.T) { tests.AssertLogEventually(t, observedLogs, fmt.Sprintf("RPC endpoint detected out of sync; %s %s", msgCannotDisable, msgDegradedState)) assert.Equal(t, nodeStateAlive, node.State()) }) - t.Run("rpc closed head channel", func(t *testing.T) { - t.Parallel() - rpc := newMockNodeClient[types.ID, Head](t) - rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() + newSub := func(t *testing.T) *mocks.Subscription { sub := mocks.NewSubscription(t) sub.On("Err").Return((<-chan error)(nil)) sub.On("Unsubscribe").Once() - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { - ch := args.Get(1).(chan<- Head) + return sub + } + t.Run("rpc closed head channel", func(t *testing.T) { + t.Parallel() + rpc := newMockNodeClient[types.ID, Head](t) + ch := make(chan Head) + rpc.On("SubscribeToHeads", mock.Anything).Run(func(args mock.Arguments) { close(ch) - }).Return(sub, nil).Once() - rpc.On("SetAliveLoopSub", sub).Once() + }).Return((<-chan Head)(ch), newSub(t), nil).Once() + rpc.On("SetAliveLoopSub", mock.Anything).Once() + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() lggr, observedLogs := logger.TestObserved(t, zap.ErrorLevel) node := newDialedNode(t, testNodeOpts{ lggr: lggr, @@ -380,10 +384,10 @@ func TestUnit_NodeLifecycle_aliveLoop(t *testing.T) { const finalityDepth = 10 const expectedBlock = 990 rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { - ch := args.Get(1).(chan<- Head) + ch := make(chan Head) + rpc.On("SubscribeToHeads", mock.Anything).Run(func(args mock.Arguments) { go writeHeads(t, ch, head{BlockNumber: blockNumber - 1}, head{BlockNumber: blockNumber}, head{BlockNumber: blockNumber - 1}) - }).Return(sub, nil).Once() + }).Return((<-chan Head)(ch), sub, nil).Once() rpc.On("SetAliveLoopSub", sub).Once() name := "node-" + rand.Str(5) node := newDialedNode(t, testNodeOpts{ @@ -403,18 +407,13 @@ func TestUnit_NodeLifecycle_aliveLoop(t *testing.T) { return float64(expectedBlock) == m.Gauge.GetValue() }) }) - t.Run("Logs warning if failed to get finalized block", func(t *testing.T) { + t.Run("If fails to subscribe to latest finalized blocks, transitions to unreachable ", func(t *testing.T) { t.Parallel() rpc := newMockNodeClient[types.ID, Head](t) - rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() - rpc.On("LatestFinalizedBlock", mock.Anything).Return(newMockHead(t), errors.New("failed to get finalized block")) - sub := mocks.NewSubscription(t) - sub.On("Err").Return((<-chan error)(nil)) - sub.On("Unsubscribe").Once() - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(sub, nil).Once() - rpc.On("SetAliveLoopSub", sub).Once() + expectedError := errors.New("failed to subscribe to finalized heads") + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Return(nil, mocks.NewSubscription(t), expectedError).Once() lggr, observedLogs := logger.TestObserved(t, zap.DebugLevel) - node := newDialedNode(t, testNodeOpts{ + node := newSubscribedNode(t, testNodeOpts{ config: testNodeConfig{ finalizedBlockPollInterval: tests.TestInterval, }, @@ -425,26 +424,31 @@ func TestUnit_NodeLifecycle_aliveLoop(t *testing.T) { lggr: lggr, }) defer func() { assert.NoError(t, node.close()) }() + // disconnects all on transfer to unreachable or outOfSync + rpc.On("DisconnectAll").Once() + // might be called in unreachable loop + rpc.On("Dial", mock.Anything).Return(errors.New("failed to dial")).Maybe() node.declareAlive() - tests.AssertLogEventually(t, observedLogs, "Failed to fetch latest finalized block") + tests.AssertLogEventually(t, observedLogs, "Failed to subscribe to finalized heads") + tests.AssertEventually(t, func() bool { + return nodeStateUnreachable == node.State() + }) }) t.Run("Logs warning if latest finalized block is not valid", func(t *testing.T) { t.Parallel() rpc := newMockNodeClient[types.ID, Head](t) + ch := make(chan Head, 1) head := newMockHead(t) head.On("IsValid").Return(false) - rpc.On("LatestFinalizedBlock", mock.Anything).Return(head, nil) + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Run(func(args mock.Arguments) { + ch <- head + }).Return((<-chan Head)(ch), newSub(t), nil).Once() rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() - sub := mocks.NewSubscription(t) - sub.On("Err").Return((<-chan error)(nil)) - sub.On("Unsubscribe").Once() - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(sub, nil).Once() - rpc.On("SetAliveLoopSub", sub).Once() + rpc.On("SubscribeToHeads", mock.Anything).Return(make(<-chan Head), newSub(t), nil).Once() + rpc.On("SetAliveLoopSub", mock.Anything).Once() lggr, observedLogs := logger.TestObserved(t, zap.DebugLevel) node := newDialedNode(t, testNodeOpts{ - config: testNodeConfig{ - finalizedBlockPollInterval: tests.TestInterval, - }, + config: testNodeConfig{}, chainConfig: clientMocks.ChainConfig{ IsFinalityTagEnabled: true, }, @@ -455,29 +459,17 @@ func TestUnit_NodeLifecycle_aliveLoop(t *testing.T) { node.declareAlive() tests.AssertLogEventually(t, observedLogs, "Latest finalized block is not valid") }) - t.Run("If finality tag and finalized block polling are enabled updates latest finalized block metric", func(t *testing.T) { + t.Run("On new finalized block updates corresponding metric", func(t *testing.T) { t.Parallel() rpc := newMockNodeClient[types.ID, Head](t) const expectedBlock = 1101 const finalityDepth = 10 - rpc.On("LatestFinalizedBlock", mock.Anything).Return(head{BlockNumber: expectedBlock - 1}.ToMockHead(t), nil).Once() - rpc.On("LatestFinalizedBlock", mock.Anything).Return(head{BlockNumber: expectedBlock}.ToMockHead(t), nil) - sub := mocks.NewSubscription(t) - sub.On("Err").Return((<-chan error)(nil)) - sub.On("Unsubscribe").Once() - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { - ch := args.Get(1).(chan<- Head) - // ensure that "calculated" finalized head is larger than actual, to ensure we are correctly setting - // the metric - go writeHeads(t, ch, head{BlockNumber: expectedBlock*2 + finalityDepth}) - }).Return(sub, nil).Once() + ch := make(chan Head) + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Return((<-chan Head)(ch), newSub(t), nil).Once() rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() - rpc.On("SetAliveLoopSub", sub).Once() name := "node-" + rand.Str(5) - node := newDialedNode(t, testNodeOpts{ - config: testNodeConfig{ - finalizedBlockPollInterval: tests.TestInterval, - }, + node := newSubscribedNode(t, testNodeOpts{ + config: testNodeConfig{}, chainConfig: clientMocks.ChainConfig{ FinalityDepthVal: finalityDepth, IsFinalityTagEnabled: true, @@ -488,6 +480,12 @@ func TestUnit_NodeLifecycle_aliveLoop(t *testing.T) { }) defer func() { assert.NoError(t, node.close()) }() node.declareAlive() + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + writeHeads(t, ch, head{BlockNumber: expectedBlock - 1}, head{BlockNumber: expectedBlock}, head{BlockNumber: expectedBlock - 1}) + }() tests.AssertEventually(t, func() bool { metric, err := promPoolRPCNodeHighestFinalizedBlock.GetMetricWithLabelValues(big.NewInt(1).String(), name) require.NoError(t, err) @@ -496,6 +494,123 @@ func TestUnit_NodeLifecycle_aliveLoop(t *testing.T) { return float64(expectedBlock) == m.Gauge.GetValue() }) }) + t.Run("If finalized heads channel is closed, transitions to unreachable", func(t *testing.T) { + t.Parallel() + rpc := newMockNodeClient[types.ID, Head](t) + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() + ch := make(chan Head) + close(ch) + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Return((<-chan Head)(ch), newSub(t), nil).Once() + lggr, observedLogs := logger.TestObserved(t, zap.DebugLevel) + node := newSubscribedNode(t, testNodeOpts{ + chainConfig: clientMocks.ChainConfig{ + IsFinalityTagEnabled: true, + }, + rpc: rpc, + lggr: lggr, + }) + defer func() { assert.NoError(t, node.close()) }() + // disconnects all on transfer to unreachable or outOfSync + rpc.On("DisconnectAll").Once() + // might be called in unreachable loop + rpc.On("Dial", mock.Anything).Return(errors.New("failed to dial")).Maybe() + node.declareAlive() + tests.AssertLogEventually(t, observedLogs, "Finalized heads subscription channel unexpectedly closed") + tests.AssertEventually(t, func() bool { + return nodeStateUnreachable == node.State() + }) + }) + t.Run("when no new finalized heads received for threshold, transitions to out of sync", func(t *testing.T) { + t.Parallel() + rpc := newMockNodeClient[types.ID, Head](t) + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() + ch := make(chan Head, 1) + ch <- head{BlockNumber: 10}.ToMockHead(t) + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Return((<-chan Head)(ch), newSub(t), nil).Once() + lggr, observed := logger.TestObserved(t, zap.DebugLevel) + noNewFinalizedHeadsThreshold := tests.TestInterval + node := newSubscribedNode(t, testNodeOpts{ + config: testNodeConfig{}, + chainConfig: clientMocks.ChainConfig{ + NoNewFinalizedHeadsThresholdVal: noNewFinalizedHeadsThreshold, + IsFinalityTagEnabled: true, + }, + rpc: rpc, + lggr: lggr, + }) + defer func() { assert.NoError(t, node.close()) }() + // tries to redial in outOfSync + rpc.On("Dial", mock.Anything).Return(errors.New("failed to dial")).Run(func(_ mock.Arguments) { + assert.Equal(t, nodeStateOutOfSync, node.State()) + }).Once() + // disconnects all on transfer to unreachable or outOfSync + rpc.On("DisconnectAll").Maybe() + // might be called in unreachable loop + rpc.On("Dial", mock.Anything).Return(errors.New("failed to dial")).Maybe() + node.declareAlive() + tests.AssertLogEventually(t, observed, fmt.Sprintf("RPC's finalized state is out of sync; no new finalized heads received for %s (last finalized head received was 10)", noNewFinalizedHeadsThreshold)) + tests.AssertEventually(t, func() bool { + // right after outOfSync we'll transfer to unreachable due to returned error on Dial + // we check that we were in out of sync state on first Dial call + return node.State() == nodeStateUnreachable + }) + }) + t.Run("when no new finalized heads received for threshold but we are the last live node, forcibly stays alive", func(t *testing.T) { + t.Parallel() + rpc := newMockNodeClient[types.ID, Head](t) + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Return(make(<-chan Head), newSub(t), nil).Once() + lggr, observed := logger.TestObserved(t, zap.DebugLevel) + noNewFinalizedHeadsThreshold := tests.TestInterval + node := newSubscribedNode(t, testNodeOpts{ + config: testNodeConfig{}, + chainConfig: clientMocks.ChainConfig{ + NoNewFinalizedHeadsThresholdVal: noNewFinalizedHeadsThreshold, + IsFinalityTagEnabled: true, + }, + rpc: rpc, + lggr: lggr, + }) + defer func() { assert.NoError(t, node.close()) }() + poolInfo := newMockPoolChainInfoProvider(t) + poolInfo.On("LatestChainInfo").Return(1, ChainInfo{ + BlockNumber: 20, + TotalDifficulty: big.NewInt(10), + }).Once() + node.SetPoolChainInfoProvider(poolInfo) + node.declareAlive() + tests.AssertLogEventually(t, observed, fmt.Sprintf("RPC's finalized state is out of sync; %s %s", msgCannotDisable, msgDegradedState)) + assert.Equal(t, nodeStateAlive, node.State()) + }) + t.Run("If finalized subscription returns an error, transitions to unreachable", func(t *testing.T) { + t.Parallel() + rpc := newMockNodeClient[types.ID, Head](t) + rpc.On("DisconnectAll").Once() + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() + sub := mocks.NewSubscription(t) + errCh := make(chan error, 1) + errCh <- errors.New("subscription failed") + sub.On("Err").Return((<-chan error)(errCh)) + sub.On("Unsubscribe").Once() + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Return((<-chan Head)(nil), sub, nil).Once() + lggr, observedLogs := logger.TestObserved(t, zap.DebugLevel) + node := newSubscribedNode(t, testNodeOpts{ + chainConfig: clientMocks.ChainConfig{ + IsFinalityTagEnabled: true, + }, + rpc: rpc, + lggr: lggr, + }) + defer func() { assert.NoError(t, node.close()) }() + // disconnects all on transfer to unreachable or outOfSync + // might be called in unreachable loop + rpc.On("Dial", mock.Anything).Return(errors.New("failed to dial")).Maybe() + node.declareAlive() + tests.AssertLogEventually(t, observedLogs, "Finalized heads subscription was terminated") + tests.AssertEventually(t, func() bool { + return nodeStateUnreachable == node.State() + }) + }) } type head struct { @@ -525,9 +640,10 @@ func writeHeads(t *testing.T, ch chan<- Head, heads ...head) { func setupRPCForAliveLoop(t *testing.T, rpc *mockNodeClient[types.ID, Head]) { rpc.On("Dial", mock.Anything).Return(nil).Maybe() aliveSubscription := mocks.NewSubscription(t) - aliveSubscription.On("Err").Return((<-chan error)(nil)).Maybe() + aliveSubscription.On("Err").Return(nil).Maybe() aliveSubscription.On("Unsubscribe").Maybe() - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(aliveSubscription, nil).Maybe() + rpc.On("SubscribeToHeads", mock.Anything).Return(make(<-chan Head), aliveSubscription, nil).Maybe() + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Return(make(<-chan Head), aliveSubscription, nil).Maybe() rpc.On("SetAliveLoopSub", mock.Anything).Maybe() rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Maybe() } @@ -544,22 +660,18 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { return node } - stubIsOutOfSync := func(num int64, td *big.Int) bool { - return false - } - t.Run("returns on closed", func(t *testing.T) { t.Parallel() node := newTestNode(t, testNodeOpts{}) node.setState(nodeStateClosed) node.wg.Add(1) - node.outOfSyncLoop(stubIsOutOfSync) + node.outOfSyncLoop(syncStatusNotInSyncWithPool) }) t.Run("on old blocks stays outOfSync and returns on close", func(t *testing.T) { t.Parallel() rpc := newMockNodeClient[types.ID, Head](t) nodeChainID := types.RandomID() - lggr, observedLogs := logger.TestObserved(t, zap.DebugLevel) + lggr := logger.Test(t) node := newAliveNode(t, testNodeOpts{ rpc: rpc, chainID: nodeChainID, @@ -569,21 +681,27 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { rpc.On("Dial", mock.Anything).Return(nil).Once() rpc.On("ChainID", mock.Anything).Return(nodeChainID, nil).Once() + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{BlockNumber: 0}, ChainInfo{BlockNumber: 13}).Once() outOfSyncSubscription := mocks.NewSubscription(t) outOfSyncSubscription.On("Err").Return((<-chan error)(nil)) outOfSyncSubscription.On("Unsubscribe").Once() heads := []head{{BlockNumber: 7}, {BlockNumber: 11}, {BlockNumber: 13}} - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { - ch := args.Get(1).(chan<- Head) - go writeHeads(t, ch, heads...) - }).Return(outOfSyncSubscription, nil).Once() + ch := make(chan Head) + var wg sync.WaitGroup + wg.Add(1) + rpc.On("SubscribeToHeads", mock.Anything).Run(func(args mock.Arguments) { + go func() { + defer wg.Done() + writeHeads(t, ch, heads...) + }() + }).Return((<-chan Head)(ch), outOfSyncSubscription, nil).Once() + rpc.On("Dial", mock.Anything).Return(errors.New("failed to redial")).Maybe() - node.declareOutOfSync(func(num int64, td *big.Int) bool { - return true - }) - tests.AssertLogCountEventually(t, observedLogs, msgReceivedBlock, len(heads)) + node.declareOutOfSync(syncStatusNoNewHead) + // wait until all heads are consumed + wg.Wait() assert.Equal(t, nodeStateOutOfSync, node.State()) }) t.Run("if initial dial fails, transitions to unreachable", func(t *testing.T) { @@ -597,7 +715,7 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { expectedError := errors.New("failed to dial rpc") // might be called again in unreachable loop, so no need to set once rpc.On("Dial", mock.Anything).Return(expectedError) - node.declareOutOfSync(stubIsOutOfSync) + node.declareOutOfSync(syncStatusNoNewHead) tests.AssertEventually(t, func() bool { return node.State() == nodeStateUnreachable }) @@ -617,7 +735,7 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { expectedError := errors.New("failed to get chain ID") // might be called multiple times rpc.On("ChainID", mock.Anything).Return(types.NewIDFromInt(0), expectedError) - node.declareOutOfSync(stubIsOutOfSync) + node.declareOutOfSync(syncStatusNoNewHead) tests.AssertEventually(t, func() bool { return node.State() == nodeStateUnreachable }) @@ -637,7 +755,7 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { rpc.On("Dial", mock.Anything).Return(nil).Twice() // might be called multiple times rpc.On("ChainID", mock.Anything).Return(rpcChainID, nil) - node.declareOutOfSync(stubIsOutOfSync) + node.declareOutOfSync(syncStatusNoNewHead) tests.AssertEventually(t, func() bool { return node.State() == nodeStateInvalidChainID }) @@ -657,7 +775,7 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { rpc.On("ChainID", mock.Anything).Return(nodeChainID, nil) // might be called multiple times rpc.On("IsSyncing", mock.Anything).Return(true, nil) - node.declareOutOfSync(stubIsOutOfSync) + node.declareOutOfSync(syncStatusNoNewHead) tests.AssertEventually(t, func() bool { return node.State() == nodeStateSyncing }) @@ -680,7 +798,7 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { rpc.On("ChainID", mock.Anything).Return(nodeChainID, nil).Once() // might be called multiple times rpc.On("IsSyncing", mock.Anything).Return(false, errors.New("failed to check syncing")) - node.declareOutOfSync(stubIsOutOfSync) + node.declareOutOfSync(syncStatusNoNewHead) tests.AssertEventually(t, func() bool { return node.State() == nodeStateUnreachable }) @@ -698,9 +816,9 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { rpc.On("Dial", mock.Anything).Return(nil).Once() rpc.On("ChainID", mock.Anything).Return(nodeChainID, nil).Once() expectedError := errors.New("failed to subscribe") - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(nil, expectedError) + rpc.On("SubscribeToHeads", mock.Anything).Return(nil, nil, expectedError).Once() rpc.On("Dial", mock.Anything).Return(errors.New("failed to redial")).Maybe() - node.declareOutOfSync(stubIsOutOfSync) + node.declareOutOfSync(syncStatusNoNewHead) tests.AssertEventually(t, func() bool { return node.State() == nodeStateUnreachable }) @@ -719,15 +837,15 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { rpc.On("Dial", mock.Anything).Return(nil).Once() rpc.On("ChainID", mock.Anything).Return(nodeChainID, nil).Once() - + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() sub := mocks.NewSubscription(t) errChan := make(chan error, 1) errChan <- errors.New("subscription was terminate") sub.On("Err").Return((<-chan error)(errChan)) sub.On("Unsubscribe").Once() - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(sub, nil).Once() + rpc.On("SubscribeToHeads", mock.Anything).Return(make(<-chan Head), sub, nil).Once() rpc.On("Dial", mock.Anything).Return(errors.New("failed to redial")).Maybe() - node.declareOutOfSync(stubIsOutOfSync) + node.declareOutOfSync(syncStatusNoNewHead) tests.AssertLogEventually(t, observedLogs, "Subscription was terminated") tests.AssertEventually(t, func() bool { return node.State() == nodeStateUnreachable @@ -747,22 +865,22 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { rpc.On("Dial", mock.Anything).Return(nil).Once() rpc.On("ChainID", mock.Anything).Return(nodeChainID, nil).Once() + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() sub := mocks.NewSubscription(t) sub.On("Err").Return((<-chan error)(nil)) sub.On("Unsubscribe").Once() - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { - ch := args.Get(1).(chan<- Head) + ch := make(chan Head) + rpc.On("SubscribeToHeads", mock.Anything).Run(func(args mock.Arguments) { close(ch) - }).Return(sub, nil).Once() + }).Return((<-chan Head)(ch), sub, nil).Once() rpc.On("Dial", mock.Anything).Return(errors.New("failed to redial")).Maybe() - node.declareOutOfSync(stubIsOutOfSync) + node.declareOutOfSync(syncStatusNoNewHead) tests.AssertLogEventually(t, observedLogs, "Subscription channel unexpectedly closed") tests.AssertEventually(t, func() bool { return node.State() == nodeStateUnreachable }) }) - t.Run("becomes alive if it receives a newer head", func(t *testing.T) { t.Parallel() rpc := newMockNodeClient[types.ID, Head](t) @@ -782,17 +900,14 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { outOfSyncSubscription.On("Err").Return((<-chan error)(nil)) outOfSyncSubscription.On("Unsubscribe").Once() const highestBlock = 1000 - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { - ch := args.Get(1).(chan<- Head) - go writeHeads(t, ch, head{BlockNumber: highestBlock - 1}, head{BlockNumber: highestBlock}) - }).Return(outOfSyncSubscription, nil).Once() + ch := make(chan Head) + rpc.On("SubscribeToHeads", mock.Anything).Run(func(args mock.Arguments) { + go writeHeads(t, ch, head{BlockNumber: highestBlock - 1}, head{BlockNumber: highestBlock}, head{BlockNumber: highestBlock + 1}) + }).Return((<-chan Head)(ch), outOfSyncSubscription, nil).Once() rpc.On("GetInterceptedChainInfo").Return(ChainInfo{BlockNumber: highestBlock}, ChainInfo{BlockNumber: highestBlock}) - setupRPCForAliveLoop(t, rpc) - node.declareOutOfSync(func(num int64, td *big.Int) bool { - return num < highestBlock - }) + node.declareOutOfSync(syncStatusNoNewHead) tests.AssertLogEventually(t, observedLogs, msgReceivedBlock) tests.AssertLogEventually(t, observedLogs, msgInSync) tests.AssertEventually(t, func() bool { @@ -819,7 +934,7 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { TotalDifficulty: big.NewInt(200), }) node.SetPoolChainInfoProvider(poolInfo) - rpc.On("GetInterceptedChainInfo").Return(ChainInfo{BlockNumber: 0}, ChainInfo{BlockNumber: 0}) + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}) rpc.On("Dial", mock.Anything).Return(nil).Once() rpc.On("ChainID", mock.Anything).Return(nodeChainID, nil).Once() @@ -827,16 +942,225 @@ func TestUnit_NodeLifecycle_outOfSyncLoop(t *testing.T) { outOfSyncSubscription := mocks.NewSubscription(t) outOfSyncSubscription.On("Err").Return((<-chan error)(nil)) outOfSyncSubscription.On("Unsubscribe").Once() - rpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(outOfSyncSubscription, nil).Once() - + rpc.On("SubscribeToHeads", mock.Anything).Return(make(<-chan Head), outOfSyncSubscription, nil).Once() setupRPCForAliveLoop(t, rpc) - node.declareOutOfSync(stubIsOutOfSync) + node.declareOutOfSync(syncStatusNoNewHead) tests.AssertLogEventually(t, observedLogs, "RPC endpoint is still out of sync, but there are no other available nodes. This RPC node will be forcibly moved back into the live pool in a degraded state") tests.AssertEventually(t, func() bool { return node.State() == nodeStateAlive }) }) + t.Run("Stays out-of-sync if received new head, but lags behind pool", func(t *testing.T) { + t.Parallel() + rpc := newMockNodeClient[types.ID, Head](t) + nodeChainID := types.RandomID() + lggr, observedLogs := logger.TestObserved(t, zap.DebugLevel) + node := newAliveNode(t, testNodeOpts{ + chainConfig: clientMocks.ChainConfig{ + NoNewHeadsThresholdVal: tests.TestInterval, + }, + config: testNodeConfig{ + syncThreshold: 1, + selectionMode: NodeSelectionModeHighestHead, + }, + rpc: rpc, + chainID: nodeChainID, + lggr: lggr, + }) + defer func() { assert.NoError(t, node.close()) }() + poolInfo := newMockPoolChainInfoProvider(t) + const highestBlock = 20 + poolInfo.On("LatestChainInfo").Return(1, ChainInfo{ + BlockNumber: highestBlock * 2, + TotalDifficulty: big.NewInt(200), + }) + node.SetPoolChainInfoProvider(poolInfo) + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{BlockNumber: highestBlock}) + + rpc.On("Dial", mock.Anything).Return(nil).Once() + rpc.On("ChainID", mock.Anything).Return(nodeChainID, nil).Once() + + outOfSyncSubscription := mocks.NewSubscription(t) + outOfSyncSubscription.On("Err").Return((<-chan error)(nil)) + outOfSyncSubscription.On("Unsubscribe").Once() + ch := make(chan Head) + rpc.On("SubscribeToHeads", mock.Anything).Run(func(args mock.Arguments) { + go writeHeads(t, ch, head{BlockNumber: highestBlock - 1}, head{BlockNumber: highestBlock}, head{BlockNumber: highestBlock + 1}) + }).Return((<-chan Head)(ch), outOfSyncSubscription, nil).Once() + + node.declareOutOfSync(syncStatusNoNewHead) + tests.AssertLogEventually(t, observedLogs, msgReceivedBlock) + tests.AssertLogEventually(t, observedLogs, "No new heads received for") + tests.AssertEventually(t, func() bool { + return node.State() == nodeStateOutOfSync + }) + }) + + // creates RPC mock with all calls necessary to create heads subscription that won't produce any events + newRPCWithNoOpHeads := func(t *testing.T, chainID types.ID) *mockNodeClient[types.ID, Head] { + rpc := newMockNodeClient[types.ID, Head](t) + rpc.On("Dial", mock.Anything).Return(nil).Once() + rpc.On("ChainID", mock.Anything).Return(chainID, nil).Once() + sub := mocks.NewSubscription(t) + sub.On("Err").Return((<-chan error)(nil)) + sub.On("Unsubscribe").Once() + rpc.On("SubscribeToHeads", mock.Anything).Return(make(<-chan Head), sub, nil).Once() + return rpc + } + + t.Run("if fails to subscribe to finalized, becomes unreachable", func(t *testing.T) { + t.Parallel() + nodeChainID := types.RandomID() + rpc := newRPCWithNoOpHeads(t, nodeChainID) + node := newAliveNode(t, testNodeOpts{ + rpc: rpc, + chainID: nodeChainID, + chainConfig: clientMocks.ChainConfig{ + IsFinalityTagEnabled: true, + }, + }) + defer func() { assert.NoError(t, node.close()) }() + + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Return((<-chan Head)(nil), nil, errors.New("failed to subscribe")).Once() + // unreachable + rpc.On("Dial", mock.Anything).Return(errors.New("failed to redial")).Maybe() + + node.declareOutOfSync(syncStatusNoNewHead) + tests.AssertEventually(t, func() bool { + return node.State() == nodeStateUnreachable + }) + }) + t.Run("on subscription termination becomes unreachable", func(t *testing.T) { + t.Parallel() + nodeChainID := types.RandomID() + rpc := newRPCWithNoOpHeads(t, nodeChainID) + lggr, observedLogs := logger.TestObserved(t, zap.ErrorLevel) + node := newAliveNode(t, testNodeOpts{ + rpc: rpc, + chainID: nodeChainID, + lggr: lggr, + chainConfig: clientMocks.ChainConfig{ + IsFinalityTagEnabled: true, + }, + }) + defer func() { assert.NoError(t, node.close()) }() + + sub := mocks.NewSubscription(t) + errChan := make(chan error, 1) + errChan <- errors.New("subscription was terminate") + sub.On("Err").Return((<-chan error)(errChan)) + sub.On("Unsubscribe").Once() + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Return(make(<-chan Head), sub, nil).Once() + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() + // unreachable + rpc.On("Dial", mock.Anything).Return(errors.New("failed to redial")).Maybe() + node.declareOutOfSync(syncStatusNoNewHead) + tests.AssertLogEventually(t, observedLogs, "Finalized head subscription was terminated") + tests.AssertEventually(t, func() bool { + return node.State() == nodeStateUnreachable + }) + }) + t.Run("becomes unreachable if head channel is closed", func(t *testing.T) { + t.Parallel() + nodeChainID := types.RandomID() + rpc := newRPCWithNoOpHeads(t, nodeChainID) + lggr, observedLogs := logger.TestObserved(t, zap.ErrorLevel) + node := newAliveNode(t, testNodeOpts{ + rpc: rpc, + chainID: nodeChainID, + lggr: lggr, + chainConfig: clientMocks.ChainConfig{ + IsFinalityTagEnabled: true, + }, + }) + defer func() { assert.NoError(t, node.close()) }() + + sub := mocks.NewSubscription(t) + sub.On("Err").Return((<-chan error)(nil)) + sub.On("Unsubscribe").Once() + ch := make(chan Head) + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Run(func(args mock.Arguments) { + close(ch) + }).Return((<-chan Head)(ch), sub, nil).Once() + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{}).Once() + // unreachable + rpc.On("Dial", mock.Anything).Return(errors.New("failed to redial")).Maybe() + node.declareOutOfSync(syncStatusNoNewHead) + tests.AssertLogEventually(t, observedLogs, "Finalized heads subscription channel unexpectedly closed") + tests.AssertEventually(t, func() bool { + return node.State() == nodeStateUnreachable + }) + }) + t.Run("becomes alive on new finalized block", func(t *testing.T) { + t.Parallel() + nodeChainID := types.RandomID() + rpc := newRPCWithNoOpHeads(t, nodeChainID) + lggr := logger.Test(t) + node := newAliveNode(t, testNodeOpts{ + rpc: rpc, + chainID: nodeChainID, + lggr: lggr, + chainConfig: clientMocks.ChainConfig{ + IsFinalityTagEnabled: true, + NoNewFinalizedHeadsThresholdVal: tests.TestInterval, + }, + }) + defer func() { assert.NoError(t, node.close()) }() + + const highestBlock = 13 + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{FinalizedBlockNumber: highestBlock}).Once() + + outOfSyncSubscription := mocks.NewSubscription(t) + outOfSyncSubscription.On("Err").Return((<-chan error)(nil)) + outOfSyncSubscription.On("Unsubscribe").Once() + ch := make(chan Head) + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Return((<-chan Head)(ch), outOfSyncSubscription, nil).Once() + + setupRPCForAliveLoop(t, rpc) + + node.declareOutOfSync(syncStatusNoNewFinalizedHead) + heads := []head{{BlockNumber: highestBlock - 1}, {BlockNumber: highestBlock}} + writeHeads(t, ch, heads...) + assert.Equal(t, nodeStateOutOfSync, node.State()) + writeHeads(t, ch, head{BlockNumber: highestBlock + 1}) + tests.AssertEventually(t, func() bool { + return node.State() == nodeStateAlive + }) + }) + t.Run("adds finalized block is not increasing flag, if there is no new finalized heads for too long", func(t *testing.T) { + t.Parallel() + nodeChainID := types.RandomID() + rpc := newRPCWithNoOpHeads(t, nodeChainID) + lggr, observed := logger.TestObserved(t, zap.DebugLevel) + const noNewFinalizedHeads = tests.TestInterval + node := newAliveNode(t, testNodeOpts{ + rpc: rpc, + chainID: nodeChainID, + lggr: lggr, + chainConfig: clientMocks.ChainConfig{ + IsFinalityTagEnabled: true, + NoNewFinalizedHeadsThresholdVal: noNewFinalizedHeads, + }, + }) + defer func() { assert.NoError(t, node.close()) }() + + const highestBlock = 13 + rpc.On("GetInterceptedChainInfo").Return(ChainInfo{}, ChainInfo{FinalizedBlockNumber: highestBlock}).Once() + + outOfSyncSubscription := mocks.NewSubscription(t) + outOfSyncSubscription.On("Err").Return((<-chan error)(nil)) + outOfSyncSubscription.On("Unsubscribe").Once() + ch := make(chan Head) + rpc.On("SubscribeToFinalizedHeads", mock.Anything).Return((<-chan Head)(ch), outOfSyncSubscription, nil).Once() + + node.declareOutOfSync(syncStatusNotInSyncWithPool) + heads := []head{{BlockNumber: highestBlock - 1}, {BlockNumber: highestBlock}} + writeHeads(t, ch, heads...) + assert.Equal(t, nodeStateOutOfSync, node.State()) + tests.AssertLogEventually(t, observed, fmt.Sprintf("No new finalized heads received for %s. Node stays "+ + "out-of-sync due to sync issues: NotInSyncWithRPCPool,NoNewFinalizedHead", noNewFinalizedHeads)) + }) } func TestUnit_NodeLifecycle_unreachableLoop(t *testing.T) { @@ -1296,11 +1620,11 @@ func TestUnit_NodeLifecycle_start(t *testing.T) { }) } -func TestUnit_NodeLifecycle_syncStatus(t *testing.T) { +func TestUnit_NodeLifecycle_outOfSyncWithPool(t *testing.T) { t.Parallel() t.Run("skip if nLiveNodes is not configured", func(t *testing.T) { node := newTestNode(t, testNodeOpts{}) - outOfSync, liveNodes := node.syncStatus(0, nil) + outOfSync, liveNodes := node.isOutOfSyncWithPool(ChainInfo{}) assert.Equal(t, false, outOfSync) assert.Equal(t, 0, liveNodes) }) @@ -1308,7 +1632,7 @@ func TestUnit_NodeLifecycle_syncStatus(t *testing.T) { node := newTestNode(t, testNodeOpts{}) poolInfo := newMockPoolChainInfoProvider(t) node.SetPoolChainInfoProvider(poolInfo) - outOfSync, liveNodes := node.syncStatus(0, nil) + outOfSync, liveNodes := node.isOutOfSyncWithPool(ChainInfo{}) assert.Equal(t, false, outOfSync) assert.Equal(t, 0, liveNodes) }) @@ -1320,7 +1644,7 @@ func TestUnit_NodeLifecycle_syncStatus(t *testing.T) { poolInfo.On("LatestChainInfo").Return(1, ChainInfo{}).Once() node.SetPoolChainInfoProvider(poolInfo) assert.Panics(t, func() { - _, _ = node.syncStatus(0, nil) + _, _ = node.isOutOfSyncWithPool(ChainInfo{}) }) }) t.Run("block height selection mode", func(t *testing.T) { @@ -1371,7 +1695,7 @@ func TestUnit_NodeLifecycle_syncStatus(t *testing.T) { for _, td := range []int64{totalDifficulty - syncThreshold - 1, totalDifficulty - syncThreshold, totalDifficulty, totalDifficulty + 1} { for _, testCase := range testCases { t.Run(fmt.Sprintf("%s: SelectionModeVal: %s: total difficulty: %d", testCase.name, selectionMode, td), func(t *testing.T) { - outOfSync, liveNodes := node.syncStatus(testCase.blockNumber, big.NewInt(td)) + outOfSync, liveNodes := node.isOutOfSyncWithPool(ChainInfo{BlockNumber: testCase.blockNumber, TotalDifficulty: big.NewInt(td)}) assert.Equal(t, nodesNum, liveNodes) assert.Equal(t, testCase.outOfSync, outOfSync) }) @@ -1427,7 +1751,7 @@ func TestUnit_NodeLifecycle_syncStatus(t *testing.T) { for _, hb := range []int64{highestBlock - syncThreshold - 1, highestBlock - syncThreshold, highestBlock, highestBlock + 1} { for _, testCase := range testCases { t.Run(fmt.Sprintf("%s: SelectionModeVal: %s: highest block: %d", testCase.name, NodeSelectionModeTotalDifficulty, hb), func(t *testing.T) { - outOfSync, liveNodes := node.syncStatus(hb, big.NewInt(testCase.totalDifficulty)) + outOfSync, liveNodes := node.isOutOfSyncWithPool(ChainInfo{BlockNumber: hb, TotalDifficulty: big.NewInt(testCase.totalDifficulty)}) assert.Equal(t, nodesNum, liveNodes) assert.Equal(t, testCase.outOfSync, outOfSync) }) diff --git a/common/client/types.go b/common/client/types.go index b07f57eb8f..c9b6a3580e 100644 --- a/common/client/types.go +++ b/common/client/types.go @@ -68,7 +68,7 @@ type NodeClient[ SetAliveLoopSub(types.Subscription) UnsubscribeAllExceptAliveLoop() IsSyncing(ctx context.Context) (bool, error) - LatestFinalizedBlock(ctx context.Context) (HEAD, error) + SubscribeToFinalizedHeads(_ context.Context) (<-chan HEAD, types.Subscription, error) // GetInterceptedChainInfo - returns latest and highest observed by application layer ChainInfo. // latest ChainInfo is the most recent value received within a NodeClient's current lifecycle between Dial and DisconnectAll. // highestUserObservations ChainInfo is the highest ChainInfo observed excluding health checks calls. @@ -151,7 +151,9 @@ type connection[ ] interface { ChainID(ctx context.Context) (CHAIN_ID, error) Dial(ctx context.Context) error - SubscribeNewHead(ctx context.Context, channel chan<- HEAD) (types.Subscription, error) + SubscribeToHeads(ctx context.Context) (ch <-chan HEAD, sub types.Subscription, err error) + // TODO: remove as part of merge with BCI-2875 + SubscribeNewHead(ctx context.Context, channel chan<- HEAD) (s types.Subscription, err error) } // PoolChainInfoProvider - provides aggregation of nodes pool ChainInfo diff --git a/core/chains/evm/client/chain_client_test.go b/core/chains/evm/client/chain_client_test.go index 33955c1645..a0b89cabbc 100644 --- a/core/chains/evm/client/chain_client_test.go +++ b/core/chains/evm/client/chain_client_test.go @@ -751,7 +751,7 @@ func newMockRpc(t *testing.T) *mocks.RPCClient { mockRpc.On("Close").Return(nil).Once() mockRpc.On("ChainID", mock.Anything).Return(testutils.FixtureChainID, nil).Once() // node does not always manage to fully setup aliveLoop, so we have to make calls optional to avoid flakes - mockRpc.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(client.NewMockSubscription(), nil).Maybe() + mockRpc.On("SubscribeToHeads", mock.Anything).Return(nil, client.NewMockSubscription(), nil).Maybe() mockRpc.On("SetAliveLoopSub", mock.Anything).Return().Maybe() return mockRpc } diff --git a/core/chains/evm/client/config_builder.go b/core/chains/evm/client/config_builder.go index 19e0f14fd6..fa702bac11 100644 --- a/core/chains/evm/client/config_builder.go +++ b/core/chains/evm/client/config_builder.go @@ -41,6 +41,8 @@ func NewClientConfigs( finalizedBlockOffset *uint32, enforceRepeatableRead *bool, deathDeclarationDelay time.Duration, + noNewFinalizedHeadsThreshold time.Duration, + finalizedBlockPollInterval time.Duration, ) (commonclient.ChainConfig, evmconfig.NodePool, []*toml.Node, error) { nodes, err := parseNodeConfigs(nodeCfgs) @@ -48,24 +50,26 @@ func NewClientConfigs( return nil, nil, nil, err } nodePool := toml.NodePool{ - SelectionMode: selectionMode, - LeaseDuration: commonconfig.MustNewDuration(leaseDuration), - PollFailureThreshold: pollFailureThreshold, - PollInterval: commonconfig.MustNewDuration(pollInterval), - SyncThreshold: syncThreshold, - NodeIsSyncingEnabled: nodeIsSyncingEnabled, - EnforceRepeatableRead: enforceRepeatableRead, - DeathDeclarationDelay: commonconfig.MustNewDuration(deathDeclarationDelay), + SelectionMode: selectionMode, + LeaseDuration: commonconfig.MustNewDuration(leaseDuration), + PollFailureThreshold: pollFailureThreshold, + PollInterval: commonconfig.MustNewDuration(pollInterval), + SyncThreshold: syncThreshold, + NodeIsSyncingEnabled: nodeIsSyncingEnabled, + EnforceRepeatableRead: enforceRepeatableRead, + DeathDeclarationDelay: commonconfig.MustNewDuration(deathDeclarationDelay), + FinalizedBlockPollInterval: commonconfig.MustNewDuration(finalizedBlockPollInterval), } nodePoolCfg := &evmconfig.NodePoolConfig{C: nodePool} chainConfig := &evmconfig.EVMConfig{ C: &toml.EVMConfig{ Chain: toml.Chain{ - ChainType: chaintype.NewChainTypeConfig(chainType), - FinalityDepth: finalityDepth, - FinalityTagEnabled: finalityTagEnabled, - NoNewHeadsThreshold: commonconfig.MustNewDuration(noNewHeadsThreshold), - FinalizedBlockOffset: finalizedBlockOffset, + ChainType: chaintype.NewChainTypeConfig(chainType), + FinalityDepth: finalityDepth, + FinalityTagEnabled: finalityTagEnabled, + NoNewHeadsThreshold: commonconfig.MustNewDuration(noNewHeadsThreshold), + FinalizedBlockOffset: finalizedBlockOffset, + NoNewFinalizedHeadsThreshold: commonconfig.MustNewDuration(noNewFinalizedHeadsThreshold), }, }, } diff --git a/core/chains/evm/client/config_builder_test.go b/core/chains/evm/client/config_builder_test.go index 7c08bf18c1..403c6c2d61 100644 --- a/core/chains/evm/client/config_builder_test.go +++ b/core/chains/evm/client/config_builder_test.go @@ -26,6 +26,7 @@ func TestClientConfigBuilder(t *testing.T) { finalizedBlockOffset := ptr[uint32](16) enforceRepeatableRead := ptr(true) deathDeclarationDelay := time.Second * 3 + noNewFinalizedBlocksThreshold := time.Second nodeConfigs := []client.NodeConfig{ { Name: ptr("foo"), @@ -38,7 +39,7 @@ func TestClientConfigBuilder(t *testing.T) { noNewHeadsThreshold := time.Second chainCfg, nodePool, nodes, err := client.NewClientConfigs(selectionMode, leaseDuration, chainTypeStr, nodeConfigs, pollFailureThreshold, pollInterval, syncThreshold, nodeIsSyncingEnabled, noNewHeadsThreshold, finalityDepth, - finalityTagEnabled, finalizedBlockOffset, enforceRepeatableRead, deathDeclarationDelay) + finalityTagEnabled, finalizedBlockOffset, enforceRepeatableRead, deathDeclarationDelay, noNewFinalizedBlocksThreshold, pollInterval) require.NoError(t, err) // Validate node pool configs @@ -50,6 +51,7 @@ func TestClientConfigBuilder(t *testing.T) { require.Equal(t, *nodeIsSyncingEnabled, nodePool.NodeIsSyncingEnabled()) require.Equal(t, *enforceRepeatableRead, nodePool.EnforceRepeatableRead()) require.Equal(t, deathDeclarationDelay, nodePool.DeathDeclarationDelay()) + require.Equal(t, pollInterval, nodePool.FinalizedBlockPollInterval()) // Validate node configs require.Equal(t, *nodeConfigs[0].Name, *nodes[0].Name) @@ -61,6 +63,7 @@ func TestClientConfigBuilder(t *testing.T) { require.Equal(t, *finalityDepth, chainCfg.FinalityDepth()) require.Equal(t, *finalityTagEnabled, chainCfg.FinalityTagEnabled()) require.Equal(t, *finalizedBlockOffset, chainCfg.FinalizedBlockOffset()) + require.Equal(t, noNewFinalizedBlocksThreshold, chainCfg.NoNewFinalizedHeadsThreshold()) // let combiler tell us, when we do not have sufficient data to create evm client _ = client.NewEvmClient(nodePool, chainCfg, nil, logger.Test(t), big.NewInt(10), nodes, chaintype.ChainType(chainTypeStr)) diff --git a/core/chains/evm/client/evm_client.go b/core/chains/evm/client/evm_client.go index fd7fa5868a..c2373ee775 100644 --- a/core/chains/evm/client/evm_client.go +++ b/core/chains/evm/client/evm_client.go @@ -20,13 +20,13 @@ func NewEvmClient(cfg evmconfig.NodePool, chainCfg commonclient.ChainConfig, cli for i, node := range nodes { if node.SendOnly != nil && *node.SendOnly { rpc := NewRPCClient(lggr, empty, (*url.URL)(node.HTTPURL), *node.Name, int32(i), chainID, - commonclient.Secondary) + commonclient.Secondary, cfg.FinalizedBlockPollInterval()) sendonly := commonclient.NewSendOnlyNode(lggr, (url.URL)(*node.HTTPURL), *node.Name, chainID, rpc) sendonlys = append(sendonlys, sendonly) } else { rpc := NewRPCClient(lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), *node.Name, int32(i), - chainID, commonclient.Primary) + chainID, commonclient.Primary, cfg.FinalizedBlockPollInterval()) primaryNode := commonclient.NewNode(cfg, chainCfg, lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), *node.Name, int32(i), chainID, *node.Order, rpc, "EVM") diff --git a/core/chains/evm/client/evm_client_test.go b/core/chains/evm/client/evm_client_test.go index 9ad25f9602..bdfcf42674 100644 --- a/core/chains/evm/client/evm_client_test.go +++ b/core/chains/evm/client/evm_client_test.go @@ -27,6 +27,8 @@ func TestNewEvmClient(t *testing.T) { finalizedBlockOffset := ptr[uint32](16) enforceRepeatableRead := ptr(true) deathDeclarationDelay := time.Second * 3 + noNewFinalizedBlocksThreshold := time.Second * 5 + finalizedBlockPollInterval := time.Second * 4 nodeConfigs := []client.NodeConfig{ { Name: ptr("foo"), @@ -38,7 +40,7 @@ func TestNewEvmClient(t *testing.T) { finalityTagEnabled := ptr(true) chainCfg, nodePool, nodes, err := client.NewClientConfigs(selectionMode, leaseDuration, chainTypeStr, nodeConfigs, pollFailureThreshold, pollInterval, syncThreshold, nodeIsSyncingEnabled, noNewHeadsThreshold, finalityDepth, - finalityTagEnabled, finalizedBlockOffset, enforceRepeatableRead, deathDeclarationDelay) + finalityTagEnabled, finalizedBlockOffset, enforceRepeatableRead, deathDeclarationDelay, noNewFinalizedBlocksThreshold, finalizedBlockPollInterval) require.NoError(t, err) client := client.NewEvmClient(nodePool, chainCfg, nil, logger.Test(t), testutils.FixtureChainID, nodes, chaintype.ChainType(chainTypeStr)) diff --git a/core/chains/evm/client/helpers_test.go b/core/chains/evm/client/helpers_test.go index e1017a5564..a2a55e1791 100644 --- a/core/chains/evm/client/helpers_test.go +++ b/core/chains/evm/client/helpers_test.go @@ -140,7 +140,7 @@ func NewChainClientWithTestNode( } lggr := logger.Test(t) - rpc := NewRPCClient(lggr, *parsed, rpcHTTPURL, "eth-primary-rpc-0", id, chainID, commonclient.Primary) + rpc := NewRPCClient(lggr, *parsed, rpcHTTPURL, "eth-primary-rpc-0", id, chainID, commonclient.Primary, 0) n := commonclient.NewNode[*big.Int, *evmtypes.Head, RPCClient]( nodeCfg, clientMocks.ChainConfig{NoNewHeadsThresholdVal: noNewHeadsThreshold}, lggr, *parsed, rpcHTTPURL, "eth-primary-node-0", id, chainID, 1, rpc, "EVM") @@ -152,7 +152,7 @@ func NewChainClientWithTestNode( return nil, pkgerrors.Errorf("sendonly ethereum rpc url scheme must be http(s): %s", u.String()) } var empty url.URL - rpc := NewRPCClient(lggr, empty, &sendonlyRPCURLs[i], fmt.Sprintf("eth-sendonly-rpc-%d", i), id, chainID, commonclient.Secondary) + rpc := NewRPCClient(lggr, empty, &sendonlyRPCURLs[i], fmt.Sprintf("eth-sendonly-rpc-%d", i), id, chainID, commonclient.Secondary, 0) s := commonclient.NewSendOnlyNode[*big.Int, RPCClient]( lggr, u, fmt.Sprintf("eth-sendonly-%d", i), chainID, rpc) sendonlys = append(sendonlys, s) diff --git a/core/chains/evm/client/mocks/rpc_client.go b/core/chains/evm/client/mocks/rpc_client.go index fa866af29e..06f79efd55 100644 --- a/core/chains/evm/client/mocks/rpc_client.go +++ b/core/chains/evm/client/mocks/rpc_client.go @@ -1883,8 +1883,8 @@ func (_c *RPCClient_SubscribeNewHead_Call) Run(run func(ctx context.Context, cha return _c } -func (_c *RPCClient_SubscribeNewHead_Call) Return(_a0 commontypes.Subscription, _a1 error) *RPCClient_SubscribeNewHead_Call { - _c.Call.Return(_a0, _a1) +func (_c *RPCClient_SubscribeNewHead_Call) Return(s commontypes.Subscription, err error) *RPCClient_SubscribeNewHead_Call { + _c.Call.Return(s, err) return _c } @@ -1893,6 +1893,140 @@ func (_c *RPCClient_SubscribeNewHead_Call) RunAndReturn(run func(context.Context return _c } +// SubscribeToFinalizedHeads provides a mock function with given fields: _a0 +func (_m *RPCClient) SubscribeToFinalizedHeads(_a0 context.Context) (<-chan *types.Head, commontypes.Subscription, error) { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for SubscribeToFinalizedHeads") + } + + var r0 <-chan *types.Head + var r1 commontypes.Subscription + var r2 error + if rf, ok := ret.Get(0).(func(context.Context) (<-chan *types.Head, commontypes.Subscription, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) <-chan *types.Head); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan *types.Head) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) commontypes.Subscription); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(commontypes.Subscription) + } + } + + if rf, ok := ret.Get(2).(func(context.Context) error); ok { + r2 = rf(_a0) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// RPCClient_SubscribeToFinalizedHeads_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SubscribeToFinalizedHeads' +type RPCClient_SubscribeToFinalizedHeads_Call struct { + *mock.Call +} + +// SubscribeToFinalizedHeads is a helper method to define mock.On call +// - _a0 context.Context +func (_e *RPCClient_Expecter) SubscribeToFinalizedHeads(_a0 interface{}) *RPCClient_SubscribeToFinalizedHeads_Call { + return &RPCClient_SubscribeToFinalizedHeads_Call{Call: _e.mock.On("SubscribeToFinalizedHeads", _a0)} +} + +func (_c *RPCClient_SubscribeToFinalizedHeads_Call) Run(run func(_a0 context.Context)) *RPCClient_SubscribeToFinalizedHeads_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *RPCClient_SubscribeToFinalizedHeads_Call) Return(_a0 <-chan *types.Head, _a1 commontypes.Subscription, _a2 error) *RPCClient_SubscribeToFinalizedHeads_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *RPCClient_SubscribeToFinalizedHeads_Call) RunAndReturn(run func(context.Context) (<-chan *types.Head, commontypes.Subscription, error)) *RPCClient_SubscribeToFinalizedHeads_Call { + _c.Call.Return(run) + return _c +} + +// SubscribeToHeads provides a mock function with given fields: ctx +func (_m *RPCClient) SubscribeToHeads(ctx context.Context) (<-chan *types.Head, commontypes.Subscription, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for SubscribeToHeads") + } + + var r0 <-chan *types.Head + var r1 commontypes.Subscription + var r2 error + if rf, ok := ret.Get(0).(func(context.Context) (<-chan *types.Head, commontypes.Subscription, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) <-chan *types.Head); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan *types.Head) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) commontypes.Subscription); ok { + r1 = rf(ctx) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(commontypes.Subscription) + } + } + + if rf, ok := ret.Get(2).(func(context.Context) error); ok { + r2 = rf(ctx) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// RPCClient_SubscribeToHeads_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SubscribeToHeads' +type RPCClient_SubscribeToHeads_Call struct { + *mock.Call +} + +// SubscribeToHeads is a helper method to define mock.On call +// - ctx context.Context +func (_e *RPCClient_Expecter) SubscribeToHeads(ctx interface{}) *RPCClient_SubscribeToHeads_Call { + return &RPCClient_SubscribeToHeads_Call{Call: _e.mock.On("SubscribeToHeads", ctx)} +} + +func (_c *RPCClient_SubscribeToHeads_Call) Run(run func(ctx context.Context)) *RPCClient_SubscribeToHeads_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *RPCClient_SubscribeToHeads_Call) Return(ch <-chan *types.Head, sub commontypes.Subscription, err error) *RPCClient_SubscribeToHeads_Call { + _c.Call.Return(ch, sub, err) + return _c +} + +func (_c *RPCClient_SubscribeToHeads_Call) RunAndReturn(run func(context.Context) (<-chan *types.Head, commontypes.Subscription, error)) *RPCClient_SubscribeToHeads_Call { + _c.Call.Return(run) + return _c +} + // SubscribersCount provides a mock function with given fields: func (_m *RPCClient) SubscribersCount() int32 { ret := _m.Called() diff --git a/core/chains/evm/client/rpc_client.go b/core/chains/evm/client/rpc_client.go index 9ab5fd135b..1a0023227a 100644 --- a/core/chains/evm/client/rpc_client.go +++ b/core/chains/evm/client/rpc_client.go @@ -2,6 +2,7 @@ package client import ( "context" + "errors" "fmt" "math/big" "net/url" @@ -102,6 +103,8 @@ type RPCClient interface { GetInterceptedChainInfo() (latest, highestUserObservations commonclient.ChainInfo) } +const rpcSubscriptionMethodNewHeads = "newHeads" + type rawclient struct { rpc *rpc.Client geth *ethclient.Client @@ -109,11 +112,12 @@ type rawclient struct { } type rpcClient struct { - rpcLog logger.SugaredLogger - name string - id int32 - chainID *big.Int - tier commonclient.NodeTier + rpcLog logger.SugaredLogger + name string + id int32 + chainID *big.Int + tier commonclient.NodeTier + finalizedBlockPollInterval time.Duration ws rawclient http *rawclient @@ -147,6 +151,7 @@ func NewRPCClient( id int32, chainID *big.Int, tier commonclient.NodeTier, + finalizedBlockPollInterval time.Duration, ) RPCClient { r := new(rpcClient) r.name = name @@ -154,6 +159,7 @@ func NewRPCClient( r.chainID = chainID r.tier = tier r.ws.uri = wsuri + r.finalizedBlockPollInterval = finalizedBlockPollInterval if httpuri != nil { r.http = &rawclient{uri: *httpuri} } @@ -403,6 +409,7 @@ func (r *rpcClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) err return err } +// TODO: Full transition from SubscribeNewHead to SubscribeToHeads is done in BCI-2875 func (r *rpcClient) SubscribeNewHead(ctx context.Context, channel chan<- *evmtypes.Head) (_ commontypes.Subscription, err error) { ctx, cancel, chStopInFlight, ws, _ := r.acquireQueryCtx(ctx) defer cancel() @@ -434,6 +441,54 @@ func (r *rpcClient) SubscribeNewHead(ctx context.Context, channel chan<- *evmtyp return subForwarder, nil } +func (r *rpcClient) SubscribeToHeads(ctx context.Context) (ch <-chan *evmtypes.Head, sub commontypes.Subscription, err error) { + ctx, cancel, chStopInFlight, ws, _ := r.acquireQueryCtx(ctx) + defer cancel() + + args := []interface{}{rpcSubscriptionMethodNewHeads} + start := time.Now() + lggr := r.newRqLggr().With("args", args) + + lggr.Debug("RPC call: evmclient.Client#EthSubscribe") + defer func() { + duration := time.Since(start) + r.logResult(lggr, err, duration, r.getRPCDomain(), "EthSubscribe") + err = r.wrapWS(err) + }() + + channel := make(chan *evmtypes.Head) + forwarder := newSubForwarder(channel, func(head *evmtypes.Head) *evmtypes.Head { + head.EVMChainID = ubig.New(r.chainID) + r.onNewHead(ctx, chStopInFlight, head) + return head + }, r.wrapRPCClientError) + + err = forwarder.start(ws.rpc.EthSubscribe(ctx, forwarder.srcCh, args...)) + if err != nil { + return nil, nil, err + } + + err = r.registerSub(forwarder, chStopInFlight) + if err != nil { + return nil, nil, err + } + + return channel, forwarder, err +} + +func (r *rpcClient) SubscribeToFinalizedHeads(_ context.Context) (<-chan *evmtypes.Head, commontypes.Subscription, error) { + interval := r.finalizedBlockPollInterval + if interval == 0 { + return nil, nil, errors.New("FinalizedBlockPollInterval is 0") + } + timeout := interval + poller, channel := commonclient.NewPoller[*evmtypes.Head](interval, r.LatestFinalizedBlock, timeout, r.rpcLog) + if err := poller.Start(); err != nil { + return nil, nil, err + } + return channel, &poller, nil +} + // GethClient wrappers func (r *rpcClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (receipt *evmtypes.Receipt, err error) { diff --git a/core/chains/evm/client/rpc_client_test.go b/core/chains/evm/client/rpc_client_test.go index 682c435245..9b21aedbea 100644 --- a/core/chains/evm/client/rpc_client_test.go +++ b/core/chains/evm/client/rpc_client_test.go @@ -56,7 +56,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) // set to default values @@ -106,7 +106,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) ch := make(chan *evmtypes.Head) @@ -129,7 +129,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { t.Run("Block's chain ID matched configured", func(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) ch := make(chan *evmtypes.Head) @@ -146,7 +146,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { }) wsURL := server.WSURL() observedLggr, observed := logger.TestObserved(t, zap.DebugLevel) - rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary) + rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) require.NoError(t, rpc.Dial(ctx)) server.Close() _, err := rpc.SubscribeNewHead(ctx, make(chan *evmtypes.Head)) @@ -156,7 +156,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { t.Run("Subscription error is properly wrapper", func(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) sub, err := rpc.SubscribeNewHead(ctx, make(chan *evmtypes.Head)) @@ -184,7 +184,7 @@ func TestRPCClient_SubscribeFilterLogs(t *testing.T) { }) wsURL := server.WSURL() observedLggr, observed := logger.TestObserved(t, zap.DebugLevel) - rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary) + rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) require.NoError(t, rpc.Dial(ctx)) server.Close() _, err := rpc.SubscribeFilterLogs(ctx, ethereum.FilterQuery{}, make(chan types.Log)) @@ -201,7 +201,7 @@ func TestRPCClient_SubscribeFilterLogs(t *testing.T) { return resp }) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) sub, err := rpc.SubscribeFilterLogs(ctx, ethereum.FilterQuery{}, make(chan types.Log)) @@ -250,7 +250,7 @@ func TestRPCClient_LatestFinalizedBlock(t *testing.T) { } server := createRPCServer() - rpc := client.NewRPCClient(lggr, *server.URL, nil, "rpc", 1, chainId, commonclient.Primary) + rpc := client.NewRPCClient(lggr, *server.URL, nil, "rpc", 1, chainId, commonclient.Primary, 0) require.NoError(t, rpc.Dial(ctx)) defer rpc.Close() server.Head = &evmtypes.Head{Number: 128} diff --git a/core/chains/evm/config/chain_scoped.go b/core/chains/evm/config/chain_scoped.go index db598e3e82..b9b19cdc2c 100644 --- a/core/chains/evm/config/chain_scoped.go +++ b/core/chains/evm/config/chain_scoped.go @@ -183,3 +183,7 @@ func (e *EVMConfig) LogPrunePageSize() uint32 { func (e *EVMConfig) FinalizedBlockOffset() uint32 { return *e.C.FinalizedBlockOffset } + +func (e *EVMConfig) NoNewFinalizedHeadsThreshold() time.Duration { + return e.C.NoNewFinalizedHeadsThreshold.Duration() +} diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index ea0d52f570..b0a5772f73 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -46,6 +46,7 @@ type EVM interface { RPCDefaultBatchSize() uint32 NodeNoNewHeadsThreshold() time.Duration FinalizedBlockOffset() uint32 + NoNewFinalizedHeadsThreshold() time.Duration IsEnabled() bool TOMLString() (string, error) diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 3e35bb4b55..2cb29d9769 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -338,27 +338,28 @@ func (c *EVMConfig) TOMLString() (string, error) { } type Chain struct { - AutoCreateKey *bool - BlockBackfillDepth *uint32 - BlockBackfillSkip *bool - ChainType *chaintype.ChainTypeConfig - FinalityDepth *uint32 - FinalityTagEnabled *bool - FlagsContractAddress *types.EIP55Address - LinkContractAddress *types.EIP55Address - LogBackfillBatchSize *uint32 - LogPollInterval *commonconfig.Duration - LogKeepBlocksDepth *uint32 - LogPrunePageSize *uint32 - BackupLogPollerBlockDelay *uint64 - MinIncomingConfirmations *uint32 - MinContractPayment *commonassets.Link - NonceAutoSync *bool - NoNewHeadsThreshold *commonconfig.Duration - OperatorFactoryAddress *types.EIP55Address - RPCDefaultBatchSize *uint32 - RPCBlockQueryDelay *uint16 - FinalizedBlockOffset *uint32 + AutoCreateKey *bool + BlockBackfillDepth *uint32 + BlockBackfillSkip *bool + ChainType *chaintype.ChainTypeConfig + FinalityDepth *uint32 + FinalityTagEnabled *bool + FlagsContractAddress *types.EIP55Address + LinkContractAddress *types.EIP55Address + LogBackfillBatchSize *uint32 + LogPollInterval *commonconfig.Duration + LogKeepBlocksDepth *uint32 + LogPrunePageSize *uint32 + BackupLogPollerBlockDelay *uint64 + MinIncomingConfirmations *uint32 + MinContractPayment *commonassets.Link + NonceAutoSync *bool + NoNewHeadsThreshold *commonconfig.Duration + OperatorFactoryAddress *types.EIP55Address + RPCDefaultBatchSize *uint32 + RPCBlockQueryDelay *uint16 + FinalizedBlockOffset *uint32 + NoNewFinalizedHeadsThreshold *commonconfig.Duration Transactions Transactions `toml:",omitempty"` BalanceMonitor BalanceMonitor `toml:",omitempty"` diff --git a/core/chains/evm/config/toml/defaults.go b/core/chains/evm/config/toml/defaults.go index 38eef40bf7..c3f087da8c 100644 --- a/core/chains/evm/config/toml/defaults.go +++ b/core/chains/evm/config/toml/defaults.go @@ -165,6 +165,10 @@ func (c *Chain) SetFrom(f *Chain) { c.FinalizedBlockOffset = v } + if v := f.NoNewFinalizedHeadsThreshold; v != nil { + c.NoNewFinalizedHeadsThreshold = v + } + c.Transactions.setFrom(&f.Transactions) c.BalanceMonitor.setFrom(&f.BalanceMonitor) c.GasEstimator.setFrom(&f.GasEstimator) diff --git a/core/chains/evm/config/toml/defaults/Avalanche_Fuji.toml b/core/chains/evm/config/toml/defaults/Avalanche_Fuji.toml index d7cbad8157..882a91f1ac 100644 --- a/core/chains/evm/config/toml/defaults/Avalanche_Fuji.toml +++ b/core/chains/evm/config/toml/defaults/Avalanche_Fuji.toml @@ -6,6 +6,7 @@ MinIncomingConfirmations = 1 NoNewHeadsThreshold = '30s' OCR.ContractConfirmations = 1 RPCBlockQueryDelay = 2 +NoNewFinalizedHeadsThreshold = '1m' [GasEstimator] PriceDefault = '25 gwei' diff --git a/core/chains/evm/config/toml/defaults/Avalanche_Mainnet.toml b/core/chains/evm/config/toml/defaults/Avalanche_Mainnet.toml index 95d4bf7546..78d3bbba77 100644 --- a/core/chains/evm/config/toml/defaults/Avalanche_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/Avalanche_Mainnet.toml @@ -6,6 +6,7 @@ MinIncomingConfirmations = 1 NoNewHeadsThreshold = '30s' OCR.ContractConfirmations = 1 RPCBlockQueryDelay = 2 +NoNewFinalizedHeadsThreshold = '1m' [GasEstimator] PriceDefault = '25 gwei' diff --git a/core/chains/evm/config/toml/defaults/BSC_Mainnet.toml b/core/chains/evm/config/toml/defaults/BSC_Mainnet.toml index 384a798e32..1b248a8c45 100644 --- a/core/chains/evm/config/toml/defaults/BSC_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/BSC_Mainnet.toml @@ -6,6 +6,7 @@ LinkContractAddress = '0x404460C6A5EdE2D891e8297795264fDe62ADBB75' LogPollInterval = '3s' NoNewHeadsThreshold = '30s' RPCBlockQueryDelay = 2 +NoNewFinalizedHeadsThreshold = '45s' [GasEstimator] PriceDefault = '5 gwei' diff --git a/core/chains/evm/config/toml/defaults/BSC_Testnet.toml b/core/chains/evm/config/toml/defaults/BSC_Testnet.toml index 364bae0c9f..252f90accd 100644 --- a/core/chains/evm/config/toml/defaults/BSC_Testnet.toml +++ b/core/chains/evm/config/toml/defaults/BSC_Testnet.toml @@ -6,6 +6,7 @@ LinkContractAddress = '0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06' LogPollInterval = '3s' NoNewHeadsThreshold = '30s' RPCBlockQueryDelay = 2 +NoNewFinalizedHeadsThreshold = '40s' [GasEstimator] PriceDefault = '5 gwei' diff --git a/core/chains/evm/config/toml/defaults/Base_Mainnet.toml b/core/chains/evm/config/toml/defaults/Base_Mainnet.toml index 314c12f8c5..f0896fba41 100644 --- a/core/chains/evm/config/toml/defaults/Base_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/Base_Mainnet.toml @@ -4,6 +4,7 @@ FinalityDepth = 200 LogPollInterval = '2s' NoNewHeadsThreshold = '40s' MinIncomingConfirmations = 1 +NoNewFinalizedHeadsThreshold = '15m' [GasEstimator] EIP1559DynamicFees = true diff --git a/core/chains/evm/config/toml/defaults/Base_Sepolia.toml b/core/chains/evm/config/toml/defaults/Base_Sepolia.toml index 6458dda87f..1fc0b51f1f 100644 --- a/core/chains/evm/config/toml/defaults/Base_Sepolia.toml +++ b/core/chains/evm/config/toml/defaults/Base_Sepolia.toml @@ -4,6 +4,7 @@ FinalityDepth = 200 LogPollInterval = '2s' NoNewHeadsThreshold = '40s' MinIncomingConfirmations = 1 +NoNewFinalizedHeadsThreshold = '12m' [GasEstimator] EIP1559DynamicFees = true diff --git a/core/chains/evm/config/toml/defaults/Celo_Mainnet.toml b/core/chains/evm/config/toml/defaults/Celo_Mainnet.toml index b48cb25b32..a494862037 100644 --- a/core/chains/evm/config/toml/defaults/Celo_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/Celo_Mainnet.toml @@ -5,6 +5,7 @@ LogPollInterval = '5s' MinIncomingConfirmations = 1 NoNewHeadsThreshold = '1m' OCR.ContractConfirmations = 1 +NoNewFinalizedHeadsThreshold = '1m' [GasEstimator] PriceDefault = '5 gwei' diff --git a/core/chains/evm/config/toml/defaults/Celo_Testnet.toml b/core/chains/evm/config/toml/defaults/Celo_Testnet.toml index d3f595baac..eb43f080b7 100644 --- a/core/chains/evm/config/toml/defaults/Celo_Testnet.toml +++ b/core/chains/evm/config/toml/defaults/Celo_Testnet.toml @@ -5,6 +5,7 @@ LogPollInterval = '5s' MinIncomingConfirmations = 1 NoNewHeadsThreshold = '1m' OCR.ContractConfirmations = 1 +NoNewFinalizedHeadsThreshold = '1m' [GasEstimator] PriceDefault = '5 gwei' diff --git a/core/chains/evm/config/toml/defaults/Ethereum_Mainnet.toml b/core/chains/evm/config/toml/defaults/Ethereum_Mainnet.toml index 2e65cce633..20bb0d8e72 100644 --- a/core/chains/evm/config/toml/defaults/Ethereum_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/Ethereum_Mainnet.toml @@ -2,6 +2,7 @@ ChainID = '1' LinkContractAddress = '0x514910771AF9Ca656af840dff83E8264EcF986CA' MinContractPayment = '0.1 link' OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' +NoNewFinalizedHeadsThreshold = '9m' [GasEstimator] EIP1559DynamicFees = true diff --git a/core/chains/evm/config/toml/defaults/Gnosis_Chiado.toml b/core/chains/evm/config/toml/defaults/Gnosis_Chiado.toml index 1b14da2b54..379377a226 100644 --- a/core/chains/evm/config/toml/defaults/Gnosis_Chiado.toml +++ b/core/chains/evm/config/toml/defaults/Gnosis_Chiado.toml @@ -3,6 +3,7 @@ ChainID = '10200' FinalityDepth = 100 ChainType = 'gnosis' LogPollInterval = '5s' +NoNewFinalizedHeadsThreshold = '2m' [GasEstimator] EIP1559DynamicFees = true diff --git a/core/chains/evm/config/toml/defaults/Gnosis_Mainnet.toml b/core/chains/evm/config/toml/defaults/Gnosis_Mainnet.toml index 587f0083b7..628646364f 100644 --- a/core/chains/evm/config/toml/defaults/Gnosis_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/Gnosis_Mainnet.toml @@ -9,6 +9,7 @@ ChainID = '100' ChainType = 'gnosis' LinkContractAddress = '0xE2e73A1c69ecF83F464EFCE6A5be353a37cA09b2' LogPollInterval = '5s' +NoNewFinalizedHeadsThreshold = '2m' [GasEstimator] PriceDefault = '1 gwei' diff --git a/core/chains/evm/config/toml/defaults/Optimism_Mainnet.toml b/core/chains/evm/config/toml/defaults/Optimism_Mainnet.toml index fd4dd9f32f..3510aef704 100644 --- a/core/chains/evm/config/toml/defaults/Optimism_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/Optimism_Mainnet.toml @@ -5,6 +5,7 @@ LinkContractAddress = '0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6' LogPollInterval = '2s' NoNewHeadsThreshold = '40s' MinIncomingConfirmations = 1 +NoNewFinalizedHeadsThreshold = '13m' [GasEstimator] EIP1559DynamicFees = true diff --git a/core/chains/evm/config/toml/defaults/Optimism_Sepolia.toml b/core/chains/evm/config/toml/defaults/Optimism_Sepolia.toml index 116ae9d680..8da575a593 100644 --- a/core/chains/evm/config/toml/defaults/Optimism_Sepolia.toml +++ b/core/chains/evm/config/toml/defaults/Optimism_Sepolia.toml @@ -4,6 +4,7 @@ FinalityDepth = 200 LogPollInterval = '2s' NoNewHeadsThreshold = '40s' MinIncomingConfirmations = 1 +NoNewFinalizedHeadsThreshold = '15m' [GasEstimator] EIP1559DynamicFees = true diff --git a/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml b/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml index 6a1687fec4..77438343e2 100644 --- a/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml +++ b/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml @@ -5,6 +5,7 @@ MinIncomingConfirmations = 5 NoNewHeadsThreshold = '30s' RPCBlockQueryDelay = 10 RPCDefaultBatchSize = 100 +NoNewFinalizedHeadsThreshold = '12m' [Transactions] MaxQueued = 5000 diff --git a/core/chains/evm/config/toml/defaults/Polygon_Mainnet.toml b/core/chains/evm/config/toml/defaults/Polygon_Mainnet.toml index 50057a6893..2a52056330 100644 --- a/core/chains/evm/config/toml/defaults/Polygon_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/Polygon_Mainnet.toml @@ -9,6 +9,7 @@ NoNewHeadsThreshold = '30s' # Must be set to something large here because Polygon has so many re-orgs that otherwise we are constantly refetching RPCBlockQueryDelay = 10 RPCDefaultBatchSize = 100 +NoNewFinalizedHeadsThreshold = '6m' [Transactions] # Matic nodes under high mempool pressure are liable to drop txes, we need to ensure we keep sending them diff --git a/core/chains/evm/config/toml/defaults/WeMix_Mainnet.toml b/core/chains/evm/config/toml/defaults/WeMix_Mainnet.toml index 35cd4a90a2..7fcbd18890 100644 --- a/core/chains/evm/config/toml/defaults/WeMix_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/WeMix_Mainnet.toml @@ -5,6 +5,7 @@ MinIncomingConfirmations = 1 # WeMix emits a block every 1 second, regardless of transactions LogPollInterval = '3s' NoNewHeadsThreshold = '30s' +NoNewFinalizedHeadsThreshold = '40s' [OCR] ContractConfirmations = 1 diff --git a/core/chains/evm/config/toml/defaults/WeMix_Testnet.toml b/core/chains/evm/config/toml/defaults/WeMix_Testnet.toml index 417718d87e..83c483d034 100644 --- a/core/chains/evm/config/toml/defaults/WeMix_Testnet.toml +++ b/core/chains/evm/config/toml/defaults/WeMix_Testnet.toml @@ -5,6 +5,7 @@ MinIncomingConfirmations = 1 # WeMix emits a block every 1 second, regardless of transactions LogPollInterval = '3s' NoNewHeadsThreshold = '30s' +NoNewFinalizedHeadsThreshold = '40s' [OCR] ContractConfirmations = 1 diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index a11e646e08..a47e56bc91 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -15,6 +15,7 @@ NoNewHeadsThreshold = '3m' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0' [Transactions] ForwardersEnabled = false diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index 38c8cb8354..460f6f6500 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -97,6 +97,11 @@ RPCBlockQueryDelay = 1 # Default # Block 64 will be treated as finalized by CL Node only when chain's latest finalized block is 65. As chain finalizes blocks in batches of 32, # CL Node has to wait for a whole new batch to be finalized to treat block 64 as finalized. FinalizedBlockOffset = 0 # Default +# NoNewFinalizedHeadsThreshold controls how long to wait for new finalized block before `NodePool` marks rpc endpoints as +# out-of-sync. Only applicable if `FinalityTagEnabled=true` +# +# Set to zero to disable. +NoNewFinalizedHeadsThreshold = '0' # Default [EVM.Transactions] # ForwardersEnabled enables or disables sending transactions through forwarder contracts. diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index c8cd5ec479..ba182b8f60 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -553,19 +553,20 @@ func TestConfig_Marshal(t *testing.T) { }, }, - LinkContractAddress: mustAddress("0x538aAaB4ea120b2bC2fe5D296852D948F07D849e"), - LogBackfillBatchSize: ptr[uint32](17), - LogPollInterval: &minute, - LogKeepBlocksDepth: ptr[uint32](100000), - LogPrunePageSize: ptr[uint32](0), - BackupLogPollerBlockDelay: ptr[uint64](532), - MinContractPayment: commonassets.NewLinkFromJuels(math.MaxInt64), - MinIncomingConfirmations: ptr[uint32](13), - NonceAutoSync: ptr(true), - NoNewHeadsThreshold: &minute, - OperatorFactoryAddress: mustAddress("0xa5B85635Be42F21f94F28034B7DA440EeFF0F418"), - RPCDefaultBatchSize: ptr[uint32](17), - RPCBlockQueryDelay: ptr[uint16](10), + LinkContractAddress: mustAddress("0x538aAaB4ea120b2bC2fe5D296852D948F07D849e"), + LogBackfillBatchSize: ptr[uint32](17), + LogPollInterval: &minute, + LogKeepBlocksDepth: ptr[uint32](100000), + LogPrunePageSize: ptr[uint32](0), + BackupLogPollerBlockDelay: ptr[uint64](532), + MinContractPayment: commonassets.NewLinkFromJuels(math.MaxInt64), + MinIncomingConfirmations: ptr[uint32](13), + NonceAutoSync: ptr(true), + NoNewHeadsThreshold: &minute, + OperatorFactoryAddress: mustAddress("0xa5B85635Be42F21f94F28034B7DA440EeFF0F418"), + RPCDefaultBatchSize: ptr[uint32](17), + RPCBlockQueryDelay: ptr[uint16](10), + NoNewFinalizedHeadsThreshold: &hour, Transactions: evmcfg.Transactions{ MaxInFlight: ptr[uint32](19), @@ -996,6 +997,7 @@ OperatorFactoryAddress = '0xa5B85635Be42F21f94F28034B7DA440EeFF0F418' RPCDefaultBatchSize = 17 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 16 +NoNewFinalizedHeadsThreshold = '1h0m0s' [EVM.Transactions] ForwardersEnabled = true diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 78f52805df..21d68c23ad 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -290,6 +290,7 @@ OperatorFactoryAddress = '0xa5B85635Be42F21f94F28034B7DA440EeFF0F418' RPCDefaultBatchSize = 17 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 16 +NoNewFinalizedHeadsThreshold = '1h0m0s' [EVM.Transactions] ForwardersEnabled = true diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 61c5e3fa26..c56e755d36 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -277,6 +277,7 @@ OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 12 +NoNewFinalizedHeadsThreshold = '9m0s' [EVM.Transactions] ForwardersEnabled = false @@ -376,6 +377,7 @@ OperatorFactoryAddress = '0x8007e24251b1D2Fc518Eb843A701d9cD21fe0aA3' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [EVM.Transactions] ForwardersEnabled = false @@ -469,6 +471,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '6m0s' [EVM.Transactions] ForwardersEnabled = false diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 3e083bd184..1672eb1b41 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -290,6 +290,7 @@ OperatorFactoryAddress = '0xa5B85635Be42F21f94F28034B7DA440EeFF0F418' RPCDefaultBatchSize = 17 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '15m0s' [EVM.Transactions] ForwardersEnabled = true diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index f391804b7c..0e12af9a7e 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -277,6 +277,7 @@ OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '9m0s' [EVM.Transactions] ForwardersEnabled = false @@ -376,6 +377,7 @@ OperatorFactoryAddress = '0x8007e24251b1D2Fc518Eb843A701d9cD21fe0aA3' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [EVM.Transactions] ForwardersEnabled = false @@ -469,6 +471,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '6m0s' [EVM.Transactions] ForwardersEnabled = false diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 7a4d3ca62c..0d670b3515 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1786,6 +1786,7 @@ OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '9m0s' [Transactions] ForwardersEnabled = false @@ -1879,6 +1880,7 @@ NoNewHeadsThreshold = '3m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -1972,6 +1974,7 @@ NoNewHeadsThreshold = '3m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -2065,6 +2068,7 @@ NoNewHeadsThreshold = '3m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -2159,6 +2163,7 @@ NoNewHeadsThreshold = '40s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '13m0s' [Transactions] ForwardersEnabled = false @@ -2252,6 +2257,7 @@ NoNewHeadsThreshold = '3m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -2345,6 +2351,7 @@ NoNewHeadsThreshold = '3m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -2439,6 +2446,7 @@ OperatorFactoryAddress = '0x8007e24251b1D2Fc518Eb843A701d9cD21fe0aA3' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -2532,6 +2540,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '45s' [Transactions] ForwardersEnabled = false @@ -2624,6 +2633,7 @@ NoNewHeadsThreshold = '3m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -2716,6 +2726,7 @@ NoNewHeadsThreshold = '3m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -2809,6 +2820,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '40s' [Transactions] ForwardersEnabled = false @@ -2903,6 +2915,7 @@ NoNewHeadsThreshold = '3m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '2m0s' [Transactions] ForwardersEnabled = false @@ -2996,6 +3009,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -3089,6 +3103,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '6m0s' [Transactions] ForwardersEnabled = false @@ -3182,6 +3197,7 @@ NoNewHeadsThreshold = '12m0s' RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 15 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -3275,6 +3291,7 @@ NoNewHeadsThreshold = '6m0s' RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 15 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -3368,6 +3385,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -3461,6 +3479,7 @@ NoNewHeadsThreshold = '40s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -3554,6 +3573,7 @@ NoNewHeadsThreshold = '1m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -3647,6 +3667,7 @@ NoNewHeadsThreshold = '1m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -3740,6 +3761,7 @@ NoNewHeadsThreshold = '1m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -3834,6 +3856,7 @@ NoNewHeadsThreshold = '40s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -3927,6 +3950,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -4019,6 +4043,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -4112,6 +4137,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -4205,6 +4231,7 @@ NoNewHeadsThreshold = '6m0s' RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 15 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -4298,6 +4325,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '40s' [Transactions] ForwardersEnabled = false @@ -4391,6 +4419,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '40s' [Transactions] ForwardersEnabled = false @@ -4483,6 +4512,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -4576,6 +4606,7 @@ NoNewHeadsThreshold = '12m0s' RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -4669,6 +4700,7 @@ NoNewHeadsThreshold = '40s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -4762,6 +4794,7 @@ NoNewHeadsThreshold = '12m0s' RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -4855,6 +4888,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -4947,6 +4981,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -5040,6 +5075,7 @@ NoNewHeadsThreshold = '40s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '15m0s' [Transactions] ForwardersEnabled = false @@ -5133,6 +5169,7 @@ NoNewHeadsThreshold = '3m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '2m0s' [Transactions] ForwardersEnabled = false @@ -5227,6 +5264,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -5320,6 +5358,7 @@ NoNewHeadsThreshold = '1m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '1m0s' [Transactions] ForwardersEnabled = false @@ -5413,6 +5452,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '1m0s' [Transactions] ForwardersEnabled = false @@ -5506,6 +5546,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '1m0s' [Transactions] ForwardersEnabled = false @@ -5599,6 +5640,7 @@ NoNewHeadsThreshold = '1m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '1m0s' [Transactions] ForwardersEnabled = false @@ -5691,6 +5733,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -5783,6 +5826,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -5875,6 +5919,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -5968,6 +6013,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -6061,6 +6107,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -6153,6 +6200,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '12m0s' [Transactions] ForwardersEnabled = false @@ -6246,6 +6294,7 @@ NoNewHeadsThreshold = '40s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -6339,6 +6388,7 @@ NoNewHeadsThreshold = '40s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '12m0s' [Transactions] ForwardersEnabled = false @@ -6433,6 +6483,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -6527,6 +6578,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -6620,6 +6672,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -6713,6 +6766,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -6806,6 +6860,7 @@ NoNewHeadsThreshold = '0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -6899,6 +6954,7 @@ NoNewHeadsThreshold = '3m0s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -6992,6 +7048,7 @@ NoNewHeadsThreshold = '40s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '15m0s' [Transactions] ForwardersEnabled = false @@ -7085,6 +7142,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -7178,6 +7236,7 @@ NoNewHeadsThreshold = '30s' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' [Transactions] ForwardersEnabled = false @@ -7438,6 +7497,15 @@ The latest finalized block on chain is 64, so block 63 is the latest finalized f Block 64 will be treated as finalized by CL Node only when chain's latest finalized block is 65. As chain finalizes blocks in batches of 32, CL Node has to wait for a whole new batch to be finalized to treat block 64 as finalized. +### NoNewFinalizedHeadsThreshold +```toml +NoNewFinalizedHeadsThreshold = '0' # Default +``` +NoNewFinalizedHeadsThreshold controls how long to wait for new finalized block before `NodePool` marks rpc endpoints as +out-of-sync. Only applicable if `FinalityTagEnabled=true` + +Set to zero to disable. + ## EVM.Transactions ```toml [EVM.Transactions] diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index 327e84c51b..56ce1ea7ba 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -333,6 +333,7 @@ OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '9m0s' [EVM.Transactions] ForwardersEnabled = false diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 724b59e52d..e534c67a2f 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -333,6 +333,7 @@ OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '9m0s' [EVM.Transactions] ForwardersEnabled = false diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index e0eefcba85..29bc189e56 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -333,6 +333,7 @@ OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '9m0s' [EVM.Transactions] ForwardersEnabled = false diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 1955e919da..60c42c7c39 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -323,6 +323,7 @@ OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '9m0s' [EVM.Transactions] ForwardersEnabled = false diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index 3ba20f6f9d..719bb8bcc4 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -330,6 +330,7 @@ OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '9m0s' [EVM.Transactions] ForwardersEnabled = false From c3dc764bba9e1c57b3f7933bcb804a1740fab695 Mon Sep 17 00:00:00 2001 From: Cedric Date: Tue, 30 Jul 2024 11:53:42 +0100 Subject: [PATCH 005/432] [fix] Race in workflow engine (#13879) * [fix] Fix race in workflow engine * Remove unused mutex --- core/services/workflows/engine.go | 6 +++--- core/services/workflows/models.go | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index ed5daaf210..a5fb9a25ea 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -333,7 +333,7 @@ func (e *Engine) registerTrigger(ctx context.Context, t *triggerCapability, trig return err } - t.config = tc + t.config.Store(tc) triggerRegRequest := capabilities.CapabilityRequest{ Metadata: capabilities.RequestMetadata{ @@ -343,7 +343,7 @@ func (e *Engine) registerTrigger(ctx context.Context, t *triggerCapability, trig WorkflowName: e.workflow.name, WorkflowOwner: e.workflow.owner, }, - Config: tc, + Config: t.config.Load(), Inputs: triggerInputs, } eventsCh, err := t.trigger.RegisterTrigger(ctx, triggerRegRequest) @@ -788,7 +788,7 @@ func (e *Engine) deregisterTrigger(ctx context.Context, t *triggerCapability, tr WorkflowOwner: e.workflow.owner, }, Inputs: triggerInputs, - Config: t.config, + Config: t.config.Load(), } // if t.trigger == nil, then we haven't initialized the workflow diff --git a/core/services/workflows/models.go b/core/services/workflows/models.go index 8d970dfa94..1ff77225c4 100644 --- a/core/services/workflows/models.go +++ b/core/services/workflows/models.go @@ -3,6 +3,7 @@ package workflows import ( "errors" "fmt" + "sync/atomic" "github.com/dominikbraun/graph" @@ -86,7 +87,8 @@ type step struct { type triggerCapability struct { workflows.StepDefinition trigger capabilities.TriggerCapability - config *values.Map + + config atomic.Pointer[values.Map] } func Parse(yamlWorkflow string) (*workflow, error) { From 3fc7285a000889b5654d87b54f3d5aa474b9f415 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 30 Jul 2024 17:44:30 +0200 Subject: [PATCH 006/432] fix releases path in notification (#13959) --- .../workflows/client-compatibility-tests.yml | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 956da46e77..47e0b8de62 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -192,8 +192,7 @@ jobs: implementations_arr=() # we use 100 days since we really want the latest one, and it's highly improbable there won't be a release in last 100 days chainlink_version=$(ghlatestreleasechecker "smartcontractkit/chainlink" 100) - echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT - cl_ref_path="release" + cl_ref_path="releases" elif [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then echo "Fetching Chainlink version from input" if [ -n "${{ github.event.inputs.chainlinkVersion }}" ]; then @@ -202,35 +201,32 @@ jobs: if [[ "$chainlink_version" =~ ^[0-9a-f]{40}$ ]]; then cl_ref_path="commit" else - cl_ref_path="release" + cl_ref_path="releases" fi else echo "Chainlink version not provided in input. Using latest commit SHA." chainlink_version=${{ github.sha }} cl_ref_path="commit" fi - echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT - echo "cl_ref_path=$cl_ref_path" >> $GITHUB_OUTPUT elif [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then echo "Fetching Chainlink version from PR's head commit" chainlink_version="${{ github.event.pull_request.head.sha }}" - echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT - echo "cl_ref_path=commit" >> $GITHUB_OUTPUT + cl_ref_path="commit" elif [ "$GITHUB_EVENT_NAME" = "merge_queue" ]; then echo "Fetching Chainlink version from merge queue's head commit" chainlink_version="${{ github.event.merge_group.head_sha }}" - echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT - echo "cl_ref_path=commit" >> $GITHUB_OUTPUT + cl_ref_path="commit" elif [ "$GITHUB_REF_TYPE" = "tag" ]; then echo "Fetching Chainlink version from tag" chainlink_version="${{ github.ref_name }}" - echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT - echo "cl_ref_path=release" >> $GITHUB_OUTPUT + cl_ref_path="releases" else echo "Unsupported trigger event. It's probably an issue with the pipeline definition. Please reach out to the Test Tooling team." exit 1 fi echo "Will use following Chainlink version: $chainlink_version" + echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT + echo "cl_ref_path=$cl_ref_path" >> $GITHUB_OUTPUT - name: Get image count id: get-image-count run: | From 9e8ebc27ee8b8e798cf8a31ffd77e1b14a8f6b83 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Wed, 31 Jul 2024 03:45:50 -0400 Subject: [PATCH 007/432] [TT-1422] Properly Handles Group Slack Handle (#13950) --- .github/workflows/client-compatibility-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 47e0b8de62..7d03348898 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -676,7 +676,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "${{ contains(join(needs.*.result, ','), 'failure') && format('Some tests failed, notifying <{0}>', secrets.COMPAT_SLACK_NOTIFICATION_HANDLE) || 'All Good!' }}" + "text": "${{ contains(join(needs.*.result, ','), 'failure') && format('Some tests failed, notifying ', secrets.COMPAT_SLACK_NOTIFICATION_HANDLE) || 'All Good!' }}" } }, { From 9e74eee9d415b386db33bdf2dd44facc82cd3551 Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Wed, 31 Jul 2024 10:23:21 +0200 Subject: [PATCH 008/432] Port ccip onchain to chainlink (#13941) * init port * install dependencies and create snapshots * add to foundry ci * fix readme * fix ci & add changeset * fix fuzz exclusion * update license & solhint * add ccip solidity CI * fix coverage pruning * Update LICENSE * Update LICENSE * fix job name --- .../detect-solidity-file-changes/action.yml | 19 +- .../action.yml | 31 + .github/workflows/solidity-foundry.yml | 85 +- .github/workflows/solidity-hardhat.yml | 2 +- .github/workflows/solidity.yml | 22 +- LICENSE | 15 +- .../.changeset/three-stingrays-compete.md | 5 + contracts/.prettierignore | 3 +- contracts/.prettierrc.js | 1 + contracts/.solhintignore | 4 +- contracts/GNUmakefile | 23 +- contracts/README.md | 6 +- contracts/STYLE_GUIDE.md | 16 +- contracts/foundry.toml | 20 + contracts/gas-snapshots/ccip.gas-snapshot | 943 +++++ .../liquiditymanager.gas-snapshot | 48 + contracts/hardhat.config.ts | 3 +- contracts/package.json | 4 +- contracts/pnpm-lock.yaml | 791 +++- contracts/remappings.txt | 1 + contracts/scripts/ccip_lcov_prune | 29 + contracts/scripts/native_solc_compile_all | 2 +- .../scripts/native_solc_compile_all_ccip | 97 + .../native_solc_compile_all_liquiditymanager | 67 + contracts/src/v0.8/ccip/ARMProxy.sol | 74 + .../src/v0.8/ccip/AggregateRateLimiter.sol | 92 + contracts/src/v0.8/ccip/CommitStore.sol | 314 ++ contracts/src/v0.8/ccip/LICENSE-MIT.md | 21 + contracts/src/v0.8/ccip/LICENSE.md | 56 + .../v0.8/ccip/MultiAggregateRateLimiter.sol | 272 ++ contracts/src/v0.8/ccip/NonceManager.sol | 147 + contracts/src/v0.8/ccip/PriceRegistry.sol | 888 +++++ contracts/src/v0.8/ccip/RMN.sol | 964 +++++ contracts/src/v0.8/ccip/Router.sol | 290 ++ .../ccip/applications/CCIPClientExample.sol | 173 + .../v0.8/ccip/applications/CCIPReceiver.sol | 59 + .../ccip/applications/DefensiveExample.sol | 117 + .../ccip/applications/EtherSenderReceiver.sol | 180 + .../v0.8/ccip/applications/PingPongDemo.sol | 102 + .../ccip/applications/SelfFundedPingPong.sol | 67 + .../src/v0.8/ccip/applications/TokenProxy.sol | 87 + .../src/v0.8/ccip/capability/CCIPConfig.sol | 476 +++ .../interfaces/ICapabilitiesRegistry.sol | 31 + .../interfaces/IOCR3ConfigEncoder.sol | 11 + .../capability/libraries/CCIPConfigTypes.sol | 57 + .../ccip/docs/multi-chain-overview-ocr3.png | Bin 0 -> 818615 bytes .../ccip/docs/multi-chain-overview.drawio | 2060 ++++++++++ .../interfaces/IAny2EVMMessageReceiver.sol | 15 + .../v0.8/ccip/interfaces/IAny2EVMOffRamp.sol | 9 + .../src/v0.8/ccip/interfaces/ICommitStore.sol | 17 + .../v0.8/ccip/interfaces/IEVM2AnyOnRamp.sol | 15 + .../ccip/interfaces/IEVM2AnyOnRampClient.sol | 42 + .../v0.8/ccip/interfaces/IGetCCIPAdmin.sol | 8 + .../ccip/interfaces/IMessageInterceptor.sol | 22 + .../v0.8/ccip/interfaces/INonceManager.sol | 23 + contracts/src/v0.8/ccip/interfaces/IOwner.sol | 8 + contracts/src/v0.8/ccip/interfaces/IPool.sol | 35 + .../v0.8/ccip/interfaces/IPoolPriorTo1_5.sol | 46 + .../v0.8/ccip/interfaces/IPriceRegistry.sol | 109 + contracts/src/v0.8/ccip/interfaces/IRMN.sol | 21 + .../src/v0.8/ccip/interfaces/IRouter.sol | 35 + .../v0.8/ccip/interfaces/IRouterClient.sol | 37 + .../ccip/interfaces/ITokenAdminRegistry.sol | 12 + .../v0.8/ccip/interfaces/IWrappedNative.sol | 10 + .../interfaces/automation/ILinkAvailable.sol | 8 + contracts/src/v0.8/ccip/libraries/Client.sol | 55 + .../src/v0.8/ccip/libraries/Internal.sol | 319 ++ .../v0.8/ccip/libraries/MerkleMultiProof.sol | 113 + contracts/src/v0.8/ccip/libraries/Pool.sol | 58 + .../src/v0.8/ccip/libraries/RateLimiter.sol | 157 + .../ccip/libraries/USDPriceWith18Decimals.sol | 45 + contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol | 323 ++ contracts/src/v0.8/ccip/ocr/OCR2Abstract.sol | 122 + contracts/src/v0.8/ccip/ocr/OCR2Base.sol | 291 ++ .../src/v0.8/ccip/ocr/OCR2BaseNoChecks.sol | 242 ++ .../v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 914 +++++ .../src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol | 721 ++++ .../v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol | 339 ++ .../src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol | 916 +++++ .../v0.8/ccip/pools/BurnFromMintTokenPool.sol | 38 + .../src/v0.8/ccip/pools/BurnMintTokenPool.sol | 30 + .../ccip/pools/BurnMintTokenPoolAbstract.sol | 49 + .../ccip/pools/BurnMintTokenPoolAndProxy.sol | 62 + .../ccip/pools/BurnWithFromMintTokenPool.sol | 38 + .../src/v0.8/ccip/pools/LegacyPoolWrapper.sol | 81 + .../v0.8/ccip/pools/LockReleaseTokenPool.sol | 151 + .../pools/LockReleaseTokenPoolAndProxy.sol | 159 + contracts/src/v0.8/ccip/pools/TokenPool.sol | 424 ++ .../ccip/pools/USDC/IMessageTransmitter.sol | 46 + .../v0.8/ccip/pools/USDC/ITokenMessenger.sol | 65 + .../v0.8/ccip/pools/USDC/USDCTokenPool.sol | 241 ++ contracts/src/v0.8/ccip/test/BaseTest.t.sol | 125 + .../src/v0.8/ccip/test/NonceManager.t.sol | 649 ++++ contracts/src/v0.8/ccip/test/README.md | 89 + contracts/src/v0.8/ccip/test/TokenSetup.t.sol | 179 + contracts/src/v0.8/ccip/test/WETH9.sol | 82 + .../test/applications/DefensiveExample.t.sol | 97 + .../applications/EtherSenderReceiver.t.sol | 718 ++++ .../test/applications/ImmutableExample.t.sol | 61 + .../ccip/test/applications/PingPongDemo.t.sol | 121 + .../applications/SelfFundedPingPong.t.sol | 99 + .../ccip/test/applications/TokenProxy.t.sol | 211 + .../src/v0.8/ccip/test/arm/ARMProxy.t.sol | 43 + .../ccip/test/arm/ARMProxy_standalone.t.sol | 78 + contracts/src/v0.8/ccip/test/arm/RMN.t.sol | 1068 +++++ .../src/v0.8/ccip/test/arm/RMNSetup.t.sol | 144 + .../v0.8/ccip/test/arm/RMN_benchmark.t.sol | 217 ++ .../ccip/test/attacks/onRamp/FacadeClient.sol | 54 + .../MultiOnRampTokenPoolReentrancy.t.sol | 118 + .../onRamp/OnRampTokenPoolReentrancy.t.sol | 116 + .../onRamp/ReentrantMaliciousTokenPool.sol | 50 + .../ccip/test/capability/CCIPConfig.t.sol | 1681 ++++++++ .../ccip/test/commitStore/CommitStore.t.sol | 618 +++ .../src/v0.8/ccip/test/e2e/End2End.t.sol | 116 + .../v0.8/ccip/test/e2e/MultiRampsEnd2End.sol | 260 ++ .../helpers/AggregateRateLimiterHelper.sol | 19 + .../test/helpers/BurnMintERC677Helper.sol | 18 + .../test/helpers/BurnMintMultiTokenPool.sol | 56 + .../ccip/test/helpers/CCIPConfigHelper.sol | 66 + .../ccip/test/helpers/CommitStoreHelper.sol | 13 + .../helpers/EVM2EVMMultiOffRampHelper.sol | 103 + .../test/helpers/EVM2EVMMultiOnRampHelper.sol | 12 + .../test/helpers/EVM2EVMOffRampHelper.sol | 59 + .../ccip/test/helpers/EVM2EVMOnRampHelper.sol | 47 + .../helpers/EtherSenderReceiverHelper.sol | 21 + .../ccip/test/helpers/IgnoreContractSize.sol | 10 + .../MaybeRevertingBurnMintTokenPool.sol | 70 + .../v0.8/ccip/test/helpers/MerkleHelper.sol | 52 + .../v0.8/ccip/test/helpers/MessageHasher.sol | 71 + .../test/helpers/MessageInterceptorHelper.sol | 30 + .../MultiAggregateRateLimiterHelper.sol | 17 + .../ccip/test/helpers/MultiOCR3Helper.sol | 45 + .../v0.8/ccip/test/helpers/MultiTokenPool.sol | 420 ++ .../src/v0.8/ccip/test/helpers/OCR2Helper.sol | 38 + .../ccip/test/helpers/OCR2NoChecksHelper.sol | 38 + .../ccip/test/helpers/PriceRegistryHelper.sol | 72 + .../ccip/test/helpers/RateLimiterHelper.sol | 36 + .../v0.8/ccip/test/helpers/ReportCodec.sol | 18 + .../ccip/test/helpers/TokenPoolHelper.sol | 42 + .../ccip/test/helpers/USDCTokenPoolHelper.sol | 21 + .../helpers/receivers/ConformingReceiver.sol | 15 + .../receivers/MaybeRevertMessageReceiver.sol | 54 + .../MaybeRevertMessageReceiverNo165.sol | 27 + .../helpers/receivers/ReentrancyAbuser.sol | 40 + .../receivers/ReentrancyAbuserMultiRamp.sol | 44 + .../ccip/test/legacy/BurnMintTokenPool1_2.sol | 353 ++ .../ccip/test/legacy/BurnMintTokenPool1_4.sol | 402 ++ .../ccip/test/legacy/TokenPoolAndProxy.t.sol | 771 ++++ .../test/libraries/MerkleMultiProof.t.sol | 196 + .../ccip/test/libraries/RateLimiter.t.sol | 297 ++ .../v0.8/ccip/test/mocks/MockCommitStore.sol | 42 + .../test/mocks/MockE2EUSDCTokenMessenger.sol | 103 + .../test/mocks/MockE2EUSDCTransmitter.sol | 168 + .../src/v0.8/ccip/test/mocks/MockRMN.sol | 55 + .../src/v0.8/ccip/test/mocks/MockRMN1_0.sol | 91 + .../src/v0.8/ccip/test/mocks/MockRouter.sol | 148 + .../test/mocks/MockUSDCTokenMessenger.sol | 52 + .../IMessageTransmitterWithRelay.sol | 55 + .../ccip/test/mocks/test/MockRouterTest.t.sol | 68 + .../v0.8/ccip/test/ocr/MultiOCR3Base.t.sol | 921 +++++ .../ccip/test/ocr/MultiOCR3BaseSetup.t.sol | 113 + .../src/v0.8/ccip/test/ocr/OCR2Base.t.sol | 305 ++ .../v0.8/ccip/test/ocr/OCR2BaseNoChecks.t.sol | 208 + .../src/v0.8/ccip/test/ocr/OCR2Setup.t.sol | 31 + .../test/offRamp/EVM2EVMMultiOffRamp.t.sol | 3429 +++++++++++++++++ .../offRamp/EVM2EVMMultiOffRampSetup.t.sol | 491 +++ .../ccip/test/offRamp/EVM2EVMOffRamp.t.sol | 1986 ++++++++++ .../test/offRamp/EVM2EVMOffRampSetup.t.sol | 264 ++ .../ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol | 720 ++++ .../test/onRamp/EVM2EVMMultiOnRampSetup.t.sol | 180 + .../v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol | 1986 ++++++++++ .../ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol | 261 ++ .../test/pools/BurnFromMintTokenPool.t.sol | 104 + .../v0.8/ccip/test/pools/BurnMintSetup.t.sol | 43 + .../ccip/test/pools/BurnMintTokenPool.t.sol | 171 + .../pools/BurnWithFromMintTokenPool.t.sol | 105 + .../test/pools/LockReleaseTokenPool.t.sol | 512 +++ .../src/v0.8/ccip/test/pools/TokenPool.t.sol | 767 ++++ .../v0.8/ccip/test/pools/USDCTokenPool.t.sol | 690 ++++ .../test/priceRegistry/PriceRegistry.t.sol | 2542 ++++++++++++ .../rateLimiter/AggregateRateLimiter.t.sol | 234 ++ .../MultiAggregateRateLimiter.t.sol | 1201 ++++++ .../src/v0.8/ccip/test/router/Router.t.sol | 889 +++++ .../v0.8/ccip/test/router/RouterSetup.t.sol | 47 + .../RegistryModuleOwnerCustom.t.sol | 104 + .../TokenAdminRegistry.t.sol | 393 ++ .../RegistryModuleOwnerCustom.sol | 54 + .../tokenAdminRegistry/TokenAdminRegistry.sol | 223 ++ .../src/v0.8/ccip/v1.4-CCIP-License-grants.md | 5 + .../liquiditymanager/LiquidityManager.sol | 575 +++ .../ArbitrumL1BridgeAdapter.sol | 175 + .../ArbitrumL2BridgeAdapter.sol | 78 + .../OptimismL1BridgeAdapter.sol | 196 + .../OptimismL2BridgeAdapter.sol | 119 + .../OptimismL1BridgeAdapterEncoder.sol | 21 + .../liquiditymanager/interfaces/IBridge.sol | 49 + .../interfaces/ILiquidityContainer.sol | 16 + .../interfaces/ILiquidityManager.sol | 62 + .../IAbstractArbitrumTokenGateway.sol | 7 + .../interfaces/arbitrum/IArbRollupCore.sol | 7 + .../interfaces/arbitrum/IArbSys.sol | 7 + .../arbitrum/IArbitrumGatewayRouter.sol | 7 + .../interfaces/arbitrum/IArbitrumInbox.sol | 7 + .../arbitrum/IArbitrumL1GatewayRouter.sol | 7 + .../arbitrum/IArbitrumTokenGateway.sol | 7 + .../arbitrum/IL2ArbitrumGateway.sol | 7 + .../arbitrum/IL2ArbitrumMessenger.sol | 7 + .../interfaces/arbitrum/INodeInterface.sol | 7 + .../interfaces/optimism/DisputeTypes.sol | 23 + .../IOptimismCrossDomainMessenger.sol | 31 + .../optimism/IOptimismDisputeGameFactory.sol | 31 + .../optimism/IOptimismL1StandardBridge.sol | 18 + .../optimism/IOptimismL2OutputOracle.sol | 19 + .../optimism/IOptimismL2ToL1MessagePasser.sol | 23 + .../interfaces/optimism/IOptimismPortal.sol | 26 + .../interfaces/optimism/IOptimismPortal2.sol | 12 + .../optimism/IOptimismStandardBridge.sol | 40 + .../interfaces/optimism/Types.sol | 72 + .../liquiditymanager/ocr/OCR3Abstract.sol | 108 + .../v0.8/liquiditymanager/ocr/OCR3Base.sol | 284 ++ .../test/LiquidityManager.t.sol | 945 +++++ .../test/LiquidityManagerBaseTest.t.sol | 43 + .../ArbitrumL1BridgeAdapter.t.sol | 98 + .../ArbitrumL2BridgeAdapter.t.sol | 51 + .../OptimismL1BridgeAdapter.t.sol | 129 + .../test/helpers/LiquidityManagerHelper.sol | 22 + .../test/helpers/OCR3Helper.sol | 41 + .../test/helpers/ReportEncoder.sol | 10 + .../test/mocks/MockBridgeAdapter.sol | 191 + .../liquiditymanager/test/mocks/NoOpOCR3.sol | 18 + .../liquiditymanager/test/ocr/OCR3Base.t.sol | 337 ++ .../liquiditymanager/test/ocr/OCR3Setup.t.sol | 34 + .../utils/introspection/ERC165Checker.sol | 127 + 233 files changed, 49601 insertions(+), 87 deletions(-) create mode 100644 .github/actions/detect-solidity-readonly-file-changes/action.yml create mode 100644 contracts/.changeset/three-stingrays-compete.md create mode 100644 contracts/gas-snapshots/ccip.gas-snapshot create mode 100644 contracts/gas-snapshots/liquiditymanager.gas-snapshot create mode 100755 contracts/scripts/ccip_lcov_prune create mode 100755 contracts/scripts/native_solc_compile_all_ccip create mode 100755 contracts/scripts/native_solc_compile_all_liquiditymanager create mode 100644 contracts/src/v0.8/ccip/ARMProxy.sol create mode 100644 contracts/src/v0.8/ccip/AggregateRateLimiter.sol create mode 100644 contracts/src/v0.8/ccip/CommitStore.sol create mode 100644 contracts/src/v0.8/ccip/LICENSE-MIT.md create mode 100644 contracts/src/v0.8/ccip/LICENSE.md create mode 100644 contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol create mode 100644 contracts/src/v0.8/ccip/NonceManager.sol create mode 100644 contracts/src/v0.8/ccip/PriceRegistry.sol create mode 100644 contracts/src/v0.8/ccip/RMN.sol create mode 100644 contracts/src/v0.8/ccip/Router.sol create mode 100644 contracts/src/v0.8/ccip/applications/CCIPClientExample.sol create mode 100644 contracts/src/v0.8/ccip/applications/CCIPReceiver.sol create mode 100644 contracts/src/v0.8/ccip/applications/DefensiveExample.sol create mode 100644 contracts/src/v0.8/ccip/applications/EtherSenderReceiver.sol create mode 100644 contracts/src/v0.8/ccip/applications/PingPongDemo.sol create mode 100644 contracts/src/v0.8/ccip/applications/SelfFundedPingPong.sol create mode 100644 contracts/src/v0.8/ccip/applications/TokenProxy.sol create mode 100644 contracts/src/v0.8/ccip/capability/CCIPConfig.sol create mode 100644 contracts/src/v0.8/ccip/capability/interfaces/ICapabilitiesRegistry.sol create mode 100644 contracts/src/v0.8/ccip/capability/interfaces/IOCR3ConfigEncoder.sol create mode 100644 contracts/src/v0.8/ccip/capability/libraries/CCIPConfigTypes.sol create mode 100644 contracts/src/v0.8/ccip/docs/multi-chain-overview-ocr3.png create mode 100644 contracts/src/v0.8/ccip/docs/multi-chain-overview.drawio create mode 100644 contracts/src/v0.8/ccip/interfaces/IAny2EVMMessageReceiver.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IAny2EVMOffRamp.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/ICommitStore.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRamp.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRampClient.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IGetCCIPAdmin.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IMessageInterceptor.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/INonceManager.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IOwner.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IPool.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IPoolPriorTo1_5.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IRMN.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IRouter.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IRouterClient.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/ITokenAdminRegistry.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/IWrappedNative.sol create mode 100644 contracts/src/v0.8/ccip/interfaces/automation/ILinkAvailable.sol create mode 100644 contracts/src/v0.8/ccip/libraries/Client.sol create mode 100644 contracts/src/v0.8/ccip/libraries/Internal.sol create mode 100644 contracts/src/v0.8/ccip/libraries/MerkleMultiProof.sol create mode 100644 contracts/src/v0.8/ccip/libraries/Pool.sol create mode 100644 contracts/src/v0.8/ccip/libraries/RateLimiter.sol create mode 100644 contracts/src/v0.8/ccip/libraries/USDPriceWith18Decimals.sol create mode 100644 contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol create mode 100644 contracts/src/v0.8/ccip/ocr/OCR2Abstract.sol create mode 100644 contracts/src/v0.8/ccip/ocr/OCR2Base.sol create mode 100644 contracts/src/v0.8/ccip/ocr/OCR2BaseNoChecks.sol create mode 100644 contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol create mode 100644 contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol create mode 100644 contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol create mode 100644 contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol create mode 100644 contracts/src/v0.8/ccip/pools/BurnFromMintTokenPool.sol create mode 100644 contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol create mode 100644 contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol create mode 100644 contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol create mode 100644 contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol create mode 100644 contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol create mode 100644 contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol create mode 100644 contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol create mode 100644 contracts/src/v0.8/ccip/pools/TokenPool.sol create mode 100644 contracts/src/v0.8/ccip/pools/USDC/IMessageTransmitter.sol create mode 100644 contracts/src/v0.8/ccip/pools/USDC/ITokenMessenger.sol create mode 100644 contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol create mode 100644 contracts/src/v0.8/ccip/test/BaseTest.t.sol create mode 100644 contracts/src/v0.8/ccip/test/NonceManager.t.sol create mode 100644 contracts/src/v0.8/ccip/test/README.md create mode 100644 contracts/src/v0.8/ccip/test/TokenSetup.t.sol create mode 100644 contracts/src/v0.8/ccip/test/WETH9.sol create mode 100644 contracts/src/v0.8/ccip/test/applications/DefensiveExample.t.sol create mode 100644 contracts/src/v0.8/ccip/test/applications/EtherSenderReceiver.t.sol create mode 100644 contracts/src/v0.8/ccip/test/applications/ImmutableExample.t.sol create mode 100644 contracts/src/v0.8/ccip/test/applications/PingPongDemo.t.sol create mode 100644 contracts/src/v0.8/ccip/test/applications/SelfFundedPingPong.t.sol create mode 100644 contracts/src/v0.8/ccip/test/applications/TokenProxy.t.sol create mode 100644 contracts/src/v0.8/ccip/test/arm/ARMProxy.t.sol create mode 100644 contracts/src/v0.8/ccip/test/arm/ARMProxy_standalone.t.sol create mode 100644 contracts/src/v0.8/ccip/test/arm/RMN.t.sol create mode 100644 contracts/src/v0.8/ccip/test/arm/RMNSetup.t.sol create mode 100644 contracts/src/v0.8/ccip/test/arm/RMN_benchmark.t.sol create mode 100644 contracts/src/v0.8/ccip/test/attacks/onRamp/FacadeClient.sol create mode 100644 contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol create mode 100644 contracts/src/v0.8/ccip/test/attacks/onRamp/OnRampTokenPoolReentrancy.t.sol create mode 100644 contracts/src/v0.8/ccip/test/attacks/onRamp/ReentrantMaliciousTokenPool.sol create mode 100644 contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol create mode 100644 contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol create mode 100644 contracts/src/v0.8/ccip/test/e2e/End2End.t.sol create mode 100644 contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/AggregateRateLimiterHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/BurnMintERC677Helper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/BurnMintMultiTokenPool.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/CCIPConfigHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/CommitStoreHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOnRampHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/EVM2EVMOffRampHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/EVM2EVMOnRampHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/EtherSenderReceiverHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/IgnoreContractSize.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/MerkleHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/MessageHasher.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/MessageInterceptorHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/MultiAggregateRateLimiterHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/MultiOCR3Helper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/MultiTokenPool.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/OCR2Helper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/OCR2NoChecksHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/PriceRegistryHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/RateLimiterHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/ReportCodec.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/TokenPoolHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/USDCTokenPoolHelper.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/receivers/ConformingReceiver.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/receivers/MaybeRevertMessageReceiverNo165.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol create mode 100644 contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuserMultiRamp.sol create mode 100644 contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_2.sol create mode 100644 contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_4.sol create mode 100644 contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol create mode 100644 contracts/src/v0.8/ccip/test/libraries/MerkleMultiProof.t.sol create mode 100644 contracts/src/v0.8/ccip/test/libraries/RateLimiter.t.sol create mode 100644 contracts/src/v0.8/ccip/test/mocks/MockCommitStore.sol create mode 100644 contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTokenMessenger.sol create mode 100644 contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTransmitter.sol create mode 100644 contracts/src/v0.8/ccip/test/mocks/MockRMN.sol create mode 100644 contracts/src/v0.8/ccip/test/mocks/MockRMN1_0.sol create mode 100644 contracts/src/v0.8/ccip/test/mocks/MockRouter.sol create mode 100644 contracts/src/v0.8/ccip/test/mocks/MockUSDCTokenMessenger.sol create mode 100644 contracts/src/v0.8/ccip/test/mocks/interfaces/IMessageTransmitterWithRelay.sol create mode 100644 contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol create mode 100644 contracts/src/v0.8/ccip/test/ocr/MultiOCR3Base.t.sol create mode 100644 contracts/src/v0.8/ccip/test/ocr/MultiOCR3BaseSetup.t.sol create mode 100644 contracts/src/v0.8/ccip/test/ocr/OCR2Base.t.sol create mode 100644 contracts/src/v0.8/ccip/test/ocr/OCR2BaseNoChecks.t.sol create mode 100644 contracts/src/v0.8/ccip/test/ocr/OCR2Setup.t.sol create mode 100644 contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol create mode 100644 contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol create mode 100644 contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol create mode 100644 contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol create mode 100644 contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol create mode 100644 contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol create mode 100644 contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol create mode 100644 contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol create mode 100644 contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool.t.sol create mode 100644 contracts/src/v0.8/ccip/test/pools/BurnMintSetup.t.sol create mode 100644 contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol create mode 100644 contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool.t.sol create mode 100644 contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol create mode 100644 contracts/src/v0.8/ccip/test/pools/TokenPool.t.sol create mode 100644 contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol create mode 100644 contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol create mode 100644 contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol create mode 100644 contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol create mode 100644 contracts/src/v0.8/ccip/test/router/Router.t.sol create mode 100644 contracts/src/v0.8/ccip/test/router/RouterSetup.t.sol create mode 100644 contracts/src/v0.8/ccip/test/tokenAdminRegistry/RegistryModuleOwnerCustom.t.sol create mode 100644 contracts/src/v0.8/ccip/test/tokenAdminRegistry/TokenAdminRegistry.t.sol create mode 100644 contracts/src/v0.8/ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol create mode 100644 contracts/src/v0.8/ccip/tokenAdminRegistry/TokenAdminRegistry.sol create mode 100644 contracts/src/v0.8/ccip/v1.4-CCIP-License-grants.md create mode 100644 contracts/src/v0.8/liquiditymanager/LiquidityManager.sol create mode 100644 contracts/src/v0.8/liquiditymanager/bridge-adapters/ArbitrumL1BridgeAdapter.sol create mode 100644 contracts/src/v0.8/liquiditymanager/bridge-adapters/ArbitrumL2BridgeAdapter.sol create mode 100644 contracts/src/v0.8/liquiditymanager/bridge-adapters/OptimismL1BridgeAdapter.sol create mode 100644 contracts/src/v0.8/liquiditymanager/bridge-adapters/OptimismL2BridgeAdapter.sol create mode 100644 contracts/src/v0.8/liquiditymanager/encoders/OptimismL1BridgeAdapterEncoder.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/IBridge.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/ILiquidityContainer.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/ILiquidityManager.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IAbstractArbitrumTokenGateway.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbRollupCore.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbSys.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumGatewayRouter.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumInbox.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumL1GatewayRouter.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumTokenGateway.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IL2ArbitrumGateway.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IL2ArbitrumMessenger.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/INodeInterface.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/optimism/DisputeTypes.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismCrossDomainMessenger.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismDisputeGameFactory.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismL1StandardBridge.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismL2OutputOracle.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismL2ToL1MessagePasser.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismPortal.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismPortal2.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismStandardBridge.sol create mode 100644 contracts/src/v0.8/liquiditymanager/interfaces/optimism/Types.sol create mode 100644 contracts/src/v0.8/liquiditymanager/ocr/OCR3Abstract.sol create mode 100644 contracts/src/v0.8/liquiditymanager/ocr/OCR3Base.sol create mode 100644 contracts/src/v0.8/liquiditymanager/test/LiquidityManager.t.sol create mode 100644 contracts/src/v0.8/liquiditymanager/test/LiquidityManagerBaseTest.t.sol create mode 100644 contracts/src/v0.8/liquiditymanager/test/bridge-adapters/ArbitrumL1BridgeAdapter.t.sol create mode 100644 contracts/src/v0.8/liquiditymanager/test/bridge-adapters/ArbitrumL2BridgeAdapter.t.sol create mode 100644 contracts/src/v0.8/liquiditymanager/test/bridge-adapters/OptimismL1BridgeAdapter.t.sol create mode 100644 contracts/src/v0.8/liquiditymanager/test/helpers/LiquidityManagerHelper.sol create mode 100644 contracts/src/v0.8/liquiditymanager/test/helpers/OCR3Helper.sol create mode 100644 contracts/src/v0.8/liquiditymanager/test/helpers/ReportEncoder.sol create mode 100644 contracts/src/v0.8/liquiditymanager/test/mocks/MockBridgeAdapter.sol create mode 100644 contracts/src/v0.8/liquiditymanager/test/mocks/NoOpOCR3.sol create mode 100644 contracts/src/v0.8/liquiditymanager/test/ocr/OCR3Base.t.sol create mode 100644 contracts/src/v0.8/liquiditymanager/test/ocr/OCR3Setup.t.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol diff --git a/.github/actions/detect-solidity-file-changes/action.yml b/.github/actions/detect-solidity-file-changes/action.yml index 37cb871d68..b86c91dbb4 100644 --- a/.github/actions/detect-solidity-file-changes/action.yml +++ b/.github/actions/detect-solidity-file-changes/action.yml @@ -1,5 +1,5 @@ -name: 'Detect Changes Composite Action' -description: 'Detects changes in solidity files and fails if read-only files are modified.' +name: 'Detect Solidity File Changes Composite Action' +description: 'Detects changes in solidity files and outputs the result.' outputs: changes: description: 'Whether or not changes were detected' @@ -19,18 +19,3 @@ runs: - '.github/workflows/solidity.yml' - '.github/workflows/solidity-foundry.yml' - '.github/workflows/solidity-wrappers.yml' - read_only_sol: - - 'contracts/src/v0.8/interfaces/**/*' - - 'contracts/src/v0.8/automation/v1_2/**/*' - - 'contracts/src/v0.8/automation/v1_3/**/*' - - 'contracts/src/v0.8/automation/v2_0/**/*' - - - name: Fail if read-only files have changed - if: ${{ steps.changed_files.outputs.read_only_sol == 'true' }} - shell: bash - run: | - echo "One or more read-only Solidity file(s) has changed." - for file in ${{ steps.changed_files.outputs.read_only_sol_files }}; do - echo "$file was changed" - done - exit 1 diff --git a/.github/actions/detect-solidity-readonly-file-changes/action.yml b/.github/actions/detect-solidity-readonly-file-changes/action.yml new file mode 100644 index 0000000000..faca16d53f --- /dev/null +++ b/.github/actions/detect-solidity-readonly-file-changes/action.yml @@ -0,0 +1,31 @@ +name: 'Detect Solidity Readonly Files Changes Composite Action' +description: 'Detects changes in readonly solidity files and fails if they are modified.' +outputs: + changes: + description: 'Whether or not changes were detected' + value: ${{ steps.changed_files.outputs.src }} +runs: + using: 'composite' + steps: + + - name: Filter paths + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: changed_files + with: + list-files: 'csv' + filters: | + read_only_sol: + - 'contracts/src/v0.8/interfaces/**/*' + - 'contracts/src/v0.8/automation/v1_2/**/*' + - 'contracts/src/v0.8/automation/v1_3/**/*' + - 'contracts/src/v0.8/automation/v2_0/**/*' + + - name: Fail if read-only files have changed + if: ${{ steps.changed_files.outputs.read_only_sol == 'true' }} + shell: bash + run: | + echo "One or more read-only Solidity file(s) has changed." + for file in ${{ steps.changed_files.outputs.read_only_sol_files }}; do + echo "$file was changed" + done + exit 1 diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index a7ced0f565..4ec9e42447 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -3,6 +3,8 @@ on: [pull_request] env: FOUNDRY_PROFILE: ci + # Has to match the `make foundry` version in `contracts/GNUmakefile` + FOUNDRY_VERSION: nightly-de33b6af53005037b463318d2628b5cfcaf39916 jobs: changes: @@ -27,7 +29,7 @@ jobs: strategy: fail-fast: false matrix: - product: [automation, functions, keystone, l2ep, llo-feeds, operatorforwarder, shared, vrf] + product: [automation, ccip, functions, keystone, l2ep, liquiditymanager, llo-feeds, operatorforwarder, shared, vrf] needs: [changes] name: Foundry Tests ${{ matrix.product }} # See https://github.com/foundry-rs/foundry/issues/3827 @@ -52,8 +54,7 @@ jobs: if: needs.changes.outputs.changes == 'true' uses: foundry-rs/foundry-toolchain@8f1998e9878d786675189ef566a2e4bf24869773 # v1.2.0 with: - # Has to match the `make foundry` version. - version: nightly-de33b6af53005037b463318d2628b5cfcaf39916 + version: ${{ env.FOUNDRY_VERSION }} - name: Run Forge build if: needs.changes.outputs.changes == 'true' @@ -77,12 +78,36 @@ jobs: - name: Run Forge snapshot if: ${{ !contains(fromJson('["vrf"]'), matrix.product) && !contains(fromJson('["automation"]'), matrix.product) && !contains(fromJson('["keystone"]'), matrix.product) && needs.changes.outputs.changes == 'true' }} run: | - forge snapshot --nmt "testFuzz_\w{1,}?" --check gas-snapshots/${{ matrix.product }}.gas-snapshot + forge snapshot --nmt "test_?Fuzz_\w{1,}?" --check gas-snapshots/${{ matrix.product }}.gas-snapshot id: snapshot working-directory: contracts env: FOUNDRY_PROFILE: ${{ matrix.product }} + - name: Run coverage + if: ${{ contains(fromJson('["ccip"]'), matrix.product) && needs.changes.outputs.changes == 'true' }} + working-directory: contracts + run: forge coverage --report lcov + env: + FOUNDRY_PROFILE: ${{ matrix.product }} + + - name: Prune report + if: ${{ contains(fromJson('["ccip"]'), matrix.product) && needs.changes.outputs.changes == 'true' }} + run: | + sudo apt-get install lcov + ./contracts/scripts/ccip_lcov_prune ./contracts/lcov.info ./lcov.info.pruned + + - name: Report code coverage + if: ${{ contains(fromJson('["ccip"]'), matrix.product) && needs.changes.outputs.changes == 'true' }} + uses: zgosalvez/github-actions-report-lcov@a546f89a65a0cdcd82a92ae8d65e74d450ff3fbc # v4.1.4 + with: + update-comment: true + coverage-files: lcov.info.pruned + minimum-coverage: 98.5 + artifact-name: code-coverage-report + working-directory: ./contracts + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Collect Metrics if: needs.changes.outputs.changes == 'true' id: collect-gha-metrics @@ -94,3 +119,55 @@ jobs: hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} this-job-name: Foundry Tests ${{ matrix.product }} continue-on-error: true + + solidity-forge-fmt: + strategy: + fail-fast: false + matrix: + product: [ ccip ] + needs: [ changes ] + name: Forge fmt ${{ matrix.product }} + # See https://github.com/foundry-rs/foundry/issues/3827 + runs-on: ubuntu-22.04 + + # The if statements for steps after checkout repo is workaround for + # passing required check for PRs that don't have filtered changes. + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + submodules: recursive + + # Only needed because we use the NPM versions of packages + # and not native Foundry. This is to make sure the dependencies + # stay in sync. + - name: Setup NodeJS + if: needs.changes.outputs.changes == 'true' + uses: ./.github/actions/setup-nodejs + + - name: Install Foundry + if: needs.changes.outputs.changes == 'true' + uses: foundry-rs/foundry-toolchain@8f1998e9878d786675189ef566a2e4bf24869773 # v1.2.0 + with: + version: ${{ env.FOUNDRY_VERSION }} + + - name: Run Forge fmt + if: needs.changes.outputs.changes == 'true' + run: | + forge fmt --check + id: fmt + working-directory: contracts + env: + FOUNDRY_PROFILE: ${{ matrix.product }} + + - name: Collect Metrics + if: needs.changes.outputs.changes == 'true' + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: solidity-forge-fmt + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Foundry Tests ${{ matrix.product }} + continue-on-error: true diff --git a/.github/workflows/solidity-hardhat.yml b/.github/workflows/solidity-hardhat.yml index fb6ba6fef4..f28cf49907 100644 --- a/.github/workflows/solidity-hardhat.yml +++ b/.github/workflows/solidity-hardhat.yml @@ -25,7 +25,7 @@ jobs: with: filters: | src: - - 'contracts/src/!(v0.8/(ccip|functions|keystone|l2ep|llo-feeds|transmission|vrf)/**)/**/*' + - 'contracts/src/!(v0.8/(ccip|functions|keystone|l2ep|liquiditymanager|llo-feeds|transmission|vrf)/**)/**/*' - 'contracts/test/**/*' - 'contracts/package.json' - 'contracts/pnpm-lock.yaml' diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index dff35b3cc9..10193bfc2e 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -9,6 +9,18 @@ defaults: shell: bash jobs: + readonly_changes: + name: Detect readonly solidity file changes + runs-on: ubuntu-latest + outputs: + changes: ${{ steps.ch.outputs.changes }} + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - name: Detect readonly solidity file changes + id: ch + uses: ./.github/actions/detect-solidity-readonly-file-changes + changes: name: Detect changes runs-on: ubuntu-latest @@ -31,15 +43,15 @@ jobs: release-version: ${{ steps.release-tag-check.outputs.release-version }} pre-release-version: ${{ steps.release-tag-check.outputs.pre-release-version }} steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Check release tag id: release-tag-check - uses: smartcontractkit/chainlink-github-actions/release/release-tag-check@2031e56eb4edb8115ce8ba07cbbfb457149d865d # v2.3.8 + uses: smartcontractkit/chainlink-github-actions/release/release-tag-check@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 env: # Match semver git tags with a "contracts-" prefix. RELEASE_REGEX: '^contracts-v[0-9]+\.[0-9]+\.[0-9]+$' PRE_RELEASE_REGEX: '^contracts-v[0-9]+\.[0-9]+\.[0-9]+-(.+)$' - # Get the version by stripping the "contracts-v" prefix. + # Get the version by stripping the "contracts-v" prefix. VERSION_PREFIX: 'contracts-v' prepublish-test: @@ -171,7 +183,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Setup NodeJS uses: ./.github/actions/setup-nodejs @@ -211,7 +223,7 @@ jobs: contents: write steps: - name: Checkout the repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Setup NodeJS uses: ./.github/actions/setup-nodejs diff --git a/LICENSE b/LICENSE index 1fa3822f51..9723bc8be9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,8 @@ -The MIT License (MIT) +Copyright (c) 2018 SmartContract ChainLink Limited SEZC + +Portions of this software are licensed as follows: -Copyright (c) 2018 SmartContract ChainLink, Ltd. +The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -19,3 +21,12 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +*All content residing under (1) “/contracts/src/v0.8/ccip”; (2) +“/core/services/ocr2/plugins/ccip” are licensed under “Business Source +License 1.1” with a Change Date of May 23, 2027 and Change License to + “MIT License” + +* Content outside of the above mentioned directories or restrictions +above is available under the "MIT" license as defined above. \ No newline at end of file diff --git a/contracts/.changeset/three-stingrays-compete.md b/contracts/.changeset/three-stingrays-compete.md new file mode 100644 index 0000000000..613b278465 --- /dev/null +++ b/contracts/.changeset/three-stingrays-compete.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': minor +--- + +add ccip contracts to the repo diff --git a/contracts/.prettierignore b/contracts/.prettierignore index 7c3131db42..440cf95afa 100644 --- a/contracts/.prettierignore +++ b/contracts/.prettierignore @@ -21,6 +21,7 @@ solc LinkToken.json typechain **/vendor +src/v0.8/ccip/** # Ignore TS definition and map files **/**.d.ts @@ -35,4 +36,4 @@ venv/ .solhint.json src/v0.8/mocks/FunctionsOracleEventsMock.sol -src/v0.8/mocks/FunctionsBillingRegistryEventsMock.sol \ No newline at end of file +src/v0.8/mocks/FunctionsBillingRegistryEventsMock.sol diff --git a/contracts/.prettierrc.js b/contracts/.prettierrc.js index 774a5e964e..1766284122 100644 --- a/contracts/.prettierrc.js +++ b/contracts/.prettierrc.js @@ -5,6 +5,7 @@ module.exports = { endOfLine: 'auto', tabWidth: 2, trailingComma: 'all', + plugins: ['prettier-plugin-solidity'], overrides: [ { files: '*.sol', diff --git a/contracts/.solhintignore b/contracts/.solhintignore index bab41a5794..bad1935442 100644 --- a/contracts/.solhintignore +++ b/contracts/.solhintignore @@ -1,6 +1,3 @@ -# 344 warnings -#./src/v0.8/automation - # Ignore frozen Automation code ./src/v0.8/automation/v1_2 ./src/v0.8/automation/interfaces/v1_2 @@ -39,6 +36,7 @@ ./src/v0.8/llo-feeds/test ./src/v0.8/vrf/testhelpers ./src/v0.8/functions/tests +./src/v0.8/ccip/test # Always ignore vendor ./src/v0.8/vendor diff --git a/contracts/GNUmakefile b/contracts/GNUmakefile index c3e6946469..0ebad8446e 100644 --- a/contracts/GNUmakefile +++ b/contracts/GNUmakefile @@ -1,6 +1,6 @@ # ALL_FOUNDRY_PRODUCTS contains a list of all products that have a foundry -# profile defined and use the Foundry snapshots. -ALL_FOUNDRY_PRODUCTS = functions keystone l2ep llo-feeds operatorforwarder shared transmission +# profile defined and use the Foundry snapshots. +ALL_FOUNDRY_PRODUCTS = ccip functions keystone l2ep liquiditymanager llo-feeds operatorforwarder shared transmission # To make a snapshot for a specific product, either set the `FOUNDRY_PROFILE` env var # or call the target with `FOUNDRY_PROFILE=product` @@ -16,11 +16,11 @@ ALL_FOUNDRY_PRODUCTS = functions keystone l2ep llo-feeds operatorforwarder share # a static fuzz seed by default, flaky gas results per platform are still observed. .PHONY: snapshot snapshot: ## Make a snapshot for a specific product. - export FOUNDRY_PROFILE=$(FOUNDRY_PROFILE) && forge snapshot --nmt "testFuzz_\w{1,}?" --snap gas-snapshots/$(FOUNDRY_PROFILE).gas-snapshot + export FOUNDRY_PROFILE=$(FOUNDRY_PROFILE) && forge snapshot --nmt "test_?Fuzz_\w{1,}?" --snap gas-snapshots/$(FOUNDRY_PROFILE).gas-snapshot .PHONY: snapshot-diff snapshot-diff: ## Make a snapshot for a specific product. - export FOUNDRY_PROFILE=$(FOUNDRY_PROFILE) && forge snapshot --nmt "testFuzz_\w{1,}?" --diff gas-snapshots/$(FOUNDRY_PROFILE).gas-snapshot + export FOUNDRY_PROFILE=$(FOUNDRY_PROFILE) && forge snapshot --nmt "test_?Fuzz_\w{1,}?" --diff gas-snapshots/$(FOUNDRY_PROFILE).gas-snapshot .PHONY: snapshot-all @@ -50,6 +50,21 @@ foundry-refresh: foundry git submodule deinit -f . git submodule update --init --recursive +ccip-precommit: export FOUNDRY_PROFILE=ccip +.PHONY: ccip-precommit +ccip-precommit: + forge test + make snapshot + forge fmt + pnpm solhint + +ccip-lcov: export FOUNDRY_PROFILE=ccip +.PHONY: ccip-lcov +ccip-lcov: + forge coverage --report lcov + ../tools/ci/ccip_lcov_prune ./lcov.info ./lcov.info.pruned + genhtml -o report lcov.info.pruned --branch-coverage + # To generate gethwrappers for a specific product, either set the `FOUNDRY_PROFILE` # env var or call the target with `FOUNDRY_PROFILE=product` # This uses FOUNDRY_PROFILE, even though it does support non-foundry products. This diff --git a/contracts/README.md b/contracts/README.md index 26b0a82329..182891ceef 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -67,5 +67,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## License +Most of the contracts are licensed under the [MIT](https://choosealicense.com/licenses/mit/) license. +An exception to this is the ccip folder, which defaults to be licensed under the [BUSL-1.1](./src/v0.8/ccip/LICENSE.md) license, however, there are a few exceptions -[MIT](https://choosealicense.com/licenses/mit/) +- `src/v0.8/ccip/applications/*` is licensed under the [MIT](./src/v0.8/ccip/LICENSE-MIT.md) license +- `src/v0.8/ccip/interfaces/*` is licensed under the [MIT](./src/v0.8/ccip/LICENSE-MIT.md) license +- `src/v0.8/ccip/libraries/{Client.sol, Internal.sol}` is licensed under the [MIT](./src/v0.8/ccip/LICENSE-MIT.md) license \ No newline at end of file diff --git a/contracts/STYLE_GUIDE.md b/contracts/STYLE_GUIDE.md index b9294de576..c5dc20abea 100644 --- a/contracts/STYLE_GUIDE.md +++ b/contracts/STYLE_GUIDE.md @@ -1,7 +1,7 @@ # Structure -This guide is split into two sections: [Guidelines](#guidelines) and [Rules](#rules). -Guidelines are recommendations that should be followed but are hard to enforce in an automated way. +This guide is split into two sections: [Guidelines](#guidelines) and [Rules](#rules). +Guidelines are recommendations that should be followed but are hard to enforce in an automated way. Rules are all enforced through CI, this can be through Solhint rules or other tools. ## Background @@ -76,11 +76,11 @@ uint256 networkFeeUSDCents; // good struct FeeTokenConfigArgs { address token; // ────────────╮ Token address uint32 networkFeeUSD; // │ Flat network fee to charge for messages, multiples of 0.01 USD - // │ multiline comments should work like this. More fee info + // │ multiline comments should work like this. More fee info uint64 gasMultiplier; // ─────╯ Price multiplier for gas costs, 1e18 based so 11e17 = 10% extra cost uint64 premiumMultiplier; // ─╮ Multiplier for fee-token-specific premiums bool enabled; // ─────────────╯ Whether this fee token is enabled - uint256 fee; // The flat fee the user pays in juels + uint256 fee; // The flat fee the user pays in juels } ``` ## Functions @@ -132,7 +132,7 @@ assembly { // call and return whether we succeeded. ignore return data // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) success := call(gasLimit, target, 0, add(payload, 0x20), mload(payload), 0, 0) - + // limit our copy to maxReturnBytes bytes let toCopy := returndatasize() if gt(toCopy, maxReturnBytes) { @@ -242,7 +242,7 @@ contract AccessControlledFoo is Foo { contract OffchainAggregator is ITypeAndVersion { string public constant override typeAndVersion = "OffchainAggregator 1.0.0"; - + function getData() public returns(uint256) { return 4; } @@ -310,8 +310,8 @@ import {IPool} from "../interfaces/pools/IPool.sol"; import {AggregateRateLimiter} from "../AggregateRateLimiter.sol"; import {Client} from "../libraries/Client.sol"; -import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol"; -import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; ``` ## Variables diff --git a/contracts/foundry.toml b/contracts/foundry.toml index 08940b4e9f..c755ba6437 100644 --- a/contracts/foundry.toml +++ b/contracts/foundry.toml @@ -16,6 +16,19 @@ gas_price = 1 block_timestamp = 1234567890 block_number = 12345 +[fmt] +tab_width = 2 +multiline_func_header = "params_first" +sort_imports = true +single_line_statement_blocks = "preserve" + +[profile.ccip] +solc_version = '0.8.24' +src = 'src/v0.8/ccip' +test = 'src/v0.8/ccip/test' +optimizer_runs = 3_600 +evm_version = 'paris' + [profile.functions] solc_version = '0.8.19' src = 'src/v0.8/functions/dev/v1_X' @@ -52,6 +65,13 @@ src = 'src/v0.8/llo-feeds' test = 'src/v0.8/llo-feeds/test' solc_version = '0.8.19' +[profile.liquiditymanager] +optimizer_runs = 1000000 +src = 'src/v0.8/liquiditymanager' +test = 'src/v0.8/liquiditymanager/test' +solc_version = '0.8.24' +evm_version = 'paris' + [profile.keystone] optimizer_runs = 1_000_000 solc_version = '0.8.24' diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot new file mode 100644 index 0000000000..5fc99a9a40 --- /dev/null +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -0,0 +1,943 @@ +ARMProxyStandaloneTest:test_ARMCallEmptyContractRevert() (gas: 19600) +ARMProxyStandaloneTest:test_Constructor() (gas: 374544) +ARMProxyStandaloneTest:test_SetARM() (gas: 16494) +ARMProxyStandaloneTest:test_SetARMzero() (gas: 11216) +ARMProxyTest:test_ARMCallRevertReasonForwarded() (gas: 47793) +ARMProxyTest:test_ARMIsBlessed_Success() (gas: 36269) +ARMProxyTest:test_ARMIsCursed_Success() (gas: 49740) +AggregateTokenLimiter_constructor:test_Constructor_Success() (gas: 26920) +AggregateTokenLimiter_getTokenBucket:test_GetTokenBucket_Success() (gas: 19691) +AggregateTokenLimiter_getTokenBucket:test_Refill_Success() (gas: 40911) +AggregateTokenLimiter_getTokenBucket:test_TimeUnderflow_Revert() (gas: 15368) +AggregateTokenLimiter_getTokenLimitAdmin:test_GetTokenLimitAdmin_Success() (gas: 10531) +AggregateTokenLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19696) +AggregateTokenLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21281) +AggregateTokenLimiter_rateLimitValue:test_AggregateValueMaxCapacityExceeded_Revert() (gas: 16418) +AggregateTokenLimiter_rateLimitValue:test_RateLimitValueSuccess_gas() (gas: 18306) +AggregateTokenLimiter_setAdmin:test_OnlyOwnerOrAdmin_Revert() (gas: 13047) +AggregateTokenLimiter_setAdmin:test_Owner_Success() (gas: 18989) +AggregateTokenLimiter_setRateLimiterConfig:test_OnlyOnlyCallableByAdminOrOwner_Revert() (gas: 17479) +AggregateTokenLimiter_setRateLimiterConfig:test_Owner_Success() (gas: 30062) +AggregateTokenLimiter_setRateLimiterConfig:test_TokenLimitAdmin_Success() (gas: 32071) +BurnFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28675) +BurnFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55158) +BurnFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243525) +BurnFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 23907) +BurnMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 27565) +BurnMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55158) +BurnMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 241416) +BurnMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 17633) +BurnMintTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 28537) +BurnMintTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 55991) +BurnMintTokenPool_releaseOrMint:test_PoolMint_Success() (gas: 110657) +BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28675) +BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55158) +BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243552) +BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 24260) +CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2131281) +CCIPConfigSetup:test_getCapabilityConfiguration_Success() (gas: 9495) +CCIPConfig_ConfigStateMachine:test__computeConfigDigest_Success() (gas: 70755) +CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_InitToRunning_Success() (gas: 363647) +CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_RunningToStaging_Success() (gas: 488774) +CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_StagingToRunning_Success() (gas: 453384) +CCIPConfig_ConfigStateMachine:test__groupByPluginType_TooManyOCR3Configs_Reverts() (gas: 37027) +CCIPConfig_ConfigStateMachine:test__groupByPluginType_threeCommitConfigs_Reverts() (gas: 61043) +CCIPConfig_ConfigStateMachine:test__groupByPluginType_threeExecutionConfigs_Reverts() (gas: 60963) +CCIPConfig_ConfigStateMachine:test__stateFromConfigLength_Success() (gas: 11764) +CCIPConfig_ConfigStateMachine:test__validateConfigStateTransition_Success() (gas: 8765) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_InitToRunning_Success() (gas: 311991) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_InitToRunning_WrongConfigCount_Reverts() (gas: 49663) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_NonExistentConfigTransition_Reverts() (gas: 32275) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_Success() (gas: 376576) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_WrongConfigCount_Reverts() (gas: 120943) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_WrongConfigDigestBlueGreen_Reverts() (gas: 157105) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_StagingToRunning_Success() (gas: 376352) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_StagingToRunning_WrongConfigDigest_Reverts() (gas: 157172) +CCIPConfig_ConfigStateMachine:test_getCapabilityConfiguration_Success() (gas: 9583) +CCIPConfig__updatePluginConfig:test__updatePluginConfig_InitToRunning_Success() (gas: 1057393) +CCIPConfig__updatePluginConfig:test__updatePluginConfig_InvalidConfigLength_Reverts() (gas: 27539) +CCIPConfig__updatePluginConfig:test__updatePluginConfig_InvalidConfigStateTransition_Reverts() (gas: 23105) +CCIPConfig__updatePluginConfig:test__updatePluginConfig_RunningToStaging_Success() (gas: 2009309) +CCIPConfig__updatePluginConfig:test__updatePluginConfig_StagingToRunning_Success() (gas: 2616177) +CCIPConfig__updatePluginConfig:test_getCapabilityConfiguration_Success() (gas: 9583) +CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_CommitAndExecConfig_Success() (gas: 1851188) +CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_CommitConfigOnly_Success() (gas: 1068362) +CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_ExecConfigOnly_Success() (gas: 1068393) +CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_OnlyCapabilitiesRegistryCanCall_Reverts() (gas: 9599) +CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_ZeroLengthConfig_Success() (gas: 16070) +CCIPConfig_beforeCapabilityConfigSet:test_getCapabilityConfiguration_Success() (gas: 9583) +CCIPConfig_chainConfig:test__applyChainConfigUpdates_FChainNotPositive_Reverts() (gas: 184703) +CCIPConfig_chainConfig:test_applyChainConfigUpdates_addChainConfigs_Success() (gas: 344332) +CCIPConfig_chainConfig:test_applyChainConfigUpdates_nodeNotInRegistry_Reverts() (gas: 20258) +CCIPConfig_chainConfig:test_applyChainConfigUpdates_removeChainConfigs_Success() (gas: 267558) +CCIPConfig_chainConfig:test_applyChainConfigUpdates_selectorNotFound_Reverts() (gas: 14829) +CCIPConfig_chainConfig:test_getCapabilityConfiguration_Success() (gas: 9626) +CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsHasDuplicates_Reverts() (gas: 294893) +CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsNotASubsetOfP2PIds_Reverts() (gas: 298325) +CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsNotSorted_Reverts() (gas: 295038) +CCIPConfig_validateConfig:test__validateConfig_ChainSelectorNotFound_Reverts() (gas: 294357) +CCIPConfig_validateConfig:test__validateConfig_ChainSelectorNotSet_Reverts() (gas: 291431) +CCIPConfig_validateConfig:test__validateConfig_FMustBePositive_Reverts() (gas: 292396) +CCIPConfig_validateConfig:test__validateConfig_FTooHigh_Reverts() (gas: 292540) +CCIPConfig_validateConfig:test__validateConfig_NodeNotInRegistry_Reverts() (gas: 299420) +CCIPConfig_validateConfig:test__validateConfig_NotEnoughTransmitters_Reverts() (gas: 1160094) +CCIPConfig_validateConfig:test__validateConfig_OfframpAddressCannotBeZero_Reverts() (gas: 291260) +CCIPConfig_validateConfig:test__validateConfig_P2PIdsHasDuplicates_Reverts() (gas: 295907) +CCIPConfig_validateConfig:test__validateConfig_P2PIdsLengthNotMatching_Reverts() (gas: 293229) +CCIPConfig_validateConfig:test__validateConfig_P2PIdsNotSorted_Reverts() (gas: 295623) +CCIPConfig_validateConfig:test__validateConfig_Success() (gas: 302186) +CCIPConfig_validateConfig:test__validateConfig_TooManyBootstrapP2PIds_Reverts() (gas: 294539) +CCIPConfig_validateConfig:test__validateConfig_TooManySigners_Reverts() (gas: 1215861) +CCIPConfig_validateConfig:test__validateConfig_TooManyTransmitters_Reverts() (gas: 1214264) +CCIPConfig_validateConfig:test_getCapabilityConfiguration_Success() (gas: 9562) +CommitStore_constructor:test_Constructor_Success() (gas: 3091326) +CommitStore_isUnpausedAndRMNHealthy:test_RMN_Success() (gas: 73420) +CommitStore_report:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 28670) +CommitStore_report:test_InvalidInterval_Revert() (gas: 28610) +CommitStore_report:test_InvalidRootRevert() (gas: 27843) +CommitStore_report:test_OnlyGasPriceUpdates_Success() (gas: 53253) +CommitStore_report:test_OnlyPriceUpdateStaleReport_Revert() (gas: 59049) +CommitStore_report:test_OnlyTokenPriceUpdates_Success() (gas: 53251) +CommitStore_report:test_Paused_Revert() (gas: 21259) +CommitStore_report:test_ReportAndPriceUpdate_Success() (gas: 84242) +CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56313) +CommitStore_report:test_RootAlreadyCommitted_Revert() (gas: 63969) +CommitStore_report:test_StaleReportWithRoot_Success() (gas: 119420) +CommitStore_report:test_Unhealthy_Revert() (gas: 44751) +CommitStore_report:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 100758) +CommitStore_report:test_ZeroEpochAndRound_Revert() (gas: 27626) +CommitStore_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11325) +CommitStore_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 143718) +CommitStore_setDynamicConfig:test_InvalidCommitStoreConfig_Revert() (gas: 37263) +CommitStore_setDynamicConfig:test_OnlyOwner_Revert() (gas: 37399) +CommitStore_setDynamicConfig:test_PriceEpochCleared_Success() (gas: 129098) +CommitStore_setLatestPriceEpochAndRound:test_OnlyOwner_Revert() (gas: 11047) +CommitStore_setLatestPriceEpochAndRound:test_SetLatestPriceEpochAndRound_Success() (gas: 20642) +CommitStore_setMinSeqNr:test_OnlyOwner_Revert() (gas: 11046) +CommitStore_verify:test_Blessed_Success() (gas: 96389) +CommitStore_verify:test_NotBlessed_Success() (gas: 61374) +CommitStore_verify:test_Paused_Revert() (gas: 18496) +CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) +DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) +DefensiveExampleTest:test_Recovery() (gas: 424253) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1103438) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38157) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 108343) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 116811) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 460560) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 95542) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12463) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 90385) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 105586) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 15719) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 13057) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 298564) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 239899) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 158863) +EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 189303) +EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 147582) +EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 521508) +EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10459) +EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15662) +EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67195) +EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59698) +EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58778) +EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6394741) +EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 5977968) +EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106229) +EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116228) +EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106272) +EVM2EVMMultiOffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351414) +EVM2EVMMultiOffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159132) +EVM2EVMMultiOffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136253) +EVM2EVMMultiOffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136831) +EVM2EVMMultiOffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 59046) +EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 227807) +EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117527) +EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77605) +EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 207057) +EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6389130) +EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47785) +EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 5981174) +EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 157326) +EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103815) +EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101686) +EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 159832) +EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101585) +EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101652) +EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17280) +EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1559406) +EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 342924) +EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 260178) +EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6445247) +EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6028193) +EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 27681) +EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 165181) +EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 149137) +EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6807322) +EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17154) +EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18413) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249368) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20672) +EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 201673) +EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48860) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48381) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 232798) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 89392) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 278146) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 93615) +EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35083) +EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23907) +EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 451358) +EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54475) +EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35917) +EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154369) +EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35317) +EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 181353) +EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 190627) +EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48053) +EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 443030) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 251770) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 173962) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 193657) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259648) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 129585) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 391710) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65899) +EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80955) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 535429) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 480345) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35763) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 520344) +EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 517712) +EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 487848) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 127921) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 157144) +EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3655340) +EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118224) +EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87461) +EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75600) +EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26461) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 163081) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 207379) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26004) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152867) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 507480) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails() (gas: 2307925) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 209633) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 210210) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 668610) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 299477) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 160598) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 24131) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 59105) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 40405) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 76130) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 178951) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 278805) +EVM2EVMMultiOffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11379) +EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215406) +EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14374) +EVM2EVMMultiOffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11898) +EVM2EVMMultiOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 14054) +EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 55771) +EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 33781) +EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 238004) +EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246667) +EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 299499) +EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 280579) +EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176604) +EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178672) +EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141533) +EVM2EVMMultiOffRamp_verify:test_TooManyLeaves_Revert() (gas: 51508) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94528) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92480) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97483) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92538) +EVM2EVMMultiOnRamp_constructor:test_Constructor_Success() (gas: 2260144) +EVM2EVMMultiOnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 90987) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 130983) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 161753) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 161306) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 159506) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 161536) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 160928) +EVM2EVMMultiOnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 26206) +EVM2EVMMultiOnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 134082) +EVM2EVMMultiOnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 24272) +EVM2EVMMultiOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12819) +EVM2EVMMultiOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 30695) +EVM2EVMMultiOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 15675) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 198276) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 224545) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 140840) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 162262) +EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3803257) +EVM2EVMMultiOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 127615) +EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 93044) +EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 282576) +EVM2EVMMultiOnRamp_getFee:test_EmptyMessage_Success() (gas: 104423) +EVM2EVMMultiOnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 74041) +EVM2EVMMultiOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119755) +EVM2EVMMultiOnRamp_getFee:test_Unhealthy_Revert() (gas: 43657) +EVM2EVMMultiOnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10438) +EVM2EVMMultiOnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35204) +EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11356) +EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() (gas: 12956) +EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11313) +EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 16287) +EVM2EVMMultiOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 58439) +EVM2EVMMultiOnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97185) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 38028) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 108191) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_revert_Revert() (gas: 116732) +EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 391880) +EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 145379) +EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 788000) +EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 176208) +EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 29700) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 63325) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 44501) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 214151) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 306912) +EVM2EVMOffRamp__report:test_Report_Success() (gas: 127459) +EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 255047) +EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 263638) +EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 335707) +EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 314443) +EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17009) +EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153427) +EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5464875) +EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 144183) +EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21345) +EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36442) +EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51701) +EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 473575) +EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 46423) +EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152453) +EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 101458) +EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 165036) +EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 177824) +EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 41317) +EVM2EVMOffRamp_execute:test_RouterYULCall_Revert() (gas: 402506) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 159387) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 174622) +EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 248634) +EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 115017) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 409338) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54173) +EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 132056) +EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52200) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 560178) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 499424) +EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35442) +EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 546987) +EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64045) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 123223) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 143388) +EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 20582) +EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 281891) +EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20231) +EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 219228) +EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48632) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48120) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 316477) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 72423) +EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 231326) +EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 279867) +EVM2EVMOffRamp_execute_upgrade:test_V2OffRampNonceSkipsIfMsgInFlight_Success() (gas: 261109) +EVM2EVMOffRamp_execute_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 229397) +EVM2EVMOffRamp_execute_upgrade:test_V2_Success() (gas: 131682) +EVM2EVMOffRamp_getAllRateLimitTokens:test_GetAllRateLimitTokens_Success() (gas: 38408) +EVM2EVMOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3213556) +EVM2EVMOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 83091) +EVM2EVMOffRamp_manuallyExecute:test_LowGasLimitManualExec_Success() (gas: 483328) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 186413) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecForkedChain_Revert() (gas: 25824) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 43449) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 25927) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithGasOverride_Success() (gas: 188518) +EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187965) +EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails() (gas: 2027441) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143803) +EVM2EVMOffRamp_metadataHash:test_MetadataHash_Success() (gas: 8871) +EVM2EVMOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 40429) +EVM2EVMOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 38804) +EVM2EVMOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 146790) +EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_AddsAndRemoves_Success() (gas: 162464) +EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_NonOwner_Revert() (gas: 16667) +EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_Success() (gas: 197660) +EVM2EVMOnRamp_constructor:test_Constructor_Success() (gas: 5619710) +EVM2EVMOnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 35778) +EVM2EVMOnRamp_forwardFromRouter:test_EnforceOutOfOrder_Revert() (gas: 99470) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 114210) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 114252) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 130118) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 138650) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 129804) +EVM2EVMOnRamp_forwardFromRouter:test_InvalidAddressEncodePacked_Revert() (gas: 38254) +EVM2EVMOnRamp_forwardFromRouter:test_InvalidAddress_Revert() (gas: 38370) +EVM2EVMOnRamp_forwardFromRouter:test_InvalidChainSelector_Revert() (gas: 25511) +EVM2EVMOnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 25297) +EVM2EVMOnRamp_forwardFromRouter:test_MaxCapacityExceeded_Revert() (gas: 86041) +EVM2EVMOnRamp_forwardFromRouter:test_MaxFeeBalanceReached_Revert() (gas: 36457) +EVM2EVMOnRamp_forwardFromRouter:test_MessageGasLimitTooHigh_Revert() (gas: 29037) +EVM2EVMOnRamp_forwardFromRouter:test_MessageTooLarge_Revert() (gas: 107526) +EVM2EVMOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 22635) +EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 223665) +EVM2EVMOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 53935) +EVM2EVMOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 25481) +EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59303) +EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179141) +EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 177355) +EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137297) +EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3731767) +EVM2EVMOnRamp_forwardFromRouter:test_TooManyTokens_Revert() (gas: 30187) +EVM2EVMOnRamp_forwardFromRouter:test_Unhealthy_Revert() (gas: 43300) +EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109258) +EVM2EVMOnRamp_forwardFromRouter:test_ZeroAddressReceiver_Revert() (gas: 312351) +EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_ShouldStoreLinkFees_Success() (gas: 112319) +EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 72181) +EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 147614) +EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 190454) +EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 121245) +EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2_Success() (gas: 95324) +EVM2EVMOnRamp_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 20760) +EVM2EVMOnRamp_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 21128) +EVM2EVMOnRamp_getFee:test_EmptyMessage_Success() (gas: 78242) +EVM2EVMOnRamp_getFee:test_HighGasMessage_Success() (gas: 234090) +EVM2EVMOnRamp_getFee:test_MessageGasLimitTooHigh_Revert() (gas: 16715) +EVM2EVMOnRamp_getFee:test_MessageTooLarge_Revert() (gas: 95271) +EVM2EVMOnRamp_getFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 159220) +EVM2EVMOnRamp_getFee:test_NotAFeeToken_Revert() (gas: 24089) +EVM2EVMOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 117858) +EVM2EVMOnRamp_getFee:test_TooManyTokens_Revert() (gas: 19902) +EVM2EVMOnRamp_getFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 65663) +EVM2EVMOnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10460) +EVM2EVMOnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35195) +EVM2EVMOnRamp_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 45037) +EVM2EVMOnRamp_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 33041) +EVM2EVMOnRamp_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 28296) +EVM2EVMOnRamp_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 130189) +EVM2EVMOnRamp_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 15260) +EVM2EVMOnRamp_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 28104) +EVM2EVMOnRamp_getTokenTransferCost:test_UnsupportedToken_Revert() (gas: 21248) +EVM2EVMOnRamp_getTokenTransferCost:test_WETHTokenBpsFee_Success() (gas: 38922) +EVM2EVMOnRamp_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 28149) +EVM2EVMOnRamp_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 38615) +EVM2EVMOnRamp_getTokenTransferCost:test__getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29527) +EVM2EVMOnRamp_linkAvailableForPayment:test_InsufficientLinkBalance_Success() (gas: 32615) +EVM2EVMOnRamp_linkAvailableForPayment:test_LinkAvailableForPayment_Success() (gas: 134833) +EVM2EVMOnRamp_payNops:test_AdminPayNops_Success() (gas: 143054) +EVM2EVMOnRamp_payNops:test_InsufficientBalance_Revert() (gas: 26543) +EVM2EVMOnRamp_payNops:test_NoFeesToPay_Revert() (gas: 127367) +EVM2EVMOnRamp_payNops:test_NoNopsToPay_Revert() (gas: 133251) +EVM2EVMOnRamp_payNops:test_NopPayNops_Success() (gas: 146341) +EVM2EVMOnRamp_payNops:test_OwnerPayNops_Success() (gas: 140916) +EVM2EVMOnRamp_payNops:test_PayNopsSuccessAfterSetNops() (gas: 297485) +EVM2EVMOnRamp_payNops:test_WrongPermissions_Revert() (gas: 15294) +EVM2EVMOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 43376) +EVM2EVMOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 21646) +EVM2EVMOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 55086) +EVM2EVMOnRamp_setFeeTokenConfig:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 13464) +EVM2EVMOnRamp_setFeeTokenConfig:test_SetFeeTokenConfigByAdmin_Success() (gas: 16449) +EVM2EVMOnRamp_setFeeTokenConfig:test_SetFeeTokenConfig_Success() (gas: 13994) +EVM2EVMOnRamp_setNops:test_AdminCanSetNops_Success() (gas: 61759) +EVM2EVMOnRamp_setNops:test_IncludesPayment_Success() (gas: 469097) +EVM2EVMOnRamp_setNops:test_LinkTokenCannotBeNop_Revert() (gas: 57255) +EVM2EVMOnRamp_setNops:test_NonOwnerOrAdmin_Revert() (gas: 14665) +EVM2EVMOnRamp_setNops:test_NotEnoughFundsForPayout_Revert() (gas: 84455) +EVM2EVMOnRamp_setNops:test_SetNopsRemovesOldNopsCompletely_Success() (gas: 60637) +EVM2EVMOnRamp_setNops:test_SetNops_Success() (gas: 173677) +EVM2EVMOnRamp_setNops:test_TooManyNops_Revert() (gas: 190338) +EVM2EVMOnRamp_setNops:test_ZeroAddressCannotBeNop_Revert() (gas: 53596) +EVM2EVMOnRamp_setTokenTransferFeeConfig:test__setTokenTransferFeeConfig_InvalidDestBytesOverhead_Revert() (gas: 14493) +EVM2EVMOnRamp_setTokenTransferFeeConfig:test__setTokenTransferFeeConfig_OnlyCallableByOwnerOrAdmin_Revert() (gas: 14277) +EVM2EVMOnRamp_setTokenTransferFeeConfig:test__setTokenTransferFeeConfig_Success() (gas: 84017) +EVM2EVMOnRamp_setTokenTransferFeeConfig:test__setTokenTransferFeeConfig_byAdmin_Success() (gas: 17369) +EVM2EVMOnRamp_withdrawNonLinkFees:test_LinkBalanceNotSettled_Revert() (gas: 82980) +EVM2EVMOnRamp_withdrawNonLinkFees:test_NonOwnerOrAdmin_Revert() (gas: 15275) +EVM2EVMOnRamp_withdrawNonLinkFees:test_SettlingBalance_Success() (gas: 272015) +EVM2EVMOnRamp_withdrawNonLinkFees:test_WithdrawNonLinkFees_Success() (gas: 53446) +EVM2EVMOnRamp_withdrawNonLinkFees:test_WithdrawToZeroAddress_Revert() (gas: 12830) +EtherSenderReceiverTest_ccipReceive:test_ccipReceive_fallbackToWethTransfer() (gas: 96729) +EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 47688) +EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongToken() (gas: 17384) +EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongTokenAmount() (gas: 15677) +EtherSenderReceiverTest_ccipSend:test_ccipSend_reverts_insufficientFee_feeToken() (gas: 99741) +EtherSenderReceiverTest_ccipSend:test_ccipSend_reverts_insufficientFee_native() (gas: 76096) +EtherSenderReceiverTest_ccipSend:test_ccipSend_reverts_insufficientFee_weth() (gas: 99748) +EtherSenderReceiverTest_ccipSend:test_ccipSend_success_feeToken() (gas: 144569) +EtherSenderReceiverTest_ccipSend:test_ccipSend_success_native() (gas: 80259) +EtherSenderReceiverTest_ccipSend:test_ccipSend_success_nativeExcess() (gas: 80446) +EtherSenderReceiverTest_ccipSend:test_ccipSend_success_weth() (gas: 95713) +EtherSenderReceiverTest_constructor:test_constructor() (gas: 17511) +EtherSenderReceiverTest_getFee:test_getFee() (gas: 27289) +EtherSenderReceiverTest_validateFeeToken:test_validateFeeToken_reverts_feeToken_tokenAmountNotEqualToMsgValue() (gas: 20333) +EtherSenderReceiverTest_validateFeeToken:test_validateFeeToken_valid_feeToken() (gas: 16715) +EtherSenderReceiverTest_validateFeeToken:test_validateFeeToken_valid_native() (gas: 16654) +EtherSenderReceiverTest_validatedMessage:test_validatedMessage_dataOverwrittenToMsgSender() (gas: 25415) +EtherSenderReceiverTest_validatedMessage:test_validatedMessage_emptyDataOverwrittenToMsgSender() (gas: 25265) +EtherSenderReceiverTest_validatedMessage:test_validatedMessage_invalidTokenAmounts() (gas: 17895) +EtherSenderReceiverTest_validatedMessage:test_validatedMessage_tokenOverwrittenToWeth() (gas: 25287) +EtherSenderReceiverTest_validatedMessage:test_validatedMessage_validMessage_extraArgs() (gas: 26292) +LockReleaseTokenPoolAndProxy_setRateLimitAdmin:test_SetRateLimitAdmin_Revert() (gas: 11058) +LockReleaseTokenPoolAndProxy_setRateLimitAdmin:test_SetRateLimitAdmin_Success() (gas: 35097) +LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Revert() (gas: 10970) +LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Success() (gas: 18036) +LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3313980) +LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3310379) +LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_Unauthorized_Revert() (gas: 11380) +LockReleaseTokenPoolPoolAndProxy_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 17135) +LockReleaseTokenPoolPoolAndProxy_setChainRateLimiterConfig:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 69142) +LockReleaseTokenPoolPoolAndProxy_setChainRateLimiterConfig:test_OnlyOwner_Revert() (gas: 17319) +LockReleaseTokenPoolPoolAndProxy_supportsInterface:test_SupportsInterface_Success() (gas: 9977) +LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60043) +LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11355) +LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3067883) +LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29942) +LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Success() (gas: 79844) +LockReleaseTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 59464) +LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3064325) +LockReleaseTokenPool_provideLiquidity:test_Unauthorized_Revert() (gas: 11380) +LockReleaseTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 72662) +LockReleaseTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56131) +LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 238673) +LockReleaseTokenPool_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 17102) +LockReleaseTokenPool_setChainRateLimiterConfig:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 69075) +LockReleaseTokenPool_setChainRateLimiterConfig:test_OnlyOwner_Revert() (gas: 17297) +LockReleaseTokenPool_setRateLimitAdmin:test_SetRateLimitAdmin_Revert() (gas: 11057) +LockReleaseTokenPool_setRateLimitAdmin:test_SetRateLimitAdmin_Success() (gas: 35140) +LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Revert() (gas: 10992) +LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Success() (gas: 17926) +LockReleaseTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 9977) +LockReleaseTokenPool_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60043) +LockReleaseTokenPool_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11355) +MerkleMultiProofTest:test_CVE_2023_34459() (gas: 5451) +MerkleMultiProofTest:test_EmptyLeaf_Revert() (gas: 3552) +MerkleMultiProofTest:test_MerkleRoot256() (gas: 394876) +MerkleMultiProofTest:test_MerkleRootSingleLeaf_Success() (gas: 3649) +MerkleMultiProofTest:test_SpecSync_gas() (gas: 34123) +MockRouterTest:test_ccipSendWithInsufficientNativeTokens_Revert() (gas: 33965) +MockRouterTest:test_ccipSendWithInvalidMsgValue_Revert() (gas: 60758) +MockRouterTest:test_ccipSendWithLinkFeeTokenAndValidMsgValue_Success() (gas: 126294) +MockRouterTest:test_ccipSendWithLinkFeeTokenbutInsufficientAllowance_Revert() (gas: 63302) +MockRouterTest:test_ccipSendWithSufficientNativeFeeTokens_Success() (gas: 43853) +MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_MultipleConfigsBothLanes_Success() (gas: 132031) +MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_MultipleConfigs_Success() (gas: 312057) +MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_OnlyCallableByOwner_Revert() (gas: 17717) +MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_SingleConfigOutbound_Success() (gas: 75784) +MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_SingleConfig_Success() (gas: 75700) +MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_UpdateExistingConfigWithNoDifference_Success() (gas: 38133) +MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_UpdateExistingConfig_Success() (gas: 53092) +MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_ZeroChainSelector_Revert() (gas: 17019) +MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_ZeroConfigs_Success() (gas: 12295) +MultiAggregateRateLimiter_constructor:test_ConstructorNoAuthorizedCallers_Success() (gas: 1971805) +MultiAggregateRateLimiter_constructor:test_Constructor_Success() (gas: 2085252) +MultiAggregateRateLimiter_getTokenBucket:test_GetTokenBucket_Success() (gas: 30248) +MultiAggregateRateLimiter_getTokenBucket:test_Refill_Success() (gas: 47358) +MultiAggregateRateLimiter_getTokenBucket:test_TimeUnderflow_Revert() (gas: 15821) +MultiAggregateRateLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19668) +MultiAggregateRateLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21253) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 14527) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 189450) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 59927) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 17593) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitDisabled_Success() (gas: 44895) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExceeded_Revert() (gas: 50598) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78780) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 263510) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54784) +MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 9223372036854754743) +MultiAggregateRateLimiter_onOutboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 19104) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 15778) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 189438) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 61662) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitDisabled_Success() (gas: 46683) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitExceeded_Revert() (gas: 52371) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitReset_Success() (gas: 79845) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 263724) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokens_Success() (gas: 56541) +MultiAggregateRateLimiter_setPriceRegistry:test_OnlyOwner_Revert() (gas: 11336) +MultiAggregateRateLimiter_setPriceRegistry:test_Owner_Success() (gas: 19124) +MultiAggregateRateLimiter_setPriceRegistry:test_ZeroAddress_Revert() (gas: 10608) +MultiAggregateRateLimiter_updateRateLimitTokens:test_NonOwner_Revert() (gas: 16085) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensMultipleChains_Success() (gas: 225643) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensSingleChain_Success() (gas: 200192) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_AddsAndRemoves_Success() (gas: 162053) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_RemoveNonExistentToken_Success() (gas: 28509) +MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroDestToken_Revert() (gas: 17430) +MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroSourceToken_Revert() (gas: 17485) +MultiOCR3Base_setOCR3Configs:test_FMustBePositive_Revert() (gas: 59331) +MultiOCR3Base_setOCR3Configs:test_FTooHigh_Revert() (gas: 44298) +MultiOCR3Base_setOCR3Configs:test_RepeatSignerAddress_Revert() (gas: 283711) +MultiOCR3Base_setOCR3Configs:test_RepeatTransmitterAddress_Revert() (gas: 422848) +MultiOCR3Base_setOCR3Configs:test_SetConfigIgnoreSigners_Success() (gas: 511694) +MultiOCR3Base_setOCR3Configs:test_SetConfigWithSigners_Success() (gas: 829593) +MultiOCR3Base_setOCR3Configs:test_SetConfigWithoutSigners_Success() (gas: 457446) +MultiOCR3Base_setOCR3Configs:test_SetConfigsZeroInput_Success() (gas: 12376) +MultiOCR3Base_setOCR3Configs:test_SetMultipleConfigs_Success() (gas: 2143220) +MultiOCR3Base_setOCR3Configs:test_SignerCannotBeZeroAddress_Revert() (gas: 141744) +MultiOCR3Base_setOCR3Configs:test_StaticConfigChange_Revert() (gas: 808478) +MultiOCR3Base_setOCR3Configs:test_TooManySigners_Revert() (gas: 171331) +MultiOCR3Base_setOCR3Configs:test_TooManyTransmitters_Revert() (gas: 30298) +MultiOCR3Base_setOCR3Configs:test_TransmitterCannotBeZeroAddress_Revert() (gas: 254454) +MultiOCR3Base_setOCR3Configs:test_UpdateConfigSigners_Success() (gas: 861521) +MultiOCR3Base_setOCR3Configs:test_UpdateConfigTransmittersWithoutSigners_Success() (gas: 475825) +MultiOCR3Base_transmit:test_ConfigDigestMismatch_Revert() (gas: 42837) +MultiOCR3Base_transmit:test_ForkedChain_Revert() (gas: 48442) +MultiOCR3Base_transmit:test_InsufficientSignatures_Revert() (gas: 76930) +MultiOCR3Base_transmit:test_NonUniqueSignature_Revert() (gas: 66127) +MultiOCR3Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 33419) +MultiOCR3Base_transmit:test_TooManySignatures_Revert() (gas: 79521) +MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34131) +MultiOCR3Base_transmit:test_TransmitWithExtraCalldataArgs_Revert() (gas: 47114) +MultiOCR3Base_transmit:test_TransmitWithLessCalldataArgs_Revert() (gas: 25682) +MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18726) +MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) +MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) +MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) +MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) +MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 412349) +MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1426976) +NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) +NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) +NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) +NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71847) +NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 252566) +NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 254866) +NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 307885) +NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 290962) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 247990) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 236024) +NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 144774) +NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 186669) +NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 237737) +NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 124995) +NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 125923) +NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 122899) +NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOffRamp_Revert() (gas: 42959) +NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRampAndOffRamp_Revert() (gas: 64282) +NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRamp_Revert() (gas: 42823) +NonceManager_applyPreviousRampsUpdates:test_SingleRampUpdate() (gas: 66548) +NonceManager_applyPreviousRampsUpdates:test_ZeroInput() (gas: 12025) +OCR2BaseNoChecks_setOCR2Config:test_FMustBePositive_Revert() (gas: 12171) +OCR2BaseNoChecks_setOCR2Config:test_RepeatAddress_Revert() (gas: 42233) +OCR2BaseNoChecks_setOCR2Config:test_SetConfigSuccess_gas() (gas: 84124) +OCR2BaseNoChecks_setOCR2Config:test_TooManyTransmitter_Revert() (gas: 36938) +OCR2BaseNoChecks_setOCR2Config:test_TransmitterCannotBeZeroAddress_Revert() (gas: 24158) +OCR2BaseNoChecks_transmit:test_ConfigDigestMismatch_Revert() (gas: 17448) +OCR2BaseNoChecks_transmit:test_ForkedChain_Revert() (gas: 26726) +OCR2BaseNoChecks_transmit:test_TransmitSuccess_gas() (gas: 27478) +OCR2BaseNoChecks_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 21296) +OCR2Base_setOCR2Config:test_FMustBePositive_Revert() (gas: 12189) +OCR2Base_setOCR2Config:test_FTooHigh_Revert() (gas: 12345) +OCR2Base_setOCR2Config:test_OracleOutOfRegister_Revert() (gas: 14892) +OCR2Base_setOCR2Config:test_RepeatAddress_Revert() (gas: 45442) +OCR2Base_setOCR2Config:test_SetConfigSuccess_gas() (gas: 155192) +OCR2Base_setOCR2Config:test_SingerCannotBeZeroAddress_Revert() (gas: 24407) +OCR2Base_setOCR2Config:test_TooManySigners_Revert() (gas: 20508) +OCR2Base_setOCR2Config:test_TransmitterCannotBeZeroAddress_Revert() (gas: 47298) +OCR2Base_transmit:test_ConfigDigestMismatch_Revert() (gas: 19623) +OCR2Base_transmit:test_ForkedChain_Revert() (gas: 37683) +OCR2Base_transmit:test_NonUniqueSignature_Revert() (gas: 55309) +OCR2Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 20962) +OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51686) +OCR2Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 23484) +OCR2Base_transmit:test_UnauthorizedSigner_Revert() (gas: 39665) +OCR2Base_transmit:test_WrongNumberOfSignatures_Revert() (gas: 20557) +OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 380360) +PingPong_ccipReceive:test_CcipReceive_Success() (gas: 148380) +PingPong_plumbing:test_Pausing_Success() (gas: 17803) +PingPong_startPingPong:test_StartPingPong_Success() (gas: 178340) +PriceRegistry_applyDestChainConfigUpdates:test_InvalidChainFamilySelector_Revert() (gas: 16719) +PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 16784) +PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestChainConfigDestChainSelectorEqZero_Revert() (gas: 16611) +PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitEqZero_Revert() (gas: 16675) +PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitGtMaxPerMessageGasLimit_Revert() (gas: 40953) +PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesZeroIntput_Success() (gas: 12341) +PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdates_Success() (gas: 139564) +PriceRegistry_applyFeeTokensUpdates:test_ApplyFeeTokensUpdates_Success() (gas: 80002) +PriceRegistry_applyFeeTokensUpdates:test_OnlyCallableByOwner_Revert() (gas: 12603) +PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 11465) +PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesMultipleTokens_Success() (gas: 54149) +PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesSingleToken_Success() (gas: 44835) +PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesZeroInput() (gas: 12301) +PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfig_Success() (gas: 86826) +PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeZeroInput() (gas: 13089) +PriceRegistry_applyTokenTransferFeeConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 17045) +PriceRegistry_applyTokenTransferFeeConfigUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 12240) +PriceRegistry_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 105966) +PriceRegistry_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 110316) +PriceRegistry_constructor:test_InvalidStalenessThreshold_Revert() (gas: 110369) +PriceRegistry_constructor:test_Setup_Success() (gas: 4650895) +PriceRegistry_convertTokenAmount:test_ConvertTokenAmount_Success() (gas: 72751) +PriceRegistry_convertTokenAmount:test_LinkTokenNotSupported_Revert() (gas: 30981) +PriceRegistry_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 95575) +PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCostUnsupportedDestChainSelector_Success() (gas: 14636) +PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20614) +PriceRegistry_getTokenAndGasPrices:test_GetFeeTokenAndGasPrices_Success() (gas: 70449) +PriceRegistry_getTokenAndGasPrices:test_StaleGasPrice_Revert() (gas: 16838) +PriceRegistry_getTokenAndGasPrices:test_UnsupportedChain_Revert() (gas: 16140) +PriceRegistry_getTokenAndGasPrices:test_ZeroGasPrice_Success() (gas: 45734) +PriceRegistry_getTokenPrice:test_GetTokenPriceFromFeed_Success() (gas: 62311) +PriceRegistry_getTokenPrices:test_GetTokenPrices_Success() (gas: 84774) +PriceRegistry_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 41283) +PriceRegistry_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 34733) +PriceRegistry_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 27807) +PriceRegistry_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 108018) +PriceRegistry_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 20359) +PriceRegistry_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 27615) +PriceRegistry_getTokenTransferCost:test_WETHTokenBpsFee_Success() (gas: 40668) +PriceRegistry_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 27638) +PriceRegistry_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 40015) +PriceRegistry_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29343) +PriceRegistry_getValidatedFee:test_DestinationChainNotEnabled_Revert() (gas: 18203) +PriceRegistry_getValidatedFee:test_EmptyMessage_Success() (gas: 81464) +PriceRegistry_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 55184) +PriceRegistry_getValidatedFee:test_HighGasMessage_Success() (gas: 237926) +PriceRegistry_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 19971) +PriceRegistry_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 31775) +PriceRegistry_getValidatedFee:test_MessageTooLarge_Revert() (gas: 97714) +PriceRegistry_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 143193) +PriceRegistry_getValidatedFee:test_NotAFeeToken_Revert() (gas: 29435) +PriceRegistry_getValidatedFee:test_SingleTokenMessage_Success() (gas: 112283) +PriceRegistry_getValidatedFee:test_TooManyTokens_Revert() (gas: 20107) +PriceRegistry_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 62956) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Above18Decimals_Success() (gas: 2094532) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Below18Decimals_Success() (gas: 2094490) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt0Decimals_Success() (gas: 2074609) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt18Decimals_Success() (gas: 2094264) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFlippedDecimals_Success() (gas: 2094468) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedMaxInt224Value_Success() (gas: 2094280) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedOverStalenessPeriod_Success() (gas: 61997) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeed_Success() (gas: 61877) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPrice_Success() (gas: 60998) +PriceRegistry_getValidatedTokenPrice:test_OverflowFeedPrice_Revert() (gas: 2093992) +PriceRegistry_getValidatedTokenPrice:test_StaleFeeToken_Success() (gas: 61525) +PriceRegistry_getValidatedTokenPrice:test_TokenNotSupportedFeed_Revert() (gas: 109113) +PriceRegistry_getValidatedTokenPrice:test_TokenNotSupported_Revert() (gas: 13819) +PriceRegistry_getValidatedTokenPrice:test_UnderflowFeedPrice_Revert() (gas: 2092670) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsDefault_Success() (gas: 17360) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsEnforceOutOfOrder_Revert() (gas: 21454) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsGasLimitTooHigh_Revert() (gas: 18551) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsInvalidExtraArgsTag_Revert() (gas: 18075) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV1_Success() (gas: 18452) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV2_Success() (gas: 18569) +PriceRegistry_processMessageArgs:test_InvalidExtraArgs_Revert() (gas: 18306) +PriceRegistry_processMessageArgs:test_MalformedEVMExtraArgs_Revert() (gas: 18852) +PriceRegistry_processMessageArgs:test_MessageFeeTooHigh_Revert() (gas: 16360) +PriceRegistry_processMessageArgs:test_WitEVMExtraArgsV2_Success() (gas: 26236) +PriceRegistry_processMessageArgs:test_WithConvertedTokenAmount_Success() (gas: 32410) +PriceRegistry_processMessageArgs:test_WithEVMExtraArgsV1_Success() (gas: 25848) +PriceRegistry_processMessageArgs:test_WithEmptyEVMExtraArgs_Success() (gas: 23663) +PriceRegistry_processMessageArgs:test_WithLinkTokenAmount_Success() (gas: 17320) +PriceRegistry_updatePrices:test_OnlyCallableByUpdater_Revert() (gas: 12080) +PriceRegistry_updatePrices:test_OnlyGasPrice_Success() (gas: 23599) +PriceRegistry_updatePrices:test_OnlyTokenPrice_Success() (gas: 30637) +PriceRegistry_updatePrices:test_UpdatableByAuthorizedCaller_Success() (gas: 76043) +PriceRegistry_updatePrices:test_UpdateMultiplePrices_Success() (gas: 151521) +PriceRegistry_updateTokenPriceFeeds:test_FeedNotUpdated() (gas: 50699) +PriceRegistry_updateTokenPriceFeeds:test_FeedUnset_Success() (gas: 63882) +PriceRegistry_updateTokenPriceFeeds:test_FeedUpdatedByNonOwner_Revert() (gas: 19998) +PriceRegistry_updateTokenPriceFeeds:test_MultipleFeedUpdate_Success() (gas: 89162) +PriceRegistry_updateTokenPriceFeeds:test_SingleFeedUpdate_Success() (gas: 50949) +PriceRegistry_updateTokenPriceFeeds:test_ZeroFeeds_Success() (gas: 12362) +PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddressEncodePacked_Revert() (gas: 10572) +PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddressPrecompiles_Revert() (gas: 3916546) +PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddress_Revert() (gas: 10756) +PriceRegistry_validateDestFamilyAddress:test_ValidEVMAddress_Success() (gas: 6660) +PriceRegistry_validateDestFamilyAddress:test_ValidNonEVMAddress_Success() (gas: 6440) +PriceRegistry_validatePoolReturnData:test_InvalidEVMAddressDestToken_Revert() (gas: 35457) +PriceRegistry_validatePoolReturnData:test_SourceTokenDataTooLarge_Revert() (gas: 90631) +PriceRegistry_validatePoolReturnData:test_TokenAmountArraysMismatching_Revert() (gas: 32749) +PriceRegistry_validatePoolReturnData:test_WithSingleToken_Success() (gas: 31293) +RMN_constructor:test_Constructor_Success() (gas: 48838) +RMN_getRecordedCurseRelatedOps:test_OpsPostDeployment() (gas: 19666) +RMN_lazyVoteToCurseUpdate_Benchmark:test_VoteToCurseLazilyRetain3VotersUponConfigChange_gas() (gas: 152152) +RMN_ownerUnbless:test_Unbless_Success() (gas: 74699) +RMN_ownerUnvoteToCurse:test_CanBlessAndCurseAfterGlobalCurseIsLifted() (gas: 470965) +RMN_ownerUnvoteToCurse:test_IsIdempotent() (gas: 397532) +RMN_ownerUnvoteToCurse:test_NonOwner_Revert() (gas: 18591) +RMN_ownerUnvoteToCurse:test_OwnerUnvoteToCurseSuccess_gas() (gas: 357403) +RMN_ownerUnvoteToCurse:test_UnknownVoter_Revert() (gas: 32980) +RMN_ownerUnvoteToCurse_Benchmark:test_OwnerUnvoteToCurse_1Voter_LiftsCurse_gas() (gas: 261985) +RMN_permaBlessing:test_PermaBlessing() (gas: 202686) +RMN_setConfig:test_BlessVoterIsZeroAddress_Revert() (gas: 15494) +RMN_setConfig:test_EitherThresholdIsZero_Revert() (gas: 21095) +RMN_setConfig:test_NonOwner_Revert() (gas: 14713) +RMN_setConfig:test_RepeatedAddress_Revert() (gas: 18213) +RMN_setConfig:test_SetConfigSuccess_gas() (gas: 104204) +RMN_setConfig:test_TotalWeightsSmallerThanEachThreshold_Revert() (gas: 30173) +RMN_setConfig:test_VoteToBlessByEjectedVoter_Revert() (gas: 130303) +RMN_setConfig:test_VotersLengthIsZero_Revert() (gas: 12128) +RMN_setConfig:test_WeightIsZeroAddress_Revert() (gas: 15734) +RMN_setConfig_Benchmark_1:test_SetConfig_7Voters_gas() (gas: 659123) +RMN_setConfig_Benchmark_2:test_ResetConfig_7Voters_gas() (gas: 212156) +RMN_unvoteToCurse:test_InvalidCursesHash() (gas: 26364) +RMN_unvoteToCurse:test_OwnerSkips() (gas: 33753) +RMN_unvoteToCurse:test_OwnerSucceeds() (gas: 63909) +RMN_unvoteToCurse:test_UnauthorizedVoter() (gas: 47478) +RMN_unvoteToCurse:test_ValidCursesHash() (gas: 61067) +RMN_unvoteToCurse:test_VotersCantLiftCurseButOwnerCan() (gas: 627750) +RMN_voteToBless:test_Curse_Revert() (gas: 472823) +RMN_voteToBless:test_IsAlreadyBlessed_Revert() (gas: 114829) +RMN_voteToBless:test_RootSuccess() (gas: 555559) +RMN_voteToBless:test_SenderAlreadyVoted_Revert() (gas: 96730) +RMN_voteToBless:test_UnauthorizedVoter_Revert() (gas: 17087) +RMN_voteToBless_Benchmark:test_1RootSuccess_gas() (gas: 44667) +RMN_voteToBless_Benchmark:test_3RootSuccess_gas() (gas: 98565) +RMN_voteToBless_Benchmark:test_5RootSuccess_gas() (gas: 152401) +RMN_voteToBless_Blessed_Benchmark:test_1RootSuccessBecameBlessed_gas() (gas: 29619) +RMN_voteToBless_Blessed_Benchmark:test_1RootSuccess_gas() (gas: 27565) +RMN_voteToBless_Blessed_Benchmark:test_3RootSuccess_gas() (gas: 81485) +RMN_voteToBless_Blessed_Benchmark:test_5RootSuccess_gas() (gas: 135299) +RMN_voteToCurse:test_CurseOnlyWhenThresholdReached_Success() (gas: 1648701) +RMN_voteToCurse:test_EmptySubjects_Revert() (gas: 14019) +RMN_voteToCurse:test_EvenIfAlreadyCursed_Success() (gas: 534332) +RMN_voteToCurse:test_OwnerCanCurseAndUncurse() (gas: 399001) +RMN_voteToCurse:test_RepeatedSubject_Revert() (gas: 144225) +RMN_voteToCurse:test_ReusedCurseId_Revert() (gas: 146738) +RMN_voteToCurse:test_UnauthorizedVoter_Revert() (gas: 12600) +RMN_voteToCurse:test_VoteToCurse_NoCurse_Success() (gas: 187244) +RMN_voteToCurse:test_VoteToCurse_YesCurse_Success() (gas: 472452) +RMN_voteToCurse_2:test_VotesAreDroppedIfSubjectIsNotCursedDuringConfigChange() (gas: 370468) +RMN_voteToCurse_2:test_VotesAreRetainedIfSubjectIsCursedDuringConfigChange() (gas: 1151909) +RMN_voteToCurse_Benchmark_1:test_VoteToCurse_NewSubject_NewVoter_NoCurse_gas() (gas: 140968) +RMN_voteToCurse_Benchmark_1:test_VoteToCurse_NewSubject_NewVoter_YesCurse_gas() (gas: 165087) +RMN_voteToCurse_Benchmark_2:test_VoteToCurse_OldSubject_NewVoter_NoCurse_gas() (gas: 121305) +RMN_voteToCurse_Benchmark_2:test_VoteToCurse_OldSubject_OldVoter_NoCurse_gas() (gas: 98247) +RMN_voteToCurse_Benchmark_3:test_VoteToCurse_OldSubject_NewVoter_YesCurse_gas() (gas: 145631) +RateLimiter_constructor:test_Constructor_Success() (gas: 19650) +RateLimiter_consume:test_AggregateValueMaxCapacityExceeded_Revert() (gas: 15916) +RateLimiter_consume:test_AggregateValueRateLimitReached_Revert() (gas: 22222) +RateLimiter_consume:test_ConsumeAggregateValue_Success() (gas: 31353) +RateLimiter_consume:test_ConsumeTokens_Success() (gas: 20336) +RateLimiter_consume:test_ConsumeUnlimited_Success() (gas: 40285) +RateLimiter_consume:test_ConsumingMoreThanUint128_Revert() (gas: 15720) +RateLimiter_consume:test_RateLimitReachedOverConsecutiveBlocks_Revert() (gas: 25594) +RateLimiter_consume:test_Refill_Success() (gas: 37222) +RateLimiter_consume:test_TokenMaxCapacityExceeded_Revert() (gas: 18250) +RateLimiter_consume:test_TokenRateLimitReached_Revert() (gas: 24706) +RateLimiter_currentTokenBucketState:test_CurrentTokenBucketState_Success() (gas: 38647) +RateLimiter_currentTokenBucketState:test_Refill_Success() (gas: 46384) +RateLimiter_setTokenBucketConfig:test_SetRateLimiterConfig_Success() (gas: 38017) +RegistryModuleOwnerCustom_constructor:test_constructor_Revert() (gas: 36031) +RegistryModuleOwnerCustom_registerAdminViaGetCCIPAdmin:test_registerAdminViaGetCCIPAdmin_Revert() (gas: 19637) +RegistryModuleOwnerCustom_registerAdminViaGetCCIPAdmin:test_registerAdminViaGetCCIPAdmin_Success() (gas: 129918) +RegistryModuleOwnerCustom_registerAdminViaOwner:test_registerAdminViaOwner_Revert() (gas: 19451) +RegistryModuleOwnerCustom_registerAdminViaOwner:test_registerAdminViaOwner_Success() (gas: 129731) +Router_applyRampUpdates:test_OffRampMismatch_Revert() (gas: 89288) +Router_applyRampUpdates:test_OffRampUpdatesWithRouting() (gas: 10642128) +Router_applyRampUpdates:test_OnRampDisable() (gas: 55913) +Router_applyRampUpdates:test_OnlyOwner_Revert() (gas: 12311) +Router_ccipSend:test_CCIPSendLinkFeeNoTokenSuccess_gas() (gas: 113861) +Router_ccipSend:test_CCIPSendLinkFeeOneTokenSuccess_gas() (gas: 200634) +Router_ccipSend:test_CCIPSendNativeFeeNoTokenSuccess_gas() (gas: 128508) +Router_ccipSend:test_CCIPSendNativeFeeOneTokenSuccess_gas() (gas: 215283) +Router_ccipSend:test_FeeTokenAmountTooLow_Revert() (gas: 66275) +Router_ccipSend:test_InvalidMsgValue() (gas: 31963) +Router_ccipSend:test_NativeFeeTokenInsufficientValue() (gas: 68711) +Router_ccipSend:test_NativeFeeTokenOverpay_Success() (gas: 173605) +Router_ccipSend:test_NativeFeeTokenZeroValue() (gas: 56037) +Router_ccipSend:test_NativeFeeToken_Success() (gas: 172199) +Router_ccipSend:test_NonLinkFeeToken_Success() (gas: 242707) +Router_ccipSend:test_UnsupportedDestinationChain_Revert() (gas: 24749) +Router_ccipSend:test_WhenNotHealthy_Revert() (gas: 44724) +Router_ccipSend:test_WrappedNativeFeeToken_Success() (gas: 174415) +Router_ccipSend:test_ZeroFeeAndGasPrice_Success() (gas: 245121) +Router_constructor:test_Constructor_Success() (gas: 13074) +Router_getArmProxy:test_getArmProxy() (gas: 10561) +Router_getFee:test_GetFeeSupportedChain_Success() (gas: 46464) +Router_getFee:test_UnsupportedDestinationChain_Revert() (gas: 17138) +Router_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10460) +Router_recoverTokens:test_RecoverTokensInvalidRecipient_Revert() (gas: 11316) +Router_recoverTokens:test_RecoverTokensNoFunds_Revert() (gas: 17761) +Router_recoverTokens:test_RecoverTokensNonOwner_Revert() (gas: 11159) +Router_recoverTokens:test_RecoverTokensValueReceiver_Revert() (gas: 422138) +Router_recoverTokens:test_RecoverTokens_Success() (gas: 50437) +Router_routeMessage:test_AutoExec_Success() (gas: 42684) +Router_routeMessage:test_ExecutionEvent_Success() (gas: 158002) +Router_routeMessage:test_ManualExec_Success() (gas: 35381) +Router_routeMessage:test_OnlyOffRamp_Revert() (gas: 25116) +Router_routeMessage:test_WhenNotHealthy_Revert() (gas: 44724) +Router_setWrappedNative:test_OnlyOwner_Revert() (gas: 10985) +SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 53540) +SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 416930) +SelfFundedPingPong_setCountIncrBeforeFunding:test_setCountIncrBeforeFunding() (gas: 20157) +TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_OnlyPendingAdministrator_Revert() (gas: 51085) +TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_Success() (gas: 43947) +TokenAdminRegistry_addRegistryModule:test_addRegistryModule_OnlyOwner_Revert() (gas: 12629) +TokenAdminRegistry_addRegistryModule:test_addRegistryModule_Success() (gas: 67011) +TokenAdminRegistry_getAllConfiguredTokens:test_getAllConfiguredTokens_outOfBounds_Success() (gas: 11350) +TokenAdminRegistry_getPool:test_getPool_Success() (gas: 17581) +TokenAdminRegistry_getPools:test_getPools_Success() (gas: 39902) +TokenAdminRegistry_isAdministrator:test_isAdministrator_Success() (gas: 105922) +TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_AlreadyRegistered_Revert() (gas: 104001) +TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_OnlyRegistryModule_Revert() (gas: 15481) +TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_ZeroAddress_Revert() (gas: 15026) +TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_module_Success() (gas: 112536) +TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_owner_Success() (gas: 107656) +TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_reRegisterWhileUnclaimed_Success() (gas: 115686) +TokenAdminRegistry_removeRegistryModule:test_removeRegistryModule_OnlyOwner_Revert() (gas: 12585) +TokenAdminRegistry_removeRegistryModule:test_removeRegistryModule_Success() (gas: 54473) +TokenAdminRegistry_setPool:test_setPool_InvalidTokenPoolToken_Revert() (gas: 19148) +TokenAdminRegistry_setPool:test_setPool_OnlyAdministrator_Revert() (gas: 18020) +TokenAdminRegistry_setPool:test_setPool_Success() (gas: 35943) +TokenAdminRegistry_setPool:test_setPool_ZeroAddressRemovesPool_Success() (gas: 30617) +TokenAdminRegistry_transferAdminRole:test_transferAdminRole_OnlyAdministrator_Revert() (gas: 18043) +TokenAdminRegistry_transferAdminRole:test_transferAdminRole_Success() (gas: 49390) +TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6036775) +TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6282531) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6883397) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7067512) +TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2169749) +TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12089) +TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23280) +TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowList_Success() (gas: 177516) +TokenPoolWithAllowList_getAllowList:test_GetAllowList_Success() (gas: 23648) +TokenPoolWithAllowList_getAllowListEnabled:test_GetAllowListEnabled_Success() (gas: 8363) +TokenPoolWithAllowList_setRouter:test_SetRouter_Success() (gas: 24765) +TokenPool_applyChainUpdates:test_applyChainUpdates_DisabledNonZeroRateLimit_Revert() (gas: 271305) +TokenPool_applyChainUpdates:test_applyChainUpdates_InvalidRateLimitRate_Revert() (gas: 541162) +TokenPool_applyChainUpdates:test_applyChainUpdates_NonExistentChain_Revert() (gas: 18344) +TokenPool_applyChainUpdates:test_applyChainUpdates_OnlyCallableByOwner_Revert() (gas: 11385) +TokenPool_applyChainUpdates:test_applyChainUpdates_Success() (gas: 476472) +TokenPool_applyChainUpdates:test_applyChainUpdates_ZeroAddressNotAllowed_Revert() (gas: 157074) +TokenPool_constructor:test_ZeroAddressNotAllowed_Revert() (gas: 70676) +TokenPool_constructor:test_immutableFields_Success() (gas: 20522) +TokenPool_getRemotePool:test_getRemotePool_Success() (gas: 273962) +TokenPool_onlyOffRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 276952) +TokenPool_onlyOffRamp:test_ChainNotAllowed_Revert() (gas: 289509) +TokenPool_onlyOffRamp:test_onlyOffRamp_Success() (gas: 349763) +TokenPool_onlyOnRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 276643) +TokenPool_onlyOnRamp:test_ChainNotAllowed_Revert() (gas: 253466) +TokenPool_onlyOnRamp:test_onlyOnRamp_Success() (gas: 304761) +TokenPool_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 14906) +TokenPool_setChainRateLimiterConfig:test_OnlyOwner_Revert() (gas: 12565) +TokenPool_setRemotePool:test_setRemotePool_NonExistentChain_Reverts() (gas: 15598) +TokenPool_setRemotePool:test_setRemotePool_OnlyOwner_Reverts() (gas: 13173) +TokenPool_setRemotePool:test_setRemotePool_Success() (gas: 281890) +TokenProxy_ccipSend:test_CcipSendGasShouldBeZero_Revert() (gas: 17109) +TokenProxy_ccipSend:test_CcipSendInsufficientAllowance_Revert() (gas: 136351) +TokenProxy_ccipSend:test_CcipSendInvalidToken_Revert() (gas: 15919) +TokenProxy_ccipSend:test_CcipSendNative_Success() (gas: 244483) +TokenProxy_ccipSend:test_CcipSendNoDataAllowed_Revert() (gas: 16303) +TokenProxy_ccipSend:test_CcipSend_Success() (gas: 261100) +TokenProxy_constructor:test_Constructor() (gas: 13812) +TokenProxy_getFee:test_GetFeeGasShouldBeZero_Revert() (gas: 16827) +TokenProxy_getFee:test_GetFeeInvalidToken_Revert() (gas: 12658) +TokenProxy_getFee:test_GetFeeNoDataAllowed_Revert() (gas: 15849) +TokenProxy_getFee:test_GetFee_Success() (gas: 86948) +USDCTokenPool__validateMessage:test_ValidateInvalidMessage_Revert() (gas: 24960) +USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35312) +USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 30063) +USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 132864) +USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 477209) +USDCTokenPool_lockOrBurn:test_lockOrBurn_InvalidReceiver_Revert() (gas: 52606) +USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 289268) +USDCTokenPool_releaseOrMint:test_TokenMaxCapacityExceeded_Revert() (gas: 50682) +USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 119185) +USDCTokenPool_setDomains:test_InvalidDomain_Revert() (gas: 66150) +USDCTokenPool_setDomains:test_OnlyOwner_Revert() (gas: 11339) +USDCTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 9876) \ No newline at end of file diff --git a/contracts/gas-snapshots/liquiditymanager.gas-snapshot b/contracts/gas-snapshots/liquiditymanager.gas-snapshot new file mode 100644 index 0000000000..53483ed6c7 --- /dev/null +++ b/contracts/gas-snapshots/liquiditymanager.gas-snapshot @@ -0,0 +1,48 @@ +LiquidityManager__report:test_EmptyReportReverts() (gas: 11181) +LiquidityManager_addLiquidity:test_addLiquiditySuccess() (gas: 279154) +LiquidityManager_rebalanceLiquidity:test_InsufficientLiquidityReverts() (gas: 206745) +LiquidityManager_rebalanceLiquidity:test_InvalidRemoteChainReverts() (gas: 192319) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess() (gas: 9141768) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 8898695) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 8893901) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 8821699) +LiquidityManager_rebalanceLiquidity:test_rebalanceLiquiditySuccess() (gas: 382897) +LiquidityManager_receive:test_receive_success() (gas: 21182) +LiquidityManager_removeLiquidity:test_InsufficientLiquidityReverts() (gas: 184869) +LiquidityManager_removeLiquidity:test_OnlyFinanceRoleReverts() (gas: 10872) +LiquidityManager_removeLiquidity:test_removeLiquiditySuccess() (gas: 236342) +LiquidityManager_setCrossChainRebalancer:test_OnlyOwnerReverts() (gas: 17005) +LiquidityManager_setCrossChainRebalancer:test_ZeroAddressReverts() (gas: 21624) +LiquidityManager_setCrossChainRebalancer:test_ZeroChainSelectorReverts() (gas: 13099) +LiquidityManager_setCrossChainRebalancer:test_setCrossChainRebalancerSuccess() (gas: 162186) +LiquidityManager_setFinanceRole:test_OnlyOwnerReverts() (gas: 10987) +LiquidityManager_setFinanceRole:test_setFinanceRoleSuccess() (gas: 21836) +LiquidityManager_setLocalLiquidityContainer:test_OnlyOwnerReverts() (gas: 11052) +LiquidityManager_setLocalLiquidityContainer:test_ReverstWhen_CalledWithTheZeroAddress() (gas: 10643) +LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3436651) +LiquidityManager_setMinimumLiquidity:test_OnlyOwnerReverts() (gas: 10925) +LiquidityManager_setMinimumLiquidity:test_setMinimumLiquiditySuccess() (gas: 36389) +LiquidityManager_withdrawERC20:test_withdrawERC20Reverts() (gas: 180359) +LiquidityManager_withdrawERC20:test_withdrawERC20Success() (gas: 205858) +LiquidityManager_withdrawNative:test_OnlyFinanceRoleReverts() (gas: 13046) +LiquidityManager_withdrawNative:test_withdrawNative_success() (gas: 51398) +OCR3Base_setOCR3Config:testFMustBePositiveReverts() (gas: 12245) +OCR3Base_setOCR3Config:testFTooHighReverts() (gas: 12429) +OCR3Base_setOCR3Config:testOracleOutOfRegisterReverts() (gas: 14847) +OCR3Base_setOCR3Config:testRepeatAddressReverts() (gas: 44932) +OCR3Base_setOCR3Config:testSetConfigSuccess() (gas: 154642) +OCR3Base_setOCR3Config:testSignerCannotBeZeroAddressReverts() (gas: 23712) +OCR3Base_setOCR3Config:testTooManySignersReverts() (gas: 19832) +OCR3Base_setOCR3Config:testTransmitterCannotBeZeroAddressReverts() (gas: 46539) +OCR3Base_transmit:testConfigDigestMismatchReverts() (gas: 24827) +OCR3Base_transmit:testForkedChainReverts() (gas: 42846) +OCR3Base_transmit:testNonIncreasingSequenceNumberReverts() (gas: 30522) +OCR3Base_transmit:testNonUniqueSignatureReverts() (gas: 60370) +OCR3Base_transmit:testSignatureOutOfRegistrationReverts() (gas: 26128) +OCR3Base_transmit:testTransmit2SignersSuccess_gas() (gas: 56783) +OCR3Base_transmit:testUnAuthorizedTransmitterReverts() (gas: 28618) +OCR3Base_transmit:testUnauthorizedSignerReverts() (gas: 44759) +OCR3Base_transmit:testWrongNumberOfSignaturesReverts() (gas: 25678) +OptimismL1BridgeAdapter_finalizeWithdrawERC20:testFinalizeWithdrawERC20Reverts() (gas: 12932) +OptimismL1BridgeAdapter_finalizeWithdrawERC20:testfinalizeWithdrawERC20FinalizeSuccess() (gas: 16972) +OptimismL1BridgeAdapter_finalizeWithdrawERC20:testfinalizeWithdrawERC20proveWithdrawalSuccess() (gas: 20758) \ No newline at end of file diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 1b2ac1bdf1..73e70081e9 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -21,7 +21,8 @@ subtask(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS).setAction( async (_, __, runSuper) => { const paths = await runSuper() const noTests = paths.filter((p: string) => !p.endsWith('.t.sol')) - return noTests.filter( + const noCCIP = noTests.filter((p: string) => !p.includes('/v0.8/ccip')) + return noCCIP.filter( (p: string) => !p.includes('src/v0.8/vendor/forge-std'), ) }, diff --git a/contracts/package.json b/contracts/package.json index 5a13d561f0..85bae226c4 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -18,7 +18,7 @@ "prepublishOnly": "pnpm compile && ./scripts/prepublish_generate_abi_folder", "publish-beta": "pnpm publish --tag beta", "publish-prod": "pnpm publish --tag latest", - "solhint": "solhint --max-warnings 2 \"./src/v0.8/**/*.sol\"" + "solhint": "solhint --max-warnings 0 \"./src/v0.8/**/*.sol\"" }, "files": [ "src/v0.8", @@ -78,6 +78,8 @@ "typescript": "^5.4.5" }, "dependencies": { + "@arbitrum/nitro-contracts": "1.1.1", + "@arbitrum/token-bridge-contracts": "1.1.2", "@changesets/changelog-github": "^0.5.0", "@changesets/cli": "~2.27.3", "@eth-optimism/contracts": "0.6.0", diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index 4ad8deda99..825715f416 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -11,6 +11,12 @@ importers: .: dependencies: + '@arbitrum/nitro-contracts': + specifier: 1.1.1 + version: 1.1.1 + '@arbitrum/token-bridge-contracts': + specifier: 1.1.2 + version: 1.1.2 '@changesets/changelog-github': specifier: ^0.5.0 version: 0.5.0 @@ -50,22 +56,22 @@ importers: version: 5.7.2 '@nomicfoundation/hardhat-chai-matchers': specifier: ^1.0.6 - version: 1.0.6(@nomiclabs/hardhat-ethers@2.2.3)(chai@4.4.1)(ethers@5.7.2)(hardhat@2.20.1) + version: 1.0.6(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)))(chai@4.4.1)(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)) '@nomicfoundation/hardhat-ethers': specifier: ^3.0.6 - version: 3.0.6(ethers@5.7.2)(hardhat@2.20.1) + version: 3.0.6(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)) '@nomicfoundation/hardhat-network-helpers': specifier: ^1.0.9 - version: 1.0.10(hardhat@2.20.1) + version: 1.0.10(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)) '@nomicfoundation/hardhat-verify': specifier: ^2.0.7 - version: 2.0.7(hardhat@2.20.1) + version: 2.0.7(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)) '@typechain/ethers-v5': specifier: ^7.2.0 - version: 7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2)(typescript@5.4.5) + version: 7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.4.5))(typescript@5.4.5) '@typechain/hardhat': specifier: ^7.0.0 - version: 7.0.0(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(@typechain/ethers-v5@7.2.0)(ethers@5.7.2)(hardhat@2.20.1)(typechain@8.3.2) + version: 7.0.0(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.4.5))(typescript@5.4.5))(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))(typechain@8.3.2(typescript@5.4.5)) '@types/cbor': specifier: ~5.0.1 version: 5.0.1 @@ -86,7 +92,7 @@ importers: version: 20.12.12 '@typescript-eslint/eslint-plugin': specifier: ^7.10.0 - version: 7.10.0(@typescript-eslint/parser@7.10.0)(eslint@8.57.0)(typescript@5.4.5) + version: 7.10.0(@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) '@typescript-eslint/parser': specifier: ^7.10.0 version: 7.10.0(eslint@8.57.0)(typescript@5.4.5) @@ -113,16 +119,16 @@ importers: version: 9.1.0(eslint@8.57.0) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5) + version: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.2.5) ethers: specifier: ~5.7.2 version: 5.7.2 hardhat: specifier: ~2.20.1 - version: 2.20.1(ts-node@10.9.2)(typescript@5.4.5) + version: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) hardhat-abi-exporter: specifier: ^2.10.1 - version: 2.10.1(hardhat@2.20.1) + version: 2.10.1(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)) hardhat-ignore-warnings: specifier: ^0.2.6 version: 0.2.11 @@ -143,7 +149,7 @@ importers: version: '@chainlink/solhint-plugin-chainlink-solidity@https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c' solhint-plugin-prettier: specifier: ^0.1.0 - version: 0.1.0(prettier-plugin-solidity@1.3.1)(prettier@3.2.5) + version: 0.1.0(prettier-plugin-solidity@1.3.1(prettier@3.2.5))(prettier@3.2.5) ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@20.12.12)(typescript@5.4.5) @@ -160,6 +166,12 @@ packages: resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} engines: {node: '>=0.10.0'} + '@arbitrum/nitro-contracts@1.1.1': + resolution: {integrity: sha512-4Tyk3XVHz+bm8UujUC78LYSw3xAxyYvBCxfEX4z3qE4/ww7Qck/rmce5gbHMzQjArEAzAP2YSfYIFuIFuRXtfg==} + + '@arbitrum/token-bridge-contracts@1.1.2': + resolution: {integrity: sha512-k7AZXiB2HFecJ1KfaDBqgOKe3Loo1ttGLC7hUOVB+0YrihIR6cYpJRuqKSKK4YCy+FF21AUDtaG3x57OFM667Q==} + '@babel/code-frame@7.18.6': resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} @@ -178,7 +190,6 @@ packages: '@chainlink/solhint-plugin-chainlink-solidity@https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c': resolution: {tarball: https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c} - name: '@chainlink/solhint-plugin-chainlink-solidity' version: 1.2.0 '@changesets/apply-release-plan@7.0.1': @@ -572,12 +583,37 @@ packages: ethers: ^5.0.0 hardhat: ^2.0.0 + '@offchainlabs/upgrade-executor@1.1.0-beta.0': + resolution: {integrity: sha512-mpn6PHjH/KDDjNX0pXHEKdyv8m6DVGQiI2nGzQn0JbM1nOSHJpWx6fvfjtH7YxHJ6zBZTcsKkqGkFKDtCfoSLw==} + + '@openzeppelin/contracts-upgradeable@4.5.2': + resolution: {integrity: sha512-xgWZYaPlrEOQo3cBj97Ufiuv79SPd8Brh4GcFYhPgb6WvAq4ppz8dWKL6h+jLAK01rUqMRp/TS9AdXgAeNvCLA==} + + '@openzeppelin/contracts-upgradeable@4.7.3': + resolution: {integrity: sha512-+wuegAMaLcZnLCJIvrVUDzA9z/Wp93f0Dla/4jJvIhijRrPabjQbZe6fWiECLaJyfn5ci9fqf9vTw3xpQOad2A==} + + '@openzeppelin/contracts-upgradeable@4.8.3': + resolution: {integrity: sha512-SXDRl7HKpl2WDoJpn7CK/M9U4Z8gNXDHHChAKh0Iz+Wew3wu6CmFYBeie3je8V0GSXZAIYYwUktSrnW/kwVPtg==} + '@openzeppelin/contracts-upgradeable@4.9.3': resolution: {integrity: sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A==} + '@openzeppelin/contracts@4.5.0': + resolution: {integrity: sha512-fdkzKPYMjrRiPK6K4y64e6GzULR7R7RwxSigHS8DDp7aWDeoReqsQI+cxHV1UuhAqX69L1lAaWDxenfP+xiqzA==} + + '@openzeppelin/contracts@4.7.3': + resolution: {integrity: sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==} + + '@openzeppelin/contracts@4.8.3': + resolution: {integrity: sha512-bQHV8R9Me8IaJoJ2vPG4rXcL7seB7YVuskr4f+f5RyOStSZetwzkWtoqDMl5erkBJy0lDRUnIR2WIkPiC0GJlg==} + '@openzeppelin/contracts@4.9.3': resolution: {integrity: sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg==} + '@openzeppelin/upgrades-core@1.34.4': + resolution: {integrity: sha512-iGN3StqYHYVqqSKs8hWY+Gz6VkiEqOkQccBhHl7lHLGBJF91QUZ8wNMZ59SA5Usg1Fstu/HurvZTCEshPJAZ8w==} + hasBin: true + '@pkgr/core@0.1.1': resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -821,6 +857,9 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@yarnpkg/lockfile@1.1.0': + resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} + abi-to-sol@0.6.6: resolution: {integrity: sha512-PRn81rSpv6NXFPYQSw7ujruqIP6UkwZ/XoFldtiqCX8+2kHVc73xVaUVvdbro06vvBVZiwnxhEIGdI4BRMwGHw==} hasBin: true @@ -924,10 +963,18 @@ packages: array-buffer-byte-length@1.0.0: resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + array.prototype.flat@1.3.2: resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} engines: {node: '>= 0.4'} @@ -936,6 +983,10 @@ packages: resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} engines: {node: '>= 0.4'} + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + arrify@1.0.1: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} @@ -958,6 +1009,10 @@ packages: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + balanced-match@1.0.0: resolution: {integrity: sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==} @@ -1056,6 +1111,10 @@ packages: call-bind@1.0.5: resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1083,6 +1142,10 @@ packages: resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} engines: {node: '>=12.19'} + cbor@9.0.2: + resolution: {integrity: sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==} + engines: {node: '>=16'} + chai-as-promised@7.1.1: resolution: {integrity: sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==} peerDependencies: @@ -1183,6 +1246,9 @@ packages: commander@3.0.2: resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==} + compare-versions@6.1.1: + resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1215,6 +1281,10 @@ packages: cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + cross-spawn@6.0.5: + resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} + engines: {node: '>=4.8'} + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1232,6 +1302,18 @@ packages: resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==} engines: {node: '>= 0.1.90'} + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} @@ -1285,6 +1367,10 @@ packages: resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} engines: {node: '>= 0.4'} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} @@ -1349,10 +1435,30 @@ packages: resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} engines: {node: '>= 0.4'} + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + es-set-tostringtag@2.0.2: resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} engines: {node: '>= 0.4'} + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + es-shim-unscopables@1.0.2: resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} @@ -1520,6 +1626,9 @@ packages: find-yarn-workspace-root2@1.2.16: resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} + find-yarn-workspace-root@2.0.0: + resolution: {integrity: sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==} + flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -1592,6 +1701,10 @@ packages: get-intrinsic@1.2.2: resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + get-stream@5.1.0: resolution: {integrity: sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==} engines: {node: '>=8'} @@ -1604,6 +1717,10 @@ packages: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1692,10 +1809,17 @@ packages: has-property-descriptors@1.0.0: resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + has-proto@1.0.1: resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} engines: {node: '>= 0.4'} + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} @@ -1704,6 +1828,10 @@ packages: resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} engines: {node: '>= 0.4'} + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + has@1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} @@ -1719,6 +1847,10 @@ packages: resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} engines: {node: '>= 0.4'} + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true @@ -1790,12 +1922,20 @@ packages: resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} engines: {node: '>= 0.4'} + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + io-ts@1.10.4: resolution: {integrity: sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==} is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -1814,13 +1954,26 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} + is-ci@2.0.0: + resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} + hasBin: true + is-core-module@2.10.0: resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==} + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + is-date-object@1.0.2: resolution: {integrity: sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==} engines: {node: '>= 0.4'} + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1844,6 +1997,10 @@ packages: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} @@ -1871,6 +2028,10 @@ packages: is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -1887,6 +2048,10 @@ packages: resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} engines: {node: '>= 0.4'} + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} @@ -1901,6 +2066,10 @@ packages: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} @@ -1970,6 +2139,9 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} + klaw-sync@6.0.0: + resolution: {integrity: sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==} + klaw@1.3.1: resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} @@ -2170,6 +2342,9 @@ packages: neodoc@2.0.2: resolution: {integrity: sha512-NAppJ0YecKWdhSXFYCHbo6RutiX8vOt/Jo3l46mUg6pQlpJNaqc5cGxdrW2jITQm5JIYySbFVPDl3RrREXNyPw==} + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + no-case@2.3.2: resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==} @@ -2227,12 +2402,20 @@ packages: resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} engines: {node: '>= 0.4'} + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + obliterator@2.0.4: resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + open@7.4.2: + resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} + engines: {node: '>=8'} + optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -2313,6 +2496,11 @@ packages: pascal-case@2.0.1: resolution: {integrity: sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==} + patch-package@6.5.1: + resolution: {integrity: sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==} + engines: {node: '>=10', npm: '>5'} + hasBin: true + path-case@2.1.1: resolution: {integrity: sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==} @@ -2328,6 +2516,10 @@ packages: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -2366,6 +2558,10 @@ packages: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + preferred-pm@3.1.3: resolution: {integrity: sha512-MkXsENfftWSRpzCzImcp4FRsCc3y1opwB73CfCNWyzMqArju2CrlMHlqB7VexKiPEOjGMbttv1r9fSCn5S610w==} engines: {node: '>=10'} @@ -2394,6 +2590,9 @@ packages: engines: {node: '>=14'} hasBin: true + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} @@ -2464,6 +2663,10 @@ packages: resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} engines: {node: '>= 0.4'} + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + registry-auth-token@5.0.2: resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==} engines: {node: '>=14'} @@ -2504,6 +2707,10 @@ packages: responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -2536,6 +2743,10 @@ packages: resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} engines: {node: '>=0.4'} + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -2545,6 +2756,10 @@ packages: safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -2581,6 +2796,10 @@ packages: resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} engines: {node: '>= 0.4'} + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + set-function-name@2.0.1: resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} engines: {node: '>= 0.4'} @@ -2620,6 +2839,10 @@ packages: signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + slash@2.0.0: + resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} + engines: {node: '>=6'} + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -2651,6 +2874,9 @@ packages: resolution: {integrity: sha512-QeQLS9HGCnIiibt+xiOa/+MuP7BWz9N7C5+Mj9pLHshdkNhuo3AzCpWmjfWVZBUuwIUO3YyCRVIcYLR3YOKGfg==} hasBin: true + solidity-ast@0.4.56: + resolution: {integrity: sha512-HgmsA/Gfklm/M8GFbCX/J1qkVH0spXHgALCNZ8fA8x5X+MFdn/8CP2gr5OVyXjXw6RZTPC/Sxl2RUDQOXyNMeA==} + solidity-comments-darwin-arm64@0.0.2: resolution: {integrity: sha512-HidWkVLSh7v+Vu0CA7oI21GWP/ZY7ro8g8OmIxE8oTqyMwgMbE8F1yc58Sj682Hj199HCZsjmtn1BE4PCbLiGA==} engines: {node: '>= 10'} @@ -2768,12 +2994,23 @@ packages: resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} engines: {node: '>= 0.4'} + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + string.prototype.trimend@1.0.7: resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + string.prototype.trimstart@1.0.7: resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -2952,17 +3189,33 @@ packages: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} engines: {node: '>= 0.4'} + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + typed-array-byte-length@1.0.0: resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} engines: {node: '>= 0.4'} + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + typed-array-byte-offset@1.0.0: resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} engines: {node: '>= 0.4'} + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + typescript@5.4.5: resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} engines: {node: '>=14.17'} @@ -3050,6 +3303,10 @@ packages: resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} engines: {node: '>= 0.4'} + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} hasBin: true @@ -3115,6 +3372,10 @@ packages: yallist@2.1.2: resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + yargs-parser@18.1.3: resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} engines: {node: '>=6'} @@ -3155,6 +3416,24 @@ snapshots: '@aashutoshrathi/word-wrap@1.2.6': {} + '@arbitrum/nitro-contracts@1.1.1': + dependencies: + '@offchainlabs/upgrade-executor': 1.1.0-beta.0 + '@openzeppelin/contracts': 4.5.0 + '@openzeppelin/contracts-upgradeable': 4.5.2 + patch-package: 6.5.1 + + '@arbitrum/token-bridge-contracts@1.1.2': + dependencies: + '@arbitrum/nitro-contracts': 1.1.1 + '@offchainlabs/upgrade-executor': 1.1.0-beta.0 + '@openzeppelin/contracts': 4.8.3 + '@openzeppelin/contracts-upgradeable': 4.8.3 + optionalDependencies: + '@openzeppelin/upgrades-core': 1.34.4 + transitivePeerDependencies: + - supports-color + '@babel/code-frame@7.18.6': dependencies: '@babel/highlight': 7.18.6 @@ -3787,11 +4066,12 @@ snapshots: '@nomicfoundation/ethereumjs-rlp': 5.0.4 '@nomicfoundation/ethereumjs-trie': 6.0.4 '@nomicfoundation/ethereumjs-util': 9.0.4 - '@nomicfoundation/ethereumjs-verkle': 0.0.2 debug: 4.3.4(supports-color@8.1.1) ethereum-cryptography: 0.1.3 js-sdsl: 4.4.2 lru-cache: 10.2.2 + optionalDependencies: + '@nomicfoundation/ethereumjs-verkle': 0.0.2 transitivePeerDependencies: - c-kzg - supports-color @@ -3846,40 +4126,40 @@ snapshots: - c-kzg - supports-color - '@nomicfoundation/hardhat-chai-matchers@1.0.6(@nomiclabs/hardhat-ethers@2.2.3)(chai@4.4.1)(ethers@5.7.2)(hardhat@2.20.1)': + '@nomicfoundation/hardhat-chai-matchers@1.0.6(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)))(chai@4.4.1)(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))': dependencies: '@ethersproject/abi': 5.7.0 - '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.20.1) + '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)) '@types/chai-as-promised': 7.1.8 chai: 4.4.1 chai-as-promised: 7.1.1(chai@4.4.1) deep-eql: 4.1.3 ethers: 5.7.2 - hardhat: 2.20.1(ts-node@10.9.2)(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) ordinal: 1.0.3 - '@nomicfoundation/hardhat-ethers@3.0.6(ethers@5.7.2)(hardhat@2.20.1)': + '@nomicfoundation/hardhat-ethers@3.0.6(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))': dependencies: debug: 4.3.4(supports-color@8.1.1) ethers: 5.7.2 - hardhat: 2.20.1(ts-node@10.9.2)(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) lodash.isequal: 4.5.0 transitivePeerDependencies: - supports-color - '@nomicfoundation/hardhat-network-helpers@1.0.10(hardhat@2.20.1)': + '@nomicfoundation/hardhat-network-helpers@1.0.10(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))': dependencies: ethereumjs-util: 7.1.5 - hardhat: 2.20.1(ts-node@10.9.2)(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) - '@nomicfoundation/hardhat-verify@2.0.7(hardhat@2.20.1)': + '@nomicfoundation/hardhat-verify@2.0.7(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))': dependencies: '@ethersproject/abi': 5.7.0 '@ethersproject/address': 5.7.0 cbor: 8.1.0 chalk: 2.4.2 debug: 4.3.4(supports-color@8.1.1) - hardhat: 2.20.1(ts-node@10.9.2)(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) lodash.clonedeep: 4.5.0 semver: 6.3.0 table: 6.8.1 @@ -3930,15 +4210,46 @@ snapshots: '@nomicfoundation/solidity-analyzer-win32-ia32-msvc': 0.1.0 '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.0 - '@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.20.1)': + '@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))': dependencies: ethers: 5.7.2 - hardhat: 2.20.1(ts-node@10.9.2)(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) + + '@offchainlabs/upgrade-executor@1.1.0-beta.0': + dependencies: + '@openzeppelin/contracts': 4.7.3 + '@openzeppelin/contracts-upgradeable': 4.7.3 + + '@openzeppelin/contracts-upgradeable@4.5.2': {} + + '@openzeppelin/contracts-upgradeable@4.7.3': {} + + '@openzeppelin/contracts-upgradeable@4.8.3': {} '@openzeppelin/contracts-upgradeable@4.9.3': {} + '@openzeppelin/contracts@4.5.0': {} + + '@openzeppelin/contracts@4.7.3': {} + + '@openzeppelin/contracts@4.8.3': {} + '@openzeppelin/contracts@4.9.3': {} + '@openzeppelin/upgrades-core@1.34.4': + dependencies: + cbor: 9.0.2 + chalk: 4.1.2 + compare-versions: 6.1.1 + debug: 4.3.4(supports-color@8.1.1) + ethereumjs-util: 7.1.5 + minimist: 1.2.8 + proper-lockfile: 4.1.2 + solidity-ast: 0.4.56 + transitivePeerDependencies: + - supports-color + optional: true + '@pkgr/core@0.1.1': {} '@pnpm/config.env-replace@1.1.0': {} @@ -4052,7 +4363,7 @@ snapshots: '@tsconfig/node16@1.0.3': {} - '@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2)(typescript@5.4.5)': + '@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.4.5))(typescript@5.4.5)': dependencies: '@ethersproject/abi': 5.7.0 '@ethersproject/bytes': 5.7.0 @@ -4063,14 +4374,14 @@ snapshots: typechain: 8.3.2(typescript@5.4.5) typescript: 5.4.5 - '@typechain/hardhat@7.0.0(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(@typechain/ethers-v5@7.2.0)(ethers@5.7.2)(hardhat@2.20.1)(typechain@8.3.2)': + '@typechain/hardhat@7.0.0(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.4.5))(typescript@5.4.5))(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))(typechain@8.3.2(typescript@5.4.5))': dependencies: '@ethersproject/abi': 5.7.0 '@ethersproject/providers': 5.7.2 - '@typechain/ethers-v5': 7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2)(typescript@5.4.5) + '@typechain/ethers-v5': 7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.4.5))(typescript@5.4.5) ethers: 5.7.2 fs-extra: 9.1.0 - hardhat: 2.20.1(ts-node@10.9.2)(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) typechain: 8.3.2(typescript@5.4.5) '@types/bn.js@4.11.6': @@ -4147,7 +4458,7 @@ snapshots: '@types/semver@7.5.0': {} - '@typescript-eslint/eslint-plugin@7.10.0(@typescript-eslint/parser@7.10.0)(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@7.10.0(@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': dependencies: '@eslint-community/regexpp': 4.10.0 '@typescript-eslint/parser': 7.10.0(eslint@8.57.0)(typescript@5.4.5) @@ -4160,6 +4471,7 @@ snapshots: ignore: 5.3.1 natural-compare: 1.4.0 ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color @@ -4172,6 +4484,7 @@ snapshots: '@typescript-eslint/visitor-keys': 7.10.0 debug: 4.3.4(supports-color@8.1.1) eslint: 8.57.0 + optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color @@ -4188,6 +4501,7 @@ snapshots: debug: 4.3.4(supports-color@8.1.1) eslint: 8.57.0 ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color @@ -4204,6 +4518,7 @@ snapshots: minimatch: 9.0.4 semver: 7.6.2 ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color @@ -4226,6 +4541,8 @@ snapshots: '@ungap/structured-clone@1.2.0': {} + '@yarnpkg/lockfile@1.1.0': {} + abi-to-sol@0.6.6: dependencies: '@truffle/abi-utils': 0.3.2 @@ -4328,8 +4645,24 @@ snapshots: call-bind: 1.0.5 is-array-buffer: 3.0.2 + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + optional: true + array-union@2.1.0: {} + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + optional: true + array.prototype.flat@1.3.2: dependencies: call-bind: 1.0.5 @@ -4347,6 +4680,18 @@ snapshots: is-array-buffer: 3.0.2 is-shared-array-buffer: 1.0.2 + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + optional: true + arrify@1.0.1: {} assertion-error@1.1.0: {} @@ -4359,6 +4704,11 @@ snapshots: available-typed-arrays@1.0.5: {} + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + optional: true + balanced-match@1.0.0: {} base-x@3.0.9: @@ -4473,6 +4823,15 @@ snapshots: get-intrinsic: 1.2.2 set-function-length: 1.1.1 + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + optional: true + callsites@3.1.0: {} camel-case@3.0.0: @@ -4499,6 +4858,11 @@ snapshots: dependencies: nofilter: 3.1.0 + cbor@9.0.2: + dependencies: + nofilter: 3.1.0 + optional: true + chai-as-promised@7.1.1(chai@4.4.1): dependencies: chai: 4.4.1 @@ -4635,6 +4999,9 @@ snapshots: commander@3.0.2: {} + compare-versions@6.1.1: + optional: true + concat-map@0.0.1: {} config-chain@1.1.13: @@ -4683,6 +5050,14 @@ snapshots: shebang-command: 1.2.0 which: 1.3.1 + cross-spawn@6.0.5: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.1 + shebang-command: 1.2.0 + which: 1.3.1 + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 @@ -4702,11 +5077,33 @@ snapshots: csv-stringify: 5.6.5 stream-transform: 2.1.3 + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + optional: true + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + optional: true + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + optional: true + dataloader@1.4.0: {} debug@4.3.4(supports-color@8.1.1): dependencies: ms: 2.1.2 + optionalDependencies: supports-color: 8.1.1 decamelize-keys@1.1.1: @@ -4747,6 +5144,13 @@ snapshots: gopd: 1.0.1 has-property-descriptors: 1.0.0 + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + optional: true + define-properties@1.2.1: dependencies: define-data-property: 1.1.1 @@ -4850,12 +5254,82 @@ snapshots: unbox-primitive: 1.0.2 which-typed-array: 1.1.13 + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + optional: true + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + optional: true + + es-errors@1.3.0: + optional: true + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + optional: true + es-set-tostringtag@2.0.2: dependencies: get-intrinsic: 1.2.2 has-tostringtag: 1.0.0 hasown: 2.0.0 + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + optional: true + es-shim-unscopables@1.0.2: dependencies: hasown: 2.0.0 @@ -4876,13 +5350,14 @@ snapshots: dependencies: eslint: 8.57.0 - eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5): + eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.2.5): dependencies: eslint: 8.57.0 - eslint-config-prettier: 9.1.0(eslint@8.57.0) prettier: 3.2.5 prettier-linter-helpers: 1.0.0 synckit: 0.8.8 + optionalDependencies: + eslint-config-prettier: 9.1.0(eslint@8.57.0) eslint-scope@7.2.2: dependencies: @@ -5120,6 +5595,10 @@ snapshots: micromatch: 4.0.5 pkg-dir: 4.2.0 + find-yarn-workspace-root@2.0.0: + dependencies: + micromatch: 4.0.5 + flat-cache@3.2.0: dependencies: flatted: 3.3.1 @@ -5131,7 +5610,7 @@ snapshots: flatted@3.3.1: {} follow-redirects@1.15.6(debug@4.3.4): - dependencies: + optionalDependencies: debug: 4.3.4(supports-color@8.1.1) for-each@0.3.3: @@ -5196,6 +5675,15 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.0 + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.1 + has-symbols: 1.0.3 + hasown: 2.0.0 + optional: true + get-stream@5.1.0: dependencies: pump: 3.0.0 @@ -5207,6 +5695,13 @@ snapshots: call-bind: 1.0.5 get-intrinsic: 1.2.2 + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + optional: true + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -5295,11 +5790,11 @@ snapshots: hard-rejection@2.1.0: {} - hardhat-abi-exporter@2.10.1(hardhat@2.20.1): + hardhat-abi-exporter@2.10.1(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)): dependencies: '@ethersproject/abi': 5.7.0 delete-empty: 3.0.0 - hardhat: 2.20.1(ts-node@10.9.2)(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) hardhat-ignore-warnings@0.2.11: dependencies: @@ -5307,7 +5802,7 @@ snapshots: node-interval-tree: 2.1.2 solidity-comments: 0.0.2 - hardhat@2.20.1(ts-node@10.9.2)(typescript@5.4.5): + hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5): dependencies: '@ethersproject/abi': 5.7.0 '@metamask/eth-sig-util': 4.0.1 @@ -5355,12 +5850,13 @@ snapshots: solc: 0.7.3(debug@4.3.4) source-map-support: 0.5.21 stacktrace-parser: 0.1.10 - ts-node: 10.9.2(@types/node@20.12.12)(typescript@5.4.5) tsort: 0.0.1 - typescript: 5.4.5 undici: 5.28.4 uuid: 8.3.2 ws: 7.5.9 + optionalDependencies: + ts-node: 10.9.2(@types/node@20.12.12)(typescript@5.4.5) + typescript: 5.4.5 transitivePeerDependencies: - bufferutil - c-kzg @@ -5377,14 +5873,27 @@ snapshots: dependencies: get-intrinsic: 1.2.2 + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + optional: true + has-proto@1.0.1: {} + has-proto@1.0.3: + optional: true + has-symbols@1.0.3: {} has-tostringtag@1.0.0: dependencies: has-symbols: 1.0.3 + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + optional: true + has@1.0.3: dependencies: function-bind: 1.1.2 @@ -5404,6 +5913,11 @@ snapshots: dependencies: function-bind: 1.1.2 + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + optional: true + he@1.2.0: {} header-case@1.0.1: @@ -5477,6 +5991,13 @@ snapshots: hasown: 2.0.0 side-channel: 1.0.4 + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.4 + optional: true + io-ts@1.10.4: dependencies: fp-ts: 1.19.3 @@ -5487,6 +6008,12 @@ snapshots: get-intrinsic: 1.2.2 is-typed-array: 1.1.12 + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + optional: true + is-arrayish@0.2.1: {} is-bigint@1.0.4: @@ -5504,12 +6031,23 @@ snapshots: is-callable@1.2.7: {} + is-ci@2.0.0: + dependencies: + ci-info: 2.0.0 + is-core-module@2.10.0: dependencies: has: 1.0.3 + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + optional: true + is-date-object@1.0.2: {} + is-docker@2.2.1: {} + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -5526,6 +6064,9 @@ snapshots: is-negative-zero@2.0.2: {} + is-negative-zero@2.0.3: + optional: true + is-number-object@1.0.7: dependencies: has-tostringtag: 1.0.0 @@ -5547,6 +6088,11 @@ snapshots: dependencies: call-bind: 1.0.5 + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + optional: true + is-string@1.0.7: dependencies: has-tostringtag: 1.0.0 @@ -5563,6 +6109,11 @@ snapshots: dependencies: which-typed-array: 1.1.13 + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + optional: true + is-unicode-supported@0.1.0: {} is-upper-case@1.1.2: @@ -5575,6 +6126,10 @@ snapshots: is-windows@1.0.2: {} + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + isarray@2.0.5: {} isexe@2.0.0: {} @@ -5641,6 +6196,10 @@ snapshots: kind-of@6.0.3: {} + klaw-sync@6.0.0: + dependencies: + graceful-fs: 4.2.10 + klaw@1.3.1: optionalDependencies: graceful-fs: 4.2.10 @@ -5839,6 +6398,8 @@ snapshots: dependencies: ansi-regex: 2.1.1 + nice-try@1.0.5: {} + no-case@2.3.2: dependencies: lower-case: 1.1.4 @@ -5886,12 +6447,25 @@ snapshots: has-symbols: 1.0.3 object-keys: 1.1.1 + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + optional: true + obliterator@2.0.4: {} once@1.4.0: dependencies: wrappy: 1.0.2 + open@7.4.2: + dependencies: + is-docker: 2.2.1 + is-wsl: 2.2.0 + optionator@0.9.3: dependencies: '@aashutoshrathi/word-wrap': 1.2.6 @@ -5974,6 +6548,23 @@ snapshots: camel-case: 3.0.0 upper-case-first: 1.1.2 + patch-package@6.5.1: + dependencies: + '@yarnpkg/lockfile': 1.1.0 + chalk: 4.1.2 + cross-spawn: 6.0.5 + find-yarn-workspace-root: 2.0.0 + fs-extra: 9.1.0 + is-ci: 2.0.0 + klaw-sync: 6.0.0 + minimist: 1.2.8 + open: 7.4.2 + rimraf: 2.7.1 + semver: 5.7.1 + slash: 2.0.0 + tmp: 0.0.33 + yaml: 1.10.2 + path-case@2.1.1: dependencies: no-case: 2.3.2 @@ -5984,6 +6575,8 @@ snapshots: path-is-absolute@1.0.1: {} + path-key@2.0.1: {} + path-key@3.1.1: {} path-parse@1.0.7: {} @@ -6012,6 +6605,9 @@ snapshots: pluralize@8.0.0: {} + possible-typed-array-names@1.0.0: + optional: true + preferred-pm@3.1.3: dependencies: find-up: 5.0.0 @@ -6044,6 +6640,13 @@ snapshots: prettier@3.2.5: {} + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.10 + retry: 0.12.0 + signal-exit: 3.0.7 + optional: true + proto-list@1.2.4: {} pseudomap@1.0.2: {} @@ -6124,6 +6727,14 @@ snapshots: define-properties: 1.2.1 set-function-name: 2.0.1 + regexp.prototype.flags@1.5.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.1 + optional: true + registry-auth-token@5.0.2: dependencies: '@pnpm/npm-conf': 2.2.2 @@ -6158,6 +6769,9 @@ snapshots: dependencies: lowercase-keys: 2.0.0 + retry@0.12.0: + optional: true + reusify@1.0.4: {} rimraf@2.7.1: @@ -6192,6 +6806,14 @@ snapshots: has-symbols: 1.0.3 isarray: 2.0.5 + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + optional: true + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -6202,6 +6824,13 @@ snapshots: get-intrinsic: 1.2.2 is-regex: 1.1.4 + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + optional: true + safer-buffer@2.1.2: {} scrypt-js@3.0.1: {} @@ -6236,6 +6865,16 @@ snapshots: gopd: 1.0.1 has-property-descriptors: 1.0.0 + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + optional: true + set-function-name@2.0.1: dependencies: define-data-property: 1.1.1 @@ -6273,6 +6912,8 @@ snapshots: signal-exit@3.0.7: {} + slash@2.0.0: {} + slash@3.0.0: {} slice-ansi@4.0.0: @@ -6308,7 +6949,7 @@ snapshots: transitivePeerDependencies: - debug - solhint-plugin-prettier@0.1.0(prettier-plugin-solidity@1.3.1)(prettier@3.2.5): + solhint-plugin-prettier@0.1.0(prettier-plugin-solidity@1.3.1(prettier@3.2.5))(prettier@3.2.5): dependencies: '@prettier/sync': 0.3.0(prettier@3.2.5) prettier: 3.2.5 @@ -6338,6 +6979,11 @@ snapshots: optionalDependencies: prettier: 2.8.8 + solidity-ast@0.4.56: + dependencies: + array.prototype.findlast: 1.2.5 + optional: true + solidity-comments-darwin-arm64@0.0.2: optional: true @@ -6439,18 +7085,40 @@ snapshots: define-properties: 1.2.1 es-abstract: 1.22.3 + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + optional: true + string.prototype.trimend@1.0.7: dependencies: call-bind: 1.0.5 define-properties: 1.2.1 es-abstract: 1.22.3 + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + optional: true + string.prototype.trimstart@1.0.7: dependencies: call-bind: 1.0.5 define-properties: 1.2.1 es-abstract: 1.22.3 + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + optional: true + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -6628,6 +7296,13 @@ snapshots: get-intrinsic: 1.2.2 is-typed-array: 1.1.12 + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + optional: true + typed-array-byte-length@1.0.0: dependencies: call-bind: 1.0.5 @@ -6635,6 +7310,15 @@ snapshots: has-proto: 1.0.1 is-typed-array: 1.1.12 + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + optional: true + typed-array-byte-offset@1.0.0: dependencies: available-typed-arrays: 1.0.5 @@ -6643,12 +7327,32 @@ snapshots: has-proto: 1.0.1 is-typed-array: 1.1.12 + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + optional: true + typed-array-length@1.0.4: dependencies: call-bind: 1.0.5 for-each: 0.3.3 is-typed-array: 1.1.12 + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + optional: true + typescript@5.4.5: {} typical@4.0.0: {} @@ -6741,6 +7445,15 @@ snapshots: gopd: 1.0.1 has-tostringtag: 1.0.0 + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + optional: true + which@1.3.1: dependencies: isexe: 2.0.0 @@ -6784,6 +7497,8 @@ snapshots: yallist@2.1.2: {} + yaml@1.10.2: {} + yargs-parser@18.1.3: dependencies: camelcase: 5.3.1 diff --git a/contracts/remappings.txt b/contracts/remappings.txt index 1428f50b31..ec64b1b211 100644 --- a/contracts/remappings.txt +++ b/contracts/remappings.txt @@ -1,6 +1,7 @@ forge-std/=src/v0.8/vendor/forge-std/src/ @openzeppelin/=node_modules/@openzeppelin/ +@arbitrum/=node_modules/@arbitrum/ hardhat/=node_modules/hardhat/ @eth-optimism/=node_modules/@eth-optimism/ @scroll-tech/=node_modules/@scroll-tech/ diff --git a/contracts/scripts/ccip_lcov_prune b/contracts/scripts/ccip_lcov_prune new file mode 100755 index 0000000000..002e5a3f13 --- /dev/null +++ b/contracts/scripts/ccip_lcov_prune @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -e + +# src/v0.8/ccip/libraries/Internal.sol +# src/v0.8/ccip/libraries/RateLimiter.sol +# src/v0.8/ccip/libraries/USDPriceWith18Decimals.sol +# src/v0.8/ccip/libraries/MerkleMultiProof.sol +# src/v0.8/ccip/libraries/Pool.sol +# excluded because Foundry doesn't support coverage on library files + +# BurnWithFromMintTokenPool is excluded because Forge doesn't seem to +# register coverage, even though it is 100% covered. + +lcov --remove $1 -o $2 \ + '*/ccip/test/*' \ + '*/vendor/*' \ + '*/shared/*' \ + 'src/v0.8/ccip/ocr/OCR2Abstract.sol' \ + 'src/v0.8/ccip/libraries/Internal.sol' \ + 'src/v0.8/ccip/libraries/RateLimiter.sol' \ + 'src/v0.8/ccip/libraries/USDPriceWith18Decimals.sol' \ + 'src/v0.8/ccip/libraries/MerkleMultiProof.sol' \ + 'src/v0.8/ccip/libraries/Pool.sol' \ + 'src/v0.8/ConfirmedOwnerWithProposal.sol' \ + 'src/v0.8/tests/MockV3Aggregator.sol' \ + 'src/v0.8/ccip/applications/CCIPClientExample.sol' \ + 'src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol' \ + --rc lcov_branch_coverage=1 diff --git a/contracts/scripts/native_solc_compile_all b/contracts/scripts/native_solc_compile_all index 542337a191..6e9f17561d 100755 --- a/contracts/scripts/native_solc_compile_all +++ b/contracts/scripts/native_solc_compile_all @@ -12,7 +12,7 @@ python3 -m pip install --require-hashes -r $SCRIPTPATH/requirements.txt # 6 and 7 are legacy contracts, for each other product we have a native_solc_compile_all_$product script # These scripts can be run individually, or all together with this script. # To add new CL products, simply write a native_solc_compile_all_$product script and add it to the list below. -for product in automation events_mock feeds functions keystone llo-feeds logpoller operatorforwarder shared transmission vrf +for product in automation events_mock feeds functions keystone llo-feeds logpoller operatorforwarder shared transmission vrf ccip liquiditymanager do $SCRIPTPATH/native_solc_compile_all_$product done diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip new file mode 100755 index 0000000000..1dbb70502d --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -0,0 +1,97 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling CCIP contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.8.24" +OPTIMIZE_RUNS=26000 +OPTIMIZE_RUNS_OFFRAMP=18000 +OPTIMIZE_RUNS_ONRAMP=4100 +OPTIMIZE_RUNS_MULTI_OFFRAMP=2500 + + +SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +python3 -m pip install --require-hashes -r "$SCRIPTPATH"/requirements.txt +solc-select install $SOLC_VERSION +solc-select use $SOLC_VERSION +export SOLC_VERSION=$SOLC_VERSION + +ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; cd ../../ && pwd -P )" + +compileContract () { + local contract + contract=$(basename "$1" ".sol") + + local optimize_runs=$OPTIMIZE_RUNS + + case $1 in + "ccip/offRamp/EVM2EVMOffRamp.sol") + echo "OffRamp uses $OPTIMIZE_RUNS_OFFRAMP optimizer runs." + optimize_runs=$OPTIMIZE_RUNS_OFFRAMP + ;; + "ccip/offRamp/EVM2EVMMultiOffRamp.sol") + echo "MultiOffRamp uses $OPTIMIZE_RUNS_MULTI_OFFRAMP optimizer runs." + optimize_runs=$OPTIMIZE_RUNS_MULTI_OFFRAMP + ;; + "ccip/onRamp/EVM2EVMOnRamp.sol") + echo "OnRamp uses $OPTIMIZE_RUNS_ONRAMP optimizer runs." + optimize_runs=$OPTIMIZE_RUNS_ONRAMP + ;; + esac + + solc --overwrite --optimize --optimize-runs $optimize_runs --metadata-hash none \ + -o "$ROOT"/contracts/solc/v$SOLC_VERSION/"$contract" \ + --abi --bin --allow-paths "$ROOT"/contracts/src/v0.8 \ + --evm-version paris \ + "$ROOT"/contracts/src/v0.8/"$1" +} + + +# Solc produces and overwrites intermediary contracts. +# Contracts should be ordered in reverse-import-complexity-order to minimize overwrite risks. +compileContract ccip/offRamp/EVM2EVMOffRamp.sol +compileContract ccip/offRamp/EVM2EVMMultiOffRamp.sol +compileContract ccip/applications/PingPongDemo.sol +compileContract ccip/applications/SelfFundedPingPong.sol +compileContract ccip/applications/EtherSenderReceiver.sol +compileContract ccip/onRamp/EVM2EVMMultiOnRamp.sol +compileContract ccip/onRamp/EVM2EVMOnRamp.sol +compileContract ccip/CommitStore.sol +compileContract ccip/MultiAggregateRateLimiter.sol +compileContract ccip/Router.sol +compileContract ccip/PriceRegistry.sol +compileContract ccip/pools/LockReleaseTokenPool.sol +compileContract ccip/pools/BurnMintTokenPool.sol +compileContract ccip/pools/BurnFromMintTokenPool.sol +compileContract ccip/pools/BurnWithFromMintTokenPool.sol +compileContract ccip/pools/LockReleaseTokenPoolAndProxy.sol +compileContract ccip/pools/BurnMintTokenPoolAndProxy.sol +compileContract ccip/pools/TokenPool.sol +compileContract shared/token/ERC677/BurnMintERC677.sol +compileContract ccip/RMN.sol +compileContract ccip/ARMProxy.sol +compileContract ccip/tokenAdminRegistry/TokenAdminRegistry.sol +compileContract ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol +compileContract ccip/capability/CCIPConfig.sol +compileContract ccip/capability/interfaces/IOCR3ConfigEncoder.sol +compileContract ccip/NonceManager.sol + +# Test helpers +compileContract ccip/test/helpers/BurnMintERC677Helper.sol +compileContract ccip/test/helpers/CommitStoreHelper.sol +compileContract ccip/test/helpers/MessageHasher.sol +compileContract ccip/test/helpers/ReportCodec.sol +compileContract ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol +compileContract ccip/test/helpers/MultiOCR3Helper.sol +compileContract ccip/test/mocks/MockRMN1_0.sol +compileContract ccip/test/mocks/MockE2EUSDCTokenMessenger.sol +compileContract ccip/test/mocks/MockE2EUSDCTransmitter.sol +compileContract ccip/test/WETH9.sol + +# Customer contracts +compileContract ccip/pools/USDC/USDCTokenPool.sol + +compileContract tests/MockV3Aggregator.sol diff --git a/contracts/scripts/native_solc_compile_all_liquiditymanager b/contracts/scripts/native_solc_compile_all_liquiditymanager new file mode 100755 index 0000000000..a29f041c77 --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_liquiditymanager @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling LiquidityManager contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.8.24" +OPTIMIZE_RUNS=1000000 + + +SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +python3 -m pip install --require-hashes -r "$SCRIPTPATH"/requirements.txt +solc-select install $SOLC_VERSION +solc-select use $SOLC_VERSION +export SOLC_VERSION=$SOLC_VERSION + +ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; cd ../../ && pwd -P )" + +compileContract () { + local contract + contract=$(basename "$1" ".sol") + + solc @arbitrum/="$ROOT"/contracts/node_modules/@arbitrum/ \ + @eth-optimism/="$ROOT"/contracts/node_modules/@eth-optimism/ \ + @openzeppelin/="$ROOT"/contracts/node_modules/@openzeppelin/ \ + --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + -o "$ROOT"/contracts/solc/v$SOLC_VERSION/"$contract" \ + --abi --bin --allow-paths "$ROOT"/contracts/src/v0.8,"$ROOT"/contracts/node_modules \ + --evm-version paris \ + "$ROOT"/contracts/src/v0.8/"$1" +} + + +# Liquidity Management +compileContract liquiditymanager/LiquidityManager.sol +compileContract liquiditymanager/bridge-adapters/ArbitrumL1BridgeAdapter.sol +compileContract liquiditymanager/bridge-adapters/ArbitrumL2BridgeAdapter.sol +compileContract liquiditymanager/bridge-adapters/OptimismL1BridgeAdapter.sol +compileContract liquiditymanager/bridge-adapters/OptimismL2BridgeAdapter.sol +compileContract liquiditymanager/test/mocks/NoOpOCR3.sol +compileContract liquiditymanager/test/mocks/MockBridgeAdapter.sol +compileContract liquiditymanager/test/helpers/ReportEncoder.sol + +# Arbitrum helpers +compileContract liquiditymanager/interfaces/arbitrum/IArbSys.sol +compileContract liquiditymanager/interfaces/arbitrum/INodeInterface.sol +compileContract liquiditymanager/interfaces/arbitrum/IL2ArbitrumGateway.sol +compileContract liquiditymanager/interfaces/arbitrum/IL2ArbitrumMessenger.sol +compileContract liquiditymanager/interfaces/arbitrum/IArbRollupCore.sol +compileContract liquiditymanager/interfaces/arbitrum/IArbitrumL1GatewayRouter.sol +compileContract liquiditymanager/interfaces/arbitrum/IArbitrumInbox.sol +compileContract liquiditymanager/interfaces/arbitrum/IArbitrumGatewayRouter.sol +compileContract liquiditymanager/interfaces/arbitrum/IArbitrumTokenGateway.sol +compileContract liquiditymanager/interfaces/arbitrum/IAbstractArbitrumTokenGateway.sol + +# Optimism helpers +compileContract liquiditymanager/interfaces/optimism/IOptimismPortal.sol +compileContract liquiditymanager/interfaces/optimism/IOptimismL2OutputOracle.sol +compileContract liquiditymanager/interfaces/optimism/IOptimismL2ToL1MessagePasser.sol +compileContract liquiditymanager/interfaces/optimism/IOptimismCrossDomainMessenger.sol +compileContract liquiditymanager/interfaces/optimism/IOptimismPortal2.sol +compileContract liquiditymanager/interfaces/optimism/IOptimismDisputeGameFactory.sol +compileContract liquiditymanager/interfaces/optimism/IOptimismStandardBridge.sol +compileContract liquiditymanager/interfaces/optimism/IOptimismL1StandardBridge.sol +compileContract liquiditymanager/encoders/OptimismL1BridgeAdapterEncoder.sol diff --git a/contracts/src/v0.8/ccip/ARMProxy.sol b/contracts/src/v0.8/ccip/ARMProxy.sol new file mode 100644 index 0000000000..e9ccde8680 --- /dev/null +++ b/contracts/src/v0.8/ccip/ARMProxy.sol @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; + +import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol"; + +/// @notice The ARMProxy serves to allow CCIP contracts +/// to point to a static address for ARM queries, which saves gas +/// since each contract need not store an ARM address in storage. That way +/// we can add ARM queries along many code paths for increased defense in depth +/// with minimal additional cost. +contract ARMProxy is OwnerIsCreator, ITypeAndVersion { + error ZeroAddressNotAllowed(); + + event ARMSet(address arm); + + // STATIC CONFIG + // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables + string public constant override typeAndVersion = "ARMProxy 1.0.0"; + + // DYNAMIC CONFIG + address private s_arm; + + constructor(address arm) { + setARM(arm); + } + + /// @notice SetARM sets the ARM implementation contract address. + /// @param arm The address of the arm implementation contract. + function setARM(address arm) public onlyOwner { + if (arm == address(0)) revert ZeroAddressNotAllowed(); + s_arm = arm; + emit ARMSet(arm); + } + + /// @notice getARM gets the ARM implementation contract address. + /// @return arm The address of the arm implementation contract. + function getARM() external view returns (address) { + return s_arm; + } + + // We use a fallback function instead of explicit implementations of the functions + // defined in IRMN.sol to preserve compatibility with future additions to the IRMN + // interface. Calling IRMN interface methods in ARMProxy should be transparent, i.e. + // their input/output behaviour should be identical to calling the proxied s_arm + // contract directly. (If s_arm doesn't point to a contract, we always revert.) + // solhint-disable-next-line payable-fallback, no-complex-fallback + fallback() external { + address arm = s_arm; + // solhint-disable-next-line no-inline-assembly + assembly { + // Revert if no contract present at destination address, otherwise call + // might succeed unintentionally. + if iszero(extcodesize(arm)) { revert(0, 0) } + // We use memory starting at zero, overwriting anything that might already + // be stored there. This messes with Solidity's expectations around memory + // layout, but it's fine because we always exit execution of this contract + // inside this assembly block, i.e. we don't cede control to code generated + // by the Solidity compiler that might have expectations around memory + // layout. + // Copy calldatasize() bytes from calldata offset 0 to memory offset 0. + calldatacopy(0, 0, calldatasize()) + // Call the underlying ARM implementation. out and outsize are 0 because + // we don't know the size yet. We hardcode value to zero. + let success := call(gas(), arm, 0, 0, calldatasize(), 0, 0) + // Copy the returned data. + returndatacopy(0, 0, returndatasize()) + // Pass through successful return or revert and associated data. + if success { return(0, returndatasize()) } + revert(0, returndatasize()) + } + } +} diff --git a/contracts/src/v0.8/ccip/AggregateRateLimiter.sol b/contracts/src/v0.8/ccip/AggregateRateLimiter.sol new file mode 100644 index 0000000000..7401df2ed4 --- /dev/null +++ b/contracts/src/v0.8/ccip/AggregateRateLimiter.sol @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol"; + +import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol"; +import {Client} from "./libraries/Client.sol"; +import {RateLimiter} from "./libraries/RateLimiter.sol"; +import {USDPriceWith18Decimals} from "./libraries/USDPriceWith18Decimals.sol"; + +/// @notice The aggregate rate limiter is a wrapper of the token bucket rate limiter +/// which permits rate limiting based on the aggregate value of a group of +/// token transfers, using a price registry to convert to a numeraire asset (e.g. USD). +contract AggregateRateLimiter is OwnerIsCreator { + using RateLimiter for RateLimiter.TokenBucket; + using USDPriceWith18Decimals for uint224; + + error PriceNotFoundForToken(address token); + + event AdminSet(address newAdmin); + + // The address of the token limit admin that has the same permissions as the owner. + address internal s_admin; + + // The token bucket object that contains the bucket state. + RateLimiter.TokenBucket private s_rateLimiter; + + /// @param config The RateLimiter.Config + constructor(RateLimiter.Config memory config) { + s_rateLimiter = RateLimiter.TokenBucket({ + rate: config.rate, + capacity: config.capacity, + tokens: config.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: config.isEnabled + }); + } + + /// @notice Consumes value from the rate limiter bucket based on the token value given. + function _rateLimitValue(uint256 value) internal { + s_rateLimiter._consume(value, address(0)); + } + + function _getTokenValue( + Client.EVMTokenAmount memory tokenAmount, + IPriceRegistry priceRegistry + ) internal view returns (uint256) { + // not fetching validated price, as price staleness is not important for value-based rate limiting + // we only need to verify the price is not 0 + uint224 pricePerToken = priceRegistry.getTokenPrice(tokenAmount.token).value; + if (pricePerToken == 0) revert PriceNotFoundForToken(tokenAmount.token); + return pricePerToken._calcUSDValueFromTokenAmount(tokenAmount.amount); + } + + /// @notice Gets the token bucket with its values for the block it was requested at. + /// @return The token bucket. + function currentRateLimiterState() external view returns (RateLimiter.TokenBucket memory) { + return s_rateLimiter._currentTokenBucketState(); + } + + /// @notice Sets the rate limited config. + /// @param config The new rate limiter config. + /// @dev should only be callable by the owner or token limit admin. + function setRateLimiterConfig(RateLimiter.Config memory config) external onlyAdminOrOwner { + s_rateLimiter._setTokenBucketConfig(config); + } + + // ================================================================ + // │ Access │ + // ================================================================ + + /// @notice Gets the token limit admin address. + /// @return the token limit admin address. + function getTokenLimitAdmin() external view returns (address) { + return s_admin; + } + + /// @notice Sets the token limit admin address. + /// @param newAdmin the address of the new admin. + /// @dev setting this to address(0) indicates there is no active admin. + function setAdmin(address newAdmin) external onlyAdminOrOwner { + s_admin = newAdmin; + emit AdminSet(newAdmin); + } + + /// @notice a modifier that allows the owner or the s_tokenLimitAdmin call the functions + /// it is applied to. + modifier onlyAdminOrOwner() { + if (msg.sender != owner() && msg.sender != s_admin) revert RateLimiter.OnlyCallableByAdminOrOwner(); + _; + } +} diff --git a/contracts/src/v0.8/ccip/CommitStore.sol b/contracts/src/v0.8/ccip/CommitStore.sol new file mode 100644 index 0000000000..27388b6dcc --- /dev/null +++ b/contracts/src/v0.8/ccip/CommitStore.sol @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; +import {ICommitStore} from "./interfaces/ICommitStore.sol"; +import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol"; +import {IRMN} from "./interfaces/IRMN.sol"; + +import {Internal} from "./libraries/Internal.sol"; +import {MerkleMultiProof} from "./libraries/MerkleMultiProof.sol"; +import {OCR2Base} from "./ocr/OCR2Base.sol"; + +contract CommitStore is ICommitStore, ITypeAndVersion, OCR2Base { + error StaleReport(); + error PausedError(); + error InvalidInterval(Interval interval); + error InvalidRoot(); + error InvalidCommitStoreConfig(); + error CursedByRMN(); + error RootAlreadyCommitted(); + + event Paused(address account); + event Unpaused(address account); + /// @dev RMN depends on this event, if changing, please notify the RMN maintainers. + event ReportAccepted(CommitReport report); + event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig); + event RootRemoved(bytes32 root); + event SequenceNumberSet(uint64 oldSeqNum, uint64 newSeqNum); + event LatestPriceEpochAndRoundSet(uint40 oldEpochAndRound, uint40 newEpochAndRound); + + /// @notice Static commit store config + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + //solhint-disable gas-struct-packing + struct StaticConfig { + uint64 chainSelector; // ───────╮ Destination chainSelector + uint64 sourceChainSelector; // ─╯ Source chainSelector + address onRamp; // OnRamp address on the source chain + address rmnProxy; // RMN proxy address + } + + /// @notice Dynamic commit store config + struct DynamicConfig { + address priceRegistry; // Price registry address on the destination chain + } + + /// @notice a sequenceNumber interval + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct Interval { + uint64 min; // ───╮ Minimum sequence number, inclusive + uint64 max; // ───╯ Maximum sequence number, inclusive + } + + /// @notice Report that is committed by the observing DON at the committing phase + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct CommitReport { + Internal.PriceUpdates priceUpdates; + Interval interval; + bytes32 merkleRoot; + } + + // STATIC CONFIG + string public constant override typeAndVersion = "CommitStore 1.5.0-dev"; + // Chain ID of this chain + uint64 internal immutable i_chainSelector; + // Chain ID of the source chain + uint64 internal immutable i_sourceChainSelector; + // The onRamp address on the source chain + address internal immutable i_onRamp; + // The address of the rmn proxy + address internal immutable i_rmnProxy; + + // DYNAMIC CONFIG + // The dynamic commitStore config + DynamicConfig internal s_dynamicConfig; + + // STATE + // The min sequence number expected for future messages + uint64 private s_minSeqNr = 1; + /// @dev The epoch and round of the last report + uint40 private s_latestPriceEpochAndRound; + /// @dev Whether this CommitStore is paused or not + bool private s_paused = false; + // merkleRoot => timestamp when received + mapping(bytes32 merkleRoot => uint256 timestamp) private s_roots; + + /// @param staticConfig Containing the static part of the commitStore config + /// @dev When instantiating OCR2Base we set UNIQUE_REPORTS to false, which means + /// that we do not require 2f+1 signatures on a report, only f+1 to save gas. 2f+1 is required + /// only if one must strictly ensure that for a given round there is only one valid report ever generated by + /// the DON. In our case additional valid reports (i.e. approved by >= f+1 oracles) are not a problem, as they will + /// will either be ignored (reverted as an invalid interval) or will be accepted as an additional valid price update. + constructor(StaticConfig memory staticConfig) OCR2Base(false) { + if ( + staticConfig.onRamp == address(0) || staticConfig.chainSelector == 0 || staticConfig.sourceChainSelector == 0 + || staticConfig.rmnProxy == address(0) + ) revert InvalidCommitStoreConfig(); + + i_chainSelector = staticConfig.chainSelector; + i_sourceChainSelector = staticConfig.sourceChainSelector; + i_onRamp = staticConfig.onRamp; + i_rmnProxy = staticConfig.rmnProxy; + } + + // ================================================================ + // │ Verification │ + // ================================================================ + + /// @notice Returns the next expected sequence number. + /// @return the next expected sequenceNumber. + function getExpectedNextSequenceNumber() external view returns (uint64) { + return s_minSeqNr; + } + + /// @notice Sets the minimum sequence number. + /// @param minSeqNr The new minimum sequence number. + function setMinSeqNr(uint64 minSeqNr) external onlyOwner { + uint64 oldSeqNum = s_minSeqNr; + + s_minSeqNr = minSeqNr; + + emit SequenceNumberSet(oldSeqNum, minSeqNr); + } + + /// @notice Returns the epoch and round of the last price update. + /// @return the latest price epoch and round. + function getLatestPriceEpochAndRound() external view returns (uint64) { + return s_latestPriceEpochAndRound; + } + + /// @notice Sets the latest epoch and round for price update. + /// @param latestPriceEpochAndRound The new epoch and round for prices. + function setLatestPriceEpochAndRound(uint40 latestPriceEpochAndRound) external onlyOwner { + uint40 oldEpochAndRound = s_latestPriceEpochAndRound; + + s_latestPriceEpochAndRound = latestPriceEpochAndRound; + + emit LatestPriceEpochAndRoundSet(oldEpochAndRound, latestPriceEpochAndRound); + } + + /// @notice Returns the timestamp of a potentially previously committed merkle root. + /// If the root was never committed 0 will be returned. + /// @param root The merkle root to check the commit status for. + /// @return the timestamp of the committed root or zero in the case that it was never + /// committed. + function getMerkleRoot(bytes32 root) external view returns (uint256) { + return s_roots[root]; + } + + /// @notice Returns if a root is blessed or not. + /// @param root The merkle root to check the blessing status for. + /// @return whether the root is blessed or not. + function isBlessed(bytes32 root) public view returns (bool) { + return IRMN(i_rmnProxy).isBlessed(IRMN.TaggedRoot({commitStore: address(this), root: root})); + } + + /// @notice Used by the owner in case an invalid sequence of roots has been + /// posted and needs to be removed. The interval in the report is trusted. + /// @param rootToReset The roots that will be reset. This function will only + /// reset roots that are not blessed. + function resetUnblessedRoots(bytes32[] calldata rootToReset) external onlyOwner { + for (uint256 i = 0; i < rootToReset.length; ++i) { + bytes32 root = rootToReset[i]; + if (!isBlessed(root)) { + delete s_roots[root]; + emit RootRemoved(root); + } + } + } + + /// @inheritdoc ICommitStore + function verify( + bytes32[] calldata hashedLeaves, + bytes32[] calldata proofs, + uint256 proofFlagBits + ) external view override whenNotPaused returns (uint256 timestamp) { + bytes32 root = MerkleMultiProof.merkleRoot(hashedLeaves, proofs, proofFlagBits); + // Only return non-zero if present and blessed. + if (!isBlessed(root)) { + return 0; + } + return s_roots[root]; + } + + /// @inheritdoc OCR2Base + /// @dev A commitReport can have two distinct parts (batched together to amortize the cost of checking sigs): + /// 1. Price updates + /// 2. A merkle root and sequence number interval + /// Both have their own, separate, staleness checks, with price updates using the epoch and round + /// number of the latest price update. The merkle root checks for staleness based on the seqNums. + /// They need to be separate because a price report for round t+2 might be included before a report + /// containing a merkle root for round t+1. This merkle root report for round t+1 is still valid + /// and should not be rejected. When a report with a stale root but valid price updates is submitted, + /// we are OK to revert to preserve the invariant that we always revert on invalid sequence number ranges. + /// If that happens, prices will be updates in later rounds. + function _report(bytes calldata encodedReport, uint40 epochAndRound) internal override whenNotPaused { + if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(i_sourceChainSelector)))) revert CursedByRMN(); + + CommitReport memory report = abi.decode(encodedReport, (CommitReport)); + + // Check if the report contains price updates + if (report.priceUpdates.tokenPriceUpdates.length > 0 || report.priceUpdates.gasPriceUpdates.length > 0) { + // Check for price staleness based on the epoch and round + if (s_latestPriceEpochAndRound < epochAndRound) { + // If prices are not stale, update the latest epoch and round + s_latestPriceEpochAndRound = epochAndRound; + // And update the prices in the price registry + IPriceRegistry(s_dynamicConfig.priceRegistry).updatePrices(report.priceUpdates); + + // If there is no root, the report only contained fee updated and + // we return to not revert on the empty root check below. + if (report.merkleRoot == bytes32(0)) return; + } else { + // If prices are stale and the report doesn't contain a root, this report + // does not have any valid information and we revert. + // If it does contain a merkle root, continue to the root checking section. + if (report.merkleRoot == bytes32(0)) revert StaleReport(); + } + } + + // If we reached this section, the report should contain a valid root + if (s_minSeqNr != report.interval.min || report.interval.min > report.interval.max) { + revert InvalidInterval(report.interval); + } + + if (report.merkleRoot == bytes32(0)) revert InvalidRoot(); + // Disallow duplicate roots as that would reset the timestamp and + // delay potential manual execution. + if (s_roots[report.merkleRoot] != 0) revert RootAlreadyCommitted(); + + s_minSeqNr = report.interval.max + 1; + s_roots[report.merkleRoot] = block.timestamp; + emit ReportAccepted(report); + } + + // ================================================================ + // │ Config │ + // ================================================================ + + /// @notice Returns the static commit store config. + /// @dev RMN depends on this function, if changing, please notify the RMN maintainers. + /// @return the configuration. + function getStaticConfig() external view returns (StaticConfig memory) { + return StaticConfig({ + chainSelector: i_chainSelector, + sourceChainSelector: i_sourceChainSelector, + onRamp: i_onRamp, + rmnProxy: i_rmnProxy + }); + } + + /// @notice Returns the dynamic commit store config. + /// @return the configuration. + function getDynamicConfig() external view returns (DynamicConfig memory) { + return s_dynamicConfig; + } + + /// @notice Sets the dynamic config. This function is called during `setOCR2Config` flow + function _beforeSetConfig(bytes memory onchainConfig) internal override { + DynamicConfig memory dynamicConfig = abi.decode(onchainConfig, (DynamicConfig)); + + if (dynamicConfig.priceRegistry == address(0)) revert InvalidCommitStoreConfig(); + + s_dynamicConfig = dynamicConfig; + // When the OCR config changes, we reset the price epoch and round + // since epoch and rounds are scoped per config digest. + // Note that s_minSeqNr/roots do not need to be reset as the roots persist + // across reconfigurations and are de-duplicated separately. + s_latestPriceEpochAndRound = 0; + + emit ConfigSet( + StaticConfig({ + chainSelector: i_chainSelector, + sourceChainSelector: i_sourceChainSelector, + onRamp: i_onRamp, + rmnProxy: i_rmnProxy + }), + dynamicConfig + ); + } + + // ================================================================ + // │ Access and RMN │ + // ================================================================ + + /// @notice Single function to check the status of the commitStore. + function isUnpausedAndNotCursed() external view returns (bool) { + return !IRMN(i_rmnProxy).isCursed(bytes16(uint128(i_sourceChainSelector))) && !s_paused; + } + + /// @notice Modifier to make a function callable only when the contract is not paused. + modifier whenNotPaused() { + if (paused()) revert PausedError(); + _; + } + + /// @notice Returns true if the contract is paused, and false otherwise. + function paused() public view returns (bool) { + return s_paused; + } + + /// @notice Pause the contract + /// @dev only callable by the owner + function pause() external onlyOwner { + s_paused = true; + emit Paused(msg.sender); + } + + /// @notice Unpause the contract + /// @dev only callable by the owner + function unpause() external onlyOwner { + s_paused = false; + emit Unpaused(msg.sender); + } +} diff --git a/contracts/src/v0.8/ccip/LICENSE-MIT.md b/contracts/src/v0.8/ccip/LICENSE-MIT.md new file mode 100644 index 0000000000..812debd8e9 --- /dev/null +++ b/contracts/src/v0.8/ccip/LICENSE-MIT.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 SmartContract ChainLink, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/contracts/src/v0.8/ccip/LICENSE.md b/contracts/src/v0.8/ccip/LICENSE.md new file mode 100644 index 0000000000..5f2783f7a3 --- /dev/null +++ b/contracts/src/v0.8/ccip/LICENSE.md @@ -0,0 +1,56 @@ +Business Source License 1.1 + +License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. +"Business Source License" is a trademark of MariaDB Corporation Ab. + +----------------------------------------------------------------------------- + +Parameters + +Licensor: SmartContract Chainlink Limited SEZC + +Licensed Work: Cross-Chain Interoperability Protocol v1.4 +The Licensed Work is (c) 2023 SmartContract Chainlink Limited SEZC + +Additional Use Grant: Any uses listed and defined at [v1.4-CCIP-License-grants]( +./v1.4-CCIP-License-grants) + +Change Date: May 23, 2027 + +Change License: MIT + +----------------------------------------------------------------------------- + +Terms + +The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and make non-production use of the Licensed Work. The Licensor may make an Additional Use Grant, above, permitting limited production use. + +Effective on the Change Date, or the fourth anniversary of the first publicly available distribution of a specific version of the Licensed Work under this License, whichever comes first, the Licensor hereby grants you rights under the terms of the Change License, and the rights granted in the paragraph above terminate. + +If your use of the Licensed Work does not comply with the requirements currently in effect as described in this License, you must purchase a commercial license from the Licensor, its affiliated entities, or authorized resellers, or you must refrain from using the Licensed Work. + +All copies of the original and modified Licensed Work, and derivative works of the Licensed Work, are subject to this License. This License applies separately for each version of the Licensed Work and the Change Date may vary for each version of the Licensed Work released by Licensor. + +You must conspicuously display this License on each original or modified copy of the Licensed Work. If you receive the Licensed Work in original or modified form from a third party, the terms and conditions set forth in this License apply to your use of that work. + +Any use of the Licensed Work in violation of this License will automatically terminate your rights under this License for the current and all other versions of the Licensed Work. + +This License does not grant you any right in any trademark or logo of Licensor or its affiliates (provided that you may use a trademark or logo of Licensor as expressly required by this License). + +TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE. + +MariaDB hereby grants you permission to use this License’s text to license your works, and to refer to it using the trademark "Business Source License", as long as you comply with the Covenants of Licensor below. + +----------------------------------------------------------------------------- + +Covenants of Licensor + +In consideration of the right to use this License’s text and the "Business Source License" name and trademark, Licensor covenants to MariaDB, and to all other recipients of the licensed work to be provided by Licensor: + +1. To specify as the Change License the GPL Version 2.0 or any later version, or a license that is compatible with GPL Version 2.0 or a later version, where "compatible" means that software provided under the Change License can be included in a program with software provided under GPL Version 2.0 or a later version. Licensor may specify additional Change Licenses without limitation. + +2. To either: (a) specify an additional grant of rights to use that does not impose any additional restriction on the right granted in this License, as the Additional Use Grant; or (b) insert the text "None". + +3. To specify a Change Date. + +4. Not to modify this License in any other way. \ No newline at end of file diff --git a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol new file mode 100644 index 0000000000..2a9d087a26 --- /dev/null +++ b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IMessageInterceptor} from "./interfaces/IMessageInterceptor.sol"; +import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol"; + +import {AuthorizedCallers} from "../shared/access/AuthorizedCallers.sol"; +import {EnumerableMapAddresses} from "./../shared/enumerable/EnumerableMapAddresses.sol"; +import {Client} from "./libraries/Client.sol"; +import {RateLimiter} from "./libraries/RateLimiter.sol"; +import {USDPriceWith18Decimals} from "./libraries/USDPriceWith18Decimals.sol"; + +import {EnumerableSet} from "./../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; + +/// @notice The aggregate rate limiter is a wrapper of the token bucket rate limiter +/// which permits rate limiting based on the aggregate value of a group of +/// token transfers, using a price registry to convert to a numeraire asset (e.g. USD). +/// The contract is a standalone multi-lane message validator contract, which can be called by authorized +/// ramp contracts to apply rate limit changes to lanes, and revert when the rate limits get breached. +contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers { + using RateLimiter for RateLimiter.TokenBucket; + using USDPriceWith18Decimals for uint224; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; + using EnumerableSet for EnumerableSet.AddressSet; + + error PriceNotFoundForToken(address token); + error ZeroChainSelectorNotAllowed(); + + event RateLimiterConfigUpdated(uint64 indexed remoteChainSelector, bool isOutboundLane, RateLimiter.Config config); + event PriceRegistrySet(address newPriceRegistry); + event TokenAggregateRateLimitAdded(uint64 remoteChainSelector, bytes32 remoteToken, address localToken); + event TokenAggregateRateLimitRemoved(uint64 remoteChainSelector, address localToken); + + /// @notice RemoteRateLimitToken struct containing the local token address with the chain selector + /// The struct is used for removals and updates, since the local -> remote token mappings are scoped per-chain + struct LocalRateLimitToken { + uint64 remoteChainSelector; // ────╮ Remote chain selector for which to update the rate limit token mapping + address localToken; // ────────────╯ Token on the chain on which the multi-ARL is deployed + } + + /// @notice RateLimitToken struct containing both the local and remote token addresses + struct RateLimitTokenArgs { + LocalRateLimitToken localTokenArgs; // Local token update args scoped to one remote chain + bytes32 remoteToken; // Token on the remote chain (for OnRamp - dest, of OffRamp - source) + } + + /// @notice Update args for a single rate limiter config update + struct RateLimiterConfigArgs { + uint64 remoteChainSelector; // ────╮ Chain selector to set config for + bool isOutboundLane; // ───────────╯ If set to true, represents the outbound message lane (OnRamp), and the inbound message lane otherwise (OffRamp) + RateLimiter.Config rateLimiterConfig; // Rate limiter config to set + } + + /// @notice Struct to store rate limit token buckets for both lane directions + struct RateLimiterBuckets { + RateLimiter.TokenBucket inboundLaneBucket; // Bucket for the inbound lane (remote -> local) + RateLimiter.TokenBucket outboundLaneBucket; // Bucket for the outbound lane (local -> remote) + } + + /// @dev Tokens that should be included in Aggregate Rate Limiting (from local chain (this chain) -> remote), + /// grouped per-remote chain. + mapping(uint64 remoteChainSelector => EnumerableMapAddresses.AddressToBytes32Map tokensLocalToRemote) internal + s_rateLimitedTokensLocalToRemote; + + /// @notice The address of the PriceRegistry used to query token values for ratelimiting + address internal s_priceRegistry; + + /// @notice Rate limiter token bucket states per chain, with separate buckets for inbound and outbound lanes. + mapping(uint64 remoteChainSelector => RateLimiterBuckets buckets) internal s_rateLimitersByChainSelector; + + /// @param priceRegistry the price registry to set + /// @param authorizedCallers the authorized callers to set + constructor(address priceRegistry, address[] memory authorizedCallers) AuthorizedCallers(authorizedCallers) { + _setPriceRegistry(priceRegistry); + } + + /// @inheritdoc IMessageInterceptor + function onInboundMessage(Client.Any2EVMMessage memory message) external onlyAuthorizedCallers { + _applyRateLimit(message.sourceChainSelector, message.destTokenAmounts, false); + } + + /// @inheritdoc IMessageInterceptor + function onOutboundMessage( + uint64 destChainSelector, + Client.EVM2AnyMessage calldata message + ) external onlyAuthorizedCallers { + _applyRateLimit(destChainSelector, message.tokenAmounts, true); + } + + /// @notice Applies the rate limit to the token bucket if enabled + /// @param remoteChainSelector The remote chain selector + /// @param tokenAmounts The tokens and amounts to rate limit + /// @param isOutgoingLane if set to true, fetches the bucket for the outgoing message lane (OnRamp). + function _applyRateLimit( + uint64 remoteChainSelector, + Client.EVMTokenAmount[] memory tokenAmounts, + bool isOutgoingLane + ) private { + RateLimiter.TokenBucket storage tokenBucket = _getTokenBucket(remoteChainSelector, isOutgoingLane); + + // Skip rate limiting if it is disabled + if (tokenBucket.isEnabled) { + uint256 value; + for (uint256 i = 0; i < tokenAmounts.length; ++i) { + if (s_rateLimitedTokensLocalToRemote[remoteChainSelector].contains(tokenAmounts[i].token)) { + value += _getTokenValue(tokenAmounts[i]); + } + } + // Rate limit on aggregated token value + if (value > 0) tokenBucket._consume(value, address(0)); + } + } + + /// @param remoteChainSelector chain selector to retrieve token bucket for + /// @param isOutboundLane if set to true, fetches the bucket for the outbound message lane (OnRamp). + /// Otherwise fetches for the inbound message lane (OffRamp). + /// @return bucket Storage pointer to the token bucket representing a specific lane + function _getTokenBucket( + uint64 remoteChainSelector, + bool isOutboundLane + ) internal view returns (RateLimiter.TokenBucket storage) { + RateLimiterBuckets storage rateLimiterBuckets = s_rateLimitersByChainSelector[remoteChainSelector]; + if (isOutboundLane) { + return rateLimiterBuckets.outboundLaneBucket; + } else { + return rateLimiterBuckets.inboundLaneBucket; + } + } + + /// @notice Retrieves the token value for a token using the PriceRegistry + /// @return tokenValue USD value in 18 decimals + function _getTokenValue(Client.EVMTokenAmount memory tokenAmount) internal view returns (uint256) { + // not fetching validated price, as price staleness is not important for value-based rate limiting + // we only need to verify the price is not 0 + uint224 pricePerToken = IPriceRegistry(s_priceRegistry).getTokenPrice(tokenAmount.token).value; + if (pricePerToken == 0) revert PriceNotFoundForToken(tokenAmount.token); + return pricePerToken._calcUSDValueFromTokenAmount(tokenAmount.amount); + } + + /// @notice Gets the token bucket with its values for the block it was requested at. + /// @param remoteChainSelector chain selector to retrieve state for + /// @param isOutboundLane if set to true, fetches the rate limit state for the outbound message lane (OnRamp). + /// Otherwise fetches for the inbound message lane (OffRamp). + /// The outbound and inbound message rate limit state is completely separated. + /// @return The token bucket. + function currentRateLimiterState( + uint64 remoteChainSelector, + bool isOutboundLane + ) external view returns (RateLimiter.TokenBucket memory) { + return _getTokenBucket(remoteChainSelector, isOutboundLane)._currentTokenBucketState(); + } + + /// @notice Applies the provided rate limiter config updates. + /// @param rateLimiterUpdates Rate limiter updates + /// @dev should only be callable by the owner + function applyRateLimiterConfigUpdates(RateLimiterConfigArgs[] memory rateLimiterUpdates) external onlyOwner { + for (uint256 i = 0; i < rateLimiterUpdates.length; ++i) { + RateLimiterConfigArgs memory updateArgs = rateLimiterUpdates[i]; + RateLimiter.Config memory configUpdate = updateArgs.rateLimiterConfig; + uint64 remoteChainSelector = updateArgs.remoteChainSelector; + + if (remoteChainSelector == 0) { + revert ZeroChainSelectorNotAllowed(); + } + + bool isOutboundLane = updateArgs.isOutboundLane; + + RateLimiter.TokenBucket storage tokenBucket = _getTokenBucket(remoteChainSelector, isOutboundLane); + + if (tokenBucket.lastUpdated == 0) { + // Token bucket needs to be newly added + RateLimiter.TokenBucket memory newTokenBucket = RateLimiter.TokenBucket({ + rate: configUpdate.rate, + capacity: configUpdate.capacity, + tokens: configUpdate.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: configUpdate.isEnabled + }); + + if (isOutboundLane) { + s_rateLimitersByChainSelector[remoteChainSelector].outboundLaneBucket = newTokenBucket; + } else { + s_rateLimitersByChainSelector[remoteChainSelector].inboundLaneBucket = newTokenBucket; + } + } else { + tokenBucket._setTokenBucketConfig(configUpdate); + } + emit RateLimiterConfigUpdated(remoteChainSelector, isOutboundLane, configUpdate); + } + } + + /// @notice Get all tokens which are included in Aggregate Rate Limiting. + /// @param remoteChainSelector chain selector to get rate limit tokens for + /// @return localTokens The local chain representation of the tokens that are rate limited. + /// @return remoteTokens The remote representation of the tokens that are rate limited. + /// @dev the order of IDs in the list is **not guaranteed**, therefore, if ordering matters when + /// making successive calls, one should keep the block height constant to ensure a consistent result. + function getAllRateLimitTokens(uint64 remoteChainSelector) + external + view + returns (address[] memory localTokens, bytes32[] memory remoteTokens) + { + uint256 tokenCount = s_rateLimitedTokensLocalToRemote[remoteChainSelector].length(); + + localTokens = new address[](tokenCount); + remoteTokens = new bytes32[](tokenCount); + + for (uint256 i = 0; i < tokenCount; ++i) { + (address localToken, bytes32 remoteToken) = s_rateLimitedTokensLocalToRemote[remoteChainSelector].at(i); + localTokens[i] = localToken; + remoteTokens[i] = remoteToken; + } + return (localTokens, remoteTokens); + } + + /// @notice Adds or removes tokens from being used in Aggregate Rate Limiting. + /// @param removes - A list of one or more tokens to be removed. + /// @param adds - A list of one or more tokens to be added. + function updateRateLimitTokens( + LocalRateLimitToken[] memory removes, + RateLimitTokenArgs[] memory adds + ) external onlyOwner { + for (uint256 i = 0; i < removes.length; ++i) { + address localToken = removes[i].localToken; + uint64 remoteChainSelector = removes[i].remoteChainSelector; + + if (s_rateLimitedTokensLocalToRemote[remoteChainSelector].remove(localToken)) { + emit TokenAggregateRateLimitRemoved(remoteChainSelector, localToken); + } + } + + for (uint256 i = 0; i < adds.length; ++i) { + LocalRateLimitToken memory localTokenArgs = adds[i].localTokenArgs; + bytes32 remoteToken = adds[i].remoteToken; + address localToken = localTokenArgs.localToken; + + if (localToken == address(0) || remoteToken == bytes32("")) { + revert ZeroAddressNotAllowed(); + } + + uint64 remoteChainSelector = localTokenArgs.remoteChainSelector; + + if (s_rateLimitedTokensLocalToRemote[remoteChainSelector].set(localToken, remoteToken)) { + emit TokenAggregateRateLimitAdded(remoteChainSelector, remoteToken, localToken); + } + } + } + + /// @return priceRegistry The configured PriceRegistry address + function getPriceRegistry() external view returns (address) { + return s_priceRegistry; + } + + /// @notice Sets the Price Registry address + /// @param newPriceRegistry the address of the new PriceRegistry + /// @dev precondition The address must be a non-zero address + function setPriceRegistry(address newPriceRegistry) external onlyOwner { + _setPriceRegistry(newPriceRegistry); + } + + /// @notice Sets the Price Registry address + /// @param newPriceRegistry the address of the new PriceRegistry + /// @dev precondition The address must be a non-zero address + function _setPriceRegistry(address newPriceRegistry) internal { + if (newPriceRegistry == address(0)) { + revert ZeroAddressNotAllowed(); + } + + s_priceRegistry = newPriceRegistry; + emit PriceRegistrySet(newPriceRegistry); + } +} diff --git a/contracts/src/v0.8/ccip/NonceManager.sol b/contracts/src/v0.8/ccip/NonceManager.sol new file mode 100644 index 0000000000..2cfcbbe9e2 --- /dev/null +++ b/contracts/src/v0.8/ccip/NonceManager.sol @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IEVM2AnyOnRamp} from "./interfaces/IEVM2AnyOnRamp.sol"; +import {INonceManager} from "./interfaces/INonceManager.sol"; + +import {AuthorizedCallers} from "../shared/access/AuthorizedCallers.sol"; + +/// @title NonceManager +/// @notice NonceManager contract that manages sender nonces for the on/off ramps +contract NonceManager is INonceManager, AuthorizedCallers { + error PreviousRampAlreadySet(); + + event PreviousRampsUpdated(uint64 indexed remoteChainSelector, PreviousRamps prevRamp); + event SkippedIncorrectNonce(uint64 sourceChainSelector, uint64 nonce, bytes sender); + + /// @dev Struct that contains the previous on/off ramp addresses + struct PreviousRamps { + address prevOnRamp; // Previous onRamp + address prevOffRamp; // Previous offRamp + } + + /// @dev Struct that contains the chain selector and the previous on/off ramps, same as PreviousRamps but with the chain selector + /// so that an array of these can be passed to the applyPreviousRampsUpdates function + struct PreviousRampsArgs { + uint64 remoteChainSelector; // Chain selector + PreviousRamps prevRamps; // Previous on/off ramps + } + + /// @dev previous ramps + mapping(uint64 chainSelector => PreviousRamps previousRamps) private s_previousRamps; + /// @dev The current outbound nonce per sender used on the onramp + mapping(uint64 destChainSelector => mapping(address sender => uint64 outboundNonce)) private s_outboundNonces; + /// @dev The current inbound nonce per sender used on the offramp + /// Eventually in sync with the outbound nonce in the remote source chain NonceManager, used to enforce that messages are + /// executed in the same order they are sent (assuming they are DON) + mapping(uint64 sourceChainSelector => mapping(bytes sender => uint64 inboundNonce)) private s_inboundNonces; + + constructor(address[] memory authorizedCallers) AuthorizedCallers(authorizedCallers) {} + + /// @inheritdoc INonceManager + function getIncrementedOutboundNonce( + uint64 destChainSelector, + address sender + ) external onlyAuthorizedCallers returns (uint64) { + uint64 outboundNonce = _getOutboundNonce(destChainSelector, sender) + 1; + s_outboundNonces[destChainSelector][sender] = outboundNonce; + + return outboundNonce; + } + + /// @notice Returns the outbound nonce for a given sender on a given destination chain + /// @param destChainSelector The destination chain selector + /// @param sender The sender address + /// @return The outbound nonce + function getOutboundNonce(uint64 destChainSelector, address sender) external view returns (uint64) { + return _getOutboundNonce(destChainSelector, sender); + } + + function _getOutboundNonce(uint64 destChainSelector, address sender) private view returns (uint64) { + uint64 outboundNonce = s_outboundNonces[destChainSelector][sender]; + + // When introducing the NonceManager with existing lanes, we still want to have sequential nonces. + // Referencing the old onRamp preserves sequencing between updates. + if (outboundNonce == 0) { + address prevOnRamp = s_previousRamps[destChainSelector].prevOnRamp; + if (prevOnRamp != address(0)) { + return IEVM2AnyOnRamp(prevOnRamp).getSenderNonce(sender); + } + } + + return outboundNonce; + } + + /// @inheritdoc INonceManager + function incrementInboundNonce( + uint64 sourceChainSelector, + uint64 expectedNonce, + bytes calldata sender + ) external onlyAuthorizedCallers returns (bool) { + uint64 inboundNonce = _getInboundNonce(sourceChainSelector, sender) + 1; + + if (inboundNonce != expectedNonce) { + // If the nonce is not the expected one, this means that there are still messages in flight so we skip + // the nonce increment + emit SkippedIncorrectNonce(sourceChainSelector, expectedNonce, sender); + return false; + } + + s_inboundNonces[sourceChainSelector][sender] = inboundNonce; + + return true; + } + + /// @notice Returns the inbound nonce for a given sender on a given source chain + /// @param sourceChainSelector The source chain selector + /// @param sender The encoded sender address + /// @return The inbound nonce + function getInboundNonce(uint64 sourceChainSelector, bytes calldata sender) external view returns (uint64) { + return _getInboundNonce(sourceChainSelector, sender); + } + + function _getInboundNonce(uint64 sourceChainSelector, bytes calldata sender) private view returns (uint64) { + uint64 inboundNonce = s_inboundNonces[sourceChainSelector][sender]; + + // When introducing the NonceManager with existing lanes, we still want to have sequential nonces. + // Referencing the old offRamp to check the expected nonce if none is set for a + // given sender allows us to skip the current message in the current offRamp if it would not be the next according + // to the old offRamp. This preserves sequencing between updates. + if (inboundNonce == 0) { + address prevOffRamp = s_previousRamps[sourceChainSelector].prevOffRamp; + if (prevOffRamp != address(0)) { + // We only expect EVM previous offRamps here so we can safely decode the sender + return IEVM2AnyOnRamp(prevOffRamp).getSenderNonce(abi.decode(sender, (address))); + } + } + + return inboundNonce; + } + + /// @notice Updates the previous ramps addresses + /// @param previousRampsArgs The previous on/off ramps addresses + function applyPreviousRampsUpdates(PreviousRampsArgs[] calldata previousRampsArgs) external onlyOwner { + for (uint256 i = 0; i < previousRampsArgs.length; ++i) { + PreviousRampsArgs calldata previousRampsArg = previousRampsArgs[i]; + + PreviousRamps storage prevRamps = s_previousRamps[previousRampsArg.remoteChainSelector]; + + // If the previous ramps are already set then they should not be updated + if (prevRamps.prevOnRamp != address(0) || prevRamps.prevOffRamp != address(0)) { + revert PreviousRampAlreadySet(); + } + + prevRamps.prevOnRamp = previousRampsArg.prevRamps.prevOnRamp; + prevRamps.prevOffRamp = previousRampsArg.prevRamps.prevOffRamp; + + emit PreviousRampsUpdated(previousRampsArg.remoteChainSelector, previousRampsArg.prevRamps); + } + } + + /// @notice Gets the previous onRamp address for the given chain selector + /// @param chainSelector The chain selector + /// @return The previous onRamp address + function getPreviousRamps(uint64 chainSelector) external view returns (PreviousRamps memory) { + return s_previousRamps[chainSelector]; + } +} diff --git a/contracts/src/v0.8/ccip/PriceRegistry.sol b/contracts/src/v0.8/ccip/PriceRegistry.sol new file mode 100644 index 0000000000..f15232271e --- /dev/null +++ b/contracts/src/v0.8/ccip/PriceRegistry.sol @@ -0,0 +1,888 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; +import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol"; + +import {AuthorizedCallers} from "../shared/access/AuthorizedCallers.sol"; +import {AggregatorV3Interface} from "./../shared/interfaces/AggregatorV3Interface.sol"; +import {Client} from "./libraries/Client.sol"; +import {Internal} from "./libraries/Internal.sol"; +import {Pool} from "./libraries/Pool.sol"; +import {USDPriceWith18Decimals} from "./libraries/USDPriceWith18Decimals.sol"; + +import {EnumerableSet} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +/// @notice The PriceRegistry contract responsibility is to store the current gas price in USD for a given destination chain, +/// and the price of a token in USD allowing the owner or priceUpdater to update this value. +/// The authorized callers in the contract represent the fee price updaters. +contract PriceRegistry is AuthorizedCallers, IPriceRegistry, ITypeAndVersion { + using EnumerableSet for EnumerableSet.AddressSet; + using USDPriceWith18Decimals for uint224; + + /// @notice Token price data feed update + struct TokenPriceFeedUpdate { + address sourceToken; // Source token to update feed for + IPriceRegistry.TokenPriceFeedConfig feedConfig; // Feed config update data + } + + /// @dev Struct that contains the static configuration + /// RMN depends on this struct, if changing, please notify the RMN maintainers. + // solhint-disable-next-line gas-struct-packing + struct StaticConfig { + uint96 maxFeeJuelsPerMsg; // ─╮ Maximum fee that can be charged for a message + address linkToken; // ────────╯ LINK token address + uint32 stalenessThreshold; // The amount of time a gas price can be stale before it is considered invalid. + } + + error TokenNotSupported(address token); + error ChainNotSupported(uint64 chain); + error StaleGasPrice(uint64 destChainSelector, uint256 threshold, uint256 timePassed); + error DataFeedValueOutOfUint224Range(); + error InvalidDestBytesOverhead(address token, uint32 destBytesOverhead); + error MessageGasLimitTooHigh(); + error DestinationChainNotEnabled(uint64 destChainSelector); + error ExtraArgOutOfOrderExecutionMustBeTrue(); + error InvalidExtraArgsTag(); + error SourceTokenDataTooLarge(address token); + error InvalidDestChainConfig(uint64 destChainSelector); + error MessageFeeTooHigh(uint256 msgFeeJuels, uint256 maxFeeJuelsPerMsg); + error InvalidStaticConfig(); + error MessageTooLarge(uint256 maxSize, uint256 actualSize); + error UnsupportedNumberOfTokens(); + + event PriceUpdaterSet(address indexed priceUpdater); + event PriceUpdaterRemoved(address indexed priceUpdater); + event FeeTokenAdded(address indexed feeToken); + event FeeTokenRemoved(address indexed feeToken); + event UsdPerUnitGasUpdated(uint64 indexed destChain, uint256 value, uint256 timestamp); + event UsdPerTokenUpdated(address indexed token, uint256 value, uint256 timestamp); + event PriceFeedPerTokenUpdated(address indexed token, IPriceRegistry.TokenPriceFeedConfig priceFeedConfig); + + event TokenTransferFeeConfigUpdated( + uint64 indexed destChainSelector, address indexed token, TokenTransferFeeConfig tokenTransferFeeConfig + ); + event TokenTransferFeeConfigDeleted(uint64 indexed destChainSelector, address indexed token); + event PremiumMultiplierWeiPerEthUpdated(address indexed token, uint64 premiumMultiplierWeiPerEth); + event DestChainConfigUpdated(uint64 indexed destChainSelector, DestChainConfig destChainConfig); + event DestChainAdded(uint64 indexed destChainSelector, DestChainConfig destChainConfig); + + /// @dev Struct to hold the fee & validation configs for a destination chain + struct DestChainConfig { + bool isEnabled; // ──────────────────────────╮ Whether this destination chain is enabled + uint16 maxNumberOfTokensPerMsg; // │ Maximum number of distinct ERC20 token transferred per message + uint32 maxDataBytes; // │ Maximum payload data size in bytes + uint32 maxPerMsgGasLimit; // │ Maximum gas limit for messages targeting EVMs + uint32 destGasOverhead; // │ Gas charged on top of the gasLimit to cover destination chain costs + uint16 destGasPerPayloadByte; // │ Destination chain gas charged for passing each byte of `data` payload to receiver + uint32 destDataAvailabilityOverheadGas; // | Extra data availability gas charged on top of the message, e.g. for OCR + uint16 destGasPerDataAvailabilityByte; // | Amount of gas to charge per byte of message data that needs availability + uint16 destDataAvailabilityMultiplierBps; // │ Multiplier for data availability gas, multiples of bps, or 0.0001 + // The following three properties are defaults, they can be overridden by setting the TokenTransferFeeConfig for a token + uint16 defaultTokenFeeUSDCents; // │ Default token fee charged per token transfer + uint32 defaultTokenDestGasOverhead; // ──────╯ Default gas charged to execute the token transfer on the destination chain + uint32 defaultTokenDestBytesOverhead; // ────╮ Default extra data availability bytes charged per token transfer + uint32 defaultTxGasLimit; // │ Default gas limit for a tx + uint64 gasMultiplierWeiPerEth; // │ Multiplier for gas costs, 1e18 based so 11e17 = 10% extra cost. + uint32 networkFeeUSDCents; // │ Flat network fee to charge for messages, multiples of 0.01 USD + bool enforceOutOfOrder; // │ Whether to enforce the allowOutOfOrderExecution extraArg value to be true. + bytes4 chainFamilySelector; // ──────────────╯ Selector that identifies the destination chain's family. Used to determine the correct validations to perform for the dest chain. + } + + /// @dev Struct to hold the configs and its destination chain selector + /// Same as DestChainConfig but with the destChainSelector so that an array of these + /// can be passed in the constructor and the applyDestChainConfigUpdates function + //solhint-disable gas-struct-packing + struct DestChainConfigArgs { + uint64 destChainSelector; // Destination chain selector + DestChainConfig destChainConfig; // Config to update for the chain selector + } + + /// @dev Struct to hold the transfer fee configuration for token transfers + struct TokenTransferFeeConfig { + uint32 minFeeUSDCents; // ──────────╮ Minimum fee to charge per token transfer, multiples of 0.01 USD + uint32 maxFeeUSDCents; // │ Maximum fee to charge per token transfer, multiples of 0.01 USD + uint16 deciBps; // │ Basis points charged on token transfers, multiples of 0.1bps, or 1e-5 + uint32 destGasOverhead; // │ Gas charged to execute the token transfer on the destination chain + // │ Extra data availability bytes that are returned from the source pool and sent + uint32 destBytesOverhead; // │ to the destination pool. Must be >= Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + bool isEnabled; // ─────────────────╯ Whether this token has custom transfer fees + } + + /// @dev Struct to hold the token transfer fee configurations for a token, same as TokenTransferFeeConfig but with the token address included so + /// that an array of these can be passed in the TokenTransferFeeConfigArgs struct to set the mapping + struct TokenTransferFeeConfigSingleTokenArgs { + address token; // Token address + TokenTransferFeeConfig tokenTransferFeeConfig; // struct to hold the transfer fee configuration for token transfers + } + + /// @dev Struct to hold the token transfer fee configurations for a destination chain and a set of tokens. Same as TokenTransferFeeConfigSingleTokenArgs + /// but with the destChainSelector and an array of TokenTransferFeeConfigSingleTokenArgs included so that an array of these can be passed in the constructor + /// and the applyTokenTransferFeeConfigUpdates function + struct TokenTransferFeeConfigArgs { + uint64 destChainSelector; // Destination chain selector + TokenTransferFeeConfigSingleTokenArgs[] tokenTransferFeeConfigs; // Array of token transfer fee configurations + } + + /// @dev Struct to hold a pair of destination chain selector and token address so that an array of these can be passed in the + /// applyTokenTransferFeeConfigUpdates function to remove the token transfer fee configuration for a token + struct TokenTransferFeeConfigRemoveArgs { + uint64 destChainSelector; // ─╮ Destination chain selector + address token; // ────────────╯ Token address + } + + /// @dev Struct to hold the fee token configuration for a token, same as the s_premiumMultiplierWeiPerEth but with + /// the token address included so that an array of these can be passed in the constructor and + /// applyPremiumMultiplierWeiPerEthUpdates to set the mapping + struct PremiumMultiplierWeiPerEthArgs { + address token; // // ───────────────────╮ Token address + uint64 premiumMultiplierWeiPerEth; // ──╯ Multiplier for destination chain specific premiums. Should never be 0 so can be used as an isEnabled flag + } + + string public constant override typeAndVersion = "PriceRegistry 1.6.0-dev"; + + /// @dev The gas price per unit of gas for a given destination chain, in USD with 18 decimals. + /// Multiple gas prices can be encoded into the same value. Each price takes {Internal.GAS_PRICE_BITS} bits. + /// For example, if Optimism is the destination chain, gas price can include L1 base fee and L2 gas price. + /// Logic to parse the price components is chain-specific, and should live in OnRamp. + /// @dev Price of 1e18 is 1 USD. Examples: + /// Very Expensive: 1 unit of gas costs 1 USD -> 1e18 + /// Expensive: 1 unit of gas costs 0.1 USD -> 1e17 + /// Cheap: 1 unit of gas costs 0.000001 USD -> 1e12 + mapping(uint64 destChainSelector => Internal.TimestampedPackedUint224 price) private + s_usdPerUnitGasByDestChainSelector; + + /// @dev The price, in USD with 18 decimals, per 1e18 of the smallest token denomination. + /// @dev Price of 1e18 represents 1 USD per 1e18 token amount. + /// 1 USDC = 1.00 USD per full token, each full token is 1e6 units -> 1 * 1e18 * 1e18 / 1e6 = 1e30 + /// 1 ETH = 2,000 USD per full token, each full token is 1e18 units -> 2000 * 1e18 * 1e18 / 1e18 = 2_000e18 + /// 1 LINK = 5.00 USD per full token, each full token is 1e18 units -> 5 * 1e18 * 1e18 / 1e18 = 5e18 + mapping(address token => Internal.TimestampedPackedUint224 price) private s_usdPerToken; + + /// @dev Stores the price data feed configurations per token. + mapping(address token => IPriceRegistry.TokenPriceFeedConfig dataFeedAddress) private s_usdPriceFeedsPerToken; + + /// @dev The multiplier for destination chain specific premiums that can be set by the owner or fee admin + /// This should never be 0 once set, so it can be used as an isEnabled flag + mapping(address token => uint64 premiumMultiplierWeiPerEth) internal s_premiumMultiplierWeiPerEth; + + /// @dev The destination chain specific fee configs + mapping(uint64 destChainSelector => DestChainConfig destChainConfig) internal s_destChainConfigs; + + /// @dev The token transfer fee config that can be set by the owner or fee admin + mapping(uint64 destChainSelector => mapping(address token => TokenTransferFeeConfig tranferFeeConfig)) internal + s_tokenTransferFeeConfig; + + /// @dev Maximum fee that can be charged for a message. This is a guard to prevent massively overcharging due to misconfiguation. + uint96 internal immutable i_maxFeeJuelsPerMsg; + /// @dev The link token address + address internal immutable i_linkToken; + + // Price updaters are allowed to update the prices. + EnumerableSet.AddressSet private s_priceUpdaters; + // Subset of tokens which prices tracked by this registry which are fee tokens. + EnumerableSet.AddressSet private s_feeTokens; + // The amount of time a gas price can be stale before it is considered invalid. + uint32 private immutable i_stalenessThreshold; + + constructor( + StaticConfig memory staticConfig, + address[] memory priceUpdaters, + address[] memory feeTokens, + TokenPriceFeedUpdate[] memory tokenPriceFeeds, + TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs, + PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs, + DestChainConfigArgs[] memory destChainConfigArgs + ) AuthorizedCallers(priceUpdaters) { + if ( + staticConfig.linkToken == address(0) || staticConfig.maxFeeJuelsPerMsg == 0 + || staticConfig.stalenessThreshold == 0 + ) { + revert InvalidStaticConfig(); + } + + i_linkToken = staticConfig.linkToken; + i_maxFeeJuelsPerMsg = staticConfig.maxFeeJuelsPerMsg; + i_stalenessThreshold = staticConfig.stalenessThreshold; + + _applyFeeTokensUpdates(feeTokens, new address[](0)); + _updateTokenPriceFeeds(tokenPriceFeeds); + _applyDestChainConfigUpdates(destChainConfigArgs); + _applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); + _applyTokenTransferFeeConfigUpdates(tokenTransferFeeConfigArgs, new TokenTransferFeeConfigRemoveArgs[](0)); + } + + // ================================================================ + // │ Price calculations │ + // ================================================================ + + /// @inheritdoc IPriceRegistry + function getTokenPrice(address token) public view override returns (Internal.TimestampedPackedUint224 memory) { + IPriceRegistry.TokenPriceFeedConfig memory priceFeedConfig = s_usdPriceFeedsPerToken[token]; + if (priceFeedConfig.dataFeedAddress == address(0)) { + return s_usdPerToken[token]; + } + + return _getTokenPriceFromDataFeed(priceFeedConfig); + } + + /// @inheritdoc IPriceRegistry + function getValidatedTokenPrice(address token) external view override returns (uint224) { + return _getValidatedTokenPrice(token); + } + + /// @inheritdoc IPriceRegistry + function getTokenPrices(address[] calldata tokens) + external + view + override + returns (Internal.TimestampedPackedUint224[] memory) + { + uint256 length = tokens.length; + Internal.TimestampedPackedUint224[] memory tokenPrices = new Internal.TimestampedPackedUint224[](length); + for (uint256 i = 0; i < length; ++i) { + tokenPrices[i] = getTokenPrice(tokens[i]); + } + return tokenPrices; + } + + /// @inheritdoc IPriceRegistry + function getTokenPriceFeedConfig(address token) + external + view + override + returns (IPriceRegistry.TokenPriceFeedConfig memory) + { + return s_usdPriceFeedsPerToken[token]; + } + + /// @inheritdoc IPriceRegistry + function getDestinationChainGasPrice(uint64 destChainSelector) + external + view + override + returns (Internal.TimestampedPackedUint224 memory) + { + return s_usdPerUnitGasByDestChainSelector[destChainSelector]; + } + + /// @inheritdoc IPriceRegistry + function getTokenAndGasPrices( + address token, + uint64 destChainSelector + ) public view override returns (uint224 tokenPrice, uint224 gasPriceValue) { + Internal.TimestampedPackedUint224 memory gasPrice = s_usdPerUnitGasByDestChainSelector[destChainSelector]; + // We do allow a gas price of 0, but no stale or unset gas prices + if (gasPrice.timestamp == 0) revert ChainNotSupported(destChainSelector); + uint256 timePassed = block.timestamp - gasPrice.timestamp; + if (timePassed > i_stalenessThreshold) revert StaleGasPrice(destChainSelector, i_stalenessThreshold, timePassed); + + return (_getValidatedTokenPrice(token), gasPrice.value); + } + + /// @inheritdoc IPriceRegistry + /// @dev this function assumes that no more than 1e59 dollars are sent as payment. + /// If more is sent, the multiplication of feeTokenAmount and feeTokenValue will overflow. + /// Since there isn't even close to 1e59 dollars in the world economy this is safe. + function convertTokenAmount( + address fromToken, + uint256 fromTokenAmount, + address toToken + ) public view override returns (uint256) { + /// Example: + /// fromTokenAmount: 1e18 // 1 ETH + /// ETH: 2_000e18 + /// LINK: 5e18 + /// return: 1e18 * 2_000e18 / 5e18 = 400e18 (400 LINK) + return (fromTokenAmount * _getValidatedTokenPrice(fromToken)) / _getValidatedTokenPrice(toToken); + } + + /// @notice Gets the token price for a given token and revert if the token is not supported + /// @param token The address of the token to get the price for + /// @return the token price + function _getValidatedTokenPrice(address token) internal view returns (uint224) { + Internal.TimestampedPackedUint224 memory tokenPrice = getTokenPrice(token); + // Token price must be set at least once + if (tokenPrice.timestamp == 0 || tokenPrice.value == 0) revert TokenNotSupported(token); + return tokenPrice.value; + } + + /// @notice Gets the token price from a data feed address, rebased to the same units as s_usdPerToken + /// @param priceFeedConfig token data feed configuration with valid data feed address (used to retrieve price & timestamp) + /// @return tokenPrice data feed price answer rebased to s_usdPerToken units, with latest block timestamp + function _getTokenPriceFromDataFeed(IPriceRegistry.TokenPriceFeedConfig memory priceFeedConfig) + internal + view + returns (Internal.TimestampedPackedUint224 memory tokenPrice) + { + AggregatorV3Interface dataFeedContract = AggregatorV3Interface(priceFeedConfig.dataFeedAddress); + ( + /* uint80 roundID */ + , + int256 dataFeedAnswer, + /* uint startedAt */ + , + /* uint256 updatedAt */ + , + /* uint80 answeredInRound */ + ) = dataFeedContract.latestRoundData(); + + if (dataFeedAnswer < 0) { + revert DataFeedValueOutOfUint224Range(); + } + uint256 rebasedValue = uint256(dataFeedAnswer); + + // Rebase formula for units in smallest token denomination: usdValue * (1e18 * 1e18) / 1eTokenDecimals + // feedValue * (10 ** (18 - feedDecimals)) * (10 ** (18 - erc20Decimals)) + // feedValue * (10 ** ((18 - feedDecimals) + (18 - erc20Decimals))) + // feedValue * (10 ** (36 - feedDecimals - erc20Decimals)) + // feedValue * (10 ** (36 - (feedDecimals + erc20Decimals))) + // feedValue * (10 ** (36 - excessDecimals)) + // If excessDecimals > 36 => flip it to feedValue / (10 ** (excessDecimals - 36)) + + uint8 excessDecimals = dataFeedContract.decimals() + priceFeedConfig.tokenDecimals; + + if (excessDecimals > 36) { + rebasedValue /= 10 ** (excessDecimals - 36); + } else { + rebasedValue *= 10 ** (36 - excessDecimals); + } + + if (rebasedValue > type(uint224).max) { + revert DataFeedValueOutOfUint224Range(); + } + + // Data feed staleness is unchecked to decouple the PriceRegistry from data feed delay issues + return Internal.TimestampedPackedUint224({value: uint224(rebasedValue), timestamp: uint32(block.timestamp)}); + } + + // ================================================================ + // │ Fee tokens │ + // ================================================================ + + /// @inheritdoc IPriceRegistry + function getFeeTokens() external view returns (address[] memory) { + return s_feeTokens.values(); + } + + /// @notice Add and remove tokens from feeTokens set. + /// @param feeTokensToAdd The addresses of the tokens which are now considered fee tokens + /// and can be used to calculate fees. + /// @param feeTokensToRemove The addresses of the tokens which are no longer considered feeTokens. + function applyFeeTokensUpdates( + address[] memory feeTokensToAdd, + address[] memory feeTokensToRemove + ) external onlyOwner { + _applyFeeTokensUpdates(feeTokensToAdd, feeTokensToRemove); + } + + /// @notice Add and remove tokens from feeTokens set. + /// @param feeTokensToAdd The addresses of the tokens which are now considered fee tokens + /// and can be used to calculate fees. + /// @param feeTokensToRemove The addresses of the tokens which are no longer considered feeTokens. + function _applyFeeTokensUpdates(address[] memory feeTokensToAdd, address[] memory feeTokensToRemove) private { + for (uint256 i = 0; i < feeTokensToAdd.length; ++i) { + if (s_feeTokens.add(feeTokensToAdd[i])) { + emit FeeTokenAdded(feeTokensToAdd[i]); + } + } + for (uint256 i = 0; i < feeTokensToRemove.length; ++i) { + if (s_feeTokens.remove(feeTokensToRemove[i])) { + emit FeeTokenRemoved(feeTokensToRemove[i]); + } + } + } + + // ================================================================ + // │ Price updates │ + // ================================================================ + + /// @inheritdoc IPriceRegistry + function updatePrices(Internal.PriceUpdates calldata priceUpdates) external override { + // The caller must be the fee updater + _validateCaller(); + + uint256 tokenUpdatesLength = priceUpdates.tokenPriceUpdates.length; + + for (uint256 i = 0; i < tokenUpdatesLength; ++i) { + Internal.TokenPriceUpdate memory update = priceUpdates.tokenPriceUpdates[i]; + s_usdPerToken[update.sourceToken] = + Internal.TimestampedPackedUint224({value: update.usdPerToken, timestamp: uint32(block.timestamp)}); + emit UsdPerTokenUpdated(update.sourceToken, update.usdPerToken, block.timestamp); + } + + uint256 gasUpdatesLength = priceUpdates.gasPriceUpdates.length; + + for (uint256 i = 0; i < gasUpdatesLength; ++i) { + Internal.GasPriceUpdate memory update = priceUpdates.gasPriceUpdates[i]; + s_usdPerUnitGasByDestChainSelector[update.destChainSelector] = + Internal.TimestampedPackedUint224({value: update.usdPerUnitGas, timestamp: uint32(block.timestamp)}); + emit UsdPerUnitGasUpdated(update.destChainSelector, update.usdPerUnitGas, block.timestamp); + } + } + + /// @notice Updates the USD token price feeds for given tokens + /// @param tokenPriceFeedUpdates Token price feed updates to apply + function updateTokenPriceFeeds(TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates) external onlyOwner { + _updateTokenPriceFeeds(tokenPriceFeedUpdates); + } + + /// @notice Updates the USD token price feeds for given tokens + /// @param tokenPriceFeedUpdates Token price feed updates to apply + function _updateTokenPriceFeeds(TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates) private { + for (uint256 i; i < tokenPriceFeedUpdates.length; ++i) { + TokenPriceFeedUpdate memory update = tokenPriceFeedUpdates[i]; + address sourceToken = update.sourceToken; + IPriceRegistry.TokenPriceFeedConfig memory tokenPriceFeedConfig = update.feedConfig; + + s_usdPriceFeedsPerToken[sourceToken] = tokenPriceFeedConfig; + emit PriceFeedPerTokenUpdated(sourceToken, tokenPriceFeedConfig); + } + } + + // ================================================================ + // │ Fee quoting │ + // ================================================================ + + /// @inheritdoc IPriceRegistry + /// @dev The function should always validate message.extraArgs, message.receiver and family-specific configs + function getValidatedFee( + uint64 destChainSelector, + Client.EVM2AnyMessage calldata message + ) external view returns (uint256 feeTokenAmount) { + DestChainConfig memory destChainConfig = s_destChainConfigs[destChainSelector]; + if (!destChainConfig.isEnabled) revert DestinationChainNotEnabled(destChainSelector); + + uint256 numberOfTokens = message.tokenAmounts.length; + _validateMessage(destChainConfig, message.data.length, numberOfTokens, message.receiver); + + uint64 premiumMultiplierWeiPerEth = s_premiumMultiplierWeiPerEth[message.feeToken]; + + // The below call asserts that feeToken is a supported token + (uint224 feeTokenPrice, uint224 packedGasPrice) = getTokenAndGasPrices(message.feeToken, destChainSelector); + + // Calculate premiumFee in USD with 18 decimals precision first. + // If message-only and no token transfers, a flat network fee is charged. + // If there are token transfers, premiumFee is calculated from token transfer fee. + // If there are both token transfers and message, premiumFee is only calculated from token transfer fee. + uint256 premiumFee = 0; + uint32 tokenTransferGas = 0; + uint32 tokenTransferBytesOverhead = 0; + if (numberOfTokens > 0) { + (premiumFee, tokenTransferGas, tokenTransferBytesOverhead) = + _getTokenTransferCost(destChainConfig, destChainSelector, message.feeToken, feeTokenPrice, message.tokenAmounts); + } else { + // Convert USD cents with 2 decimals to 18 decimals. + premiumFee = uint256(destChainConfig.networkFeeUSDCents) * 1e16; + } + + // Calculate data availability cost in USD with 36 decimals. Data availability cost exists on rollups that need to post + // transaction calldata onto another storage layer, e.g. Eth mainnet, incurring additional storage gas costs. + uint256 dataAvailabilityCost = 0; + + // Only calculate data availability cost if data availability multiplier is non-zero. + // The multiplier should be set to 0 if destination chain does not charge data availability cost. + if (destChainConfig.destDataAvailabilityMultiplierBps > 0) { + dataAvailabilityCost = _getDataAvailabilityCost( + destChainConfig, + // Parse the data availability gas price stored in the higher-order 112 bits of the encoded gas price. + uint112(packedGasPrice >> Internal.GAS_PRICE_BITS), + message.data.length, + numberOfTokens, + tokenTransferBytesOverhead + ); + } + + // Calculate execution gas fee on destination chain in USD with 36 decimals. + // We add the message gas limit, the overhead gas, the gas of passing message data to receiver, and token transfer gas together. + // We then multiply this gas total with the gas multiplier and gas price, converting it into USD with 36 decimals. + // uint112(packedGasPrice) = executionGasPrice + + // NOTE: when supporting non-EVM chains, revisit how generic this fee logic can be + // NOTE: revisit parsing non-EVM args + + uint256 executionCost = uint112(packedGasPrice) + * ( + destChainConfig.destGasOverhead + (message.data.length * destChainConfig.destGasPerPayloadByte) + tokenTransferGas + + _parseEVMExtraArgsFromBytes(message.extraArgs, destChainConfig).gasLimit + ) * destChainConfig.gasMultiplierWeiPerEth; + + // Calculate number of fee tokens to charge. + // Total USD fee is in 36 decimals, feeTokenPrice is in 18 decimals USD for 1e18 smallest token denominations. + // Result of the division is the number of smallest token denominations. + return ((premiumFee * premiumMultiplierWeiPerEth) + executionCost + dataAvailabilityCost) / feeTokenPrice; + } + + /// @notice Sets the fee configuration for a token + /// @param premiumMultiplierWeiPerEthArgs Array of PremiumMultiplierWeiPerEthArgs structs. + function applyPremiumMultiplierWeiPerEthUpdates( + PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs + ) external onlyOwner { + _applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); + } + + /// @dev Set the fee config. + /// @param premiumMultiplierWeiPerEthArgs The multiplier for destination chain specific premiums. + function _applyPremiumMultiplierWeiPerEthUpdates( + PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs + ) internal { + for (uint256 i = 0; i < premiumMultiplierWeiPerEthArgs.length; ++i) { + address token = premiumMultiplierWeiPerEthArgs[i].token; + uint64 premiumMultiplierWeiPerEth = premiumMultiplierWeiPerEthArgs[i].premiumMultiplierWeiPerEth; + s_premiumMultiplierWeiPerEth[token] = premiumMultiplierWeiPerEth; + + emit PremiumMultiplierWeiPerEthUpdated(token, premiumMultiplierWeiPerEth); + } + } + + /// @notice Gets the fee configuration for a token. + /// @param token The token to get the fee configuration for. + /// @return premiumMultiplierWeiPerEth The multiplier for destination chain specific premiums. + function getPremiumMultiplierWeiPerEth(address token) external view returns (uint64 premiumMultiplierWeiPerEth) { + return s_premiumMultiplierWeiPerEth[token]; + } + + /// @notice Returns the token transfer cost parameters. + /// A basis point fee is calculated from the USD value of each token transfer. + /// For each individual transfer, this fee is between [minFeeUSD, maxFeeUSD]. + /// Total transfer fee is the sum of each individual token transfer fee. + /// @dev Assumes that tokenAmounts are validated to be listed tokens elsewhere. + /// @dev Splitting one token transfer into multiple transfers is discouraged, + /// as it will result in a transferFee equal or greater than the same amount aggregated/de-duped. + /// @param destChainConfig the config configured for the destination chain selector. + /// @param destChainSelector the destination chain selector. + /// @param feeToken address of the feeToken. + /// @param feeTokenPrice price of feeToken in USD with 18 decimals. + /// @param tokenAmounts token transfers in the message. + /// @return tokenTransferFeeUSDWei total token transfer bps fee in USD with 18 decimals. + /// @return tokenTransferGas total execution gas of the token transfers. + /// @return tokenTransferBytesOverhead additional token transfer data passed to destination, e.g. USDC attestation. + function _getTokenTransferCost( + DestChainConfig memory destChainConfig, + uint64 destChainSelector, + address feeToken, + uint224 feeTokenPrice, + Client.EVMTokenAmount[] calldata tokenAmounts + ) internal view returns (uint256 tokenTransferFeeUSDWei, uint32 tokenTransferGas, uint32 tokenTransferBytesOverhead) { + uint256 numberOfTokens = tokenAmounts.length; + + for (uint256 i = 0; i < numberOfTokens; ++i) { + Client.EVMTokenAmount memory tokenAmount = tokenAmounts[i]; + TokenTransferFeeConfig memory transferFeeConfig = s_tokenTransferFeeConfig[destChainSelector][tokenAmount.token]; + + // If the token has no specific overrides configured, we use the global defaults. + if (!transferFeeConfig.isEnabled) { + tokenTransferFeeUSDWei += uint256(destChainConfig.defaultTokenFeeUSDCents) * 1e16; + tokenTransferGas += destChainConfig.defaultTokenDestGasOverhead; + tokenTransferBytesOverhead += destChainConfig.defaultTokenDestBytesOverhead; + continue; + } + + uint256 bpsFeeUSDWei = 0; + // Only calculate bps fee if ratio is greater than 0. Ratio of 0 means no bps fee for a token. + // Useful for when the PriceRegistry cannot return a valid price for the token. + if (transferFeeConfig.deciBps > 0) { + uint224 tokenPrice = 0; + if (tokenAmount.token != feeToken) { + tokenPrice = _getValidatedTokenPrice(tokenAmount.token); + } else { + tokenPrice = feeTokenPrice; + } + + // Calculate token transfer value, then apply fee ratio + // ratio represents multiples of 0.1bps, or 1e-5 + bpsFeeUSDWei = (tokenPrice._calcUSDValueFromTokenAmount(tokenAmount.amount) * transferFeeConfig.deciBps) / 1e5; + } + + tokenTransferGas += transferFeeConfig.destGasOverhead; + tokenTransferBytesOverhead += transferFeeConfig.destBytesOverhead; + + // Bps fees should be kept within range of [minFeeUSD, maxFeeUSD]. + // Convert USD values with 2 decimals to 18 decimals. + uint256 minFeeUSDWei = uint256(transferFeeConfig.minFeeUSDCents) * 1e16; + if (bpsFeeUSDWei < minFeeUSDWei) { + tokenTransferFeeUSDWei += minFeeUSDWei; + continue; + } + + uint256 maxFeeUSDWei = uint256(transferFeeConfig.maxFeeUSDCents) * 1e16; + if (bpsFeeUSDWei > maxFeeUSDWei) { + tokenTransferFeeUSDWei += maxFeeUSDWei; + continue; + } + + tokenTransferFeeUSDWei += bpsFeeUSDWei; + } + + return (tokenTransferFeeUSDWei, tokenTransferGas, tokenTransferBytesOverhead); + } + + /// @notice Returns the estimated data availability cost of the message. + /// @dev To save on gas, we use a single destGasPerDataAvailabilityByte value for both zero and non-zero bytes. + /// @param destChainConfig the config configured for the destination chain selector. + /// @param dataAvailabilityGasPrice USD per data availability gas in 18 decimals. + /// @param messageDataLength length of the data field in the message. + /// @param numberOfTokens number of distinct token transfers in the message. + /// @param tokenTransferBytesOverhead additional token transfer data passed to destination, e.g. USDC attestation. + /// @return dataAvailabilityCostUSD36Decimal total data availability cost in USD with 36 decimals. + function _getDataAvailabilityCost( + DestChainConfig memory destChainConfig, + uint112 dataAvailabilityGasPrice, + uint256 messageDataLength, + uint256 numberOfTokens, + uint32 tokenTransferBytesOverhead + ) internal pure returns (uint256 dataAvailabilityCostUSD36Decimal) { + // dataAvailabilityLengthBytes sums up byte lengths of fixed message fields and dynamic message fields. + // Fixed message fields do account for the offset and length slot of the dynamic fields. + uint256 dataAvailabilityLengthBytes = Internal.ANY_2_EVM_MESSAGE_FIXED_BYTES + messageDataLength + + (numberOfTokens * Internal.ANY_2_EVM_MESSAGE_FIXED_BYTES_PER_TOKEN) + tokenTransferBytesOverhead; + + // destDataAvailabilityOverheadGas is a separate config value for flexibility to be updated independently of message cost. + // Its value is determined by CCIP lane implementation, e.g. the overhead data posted for OCR. + uint256 dataAvailabilityGas = (dataAvailabilityLengthBytes * destChainConfig.destGasPerDataAvailabilityByte) + + destChainConfig.destDataAvailabilityOverheadGas; + + // dataAvailabilityGasPrice is in 18 decimals, destDataAvailabilityMultiplierBps is in 4 decimals + // We pad 14 decimals to bring the result to 36 decimals, in line with token bps and execution fee. + return ((dataAvailabilityGas * dataAvailabilityGasPrice) * destChainConfig.destDataAvailabilityMultiplierBps) * 1e14; + } + + /// @notice Gets the transfer fee config for a given token. + /// @param destChainSelector The destination chain selector. + /// @param token The token address. + function getTokenTransferFeeConfig( + uint64 destChainSelector, + address token + ) external view returns (TokenTransferFeeConfig memory tokenTransferFeeConfig) { + return s_tokenTransferFeeConfig[destChainSelector][token]; + } + + /// @notice Sets the transfer fee config. + /// @dev only callable by the owner or admin. + function applyTokenTransferFeeConfigUpdates( + TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs, + TokenTransferFeeConfigRemoveArgs[] memory tokensToUseDefaultFeeConfigs + ) external onlyOwner { + _applyTokenTransferFeeConfigUpdates(tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs); + } + + /// @notice internal helper to set the token transfer fee config. + function _applyTokenTransferFeeConfigUpdates( + TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs, + TokenTransferFeeConfigRemoveArgs[] memory tokensToUseDefaultFeeConfigs + ) internal { + for (uint256 i = 0; i < tokenTransferFeeConfigArgs.length; ++i) { + TokenTransferFeeConfigArgs memory tokenTransferFeeConfigArg = tokenTransferFeeConfigArgs[i]; + uint64 destChainSelector = tokenTransferFeeConfigArg.destChainSelector; + + for (uint256 j = 0; j < tokenTransferFeeConfigArg.tokenTransferFeeConfigs.length; ++j) { + TokenTransferFeeConfig memory tokenTransferFeeConfig = + tokenTransferFeeConfigArg.tokenTransferFeeConfigs[j].tokenTransferFeeConfig; + address token = tokenTransferFeeConfigArg.tokenTransferFeeConfigs[j].token; + + if (tokenTransferFeeConfig.destBytesOverhead < Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) { + revert InvalidDestBytesOverhead(token, tokenTransferFeeConfig.destBytesOverhead); + } + + s_tokenTransferFeeConfig[destChainSelector][token] = tokenTransferFeeConfig; + + emit TokenTransferFeeConfigUpdated(destChainSelector, token, tokenTransferFeeConfig); + } + } + + // Remove the custom fee configs for the tokens that are in the tokensToUseDefaultFeeConfigs array + for (uint256 i = 0; i < tokensToUseDefaultFeeConfigs.length; ++i) { + uint64 destChainSelector = tokensToUseDefaultFeeConfigs[i].destChainSelector; + address token = tokensToUseDefaultFeeConfigs[i].token; + delete s_tokenTransferFeeConfig[destChainSelector][token]; + emit TokenTransferFeeConfigDeleted(destChainSelector, token); + } + } + + // ================================================================ + // │ Validations & message processing │ + // ================================================================ + + /// @notice Validates that the destAddress matches the expected format of the family. + /// @param chainFamilySelector Tag to identify the target family + /// @param destAddress Dest address to validate + /// @dev precondition - assumes the family tag is correct and validated + function _validateDestFamilyAddress(bytes4 chainFamilySelector, bytes memory destAddress) internal pure { + if (chainFamilySelector == Internal.CHAIN_FAMILY_SELECTOR_EVM) { + Internal._validateEVMAddress(destAddress); + } + } + + /// @dev Convert the extra args bytes into a struct with validations against the dest chain config + /// @param extraArgs The extra args bytes + /// @param destChainConfig Dest chain config to validate against + /// @return EVMExtraArgs the extra args struct (latest version) + function _parseEVMExtraArgsFromBytes( + bytes calldata extraArgs, + DestChainConfig memory destChainConfig + ) internal pure returns (Client.EVMExtraArgsV2 memory) { + Client.EVMExtraArgsV2 memory evmExtraArgs = + _parseUnvalidatedEVMExtraArgsFromBytes(extraArgs, destChainConfig.defaultTxGasLimit); + + if (evmExtraArgs.gasLimit > uint256(destChainConfig.maxPerMsgGasLimit)) revert MessageGasLimitTooHigh(); + if (destChainConfig.enforceOutOfOrder && !evmExtraArgs.allowOutOfOrderExecution) { + revert ExtraArgOutOfOrderExecutionMustBeTrue(); + } + + return evmExtraArgs; + } + + /// @dev Convert the extra args bytes into a struct + /// @param extraArgs The extra args bytes + /// @param defaultTxGasLimit default tx gas limit to use in the absence of extra args + /// @return EVMExtraArgs the extra args struct (latest version) + function _parseUnvalidatedEVMExtraArgsFromBytes( + bytes calldata extraArgs, + uint64 defaultTxGasLimit + ) private pure returns (Client.EVMExtraArgsV2 memory) { + if (extraArgs.length == 0) { + // If extra args are empty, generate default values + return Client.EVMExtraArgsV2({gasLimit: defaultTxGasLimit, allowOutOfOrderExecution: false}); + } + + bytes4 extraArgsTag = bytes4(extraArgs); + bytes memory argsData = extraArgs[4:]; + + if (extraArgsTag == Client.EVM_EXTRA_ARGS_V2_TAG) { + return abi.decode(argsData, (Client.EVMExtraArgsV2)); + } else if (extraArgsTag == Client.EVM_EXTRA_ARGS_V1_TAG) { + // EVMExtraArgsV1 originally included a second boolean (strict) field which has been deprecated. + // Clients may still include it but it will be ignored. + return Client.EVMExtraArgsV2({gasLimit: abi.decode(argsData, (uint256)), allowOutOfOrderExecution: false}); + } + + revert InvalidExtraArgsTag(); + } + + /// @notice Validate the forwarded message to ensure it matches the configuration limits (message length, number of tokens) + /// and family-specific expectations (address format) + /// @param destChainConfig Dest chain config + /// @param dataLength The length of the data field of the message. + /// @param numberOfTokens The number of tokens to be sent. + /// @param receiver Message receiver on the dest chain + function _validateMessage( + DestChainConfig memory destChainConfig, + uint256 dataLength, + uint256 numberOfTokens, + bytes memory receiver + ) internal pure { + // Check that payload is formed correctly + if (dataLength > uint256(destChainConfig.maxDataBytes)) { + revert MessageTooLarge(uint256(destChainConfig.maxDataBytes), dataLength); + } + if (numberOfTokens > uint256(destChainConfig.maxNumberOfTokensPerMsg)) revert UnsupportedNumberOfTokens(); + _validateDestFamilyAddress(destChainConfig.chainFamilySelector, receiver); + } + + /// @inheritdoc IPriceRegistry + function processMessageArgs( + uint64 destChainSelector, + address feeToken, + uint256 feeTokenAmount, + bytes calldata extraArgs + ) external view returns (uint256 msgFeeJuels, bool isOutOfOrderExecution, bytes memory convertedExtraArgs) { + // Convert feeToken to link if not already in link + if (feeToken == i_linkToken) { + msgFeeJuels = feeTokenAmount; + } else { + msgFeeJuels = convertTokenAmount(feeToken, feeTokenAmount, i_linkToken); + } + + if (msgFeeJuels > i_maxFeeJuelsPerMsg) revert MessageFeeTooHigh(msgFeeJuels, i_maxFeeJuelsPerMsg); + + uint64 defaultTxGasLimit = s_destChainConfigs[destChainSelector].defaultTxGasLimit; + // NOTE: when supporting non-EVM chains, revisit this and parse non-EVM args. + // We can parse unvalidated args since this message is called after getFee (which will already validate the params) + Client.EVMExtraArgsV2 memory parsedExtraArgs = _parseUnvalidatedEVMExtraArgsFromBytes(extraArgs, defaultTxGasLimit); + isOutOfOrderExecution = parsedExtraArgs.allowOutOfOrderExecution; + + return (msgFeeJuels, isOutOfOrderExecution, Client._argsToBytes(parsedExtraArgs)); + } + + /// @inheritdoc IPriceRegistry + /// @dev precondition - rampTokenAmounts and sourceTokenAmounts lengths must be equal + function validatePoolReturnData( + uint64 destChainSelector, + Internal.RampTokenAmount[] calldata rampTokenAmounts, + Client.EVMTokenAmount[] calldata sourceTokenAmounts + ) external view { + bytes4 chainFamilySelector = s_destChainConfigs[destChainSelector].chainFamilySelector; + + for (uint256 i = 0; i < rampTokenAmounts.length; ++i) { + address sourceToken = sourceTokenAmounts[i].token; + + // Since the DON has to pay for the extraData to be included on the destination chain, we cap the length of the + // extraData. This prevents gas bomb attacks on the NOPs. As destBytesOverhead accounts for both + // extraData and offchainData, this caps the worst case abuse to the number of bytes reserved for offchainData. + uint256 destPoolDataLength = rampTokenAmounts[i].extraData.length; + if (destPoolDataLength > Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) { + if (destPoolDataLength > s_tokenTransferFeeConfig[destChainSelector][sourceToken].destBytesOverhead) { + revert SourceTokenDataTooLarge(sourceToken); + } + } + + _validateDestFamilyAddress(chainFamilySelector, rampTokenAmounts[i].destTokenAddress); + } + } + + // ================================================================ + // │ Configs │ + // ================================================================ + + /// @notice Returns the configured config for the dest chain selector + /// @param destChainSelector destination chain selector to fetch config for + /// @return destChainConfig config for the dest chain + function getDestChainConfig(uint64 destChainSelector) external view returns (DestChainConfig memory) { + return s_destChainConfigs[destChainSelector]; + } + + /// @notice Updates the destination chain specific config. + /// @param destChainConfigArgs Array of source chain specific configs. + function applyDestChainConfigUpdates(DestChainConfigArgs[] memory destChainConfigArgs) external onlyOwner { + _applyDestChainConfigUpdates(destChainConfigArgs); + } + + /// @notice Internal version of applyDestChainConfigUpdates. + function _applyDestChainConfigUpdates(DestChainConfigArgs[] memory destChainConfigArgs) internal { + for (uint256 i = 0; i < destChainConfigArgs.length; ++i) { + DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[i]; + uint64 destChainSelector = destChainConfigArgs[i].destChainSelector; + DestChainConfig memory destChainConfig = destChainConfigArg.destChainConfig; + + // NOTE: when supporting non-EVM chains, update chainFamilySelector validations + if ( + destChainSelector == 0 || destChainConfig.defaultTxGasLimit == 0 + || destChainConfig.chainFamilySelector != Internal.CHAIN_FAMILY_SELECTOR_EVM + || destChainConfig.defaultTokenDestBytesOverhead < Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + || destChainConfig.defaultTxGasLimit > destChainConfig.maxPerMsgGasLimit + ) { + revert InvalidDestChainConfig(destChainSelector); + } + + // The chain family selector cannot be zero - indicates that it is a new chain + if (s_destChainConfigs[destChainSelector].chainFamilySelector == 0) { + emit DestChainAdded(destChainSelector, destChainConfig); + } else { + emit DestChainConfigUpdated(destChainSelector, destChainConfig); + } + + s_destChainConfigs[destChainSelector] = destChainConfig; + } + } + + /// @notice Returns the static PriceRegistry config. + /// @dev RMN depends on this function, if changing, please notify the RMN maintainers. + /// @return the configuration. + function getStaticConfig() external view returns (StaticConfig memory) { + return StaticConfig({ + maxFeeJuelsPerMsg: i_maxFeeJuelsPerMsg, + linkToken: i_linkToken, + stalenessThreshold: i_stalenessThreshold + }); + } +} diff --git a/contracts/src/v0.8/ccip/RMN.sol b/contracts/src/v0.8/ccip/RMN.sol new file mode 100644 index 0000000000..424aad8fa5 --- /dev/null +++ b/contracts/src/v0.8/ccip/RMN.sol @@ -0,0 +1,964 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; +import {IRMN} from "./interfaces/IRMN.sol"; + +import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol"; + +import {EnumerableSet} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +// An active curse on this subject will cause isCursed() to return true. Use this subject if there is an issue with a +// remote chain, for which there exists a legacy lane contract deployed on the same chain as this RMN contract is +// deployed, relying on isCursed(). +bytes16 constant LEGACY_CURSE_SUBJECT = 0x01000000000000000000000000000000; + +// An active curse on this subject will cause isCursed() and isCursed(bytes32) to return true. Use this subject for +// issues affecting all of CCIP chains, or pertaining to the chain that this contract is deployed on, instead of using +// the local chain selector as a subject. +bytes16 constant GLOBAL_CURSE_SUBJECT = 0x01000000000000000000000000000001; + +// The curse vote address representing the owner in data structures, events and recorded votes. Remains constant, even +// if the owner changes. +address constant OWNER_CURSE_VOTE_ADDR = address(~uint160(0)); // 0xff...ff + +// The curse vote address used in an OwnerUnvoteToCurseRequest to lift a curse, if there is no active curse votes for +// the subject that we are able to unvote, but the conditions for an active curse no longer hold. +address constant LIFT_CURSE_VOTE_ADDR = address(0); + +/// @dev This contract is owned by RMN, if changing, please notify the RMN maintainers. +// solhint-disable chainlink-solidity/explicit-returns +contract RMN is IRMN, OwnerIsCreator, ITypeAndVersion { + using EnumerableSet for EnumerableSet.AddressSet; + + // STATIC CONFIG + string public constant override typeAndVersion = "RMN 1.5.0-dev"; + + uint256 private constant MAX_NUM_VOTERS = 16; + + // MAGIC VALUES + bytes28 private constant NO_VOTES_CURSES_HASH = bytes28(0); + + // DYNAMIC CONFIG + /// @notice blessVoteAddr and curseVoteAddr can't be 0. Additionally curseVoteAddr can't be LIFT_CURSE_VOTE_ADDR or + /// OWNER_CURSE_VOTE_ADDR. At least one of blessWeight & curseWeight must be non-zero, i.e., a voter could only vote + /// to bless, or only vote to curse, or both vote to bless and vote to curse. + struct Voter { + // This is the address the voter should use to call voteToBless. + address blessVoteAddr; + // This is the address the voter should use to call voteToCurse. + address curseVoteAddr; + // The weight of this voter's vote for blessing. + uint8 blessWeight; + // The weight of this voter's vote for cursing. + uint8 curseWeight; + } + + struct Config { + Voter[] voters; + // When the total weight of voters that have voted to bless a tagged root reaches + // or exceeds blessWeightThreshold, the tagged root becomes blessed. + uint16 blessWeightThreshold; + // When the total weight of voters that have voted to curse a subject reaches or + // exceeds curseWeightThreshold, the subject becomes cursed. + uint16 curseWeightThreshold; + } + + struct VersionedConfig { + Config config; + // The version is incremented every time the config changes. + // The initial configuration on the contract will have configVersion == 1. + uint32 configVersion; + // The block number at which the config was last set. Helps the offchain + // code check that the config was set in a stable block or double-check + // that it has the correct config by querying logs at that block number. + uint32 blockNumber; + } + + VersionedConfig private s_versionedConfig; + + // STATE + struct BlesserRecord { + // The config version at which this BlesserRecord was last set. A blesser + // is considered active iff this configVersion equals + // s_versionedConfig.configVersion. + uint32 configVersion; + uint8 weight; + uint8 index; + } + + mapping(address blessVoteAddr => BlesserRecord blesserRecord) private s_blesserRecords; + + struct BlessVoteProgress { + // This particular ordering saves us ~400 gas per voteToBless call, compared to the bool being at the bottom, even + // though the size of the struct is the same. + bool weightThresholdMet; + // A BlessVoteProgress is considered invalid if weightThresholdMet is false when + // s_versionedConfig.configVersion changes. we don't want old in-progress + // votes to continue when we set a new config! + // The config version at which the bless vote for a tagged root was initiated. + uint32 configVersion; + uint16 accumulatedWeight; + // Care must be taken that the bitmap has at least as many bits as MAX_NUM_VOTERS. + // uint200 is much larger than we need, but it saves us ~100 gas per voteToBless call to fill the word instead of + // using a smaller type. + // _bitmapGet(voterBitmap, i) = true indicates that the i-th voter has voted to bless + uint200 voterBitmap; + } + + mapping(bytes32 taggedRootHash => BlessVoteProgress blessVoteProgress) private s_blessVoteProgressByTaggedRootHash; + + // Any tagged root with a commit store included in s_permaBlessedCommitStores will be considered automatically + // blessed. + EnumerableSet.AddressSet private s_permaBlessedCommitStores; + + struct CurserRecord { + bool active; + uint8 weight; + mapping(bytes16 curseId => bool used) usedCurseIds; // retained across config changes + } + + mapping(address curseVoteAddr => CurserRecord curserRecord) private s_curserRecords; + + struct ConfigVersionAndCursesHash { + uint32 configVersion; // configVersion != s_versionedConfig.configVersion means no active vote + bytes28 cursesHash; // bytes28(0) means no active vote; truncated so that ConfigVersionAndCursesHash fits in a word + } + + struct CurseVoteProgress { + uint32 configVersion; // upon config change, lazy set to new config version + uint16 curseWeightThreshold; // upon config change, lazy set to new config value + uint16 accumulatedWeight; // upon config change, lazy set to 0 + // A curse becomes active after either: + // - sum([voter.weight for voter who voted in current config]) >= curseWeightThreshold + // - ownerCurse is invoked + // Once a curse is active, only the owner can lift it. + bool curseActive; // retained across config changes + mapping(address => ConfigVersionAndCursesHash) latestVoteToCurseByCurseVoteAddr; // retained across config changes + } + + mapping(bytes16 subject => CurseVoteProgress curseVoteProgress) private + s_potentiallyOutdatedCurseVoteProgressBySubject; + + // We intentionally use a struct here, even though it contains a single field, to make it obvious to future editors + // that there is space for more fields. + struct CurseHotVars { + uint64 numSubjectsCursed; // incremented by voteToCurse, ownerCurse; decremented by ownerUnvoteToCurse + } + + CurseHotVars private s_curseHotVars; + + enum RecordedCurseRelatedOpTag { + // A vote to curse, through either voteToCurse or ownerCurse. + VoteToCurse, + // An unvote to curse, through unvoteToCurse. + UnvoteToCurse, + // An unvote to curse, through ownerUnvoteToCurse, which was not forced (forceUnvote=false). + OwnerUnvoteToCurseUnforced, + // An unvote to curse, through ownerUnvoteToCurse, which was forced (forceUnvote=true). + OwnerUnvoteToCurseForced, + // A configuration change. + // + // For subjects that are not cursed when this happens, past votes do not get accounted for in the new configuration. + // If a voter votes during the new configuration, their curses hash will restart from NO_VOTES_CURSES_HASH. + // + // For subjects that are cursed when this happens, past votes get accounted for. + // If a voter votes during the new configuration, their curses hash will continue from its old value. + SetConfig + } + + /// @notice Provides the ability to quickly reconstruct the curse-related state of the contract offchain, without + /// having to replay all past events. Replaying past events often takes long, and in some cases might even be + /// infeasible due to log pruning. + /// + /// @dev We could save some gas by omitting some fields and instead using them as mapping keys, but we would lose the + /// cross-voter ordering, or cross-subject ordering, or cross-vote/unvote ordering. + struct RecordedCurseRelatedOp { + RecordedCurseRelatedOpTag tag; + uint64 blockTimestamp; + bool cursed; // whether the subject is cursed after this op; if tag in {SetConfig}, will be false + address curseVoteAddr; // if tag in {SetConfig}, will be address(0) + bytes16 subject; // if tag in {SetConfig}, will be bytes16(0) + bytes16 curseId; // if tag in {SetConfig, UnvoteToCurse, OwnerUnvoteToCurseUnforced, OwnerUnvoteToCurseForced}, will be bytes16(0) + } + + RecordedCurseRelatedOp[] private s_recordedCurseRelatedOps; + + /// @dev This function is to _ONLY_ be called in order to determine if a curse should become active upon a + /// vote-to-curse, or a curse should be deactivated upon an owner-unvote-to-curse. + /// Other reasons for a curse to be active, which are not covered here: + /// 1. Cursedness is retained from a prior config. + /// 2. The curse weight threshold was met at some point, which activated a curse, and enough voters unvoted to curse + /// such that the curse weight threshold is no longer met. + function _shouldCurseBeActive(CurseVoteProgress storage sptr_upToDateCurseVoteProgress) internal view returns (bool) { + return sptr_upToDateCurseVoteProgress.latestVoteToCurseByCurseVoteAddr[OWNER_CURSE_VOTE_ADDR].cursesHash + != NO_VOTES_CURSES_HASH + || sptr_upToDateCurseVoteProgress.accumulatedWeight >= sptr_upToDateCurseVoteProgress.curseWeightThreshold; + } + + /// @dev It might be the case that due to the lazy update of curseVoteProgress, a curse is active even though + /// _shouldCurseBeActive(curseVoteProgress) is false, i.e., the owner has no active vote to curse and the curse + /// weight threshold has not been met. + function _getUpToDateCurseVoteProgress( + uint32 configVersion, + bytes16 subject + ) internal returns (CurseVoteProgress storage) { + CurseVoteProgress storage sptr_curseVoteProgress = s_potentiallyOutdatedCurseVoteProgressBySubject[subject]; + if (configVersion != sptr_curseVoteProgress.configVersion) { + sptr_curseVoteProgress.configVersion = configVersion; + sptr_curseVoteProgress.curseWeightThreshold = s_versionedConfig.config.curseWeightThreshold; + sptr_curseVoteProgress.accumulatedWeight = 0; + + if (sptr_curseVoteProgress.curseActive) { + // If a curse was active, count past votes to curse and retain the curses hash for cursers who are part of the + // new config. + Config storage sptr_config = s_versionedConfig.config; + for (uint256 i = 0; i < sptr_config.voters.length; ++i) { + Voter storage sptr_voter = sptr_config.voters[i]; + ConfigVersionAndCursesHash storage sptr_cvch = + sptr_curseVoteProgress.latestVoteToCurseByCurseVoteAddr[sptr_voter.curseVoteAddr]; + if (sptr_cvch.configVersion < configVersion && sptr_cvch.cursesHash != NO_VOTES_CURSES_HASH) { + // `< configVersion` instead of `== configVersion-1`, because there might have been multiple config changes + // without a lazy update of our subject. This has the side effect of retaining votes from very old configs + // that we might not really intend to retain, but these can be removed by the owner later. + sptr_cvch.configVersion = configVersion; + sptr_curseVoteProgress.accumulatedWeight += sptr_voter.curseWeight; + } + } + // We don't need to think about OWNER_CURSE_VOTE_ADDR here, because its ConfigVersionAndCursesHash counts even + // if the configVersion is not the current config version, in contrast to regular voters. + // It's an irregularity, but it saves us > 5k gas (if the owner had previously voted) for the unlucky voter who + // enters this branch. + } else { + // If a curse was not active, we don't count past votes to curse for voters who are part of the new config. + // Their curses hash will be restart from NO_VOTES_CURSES_HASH when they vote to curse again. + // We expect that the offchain code will revote to curse in case it voted to curse, and the vote to curse was + // lost due to any reason, including a config change when the curse was not yet active. + } + } + return sptr_curseVoteProgress; + } + + // EVENTS, ERRORS + + event ConfigSet(uint32 indexed configVersion, Config config); + + error InvalidConfig(); + + event TaggedRootBlessed(uint32 indexed configVersion, IRMN.TaggedRoot taggedRoot, uint16 accumulatedWeight); + event TaggedRootBlessVotesReset(uint32 indexed configVersion, IRMN.TaggedRoot taggedRoot, bool wasBlessed); + event VotedToBless(uint32 indexed configVersion, address indexed voter, IRMN.TaggedRoot taggedRoot, uint8 weight); + + event VotedToCurse( + uint32 indexed configVersion, + address indexed voter, + bytes16 subject, + bytes16 curseId, + uint8 weight, + uint64 blockTimestamp, + bytes28 cursesHash, + uint16 accumulatedWeight + ); + event UnvotedToCurse( + uint32 indexed configVersion, + address indexed voter, + bytes16 subject, + uint8 weight, + bytes28 cursesHash, + uint16 remainingAccumulatedWeight + ); + event SkippedUnvoteToCurse(address indexed voter, bytes16 subject, bytes28 onchainCursesHash, bytes28 cursesHash); + event Cursed(uint32 indexed configVersion, bytes16 subject, uint64 blockTimestamp); + event CurseLifted(bytes16 subject); + + // These events make it easier for offchain logic to discover that it performs + // the same actions multiple times. + event AlreadyVotedToBless(uint32 indexed configVersion, address indexed voter, IRMN.TaggedRoot taggedRoot); + event AlreadyBlessed(uint32 indexed configVersion, address indexed voter, IRMN.TaggedRoot taggedRoot); + + // Emitted by ownerRemoveThenAddPermaBlessedCommitStores. + event PermaBlessedCommitStoreAdded(address commitStore); + event PermaBlessedCommitStoreRemoved(address commitStore); + + error ReusedCurseId(address voter, bytes16 curseId); + error UnauthorizedVoter(address voter); + error VoteToBlessNoop(); + error VoteToCurseNoop(); + error UnvoteToCurseNoop(); + error VoteToBlessForbiddenDuringActiveGlobalCurse(); + + /// @notice Thrown when subjects are not a strictly increasing monotone sequence. + // Prevents a subject from receiving multiple votes to curse with the same curse id. + error SubjectsMustBeStrictlyIncreasing(); + + constructor(Config memory config) { + { + // Ensure that the bitmap is large enough to hold MAX_NUM_VOTERS. + // We do this in the constructor because MAX_NUM_VOTERS is constant. + BlessVoteProgress memory vp = BlessVoteProgress({ + configVersion: 0, + voterBitmap: type(uint200).max, // will not compile if it doesn't fit + accumulatedWeight: 0, + weightThresholdMet: false + }); + assert(vp.voterBitmap >> (MAX_NUM_VOTERS - 1) >= 1); + } + _setConfig(config); + } + + function _bitmapGet(uint200 bitmap, uint8 index) internal pure returns (bool) { + assert(index < MAX_NUM_VOTERS); + return bitmap & (uint200(1) << index) != 0; + } + + function _bitmapSet(uint200 bitmap, uint8 index) internal pure returns (uint200) { + assert(index < MAX_NUM_VOTERS); + return bitmap | (uint200(1) << index); + } + + function _bitmapCount(uint200 bitmap) internal pure returns (uint8 oneBits) { + assert(bitmap < 1 << MAX_NUM_VOTERS); + // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan + for (; bitmap != 0; ++oneBits) { + bitmap &= bitmap - 1; + } + } + + function _taggedRootHash(IRMN.TaggedRoot memory taggedRoot) internal pure returns (bytes32) { + return keccak256(abi.encode(taggedRoot.commitStore, taggedRoot.root)); + } + + function _cursesHash(bytes28 prevCursesHash, bytes16 curseId) internal pure returns (bytes28) { + return bytes28(keccak256(abi.encode(prevCursesHash, curseId))); + } + + function _blockTimestamp() internal view returns (uint64) { + return uint64(block.timestamp); + } + + /// @param taggedRoots A tagged root is hashed as `keccak256(abi.encode(taggedRoot.commitStore + /// /* address */, taggedRoot.root /* bytes32 */))`. + /// @notice Tagged roots which are already (voted to be) blessed are skipped and emit corresponding events. In case + /// the call has no effect, i.e., all passed tagged roots are skipped, the function reverts with a `VoteToBlessNoop`. + function voteToBless(IRMN.TaggedRoot[] calldata taggedRoots) external { + // If we have an active global curse, something is really wrong. Let's err on the + // side of caution and not accept further blessings during this time of + // uncertainty. + if (isCursed(GLOBAL_CURSE_SUBJECT)) revert VoteToBlessForbiddenDuringActiveGlobalCurse(); + + uint32 configVersion = s_versionedConfig.configVersion; + BlesserRecord memory blesserRecord = s_blesserRecords[msg.sender]; + if (blesserRecord.configVersion != configVersion) revert UnauthorizedVoter(msg.sender); + + bool noop = true; + for (uint256 i = 0; i < taggedRoots.length; ++i) { + IRMN.TaggedRoot memory taggedRoot = taggedRoots[i]; + bytes32 taggedRootHash = _taggedRootHash(taggedRoot); + BlessVoteProgress memory voteProgress = s_blessVoteProgressByTaggedRootHash[taggedRootHash]; + if (voteProgress.weightThresholdMet) { + // We don't revert here because it's unreasonable to expect from the + // voter to know exactly when to stop voting. Most likely when they + // voted they didn't realize the threshold would be reached by the time + // their vote was counted. + // Additionally, there might be other tagged roots for which votes might + // count, and we want to allow that to happen. + emit AlreadyBlessed(configVersion, msg.sender, taggedRoot); + continue; + } else if (voteProgress.configVersion != configVersion) { + // Note that voteProgress.weightThresholdMet must be false at this point + + // If votes were received while an older config was in effect, + // invalidate them and start from scratch. + // If votes were never received, set the current config version. + voteProgress = BlessVoteProgress({ + configVersion: configVersion, + voterBitmap: 0, + accumulatedWeight: 0, + weightThresholdMet: false + }); + } else if (_bitmapGet(voteProgress.voterBitmap, blesserRecord.index)) { + // We don't revert here because there might be other tagged roots for + // which votes might count, and we want to allow that to happen. + emit AlreadyVotedToBless(configVersion, msg.sender, taggedRoot); + continue; + } + noop = false; + voteProgress.voterBitmap = _bitmapSet(voteProgress.voterBitmap, blesserRecord.index); + voteProgress.accumulatedWeight += blesserRecord.weight; + emit VotedToBless(configVersion, msg.sender, taggedRoot, blesserRecord.weight); + if (voteProgress.accumulatedWeight >= s_versionedConfig.config.blessWeightThreshold) { + voteProgress.weightThresholdMet = true; + emit TaggedRootBlessed(configVersion, taggedRoot, voteProgress.accumulatedWeight); + } + s_blessVoteProgressByTaggedRootHash[taggedRootHash] = voteProgress; + } + + if (noop) { + revert VoteToBlessNoop(); + } + } + + /// @notice Can be called by the owner to remove unintentionally voted or even blessed tagged roots in a recovery + /// scenario. The owner must ensure that there are no in-flight transactions by RMN nodes voting for any of the + /// taggedRoots before calling this function, as such in-flight transactions could lead to the roots becoming + /// re-blessed shortly after the call to this function, contrary to the original intention. + function ownerResetBlessVotes(IRMN.TaggedRoot[] calldata taggedRoots) external onlyOwner { + uint32 configVersion = s_versionedConfig.configVersion; + for (uint256 i = 0; i < taggedRoots.length; ++i) { + IRMN.TaggedRoot memory taggedRoot = taggedRoots[i]; + bytes32 taggedRootHash = _taggedRootHash(taggedRoot); + BlessVoteProgress memory voteProgress = s_blessVoteProgressByTaggedRootHash[taggedRootHash]; + delete s_blessVoteProgressByTaggedRootHash[taggedRootHash]; + bool wasBlessed = voteProgress.weightThresholdMet; + if (voteProgress.configVersion == configVersion || wasBlessed) { + emit TaggedRootBlessVotesReset(configVersion, taggedRoot, wasBlessed); + } + } + } + + struct UnvoteToCurseRequest { + bytes16 subject; + bytes28 cursesHash; + } + + // For use in internal calls. + enum Privilege { + Owner, + Voter + } + + function _authorizedUnvoteToCurse( + Privilege priv, // Privilege.Owner during an ownerUnvoteToCurse call, Privilege.Voter during a unvoteToCurse call + uint32 configVersion, + address curseVoteAddr, + UnvoteToCurseRequest memory req, + bool forceUnvote, // true only during an ownerUnvoteToCurse call, when OwnerUnvoteToCurseRequest.forceUnvote is true + CurserRecord storage sptr_curserRecord, + CurseVoteProgress storage sptr_curseVoteProgress + ) internal returns (bool unvoted, bool curseLifted) { + { + assert(priv == Privilege.Voter || priv == Privilege.Owner); // sanity check + // Check that the supplied arguments are feasible for our privilege. + if (forceUnvote || curseVoteAddr == OWNER_CURSE_VOTE_ADDR || curseVoteAddr == LIFT_CURSE_VOTE_ADDR) { + assert(priv == Privilege.Owner); + } + } + + ConfigVersionAndCursesHash memory cvch = sptr_curseVoteProgress.latestVoteToCurseByCurseVoteAddr[curseVoteAddr]; + + // First, try to unvote. + if ( + sptr_curserRecord.active && (curseVoteAddr == OWNER_CURSE_VOTE_ADDR || cvch.configVersion == configVersion) + && cvch.cursesHash != NO_VOTES_CURSES_HASH && (cvch.cursesHash == req.cursesHash || forceUnvote) + ) { + unvoted = true; + delete sptr_curseVoteProgress.latestVoteToCurseByCurseVoteAddr[curseVoteAddr]; + // Assumes: s_curserRecords[OWNER_CURSE_VOTE_ADDR].weight == 0, enforced by _setConfig + sptr_curseVoteProgress.accumulatedWeight -= sptr_curserRecord.weight; + + emit UnvotedToCurse( + configVersion, + curseVoteAddr, + req.subject, + sptr_curserRecord.weight, + req.cursesHash, + sptr_curseVoteProgress.accumulatedWeight + ); + } + + // If we have owner privilege, and the conditions for the curse to be active no longer hold, we are able to lift the + // curse. + bool shouldTryToLiftCurse = priv == Privilege.Owner && (unvoted || curseVoteAddr == LIFT_CURSE_VOTE_ADDR); + + if (shouldTryToLiftCurse && sptr_curseVoteProgress.curseActive && !_shouldCurseBeActive(sptr_curseVoteProgress)) { + curseLifted = true; + sptr_curseVoteProgress.curseActive = false; + --s_curseHotVars.numSubjectsCursed; + emit CurseLifted(req.subject); + } + + if (unvoted || curseLifted) { + RecordedCurseRelatedOpTag tag; + if (priv == Privilege.Owner) { + if (forceUnvote) { + tag = RecordedCurseRelatedOpTag.OwnerUnvoteToCurseForced; + } else { + tag = RecordedCurseRelatedOpTag.OwnerUnvoteToCurseUnforced; + } + } else if (priv == Privilege.Voter) { + tag = RecordedCurseRelatedOpTag.UnvoteToCurse; + } else { + // solhint-disable-next-line gas-custom-errors, reason-string + revert(); // assumption violation + } + s_recordedCurseRelatedOps.push( + RecordedCurseRelatedOp({ + tag: tag, + cursed: sptr_curseVoteProgress.curseActive, + curseVoteAddr: curseVoteAddr, + curseId: bytes16(0), + subject: req.subject, + blockTimestamp: _blockTimestamp() + }) + ); + } else { + emit SkippedUnvoteToCurse(curseVoteAddr, req.subject, cvch.cursesHash, req.cursesHash); + } + } + + /// @notice Can be called by a curser to remove unintentional votes to curse. + /// We expect this to be called very rarely, e.g. in case of a bug in the + /// offchain code causing false voteToCurse calls. + /// @notice Should be called from curser's corresponding curseVoteAddr. + function unvoteToCurse(UnvoteToCurseRequest[] memory unvoteToCurseRequests) external { + address curseVoteAddr = msg.sender; + CurserRecord storage sptr_curserRecord = s_curserRecords[curseVoteAddr]; + + if (!sptr_curserRecord.active) revert UnauthorizedVoter(curseVoteAddr); + + uint32 configVersion = s_versionedConfig.configVersion; + bool anyVoteWasUnvoted = false; + for (uint256 i = 0; i < unvoteToCurseRequests.length; ++i) { + UnvoteToCurseRequest memory req = unvoteToCurseRequests[i]; + CurseVoteProgress storage sptr_curseVoteProgress = _getUpToDateCurseVoteProgress(configVersion, req.subject); + (bool unvoted, bool curseLifted) = _authorizedUnvoteToCurse( + Privilege.Voter, configVersion, curseVoteAddr, req, false, sptr_curserRecord, sptr_curseVoteProgress + ); + assert(!curseLifted); // assumption violation: voters can't lift curses + anyVoteWasUnvoted = anyVoteWasUnvoted || unvoted; + } + + if (!anyVoteWasUnvoted) { + revert UnvoteToCurseNoop(); + } + } + + /// @notice A vote to curse is appropriate during unhealthy blockchain conditions + /// (eg. finality violations). + function voteToCurse(bytes16 curseId, bytes16[] memory subjects) external { + address curseVoteAddr = msg.sender; + assert(curseVoteAddr != OWNER_CURSE_VOTE_ADDR); + CurserRecord storage sptr_curserRecord = s_curserRecords[curseVoteAddr]; + if (!sptr_curserRecord.active) revert UnauthorizedVoter(curseVoteAddr); + _authorizedVoteToCurse(curseVoteAddr, curseId, subjects, sptr_curserRecord); + } + + function _authorizedVoteToCurse( + address curseVoteAddr, + bytes16 curseId, + bytes16[] memory subjects, + CurserRecord storage sptr_curserRecord + ) internal { + if (subjects.length == 0) revert VoteToCurseNoop(); + + if (sptr_curserRecord.usedCurseIds[curseId]) revert ReusedCurseId(curseVoteAddr, curseId); + sptr_curserRecord.usedCurseIds[curseId] = true; + + // NOTE: We could pack configVersion into CurserRecord that we already load in the beginning of this function to + // avoid the following extra storage read for it, but since voteToCurse is not on the hot path we'd rather keep + // things simple. + uint32 configVersion = s_versionedConfig.configVersion; + for (uint256 i = 0; i < subjects.length; ++i) { + if (i >= 1 && !(subjects[i - 1] < subjects[i])) { + // Prevents a subject from receiving multiple votes to curse with the same curse id. + revert SubjectsMustBeStrictlyIncreasing(); + } + + bytes16 subject = subjects[i]; + CurseVoteProgress storage sptr_curseVoteProgress = _getUpToDateCurseVoteProgress(configVersion, subject); + ConfigVersionAndCursesHash memory cvch = sptr_curseVoteProgress.latestVoteToCurseByCurseVoteAddr[curseVoteAddr]; + bytes28 prevCursesHash; + if ( + (curseVoteAddr != OWNER_CURSE_VOTE_ADDR && cvch.configVersion < configVersion) + || cvch.cursesHash == NO_VOTES_CURSES_HASH + ) { + // if owner's first vote, or if voter's first vote in this config version + prevCursesHash = NO_VOTES_CURSES_HASH; // start hashchain from scratch, explicit + sptr_curseVoteProgress.accumulatedWeight += sptr_curserRecord.weight; + } else { + // we've already accounted for the weight + prevCursesHash = cvch.cursesHash; + } + sptr_curseVoteProgress.latestVoteToCurseByCurseVoteAddr[curseVoteAddr] = cvch = + ConfigVersionAndCursesHash({configVersion: configVersion, cursesHash: _cursesHash(prevCursesHash, curseId)}); + emit VotedToCurse( + configVersion, + curseVoteAddr, + subject, + curseId, + sptr_curserRecord.weight, + _blockTimestamp(), + cvch.cursesHash, + sptr_curseVoteProgress.accumulatedWeight + ); + + if ( + prevCursesHash == NO_VOTES_CURSES_HASH && !sptr_curseVoteProgress.curseActive + && _shouldCurseBeActive(sptr_curseVoteProgress) + ) { + sptr_curseVoteProgress.curseActive = true; + ++s_curseHotVars.numSubjectsCursed; + emit Cursed(configVersion, subject, _blockTimestamp()); + } + + s_recordedCurseRelatedOps.push( + RecordedCurseRelatedOp({ + tag: RecordedCurseRelatedOpTag.VoteToCurse, + cursed: sptr_curseVoteProgress.curseActive, + curseVoteAddr: curseVoteAddr, + curseId: curseId, + subject: subject, + blockTimestamp: _blockTimestamp() + }) + ); + } + } + + /// @notice Enables the owner to immediately have the system enter the cursed state. + function ownerCurse(bytes16 curseId, bytes16[] memory subjects) external onlyOwner { + address curseVoteAddr = OWNER_CURSE_VOTE_ADDR; + CurserRecord storage sptr_curserRecord = s_curserRecords[curseVoteAddr]; + // no need to check if sptr_curserRecord.active, we must have the onlyOwner modifier + _authorizedVoteToCurse(curseVoteAddr, curseId, subjects, sptr_curserRecord); + } + + // Set curseVoteAddr=LIFT_CURSE_VOTE_ADDR, cursesHash=bytes28(0), to reset curseActive if it can be reset. Useful if + // all voters have unvoted to curse on their own and the curse can now be lifted without any individual votes that can + // be unvoted. + // solhint-disable-next-line gas-struct-packing + struct OwnerUnvoteToCurseRequest { + address curseVoteAddr; + UnvoteToCurseRequest unit; + bool forceUnvote; + } + + /// @notice Enables the owner to remove curse votes. After the curse votes are removed, + /// this function will check whether the curse is still valid and restore the uncursed state if possible. + /// This function also enables the owner to lift a curse created through ownerCurse. + function ownerUnvoteToCurse(OwnerUnvoteToCurseRequest[] memory ownerUnvoteToCurseRequests) external onlyOwner { + bool anyCurseWasLifted = false; + bool anyVoteWasUnvoted = false; + uint32 configVersion = s_versionedConfig.configVersion; + for (uint256 i = 0; i < ownerUnvoteToCurseRequests.length; ++i) { + OwnerUnvoteToCurseRequest memory req = ownerUnvoteToCurseRequests[i]; + CurseVoteProgress storage sptr_curseVoteProgress = _getUpToDateCurseVoteProgress(configVersion, req.unit.subject); + (bool unvoted, bool curseLifted) = _authorizedUnvoteToCurse( + Privilege.Owner, + configVersion, + req.curseVoteAddr, + req.unit, + req.forceUnvote, + s_curserRecords[req.curseVoteAddr], + sptr_curseVoteProgress + ); + anyVoteWasUnvoted = anyVoteWasUnvoted || unvoted; + anyCurseWasLifted = anyCurseWasLifted || curseLifted; + } + + if (anyCurseWasLifted) { + // Invalidate all in-progress votes to bless or curse by bumping the config version. + // They might have been based on false information about the source chain + // (e.g. in case of a finality violation). + _setConfig(s_versionedConfig.config); + } + + if (!(anyVoteWasUnvoted || anyCurseWasLifted)) { + revert UnvoteToCurseNoop(); + } + } + + function setConfig(Config memory config) external onlyOwner { + _setConfig(config); + } + + /// @notice Any tagged root with a commit store included in this array will be considered automatically blessed. + function getPermaBlessedCommitStores() external view returns (address[] memory) { + return s_permaBlessedCommitStores.values(); + } + + /// @notice The ordering of parameters is important. First come the commit stores to remove, then the commit stores to + /// add. + function ownerRemoveThenAddPermaBlessedCommitStores( + address[] memory removes, + address[] memory adds + ) external onlyOwner { + for (uint256 i = 0; i < removes.length; ++i) { + if (s_permaBlessedCommitStores.remove(removes[i])) { + emit PermaBlessedCommitStoreRemoved(removes[i]); + } + } + for (uint256 i = 0; i < adds.length; ++i) { + if (s_permaBlessedCommitStores.add(adds[i])) { + emit PermaBlessedCommitStoreAdded(adds[i]); + } + } + } + + /// @inheritdoc IRMN + function isBlessed(IRMN.TaggedRoot calldata taggedRoot) external view returns (bool) { + return s_blessVoteProgressByTaggedRootHash[_taggedRootHash(taggedRoot)].weightThresholdMet + || s_permaBlessedCommitStores.contains(taggedRoot.commitStore); + } + + /// @inheritdoc IRMN + function isCursed() external view returns (bool) { + if (s_curseHotVars.numSubjectsCursed == 0) { + return false; // happy path costs a single SLOAD + } else { + return s_potentiallyOutdatedCurseVoteProgressBySubject[GLOBAL_CURSE_SUBJECT].curseActive + || s_potentiallyOutdatedCurseVoteProgressBySubject[LEGACY_CURSE_SUBJECT].curseActive; + } + } + + /// @inheritdoc IRMN + function isCursed(bytes16 subject) public view returns (bool) { + if (s_curseHotVars.numSubjectsCursed == 0) { + return false; // happy path costs a single SLOAD + } else { + return s_potentiallyOutdatedCurseVoteProgressBySubject[GLOBAL_CURSE_SUBJECT].curseActive + || s_potentiallyOutdatedCurseVoteProgressBySubject[subject].curseActive; + } + } + + /// @notice Config version might be incremented for many reasons, including + /// the lifting of a curse, or a regular config change. + function getConfigDetails() external view returns (uint32 version, uint32 blockNumber, Config memory config) { + version = s_versionedConfig.configVersion; + blockNumber = s_versionedConfig.blockNumber; + config = s_versionedConfig.config; + } + + /// @return blessVoteAddrs addresses of voters, will be empty if voting took place with an older config version + /// @return accumulatedWeight sum of weights of voters, will be zero if voting took place with an older config version + /// @return blessed will be accurate regardless of when voting took place + /// @dev This is a helper method for offchain code so efficiency is not really a concern. + function getBlessProgress(IRMN.TaggedRoot calldata taggedRoot) + external + view + returns (address[] memory blessVoteAddrs, uint16 accumulatedWeight, bool blessed) + { + bytes32 taggedRootHash = _taggedRootHash(taggedRoot); + BlessVoteProgress memory progress = s_blessVoteProgressByTaggedRootHash[taggedRootHash]; + blessed = progress.weightThresholdMet; + if (progress.configVersion == s_versionedConfig.configVersion) { + accumulatedWeight = progress.accumulatedWeight; + uint200 bitmap = progress.voterBitmap; + blessVoteAddrs = new address[](_bitmapCount(bitmap)); + Voter[] memory voters = s_versionedConfig.config.voters; + uint256 j = 0; + for (uint8 i = 0; i < voters.length; ++i) { + if (_bitmapGet(bitmap, i)) { + blessVoteAddrs[j] = voters[i].blessVoteAddr; + ++j; + } + } + } + } + + /// @return curseVoteAddrs the curseVoteAddr of each voter with an active vote to curse + /// @return cursesHashes the i-th value is the curses hash of curseVoteAddrs[i] + /// @return accumulatedWeight the accumulated weight of all voters with an active vote to curse who are part of the + /// current config + /// @return cursed might be true even if the owner has no active vote and accumulatedWeight < curseWeightThreshold, + /// due to a retained curse from a prior config + /// @dev This is a helper method for offchain code so efficiency is not really a concern. + function getCurseProgress(bytes16 subject) + external + view + returns (address[] memory curseVoteAddrs, bytes28[] memory cursesHashes, uint16 accumulatedWeight, bool cursed) + { + uint32 configVersion = s_versionedConfig.configVersion; + Config memory config = s_versionedConfig.config; + // Can't use _getUpToDateCurseVoteProgress here because we can't call a non-view function from within a view. + // So we get to repeat some accounting. + CurseVoteProgress storage outdatedCurseVoteProgress = s_potentiallyOutdatedCurseVoteProgressBySubject[subject]; + + cursed = outdatedCurseVoteProgress.curseActive; + + // See _getUpToDateCurseVoteProgress for more context. + bool shouldCountVotesFromOlderConfigs = outdatedCurseVoteProgress.configVersion < configVersion && cursed; + + // A play in two acts, because we can't push to arrays in memory, so we need to precompute the array's length. + // First act: we count the number of cursers, i.e., voters with active vote. + // Second act: push the cursers to the arrays, sum their weights. + + uint256 numCursers = 0; // we reuse this variable for writing to perserve stack space + accumulatedWeight = 0; + for (uint256 act = 1; act <= 2; ++act) { + uint256 i = config.voters.length; // not config.voters.length-1 to account for the owner + while (true) { + address curseVoteAddr; + uint8 weight; + if (i < config.voters.length) { + curseVoteAddr = config.voters[i].curseVoteAddr; + weight = config.voters[i].curseWeight; + } else { + // Allows us to include the owner's vote and curses hash in the result. + curseVoteAddr = OWNER_CURSE_VOTE_ADDR; + weight = 0; + } + + ConfigVersionAndCursesHash memory cvch = + outdatedCurseVoteProgress.latestVoteToCurseByCurseVoteAddr[curseVoteAddr]; + bool hasActiveVote = ( + shouldCountVotesFromOlderConfigs || cvch.configVersion == configVersion + || curseVoteAddr == OWNER_CURSE_VOTE_ADDR + ) && cvch.cursesHash != NO_VOTES_CURSES_HASH; + if (hasActiveVote) { + if (act == 1) { + ++numCursers; + } else if (act == 2) { + accumulatedWeight += weight; + --numCursers; + curseVoteAddrs[numCursers] = curseVoteAddr; + cursesHashes[numCursers] = cvch.cursesHash; + } else { + // solhint-disable-next-line gas-custom-errors, reason-string + revert(); // assumption violation + } + } + + if (i > 0) { + --i; + } else { + break; + } + } + + if (act == 1) { + // We are done counting at this point, initialize the arrays for the second act that follows immediately after. + curseVoteAddrs = new address[](numCursers); + cursesHashes = new bytes28[](numCursers); + } + } + } + + /// @notice Returns the number of subjects that are currently cursed. + function getCursedSubjectsCount() external view returns (uint256) { + return s_curseHotVars.numSubjectsCursed; + } + + /// @dev This is a helper method for offchain code to know what arguments to use for getRecordedCurseRelatedOps. + function getRecordedCurseRelatedOpsCount() external view returns (uint256) { + return s_recordedCurseRelatedOps.length; + } + + /// @dev This is a helper method for offchain code so efficiency is not really a concern. + /// @dev Returns s_recordedCurseRelatedOps[offset:offset+limit]. + function getRecordedCurseRelatedOps( + uint256 offset, + uint256 limit + ) external view returns (RecordedCurseRelatedOp[] memory) { + uint256 pageLen; + if (offset + limit <= s_recordedCurseRelatedOps.length) { + pageLen = limit; + } else if (offset < s_recordedCurseRelatedOps.length) { + pageLen = s_recordedCurseRelatedOps.length - offset; + } else { + pageLen = 0; + } + RecordedCurseRelatedOp[] memory page = new RecordedCurseRelatedOp[](pageLen); + for (uint256 i = 0; i < pageLen; ++i) { + page[i] = s_recordedCurseRelatedOps[offset + i]; + } + return page; + } + + function _validateConfig(Config memory config) internal pure returns (bool) { + if ( + config.voters.length == 0 || config.voters.length > MAX_NUM_VOTERS || config.blessWeightThreshold == 0 + || config.curseWeightThreshold == 0 + ) { + return false; + } + + uint256 totalBlessWeight = 0; + uint256 totalCurseWeight = 0; + address[] memory allAddrs = new address[](2 * config.voters.length); + for (uint256 i = 0; i < config.voters.length; ++i) { + Voter memory voter = config.voters[i]; + // The owner can always curse using the ownerCurse method, and is not supposed to be included in the voters list. + // Even though the intent is for the actual owner address to NOT be included in the voters list, we don't + // explicitly disallow curseVoteAddr == owner() here. Even if we did, the owner could transfer ownership of the + // contract, and so we couldn't guarantee that the owner is not eventually included in the voters list. + if ( + voter.blessVoteAddr == address(0) || voter.curseVoteAddr == address(0) + || voter.curseVoteAddr == LIFT_CURSE_VOTE_ADDR || voter.curseVoteAddr == OWNER_CURSE_VOTE_ADDR + || (voter.blessWeight == 0 && voter.curseWeight == 0) + ) { + return false; + } + allAddrs[2 * i + 0] = voter.blessVoteAddr; + allAddrs[2 * i + 1] = voter.curseVoteAddr; + totalBlessWeight += voter.blessWeight; + totalCurseWeight += voter.curseWeight; + } + for (uint256 i = 0; i < allAddrs.length; ++i) { + address allAddrs_i = allAddrs[i]; + for (uint256 j = i + 1; j < allAddrs.length; ++j) { + if (allAddrs_i == allAddrs[j]) { + return false; + } + } + } + + return totalBlessWeight >= config.blessWeightThreshold && totalCurseWeight >= config.curseWeightThreshold; + } + + function _setConfig(Config memory config) private { + if (!_validateConfig(config)) revert InvalidConfig(); + + // We can't directly assign s_versionedConfig.config to config + // because copying a memory array into storage is not supported. + { + s_versionedConfig.config.blessWeightThreshold = config.blessWeightThreshold; + s_versionedConfig.config.curseWeightThreshold = config.curseWeightThreshold; + while (s_versionedConfig.config.voters.length != 0) { + Voter memory voter = s_versionedConfig.config.voters[s_versionedConfig.config.voters.length - 1]; + delete s_blesserRecords[voter.blessVoteAddr]; + delete s_curserRecords[voter.curseVoteAddr]; // usedCurseIds mapping is retained, as intended + s_versionedConfig.config.voters.pop(); + } + for (uint256 i = 0; i < config.voters.length; ++i) { + s_versionedConfig.config.voters.push(config.voters[i]); + } + } + + ++s_versionedConfig.configVersion; + uint32 configVersion = s_versionedConfig.configVersion; + + for (uint8 i = 0; i < config.voters.length; ++i) { + Voter memory voter = config.voters[i]; + s_blesserRecords[voter.blessVoteAddr] = + BlesserRecord({configVersion: configVersion, index: i, weight: voter.blessWeight}); + { + CurserRecord storage sptr_curserRecord = s_curserRecords[voter.curseVoteAddr]; + // Solidity will not let us initialize as CurserRecord({...}) due to the nested mapping + sptr_curserRecord.active = true; + sptr_curserRecord.weight = voter.curseWeight; + } + } + { + // Initialize the owner's CurserRecord + // We could in principle perform this initialization once in the constructor instead, and save a small bit of gas. + // But configuration changes are relatively infrequent, and keeping the initialization here makes the contract's + // correctness easier to reason about. + CurserRecord storage sptr_ownerCurserRecord = s_curserRecords[OWNER_CURSE_VOTE_ADDR]; + sptr_ownerCurserRecord.active = true; // Assumed by vote/unvote-to-curse logic + sptr_ownerCurserRecord.weight = 0; // Assumed by vote/unvote-to-curse logic + } + s_versionedConfig.blockNumber = uint32(block.number); + emit ConfigSet(configVersion, config); + + s_recordedCurseRelatedOps.push( + RecordedCurseRelatedOp({ + tag: RecordedCurseRelatedOpTag.SetConfig, + blockTimestamp: _blockTimestamp(), + cursed: false, + curseVoteAddr: address(0), + curseId: bytes16(0), + subject: bytes16(0) + }) + ); + } +} diff --git a/contracts/src/v0.8/ccip/Router.sol b/contracts/src/v0.8/ccip/Router.sol new file mode 100644 index 0000000000..e50651bc5b --- /dev/null +++ b/contracts/src/v0.8/ccip/Router.sol @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; +import {IAny2EVMMessageReceiver} from "./interfaces/IAny2EVMMessageReceiver.sol"; +import {IEVM2AnyOnRamp} from "./interfaces/IEVM2AnyOnRamp.sol"; +import {IRMN} from "./interfaces/IRMN.sol"; +import {IRouter} from "./interfaces/IRouter.sol"; +import {IRouterClient} from "./interfaces/IRouterClient.sol"; +import {IWrappedNative} from "./interfaces/IWrappedNative.sol"; + +import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol"; +import {CallWithExactGas} from "../shared/call/CallWithExactGas.sol"; +import {Client} from "./libraries/Client.sol"; +import {Internal} from "./libraries/Internal.sol"; + +import {IERC20} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {EnumerableSet} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +/// @title Router +/// @notice This is the entry point for the end user wishing to send data across chains. +/// @dev This contract is used as a router for both on-ramps and off-ramps +contract Router is IRouter, IRouterClient, ITypeAndVersion, OwnerIsCreator { + using SafeERC20 for IERC20; + using EnumerableSet for EnumerableSet.UintSet; + + error FailedToSendValue(); + error InvalidRecipientAddress(address to); + error OffRampMismatch(uint64 chainSelector, address offRamp); + error BadARMSignal(); + + event OnRampSet(uint64 indexed destChainSelector, address onRamp); + event OffRampAdded(uint64 indexed sourceChainSelector, address offRamp); + event OffRampRemoved(uint64 indexed sourceChainSelector, address offRamp); + event MessageExecuted(bytes32 messageId, uint64 sourceChainSelector, address offRamp, bytes32 calldataHash); + + struct OnRamp { + uint64 destChainSelector; + address onRamp; + } + + struct OffRamp { + uint64 sourceChainSelector; + address offRamp; + } + + string public constant override typeAndVersion = "Router 1.2.0"; + // We limit return data to a selector plus 4 words. This is to avoid + // malicious contracts from returning large amounts of data and causing + // repeated out-of-gas scenarios. + uint16 public constant MAX_RET_BYTES = 4 + 4 * 32; + // STATIC CONFIG + // Address of RMN proxy contract (formerly known as ARM) + address private immutable i_armProxy; + + // DYNAMIC CONFIG + address private s_wrappedNative; + // destChainSelector => onRamp address + // Only ever one onRamp enabled at a time for a given destChainSelector. + mapping(uint256 destChainSelector => address onRamp) private s_onRamps; + // Stores [sourceChainSelector << 160 + offramp] as a pair to allow for + // lookups for specific chain/offramp pairs. + EnumerableSet.UintSet private s_chainSelectorAndOffRamps; + + constructor(address wrappedNative, address armProxy) { + // Zero address indicates unsupported auto-wrapping, therefore, unsupported + // native fee token payments. + s_wrappedNative = wrappedNative; + i_armProxy = armProxy; + } + + // ================================================================ + // │ Message sending │ + // ================================================================ + + /// @inheritdoc IRouterClient + function getFee( + uint64 destinationChainSelector, + Client.EVM2AnyMessage memory message + ) external view returns (uint256 fee) { + if (message.feeToken == address(0)) { + // For empty feeToken return native quote. + message.feeToken = address(s_wrappedNative); + } + address onRamp = s_onRamps[destinationChainSelector]; + if (onRamp == address(0)) revert UnsupportedDestinationChain(destinationChainSelector); + return IEVM2AnyOnRamp(onRamp).getFee(destinationChainSelector, message); + } + + /// @notice This functionality has been removed and will revert when called. + function getSupportedTokens(uint64 chainSelector) external view returns (address[] memory) { + if (!isChainSupported(chainSelector)) { + return new address[](0); + } + return IEVM2AnyOnRamp(s_onRamps[uint256(chainSelector)]).getSupportedTokens(chainSelector); + } + + /// @inheritdoc IRouterClient + function isChainSupported(uint64 chainSelector) public view returns (bool) { + return s_onRamps[chainSelector] != address(0); + } + + /// @inheritdoc IRouterClient + function ccipSend( + uint64 destinationChainSelector, + Client.EVM2AnyMessage memory message + ) external payable whenNotCursed returns (bytes32) { + address onRamp = s_onRamps[destinationChainSelector]; + if (onRamp == address(0)) revert UnsupportedDestinationChain(destinationChainSelector); + uint256 feeTokenAmount; + // address(0) signals payment in true native + if (message.feeToken == address(0)) { + // for fee calculation we check the wrapped native price as we wrap + // as part of the native fee coin payment. + message.feeToken = s_wrappedNative; + // We rely on getFee to validate that the feeToken is whitelisted. + feeTokenAmount = IEVM2AnyOnRamp(onRamp).getFee(destinationChainSelector, message); + // Ensure sufficient native. + if (msg.value < feeTokenAmount) revert InsufficientFeeTokenAmount(); + // Wrap and send native payment. + // Note we take the whole msg.value regardless if its larger. + feeTokenAmount = msg.value; + IWrappedNative(message.feeToken).deposit{value: feeTokenAmount}(); + IERC20(message.feeToken).safeTransfer(onRamp, feeTokenAmount); + } else { + if (msg.value > 0) revert InvalidMsgValue(); + // We rely on getFee to validate that the feeToken is whitelisted. + feeTokenAmount = IEVM2AnyOnRamp(onRamp).getFee(destinationChainSelector, message); + IERC20(message.feeToken).safeTransferFrom(msg.sender, onRamp, feeTokenAmount); + } + + // Transfer the tokens to the token pools. + for (uint256 i = 0; i < message.tokenAmounts.length; ++i) { + IERC20 token = IERC20(message.tokenAmounts[i].token); + // We rely on getPoolBySourceToken to validate that the token is whitelisted. + token.safeTransferFrom( + msg.sender, + address(IEVM2AnyOnRamp(onRamp).getPoolBySourceToken(destinationChainSelector, token)), + message.tokenAmounts[i].amount + ); + } + + return IEVM2AnyOnRamp(onRamp).forwardFromRouter(destinationChainSelector, message, feeTokenAmount, msg.sender); + } + + // ================================================================ + // │ Message execution │ + // ================================================================ + + /// @inheritdoc IRouter + /// @dev _callWithExactGas protects against return data bombs by capping the return data size at MAX_RET_BYTES. + function routeMessage( + Client.Any2EVMMessage calldata message, + uint16 gasForCallExactCheck, + uint256 gasLimit, + address receiver + ) external override whenNotCursed returns (bool success, bytes memory retData, uint256 gasUsed) { + // We only permit offRamps to call this function. + if (!isOffRamp(message.sourceChainSelector, msg.sender)) revert OnlyOffRamp(); + + // We encode here instead of the offRamps to constrain specifically what functions + // can be called from the router. + bytes memory data = abi.encodeWithSelector(IAny2EVMMessageReceiver.ccipReceive.selector, message); + + (success, retData, gasUsed) = CallWithExactGas._callWithExactGasSafeReturnData( + data, receiver, gasLimit, gasForCallExactCheck, Internal.MAX_RET_BYTES + ); + + emit MessageExecuted(message.messageId, message.sourceChainSelector, msg.sender, keccak256(data)); + return (success, retData, gasUsed); + } + + // @notice Merges a chain selector and offRamp address into a single uint256 by shifting the + // chain selector 160 bits to the left. + function _mergeChainSelectorAndOffRamp( + uint64 sourceChainSelector, + address offRampAddress + ) internal pure returns (uint256) { + return (uint256(sourceChainSelector) << 160) + uint160(offRampAddress); + } + + // ================================================================ + // │ Config │ + // ================================================================ + + /// @notice Gets the wrapped representation of the native fee coin. + /// @return The address of the ERC20 wrapped native. + function getWrappedNative() external view returns (address) { + return s_wrappedNative; + } + + /// @notice Sets a new wrapped native token. + /// @param wrappedNative The address of the new wrapped native ERC20 token. + function setWrappedNative(address wrappedNative) external onlyOwner { + s_wrappedNative = wrappedNative; + } + + /// @notice Gets the RMN address, formerly known as ARM + /// @return The address of the RMN proxy contract, formerly known as ARM + function getArmProxy() external view returns (address) { + return i_armProxy; + } + + /// @inheritdoc IRouter + function getOnRamp(uint64 destChainSelector) external view returns (address) { + return s_onRamps[destChainSelector]; + } + + function getOffRamps() external view returns (OffRamp[] memory) { + uint256[] memory encodedOffRamps = s_chainSelectorAndOffRamps.values(); + OffRamp[] memory offRamps = new OffRamp[](encodedOffRamps.length); + for (uint256 i = 0; i < encodedOffRamps.length; ++i) { + uint256 encodedOffRamp = encodedOffRamps[i]; + offRamps[i] = + OffRamp({sourceChainSelector: uint64(encodedOffRamp >> 160), offRamp: address(uint160(encodedOffRamp))}); + } + return offRamps; + } + + /// @inheritdoc IRouter + function isOffRamp(uint64 sourceChainSelector, address offRamp) public view returns (bool) { + // We have to encode the sourceChainSelector and offRamp into a uint256 to use as a key in the set. + return s_chainSelectorAndOffRamps.contains(_mergeChainSelectorAndOffRamp(sourceChainSelector, offRamp)); + } + + /// @notice applyRampUpdates applies a set of ramp changes which provides + /// the ability to add new chains and upgrade ramps. + function applyRampUpdates( + OnRamp[] calldata onRampUpdates, + OffRamp[] calldata offRampRemoves, + OffRamp[] calldata offRampAdds + ) external onlyOwner { + // Apply egress updates. + // We permit zero address as way to disable egress. + for (uint256 i = 0; i < onRampUpdates.length; ++i) { + OnRamp memory onRampUpdate = onRampUpdates[i]; + s_onRamps[onRampUpdate.destChainSelector] = onRampUpdate.onRamp; + emit OnRampSet(onRampUpdate.destChainSelector, onRampUpdate.onRamp); + } + + // Apply ingress updates. + for (uint256 i = 0; i < offRampRemoves.length; ++i) { + uint64 sourceChainSelector = offRampRemoves[i].sourceChainSelector; + address offRampAddress = offRampRemoves[i].offRamp; + + // If the selector-offRamp pair does not exist, revert. + if (!s_chainSelectorAndOffRamps.remove(_mergeChainSelectorAndOffRamp(sourceChainSelector, offRampAddress))) { + revert OffRampMismatch(sourceChainSelector, offRampAddress); + } + + emit OffRampRemoved(sourceChainSelector, offRampAddress); + } + + for (uint256 i = 0; i < offRampAdds.length; ++i) { + uint64 sourceChainSelector = offRampAdds[i].sourceChainSelector; + address offRampAddress = offRampAdds[i].offRamp; + + if (s_chainSelectorAndOffRamps.add(_mergeChainSelectorAndOffRamp(sourceChainSelector, offRampAddress))) { + emit OffRampAdded(sourceChainSelector, offRampAddress); + } + } + } + + /// @notice Provides the ability for the owner to recover any tokens accidentally + /// sent to this contract. + /// @dev Must be onlyOwner to avoid malicious token contract calls. + /// @param tokenAddress ERC20-token to recover + /// @param to Destination address to send the tokens to. + function recoverTokens(address tokenAddress, address to, uint256 amount) external onlyOwner { + if (to == address(0)) revert InvalidRecipientAddress(to); + + if (tokenAddress == address(0)) { + (bool success,) = to.call{value: amount}(""); + if (!success) revert FailedToSendValue(); + return; + } + IERC20(tokenAddress).safeTransfer(to, amount); + } + + // ================================================================ + // │ Access │ + // ================================================================ + + /// @notice Ensure that the RMN has not cursed the network. + modifier whenNotCursed() { + if (IRMN(i_armProxy).isCursed()) revert BadARMSignal(); + _; + } +} diff --git a/contracts/src/v0.8/ccip/applications/CCIPClientExample.sol b/contracts/src/v0.8/ccip/applications/CCIPClientExample.sol new file mode 100644 index 0000000000..b105cf8b00 --- /dev/null +++ b/contracts/src/v0.8/ccip/applications/CCIPClientExample.sol @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IRouterClient} from "../interfaces/IRouterClient.sol"; + +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; +import {Client} from "../libraries/Client.sol"; +import {CCIPReceiver} from "./CCIPReceiver.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +// @notice Example of a client which supports EVM/non-EVM chains +// @dev If chain specific logic is required for different chain families (e.g. particular +// decoding the bytes sender for authorization checks), it may be required to point to a helper +// authorization contract unless all chain families are known up front. +// @dev If contract does not implement IAny2EVMMessageReceiver and IERC165, +// and tokens are sent to it, ccipReceive will not be called but tokens will be transferred. +// @dev If the client is upgradeable you have significantly more flexibility and +// can avoid storage based options like the below contract uses. However it's +// worth carefully considering how the trust assumptions of your client dapp will +// change if you introduce upgradeability. An immutable dapp building on top of CCIP +// like the example below will inherit the trust properties of CCIP (i.e. the oracle network). +// @dev The receiver's are encoded offchain and passed as direct arguments to permit supporting +// new chain family receivers (e.g. a Solana encoded receiver address) without upgrading. +contract CCIPClientExample is CCIPReceiver, OwnerIsCreator { + error InvalidChain(uint64 chainSelector); + + event MessageSent(bytes32 messageId); + event MessageReceived(bytes32 messageId); + + // Current feeToken + IERC20 public s_feeToken; + // Below is a simplistic example (same params for all messages) of using storage to allow for new options without + // upgrading the dapp. Note that extra args are chain family specific (e.g. gasLimit is EVM specific etc.). + // and will always be backwards compatible i.e. upgrades are opt-in. + // Offchain we can compute the V1 extraArgs: + // Client.EVMExtraArgsV1 memory extraArgs = Client.EVMExtraArgsV1({gasLimit: 300_000}); + // bytes memory encodedV1ExtraArgs = Client._argsToBytes(extraArgs); + // Then later compute V2 extraArgs, for example if a refund feature was added: + // Client.EVMExtraArgsV2 memory extraArgs = Client.EVMExtraArgsV2({gasLimit: 300_000, destRefundAddress: 0x1234}); + // bytes memory encodedV2ExtraArgs = Client._argsToBytes(extraArgs); + // and update storage with the new args. + // If different options are required for different messages, for example different gas limits, + // one can simply key based on (chainSelector, messageType) instead of only chainSelector. + mapping(uint64 destChainSelector => bytes extraArgsBytes) public s_chains; + + constructor(IRouterClient router, IERC20 feeToken) CCIPReceiver(address(router)) { + s_feeToken = feeToken; + s_feeToken.approve(address(router), type(uint256).max); + } + + function enableChain(uint64 chainSelector, bytes memory extraArgs) external onlyOwner { + s_chains[chainSelector] = extraArgs; + } + + function disableChain(uint64 chainSelector) external onlyOwner { + delete s_chains[chainSelector]; + } + + function ccipReceive(Client.Any2EVMMessage calldata message) + external + virtual + override + onlyRouter + validChain(message.sourceChainSelector) + { + // Extremely important to ensure only router calls this. + // Tokens in message if any will be transferred to this contract + // TODO: Validate sender/origin chain and process message and/or tokens. + _ccipReceive(message); + } + + function _ccipReceive(Client.Any2EVMMessage memory message) internal override { + emit MessageReceived(message.messageId); + } + + /// @notice sends data to receiver on dest chain. Assumes address(this) has sufficient native asset. + function sendDataPayNative( + uint64 destChainSelector, + bytes memory receiver, + bytes memory data + ) external validChain(destChainSelector) { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](0); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: receiver, + data: data, + tokenAmounts: tokenAmounts, + extraArgs: s_chains[destChainSelector], + feeToken: address(0) // We leave the feeToken empty indicating we'll pay raw native. + }); + bytes32 messageId = IRouterClient(i_ccipRouter).ccipSend{ + value: IRouterClient(i_ccipRouter).getFee(destChainSelector, message) + }(destChainSelector, message); + emit MessageSent(messageId); + } + + /// @notice sends data to receiver on dest chain. Assumes address(this) has sufficient feeToken. + function sendDataPayFeeToken( + uint64 destChainSelector, + bytes memory receiver, + bytes memory data + ) external validChain(destChainSelector) { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](0); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: receiver, + data: data, + tokenAmounts: tokenAmounts, + extraArgs: s_chains[destChainSelector], + feeToken: address(s_feeToken) + }); + // Optional uint256 fee = i_ccipRouter.getFee(destChainSelector, message); + // Can decide if fee is acceptable. + // address(this) must have sufficient feeToken or the send will revert. + bytes32 messageId = IRouterClient(i_ccipRouter).ccipSend(destChainSelector, message); + emit MessageSent(messageId); + } + + /// @notice sends data to receiver on dest chain. Assumes address(this) has sufficient native token. + function sendDataAndTokens( + uint64 destChainSelector, + bytes memory receiver, + bytes memory data, + Client.EVMTokenAmount[] memory tokenAmounts + ) external validChain(destChainSelector) { + for (uint256 i = 0; i < tokenAmounts.length; ++i) { + IERC20(tokenAmounts[i].token).transferFrom(msg.sender, address(this), tokenAmounts[i].amount); + IERC20(tokenAmounts[i].token).approve(i_ccipRouter, tokenAmounts[i].amount); + } + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: receiver, + data: data, + tokenAmounts: tokenAmounts, + extraArgs: s_chains[destChainSelector], + feeToken: address(s_feeToken) + }); + // Optional uint256 fee = i_ccipRouter.getFee(destChainSelector, message); + // Can decide if fee is acceptable. + // address(this) must have sufficient feeToken or the send will revert. + bytes32 messageId = IRouterClient(i_ccipRouter).ccipSend(destChainSelector, message); + emit MessageSent(messageId); + } + + // @notice user sends tokens to a receiver + // Approvals can be optimized with a whitelist of tokens and inf approvals if desired. + function sendTokens( + uint64 destChainSelector, + bytes memory receiver, + Client.EVMTokenAmount[] memory tokenAmounts + ) external validChain(destChainSelector) { + for (uint256 i = 0; i < tokenAmounts.length; ++i) { + IERC20(tokenAmounts[i].token).transferFrom(msg.sender, address(this), tokenAmounts[i].amount); + IERC20(tokenAmounts[i].token).approve(i_ccipRouter, tokenAmounts[i].amount); + } + bytes memory data; + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: receiver, + data: data, + tokenAmounts: tokenAmounts, + extraArgs: s_chains[destChainSelector], + feeToken: address(s_feeToken) + }); + // Optional uint256 fee = i_ccipRouter.getFee(destChainSelector, message); + // Can decide if fee is acceptable. + // address(this) must have sufficient feeToken or the send will revert. + bytes32 messageId = IRouterClient(i_ccipRouter).ccipSend(destChainSelector, message); + emit MessageSent(messageId); + } + + modifier validChain(uint64 chainSelector) { + if (s_chains[chainSelector].length == 0) revert InvalidChain(chainSelector); + _; + } +} diff --git a/contracts/src/v0.8/ccip/applications/CCIPReceiver.sol b/contracts/src/v0.8/ccip/applications/CCIPReceiver.sol new file mode 100644 index 0000000000..7011f814de --- /dev/null +++ b/contracts/src/v0.8/ccip/applications/CCIPReceiver.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IAny2EVMMessageReceiver} from "../interfaces/IAny2EVMMessageReceiver.sol"; + +import {Client} from "../libraries/Client.sol"; + +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; + +/// @title CCIPReceiver - Base contract for CCIP applications that can receive messages. +abstract contract CCIPReceiver is IAny2EVMMessageReceiver, IERC165 { + address internal immutable i_ccipRouter; + + constructor(address router) { + if (router == address(0)) revert InvalidRouter(address(0)); + i_ccipRouter = router; + } + + /// @notice IERC165 supports an interfaceId + /// @param interfaceId The interfaceId to check + /// @return true if the interfaceId is supported + /// @dev Should indicate whether the contract implements IAny2EVMMessageReceiver + /// e.g. return interfaceId == type(IAny2EVMMessageReceiver).interfaceId || interfaceId == type(IERC165).interfaceId + /// This allows CCIP to check if ccipReceive is available before calling it. + /// If this returns false or reverts, only tokens are transferred to the receiver. + /// If this returns true, tokens are transferred and ccipReceive is called atomically. + /// Additionally, if the receiver address does not have code associated with + /// it at the time of execution (EXTCODESIZE returns 0), only tokens will be transferred. + function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + return interfaceId == type(IAny2EVMMessageReceiver).interfaceId || interfaceId == type(IERC165).interfaceId; + } + + /// @inheritdoc IAny2EVMMessageReceiver + function ccipReceive(Client.Any2EVMMessage calldata message) external virtual override onlyRouter { + _ccipReceive(message); + } + + /// @notice Override this function in your implementation. + /// @param message Any2EVMMessage + function _ccipReceive(Client.Any2EVMMessage memory message) internal virtual; + + ///////////////////////////////////////////////////////////////////// + // Plumbing + ///////////////////////////////////////////////////////////////////// + + /// @notice Return the current router + /// @return CCIP router address + function getRouter() public view virtual returns (address) { + return address(i_ccipRouter); + } + + error InvalidRouter(address router); + + /// @dev only calls from the set router are accepted. + modifier onlyRouter() { + if (msg.sender != getRouter()) revert InvalidRouter(msg.sender); + _; + } +} diff --git a/contracts/src/v0.8/ccip/applications/DefensiveExample.sol b/contracts/src/v0.8/ccip/applications/DefensiveExample.sol new file mode 100644 index 0000000000..54e1e80946 --- /dev/null +++ b/contracts/src/v0.8/ccip/applications/DefensiveExample.sol @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IRouterClient} from "../interfaces/IRouterClient.sol"; + +import {Client} from "../libraries/Client.sol"; +import {CCIPClientExample} from "./CCIPClientExample.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {EnumerableMap} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableMap.sol"; + +contract DefensiveExample is CCIPClientExample { + using EnumerableMap for EnumerableMap.Bytes32ToUintMap; + using SafeERC20 for IERC20; + + error OnlySelf(); + error ErrorCase(); + error MessageNotFailed(bytes32 messageId); + + event MessageFailed(bytes32 indexed messageId, bytes reason); + event MessageSucceeded(bytes32 indexed messageId); + event MessageRecovered(bytes32 indexed messageId); + + // Example error code, could have many different error codes. + enum ErrorCode { + // RESOLVED is first so that the default value is resolved. + RESOLVED, + // Could have any number of error codes here. + BASIC + } + + // The message contents of failed messages are stored here. + mapping(bytes32 messageId => Client.Any2EVMMessage contents) public s_messageContents; + + // Contains failed messages and their state. + EnumerableMap.Bytes32ToUintMap internal s_failedMessages; + + // This is used to simulate a revert in the processMessage function. + bool internal s_simRevert = false; + + constructor(IRouterClient router, IERC20 feeToken) CCIPClientExample(router, feeToken) {} + + /// @notice The entrypoint for the CCIP router to call. This function should + /// never revert, all errors should be handled internally in this contract. + /// @param message The message to process. + /// @dev Extremely important to ensure only router calls this. + function ccipReceive(Client.Any2EVMMessage calldata message) + external + override + onlyRouter + validChain(message.sourceChainSelector) + { + try this.processMessage(message) {} + catch (bytes memory err) { + // Could set different error codes based on the caught error. Each could be + // handled differently. + s_failedMessages.set(message.messageId, uint256(ErrorCode.BASIC)); + s_messageContents[message.messageId] = message; + // Don't revert so CCIP doesn't revert. Emit event instead. + // The message can be retried later without having to do manual execution of CCIP. + emit MessageFailed(message.messageId, err); + return; + } + emit MessageSucceeded(message.messageId); + } + + /// @notice This function the entrypoint for this contract to process messages. + /// @param message The message to process. + /// @dev This example just sends the tokens to the owner of this contracts. More + /// interesting functions could be implemented. + /// @dev It has to be external because of the try/catch. + function processMessage(Client.Any2EVMMessage calldata message) + external + onlySelf + validChain(message.sourceChainSelector) + { + // Simulate a revert + if (s_simRevert) revert ErrorCase(); + + // Send tokens to the owner + for (uint256 i = 0; i < message.destTokenAmounts.length; ++i) { + IERC20(message.destTokenAmounts[i].token).safeTransfer(owner(), message.destTokenAmounts[i].amount); + } + // Do other things that might revert + } + + /// @notice This function is callable by the owner when a message has failed + /// to unblock the tokens that are associated with that message. + /// @dev This function is only callable by the owner. + function retryFailedMessage(bytes32 messageId, address tokenReceiver) external onlyOwner { + if (s_failedMessages.get(messageId) != uint256(ErrorCode.BASIC)) revert MessageNotFailed(messageId); + // Set the error code to 0 to disallow reentry and retry the same failed message + // multiple times. + s_failedMessages.set(messageId, uint256(ErrorCode.RESOLVED)); + + // Do stuff to retry message, potentially just releasing the associated tokens + Client.Any2EVMMessage memory message = s_messageContents[messageId]; + + // send the tokens to the receiver as escape hatch + for (uint256 i = 0; i < message.destTokenAmounts.length; ++i) { + IERC20(message.destTokenAmounts[i].token).safeTransfer(tokenReceiver, message.destTokenAmounts[i].amount); + } + + emit MessageRecovered(messageId); + } + + // An example function to demonstrate recovery + function setSimRevert(bool simRevert) external onlyOwner { + s_simRevert = simRevert; + } + + modifier onlySelf() { + if (msg.sender != address(this)) revert OnlySelf(); + _; + } +} diff --git a/contracts/src/v0.8/ccip/applications/EtherSenderReceiver.sol b/contracts/src/v0.8/ccip/applications/EtherSenderReceiver.sol new file mode 100644 index 0000000000..ce8ed1ff7a --- /dev/null +++ b/contracts/src/v0.8/ccip/applications/EtherSenderReceiver.sol @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; + +import {IRouterClient} from "../interfaces/IRouterClient.sol"; +import {IWrappedNative} from "../interfaces/IWrappedNative.sol"; + +import {Client} from "./../libraries/Client.sol"; +import {CCIPReceiver} from "./CCIPReceiver.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +//solhint-disable interface-starts-with-i +interface CCIPRouter { + function getWrappedNative() external view returns (address); +} + +/// @notice A contract that can send raw ether cross-chain using CCIP. +/// Since CCIP only supports ERC-20 token transfers, this contract accepts +/// normal ether, wraps it, and uses CCIP to send it cross-chain. +/// On the receiving side, the wrapped ether is unwrapped and sent to the final receiver. +/// @notice This contract only supports chains where the wrapped native contract +/// is the WETH contract (i.e not WMATIC, or WAVAX, etc.). This is because the +/// receiving contract will always unwrap the ether using it's local wrapped native contract. +/// @dev This contract is both a sender and a receiver. This same contract can be +/// deployed on source and destination chains to facilitate cross-chain ether transfers +/// and act as a sender and a receiver. +/// @dev This contract is intentionally ownerless and permissionless. This contract +/// will never hold any excess funds, native or otherwise, when used correctly. +contract EtherSenderReceiver is CCIPReceiver, ITypeAndVersion { + using SafeERC20 for IERC20; + + error InvalidTokenAmounts(uint256 gotAmounts); + error InvalidToken(address gotToken, address expectedToken); + error TokenAmountNotEqualToMsgValue(uint256 gotAmount, uint256 msgValue); + + string public constant override typeAndVersion = "EtherSenderReceiver 1.5.0"; + + /// @notice The wrapped native token address. + /// @dev If the wrapped native token address changes on the router, this contract will need to be redeployed. + IWrappedNative public immutable i_weth; + + /// @param router The CCIP router address. + constructor(address router) CCIPReceiver(router) { + i_weth = IWrappedNative(CCIPRouter(router).getWrappedNative()); + i_weth.approve(router, type(uint256).max); + } + + /// @notice Need this in order to unwrap correctly. + receive() external payable {} + + /// @notice Get the fee for sending a message to a destination chain. + /// This is mirrored from the router for convenience, construct the appropriate + /// message and get it's fee. + /// @param destinationChainSelector The destination chainSelector + /// @param message The cross-chain CCIP message including data and/or tokens + /// @return fee returns execution fee for the message + /// delivery to destination chain, denominated in the feeToken specified in the message. + /// @dev Reverts with appropriate reason upon invalid message. + function getFee( + uint64 destinationChainSelector, + Client.EVM2AnyMessage calldata message + ) external view returns (uint256 fee) { + Client.EVM2AnyMessage memory validatedMessage = _validatedMessage(message); + + return IRouterClient(getRouter()).getFee(destinationChainSelector, validatedMessage); + } + + /// @notice Send raw native tokens cross-chain. + /// @param destinationChainSelector The destination chain selector. + /// @param message The CCIP message with the following fields correctly set: + /// - bytes receiver: The _contract_ address on the destination chain that will receive the wrapped ether. + /// The caller must ensure that this contract address is correct, otherwise funds may be lost forever. + /// - address feeToken: The fee token address. Must be address(0) for native tokens, or a supported CCIP fee token otherwise (i.e, LINK token). + /// In the event a feeToken is set, we will transferFrom the caller the fee amount before sending the message, in order to forward them to the router. + /// - EVMTokenAmount[] tokenAmounts: The tokenAmounts array must contain a single element with the following fields: + /// - uint256 amount: The amount of ether to send. + /// There are a couple of cases here that depend on the fee token specified: + /// 1. If feeToken == address(0), the fee must be included in msg.value. Therefore tokenAmounts[0].amount must be less than msg.value, + /// and the difference will be used as the fee. + /// 2. If feeToken != address(0), the fee is not included in msg.value, and tokenAmounts[0].amount must be equal to msg.value. + /// these fees to the CCIP router. + /// @return messageId The CCIP message ID. + function ccipSend( + uint64 destinationChainSelector, + Client.EVM2AnyMessage calldata message + ) external payable returns (bytes32) { + _validateFeeToken(message); + Client.EVM2AnyMessage memory validatedMessage = _validatedMessage(message); + + i_weth.deposit{value: validatedMessage.tokenAmounts[0].amount}(); + + uint256 fee = IRouterClient(getRouter()).getFee(destinationChainSelector, validatedMessage); + if (validatedMessage.feeToken != address(0)) { + // If the fee token is not native, we need to transfer the fee to this contract and re-approve it to the router. + // Its not possible to have any leftover tokens in this path because we transferFrom the exact fee that CCIP + // requires from the caller. + IERC20(validatedMessage.feeToken).safeTransferFrom(msg.sender, address(this), fee); + + // We gave an infinite approval of weth to the router in the constructor. + if (validatedMessage.feeToken != address(i_weth)) { + IERC20(validatedMessage.feeToken).approve(getRouter(), fee); + } + + return IRouterClient(getRouter()).ccipSend(destinationChainSelector, validatedMessage); + } + + // We don't want to keep any excess ether in this contract, so we send over the entire address(this).balance as the fee. + // CCIP will revert if the fee is insufficient, so we don't need to check here. + return IRouterClient(getRouter()).ccipSend{value: address(this).balance}(destinationChainSelector, validatedMessage); + } + + /// @notice Validate the message content. + /// @dev Only allows a single token to be sent. Always overwritten to be address(i_weth) + /// and receiver is always msg.sender. + function _validatedMessage(Client.EVM2AnyMessage calldata message) + internal + view + returns (Client.EVM2AnyMessage memory) + { + Client.EVM2AnyMessage memory validatedMessage = message; + + if (validatedMessage.tokenAmounts.length != 1) { + revert InvalidTokenAmounts(validatedMessage.tokenAmounts.length); + } + + validatedMessage.data = abi.encode(msg.sender); + validatedMessage.tokenAmounts[0].token = address(i_weth); + + return validatedMessage; + } + + function _validateFeeToken(Client.EVM2AnyMessage calldata message) internal view { + uint256 tokenAmount = message.tokenAmounts[0].amount; + + if (message.feeToken != address(0)) { + // If the fee token is NOT native, then the token amount must be equal to msg.value. + // This is done to ensure that there is no leftover ether in this contract. + if (msg.value != tokenAmount) { + revert TokenAmountNotEqualToMsgValue(tokenAmount, msg.value); + } + } + } + + /// @notice Receive the wrapped ether, unwrap it, and send it to the specified EOA in the data field. + /// @param message The CCIP message containing the wrapped ether amount and the final receiver. + /// @dev The code below should never revert if the message being is valid according + /// to the above _validatedMessage and _validateFeeToken functions. + function _ccipReceive(Client.Any2EVMMessage memory message) internal override { + address receiver = abi.decode(message.data, (address)); + + if (message.destTokenAmounts.length != 1) { + revert InvalidTokenAmounts(message.destTokenAmounts.length); + } + + if (message.destTokenAmounts[0].token != address(i_weth)) { + revert InvalidToken(message.destTokenAmounts[0].token, address(i_weth)); + } + + uint256 tokenAmount = message.destTokenAmounts[0].amount; + i_weth.withdraw(tokenAmount); + + // it is possible that the below call may fail if receiver.code.length > 0 and the contract + // doesn't e.g have a receive() or a fallback() function. + (bool success,) = payable(receiver).call{value: tokenAmount}(""); + if (!success) { + // We have a few options here: + // 1. Revert: this is bad generally because it may mean that these tokens are stuck. + // 2. Store the tokens in a mapping and allow the user to withdraw them with another tx. + // 3. Send WETH to the receiver address. + // We opt for (3) here because at least the receiver will have the funds and can unwrap them if needed. + // However it is worth noting that if receiver is actually a contract AND the contract _cannot_ withdraw + // the WETH, then the WETH will be stuck in this contract. + i_weth.deposit{value: tokenAmount}(); + i_weth.transfer(receiver, tokenAmount); + } + } +} diff --git a/contracts/src/v0.8/ccip/applications/PingPongDemo.sol b/contracts/src/v0.8/ccip/applications/PingPongDemo.sol new file mode 100644 index 0000000000..423fdc4546 --- /dev/null +++ b/contracts/src/v0.8/ccip/applications/PingPongDemo.sol @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IRouterClient} from "../interfaces/IRouterClient.sol"; + +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; +import {Client} from "../libraries/Client.sol"; +import {CCIPReceiver} from "./CCIPReceiver.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +/// @title PingPongDemo - A simple ping-pong contract for demonstrating cross-chain communication +contract PingPongDemo is CCIPReceiver, OwnerIsCreator, ITypeAndVersion { + event Ping(uint256 pingPongCount); + event Pong(uint256 pingPongCount); + + // The chain ID of the counterpart ping pong contract + uint64 internal s_counterpartChainSelector; + // The contract address of the counterpart ping pong contract + address internal s_counterpartAddress; + // Pause ping-ponging + bool private s_isPaused; + // The fee token used to pay for CCIP transactions + IERC20 internal s_feeToken; + + constructor(address router, IERC20 feeToken) CCIPReceiver(router) { + s_isPaused = false; + s_feeToken = feeToken; + s_feeToken.approve(address(router), type(uint256).max); + } + + function typeAndVersion() external pure virtual returns (string memory) { + return "PingPongDemo 1.2.0"; + } + + function setCounterpart(uint64 counterpartChainSelector, address counterpartAddress) external onlyOwner { + s_counterpartChainSelector = counterpartChainSelector; + s_counterpartAddress = counterpartAddress; + } + + function startPingPong() external onlyOwner { + s_isPaused = false; + _respond(1); + } + + function _respond(uint256 pingPongCount) internal virtual { + if (pingPongCount & 1 == 1) { + emit Ping(pingPongCount); + } else { + emit Pong(pingPongCount); + } + bytes memory data = abi.encode(pingPongCount); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(s_counterpartAddress), + data: data, + tokenAmounts: new Client.EVMTokenAmount[](0), + extraArgs: "", + feeToken: address(s_feeToken) + }); + IRouterClient(getRouter()).ccipSend(s_counterpartChainSelector, message); + } + + function _ccipReceive(Client.Any2EVMMessage memory message) internal override { + uint256 pingPongCount = abi.decode(message.data, (uint256)); + if (!s_isPaused) { + _respond(pingPongCount + 1); + } + } + + ///////////////////////////////////////////////////////////////////// + // Plumbing + ///////////////////////////////////////////////////////////////////// + + function getCounterpartChainSelector() external view returns (uint64) { + return s_counterpartChainSelector; + } + + function setCounterpartChainSelector(uint64 chainSelector) external onlyOwner { + s_counterpartChainSelector = chainSelector; + } + + function getCounterpartAddress() external view returns (address) { + return s_counterpartAddress; + } + + function getFeeToken() external view returns (IERC20) { + return s_feeToken; + } + + function setCounterpartAddress(address addr) external onlyOwner { + s_counterpartAddress = addr; + } + + function isPaused() external view returns (bool) { + return s_isPaused; + } + + function setPaused(bool pause) external onlyOwner { + s_isPaused = pause; + } +} diff --git a/contracts/src/v0.8/ccip/applications/SelfFundedPingPong.sol b/contracts/src/v0.8/ccip/applications/SelfFundedPingPong.sol new file mode 100644 index 0000000000..80bc7bb24a --- /dev/null +++ b/contracts/src/v0.8/ccip/applications/SelfFundedPingPong.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Router} from "../Router.sol"; +import {Client} from "../libraries/Client.sol"; +import {EVM2EVMOnRamp} from "../onRamp/EVM2EVMOnRamp.sol"; +import {PingPongDemo} from "./PingPongDemo.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract SelfFundedPingPong is PingPongDemo { + string public constant override typeAndVersion = "SelfFundedPingPong 1.2.0"; + + event Funded(); + event CountIncrBeforeFundingSet(uint8 countIncrBeforeFunding); + + // Defines the increase in ping pong count before self-funding is attempted. + // Set to 0 to disable auto-funding, auto-funding only works for ping-pongs that are set as NOPs in the onRamp. + uint8 private s_countIncrBeforeFunding; + + constructor(address router, IERC20 feeToken, uint8 roundTripsBeforeFunding) PingPongDemo(router, feeToken) { + // PingPong count increases by 2 for each round trip. + s_countIncrBeforeFunding = roundTripsBeforeFunding * 2; + } + + function _respond(uint256 pingPongCount) internal override { + if (pingPongCount & 1 == 1) { + emit Ping(pingPongCount); + } else { + emit Pong(pingPongCount); + } + + fundPingPong(pingPongCount); + + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(s_counterpartAddress), + data: abi.encode(pingPongCount), + tokenAmounts: new Client.EVMTokenAmount[](0), + extraArgs: "", + feeToken: address(s_feeToken) + }); + Router(getRouter()).ccipSend(s_counterpartChainSelector, message); + } + + /// @notice A function that is responsible for funding this contract. + /// The contract can only be funded if it is set as a nop in the target onRamp. + /// In case your contract is not a nop you can prevent this function from being called by setting s_countIncrBeforeFunding=0. + function fundPingPong(uint256 pingPongCount) public { + // If selfFunding is disabled, or ping pong count has not reached s_countIncrPerFunding, do not attempt funding. + if (s_countIncrBeforeFunding == 0 || pingPongCount < s_countIncrBeforeFunding) return; + + // Ping pong on one side will always be even, one side will always to odd. + if (pingPongCount % s_countIncrBeforeFunding <= 1) { + EVM2EVMOnRamp(Router(getRouter()).getOnRamp(s_counterpartChainSelector)).payNops(); + emit Funded(); + } + } + + function getCountIncrBeforeFunding() external view returns (uint8) { + return s_countIncrBeforeFunding; + } + + function setCountIncrBeforeFunding(uint8 countIncrBeforeFunding) external onlyOwner { + s_countIncrBeforeFunding = countIncrBeforeFunding; + emit CountIncrBeforeFundingSet(countIncrBeforeFunding); + } +} diff --git a/contracts/src/v0.8/ccip/applications/TokenProxy.sol b/contracts/src/v0.8/ccip/applications/TokenProxy.sol new file mode 100644 index 0000000000..6fd26c076b --- /dev/null +++ b/contracts/src/v0.8/ccip/applications/TokenProxy.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {IRouterClient} from "../interfaces/IRouterClient.sol"; + +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; +import {Client} from "../libraries/Client.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +contract TokenProxy is OwnerIsCreator { + using SafeERC20 for IERC20; + + error InvalidToken(); + error NoDataAllowed(); + error GasShouldBeZero(); + + /// @notice The CCIP router contract + IRouterClient internal immutable i_ccipRouter; + /// @notice Only this token is allowed to be sent using this proxy + address internal immutable i_token; + + constructor(address router, address token) OwnerIsCreator() { + i_ccipRouter = IRouterClient(router); + i_token = token; + // Approve the router to spend an unlimited amount of tokens to reduce + // gas cost per tx. + IERC20(token).approve(router, type(uint256).max); + } + + /// @notice Simply forwards the request to the CCIP router and returns the result. + /// @param destinationChainSelector The destination chainSelector + /// @param message The cross-chain CCIP message including data and/or tokens + /// @return fee returns execution fee for the message delivery to destination chain, + /// denominated in the feeToken specified in the message. + /// @dev Reverts with appropriate reason upon invalid message. + function getFee( + uint64 destinationChainSelector, + Client.EVM2AnyMessage calldata message + ) external view returns (uint256 fee) { + _validateMessage(message); + return i_ccipRouter.getFee(destinationChainSelector, message); + } + + /// @notice Validates the message content, forwards it to the CCIP router and returns the result. + function ccipSend( + uint64 destinationChainSelector, + Client.EVM2AnyMessage calldata message + ) external payable returns (bytes32 messageId) { + _validateMessage(message); + if (message.feeToken != address(0)) { + // This path is probably warmed up already so the extra cost isn't too bad. + uint256 feeAmount = i_ccipRouter.getFee(destinationChainSelector, message); + IERC20(message.feeToken).safeTransferFrom(msg.sender, address(this), feeAmount); + IERC20(message.feeToken).approve(address(i_ccipRouter), feeAmount); + } + + // Transfer the tokens from the sender to this contract. + IERC20(message.tokenAmounts[0].token).transferFrom(msg.sender, address(this), message.tokenAmounts[0].amount); + + return i_ccipRouter.ccipSend{value: msg.value}(destinationChainSelector, message); + } + + /// @notice Validates the message content. + /// @dev Only allows a single token to be sent, and no data. + function _validateMessage(Client.EVM2AnyMessage calldata message) internal view { + if (message.tokenAmounts.length != 1 || message.tokenAmounts[0].token != i_token) revert InvalidToken(); + if (message.data.length > 0) revert NoDataAllowed(); + + if (message.extraArgs.length == 0 || bytes4(message.extraArgs) != Client.EVM_EXTRA_ARGS_V1_TAG) { + revert GasShouldBeZero(); + } + + if (abi.decode(message.extraArgs[4:], (Client.EVMExtraArgsV1)).gasLimit != 0) revert GasShouldBeZero(); + } + + /// @notice Returns the CCIP router contract. + function getRouter() external view returns (IRouterClient) { + return i_ccipRouter; + } + + /// @notice Returns the token that this proxy is allowed to send. + function getToken() external view returns (address) { + return i_token; + } +} diff --git a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol new file mode 100644 index 0000000000..40b7a4a2f9 --- /dev/null +++ b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol @@ -0,0 +1,476 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ICapabilityConfiguration} from "../../keystone/interfaces/ICapabilityConfiguration.sol"; +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {ICapabilitiesRegistry} from "./interfaces/ICapabilitiesRegistry.sol"; + +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; + +import {SortedSetValidationUtil} from "../../shared/util/SortedSetValidationUtil.sol"; +import {Internal} from "../libraries/Internal.sol"; +import {CCIPConfigTypes} from "./libraries/CCIPConfigTypes.sol"; + +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +/// @notice CCIPConfig stores the configuration for the CCIP capability. +/// We have two classes of configuration: chain configuration and DON (in the CapabilitiesRegistry sense) configuration. +/// Each chain will have a single configuration which includes information like the router address. +/// Each CR DON will have up to four configurations: for each of (commit, exec), one blue and one green configuration. +/// This is done in order to achieve "blue-green" deployments. +contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator, IERC165 { + using EnumerableSet for EnumerableSet.UintSet; + + /// @notice Emitted when a chain's configuration is set. + /// @param chainSelector The chain selector. + /// @param chainConfig The chain configuration. + event ChainConfigSet(uint64 chainSelector, CCIPConfigTypes.ChainConfig chainConfig); + + /// @notice Emitted when a chain's configuration is removed. + /// @param chainSelector The chain selector. + event ChainConfigRemoved(uint64 chainSelector); + + error ChainConfigNotSetForChain(uint64 chainSelector); + error NodeNotInRegistry(bytes32 p2pId); + error OnlyCapabilitiesRegistryCanCall(); + error ChainSelectorNotFound(uint64 chainSelector); + error ChainSelectorNotSet(); + error TooManyOCR3Configs(); + error TooManySigners(); + error TooManyTransmitters(); + error TooManyBootstrapP2PIds(); + error P2PIdsLengthNotMatching(uint256 p2pIdsLength, uint256 signersLength, uint256 transmittersLength); + error NotEnoughTransmitters(uint256 got, uint256 minimum); + error FMustBePositive(); + error FChainMustBePositive(); + error FTooHigh(); + error InvalidPluginType(); + error OfframpAddressCannotBeZero(); + error InvalidConfigLength(uint256 length); + error InvalidConfigStateTransition( + CCIPConfigTypes.ConfigState currentState, CCIPConfigTypes.ConfigState proposedState + ); + error NonExistentConfigTransition(); + error WrongConfigCount(uint64 got, uint64 expected); + error WrongConfigDigest(bytes32 got, bytes32 expected); + error WrongConfigDigestBlueGreen(bytes32 got, bytes32 expected); + + /// @notice Type and version override. + string public constant override typeAndVersion = "CCIPConfig 1.6.0-dev"; + + /// @notice The canonical capabilities registry address. + address internal immutable i_capabilitiesRegistry; + + /// @notice chain configuration for each chain that CCIP is deployed on. + mapping(uint64 chainSelector => CCIPConfigTypes.ChainConfig chainConfig) internal s_chainConfigurations; + + /// @notice All chains that are configured. + EnumerableSet.UintSet internal s_remoteChainSelectors; + + /// @notice OCR3 configurations for each DON. + /// Each CR DON will have a commit and execution configuration. + /// This means that a DON can have up to 4 configurations, since we are implementing blue/green deployments. + mapping( + uint32 donId => mapping(Internal.OCRPluginType pluginType => CCIPConfigTypes.OCR3ConfigWithMeta[] ocr3Configs) + ) internal s_ocr3Configs; + + /// @notice The DONs that have been configured. + EnumerableSet.UintSet internal s_donIds; + + uint8 internal constant MAX_OCR3_CONFIGS_PER_PLUGIN = 2; + uint8 internal constant MAX_OCR3_CONFIGS_PER_DON = 4; + uint8 internal constant MAX_NUM_ORACLES = 31; + + /// @param capabilitiesRegistry the canonical capabilities registry address. + constructor(address capabilitiesRegistry) { + i_capabilitiesRegistry = capabilitiesRegistry; + } + + /// @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { + return interfaceId == type(ICapabilityConfiguration).interfaceId || interfaceId == type(IERC165).interfaceId; + } + + // ================================================================ + // │ Config Getters │ + // ================================================================ + + /// @notice Returns all the chain configurations. + /// @return The chain configurations. + // TODO: will this eventually hit the RPC max response size limit? + function getAllChainConfigs() external view returns (CCIPConfigTypes.ChainConfigInfo[] memory) { + uint256[] memory chainSelectors = s_remoteChainSelectors.values(); + CCIPConfigTypes.ChainConfigInfo[] memory chainConfigs = + new CCIPConfigTypes.ChainConfigInfo[](s_remoteChainSelectors.length()); + for (uint256 i = 0; i < chainSelectors.length; ++i) { + uint64 chainSelector = uint64(chainSelectors[i]); + chainConfigs[i] = CCIPConfigTypes.ChainConfigInfo({ + chainSelector: chainSelector, + chainConfig: s_chainConfigurations[chainSelector] + }); + } + return chainConfigs; + } + + /// @notice Returns the OCR configuration for the given don ID and plugin type. + /// @param donId The DON ID. + /// @param pluginType The plugin type. + /// @return The OCR3 configurations, up to 2 (blue and green). + function getOCRConfig( + uint32 donId, + Internal.OCRPluginType pluginType + ) external view returns (CCIPConfigTypes.OCR3ConfigWithMeta[] memory) { + return s_ocr3Configs[donId][pluginType]; + } + + // ================================================================ + // │ Capability Configuration │ + // ================================================================ + + /// @inheritdoc ICapabilityConfiguration + /// @dev The CCIP capability will fetch the configuration needed directly from this contract. + /// The offchain syncer will call this function, however, so its important that it doesn't revert. + function getCapabilityConfiguration(uint32 /* donId */ ) external pure override returns (bytes memory configuration) { + return bytes(""); + } + + /// @notice Called by the registry prior to the config being set for a particular DON. + function beforeCapabilityConfigSet( + bytes32[] calldata, /* nodes */ + bytes calldata config, + uint64, /* configCount */ + uint32 donId + ) external override { + if (msg.sender != i_capabilitiesRegistry) { + revert OnlyCapabilitiesRegistryCanCall(); + } + + CCIPConfigTypes.OCR3Config[] memory ocr3Configs = abi.decode(config, (CCIPConfigTypes.OCR3Config[])); + (CCIPConfigTypes.OCR3Config[] memory commitConfigs, CCIPConfigTypes.OCR3Config[] memory execConfigs) = + _groupByPluginType(ocr3Configs); + if (commitConfigs.length > 0) { + _updatePluginConfig(donId, Internal.OCRPluginType.Commit, commitConfigs); + } + if (execConfigs.length > 0) { + _updatePluginConfig(donId, Internal.OCRPluginType.Execution, execConfigs); + } + } + + function _updatePluginConfig( + uint32 donId, + Internal.OCRPluginType pluginType, + CCIPConfigTypes.OCR3Config[] memory newConfig + ) internal { + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig = s_ocr3Configs[donId][pluginType]; + + // Validate the state transition being proposed, which is implicitly defined by the combination + // of lengths of the current and new configurations. + CCIPConfigTypes.ConfigState currentState = _stateFromConfigLength(currentConfig.length); + CCIPConfigTypes.ConfigState proposedState = _stateFromConfigLength(newConfig.length); + _validateConfigStateTransition(currentState, proposedState); + + // Build the new configuration with metadata and validate that the transition is valid. + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfigWithMeta = + _computeNewConfigWithMeta(donId, currentConfig, newConfig, currentState, proposedState); + _validateConfigTransition(currentConfig, newConfigWithMeta); + + // Update contract state with new configuration if its valid. + // We won't run out of gas from this delete since the array is at most 2 elements long. + delete s_ocr3Configs[donId][pluginType]; + for (uint256 i = 0; i < newConfigWithMeta.length; ++i) { + s_ocr3Configs[donId][pluginType].push(newConfigWithMeta[i]); + } + } + + // ================================================================ + // │ Config State Machine │ + // ================================================================ + + /// @notice Determine the config state of the configuration from the length of the config. + /// @param configLen The length of the configuration. + /// @return The config state. + function _stateFromConfigLength(uint256 configLen) internal pure returns (CCIPConfigTypes.ConfigState) { + if (configLen > 2) { + revert InvalidConfigLength(configLen); + } + return CCIPConfigTypes.ConfigState(configLen); + } + + // the only valid state transitions are the following: + // init -> running (first ever config) + // running -> staging (blue/green proposal) + // staging -> running (promotion) + // everything else is invalid and should revert. + function _validateConfigStateTransition( + CCIPConfigTypes.ConfigState currentState, + CCIPConfigTypes.ConfigState newState + ) internal pure { + // Calculate the difference between the new state and the current state + int256 stateDiff = int256(uint256(newState)) - int256(uint256(currentState)); + + // Check if the state transition is valid: + // Valid transitions: + // 1. currentState -> newState (where stateDiff == 1) + // e.g., init -> running or running -> staging + // 2. staging -> running (where stateDiff == -1) + if (stateDiff == 1 || (stateDiff == -1 && currentState == CCIPConfigTypes.ConfigState.Staging)) { + return; + } + revert InvalidConfigStateTransition(currentState, newState); + } + + function _validateConfigTransition( + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig, + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfigWithMeta + ) internal pure { + uint256 currentConfigLen = currentConfig.length; + uint256 newConfigLen = newConfigWithMeta.length; + if (currentConfigLen == 0 && newConfigLen == 1) { + // Config counts always must start at 1 for the first ever config. + if (newConfigWithMeta[0].configCount != 1) { + revert WrongConfigCount(newConfigWithMeta[0].configCount, 1); + } + return; + } + + if (currentConfigLen == 1 && newConfigLen == 2) { + // On a blue/green proposal: + // * the config digest of the blue config must remain unchanged. + // * the green config count must be the blue config count + 1. + if (newConfigWithMeta[0].configDigest != currentConfig[0].configDigest) { + revert WrongConfigDigestBlueGreen(newConfigWithMeta[0].configDigest, currentConfig[0].configDigest); + } + if (newConfigWithMeta[1].configCount != currentConfig[0].configCount + 1) { + revert WrongConfigCount(newConfigWithMeta[1].configCount, currentConfig[0].configCount + 1); + } + return; + } + + if (currentConfigLen == 2 && newConfigLen == 1) { + // On a promotion, the green config digest must become the blue config digest. + if (newConfigWithMeta[0].configDigest != currentConfig[1].configDigest) { + revert WrongConfigDigest(newConfigWithMeta[0].configDigest, currentConfig[1].configDigest); + } + return; + } + + revert NonExistentConfigTransition(); + } + + /// @notice Computes a new configuration with metadata based on the current configuration and the new configuration. + /// @param donId The DON ID. + /// @param currentConfig The current configuration, including metadata. + /// @param newConfig The new configuration, without metadata. + /// @param currentState The current state of the configuration. + /// @param newState The new state of the configuration. + /// @return The new configuration with metadata. + function _computeNewConfigWithMeta( + uint32 donId, + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig, + CCIPConfigTypes.OCR3Config[] memory newConfig, + CCIPConfigTypes.ConfigState currentState, + CCIPConfigTypes.ConfigState newState + ) internal view returns (CCIPConfigTypes.OCR3ConfigWithMeta[] memory) { + uint64[] memory configCounts = new uint64[](newConfig.length); + + // Set config counts based on the only valid state transitions. + // Init -> Running (first ever config) + // Running -> Staging (blue/green proposal) + // Staging -> Running (promotion) + if (currentState == CCIPConfigTypes.ConfigState.Init && newState == CCIPConfigTypes.ConfigState.Running) { + // First ever config starts with config count == 1. + configCounts[0] = 1; + } else if (currentState == CCIPConfigTypes.ConfigState.Running && newState == CCIPConfigTypes.ConfigState.Staging) { + // On a blue/green proposal, the config count of the green config is the blue config count + 1. + configCounts[0] = currentConfig[0].configCount; + configCounts[1] = currentConfig[0].configCount + 1; + } else if (currentState == CCIPConfigTypes.ConfigState.Staging && newState == CCIPConfigTypes.ConfigState.Running) { + // On a promotion, the config count of the green config becomes the blue config count. + configCounts[0] = currentConfig[1].configCount; + } else { + revert InvalidConfigStateTransition(currentState, newState); + } + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfigWithMeta = + new CCIPConfigTypes.OCR3ConfigWithMeta[](newConfig.length); + for (uint256 i = 0; i < configCounts.length; ++i) { + _validateConfig(newConfig[i]); + newConfigWithMeta[i] = CCIPConfigTypes.OCR3ConfigWithMeta({ + config: newConfig[i], + configCount: configCounts[i], + configDigest: _computeConfigDigest(donId, configCounts[i], newConfig[i]) + }); + } + + return newConfigWithMeta; + } + + /// @notice Group the OCR3 configurations by plugin type for further processing. + /// @param ocr3Configs The OCR3 configurations to group. + function _groupByPluginType(CCIPConfigTypes.OCR3Config[] memory ocr3Configs) + internal + pure + returns (CCIPConfigTypes.OCR3Config[] memory commitConfigs, CCIPConfigTypes.OCR3Config[] memory execConfigs) + { + if (ocr3Configs.length > MAX_OCR3_CONFIGS_PER_DON) { + revert TooManyOCR3Configs(); + } + + // Declare with size 2 since we have a maximum of two configs per plugin type (blue, green). + // If we have less we will adjust the length later using mstore. + // If the caller provides more than 2 configs per plugin type, we will revert due to out of bounds + // access in the for loop below. + commitConfigs = new CCIPConfigTypes.OCR3Config[](MAX_OCR3_CONFIGS_PER_PLUGIN); + execConfigs = new CCIPConfigTypes.OCR3Config[](MAX_OCR3_CONFIGS_PER_PLUGIN); + uint256 commitCount; + uint256 execCount; + for (uint256 i = 0; i < ocr3Configs.length; ++i) { + if (ocr3Configs[i].pluginType == Internal.OCRPluginType.Commit) { + commitConfigs[commitCount] = ocr3Configs[i]; + ++commitCount; + } else { + execConfigs[execCount] = ocr3Configs[i]; + ++execCount; + } + } + + // Adjust the length of the arrays to the actual number of configs. + assembly { + mstore(commitConfigs, commitCount) + mstore(execConfigs, execCount) + } + + return (commitConfigs, execConfigs); + } + + function _validateConfig(CCIPConfigTypes.OCR3Config memory cfg) internal view { + if (cfg.chainSelector == 0) revert ChainSelectorNotSet(); + if (cfg.pluginType != Internal.OCRPluginType.Commit && cfg.pluginType != Internal.OCRPluginType.Execution) { + revert InvalidPluginType(); + } + // TODO: can we do more sophisticated validation than this? + if (cfg.offrampAddress.length == 0) revert OfframpAddressCannotBeZero(); + if (!s_remoteChainSelectors.contains(cfg.chainSelector)) revert ChainSelectorNotFound(cfg.chainSelector); + + // Some of these checks below are done in OCR2/3Base config validation, so we do them again here. + // Role DON OCR configs will have all the Role DON signers but only a subset of transmitters. + if (cfg.signers.length > MAX_NUM_ORACLES) revert TooManySigners(); + if (cfg.transmitters.length > MAX_NUM_ORACLES) revert TooManyTransmitters(); + + // We check for chain config presence above, so fChain here must be non-zero. + uint256 minTransmittersLength = 3 * s_chainConfigurations[cfg.chainSelector].fChain + 1; + if (cfg.transmitters.length < minTransmittersLength) { + revert NotEnoughTransmitters(cfg.transmitters.length, minTransmittersLength); + } + if (cfg.F == 0) revert FMustBePositive(); + if (cfg.signers.length <= 3 * cfg.F) revert FTooHigh(); + + if (cfg.p2pIds.length != cfg.signers.length || cfg.p2pIds.length != cfg.transmitters.length) { + revert P2PIdsLengthNotMatching(cfg.p2pIds.length, cfg.signers.length, cfg.transmitters.length); + } + if (cfg.bootstrapP2PIds.length > cfg.p2pIds.length) revert TooManyBootstrapP2PIds(); + + // check for duplicate p2p ids and bootstrapP2PIds. + // check that p2p ids in cfg.bootstrapP2PIds are included in cfg.p2pIds. + SortedSetValidationUtil._checkIsValidUniqueSubset(cfg.bootstrapP2PIds, cfg.p2pIds); + + // Check that the readers are in the capabilities registry. + for (uint256 i = 0; i < cfg.signers.length; ++i) { + _ensureInRegistry(cfg.p2pIds[i]); + } + } + + /// @notice Computes the digest of the provided configuration. + /// @dev In traditional OCR config digest computation, block.chainid and address(this) are used + /// in order to further domain separate the digest. We can't do that here since the digest will + /// be used on remote chains; so we use the chain selector instead of block.chainid. The don ID + /// replaces the address(this) in the traditional computation. + /// @param donId The DON ID. + /// @param configCount The configuration count. + /// @param ocr3Config The OCR3 configuration. + /// @return The computed digest. + function _computeConfigDigest( + uint32 donId, + uint64 configCount, + CCIPConfigTypes.OCR3Config memory ocr3Config + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + ocr3Config.chainSelector, + donId, + ocr3Config.pluginType, + ocr3Config.offrampAddress, + configCount, + ocr3Config.bootstrapP2PIds, + ocr3Config.p2pIds, + ocr3Config.signers, + ocr3Config.transmitters, + ocr3Config.F, + ocr3Config.offchainConfigVersion, + ocr3Config.offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + uint256 prefix = 0x000a << (256 - 16); // 0x000a00..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + // ================================================================ + // │ Chain Configuration │ + // ================================================================ + + /// @notice Sets and/or removes chain configurations. + /// @param chainSelectorRemoves The chain configurations to remove. + /// @param chainConfigAdds The chain configurations to add. + function applyChainConfigUpdates( + uint64[] calldata chainSelectorRemoves, + CCIPConfigTypes.ChainConfigInfo[] calldata chainConfigAdds + ) external onlyOwner { + // Process removals first. + for (uint256 i = 0; i < chainSelectorRemoves.length; ++i) { + // check if the chain selector is in s_remoteChainSelectors first. + if (!s_remoteChainSelectors.contains(chainSelectorRemoves[i])) { + revert ChainSelectorNotFound(chainSelectorRemoves[i]); + } + + delete s_chainConfigurations[chainSelectorRemoves[i]]; + s_remoteChainSelectors.remove(chainSelectorRemoves[i]); + + emit ChainConfigRemoved(chainSelectorRemoves[i]); + } + + // Process additions next. + for (uint256 i = 0; i < chainConfigAdds.length; ++i) { + CCIPConfigTypes.ChainConfig memory chainConfig = chainConfigAdds[i].chainConfig; + bytes32[] memory readers = chainConfig.readers; + uint64 chainSelector = chainConfigAdds[i].chainSelector; + + // Verify that the provided readers are present in the capabilities registry. + for (uint256 j = 0; j < readers.length; j++) { + _ensureInRegistry(readers[j]); + } + + // Verify that fChain is positive. + if (chainConfig.fChain == 0) { + revert FChainMustBePositive(); + } + + s_chainConfigurations[chainSelector] = chainConfig; + s_remoteChainSelectors.add(chainSelector); + + emit ChainConfigSet(chainSelector, chainConfig); + } + } + + /// @notice Helper function to ensure that a node is in the capabilities registry. + /// @param p2pId The P2P ID of the node to check. + function _ensureInRegistry(bytes32 p2pId) internal view { + ICapabilitiesRegistry.NodeInfo memory node = ICapabilitiesRegistry(i_capabilitiesRegistry).getNode(p2pId); + if (node.p2pId == bytes32("")) { + revert NodeNotInRegistry(p2pId); + } + } +} diff --git a/contracts/src/v0.8/ccip/capability/interfaces/ICapabilitiesRegistry.sol b/contracts/src/v0.8/ccip/capability/interfaces/ICapabilitiesRegistry.sol new file mode 100644 index 0000000000..621c3686cf --- /dev/null +++ b/contracts/src/v0.8/ccip/capability/interfaces/ICapabilitiesRegistry.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.24; + +interface ICapabilitiesRegistry { + struct NodeInfo { + /// @notice The id of the node operator that manages this node + uint32 nodeOperatorId; + /// @notice The number of times the node's configuration has been updated + uint32 configCount; + /// @notice The ID of the Workflow DON that the node belongs to. A node can + /// only belong to one DON that accepts Workflows. + uint32 workflowDONId; + /// @notice The signer address for application-layer message verification. + bytes32 signer; + /// @notice This is an Ed25519 public key that is used to identify a node. + /// This key is guaranteed to be unique in the CapabilitiesRegistry. It is + /// used to identify a node in the the P2P network. + bytes32 p2pId; + /// @notice The list of hashed capability IDs supported by the node + bytes32[] hashedCapabilityIds; + /// @notice The list of capabilities DON Ids supported by the node. A node + /// can belong to multiple capabilities DONs. This list does not include a + /// Workflow DON id if the node belongs to one. + uint256[] capabilitiesDONIds; + } + + /// @notice Gets a node's data + /// @param p2pId The P2P ID of the node to query for + /// @return NodeInfo The node data + function getNode(bytes32 p2pId) external view returns (NodeInfo memory); +} diff --git a/contracts/src/v0.8/ccip/capability/interfaces/IOCR3ConfigEncoder.sol b/contracts/src/v0.8/ccip/capability/interfaces/IOCR3ConfigEncoder.sol new file mode 100644 index 0000000000..6d0b0f72a5 --- /dev/null +++ b/contracts/src/v0.8/ccip/capability/interfaces/IOCR3ConfigEncoder.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {CCIPConfigTypes} from "../libraries/CCIPConfigTypes.sol"; + +/// @dev This is so that we can generate gethwrappers and easily encode/decode OCR3Config +/// in the offchain integration tests. +interface IOCR3ConfigEncoder { + /// @dev Encodes an array of OCR3Config into a bytes array. For test usage only. + function exposeOCR3Config(CCIPConfigTypes.OCR3Config[] calldata config) external view returns (bytes memory); +} diff --git a/contracts/src/v0.8/ccip/capability/libraries/CCIPConfigTypes.sol b/contracts/src/v0.8/ccip/capability/libraries/CCIPConfigTypes.sol new file mode 100644 index 0000000000..99adef84b1 --- /dev/null +++ b/contracts/src/v0.8/ccip/capability/libraries/CCIPConfigTypes.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {Internal} from "../../libraries/Internal.sol"; + +library CCIPConfigTypes { + /// @notice ConfigState indicates the state of the configuration. + /// A DON's configuration always starts out in the "Init" state - this is the starting state. + /// The only valid transition from "Init" is to the "Running" state - this is the first ever configuration. + /// The only valid transition from "Running" is to the "Staging" state - this is a blue/green proposal. + /// The only valid transition from "Staging" is back to the "Running" state - this is a promotion. + /// TODO: explain rollbacks? + enum ConfigState { + Init, + Running, + Staging + } + + /// @notice Chain configuration. + /// Changes to chain configuration are detected out-of-band in plugins and decoded offchain. + struct ChainConfig { + bytes32[] readers; // The P2P IDs of the readers for the chain. These IDs must be registered in the capabilities registry. + uint8 fChain; // The fault tolerance parameter of the chain. + bytes config; // The chain configuration. This is kept intentionally opaque so as to add fields in the future if needed. + } + + /// @notice Chain configuration information struct used in applyChainConfigUpdates and getAllChainConfigs. + struct ChainConfigInfo { + uint64 chainSelector; + ChainConfig chainConfig; + } + + /// @notice OCR3 configuration. + struct OCR3Config { + Internal.OCRPluginType pluginType; // ────────╮ The plugin that the configuration is for. + uint64 chainSelector; // | The (remote) chain that the configuration is for. + uint8 F; // | The "big F" parameter for the role DON. + uint64 offchainConfigVersion; // ─────────────╯ The version of the offchain configuration. + bytes offrampAddress; // The remote chain offramp address. + // NOTE: bootstrapP2PIds and p2pIds should be sent as sorted sets + bytes32[] bootstrapP2PIds; // The bootstrap P2P IDs of the oracles that are part of the role DON. + // len(p2pIds) == len(signers) == len(transmitters) == 3 * F + 1 + // NOTE: indexes matter here! The p2p ID at index i corresponds to the signer at index i and the transmitter at index i. + // This is crucial in order to build the oracle ID <-> peer ID mapping offchain. + bytes32[] p2pIds; // The P2P IDs of the oracles that are part of the role DON. + bytes[] signers; // The onchain signing keys of nodes in the don. + bytes[] transmitters; // The onchain transmitter keys of nodes in the don. + bytes offchainConfig; // The offchain configuration for the OCR3 protocol. Protobuf encoded. + } + + /// @notice OCR3 configuration with metadata, specifically the config count and the config digest. + struct OCR3ConfigWithMeta { + OCR3Config config; // The OCR3 configuration. + uint64 configCount; // The config count used to compute the config digest. + bytes32 configDigest; // The config digest of the OCR3 configuration. + } +} diff --git a/contracts/src/v0.8/ccip/docs/multi-chain-overview-ocr3.png b/contracts/src/v0.8/ccip/docs/multi-chain-overview-ocr3.png new file mode 100644 index 0000000000000000000000000000000000000000..39302619cb445c67ea075ded0124745a15fe7d03 GIT binary patch literal 818615 zcmeFZbyQnj*DnfGC^d=|DOTJm?ozC{LvUKOxLdFq#odY*hf+v!C#A);xI>Et3&Dbu zoK5?@GR}E;$NBE~?mzc_86(MN@4eQZYpyB3DIru{_1V4KWVbOeFzzYH%V=U?+|9wj zz%jXX6F4J5P2zxoal6*1{i7QsAMb~} zx~V;tuKbu*P!NNfyB1|UkBjvZ+-xaMvAK|i25J1<;}*h@Y`xX##v^2ND@(>botDrN z^Of+sNu+DVyAi(|FFxI3e()=JBwes~X@p$j`^$p}HE$+@7ep94bo_=1w=fi_%10`M zLgmTh7{4W9ahSe(vPV%@ke}~{C%1=X-u5hH$K4NnZn{W^Vz+AIWk}0lTA8ZsyEPx5 z#jI=zyU2np1u7YQ^5zJBoRdcv>%>$+Yxp9cEyNU`x6^Ms0)3Y;)Sq_sLwt8c zhB?Q~h-rg>hr(BK#+_#UVL|=RJ3_0L;Gq6;CNb?))~9V2eO!jTS)g?M$JLCxdc(&j z3cobm()**0xI0srU!eBIm5Yt(?kA295*&N?!H`LrV(j~zu$9U@-^#de{`uC{gA;=U zPgc#XdQ9vZ;PmByf}!%_4UEJa zi}S%Nzn9clde^XJ93*e;^enEZE@*sJCSDCa4pq?Sy*X?tN~ZL+Tu;8TrmE(~^9E~c zNZU*!PxCG2C746d4GgwSsh_J&><@-kGrExad`>))8*$ITi^B-=awgw#{yEhyCrrF9 zOcwPU29mfW*WB{>eShAajSahyd~ge!>-mkJujpcK%1~o}zWGQJj|p?8l|vop@a@}= z56Q3ff4rA|6V__!OmXlAa|c8I>n(50j#l3%I8Ptkr;#RG&w{!U$4x|Kuk3#2I`#w8?$AGNmhqP|A0p(v=Md#7ca}r@gWUZlm>qnl0pB>> zQPxyuK?*m!b75FK`&~bADN|n$(R)1dg6%{{JnUw&zYl+n*3365bHO1D@A+8cjS_sGu1A)w?h-( z{3EJx;-7bRR*u2v`hF59(ttQ>wI|eqcyDeQNm0Id^y@+PTj%&EQXlA89z=$4v^kq` zyId=OGb!IB<0tRON=uu|y2M04^F3LgQ|qyt(P~&q6Ir-p}5y_p5iU zCvX*5G3g;#zPFOHXMa+?r?XeMjObEhQYZXO_=a$pu!d=r)kud#r;VA61 zqJB?t&rCvEB6gw#=MST=dS4B{_&i;DgStVbJ*qRSQVlgTIMPa@hg z+Em5aW6EPvqpqWe#m1Vx#i}}9y09YR5`mJ1iC28ed{TV6Hsqsq*<9Jh`RlpNqqDg_ zPxteaDv}y?D|A!F^-H-N!fHzRO&gWZ(huEI@gtuqGbLA(-P#P1H_{Tch_zz+-$tpa8I0sj8u-)k=ve! zoKKU>jCAD@ABh+*!=px0Ymy0)1^(95A1a#4hp7jt-wHen6bf_-1p1%z`0}(&nN+p} zeF%!WbK{QP!+9>o6rR4y{zrYmYzgdGY`58_*-Y4nO$i%ccIIr$F0jGbwAgX=#lL7) z?NzdT+4urBcd+d*FRN&AkgnOS(YGFP+@BurOR{bpJS?MV=lJ0mZ=5^_^2PRz_0PTd z@U}%dUAp=^g>WLJ@`4m}F~sG-*$C!6y&E6jtd*oyIg&N7I>0=D9LNoie7OIR%0P50 zXY-q<&`%nd{Q8c1)EbM+h>LmSSe=;5gd41Z$}_Oz$qPE3C~gxUJ#dJqfvEVCj1P7n zGBTOes0PgjDLG{!w;+m;&iRJ<(D{4wOX8m5C4R#GTrH>;5kJHiUVU<13cK0CR;S1X z*}%BK4}tmUc#IJY4asNJJy(l?&0~wtBBvs1Xejfl2nrf zDEqQ;@N*wJZ?$Pc@*9()*eVTmtL&ZYhxTSyK%k;hd1Du={8`1r9s-vSbwzcjb(~w& zp7(rdGKownBnDo%db*i7&(&Mba%J9uBpk7|(r5F&;2olOv0l`RGt~4MRuYdl?GDV? zN^6ohkycdiiA^XTEgCK0^)oP%qk|(toD+D4PTKvo!iqgBK%x7m?yh$ zB?YdpZ6Vn3nEzoQBV~_ge_0Re13`)#4d^i_#+P=G*U4?Z(hqT-rJD_M(e)@D*KdA- z{6W@{dd)7ode^RTe7%&_NT6cg+8=&%@qNNQ=tI4S2@jiQNUFbF-%;`w`kWTs*@*3TziOOhJb|i>vQPZ@Kz%uT zJ8Mm1j6zq$$n|&=uN6d0vq26z?m347Z{BNs#15Ulm>xD?7y*y`vhszPJ3U)iY^l6(yns3R%s2R@ zd7PbojeFhF8q(V6l{6PSyE0GFoD4=FFSgF&amOXvMA-u9&_(Cv9ZRVT$^mw9lS%`3 zeeTbB;~y@!KCwP-N2EXlNtyi=0}N2gXZmwR$hCDYMEN{SDJ#0^LCXg}{e$3dRAZ0` z(~R?xi@`@rLrb&}SxDi$y-&&MVVB5^moY&rLG(glbJn@~xdzf4&Ujk5J*bhDrLyYR z>R)_pyH~xGhOQ0PveD9#stFO}x&84$5CJ}hx7&3L*Si=ACKw?~*47)OudUG7eGiV+ zL`A#?L&PvTg)wh=Vt=i4OS<=#=M`p`~aneCW+mf*s{90K0}+>M2;Ms9>-F$G0%9W0GOq0FE$$w>ajb ze;&(WGGSc%eI5$~BiIJx`d{~`0^gUf7~p+5=Fj)Fxc3;?z+d>l+xsKdKkmMp^YPk0 zj&V$YYZy>b^Ny~SvL-ysYfU!LZqq5ge~ zyPX(~o{BoPw3DkPH9yA_jwdwYx2dVAMO`hdgf(U4{u&PaB}Vho-Q8K3lhez~i^GeD z!^zc}lS@cQi1P_ICpR}ca0k1akE8nwZ+1sF+CP*0V;&hxH*;4TXLlPXN9xOYUzj<0 zxQo%yTt4WZuRnBJdfWW#NsexREelv6=j9bnE{-Rh|C}2bDtdWVSl!0k(q3Q2#sT0N z@CFi<-A<`zwzP^qko?TI4yo#l=GjvCVqPcdTs`6B)N@@nl|tah}q@qIt2J&`tuDO zW6OFYg7tAQFeEV)WS(k!V{Xmiq^piS`nuaG+|hz)+_D>wqminR(Wax(%pRr*lhNd!&WW4)wT{N(47ko6R4cNTDiDo@GMqD!sP*;B?;JFR@h$(~Kc#a4`UxMsi?Ssl;T|$_4IZ)Lul?;`m zGGHWu){n*(Yocd%$4KfG&*~^lBipw*fA*P2 zs7=9PP=HH@Eoec=lYi&Z|0Vs7N5_iMSf9cD+w&Z}G@ne9oUjzRVivxhPruYBtVxdO8G}DYr*>$X{3GgTG*BP`@StfjD za|GC6!fuC)_z?WLPc=5ykEcI=_%wUyBGN*p=z1piJhkOz`0*K|>+fxK{~QPt>R6bP ztFHUK)SKf_%`Xx=wO&JZbH9gRZ<=PQY_g(s3EU!Q!~vNyFF(5@xKFaA<#~4EbadR4 zgpe3u?fZYQb%5p#FTo)DWUjseyIwUQ_G9b`?7;JjJI78Qz8A9qTPY<1GbUpGj;)L_ zyYP8zTnj%&WXKBGFX5l3M>h&@A$1H<&zgT z(tRR!nHw+80gbloJ)(jUt^T)b^nca}g05pv#9M6cmUu#dKNiO*1RKH7;^C<~u)(sf zhG@DRnc7bd)A}L&Oa&~z#r1vMYzy9p0?ug~6e{%3T7mqLPZYp)4fa1veT{?=ZsDH8 zjSmd|NO=;@(XNs$~&2>37G)!%2l_0TPqWFAq02|>o)zxl&e zj)Gh9=iL7<*^wZmQ>F%j8#PbaV*Q7hU?f7ML<4sGOn)-*54i-J3yxN_8$17f1T%Ap z)8$Mm$Y~K1uf3EqNIj8z{+NqpM}W!x&L4RRLpq668_=T$_&>G(S=<*?;+u=t(B^QH z&EM-6)I*=z8<_6arhc&dL*|{$1<~Aj%kyS2zrjCea5opcbaMxGqbt6!{*gL{ap+v1 z+~}|WlH7ek_48~PcPz|&KkEBU%XRumlpu3h~9h&=o^39!rVW4v|{*G-tq>!_!C5Dq`uoy8sD)`jrz zu74csD?N0Q4d4F=8krhks+c)UTl{*xXvR*;j2rW`i#0t}M(JN+pm1Jo!5$u;wJN+~ zI48iE8f4!&dK-_Sa?FTPk!AQ3fz61Sx}%0+AyNBv0aq1^_g5B1SAgSdC{_CPm)|5X zV=iW~0wn}-e!L6BqCTs?feLWO|A>RWE_vv7=ltR)og~5k+Yiuk-N!Yc>8TfU!+$R9 zv|yMn=pwbZ-0gOD|0jQ->-k%e*T+j#Mz4R)XCR{koo~GH^%|EzwG!Rhp3_GkV}q#c zysR&-xS@Yj!Y(xU?b(yvrn9KXvqjR!zc>ZX7|-YGX;H1l*Z%AC1}^S$YL)6aQ!!v} zXD%kezBES97=AC3Nig3Go|;P)zWzWG1M`Xx>h3$*@FwPu=63-|y%_ZV{Y~C7%02-U zBSdW^&0F@$aTu@VUlYHVAXUG!0L{XE>8$ppt_^@{KPn|fuXxh$si<#a(dD#ZgmT=X zeuaVcw;!`sz%ANkTRjQI5v2Q3OhjqQo-5+l{{tzQ*YV@Orbzd$bd57l)6yr(Bq&z* z%Eu1hz$f4td~?NPs9#CGxlKOlBZD$%mTqJWWunWWTU%VR`dga*5F1l-exQwsuR(L7AcM0Z zyuA9KsJnhi-JAHHn5(I4zNAj+l}v&K8jXeVA0~V79C#|$T}8pGHxvK$SBO zk)l|CznQ-oN5>3I7B}k7O>*^YyqBva#tLORr+R(mjsX|0>jKn&1>@hllBuuTr~#Um z*Ojp-MS+9Q$Js|NkXpQktqVHj}5M zLOvVHk`sO#qs100=MXwxWBI0~`;=U&(BUTM9i(6Z%rPy^+nH7Y(y@c-uOKs@mTa z!w8w#ke?Rkttc$va&|O5xTaAF1(6%mCer`m5x3|90KLXXlkdK}+6uPmQcuz67`6DF zBvB0i6W(AJi_}_2ksC@VhwGGgFTZMwu!(u6ETho~VKZ%R-FqqFFQB>&(HhZ&u*l1l zTV~^5ZChqczNUw0*1$Jrz@h{<2Zl4Dns9E-Jonc#U^Y?Fs~NP5_k=OWonlm2Jliqc zPAet^zs{#(1~1(|iUsyx!DUISN@A5#3@!s+P zo(^8`u+x4^!rk@eh1th=^hqJ^&#qh#HO?J?;-+r@C z!xUn_wddI;+G>80%+_mn&fR~Lwc6dqMaz~=Wk0HI;*(vQpLzSrrFsEAIP^dzN+hRg zuCTFbYBS|k*%QE%_9#5La?Eu{J3toS2>7@6tl)O_XRV*7yCV*BEc)a4sCO6fmwO?M z-80gsh8zy4AK$r8zYntg2NkPh1)N_VXDHKa{g;k(IkQbZTBs>6b$WSlfsn_Bb~)MC{N5K8=11aFHA_@edq<8_Eq0K1c}lD|_EwWy*Ya;2!PK$zv>IsG)rp-*PBZgtq6rT`2ctePQI zC^k3_Z>+YS30w<-^=I@=S0-}kYp04kXD#=p^}4Dpgqe4u6M0~${nDiK6IUgEHPJ%p z6Beq4T#HbeIDQo}h^NnN6Z-*tNKC*j!vMJ6hPFhj<1m zif3_ao!%p5C+0BWHmkB3l5Zgu=o6f{!*U{xq!6)rZ?bYcU1Z{LvNkub`AJ5jQ=EPJ zC_z?9SAY5pI;?W@AYfh-0wOFq{YWn4DJ8*Y0t*o9FpJH#pn#OGXAExZm-essUIg1H z@PV68__R9ia=VOD+nlIhD>b11DTJ)?TAv20_fIRBPPZ6LZ7<0rxJuGrw=o04 zxwA?i6Ut;u$U=M&)1hOC`C34>Mc*3ZeE%KVNWqw3z{t3tewj! zow(}-md|*!Gvlo^qc{}+=dm2wO3R)N$JfxNQSGF3n%*um!+HLRgy(aX`{rbaHi3@) zcvmyKV#G+`qb=VMN$Vjx9AR*Ur<&*LI@Q@fct5w;8mmIjGAUAg<~ z<~A;hfSW3sgv;e%9W&&x9eV^-ZSCaHdn&VP4?o*ny~jTHHYLQ&heU$NQi*6H&adXY zc}9&BQP9Ha5$kn&cu=-{_e$*6BSu}aAt2Ge~+ zTF?(1NApV;tvaio0zGs&b=iu_SI7$W_T~Df={scz6WMn4da=!$!F#ZNb|j+I#whs% zzJ|%hVV>WUHJzoYgE!L-79Hq^8-*_5j3=%!?tV={6VCZ zEo|(41VPsNe@PQ?>KP0tRzN@XUpYw8s_~!Sx=0coIq{j{uVqn?aZyUDyK4VtuLF+4 zT`4M*$;FVHrrJ(B*3ymfQF5RFjB%>^=%c6j%VWLVd83yL1;w)(O(D98j3CeTQwzJ? zlixt6gT15PIQ!%+GS6=v-*v6aC8hCY%0h<90K$}YU22%@g>LB#-I2t3mCLrFdN=)w zX!&5e7~?|!h3p}P;MR<+$Y2If^WbC*Q8BgC4c=&agdOy>5( zE?U4_BtonP+{kOE@nqoS-;m6e~r%w6|JN%xn8lE&&vw3%qrYPWZM`;Vh< zDi(UOQ!M?sGU|HZ_uJQDyC}#EWqB?Y+#4=vJ_>eQcZjZaWR%8^{-Nez`n~L3_xs3A zi}sC`3TuQ!j;Eo}(SkmX!Xp}=z2(FvpS^A|ud&$aOvr5g-ekuUPzN2}N=M{oh1UY* zzNMUyb(B$@nD70i*)r#!KLYB(D`EKx#)W0IBHD`s1rq2OK08p)E4i^so^sQepf`i>o`)ri_GiQD1>F5^yzq}2;-?f*hwDRNE zTi4|^yzV5vG(vVw<+FxHD~Ilw$GIzDmcNhJsZVYJ8YMIVV!+ zeftu)`6E7MKsu^8>EPppaXnb&v}M0MB7;{NvIo96|Bkumex@sDtW2P>{aH^JuqJfv z;e-!#bVF%vi4)9p;9hyfS|y+SM0TaS6KT_2AeTG z3gR9g01;&^*32KxwAs$dA1>Hu?bx3pYRTBiuCkq$v}^F#OltaZBt|NM^ldC#tU8Ny zux7c+1zdka1NaX0$?CKYMm*UYFXs!&?Js6dpPD7IXvYfi5KrD`6Fq zqx(LW(6q$71{mo##x*6~9-=_g6O}QOuTT#7cv7>}i?F1N^NI7RxHM&WJ z&OobmM4@Fm)GE-_g3Vc|PjS*W6)ushq!kWYCM0BSgQ*LK~McHr1R!>JS}I_!)2hNvjd+M6`PrY<~)UXImjx}-<#LC*x#uZ6&l4pkiQf|&S!(2#L>FS zH!Hv7A}%!NNkoT%U}OA(drqEXs@fW=T||&5Xx8$)gP5v|wx99|$Yy18!bv`(fWmSl z37%9FoHm+_V376i0l5Q?m@ygB(ZabdJ)&=>k|J){(9GQh%;pJ6nK=&r3e zZf^^O612ewvD<33eA91ILUQ61v^7H!yVDqhj~e+? zY3=mzL*t+@p`~7Z&DP5BkU6|~8A2o`2ub?ezIk*G-BwF-R&jO_aJeUAU-!>4%^}lOstWRS+gxq#QzG7#kur>LMfLT ztHY>G({tfr+oQG+S?T{}r9?pf`}p8wO-elIA-g_3fWoQ{v>LO?=PM=w047KuYSHuI zsj9u{wofii;`o>;O_-v=iPh|rLB^-~>jsq@S9eXeEbL~O2 zO;Few)M-_*IL?wSxs47_)|hu=1dn@o-_on^d;_~!qcq7lzD6X(I48syt9Q$%a(P9Z zbFw4U0q~_gzi5N=R+dzj65i!VNT&>2T8<0si&7;enLxNrGVnDb?w2#&r4W^(beiLM z2>NlAdR%(v*h+aoJ(As|=yRHo8=I}4(c~(4%OXjfL>=l zpXms+ConmepeX%&@Zv0T89xj8c5~t78+P*VnbjVan?O@|EaRH$-6l;y5Ls*e=J``% zRJPaAYzQ^(KyT93_XiBG;$_YH1)wwbk|u)dFSFFMQ{!&C?=Ip92{7{LszDISZ-P zJ}O#raww*4_G5jH)xV^AKhytx*KzTJ;q)Y4yOh+8D-2M~8i2!a<`aP0h2`Wk>E(T# ztZDJ{@BIedUB5IOh&fGS8n+<~$sER2@GM$i)nYGG|3P0RpOxVirM2;7GhEOJ-{pENOR#0M<%}CEQ5_(24_>Jme`1I?bYghP^=u2gB z%OEGvnBN{Tp5H<$OM-l<2{cdwmU+B(_R!5xs7yk>8$-7kA7Zp)EXQ9>zsf>Kva`+= zrCqGgw|EbyP=;_}PQj0gTJ*f&-NP!iyj}RCG&g(=vs_uzEATu9W-X8zaWR|}Y5}Bf z=GlxABKg#SL)8DUid@uNvcOMFL$?go54gm?)Lm5~Q6noVCN`6^F;^9SW^oXlrBL&E zDq?kK$GH^!VelE5$Lbr!Dm}q7kU}C$wFX6+OahKpM|aGxw-I*zL6+gVO0nN$`*kXQ z7Wxb?tynj2jD{*Q=^xElDWq`ck9#6Fbm|MA-s{Z6wH(eLsdRm|8#j%eNFnAa18$zz z8h0|X3oQjr(&vbdXD2T44SKF~H2Wfv6(@-Ez~K@vT>ToeP|ESmF)tAD7>O}W&t$Br ze7u}Wq~HtCx4g}LweF4TaT&_7?pmnJ;~Rg^6ZwkE5J#2$GF7wmT3P1gS8wcamBu-~ zMtUZrc&_p8l6J99f8cMxZHfG56IEO9icGcOu$|*-+kHdAf1L&||9Sh(OB~)y0biwk z)-CM%Ymr{b)KjKBM*XT<1)b7wn+^x!qh0@;_I;52t{HvR69Gq~JfKkhr6ZOjNM5Wg^uO+lyq0y43g zfdz$4DA&<#MkvRHe&+g6_pq9dHpD=>K<>vru(utjsSHT+nQe73@UQQy?MGLkmy! zZU3RBjWu-kR{V!rv&r}GPV(_dxLw;~jZGWK_iCw zdY{wF*R!QuB)zPBQ;Fj56`StfWljbb3)G6(UKX}RpYU`jesA!anP2{gDdKNz!*146 z_L8xgJF!fueVG!FvYX0mezO?ViBh?h8!!Fhz}G)tvPIOOWF(5|Pk;tr5FPqn&`(@$ z7amXsO=2^V=}BNI$m%%evs+aLG9w~#Xe&6lYp_@M5e%G-W}UN;M8J?*y(J@VQ~l2X z=Rj#UrB~q3Ke~7RAG|K*?;RorvUgSX^9JIShoM|W&1Z-5ZwrpdV5{G-rNxu@ODP3F zK8d&#;!H<;4ZS6*5Iy+4Jk?UDsAR&6*ZPE2o^f+z>s+bHDx#Vz^${8IUU7L|5v)9_R?xkJQ zgy8FG(}V}K@#C$`AfT}=*Gxt@kHB*PO67VF7eOZl8;JcJD^nfSOJ>ts*O7R>leRZ@ zz+fKD(U?@g<@1SVsUN6+dOC_V>84f?bk0VuNkWm*=U5}R z7O;};<~9?>k>@P~r;lIK<&aeUJzkLK|7}M2F3re(C_A3zT2UzX^EHy*pQB~8GrIZ& z+H4fL#UW}mic8P367yLn^tXTHDjA*}&xt3UPU^brXX=&AaC7j6E%)ypr9Yg|euDv*w*iZ=sp>Sj}*!3-|6fp&4vx@R46K9uvMduqb z02lJDcG}gXc6ZKo=Le>e|B)l7Ji^3@1PNHZp~!s0!GXQrxU2|4@M{@D<2Rtcwa;;X z{3H-_J%88?Ak`)(@x+d!iJIo_=6>Ox=}1F12hUJkFk`h2xB*MUFk}4jpsK-uNLca<7&^JV96G5eXnyJ8BHRae@K7Ks+XOvfmRuBEh$@6d$sOD#GD* zeyPnS_Oc*?)M9RMBwwan3Y@r0Mj4=$>DK}|Z+45;C?uZdbz*XAK1>f_X~vF<(O4=Z zg@K>8OEg)Qzbn{B5mxLIb97&@i}WTzy*7=TP2j82@XQ=fja{*a0cZ8Rb&w>dYW_jn z7Jpo%a-o-RV8w^|LhG!@+yNU$r^UO9G+|GlV*Wj3cpzT|$k=r!TddfS9DD*3Z9~0DcjnkUxoQLM{SvAiit`UHxfX3jFKR9hFZ@S~q8(_$8ot;?7h3ENn?{g;v**m! zdVHO5Csb#=0+e+j)h!a`-l*HmCZFF0gdT#AF2;>wDS)>kBXkH+cv*kn|%@|J(9o z%;(F>Ogd`$Lr9#6wP&$rwsJZeyRK4`l=Qsgj>!a&Lslje)64X$N&%T(wDrp*d|?G$ z`q!Fn{0&qIv1CUl=|nZ8I0hi8Ot5^gCngq1ff|5h*o)AstqWon3k-s@D5KIhWM8dSeDueX`zwV^lf zP}Zb2#q3TK$Xf1;Rnp9pf3a>|M)KrX<;3=s&@E9{_vqMhnp~;bshu&)pN)n2+ff&g zg|at>_7+7c0b+i`ZMl6SQ^0I3hU%7{uu^3mfiM<(heXL1masQ2dX4{eIBKC zd|6p~skPv=P^Jw^78mm$JLRWvHppc>>#2?dCFLj?cZ{Q2<*YdvVr@y|m7;XiG?j=1 z(S+R|{(|JG@I&6D&2-APp77Kxuy7Ib-EQjBuaf~PWUDjnf(u8TG=pi%_GC5-xGnn{hr|Uau5>hS7%yubTL9$^Vspmx-u;1# zGRj%g%ui+LeeLy5Kvgg1NhS@g{En*gvz%zcNBmPI4!%U7c6fS`pQPwh6CftTH4fW- zL3@be_~HCBt)xRtrzYAA5%=m*uYf~^O8}bR0wCk%5*!{jIFD-94FfZFUM8DPwO5Wdr!$sR*mJ6pa80`I3CrL|qB% z=U&_h0-3C_7Y?RBB$_zVt8~v@?vEd=HMrS)l%$-pdV%TiDSo=yvbP~4sj| z{Ck%yNgajN&4FjRzuI5B_>u_H>zHA{Ab_hnWTtJ;Eo4$|=Ias_=Yf?J@w}zhm?mu6 zM+Pprh>%|ca$0O6o``r~%8dus!9bbT*E2AMPN>3im(1W2jeSX}42)yULTnNV@H4VJ zHXmMVt#NXWAd^r5eHHWvLcR+Qu%Cv zh$736XP`tC2{`3Ev)T39Q3q zy^2+=ogFqL_uH4fes$YO&{u)OxQ=b2%p}=R;N*h!W8HP>pZpKy6NMA=l&EM(EAu8y zoR+e8)^5GT68O&9Rl1{;ndOlzW(tyZG~PdNUb?6DNa9S7=C4G^1Lhc-MA!mv;h|qX zkpd|TvsOVeVKKL2Si(BBqS0(+D*h!-M5NaWg%2$Y8eNL%(U zH2QD}r5Fj$)YL2hLM)!XN7BNgW z4!2I#4!4ClgAYw(>?Rx;daReTA4pQ~-m>VWq>)v$h>NqVP>eEa!b$M9Vptaq{YSHg zo}S)^hn&2;ydPbV&s%mSeEd_#WoW`U^5%o<9w#DL7=gq{#HR?hm99*!fU^}Z1*+8f z;R2R)PgV_w5rzQPqgj6li|sQb0u7*hhCv5W{QS%hY`?$xqm_1fcO2fQBj?lpX=Qkq z^o)OOy|7*>f0QCW67}he!mdru*E>aR1qy+`^S&3B%5wTZA&l%`L3AwX9Hc4n;TTWTrXk4 z02XPbMNCtWo8s$5A9}aLhyeZv-Znwa@@;v-iAG`g$={Zca! zY0K?6Lco^rdJc!{+SHOlnQpN1$HW&7Owx1|R%ifq|D^*p_Q$9xUv)6j#FtP!Z+BU$*A}$m-lxci4D0>6u~as^(5+ZyI6~obDvGx6D=VgXYON%o&txt313v*IPZe`S`on zf?6MEYc5ca-(iZQQ!O)TpO{lIb+lOa!iZUu2|BCO9QQ7-njwyXmHKA*Uyz_%@p0XU3&aKK5HprsDMn@&Q=)vnJ@;l`Lazt6gJb;?9%amC!QawdBpn9a~rwmDTy$NnTrm zoChGD+OL3%36KIcF0&KX^Kx*SMQ>_SBU#S4YdS%2Sa=OCD&d2G8GkeRt^Ld+#&tXvE3Zyg*2|z$t z!(og##2c|JMH5Dh$9Stv;pflo+`U0l?B(H;-kOR1vt;%=iMN0pP2mD`kEowLpM{wA zF};3SSew9F+AkRWd5?I#3-T3g^W$t&0L`u#o!Yy$%}!Ne961d%u+l; zq*h_BVtb7iz*BPZdr?fS235qI#!1(Lqk2-@U@KuTm7vjLO&@V2i*|)oH(fr0iR^Rd z@ODX@_#veroro7A*+Jx}YoYN_9>A4VbSbX+O7cE~pcc`3dkLK$I5w2rQ`QqcMRj72 z_Qtomub62hlqWSMB0A_1oWQK3Twxh{I{N8@c=R;IN;DLeB>gO^H#AVq*V7wk2wz{3 zke%sdfAxNkp84t4Uv>AdAW8bS_kkKm(!0eOD{+uW@I7z15VO&ftol?}e1f7s`Crgw zu~Q^4E4fXs)AT2C@B>DKk10XGd^^K&E8YeL% z$8)Lf=(U0CX&-YZ?6cOH_+_=2TqHnwyv%f|7E!B(X5=ebSRrB+4`tdE!+9L-@p6S| za67N{;$C$gX(NBLWA~nEe(yd7a>N@tO`o$hS#O+LW&4xFkiKd3vx(9kjP)aZyC8jO z5e6x@MS@QFgi=zUe$!%X$YOgd4puq-t^IRS+g^moN?Udj!si@C#406B8?$vi=j@_H zxf)-yLUYIh_U+YM&IbYTFGjdC%mUv$6^^TOqi_l1#2eqevx=`;uaHlTQI2D9kWP&ihx?B+31tZe_~;XTj`U+@mIhv&uK8qKxrx z%cs>!t`{4!gA+dWWS#^29=eX+8}`wJHgqZtB6J=vnH2~Ofcbh}&P4Y7{9PWv1~6P8 z*WUGi)DR@yv49?>xI$BMYPW|Rp=BkYGi$0AdgEz{MV(HCZ#YGCGlPYFqmJHaF}{4D zu>lLbzjstM>e;wo+iM`{B>z|c9DeNAq3_Ad6DPsTd-;#1wJduRWw(p8Wt5~8WTLxs zfv$cU;yM@j`>l(!m@SlBR&0!Bg}tuL4?0`yw=&|_DLL`}H2*0S$q@2=o7%VP?)5hb zIePwR+=*?eQ@N%s6v&j+!Bh|i9*Bdq^BhM(py4j>L>kv{8*VsMruFE=f6jJcLoj28 zKBq|1e*vu1l3_W=E?y%*y3-*tTrUmkwWQ0@lP{8_mcuHH&Wexht?@>c_wkiVKm*%D zB2{lu|D=6>bOw5j?~}jbzv2&e4U_zN;~OL^VKW)ENB7Zwe+!JCs9n6EK%bU3m~J|3 z-9wvA>Za6icSG7w;mMHyKRP8}f4x0h=c)gV_`BeBRV|7KsA-W);W6 zEM?%fp4;a)PTV$C^;^JiYoy-`ZBOE!DorpNrj;-;#(d@Mosb`?nX7JW9)&BMJpWOG z*~}BlgtX^yv9LBfeOYJ;+ zx@ilmpRsyAv$C1ZaW?Z+&V=#*DF-J39bzm~xj>>O$MbIJX13?)2R{EYLT2qzd>TO0 zSSEL(7vcw7NX$d+$}UUAHE%=e2g>}8yB_j+?+^WZVvm$~ZVU@S73soo4WUL%^Yq00k~+u zEer@0FIEdQaD_ci$#(SU{JZe|>qZaiJZ&l&F)ia~>nbK#8x*;_6PiC*^chU<>&VX_ z+e)r6{!{9)?ilUSwZ@dz7ew`y7$|0e=V7~QE^8ytX2YI=@jNKZ7C;64=HB=Yz z0J-{FxJPGzd(c^zBRrGf`Oq9_A=z(1E7z_?6GS*n-OntQZ6xJWFX5}ZO6h_El z>+1jjl^TZymVN_)ipWwHD#!7TzWY!A@xK5RN=`b9Ed zHK?~1iS&1uz~+pE0ch8}93a41q<)UND3MRW(p-1kJTq~*)k}Y?t2FI}EBu>5J=mpr z_O=9qK91g6p*ubI9jv6zx-(we#Nl75p-|bMwv$3af#7J^CY6$=;)XlDC=N3py~?R; z=!#4HirZy{6At_&s24f-@vokgpZs`&Zrc*whBcYHRk-8OXI9F`KlZJ_!np%wJ2R<~ zdtYgdBMUg-RI!8Ne!YT)F;9RvmM((F>*-}%nY;->yhhG?Slmu(F7=F#>vs(x8^~9RWo^n+P zj|$mm=AKBukJvls5nEZ08kB$8px($~FektRjSFx(DzB=wLDu;_SvFT{HkQ2z-VhWY zX)8Cq>}G{?>>JkF_TScT_RK%8MygF6z^E=W_N9Tpq-68v{gL^GFj&4M>dj@<%(7K& zpRN4n?-*~*zIcN5633ecis;BiP&&4a&up3KNU1?5uzRE<(-e9VnBfgCJreZ-`)VjfmGjEz78yGQ=1NJIIpZdOT`j#F0}E!<$d<#h1rhkxXnGoaGX-8%c^tcrGRY z@LZR5;*){G47=rEi*$w6_pA!fB~#batw7CcP5ols`t(^}5T8QE^a;Uh$GHaj%g$?{ zLoP-Fb!r%{U+U^p-w3v31~t6PQ(QS;h3-0w2l->)?>(G5tD0`K(@tVb;qJ+yFIk4= zmsp}(Y2!pd_lr&Pn|MF_CKIwQF3@redL2UdD|RM`rY{gcmsU>_3&$gVr})eKz}(sW zo;$`_F{el42R<7`Be|VwJrz2emLsMj7Nf@@Y8OpVRTZC44tEqXSgJ+GD_pc;UBf-q zf!EU>F98a60<@E!y$B{ZN0-NArCM<3YsINC9PXiXVITe{ev#^460c|^wxtJ zV{t03t6lUyuCQ1GzU?HSmzGu+1FXe1K2H`STriM1=H&D~cpHnVs^zJYl7t?ZqG z{B%_&6k8GQk+$kU);kWZ^&TsZFVBST+YT2M=g-&D04-xlTNPGtTOrT$qI4l&IbdDX zDcn{`=|Zkyihh^P6$uH-k6c&V_=Vi;!>wV%l^v6s`Rq)O^|#}Bv**#2U2Br9M35oVFk0gCa z?N{Wc0G(4k__FTHK3+1H6$iA16D`#-qQuyPSj3(mpm#DRmfNkT?O+l<_`<0YL(;5) zs9zYDIZ`nbDzgJV;%V_=8HPwQ`?QE0Py6+~VaXKqzUw}{oIbsJU#9S7+r8ard)|}t z`0inJ^N_&=f-#UTOEvwMLb|@S@A|UZeBzy}8sPrN+zx)N9gdXkpxP&{Hf{ zQH+nw@mece;d>K@v|OiZ(Zk4fVch?PDn$$ho}5(fdW}-;+bKNN-Qm#~7HJO@Z<+R%j*#VZ0Z7NkE^9U8bh`nRX2X>CvO z9%v(l8RAZCyOr)LLx)NkvXPp>#lvX|P>M%dR0B7j^%R34)b2{M($>_^Z(I)fQb zY^!YK?hak z411EqxE&aY1L3t}=7DC8- zZK~+hUdK%$UG4TpHB?I1^&&jca4=FpeO9@%Pj5=n2mIh%SJe~+;TF(*veN{fTb_e8 zB#6Ne@nq}sFg}K?8IKR~EFM8`+#BV7UOglG>~mZc$cI4J(i6_;7Cxw9mk^f%Q;HBnS63 zL=W;#R|${$QO|Jqe%pCIYD(h9OmbS!tcYqH7a50|4`n*>e?9F*JGj{Vo$}Ls2+DPH z!{?`yK}SkF1G@fD0Bj7qk<{8}FIa$_1oUWbF>Hqkz<6EHkN{8{jAmz<@RR4;~Tj$NH%3~Sk=7x?quB=gNh%~G!E+@WSrVm%*y z`;uoTV{`|v+}i-xrLgFRBDKj|Z9r?h$)rv}T;Gx@@I?mytdw_z+w2M#cz^pXR+EN> z?aR&(tT;VmkB>9)H2nNN>H=LEbWe3DnlMznUseo={nKxHD%0?&?RsqjXR zM0XY{D%8M0ACp?TyufSy1{i)&tX8%y83M{TJOrHGnd(yTd-fdEi~0w!zx1pX>6|kl zw-^~(icI``HGaIi=AbV(tl+`_XyeVh&>XMkjNKyEUY+F>0TNHgO;7k`-Ix)-cIOVX zn@~9lS(Un*X)||(DzDk@BX76>^(&mO?pv1ot8)!{h0JE#=F2VX^}!IMaQmiL7jt!^ zRa1fo%G5o08KRS86HveAmY$eZ!ZWR60d__Q35fQX_qG$JskR!(on{{H8Zq+7AqG5G`Vqw+C}Y3sO_; zUwf2B&wpr^Y{L0wba5Lb|4f(LIA&hyOs?c+Bwz2X6D5cz9wJ+H{|X}EI%IUcKZvY6 z8 z1-?kuB4-xC7Uzd^^y!zWk3(9Q$s-$MPIqp@tSViE;-IvwjLQ`Xvyk&ed?QBg_STXW)o%=b^pAG{Fgaox27z`1$MTARxlrj+{zr{_Rv zIrOy$p6mnmu-9W>8g0@1nZjFhIJ20l)(Ir@^}ZR{fcFWh)YR4^Zd9`H4T%JF|8@T& zTfOohqSx-!dH^@SjZ`*8k}$c%iD9txbcdz`983iWHKDXs{Qh$=-EpVdl62%$pb5GP zd)Kc2m_G4+MekCdwDrr0(gpyc-|RHlYR;re4CjebLWJOR(|mWx(I-kRQ?q}kdrRUk zVBj6IoTN?`Y=!sMZ-yX@{Kq}xN~Nl~z}X8*nn0izF_TXcFCWls>NfM>E1siV@<}s= zYlNnG$XHHk+Xb@i4(~HlTZ&;cqeQvj0LdDL3Y|KQF}VMq_zRT?gY#Ien#}uQi5m1P1Dys6pa25tfDnKRo|_fvg0!8_zZWcs>_-5jIvAR-b`x{#-KHdfQTx?5`_vP|1Hn>vo0(q3!4w*OxfUtA>DYgN$9&8(gfy~qjUEqbk|EGV05n-D)t5z z$fjqoXgMq5i9x5k(jGbDHMncwtwLg+n*NT$HArhV`~?2BVGo`4rKdC?)|XSvl_Fl- z+YWjL{R^G5_O1Y2$F4tRq~f3LQaUYm9M(b$qs40s)^eyBq&8tGU5ist^PP23GFI(#(!PJ z0Sk<{G36eaST($=Uuzw^@p0D5?K2pF=XedHrP z+5-MQ3Dbp$v@P?O9)(nim^@HIqg!tuf<4l(7!`-fLwbfmm`1I`Y?^mJe9C(Ihh_le zY)HBw1bl&ITs1$$^M&ebY}o8v9co9JbG`` zilHKfUca_6F)`5=zHVY+IZ>KFC2|5uij*s5zWnD5z&E!-28)^%9M|5150Ld8*s+yk ze5IU*BLQq24Y#+H{jG~Odf9FoyH^uz#a9eIU*H_d*T`cZ{Duh3Hc0|gi{Fx)c7F%c zVT!$siHNK@Hk*A>hkC-4?tMV- zv?Myu*g)!aW~DpbDheL3l;~=zkbX(_R$|fJIVUXrwh2d=`q4t`t@uyFL6Z(-KY91b z$P==E@){(@mA7UAGFTYpR$bf_ELq(hMcoQfRN5xTv4DTbt zn&I^bLY1PB%1UQZBR!tY{f)6XgCHt!ie1LYfc`&}{bW{vY@w`wWuc|#X3VYfS)mZ3 z^lhpowb6GOTcjQp{fB#hk+{Bi9SsZygU$IgE<20+SInNBG_g8$sPF%|F+MpA!{yy6 z>}y^~RVzlo7}Cr8i=qO*h$JE%H&M`QuvyKVK#LnF0F4R zfstIxI|&Bd+tu8DO|98VQz|M;%{kBJ_)VaEzYCm&?KtFgSg(yMSQIfgn=L2>A8$yM z5H0<&_TqE#o`RFH%B^qwp0yBkVilyRb3h~C7w~(o@^m)6C7OpZVWRIdMTjP$cr{D3 z1G(wOKpjvAhUeL>=y%Yj^H1%t;omXxtVVg4_82oV5O4EFFNSeQa8=9~VD0KqKm;g-h&I3U=M$i?oVIvunfVK_N8JEg}Jj!I-I zhEpqD>X$Ah68@_!?0vsH-HdH_yZyHqP6X1%XG$?oALhMoA2K=) zveitT`s@&Mb=#5yLFWk3L8muyUm>NU`B0J5cM#9yG;y=}^3pfPFk-oLz)xqr0Hqh+ z-}3dX9{0t*bt>yuKG5#?ceB*)Dca_}ZWpw_ltqUEp!CHPf)rlREFU~6eMI8C&uDJE z0khuFe}a5f!5FN+W=++7;V+nl12JnLU{;WPyg91#1(>1E&MF#5Kvsf=UOO+?@6*8A z>^*$gUnUHmO5Dc_)jA3jZqh_p{wp`o{+iHL%v~AMF4sZ&$EekNfe-&0^$WuJE{9B) zT=K_xd1_`ElGh@3hW+|Le;+gNcg$ha(%bJ035@i6USG-SmBjV~vItgFB#sYILvw_$ zf^^;?uJ==VF@2+-`Dys>un^JAI6~@*pMqBY+sH2NZz5V?)O=^6d#58cDC;)NCBLTe zcmPv(;SmsQn7#FEo4ygIwxc6-?6|s_mk@ax$+L@M3jpX=sSzGR!Y!nhdu_-L0!}r5 zLXNgvoti15!8U45k0-r)wo@P=T?O%syfGV-O(v7l_d^1JE9wf31mUSZ zL*3s+epUch+}u0Bf}ws((vj~}xWyq~6CaGQqvOXS(5?+6z>o2r*l_8S*T2v1V*4`olwx)#N*o{HagYGU@*1 zAb_v}FUkRf24Cxa6AlB&1O`*qpT`8ntmh{|K};m6DEN4W8cZi?_Zc4xI#^Ti@gbWe zMkG#zPX)@W)*N?Ia(c#9bKYUcULx8K_;5jO|IO(vr?q}v)7sch%bi65JVB0c=Zp~_ z*M|NYk}9bnOLi($gjxTkjU=EG+e>@)tRtgjaODaWahkR;n48*dS$fURk(}>C>g$IOWA>XS#HY@6L%DI zh42sF{2^>^U!R0L9a$O3kqyQGMrB)3pw0*pfOQY#sg(f8kEz^B9D!5|k}7|VSsSD@2-L$p9sh1m907@UbKNjgIeCC^auY2$i2P~E`p0hr&HqY&SoZ&&e zP9EflcnpgY8NdimD!-q+d_`$GQd-*H0S+y)B8b#Rr(!$`D(Vb;$gf5?!B+}xOr=o|W> z3X$Ts)Y$bbfB9lGD-;B(jedp@_0K~+QgFHHwac=zx?R#@dBOXz)69$1z3JH7hmF`H zo^2PJUL-ygf4bi1@iDqXzCt!v55nzpt)y!^6=Z$^{%adWYA(cO=d{!$oB=Qr-Y^o& zmhd^!DK8@MUsKp`%DB+Fy{p|C3;MYkzpkHeZ$ z8V7fMF#dV2G}im75Tj^*5ALEaR#h;kb1z|H>0*@UBk#P~ecRt7jd|wqg{_1 zs=j$TLLXeAMS0J%mCM@-6!JK~D>M0OPA~`-Pq&7{NC>*YtYT)Fuu6%E{P~)Y&%g|g zm8Bl~<{mf?9W)sa6u=jlcBoCqf&z}5;?ZkKN3SBMll#!=)YQ~PGi^Jb?&`-mn>DjS zZFK57n3+h3%g?0+n;$aKL|eEF*QqkppighaJLJhjbSsj;wZbGUg5#lDquyX@O^SXV z|5$+}K1tw|{PP%)TRyztbGh6OF`Q!4vNs%1?BD0N=*_r&Fd7~w`SeY5zhx+8qV|`% z)P8;@8uf9Dl<6_j zxS`sfj5=!9ZH8`dn_$tWlKLZU_#0=s+c-JNM0NBhmZ6=j=8hl6^dgv!<;nhFC44f% zzOVO?zauMd+K3S$8GbkiPNJPYM z1$D_Kt7`^I@t3>fSO z2@sNsyOY!Yx=auixEdqE33!wU(=<>QxCnrmK1DEdF#=|kOsszLEtBY<6Va*YXPO8j zK}HTa5|v6pF=*8HQ!U6`{>QW_Il+cQI*25q1Up`esZaD{;ZYF(jP*Vq)#Q+_3X1*0bA>bW4)uUFidM ziRO4k4$th9qa|MWB%%-5p3R$yh>DR}-dfn$-VvFOa?={*+&hAnS`>nW$U{yEe>hy= z4CwvD>24Zibj*t4u;vGLTo9oUyb(G`c3eJ8qZQ+Ee){I;qRabrudlC$q4sAQ2zi_> zBQf2}SS*Lj)M%9p6}aUH8G+X^$$JZ7^}o)8d$K&nFeYHV^El=%DQMtF5bs5y{pqUX zwaf=R3fkD9y|dDcoG@4WICV(OMl+SEVt{RArtGh1okr%Nwj{4 zaXNfJJ*px_Yd1d2s{&5~ zT(z;2XJWN`hl>c>R}cE>xbKNDuTfhatXbHJ1PWcqEWi80-^H_$MQK-=o!T zdZ2{ju(mb|c#5k}r))?I94@{zXnr7aowu7oMIMZUIDc=dEEnE|FQG3u!|k7=2Eh(* zqF@39p`E0jj+)bFw4_&-h#(p7?#!pOQz-W5Vp2~i3U*U{sDT*k84w>2h+nXNc}clC zBWJ2_1#3>3FD^QlLS-xhjYETmgX2SCq`3-e#q1pGqZY_CXrSq9uK!^)2UU5uES>vZ z?P^k;)4B0y`m9h~U?j=fN_)2=uRo$IS%owW^*fwZ+6-s%z{Ryl0mfo#s5$Codry?M zFQm^*iK1paUXA7reQJo6{WUNSiFVVOXd3{>9#CWP7=pbQ-VYaSQ1B^S^V;rM&19@z z2k|BSOY$eDQ$y>=$9=8v{B@2mKu+~WBssYvmXaodB+SR7es)xu3-_;4{$vJ>VP1%7 z(kWg@K);iIGR?b`Poc75LRg`hxgVcii-hs#7M7D4CIb;9C=qfC!?ChDLM3YAN6Mhl z_aBR}TBNJNbn5ltR$FbYl4NfYWWGMoibZ}a^t0JH7sF!JRG5h@`(d&pc77lrXNp*R z#`@E^pW-0D8ch@-#NQBexFJgT=!BLBv=4j`A;BO8KRi*3mxD&jsb|j#zkYSi%WU?_ zMC%;%qmx#%{xy8$*>;xkVaMe3oGHv&JY4jul<&8_!wBNjN%@WDa=Ok&BmXsM2{{YP z)qL^?&LS{zY3V@?+yBEh96{r0hr(u^MLS-LH(5FML^|jBtY`-c*zhng{Qhp4 zFGBKHgg+acUbDvC`yqlrBXrvJu!oCobdDNL`^J^lW9kguI9YEB)KF5Y58Ioc)7tDs z2-t1)`FvODTVD9Sp^)hw?58bpkytk0ar@hCWzP-w0rmNbTtsot)=I$cL|>-p*lbVK zFY>`_^Qn8Av8@PYym6|ihgfLy=%bas$bC=y8)FF>=vs|cPK6^s8)erxlo&cufFn2MTNl^98unG zIo+tP#fC?CSfus$Gozv-l^~QjW+kRYTOQ}fz}D`e<@GpFpRmg{60q+Phqlr0TTxFU z2M2=+o&W4x#!Nv^=gzJowP^JwD_Xy(>_=S8+|R%E@_Y3pH*kKNQHoy{*V_HY%^$)W zs}$FP!(V4y&Q9#YDjV5YZjEE;Pb3ypg01^dlpXyjkp+DM@XI zP>;M097EW$zjhM4rCzPiSgL#W3#FZnA|jvtMRl$;j#v@S#qx5L?qQ!i;CduX7neIc z=)=^wMtJfNv>cn)7z&Uet}iYW_s~wO|7+B-@95W$GO-VBSFz*|QC$E=`~%D|C~Qv0 z5yBp&yZ8^m{(+pID1Zp^Rd5s;A*xmDsc7lbTC2E& z0xtADx!^O%%QK{*PcKmY>FQ-jeQBU{Fr$V9^f9oqwz=ckzIb6fA$;^<%;lZ}Ppl-D zX@)r+0$`LX(i`oQ!x5j*&i+vYX`S6CwM$G!i#b>L{6-c@9fI*9Gc;@Egg!I!zEe>F z{ms-CTk!ggi!5_04@pyfO~e?DAM%2mm+$XKqM$JvHTYkCXsz(J{-2fZ^lJ29%vQ1^ zT7D50ie6|+7_Tzl!r6W_#jUiMBhBK!R4tZ(BATv}KripGlDBxg{XMrmzhnXJEXI<5(Jus^4Fzepazn66Z&Aig&@l z?RG^f-fbnkw!v_9G*X5Aki^HLyV5;(ENumDJJRdtSnDs#r@~YF?aU}hRCaS(-}~`2 z7C^0SFs11l5x5`aqbA8|*&Aq?zf{_ACbO0O2`VrB=%zfZR@QzQ*v$94lq;87xXL`b z((I0x7Jc=N@p&o-P10NC$2>b~48$0GUXqRzVv3`vUTQoA(SM&`2>`)lU?>g;2qrP& zPvNxJpi9>pULoi-09N|xc-)dd1(WntHbsmd*pOf{5GaJD)ysgkDnJM-BO%LHa>6PZ zZ+D{U`WodOk06tL3)dx=#O#XAm<<0hurNgv9%C*6O{xRO(?a)-Q1e|8X14j1ZhQHs zdzM_e;=E{q^oGj5K*gKKwh4PJg^t(hiY34(3YzFns>J(Ze!JacsT}FVchS0RDT8SZ zAq-Uw9R*nSIIAS2Ee%pl1;FncL6Nv>=W>$^6;5oo(k}}KG~2F0m8)U%dhRc`r(jziz+y1eyNe0w>QFRXC#1JSNGQoy z=qz!vLAGfGo2;sB(Hy_Jw)&i6RokO2PXM2inL@vhv|hcOuv8T9wvdftLrQPJef5+q zYtf7zS1`9vZs1LW-$jG@o9^^4tze+zs;J9wgpBeYvoFxFIKnbZPLjcI_9 zy_d|O!sSyU{nx1yP=HevpM?tp0boGr$*G^-o2iKbSgXjv{wKt#A6~<(?~x*cENF65 z;Ssh2AQ=)$DJUzYlA2(eysDFC5a^yl<cvtEiqSmZJ4oLg>y*c665 z^JCI$FKn@JSIp2xiXeU7V4>`U^yTGDCB-sDYTk0gUxsmvTF5{d)(Jt;hU)a|rz)g{ z9>ZG;uMBo=3VDrg)A9J6@|1DxAB@{A#tU?HKfioSu?qXnY9fjF|}l-##(fi^{mD)EaD8q+)5RW$c|QPx86?S(nOmQbc>$(rhQ zcpP?c7c!MDbmrk?Nni(%mMj%Tsxt49rw68de48p|<1i4E<{_rvxqG09TfW;{jGw(6 z)2lJ-1zzV;Et?B|FH9?ar=KQ&NE&fcY$TV?mp;*=-_>4$1;q(ah6>m|ZdmF-!|C5$ml0I9N9 zfhya4MpA?K*OjN3!??X+Uox(LU#0X{^au(lj41d5SY&-i#BwQrNO+*I=q)lUI6wr6 z?MPYXGLTES>^`QCHk$5vI&5=`%;J7|MvffRbg^jq^P_Pam4Xb@;!_CSCQ$c3%N z_io%k3zrr(o?okaFH*-XLSkdd*fX%XiKoLv-o$urP}pR_Hfo${)8Vuwo=w#Z9fik< zSQUmGQfh6yPRU8kXuvhgNaAxffn`voE8Oq*Z%MEgOCRczXlQ$Q-g4iQ#O7OBHkgf; znJQ36!nM>(1H4uKpn6V_1^@OmQ9o{zD_bcVu%lc@c$e0XPQUSUD6`1T$F@Yg%MI~e z7R9;`!Jqof=%Jh+!kvwx>t*>BMMyo>oP~;iP*lgAVj5tE3NSDb;8&<%EaWg>kJtvq zE052OtZgaemxGeVF7E?IZ8NQmzXEo)gK6_6UEREyi17{6*llIgQtIa#3pTpANAjn8 z#~`9n_mPKxUqFhRikOJ#hkGwWrRi@%!f)URb{U9MhhcqK17CI=orU$MH*4kczGMD| ze}t0ELeoz6KZzU(!E6XIV4{zQgD?&Cml$~8_M2A}NEXO(n@_-^Sm=ouV5r^k1NbOW zLH@@e21JnZ2M0}ebaxnZ`EctwR`q%m?VlS{J2H6h5KMf%H93ELx_MJ+zRo6Emim`DN7wc&^`=R_PcTkmnKOT-pvqJRYAfA~SXIYd%4t#~Id z6J)nC{vwV^R|20Fw@W@P^h97F-ibDhI0#7G6dcsIg}OSQI@CN~*`|WxvPiIqiNo3B z=YHLFF&ApW+e}(bhd1AMOWyrPVN9~n;gIGNp%0z-KvbcodO2}YuW!)Hs;s80$`%Gw((QUxJS*aaS^T^2-qBGPi6kpu#f zAV~!9H#{X)R+670rmydjys*RiYe{bkKe~C~c*syHRLQA9G64HelSP>G{mW+47bw{i zLQ#IIgJ^Q&6iHjCkrc5NN?)4Oc|9T;oJm(Nb-Yp=mcz?2!&sfLpDR*`1UDgu&Ypa) z;u&tbf-f{XKW@H$Xn@+?gy}b93sScfDdvtzmHll#lP-`UosWa?vS?}FfQa8t(`>2s zRxLI?q_K;yDr#zBo381U@dvhb`O)2>rVCcc ziK!HzWm+u$K$$3ND%x0!E;o&9y+PVin6P}{o*48w$BYzuRe})%A|su-dt^ln;D$_T-uL$PWwc5{{itpeor6+a6EN^=Fn#I z^M;XpuQDp)$zt8P;};dDbXxU9W>dw1fUKX2D}Y#{b@VSCV>(-HoDP(T{qz7?0Q?`9 zf=^U%`po8iBL7)eK{$kBn9fEMT@vr?M`QI9n4y!+5-gnTNp13OrtR346nqYoTyul$ zc1avdfzNYm@6OS7ZIMHtS?G^_Qo>I@CnpnxfsGv=Z(eQCzS%UoOABy=r$0E;>Cv+Q zebBSSA&U?LY31UjO1N)s?#xw9;b_ziZp=NlXMETk`ERYlP+#4lMz zs~C(7oI#g?;mHB`EzI$kUddqW0OVcz_z8-L29C>CW@kC0Fm0FPS7@%Gc%+B#M1x}D z)M?0$>GK|Mao<@klof+1y3y{Gm_;P%1wOu}C+~|lZ#EgvLM4Ia4JL-xw%-ukyV}im zEP7!wS&K88D@~Y>`os(_M_kGAq8^JSS4IS=fROcD-|R3QDQA;Bp}8oujrt+xaqBU{ zRRJkDI5>-?`as4^lk-Fc)Q{iz*Zc{piX<{O`!+%vJW(&ust@(|uitA~%$PNrx}4I% zd}W`xiqWZ;CVQ?5A9j04D3ijkGJCX8!n`T#R*_RM8vK;Q|78VyYG?$>`?M&>#=Uji zoHLd(B9|EQz&D7?ku#y7Vu_O)g6=`84^~gD4>k^+xf*eRCE7}Q{fAi4qI$yiL;I%> z(&?@S<6;nazYhw^I?AS4|D`R`)CjjVV0FwiCAk#)@ti6H9XcH~&07GcBsOaYC}?no z(v$XkJRc3-iiO{(>@FSnCM4bWn-mt~WLYd-^CZ9dj$ZcL&yP+%9X3vUXk-~UCLU{@G^+%%(@#k+AyVK#^3Kt&B^5!cIQcy0Dh4~>dCKf2%&)zhid-`i(1Nib_= zIu#g$-&*qEoq)a`J=m`z$B!;6QXPGBOAp7O_mnxr3skn~Cun*l;MGbQSyZ2F1SCmD zG&b*af-}Ul8h9QVH z2DSQ2Z=n+qU}Wp=58NHdzp)(WmE&WSXx03CJ(+i_*MOpHu9wNM7%aG6NKmN$b%)9 zGBm`3WKVt1hhsW+E*|>3U~EliB0ozWR7sr(QZQjWW4zRlJ6yfTAYj}}>cBifUbta0 zJm)8lAD!`#j%fU>PTaJAf$(~%)j=PfG94=-zFi`@@AFyb8;q1kF0zXTTT?>B&7tQ? z*9gMB=vfjkQ3U+TVs&wCkB{k1tG?aC$@j>P8h0X6+nx@G;5p6%#n6wJP)nhNXt!XN zQLfrwogUtfsb<5WPq-L8>ztGy9VvkzzC}R(9@h7Td*(0UNb;TFXa01Py*R+riVW){ z<#45_FcH|fW!+{kWX43ZCGR424D-K6E06%EAw1mqH{}ao1?+ycu3K!a)o;V?;;6RE zOHFuen|pW%bMN-w_pTy%72;;Uc9v)z`0L0|wN4)*gs^xd*z+YIj(jKa*O9#&|F0vb z*Bo82KjZ8Wr-HIHN$=(SqGP?g;OCpqo~7k3HvTXMh`Lwq5~HkQ*hTTd66o*e{hT5*Q@x?;H99k!@u{Pt|Svdw~Z^BB}pv14WbxK z*Nz0Lsa(5#(ly#4|HvhsLd{}|*G_E~V0QDbl`VF?^4rs;lKbR+&6+k89T-Ay$lp17 zn3V*vf8Ljo`D*3YT*a={=$C)aN69YNn2 z%a83ljof-quHNW?*-UT}tL;Cx*bv>#m-urCl0Y5dd68-Z8WtOx;(6QR79ts%S_d?FL-# zvjP|5d+7JhwD@1V!c$4&msNix@YA*xNCMcp{*oZ#?Or(QLx>7U?x6+)X!26ySpqDi z!|n;T(>^!T1v;ai_W7(gu*F#FE)O0w&iKs*X8`F4Noy_Kpy#;o`rxW1_gx7*sNS6u z*_>lPL7(7Hy3Nu{ot`KPsNL-IapSnsKm76*?~TLHaW#0(>e3W!3Na(K;17E&t}2s(-nB3zC5@=diy<5jiW*aK(Ex$YVu5i>qRz(J<14jN0k*Z zYL<0>I&@j~0SB&8q>9Gn1y?nt}@BHr*K zwX)XUUW6*M$zKf<<{5%MUnB!|_x5}ZXd_m^H}*j;=ss=!h}j+u5k0Zp&pE6YTeH2z zB@$VPzpIpxl$FF?3wW&%L55dn%on~hYin!UtghRp@_R_#I@s6c;D`q0!qeqsx)@1KWI&>{i!*v1M+4Q;TpOxT%` zL;f6fGK43-R?>UaX@n`FFzcqT}acgRDd*64XNwPVyn4}dwUPL&)XHO^0cg>`uN zXb9V1TRWwvKr0J!eOP{YMi)QRM{+O>e2ZJeZUwC}3N=(U-U&$6f zik_~&&rmGWMW@aM`;~XB3hX$dzumoxa-VdsfqqzMQfDagYV^D(s3N@hqP`<;Aw(88 zcR}okn*h{G#UiasS7;Z8mzvPXggT(zzk4}pzFUp5xl+FTRdso8LcDS9Mm8SR?>Gy!&PW`ct^Yx2Ih8( zt$aL-!{@Z!**2^oB&hD($&(*-zWcQ9;7Vej( zkDSe-;8;(*NQBs~PE$;5gXVi(j4c32f(<%i#mNKWDcL*c662{dIG}}_3H-S1!>t9? zTdr{{%~a*Bl|D57dx9Z<$Up!vi3tS?{YwgJR3TBZW}$C1N2|Yty?U*e7SlhD|44#< ze2gFwYWd}XMnDkr!Qw#Exnn$dEQ-I$ceHzNfZkz$QFHcDzg5lUqsvP7JZwe0ljHkq z;>!(*_QZls!m{e2pO=5n=-thzrXTQb%#>k)PiK_tiH?jBmUi=SdBi?@kafe?7YRlO znhRM#uOT>k)JkhRy9Ev3_PN|w`)r%K!C92J=xFZ+ z({Y@&Za-~>=EIBVLgD;t_!p`EZcb)jGhGse2>KVK?)`XdHwdcnNp}?O#YhX-YAyXR z^k8spG|8T;gXLHIp;J$ZdPVT|d`JKKsmEYOc7gg5LDb24EksI%A+f9cdB4GQwDY9( ztnVOS*w9!w$s+EO7l)vg)TvSvLlD~NKoU0*c3+~Px(O!)96xCPd|z(6y3_(H)TcM~ z0;Afqd7f(L$`;R$)UGtxIQRP_;Wn`uKQI()HVB)x95fNS&fC-9|IFw3F+&w zi|T;grZ`pRDqo~&whR$KBD&2aHx*d1Xsa?LkFbm8y0}B>a4XxvXQSXw?eV$qxdQl` z8p0Ygz;VY26=+(4olncvq_a0)%44GmBQ|l-aOQ89ZqUQiP4pQK}-FNp7?%jr~qu4ajgrpBmIS4Sv1St66=;l^`92y z^$a6+763SZm=KB^VEKwpgppcs^aQRs`YnP(yNBS;WfdAR(%BF}tJ!VbO&Bh~ZxZ#X zFwr-GYGisTIGcuCPI9MiURnJw(ozB=x&idKlSd36*J*c(+mT^9P=lCwkMvR>Pap`O|Lj>v30LDaK~Z!DHucz zVM~IX06}0@&cf{!C=z8KF4!U!^#(~&SkA$Ee%!7L6%XV>D4lwhZHyS=e zsqZk-Jx1xf`tbEL=mAjWx!Cp=?|37nr6Ht#dM;zA;p54uESvs9y%kO}M+tFzOO-zz zhsV+K{pIr&k2Tf(D1&_@r+a~W!9vV|C3B8v;>fHHa%Ng}>$DCQQ&eIcO8#_h)A`Sv zBgx~?9f7u%K3YzkbOM^_K&D0fWv$y$CLX~NjjEQZa!WlGIEqKPSOJ3;wIs?(sZSnR zj_HAU?q$XTT$izrQ44}c8h4{21}gRV;Ag-S{g}0$pYe751mZ>Lgu?W#Q=VjSA3uJy zO_Y3PxG*t3-8Yq}6!yb6Wf5lI0`{Agb`mH~y&2??t?dsy{E$ zstqH9odqPtOy!xZknJ4%e3qnl7r3?co9`Me&-~x}c)}2KSAk$iNIkCEHt!!ce+77< z5(~y|idEGljZGhQt=+3yBJZ9k*6!E~Yf>BCz0B@YORLZf(*N!SF#gp7uB%wc1jo7O zG{feLY9rOcjMulf62E^ZSGR7WbWH?{be1mg9DB~;oGKubynzvZ;pNZk%4@SVXz9-L zi3-?=u4Re~iwM$RUXDOPLo33*02dU!iKRC{Zh4;WW%9gY73+yH{rlWn4^bqtSlhcv z@AxVZ)|7Tftvt`QLBu}qXtoTDA8sb%f0j~Bup~vR%J-FX6ONOIP)*(AcAvi5YRQic zQ%v&SzjnPX*t~BEWeqdN{jCcpcjbYFi@grXwLop8%AV@-)XW%`mlvz1FTq5(^~!6< zM*TQg9keG6DvM%XAsKMnVss)*7^-VfKK+_@9F4MjE1e-|8(Bj<`0$h!xGA1^f$W?@ zp^bZ7fWcDA{0M@BP(bkULRiF9OsYYw!t#{h@)PT~qKp@UV)^^!pKSn%SZgW_fFnD$ z%U>J7!|KmLitx?f1iq`HNL^Mjm))|dzQIbH(i=Kjo0*yKUC@?Pi!B(huNUHzzmSl; z1`|($7(#KeYhTr9(iCx-nB(r|Ly2An5+Px}$`DjA}$!r88 zBO?V1$HLTCKtS0}RrCz*WZegF4eEVM5}tu)mhPem(Q6dO5lCaIbd?q$a~aS90WXZt zRipPC{HV7}&V^W_yLEtI%l*_Na2%;aDs5~!3(aWd^x_)4hk(&0fXnnAP?MDS#aitH zs$`)!+qITJYx>EJFO0tt>L!_eD--+EJMi9UIcTy7?{ z+)kF;^nPuY)9zfr)N7z-$>6+)O)7;hh%hFS{}5d`Oo&_xS!BK(9U71ccL2XM7EP(8 zdhKG#F(1b>(=$-{HoSkzYBg_(nAh``NFQI_3UcPi;5m7W{M-(;=`;o~txCBN{Qp1$ z!F)(B!gTe4)JclekK6NPNY?je~@y+h0d0Sdz!085~zY_a0M~-iH zdE9huNhRX&>Wh|@bD_Kixnzp!!EyiijBOX{!>zr=Ots{9+@cZ-O-uKifWoyk&i{V^ z{p{jCMQp6&2L>5gx|hgne>w!gQ5#3~Wd=Z21K%yf1*s9 zy&9W|Ioz6~TS_lo=QtJ(yiVj*OpRCiJH3lnsIS1pmoY23ea;F68F1fK=tBYRh<VL%HGbK(MB`ip47pIhwBw#v!@{9Z=2X!4Or zxI@`}kMZ3?8LQ4`{6NVVXKVMKPaXttr7{6PCAi!|894GolGs#gE#RuVfZW5<^m8G1 zqNA3RFnG@6xZu3nUl}D}5cukE~h1VG?G!1p#X_8KpIIv&hnK{ z)F@nLhuM#CtqBzxuZ>DnB4VIdmeTN{`eW4$yrlN&`)(^K(mJvSmeD$6EzzLUqf!Gv zm((&&q$Lp(6}7Q5Mq8j<6lQ_3xMd~D*pbYw%hvOS1^%i2!=)cnjxr;c%3U-bAV|4> z5Veq#OK@G0w76?Q(WALp3!%e!@$jd$n?m!K`h9cu(4WL{^B|k9Q3>=o&LSb*gNF#; zjE2|~Zf+tjK89Z<87D@0w<)lcf2G%d*k>0)Xtjt(pMoBEKJo& zcL-BvNFr!INvfRv(icb9a0>jL)k?04py|NZ8lL1xcv?(4qRna7!n`XX4s!)31N zcPFO9*XB&aWo8Eq!pvHIYdARm*l}aB(2rLEtTkxHzx(P}Ckpi%S>tI{@tT_jRnizJ zwZ6V){BpEPIr4UYuQ2&?qS3W0RJMXVToYf?a^KY~NJzRR5Z-ZZ8lB)-saU^Dd1 z3r3S|ZC8f40u2&=(U%d9+QB{8$Mt_192>h=p<}DDa951mGcsf02W^kZSb?|Q{?U}T zLn4&QW|jAMzFy=vb|2fM%47J+MnefGBG7S+7Dr70yo*Hl{RMWi2XZxma!0VK;c+7W zo)<|@YI$!lvB$sraM*a)Cv3uGnX}Z+;-<&dv5s8!y?PU9Fe;xHUHWvgGlTg=Xc8|& z7XidjJQp)$9Oh@sCGWo*4>o9!^u4dT=gp8Ff&O>~Bb)$lK zKn2yA^unC2_}U4?QV=^H_wqj>c^DHw`SXo@#|N9QF=tUETnIDB1lT*8${%&nC5bcj zO`b*jC?XK@dZI<7jU?qQH4dZzjKo}ZL_=VyVScwyOiTHnuB6FFeP z9Ia{r^5o=XUM&_qktUGzatl~8GP2!+1HYssT<5LvfEPvTWKW;UzGi#9Nb1RcVrZOs zS5mRU011>dHyLX+y0>WN16QwB`DQ7;D-5-Elw0)r;xT3NyM>>Ic?Fg4Y?ye8NQR?) zdJjq)5l=Y2y&LoX=-$cT#g>J8v^~T4f=Rm$vBvyY2${Id_mgDex}!A**w^ghv#O_7G>o22O~sFKXZ_LRPsWMEH;nL1ZXA$MU{7wU3ZVh61|47YSF=KUxh*s`)Q$XneY+6sV2{QP5 zmN2}S#$g$FT7^SL`rBGF;B{^g?Rf=gP}k@Jb#aifAm^l_6kq$fq3U`5qi(b<;Szo3 zZ2$nv(&tFtdhY`NKIuZs$unv+NdKQmnNEC2jTaB}LjwCP%y!%5LW!B&`DO2le)%%3 zbGXem_67)WAu7lEvB3C6B$$$sZn1`+th2j+{}D=i|9ifCo?5FhG;lFY zRobaT&P_gv3t|zYA?pGZf{O~P6qvJi491829IAhdYj!=H5N0|u_oJ5$ggxR_os7?$ z%pWffXx{^Q&?I%43rBsM&1sX1uUCWH3*8$rN>6s2ma%x9Z5R{yKA+zcQb^4{33;{p z*Np4JdY1;g{%=FfLYCa_h>z!4;wSn0!WbN-}scZtxL;WvCcUs0q( zVt}%xP)R1BLCQ8xCoU5l`)uQ`m!UDP5Oxx2Wav$F_-!8brkhr}g&dBFBrR<9gNAM2 zI6QvUZ?IU6@yX3RMGiZeZ0Wqy9zQK!CV{%p^7^&+&$z2b>1{(_2z)`_Ihw2JsEU*5b=Xa~m z&jiBy3atjdjecHkKhiz;4Q-8{S8I~}zKMS@SgAF6-Ebe4B>UwQVo$QS z3sIc9EIRf&wnF>W>4HWKj{}Z!c*Uj5CX2i0q}C^T)lUqci#bb64c1Ta6zg)`?%bK@ z7Y z;9hdugK;YbA~odBBX}si%kdC-J?Me=lbP}<05C6_9BZn_LsEZ%YgV4uiagF=kGTdt zt+Ci;x=o@TpNwrUzwG^ZKNI;RY)3Lm^(>^-*YA9=*fEp=WmoJ%5@+@Iye zr=%n}&eq?vB4R9mgUryps}pMn2cK7)j^MrXZBz~>kDDzl!5D3HqTqcysF*rE=bf1K zGQaXO?~AHFi@i{V6USBV@4wqaFj?IXO{+%p(IHv|D`XjTgmQZvF-+<>%#ZJt*xL8u zH6TIp6Hq*r7*LY_2tR{d8h1{rrlv;u?79j)t{}2&fyOs<#qd!-X|08|@pbRq{c^L7 zhi2DZdqN9-kyG){l;M$(I%Z#AR=8YS=L=?ID~ks~>C1j*Z&IuAYFTfxcWb9IpgC)W zYUJ&-3uz!KK2?GtlJc~3v-3j&(+6e@0?0I=x&%r|xoA`fnorEV@I49Vlxk(s z6H0kncICU%zLuHN$_M_tUZzh5t3<5RewlVowV`zo@nATwHk!sN<<^2ykjYl8m(04H z6Q3P!hw)T}qn=o73>t8J78hm|M?d(am8)J^z-0|e=|vOwV0>X{wZ5>t6ML6$2j%Kk zV+;X9SmBe{!-^h(#z4VQ?|QS$sV(cb(L(&o%p4J`?Y zHGNtzgIsV1vDsj}$_01YVoDxir;V6o&aiE#)C8F8gXX}P+#r$S^qgs0apj--V>k$n zo~IaN_HW*~wydAqJk(!I${d~N`0=cet!AS2e3?{ zc~+86O^2!zDwz?Hu2Z8zR6AvyQrPNe)3S31KX_rnJ$Nv8Sg)%2#elU`w}HH-SIGbU zIOn=7eP%mOY_Oo!%bK=x#_=5Kxt!gmB|o~KG<47WqnfS>RoYn!B9jc~3kB~&M-rZ& zD)GQ$(h-E;=3Yqa@5(ZA^4gcTWf|?U*Bml8Wf_2CWrl_oJx+dFx#D|b;ip$-YvyN+ zBZS95Sm~c1%>d!mgNEHEQ%~RYuyf%&2iF68o+7wtS;bp$DjsYf$mY#+{vaXzu+Gm&9G7dUMikynT0o_b=DT?*s7fo*C;~r zDao@Zq1aF7wwoH@;aw^JLLK}8bXN-4Iq=td$oM|>2P?q_joNRL`e^lmA3M-mL<^M8bUA^n*g@cu)^Kx4M7siI6zdz?lq%=9$X1y9e%y&vOqjJbzr(0 zZ9w~3diEl~;lr7AKyAi&sIkRh^D8Oi$%LY$p(+gxojOqQdg`J(F4<8`iBh0c@W=k*-^s1*W_;RC9w9Kw$tc=vbth+G={3VE+nuT$YLpEfH8=8d9&a_MId!JD71wIC5&qfa}HO2X9;=60VXXj-XSIabVS%cp%#g zu<4P!epe)s=}=C9zkct&mg#SnZNIXkz90u^Sk?Czr7)SS`7qbi@$_ZG-gh5enI})x z1~CH=UFVyYcXB1F)NSn@Wo`Q&XKtLBx8rhq?^&h`GNv^}g&2AXA8wdd@0A!x# zFwrd&Xkf&=H6rbg-PHxpKQM(f8jC?lFQF?Cq<5?(EEruX%j3}nvr;WG!ncmpDG<$U`WSd1zRB6|vK zKPm|jR%3lMA4?R6l7Ck9P|wy`Gx(Aol<(L7q7fzIQGkAXF#5?{5DCLp<0ZXKp!peTv5HT7YoUK8YKR>Wf`tj7 zJ>x-pw|y1-XDHkDhaOSs>8CXsTS?iwh7st~`p;nhC^EGcC6RR}=MxiFaXw3X#Ymt6 z^?3u%$mTk~wOt)GtG1Ycp-(Cs+289Jm2NSD6?LrCpW}zR6!3|N_V%PQ+bs^jdgl+C z`Qg7hXChqDD`Md|q)1s`Ee|u%+#o`S`g_?ptqTJ zcAJ!nJv$xLhPw&z!a>ys;t<-+)a~4!J_>BXv``A~G@(P*;|<7Jv{Hb^x&`Y`g)6mR z~8A(g&r6 zi4NZ$nQ>+qGU4yHQ4b~jxig7qNotMZJp?2q_To>2SW=N!G$YI}>#(N290m^s@d1L5 zQ$8=Z1qHI*u3+Xf{fl7Vabz~^-0{kTd%T_;;-RxgTNB+$%z95H#r{ARLR`NunKhZ^ zH7tb8j_Rk5IGp;yIu?-Kg&M{b3Z-1WrJRw*eOz#Q)YpGs{bsw%dlF>2WWfMhI-gFm zTLJl~c+=WPHKO_&6DHaH+GyQ1&Bs(K4jP&40i>hYE6Z&|cXX-5vTUAbjOH{!e+$=7 zdkg<=Nz*6WvNJ5{&);zW(aNxG|5!)y=NfbQo1POe1qgPyL>IXdt+}3o+>PVTxN1=s z&H_116*?Zv2NIkM9=*zyxfom_#WREi`WN5Al9+8lR{WyI2pxrRlBOmJDC?tR5|Q5w zT0fRE1Hl(ENM$Mi{K5^gdydvWk$ab~OnIbuYZ_gbs6Ba&(y=aklbGjbXS05$uvh}! zYeG*J@ObtRg)sPV?I+o0KV4J6fGhO!EpNcYkU`Z)g@lk>BB>e=JEj`kIyD(q$p#{6 zve2o549uJ50APX?TA489^n??$@#C>lLF6A~_=mCoYEe>YQgvKZg`3G_>QF9sB&aj$ z&0J??y?3krx4$Q|?p@^Fi{rg#FnRB!ZleXX9Gx%jnAil4@hAxbe5g5! zTVFofjt&CAnj|c&fA0xLX~f2#CQK(C03J6d{xa*la-bQHihzWMY*#rmL$ksj-(0=K z=YATl84XK>c%}ZB`yt6QkxP*JHcz)cLg9aMO`WpKFaguAwV!MdY4~q}ag+s1Sf;=dmZ!tUeW*#3Z=HC< zYLT@6k(k>7gw97`7iB|WjznnFtIn}BI7iu*nQOrU#dCBAFRtmvqCzrt8OU9GrC(s$ zuQ;o6Re&TxmK`jGXt8XHtEG~CJDO=FN9rTj3faGa_6lmhShhQ29 zLYMKrFx^~Uhkm53hGyn~nZiGXCr4>^Hk{b1U0)N}ofYpgqB4ISSDEf1Dmx~zJp|tZ znZ{eQ+S>Mw5Kg|yo6V__XIYrwHw7rS`Ab0yOs24ul$kHl_w^%wo0oZZs|~*7Mr=-n1LdiZ)gHdl}&! zI8jm2*^L#y2A7?dZ{J{+dNssL)9Vif89S9=o#ph`2ZUxDDsrPiF_XW}zQvk{lEV(P zbda|}Ee~>F!9~ZgzZtNpAa;}V0eKC(g%AD+-So_%K^rQSDZGMIf;`ktw^*CX$v(@Z z4442OkMQ@~EM4q-2RZ?Wg^(-t&iKJv*`ATbG1b z;FWcLm}PvvH59kM9Ytraeq6fl&*q2($99p5pX$&kr{NUbHtfJFCzejX6VwZjsU$w6 zgvDon!?6WFYkH?f(h^_~LoS&fs$?KC3Vgj2IX1;mfd!&+bqcPe1Q-SZX3wLWZ3TD+ zuto{IIIBf?3Y?|it#7oXDEyuN0ND6E1-)A?EZ_DI7%=5jgR!P)9SE}=0@z*uOQjY> z4j+3nr~fOq!t}teuD$-P<{uO!cLdfG^_gotOT;)gL$(QVWh8j+ox$hQUtTHd=9Dnj zLq2H2#r5ra5$pRKa3_t5rN><yT%KeDjT41yf6+FXKoWhWts%((T~Rz zV3$m}4fKL8S3DjV(h9KakFr6H=ZF02Pc8s9`UrAw>T({pTOSN|q+nN+V1Ls<8e;-9 zWuRgfsOA9}A%oy}TCG5SK~E)&|V(lLPX3u%E{XNiz#B2*>&)Vx7SoPlJh7 z5n4p$=|tjlFy2SiKsdx1{lM^#%wAHF7VLvik5zXjqQj)>+Hh{LR?S96e&li}?m0gSqL^koy|`3Y z(TeilH!*O1@}!SvqnU^*je3H0#@NZK93Hasl}FaoWTWmfFx*2g6Ggw|9p_bC3xHFD zBOEpsE(q6(ridd*XE#!=$y1C0%i!uQl!L*&R8*6VZkWElzQN()@}97kfMtV>zG6Wr zufb5D%7ug18Pj*S|Jg+mw>f}vtC4ho-?BY*(1J6cHMn1>qM(tTSIMIaaJ0!d{oscE z6St<mhj8ClB^cpT-V2tSx+a9Zv~1l$rg6?T<9u zQ%rR1elPHTiRk6GwuQk$R~%wX*KMZO-ASSW7jsAE}&Z*H9sFWgwG=m;;iZ%?uy3+-ggeM_@ckyj~?y+i7@P z1QQbHSHP`xF#YV8iSwa`|3KmorkXM7hF+lkQ(|wpEwL-Usi7wbv%0RGll%t6G6n$} z`S*ddyff=t%gO8%FeMlO`H>3(qnetZY?mL1)^Tk|*+1>-OJA!?KC7kH=Tj#Ixxfl| zBS&dJgHyJw;=+?8R`sIKE=?q-^X@(*7sN9iy&p8jQ4)uMNy_7eA(PzeOF^Zw$CYGC zB2!1IKN$7Sc){~)Keq$4d%awBPpK++cbQo;DY@R&C>A+D!xI}(jTs%w#!40uuy+`RWIzG!v} z-d{zt{!crII2D#+zj7%~3)%olqn+md=|j`#`mH<`ZZo>YqP;=zLFgA8@xQRx#ZRTP z(ZEc6*aaeDN4T!KxEl_JFJn;Y+<1v_fW&8pe%g3un#osHDv zA8(H#kxAjW7&-U&hNJXLr*)P;BnLGhHeczs37A&BhYMP!_h2(-IxcCr3@(UA7$y;4 zAU>;jsRnFrByWvBZLQ6W)VXr@9*C-Fo3G7t2?|dQ>0!Zs`e|5%T@u82c(RzMw`j(jv!{}KLqw1tYcLGuq-e5 z))uPx50*Xx+W%*5Wf8Jy!eDt6v<$*AP4uB6>=!EFHrfFThoqjAP>J){J|pB)@_+ig zy-GXaU`15-c(ePj;v1vyixBLm+hPC@9_51BlYgaoBFFEB6M7z%(Y9kvnjz?Ypt6r~ z%AV!Kh-)-ZT(a`#9l2=vz&Wia$&50_>U=zr^%&y(dj_}YrR#yIkPXMXE--NkDe_H; z=zadY>$tRFFQSr`k4swkBZ%=DM~qqkVgg1I>baxmoSX`^eVW2WBRo=>pG{>)dYafn z6Y`t^Hc(QgMI4q{S8~3!#$)%3t(;qQv!^nbqq*9+crP7^*Up&2W?da#cHs4Bd*W0F zw!|cT>km@VIZ4=;l)F#YA9#}J_#D4wUON8ZuZ_*YIQ8@CoJw#k_wp~aoQw0FudBoP zNEerv`Lmxi$|BJzB&EsY+jEV9!?=ggNVdB<#@?6CgSpTZr2$9xim$p|uZp^9t^Fo{ z2(8q~LR%_{v4iYN%B?Z!kbl0_jSSpiyrtreMp*{m0>Q^r394i;@6jNOp#vt(VmK_| zmDRV9I>!h)Up)7}m#>lnORLd(AD?h|<32_%0N{ggFf)9<+#aVW#1EfjTJ&zF z>>^V*PX4-^Kxwh#LX4$1JobVPrBbVdZ74mZ&*msmMa&4yC#a9{nT99i z-;SW?3b)xUQ}4N7vXNLmj`fZr!{G17wH{g87oi*h9wG&QrKeD5r4K*q) zmSW_f9U9XqSf~L8zfm(@Rt`}a78cg_U|FH#kKZHI!CD(VxQ7pAoh*JAi+}`Zg7eLS zKLF$|&;GVuoE}hNW_pbxR277?br5zzSj%S$a(>pT10iw3pD=I8Df_8V%moG{sT$&0 z^>0Im`?vHYhH%DjY6x@c0nDi&WPHUyCqCxN4cEm?phvD*8O*o-f;q90l;@_NZh*d9 zPvr9|h)J%-z&L(j!bt3>&&=>|Wxw@vad>riD`j=jIR}^DbBfHA`pj_s=lB^xo<^R; zmFZFl98cAM8mJcDngX4dxH$|{UMPR8@kw~|;XBBK?nS(eX=$d=nAL7-Tx!VW|rzZE^}bXyL3ec>Dl4|!AXR}M1Bss5hALoBCS3GfGcxr^3aSgPWJHl zoGlw+p8I1kgz8=e00UTLoB)S~s#?Gk7*W zla@j2n%U^-O7pGW@ zgV4epUYS}kJ$NWriiQ{uf>6?=0dP;%i-SSqPU{a&no^<}M4GN}y6X1VH-0D+c$A8P zMu*>&Sr2Y8!H}rrA@+R`zVzVc-Uc5mw|o2M&_#gbvVua!6A)R9AF3`7V2H*i#gy&+ z3@wC5h?49lWLh1~vF~}eaML3o{jOy#tk!Nmz3f+!m;kOC-F9+2{J}H5{o~Hkq9CeV z&+Yz3OEZwFA*F^nb(3B}Rs;>_inh{8f^QzNgIRZ=k@zUNb=1`i;-|(-%5Z{6eir=< zrZdF`le1c4u)LJE$KO;fr#y5+8@4{$>VaTHnD69gTIa@LWJO=Y*Fu%9f z&0VsZOY314+tJ=wC=y`BHknt_SrJSFZe4bDEcRu)2wA9?eTOteYY^DnW?S9b{Heg> zHXuLII&nS9hjc<4`7B%r%jG5Q%i=n1vO4Tg&@>y`@R_?KpBsx-cao9&+tmA6^~v{T zGyT*JwI1~ii}tZ`CTH|~XZ?NNiM=|>Cc22q>1~t0bqUGD$K2+LJ`;I>v5(<_u^5KE z+RrF)ThJS{F!+vm(d_NSX-K1Sk$)L+-d_1J*+!q|;8F(ug@At}eUUK_Zg@}cOH;Nj zvqJW#_YGn}|Km(G9xG1#VgV>ThV!7?jG6l+8t(uTRcIA@3>iWb4=P=Q3!t4NEMc^ZO&9)Hm>!M?$t(OH*s5%gEkgwc*2G+*r*wL zQpF$k28(w|F*z*1#6Z?45E=j7)#drd!*ch(=4vG`UnF(G-OxJCr>u-wy;LW} zNCsoBGlcQznUV+e(z8QAVE0y+mKLR3@)1m-aA|&6ZYkC;7p;RTDZuZxAP4X3Q+W+a zF>ucrpd0TVi-{Hxo)C=AJN%B$IgBw zUJDx0CY6eqt*#HUF=Ck-#8WMu2MvpYuG{_DAI#E$zy`NeSPZ*$o6PeYAy+eKc7gVI zaj;i%n>m4H^%LZk(GB8V?F_OM^BYl8_#$G3UD4|tuJNC3BVxVee42^5rrPe({rs66 zd3;eU9+i5vD{aiwl~6Jvo9PoO-{%;vhx;ffdegLjN@J@Yt8@-v^(1DONs@&ct4Ctx zG`jyqblI7f_*437Ze=AX9G`uDz9TI0QM<~G*}Lz{sQo!hr{2CY|8E#|uKagV=W;w2O3FW{_#YzN1|z{o=SG;6}}#pj^n80u4|Q9s@fn4N_4ZfItyS37=k|3p@{= z=k7nMwzMJZS>nrNaXFxO3&xgxBeqXDGv-iNEdhl`)Cdeywpast&2bW7x@bO}6dE$Z zpg*gnjVbxe{>6v{{Ee=num^GF%Okz$r&p-XRH9I-!})DCmSO2raeQ7AR6)hc}Gi+sp9k;ra%7eixJQATz+PN9d#O_RWsO`$YCM1EB_H2V*s07cMaB8%X(h z4iaQNxh6KOc4K62!Ao*RVxf6z1N1j^9esLffAVFKm*qvQtEnH1b;4HLk%hy$AK~mtwxRyF@?EPK_Fr@&Wps!Nf+`a1}$p|k1EW5 zQjduFE-6>U--OpRvl|;>3G^B{#{j0LTmUM5z_fQA8;{EicGpHKd;p~+a*RhcVP!Uyl(8BT^+<1VOTa_8q|!1*+fkH z^qH?GDgZWe$NB7E(!WVxrPa#KVsCh(_nHzSY`7D%-NBs6Me@AIg$ktuo>a#h=n48n zzI?}-uNO+I>~s4$ze?oT5P6{g{#iS~dfjbaFO-Rl4GiS>5&{+rC}$>&hd|gs{XWPO z{0mQmud&yF&&B@v<3`gD(_R~vf{olv)1KiH+Wp<^7NkTv!Ppd^BC3oWFl+^2rIcpc z_Z(``_$09o&DGks?>AnZFg#07p_*V!sDjCn3NbzwG>wL9O>0?dkg{94vTF~=c=RI- zx#HXwFfaVqkZ8Qq#_w#|gs1zY)-%l!i{DQ>ruRe30fAd|;m(eCqR7MoN$pzU>fXAi zHT4bO)R$fPeO+w6>R*M+?ejaxUcf2XCfCiv>(zG83)q+q z?IK>-Whw*J7PRQN!$WxRp03B}6N%e#>?fDKEdi`R!n!b@H+xehio?5k_ivw|jQRb5 z+hi2S|2&I7-FQv1ZzLDeIHo$rFZcu)4^rPjG*|j9Z`@*(#?i*tDcs%ZY_g`Q0riS4 zaTA&@&JB~zj{SkbI03je0r=DeKo2z~gn3Z$DP$e1nbiJ#`b_o$0!i`F(=jXw4LN8_ zC;8`^P3JlMnd(kq^JzBZ{$|#e;;^Oivy%zuqb`R}n?ulG{Irv*&!00-3i)s0UdL>y zcTdQ!uMjjGi}+EZO~YAVd7zlsY{kv&98q;myyXVDU&(b-vYvDvhrvcS2RF1#LA(VE zg@1MdycJ#Sj$uR%&cBft8d%i=d6Dy@Ep$2+@x}&+K1Fr2n@boP{aS|WHTEvXq$tl> zS?zIq=ZWHgUG;%$O=ww(%B(Q1_{tv$D}hPTrG(Jx#J@Rt32ILBUKX9`kYwFMfWsKA zSx1|0^z7Zy^CSb7C0$bZ{F2^b+EF?#0T+h*ar0xMG40^t<1(6)9igo9Llh&0%wK^q z6?D+2{WDs;haU}uXU)L;ro}-LG7iQ$>wNve?dlu0WfK>IUabhbPGOQ z{6X}*L!rZ7f%8_ZC>B65XQFhSIv{s>*eX!`7qwBOO5xI==lLlmOcc58-1_|!l6vw1 zGt;!pEx}rcV-)?B{QSx(+0*gSDZ$6FKJ;jHe^+7qCz1Irhxb;5wgf3b8kWMT8qIjQ zFU54~OASB#p4@|nkTbExf!SIaD11coeuVM-Cd(Z~YHPY9md<-7-mI1v?pQCKM;pU$ zpqmcdzRw0mo!uNtKM~3Wk@i;S+OCzS`yc125&Iu8z{{s@v?_z-8gzR3+4%~KI_D#t zuigRSp`755o8o|aMXog$!9-EDZ4(G3Vn0SzgUPSHtHUdc)2_!6r>vomWm`x=_T3#8 zw7vI7s?lR0owD($2iqTA8C!mBBtg%+e!7grUz%GL!(mx6~>PcIq}fhk2y_ zfeX%{XAMp^kS+jplRF5c^!w-fbitSMC$;>3>|%S_BX_DkJwJj(`et)AgHNj;+-*v# zgPnz`8`2t^~PQZIp|z?|9!q~B`N)%_n(C4e|rM^=ov}UxzeejWqeU8+hk{J8W>fB=chIX#^QWvpz2JVdYl6|2#XYe zJV5Il;zcu+$Yjxg(-6HLE~iGQLjtcgX`Iiks6m}I-{+IUDH{x6ZSFMW(th)9LxDg5hcEH{kwA(zd4n;NSh?uKGF&o>4 z=+CF}1P~3L2BJTvtFs(nlp3T7AexTM5RE4d1pjfxHUx`M_XHe3$4Y{m*oE@$0N8o| z*8?0NY>s;3YA`oP)0~NoQ+B_gtXfe@g;t%}a>LkR?jT${RKiO*s(%r+&-;${XYR7{ z{s6STYo(OYL=tlR)8e!K*KU(YuCz)iGhZ9cmUuKUY#Cq{fcS)(NDTi9A)KHqnRpKs zuB2rBzz62UL8;dkcEB3aN7-8rObmg2HtnF7YeJ9uB`J&s)RbLR0^hX|`H#%J`@hS~ zBbcvFwRQ{R^lp`Q3tf`SnZx8F!#jLK%O;B`OOXQA!Des>r zg}wt1@qLcQ^7lrFqE+|p<&x#Y#v-n#GU&Pb)VFOm9>diP5=&p6Jlj;|ai1gpeWn*%^7*44L*K${ zF$`N{Adz+Z>$aBLqQVV(kg60FT-IODc)z}`x3OLv_nVC@w<*<=I|T(KDPiGz8T@YV zz=BWBPd#kF7jaRSyX@#P=+r&W`1Wh)YY=xF-cT;NOwLXW-DQ+?I*Ul~UoDWr_knAS zX<0g8hP+gxx5=oOL~Sz*YQ4C+GcjPSrlQt9FeX!=p#Q{sAeK zob9i9ROh<+M6mffFVc7Bs~T1~ur+w-<%gH_%KLEL>0CrWIbZ(@m2rXg8S$0ibOFbp z5A8)uTrCI2w?*|IDfwg`Kr69fQZn&5r25N_2_G*b7}&KH6?V zCPd!_R!{I6wJ=KPTLAmO-q8<}hKWKEK-&T8Xa)%eqaUY4!1gbUVJ>Z^D+<$#f1f(c zdv)%8ebr>i?0&fFTvLR{{#odwNmf>dC{_SkCiKkNCb;%*`#uM?#yhkm({B%T(V+27 z;beG9Y4W$nJs0;e3Qq*(x5m0_AcOdF-P=*8DqKKX7v zzF?U7k~2WWtrpGRt+tAB9kwV6{2k(2>y@l(!~oCCK& z^#}Dr9-RN3aD;6BP@w}7q6)tOCl3NRqX+0^THxHC_6qAlotf)6P&(PYLXy`TFxbg3 z8%RKCjM^uR`6?-vR~E@rzSZNfGI|IH0!JUs3i5>pxS?onGvqvJB7&LD!beyFR0W$7 zQ0GQW9&||y_|c%+UENmYZ@xxm&S-3%(Ae2sYcp9pPx^k&`pOBBFzG)0?s?MvtS=wG z2cv%#sZIs~TTO-0Kn;R-FtbOQ)6X^AQEEtCAz$bNHyI1aV_k1a$N|h#0$lY98R#Xz z$Ou^ni5-z_DJ)EzN5EzNfT*#I)IHY#_YXBf3K5l|U;~V78Z2~1JpBcd3pwT^pJ-oJ z(^kIu5egch0P0KT&_oJOrC4ezH5F#n9!XZQeCtJ9ad_K@j@eU8*obz6BB+6NH2ny6-&$&*< z+=}{v2Iv!}y}G*kpjwDR%M z)I#;)SNNOpN@Q@b45$xc;FUH&ON|lW1k<1A)0q)mX<)Y8q(KeD`w=aGHK3Jjiy4zK z+NTIY4Y%4)1#wxZ1**CDw!iOEAJaW&b-wiT@>~jJ< zybY~vmIhV;TqfmgJ)q&z{4N80O$JujRPD_$a+Az z4IK?FOVs0Jm+a+d%Mco+jBYp3tQb^QR`#+V9wO?fXcmZalX=*8NnEr!KZSg!I3G8N zv;v$4Vl3SPINX#?8<%_gRsaV=4kZ`ir{En=qJ8Mm2i?V#J0;3!5fKDsTG%0(PTAbgc$(6?4c&5^d=Ip)6zgPY;>IZQ{Wn- ze2(}j!Sz*TLZGVy8K~@~an1t_TTaOBjfdLuZ%f~~J^IxU(fDk!pd7ugUj0GeA&b@c zPPkO3-gf;L9i?LOy(Cl{;X_m9CWGm8$~#hNlI!;ngsNoz=OrN<5t%19@voO`iRZ#H z_B;&DiJpyv4Q+3_SKha{uy6^i5#1xL|t|l#haWF;CCN7 z%hF?sk8-!X1aS@&KS&MdTix17$V}cGf=$p}LRorO1~x+qQY&rM{$RL9sI6=I%YHf+ zf-CNwTIqTGuXf>m04=!8O$5~Tod(s*bR#~!C|ci7zA?!jn7e=fcJw6B$1uo{PjXju zOfQ?=T*e0(*iauT8`>W6|L9XLbbQ*%Y5+{yoVO5#goKRxlF@OQbsYu8kD&aH6WnLZv3K@M zJ>L&>znZf3#4{{9A#=aJquq0O&HccfU)lfBBnVC9b`LZCOOwhMfsE4pBctTAGNSQm zf6C@o-lY`lX8kf7CKD^Llui@G{PgQX5XsNH+VQ~rhYr`N{$yWWUKGi{Z$dVHs;2sL z8v~!Sn)!`9F;T(X@?W~}NjD@?snW*oM0V6zYB_XjzS2=zh57FF@^-$(6>mue_IVxH zX=?F$r%Rk3EaVFpV+(08Yl^tWo)6Yr4`-=Fgi61suHpP4RypgmeyB11Y-_V+EypO zz(_vcTpomqO_1FJekwuOv@x63u<$?hhL(3wd>E$w7ro&lfVwsQqi#VyGziM2y3Ib7 z9rmM*+*Z7Y;uDHZ=3l4o@QDo*4f=n<-#p3&Em=*a?_v0G`IK@@?JWYqaxKgNxCB^!FEg5 z=T#tm`;*71BS}}KlGR~NyKMGnCuYA&pKEM2D=v)VaohW(I*Tu!R;{>RZ#P-;8ng#X z$5X~oe6gcXyNw{5!R+^)+4%m7(evyOo#^FA+lo@=B3<>)u!efHHhU&b)V0J8Q_1ev z>r2!b&x6Nr7%?^?=du3GlmXckiq3!^?a%nM+Nm3v^{Bl2w+(_-qDqhX_V^Qon?)b;&1Id~ogTGjRh`?ycHsjCV3 z&OWT4BNJyml6P1Ja5u!@ zeBcdNiJrBBdz)yYED6)YppKl^#0W}E$Zv;NMCZ!>6-F0RN-Qj~hI*cpj%)Iqqk z&T&Dgo2(w*@%S$OA8~Xc>-ple@jPD^8-H?ZqBe$~M@TjO8mB@EV^>jRxYX-`@jNU6wo#z@J&nP5n#jSzWq;r=PdROE)%3wMN(L|BB zt?iME!tbKz_0-h;I+m4vuh`nOgDY)2)UjxFT3^}nIHqIe+#501VDHuRTo&*+Ba}iR zWYsEsd+dyMJ@JJ9MQ|*io^_u5`(g5oE^rm!;!vFH`Etp3_g0VKUGn+TZ`l5{g*NZS ze|=D%!p?rxS#q1Ul7`Y&H~22D;U%#CuQZqz?NozdL8@-w!(iYE$Vn?X{7z3X{gYiY zx%<;E?l-~iF3vWScnZ4-N-CEPab0ul3aiKD#q6A1{~E}Gj)t_v)2R+Nzx5E01(UG< zN=!rEDaeO&`gy$85dBTA5(-_wcTS7{$9+L)Pjdknd#-$k2XTsAtY69_i+b_-rb!1%IR3cK{B>=p7(CR#OQ zyIiB2kE<+>^x}?|zrpv~!M=!YxUR5}KJr^?n@Y3{av2NBeYAHfH=93DVbCF&XjxCl zOKBJds?B(|fEGILuHWvp%WnddHCk?d|IBe6x45&ji6EMKD(c&Q$#?iVccOs|{>PT& zZr9!Kxp2uP!%ZU)l0FnQ$!jBtNX?EL+8=z9ECg~CjvcA*{>1YB=d8k$#9$I zQ^}+qrV!K}q1nxkRqM8xGzy!$VXYAYppgnNA*cDBa|qyte~c(rL!*+lSv#?4e4!F? zw#~8L-put?5U`rB$J3XrzqkH;r~uV0`@ISQKFi<+QFuyy!(HN=_qplejQ6!x27?>~ zU|T?1DN_iGcO0ET;Wlwy_rSN@RZN*$@*jk=2_YPh;XKBFAsjRufGkedZjpK&bQ2h| zMV-kC4o8v3_h_;X$?$6=&W&e7OKujeIAo!%mY3^Ps}~kxRCGd*P%?u96}(55SYKxV zo3lIyj>HS{)q~zEy49a>U8yC%6Fl>xHUCvoO4)Q~7KSF_bDrsl<6@ghrpadWF>+!2 zeNhaV!^2m^n9D%@Fw#Ny^tY7JSkSkGCICRQTf}5TiGV-twnB@8l+rC38va8DkXKGY zy*)S~c^?}&s>h_EKm{)IblIeP`7kD;<` zn}Aksw~O-Bv0^8hLjn#-g&?WLg)Y>Sv%es38H`UnRrGdT4BQ`PtaMH^-RxE}ZZ*~X z$o=XlDD|kII|y|Lo$;k(QGq;|0MG#nMk9_+X`%5U>}Qu!(et!w>+oqm_m6A4!SH1S z!S~j7B&&B*3!^c9|*rrCSqFh5q{u5VGY)_@b(QP^!4fme+#mUgRQ$8Bi$%F`* ztS$BDML;C+C~)PPF2%9+M!#r$nO<`@vF4=5141r$5EjyiyIpS!GmaiZ#atxFBZ)^m88HyBKxzXE64tHIbw-S{oEJv+O#H$$Eyj|IzzxqlY`&-9 z-Iv>LYWpk@-gPia1`SA%MO=fk1QxOUKbY}W_J|j)Y&t@!9a`q#JU*f6Oy=srHHy5~$&!|;@69VhwwWZGVp1BtL^TOM6q8@dQ9fkSz zC8T5_6GSFG{vbKr{+@S)6{T8LE0UdkW6?Yoie>`qvMYf(ra_^Pj(7Asgbo%PtuPu6 zOq4z?VL$yN&b!uxmTmf-tvd$n2E%=8HC8Sg878#OVM#Wy1Bj5!_L>`oWRxN*`@3!RtSeMa6j@<>^4B4wrN7`4})tmWL)vfUp zT-FPta|>WS{)2QLyC=sx(@9;iyb9)6bXsuOpAx!I>Ac_xGXsRSK(2$lmEn8kn)|6? zD~np0szQ=Udifv1YG+_#+G8*)cUM1Emu3pRmF)RN7fo-&q*n3*+it$IGi-&~_F@;I zM(bP712lm^5r*Ua4!M((W7Xb{v*4rUce`JztUKIwlFpiKkKXAh6kB{wAB)!AM?6ry z;vZg7kJ10pfrqliN4YW(Gd)miGyTcwr3*-LD#HpUFl6@jECS=-um9 zCeM8llxTl3eENUbdh4jFyKj5=F)4vVgOsE+0@5XLNI^=vyFpSUMd_51t|Q%zba!`m zcX$0Z`rPk*?|ttW4E}Q9iO=3^uDRx%t2>(2pqyu)yJ9cdcK^c=XFL2*|1M*;)M2pq zS^`Jueqqb{?y}-Rx!i7mO5#6}D^0-tkqE4;8ywg^U$m*wI%jh{-%B9qkE(~?Vne+7#KxK< zox}&Ts$e^Mt{zcwQHE5kKYafK4e>TDU~OTgNN8yHk8VYGG_PVoK%y zh{a$Y{}{|)Kzdj2Hv5I`3iOio>a5youzb5<$ncoQP%06*Xb~+gGP+2YR5X!*O0EX- zvfS8LER;;eWw&L`_;`w*1FXxo)TsBHuwH&8|1&UiIu+#ztH;M8u6((xm9{wOs&`9V zi*32nn(3!U?ep%#)XuPEvwDUhMr2Fv2)plXp-)6tig2qJuE|{|XN&t#K^28IM4D}R zs|8-RmuAV2i7kV?4zW4e9v&#qDUTv`< z@rliG8vcFgm*`@OI&Fd(XPK$oBn5WAtfADf_C>XV=V5n0Mn0B&>Ky*dy`Y1S*=23# zA;jtrJ%zX3q4JkiQPvVc)YEs~(Umw;>eLarq?^x~&r3ks_;Zs>EZ+`Qea8(%W71(L@YU$w2qu8#y3|XZpu7X z>1@;b>hZtgPR98`BUh>FroI2+ZLW%lR9wKx9{*$dX@~FtB}TQcdxXev5lZGWKIdT_ zSyJ*^vo&7u;=WmH{W00Gz1#A*@5lD!hSx|jL{OVjlUaOVA3T~U3IS-g9VJWzRq9kQ z!tWQQ&em^}t*Mp1DExqN`j5kAKl6n5gT4D1trK?=>=tdW(+O8tEG1gaIZJdee;U}x z#q&>tE>q4^HA%!hi7jlukkzMoSv7-&mg9z*N4n@4GHE3Yzt|KoHxAaulH%6 zBrLjRK}VAQt^Y_^ijIJX}u$yEJVgcE6K?q?3xiW`mKvm5U?yg)!-8i?UGtR>o+szacE`B9c> zkJCviW3Jww?A=tu_$YPpXqNz5%1&b0r#wqC3-$K6AwZZ*`yMUKJ&EWzF1fiP{}2Yx z3wH(`AM?~4Lyx6A$UzE!E>a!_H6yaneGlY_j@ zofgu8=#P$`k6-ehv!+cWTjt=u+ZB<@VtmT|#0jOzTLC{JS6iASIHpdU<_H_UMu$ZC z*=r+Xc1Kw6 zgS$hKC`D^j{vlXE#f*LTAX0vqT~8p8_x`;;!0+EL9?8$icxIA|uFXLDX~!9t7K&<* z9P!5yd6X%pe6{Js0E)sxx_|ZPVQrVc+oh9(DazuaAVO0>OW~lm&{P``bt*!LXd=2D zBOR7Z@*oDyv1uD4=^kTH-@`^S%3p5bV~tyWY8M&O1b)_(DDZGOxt+>?TlxG>Cg?5& zG)soL;zQ{#ENNV)?=E=7wd=2bOGegsz&{c;ZtAc9*bQkDw+~?S*Te?;-WG zH8o2)g5dL992hR~91iSj<1e`E_r`S4%{yoIKs;tedL_~^MAv!ou!Aa4mbuzYti3-?uBC}ZbEH^@#+Um*gdK4^ld_Wg>atkA zz`l{K9c-+_|{_Rj|1J zhss^a$0neLqFF+`xSJm!_4kvIo;d&V;EEP%sC6Ku_2L$-$!{OSl~{6vgbe}zJYPwpl6u$EDAHs(gI4^M zddGOSA?ul3OFTqaO%yyQvToZ~)jJ5n)HwLWi(e>oQ^kJU?ZNDjM83+A^PeZp=2&(` zJeJqPUJk;h&)(7y&dT8lVz1TJQx!sQfyc3*dQ~T;UhhCQF(WETz)-o%;yYYw5sx?i zr}R-?Hq?RX1E1~L1CfjOFnbBK2UgENRAMgK!*l^FnMzR-K{kR}PXG}VE`2aX0Osh2 zMoJ)*?e9N)pdJ0bj^X<&euV`NMnHtAS+G+F00-a=^h#RbMBt9?buPQh)3&LN9g zLXJB!--;l@o$RMP_y+_`x^0M&qL|C?J+YjZ@qaORaKmdUU|OTsk!r;P@p1mAZbvF*n!c)xw*PaiGALU4wc4JPJ< zNFKc6>4WcQX=_BYRW8yeaP&(-=|MN2$ z$&P;2(^x^r6hAaFN+Q0Rkbw0MI+IKF_V#ia;&Ao6Mk~hxOSjR?cc_&&19!YbkM^rg zH5wVd_>b6BWm~yoQfsOP<2yrT@o|M)R2mGnZ)M4)Unb0^{7Q#e{`x6WhTI8Izo4&w zsQ{Xm$#Fbh2BejXqzg2LvXxM**-0jA$9jR|tF2-@B-xS2zr=!hIA8U}`axcXP&L_l zK^k#=ZoFJywLqEz+9$(}iY&tK_J48oR~WX_Y?jcZ=bMyF(SOqJf25Jfq4#=+LLwd> zr(dfH;BY%ztVpkaK=Dg!?1S@X2A|Je7*A**A=ig!`DVYbdPDu*xTdOp9J(mATqkW) ztJ@I_D;e5KrTS?vVRJvrG`a9a4uIh%+KwMeH z#lA#ld?Z8qk6M+WaZeH7ZZo|)>*c zY`7kY4=WNHgkVc7yHn^0HO5m%rrywLb>axMOM>~s6$?RI6lOqI+Zm=%Iil?>Dk z#~07{-@- zx6ZQt`aCqHh&RoH9`MqK2F+VR5J8BA@l-m36Y@@0Z`g8hbhB3pj%;n|BD&L{?DmJe zfpmE@Xb74HVRJ3_`G9~EPGCQ`KO(5!b2VqR=;OVC& z-^KM1NLlG7!Ax`XP>8jw^w;P6NEMgEACtfEnWr{*4+= zPaLaCTNFnp>crfs(ax--uydNV}g2VaND|Z5Wvy2w!msxe21eya;jb}vGaHa`` zZmuJa7IRA!vK0ydii*C)jqbH4t6KLA{!-e*s=Wq}d>zj{Nk8{@Y78;L>2?doPL zQyN=<1)Hg}#;?bu%J~_T!1o+0`=`>d#L8iPh-`^Dy~+sLksI+H{uX;)2BuH9{9pCj z`{dh7#=3z?Zevu_>R+zT$H}~)jRk6gTQD4HI0!K5k0JTHRTR*D4SCnnpVY4EJEZZ7 zjBnjA`@$ay`sy-xiul4xvA#uM3Y4D_*1sT;(0LeMdlUlCqb&32;CwEwV%*}W<=EFq zoAF5`Lul8F&L%V5oxjmw0AIW!K)BeQ`$`aFD+Djw<23*;8&NL!Bkbau9DA4A9tgtG zKS@1KWB@D7P3lz+3bbk?`q*c}8OC`{hla(3unO-Zcv`Ecr@ zv=J$KzD6Ti@Cugc7bS7 zn0JXVB|axdxFDwXW;%r-b^Vu9RlZ^Svk?`#n2NW`wSaWfTS-N$a*-Frw7xTMgPB|~ z?S@oUNsyA0_!mV%tof`?%Ok}?xx91*&v#~v7{};X;7?o9hL&th(D>Z%0wr2=-Z@(z zeMP%n?T)k;d5b_I62rO4$l5*=!=p#y|689+N%Q*~Syl+c@vm92?pzNT z{a1&O?oc#%zB|R`CT{CJSJuqU*>>NDt+7J)+8v zqRn*p?bI!x-+vh%iya!Ax23aO)gW|m`m&FH&mPwwCbCD9kD1geYhc^zLE zN+*!vAT$O-`l6AReWV)#`Hi|-o3?wv=%iP{UZU=gwo?AbHdhKn*r%Dn4@|SjUcLH9 zI+3Rlr!xol2_WT-&?l-tGh#EmI2mHIw@bcOdCwAr#!C}Menk{BbWe5rz2Ndm%}?_O zap#`~py~TpNHV;D1e&-fNbCRkja3j+M;=~A&}>?+p6-ul4^j34iBmN^ZPpY{# zZ;%}$4Tb~&E{yFobjFEAKpB_VDWE3fX^ddiseXCR4^OJRxRI|1k}yvIw{)IS@paMyP6vRq_u(kM>ykY}QcROmdkMa2OLw zq(y4sn^i$o(v~m&dUu`(cr}IERVr8NelT0r^<8@*J1H^x9U;sd4c4Pkj3DeErC5b@ z_V#S0u&a{e{dCGw5azqh13}MF%H}^>tW{sPT8OKYWM6 zJw@hl!Tocj1He;2G$ma3;&Rp2QQ}rMT(oO_DWddH-f;_}`;@}?*^`{8{GYr!R0fhE86-(bU@vgiwY9}uuuwkgB!6FjsxZ_d0) zTljQ?mrNK4rat3Jxx{Vx=V8Hc>lrVRt{3)KZNF)_6xi9UG@#wEeD(|Tg)G8BrR(vRMc?@q2OQ5P|kwA zAf`CA`4QLQaE3IQXfQ!J2CL2@n6W1ViKn(YdH0|o=3!SPL;N%L$N60>cV&8vcKh5P z6K=t``GZWug|*hDmfvO_nTL*%4P`T2SiV~kP=M-RTt-T*^@k=>qTg^G1gK~xH7OUf z9sE;g&1)qN91a{LU01Vap$vLlB?V!Sc=$y>cwG!-Kn$x_IzEehk8Amr!+E`QC%rcU z?QqXX-0(L=Ll{IDp4C&kdFtS9)|uz`{Xc5#=FOgH?%BO%f|z=dhn3t$5NaFpvV3bO zw^be_O`&$|V7^i*pCMvUki>$4V9p&k$PAY)&B!t-%rXSNo-y{1EOJe;*BVU6CVX~* za+l<8zRI3fv(CkY_*W@Nwq7WD>WQ1?vPqh$R?AcTe$N2!-!8c!5&=HN7xIg$G3*t^ zTS3gce}s!BE9|i-x_~eeNQ?cxD*A?1Z+5*G$*&;HCdO>X@)&-WcZ7h%BZ1`^(Jr{8f3 z(w8gx9tj_f{UG`BqO8`}7b)2%DABuT(q`*OC=Naca5!I8$}K}$EdjynFW}0ZWsmq@ zlRyd>@AB)Tmleh#cS7y7t&3-=5DN1RuR^_^Ql^e*ii=BDJsl6oNB9(v+KOBFMr~Zb}VA#34&9D+Uc1ecG3y-)^k+87NH`@TymnGohtff;%Tlh9)K{ zaO3PHHM7sV{7MfZ3(98qkeTrxD6=vu-I_qGF5hb^2zt!^T9B9C^W{%LlO*Oaq%Lk7 zEYRr4vwwJ{YWH2cJ3@-Yf3nb&>;oY`h|A1ho-#Q6Od&(1r>;c{RjJVBbt>PdP!f-% z#46vJ*H_nw8Y>1=mjCDWPr2d#32+_&fxr}RBb5KHmVMAiggKHT;(NGZ>+**&cBAQV3WKb8ciB7kHzdX+KIljRk#Q zM+{^+yT3I*%L#jXU1NXDWg5Zm$nnPBqYz{o=)Mv(XE9mRb-C7fJo}q~$!A#H@d$EzTwa3pE*6lqPvLu3>I>2ZT=m{;(5?F|oz-9dx znmm^cD$)pbJK2AN*%2zJlq(*dqVf;AkUt4J9@^Yp0m2#KrSViNIqzDA|!QDMW6DK`8V zW|(C5GrzGz;MeF8N|+2xqoUkY6$*|H+F2}+F(f{5ddgk0;mg?*&w;Ug7yYU#ve~n~ z?U#8PGq^*Bl`-}5z=4nJjOF?5D{rU#8>(}oo=$GF-tAS2Hx!FW8v9Ziyrp3rN#Vnx zR;iee$K@6?-YC7uOWf8mzkh#J$0y=-@q}>(n3a6mO1GOE?wQBa5Qd}pYbqdQevm4I zEAcD}$oV*gd~NRMEH;VvhBJM~thlqYi_7*%oNxIE@}}_EUc#O43OD4e*seble>Fgg z>b8$9H~FUd#94Q7M;Ld?Dmwl(W|v@=Ikhpn0C?tpLYbOMx{kbP-#B&PmNa23Gl4%L z-}a$3bufIDhW~Px#p3_m?T|3sKh^5A{!IZ^988Tn_4yeKXwYq z4l^nIF%l9qPlPD|f9oKVmc#X#MXAL!Hpn{qNNWJpw_szH@E}Y$l+{d;{6qXit`cP# z+JiGfQ|SNijA-E#L=d{Ndsh(ryfHtl|4*%XI5LkP=@n2-F`0OggIclnl*%6&=-D5{ z&E(n-{y_7T_VT}#2K?T85Q~3SXAO>d+Vr7e7`!th#u9i@b=}wz_y05i3(jb9#`~@UIA7^Ols97987xI=V{#vji{ZyS`d67 zusLXw%g{mkrTP7J+-Qy`7;t7jBYWNR%_;#cl5ij9$Z-jwiqqGY|yoiK0UDyvyj=0A0gW{<;OP7Vep5vH4(TOp~Ar(tG!c z#29L1SBGY7$VVgHhu^tss?*&TkgHEr+cGNNmCz_FkW`^9;ahxa zApkr-w<4WpmP3i@G~#BBl_7YC%+6Z`fkZqa4~3QV<;$eSk3lA+OE>8p?kbX3^^Tjm zz8LJm=^u$l6B{up{_6i4TVq|hPMf#Vo}+a>zdwb{xzTw6{aLb1Icb$`j2j#q*=mS) z{{qGFPu=8|#`g$7%G$EP6`5>MkW@EbbuFXV+QFUOJP{sU1#{?E$ z5LB{|e;nN9|03jYoT(2akZ`BjQF38ave`Vqew3O{FN{tp5lBLop`5*RXfQ_u-5gC} zA7jvZT~NT9ZB!Hr!AGP}cQU>ZGzY-Twwqz1cutxP>1XKDQfR0&3eVsg~zb)su2aJy7pJ!a&er7^ROKPX0l4!Rr^b>tHQ!2rL>&6)m8WtLJ|er=N-?4gZw|@L!1We-tVn z4PW$w1KSQrZl(?$L6&04qc+K_Y1lJRm7h3&hUxS&n>sI2=r8&=AVEhZX-P-Bup46J z+jEU|shs2tam(U*9_yTGAGb%qu)AEQ3kRR5D>9gqhyaV zI~vHq>0?$BeR`ILWFTw%AQTH~bsh#x3IT78beRFQT&}*#NjS>)4DmP;<+4IV*}!KM zjW6H~a#X1LM)gnjnIPTRxX_%Y<&cA$U!H)OU+C~4laS+c zr|#47Hu~3p6bYcje~->p0ElN+zbr0tntW`BTBS1SI85#M(pm11-$ANQxIsgO+j#~& z_;^4zb(hGe)JDkP_<6#)jX(N5m%JI1<%DBT{7IBLxjNh)U*-F}bS#*!Bxv$N-&hNl z&2Y#8`YxW={zD(p8yNoSn9$1ab zAvzx(QYM?{c7+GoHJNk%PFON6ES8Z}(2owYlN8h=d?hPrg_d*2Wt-%Rj+u) zul``M5j8{aYRcQ!X#b8Px~xB62>qoBX+iFQeUBG>nq&+!B+(a&%VkG(bvo=$UDikX zkX7Qy?O`^apW=Fbc5sY@IidKk1I&Rgp8xOg90|Q}1&boLIgLG{FiejdoFBc1i6Dl~ zUvK^c92*AunWatIp3Bg$5AsnbB9b(a^D$Xvg6w9YD8D;4a!FhE1~ZgdxMX=MG5`c2 zRZ1B1z#cdy-o7LjtnXJ2L-uZWYqZb+!-Jj$Uru;5f6!&=?5tE~ZmDUB$GSdOuMX5g zG*akprh&@7fJdbj+*quz4zfd8&kwUWqK0ziR1m;BjP-%Gl?1aZQPF*I=kWbKsb)<> zjhq+rvPgr1eb4k+QhSKWP|oH-Ab7P`Aj;`hRC})Ha?5O}#2xjm+4M&#H4LV@7gMq2 zZT4P}rE~t1bz5`rmGb@V4IVSP<801c+UOltd6Ck3x9~->Z^1(`T=R|AkFl|8aQPC?WNs z!*H#b+4p!nLWP`~-IbCN-G{X9lU*pZ2-^z6s*6rKVOd`U3F+(J#2^7xa%4pG_3F|I zUP-dp;m}&PlW<)HqHMY4gnuwSSB_bYcCX7y?|pbI8y4Cg&-)dIEPsmZk=(%0aFI*} zz|YwJ>=kK*JrDI!mGys^^3(+R1c6wT*+b*|lLZ&+C z-+>wcX`PUo;(%+o-!roJ{-57LAQYuyL9w@mXv%IuHq1FLoh4~Pk409A?m z=+PrnFM!Bk2Hig$k5>HRD}Y1!;%du1KRXidkDrtlq11BrC5zE>Cuy_MOiId-9kaA& zivMNCYsY}^r1fVdOJ>J3GcE%5rgsn9eG&X1-T#^jfxGv?_m@}>i$_IJeo%WD@U^9# zJ){{qqes49m#-EF9;XMA+Qf{EP<5;|{nP`_Sa`a#~_EN(5_DY&}%k5hYdFgSK1 zp^vSXT8pMWr22+_(|BQlO40@J{F~H*#wY$+0jY#cKAMD1db>yVG;q6|?^uVS`asDQ z&0!j*stYvYtfa!8RI5j=-5gE_xF}b|ANxs6w|yN!$Gvi2b_r6Td|CR0DT+FQICaFb zg78e}D5A5-?vDAz2B%D~)o2k`)fsENnF3Ng!QkHk^2PrcAiwt|y@1E@ppAM?Be%_J z>D7At7`3DoD2_$@W{0zeu@Y53`%y?lwu7->B9w{D()t*L&=JqMzv~;R9L=tMe)4Wu>pN|+FmDRYgGN=A zolY2(^MLtNpTK{QrloJ7rSJBzkQ3<65l!#nLPW|w6+(XQV^ZW&_cJX6jD$1faAP=iS zOro2)Yv z22y4JL#js1{TB>zuB}l?4f4VuWz2mL&4r6f!z|OTwjeE)+{-Lq!2~s;NS?{$M88aHxg^5W zLpD|Rl#;_{!8g{dM_xUGzAeX-E67YQd5uM`6LpiiPib#*F@#B|ZK*Gh+w?TaKW*-3Bc)d#Z8LaVJ&J=6~Pc8Y@xS@6eOd~e!xnwr}R>JDt`Z8DPOj3Q|YtJkG%^i z0+_zNC%@5dnOujc%I4}Y#zVTt12yD1W0*`+Kx?F;jjL zGJPV)?qSY6X!W)@_e-d%0x~rn$BU$9nLG#9GE_9Q{IRLG<~cNJIb+%WXc)*^17&-U zg!zZpq&+?%WjsA(INut8!&kJBDPA!Gq7t8TVxaJQo)R$Tt$Q3#FsTNE(GcL!u4*qJ?#3x$q!@=?_Me8t8>_IVWPj+ z9AhA!`?@g*o6_zriPfzCg7dmxv!z*7`f#fkANsTIHARH_cDiID=B0aAaHa^uS6;KT z_&;m=exp2cb`(xw#~fFY4)%P?Hp%N2c`C;)ot?Xkf* z08X9HO6NCgbm+A9Lx9pwnIQUK=ZWh2!DO}Afh*}`fY*UxiYH>EneI|gE1*@5TL!-u z!wY7~6q#C#WX_6-cS!>|k0;6UW&XSaW=zTI$7}RN4#3iKS6IOu>+DR4vxZZ{dHUmp z!TzjK9{Es23ftu&uM*SHGQo)Y^x$TXTJDuIv{YNC@YFI04qqG+7KykThMMS*Q=W^G`LE0;m!$wqKLN+A=&BcP*SxsXwCf5J3Nd3X% ze?pArh)~g&NvY#PDT|pKWr|bkw&Cd7laA2$`)smmDGI+#CyGWt zz0q=%r&ce;M5p}V9~TC1xC!IraB@tVO0^Anv@x*D&bph2W(CTVlt^V0)<*%~BNX^S zU_|CTTs_8t_u4ILZjU5AcwFKAut z&*V4>qS-?)cPL7}`6)!4^*NdTK~(`&DIh)m1zn&XV3zp!_&Dq~epoA{|FNc7J}tMJ z4<1T;V&(jDqJ;j+!Ni1pI{3|7$CI}&2yr%wEKX|>G7sJ}RevtAxn&CsoAE0ZY0 zm?3m2S!qpRhlss%j-F~@OW!1654$9{g+ zt9BZR_pcidaR1%dbVBz;Peyls?y4nETWPG89)2lr8LCg&x5BNXkqAC5qZRF01fHBsrAm(}AK#0lDf%Re5d%|n zp(~VTfcf5X0;5r&Fd4}yH5Z0Usith-e55B;=nGN-y|{mAE5@0f;VfcBMvc7Sc_0J7 zl+1`l6HJxpH2v+eSgiWK#>ibNF)jTXW%IiTJwAY+|K~|w0H!#y=P>IE$UO}#v$`nTUafs0>MRULblJnoVkT(^gymOoh$YJ zWIhgC!L)9EWvrD%%P(v$PS~F`HvJ2^&tOS|5ubhs0QuhQXNe+v;f5NZLB>UA1N~B@03q(`)1$jMnyKX=4(Sw?$niSI4DtZelQZnkWP*q z)jbjY^(C&)bV~if{2Kkn6k_-RPp??w<|zV6#Bfk-1?zQdyS@-=--!c>zq0D0iQZ13 zHDqsz&I`~Szijt|Aw=?$&z7aS^Ov~?(sk4l{1r^1fXnyhOq746*Xom5Rs?mw5~G&h z(1!R#xpmx!fiN;@6wK>Nst3CrjMG0$FyeOoOu&}~3W;lX!F!=K((?t1W`BQPfB#_i z=&`hsh+_02(Sswitody`U;4zsoQWWH1TZIgUvtI>L1;%O(x6o6$g@Q*%aI7#i5iEJ z>=jmQ7!@+0p&wdL+D`3$$~^pE!qsbyAD0?wxTycKUg86+v%s9~p@Zpqx`nkjR~wM8 zQQZWVtAHJ8Egur(eTQdNrARbfvh9?~RR2H?Npx2I=wy zM1Kp#By&t%!cO7}@4?QqX8w0nYa!;>aGWJzCigc&dK$g3l@_r!<@au}?E?A25MUat zH&+)I{w0n=vD|ngBP_oeB(@TN^98v9;_jax%mcd_=$1=?-BmHD(g5r4XPL3!=JeDE-7*m%a9 zHmL-k)K0m~%L2{12IEbaz_Dv@svQzSh}AI3g@?W~Na3Ny9Q&fhM3D-{8=Cb_eo07% zV_)?A@MzhdheUhM@MFDOO6@#YnA6BrJ4K}oBucdz5&;13=6Zn$aZMtPl_Wsq3Y9Pf z#Hnl^3D3?um$e7y;g8(#Tq5dDR`G&nDP4-dkIDTeea-KEYDT|?*FFZNU~Y8LXm^qY zSobW=NpWQKg9mFy=30*Q+w|b^IYq(K!3er2M>*dm(87ff^TQp{}Z?g(5$6tcT6=BzP$poJqklsz*nEEYy)=eJyhq+ z?R#IAqOyz4QP_T9TOiTfwJ}lhM7Q0K-Zi*QHfM?kiWU`%)2|>{mJt+jk@hsbHwo5@ zIR5VyzzA0I{U_gP9pZR)!sKas(^NU^czZRR& zL*VyNTK%yQF*AN+(e5ecreV^`sQWux)5?4^6BGNo@MFRA-N1pX73I#dMKMC?Y;MB1 zR>`l=dpGMv+?{=2#^>K#D)-aicjqYOFI^6=cSLiN*>JB5l2i!lu<<>Y%oY|@K04`? z*Y8f0LPmPs1drXfmR^oP$owJCSAQwgWzVAU&pG>--j1k%785UmG&g z#rWi#)}+5dB(i34N3?Gl+aD68$XkPOV?T&{piZfS_}$|tPeR|C$d&cs`aMI!PBt6= zK_#{nC8MX6Ue0(U6~jycman`4C0#Q1ZRdpiAIUBH8?jfeS0|1q8)#P!7C~8h&vDK5 z5WG+$3p-GWc_Z^zdJ^$E!zh{j)qYX-x2^DFXO+j>8nkC$h9moPeEZJ7IL`SV1h7nP z`(LxI^x>U}(@wF;N&(GEec;CTB4(8(jZsTuXsg0-fG`2l`kMWXVNj(kEnjQY{s_ z*KV~oLl+=(e!heP1zOt(RCb!u3U&L&Lp6B}IdykzCgf{(Oe($G=t}~P49}330se9V zTbE8Fv)z6{t>z66W&(>msrbutLqIUfwzub=K$mIbx+nEoq3iL>lifMW6PeIHQ3YSp z7XkJV+d)mij?ntAv^MLVugUu17kk}(&duUFPJZ&fUQmVJL#~7Kwh!dT6?LZkAMZX% z(*x(=?8PNR7q{Id!Z)up4R8Yj2iXk!(qext_ZgET5<-z*3LJev+w}b`;`&XW({0Q5 zL^XC(d=YKZmk4Sx#roeuGAa_2g^iNu2kMSIhO27MMsYzG{IiqdSKXUWTRYUo1EqBi zRF{RO@;y2u4NS@vx(Rd2vYk-ylGmn-gpGI?eQ~AXgVZt6B+ud}BW;uRtuJ92nx)u- zBG9(Uv;FcnMyTy5cs`@=$9*Yv@=vSB8x=UWsq>>j{R%ph;$CQRe=RJxA6w=~+47{B zes$=9#H3iu5hUp{0!g?nH-;dit?=!`FvUvv1%fP0?{=ad?D(WyqRIFCHk@r*c2?@I zTNH|pChHjE^Cyr{VyB=n<^Ds;*g4n}fr^TXNrPE@$^P?oI<|lGR9!|!MwkA2UxKOU zW4*(aKlzaGA@7FMrHZVVMLx zn`U3hl~rNN^H>j=iya=6*v(W^}`6ADCkL-9Qkx$Ys`Ywc!)j_tQ3X*v(A! z6Sji!dp^D1F(GEt00(XP9)XGZdS`s^+nL$qLQ(EIU(#c}alVba<#W@+XmOUobfM3z zjOdjtElS6NZ%_6+b4)eK=jz>k(obochL>wJFUOfd&bsJzUv2YS=UWQCQ&O7xC? zDn=KDnBS#k>C5{!uCT>^M5g>b)A=$&ka*@lS?}g|Q?%M(xWX7MJ^mEQ{F#^7 zyRmvb5rg2pKv!bgSmU5h8ukg}d&=}=OB+X3;~>^x+2_i;_45>88w6&qQla42bWHIr z=77ZSsIUh^X$Fn|F6!JV!D`KE^xtRl-T(DW1_I})MqPgP?>)|BI49H{thP>6V!mYO z=|l;~2FRg!+=o0Sm!`ruyUGymzd6XdK9vrb?iAl-%Sl-c28Yt#59VudTi6E<|9L>~ zKse|?p^i}JVqXGxM=UE?I6Lr1{RQ=I$dvu{#_h&YUu@lz8|Pd&JwRnj{j}C=n|;5l z$g6`if%E{`m5{>*-6tX=OugC~j`8v1#V~dp#Fg%#u2qRwT8RWHakTD|H}5a?Ce+Jj zt}h%`x5_f_Z8Q%5Hbny0{d5 zSr?e8aYeoJFUXS5csC}ACsXyC)>NtB>(l3VpBy@mX&9Wf!YNG^so^q4sEf86+$Y>G zI4tLng`6_pQYqv@+>GUL5cqxS>wZPte?B6Zk=AGki1L7JD`rR2c17Nx)61+6#~>v- zo~+<4wFL#JDs(UQPJdP|F~RvjRdYkkC!)EEAl&NzJK3^VLM+QuaSg0f(RP0dLw~3U zJNtJFf#R>&9u8exDJS-SRfMk;Ku_0-uIRz{RlYOvU!!2qKqxgi&c` z6L<&42kKIEn+71K_b2iCx$#cDgQ_F!qc8b^T&?a7n&4o+W;5@suF0s&l8mfV-m4dl zUsIMxUGy<%f8O{p37wMFjOWc`mfWdY40tlFC*!|*wZLh3%l1h0eildMg3Oa+p4IF- z-xJZrkwY>Fn!4RM@v-94v`DYL%4IedY^7&6@V33?WJ`FhH}2I$8aJ zshVUnS@Y@761{42O>+->9A`xGZ0t{dHca#H+-8iw@{b`@bI^TPku<954f~QAnS`-4 zGm}#5GqUsx2bIj?s?=07?zinW!}Bu&@@FVhHWpRZ$8BABwTaBde&sVVPRCQd%*@^? zTpB6}tBb>gRiEFLsVbno{y?B%9X-Bp$~GD>Rb9it1bGR(H~5EZeEz336|Xr zRDSQsbjirA=3)E->txqz`LdW0fT?`tb;3qIh!fw}8fwX5R)8EohV zCkRILg9uW;%U%$vt8MZi&z$qeeecU`(DM<1<&RvHBl&_R8fhX1F*qr!do*y@chNU+ zEtKk?P1t#=nCsez{=|SrOf2UUW{Is*{)*6B5Pf*hT|=uJhTU&J|r@0);ftZK?i18u(!86#7kb0y7`(lhiw|mRA+B(H@8a< zrkukIV_FN+BPB%h8gNvVT4ZCp%OqZerM$y>>gJZ+_myb(jfuWi*_{~zli^qs>xf}} z@HHO4J<8?x+eD$g%=zMs+_>{?s;BOVBK-mwqvcc3fc-7)L*nITUs)I#wDQv=ewwNG zO{g5a{hsDj!8x2f$)547D}4F>oznIpJwjkChn%mCwn2qFTa~Pz}nTAzYxfz`mcy%D@NNmuSpnI$2)*oE++>VUtd{ zJ6m1xdu=%lI{5qR>kwj6mEsl1x6mEV<5x<1HL@>nejU9V-5#&8ZapTgVbJ<||NZ)t zM3g3{di=9X4RzT%o1jl*kD(^7Fxc2u2|UGC)=qPLw->&Sn8fQtap5TF^MlNy^kkBL z?4Jm0LIbI_vZ};Hww-P|wEVgH;<>!9&-XIfY^b(l>74;Z`#!5Uaz&_Sr0Wwpscv9Y z@&DuNEugAg!*0<{35Ws&fMZG!eoBIa3KMqvTrIzTxGW*P_@m` z)GKkQ_AK8;MtVFMw>^5ibA*WMpS}Hqz%@FKdan~~Cgo2e)#MYgUikcxx@X0l%<2O_ zAGF8e)C+nLxTQJcAKfA$;0h>J&XmO@u=zp6D&Fp7S;ezL4qv`!+recU-PU~}Zk{ds z{zd9&WP0GMo;o)3tFOKGlFJE_y%Ka(eJ^I~Y_ZnlQ{#~nK+UY@gtxOT+|KHuNpE(c z7}7G!9^Ile{1^?tq(>cB;%qnOK&M_~n02Cj-Gh%p>AGw52dj?Eg1x#`<6)CmBuhUL zQoiP^4*#1<50@UsZ6%?HP_W1cu{!5Ktj^9X2CP)wa&yV1ngxlv>yOK*dSdDDt+ku- z)Y8SS8$t{?NxIULJE@!~O}#JauWf!Uf5Xp~JzF74NWj)N&p=d7 zMKI|d1LQ-g4)Wwl&55TH779hON~H)!5$?)Tr@s4eWk_g!#-Rk_Ub)FPj0l!7m5iX= z3nMt?@9ByLOZrToWtPL0JXQ7Snr~fn<=oNF{BsRw;snbb`@`AxF8m`K(!eZ)ER6MM z8++!f^?F8pWJ0RfgSvyTOjgY*%o#5Vj^0XhO&l3xxq&2jPqAOwt0~23_9e0^~y{MRZspVO8`C@D|3X}BrQ z3oN>ZG7gKHHzV7*Iw)j9bemcd|;M!9PUb02QO z@nVN9ty&BtF zlgN8)@;FBx6DGIvDI=!Tr4vbqM|bu~5F8Uf_beB}?lgr?_SWTP#y5FV`Z=+Y<{$4& zABv_$I~wUCUil|{G7osc&CwH~f80PM90mJ;euv~FS^miYG0d41W` z&lvb#*D}XHE>Ay7^BeV{M5?k!X-m|`W&%0Izq zH9Lb*s~llze^B`DNC5-UcCW69br}b2bTR{OVlHE7puu4c5>T!(hQJLI@!tPy!mW)P z?7soY<99Sj51~Wx9jkf4Fig0?yxr!ckIk_@^<5v0%;=W6kOMX2I*)lAM>csk_F0+; zf}>Bz#qE5Cul}ZEIaZ;eUW#Aic4mO` z4K{gH#wNvdLj-|zLfsL`P=-dHL9XgG8QmlOKH{*Jz7DDzqE!R(kAr0gqVdniYdz9` z2XstLk+}e@RCpq%M?WrCAhC7?r!2WyhW?^JUlO zbUuDJI;m>QTWXjn_tHub_IsZu$x{m!&z_?6sctuc!EU9mV3myx=n&=R2@JRi5& zEB3I`Wk5W#(%;pAG}`|bmX%fB%Xl{Wml@ujB{wYiMS&XI*6ig<1P|A~v|D5nIDL_? z^}t7Tqxs-*T`5l09h(?J1;<-t)|tNdRP8!w`CIfl+tSR%RjtRa4=amWt#>GbI`eI4 zDk-&op3>(#PQ_=+B?_;(r`}$N(BD7*_K{koOE4l5g8__g;(m5cAOFbEH84>;^Z{jB zK`(MbREsFfJukD489-glU(w?IYRn6jlkt*Bd2D;6nf`e`NC#cSpOUSqpg=rqkaq|S zVpUrDpEZT46#y(moZRNCjV(;`RCc8bDHC!hoHJyD*^;b1!-9@F=3hKv_GmojJwKm* zQY{Mw6?*tnk$S^*(nrQmjKAwq6@0~~AldAM#9pSTaFtXD#6`PQlLPz{4fH@p?}>Pc@3^oQ882g{JE=ExpH2=;PW;^w7Tc z98$+|r1$}{8`ETi%VQcwwemvU#3G|Oj-)IBXFd*qZ1<0liC9jj#{~to!#f!sgB%iPY6U2?UP$Y&71@BzBv- z5%3`Yo2`-2f}IYK)(Rc1?W&wQpps)93SwogVeH91Ud-x z`i#uCvogkylkA;n^`$`kT$cUg1IJ$=oiK74I0&)hAHH)*Hrs(3s{y~oa|KzMdDVHD zM{hLHW_9(b`+kalPZDGR8msS;8^;{PTuWwLalSS$P|a~|sE#X&!xe4%2oCOtXP8;d zy(LA{p1Gs?QWoG@2`dO3+K@3Yl*D>&744t@_{llD{4JRbq}5{~37J-v^SfucDn*&q zU8_SN0F80KBPWY+ftJO>U5N1FB)M2^{DFjOipm0O~Lq(peaSen&GF5wF6( z;wES6r8*@G8V$Ce9I~yZsx_)DUxua(QDlF_r4whINCZvlJ`7W!AFqUO!;7C)l61VC(E#Blhxy~eS`xaBH5eJwGG3g{c z_4umqH+mkH;L9H}+Es_}XGC$W6g|Q2Z5_weLq=`9{Z(~Ni`N0_T*LV%$=?`I;N@^Sl!Suf@0yhBMUR$6Z#_nPtV1`cu zsx&hNiuIB{oE~B=6Ct{cT3_B5vZxQ;y|&geD7}vbz$=!?-WfOH!IVYcM3grj6jn#8 z`85J0$)8snB*|jn$KCk=sRt6%TPZ{nKz@*JVj@yFCu z-SzkEm2!;lg`~#)4fg5(zrj8fN@)C*!|2gyF}{zk-_z$eM8e0%C!5TBm&ber5obT? zH$spJ$D(=)v3fK8b=Pg>K_{1T*IS)$?Bf@{qxIXU+YNO!;$~vo&VWMIS@($gl+d04 zDkw*R$_t(E(Kd>1313k*)O=IL;qGc9*UCOTaFem7!siaK@ zL#^+CjAAHCu4^|%Sv{vwTpWQns5xC{Pw67##j>sXC%SuK1r)Dn_4QCIm6V9@wl|KZ zRnQ^XLlN3EOY{DJ@M{AIrcfrAvJ~a*0@-EVD{{eO%=$adK2V~$klxffx2s!=t&*#a zviF|ZVcCda8j z$e%vS3?D4cNxwEE=l3MMrg$2*?RKRaKvKu6rS=^@Lwaw2-w=$%vSqMzRF9(}j@Qdvxs~?sl#cH~%y?_-E<%Co~=}dO!frsf-JrZFbG0X6x#8g^qsqrv7 z&s?cI&q%Q@MF7^aSh!_k6t5h!>Dp^~s_uIyR$ZwN3pNXQsr(<^Yq|^jZJIS;I>jjm z_K@=L9tw@7RL~;HPyrRQ+De-mf||^g&aZ=HMonK=4rtsOzYmtT$p2?btD#x=DLuo! zNYqMTX9tJ$C(|%cy?$fN{S?}Bvmx?4*`)#j`HN4sB7jpqlF#e;nYn^Mo3>uPGyO}1 zL-iIvfV^@?RVD#F&4QQAPt0#21Hu{5fUSx3TDo#xU*iyzj2Xo=8~XS><15-i!ua4F z-Nd(&P3Tw7S4SkEaq4f$U(Os=vY0%UAsJqL6Ee|ehz-aBU9d;hQmAZJS{k|NC^e}f2(+LO)E&#D(pl!s6Uj3}2i|{EJ$I*b|?zL$%nx;)tgHHdh z1R*x36iXl&7ktM6sITO*d3N3%x7omn8eCF{{jdoA)KPM#|G#-F>R! z@5wSi%V0%(94siR?NZhWl5?+@sVQja^2XRb4)-g%aH zrHI7#_85Pd*!@|X0e|Fr&iW6f-{)s#v+o~; zuW`&idC=H;9Z7q|utc1FkA)5tM}A{Zq$5nV4bs1cpvpqL_R9ZLxkm<)JfbVU?Lmz+ z3|VXkOEch`9ymc|?JxEGqyQ-B@<+}K?~teTDOIptZihZ`R0t7AreqW~7lV28*JQpo z%?QR@&7}xbSy}LWe3XwaUmpC)hg@W?R=1!2zFM>UU1dPCb0HWS<+orNW$;>=jH{V+ zTf*t!=UBmGlZPTaezL9b<%@4B^` zgvrVX?s`3wP>K5UJD>(+U1k(Cd8#IT%h#375lKB2Ia_;BD)uS@%Z zCXz-1d%Dh1CVqtlQxa0^+f4>$x)wW_;JXAft-b@YCY5v<_F9;^p8GX5yM)BBfGua` zA#)5WT>ps%f`e2M}`5#EIJW^LWo+D8VZUB4F**KnUpF1pKNxL z_(wQ+?rvVu4?9Czk!z1xV%{p=Ov7i;rNSVAiMg?GSrtGL){plq^#(D2nw^%>5$76i z*c7ckGz>PYzC^`y^?nTfX)G{)UmB|}(g5m@gmvzBXF+(y<+!PGdV1Y;4uj5ss=$y}Pu=_>Ds^1E7owYH*}83=BBOeLqSr@kFl7Z^lPuP6Mf zLi?jf@tm(kdk1%F9}|yt+7!NcX@%C=meoLhyd{lif--`-UUQIPe{m-i6{|q!Nv|A7!y0v!ru6M{e$bjez7mL+)>eIIaSrRx~<7J|3K=tMs zDUZ27P!`Wn%n<2{r1G=V=Wo>PhZLAS@ST5czIO+_zZE7%N7+>tV<3VH(XjbFFiZS< zI70j#K^m@6%fa1s9_LJQ1-RIm{iNhb?u%P_FKFZ6jm?10m$y<=z7hd1``P_p7V1iu zhh9enRgJs8Eb4D^jYJBS0k1e#o{tqETmJR6g!GbyRRh-ujJod2t#?NFduOLz3S2Y$oNGgiZZw4{vy9bOiz!T!m~Lj~v_L55;25 zz4$h=v5LHTQ<+bXSv=R-7p?~yQOaiCFa{!(BT2@G^Dz>30|SZl2D3? zT(f(Y(LW%S-z6*C-QJFNmy8z*xA z>0l-rkOh2g3tSl&z`Zbu3|1T7Onp*QLj%;`Q~2?L)}t~S)3Zl;Ax6?FFhgBUs6YY_W&i zwM7VUN-P+48xlABCj*)?Z5uYZOYUvu-W8#9bv#Gv8MRanpw4ui%AdehGN}A*D2l-A z=4mLz#lw6KwHR-3A_@p#ru2HjIBYASI*;=N&X0W*H_02drzE>Dz)df0mm6#oA z6;_=`*i|Axina;s){$idZP0z5obzuWUDEG5C8>3}Nb?M!XUP0;v^{zY%D4&+Oi zxsG!X5eG^XyB=NDB(R5l6dDYN)SBa!6Ea+j@rmXQ>{M``rFTan72;K#hF7=6Vjt?L z=YYxV-)~EjBh2qLo#tEozKlRAbsT%1`0GjaJr_HpVb#2nm)ZqOAe-Q(biSa)qnCUz zJc(fJbSn1NU-CTnom7a&H6UqGhSx6`xuJq_ylJf6*>`ZR`Kz|$(S(Q8KI8QBKYy~E zFnoEt8z&l)tN)XT?2Q-R)Zv1298{s{(Li^-QOdnpUpFXT6C5QELS^-VPJQX^BcRyZ zObl)GEwM=eQz>=$BTv}oUiE*kh7{VO(Htj=#O|F5fT7dHf8uryPEI5M>}DVISYB3o zUb;TAnhbEdGWwSbKt;V*9n=%>5HKHrLN#ddMH>>2ubwkJj(x>dPV~MH1O?%QUb|?I65mj=khFWBRw0dGWB8+Z%WoIO{9KmB zc6&r6n~cT!+BLBWyYttRW1Z#iaWDHA9wq5vMz!MqI_`j$FU-MUf*S%QJ^LSf>=grU2WyfjGryVW8Myymn7I||=xiOG{tEhD}8 zPZ)R+!#khgRKYWI$f!32R$yVBAX%9&T6Xf|eNaBO#`n)B1!P_zpiMxgDJu^I$RB9` zSylfKrlEVFDIzXLC7r!X!b^)(043NzSnu7h(*M)+Agos$bO42HT;zWAo%2nHA{p|suzT{N9p2Gdtdyeyi`@Hr0*8I_SI5-ndHOncS znB%PAFD;$S__@HA-Tfm6`A9!AF&lT~;bU<9UC_(OFf};An^>J~*OPwW-pGHJB^iZO zW&u*z2xbAQZhuUCPWRKjy{F}YkV!ER{s1g#t<8cj-o#f-A%<%o!%Tm!(vIS4dB{rZ zEg;rvKosDx@l2d|@ru?!tq{;8AxL}-+JhHB!A&~5;*p(K^f;H&_dDe^I*>Lgdwgol zA8qXiNM9ferNi-z;mte9Gqj4W#Y#1cL%WfM)nf*hVI6i8gNfnDRdRzJ=m5GTl{=J9 z)c*^rRe|?s2h_?g|FFb9pIj$=ccV8X_a4<4}hNB$d6=u_9IBJf`X z0gO=%M&seAg^;4}XocF*h~1x_r^e0`v9X6h_>O@OK#4%lOuD26fI$Xxm1r8cjiFD` zJdT>gYZVL*7`1)JQLT%0OTnSw zOER=Lde#8ttjCZN(uJ;9U)o=Hu@wb=jpN$QlnOzpV3Bqs&p8G8Vyhws6Ogm(C;agh zfh1x%u^|w&ei>KOGp{L>_LYTdaY#YHGFI&04FpcAR;1ic5w+94sO4B zh5+*7+e}b{knx*}y_B-rQ3ypJlV=5DT?|;gW{?W=%_|q2Iwd8}=g3Zw)%~JjEFX=! z<=gzb31`Xc8iiC{Huwd5kn9ta2y~(GUHdz>vDb}k_w1~@vQdT}LyvH$|L_!tsT{&X zR(}AOOwZo8z{vdK>kK%=)PQ>v2)wprOT~l=pd{TSJ*}ui zpA;e_B7nTx*l5BNWA6oVRyw2r@0~*)d2%YURU;16p~vdN^95tm>Ek`V_Gz^GRH)p> z-!Z(rymk~=UkeuY-UYQMtM+w{ePeKD=FVsx!!{7upl_H@S*mho+2? zWGCr{`^WZn$Gw~Hg*RiRSTA*Ryl8QakURUd-@WVi$d-yCzVu`yTe;HvX|sE#YWaju zg12CC^3FGMWv?QvpHj`67|ydofn+#>k=(YLm270x8l0=Nz`N4-=1x61nqwL{7lJb` zE-d(n1l$&zkwg`gWh3CK@=#Dvc>fK+0e@hi!DJIvZw?*-vRpE6dq)_VQicN;`E+>~ zBd?i1xV*d=&aQeAgZXnk-?k>JWWZE3S;Z2hb-S3RpY<@dwT{>aB*(*cA!7o_wQ2D!t-6Pm0~?kdmoN z9e2@A1+j&FQp^U+)m~-w1EiM>tH6^Nla4*A_g*YqBl%_;P4?aX}XiVjeKSGE|f z#!5C*W3C@FfT*KoM&^QTNaBgnXUNq|S7n$$`*rjB2)T2!+97644Q3=mEG4xq56lv+ z-6$@d+m8x2jPr&+>VY@%iZ`zXKEu9$5>-Ju`GhB$A>3k!q|uYeA8p5CnONYh$%~Ok z@*o@zZZ2cd+GicWaY-r9YP9&JSjE-z0wDtWm^&YAT(Lmk{!hKN+NP+2HYHAvwLY>cATQc?51L4jWC$V7t46NoCGp(e)*4< zs@Zn<+Miuf*tDwKfb?_dlh`~^kEm{P-ZyaABBpM3y}lA$?Bv_Ve-?T>y#t)l!ldRD ze*1v}b&j@>HSZ5!s1zv5H!%lYK$wvQ)2MT0sXL;i+4lH-3d6?67O#*Kh1L}phBR|U zYdu}->~?JlmwPFJ{0c(z-@?R#yxGmmG6lFF-p1w>3QT`$eM_qDL76wDhiw-8((iVA zXkPg`XNbR!gWemeFb`I>*6Al~=%a)1wQ*kPGjF7j9(n7p6(5Me(tFF(op0@Y zJMO{0e8($CAV*Qaf+`Ce4k{-IMI<{zViN=`078o zTO*%Hxn_Ld zH65Y?qE=yKW}g5SK4u)o#D8pY1s*@vU^DTBKB}yo_XWN(eznyF;CMYgw{!Y)M#0xt zkhP7&l#y(X!z9*19IU%=dg@(kQ?uw%;{a1oZRDOp2JQkH*!zVn_xZz53fH1J)Zw|x zlaJQ6L==AI?wX~1Uh=86T@*?A60#QgzyW{trs9-~3ix@Z;?A+nqKS7?Qfy*H2mqs& zYwKp{%Y5ASYe0^q>-D1UWu^^wtW9sRePRi%{x4LuH%|k+oB6s@`FWmGg4jA*ziZg^dXyrkt5UDEjCA!=_x0=XItfb!x4ftLdK9%3@c%xQT9Y=I@- z{1q*)+0?8CSg6?~JMsS(3I<{skhFqOREq|js^Iww8;O71cfEwWmxBf~J*BinJI=tf zfKPr%QDeJ0#J2H6LGA^$VbXX|+tKNdhlK(SV&OgZZwZ~00TQcJ3Hcp+ky4*%qj0rK z;y_zb^`ME=&7o?_^M5V_&>wT7TdHYJUQ1D-s}DSFrJ}wo5gbw@70}!49NbT-b5`!l zP%Zju^DS{S`*32V40Vh`C-OQxzph$18qOs9gd!{k)W2$v=gI4LQ=>&av}*C~avXWS zl>(cOY7rZDHDH9xYdy!1mFeu}Mgu6dm8xIm`W=733t$YyD7&G{zJou|=%pEgy82^8Ok<4OttuZ``=NrQe0()NmT5l3#NzDl?;YRT>e; z6Wu;JZt%fN0Ec;P$NF0?qv~yzwH-Y1tEcT6jFagBF|joJxt~v}?D*xRh57K>7yL%m=s; zaqM+MaTUC}VQAPz?j!>M;1dg_;~rtA>0T&&)I)E0p8hJP%-yO>NQ?leyFfkX_rE}M zv$J>Vm`q9CiF~4EX0wgI3zRlsH z6tx!*mfb#&hX!UQhww7r?w{Gn-2-zmAkjGL7c~|Y9V6|a5Sh%v4FGp`S|bi<6W|NE z?+_lR9=x}I`z;0rXrp*A(Mjo$l<}R97kQk>>;1>x%+h!YpdVRk-j-*=Pj=NXyZ&C} zVRLdR@v-8Qwqk0?`^^pgg$HZj9paC^sLpxI<1>(A(h{W;6CCoNh#oxO<5 zYU`h@7b%<`NF8z)52bknOka1jQ6WBUjfv`sxJQe*93YMX^d>Mo-DhrS&aX|Hm^{$x7-dZ%%*kboD(m5;)xQnJUB1j#AYp(9dY2tDM3ID8Sw=u#KEZ;r?Hj04^GRqXmlIqe$j!=f(nzt+MUp%BG}qZR@J-^qi(xW zmtI(?%8Z#`%TH=;x;Ug^yoHiDv zvse-qOq}J?D`L}|I;+x3Qu$@f9g}Sx#M)n#qX8L zXB^we>y2dZyg(Sds8`~hEgrKeoUK(pwwS7Bi(?ypwne7uce5k#_Y_kgJR5%q_3=UN zjQ;A1s6#%rphk8@x-LV7OPzoz7RPp}qh*C<%yu&c9sA3>ttiJZEuNxx0J753LRDNW z*|;_KKSLWTv- zw7KbfWTxC>w~Yf+`#stF^cD4|$7|i;OJCHfT*_%DS7o7i8Kkv~asJp*-ZQwIqgQR# z-nN;pAOak0ZMpOB{(0YrIuY1}iORH~Y@&>*)P@`HKKJUEk1&4{Zk7ti?$<6x(qmcZ z6r?w|EX~%s(kvsrv39}Bbg6nh$Y<=I_N5-X_2N}m>qrIT+D`DnbSf-&2s9Ri*AF9q z-BuHub>Nq~6$p7%Sv&ieez;;<&9D%$-s%TJ)pjmOt`DcQcbqS4-{qk)L6dunMNOn+^8t ziG1En{>qzhk;I-n7iBt-zTBHwpRyXY{ik|Mfbnka=g+SuE6qSX!F2(n3jIB(DPAR& z0zzKzOBnDT9dN|Kll8mqZ)V^BGyEh+yyHk-+~@P|p6!UmplB5xoCe?+F{!Y*9JZ&u z2(0RG#6Y5G{%dFgf1q4S5R9qGT+R9xqjYqagTc>E4jK_SQ=Pb33QI08g)1dCehZuh z&VSx-7t6kr|C4l;XMTkxG?kaAf~Z*SXLV6h*yNAy0vCG8W<1E_1Qm#+OEwE(5LM`bXZz!Kln-TriHHBbv~Mbrrh}U1?|f!7(T83E#xgRL-XvYlJR&sb%G1cNx;9uM4k0= z54lh%Sr~2YasI_CTt@(mr+IDVBNtkNncqzC!Kl*0Fgf zPBR*elAcL6zkoJ2k43aeviTTO;~dn%)tl=~a{u5fHoviwHz=L!X#_E+3sT~UX#6r5 z`ggZEsX#eR79;+nR5LPWf+m9cBP(^5<>|>iA=Gy%_hb?UxNfiZ`q%RhL+JvcWB@x9 zIgt8%@$9!*siU->cFC+$s}rVvlpm?mt0l77tol~FZnvl|nyboghn=l|CQmp4DsM+N zzl+$l+1*fG5y<{zM{y8fNybr(V*Xi$+l-bVRr#15!cqib2lO^}WZt12_hJnc&04LE343UTC93*DN^*XuI$j{tq927 zY@`!4)L)N|v3P!(_w;zG+vJsZ9>v*6^Maul@j5*3!4Sw#RDULbUMMy0?+ujMdba@Y z51r1W>m_`a?4Lw(=cgfGIn2Um1dNLEP*~#jy`R;Fr)`OQUPmhtxc_hT2E{(emu({d z1#sLAV1#8F&_T9u9mYBOy#G@_ip_zgWM!jv@E%Q*{WxyL?3lGd>#>LQa_rOElXYh{3>szmDu!nO{hIji;I&Y7|WDM*50xEjnK1Pr?6(_ zB68V;8f!}J=U`$OpP!G`fO&~IzQO?1Zj)YsodH@vyW%W4L-^evCoIHCUSQ< zs01)(4uj6j@>;6oU+g@dRD+Cr;C%tt+W;zrHm7y6CmpmEP357v;&XRnU+%}jg1GL4 zeb;@3bV2pwOWT1=+xzt%ClnUE+h6nSDV&dvNbHPzLrGP;H^p8-qfMO(dMcy6D46&i z5*r2qN*S_B%e|?h{R~kPpt86eO|L4w;Rmoutm;BdKq6-;2X8+o*TOT_h6OSCgXL?B zPm`NJl4%YafC+4T9kjwLMMCbFOdtQ}wmcOnFjGOd9y#5xbwY-!)EtBl8ov%eo{Zr3 z8OP1U_(ai!(NP>zV!Lu2f2f@)U|2_BBmJJ>TQsdm{izgh?guZa z)4o)6iDfC%>Wd?{qzh56>wEyG88Z#-e8VNWhlz}Ng*`|mNO}EzGP5XE@O_|rg+hC) z6`@`43=<0`;QH3^Yqgh5Lk3Q8-y4VW*+NrDjjd)-_`$)ir#f7EQq7AP%Y7-NMz@W8 zWcn%z*QO*^ny)`kq1&D{KGki&Qc~AUi2mxyrDId$Mok166?EOFC(F zpGdcbk?}|QIhPcxG^G-}#6W@Y*Z}b}A5Y@->U-?xjCb*8uccxhD8fAb-}Ztq{Hubk zm;{2`WRUcT42IXBg3ycmp7eol1O<#lOk`sf&tPDp6sw={(>%s_B@4Wx>yMSq$__B# zTD}Du>;T69rKNuun~m%hz-@Da*^~rM51+KVI>uv@F1fmSmFz58pJ~6V$gcLhcW4DO zdIQ;_&#H8jb3wvD*q`EkXJg1TB(WMQ^!@)FtV)qsgZq6Fts9Mr%@7pB(R7laZvObTbxTy`hQ@Wx)K6t?(^@f)gM8J1FV$o-_ z1RO7$qwu?ZG&!`@(~_>?E?>VORPIf%q_Anc{z7K?Nf5&*?D(#HZ~&ApeZU=PY)X^{ zlz@~X|73pgpKtxqP69v<8$oo9c`vZ93)8YJ0$GcH?5}@&n5g&Ikad#x&4*Dj`i!S= zj>#u$-PrwxTAYAVAT;GskN!ysrjoz+Qm0y&(cC(Q(&RBYeO4?63f9L6@e4}QJWq@= z`5D3)+w~@8^F*0hZOK?psy;Vur5=F3O&2W1-jAJo=@1V_daGP&nWJWeq(NZo%u zt|K`+SdMgDv{zt&W6q2ZXl$gsXuW82qLnisfzgUye0N{QT)(=DiKJ1A$A%z+EP5Lu zlHs<3L62Uz;Y(nS$_jsd;QKE-{0N0j8zlCqc%`(+Wo+=l-pj#5{nKfW2(2s1y}g&5 z$e_$a9ZDuZ`03|YsO$Tb8drj!HkMXN`*DtqaGb+_B!j&>(8y|L#+-I_#i>bu*4!E& zvH!bQW@UOt>ui9xAmvUf=GVIk>DNrQE#-@sr3nzaT5~p)3&o`!ZDlXIV8#SQp z6^veEEINK#>H=eq!wl-qAoQfO-CJiGu^v^m`gMHul0-?YzMuWd?P1+D`N3x@I6E{0 zK)$bTw}SUe-i4)mol!)^_GHNOWpM#fVlJTb_c-@AvZ&7Z>0LGye!Adj$#SsV{c)A3 zWHQwHSwxHr?APmFJ>{r}ZiI` ze$)0E{|9PO>cjZa@DRvI02Y=xPo4Z?Z1TCGqBd+Fn45auvZ*TH))d2xXD7~ut|J^)xSI*JGA(~DJ{ zh^JL4qrI9|{}Q^ZS3Jvi{@eoS>kYgERJ@2!l!(bdbN=~PY`||iQyyHveZCCPHdr}1p2tp8&OgxQ0 zv#YV{+-~hJ^5>p)(WVKw`N*ObufKCoOK$gvdZsl z&LCkfcH+#S8h+|)Z<`bK7mzVg5bmMZgM)<(#!bM;2s%FhfG~)D&5}pxLOv4;N{P8H zQF}*?;hCyU@kW}1il(5ZCPFe;=KRZeZ?BHt3eFH5w$(*RC<;}!UfzBp0zerzl`WJ` zOc`)$_r(8A`S42lz@Nvbg6$iRA>@Hu6Ut++zY7B114uHViY)zE4KQ*4hXX5=0$Tg6 zV`F^3Z;2OvOW}W5Zrp1Q57Cni^4Mt)A^PD9pbuYrd*vu5)vyvl68K<#X~}P`KfQn^ z@t{#1o$J+C4Rpa)&*!H`OP`>@6J zbBvdnb~*?3!FW7L1v+x>mg4*U#VV)}hYkMO(Nm%J z=cr?|2J4wy$d(D?P-x*i&VL9M(5Iu(FT4!u^;z(z76aB*@|6M2e+x$jwfgU}(SH&_ zj)Gv9v=7Q|h>8E4&~b?U=Ee-j|6f)W6n0)6tq(5naT@eOOekRFmqzoq!6xXwcO~=f z#v{`??o9I&u$`~ySLxC{q}8WJp7S`l&--S!P?JNgkhm{Ruwb=_?Ny;)+5)B$Y6KVn zkqGHSxtnSGEg4Jh=NNn@={=Z@L8_87Me6zN_fxT}{bdob6zPKR_H`~A%gy?>UOu4C zTxU1D4b9h>E1p6V1jxuJwwu#NM-&Gk)~09Y0~eexawLn@k9RKJFq+f~r@|i+3H;g= zF`>rGoEB=Xg!lQ!v9=uHCSKH0>YKtQ4Rqo!!(!s` zd%C~$jrU(*T7&JkUA-`Byve;03keHZC*XumHk*(V`h(j_1jEU{bY(JZsvMdCs`%L%`AEvZ>TM!# zAg#R=xUihC|BYk8A`(InEvRUw3~G>gg^&LHNFN2VfIecO z`nQ2$#CZomKNF>asF{!zX&q^#hY$X`?f#2YLLsHKEM~3jV%`fFn~w$2C7SypAP$2D zd|vAACU=k5TL$V*A-LbnHu~X~Blg>Pa^IrM5+92Zz^1^oyJ#c#FI(VMqT0Ta7!Fpu zpd@qk=j72BCtv^%Z>zOk0|`*M!t;6zsBZ>In9%{4B4rqpL`mrU4u0y zNFu@ll^*Hq#%3-gYnW=;+3cEBLLhS$@gZK15J8!`m;TwW@WA}3AmI{u1ZW#o`$=!{pI9z zZ^3Viwv8a8*E3BQpO-?-9?Tw>aAn$*}isjycjw=>SW`dLs^>{|=*VK|U)Ff$XdR%} zd0EI;%6J>P`c=rnJ-&l@aCtjt+$M zqv%q5Ty>kfz42Mf`qcp`z!3w@ics~e*b4h|K~>OcS4FhZ!Qgr$XBCyGoD z;q`)$h6Vn|+F|}(yCQQI5rPtyv|8I%B87CJ7T|2hPjn+>|POWyhH#+w`Q@LCfaS}(* zhZes)(GXfA64Yy7>*IJxXs|W%+59tq03)?#Pa=v%6us*0ACwD**HOw`pvv%4?S_jk z0RBdajO&#nbm6a~FZVksov*JvvhTxu^})a-0lPMF(EBC}K$BxZ_u=w#y znwVDuN?zLgpD~{`bvhrevdztYuf!&gLuC!~cJ?+-8exihYC=fB8rhjS{kIz!Im!y3 zsC5zKwbqQdL_Y?Avu0X%(2C6zZKi9&+8oV`Aneu3EVYPQ2Yi)6d;+`8V~4yuXXgu- zU%DvOf_TvRBWLg=H)4?|4vl;&EU>e`MRv22gEhc9)*w3?@cN|q^P<>J;D#npr7PFa z0!IXZ_f#sQcmV`7Td6D~2r{F@HqQSc?;O!mkeTxGx<}vOp;1i@8JNCo+as1<&3!`f)~gNWfCtoy2!p|ZDhwZ!anXNuI- zh&t<@7i$U^p;a>9fJIElXJ3MfYeCj8PwZ|@G%JGA(3 zU~yVcrkB^sRh(-abv{lMavQ`lvZ#5HjI;FviH&sZ`N3-`n}b61QR|to?Jw7=KgBWu zOr7{>IKt+|)jD0Voug*KophaNf!R`DDTEaw%W^G~!Tg&*!*RN-g%`vtCvuOpC)18@ zW^cEej+;&B1kafHqZRYoRFQ{$EUPB2LOPm$-{KFA8l#9w`ubcZa}@eQU*Kg|^*%nf zU4%~s0c>uDOg#JgNFF{pIeDhlyZchjnqf zDy^!%Btucep>?-}@@VqcuLLpPI;9{}|2pePG=3|5&fn6iMSioOSl zal{v%U*~%ZD89bFk<{(+j94G{^rqiQMbkd7cizu50{l6x<6uAzG3wVL+ZlSsa_8+x zY_KWAr{iMr;N^3rqPB}2V1ftS5T4n%a_WBHR1fKwE&{9Wj3$aA4%VWp)*o7yZ$|V7 zZR6S#s{czC)Td}59N}aRzo&C)n4T4_Zi%Jjutes1FG?5QMx;9mO_Uy%ymB~}&1fiA zEg%HkgMp}+c>cxZUB3hGl5slk>2GM&Ic(VcKD7-wijhx@^FBTS;V0Hy>tMUMbKZQy=cfS%yqu&S)SvLJ2~2S1dZ9a*4tH5< z{{d(4rSo7a0m5p(^z-B9zL}>gglC6q5?SJ5ig_>S&S($skZ?cn{C#RJh);{Fg$kI? z0<>zZ7q%uUAZ7T`Vx5rrd40#zeM7I759#mnUF_*}(ds(}z2q1AsxI=eq?Bo&2U?oF z7rkPNVpYYXb&y5W+Gbr7sQ%yt&l5wYe1^KzTfpbM{|Gl?_gSl7GERnIvtE83S+Lq8 z>ycoDHsGY9eo_r+9sW1;8x!y&+a8vM&t< zX#@dbP`U*~nnAi7L{d@&#HJ;cR2oE(Mp9bo5)cVRQ7P$Ax}@{l!*$*F^R4xL>s`-Z z?;qE?kecClp6A}jK8|DW)2HD%lMLe}#qi)lqIV-LL8LS3?QcygCpYH4!@%6ALbZ6F z^Q!SYL=dE_YHBjzk5Nt%c{{{kC;#v%M^B1WOzKSf5)5>s%vMVvF)M^gLx zU?xWEJ>7BwX?^y$c;zkZ?d^q~2FMKZ^+PJsCR#%%@B5_F%gZl+Q&=H?Ps%76{5k1r z3rxDX>hetT9xJ@;r+8la`TpVvm&QXwwEM%u=WAR~9L^C)zH5|($#M)KltJ=(Ro?p| zt%vSM2ky{WI1U03hiR1nuCs`ORrQm%=Nt9J3~1ltHY&00I_IA1=HYQsKtOwlJV>)E zo|k)t{BrzD*N3D%p<@w`mxn`^epOD*e#@-7H}!13po+B3w9Wha+Z$Jc#}qC;P%whK zPc0bm8$33-T8HcF>M%!AgiNiHZS@#0awqG*y$#2$(`kR82~sD={py?tfD{4Shdz(! zRz@4!1IK<_cXqekHlCHob>BG1TiAR~W_}p=isqYv#~C{Q%)s2IrztKDeF7CRl2cCn z)H`N{uKqi6&;e{~2jfz14Q8d7|N57uwfXXr@oLXfUjb#Jm+d^qArL(W>q!T(Patg_9^&KXt9v5$>5Mr+kMVZoEh+!DVv>2W1cE;*cA zg)HjkddFHj)eY1Wyu2xjq++Y*N+h$PQ8GaXCgF1f;9`lj?B0i2$&-KKB8AQgI`7?e z*5Q$npFMicEl&>jZtiW&4P6Y==t-4f8mW0Y+%owvE15EQ$k)}v4NKH?&J9qE7h zqD5RCwe@~7xwxJ(n3uWppe<>2zp&9@cyiGYob=iaUhcbQ&vuSFzkSnri!&NFH4p`_ zylQhttVzwn{Ld1f<0m_Nd->Y=`aCamY0RdmpD|LnnwWa0~;^h`d$QGdWX}=t;|i#a?g~>JB`>oPUGZpez^az zJ5lKJoncXf$aT3e!|OG-vd`BMo$p=Qy0mEFLnYfO>vJz#Jqh`xXfTSocK7NMGvhit z(JbZ8>d~b;9wTi(iLV;ShL$^O>O1P1H>QW&hx9^Nh)O(^@w7*}>a88GxrAOjPR%N_ zwYU~f5tnV#)u0d`C?6Qh!#r4KOT$%WqxHVbE`%)VnvGh#vOLvOk-1~9-}hdK{Yj~n z-j;UV?_OwoohbD8bz)DlXOHCe7taP5svi~QqMX8(&9KOB{Pv zQs{Y1p;W@TcjQcaB6o%dtiNHgu@C-y;cT+pULN6l-(O@_P*iQI{0ZT;*2!J`3C1%d z^O>xda8i|MF7&;nY|`qXFUDg4zhq0H%&o5&_syS1)EwXQ4Y*OYFKI4Z90(V4?BmHZ zlem{zB}d*^F3<;_-5c{0Va;W>U7cb44Y?SqE`^|0_$XMta)0eAneY@yBmz_{If17r$zc_U-X&RPYq>RDh5T$c>Wo!PY+V7s! zm0LY2gN4RI?)yuXGkqp+&1Dy7{Nws$#-foKJH4r?J%?N-6qX@U1SB2VYCg)(e!0Y$ z4wkDnA5>>!8%!HsYTF(iEVzid&FvwsqQ5%rgwaK?v-@5%GKGo6j=pN|5FBD;&DS*Kp>R#}ev)~TQ0@^XI{z~On- zCoA9E=Rj$2qfK-7aFVqnl|6@w-%z_ZXFrvn&6rIdeTMe3>}eLP1z|HnmoOvnR>pxq zK>)|<&Q<3j;o^5-vgCxQXJiq$@D%UQ8?99Hp3qOCva!L*@ir^^_lvZmz3(~+Ory!< ziK<(je9_u?Tv${tf;w0LMVKK!5LhCik7-4-5Cr$W?N2Iu*k*s5Wgu+?#tFOsPPG5w z;=#RY=u^XJer;LI~E^vv4Q^8r4u=!GvzJ6V`s$QEp*gv)1a!USAHYXc~Ywl zk2D5?pJ}JLF?Ja7j@3Zq*Pp2f?CG2`{7blh z5BXL5o@+SmD~yP&drfkR9|KY6s?_w(ZKj#=w*;f^b?^MPZ^268w85=u0>wU1l$BR;A@*x}NRa1`cc}Gi%x8LT* z*RgtJC&u^BZb(DwH@!x}GvI9T;v!2z2hz#U4cJx{8gDp}6>9UdO z`e`sP={M1Y^9>pPsZlTX*w4mJ7Ik-3q?0RpHv-qOyBDKb|Cq%Ks%!h*(zfjXed_+f zctn1|Q`PANrQ6c9y>}?(iSp{mt?N{hjBF-)uXJ*E`kf+Rf#wm}xugd2P)ulfme28F z<MD7siAe{+PbkdZd>G{-^n|%+EI^AJU6!Z1-E<&5wLla`G%i3hy%=Va%tI5Y- zPjgZ{RPkg|I)P;#JP`b@C#Kbp5TNGNZ7mHh#-J^8KRhKSz#pMKd%W60>c6eP5pcAt zNX8ngs#NUk&++YwYmE_A{U1LBC%(=@R0}03mAtG=`*Zr7x}@_`1U7pIe|zXv+Ks%5 z30)_z%i-DKkr|g*Hrq%o32Kwg%>OL7zcH(`d$hmubD%^P=|enACr&b?@f#4AE%d|A z-+p)d=Wwjm<6NroJr@1Wk3nYs9BY?*7+9%cbDYGDyJmR)9R2Ss!_ln)$aH+2y|Yh@ zet)reYvc4IH%k1vD5LNUZ61P}upYT{w%WS=MLx5eV&c^Y!8RRU_OtX2eb<6C18gQ^ zce#GP(V%bM{(1)YYyB)a;7ua`VvOA&j@)@R{V9c&_D%f|Ciogyv^6M{{gerG=6@D* zavSm)$z2Mh_;jXRlZEqZh5~WoW$S12z0)Dzvj)HOMrV66^&IKH@JXn0PbE_=Q~siO zEw|~*^Zn`83BCNM?ep>Rp37Yq%K9MUs1F4T7J4eIz2_WFeX&5FPM9Ie9TcN3{&05u zJ`UobmpP2fvWB_|2`37Q8=@ft5jBx|`u2xGv-_`dYBxN7a*u&h>!4xSJRb4M;*V6_ zCB)oT(^#28piiZ0^WoY;aii)B1~CR^A~!j1vziKVa#RvUrSq>hb(v!BCV4uU&v;DU zcV|1>xSi5Llu7O{mPd0N@fk2J;qC_hL{8&L$)--`TdHz)6ibEWAE|kyXReNDKolXm z17a>D`%;8opc8!xd-~>_OV*vD5@3hv zI1j1=Jqd=SH@?cDpEcVV3}0HcI;F+8wF>);J9qXYy-S6K?soZ;6=cz1gLkc(*n#q? zl`9^;W>s!aR+|ZCwtl%7MWRKzKm1CGu}_}fxu}2abtyQb=iJmY2pVTtGyeQsrdC*~ zmca!fv+C8>N5RN3Ss0=9`Ok}SA^^HLc%g^`9-txCNBU80pwR z%Wg2k5F2XaKF~p%Q88OWrFO;?PO_W-h1O=aDYdl=9&1$&v zPV#47(eT5Vg*RiC8vz(q0sU|idbxJZxKTL@n$6~+*0(N!=r+X)?O)rEevi6Moy8-} z2*Nvc`ehNzrkB(c$b8Lg(h@IMyM=l<#;4yT-RTWWT1ynNM>i~%5;$@20Qt`Pizb2t z#wh7y11?;{Q!jnIbOZ0q6kpwXC%2&2&fTsVAnCi{zY7b8`zww9`;PNJ^5VsnogmyW zdT;0?cxhpvuG7ncd!zYs9;Zrq8p1y_(}+eaOR(Hp7&Id6XMvI0voq&6-WV`EFsps+ zY~1*yeuhrOYk9C-N%xJqLr42>?eG@Hl3l7K?bk?6tCimDFr@Cr!YY~n+42etdYk{u z0&w{L=4ZJ9gD*ObM9PxkQ|;6Xi47;A7aBS63a)FWlO$VfZI{qk8i`gU&6ZUOIKTC zkQoF0#@D|iqAP-o%k5Ok?LIFKzHo5D&JMjR=<-0N=$+AeDCMyc2{nUgpAuW2#A)qQ z%9{bC(%QCCZ)3C(<|>AT*V8-cj^{@8!XLp%6>_a z;1?BkhAedSFvJ$Za~e{b+qZ=mx@+HdlFs*=&-dqzKN!KH%^MDKrnzsjLkfw(sGD!dwEX-6%chMgQ~jNm*HU9THIA2HJrM4KD^=cg-Ut8123ac26^nirfgns4Ck$zn;l!KFhkouRff6E?kcnP+Iyx@VVRj4VwCC z7}Zp1Z~UfEMg)zeDW`7M*K)H-AS?{%k2Z)`>G1B#j(N?UmEQ%Dn)=}8m?$A3ss!H> z-*w_^x?D8Bg>;wg4+)Qr+)IHssqn-7Dc?_wD3C$|j0V%{6r zOY~J2^DeknvvTZ7`7|o}EYUb|&fkiu=t*&48ce2Pt;r^%k( z)2)d*9`#%yvSii5do*zq1s6q)Pm3v8B%HUsyz&V|hx(|QozR9jUX#B2XX#GehLaG( zIz~g*Hut3M*?3Os)rLT3(KXG47FYoOYy@ zczK3!ri;H(pRq&z5)t_Y`EP$W-5{vecz-mb9^Y#zQ9Y&e95R zn9WJ7I{#EUushQ;{0~^r=7g%Bvw3vK%l*Npqu1#Ko+Zp<2LM`(~bUnky_q(XTr;Ue(u?AFHygeJ0oAeo2#6QIi2epffl~? z6?=})l*71ulvj!5Xxy6jIPAipr)gjJST0w5p|-x@Ox1UvONFwii~4@WecqRHUc8Q~ zI99u)<@)3zOFc_41%>gYp<6A6X49F}3;IkewJXvyOBuS^s(72mV}vtyAvBR@nYy`4 z^h<7@XYu95y!R@)6um3{{_T8?q?f6t1j zF6I!DbZ1N;Wnh`ZcQ%?8t~cKt$)}8q{xlvR?e|vQvzF?*Oj3Md_3O>CtdK{$yp_XN zc~kfq`nlS&?vABY50zv2Ek@h+35Op4asJpGXdN#>W_z%+)|)Oz&@S%5*0+Ta+OTB$ zzCP2HZTI<=2RX_RQL@S^>UVA6*4|R(*o}ONxv-e;_xx-4@wCH7sLLr?rip{szbP>h znf5Q-{E@4(zTU;ZV9a;Vso`B}UjtO*G$wr1F_Gy$M`ZFU{*jl>4Scrd=%=i`26Ut( zE$T96Pd!9JAv=qH%3jns=7rKZ+FRg1FLpnxjq-9`^i7Q{0$(<_-?NUiZe*SZYwep> zWln>Fcs7ps?ANc-GU}Y!uSuYE9p~*spwLtT`MK|CB@1SgSW3>lwP=?omk4;oC3k`j`xA(Z5q- zyH=b1`4K-~8AdMd7P&~18nzQ<;H!1ami@i9-MqdWzH66Ldj9RBg+ASPw+)1P5`r7Z zRmZ{?)XXe81BV*;y|IZv=s+$k;D56z0>ehwgzUP%mP>w|7(qHO;3b`YL`n_iVK|zAr#-%+Cn_8{Wt@n5&r8X`N zypqMc>0M+74rDazcqnX;?)v6PqHg6AxR^iPDD!JQ$=-e(pTzYs_o-KZa)(MIFDNqy zXK+)dRFPy@diTC}Hfeuh>Foi=AF(F~RnXr5W8IWbKQ|H~(ELD$bd}BDzJfd%Lp4Q* zA-(W*X`nPS{DMSZ6$4cS$Fs{8SSp6Q<W7BzGNQ*K)3p0O)GN94%(j@v{gc zGb4#$-5kvee*Fn1F7-bJTKWYznl@Ev%Q8E%s@fl1Wu8$Ha~rt zsT8X{dcEXuY;g1b=8o`B^{Cq`dHvX{_b zlrbYWFL054L)&z})N$T$%d@sWzxDA`ihC{QlD9!8Z1_a{K_3IHNas|T{sEqE&nf`M zSN+KseJ_?UpY_9p8l=09y0=S~wpLjMDTjNx7T?t%qKWe;2|#ON&~*k6p|EaCLNAV! zN*rc6jl5@cMP6P^;@(`>Tmv&n=*X`xo-6h2t0n0K62bn@W1!YgGH-SE0>cTeoalOl zJty|ycg6H>(p|d7k<5^*Nl?$lLXI>Jox`ZLJUfeH0kO2`BdDUEIIljWJBEs|O*H)g z;N!hDuPOYf>*5Y-2&Yod(tG~-UU)iu77aY`c;qxpL&Ut{H&<Ww8G{~os$or z&-;AqMX|I?8E1O%EK2^D1{hC87WDC}?PyG8QK|Xr)ZuX+`Es20oh)!Z_W0ZjdzmE& z*?d}Olvd2_&F33juEY0&`d5OYt-YKApxoclwrmY1_m>N~qmgu@VMthrC181LUirM# zoi}?8G-LaM@GP*XXgRzo%;@ocW5xPH$7g0|!BN>*rKEF2c@0sP2hRdELSJm0)->V+ zJ_Fo04bZtuuX6W;b1!bUPX6{_FJ*89*>YZ=01my=0<+GVs65s z_5z<0w(GsWr2<2C3>c5L2J1a5-A7XI(Z`j1`QV{Ox;J(X)Hw2F%c3AH>D^Y_JDUrd zYo5#1N{A}jbhow1GVlGzm-5WL@pQCHK>3^3_fWIt#lw)Wuf%d2X}WL9{+b}%`=cc~ zWS<18S+NbT>x{T-oUGGe3^5r*}7# z#ln1hZ0)r8YTh{@ z*?KxV!CcoEIN`^BeqNiQnZNL3@kLcgX#*O_2aI40kcE$d%&^z)OhS!Vu2%EXcN3?3km8p|R4Bl@xKZWm?CQ+uJjJNGZ73D&{UsO=UTb?-ujFQE zR_CVU9`e9rx$wq2RYso!@x?~K9PYE}LFz){*xPnP7x!rXRAqVEscDkgu8ueN!X%h- zS6|h;5gzE4APZOT(L6o&=9*?g@nAs^>}Xc|IokWD4X_refL6_ytkbXfbCe2%F`OjS z6WSAjI#bM1L#K%iWhZMR!umG+Xr{bV9&)8m z`^fM=d&UrhQB9F_ry{#qp;Km~()?S|C!paQ#iJ#2p#zkTWeZK(hmK6*dA2J}ot3Nv6jua#?3S!8+OQ3b{I zOslnpEY$!aytm9&jV7taJ4aN6-a7N`J&H)ZM9Z1ERGHz~^E?I)L1_7B$Ww~yk$9Kb z_eK&&&4yH0ih8=HjfpAyWKR8LJN7x=yfCy`D{FYSz_&sA_P30uIEK>McnXrgguzteK+*BDKbGTU3p5=nY(rPDAt?J6cVzN|CWkU8}9xi6`Cq6D_7Y|0( zYROy}=6~xwN7+@y)wCH>z}CHnqsbc_+oDfG1};cpZMZGBLo>Dw2~?7?RIU)90!FpZ zutKeoq2*^8!10vPO}EJWP-``bxREBLVc$>c4f0z)g2briPl~7hHo>MN|K@@|;hwf` zHh0SE?qh@TC89=FA=qdqneyPxZ3c1if2f&}$SZ1OtW}M3gHrJXo|7lVFx!XYWbrb` zem+ja!k6E(S^g+ogj)jVYkM24O|FPsjb?El7RI7Jy!AagwQG^UFt(>MKY6q?*6}gh zf`k6u4MX*4Uc)!YsQji<7oXUXR3_~a$6x$a#3)**q4I>7E*xGAUVrr~r1$Dd`d8}+ zDYn!ndwIXsHEH<2KtaWbn%l*}H*$$vQ+TN$!0y0=V zQBa`=t$MKgCp7_w@2t8=GMd6ZWhjL4*bcMe63BJkbpI8LEnd?qZOG}Cb9)e4vmn*t zSQt*zs*)Kx&Ez?_WskMT#0u!z&e~w}JCGUucjaz@IMJPSRjZK)CyMP7G|c!1$pcSp z146YO5j&|2pqFRqfR_k=lciWbIX-l~^lO3JGB!oZ(}Oo57P%)Lk5Sc)wK3x&b4O=& zdNo?S7DP~GQh?eP@~_$^b9_*axGjvF%+X2}iJlLt1f%UM2QSX$&jo~i#;Xi=_+E|1 z6}NQaHVEXurDo#Bg^^0{GzsLH!|CU^uEZ=V6;xpOmTPsD;+7l8uG96~qe2A>j>i5R zZ+LD--1Vl|;tZZA0kl3pXZ`1d!#mkqNk~m|osEkK-QFzCOC}9_>b6Gig>M#zD&-Iv zRm9@0lSOC#;xeEq%AY6$fyE2<7qDzXI1E?anb`eHI-~ZixzC3nB zh?H-Z{#F#9d0my$Si=RKVmx|p*X3bOm{M;v{-d4AXYm~gf_}I?9euJva`oSsaYY`W zcc#v^k)+YqvjRdPZ|KL$Qf*W@4VL-;DJ6f%-^S#<5oLM7Do`&+(;eSc=MKD&UN9wO zhI)LYH-~yhr{v>@2V~4-WZ3}b&JEBw%KKacKAgu9K+#cdf|qTzw2Jgw>rz(8QKAJ5 zl>cIKza4|77^7IMLHgBLY@D?e7uk6rh(p5NE%{;nlxqO4MHeyiLcAbL#2Eob>Sp)V zBuHQlDYECtSy{?@IjC3j;rK&vX=)f27zfqS ztT9kk)XhwW4G`a6Qx-fQ2hyp?)Oh^)sT|u&b&#`=T3lPcpW`3R|0uOD z*nknMKiQNIGeDKTp*#5vnV}99KWcAPcp0YkcET8JUWIX@Y?yb>r8PDl63%6i{|TTC z?@T@GT?(3U7OC+RXwfO|d?o2#Cb>QQV9yquFJY1gt1a=8S|OmBsNJcaIj0tNj`s#3 zhE|FNCI4*+^FpKf*L!D5H!r`+*h@+;2Ey>O62izy&*PRXlpx(L1TCM4Y;cpiN03G< z_wSNr`EtN8_V{m^N=dI9VVLZAVt9$?_MNawJGWDw05iJFG@~H0eS(ICAFQ=G6c^;@ zM(b%m_a(q-g$R*Y^7n@E5GkLlt&IW5ErY=}J^SKZ(uU zfriR)mb}guOhH=Sefd8$R4_lP&Rt8yv`ni6k(HZm#?bgECuG+Uv7D~>^-nryTK zA~F~IkOPj^!@pT8{H(#cPzJ@qZ=x`Eh()^@V2}NhF`-7)*L~5VTxtANAaAO+b_;Nw z9KrRyg<`d_25;W-%u`5QjiNcqBYn7`N1Qx~pV35&s?(vJ0A^8-Q4pAXdz-xe+T|KG z5(ZIAvBMz_#0pi-+3D@YLA}$Yj80T*bJWY;n~@h4&{BE06>YlI4bD5$y%oMpkIi|j z?Zq`~rW=2SJrFw5A8ejP97t{Y*Sde(|;^U>eyFD_;u~0c1$F&~nre8y;@%s2( z49BzncB*cD0FM^9mHk8C=dF8oR`q8uy%6{HUBsRh*|+*zQn~l+f{(@KBOY0Jme%gL zUG4Vw+2mR5Wkm(DHtmaE#e4RRlniru_F#Z0cT11}!gc(7_$sJUN!sXMgv6Oo_zs>3 zo8&8whTk1uj#$4uN$Q@oYr@yB9ht&GhXV->jy5x1iyNbyKqJ}HaAJ|@k<>1J2BX-W?%*CGrrP?(v-R< zqUHVI7-d*S4=BJ_y>xwXc)pYj&aX}`Ebv#2R}GD^7&Lq|;!vTE`jB>V7-I$05lP`h zsEwyc+1QsadtcJw%TjG)I>CvP1&}I!_X+S{wqMg^<0V}~K#MklC}?%ZNx1WZl!rdV zF$b15BKg68g=)L=@(o~Z;M7j@WhD&}aUS{v22Qi}(q<<12Mg&iIeC4v-(tUR&BB6! z_AwNJtRsw= zuo|HC9)=gYct~I7isdoZb>9`}1s`fWr`{V{mCc&lKe@Wtw7V2cJ~%AH07jrt%qmK@ zTkQH+2kYD)yc08M9DgWSbCnE*)d%IR`}^ok(rw0NS&I+g2b)DAZ+eN{pI*(b8MEEk zPr!tZt(PLHgOyRk?s99?SQsw;&%&$V=_rQNGJ|3+B;jIVGT6`Bc(5LJse`Qb(801gLLs~5gw%k3@LhWBUkg@XF@+;4ul$_jkcMjjdu5=BUrI*J_Hge z>cZGmcF=xm6WM~TRLOP7i?lA@7SAXWf(5!NykfV2)_`( zLpY!3$&$(6Bh9cBVipmc$75s|U%LpQ#N)lS7u*P-TVyKM^{$=KQ+<5m8mXp$KV`7L zxTg7yNK!3MNRdiEC}1e=Eb;?*4b)*W^i9q`u~lFc2U||NF4L5Z=T>2sYFwvoTf>Bq zt}N9<4^Y~5!7ZzH{F>rFycge~Y}VB=FFm*?$%gaPuUjn%0(Zx;IHZ-$@%wsDi^>wL zZbhuD6}WNNfeNUd{v{+3@$#w^=Bze5BwmmA;Be610VymFQd;8Xu%EUa9xuEt+DC%* z@vJgOJDJG$8+Dd#xYHbKnWqYNG%vI$EGiB5vWM1x7ZqWF_#ohan0RZO?KJ7V>&G@< zk_U4$%mH~lz+1c-2%w#NbsJP`!7^MS8V&pMl|wDeC9}l4ZJU?zsl7O-+COZPGI2O^dKX1 zcLkhEA7QS5b3VQ+B~Ovs7{?FaIh8Tqx&$0-*a)A9CJyUF1E*dumMH!xzvA}K&gh`C z5%eNXkzkKBSziii@ZRTIRp<%&6Ai7ebH-eZ8W`21gWaDYGbxrC;MOjP`Mh-M5CoiT z`49>_k-9H7UGbkMnek~7c#JQC9xB)+rZD_&;^FQ6lAA4Az%HH>@_iN0XU2uY^{f_J z2&?9gKS*T`w0q(Kzo~&F%j2#LBn(0_QP?3mdl@1;4~_t2?cv0Y2Tz1HH202?j&(af z7R3$RinD}v%M?aQlAVh9{lS9wWEsyi$}qqtf&xs zl9Z5DzHP8oai=|izvrXv=KM5oHxbV>d(p!7aoeTx9_jJ{0SZmaPk``PEE>EN$z@aF zK9%gg@Ml3ZIqw*;bZ&OI0%Saqc%0gi;!+cdWZy&$Bgj&>8?-C87)jlGq8 zWh?Q2V!DD~mYYKQRVoWAyYpOR7jP)+g}W6$fb3PA_PIh=iVrdU8!l;o{hai_j_ExZ z^f-x=NJWr+s<+`?y2_ZGPz#?!0|e3HX#FqUv+Q?VhAKLug92qR=uRJS_~=&Ox0UC` zOG6^gOO3ZWIo z0F4x!O;cXD`7ijCQftGDM+lS#LFZ*BD3UHc=L*wtgj|A`&Ejyio_kj_=e!5v;Cr!! z416y?FxopG)**MqI}W@A@%w(l^Bj(coAU-J=0UAn?eE}Bb%1X8B9|5R0j{vSQF+HX zFKC}A$rsEqjvf7!nxocfe*qqCSjj$LSh$WeSHyqJ#g=hfy2+_<`C2^$^pY;WV-D5| zFAxCH-2xsFfA(PQd9lmj2%>gFu6|GO{Uc_nmVe8dN6w(Dr{3k z(`}!WU-fx6Uqf;{MYB5K)O`-;B?+UEreY4ZqU5>;BN*jB$;&%j1rzLCYw53(dI}fG zeT`7jlei#W*VzRH(rui6eMPVB1t7F>1t{#z@h5HJ`!WpSzdwT`ib1SOZC2==jr)k%1WPf{&3CqZhxQ81deozro)>GTx1=%V9!2tIC&?0 zztV@DKH*6^U;l06Z)TT&>-psx{uBM@^TIp6^cYu}rnobce{6c=rZq~9B**%^2z*eF zkIl62Nr`8+l$&rYc0aA7oeoY(G*^kfrZR1g-qaPiMD+gRz~yE;B{%I-7XkT^D~^52 z;9y;}J2$7~UEX$VVYO}4s<#1f{+-OU%1Y#Wdor?qum9AJi%*cc^jalHG7=@Hi+h$5dQ zFCpDfThBfAx0Yfc3YZ!ena)irpdLXBJvV4a0{JH9V?M{;?(=y$5Hc*MxYzG7f&OeT zt^@WUUi9^{7Hy7*&lRh|lT@IiAlh&ii#5jcqIc8g34E#Cl$+h&yNvM-42NlyZLQAb zq;lQrN?|IjINFsXW4)f=OF~T;fkfzdxITJ%gj_l+3w05(xzq)DzwP(1h4!5o9E)(4 z^G*qOq2|9Ade~fhq-dKSP~GLSJg3#%A(5zalxUx#v(%&s#%2BY5(5;r^L=j}^$m(2 zlc5q*nk+K~ho0s%05?o$9B*_%zF9m20&M((dY}>r%pWp63oBH~SPku>r%rgj6HJ&) zMcB%Xu1^=`?2zOltH;HT(Q4}+h#e(3Xr51?2b-|<1>nSMR}=P*bp1KtBiEd7g4Bco z|J2kU1n`^$*{HtKpuxOrrD}bfEcMP1n?Z^?zT?DU=G}=8vKLa17(xumW+43EhsgyU zK*AyWPB*mxEN58QUm!;*er5Oav)#_c%f%m80d9$3OurTYWtqGn{&FEj}a5X0=CBV@J2weq-$`mra2&|J+swS*KI zgv%Ol$SP~v;-rM0*G7!&Nz3a9KX(bUQ8P1(zb9gBL;lD6`WR{4!D9OB6i$)SRPv>* z5yVrDyOfS^K%X;$(w}*`@2aBr6m`mPk_+NllC2X>$zY1$AjCJ30&x zQ?qQDxyY{I*5Xy3l@czFXFwe1N3IFtuzA4=Hh=xUi{q_Y_Fq)Dtm1yY1amMO?~Mw= z`JIhF$`$?`WYbW2B!p6Pi+lL3ve9B<0a1NlVr$1@sVa#0DSKpAJj4&uWCNygYW73o zA?xoxxC(8zfd!G?og!u8?tRZl`UaM&iL{FS&@U80c9WzYgm9-jAYQuRux(0wg*=Y+1kwje)O1{ldJR5urQ_A}6W~ZY#%hwW zo}p}Fv%ZGsoetl__D1;kX`Mn-??Io{U`bF((V~RE5u1OMMP;dcG4OWF&Nzc;h}2?k zcsBNAU&FbMNz$!E%K%Nyl~tDpPM2ouU6>(I@V#pD8ekOaAKP${U4i3^C7|-G28^h8 zr(xI5^F7WTq8fBT;&GK}xxIdYp+;O=$gfdNG{4FFLZ{KXLE(v>dSTm6DhHq>jcK9) zfvDox7xyDJAoSR9%CLSCc#hY(kiPa{sEc>p!nX{8_*kIVxzsh=0!0gS<>?*DRcY-RMx}54umt66}^Kj5UH7@B+O^3C_zl_RDTX26}N)mAv{Jupv zo&-^F_Xp{Zwv{$=@wZ*O0vj{YaEu~2|lB=`oD67owwN~iQO^I*JUna>d@JOziz zaCcDjzdJng3{X+HG!}jH+5kSavK{;oOZm9d3y@$VaqD8!+baOyebdkvqdLom9kWm+ z1GQy#S@^~qZ#BGS9llz8&%QxP&;e-j05DGs>fOBg>Y?q5_0{dD%~Fj@DT z0ILP?qa(>|ch_guKVKcoJ<3suQS{@63NI4aGL?Fd%`EWJ$U5+wDuQtY!A>?FVmDgn z-r03laufrd=GXDCfMXKCu9shjJ(74h8;O&HWErYtG*hL)0(C#k2673M85{`LajBW* z+7*)4y8ORD+i{fKf_6e2|19=sJ{E=v>MYm&)$E974TG{sX(R~O1DW?H3P&j65)A#- zJNm~0qZUtg6_#rj_%@A^J1js0qOU>shlldM6^-8U0U!#aAO|k8FwwJzQGKi)uq|w- zGjZ?u9ei(w$KHTDykkkI&)Wh-Rq9SSGzd^3m6Qc~exG#zdCNAR&w5fyp=XIvV5}8# zS?kjq;f4yrzy`LDY!tvSSfJ1>;Yl1n>P5x%EDVGwNXu>+V!~WxzVJyT*>eMknS`N8 z(^Pzgk5yOTCGO;;oPscU@@&am(QfOZ*IYR6xk}t^x|apdPxO@&NgTSh3Vzzk%U=v& zLi@=+m|pnb?1MqsGZ!QbJV?*yeC!8DK%(e9tLXN886`OR#+r1iaZFoy8#sFQSd2X80!$a=>-qQ>c=LwSqyCeBz3k;8(X1JS-iym8S z2XMUOK{de_E&;HCb8Y`<#2sBfBx?E@{hig0J}>~-fYERr&|g(7zd?R%ESOzc$5PLP z6Ink%?>v_Rkjj_9rv4HGd}A$ZBT&D(nTluCQi_QVNW@)6CClAHsW`L12aYRog(9L> zaj)z(RF1>n*G^LNT*3b)x4a?vHu=6jCGiDSj4&$o3H?>bc-X3x7qSTUPhKv&nEs`D;yTFHveZYWNpniU^!Xc)8 zZRJoKK*>Y_0m zf@mJWa@?u=fNNv;8dCJXc?`b^zLglz?A~erL^0Xv0-AwnS zj?L+6uYX}O=gDbc$akX7+cIwwVeh%YvQ&Fkd-MNQf_0KyH9ReOp^$dszxCJ4|6~1C z@TKvqcS)Uub%WS%@PZI)y5>P|TjC!zd7l?|>!-u4cqn;raSEK5?=nvw*{HisPac*7 z_sGx&4l%$SSm5FmP2Ba5uaV-xx+QBcbX`H=Xu2VUeexWy8TS5g%oVP^Zq5HF0BOjM z;(s1xw1v-mWmL2YoY0Q9ZnM9Lse}Dfwio)f_O_N5LRm>VagorPW zg?=13vb1T2>D)BX%W*L6Kn+?rtk>Cor+NJo$U|3ZN?EACQlFF{4{d299-{2Nm~hpf zejW$T#VfU;l;(`?)8w3BpTwC0aXlO64?=OcOAs17G?o-{*bUWg`81lKqgNh?^FaF2<{@3SOT~fT}ub^wX`SyU9 zp^`y``A=$MI*Iw~#^3!hDmK@+PLP}c_uzEG3XjAePseCwSt<0Na;f*@fNp?TD6FgB zEzDhms?-*S(%%UKQ|9>gHg2TBo!TXl%EwFaj0dPg3WY(ac}2SQ435b-E>gMO7~%zv zcM2)5G9W)YOKuBQG$=KfYo%pXa3-8<5gf8ny;jrEk+42rP}~V>*M*VOqu$#iIB&MY zulH}^KJ!uCe&qv@8+4%?Ca&)97l}CDDLM;EYPgIpqT<%KYpn27?3s$sL+Kngm_ALB z%kLfy=*-Dfxkmq9NVI#KWjeU7Qr6r#N)1km=(>To^#`6a76xve5<)C6M0u2(O^)aU zf}h8?r<64qkB~Wz{zkNtqasAp8IhyO-tj(()h61hOpy9+4i+iN52Q1tm$7pody3n& z)ix$MFOIZgYlw>N$q!=nn~dNr?Br8*;Q)*iAPS=Q8Edv$1UjLW!{>iAPi@l#YF|*d zt&~}gYdyt1OU|16UD+C!3xV>mY|GCs^O_MHteVrScAK-(k9hi;vR>oVL0e7n)t}(9WQ8VdS56YH zTC5+E>-hL+gAR%FGdk`nPzBsbDB1>GFii-2>!`)lx>G_>GxAoyno#t)(J?|_O3 z?8Un{y!3MN;ldBSp~|^iZ_bBE!^4mtOLkwl2l=!DI)+5V?o9?}8!sB1H0AZskY)dC z;Z&1y34z$(1#O^G=hV=_{`ba(NcOkt0Ktw@p;sQk|27*Zp3!$-8z}dH3P>e^?{(rI zs=?|9Ipg(VWX=SB63^MMyMuI;u({Bm^n2JnOpy3i6w{L(*)sc{qM2YsO@VRw8`cOS zE=wGE*1ot?3@hXSRM*Z`BMu&zr(*&vhuteaXaT_K-(bLS{>^+JX1ll_ZuXd+%j~-*?y{Ef_;Y-zA%}8e z(#u}p>M#zTY@aFd<|1oE-_5i?_#&mGiK@euO-a}4G=XyX|7~8zFjDPIcJcO>s!8nb zI!&ergJ4neaAkC4MxfR0tG_kqbC|m*aGs@YRiB{~{)DeP-{*Brk(8dPN~iBk0fd4N zTt3Qlq$0t+6%KkhUt4xD@GIK%y_@RnWHUI^5)mcaY}=2I+g`it#_PkZh?Z=Pq`v#r zP~iKocx;Sw2ltj*D?OsExKM~|bm?mDt?|C3iF<&87SO zW~P~dlGG6ZU>QNA1db-CviDum1Fs1jg(=r%vHM)( z8t}5CRFjWzfIJ)6wsc()=|u|pkO=qR91t+lkflWkOziKTD^URPP0l`o(GK9pEWXYp z(vGv=5>ktL?UdB5ejqNpKco6nHBR-X&4&R_W~Zn(a@l}Vv^nXeYr#s6NU7f%a*W60 zH7=6}+o){^wAtHrzhs8eAWq1hLiV~ot)NXX40dhN?Kk^CbkJnC1pWi#{2g@0#`1^> zRBf!#aZ>q1X%ff7F^EYrJzn_1zD<`!ho|V=**_txMXA95*=RP@G2KsE&9N1J@AL4>GzF5L7yY9=F@8EP|A-ENBQtK?0i^a)WO9CaX*eLw|_)}ULa;v74Hdp2k_lFYUe%V z??nZk$5kl8m;D)7gYRo-gT~ZQe$9pt{9SAlXDb7C0)|a!FIxpZT83nK)q?pQE}mVlx=JlRKZlsi)YPz|S8cb5u3n{9O1N6iE0*%$ckp z9vwfLYfN*MNWsSTG!C%*J=frJd#CA;HQPAGzPp0acy)qceU~PQ)c`3OCuqy%Fr1dB z{%Y$5SDD*jkli&fe9y6^5kQWACCPARsX4_C>5-OiYYdF1#rp-03elH7%a+BD#~lm(-Hzs16s9H04~ z+2#Y~*&#(DBSdB>GBYE4@A;e`-S_ePeV^x#=l2}XKONn7b@^QH&-p&*>-9Pf zOf&L+$ToFi4zOS}8@##6!^k$f`Riq<>vHn@0_>soXS^l7ZwyT4`-=HJtv~)S(0z#b zp5*ip8j_b_VG${3AA}Hm$p$#)_KL2=l+GEVG%!{>h>hY44W@_#DnT4jzj%@fBogiK z+e;yl07{j7u)$JVd)4{Oyn51Wk7KX=;mVhFP>KVMmE(g9$ z1;u}@@GKoDQuZiMBQxaaZRiR)HKfxpac#8;3j60~Y=QRA=q zeFq%LtBZiW%3|9dw{3~5uhhAAsjOMr%oj%Ch7au#FmV-aeGHjGWez74Zlgvo-{pMj zEzrr1L^IZS)77&a!7R2w4PhAt(SRH4#%*!-JjL_CRICjqvCBHY0c1sDxIZkssvO#w{u9Y zxc`>OH{IAjGFT4|Cmq4nOu}t5YM)Dl@XkzUa0~a#{qy73Ki%l!-c{f){JPNlhSRxP zTF0C3`$qp86Lu%FJNfT2?u}e~XZ?+*QHl6xR7;OPr+$^fAeuwq^4&Jvb)5<#+aaBa zo44y1+1J7TO)uT5^;2;WMVI2*2|GX^Nq&eu`0^fpl;i?gjA1A~+G53U zX{emhm;EZ;aPt02e0zxW$h>V$$Et9W@QTenWm9WdJg&(dMh_RSE2CW)-)P0|y&jx!FJ_J-9Lf~Q{Dg6fn|F&Pyd1z}pi&^HJu^)T$9JL2X1sgzc z&sPR}*URm9XF*;N5^!&<_7=rguf?EOmYi{W^}CibpzScP<%^L3afWn+b0Bt+sQU6y zbeSQNE|L8AbP3R2JkWF#)@bnuO-Vw7*ku}r|uXnpY$kWD3u1CyW z`I6_hw{Elb`Dc4WC;`Klk7o-I;T0tpeM(|BDfsId&R;xGIA-drsK!ujVk2P-lG|Rc zg2nY3RsevAdF`Wk>!QwPzyubPNMLy>yU#(Eh^}10G-oVrw7%h{{Gv=nSOot=aBXrhsB+uzO*3s#O8wZHj_q z{W_|NiZMQuH@JmO-?*-jA~#1a7zmoG08!90yz1$vc=dytq<}E#ezUX}q@Iy>{^&Ia z0a3R9Ep|cS42F`VLQ-mOz~L%)5SlqGsB&=1S7aq z#SHHm8l2eOGoiET%a(YngiO>AA^pVvcJFx3C&3WKi+`eK6q++NY3xt@--%mG0jn;_@96ym==~%C000n0 zx)*Jtzx>k=5PLeqD_w&0S*3i8b{0}`NLe(cwh}Ce3y!+IVBRx3vTNGC!1N@v8-ZKJ zN^PecJ#AubgCx~C;1U2Pj15Z6mUI|s1~$?-H5ok4%?RK2~JLKnn%Xfb#Hp)E{Mo=Ymmq#+#Mo?QIrOy zdV6NzaV21;KEAwFLFk1QhfP_rODX^YJNq^jF2J_mTI)Wm5s4x82$^d_u9p4)X7|?8 z-Eog`?O~qX=OL+uNS(-%yuy<1RtA(Nj1Pq0kz=_2dEuF64Q>u_y{>RPuX{%3b=0;d(zW8k13mJ|^UOHIP!F)RvBa65U;{OFY*- zqnP+y(g}Tz_UG6~HrDWJZp~ir@9L~N#j4y_jvECN#h_7u&(s>4v|tw?%}1Q5=C?A@ zaMZ*Q*VEXn^2G6q{uM8VR6)D6bMzwDv)9ar4VJQ%llwc$$ReJKE){)0u6&}CH(ulV zhu*Wb28Xb4y-Jz95yP=OASY(TYf2-Mi$N;jVYS4T)6~0aL5tVI1%XF|!9~N;$sAq6 z0wu8wqGnKzHmI{=5%YIueloM0{FuM))l^_hg8)Q2(u3n808Xr`pn)qPk29%?d2chi zaBjvTKgb-aiZ75cPH%8@pSF4}z(uMuV$)Tp< z2uGmh*xVM50bO2(9D`K>%Gg`cx7J`bMXouo@JD2-CT}MI(srNkf=_f80uR@egAE_z z5K^Y3|JZ5(Ism!j#~bl1k1~oT!Jj?<9V;KT6?F7uAYzexQ=_-pW6`d0lt0h{WySi= zQXW@3?oZhc(Vln~4KB}csEpI_!ex3NNa(!!jRG~trHEUwantEAcf_+uqyR)ZzJ-^; zu{rL}bR~<(i@z<7In-DWSNr}i44e+E4+vGLw^m1rj;R?Y(3=-AOOCNb4>N&~A4P5i5JHyP~0c_lKq$O?_}H5WtnKDLp<~!dLMIu)+sfKl74plhF+g zp4f(-kCyMpt}^?0zur-qMs=6i*Bx_>x_(Zm_v6fFWY=xK8&)U9Bu~FfJAM`-l8l`_ z5_6QO8IntQ{Vmp|MBncFQf`R`haQim$}spSpv(5C6?&_!}H z41{W;?N@Rx!<6M&E}UG&pyjZ3!CVXTbFW6BV7k@TSg0~o)-Sf&cs^yh3U!HmLX`y3 z+#r~}??7DKf6kfpzLfz8roK-B3{nU-wq&*JEGFulWDzxH;PcN%sZtiq7?VHmIKv!{ zLnKO&R*P_cuHRjvJ()ilR3Flev9;B?^`QSkes`rNH;kB;@BBRY_QOA!fxjPfh}d-1 zI(HoQsr9$VaNkRa6e;E}fZiXwb4=h5oQ0^#=if=6t#Yl7 zNOrJTF$@s$pkk2>PV(E;uj)8{x}S|Q$CcXv5Z_;+dJ*`f5RF2RXe9SVTvQIl{)97A z{F@;Adp`)(%N1crkZ|bxdV|a;w;X%6lSgyYqgk5lH~UFM|Wl)jO@h2MC%vU z4G`8+GA=aWL%?zEW&({Lz-`%#<6z`Y(P4%Y!E~nU`c1Raiu2u3ByZ!X!>PyoHag{i zK^gcD74;SO*3D`!m%Yg-e$#4B_#Q3fF8D}M@MYk6?9+kS*d4upaOVY=w=-`Ca*nzI zuNgf+Y#aUp0f#PyHfEGVtGVzf{p>(+XcNeBIi^t3D+pe8`Fur^tiJIpC>-kfPrYxf zJ#hoU0!n9gaYyD6z>RiRJf?KyMxjn{$@j=c!+W*U+Z!gFe zx7@mqfqv+d;fgr!t)X1(wWk!F! zRPzsxskF~}D9x6DWcTN5cf*}CwDm%&@hpnH8+cb0bhDHJNK5%&L5QH;3!@IWHXMf& z`RDyG8nOovcEDs>2NC+Cn?K&cE-IXm4_k6|_=CoXc+BSK;4^(#4H1pUH znJ8`Jal+M>^q0#GcD{Q!8)wm*D`R6=8J{^s9}J5TzQR19J{1O# z=D~)T@yY3vGWoy(Bu7Zs#S_!>Ycvfjf6XRoWJ-PJhfdXKwsdd@)oMj`oaavY=80H1 z1Sw{+Z;8oKK_q}80{Cs_dd@rV4O{)*IjK-WxSBCd2PEUcZtJa(%B#qQJRu#4{3Rcu8CE9SeO_5k|%5KukyHytIxF(C`B3JW9TPo-;WvGEsq!l(&4UL zw0|A^XeQ?B))Ds~8kA%h5v9byKj~u2_CLb#?x0x?zHr6WXlS&`qcDL-zpdj30OHhC zUN9b+eciByVcb(-Fukw26NP|Hwpu09y46lb6+;=@`TA zALM@Gcpu8eBwL#0O0bXRkI0@BnTX}yzT`bS1(b<|T=HL!Qo*C$YlbnxpWB2qSxRz& zEJ0>CdXtwhbb{@uS*fEKF$BWeuVYAEEq6!|F_Y__j3q(3$UKirdd{K~0`lIx@+4Wv zE6%-H;b+z+X}awbMtMdH^KApSy07Pl1YX}?!?9+~WD)CI%k(-WYaYasV@uLWZ@tv= z4J*FTi57C2-#fWBJ;$Kr4!N5Sh$MIGXll+fwLL7=eXW}9ux}$IZS~FfyQjtE+<9@2 zv-hL;C)OF0$*!+HTVG3?zP#S~(v|{fv*ee(f#Cd-RW4y6Qh-v0z^}?aUC;aS+VK}g zj~=BB<)=xDgizrha|iKHe|+NQj?4M3`V3>*&FA?@|16qLr{Cm{5r14Nt>OK(y zoO_F00@$C(aUf$(x_$iiOb^nfo=xN5PWpQbNGZg3e^ub)zGpukeKcl!o*1V${IsR& zfD>KA&Ccj`eWvqJptrLp;2%&0YsbSi>2nV%5G3RFU7OaYO+95|sHR#PdZo?tb79)g z=L3hGDri);3RZMCaL@LLu{6d3$;Z$CmBe=?aVYLBgg%fQ+7IV7_Wwp;PM$?uI}b~# z$jUM9jK6Qh!{EiZ!~F4#_GV3C(0L4Wl|;}R=ts}ITncK7K6(zqyS=)atuW?~xs*}@ z5Q3yK`yXj@fXq`wy{iYB2M_|hszvlH`;@w$A1#X;h3Jw5O-<#E}3;smbW?l^^xWL zoNy2Hn7MW$1ZIg8Fz>H}^Wfbve_I2bPPGG{Yv$vu<~tEs>p#3?=R8pTDk>LcK?==| z|8~v<*5Y{mLi*}UT!uGQ=VxE@hjg^{vq0k_3Am|w*f1zr=2Fa3?0!ugZmx zrrRz;b%9Cs@g%#=@x`5VF%Oi@@tfG!3TwC;=|0vylY8H@?IyX;gC3U}KId&dv*VYG zBjxf$j91ujiT!z7+@MWfTzCyNT}2tKn1Lnp;tKCzl)eEy;7QW}A;7YJwUq&xsXim1 z9;IH;fGyc8F(J!(61I5wHjviJ!Q!xBmWCPv4&S68N8ibT3X+Hgv_z za0$AYknF(Gw%LC31}4LqTHvC%t)!VX(?x{5!@$|Bv1rb@|LYsDw{Q+dqJxfXW(@%f ztDhtz5K;Q|+uLa(g?bN1)vq&lQh+g2_O=jQ|KDw$2%VKf6ovHCFmJAAy=|J!8g=@ipxFfsMNZJ?3jBFER6HA z0iS8o8VdHR8iMdx>uoqN?Hc*E z9QYR!!hA0Wae<(YDF2k@&04=nduiJoN=)_8aB(a-a*dRScO*l(w62|CjcVDp=Sr}_ zHY}y@(|zEvXG~aa)Enw#uZ8-=Snp=_6cmh>yvt@xOnvsJN+ds&tB|tf+2J1PuY*Be zFD&gA$t)yTqMMnQ?M1GzL3(rt@)SiJwit`3BZbdT^R!Y14 zjHt{&W?IIKX4$9E%HS3~i(_=`hQ@C$}&*aa0+Au#oSS!1-|;$Ntmz2HTu2@ zFX2!=aBK{OqI0*z_;vq%EbaTQwI!G~6FvKo2tJVfLXCUTut2Z1={Y|W!Htoxwsx$a z8!<%n7U;sD`N$hZWiC^;g$#fZ)rvgyXOx7I8*melIh1j8#O#CkKllp4Vvm6P{z+Cm zNE72V6G}n*vch5@WGb35#~E)!p{F#{65l9%JBS=^IM7UovH6gW5zID47KT`%!6Z1Q zysC~#OaY2D??5R#A7l<|3RD+R>6mB?Q~Unn7ga=Y*3d6`;_>1#jHT}ci$8A@2U!#m zP(-sp$qL~CygVLSGWj2CyDAKdZemHHpp|vnUVX4S_)6Zd;N6mpCli5me|N2Jx6}l* zqk}&XcL}eyg^bVbh05zMw4kn5- zpnc%g!%X_oaq~Bc;tKI(mZsp1U(L`O&PGNLXj@w14Ma~T8y}tWF7G;+D3kkwZ~+Hy z?Js8%Mciu_sfyVpgSo867}#HZ<@`RxWmb6&&B?$iv0bg)mhjA0BSU*IIE1S(xi}eW z)nSdo%@AUlxO+8b1}>kJ6DmgOd0CsQE%TG1VS^05*zC4V+iWL%quRa}CgHcSpcE=E zQ9&+oQ-Cs+VDo~wl2Wb6t)rHR&WQ(9&GCbG5qf^`9RmxP=&gTO9?>v;SB4Wc@nAxC1GgxlWJ06n_G7 zg!dhvZFT@l4psxKiED$npz|LGjHR0exA|$ezcXib!d&{7t3OO55ca)L7bEqTfe1&v zZJ0%MKz4d(xm{=;foO&_J}b5B%={3u@27!)QM~$Z25N#jS+8i2P9tfx@pDOU9b{UN znC+`Dhlu>pU)7uLg6Iz|23tKh@4lV;RcEvp541g4!6b=P1E*rXNI5S{C%e=6NSb_b zY|{N4)M4ynML;yU|=a`necwADp2}8+l<>^8srl( z{UEa$|78oD-VZ~MRWzAYvzCDAY3%(*j&S!-5;*@>!!5lvL;u?D(N@ybhxeAX0C#dH zlSNIZeL(nC&v4q`O$3l{OKOMRShDFz>3Llw7e+^%Z4t!vZ3yud~`pF?5%v zMpdfKiwYvtFNoA95xc=}zPd-qi zxco_PJR{`t+b*rjl39QJ^qzS)^t z!GKGsASbb3%lqmVBE2EXH5>}Aa(?!pD{lE`QTjPL(R13VQobK-7^%mJy*|~<9CXI7$@TYQuos(Cd6eV13>9D|8o-P57I~EEO(N@ZHo~)pB?3 zbcCh9$KyK`3YeQ%yEvG7ivWJq8<~^oF6%yz$@v9KLFFZ%G_bpF|)8r)JXZH6oN4VZ1Y-TYG=5R8Lf27u*_ebJ}T~LM4Ul+$k zjuAHs%5642^}erOKj>S3c_&O1DahAnKYCtlT2Mfk2t?O{@pNHW ziLHcRh`UkPr4Z5JlTr5ijmQLM7{MH`fJW$p5fhy9WjISr=CB?q4 zE{CxpSdj@V%prK+vqP>YCnO}e6J8I0_+1B!;5rxHcP4stLIe}{^<3fW$#VGor7hm;zXb_&ElIYd3U77<9)rSn0S=F(E|0#Lf-TTB6lQMANB zHnv`hyApBxflEc;CUQj#*W*`MBXne3FNi(KTRU-3iDL?;GgJ8&d2Ml;`gx4&31B}sd!4rC5NV(66srW|?p z`W^gcrnV)Cifq3=9oLziAG8YV)?ID;`sp?+$5J{KDjH}06g{<>E-clJcJgO0U}`fD zJYn}HuyC$(d}q;Fi8W)a-3ANqkgYQJtn6v9@OFzn zBiRwSrJD!5N!%P!IWg6m@MjoybTh-KhY4Uzpb-%ki`hLAQcFd_Wq=IFW!bXa(jq)ZX(Ee+;?dDvCcY^r`?a8_Hd$N^&w zV4*Q*$$9jy132l9;{vbXdGrOD0Lg|%GJS7^E&xcGg(mxw`GXfQj0qdG^F%4?=U@pt zSk!oHzbDHJzqIfklr=j->$d!>_mzf13!M^0iS(gh=m^ zIH;%F99}^5`?FzB@y+-dpN3fFz6HIKVq1m53g^r`+>(WMaB0l2{<23b#&F}JvTlw# ziHO({hU zuKBTV3E?*z%wL%oVllMonfY5>T|6x(yU&q&bc)t7Cy#FV{_U7gCe{&^4Vzpazt+I=nS07SjYLh+fh zA1kA-sriq!waqn;Rc}_@&3{3sBFd>W?X~e5mzd%D-1lr)cH*H_?jTAmVxkOln;8H7 z$SVFV!s|yUgF5P7(qpO*6msMn(OmP%*=Yvt&qwsO!iXF5{3im}zPc-sCt7Ge6OAYTtmG}5oz>?5s>22`Yd-N%k4gB24Iiq~mBHOxW$ zg7js{F{Q#_%~l+ndYr(bhQj-;0jtXt*pPQ)mz)9c7RlWqN|!F9bC->IMTjPx_l!hS)diDm3@(s1)()&{X0bK|W?{Y07tApL+_vpnJZ&Pw_+#Q7Z9>F|BQSq0__VVi3 zVNWtH)`Um*+;Bp)9#aIEIg(w7u<)2rtS}@YiXf;0p|4B7H*We3*4jR?Zi~C5)bC1) zg@;{&k*OI{u~O-VUCo?jYoe2>*-LhD>T94*!1+DD^|to88f_7ezZ+y0_3q)r{lUY6 zj76@yb%X^Ap@B_yKY5IX;Trn$+7EdHTIP2b~1$%FjK*u1GKrDsI4W)Q=MLY1GK9eHfzk+(2{XdaG`>m>n(p<(zhXbGs zEO_JFGp0yda}&VrARIIUO<-qDKhu=P*A3i#8@XR=6mv`J!D0%Gh+4%Bk17KIxgFzF z?h31(wPiH>I`|#tU@OHY@Q_RlPlUoXI)u=9R>cjD4t4ui@|!Uh)U4$a0DX(J70Z9X z{3x$;9Bux}4D|T&rQAm)LlgcD2Zqe#6iV7r`^L2(;Hr|m+_Q^mV*-W99)S7F+0!Ny{~l zvUFRWwxT2;lC49gWZ$ZixJh(U?*aD+)I;xJDBrrPhyt;gz9E^mg7sc>z+j>I{dxVP z5WQB{qh$M8nwKYrty){{*UE3<*x#mA&^An$G0k&Iystl>FiH zBI&BXJn60vQJE#Ao!}Vg(KNMFJiXgrLfh|dKc?Y2)53>8$r;zEOw^i8_BAZu>Suzt z&T33U^WNw=^xe-Tbp&L-?sdyfirI2R3c_68G3e(_#@d|KQx56Kf=9NK$A8nroRW zqpA=tJ8^PTm*A#PeID&#?dSEP1{F) z()q1_$V&EbZz}>zw$!ka6B{MVv=9`0uk$s#LJ2Qz-O`0G&4lcrX$QNkRS@rpTc>fZ=ijFV!W|hszuG_LL3E_bw{WTmI(BLi5je zmF!LY&VWx$g_bm>h}yGS&{tADsJJVl8$o+81ZxAVnq#2tqYP!w>&${jsvY$-6uVs7 z=!a}Ko*VUsKG7TAjEf?O%`2^%p}CGGKtBxZt}4*$%n|lnHhmRPPHK#@`P~vf03GBM7=ru`pHm6Czi>pju8d0A zcV`8QI;B)zG+f{z$=7*1V?H@AnOLP?_q@-MPn(a&58crRX7ff5mOA!EvpdX?iV&*g z6DURpMWhv39~E?>L#Srh{frcG6m0#ZzJl~j>$^wa^L-^Y*oUGy77U#PxATpaM(+-@ zUGr)buP;N}QfR-AN}+Ow?4#y~oo0OP8Q-*Yl%>@4M*eH7VPZ&|y4|Y+8a~F8y}mZ6 zimiQ|{xXUw^7z|$Un^F5nnyf)d%uH52Xu8sf90i>#^8XLzOQV7jN#w^dDTT?er|!i zlTObwm#bI~BbbRYZ?G)t;w_T>J!C!L&>yl5nVZ;x=PRCIVBN!8-TQK0_|jv915u{% zJO~3q$ha&xe4<72w1={Bc!0C1d%_Vh8R$=WE9zFv8Qsv3U$>xM7|TWFC>YOJjkINASu&`wv#~Nlb(S%ij4s?3Q1vH za;c@iSqpKhS02}rWCtUaPS3%VCW~9J=#baN)LvO!)(*bF{PvUla+{+ZCu6?gl zqh5RTcN5!rI#*UFQYS8z2%%@icA)6J!`%ei*5*F3`0MKu7nqAXa3roqsm1`~LwlHh zFx>BmcI)>Bjgak~^ohVbg~mp`{61Tcf(jLn8Vu(eAc?oPB;QE5>w{9%aLO5r_0fNs zI!oEdu#pfs(Pda?r1uF}sWiuNABu83>4fjZi7urUl0m>?hd$Ud0KS+>n8FHhK8?9~ zQ_f|fK)I>b%;c8k&N;b+TfPsjmtRd}xf>9@y&#tmEPv42|AV2XPML_FRiF3Kkwq@m zu6EtM_0Hs{xHKognPx~f#|%(E-W}mzryXE=Z0m`Ow!StqpU1~7s7kI_VTDE zTq(8047{=>X`|XS=`pTrM~a62Ke-HxpO?l`ARha2FtimMeqhAXiQVWOlka;fAm^7V zTp%O#QX#B402>uy@VW2Lvz<|2{*H6SJ(Lajka?A1^_Q3@1Bc2%Ggy~+SzGOJSF^1@ zGq6LQOYWff?RImgT*8}jF%y%I$!h7no-YloibIUqZp{dr6~CBA$wJ)uOZOV;eT0E! zi@6~l{tUM(ow#%v5i%fJq9#tW@jzumsr?QLBLO~F3dhG9C`AfehA;Fvt8wQ=h;DSk z>fEW=a2YlTj(NCVf51rFf_ni-Q9giY3>+kZGH_gW9b()Rr;f z#mRgo1^~;XnV=P+3s1vW#Gy9jgF@mN^f{Hpt%-c|X^dEWwNhy%3T?TyA+lDmSvEYh zY||kYDgi2L`+naWE{6;G(qX-R698l^7c7|x=TD0*JkWR2Bfd{uN6vS%H)YKVHnPJq z$YOz9^)z9X-a3!Db`UL?&d<&GE>_;3#AiZl^#C3ur_%?Wd4IN>*&g6v4^!oPU2O7g z6}6|1NBuT5rtA_J6ttBzWsb@W5(qZ)Eiwyjpt3-g0WHO)1;2J4t8KQ==q;f_H?Z+= zy>7-|5K1Yunt!?LU|O=?KStH2RukS4#d-9quAeo%sogYI=1t*PctKs=gZPUB0G89}_Ac@?L5-@&e{Z!QH=90`7 zq58?AEOV2M_sS|UhR~-T5qvlr7>i`cy5oZxbC(vUvb|JdT_WGm#X;A_FDmt zHjC-_6n*j~^QTe=4_epAzLupXgR5Z2S+C)C5GD8bULCK!AnB)7eBz>!p}L!3-Ib(E z`o(iQQz(SXXJsu?)+m@}BT1zTsJxTYh0T~-Hf8{0D$C``8(RalAfYFvAsATod|A>5 zAd`6Wz&A+Rzxa|)sk$J|P{lK-K5mRP@gk8W>9hORp7r=2*SR*4DW5G1f-Rg%pLw!O z&2y9naO)J93c5I*leu~158R&`n%#({z)FG$RQfRf+TZ(e5$gK(alLR1tgs;O=V#=| zLz{YF+wX;6Qujo@%`>U)(vaxA+Qg+wr=uQ*LO|gcXoa|uH2Xl$=r_QBMLu-$B3Hu) zfkrwVKCe7K1H@6=^JB$i3Ts7m1oRig@5|B=76d3kU9RZ6>jUBy)t8SIV)}H6jmDtB z$U~*3;mg->J_XD&U$oELL!e2QpY*B=!pxD9V!kD9t0y$|72lUIvfj|4z`bcI?U$&& zVi=L#ox0tL$+C5;lD4aG**LXscQPue{7c(@;u-*t^E<<`W5o=J>-6N9%kwgq0BPtl z_#k&Xw!L|%32lcDuboFH-;o-dihenXD9&CL-fD1ttefFbycm zK1_09#p9>Qa0#%gTB|M+8w5+7j3maJ-$;HeMA=qJm>iNAe4vDZDTbp;=`DX#%-@hF znRmh#-!u#&zXJJ3|38d0A^~BdzQcP_FDFhS>`HNwh+V!&%_Hu!uuWZWt z)_G@K$dnL$6Qn+IzLo+U2TO6kDmheB?xEh3Am+EgVcY|a-}0r~O_3_!o?nTvno0B= z^Ed2uyyD;@QW(8AVqwl1aeGYSvt(`AuebY22IR*F-fD!z+#N60rvPHK6egQW(ljqd zF^!WHv`0uA!WGL_!aTvg^lp}LDW8`JUY*-_V%)cN=Nq`Hlu zEhQ72$egM9Gt5tV5GD>6BwUn=O%LSLU58GVA5yXg1<_-zP04WEUz5)K-SSlXz)z=G z&$4x2^{hkzS{)l0WX@O+s4y@CfvzwaTceatf_DyL1}>WCfgofX zt-#`96T3HpHwMy0q`_b8B%pB?oe@cb$0`8LP5Ym3Qa_ZyRYCNy!mbpHBI>F7g$8}w zg_#G?*NqoD)053sj%8>*2KIg{_zEY-!bH&jy$(pU#zi4#_2=T+H_Pr=jM5%&fX~bZAxn~PQLRrPKSp?zEYFcu zY%1`(hewO6wE#g`N!Mk?D#q4J5rDQvGc$!MvakoCsDVx(iMCMA=6qkfcyS1?Mw+nT z2jjb|b5WMi;Bp;#r*Y@V#!wxZl-2eWLjAtxd*aa8D)5rXGWozi>Y;Nvi#1A0jWi8m@y5`6uQ$jxKi;mkkO8p?{}l}A4kDw$XMGQ-;4xFf8f<8gQ@uC zYyQH+t^nULz8ts=MK@~I5Pt6QkXsoY<_Xomjs#{1GW(AWSb}6XkwRE(@*Lz(0>J5Y z3M+)>mr~w`>+vkm&+m9h8r(ch6vB1M_~M{F!>JftB)c;Yf!t?qtQr10&{E4byc1rB zcun}a6{D}fqQ-eKHypWq=u#*YlgBBLM}z0{V@D>~>%CDJ@B_VwPY-hU6>?yUB16%# z7I^<0m^5(J{`Ui`MTtY0M@9^YskEjDz5?!=#$1Fm4m?8r=$%+&( zf@h&Cq2T<52EHvqZdzOr`=35QI*w^)7}~J)4ObO*$-f3gh!~Vs?hR~|7IHj{|4+w* zx0?&kf3V*vS&L}J|KELtEvDi7m$Ukpc_S~?BdG=Qg?Fz(bA`V*p9~W_0X}UM_y6J# zdQ>5iH$%GhO3#DAaUj&F+5n;0Q%%RFT2ESb*6}lc1FK&*rXCFnYlavQX;^5rN_=e8 zTWzKSuwRGN|864HeDE2=lf96kRKX+s`+fpp@Gz-aqi8~ccky2*U2*E9@32GM#g;yijVz+m-$6V;J2r^v^yF+6x8M{-9Z%dsvv*j-(N-@C<$b z`3y)@(r}u;hJpDW&f)#pg}?8D1&(J&3V{{114{AsNE~Q$tH5?9Hp61mrvjD@)aG9w zvACZW15dq|v82 z4A6T=ETbB4`0wE{A%|D<=44rjgkPqE<9EJ=+g`Ekuf}Tr}r;{Iw5`gOjt{ z-^G2gJEksxf|He_M?P#iq0E*9U;1B;VgNB#Y0LlVt*67jEkqY-CiNa>Db*~e9wsQL z0voa;wKN~d-mAf5ud+D)J;cz{LwtHA0)34JI(t!N+Q3<<03}l6dm|r7CZ2;LNNWTM zE6bwi#%9*&lKR)~V|Mw<&g7F;#B13!Eo zZo|FThwuL8X|&N3Z$A+J2K~%2=0&;Bu{eM8w5cbr=cFkF0=3}aeiUc9o<1li@}Q0X z{Xs1tZj*m{#Lb9_&4S$0)N==?vHdwxy6x0V-Gc}9>qrs&UhD5W#Zh~>u7+ehrArRe z07P+xn*R#u-ci~D9QzX@a|$`@?|FBV?Me_X*j;^zz_Gw`vdb5msLT^Uh9`1RK=iz{ z+e|c4xqW&K8a1Vr32uC-(boyoh*^f&9rR!DXwgPHS7S?l*N^HOi<1koS>}d@#0JDRhI1;5OWOERK0+1FzcKC^l;S^TC3vqFIxD}6Dn>7V zV?@L{=6hQQL`yD6`x&JHN*oc)T@n2WtLH9(_%D@+z>hv1&|RDw0=*0)pPl8Ud0{7W zAXC*1n0)$isGU_(C08Zc=4#hV$vx7C2<1ZEGX5UG;oU!U5+mrVnX z!177mdK)id+TH*YLc|>K+|dYJeA4i6IYf|$X!vQ`HpK|}(Q`|H3Bi}}!%Dx?g8bGNKa%u}zpRc8=WB{D zM;?pM4F+-n34YAyCR|^`+F`@oBqK6FA41Rxe*5Yqzi-ZbI&nI4h$IZ7AzI;As9@M8F+Xl=Ni{= zg>y0#hK~lFiO>(PSPa3_HLQLwI6V~pm%c_&t`K8ZUVuYEpc;a=phS@Ud>amhGBhpn z-wbT?rv(L)@SheCCkM|YR%1>x5Av~1%yO2XpbhNJxW|QXC^wHTloxeHpc#LdcM820 z;EgP9_%|mUK)mH8<2FUecj0m>aDH()y{Vj#q4QJYlW+^ zrLm-sqoF6>ctO}0NcrGYIXb*SbpC}N0Hz0$xwKjMEk?$_q+%BhbB}tR23i49+0fw{im4xl_(5l*hTU?Bej`j_jGjiQ0(v6 zIpoNXZhG9SjeCdY(UeL4w-Ay2jL5qDjV@k17DQ<4qME@UlYTx&uWJd*_uVKuSmrM0 zuGyR9!P|%LVg`SEd%yX$JIwey&%q>nb~kLbzhI3BPURV}Wm+JPH9S;fNg;!$Bmxl@_4d8PM8 zPBpA~dI!xSr(}ZB3lb01JBlYlxuDEs<@&fU z9o2k|OZ(&}BL)QSq(~{V!jgpO=PS7bTaNn@%?Sj;vqhLSdQ{J{P~Q zMC2$zyMFwHx6?;@|LL!S2O0$UN+0(4sl8VkE)_;*UqDX!4^}C(L8?oI{|Q#uAy6-= zYPk!EJq}_8KOz3kk$B_%4xnRu}Omf*9 zuFTMbsE&v&mG(pufKI5xYiJY(>jLY*z5K}Yg;k75Y_XC!Y(uu(K-h+nn^1HbvyyoS zk;B*{LMk>u@9$fh`Lls#E3Y!>-L*j}im-YHSGn#iOPwxX2IU`yvS>BPAc9i};aw~1 z?Hckmp8b&A=1di{*CZ&pG52RQF7O!tMSU?WXA!K9{DFkwF6?WrXAlCIJ*+_$zdqj= zF#I0t)yFg@RTSW&Gr}fZm5?ps*Fllxm6z|w!0Sg(9}GovE&MD=d`EH3?*0IPutbXr z4m?{D@x*nrU^F@O;|^dL*>JZnlvc<8xnY*Dl2g>v#%H#5UL_%cv(e~@dayLrz)3sF z74KC~mFJT2z4r{8*0-UMdY%A_O+GWjiC*|lA`BP#G;ccxR(}?U7d*So-(KoZ=?I0R zgQ%ONY}YN?Z$07E z!08RehQ8KIit7DOC9kbZ4}Ti2n?J5+fK@ebYO_B~)MZwbt;RKsaLd5RrTgATuQ~MV z_Bhqy6p$v{PNpi9h*(FhmIobMr|~2fv{he;;&cAClf87Kg|mp6VLWSMUz?ZDMX{0NdEfrdWA#B=C(!VuFY`UtT4&%{Q(8V95y zgN59+Z{R^WX#cedY-K{$`aM^(lbDAE>GBKzb%cdCm5xvvd)l;&j^MkBi- zW1QSj0M-|@Y!Gc$dEPptbEyX$r-xHbxYUrOm* z&-owS30OvSHuvi3T~ULuZPYNU%?vP*GzwWM3!$oMD9LVGSg(xMH0Seteg})1tbC#A z4}PBB>Hw0H1dt7*8!k3z2siv$V$MJRGQwfa7L^T?_sdqz=L|KXdumtTXQYI36^!g} z710ZmzfyA1!G8wsaI( zdvV8HG`H?@WM@^2HcJ}8l?o1kO^#aDN`AeBG7jiUc3ePTasyzMTo}iC?Xkr11kBC(A636zU zI2UL`9+A^|u52eWK4@Fkz*Y1ox%uIq_TwD|Q_rZ$tJoJf@2`)qygNx|z4^(ZJfBS^ zGiqPW%kv(Xj)a3LjAD+FLSb`5?n(C2kBM=L!34cd-GZq?wp(6(MKp4yt28JBG$ zU0^?JXoEH~%O|DM7kJkS?X0cb@3J_x+4-JkR)kykoq7wwt=H>s)KD zx#m3PF^`$_DHSDpPD2@JI1IqhLR30)KgUx^LlfU@J8M0Aj3e-cp9;`2!EmUkv9%CT$%z9wxxuwh3xvEe;W22e(hl-t3_LY6m8vS>({H&(mX<5a;4~4bVoIDt zxd=;ZEll?v?av*Hg8{h(&6SI!aLb;JH~W&oc=nTa#G^+X6S%zNbPR2|U2k7EcfJk4_ciRQij zu2N{Lo@}F4B05__h?6Ay^32W3J#3!UGNit?yBjoIRJ>K4nC2Y+z3ZO$1*}jg<+TKv z(F4Sd^A4Z^8G!o41>Pq)_g5IKz5P+1i%0QTfoR*TYTu%Bv;jv6Eo&Q`IvrVB@ZkA7`Y_#PAI!-J`j zCLx1O|9H*CMYejX*(HLCY}$}Q+Q2A#@`=F={?qxftD{TFj}bc_1$(bymUBIWECC0J z2OMO+l?IY!wUJJ`p%CSQkP{93Steg6apMJfH=rIS1 zt)VH@ou0U4gK(_^Ql~5ROl=N&&NSbZI4H_#HWi_XsO&-jdbg7rE`M$_P=8DPcvCX4 z2&l-6ZuO0H8@*liW|l|?9E@QQl3e`(CqkHt6BSVaLwJf&Ljt7!69qYCye$q)1Lm=2 z<&^-pE&4iwC8FKNr`M~ixl21i3dqK5d}LFGNr$xGMTmqyBVvh?v=lRTu5^R^S!=

f`CP(pD`&2Ter2^98|-S%l_*Q0 zwSgt+D4xKdjPIM6wiPd-s$L%3n~Aj0sg*gYa#fpd4q)QYRC)KMRV)$5&`u|(ru(U+ z^dLn%%@eP^jrljs_R1pB2z2rY&cdEgy!77!92J6ADoj1c09+r)-ug_eug>t?A>^8% z9a1M)et?4nj1e$U^mD zO=j9CrQB*2#|O^oafsPsE}@lz?Vd5d&(Y z^7oRnSdWx3B$!Jwx+1Rkn>*z?=O>f}aJF{W(v@u!vt@+VNEADjxiN}0D4}rRw{>n` zEXDC>%zg2Vdc$VtMFJ7&?DqK!+hLyGhcayhU2V|?#B3m=_%*!x?}l zK?i6d+fH@_P%Hv4T^5j$H$S0YI}B#)Emf!erDi@ogtlj->7I1d>_Q}5vhAQ;5a?>w zqym|{dP=kTLVLO8C^C`sAY+Hu;uf9{eH(1RM|b>UgwY&+?zUo%pSFk zD}LAU-&<%1n!O?l)oV3)?I@GW#9k=~9rlCQy4ZX^f{oql;1@cUDCo|e^DrDk@H zOP#T;rsiV@`8+WHIgei8KK}sBtVsP1kG=n_)Txd%Q!C0L&lF}>z#I=dyi-Y z0=eLGX(~ix#TLVCPZMLliN6vnHfW`WKmwmoH(E$&#i5#!UY|ux=Llk@`y}kqFz>oG z%brhhI~8))X-Qp&i0DwsL4H5dEL>58*MXU}_!ocohW z5N1+zqkS_9P`=K2l3-*dBRW_ zu=_scwb4A};frwhpmnM&`mV$3NV<+{nc@SDJACZlNn>sJd7`M=QtN$PrnB^NPfl_p z(JtXFRNr>B%RJ&feSNz?Gx?+^p0C0#`Km2BSb$lv$l184x30dcdyoi$B)hKg-~lESM}s1KG&b38^rTS z<*xoPc;Mz#7u>f;Rl6p9U`aSN@Wso?T{!ZH8YTL@t!jC=e?%TEO@?isB~8B!AgVkl zpx2{=*;LG$m2M>Zz}Pc@L9+_Fg`cSyzp&|xF9_2E$gCm^!2c{n_D|Xv;VL6y>2}ER zQ~^E@Rm22%AbjO651O7-~}s?EAM1QD>!dmV{%xZ=#9xVGRe`Z zC{WJVRKcT@BO9f)6$EBjvIpi@DEO#>W`p6F>uQW)+T{HLp-B?D;hGd9Nz;+yin0Cq z0#zjlaMPjHab!Njpw)4&Q>t_GgxEd1lI zwGe*|8YeVvF@vS{Zi4!GrDns;8=PJ5d1Rfp7jF==>ae$|>Oo?xD2@P&kTTYM2_Wv` zZpH-fU5VuPKx6D9Hvf@GwrT%Ln(akPW+=l9(}bB^_%_+FtEihsiHz0c71^KJVTo@~ zeQvo3zPTlR5ME9(U&O5t`AGzA1;_FEsYuJ=2IcyAn*;#Cwl|F{DS2{SW0m=eV+K=@Cc6=7Gf$PWQCSQi)E zJfRWeS##qDb;u!_lB@^-ykR#VcnESp1T%_#^$ehjC)lxHV05p_{j}~18Mpkw?mFe1 z_U7yBOhqpi6&0RDW<^3i`~cj7PC`$m_0xO`6}ec>jSwf_*4iN$--$yD@!^g0C%aa>^cNk- zIE-RHl%isaHBbZ13TCbxMbkhkLKH!=sUON8E8n-?dZU(CI*Kz;-|dDmvW0F`Nf#AH z*s~cdV+J<7iF(EVNl^@7Up>dF$4F5-5$tK@B-!rl`Yr%Kw$lDmUoCaS7M&$Mer^$UTUImzf^%@&=Zqb-kQh5 zWYAvjdccA(v^+^Jr8%-hXKBdCuxH)6G%a*3)x5^3r)S+Q)Ed7oq-?p|sYDYfAD-uM zq~aN0m0GBZ@s^pB;B^G9m+(=;oYbaBu0%-eugmhbS1`GU>PyJ9ED@SpnwC_3SIJdt z2{s>W35p*Tt7GS3R4ddWjCgM-0{Mhl&dg32(^|4L*AI+kP}9 zcYQZ?es<-}Wt-U}4og~pcdOHz*pw%v*X@W+&|y?%Lx>)Hecx(bh%k(AGKb zJG)SH&*t}r9aNhV+}=a61jEMjD@DM~2VsIY7xf-8^OP8ed!gGr=oWQ47M-2?fnRL1 zEje6j7)8eI_^>mf{x$%3gRCQRHvv*`L)lL9m`{*pjApB&-`8!wk?voAW44W;yndRb zPZ$SgonD!sEfQ)1AgiH^w&iPL&|rdr_3UT8qGvd2XW;|Y)H%;*bDg2hvSLCnCbbo-k|*lD9Px@Wi$b_r+c9K&i2a&e6+`!MB#K~?i*)>sGW zgt3zlH`Vxp?STea}8M8RC$Nbi^8QFdX6iPX?Rdsx0g>x%|u@Uzr~(Muxr1zc^uw)D8c)1r_-5S zL_V*u1$^~IGQbuLOBz;5)yz2)MiWg~XAu4MQGZx5fa7dXl-=}WGw8du$oC>{U?P|J zG!%MDiqcpAStfGSr}ZSvIv?%7`wNztm!-+=$C3A+!9!EPTZ0cK;-f&;&CCw0F~ruA zkb3?LoldNqQzY=tL5rBz&rAjfx$KG>rj-GM2VD#Q^f+AxkepF_pN)3*hwz{0KsJJ% zE3bL5ijlG+;3%%kx?M0Z@c=(V%KISD(vXnb3>#C=P}NeDIUO`v2Xu3#i)s zSTi03qokH{u8-TPv(<+VNA4)m|FKq8%&o;irPo&}^9Y@+CWAM|N?P-7Cln(OcmJ}* zsGV@#dp5nk+&UboZkjV_1NjLb+)hK;GQ;2$fld~l^@1DeA3$gdUi5OS*G66mPr;h} zt`|J(9Fz<=I{{~Z_{YR&Tn)8wW;Y_tH$)41G-LVf_Jjqm@sIuYr%H2ObVA^sz5-R< zjNr>yY3dq+hR9N#P~o`Q6V!flrkAk1r}ST?eszQff+^7kpU(l_rZTme<7@{3`|_J! zrbu#wZ~?68bX(v*M8ZEuZwUU72E&UUuF#XgAg)I*3{PC_;`#aSsqisFOJ8?9#mvmQ z-4b2z-0cXTONpWP=sIOm#Jj%iY04p%bOw6i)4JVQ-3wn0w*njtN3j9HhTj+bl*IYP zhm-|>t7RVO9Dc((aT*Y`yr=f*b|{PO_01atXUmED5Dv759estj2PKjkrgk0_X4hR! z(XMoqxO!}_2t&W{Ha`4x|3Y_u=BRKKydDZG4%gaDD8B}t(|$VfEtm4QDAx5CuTq4~ z&~>$yExWfJA7Z0UCsYEt_18lxxt7^WcweHFvlGJdqV+@OM5f*kmg@E@Y>#<`znb&<3>>V-A1Yt=uuwadz?c4AO`7`2jUnlxq9#{% zcA4JfPJ3)}_u0O^1{dJ%1?_sjiXlzfFbmU(94I(BmSDbwck4r`cI}5>v%!m;N_^rt z62#L8Q3gXB%+qreCN`qV5ra)^QTPuD>Y*v@tQ^YLMOTQ{X%*>S_4Scg2TS$LLc^nR zmTrq=q34)jz~7kEQixxwe0rJal#Hc#_%bb?^JK zRdj9UJ65)v(Oq!T$3IZL$EEoW`W%lQ#P5D=`@BBT()&n&`95}HDAbBvjc-Jf+}lic2^C@st~)+K*R&4nBqN2n@US*v{~~@h_Ig#39C8+Ne~rmy0eEe;xRq`hIY{{qQZf zi7JC9bf_W>IKy4lODdD0!5=wx&8YrhD8JsyIz0{Me3;5+y-fvu!CA=_j&1<@XWv-F=j7fvaw}7MrP%k7 zp(9k^nogb!@i6GHg}TBSm~aIkF&NEdzO%zXhVUSNkc)5PU_3tahgB1pDK9sM2YYfS zNzT(lgNGu};Gm!5ZOzHSGNNPm0CM-h82}W7pI?SqyTWi>s6bE-nGVraong#W^e9Yf`|e-SA?duVS;)pGq+1j8BC%}<-R>!s=j zH%Dz)|G8NCP{)N*2e!*0-dRSmG4xlD22vg+rMm%_5+j<5Qo}@#%Xn+AsxYx z(LV{1Pc(ONV%Lah)0s;E14-}zIRfmoJAD2wk=l?hW9&(T;TQhQCPslv;THv%7y!4tUQv9EGKQ?i|NtYb&EH=n zrJHW`PoHt6kW{!4zM-PoI_{EOLV~2&m&bW71iprkIC%-wgS0_M0ns$-8`1p(QEiEg z*pFZN6Sh>;;6ge|dAQBhQ#E*JmEwXMzxYS{#V75@{~VMeT*s1M%f+^XS099OhpZes z6{S54;pdF9MIb}u$a70Is8AU$Ex4tKGTc7<*1s7fS~1+p!fQHfSpS>bet zNv~^=@gE5p{qtvSdzCjnAX=O-4bwh7=9*#e$YSVPQ=e7%&wZNAuDB>s8q(|ck~?N<{@SOqGW+2ernKXw@IVtm-zgavD6D6k@gOMHPzZF4mo!-KqM>881YBeEP8 zL-HB2v2(GcX{vBg)lqCo(nW` zqM%N7SL=*Wgnh7r!}Q0u+W!WWiRc85U*ZZrWF>h&skLSaLZhbe!< z^%T7KJmxX%=H2Ri>2BZr*_^gKvgGFf$zJxNh4=2XeZmU%VsNu(Vh1b5!9a>IBHiD{ zZb4iK*4bi}tZ=r$-4GwVx!~6bacwMIexoLqOhZAS;5B+Gl@a%>J-vMpQFthZAzh;* zk3OActVqoe^omU}@aq@oWUo8!qLe5Z-45B+-0fYW1bLUO71POw=%2=W#{^I@Y7Uli zi=n5>Nl?Ou=i|Byu+QpdA#a0n=}Cqny7N7dbcn5eUd3)jdT_Z)v5B$x@fu!PETTUF z`&4+zV)&zmbU4dx7(rBM;7a3dp}`}ANBiNVF?P_(@1JD)LEex)aHSH~pY~LJu zgBg;g#)sNurAuD zpc$MR&Z47Py?9cqDbuyaeET95f>3O5MKFFJ1^Cmr@KdVc(0c|mm5FD=l9GWWx%rzy zf9!FEh}&r?Eu2A56i6q`*3(}?5~F0pxOCf19m>LyE;{6V3gS_{oxbUqgH!|c;i{sE zd>jWJED}PsqPL-5XNFyav=I$NdR5-aM2SqU{z2s@#cEBb>YP+0%|u-2b3fs7YL382vavgp>c(d#(7*%tOqgyXYHumDv$rFyyQCpcRCbm zw7g~6r9f3jefST16Gmh1**FfqIagiXP(u#QxH>`y4<&=5Z$KatewmmBjrO_&?0pda z-mgY%M5ihQ^65~a&Sx9ahoKoPNb7AVXbAv2U93it4muakp+cc96n0uV(;mxUZ;B<- z3(UzrFRM*2i$=r?EpjJJ_x&F+!S2g<>emon4v-lp42M6mdegi69;FnhR|Hxd+XdST z>F_#)eLDYI)BYI&gs`yf9(agZ_Z4W3zrU2OS23`mkh$A%hBCwDPlfkb^)JqYb_7G2 z{PpZf10|`bz--aPxsWyq58>~ZEG9lGEOF$gkMBako(B32M2s7-pqKd>8t;n*DhTx> zw^-|L3FU8f3O}A4Go9))14RqRVcKHrO_prk+K;!@KTthSs>BELD)or*%!YmrP14oJ`Sdla7E}6j*di+NBnT>spZ^eL(7sccr^V5vh>u)7 zw_U{+U+uH`rHuUgn&^%cZw-6Pbu`1Sb67Cyx$c)u@FS=u*zzynTn>Ee`S3so8g)xm zuihXC=B^?^yjp_@DmJBHcx=Uq%V*IeIvU-Y%ByDan=zmB=sTD3HIapT4<`MdLmlve zX9%Y}gVXNJKGbQR@3+x7rK;=ZR|4#f^b_SV#@N8&@uWxhCt_wK<+OOmmfqItb2luN zKgzok=L4@_=-jNL&Ef{f;&^oh!l&u1e4q)Pi72ekVM6Nz=*+NB448Wx3hdX4?S%Sc zw|M2;afRF&Ady57>pFfKIG{&J)!)%!UdPSz7p}aUSGpBt`_;YAL2E-Aa6xE$P5bp~ z4^&%6pe!r2vF4&IG{()E?EWYh{CjA*Bqm2(#A>C}-- zw6l(o_exp~*WLG5vC4~|$Xq_`$+Zo5uY0|8ez7E_)KpPv3=ds5R>GqM?fLB#K5 zXkG}+h-1fDfnacG?}Zorn||)SNmYcpQ#6OUs>e8a1u)y>2rAuKU+1vJ zMOKriD7us(&I5pEI=p(uB@vCMUxOk*EZ-+LP!`!z3Qt6haI7*Jdp34YLddiyDMx_t zSZyi%n#|AIf#cGANCVoTqut8fl>mu37f^vK83v{8Hqh;$-8~t}UN8R%dPZe4k}4;n zXW3?&`)A^5xqWNV3vDN)byQ`w#$6PxP-)B+qgb~U1t|DUq|QNm_^?drH)PULvzwsq zM7E}mP{-dkg}X$1Nm_K*?pcM~yFuTf!N`yZxZ4Hx_`57V_-8iC?iufb{lK%>u56p2 zi#Dv}Fwb?#OQ(aFMHi+pw3{?>6)36HUGE+&$N`}M9>1PLZ`Gb^8JWb=#ze+`V+jOW zdPqLrl^7$Z1+NED4fy9@IvrTl&@~Cr+v@e}X9x~XU;|wuR`?}7cU(3ZD}Jao_=DsZ zcMKCZf^Is}-T{dwWF&xU%aY;pt={%RM^!2{7m0>8Du2wREGmCZ+OxXiFOS=WFQ~y` zdC(?(rdpc+9+m3i>vLn3T#47ZP1LFW_?#tGCFZ9Oh?z~`?EwoR&9MD@5#{c)mGV-} z|D0VO2C!82mn#H|JSL?R{HEhM`B%s{q7m_$W^`@@a0f;>G%kZE=jz$q)r$b3C$dU<5>>MNwEul04N6_k__(Awd zG>4P!<1uBNF?4{!7YwX$J*fcf#k)lg`fxZu;ZDqRJs)?n8n-h3Qk|)E{Eip>z|x6Y zOfN*m8o7g(kvjsfTi)~S57wya-L=-whC(KX z5l;%_-Y*L3xFXxx{yA;IX=Dg~%81-dQpBCdV~*C7wvu09$DB7B=yfPsDzd3}HO#Wh~% zV(rsSR@W#Zanrt}H+|VUk3h@8eC1CdO!XYy4GN4#-x6*pWypqtY7{A#X3BHH#qQ*) zaQe8(zvkh=fvO6xd%UX`eaEt{^z_aaWs^=>o?_KBn|;guP{vtX+^a&Mc_w(MAG1Zq z&inbU>wRdHHQbm#FM4A2tFoNwBURgvRJ!yRWpg(BOLnVAJx!P`UJN&Bo=ADzq&C_tq7nPLpD9K2o+xv3PHlvTV!RT%%zv=WHuHH&Z*67+_hj$Ly z45jFZS@p1NYcbtkj-}??C-9iyx=Dt6*ONz46OvvVjAYV~nsYnW@M(~Gk10#a=%bjX zFE;FO=S2p#om82CZS&T~^4j@~dlJeGvxm>>-hl)U$sr;#+ION`_5{B@NTg@&!R~COGM4JV1f(M z;-Z+N%y7RvLh=T*ZlYhnrnrp^$-T~-HF+mnE4QxboBt_n#_zFE zl0G(#xLpBbhv|@~b`p-DjpH;Mp{7kQP^HU%`Wz}WNg7J$pbKI>evg!|+TsEe1$HtBPrf7pnLSm0 zQY^vggZAhu*%)QA>r(cv>~h`BrpvPd&)<@t{pJ9s<8|@7U1Q0boL1_OOtq_XfH|br z_mD2=Q@f|CDSWVcMGjemaf_GPm`?_X~A-+6Ot&~bjXvH4+$uD6)6vBD33!;-IU zv4!&kpJ`9WYUyO63L`G$3$c%+8C_8Lbj208>07RrG5uE=ZU(14h!@42#f~=>7n)n* zsLAEcbcl-VSv-C{(m}^a!e(}KMd7^5w&Cwmg_Jcl=DDOGkg>0QX_#yz*&0m~W*~Ly zWzZFRx8p7Sfs?n3-Mby;r3W?dqM21lvZbX?6Zu_L`SL_XCOfa^CYtRt{d4X9(=tT> zk&6`u^w(&ZKeJCoo7ZN`UKh>3TZL&9@*=vIJM&5DSs}N<9JLk(Kx)`#l5VRM>gr6m ztP3z`mFN9OgAv&2?a-<`8^Buk4%%*H`It|_ejDz+Qvgk$YcZ57Krg%)FAf1Rl_cEL z`d<+K@6*vSuxO_51$yUsOQ5&7~ z&<+(A-jx}SG%R1~aOQn6N6@SEMn|^;v}_=D(n9NNm~mel3#mUjVKRu!&9yl>;sLR& za5A2Q*s)8)>t+labLJbJqv=1#84YKv-qF>TAU1{Jc)uZxstx*rnP_s@BjCa`4?JF( zDd=G_pw0aifazPKSsYn(7}Z}w^Q<#ZQ$GFIC|00`q$by~kc%-2Wz+Ab-@b&GRL8~x zs;jGAep5G};hn=}HGp|olqQdC*+d2B$ZzpW?sW9t(zEb**s;%`NakhHD5wDL|3+ZMi zR_6NWS7EaIE-$krj32)5X4Us4%PpE7lgQ1Ipu?9xFFdmrZAmb}<(!HuK3uL(MA#8F zKIAiQe$x+CCn>nw`3hO8L}VOY=siOz+56=zMDqm~6hi4_#Yf8yrEpk-hH(zCVx?}< z9zA+AT4i>1wmm|kzWI$a>-VMK=>kUk1vT%eFh}^SUEVOo&Xud9sCp1SMn_FP=S}a4 z6P#O&nkSq@@EC_ie#6@E>__S-T*{A!{hQcdZpp8n*7En=hxrTqjPgn63|roL!i}73 zi8HfT|7tPt*CnO~OviN8LfzV)6UtRAUQlo>7n!muak;IKN3gv%kf?a;k!fTnaY8!0 zTLOn3zb3rHhkW>=yzB=V{QoZsbdX+L)qc&5BVpTfU?%$+IEeC*x95U*2inkYVRhCe z5aBirxKi*t`_~C#x zRa{j9m4z*HwS+r<)6yJO%x7Droe4`>&>O0ykFJg~ParQ6z9JjUqc)t_V^b0V-8BbF zY>$VVcj$KZWZ1vpDxhZ24I;m(+7L_7;P9n`r&s(%_{G!l-3+Z6mnZ1zo{#0J+$X&H zDn;%w>ZDlQ*=p87D?`1Kf>!oOXDM0wd*9+3MVs09Vowh`vxyAmJn|(eIq^C`;9;R*j<|s z$0`u)5&2M}o`6s)`TUwR?feqLVDxr@K*;L0bPPR8x^#k1Po}JhhMSbkrJ30EEURt| zx(}#%=aA17fa-~&z-cup6R}i5IAhWM;esqh|KQwv-?!0n^+7Sz8+;WfA(B@XL}MM+ zQZen^iA+71SyuEcOX}{5p)oXs6fAxV1gVqC#TcuAtX(2H=B7CV)<-{Q2Z za#|&}H{tw!iT+vlpj6EC06$wo@k>(d1nenZ^vtCFKps5sE6;Z&$QkmxO2$J|+_|bF z!4O8rdEU;(=-6|ofQu*p+A=mdpZA5pxZ9yo-za1v+KBoCUJ?t%x}7Y|iR3!xI3M3F z#y;M9Dq9=m9Lo8O=A->gxsWxR9{{ak#C`-=M~!zYIh_=N$W!w7oqoSM!k z#q^mn81IZJmp-?aj%N!jONpCH#stGk#{b%A1bcBAwzlY<4?eOhmkA%^G?j$`7*Uu& zhTBwjIY8?vvR#N5`OiOJ2{En!sk&2t>AU&+1q;X1&c1Zno3Z4D!W$S3Uy(is(RAMBjK@}j7G0ITqv4mk&z z!&60Ik;0FWO}VpVt%Eo>f-~p#5Kcob9h_4g^|9+`?{sFkf9;pM0P#5sw4x{ zA*chB##MDLcCVl_i4!jq%ckSK+T^~H^7yC{`+dG2{Z2}M7FF9wJ)KfE^}e`PGxi0A zxBkC4{#cp}$^{U)e7QMZjJlQvi?+s2%1`vKL10`(cO#!jAOGi+@X{3@qOsMZJ6^in6fg_^t z&*S;WSQ;ddvqXKP>KbAmny^@Lk#Cv)>q&f>?l}Cgh{-%|;4B=O{o&BqXbg*R3Z~N} z^olzXUWH!*{)*o)!!ZtQ1&0Le=+ax~NV{v|zx#b4Fl_q7@ZUCc_R=`~$ogp1KDpR$ zGNN&%)Glm<{fRnjthZ`v;@gulzOvJ7!F=udKr@bI#-+Xj&DSR}Y-47}Va6;yL)o?x zy2I1x*>YvYMoF(Q<5qZ{hx@Bp7F3ixKak2%$PRZ~oqVv1l4^RiRWE+`bZL%t@ZD8P zp_^?KL!}igi#i~~)-xfE!Ep>;rfHDc=NBzCti!-11 z@-({JWKGwTXQ%^22+T39|DFdACgj-(8Er_B$HhS&*UwDb_usR}uYs(G(~jdxp2sG# zx-~}H-tglwCHVfBt*)ao{Na=)a^CV2uB7ZOwNm+;6BAW5gWvm~D-{IGi8I?bEEAq8 zZrQC7-Xi#7^NZ2O8-nf>+XlP`#o;NZ6au(Tq)`u3_0es67j2{HtBF2|kGK=tD{N&c z{7iR4%R@Cm=d>N8GE>ehzGl*$rmGSoXyl<=r!pwQ?(zxKI?!5&zcNzajZ(I&!r>pM zNUvD#h@#2i9@;;xRxqBjwa>Kdgw48=VWMy|z#I&$()aSk0r@H--O;G1coZV82*1;7g{cI^$NP5h*rrA(wt-XP^Y7*c)DhJyIII;gn#Mo z^S4r6;Ws$QCyM<*0!Tuy-Ys2UC1w$q=VOJrG^kPE$$jRdQb0K>b!ob(=yD3b^Tykr zxojy`y;>s6WA$phZ`V(AHLA;5)+SDaLk*cyjSKbIBcusBQ}t$k_GWe|7aC%d2QBt3 z-M`NBAwajep9=Fjiw?U`{*iggwTE7ZOnMbql=RkKSeh_PxYPHb?;FQvWl|C>c*^z#bZoNrr_KRxfhAMH=nB4H+eRoP-Z zjguo^FG4X>N*alu`eW^Tl0w3^IRig5)``(&NzKwayR}PlWa|cQ5D3Xx@Y*kt*{uj@ z2d62fYg=n>)OV+>)E;6pn3nfUkCEV_zp*9GPa%pwN=eH*c43QP41E;7yDnxIDKTs< z=AIlXv7yLs`7pCnCyk+mxO^Y*hUBOw&N2H>$YE%&ZJi$`YZBV)It^Vsm~q zyIGG#DAj|{d)A97L>x5Ql^+hcM_!OVESWpKS%9lz*w;`H&TFX1>oiBrtWl+K(Zc|J zW()~>TBH-$adn33HHq%=?T~VYNIu+4lq$*mjg6kulb*{ZUX`h~qZt_Ybl~|p)|0(S z{e!1FcnXIrR=syUWUV>=-ZI3DNp2Nxl@1-Rm~EBLEPqH1?EdiJIm^Fh>X-;7?Kl~? zL0*KqgE*K3-ng&e5E76(D}h~$Ulm>rBMXUXm3fx8!PNU-i4ZJb_EGwqS^OuwQKecS zgi9o7hueMWd5%gG0Z*DteF(ehoTz)Qz4@rm>n*ECz~SO#IvlOM#{S%gGEYBp(FKJ> z|Fn63%e6F%x=9EJ8v0n3iw_=^&NnD1P$V_C>a=4Bzjl8ubrS;Dl5-q+{aW0vxB9b` z+ith_Q%T3E-+e*yHSgx+<+0vonqGS20m_bIT!wV{CP^dH=78d+%imvHp86ZWy}b1I zUe5E#MV?Yc+J+DDhI#N{+_@xC$ldaH*&ZQ_^e9n;LWpT94*78=aTF5o?IQQ@ZagW) zHN+Fhfrrq}q|wv|VctjZzttZq|5^9HuLJ))*G3Wl+M-b$G(-4O=0xCWxL@ZDCKj#Q zXifWT;vU?2(HxJ(m@BN>tqzK0S#!7DtyH6&?aV~1pMLGj<#*hBk7vxnP!P+NC8y-J zo;lwdRzh4LKaj#POS8Q^5OZK>nXWg=w+}f27WuvSbFJ$4JnqVza=iv9&oV?O-h3-Q&CD%yh8AA_kS-cprlJOA|iPxzwRV2JojHioJj$jT_f`o$5v4Ji4~)#LFM zi6_54x-kj+5{@i94KXpY@LY(u=1L%=KrX_{hseUyrknVI>af5y$csNu5Bz8E{#p8| zQTktVt9+q{~FSWlNKNkR3{w{QSq~13r3T+(E0cWPD?m@1qXu^iHAT z;gaSz=XSe~@=2A^DFmD(jXU)Q))tFN@Ym>`epC+Ue!>r}K?|@4xEZ^PB#y)WU@% zA-YIZr^{RPQY+8nB0W6w#fNyB7^Fx%oSKAjX=6EDAjVF%k_1Ba1R9 zNBMt6gGlP<^AHIXqBlDozQJ3s6~bGu3Ek%xRc+8hE;cRW$n}7K-`axV91zw{X#-XS zVzGxAn-`I{r9t+M2EVo96THF~Doj>XSZ0h%$ahCHjQ%hCM*`Y++3=P(Y$x^$kUR4j zdDG*0zxyqij=AtSj>{bzuK$Ly9?a-5BL&6yn z@gE#hZ0OKVcArx4WfEvID1_51Xb-S(eZj00MXVz^MUNEX8?#ST{*x(F_x>@8|B;NT zQYFCy;K|QcQk*$MkzDwgBDt&;o$!$5$fqpljBCX7VMk98aF_HArbq(}AQM2I@AIsQ z461L{3Fz#}+Cl`lBm%B8x6n9k&T+WzZ@l{KgC&D|Q~b)tN#%Lf23&M#>3+y%r9&K~ z8GX-iwrtVQq|R_`I~rE)&4ZsQc^<^{Q^2DGzH63xk-pIq1&@tSv2mAGq|x#;jLpda zy3WFImhXYZq^c(wkInb))cZ|TAlN1adKD+-=cgxXrhL4vny^njI?p?7gE4Kxc%LCC24 z3mkVC;V$KA+WF%na5$1cz(yrpugr`PWa?Ufd^{o4E;hK-U!XHuuTM?+OBP<70b1^r z>s~s+Sf((sZLgB=Fi9m#Ia@KM9n?O1K~l=Qy&3t- zuQpsbDL1CCO`T==$QJr9X)_vU!>MO~u^{hcy1Dmz=Dz>6dl}Is4j^f;09Z2T@^i^w z^gy=~`VQUl62?H{P6mfknKuJ`tnWbBmT-BVP@tIZ-#&8n64s9@D2MAUz#L|cs@x$e0|EUbTVU&GGnlBSqrghk|`xP+0zMKxTB z_vdgGAcu?Pt^?x!IFZBr`c7O2rVkD}?L!K&r*y|_edC;2y?z(A$&t9dEQ>C_Gwha} zG#}SmNy{#)$bc~Ml7)K9l5j0x;8IfG54tTm-P#pU?M)A& z7U`hrq80!9_;7c5@%?%6M@2?3$uJ3|D>U1SW9KZXFsYNNsQt}=r4UM7#f z0mW0CAJOJii9WY~1j9#&oIq?c4Rm|7(%f@>lFljc&+4>5W~N5||B7$_rRVuZsk!I< zo74`>xsHSY7|SDft>;)cS=2YVF)5$7r!17(pvU;$z9BNlbC4UsEXK_3nCCxIm`|?eQ0t z3`ud6%8TzBBX98bzznr);LdMNx}Uz$hvStA%1T2ycq@yJ&vamV{nlj+2DhUAx!ug4q^iMq7i*P4C7K3}n z0;91t&m)TI!{KCn-$JJIfzH96c*YZNNrm(cl`ZydgV9drzU0v^wD%$-L%8_aX6e^A z6v@(idA#Y3iYuF%U}zV|hXsDu{*wTLyLk71{W4aCu}Y#ej0AY;Y(_2OxlvZ^xz@WA z_O4{ykNG;RW4kpdB4p<+N>xlAA{kXy`ow zVNWJCR;5<|S4~m@#0(EgGCHO14I zyQW~m%ofklxV8pt9DLB%?N6bRiS)B|p=yJ1lqR6+_W~5lK$we6;w?!CIA?K?UQC7J zoW`=`BbTGSyCBN(sIReL1;okH9!9g_dR%_Xr(OBnSz`tU{b`wi@EMx#5)?Q57cOS0 zm6|9>N3p~gRk~q05^V#EPZA_caKB^Odp?Tez8k@;6}d6@EjOyn&Wn5%o19l1v>DSe zaH;+3lB0rygNINkg|XLYV8DrLY=hM?C|ah1>Q=z`LfEYb)MOFK8gEJN<_(CX2;iXG z?k;rSOm+{v&anVxYP5?B(3kID_33yPdV@M-p>uy*5Y+I*fXhW}h$!jx0F74;#H7+c zJZV$}g~jdSjayVRlSNN2jzfo(IDZ}p2$E2eO(vgb510E@jGdPYQj>42L31f|qTc-x z#3X5;q1O#9M_Cf@0&WFplAUK0?4U~_ni_84^>Bj`h&VHi_q?lo+<@?u22!2Nu5kE5 zkddA!+lASnszFWOH4NWxa)R|`p4azYZIiLO8&O{;BjS|qsNQj0`sAbDsI>&N@ zTj;}c5UZF#4C8}=6Grza1H@IbR8U_~C<+sFjEgGu5KPJSu$@&r9=BR2jD+7uLHVm)H&;N_VhgCU0k-1OpVT2}r5|Z> z*#Pyk@VieXf5+X_?0_G#w&hTwpeX!urCL94`NK6}ogwu{^(BS&U%KzQoPqA&#Ql4X zOEQ3C;Oj0!U4S(!NP`iZldQ9eKlxNGYZeN`)Z^nfyuctOmK6!xT0Ewmo6R5tmpzpSYd?0o<4xlB+maIU3}7R3NEb zMc184N~Xuz4WAkhv*l8koSTP2!m`XH>dgfj+gd*c=4M;Yt2%f3OlH29PzaHmFBcAn zhw4plCtm!rI5YAaRU()u9(o#OqVE|IUbQN&E0F`j)*7M5!-elpvTR=EY^{y+Y1UZW zAQ!NH|Jj{5LGsGA)ZlA$Et4OdnBxUq{H-QFis;q3CGT0|%TJ5Pct6d?L@mCXo22vd zngtGZJSp|?%hauk!Vr$4Z?DL4W`GdZu#yP$aP zoNYVB20;xrQ#lK#4g7Od{kkF&48u4?BFxqOqbnt#T1`6WhRuSW&5q7PByb8 z^y?2ld!JH#57NUDD&wp6UMb7;0 zeeZqkE4)a_o43E|IE}n2G%hnhwcg1W#xJ>(o8O-r4op#vRU4c8{S zoIfi0mAs}?V^9j`4d}za+>)#PX&=eD)zWFx+rriu$eG5qq>?({1#I#SAFN(i0rN|- zg zBhTj=BAtcBs>I!n2?feu%)R5l0`>!DQCxMZA|-z0jE9zdK(c*QHea z{vy`+o2>UkZ|`1trQmba=twT-4|I@*VdcIvd>u#>X*Y~DcFV4wVxh)iS;o-49f}1LXbq@A~1VCG+d^ejaG-c5)_ci-s@SK z&3Nw;Fq9*WC;Pz}Ne%|8>kxc<8_=1<6_F$;m@%*-_I4L041}b{if<+g-*g;g+Wgkq z&@QDghl>C@2$4mmL|iZ2JPh=%xuk6Wokd4*0imm!9&7jP;#cDPo+AaYcCk58l0I=X ze1}1ptfdoCaxdy>dI+5x!N(*bV8TgsEJ*I-K^pq(A)DM& zJgQaDcbWkA+Ii?gIq5Vnh671esP<&M;Q|-2Xh(@rsmTTE(lOv-=vx*cMK^lHJi2y| zv;A?@LM>F}v-b}G#_ZH1glirfT)IfN!)cb@uaC0O!LbSwLK z1e58Qir^G6`D*2)r~y*m(DB#Y{3Hn3^>%-RJ98y$rDyIV##_!u^CBflsF`?FJ1p7% z(X0>`tp(Z0XF$_fZ$@$|;Wtr&qBRgwzmBu>pzu;->1G=z^l z7eM+LIq3_ECi%$O|Dmg1c+caxlvg4Z@ct1Fiig~?SUcayCcb?qO#W*g>tN79pUBbv z=50fz30GxR?_uCuU*7KycDk>TUKba88d+Z&9tH@)BsfvW5 z%%EjKQ-%ieHwS!WG2P4-e(Up1Zkb>7H(?2nz4}bKsbypA1wvaT75y6twQ&gVyFhTM zmT-qBE7kV^FQptz@o%ySF2WhSpge`zJz?A|vELBZda*aSd7`w{zcTUq+XeK3pHms# z_^2nx(QD_)LG50ExRwfCqg%D!7tZ8S`r}NH6|qF*G4Pr7;a*5=BPP)nA5j3rbR=jl z7Kk0!R4U~x?igb+H+k}vYhxTH(EuOe!1*T`1&JiOZr*?jw;wPm^HkB5bQ}~DB8l~q zEq(3Acnoq6q#OKA*W9au;F*Y_9G|wF-SyVyXc%%0(pnMBOM~|vcQYr(2G}>!kH$<6 zbD*M#C{WJVzCPhqETENLze73*(%?wu9{)Ve2z#vskHL<4+Bl2I04Ui4Incb&uAxkD zwBP3}z5ERlcuBvQBDW z!!}U)-C-E902Hd|(mhU_7r8m<#Ig&?vNDj>vQ~LU!=uVVW+;-N z^wU**;y~fl*>CJ?xJtLJsp6wm)-ROgE?{KDF-p^K1igWzkLA+|5&zcM`-}&`qjnR4 zyNIL|FoAnS-d{ThCe!gg5G=OAu+~DE4zA`GEt->=77dPZC_Wz5GZnn&ATu)V4%{*F zK#HuO2jsXMo=uz+f5@6*UtOxp2Xg{~gOh0uH0{08Y>%PwT$O}<(2q7-juxKnN8u8nIZvsGx# zBJJh&mki0G)&GKNY$&e;S0S7po@Vd7(Aj|+#;rr!y^rFtux2$6FmD5fxYTxM;1B4n zxuRi0hGWyAj&Kx|cu`TES0~Gqiov5mdHJNFId2)DY1BwTro$e~=flh8At3f4O@MuP zPZxqrmGRp&>Gpxn5*_#eD)rv^XQxVlob%+Q3fIbe4oD&GkSHn<$Oyh&JSGR!6BLrW z$a7HjpywG73q)=fQR> zu+E}6@Fw>@0s0am4_D%%&H5|+V~&{$-;nTcUmJ&gujGv`&(RE)F`}8_D44mVIVFvM zZvgA}?aHMP#)U31BnQOJt2YF?d#hdG_hsagH4r9gnnTaige@f4%~cO+Lj&wPZiSzl ze;e`ay5QgJr>xQ-ZYcMuP^&!APw$c};K*kVUAPT%0?x}Z&e!(C_;{=3_CTed<%sCRIK-C0E@lnkqqd@c0R}nEIQxlV1?!NSYZ(} zQJQDD_wjGRp|TvM0~uDF+vwIS!=1dKBR4Jm%lWQY7Ma)8j2(~vzTI)YPYM^8Z%<*8 z(1eri#jU8XNiP=M+fDYp?3U{o!XRO9()!4A5Xp~PVd3p3>5?HHY2PZe?pe0>tx!dm z3!qA=Z?ocVZ8VfMI$r2(Dz`MZ5afAnF5=I>H^7&JL$`}OstG1rt#8KDDu`OQ`{uK_ zQClY_U-b|qq5J78$F+uBoYr=>C+p8f-n=8Q5$1#6jkLf;yz^gIm9Ctg-rZ<1l-j|y>X#&$R-`X&;;7<*sW#TQNm&O0pxc9F1~8l;({mz;-;a~%PU z+|QC5ZRYH~2m<$p=<9ti^lu_Rc}HU7;B<|0GTCIi?< zgQ?Ss5n+^wh>RkEr$xg|+sR(Q%yMX)e-Vv@0I|eIZ-u={lRmyhOt9~co?iGPee6I8 zv>~H^liUU&Xz?Bas(fY_P)!HIqc%T*hUoeLxa@W+kOD{;2oO#|vMf$g;^G+Ko*@fTuVQ&Jz)!$h*!yT%N#Sf%6QB57E~Sxjb*3?O;p0Z9+sqQR_MhNx#dE zhK}2vi){@jci#7c?|f~pmA$KMqUE!7NEvIB#gg;@U{*0Gd`(SbK;}9l-Xo zWnS+v@dE`DAOFm9{4^x}t;+R zsOOgoxeR-3(OaQDCp^St6YrU(C5S0m<-0Fz?kR?ZrSWPptZ8};$SO^p+M4{nfQ)j@ z2t9+8eOedOTywYYOLoz>dvo*%~Tq zlvBh-0-+9VE?>}cR==RYnu;@jD+hH>oyH?QY=F0*6zC&2ki_GA!prPfvb#lMq8rWP za}s0$*ADrZ|21T6xeerxUDx?ODO4~9+6Uo6*C-aJut@g{%V+U&#j`Y3IggyvYUrH+v>qrf9f@7luIagUyT7A4lm|`&9mD77B?&p zBU0=>uWLk=##lIdB7nNH>^JoT!x&V3)35U6o85f>P+5pnv1nElf3D{XP|9xUfHv)x z>$||ZD&$?P@70%F4xf#VrK>JXqW+zl&EDC|UJm{;kz~{l!6&Wko+gXnbXdZvl)aV~ zs$*fQp=&%u^PN5kBro>AiUeOJ+tc0Dx8lx}rotapnQq_klQTV0@>Z*~Ym+|j~_)tKVoC*kKQBzm5Pk@JL$aSAosFF?ReAfe&^=_E3h69U zp02_Vj#&H*840o+KHCZn`EzK#vn;*c^HZwe*lzA(SKsx}SkZy>;%3!1NAbH}LdfZa ztJ8bwxR0Rb8aX6rh}xI-;Mkv&^y-cYMZvZ&`tKGJcNvTw)LM1u@(Jbm`x2t|&pgAa z?F~Nx!fsg=0R1=9A|P)eUI_As;jUj}Oqlp!s_FUGXGX7ohX1DR!`XJdGB>qdQzsx3 zfGdj6DGOy9&e*VPNbpQAwnpK9loXLC>83=&Ca!K;9M(BCYy?qu@3go8;PRx8B#;D! z6Nm=OBDHET$BgyHg(F`7Zca&L!&$T3as?YkKg9>AP4krF_HRk-Nftg-FO1PUhsoC8 zm-5b+dI%+BAHXS6+j0hi*Kw1FWr6*J>G4L7{;8M5)At(;ZH>IP(uwQ}eLdK?sRc%! z0!$j?sDK?=QG;lIPod>b?~RWMhhRaKV7=k(;jR@@+_RXN0OJ&+hsyz72n8Lcf@L{X zVIZNqlM}UGnoK%&^O=A_4Wl<5JTkgkns5WCnTA99b{J|4$U&LgPsckj2~NtE$gRKc;sWtI0WzkC_(Mh}1AR74O+w0qsTlm+ee`IG2$ zC+S0rcAwunkriXlsGjIXsRs)17-f$^LVkq6Gq78MxxyHAnG&-JYUZB$4v(17ulEk*k49z++AeXMKEPJ8?zR7xC)2>!}YP z&UiR%o6!UinI^ut-@%m$I@qM>2nxG<7No+dd@JB<{XXWuRS0uNN5m>aqj4B_CoPl) z^$L}ydnNhpY$tse1+*ZDvG`OT%$yr?ms&V-9(@zsljnR~LTl@|gA8EVnK{+51k zF94ulGW;m`t+@H=ExeDC)d{q40lj-Si`m=W#!Z`EM3*agWPo?1vmQ$iXb(Bok3Ct! zoUVMP4HF2YH%fzGfa`b_a8QtxDR=>9lCODCjHpCZ+~&7hdFG^-IFvjGT>ViZ>TnMD&&coL zr%T~fE@cvbkfi}vZG^#BQ@QZIYk)Lc3Ea;PZ8hevHfM47LkH^1$8@Wzec(%NkaH$Ie8l7@%VZ=h>xOiE{G5z$ z#oduc7bx1}wk-8S91?VaD0&rw7tf(6FZzT#J|kw6>Vx2YwO_e`5XWZ-LkRkQ{$v2f z^zsX#yABNuTJ5hd&kqdJc8E|9LJ17(L8boDb|d2QT;^lk|dK}bmvScAv^`F+vlIwk16Ge{T>8!lgsumF27Y0w{D-e3rT?QO0CC;uPvODL4U zw6Mv#7@g7svhB4H_nG~2I?+(NZ2^fVj?V;(}$G#i3N@JNLoa+Z=0hT6B%`EGGbCfzGZgYO`D4_Iw<&rj&?;NySU5P99 zK|qHlo<^EkBQC@0Oj`ZSI{F_?SR@rzF~aRNewu-$%JE{$2ybZ|;b*Mq5D@HE8~63< zab)OQ0#9*XRBRFAV!Syi&WC4PNu4S}r6=@<%FCjtK*fNnpN)PyZO~v`*3v5lv(5@4?=zC(gGerxiyxc^D*RFITv9~ZCA`Y& z=|a|#f*G%MzclyQc}cY^{lIqFkWK{EVOGLABSHQIVQVqEt;P`=lMB%r7?qBpZME(oX6RMQKLGQK{<3Mveshyo6OqgY;HvbyNR(Y>7^ zoSiRffL*WyIuIR2D++dh#Dofek=Xxr?0YCvGG@;o4s zQ6ug;I;lYhr)VGbvpx?|H+#P9-3n5#Rdc z-!cG{43GAjGX#0j;h&r-$GvTz{GNQX|IMtJ=5EypMrnbmh$WkF28mY?=Q^qpc9Tbq zga>h(RqpXMFcU0wI>ZQO*K$mu7~X=X3ZVl2J|sb(tCXM8OYk^U;|H5d(m$>vL@%Dc zQjX}hKgLBxdg`mbQ)|gczzk8RfIroFL!`bOIw>x1;+Z z=_hjj8OdQ&?O`IW%2De6%BQCgsW>^APND4%(y^ySyAn<8lg3>$5E3X;lm%`j{HZc0 z;Ii?iKK}wfko0lIKNk{UO5pwR`M@c2eYHUdMDnpF<~G@^6)H z0@F z&SmVaxcj`vT-;f$MMAksrIEc@ zgaPbjv-Lkd3I5$%D!PINELHuOYx#+TgBCWwmGYNNN-q3pW-+-``R(YLL_QY@IeH8O z5R7{KINcnXe9aWj`)tp;X6&_eiz{Ea8hYKDxTN4u#ft1~LkO!FtGB*9S{Rc{wf6P{ zbAT5v{w-oS;-&to#~;C4k=9exQ@rVK>uW&+n%oSQl)jch@U$$2fEpXhu1zubs)V<|zPm;MmkX18=tc3?(W?ry7|%NuI!GeR z5qNbW9f`pY9uXGYi6NqfzX9<|zd%wvQ^Hw@B1lhiovzBZ83wm`ux9cj;%Gv;f6pww z52cgq6xB9Tzw<;R$i#AF{@rd~fWHAi1xb-`=bgehk)C5gbmk}Rmw&!Laqh_uumBt(7r>Q4yAcOh zZ1bvH-$NHfgA*GSSwYG8jx=q#+Zx-|==L z@bKCStzsI(#-O;fnA7wbr~bHIaL`zd z?e)H=Je%Lk8mb+M5Fo2Vxk#PrtxEbJa|2BQVG%ggFXE@1zkO0p)c8aVOevN#CXX{C z8T=lqjf7ikD755DKNO{(;iA481Pi)%0{ZMlE)D!{hW(bgdM~b9B=aX_SIWshX|T|A zgphT&V;*V5rahcm1_~XRPrfe?(4L$729Dg8{`#X`bz&}cDm{ zxHnbYq%GK*B-v?hw)u7KnrNQhK_lnvPg8zE)4Rv-x3Pk~GuYy7E)svc*l0zz>?NrS zz<#rA_IL@ADsb)!zc{p>FpUkFs<-hA$A{rK>1&YSGCUQXnPAyGCB?^$4j1So`V$gp+o)FOgXt zb<1v`Zn*Bd9lN|QSJmw-$>FbPHHdOMJzTXo1@QMaD}htx2hrZ-W1Ip>CP)n+A3p=r zxC0fuS>=$!2&yfQ)KLFS0Ok#2fA#FRRmXJk0mf{v%qK#e>BSHiU&<6 zWR~c^H5-X`90B%ipI}1YDbS1Gsq1m6Z`slCyl*9m{1FUZ7e{JLs^bt~lEEP^RP}^z zl%?Sd=C5&?908Y)=gtL%@sf!>oUV!ed>FD$K|Ka|Ewx&t&mR63CgW7HvYHEFL?b14 zC612CRc_|WxYHa*o<)LrB*t+>=3NhOYkpJ7e# z6ZIsQjvl!kQ%NM*Tiqn>`oQmxp~16)LK9PatV{S71X}3|UV+Mhj-~?7P8-v7$etFN z8^2-w_tTx+kM;t|hDX6K;GL2O!~%^b*}6GJ`%{tuTk?e!hP{RJ0x+||S+oKDA(1H6 z!|&a4lM!_rLF*ItkS6DGox~3((2w#MnNgOX!l=hr@5B1<3b&QJ6@yf+NUv`n0_5^mml9vI@RR@}JM7^Tu!F8Fg#vf@Zf^!IJhEgAnPRbksv`a=0p- zu}YDtQR`5^C5~2L8hRV~tj}5g4clSN(>m-P0iIw~bPgfu@LGxz_VC8j=HtEwI3q_P zMD{XsfZ>ea7+-EJ))W!4tCsHf)7lZQ+=~*avAQb^sBxvB@}Vutl2qx+_!{m3uC;9t zfa%-xqi!8sw0%50S@I74vyx|Fi_}Md9P_72c{wfo^2UELFmTTB@NHbEjq;Ul8H{k+ zNU?gXz;0i6+^Slk{jeJmm_z>`LCGz1>=6vy4_pT)dvOZ8Vw{>7xcQN!1#7j^a&-6` zq``9`?8e6NCmXt4KHB=$xqc?-KU8;&{rlHxm1c8pVCB&hl8|Qh(vv-!b-(IJSQz0^ z@oB=(cnPEs#KOFR^=7T{*qc-E-Ynt>%F<9jT$x>P?oYgp4ue0=mf4Hwz74+y<17)P zFS&D9_sZs^T7?dtqI&X$hoM%AoUtWaZ;NczY#Z_fy z3Sfy%)LvAd@d=PlfRZ8c_2=H+bFG+l1+m5u&<{&$=~?UnHIkH_HfPj?Yd2n8xmzqp z@$mag_Kz@+yp}gDUqHerkX+Q-#<0^{o-%;J7XM$sy_uLuoVC&4`(T<}(5SD`_~t$U zQr@EH&)Xs>r5`!Y#VK%c^~X;QlpoyK{!qsA{o}$N4OAm zaFKm@2;^cPL=S*2EpmiAyon??tF;k%27+Ca z&`>G@{dR2g`x+3Zt5jDQh%K02u9|8EGjD6i(3oraZAsad>N1bzc{_#PO})a_l-SfJrL`uj>B)ciDmfzZu5w#6XqOTsaP+vWa#@%>mBmJi;-tzz>A! z0a?D?T5@o?XERy$?aKCjiE+XWFnOr;tH`iURw?HKg zyKg6+pOsx73?PO*ZkM5$+B;MO1M)BzuqJW59&!Hr8OKF{Ia~#yMa65Q*=>OLYSvZa z)qkbD;LN6xgoa+l=iidmGuU~F9(nbBIA?O+t-CIs=1c+JAWDx2&-TJ&Yje z9DC6JN9otng+1t3Y^`~l06{m|IsXNUyWRcXq7`bGN> zg#!@bC+o`n*0QhJXtn|V4cAePB6*DG2d6s>*vAA7#Z5fcHzDG-f2!LUTyZ^^baPhH z?_98bw8V+fveUJq{GH<${=eKEpT$kwN%e)ZAD2z>23jfk8GqflRb|<`8PsRxawt#g zc%v{hh{QZSS0O@%oXIu5j)(VsXJpuVOf z5f!>yyhvv|ar<7h;ynr@Fg*4){S~+WV(#GqN0|wWs*Nk&48EH65)|T@8yX-_fYMq z`Afi`cHyrY+go5jMd<(uAdjqfH^dRbBrYFa`5UJnxFzb!R#)oRS3bYl4=Bq75Q9+y zvO1{0@7;in<|f*ABqrLi^FVwtZlHW|ZB9)p;q+iF!RIvc5@;VE5Ga*%k)S(^bzbN& z2)Kn&a@?A&0y%vUvCrw(X|3CxqtdAT@Y~+8x*x8OO;+a;ufHwT^NIvuI9}oy{qkM* znx!mv5uT*Yb_%C(2pd>_Nj|^*gxJBC`7V~NILbYpzuBJD2n4Y?8t)*6QRS3kvUB!> zV&A@kML!G#K>uJ-ky>Q_Mp+ecbs4iZquAt8N z{T-vwP4oxy2U-B*%~@2ue&0yCn^{Fo<=Gqe^<-&M6nt7EhnE^Lxyy5JSLmp75||Br zf3m*tB_NxG6Wu8VPr;7DD}=z$L)>Qx}^+L0%IHW*7uG2U|)+xRx@y0Uw~ zb93T1h(SCH*tdYR=wbtp^naS)e-0mT8>+wn725jVJniB7j`-ihr6#5HUHeOw`sLNJ z%Sf4L`F;PoeFRowq2$fMy%sFS{1uB|eRay(1rL!e=$pM4T9?x5aa1cHU`4uhL*(|4 zVk!6TE21>nsxRQ$tGIvgPTmA5F@D`z#FHG}>T@hZFTBw#^lK8ZpL9Pzc9nkT{Y&1o z+{V&V8K#o1uQ)f}FFgQKEF&&nZcbKt$~?X4X=5C_qdYOaoqKfXNl%TBi`0DnacGo% zC6yp+5b_+ydyzB zntK;%*>rPT%~mYpevYJjC&5Kbn#S!Rtp_S9bP)cBl_yEGD$E#(q6#;4{4lFMUFD$t zEdQM^qVHnttpFs)7L}W5Pqr=%bcm+OzraSS0$CObGi(LSTEGyi1Q)MP%C#t8AYcQb z!`DG1z5F0Honpy~(#d26?241YS{Hp&8LUiM#O#nQ;m13GO`2m8kf>pj0lYZk|D?vQ zGoZAQ?5Fo#r7}QT01cbxeXqZw8Ch{rlYu|=|X@p6&K-vF+h zqqJ*C{63&vVXIhbR}9*BP~61ZH;w&^Ngg3W7wmS1ozd_VEC%pZ@wGl3I|la3#F%6$ zj4slsxaVeGGgz73c|t;u25R)@EOA7BRM};Kav0-8P%u$x`g%}>zt#WY*)U)q1`l&| zFvH)o(O)-;@!$O};_#l0mjs`S66p&urm9xQQAb8D;@ybk2>}*5CcG7kEW7wsLgsce zPGCbq-)kHR6&F+BME$%k$iYm>qpv09MeE)^w&7aUr zQS0&dn#(ycPl0#=U1iY_kIFv*REM|Kmp0ce8_Q2TQX{&UyAq)7g}3aCt9(?@&7KQp zW!>CV_#-MA!WM_YCztAzobX3DRZRiAHY`e^ErE`P+DYiug*Gv+T?uK+Y_`dbiMK`d zpC$ez1JR`M$J1NbHI_Zqhtm(VqbxV_Z40kc>>@zs+D0{yD@yAH-CPGbJ2 zKtOj*7ljnt!%WWPbZwO)sG6DOeP!cml{r74UVI7h%-u}{pR5)GibD*_U%4-V+s8 z8}W`VEp-HFuCT)xU?8(8n@95NOVbVd>*k4Qtt%V1t2%}$bOJ?TfeN_I8!q$o)iufJ zF3y1X*7n_DDUHURF`#fEiD*^j6eilqLXMvFKfr+ozw8 zG$G@pEhm88{;w^TM-5US3g%@f0z8Xqs-)K(z*8^CQl!3~#H?R;=M3yg2YE^{8yrX! zuRqYtLU{^={g<`UNs3RMfUK5AzvYb;C{BYl58nlYg_r`ED|Gb6d0W9+?`h@T+8T8l z$0wmTybQ*@+W@|cBWgInJxA=Hb3Bqb=HhT#fQJ|*EMO{{kO=pD#*nqA0J?>K6$@rX z%|Gt9x-D2KW-9R=Lp7;1+-Cxlg9u;`q-0%3a-;`@g8-U4d`H-Jhz#p}R5R14?PMh;MlK*VW(? zJMzHPc5L$SU1h)Y!VJ4A*wABj0^ejPtb0z znk-1TK55bca5H#KjG`U=e6!wL&L=WUxGeVYg8A4c6$yig>zE1i%r#Fdk3-bCNS=_8 z+F1cnJDr#YXpG@gi#Ui!NwgdP>5pfH9%ML?!c_|kc?rjWoM*8AUYp8Fo^%caSW`4* z0H4Hrs}VQTz^!4_yxQfx~#2lSltqs9$XeknS8*omen9PaS4)L#&cK0gsAYN z#nf0FaVJFUN_XbF%Cw>os&wfZjXZFXHxFGekWnz_GoTo9UFZQ*P+aC!KrZ*N}%LUjU?VX8i;+nnh zxT78>ivu#6%;D6k!Qkn30Y2w%P~mtn(YKhJG)6}CA$WkKYOwNpWB(TDPvv8ZH1DY> z@dRjV*~2O0=&nDjD&?#XQOe7{k558Z0IuuxAldhMT$afsMW9#j$MZd}tf^F2n3I|V zf3QZ(6QGi3YKYMs<=nPtKqiB(o9YE2wRds8tMVvenm5&xkIr6wPmP;HYf^!MXiJ|W zH%)xgsg@EC(_*&t9LO^~f~h+fIS%FY@rbtmVW3()KRt+nkxXv^JDbTW3(1BxE0I_^ zIGi8;!jL?Ti|UBrDG`?|9u2tQnkDa-p3&~f1anx_xyE5FM#))z}c zQ}_w&$Opf31BjP?A$D}o8FKq~2jt}ATnPKBC*bmQ9!%F*zwWvxM%iKz+GUU}p#is4 zwK)2Mye!dqq4ox10EyF9zs9JNhWzn}xe;?5`s~{6!T8w_MgltGF-C@P)ejO^lpf_}l?k`)H+1U69C^@+n8SUq-m?nhd^JKhlP_jOr#IoB-y zl6PNwh=4z~11Jcn3sS^swKm4!aQtoDIf_lmbP{?P&vQ2U%4IFQG@viqJi;1hfGSc7 zL_?b{eYEhOD%W!H_Gnoe&O17Tw@I3|$Bk0#&}J~pa@nI%^hB{iuBslx8kTyu6Q=OX z$4wad&R$C&y*`F!Z72tR7Qu}#8nkK+dx@w;`fq`r{xO}@Hu_QC#J{j3|HnCb>CLg< z?|-%xy{`MTGeihOboV-L+bczID(C&-{Pw!ceus*_G_%zHh5Ra3P@aS9;UFKjj74&jT|l&5jM$5$fXu4IzvRF24s13ysi&j0C%uLBnSa~UqM!o0l418 zhO6N6qmy*hh1PLxsLfW~|$n zGN8dZNn4a67YIKUW?G{g^IMVcWdU9t?A&wYdD|Bujt*jYhEAa-!qD=GH}`vksZL9RCv6CI(Z*Lwrkuzu+`BP?Gu_m&B&z^nqp_I ziK0?%kG_)*yH8Mk5?}zi_&uC9=4QyTI0yVJ;HHqc;VSQR!t_{i?lF;=c_zg$*OdI0b0YTgU~Aj!&Pk9AG9n0^Q>*Jue4!i=%6ji~Tf_j;Ct zeZ*-UicUT^&igbnaj#&X9#Ut~Fik?E67rt$PoJF#80g5hB;i|6!}s>_<$YI>Ki6r}jQ9;S zEF>O|<(+LQBw4yGq)8!}V^i4C33KON(^9CtFf#HwZM6#Hl0uW~MhfFG^Aaf>%Edlw zBjdoqz%99m_`1svhjcMjo;JV57=PfWQ_m0Dh8zC+2D$R=CAVLg`J9L^;D7N@Ux3jX zety{&5R;L{o15p|8G5RgeNasMJ60SWC$C%8b!YC}w#{45Cq0qxCzl7?uhbWoBVT;R zMqVWN{yAqB5lnka+eYx1&mbr2vBSVdYJ|qY z8)H~dKm4P~o#iM;`|;>7$-9mgM4H;+N3d$9a9G22pzV?CLV?4I zpD!=ZJgLLT?KMp*_m)2r2A=>oPfN810fXE#5ezWQvM@nMP^?Ay)$J0F2FC7gPreN00O4^gJy;H%jK2Wkp%OJ zKbG(SjQXhf?4BP(+Z^WG)dO~wi%-1mjps~0<4jY{yfIt^*0hJfpfQc(ivZ7VuR|e~ zKn&IhocOxr(D7%I7OW|0%R=676!>0T4uW>%z`{@`aK{=~KD*1AW9%-^R=Z7^W7zAP zxGm+ns}Fc;tu{!cg1(WxUTs&T9=%heX7S1Fu%Mv*>i?RNGh)ri`)gXR_Xqg{!jZ}gKgix4ce_ueZIN}e|eTXDl}bX zmBXNW&^9f3a!rLqH@gER|A#|#v*thkz|F>8Q#TrYr}!`C#-78{!q!0!Ml!=O>hXY? zXKAoVh^&;^w}`Q*R+wk+2fS_KuFLuGC(ljDI<5?lL*eyWfq982mPVBc2xx|Hl%`@u6DxhmNy= z3cpwe-~B^x7HMDMsVXx8bI)AWbh{V13ikM&t>C+c9$Y8NfCBi)90FUf0;#%EVAX>K zjb@WBe=qe&J(?9$y!yx)QQYdYMljIQLOX+PTy6t^)T$xBh2D%ymd?Dzi+ieew^{Bz z_<{l~ zO&GSzF6Ep`z?R>y~ z28s(u7*5Q5(h+Nb4*#VjA8n38NB3-XcSqc;RD0FI%2@dL%a6*TQg*@zXWxrl<*sG# z*492LZksxuZ@hq9ZYl|zgnO9FkdwRJrI?znW0Q(F4Zaor2j?o`k8&dCH0|DxKH`Cm zs_!zSh^p|oSyg^27vef9zHw0zTPE=9MKD1b(C7C_9ed}O>{xed$~xQ4WT8viTxvQPEyN{fjt8-ds_4y=*x2fR65y0CCx;p zzIR?7^fY$d@$E41qIM5`78Qr`;)MgxA7Ike{pHIS?G(%=h#`&p#1kn!oy*JJe|34> z#YHhLc^S07LTtpDL&AWLd785)4t|VXj~d-_?zL+oHXMvgt3e2|I1XN!M{mqjyB*$g zi@y&8zYlm@kpI3%Qh1%Gr;Dv;+@TjMe6F+tLr)Kxt9Mlmk_Pe~g7+?-){a}}lMJSg z*hkD~Oi;YsurqJ{+dJwv3J#iMQEd1^4%d>7DQc*mphJNP#bgV&-koP~V(+EVV7;MN zuck;4D2>lNr(`yhu_>>-|BN4Tx!-Y0R&8TAikj4N(Aco7_Fn22S?YfM_5V=y)&Wt5 z&HAuGBOMYV4U2%JbhC7>GzdsZmvl=>cZ<~0Eh&=H2uewZlyrB)cdzez&hLEx?dr1e z-1E#_bImm~y>T=;@uAL)9qaF?<%8HB3Vug|vw)+4PUo*QEAqd+HpANl z>Va5Jv#}fU@L-5vkFOb9+6Re6Fp~_ZEMLAG{EU8OpTa}0n2HMkCF1r(XcKJ{G}b{w z7V?#ST>Q@N?$Y1CbQMy?T<00VkTv`G^#y zGp}8)czUb*@r2CDK$c+Bc$gEo^_qgf*IR9;N4$Luc>9i+S3_Nh`;=X3aVCn{Vz{|} zV>Cy}Jn|Xmgu0tujq#&Qd!Z`#OYbt>uQZ`4g!K8^arm$E5@E7wG#at46=;+Q%cmR^ z!X)@Y3?730acH8V8%7IY49+5$oh_Ro@Crno2;jv+vK|YmrQ&9*T`)!JW(j<;ru={g!AqFYCuNDJmvKQ7bPX7yO$R&822jsnXjt*vI@7mT2?0% z|9b+s;I?IxY;O(*XEjK|vZhc-DN1QQBl*@yS4aNG`2RU50VD$vzK?F1U#0YKkVs=k zT9Z$@IS%L^WDLIfcbh>4S-9IsXYb_3g@#!Rk%M;McMJGYnO(P}E zq*a*lI%u**P4+XyUpIQ=2`0>0>q9W4QK$i2Kd}oua3ft*t)>0@%r@HZIFq;0!&&2d z>*u6HnWCM{F)5*>vmAgm-y~?C}bW&p2Zm7Q-H52+LQG#)FCIO{I>B*J9ayo` zdI#o^U&my2U`=|xR*w^0o~f39;41SJ8&!7KtZ1!CzE!XM5TFlugz z#Qjlp1$0hgm@UPh#%E>{yP0u53%N<9_N}IB?6`Dip51Qzz&tqdWG*3_ zEDlfQFnOC*yT71t?bnreX-o-Q`79?HOXny-*q87)T4%SGq3f>2eVk}ge_pH%Li978 z0BqiqindA1$6XY^pSYS|FV*TLE>abUjT#KXQwP?E}{7-ZmP1@~ljk3{0I4dwThai$CRdE7t( z`XQDuRjZ&u+!*8kjVi#%(Rd!lFq$8nt!j*jio+HAEVKltOuo_nLj+}r2<#rj%)5hx z&rTvAwWZ#EmG4)oR5)lTb*vnCuvQ+UTlg#XyXoal734M5*LpHKS0;^`x}tQU>KL>( zA)Ah8bwi5=yBxN67%&E-jtD)Oai0DQpUZH%v+nUmkqkYftA>YGX`DFEg(aioU8E?` zab-iZ>G09GH`yOhivExw&NsOJQw>v+Q|HtSMXfz`(LL+(H!+8fuau&y=EI&gh7Ij>A0& zR4b*CYd3_n&5AM@eP+h^zIoAe=BebCV<+JTBgt0%CQ{vP$ozvH^0OZNqMZ3QJvT~e zr%f^l*6#0zDMcJGoSqzry7*;D$ga;k$T^4gW6sG*M*eAB>TsEfn=NFmO_oUhKVnUAsE9V5S8V} z;p}jwh{BkTMaLTToY2{C^IyJVMXE}SKwiAsD8i<0ABZB*8|O6BESrt4c-$KyfL|P| z9gHuv-N%HkUQ3fGarwUEypvHwl}13GZGM)QVB|$2XNz?=1$U*UdNvVU6&f4uAb1vpHc6?*8a z*iPa-2xg!OPro+#%k*0;m4V~;ak`8%68GAUp;Hh9nVF}(9FQ|qyDn_v1rWHah?vpO z%5UgE$cQ+-)`u5IX<~FV;IV9Nsy7pe3?$%K33DwZ#&K7JAilo7_oOr~_jf*ge0(HU z)w1)~A%cfj@!p>-_qLRYt4QOd|9CVlpJF~;lDO&O`SMFgWnDZl^dxHi-T%Am#nh<} zww4?(+#A9Nl#*%KM)TMxG+t&@CICxf{&%Kq*is1=znzeH>}J_e=J{&~(sntE7AhC~ zE<%4ImzLsmeYG{fsbP2`5pZz`y?hZ#FQ9CElz*L!%@sI z?HQiZkg_x`YI|(dC+U1o>4>xca{JLhB*Nkuei=kN{w8LUI=mY_B>`+q$wb`-Cz75k z1^(*xOTAcHy?1f;^Ck_R`le2IV@o9qfA+nrJl4fep7ThZ(2-y;GHhs?GEF)V?{FXDYg2j!eWV;>ty#5IGqDOvl8nXfsmhzDl=0~6{PS$hh)jV149;5j9td~27M7^*U005Y`JvXiQHf8uf#irr zBH?T5erp`IG3$BMNxOL>28#?!9Ht+0x7N|P!QR!^QsH9`Yuye4!XX&o9aAV9qlC0%p*BczR{Z5cvh>nQzWmVQ%z7B7lIO@QI zm6_2`;V|HyqFKGmhvdxuw;}vf6Xb4TDdeMSG)E&Fi4b{okm<0E> zC`5%vlkHPvgQGEXXATi%tu+jXuv=U%DPI&ONx3&>h>doIjq%W{DTiafKO1#{`oAGSECiT^vx9>_I@A+^ zHBJz$;jqZeYrxH1lJ;BzUV}f^i?1D`~cgqJ4d|ib2zn_8#G@;Z73w~_}7ZaKnJ}0=?re8{fgTicR zdq^{r5C%nsK<0h*{!G;2N_*jmbcjT##qCu%VV~_VA3CP&Td`uDz%A_-hw46HANMC$ zMtH)K+$hcNo*uN4ney;Fq6F{DE3B~H@USbgB>7T!;D7N4{BCXc8lqlY+^1F>KTQx4 zD%7HAxENFk)@J*BQny&BZq=*;;Q=}yC;q!gb zu0VZmoq!9+z|WD-Xc!x~{u5bmMvz+lPP=o{(+`hP!-7{jM63zAB9jhcS{Yn3!CQ-_ zfNv&I@7fat(OvS_XCR*wY@01IO5sWYpwfIK6M(Nb{97zXGpHc-eGw3tohAiQmqUunys^YC~!s!4tbhl2S|K0VWNQBdO{+szpGX*As5Gc za&+5^)9iVRGGyqnd^s?wUFY~TI;*wF^%XsogAi-AZe7o`pAi$a_7T~5HUpQ#$&;UY zt;%Dm`0zx?XB_0CcaxFapUbriNWgx-TplYau8-dN(Yie#0?2$ku^c;`iCjpjlr=Vd zQ-0L29bhVlkJ+wtRF*$>RmoO~bctO=RHb@CawH{cnOhJ^HjJE$;;PXUq!}uK0+|^+ z;x~z-i@P}wp+B?N#)Q33E<-(+QRzPYovF+iR`4W$yTUGeLo5+;G!QJgEhW;B#Wpf6 zZ-5e$5e96EMrX9^pkc+B-k^#coHrC1;UF+de@^xxb%Z=X9~JexqhpAm5X3eHI(-p> zV-_O`D$YvAUA4y64Gv>jm|Ukc3n@cHhcv5nw*I8113wd`@4>|&bHucnBzQky2Nuz>}cQh$9<}lmV{bU>*1ZkWfb=5^8>${(au$_0r!5XN@lf3aVIx2{(`LeR0o$ zL;FtUKjdr3ZrWv2Hrt>j+&-z=OR9zf_gXIqC1T$Al?YoQe%l}E*Yzc^DH(2j3IC`V zq%+?j7r|jvazizXz5cC8qs1omSNF&NaB++0NFuFX0flaVLlOz-euhS#x%i5Pdi_h% z{!8+Vr{b~3bSch__4@dl5<2V&I`7Lj--1W${ua>`KzX=Bc;LZI)cx_KxmeQn zBUhG?N+LMPQBqHAXiyhvV&W-KyRy~p)!roz?ioe^M7@OutDZ6M*yR!oh#bR!eHtqb zuZt)|*(7*FjS==P@OK><8X#RK~uow{Nd9&9cG)Vt~)FRY7F#Td{Y+q z)$_SX%@e}8AuR{n5Sg}UpWe5p1^Rt)tXvgMHs~=-9@q$X@_`DV+CONBV-Ej5@8zbN z>q~D`p~cHI`nFO$nbWpDqcza$?Rw^J$KbR{N*s@pK#i@m>*I;$%(XA)$JddcgR3zJ zE{}=3>aluolG)9lKewI-8Ike)cIO|ChYElX4bKm&76u;@ zvIdv_10yC((Y_3)73XmIhwliJT))j1$0B3T2VXfKGQ3UvE_}{tF$WjjYY^s~k(phL zr6;Jj{q$G{RnYd8baX~cG1n@A-TA(DWIxekm0#nVB+|&cH+sB3rRQ~5J1q+OOwM{^ zvPgJ5u@L~o=W2{(s_+-3i=$uTy&s{CYchIJ{D;Yifdg+(cp^F8qYv%E#}|(!>G0?kuifHNKbc}YgLNUrzk}6 z7CIKew5AH=c>hCf-Vq9z&A3GgKKcGf5)9f3(|Y5|AJzJrf+mtS>V#@h;(DS*VBU0gD--6U9UQ6T#}ig^kbO~oM$jpr{g0gyz7h@L+lU1* zVUOIaal0>ij?VAHL(X{?*JFl4i5NMm|5``iOW}}Zv^OBz89h=IqjoqrARV(AmShS) zx6+W$aUW^!OJO88mNWWGDe4oZq=&uORXkuNil6&NsO2I0a%bC45KA{bc%km>gx3M*EiD4dsB>I|SiI{#~i`C0Xw z#JEGZg_SS3=-aQgcTN9KWu$yU#TDTl2L5r$eAPq<&z6bsY`$1ij}fMZc)~J}`X7?n z*xRJV(-&#qXAT;o$iGEpG^*Gm=!6O2ku>_nrH@qdn^y-t12Vfcj;GGtC5AeHG;2El zmhJny)k-5h+2vqA{?Lja9t_E}Z(iEmWWA}XQHTjbUoLHR>;dpezwfZ{+TLBGAsHPi z@<_DRC+NEF^kVg%!f`o2z-NLXZlC5d9NdXttPq}T`UqTH1Y7OQzgiRs=wOHa8@t?( zbt8;cTFfEk$~968u|g1)5d}y%dOp@bL5_#{rRmabdUCcgsZL`2R~yN>mU}b+u11>0 zu_7}Y#ZKD1T%U5zn&EnQlJa{zFZh*0Szn}?L&u|lr*7OEo?p*Q+WkC9@&(l6u>bKH zaw(=7-3O}nj~tF6XEQVsp%Thgm8Y9^lB1S=Ou_qCZ2R7#RCOjgb-H-v-Zv+t2;T2> z0v|8X2(HH~j0Da-YkSX`CO`iRz^R%+Q>NuE-@z zfZgUe`%xDto5GM}C6j&$TJXeqR%^%6Kiqpj^uIU*Y-r1e;Y3} zPeq6qoC+)uoF2SK;8=sx|A6Xkv;%e7ZF&m>;{x+o~($@V_?GWPKZqJ)5Q7^Y?5hn1L7Sg6o6SyH1X_^f+xwKo<=xOMW+Cc zWATRsVJG=^;J#$DJ55NWQszt1(U~7O!X$gY>VRiTr8zh+BO>8=mpQX~Hcru(Jg&(~ z-p^M)?XNuFTcTtzq(WmE4~0J)ksusr8bnI}p7rwY#qV33GYLl-23&Ns=HuqT6rAXA zX1V`{HS~&bHsFl?MT5all&F6VK(}dd5GtKmwzJic6(MUXNQ(^xPDrC(4OXj~fyK2X zud*XH@Z(We>u_$>kO%-C4aUksH6QDX4D223_?&MI0)`0$Bbet=#IjcTny^FPY8fQH zDBox|d)W&|ZYq<*p56>?&v1&CCLco777=>1J;~N3M@eG#_rvjPb%;Kcw4(L8`CRJL z&g$5EC^}4bN-~lu?!kwk2Osgn{AKwhi=j*24%76Qo@E-La3Z9*p#?+3T;8~!^KCLJ z24Vos1hbmJ{CW0;LX-7FP=2BXK||s5CIHq!do`=GrC$-p>NI)a%$z@`mj~QrC#VQO zMd-5FeA4kW>VK%go<(!`%so&wrBw#k8x%VcY~KORuVZ%qK9%p!mL#-)>+IE%BowNM z-CUqAdTzF+Mh8O*iqmT{3xcQ$%|vxUw-WFXb*fr z86v+abF-b|0#8_EfFUHC$R&ex3sGH=vB>ayJs^U)S+NA=r61lsLb$3aaj$iI|+uY4iL8w z3imqvT&2kr@rxQ`O2~1@c>~ep!#P@Y;pU&rXu_$oorD2d+@nh21sad)uD)0itZ?EV zfm<5#VQPk_SaVK(0ULZ>uZ^9>#tBS|ff4_Yj}-yV}us)3_6U zjgv{E70m*P6-AX#Vadj@?)re+s+vd|{>*9jN`J0-H`;!oH6kGuljvud<}WL1gJwQy z)_Bo%wt0LL!&cA7vx=Lsg65i_KjYaqCw`J=ZXlpGpZdl$IGRMbTpX>E4`#MSM`-m$ zlXFhxN&9>AtCm0?n)at^)&XUc3ZK0&8vc9deJVNq#JgrSV+LIf+)~ z{7CU^{V^Igr7&u^Sk2orv^)iJ_xGHja}4Z)?WVQd1w~>Uo=vsR37(d}hEh|rGesgK z{YWW>4!2rs2WN-fGgw}WuKRe;WxayV)Lw?!4(_DENp0dw}A<$ zM*nJ;nGzS3N=oUOF(xQK9ZtVj+p*NlvsHD$#1RbYqUQZRrm<@U-WT2fc#XV0H}c(A ztp6#N6fRl8H}L&jD5G0Kl#5)bqe3MfUq@e%M`+p*^7Ks#lM|P~NxQ!!Q;$mlY87M! z+%}Uc4N`b-1}U@|Tb-DEN1F;$c>Blfn2|)(|1gxhm6yDCCbTAkZ^$@!+;2Qv?oMh8 zv78Qhckk)ZCVBOS2rW3Y{{8*30bNQfFH=~MYVeC!YTdf(_VPfZX7_c_El+6{NA}tw zl|4no*6NM$USwX_Y9M7IzieM(q4VQrk8RqL+JM4X?^Z%DyxZq&l17_?*D7T?LdZ(n z8W9$5?!Lg-;fRVcG^cw_!R!$+)xjzNmaQw{^3@ z8WC|Q3{}K`Z#rM3;<~%JeB7)2tefKNY{RPOV?fRZXOs&+t1*)qmmf!{4yjB4?w3C& za}B?G!jq=T?ne#e5DIO#hPb{$zDH=-Iu!X{XdbG0s-SI+@WQRw*ak>io=^&skaC%J zjI=OTncu&R#Wm~F*6I5U_KpH_BVuqMsW_A_ECC|vcYU{aD`>M&Cw0{_PXVOD;y~`b zw6PdkhMyq6%1kRAnJR6o8q~JUTNwbQtoUjl?)%MYRjS=PIR6kk8}--8Z*n%3%|E@C zunbXq@lD?l)=Uwv0OrY;a_6)a0XNjd;ML-=FqxB$9=~H=H{nwsrxqtnoacX1_Cjn! z28vDK-&_V<`?3ljfT7>C^9dM{sj^Wy(>Pa7Rs-#63$eJX)5l=mmRG5ECs?~hYaTrp zU{ux79mk%tcaFR3o#=ORL2cJ)fcoopVpc)m@5`o>GziVS^*|t>e)~bcN zGs$I2pNh?6C{u`u^5M798Tin)f2Y@YN%-mu)TQIS3>@XpA}_Co|Ktf>^r$zf0~SKf)=|rS2CfEPma0e%jz5 z*BX{>f3ZNnGE!hhacdPDn`72QJykbJFPr{aJOCa4du)S5dhN0OJUh9I^$!VhPq7!4 zx|bn$Yf2@#UhD6QV3kdSo#NpXAuMT&@B8G4svxKB9&UaYPn2}A67A@IFh*>~P`6E1 z-jJ{M6HZvt97^3&|2`P%w-q>@>GEgAQIX+=~$ z3;}J~*=Sbht>$ zFYry$UHPZUj-y}`EDTYJ4z`B7-_4~HyAlije&na6&?@ij+fVHbQOgW%K;MEZjnwMn zfqGtg)Hx7_Z~igL_LTio*e{Soe@Ai#8IM#-@4me5NY8vtQ_vS(Qpsi95SmxxZRPSr ztRD_LJ*l+L%0?w&t$co~D4tju@OrhN$KlS|d9fl8!wO}=&n?dSq|qaRjYg*TgI1Tf zAu+N^<&nAtKihvPz*@o8!N(tpMf1nM-4(Kg+K-jJLD}~a#mGu2bM7e@+=J_TOgDH7 zyhzSLZNv|KVOtyCtA+C+=+RYJ*F&Cf%q8Q&N2^__?elRm%PW@?dicdQ9sO8>W3K(s zMBL!#cO}|ww91AJFK(zgFr=0spV^+mdqblKChbke5-(q*%<)$*k1j=BEZpBQUg?$M zuFjtC%cd3=9mE;bdQHvUDxB?LsCN!b9<@KYbTaP+h48%2C-@OQ@~{uGk#MCe2}0Xi zs_>u3S_w0Kth+b@?&5w*kp7{$AChsr<~(wL_hT?e{U5i4D8Zy4K#uSTh^%E&Ch79B z*vhl;;zZvs3t4e*GZct4yYO##@&OYENdSU!?TFwW>O{KpenjVL0hXa{FoQhp5(KzoPf7RsJ;k;$6xOQ~I31V47M9`7~$HJhWf zPMqy|3xy~DvUZb2W&eTt0J2MGx+(l6oesM%YJ31Rxcqn{uNHf5OYVw#y>tn(YNMUM zFccr^&R`6}o@UYrz}z%a9XFr*#Q1k!FK#&U3*`Eu;;-K{S=2c{(Dck;@a$`|T~CJF zZC#Kaq}+*UBE16A=|_j3_{}QBIl{kf7mGekV!RV3zOT@ISA@PQul3>g>&tW1E!>&g zx5MsYW)5qUdxanq&yh?Y+~6u|60fN>oTzZ%f!NWs_ceDrazaRukiJ2Pte2iC;!4ZB9l1<{V%J*(m)Q7}gbnUvzPT}of# zjqxLDT6W8s_mOE|RG+{@8R&M{c`bvfuIe|8*gRF`(p_!SV#qWUtV@TRf4#N&<0@O8 zYe7cJl}7{<8SDQLIU6L;Dpj*=rfmYzn&KHdrvZ_h=(4uWt~ zqU-;0zf_%gOVgw^B-r^<&GSMQ2e+VKd*ZEViO_yEHet6E$c5@uX_g?5iKxRv24>Dzd;| zhfN7JHZ7D{@P)JbB1DDU{=7qM%fD(c;c6&Ny0WQ#6DJSsfbJ2HhyT&mfr4%@3;#Y} zsOG%$eI^(8W2w*DUr+2aLb0iRRDG`=F-E3xtGu$`FghKr(~UqqNm8cFG7#I*u1bWv z7w*$|^mD5tBMC%3M8;26XHg?8<=uUqE@$BY^pP-ZP@xsDo2tjL^^8=tCFvil(8MN; z3wjOm1`9hNDkz%BD}7;;Eg%^-wPV0*h!&mb3UE!VU)AWE)*Lhj`xmlxM6$m$iRh=1fh=MqN6=8nMaa6}CTI-az?{SKIq7@i>5 zb^lh~A;(_HF!a4jc=G5MGyRN1I)g9@W}dlxG_o1)FZ-$|8*_T)qavx5nxFb&KbQ<9 zOOE_HfQGw#^+om)KQc|1mnDZ^}yp5w=u|YuHK1dF%dI5&oET zKoFM<+h!=KEYfJ1lBBzPt7eFrsJyN}7P^%ti%$7U3@9|1)ZU&Bm{$61E0er(er7gq zy60K)@q`ofI(JnQMVwfz8V6S=9qb!7wqd2#P?}nQGz{cwE50=irQ8jsNI%<}i@7@6 zC7*G%M8|(;K~SFZbx6;as6gpcRL^Pp)>zt$)T5zcKFMq0+PjffRXEv5-5Zf|ukU|u zx@$PB@0`c6@DG6uQj=A!V1MyB4Gs3H8~=U^&GFy-vT=Gq!p+BjkyNBoM8CK{_+B`9 zbWC;TK}KuPF-+Nifyf)>St#+rtb^Cip!rtO$9x5mvOPqo`z$OS5VfQ}c`BP=hzvb- zKZRVVF)cdmZ>Ks9v&?EENVmiSf+79Mu?vQ6e9>-yzDiLm+!2Qouzj;b1;SwlT$)F= zf-zkH`FEw>wdg5`Vw~fQxJzc#N#I&B8g(_NbwW+!fxb-EXw)zlHgMPAdRswa0Fr_o zhs@GX@Ux%%W^ts#%{8_wHi>M^S*8ebc&||ydTnPic8IwiDVBmAHGVjA>Bk7Aj_YcR z=#k6msagDOF3O@?kKQSRdIg6f!J_UN)T*RqKJ&Tgob)eQ#Ejo7N@vbtFV`-5?WqiF zhZDZ-*m8*3ckce`G@X$6mPEIXvS6^) z>XNS3MpKQ|IvAoZ_cMi!ECS?ua*S(tA+)`Na-!Mi>enh6Q#g;W`*8S1ESs`!TdCy8 zE=^w?UH5dC!zQ{dtd?(Cvx5fU1Jdbjc2{x91ToXbo ze&Y_`VaGOH;7EBWWQu4C zFe8PpZqK0u71bNX()puPRnm8Rd9Lj7Ot6-uK>@GEjA1-zuil;$igTCjB77k zPL%NiAOT^&KkjND455tViGCgOG90rVSCA0`l9J(UAg>AXF{4D2e8_gutF!4HZ#}e!my9V%HK<@n!`m5|qzjHbVq zKO`&ZVYan-A4(2N=yX5R;SyY2tXQF`oFl+RCSW5ZmB6Dp*?)ybG3z1)R?v2b0!Wc_ zKWxz8eHstJ+2egSFM#|fiwX$-O(1cxZ_mb%mor*JgguW`!y(l3q8OpiB%9^>;80Ug zgA01NneUq+O+t_UD4s!yLCXKUV*|aj3cOoBsomsrS}<1AYI^Qe9gDPY_%=Mv>At7K z?8uE+cUyk7bYl*c!(5ak^>yKv+cEi!%BdA^7nR%tsS$I;#(FR$ZVQ?=@>G4;AVbKf zIW?t=*{Oh4?2?lR`j-?(1r$VPh03PCygnURUDPq{e_NWYWcK9p>FDiq-Fu6BBBlft zqTiqS+?55W*b=rXT!+-?ee3|Q4V$&}&V)xVw;^|}_FOgz1hCiT5}AU`3pwKZOLl(; zx`XXrJ#TMT(fhY4r4N@Gv9HMO9p-cHC#rDi8)_RU5o9GpHX1DXCpo>(y@iG4vB24# z<4kx(3uEX$_1)c_fbD6BRTun6*!zn=%O`<-rh)lPMuD?$wJF^Im zYVoHA4j&iO+2UcT&f;rC?)GFuW;}GT209=scIjqkpySMm+ z)Vi(`ojY!hq5K_6(Pw2&)7W;+k(?ZX%bp2mK1;F7?7}zO6^KV$UCXzXjS~vvRBu*E z-^~lR`NUK5(M4Hp+||>a#c^vHt|&oBRtd5RF!Sn4o|j?9swuR&+(hG*ZusPJ0t#(J zV)2|Nk&lq0AX@kr38vZ`i!!GBTTqmAjej(zlowY9KSL7m6ZG%|zg-6+IAir3Z~pE#S0lO-Z#jQ9j!G&F8G3#n-}SG}#L3%;KJ3z6 z>q{nOir@5YL*ruXnEvwZI;BU{`{>P%AO5;|-4Gg(;I=nnGm_ zNq+KsU^26TI;_=BVH;n@^TSJ@8Fh$ZV`y}dwBOIH*MGifgg+ZoyAx@1ymSUq`Arqa zj9XK172*-9C^{Y4)+Y?OACU$P_@clRr%=+3r6Yn-$x}jB@$@~>2FCeHw3{eHW+=bQ z8j`MCywoXO2_I-cS9Zp&mh=n3p?LLRaFz$7CW%>{$e8HGhG?o`mA4s7#(AathM_aI z`$#xBLrliUH6>lk^uWKjvZ1fpBZ?;dvPERgTQEFvnHBcFLr&c)MdGnb!gGIb_ty=K z`kPj#wp!(HY13RP%4PMA_!QC^)p@5T8G|0k7(@pM8SA^2-|sdTE8^ighM}B!_h`<$ zQ<9`F{(xb|;XBAX;{y1Y!>?X*x(RFKGI0K<66FNN!G{lfzL2}Wl5C_T6fF3o^vm8t z^tQ%91J~*H<4HWWYyu8TI;Wk$r&o4NSE^kJ)fx i_LkF&KDp6Cdt;_a>dFJl*yy zca6F2``Ti6+?;O7MO?o)PtE8qE$pm+O{5ht>o*`rPniDn$~+)ZN*on2 zm7C!98g;*I|D94_;6Llce<&&{$~0r_-7ayz_~*-mTDuj4+D*E9yW7iS^UZ9%`F$26 z4#rt;aC=+^6hV9v6|J50?z5J8L;>U zDMMk=@N<#ZNWm5(i`qpL#$ECE-_ds3`2h%*kQZZqHq~rb;QT)EhSpMc*W%hbm${5>f7y~x*wIaq0b2Y)KSV^!A z6ynPVX5)m@DX>Q5Rv6jZFPM%tO$d5Ux&YzhG808qJ7V?`d*efxi5V=sUR2m3vGlFa zoZo@Edcp(qfwRtyF`qJsRsv1x&UB-gAoSPo$I6cJ#OedO_jMA9^v5!}CbKA3qV!Hb zS09y(C3g!F8m%2*a z%L{6RF7Guybxj+^B*mwc->}O^X&xd#skx=Z`t#=MLtdrzLwDT%C(153t3g=P=_w6^Jgup77+c(2+u5veP znN;Eun+A&5BY*1LP@f4^gHg^=YLPcJ@0l2s$Qi?x$a#9l(2weX$eeB`2S~Auf1tWD znQXQ=mNr^J5wuD+*dYQ3A$)Amh{awW&3Mn3ou{z=&)7}-yb7VX`A_I&yC9GTwkVfm z(M^7}o5o&|Rvc9>Ut(C465j>Z z=)C&q(~XAVU*^Q}Jn0i10Y7B0vyEY^?kDjto#-tMt8htFJS@l>AzYAtI*pKJ zvdAvB-M6lE9;0`_qa=ywl^3c4zyN zm{T@9WIZQ}15SRbX&0CTESy!z$l0+)=Tpp z)3bPVZGQib{PdL>7r8}x`oesI11-$?bmSaILuMonV*bD#D=GHY%yq@gjeMUtLi>1_>t%eAy%^>si*$5!N^ZF;bg=UcRkLC~Y-RK*5268K#u^P> zwE9%=o_S&;l%Vh>^KUqySuLi^7(l5DO$Jpj5KdOdWsU$ZYLE6?_LjPDC5^Gu6~|*C za>?u&F;NI2whjS`ttv$gg%RansSogd!iupcBKtlg%|=*dx^FM2dA5%}wE#5NPZ2pDN(a9PXBN#^2>U3YIzvr3ntF zuF)sXZTn{J@j5S_yLhySr#5ZYO~3n@dJ40Q-Oiu)s@xz|d{sK$9-woSV?0xpNXc&p znXrxD_b)SO6>oe>wV*IEXm2GPSzdT2^syh*K-czAC66~J(>@u336qNxPE3u;&OQV* zWEfIXIeGIcbQ086sQJY!=CY6SbZIK@m)R)#liM0tMBw%5Pv>IUjc9J|#QOmWShMi! zbicC~r%!JTc9Fy($w2K4?+D0u%D*=Ci@4HH$H`VUxiruV;mP25-=_^*_+~EnOoU_LhFCjshuso%l0z~OpZJ&wI^*G73t37lO#5}b>5Ax}9? z%UM2_z4?Z3J5!7P!(k5y*nk1N^5-<`Uj$3Ti}Xr`HXgVtFq~U&AN(3Zt->dkoXeZ= zau1-dOan3yZknEO`G70OyN z1qz;@YRMoo5;Rb`PxW+!qLmp=(tB^PQFgbrc&vqGp;9?lHNBJBvN>~C`eR4gOI#dY zcVw_k5swE~r}3S6mQv5yoI?H8_M60jNesl;+$o2?2YO)jvOf>)o4rr;#Yz%?s20BCAB(&DP^w#;=lpxsPyEUO z`Co4T{dUH4b0C^`xmyKwmPI_5DR_71Ke;^=#1NQe-K8$T3twCx0g}BvK54Mymj)(d zjz=Kb#2)8$FE~j$Iz%H*Ly@ll-3Wwl8v%ln*`jXz%#iY5ms z^Gw8ozeyyb#>|bBxk$QSH)C;19howzelylkuTUj2Q%KSZ#=eSE4|u};Iwz_qhX_m{ zn|==V(159QJ9%;1b#}oPYC(`>ZI!@;O^r|Z0jW)tCk33^+^^a+H*$z{H^^r|P`Y}u z^|GYyy4b9VfzPY`;Q83s9M&uW?}t2_To$EI*6Qwp-?iy=h?e(l%^jAG-qv%EF1Z}J z{5FplN$(zb8Wgf_ZTf5H0lxYzsCnufo8nKZBg&$c({=|}W%==-?pBSzgGzuV`iRo- zS65}$ejJUD_~!5e{yQZh>pxaco^vQn9h{v>SDXI$S>5{|eAZ4qTy3UMX4v*TdU|Kk zli&MpqFTzVZxY-Yqsg zP42v3*Xojcjb23nLh8nOn2i}CTtF~k9}Mpn9QV)KUSGWPqfr@_N$FcI&YNYl+nw6A=8 zz3{3`dPm*n-|CPjt=*LifB9O+F%|Qo@aF|;ZVxN&?u;lO2n^@X&Eu$io2hufhG-6= za?|lf{f%K4=h$ya;jig27JGhqmAsX~gQs@J*xW0JO87u%en#>$=l^bWEj?Ci;fWL5 zJovLJoAolO{?jqSm2fUg~L0CY83Z~TJ5?Ln``y`>B zi^`7>9U(!rs2qD%e}CNffDk}%n$$dc3tIZp1>2%=r999KHYbcoycJt_FK~#(bPL=h#I&atvTf~axrB0e|>dVZ4SQN0)=dvExCFjcZd#RJ#sq_UO*rE}GqDroG>+5RKj zybkt4pdU@%X}15MpM=7b;ia$UvhkecHqS~@%`T&7Y5y{@P`==G+k11eH$ThbC6tO# z>mCR`YHe+mP2;4Oof7$Cucw$XeC{U6GAiOc_Utec_A`}ZX>~QYD~v#|>m~U=k5592 zz&>CBm<;zqb1fE7Wk$JRIo`6}Q#LpmM86>C^?2MBPI=*_6&iIb{upE(U$j}E51U&m zI**gQ8|9O|f8jFvPJPt64isVBc|pLQ{=G5EYos87g-R}!N+fem5E2}5=hKyQe|L?; zk2w~Ie`q|h5IEfArLYtO+)bOnlTH-#OH@@(ZIJ7$m%f&7++2PD)G3M^5vS>hf*j~lx>HLR~{jJy3(TP zT+2a>>K{hst;xp>d?f9l%ZTp>&qNPsnF&9eKsj|^vFkt z8)pj82x6tW!mMJ|T*Bv~9&{ya8IAsgKh#k4_}=ccd*AXWR)52T5el9t$4OT#G{2;H z>56SWn1O-ML8}!#H`TIA^`CtAQ8(K5=g)Yzej{}SPu5m?qL|^Gs=53Ugie#cvz<_0 zM4^kbR8c-re45ukbu-4%Ab|rU;63GA%SReI4eZ{-5EuObz8ozWP?L0p;;B{gSaAG9 z{mBRWtxe=56XjH&t>>#Lth6dos}Xa5{b{gk*C>yliwZWTYHZ; zU2PVao}NB^HuY~X$#+73po=mA_6;9Ms!7i?@2yVTva6~m|GJm+HmsoI4_Fw)?pb>% z>A}jwL=HR=l{|rivvU{NCa9Y829N1#jWeS9VrxALb#ekT{ZOq=CX(;SACowv3*%q9 z4bu*NB-Gf3XV}&(6+lO7l&*G{(~EJ=($s}?C;Mn9)9bs4%&YP9A1l{y9ok&2rnNu9 zlM>5tN$$3{bjxlyE#fxH z@k|<97e5pZKvVxn47?ANU2&a=%ZOH^N(*ygxBWEs8&b@C)Ky4f3=qq0+7~qap&Z8u zg=7aMKDMpC=)hZb5>`g3P>I0WQ|cv|07^CBc{4$$nZ^YXuky3acOiRGtP401-Q98Ka;tlv?>gUmogc41 zmuo#dbIcLoJ@ZZJI(Hbc6!M@ zD(ugXn?6JI7bgH}v-Rs!VufL(+8;fmufM3KlEOgxE4GZX7X>g;JkM{#} z_7kik(SIG`LBn=F-=_lCYs26~bLXiMCyc=hjT?Py__`H;%lRzmo{PHs126&#gUtj3 zZ%oUTxg3fRM`)jdx#1y1R1aty99k?#@>S;2M1-7$o7pSsnqN1+g*#{<`tZbj{x^q| zR*luRcf=^*QY1f^f)#C`*x?Z&|AN)PwOaWV{# z?RuGMS|?$FTKP|}yQ^e+pxi@Je8m;tn{Kq+j}ca`5QaFfiy%Rzb~d?`8)I{j9r64xi>>lZnl+Ce!P zhv>VcgG9Hf@cpc?JTcI``MvKKjU0mPestu0_1(cRhGRpPMg!#*Er8VyoH+bBRjkOUT-*A$*c;++1RpW z4+GWyAcuHA(7HV|4nBy)fc|8A9v_U>$C1|>+kusAGadhmul<4?*CDdwh4>L|J{o#k zd13;qzWRe9sZ%ownN<`>ua3fEtBtN4vS{xtX2WMqj)ZvO%BwCgVQ4Z)GLFqCEiTJ3 zv^tL4s8}>MNx&oIa8x#k3&);pnr>c!V?slTSo;o~s9;)|k9$s2UtAoTjQjLqx97u!0w^5!c{9)&nPhPRat!l6?F8zHJEq;<)A&?>tTfVo){u_P?J9r zmDz{)$<)pn&%iw07N)AMtgKA2oGi(#wkHLmlcQ9I2XnE*pf@oVFA}3mzELH`|El@j ze4@dtVYn6AS^5+v7@OzK5`1?wBi;6BjxGWJmo?4aa>LH8HhgEH=%lR>0@M%eA&NOP zH_-DcF+4e_5Zwj=Zzmg@=UIjwQm1K&G&k*QsIOqLMH^4bYu*m48abHbr1OAA;cook zTnCxe*(*%bku>2KU#jzzMekBQfP1h$dqAVsblJ>>%$YRD?+5DK-|Qg)@K3*!oGNeS zNe0>-pCc&e(*!F7E`CQ%Fi2oc+@v!uGYl>uPtb4LUUa_LL}xS3O*`eUw0O)A!;%y8 zSR5i~x*axqh#v1*ciVj2<;`8&i=SpnGc=K*5Gw6-n%hhr@3lIkLd0grWnA2E#t_ei z5|T#4@HO@~B$6E;Mo9mvltMx;zm&LYI%*wv>5HdgPLt*r^I(#7xt^xP2%oHc`4lX~{mhaqhL>>G^ht+_}0^HPG&SLiFwKV^mIh&E^7-wwumu zIJ7Ih^$&Qm`7J^%hDG~>%*u)zA~1qN_J~Z8At^h8ZU*yp(MxFe#tiP@Tl7zLZ?;G_ zIrATHo;>JRb|*3xYG$HI_HK-2;jU{w{)}V$0V6(k;nGAd(D3nHSQVMn`&}!J zB+a|GyuCYS-B1)`I837-W@Txxz(h=0C-7;pUcg^BG_=!UUNmSp zR&COF8j_Zp)bHKGBgk^J#TL%%8yWe6drE`8A-pDi4F@#=?|ZO1)o+`i(^JisCUlAT zDEIl*oW{c0<5DFac}F0))_Q`*KfGD@XG?gKq7|r05`A(udXdo#qw? zxnMd6mV4bUl`9kJ!)Lh1whqAxrjHPz1xYN34!HmB6lDX(QuudLTJdS8%NjJ0NQ;ni zid9uJM9ZY;*OLv0cWNwNE#mg;ReIliLRt=u4If4TX>WVk^Bcga12X#K0`-ewpPV|^ z?~ExXKY+9mfxst zb7ylRm~K2>|{EzM3x1(5sZ(!)XmCWTHaJ?`bq(_fvS-`dOeJ(_EDiPH!HQ z$LS!m(zBYtDy`@$2#P-DV7Ei?_=qVI>Noby6 zUUgvz%@bf@!;|Y<1G|ojjK`@)6LRon4A1ylB1A@CeEEl*!-eL~xTZ+~$k$Eq>lJIX zUZX85xv{M(ABl{+D>phLwZMHD!V7~#aB-lB-j8n%Ce zzjl9i01(f7nFF7xsTp71@35RKcG@yf!86?Tz2FNoLs?c^9ClGDmfqXFi4eAd!F#NZ z2W~YRKSqncp}i^4Eip83usmVlWGxza2~H#+k2vnEa$+wUckJdH+K%;N@RUtUE}yu( z>ivlPQ|g5nM#q=)M;~IISF)L3+m1RGQ$H#?otF<}zUf!!(xw7Em5;xi_XTrRqw8F~ z6B5^t6oLcu%n)w2FgHBU`$p0xf7Kp9n$6MlPcO(lsqA0Ov9?TJ5X$KDz#KnaWc;XT}~x7`?};nCQsD;9;%jc(=1Ay+InW2Tq4S zy9CFb0_kBJ7OpJwI4-=N8L5#x9$qO8q)DhC7dzte^?!nso~Kh2LzAxV#{|unQ{)r4 z)Pb(w8%i@n&$~6T^Aj_heZwn zRGxOJQpdQU7Ga8Jv?4Y*cy@lyYtFs?0i0RctjSZNb)4nrR@n-4>AMuPJ-v4L-mm`p z=jMi~azn|BQs6b&#;Q7a$Wzfq6M4%uaWa;XW3c=SsGL#}!32cJ01`PotFMMtX=3N8 zZ#$D&_?Z)@D1$)R%~$@S!7UkelY1vu&g}5!a3fSq;8h7OH?%>97EGl)hph;{Lz>PW zju8n`MreLT!PN}~tk9nLZ#AdxD^SLW#e4R?PSMo@@2i7W}RS5jLB^JPp97JzfQ`QUhhW^7t|)WKGoYuzXSZpJFMFnQmd#XkGOM#{#c zz6;Z_!dU(+qKGypOd*~Fx#c~kTF-CC;@1eSC}0JHX0>Y^<Zk}`@-U>sq;d%Y!H?t|J|?Y2|D#n`;&X9I9bfh za*BA-k?++u69`vy+;j$0J~L?&3Dz=7VQ!fhB^S#CQT+J2#;^?8IT@MbScenQ7X`e8fUxzP#Lc?CEh{AlKq zZ9zKn1prNs(hl1Fy{xTP&j9GdJm1Ey(%53-GXu-$TNjsxA8&GAN3+EVIo<>F2uHHl zphT7&Wg3)*N>h8cW&-Pl0W-jzv_9ET+Vp;pzicA}TsTOrW^hq)RWFE`5`L_ZFjsff zloD}cd+a=Tg*X!Khfkh3Bq91#wy2G{Q0*JE|ugSik9 zv$`L|_oGHj?|L*XvETP@WUaRf@EQ^>hH~TP^zzqkOt(6Z=Cd@{mP5duNE>h2odg|1 zi0ON^I8aLoJF%CuH9#M@o#`1|DEbRFE-%|N+z&a>LVYG%Su!Z17eGfh0U*sqHVxEvzJMA&QIDZkt z^jUJv&AE@DKZd$yE%dk zB8f`QIp_t24uk+@i10wl3ezF#nHndB<6u%cE>)&Ptk)4QO+P8@B`tN4U!29ln^jY} z=Dn5j2(d&5^N{RrE>G^L4YBXswtVykRD-hZ)trKm2t)cW8m*qxd%1-_%r0r6wRn_% zQwbec(1Uxvf51L7o7}u}Yb4-yKtgOaEJLSi9N_y<2m((NldLknlsm3Fj9FQ6us>u! zF_|eHAyyT^Y$cQUViz-cG4+_mY*?Z*w&Pdv!7RKJRubt=-OatTndD~%9g$6Q{fHXd z?9@_dyneN;^K-5Z9XtG(wp-;j=fwe)YrRPb;241@I65DKUiwV%gF%vjn}7JHI9iRv zhn-PWR)K5BU>t35tj*$Xo%H$T34ah?ufISQITj#wM>`afZ)|S@NWo-#+Qi-0bOrKO zXq|om^Ly8Hti#c{PW$H@vI5Zs?BLR*qMj&<&pUSma~|)cAsqVmZl7Tydk>1UP#w?Z zzI!*Ei$skS6iBVYG=UGvd5b3@A|e_jgY6~ax>x5Yvx7T=Ad z9#-=`$w_q|9o8`SC4{_#ZAZYt!HHr~ul{gE*xxL?@YsCpo9`6oR%80R_Xntv13@f{ zuIKCChwQ$&-8n>Ri>s@d?u%-i=gw*>p6wCb4~9d6gH=>{8w&G;9-s_}CDH5T$Ypxc zQu@FVGAH?}`~PfexjLMm>4|!rb#0j{usK$cyxUME42~Vf7V7%!omg}aIDLs$F_1}< zEFGg?hddR}oXn1zy^!0RqqekP+qL51fb6-UW_n?WcwD=_1gD3S1f{@s_}3URc5V|vBq>LSX^k`3HLJ&F%WONV=Nv{`6p*nL@>!i4$R z72%ygGNb2+)mx*_Z)46yaUz>H6KW^ljA(`t_~`xOlv{P)K7t81~;ad4FO5 zL#g`NxFeaMgD!evAm*uU`aJ|oX%Rn#OUFHWIQjubn5g6Wz$V96Jc{6P+6ZO7^ymSJ ztY+LaG&II;1qHlE2&k7k19y}gcVCGmST{IISW#X=-{9RSav){*C*$DdN{n3r1BahK z-+@pSZfZc_S4_XP~fM7+r3!liBo z`kSYo#~-z?e3tV_q$MN_POqc8H|a^ESV;GK%-L(hVDX9|-ltXx`XgF!L#0|Z+Srv2 z25{736irRv8D@g&;u+64ViQd7L!=bAcP38mJmyA>`em-r($@RL^cy7so39q5YLVtn zT5jZ7M7PPZLBB;>rbC@(3$1KZ4&FVV6)T~e`} zsKrgVo%FTfwl=BY)l~r2RwZIE;6txbOJ5tM)`in8d!;k!RUk>j{s5*1SoTX1HE_q6 z4kiUKyI=dHe*@bhRUZUy1?cgftG^z+yx)rrEIdbKJssg$pa*pWlDa#U?F;MJ!nx)< zN3vGHfZA>xqR)7N+ZMmAf2n;mop}#|=~-icKSo=SYg&*KFNd`{>Oh565F!8fk`(NW zw<^~f6&8D};6MfTxXnzP(w)e@?3AK=r8JBdq3xSDQlAyuqE#H~hDuyKE=+Vn&7u!{kI|FXF)pQv^V{pov?Pac0X z4lJq@!TUb9Bh`MFF%Pd>bInwWb|sCCDA>~=Ah*nfjd?EXmhO3OgEQ}uc}ul)b7SQ~ zMeMJ&GAU(;=&FY*Y#Tc6>CvT;ksEx?F~77JDku>yc%ZO|6f9r=s5Ujw;Nng*qpZjJ zINskH@2L2Wv9`&-K1I%)d(PYPp8x(4_=5f$*s}sF z>7oXfZL;9hcjH9CTV9U*y_7N~DNhg~OH0%XZf2kH=#{?Gpx_tA%&vVHSNg4Jz#*sy ziYQCmv;J}+e_F2HW^H@+O`l58g!{1wj6ETEJva8_iGc^c^GSXl?-jZOx?`XC7thmA*Dm3bQL#?oPF&Cdf9oFs+(WR_retM>i4A9#G87~GBB70SjQuTXC4(jc4s&?O>EUc|Kr}@!GcS5upX5f<|)8z z;RFU(``b2Ts6=$DY@vly&y8`4ga!Ql?Mo4qnW_@})B)?3{$h9(=Q@i>24K$$H9%`9 z=BE8qOw<;ZRMF;65GR&x?qL8a{$B1xNuw`m4fgpm&KI4a6uVLHa=E5rpb4~4g+7WK zx0#jfixC_}Eqrj7kel+2WG3~Gg$_gIdrbW5?yr3F!25s3H}XJHPZn8ksd^T8^j>;V zhF+~M_XPbTP1^4tzJujr#=^yiomXmjh7c=8zPLTqPAf?y@jS^<3oY&1$%ux!`9Z2a z`oyAQH`Idr zHjGgTV!MJw4cjq+y1} zB&iY?s~dL(2IznO2GEFH93f8PU91-)M2PpLxpPS#+!u#ISq_Ct%>DuIfd$jm ziGs_}zS@=HP>2Hi_&tk1)+hqQ4ve?0mo9J?1n*yduW=a|Xxx`5bj8Lcc$_71tV{iX zZKt7ObV!L9YA`7rzuaFVr2kmnIEveYMTm>hasB;c!+MXITG=5xR5gn75g<6YxV9_T z)V!C9(bK86U7D)5-|U_Lv*=6M2m{Ybmt7|f?P3|>%2k$ZJ^v2q|Fb;-0&nk9&7bz+ zZuewnF&!;~alAXRZ)bTe|99p3RNy_;J0*$}{yZ`c2plgGQbL8IUM3>ZDAgK}tWr-t zjXauwCN0G87EFQ34`S>eAMo)Z7SKzInTaQuGeMaCzOu#%Uk$+Be4AEJ0&z%jgSON> zBhp#)()m%GRf{I);mLUZ?sbuhcV!%swqV3@>RJgtU%H6s^vwerEe}Ktc`y+-PzpcrfYp`Qk8e=GqA=o7s47aiYkwq6tbvA%8}xUJ&-f!hOD%u~v|@_S&d zr$;BPS7q&0Ssh!nF^@zh@b90M_maxDZz({dVS8fAyJO-vBD{3BTf+UlRZL*t@b)T`rLm;o#t4pJBrvyRacL zdrM=I4?zOUxT{3c&i1}jQc=ICoid2Q0r1Vq1!CG6EM#A1UgjTc5myI9|9{8XxCT=% zp4CFD`ouo}B-X%BA(j@RQTu~#mG%~qWOWKHRJL}H<50s%p}64BX6jqR0?6TaUP+I4 zW*(N-MjEemHt_(UPFUbax+XIEG>=hf<&$U_^@M7X=kR-sx5dW(br}Ru(fi92)%+8a zKH~%ihKTe9%pJxvM0*q&^~}lX40Mk@erma#J5l3RK{m6~gPCvtkqjTiT&h1Ycgs#C z3N4}-=dY}vTEIAP;$(yGA{2A=*Y#+Y;>Xw?NX(&I;#fgW|6|8{`x&|M(!o{Z9M7v|o_y%-- z{`cC>GtQ`gw*z1T+)B??H3?|}@x?R;NXc6Z`z?wq;FQ!;fTC?EOnpXG8!Y?5ShAGY zwP$p^pK)_s`08J;2D-R`rp;EplRvtoL#bC!=Gr>J^q=4JqR#Nt5I`0c7Bw;mYP-ug*9uB( zK$7B*1VZkuMBUkiT<_h6n#RH5qWpe=I`d7iy6@izsQwMCmw@lhHWz?j-(lapDW0ga zA!OF8^Ft*ZpkiP^!Dmz!`<^p;AojkWUbW0Qr?{h|!=R^JzNFUj^P#DF19p-iYU6=Y zhwW}N@yzWWfqRa!_)fgTU(-OU<1}i!C9$Rg(w)me!fEP*ctVo; zvPo=8<;Seo(iyyT7Ku7b$HnraIyxzfCjbx zP_6OBw6gI^1EsHe=v12)HqCFggcGQI=#$+qQUz2pY$5KKi-dL!RtanDf&@FKRW_5b z)PW^3E~EK657@JMzi&4codMxIho^?S6_Gn9o{Vv-^R|7%X#UA@66s&5itHi@RN2ET z>?KEW+cVyhkZIT2ueHDSBm}^ku5-+X-Ww)%f8BHVP~^L27}rrp)Zh37%@Q7aC#-o& zzlux7k;u-5hfJ-ESWPek0gD5*$q=6G(VG$+2)ZExF57(I z`wqYQ$ZBwZ2u)1+dKNWhjzm-GNd zqUx4b?8%ne9Rhau)3Te=pEk93UCzGaL6^y%=a1%`t^87D(PL(-J#Yt{gGpj^In*6$xA(u|ViH?0@#802OHT z)^aTsLY^+bF2`AwVmE~Q`^66~9k_Zgrq1FI+Bj6|(d@8Cw)pMjx~!d10iAT?CcP zftiU5eGqYn0@e{0Y^DpdMLXgWWE2dsn^n%Y1w%p;W!9vdBRN?*tsbN}gYXauQ;WdE zB`M%5MUW)kZ%Zo=zW4x{su2{B9eIfMuLRy9AYD6|;Wqp1G6;Sb_g4I=zqVioQ`eu! z%og}*8zf4*0=BiN|M|WPfZc|=M@@4t8%aQt`P_>@M}}KMObk}4ffuQ?J}K@NA@AQX z#iS1P&`AQ0i6GBlfGPIry7hHii8CMl7WxP^CYSL&{Cjw##igoqvy1S}IHwzrd(jN4 zF&&pw7!Z0f0`^RI%w&d9ENtws=!X2pvc0Tt<6DJDcEB+lyH@48-ufOqFj`;WUf5g; z`Z$PnUFyLobSbcM7txT+hgs+LYMWF_EnmZXfX<6)+Il3VxP-cg_CzQ?(aX`YjsNE- zRZVPfoFU<2e}Dh9o!}>-1rIJV3L$0BSX*0L7e+qgIv>p%n7_;NN`{F$?K?Z1 zYHgK}kdjJyoz8GrDP#P=a=uo2*P@V~2K78x9{KI|kW^T#C|*LmBSs7?F%FVjEztq% z8HhE03@7)Sh9(8Y$Nv*9Q$*&F-~|MNr7JKy6Ke2WvHK~W9A(nHc2$GAgaA=Ib`P=1 zf5C`|HyJd4k#?EnL9kQ=a{c*ZckK?%*j$)}QU1nVfVNh!^&COqPnHR24sEFLlSLep zf$&kh;ohGbbSA*9sLRCcH{WsXNQs8~@EPHz289c`VQ$^3GxqS8dx-|9w0e7Dtz0;g z7dy`lbO+I4@L8F@*Qvj;<3l|4Qb{7T0++d>(kUc=?3j0F#Wx(qz1azu-#VDfC@!gd z(~_xPv8iywfEa!Qmz4Hqt9r94-EAO6;s9r}c*4c0`57p6^_9q7-IlJ(clbP5>pU!A zIc@aWQ)=cZd3hn3NAx4xO{ z>KZ2S8Z!fC)FuIoj1%~^mz2zxV4^Qm^qN4BvQ(A14%(OzG)?@C6-4GxCH${`woh`F z&|ok}FQ|TD)ZH9F0bYR`uv@|;0)Q3z^W`E05PK~RVtA!cmJ5LEY_A*8JCsbvVCj*` z^*qO5IddKQpTvy(AhantfxENV{rc9#*?wXgvBP0;iT8MYUL(og-oB#^x86=qIIzTi zOUPMGMiW7zCY2Y}#Gv31XS(&x1A~!3R=d05=-~CSipZHl^;8^3>&YxX_3f47Qx*_Q zzbR(bYL z8U3e()O*3JUmUMWv-+e9cRf}fBSJXD+{cjs)dv`e!pE!p(ABF@GB^{a`JQ$E{DiNS zYWf&)Oqp!=58ecM6V7k8u#2L~E!3yZ=sEjlqRZR1RUdk6Z0rvK>mD8+i$8xFtw%lY z_OZ5ZPRIT6O6xm6oyV2`bCP~TnqTqlmcqp$KPJ6&0)^#I`US#U(OYP4;DI>lg%Xzx z75Un$tE86o+irRdv$JI3bd^%Xc9sQ=zi3N;5q3&6Y7-7a>)15Lvlw#P@FLipUXOFd zw}(KG-Z2S05!pNGre*<*kg>~q@0cj^n5D%lKvGIFP0F`Br|UCKECi4_iTIE*I0o~! z<-{k`Tn4?Z86SIUXgU__SRZt7$r%l7p%scwe8__D@${O3)iko|$MhJ*e}?iJqR_?}_^hRz#0Pldre ztKs)vZ8EIogRpghj3m)IC1A)>R)PXr3(D0 zRV5aoKD_ax$a$o3U~v5t1(m$n`_>czchi>ZnlXQ9QK09`wT?ZvFAiY}`Y#qXtT7AIFp8AIo>-wGqqnrla@+3R8uq)D`#s@c^_=C^R}1Ni6vGR)|8qA1 z_C1F$xdJds1!=^5o2KQV;Ztswx%cNz-DTzdb;%v07HZ2I@>}JpFY;aaMDdE#x^}JZ zqw5xspATZBF{uj>mafuzn58$N{-7Vxb$J-dU|#Ge>ivxHn@yri%-ttv>_+$> zc!~zmoq>7>A{;<52Mu-z(-#ag*W z7;ER_28A?eNP$=~E5l*mG=_-LJ-#gJ+tg=A-N(Esa_v*KymiA2ORUt_=U{@Sbswqq zZEV5;x1Zt^zIHH`E4aA59B0Qycm|RvNz1t)ST1UST@F4ZaoG?HU0K)X;kmBG9j-M* z9-unM{EOWyLG9~nQxQ8YdFc5?@PxLGj{HjiI&PeIfYq)!&=75BW>5EhvC=ahBA<{M&ql#rbOt@#X zbE$`}V_0T6#XX-6f~wS(X|nrWBiJh0J&K$Cn-P~ooSjo*iLQ_|hcTV1*SxBaS&DaNzLb>=fC(>ej$5%qNKcX+ zFyhmJU`m*tI4qG57-+Zfe3ry97H}1o)vRQiFiO3~Y6QL3oa>gM0t=I z0MF=ARJT#lY?%S$W5u!mxcsNZB64p7al|g*iic8VdK_htjN!KvWfIPr$41FOTt4c; zhuEDq3AqW9XkomkqUJLejko)XB3>Ircp}mSThLw6$hT}sHvvs*SYZtha=xvr!~07t z9sJP0b`rj)a4kM^>xS(7@LGVbnV@j~PGUm`8=*W$X1-VV&r#vKu$Vrr+=^PKJLajk=Ct8G(NDrX zrj>57pC&HyRM7)wXh(EHd?~=%S@f z?3Ok~C{YS}Bi)?@hVroF;9! zZ^kJ?jUrjuTI0y;qI+H9aYPZQqK;7hj0u(`+r%}Cng2^mihz4i z>JR}yS#j-SD~m}tC?48b(Ur|a;3015ZOY>y9@hRzdZvrUm z{|bm<)$DFfo#!+;I4YFzurr)XJ|{)_gBY(pd$|m#Ec(6M+o7BA>Lq-0fNWRmF;$uV z=KBn0y4MEv)E8{^D!WHgVPqdVJ2M*ipXl!M z&N=5R^v}rUsvttjo>qdaBTfRElZ5<_Vh4PUQEScfT=qbb_SKWSlqfZ`MDO$a0+RD; zuHUFWCKD8h0JQchaT^gL(YWlNv}1eKpjA>gAasdRi0PuVcDuBYwIaMUO{~{rw?iqH z6C{PgtWyP9si~VGrI2C5DB#ch#cN)GlJJY9pDg7xgT>OM4n=_3k(`}688!NafI9<4 z4BdH}uVZMaxHd>DWmT--H$Sp4URE6YQ@??dG?|UFj9xU$8p915JZ@zHvZ*6?1t0sg z)OS{(1%fA_p6k_)sT0yV*0NZ#IQ$4TRcR~U)=@??ZQ|I;C>Vr>C&&UG1Oen%EL0o< zX2{0|Isywyv?tsqD^Xpwk`0E<@7Z4+4G7-}j1}r(DkuzmsV1KW6<*6{3*a#7`j0Hk z-I?c??G095%wky>PwbST)tD9IpLj*je}xu)0IWU!jrLnmw{^K11+648DS+Z4HVfv4 zFK$*?SAX!+?g~Bm*atCAwnZI)eT-(Azr;{0)QMQjRml%);NDe+!=FS?3zWhn7YtO> z+hds~YzQF}LJ_Pv^^R40JmY1H*>GF0i0&77lpC8b-t#)Y)jG4{R7W#Am9VePEZ^~P zTjSnT?I4+9h@r)FwP1TKI|ZNx19&RH*lc(99a)zb*KF1!ZbZ4Y90^5MGu6znNf$k7 ztb1}IH`VBa83szr1ACd-?M{pYP^`RiHb~6d+ywXD;5X$#$q0-51_tTu3IX|z_n}D@$3}XrU5~)O*itkcV=V+x5N)g zpFl?7X8A|_eFYmX+RC~uLt)FGU||u3_1z^&zLg^rK%FqSmQAvK+Zp?lo=!netaJ^r z>k1lH+)lT>b8{`i=3}`5l(UpxxV|`Y-mO~0!o%}JS&{vDeGuA>$z*T6LI<+VwaKMt zk3VVwGLISR9X4HN9&9X}C->d3TROS!{XBQUP&Ugh-EL1`H3E@X@$SXSI{imN*n?uvK<8>1 z$KGw{Cj z0Xpiy&%M%t`Xk5x!5?XRH#V9$-~Bk4_->NbBpNs>@>)Ufofrb@#+UGa>LDe05Z`w7 z2G_`bm%gU{*=g3L*^E)jV>OJSkqf5*jF77Z9R~y)`6_2$udWm&8XY*c11azwj2HxH=A9y~{NzS53;g9ZKp+Oe{#bn$>^x>;G##a`VyyZ#peev^K( z5b}gW%w99?WJ1; z^C0POKguQeu(+OgB@kF;56~RB))r|@+nq}lpx`Ln+}z6fis(XfDvKK$JZgx9`1lCe z*I@i2&NX0_oQrY3sn_F>jM?}Bq;6b;IW#o%O|>Cysvl4*-8{3SKg%4Ke*Qd|Pn@o_ z+hMz{aU)Ig7l2eN6PKCKkzinind#8>{9H18bJyhI7vP^W{@IX8%BDNgh59$Q6mRtp zC@LuhQv-=WTHpBsw-$i#A~qOou@C!t!RK)q17glG-#!e_?c`fVkzxFWMV%hror83h zYc=Gokfy`cev14B#dZIgy};<12vD#5@CvK#t->+O9ct5P4J*BRBR-rP2dhqtBl|@T4HL#5Z|Nj9>q7Z{E*lj8Olj*2KnUyi_EHZ59>)I1elvqV- z&q^HIujkq<1c%clxW!HivlC)5rsQeXz%J>yu}dNu_cv?A<<^4gW?vBcRG&SRNqpno z>i6tX$RYnynzan_nV2!8T1J|OZ)L`W+VabnmOmh|u^YiB>2j&*BoXZHM;eF6BY@wu z%5xv#bWhMH%XA-&6l#odpqJu9l}ZZ!R?r!Nd-psw@Vy`{ z#y*E4`&Jf(@PRb(9!80Gwo=wo3#M?dt5Geq`A7s20TF{N@Vmu$bB&^gwqV60Up3P5g9l_c<2>?+-Qd=KJv`s~531cS}T zn5;+bG{V*1}%MPreOobpqOxtU-nuJuV2H>f1ofV*#k=!PC_To46f2n(o*o-Jgk zxNR-kl2sFZfZbYwl?994(9M$o<)0VzH={%J6|Dr<$B;vHW4e3~#+{@fPa!gPrb zj$yO{qmi2vB84_C>OX577{Gia6ZJ7GhUIfe6C4=85R=aaI-%M+fY$(GyxSL7i%BcLtsPR0{B>>Q8JveS(`1wUc1nurc!h;to)$<=oJ2DeNzxq znF|cIP_|Mo#b%HimzqcybLJ@ugOPOI`#0T;b@_&&iX|vpq%mpX288lvuRS=%4+Kr% z4QUD~+4OO7aGO`qK|`CbTHBayzaEc?b*Ji|+!AmIzbGc@iZdE2A=R)}Rxk8Qf?a=i zN9|Wl%1S+;>i!U*7?%vs3q7QQxlqw6MgO6%I#xe8x>cbl=#_~6N;^$pV36n);>A!g z_!nLMwZzKf8Viz`mpsr&EX_L ztE8?HV{G0ailpqgTKKQ55_m=^)Y74(Wq=RgBNGd}LyvC$`cfKzaY%TT5eaYupU9zp z2k!fNA?3_bu=w}xM?>WrD*qA8O?e~|5}I@=3G@17w;-I_s{)x|N8dNs%Lr(sTxdNp zPkLtB^5mhBm=yM8bJX{|X0wy~%Bbn=fl2zKmRPnx!wLVdz$J}AlTho9|9jL!iAxuG zX^Z9K0}IKp#m1vwNc|yc1Pp0V1Xo~C``hDjvLjG51M3+k9E8^y%bR%jT3$253&!G= z1|{DzWtvZU?)ci-zSsx5z6I5%kK(eEmj8`IMN}|%_p=U``>{bMKqq9HKRO`Tgph|P zwv@_$hLi#DD`TMLX*E@AUmA5(=$E5aGFQ?MW1p{nMU15FT4w zT~f+Kj={aT+{O^li!ER<(W?0R(+x0ACP|UJDR!r!Goq`0c#zH-3@;fypkc5D5l69pW4hEC z9glIE=mm3iYOnS>#(%nE4wWe%F3?`@l1nRBHcVlz`B*I~?z^1C@n=FCHYcM*@qP$s zgN3(8slWW)X;!#Fc~FH$byZP1bGu4s<<0aY(;~=#O@fh_{%xK-0_Q# zcSleKjTtK4vTmfHNFG4X@~2bM0w)leKQ%9`1oZ>*;${(OWqOzPb*rU`wL!BTG_?Pt zqV)Qqum++|RH~xLsMT2*pifpB@g-otvW;iDh@o1l^GizsW-=q2L;-%?1$@Y6)6NJ* zOIRRnV_W@D2Lz=Et-uyPEdy#sh5xr0px*~g8IHE?ETQVtt0W@q*L*L?r61SrpVpa7 zT!7T2-tJRKyr+;cw}&q*RkMFb4+(U)m{En(c`* z*wEeo4BdU(|CQaZg)bAQr*>y^ZhRT=vezPLf)x6?iVN!pEv91`2%L5=DTPjv4aLGK zX}6>Lb+l)L)AfsU=#|S*Krh(a{)69I02UCJD{&Al3VQa^?*)scmKPB(i zGWYzwDwH91F7H9$vjxf1(J}xqB+}(#z<)z~6?zj6P(aXQg97Og7ef}n(%=CtQDj2f z0bhLPZ~P~)s+U4>pFj=SuNI*rY#ygYG+IwK)t$lqzN=A>e=2#W=2!pe%Su?X#2JVGu44JSh{U>)pHNLGNU8(F z&_*`G>g;)Ws3bie1#6}4pRV6t z1rb~cY(cG3LpU|5uC~WP$ilwRLoC77pEnB%b{{S1eq)+JiIMUQS1c;Ef2Q&t;g5`7 zQqmz9rio!;AKo))>SkPLUNUTUu#O$*Cl0&VqF;=3#S+D{UZv8v7mW%G43rQ*1|!4v z4-Q!0c0V*0<>p=-`e0U)Kb07pkkPlzfkR}A9KO33AwOcy%f~Ojq1{6ngmE7nF7nof zb^#L>yD$PTqXzA7Q?Z^40dUZ5-9a@XIeAhxC*!We?GU}%AM;b}D+7qiG zqklRh)gv3bIeUs_Tt0+S;aS9MgaLW&n%y4a7x9)V*N9ssAOFIySE`hJY|k`SmWk6^;IN2q@j$0)U?_(Ctent& zo@!MkSbEMVwI?g?^&<}IpR%Ck*G0XPz903=?R`g}Ww8~sidYL+*WL%tDgoI3awgXv z@HWetU}aU=eQqFY$%HztO6vbR2}KWj8o_fD6V4L;>1BkP$-7CEhphpE%-;9%$c?h6)J0MZ%`2>HokFUMPN*&oY8A`lE@+7Yg z%noJu`bObqQtxWSZNq>`X_a!U$=4fqz;p51Nk%CT;G%-RfC_DhZl?P<3!XU))lhko zBxv9O{2|^?+?M|d!bAcc_0LU>`_Ws(^2?U=@nJu_2@F3G7t?-sh@z}3+RdHto|;t% zoYp%+TEP!(Z6#Wf?fV(MNUPrVkr(MtFp#7CI6!f6$V-o!$xD-*7+m72>1mAr9k!_S z?4=K_f0P>b1TTTgoS?idJ6A+3(65JE_L9Jz2cX^}HN)NUjO?F^C1e^tfA}j5+erie zIP+#z2bkOpG{~Rzxkv+(a|1slI{P27>hlz%aIO-5ZS=M;ul+s#kh_!>2y<7?X#IKu z!4>brrIIOFR!(1Kj^cI24&f0rh`GTw!8HepdT#ZIE>e+wiy6 z{B2_Q7Qh+wv!9)vIarIgav4FL`&%Q_0<7*Mmv*SDO&|E*aJ7f3`YZ7(>R)SH%k7VD zYj@E0po;oW1Uq~tQc4oEda8{tNz>%?=TkdPAdXiC(3th@eL&^Uh zNFhMr$W1kE?^l6v;JE)W2aqcRNJIcQRE}^!0A#*-#Rw3{D%9835*I?Df;iCXo;bQw zKpZ@S;)1s3K?*<_Dyu_r-7k;B37P^8`$~I?p;Sw!7EIrJ=KGjr0aV?=|2Ekcal+h; zzU271mP1d13@wTO(*BQ;zf=<>0r4Fn0B(S5o`KpOfe&BJg{Xn2$4~+9VBCxA2F@sD zK)Y!T4NSvD@x&RJ{**==@)?qI64_ zbV+x^q74wGL+Ne=X#`Q}Zjh4h2ETdh<8$^t?|b&Q_wT&_8Ee73=RN0$Yh2?RBar=? zhgj-vtKGleJbO@MVo({ox?3dWKGi2?DC7iCHn$ITUqe`4`f~Wzo4>5NUm`HI^qR3y zzynHp|NC&4#uk&Cx-RiI0j)_AS`%X@g+J3~v>UolzSi5E%QZD*_aoz-6yHC= z8?fvl{&-T4=5aOTam5SWg-&|P!8=o;gC$-+-S$V6oc#mPds8j8S)Hohso&(bJf>LT zHS-^HB2Skp_+aPk{8>qB(YZG)WzlHIlxV=_?ui?v?(&$H$fDc^^zMbaAZF$BQ?QWv zdV$RcAh3gql;6D}EA@Y`T&DU8fNvUJFKZP2>k2YGS4aB+w)_W~Ic|gWs*m^9uB%?O}?nNP8rpYW!*LWsoAK^U8vc4 z+l!g%jO$-nfv+q!*goNPD1|+)dQB51Wz^JHu{=>ww8*Xn)qNKe1Wy_3xb3oM zUy&-skBi6jJl7xCWzJneH4co)dJGt8O&SoishK8!&-C4gZu_|dXd`VL`?bi7f4#^* zt$W~kLT(!Tz0i)kei6Y6+~*M5^VCa7-l5}fd&s2E3FUOmkWJ<}0a&CBgeghu(JIQp9Ah8+aae-Axqq z=Km(>vnd*B!DEr-HZ>tX?@T~{n;&aGk5pOn7O%OVQ^H|Rd*uhChw(VyXm9neNF7Wx*?)AE8&`f=Y=saxiQxg^&q1#jnF!N5qhn{B>X!z$@?N4+pY ztIEbC+vdGYtU|4`wd3X#B@ip)eQOzPliVbu=ednpe{o`|>9M=`t+eQ7-N0NP@RHlg z9hVgv7k`~VP%i#Y48S;==Cw4GDCowSNM@dj{_O||CGj|10a11yd9s4sg zJ&K9LB5b91X7&^fNB2c47n0U66uE8Si0!d2N%j|O4`pGkom@+{!pZw6?$vEz?E+@YZYUiUpSR*mBOq*HZnL~t|x&*RA=9zFG59!azS zLnP6ubsl8?vLddFsTj{~?oY%h*I{#de4Ga6HV#IW3X*?Jg=7HZIKRH3#VL^c0dzF_ye_*xk{Z}@)3Wbbr zQP6d5vH2lRoMvbC^B(SxpXt{-K7Wax(X7sv)3l+wefu^IC!FHmy+Y7Z)bUMgb>a)L zIC1aH*r3?=SD|!HW1(Mnu3Bx3Ox$k*)G7ugm+#TPs4nW@>sF1U;0v>IX0*C>%N9YMc>+ZfMd>DXE7 zuD=e_3A|gWh)}{D*H$0BLcNA$iv?n8YU-QMx3{()ILYdg%!8^;dlaSXY!KP}^VT~O z(>_1Fbn&{Ep=v;9%PWvt-2`UT&{GLmfPcz6fpz$=G7*%tQ9SkgyJek*53`g=0(L&1 z%TyzvRYwM;D8Rl$4d)M&O`({tQA?75o}ZrpFPC)qvSyVVH84wQuM3`Bp!+9dc6^ta z5?vlEYnb>sJtS6au+H|ZBKne#*x3hr#`p>=mTv1aFM2~G!+CGo?q=5#E$W(-AvRMv zO3(*UH9PU+JHhF!L0YNB=nl!Oas>l)`JE|0+~1x3Q9cG+C@JCK_tfXRr^6qPvm`fr z_V!h2zQ#7;R*o9Zq(?)?~8nRTnSKGsJhhZ_@8frK(oO6@Y;pX4*` zE{+q;m%J+DnsPt%s$olhYZAVcyZ@wWHP9U|zN1EOyWewdte%7sbUv~4fpRH&D?g7` z4(CG8;R0=Z3-|PQL!<5QXFotWPGuF>%Yhr)l~^U(!LohApXt*l5r@Ucbw9oPgx_*L zPV&ohy= zhz-VyM-@cw%wABdTeY5M=(SHL4Cgtuc9l+7&eR+{%*#``_ai%*$l&G2cF#eh^&~J5 z{*2w_&QtlHO0^?1-rvUdIUFvY(LXkH<-xS?4LEgSKPV9A{AyVIV!rvMt_i!>hEloJ zu4nwE8Ui4-p7-|b)3c+YwPP3 z;mYejT~@D5-5R^f=UMblFpJr2DwmS<;!H^Q$GLE!Zaqyn@`3T^PB9+U`C6=?#|gp@ z?AGcbKB{5Qh&vHZ{6d?(KzN8cE>2 z32X^KOgvF_IC}#`It;;?LB%SxhA|m>EX1nY?JX-hVMZ@}i8EU6N!!tO_WqnlBjbFM zI92iXS~{u{k@`6Qda1*b-00rBhp)EQtEMwu$iqdu0l9V$_`}|44$!+?2H=RcqjK=Z z{|9O%DBS{HLzuuL>(1^n@UiCefX_Ubj{V%JIZ3YPjL^RQa4Jp5f)Um`$ zpQ!O7T2D~#SLC-_VUUTvm-QMnZ6P$$^l9Z$g9>|9U#}>(=8}J(qKXJOy%@B;^UVlm zFVY*E>|--B zm*C}`E0Gsc=yc2?kH?4%ULeJa0s@R=j-+d&s(%J57MXM)1HGuk+*7Yam)=4MxGZ9v zILc|NO4o{+uOBXR5tNbUE9jJxBizmlN=A+wzFi4mZ||Cx?iVz1{7|a@D^%6ycfLBC0S0Ml@xPRqt*t^MNHo7x}UNrG_5q=2whZ=IV1 zP|5mC&u$@}RA1~|F>To3Oe}0N2|6>1+1aS;TvR?%Z z+#17BtR@5!Ia@XD-2w)3%q%U1gpsgx3iRj-Ainkk@oy9TPnw$VALJwYJ~&yb6vPwa z_B(0}5aoS9$p+r1prDwqKl1n-g!AxnweCmvCLmHYwF?yZb|w{%cV+iJK77Ss)^pz_ zmSNO)=h4#urnwL1{h6~F(V{P9QKFmE4SE}^KM7$l+IFVoa2EB#2a<|;BGX0l6^_ak0{6<^16EwAp`7_I03S2NUq~H!@-zKLTS*+I2xXE&u4mw@eBtb~}v{ z(L2DgS8uq^TW&M1nB3VB_9ywy>5ob9xLmHPrfNQrPl8Y|*=+bZb2j=)(CNd0>$Tn2 zXPL^*GRG-SFzudc#Pjs0Nher1cuk*;LX;}#SGs?i<9%@4%<^G=3`4-EulP9Fv7rXV zxwZ0^1ZU!=fA&)3ZZ}IRndW;nR-jq<)pf4rYlcUdM+<#cd(LM zh|gAAGE1$3J7lHStW0L`78bT=Fp)HVZWB?3#Eu-G(>I?4@jAuc|Ke3q6Be7t#8Ook z)MwJkOl=kQeD--k!q9u{3A66D=-sUECly~%D6IAf)+`3l`P+zSU@bw+83WP4Z43GSA;w_Hcrsp(n`-9W$$UQl}< zUCxk-lzCMS!e0##k^@%Id*yZw0%ZB=l*eWcbt4&>&EyAFMid;49?Yov1Srx4{e_FE z_x;dD>fE>x1PBitJUmq~eKvpc^i4PhP3Jxz6f-LH;uD(<6ZxSj%3IAP&q@A_XAjSu zS|6{945kMD-MDxLyon+0^xX>(i{B@@4KwhklYV)TrmR9Jjt}#MjRPxhvW&nW+Nr3{jR$}*dXXJx4IMg=*CuI!uu40VE0S)DpiC)L{vpDf~TEBI|u+dkoht$i%C`Z?l ztE5FE*#a?}=9r3zRKu;+&D1b?JYuDK>jr&**__C;p`IN#YdUU@Xe^1I>)j0g+)uia zzeej%A@(&XY_z{&Ajjiu4xN}ees6v2+O=!T1@9Ycp@|J{45~n@8_0DZpO@8IO zWNC?;u_O|$iDtI&Hyj{@{!9}qyFwR-E?)>DDAZ-)~hl-ElBC}N)O^}zj zS#EqYq2&KTGnGu&3&o~`YClgev1ezE8NA$Ke6F<>7%V- ztYC~a6p=iip&2NO-}!a{N0iy@iY5upHEIx;pmq|mr8$OeY&PuJX8c;NIvZ_0Vp}eE zm{lX#S#s%T?x(=oR6lj=+fw`Sf0`W0ukqHyzL$B!bDyf3(UF7^)Jl>xUfO zufsATW>!KJ#H$e?g{Q&LmzFxW-GL8t0S9nauo7$%_#0ZafS#$=kYl8Vgojq8)mv?( zgmNY@b1^qPij=dWw3{UIy$#HWnxcy8Ph^q_XWzc%dUf%bAWs{mj~dC8O9}(&o&s<+ zJ8Pp{0=%+s5I^fKN=j(L?1r3&8`L6@7}q1L4fmg03@WKjc0M4W|9Bd9dcNIG4F)+@ zbrqBmB5rb+>`6+s1mm>;&somK_o3)o zAW8-to>neqwUu6PUf?J$ml%d>Y$H5`T(@YRR9Z0ys87~rU2H~W7B1G0foM8&@h#DQ zYhAupl^h;NsL^(vxmrbUIsFte^-)<^w`I}C*UaelfH*DT2M}`ohX8rFkph&G{%4XI z1%z{iXzKrh&y4l%V<<+^7okc4jJ(FzLCT~bgmzOC59zrm;hFh(H<_wsyhS=AdZ(@Z zR~z0hVf zQ2OwdXt`eA!g4?aC53DxPnEgK#F$7O3d!^ zl&X>_H)|&@rlM5CA+wbHk;+Ao?m+K!A5Jq_iNlDxMG)pc?qRM7+0Dn51M4*OXc{gRcgfBJ|$_ z<#2+$S11x;(UWDm{nv(=giv76D)tf;tIK^EonsLoBpnujreWT9yN2!J)N6f==lsh; ziLkGP7z>F*!Vs>?-hjm+q+MX15!X;M?cFjlPV2MIQ`4W>QSYNRJg;ZR28*xD#I-g;j!O z`;Eb07PQ{;r@bV=k4`hsO{qdC)uYVc11%hbxv z6x~=);ENJx7ceaV`IHz*_xV^N#|>lS$#frJ&xE=Wb=M#GL<2d>(#s2E+aB2^o&GHBjyVuLH` z+)+2r_;X!Xq%vEEm%hlKbRO_D@BeCGt`E-DP}LL#q2*%#Yk#IuH~;Ay0@ta11n5+W zP5`71Z`({bSn+gK{RuY$1+~1iHIc>e(gl_kz6`3OBlG&MFiN-`tv}gZK!vPjT<CVoWXqJ&F~2d?P*)KP>G$2}Db+`|6*MknXLoMJ(wME7F@QfGZi!%@saZ}VVx*TN%0k+hU=(%uQZ2yOH~YHS!OZy^Eu3d1GHb6PGUq*c@J#o#Ap)5R@0 z3BODUIc4uw#L z9s^bs-2Wm`syufVg<|JWSrP4htI45Xa{gEG4AKj>@1f;0UhK+;`C(~Lis;H>cw zBN(B8@aVsuj#A|Zx96SLla2OIpP+;YntpT30>+5@EfmWG)e|yua<~}{42jN$XZPJ1$C$-mL>=zO*R{E~jq^vQ%Y5icx_81N_#r+tbX3cLxB{GrncW8;C>h}b<2 ztTgvFYBvop&W^{j?6>ET#}T0tMtPab+V5NdDnW&X59*|45WV7v7+@Oz0fr%m^Nxh6 z7ej$NFWzi;yhh*$mvp-A*useypjV&3|CXzuDMJH96-CjWH#?zHckgbCkAsNSBKD09 zA15cFHmuDt`9}r!(^i%vkKL2K-1i>dUt7D`E!J-HGffK@HT<}$sAfCjw^*Q5zo64l z&(BMW7(E%@ydkusy3Yx-0@!T|=vraqzI_8EDB{QWUHyf1vb>E@TOC9u`!7g4b4lY1 z9`w%fdvE(KvVS{lG`%oWX?Y}KyDX>-ge87MtAidEn~r9h=vB75>fwDji)MG6t*0-k zv+4CvNSuDCl=ZUP?6TgUnC1GJ78ti}TOd^I!UzVVr|Z4~kzgP7)9>tmt#!lX@taMcKMRU^D$lxJ!K+x+ID8w)=?I9Wh)eMH)Ff9zn;yTL4Beq zKR*}6gQ-~Ff;Shi8ci)WbWO~xEDV3ccC-{pdRMa)16b0`iD7WSV(+$E+#1VMM#T!Y zu27wf`(xtFhvBDB^n|SN>?2d}2QsxXpxpuq!>d#1T0G9y{rEvR>-xgjcZ z15}-8{cjm^0q?`og-Q)QVDP7qlVdjc0N{pY&^oWPPUDZ&jJhB3^veSRfU4;>6*XMs z)*!sdF5`eUnSG5tq|jCdB|?$KL|e%v~RlHhwTP-{NrR{O&!ek9*5lNZewGEDwWv9<*+{Cp>vr_P3;7Ig0aKl_@Uq0#@DVcZ_{gDKuX+Hl^E%-_lH)G zmG8@o>hq47UYbD{N9cLwD-(i+ z`G#nqpH7i*jtuxn(>cH0!eN8(**{4>mwt1{$x$&nX;i>_{?ZDVU!e;}<9wCLrV_or zPW)}vTy1tPMa%XvHE~qFZn_Hr5?9z}XF6LcBiS9lWVdb4U?qb2YXCm{vC(mpVOh8* zzPpQcWC6K)o-B^KjdVR4lJ<_PE5qSw^o#Vd2&^28a?L9qXhaABj}!jf*s=>z)uKtP zps?4i_-;6GH|&N>FFv|q@}gccKjO6-`LUbkO>Z$({5S{*E_#6Jod zZsaqsOS^W>OuNx^`l!hx@bSWl3Jc zb9KtQOYLSQ_Ps5xPE#skGAO1ab~Mn8b5Sqb9-)MP%jI`z@x!RxP# z)r>>pftFU*>2OpwP-p?Lnm!oW*`r2f4q77+4?2bzh9vSsM<@W2edliHc`Hx)PIz2g zTz=*&As3rGKeAqVt1-7wm(RLLV#`5=)*FUV>0!^6RNG7MJOa(@w9Wd4Wok9jyck>L z0Zf-Kl>h-lcBm?U5Em#;d@5@7cc0uoNR;e9@+=Vjs&@E;k4R}?cKuzzoFVQBeq@EI z5OZpI`UEH4>@@VeY)S5ma(-BP#}>=)+MF+%AK*E)sYjA1qV1j>H7rKQve_MeCNqAR zf`NQI$S7e{mXA^@d3IMN-|#$Opz{o&8dm;8F!B@8FfI&aM20!XlM)Q!WHze%&EuZLUDk?$OYi)Ed9N z^_1LM;Kgu}-rVATo<^A=?e+D;Jd9Lr$F(z&*2uW~0x@2X=DXifT{SW7)O(~@X~;8C z?}XmA^Hd?^j%pz%$a~VL#>ZgPm4}Z>k=EBAgUsRVG~4gUXhOk>!cu7NoJF~wGc5K_ zG+NN3H=+ug>L%jjV#VSyKUE6?t|@zY8>To5e>uOY{K>G@R%Eb$(1NG&&BL-mBiPF4 zSmrcMGxP2emg`r|2mBnT?17!Dd>K+9L-XVVC^qN%`GKU_5P;>Sn&izr2V|#n0VhB& zLM<;p258m`xoniz-ERC2PB@*@%D_``VtIM_o6W_}+u&OYWlv>CjY0j^a)`BTg$_<* zSQCnW!QzM6TWSAYil>n->Psw32#~!;>8y=c$*VO#ze?H=O5;c9SVo4Z@i@GfuXj@q@goBenWGJM5cmNtuKra$0{hsi_`4^sb;VL*he$JhE}R_#Q9Q_!}RJq8`jmoOusat%z)&jI}T zSLv9B9}~e7!S@c@P1}Sr=>|0K^3(`zIh_IWG)o<6AG6g9-i;+Q z>d~_5eize!=Zuv`sg9k#w>C;dCmj{@3>ZLUOR%?(D60U{DY7{T=S%;AKNI{mt!QzP z)g+iUxtW$oq=&AB{65zfPLPIWkN+MXmfiXcl;763R=n?v$AHH3?;t6+@R4?28O#g8 z#39Yrsi4K%KJ*0ThC$vhlpLlUE*=2pvAJnX@ErpI&KL=pxaE6Ef$fwGx&GO- zOc1sCaQ5y*to7-^IziLzl54|P@DkaQ7^if$uZQP~q`OCtAUYnXu$EMq=e6<^B4FP^ zC4&^e(81ZCo`DGtd6MB`=y~czQlW(O1J0)YOhdUlOz1i_&oFOt8b1%YM#K=9O+zH= z>55A!NDMcl=PjA8b+N74T(iYZ=V$qJ0k~jh5Le3wB1mqwsQrl%v?0>mu$HpuufA3~ zh#wcIIz#b?L56kDFV-^db6Q@4_oXtrgfekrlgIXxBL+mVlKrV zOR;^?alRtt7lt99lZLU+O-T>ANYfe|S z+-J$xskt%EThuhAqqRP%R#~w=LEdn1!+40T8kDAjT*gpzk{H#ka|J?khM!x&finUT@v~{*A=_&!p zp8;xY&-4P7Wa194?S{(m^=AnkoO5ZG8b3%86)9KsZaqB*8DOXVT_13)$PL@03W75! zfE{RuZ3ehbyR44|eM{iWGh+5CkG0+d1?G|pA7{k(pzCW-eJXITX_FF1JuZb z2CnZ7lZ!;qyzsk-Y@iH|)U=Zk0WyUQl(xsCpd05%+f3HUYu$w%b4OiMz;R{uOhB0< z)zo7@{?oUyH0g%fm68mhImR>TFyhhtS}Jj34*k{4iejhl7EV@Q6gt{)rm{8QRb$Ch zTwFsoWxA^3>&8aX!U3+Y$%hM5jW0LgSCTR7UMVB9F1C-I{?VNxMynjQyb_wKf>6A= zJ?ZxIg0d@7I1Jb^gW-cnevgxC6EZhp+fh$yF>+?(@OkQ&Af^CPkp zhnwckWusqdiDJQ29Lm=W$W_ggc@IjH9WwZp9q#)pK`=V0jz!SgnPJo(^-PZ(A>g)i z``JP#=62czn51b4NE@Z{fI4TlGQi9eNGr!{IfUzTzMy>93=B8S2FUiB4c2s7 z@tF2WxmjsA6^SC0h=bD2mu-u|+#paAeNy{T_;9x6Dk?Ryx@hF$;?$PgV&K6BgjRrn zEcSFvAxJpwSXS#>^JD-MJp1;Lj#YXy%JpZf^ZAL>JJ|%ajqoA>2gaTbd7m2QdhcJH zdyEqESg0US1eZa5SpsnN<^`dRI$^uqA)>66Es8SS*Kkr=k%OfrZUYHDQHm1=AHyuMQY8ZrCY4pHLdAVIt zTstiWa?8Jc)i5NOvOg3f|Eo_L3qrXKNcjI|o?AyMKAM>NpUs)vtb|2@_=# z4PdIITn9)p-j7Igp9nQJDt=G+E%yqw=z?{WZ!2{J{wr!$vi0PfWivjitNPO$)@D0p z-639WZkA2g>_yoVbj4$GUP&43^@y$z-%&3LpU(QK8a@5dBizc|D6idcY3E}!7TLYT zQ32EIqTXk|tT~3caqk|+T^`3jQdLwSXLXLEnhN=#dM-gTB%CEr6#xuLj=J0%LA}Bt z_vR+bS(e=QxErRr%&E#%m(8Z%7YWKdz);k!_l%mjNtAmSK}E+9rB@x@pE(mTB&m`B zQ#Fk!u2CXbSQ{+^k#~r3Hy<=%5N#jq+YzuOOAVnkDkyv%Z58}TEg_ncC< z25#j_3_%kp71G{$!ZhBKCfN(@`vO5awhS;L3)`Ty7=aAWFDi1T;FxOodBIY24cOGc z8we7-g||b6I^m$&nX_9~nSs}hS|Yn{NHl2t!SM(Da2@k)DZv_0!rLnpMp z3}Avy0}v_|KUh)`n^pa zg`QQIAbOwT;ku=@GzR{Ma%=x0y@rmbib3zXQ#qdM>|>|1zTv_<_W&wx_mtD_TqIUJ z79kaKYmg7llJ^wVW{cum7scy-EJ|%i+Fr@aQOHh^5F*Y0_-zHTV)~KiNR56Wx2xUH zDEA*z-_@V9y4~3y8S5(co7@^6*tU38CLR-lzmaBY+JH|TSD-;D#&?9I>>i8Cj-tz* zXVThMB4Ky9xV1n)3+nZJmVgMyTc}ky<#N!xKT_+#@>D)0I~hl2pUR0K$yu8jwX?sf zKHrr@4u1~kg~i+e6)!Pn>mE3e+2Qv(DbK%jTW}0qeO^UtL`04i06y<8eibDNC?6C@ zoC1GHBZ^TpiC_{B#6c{Omf+oBzXS$q$DD%D+AQEQJaG4D+sH@t-h3o?gLx4w%XacZ z5GeZ1EPhLPkR(_!rW{C&&=9W;eIAufnxXQ=?hu#|+EDhFBM8(Spr$C-AS&=-*#rr8 z#IZ<31<|_m(U!q{cZ#0KKFE1n!$@$_IX?sZFdC%HpLy4XG90IB92jL@v*u8A7J+le ziq6@2{`Cq6C7^>|1!&Q$EcJX1KM<>Z@mjC#fA^3G)hRG0t6~ou)NXY?J+QtlpR7H; zW~-;dsdS-jMxG+#5e(*ko5>4QfPL8}Vo2mwzX zulo~RHOKOAsd;AE2D1AffJ15e6?Ba|%sr_1oQJ%+cW#~U&gu-jeEt(&YMpV99HYNH zqC#|=T-g=XV#`yh{lqs7uGc-rr;@a0R5yJr$Y7bHrNc`BXLH8i1s6(ux}7T~$GCDM zGn0g>Y}3t>_r{dfSiX+rp$u={vVTVyj`aoA6HyxKM6#M^_1fs-dDW%Yg_9ZFd3v^! z)xmROCMwZ+gBHFVufB>I7w|qA9j!N^e8PKhTwG~JYFX^j{*;I2oyx;dV&>A=Jjsg~ z;8+8b7eaQ%%gqDyypNG;T(H?|ip&Ud2F;J|JP@MLJdTs@d9)?2R#xr29>2zx8w70T zRlr<|Ylo|(+PQ!{(*}?ETWvIK^;xPcSGXnI8XZg)UPl1``e?bO%jxl$aVd(YfLEk$xx26bg*HoH;4~triOuig)6;# zz?n$D_&%u}q$Mx7&6Rp7UpM8|I4pIB3Coz!ngaJe50`i{CM&%3lHS`#&vKk%5~PZX z%m<+P>6iCBj|Hde-%A|{9R0RmwHx~Xh#M)?t0vpKEP#eN0d*|$>9~qQ!WGb=jsdB{ zw$7z1ihFKEU=+l<85;^-NJzpC)Uiy6W+Rw0@6ak{NGZ$Z=($+wM3Y8-^~r5GtRO>? z-uWr_npms7_e%vo1t&4S z02to>$TMk-2t?0=Q9&ni-vgbKJ0TZ$(r?SXq)7h|P6$^JyuyRp+5UcY{&PIB?R1@5 zF!$*#h3D=04ps~JRFENHNvx8Wea^P8j#XN- z6!{!(P=Y)#BUpAoykO00yz(2XHbD$c=k8KBjL$}U{~mlzDfRy4{gElT)u93orxle^ zBnBOVU&;y;R9@~9#p(e3?Br{PbTl-;uL?gMfW|lBm)=>y_hNXhpDYl3iDQ#4c;Y?X zFnA?A2?{s?&~kAnQ{zei>%CX8zO90&eS!o!keKSJG};@V0;WzcaL8qab5A&eoq<2L zB0!#vhEh!~Z5o=?0VJhEOuo}zzn&9Cc!Nh5$V>)8-Ny&};LZPg=^};>L_|1JLuhiF zy7gS0$0D|aW*kj8&K{5ajsg7?NFn=o8M1$}ko_~d53W`!lh*Cp(MxVSB+bt`eBiQU zxSYmY3%jOYQ@BV1PR}idikwB*aH;upL=J!SOUE!L;z8Ar?zZq00%cP+=|XBB|B#Rn zVYW|Nbu(ISs1crabe~_h*tkacNrn;cbA%QPoTI^CgK@jD4HB;V}0qki8;K7wfV~L?GNIDN$_9e)LUN^-9;S#u!R7%+WbhO7yT}gwf zVa_OU^o=GzIAv>;q~lI$bk!)NNm$TG3u~2|U9|XhQV=mbMghT5i;%d}v0U=DFp`!+ zo!SA>vF#LLH#kcLO3DCmX7opGLGsF^+2^A##|r0i)ElXW}j7wSB;0AcZp zIgE;scP{Bm0w3Ewoevm_AdU--k+p>1K~v3Dd1(I90j3%dBO_uFuoZSqM=BWWOJxU4iQ;)q-27m&brFKz5q31D?j>OT7MJ5s*k_>BJ!K^r^90i6L zMt=Yro+EC9py7P*-!{aMp#>>4NQO-4`SE{)GQJ)VTvs~hO>be5JfHEE2tXwdAq#f{oz+D z?31IP1RpBpA8dvI?6{0Ky|ejvcWHKgJ+jti6Rw>3nA7(;t>hI%#Est3*~AsL+!$1& z-w{0;CBQ{uRarPqyVeHyrIuOO5Hym3Dy?Tob~*r#NWFRTCZPpD=Jr704&~!bD4qaZ z`sZTh9HsXZ-i*kRAAo&~q81aaKiv>A-&!B%YmK5Lhr7noKO#Mz5(=X$6!AXe2VFt; zd_u+e;J&d8vbS#9D55D1eLCIy@#<`sJ{LRGMFQgiT5Twe9Dt1%7T}Kus*3cGd5uw@ z0i3(wN(tcHC*ZY?#QjHb?*H#m=zRe?p9t3XJ{z&SXYXTUyv_)J-r6a9^@V7_zJA+K zWL|HDq_WRttS|O4MjTVqk9cW^@sDGapXz~RWun>{lOE@d59;H@&s?L4`393}Ko9Ww zDG+k~?y9&-guNp&3uZ2z7>HF}d-V9}~L=mrvr_{YP5&~sp1=0(BZiC+N8#_z+ zCSV{1%#!z+9ozmyV9xG#L$1?+QAwHo zFbA5HY8Zv}KQBB+)iR{;0F*yrA(oL$Jk5pdc&OqCOTZEf-BMHFyQ1iSr(+e!xIBk^ zOg%qvU0x$V$MSbm`YLpz+$}p90TYKw9|Nkh7Gozuu?3gxzt4g$2}Pnkz6L}++2-W?8qt*2JlHT&&;{Y{+XB^k z2tOU5lUeD~<-T<^AI6YR5iT9gayazcvgo}G7dEu@IGUmQ;Btm}dT3QODjPu?aVy@N zUdHMay^KvyRC*&~QH=iL>p~U^*1yC!I$r08Y*FvO`qIHfW|@tq%wXxEap%i#>3mxt zK8c{5!uOG-+$@syNPkjrrSG<7rS@3A+F={TVpqIBp54>&8CzUO8S7;$W|ak z_oRGztbgU=^l+0s+eMmHi(6VGYmG@f=Je1eLt&%5(|n+CDQNb4W?p;LMg+A8)~ip~ zIaa;Tn!Q>>SCQgy&TZ#3g$BxmMS`j-|~CK-EuEpxy1%01J4_X<`Qo zD*|(XAKH^Dj($~&PcBY2fj136RL>-UR#*$*6ga*G;^rUNpAmrQ6axaXqX9nj@14PIqtiKwIJ&216~f3Yddc&2(Mh|`PA$r1zYpn2CdB*ljRbd2-#f|ArLk65 zs3__mVmW&59MK|zVs@vpwz`kYPz1E_m$x6?OUXdI4Re;{KFDO0Us1-h8S?w9m9*Qtb20J6p$ z_uRYX3fwP9moY%q2{iJ~?XM0$TLx7MxO$;)z>BD_0pi5cF(W{iko_eTJ*tDh|N8}5 zfa1gyY9r+6PY(q+oJSBDkHi1KfeMXnzp@d1C>!a&iRf*Ak#R#>e=@gidEi5uVA@P} zamIC=1z$SVbeNx&#dxqW z84lV&N7qebJ^?&86=0=L`*U<^c|l@k=zNa}oLmfK^f15x(jf5(FQ@+u)THTo?{YPf z=bT-;#9FI%7)yEX@5+iD5p?Lt;=!Stas^LiKhM-e$L@GvomG?l5vAwRNKUrK`$~5! z>nzD|_mN`fw_~8;gTwgqYh@AV{Ui?;+q5nG9|P@=H{agWI!IQHjw}by`9dwgAq_mI z$Ki%J1|NfL{CrVB_DiLF4Gv9a=-yq7MY=b0qWVB05J4$4q+-q*Z=?K_0LdqF9l)}I z&!Kmg_HRf0kZoo6zm%8u4@j=B2SD%UYBwN@c@L`1ei{${7%GKLns(BJ zZM>rZI!#zl!EUdigJ^0xq~K4xKy@;B-omO(PcUTwh^9i|3|3yFz%Q2p`~<-m+L#5? zXhU~sNee^pL5!=PQrT9_~@pe{60=l$OE-H83%+{}f}o3m5)eHer~dNCHl zpUpF^2+*wqO!M8~j5hF6BH;A*D!(!U=sNAMgJ|-v58{Q3$I>4yfd7WHODOx&#`Fv< zef(2mCIE5DQ9U^6;EnnJ^)%Q1N|Cl*&|#$yp0mS1`hGCXAa@2JAJT#ezbzPC!`dbG zRpe?+`-RAOfoRuX?tGA!E)k@5f9+!vSgVX(_Or*pVDm!;y9lUx{d)%cpD{J(YbU-G zerPsug#sJQI=53P(Yq{Z)t}RMIsSTzD^Rbaiz1X-t{W2|simU`J<;?UJjH8Cok~Cz zDa7_=(S5~;pAJ-n3^H?DJO&jRfV-IN8N}{$tcF0{=q-*0f`JBc!9)N~@dpF9We6_2 z34lW|2Sss=|8^Aje?wNZweM?TB84p?mN|+odZoyGEJUgP4n4qBvNjhJXx$_xzt>%d z29GE;>9_dGe*Pt*EGv4vPSd^ntC@c8C8Z(*hq$7^bQ+B-is|jBQ1{3usgH`L2{;UI zzfYiT0CFrHCbRFraiIjnm)^@SB*9Upg(S7SZ2t9e`G+GSP6lLI>FP-oNxx}Q{Q`!x z74#RzO!)0wsk@SetPdRX0}Velq5ruH5)cro=Lp&5Q}9cHT@FlaEFd4YJM5C3sP!Q4 zP7y(Z*aODqjrLCF6_t6vTkr$|_gNM`^_1ir&yzh^=&Re3XBeTloMpaQO*Ar%Qfnak z3X}!+wR!P_{SdJoM2lN10!5(zAfjucrSWGpOsF!eJUdxjCqGs_mQ@iq*BHhbWEobH z+y0x}LySdoxe6y86mw4+dY)fwezx(f<&mBe)N)Jld4L<~#&qa;u_wGSJxY(?z&4^Q zKsjFoJi^=O=wN64AhoaOc6AVSuMSv}U_H1TFg3-H9YJfIdk)6O5m5b&9`B%y(a0Q4 zI5h9=Zs^S1T}t_QpW$8S8`j5SU>+O!;J0QH(B)vq0xEDXL$#$afZl zO0>?FH|uIN)f>uP8e_~tod&qA*-ieEL`-z1*Z;t1EypYukAd%(1syp0pI=b@e9LR; zVgOiFce+x5a+e#IF4)^;I&dOHqbPvl9Xn(JKWPzlL32HT042Da|NWr!00~i#w?1Y( z+485LdMJPx$W{yxj2T?L+nzGuRlf!l303bwGHy%+>ENma;#LvzzpZkOs!MxD!RfLD zRK$LT*c*4D7h<$ebm)zLwD*?2b<^{nJ}_xJfnu^Qk9ri|T$PihJIa z0^pheD-3?>0rnO|VXy;nJfU_e1yJe6x(6K#NEYc|T6Fp&HSs`M#8zP1s~N7vj=z2} zZ7PN=ab&r9U&f4l(1O8!XGKi^*`I6yjE({Vonf1O#qcoEO(vG~9->VTBbA5LF@V@ zUP)sGYF>oAL!o70^UuJA-!3bz1aE_fB>8VStXOEt3xf+~5CIMgq7v;@Y>s7RG+;Bq zjngsYZ}9gHCuBhX*`wU3b_sbb+O;|BZsEZC=XQg~hD5aLZvk<1z3|3OE)=1wkS@^Q z!jJ_!kot>k+E@+V&%Xos&}V`Q`6- zMeA54n8qThwTCS1fHZolZwY3;7qu<8q>+yss-Z>w&2p*+&#_Gc`CIkKUmoiJ#a8&+ z6!8#egkI`=lSbq($}au;O%T9}&qTW}$)JjN8U9{?FB&9&?8yNPTpfw{2$LnC{jhw)8-c7XxsTl=qFXhs{u zpSIDe!Cz5Z$XA3z8Y(?*|O?KiIE_sK@&f zn7X+%ByP!AI3E(1v}^x`PeiQgoPLK zP>28hf^I;=BBn`z+INaN&`ksJ(EtAZtcTd$MA&;$cDbfV42x0@;@ptS5!8 zP``$j7zQHGV+)K8*Rip<>g^dW&UbRCmzZ2vZ3uKB6=WI$wD4idmT>h=1$Hf!Gd7>S z`w{v-UmBVu82)T}m95txy4am!+ragU#Rw*#2sk{|u5*P^jt#U|znFBS7&T=ANhsrj zFR`5mWW^i6?;JTa_}eQNLMC;!fH?)YrBq)SMmhDT$x7!USf=rj0Mnqt4GE4jC3}D9 zcIIPmZHnfx3ImJu>yANhJq&sR0Gy_GYgL=ITPA)yfrS#aN(^!e?B9&ZfIen-Uw?7V z>u6`6ymKi$3NDZ?Xcy$5v%>Sk?>$RpDgd!Zs%%q$ggYN}LujxN(NvV1Qy*JUO-Vf! z%CBf5jL((8{jP97*FMS}{x1UqxK zPOD*RfqyeP!SenwAU9n4>@wnfMhQn?ML%`I{=vm04e4qU_%`;F*_K$f*#Ccwy#-X1 zUE4NHOGuX>jmXdlD&3_>4J|E5NrQAtjesbM0#Y)Rw1jktAOcDXNOwthGylF&@B4ZG z^}Wyctu>3an7ppN&wZSIoWuDp)f+E3EHlxHoEyBCzAj(ke~905sd=)_d-fC!qUU}m z&4g7~Umq*s>){OyxmOzLM$^*K<|wkis{Z0goLK!|_TUq~t~{QXf<7Ue8S6fTm1Ymo z&+Dz{2BydUhz{7RlMC-}A5vNoQ@_T$6RM}P=vD*S%2>T;gpV(OgY+o=Pg3EXZU;J1 zZ`J*!Nnr-0;{JzzF=th=13HC7)W;XpPNNlsfc^`AOu8--5&&`xP?;hFYM$mOpF6E7 zBnwZ9xO}t#EZ;8Qp4NjeY=flV>Hi}Aj9=aTD9d$EIgVp$OV}^=0FPh8=8u2%S9%~4 zXg{_q@^F)Yy)o zK-x`pA}4<>9;499c=2;_5CNGAUuO^|Rd zy2?fMUeB>e3CPyD0uKsYq;b&^X8*ed;Fll|cf%L_2?%6Ltv`Je!Jb5&#~G1$8A_eVpx8tLqE?%{>U!brtRWf4wNUD?X2Pn{{=)6uE9UsHSI{C(#i3z_skxL0Li_uB z1Eg`GBOC<+tLIMRj9jKu>#z7+r(6}vSlqV{k0(P}fv$Aqa$aZ#2iRRzGLTmbEvte9 zL8fWgz_RB&^8?$v77`OszsT%vHvuAn&X~baW(~0VZQor%8IcBdU!g5f|IVcRVcXRi zzbXr;)cyFB|GxT|R5685W?Isa8wu19D-|=J^Wl;VoutQ|i7Ks8US_FaerF}%FgCHc zL_(5%aW_q>02j85q2L;d+!?h@tzvjU#wc~heu*ztid7(6wE*=@7!2*5^1x{8o@jE} zNZPJ`#f}Ji^V))0*6TTmoA9hZUTf#A)_gsuIf=z@i6NkgI^ySaI?RUWKzL;SXN2B4N|_cE4I@(#fFT;9(au%NET@Ez;N>`b278_QYzBgw>}U zt+-@xy0SOW{A<;6sqMhzEWAVoZa3}~gP{vSSqCx|gfOzE{+USO2o*;rao=Qo1)(`E z0SukM#ZXtiXDO>vm^;O=2ZvQHmrH7n*wyr1~C#c;FF{l8TOo ztFNjs)J9uBqQl{ipkDa(3tU_?-Kjpg8^wg z<|z-EIM0oVqiZbOOi)G{w5&vx9n&{d)!-aFe-?*n#U*9f7>p^>x0AEzg6iV+-aEh^ zz2r*K##_5{NbqLO=a~{;Lk9ti!sX}oG_O7jI46fNpTL-QwhLBLH=UgsxK!ml zyutp?D;p6y(rUrv6Ze8R9Tw%X+9Gn(VVDth>Z_UxT4bn1A1?&~T1jUA<6UK;i)wr` zt*NEnj06ea+kh7%Z=b`khUq-@2G-VWE4&+f5d={`<*pq53_}g!DyeyO60E08h8?`add~04bbAcyvm*1DDnNS?7P}5`|KtJAg4E-IqRhloxinEd)_+ z`|V>SzTmVF$oKbx#!sPPW3V$x+W0Pv*+zUO3kEG=zTXVRl>%M}IhS4b)#H#-NCU2R zrAIQrx(m&KKlxAW2|RHTLimm|z`w2So|tqg1ST27Oe0U~d1{}BD4pIkq^sWiWY0X? z_B0r4%e+H668AkCgVh@3b&qLHNu7e~1gY8i`~$DUIZBg;{ajI`Oh77@sY zoe(qjeq6kwa$=V_EDnX5K`jE4!$^6la%9A%#>PbSEdYjKw%CfExc@N)3zk1%>N2W! zZB?163~=bJ^>r(A`{WOWKncWdHwc0%WQ*er+p|Zymjccfcoul?M|Ao7%WfjIYOUOF zI68agpE;!X9UgKpNN(p!zqzg>&=O5LuB(@t6C{Q1Nr1!+>bvz;E>z*z-Im6TsWp)) zl1$p=v3+3FC-Q$m4-FU;SIkI-u^~8rAm5bui@pmB9)}ir_{%Z)GQh~Mo!z#YO|4i4 z?)Frx>TzOi#5TRhb)O>0kJAeJPEJ{ba~(1evLDU2nsR9O|Q zZT6NW>@H$(-*0HuC!e(k+xMA3{uvpKYLd26jt3!=C1Ym3grm zB-vOX7B*&bd@lIxaD&f0iuRUQUa?_}RPKqNx0J4Y?B&x7WxNjj@X^RmYhj9@AJGOA z*70zBS+35Y`-U7llTw8dK4v2n!^72u8euZ-brXH^cpi#JHq%q|3e=1neHi}?!xY;- zNP#bOctgI$AMI0>cF_*2jcJU|jXJ9<3Q58t_;$zuJQHrYJ9_dZMyEp?4by2!Y0hWo z)?-^VHbA|19 zkFv-RbRsXiJYD^S0r6vDs$}5P&uwb6KXZ4oBaMnPvst&!&X?NVg#Fi9)Kcr2MgzabQXU0<3+ATjXZG{jLBUF0P9*ERj`01% z)tbjoh%HfDa=uI+1qokMBnSj7@33|c*bY+W-(G!jvd@Y9N|Zgh&mbDCIdB#*^YcWE z{f94~aXq$aLx4M#Yk8;{vMS7)C9{uVX0UI&--z`Gi`}aZIt} z;Zr!16YuG+g-6RX`g_Y(dn>J-LnVIWxBCsonp1puNxAAXNxked6-vgowOl6o1A z?s*xBYnH_sNi}M~)M`S~YJjE?ZS6p}=3fN`Zh!B2G!*WO)r)Y0jBqn?bntc$t3eEo zeaQqno*udJiq8`C!9;}`DQ(uvTit+xHEGQGSHSkb@Lc)|Q=J!aV-{P(dS)PWu^uEvE?eiIL z9)CA%eAVD9rN{T&uevP5Z8CQI+b7i>%PHB>t>LKn!>m~}`=2#Rz6RsnZ`d$(yHgMp z**#&U^DqNUlu=DK-CKY9iDL4aa$D|h5zyNba4e1=cW`nS)5(cm4m9)5>Bqi2Je~V2 z(2D==-sqS2%X|69-}WA9waT5G|l z18FS11$BDn5Z*UyEE@d<{b+lsZ`Lv{xy!Us1-R*rGzOf7J7Ts?Jx`2^(>iacu+b(5 zFNVFp*}}7nHFgVOexFjI7DUsZf(FDwv`7J*{Ph2bHA?G4VR`N%+C@;vt--X5RX&Z^ zdEX}F+922ot{`OetQu%37PR9TUmJdXYZ2fD^d24f_2|?m9hCVvwgRe#LM=rSVlSGs z3Fki~Y0HtC4W2g;kX`%FA))VrVxTC4Iq-gF4O`Ry+En21H%9}5R`T90&vpZv80W{+ z+@K^xQ#qIR`#|1x^W=mZ$j<5VPgJBm`Vvk^TJxjyhYm>(V&Is83OR2G=dW~u;a}aa zh6Q=LR_`;nkv4LGMkuMZF?pzv6TZggv|NL%t$A89(-sx7BD9f^vNKVsscQmPdxXi` zA@YDF@4Jl%V74-dB;nhIE7@jw}Cm|Bo z)=mdr&c%em!T%a{Rop61yxyVp@?{z^LKcL%U4OW~{ob_qKhg(0eo#46Cz^Z_leECs z&yPf=M@%qZCWk zjN)~Sdr5EU@eT6H@YX0Yfn`!fzm){sX|HVI^(JL_u3v%aGG#!*t(3 zlFfuST1@iho3-|r*O~`ruafc_345Oc>XUS{uy7I`l@^bKF}0TGS4Vg6yAykJ2e^S= z-sN9}b9_V6{;8(F^xD!aj&m)*uFQwxK1OuFh6OC8M}D-&-qP}^rG%F=mQypwH?k8e z>~p7Xd$-iv-C9HHdfN^a@O~j&=XG*l{ULIc+~FUwyN=e&!1IWr&TEgBYsf(-wajj3$FCYtzEOk1)HK!p2)K z`n5Aeld{z~KOI*%fRA`}v~A@-aq(j-|I&r_#%hp|IQMZyj z-hMQetU=G!yr$D_8v?V{WNRxL2u#%BA*KKL`re!0EUTJ8X+1%<4?4A<+MrU7;a;QLID>N?>N)XRiG7G_dtRMuvjP zyW-^|wr2#F2ATXv;?Cc|wdXd!8N%1VJ|OTx{?Vd$7ycfeTi&?R`gE&*A^oJurSyBg ziH^!uG3m8MKn_so~&H@ynYWp054Cp=_*@Qhw{vBsIYsrx*S{k8L79 z)sLLi>S_nK>sE>Kn$~iRrkYGV&lhrJ1rW8ZAF9>0Zk($t*h{o|v_mbgzD(Uy{rI7T zW{%2rOzu`r-}WLFG&i$Z@rNBR6n!~N8hkJ}0(slrmNm1aU$)?V8}TM_#aL&M?=9oR z&rc5>^X(M-8;~dQ1GtNo#-jvHYzEPJA6*5PHlQoVry}BwkJNENy6u4y(|aBG+X}}} zW8Vr^nJ1ybbt{<$4w9?5SPt2zCJZ;FOrQ~ze{409Ita**LD_p9AFa~gNjTs|{_LRI zOYn&X-{->1_+MK|2V~AA>be$W&-zM0xz(O6VD2cTD##1x1yDU*T!RppT6Uwh%))X> z<}$RR8?Mo?eL0{>SBOBGJhWbHOTK@@R^I9K1#48J30T-9L!~pFKvL?T_(%%aBwCw# zTD(OU$_?w09?y!CpB=ky!Dx65Pfcew;M99CW|rn}=f6_16u#z5)S3N};9Rh$(27Z+`Q0Bynp8(Sb02ISJP5dfflKJLFz1T8+)u%?eMmGu)&T3URClygo znP;;*J=hT2%RAOBcM^vdZdK5}WV;)>!Y-8my-Qnu`6m)RPa9TblD`Vrrlj+*!fb%H}U(~G`W>|6Qce0sKc#q zM;5rh2HwMx^ok~9(vm#OMsAf^8~nJbgUr>aK@4m@8;J4}_zBJ>`tJM4=0~tk`;o3@ ze?>wT%p;2{=5Q7eU>`1P*BO)F|oYSQ!{3!54;lLYslYXx_#&w@uQC(&} zQitA$%(FP05ueD2TxIhhPaNH zdL@kpH7-2kMk|GHsW)4$`=Cez&00bmAJ&q|SGzAt_ATa`?a&$$;?1_T(r?f|D*M-) z{PnSG9VSEJOKDbs4L7L|h&oIS`!QPI;Eff_s-OuNbIR96uLSbw+ZIO+R4mWpyt`}M zh+=|t5kT%s`L_>;@0;jn`QdRV-|lm~(zZ>@uma`3pId9>AwSSYHf&r|`m0u$9s}zW z&p2=bnv^50PmQarL*ZEz&N66xvX`3U6ivhdIQ>t6|0pAjJ9Eb>H;`mG(SPUW=2SlVAeMovU6m-A} z*yOh(@Y!Q#(UoLn`~wjB06yhcPP682r}K&~LeV`Z?5Klba`fF!Pe}E3qYD*nDB<}H47x#~9Dk7T!vr@89h|Osji4|6IAtY0h_kbOe z;N2<$|7W+SE|P1!Vj-~fo%2TT6QX$D$>xv<^{xFi-&5;jMj_~()8fs{R^OKHq~1gq zuvD=)mUgP*kJ$dTcQsio5W8|iya^b7L8!wso^L!X>?*-#B)|=&1Fip0wK-m~Sno#@ zVN*SMKx-ve1J2-lzR;Z)B_D3Kzqn1=#i;MFkRfp=weT8)g!grIV8pn*xb7)3R*%w1 zZFG4=@bbDE>;NzcbnkiwA1<1fC`3~97QDTqkBdZjFaCB5u6wvxb>lzWSK$J01m+@V z(RdxJI_gI0^UIqzZHM$2D(#I3UMcQY)X7VnZ*GxG2A*?2w~&91LrhEzIGv+Ojo0#5 z#~M!1)R&)O1NCDpb)@%g6=|hYBlxd!7e>tRr2RcV`Lf3x05Qj84(rEv0N$v<2rV?on8Nx zy*0>x@`uE@T8e;}QR4I4J>L%&2k_*r+o<+dW+8$JFiswq3xg$eTWi7|rZvN^ov%q3 z%c97?`eS3lH}oiK&|)pzSlIR3=!c!T79a)|xQIL&w#az}XdZHv45b!~+5ElAHwc3z z08VB1Oc^c*`kjzH?Ebav#1oSu8u5gZHgEBxOkBs_Xkwl#-3tdT#RG*hoLfHvMpBMC z2QzFV0=Bi2vZX9edl(+M>Ej`PIP}tU4LZEqS)VMtb$mV|>yKl(xLY0d)v%^WT;+-s zuVdPHOa^ri4FGzsP?P9r);zX}HW_~#b_m8%VwA7kpy*%Zjo-J7q-^TDZ$S#oYj>V? zDX(bptUz6$#&8@+EZc#D^fNntHI4f&OY+!93Kw(#91}i|)OxR{tJy(ensCdVK3f=E zxOhbAs(iJV4Sip>T2aN*6w&WB=D?-c9{X|QthYSiR+)!25er*8TW!wW*K{Zb6YIUc zfY0m?=34HTIvlOKyf-SU8k;OR!0i~aWjj!?eECW&o<%1z)5^l;Gp90eTKL;_3aB8n z=_KZ;kW2Jtv6DxN@S*=N@!cyo)l&Ihu(NvRvlAOJJX9ozodyZ;|%QaNY;*2TKZ9SUx@yo{~&-Cn};@heUd&H!dMZ8waSKVxOFd%Ds1T{0i0@JBaq`eIXL>=;^NG7`{OxD+BCOc(qVcK_<-O6|0o8BU3q?pCBoCUn z-?V1RPeJ^;j_$x>!@`+nQ@M`W_TaQUsF+gbU4|hw^PuOA@_08XsN-bo`Pv;F3SGIa zjW2?KbxIXfb5&Fl;|C^6LuKR|oPIx(2;`^(M1je7-x-V)<9{O^_9#0KhB_{WEQ9l* zr!o|%>*D_r*E6HLFs7eC$vBQSm4xSsZhn&5iM+<5m+6E_z(@eC&9UeVDD}$BB>8^4 z*c9+;Y|2P(Or00P^9|Zb0{2bMzF6!YiflK4PMYR84lRv3uca_^S-K!0P;K^@Izh~n z7f?}#9c)Z?mgJoEGB(~UDmwA!z66T3)#tkEFD;39iQjgZEY?*b{STqLi z!!kj@uB2`XIPRM&@gp1N{S!O!#XS`#8r(uU8YN@$FS0xr7X%U@wC%JK_uV4Xp)HRe z(27%ZAjtwL&|g)8ZN#z}qOV^&ss%oayB1$}U2a5MIIxKiEsNf!2d4FN`+#QqM_yxF zhIt}##H!A352vu^Je+dn6a%Sz>Bjok^OUW|(uE<|+DhfB%&dpMw#9tiA!pIrj-A_& zd^p_KU_J137f>|5*UI#e1rfM*d$6BD@$puiz9lf}!rz(@EiTz|R7<6TH`Jz5qG=0XrOV+9< zW|RMNOstV$YxaxoXt|i@hEz-9PQ3H^45j>2IvNn&lHY3fCS@P=9C19~2RXfPkjk3< zl#zp=VWsWMREa^5vL3EjXOb6B*0oj#7ESdHT)kt4zm|C~MfN0qwgI(C3L?Sb zf{W*^0D`jI!XM|pK(*0b_aLqvk_%E|)|7$R6hNo(Xlp1Z1R46ygh0@ZEa;Ce+<|Bovtnpx5{k+GqE0lM*?nl;3yO)M zN>ZP@s%sA@>@WvSAqcWolzPD6K@n79;mjTk+Le(3 zXUAT9zbId_-$S@}1}go4#fGFz9k%Zr=GypsrvWJ1P&Gt_heUKkoD%xA9z10De0wiiy?1rb~it`x!u9paU5!qbBx$ z2SYdA0)C*&Gxs?yNHX|e27SDcmIm38CZMMlZbM2an)O{_<f4(xzkEC{B1X|c zhmvK0{?WUAe^2Y7JB4+TXZFSjVJ-Y@QEmI>A2zQpqb^`%qG2bK*-X@lSal_H6j!@C zh7`oi{6Hh}up+_MFMT9PTd|xKNx0UJPI-?y_H{)asybSA^kB9an`>Zyb~K*JS66*6 zK@2Ql^@TrP8;I}@v&lYqK2Dt)B_wgHW)(5qR% z%ty#$P!1}kpvE?hrZ>{S;wT9?^T||>y<#|c{vhA*MVFMkF;$aY|}P{d51{?FW(&P6EF2En(gR zgb4QHHE{p~(}YD#9V5?td+WR9LHw3bL0e%OirX<&VFUWQP%v}#>u7=LR_$q1#l(Tp zhlhaodWAKDa#{gS8Fo<!o8&Nm!nk!4eb&zMLA9|^Z0W_GwdcAXUy$Sz2gz(V#wb>-uC zMVPS145o%xo_igggTB7wNYuI88Y*yYkYH`GL{ly1Hin8slm|qE}x| zPCX0pUJX^9hA81O67{kuNhe>4B^}>=owS8*;_nkJlx8~BKXhf_!#A3h1Gh|PntkQv<8W_m8n<|D+vz8YE&f|| zJf;JcNMr{x+wM)?NfmL!5pl)pRu>9DolA^mv2*|f;fCil4xpZ*tMxe2HgXw~GV*f- zTQY~0D(N4Y7I1ub!g+3L|NV9&vS#vhh#}*KO9uw9CUAg)>i72}0^_YUn%*`6HkcPM zILq)&-($0z1%~Ygl}srXBy4y5fZTduca0q)?j12{JdJ)iGZ{3RV)RTzEOU5?6FU ziaJxU2OK{G?najUom=egX?#igqza^M` zPj}MlD63E<;d2fCd+ok@sWUBuT-%ScZXav&E(@9wAZai|LM{ex;y@>r9`-+%V5mR+^}`)v5Yvz*{hBB$5NY)+ zGPIZ0#(i`NHLH7}>*;!jG z#xhx81Y=*TH4|H$-mfqDWmSi#A967|1oH*A&^}+%eE_Pb9ATS`1t^W;xf=q^TFDrf zGpnY>K3!x+pw(&md0{RQg9fG@j0_!@y48W)WIE$(zLtH7K^&`U7&eO)D<};D6 zAF=Fh)N{L3lKIiGu7cQu!5+Os)n-uh56a z7MOw#TX*WzENL^W3IAi_PNIg}I?_i4CJZOFHg^(l@@ggov?8czdXb8oYxmRc+8As;_t= zplLRz*k$qD&8U9w$_&brYg8R&y}^x^Av_{^t^wo0;?Nu$e{$^(v;OAPI#H{4x{cvj zR+U}I>xw&3)SeL}OkOUY@fhe6z6*}=65ov-H(Y&>HV*2C6NeM6tpdubUE|NjAKp_8 z5M{=W@Wrbm3RFxdzTKaq7e5y>+j>`?qoG~;E?FiL%Z038&-4phU23P-3$$Px^{LNo z&f`Qo-R>;gm_D1U*T=p6o&uA)j@2afTGnG(||#eE0NX8Td0L;v=cWe|BRw@?_uJdr?IrU{Nw$q=z} zEiQg{s`?y#JM-xbJXm}g=2qiGPZ)O0goe?Z(BwNFBAA|2)L+s+WQng(8lXBraP-yt z+Mf%Sw!>mV+BmfGn~)$3Fe(`vv%j}F{bG>5OpSRL#I@(UU%wH^ZpEB~*9t7rW0fmR zjh{G+daqN_i@B>(X_jUw-TQ>>de(a}jX!obry{4BWOn=X+BA!dT3o-hXo;i13LSa9@K+mKpnwCtS}lA!EJ z`jkmk3VoTGR4{dolgoI;2Hm*-rpnE2Rq7;Ks^?CDXg{#fNzkANF$)@LYX}vl96CBN zdlOm52nms^tkrLb}WatU*25&?b7L< zE;S79^wsLKi1l=rv-thFJ6Z{)+1q7hxAKCa%@YaMt1;G8Gai>aNE;`i);f8Zf#k4D z(v!!71mVvk$Pf?6%v3l6+2wzURDnJQfq}s^C5(=M#R$p~fQxh>2|^&Bxi`Zy_=1O= zqHdzyQxG7)xz)pkLttQmk;Y?%ucgku9D$0q;KC#rbu70#C^t zg38G#N6aXzoYh38^eSJ%9!6X*vEXO5YW)LA#H}~&sP@xk?>Fr4b65oY7BUk>@cZ#R zuxv~WUX~B%OJMNkR2G5=uT|j%DHRq{BzW!8W7B=-`zT9d%k69=U2fyk1$iUEGk?!F z5N60b-+>i9hpT%m8Svwh_g!q|51I3 z8TtM*DI6R;I(D!dE>6oq2 zTUlSML#O}zGIU&SLkFSYDg>TpKwzBZDS-61fhS#(X$-*S*@OTLa42{srX=F^?J}*1 zZPAje<)(a|Zf-gJK$$emQvwf`Jh>!l4U%1Q)_g{{xhAWxCqz;T6g%nms$!?|B2`RK zaqChi(s#*QGiqL+jmu+?gYT7B!Vq$l%H9)eZu!x<7`PiR*PD#Dp}z@9*D({({M- zB=E~qKw{i3$^Ms9GbW;}Bp(<4F~p{KHUPkDfQj1{~jZ`Qxw|9Jk3TqL;|&R%hnu&64%8}9R{(Q*E-%C*kgf}LPNiY6=O1{;>lo|EnG4Ke|_1QTStcG z-vbjA6a`5E8U%+aIR6C>T^C^kWbn)zPQ&g&c{f+DSuTG%l8ED%5f@>6ji*ipf5Yf? zx2?D?%ZaQdD|`T7f$jP(Ay|4<+_4}2b}OQvD=R8El7a--Py%ni(e?jU2tA_Uh7C+* zqQMQ{3u2>q11DpPzDJlhbN12BmK7*5H1aAJrOK5hkF%l-9fItP$CEx^tkVrl>ECGR zD?X)WC&fO#-E;hyKLFe)AxRZ#6^CB5(ImRuEAKdt#ql~}G_BlU)dSwK0coEPsSr4n z{IB33?wNA#dlEwwmYm6&p0jlPT`cbAmXP)bX@Pw>C4KFYv&0} zS`53Vx4g8~PvNsoH|~3g*q-~UjIOZ#%5=hrVsWK7`Z^=6$D1ybDwV*~Jz|Hk26dyA zA2rOB`<-&2QY)hm{W#*56%Oj|cmM-W5g13JfPcQwSQ*DZ>#6x>-$7p`?C}o21Skm3 zPI9`kCG0rqExp{IeQnZc_`P2)vc^rf|CiO#*Ybmhq?RomZM(;7>>Z#%g>t9c{55NynR1*sey_kjHsZ+#<`aBkYPEAQ+ zdv6ld)WF28r#T$2$e+pydNWOBtnRi4>(H#m16uasf}$ zS%*`BH;q7=Q*dax<71L`r8_ac*iP{<+Wn3z5}TL2<6}!gd^HaCzeoQHiwJxdOTO5% ziRTvGk)?9#CAmA)d{;Y9UnUpfLrkmwYLPp3r$atV0KI&n(iZs@P8xQ#b@0qZL)4?- z{51xCU{_2X-i@Gzo ze35}v$g%&I7E;V?#2H4(KE6BqBEsuBkcFyCag>O*=yhSoH2XU`ym{5V*B$N zt&~N2uRDiUwGp1dN3Y1QqMS&h8rKk4s(jusWYU9CL|gNvd)L_VZVQn)>c4DHWefS) zuHcw?FOF-Ez7XY)(~2OKU5h-+pg^AY*GO!rDf%0+l?aiE$#w z+uQCY#9{j+VOMUz$!LW7$saWpWB|;S_X=b#(oHA0M%Ab%=Xll3*9Qv*J?F@Wygc5;-_lhuB z(F)w;M(S`PtXN=>#y`#ILK7k=u0taN*wtR|)U$->LNc&EdZi)(GVCb;%o1V9gA0P56z;mr11!068DL0S7xsr2`o6a+ zLp_x#Ng%DU00!%;KARU2vdt~LESl+>^3(L{u2hA*8`)%~4m3v#9h^Fp)^Ait4(OB# z0!-PqF?~HV&m~6M-Ep2L%CNG3r}UO>-OUy4T`MFm z?P`FL#Xwi81~z_FHJN?~<2D zH`U@MS8s)Sq}H%9=v$FuU%L2UR1?kk$;x>6!BEN*uppgh+dH$5SI-r*HQ>0 z_8~+t6AHFF=t|mOu2k~ZpM5x8Q&D=JmTfMhsvyyC ztV~A==O*e>e(ov!g?v4 z2gr#aBqwsj4*$wilQ#s6mzj~mfr2iOPxOB_al!qP=_HYFcr~{T^r*&hDhNbjYOj+a zDd76D4`{-k-=D?lsC}M*bF{gInf3L)0dIhF05O{iiTd0C6#l_-41{wJh>nx9eSTz%UPI7y;WU4DF)eZqI)pRx;${ zG=Y<|BSfwQl=}YySq1LOFFy*`dmSlX{xzPWksmTzaYBN9Yl*3dOCc_DZ=^q_KBBOq z%wu};^9qOmi1th=D~ocjIkxQ!HGz`H*AUdt1*}!>NxIDH*Qh)j*-L+ISBbFm9pXba z2Q*NvxI9SvL~hf!+B#En)6{y@jUNHS;0U-dLsY;OM`PfD`-Mz3QgDUot<4%TP2a($ zRnZ97V4{<}06Q8BfBzD^hOdYP02hG;wmUW`{Q7^WIu`I0P6A}Y<%84mxpx=_Xl642 z8+>1mdKw)OC9C4)15BwulE*bZ|!JHZnFbL3UexKqLjCp+w^3K(qQcQGL zuD}*!5wt+Gkl|uJz;p+r$Pln1YkMc+;>lB`$%mYrd5|`B40k9SdE8lqsh#zJ-Nl$p zQ214EG1+*HTlXU|J8HGHvm{V7!^A7bg1lKkFCUftyqs##$~zYS8OP1lg7E3 z!oK8%p!_Ff_fpZf70dkf>@Hy7xAFBicEEBELIyhdxUUnkU)BH&?;!HV+F!AA0P?^* zchj23wvQ(2st--UWC4dSXUjQhHoHr`R4ahL{TVdXYwN8tK_#1G525cemnw7>tof+;61KdcK)4|FPsU$$~k_DRs+J11Ufek7UY<5 zZ$1X*p3Z$Jg1{pRU|$Q#$V`m$gRGAzxT<}MLEl9C@IKvTmPq+4)_PH?y1g;fwg{9f(mI@|L}Z8DG0PUge=s)K}!j_e;zyF4^;TZ;?08NQHL_ zuG>_LyYd_HEMsQ&Gl9_T7)IV-UH5l|UKeT%6nVU#8wShnwSR2(__xfy0Ww|k4Lb|` zCr<*eTj6awvD+|EcS<7!5Uh8FC9+05Lv$n>PtdmGXYMw?-^@|Zr?Qh)>bD(Xx5?(C zw14=U_{bIYR=8dLb?aRYbR8w$)*~g}5x8ZGExgCKk19RFl8-xYz6Iq_@5S7DALADU z@m>8$kQ|}+1TiyB5IPM7#x5RSkd%hAL5^NM5#;D~DZ&lqW4~y<*I+iNa%P_YmZ-%k zAT~+{2mRC1pqurkorTjUFp&7YwR$I`hW;y=f~T;t#bC@!OSKyfWtG0w4Dz6fRf!GU z@DEoresGJNkn7H(LMhAPc~s@%%EgAd{j~M{n$P8Q?8ag;pg5FIQsrPkp`KRW&&V}- z1{w$5rt^oKmH>%E3ybrZuxaPs7#nhz;b!Xf?)xmqXZ~IKd0K^a;yC^CCGWBy?;hI1 z{cLtLIf22I?9ly*37POxae@*nt~s0{@DtWYPR9=TSY&<+Qu^sz*e$%bv zO7C956s5N0`*6X}(uTy$-~`E0VSK)TFA`@2K;#JLbOBs>E&u~{cGX+wBejG5qt=+D z3geVuiFv!<$7EC7&Mf(cvf#yzBYIJ)+im^0wqS_Yv~9_!bDw9ajoJShbX9g^sUA*4 zflmj!dgyDq@4bq0p5FLuJGQwsv(rbBtErKsR`{$Yk>8c5yTMGdCLagry#q_j{Xh%uJNx0%`!$)$!~OU2m%B*MFqs-;KIOGM zzW()X{JM9Ny9|6<9_E2|U_a{{9yo7JPLWAPRrH`tyb|7*W%DG)xAcX?w0t z%qW@pvt;eW>Onuz>DigWWcGaW^Jv6NEHF3QSn5ZHD}+EH z`+zHa-=_KOj;h%Colac`vh?fEPh&+Z9+^??x0fx>8P-va2OjDhX+^?jt+_MP!d1!U z_v~~t*#vnuu6b^4yLV8&3$zip%iewLlV)Nv9llNmx8l)PM4jAi%$NIPOqh>lOYs_4 z%ZNnj#78kEPs-tuw?Gj2+n6xA)6^Ftuy?f*2`AqTj4L0wwUOC8d6*{-#H=phEYeTV zpS7mzB@es9h`*-D!xg~Mn9ikh#waD`(q|dtY zl%_hH9q}n7C<&Z!7eQx`6ge2;#fjd`gU$e_+LPZhV0BkMceIL#FpZzPIeklwvo0fY z+c_Swt#~kRf-P_qRaEw{Q)R`YScfPCK<@PB+spD4#rKs}ur5p=fX&hw(C?2jf6=T_ z%z5bc^9B=g=?Gwocbd&Pl8uzjX`)WM^kF;h;{N`cVND=PGAt~t7YxJV86?KVeOK>$ zU{GguPktH)%rrydQ*!Ft+vRV9{C(UlJKcO87FMM52QXkJ3~<+2-YUu>Ac1qkpMvZi z4Bm)y1s!am9q@Bp2#3BZTH=LSQb@jJQ&l-Z-IrbN%Z&RB`QX1)YkLNbFU<>NAIjlKOAe-dx@bN@FO%gukIlTPkBbTDPxPrVl;1-vt z3RI8g0X)?$Zq4cb;MkToh9`h~yog5vT|S#<(ZyuO2tab*rB9isu5qwK`9U&dx6~Y< z1GM&5bia9zB~o3SaU{^Eczvg@xPa)n6kp+{G28fJmQeIBuSmr9(kE8%4{__yzHIf3 zle!;mHpyRYUIDalD7vZ$;$go7AyX1q$P@(9chnGi2qs zkHUi3NG*Y?{gI>2$i>4=z0<`G2DQFR5^{R0gNuj9EF~pXwvCXduxm!#XL^M}rD*?b z(qQb5wpBsWSQi^r%Yp%z{JiC{AqaC!H42j_2(qxv-dkW(??EEVVGs|7z77m-giV8OpM z>$2^YWzmOd&@TGn8OJhQN#U{oyKs)3JS-ADZ~|7B;|>c_jfPq z5Ecu~+(~yFxKnu6 zWL@`;c{+4kyr?PGoxVHu%j4csh@<8+g@62Fyh^+B$Ju?BJ#FucfGG;cx{#vJhX}mR zAIKuK(?g^_8n9EI&BifYbN{0(U5tl8j~bY2B_R>Gul*xmH=nsRnx>z7VOELQ<{;)f zQrvFeC~mYe$S4O;4wr+0Td|YWK4CAftE#Q&@?{7Wn`)sXQ{=s0X0|UaezH)gd0fqO zypYuL_^1!N#$z4{>r857a-pXi0bY*6i5-FlGHIkAUqd5h6D<;5xQww6JPLD0_QD^{ zCw7Ge6kpmQ)#J+uVsY`-+Dbsdyw20fd}b%~lzHI2Udk7hTY-x5v>TzZuWY*FME*a@ zz66}gwrl%IgP~-|P)erAEMsP28!~TX9zqBqGLH$_Nais^wwcUirVJ68E0G~0Q^w5W zzwUb8=l%Zgdynrw{^xLLZ}wx~`@Yt-uC>l}u5-~BJg{WN{v0jS*mj>ki!N3u?9>wH z@>cS6ojZOP#pr3#IkWF>x$6@4b#Qsf6Sbd`F5;9H&y-GBaNO^0v?sgWX5ug7PCE8{ z%Nuu_d|rJfyFiA%!t^p5)11PkTNaSSZ)3stT-bS`FNAy#w<3m;o)lfp zsYt`_`^7U^!Z+1%y3e)!$hj)gE~DQpXT^3Gcz*=hPdC&)2m=J6S45%i`>BKh0 zOnEyIRx8Y=(^>HCP`k46t&?(#Gb977eG^%3!fHLD zD16E3Er+q`UeM0ijSlMEq>pwx7EhL)+q<0iqBx5o!|v=pd6Nq5gn=%HA(Q3Ekad5` zXZvx+DI<}_w)>VBLsM$Tj2P?WLER#cD3gMi<6sV?i#&0BNdl;_IVrAv}Xma@1>R4`)l`MqVn3 zAimVH@P_)oLrU0UZ6!rWzWo*{nLxg69m))Il(GzJ#C=;%g%^V;q!Y{~EKg4gVTO6Y z8GKd)eL$<6sb#NZ*Q=24k&F43qAghDw5mhOsDRqvnr}Mc-$hM=hI#eU^%>zBu-ScRG82z9)5FofDBts9raDC)~({u+3t3h>1t_HNhjMVEMbBqaGmhlgTSxh%Q z4kuY8d=7N#Ic4|`tp>BvKnV-WKRn!?&@9hhJGmfB9ud3+pUCZqV|9A?kw^CaR*{pH z`T(V|7u}gxqp|n?u4T3bKm1z4dmM6nxV^=ZrLe|9zS@0TsLY~5$5^++mJ4D_|zP(V4YRQ6?%>rZ)1CrDLOsH*U}IbwgGH z`py{=#{7=DY-4bq(z2>qU6j3p&F&tzKP0_zpx?mzbe@&zjAotBBUYn)_RYCh$1S-9 zGBL%@rq6tzPivVRG_3u#cAl9S{fd5I<1~gj$w>U%Z@+=%058(-GSBTmjER7x8IQy& zA7|Xy#<~W3co$a5^X$L<-bp#4mu!^9eN*m=ttGGUuUwaI$@Nh?iO#V&Od?auzqq+P zDmQJ&fo<&%=9Y0Js|>N-eP=%XLV^fIRuE9(eS$vZ^$<}8E`r)1Uwz{6)=&8ZAc^cg z_fHbJ3kej^$hz+9xc~aWc+|ixrX)iar*?+us*>&3g(hm9{NsgBY$2D24qk9%E_RmZ z?QmOvWY&XOhSZ{NYDGUVnDw8-y!kLJ3+;Knl_*Fxkw@ma6^DuNRU2=8n{dY=*eRwj z3bJqmbonN6M+>PTPK_?ThGjRZPe>B5wXX5QR^0E$S`>>Bqsbme{D#qF*wI>U%-5bt zsU%Yz#%s4Gx~ORID4NVD0WN=`+$D#3sOKyZk}}rizVuWLU*F$ zOphF)bqvM#S9;|qlvA^g844V~nFSpymFFDNhalldZ>o5Ds-a#;J**fR%OJ6D%eNOp z#T_>v(f3=%JrJ_`&Uv`cJ3rw~j6OwGynlkEZ847Q0#cCmyAK$)LWPcn66q;=8F-jk z;{Jf4zG>@A*4sDi$OkaUf!|R%3dpfml)=8 zu!_&;IwFb|w|TGRakL?{IgdSdRMQS+W>IIl>1DL{^nhpacq@fb-$Jj>ChTJPhC7Q3 zid$cxm>FAO zCiN@=;NtgGV{b15Jqv;HqSedxH~U`E5nu_y{!%MH0*)^OxB`hk0lQIx07sgwz?;g; zuIedT5}5UmwGxjF&hNGtQA>ZoNq=Jo(eB!ptl*DtlxSkC2C!n}-SIFzt)6Qt(9lE5 z!F%d`DR>e2i5X?KqW#uTRXLT3Y~RmCP6e1|fA?;Bg>3uQY8}*Y#eSx!tO{Vx&6E6> zApR?lNdRsXBo7Dzfc@lXRz~}c7%uMo7en^B zx0rmnWhu~~myFm328b}sr1&es(x|nf&DIBhU}FS1mV-RSq#J^sN52pPLq<9JBLy0! zBukoi#&A0Jj{`e|Mi)a0R#n( z4)?p_vr=@{XS(D>Rp%dSq9(_5&YZs@kIayj!a&~=K7Q%mU2#B|OanfcLALyWE0B>S zP+uvDFBp^zElRmjWT848QJ7|a8gVcA+fmm_N9DCUU-|Ax9^b7ki)t`UEh8N04@IH} zy%p%%R*RF0osq1xHi#bKFP3}Xq^v~AX_zD3t}^hle{g2;(e?A$6ofXwqN_(3DJwd1 zRutJpoqYCV!7%w+`j>?Y*`4g3!xUES0=7FjeG$@{RSFJ~#Y4G_VX1=gT7^4=^dU-k z_}Y+}Pbt)5{-j~wSYh1^WGEaYZy_PreP6;@UI6D92{Xk~;7y#h@&15wNqLxoOy>(! zywj8fsh8NF3Ro?p@-+*wq8~2MUC)(_m8Cb%LEBPsI|vr)mO}OQf4tG}l#c{}S<}0x zNEoMHw53uJqkpDP?+IInKr-8q0o$w}Mw^G7=~2H8@&2<;K{I8PZoL~fzy0`V?h*9s zK-W$01p5Q0{)qRfVj_ms4<#GsF*-NZUs5#BRcs-mP@Zox<~?snz%`Kuzmzd-TQX=Pk&eRGo>8{E_+(H4B6-BcqB zqYhHEdW~K+x!a4yP3i?&h3u~T)ee1FM?Znb>dC++padsosUFYyw?Xr8f z6=Ikp%WBZVJcn#255Uf+ny5#)iWOn#?dg+8_PF8ESrX!I;w&23ngX$dk-9Xg5|IB2 z^PfI*W?<=Sl@%b?t=ss=+aHqL7+n|q@WKC7G4uKy`qyq>zA*XbZ%B*SL`<{qD(wFe zeO`Tr*BdWCteFMnsm%P<|4RMS2%qCTCTYDBbu7CE3782kzBbszlyx(P=r=3? zv;we4Npfz0%fZ8I7Wvfd<Nq) zQBJ&h`)anjdSac^`B-L+EC1nd|2Dzb;0L)^{V=BcvZdRsC^FC6HLp|k=sRIBP%el- zwUP#}e+zm6L6Gs@R47+W8@;VEGMGHrP0(=oE<|>%L=O5QDk;K@R|&L@n%vgt&3lq{ z$w>mg>y0c0cI~FmJIxO`4EzK;f7;4GK#ToibS4Y4zA>*scS=5rvV0#F`2!B>8Wu*I z1Y7hZ--h=Uuwf%dre;`tNRR}t9~IJ?Xr2JH`rr-dH)=bt2qR%{<};YvoXQoDuQ~)HHFZ7&vXzmqsds1I2(0Y|)KLEUjRmHjt2f za*Dp|(QKv3T8nxzV5#_$fo;@-3}uIk4sMNJ#w@NyQAKM#8ufM`{KDaaHDEG*X4llu z4}0?4!tE=AIYgy%*Seb^GPO8X=3V$A%}b0HePp5qif?8)XEg4A(Jeng!8Mih^>mi7 zixfA*cd^p|JX&(NGa;aduVu_?uafJ^C|R_a&m>)&YD9#%*Ul}OUs)M)L@Uv%^*dya zTSd!FZ9rvm8{(MkFZaVt^>_Kd{R8;xAc!@=MKVY_h{0vn;;;S(gc{Jv$zH{-o%l~s zW>7u1(h(>P5cK!ZUPZ+pY+3vD8>NtC&gA6 zgoK37eh?B868s4XAv9Y(`Tlidp7BC-lh85DJ8va=%4Jxq$tocHtLp17mD6$OZRiPx zW`g`+t{BJ7@AezUrKW+&Hlifo>p|~bQ>Ll zPS9x&(PJnIj?_HLF?feh!LvNkWUpyq6@MWM(|qi6H(e#lV|lzm5z1sYL*8DB;{Y6$ zvD4q*-|G12kViy=B+zVCH0IIWBB)VD??(#H4P=EzxMhk~MWV>^K73BhA|5AX0^@h& zx7?eht>-7-v#p>GgC%{!gy)z z=@w40^lI@RbyCa2HGz5puhdErh|DYjdwc_xbkFh(Xny zur;K?MWX+}t_0y$%^kP-EIY4o*RS#Vrn6S&_m#G^=Q?a=V_*4{@9}NKzolP#g(2C49??kOEiuAxr&?FFLbCe@w^=wA*#EJ4nKk0Qag62rxWvEXs+paf z)2dmHlIB^8f;LD+_8dCd`e0P#^qvBV4C@tMi*wE^Y?%~5iB!lIg`f<-mdF@Rg}Z`cO=_s&^Wc$Ey8|t^|{KxTStWuG8U8;OW>-Pu0@_f zP1zUz8JG&o=Qu528XEdhYb5w~CmUpUf=KMRFjSmY4H|Yz@uvy&G#>e01+s>E5=fjvF=D5fUqOsc7(8|yQQ zQ$sQ{oIJSaue@Ao+*i3;#(VfE;?0{|y6bDdeqE3(a_qctmli%y4EC zYiy}XVICT1oB23uPeMzW4g1Qt;n~qpV=(3{Nn71AS0z%&v&CZmG)jCs4@dK;@ldrGN87h%Dfq>_OfmVUaN zGNjBnzB|X1F*Ky2oWAqvr(?D7EioB(AV{3_`7gfu@2m_a;=p137^&4#|L#%fk#&g0 zG!qejjZ$+PeT|Bl?M-`e`#Sq;Xmsg&&>8pRjR@<#jtI$*mD*=Yi^2LE#&r{HeHsw5~VlAbY3NM%~Pks!-)nB zB~j_ia+A%0Gs0}zMVXMgh1OWSkCLJ2-Dx`R7lw3r^!5@ZHo~@BRZz0dz z{_y)dLWOAAfYRF*?>?!}g!F~Ke?_|Ye0B%qjIdmOwQkju+z_BYESKOPJ^cQ@JaZ0(>J<88ztm*6al~J zHI8BK_8zI8Z$18g5;E%3mWuEeFi4i?A54$ zg*{?D+fpBn=R%lQ!(rTLV22DC291o^mzrs%6%TZIq&D;5!F)~&Pqu<;u9;aLj4h0mXS9}&*F2ZiIDCU~eWe}({2J-WXm>l|kZ6uP|zE(*R=sOog5e7%B5euimW`uZ><6 z@|esLSvjSN#U=-@Tdy5nB3Le-jxS@F(>)yM!w0vJie ztv}mJu_v$gSD52c@p$CR|02?-R~Tb$W8s^Q$gQ&;lw9wg<*NFQs$QNDywkZi*ml-Z zMhHd5Ali|DKt?#HbpI@`GCacun>W)+LbK2<7~uMobCGPN*zhTZpW*K`LJjc2F5dhM z-3w?p0|m)Uk1^}kW_+43eF3ar1}=v0xP%eQmpgz_2}mY()_$NT>%Kk{`PG5`z+3PW zyS^e6NEp%QN!sv;c$mPh68@6>FC4T{q*!`F5RS)XQG{&gBoG3y08J*RW^P1xUwzkK z60HZTlhV6>){2BWS4{j`2S_3@rh9!N?KckJ`TBGuHIbyz6vaJODP(p&;!hRy#A;J~GKws~&()4JDFpny*gsv{0T0u37+-EjFmxU>F z_%2I8KtM|U+Ggmvn;fA{dtbV=6^u`wa)eOKYP8yczK{$J=c){3cvTnaAN}~SZu7P) zo+~h+SxO0@Od0Q^lm@5U$8?!(e=!BJr>sLW+OE@od)(;AP}|`*wGv(Ywx|I|+J2 zWMqpT$TPe8Ele~?5MItcKI1azk?fl3J3b%aDmwWcqGl~udfk${e(ZV7GGzRp!Bv4? zNgOEJalFfzp#e8l?{TrN3PCjt*=!ai6MtE%qGxV3WELcE+Ot*lxt_?Hp@)zJBiS%F zG#o86MzeP=n^SD>{gPmMeUE#cOpG?ydjKr$q*&Cm)5YlG=R&y}iQSL5?e6&|37J3Z z=p`_cobhLG3W~l=n~o1Q%U7y&@!IdACo}?Ln3--x0Q>C^ZO=^xXQjBo^ioFmHE=0) zAOH4Xu#+fzj9xDI@pnJ1erSG!9G{s!9w>kB4&DoEQ4hcJ25x&OKk* zfR(YCbihM7&4iF)2Dc(?Wz*tSE(!(zP)cMdQvE}J3E}g({{liZ+hQ8oKiM-xX)lqQ z{y7^wV8Oq*gs|XK!b~B*v9E?qEPN~-9E=L&lR0qUB~)^crJ!`_=t*Wi6=;)j8Ht)- zh;qS;Adr@pe&5@x+8M$t@wl5O%;^i8zaTyK;e+wR0Gc@MtDUf7L*=7Rw#s zf)J`+Ut*)_fhv%WoqU>j!C<5PRPDpbC-RE)1fguyA`21`_ag5>z73-4tnB))Uq!Z>me zuY;CT7eb~pCRR_wA3y$Uq|UWip3T)hPfK~b@RsmZFGzVr-BxeOi?AQv{zXa1aZtj9 zz1I~NR_&`8q)t$A4U2m1JD&J7P*z-rwZi4WSnZvkWi3Oo^dVG>3}cJgBEveDLn%5d z*|9%Id}E%5rztar?hQURqON#++3eJbIwadV8*RZl3<kVa-OdC{3E%8q3D0 zcSzm^*Q}N}Oqs`w`a*wApk{3CCY8KQNNncUD!aaA>K9hs#!X#Af+od~I~8(Fy?Ba% zup_QZ!)XLNl<873AsPm0Za_rJ^-w)SAF}<5(E=JXq2VbQN*r?)BMEGHf=C~sS-oh3 zz__vJ9)XFM0xWq9U$Uw+${{uVx(xWPRYA7Xn%M>MMV-=H!L!mqz0^RVqtf6kXT-iT ztaJq@?_sHw)9h!%k#aMx!hOZ#?RzW<4fF)QMtY-F0muQ1wVF*$VTK|Z zt4^!&w!4)9KxrhKMG*W0fA7PYf9kiM;07;#21=puO|CzQfeayu3{?x{lDU9`scVV9 z5bxkL#K@y2JwR_I9e@c1<<=g8%K{G~ew{pX?&V}lP?!6R^q6`&_`3{x1vfWAau)Rf z2!@!P8GAIcmFSMLeZ+q*>1)0tszS=#mn%0OiVu}-?Az?sHP`8mHhRAxpyXu7VRJ?8 zuC>zy&j^Ss$?%|aciu|L29q+Pg850z2eXwm)1^+!6!hK(4$Hc;MMnf3AIz2SC8U?n zQhuTJ^CO8Qe|Z;_eHpHv1xSR9(^89lWz_-1>J;KRsl%xF736OkyesyEM^l-~Br-Mn znA`{J{_a;Ld<-bW!RG7hy5W;3>n)Z;c-pab3q=@{V~tu(L6|xU zZHDBv{bP==&VN41c^{36JVho>G&g*eGz524?&6bLxSzjIC>g-eHg0F!Z=UNt9=|`H z%}Yqd{r>(J`0LlhY1A7)%=sQg#=BajyEUB^W(7xLk+6L2J9%;~f62h8b!)Z{S&!I9n2lm`U;1Qs_C z)+~|VN3NT7(X!a|wfY|?&r7B?lfz3KQ! z5oma5ir|X%6Aqjh8VT{WW!6qJNZT|UJedYj*YnKqJTBJQM_6?#(G z)mK#*fG+l$8CxPqyY!^F4)1Wag-A;T=)Xdrij9p8jwg@5fvH3h_6m0-SCY}+k0CKm)4tGHr5MX9!>)DjLqa5+ZOZ&MpEJQNhw5~W>ABq`9ghtN?*P8e zR`Dpw4DduV>sMM|o|A|v?uG>Sy+GL_!zPqhZjZX`4FpTfcX#c_FyFRQNM!1BnZYY! zJx!JeP-pO|o^fQYZx%B3e_U$`riq(0>zK>?Sdq1MUL~G0HHV<>S4Z@b+2;AuMU25q z#aD;>L<{3+u2tWOyz7U84=dKozEoy+U`K6QU2Ngc%i6)f-)e*<&6=IrUaI(4M(i%skww4U4<{D$EZfJixym`8KYHHf znlUf6xt&9iGLP!O&v5M7nA<*ir&vElfwJ$oJKuIz;G@kg)f%JrA1PMtKd9-O{w5f& zSMr)z&h5)CO&g+jo?OE!T@s14P)cA~=rQ0+!C@2JzR6vqaSa=Tu(#X7d;Z;h@faMV z9nh5)4g{bK_IF82*yX1@K&(7epMe3@D!nKhSo=(jz7vRTA5amX6sG|?mh&*H$%5$V zM6GiuQiA*#yFO{x*!MT598KNBOyd&ADGN!3m`_Iv%@eJw2RC+%eGdbv(J^YG%!E)| zG?gcseZ&DLYWy$XvvBJ7-gYQq=K%;KQfnF0jB_fK*sJ8)yC%!e=Vxr1K}{wXhOlAt zdFeYLV^*%T8KQ8Y5_ljFyRfcp*WI)f=;DdR#9OQUKlqNVQiZVR0*n9JnwmR?b zD=$J#4V1%cU--{mE)PWT)Yqrq&v3I{I7m7KoIHd+3xk~|9o~#wcE&I(OuZfiI4tfI z*)ln4i0xK&z9D#ziaHmx*g7yV`f3KR&mT32#0V>UbS8;WwyD0Pyu%>!dUbnc{zsS% z04tC7n9!t#qfT1peH~kVE~!ZO$n2}rvcLTy$TmP2vsEsojI>olHd;llZQtnTTX?l= zjtU=)j_tS6^|Orpvg`#KQ)&k8_EoifzC32dEp`Mg773(<~9b=m{j)KM)bJg(EmTL_V=H^o3rS z#Ix*6nC6*6y-MuqvlI{2uM9{pXD=znb1I9t%r$jO<#$=mNPkJz)<;beF*^SEU{%3; zcDse>+pmkg$wDo<4mykawa@~b5OYmR`9EDhHMz-G^scY&Xk2>35C@R zkx}s#A;*qw;K-ntT`v5~J{DdN0_W@VDY85{q&l43fPks?`sfe1rz()OcKJ-e@TbFk z2OLbNC51fH2reQH=EF%L$Q!qjb{tL{SdMiRA3Wbj&WAK|>wh4Aq>C7qO)U`cs3mAK z{oOktevPw@ir3=Vml^3!5l5pMN5)Tu`a`+z0r$zX{?z-mP=QiehSY|>Q{wnQ8kF+l zl7e|xyg+%6gkjfg>*w&tB14f3k7S2ROtZHRl^KxIcA^gc;?JSO-U!TYi*q#rDe z!YxS?_r?P2h?MeDS4SZi*j?T zcI!4E+o(mH?Uf)i-gSJ1>r-ud8yJ&yltPsf z8X;lCFe!RRc*U)CDtKKDf*^41E*XZAKvle!$v!SN4d7mdMK={)t~@tL@yGy^IigHf zq*$<)fdF^7$yeg^sZ$+m&~-xVW9*(2Vb=Z}4Lw8mOrEWTH686K7Imoyt0$XGGTgWk zfne$`BBr-xqYQMizmKWKh(y5R*iAHY1W?xS8Y04$8?$M?tf2vSd3=w&(AlGK?6wAf zgqj(;$GiM)%fQ57j_Ujyzmt4s@6PG|6@>!@bAwlu;SBDFhw!T}y#)OKK0M$2E;!^O9mreI zOK@K9H!ElLrgSC+snbY zxx15gHn>P-WmF$f8v%P{N0CQjnw@vHJprjrCJV}%Xtx`y?FV7pOjfO47@3$31=xOs zBRAw=AxFm2u{zme_2%&j_0Lm@<^iCyrjA7gPcPOlDgrs+-Y}~1F5O!Z*BCbKp1BYX zxEQ!DEsU^w205FST8gl9<|{${uOxxSHZUa6yn;6dEp5mIX^^SXSqk`P~Zl4FDB{aXh3K?MZPhD5P%9Bq@lD-?aT&Nk+e$u9AjX6iC0Guta()bs=z zm_0yXm-r*D_RQ)*g*^+15MLi4QfZyZLgn=~XaE6%UFCSh+-{yfqAp>w(fulB_3e!x zB3?!E-1V-Bd&@xjfuS!5wYG&_9?Bg7(ncOE4#obgA$o6n#oj?XYjyP@m52*F@XC9c zQ)4D~*Dr>WvoVpspM~_ZQ^aSriDvyrH=FVIRwxP0?XNV&cNsN$-4+)YcTBwi&{qy< zm1D{v;0ZBQ%_Kl*oiJxTV!nsYs{xQMQ|*{=8VU7&tc>}vG$}d(UGKJrVjkzV07y$+ zC*#+`r-D4d(6G;3X)p2JkMJ5xJj$YFk1k=Za9cBF$jb(f#>YwHJ<*_y2uWQ6eNWJ8R$53{LQ16Vk3O zXNC_^VyvMlisX*#?&kGymBEx3A}9%WoZ9@)G$^u9YQp65wj?vqFJr1rJo6I#84A3I zHe_XhOG?}aabnX@qKHQzKOzoifra-&zx7F{9{p%Zw`T`8YS&9PZq%*US|!o!{0N$c z8lRQN?difz+fp6^Lj=g^>XW^gkmV15QA0=P;uu7`j?*1;TAo?AbmdL4x)E#bZ%u)`mH+%D3VsSvAxafPLPR#M2uhMbQeWr<=B zT&)INKna-OyrdYNhbHKV*$*EEvlMeiB0m01yCmVg7lRy0DX76J3!LLWb_gmb(^PG6dLX*_Z z2FrTgi?ZjWfupjwCF|b9>=EsMaiq)LTP*TUOfZ1R(xTFdUbk;vZ6SB~Y^n5)IiI<6 z`l2Hlw`PWX?T6Wdr)+6woyO*-F3rdUmqnT|zl%kw^sA-K=I?np+P0kjUY|}xqHEX8 z5UGH==-s21E#lp1UAlFH2J8^sSs1j>1aR`rh>Wj;JH&6qXkuKMMQp91@ChBHhw6nEv1GKS(15gklLkXAS!N_obGPIFy{?s&vjP zq={AT3(Km~e#-*)>^9$Qsz>|s1o)JXhS&agJA=O#rR-(cA1K%MEZtM*j?Z&>A)cQY zY$nMrAAlp}8s%9d^qnvywA+PDK92p;ShYjTT>AY~e=w_|S^IZs0=87w!=59|gAx;e zh(N!qkOc0}*ngVEZQwx2uV@F~ODM8!Ub%4Ey9(bRNO9VjL!%AyHCfg-D-XiE&Ja=& zuf(+kWf_{co<4}cuhu}-JQNcrq>*@`gL(_18+TvaTIbWv+a=Or8zK$p%+10~4Y6u|65l;5{NFoiBvFxgljm@HVAD-qk*I*)V~i+l%1BGgJVq3m zqNdsz(B$~1YWlAZ)W?sVaTG|h7QbYFW|N%?nVJYAWX6%<0chu)7BgL z{?E8ixP~yZ44xV&aVWo^pd$O{4nYw8)$1WSG~gpuy6UHF*gr>lbsYR=XkEsMxQ_=u zw4RaJGmz?2h8-@W9;V3pPG&A1d={U}}Hrav;83XxR5nJc?{tUSoa6smf zXn>EKkpQ;l6-;183RytwgX)1CB(n|B0}F)*xrNK?Zbd#mK2ASAT*`1WtaVC<@Rur< z?z<1z^JwoCu_upN{Gd{X2G!$fQ;JO_7<2gqe;8-&ISUwSd~td8K>i&zq3{56oMj4h zCK{zB&ypZT5V=c7bt(?8O=4!YlqfdmYFETW0WH?w|ErEwRmAF#~_;~c5T$Hqn02< zcuyeh>~st^-D-Fie83@QQ^J`t%)&JHfnGLO9K-D{8%$=w;cgT&FZE5zq>%gAU~IZL zmo=3sCfej^@BFmgx!AB@KOS*gXLWUKW?fb4a{A6)B<-{@ps(k=6MMfuJ-9~G_9CMS zm_O}HM2sq*LFN`>{(qgg2?6uenT|P}Q+x`rw6c`vTh5%|LdvsaGC+UlR7Jr?DM*jpDGi! z{qpA1sUo8Wg`0MxFG0ycEskB686Xxim?@y`y6C(nCWDH6Gs2d6SDP&O;_q-=;p3|X zkc43ViNZ5%bW6QD+9U^IOIEdmH?u=jW(>bRXJ_Jd8qg6@euDTkZuNHJC zVExr%;mYqg&|k!JBZoVTE>CvzrRE>)FR(=7jAakE42Un*h`y#S=*a+Av21vULghzq5=!xjW&fDS%|e&dYgRng17%{~6Q#Iqo57Zq zsl1fSV>L2u1ouirP?4rt9ZhOzR)dObplL9^?2?Oz^BLZ_RQAlwpQTDgDz?{)&%Zl^ zgGP`@&)x5bm7eYyH+zw$rLoO5CKB`SBg(+LGN4QUg4HaL{ zxX59+T4%@&^e+{wfvj}(8AWvA9zTm!S*A;+G-Esd0Y!bx(?dQ3yB#27eJt}nD`d~n zU%7dFzw2q?)Oy;YZ;sc|E(qY)oP_%?_}AGx|0M-F4L`d05=nuUf2TnIQ-sMaA4A_? z&iH%TNqfeTsA^wpBg$?&TBUHYAByBl%Q1m5!)K4NI7c!+?ab`kzE%}!;2(e3(z=Cv5a)5>#*`p54Qvm=U$Gj-?;QUz^exCb+|*o$3`ME^Sfk{+%jC$T`_%<;w%j@XJWc(M-3onq7e`P!L(}WJk4? z9B`CF!6i$Z%lM*Uv2GQ9Sla71x#unsKMa5^B6mNX^G{HogZN7pHa~~Qk7tpvAeH~^ zzRmVSS+3udzp>4MTFm;5Y6%iil=xEz}oi4I|AkJq`NxIEUNI@_Ckb8)?xgN-HLUZvcTOi=Dk6h{5E z`lY1CyGh+|pc7##ctZvP5!s-pe=HpN{*nL|_RKS4v}R2ju=@X#=-f+k*lkvo^7WF4G`Cq>R9CVx zkkaCp8>=p@_bgrhSSYPQAXIN$MCoyKf>C}aELjfc)D^^}Nc3{g{)R(Av<&=ar@~$E zrtXOMu~Y_J9G36;Q8zHV+CH-4J#fo%B%u+GG3bsTV*whvgm&n@f8c2DAH|wt1GvR~@h7JLBn) zq6OD0zU66h=Dzx*0^A^(?;oMNOl4Bq?2q9i-ybF+r83GSn#Ld?4Q%P7qHn42o2-M6_ zF%w#O&=IC_FT1 zVuJn}k9TvDFW|1_*4gP%pi{-XWubj7)-Q%#<4N|1G$rHqT|Lh77(vHxc>D#Qq#8Aw zti)i4Vv@BPCNUWL&6_|a)s0%~P78{&H()Ys)@8&23LNaf%cpG^1?4e1YTH0(g%L&gehItz0xPGQUq|_ z6u+-KD$FK6Lwese_&JY7kHTfw)R#KOK9@||X_{N|94|@Kx=p?sbr~#*UN2&{!O6Hvm)(X#d z3zG1xq$08X7i~uy^B0yT%2Uq&9FrU>Hp&Kl9<{P*7H0E>3Qe98dh%5+)6Y-OW(t*N zYBaboc{QYra- z_4ERwkMSpZLhS4xMX%p7U)4UJR*$HFujCtVRgMcWRMCq#nV7^2mi^P*8uw^l5ZPg! zE)8@-N3w}T_{#~OL*=5f%~cD9XwI+>iR$gg=YI+@59}WP3LaB0GOkf+e;%+PUL_)_ zN+Xdqy6dQs>gDc~)<0YziJa07y)*V7@SUC+46D?viQ32t>^1F85myCT3o%^??in>~Yw-P{*JBmHJg)Wr zCBV2Vz%uizOYzf!CV85WqYS5n#|_lY6|;@0;j^6?(Pq`pjZGx1nAe4V?yz`ltde-I zwNYx)mk2f-u5c6{+E7zVcqAuSzGJ`SoF?-ldtgR!(IxpgSJfj|DHbf>gZ{^#iwxw7 zjT%W??hiMfJ`~I>ZlfD!!y42$1vX2m_9vF`Zmhm#=#1lK+ojwZ8sn;QO0&6qRvp?t z=N7UGuuaMCj%uH;=!Webtu!6q|5eN3sCzeXfK0-VyY6~;T3_mtr%cL5t)chM)xLof zBr=Kxfu;YH0o;%vvVsIWG;Q}o*77ad*vL&-t~nfd9pjOhzp;({_(?hH!G;L^XNX6^R#2;g=OO+KFz~^_>30{WYJlVQ;^8`;z|j;aSQImlO}u z-nIdBy`~V=P5y*N<+$bn^O!uOaI8Q}@`v&91_^ts$!`juJfV!7aw9V!IMC$<@;^NB zb6NnekC6|7+~SdVa>z70tKunJ;mYjslb*wbvym#Kc&i+AL&sKg;UBSvk0NJr_nYiT zRWgIZXcTB9yfP)d&vZG*2Ip563?#5*e7F|_d)l(OM}291uXn{Q=y`*Q=QEc?3+{Bw zAfpP~?=CaM&jv>A%Ivfgp2!@8bzXm#jH>@mKvN#~A(Qc!Z$^X229AH3Y21TEt6>S> zfyu+5Jn3?kPDRIBn-$KFH92dQp9x0>jtuu@Qto^`$`&9TnQM({cf8CJNpJ3$^!jc- zG%E18rpD3}^fK7)Rea3pvfRBl^J7LTfty+bMc)~;O2lV2rGyAiS!qOW1J{O^QaPu& zji762R^^4<_aIf`-K0&MfjJh28Jpy9{P&IOvJ3<`+*o7J?j7uM8SgBHH_gv3AEHw1 zypQFmedlP0hNPgbK%s>XT%*6;?WzU%&2t5yER^yU8k_#p$qjKTg0{QvfT8)`M+#qsi@AZt~tHmOmu+XKG!yKd|B6juB)L?VTW6e_X@MsM&bShhbm& zMV*wa1j*?;82a_*ZD8J^K3kKT#&&zEyvNYzOFj%hichHb2bU^KU9L9%a(XTdSTj$y3ZIZoF$_5r5&sR{-k?0<;wQONqfS8(yehLKeI)3ZS3Q2ser8V zr99W*Ik?y`BxT?_`CM{HRRG=TJ(~_ zj4;?cXCl^AS4nPBN++=gGE;jxsiEYS_|Pg_2E(NaBvU%FHTd$F^|kME6}BTP1aceE zWLR27?w+&@V`@#e#jGq?M1{S^4KDI|ADmOVDkk&Dio+B}PB)oEle)`he)_8YH1Unx zi+jYpWY|+A7rSpiJ|+L>>&;ypGVBgc7I9mGNT?KwF{W!)3eyBQ4Y|eLKhs5drVFuHU;o6mR24z3`e%z~JBB{AI*OAu& zI#osu2e@M*N6$dR^!^t8V6CBcwaY@F+uDV1t)(p&zf_e|gk|ZkNbXcx`dZm5W7IRY z!sos$xy~PVFKUOZEX|EH2L3RfFfO?F?gre7i%+AT|G70%k$(j;r{lelj(nU#@{+ji z_2qZ7Hi+SzFSq|~IKE&wLM}TOeXQ;Z6Uz~=)p}AuVc;xja-La^fnAT)i zyvTqT^dZc;*{8&PcVD3t6Hn54_2op(D0K2$K2!;3qio=o4&Et!6gvOQh{VBsZNk^; zN1PNHoy8?V$G_IeJFnaJB#VYh#O&gqh?I{zG&g6i*C9Zo?!^O@3+vc#kIg>eyCwbW zb9cAJg$Uv{@24WNgqIkW+Qy$H3Q(D|#>AP%wG+{pea;-#slA){!@j+LN&ba6VIymr zReYzR-i3mnqOT2Q@57WSJ~9$=8RaMQ*(Wc5!u~Yw$imcHwpOQVKc|PzRJ}T}dth-v zhErGmG1DuFuojJVigY2|RYHNx?;d7SlG6IUyzr8kaqhzx|5NgB#PQTX?qhgs-yt&7|~uRnA0h*TYgZ52{=)-F_1nRZ?oj88%qC4z)Rmz^OMFI~B5oSHA~ zI;Z$X%N?70Oeolm_$1;kOeaWbPmtm%)-lP_QB zFjO4*dVz-et{IOCjLnBPhhES17uS8xwh%pkMRHO0I9i5Iio}$RUzY$a@Y9ee{sE_T zISm@+A>&2=04o<>G<@*ufQGCWtsWP+IyqhWUGGH}@yv?YVg#cnMWNw6PUGq)wd4y{ z&X3}HWb@XUeD$)zcs~a)n|8ountkXi9hsZ*A>EEmI=FzvV6IEGVr9EaU)z=T9(ta8 zlVom_RcGw!`jq$$CbLO(18pH*uf1G+Zep3s>Q%j)fnY#DFli@to6-Iwr?&Qw%Y21I zRruMxFYoAkR;y!7iRxN~qJEzxaGVJ8fCuz)jR!wz_lN-fY*L=<+ASQ(>$m6>`VvcV z@gp946N9G^-wG~&rh~Z6C7+uG#w6{cTV0YKhul}FYZDqf2s?A_{5?#LUfnM13Rl)= zMXUbks5h#Z6mVfms<`2um%qK_@Q}!7uiweTurz9>#BH-m1D_+1dCzB}%YMY0bl7ov z%j~uJcWZ+>NBl^78L55FCYBsdpM6s;{?r>DH?p6*Mz=X=P`i}QADZ55HhP`-)cGTJYy*8C&YUBBb5uLk%&+h3GF2B{BN%qgm}f4#Egi?Vx)*ytosjMk)&UQDO`a1u139*!v|yTn;myu z?7#Y}aENsI&`Whp{tCKh#DyX;4WJIWCBxOBhHI@=cUr|gHL8u#mrK@i*c2ih0^ib$4gS1UW<1>r6QC z`u)uZ%$`As#p{1gyrQF+aVGrf{)f|Lc{XXB zbA1gB{Jbwd?OsRi9;{gM<*sLt?#_fJpI>6PRk%FA9=_ zy24XTY5U--FGXVcz3uONlm2zgi4qyFDEk$)>;=5t*;%FNQSYat2nT-@J+3|z(+Kj9 zIjUDDC;dGg>luQ!Oy`^JNtAF%v9HD!{6u#Nb{$rdMU%8#=X>;L6jx{}$~xvUvdNeY zuCU!qXpDGGhILDB47|spp167E>>e{;#`SJ#|927v%Jo$8;G0gG43Hx+S;VbeI8GTq zsy(75EfM+cth;u+x@T>^j+<;PrNG|W?llTzW}_%A1 z7<%`uwML9Z196t#Qhve>&-yzP{`=?Nt_QN+`&vKqNDcb{znimKifr=bqhb{v)2D(5 zOfNSUX4pjQi@hk^kNutr@K}AkIf=R@6(jENk#Pt2*GY#~L294nfCdqzNOSNvkDJ@h z?q3266?(KtX4;COv)z!20gah-j}&X4y$}L#GAfc?^VVz8n3nuf` zV=x#3vf012W;}DwXU-YP<{B&g*0{fT+$Rl7G_!>U$V+C4E;FQulR)kr*1h1L=~&{h zm;OZJG*ok+G<)Aly)XRU2pbF!HNGOiU#mS~Zwn^9U!vD2vdAo+og?&kurIiR%`SVR zG?z<2HA7^DB1f**srlnB*2toQD3rEM1>&m97gD>w)YBl?2>hNxefyVxjTGe8NX5a8 zl+FJ?Bc(vbiKN_-*hc@ulB+G2uh;L{Ms?8H#T3Tq<(=Ae9TJ1p;M7o^@bhY2WfX;Ng@?-U`q7|3P@p*D2)7Qf&{W_9@>DNv^#< zcwzM5k;%ENEGyJ}zj<|i*Ho~leb38U{n;RmC<*}9%@IXI4UU|`hqy~f=`}*Nu2=DR z(4=4-b^}PC{ZJdROh$aedorF4 zc+K3G0R0{pGC%ubMilfE?XI_6pB5U1Jb2%1>%}}PL?T3pXCLWnRgvOC#Nm5S?l z`#MSpr~i7yJ?@+Tdy(VMA%#7wOhJ;E6upAj?$nUlpRzGpbu8-HcL;8-5~>VZJ;?(Y z7QI4wMgB21_kq(2*}VraLSL%<|IOGSJI9~IVO}+|=zLrG%(HjA>D?7e^^ha?MR?f8 z2&Jm*2&4YjV{+_s&(l-sGlZLFtf0Df#U_RaMNklKNtb9<5jA?fp}mhiBvwtqOPGzI z*X$PTq4EB;=a>~=Si_kd{q9BpgYLKqr_{qpOhdXL zVFU9X0Uy|n%zx{eDP(%~2KFTQoK*6AO0a=tvlRy>2d^~90U~YYBBp|#&FO;HWh6m? znpg*`@h?1Hn>Tr0#C@btAVu$<4?p~Cf`IR$Rk3qm!zpFDm7@Ank2eDegX62uAa21x z-gfV}<7dt^dJ@Kkc!Ubs{aiAjk@`R>Wt;TF+7|?L#_99-eoJgdrSiz8TFFqghCqs-t7;KPeF%(F z!`?Wc(+g9B0=$2vr&;^}ZE;h~Ag%S~c8yrn*WQzW;e6MfsdvD{M^}qyxy$qs1-J&R z6BQOs@#*_ikY9qO3C*H-uP8Ik@IEx?K3f)YK=5afp`pTgtoDWZAiI~o_t#ZkWYe+&@uOo;Xe5iSSQy2?9uUPJ~`i@O!=!@tdgQ=}3rL8lvWzdm^$! zuKtA2qom31-bid=FHsE)bnv(zV!IMVk_XeM6QWt(ZP2th3)v`sGG>wUhd|;-3#L(M zdsLtjYs^wH+=9?lFF6BR=->Rr_?SWB5W2P75qXIGY*Vle^BWBeA^7tQMhN~1E?OhN zBN=q2QO7)YfvdzDXV~DlM^p7Sx#|2IBb43gX6qH~VC9hTr&Q{TcSFun6qQydp{m!q z9ZEB7?i`LWx@p$^#HN`0|R>BmxR!|EsROZ0`H;RLV7 zv>QF}t9r(w&sK|)vm|CMhD-8aii=HiTT9kd&*t>2oG{kfZQtvtmy23?=sy09HaWC! zdKx`|;dixB3hS+g06*=M1rK|jCBZ4Ij^$#t6Ga?}BGO>J1^R-NO6(3?`NVy2mZHw- z{%kagtMBc72RUiY zc1*9A-RxcYGQ&VLM37bpJp(<73~Dr==?3y&exWmE)g;UpY4*4d8xG*G^z^o##eR34 zl70LTe$vmJbN%;RFC+$x4%3vol4g&PPp$>0zt?Fz(O~s|MC$ZN>;UhRiN?(mcRu0j zAV(2(A&3=(z*I|-1{c&L<&lFcH|Lgv=GC5ql;*K4j~o(BQqB(ev+~9tK@kC>r@?ZA zqb|WQvS6gG@LQUPi?lOm}i<*mDV{n?_6F zLM?;y8IG7x&TCb#J_=eHJX9X=*O_iKgMAzC_wuO}y%Lw`#0qd0+Krn3^0APR6@9!m zODY(msnNeRSA9QK(<#0k$VZ?0Q@P+@it?%Pla7aV{p*t%HHGK}E?s?!Z0Nq&nJDA4 zI_~@+$KKG*G9d$27xP1rL6CnQ`-)YkE=)r3s&?E?tT0M$xU zB#r3cv_U3TI|fg<@}IyHpix@}L~QxLd$+eg*3|H5Yg^^*c)4ELJbNZ2gOU0Q{IBK0Kp5jkw%!z1l)+@V-Do#aVeCGCC$adXo29Om$ibR_T&&xgS#7qLZm|D zx7m$RoafU57@V!=L{PKN}Zj7cq+{84n1erma6s6hzce1stX$6lK;@80Z4 zO2`=f7;zF~sVHbJO#7(WP11uPF65P)N0`}{EJR@x7!k+K^-Hz0HZixsByXC>I!neb zMoJteS4}==Xv(pL$-|u33>^#pt=04OHRM+a(F-}pp7C#Sp=z<;qTVwG@d?KN=-1?K zZ;9^kzR8a;-(&&-4V~-_T>JifV6hd*rMqFRz8_E1eVwo6%JZWHBlUEd0pUau60zgJ1>Eqiic>x9+I7KV@1mq zBn(Dc&LvceJFO4jpYRvRpO*A3%{^GPE>LJz9`V(7xb zgh9RUIdW<+7#GBG=ZEz524?W?4!q*h$_9(_2~(QfS^MT!9w&4EvdEE>0~cpZ?rmxst+SwSKMx z(IyRGh-h4)k06)WT&;@5U7mZ5-oKDS3>w8%n`ZjMe|9S`ZNzl)x=-PzNn%=HOZwaS zwze-ey~Ry2>>N4|kyS@kOd4ejTJFT?{t}k<6!Rg;4f7!!DO<;7a19l=2XJfBat6Y^C|m5? zzcwxeZsRVC21XW6c!OGEBay_GIvmbFqmQDi*%At2OQotK1k_8tGKn<6jQoq#s}y zKTJwhwxTbbszxN{G#UK`r2{@U?NQq47q1t5gk^!>*5uNq(Wt~CM!y(0x?m4!X+WzPEhaR(C~C|KF?vr@P|%o&){X zY?<1ajZiJ>Kw|$FSRi5|nz^Frzzlx?5xb$(#aQ@smur{b0c3SP!~H&ABp4)RG(I-_ zfy1<5DhxYj=4FYUU=f*S;ztxk&^DjGdF6-ODW4>#0McO(l{@8QZd9@imIE^ZAb{cW zR5!5FGi)h<#904Q8txF7ukj)?srNIi0W$Gxq?K!DI8rmOne|7V^0)$JyfSmuYiBi( zQ?l;mHTXBoqy9*kdC6ZFkny?V(qr!BT1dshX(R~E%t@{Au}#iXetdZ5$p_{aAye%b zKtLkO_dBKSN)P^Mp*jColhvQ|iq$Fz-+~-Txk%pyDg>R1oPx2K4^I?=;7X<+?vs!} z=>J_l`{C!@k8VGd#`;86z}4|Jfy$oY#oV`Yj=@8H(6zK5~HAbKowTb9>ub_Iov zXA*T!8KbE!>F~N@$a6x^JTcwQFOij2m`lz!X20OioI4KnT${9MbKn<5Tr@2Xsr8YE zx^X?0I>a?&Y0*Oc%%XIrBp&_D9FjQR45Nr*)vI|W!2~NoQ7=%tbh?3YrSLl|CaD#@ z#6ex|{8rarU*<56{mkn(nX=@iFJ5=EXK>j?3;Py8IBGUCUwhSTqWWp6%gyX05|@yp zX_eisO1%ysBz@7#W_DAX?~MsLJ1`kEXoN!u`kqXlZRji79sU+HDNe9G*b-lXevx8O zWy1`?A7EOOr3yi2zRxUF>wSNg|I$Au?UAppPB#ZWyUA~kw(zx+w$>IHcbbr^f998w zu6_S?!(-EtgsM!@zC0BKvo|d8z<1?t&s&QTqG|4;I66N26=jb{(4%$XE_=dp(}@Oy zSI=jMs*M!-60ILO9)+E7u7q~E_~MKcF+x#aXF?3+)*f9Uau{f#!0UISK3npC>^~jc z{^M?u#UgF_0cFdmk@INcE(6N8KI^dP30!N~ER{RRjgnBr4wgw`JPKGrZziuj5R?G~ z#;=vg%6MfVp%ltjnAg*ej^Zct&En6;NilcV0^1McyB@!=>ui~ON0nIugLg~AW8Xx~ z^_8A>rhMh=WL~4c3C}Ia7^0*-=$&)Y4x*6Croisw{s04%T2vfBww$l})R&8F!9lmUM%Wf(6 zdSnzo=(pF!vx`1C@par0nj>s-=Jv<5y>V?bCUkbuuY#OjN>hc9TjAv0`hK|JE_??E zvOlXU0U{eA;a?j8@!PVP#pr}A(EX+Ma64IeR-XoRpMw#y20y!^hnFUaMF9v^PDj#Mf_^LtVA_MfG&LH=?PX0 z=17Q*6SaZ|NBz%H#N03+g?@6lio9GqcMuCB9!3|n%E*n|tjQ7&YO=sS8Qc|l4@IrC zf1dcH9%CsR!jJvQs=Jlp)zjua=S?28ku}zYv;N+^EG6P*J^ss!T{GSsu2e6RFY)`F z1R1;EQOj=zxE!)ssi2B6BxNi6BWtgZExo}26O}gy4ypVF6m4}yIfn_wnRdx@AwDbB zRi;lr={>CIc*wDwLxM)tzqen(ZnY&_)w9K4>U^Kkdb0LSdZG7iux90eRzBGxvv^vC zslK~G{dt;))o8M>{3}uuh}6t+CG~guP)&yvnS-#0l)Scw^d#_t@fhEmR50@t=t$sJ zr8J+(@bOLWO55B#^9~W^Q<8D_e2b;Hf4b<2H<+MX9h}gDrr2>kNx?}MIegxKW+~XC zRzTGYGNWy5E1^HDm&4U;e zGe1<7=`#Za7q%j8^9Mv^i1~=deqZcUlxledSE;%`)sCPYa>6FbEO;DfheQ=3W89fb zPQ+=Ig5!BsthuuG7@|~ZF|ULsb|ic-PU=R+>o*oI+ZsL4$S-nP5ify3k|PeL7)_Cb zitbQfAjnOapv%tRJtDqLCR4UNqCeE+lPa){w-G8g9`tKIDU2Cgs%YXeI<&y_sDXSW#UWw(d3d- zWRX+?duk4<%unXvwZZG?MU1Urmcw%x15-`0kG_%I2dXxX=HEMoWKiQvXHzda z%N)bt3#A7ap0!pRQ+c5{RXL6LOos*L%el$o4jN^y#0Pj?My52GV|}UIn79(MPd}@n zi#{FxBzgZQ)6bJTTt7^^FKLN>2PHETu;>znjjUvEH*+*7+%Ej$5(ZItIxsj%Y57h`3*697A)34u6 za<0xs=%tdL(Uu$cqTV3!Nch52O#D_M*?{l$B!$-v%f@pKl2w6jzuFz?vX4k#%4uPZ z{R1@rkX7k*SZk>EukJTH^rdUU+jlSDTKXLgl^0ScbQRlC8td&$80zt118%0Sd-ur`|Zey@7Gadtjj4#-jlm>-k@Avr-ZFo)>!<8 zh*5wQtHBTjS^4?!Y^?TLf%Bcl z&U}^LqpUJ8FTn^5r0d|zqrVkRO3Ld2?Yg(9#KU=QV~#OTG{c|F)w*J`e6f_t>rdi> z50(le_qi=lKbNEgZJ}5<;lJMV39_W2d8nYIhCVj|Da=k#gj-n{0=pdtX?hrx8z`NM z&j^UckJ(HM1kS%C&V|xlO%jr8a>dKFf3A87B_}lY%G9EGYc&hq#@YHjB#LK=Eq4^H zeeYxgCR|r_%sHPVCt%PigsI^T65v03(m*wO$cSXDI4q|^;%vjc`{Ld~tog?u!iPfs zwRS1SU#zxO_jtV|R`37b@wpb%<`Rg;)|qhD7=`;kMm6fW6g;v2B1$wiYEEYLs#8J3Z}M=wy9X>(%8-tUx|ta8K#GT#_wU#` zIDGR%MyCm3x7Jbo?8caEw87)TArYR;+L_4bKnE_y?2w%gUc+sp{@&>BEStis$l@_H zBRo`S=a?)4f4oS9D8g!NO zXGzEfC|F(gxEd+exFJ_~ePskNwmX4|G{QNN4mcEa@4=T?yIfb_lY)!C^UZ z(o1L+_K>voygOy+S={$M2qfgx@G2=o{eP@|Yp#;bGFU)Q6^T2AD#ImpUESsL$1 z_Uc^lksm*O@91~D%_)F2%@}W@rd@A$fAYoX&@V>l&`UNk#6au?Op^y<<{zlh6d#C5 zgHk*kIcI>nb?i(3{tT&>0XV30%Zc=zPJ# zUc*s_k&RzqzemUVqK@AND!oTP39%YSWnp zt4-|ZDUy=7m|bxkMGY@7x@$qeSOI=Xd$epWd-@NEIiT@i*RHRpzzp_s&^q@DFqV9} zpyb~w!y3i5i)`%B4GXM#oZ*%;%n(IiuiI9VChGO$Lx*yN{gu`*XK~M zdfQ;D68Y5VlxFhH>-mB8=^x&D=dj11C=>s5TZ(cI=}0&hPU@J(OhNZB)12}L2h06c zChw0(a|3f75{@t;h&sUzu-2B#A@4CI_QIiKlx;u=JCJ5WQ0Y-m!~T(MS>eQ6+KDGJ zyWC1eBOA+>nYmE+4v@@ZDO)lb|5GCZH6S0jcYVnSE&Do~Q~L}AQy8-nOIH_>_CBEF z7EH%@1S91seseDyPIL*Pvjy|>U{VO6c{zTw?>!&6sr)rL<9m9HW5?ae-C(!yy4JN> zcRr`i2=c|%)j%+sAn071ml71Cu5fF?hK2Lr+o9p4JU#6{dlHGgOH%wQ&EHRZ*n!L~ zHHH)n!VEkfYXHtBck*0lpL?>5V?kW!utpZv6HOJ3p|TU(KAi@M)nuMRgcHVZMUEAk zJPu!FjvSJir<2A?0zYM)cYEmjGXShaWsr+AtczkYu*1_Yq7s%~hT<6{AN3~GEDV}e z_sV$gK-@!`1&Mb#m$faJlaM*N>Hvl?`@JGdIu_V@g3ICVrwaX)Sj2JRUTr5-GK>bKh){4>>3meP({wN-!5)D_cB@x`phqXAU!zB&=Gw>z!bRrRn z46Ya$jg8tV$OuAuT6a*FA>fv*!8d{7>6#mDj=Ln|fXpL{XbA)`h%Ad+-o5}lCdFZc z|7sHy*s1fe^VPx4R<0v*HvDm$xtKV+rM9nw!Z%@HJUW?GJMx~T8ArF=%lY&_MNiRYpj8)q{zA)%BkM)ZRJ2Cg=@#=oS z9~+x!@Zf(O$GF=0E7x-;t_+62?SH8YkVbI1vCJw7Pt*C0>jc+`kM%`bCljyPwd)>P6ftc zwO47FLsugYuclSUfJ-HkUGO`(OZLnQe`#=FFE{wXZ+Yjxa7LdL?w$jg8sGa+W1Z4L z5vI79mQh|T0rnHp7F-KEtVjFD&1?_4xuHteY8AEuMyVsWtQI7=THRSF4gOCl-Umt4 z7k+n9K&`fCfA25ThY{7>=~dfiBV_>dF1q5F2#0g!dKnl^jnyfAVR8$b<0UR<2ee>{ zQ!tpGvHbhZ2&V0;$2tOB;z8UGM-4yd&U>H2bUix_#~NOl9(I9I&tUbfKNz>)!@&5g zs{H{bIt`Wqs>j&@G8pC*1d4ePWPFI&8`9~480-GRUY4Ir%3ae$@f_L!9u#7@5d?!% zZe)z8=*qx84&hdiF<5AN+h~P@7=|7s=Q^~iU79o|j-ulKa>adPLYg(U;H<*b$#5L) z=fEPQ*NrOV@tvUuo}BI&ZkZO;BMDw#u`?UoZxEK!!f|NP4BNvDR&`;<^6okkrgq?YuvjI*M$Yi~mH6|iAxIV{_7SonoJO(|onTxr`1Xcd$o zJgwbdCu5n}e;zBPs5tl~p(rTJ`(NdyL_i1Pbc&dP)xI=Ps<_|BXTz*nN32y%Q9Xq6 z_60~{0n@I;wp?aers2t#ej4sMNl3~XwLXp;( zWX-^nC@P(Tm+7Dyv)Xlqn^}2YB^+Nk#~d!`%px|IqR}t#n3gI`YD)>NHArfAC+)k} z^Pxf=io!X4920b^(6tB?j`N_Wl?M?2i13?n<=|?=^IcOat9|}j0#F)?AA=aeU}TWt z4^)CfKdJ)yHub!=FX&C5JVm8_M-7!u{p^S53Of_3tHm73Ji9vBTZ-H4(yGoNtJdyr zooKQk@UNv&P4b&k8Q9Va-_l5_Di<2bou*{gEE7?ElFoS#EW(Cc+m{VfHOJ4I8Yobg z&cc0iBO4%O{<&BybBBW;%C6#4oZnfTMbj9NC9Z)+2H>8OS`ZX$v>VQ`7;&KDYZm)f zf@D{Jp)mm5@KA+1HOfZ}r}kv#KIt>L`-)rz8d#{yXM&gCs0atdqd^l1pYJ#N;;)-M zo^7G{D`96j+5c($goLiF12fVCNb-nxu+ircV2u$)EfQ$Z# z-Wh{Y`@^-~m}(EUX1_LMDY@V&M&dKxk*EcLdcN@8ILJrEnSi?s8?WMF30Zk+N7OgAQf{l9WaTyli z-mo&Kek6!?VZgJPB@?P(hX{4Rt3v~My(3MB8fF2>)}YOfj%P6JNUf>aYNF@ zbF~jK2RYaIYzqkxOv5jbMhi4mr-VJP5j8@`hNlYRS$(|(r>H6%G@mI?RX?`e5`3Lf ziO+i1t*X-}ZC<`$7+o8BF&J*S?A^b~r1(zh+r{~lBXWKbqbF11Xn@p4Wbezw(qOYEqswV%PK4i9VwHQ)A9b66fW@ObCrFQ_N492q7kD7Y6RBG;TkK0;uU?$@4D=> zBi0c>Js>`Y&NtnLS<_m2CS0s-yqh;kTl9u93G=c{No>nQoB{=|85`~NCmMd28xT$mq=hDyA!#e ztb`$zd6&M^2)bc(6PyoaVvV4(&+f{9-%Oh+fm$!Mx0p^~2I?^SNWRIDjked-((3Ab zZ%Et1(^YL;o9M?d+_Z}^BqRjt@;zQ@TBbVnvG z-)m{-Yb+jn#^eu4J%12%F?_uGQ0CLCiaMfeNy6BoSv0@}#mXU@E>o#U2GJQowDDOA zd%j*p=2-3^?2FU7;Dco6t#P&Fm5UQw@j>|~i+D`A8jTFv2Ti^Nr2Gzm%0-nWVGF=zHUwgR4X}aw~+c}Ux z{UqdP|AJXs;jPqBqcUrFKd|u-qSSexZ(D>nC^dd0{#W+6;YkL${b4@T2|-`85@G$7 zMN)fmWQRP-ui6`1UUJ&-jLj)ssmHQigU1!dCtSV^Cxh#Lc8eNaFAqN*XSwuLGwD}Y zEIq=1RF2lSaV>s%J19Ylgp*t*&%&ZNV?Fsl{_9Wr0o;urfF|hz{y+Ye|L2GpasbJG zwAlqUD%+o@#3{`l4~2wwqZtf5jHQy%Ait!>`g{qg8@!gO#UX0Nvu&yFkx|@^_Qr!t z%%Tv5ZCt~S($wvfw-mJU~r_?bC*iU>kD+mKu)_|e%{KDwu3tq<^h!V{U zKR;IoN{5ch>ku_W^}t2B&(G$T`idflZ4T?iu{s%#{MiCo12KTawQ~865bi8YBqrNO zG{=UcC&Ui59((Zd{RL^?K@wD4;hih^(h{jUy(wrjQnxpsLC%6ebcWXpv%YjJ((%?R zs37LWu30L~uWbUiK`Bo;q$@Upy&5mGa_0`%+Yk5vY1VPRjHF4*(NipnJy^?`?MKm^RlcN%e zJg2~?mFw}(S7b@Rw%!1Zc0NdbD9>CD&`6!qq8&G4Iz)~U&HJV_Q1}o$RbsREhd)Zi zlTbO!V8S0~)c{Jo`8d5~h>)K&+GSzmr(^w^B|*A-ONv^N&fBxFy;(m|9N?j!tL zLe+Ll%?J5T8!lk^(bO4=(q?VWA&+npwl*<+ds!nEE)TEDxpaoDx>B3M0BDBioj?Pk z%i%S0gzlt2X1WI!t&)n0>@o<$BqoEs!4P3&wC zt2A~6}ovw`kw$ZI{QjbAk+Fb!6-<6=bmdyeBF9lH4l$TF! zB(kNum21hYlE0AQpl~7PvCe!g#9hw}NpaK~k_* zz}EE}4YBR*?T3Vf(*Z93cXDgsuL-iS|CZrPc&p0g7P6V)4X_WcL3at~Ez!F_LM6MS zX=#-X?{kvingWHoq~F`QqMxa|AVkYPBQtS-bFRLx0OQaTp{EM4HgID1?#i600Gvg^u!}{64kPdQFO?d z9^XHL{5H)3t1rlneY;pS(%$p(0R~aJ9xmn{J1SxRORQYePgC6L$a!>A$5Qg7K46>2 z7>fAFyf8ZHOzgm(Qb1ex#4P0DM>sS4?p1j4}BWEn~!B_|30*6qK__Y z*i`D>%SVDoL7{+Xgvt*HC*Fs4(0|1qB@$dLYGi#Y-z2B+^0<)xe87pz#^Eb1iKEww zQQRhwwh&@+b|a`{7)7SVn?7LJ02NlR`8vp%LTIt^U>7L8%h6F4ahTPotSpN;^&ayK z#lBw}|4}!0xK1^06Ro{KTzuEEa=~hM)Pvh_ajKCVogqyN=8z#oDZ2~s$AQdZC$}V&q{rP{yT4Q0OA`IXGLozjiwvxo*c;LhT{Jz2;Dqd46>`fa< z+X*YAJ&bq+#o5b4{XG3(+R*$PjKS+=nIDps=)z$_39rK;AIppZAf9BY~`AV~Q9)P(- zXNzWP95ZJldA}n}LBphkiQTAPjmg7j6f&gm?BN6k=Yt&#tA%ec#txX~qN{WrO#o zUgutL4~YK0#E*U&R}n7pQOlhYOPa5N&nc|yKyT(lbhHL`T5UEg5Nbz+(EjLmqyx>Z zp+f@90_Qndps~qLD!WalCy0>ck-OiHFw%mvIamJ^#wY z1IqA})|Or@4Aqmm9PAKW zpPk;Z5pHbhWZm6MKM>A^$?3;jQ2k_$L1yHn3!b37)VPW;>0C(R#7}X^`Q6!SSC9n_ z3HhM7Olf^YBSpr^^}e$w|0k}%0OA*%e>KV$KDyx4nt?i#cOtcaDSf{dHBKm z&?``6y`H?x*ZPdm5t$+jQAIKCO2ZLHC+sXo{#;a99&&2|S{|Y7UF}@dx1H4Qa%Lj` z`(jbgC*Xb22_Qpl;BePo<=;0>>01i0tIWi~+Byvu0g{(akOa_rB;W^jDY=+wh`yy3fQL+qm#r__%)xwH$YP0 zpL3~)1NvEOa(Y1E!wN(i9a;Rb*6CJ7%JDd)-3tc3YRhMMjH(NN>n%;Uhknuie>il2 zq1qD!f&F#HwVw3C@_sT4Yv$Q*&r`SwoNEESEmAGks5J5^caAqzpr6x!y^J-isqYE~ z*)e}LAW#0|sf!I#E!;@=!jgiylAT_xeO?Qfa7uVkO$^g5!uc*KrudKuU!3;qKVsvP z1uwxVI>&DUyIM+%aJ8}bi#IGJ^ZlKpylm(4F~R#5pE#4ShjHe{IyQ zaWqhXGXey`%lzh9Zo1pa{I95f3pQ>p+B8p=m%vqS`a> zYcjys-oN`%@!eyh;bv+MGnuu#aQr{7`?ozmz%-J0hw1xqWb{;&QQ#3&ZJa=Jvbis^ z$bD(I$ldtxt6b>I?B^^uvKkb=C^HR*ces+Af2e9_8A^u{9~BjHu^Hha#t*$575TqC zGCo2txEwq9e?eGR2vV~o{^xu^uT;~#r+50P*NLY@<$rt?{Kiq>yol2SP!_7@S@NM$ zW;fi@eiL=HF_H!Nhw!bBAp}p*s3iW7nqDA+f@V9|D^&)z)-r3?Vu8u!!!#D73?DeI zF)QEvXemeU{rlXYom>XXm)L3tG-H{vs53UkGbs{P6~uFq8XTn1u5;NIYRn$vYDLq% zvajIp6`f75)9)>QSMD}{&l!(3c6``>1w~4~tCml_%qwWJN3HLXul6KI;*T;==NQY( z$fst193tcQKib!+cOH)eG7X>*jmZb8bsDMQZ4SLu5&HM$TZM0RPZItLf~Q`2e+2># zGr$LB;cW}zT~J5aQMEenwNbAcJ2J`xtCEb?zh{7tciZ=}0rW=*qM?K`g5qLFslm6( zcMiLM~1n&C>v&{g&8 zAISibJ5^n{fO_%3JT?fW z2<80W*e3H*ycn~ps=KBg38L03W>%e6H-F&k1HUr1|8Zq-q?EPIFb)7BxH5!PjFO0Y z4Zb^U?qewy?4mk%`N?&WzbY@i!fAlVn9omXTTbeIP6BtG5e^Oh(fZq;P=Qz4)dfYq zOS#F4U3J-{YIT0FghCMP@;11nJOWW478M{^F^JB91(Ymbu8Cvre|+=#9`<`=LOD3@ zhVvw3q)-D3y=?;+q;cun#3LWVNIScK!Cig`ZL6w~$H4=9l2eMfa?ww%9}diRQF=Sa z&~J2~;yHRqh$~9(fiwF9uNGc|-?6JCUvUE>WhK7g4s6e|#Ls*N`12hsGVcGioRl6o z3m3B|Cjq<8^JY-=e~d2(qV`1KR>%{a^8~5=Rfpi~iNc__Q`yqEVEtg<1j2ea5Y<*( zEW=n(ChhG4tvwRHwu6qsME1*HWqfbF&TP4G!+?W@jYC3SkFD6&9mIx`dDXFP=5g(EbuStiq1vWpqU*`^UG6vY zkt4bZpp^Sq$m`rcY(qIqe~#?+TqzyAls75PBg1Q zZi_G!An)&Pw8}Dbhmch#sG@=s>?#dXFEb<-xYG#73O=F>!1geJZLP*b`6BqtI&2}@ ze@vAhJoH^y-FAOHQ5S?KroPl0C&(#*u@ylg$KR7X^v?aGR(*P3pFi*NAZi7>$E8(; zTNM_4H7>jpmZKfL;MGL!8w!%jU&V1xIMW}c#lLc+>S>uHk7Cz(T)8!)$0=Or`3Z8~ zl^ge?@5G-0WWYr$oSGR8F<7fYCtvls_H@k;ReCu>L-3?6aUma|i7$HWW6pnk&oD6> zwHlMg?R*_5L+8-(cH-j11GfGoeq$k7P7bVjTq;KjT zmh7l<&*i(e=;so8ULHj)X}1|8XNlC`iBIHv%KV zr)2|b=kc!r^=C!&Xui1if+NJR*Z)hV*X#B!2*F)AD-USZ5^VEh#$l)xs{2ZWlMt_^ zq`^s0etw;pU9>j?4l$&_GZrY&au~y#aJ=xDLr&!ys?Nw*KBKI zjjI1}r6=&4*0moDBUb?dRdGPCE`*~>E3t@AtZo#xFZLEBcQc&dWq1l?*?`G~j-Z&W zO8i^`#T8`uC1V+)xtP8-*yiMFY8d2o+P5H2FuMZw*`o zoHQvpDP0Vodlir5XV2fj9|^<5r)BsbCr$xQ9NmTW)QgafqWZs+g#N;C#Ib`4C<(JE zv`m*_pltlI!NrbD$YbI^G;39q2G0uuz>^9Bo6NOuPN;Jgw#?c?Ui~q$*VwRi(O8*> zQx*^$s$WFkE68OCdRgt>D7Hb)*Qqmym0%nOt9t94#toH(t-%4xvoEVer5PWKo9e6W@oGGZ*g6h2U!%vdgoN1H z(eB!F0|pIVR@2C3?-$5us+3`VBoDF(~{o!@O5gc1BX{y(1=;W1j%1?Vzi=gB?!q1BbvT>O^X z{kK)+o9Qv4PI$Neb1-3jee@G;@~a}^*17@m;d3Jw7h=~CCG%=W6`*gaH$}C zjn4SPx$*{q>whU5s-W2y%+s0-`7s6w1wE2D5JZ>|YMFF>npl~BA|s?77%a**8jGnf zH?Tx3lfI}liQ#ub=A^QHmBbH`KVgO!;iAYt#ruJqm6=cD@=s;Y7G81UZDp~CCrzqpuu=e&KZE+` zGkoPE*IoJc&n<#vg)gaNP+HVkZ3Bw7BT3%6uo z{x;~Lll)QeDyKc#GgLAE`M{mR$v+*FAL+580~m_Dwj*gj^SmH~WOlO3{aPP-?TVeT z43APYSfPnR-h6e(q_msjP#o;UHcfuJRm2cAOR8l5Q!$vtXf|OW48{ODYA-)SYZ)}F zh#OdRi2`ZvARQv89RXG8wB7{x#SjHA0@3ViwEQp|h zZxQka0aiNplRpmn&*xSO5Q=-807A8q^#F!WkkP>9kFIFy`=EWqCQKPV--Ob47t7`1 z_Y<%ajk?HG_K{C@k!)VEcOGf-pTqzjBDMzbC8=1WeC7+zIOuV zA3l03M2fQ$1Nu%g4p0MEddFF%(uxXIua0^|+CoXS;@>eru~Ux`2^Do~Y#~s8oaoC? z7zBwuGhJ$2!Ad+yrP~A$3SopxX3V*-gzG9X0WOLe(!()fVca}M#P9#kQ(=GQRJs0L zE&h6ajNskH+gR7D)4yCq=6cO1C6l$dpne?lMwqK0VE>z}t7V6rj=RzLbym6gxA&j& zHJkjoID<-(cbd?Y*Ge9Y@#lqay|br9yZ4z@AQ9z=m>&Vxlo<^hV=%Qhn#U|2>r5XW zV*ULRnnYETj!rlWz6|2p|-2dC5? z(PkF8kZXrd$d_H>XReQ5E?!GRBer-7U~h99@bbS)h1M>WIkKaz_8ZVav7@C~$aG7R zl6A)4%!PNnaqH%9#1a?2?w)0eW^y;J@VdsAkWC5|q0T!S-?F*#`}A$7P~@TaG z$RjyOdMxKJ1oAhTKhTpB$dQwbT34RXVhz7$cr5krIl*nW{w_SMIU)alXnX6Zs@|;) zRQZ7tiin`1A|WV^f`D`gl7e)HQc6m92?!#BAR$spcStt|Agy$FNO#wrYYXZ*_nhzh z#<=7DA!D=M?DeiW=R4z>&wSU|E*P1S5NRAl?iF(=QT8Ko8ObBZ8lrG4F1#gQww`N~ z9eI0uPW7u+@R{G<$}Niw2?-XHP`wcSc=iW<7lD!nDK0gE)--W~UL}EDGNRa()woBi zDT2KkPO3w6iiz&FyR|Y3_`=h@LI1Zr*_x#G-#t)Y!iVP#2Xi@n^+$%5qB>1nOfk!p z1Q`WuUsuq~^E%F&@*Z4jLPpsqS3fE*l)(6iFVUmz7PUFf!{X!o;dDd$bvr_VcScnP zqqR9MIz{?5nl~Tuv84(GDP|6mi-yRw%sUvKzi0oU5#|FvJSdOQgP8$|vuK2dP@s>m zT_&Nhz9l4k)@h)R=Q&A?a6w1El)9J3mz$=d-#zDZYR(AMCs^%mTCDnXyQEir?XDNd zZ4mw9@IfYwoNW25H0R~Br-gKDe*0^bE15-35M3{Ih~PvO4j0WJY2p?3^?5XBX-h^k z)subltJPFp#dp)EBrk?0s!lG`Y$!t>WS=yh}?k+S}OLsr8`!?b({XyCWl z42EUyn@u-R78Vyj>Y!`Ix?OFX@Js4%`93|vFk2oI&3)2-jQPeH%&xbGz}F==ZyLd~ z$5wx^^YGm96bT@IqP7}#h*flMFBsPnPh>$fO* zO(zO>EUe!CVAW|O|zqV(`(Drfg1eXSVIq~?8 z9jDZqBo&Li?qA#UN_Ev;3!T1{n=sO$f=pJ=F_p3Cgml!x%5#Z*n)%(((ZM(QXZjcB ztexg(i&nO)o>@+{h=w$THJB@)OUvo{a}R3jxfDF;OjV#MqSVJ#F0>5eVSPq5{a)+~ z>qkoaM4k$VIf2^H4c4-St$ zH!6}R(a|m}Qao2Co#HRK)Nt&+(rC#w<90F4vD(_W=M?gDQ!%}lV#P%zrM`^)y+h1+ z_<*WriX7FO$L!d@BnD#pK*I;8s_8#>CUfPxiBTz^qfJRkK>WCrj%aq|ppdfThZd35sadfmBuY(p!bX^W8>lJpB zIjc6*cPsqisU1(7Y3a#O8bW?-GHR8O*1_mZ>3&Y!j~_o|iY=cUV7#%dak;fJR++M4 zH6?cc#*L+nHd^bEEda7j1@idl_t7Ix>HG6 z5|QSVzuMtl5iVnfpkzxiVDSNsD0sRc@Qbkjj9~_U&~UUwu;Rd_IAzfyte0{rZ zuE_K(A-+nH-kZMmUFsFJhG`PY(fe#g0|^_9>}XWM^9JGO3~iX>)HZzTA^Gc|3sPTnsGMzb_L$Gqi>o`l#EzlJ-5QNWqqZ{a zAI>TF=o#ih_7LAR_Qm15?P5l4`)$T_UkyNYU$1-2|27rOP5Plrf_Ce#Se*w+OxWVc zyz$v|(WO7n{fMu?Bz^t%7=O@Lk3v6KneBxv3p^pu2XYsMjA<6LW^1No3blC7P1gmd zwv4=(U#>T$ZLk2XyzMHJ$Mvku` z-gvUG%D1=x)3=>%O+Q~~iVb%1woT$=n_Ogb+#gr7`>+sR{b6hBlAv_z&D^Q);+nGB z3Qi1iq?yVJb5}UbB`$Go`VviS4h99Z?Cw7=mJoBNdg*eY`i=*mZ9hCmH<(3SPc%Sa ztG~zQbn3;_=pSzU`c7Ud{H}C>gvVUOy1M#jxD$p#pdzOY zYWJXvRW|Vl#a&!+3MHVd`=b?f@k(p{pc%i$%j@uL)p&Tc-T*`VW*2r{23LGU7+pwD*fC+_s9VBQ0bSSPugkDgXA$b3|KD4lBVc(7u+++5sf zVx7THU^Se6rlwx?%Z<0X)h?UGw~KQ^bef~?=L;?bbq)|+t5-;G?UdgO-``bO9mM*?3JR!|hllGY^+Ho-jn5fb%@luI3 zJ3S@ZI@)d4P7d+Q@jC4>VH~;dCF5>;$4oySC=aJoyR?x>n!3(wpBgQfE_bgfij#3P zu_3TlvtQ|!URATE=vv))oAJjn|KMf5lF7C5?IrUK+~voq2{KuHSG&t>DjYei@+IC~ z-N-zbI>X!ej`Y=nkA+-~5gWQf#w&*mL&emmqZAIu&yjlL-!!-+04f2!z$_1JE4c-& zIiIJ~2QJd86AfXqy17wn{!?t~1z&uql0V;%$0QvhW z?9L}Hxsn>SdQKz?|*62{&uVoSAQg}lBg;ow}awgw<(iu8QeTuW5)LRR`AH`sI zTrE^(Z+1u9TK=}nSR+zp9^W7i!OeQU=f)YHfqu3AuW5bS`fZ&5#EE+e_cf)oOSYxl zcwzh^{py>py#Pmb&j(Rf;SjOUOG=2W<>1{9V#BVbTPP5hncOJJSMV*@NSDsHAcfzQ)<7Ehla(`ZwXN)dgeScp? z-lYfjj8B|hzSwrQVdcp*w)UT#YFFmMNpd*3<}7*Du(e?Y zzeW-<6c+-_7<3ohpT`fg9&`ner&igM)5p=th2iB`1LZY-#EM0f;J44LYRE6x#g0Ws zX8|0VCutjq^NzkZ?AhhliBpB@23*e6C8Tp&_Oj{MlM~j31TE`|iOj2-Cy0ed1*Z@y zv=zo`Th|)<-3p~r5jhZx=84poE*M?8z)%zU6ROB{oY2@(S zVl&!$w~}N01UCL!SJJz)s!q8jzdwKZP)MYBQ;-^xJ3S{NLBos-sjP0itb@!>e2vvF z;7M*jwMLFgPw?d22x&uWedOz{NH)uHrsclhIr;+le`m-f%>vH~F70$L+5f{&kVzLI zc+Bk>CY~VHF{b-q#)8;g?B2^8)2}|-@9A-8o}N!4BdiZz=BPPJ7d2JOY(wN|7Rn+z z!`WZ(d4t(wWn+EdJj`ERT~DK9#&l@~5|RIP*`xnN?HAWM_{5#W2+&$H&wtb!5+kUY z%Y&QB2EU*A+`nd6-#jScz44&o;7KwP8>1OtGy2b}?Omfa`6@dicn4WSVs}jD(Pj8_ z;D%oK+UXD+z4K?I9=$5W21yveKPS4t3Mo9wE$cqm&eY&T1DSZ|?;Sh7gGl0|{@`(H z<(Y$q+J!|W@u^)o)mn>QdVJy>;eCx9{u32!9i=>GU-9g=e|R-$TjOC0gLx0%FS3Xv3u7 zu&(I6;Q3`0p!xtxc<1B9n;*!=_&~ncp7w<4v4~55WLMJOhZg$nUp0tpJeuR6a-FE| zAIY6Z7V-=q7E(+8pBKXI9dl};L6hQ3wM0nX<$|QU1?kR_(|+;~RI>1W!m&^O`7U_H z*Mj)KexE?pyP_9{s`}zorSTDgK{^g5J6IGudGr^q#E7lvhao$h^FP{(D{0-UNv(~6 zy^l5r{OtC#9`Ga&rMh4ShN;%X5@}a%B(5DP1720Y#W(L)pZ;}mJh(UosWdw3;JRbKg?S$N)*#rcQU4$d&q6ziOC0?3t$Oi~ z=W7Nh^37E49$obrq6y5Ox52v3l0Du0M%GPqIkrZoz`D%);+tUip(-_6mSh~nIx;GK zg6l0$ZkE5~J>xi7#RkuH{=Jl+V9{nx7_gM9V*lGx&LuX6nCv~DzQ;(cbh)b*A?wxjMjI_^A0@;J;3ZUNd}^;9*Cc~$r3&V-trOpA6L#PEIh z{Ez$skyPQuJv>SxDgRJa%otn#VFENvbV2aZd~ctC5Xm3FOLR$^y8_4DUZ00lqNVlj z_R}gDz%{bWOPb#Yxwza8I`2U$C0(VmnbP+y@u6)cmsLNT1+^JOaUbCXMi5 zUu9GL$9;t-ILyvhsewk@X%ZrJ-6i&9f8JfyWcBoCWyb`xa?zy)wD5nT9bH-u(L&La zQ=kPAL<{$?-~AOr5uH4{t@hV0ARR*ln}~$X=KmHpv73*>lT;t@2kC2Ei8;xwyNdUW zivO)M{NPIzJu;^hxc&Fbtq@>5vf<^;D6V3paw2`L16mSIh#@^(9HJvKC=#mJDbc0V z>{vmiqayT>dscu54jK#p0a-o(*Jg{0mlXhY zoD0^pOfLJ5PX@FWz}?d%087 zrO0X)&Kd}$Rb(iz7{KM(-_)M^5$n|(572^GeF%MjlNp{8avWTk#e*_?E9El#ym;b^ zECxZdeMPd6%Fy2R!VRWV{-~tl5~p~6-Wl?PJuF>E(0~evQ${?*{w$`t+ps=N=Idp$9jbhgE8=RC@o7{s&MYk}na5S~Te3RVBss$d3UWqn9gB$JvW^_d=rr@)VQ zsG8o-`f^R!FG!=zzN$nLkMgQ$r4-oiog&TC_<~C>Uw#Io;QNZ$@Y`e^QcMbEt=Y*O z%Wjo+8WH0fM%E*FfDUA2K{W=`GHhT+TAIf-8uAwUn9bn>m68ymyPxC}(H>bCo-+m=e^?Hy^X<-&@@5Jk3ls@ z?|!mkW|Umg1Af?6iOrO&qoJD40aY(A)UVI=jzhOsrrgoaNi+7|t2m?Xk68WJRr8I0 zX!m4md(HNjC}xhxWIqy;Hf94##iyM%Pq5(HH02yi;u7n*Krm&I4+5T+y=QoLv&QOz z>nHc%M292@>X;iw~upWK^N0Y1JPUOxf9>h&K*w zjUMSd`2rJlYUPh{^Ip@FV4#9)MZoFkN#u7w5y<0YpQDO%p6>g4X6dreY;S>7Gzqhw z?-*3agR&WF>^W&YqLK&geJR#$2@!2vsgp)fINQ%_+D}myO-4DaT8-9x_QbIo3|{HZ z(Wi9T-;LRB$<`JwGYwkVm5@BJp6^SJJ}Dn+Z*4L5jf{7HGj?~iRSN&|Wm>!Cu>h4k z1EAX7kF#AGF}c4zllWOHMPqHSq59QjEA?sRWSMxMq)A5YYG0GJRQIvXs#J=AbJG>X zYlDk9#690Oe`He1ysJmKmFHl7cb`f9WiN>Rw&6j^AD7BQ$?^_UDYC+aXk+6;@Jw(p zxh^((n))wfz?-r1Wzo|8JMM^s!m|Tg5*mnLB0u^j(m-@IcdFA@GYLfRu5g6h_PbD8 zc0yX|Y*lLL;0;+?Zzk>PQ%?rV%jTP%Hu`T&W4M@x+Y?m?zQEsZ0W-IiU({|DEy5O}u5L``3#%EF~o~<}Km0YR;mQfFb9nT9IH*wb{+fx{lNbtYn;=j`HW(7GctFnzdJ1sMwkaXR=)!vYk|yN-B0(UA%fz=2KWlx@tY7 zdFrM=cKo^5-{QKJZjQX%R>Gi?v;AZx{vs@s)CZgOwsDUf8;jY9ptNL^^*vrW-bBer zgXhw6T2wSNb%nF*>|ls?aNJI#MeSS#Hf^%2Z_j|sffK0d)#^-VbDB*{oM=n3>$Hj1a~bIj!2>1T+pBI)y|@;)449&7%IFHOKi0c(bT{Kp99DWcEqx!oPaJ zO7r8Lq+)BhhVD1FpbrV>mKo^qFi`QpN#v}1gN@)Q1k;c;}aH(L>xy11R9z^2i zORJb6GFts=+@E*<`*^!QoarS7j|$WI^8B>PM(X!xhFZgUof>c84|+?b@{-XQ;XEGe znU~ltNl%~8Bs`;6FR^BkBHBo4SK@L%Zcs&_J5hW;jHznUfGI<_y<8uUl2R|FJnn>a zTcMgeQ&dd~1L4Snhq!sk!FPg63hr~CquGqj4_X~$5&1CDqhwe0xD^xFSr+#)KR@D1 ztzH9n72cd_CYi1jqY!foKG@9S{isdf(SBuTbJRaxwZNoUL}m{tEA!{Iq}fvS6+QL2 zxSe4EiJ;1Llrj6;VU=8HfWQ4 zPrT|+?rGp8x5AbuP|gvT2D!J@(#dY29|~ z)t}N+gB2By>)ra>UCiDsrFIs|Sz2!82^tB}tj6!0llKA4{Ak?EI@OgOo2Ha4psD!j zA3_4raMpAlh2sRHln#V)TQivzaXPhu+wY1s^QL+#a`cw~dcr>7%bP-fy={H3bzVwTxc@;t}d)+DRJf}?R(=?SlF_Kg*zhbF$wMRzO zQx%44M*qqIKzne^hVue)-C?R9+j z_(Wbgv?WOg(yOvM9l$BP<4ZLpY+sZOjHX=_Uu}t|L}$>2@j|tG&aW5Z_Bx~*MhBS3 zK=H?s>PYM9yTdBc?LAVlY!iG(iV9g&#bUO(`KuVhV}L(%Y$h1ADR(MF{KT)+5>E|M zC`lKn1-ZPFVPEq5!LtRX{a6j!M4b256bmF%+bIA>k8fr%?2yQOv^<;BY=1finEMaf ze6AVDlD$b+EhxqiY}=Ael&mGT=_8YtmY#k9T8{Y#!$33raf|}1bU60a((UO~`@uCY zl_>#?`)vtPjD#wi;LYOU48QG&f?G*A1{lG||2grKDI-I3{I01^3*UXp1QtL+_N?0ex^^s)C_`Fn?(BpAiWs0 za?$E+gj~|iZrR2IrOI`ojHXwnx0pWPtrLe{9ew=X#wj@Ewq2}zcUinPf<5PlM^dmo zkYDt#I;aL$TV0js*S3ldT5o3dj!{69X|9+_h?+8JPpJil?b?*0hFulCV_ejR$F7>< zvb1(Iw?jTr15?i(yX83C$3&^EzE{{~G$7JDu~R$W z_zBj~%2cdA+t%(uLfcOJ;3Bso8P2uB#i|RMKihBPW5?v0^!KO{eO6VfOp;Bn{*fp} z;?xBZDeU%>zyTMiZ*+$$-Rw0zIpl@}(>aEV=el!*GhOHP0%;1rK9S=-pJ$8snVvTZpqNih$%2TzZt9^;ujZMOrW&I3f zXrJW1Nd5G)`U-FP&OE2x&ktU!AM`KQg+|Y;#D1nRSR*p+^*(zo4w8iJKou)tPph^N z0$%l-7_i0Sj`^#e<*V#Kwix%`DL~u)!d*~`;zvLNIp<5zqPTf}sH*kD-dM^)q zk<`^QR-|#x6svf13}2E#vKvTH#WOLNy7i-{mca)HhtR7|?=k7td1GrQ-A_-Ee$RIt zTIbqxJ$Vx}RFK_-!oL~v4BGIdb2M_xkQLUupW#W;{N5aJ%}ZZ?yUVHyKb9|?)p#sG z_-X*;x0GFHV$&ukAVnG~arvf@FKEURfbCph6Q zP=;Clp^Q5fT=Pw4#ePqY;dY^TCb}bn!EeUf0*c`5ET;J&V&ZRM)QMj&B}w~0#cV^llyi2IkS)>yL= zV$Nq_#h`aacc2g$fX)_?-DE2H5|U9OcuB5(l?VfIa;^w+`Y$fem5&N`p;;3yf`YX| zC7SfwQ-xB{*g*a@@4>F@f@yF5{kjnP)D8KIg6Z4uSxsqU;P}?s8L`XTCrEhJ+=<}; z+fLf}q;`^0<7pvBLVIZ^Y6wHB0U%-V-hAW!CZdz$^`V`e@Z=VT>3Dn7aO_V>gqm`g z+Jogz13o`3GWO&jhC?|qy<))PYg)0#`f2CHnX7cBFBss{bF@#yOaQWM zw{jdt6m$(pRDN~8$nU~SorY_%s3Lrk9(>rp0AzTWx(J%lO$H83`&|z|L3=$U74<3d zsg_=_Iq3me39%V;QapisC8^nItzEID+{vMAf!;f2e(99g&(AM*7uC20Jf-E51k(i` zt=6a#LW0PwXm%?j)zyoGSHJ1Xs9b5YLb}S7JU@ir_nFD-#ny8M87D^Ufa@5qoTJBN zF(Khp%i_HZoAMjvqlwMDTVroHzKz&bn9UZacmeuTM+ZV@2?dj7DIQx7gLVVqp3P}s z4fMR2$tlvQ#kXJ~E;w$>o)zN)O=7~^GH$UR`2wEUVPpv_lg;7@5@D7F=3 zocXSxL`b=q14zK)L@v^~Mxr<3{_)jZRKOK2A}`A=gqu;@A&>!(iYbL4go$zpzmT?} z5O5C!_s}DKMg?VcU=+8*G;S)PXqz)+S`;)iV$sOCcof2ZSL_E>;c?!-(lm?8mlqgA zAVCYO!J12wzXnlod~JDuZ)Y6x?>Cw*d-9pvW>7*Gm?Jm}?u)`m%PSE)PAYBKH(Yj? zyplrq+Uw3`s2=R^31OUSV?`<`TG5N)DrfJd7sh=4hej#(*$sp77q_3Z{3Hhnb`sLd zDG9CJ_>gWj)4^mjujbT^8Kb0oJ`EAPlo(JcSlYN!8ZGk9J2APDC?Lry3 z0UXFP&ZQ$P{@m#qJ54O+Lhd-LBXL%$faP}B%RpDHOL%B8;O<9e*7<{)WYv-=rxQ&g zC@mOKW<45bvM6;N3?rERm2H92z(1Xbua9UI1YmfQ1&=?d%wc0%{(+po{7s$dwqykL z;69e;^X*`NgV*Bb05GXyW_<8=*5{ZtBiKwW=ab|`fDRe!kK{hJZ*Rp8D1JJ=CQyN$ zmE`I(lQ0if{R+vK71ESGFedNa(ysmn`)CYOo9zgdPhTy1bM*a7p$wkzIhVn>T=E=! zz;^Vs-QHR!w`nLKPTnd-LdHNxd2>Tb3@)=~*U7Plm#1>Ak<)>l6q-)azDIF;2A#^Xx9( z?Y!RTwB}1lEh9+c@LWtS`qmoVI3(nuoc60peb&9k_Jho&j}&J6%+$Gs((7Ur^rcm0 zb|d5|cHBwDK28-vOWg=;yK3Uhu`dPj;FDA(Io+Yj_De0#u7lY>UcC(jlEa(|CGWp} z@TDN_^%ewfBf=5H6I#nX1W>0Wd6&MPV{+QIEaNropnKArpFW_-3prC^hT1UgO(ci< z)+)uDKEwQ(V!9I3FzIG3xLgXD=q>i0@ox-g6R+|iTuX*f_)^7gJUKBc5d7$r1x=bv zx(Z9D>S{Um$0S1aHUnw{*-wOow$iDQ7sCx!LR3v|;WkPUeufXf;<1Jl=p4ilwi&eo zlSp_TSXF6rmznyOKqSOaB(c5F0J+jmbP#D(q1kAhVP}Rxl6j}P%~ZR|s$2aT!bda; zX>WK3S`te@%8*5F@OuBU6*t4$ADtmsl9ma>qL- z^|zMCWdP_};prsK!+(kGm3%*s1&#_Xi~cWJ5o&)JaV(v>eB@p*p$QR0`l*%fzX|>r zS~3;r?F9f0?-J=Az&5|IukPRsP>7lO6N(R{b#RvFSa!|T)`FDE>gT5~Qz&MrWyseq zjn>4g6`AX44I$W|!+eo&D1x#V#Z<)zy&M~GSgSDq}cw2A)Xds;WGI~%ALJB5b=u3A~|iQSD;2@P%r)l`1u-3 zJJcm+>W#YKtT--er#+9sE-=Jw9ZS-kDX`kt#a!t=2<5Y zWlNeeb1cqw>sq&!x;h0a=Sh0rR!7HJwi>9~OS38iMRkq~@9v^Iph#_Wqn8AiR%iN4 z3gEdA0-4sf9L%W60G`~1O91iO_a#hKu26mP0a z$#sGAvJ}r<;iEnCnGaxji$HL(E4e3Vykj(;GCp|ks+!oFXLtjAdtPr51TTa30MJPt ziOcSX`c%Hk8WI;e`Ba5qc&b1hq%m=Tc<5oq!xU)@d{h@dFPYB^+dAn!h9=M6sx0sk zUf|{k3JcG)tJts4J}F;3faXcv-80;A|1f6I1|$LK9c!*q-zG}PG7qH9T4U1D)@Ngx+Pi78A2|kD94RJs>YMdzOMz> zrrXypw%5_r@uy$UF&*R?RoDYMoM>`b%FR4?s*F^#q+qi)1J+;~`9Q!C#bHCWk$S2; z)Twkmo)G(vcWqavE=bfXRKs~ocjcY^M4LrI{;xW4+Ho$gQ_%CCNyVNuF^!Bd(MqNf zg!dSquy97+JZyiJ+Nwg$^v#$k_VLt=WOo%)I_ujP1im}|SpyaP|&HbF3- zD-Zx|PvK=nS28o={&1h~`H&7hl~2ycd@mmDC_d8n@FBFi``SnjYm8q0j^+M|(^Hu> zmoMiHvX1J#M=5?CMu3|%RvI54X2C$40_MR;#4V(rFLuL@Ng7CL7lms4k+mb>5YXzm zyrMKmK_DpI*_J|1LpoH9=FPEClpMO*nW3Kg4{>!Kg1kj?Sm^*bRGo~@D^Dum$>p0a z70shp`1Q`@oUEs|+#b96*!NI*5;@ziogIZ{+C`3AABnQ0b$2!v7-{0(vl4ngX-^3r z*jT^oX+Wcxk>-ATx)}RwQs~YrdcfWMkk(H$k9w5jvS@6{wnbOg!$%&xGA##jC#a#g zz5!@$6452|8Q*$0dj`3uG*D|ybOXkwidU7^r7g_e3K{krK;w$lMH@^3Qb%&a0*6xK zq{Ww)!e?miimt6FXv#F76%^vN1>yl z2q)&ElfIX-p6}6z`8E-XM-wqpEj*%ir!vSpqg{p1!b?LsTnvj71^9}6r7etEp8^h^ zp2+U8gGR`j0VRMR*Adh#&(P$CWW?(W8n&P4sUE4xeK?gD)1e)Pb}(*^vqPmX8Y7c)!gc%gl10H2;abkIz+VzgVdP0B1SdbxXtc-dY}< zOkS*!_wJ=i`sXe{+Nb*fH?oSBQ?H&TqNAW4BlhW5a=SHo_ckh>fbg%b7k zn&!ECytqKIa1)XStyBtulfpSsa-@>O_#T3QDG@=~DC56^R{FMH8x`xd;H-*;*_-vg zM+`hXOiiTFC;|dZ<6R?Nh(T8=(?gtg)?e74fbkLvnkx^GB74MV#s?RxJy*L1cMI-N zcVoWaeE2g4wNlo50yu&l>XM0kAD_uRNRWTf`X{loT8jJ zhrM(m-P%@KlU}Ru4Z&wNT~oG_^yF(RlzSlJ2@m6DB4X03c}bfC{2Er@jknX#$K6qb`Kfmr$~jN zhJa6egd8B#toU7pcJ6c<#UlQNKptbgWY_Y%?q!jvMGWvcNb#o8XcZXV5T=IAm@GS8 zaLETkis@&fqYV0(+xN4GtHMECRnYJy!EC+N59%+mZvckhbJbd zkmsGY=_^w$@i=pCKRD@!=)E7YU3x}k9d1_r@)()|jj;3{!A4 zIkH%vut{SdEgVxDY~Uf6oh9^!pV3slOf278TAKSJ4+|nyL%-)o%n*B}qV4?UJYKb8 zVt9a_(}h1ISojVRq*Zp~5`T~m7q^B9nfC|=rJyADTAM7BanJ4kaOiy2LCEe#Gh zVRE$XBU$9Mnx=pzosZ)4b04Vr@Ps@_#UAs7ufl=^5Q4|g=Cj;Dn)`+ia#vodeSB1? znZYt&T$V9w*ZpD;3Kc(SHgR&iFo9y;@O^{7T;gW=-xmrb zRUfYX%~2-so`R{G<&H&d=`bs8PJl@af&g~PQT{#%W7dqy9e{4g16KWyI!20BJFkNLOLdC`DDnFalQ( z|N7q*f%A$7B#Y_k5FgT_?q$Ih&;*2;=QR`yQ+^Pn6jkz#h_)m13%vjp4+4ax{;;pA ztj5`n$R+@y3#IvFNC4UE*L+(gJ=5a-9J#?J#J!YqzAMQT@Snk2$w-}#AR`EUNbH;B zY2v#;wg%QI{>VAO4b=b8!47$ZbuIYs;*kKPB594>fD7sd=2T!1hVIs_TOT3UVYiu& zkV{jNhAn;_5--uYgk)Yqj10|+48wvME=VJ*yk4dN^!$g9Qi_PK4nOM+Bpdhc-#yeb z9yv%`K!^P236ORqNINT>i33$uy*>rkujLy(|68VT1A@T1C#VtMFf%o9kl?el%!Q1) zXEe>q>!7OP%|EFForDSo9Non}Z&O(fqL zl>iP7bdv$VGnFJdi}nKcwx|S^RVJg-YKiZ~4Nns|ukF5Ae|6Gth6mq7Zvg!b&2o z8w4lC)BKi+Gi_T^|0tIN^<4TaO@@FgP4D3kf{Rk!Y(E-YD{Emq{JbO-Lm` zpH<`{Dg30qkb`^t(D{M*6jXvuiU#ipR#Gti$}NuGK1#k(pW;F{x*%9I-^F!mb@=}{ zv;g+Qe~Ez(huNr&tEmxbVErNZ6D*JRzG(_P%%u@k4Ykqe2~ZUq+*enLSod)q9I=Wq565bnTu zusXwH2QeuSkG4Elc<#`q|CM6r$~S`M<$onGGW%AsR)5bLeuW$UFH7_IaBR@#;hiUz zznQLC0kDB5b#lmkSfrfhN_y(wS*aqeNv4ON(G6+h5xXPBg8L416+8>CD__FL8L1)! zNIzpBB>XhB66Ip6$F%(%`7alLFme4BxtkWaPOSA)-+7SO6!x2;!3_jo*iN0B$(`v-5a3liKT?7K0^aTj;3_?czPc(OgulLut!~QS;9sf!Z zj-$`g0y$tk(%~LL&+8I}T9UJoRa@xDiatvrH_(LKz~cXW18#(W^|~v2Dp@5BkFLsx zhZM5MBd>#-BL7A39Qi}=^u5BVc8}dTnV!|arO=X7Yj13aL96ZdZw4JH%0Efo1|MY$ zlOO_kRXEs*U@@=}rO`f1Tm#j+A)Dr@3=uxKwp!_<7M|`_vgk($jAQ=>7M24gY zi9{rWJZi`tenxW8g|LzTe@LFt&|k3oQu7NQcYBItMh*#^})97NG>n-d_&7k}ONR|5VY_^`x=lyudNqF1&My zF}TS=zz?jelsk%_2&s~CEWra8LjGG!2Maru?XzOpnoBhA45YrU?XD%fDn(p zc)VrPEWo|JY!w}vJ7w~5j2|edsDQ=C1Zt%C=ankrX}l`eSz5!7BbvjM7 zv8Z9Gr^v|2{HL>j?Vw>KHn6K&?d4_%Af1JL(K1aS$5G=s(+hFiVmEwPLW$**)8qXq*fVLX`9R}P|K zEgo3KFNC5ON3F!V>Z~A9BJuKtVny=-nU3}A$4H^Df~*_n-;O#Em>zy$AK$}p?0-d5 zR7m}|AFlFVA@0Uu4q$)7`*~fmM)>wBG(p@<;yUa5YHMRfT0(K>N0*!Eg#V1bfTZDhqeN`Ixu6aKZ+dD6>$7R|MZ(ar{Hf^U;lUft)xLxI#JFO($+?MG7RcmWCatcF`OS2yHaGSoS@fOJBi z{6-Af!Eu-f#QW&cqqvQiQngth%HEjc=ptX*i?eHEn>yQDF2Wg<-lg1v*;MsQqqYU@)mvo9hU^(E&*jEa0j zek{||*>Q359K3T}YIjUl&Pf0!OIGBOh(A~6Jgy+E?NC#0jVJzslsRsE{??D-6o zCEr2Eol_Q-4O6D zcdyj{M9FgmBHpOz9~mFE7qhkD$(j4SqswLipp2Y360uWdd zN@*j}GL+6Y@s;w8!usqcBa6Q=;#?PtJ(1@~IEkX>yUJ=ccaV&?WfKQd8ah*}d}Lwx zH!H(bLb?;?GBl|5KE+&o#Ndw#s9?MhjsLDiU`Pdt#!Y_wK?i=qwfkk_xqL;%&EmzD zZ1J0-`}&P~$-Rqa>dkC}j@N+3`qXD84h<}i^p=~Vrjz`0Tw)rw{vduyVwK^|(7jel zYn;wQ7^JsTBJ|~?lt_jutyuZ9S2zFN@PG;Uj4I@f3>l(e*SnCC*quU&Zx&8!iX_$x zyY-vwhm0#$vD<*IBY15@9u>I6V))1#(JNaJWR1c6{T$hgfoxTk+{a`q6OB1>k~GMr z9I*&!6(oSiMQN?UglAyg zL$i%&tyZ}B2a&Aa$^508k6$g6+{M%Up`VINX^4vuf9oeXR@x|St;xT#^P4f#$ zdbKXt3#ShxG>Dn*b*@1lv|in&U-!@^Y|mW;HmW6XO*FSn)-P^V>}(BQF_nx!z(X#K zrl`If+2Iq@tyN-q!41mGw&#aYFfJ(}`gO^0`u^?H?JNiwL8$Ux3?&Fejk(~nJvtn} zUxtjD1jW=+{EMk|tp+z#+E3E}$xRvhag}(t%5g5ToJL{zsE9{#7a4Shv{-#(f`FKq zK3+U@-MTi=;;7)Vl81sTkRv^b!g|Mu-DUp0PDNfE0Yh(_56$>&_litf-#_NNUqzpE zWqqJiFK!F8M{U$af;*0zSqLTD?FLhbl)TOp${yOtvfa?p{bqNBapyD`ptKA& z4<1Ex!Xg+)`CL~|@bPqC<7f`=4-@C8CKHN2H$4{j$&40XE<;hlCn#Glc*~<_1R1hN z@~i0MeKUdzXR(>c5ubw za0CmdJzc%o<{^rvh3Ns4JOqQXUp68SiCe$?1G?hTSo+q#Rd|$gih}G;ObYAsD(`EQ zK2FC5QqLGuU(J-}@2%PS*0*qe<_m282ivPt+G-<6aV3(?2M;dP+1*?!j#Av_p*1}{ zA2q^}jAV#eZ}{4l&CKU|2#e^Y=!@u0i8)V4W|M0sjpYmOv+_HCi8?9{EQ4N z;j`L6qrSsoHSK%bq(`*FxGTZ%p>7a?mO0EKyhZa1PLBgRA&Q)lVLWr4NqhR{3dgS) z^a3Yh%QSPgXE&W8N#QU-a&CXOt&G0x+O8XHj z(|WBR#KR$&&I&F1S=Lw%c}!x74DPz~HZL0w&Li#`;mzL$J|~lYem-~3S!=jwa&%l0 z9y;*jZ>VJxz5xfc;Z|AO92U{OhUUs!Vnj4YkS4i|*676PkG50f-1$-c+k#^k zi4d$95{*Nw*buXP!S?E*CJ=RCGJ?9Awmw?mjki=C=+tyfsgS$8C>akaC6pbfzRLM9 zq4btz#1&q%mh^oX=0VXv0H6=Ne*aQ|A&m98a$`U;eH~#q{rvg3yVNe{vcQ%(&o_wMIWZHnfk>NYeCF(4*l@rRPmH`pRG!{7$Oc&tw0P%-%Ym0x-KdmXB7|og2RK4x{UZuUp_2Ai7Wvog%I0f z*iKF!odxh)Vs1JJ=6L=x8!FmT{GM=Drvc1?Jih1`y97kB=yV}!~>K0lT8V#pMYh!0nQV~55QyH~#1b-#PFp*1egM*(SfH~2+KB{X=B~EK< zhjP+5-hEM|1?F^*OxFNYjmt(YKXXq;(aB+;IFM7SvF-75j^FoiC6x?Gr&4QUa}L-1nhsIcqtWYdIX+wx zb_z~y?OZ_s5%HE_>{{&%9xf~%sJKem=3(>PgEmVy0v1X(uSfhzdr^&qrXsMvlV&4b z*V(g7lX<9AhRJF}a?sR$$WwXk{T!|eI971b)ja=~76eQ zH`xcHE$z1Gi(twwFzKUy^L3U~h3^$`&eb(I zUgBNc&gb|CWeHNi3GEz92ydw;8FV?z(4T;uBL;g{5Lzce-r+JQ08KlNk0d$Y|4K>! z$Ke6Ct6w1@tNpO&GJQ_y3V%>Iu^R!CWHv#52sSldVMqX4);!Nv9QyBa1p`N`pL>zW=?Xvn*_&>$D zdaSf8&EdG;pAQOX4DEJb!_P5EnAZmj7A=2v`fho%B_7B{Q)|4Zak+NPG)|#?xg}k@ zq|Nm8`95?sBEc}O31e!_ghJJw>Q7V5lY;5*;oy$b%j2^c)lc?{kOQl73@{2ThOHr_ z^$}AXnFQK+h4cfh`{LE&`LOXKkFMs zd7+6Udk|2bRksc&^TDI;n9`%g z4XZhxQ9(lcnmX1CJ>#KD3!2-hm^2M8ahhPp;H2FkqCv6A0n@kRJdQb;rJH@D6J~ej zp%-Y~0oe46s4>{PYd^@j%ea~d`iV+Nu%;26M!5_WXz+oHbM^Oe2cQN7Q;Xn1mmcAT zfH)UemOVIwQ-ss@x>RVUit+1TJ?+;7n+xAqyDyYI*qB>)v=N!_HT2Nooq`l?d2Ds7+9 ziqpfRjMtWIprGzdpZ)>|BLequ^#v=!N1h(7ZPg#^P-DkWkN)K>0)T2w`EfGzhi85z z4AhPIY#XawS-8M)Gb1e5ZIJB!J{3;k5 z@${~}FZu0z7C~Hh=CERHT`&*&b3`Pgx)K=AXYOX{6tPDi)l(>Y#UyewRAdxgeK%!3 z-lAL^#9lzaxcB(m>MK9UWftLTaAJ>4>dC|X-Z=fHnB1p$c#FsM+gN6K`^Ncip~8U#7I);BhLFd?mK56t1_dQ*x40wSz9B;A^kHUpM9G zbr*UZ7j=eSn|apE3$!v18Jfa0A+*#)D~fEUC6-$0MGFf}`|e)j7G90hYtqX*A6>>)!*cwFBov+u z{T!9`Tgu<9s5T+H)E=rha8;MJbt~B`-Z}EJ(=En3Hms)oWDEXVY9#R%zIJV#nIh}q z{ff6%3eMcST(MsybDdM6R9dz7WVkmr5&gDt(QejH8|8fSvb6p}A(LjOmwnQyDSgU` zDV8%`1N3i~r#WMFn=4NCPxQRKVd~VMv*23FX&y*tmTSm$xh}w9k5FXiOafRI?(J@B(O_q&t?0eoGi(jQ8Pp8v*Y=6qDD? zgB$nVYy5uxdI|#!xmw<|m8+kXHJHPv3LZS-0z#S}s4cf<0gNJTbvhDALuOIeJ!7>D zhjqDExM+$`UWd=X-=U7S;O96jXHmNi{I>kj7bGn_nzp>(Khmg{B52v`m#lh+`~hCh zfbdWADULxwmf=BeR$nqL30EINB@?8RuaVRHbv^9+Z%%w)oebW|(*q7;1#WiW3C%R`ax8 zHM{OkoIUuSB;Ds=UqA|DTq-m4sn2M7u@-wDI;ZaMR;u=+u}FB(vi{jyX|swV;^Ikd zDdLk_cZ@W$jGOjKPoj`p^K%8su29zMg7E0+x<%xYC6k1i0?cPYzALVhr|*5JLy$cr z>9hV;99eI31bSih&It?j)2qtL%z7MvqE)T45=j|k=K01Zyf$K;c%vk-S@Nemtgv+4 zX^OrgeA@sul~=t~YwETp0LM5~4AMy>r?2vvJ@ni>5SbOsHkj7ltp0sLC%|@1sN}LJ zQjx6o_&v7j>`B!NOj0bSbxt87>6jJXc*>>E{A#KfIcD{4`8?TQwc7r*AJaHp5ZS&D zi@<2^GW}2aG=^oKPR`EV(7NJF;XqD3RwZO7cOxFA`AC4*frmi8T}5{nvSz(Mft1tCUWP8cIWebX5G8zHFZTIYOBqN5dk5Aisd3FGUckfHr{!mE zvvhr(cg7z8r<)u{CU+R_5_7k|2UHri7}d=eU~+LU>z|j?FPt0nj5}(f z2tqvX2gLJxw_}@SFLLzg$?)(0C-oHtmds@^)QrFLJ%9#J9zTGs(8(!p5U}l^h}%!* z?raaH>MwsAC$;ET&85#sTnGl6WJiNEe^q)w$EHO4(fs$0(Rhox&A*f(6o={n@tUCK zg;F2Oas8sTr>f}lPdUhKe#Vd`B7tXxUA8kVPcA``9rm{G)y8qB|79w6){hQ5Uare+ zGmUyNG<+Nmwe?Am%MB3-P@D>q0Z;@t(4_KMpBS*oiQ4$?b6UI6(+_!G=tbn=ehBI5 z_$*Oi9aXPi6TY4^OUGg^Ch_D3dXSDpkjdQgT*zzUL$t=xbWk=VXj5>X94?fn0A>Rn z)wwzcI(VZXIRV;2D+|-3ktCfQ6>snhPZBUPx3#N_T(}B6iF_#nv$;|F^LdYmi8jgK zzh6~m`mX>{NEfH*-Br4(bY-Y15PYy)cuu({a5*2AoF*;7vp?xfzNgNCjLJ9Loc z&`z2V$Q9F`ig`<370z?Wexf!QWTkbjnx-O>wP5D$NV1t5-y>SzWcizUWR()jJ1z7&g$zE))N{qm%&py1K>&-y@ z;mdNIW>+@_+uUey0*^t0ceVfBJ3;-N;P);FWeFwOd}?Hi=3hST5MBfLnjix_WNE`3 zf_0ZkKv*l)E2P7DwWDA37Feo$!F!d=d;}X``_lS1{ALv3evg*AHKm zyT^ApD++Th*qEWkC2fez>8ORqJ8XF|PXCu(0L&wHoWhI9p-74#7%oExO$}XFic-X= zv;oEpK0!C-i__YNn}w8IHQqm4U(}7(7i2hwPn8e09l2ifhI_5NfP`Phrb=0rr;|In z?JWmMESR$JuV4I(T_5LAT~-so&luh)@yxsDEGQjC^3vH(ba={?_0IT~arIZC>~->3 zt1L6r)J2Z=9o```p4Vc6cfD~32xu;DMo9^29$c0a_56{$$TQd7>@}1gl5Oz(S8Wk3 z#F@vC-hBTF+A%Qac*A;Qxe^K)UP`InU~uruE0!I6t-M?XMukHV=*<@ zV0qKGw<*ol;V^yXpE4qrp-8JXS9I~~Yp%M)Vrb;TB7MA{xRnTsRcowF5v_3A!?v@$Rz5w7`@n=g1AIEz&~1yjBa9>W}{1& zvCU~-S;=f^VswH=Q>Bfq>u-X3l0&F?JT_g_HI!E7Nv-{VvG^U>lJl$Q0>@G;Ly!iQ@FRYgC6A( zAO(Bl>$N_y>g1THgC*0G_R6R%C+de*CwN12f4+20t;=6hksLNegqkN}3z zP_-LXuTP)l(;TQ*VrITQooTpL=vDxflMmsC)CUe7%vBCvrRfshIzYyPBTqFkrV)-- z4*4PC&%fz;nIe($taHj^!! z2HPt(pDRr~ zAU3)zBsytV_1|-b3pK1918OuS&a%XmCo^y1u{U8pMP^0CdPREuzkD$&olcPf?f5D` z(t;OQ0qX2^ubYiEwb+z4O0rwr-wDIJy{pXF$GqtyI@cb#4TG%#_JV~$F^FnXg3bk; zFE9rBMSTl$H+1_yAzUkNpo<>55JXYIlU-`rW&z$PmV4yI(V_QQ92iI?vr&)|*@Ay0 z>h+nwPXzjFazD5^iLcol{hFCCweGva@(2 z22pT$^pHtf#y~l((&r@n&6nTEwOsDY9GUp+Q#-3{;mL~P-dHsJs|v&2*q-I3>Rh>) zm(miGdxk;MdS~R+KQUq-MI-`0J||Isbm{Jm`<-X13dQo~I zoTCO_yFFKh|NH$~j3k-bP zKQVQ8F~eA82~jl+san({9vgcJrRGpcl@AR}9@8N?1!(G?l<^X84{8yc&w~Q?he{|` zn6c!^!q2pc_^1uZycuX`ZIjbu9@!~rTDjXs0!i94rA0frW+~g9Ro=^kZC6#snGatt zbGz@XG(!|BDdWRa9;jflDu?f1=F~7d@HkYvZ7eZ=WI`+Lf2g#56;Tc?+Gu>U#cOG_-)Fe48!?mr%Aa%q_0q1s}$iH`RdmNbyL-H?@ysotZa*t`4a9GzIez zgv|i2_}u3y%?3-$r#v((wl+s|r>4E0S3Fb?wf}x_kL?!vrk@*Q-@oj$m%eAgVX&lz zZXi2RM}%fwo^kGT>ckj;5&6^K$uQ-h-pU&0QAs$ERF36#JT4Jg7f=5er5wEW!X5KE zUHk_wzw7$FIHi0?4|tvB_TKeD>789r{7>sY9y`q2hH$pk1xhx4RLyQ%*zCNyR^W6o z&v0BgR&)UceQZEoD(SzicgM1&Jc!~bhBR>U@Yo&i;jgYXbKE)REBqEQjvdnXQ)6z+ znkZkF&a8A4cSCQSV(WWfD_O}lZzX`J6~{5fwv9W-1}bXUceOtD@IweEYPwy_Qy=#i zu->9+DKrlogdpEz_|jUi2dlp>E2j(1M|9jgo83oTfZC0HSIilBba0$0SI{8U#_z&G zi>OAK{m8B$op?>KHeNe$ugYdY7-oD*@K)q1B;I4+KUysXu4L&vlUp9nFgC*F_UAet z??DH}MOaS^zA~q}w%k_c(Rp z=L_ajWTLytRSrm~-qaaxJIJ6^+qKVhr>6Qk^-=7y`0!3{4^5IR#`%>LuZ`og)U$SA zDTJu|ogPuhPK6dq`~(XIYx{Q{{M~8~UddZpTH1}}$81b2c`-Xpe#zYYDbv<%n}w`% zd_pUC&*1dEI6=ib#;wmHfT)}N+wkjLy7`(Pn>_Ni^`B0CHO^+rcKo&>I9V3)@kt8r z%H~9fwE^{{2L_*0V>dZaWn3sl60vREW!%k?qKTr93GN}2qu~^);OoC^qAb+fd`5cg zWJJL?J){(Lq7jEK79k=(gyCVTMp(A{GVv>eS*mL)@)5rC9sy8bR#J6c-FQ1O{!jrj_lS<8)uNplJGU-eiHm~P~lFs!{CLP8M8uv{zflS`KY&U*KDJ6-KbK~ zGA#MO#oTc+moy;q`X!G2YwKy_{7V}}(o2&g40w$-SG}Z@%GIaZj@SNg0Qfw#y}Cd<;ksu;1+a-!3DzS2B(>+;GEWNWH z=h!W`-UnD3zKX~5HPKm}9ZePr%U22#=-Bminy6AOhArcS>!XGBf=uo(n%Hi5s+`L> zy!*W75IzjO!k@$Pj?V2O$Hy4O<0wg=;zz&p)d>ZS#A9r?=m>A0<|`9Tw$}^&JMWxJ zEKTgR^cYWC=!jq&uW>6^F!Vn95tQ3&K6GYt;nXnx`=5?rLYN8jpULyONd+8B7TF?9 zkRnXoRa6oZKD%1ndi>TB4-9q!qw;XnL=L;yr`b%MsP$@76OU)k8x^yZWuLDmu5Bl% z>eQ;Zz_ca(gdo%Ix6QLlTT7W#2pD9*6hnge8e3{%LM@x4<5ZPQD%?32TG3im#}hDF zT6Wb&`8N94=kIOj6WbE`g?mTUK*EmPg)S^(hnpkjP}KT!dr;}^v9uz6qk?CXhYEx~ z=*vto>)7*0MQs-Od(1+9>3V(@v7V&s`sLcVh3%h@%;b9@~dsx5C9HMFW2zDPQgrZ}(!n&mAg6 zR(lQp=x)hCyBA=l7;tdz8&V%}7eg4uBez^|v*yOF+x%;i?U;^-=-FT2$}e}eq)n|Z z_%L^W`a-~N>c4!k_-#lh_whZL`zJmWX%vllJY8K9@d$ugZ6e5W=AWzu7%^P5jb#lI zbBtNSkA=sOKWWS4<+MQ2^Com~DpGPS*RpGUhkNnEXQtXXQO9hBi^dO7n58$7(-kGw zAWtP)7qfVT-72f`#TB~ZH*VV<=wG(JLbr3~6*}`^ZG^3 z+p$NJ?~TpbjLH?BA5?jpE&v6dymM1RMEIq4LmNvt`mx>Ve}|?l^ETiq9co?&iv;Ek zgD^}_!${cDQdk#0lFoHJ_C<)mn^KzEzY-M}&%oPvY;o8aEo4FJFa)plqhs(28b9%S zQCaWkL|$K#ji}MC|6$wtjvkGt_66t8M5~^hum6oZ| zr+Z&ND406h-T;k09?5*O4kOCKLz?7u5O%z_^X%U80&JwQ@(?+QQIA~4{;4cpfNhp5 zgAx^6V>}=h7{$=&)ao_VHNM}1IL|iTR*Yi4ly$;4V!Ltb9fK^Ms*X}O{Dz=er#gKe zbjJ#7BCxem7uZM2kh-n!U~m_$P2JHEu`bd$4?3aT{&But0qnN~pZ#9XsYY1!edjfi zsbC-9D#{$A{6YEvM~V8;23e7{iSn>KC6XR&?GQ$>@IewTz%Fw|5s%wmI(OTMJL=cN zxsA1RxoXO7(GhtuuOftVj&m=SBna=BH@wIw)K=|_L#O%h?7x-{7&lBKKpEtU%znXA zN+rJ)JmOvMk)RKwuau9Nev;A$Gn9$P@#t4ySz9qnC@FI2!t7GeMm!?Xxy|fNL7QM& z2wBAo@jWBAR;{iHabJjogXiKvok*^syukVe&2EY*aZtq$Rhid1G|Lyv?(&0O1_Ra= zoq)-S?PQwXKk}za#-S#*({)7`yP<6Zmxa(l5ZB#VjZxj=Cztrb{q!qbNs-o`iUW7& z7@%_>4VmqAY-khjX>w|2MBBr;=}R8b$Z6y9u&sqo(@Che zU3>{g2jh>{@Lxpm*?9A(pP>G)eqH8_QpQdt@TINYq(@-RB_=GhM2g;kw%StlW7ukC z;^o~ERbn0;BW0FHwvF3HA)WM8p`qL2&4k=M<88T9+M!QJlk_h_`l})oCV{pDyF;sc z=XNE`mL0gTcUGm|8)q~+(`8R__1{Xe9Rfx}`&nQw?`E4qmP9M}iYEUMlfa8SN#0BH z0?S1lE;PAR-trr-{?fB9vc9_3O1(5a1o=T&tZlVKyC-m1Jz1CT4K92n{QHic5qZVv zd!g4?C=K1UGx| z3p^{LckOiP5T7#EK193`cyg#_z4J-hpDhCI&t9ZsMEZ`|B2vV%+Im}ygQGoDcVcOL zGGGz}~I1gO;=ftuwE9{o4u&MH^yM_ZxmQw%;>VcU(DCG5iOJso#ruJq_$ zM=aA}uYSj-9Ss>01sqF}<;IFxhET}td&&BOTkt!eYQ#4mq=~-MY124CC-ykk!te0w zy`oPel%sQ2SfAIZ3d|SnBkkBs3>A1BK@G69lGULyT(3KAN=xwlr+fH@`EYj zLYF~i+j9+Jr&*RBIH4bnAxC+3(85tEv@E+0jH-OXbAq0dd5F~jBjdfr*^J&bJF-KUuH$c1?7uN z-IZUqwKIzG{wV@BiEsqChO2d!KXPABO>W!Xz2M-S(^z4M!`ai55Kj-@o2Xlh3#Dd3 zkeA@w^8*Vs{1$#KgONv4PcCHp9S(6$alP?ptG-S#ZlgEP<@KGnvsgFy&h=xM_piD5 zYlhmZubo+~aB9;FLN^y_vyT=~&P`Z|cgp-Jsz9Jg`dxyC0xrjv32b-1+3dl(*9g;X zSG}I-b+(YSyDXzO8cin2mJ|OD0`8J;*W%&O(srNpn^*x4QRVc~hmX^$$(|)IR39e| zUYaa}6&1n4UdAxYPDRsNu|EGktlwkOhoOFpScym~rd1K&eDDFJi_?p@bxn`N-7KJC z-ZhtKbwUz^=lMKUSHk1a3CEdis+|s&@l-B= z038vGx}LKqNTKbY`9QT1N0Ki~RHGa2t#k@dUhIy+LQqgugVH!3z7vs`z;(+cD(1RJ zycA)blc+TI9kDP&$zDfwHIV75s;= zv;!j7iz89bV5Yai@3Qe@MKD9y*BIcPxn|ztzt9+8s-=`=c=Mf*s>tfjUMmqg;4V4w zzIV!h(xMgf<670ny3G~>ZV?UVaRrlDfFi%E%$gdzA!poR(@?XHG^uzLvG_q@_l%d##FT| z8gx#DDvUWAn}fM3LB(JOf0Ov>Va~U+f_(6HJU+r9PbUZmnR-JK{h(0%=ft#Q0js2b zK-7i(UA98Ub!q$1LQTZtYD-2Q(@p`UXyGNDU4jkYKg~Y}5AfZbiB5etqg0sV6RKAR zR^?5{HxrRX!$!i@`1?^}*1phZ@DKg3DH{quhNYsB<(x48RcN(*`;(@DG6=iF<9Qdf8rP>&Iq-}fnh!F&uY6Ik`>lw+qc zpC}N*zlpIJn(NZASK(QeT5}t#Hf@7mo3agVr+z@VZnh3)ty`U^?R`GBs08G0`Stc? z)aSe$Z=UeqpL&+qpmvHv?`8Y!?vD=D+eRPCFFm81tqXIvU%*lD(l)=?U#)CK}eZM4UjKgRYX}6Wlo)UW9m(s#hHhbN9%QSC_4}utg;fuX>->PP$V$#A=es{q? zwLo9Te@FaE@!+D+}_WJS9nDYC}Z2AcrnZhz}BX1NYp(2;9 z;BmE&nPNH)=aV-*mm#*;!5gm+hyejgAy52odhC4h%n)}Uk(EkZ5V5xyM9Vxv;JskZ z7EQo8L)lh{HPnX(i>Ec+*lKj`pEF4=NU*RWe6#`*XV}hVnJ?G^Gp=?{7?o_yn?AHVo89b#)u~$EVW5*w zNK@Ro3$0l0&)J-uWtehyuwWALt_er_L(i-|WxD-qY%@)#)a+Oe<&LB;Dw0n==qd8P zAt6nphz7FjZ983&7RYs3K|O(9UmCeyOSHMLlZ@IcXXz~x1ZGj{=(ZD_K>(< zLPALoA)#3Lpo%s^3vbF$^_yA-rgqb0LIBB*_1%vNEdJ*wM841Jxubv_24r6-a&8cr{o zH~7&-z^`-;6*ekHtE7}BmX}KF_Rse)A0f!pv-P?!Yt-&U0ew8_zV_Vg_U1rQ8I6dB zBR~YM7b+lsin^;=8sub`rb=rwGj>$9fT)xH#F#mjC3LEwt9^)E@WH%KXtL04tVCOnO7?u;zi#Lx2#7E=R=xUsDQf(8|dOfjF{5#3JkRJ z5#ibS90*eUz}%^mxq+qKdi%;{joUj~ZCW@Y1uoBBcym4d9)H>0jgsn0>uHew=h|Z4!AIAm+si z#I0Z6@MK+SZ8)`xO4cXltMTI-hNM7ctXcFx@0KP-Ux5YUL5t&~ok z)*fKOGMo}CyqYRIY~S=R)Uj)Rqoqzaffs<|DEm|ig@&Ulj8Mm z$F8%zSIerNxW4wt2}wXzEOy-~i`ev~X5^Gr)D%pVE;X@0!_4$!Zz;2j@7;(`Fq!BO zU=6E`5f-%nhSTA)ymMQ>4^#F$&1)mBH>>8puyW@8O24uQ?l?}xtKQ|3g>bp`FPH#) z3&+5OQW`*2x5Y&LXQ zYvh@FvF8GX;z?$LN0R7{?HaM1pbR^(`^JwyG;rFD?c`fu-$8#Wx=HjOUYWzHOFpzY zYwnIOZ#jhfRaS=iOq4!qQ1RJkH&5M-ec(a^EJp$T)Kq=0^M)Lq_^)dR-lcQ*=7d;P z0&P4XUFA+bjGw5oALIm}Uyeh~l45BOnT~WnrDml0$w^M{Ta3o~_#$Nk&-tIbtHmSj za9Fu9S!c?R`Q^l~Z52DOCQnJ5P^g^~1jII{nMS)Zn(7dH=BAL%#!-dmJyrcRA%M8z zP59)75SD=rfH@EuGNqDo;62!0q_)=uYi#6$_}uguq9qjlu;)kKOf7Tfx1ZlmY6E<- zI5>olC_)jz*it9%y7AFZub?>3Ub5!>R@$hN@7jn>w7cDiYR$8uT#w-8D$f?Yc=0<( zZu832yG2n-8{~KqR3_qG6~MoX<`#8fsOXd0{&XUbI@R`#=PEq=#kRd?-r^6NS|Nj} zvNRmPC?Q`#=@6a9j|EO3csT_s=8E7R{X#SK+MF|D3;vQ4uep2{;81(_R1mY)as9=c zC{O3gD{EQaZYyz+u)~2Y{bT3;G;=KTWYyh6&C7tDXjY+_H64vuF+}XF;INdJ^SasW zs!li4j)*FLAnVKgxre?doh_!=#s{GyV(G%NLLph-@DUpdH_4~sA$fP{5$Q6Kj#ST3?O6rQLaw1jlrUk#y}l{a1tx~Bb9NWy z^{dD;-I3C23BTQmT6|q1!3)DO({}bucQgD|ZT7UH`qPzJSp{uEVitn`M4L$BX8(gJ za#9(vY-XJd4cIrhJV+>w(YqZN(kNARrR$TJOu}V^%P#DDF~ClYh+w~s0%MO|A)qu2 z1X8of=ro7s(8~Z+in#TMcy8^^nxwf>pJWY5y@FeA7a^0OZMoKU6}wmu`|-F-fr{h~ z7}?F((Mx;x^Cj}3pOSVHH}M~p8-wB%E#c1wbSCQp>dqh8y=;|m?S6K!yD-?7ri!yL zmk;7c-uGN&KPXh-D{?J^o^sCeFc|zGZv9z8BM;W@@Lfy=)YIrjk`B(w-UOg}i+wSwSzf!d&inj< zkRM1FA9L;+N$(B!5GKjSR>va)xXq~p%&sylf#Y5F)m}p$j%#-^$H&u72;eD4M0N^! zK;>K*L&0Yi)0ribaI7Ub*&d#W#bOhZ_$^m?th*wuv9Fo1ghxZJ2UM~`#cEAZlb+6g zfBwj+dJ_iuyXFcxk3cCF3^WU8F%K0M;3>gV&-l;5W1M+&IE$+o8DQ-4+gFzR|IUp> z$kH(Z*ca|E|EeMN!4*VNL3k2Lbvv`-73>BDY*q z%%#r!QJ#dDJh#K6Zd>C6HHMBnlICT|*Zq`4eS<7}_gH7fROP0tS*q@v>h861_Livf z6Qv3om5w=kMDKPloeEE($y(nwy}~72dj@wMX#YJBhR|5eG!LC>sJc*zVYD)v4?>Y@ zDs1qBwU75RATrwpz)j_}J21#7z6{E!SjGi95Wl&~AV0H(8UF9d!Yi5w#c6Z0UiNcN zJhtnEl7siR6sPX`es{GSs!XzgC0A7Qf!dj_(=nT zDR_%K%G*MOM%!pB4q6@hv4ZNwo|MsIrav{71fZve+GbgLt(k*Qv)mp`Kl&)b`NJ*j zWBoC|wTSWxi$)owX~d@b+};K+`jfDb`gI|Bdp%;eeQwH+XfuoZ2^n^pRx)L^C+EJusIO(&b3;%-QP z_loj=fm05-%vtX3Mh4Q((|z|EGyyX%NZ-2YWpA}bY->0d}NGjX^xMmN1qzVDn9JBFLN#rDmUji5U| z)T=k!`qPR;pwCE`hFiQuU=|TH_o2(IB{t$9+Vci-aX;P8*z=7})#EY^s@_y*Y^+IW zGvpf$(|cwf;oAMT3nx#!Y} z@bcx#8Hv^a%~(!VUSomWxYCpn)tKWA{b_=~b)V)rKtgO@lxun+B70fRxXq=k z#&KK^WBlQ`{NkWDBHSW%y~H5zt&~Y9{pMGR6lOKub?PmNJ3wAPX~b4zjXJx?1N{ol z$bf65eWnGKcAm|zoRZ4|93$+!am18jVgobFnEmg^BOf0XB?soB`FYe)zj5i7rRYc)AP$ z>sX6l7!u*j0mb`&g&@t89wYZ-1U3V7bCo`23%K>B-?cM-7RV(eRpj_4q93OeIg9f6 zw{)8|q#Y=d>wrOLT%2Q!A&H%42sYMu@E0zmk#ev>8Lp>6;SHuSmU>GzGc*{RMwFABuz zw(|@;aEGx$xZ$uhvS_oaS`fnI8RzcFQ{|)iUbly-j@3N7Rp(( z{jdGzzgq8Nl{8&nKXOqiz4U#qn)#TK&1rHGsQ2)cwkHPXYuDa)55`y)N&Mf|>cuml z(^QF;xbimc<$+AumU%$DFdwRAr(4|9DeiPX8jUJy@6P0-h=6TPH}GNfc_1fwx#LUN z8BrbpjIDmhjrxfZqkB+VQQ6`{sG?LW?AfF0(LM*(ESjWDdJ~;UXlgooaR)*4 zvGPhbPSvVhW%*MUeO453^BGMvV#R|&8SlQf)HgXY73h3IE+YL&CKyw>qZAZJ6II#Tw!Bk4w~`^O|&S zor}2|orvsgg`WCcCUoFha?`xX+9b}m}Ukn z7sy4d?v4cszth2lX+FhSw6!@M-Cw;%oJ9^lP~6(o``PKLS+>>EiW!#WHhf{}D>{5) z((7@Q)a!SU8cD=2B-a~=YD)n{yZ*$7*=z8!Eyhuz>5-qww}XgoF!v09`3^z?RW?$} z)XQ<`_&k=kNfpJ9LUb|va|4^mL_lappQYW_e^L5uQy8vip~MwCeCro%*=vW6 zPr*z%r81mdDOGagf=d72IGuJ@!uz>=c?ODGlgVPllu1^Xc3L5TTgVG_z%MmPtCnZ5Z$ zx&PAw=&p({dHj~++hb!}!ept7s&QcuYhO-CU$TTLFeX!Pq1gS#+*&;|SXIh2hR6_% z`la<4WVhlAig;VQK)l|E81g{5v zDev-#^D~EG{D98l&*u1``T!(nfcmR6c^#TURc5CT7NZ&v>^|;o*RF{BKn<62wp};z zqYs;kw)hZ<{+iUnM#4HyM)?u`*|$72=jtIawkuYXorgtRD1*{H2I5`N=ITe$Z^}jZ zY?l|g1v{I(XiZjSSBM57Fk&+5?e%h)(wiFc*p^O3mbB-H;$b1%OgBwBWj z4Wn2oCvIB<)qjN}08LDltj7>CGLMZ|9VJnu5D6sr;LJH}41XHjyPzj9m^$}iNP4HI zsM}&}LfAMR!hX4Jgfoxan@~)bQq~0Rt_djN$|dtm5~$f-7rPBQ&{Ut}{2BSb1kgFc zE%*wFNQOWM|DTnIVs2IE>1PKgKrgS&Gm1*k@9y-}VXN=UsC<}MVRFlw^CmnUR(r zF|0wMCJEBsc)9H>J;fEeIo-VJ#3cO&h!yxzhZ|+xU_%ln5qW-nZ?cw>T-bQSeD)P5 zOUTvOwrmy@0@&IL4V&RU?OG9ym&FYnQQ2O1N-nvC+CgI@FR^us*J1alz$}VD`;bHq z?U>6SCH8@jt(r0XX^Ze@IfVjNvnGFa6@6YuB;E9-uD%ba;X5^FNpUJu-5iOxYjB?S zBwgF1xbm4cZ-*Lb{ruzXCw!@6#-SF70xEm@oDe|2v2R)zDOU}?Q?_|J!&KObkDDd7 zE_p8O*yapFvDmCo(Y!n$_!tFs^AVo*CL1?-ZSsj^UlfPt+4)>$k1WBOY1b zwxgYitnj(Z#~JeE8ME#CDe)Ky``JC*S=s^TvBntv?k>PlKvf*s=1KWvK#*790}@3$ z$hwvHbz5uwsJnkpA<%E^Al(2%nyfJFP~eU$5pCe)9xvW`EH00ayJwhoHAACAvXG5h5YBvf%wBJdm| zcmE1dNN9j=p({g2>?zw%u$llC8B1@7yXXy=Ki~o zA4^PQ+2N-Dp+gILG+qAJA zZTv}Kz{MA zH`W+tN;WvT3t9b`j+M|?-aHl*-FADZ@Xeo7RCoEhm{001lb8n7YYu}_j?yTbE~mc# z*Y4wt3V4!QV)0}s+yA&`mgMN%1K8TOJh{U=toDmza{k2m95mstP+DYR%KEtW!e4BV zn!UXI`N;O~8bmiw(-rS$U zPW#ii%&Q8M95_toeRMdzWF)(?{zF19e@xCv_VEa+@RbgB4YPHTo$CyDf2*R-4;_cjHpg&h`QHXW@5t=wtH$|JbSzX-#P%G5+RA^B zS`$cUFUAk@>wsX1>nk!x7c`ObEtf3R$U_@Q6>!c-{y$#hAzd_F_S; zOPCLhCPU9clGOs43v{#MrR4v<*Tv_+eCSF5NWdD6*^jjQ;}nyY#``f5&*OH|QI;zU zSE7_a~SX{l05e`@jPy4yiFTSe3b=?Qa46bcA!uud`9#0-_e=t1iiM?%p zvgVEKU&+S-vbe9=Z(o!_n(LrTNdZ*V*&;9mj6Iu^|H6P`jq1<4Vt}C2_63&E|I-jW zw<3Rd&R~|%b+bG&#M)Fxjc5^9ETad8Uspo1*u(Y`jDK+Sa>eAxRdd?{{oFsl;=5zH*=f*E5@5A{jGOEBd)5KC?+452BY0c`dnix%2 zrO$Gr96sT13?RJZS6>2*0gmj&K(A>EYG&2L7cQ^s?wS5wYjp;C)E!hBH0r=8;tcJJ z{hzPChFz0>glhlv=dr)z0#AG(fnLm>1pM?cDnwFox zW~!HyD^VYy!Za(*1K6sqqm4>2IZCDVw`(dEX#_QNLg>UR<)TuQvgIO<#%fFdMvq6_ zKbNsQWR?QSXKz1I0_LZiDb;+3`+q~DzPkclS}aBVK9&6L((xH;rBx8BvAfda!p;uq* zEGGzO_o!~JH(b5@3t+pMy@-{lr67!~_pd|k==+sV3Zg;aM1P8#a2Yw-z!wCL*h4uW zi4(FaI6v|0oMAC%a1^n?Q0GCw9pwz}26m0)ha~h=Yf-LJ;@7QXo`f5T`s=k5e5y&e z^6oomp`24pL?3_6eTbO4U&7fFcdOR4)qV7|==1$IGgUw2x4{%5Z!^)n)yF)4(Acq# zR|Uy6oTJOr1hHSrO*yx?Tqf>`a0t*c-d-B8sXNbn$**|<-{8KK+Gkm1LUZdK=h+1Z z%d3V08=^N=4V^!lCbD|#*nvfv838yAvmYxOKUrgyB2iyy*(S_ZKv}=i z4UBH}N}rKd)`1sC)nl1?X-g;6>7yMuaN}(7>^~YboUDRyKrIN;mSpQCDuxY`ABS?R zoD^Y0@W5-}W()Iy>Pq~1(c}IkW)ZviWV z(H*7H-ccvRbwnLzI(BZEI0zp7WD#uqA>!)cL6ccS@loyep5Ct(6&)7K4|V5igg_}0 zBeZTX2?pc$Q|=efeFgs^gj#CWl~{`UXn-8Vwh+AF6~3-N7F`-#b{dbW?|mHn#uA`$ zoOmo7oYg-O@yx6C=~Hbz@phM&4m;eSn;v_s33X$}28F&bk3kzKcXC^_9+zQ{MNHvO z#G&-^BwrXkN2vQVR1bKw15|U0E8rP6Es^(b%|u;MeB#f$6@?F*W}S_THL`wPS0{hrk+A= z733-le&E+pJJrISQB{%-C!2`)nnT_c@`w*W8s9ASEf!^ou>3UakN1~JB;f^&CBI$QqY8-ww%v2fgB=sg`;3xRLD4t~A z{BTC3(LYt#i5vK1*Z4{@OZgdXFIAHSOFTaw7Okv}6yT34pL7VIfevT5BdWIFNO&-u zQQSbxef6;gqz|YSL1(AIzby`CSt93RI{igVEu9$Tdg8_5-fkra(kpy%kET$;o9ch2 z3B_QCI&?v|hm6F0Dv)^)S~k`&5u3VT$5hRP3S z7LHzRU>&=sw_~0Bt@h^^_{In4v+xKc-Cp1!UusP(*kV3~cYE|(ACSzho>v1B3rC4d zJW0K^jA_`Hj$?h3PdB&KUomByMrmw!(GW<>!vIKG8?k;l1H*03@p#aW)tKfRoW?dO z!%b-aA9HUWPj%Pzk6%e46_S*MNQMkWLdGOQNXn3@Lgpc}42MdIj2V)t%reijqs(*W z@i;POp6BD7-~OCK)OFp@_x?W5{k*=vf4mMp=d<@-d+oK}YuIazj<9TTa&6lGJiQSU zv>j~H@R9rG=Fv%mwGU7%8|01mvMXMCxrxwO(VAj($PKeus|2J>jZEL%xNc_$hjJbl z$JyyX*f;pwAa&IDmED?p zzEY>`7>NiRZ=N$Sy9}e_)D&zV&_|1FmO9dZxl=NVTA2#&rTx<0S35oCub!=UbvNJj zn;f0LxW`G=vpnoyRw*=qzWnSa^TdGROJ$IL%aAnC_CU+ypJ0%nH_-@7H#*D%U7h>^ z^_QUbEng?4K6Sh@wC_+&1Th97Z_pAnAkPZ7j+d}k^H2W^)>pTMX zfE#ze{^cnC;)oG5eE!2n*miV->T(|9CRsL}{%4M(wnrY4>YN~A{do)OG37ycBm5KX z({I%!j_p51;J_$2)2bVgZO|$m)S#O4Ch>?gWKur8qp734cDUI!5V~&;f<^k6h_k95 zlegn1V|Vrt>%w?WLG^#QBWvFvDkcEX1Vo-aQgzY*t7_?%r89dCth+KfHV z;vfHA>$}2S+hO4Ls}jZZ-NN#PXa&%33nB#X+)pe}GO+(b5<3#k0Z13!u@9y9itk3G zi!e)K|8IWARnjL?-|U+so$Z`ZK%ed0#Eo3;an8Dy_j)=_F^^ANdU~|Tqy$9JFSyfo znX2Aa{&KCti@a~v6uMo;b2d+EmF*0pQJj_k#Ro^E0xm~fxI?Pt&m?PXOREH0i5n63 z7vxKE&_*QkW|}XRNnRtCqA3}I5|E0^3&k2{M3$rIikvszZpKG&! zb-#m1J8(W-4`~XVV0TnAo)q zmlH&neki96V*m;u26b_I?OmqY&r_fTDBts;>~^CbS&)JqPs^gza60qZ#8H+2PUUp( z{+%R^3=q8Ljm_a;Ef;XcG|@9 zM*tKOYP&&N8Jj9YwcE<%k4@%azU(-CbmQ6l=@Q)#?zq6=zTiW>b%9g4HPv45&U(d* z^7K=b^1&dGNKhzr2#Ea(NZAT(QJfYDfOIy+mOk z!f4oq5rr=0dXBLL0`IECeMLSFXk%Sog5^-->)3*^%IfitpW|nabVP#-04w*nVw#yR zq17*erq2sphalesVLoVm0)lLSqShSJ4_<)mC*yS7PRQAK2=Ro$` zv-DhDP*rqZ5Ue!9R&D}n7c1$W2LeWLJOvQ1tug$ScSWgvIysI zi=F#KYyDQK5$;ceTopTnedq-wV#>+I-+sE}iz`a8H<4FKWgL+VnQB}26t_;Td|TI6D%8x+$Su42x=(Gd^SNOKPx!4w|^A@f);ScNUcFr#x@J!FXd0RBZdN=iqWA>grUtvd9<+BF5T%7X0zt@%U~S2rOO$tg?8@u}y8? z9*fZfO?lxVP8>fXvzwoH4fvuW4tW!I0Enswu9F#|B*Ze^z>Zw_GJJR6QXndjK`p_* z{p1I2+Hgd{9^B%^>^6gagS~)^aFsj8*aU({l8<&$ef%%q5bMc(oL1p+roKrj85?gP zlz~Po1fwl-MMF)u_H(8(lzhXg_X2l5p#cZZ1FS31#9gurjrV=yo8lly;Lfzg(AdN8 z<;)ARRbxlE49ZV0RD;s0g{&WTEzF&7&8vXHX&ekEpoVXxpYbR;wcaDPeB6ue8EA_! z5f$&qgv9#Ffp4J98uEQK6?|g+gC6^S<%7fw99(bI)413Ehd>yt16!iLG5sAX>sKap zXeVpgAEblUc1-ayLb4S$Ob@)RDGoLuHt*u12&5=q;CpQHU>XIV(^!DjEIQ}tPac&c zBbP>Uj$2Xx;=5lIGpB%PsRs^wlDa>Rz@O<_eB_+>h-eo44j z8k4;46qV5cLhp8YKp@NsW0s-&PUf#g>(f5gY|3JOK9CLN1BGeRhTa(_VvqG7Qz$zC zkpWyCqR#i|-t9Q?J7eJ&Kcu@6=fAidl4kn-mcw0h{kbO1nH%HaxfM<$f+-eRShS@3o}yLnU#Zfd8n$w7)7m0Ub;LsnlGVBTHHkVuZp|z>wLvX3_A#bZsjy1wmD%=B>MMPxNI7OE^t%xQ?sgOYMJt$}B!gBaz5#Cxx9H$d*NpTUWXn;n;mMuA6)-r!zrx>~N` zwo*^YoG&61&))KO$|S{15X<{oZpv<8OD=qUGbQ;dl9LR*RSt{Xz<>`J4Z&IT_{7Vl z#lb4)ZDD5BfuO4GyUh_oUiN(sh@-%nbAHq)>xo zaeE5)W{~?LU3W5Zde+m2P*`0A<@grFX&*R;^Q%J0W-TXes`ob2o8z?KF-3k{x1@VY zA4eiEuhXHmRBgbOEXApK zE{Jbj%MKNDxGzeCPCujOGZ#H_lKD|u%@1qP7M?;v{MiRT0JMG+YGD`B>&M+S6&J+p z!$4j@HSOz~7`hjyn$vn=eDXY>us)JJ7aci+BB~K>p2iI(uy-j^-g0fOexCwj|>sWb#7fOH2WAfIla8) zIbNS9BmmFxdFTgK#sRs-VE4HcXWLzaw)xFMPO{#uFy$AfUpL>LUt)}UVNUD3S&G2O zUAW_WSBVorSNpyPcK#J2Tm@StZSV?o2FLEVLUrQlzTqFIUi9l-5oz~FvI3#l~` z8W9sf(7RZ+j9Pr-xt(^r4RRGYKOPn+sp?Pqh?7?K#Jg_(v2Xpdbhi9((F%amDpen! zq-eTJ;zw`|@-y7{{^FC{=G?&>oG(t{AG$^O&`$pQi>=5{b1=dvQt|T%3}ScReDW@o zTz&nitH)9=My~uLaKuYUgtJ7{ka=7cUc)%wPaxA*QejE2gP>L?*MgS;&R^vkU zp3$-@d(nho%S;*6KJyMMGFKg{ddvRoNwq&8Ix^!))%=C)n|mmoRLoU?lDBrWoO`9@ z2rr3aKryLOk{QiM-XOOTzTB0*vt*1HRx;T4ODh%N&&XJPghc^#Baq%Pt)hWsaux)@ zWkBLtC*v(4?4B}9O9<`xLFYRRQ zeb2jo0yDyoy?JIo4fb>&^l29K<*dXMgGAeA;tv1?{*Erx2Q_X4I1%{Ng4FF=5I$J0 zv(#y19)5#io(p6>vG_6rYW?BjqD;8FWf1jl%Q|A9E0hVn;vw871yarGG7)3Kwt^c_twf{8fX!7@9@EUr}(!yVVRKhIGEVC10gr*2IIh|{^g1m<9%E8O^ObP-A%u-M)eD?6uuFK zmqY8JxnTZt{y^e`wATaCvBb(!Ajw21!PW{gvdvAPLp2T}+eTUm*}q!f;5dZN7(W$} z&mP~b;mcJ??ACZ70Sn^GF5!=%GsNPWHx%clL}2Ji3a7aD05(H*|5wW=kjrG3t%@H2 zQ!FpSeiLe;#0NTtdRStcGm{c}K|99tg86fSV>hr8OAv&PsBJ~!97cQ0<8Uf z%M-}ZFDrls6e5b^Tl*HZTRnc4B3%^vAkaUMAEwHEJMy#kC{WE@*diyXiBs1;2JMZU z53UBE%o8-Zx|59ot=<*tUUb5=of<01I1hO?Y3v_DEjaQadj~^)i?mWURpsMuvC$n4 z8cY|RwTPUs4qy#ab5={gA1RV$8yh1V-uj~u+g)#WYFXeNS%;VQ^WCFM;1nvo(!~z$ z3pEFOd#VqTN7!VFIVsZ00?JdkzAt-Qk)P_q=}cQ$-V0_^he>_DeJAS&JqU#}dIkrX^;)-xl#hO*#(K%hw1HJB#4fby9KWUqu21-1 zxp~oN;_Nvnk4Ieta1`bYxQ0C$%sR98e%v5IU>+wJzSKZ*EQ!&~#jfd$rY{lC_qY?+ zsq19J-rWEEgasogc}BoI1#uIE`(_KsR3?DWb|ZlAN>t5CXx@nD^BkSK&E9j}o=+fh zfySMbeC8uD#=W^}$WPiy60T;qiGV2`4yc?aFlzNHL28%$xGw?rA%>K0q|OUwP4k?# zTf2YWIUX8-^$d_GZUbZ#4J&S|_}IQ@JCTH}jZ2qAj4L})r}|*MgWxT8O$9Mb`}gyA zJ*EN;Bm-2x`cAX5z17xWqr8JRgH_%v$~r@vQ}_BYK4z2Gb5 zd?6jUD_iA`2dg85?xbA;$q90}Zoj|ja6+%L^$Fr-ga<_( zLuC#p4ou-wLue|2Zi`{C0GM3Tsm*x>){?N9r8fg;RIH`+Yifi3Le8s@W8zOj?odn; zAD9H3TOH40So6AhL8bOQKKZLyYhmYsec$ZA4fyG7INL`LQ9gi)i1f^l{|o&Ds0w-; zLKdsnwH`|$^Ff!B%y-K){mQ2zgq>L5xer}tpx7hl{!cERP_y$E@|#(t<_CbW8f$Jz z8=rd{S9!M5!muQ$&UlJ;3t?R1PNu*nws(W?&yBQ8a^ZJhT$!(u(@o!AvyWFweQ@gI zCIdhXs|LU2$L*ucybajE0p~;CVSqh>EXhCin;(r1a*y_87==2vl_puW?j{2gzAgJ) zP7tG1Lbb^uLz(IisyM&VvCYN$@UZ@G5gG<4pC|)cfc$S9L1>pF3Xi;4m#;NGahO*g zHPvy-3T#+1(CaD=>AQEEu*>Vj3!;+-wwvxi!>vv?Hk>$|KMp26_g55jWC(A9&**%h z1Ls+z4fkyww8&uc?wmQ_<936@0;JC+a4;D z_dq=cy1@h6uYKg-y;y>Ubj6^}MV){PHcs{JE?_(njvE1&i|Z2hNqmT{%VP1X zzaN7?6Fd2JLJ{3 zdjlSr<7-|9ysr+ryL({l&$|zOq-0LPI*j&Ck9nzRmba7c_EQaJ*1+8=fE!m2gI)cs*=72pHa_g`;QTCj_bdN)hZoAi@r_?H zlQho-oNkFOQl!-1J2)<(P;&o!@>|^d@(*`5#}$)h%Q>$QXgh>~_rG)}O{KSWfBVYl zN&ZXH7`vM(v8+is`ZDM4#)UWkhbwY#Bz+g)T+rof*ZNyh-@APmqP_DcVG!TP{N7`Bo<3uyv0-hz!W&x@hMdJ0k zownO|{V;H~k=~{PZ@eI@{GD`{#DAB`)Z~xO*C_|Ei9a*GLx!tG{Y%)>)gEdW3*b3> zt^Vd3f`i0q-1~wV`wq~4`4_Q5|96>eGS>>ibW+AEvtj?j0}ZV%9FI+WLps=v`TCnP z8GjJoUuqB@0n>mQkdSPiib@cOn#b)2ohF!l#ig1lviVdnSaDyT&R*=4|)L;Jte<=z7qH)gFBL1Kk_ zE3gBL{~~s5cSyzkL>gV1WLXiIz=A2#|6f|YqLW9`Nk@}P_0CIAqUA+*YQ^nI7~Ch) zNU+qQrQr@jJ5?|N%~=hLeYlIx*|oz+scteS>7A&E^G{eMtuG<=yt6Qx&wszM0ZPDM zvnZYNHk0z16;fn{`9nJ71PfSo+A<(b&EuMaKd8U6{<20e{b!bQEjIYeV4AnmI9v8T zXkJv-hFMYDAVI<>6*6?;eQlq&vBNg9rGrdE(}Ll{!^v}{3w}pwuSbQbl}&)Ry0%k5 zjOElU7SO&O>C&+8b>N@(Pj=f5elkw$W=K)X^M9*tanH{s4EqT6N#7PQ!s6&8FTx#sG zbl)Ev9Cm7bhMTjl*?BwLs&M*VBCE!%mEF*uT|oB;aI>51?ikq7{P301R9RrQbG%+R z^BJTsuuNiK+JLX({v=Ke+VJm!5c}1IxG^_!5AqT3n+pX%17y_pFDzC77%%|f(q9)k&h5vWHmKoL7%3-EfW0uH9fV0rY|<(&b4h*FSJ z+idRW7Fr_&iQ&y9GhpLPR&+vR5OmJyV!U41J zHL@oE3b}fl4HY(<$=A+x(c|3WQZ>3(zXpz)8Pt#)1qT1 zyZ__!(sPg3p3{89|BcrV;QK2NzVU$r(~DBZ+B#=>rsGy;>5}J&3EO^?t)#5fpYk1b zaW-k?O1RkXgx-~3Sk|v#xm#=zN_L*{RFwL>P(!hYhldWRP5AV|v*7US*3x)$?k8+T z@qV3>o%2Hari^nu!hdv%JZf2i<;~*g zuTEd5E6l!%os2JXwcDA^?(s4uze}u;JAIw0XIrf{+IDIqS|~5%yC%ehuIuT1iCN<=f9P23zU8-1qDP2<{2D%|(4KFYYBpl={Ai!*0=dyy zE2Q6HOpVYBcn--hvR9(x=W5G2tw{|H+kJ2;1A{~;!&1|^r@+j*6XBd!t&A?l zFdtfaGmCzpSBdP`3>-2uX`>d_oX0fTmNKN3Zhkpn@Jw;CriRSWdh4fm+P&fJ>cW=` zdASNa*zx%n#(eIdbssx27F$gAp=ezOyOPC6s4WL>)ESKV`?3=V;lkl0_0t$vA*y08Si0oT z2<$9`-(kLMn)Ft~Yrh%GU}?!z1y^mp7QpicUier1sn73Fll7^uZdW6%RfVO1ji7t+PCqf%DE9{C(L8>XEmD~!jIgJf7FTRC)f!7TG~ zUn`cVZx_ruvySPmtMw&NVP8Xi8Ur#QUEu|u@OCNMQ&H;=qG2|z$mwLTRLe!Q_C@5~ z*YF&#FB!w-VgWUAaXB`hWDnkA9`P!pB7hm4eGrWu=-{vx%LkEpUfYFWEMZ5#u7g5m z>)hxc7hM^#EKqP6ebC{m-C4{dpYKB0ksVKCK9}@nBdO6(DF;73Bt-_zt`-TEw(6qP ze6Aq2J>fYeU%rZD04@XAV&qE276=tlR>AAM-IzO_8rJi2AEW+h75A~UAgO}GdCMag zNO+0ZTCgj3TcGWZ{@S-r;P7e|$4=$zBr_dxPN-0}hFlztpP)iljBlPncV7DW`W|qAlmEusk5eQEeK~6`{5?#%5|pB>M3+i z4#+Vdk33srZ*Olg5gROVm?W_SqPz5)HOy-{o-Jx>jPC*3%p@$k93K{mQ9Nj~KvH(O zCmS%_J6+FA(SXpKrr|haMosq-4@a^wa(#- zLknwr+@_LH1Y0nRxrQi12E=B3_a-4$pxTH+rXM`#wEUW3TWFnNUr_(Ln^(YM8USFwCZUw>yiv#CnpV;#7%;50=98IZ`SeO6xcZ3^=+MGx@FJ= z^-@S|4NKX@$EY`}hHb)V*;7x|aO$Mz90u*i>;sA^2(ET(KNU>HY%_;!%YMCi1jnVp zhy_|Plfo$*TEt8>(yIIFspkkFVv8|XkK4RImgWO{AE3>OJ*3h>k?>9p@Bdv17lxJ> zS_yER|4QH=9?sq@xO7L6VW_(mt68((!KMzxfnCkZRptR_i2#OTAQn&U5OVIP(VAFT z>Uw^3Vpa>4GV|aV`t8bBz%+P%M%F&GKq)^*p>k+$7H(0(j2s@kggtSZuSQA(>q?0$ zBXDV{tJial_74GFJliaGvI@RYW5&F)x$YC-aMc<|&_%Qvq7ADQ1cced-x?b}G$QD| zdiRys0Acd8`TvL>Z=8V5m8{iya+WfaU%cZ>aY^Ya54|@#R;b;oU(cg?^xH~AGDSxo zB8IDH76NHRU@6tUv*=1>uV%+!qzWx+!H12sKxu9LnS*0&b+gvgm6+cMm;#wFjO1$k z;EN@8n2g_HNcj|+P5dz`)CcwYUYZZ)c7dcKPFpen{VU}4zsm~h=y>_aAX?NQK@>*= zxD2i;yuI8OCsC0RTeNNJlcs+L(|PcYEe7DLG{brMWD@kc(V~p%xd5Mzo3#5 zfY%xRZ&Sj+7d4A9D!+rDAJ#yFUPd=cI^Rs}s)oh%MbRrjxEX3 zO=@+axH}<3oULedoLt40JcDib>n zMu>sAr6g%17@%!gXufQeb;{bjxL9xHZP$&cwCww|WI z3R0xBqU_92)Qly`qF;4Np%^)1S%;;q>tE}Ll;`;F1yP%6@KoOm9B#532vllG^Lmg=;%+9_3~ zfU^#-19JcMpV1rte>Y_(@zjC)Buv<;mv6zxc{w`na76)5wc7#J{&Jsc_kj$L6ZS_J z(En+>2;<#k*AA0E`t9xH28n^>de0oAy#PE>eQ-R zUz2$y;s8wBWB^76^3W%$;9B&kkcIzE=h44!i^TS>13l1lyY%*%gIBnGvFF<+aaDq} zK=P&0f6$%vuV&ODga&+c-SEYl^;S|=1}S~Fpg9Rf)N9a$vlx@`?lk7>HdTK0I!Qa> zz*E$J*ZJ}98@>M}^ZlbPquF9KQ2F%<$^I^^_k_a_P4+B0p&k4pjP?^a1N;SpbH(6fKq8-u zR92OW7_010Jf?5$4u5=h{f!?!1(sD9fqQGR_0u`jOTKS5SZsFU3F?itk@f+!*U7lE zIJj~JEnC#dT=8$}AuMlm6jp=b@g(o8=bFN-B~FRGD%z5n#~#ri+mgDK>m+k(Frr~3 zxIzHjWd9BKn=04VIIss=V`X$F+Y=XSnIb=2{EW4ZzMsa#-K=JA-?M;*tufY9owYw( zqL1n10N07KoUsZnRqg!X)&H)A7lwvy)N6tKB_aR!?-}w2 zo*VuD+1O{lX4-Fe-a=)q(-djjTjCWz`dirHFT6(9c^C#hSF@VQ&Sg^7xHu>x+@Cx? zrqjsa+ai!+FIS;DbYk$ioVsK2uiP~AJ1!ep+5s$NKSz4BEv6g32Gj&zzy*)=kGmE$ z!_TJ)V&aZA*9O5hnk7Sr1Hu??9eS8!%n+=_#e6Gk&AE3=F5tO{6xUJm^(SftsCC!K zGozS=U?xTePfT^WFEbRG`FP{gTC8fLc~C{fw=7#wuXp8Bah8?j6Kj5f-(x5)M)(o1 zNdb$ILDMr=W+e({S0nS|5Ld5Wcg?m*8Eu)94^m2bD6t0mOJpv2(J8z#5fry|w2so* zk_h7oU9AuG%)LgHzL(u&-5JF?P*$D!2Jh?SzZy z2~VQrKeH`v3)tDwZlKAL?&cRB5LPgKk2iYV5HVlA{z9er;|BcDyR>}%F$`_8-OXI; z?S?|Kb~~j?@j1h!}f|sE1unqfLP${e)Kkis4W5L0+XUQFf<0Lji4i@L7pG`R1+utb9(;M@F zOJ^Qlu}UT<+RMtqhRFtnT!SMpFHuX{7|F@0snLin^bHz^#kBz$E;sJybHh)1lvUY< z3axx22Lzg~5D8E|dBR^XyZ(i}cKOC&t_Q;+O6}}1`qc3Xu6umDTSscHB-({i&EX0e zi_G{k5fM4%oz@07-+H22x+3(_sxG~6G*hOqs;+)vht#C>^KX!--~?Fpozo1kP>k4Z z_98+)hII37;(M4;gMu%%sSOR`!*{;BFgIWhUKYD%-HfRxG4b1QYo^jW$HT0(X;Xj1 z;6Rb)DP|T{KQm3+H-1CKFL-r+x_{P`!{&0h#*nMz%n0$TXUP|8_A1WSV+yoq+Js=~ z}h=VDpga>?7lpI}LKESnEH>DjrYPS=Zzf7i*W#N^qTF{xW@l~Fdi~j{Z{tzWI zqDZN36=sTG2k(@1neZ=45zYo)2ZU|fMQhLWHv2U({E?LFVhg1NG0|)@@jI+0_pg=E)-u31Q*7VM zwlruuz*6qhroDgXtTEz%YDm9r_Ydtn0KHSq$CJS)L1G z$@8&&`naHJ7AY4; zgSG0KX|{O_wg%uNU-YWC@j|87YCWv`yu@ifhBIxa{XA)V&xWI-!r~qXBCGk2z7&NH z4;No2JD$AAij4gN9Mh&h`#Q7S)Zp3-E|y+K`uz$_$rU0-q4nPGL5b5W`??-@a5U1pJ5^iRXuO#65W`Y zCMQRgVGm8M+S8KNJH){|t1V>^x8Cu*TO;()0v3&SZurxke$*U~2 z-NVVqTNK<-DlA}n2rEt!vEpR@23?oslQR_5Qx{z$1=mgN!EL+KvI7eCowBm=DY&J% zdv9btk$t@pkC??NjyIUpFZb-VSGW&P)VM0fYON(rFD_o+*;&BX_(aqK_P2w~BFw@x z5M;LyXDSm3AS!4qVG6mKMnYb^@ggUg=D+iLB~k|n)Lj~cmTeG^$2{8hv{+Ry(OEmg z&O7FKY1VS$qsaQ%r%a{sr=r+2HO?QpRDaAzKyOUydHiwbvk`le9`~B`lOUCh(JP+y z2yamR>qdunVa}^%;!2NI={-PYwlAe<*Gs3b)v&cyi5=9sK@} z(FQ?AS9Ng;V;*LUSh{EP>2_8yBTP8*T#haJg*M^>&|ADKr%bS!%$Lc{pQDqT{EjZkXQ@ZC zv_XgfX@FtK30&-om8Y^&Es>OYI+qmvcm$V(giQjua55ozfW-*DUZdaB&~H}%;CSQA z2aK9+Zt4am^3=ANT$nINN#Rld;&*2{kA2#`gqBU*9-bKJ<2gn(e&+oZjnp$1mg?i} zJg|A*IyuK?HqiIZ0A5_6pY-_3QZHHSxP{WvCc)w6y<@fW={sGz&geCkBtB+?nTPe! z$Vj%7hdJ4@+T&t(*qGX&wYJdWTL>`)k$ufD1!UfS1*EH&09G=v%9Mn=;R@$=YV~+vvKSzFaZP2((U60 z0p3A}EzkL}GaObYXJ^=5tmsiZBc;?U-Zb2g?;K4Vx{E(eG%c8|dTmDCw0K<(DHc## zdWdB~80<6gftXDl^P(MQ|1fnj{1Uh2c*Qy24LHx|wk6EsO*I|oA6ZpIlE>-Dc8!7GR$uh$<`;XP8!Jx5`0GOP724$g(q=8Y2##YxM{_+cMKk{-PcgH`o~ zH()~XBh^qciTu|0Ipk^SqSJ~?6JN0J5CqsnZp_{aCzubrww4&h8e_(*F3m=+y2sf5 zq$y7-C(%XInhtS3+g$U^>qM#AP_y~1&Rnls_OsoRFSqmnxvPw~1R}CQeG7wMSZ5XC zZyTwzN~N2WBG*hScJ?t-=@ezublR7|crC+xiqUR`gN%Cm@Vk_&f6Dg!gtCMN(|c-` z>gYL6^sUmZK}_M#1?oXl*RBDrOC8ly7oxQ&HwJhujTv!Lp%sz}3OK3YSC+9WQbdOi zg?$i7VmrZuu@b{!op==QoCX7}=?5cU@5W+<=T>7`s!UasS8z&&5G2n^ClGEmo;NQ< z$FTLT`#<|q{B?tiXKU(Nco1NQ$oET_o26zdn7+*Tckho)2qWY{2A}?y|IDllNHJ!kIfMWvz9R3?J zM|W7^G8v(|`(oY(XUzv9?K|F4ga^hCd9Vi6&3-XyjeDSGKVQi7POnJsG1`oMd;|qk zSeUw(ZRD11+;ZG2)&seP6T5df#UPUr@0)4X9^#S5A)Z;tatu@4 zhj@+qskdlrGa7Ys}UYPuv4!zbCF?ZCD&aj=$)%qMw5MITQPSo~Z!m0Cj_nnN4-bPIC= z)OS6843kuMs_uvuEU~)%hplw=>O?0~>_uHbI)5$=*(i`t&gGioa71^@^_WBw++ilV zb;6(Hitb=L>g!~T%}~+v^L4|`P8WHYnrc2dBXp}qy5R-wNBk{z_;M%T)wTTuAc1Mo z<0!x7G|UQoB$Xd2!|rmjF?V&uAY{wtv!4_CC)%QXqZeWy`~BoafsJbQ@k>xhSdd z%7wk1}smKM+h_Hdb)|Ji2#@+8;oMXskRk-i@TP9$_I zoQJPZXiGHtU{;k|VRtbBb&)z?qg{0<5(E@4(NZ?@eB`~TU8v4IGWG#9$KD~2&H1{I zvRk8#x73b#hO|lCj?_#Z%b_|QurHq+@;Qi~f{t%9+(~J+cuT-fOEg6fKPb8XqAmpi zV~U26{qoj(Q2ZoFVf-l|PWx9U0uZq4ZSCKIRQuV3sDc}&)N^$W)h2ZVi=~EFcCnOi zQ%wlNOmDWWf3V8lF_pTQo;-3aF;RftsqksdG?7Sl$MrExr?FfEhIdAjk=Rp{M~;gF zlzW_OuikvszLQBTdXLbUS&QC*B=}5M=MIu$owVV<0&}@BMMz^ho}yZKfh&Ygrzc%Nl? z{^I0d=|SsiWfOy0oFXM0RLLVY?oq$sb}8tL0c2qp2%YQ2l^Az9Puh%9J)}Ro5&s?$ z=irg4*-j6*Fd5(!1s$1!zO{C`!gloU zaEhVe?w>b0Ma2(TO9s#in!kD0fbuy4`k^{Ezat#Ws9O`}2yzPSXpNR3*qA68j%sQG zkRsvb)^W&;h~>vYtdiyoP15z+m&hR7F^rF2op)W9=IyuCI8ksJf4V8M!!y(pJz-^w zb+OR;z<#V&W;#we9G(bxoL8?KY-Rm1cwgGN6!Y)iCa-PcV#uH{EZzsMBzD1-#IEgh zA+YR=$z1J^k4~)}c^{TbQIV2}T)S}+N&&y{^;E#--vn-D>Q+CV=sqtyi{9+^EV#R` zC_L6~26V_F9fe`if7}cJ*0Pr!Ti^gWGg5=`P<`I%w+PE6^E1x6J_-KWfG56`X`PD! z5k^@{XRO=gd8Bp;9RQk~%k=zMX8l0a9WIij(#VgwYUCh@1De&tnEoLx>Bhup3;Xc{ zT-TR2?M~b86(Vu*#Ft)64b0q*Jj-6X<4wAgq6eHO6muv{3J)yk9Dz)XQ;|29(+HxI zDQef4@|PPdYq3zxD=E|OVz*zDdYY!7kaJ~Vqr6h?36ryDVPPThQ`h>sx(nRgZON>k zbpzkX*U=)Gxq2_-oJgFXXMT+A9Zl?~0aCk(4UyAt`&u28@e?D(ac(7MoJrC5jmUl{Wxuz^#AH=TH zluXo`YGTwi)V6oU=GVZ-e?cT|ntYS|<&t7;i>r4mFMXVXlz{$h4dD;aag_9P5NkLd z4296nd^E6B#WH{~&TCR6+oH$2$@N@ggzyVi_dcOW7l4_jZs;X%#MCX=pvF_Sqwmuo z8N;2B&O-J-lkb0~mj?<8+>j_b{)|_@*@ojSqn9X#=B9rfyWG{7geQs9sl69X9_9pY zrP^26d0$Hn-_Xm>P~6Cm?HllKbRdq^^$g--(DTkVKyU=|*PO$xLixyj>i!FiMM|el zB6&7xM;7I_H9{mkiA&$8*1uoqwA=L)UA0wFG7AX^e%xtQx1*@B;1T!3^#guWxCkd_ zlN#g7ik7sg4QGgx)9NiPv+>Ss%41aKE+FCMe&e(4@qRZY^=6`N?B)sNu`*!_wt)z;av9R8^bCs^ zc3{DQHEgZWBb{(&JtugiF3znq6(t3DR{iR{GC}v-xi4^x6=UI$BM6Zhzk~zY z;V_AF-L{`*r^aikU=Mo4RDVp7tbDkRlAGujMs$yf5aJ&RI2l;On^siL{84%S_0e-z zuBLy)dLmpeknOsrvd4B^QyIFod?L>}!~&`#x9%9qh56msF06f5i!y)5*PHOS%SV90 z4CNz&3d|^}(rRfDTBaYUH{_CQ?LITby>cSp1yq7NO;`dKZ10uh)Nn(mf|DjDDk|3X z%YGKOnwyS`GvedTo>;e%4Kdyra%uUg$~z*x#&Hf2_*V*Kz4)usb#7!y$McUxg8WDt zzKnI+#FPLyhf^zIP=`ad&T47zF4d$s%~3jmj)nFSElp^lOx+3>BmdIItE30=h^P}0 zoR{)SjjlS(k1{Y8A?@;FAN36EVz$kY0%TB9RM^=nE=;yy!7aDGwB|mOKfPS1uAhuA z1hVj+6TUCF44HrH)9js;xzs>QuQBi14;)=b3;3V3%{0-{A3m0lO^)OtR_HYD?NFN^Xw=-;M9C^2TJZDA8Nd6?{k3!b43XEc{r`Jn8jjMC7D-nq3WaBI+J@! z&+dXl79m62bVJg0T`^MmA3c+Z2tiZeJ{0QyV+K(RIGy*JX zoGN!CJj{%*I@sE!P0K9ydRbHWqv7XKs#tPI&x#*l-qmSe}q_Eg=$!MuvR zwQfxyw1eTyI8&;s`{GuCk?!1As)?Q%u7a6D>Py;xvz6RcKP{GNhJ4`uZiiS(D`rxR z)1b9HsyTSfweAa*ebJ{Mt9f~2dYe_ZwCXGT7sPyYwb@y%V5IBQp_Q5NN&GHLHk365 zB^#1{v?wX&7O`KE>A6cFhBa}W;u+cP=dQ;>ZDoE`9f=O-PCdi=a??g;^IDrIqzYv5 zGC+hyvv53ek{Wk!OMe@*h+=F$DaZzzD3O=)Ap8BH8-UwF-9J$bBv8)?*3TC7uH-)bu?>Y8?NLm z-gLbavB~4$Y8S|a|I2Ha3cPlf$#dRVuZ$>Ucl|`srRQ70i;F+~n9T*A_}KAb0h_K; zhQ%MPCm3!IxF7K6ErvNBu;;;}A+=j6$+1X|lPip~_3bljSQ3?pfyTZNEIN!T@H9g^ zrmcXm=fiQ7;u@-FWCopjpqJoJUp;wq`f^i#*8{ zc>k$`F#q-^W8`&~mF*-NZ7wt4i0~3iC(|FBlriY~Hj4*y>LDQl<54BwfQn)6L~_>c zgg+199De!4xj7s>AS?eU_T?vj1v@uSg$@K`EbFVPufx)h>L>so*QHZY#q)B0#y!uv z*H^2G;KH5sPW!tqVf9ryQ~J;HywR;S1n|8E%cI{oPL&eO92$BML3-EL|E_JoT^|Qi z8jkX`>Bk>~!Lg5XWjg|_mH3X08-rS7X1=ZAk_8dkE$~8*ai?s}FW&8Sy1{X0Y;U$$ z(+trMUUZ!iAgLXqI7U2tapZUq+0D)T#EopIPyk?CePHvFg)hk?mh|$feJb~2qfG~O ztS;IfmEFV;8PI{vC%y5hI8)`?oTdS_pMYKAviH#O!(`tS-2TE-IO3?j>;atpeof~J z>qkBx(|SQMD)W9beaCeuadr-J9d0dpE`umx3i;F=rCG{G)-<0A{Y;;Azy!lw?(sXv z@PxsA=gUVS)M86S%{N)(IlB6~NM&HhYxof;OoBE#vLiDU@|$kVTSM1Jvw_0-<#E#2oLHnQJ@EmkRC5qG_ownw*NxoeYWSsBaGK$@_3)fkmqDO8$ z^)@gCQNj<0Gns+a6Ry++MTs(g-fygA)ZH4%%IWjUGN+_!?0#h%UiL!%T5ZI(WUNVO zXX&kn+80tZ&UTH8zQo$=r`(^SlY7&Q(1}l`B1DRWoU?aBsSn=NcQ>4kmDCds<+;30 z0)Zs41J+%5E7kJ=@C4I@Z`O4uhpK-#Br8!Cj^}VZxUOnZ{#_Nxl!(;fRqC-Oaj}O^ zJ1$6tkGyM`HtP%&EW{}6uFdgc0O{Tar)PN8ZI*YUz!(Pr)_Ji}wIJ9sLhz59Nlyi&5!`b+eir{hwXOV`~- z4FGad@g+P21cKre);~#hT}iQ{Cu>}1R=~|-vq5zNk(Jdi=oAyjO?K*l?Gb80bp|u` z{zq4x?Et#{5d5P_T%QNf&^HFJ1&G!*>qe0W#yAG z+9t)<<7Mc(Y$jdg#fjk6J3M%cx9C3O{eN`5bySsI*FCI=f^4 z-6h>3-Q7q?cXvx3y5n~p)aSYH=l#BaU@#nVUF@^=T64`g_u7Ru%`^dK7gF<6pKOXj z2ycotoz|ro{|~!KW3u%KoKm`fsQ7+mM|IMiSNjik6H2xn`&_JXH^RY*`E?413WG~6 z0TaxP)~wQ8uG9K`9@USlnr{fLN}M%v5e(3!V1)wrjeKik{_^U?dPxvpJWT@}9G4K2 zPP+8&e+6HDgi|+m_8>&4AFt4XQT>0DF1Sj^wRw|uRc!NDtFUZ7htNf1h^y6gU7)Pr z0l8DpI!!}ORD2>Esa0)QV7Bm8sV?jv{y&i4UX2%w$%>*ds78*#N-({5Nxt*sjSbaY zLrN|+LZhaIb` zdB9;aPZ0JO;y($*Il7lb?mEAvOD*#M;IZ95cuXt)`Jf0OV~Uwx_V*Qou!G=QTyqRB zaX=3_u2_GCTB$$nn1Q%d1L$OR(gt=B2WkVN|p#wJjQ;%D7N`@=YvVa!4f_X6zKC;+m#tB@u~ zS*mxqu`AVW*y}{L-v7F(XyrM;FeP>$ACqdfX7}@M|Z>; zs;H7jhMuY80z3sLUe|m|{ee8!rxnOW!^dd#6n*q!$Dm{1O zav3fU`xjTE|A(Q?+k6_?-R1{j*3TQ=XTX(f)c?La6?1G(YpsLUgb8@UjM_ucK8Kbm zDU;n5UW?TVXbrsNXz}jA_$5&M8N%Wwz~ZU_1k-Xf`7Re{3AH9AjqB2GyEbkIPd`nF z(dl8_DtauTHL_RcJ^9a!{^n~V7YvD1AW?|x|A*0q{ln<4)EoQ>?Fhch#EBGk5}zBp z7_688^3T)b%)s{iZ+}YY1R0Khc`tBs3-1w`!d)zR7>~Q8OWwbH?T{T6V|5?&rIGku zJx+>YaihV1@Acw9K1H--#{D`yAMis@hIMiPKE4HqZi)>zL;fDI;&NMqW%wuTFeIk(c? zU(^CtklIK62QgEc%~Gj!X7)je)!R=_PpYGJVw=~ljrygC*XS;Ak&a|HItP8f z=N9n_o>#-W>XXl-G%ddL;-&OHqznfB6w!r$6!o7*9}jCcsYB{XPCfPx!|fj)^F&%B zQS%~POz+eRJKrn0?0%;6Gm3iY?bbkR@J1q$5s{cSe~jg92)NLn}MEqFyKp0$)7}Gw+k`z zQ;SY`7I5CJ#|eoJ8xl!|`n$QcRxWScE-r>dkkQmisCNlSm`!Wo-#-|Bnk+CfNCFBb za|?SgJYcLrO?d!IDhgkUegy2#ISBJ=Y3K_N;xO``_+L6)!TAccxj>Y*)V>d&oRFA4 zL$J9Gb6S#$3M2)W_y;a?@~$JgWiUQhV-} zW4kCrw=P3u8dZBcvQ)#?dyEES4^x|*9GuN^f3g%xVTey2`!~*s@kVPv4!mq|*ri#o zuw*LDK?8%N$Tt5IvWiRV#LpIo?N|{~h4IBWnka*Jna6rKI6xLT5R6?O)~0bmoDv_l zOz5?kK0bhB?S8@VU#|%8hoYfTE;XpWFIkTAPK>e1difiPHC+;k|1TjeY6{4A*t)n~ z{(yk@TGj*1JyLQ`tqN`Z3)_8W=UzoR%4xeu4KO?o_Gb_{*&Sw(v&WSH{E0M>#DnQ7 zfTxA;g~FHN^hJEW=*OMPJg^04^X}SqtW~Tg6w_LUkZ%5|w9unameR%#HmYLN4dHQX zJKsL=rvP*VsSf`ldhVfg*q6f*ZF0oaxT{wjBi^Y2to`3o`@_T?fH_fTEKaR}@&}JM z2*O}scnnjmRm+fAU+URf&4&fZ1&KWQ-@)MW zC{WSVG+Cs4o-4BwKWw84GmiN9FydGi2G4aIWAmRb1m64ZSXE*wBaM~a5g0D{j|3g5 z0Rh}M6+69bb@je@qA$ffMr0*C(P=DKDZubkxWR$re;k$ek?BKN)0oo$x802)Rt~lg zc*i_x9Ko`7SCP>bZYQ&I2cpU)nH-@~?8C6MSB5eBvmVL-yLF)1$?Nkd| zw^G4l|6#M$G6el-XZty3hpK$0}QTH?Cuj8t~>K|g~!$TEed~n!nTHfAkVqr6dMqCA^XzOMu#)@_uPf)* z#ZEjdj~Q~iFMG5S9PkOV-<2Zf8WDgA(l#;(fEyJDymX>wlWg0CRwLVh1-h4{%=D2p zZ~5;mfceH2KFS3K3(dUVY7$WVRPn-NE@rOFwB+o=F#N`C9uM(O3s(yyV0nQug|yP$ z|F^l}%d+F@C}~;47cXVJ<#FY*8{P{j_w2uJ7cG^UNNaJn%B|uZ6X8l z_U^Ov&9uzi5iPOK1f_q0Rk%={>>Fn&W~A*7$EM^Ey6xKQ*aHFz{0IE`G7S3%ZXCI$ zk$$~{K(&GD4w!+s2?P>jI_BGm?m9Zbz<;ZJp|4DD?)U!hNGl1Eai z+EW-8|9_YwDvw3LBeo*GCR8+=e+cxBnshMe&_{PK``2rhRPm9|$^;t5A0?Ljd0daM>K-n^^zNbuhbNbuWEN(x@{=sK{oLe}lKD8%|;5P^T% z3}P^GT>itf1@loNBZ&)mH7K2Tr}_c6oHD$)`4YF62PY-)QW3o9XV6~<(ZHcz9QWo@U>iKi ziIL*kfKJhHcvW$I1|Zua!w(vT&l?PRzyCvNfGTzAaJ;BZxCWm?;}`>Bgaqp*5HD+& zXw;Zcy|dX8Po6sHc#)$gQ4FFFmtt$ix7)gRfeX4(LpUpGD-qJnmK~x2^(#;ecmV-0 z0kLbDuv?O_`+2&PpdVfP75U~e1t~xf|8;GQ{Bdn`vp)W_00L27_C~ENN9_XldkrsP z#y6|dFZG|Wm$y*(J3hujwUugmW$iIRrxNs0{pX7RG8`gQz_7ghAmPSd9sv~X3 zCc7fQG&NpR zWAU7>!NjqJbKZ%YT@f?an9YXZ;nP_g`=GxS`jUqe`jiom7L7wOl_X? zm!gd%z&_IO7#^ErwZ;p)D8z(#OsK6eOhTt0x4L&CxImUg zeyQVTRg7DhA5*e}w{d}UN{lb{G@YLR3?lP%8_-HR-Utd49IT1$f;o{E6u8vKKeiG> zSF?v{o5Ol`Cb6fgPMZ7Ie5sW*rG6qdAlt_}23#s+ftSkUuz04K-T_)>S7 z=D*s#gU#TK$|ZrQO+Zpzty;1G$V+sp~HTlCrW(aCCY!3 z#r?2gtZ2Iy3b#8g^HCaqH`?-B;y>|-C%-1 zVen3-anso@(=)%~2Mj4pETy&OsnQtE`gp0bzg_v0>s;B9_pOQYa#a?9{ z15K4Y#JmH3bQetxHl~i2xC8^(;1PrZoyxcTmV?Bc$T!BK@s4+atA1hFtet%xUSRAAa*uE$ zYIj@~^p28ENy5ZO27u%VouLN09V@M2a8mFKWPbii&xYis9ueEH%1}TX$%c|C4(O@zQ{iq|m+HIdH8!io5jgoxWp`sls*(V9%6}7iItH$w zQw!|9nWu-AF(9#fxPzTBIfgNzxcS?N-bD|Q{qB1{x;qzF)PQ0AF*@3*qGe5qq!)|B zHb)zW$H5uyz2Vb+AZ-#}Hw<#O50pFT*C$%dXTK&?yFV^&7&__$z+BXeCqT*wkVm?) z02e&z3m1fO$C|Cz2d!L61k2uav#9PSDa_V@k%DG{mygZtk$jn;j{)!;XJ99=C^a~o zOlfZ)gnLcq!shHc{#e{)c$3`-+FoUM$JYs^BHP0fqnbS+4fCXcWQ}ErY7XcRHFLO> zaqqmmd|e#93qsYHn4Hvp8$(Y+6EiR%T}e%6G~A+2ds`^`r*GLb;eZnOHzFy8M!P+f zE@$!sNw3Dae=)!>Ukd6mTc*`jS0S;&U|x8*@RxXDv~Z+jx!>K*+T#MY3WUYZu??m1 zP}nY0#f}>fNrKW+H@9}2A3T*@h*JO-1D)NmPIO6Q=IDW!yRcSzU|rKUrmD~c$X<2Q zgkK&OaI-BonY1TLLn z7{ATyzr72ysm;_NQx>Q*$5c-d7(S}+Pz}~LEGb=+4HUx=|9w-Z1SQg*pyzSDkI@EF z3k%ij#<6M{>JvI&jkpfj%)g?^<=MrF&+Op?Q<&qEh5z({q3O3!dNoz6=^7$mazrP( z3gq1(7}thx(lxH1+n_o3{IzzLa#08%IX3kR42*dIG~c*C`4&#s^PB6Dq!sgcFtu08@o;#fF=q%o8zsklqizjf*J|rlT)sAE zaae_2{@cl;R=FkrKU0T~{?ed!%J^V{A2k5L;LE*GLUkX8guBnK&{*k|rJ?|l zc&Oa`c{|f~d#K-&S9|k@>c;@$6Cc1&Nbc2keY&xVx4Bgs7PNCdieL0Z#`TTzJwA0P zTN4U9vre9&y-mCt`r%K#lsK_hwGn~DW_jvZg%QniD%xRm6)Rr!cROa_f|4xsCra*^ zj$a;;;jZ0wXQ^7T=FyfU9o&;N)`AkENX}{DtZ(nQtM31$oV0Ll93iP|H}DsPv$=AN zcX9t=E*fS&OpvtI=>z(dC(VBx*fqL*YnE73d`=~$i*PSiM z7Z`lJsepI*C{*r*SQVAN;1V{z8s^xrJq%2Zik!G>wVQr-vg%*& zKl{Im3bEIV$re7ro2=D{NdG7OwC*;%nLaBoADW$B-r?K(c(i6>4A;j$_Dgp6@GUsU zzsBx9z*7?KZchlSK+8#Z^wgfPKeZ<$PP$glXi8}>7VGtM{d645G2Ynt8H)rVc+G&S z-nBdA;kBG8i0L8$Mkjq#wT2y*d>$1#w+6$X`$2r62VDyIcb%a}URVff_I`8!obG_5J{AJr3vr8Kc4I8fJ`3*IXR`Th{cUwf+M2sTJY+k^q>&olIh* zV8D5W6QW;oDKe>n#O9NRaW4TQmmLa)5+paZe2rCV?9GEp1Y;uG)uG1r;hu*Gx|ET_ zB9G2Z!z`GGP^lv`xrbZ^mt2=>N7r zt+K;B|KD0htENcnf}kuGC%de(V>8a&l1fHRix4bDsM53f57&4-XJf*GlbgL(_(z5s z+sqzX*&HS=SOwXMNn0KYl!702r@R^rDq^OoLAZ6ft1{X&KH zYA)x*94WA5K0*u5#ahdEPBpOG!%uGe!tjTjBcbcN5i!y92wZlN8#{tA+WTRNCl(+D z75dKqYN35R*Fp7RsGCEZm?)CnE5gk|B%e!ZJ*carM;1SNGkF{5Yhr58Pr4Y;6hxuR z!-Cc^Llrj#;3zQ1{Np#z>FSpeP<_%yT(V4U06&G1)|89_UcUff0eU+G!2&*U!v+nm zs!t}V;Ylg`^idmwp;}z4n$&AKV4zhIWkD?9KY!Kv$A8|V01bQw{{Xy>0ziJ)4vM34 z-hRz+mY!f6crMGMbK|qr5w=n(cAFfM7rKt*A2ZlKO59lJX5MCt%VpDZxWfj}W?8A?)yVaIPC%FyFC3`9-JaB+g zu3TJKKH2^MDjPQ>zdHvzgXQ0o1Xd8dqP1yq)>g=~%VR36V$P(lJ765naEpZrIlWZo zm*Re~+~!*BG1uE~ERHqAxwN8XS2*Vt-Dj=Jx;}Z}KYeupnm=GcG5A~*|8ZJy6#h*F zKKgBk=W&bQb1k;ZU)Cn^Rccogv;!%SfJ}-8wA*{PHs1B3os3xHn@L1$T$tLOz;^!t z7^c<3*?N*+_2AMsV~LG}@Qm)#MEhp}u{EtT7Y&50nFoy1G|a$)#0 zc&FukgYvVRS?rTxorv}{+k(e=9A`Vh{H&4#!$WaFc13~$^R;fBuZmiRW&UVb1DMjv z^e>(}gA6@|RiK{>wv`|S$^>^-HwHCXfEHPGNmPdxK8_E^o<|G@Ql3tyb%afbQ7TnH zH`Jc9;XsoHA`wCY|I72A-;4#@R7hml$8j6_)M7;sU#}8hPS^qC`f3%&%NYeX8C%W1 zQ()h^e6{G4VLYQe(4s;%x;VkqYD|^Az|G~SDe`!1Hz-2j>#jX1(0P*y-;5@ivFrPc zNDl#$DV=+p1hv`u99xAtp1*O6cMD01>FM#-pCECa?#*}3>&Z6x+>Rk_NqD<}8)5ka z60~nf#C<4$mxK}}B>&81$x|1a!eRS43gw2x1D_2FA3k3e8VN!XIz@WUC${mm>u1>I zB}%P~I%So{;a1mexHSf`W9N(2KuUaEqOO$Q=sn|ac`O^H9Gp-NW2MK)C2Bb|sQIlNuUd1dbO zc6=;>+h>fdA&XVr`YqmO`5e91s&4lt3&1bphh`^*U>lFN-WP-{bvX!b|E`dh(#*Lb z96jdi2?u;?Mube3FPE%6`p`@L+psMRt16bMxnybEPZQ)63I(5WzJy~e%!=3IdnZCi z_vqRuVa`+kwI@fXTHZ1Ci?*?FU(mBKc4E(T^<@f_tvP5Ul4Y% z#PK&5Mj1n!N`FFxP^+UoS9P_*`rwHSrG`B*i_yX&mHg5`364jS>%E|`dIc4NF~cI6 zOSobr`c$jUJ^sVIOOh43S}hEO8x2h?|Kw|67cD^FHIltT9DAqGu?XMH37MqH-Ae-A zDQ%lb))Rjgv{i39LEOWJz$jQnAkvsC!DZW|?e}tWLfp!h3OH}^p!Mm(W!l|x-dKx! z03Xa-Z~nD&1M!uI3bc*cG|e9zC2mJ|)tFj!pHm3>xjv+~FBYSDScQAg*1LbaQP+5A zAUTapaYg`cHWsC6eZJ+{`N0TR0$ObM2b%g#0`;z!zYdkW^iNpAG1E@u3?UjbL&unGk_at14ZFy zS~i;c_+II}J4F5^lYEZ6J1=(dPV{#&AiBQ7dW9r_^ri(=e65VHmzXeENduk|juJA` z)G$lk`KdURI-jPqnr$ zkeSX1!tcfazoaO%&61v4a;x$S+Ik?4%-&g<4QOlcaObpV#_5DWM^EouzUt`kBkO9s z1|KYphT=o&*`8Vh$fbowHR4O|H4lZJ)vvjZS~eIAO3UvsamWzlL>b&na?luw0V%>s zkgP1kz=~E9ma(~`Go|HZDoV(mSu#)2GRdevs-*^2xKBIba@gT<*lx8&;uHN$V5|NA zThTX=vG^NSop>9Uw%$H>Lrfmb2yN&=%Ezy#KOfDAxZm_#zzc7lh*aKFf7Sn`Fqf}I z3^QvROKhfbKOQvwnNai`-;cH6WvQu=G^%hhI1u-teL+EDePOphlPTE5P+$cgT%87% zpk9+cg=rj;b?5Iejc#3QE3J!)-#-e#)ZRH2FaXDhAV2@gb$^~-z^HDEGs4L;h73Vf z!8R5o@%m)X7zvlF_8VnO?*b!NT>F*Jy)K_w&bd!E`a&G$hgM3rFhg^vhP^H0V_Q!r zOgptX0#i6_vcevbHhNR#eof_;^dUa5tsy+z)}x6stL+i!3+BuoVCd1aZx$F(jR z+GVt`ykVUT!9@LE3&E@t(n8T1$Pn=YD;JAj%x94MVJ|n$=fiqyEU+>psDTi!gM&!g z+kR$wzcBrLYB*jeT~qKOZUVB1gDJtI^sazaELX8wdkZhy3k4jhD{#>`La(Rb!uflLh551b#(;t#a^(sl2; zMzX7LIE2wEwkbs>t8N11NQn+pcJFsOqU3>Vi_s*(n^qTkpD!t}62tOD^4x^LQ?Uzn zKEXQ&{^_9z{+`*z>2%G!wZ3C30t&U}SiAb@z^CKo0!yP^qDwIMDwEQI^$QjJe4y@62+5M*S!PLm z5Nwk`VoyK`3t>}{oe-@`@y~i0Vr*vkt;nND61Wz;{do?bv%hJaWR}c0=PWiY3psd4 z{X10KW`VMA4U~QB<>7Y3L#}z;F~=%oYZiT#?)5yi7RDqfqACHSDyyVs@v?82&Q->3 zS24KYEg!o6brJiLfV+G5$e;k&_nNbtg@qH4(L%>s^YRHptg7FuqayibI~{s#s;4!V_2idcvtMww z1}OBcHDaQ(Z3#cwx3t(0z`s%ouNaQu=PbyqXacJ=81<&Yp-%q8<;OyIngb?%dh_i~ zI~dGRjgM-{NiO$ATxwFi>9w}h_&jcbHeH28WuiEXmfCCT*8-2C3j!X&goh{$0jY4& zfr|D_$T_co-;XImc&h%&zK3pm@8zV4-^Xe$91DZ*-c)-8g~$rw-OFursoReCT-8M( z!A9CKgJvcW`Jw+rroW*L&ff$83mIW^_zP2XNyX4hB+fk8v#@zODqx6&@tPH8qdzP^ zJDFIuB!zt4DmYW@lW}(-rQxtb@b^#WBw0hmJEqh&8_#YW;6*>w?u(2w%D|e60K35k zDUin&eUu{Ry1*i7Qh+5Q+9pW>@6TuZ8q)XN*4^@+dvItPoCA_I-8XjZ*rS@##ah7m zuV0B@{|#mG?>BB+LaIxQ_cg#EcC0p4g%b@sdARsSydwlWus zWygV#MBD}H;qEQRk${_VG9PxtXGpCulmEg0>(3-6-gb?U5J@u4BO&|kb3~UVR_iTZ zpo%vqcoF-ZoQ}#5P^Ub7ydp?-j@JnGc*-J=_Fo`!MV=97K0TOHm|u-Af&S26Lg>KZ zsh8r|6w_Vs`);dwm1uG}4l4o^FV9Y+ocbp~-$R?=kHCLlf~k zTUl9#yi#I}wTdPhc>zv-nlf`Z`|QVTX|1lo8t4!sRC?ky&aB%v>e9%z{c;VqZ}zgc zPqilt-@rsf>*z0X+NGWN+=tcq+`G$$y@nrZK_1ac=pC){v$8^?m)DY2DFAN*Ur%*# zF{C;CrYrP1e4mr{3^m3m89=Ep$VR>2*i)LnVE8Sb81UEX#XyOJL$u8a$?RDCYv?)781%(s_5K(qj;kOqFkC` zmIx*}m>!BfG0s(_w6BuMy9FjQ>ghWWn~hVbxy{7ep} zE&Cp=O|&8jaspZ~Vd2!xV}d^|1v3Vaw`1)M0|NztzSo4h)PwVw6QNUU11I|Q&E}N? ztYBL_w69pV?OyF~h(`Pb(aiJ1yKZXy;6Vzaoca-B>l3{Obq<#Z#w3jap=SY5(=IxUVtIUy1YOUl^zIXrDN?pA%N^9j^L_jY1C72odd-$71ihl&Mq;RjsBydmVX(2)J%K1dkV2&@bhbFm|%hIHBnE!-w| zA83DD-HFMgR4jsiL`a}i$8CAATg8x1m~W&t!68fiu4>PojK}J6y~`nqe$Fpc8ZOJs zi46l}e?urQph0I(tO~$bRjPko5P#eo&YoP&<3aZd!xDG<)`MdIU7c+wwo(ko^sqkX zSIr0iY>&0EgK^5p(zhDd@JM@OJE!5Kz9i=#f{Q+nU1rdJ{T_{ulyNx)L#TwI0o~+u z`id$+DbjhH-ng|cf+A5)zQ~dB;S!@#JC;uMO})+bnCUtUqMiaVT4ziDuzfN3QFZH99o7lr zIck%0mp*OEWr!gGDutX_GQuKhzj}LN0t2JIwS!ixy+{>42~8QV-xs<~m?f+cbw}oT zm0AKJ@7V;yjUj7ujYbF;lG^p-Y`ETC{J6p_q3tx2#TJ^oz2x*ZdrE2)UH2O=!$-xJ zey|th~sah18-`^mR4-{;d)KfF}{zE?;%4SzdiYe5X*U_&M~~j@8(gByfikg$7Pjl2OV! zk6j_EYAsaQa_P_2^FaO5w!SgplR|Z3m4zGi4<4s%_JS5ZF*tWvNUb4`<)A zHlZ>GFoJ491KM+YCw)FP!{^QWpK7TfyTgr^DQ@e zBth}oaD7sAVAP_i~Wwv`-;Jy_&%^2e+W3Y3vU#hWU}a}MpRaY8T4NM0QBYS>1TUP^8!LTCeh$vk54L@= z8MA5E@v}?960SPiGcu_JWm>UHAnZ!ZNVp+Rjp_J1W+4ZOeJ+c+syeU7|^tHikAGWf{|WJwj6{9#;d<)OgV7n&8vJP`c^u zS*C&Fz}o*V?~ZF{y8O%XrK@T+&8uutr|}E8oG*61uEDgc(3QfR!9cSe4fGhjJshc$ zI&$^l3NJ)M+GC5kMa>`W<9BOEX0L3oO!md1PdetRI|I@&`A#|Z8fRy)T9lL#Zc_ob zf#k+;x~?|wRdHtBFh|5&W0bv~NLSVimi}o%eKW}IpKC3KDz$=^Cd;{a8a1#&<0IdG z4s!G}8S960`JZ8ayK=Bya=mu!kgmp7QOGM{+kJJF={#sU`+jih0-ZI&_Ra9CN~~T9 zrEZVls~II{mDamesR=}ck$yJg?xic0pN`S~l4LxijZt-r%W57#gFq__Oc~ze4o_(a z2WU!b24m=xO%{-p6&xBh1!OGo(LU4 z3j=?WY)3NaP9>yT8rAe(_jW2Y%V{w?>HNZT1BMl;fN9S?b>1xxsx7nG*T3PCwxN+ zL)fUlcmL!)-@w%|;u1|x=FRcvp3!0ppU-QE=dqzAr z*WurjmFjxdZY^v+Pni|fRHU)g^0n3xuNF&r(!^)iD2!m@wZ-If54w3n<*DzPJZ1fX zN+cimcrcTTDEjfwW?Jlcx)DIx!1kJ{c<1lXd3y8#8=`4|fQY|x9Pd^x)8E))kXHQ? zND%?OQ5H?%Wls&1)`=?a6*}8kv_j}9{bH3Y;yp%}pN$%6bZNcMJuP<7SSP}S$H^pG zY@xiY!Z;lLTrUNIYjEnkJ(X#m`fNx@B=KdWP;tdll8gvQv&uBwss90qZhXMd*K={6 zgr)NAu-|6Gv$_0c1KVZ92X6|CP3w+->?U=u4pcoS?(sF8kYT5psrh+wWVzkrn?sl4 zhPC)roZ1g-za)a^gIF+GKVtf~-quJc*sD!sI0Q5W^e51V1jWZq?-a{k?e;KS|K#(> zP6_7L_o}z~bhz?9 z?xX!TqI@tss}Wt%>4wMU%(E%dY%U^bqG741mLxwXNNB=PRT?IdD`|49J%D>K4JNcL zPS3qz&AUs@druNhg0nRcg=%pZKqz8h3nKf#d_XupQRDQJ}cN@hOX;#dAvC{qg8jn98PZ)b_3b`8Xvk^ zC0vwX1qd6OA2XGh;L6=C-|v2X4;4|)skQmNz0g_RmsQ!)bFk$NsTa^7RD|$v#caD8 zW~-L!WJ`9Tm`pEFG!k3PExloFDoltuy6}{pwHYJ!>^9d7@wGZM1MBRUZdgC32s&|fAE;dd7;^dBaz{{D$c>yyyA zNr&qhP_MP&;Y~eKuZerK7&R~RLA4p1?5D!y&{M8KID)-@i{&HQRl-bYfPErvo?IMYQY12LH4p*uYzxrvy-Fcd`KGGX?(=C-6G#T)$rEJgD> zmvE41RF(*w=?blI?AOkNy7LvL?F|+TjGYWVfRK8}Zb=PhRj2<$k3cQ|ri>4*`MDik zp%jd#3cK4xgg-CWg|Hle+X&VYs#2FP2SWX8egpoJGT|FRq@4k2+ znVgwMT*Mh^RSmYS+=$xMk|A%NCr<~mmqRk>@B}z?z52DnH}buu0bN@CapUK}fNM5Q zAP)sOdB^y;Qjxg*Qi}mqV5kBe@y!<)Ul)Y~#8Pts?xKJeh zK(wP%hw-CZhGp?A8_El&zSzPH6-ydG%W-O5OJ;b;%ayXne^9S{K_v5|g2da(>@_hA z>HuqFVvn%Fj_|;Tvt4r?2G#+ym4>4ixFPQsFwH^(JHEIZpFv%1gb=_L$O)tQ9LWxjoaiF7kDlp+o*NpCxrfeB=RTj| zaQU4WBk?Y6bjdejF@y|{X+1RinD9VTCyVb;Kmq!R08wsSLVS}$Jty*8OEa|ZoGmJ* zGk3f^ToQ-~mx;6y;nNVe_nfJrc%xIDDX(T#hlRvW#T;+N#d6z%maVJ z{VUl4&8(vZ#`zrb)bN~D$UTn*Uo~99VagUFL+u5Dp$CkHM0VF{{7NH33!A1@$TY2B z_Ba1*lZ8eX0ynOU^_J-kyt0_Wg)JVORdr40VI2fyzw>G%5cx!ric*E8o`MNRY-K8NPcd{sN!<8D)95!oEz0=2HvknudjA;~Hm@(;rg zjsRu~>$MK?3)lZB|gxDDq}u6}J2Ni93< zN0=8C?jSPip>?Nk)=MdUy+9{o?^zlo#@@!yXJfKD&2L)V*iRxqY?obdA}F0_iK75( zeXtMzd^5^TuY@PDN=O69OP{*>mp8|FiTO-T` zggHK+LEbnh$f89;7~S=(zx~)@lCM8|9Zv|nzgQSS&}*g6?60QO#-$hNR=QU7HpA3D zvb;0w<`Tjm?$f1$y1SCg_uu$ndxR3dS94H{4Ln&NGx+IvhdW6fC!G9k42ShDaECy! zO%^yCf$Rr=X?`d1#d49~W+Qv)mVoz0I@#I==-HCkz7x%E6@uKw9*IcK`z(Oha@9k8 zb;0}?u@v|sPoY`#qNz(GIIzQ0w?9hYZVzg2&@1vY*)<9uND*ZG@PazOQubSXAM z)x!nn!A&Fuwd_==;S3Esx#kPOSI7#Gq`xG=LrYW7JbTCF{Jmb`-wC{Nnu0jRl*7J@Vt z$(k4PVG+d#YA2C$^$<`9;auoydq(Fw{4asF@9Y4ZdMAg1i=A<;$NwNezCoHpfzc+2 za`}##!0lBN9kq{9iDoq#L70bFg%;&cdgQKXaPIy}b`J!z)Q*q7AFh}hpXT#dF^zSP zSFG>xAN;I9Dw)r@X)rIxOl*wp7mj{`!$#fDdF-Qd|~0J zw0ad>tj^MwbVI+wUe(dmQ}(;7QG;I2Z*Q1k&4T&jhc++hZFhnqg@iwZJ#b-$7fcrJ zR%0-wcm-B~&aiWgmxMC!x{x$#OW!g#JQYyF;D5-l_(s7TX>P~w=ZreFW`-g%!{qoT zXld?wx>RjeJmQ7je0qk*@RHaKsqgv_4*??YkPFnPM;$&fM41@zZj`ew z%rFOO*_juZN}@}jq$hh0d$PMp^96p-KO`t&!YPUEpt0%)1FZYhfa0=da$vMG7y6=x zeFAQ}2BRMv-`xWb=jGc&!;VNbDP#q;bfs@{-H}l~WR0~Bw|%vhA2VFi52J4?Av94H zFh4mtEZFGucv26JeiwD|xk<`?+k--&l9 z+3O#|W?U+qj6;8Mmz_lUG#WT`zPG1IT*7C;e-4k`-YCmM-yq|p)nJXEC)cGfcJ*pM zMEM>w!SwE67q*9!WI7^&J==v`c>*)&FK_W-A`7x>J)stE{ zP~VjM6PsPd#u-v;(-z6;7dJ|bRW^Ui!dK1)s!J}SenM08Xqne;X42m*>r3tf_Bk4$ z6Ca)aO~fw0kO1QWGZO3L6TE%S?-hPr8l()Gvqx_jzJ`_N$uhI647{2turPMKomfYB za9+EqE=(~wfFX#E%T2|v0iK)rfHAaY-g>R9kBDl zXD?eo{Dq_PMO$^@wDs!U%l(C#enN3Dg7mt`CLs#xY4p~M(PT9|Zl9pj3&(a9zR(;)?SvT^*81IrkqYzL^&(BVVC_R$xY~!SZi}z%&e3Yf zf=K~{R%zTCMiET-s|$&zz%3fgM<*8@H>qZ1m-Ibw_#r&VF21{2)0x@+ZLMB>rqlU; zW1EsBJAx=fDV!mxt6b%LOp;Y$kznATY5a)ak$pp*5Qs8I9!pYrS7Mpxvi?gLZSY0d z^GVH2!PlSiVjB$djKNK*Hl)3+f&vqVjnESnF827SCdMyHxT>=8u)K$J(xM+%+33zX zmC5l(sVS(|5h|6XRH@1;w@fX#gT}Zfj|*`np@{qK)Yw$c<@EKGLAKt!oC7HS`xg3N z??-a#Ka6sDq!bcN#@>s5XjRD>EA@Erwojce2${9gxR`%WTaRw@C;J9AdqmKN;5)fGAnU;V zU|ai%PyBFKTX&n@(Ju6d#X5Q@0H1jzhlRF!NEMhPB-h4|gcBcnK zfGv8hu(p-%UG71gZoCw}ZK%7qLUT0e^9zeE%mNY8Bng2XHwL!jb?Q=sC6kxJ!U{qH zZ2w6r63}&$q|h;KnWFT5o?}1x!|lsdzYb{T@62Fk-dK#YOrVC{ZxV1w(++0uA?G+pz+3Wd-pLmW|hI~FuIa$>GWLe_K;*hx-kS@fV zk`+gkPI1u&h|WKWvcwUjvsa#=^@21B#a=wJHzwmxlpymae+4^boKl`ru=YM2ewW9P zrf1oi=XigEPMvTex=6j2F7d-EY&~J<`q-hYRWV=koLa33m<+8l5|LyV#HIY$>cF@5 zlgKzXNr<*U_~yqK-zlq4k#KJ)H?(@QzwwPwV@y>Qg_sXf8LE}0Jald)iiP?L; zaYBa#Sev)%A$7x+;+3LF`jeO8(!x#;CsfoQLpazrCp2mB_^bw)@*){=P-X z6lujMXg6v$fk`G_(fJuozkY`y!Ur3)()R@6foqwOfeESSmAJG6L>}rB5q0N;FAx3t zGJ+f&I2Ji&@MN-bQv?9zJgnnoaDTp}9rW{L;tcLFfZ*Ke;Yg9iCeFI6{7i+-499%C z(DZo0F42R$?;t9ChOjZ1jDfX-WrB=Ee%+`MjLSetD5)8w}$I>BbCXhh9Z`n%hqJKevb}EIIv9z zscb>dLD29LOn(RpbELZ>hOnk=oM+3}Eq=-}b`fiv6Grog3JGt|G8E4pw2%GmF__t?RVQUX^ z^xKg!k4FBo9cJ$FHZ>J1?~*QPny*$pBQA?(D^kNSXw_C8UYC$*ulAzIhqJQ~+?w=7 zNdBX1ft=jO$T$u|0I zrx3;m?@|1#^sG*OQhd#Z|51A8Ba^UPZ2N*=NE$fe;+OCQA&)NbDISl!3i`?v8Rok~JY2-SPWkBjLD^DmNHiQZCA&l=veahX|2~2c(r~`> z^}r)Be_DeM#)oym(}rFm_FeH?Z)XLIJ<@%6nMwiRSz{*Jl>#W+Zp)kv{Hs3T^N;}N z_ehTbD4)9Xp6=-n#+e35H@=wg+Iy{rxcLT_-;gi8Iu%)CY%N1SKDt+5v`3@L#r;~8 z4#%r&>eq15WM=|xoJM;C%CX_F00LPfxM->;x{4V4OZzXjHOp(H^}%GKcXuy|9qBCE zQZ+bg3NK!AeYiyu=_^zs`6n5+YWO?OI1SgXv3`XbFbut2~*R=t?V_>gixWISn(LO8)hENv#dA)lV#|h!(&_B1w`=xPwW?#1OdiG!> z*=|Dsd_ORzQpyZXPBm&s=%!;hiAnUIV4vZPbR3DwmIowT&wHUNgvif_RV*M#Rk%nF z$p8|t^?^#Yn%kyR2N`hg&P>`sJU79lvnmeVdyp3>M|Uu;z>Zt@$cxv0X!Ju{uo}=! zPlX@XKQ#s98(>HjdE%<|`Ish#Lw^{|;;EXNh^QbYJPaOK=QS7skB*cTVy;j=V&}h{ zCr){dgd6%f^W_%S(QxpOGW(0q>%*l)U6Lj`(%`;?Xh{a=Hu!Y2rrq*NwiT_$EUjis zk+Ez@m8FI#TcT&o+z-rR+K6~f0HTQxzehde&h7@;-$p2RVAs?gs3^DqdF!6 zAdAjQie@$pylFb@cZh$W_$;LyA7~q{$K9RADP9p@7z8rXAzDM?m^ zw!B{$&xa1pd{Uo&95B*uJ}%U6*AW3p)7Fv7UeJZ=UU?(WJ+iX=|PcywX{wh^G^z?AndtoW6%9|x!_c+_2%8IsGg;b<%YuPYu zz14H`OO!J>I&rE*)qj}xR-@v2J4#{UBBACPBNaGM+nuiikV;0J&1cM-ET%^*6S|_3 zqCS8A0valb_>7|c?*qYYzWDwn_w*{5r`yp?__^Nmk{<~IMfoNP7sDD=CX0eqQnV+T z7rZg21M?Y5wgVq?++`(R0XWjd#)Wp;@XsX|O)hHC#>$%F9$#fBQ5cPAu+6R*kR!jj6+i z75nvDx<%d)*eirgOi>J*Y&$X%{Ct!U(RuwiSqOuQ3v-fLQORY>{8wn(Qo=@1%vzz0 z5ww|~)}@CJzjwWOibuF#El1HuZtx`lE#g#gFt}qC#f2H^O0z1VH+kOQa&W%ir+qWa zay&y9RZ98WM?^7A#0a=^zUF<=gj-Rq+TqgbK`-IEJ9@_HFkRC$Q|K-{qINRZEXj3S z@zZ#a_N=K1RnBrrrmZ{()TpHi>)%?b!BZXTX9*ymami2{Qr2fJ_qI{f%-^+?E~oPi z#Ehv)pYI{Vd<4l^E;jmg-787A>38}q!dn`!57Yyjf8-L8ACg&2K&au*k1{d&xQjik5C|w4x$jBQ`>4)>T%$VkYhW(DrrNbHa3(FbYksC?CM(6~_&?D*4}QHL1**zWJA$fBQtuOGkTd z&dJ?k7uu*}?#;qv2i0vZ?R6i>bmg!Xc*oV#n?9u9G1%v@vPa6ym3L6DQ?!XmP>2@-nY$5`fBsEZ-%t05 zD5!e9tT8NiTa+CA1fR=okLz;x!dHEN)*Cnm)<;a$v>wqN%V_8xYth9~X?SblD5024h((&@MBy;2?AiDkoIPoHE72%m^a(ZaBYg69+NyeKR8f4!0 zJ*nN&2%LS7Ru(~iv@d|l`kM{g7kaCec|70Oc~evoNP9&;|JAJ*{@6)3St&k16qGPj zm>!ltwmYdLefV%~PrH~~@pj@IUL?fk`24w@y>*ANN(jaZ)K-|&7zF@YJprJVZ?5H6 zMedigkMjUJ2{u19U4}DW8>S{ay$tKt9q<_ynO6&f>h%P?3=*q*XIj|W^Dg0;+Tnca zrL$iR&qvDC%1gE?(`9)lMLSk(Q0Ith!^L)}m9b%X(B5n__{CD-VE>OKr!5Lsk_?8X z^R80Cu1FR|>g|A~kglBq>T7eLQ|&>b&Kic+dh&M{{7K;aPT>Wb8|SptAgsAk08xxu zh6(Z&D6<>YaJ%Yt5;i#{xI{L(Wgj-d1A6IKH)`wj_5qII*=e>qKaKFs2-#utf0N1}6q^4D^hj}+| zCqEtS%4})i>0_lus_t%a3Bw>0D#!$Z=(-<-&QL2VX?HftqJe~wP!|7F?NxweT}GNg zjw4IMFer2VFMX)dU^(Hx!^+X{u5cm~HuQwKnJ@Dz(rGKgy|@zvro(G_#9#1_kStCY zRYNu{82Myx&I{g2hDxMNWdMx#Jb-^Mz7WbAKR`2`qeh^3^3C&dVve-J7fFUT z0?J@XHRdl%XRldzD&uxO+K|ynTaQp_^@)NC+?UjH-|5f7_SroZebeehKdKuN$;VSHC`8@0}pnQCq*`n@hliY!)Quh^`wCLe zU-^^J1{+ik+jR)u14&OLSL%W#K|P>dyaGnSD>buc{)F6A2NCe!agX|xAsFX2jA()B zd2jXTiAf#ImnuQdC!3fwQ+<_KAj9MDGG(97M2eez{Q>v}f#;^bc9-F}>%Qks(6-pD z-=UZt)>F5byAEX&oWbpOh}v4+ky-u1_qp!&HMwatP*!ajsnEMF!y&vWb8TOZI-C6N zR?EErXoMRVVQ$?SyyRV?o7eI0u4m+N759uZpbfcATd7p+PMZBSB^YT~v%`y16q27} z@Bl(I8HBlT!YsCl*oREuil8lbm<)PVNW#}Z(SDalZoSdfRn#(SZ z3d0h#medy)8^ga+z)V&h`@mtH>7NW`wq;6}K0R-o-#?{e8TzB-uf&@^7JXjub){7N z4$Z?CiZ@fHYh8au3Mq8sGb3?1eN#lo41vr#A0n!=m1LF_I#=F|a46=-oIP-W!pp6 z+~jjBDgyS)$9mJVLEK;jOPnQC_onE>XPL)n)_I^j?DGstzAF0o;!AUMB~^F=I)JJ) zkscnz;Bbo#LtZ(uo$jET#O}=X`PG{Da!V!NHd9grDVqzNlsRM=`Y}b)kxR@~FYWN) z@C{6zZ_)`vW-FLq3f$U(F7G^duNpD)Q)Mn>`vH$A7&d)o&++Q!JOh z`;K@qjE+`#!|XbiV7}|O+zceAVRS!M$p7xFbT!Hk<^c*1PMCw!$z@NVE0yN}G>V+G z835EgcV<-_F5i?s_|n91*G)gEMid<9wg1r}FO}6QRFfTmT8xUnu=FD?;vKv6b1yLs z*FIL_)q&3Ubz|M`^at5G^(iYeQL>Cbs`Z6?>w7);;zDUZtiyDgr~TRnB-ZGG_-a8r z<}3Gnrc`;+1L;OznPC%L*a7j*fQ!}(fO8WT36GQlrp9oZ2}UK4%}UWYymTA&kJZ5_ zZq#fb2?GX1COQ zV?j}WzLUYq?Fz8p9w)eRSTeO2qhz3l|?K4nEK(1 zHT@1n&f5*(`9r)&D!lRoQ=1~bxLqChn|fSNyt1>1#O!R7&0N0M2td|QMCIrO7`G3u z<(zA8r8~cirut8kG)~wcA;BUo=-6hPycE`nj}Z7oDr{&(#gC8T&*0 z(v&6-?b$v*Hrs21TaJsjqxtjA^dE+|LrjE|2LQrjMWH(HL&*+fl@i=-wRxm+JPEju zsIsNK=G~lsw2Jvm$WM{M2_`^2ooOt(FGMylDpNU9V?>&vDv1Kl$jgZ~Z`_$qY$?YE zBPet&{n1Ne+pBpJ>du-yPixf*!fznnB$bd&wE(X9U` zmKWUa#~5b?FHMZ{{}pk`@>Svi4AzTE?5%Lb``JS_To%)`7?2}3vODLw0`Qv-UU{EP z&?`Z5MUU-IalEH_+BCK>lQp+ZNbCfaR{bm%KxZj?iofB7Y6r_rE7;hYJm@wq-VlsZ z5XsySsa6q_ya8t&=C|agba#Y_I~1W@<4% zA4&}hZrcO6tQmCi=(ByTh%o4WmSlbOFD|^gqcBE&=jLiVGc)a2h2I1qNNGV{$71{> z8f0np^?LZLv#6lX37AHZoq9z=-WpBX<<0l#tEObl38%l(;Hn@QpEVqkhz<^l%Pb~qFHmV~^}hoadp-*Tv}^d1=kiT_~;0M`s*5#aVLy09(tJ`)j0L-6r}eV&y3 zJ^JX9D#j{!6ZFbL_RW4GF0Y9W;7)>Ba8nY2%%UX=09Jw@y+!|83C#Tecs>nkvP=Q? z;pf(qp#XIBo75_00sqxI_^XqR@Gv1ks#FxwV@V4PJ&gs{Cvm_Y}1{;3t3XixezEUbgO zm{gup1f-v8>CIhI^;7$QG3Zf&N}+?j!v^xPj?qZeW;y#FS(WDeQL;Gv{AUc!XKrOi zH>SlUS;*yOVq}c|`iJ`y@#<%M>)_;IH$IxN-sRUZJCj$=_cD~~RnS=|<52&BRCM|pt zJI%22c@VkKKpRh9)=q63!cV>EjSPu)j~-WBVqn37c^i3tn4$U{87rVYe5|;tA6i$I ztWu}&LuVqQyhf?sLpjht|M=H_QlO{|QO2LqQRGuCvYPglz%5{7bK~>Jr=gODhmrtl z4BAKf{k)-8RBvzOq9aED$bx}+Ah->yobC&w1E0-{y;EEX!2xY-D-0b$Fh6&rYb|Nb zVAKid(#PamegOC7qVqlrN}!54PhAKaGn70LKDX39Ixh}cxf5Cak@Cz%Xp~%G77qlJ z@5>83JC0IE*$`zD<%Y^792VwBh#~}P!*c&}>bIh^^X^0i9d(R7()-fQ=OazF#5yQ| zgZ9n#VWC{OAi4YbdgKEnY!sr~+0#@8^L2LbwF>2QjsQwpSi}=> zexe;|vY3U9@mqN*KsbM?Op`Ou`mo^HBj$Ftc(B8y55Z9WJb5g9X|PIZkGGNo=w;1= zxLeC*Z51FGFc^R26pzLMrbj(uCjq}yq+BFvdCa3CvHR2mZ04mHfch=KtJ2dFjFK#> zcWi;t6N{%H$|hW*!9gDW$dFMd zXKh9ZD|&jCk&l-U*!sqj^ZlOeY>-(TFi!T3e-hBdAZm%apFN2O=a4CV?otvXVg_%I+%zc zxs=cT8rSxOY2>+TstUBKjM~X;q3t1$&r^~K`W|7|`L|A^iqzZ+?Pbcu1nPmWe2sGP ztUwpv65m9>R6$>E|IL+!(tK%|p#JXZzy^=2FWpuZ{~Vb8@3bkACGQeaklY7t4(R&) z(JceueDilDu~8)%pn4Q_6W_q&^R~Qj94{rc`h9D%&Gt{7?QE<9qCV+@qYKg)^FcZo zo2tO7=ccPbX#09Lk3Sh9rzfn%1&3?(euErvCw7D*)9i@Z4|S7jKoS+{GD4Cd5Gf8y zIRa4#0O`V=^FwqGx_*>+Thm^DUpG5mc}w(Ymx$QVdoe|vk+t+eSfOQ8Z;`Z0n(|&X z!G1`gDk7Q*5HVhD@1`F8N@{_yqJ+%_?ywdf83Glf3yBJPg*}?@j6GToA)NO;#_T^a zJQsoJN_0{Pug)z(mK-iE6W{biD_{nQm@@!0)_@2kzKQ$gv}JClR4;gIX-Zp)uaERO zKI{|RF0D}GY)W~y!-m1^c{MJJSyHGsy`T^O4 zR+C!*oyAw{`=Y*o3M>Z}2QEJoUL(8tLn#x|MjrjWPxF_~KQP8&dpbH>iV%2%*D%@P zK7!xH1nmhZBSwlR?978@38a4G?gVt*6Gk`z?)7jC3c15Y?Hg7 z^p3H+T-O`L2!JIfaZ@sCYC6nhoZ#MBEj6wXz<(0q!McXdHH`oFZmM{jH>#=5;DI_* zp5`r@@Q2e*biligQL5b{xG}br_c2>-imd+U;%4>7!%1^a$<@Ydt#d9+XbnIBgs?3nV|WG#xOuA?_*xPo6Za;+X(qw%>9vv z+bt>Z&Uor*ar|MiCgH_SEULBTUkf_*FOdHWs>N4)4o;xkhz&c5on^ zs2F2ZR8cBYZ#XrxFz{tIM4xvB5M)>ke1ufQO3+@lVQxlr#qm6k5`76w+0Qs)A|(J4 z$RNu&O;gNu6#iQqqH?~LZx~$!y*4jN|JEcfB+5*sG+pVNQ&!R6buf76QwYK)S;j!p zIYG?8!$(Dn!DZ8@O2LRRayv)5zmj}NvdXRHTYXk>=lg4M zb*t6oBs^TJ$t8pu zQ!-7{mZ(8)88EL6^AQGNdeWnIlHAMV0!C7_cg!(VhN6?>H?!o z`tc#|2~fgWRj;*jzf z03Ya0kjQt;6E570tEKG^(A@o5v#^xi_eD_I>_=@13V=%$$CKY^?KPp{GM9D?aFu@p zZZy@!xOPUI33up-l)GV8DNi@)Rg4?)W38vCrXRdLPRCtOlx@f_`qT_%-+$~7Mjl$U6+$DmHd zc^}P{pG^xFzB?dTL>S|@MzhaA8@n>bIMyvZ>!}OEK8I|5m11Nal5@YFjvn6_wE#U{N8-C-V^RU?C|^sLE%(j?pc-j zhX+&`75axvzC?X!}O zax?GvUfR8$QV0gJtwaU+0TBK@uIG&cCa+wt)A9OHyKi3!bwh8et!LN3Hc@}U@OlLl z@9KDiO??@Vg$XO?6Jh8n`dRvpW%p;uu7K5N0h438b}d6O_loXcn&~ez$FTY>*8fsO z5D+LIO**QPjH^cBVeN~s8FsI&g?qa)riq$qhTon@0%36>@e>XmOO8F}^R5x^EAL593Dh00!3uAnbPp&B~44F_P ztPx0dU-?*BMd<_BpCK>A4I+3%VR4uZDz6Mr2KI9A8eX2fXJ&?ygC6%4FZhm>y1=bS z>Ta^9I0cj&c1m+#So=c^83hilhvqp=Z2l|e}K)626ghkm_&kf4He?BuG_9NOxzkDBfRoQ_O=p$+&e3meY;dlf{ zl`oafu`Q-)i>R=QWC<)WsBuU$ZW-=GX_Fen@`kj1DbXGushaKeQs`XY~%HA_(;{;99@)3?u$byOYPY{%J+Hu{1Zlx3QqCu zOPp_e+`^)0ZQ<9lsT0)i+vJ6LMn(!VRY3qm^}*MR*^>^KOpR`jSz*6Mm423trt3`R zi~f}a6-G83!dlOj`iv?$tEz1gt1kU3jZp(eQ){UYqZo<~ts!b3zMA-|T zdT7$mLy?S*kAyN+{bIo9NF(aiaBK|K(FPrAl^c-f$lOZ+i*~$_zta4@a4eSQXU3xl zPVMjIh7gRL_Q9J4tFfSh<*dI%tpICr;n*39S&{{~FJuDo_Ig-OEBtScRgC;8a9`uX z%EKM1t%I<>bVLLQ_v^?pM`ZzFL`VlRw*w~V0CE$JM+ySGN^);(r~%XTFhLd~YH`6X z&xfaZQy9Vlvc+lQWJ904ZtopuJol#BsaSc|pf_A%v12@#c$o!9sVZAHorqNU(3QQJ=+c*eHM^gdype z+GoxGGf;be&}Rv~RqS^Mb}!;2WMq=g!MfI)*WY%r=vUHFD|?7*;!fJ$o@7q z%XR>jfXsJO5QqYq29SO`W~A+h*7YNtyH-m3$kAurItL~0z-i)`TWKL-pqZ>CB~&ky9vhob&@+x;=E8Va}}h+1pw z8}hCV`;{PoeKD|^K_-Pga7JJBbbX^Q`t>uvV8N1woV!&066wBWk89kP`!tJF?5Iid zuWk=#Z{q+hZo2Ajz1^7ui{+F&jm%Jc6pEiU*fAccK z<|@NQEKzT36dfE6U~aE;2EH{}-n`0M>gNv^yt*=>G(r^zKb~$Y=ug-RcXt?=ERAz# zs>I|31mJD8^fp{ezv(@kPMT2oI(@>LWrIUhqtFDPC7Cz?z6Z5A5kW|JZsOXf?=a|H z-fJ>nL{}S-l^~fOR;j{t37wR4b<{IiMi#8Ormj*lzI_Pc*#fY*NrP`8DmVL8DtM*E z)5D15k|o1HH~Wvh1sDuYo~pMa!l_I|#^AL2%P+AN8-2vbmzKh=3ZLJ8SXnQRbTO%D z%J&euwsBRcyR5him&2Lm+m&rG@^<9I_x?=OR2omdt3@jjFd`cZ`Ei_$Tn^t6l*ndD z!a^*C+N%AA!d3qwO`&qg#h-Mwq{C*}>}ucxq}=a`KRP+!8|<{=8yHQnT@i?dKOUdv zTN~!^eATHwEnJ8V&Qc>S=H@_2b-&~QG)-^Sm54cC`2s@BqQRmAqqQ*YD)BDbROb}T zpuM)fy)V!VXIZv17aB!MIq!UtfTuGH0+%HQ1x8%aE|N?K|NpsjdOEZH*Gbzo|2uR} z3Xqc7ZhD`8U>0XV1r)b+_mP=me`d?`^-ucsa}m%skJ_?jdWp#2R>b+|z?O1)z=ZlX zGzC?O6cD)smID%XiWui#Qv|oQ&JC)dIS0$v=kv=^26W)QQ6W)AKwh6g%>ehp+|p>E?SzqR1{a6{Ms*RuRC| z{B;orUOFl9NAh2{7O~Mptysg)1VZ(oIIaA&fF}L-ViRegvG-33)$-Od&>~=!%h8FQ z5@1IsqAA#2@GTsz(T~Z+85H(|Q8(X{{5DK0J_%9CsXyey z@oJ}SmF4QQO|=iS!i2m4xLsHnbT0b)N7;Sy#Bc)JnYUn>OXc@&l0lb*i)s0iH0NjA z501mR+#)I5&XdxBM2C>C?`Naxj;7d(kGQ;XfB`G)S&a*gJ#ImVWMMl}RLbX2U8;8_L~ z+2%Ee*GImK>eXvC{$BaVj#ipQp)(j>=Z4-=FesO=Xpvsmuf1%#hz2pwW!pr=gr|IYnbPWV<`cYi;xAVf*E|lBu5kf8 zCXJo>lG;QeMPY;92@@dWGht;07PDx)8s{7*bfx@D;rmT@*f8%=EuGgayNVDG4Ebksy@aO3e(QE19cdEwFlZ1aqBDW zu{Ltza^;Lb4V~~`-9=g~AHPVY1E20u!?Umb>QIJ6J$m+X*(uD>ep@aSg# z>d%jgTG)PEBn)9(N7NZP{Bjv(Ye&ac-h;>Ic~WR%-^$@@k{>i7E2H6b;OYHN+X*Vh#RANTy#2Zn2+q>r)mDX|}sB^*Y^_99!;vQ{4T< zVm<mMdbQZW`crTS=jDYAlFCR?K^7)t=K)}H?6LtMUZ3>#f-5E>>4+wmra*qw6olZl@6Fl0ty(2&YgE0FV_{N zTm zP)e5@_e)TFdC-!?O#lp_H0rrekjNfNF;h0MKF2lH61DKDNrtAw0c22It=gu2Og6>R z;))g&Ul}KX9uSPe!<>MvFK@9Hq+3E8>rOJWm;YHGiWYv!VkNT~i!}%$_-ze=bEHG~ z2?YKIIOw44+UCrxbP%w|rKy_%=8<+`R%`6ZX*H%~)-mtO0hEw-z-ZdlBLKXzK*E(@ z7&pl#?bksE9cy=hEg&lPp5NloL0x)zesj^VY=jV&p#q@S4pw0uGwBBbJ3p8%K95TF z_dpHW@YSl!76c|0)31?aNIlYt*>RpiY)yb6*QOQzPdzQBU_2my;D=q8=?w2zZ14 zUDm>j`Vv^J-f-IQW~%VI>8R|@W?SrGQ%@e9b&s*m8#=oiB%Ya%Yf%S)BBe-xyW%b( zwO`?Fn7Dm*wAFB8lzQO*_(F7yo+n+UHO8ldKl^xz!?V+j(ySdR&@Sh3Lh{m`=yFFh*OH54`+uu6)CFvc{f52IdtC zRFhKyW3u-WF8B>n_LG-0)PoOrqJHesA1VsX$`|DJCpQrsCbJ(l7zWWGQ4jhDoIf+z zn-7hnt$>v~U?Xp&UV!TyK{$0-&B#Qrm|J0-~C9OZ@il`7P-QHiB zI?U7Lfavr21P3MuIy(oKZhMJ+1o(zQ5Nn=2i|Ve~3AuTfZV74t5ArS6thjIylg-O1 zfgD$n0mn{+w4CVb9EF2Z;euEfm*$>SQ9USwIb$1lzav%D);24F=ZLgPzowte>d$MuEj zLB4)%Xxz!Pc{1E5bG4Qim7d9&Q+}%?=%$!<@IX@taDL;xL~vu8w7j)cif1&CTCyta z5~nTa;4-?$cQ|}(-=|k?XiJho=H}KfyuZ+PqdK2Xg{y2zb3Fa+D7qDBza+zDH|rKl zU*1b==xDZ8%r=6v@^wbxv)+R`4=U(g9LzI7<1G)fp)nSmM`v=wsc9beTp{%dSSo7X z6J!}>_nb9(uPxSnN6~ZiXST$9BFJAWU}yXIT*RH9z(=FM#EiD&aS6ibD8dkS*+3%C zAfuqrSsoh1B~52|i$m2zzy3;wP~Jge8rCx)VoJ4kgP59=gN6;WFF3eEOgsUt^7FYV z4)z>pgIFgj7=by>OhCCD-Bv40@ig-Izus34VqZlM?)h~TF)$ZJ3!MtlB-@U7%q1fu z)yY3#PL*^-z5n^bX0s>olMtSDOE}YOHj5re*odl--=;0gKaql;7YZ+CoFO7V9joYJ zhB-s2s>B8#GbPbLVq&))q8}tAt^+Hkd`H`a*k;=%*t0tEwc2hR^AskP_3ca?hWn>1 zg$iquS(kVd_3;*JNgewZB||t9;NQtZDcNA}jx_sSa4q_2=w9#$9-(DlW>7&XbIwTt z4Y*0D$~}UzC+h`=*45=~AReELjPFq;SRw}}byt7+tsP1U-{D50lhT1d{;Uo4`&@2+ zegFomw){ZEq5Iq~lrY1=f|`*eJd7+IpBw_3!3%?}tIo#{1d}z&@Ou{!;AE z2nN**0+O27!4T%61BQ^?S|&|tA1o?J)XyKNb{6?AP6-((vxA#8K1vQp0WCH}+fM-( zUQ{6Xde4{PjJj^vAxRB3qnsVNT8R}0QFFZ5^{=ha^mH|6U>0{n6d7Zu)@(Ord)E5d zJ@mN_J`!}lr%YH@@05{5(^vsdLTtlLv$8U-EM&XouEme!%_ERWz7c}TvM!`e(dAax zRW83l_;{OLZcH;~aN1XPr)WxJ90NWkF-!#iT44;bec|llDOT zZNr?{I~!34{Ke1$R>h0{EdMLaE1sTGE3Fn^JQ*5$F3-x{EI*KK%8f{OBOxMO7i0_V``33WFD1 zB=nL~MX(}7yks`7hm`72mf*fhF)B5c{3Rf=nQo2rvAM8$uW5vQ4FvsJCn;^0@uJB_%8B{#>8(aE~`=ymDm-*BnexLv2BN=lgR- z`ETe`D@`!#FYX0|yMd3BnZ-y|8-Jlex-+NZ#{xE0^j$X7(;foUy$<4YT2^^)#xfE- zA1_8w*+h?!+^ALAgAeVkh3hcF!pgJWmO;e$tx;c&!CzZ~J!RMEzpPg7*G%XJSVt#7054@HMaC?CXJn5*G{B?RV!^fBAFj5B>e+n7`GPh_H5`{JA)1{ikbw3h zF>D2!Eb;ZJsp^{z^S~@Bj8ClowGN%BacsNB#TQFW!~9O~EqwbHZdH5b-$TQKT8l^U zZg24uNhf2f2xdrqp~u_fqKXxRnZ>Uyg|b=cUQ!J2CVYkJnex%bLj`Rc3+S~aR+<@VZ|1#oD>&asvXInyF-&fF_e0K-gly(! zS~RWhrJc6BypGm)JNCCtCUvIIUIgTrP)Z3SfHuZ+Wvt7Kb9Cfb`=PML&xYYKpY8<| zNs5fq`*iGD2dewz_#Tifn25KF^*3wQC;gb)FUW6Lar7xdVz8A;yj_vMlny&%)@A6N z(r3yJR^!$>s0A#ep6&HA-?O?MZ;9WZ>I!Ra+!hHlk5)Tk8!{pSW^AD~f9Z~uCVwS! z>epj|&|~hDk1EYHAAgk^?7#GvugVp+SQI{ApgcnpM0D`X=E$r^{msLBhV~)cVg547|{98F6Da zZgdy=Cs)Gw+YD$gPB8o%BH52)HM-?XVz6dgljx`(Dx6rkb7XHbA8 zR=~dBmybSB*JL56M)j7r1bPO2B6aE6kEx~);(g|7Ym2QUyEF)SN{;?gk zZ>!7tp(A5C`Gp?@gHkk4c778|ms_3)7$|YdK_6YA$G2)^3uaN{+h`y;J3$D--wu!E z=ap?4TwB%+snr*NSEWAMJ>1se4hR%IYO7-`(I!|4c*8VG%Ay>ZeudAPh9hvg^@;X^ zi#w`zeMcUvWXLdBXYyFeXSpt5Kk=b;<&KMW=u^)@y>+-A;DDg_91#LCJ~#C06JTIZ zjP791X*U80FjiHm_A_02?!@V*_x*2=cBEkuum?iuiZ#X;_N(IB_2EuWe@`HOnZ6D7 zc-UiJ|0&LwLYXo29RrMDHeH!jVhkk3uw3I{weXcLyOlrnzVfmswjI6e2mnWH~Be zCoM5{?d&Nw2 z_iIMLN`o`kIf;%}XgE>MVHHPWgFzvkWVJ-~( z+P!LlW;%Hwwix|M?6UQl&UVqiSpc`!EtjVo&!}TczPx9>4j@!i4;_vtz0h82(`uP) zl$q>vZp(pY_V7tktB#4dNV?G3(Qm`SNRrrmBF)G;{Zs~@)837QKClIjHUT$0%s8?S zC9#vv$PJa{QEt%0s9>3qW#m!rP+8j-1`NWz&##(ma3}I0co(#pA^$1OE8JF** zGB|I7o#pHnt1U=9-Y|=iDbVHx^@L+VqH3+QGA%0AaY>sguW89sxn#7QQeUrT)XqrA zO&90`Z`H{Gbl84oCT4Put+3H$gWJV!gomSG{M%PpQW6687603-*VJN>l>he$twpr77K@gPH3N|g9 z$Sr10>c?I?@sm0|L}I-aJ>kIh5>IyuyRe6JHw!m&E4#5oVI)+3-z?ScUOV9XrE|AK z?y`(GFU9M;DOhz=0!PFuZ1rs7#}+(G@qrKA#cu=$M|}3zDz(>w@l0c=P^U|@T)L&r z=-tUOe@Sw)Pe{^P(aN??qx6|0>CT!E9#6dqu6frzv;yVQ?9m)WAU%*H@~USr0dX*; z1)t{z39A5*AuwhW0nS*$)Nkn=TEsj9M>$iMYEHVheENGwb-d@(NeKaL0iPFgS}PVd zTe142^NYNG%(Gb?X;uz#%B(1wWU%(Xm%!(BL?yRR+QU6zdYPQ)2%xZ9Ce^uC8$iloWz*;b>ziKPw$oR*uiRbmvR+aN{;ch_EpuMPYJC|r)sgXD zj)@00w=R$J7144U|L+VF*}BMWE*5zd$CS&p-<4*K)kL^50s=#x&Jz7c94ETVlhxlZ zz!-qXO?bSZY28w7{Y+v81ZfG4va=FCnNJJVHxsYV0)&QS&uLfOqtqc$C>p2TH6e3m zx0=Hl!F#J7G{(IN!W-mv2fy8`EJs9y>983pjyLZf@*#+$7$D)Lp^-ugFhV7p(V;3s zM0NRC!640*SP@mVG4M$#g8d#FR{O+E6?FNV{YgeK1m-Kv1Ca;mXe%eNA}t6-*PV7!rUqm1>VRdFOVa zpUvn^UzuI7pdmzjw^lC3o&G84(~ng&x%hLG`AY^m)i_`=zje7<<#>5&62et0I8m1$ zYrb}#X)=-*uVukPg_j6jl}$%ewwwvEImcwN&j<6ln6S<44&nra%ib?~AR6xNu_j1T zfyfydVF;`H%y{bF^U%thK8I2R0M8$Wk>_zLMRaN7-|^uu0QS&us004F=cv z0?CCZ-*K5nGq=BtxP?*}$Wx#oc?Q0|2Q`8Maf<>sDs#g|Pa1Nlc+=X7Q{bj7IP%c$ zl&VD|;&5SrwN0gTl|fI(vFwUI<`|n28olcnKUZyM`~a1K7c~hLa`p1y@Tl)ljNZ2K_^9$3n+Ku!*Q3hINfMejwr(Y1cZo73tEy?{?KvNPl_{0I zri><6aw&s6Kp|gvUXt!9$7Rf<-PZ4$$+d*DtnM#zIgYlR{PWxO-B4O{6khRM6>LZX zt2|avpL_siZj(Dh;{&|h$Idn_x}CsCTXF$||EZ(PV4)YTwDV;c4(AT52=B-bgt{4B zMsVKYjuqm(@@?`o-)HeO%8mj=RC%oVlZv~pbk#t#*n~&T?2Y8u+Yu3s?NV%u1hbfu z*3=gIsT^>={@`cgTDZ`l955_zk3RzW(n2 z04#|%$sCpTk)4U_{=2c5YbrJ^cI)H9#uoC@QB0q=SE`g<-r2%Qmn*#OKVE1 z#BuDT%Cul`t9+jYtIhAgMvm9wa^wVp#6l!Gufl!hgP;|5txQFiw%J|N-8DiVWt(C) zhZkpChFW9JDx5LwMJ9w5#DTnypi4HxJ;h9jJprQ!`%EfhL^<$tdHL`uzZ(l8(;qsa zNnkK)$)2?`mF``DQVtAPl5icqX9VI375QW9E2hIp)(WKr1O%2@7Qb^|O>!MrUu?sL zf?@(*Giso4R22HjDouwP`0%?35Ca;xdA8E_^&=rx!3v#TPP?5c6@8w(Ug5tWecl5V8CYtw=>NOyO)lys-Gba%IO zcXxMpY~Z_%=Q;0tzVp|fafU&zeZ^Y8TJmJ@?}@!Iqp@9Gbq=h&_CXh8(-90o6i@HM z+aXW3en*?{A1LMUvQxZz<5nj#uFKWATNao6CF9!-zAYtC=I=VJ$7`ZfDt?57{$J-M z?98=88}<5CTL@IMBWZVS60?=r)VXdj9?=^zP&;yvHldD;4FkW3@tN)LsD%>!$#?yv zQHE#9i_2XSbB;Bj4&uwQKZh`0tS&s~67NMP#^+gsUpFphn0OuHC|Bjkqfjab$6>eK z6Vr=u2DGawm$F_DD9PkHm!z>1=)aE^(3AfBS>)R{?k1ZKGN5`zr@NxPdd~k5#;A89 zzsyhdt9C5#9x;s5IbTG#t-kfOY7!PVODk6z7rzWTx7`G`GhJrdPt6*}3qz{e@;*rY z;drn|iAihxy(7b!w}hMB8F04xBm8%qftY9DY~_CBBPWi&X(*zD-@NWk*gv^Cs1^wa ziTq%&Aqzj^GmWG^NjpgdFOsydo>ztIX6Z4Qt{Fq#^-G_yW?v$chUi_#D_YyzPR*+W zK^+EDlFY?3Vp%O?ecHfTb6H+h5Jr`M5D<>t>RmL_whB$=Mpxn}iS|dfBNX_Fx!{(s zWE(&$fAn>iHd zp2*rMXzZ?@KNV7r ztb>efYz0t4{nRyBUJc1TU$8CKY_)@8!1X3_Q=(>GCvw&wjs_>sq?}&#_*OaNdc0R< zH1H2_kaD>yA&H%Kl}-_4?j2+a&B7V(An;LsJTfdQR8FRRr&&`zsY?Cyc$&a@6< zRkM*+nJUl34i09mcpxKsDiM!wPyMr0p9T)5=$Z3q%U?i6dBQaZinbI{_8WHQn-BtJfdY{6z%2kJ_cV0-;b>w z8lP_GQXpUaLy!F{8JL)RlS2(fQZ^NF`DWL8Mwi3bJ*7pIQkZ7$)XiBMvPYh?_UMlq zD}9s;O?O`}W^RlYY|X?@`n880{!(G|qNGi2$`%Ka(5Yu58d{sF4u54s>A$8dKV?~+ zY*l&gg(?61B!@zr5t>L3VZl`c)U??ahEvt5JLRW@CvL-hOXMU$VD%R zELm=gJR+^5@6;U*eMRy5s)?fCZoVpm?x z$b9|qcKocRA%IOSHxWgBfR))118X3SH5!Raw!y`W4#`^@URq8LIUJwYyRDvr%A6@t zS2tb9P3B0Xbm;+~zQ8!(;yZD<*`VdoVucp{SdKEe{ZZ}%M+P_*1bEjfQ4Mrgc{_6! z-@D-a;eBSDla=JR62p7SR@%DmligfC{V}TRh%ev$D5Ib7N;)EUcMm`#C%bGZ?_;Ft z2+hf*))7T~`U+Mp+}ET;PWF7Ew|6(T_V?t;Y5;=RP(yHrpGawFT|OO-nw`tY+*R++CTe8*hBo}a6T`uJ{L z#Ml?n?@?DT^R*%Y=x1P6)R#xITc!C^=u|lNw>w@hginz?ZjO`((GI$rJ?+b&msQ3i zC)`Jk0nc=$GR3gR4`zcUZ{s7E$~ZxGsamqT)G-zJd2wDPa%wGxho;QtOZ*lZU!mJP zAA?b5**2Ik#wYt5(Z4F5T8!OE&=Cz3P$O7xOn5w}HPzUFet{b%51tFOfC5;o7pgfp zqB{rH$l8}Uw@bKf>sfORNDZb?E9J%=Q1;`wH8Rrjexx4tkd;U_mg%*IDy^a$2|Qa| zqEyAOd7Oc34h|7AH)pQ2A*VJRNx^yxgDx_z+btUw;wWFG!~@Lqk}#IU`d4ZH{(U@< zGz`c>2S4)`PylB&17Q#|@DGepT4Qe@SKNo*(3@y`s2Du>olvGjDV(9NA* z6S!6L6l+ul1?-lnQK)z=Iv2Zn_0vb_w>(85}qC4j!v7%EQXD{4%9FRyN+o^)Bm zKMBiMMrc@VRvqigAuq0+^u!h#Hyn@o+E}*(wRH+2OG!y>htjDvun@L&cq@{BFj-Ls zLs%~Qa+1hvmDET^!bA)i7^vGAfMoyjfk?084j!As3AB>pFE#rE>C>Z)Utj_*VW##; z=H1V8)RoG{^D3mKsd}VK+dCWe4_pII(|rv%0XhPDj%KX26K-4It0900M-zYdhy4U1 zxSVvOIP^5nyEE@(At>SYxL4d>*#6Fz@Pw>n@h>F?TED#0o60wL;E(DXLYnV~HnoeU zI)ZkTrF^fB#rTA|5w^k*EE)0U8T)TY_p0~=fL(57M!PoL6hUF62B`^0mAq5h_j~B; zf8!ATy?KVg-$*UpWz6#9f+z;^zDQo5&SJs(8Gn;ojMRJ(ZJ!9#v0C+NkALz6`<@po zz6(<~&2K&Tw5?8*=#fIE01_#q+AioSy3NZ#GXR`K|EhDES(8rW7%NE1lj2{(E>z{;fvk-g`I= zJj82o&{%D06FKW?yu}HUA2#D^t4HS~c?6Op7i19hsq8{74So=dRVx_#>mHpUl4d%$ zXJFmwN`}5TpenE!2C+`#0#Aa!2h#P2)0LLDAzMIBr_B?W;$(+9Si2Mn2{im>f^fmJ z55H`MB*XgG(%!^?VgRe+zru`yhyb5Y&1Q2qNCcCQdO>L9pq&81tY72Ma!Qdo%1OY)G~5xk!4YNl zMbQtlfK6U?)bqugDjNrFyq)L;=Yp$d8q41_&f@$a6ON7SO|Sv?IDTy647d2g+{Th# zSN&3IjbxnJ0L3gPHx6da-<`SP!M z;ByB-@9utVv!eHpxF{HXhU^!P%~1oNZ*}9K(nTZSB~R|d<+`Nk$NiBe|68p;A46!b zB}1CEY1x6u1obrGhwIJ>A~X=F?bkDkH~5Xow&i=a-DpapOaS;f*IIOIE+gi=`E;>e zv61x?vn}AtjDdl{+im#kCXZ-kWL^g-c-?l4Sie6>k#^#+5nQ%pU4%$2*u`u111_qg-mOT!XJ2(MXwY%IK(70d?_8ivwDJoeBY0Lza5rH=WyVb zA(}3*M3(qqTQM-L4o>8|EgAyo4(v^xOrU8vmokv5LT4n;`BYsCKLH<^nKiP}5*so~r%6*WA) z#^py6fHS6}RBUwVyFVrQF?Oe{$<_X3oy`ybyVeA7NME?e8^3$V$L_F-$ur`5d&QS^ zX3lTCp*8%J6ja*MgsFe^)O4G_|3z}ju`mA@CX-1uz=J!Zy}(HB&~8U| z(LkCk&wJ>agJ26-n3vIFwTh1`?+s*e6OF-BHr7R_-_I7;RjQ8gaaY__8lb%(p7+GF z*0zpFrZg^_;J*+5Krw>E8Z3vRt2vzhu6&rgH&>FCFI}Nc>v^>5@+z-I2DX$T9f$39 zYjBcmsQnmm{`+wx!8{?oZ8y-lXBnSox}P_lto{`BB69DqV7PKk0@Uqi=WsAvw88J< zxUfvg6c>5iT~G)SMlU@aHv=g^wpiqu^|{Gk*q&G2J&`gsL7CcV8`e$};Iv77CZ0aD zw%P2v#l8mWiyayg5R1?rA`+<(w_(;23FspuOsKveuzsQ6_`yvS>h(40byMvXpVZ9{ z4r}-XfQ*b0UzOrjj4r1Q)jA^FL9E?uUg9ObAAj<={>5_r`)J>SQdtmjig}YO`hGtQ z0N#`Xmf^Rh7bN&w!Ee9Jj0hYW8h`#$K6z&4|BmorULKW30duC-Kz5|nX9R9M>Bzvo zAqS}&J{`U%Cf^zLQz9&Jqw=I#rs#PM|0PGTF(x@a_A@F5nAlm5Su{6zf0}xCJWEJV zwp(U1@4^ou>PrN~WAjqWla_4AYhRJVr)Kco`J0_#@DFnLKx|_QdgMMI(w7X+PBLuf zZ@Jg0XKO1OKUW@?;EJ_cFuCe15%mukLyK*X%n59_$~$C)T+h4E99)Adf!QlR4Ub)e zi3qJqJ&)L}*7Phd@rh_zUO>iX(jx)K@goojGe%4X98<9L}O5s~dI7%Fq z24c8-xqqhL(L;J~o!d!Ug4LJT&Z|mWr!9mhr$y3TL64qDdDhQ2gslytaU*>RK-gcd zSi-;U9EbRu>6$Yq>GjYwf(Vpu7eTyh-Kp=ZHZ#*FWz?Ia)i;wn zpA~_+;uR!Npds38iI^Au#X>Q)No$hbJI@bad^~QHXf)n@rgGTE8{6%&^x#&)O|NqN z4@nnfy3MU4-zAH0w=bB$+LH%n$YCRbAvR~U)z{s4|J+m?s(}@@YO*lqf^{9OcH10= zF{){OnD+L|LM`*r(Q&;CSbZVM;Et2X)8H=Q)oWl34je?nDXz#+GC4(J6Q=77UePSL zkc4QU=M9_n;YX(lZA3NhkpNN3_j`(OE1D?^_=lfz7S#7czBqhUeK~LC0ils z`RVLknXmEFzcp7Z{lEJd%EKNBL9>rYu#wAQO}dXRN`gntkS)EzMa2l`++7lop;b5^ zYZcgb;wZm_xJ>RIE-M3%fBDN5FQINg=4%6pz^oYJ4oiQ^LgOK(CQXaxa*IvJFwOzA zs+UB6+7<-_FZ#d#b4d9*_xlk-%g%Lq{ZUhYGDSB+GxSS7)XfnTuO$yMVw&qhwvTVw zI~+}c98e975H~u(C?-)&=Iyh}E_>1=s7x(#l-ufMVkG+MEIo6gfnYvm-F+VeK_eQX z*)}(}LXBH}{YZcf-<;v$vpr1XxNF!y7Ok^8OxqCJZF7J2nUCLYY!LM^f-iW`$p5d&;WSl_-uI zv(OYqsrW)ojizlbEHyym{4N$Xm{zMT0;kR(#QK;WS%NY=R8Ty$Jz~}AS5Q{v*ziTt z8F^4&G)qylapmDH&tjo4UPTpM1evDAml_cZO94&{OUQ@K0spGA+op_-0J4ry#@E6X zgv7M0H>Um@-I9dhkTa*&ganl4i>GwoG>ibRoZ z^?V8jwaNTSpi4)>!148HVx?X|_r&D|V$t=T|@S6O9 ztS$rhZ$t16*E=>mecQ2G11*SX;p#(4%wiipj*p&qWz6I8H&UMel>R&zUbMOYb#$UGTNy;Oagt*0gJxJu8@$NxhO)(8jUnY2ntXaT>JV! z**KL-I5q)SXSdA`_Rf=fzW&$G>;nPD0w`bc#>~DCJ>JuEzf}k;nI)oJmMs_lYiqF_ zF)p?N1b1GB&M!#p$H&BhqSBb&>zm)94dQhid*HDG0H`ix>i}jmH?%tg>CLp_`Wp;^ z?OT(}a=S_Cn(JUe5#xCqdz`uxlN^d%@C#CgnDCX{??S^)V9mS_zWH-#fCJ%s`!YVc zN;S?P3OAYMUvX=BfC>ub!J!aP!hUYErkQv9f1QnXKcF<}aYPX`C^yjq{1?Q^v}vF+ z>0x2s)N9xPK(-{{XuRqe`dkt5#j#)~80e;>;`x^q7PUM zq6DW?t@-p$S%2Zg4{9FB1ks?BfEz zks|d9cBF0S@>SWg`p5-NQAl_Z7n3u0L``K%Tk&!J0&G#kD!ZzGevS z&YVCs?~pHH0acBMaNHFk1tw)D6kZFLTTpR>8*}#nTvHUavSm~Xnu>j)4e>+B){)z{ z`$Aj+NtD<6bNO2Ix<~pzFh#TT&Y>Od8`oN-`8W)2?7H@&w_bM1WCML5=W8l>04O5b zKK(ZKzRYDKG^5V|c=I`sK;z2jskuMpm?HqP3r&%t?6tRFmyG*XPIh(~g_%Yo@vPE# zhPdv(i^l*`j?+`AHm{V1JUH>8YujU1X;T&a2DMKE6^<%|ZL{z)ME@TWV&ePFtDY@W zlV|H@LSFzSA+3C%^x=`of?Kk!Mf0L1^t9=jpwZi5aW>O4>w)M8B}~iWt-!Z*ngO4s z=fcm_WBIDYF0%ENpMO1Z!nKzmstW75bSIS*jhEZJafxa(CHh7WF;MK!BrL0t#_b8Q z6R=^Z*T9g>$eLJZPixvZ9T{?Vz9|Zbci$aVyLVTcthQxqH)YUI`AA4d742=Tqn`|wix!9pI#+$^vUWWP6^ktfE}-6Vf5tMekINbwgy`8GI=Znd=10XJvSI}71#Q4#IpuT@l5yAvGKLif2NsXm%-Tw$L2 znDpL7C=v=YdZ{1Q1CP*ny|qX)?O2Nz+fX8(#!5;lpq@sOf<^=qsQvhp2--6}D)ZB6 zuI=%|aJj3ibF@N!OG?Q&r9+@%K8be|AHYF{{=&$ zNt&DovXCD291^fhB1yg!=-*Oo_9r%U8e{`#>8M) zWu|z%6-YNA3x9a+<_IS5dw|1zjegxVKt)a`DIw8OA=JcRYHTGCfTRc(ObZ0-Bv;Pw zn7dG^XJfLS@_NIdQ4fNgo%tZ%JXUx5x;eeYs*=ynXIHQNB90XXr84k%b2w`?SHFwQ z>+#@|BuzSA;(xXG8sOM~L)N1lsDnm6vfA;~JHBKD#dbck0_S2!9)s|q%J@eKc7r1S z7V&(4+!4H5&2gxKS>2B-LsgP+_~FAfL$Qpp2sIvr;#F6%yJmDMRK{f1;;v9}K1#7~ z93e_S-K@^PV>m!Y{_5=A+%2#JS#0|=bUtjXX`b^iZLHg@Y9pC|N?-n=bO3QePV3jP z@=KP4>36k4b^L9PP2Mo8Z?~l zFk`vJy{z6N(H_v+nu99IaG~SJ@=ssI@lmoR|6-1j5zTAuQ4*+V8@iigRT@^@&9`3=6DU-1 zd&`{d+FtCS7#$!HYdM^I$B%J?D62BaN6YgGCVPr3r+9vYI~<@=@-{LLalx3cpF!DS z^Ik)O37V^WJJ%BNZz;Ng~L zrKgJ$*}6;<_xOmHHUsI7V3e5q=c8a{fjGwgLmp1`&ur7m9pMBI4%sALAv<*fc)c^x z_Dq@4j7SE6T*|dmTWjT`5=XZg;$`k=Z_o4#Os$GvFqzCU46UHz-d3 z5Y&#IWt_V`9ozM+#|ZlD(TL1baYG=ZufrCt5kPuRg-H4He@{Iv2ydUY(z4lj5OJ4& zfFwWsYOKiPf*;CiRE;c~iE_E#mGkKSXlbD?OYdcAQTrdb;(r`7sMjF^?a@TkiI+kE z_=LG}*mEp8o)N_kA)%`avB2tphQzh=-0)7r4Zi)%dwI=6rB>|M!=uG7n5#W5u_*`R zGl%NiXb`UsnvjUpnm7ef&I?B3CqwzP_~M07R=nuJ@U~Td-YF2HE>6_^cl~%WxZ(((`z~07BmxeH?bpM*#t^-)?*BoW zR{MYDvmeT%8ItPRQIVs-b4Ij}M=S;x94?T)4}pBtP9M1gl4=h3k7~8*;=hDiPG=4~ zsXULu%W@e&KoR4nwK*c(Ut*x{_ro4Q(Y~1Tz8cLf*`mrk1jysHFN{rMxg%b7*MK4- zQ`D%s<3{M&`I_vtKkSZ3f>NnSmE`w7#c#Pi@>uEmCuH>iQbkTO~H+=SnepP&5cl%f4D+afs9C< z+QiQ;4|>x?)hChMZ6&xM^TnT^@->SZ)ivs=P^1z{w1N#wl3=c5k%;-Dg1Vf){7zMv zc;~$sf=)7i4NAs@tw6?7){3{fod3%@paqi6PTw2 z(fIUpyfkG}kOw!?lwrPYU(TX@UbYEUZm^^F3yF_`q?KD*v%cV>p|tc= zW07?ufuUbmc;;rRTa8H30HW_!NJQsi2tR12H<-w8DMYk%$wip4+h@ZG zDyE3IG_eQ}p31sM_Y8`1yZ5)CTV1~UD`cItY-CK^)&CP?;av^lXZ9=wI%^y;96rhG zufVoe0E9;j2o=W{TFqSHIc7fv_mku_hTY)pR;Vc?g zPHO5*Y2wJcwAUfbx`kIil4Bfd3#b^|uF|{DOtZK;AVMY<+H(lmFp$Zsl`V^;UfJYp zM|8FZKzeKsUFMCht5yYx6wN8(a+{4xb6No7@5<+*N7V! z>;?7Gw9@?bH-R$_sb_S5_p%CWcYe}&Xph1mg5el^U45>B1h=^bsBm>w{2~1_B}4Rm zphJ`x-H+&L5^KI#x5~;R6fac^8hE-7tpUWzmzy*lBq`~~bYu_*(g!f#dy4CYf3(Pj&4$y`f_w@GsMgofR%%}|= z$H~8(Zxqm9XH`33DcIY_D~~J6K+c1wPKn~2S-Lct6zYw>OFa7b31pkW>F(l1U!__P_8a+8_9{j?##_mBd5v4?jck zd>ju$t74BqQ}{mQ}Umt5>ySdZm7)S-AP% z42+A#LK7U3I6D$G=b~cZ1h~d6gQk0FKYFLOqyq4N;`N}p`Evbd#3%YAH>pIjG#rLM zg?56(NZYYi zucRTHcNV9d9KKcQnK&Gai~KDb|0iGlt(y=L5sdhnFoI-R8TbyzYCeD3>W>qO=A{fm z`U0?GArCZ4VmkYmyE1!I19)sg5Wpm-g>szXueHiiRjj`;aoYfxxVzygAO6ohrxP5! z5FyP6rhD?`VpNC9biY#e`$Ieja8kA(>{)0bfZ|+tSI5i!A%&#ByvPo#zA-i~J9$Ck z!Wh>;V!QY3q?EJC>+Xm}$sA$r+L%|AT%8k5v#a@6>t^LB0xMe&eNHx(_eyGu^}Ubz zuOyR#5c!KiP+N@FMHVXE_v_@GdkYZ;8c)h21Cs1Meyu>$%bv^FxuyR5$_!n~( z<;`P0{9*VbWf2j3Mo9s73SoKE$itd}1*!Yx1S_SfDjgVdo#RN6QWwj65=HwLPvWN{ zv<865u4b3uBh`|zY*RY@VWP0|NQsl2LrVy7=}#v&o7nMxp4`ulS^(tTg|Pe{`etw; zVVmt71_JK~>1BfMwpI~jN%%6S?nyLkLt6o zrY(Tc*6#dI36+}bKPHNCz6OFi^=*=pi|MqfMkj+vLjr9LC$t6D19S z9Z;Xu+I*}=11Uo@1pBX`Qn&$C#z#@fgM8;G_q{oF@I&MjJzDHXzL3swrpoR%%TFm^ zCdFA?BRJV+j^MNJaUI$*DK7s(jwM`wHHFy5{TIn$xKnRL5suN9jqfHA)Jf7~KM5~4 zp!oo)<1mhc3mgPmo><;p-9Hgm+T5t8jyYVBrcI~N2O1e~NV{;p*B)^MabDv<4+GMO z$7Z_DoTMFpJOf}D91nu|vYSMC9<3e}z&C?|hOCi1$##DG@YZJ2k;Ez=PgIbyJ4%+~ z&s0o)s6CPPvGXd+K}I-WQIL^Q%75Lmk$AdBOe__QupA}-&w3ikd#-NOdjCeCRrC>A zaa~`H4b83YsIAS>1A{rKm~zK=8=q7oBDcglh8SHkpBOnGRyxCQ}X<}Xg~4Z+;< z`DSzVuV>6PKE*m100N1|#_6t|H_3j60H}~|B-Qop=M%7>Lpg~gjP>a&ZO0i|NdI#t znR%wC;@Wmtu^()4;8m&qV6D@l88RAW)wk&9G>CQSeeikvhYU#F7g#UfEPy)1dd!u3 zL;CG#autDS*Iw>&g}sW~`V4PZn;T*OrJVnf?BvfMB+H?N`lf*8O>y~_l-PptBDe8s z@0pmnY*tPqPXC8YJ7sww8IZ8x`{}Um>=={5A4!1%3&GnAiTs@AB#p#3l)f*}H}+4v zK~Dxjr^WYOYfg4WfAFB?%ly~dq#`B2xt~H>abIrU>5EZUP>5UC5d1ra;Qv+%VZDCc zEq|7?R3@4VldrEO7fiKJK@bTfH-ExW)?1(>Ms+bQ<qg|HhkfBM-K71 zFQzxixFZp^czzeq25e4?SNp07k$2E)@OOm&N4MtswU7M(aE5gOVpo*qvz+z-3eAZ# z|24KUt)Goq&eFEym2i7=Ic(X&%t#zr3SYv%br&L}UIoP1u?Wcj2(<0m<)q>?;l2Nz zUh(Hn^-BmIXS69>(c6uBwUVaSfP7YbXw1B*|JQIPDf)X4DyVPajN1ZwyqX|Q*P+(c z78EGwwaz-Tqlq^SB^QSVzOjEORp7aM@15~zgouUGSwW(@DD)G?FzR?IYn&*_%d{9Jpn=RJz6BI0Z`=v#ctrxkE*k%wBpKw(&X$gqa-&T z2R&G1zE*z?S#tYACgCbw7*n9B>r>WY$1L{-+@@>(0Q!;BUU<)9K!PeF5|vcA;L=`e zOj>Y&B~AC+X2ELN3sl=d}9*2w{BC@PDdwlJpt+;rE%c9+xvVWryhQ8n2)e|F#*WfKVg`%~-22m&$ zDRpOtDW5T(@Dxj;3MZ4%Mu+~%!T7&7VEi|J{xcy+KkjII>iH@I0cF}~{WNtBlKq(I z55F(VY7pE0W2d!LdX>tyY_sz-Fz6-$Z7ZusM(9yG3FG}+kiQfbms=~d-Gwo@&XOa2 zG?kprhj;_En!?N+a)s2rYozn}?utV^+C+Jm(b|EMTAZyWPIq%vXLj7oz3$WU@w%!S zAD;QvY61zsPYQ5$Vx|6eJcpC zg{aU=#hwEfI5;laad!9o7RmY+@|2&{jEy~(addAz7>a?2fEcoJDtFlGT(V5# z5X*_j0L?^3qe_?^y0o@$q7E_wyt-iP>cc4|3dw%JN`GM*oW2S0);%>)UX;V)qVFMs z(pT2a`=s5)AF_qyl{9`(=%|K5*#LG7)Z-rD1`*(7eX!TLIoj(O28B zjWt$XqU_^a<6c}XvTZsjve*BxBLW--N5&qh6vEi+e)ENLWG1pF5@u+a2!R#%B$?{v zHaA#H$N@5oqUrn+w$~zi6uySiw#iPXHpxyoBzv(`2`E(>DsCzBS9am*;SIqGtbLazX`oiKOiGbDe&(aXUy}rNWU}E!3vuwXpm7oj88PDE3EF!Ku z#c9PSj3~2ids~_566U$YlKemTcQiz89LM<{jeo*8W3c6ixr9$(9Kc~p$jD-`qHuL& zH79;@OMH?Q*W^5T2R67I1BTzWB50*wVlFXpB>A-FH6a`^U}B7@BZ3Xa)l^V1T;!I@ z2laQ5gS!5d7Qc6wJPK#c~rrem~-+Rpp@e9G@d~f@c{z&ZG&g4;n zaPx^C6@XsUif+{f{5f}L=de_BXri00Xko`(^MAs7{}*x#MEN3V|Gm|@4;1)GAEV`_ znVQomgD8sPKeY?`$9Of~;C@55Xzje^iIKV2!O51<{D79~Ir=epqsK78v~+IQL-nxg z!S31KeDw;UOunEJ_BY}+`uKp``z@_MrqB!Af`rF;D`$3iI9ry#sp~tJnBe~8*KbE} zza?DLNTL8*yJ^{FcLF&^em5;C^!xkN%WnjX-Z_nuuCM^I!o4XeFCU!YUCft$5pMS& zc?_$|@Bh5in@+l~(cPSGI<{deQJ}Z$E*E{!_QstenA;tW#qg7au@+1oWU(bY1VEr3yY6n$OMK)1j zE1bl>`#5=168oPl02R%IS#W6A*jR0S?Nml2v%;OpdH`d!+6*dz*~l+8t1T7j?16)H0OFA`%C)f! zxB-I3hkP3LHp|E6vcml1A6X&oQRD&d-lERcA$dJAnVXCor-P4t!Pf#oVeyBDx75;7 zzj{Z5%4y|ZPY<%p%sN!f8f|_2-_O0sXsmE7%izq$?*v>G$CG(zK+PiTCvlVNa^2=bZ(dbRW_oYT7T)K~3E+5`SOnIg9kLQx^;ES&Iz=a=?u>hG(|B0Jx zPlR&c=wSzX!0peCb5p*`HI~uCha{QwlA@!cYry!$72`5^%f95ra+D9GZlK_Q9Pa=8 zNJN5o{R;sJk?8Sr_F&1;d}W4N^4Go?>Hu2B!d*mqG^FjDVeM)YIr;X)RNGS=L~kI- zPiG?^zuc(TOHiYiwxz;&{v808+ZjoB@lnT++pz&mU*ky{5uOX-#rPX$+adxw-M&ER zM8M0|3Vv|l#-6I~eRQ(AXI$KB25fNpBPpt52}baztKPCgF&L_ViYa(tWO{qre%hzK z$uDBgWez``m)vArqEwfBs48Y>m_=ig*9zP)iWe_pU-oWM&i}r-^#z~^TLbrJ_%={{ z`gU#l(mqkwi8r$r+v-m)Q}~*wU-5*sYN!RCB!L(>+!yfQ!lEJd*Pum5N7Luayid72 zM=yA)x_`x;T#Kw9D%Jr-deOyu`eemBiRJB|3bCu1g`1hi7sUq3v-GF{OtiqCJJ1Dd z7bN_*s=TrlmnCEdQ_|jvp0RQta&}atY^N6gAo`Zi@aGVGMWhE(3M4Vy6#>N(=D0z` zDiyc03l2~SXH|sgkhdQ;;unr$LY3QC-5pyC`>hJOn{#JsiEIw;(oq=5!>}5dYg?#c z=M+o+8VH_wVd|mwIhmM)`U7jV9?^gQ3u^^eH1$Q^xYizq{Z?q4cx+Td-+9ixijq<$ z1eAn43&99)ZEYPpR$`j`a{*_a@HFEFhl<9y;8xf?KzaA{&xJRF zrMO91{FshTCab}q2VJDLKLABml%4X{P-${Kd3RdQUSe>d?XDpvC$o6CPZXDo- z;4{QMgUOWs(PESok*;i;$`xHVv)7KGxyp}b^hTT8cT+YPF_ha6Q4vJrLnRH(fdHAJ zyA)gDem{K3c2+#^r*`W;nt)Yc05GGbvpf+;e8DzCF>MiZw{(vmb7MpKH}ag=aVle8 zXr$v!M-(ZJVMI?NqAejYb=c_%py;wRiD=2t&uz+_Gb=1q)jW%p7IK+kFg}F>l=(iZ z2(};pJAMN2Jc}RC`R-}8=rRL^Mt1R5Q@pTnkXve?%c1^JKNytp*w! zkbVk{^IrbK^nXAWdI$&_DwvRPqJP*5a}?QIYQQZq;=7y8EI&@E`HqZXgw1-|o+ zFz%3^NXYw}8>pX$%xEiC^`I!M*MxTHnCWu31-%4h7>tcg3lKz>f1WaXS?v8BsT7mE zRfcdXx|T=CW5Y!9B@&+p1*%t~KV&3ytRwK##g)cvYvS#$ss4J8&jl(j>ML{*zqE=@ z)Yno-(L!K!V%<+OMhNoJ)sB|l@qUO;9Dj?v-D;Clv}PGFRGzK>cu7OnFY-p<9ym|0 z)QzS2t$7^vkp3bE$}rh+v|rCSmW|#rj}0>OhQIt%2ZN8i(h9Fo;s&q zts<*nSJGqUN3E2ZDB|JL-Jg|LuD^opGHyJpxq2%Y@w^PWNfY7ij?@$aG3ueF6g6oB z_#%2WUirNY?W8>%{D)s|qxp>Z90hfmavikN zkGqaQ*Oeuci-iaA4bR@|`_lA4`p%Ui>K8TI)8IB_BvO|*jBkYh)D)Vu1z-P4N&U_| zauX)6SIK(paB7{-cxRo={Y_cn?wf&{!u(ZS?@JlVM)^(k5kGD~^t5ch$P<~T-ec6l zjfw&)Ivz-ZO0n-F3tp1A>@Yni06LYtXTz~SHCH#cFdMEj$nKX`7e*1GO~@mCp%Jm8 z#fFg##hs}1q#m#Lnr|dE?g=~I-oGxIH9lHUxYGm@*x8l9bv|mhsG>D4_Af|1AF#-U zWps`a(&i&z;;8yQpZlSUm`CNoYjA0gq*sAflL3$Y-m1&DF?^icbcCDf!@BQFt)yCI zpp>qv`mNo3#8Xcs|HaUParD7ziKC zwMBe~6VkTMn-z;P`Qp|o_lyX)&FNquG5`w=%nVEF$1_x({M>w#mnjSZ=mGr@(pNfL zRnP!MYRT*~q_{BZ_jAY7oIH2( zBjIt7#!FJo;)3${H>6WC5Vgjac=0d9 zkLQJRGu=NU%Nf4NrcHpunksNNm2i<6a##!gJL--f3KRcz_i(RVvD;L^H;Eh4oP0y$ z-C>sPAvd(p7q6XZ~35Hv%C9^#%eF>pf06Ml_%?`m51^Fp?3_m&nk zfbm&HtXZD}EKLs+>B%16=00;nkcXdO?B_qG#8ZFR8^>-nlI{!9ZZ!97FDW%=_?my` zwWB14*yv+`z?MmEop^vv@r*3($FOp{5LZ0Y&uwq10Bq{TUP zb}R9zqNx?cm?<&h5u+9irz}+mH6jg7XGZl{KGMAVO9hLM}j`rKMvHt!PWCjdN@hUId6C$+xtiw zCkpiP7s=&LcI+rOME&g}6<6^Oi1MmW#$ej){3?K$>%L@IAUCMZ z_9ib_8gPy_MVt!9752YJWdLMt9qL3;i6Qtvst41KjOeXr(rygqOl&ssUls7cjMU$} z;A=bMiBGxVhI?7CxGrR|r{*e`9DT7Q#5p;DN8G`k*_z4HCePn!Gt=97dM{w;hds)s z+kcuB&`=^4#hS}+7P1UK1WeT=r{n=$kZS~x)7T9t9Pf6#M($zF;!Dt^SWLz- z2icxK#j5Tc^;cmo7$p+uA<2hpaegQ24u+~+R=d>(yvcyjoAde(9!NObHMk}IsJ%;e zjv41+Re37YeYM{Co_SsDQw4*KPa@Ldq1zN7P7JX@!aChJTj>FRL+odC zUAMWiSaK$K`qpzLh%HsL>w10!8cJoA5uTgqP58wJ*VDefO04C%Y}WTL=FwxwZ2EYq z3Weok=eZH z=KiHc2P>)8JhK8%@l{0Dsdc)jkqgDbG$vHCAiV2vnW2Q3*j+As-`Sb9LVo0s{{P3; zTSry3weiA=Af?hJ-JQ}cuu18XMnXEIyBnk%Y3c6nE&=K8?r!+jM$dWAz2E(l!5D1T z+RuERU(GpPa4yjIF8ks~_A5o~c8S3@5Q7C|NF4!H%NP*Q)4eC@*7-$+5m-DcN(7t( z_K_47n9ckj|J^O#x{m|{;}+l%E)sb^m_iF*U!CX6U8jJNPlDA;AP(#XDMh)S5xWoC zky{o_IZmh0y*VL<)?O+e^7@=m8W|n!15TVLZv2)C)=P??5qsF}?g!4}(6wB8=U{nM zJd&C{*!xYM!KvLwa)Lyee_5klWS@IKOgc3R^=D!Qa2nzAuAEYZ7uNXxNptA-bWJH` z1jZ{a&YWrD#9=W;AF9{L$b4T0UhdSVGgg zZ-rtl`JpK>$;u+=gp6#r>UAdDB*A+$3Dl2BACZI-p&-1z6G^rtR4fqfss($(Gd%RhbzAnhrxk; zljjD9vlOP$^JBW9fk}>>`7iRWDG8*i4CmnUcJ{;H~iHYl63??ryHqoM9>F( zstJ0}*^>$sY(Bo}>yrw%CKGit%D7O%%O3(ixJKNWP=40377NtZccIiqJHtxYs9>8 zk~jEJ>!4UxCMq;yV`FHtWb?gdB(`6C;JA0ZN5M|7WKNN88}4w(htHJ!>JV>1#;PEi z)3ZKyB^foQ!zZOU?)o z!J`ZFX^DQtks~}|WYl*>E|n>k99czMC>>6efs-Z>NyjS(U_}kwts+TLHs0tixtamT6osAru0h;bKZ#mS4YZXvU3I&hAIme3 zwY=XwEBUfV=F1*yFpg1pyp^KmdQV??eMnwq(#3RLdq0=jq7-P8Q8`c_?rVUjMsb^5 zP$}C?r#DKL^3-G9FYlxe*-tI;*(ZlWVM?KYb!89zHQ%L(*pF5OttSuq8Rv$wz_2SN z3(Y(-nqsYzW?za%H(sTODFm%_1NxJ#SDREqE2fj?8pI(3H)YvE0;rNU%yGCn5F2}+ za`)#)amQ{KQCN(dcQx}&3E^7wE-pXxHrl*O=Bn;^Q=Jxsj6?v@E!m2QAmkW!^DD~* zTD}bU6O2@eXQBZa2?#OBFNyde17098utGe|CBxw1f}~FE?1k3DUvOl9H8~@l>)UTA z;Wf8;!cVwjzV=#U6!e~v!pN(-aJ`;k8gw#sJ8)d^-kS{CJhw|pV zIF}Vg0`qzO)`*IFFRf|sCyFgu83$%mU8y?dpfZyd9h7ir;d%eN2b_ylI^bwys7!Iv zKm#izdn$=uY@X@2a*+%_rQM zXGPJZl1?yr?`p0)YHr)%bpfG*#w`F=mVN7EdP?tb14+<*5ZwMHif6RMgh5|<74rEY`~WgD+|do3VZn!gA5JSn>6_$@ z;N%=;Z0c*{3Qrbp$NE;t|gG3M8_6a}@uu3~%N;vTkij(izXM_-!_t5ZEuAJGrGZhun=R%c;c zLGpB)KYpb?uTC;#RY9*~^TZgr@fJ-KL`y^%WG;Z(tjo7lr$sZA!Uk{Qej5v1W!Og$ zZcmE>yQK>$;ZC-F{Eg+1!&*O%shEW5LhgqpC-FVV=8NpBBx*CBI*7QS47rGr)*fXw`?POeN zwbL=#HfQ-~s<$~pd1HWLJk7;upv1G@G&?0l1RT%bB%cYW$q9>#8b zM^}m3r71d^Gi3p@52EkXkS~Mts$Iw8M~!jwUjnF)D&>^77@t2Ih6*S>oyj@2P!I)0 z`dpi|y}cadGK-U8FQ2kGx7ndJ&n2uuyX$dKF65@9ge4>-qypuP!I#?k>wN4qtd8#w zrp?a~f(-CDL1q|#CA+wG;Ji9>NOVB77NBsE^2cv2@6k{0b9Jxx)e5Is=nmq@bgz4&piZ9<|Y zflQ=?{X8@ralyxTo~VT0BKxZm4HOBlUjk^_CG}5h*$wkZ?;e)J+cj}1mV6MI_Fm51 zY4DX0h8*@P`ffbVm{(7+)Ce=*_zgbFU-GMfwj(@LRr*=i=`iD${9Qj>+Y+{DMBkdS z^CW4;jg>yzB$Uu0m4M$1nOt^wv+qnyOjzjp-ymmDh%rAut_fa(lH;j2D8sLoZYSE#o&NIE>6*Nx~E)OZ)RU6Dhl)Paf_qUw>+7 zFF9_tcEz(yuvl8zdR@6LZnKq^C=F9v#4UXt<{A4&w}F#CV=c{gWxii$V1IrrCq!kj zS^Qq(tj;%2v_B~300Sf4k`a#77Gh7SxCgq#Jy&z27l+Q}b5Dk4r5X97%cP6|>fvRj z3PO2Vfm7Qn$h*S!%*o~cP^WKO&KAk?W&gc_X7?Jr zriX^}0i+)JTG;9hR0V0~H;TEHmW?Hcs}G;tEMvR?J*kj3d*}Slbz?5UpSt%$ipYmR)VzNtx0arQ7J7(=#xmGKVoE5oIW8j><#!qFMr|!1@@RnU{FWPt?3(F<<#E0!G*NX{S5frMXwP_!;dHj39hSJ&r!$L0Ixiw)X^?7m@ zm7@-MNz)b8CJ&2pp=dAA1xOOfD6hRiAj*Q;K&k3b%-<%eQI$q?-!01)WrY&Kh@4dapW-9Le2cd+=%YBsVp1J3@zcyk2=-HF%sJ>I* zzqk2T?RZmS7dX%!5d;;bM4oVy^NmcoOyx~jbx-DDfslk>X*WnD;7!m8zjDs1&h;^pV-sn|g0Y(= z0SDX!OHBFg(O>MA+zJ3!ZcIv^>{aFCCI5SSP5$r}OLZmH*N@mors7mev|6NCXaQQl zVS8^H8_sdva$}jnNR~iOb8u=yle*b&FofpVP$2Pl^+QYB)RJ=7PfGWsQ@^|GbF_;n zk&vC=6S7@wW>Tz&pG(M&BNCN!)#xqah9!?3A@TrRK*{v`M*YVisGs}oNve-!sw{XN zs|HxHpAc0aDDSg#+S*Y3z^!t|q*)-PB7_j)UxNIJ7eME-^S1GR*Ew?Nguc1m%cb!4 z1p5n{EMo`n!)qdAwL;Yh4meqMiC@uR%=o-`iL^B#9TZTXLE+a?5@HnvF>&A*+y1R7 zf(G9RYh;x4x#8f#{B-trmQT*uogd+7RBPJjhTnkZSYtUQ&qXhyHm!g5GSj(lHS4Jl zQu|fKkg5qSBCwiuW*RdW$HZE*gsEC>$k8#;|6FOmVg4b_)d5KyH&gsGd1a(4f_8rU zSH`EepprD1@9;G5iP|$ipWKegMMXG~!R~DRD!ru{?JA?5uXog54o9kOvFEE!8!AuF z&uxr=EY_kImYRf8r@e%$a^* zoNDAl!0Q6!MY0*!=Fe+;sm+tMh+Iy0=J&3T5|OqvZg=<&t12g;b~$)qO?~(Ze0Qf5 zz2wH_$sx7t)3uUTUsAc9D`Kvdor65NLa_j=O=Pt~Goy5!rFay{VAsj}ORe*Rk`~Yx zD_;timA6_R9Y;l<0X&BplRZ$-@R@T&mw`JOBB}V>2ctlDJ3WIm-PAAxGb_TlEkNqEFn8s;^lewu+$-X>0YPx5c%+lvkmTVpD6x$!qfp3h;15VUH+-Rt}=?^=i#b10%am*yCO!Zm&dz#K+zahqaEWFS@$K z#_b@&l9uDw@Aeh7p7I+BD9L4Q1_?=pR*0fEOj?vR>26iKSier!8)3&b-p3kp46h@} zI_O2$=Ydz1U6v1p`u4-1g!Ghc(P)p{8QcZ6+vSGAar^4lp21W~6k-;-@4olg40MFN zC3=yXiuOu;*hqJNk<=baC3=R!)O_3B0K$qLh{c5`nL#J*T8gaPS-=li2$&%r#Rx)s zoacim2*h8fENm-$bep+$c0zQjT#z$z3De*FAy>e1O7lhjFBF^u6?4oWy(A(4P9P>m zDEk)lmWkw(LU|pGZ?J3#N6b=j`|eOs^7d{qdP!vzHN0(Gy2>~%scJcF+keUuTG5ko5fk#C6(?Fi!pbtArT^|m zF$_AXh>yF)Ni~sof4opH}X6!W-y;lMR^<%h{;y@9d-Rd>BPC5_f_-VUeH^< zUR4TLPDZS;o}pYVUrRh2cLG+BNMNiOEoKC<&yh^h} z0n~Sb^2{%Q7tpAYxUs%ncTnqe##Bga#=xZaj)qp0f0~BP>pdyZmVEiee1B=- zuN4yF{|T~$fE%aR(X)vH1E<%?6^G7(GOg$6rS;ji^1GZjHJK;O`R}{!Eqxydsv`zs4;q zYtWRx!@fS}18O1hy9X~`z+>&cgv;$?fw3zA0HR4MKP>T}+W>gz88o%d!;t*=B`i?B zS|cmyS_5FF^FY@xQ=xXd#sO$CC@(1?NcGVIW|6}B^WRgV#N3w>AoxIC$@G2bjzZbD zCP{HkIj%G`cW39AhU=;SbPj_dejm1JP14HDbhrGi`orc8cY3VRnp4MUvn#R5&w;=f zNQOI*p(%qxa=W1Pq^Ja#u9!esiUjm$B;WD}$+M>L%YRSZbIw0Hsbjsc2vrL$^ir6f zwdo94R=J?hvi?8{=C|^~qDSEkyHha&3NPv$exi>Z@9Cmkb@YK;+l+OAw{p0^rE|O* z<-X-_ytBdf7z#yCBhyDt7zEMtJOs7MB0w7aBtm%-nU0~s<{E9Od2>G9bq?Xdz+DVr zI+YmJ`u(>64tIr$Wm~4n3oqw4W>WT*#$1HNuN}J*N_E$kbBLFe>#8|=w&o+e^X9&B z>y|8|VBl4oj9G2@j?s}5BtP_t#iCDQqBG-~6&RoN?bB zpp7orU}^1;2vIi6hDy83?H3}?7I3v6T}5tjr~uD9@)Pp>g#Ww(VX4)<`5`B9$@TWF z&^W7Y3>`>FRuF{sXF&4ox;H8bNF_hf^_!d^t^9c;L+I4khm0K@O4=+H}D zVu%YFYQ>MhXGoCBxHO^4a-ks{J~aMdbn(!VI4}-A!~l=XCK931L4R><>9oA=;R~LL zt84Y7+YhHvCu)s4NCFl|vX<6qqAnLV32QfDOU11i_(Alo0PDejY|xKU`g~nn{&c?# zKWeggz03mXm-{q1>W{c#YDI+?qOjkn(sIJa>wp_J)GiZFz^$ zHuceMjj`1}Bxq@fgLf-*o`SkN%)OEPdVLKU?&)xa>anU4<$n^#Xb-tuDCG>|%L)QZ zufW}62HE5voy1Bf&w~nJ@kG-PZYKh<4V&%-qxSq-eO6^&Y+9;bh43@RpytObPZ8z3 z)N?@Qu@!$v!Q-%lY*xD{60aZ;s`J-Sk6*KZ3q2w*Y!Ty zR?{d|)%77IHpm&r=xoBNZG9CtrPbA)^G2_+E3?Ht`_3#RvY@2CxOvc@aH-}K5K88G{4>X@gv$8rW=-gJ| zjIltKQ2=xd0L1Jh66Raq$+Y0;jyHXeO&w}K6z8^}O8!*H8c%+riob3*}&ZHX&j0Z55jzR3U zQFXAgwYl2>$_Xk)pXwsOq1UQ-(?R5)w;lyh0FjF1XvO*V=ARd}1CQ2aR|4_F+h5Oo z-;+TIwKl@8YYYgrJ9ZVHJTA1atQo&gVmoPwjkLy8anFKbJDy?0PuFOI!5-oP>f%6L zJ-EV@?He^Zl%CB|o#8^iz;O-fW7wZ}2zL_V(U94qZe30cK^x0&{)H;Ce4Onrc9-D~ zJO2hDMjpwa+fFmu{^;G&M(q8bQ|tkK3b+mA$(4=5vNX5gEG02`YSCFSYY@kmg8R1b zXf8vM{W!`a?S*O3BNRG%{!$&#HUvo%BGep0UFmQU`|%H-Xt;5X%;K{LuEh-q#V=#9 zKUd3^SAVac^FxR(vTMw z(J;8`XiZm{5D%n;0Kb3nKk{B~=>z3RKvU~aGq=e)i{pyy3#wUOnMHy($oHF>)X&IC ze;jd<67;d5U#jK7o3e;)ORu2C!z*#3w=Ib&CIR3PDN=8py3Y~<1-i`f5#^&RsE-*I zz~P&B+4O{PK$qDxEzYW1Gr(YVOUdHgWa_-Gqubgnep0ynvM;$vQp^0u^O&>^3mppK zm$ZHBWZQrtTj6#!ypdXzsvmyV4JYfsht6{bmr-+sesQ#%_iB50UNP%a6yin)J)cKb zR#s5ckEkyZNZaFeQHgokUA!*eWQH|)CW?(Hh#7ujxZICtzAw5RHg>uFC08{-+!NNG z`z`Yrum;c`}^~&LwqQzC=wqC9;_gKPvc8Jxb(E;p?rTzddLocCDi%` zwlmwbeW;vhdd8;xcsYSgFfG3xf-$h*+twkjkHZ@Qz0%vnADeio*70${6{Rb^Es({Y zgVNIEJ0}T!ty9YsPnv5>7GT$6>y55#+w3F?VqaaXDbSw@Wi(aViMT-N_1SVtaV`t( z%RP@2Vkn>MT+m{h?-Fv`)bLvZIiv@XXvYk)d3`8M+*SP%mhMHzi!9u3*@(zzVbWAV2MgpzSiG*-FUjMqdr)dYq#** zg10N$pS<9C@%eX02^z4jIT;bEb6vIWx6$WK?=m(21|%r8$CW7|y>;|V>mIxKHgq{z zB49n%!ie%9nia-L^IRd&Xr7iCvTRZaAwdxmS4g*b2F#LaozP^8GXeDVubi3~@ggj! zJu|acZ1FHO04IZPH^!P4XwB9nY4bdqQcI4gsCaL?P~{F|boOUcX=*ujO<&wX*5=k0 z4G4vaLm`s`3ewB$h#9OIsA*>s#aw-D3k%3QdlS9yHXH!srTy+l5}#lKBIHT|sX9u_zEd!IT`lzNokVtR#q>`P<*j(7WjN8FLJ zDUr}Kqn+pt+efC<7%1=uP00UeX66yo|p%UI3HXS<(JEM{#>@c5p;*4?W zL?4O^vyGH94eOi3x{D~F^1wgxT>%ZJmyxw z&Z{~jzp6FNuwZ44WevG0YEy!1&o#V;YDYLsqoUlXE`ibbo>Yhu0Jp~>aqi<|;>ctYK(l&Z1>r=H|DSmn&-{{3U_}SDjxwW#{=P{O zBYB`Hc0a&_1L^NL+^4e!OStg@L7|c#FSCej4z<0fQgME6meZl|7{>(Y0VmkPpz`P+ z%*TZUJ9d>;m+J)&-nC^9HE9@Kj6*640$)KOvZz=~NXH45*Hs7fb=&a3jF7W{xitjX z#&zWvKpk?)Rj`K`VsTS)GR*~#Mtre3-^`t$UL;~KgSN@+%u_2TmJbl>os8xqkfWLs zug3{F=O*T7v+`!Xn}8Q0-rdj2F`B%~!4sXx0M0adu!m zYzn58-?G+Xh90#aO_y=q-UWtXhs5+Q{*fSY*vFqbzw%9#fsyz->sYVkooX>PC;p5L#`?@!t%)+IV~C9Bx< zrZZ>McW)`1unZStT-0f6^Xoi0vx-z-dJ^ug*;4}MW~IM<7$?g-*ZL@baBvVPGi1I3 zV)1TYW6SW=TSnNP3pPgr09g@@hFqVG_O`@+e`j`3rajJO z%=)K%R`6V!cQN6DBu0noK9GgJQL+vK113XW2tNk`&a+YSlT~Vq%z~)v3^C-4-j*d2 zp@`ui8h|kofO}FroTty&jHu|Zh>hZ^7^v)u-blNH+1_$;Vj}I({|MXV_4w%Po~6rp z<)%q}ho)$0z3U^EDNtGW!}NRj3o!Vm`~$viiAUzw3=XRZd$z3h=<8fx z4O}(S@}FD1`$&KFvYqi^_#TENS+qR_wnB)D*S<~H;o)IQXuyFCBb^&FPeacSfFfuB zBq>nJiADqs$qa zVRX3lU-*Xu!Hp-;j^pLdzO+<%W$D)lo$Sn_s$?ANazY4NuNPr@P6Qm{h_Cv0!b{XJ z@2Byz{9r``k*{M!5b zkDw~4J0;8F6#WrWmEffyH{wQoy|aVP*rm7SetxqxF|6!*ON3|uQ7W3szot4V1UD6& zRsapTV?}Oc1Wi2&xIuNocH(db56%mmv^&-PA!bzn5B=1*cn`QEO({_5HE^tp$Ee_C z+uF|l;wCJMB=!_`=;gs*YUV+S!tTU`B9@2YOZVw35vnqoaJt?sIBI+L@YkKj_T0qd zvo3kd!8?`xxFCid{=+%sA-1$Le$je{n$~dgKtq348EnitBJj}725vo_;GokvDOH9T zWRqkqr!($y6^d)N!X*Mu5pjvo!y|k>r+th~&ksPDgkD-{5(y}uanq(g+;hYS9zQ5Y z<-=e04vF8G5WwIeNm-~%K`yHftH2Ugt!jOP6PkaDzZI4XUE^AnITc-J6=}_#} zoCc5%m&MR8o~6Snuym;K>f%Bn5|?olV#76Ztr?g}x7R}bjHK8^BSbJidIQ>GRzIn@ zuE@&NYKKR1LsXFSc}4X|2fa_Ni+%$y0YA!=ax00gH5HkTGHepnA7q@jQv1sNOOe2-1Ve5l01I+a;N`ZI)_A-WmdHZ`%Wz(y^Q zmMOa&!GI8Lj!&RB&en5-WDXSj`YYMfKCYP<7Bp5Rhrtp97_)rNi!_ZlE7+0n0pOQ- zLvwfP?D8n-$7jZKJWyW zsq@en%0`4~*(O={W>kdYpB?b;?{eHFgl!n@3HvWhrWngDNW>+?C(I}O4)zdd*-*g* zEHhHJubZL)MH${PJw=d_Nrqdlm~O2=7+$tkx#6AuGQUgc^74*^9<2?r4@djT{bMU*}HyN_O%#ZN!(s(%#0VoAYl1u4iuKYlS4 zs0_Q#%<_C;rPK~DZbbBX!Pp{3%w+9Ugp+-1uN;u|T}NM=5_|Czp9Y!J?o|5Dk4*q^{1jf*VRs+W%g-#Xi(9`AY6c z;n~70f}RYK{;q#-y8Zvx1HaxMGAtEuecjMG_bAJFaf|S-CtpiBDE8!&E=GnWKH!4j zX}a1o@+n9Fz?Vy>Mhx!rI8}bs%Hax~Q!)U40iT}G>1vFZsX$j*WV))RV61-Ca>89{ zZOlG4e?ue`-xrXY>sg=dZp^A*7@&ehfK5t-*pdgl3B?JA!;`HTm8ufn=Edo6md*zp zxXiSk8YYyF->D3X0)+5D|17Xq0{~K87o$+Qx z6FncFm$5e7e|^LG3tM<^{JTt&)Yd)v=D?>1B04X%8e7_1pR3ry!FXSa`JHfH!t0}0 zMZ+;+*9B4eN7jwz^OGHFs@r93twBJAW*eodvRJ~?s1M?!KG?w_P@Rh9NkT%jk#4PZ zn|R&$Gz)E9%^f*N-@vMKT1wd~+LEU9c+hXbU_38cIkD8%AoQ z@5T~EyYfVf_U(SpNnadat{$5&qW;z-MdR@}PK;d)`G8wcdpzu0|AK!O{#GOjU1u84)=mY$f3mQi-AU{r%wdc#WwBoOB!g0Uc&S$*fl+C zw?jE;mIkh-T+XX$`v0-awWcv*_LYk z+&%1v2X;q<-I&~hwFvnS4tU@Ic31x@n_4mwxM_?Hanaf%_vja$6nl8B7BC=LfydYG zX+cQ5CzJ68 z!~~eXVglLvw$Do22g&@Nn*Ne9sQDHcUW8NZu$Rrcz&(6J*DAUoWZ&6I_sl{}zQ^>> z!5e>+PGpvvLeu{#oinSOq8!=48~+s93QLyV(B5fdCHFUNRY_cW-sG;caRq>Mm&*gW zPi}^hdcJ<>8OKYj)~SgFle|lxJVZ`=hwtF;bT5P9xT7(|0?86jYbdWk;sK|t1@y}a zaVbjm1#!xCKpbtSz4J>{ge#$1k%rrm`}Hj}U=>Bw#g%Q1zn?Fr@hy>nA@k??R+6?D zQN4!mR;TGh(U|dl)WGu8l((>mmeGFp#pg=%p$f1oFcJd!{*FJoK~qW9i{R*2M$&N~welRjim^Eq;C+W9fij=` zBtvm%T@z=c0YLh`eiFE5Eq6?n8#JIM+j1EHRULHxst%uQZD_%*R#e;iTnrU`LEu?= z2!gfqRF5S9d^=?AY;uY!03ow{t*E1t))@FNJxOZ4^7MfqVFzdC`o=_KFj46^y zYRfEZkLF@F%IB0zw|937SGvc<#83cMZ{_~cnU=sQrEhq3ahu6eQ;;JOyzx);kYhtK z?)<>)&dhr5%VqU1jG^%he-aqd^3+6xaF$nx8iNU^6jFG6dENd;uc_@2z+!T~3e%&u ztZYA(c}7$bvER9zyE|L3{5S>h5VU^$UmuNr^eLKh>jmj-MB}h3Kg8+aobCfYYO!Z8 z)+}(dNz-WkcnkG6+F#`h-9?|z!$zC7GHj{g&5~F+oc~hs&JPfWp;vaban85^Rn#T_ zLluW~?&@8iz0>rcxSq7wPyTF=kJ;Ox;ihuLdub{(H1w6rgE`}_tzSRCtTb+opE`Ee z-B%djz<=fQ^}c(Tw}F6-_7X2kPQKo8jZD-1{x>#a!l zW}7Z7yzewnhv&M8{KW&E$El3kuT;jvzB)~EFgj_l9rD%vzs=*95U@EF5#c|^JYq7YXZs<>$S-|0xGrQ0 z%Bcv5iAEq`qN5cFj77Mq3XJtG{Eldb?c>?9eyT_BKWnhYiyVqTO`56f^Td0^`(U^0 z0|(jDHu)XcA4+t0HR^m;Qz-{+KWLA2=dT3!dch!iqJJbHePDXmV*uld^_-Dd{qjpq z$Y7`x1>7*l{x(eEG`su#_U_?|MEhqbP<@fw&l}Rzmjqe*>Vf>j$Dji9@ExisQm{(; zWiQ(-<8c7VYrLhju@EO+({4>o{~q9Ric2|6HFqb;)<=lucRRl`!|#z zc2V(v>8h3;OW(j{2$do6@K;*($%atj<4*oboMEyT#yEEtpv8R}_d~Bwh_k~hJJaly z05OMc1mF;&gB?Pe4Eg9|ESetjzYgInN-rSiee>>YS*yh)yd7Q|Z5DJcqI!HR*tov> zT>>f@twHo6PF!d} z%OgGN2faBwAceC(zs|dUH0biikoA5Vo_}oletq{LEGV(@u5ZfW{KQ}!T=)MG#1LO% z{Tuc9C;tr|za*aVf(8)@Y7_+)f2gWB<&`+2-GMZ^dI}@!3s;g1W-8#kK%uZx)w&Wf zF|hzHcmGZ6b%?Rw#pX6N%|`GTcQWArcmo9pvbNPPty(r@z?n-WGZ-m|4jfe`T!e3G zWLW^{65QzyU@_w_SXN&Wbz-X`u z+e-2;L2W*zpt!eA1olTe*z~r26eP*?J{3*5zbcrwIqRnVgvYAFB$q?zLov@rC$!=f zecK0Q`Jj=}+Arz>5Kt!~7=^i$GSNhAjgf(>J`7U7rF+>6h@smPMN2&FL?ZPe?&nnh z$f4e|qoya(7-~YGKwv3v5~qbhXWU)xcixNS1lbV*md|~oTZ6a?(2@EF1`xMrWV06P z$;su;M)N8J7ig;1pu%`O_;l=YH_k#V+~z$_qVVLX0VUx*GML={g=~6=xeYKXejLxa z<~b19BK1TEJ!e@id=3*idqEWHAv)reoUBkYaX}+>-fuPCtz^8xlE#>J*2SAz#4JTM zjKtx*9#CoybXd;XK9Ec3f6gUnx>P{BR*Tt!r+ed{WJ3Nb;cq=Mfp7XcsN%H20CN>z zl1{Xb`6@^{i^5QSQjy-XRX^@dVulf#eT2Ro3X=k*hP`7zKD+d?zI_^29mt?RJV1-r zb2zOU-rx0&l}~ZV@u_7Ne2y>)%UyDW+%EaWRf1vIW22iS0~~Wo*T*)D&nFAg`3cAdn{+~feE8q*O=h-7 zCh_2fn}|Q|Xjap$;Wxp_)>5aIaQbSh6ECOA32JM0N*<^hi5l0B2TRa8(u1p z?C&G;R7cp7ma_zLN1&1%yvN8zmOD@Q6laxEAeZp{o`gXa3?{37DhGE&tmc}X@%!5oHQ?|)x;cz>w{o^f{rz7#-gA3WgLY4->EsmshwaEy%) z)1Gw^nDJF(CLnp#Iu3)XMGqSP1=(iCM{n>3f7!rTgTP%M5y}M87$uC%(EYcv zw5;x4#~wMVr5$vkf4Iu%8vO3Em9V%Wv2;hSVxL;*$)N|Ng`0Ho_y2?d@c0M`gQz0$TQofBdGF;|O}#OZ%z=T%kaLb@sTr#&JsSX~47L#cP=3!+Ni0|@QHZH=^b0;{%X~Jli3Z(pA~!@eZSiiK_LmD)suEsgMEH5n4~Z9 z($D#=Q1eZw^l!HQBwX{pK^CK{cP(oVWk@`7U9X7XdHMSK8tT@VFSaY=Kf&)Qn<3IF ze+>#0Kp%92gTBI*OB`>0hmGdBVUh*KROPq79Aki?+k<{0Io>r(LMX1`1PHhv8i!#< z>mU^+S^?=0NYw-3dNF>cPIu&X*Y}~>g#*_jM*`6uff!|G?)A&pfX&Bg>3h!zv83A9ZA=PMnyv>xz64VP% zZ;#!q+WeS|RQEd$ek@eFALbR_wIv{E-$#GzmoNO|jsKpt-tbh=!_>byn5$v5Yh_=r zxbph5Yb~+4Fy!F2h2Dtgu>9#->c*wV<&OlQ0Rsdx1ln&F+Oz%yGn}lqxPxAYWv|Tl z;fB3YA;I=8UNfkB%bfifMZ?+N98D`A@BJz}qawLt{;TAolq27UP3Od7QeY(UMtmfI z*u){onRG0(*yUp_k`I2gW~R&hM(}iRe&PV)<`v!jPFH*19pUjhTpzE>hOp*m{Jyc& z##_S%o&Y6nL`{S^AZ;5g0r#tvWuWV^v z?$5?8T{nogICBP1P08pbN$$CIsRg4ZRpcssJ_3%yrpT#4Aj(+=QqkqD?LfTbyW*Ua z&A7BJ0P{2g+U@OKEN%$ri*x--a!`cd?B^X)ZXg0vj|807-pxD-K+-)qyFD;gGy?bl z*1+H&ZcAmyC!;B6Q}yBjVj()m$ywvJ1kJ&4Q+@RIrw>I&x2j&yg>>*hU-ZA)3Ih_v zbF{}wUdUbR+IjDhLCu^C2>&D|@f!={>8zn*tM;Dwf`ctx(Q-EjRE3L$0o&{pm0a0x zu3|Qt0l%}Hs#y0YYKB6^&5tV}2J{Z=0pENcFKmx(V0oku9YHz`x8z(p-k1bpNSa{F z3dxNxoQS=h*!~1YGg_4l93*^f{@qw`IXHL&r;E#n?c`Ey@{i2iu14ko5<2+`9MTFP zJRYvA<(rl!!x1Sqe?(TLbX$f@D?$n z@#Z(O>0%lp&7_55;ZXLyS^q->U^84P&YhJW^L}oy{obz+Jcx0=$?@{GKai=E%xbFI_q1QtNyJZsRFs;J_h(~epzh%V&*Umc@z^Uj7E_|tr$A`W5Fq2Y?Tn92Lt=b7dYO4sDkUSmmfNZ`# zmbkw@fb*`>7A5SDMnVXn!-1{mLrluZ9KQuNOt6sDI$zOkN;%{7JaHFmUO#aFUarts zA(VS*E`>fC+i2e;lAu$c8s>Q6JNY#LlwhKH4&INkM-@!J$g8=csO7lEjB&U6A*MYF zdHR|8gdM0FJxtfqHF9Y zfoM*)tY3srZ||qQ&vw^y@e>OWNgw)Qe`*9_cnrQjM&37jOYZX_0CD5C2+pPI(r3hT zMDq})Wl8?wQ0^V@f?tzs2S8_3+Z~j-N^^5_ANgh#&qZXTX3W=FL&K;3@Ql}3{nEdC zJ26rQZ1|dPX2X;ERUDZOeoca4VFTz({D2jK{{JG0pCbR6bQ@e@UhSFb@j9v%8x-OL z)JV%49$32fA^GsOz7))=$-n`j-g{gJeCN6<;EN`4m6s=ypg6NCBrQ>%OB z`b~P#%B%b3t*mBGi70k~@65136~u%kY-(&&5Dhp(hB)543`?wW_ET{OYluCe{a~5^ z1$2YP&l^_+e2$tw`&sZk70dpTcCjRKx;*XJ!l%gCr=b4u6LBM<2VKW~&`n>Ss)SJ_ zbLDWSI8p?#sBo&t!P?PoFSPOS9)37t7BA8od&_ew0`2IDKdkN829Eh%PcJ<120~K! z^)JjU8L_n>51vC2k_=9%dt43$_wUtuAA-XdhPjYkc|<1J7t)r0eRb(+66iWlAi7$kq9Y_lZ=@5)&5}5Dhp?Px_lDr78CyopaTF0ZgY!{}u&kph#2^ zN3LFtmZ9KxuCnpPqNZC;CCUY~&lTj>ez$18mI(-LAGQ@+c}0A@6UW!ut!butM={pMyB`sU%1x{1jB~0)t+{z zhh-ejm~dtrzyhjbsm)hb$m)lB+@q$;W+|@rU(UvKnkwZm?s%MV%^fBSdO$l7k>Kr4 zL^IiARd&Yt69&)Y*@6b7`L=Yc)5C(JFKfnKUYaowb^-#?w?ZLX_uxoGKW|GBty!!6 zU`=J3Bz4HvVK})^s{`!Mb)1irT76#LE}kE>woQ#GNw*mG1cR0@D|C4UxM+!WnCerLa&5Le`yPoA6bz)n)xGyv#UhT>wE zTQzU4KsyZ;!6?mY5428DSM43TIm9>7tIlF7<`jheDap>q_e+`zteL0AKvaw8Tf>(l zOA9H0i%oWW!g(B&E=Tq21 zn0l7wDV4a;{J&hz=P;Oc>l)Gu(oE5hyag%4?<%Fo z>2f@bNeC*y0%iNBKWQ^VB1;(%6LN^e@=YqC$Mcra@6T36=t~O=wW9u4A+5vyCy?`f z$ncN)?&WVHLh~a}W7-UGNGlKAU4hW)mZ5}<^PP9k*tbiU6w8&$Z?4OR7CEk@&wFEq zLCf2HpGdN(?9`J6g(!+Yg$U&7KX3EAiUV?kXX$c7kj6d3bf)**1GUe#5?l47{EUAY zn`6`qhqNa>GSP_87bQ1zGI@C@wSY41cK;P>vSgM(BAm&l6LHYl3GekgTmqX1xkJ*B zT{cyyj(;TjzBO{5Phq#OmCw(o!Xt0hK7>}llrJ&DxB#s}6 z;aE+z{70IvGRnSc^tRW2%;y?q&2Wm5z@T-+I!kpfXAN5_xzf5zyHs~%__FKZQg&~> zk=H$yQP73C;2yH=iU0%G8q0HQINud!{mb;4%$+4hLtle|NdIpHoPG~M7^ij`ejPT$bMa6}-LC`|!L zau1${%lwV76!!O8B{D9X1!$84fLVelC_uEkvBJFT_NG}-i< z+1)KCCbtWNlIiuwta>0J3v%x`1hSpeG9SA>udXjiv~*u-(PGd(0BE&!i)WA$S7)tr z&$MxSwhsC$f}2|r-#;d0x zD$=Iq*xO=-#b%-DuW|Rza(gv^PUFY&%kh)0>~} zpgG7o^snA?l0klf=BXHcY`tk3^Mkk!t=x6YxthE@m_>mD1ndX3=eeV=i(Ru6n~GsX zt+ZcnRa#M5RGUhHwHZBt7tydau6N7WoHgol9Z)@u4RrI4%USweT>A+3Mdy!kV@#&` zKed?H)rAV79E}Msm7~fSj{<(sN5QNmbi6sj>F2+3^i#D2UOuDDEAn9&R8e`o3dJzu zFru~G_!^A!{$luz516W)t=BU8hpeJ=ixbK z$vYo^e`J1pLn-q0uf?R=>493my@((9@Mnl}HLapZnNfEy9BiePKE$YRMTh@o4~E+h z_7J_UqfFTIQ5F*EDdzDrz^--8Qiccm@uslm9>GzzAr9?d%N0SUN>sM5p1H!8`5v9S zDe~{EA39)q2j!Sp&XjPNkhYH)LCS3@$QHSQqN0)51*alszGxj(Jza9jC}4h>CPxQz zS%7Rq!!PEo*ga?!+(#Wx=(wqV=p)-;Du#sPGgk8=MudoV0SHJU9+QJE(lAQO098FRFSEBd;f48&_Ax;Ltet5`f-A6 z!$SCL{~E(P>XYM7?pE;G4gA%eK>Pd+(Wr6#dD&a6K-cc3T%6|7R%WfxV8l$eGYHzyPfd}2Oa3E}}xOT@nW z==Qm91%Xn=5=buotu3FV3po7Ph}x2+6{wKXB?KzXYDi$`=6$99ud@r*dnfo{!0%NKA^KEi z!Bo2T3A7+a*{NuRlfXAT#7(UrAzB`_VhUcEsC#>&1@0WHj7f~(uNkW#{o~|?m;oZw zIJj`pok5m*iI`B^&!C!Oe@|$VOR)8s>FdbsbBIe_I#tA?#(ephdVD^wo?0$rFc-$t@v3eJ>4%D}lZL6K9w0NY6-#%T+J5eXsf; zKg606Xj7bT8VB5;d)kB;&wR={d4sQFrNVi^Pgui%=kG^6Q>{s{Lx=9;fe$J;~nxTEa8F8yFS^VtywMA+!qb zP6bRA>N)J}$Lemd-|Q9m)g}4#jitBTE@DA=J>T}x(OrH?&cvRhe>(&Nf=$bspthSh z|K1VSMWD*}@A@{l=i6Fvco0y$ovE+q51K4qwCC%*mc+!1hy?fAHyuj4LE_Vc!}Zk2 z^y%o>C|V0*oA=)teg#24)i-0aD9QduKuuc1+kHKHvFRCd1bzlODya;#ZZR;mUVHhK zSAXPgN-z4}I%mRZHPobc{Oq+&0e)cVDFmMIW$^v>U9e_Q_PDe>pHcL}89v@5cbw3V zFWgXqu2i^QY_Bmp43)evh8uh4n@q`XCBVmiw7T~ZnrBxX2CbNHz5m?ni?o7iT7S`=SP&#S=2>a&YQ+aGu^7c0>HP%CEUVqFExPa_aGwgkX=+~BB8ASWOt z@3HCgnZA0?(LY0`&$xOqNC(dv+cTXu_+mS@ix1&Y8?xAb41isl3arOE5kvBxQrSHy ziGr`knwvKNB>Thp!IMLzeM2VtMkc+>v!b}U)is}1%Bwa~@X-d!<@CCP@Vo^-Ut-uH zA0DYnwOE(uXr~a|t}c~Ht{Fn2O%L4|EU>OG>$Yx^C);)ecypz3(-|G zet{%Xo;Tg|(?T$XCmTP=5!2iB^f~y-Y9d%!-9KMh zl}b5E>H!=4)JJ(RQT2yzC$qds4CGOA2M$<-W@Swao0;@HT%Y3ROxFYW_`tzj@Bn-O zUakb-<+8Q84LUPk@4^w`>UyTzll7!ROC3We3R~)yv!D?na2`DN#rE1a*4rV9gyxx6iKPT{YWTvRT0i8cf1@B}C6yLto`Q(UdF7*WH zeD7;5c&8WUsG&+mu#;{)_8E+5^8Eniq{*&zCBkLiY{dZJ_9G?sTC*s!sSdgpeCId} zhrUkxQ)c|9c;btl1JkbcF2H>S}^Ljch0RvPgGL6dg@dmlNDE&Z&VI9k?-ejdef$7A zaw*KGW=@eJlNV*b5t6BGr;Z5dK>InR}oMtNh`DP=aMX z0)L^E4je;=iN4@~NqBJ18AWmPv-1R`W=zK`olz;t-eVK-Xz?MVOS*#nVGcc?BUVDA zmyIFr=+Y=`w-RKk#FX;a^BLkZv}6Rhj>E#3qK&=%*v4LP$W+|RU z7jOxIKde3T_QBMeFk(**p}mk>5jzP?$l-qW^N+jFRaYEBb)D%aVIowQz-%(X5vNw{)LMR}JanbhRWLmbf`2iSt<*RU-FQMPkGZ1$MMPQ#~Qs zK==c+rxO9tOn~9zMdw~x#)I|8Jf^+V@&flQnfS$hv9Kv*(_pkaS3SX|ONF`$GIy-Z z9WtJNG@iaLFaH|hRBeA;7B{9>53Al7pIje2BInQ9>yo?lxfC0##z!~2`e>SBXxIF| z<-p5Dj6}jevPtV=;D&hh9;14`TQM(g+|d&3pA}q4R4sQ4un~&dlnuj>m&qX1UA@)x z&cD~Z5SUdSBVh2a@FHTp_UHUOILh=_G_Bc;QE^ix-t_$G&-1-Gt)uS4`P@p;&K#qN z6+g)qmAK|?E>YA$1a1Z(j-W z9Iz7b(L_XuEq#uHQdhtA+BMx8y;#YMuBpz9g{OjNHsZFZVQ+ zI-8o(WA}U}-$XvCNq4SNo%gA2tv`I}@fs@<<;3N?qS4S*<9s3(7O=*kJaUxu?>l{`6O8+H< za4vylq6i^`tp5n1n0J2(Ar)H}F{irX8itHyGn(O&l@C9F>8Mmf=L1cJhEA%l}18o_b2g8WFl*Bkp8e#{*UlTrZPN#@zU zJU0ERWI0CS>6_nyXKuK2TE-t#qJYQrd#CF=qyBG@cSb{3Y8_2{Hf^<9Zm7fBPa%n! z_sF%l>>521a97yPR9bkp2!pQB(y6~tD@J4cA7hC}+we(74Ndvbqs@tb0J@Pur{@~( zG3r&aCqZI8vnD>UdmoM;^W80CnT602CWGOdkHs-Qcd`sADTa|)|Kw^3=OoWh+J7?^ zX2_pqW~Nd7dwyKvzG!za|IiiEbGot%cMQbwx}$(P{A<18bN-%`@x>xiXi+2@HVh>xt;myTl+2`hu!g)TZ8`n@>`z}!4yQ6vPS5kr2pw5 z{Bu1NIy~~>EGsw%fp&k`p@9Z)%H5R2JR->`N5Of3dcN7GTJ%F%amoTBRy*CxdLe{% z-W=Zm3$0wntw*v&#+b(nWoXhjF+O8Bb8k;<2p^uw*$nM0pEHygsZ4*g$DbN}{qJZp zbcZXW0*1m5xj5^^uVLx;`&NdheuH0_3SM`L8S4#{_2$9x*@jXAbf;?ePr>9o_hNEB zvKXlNUqVPUaqX2pr>oz&4kA$mCE+>^qMh=z={lax-5G?3dtS+{8Y71T#$fkS&e%bU zXe}pd4V-zAV$le^`2*&B3#aqud>QWmT`|c0athY)q<)6eX|h{rl0O~ozhyPbcF&nA z(F#dS){u%}H(74=(yE4tAp)=wLvPE>qwV~KSF1^^ABYJWsFEFvTj|gFm~ev~8s0?J zJATD-^jpr=A1D&JMatRYtHly-gI>WnJ@fakk7B+2c-3}-fvwCwrxh*levK1)OZO@^ z4-qaK=CifaU1$V2Y*PaDrn-Aqys1n1vGhhO$Hm~fNWIv3o{9#34k=t5{^B01XoPg1YFSpp}cm$S&!0o<5l0KNn98&J<`!J9gg2OMojc^+5!QcN z+35@S)sCLp54#d8GpjAv5&G;z)ih!7a&{!-dw1 z{UPfs0~$hskjj*gdG0z}1aX}zOm7$VE45Ji`MVa-lj0Y77-A^d!|udmx(!QI;OLl+ymQp-YqO$ z?dNmN?$Ik9Op6^X+bdMk$ilPGqNhN58A9WEq?c+`)aekY%LIf9@F^*b= zOV01iY->D?2^5iun@w0_IaYb0v&}P}52N-%SSPq>Uote=B((ak~g69O*U2 z>r^Dns*Gx#&M+$%88*sni}dG_(okR5nPIt7iX%Yr63Nqj>_rK7<^G#GC5D#;$bwfq zO9(cWPt^BMG>uNSTxqs~zD0FebFk}W-}oI7J*XEv2d?sJKKf4x*L^>ZGi8=Lu-$b| z!Da)Q?H3p&gjbPCFqFv08AQeiKbMN#y2~1Ut;YH0>7wuZX4Gn!A(V~bxR{O7tV#&Q zXuz%;qKs+R0!y{buc_KHGAxQd-8Pt;-t4};Z^CS^if8YDM>pn?KxE?t4UoxJK)ou4 zwBj#f>l`3rD^o@m4>mc8F^G}SD1xOt_c?0r)5(%YG0o;hmj@i1ev7%?aYDy{DX%0n zb)s8s&Xf~UW}(q>?Gf#B@X(3~VvB7Oz{%BxDGR67y!hgmtmWNML)Ns$?Mf_W| zds2xdH7_s*!#M*p2$C|J=(VT#jw)V6=2^BLe`THPNE5of9}r%sxoEwzWJvkx6R-0b zfqK0?`H=0nV2hml9=Dgx;`7>_3U|(iHdLZNvd@;8?CeMHwv^5SHL3!cYOZiKs?b{(F-p^iAy32eCx<& zh*|YHnD3AbWZXvb#eS;dE-~p?E++%wT%eCTqR2lI$R{tW+#ZsYUX>@}N{r=kk$pvo z`5mPFm#i@_dVFWB4!>ezzMY0$lJe2D8WbC3 zQ>C`f+m`g!sP_<;;(nmt{#q*5coGJV`Nh%-wwq5<}Ge#f0Y z4a*wZ7IEceiePL{ua5He!0fwXg+I0Aeon}p6ezEL33HOXTc;Pf}miKEA}FfAj$RB%-fQEA|fcCL1#LYsP{~^PpUM zCJr5T1Hm%=pv47t2Kud%D;wV%aVXtCmjs}f2s9{toBlz@p-DPAsvZCuHV56J{6 z2QOoF3e@kv8IlOfTb)PMi4ETfe^vQowhX6`Nq9u546?#$nWUFXelnTAMw`1P*a#l& z5lZ(Rhl8UP{-IW1MI(LPsWqFGpFF2@^EcqveHYEq^(@!fEswkI?kg)6XOTA~le&Rr zE4D@w8G93bx^p2^;I*7)^;9OWrA7_>9a8p%yY;5izQl@(i-}kL+t22G%DT4m5+jG= zjYf+RtJ>w4CSLmRJlMry&RR_1=TJS-@-Ax|6UqN9I?I+J4ojde zade`|MBLfaiLH;ak(9M!Twi2(ky$X52EyB$<539rW8cnr??cmVQc12NE9fM?K6V*# zC=jf=i>X%6w@Zg^^%}qm!S3!ZVeShB6%|@_b#)aHbl$z#ktPM(jSn}LhlDIEDLIk~ z(f^s{{|1>T>xH&%(lO3#SsLV5IDbHfn0(m2D1i8pQuF*RTZJd{D?iD2Xl|Jhs zy(N}M$7B8?^w<2G5P5Tf@-4*M3x$(${4E*5C#q55mca(jhOsw^dRb*fZ$<~7i1s2O z%91Klsn~wIcbZjfe%m61j`O_}s{_h&17roc>5a|1>SYFbBSlHBHuoHcOBseG7Nkcl z#wSu7TV8FW9M)#EeXm)GuYW3Sc4j|dYqN3SR++j&5&e3E*(CeN=e;ss5e35&>!MQ2 zfx(KfPOZKq=Ao{5NBN9r)8Ci$ic02gZnG%KNc|IIsCP>h3Y-E*KA=Z)v<<%;qABJi z?1|s;qR)}cp4VY~6LYgl??v6t%4(36NG*LQ?qzL-zq|qzo=D4i^vlFs@#aL$T69*A z*ZA5#da(RKnO_6vC{x6&Q9YqXQlR>x)SNQN?GVFcDzB7I(a)X|W5_lpzj{SBF0%fP zgW*$$wVE5mKP4?=c&ZL%x}&k53wc%vwaf?X-*xMa=S_x4MF+=!#7OlAXm?MW;(W2X@7PLNBO+x8xk5&UhPAsjBy^Zm_L z&~+n~&t)u4sORAQ?Wm*>dExo26TvkFQpbj?+6j#OBu z%+1fM<2Si79SkxrM=b``mT1Z(a51Vk9=Gq}vifoJUHzNkT)A40ktsrN`tVb~#nu56 zQS``^iTyI=wAv-b$;(Gj9JgVaI3DU^sGD&*o12t-v~@}Xiq6*|S-Z-nx2Fra*1QYW zc?*lnkvcd3>=)iY0WCHcF2YmFd>#MVAk{Nrx=u&v_ z8wx;qx6m{4p1T!RX`4)Nb7I>lzeRP?^lZw(7|Y4xu-K4%?v8_S+k-X#Z-}>dn%VP6 zQOsboxxO7`w*HJ)thJ)kWKzOokjkS$#B=#Qcbf4rlCAq(;$|pk!qlP#qxy9kjj_^0e=i3B)yJ&;;5oe&f#%yy{e9`}9}yb#PCjYkv2kO;!x z+~@Y5MZ6+KT?Z*;jK!9bbrXk&Gy})}dz88~asUlTvhpLkSF1b1$DMPt9hcQYtfM?l zXIZYr2RK1FtXxiJP87v%YeOL3wIk{{4kogrw#PpR&&46=9Q{BQMHL z8JAgJl8(N4qY%$!a{u+r&O`MVTOZ?i9Y#Y01{!s&FhP0Bdje_|8CqJPPZ%8qPiq0v>CKvjH#l&MZ>(zF1uiNmR#TU#3GOM0I$ zHrWj4nYPpKjV*ODmWN3BC}mFze|105?C}-(F=5uuxYv;!kp}gn4eSaAhv<%@B(fu+ zJ!W{|aP~GUi}$`3cR9!U$G$ntOa%L#ehy%X%+`dwjnpQ=O1MnktozXYuEu;Gm&`QQ|a-hT z!$^6pe;j!1PjyPs8Mv#^>Ps6@eiEriz2(&d!x|cDBjuyV5dzZZS5%D^vzH2xp){Y3v2$B?q^x7z{5h^Zk zqcap@i`e)5KGe`Z9dzw0voLc4R$G&SB7^%oq!xdL9mHNi;aoGsS%$S3wY7Gh$>bYhU_07cM;+fo%3JWG2&v(Z=$@GFkf%k_%a+^Qb1B~1 z%#Fu^GBQF>8IjN`2%fs`rDitiFKZk+I}kIe8n}1c`ztwrg|_1tZHIm2?&3peEwXrZ zpWA6+xlq{lC!Me_)tG4k)($}?dgQ^8%r8WIgULkxztrk`o|v7k#J5C4I18Yz=ln~#4^VqyAAvm&hgKy5B?n2DwzGppR zE3k5?v^Uj0dFG4AbzKb2IR5>0TC5(D7S!Hkf6N@LWRWZ~MfnZE@SFII`tofgkGetV zi7*wef5!_Wgx@jRJyqQSvGvxgdM{s&4U*1%tZ`1WXRIrss^tAPg7ccTpwcF-&^YCL z?r(1_ZV0Ed1OY)$=r*B0H^r^^dmPY711JFx%#L=pCK8BUwwd*;F^2s76EEKfqpwLO z9sF&v$%n?vGM=~l^UIVCHd7_6G>_9s~;!@+DypGc+c1NgPC2X}i zgFF&0ZR%@pZ-n*eoJkjpXYCw*2v_$>)^`IUh#@~ajBJ9deWDpP75*E4KZs<^%I+;y$?KwEu>ZNYp=1da?3gd=M zf<(GZq6p~3_R*nmIdgH6aVJO?emQXZjKhBU#~}>G>E+iTVOI(xptXo%A3l*-p+Coc zWzW$R=lRCI@-C>sPET0eS6qeCtP;$t$b9%u&0T_DM{jxxmflWp@@md;&^L7`}UVHeu?PK(yV`k47~)Ylm08JS5T+_#zXe zO>OLn3uu)*wlQJZKgDq`6_?mZc6DMV$~%PKx{vmoUx~)79U3iN$qC~l>dko>VtU_| zk1~xQ+5G+(D?)GG+WkepOUZyJbbkfi*>l>er96K?O(uQe)8$zJY)&qb{+++496gNC zp5lQ+y(8Z}F}P*sSBWOVEV|jxUawoM^gAztOlzzItBzefbk{FaIEHqH&{MNVTtDbB zY0lYqlS4o2g^#ui-5mwbYUk41Qexe3o?rtpnz;7E+G)1-qm@!8S+8umRBPE6$*b^g zhX=Rk#$oYWdnzd8&6ka%6HSNXFDI&&v2;1@1fNrf7P`Y_R;x!gZGiRxbjb^a{kIxb z^)2&98kuz{b&}o*4C60i05kG3*fy9-!Y~;rim;|jIZkzr4NMSIFWF>mjyDXF5Uuas zI%FiP`HZy<^TWfD{SAc~3=q$)CaZQH&H6Xtod$^Do4;a#cW?e?J_$i6*`^W(v)xE7 zL`T0^lmo-kfD}xv5%~2+Z_*JV!Ia<#1NUm{QKTMXpt$!t1qRx(Vr zJ;wek>;QDi1bWjk8184;{q!%hc+sZSOiIsv0XlL>Ez7cP#Onm@OOF;vJpC^;m(mbp zgeewT80Yq2bXV=+@{MSl`GWA8AG3px{XIQx$IG=M*{#{Rl-LD29v7Sqx^G@eR!Re6q z&63b7>r=`u<<|RwGo*gf8$`49l#Kz^HOOTfhep$mRAjY${6T|fs*yYlr7e4HG+L-_ zA37|>k)v2&nU5*nGiWBK(^yfl2;gr2gFJlrat>FtE~txx9=?Oqfl^xt& z;@Z2d!=*{syn4lKQR$e$%3f_>wgKkhW_e!3t<@J9b6yD>Z#YUJnL5Y->KT^4NBxUt z5>opT(!SzCQ(DW4aA%${PtPWh%k~OC?`8Vp6vXi7wED)lzbIuJMXk(TuI7dA9^BVq zgrN}YM1^J#H1}|QF*q7V^>1OfG|3Etx1@rRke1(9E?=uMt!7&>TpEjqSSciG7$YI! zAT2k3SQhe%A9ILesN5G0ci!}s-vqtD0Uax)kj@4QFCv$~oiDCnWC>>< zO3eBxY4{<*Hkk6=@!YKcQdN=>d}*YA^Lr10_H$VU8qsY8=Y1W13p$yE5OrJr$BHrG z{A!kvPy@c8J-=k(xqR+AQ@vz29LK?mgzcw8wzqp%1NFi$dXz`FEr!q6TAu~#NQ!_a zFZO3{_u8L7$s+RN$6_6XzM>#d;UUtSZ6kbM`EA*p$mIlnXWqJaSe=ma*65azbRWrV zAU#oYJfbao6}g6C!_!(d9B8Oi=Zs04u1umysdp;W(|UghW2fGu^!5hr=!Bj!Xsf0A zX>YY5S^xH0$itTo!+K{{Q%${Ybx$46a%(C!#B7#3(TVKDBj@N}#D&n}EZFBw%WeL7f@FFhr;ZK-lb2~GHdCbM z+HiyNIvg6|34r)9ZFZ@bio^49X)43<<)-fC*U3*>jd9JcD<^I4OIif+ypGse9cXhQ z>+rg>?R5*50m3RuZ7dOjR|B$W4^ zRpgFSR2Ugx=_wu)C+bfqL$-T1!V#i~KL$4bgte{vG_5bom7|gm^cq&_+fd*6ak+z{712L_?0j zduj`fJNX9zygzj^dG9Vh{Ld325|;`dU)m*j;<`PCT}+px73y8M9S#n3;iUCB;eR$C zMXGjqozlx1pzRTWU*9ecaXTD5O`*Hh-WOUQ%_-e}mMhg7L)MGl38Q|_LT0?Y;Mcfo zzvYcZ_GrauuO}+xeT$9@v+Va8#!pq;AZs@?U(L$TW zY~9;J6X`B;78UN=!%CLw# z?WbG$u3xn>8(^6DmB{7J69V~C1gRL?>unh*va^ql9(=FU8YStyQ}g*16X7eCy5X<5 z6PwDow@>{9@)n*h4kN3oUog9rZUnO{wtd$l@D%xkuE6y4)`(hFhtzL&J)HI{dhizz zq@=(rWI-^v@IT!C(R^6UC6v4X`T7O4y7%6mq@Nh!^DsYYMvZc|Ut$G=3^J(>TezUS ziiQ4@Y=V(Ivd*IHY2(2Uh3;u|GE-h@kp>8ochFF45wmUA+{eAPknxv8M^wFC5scu( zgxD@kvY5RO)-8dpE1{jR)#}l<9>PmyBc1bx&Eoedyj^wdVWN^ukd!-oq!MEwUB!ib zQuI{L`{qM1aO6Z%enQ^X952}wHsv%R#8%?4*YxpeG{0spNn@DWOvZ1)@b+5od9RV1 z<#LKs(9F7l5P0?bi$^D3ikT5R5mQZgFWs>Iz^Br^N2mwGPoAX@I7}@&<%puVJLR?V zm18bYH0iXut?`kNRR<{m4UWT=!2HqBMIB_7J43eGfLO#@23A|vT9+q)=Hi>bnu}a( zpOFO`dXVhB13QSzO&k2mj9EO5w~Yoq3it58-|o8zI)_qjun3K< zRG%-k)gyw`8)(pZPWY4Z@J9Z_>Rcv1SEovP|L{s8lkiHXn#T0}R&-djF6UKZKGI&H z*z4L?CoR^qU=JN$RD1QN3ji%pXQ4~;17 z5xqmJQP{hhf@v`uAk~P585Kdt%qLs+4?Z=c=A3McZzaBj8NTPwr*oK6F8WP`g$tH59E zt<2A?PP&XOEO?W9s>sPO%(A;4^zy6NQk`TLuqat=3UMV*!nJ*hvdrsi_ADDw`O>w* zs6qef&DUqj{|@eX-?1zD3Z{G`2+d(Z=!O$b&i1V#|skm@|TsJwD_Tq*B zK;*Xok&pkSKW;H({u7NUIFf2!OImSJExN4zCJ81p;rMys44#2{PigyR2Lv7Ez5$P%IiRE9N z3>*|x6WqIzW};mihPO-ZUd6)vJzOqcrsQgDn7GECvBtIFZBcIR02dcsN{0Thk2luC z^kNCN-8Js2^4HfC&5396mdUa#aXqKieB5ChGu_6gzSphW8Uxzjr2SiII#%v(9of+ouz$`gZ!^gi zr2ksTLiXO(s!;BLwvi{C=0y*2)E~!bI_=s`&1X_4wapgWeUSG3+%aew^<`{d0(dOu zTBfR0xJt}Od-IfPe&F`D(%xD;5}^Q79FHNTlgXLeBg$HIpc%!^r|+ItVl^b%AC2bc zv5(9iwHku&HE-CMA=MiB8|Snp3Yi&hdr(koXafvQXXr$+X%8Wu($+E)KBet{bzaKa0iLNNrdurW0Yl&JCvM zI~T)Zy6pnflB(kmRhS|disF^>{LDirjF5pUp&}ZVKc!9q*Ava3!)?8Hes|h`dHq8g zALW;K-&>gO>N6+zNvi(o<{p^{vf8()rDBd-m5sFC2fjXDGLg;A}u)-Mx1G2+52272Q zcqXeLBu}Y;B4ls$NAS4ASq*|&`(L|gah$d?XGeQ?<=5A*9lwdv$bfpjL+CSss~Ouy z_7Ym#viKV3U~#n0twfX0?5?8BvF?-nXKthQ9}JG^!H%U>pA9Rzd7dT%H$TI}SQq>5 zg)|_=v`y(%%!aB^35Ic{mt|)msCl7v zwOs0kp`QrfG7;aMPwdt~uB)A+R+q17;o%;#O|}z!=NI{f`Oz9w(LyxddV9XF+Gqh8 z;`tiQQC4^0h_tBCE^1`spTl8a+}B+0Dn>s!VLOQYo;c{y+7A6au5&+r)FBKE>1izs zu+iZ;kvM{48nhOHB{{|36Whx#Yja)Jc#j=8fcm5_XT#BZKlnI9xqrWy!p4hW4PUMz z?Hl<_=LYmgY^UF0J#Wa^A*`s+LEpluk(9-|Y~>YsTxbcQE~UgM*3~PZm8FMd z;5^t?#_MI6Q*SeYm8wd(QVpq$=dUpEp{b)ING9R2QAlucN?QuyH}&y{b-pfV|0(wG zq*bA?qinbG_oAOF_#){EL(z7%jUeH-e$lKsDpqH=a%b#=UM033ac8oCgNwaHd_7w3 zr2F#(cZ>LFq9I!*F17xow|c+N<{@Un69$gMiP|>(bG6*ZgMAtS>8 zC-mDtm|H!LQ=tMnlI%7-k_=06?&lhr_)= z;f|XsyTzqmDR3;rBsM)$EbH+t<>wudU;MdoCg@hj>~=&OV~yu~aZwFS+NL^Rgcb2K z;ufWIY+^uRy&mIdF4h%wGG`lK^$fv$NT7BHeV0&-FtA@SZrTx$HzUQ3^qg>Ky{Gl-9s@Pq(%*h>b!bbhcm2M zDfq^%Xryx?$wc;!!<_MvOs6FjVwnU4y5hsLnwcT}l{G<={_J=uV&{6$!D(kE-t8Cm z@S->A>rM5&f>einZd$|a)Lg4srX(62JHs4Muy&h?_M(pfRx!+C;<`%9z6vR#Fy0@8 z*L?2%4YweXLs>Vfr+BDkVX}>a;V`!&l*;|He7bu15(7-O&f(+;t;n=^-h|03 zPi!uqc?=}%abP?7)cuD&ox3D{w|+Pp|HBKYxl@>1Nc2IJA`2qkl|V#8kO{7H6D*n^-f%+RCZwkREpez zC5zI-V;wotDw@$daH!RTtZ{BKr=Ijly&4ot{@O?U=G*m6A8!(~d}tCMnZWvl)lpaV zs4qoBtnxULQK2mU@r{4gH4UWt?*X!?f1ZsIE*(iWf=%R!!>7v_F@05B(L9yVUwfG^tIVM`rVAc=le3X2G7?? zdP*VJse_l1fOQ~*S(!YhOUah*iT75AinbP0TJ_-PCC!2LTT6ZHNAcLFp$_+Agy>wUhoDO-zL9ZqUn;xl}>Ixr2iN*$|P$*gJKjY~|hsLQzMk99c+ zcH>bMfK~aSl<@QU*wpL{*H#qdR>K04i(jp=E zzJ~7g8a{_~JJYEyzNa*Zt7Kp;04O?ApeNp59(J7_!$q@bVMeC;vnL^B`(7!^+w(Cg zODXYEk-Z=LnTSjr*Zp&W@cK+d+j0S78IyK=b))FS zV;oSHV(cE9Pk9M>8P1qnxaS%sS%1^i5pt3mz?i1ETKl8oE zZGMIEZ)IbIETFql7yX8x^R+P0zvEIyvyXovk+Yl>=W1>kZErY0wD7b$-5#Oe z_&ug&8Q(6LXgC9X477|WQeh_qU)HvZ-`-Ays~Z*+&%?x83)2gGl%kU`cOyFSedK3E z{JQ81mQ%{-8$xQk97SdDgBl#Hjw24YOdhp#1OOs$g{B$5?X(0GC&%5D#E5FFaPiH+ zCc`eo(Bb%Leah`^cjswGw>n3IwlD=}bBJc2eXvvo_%2kKTxb~*ld$+$9-TEPLBS0n zM=uzLd0NajpHN#xY(^`_n!ECBd(*xr#((9zUg<^8_{pJdOtM`nh&z2=vVKx4epn9m zpReo{Fu0#OTQ=J2ly%pSgzbz>wN3214wSK=oZ+dJy{R^zs6#lo_|FDQ`;xR)XmJC8 zTn&5n{{CWMzRZ9oe3&C6*Ru840=do&wlM$RYdz-Bt!7)-$v&@UCykM!NH`P<`x<~z_|h3d`u0 z7~H6{IsM)d_n(m>bUzH|Ii7QmnV03;cdlHS%pV?10|S}MF#&Gu`IumyzDAvC+DtL&S&*(yt5S^qnfm|>N$gPAzB5ww5C$1evD508!~9)rn8%M0EH$YGt+f(E!!Ks(pS7kt!-k zgawG4Wd^6 z^}`%R`^2jddp=8+FqsF2T4@W7vRF}==J&ibA6+bVG+V!e6F8Fb%uLXukhDFcDp=b< zcUlg*>5u?iV6hcqC$-fIR5ZTtqtp>KEPEuFaf z=PmWI{}+^hHPV+Wb~n4pW4Pp*HhC+tMV@sg)Qb#S0VX|K7I|zW6|BOn!9Fj9=#2iE z0D%;VL}I;zDW7l*ghP+pW|7OU1XQLK>mTk&Y2>PsUzdSn8k8%rec{X{!xoA8Fc1Kj zeT%Av$r_@0(}k9pH-rK@le=W8rxyvb3Aj`ZG{ODFJod^%1WldYg(z>7{3IFCa}m;W zkAAwfr$*#N3V*Y}l~iEsQhvf@%BIx>ZfA^U4OQi%02!^FhA|gj%R0ZF_kdX@PqTIN){8kOT!(?kbF@f+n>oQ{ZoT#H%0Pb!< z^$_nIUGrfdKSdN}&fQeBoM|2NM`5`3N^b7FvIF`g3Vz?RBs2E8=c5Igwr{(|b0=Qg zp&WLhXrG7=j#)?5m>N6}eYU;KKq2i*%r;ls$x4G-a%KdNu^}0^0dj4xyp<3b* z&bGHPoj*;T5g`~6PQhx`+H;mu#mWP1_L)_MihkyUW$;=Yu^E_sxMQCSk zNSQsuMv%b3Bv*8K>UXKd^9_Zwyih*?AhEch=!}N?pJxYsVqO$HJLV@-Rxh&yz(=Qk zC;t~4-}%o7AobmFfB6+_9+;uw?}>lc=ewBH2x9>J;atGSzz2-W4TH{OI{y2vRn2=S zz3{0Bjr=x@GeYc4GJ;GDm#IZ0% zmvUWeDSOv9hJQHzapXaQwvU2BnU1z=IXEp6xP(H$@v37ZuMxhGzvVR|4*bo6;Vqq8 zULBJ6X8StK0e+Bs9-_piy>j@nvpA~lwoxjchl>b9*ku?j+42?u86@EVo@p|Ckm_RG zfrbbq7{>SxihyU>Ls*G)tAXc5EG{WuyB367k*jnast^LVR=`u~uf#w!ePu`^{M}OK zw^e!W*cyXkYv&sSi&C}y^i0=b20$t3^}cibC#lPezuEGSu_oXq1^5TM#UK(84#4W%n+%CU zqAfI{klfKOE&O4X=XR0@L%vNml+9h@fEine53(XvCd?Y%lN-u`7gy7sUQ5LL$LJ{x z5Mx}w3*>~2vlQ5cb2t$`Am?^c(|!wUq16(t=V>Ei`^rpxzP$o?vKP1?OBZlpOS@+QPYQM|IO_pPap~}w zId^zWOj$e)*+ylo0)cR&Y;OlXj~*I>^cF<7c0Espo#dabTDbjaTD9k_{A6n(D0bdY z#WLgOxk5c5g9Sd!vogb$J$5$8gKcq3CgyZL;VJP5rLH|X=G>w9RyL+Hb&v*UM zi+-UyKB`6g1q+>Qd_?Xq*ZCvgDD{!o{{E{kj7lAmU}c{1J&%e{!g|m16{JVbZ8srY7RzX)Gc`J*6zjOI5(& zQ2yM;v(=#7SFW1z`Sv-0!rRE9o#y~*oR~)l2hb+%l&%W^1;CXv+y?m9JQR8XpgWLi zD9uP^y%N9+THtN7YkaPCQQBUECyYm^rX=knaBhvD1a9$34lDBtKNlWP@UE=TygjSW z-62)isB7i<1@@1`Ti$4a58L{#!~gCv3+*%b7M{RJf<2gXCXFoTYwllL8lWkwjsm}k z-F-*WMTbe4({V19=Wt7+pW6MWF7Sfm{9^xo!FJ#ojfjOV;|8W4WqUrqmQRuXE;|vM zKZMbu&_!-zIW}kRz_*_b+Q+w*rqS{}P9EM(kCSq68Hm*Xi+-ge=+`r?d^jOx&H`TDNskMGOQbDj)&^l0gL|C{bvF-P6HvvVJmmenNy7|c|;kU#Hv$F-#B5)BwH`#RHBG)|+{Iw&( zjDnQldf~drZ zmO+51KX0$YitJ^haVekt08Uc#K;g&+>{7eWN#tZL4&=qJM&F*DA!^4NqVAs~Dnwz_ z42`I-g8Q}pKva-rk@~#=QSF_7BkJ+*$!qr71{)8VJ5I66;wxur3=qI@fNEM^pKSUA z<9z=rcdX6X?14mJk4>9CV5FIP{~-mlxn<-t*8KA?;wF(iqm3~M#${PfGSft&wdCG2Uyz94{x5g9r)jIVJR zw?CYyBz~*@dL6l^r0nwi!~WT1Gl?n(8anJmz%++?=!t(l_MCH%zecYOCu`;^HMpF& znZ?G;Xy5b56{h*wyK=810Xj~<@)`7A(fQ@rDpQTgUux>%!jK4Y$=$QPCulB6$O3$$ z*_p6gYx+Ns?zG3mut4R{O0k0yaNt|mi>P}j|73irZN^Qnj<(vZi)rf}NKMs!(q9QK zVh)JCK8&oeU3wdcyTmTDUUM{Ila{M@ivQ!Y+Uzmd!u$?#0{2g=&X#kwUuATJ+lm!j z@BJ6YxcTCmRgDl-Oi^uQDm!pXoCcd{O$zIG0GoRf10L|wtO&z~Cm4vmt3?Bn$W&Jyx~VV%{pf1*ZzYHSp~rRn*5fXcQ~n2LSkI#B!l`>Zz^bjaTZl{gs2R}m zshgkvx@nWxk><=Rl+a#*wn8izpwG7vXzT9#oF@U|b~Yp^IrMIK7ezq2p-%#WiSD7=|#WBpvH zKNPhDGmXVZ%WykLyVKY+Jak(^LMV(5%=y;Vj~5+ocO+pio3i4c91SHlPrlaN@eytU zW&Ia#M(o+>mq1oq`-iMn|3Tt6nE#_#F~6L^bt}0Vu?)J(t8XMxo?hr$R@UE6sz?L4?E8l zviWBGmLs}vs9en<#rPf6--dDvtuX0o(Nx%~DzX{ChA4)_idh=iO<&w{-ZXE8^613x zTpjKMfdWQue^W8Twn=t2?W4VQQ^B9mb0q&~s{M|I7JWMX>s&iowJO{*cF7;M=P|bl zFc+Awy&0=?%Lh|rBJRjsvoz7F5gQ{y^k5RhFokvroywoN7~YCAT1BQ@x)*ac-13^` zv)*ZrTqN_3{6urgdG(gx1#M^@O-nT`*(!cv7A?5nwWvod?)STt{0BKT^t`DK5A|vj z3~`_IX(!2dy0^&t;sF5Dv;k|GpGfFQ55~*tL)jh3?+uG%Jnsp$(aJ*9q?8hf8+K3G zn_a24s2Auv1@QBqV3~}ji~b;6iWACgZ6Sm^{+^jVc~b$V>0T6lIEYvUH#~7{BlvUG z0vx9vj?s(U6N&*hMCX0N6{J9^mDkQQ-oTJ}%Hhm5DgaaNFOfJJW(zx8aVNQd;V# zIanF%|Lju(2H=ZU#dPoZ>i(USz1y&EL&B%Dej-sn4vV*E8>u?7I2rW&=w5~j%{m`{ zP?(hlj)o{we})a}mwTU2uWPCCcbVIqZkjE8=;tIHa7Oz|z1nP9W`2I%>j=%4FQfGh z=oY=mUTir~xd8C`sNfW(aWrk?h+y-Qf>X%Y#-P zZJf!64H&CZ%xTuj-cC#K^}~SO^?vqp-rU5Dfjz3cpQ(Eay9V1J?HZJY5(9Mocnjmn z&)%#@C>j4ATxq2!R8>p9q`?~Z@=$H8Mj{{Qubf}#b}9I3;T*I8q!Kjx_$DK>Hsi1Z zU#fCd-u8moY14AoozX!ql>HBnM|tJhNbRE9J7o=?|IU<%~G{jfVNyG$e;&? zH^J{k3#{r-B#0C%ax%E8JHJ_peRW;twV5lJPVMVg-bR|O%A_L|z0%BnBCL$UgzZFr zr~5xBS?Z_yoT!A*$N4qJr7OKC*3g8Sqf|8<6FGhiu~wS!IR-iD9+;Nx!S1iOB8TfG zS-a?wGKA&ZG&hl8=*E|#Hw!d_Gm|$}Og1i_9n!-Q6WnD)+2nLNp7NQ7w8P;>&KUC! z_vx6q@p?grui3+p^B9q|^IQhw6LH8it4TI(XlagZUN(RAZ;6_t5=Pg;ih}&&{lYj895vc7? zbrl(IneTiT6^f>fuiU-HWYk85f!@m|?XxeV#!>hqW~93VErC5NSrz)-Kd#V8zK_Ag zvbl&l&2X(Yh#0Hg5S%EuOJ_hX-E{sP1^AM?09|Q@7ZY!pOi&J>Z+f9!hDwa&r@I=Y zGI6B%N4>Cqxz=SO{~L*H>|-s%j+I59%g2UBDf3kOCZxUJs^sER4cHDU$lNK3-Meo~R4Mx<7|QFBQlz;Km(Q z`xFsTaOP*r7scoPW&tJ9yKkvGn}WMTg1~ON(AxrGo6o(@;{$#A z)DyYxSQj>`4V~oQIz2f~bKIB;41~=^ukV9x0m%l)3A~4sC;oLcHOvh{6@u=Ys78|7 zyE}{BoYWSUQWO-ArLxYx*0dTm;rQ@$pF8{fORu)pDHTj@mc7BcGrX3v3&MU69R8zxYZ3w&X$vK{tj_3!m2;nyJI^n z5eYe6tvh9TC+T=xLn)+%y0%$xN$a40(jD1!MdthcQ=PjyRc9tyZr(YiY9%O~cz!&Z ztIjaj%H{f4T~RSa!~Jl9fIXSQnA!d7=o6+vkRz$1Pvvlvho7Ye9|@F?)5|BgZiV{> zK-rDI6Cs;~-@VzwYb6vIXgXrC`&8MewRmIiBSr{ zn*x)9z<*pxQ8P8;<-yPt?_tifcj8DTZx-_TFq-KRsufhykIlJ(r z`}H-u1JWEWZ<^S$%}h<_L#6LyrIL=OoUKCR!bzJuYf(! zg<5k%K0H-i1!xN zj}&k(TfDt%@WHcx^4X%A`Vx4YwcaZd-dgLoM>Yr7xp%lU*=SI}y_!<{aK=i=&;H=S>HdCp^TsJF zWaflnlLwHji&#H{E8$ciI-|EY^4*|wR#quex?4KbQufMS18SeyE{Q#EC-)S%@&8J= zoGfnQX~UG%)ma2w_RY;9cY4oO>n0mmEsy`qX;>kJ8+xsEHP`3T0{Bk^VlvU2u^NSWdZhrL?(Pgy@!;4C z0F(0RNy&y4a?RrTGgd)B94t*=-p2WA@R{+d6Kz3T!@qe}=Wz(vIL)s;%H}`*RlMlC zx&k@^!Ib|gzJYb#Wp6&Ns|lt8_lyYgX54rChA1o3K~79$5}rBZ9a5B3gL4ynoX-0B z8Jyy^LO=7+Qf&o4!V)|WaGW`zatYDIIjR+c+KjW1m*<}YHkhGpJaOkgm5rA@Kx{d? zF8I`)Fb+)CAtoli5Z0li>LAe=dI>3bnzFE-Dsy&l3AB++{>zQjfTMVWlAm$1%F*h- zvkO6v$)^vtsMs7C49?RZI>6-rs{?EswUdZq?G-qPbD9UHHY3Dm_!%F0yf+z*Vvt&@fNPp=@{kP=;!&!W$ga}e^_ z3_b|FEHhNiRSiZsIaKuMmT{M`;*D+b*TG(OHGzL5j;(y+93Et@CWgcrRByjVUUlZ& zCO}DsP1BwkyyD@hm&>Ew$EQh@GcITE96mg4aw)N?t3Voc$I$f(p{ku`n|$!3NAonv z|F4n$#YkQtlRdVDRN5~Oe24KSEL+wAuzb~8cXDCyHxMAhR_Csw_t#U20#bF1&_RCr z1@1KgZwmkn0^s$(wOGxZryxfP()`$Hn}ZLH*#}dB`{%eLCW2{xv%IY;;A3x5zWY4& z8*@Uh*5x|w(Mj8O92XTcofQhH=sp|JWDKiiKy7%q3v_~d)$Yc~R*|Btyx z_X4Vk>QrIMWkX=6831(z*gVU_O%r5PIkB;a@Qd8C5~}~5a4}KyM~DUhsr_yE8>oFj zcTyBH->u~D2kao5eE`9hB6WV=uaPX5SFc0OqUsgT(3_tWt4naap+FB6GF0H4 z05Tfz79kCOd#XQ?9Q!&HSVY&M_v@?ssz!R$kW8md%F~A1NxdhVrzsq|NS}SPP0BeT zHQL?BbN^Cm&B2Xz_RbSJLu;K%FZZ3MztJ1@Y>@w3D&arwfSSuJ?Fdn3sCrcJ%eD$zb~bwa(wO+aVNn439e8`5DU~Xtx;f)pD}(zqOIptUTat z(62w@!_Vcb_PV-#fj~56^KJ0~Tt${mTF73MxKnvnk+B_-aRP_-)gL2MTa zoy=I(3hMc{#)^&7RKC3UzZLG^X$^W4W7rNUoVKCF^z3BTu zqrC6C2XEqeWugTtle_=_sZ0iwYip;riMS063_>F!Zk_~$n-bM)ljo+?BlvU&USL5j zz6N2;ZNQ$X(;-XxpI`^n(b8K)Y>tYrGCn*F`t(($@$AE$s1OOt5IjLdeU23}?$?sT zbE$v}b3*Jvh2jlDFDja=Z=jlaTW^b%K{rK+Pc3|Z(M_I)7|lx-TmX!)8+8Y@$b%B!54G=bOsN~xPlk!;`tUinHZ@09%q{B{y_CHf+yb*F&4V4t)amhMlZ_| z`_*g?8b#>dN+|=vrn$YTb@2shbfhq`+BWQ!kH6Yw|#fl zCV1Q~hQ>WU?O3~j+>*}|w(adfvnwLarhp(n^Ou$9G2k;q3CmWw&ZWuIO!r!)=(R81m4S9geYf6tT}c<{8r)* zxrTon4H?Gr@kcS|>EFK&UUjOf;T%7P$Vb5+ba|oRQDLz#32;90mTfb^P}|F)F8lgH zs9^4>jwnHt1JU$wnfrsNK)JdHsq*PiTL~@GI11GK{-x8bIU&>Ohz<)G&bXSE%X-C6 zg4fk|GQAn;@=x=JvmXC#E5C~Gy zbc+uB6a;8QNjc&Lg8M5zA_UL15+c`Muo%AEfN`uoIPu%1qAKw?pwCAUULz8T8-7I$N!J6?;q0}Lg;arVE21C;Jm;Miqv2OKW5|b zKwHk3_%(HB#w~Il%W!_MT`LGT;ctE8dt#p-gI@V@9jYovyKd^+Mx!?lR+sW5fqhp( zNzvC`Sx$OK$TLzl&ojHC8+@IP1ZQh;wyMAX+)YE9e_&D+-GlTD2lF6Ooo}vRN1Gq) z2xOf&^YK5Ir=mGIjTTQAxx3bT z__hlU7zA_>vg3&jwHoti*+H2I`s)M!q87~0v))~itD|x14Cmg% zkxRMhPog&f3y~rjZL!RJks)VYSr~;DqtzVl0&B>&dtY60Ar-?%=Gjsuw3YTof489E=I``!YQBd`k-W_!L0#9hJy2j z35V>w8CRxN?&H;WPwQP!?sxX~UpVuYn0o)Ju)UnZ6C3*H)jWF+;R5RdDY-f4`V6d6 zz2G$km@d_7{Y!9d%`)gE%j5HA3^^96AE)5!H(1(Kkk>WWCfT)|crxTJGUp)@-q)w6 z{nu0XgyAQbmzURfbxC`6!x&u`(d+Ml+4xRa|C(ZId2?vN{PLVcx%1=tUnAV>6aM^% zJF#P;rl0ZYQs>{T^SEpiv)VhT-0pF3lt{Zh?6ux}>u(DUUMfZcqbt5y=Cwh8H|#n3 zBADH8$N}GK0(K)rTmXNZPz;#JJrXJIH`v8kIkB8L!(9>AIiU>>5NauF-$H@EF0BVO zSX5k-hreA$D&x} zC6{4;4LMs<%qR~5Y{elL>sW!Sc|;7%El6)1y~(_IQZPj zz>JZ=d3__hI%8=-ID1+%fHN$oUA%z)^4B3~ATefy6e0rNn|Y&3RvFiZWE=yi2h{cn9lK4Jh9xC#AG! z{<~zHpH0`s+dp<7gee}MYLDhI&87B!!VURwz;>}FvuWJtelkG@{wKIu*q~1 z*`e3AIp0s~dZ1}OWcmGqtvk7DZmTzE27#(I8IRrv#X5P^$<>WZSFIO9h3@-8h1&O{ ziw(u{s+|*DWErv)>L4n? zcSM2`);|~7s-5?+$Ltn`_cbb}6)GPU8TMKZMPB}k!Onp8m`<45?-=%hh z&9%4Sz;3cc_J?ZVT=S65=qY#GNe|Iv8!{Qf*Grd|aHW=GmwAe%m@1iE#%unwyAE~x z4QJ=5*#HD4lup}o0B3pAJ8bqaM_Y*Qff%!k+#Md%{9A(1qxYds+orWqE|%{_vy@Cr zTFgcxb02xOB^4X>)pq2MyD=QiT#c(dRl%gC;CJ4KtrAdEg)E=Al> zMsysy-L9y%zL?IZRUs8o(5{!JbZ}5?MEc_kNstrOhy_a^ErYzsAh!kUNb$SB2d`wk zI~ojy%o?K6Krj3p9k9<|vGo8%z6*Yd5ZGAk%*IvT($HU<+Z^OS(%kq0)(5-3S(=hQ za$>&aOJ%q>urpYT5R|)9!`!|9GER_@Hs=oi8;qa#wOflx9&92G?V5clt}=zui7{_A z*=Nys&!`n)+8T5u?-fU41>%bZt+}l8BO$4uNbC3{lk;}?MtjaHl{MrQ%TO9RJweGoCLeGUbX50F< z<|1az2!>Pi*ZECva{C(J<2ZtugoenDb6F;TT8OLeO%ydJuXW@kPSz)aU&`)RO{Ep3 z_9OoJHAfY0e5yoBo03ktA9AAc0rzQ?V2!~GY3em0i(kB~@j}`=dY`fs(y(tKD=?Ja z56WFL?m--x4retxW-Je6w5hOLiO$HQbej75D||+R$o_-iy9a{LEf2>?>@4`?(7~ro z-4hHPn|F1?iW^bx?$-ZBmW8t_ODC~c@zJsg@>0h5Vtb6rixy(7 zS&7buu#6c$Z{-^*LMtlbFQa)sQ*HZG8Re#ZyrziEhu1e>#wlEzrZ&qfsl4T|`nf4z zc3Ppp!;te^HBoZt5M38(Ot>qcOg3}Vg1>gRTdfAuSulu;#XUca2L+M#Pmom<8MOxuXHr)+@}(9Z>~_z=quKA$%UpYc0+bU$zDOtM8co;^n72h zcxJ+K`5}j`q==2Nzsv*F;nk{A^M>zmchyd%3%1+iDs0)3@cWvDMibm=Jx;<<-h++& z`Rm%Pcof*dY3qJjvHm#Dc$E5T7VK7x5JmEmU*9i^`SIO#7=Ofg)b+rxLVD-cCKf-0 z(aIC!6AOelYcO49B~{HZWRr8VJq*?G`hHe*fIa#8!70sQ$d zjW>YOkazK3Xci_Mj?S*(+9Ffv7sT}7#q=ylevjpCRxf%LIG`>TH~24h`NT{A_;}ad z72GzosS1y(VCQ30(zA}PFqEmP{ZJr`2HJdw%j||m6dTW~k-yH=Qiw6#d*VnXYi~vl znt%XYqR@GEyC*BK<43Y1?-}QgDn73k5Tt9eMjqs=87gij7sLsW(WVmetu|c_-o$rMQ@^D(@mQT zJ>Hx~UynY>#_H}4F~MkQ@V}Vs&oikltz;9M4Sn$;^RLBX8RF(Rl98+IjmwTJMPy|UOdWriHu?a)g`ept>d<9WhkmiK8sE)_a> zDBaWKE!@iaP}c!)O6tqB9NwjMyE^6E1Npo8^c99hTJ%iyAtHAM^%>t6605X+#q0VT zIQ{}tN=tyVIr~HW~ox^BqSN;xU(4G{2yJe1m7y$`KYbNo-8W+{) ztSW>y?+fnbgx--4B9EEpc4v(l$xBJc1#JG@;g?r%A( zAGK-<9h$DR2wFE=f8Cgx%n5v?L5Rw;&Q?^;3RBdS)2vIM7oE_4Qb-T6A%bsJ${~+x z^pkX33f}H9XU^U=z?fa=_qzJ_Evi=On`*&b+T_gFZ|VLFU+Cw2XnqubA2;I+qTiq) znos+#92%luok6q{8lrz9r?-fVzfX>>ObgwUf@K?Yeh$S?4QJH2_L#$<(Gl)uR1%yf zg<9oNI2uil%(f`)dVIJs?wRP0?9Y+6e$Uu_wA*rjqsdV4on9tL+}sc1tcK`Vy%`6# z+O-7w^XEp1NQXVAs@?qKRKCo?d8|~FVR69i`F zcJ}o5G8rL<8+9oB>7PD!8S---O%iYSw&}D^cQ6X|+8TOAHcyoY5>dj3eR2U!(n?C5T9(SB4x7HngudM2LL{0ebE( zjmo=dzdb@=-SH<@l+NuRqI6*8ZZC^D)2HeuW7f!1A@wCsl48h*mr;r9cJTKtnBNh0l0oL6-x7-ei$hOfE= zxlWp=@fc4^-3*bvrm5S4(W8B%K8dK-xtlnaSYDFA+oVVZX1g;bK%6yE|F!BxWMl9z zC3{->Imf-*kyhjSio090znEyRlwvD(qGmn5GAYlV&b4hmb`vL`c%+;!Wq^Ea;TJNd zx5~Xs%HG+YeoLP?;!WUf>UiF#+mpw5yv~cbBkSL@UXW{=@jcOvShc4m$N38u;fDdR z(RJFRg7qqP-Mat2P06tlPP7BU_+0xI=4&}^=v{*~G@#k3uIz6mnL%QEzPk4G64?{mEbuez!xm+E{ zkh9P)R)G~6z}>%+@qW+De^p+t$HEaE$FT%mdm_chr5sDDDQ__ji+jmoR{Hrpq91s5!|olpDpJ>S;eEV zZ<_xisO_Go*LC8kH90yx-q2wZX`g*;$8Oh%Ie0&lk$bEMho2puGa!cx2*T>YFY(%U zm)G>u#Z8^D39g zyJvQWEGpnIu_Jjc3Q@Jr_leaD3F)j`;Mzp4pRg6@kF^(OZ%7f}9Md`0vC{7jx%2_! zHdDE^c3sabsq@VbBE$j&T_~+OabJy!h&-jfkQn!?e|<)#e+8H73eziHw07~=M}ZaKFW(Q2tj}bW*ZDx@ zC>)KLsRlTri{VMi0C76rUqdak{Q@HuAC=>nNwk*NXGAxT?XqTT$Ll}(-)}T?4_R~c zo1h|n;QkQTBKuV-ZaOX{Eayqa53c1g@?+Pal^ZrX$1mC$DV;lFUN?)ymGf2x+dL;$ z_huv_x!;)Ty~wc7^+lQ7zcr9Ow$o^<$!;L|hT$8NkIA9fbng8tIarEH_hkK2R!8ot zZ0o;r;Ti-Rj#)M9p0eH6OibKwIk1@p8?M%#OgA6myn5OFja)z}Zb(g@&2)6oJxZa% zK|R;}lhZF3T&&p^&PVL$3Kl5W&mQcN9w7Vf&k8lgc_EP#H7<^Kgxoc@*aR7TmPt?X zbw`FA9er8*f)Mj68abhfki` zLT^$7q4uM^ISvf?%iE&{Tk&3Ezn9PJHNTtK*=YJ#y(&Wo)wuI*Kr!5)GmeWzTs}5? z-plz}#FOhBh8;PNitjv+d|z~UYA=dsG~33L2S_=xDth+;-0(kWEeuo z^)8L1KmNcirCbh!65|IF_qFQfXOG+ZcI6{!yg8H09<qX(J#0c0B1Oq+RT?bha+|f5*3TYl z1Jk(;mf=FJI%n_Dik(cc%;bo^{iqwcKz344!8X)w3kpPBQA{)tI@H`T5E2SFc4NFB z_n21Jcq~caLl9N|{GrHSR4=q)UMHe)qSs+22hBI?r_f1vgQfWph^!DJ40bsfjr;q7 zK$z`J<7Hyz=ZqR7NAU>700KpGQ5IUKx9gKWva>?c{nF-J&mUq9!F(+px5!&qHo`sA?z!}Y99}v%i|76 zI(N*dMiQp!%{rS)Bp7*1T%+a<1j(%Nk1ht9Js&-~Z5WjB*#8v;A9>8z>MVS*FAv+R z@rC%0{SV>gc2~=&_=yj!wJWGzmPUdr68CZVz3%7m5Qv6{4yhBEcajc}lmin4TxLUg zvoz^(sKP`ay+T92m{tnZs!&*et*4ws3N<*J#KVrd8+V-04c3n^SvkUK{LX{py?Y(5#PVQ$Xl|Y8e-#9S z(1M_Ze?u0!G!`aC3xdS2Smn@y;5flU;$+-RJ{Fk``E{WXCeIE}eH|`INn~3xK3&eH zPhBF96?`_Fw_^SKnB7MVti(ZW`TSxB{ib#*qmvWGLId*2JQ7E9v2^=o`_<=jt&=W& zI_(>#{YyvFO9btVtfts`_zOZ?UI#&TQ2wfU z$r{DCDjg!vpvKsVdi5(&3eq1=?p`-K zR&H9TO#0$I1U6d(6)J^EMy6*Kz+}eKi%*j<(k*C<`BPQF4~-)F&9S{C0^e)k(F4fL zl&w$jX4E>~Pm+i&#hwV>}NPsMqku9oGDw&hm+ZOFttf1!y6tR6&;<{rVaeASXcbg@kW9 z)i(}&AvSL}Cijt#Z*7=s^CGrr&t&xBuT8KtmX+MzowsTBKjyOaOFNWem+8I{Z~sNs zn*sme(^UMH z7fR+5e*!#wqHB;;d^&d|LP6f?8cwMW89~}fz8vU=6!PY_vc>3qe~$$td5~ZkTUBP+ zRH4a-bXbeAta%g^FGw*Uub&EJN*cX{J7MUEF{gVCcIkw*1tn?D(Rb!bDtZUQ#nwu- zkS9FZQLJgcBwZ@m??8>)TKv49JI8#;mq2UzEEU;`|0i$ z5$`P~UH!0w8Mk#-88J@rKvrUNf@H}g)7TGz)~yGt4UcWB`;{|33(wHNh#0t$J&8W6 z&A#IT^PRC*$-Sq4R&CTOi(j{ZE;m0Mm*Tc5kV~ZY3b`+OWxgYk%1kwo#Q7jEy!W zuU*iY33$cCl+UIe;T%=5N+L)jpIvt%0m7KxCTMx3o)YAF*=(oG;QFrXz@N#1Fh)PR z^;b_sm63th*pA05*`J%y4H%(A;=rn*+P;G^|!U_N|b=D8A)X zc~XfYXGilDjS4JPda~iUOqe;-#AJ;F4i*ueh!$A{ot2h;S4dNP;y8TwHX(H<3IgeD z!=s9+Y?K#51rTQ`k&VIYput8@5_!VtrLR=zsM0S>7gf0YGkWjdb^<0cwJUXFhot% z!Ob8Xj1&S@lWnYAg2~)>G(tyZYn#&}np-?mKUy~`fO3b1b*{0_f(juxV%0C}WKYjI> z7Y%O%@Dh&;_SU9;B)y614i7f;LfWL}iTgWnm5q

PCm9!XMdVF%gIAbsVIomzd5K z!7?eHXKR(^5iZkbzWHkp;LJ5)8WFNrXr^3|g6ZdV(Q6l0QmO?if2F8U8TIGCs>@X*c@Q@lPq`Vx|2(jo=?I ziyL312HQ<=(|-AGtjCr+QGpW=rAnWe-||h7yemiWA}m)VoPg6vXJq@PDNiwaB1AFk z`7`2MvCh~FJ%PHjsdXH3-PUtG6vd?kY>-2A|6INF196I)RH)0?Y>R?Iw2Rg~BJvbl z)!d|sI1yq^)<=JyerQ&}AfSdU_orOFuU(7l5(wjPTzT{@kzMov>m#}S=*C!}TA}Xp zNbK!2wN$x^?R3N3>Nh`c5I^KKIDN+p`|K27`Kl%+Ycv&$zB@Y5f}BUU6@hh&=azIx zTk}{ky7OD|<^qorLomJ#J^EE_Kc8SCu z^U|?$7MAuAt4x>4otFoppk}OnhLRb$bjTDT-u-!_H2*G33mlv0_^P-8Hf?@f9wQ%fvZv_mKq2?$b=;0;`=;DJ7_vR^ zrdD3;R%s51>Ay=f4th41w&9memAn~?kf5~~aEG^V_J@8fNHsQerwBl15asN&0fvk`@2>*VhR&h&~5= z()(cCpjXL|LKIm|&1Ol|@;Ohgk}O zqi6|-dWblzM0d;IPDSYVw9gpMCV14HigdKfRk|@k`ddV3|JkznD2z*o9|DH`Xx_C< zlpTeTh`vMpvwvlv;mZCn-<#=hSRYLa_V>`++!lU?oawO^ zuglUNOn}xr^=n4Ua^#ZE^XSrkej$HJc}GYp3lm3}Vu*e-6B$9)^9ozo&dGteg$0{r zB1vz87jc>^Vw3W+H-cTY))g^TpBT`5kCvsw_yvd5^BDWZ#u~c}xfFw%e0bZ5Qstva ziyyC7iA5&mPOn3Er!VGdSI{J4^^!;Z24N#`J0GRdu=Bb-2a`UNgC>^b92TYSmnOp*w^H&@HpBC-B=jP!?@QM4) zoyeZV{5u%MCk170vO&ea2kz9-O4izdwJu=t>}VCj(_e;Ks#$2wu{k*Eve~LXStU%C zMcL<*)u;a0h1rtThp%V#YnbE4zY;ty)_<|WiY2u2A{!RLSsR~iw6c`K>&9iZ_o^~E zWM!dKcQWp!xF(=W$ek4~4%JNKA$hhtT5FynPPOrUnd4LfE{5#MlE4$+I8lig3%U(w znW!=)R{+tI(68G(-DIcs#F)>z0Jy#~EZN`t&jW3qq*8aQy&1Q6tazx!d2MDfe<{Lf zcw!^J#Y;Hud68cibFiITQ5muuLg5;|EvhuPdIn2A!tPPABz^-g(DI+s#S;mi{-#}; z3;M`!EN@ILd$rv^W{EAk-UiAdG0Pw8Q`uau)z!F@m@GmnNMp?^ol7Z#07}FI%^BN& zF8=BWyG5I^RH0UF$kq8g^RucLITi#5qyH&Pw-<-qc@sZJbBn8TJBJSXIUCl~c&73E zxl{tr`+YrbJ3M;nN6c%xC1PL6HHCAwZo<5T03Ghk3~-@eVxoDRurT2BTdD6w_ZSMZ z?kPJ-OkSh1EobvzY$}9ceW9(xCl9}Ezv_uIdrxriUP^?tnkm6`hKohP#xUFUl+xqU1=&=O#KTibB9x6VcBHpTR6-rJ!~KUvBqUf#=VJ8e<^@ zk7!tAurYOK0NpyNfKeWIZA{kM5=K`;tuzp`vTL|ZOGeBh14?yyTrOGVA3QSQ>lxFW2Er6|G?RW!?4 zJh7rez1%5y51$T=qV8S0vm14aFCYgWpVeA9#S0M4USpf#k#?s4t9py3(4Kt+-z%Ir zuh?&R0`Hlgt*J_~Yn?h@BK8j;4A>2`oKnE+H_ud^ zC=+@8Ft_H&V?O&ajWwbl+7dzA6DC?$WBS`XeKnFlO1?zXaWJ!8Dz6 za_${ISGBCEDmT8=rPfC`9jt|;{eogD+z!@ZR0t=NLSFpWi|?^s#m8i+a6AybXL-I#9VNbr;v0_Zd6PmqiA};~ygK;j5s#?WHV^sC7;A&CUAWj!>PQ@se?PbJARE zl0n-I9X`^U^I6D$%rKyzcu?T;I{e}t=eErGra#tt{Ubp}G+NsOkN^32@(90n?G}j? zmZvuxlS{gcpU3PR6tyfa%)VC$ZQ5o48so$4lCw`o*HF+PKam_aM77)4Xo^z zgO>-r_e^~DjxbrWp}}LONugT*nPfww^j3vML>1qnTzvYf`fVRs(qPagBp>dL<)+w4 zm**+!5aA&q*`>^Ra2JaOEcR#6w2&i$RJ$DC(tP!`nT&w0O(_&3TI>sdxJ#r(-et_s zY4`_fgr*3MZBeB{r&qE-y{Nu9n>jnSmlC7u`ctlHIR`X}o(@%xCakD~ zBd&3t!<$hj$lVydpkt-yd5WUwDQnmYdO~~RCcop#R|KDWZ+jNlP+u&RzBX}-;#bPRt;)DDnp>T%E9}F8_=YI1G4P|dwm(NJ$J83lj>jL~g=*Ozs zpIc?4VDH*_r@NqCrM6TG2EZNjc)niOqAUX;T8D)2!ue0TajwE zDSM26R`2IdmJE5Z$xb-8o_84#5P7o?(nv0g=gysz(sQQ;?W^0KpYB7p)QX7be69~_ z?z8#appjVrQR(oMOp`(O-9*kc_Sp$7^|yHN;_L#Iy{C8ww_3$7G&?B}2sX z`G5lQi)LWnP9&RX%gS(oc~QZS?(3i*%~7nHtu?uH)yxbu^cp@Arwrw*VHG86*}@Ab z={jBcNJUD|n?EtViX(xJ@xGvA)X7SO1>pnS=KWe|4CoXx6%ZNqip1D2H@>;+3`FHW z%P42h`Dh;Qm%$5Pxn5<&s|fL#eE2)ug%!}N>xaL3Hll+>FHU=;Ncg5p`@3yc9tSW) zL(s+Td}Vkj{V2V}OsBt`9X-2hdHk|V^>y>Nmz56x7{poSE(6V7{mCo4u@4nTC9DIz zD(xHlC?`uSXV@SimrBSVVaD#S54PgU8g?ZgTC*zBJi7lq>M!n-d>uUsZ@>P7EJH57 zs0+pj)cta}&r04;ZmS3FuzUZ5vbTV$a{InO1?g@?QjkVMq+3e5q`RbBx?tT9^#v8-oAP?VOd#$|v;?~8*9bb_MzR2d7bfB_W_n_0nR`>WKN%+@+sq_2wM+fj+7 zC-`(Y`CX5IPAxcsL^La3y__pA9p`3pDdYbtK3%AO+EG+{xAowF}TNRLqtNt+rbUynXcZ%|A57KRm-pY_Tg%c#|%j zqxY3_JkP2SD`e^b@=q@uNZjL_#SsvrwZsWZW2fH;JbLu#{$2##-t5o)AG>q#9x@Y; z;SY6VrO7daK?Iss26^i4N;n1PW2U)BRTZKNnz=*inJPi*<;vxt`tx~uF^p2-@%xm| zbvyNSanviu4GXs(%gOHjH5(}>^+m#;7I^SVdY~S6#e zv6ozGBbbIt0;cSQ�*2b}DcEZ5r;Ost&F*O&w(;&@RjuO)iR+#3$Fg^xubl$eYmH z&F2!kem;J2?d&jgv*#Af)>@;e>~AH`UMOs4V^bkhhYR-NhnYFwQ{4%}r9vYK0L2wC zp9ZzN&9zN)FlzWbJvvxA1R<>Esf!n-=2Y*22^srqP%4va-V@j~PPFRH%z3&mCb4Eu zpYbvy@Dp<{NeKFA#Hk7Wuo=sb|5Ec)oQT&|vMAAZs&p0JrFw11!VnggMi2@~-Uk}z z>m%47GK+WdO2BMFqL$Of*p5tthpw*f&w~ZhI40e|j0}p`uU|_$p&y+uAbW|IYz&KW zy`xVZ>L$595MVdF@PUFW(!81}%28@;Xs+Z?jv(fR@y^$_D4w}8l z2^Zhb6X6weesh7n7EPlEjx+bonz(d1${#;|%u&lJcDu`Z z-Tqy9NhyzNo5Rdca_oC^PY>OYl(klU2>U7F6H5V)ODuaXo}CKHGp%+{?^}mF9dCu9 zVo7CQuM7F2y*x9ep#oK=dN&n$G9Cnvthy@agGt&r`=cfQ-Qwqkz7GcehplM@ec$7O zLPB2qOU7Ux?hklNn@C3m=6?Au1|vSdaAvQ$KVSMp5ki zAaua(OptLc&i#{{R<#rH%7$l9@-_PNtxxBGusA7qP0$=|6WS&{Yeyx}$}nA4|%wf3`j#@YuzU@wo=`p#*K9>U>p> zSL=HHp6kGwG&VN2)Y(8N+CGL(f3LE!LTr=?m||gqtGoC0@>g^?T!vkBvQwCONe5DF z?}X2*vQ*hf)83rOpg!B1&eW#t4gNq)!sp^6rkuBRijSKJbbNw`Gsh|+ix3sQK5IQI z2)@@=BIXnlf(fbhJcM#X-$ciJB*N8ZaO5dN28$XKA@6tF()^8ugw0`KsOK{@}0C;i)P;tMWk4Bu$rsh93D#H;ge z40?&zcE;QR7hl76LUwcOai93E zg@}iT*G<4Ucdb)v_n4YVtF2S*vD@tDr~Lw()gS25IRnid;`Z`Y5PP-*{0n$mKg z8hC~NRQ_lL=m4>$bECUxFw0KU0rxxB1ZoIuR={g)k-Y zxnj*}RLH8m7{K1gXd&ydpb}1%rA$#S)2P5qXd!lQb4WhDC4Z}Yr}N#D8I)eo{1R50 zzKJZvjF0Q-Uyk+1$C|WY@21NUDfn-t85><^*uRub9tJgk$wQxzdDxU%Xq5C#x5F?X z>IB_@{lY5hBa?J%*mGg}1DAhonRL^vKaG&DZ;pCxm{3YcPY}$_mC3PlHwKRqh?owA zm~DH!{n*iBEDKmmcmhYO-&*gOS0K{HK#~xk&ZDq(7l$HFsWvVlN z0#k%k%kNgdv>P=ACBIX2v*fXT^r1fVdz{I84C9uttunFUuYyikfE)1e$rOJ0 z55`25Ku<52Jh@xLzt|j+V|996$MawZBMrcfUhZWqwE=5j#Q=W)?ink{0Petv@#Fu# zh#(%un@BRrg$7T%(`{u=F0N;soRda$OG``Di_SRij8@TxmB$3h=_TzEGzKO(!kwiR z77ArL+QKryElFR#L%H(ee`6)Z08(t5A@nAlEIMO-J6YyH&42qfE{!S) z?2WFXqGGP;gr07BI_GadDfN9vMgl|B;VAQDqr`QO`zF@|D?Lry>eVeuJrxR*u?vRr zI?DU4sgc3A>f*i(OkZ!2$?-|~yN-93p#N;kpN$4`TNkGzvj4WgY7;bC^TSak{d!3PhD9V-uO=&Et0%l!=WaHN5}YY;_SIA)H0<7VBZ_YzIvMfoKI^30cUd?b$xD+RS8*CpMm!RxyS{ zmb8RgxF3L`*Gt0Orzq)l>uOcEq;<+^EjuA1lH@<^Plt_@c->&c(MekF=D?Uwu|B;y zm>6>(ND52@gY)$;)+&&taF{C|`O{?Kt-1UYG=DAm1W)aDMDAiel!@|nc&%e}a=}DA z2ZE~HgImMFJ`rK*YLSGjYl|FMDle-)&DOEkip;<5wulOCMl6EqeSf=|5ovq8+AR&Z zG?i5m@V%VNT5$Hrv!mJvy}@*7^`b*n$LgICMQdV!78X&PlL?a zEX>i4fl7UJ|+XB z7HqJo8Wr+i<)8J@23)o~Y#c6}?WvuNl!^$`3f$iDnAdB|>BJ2QMF*F?Tb?7~8)YjN z^xb_9tjNhNK@0gm@lNJ|@N;Jf``T&m(`U2!$`|Vlch4N8!^$3P<||DB{9=|XP7(qv zjb0!S`fUR5;S_!x&J9p1{US$y%+nPBy+t6>9nVVb=jSJ#g+W3R@lQHLOQLxV9~KA) zcnC1r%!Z^gJ|38Gw0dNSa{G-*mW1bBvG&`DRDM)#feXRxIW>&-))8#Yvt6-%t(y0R znAC}0*TgG-yLqN_dK&g2-+fJYz9F=wlHQ#jgas6S-X(Xx_~#mE$1 z>8Q3p`s7xSMWz)HnYQ9n#KgaKmXb#00XAYus4%0LdC3hrKFwF(oXr3?yOw@}R@e3s ziq5}-;qv}hH~`qVjzhB(ubcek!s{>{S3ua~0v-L=5BUJN^5NhyuQKuiZc3P%`z&fA8@Zjc=_%gBhB zh>;KT-8`BOpmcO9Hg}JezpKVsp`<@~Za@hu4TMdI#1k&SRsPOszdwY7$qKuMwupV9 zq&a_GjDLkfgdoSnR1pFDU=wCJ0BC-k)HsYm4EKP$TmTc`nvY8QA0iICm;;d9*G_r# zfPs6p5~J=NB<$GOyEFRj(V`-bdv5RN`P1hD^o0#VwW0;qCVrx6@!) z1rhNQ{}6Y6xmElA5B+oCJaB_iCRvZ}^?90UiNSX5=Q0XO18@zfnJ77lS#J{~npTyB z{LAsrV1YuqrHt^Nh*#uBpAIo@(Y5OySr8IVMFU|bQD%~%?FhXfM(qHH{aJN``K0Inu~*ZV zCLv?h)ilrRZuCsd+qMPg_I?^0dffsZ$5&3YGY>W;BSZ#F6i&(*CkBONUU-Ni8_Wz;f5ULPgsc()t7++uWcGlCs48H)!$4IT4tkcfa- zB%ap=)RqC{U00tsQe_DmYR*8JV@^NY?CSRbl`H+;FD~*UfMkY zZ?rmZl4lX155kffn_D1(!KfS7Y6J5e8@foz9Slk1{ zT-ZQf66>CP)_luj!HP1T=adSFg%rG^DaHqO^AvP z*xz6hxa`;eCc|drhZ`N?lVA({Gg@8W0bSsD{q*$Hen!UQYrh(8d-@_tb=SUvI_~xN z!&|-BkO<4dv6c7Qk5#=)G0<^FuXY8gI-j<7NV}3oWI~8wA^ZTur@m$TIAN?Mzb4Jx zC}3UH0ZM%R&3@orv7?Z7euwd2h9s+p1uU4Xns^td4ct;W1e`tBYV;zmv0ru7xj%fYQEp-JJ`A9K?UJz~i4nvs&IwC;5-mcV z9=B|6XO~X^2921w>MAXb;#O`2Zzo_Vu7a9wsRS)M4Tb~Rbk@Zz^e!q+Slz?hDCc~g zs9euB{&L)o?{+GYYwPIH+7nK=sGS}ldme_CE`52X`F`_k{n4lXZ?3O>8OWo?{AuXp z7~9K>I;5;H)o_|c?E(S=z6!0;nLk;(IJLkKknjHygfJHHAyDWt5<@bY5mrj7_Xn?b z|F2^6pVo*n@TD|`{?S6aBg8$-_g=Ax(b2H3VH5$MXw%C4O>7^P@=$&7b0 zL#3YXt4zSxGaQ~gYa&BhfQOj$rK}(i=w)3W?`K(&o4a7n-Mu{-?!tG)(P0B*A!3n5 zf0_MvTu0Hu4pV@Rk2*

  • HInsX*zj@~VtlZOaD@tpb{rrr+l;wl`M;bUd%quf^+^ z5~v3VuL+SKIHYbYQ)ktJw6gazt|cD>{0Os?jf_&ciU1k64a^=6Srx`xOrUW)W-;>C z6kb7vLER6~s7w<^C*E02FV0YgjyWhy{=7bT!eNvno6MQ3P{kNqq?rdK1GuyO7v83c z#dgO@T$>j?W#DX$o0ZZ!olx}i-GB_|XY@2cXqUQStRYjnlpakid@G-n$<=BP`CjX!+2Y-p zo2>Q^_WS2UvR2r({^{lGSh=d6YDgygYTX)WI-kV`5kPod zPq3cH07U2;R#Y5>0=@YF1on~3EG8xH0lALkzhjjO`wg&%Wo4{7buRj)HQ8ekG>Fts zzU?lPLsL*kkhD`Y!XvyL$0+bPPOfeY&7)7!wr>Ty*uBlwAvTUlX1BDo#6tVHc?o2; z<=2>GT;k=DEGDAmuFyr_zsH$9acvptmAdSS^te39 zFc|v|_n2m#qCG~DYz1OW0l-fNSJ>io$?L|^jYuu^T@3j@+6_C#N zXFuMfVLQfndMrk>Lezr~z~tA;-JE+5dh(ongCgZZe#i^)Rh!IhxJNVx(HZco?$;Onn&^UZ%w=A`PCf0IwWzk^94;HHhIj|e=- z`&bHoqCAP-Sbzrdn2+XWjC6ed2FbCe6anMn^)H7$!0h_IY$hOQ|5Zz}#OC<*gK zL?Sq0t58A`qy4?}${WaED~%LXK~LYkxwb*MtB&*_BS}e_taHb=r}gav&X^ni{5oJ< zU!tA)>G*kEzwX!F@2BCr+}@Wj^Y6?EB6b&S4i!sQK25qxTywe~Kd-GYf01{0-i}{f z{OFxbLcUY{D|dEoM{jhXofHj)J5+ps!&Oh*EOKG2)_51Zzpwn=l7K@5=pihU2;?&gjdR_Pn(n9C+^<#z8LO7VQn5p?W zp3f;kr8`ZL!W&wk3Zy7GF8~Q5>t*yByg2gat z2sm7^@++L4Ut3?H+%P*Ax)rDuO`i51+<7KDf{3+ZZ>~b8BY%9nnH2DY@oC40z!FgIQ7*((11d?IsH0NY_RW*3;&|2Tv`f%rn!- zda9)GGMsL&Y67Hwgy@h&0Pw@F5O1P`QEy!7;GJ0b} zHu*Jh<;ZAdnqlYiEk9{%|GduKSC8v)0Y_-YX`Wh8lpOAX!FGj|_cbot&iIFzn3#MX zr%jB&v%PFMjd9B>wN2T(zQc83|*zEUu@ zkO}1LP&y+FnZ0S207SS6$<1#Lk^9^fA7J1!MtEfG0IgGf;djBxK#h|A%4`Ul74Jnr za&mJ26QDL(myY)%#b=22?2ToL9Mfdq(axL8&c=F0z+;AGU}$*c1wP}DI_nI%(+4)|b{w1!uiW6%e z27AKa`(Ks8AKxUqMnc)X#k{-TAa(RTiDMF8S??Qjz{7$lsdj{wkR5nq0fDs-1R@eU zRZly!|K)|g-vBTCgp*mm(@G{eJ!NkM?2kJ#gy;?cH-dEp1jCUI{|ZR1DLi7_55>jI z>Q1({J~0&)%@!!i=I{zVz)(9to{$0B=ces!v*0_xeMZw>}49Zb|^dq}5+qOI%QmVj0Zs*V#d(ebK4L8&s>{XoE3CAPw! z#vr11qJYh%K8;LL&6MUlt~c@Bq~|dVFE1aePHM5Dd*2@Tee)LyUFzNR6!g6re0b0E zo)bWY%FxLW1Iar{=PheX?@=JhXjZ%qb+S_E?t~|~Jl-ll3iw}1^shy((;Z&-D1YHJ zkJf593mW~BC$2aSXvB)qlR*#zO+yTH06_k9T{9=$e;{8DkW^M(<7+wo$ap?A2u5RM zJy5#39>aTlr!1(zx%gC+r!YV&9?bH33=sD&_7a{hfbbXFo>|_M+kVWywz%iVd67j} zED!%ueh@7^EP)fMK6)@Pje?u|=^8T5+eF#j}W+Ti;_brs#5Fz z1h7L?fQ!Ja(WyuuU+hAt|KD)`*N48lG|YAPk8bK+%e1B+83#oRQHUFL8YfuFprn5Z z`}7#X72Z@r=%f)!`t$4hR^(+MboNpffRPD5r%75bNcOn4~7>L@G(``Dp%H=S4RBvsb3X~b$ z7y}WFcZxe$cnRgEzFeW+J{93IEmSH0k{17_HP?@vCmey{_@POVc-RgwmLhzA6`yV zBse1E^`+m3RaR_pz%Gw7o|BUk_kit)O`~DbajriiddW!8G@$^O%%1LO6TGjdZ}79Nqg_^TYW-I{Y6=A4DZ{M2HOLlHK2PjLH-h zy5uU_+BpKcC-?_o#V6DeL?5Bz>G7Giem*FvgdDQj5!C<4X#f0>ncDaM?h@YL&HH(r zR*?b)gHG9WQfz8|1z;=&Mkff9&{Kq_|fU9C~zVi zn2tlX6^|}=k06Q%Lf@wb(Wsp)WTD>OCEE@4G6w?r6*G727n50$sXn+;v76%`TZ(z$2 zcUa6UO~Qjlj`F!t5DHRCR$5Q`C_IMmwg8`Qe<;e5VdJz>0M0o`iHM5zIKhjHyQ1%L z+Z_Z1sTCpAT3)QFPQCrrhDj|Z9Qd~y`+I$QD$vXB_RH=L%NGY1EG}-Y@nct?Yt`Ts zKGC&%L5wfW1krS90rc{A$eaL?n_}HtY zf7c4Rg6-~gyYgl9vB^NnmMj^r$v;|48RbB0DP+in_Q6GsC?O7s znHKuJJw)oA;Sx%TgXDFGj4dz@eEQK+;5`N`a52fiXGH)9-yR(`Z@)-H)v2@{w`54- z)2#HonaaLcz}M}vHwQ$TN2yqp&zvYQJC9Fy-VG$w!%v^;HmdN?W~g(zGd*YS?>qT58?ePfVj!m^5Ee z($haSCKao=;k-Yu4HTn0r~f-)@eiE)A*wgC-glvU4`p8iD3n5xk#32-!=Ec;0TZ{k z_dl4J4lpqbC^WY+E|tj%^mF2 z`3{^-)6;0NDqMQ{W|Jk8n6Z2JT>u4jRqQV+dSRP?(#khR=_7bV3_YmKO z0M7?Bm|e=ZwEN2Yt&iUqDox)%ttLo-<(NU0U-QC-F^d;MQ!XUTk+2c-S_KEPK=m5C7?N_HkRuk z(!q3XO^}ZS7!FlAdq`KV4L;R_{Mz)sL~BdHVR@odlE*Yd`+lof{|To7P~Mah;XDB) zWcGHwbQT#}(f_x+{wt1s;*nnEXc62+lJp*6h8*A?4+2C`bRmEZV*Oz$AVa&D!6^*y zyojs44iM84x4kenKK~4Md(5?Z9FXAv#kt;tew}owml+`A0szB0HCYRdelt4e)6JkL z{PXBR$pAFJ3T4LCa;ESkG-EyEt(=jL2c7Z(y`l(!61f{i&e!1q_kuEM{_>U5X9p9hfu*BH_M_xLmtS~4!X%ND{t0;9s2ya0B{7~3e``wwpZE}j2M zbxE)tkxzmhj~1MHTu%b~;d{T7g`Q0lhzyPEL7-Id3etK%0BF@!!_g=As;|Xm2uM7U z0Ah2;t-pT}qE$GLQ8dmjasN{&SqQ>rjVyczo30VuoRltWBf3=6xGnm&kswI3g1HjR;wm zJjJ@Geju-0)N~LFL@4s&a|=lyGW^{hPUbhL!Y%=KC!&?C1W#UyTz_HFC->5+Qv>(t z)#xp?K&G1dYf+tyDE~^)f6Vp^q<;u5mLET3oSP|+p@&R9lv^&$qo^d;Q3837m+9;w z?@2=P9vhJN)@FL%8wNj;)Z3&L5pBF%v(toEt*(v}+ONyhPi}2~&jC?r1S|0okg9|6 z@8V+Qdr*@r08XAnoY&OBUG=}FLjX{lQZ9wpy?t zNn@jtgT@_4{BuH9SF8{^o)}Zo-!l?M$^bkX&PLNt_nFr~8cY3D@Ju>_*7*1pGC0Yg%k$ap8~||#lo2_chwvV5N9C8)yK#1-@)HatMHG`I(+nnhk#Ok&s^Q>bUWsi z&heZ_J-du(@7dnBvh29HtdRfc&%d3O+1*#=biSitXJQEK?H%^yK4!}OISf!TrXf6} z&u^&^E;|lrr3;CSw9ZK3)e#%dI%A0Cp-1;+Ymi&U%KT=bL<@`{LtuhPFgk&af=w9? zE@y`*7=(Edi@RzBjIv|;`udsUC4YyPaEGGp(Ja@h z#m>KZc28(h0cF5br7q5J1AC^}B&ZsypIl*&tLcT0Xu+#xPtx zJrrCrn9tEFNI2%hMb4Ojr{O6{=5|5>3W(Sa#-4pkoexN9)uq-4Sd?Kpy<&gyqrVpd ziMTHrO(ymHZTrMLgSCd@Kh&z5h!DdHJ-(A!!3{VJ4t5Ty<&xC{{rv*JVWtbwi>>1@4H{RdD4Vl>a zlrmk1{}4J~B*}PS6r_zmPI3aZPw=TRWPa-Zy>@|m#_ZIEadUL7F`AtJxf4hb&ANTug*} zck!c^`%><&pS2OI*S{mvOS%7P2ScJciUcxFVCUe_ioN#vhm2!DP|%9sg2HZ1xdPf$ zk4brM;5z58Y|#x&Zn&O2Ho#cx6WbN~Kb{_G6A9=(VG1zmgc;`?e+t~b*xUETS`mhYH(jdbB)iG8Wv$26aKLgy zkwDBnpRcJ$r#76v!{Jj0uDr$g%SqlSLG6)A=4IwddodlI>&iR;TD9{*io`)Pv4V6@ zcQeFCj0k|;pTEh0ED6*7|HxuK(6!Kw1!}=X;*qg2+13kw1qB7x@T>wW5j5}a;1-W* z1$|L)0bc4cZln>|PswL(-3;g^%+z}%Li+ftvNQ?vuE=lw#g{Y^lo}w)RhK+e2~Uqd zAsF-WB|nXcDvE1zVpB^Co$y9Gq(b@S54Vus*l>;l1q=*K7qPi%D7NawyD8H3HY;A~(#N5B+m+9U#h4-#9YD?t(ZZsni9l3U4)*%GXSTzmP!6QYRhH1Hm>^LnGKzs@X zn07@8S~$JOAhMO}ZyWD;ykC>pGEHX!HxO3!M`k1AK?VvU?jjwVu-u>4`^G035WKtk&<^yj|F zn3`G_j38nUJ~Ms{Sg{fs-Da<~3_g2J#xg%?X@8iAE5GcZv1(Z5bH<+yKBR(p-t#u6 zU+g0cQk-{Ww{ZQt)AB180nb#|UfgW<2PV!gu{-KW{1T79KfvB1(jg z*ICS6kl?NL6zm`A8O9`Ge4%ggnPX%i5gP*f4~Vn_*~8Nm0u$+n$OjUs2mb#VWjM_B zzz=lD0CZ-*RRv-fGg?R$%IHsHcF7(}cx|?5O&MS>k;1t_%P34^<~{MVQCLqN;R-bg zbeiZywYAQbOjNSmNozXu-B>50`n@3!=BZ;oIuv==CCC|hVQwKN?}qJR2q@cm9I z?|{xvNIah{V;m%9uww#DA(8hD;~(Jk&8Np8_MMD_0)=}-Ose_{zGXJZXz|&!UE85F zFr@IEe6mK*zEk*-^-okZ{e;HD^Z9_wz+m-AO0#Ji3U553$3j+Z)mEiJOHV&he9O@4 z%H2T(2nh+mOP-h*V6<1GYeFjfZ^{csuh~WQw?IY4aJ9&3^@nDZeiO9(hV>E=obACUXxS#*7AT+sO(S^`@Oxewz{)oi zP?%yR#l7&z?s96JF3rPfWO|t}s*rlk3>ftcu`_^E2)izhfozoqB)b>&0+MZgpH4th z(@7M?FNU?{MsNwv2wxM65jyj0{rP5Rp`AbgOrlT>JUxR~_& z=;KqQAq7kTpM_WR208Y>y<3uh6e~Ml+@&tvfCX6Q4IuzUVPF7yXM+kJ&{7dn8*2lk zblnOM%L`Wydc_IN_Q%?X^fhi8O}2LfHr6EE_Hd^OKNX*;G9>$v%!LJ6_v=;%O0q2| z7hO8ELcg-nP)z|wnMIRvkR|ZCwuK@9zj-b|gYD?C?Ti&^O&XQKHI3`o|Q7EYkp2r)pc3|LtE$@`4C$bs|4PkwJ)c0bjn- zON!>FgjR&}?Gl~P=~@>%+I}eTv|cTCh=szb@6Z3+?%g;b4}vgNOkWp*J0hl5Xbj9N zoTX=S7#RUZr)c!9YGMGFJSQPz5o9j_q82=1jM4tn zrcCvt+~MLB+?r-O%Q0cf{2EU)cTmQbO*EnyPAZywqnQm6uZKo|md03>t?BvpbILw1t4%GLdX@14Cz_VlKn>c%fg*2i~zAMa9X>g=a)6>vp>r zuAr|XUITSB+C7Bz3pPx>!QrlJ(^k7@d?6zyj4Q`uGq#T1A0%<5GE`1OT(a$6_{Syl zIpc0b+eUFtSC}DCi^CJ~d7*X6=|mT?kB?&vRJx7X=j2ygM09o0ScF zmxliMVRJ{_`yydXdH*0xD&)Rf3Ey#>-TDsSAbgqN#f4K+e?r@}`9w;FJu!#%oUrYi zC%k;KI13)8XR=nKhq+(lU#AyI97%28uyJ4>gpW1e<<_NIFJJY!cdcxP+1tc4X&Q&5 zIfh;pmz0dZ?>j5{m5uH0XCHWC_V$!lpBCAl8o`VyDn$qffF)kHpIt_wkON>3_+*wr zR2DN}`Z>JM_g5}+fJ{f!q@tUMKjbn1P{uJqh_&BgDCSAn1aEVe{E*{~L^}Ws>xmqTiurT*F!D^@gTUgw$OCLt zp65wNA3`T$Y$aw3Swur!mTvd0jPQY?F-M>D84V}Q0+V*)p}p(f5Ipf=>kX5>SuUwq z{3|OKD%s2VMaKk5OfSr5Pxgeb?}Xvb+VXQ-$JP^2-4-u`k-N55LCDnif}Q7qT@Drg zDoag;F%n49rrPA8Ld|KL9Jc8wgU>BTk_J-Pq5TDR(zs%Z$m@<;BX^ihCpoxJr>U(p z*#?n4L1#=`A)|ce`Wc? zX9Fwdc~oF|cW^*jVtZtRA%xTSj6o`fhFtEJ5zW?JsE)@=H;C&tJskHz;AVv65gz9NWa8BBVSx36`D-3(Q=I?Zd(5#*oj zT&YEkFZyR|uOP(5YrGEoVe7ug0=@VVb^GUkGSd%vvUS|_RAS*DW!NB3g7XvQaKHM} z6^VY{`K~QRm^0b^1oH>3|A0Hd{5eK?fP!D@f{K^(a#pFoWK@400}*m7og5p19ut>`fUIj3TS7NS<8o$A5Wf=a*0 z2HHW+gvEjYQV)b#-tQ@+LY`0E0nRFhHU&68uhwjojF}Xd^)iI zs6ywCz^28`g~Mz%lLcKnBb90)jrYCf5CL(V6tMZ9*N-YwtNd@ zxz2FbMqx_{3*)UvOjU(Fd7kVV&*J`c!Uf$RQ9Qp~NBV1HUjrMfL}QQg*T%|_vA=x6 zB8UF$YD=GtN>RHZ+)8$}UlXg}no@rw=ib-IT>P&Z^Q#~gHUes0WK;IU;c_=_n@Ho` zJz*#jWAXbuDEcZ5pAUENd+$n(ZMku}-a?q0HxcmPxjsGcr+v$D0N$t*2e?&z-)jo% zmiu-AdqMoj(nGrW$@l&y!ymnL>IppI!s5#4bqk-%62Gi-kg(4xB8C~#;yCIZIK0fB zGp-g6cpey@6ug#q7uB~McTc)7DL2)?XJIM1aGrQpzW+*|*kXD$?FoN%9B^>5 zWpzu6S^t>4VkVUk?`!i6f3cF^6DDYXmcSV$cT?wsA6auIR!=?g`mUjY z{DDqLXko0w!s)t=HQm7T26YLPY!u57=5B592r`qiu0)O6yeQ}1#R71vaHnMWrS-k* z(wdr59TpBdP_o+V)|QVvx>l}?(Bvi&)=|dcHBK0!>@?n>IdzSy{765YOZg&M+?tM5 z70b6y{+Aj~nBbI~26L*q&^9aOr+9c!CH?(#LAgTltm5M<1*Pq5!sL`*67k+Ev7U?I zgX+4004DzSVjG%IETTlK&-@4$S74$(~rRYO<*N%8AtBOww zdj?b;)?9BLNR!ci&3->%jk*XKJJr*HTc)MU6=VeTBUKYC{XH0|^V;H`>nmZCF)@g@ z`9r+NNP(U}M1l5U_A_c9_)6Pn;8a(_xsIhJ%D%uYtiq5`m;OfBatye2czF7izsa&f z`C}A=Ae0g%F>~}iGSCx?@zEs=UyMEB-6Vx#5o|U!yZsBQXj86U0`5x0ZE}*lGcENDCyuDOo63Ni++vq?mUnI)#b9V0|ow7b{ z(Rtw;%w2Dov$M+W8XD7?FWae)lL?KEKX*E#EqC8y+s8r_nC=E6s#KQjzq0!~Tu24u z56Ig<|97=F4jrA8{}q9#iwh^?1#x?dl-)hkEFj@^cdQFOaMGw6fEjkr4g{5D{7LvH z2qM=9qCX9Fjp3tJx4+qg+XX0tS89B91U4hRjr1@ zC)2`M23HplmqZ}5mM~Ne3ICl3Gf1dX7d#Y#3GCPd$>&JZuiBro_cg_P;Os3neTAAk z+6()bn^NM0Arip1uQm0|dF>5n@g%`YWC7Ty;vixzM~Qx)$&@_*=yrI)*fTjHW~f>} zJRpu7I3YaOoB@EdweEc3*-%4c30V*NN#pBObe``MW=P;OBB2rX+f}pHtFe-k0m=lb zj3R@eI63}gvg_w~UopcU2YLCEdWFrnt`~(PD|`dt&wn4*(V>PWCr?VBDiBsNza47m z)w`*YxrA%9HyzOB0Uhha;i;XDye-IE4w+seR=_^Gfypl@Ffz3FqanYsZ*vYOtr4^R za~A;CXlWRs+Rgw_^)D~45!#)kW8+1M?ISJ-ed8kS>y6q)z6Y7;ZO)=KS z^4@T+9(_E=@P2}X5Uj1-7D2PjrYcMQmd3_QC~PO&TNDsO)ik-%d^FM52s-LH-g5o} z=doahxk1Z2JE7wRniS8U2LO}Wyy#B9PH=pKP=#02XX(Fpy~zXC0Gf&HYRDTD?vhRp zbYXlGRdFY|tG_$`Jp|~xONa5)g;efVmRyZK%3y01m41M#*p}vtc3hvM0@)ZO;Hi!N zO98(D6p-$i_9mqr_Hi4BOnr1R_m8zFCu>?ilCI0Ntcysjjz-XRv)#6)g`%=#fZMQT zLQx{7&dY+;D(yd8&YX3g1Jr#sf+&zX^lMxFb)@aVJjHCCCu!M6VN_ANjif(~Nu;&l z)XVmt*3|n-<c3K8KfS)tW=P`cm*=SGwkncyb8b0b z@XVbMS9<1zg~<~FGMwBX)$54XFU==|irB)2o#0L+C&Uj;YMzq;>uaoyy+ zV0YS3VWIK~>WiD>_w@JO>?8pn2q?dVKPPlG#`=9{rG{t4zB)Rhx;9{ z5YVb&@7+5wNRHLCD`VXGD5Hko@|gfX;PRpgIIxT?ObJZTEOleI<1OIn;XH<60Upf8 zx$ZMSt-p1QTG}U%VZ7jrt#;a*I(f7pMA>zC#bk>JFJ*?Yc6aLiaiI0ZlC7leGA$BL zBr*jhU{sx=k7`wRK}2%->iK-Mo##>$27|>mMiX0~gO+H7KGe{vOCnv}2a@b_li}3%W5bHo_gGqWl z>fh+QiNFP=>5gBGUx>KD+s^v#bsdCl{bKc9BG3aQNzE(ZAPj6`S`%aa4Ji7eSPbwt zh$^E4@WSKi7WrTy9AUbA2!coPLvkz+AR^atXkFx8yWn6{A^V7@C3NL^_(gINHx|qU zrjUkzl)`I_x?fx`e9m)WjQH8TU?q0>nEPO}iw^VNaVr#zi|PcjHp zPu!MQMc;4pzZzPUpBkPA?xRp?W&RaT?v1n{@+(lX^*dVdeZE#1Zu7IWbjbsN<}*9d z4fNADf^`zP-qwX6w2fig@jO~9XF}!J5L+*{Ed1*TIW{1t8N8N8`&Bb-LFVCW6;8zd zM4S<ySYnUIPYD{X9TB`KGi*%yT*3^hExu?;I#4lKt>!wm1ZdQgm&GP6jN6x2 zGCV_j{+P!egFgEgP91O5$LBHIC+kOEg0Qfj2HGq0MM1 zOrY8Wyn^Op1=h7XV6c_;6#FqHC5YT6=jNFobEj-l(81lxh0Qr8AiaDy`&1M|AJYu* zr0vo8k>CreZl%U*QbyMrM`1JzRR<0Ji9cs`1nB^yNl=n8J?P55C=gv*c+yqrPi6Bm zP0(^vTV!q_Y!bnni-)JP?(kk5=Fodxvg+ zuAi)KIk@0i(d@7S=TW^gObq5**z9E&yw555x8@{l=F<)K0{1T5ulc9gFGfhJH_o3B zgHbyL9O2DNPgT2){=g*IY!Xwqa9gd zk+gRHXqko0Gp=yLpv?3l=QLmdk^50EVcL05RaKSw11fNTG_?Qg!;|lQ80Qm2&PDqW ztt>&Q%q<*fSFaiNxJysP(_{;)SFf4tsqAbR{29D^lMES^)&Smmd2mqP#m#NG*&jYP zv3Pv!ACqtu1s-A+6{WxCZKu?MOtpLSzJ~qJ&V8c8z_x`}IA8X%rYr1TQ5Ql?8cA$^ji!mCH5fM6II7LU+!dOWVu&^WsXAa31b=VUyFffq+ z>Vkbbo$Sph1kg<5xE~lI@m%L7VVCxWNs%Rj;b(;m4^W1C&S?4ybbPYix5=tkmo!nQ zo^hn!Xg!^8ep#=$^1(dI@~fq-vPhd$bm1u8c}z0bt4^qAV?@kU+L6SfTVx|<{7|ILXqJ_Gk*gd!$ zaJ5k^S%>)PB73L?vQu}}2=LF&_BSAmy8Bg)n$Aeg`giQMyYE>Hq|dhHb~Cl; zE=+Y*y7N`DD~p*?yD7Hj&fU{u_~pt-u)r~8K!wKK^@{NOKtTHIquOVG99=9w$>t7h zD|hIn1s#_!_a5Co%2r~p_4t|e9y|MAElK%A`F@Fe+z`4L zOI`!%`fTvJoMsm27+)|7CXr72_ofqd?J0pVH~|MZUj*KKi6)DEY0tx%SD>`x{{ z)mhj1c64s=m*UCCRI22jnrnUPNZ_gbRZ$0!E}ZHUkw9d{yc@oNfIzlN-s2ELuIN&K z%2XVCVF{>5HITAXCq$a`W*DyL?VrN?D=iWrwXbj&k(Qf*%UlI2L@&zt<{>)Y{hxOQ zpx*+GJyB1ftF5%R<8w{VV|l$gx*0rP^Z=$f9^!42Y5v_ZE@j;X-i#owbSol# zl&p}RB$?dGc_7)DZa>d7nkYI~TI&X8>uxCeY<}cWzy}Ku*NSIITPLpZ#|j{Ylr267 zg>5P?R6S~(?aM5CG)fRiXZZ*+VGT#RC~0hV_E6lkp9#$l3Nxb;ay&R}xTO@3y;dwz z>;tsc&n>m^DUyInsrdmay~*yEoNSn+1nBLcgHuH7?03%4kNZ&82X*J8dN&IFRL6^k zYYP=9`mg&hSa0(rKV^ZGVX8v9)Wzl2{JBfid$<>d5Itc{%u+MQxt2!DT=}Qi+=QOL zs{bqy@zXv~YY(Pd5;J~^<1o&DizY(eqzZAkYhY?fz&Vd~{^wtA^3@5{AQQTyGqRqL znFIn(XvKnZZP;W9+VAfTF#Kl)5>7fOdnR+C_Y1BZxtYewYB(n5-I^8*za~cn@sa%# zmweWSd>w`{v>&72ROO4`NC>^8`dU+C&(@!(LDgZzsh2C!-upvWl`oNIAFPYCnvnM*H&#R)h$aFuFWx3*2a&%n3czr?x{ihV$m<{GM zWR4Cgi(Y=o0F!Skbn2YoQBXujbCiqB=j$VpB7U&^>Rhax-PZt0fl^}pyHt+E8RE?A zlBiW7jWQ7XXvBxsi$v@0Q}#oyBj>7iR2Ho#^KoB0^$DB!B|P~>&_R3F#M}ygFR7d# zEwaf26&X&7MLN4w{u4+k{>=KHbPHsJLn!N|YU=#ub*w7lf57{U0m3F@-i1L;xO2U<^b;dDu3nziufK>z$s? zW292x5#EOQbBpX?;ua4S%u$Su>G3Sk4tp7VCyG`NqT<<|ZytlHEh!W?r4;5fT(`lb zk_oJprA&Nw`~AmPL}%$XU1>DmCSqt*;8|J6rnFz`U|U1-9xrdfg*a+91e~LheVI+< z)hi~gmKHHt`BbfkO5Ze4s;oG3V#Gv5mS@htJ;w~6f5FsUr!2V3OS|tpd?nPFDZr-aT|N6}d8~2Eiw4a0fIsSu zeE|keoANgC0ioKYrC8)27u&Ci03*rD(%Q`l`Gt2(B;~$!w!CJi*)I8}uaeVKCgcD1 zF3V5=P4<5q$KOrxQUQZ8OHC#pb;GfwI2~`YTdjyAh(2@iKf7e|rtvXVyK85zffSNv zlb??Nf#DvaB%5Q8TcNe1vyf8XE1msG%z*k#Y+)|SR1$Z!x;9pM4lw)k46bIqHF6{m zAbD;Gn5x{!OiXK?CC(B!eHbSe)&>R+QEZ z0iw6RHQnE{jM)f+=HLEYYJpQXyGeNZ2P0vM2k?*7z4Uv?PFqvGTJXU|sVMo8S7I7c` zQ&v;Ui!)0{@MXF@^zUK{#4wA4_>a=H{oHCb`^VerkZL8FyPjLG3;zM@kcoPJ!T#-e zhw*6GS8|L!)q6FCz1pN)Pr{5-Jwia_<|J?eea%0@3cVmSUN!JFk7R))_+ZZZhRKeM zdFe5bpvvd!jjw3;&Ov^#SDIvDkb}FjNG!j)@Uo+@w3Ow={X20Ogb?;zfvD*--}S|@ z+x(ET`eIPZWH0=zyX8(xJ*klbrq+RRU1?h6-ZYaJ^46BW?^X$>pQ9VBy#07j8P_V~ z2Qu@r7gBJHaerkLZ?HW(W11=*&B)1gVeex{7t+q*V58{7zI6gBAZgH96krKjjsA=B z>0s{NX;Ll_)S?|YsCZ=AU;pDJ$c||9lW&ysIg_P~C#JEV|L-pWjGf@g$(@wJvzP39 zt%~VPovWsduRvt)ffD;)LSSi9H2fR1uyMD0dit-7lktHjrlq@m4pYebuM#WxCQ9%h zV0h%3Y4BIzvF(ToX(x3bW~ycB3F}CD_TJ^I>&^eX6QIYz7IbW1Ofzs&5!heH^dKTc zI>1%UN>N|y{Tf#B1quiC+T-)*+Y)=6@A6uRxE{CcP2M#aUeI1Rs5_WXbTUMA2FoiI z12Abz`HK`%Dr*#H5~1xM5>cQDlAN5#6t|ca<3+!rjJRG;D1KqRt98CZF!$hK7ui!Y zpjbRHHzSzNV(O3E!zF*^Pa-*6ZA)s$M5~%l5JJRb)LR&o(?Td8q^Cy-u}^=66v<~y z-0mmRaroXe{#O1Rw7;C3M<0S8nxyb|A;TNT09LUf%vjSgFN`dH7Z{y7H}Ak0v&Qu$ zN08EJE(;;Lb`K8VXZ(kNX6bBv>spMD+p$W*i6mLom_j1D z|IAlC0`fP(2s0<@-YFHKVGI(yZ^X5GM6v!>;sv2UwMP@VI(^7q*SlOZ%}QbK(e){^5L8~W-W=*Tsfmlsg;V5-4LNw zj6^VkD3-$jhDufwzQI>k-!y01{>f7(2h@|m(<4PX}JBReV7f}4wK+l$>m2l<&B$|;u8Sm z(-fe3({%GPKuq|R4B-FMY=F@8hQ%3UB@o9PMFJI*aUKISz_#=C#z9WnL}_8Mug>B4 z=uraUFqv_6G;2fpI9J&F;VDo+fw3Sb?Qe|yY8ojS2I-zoh9=J zcCAA*fbcJu3WY+rwtT)L0|Ml?yi93!Vk{}XZ6a)jxtDTotS^sy!rE>7KzcV zwq=D~kUXrzl{!^xgV*4`5{`1>hr~mvpjTS&k{Yr7@R88z$%+^@NL-iSIhU_}k z_9v^oJv;`rT7i6W8O8)P@8*vOU8gqQB;W@a9^PaKmYG{FMTRo>Q`?{7&umkX$_j2T z%XXF%;KTHi?(y#7nQ5!hvX~|h5r$Nqzc5|1co#ngcv6wcL;=jV#L#+y1)W_h2HS z8PJ8%??>A2&Up%8W=6e&=;Oh}XZokvs^%sdC8GKLBmvS*e>Dm!(V<;fylB3bl}sN{ zFTAgi(Umt8YcYXYn8bg`%J;fut?uBS56Ta(MemxH!9jugES@T-Ym`mqO-2~SR-RK( zlDp`Xbc90&6&x}$GK>8oLtA5`9kmv4xR8VOH)@;TyC};4MJZ`!r-xpB==N=7Nqx54k|%%uuTc*n*8e z#}8a^g~Mq78dKqc0Mq=yocw4E%5cT-xg(jBjyYDpm(UjvTbPi(a>M%~wOA;B@rCkT4d^;YXm$$E z2r=CW4k{_(l4T_mWdKoDqYS|5`({EeDI7cKN-AZJrz)6y>*=w#+%skYwa8HZxuwcaW z3v=+oW znWY&0Ia$Z@<>h0VM0|v_nfjl;ne^pLn`K-MmnVdh4p_qeOCRMj6=*XgW4Xub=NfK3 zZ1GPQW}g z=f3|qKc6vf-I%|WY0d2*h^arZAz*9rxly|cJXTK(e?LL&>iUvZ@nwTPyIVJ0mW*y| zP0DF!I0p|m!iqrFNpR-j#1!T-#xnP=HCBCGV<>wqH)2ZmTEn|w(VKU=F>2L0oD7Hf~;MDz<{Nf;pb64Lm5j>)Iog{8>+Yw%znoR8zUWn%t3wlb9Y= zv)8jWu|gq`CMHJ^mjcY*sXUS?aaCdA#Dtk zxX%%Q3LZ*rfMe$X?h7~5)lZ+~KrKzkDY><>4Q!m|#iaX;12TC23mdbkoGZYKFi@Z! zi5^m>)`#gnGD3fAeGvLS=Q0YE{d#QG~ zA1Ig5aDHEP*ELd*hRP)FB?z_tawPsGga-!JJ_bbl$$`r6aIqf;(NnKUxEhFSYhr|V z8An+b{#6iqRPRycO#_EQz@Nxz3sm|+l2LSv3r*fsLW?0ZROxSoAU3N+{xn5Q)H62$Mk-9yy7Y-!)h-yuY+GSDD`U_?Kov-nD2AGLv^|Kj&56o75ed(-HN_2Q z_EoW+=GJ`vA+z}*hOl!H;kE`_V{L5u!paJb>fp96G?j}?UPMp*ff*?7Dp1J!NExuD z82+puD$^2JU+J84moK-GPvmM(tRI9ntv)6Q9{p+8cF_p-5DsREP2;Zmh9n5|oLuj3 zo%i6rUGn)nFb^0DX`gJ|nZFJ;m@L`l&d~e`-CdX|yufz-Rqt7wcUHfa@N|ebiJ-g> z%Cj${QdvJ>Vvt6cdB8Z3BdAbw;>N%ZUWFE!^O|NxL%U)7W^CG50szTG76D<{$!l83 zkyt~T95Q=A&8J{;Hp?0f9o?tbk&fJSO|PBry;mHWNAd2A^V!_ZE3dH$Xn=$Qp*9pa zQUYS=C9%Zy1~V2}zJ z(t~loKsWup|I!|Zvkcj5w6?K%r2gbz@Fzvb^Ao)y+WtOE_?O-w?xem^F7%KDC>2b! zCf^*}`Uo+!3sx%w%yUr!84$z=iE-|K`qA`AsHTv6a4SXr`%mM#>a@9d4}Pr%N7;f& zqFD`rt%Xz`o6FEAeq@^g3j!vdsPc^MPA6w{EB&#`T90j^>k$QG1M>8P26=S*aZk(h z<7u~>Q%%*jaEDWSKfF`z!3IEx_s&uGH?CdArmk52jQy}W4d+%esehH-I@`!$>rQTkA zORGQa9j+Me*#iOfalCAUufvK(`#4qvxviBmB8Tw8QW&0s?uLRR`A1_?#N!^bJKhb1 zZn=05N^hDddR3nZ(l#YHkjX|-Ohfp96co>A-f;To%_2ju;>*l}%X(s@)`7L?U$fs0 zBZv5sBbeqSV$q58#G$@~kB`YdYBF9U)B@F1&?B|VH{|uV^WtCg;dv6c%Dc1IBk49^ z1xk-Wqz`>Y?qmq{Fm`WWA6~ejn#(SMy%32~%H`s;@?_rd=Bn7J=BRSw_)Yr=sdy5@ zSDWjlxA#=?X8m>ef+O-pzAvq&w+szX_~BPy(}T&$+UTOOr{gpudCKTZ^Yo`%JU*~} zP61>a-*@2C>TYJ%3mW>`vUSNDwq!0?A6y~%7a+_ac(kV)!iFkmz$SxS#GOA=rsbQow6&s|SE zl=(6^Ye46HZM*(#dnciZaAM;+^~yRq8JS$Z5tpO==MMW5i2?uQLp0x=5Sk(6KBgtt zjgcE;zaq?I1`meV;pMsOj!wUYqVW2dQI&W@3k%x5%0_VU3+WP=WnI6&aG5d_d&f4 zmAs=jG6~Eg3n={-WP$GMpbOlX567XZ)Hq9y>qkO-1F7{Zuz{d3q0zeGg@e;>_DHIJ z5=xk=!vR%*}vimi4v6B_WU z5ChHv{lk+u7S&1UwG#MDeT}b>)Ibhes0@0!IPA~wC!IHh!7EUdiT&K9{lrxgAtKI5 z6w7!V!I(+q7k)IX>!O)qZTCmf?O_Duk@9^CmMIV$GtpT1K3Df+tUU3}_iRV&NCr(< z@=MfD`FO%b8>-$BzkBYol}MmSW2nf;nB@>s{7CM)F3g}>L|=A%pgqj=#b?X)Vd-%T z)fD2C1!mZ4y6=69uX3HLNPeJXzaBU_EVghN@^Y0ENMw6z%(&exEAjGNBZ2$W{bO&{x9(G-xeHXh7a384kH{EEQHoH$MN9kC)!pD6!PGwd zV87jeutV8!J4RgR?l;3i0tTGUFu6Wm=#a7ETUxokL=_K9&2^FO)joS4iZEK==C8;* zv>H)!d90NNC*O*TGeC^0I^IbVR303xd6KIBlQ^@-lh3w&Vz91EY6fZh%@iM8{cwMD6(EbS za!PP7{CDaNRMXK&X-Z!eU@lL0+1NuWXI4UJEajJ9K5UbGGU}`Wt>$uV-;5sCCqKz`leVVF&K24GhR&y{K6AaW5=$~>+ex$VZ?~$82@N56 z8}R0!>_m9WXZXu9|Ay7~f%(O8`MM12%>D86>Y8^I@yiNzNwbBPVz@@pHl*n{(u zc|tU_UjLcFjnP+=OCR-Y^|}NtS=!E2eBtwOi;(wMtKaVRRr9pDHgr@jIBQQ`i%fqt zLwkGb-XT}9f18mu!0|qL{95U8!-VO(mCvzOwu5fIC%WmPqs25jxg-gRi7U^O0B{_` zs&umA6%_J%m7MdGz`Cq>=hXxk%o0Rc_MG5fDY_CRwAHQSSGjY<=i6vIRWH&s98s6y zy6$+0Ahhqu=>WZm`f}0+JJ9VY1E#ZvF!^^4dLkT><17s{tae9v!v}*Jl9W02`dx%# zhDy{ZZS-#u%V?jn+X+h5caQ1^CmzhC`KP|ocmTCn;EL|VbO2XijhP!7X?URKhPD+3 zp%g0SZ=1e{xl6vtQLBeO*}bBkD|x{RHpL&?mHy;b+Z>QXTdlgKzq;ulGnpwy9XFp- zBv94zqH$w8B~fhuT;s&;xEX44ZX|x~DuI@1>w90V&Mf9==4jq`!Ckvvo}i>$ZmU(k zR_o0yXBnMd&lKKN8g4R^4lId&Ki$D~=zW9CL>?P36SE`KFoMh;DU4n;@o4)N|6Q*R zqjnpM-%zIFi{1-shodj6KMM;j{K~W&Hu(HzWm_-Nrom~VgFTj!=wgRdEJaK65=A`k z_UaYTM1oS?B8U!9I0y0H&lEm>Jo1g~IG$U5=to;E7&XK|v$xeG!Cm7nxHsezmyBWvTE2{VoKR^t4?JREv{|$L ztQf9~%nW8~EF$mt$|oUkm<7oMA5*^zXnE7ZMOcH9 zE>My*lqa)|uRo`oZWDOiFC^6RsdamJKpz(&4Qc0;r#&dhM0WRe-$$@qK(eN;*6A7+ zIqswt1na??==?S=m62gW=M$osd|PiCGBipr`6XPABX?Zh?06fqEhb3;%)xd*s+<|` zNcN6ETV4_IvP_r+taKHcwJG^&>q5HV$I#JgQvI~$TNgjolMxh;l=t&b(8DZ&sr>=Z ziT=A|d%HVHvc*eCft(|7oYooL)pvHk7&6w{lL=F;;*bE~Gl6O)l(VYLbGL@qU`#!Z z&**RBj}=mS3TEWaf($7p@kBVAt?`}j2yO{^8NZ6IlB0rb9nBb4(Du-q#)+U7#NoTd zf}au!y-60`>WNjBM{gB9sVO#7R8T@o27fbFrSmQN0T$>J-D}K;$(GBnbjh@tlGjm6S?rM)_V~Q45*n+M{(lI zcVaeYYfF)D^fo~cc7>KYQ9PD;a8IW7pRgIP(29iAqB$W>_X_ z$G)B#VHH3=6+*DXl8LyOhJ5=2OuYp~!OLA({qvmdgR{13e{G!r!)EF#=AY5LiTHpF z^BRiMkg^50G=imO9_cZway2o}X9~7#i-RhXfSvT1g1PplmaL-N1=_6{S0xl?!=Ez^ z_4w+~t#M%U;P_}?8G8D%oh*!&(0k}VXU8FWv#~Qt46_6p4FaB%{wGg3M}+LaNpv_JvS9JHOlZXAc|oxJvbM`6+W*;HwIP$fkZU-Ab0KM zp?53TtdiU{QAG}F#FLP@U-!QuZp~ImYt$QVJ!`gwHcikQ+!su|_2c`O zNA8)^wni%a->_`~W9dbMj*gC|kKtPqp%`ROOF@BIbHf#2mk8Uldl=wOo$46T*%*36 za))>6_81#c?HTi9E^Ky>L_N;{LzBkP`Hvz@i@E7Pdpnzc+ zLLyXE_O}bXU}DD1L5a#ODV5={M(}4YKdbE~F@~8N(Kwy!oTSbq%HXmu-EQFO;XhI< zI>*#$co+`B)_Nh{0+`m>#USH{94-G6aCvDX$rTeT7?|!i#|HsdKC0&C<|fnSeHpG= zP7aSQ3xwV1-&_w}y?Yk1RQwF`&)#9PgZ1rpCUZfFako144yogsqZ%yFUX9SK^d@TV z)}MF@VCF&d{l)i3@OMVdqwnuyDP%EunCz5|Fx!MgK|R!X)qgemW6(aATNFr%;W=ms z^{INBeiW6g(2;SI3Sut#nWJUuL=YDm56FMbn}E76n{+|0S^rppaK9%wP%|@8p|#5F zHhKpA?aBPN?}r_hdhpqI5jW^67Gnc!fh22;C=lo2b|yN9fl_5M5v}K*T#T;rBJcv` zLfyzG+DfO-&TFkt7tibsS5Q8a``C2&HO*!ge?Su+oZS$nl{;Ma@c+zf9LsDrO9JK{ zvMn4dBRb~axcPqKRPJ?$!+wp0u7TchHQA6NG%Y&hXd)1aU$K*(qWXrgNT}!W%fhbj z&rXwB&Qb>o6b3=^^lUGy-zR6E2rz4;p7`t0OG4kJCbHoU=NuHSzh|KGlTP)mluB5UQ^nI6HKTCE)ZgAH=p@+k6 zd4tlgT^&l%Z-+bi%ybKDSsu*I=iWP`fq7Ka7_mOEzf#4QbSCC%)DM}PT>fNlZ9|{C z!B$bQbH32O>zU4bw?c=Ltx1KNDi%KJnJ+K#BTn|OwuNR~^Cy>dtXBp!1~W`c?hFCb zuc5J~!qegU0t-r~PSj)VuZBhj<-_J%5?>f%i>FC{zwQJj%^I)IQYBOCA@xP)Crxes3@r zo0y#JI&GBzU6!y&*M!6G7{Yc#iHB8lzSX7TL;p&ALT4z2HS@2vik!HnY>61OQ3$`o zr2C$J>YsLJ!|hQujp<+S#r53fWFF-ua}Ah%(z=7CSx)?Em-+*t{FQF4=ndKNDu34( zmSOnx@C1Xv)eV;pE*pkwZ7a{<^m#vt}X{bd0=6#OxwcBY6M#< zxf-kqz^@j-EV7pPUAg(X<3Y?NQ0rSQc2pSfgWNb8NdXIxMLTDA2q7>nH;nGB z)wzcAbC)BepyaCxn<}RbOlCtRZOv9$kS`%Xx|v!_E~zt;5(D464OoineUvYhLTH7E z%HOj6lZ#=+5gxn}7+wgW!C}(%Chd&iAv98EG`aH5 zg_Nd9h@ei1>srfQ>lF}PH7iNeSKJrLT| zGzbIJWA`$@#TyW>kk*UbmSxp$RUYGO@N0uYA4yu)8c-}k`omH z1zUZsX(fjFEaVp%!`J%NMw)0IfHuh{N`J)iZFWD;mM=zud+U)+XQ{?g8y9Uo_g3h& zWKoLz2$kIkCox12);j`Y3M{WagqBVRe2!F zvq>YUEUba#{^-WBwl-e+X!d1f`+RlFyVUmp}%71>E zL*Y9u*cFZL-6(5W0S)S}U_2L6a4H=ctxhR`B;?gDc9nH4mQOPy?Oq#12odqjFKw&k zj>KQX1d-v$_-tb!|H}`>6(%sEf72*nO|KL^=42aWQj2G8Y`t~l-IbI~`>Zqslz}V4 z8+ujs4lXWtfkg`%%A5C9*TwQs`uv!TzZXa1@=(yy3-B8Ug`c4ORro*1vhL3MZeOA< z%%zL@+a)F7{_zW-cFGA2+z+X?50W_3P0wcm>m>OL%<(0+*aOSy)XxH#wz+&_zpA7l zho<)Y^i2_cf00tbV2{82iiHmgvb*(ZY-5=I`uDFtEkKpiKq;P#VsCnaIE-6eq3)tu z;8W$6A6e2V!>E$EFLoUYGtOl3J7L@1VzpA62rUY)7g;DzVwwreV(GX~LD8Ok4Qza7@Wx``B7F&-X3r5) z?Fs%bj2Tc}xcBuE3gdAO5HH5L8q-Dhhm!562NB~MLo^M3zWkMIY)Mr;sFF{Zzl9TI zB7AnkR{^T3B7T=hC_2o~Pn{Xd3E4dmRrA|%UE35W!$b~++|-%*&Zt2EdGS-L!@+|M zz`*!Ndo>m)G4`f0Ycnogk0S=IJ=RXC0FwAR8^>a-H=f^VzVkvvYzd#7k%!y=T6IjK zZ9>#tU&SiqMB?npDIUexu#Z{-l8rqP zsHP_3r>1L0(QOT$d%izhD?i=+nQz((^bRr$8+a{Rpw7( z`o)koLeRZydXDq8YP@A;eHM>mr4D$u{oyTpKXYP&rmJkVZA}jLbmX)jC%fvcgzF)B zL%adtl$U<&9}XSIXLW=z8}_>EyX@Q|#9FIHZPEnmnlVrLViuF=EvaIuh?4-OrS){b(EDl2PdaKMn(9Y>| z_P;W_$urs=Z0s+yJ6^Z(%#sUTFn?x0p)NI5)@35e(DVgE5k20*B+c+3-1-{agTrCR z!FxB^KZ*Z8CWbHU(cbQ9xf?!>>ZweZyXkF54f>T`D84!wdZ2*#l8#a=*6Z1AID1l` zw?O0>!hs_~wov2kDm_vHGoEqz?kBheDrGt)I&B0NdKLZ_Bjqs8)hu(Y2>QDv9Q=_$ zdEd+!Q zvx{3>6yr!PI3Esi@|OU0PP34N&rxg;-jnP4=+UEqZ*fJJTDA98RdGO@i}Q^ZYztGh zJ~A?LL@$$0HL2^nf#`=K2y5QHVrCRln>m`JE9+#!hd=hMxm_=yx)dp*+P79#&f2d1 zSY?vyK4?}Dli26y(kOOgs6WpdH(qbgyR6JSALx5RSsUQg*w&_Ap!Gqcb%z_rC12ua zJhgp>?i6!TgL^W50}Y?`&U2vp^5Z%sTB>^o7f-Uvm1Yo8>a!#Hh{~80tx=Kmuu7qxtqv*AE&*CBXoiW!)D*09K&~vITx^$Y(dM zW7j~S5cbqx?@w0`)p5YVq(CmPZGnBSRQK3Og$9*6OZN6t6k13BGoU$mDApJ*5DEGl zU$6HkQpIzFlHhOBG=&p5E2WAz1i$sfK=LNI%P8c~h(+--3=gOuD-023{_c^R2ye{P zFF`{mLhzLyUHmjS9sQ-hDhEWXqmSG640X>!Vix-S(ajozlUn*ze0>y z>x=PadD}_ia{ChTJnoJX3If%JHZ|I@yK1)Q2goX6K@H@PKWnu;2OhfAG84fg3tpH| z0;R?IfU?2g%QI5=$SV19)*wmtO(nbtoL(eB9=TpNNDMFy!A19*=BXyC)qAsO01xUdme zqDjbQ_gUJP3$j)P86u^WO9WRWNAo$#pPrc#K%5MqS(#Qd-zLD|lZeF4uo^e{|EXZ` z-`B)&u)Bp$;$eTtUfEdH`BXEWcl{e=SwHUk~bi*uf>7{jZLt3Ttxe4+n@qT zDtxbc{i6qN@ifR;(nV<#b?*fP@g8>otx`4^*@zj%NZ<=$dm7t8t-5F*$7A?Ul}()F zYSi(=oGyLvM0&41P%`DD4O(a4aScEb2lA4Abcf4L#vScB29`yo6r8Q_H-56#F40if z5K&$%7$E&0J|QXmnO2>TWZsmxkVF^*-c<;JGP3aw7{?AKax3wKqlJ74JmMTZS$qM?ghcFN(Q#2V)~P!Uw; z-ARClfOY;?32+d&^Ldbht6U5)r%er}kZ7neY+PBsHgiEn)GYd2J!e45|` zwGZ(-k*8(_W4Y<{yXPE$_eqt;ZSx1MSTDcOf-pwohi|%- zo8A$!TmE?onpfYT02$IzbC2&=LY!wB<$0(Q1|Fe15bRU=7fC8;j+hI8gcw_hJ~97z z={@bMm-lZ~3*^$|F`#Q*15bh*+JofDb2$i3fCW-Kzb^$Vzd8ENH&3%7PWqDoW`uk( zDdhKaAnGbxsrLK7Z-$8?2{$IOtC*DaKwQD&ndjK$FX8(C7S~S{Hl}M{?j3ZAOi*^g zXF>6ps(C4@211^c{{P`gJu~B3mwnOGGe{F=D~TMf*9zAxCfL9i?S$NO4vU3*wRLrr zEMWZjWKYWmxzhPZ`a zCTyaS%4 z+*8Ftb8-)6ju+Im^{(@_CX2<(`lGf4+~=#@Mqrp=fQ(Mg&dMOZ9pgr@YveJ_D=dhw zocvdL6{Pc5vj`y76h`nzBV{@SPhfH>pBisGM~Y(>*}U27Ufp9@Fw09V1np2HVUSA3 zP>R3Px1_y{@QY=o-(Cpv4}!4Z&vE^Xv#`ZS z39T!FA84F(v znM{>-y-EAOe8yk?yp4tBAm+V!1Z)EH-~Qaz6Ns%UU0gz17d{{2Ph_2x+CJ*%^Mr77 zwfz4N4+{1JqndI6`Yh8C|4 ziRX|c2+hE=&{q>}%^gZ2JX46bV9e6Y7ZsAV{mziGRY}Om2x3C|BdHcX*FD@Cj+EPd z!)_H1dKN_-WB+r@B(>N+A&fMf(%N*I9HGtD9i4vM@+ui}b#Ne;Ts~cNqS7+GOZb1j zUe!a#ZVZB_eV4kv?FNWq?$1 z-zH2V!i+E!8co~T;60bVm`_$Ukp1dNN5BQl*#ic=wc$+Vv#|nQ^XEXUE-l*S1Nr>f zkkP24Pw?P=H`*3TfHyO-n&kM~WuXB)6NyVv8|HCm4+Q_T2f$2nxZk*Z;1JL^=2~c0 z=bkQ8rpq677dIJIvYf~Eq7gaFY^rIj*w+ZvIDV}E<40F#G><{;)F7|RPVYnJ0$q7$ ze^$b3yAZ8~&M;V! zYMg#nuXa&v%!cKnH>TYwoUXa0>&r(mz(Lura+o9FGCeh%bGhO?WQwHKz^u8|e)XFL zUOkUalz}0O<4+&Kl0cP{o?w_UrKB*h>?NdY5rFGdm9&*U8EVwPx z6;{5~Y5%MgG*(pwD2GvgTb!j86cpS$XtUO;TJgrY8PMyDexeH#sJi>X+gm88n5io4 zGk9nXw{PO4K}@>bp#HY@?RD~3e)=XExG@5H#XFF;~;d1BIXx?LY_FqkzD zf3#zeWIi3uCEo;$fKH79B@9Xh8^VpX4D&oVU*7eryN$YYG*}tNrY@(t*6% zqY6lvbav(7`W+_qAj6l6aw*pTMi@(A+=1lP)miCV$R#*=_kUtDkT>73l(dm_S8t2S z=Q7W8YLvFDY#>Gwmxc|ULCcp4j~D2K2idmJ*gj@%>updq`nGrY z0$33)EZBokh`0+vWio(~=Wm)`fE?5X{GZPQ(NFGxK6rYNLL@)YgzU$eR7X2P zXgdvVL0RTk`xn>vwWtq89iZL475kv9QZS#Ectq5Zhu2UDO}+UV#-R+mV$q|wMigug zhS`BMYxn{@5lzAU|0eRR9;zr(hcpMxcXVSNR^hbvd-EQYvB(Gt@{&A3_jQuKJ5y^^*2C5&!J%fK1@nj1GG6`}0g>cz`Prv+LH{^{uJW?l%3U zll2e)2s6;(R7GMB?QvX`X&w%JvGLO+f9JLted~J0TkXTeMD)3eniX;xW`9gE#N@E zd#O8IAAD4zmgTh{xxK*OaOsG)RV&d$cj-@#wo_KGwqvW$SqL64(ADc$v$cxfA^He9 zIyufcFC>J8q3ukxeHA-UmuEJX6`ZFy!L=au!cVL@{>aX@hW6Sw-S=cEeAn?zhy4Lq z;L6ez9V(toNpqdarQ6PI;{{S_To$f041zb%rp4DjPdjm64l!$vFKo zSn>F(1}gP6sl)9vG;^;j(tg{}A&$T_y(ER|3I-?8Qz=q4sm={~X4rpMiXx@C%t=DC zPE};*sqQZ&-ZNx-wB7eyq*zh_!}5unpZiI3*^l{eFUrj{^76=BZ%RyFF?uz-5!J2L7OO|k| zvMb%}=YDAwND$c;5&$z`;dce_FA<19mqK=P^>cNVGPuU^a80dF<92{#KNihi*gupg z8Pac^Vg|zHNSzzO@6BwDDv%~w4y%2haspTCh%b^G2%+4uVQgZY8Pbb%^Xm^G?pg>6 zHMzDqxMslOcnqV8-I!AhQoD*B=IlPrwY2KreRML~KMRCw{$^;IT5UPvQByC?*B_d$G9jmFjcut7iIm_6+QlH5 za!Dp1~lF@Is2II`Zh5ee3s9S zQZ=(IF6s-8O1mTcg zswP5|yK$o1eh2%@a3eV@{&1&9LQH!0L7d2OB<`Ng4rdEQV}^EBAm@@Upf9Qkn0PC4 z%5Hr?Q*WpwavE*J=!Nw$5L;|vnvLCc2_A%?5P5@(+EuigJYha*bYaKyC5}y{{h@fF z2GRyeu2A9K0Rn4Cu!23g=56{r~)cI2)8g#%T69TXbqJ}WYQDARpke3LtY}**QrpTT9XK2(pi?7K< zq&m6Eh3C;lH2E$J_QT(1&MLrOPr!VOVTufl5|l{`$5pfpMRL;DDF!>;*n1wsdDD!^ z86^Lc^}XxB$fNJDgutajQ*cR5!00FEUnmv``Fin$CtW$=od;kgF!6>n{}*j<9aUAg zwv7v-f}*hLj!kVO1u1FRbO}h8fV8xLG%CWTQ(BOXph$OvN_U8q0@B?`3*THk&vVZC z{l4?Q|9xZZfx|6pxz?O_T=#XyM1FU<7X83Nqhi1*4d4Py;%c9{dw0_7IV1Wy2k#hB zyq7w_O_(HKSbke3=zLgz|9aIt`OKRScVk%;-b%CzvIEMP1M@K5D5!t()sPc4A4U~P z>l$3MYoCM?#4IFPmU7Gxt3e*~KOhByy6*thCh_=HPpML)54P_$Wtk@$d*QW_AYn5v z58nDq_#H~gzh%Cyk?j(fPMG;(@i$wSJ!$}j9komoM%wfB*FN~jfwpYbnZ0!F-72v*ui|`YYovMa`bA-sTD{Kr(}Fc)15DAufrO_s6&YS32l%AzjxoC2g_Gv_a>6J7$65JbkP?2M7E% zJqkdga!9M!mZGR{a4OvXptcc^uAihYpp z6!?{=62Ch0>IB`)gYSR4ub`Q!l3O%0|2R2=6!eu|H!eormw{-Lxc@32%7t z)DpO?zSw?I?NMh=rz39px@T3!5|YED!YZhM;3G-j$>xXn*`xi<18W~lot#j|qyibY z&?qN`*90}c-4l+q39ZS6Ht{AM7F=O8xyFs}d^l89jeQW;Fj|g-_>{6GUI~)Q0moi^ zTFe#8tVH9WpU0b8bavxL_(}YtAYZa;PhkgDmA>z3n+)c{0 z{MxGgH}m;DS|~hih!^j@7p&)h9@IG()aeV7%VS@f$H!$FKX~)_?O!<)Rr2=(ree6z zkVv4&BqmkNdn1`jBi2#&EsEMUWtf#^x)4A+687o4CSh?PRB90x^Ha?7btbZDI8kbTSs7BBDR|#13OVYk7S#HtC3igw5(GhsWK8)PEI@_1C z{?Z;I^*&#{uoLtb-tD#yv-~aLcDPHT4)z@0v)+P)0w`$!J^sao{5x@N0OG(R!m`CQ z8F13Odo$TJP^}LiD0Z3iYj~^ljP}G3e_{HV_nw!v$uX=%skPE~$?Uc~Ds=Jz|F>K2 zJ;ue?`PTd*P$=y9-#s~`%tuz^mXC6^J>td=HCk0Jwzz04UjmXLgn7E9~$4i;C^L0&m;QvcfPUU721FCdI zo-WepW`YRicSI07IY`cMK>j+(l;LU87b-c~ce`6iclgpDd2_~GB5tdzrMuDTl!9mggJ&D(M zS8o>-8M$$;@;!CfezE)ovm{RzkU6(Uhy}z+k>r1)6mhPXHyTcFCl=j)i+an843P1@ zZ!>s@_^wX-H}P?H*B9`#-;Q5vs#y1(O!T6NJWn)c7?RyyFtevoH9 z%oV-YPL(d^hXMqVOfb-p{QR}78fRwsr1o`_HIpAuQa zW^zU4;1_VsBJ?#bfG6qr>(Bv;kS48sbsi&nnEdy2g@CH6s`nr|?=rq~=kmlzOfc7+ z34`lSukhR;NYdtbxz8<6vwTPU+-B-X7d~`G+xd{`8tQp7Wh%6NC zX*5vlbyL%WzKZl{hI*0Oh}CGR>mgZsjoC#k@|Yg#uOdQaNm!4`t=AM2(Wg)+-F(vV z%IkH*+*s^R)L+?seG`EE7Wjat{jcdkgh5C^0QL>sKNbW$7JVdk3(J!6WuxizT6e2- z*ZetALxr9kRKip>TG`f5KpcTEE`6H6!AhJa=8VPBbdZpT3h3Fd>7KXCj=O8|^S66- zwTt*eM;#K)>*_6nfjjm7qwQld%~Y=cpsRGhy2#0UUSFRbKd6kePaS=ylQ`ny3^WKt z*v-}Ie-`-5S>Ws6-pd&HXnmnj7WTr0=cr=+)s9YR`VlsrK+tCXDDF$ zI$B-%>>f2}Uj?1C;WR@xF3$H7eH?#n?<`MbW%$@f0Mau*vrmlmKazICcOP%kb)Ek? zRj;spf_*+};@>)uDXk*g3eE}spIL6r8|nuc{!wpPrWFzjDBnnaA}Zux>4N-T0-@l7 zE2)*wmIC!1hs5iwaTBT8dzyznPDckexf`}J1`K+!k1SV$BcLqLz)b*qU#~^=$tN0h zS4r`Z{^1h-KEnH*zhdnE*Lc-f8@F;0hwd{n%cG&72t`sdJl&HN7> z!=N2zJG8&I!%=A{LGI$r5MQQBbZ0$RDJq)T{$#nA%&ozFp^0o@NjPiOuW$&*MEt!{ zhI%21C>VOq7^dwI*M0jf){Un2)PT|I_v1F^E9mj(PFs=26=>t^V!!r#4c?1M&A=J% zxb{c7h&Q*NMMfHVbplEOX;KHYYpMxP>M*j`>F9I%SZ&N^n3371k^Eqa3Q9D{V-%N_ z@#=~fO2(JOS!QaTZr!fT^>&>y(d3>A2_Wtms<3* zj+V3mR`&k}upoD3u|8Hp#`6T#36638AB&HeuPIX_kL{Z6M4pp`Qt5qrmtOTjCB+5s zTc8kb3ahcbG=e2tHT98VB+s?DB#SHE{ZHHC1o~s{x!s9(F0x7x8@rr%V)Vj;cIxrg z>kh8Y0`+&8B4tDa9Q?;Z;Alz~i&vJHJQpab`Y${e*er|5gDix0eff^O?C|jINR$x= zz!e{l9_@2W|4l9o@xniXpk1+HspzyJ7>o>^5;f;yj-U=5|HeXLU{o?SQ&trtq~uW`=Epq#I6(#Z8l>cm>7r&5< zbDZb~d-Su>jhc_m=O#}pICNlw#FVHctYdZImie0EmY>++OEMl?I3PZr9hqu7l1fC>$gbRYK~@NWB)V;A{wTI+GV4l%eP7Ue*gFYp#(}0ZvlWj;Y!;Jr~RgjH*qoD%K zmGP1ID{HmG>f4MOVa~IA+Nh13jet4Uv ze?GO2HJEFLOGH*iZZ3&;^S5JXL6pjgkQz7xc0{iZ)8}mDt7; zQWJqq6oHAP7*vBV(EyOuM~@9bm%jr(4xA(&l*^U^wx#3E=%bYHtS|O$R4$r-RhILo zfk``$>py=X9CbckG=K8URbraN0Zf#6(kq9dR9m4Gz zZ+sB#$xb|RII2{RJK{S?{s2;^xcFg&P^o8EH^4Rj9WYEO=H{@zf?BOQ636w5>b@n? zHgl*vXz*?`X4ey>WVrD=HqYazk>&awS}+LA+sw-9hLsg*!z$oJ0$;z*eEwqpIq8wM zgRmE(frElTBLCF}QrN2QWgKkS7s3N>o^2?n{GkZR_swxLtqr z-R~co0?R@FYHcER3hFbIC=B&}GGNfOJQsJvVFox6cHF*A#5*YvGC!)ersBEw2=Ta+ zt}76SklX2(L>w!SqW`H%3IH;&$}=N3@{hQ7r$0UL*Tm>kjpVoa%Xg3p`X6INX4Ks# zWf2ZvjUSo6T79t2UuiVKRblYqiIt$x@&)_LPT?o7{$gSs#KfZ5@FJVXzu<`8trEz) z^$KCRU@^xGFoq0y{C~AX{}ynhc!X`j;16o^wW+dg#C-03te;+o>XH z$D=BHZM%GZejMKjr#cLVkXKLc-1ey>!-5%5s(INgRfp-?$kvOq?5ZCqg#KSdKDE}Z zVzAtFzlaryI_M6Q**$Nf0)~&vSO#mI`HuY>f_m@yPPrUUq(J6HGs9O?f*KND^S5BU z%ts^0yzpA}y#vD@2nd0B@i!3kgJc>98bKUbMnZK-C_>+q+=3Q=)s}mN8aMvI+Ek_D z`rFb#$XtY6Ej}>z|KDmRMLreagKDhgp6Zr8+5|KFOO~hX z0(|V3pRBg1C+(c-)+`qt=RK_RBec=Ey;Zuo`v>Iye|6LdJGp3_=Mcg~j%wuOfPgFZ zFS>G}GP78^H&BF{*VF-Z8v&40hkcj?3OmReuY?zsyR`l59CYe*7HweG>@BwUy=ruF za*Ey}e~@cZfK_OG@FuMBK4_ZZyXZ+~7N4%0#wOy@({AK{#sf@TFK>nvkF=}`XnH>F z(&7M{{Z_{0!?o_pU*Mj)+=ptO?5-q*G7%3V=I!j#0TZm^3+nIOppwH#w^;=1J9iA% z8|tbVVi7~xN=nL2e-0?G<32ohZBBd+1^{ynni)Y`5dzu%mWuSWzimHV$)#fKDsqp| z-V6lE$=ZtCG~G@?E|6NrxM|o34zoz(_Q!9%<8J*h#{iS)S2SoyZUOzqie^T7eQb?D z9uT+wdzc8-H*0*d0o_|)J-^+vJW_K>gp0VWpNR?zQcPVJ5j+z8l*ksy67^@^s?XRv z=uz%Zd=iSAhffQ4eVuuBqK>Ucb`2W52f3J|D1$(}&OE(2Tp@s5mOA9t!nYWRGAi~u zma197Xl~0i=s(}B5L(2iAb5#69@piIiqpHumo4y$_`SJe{B*jMM6}5<+gphT#$PM< zVdOVN^Bj--?bTNvcv-h3z16LJsv9CU`J;2=HpM+K@Z(6YF>=b1R;4=IqiM#a=HLl% z7|Wxl->Q_)_%|E@l_hC#Hr@{mSe8L>j*IBdosA2}8^CwPZQ6J!IJ>*Ytm*Cn(${Xa z%n_91L!@s$A!w|rfOvbC)nV3nR!v#66hUYB$>GKRMb?~M`@d^Ze?x)YRK;A!-(`N4 zplmvnqkw-&@kI+%vpQ>J&=(Fyfq`!enlRG*pMp(jVJ7s<_+Ks04fU5Vr)=EUoD%&% zo9s{SeaJj={)~9lOeXGi1!Oa{IN6LU;o47svY7P06(R==H@k^de==pB04)+QZ1di= zEN1O^C40e}C6;S5WWpXvcTu}*sEpt4-$5TH-I>VqaEC+gb}HsG9_+pI6QV*GXPC}L z;8D0AR4|ZW;yq{d%b)?xH3?f-iIYQYz0q`#4ixA!^h8%n_in!sEq*#^c$}PV=P{Re zb86RZpH30@*?Xp|A~lBI1k-d~fP+LB2`b@UwLcB|syM-8=L6;(-F7=r_>Vf(ciK=b zDzi#TAgG>94iEibYEl1PB@_Z`Y2uMp@6$ljH9p|GZ<<`YNd}#QRUCEz=2Gh8_(2gv zaeYAVHL!v&;kfrqn*69YH#dVqm0h;ZzxZw&okb067o1Bg59L%)09bH;H|Gu-rCy*9 zCcpZxeiD$_d38R0u_gDUD@~=A7JvIDp+EIY;;@U6JOPU~srwF7+Kq?*V#qf;4qG_c z%1HAicQi~CeuRf%mMC?EX7Al|dB|0hE|?3*r*pkZnZgeo_qFgB4yR?!7KfcDEKL#e zrjbJRzJvh)Rjyp~Lvqh2;(Sv_KN5P<6-yjNdt&;nb^$`AB4U$qAb*0gvim!9>m~Yq z_cbdoDZQHUpXsWXQ`gL<@~3x}p8RHE4$xf?LrzO>Z|;0 z3XwuAauY>3O&4mdTTiJ((l@fEf`5m0724AddiYc!Gp6u-wqEWm+j?gpei^#}i%UjpSc7gk&BzfuJ+ z1kYNj58B-XajP&W?=(*uDLQj#BUDRfzg2oPb#i8dNRf^t zA+~c;aSR%9uK;R;v!?A2_JU4F$op=NMI2w_+VLI=stq7G(dwN;#P_T^WosHZknv5b zR51+A%gl5ZJWsk_z76IiBN4u@25Zec5)#Cz#=;0iaF(c~G2&E77RMV13{b^|2+n6gj(E;7~?@+Tm2CX5n;BVj~QOzs?V={CUCso5V4Z0!| z&t3M$5F7j=2Dt5Yi6o{MS1^gxd!}!KAA6=8&^2Rm64iw2=W%z;CHgbOqYP_Y$n$PG zkAG0h_>4j%n6Hbj)%>j1eWBcuaxZy-bfVaz4|iv0=8teiyW5W_xK8?+?Gy=)Hws~9 zY&K zo(Y`ZSAySATmGo_O~3I~*>_r}o3%VKCBG?<8Q$(sr7~zXp2esmYi44a9>c1ub|i!k zAJ~3>C(e?ou;*@T%$OqZF;M!{BiBOA%7I>Q_YwH2{?z>ox<=E@LcA-!K$rU4V&P4K zWLd*ekl#3>`bqdcY&N?~Y49n3_d+GU`uU$j6QbTk;{=oPSLAc=3OtZ0@KA=2uF3>X z9AKpk?V1D)2%NMq^XY&leGficM9rXJ)yBS|}Fc!*TrzIH)H z0|%K5n56CAre;S9gU5Czc}*$ui?Z#r*!P_pvmN6*J1OcXf(L8ADNxOxydN4Ey`mrjPU=PTa(hK~7r3 z|D-b7xMT}a2iQ0i0`hXgb5i|A8Y93Jb7AkJ-c7P z(b#l%EE8W{$HBM>P1J1#yPab>$-KQy6%f~c=SzbrafRP(I1`UYg@j_cgZ@=-4}0}6 zkfRB1QFs}u+lEE;8?GW1K5aFCcvLWc1-$z3FcvedSanz=$J*T2nkLL!+40)Q@lsPJ zkqLh7wRTm#fYl00=z$1jy}R?vH!f<=bVKK39~#VW-jr8!hCYlZCZfBF15mQdCnxYFK5F#(k+)S8xKAfHZtv zsB|4<#9zdIh{SO<=(+|}5DO^aSA!Q=;e=oV)50_qVKVezc%h2|#lS5vddOj|yQy3v zK$X5ZZ6-`N`L|CBH&*-Xu+#i(Vv}nHsXI|W)wg%Zd8{OdKMt}R2SgiePB%n=l;*G9 z?7i&sc-l|>?T z_NHS5TDLEhLqP(6d2Rd-8%e*q=@`S;$cdUb=82loFNOA$!{Y@%pI>PrVb5QD%OnYF z)pLKjM~AV*BmrynJPhJxcu|b}JO%GM*!ZDdVkSdA4&v8eGc%^VKESL7#Zv!eR)M<>pJyWAUX=nsm6HmkEIu{N~`q$@nV`ES=y|qmwox z{s{J%0dl<3p7O5NCr0yBfNLQ~!5jGh{*4AId^MlyR~Z^5c~j!;|E9@WtO#-R^Ru4J zXTG!fBa>v*evHaLGBta#S=y}SF;`DIzqZk82aYQU_;~rYlyO24edUyCw{QemzykKw zaHSFB1oA*Uwk-@8HHKR8h^ zh8)9l;MEKppV5RZDz{el+C8(^aTE)zKlUGe^SYu3*q(W&Kl@Ebf~#e;pw3PwF^SI9 zj7n@H%z6-=XVDiAo=UmyOHFiuE2I@^r(gAeRxmtvgtfM}-;fC-c~hd2avulGoh~Jp zl0}w~E4m{gL(eG(>{7QqIg2v%H}IK>1@h%ovtf82Cr}7_tDgxjlHhv`u;1I-bQp8s zPqHO+yarNTe*5yGOkmm+ued^Q2!#0WH$3%lR4>xUF>LU;*DwAHfmI`!tX^OTl z66@suAxJ>pegh>$PXq$>fLR> zgjS&Ifjr=1W&ABT_?}Jz_PPoahl~a6l^|($JUmqDrPbvXzTg&^Nt(!#vqfM-gxD%^ zQ?brH53s;=^X5NwRUF2TH4hJ#=R_&g(a4G;3LSfEMP#Q*F?K@!`0EaJwBW`N(29)_ zCo{%h_aO!8)pmk2;^*K5=Ad{ix`>`F4}7r{VMUMOG6{nRp~FaI0FSUx8BWN2`NVWD zoFH+j{^`z{g7p=00;Ud1HFN}Ym$>OUTXcXkc))O1bwyS*g7GMA0T0TF1<0&y0K`R7@zeE>+RZ<0eu!YmIyrq+*ce zz4b+vYZgekod?6HG-f5VCG}qrz?Z$FDdx~o}20U z&*#K{`zK&cNOF#C?gk$CZS?3dkhqCz}*m7imTNU=SlW*Ddg#ci72CZ80AyAtOC9v);+D{e0n&|`4 zsUGoju4H`7hPmT%dJArBZ!jk(70L$>#eW#M4DUdTpTL6z?^W9g=7v(I??xgNR!Y2igGW^MYFv2wc*bEaywCucF}j zXU<9JuKWjt4972CEYsN$0ukVy9gPgk*Eh)}U)|RGXBNQ9U=t$W=fL(htsOGH_-p(8 z?aw!%8)I8QniK$OQr};i#0WI>-o0LiqPLx{>v4T5e%Ha)ErJG)L@6Hmp9F8w$+{;#l+5E`e|tAfWcJ- z7HtyddIh}PL!jwQM0Bp$;E{r%SOtHbYFH90|9D;N$4ESiU_{LOd!gRbn410^4w(8^ z3fdc!l~k8z`z82of`CA{VzhVj6AT%mIBQ)=urssJ&KzBLIbp=d#8iAlWKY_LMc@h# z%?v>ATjbMbM_!r{Zg55gyesH7<-;u5+n&qhyq51&Qu*6*VEH_@KscnBf~i)b+TK;J&&aChyzJ%BBe1IAFBajSXW5&g_H#N z7b3Z#rLjo5$17Gv6YilX0vc!=emMD;XQ)tu$G=J|&D;a+_vI_&yi)}j7Q}j?3;AQQ z;J>bb)}i3f>{Er$BUs@wGJ}!y?_;rt#HI9EckRUX9e&8F-h#Cb1MEdao&au>1bIP= zj%a!^?#BTlul3465;RYHF~?ksT81dkspQ@z;>N`=cTE4LYJ4`t!8Nxgs=t3tr%oMaZs+xr{5lYD>)8rCvx~ zd%tABIo}Z{?bT=@{qwnV!Dc%-7rqD<>4No0EvpyafkvrFFaasT2w!3Mpwxb2ju}n#Q}SU}9pgn_>wUyigC_c)+cBiQ;+N+01=xG6&mT}` z$42u1&8pd9E~3$7k;Gi8RP~;ReZ{(o9|FoO9MBl!W4`8yT)cgEX5ie&R_C9n zd`gR8A#|aocTMLhj}g5c;76k5V;FwC7ngH$IoQV;E_{TfZZs_$A>(oRlu{)(`@MS! z0OMCb-R9+EVi@&qdgIP%_y&RXU#v*|XjpHHI?Q(aplv-jsPEO-dehki{VL(MezR3m z)WqmH@9F!c)U^=zH(^>a>5h%752Rx8OJ&UuWry}SG~{cYk1CebGUOT*Zx4G8J8I*- zlD+e2??ArZ>-c7dm|tvNBoS-uzK@bwl&Rq-H4p?=7^US$U~iY{?9p|$i_nfhI5Z#& z#3(ppV2cu_L;r$YK;;T$fZ?;-AhlA$JfPdo`iK|_SAexr=syJ!{W~VeORSHV4VGFc zZEVvk^1>BS+dF2EJUiK9ihJ#)@x@u)C$h6HxnyMkri})+0YpM7dx`l%#emua&hq;+ zhFf+3{@u{ZQZ)}xzmErlBe|zOUsI%}N0Z6s)VOSkqGcl%G0WElWI_=mCB12Uyd&#| zOrq0hU60I|5dd8zVnRQC&kcpeoj+SyN@YM2HFw-6-FzFD?nr;JRlH;55}^@_C@fJ+ z%ih3&URwFzFUFEWjWmWp@`#~L{cf`N!%^n}@wz8#(cnw*nMv6X=IHMe50C)4eH7~PT zp4&TnyfiKjI?3|)efFXrJ{i+R;=$CBhQFPz!xqja%YYpDgt-H#``ZzJiCP2mZ2h~4 z*>y-kgT+GSHZ&jf7I?LJ~kdabc?WwcJo8Vv<`^9FhxaQHl~>^&4hJC z?a% z3&m>AnhkpU`|%7$>?Iwe8YL$jMC-4u@aEjoa8P-%6=CrF`0Vus6Id$8a}myCpFG3- zP_UX>iDKqE_u~Cwo^1X%_szs`jt?`LG`z>4|({%tcn&rLVf<>Fa<*)f?yYDV$(GMXCZQ z2&saPL^ZtxOs45OXr&GCZoXUl6*gy;rFvDsNbh-XAQB1dfjC6m^+}v=lD;AOpS4@K zew``OI&I-LKoDM*W}*nd^CVUNb#=?0z0(%GZi!R&otZY@ zwHP5gOCxgL97xx?g5Zh|nb~o~v5v;`jvJV1|6vCs;ZVpS0)-rsmm!A|up^`3%hrm6 zurekLZvt$EM_{WCev%)kV9vaP_^!b$xh$*xbe^8$y`|>f-d@Yc{}Bd#V8V|T=)Xr1 z`ptojMfRUa6e5t{85q@Rz|us0r3#!J=Uy~UnGe@95WrW1Q11yuy>R7liz3N2U^34b z(arH}pAuCU*~d|_*=(QY0ux*OFa88`nTQ!Q6oG}9q6a^C?tw~SjjL(mzQzSEcHeM~ zryBmc-F3Lci8uZvtU1p-=n)b|9kR^*CRAJdlqiH;DJKiLGFw}^9lhh<=v(4t!ivUf z5C;Cu;%n@-Oh86M%CzIZwGSI}MiqGsh$#Oy2`E*R%wxf$Z4p=M9egl1JL~CUVj+4u z_FhfSO$yekJ}<-x%xnW#>kL! z%8aSo?0mOi*9{aMv^Af4{5g#djHPg+px3|u&7{_ku41y*nV2)}^wx*S(+=OTFhWM< zaOI{a(lv^F^9YWFP*xAe)7fDhTEkkW>q~uUEuax^z6R92;j}8gk$yw*J7#t1zDshA z_){o_a!#GBu{kfbi~F5ff*vP=EsY?pM{F}>DKT}{lm+-) z6y+96z29$4|F?o@W9^S)v?y}kgcScjCrs{7@6^+_oTJuMsNt)9;9QaST=^!g*=wdSfX4U#o3lP!H5b;CXl%x*E< z&QdGn`vknqJ)b+XJ~(ac@)3byX|4&Ua{Lcmexde#yqEnW_I>iSKYRkFtcmt}v(UTl! z^<-x`sJzI}UQK@gk-OQ2 zZnGb6OZ=n##PjlmbVv0CpFcUjqv_N!g?u0POBz1#SAaI*T7hsy>^B`Qqvo_+*9Euf zCU07!dJzC>v5t;?!~;JwaiZ?1@Y z^EL6#o2TR1T?R8SNYOxYkLup*ht#~7GV#%Sl~pL7$5XeCd_m;AnV;D>Zx6t~w_j2++&>N`zd+|1p`Nu|I7xyGaVS15QgwGGF!N_5&yYh2y7v1g=BM z##Im(C(s!pRG8J$!;KrxrqASHOySeYhBT0w9}AIini6TZMz~Mlx?iSXp#KOA!wE%5 zI!Dm*VQaSC)@0iyMg(f5-uZM4H5STQdGIw^=HZF?o&^BDaBcnyJxTtwv$Dfzy(AOW z1ntp+Lk4eEG`r{B3OswW{=VMjk<8>mF8hX9lHIQZ>YD16W^UPt4!!yqzs{HBWW#l? z(GQwm$~xHp8n+^wZHchb&0e&pN2B^&EKx-U)5Ah+>WwZcZdCSPN9^!@FHX0bl7uYo zx8ZJmpuQ{bwH|+sCu&6HY7?^2c@*bKf3l7}8+r+ac+fRitY?QyE~M4@$!a=vlzSjA z?rz*iVp#$yhgE^+>}D;f+!0kOUb470T=l&if?2sV=Qf`83xfs6IaVzE_Z1#XV++VvNI*CDdfQ zP2k2&|-=xO4VSY8PJ4wJ^O!hWSK|)9% z{v*&k8zJ22F}$mqPCc0E?ak+Scd*#jTyIf*weDc^?{#A;4{;T-V*K21+`D!2_#dVY z+aB_2F@D9z{bcidOZ^NwoEH}_1hi>mOVu*OUcl7ZSp?k|*hKvIsD*ewNX(e<>iW?e zK=4`u8@t};4@O?)In&`lsf);aH5w+Y2J$9AxjJ*QGhtXUJ+^;Dq=@LNjY}iNsiwgw zKxue)QlxS{{`L6h9Q<+DW_YC4&SymFY&$FbvV_ zii0T3EH^BhC*TN4J%ap+MuLzyX8w;m{S#717);i$TSI=dNjrT&d(8Z{<8-~WW7O1G zoq2{kBF+XjF3SeHCWnNrebh&%0MBFVLe(7Fqw$Og79tnoV0H_ZJzd;LHX-m3uGK~a zS6mk?d1j`XvTsv7*TJ71GFYao79w)8%u=Ve9-r>m#-x$;cI+bv+9D)MDHE9?>2jp~ zPw4{bZMipKs*JJE1(FIB8p!gLFI@SuA`Y2i#}^F@X!fb!B#B!-GNs6!hXqdu@LGaz&+v9aj{_Bz%ORLdsBw!##8)Y#uwax z3xjtBU|i*Xg1Vq&BIVEz1O-E5;f((g_v~Zkd+t$XWeWarcXq$5@~qjhuwk7{ z0EN`r$+VGx!Vn~ntu?LDG^wu%y=DFwRG`pK;q}ZG^p__tw-Kx>#@~$++?kyLwYAkw zeHSwJwXzt=Ko~cEt}P#^gfESJitEvTcKU0Ino8US9|RHux5vi{IO^q;6S|S_(?GJI zYX$V&tWIcs(!ZgOmVMJ*>*>iL(>3fe@$l1-(fiJ4%M&-;R_iiBf7&PoPe{LZ%1c4+!I(bjxt;ZGX}MXskbOs0Ta9`%t( zsu(|*2?VqAH|f8S(KHdWV$(~bmVUIBk(PL;o+mRk?l+lkJy@tk%$6sRUVbjfAK1fJOiU@)9?+rU_@+AS}ZrgQjG-8Sw%;@}dUJ~K%gZ|%O? zsd*9>8>I1O6RwhDG+OylujzUh5&H+$Yn4<#196j8ny{a*oLSUb3kMCpdiHi)NE+7K z7ckz?eHlSk{X2pTWCo5Nqa4cC|L6lEI&&+dc;o1Xr<6m*Eqbr}7qq498Gl*SfZtdL zG&L_NJ<{oS)M5rIHZStGKEGrGq}i1a75UGd*t!(NuL(lq?5RFTV{)p}-Is}P4I|A0 zRR;VF|50HeD2icsi8oZ6-loz0oy7^Hgt&vMlZ7yUaHJon>f7x^x%d>7IyE?`HBuy5 zM8;2Dm6P-#H^HVIM9U;jJzTk1n4=9rWQh49ch1P&G~|Pn^@?rxBwNBhTu}GUT&<=l1Cp4ls=kYg8$1*fX z31BivpYd|PYk}BkQT_6bmtwE>=fb?a^Cjh(wYuguXOvB}|Lq5SS34x~t*PPukj50lfA6OZHvOFLwc~#942NPv zj=a72&vpr~dQnWB2K6T^km+@9^4TGHJ1M$78uG0+XwAJS1|EskB@33z_^K#nk} z6iCw2dxbB%n1~aoi}{~~i|;0mDA1GhWVe_0D#3JO8OqyZuF4Id{n+eb%>Ai>Jj6#4kO1Bf*ULZOU&Vz%izRPc^Sm*FlAlKE&LBTi_ns+b%qF852}Nv8H?$X# z-}*SoC{ISac9_pg;U+6DE2Te3!%|2iU7s;)6ZW2Oc%*j&Fi*RGa_kr_ltU2kU6rcF zNk$kmVQjWMXMt$#zE9Xo0I%kHI(cmcq-gw+{yOq8csKGS6a6Dn>9;D^`*VUXkPH}-8m`d&1TLwwG6)#Zt*>G3>7`v+jX zl>F5_>Zn`1h-kU-tktDe;`PfHw2e2igyRwcPZ<(K%=l{L zd=`9dam(tOjSj?kCX1NpI4C1w>I#dTli~a1JZlqolY#sPsY@YS!h7q~=s}T;B57@z z)e?zrm2Hgv;#AvJ--h-MPw}Rrj}PGj4yRKO*KR~50hFE7~YK9gk}_>&V|eq?}9Jf zU%}D1q62vs8MQ*J$$;y~QturS^gapHV9Y2WRu3Gb54^oFu=z$KNA%VUd3nJudh{x4 z`N0GOBU}-x33OPMQn+%Y@FP3Txa0}v$$@oVLfD^i&*hgXqs-}w{*E^n6tXzJuCS?X zf4jiUrZmca%L_EAv%M+@f$3dYRhmpT0cJGnBO`C3 zs$4DZ$}{^nJyC$>MbN{|+D<0zc3dYi-f%v%D(dqsHr0AO&r-$T`)grR$zg73Dflka zrfb3Z7_Ps2Vc-i2RPcGa@;l4E&&FCPnVq0>ZH*N`s!K(mUpD>h1p#_URp^36 zeER%LoSa&*>z-sv3))Y}wu!lvO2;CK(ekms47O@@=$W@l&^%15^0{e%o z*gvHpQh*VRzcK{TgbRR~MkV)*pImRm`-9J=ihKVf#gQyVw^e7tW!xw9qKR{=)r54j zgY;S9Z^Bq6Y#-r-g@&_gCYg9zUb9;SPO_Ndp`lVZt>hjNu5gS|W{BU9Wl|dWsLqgz zVGeNeKRhl07W*ZhsczABiTyX80of!b##GP!b!tY19Djv(_h1%ZLhTXyps6^sCjV1 z<(%2K#z6iWSGu@nsMG$>Nji05T!4<8xe4GdJ@1p1=+UlZGzYq`Oz#uXpHjt*Ao_A5 z&Baa!tKIdCDk|WiGkxGYA?CK}?<1_n5#rma>uV43a)A$jJ5`o7?W<_q_MF$2ReknTz z(3rr8v<(?w!)BS~6!Nv!eIi^4B0X+CIal#&^nJ)h&S$~+X`~Rnc$*Ne5gZMRmuAC- zLaE5W%we1m)A1Z8@#l@caqnLe)S}pf`>3%ADw;ttWE*y$9x{?#z!lK--}Z=o$IWjC z4L%H9XSjU3IWd-B+6J_lUHY)rZNK9JdC49V(f;|pjrqYi-A1~H>9(U496T1C?^Dg3 zWQa;ejM_aE`vrWlShM%Q6t=l4_Sfm3P~5L46RXMyqHhxtdZk_0&&M163;S9f8oG|GE0cE zCE!;51*{f0$SR)dHj`YfwYBcV{*CQ6@8Wt8pk1b0(;@RIqPt|mIWKB}SA>3v5+zLBXI3y_bDp6Ymh zN3YCEZoKOawGeS?#D@2u2Y1$|7%pO~{K_oF*LB7!8TlDr-3J0qD#+(P3Vr5}tJL-jnwil;;hn&mRxg+pJc=(P60d-7NDXI<=m+_ayBt z*B^jaa!q&|i0U(4FK(x(bTE9~XOFo+1EZHkh8_>9XPs?nw4^l+TLRa))SoWZd-H@# zeAMRGb-aEI`2>+S6GeO>zd{i-qSxQKMx9#*+b$X3sH?o@cRoMvK{nyONK(7-Y5L$r9Su=t?Z3AeTQC(w9gnhdGq)1nhaX| zRm$@6xVl&4N;ba{18*{TFKX{+0Y{@h2Rj>h-5q~q@vn?jvFUr*W-q=$&e^I!07#J} zZb=oHte9h=S&{jc0Ob9#5+-ZeFJ*M?KV%fDuaHQFWYhr2s2P8ldt>XHI+KMEEsnRh zI^)is95aqzx_x%WVz=pQKmE@X9qjw95oRC@L*j5VH70|nrV<4kWeB=p_1cZb{Ge`hqQN0xI+@`soccAE*?e?% z%nNGgQIBkfs!v=5{Ru!=`ExI2@L@RIoc?bx5gl+9(E5YTq=Q1B6Prs3b1;k2UoRjN zHT22X9AEXL1x88i~dPYcyd`v#Ok|bjba9Lk8wRlcGsgJcVfl{ z*EO$lM|B;J3nsfePbWQOd&63wQ4k0ZTch!8VMo)|t?(7Zez@AmrH_VXrHnYw zq7UxY4&K6*i6_~ZoDq5#JXooi32duRvWZWwiBRa9yP_$pzAOsy%L5G!DWo_+2hrjH7Yw+*vx;6y6&>NW8)6Tqq(Km< zCW+E4Un{*# zc@;4HE9I35l}TN(fHLk5nM`Pi>WUj_44SUGz-N|4X&p#}1#z>tD+6Oida3tDms-o*)YyELmNja0wa zMytp*yh9K+L)p@2SU4|x_9ou29c`aC=%*Jwmh3TTxCtr`)w|O`Y4J7eD7az_mC(-a zvFnNw?w`SWBVnr=Y9Ty=Vj-xQ1>}KJ%`JofcKH&R{B-y4Y!A zxXV1m@0NXtXhnT7wuRh%wbS24{S(0@$ow(qdF*>kN;(pqJj5`rsf%#FxbByfFpH(k zTSH;=rAg~Lk9%Uoo3@-^}rOtS1Co))z^X|k~0^nW3Y>W zBN%?XiJ}voj{TqBXO{=OQ1W9#q?S7O+qFt>$*Nj z{0(+Kz~7V+>VUl(eYnV`)q0U3$VZiXtHO&(ovYRQ76~OtLboeuGS#2|729T zLY?eYnT?tRP7gQP48TQ)eKbOrXQO5@qU2DFvXCa$s4Flh(Rg716H-Yvm{#fDGk!*fesca3^&-h<|A1IZ(nx>AIy&}xc+IE*)y}$mDkl)y~kSJ)a1108N|adt;MZsKa(Z{NkCz&D?Gb~wU^K}WyDcHp_i}slJbF@gviRi2?cm6& z7ezzgq}buk{EXdlO;o@3|DJzWqf{!36|PdBcuacsVQD0^D}i~h_7RSYBs5DU>R+%} zuP!^eHly5#9tDH&i-1NUjop*pyQT|;sIO&~YYXV)E&QPS_hnHE{ofl{{us+gbAQ%Z z+~Xfm47;R;AQ+^^Qf+xXPV?e=a$GQ#zr@(=3)HGH;o+;4qV{eq2mCu+!~gGx3j~=d z6a7qCRdD;I=eC$@vf<4$es$iR$g?GiLW+Ww+1z>bs{Zgc5#dCun_6h8H+iZn{W>|A zR|bc+8-3wTEyEaq4jOd6abxk=;;E$+2o8KLlpV5Wql_HM~B^-zbv-fH1N)a|QEZTDm`vag3MjeQJVY!WfJzUH4rot^Pc6ne%@5 z*k~eOw5Y?ts!+F?BQD-) z>>Pj~Rd6#T)xwSs4uCm}A5LTK)tEj~_Mb_xJFr+F!4Wn{(5F{1&) zz6;s?8vF05756i$y#A28%r!qeHU_EGhXn&GORZXtpXq|RQPmgYwt3Qt0F)zJYS8%T zt_e%|zo%~XyNU8?I+xpBjBF7&-_D6Dd|-(ywx3dMoOIhzlg~R1T2BNjiZ29$=(tjg z#KZbHAOR7)aF1)OunjO!2$v=zT6`0W|Mp4}M`E6pPFhq7;5ByaQTt<*uxXh8;h&X} zNcMYNAOJsT_(iDFJp?sP;6hvMI{4#v3|;LB_22ufMro4T4I^g>TaUK@X%nE(Ex~h> zzdN3A*v|Wvb26lG@fQ`wzQNC4gaN^$ zL0DH94AKo-tTs)Y8n1cFM6VLAggIy@cio(?-foY5`=U~+&Zu6Zi}q*I zu6^gLoJy^$O+*UWWl$Pr1}eU@)fi#D-Gb;UAxkW`$)i%88m;TE8_%|rQx8;{o!_e` zUo&fdeGC_NdloMh9oq}Y;GbW*d{8gcAjt4K<9zuRoy2sZX8SjrmC}F@MrfXNC@z?{ zN9B9>muKFYRsZ`(U;QT8Ht&cCGu6D$GSpK2^3dEaqMxhN%UyI53Djs<#zRXTj(#M5 zR}XXZ6@x&42oo+LWb57FvU1oMXS`}W{mi*spChp}nICyNxJJ=7p{z$^nsJ@@a`ooI zj+oEvaW`r3#V%Wg%gP)d1NGkq-h~z)reQnu^ZmKdk<=xO5 zEIT4TYc*Mu?9VlRoirPceK7x(LA;HKsW@pkQ}E#*?$VI&(cL&quGV?Cd<1heGQ~O> z{2v79q$!zkezkf;jVgEk{^`i_e{2DEce&0s$7YLKi@G!qa zEP^k8k9Z%9?*`Fe9~2;vbimlJSw2qWZC)bGC~@H(E?fgsnbG+U}* zL#vJd5Odk8?wV4mHK5TU(kwsXdGJy0qoTK^i?li& z1-JcC3UVQoHU`$0$U0KiMUeF|0NlBdqbcf16_3BK@*cH5-JLODv72fj@;oIe-guD+ zj^^{@Izkn~VS|X}JA^v@=43uebF){GhZWux=UQ^69mV+IGr2g?xh!Tsj7Z09#0kq` z5MRz5A!OjUha5+q(mT|Iy#BbQ_L;kZ%HtVwtF4KC%;%bRsz0yE5>vQs z`RO84OEp5EP!)k#Trt@O*Y(uXnG-`^*Dc~_dl(5%Yya|}Z{0hpIInbr;vac4(e=}@ zWwxn@%=;J@fCwlkFgd!;)psxS6TL~xgs6M)gN%h7L{d}9BO z6;!yNZ9E`HoIJ`BzA4&`#(M=BAcBQ9e+GQ2>{yVVk|x-Q^tQ!4xH`RaYlfe`Fr=YU zZLD<x22!IeaYVY(IMpZD_7r38>&1|v&kQs$Abdr(<5SB zory0fRIe%Qx9UE7AbA^lJ)BykAG!sZ*Qxg(@qh5)GdC3!l`2;2WsW+d0ZQvsg?JzF ziuIno-J$`3_>n9U9?ahRA=NidFuQ5%;r5wfZm4}~#^ zg}omuteVpp^6N;Qkd9%9mBCqG4Z%9x87J|ov(vnpqC;(JVA7!tR_+ghA?I^(!0<>Pio z#MH@?c-U|asACZGh&~t*PpbE`Ed1{u{zKtgfWAS`wSHAC41yY%6j@S)$7t9!0cT!TfK-igJI1y+9+f zedJ4}r4Cx*;HvcmjxOwcSKBBR4H~E&Z!Us%rG9l-*?Lnu8&mL(Wut`bXOsraB zX%E113$L^<{3Yhgt3N%tvN>zKeHi|(r}qvp!I5{9qZd9yF-8}KEpxT?%JMa6W}%3a z>t1AZuxUFn43oKn82$MvxR!w*f7Lk%xHy_ICHLg<;eihg#6|%f2#BUsH2Dh~L7l;E z&qPvbwkEy`19Jw&LV^zIX)!3D*A6qO`un^nawb>i^ww=e0Lj;1_-26!IRT1 zR=RbB^J-Qp$*>Pu_wGRAO7A^K`eF*HP=QW6xyiyE7e-6T1Bv|q$U*I7{_a(f z9MPmLRoDzM43{yWA>XwKaEypbUAIqf+S;#v7}}qGrr2*jju)<}9Aw`cm%y025QJcQegb zT5Z1(;jDj~T*ReD$X^COi*v5>o3iE0>7U*nivfAOcZ_Lh+ensFa#ERTHjT_T(`mnr z8qeWA|4)_nNeH&n0nM^7^Dvyc$*;Ms8XOPE{miyU$OimtNvT6t;-1}*mJf_@5myN8c5i0$y53b zRrN5%cxH*muZuMFBO4((V*qyj2oMI^8`|IjFer5%9#z|(ps#$!%{Ye%hs&N;!yw^{ z+1%KsrlHl@uX5O46;KE5O4p~*@pQmm5rys)>9z*UWoc<<&_%|I8eiseF`T$=oMd>} zIp|(rESoTTmSvraj0j3oe!Pb;{9GTvfg&b(#b;)nC-(yD2tm}y_K<^{BI!R=b)X&S zbeAsr>4r1ZdspPjFI(?G15+GsJADAZU5@3Ie6!chqlQfvMgBQPN;)#|5cX!YLTCf0Ak>e%B z<06!VPR(X``{{Nju4D=pSPPMzI#)Qlp1^E~&QdG*bOCGMde9j4fKw?;P%L|{$mQ)6 zg|CLl2sS}BAXe(K-W3XtLc1wnttRgb&(Ii1AlXr_IEb_;`7yQ8+Io00 zLjsF(4jz#%Q_iX7qMB!GOVW=!?Jx$;cThi`&WddptB>q z-k0%Wj7UK|Hr+qYG+2JSYWpF-|O{Elr+0J_(7c zuy{Of2+#cVNDLiy z)?}gP{kQK_1B!Z0VZ08jE9)nl3~|&2bES^Mq#!g7W9DXQePv*UE zRJh&@uB!C1kJ!Hk(h@uJ-b>k8;jHgYv0ZXmamvhM-L5Rbj;d7({L}jT%d`a1e1snO z<$o9(#S;S3$bUvMIPQ0$c@$64DJ0>BD9*?D^=e{1#T`L-gate@T*2d%2edvH79>*E zl7jZJ`R_BYlOxUf%}1cq0>rLV>OVNlf0r7Wmx#;r9EJXAZ;D1E98Sw;`KANqNRae> zolh)(I4UX80AGr?MLfA__P%%l=0d#Wy*Rb>2U;3MCyQREkALS4e%bI#C{%yR27vj6 z+;|r=LyZ1e_fIJ}pV^k(iY%%;=VJh{SMDWX4qzi+eMfY(ko7})Uh7-s@ef}Rw=!i3 zxFv)Yo%cX!tx^)jGTLIu!zbd`ixNThTDD9sl^NqabC&w6MPXPC^+biU}|M7Ij&RG95_pASP zqI6AbLCGxg)>57$Whpl@%yHYFCdcx8q;llMZ3GZ&EE_$-jR+^eF^XtOrj{TkjhOCyu>T{<3eKaMUeBx|Kt^wd(tnIg0J>1S}X zfT}>N_gyg0f$;K7c>VW_L)v{I&mu<{l?=l=XAkr|FDj980)t~&71Ura?WX#3rIt0A zlwV$r(uG+PsSyoH0eOwJe4XsPS}6A%x z;dBEoVg{c%J)fA%r%)0x;_%lT|IowDaSZi_!~cT1B?CH@CqOa4ESbZ3P~mYZ z&b&5rydLC`GV~V^mME|KgD=havEpQ}l38POKU%Jb%`he9+B@74sX+gXE_~wf>wOa2 z-O%KQ&GkXuvL}{ftRUC;?1N*=afk+#gndPcPbZ>qFjIhMLwc215)Q8Tkk|H{2k~S@ z*4%pk?i99wBH353GriSlkvzi$1Ao{Wr$x`>+Bq#TrkruBS^Ni5QNOsJug&0KFq^iVj=pP*@&MU3gZZCmglL|fcTI~An z#meUEH*MIbm!m$6oHDE#-@iHkwY}B&9_W3S##4dRLecj*@X!7AO<%Lt&qnMvVxh_F zc}Asjv%1HS?gpY0%|;ho63{IX_uqrFH7j4YZrwcQFzM0w2AUz=o1|O=h$uk(EnZDv zH6#FPHk_nB=77SA#O2Rw$Y?#s=}|Vv!BHV?de|x|zOBh8;_0rmAVQl3w5Lj^zZ>=s zScv1Sw}#^#mv$V%|ted)#cW$Zp(-)7PDnZZWp( zw z@^#FkxnP^R8OLY#SH|y76GaA+J5%20MoMPQG`nI73Y@BM=FyZ!0?SYhgE2gvCuNv_ z$S2}^skI>Tb!94G<>8y~#8Pi=d==NMX+{94Szw|fP$3-BgW){5GgSPVCMvpdc=bs- zfhM-9SeY#shP%_JZ`|H?u-`pz;g3+lW094oxiQpXY<%;$J2DZQBd0gcK*LJsw^OLZ zKllqb_2Gfv;?edl+V;uzraSzcioC5clFgT50zDYT421fR#SAiw zD}Ctyv6w|sbbtq`0YS8nf#=Qi#-P6)y=>Y`Dn~OJS_}q<46B^>5X6LK zzuimik|{AJDdoV({}^=Uf{`s0gBDMtaRvm>c3C_`XS`6QD|P#`jnx#4LDdxNFG$EN z=2{)_rponVeMxo^>+U#wW|PNej<0O+!viG3q*XYMKd>c_*%`DXQRl-VjGUhw^(26b z-SW=Ywxgv5pY27j@2ruurnu|M&;*CBV56T2MUHEUYCPpk6OGllJ>39ptju* zA$Mup>dkQ(8l}&w^f`Mm-CwfC@?&=sMeuPX`k5?DoCsY2%7&`t=G|4m!{e`F;B%}O zD^;Sn<7l)w_e7j#weV`?nR1?_v6FM{OsMTb#rhP)969T;e43mSeT~{w=SQ|zf0!H> zj(%%iaXJbp7on|oIQwwAzeihvWYsn$q;TIyc zf_b3HN`bjK>Ictrh6D6XO08u}oXaJ^UD(vMlS2lQ*$nfx+Sb2r{!w#@!@%wRajCtU zH$v~!Kg!yDGHijsad$b7%e3=n`z{+V{FM9eB4rz;WP|(aj>6W23?d){pu4kmv G zR~PkUD*+reu)>=8@_S@z?rPo$tulr6Eq&dl1 zns#!so%crXuNeMaHmLY|`q_HPFCNJ$|0yH@6o1Jd$4BPT_AguM#2@f0L z({OajEbMa>J#^JJ%@{-P!zE*id3#XiRPnKz`k$f~?K?YwyY`I-1xTP?^N&uR1bhq2 z(@mKypVNoB6_;rTvD6Y!4n|b({2G~bi-2?t@W%&n+)q!ro@F%qPubmNv9uLLMTu}K zOFA?}Ixhu^t3kEfe1(cND{QMLX62xt>ny2cLEF$dlMQ}_rcgZ9o}pX6<|&cF>$HPU zs##`!N@^1H=|{wyzmiYai}8eof2U#I^s8`0)V>`6H!@Zpn)d{UqidR@+0T#p^Q)=S zd)Y0Dp#!6JazxJiU;Rw7AUWM(FP;algaZWNWL|&D;bzwC{&0RhnQ$N&N=!^3RYR1D zs{(zFBaf3cAC7PG4u0~ zvtR@h!)&Ux>5?3~=Zk20O<&rbML`x1kjk?~8o>{?!slExxIC4a&kz17I+HI@EjvMC)666its&M%GjdvqAx({5J5#7jd1U45WsavmT z&;b4A7iRM$Irtf$i^=(|@lHe#t$*%SL7=tckBcays`N$gchrFJsiH}r`82YG=PAga zBy%d(7~??=rG!6QV*88L0V`6dqJQTnsCjlTUNHBcj;yMvNy=vVX^cjiRd78yBnx~S zuDRX&jSh)bnEV4!=o!3_Uc4L?LYV-W3~sL5R^Oh*O}6cvS{OHk^Jo5pGyp>*i+zh_ zSJClX&ND*lqd|)af#cdw*7~PKpbPC#GEeryN3qa^DYXBDP9`fmN#oly5jCj8B_Z!H zs_;$AkA5qrqx~_F<8%Pmg-Eb7boS9JR*R>j0}7bGAL53{Z}BV^!mOV}PeCsU!SB<< z8qGzOEOBmm>(Kk3q!h|I5W86Cp$4_Wf0{P;Ff5UHtKarfH3yg?%p#kJM`yfMIl0zV z*3$S{BJX&A?AsI4EY1Fl-StD*mY3tFj>QJd!$MJtP!@l0&6ce0{Z#;eQ^W|TRt#E! z9Rm7O<7{an6yi6h1TsVMf&PnOgdK@(2+1-|v-NKSTvlH!i&PzF$0-_)H{z*%=NcUz zB!&}crX`lBK5Ub_yGy5I`E54DAR*BZG5PeajX4L#Ad4EQUZiHSd1SIvI}5Fd%Bb}C zt5YJ8a6aFdooj(*qgkl|)#i624?f$azZk7mqM%X8l%L8n+K4`0|H|{S_nRyfCsxz* z87WLwB5YtDgYfyqf%qx0KO~a_=c~!d#&o?&f%kA9WBk*CoI$B@);omGSJ_6+E&#wz zaBRC{mC}4a*~sPTfyLRZ_p{#WH$K|MofhzeIn9Wr z5EcQul33*d!r?Gy5wysB>dF3pF?1=d{b9F@Uc;4E>t1pMqU+#l7*XFp3!edHn12yA zQf|~ZEMnUc07Hzs!TiiGYP-Rzd1{FI->I2Fe#6})a>@;j@TZppT%cz!ipYFXWphIM zbt}XIN84l#OeSA2tI_${lkILY9lvuoLSeT=CsS~y%SXjX0YJHA)qQJ=GMi|Q#tVC>n zd}R(^B*Ku_3+La9ykuUelqO`WIRV*ot4u7<=5R{1Lszd=2xqFR)tEfclj%+1@E<98 z>NT~RZ2fuS{QuNqy#H6S=VHT!9Lq;?)-o?>uCFBOCJ*8`Bs4n;|7!(|hKI^#oRb3E z6@1Y|Os}!0#p}CX2-q1pPj(MqAyF3oWAaOv6K3v5`r}?Z}ALG^sR_6cIGo)M*HI$lv zx+W&YUKV3TzwA=F=IjMn%{4t8Migmh8E2sW3xz&$D4nf(0YsJJ#s(-#l39D&$uk`_ za8%3{(gQK5CHu_$=9{VH$Yj0N^_r~twiVooUO;ll7V5EVNV$>p+t1ofXPW zlzz{duF|?~I6R4r{DYM{7YxF;ajwIPKEG8P*W5(!X`JD%~dJDg4ys zE)A5@MPxBbg!JZk5I-AleE)QBzE*-o*cDEWOV7cYxd28}%=5nv!X}e{0km*}LN@R5 zeG4t(mc5!y45ti4b&`SyNFbBpTb1(10I>h=+xrR5ht4Vjgr(ELIkW>Q)^^1?8D1~; zX6xQ){uMIjByFmlNMt0@Eq}9pvJqL5^4gPKQBL&-V9O>LU!_y25x#ag_y`E->;SSo zl+LMBcERU_*&l}{S$T8QNutj5oFV+R)eO#q;7513--&bG>bZGq{E}yrivnTK##%1k z(I^@5qioiMQnR0rz~40f3S+qQa%uk-R6Wj(rZf*7P=6z0q5Pa!rrGC&)Ps}$_e9P1 zR%qs3@a_Ov1_l;nU|!cvrCj;piyctp zMc5loiAy`W_)2!YMc`t2CYwHR>D^ADO2s3757!v#w3H9I2^EG7ct! zxQNM17r+;jqP~!{T+*O035n|3V{}S*xhGPs=`v=j7HArw#|Pf;4_|u5oqfL=#>ztJUTn>1^k@}ZZD<3l40tM z?*sOD3iaX6uvF=cE9v4_HtvE*iieTM>^rI{e@q3K`v798 z-TwiH`{6r}jpsbJ(23%=Hg%6d-%#uj6xw-vf2R09p17S-R}FJKK0Pwo9=5Hb%8Qkb zg=|kYf(lav@e)F#>4C)v1n9jX``u}imu*642O(lZutI~AML$G#Zd%&u;Ksb;XGqT8 zVgu%jJVyujXc91lgS7wsdUUwz;@Qhn4kc6c@$B6zXA*5Ej%gIi}JMPHq@X?jc<$kRuYVxP6Fe zy!d`1x^Om-`Zy{Fn-&cFQhaEztYDa%bE!9zTDe-`_w0))$;8j1+1n~+4rbja0=jL;=iKcP@+I7$x-X}FQlMrx_OH0A18+&cXd#09L&3a&t-*vM901l5k+00d1oh< zz)No}{z(3w{oO19s(u3uwAdkP<`!#%hS(1=2?#hfNY5+(0+go1st#p2ntsOw6WkpE zZ#k@Vur&&S>lLcj(&@?SBBEyV(;o~rJ0ccd7*R*o*t`A=i1?hI=Qa>?U+C~6Y4PiB ziJJkH%Ll3L*%*|jXvfWSh083FPxsnh!6LkW9#r%4=i_jW5aL52S1R9}J@DNa%lcSM zaGlR^F=dOMWjA$rHAZhblrD2=N6GdWe}K)q)$EmJ^TojeW@~^0HG|e6Q6LaO zL7$1Pb`nV}*1#2BlqFsp!R`I`Hn^?_{)bl^==7UIotwHt!DwA*5#3QN969ZBZYY7) zKZ{m^KKiuIxA+j<-(+*VKNQ|abbG>5Yx1GBuHkqMf3j0z`cP`d0?own?~V)n3cRwn ziB+nAoo%jPtH*b4?8`tIrv7=?wO3FG*B%tIhrLmM+WiX)1iK+uJIV54lzP!YORP;A9tdfyhy^$nZtN0VN##!O`2Pv_$I`5-reIS%g=b6t?if- z&-wKEYh~Odc88Ak1t0f~@Y%CnlYY+$al+#Wh7%3u5Q})aW|6^4PPIOoYMU{0-(dqq zgN7#s%-ZdN=qx)Eo1Hjxp4xQ|4_>Mlb^g`jj?S8`CGt&a9+Rg7pP)BfPI&giTl55r#XxtMHT%4VgRDl>#|!pj1LQTF#h z2Kkh3RN1|Etx317Q5958p!}2=qh0Xz&;;({+TSC${mS&7$@uJ8{8aUse#^QNC@*LJ zseJO%1P!ZqF%7XaWmN}%I7Q0k{<#IzT}OH&IqcRS7cI$lYfopej8UGE_=pp9Vt)}KHee!5H}|U?90>j2T^)6frUW+ms-t1ona2*AfIk7gBl_KF_2+YR0fuFn;{{Fzh2rG zhqNk`^rB+;d`}0HqJw?gx0@(DuwSG$L40N}|GJvYX#d(mzA&!;aMRD#i8L&Ry>zm_ zgQ^<%x;g@K-5)+s4NO;=aJ>IbBh2N6lLHm>3DYrqi}H}J@|_r_D|@Wy1-Fd@e2Bz% zn9~iPZ5v`L<1r*bT^fghd7dulZ#`4(^gJmj(2N=Z+mi#!@?LwgPYG^BhBG3>B>t0HUZgT7PMKH3-Am;##uEfd9#^=paO^! zDptMfZaiC&{Q zlOQQ~a(UTTu(MX$7-3zwsF}iq`%aBT-;}D4v^Qefuxuu7t_U54P=|NA1@&}BN>~ZY z&T65TgwLIBD={ujGCt%&2m=pNg9;aaU2`hLVD}i?;gk?x&i{}m!&JW$(qq=7#V3IO zdV>nPhr>?m9}@yc_bt5k`PJggmM4=qlh74w2YHu_ikpEgA>DMN|3@|$9V-=|fSi?M z!U55(f?94kJn!|4uQiQJS)is}$ekFTcd#Tl@168;HwM+pmo*vh2Yk=VQ}H+&neo(eR8;iU zOKG1+k>taF$0JJj0z#Ejh-uXxN!3{4R%4bX2FWZVH&+U^vy-~&LYguwHpI(d?Watq zjew3p>SG+FXWIe(5E!>W6i%G`b$n72oF0dQD@CsZgjIUt4?`?x`V?564_GhOT8=j6 zjxR1?DrE)c>dd6v$jvyd^4+adi?3hDxa! zEi>Mavcqb0U;A{deeG6EGx4e+&R>O4N)?=U+A7Zs)NSmwnB8mu8Hq(@IEzjWHR6pZ zEA*&HWS*F{Y*q>vH;2aCr&IxU%)CM?b|Bb3W)TZybF10klBCFZI$WK zW>eCHpP8NIn{x4T#P^*ZtH9wmcJ3H6f)O6Xaxmkel#~j945QTQtHg0V5a#4FlZ-X) ziLDp)oy(9r1_uRMoP)VfbuO<55v@SaiG?4X#gl z>`8#q&~t?Wq(; zX+!uB9*B5L_OB=ws#2xB_!*NAMVci_lu0q*@g~3F;)n2|KS9*e!)Kc{NC*1)n0gg6 zKS>VHQodK6kmMW56z-j1x}PHKz-t?%mux+jrw|ek&jyOv@#+?KK`;xYO1leg5Z^{x z1fZK8-EMz(P@s)5cgkS*q2hP>YmzudM-}##74xB)BucLD3o!WbZ5maTQAYYJleM*2 z%jqGxYwvJ(QY!D(heng#+8{11#Me))d2c_CFfm1gzqrc)$3Lr=TXFEkC31Ms9dBSrM%Oy_!oiM!L+Y~Ns2?e1e zE}p+rhu6{RTjKQJ>k<O1gMtOZdb=<2`suAx@rNt!suAs%907F zChAW1)NADDdm{e1^tU*kH~u=$^})#$MSYEtC$|eDofzmC%q2zS&e)b)fjA|+2JTQE z=+|3rb?{v!Sz{uWKhZ@5z0i+)Tox7fkp*Y^`w7`X^BwG^hiYfF<&gMp-D|Y42|?5~ zv4qLzb)-JO-iWzI@;PnTw|QOcOXNyMMsPp6xu~dptP;U3;|N9FOKA_+%&Ii0*a^An zb&;i3QXIrg*dyjqhy=co#2<{q1YXmkFR2G7Qt)_Cr%?L8t%kOLN4gHZ%(dZ040aWX zKjyVT5fygE4|Tp0N%ab@HY->EnY{$#3=7#0g;APo+e()!oxh#ZqvwWnG;(0lxNB8<5Y{eM8u03Jicmyw5RwO zDnr3K2ckEh7P}A~^t@)W;oOlgcWS>%{#y$U46++GVjeLHYE4fx=aTfFDdqji893|( z*k%a$-Qh9k!hRA6{Hl4V73fECzLQ+z7W@=iIoY4jCIoIaZj1O=AXx6oC;lZ=(e|>_ z4yitS&UYO>oNs_j`d1%_VL;}TD$K7GR6mJMw+LvpnR95cWE70%_-@bV<6Ykh;xp^Y z8uQj*sK_R;7lX$}C)Goc5 z@}_G?&<#7O#v@SO=|S=#!968`|8imf{u#F zTZxU)?0$n^P<}VeW|g!TbsDAJL&pye#+Q%xFjR7=VzDJUnrLUcam5m-atYsEwBiY( z(1{)$9lc3r)sGPtD#A*vAVX%w_FKQGn04!(?7hl*p;EOIhl`+HAGU&9Q)=y-z1!Nf0ypm0MeFDEh6`6zxqWRQo6{g-#^p{`;5cG-QG zdGmTB^?9WD|NM&t(!bP_<41a6AQ91Swu{iqF806>k+n|(7X6PmnP-5I_d{NOx>f~> zE{Y(kV-HjS@rv}m!i0Dn<8SCExJS_;;DTkzM?CYG-uMw+9R;z_OT+k=EvqE7F4QO+ z)Q9_j1?F0OG%vlqBIuW+ui6#0)0Y!^WWc6`jz<*@6GbFO;KR2#34no%wL0*vx9As@mdzb}!B3u7h&LQ zf1q4QB`dZy<7$YTGkt!oatduv!T@F_Ni*8G{t@_yPy^sA8T~dmNjt`^V8DKS31he%;N*hzMecMaw)v#5XHAeI~NaBt{SwH>dBtRyp{*!K#AT zP*G!$9w&6epD7FbAw#UIO$v8U&zD%N&*TPRxM-9g=uk8i!70#a6~!mVsWd@3M%xB{ z=m(~P8hA5M3%HN01$01^(ZLrqDIafdUSX)9QokjW(3Q|K>}t$-tB0 zf}fXWCRSVMpQJO`tt)yZl8s~F*9$AqiQS!s0t zen^df8rFt^p|UdaGernkZu!);aIk>lNF$7`6Z&UzTr44$TFQ8~<~`YQ$0xL9Fj?*O z5)G7tR2Fz%W@NNP*rE6dTscbY7!heHF?>%s@SLLHtS};1IKjD}2Rz~i0107KToP+yfts{y>S(1k7)2{*iEW_p8`L|AFUob6GL`F89v^seugn5IJ99 z0Ab<4daOX8eUGXwdc?&F?p2fj-2|8HZ4?xhEV!_jVy{6+3@4IXTe2iVFm zP(orXk+yY|nM+|DiaeW7lLCPQG1|b+VK%5Dz$8R;eA216eF1PO<$|LB-3(&sFD|>2 z@BFav`;zf)+?d%b>m8lI!L%@wl>-YFSAOLKCYDod{v=C&RDLk=WN^|pzWj`!lOm|2 zOzaI;Ji)HpmvSkS+QvXV{DI7LH#X%$^k-SE`O|MfaI*}8m->sgBUCUwM`JGeNm(*j zl~OmGQWj3ID#2J3QQ#Yg@BQGnB>nLv!X*(MpjO%YMOqm4aUFRa9QPDBz8$19rU*DS zukkC)Iv=*dwJzs0=|r8~Si&m3-16Wp-j7VCiQh`H6mi}UGRSB-I_MCZ>zWw^k*Dr6 ziG__j?)#V)N*i^9ev46_nF{!4)YQ9llzuTF0Ge#kz<&Ww3bcI^d2S{(V^-*qE;+`} zkB;hb3q3eBmGsCeN5RBvYgTXoBa&-%*)pq9G0j;MI_2ZJpTe7bC6Dal$jhGwdW{*W zBC@U7Xs>djiYxh(O*LI0C*q? z5_+#15T*H)?Q|}B1I)5S@W#Z|2DyV(mfCxLUE?!D8+ako^c6ORW=96;A9`dTX zuD$+}fdkyaX#j}euLS;pb;K)R%h5zI3Vs38jIuS#bOt_A%OOpfs33;BhX>W`*Xr2W z>OY!4KUm$C@Z-VF+1fNI*Z7ye1* zTOy|H*H2#$yYbih?;Wn}g~o$g05wRw0|c*5{wzOvFMEw#HHsI1tj6e|@Bd^!&mYz% z-!#>tBS=z_@U^^IcxlH|Qz{2L2Ke^`)|A*LCcPR|IG=;WFc)|V`|07J+c*5cBMyK2 z4F&r{iJ~Ec^h*uQ`1s(9N4Wp)UYP%3Upg>;C3N7(l^Br6KLSQReub;a$p++SFLaEK z(`6ibJ2{IgBVHbNP3K_wh$Xm2`n8)O2E8w zV7qvpJJo>$oL-|KlEh6Vn{gdk>DZ;%@=3(o9;@~xL6n&Zi&z5aXRXdR)l0|GV1yB} zy&n(hHc?1@IV1^Q(Olf-fNPsDTW;Xz0C@=9NUKRPQz$B@fIzO~-&r7y z%iCstqJ6fRRj5&tUzML^dHX$)wTt8#iNK@z>vM(IC;6ep|8CL(#%v%^7|MSz_&u4^ zY>3r1wHgiC<$N!ce?)m%4zvZ7q zmfI(r`SG8F<(I|iYZHmbmSE)i2Eu}NLgeQVYV^P6i2MKW_10lkuR+_Wfzpk1NF&`X z4Ib`Pl)lHITp%$uC1Y zM*{-u^mdoxw3;Y*p;2iNd^Zl?gY)M-#|=V!IyL%9`1#e%4J~REJ&2mGpTUECxCj1h zdo;*vy4Hme0cSAriQO#p0r25CO@a3@-y_SH%}I(tF#337WIViH;B>?>g!AEKTDW?) zTpWTy$6Qi{2)(o;P1uJhWI$ecy_HkwXH`wm+{X`PpE{gyUY`Hy?iO72dphH^*#p$G z%YU>!no0hducZ!^&-^g_hY~>_BnDVRWljkoI}PunA^^q6v{c|8bGw0nX79cpjF7{x!EmWJAN3p*Ar)TYt?+4R%pfh4F+Ly3%1eX_(ClE9{O z>mWupB3Rf1W609WdL8v6seu(RxgX6kH1;RS#KK?Us!l^I!RcPsF$#J~=m{P{nGs!c zOHwJ>*lcKmA|N1ewUMHq1S^pY%@_h;z;++hcja1jjbXi~p}DsEgYZY6+vwmGzdEtF zF@WMvcK++ycYs8v*Y~wAXkYvPSLiyU9PFzi0}bW!es;9h@^U*-D?Lu0H(1kn>soxr z!(%2c>xNqXAYu!%GCLvNTCRocW;_%xT|<}jmWOEz-PKaSl~K%{`G#~PTOjn)w@8gP z>-LgZZ6e~*prGgJU(Ne>pWThDPL$%b>I^Mleh=mZ)(ElzYd_>49M6G4yhJ6AnyEEA z{lo8dfixn*iEcy$T!cQSZB{2rnJE*L=`<^4cN0@hC|C)0bn#VYMF&;CLq9h~E`i{s2XWrL_1qN*Sc5F!E+gudK0P4C>HOheqs9?z81S;^pEl6_^1Y$U}=|f`5P;bkmoB7 zkjJgN%C^l}-P_TeT(g03m~nGhZ#DxH3WucETn~R?^~Vw}PkmupM1K$%41LSj;O}z~ zLp&QhReQKX-v4vmMWSpmx+nn?@x8!bfOnVe4QBjh-yQ^0xy&cbXq_?A=iz zzgD1TbWMjo8 zL78@%9{QH{#uS&;ph^8G;@`_b64-*2s%03>%F{ULT5Z6T3_kxaC_aO$f?bqKqUn4q zgSUiQo<1e(&$X`$JR&Qy$qJMbwyU3sOFou6(aSi@O7*$oWZEy#ejdhePp zlGF|Bn(H>Drqp6edUlMXM~O3d_2R9FDYev}lJA4qmEd(FOHI>KWf{aQ7MeNgZRYx@ z-Hunqljzh(%rQB>plvKYhdpv?IN-mCZgI`^-jH%x8v^l$v0o($o2~ca!oVX{@VS;3CH^$KLiPn&EWgZ(nJr1onD88 zVDA0zFY*IPJZ#t%nm@!D%9w^EYEAAv_ZFLxpZfZiA%sL=i%+E6ZqK%GIc|h!<;I4y zB#-38mJ@Kjcc}J#rK@|qJAhuKP>9g79wwi{=zg~RbQTdx;zUl2rNO%r3wlCqeQxv8 zj|GC%1RI zF+>W*ma5OGq%UqsIh32aJ7B)QR_bso9*A6kLKABu$#|ffkiM~T}!5* z$(DTHB-{J?SCt1F5-uka$f;BbLgC}ENA8fPo;@$T0ZJK!yaJRi{@b1!Gk$d@%?Q!k zi(`k>!)6iJ$v%cQhc!zyxw~5?%ZbwdEh=8)RZObD*=7sO*pCxzY8!N_U6AjI3ZE26 zN5`ptf*|qT6UdmS#lrG6_xg6v8gN;q z@4IRuODc7b&)A6Rnb`0mwB6q*{cE)$kJ|+dulv;RS$$tFisN_mp)ieVm%}$n zmD>nS3K9?Zx?l5aZ7}}xR~^xabPx*2KG4BLy%9TZIY#%(aUc4!_$B{9*T*IVxfkU6 z{`+Wf&DU_$KT99pnj(-6P8^{THakQ-x6l&*7(ea0txy1UYSw@j`5-iR^>h2HN*9&O zM_CS%<7?!w`5*D)#RFRP2)>V1V##B3yo6I^JelfJft`h-?eT zZQ;`WBBJ{qhSg;eE9%Y!>o6a@r;<@PH_^kBdjDUDU2T7+FPra2ZdTseO>7pX-vfv( zecUoan>2U+%jQsAb}N2*7hs{w@PSA1p>EhMwx<0w`I-IJe7>=I zbkjtRbP&ir6gwPWF}@r~CJ&1n@p>)+ugQ@H7XbepB}*_YDvcG7pNq;AcfKKqg7ug4 zug^yBqS82Dp?ps~{oJJd#StC0(m&D>22$$0jGGEK`Hi>;)R_YO=}-qIO}H06f}#I%5rQN7BLIKZp*uYRr@6 zXB%?sOI{m#O!{Y{L!l*?_CxhqD{3voFK>!`%h>ABC_lcAD%Rk?xO8I?ph7Zx=75n0 z5!>4Z5Z0}hd^+-f@e5ZO;&?tnZOvbRapP*CN>r>|{E%h-2(Tm-Omi&lZ572MIh14U@ z9hYF+Xn&H}-@#qY_pA_AJ~Kcdl{#%+>@v0KJc%nf0n7Nnh$D3Xh>7i$g5(bRaiXt* z-%+OXK#l(Te}z*Yw4qL+z58m({5=Fi-*IvV1gjaJ0o48&!f$&PM($P0zS@Bof+enY z$?uki^AQ4{F`dvp?#8khjlo&Zd=1qfA{k%{K?_0day{X8xnurY;TfZzMH4;}0Q9}9 zat6^vEM8$+6~HL2b(vIIQNxD41$KuvRdy8EgAE~Z!ftg%KQCM~R+r-aLSmv~pBJldK&!ymJT!2ew ztHtkN=XFGnv~cp-hpYU!Y6_+YJ{NpZA8&V(WJQz9W21Qqtn>k+4dhWK!xkEL&>T%D zGyi+Cl=QN9)$-Jcnj1b43H$kwUpWUMy)YC(AKQlM8f3CX1&aArQez<=|(jlZ+#KFw)FgV zh0gc`Iw}BCu5WBsDHhqC;+cLXC(Mqb2Z)%GQU$`dxS{syNPTFDd*7>u3KE^2L5o;z zMln1t7XckG!nbAfV7~Evr0WN~7aXx^iSG>44((b!H$t?q4WhbZpY1+A_x4!74#_EhgqZBr=BNN&oUVIR((rT%u&8LH`l7; z``9}Ix>6{Q%KrEQogV@xT<<)xtx%lyUK6-ZfjhD*sG)=6HC7|t8ejAlb!`g3kW~TGwS+QAnC^dQNiJo6 zy)holeD9eY#F}SM?|KRF_!e!Y^td#r@8EMoedqN5&v!tym2$@&&zE>lTxNAXJAHO( zQ1|U{0bYE;ve!cwROsJ`D+pMsQZ#|FAAyNb#qf#}vI-re;C1RuYBLbQ(fv?L_a^&{ zod;S-i2c)`dElnR*u6mzPIN2|E!@%kWx!vEiW_ElKww`W!UJm0h2y_d! zEn7VfZ}<=~>DY_3qURpQm%$&`&Z@sDu&_kwZ6}XzIEL(ufXxKvw2lDo1AVL zJ)Gf{K`>L8I(e+r-mHZyks=(@w?aVywg9AmsKCaA%=YMT8w!qpRTQ1IFDO0l;BSR0NZUF$<=kvWg&w_a$3H-ar?ZQT>} z!M{ep78*F;HCI%x^O~%QCQzug)%~7buHC)E(I_cqOuF^wjWJAmi(%6l`Lo@tu-D`1 z+}<#kq&RtJ_tk6~eVIULVKDUIGlpAM<#vmLgwEPnMZWA>6sIP@!8A7uvH)wF-n0JF zH)4OL3%N=@{)pT{m-p!Z_6x^eCQ;3?>%ps7iwf0FK9Q5?E|A#Z@xaFPRbJJHMK)3? z;fWv>8OX`ca5|-^GH}mw5V|^nilIeQDjn``^w@z1(c|QtfZ5aprX8`?l|lWII5slj0i+h4i678XdS3mb7$asbbhB&TCp_IrrrTzM# zY3uD3LZK73=)EDw*(?>9E=mJWX+Hk|uwX`cX)jRUeLWo0n}(~Xw?E`b2*XD66mI0& zrwRFfAUj2`9NF;YeFl&~pZq)sGR4WO@}K2+5T53itK%7)vHH@4CXSR8OhX2L%L^c? z_Q^z3BVQ;)W%?JQ5`aSR;?RnI8XHg-*)p=zzIWg{QEGBD(P^{~c)q*X z#s|5YubJ57l(Wuv`3=(v(%Z ztJahx(bHz{?o%ygF*!5$^%0=JwfJ3_INKBG*5)a4bGZ9q=B?Vpaaj6*uy$Yk00eG0 z^AiTvIsOqF0`?n2719VD!h9YQmd&N$<0*RGK_;e!mPjavBCGW?53Mk-6fpDC6{fZB zBZP10zJI4nSxKUd9QS=3(REj?9H|r^4R5W8_{Hhk=ZrSY;ka`CxojksT&~fG~Do<=tmNsttp_CJ}9M^LS zI`^J6(N!7kg5ukr?99*-JZTmVgA;iusQ>yI*;69~#nhh@w|Xm^K}-YLly9}%$AV_b z%%DW{2i|8tvpYKLpFj2Xzc?Suwa!hV!rMC>dR*397d4j4AmY%`N;O7u1j?2t=y90t z*9UlVFKyOTqotbjH6{a3O!HGfiRxSc?iFg79F)jnLz-B1NDHU1DE-)C$K1laTS3R!OyuuAsfWer zaDUt3JeZ|4E~kmC@i?uPF2nA5u4+|6T(S8|OD|i%_n8|hXpPWWm{+Jb4AD@l)N5VG zQ`YDn7H=21h)qsF#^iOjTw&NtSZA7WxhaN~kV~h~t?ep6C$9!goO=B*OtUfffeL{p za^I85VPjri8U1PX&|o&A;(F_PoTv2}+vZ-AXy{WHs~<#Dh<(53qSHts-^-Z_)ij@h z9AQYVt0t)`Up0(mJeagq$-Rlzc!tO64yJ>D&yASJX$w2!YqmHk!YP-AQ-du5IbdOA5|QfWlYr>bQ;B~(%IW^wRH zElei$@vx)2VJO@#d$>Tc1g1mgn|V#3k`5=s$D}@5)>(Fy%Mq;)CcZo9q8j?2DwmUV zu+ab1d_uA=qd+||S>x-8d~t_PL5=Be;_;F>fWQ2o%OdseKVgjIw`q|irzt_h{_hR* zZ!zD=U37k|H|kWNRsw{#5_RZ^93RE~ZR>?%Gw2XN#)u^Dw2V^m^Ig!V7?@$0ro zy*Q710zaM>9Bq(&e3g-mn0B}Tnhr*D1B;;`*Ld*vjy6D^Nu418!1`JnsB#81=^u6LZf_s~ zZB-_TmRr$&N6OOkX_xn`D}#rhS*`E2q4Vv)EoZnZ;~P02)-(r_wax zeeT|O4<7mUXWRh&ED`*Vb*cQ1%%ZHT4s1~8&}k|dR9nV5gGE&t)N7x0Oj*(%yy#`d0w#*&dfUcYAV()sHv?8ErO#<)HKUj68XC_(E`f zpm4B;4F6%gy^UfTZ5OPtRWU=3D%Opu<;QimCDig?esSgosbbDjo|k4$OlwE=%{4z+2bC0Z_AY2a<=n=bIKS6 z1((ent=?uf>TgHWALYF8*)({&)F1v_(6Y_MXE+N1DBsnt*|ygcU?$Yw)*W$9 z;1AAsi_YaWb$}|22Y+L~I=sPKS#)*;D6DhHKvO2TQP5)N}yC;_}lN*dv) z24#HxZ2(^wVN?j1Zz=)dQZPNbx??{;BJdUr4QRrL?^1@Qk5XAdhY(dT`;Pj;T@K{!%*|}zE+8r zMIO!&iX;h6mUs88kh?=NF89>Dw)K_ax}s=RDx#2ET>E$mchxKNK88_)mh&;~X`AAT zMFEqLC~~lvH^mx?z+=1Y7Qnn+U;sBJHm6X38_oggiR>=m3!zJUu#oi@FT z%bl(tz4x5E`VO(a1xGUx#nalo~u8uo&Wgm|iO^1AErs3V7aMxq1+^#Xms0&qnHWV@!p7 zb=Nk;?W6tizQMb*d0<~>ykITf36RDZOaZ5)ut)0~x+tH#CO8M;c(cA6fV*-Xf{YLD z#Fr~Io`1=vv&`btD(_B5;>SJ8j@)WDBbZE7p)k`dcilOXIm1=EH4l%e$pze5KU^la z{e>6Z)J213U8NG_^T=&ObI(MW;4VKCd1yX3-b`D7$&rcb78i#TxmAqbrBz#HOhFvhC-_>T|=&V0=W zw0i%am$);$;$(#ekSOb~D|i|{O(;v(6!9)1xgZViWr!S8wW z1iD>d*7=Y7ZF-^f@mz5Dy!BdzE{%Ruf>sLP;ZrH##HNpjj#g-N%5cR<2j%a5m=z$h zz5})WH0XJm{Ejefd?mgxssGY*2DknpdOd8nv4Zak!-ZmHu0Ie!HVKj;vc05pB#Yp% z<&D+XoTm1_I99?!FCbA6AyYH6OoZ01sqk_fzGvMBr}S^`$Zo(e%AYhTOoAO4A<)Hf z{n4LZ>!|~zyg(|8cNX9M@qj3KIBRGrrOa_Q@Y;OwbM&~aG*GZjk6HE-l`@h_DJ+Y# zpB8lyLDHUmi6V%a7}`8-UTPo|iqYWaov3cDd!Qk1dU8?y>US zwKe2BNwN3e3g2utF51D8ElQASD#4E1TLd7*jC{ro^#=N|I0!t9V5>jc3MyX-P8r;k zx5*EYAZQy;nL8S&uOv(`Lz{zXrk+*i7KZI`edf(}san4jPZh9zImxKqzg6csM5|J% z8l8ekD>l>MB>3`zxW^|Rt(R(%6B{uBsL({^pU=Suh*66*IsX}RlP+5*9eV2SY0pG5 z>jc?ZL6hz=h++Y$H&VoU5Qt1x&@9?Y=ha%jm zdR(#8>dHVBt#IFR<4!R95GEmXfZ<8gan zGsj%^__LMY^@bf3${{JeI8>HLWm?gQ)MDtt^MU}&JKcK7;}ML+6PWI8S|$*oJw3as z4&l1{nYEUtn{1BSU~_Xp3n%1>_~D2TNgJtW<56K3OOa>sDZVhE?6qa%7&As8Tfvfe6NjJ9ET1SV&G8Z;zBb$BQX*I>57s06i6 zCelX^C=rtgr~6-KT@05h1#zUlLrgyO?d_IJ;e3TZ$rv(>_dC@Re?0}z_+k>vC+EzW z$c;bDblK$*oUKw9tzn4Uy`va#E{~51l|PGakRit}D&G5M&IINLfXt?f?^*6jiUY$Q zeUAFWaMOzJ_FC+KdjnW_MediLqr%|Y=KZF?fvzA4Z6X?&(=}k4 zD4Sp6bUa9;2tqVSGOj#>pxk_a@FzL;LJVVVdnc@f8;vH zWbOUigv?P@_WHTk<;rTp-zManrKSat4*eP^r^1P0emWGu_6490h$x3ku}>Gg>@(6` zb`Af8p7VPReUZ=kRaVdUGqtNGmmYlw5n)Dk8Vsyj3q|UED*PHWecxUlH&tun5v6lt zDh1p+84RU&)E{}8I#IrUvQNNeAg)rWi%9o)6_nCD%(7?rk+~9-cdKBy|CQNK;waoB zLECOUc5%!+-2PezqhakPks2c%ToPA$tp*eq{#g1NfR71gi7a;3{HUyljhYZQbCNq7q325PUV5x?i@`8r)jjz#t**?fw>&hj& zR!2d9s$Lp*aJbks>0`xwu@#9-YJ1#NEe;TD{S&MaHY^v;wF5j{TkH-g?Yv> z!H6tQ5-#%?wHJ);yRxn|bNwbC{hM5Nr@%DJN8w7Au+B7FHEN3c;uD*gKBY?i;s8S~?R($8ItysE~HXYr=x8G-O} z)1$e&sJMJ@O@jpf$%w-peNWO%$*Pzj}t zN>L0P4fSiBJS1CQeUEo9lJ~ALT?^#0v;yi@sE&{2fs~l1e@9p(Nkg(I5X22WQt(rJ zngiUQ!M|}onbD}#vCacRrbbu1J{0vOmTcL>L5BJaiQyPr;6cOn!sV=EK~5R(swUX;8@A3}0KFp&%ztN9s?Fd>Whpj6HNvM^Zem&38kpPE|el~K>l z1m`r}d56vPClGWEG?@oXuq>S*QFr?hzn-U98cb)l>GWo|`yHAxgNRuH$xAq9GyAk3 zD|o``5sInS8O;7h`Ew6QQ!G&EBN2x-$%q|0;Y)|~t6qcdg*Onp3MWkL6z`bFEdCG> zh$0rQbpW?nU{(F;jo7F$9ReR&wt#pyzO9nC^&PY|n?-+(jBqm+K4{YR9`QRNq1Yww z&pxa?W)_(*n+%N#VaNl)WRy}L`|@E?3+jx||KrWd214FsrE_eV_%Jz=B4CoAV~a8D zeP}IJsSE{Mc1~HcgTqcesa!QLFFD1L++pdwKxy}pLGoGmD76@TyYH)Lki>9w_1T0e z)P=UFRLVnGP3Aw8>3wd_z1#hDye(*-1pH!se^09#ZDT<@i7_eM1ymSK4odFZQrUmZ z|3_=2|F@gE?|zAu>od;($R-hDfc21lQ2(3#e!8>u?pdN%dE_*iqD0sd3Q6$jtoa{! zCiq)c72FlPn$--d;S9e6|X#DXH{j@RQN*7Ie^*z`*UYG1$uu(T(+ zs}`ojFj)Plh-sQDluOnn+Mr$q)`4H;sJ|_u=T)HdFHB2U#ka)NiCL=m?nk;}yCD&tD>a>k28! zI($T91s!KojKZ&fP>NlHt)$pL(}Ffmae5+BOzLsjY-kZ)F+}`@_-;uWkul}=1bpe` z0-l_1b=aSd6s8t>s^F{(v1d}nj0vZkQpwA<8_?}>^3nUgO(VVU5*Hr*Sk zgdP2fPMx{HP7rkJXtQsbQThHEtz_c8+<8TZIklg`b=;BTDV2v?O^)f0l*9d$awrMC z^vYu?CJT37{eF{gsEZX~=w+HUFlI41kdL4PT`%o|>B^^JsUZ(Wq7#@(#7z z9;}VoyYZ?W??aFZp`k}ividXcPJEnn`RMV>97ud31}kg`|vi$)Ck0c~HZMMgKj?J{_o#>7=lJn8*-S>|S zb{EuJ6j4DR;5k=^N81)o|;Fy zJWfg~H%M`TcROej?xq0zVYpa5TB4D_Q~e}|$_78P<2c9OjyFvOI7JOu`-XIkM>}&t zvPW)BtfqN|{D%eXq6vBHcNjmbA*{?kRw`N_F9xoN(PgNtl?X^;{~P!*NA@971WVDsOEM8o zeC9S9AOqYp5g!FWg(&)EGMn3Lr-(gEobE9gK-ps)blaGDI%k4mAg37L<6yF!I`29r zhjp(5Tq#?HV*3-~FhK<;oSQ4e4nSz&W4AOhe?}9>`c%cnr>Cowwf|C$EC&K$nEn_d z(X4HHw1a~K{#$s_;b5AE7w9mhh=_=yAgMf7a32sP4QmRfF^mF|P7GU>u+`)Icar<$hgnMB>02quUnB&z;qzUc48GIH97B_o#2H z1uhR4L~9DZ$FaFpXk5sgb&63i0c}FEwWfzeicA`t6^hM;)x{An=B`egH(sTFyGY+~ z8h6Gjr8EL+<(E-B)S;rT&92SYrcM?V#(oB5xqt%B)6NmF^jT{4jiw7MqS-spt)k}z zT!n;y@U{x5{yF%ZbgD>Lael-+uqdOQQJlfb0^rhUVwg)p2UybSXM>TmY9*m8ud5I9 zNgn^6L@OjpDC2Y8cn`g0R!Ai8Il;>IichOnF@S*6r$Nml=nJ%1NN#%W^^hJu)*r#^y`G%$N zD0J8WHYM7t^H+9DK3zB~^n#ge6rybrF*NGjg{`xB8%+8g%fneuV1i%tMv$vIzAKQ- z#($rvL1iUf=KnXnio}H6V28x!ERjiF?ZuI#5wd-;gj1w<0dOhVVuMKrGv!%! zdEr&6mk#*w8I2bGkV^T{RT6_;RSa?m!!*Aef2ea%l#6?c+2 zIJW|u^VV8t(MTh_bw;;#%dIOaSI?aUh;fI2`M=yUi#4j?Up z)$~NX0Kk;-!4IGz@9ea?Zt~*C?zh8C+E;gr={PyG9l7 zg~t^|Z&qW^>6(5-obxG6zgFq^G{4ed5%|S9M$PLs0VWa@cF)~nE3#EZTi;tpWJ>jh0!|EpCyHQ}rOCv}@!OEW)h*kmyt$NFl%5P(>vsm+wriOXr4Zrs;y^ysBf$F}fazgRH?%@JAi z{V%b7zD63cG(IPO?=6{?|LGko@KveOg=QWLb@>B-F{@3oUtmibv#^v%`(cd+h~MZ< zV(r%vh+G0IQrp!0e&rATP3EFzAPzwMsRFv167s#{Rf-hGJz;3lS=w)oUaEJCqMe*^ z>LHl${^cg5;MRX6VN%xMghn3qkA(s0V%`(+Ol^^lmIz;rZos=<)D1?OGQGsiuQJ*@ zW7+<74qFGm*zQ6QJ#TohYdhUU{85LlWM*%n9Vh4pWyM7XrmN@m$(n~4#f{5xC+Lqk zvD71`;SU=vb75;tsqC)wJNXmPY4q~F>)(Dg;fc`C)J!BeoVr6~b!`}&yt@l>e=z}8tnRzI-Gb!%WDtEd%nq1FNhC7Rn1`ZI|kighp70) zcGfdF>d_~rkpqI^6u*Mmz|2X=;uHpgW&q&Spu$Q<4ih#?UKR6hVWfT;BC z!`-R8UWfGz>-*F$IwW_HaX+mZ7&n9w@V)X!c%jO-uL^4FQy3OCC<4n*-y#R*KY4H_ z0l~tm^REeRws8$>veD;O4~=j7Fmp(FKp)Xqer+xc82BGRAgq3L_MY2uV}#l`-ch*u z3=hdA-<0Hh1Ccm*p?j{OvWb~b{h&1=Rq00@<6a<0PJz(W0^=_;m5A|y42wzvJ@(3b z$;1bAETgZPY*90{uddY6FiLtn9uu_tq%S{Ge`k@VmW`ZJfGC zLYL1W1-(84iCn0JfZUxTIoXh%tzh5#8@wpc(fE=)9|fC?+3v;}^n&=uj=)g&N+o>*BVoY2m~54XgF~C@ znnDeldG4@@;Rv$B4+E&#&y7Uzg3!NQk~>fxRwP=K73AVh*F_cucaX& zF6wo>+%!W27@>GV+q>~IN3eTp3P-=Aui(Sw#f8L5SF-%u5_b$&OLNd3*GMdYof1GS zg8iO`55yTf>KZao5M99_q36-u^Z5ru`t+%-j#3p!5r+J`SaTs^EiHU8#HxiUrY_A7 z_g=e`43MR;RHECM!S;rl!xbr@T%@5CcTJ``y1#WRdsXuYHqPS4qoZ4{s5rayR>7|+ zN?kRSl@s3h9${^L0$l_^*86o^23&Ye(CcBo$AbUw^=E_e3wrn=35PAi*}*i9mMT>L z2wUh^g;pu!K!{AZt)A*4q10C zAk}1*GZqIYaSRV=8{8AOC-CUe9TJnPETke>9@to%Bpy^)4!$>FqwvMPHak$hn2ltv zZ0@!2W9B;_%xmsdT!Pr&=3X?4051jvs$mAGM;cd(%(YdyBEkki{>ELK2=(sUL*Q6r z+hNb3uH!TWRDKC}lN+xYi;{#iU|_Sbv1dP;!O zltEssOey|42~Ht3zp*`$7N0&I4>Y33GjPkMz-gd^oLytoP=SUM`m0BWJ|7Ba23LS` z7l|CC?9k5l*;Me6qGVudK6E}a9!^!%D_5HY#Z;?@Qy`2K7*W!>*yc6Shsop|E)1Bw z)Km&?ZjD17v85A`*Q~Rbm0DYnMv$VCM6Pd>8pj7i|Mfok^Mv~kx+ zc5#(lY!syK*XEeHRi2cO54z3HZ*DI3hla0LXpJF9CnwKtZFN4&;8pWZg8QyIPT>VQ zGr`kB!N7>87Pl-=#U0UKRh2E&thgNTWB-CAEih*$;_*MF<}P(7fdG$(@*nO0@0ea6 zV=#+B47c0V2SW|7ZULAV%9c+IE_K{6a4ST0$G3uGghoIwO4QY!OB*0C?H&L`5wqUs z8cqON_U^8%boRdfo=81~-!1^eqfqv!xDty1_V7(SkjiJX9(vXrIzg_EZLKPLSw<-x(Uj z2&Uk`)BK1aLzQ{(CkD^N7)TNz{yb10&iraY|JR52F(Gtx5#FIEhb?7LALjjk`S2%j zNJURVM#t|S(%j(*IKdnN+`h;%kSZ|~0}H~9rSy=>1oSsX+kq5GPx#NdU~rO( ztuiL%vXHSV15qqm6`B#!rFNf4YWeJC;F9iO%Cwr7ZVMZmk&g)0BrzUdxJ(*rb)Inl zY@O9;xi(jp4=@RXk&*1Tkzhyf&ROXUxb$VoCY@}c*(QkqcK8Mc@!fDDIV@Bn|40!n z5II%CwrURA>L>c{%rDE!?S|cXZ-vwJv+fgnqH>uSb?<|+y@jWTDvOpH-)eD`y2fFp~JqD44M*v`YGkoh~91awYT{Sda?Tg8l|pXj^K} zKR;gL5>L35%X!xBXZ9F&gs;0AOPi$;L)Eq?LIAzX-z@->2DJrhZkc4rF4n-}Tz)$mor)OA)pFc9~#77VizZBAeScE&08soBh|(Zl5_;LprQX;jEQz`~@WZB*KL9pBEkyD}4` z2U5ZniE;0AWoU@tag0WxQMM#ceeYpuzK35>p(Vc(w_6H7GKBevBPuX z4*cie^(N#UhD$zi-1Tz2%#hbPc6j2A@{%pi5TkE7OLeVU`1-NHl~~MKS0-)lcxan9 zEw=H_B9_CHG1J4D&``6E6TiBqC^ZW$aJmA!BNUahvhm&`3VlB)Hn%4yh6T*m4~*NL z(){$2$j6IQ;!tfSp4UbVi*|10Q@ip1&3u4A2*LmzU+NQ+<2{}aX1w&G%MH5E0X>U% z#!iba`4v3(1oM<^Dq9NZMf?)z3O5dm_+oLK)-pqOUOQbV4f4@`1!Sm*0u?7)D3D$s zgW2HXAnJp`yTinKMw)8uv0z4TGyzv%_FFIZmOpKiR1d%Q(DZ?Xh|Ow}9tp!WR@Kow zQhaJ!>MlO|7%mlbAB>EKz>c_f=d?R}v{J?Yn1OdGRgGNKUFB;RKTOV@wGo+j5pkKE z>f1Z7>;GEp`t{ct$!|si<=JzQVmnQJhX$lx2aAgdK{IS7%sl5kj!(7tYewyntTc?Ku* zi7cCh-`)Qf^sqS+Pxx$0ubAP7^_PXb&QZbnT}JPd=2vWmjOO_KWgmI30P!_WDQ`-$0IF z2N-7pa-uAA`o$0MK#BP03PI_jLIXkT`vzpL{!|2P#t0T-BV>tk&yl5Q=2JdVQ z9Sl49H(%>dr@-wDI*Blu&jW#-ZrSMXpdlQG{bgTbtzBg8XyQD8YcvNM;t2;4XZKg{ z`Z*=`eGJ=WE%bzbc%j$rf=M@U1awzO#KFtjO!k}JphrcfigO)08R#B(Xo!zKcKtV@ zDH5FmSuPExdeYD%vadxc9z>;BT;0p!6Ps8id7hdJu!n^wL-TBhqeew{C4HDfED!GQ zi#D^|1@*8?)*_VgMTu+62-#j%j<3pNQaCi2@a0fNrmLPj*5VLr zI%ky(@2>BQq{WU{o0yD-dGputB9qLwgvR3f-Sqz=!i<&SK-IKn@%2Eno*Z?;+SkO< z8=`e@IbhMyXAuY$nTVaTxPtVmos{Fp#`f%}WSRJG7#+!tvh+vwuO-D&pLUY1I>1wx z8;M;iyD0XO43ShS^j`Q~j6AD|D2wj)o6;~Etz%|+qR5Q)s->kxVCq0_xK6jlX+OD6 zTfJ8eNd-w}@7uw_{buG65*t{u>6qc>+wl`jRa|#EI6+Q19WJ$$=aK78-PngeU*8}6 zjqg)rJ2*&pyX>T3CGSNLzqY>rX6_e{Ty7ZxDnTXv4?c*sd@{D<6}RfX_yxLV>{f9d zsZNbZ8Fp#OUeHq1aAKkAhU#^hk_th*M{C=F>%^FMp@*J|pAxa1Ibkgq@Bk@abu8e(fM@Qyj<aM%j zW6&D26zw&7FKucuCN-51nbi7f0>tp@OQslBwJ3$AB}goImu{6yJl7JS;5)b|GqWiA(0@Jd(ZL z;!lLEX6{PWl0BPzy`0F{rnmrk7NHR?h7}K!1(o-62GF3tFrN^6B|bT8^y%T>i3z>` z#ti@NO{;yA1Y^@c0j`OcPTR@};;t&=;K1+n{o}D#@0q(7NzXZtN|akHw-uNeFzz=I zP?scLPDXfCfBC7mA|{E;sMj9ea!I^0vFmpA5JVQN zZEqC{;+O`L8I8X)Mq6sLZp%AA|;!okB5$ zJnVTTW%?b&=U{>2*HT|$vIt)E+opP0bnya%s5lY3UYue)S1R;gW;vAzU_z&uzbNw{ zZ}I2~e*N@|&pgd~FXqtBQHY2B)C!GxGd6GMSp>HLhN2jTGbpUT&B92ERdYJ*{H<=5 zr(vQzE?$|@3Ox7ot9l`*pIM&{sX1JJQ?`H`Ec#BQH}}_HAOwveV9C!-cz>sGw7`JU z*irc*i*I&Njke0AUzlE}<|&^WNwre!IJ8%HMCi52;L>R8dt_(pIW*z}Th6QmQnCnc zA){=;wBRmdEZ!(`A+iXE)*^QB-J8%qUu!5yS0_Rbbyp6oXnK4a2QlQPd&g*Diyi`x z4+b16yiVhFq4m7jD;_Yy*#Qgck{O!j74s#K#bK$7>39DI9&XC}8qQjq!IZn;|AivH0Irm0#b61L1{eFqS7>yW~(6TR2Uq z1FPGc3##s_Q#1SBJ`R4b8vr-@qA&Ub$)?h05l$u&_pOr+gHYuC%eAn}Mz1aG#a3T< zx1W3VvWapfH~Vwy^Br!m@+5*{mZVFfjqOgjU_yc?hZFSxEfr z&dQglB1^R=0OL7ccYq@XjJ}o4TpQOM>nE% zk2kGFCN*71kjl%3)-R`r7S{FC*4Fmu=tu~pwrEUx{Jn3R!4JH?z<`c(A{Ow5(5Y8I z)!ztc``S~&hqit|@$ccVGc1lo%z}A~lBt5!y|6&ExVU(CczJdz8xYC}5h|nl=KFa8 zbhU1cWc_v@wR#jNXYq7*%Q$9{5JQKxD2fwNR1`A|&B;;}yFS@K6cHU+RqP?>_d1c8 zMtw@*a4mba$OV>yZ%Euk^@(%)U9VCeEHyFh)m=r*dpMCBg4-WrN^s$TIbLE|_uku#=#Utw1qDlrg&*W&xa5c>(O{2cvNk|i!TNS20#2C# z>xE{QBK?l`e{Lz8!MQO8o5&B~2kMVGTz15>4R%bryZ;woUl|v5*R^Y)gn|s+$k3ev z(!va_bazR2H>kkSA&r0zAt~J{U4k@-f^-N{(slND-_P^D=fgQ4{3$Xpd-i|rz1F(c zwXP)(#5r&PPL$$svNK0~7aa!{LBO0VlFX$EGszIpPE7gv(-Ab>Zj9h!s37Wt5Pe<=&KCgQ25m>z)zuIQmV9x#e>e2eb_}*{vVw(lbapfY`?uHq9IQkmpAq6YbiFoD$c=k0B@8`gf*iCP z+&-x*8A0tEqnrj4?*TCh_>a&pao;Az76kJhaok3(F-X8vOj-fh-^-hQT}V$CR`F-I zEd?s+v^OB#$~1Y2E;zmP)eaGqiHG?8=>1m4uG{n1FaiT}wv;y4IiDdg3O%J`cxxxu zFlTLJ)RT$Fe5j=AU8|*q<|bJF#%Kkzp-AAsoa{ly1CH-r{o{5NKfYbXe$2TDn`BjO zet3ZSN^#RgBkqT=mYc?g7zB|F9>^#Z`EQhnEBCn3(g>3H$ZR)J zD_G`4Q65;MDzHX5FzR^w-pd#1A@=08%bmV?#w?6Wo2$XK26M=lS7a#dq?I}XYlhT6 zHVfn?>m2fDb2tvqYAI$fWJ4!Xgn^xVKxtH67k%wizvWfOOEVDwmSFjc(RJDpn$=RpfQcQwFKfhX-us zRt#BLS+bczHP8iZNQlNu$GrXhaGySW@`sq1!EJ3Io)&zIK(?D`5g&u$hVR`lng3|| z#Vh}@#8W|9nt#F*2-#rF)Dvir-ebKl(EldUdyv0_Gmxg#y(gL?=$+f*r!1a4d ztLc*3r7V5eS(PJWiD8AZ^FrJMhCDW$@6zPk4};+rfAGN3f{>3h{`Fo7t|;&I=_q#= z(4uj_9!Xmn04t3KA%}taQ1;E@l`xu{W3;HS0QuzUhMenYy)}8M`yWwO-m_d|j@1)d z7l_4N{^Z7NVcL{O&fvR-pVaE5AI^~R8(X9Ps8J!%h`r`Kn*U>^X#=;jpQKa58N(`?7 z-Yz|0iKzx7&{Wc^CT5ri1q^9hZFf8sk|!4;6whFgertTyjnY#nXWWVj;@;nILXgh%QB+Fab>J79BJHMwbjZSJ^tc!PgolZ-f=sj)9r;0Dz0 ztQMMa0&$Y-hO&}e*Y>4qx5d0J*04Wej0`ZwP>$g?$tYctM`zR|X{}oOj|{k2XNabp z5YEQ|-GKXvW%_TYlOmb6#e93FJemVzL=+zVSoZgZ3$p^$7QS=JQk3npj&o6WI_ilZ6YmRrK!b~RX zMIsZ;@vc6`&7DyhG%jK>S1=P-yIS<4syab@jESWsu1XB`(_l?(T~>ze|HY5T#U z-`T-t=G4jV!u}~x4rvRdMt?-r1u7{|2C6uJ=yc)Q14U93V9(QKM)52fEO7HAovN1~ z6jC_I{1K#JueyN5aF@bE60V@O%x)6WT!$ZxGu75_C+=UkM8h>8vHw=t06b?(B(9Vx zL@4TetiDq5!0ddgK#`P){--Q70z;A`_p9DMoaKB3gm*xhv+1aquy>Z1F>h@qzp+AX zEf_AMB0k^h9sSu~*sOQTeTtTk}3mR$?!nw}={s<0J3hL&-8xc%`|DQP-c% zZ+IEg#q;l~oK}evnT<45v^bD|sCkHXn$Vbj4{`$i(^r&wQ#9}OCSEq;7+fG1esUj} z{w`nCY@1*4%B9b-JA8iPpvtMgjayd5uI$D1O)>s>3n>L8(QwUYq+@@`CEtASn4Ml zo&2e7)Hl9rm!IjBR`bV7hRs0z9?W$@*Y0Bchdi$4wWwYyvm~x__%2y?>`!nY zbH#A9H=U>wQ3-}9N++34dQnBDS8&VHw?>AXyYIx7{;Jy_Y+${S-aN?b(z|3MR=E@U z=h+;GJ;BK;v7OO;o1Vvqz`EP29!;O@M=hNkH`DRfXx=}EnXpp}Rz2F}$sM1?3FrmIU&nMwdumMm)7H&(IEO~ zJ($|j%0QULK+121XHwL%vKkl0kP2WBRMiFp+d#M%0juUinOG`9PC`o}_7J#4JoU#H znUcYG?nNa$L*lDwUnqK*j76S10}i+OK%!jyb7;h!FarZYBm#PeAmneR1Umsf_%Z|I$;KJ`Gx;L>sXV@djcVj>*p0Gc-kdV-5&>+vp!Vjc|Rp3YD+9$2ug& ztZ;Mf%M3+BFSA=&{3 zQd_LB@#y7C>fV9@q&ae#E~;rg&*zN)YuvS(>-UH&*z13MF2~cUPN~MwN!063BO~Dx0a46$DFEY26xU$ zzI5P02O?7(mGfSBHv3=PrlO+K25Q>+`ub5+&<@3~7;<8McMg)d>XZm{pqp@ikIxQ1u6Qd?Ff3n+g0m7{ak9Gd|`^y3A*@ zxMo!VS2a_&rB*})6fgXGdjmQ!6kf&Udq820jGX3>RH4C(Xnoysn%a+wD&ivUWq!vd zg2P2p%T;T<+ynaQ@EJ1tVuOaS%Keu;vT8s$T3*0(&`AP;mk0#*_$iX|MjKTggZ_}z zlpqdB2)r?^#VvVwSQcoWGDr)6$P^-0q=-fUl}|ZP;aqankZ*?KH=Gi=f}n;lk4rdiC}cfe)QL#zQ>^mrV?>?xzJTG-SYv! zbzjPDa^*V~;?b8#w#UN>AYVtvE!*d#l)^ww7P;}#?33{Gt>oT*voJ5$?VaH!oGcj; zcE>a2-Q6%;jbfWwKS{xFtg1hLgmL^#sdsihZFji5Jj1uom`W(BC}7+^Jv&4XIHTuy zsYFQ&HzDP6dxz^XMQ%Non=;R4AA!L0*%Bn10NUuB3;vAFo2(!B?sM;7&f;%>Z=@3V zWc2y9uV*}yvuUnEwhGDXM@16_#fb0FDevGIf5U`Fn;ynbX!O3Wch?+@z9j}-L(vx}zaMMZXsz`Bip9%g#V~qlvAQ!Z4q74|AaDwHd{uc2B>UAR zak$_$IGDXgQb6ysoapv3`g1i@3`6}lhT+T>t$IN!u4uE@9&X#0*lo}_l|sT@fS$}5 zb8fcwIqp~AMzYRs)qx|2-2U|sz3oTeg4-<)y${{V_~13V*lz^fZX!(SH5MvTp-8`r zW5TE36J(`uzSpOSr^u7WW2$8(&FYyc0n5NCd+k``Ew~m*}N|mG&)>^R@Q21b7`Wa{h>m$=By?ekNK%21>(~x zLEqsRVgaha;bTtyJKl$cQSUG_+2laFuP~NZ`_~f;KMR6OnUJ3eoos#?$sZm7r_gAb z*kpAp@GMUAlYY2l2v(YqNRbRGi2tf!e7d)&T_aCO8gNuO+LyuDG=IR|GD~Yr@p44( zOU6^DpSR>wI4H*%3dK+uiUeyghe4z9FvaAFq0BLdRJ>%X?qC}4cmlw(UL0SQ2983x zeF6yQT#l<~Bbgi*nx)b%E%q0$&|4L;Gx*#4D9K_?5J(r);%fEN%J}E5%u25M1x@9nn>G%r`0WyW|5!iJsLB# zi(d{EAu7XISJ!1d)MKf`3!=qO$i79}3Y1&Q;Qn6l53*FsUOZW8d*Dkq)*;ZwDWAky z_yligQehf5fc{;bL9-$^ol-nS*fFK_-e+SjB4)LZuN+%Nz(C_h0+WQ*Y%yo)pO6U8 zJHPZ_QFIQhu%;@J<)mT=dqOy~+Hj9!FJIwVL@a|&%NYiQ(E5w)&ML-{xJh1Cm$m-z zF+zD-Yo56l5eW_;c{ER@cnyiwQFw{;BV3)A-Ou^}#fr?u_c(@fgc%5rsd25JOvyN7q`Q&tK{R3Mn>@+A$AM%*4eNV&Za<1Nre&(7|(pw3ya=x^hm{ad^*%q;0!z;%QchgP|%7YOM#-!`k z-Mig@Pz}uE>8gF&?i_YyC8U@NPCL3@t$gdo}puK#i zdXy>MH0<)_5VyUbpE#0Mag)yj)(UBRWnW z_YDWD70vSz=Vm&+qQB1rz}ZCW&o^J-~e{ z-~BTWcqc_k5hermhD3J{9xq{5t`v05S#p{a2q5%Iq-;__2&?@(=t|#=v&Q1Wfo!Vy zO?%!l`*0^2G@_ev5k@IkiKw*MXNe*sIP$#iT*v8nQd<1ExDy%M2Y-}5ujyzf zg2O-YL|4Ej(kx89P26F=4%42j2GT_^>G@L?P7}{>KsKZ+gx}zo1TkN+U`tDmWE$jW z`wSE>E5w}c?j}^sxtayw@uy!boH?Pr7pN58J?1@5oA7dJ?rRGXV zXlTdCNbEW(?P~y?mWS%pABAF*vz)uTyLTV`nvUnQR?WH4aM#ANc^&TFp%LBpSXy#?V4 zG-4ts2F>j3?2s`$vepzkqq<{;S;cW6E|O_$byg7Gv(&O^X8B&H_{9=^Cc6Z1j1MH- z#~1*XF&2_%4Y`f}7_8cYI2>NWYS5>!Wqz|?EP@x7Xd;1>>CK;^B4vIPKKxonaqOZ* zzrx0Td$urYg2e-04YJyER9v7A6>xl!QBC>Q(xL$YjnP_2gPS({A2tp{+3x(D&q>LZ zjdp>+TM}w5EqeBMyMIkYj@6K&Y7o+?6R3d=C@dBgq*z=pJx}FvCERu0oo^uv%or0U zY5Y5|ge&-#uN>`#o|rJsuFkFLiT>wS^ye(#B=%%?TJF8tcKiYG$x$ujUy5`v2`-6{ zTfrZfS>MHHve_K&4|OA3Spd4sTlo@GhDhal`w0p8^=zNB^;{n{WiR=nfJ%!wcHzwE zgD~gaVNt%q!V7ppz;%Feyh1hQVjs2Lhq4YWIDIob_5p&q>J){PuoZENr8+S(#lDUUI zBz*-?4V#s!s0~;mtxU{&^Zta0Mlgi_4ZxEUdtrnOB?$DU-T_1yxc;XCzN9~?u%F|v zU=0AASmJ!ew2twfKc!Z0IM`6d;z-)sNE}c^+~(<9@EV%er>J)>8>Qqg(ZRBmRCg>S z;c^oRyx_Kd)8afUpeN6vj3ED^9q>-j`Lt!;K-c(JPoOr@F=bPSz)^+ol1T}|<$9Z$ z&sJFukH1Gr4{;u?hxoGZ%H39?`Ua2aC^v0S+NNRz{bbkl7^vry7bIw{jOu7x*h2^6 zRMfui#ZF0D&ApjvvlJGpjlk2=rmPKi_|w$}RORJFybo}HUF!@i@O=4QLA$-iO84S` zT*($+CH0{iQvKfLS^~lJC;hHJau4ZW;41B;Gv*JVbLcn6jO8hqeSURM_aavj z~bZZxN=N@3 ztk_<_O2?f+uhXA2#0=W$@afbRHzF)z&MuD6NaybuZNb5!*IldSgCdTnrzQYWgeX-7 zPQVEmrHP zZH$nOhz|4Q56huJ;lkU3o@*laF_)VHPsG|Z%SL!h_hK6nss-9K+cV8?Wzr!{3nbN4 zVh#RX3IS7$NVYRy%$`_f_|;2WUgu-9L>4VP=jHD1w=zngEy0iGTcV9Pwrv#Lpg*x2 zTRiX@7A`_huS37F;$UJFkukv;8QK9IN1&TEUO7#)%4#kw6yx3ul?OdVYw{_yQ&&5j3G04~3(~sBHRxT!@5U(ZaS$(aapz48&ozHE=VN zGY~mTUtgX@Z)Hs8bozidt)Q~iJB9&2vRP%t#KwXpOeSDEn1^ZROEJ^bLg&b5KMSGl z`I4B9o0Df1Svywj>M92tJ@&9}Kr9&*2u38SUwx3a(U&d9_5&*FJxP)4&c{P?o0=`s zU$~`bCWtr#{FrxFBQ5tv3L}0eF*@G1`{u6S$jAW3p&|5j-tH?f#8Zfna?Fo`7(bm0 z{l<3wMdJvbe`9Ue+EHz&aMtIW)#{`s&2=*Wbz z*Ph0^FE%}fzXxbn+pwxOh$$O3pJvO%s82<68Br@&qpaV^w)IW_X z?@{0KeeGHGQU$NXIR`n0!lrI7V@v=f1yKK_ql@UdoZTKRvydyFf64HaO{+lT>^HnM zTVtzk?sd0F4f6K}=tl#?5W}i0N04%zMcS=aQT;n4s^Hd>V$vy#0(ot>3takdUBd6eNG82wM@f(D?J@u4dY?@)o0MYORd$Sbv3M35J9246FRTCZWvU{U2rf%U4jKJ9fFpm`ht3{qp0Cie##s7O+ z0gT37A9y3iV-bN>)q4P#Dj@<5#Z>QSYc3HlU?vu6ZaiSVW1()Ah~I z09Jf=gMT9dByy6Ds&yhSsD!(OO(gH)lShfJWOS2VmeKb-kM?={zV(Yc;2iZt6@sE$ zYMouqQuJtv*qnZyOTYfS`t>V#O$0l&c(aT{>`HUg`AaEp7y-i+g}A5IDIU$10)?ja zRN`o=kcnVfnXRk-$?0G;505q#U5hN2Pdetc35uf~??oag= zsw%mm5!|m$%>rr~7Nd3vJ)d!l1x>P(KT-Si@*EmIwEYWSo%DErCwt8)Kg&rEE;{S+4BTBLS$X2<5 zrcFMB0~;qxw0+#=bAd@!D9KZ2!4Yx)gNNE()Ey(_rvg8j}(H=*MLdeK5%r zW%}$PZ9#0pVwvb{Ew`XRkP8OEku=|)0Q-QZgaMA7_(xD99Uh2RNLPcIP>6_#IDv+= zdw4{%D=9_+Dxmx(1tTEZc>@=Xr`9SngdcCua=UM-|M^XM^muc1HN@L3LrMpj2cv4Ha>Z&vw_Q1N@?v@Z%ZY?F$-IUN^mzz50NwK6?w>EMIzB zyJE%hA@xk=qiWfG9_@yJSUxLI;z-6*(OxGkp6c;>Mx~U#?P<;S4X;N8b!euk14d7A zn71!UCqAjCdUivpKFuS~bJCg}y(bcX-Z`qR+*q3?E6*a2BPtfISlGOJNtOz z$-(g&YgBw3O+NYe6ac4#nW_extzaebzhA^36b7>DZaDKgnYd69==}hOAJu+&cF66# z1f!FChhh0ji$t>@p=vv|i^ngD^Ye*eTL3%aqCcwOIs7lEn~$H$Wpd~IWH)vpKp|>6 zHYRO8?)DQo827CN!brg)LFM@sT(*-Fid-L;CQdJ#)sQitI|7ejKYhg)hoC4XP00;at@?N*zn9lI!_e^Cv z#niZkw~=?EBd%3t>j zo5CowXfD>l7;dISTAQ}j!o9ana$B$JB>9?O&1#rA4Q_|Nf7|3;+AzLm@~wVTq{U=J zXrg!~=%b#8Rq$;yj{u_{qd=ok6#64|^4r?o+-5z-V17Co zbg)1rhs&#cD_Y&uGC2m(ac&~6b+Gn@)q^<`w8WI|Pmx3*poxjgAv0K_N9M(QonJ3h zn@pG1M{eE-ST=W-W=wNgd{_S7>TS?`uVID80xLWYU#8r82a7@sm(E`K?E>-mIV^Fl zR2WQjo#fmz_4Y6naTJ0jD~!X^+HAiG(+g_(t(bR!$ay;=ZC&urp!R+aobD=8YHqFvnvKpusii13^1 zyCCuD>;9Fbu>J~e2}Xdd(5zKd6#_~KguYmYe;d1%%`y4oDirG?Gx+NF`v4LUcVi$9 zQyf*xSPbeM4bd--?bfFUr+<%;VXCkwV!lO1q&z}JVCn{{@GXtU^$}6&v26H|@<~ct zGlPi8_r7>#=f8p6CYm-M0TE#crPfHgxM_Pw9{Fg+ob2^s^p!yt&fizmU<_plJfal# zSoz@}=sAr10rCiyW@&-neNg$g>CYi#cmwMqiZf=QUKJgkegiteRc4wB)Ym080zkB0QBS z>9sh*A$FwO?mQ(M8R8Pvm7Tz-#4)mD4g8O0oE+nF51h0ew6M%Hy0eOiiW1rzHo9SM zXI++uf|I01O*?paax#rbl!Ri@nq7c*ohu7|B8|GwnH_cO@NWN5cP!oebI|jtHR?r!(ZAknJig3Vy*+BulGmX%mhLVN~Uen!TOI?Bx9u&Xno<5O+RHP(Ft;1i@p?K_+0Iqtb&5v6vsj z1{$;Z(gxg8*U9UHo(qf9Mmb#s6%RAbfd5HM<&9!zk3-<;X{N8qp>4$jIHfc7_ zAwD>pmx_gOltF`%-i!7U=s@V>hgY^#fe&^-|6H}FY{TC?=mBndHKNkE|GwLnSj3H= zS;q6t$Ec7^JMvcK>BI*q^m)o~rYWQY^%cP74=l?*&+Nr+-LpTCg@h(p@W}iMRk^su z0e?f|@V&md5wJvvDst>o3IeL5cP9t63Jfbl%Vi{w@aVyTyHXMXJf298=R!X((+*9O zmxiFP!0e&BV5&@OCki6aZMoGgPpmd!N$etL)*HXG*SGcwwdt#;tHz5Lo?raKODfP$ zsNVa1j%YTJx`$;O&Sa;&<^RQi8$FLTaf%sWwZ03La1_XfE z3qt{yjZ(448&Ap^Lru2)?YoERl;olVt{@z+t zUSXQmdN_8Em)k}baFckovVWc|sL5*lvH!$dhv*QZ9BYfDOP{cvpuo@POz5ffS%qGb zzW1ShG-#f&J2RJfg+(AOT{k4@H4$|g%SUCsd?-{)pfXcGds;(zfM9Y+t6KWm?_}T2 zH1ZG?mfY>q9zzRfsxbdxoepcq`J22{%B612q{xFgrzZ<1DnO`qv>NL<+YHANMt6!3t@*RiuQWas7)!3&8%WF zj3Ms8mx-de{4Tl9>`OOCvc+h(^;4&O*~USQ7>`c&{bB26sD7s|m zW6!$IIifDmY{GI(u|SM{{bb)XT4lg#_!30<#@QpxIUf&x{gc8+ex%%?##5oN@3v|_ zmIhZ#A0Z8-doPv&^j}oDtR$=vsidNsM9!SA&fTLo=(k%z1=+WWAu<4|bbuPc6e|zi zP01?-R@i#{`$r@eAxnAgFt|rEtx9~rU&TwcI+m!2GTNtjNHDb4lvTzKpUo9OdYKpM6d`IoPE=04Ke`L%S! zcrz>2>uibi(zPg80W?tA3m>ZN5OLu`mjh&1$(!OM-tDCOy6tjz`a5upA)z&A2mtwV5qatp2cFXY-2}n;OV- z>0ycFi&}3mUU{E-&FFJ{S8kz?wdnezGn)>T$I1RaQz4!>A~h#|uo1k4Y_2^>v?K#> zsJJX$^EXIUZ0V%9;Ah5cMwkIDT0KYY+0^djt%b~4Z>VpnM?`4QYAo~1& z_T9D`HM~%OcJnNq&F}aYXwz+3NR1P}kjmRClBFyGLlZ!iWXcq9jr|Zww(55xV?M{k zQj4*`FbwY8dux-b--!b@B#<+k9d^Xj+56#oB<8vB*Nrj{JS)%vfU=Z>nj)uw#k{$CsYb}hnyb!lSD@l`Gbh;r!_0%) zQNP^(PVdF{j*Uu3xz3qVj_0ZCGC`{O(bDV#0{nsU*W67$n=HWZV-jJmTg^aFG&Gx$ zc)b5I1c0xKF9zh%MQWvgX`)})k^cZG?rM*px^E>)!|*lRl_4QXlwy8@(orOz6Lez% zt^)Nv-X=RKVMdk@17;EqL&k;>;6K588qdJ9OsOmNp@noGtO%4Dg@_sG$y0tYtiPXB zJe~BZhJJ>#aasDf7uirG5K_+5J3Rj^-Hnu>`^f&&TgR=rz)Kb$OO1X))4PgHCZ?Fe z=Z{Duj}7j0=?RS-)PZhtBfurb9d$|Ff-@)R^08tTCCWC&m0pP z*?cQ)+LNntNoCeC^VI~5Fh^>K7W3B1LnC-Uv3v=~5CqdNfGo`mPsat=Ec9t^jIQTK z@NKDH);D;Y`E2{U$JiU+YAX^CPnO&Zv}SISsM zSsfPnpN744C%JUR^vF~}4|DPKCk0)cu4~7gQ}1#2i88gTgQ6Msl402@uFHHbqj$ri)SYGlAOfqlXP7h9kR$X?$i z(Wda#0dcrZ)oPnb`CxO<7ijhMeK6=o0&GYyd+T;y|zba}ilu&nySfrh5jh$Gz09~Za$KO|@#S2bd(Zota z3Bx6q?P8RQ-)&A=Mm7ZQL^ByPF5#Klw7gC0r&D^ z>6WSOFNZI))B`qJnVAA41lzc;fZ1yH#Tk4MbbBaQnLaCz4%pVFsK?G5kZy4fu^bbB ziR$5-RTlD>0*CGjZyYT==m!d27gFFgRer=~BqFmFB^vlVt%abCQHgoAAOC>KpDi1{ zH&c63z4R!7&B#yedD;LW4Kb~DvYWOf%o_md2Ns@5=k;C}(F8x>6c3uL2dXM-Kyl}Y zEBG4VJ@IRufH$l{$c$y$>u~k;WMp*AUp_Sj9QCzTxzfL-Dn!sfltC#^V3bZ2;8_R` z>yF9-gnwkrCh3{Qiy2CUlNm~q zrNAHBkJh;e9>Y*{wHkzq=~3HX!$vs7A6KP?8Xv2 zg8wA@z)n6m7_83i{cX2A0<6xENehTlM`!0`1`ub(|5{hZ5|wrS+%}S_NL-!T_%{X9W#^U}wB&9b6G?+Lg(cAQZ# zkROePF-ErXK5H-1lMVAb$D3m}lavUl?_cxnT{D3n1G5!B$Qeu$OKuL3q8m`PKdDxQH6IkA+^Pr2~k)9c2e+D0{Vq|7z;_6DyqVG>Mi zvHLLJ>`(cvtS3HW`g{)GqysWO>ii)k3JIlTo!XHe#Vg|cxHkMQC_Lw8cj0&b z2lGGeazdzfxlNYQYDAFhUu*t#4tR}xrA8_=4pr+_ru2g}fbD5MuoMI2G=Fw9j0=K> zQSnGxvyr|G56bDd_p|;e1P)gPF!S&1Dz=47Esr#ss&@d;T2BvV^0q+dB(T7+iAJQ# zdwF>0SL)vMV?Z74S?{e!$2{;RTRb5FQWoH(4?5*({>8;$5~vp0bVa5x08aO!&fIb- zX*A#+-R?xioFt5vY^xhkEWNi$k(!H~HN>-k4@BK?uqFvQ*5ddIAN-zg2zy}JiR;Iu zeJXr~Zq2M$?HF^L_MG;`J3&<{g&9eh2}C!2+P=T{^P9InBa2epdE#j-d%lZgU#Wet z@#eEXL>FlhahAii0mI)z^A3~cPIO+u$5VwIc~tXW&^K4}apXs(g`V-Q9r8qKa!OQ; zbrY=4hUkyYIGZ<3_3@mEUeO1v|9%5C>3GweITiiwz!?!;x$n6(86HdP@ZG5VWWhi6 zsdKUyx!K29X%O?~+S>jPu$Eh8%fPO|rmB-(rmf6@EN|9%`||K6{6ywCRsWp3+!@rTh^#=4zeJ1QiiBy?gqEsdK=~Y`GrIfP&cFzU!Pa~QAMZdNtku>^52Z4_wIhx=vE z0YsQ#A3uIX+V6J|K?i`4Wte;t3k_((rwDZeS&^g(xCxo~yB%wW2=VOg2! zi;8{RuZ1lVx`xhf9$Qx~)J%>3y_T`&yfmL9enY9Y+53}jJE_XxTFpzTg<;JbS-}*F+bV|r;0J%-^$4iC}ZPDn7{#m6!7UV;EfVDFhF;m1R6y! zFwmHCc|K|Ig(3~GQ09quIWfGz>(al-6pYT2td0gi4_PypeN*+b?9VMv=m@5Qz~yS2 zQuaY}mg%WkPlt7Zb_+CnWXr;qtN8|_#npDImYM(4d@e5I8v3wQe^GYz{i|xb9sO zJ3=g69r>vEJx4JCry9kB8}7?p3SHqEXOMvK8{XQQUjzvwUc(y@L0{{DWY$SDM&AYW zpjge-mYQOH`0!!x@K9}q)Mp>C0_*FoT4!4U$9Sg7G8UPZK(DX_XrZcxkwom}z{_vy ziaM_j5T2f%GF2XeA}g=uFw?;bahYL@BxosK(V3~WCoj^{YDqH;SO!va62`{w6E%Pc z;PzadQX@Zu^KuV1qVjd~Jebg|+!o;PO_XOZA)%iUFD3Ned)Oj)0)4i%PDly zR~+!#9uF5h%LHaT8r}mH2=KcZrhU!!PFUkKks+3`&@u!C! zDf~)+=qHVq-NN1$()wf0c=_9^2oOnhueTUL){DDIXqD&+#jazMi9zgzq(k&H2oend z0gNnQHfR1$d?%xT$F^1r{VPJ@a!*E3F7NH7EAGi@sK(`AI@%U~XgTr@mZO`OH-|*v z{fnd?0*dCd*q{%pq}&yL`xH?m6R(Y8vTJdV$m?(&<<|cuLu8Z9cLjEqRV-(od&3g@ ztCE*y;;&Sn7FNbF>EuI0FP{+prZPORlh+FZmPQn`mHRvav6TBjVH|n~2StGU#X0tA zhn(AC;uidk#F0w56@|UoV2`+Hm<*Ph+%sWjSt; z1MuU!bJG-7>b!Nub`7sWU&ArXWi|?zt(0@X%{@n?MI^)q-`V#wJQe-R}eCu}itw>5F{@a^$xA9TOT1|%c{Cu2fUn+CX z(lz2X?f%Hvq)6G#UVznPMcz_tZ6xSm`e1xqfI&IyUuiaY{k)mU7xVCy&I2%vRXw`M zA??RkSK~+O#Rh~5YaHF6Fqq4OMDUn(C=R6^2#gq2I&eoMGO;B=@PFuf%6uJexpXe&SgV)ZTJ+_3rschq=j#`WGOu0P%(zLh{ zXV5#i$Eh#jcoO9s=~LQ{oJ52HM$UoGM0!XSvB{S9(Z zHC}|$*koT0XD!{%dh*CD(kJX#oGJe;Q07F@TKvDFaKa?i7=Q|Ji7jdWve>c$k$IB- z&@WN%OWZ{*&c$y@kzVI3GzlMN?@jY<{>&(QEK;?K@J8pi3C84Kmy~k)^->Uz@x>jK zCc~s?#!@srpf)TX#t?H-xvUJ)+7DN)#H~UjNczFhEG5CfV*(BXLDq65);Ik}x8K@s zl;fc8;?7x8AAow0YR0dDOB3bQYxM*eBo;8*I%?Dmva)8*N=oYp_aW<$5X!@oDV#tw2S<~u+CRg~KML(kJ$t3F#XPPEz8 zSD_Mtj7#GLSv{a#K3x_lTlo1WoVR1}{cl>eWW~MVq`RQMjn{SLc=9`FgZK=c({G}P z;WTQ+@RibEeA|moHT!+X_PqxW8K}aV(^!$9R-f3H2h!}l5iS%ygiJtXlwj(y3WaTp zA|-n`Q+`5@PYg<*XUWRdsdgV+26n7A4QIeZJ*}NU>AaqU>l~T==!ZMi9Y7aePs=nL z1|*GMeF3s3DF4+C0pDLj6ib@{UbsXicoJK%jdZX>mMHI4Rg$}Z=p+s4_QF!9%}1*S z9eMU|w}i#P0^S8iTZbm2Xbf~lsHoxnUz!ICAl(I-p$bS9Q-c$uAd+BtTC{HU7lR=L zpW}L}%TNZ8saifgjE=+*{O>Pf0gq;8ff4jzU+CeJLH@2x2eq;iR)s_8or*}XunOB2 z>sr`jpzi@3dugr9CpsjP_t&Iy# z>WQ0`rWED?C|KP^ePk5n#sgWUp%GW5;Vm(JW6+4az?&8V$g9^{{4UKP_?=;WNk$Bo zq6=P$yoY7+lpcKUZATpt%=`-|0YRQ5u(E#ylW?2B>+qVUGF~d6nc{<&nvUDBt^+(G z0o@=CAbkYm_1(w1poo2}bnAdXmxAU{v(YOAj3_RX}%lz=pIIO3d)xs(=u{i01K5dcuFSl*ADi< zVwb#ZrD;(X`oA)ObrieXwIqkR3YZ&#jk-*x1VA;Mylx;_{@Y_Jxw2`JEvTVl*kH@7 z9)EZUUiPs0nIL4mz9wM#08^bq=pdwHhPL9Hjzq-`_W8Q}lxxA-hw@euCN0l;U} zXxg7(3JnYE92`_&pY}`nD}VtkjydJ3lf58 zFjOg6`x#iMcEu1MN)QVXWPnN)Ig*3#qhu@}qJl%IAa#_gT@#8b^n)Y18y%dXZipH> zSkA`dy|qqWiq`7j1@_&>rQ+EdD|d@^K(i3N$cGzeSbRa*0rG zUI}c|%z9(0uexuCICSNj_%e%+n{0Yd!1Hi|3S|TmjKTh&wVbYo)y&UDsnXXyM|ENx zP{`T_FKUgY7~h)@?}x?0_kPduv&4AqFMYFNn&1RKSrOG9!urSwD3C7oM895(ZZ@0U zwr&I~#RYIMm==iCe#?J^5+cq+9SP>j2@dc>wWudps@3js)pqlTB8-D$lRsrc_@8~F+ zS*i3$-2WUc0)Zrqo*JSEIP$&*6oaqz&Ss?+On;eH#+az3yehh?@xJ_Rx!trcH=};? z;2S@SN#NaF6mw1T&+;p4+^8Hil(xIpr*2adQMl}kgU!f^KA zspbt)?*v_4D?n5xg2w3~PLJ=zX8E;$^7lMLkZW=V5%h1|lu=ln0X(w(114H_YjC+O zM0P9T){%{u&>wxPy?^&+0d<}19&x+70ZCpU-|qOlhzh7B0bwZ$&^i(dq_M@xzbV6D zXm{@3ts!#!`u;Y^5s^n(AJT5FFE}|2n+sG#Kx65~*AK6yufeFb3a3TM0>|(I{RSSO z*;1-99~YG)6T1Xdo>WJHlx+@B8yR~-Z-+|w=bSzoqAXJcb@`3V82X+bU-2Hl%j^kD znQnRbUDcv)`omZ~3f1Dd^M6=->$oiQrfpmi5k!TH6a+=OQ9`;e8YB%=M3EE(r8^Y# z0tBTc1id6gx;sRW6a}`QJJxQ=+9XI=*n;yroR;^5M8xN+(1?zI5S7)-WNVC?MCX= zg}$TmRane<3onwl_{}Y)f-Zi$C=ReDc#P|j$UVlhOqd(0_Pv)MTUuKB6=rlJWp
    TVQ-14{{- zA0B>UGv0jOeP@Gu9osn3Um}=z`87Lv`}YDJPm-(W!NRXx&}Kot0Fp{v^0ZXYo0F70 z7FS*_*TG*D#9?z$l$z=!GWpVk`Qf7F1xrZ+SuC!SW=BB|pL*DsJT4~y^-#rBG6bDa z{zF)p9k<%Q+xD}w)H%p?Zeca?BzIzVyfgg5)0cmI9KP07K97^}l|PO!oAHH-qY*pR zG!j0i!(#x_&G=P*o)ugio24{t9P+cSDV@DM8;s2q27hKmW$TawGscUMq51PL!vW<-7b^#OLu* z!uwq5DtN6>OOt259E0)nJd`#&*~o~JJ4f5w4{*hPCfNjjD<^^?8<+CdJ6igCo?<8? zegv}$E00?m&VNc+L@p;I?y09~A4}9TUY<`NS}N|e4c2Yt$9S$HZ&Z)enI&x@7B~AT zL(l$?>u|FkrLOwbn_heE_M(@k;=J8)%5N#bJj`mEdhpvYp3=CdVhf+92%ckjv?Da3 zx8(3-O5<%80tUNE*7$Ac?-1c$j&pgO*~qid$n)rHw!0=HMtvz>Je4rO3txy2xzYF% zZco&+E(;Lt#LiqZiA91D@nQJk7D%Py43DQzae+5{A^}!b{L#h;N*IXXMt_{+G&S{c zNl8gLT3H@s+9C{HFz2%L!&Fg23Qm!2{N+QQnqK6=xVBzbNX#1JoLK-sSR<~2=B9$_ z=1>1dAs2IwbN4mpqZB8D2T)Jd?jd-?i=fnT9lti+;wRq%DP!o$xeb9^3cR&5!b zx^P7+C+MnDM89o8bVB)z3rpWkEH>9E&dGR*>1xn97~eegYzqJc9R>0AvRSg*6}uQ) zvyeB|x?7Q?gyAuX2Lhu^7?!MQ;WudT8U%ve+}xm$l*`?9+ux(*xn24rNaYnjcJ|JL zi(U*@*uPXTpjogdsQK~1i*R25M(%m zMYKA---AuC;^M&)($lEv#;{#H;)a#EB)Rz1PLB497$hUO9QjWnp5J zixCrnPrg%3xQrRjw0Y}AdidtSM-xLn8ZJ^*`TIv}Z{2g-;kxa*;}u%(A^YUR=Di-8 z?{G*Eni(^BHjbwcYVNicsT&UssCb1KCs07%| z08^VIG|R+XH;6$Z@p-PlL|_Ui`I9gg>TBH#ka}0umAS0Hk&p;@`i&R3S1)=wzxSi^ zdQs4VNYRmY^V!zww1NPInjZoZyC*JzcfwKcM^l;-Mbg67y=g_ZJDGz z&#lkt+I?l_36CPg>{XjF_v4%0_xXU^RLXQWw+sS>QIP6nUW8|)rv&5wBS4(8Ku0cQYj}blpXrdgi^nW1vfdeSYl0$ahaP6*cbPHFR;; z1ojV8FTXnhr#BPlDaP)1bBpZ#Rpx?Sq9}Q=F3(RW$BmVf`FO8~hwU4GJYGuZqp>{2 ze+T|L63N8i&4dP`sCW(RT0fDYd{&n?mrbB$`}ECx3r*W-9(@U9l2lMFH!`LqGK57P zd*|b0PO}9RF|j8M&!6TzM~bQef7h9=_i4UjKRw57^W?!`J{Fi^vX^%!`#Ust#>+ta z=fe7WM7kZ*h@=XHhV!Lwp4?`K&6TVtXhn2nK4a11Fhq@jgz@Fl3KM9I9d+2UR4d$f zFSzeGE(SNFrJjK0QY#wheFnC-`eWwi#>S`s$^O*iAql%hbJwly`>ES>U%h=jeF$7P z*9a7NtjOFuN=e;27-c8>XuT=%zvjgGWN9y7Msl<|pS%_M7?)>6bQU!R12AW`GFT>Ooni~bHNjsvuMr^`k-4o==0 z!m53YzeIJ+ZpsnI7fp+=OeLIyc)}@N;gi zIoNNwVt-HjRt_S(z9*=c^JRXrJ*l=m>BC?xzX&<60Z1FyitT6p0507(zrpYVO?Hye zK1dpl!|1(k4s-s4US@IwUaF9)p&EadQ8Se~k8sE{>G>hLKc^Aa^75Ap{BS)BORwHr z14}kOb~V0$H9L13LfMu$l}QgD1$!nFGMKFix%N}YO?I^^M@OmsoyOYKhR-ETZBNS) zwHW+Y(Ut1bj-pNvj>T34{7@TTPvt=CV=KHOqxteEU69~Z)PbbQZ(05=O%|5l-W~V2 zZa+qQwruxfG{;L(zT+eH27!smC&6M3guS2$KU}$J9#fUEIP}KJoicut%aSumrd==; zEaYi0)*8O?^{C39_fUmS<0t1oH;SKZps2q)$(@W4_awA^)GMu{j3N-8PZShKrbN!;>p@Go0x!}qss|d|3BK9*F z&|)dqT*nQD$v#vxx<5h4#d6+?d%bP+r;R)eeFjqkd(b=Jgc?h_;lj?o8> z$a!>L-+1~tHINzJ@P&d1;a>iXb3_ywa!i1BA95ldpu;)RJl9HMzdCApesQHtS-w8_ zBGd6vJB1}f-!I>f=D{jBDNg!@(P;FF=;`=HbsOzb}38?WLuqy9%t%LH9_~1h0Cmn2^nwYA%ZYTkX3P zE4g9YyNFw#P)LOzB``No<_|k8CQ~{0bwRUoJmeCprl!V6;eqn23vVxnbNYoQC9%Lj zvIJJ>1jae0XL=rhECp+p&~(G@k;2stMwXX!w`DdA*>MVVy6;^?MTtO+x_Ex!hm#O@ zzi42_pyZ-)UpvL)f}4@A_?7J7!xJO-VDlm*xeNPe|B6D;zO1yZnU+pDM0*CA>`hJ| z;uC%bch%0!YClON-Po9wv?y9REU51qLcLfYepXnltx6!lKU9GL@#vo1I93C0G8?lj z_$Aa{8H44^2FbzIa%yqaigBTgWO{w9`l4`1xi)Wa!C$vf__2|!Q0TlH#(!vCHTeg4 zD$B{x=*)PWKM3+V{0q9#Fyc{nd$sq)&gEOuUEG?CN91IJ9$^{(2*KB%flYP%w3xj; z5?!l12uGD|(h|6^@UVv8eQ$?g)g7oiLCZcV7y$d|XVuZ<^0#L)x<9YO1lQ%00|rJE z1fvjhj|ZV6PE@Ul!KA%wsSPcv=({AUbA3eum%P;@d5>CHY@LFMg{@ir;_#20P9`kU zXa~Ze4qe^7K_OpOc2yu4?M+}-_xr19QJ2G2Z85@2Td++4mx3 zu{wHqbkg6!ac`;&M{4gx1@`eZ`s!__K>9dX2y-4n%tddKFoZwr!L{sj4rm{bJwDj| z-dm-^V+c*~@{%3zS+xtARk#~Idmb%4jWW9^AWRl^dx=W77a}EDB%Qb9FJ3MW56Tc4n9sce6O01%QIBFDuOatA+WO z57%aNy?uNZr&JFuudX6XA{M7JDjK3kCZVI~Ng9=CUw?lQ&F8&dIR1%x4Dap-h?cYNh+r99Es@9QUfH z_|jnx&W5Cm367QQrsNMRt!^wQ`T1^kKjmDFYcpKg@`hYm`8qck zZ-yp}TB)}h5F~uRG2~H^A(|vS9xFOF;9}ft9k;$b858N?5$7;hFYXY#DdOId;NZF) zqf-t-lK_jJTqXV+;N* zC1HXAVJA8_HZUbw`U#%#Ig^%Hu5<1iZ)f^TuEF5Zd$_fk0r&VxQB3lJ%nj{Zqb>7B zje$%{wQt3}B4c8iQbt5eUXC;eUCVwQshu5T@BHTZ5qv2+8&VMf_~XmG}B;cm)}+5_#d1NTHRU`eKImJ}lipCwGpV-`uN>8%Zyj z3xk0^&L29AZ|LbM(cR#Dzi}jDTQSTp!sJcC0t_6kvhmI98zedxaYZz+E}~>F z{9bLy9RK=-*{(H@#C3Y61{a~@da{+0I37F2Fr#xzCGgz-wc`|J-zvQBnZ{?2$FY(7 z$1wRU6CY)In$I+sIFxswAo~;#J!>eFcODbHh30vj-D0&X{h0;@m>1H|h&`oNkm1R< zE?IV4Vc*e+>*bvefw&%EK>wD z-bTF*^<5?Ic?b{h4D^XI%C~|4vU}0iREioIMVR(XGGux3dtY~TP#R1OVbWDhVGlp( zC~b}`KYyMv41ywBkvfPi+9y($+a@jsPz&(Rth(ch6REKaOb$GiAI_edwBrNcw7gHr zp*|SrGFRleQRuj6&???mmLJTkq~@A6Rox>BH1@2b#TNxD+ugf^luCjT&-Q5o)4JvD zFO?MRQh&SqmITdFaK!7yYrNW@_#@4aVsF_FeAmjAdWc*9(60W;A>1~3ILAmzdcSSL zT60vw@;%wncQq+$ubP1_`;Q94Yg$f^m4UDyd^1yq8v6 z_Uni$XhY)mM3~v%(+JzsPd2vKec9-)Ro`1o`u?PakXL!6uuXdfpEE}MR{4$1{1}J3 z1Vz(Xk6NQK>I`vVtNisLT>dc;)3$8Rm#?zv{Wwu?XG{?%Z}JMw?1>4kD{1VZdntr# zKPN#~vQ87KzjiKMa)0Y)AdNUhs|N?mspO`dU@r5)pfBc^2UJ^ghr60`9!79{v2eXC zxyxT4IebExrA61;-HS%6P=niMhJ^Av9b8DMLpZT0DfHrr2RfqpgJS8VN-r>2b?iA& z`&6;LjbXNqrGAG&A2(_@A(WgIb4MLs$CuWtCUE$tf>l#pr}Y?^0SE|AFfYPP?bA-x zX(z1NQF06y-qYRdM_UG@c`%swx{uytu&v7cSZ}-8XCdcv z6}C;3-eZ=gQZk}23~ND+VH_+Kdt2sGg_#X2(o$;^@*?R>*z0yN19|!ZV~@5b_r?45 z88Y8LzpKtJOvb7qm2Wk8wyr}gAo$TwA45!D~EHb116hA=lLJVbaRXYffc35nkduee_Whe6HV0> zGB!Pat0Q$^9KUH#_l%|5+FFBrufFSIjn~ZczzmlZYkzs^M^?fy(u3SpN1@+nQO z)@eGe;4vdp3A|)B=VtBH2~-U|YOlW-zQs@GV5UKVpBzDFLU7$hGgaL8hDA4be{c&w zbgZD+9G7ZyXs^9zogNew>PKPqVz0@zvrwB{8co1V7X zNTu4;n*EloQ^0LvZed?m0BI2l=iK;3!DwX}$dQW6)#SmN zgI6u7mi>GF+_cnXvYl_@NTYP>zQ!4mTR>UEVC1Fom#CwL_yOth%k72{GApiM-$-Le zsq4|50k+yB|WFnFl$(28eN=rBQN+NQN(vU7*k#St##sD z#qQe8H!T_{xp%JDhf_?K$D*y2VN}1`O>$hoN^HfK{L7fOBabWbzz^E<-7Yp-vpe&i0I`c%+!eyJyTQs88l?q#q)tOYm(1p?4u9I~{dzWz51w%gned^X?j_&5ZpF*~$8a&_htg z9e@a!uOTe$VJVQjk_q#G=!C&t7*J}i*u3%B-%ETgPo(7}dz9EkD@*O&o79^H&4wwe z3v~=HUJb(udz1^1Xuf|1tGmQEe>@>ljRu-Y34&wOV#$0t2ND)**+os`Uj{1?;pVVx zj|cf((D&H2)3Ws>m8aItGVn>>YE$9yl@}*aV~;Z(AyH$GxuQ4m*@yLV_24Z`&M&!6wNt4mT*bllncs$w3ODi-F(T{IGWC_@8P z+PG7}mu?^QLYh91KNs=+EJ% zXIhA7x{YASM1R1LyvsMxt&zDNZ!%nq@0StyZvK3Bt~ie707J$<@sud5IeuQuYHZos zY|_82wJ|xG4jU7tX`JGP3GTKRTkPx|_MtQy`DUgygvBn^+_WL}_?SwJa~6qo_?-O* zcHxs&#lCJ`xXeg2xIU^yc$E=;627S!q{q z1pGPsr77z;UC%h=QD2HAFq$46R|;F>t^ERBwkDIJZMOa0@m@QPMS7(I*o$_t2)M1WOU2M@?4BjmfR=ky-=em)LpL<23^R`QxZ~@k#i{YY=A1n1?x$%UVD->BR zpQdsl#awFQYk8$T`f&WU!worUl%~#|Ol%4+J0mUUjazeDBXX`#QLg}*QUo3IO z3m1GsB_WRF&cYL?r4aYX>lw{?OG964%T9k@fnwbz{e~6;* z3#9#qVu>Y{LO+s^iNavh__cf+h_ALy$N|@QDQT^RL6GOSpCWC4cw!*OtR!=qjfEPB{H&EaYFfBZMyBUVO#S{oKl0(#ihXa#4+X(GaFv zUDfn+2vbT`R9dTJ{D~$DVAO`?745ZY1q1i#W3SWpFp=**|HjG#3#Yy}J70Ti4CAS= z+e@ItZKyrx!3kTp^ZcGLp7@fR(+#^+G)9P1g2ZLQnzz9{E_Lt)m%Rbtg2k(%#DiwH;)6h9IgesW=nYa+Y# zgbz&R3_tZ4lI5L_$+`k)*?ec}5$s4VIM zZ9vn`qTB~NnYaO~3`cfwjv-m!n~N{@igY@-vA)}tH-8Pw%ULRJwpthPV%*1VM#HY% z50Pp+)0n1s$g3&-NPy>?R&_W-la_E4gFJ3*U&c|(+EY{Bq%C0dLJamKn&9D$>7%Yo zuGZL;|#{p_cFD9G`$=MCD zwOutO+PSb>tbTW}9fa z9}6`~z8x^eS&YOzUJIVB{V2$)qG;g3)>(BjZuehp@Bb;j-gnQ@>_G{J*KKRXvu-3k zsVmh7LlV7Rm5NnA)LP|4^yBaGVtO?|NRs;|=X8=9|GV$A&b+RP5oe~22HkyG2lq2? zM&-}3!^mjzlXf5Oa;b!|kB+uYoWUWkGXxl10A-h`D-KQ*_C@=1#<3877Rjt`*#}}s zB6>f^)8e0SHA_7~C3yRItV68D=7RXMC^G3oIG2%Rd_n{70B&R{BhO^=`AIRCZ2*Q$aGzyry)i7!)7mru^uxIw97^~czYVjg{_^0Gjz z0RgtlIh5}WMe$j%rYmG&VyU)33<^)D=A>%Zt|R$5C~s(|y*a+Mu&oRjj&YjT}_m@61`>+-;*{hfEV{EJox#(et8;<)5w(+B3XN0pphLMI)g>4D zb>AUAq2>Aqe+-FA$;Vp;zKHj={Ox^986h`Tr9{>28jVF@uzb$*pTgQklPQ}CQ)SbcM&Q{@OwI60M` zpy9jP+!&!=uDfzx1Bf151eUM}MZwVnZKQ*Eqv7A)2;71@0xSG;D~7wQ&UOa1vtzI4 ze6Ks^d@oDycxyJeX%!e0ns(pIVf*CN)iFR=qf3oE1(&~QPtOCwt1OZyfVzkNkHiro z$(^rFf*R*1e?X%Hae(I?rUG8Y8**f``V8fz8$*a|OG`8wf+4{g4EruPl?rftYL3%T8NPSVnVa|fO+vu#n|L$_t*#I^HK#SJh zMiECD$wmi1T;YIh20B0LnXDIUD5J%xBwP!{wkF;g_bK|ZQqfj`Tx$t3mnf%6J8ZCK zq2azozCSCw)YJ`u$yF@Q(`Z{bAZ6gi)UKe(1go_&?)6s$=51x_n<@^KF>(8Rx3?ICh#RgF5yV67A{4abc)E8?5gN0zEyd7H(6R>#{kLwQ9Alm>tz7Z3LZ}-R#BFCYsmEWRoxWkjG!f100{~A>SVhDuqT#&x1A@MmNn!9 zV&5uB_9AR?;HNUvc=CW#2}L}{LQYFlxA-HHwyf9Cv2H%2gk6K5ovU0Hn~s{df} zQf0x?h}ce`h2BszYo4^pXnWB}(YR$sswEouWO=v$iGYp+`lV{mAu=|#( z8Rz;&-Qp_?hd1Gq8A5zKuS2*)ewEoqjZKv6=Uf-0?+m2f_!cJ7FN)h-CXrcQ2bVd@ zc4y@UhD6e(MztU1_^6F+Qry*hL}`oR(~HK4LUS}1nAy?8C78B{JGo?|R9_ZgOj1C} z)yCj2Hck9zuFizFPPUyrK#N1(h`*Bm_)lmt^-N-#X8ReGT<`SBJrKd<7xT_Tor0w7 zrx1U)l|g=k3x7A~3%eohiT|K*cCd z@3*!NT-K|KlIg6lmBaSEr1&@+w?6Mnh|8|I(4B5%vjU6&2pW|O7nx7 zKhf<^h$L7+4|S<_D;Uu2&v5JnWf>xb*}QBk2@?a2VLml6~&mz>u2)#5e0r-rG;V&Y+a>4yC5Z_p>vj8W&sF%`mJ~gU?JctRmC%9$j3rPu0R|R66mv zhN8^VFIGICHfH#s$n!3Yg)Hn@oVaQn~%?jpc9T{_CDY` zbt*WppQ8@9PCUktQ1(_cwoBa^`F1U#mhcnfwYG|S`?OoJPs4S%?rj2VmjMhdQi`KXaHaKYcj)Y_%bCnd@4&$>Fz( z%kF;yRW^C_#nWxO2K^O43RrscuLQwO>!G`ZnUgtfQPS)eC3P3!_H}`q z`i8(51WFhmL!*7W)9xBfGA^{4^Tqe(v?%4rv)rH6%j11r_Vok~ai%}(7yZ}dkLa93 zo+MHW+((yM?e0ckSW&ggP>TYO^ce9Im;TXD(6eDp$qrACJu)ZPE3qecvvxPN=D_Yi zMJE_UE^o%RMqC5XypM*erQBg5p&|HhFPrH~chb@^IT7#)$%0?>ohK8#-V;S7B^%WE zfuoHIVNuFR4xoKs>BWP@l8Z@l=G{AyYGI$5Wu>#*^bNUdP)u$+rlULv?J)5BhVl>qIAx(G zdNHBlyziU%_1Izb{g*2%9@O;8pBEK4U><5yfm?xgIQPCx`Nn;J*OCX%X8PAtXe6xp zbE(GxM=~?LTwQ4&?X$6Il#}Cm$laPyO_kJ{_ zm-;c3)TWX9E^@QmZM-oG;CzhYCg7CLM2 zf@K;O^xnv>-)a7ZIdB7bYiEX6OM!9(20OU&OKp^(!`!W+(eRrq7g&K#nec>diV=_r z;0Dk-gGWGDlbONDLWTd$-V~$$JC403Zx?%uOG5d7a5K{=~*iP7B`X z4NYkPx2DgiX!pOqm4*H9Ii8GU{PiQSu_OxDn|gN!1i0=Rc~D_j0_OMeQq}7|+jcei zJGly~P-anRaEnEPhM$Y^x94Y(^IrSQc_TCv6T&)hUWEz^Um`Q&xVz}?xCMD(NX~4d z2y>*+zCL<)P6aVuSp1^fW>iU6Z{1_I)Ei;W&@JF5O{WcTvtFn7ive<0j3>X{0uQg8^*$Gdcv%`qIxf5!f&S?lAxLkLa0s`r5w_ZEHGOQ50*ghj z)1qo3EBp?#+ncpbe0A0nO^83%qYMRx=QPIO3CT72_2)V61H}Kpi;bv>R6>Hb+R!U%hb%*t=VA3h6h>WrQ$o1DKvVxAlG&tMW}_4N>t{d}?;{_ui!3 z$vX()hgWZPRs2D3j)}Uq<*4p_@mce;NOTX;_4}MK4gAyz6@`LsLmjksL(p(^lbY zE-=z+>(~$UEk5(do|NEVOW!ER9V8Jy1Q4sL`fXKzjq_jU&#xvgf-cv+m<83NU&zvB zK5mB6T)|tiX%=SrE}ZvAR!p7W$AgkPHdyME1FQ@4j2I&7xWZpf0g=d0)HD+uDiz8I z=%2AN#UOfXz-(uz7)+XDr0vQ?TJbqV_Fyu@16+St`lkq~mp1-|x5KanqYFc#@3tC- zs6~!baGK(VPp6k~PkFR-7e0EY3vAvl<7h(|X_yeQO8NR@>uXB)fPU5jrlDxakAq%h zTrnWyxx;J^le1ooU5Bpmp0i|6*tOecfhD$+^gN{tGI#XWj)cXPZ;qW|5JT8;M8{Gz zf%T6E%Gdfcl}T3$^U6hfWf?0T|HebeH*);_js8OLp2rrN$Q=|h?ExLxQ`2x9Mw6vK zK{G5&-CR!4o-a4ntw_~lGBNxTWvXH*PQ2g)`7zHcD!^_KW9e0as-a?ajoH-rqf|t^ z;17SUAHPe>qC->v9(HVOjz>qoPP;PEK2h+X*Z4KwKs$I7hJbit?qIKQvs@hV+f_`G z0ILSi9zJg?fnj}%#@c{~rk#6!{IIAOObx}zXSK%DYk=RHsqq?yd{DVIkoL*BYww8KO7OO<+<(Hq_1A3>*?xiX2 zZI5xiq6!6`oYbk zzUXlp6q86F6*-PQ4t3BNRGtKMP2$}0XJESmtDirGsbNS;M)?hXzkoz2EHu_o>RSXl z5vT)WD@JLJfLzy;|HR!q#SF!gA5?d`fZ6OadzcEhrtlO=KxOoN8PB@Ju4GPXKSzX0 zGmS9G1K-qRIOW6(pzZrt+I1r3DS63e)pO|sQ3Kr;g80{ee_W&vDF>gDr)@8g)C`pX z+R$tep1zUONxiNKVV`bud7Nk@=?YpHajzg?{W>6G+L``ZHHyDpL~U`d0D~pHUhY~1 z9Hn^8En-bAI$veTEp#&ZSaG$8S&_1+M(!Kn!rFkzVS^1|z^*EEr0a1&@^(D5;E#(N zg(c#B3~z_K{Nn@;1)RP=dc$GEdt8PaIW$Sg<7Ww&Y{ZMR0|$wlhbyPT9}S)ebmc zf`DXVI(ZuC=Z9eR1mzzmub-t?7J1Xkm`KpH`S5M7$I^(}xFokey;E@PAvxf`+rVy^ zW}8e8A5fI7EJ$*3?DvKGtJ8ty)W>2kWiSYuwV^>v7BQzJw%o+mmeN^Y*Rpo`YU=g# zoq7&>bmqvOcmS7`MQ1Jgi@*1I(}bFd77YiA8o~mpe42}oRlwmqS(;%1Pmz1#teDWt zD+k4hGcxV4m2(8DR)h_=^DQE8dF-xAJ6WoOBAXRKeji}&t63}Sq4){77QWmb^3Ocw ze&n=Bgg_?HA)>Zgb|vL1Qr4=E5-|T@$0`KWzYoV@oS(qKd5;^6R@Ksf6h*$?K2ikY zQ-C7S;(zoJ7ho5m+44q+vF;$(=Jlo65SG^PI%m2cgy2K;FYw_bKL;QE3ds^Qeq{*= z=|Bm8UZKc$3gI8%UwJ0m1VJ+-#SjN;O7#bTogq7Ug+`}UqcKQB>jyzJfB_1^NMd5R z-TuD~5cxm#5WhJ~AMs9CpGYd3cP+-X>BOs0Y4#OQf+njaZX+aV*DH0Vu6N zM`F8}#RHF6sSWm3?}*au(>DP}q^n7aBucNrM}l|?)NVf0bglTVnHEL4t{a*;sa%AE z5s!}^XZ-*Dl!tJ!NG&I7g-SFWDQL`}`sJG|RgfpKMV`bsiy1r9z3p!?kgaDwzo~ob zoXC*-c_a#xL`ij|CaIK{jw|{O$;CGrF&P-7VOTF_oxCVO0DZ$fr#t!~urP;%j6SX=4Ol?>BktLFwTljd~qZ8{T(uC?_jfs9Lc@bKo0VVT{gbq?(fFkiKgOGjj!}msqNZhOCMZ!?O*RNplm*N^{6n#VS z>P@2`Im1RBeLiz6st1wx5>A2&c}TimkJ9#~f-dV_VKjR2nT=QgWC!XcHMjbSua_IA z@fXj#Yp?om+9aS`v6fMq$8d=8!Hh|8ytNMsX&6G}gZJY8U(EQw_rY69H1Q<&{Z=OU zcrUa9R?)L8nZ1;JvmhNRA<}@2nISPe9%=)(+t3mRDcU368I+lHjp1A&Py?$67lori z{jKD-eA!n$KMJVsO zVYaN_XshX{aWMOvm8tJ4h;~#Ms>XflF;Q@ai7an;8=!1z1Z#nx%6%j}Ubj;JWOVBT zx$E60;4#Jusc}(E>G}Tk#dMid`yERCB|Xtmam~)M4WXPrvE*0afi>Wf-lByLaD$iQ z0o|_h|K#b%3NURuYqf?0z2~9{1|Y}ch4wKv-R$^n0&T>rNa1_I-Ze$oMW||-Z(&mJ zviy02{v93G+X6S~F{Vlmz>b8vpUjo%=8~ptiAZ7D^ul;sELYH~R3#-mbNL-(;y(=O z0stWuxFu^Y)Kr+(}e-5yb)Vz<#MIO>!02rvO$ts*WZJwVl{IbWDbWR(pg8~vFdOOA+g_MvzrM@8r zB&)-}Tpj$kKVc{p+!7?)@QbjWgbF2w8BEKx&1B{}GZMc=f4}2j0P!XhR@Lo6dEc%S z4__AO{GstnyH7nBtm6>wE#k~Z){|3uJj;VLlh`X;DZr`6>0$HHXr*tjzm!h*WZI?Z zJm~H@be;c!-z}S((MU=>j%QMM_>Npy$KCDu&w43F^<%2LT}BJ!({nS58784S}?Yf0ECh6A4%Yw7()M@NUGK!IREz49$O1_g_pA z>fTyie7=_mHM$V=PHSrEX|~Bck2Tam8$dHLxmkP~zEWKbF7zAIL4)W8|8tUwFLJGH z{7vYHHN|Al6wrcHV7BApq7J^rK)%|CzMi&FcOfUNPI#jjZakWoe^ zFw-j=cTYCuG^Y)^@sLLk+@~o05w@t6SM@#8WHFTt2L*ARMEaHO(E}%6jwGn^Cx1Q6 ze}Dl0J>Th$VWrfw4w>mGyJlIodNoqOJbb(UAnr?vAe#`>VPDey8|4zKx@H5pmqna~ z?MTs~+I$Tb0stX;16lT*3-$|T(~CC^4U-FMUxZD8yWPX;p2roV11NG>r})4z9tOR_ z4Izf7zoN`;UvYwOM)K}ZJp*~RHMyeZg%AxC@m&A6N@7?XR zWb4e#(j6(ydN=ws9;3|&E_oL0vaR_!#UEzwh8(!dq5sV{j=YTC1X1&4M*{vlSUg<8 zV>tM1K5D2~uO#Uz7xz*bg=Vq6$L*&9G0ecC#6spR$o=Yq5^#p@)B>XqD$BTSLWN z)-Y@4cHyymC{0dhD#vxmqi<#BBe-;Brdu0|`Vn4{Z3lG)7aURhnU`2O|0p~geGg4) z!PLp}ti~t|E4Q=}_CAI+(lm#!Udv-|^%|RQN}%rS%H0-~PiO8M2Z!aT;-kaCYZ^MW zojEwEjf0co``?@tgrz@7%O-OaQ*ROZNLQAJ(YN=SZOPg!>!g2NniIquP_P*R4IjU_ z>gjfcp1dNa-^~ri&2Vj+O5$Fb@6W!FjK3am!}yVQ+!=PY`-87u5gJ_~UU&r&tJZV! zk9wyVlH)%o|8;K|q7a~*MuPeQ23d$g za>l#ABHTgF=mk}~bFM3qVr{F!e5;VfDh-r6?cTsc{9R;B<*SSL3_(a7%;LbUn`diX zZPpaK9@N({M$kTA?zSB-<%NSf_v92}%H9lLD?B_Vq47Az#nN(fv)1V62Q+8PL0Q5; zak5Spaa0d~s}lYqp_N5HYVkvGqAT#uz8Sm9-re+A#wzY?JW;PF&xlmsnx{mjE*{xd zX~bKdt)T($%MFpQ5LZs%4`ju50MQTs%>@!Gp^QEyK4{wsOltZjAR-N2XTM)c3dRZ; z!CP88MUwDN=bc9-EpA3c$6K%Vs#QSp5(Z4Qg6jzpBp?t6O7-SHFoM==t)Cxwv+sAW zJiJ05{tQEMG1PYC2!iP9{t4~;O6}>&A(~frx-(T-pfpMDQtCc=UD;Z(AHK}4XP*68 zqW#(pK}$oPFbD}Vhf)7jduXE z(}j?}hr+1q{_c9)Qin)eM(r-VR*PgUqe8jg*zyBd1+@f%+rPXQxTn!*tMZ`joCYWy{%{UZFTfolle=*d98;-XikpP@I;Bo$hluL#bN zVG0o_R<|lz4v+qIRDVZl#(9tj+7#XY^G!<+K$rBty{X8!i--gRhs3rd(xznuMH+Xm zCjff9R8GkwCim#Shp~+fMe26_T!F|%iiSvC1 z&Zas#?u|-kl4PvScL8I&PcCaO?F%lceGSXz#CL>df|{G!yI&{wI(T=AlElWn zFhjxyco;h5-o5%C-8)%UFC6ley21S&h8BAlEs@+}uK&TCO_bJ_^WMBoBk+myXSYdQ z7$`exGDa@|(e|<)Uu>cBNVaJ!ea@7R)r)X?pO*E|$~Pt~iY@N%noa|i9(L(LkE6)h z*Wk7yBcz~2W(W&;@hUs)<`ozH30+PdLDkq)pCFb-oY;l`k$ZfqfkUa2%>L{JO^~$S zxrk%)h2sC+mntRJw4GDCA;GQhvHS#RbiLcacUF>??cSh79KWynooWmUslMiXRS?Mw z4_qIZYQ$y~=li4%E(CyXLpz*DpZl7gT^P?WFYu8so$#SSQekUt)|{d*!-QpWZ^W&f z^DL@{vgriLdF0LL{>N{2HI4h&sk5PbFT~l2@;zs;9(ia}M;sHlZ5?yK2BF+Me1_A%lV(a-a(H)W17Et>NdVXGX*6 z-?I&uY1%VE;B7YT+4BePFF^8+f>Xbo^Z|aUJD%Ut zZgyrQTtv+E4em;g;nGOGv0Z`+MOgi?vkJsPSH0PhYlFcqqHCA#0kwWj=eZg5LT1?9 zxd3rx5#M&QP3|_x!*enl8^eRa$U|_BE^Xy&pveX`_%v{l8jkGm>hND^IY?&2Igs>n z5h@x?>Di7e^cQyUv{n7VV;|s>Aw!dd+UtW6Hw2a-Rvm-CclG71qzL>r ztAj!az{KJ}^{ehoWyhX}=#_Y!;!J^lXJ!#)D0qg@Q*Err&sX9K!MzxITnSQqBdDEc z-}#863&Y0mGz$u*a_>5e(RF9PrmFM*{PEbiw9sScCV3=x3PmrtPIsiK*@i;tf?19i z6Ua#V>clbd!A&H9{GOD;1VmmKaiUvd|KLunL+*W61djqUd30$<1kn@o52F!H5TD$y zApU=fHA8L?YZl9&G)W5JM0`)_p+`t~7+2+==7KZ&O->fqF?fwctj z!Ee?Ve3LtBK^EPb2jWWf(-%&9iKT0o{Ssa~3^*Z`TBQ8q$IAwDv@;m)sqibjmFERKrdlR`z50kzL@a+2NW!^>Ppsd?#Mni0^5 zIcnI?be%_}#|9c7M&#OZdUvh2ADn!=v?~SyHssPhqfq3fe1Y{p!K&X`<5AWgm*uZyEi=cV5ue|+OT(xcBwI=qVb}{;L!d3SDa8zddc8& ziA^WdGqfnzTPI!T^3v#+;n9a?Q)f_2YK8A<4rsA6zgd#M&|<%(5<^g8S9YDfR@y>= zVj6IGxtS#YMkd5~X_iP*ar}})gJ*3?{GVs#*-7u$S+Q^VXFh+mE7L&mS(w%z@9c|4 z-dXT>yaUIskBeo)Zsf@$HJXDHhBFg_%pdqEto#fD4hIPT%jNk;+VRW*Q~(n}`@*w^ zR+_Zk1x?4~XOqW9*Y0=RDj(Q;ZCm;-@5I~|n)&)g6>q5#q<9j`CjLhsA*ivrVyJ$r zOW{fWLM9%hQl3&4(9PvLyL;FEBmCvZPTsK}Swit4I6-qNQip1yh6VepFUNWjMz2-soVzgC)Y)bf&MM08Qio66AB&7fkA3i1bN9@Wuh+TMp zi(T;NJZ(sX2D3Q`?$Pjy7V|_ogg`2zniy72Nc_qF|2PL<&aeYalSkyg<|B@AkdKtk z(=Dq9RIa93M%djf4==gNA8~izMdZJ0pGZ#(Qib~StmyLLBUZ2NT`0K&K<1;EOv?{a zWp6;mhj9Ks=H3Gu>;L~BE+eySLe^znWMn0>U6(z&jBLsZ4HC(Y$c1d#QT8ekLRL~n zQbZae4SVkq?&n*dPv1V@`};fh@7(|2{r}(RbWZ0K*Lc6i^Z9%{ACJd#ho;>F)d^Y# zy^v>5Jg2}5q0XZw8~=T~=0bUC*72TYMk->Za@_%R=A5`~E)DW{Nu3wu_F2)$%`0alT~})s$(B5#DE#%C&%Y3E$DzF*+Rq8fwzeAb}&*KVT1lvYDL!n-3hGnfQ66ARM>V#drh#>IYEby_&8c zlj6AcWxw}CUUExfhHMF_o+`jU35<(sE_|w<={sm!{{pnWNAt99lXt=YAaz?tv$xuz z<+16`qxx#~2n4h|HTK%DmkLxL(9#q)6g7E}F)oKn)k;Kjf%&pmf1WkJiRI-`u!J-P zY=tgCTn~I%>;a^4l;2vLORo1`sx!Ah8L412L#%FPNx=bpZ7ue;lBT9sRo$%4r%Lj^ zg*qPhFIqio!&yoyCJ1RhFW+;tcU=a*k217q5FgyAA=sP$}p+)8SZ2~s(Ed5vd z^PQoA_&xPprl!8M^Q9b|DbUj{egsmX+VM++DWeJ*EFhA@T%8@9Fyg&n1|&%Pcco_T zv$bP4g=0=T!lMSFn3UtX|JJHz5CO5c+-*>0n<)I8SADAw3VaOl15+K?m^DYkPx50D zTR(s5YOKg-JK52e6~HGwY^t3vzk9*4?dc|0tO#u2i54~PUk_`qr+)DIe@35w-GD*w zfwD#WY3tcEP=d^fmPqAq=%Z=65p-o;9Zqwq6fjLAMc!c&!MLy!Qm$trN;yX3QOjxF z3R}}gt^rNJ(M9}d$Un6eiPLFfHh{~RXIgG6kQ)KVIlPmQSvOS~gX$>9tZo;i2w*S!hHpZW^?lI@5*EzUfuMY4e0vW;so9}4vD_H$c(Z^(Q3J%4iGB`deJP6LV;GW%lq zW(HW*{l9W-q%%GC>Yq9Guf+bZSPbd(d%iRO(!9OT6ngY>842Q|`~SW#|C#>=oAJiu zL0fhbe8D2jzCac(j4;fEPUm>r8-2ki;b~1n)JcFe>On5piZGjj<)$LR?I7>=MJdLS ziS;uoJ7bV!k6iw~MkGg`0vgP7`@Z>NzeKlX#(F7O3ssd^^FLCLS#~+R8LFg0_fL{t z7rRvHd*OR)5zqJV)aF3=tUGozv!n_mg|Q^R?(+F8NV#{rm}&N6DY7kEQTwNM4uY-U zAloQC!1bs^jd>ZrU~e}>K-;VjC#R#bp^;{+%^}iZyE5Fd5;|mCwQV#UN8_-GAmM%q z{6anuQio1|tkOp497th?SoN&A9nOcssKmZrtUz(a28*f0OUpZ&Wd3X7hioe?Zk!-^Q16bVw zTG<0N;HuAF8kkbzrTcLWah4G)y}G(q8G-(I6|kA!`=2_}7c0T|E$PD($|FZfqAC{q zO>9!Pf%{pQx?441eH5PL!9ML7r4IRtC?uT{al%CUId;1db zfOCt8#RMpUk|;#$-%KYvPVP*3p7}8|)L`)h7wyJH=h6568lBn}BX~{2?dFUmUu^J#?Jl?=!ZSlLVQ9n4Uv%cAx^GVc;(lm{r(^ zFEHo3`uKI{#jxJzjKve#E?nu}YrN2u)wEjBL6(^L+dkwEA#xHP712o-qp(?6yC5$` z`}v6%(`|ku(}(>0G(TV?#NRx~dcgh=1CNpWLv_Xt5ZGY3*d(Gu<1pbVo z)`J=(@1izWtKXGJ91|2NyiS`|xeffFJXmnVVgp?OY|r$cP|J7H>C16}I-Go_C1Xk! z{=spxJcQ8qIp8|1FRogz?ijb8s(r2{SXNkg&-NMMKezmH#zx}FxdgXE@|W>wZuRKI zFphxt9{u^ctf{h|E>4fdeOE6$;+NfZn+RpHjuo-03ppBpgM>;8;^?h?wC2hKn;=a* z{NkNd@!08#l<^H{a|QEIH|Ti`6}>8gb0co|f|7gQX{(LhR|g(YewaYKbrV?99NT#3 znK$qnjANWvpRxesboN+}org$T;Sko!98ZR0B1E<^NtMx{62zVl?QBaU00%^WG^?fD1Wn!8SkV3MV*ddG3iV*QVP9|Mo%6JT*fsIb~6j3j556>tIAJ=>-rKMey+hgehL`2CL zx0TZRJ{ZI{IMD!bW(6n%jYT<%etS5K& z_)3ZI1%27*PNUWBQ+kM0BJ5W^8Yl?A;+@n5ID+&CAv9 zW{&p$xK|y|t$uu%ACLcf()~c!e=UOG1=TE0HZx$;nNZ0!cmT~RXfb|p0&FqkAXSV| zqc87;n;7GI>#@NJnjerAO800%$|zx|`r71VJz|!XZ{X@DG#$RopuF-mex0TiK>1k(S;pGPN5Xi-?>6le=TudimvPitJMW@Y>hY*9S zq`-}=z#X%0*(sqb){ie)(M74~gJXaYO9!`Qg?i7MT9@y%KdwPi_SQP}gF`CV6d+Ph zP!tc~kFg%Va7=EdCAxbAVptLYt1pr0*ZHhbzte)-77;i)S>2X5qI8Dg&mY3T`6kUy z_^qVJ_^FAHRZ|@a-v>YsRrgp>V-SK$kb==yH26z@@dKHe0hC6~wd99cLV4hsWDg{1 z9qw$?V$sE}4QV0JGkCtH8-CVjFuqj3p!Vqaj0N}n`Enj`Hh2wF(w?S)Q-BWA9Kw1_;omPv_Y$4TDfH9=2dz(Ho&yOD_^ z#$BBe;cNGY{Y3S5TvO_ohI;RAAXI(#eq)mkERz)v!l3;vfo^1Ph|%OIEMB`ke&h0e zj~(v~`%_Koxif6i7G{n0+}Z2Fsmdq>u4Cr;Pv9ry?}cvnz6RY^0Mh`Z4SoM@^Vau{ zgghw2M&*q9NEvWQUQs)dpH9$YWTeugLA%QOy($N>$LM=&#~>{ktPc78ie&7vqi@tZ zTWmF=DApxnxKAwzw(N+L67k2$pa_0JQB!BgK}KI*oEr3*ds`3_r?6}p8V1cD3+&g* zt0nQ>+E^0ZPIc~v_q8sK(f&}YPun1w3qWH=lp6ujsN)v1#PoBpze0p*Jz!+Isa+Kz=_CA}H})@t zg`nT~;~UX2p?lx*lC5c@d}z~*6ne@fo&9G__B2+2my5S;E`qX`bwnUG&f~6lr1j&| z%S_U!PVg%{3bMt69yxI#NCJ6c;09z-X^MBpFN0^S13VBPCj$`fz<9cyQB!Op2p)No zGyDJ(l-Hg)mk)45P*$k)&^1-a^q3#oYk1i3 z5QmJ*i?>bkitAr)j0R=GNn3F^Lp+J2K=IyV$einyO5w3;I zXab~o;`)y{nFjb_hSUAX^qm!pEVF596f%9tDTD_N3bFicjps0?^hsA=RU{fb6_SuR z3gYLpom$Bv7f~8uU~~-I1VDjA&*@6eLEV+pgi&tUar}}Kmi#&?XQDwqA0Z?dXo}O( z3H_c7sSI)M0g%;aeoAsL$vQ1 zma=@ZxGTptl8+xm{YQSd=mTHoAm#+_EG8@Zj3(h}`6u|hG$)M$-h78`M|yNsgZp$7 zlrQn14o!b+UgZ)FZwB@c^1DWD0Ktjl&QGr_3rHtX<_*MHp9h_ET|GB`I@S^-) zGPq~f;&c?Sj>jDXXaT{}5N+92RVsP=h(SCW@p*c)!Z4d=9Ii&p;{W>2$;a=xQ*yBw zC_=n2WAtg$iWDOlI^WhLw*hCTz>)6z=K;$+!nTM)%Hv+lgy?Bfxy`P9sgl0YmZ{6G zd3h4nQMaANs7PBG5O1yR$5ng!_l(HSc~-CcNxbR$S{(X($ zd5^?5+)*1LjY_et>anR_KH#e>h<55@)V)f>JE*&nZ_pd5MvPNdO;Etyz4ZA@L9QS8 zD5z!jxJO~`sYH58G>$sgZH%Vt+8>mEho%?gdY|AgjHE#H!sdO}M^0p(^m=7-Rn3VuH_*3WPV|Ds_f;($DbKL zc4bT{BnujM9sw(w%51CUH&+gF1j06n*tuW{jspU#I#Z?{3T1{^jEv8+Q>?w+$~_u~ z#H!npm?{QrJ3ASlq)VLf@T(`DGu+uV_poA)E)nLCDr=$|@WJDX)es^MHEGrob znyw?CcqtRk`qn~`_XEo8M?W&;D5FH;vQ-3`Hyxt2Xws%p5o*C2xB#k_M zXi-`|g*|)?NSi}D`f9n}mkzGioi)s5FCBQb+Rr_@@uS}~>m;N;rAT>p`_38mz0@a` z5lMY2|C##K|1JHwvN(5{P1XYmv>R1C2vje=KM4GvI&`H!+uK85y*vK3Nq1szUc^S- zB9iDZJb0oDVMcIM+NxpgE_jtSb_YELM6Q+Z?wa3t14r8Cnzu%sd_YVAh1&lU^NUs! zgP=y>3(e%X0BE8Fjj{pvSt{SH!7H!BBLvb^;M(hb?!ywE)U?!nGFy7{Q-az-0T@3c z|FXY)Xu1i~Yr_FBP_SoWINZVuC;>DAC`frnKISJ$gEea{klc04uG0BGoZtPNdk~64VTX{;SA{fz^|w9LIRk#(A$BXM~{=hh&{V+fuOvV?@U#YP?T0q za46sQw~$5M^SxEWpyxLLJ5$6z*0~YtHl@CVH#?G(8r2s*=v2cRA1xu3f@FJ%Ui3+Z z{hW;h>Na*77cdCcpSRTm84a~Ji75SPZ}M$MsMNlFV z-C2a`HT?S6b@)M;IKc7FAVZdc;^Fb~)WGW_=R@eU*Tt9*i2|f^8$8`2iT9HUwC?Io2v_Dr zw3@Apv&W?OFntZ6i(y^t^+x~M0l&tTJ@_uaq$~6BDd@-P^b`_rN^{a8$hau!dyY&Q z-xtTgpyGh&P0gM$i#eer3kxr?jm_&i{-^lJ;C8>xM6~=gkLBV7_#q@&xE66s6v$6K zKbEf#l+ic6lyolm&J+a~8WqJCmS$_ZJ{(}3kurmn z?FfuYkihW;Y_FKmEwn})UI6puJ%@PzsXQ=F*k7(nOy#>wS`yuOJ|qsY{ubIM*eZS0 zE#4MKjgu4%QyY6D`Bya{b7(EQR~cYwLhNwB*2OQ89#4!Gpfp4b76@0SNx+vX2_WM1 z(k_wg%1fWkffeZaOr`8#gPLRm)IYrdqFpK7y0;Z?E(?Ntn!rj+?%G0350snC;`VrF zTc&)Kt(4;z(<(21dS?%@)<_P~Jrrfh`(8zuIj545)&`ABorlZ@aW3O5z~o@KV?PNC z-qSrjy_a$FYH)Wr!DW$*RNqGm#)xTn<@=lxtRbLI@TxyC<$vSViuOMHm8W*RMWtf) z^J6>zx-KdLF+`us_c&DZ7vL{|u+j*F|IygOSK@7BZe|B&y=gMsS%zzTRt+h?0&!vsmGJkXC;yA{hVm`D{;t39_;s zu(GdrA9?Y)Nf`Sd+2s$9uL$jozfVicWuf(s$NrUwLpa(&z@eit@q&XuXnbs5ZpbuQ zXlWchHstZ+gA7A!JKakepS)jm`Oiv7cx9%Z3m98+hOsM2zO!o?wK?ay*LG6133!x1 zdUO{buaOMBHs>Um>@2i6_pz#^?plbKWt~Tn4Rx#t43)7R;}X0P?Us$D$0*1I{H(Eh zK~L^R-J?`&RAf6g3|aJ5r&(as;;l7YnKTAdWUl1HI-Q<@OH~)#t?pKlBy=|O%Otn5qKmWhV!(@03xH6gBKXZt7+c!q z;<5#RZtq=XLNFE&dH(bgh8}a#dwnF#*uP7;3maGj^&~+N1(}@{7=c!?>Cq75ZXFwo z<(&EQ(G$Zc=iHSsP<)Eq8l9cHk1_J5&UKVlJLw0dMB2mR6AaAqGoG~yULqfs%69`T zu+9S?glX|C2-DJfcXw`_exG_E6m zP*~1El-BT=O_G>slR&c7)l`UaEj!!C3Fz?RGDMBk;cGT35T%9(136WO5-)Kvx?@&iHWH?b*Rq7!JDl z!=S;()0cx4Pt*h6zGjdI%SNLGMH|<%t@vW`1ebH5{HpL-aWSrjS&J3t2Sk)5$#S88 ztqyhez3QGYAd_oArq^c*oq zmi#7j!$nh;sP#P(??5oqd|+8?^gzZ7I<05b?Rr+K_62)~o_EtalgO=psD~!Z1G+&k z$v2s`dbd;LcD%iF{c}#GEn1lDa&fCCJ^4|5G-5;e*^LENc(OlldDdG^%y$^tw|*~* zKY8xZhsSdl9ojIrsG!TX$oT{(Z>)DHPc?-Sksl88zwI`3j_K%0_#oI^WxE`|MINww_ zXs62iRuB5UjjEW63|TQB;ma9t&275ZnENt7y(ayfFAw!;0(#+$%kglljmGaIi-m*$ zoz2smhyNOomd8s&Y!Y?sgCh|Y#uuRv15Tyh!3A{lc$q7s@2`7&C-aBSP_W-{AvajJ zmm&i)jh|<4gXFUls=q!3#xMFXS_|@X-m%wNCXpL7_p#alari%`#fda58yG9l(-6DA zg3HqNu{`*?IuF*Ay9`V?Kv`*!ufzO=G~@={6BG}Kd#pVw>DtlwuKi;ByrIugokwOR zGlZp=NJOKC>Y+Gfi7JJu+2Pdv1^OH-glfP){sB&mCUHj1Cj5q{TEvEBK7%(2FP^im z6Bcn=16|k1O7jEwrt#p2<=ZXk(x>t2he{|p*&?+4av$uEyB>@5T4657yMj~R;N|jo zi5gb`!X$TSR+iYA?*nhsy9Ak)IXQ$y2TGYRDLp-Bmdg_xrvgr4GzDamsBZ4VCY~uQ z*At>XEI%W~EIwh};kGBT|8CEzC7ZJ9ALR^Yr^6f$WfjysSVnN8YjH?{@@( zCOwXJ!T@tw@l|gcKDdzFbF#0TmzFf_RtOr0zP4E=+ zlCSR8+!oS2MR){Yo7CM+j>T+%?O`rpf>$lTdZWPd@^gmOfV&4Zc=6Sj=f5Z$6N&F@ znL}}9QxLHioQDbM;YvQr5neRJ!G>U7MNd)BNe%{Kcc^DtZ`J3-Y&F_lTA3SG>==1l zpkFdB5vxa#2a3a^%A^~OG?yV(@FVkIjm0uay(2;jWeUgmQkRbWXo4h`XCTaOeGs@= z^yz{XhlV~!pkwa}8Wmm_yxQ_M&@YGlL#l{08YExOZO?Kk(eMf#{-8lmd(C;1Rov+( zro(5Ye{nlaKj&fCG%XoMaeoB5M^SB>3%NaGo1YV*%`LlH*jqthNnF0v>7;BA?}PF2qr;g?OoRz{dZ}MAfjLg}jX0 zJju#krH13pZ|N#7BMbbH^vlx%Fz_-FQZN%YE;bfsx++4CYl%)g=%aBRvUkhH%cIXM zk)H%<&mc@SB$(OVAgqJ-y#VyGn@S%ZIaz=8_H>4nRh99hfk$VZC8}7$d1)M`-;Qy z`>RDcJm2^P;SGVeQ^o2ev`{I)=1KUC?5c+2)?rorIazSp`7rCs$u$P}X7G9J;(#KC zxW~O4BnQSkhd&40^)lp9NrkDf9dLie(}%71fNyh<(2sPtrj`}1VVhvd5Pr-pc6oES zRPC6Q6Vo7lC@yg45TC}G#E(k@C-bxoU z+>Bx4H!Gc6<#<;Xo}F2Kl!y8xkq%AXY-Ql?9mWSo=Qno)y*NGym8^-J`h4G_+O?+c z)zx1aLw3eKEXCM<6j0H+cp-owF+^i;->qg)<;~=58x0U{zo0Lg`sxk8@HMhoTeN{k zUw$RgzUx};&&#$61x#5o=e%WnS4CH-u??#&|JrkB?)QUfS&?a1%5fv}<7KS>^`5&f zknM3_q2;9^7W*mr6o$h|FZh?_5+6-e|rIp2ztTXO;pUucru61L}YddpJf5Q zsMHZNwG6vNE#ySA@4pd`-B3g$V8!hC3Jr#DH+Cg zXDM*|Y0MneMlN zVYLwCW+tD({yv4arV>M|mF3B5y~}k2rG?H(ygF%s(L8C_aa2?5%;L06@3}swS~=AN z8{SJVa#IJn_tUyzo9S^ZO;W?gcM|D?TO*ACQAjkpV$8U^`x1|SaH^adxl40pkfbCm z@!!&-3{^Bb9I0-O;X0HH-M>#ibIB?gB4KbsPaEi}8l{kmEhKbu^R1TK`b+v;# zMvgX#-4H`Yp?3Uh{5~vw@?BG*QBoaWuLpASe!01iGYvc@U%nC>2)vp?lpO?#fYV{( z)u3OSB@bCWI_`g-Z@4@JdgZA8%Fe)^<08Zy35%4{!z+g;#hp<^o({zrj`R295G8{ID_8rU-)tRNo_UbHb!5U=(@}A- zs?mgTuoVtD_mrS<UV z%WBBqvO|$YWhPtYW*JM~@rSmxut9v2q@=TyVovK%frbb*^WNBnp`s zz_9I{MLVp@Q)~)~9CeSgLL1cOqIHd@4#903%088!2(OYzYqw#_b!=;!Dpz|qsQ3wg zwVw#H$P=N{b=?8+N`2I@X{1!2MkA>SoT%&YAkUfp-XgF|s0CnoP}sCFE+mhDZ3OsFxA+kigaUxjywYRqrGf*K-f+F27;GU2KIF)tu5g8P8 z%Hv_&jV^$3oqe;XPmL-1Z&t!cH6!423juI=s5t7oAP%D$O}+FCDM3#-SKN0(&CiBu z=h-!l87D{kH!6!ebRE|HY-gjv$%j1M@Uyo3zfxj9c$V|~zdq7dP*AG*`z9^Iz{>~* zjXA^5v>^Ac>E#MB_!ekh_^etaH$Q7JAm5@q;qPVpv%tY2CIP(go3@egK;N^Jna&Ag z6HPgkR~4y)HaJ8R4*6#pe^9(+der23;XdZ^&1)G%DCOq!G|#7YcR%~vKPnx1qI9nq zA~a9z!V%=?DG}h5AVpi^jQ#ul{#Uk%wP>r%UzyyU`;KKHq2AVqN|P@dB8D-a_~6FV zg(Wmd2>5v?9g5B>o#SFP14xx>K3$9%$s#PP$g>Va-n#5(QuI;XQlRUmuc& z2f+i5|4*MqKr9&H%#=%6mk(LM-wMIgft&;!esx;rD}Lq<9F|oE73UiGPT|=3_tTOp z!D{V0Cbt*Mc&Pi4i;s%xf6qtK9w?0q^I10fuw~*0o7SGnD6tK;0ReJo_EA#(%IGmt zNQv}J^`C(owv|DyH#=Nu$X)c;Lf{!;A+jBK-p4p`!jtu;|6R%bSyw@^aqf9MtUx)E zLR^S4DP2o~0j@EeTO9ai{;7A`32nZG(+w{b;-}oLSPRiH@HvP$;SKj4W{1^AN8qL3HM)mV~)7e)|0ut2QVh2t#@g*@h^#zT&ty&Z}Ey(9nIC*XG0MbL9j zBJVnU}!4&1>{>NiI548m>f9tzz&wX44vRgMvD|UlO zr*}qKi{9tfc3O)q=?Yj>VE$gXJw5C0?vt%{N3#a6pt`y`hphuOT7O++8t3;m3i|g( zf&KUYHXEE;QOS6A-lU`3>}~%CmsOv4FU3~sFGc`iVU!H+M}u(K)m2`JLI;3`j*_@DTQeSWd6YN@1_0!;sV2;r1=4M zAG=E=9=ki+29-{@K(n(lSFgEkckpl(?P70I$P}u zG0(R5%T;rf+xob^!PmyEeqLce&upWTQ(VGU>}8=uC>1C=C-u@9R7A%6#@pJ zKQq03?#8d>?$JaNx0>H!@;@hTtcn+R=K^;VkP^_!4eV%mp^3F{Wud+|1&P#rH^ae? z2DzT^{t2z-<9n+%Nk#P;7%tktH(0(5(xQ&|DLong%~E8z8NhO{-<<4XMC$)$;vmJH zb#N7&6f|~!ab7jg;ZdE4OI~UFgM)NNp-0SSlS&?-lPWre?u^1cs(D4VlR}HfZF&8* zyY_uq7uTWI1%pTKycLkuYjDB6AVBou>#r|}Q%1hvv48u5m=ZiB>HWJEdp=DMDZ7f5m8cGFkLqYT=#*J@y4pUGqrjK-cfash6r0FL+ zL!K@YgWias<{<0wLPz~Ovb@lxp;!~hu9lBL<4#IWn+hVuG3A}#8B;wEwHGSFVR$T$C2p@*@zp@ z7MY8Ly!&YaO_D6_dUm*0%DA&u%eHD(2)%nItNKE_nWayIE#c7_8_BX*q86QBn1^E5 z{YV61ssheY|HH>oySonHo@?i@xBsZ=_L361f8I7qpk9LcGc`{8A6i^K3lKZ#7bkc~ zK_;b%Xldh*eAD|*Hcq^7Vkw?iJNMG(d3mCXfLnmLpsX;m`1Jj>zA_udMW(~g&fW41 z$e+GEyEc;<)e3xao@f1JYst{K)j;gOIioVEvvS&_asY z{2na$Gem`h3?!O-E72TzFbVvBKmaMI&bKQqPewVW^kaeF_Pv9b=t=fsK@{dF7&KEVIK&Pz*xh13{*A9c((KI0+bm&UEj({R&Vl zc*6N^ssO{oxHpW^L8Lf^oCG|WsP~@(x!a@*OxmNb66c24m*OVp(1&!NCBfVVPf-2`A}KnDJ{o z61iZMT9D<$&wW6V26ME-q$jYwJ?_V)+Q|sp4wEzClF0K*V;`z%tQm&8@KT{ivh6Yd z)?>~_Cr66>E*}hK(kBo=5Sh?s)4gt=2B+X2+H~Nb#RQ`5Yesav2GCu*ey#E6qBhJf zh-A_;z>wjEvY|tPia3eo2cYl}6PDg9qh7Ed(b$UF-E`Rjad{jl20j(2NK)bP_j3Da zaVis!((43haBtW{4r5ZxVJ?IVduiA~*3nTTF^iiht(G?vE3A-2UlnXKZWDl#Ui$YT z`J)&}9YB%$7(BA(-|$%BV_0>EOKbLI8&VtdP!k0)Szl8Ix8u7mmp-2`(P9*3`Rnlj zT}7_s8d{l#mt9Rpp=@Cp8n|QKT9aQ34zUTnnjB)v;=I<+Lrnl-kE_|v_}9iW;zo|D z{O?b(muV^q;nBKjl5v0+3h+QkOM=+|2U?e4jM7JngjYU#s7~;}>q}S$CK@<~9f|eZ zSkwfH6M`~=0;u}>n92)~(ijh)ngbN$#lvLU!bC!YaFBo7l#8({{*XddVj zG(Mm42OcGuIVJ)5s(7>JkmVSJTqDJ&WE4d`0k;K>c|g~6H60W}G#E{#RQRgJ-|#7K z8vT6%IBnqU3~?oQ>;hV=FeD;52$^~DjVe{qP6JF&cA4eWqN;x7u{@4brr$q5*x>uv zzB|JVC|5jSOB)Ma_u&Pyou|ulFznah3Kz(81wZcZjv?N9a&?9la{_HuSD7emaT;Vr z3Z4h+%AU?!Jic@%P4!IlX383jDnk6CioHHpZ)6$-I9f@6LcH$4ETJfSEMRyxU+a{E zfdz)_roTH4j@rx?*oMbrAlMXb*m68P&dGNH#v^gMjQbMJUSR;L@0zfmh~J*F1Zbf~ zVKhO6@uai2v;0?6(-eU#VUXoqc?ITs6umBSWgS%*U62~EwBu0Oh5^5%DV!r~7u$(C z@{peMRI@zw+8eO7H2d7-Mm1D!7v?|nT7E49CViMnh52&Ne$W7DGYR-*6bc0}CMti^ zZx=WXlbZ+$X7&d&a$R%=CGS5k^cF#!8!FA*Er|Qbh#`U6=IV^g!5Q{Z~0@h*d~Jh(A{gUZ}5M?$r*iYb0yB zhZr4$@MbREVa{uI(CpN(NmujNb9hSAeKVqGgTyz9nO{iXH!W9T_nUuueH-iDE*p#L z3azeV%XoD5*-e-7Duw)EE?T71EKkhQhFITuM#*x_nTAA$elVSf*BF_Bvm=U-W122h zkshW9i1W+&bSCIHBX>>|C=|_wkF_;6RbKw4#%sap3Il11OPkzJ-1I)1f2QpSL7251 z<;3`q@7!&0vna{$83QKfD}{rdQqT+eaw15o6R`le%GN-mv+EWG5zSB+;YPupV2CBd z9B#KX)rm=@4KQuqZKcyMd_GWIk;PPM*Gv#F?43m$5Rj(3ddeIoj-H+4$^J4FhBh=G zZQdp!NMSbnuDH7qQ~3xL2j7|`pl$yWvvLBaAwtcuaDbpvaK2UsVjYadxd^W)|v19E=Uv-G&ocE$E7DXv}@EG zA$y1*TU@Yuz^gXAn9@W|9=BZI@^bkSdGxzd8cSt}K#MT-r$waBR=$R5LQOzcsEw9|ewqCfOHF z3lQHKk~|J@#HtF6=t|OOKnh^6y3nW&?qTPYJ~r$uy-NtMxGhp5;`a6WPH)}W?MmPB zdU4u${J+61*@llVv>1MuQ+e+AD`CyXBb~IT|LUYcey2f$C#G?LPG2zT5%Wz%SVeprbI@+QHCE_(TZWH=LoVw$><)IXfcReKCUV+T;!xUV6~*>Youi zj=JSUb0F39VR4pwjDKZRK}GslbGDrv1Dn2sG+kzH4Dln`ks@RUrfx+IBaH|(uM!1K zolxdzG`7`Ig@^EGV<}U2n)gn%KhR7Ko@QJA)Vs(R*u}Yjg7}-GSpgnB+F~1cF>U5d zocK=WjY475j9dJJBwG1++Rl`86!8lk3aJxi0@?MeAI~q2=fv<$9AeD;Rr9o-mgg<7*Y(GN-OCdx6jvV?vx!P`as+yH5vK| zJ(rYq>15uVvl)i$wm;kmYlk$@v8dQ%`ZOy9Sx4`1Ug8W6^R{_b!=1WBeuexB*&5Fs z9U5ZKuEoZ!Lc$J#SnBJ3?cQ}|)I;;NZT>yC21EQX&I`!~K2(%E+3V*&tsS22Z(MVD zM48J(>b2=he4%ojRs*BFojAz)YKfRTTj_yPA~jEYl=*bu%mLpf6@N?7?C&XSxX%xo zyt)jfQRJg#bFzXNB;vPa*i!=68@tn_O5(LR&u(gudarDE4G%tVl4`yNUEN}4%t{&* zUQK+)%N)W14WLcYT3oa^)~vjT7`j>Rl?BuPUKTW1NewBdz0}UBNJ;xI-+I@I4vn~cbUg`8V%zXfH=s_q zI{xizOPPqVn$_6L*DDFDQ5?4-&yQl`l}vTo&#ZuJ4X#Jot=R-4mdEhjZULQnH(KN9?)F?@ zKY@WEpAr$791S~JWDA^Dt*R)dpN^5^hfR+}R6?_0g~v~rErlY7t4zsOxdr7y$_gXj zPHmZ{L>82Sron8+PHdMy%P+fn!B&J^&1T+c1v0pjpOBMu!0h_-iVkcP4(08Zq8V5& zA-(}xO}JPcny>G7Q5ITk*0$kTjq}6OPji#+qx~2N7A1+6*GUf`LUo7-MG8d(?d4m^7f(`q`!5{{#Xh+1a9K;q5@9gaHc z9+>@T`L$R!*V2TmBX$Ft0J8NzU=6_22eo4~4hLdAw)sgpq<+WH`>B7qLPX;TI7LK(!1R~;l;rin zZBUp`N;n0mHM8~@$AUlyogVMY-N~JY!90Dh5_|1?oI0(bMOo|#gvmY^=H8^jT_gJS zBq`Z9vJZ5_IW@;Cqe$f(`&bM~mD#QcEm);XoYOm^wQWTaL z@#WaPq||bx`Pw&MN*IKLU2G<#;@LPP)}(*x!1fET(^tG>kOhoY*Qxi9Ml1~xANIrER} znQI*T6(M$Mo8La2S0y)ybX@D`8lc^Iv*;Q=?~22aDZVwm6o=9hiecZ%JQ6hR(Agn# zboyuH>($%pX~#7moLGV&0PSwi2`+yMKTs47Ja2Y4eIa*JjPtL-@EU8vZjoh>W#E{71|oaSe8aZ z7_dG7M=-eXYSY7{eUUw{h#r{M zP}Uykpl9=tffK~Y4V2VRNgf{lFoZFd$hnOk_wc<{!Kt<*GwTubDJ166y<=hy=ynCX zO9G4zy>ox)m3V9x6z2tu%3}<+ceHhzRcLtq*de@UAQ;-0s#De5u(P92eJH(o0ru;*{k)dr2ix zVoWmn+aNsQwtOw1>0(6N1091;oavP9xgcuY zm6WY?RZYFaXTtV+{zrgi4$#2K-$nT!(0~~amVVjglA!(O45qes#@VB-f5!T!#>?33Ihay|=3c_=ZN&9;}Xls^)5 zYFHOJ^llp)kbeB45f9-7ReI;)M)~8STKMjuc1DeSJVEM#ZLE95iR+;=*9_!o86T+L z6icYpV8WR`tTE+ZB3p|k@4`#gbpbCr57K*=$ACx#``_upF6Cbf`3Yy?VhV~lGq@~g zj#IzDvex|rMFEW%V#_7_GC&bzRl@skLv=2{t=PA-5rItIGwxxYPGDiZX4{mRo=^Fs zmFh}9tVl5frblUOrx)s8WW430N1XiQuWzyjTz$@Yytf!nduTNukNBo2SLOk@BG_3& zf-<1RC=A;VQTff)I+|(N;N^lsyb++e28%ox8{VN? znMt&6O`=eub~EC=VG_aPHLfkLw9wRtYge(z0A<^R<>iAnsQ2Jz{|RZ(;zXRX{ZbO;1S7$+>#Ndx*X>;##&$YJ3DE zIP#-SZ`~r!*0?4vhcY12x|Rlc$4ldC>%o|U(k(S&r9j97_y9?%M;BlJunO7!bZFa& z=z?Oq5sB~Qn3QABnI2^}T@xp>Slb5>I5?aBeN&AUk|h<0oGO|-xV6g zD*X|gfr)@k%P)o{59~RG=(Twvxlg5WUM^RfySMt<1aq0iPD6*fD)!hpu!AV5zOz1Z zFXdSnmB|ms*O|gp^2@OwSJ#5kim_y|h|H+Sq%8BJUUZfqeT%j^1Fq#MNVb|IHPp;8 zEsag%YA2%Y->Fu{Dy<#FlgW~k&)VTrZrDelcNl+^sJx>Cv(g5qcAZC1JAV$bmuFZ}>_kU+_@RK1l_00-3h$V@lOao5ln zk-YF1t>65lYY=-9cGP9;KK)r)&;t5YFzxIs&0--Wt-bOi_Uw&1?erwgtV7?VI3v*3 zbkXQs>gjNuXm^E-J}k| z7z?a@11X6g)lGV&-=GDSt3t%$??U8vJy1%Mu2W+ta(?mFKSfH*p~cq#PTIOjt}*Tc zK>3xzTww@Kz|*d5d7SmG^ez#mR`}xAR0_pU3;>+mT@P6I3qUbV%HbZ%BMCSLfB1yH z#gCFSt(s8(!3)nN0sC1$Fm{kAk$MS|;fsWl(0HnwDQ6*$)FN8wQN5^B*$4-~yrv7+ zK^{63xB!|_(m*D4{Uadyv;61-${@N5wy-wuknu1e_)BVJ6NrC7SZ3t&>Mb6viaG~2 z?$9Ua(uO9isYAunCFb-aZJOe*JTKQZASK(MK+2%`);%sMYreM(rd$|PX83iw=OLf( zB5ryce@UA^S~+QL%25R$yDpFMG1eBSoy`BLo;naAV}XKL+zXG1$okiu=9 zf3v2Rx$SrFEWk{)Df}DA z$rnjStP?jE4{6EK^E>Ev$x)A20nvb?pms7FF?){y^Ai%}wO-5p?X~^^XNu9H3f!2P zr7bWXh~n8ZX_MkIN z9VbrMC;#v>d-Da|^*ZOs6zpnjoiH9?!JZgEPo+>Z5_YIwq&2j8EXMQdQ{bD5zo04> z**2q1Xfhaa$Rs`Q!uP=bx*=3LGDB3)9r_XfmIQ|w zmZ(yo*7t=oBl-tg@NND=J3!MuFtlP#j|*}s#Ua9G#f*|8ZjD0k74P*~J>k0mZRUd9 zo4jAa+eclvfF~JX0De1u=KN8fC}l%j zP{UV{?fS(e6^J5w?3~)#T*fW$zf7aK53#E)+EN>Euns`>N;r^sm;&1Q=!7SU7-i9n z;qfj{#uf!W;Vao~zG<0e2f@1eY$u2{>ZpKZ`R>Lx;^MWjM0!h8q(-qi7L2=nO;)a#$WqAy5D?XE$%!t; zbofMAiP$q5#at~Xp5s*g`PvVI>>u!k+-{5+$grkNzZM9pFV&Dq?~7 z46Ta=KViS9L#x=s5{3gH)~RxM0LCkyXFGz1%zMpfOu_Uw6B|G8y009VO{#c2g>w*L z0k*SN3C@^&KG1WTSF zL;x70uS8CdLj0w!Z@0@KK#Plo*IyPcQt^mP;D)uB;5oR3>t=d5tuR+GntqZB)=dJO zHy9Ose+;?G>;KVJ60%YSo|2c-K=Blg2I`!C4y^tG%--WTG2SI+u*cm zk1NMYG#{*->^*fzuEYss{DqgRzHf6ptfi5_?d7R?aQvylEv=y}480vNNKp>~#-WO+ z^8$2?lp9{zxAGA(rt&&<6H{nH{gZMfV_Sv-2`9Q4-1`ikt69lH<_Tj z##=TG;b0VV6opaAsY{UeIo%SSUWla+RtfFshnnOHiX)=kK+!b|NaaFG!#~2AA=U(8 z#Obi)$L!^2fefZ9sBnU=Xy(|}fKAx|EHY@{;%W)VM2GuFzz~+y+|(l!MMmQV<|t~A zNh!mGoav=|#{DQ}^(QbM80zkz7kxO@ActgX#2v=_Xb;tUgMh^TQ1RAv!7vX%*J3{| zI^6~Gvb2L2AZ<7~NxeLy?-Dg5{SJf(o*2V*33(~zJrdLTJV28tcU`7z zJtxPApjt#%&OIyuvA!D+=2W$_3$wBAvX`6oMF6gIE;Z0aK+q$egn+IEoou^8an(NN zMi-6+EPFN6L}5JuSfw@{-{&+0JUfFP@No6P{q-{xp#^31Govgn8OTSr{73fq-{cCZ z7KqxD*$N<;N!QKeg-f*#yKvXA`w(w@a~b4-Z(^hdCSV$z0r#w!J8g>^G^E>#MRbwnFE&WTKEc=Ux z77vFb3(GZeNryM(?xj%{(i<9a$is%=_${B1zW@PCrVWIduXw3c6J}mtM;Y)#4;)ab zkc3IM>7CAiOpHShYxR$TAia`6|56QDkRLiL5GAVr`AEOyK1o079+j;W9gY|*3r3mH zaEKWUNTQXl zBpSUrjrcc750SEj`_FuTVyVK90d!_aKqD3VFdGPZtWE??Zu5Kwve;w<9q*2eBw|G1 z*ym)kV+i7NMnKY+65_S^0#<%Pdi}~ZqQE7l4hc{BhY{n>V3v_akbv4~0DveoqB}_k z`x^(5=1{3xc-hX);kRL`T{)ed%1h=HI28HCs|qbnE+ggAJCpU?i5-@ zT^V7E5j4m~`W^g*WzY@m9Y-Eno1Cu>N#{>IEq{a0tfYK%N<{_I>O6KGu^BxZeaM3S!rNU>vJEz3o;4NCX-AQ%6u|jWhA-sz|25{4@}7mAAh$pDrHDtAFq8X6T{-t zA9uud#!aM|NOcn>5-_bldomm1;86+iZv!ohN;KTLm7G+yPG;47nzfN)^|8fmVTDKB zL}!+i*A*PfI59T?;uPmtmH0P_;s9MG5WpRL0>5EFM~R_$rp(#cHF*`tS;A8k_6P>g#71Z zT~mgeQg0cwwiL-q^+d@WD~#B>FJ}TM=5Giob=dW>H*ERxvJ&nYQ8p11+~|MNqT3_L zTPK%$zDuC=tr{pN$b$SpRe#Hu6Ra*Tq4fds3;8bZG2?*LppcZt;{M4U-TN0ns!X-t z^&1_PiviZk{F_uZlHU5-n)C6^vDfBps$?u-U+tVkqloBvKB^k2QL=1pf@G6vLt*D8 z+Nm&@g~0)y(%5OXnGz^wGXTVdazD*CO7!P7#js~*&g(zyl`_db%W0?-FYN(Qhj}n1 zS9KC4P?F<#50GR#U_VL0%VfRYQ~D2RhivdNXj&G?=3j@n_1a7zo6CO=lZXwlVBB#M znL6qb$j9Jp@IHx7jR8aUuzdRiVU-=(e2PIOK69!{&kZgiZs*yTVe4r!NAg(=<9jp@ zMC1NQiYTEL5%p5j^fK$beu|ty8iW49L`8S_u&E$4XFmD=JsfbiQ4Dasd!N$C z!U)Cjb)xh%ir8^5gGyn%9w&PzVS!P;^x@PX5*`3}A|u!e06Nj&2TGV9fO0)Ez^F93 z-sC5&S~F(*@X2r;q6j|ELubVi!wH_RAs{$@u$IExR>v(iEX?`UTJUWnNd1uWGQrR< zf>P`TEf#D5#rQ_@3w*-QoEkqu{Vc^#U;X4YjsX^WGo9|ez9}eQQ@~nhG4afn*|ERW zM^tbte8f965RKMjk1AWV57nzdPVo2*Ix<2c=*17U*v@>^>o&1(l(L1E|1h-wV6k8W(zKaqfoj5R4qZt;-wzF;UDO!wGr@pvCWX9%n99BxeLFDu#Cio9nE{zryNhV{x+bfui3_j=fUQNn6!| z1+09f*iedlfOCE8*he_0L+naB#a(iFlNt^Hx_#Ua6T&ugnjG(iH^UIqg0(P`HTj1(|+ z6QKr3$LbCt4?K9>%3xmPV&QGN#w0ngV=hxnUm-%C|pS z004c8gm)h#rX1#Wz%ecfYth+BzLwYt-oO5GM2*$t$9D{&yEzMMz|e(jpkn^jzi|Bw zEKWTKx4FryB!5qpuNc+Xw|*B*HMCm=mDg(9SUc8dRSR>pLfxzrjC-TH1Q%_Mf-22w zf4vS~FQgleJU|PUel=U_5k`^%(F}MDQvfVqgFvZ7@m`Rhlk3@br^(roR~A1hHa@QS zNNc*$1H;#X8>b*#xeF*S%xmwZd$5duYBOUcIRi4yGAcE>?^CaX{g3%C z0ElQo*s7&XV-PzE_DJ{x2N5RF$_nAk|`vvB92bKO-==|jUOY`*m%TQzaK(EY1W7*%VEZyC16Z7tA_0?%qSHR6AGDuib>clxvO)0= zjvipRs)=O(t$j4I=KnZgSqd3Hhh(E5I1tkJ5=7{G8#_TB*wF;fZPxd)b8Zn$XT zEBT^yT5yO=f02+kDc+Yn`NEpe^Let-F#YQ~4F>!UR7!E(TgSX=RC;SeiGlR*ZV>oG zq`s%-r%+N8BK@lE2VIr|wIlNPeio-T2%O)pU#3qKj3wDwczQ}-NDo%RdN%%SDtbXo zz`C&IJk?XhUiDdB-zNITt#N|Pdq-$+)YX|0XQ$@<`*-)&0 zcS4$Bb{f$lIL)CniDQ(Oz9>HrSg0qnpb>#HOQ&slQKU^%O3` z!*bE_bn=y7@-0HE z*3Y9ZfC!Er{;v*xwDeXk>z{k+3=bJz`}f6ho2rnN+uT3@_;3}$5LXR=y}0n}oIKN{ z2xJbcANQd_{nX~v{1F6#V2Z$63~TliA2-X$+_y!U0%*P_r-}8>e1xF{Ut1hyL})Yq zO_1jctDUw6j&CH|=`%d@xLiAZv-y0DXl=?PY!-I+n68&`oF12W0RSVVB7&D0aD>8e zG_SV>HT#(`RTE_WJK)Q8gnG5H&S)oAMH1Ovcj4rYyZfi zS(f|JOi~i1Re;fPv3IqGonqn!oOIkV9630P*y$sFTkpa4ajPq9a+|#^Tm?s<3CNDC zg&Vv$^_i3pM>je12)*IhJh1f9!xGS|IDvLDfvPNp-E(^WzYO(|b)lU2GQk_Ff3o6&mAnk+L;{?%+X7Y*pgtSJAq25O|1N zp`FxMgR*~Vvizgv{5OLZh7<{KrI9zP8Pn~sGEI=96CTCto;HU|COix$N`1!VSHVBr z@W>W|RlH%={;kHd6$9xkH2scp({EaMEIG{l4Xc6N=vi8zkQJ+i=gF~G#&w#JPmGov zw$TyQqa7zr_oaSnV4jD;Uc9jCSGI08V13hMH`8!yeM0irY183VL@=* zeLZrsag9wn7wjr89QA~eM*YhDD1z{r2wC{2TNlns8`DJkQ4*}=G7fBxOW#9drK=Bq z^@&MW9iF`yoD_0fe0K}L$9mmPtxw}NB|6C`vUcw%NP&}yGzMMVIPPTaNh-qP$65eG#w2pT)<4SOU|my{P!y2yh}YAX(Foylbv8}Mi$U-;==xjVL@}H<1Ysd3DPLi$?&f@4R}wB2z%;4k3r7eFwiSgON>D zHXEWT3{Est= z5ig#CewR~lmxpOY{ei)*kt$F}+RvtQW6AAw|MX*SiuA~R0&oDjzT`#eWsEG?Uv@l4 zQKk^gsBxYtx9@v6^2%eCYt&O_Q~d(=J{SPqa&y(7f8n+P9+FH?`Su z-1eN;DP;`;8hkd@$6s%g6*TX@aM>lBvIU$4oW1J~y6-oQ%AdUd1-g-AO8Nj1P7QFt z>hIG(gg%Aa2M40gL9!rAB6R;CSN*%b3Me1EAriXuYY;piqYZHS)RS8<>i;^|`pIoW z!!ATL)_?8$&g1Q$>Ch;8nT+J%-S0NeeQ?EmMqz(x6^!EutAuGetCa+Kf>K$U2AS{U zvpMrM^Y4gRpTV+^9|zdCF_yBW?6UUvp0n1!Pudg=5i#)jY)A)JG#|?iCup3bKfS+7 z75_`bJC5Hn8(%@k%#`TmkNe{IQ-&8OhvOw_18tIL=viLbh=?Ao5*t10lgK1Qnd`BG zOQF2>)Q7QCEx3>0&bRZ!o+bgeU;H{#!Ty*9U^#(^WrpEUy>SA;d8^JfQYoMkTs@T; zM4M(+NoYVdbI+7j%S^JpwN&xQ&*mx^WHnPv9-77GBTOZ;dcainJd_BRwoJw45gxh_5`00k;qlC+&`s^jZ2!U; zc1kKNsyUcE&`A`Z*j8uL3I*NIAB5OJ1kBkeY`aq{tp`Bcqhwx#o%Je#&i}tB(ElN6 zRxDB_Id&MaG5=oTBX@VpU8_k&j|Aftpz8v^hwsc$?(Da-tH9IP=v|Lasz)~IyAU>cp*=y>7RtT#++qDf^dO%GkwDBz@>}0!&AUJ)f;4Gxn%=rd%T`tR~cPXg|iL1V-)IWM% zkocb(V&>8XgG+I&*|SpB^MYmuEij?c@HFpRKV3R0pQrMHr-xz)IUnWoC#ko&P_7gx zo}&!pG^><7ua~$<(97Im!-!9y4)~8uZzwHzL5IrXjW5}@w{URPFOyw$zRZs6`}2Tq z;c9o|ku85b~UevvSl%&I5p_AU{tBd{W(=)8qBKk-d1*`I8shs=UHsWCyL>=vVe_Z`l*en;*e$z zuau}_6-McJVZQA5KAh|t1JZLbtP%KYIle1vTpok7boK)y>DxqbCJsyyp7+xuwGZGKRZ|}-a*hdt^aJ&T`=l>t`)B6u<*q?6^+ES*_XIkaY-TKi(RK9#2A$%C7^$7 zJb{Uc&tPzfsw@L4FIvzdDVwUprZ(&bT%hMmVmjuVcci<&%u5X7zDEF?S*4@pgM+2# zJBxh_5X1#eK6F2_<7@s)#W7$wo!;^$dD*VCn%VtE$)k-%hrnEO!aJ#tD|M(`VvDOP&id9wvb4L z1V=$<(z3ZvVzw{rFvY8Je3pYGgvRV@Zd~&s>LaqeUqM!-T1^0?ZSTA z4$e{%C*4i%V8by0Fo?idCfZH5^KY9^Pt{pZ;dND(Ia-YBrRjlZKFL=oj>6FllHM<>fHvG1m3 z&zGJ=tG_o8i7%ZNXg<9zbP8j~g=QayxlhmGcj%u)by6sVVJGvxcF?V-i^fjw ze!#vDnjmS2h?DX#0T|LD3QR~XSCMk`CPaS)0@l)CrWMIbavK$p@fmw!*%bz&yCUgj zAthi^OcQ{$WZ2W-E`la{{OSJ;98cjcb(1wEDK~#JsPTtiIvKTADBy~J$D9#(C>}+| zci2p+xBidVvV37kCA0*w!H74%)Ww=p`tFE&s|<1N^*3cn|% z%Fy?MiFCB~avs zd$=9^Y}BlA$eNC8HXg<_Jrhk9x;SY!ngmyPmTb(-$^`%vA(RDxRji3m6o6g5fxc~0 z3`A*fPp)SplnXUDMjPFn2M>A1$&z@T@*97gj&EXwH@A6URX{qJU3O09LwoqLxxdWB zxr_k%Rf@+4%7Q_DO9d2=n{pihqc&ys#|`Plqk^(AvD-PI z66dwTzqLhTae?$)IpFb1G#u6ObKjqlMBgL4{MZkYmwm73iC&i5pC3NG&75XUdZ=u|tsQXKj*7KNKT zwZfrk&5CZWm{HezSAf$bS`(V?fmYsCJ30((c7u%4>hD|rsd6pz^?u^Df#_jdB<-fr zP3V>*Bz$ver22kVgda1h^nD1POjXau6D@Vhc76eJ`ZG&*RG84$&egf zlInUBiP$mjd{Val8e7HDQBa49R+gT{b$_IZC!`S#E9~W41>HyfcvG&2LO&EG)o#Ye_M(8s&JspsXkKcoA}YV|L`0&0B|?_1 zKhb{o2`;V8n*^eSPv~c0Fz&mV3G#a>Hs-czz#X7d*K;wE(^~*p#=>%chOd)W?RCUa zn%-T|pTj8g)PhvpUAX=udq7zXZod1uobzh#i0>UBt)yL!5hkl2)_aq#R_86|V1_ ztR~9D34RS-x|mO81%a&5H$Cbp*+d^{$sbzsn$jWE2)?{k8)ToZ{Hs4-<7EqBbxuLDU$ z1hnF0OUy_HaiV?`8lI6la>d*V4@`nlv%1&rW=ZLz``p>7` z<{>32Qp=RL08s|y9hDl4dSU>)EIj}!Wr#5kXn^|#@?6*dk#m8c{MK(QmkMGC*4~Q} zr*O~b)hJM7g$Smu%E5my7&Nr^0XEU)i>oW8@~3yPJ(59sZxQc6cwc$keo8JL^(qy~ z{PZMIa8fL$NSoa$f0EV_tj`)F>M5W`!iJg(*O(F^@e!cT2#NkaZ~yyMA3H8(!YAEd zD&>5Jy`(g{9&z0mEg4G6RX}q7>kSoNl7ORx3=vCaVl?++U-XON>y;6*0G$>wn9yFAsBFYU@!bKyufCUx(XX=OSMA9Sgyml(9D|s7t6xtX3d^E z2YcKq2Q?%5k@pTKa;oHUv)mWDIiH=Z?aYRy?QHbMGg0h(l_VMNQPnK_As+yix$kyv zpmS460QzFP;w~J__{kwehDi-{$8~^~n+-I!>F_kr#uDBz% zMNDBYDyv{bO5U=+v*GQWdwHz_GELYm(9`X@W(ZW(AX8SkGG&&(-fxWX<_BGqE?@ur zqv-etJ#}RI(h{=Ec9ACn+nFrxhq|g2iv8(j%ip7Y{pF?70#QuyBUHz#WIl}7s@6BL zgC%U2^LwdY`5$9VKEsF$FUM&>M{y4ujBqj=m~hm=7u~ha!iF%OzW?g#_?d{ENX3ui|S}}{vp``Y-{W( zzC14uMBiPa@XF=HuC%28icOJSwJ)1HN3?on+{Tb`-+G?n4~!dht(6)UdWIq6ehnG- zU9I9-Z3VNWlErSDlWoYYq#%=pB>>LZya_%c;Ne zzCnLzMaD6vDaKXl;KTJ>q3Ac91T@zJnospC)CL-> zgX~wvT#*#<(Ar?>p%?)MZ>1IOnxH&lUC?fi!Te`_^h8x{>8nY8muxp|r`&~)zp_#Z zYDeV(qHw^Zr(1iI{XpA#AdbjnAc#G`0ZW%6G6ye1G~j2m6oO&1;W+!2=c4A2Gdy3U z{hn8sGnUoQ!%DIlcn|}^z07k7tNsLSvytATPQYgKt5$_#cNDwrWStBbw9W-OR>Y#|^mBeeRz~^R0WnetY!DF>vA&dOW z^)T8$l_fTRp{MKgsh*Q&PzT5cAnHs4$`$$+2&Mv2HO!^{-(Sin3g_;hna9mc|L{BX zpC4+L|Lp7yuC;BXz3#SOg*~CNPUvEL>`-Z^Lvc%$=E!b_YGwb2QGTtC%g*On)l`|7 zg5u%60%!PQuJ!`k@z<_M3$K&$T8HP+-O}ACKRLwlqg)pKi8A*yLTMO1m#3WvYSdW! z!-ZfD-nW$j*gzC+{-ZGdmWNBB$L-EgvPd@@cI(Y%8}Z^iJ9PrEz+~xbawI+9%LoDr zkIazjwLxiDY*K?*44QNpp8V-2dE?#Zsd+$dV=1;+>5iN3_qUocPw)=YO{@7*?k!C zLQ}Tm7ST&C!K*Oh{GY=Jfp}o>H=w%{fe^(begY%=oICBSq;0@iqXAgGM|E zKTJTID66FEbQYSI1_nd`YVEVAxx;&W{NEK8z4l5~nlj$GAN?FWLTzQH_kls=T0GJM zsHg(-E+!})Jo=qGz-UpPT%46x*bb;PO*Bt^c!PeIfYm(hb6>So6Y}u_v~?s_q7Ozxe|8 z<|v{TrE*=~8T@nsT!J6y<6&&L1vLl_RvCr08xmiKJ=x;`)C2IbyBJUQ- zVc7?^v;%e>u*j4v68Fw0S>R1Uj6tD9>({{<5(g6ftq&I)4zxy_or`-t=Wc7(El-)< zFDP1TdgRQes{;Uq40c;BNVQXVJ}*{(WYqKbb5r^nT^(Vaf_vyKpIspjswFQydSXt~ z@N|=(Z(b+^iI^E969Cl30d5iliM#*=miAjnpqAZT`qDiq{~bSQ4>duyuD~{!m~Gw6 z{VGOm{EiU-7yi%jHMnv+Q!26{qylVUt$YLsP4%0kSAj|x2L;G5(ExEWm4{2cq^!Xt z!|3VJ^97*Enxe!X4LCju8Dw4~KUZomIG=X~D9;=y?`)G4cT!x_s5sjzo zYpA0WjC{K(9yg_%xb?VIXTp?HLt|wC2FY?R6xKQgw)&htvetbTX^bshljckPfRv(T zf&9Hx-iO_$99UpE%ZmEY3t{J>I?WJr!6Y-QL~M$I5hkhc zr4t!t2ZvL4qTT9Vd5vqBJ4|`J4U`kXS5@-YQTfr~B6n%-qmrkmtA8>(7kb#qL)WCm zj^k(*-%ffV-PYzP6Rn-Hz2bwSUS_O?bTyp^s~>#kOHxt&#o z&VE?qCqZ{nf;)PfxRSXn%MI{7_ zOm9(eX&h`$BpMP~5Jl0atTB)Q`6CAj_^ZNdhf#->t#4v=h2MMFWpmW^4m50kc#kaf z*l+WBc?voOTGC@bUnmEPLTdtUT@9N}j*|`^s&lU{vTO!6y6B&h1{63%+&P4Gm-J^C z5AEn1FV1&KTf80b2Qp*C{8HU9?5Txv6H=Q;k3Q(LV?VOaK6T&AqZj|B5;19%Hn$`w zcG8%@@NV{2dahtbv0gOxl$*XF`Sw%@+s0RApY-s#&YpeMNVLEtk*M^Jpq|-EuNv;} zOH3_;J0I$GH-Q?V(|p0^#n?02M!^eLuZY`mBr)jiDMz~L*zK3kD^7mty1U*G!B0Ih zdv^_45FH1wlS8x7VFn~f%&!?@zfeT#uFYM_M;FaH;zbl>TI<|3v%85?ale>P(3C<3 zSNIwdGb(yI%`zT*`{H3aFJd5L)6T_f5Y9OJ!{QuNPm|d163}7Z-q^?hh!hS4XJne( zUFO?;^xc;k7qU^5l&dg4;rTMO)~vQZSo&}stt<9{sdSNrs>$}qo!8H2d-0KkFu-@Z zLo)#bW`b^J+p-x?ertMZ)NRlPKn9G_!1Q!b37X z3cu461XraxpQqJCMHfekHP~;D#i-Q~H&~>uu(Q|`o9&qtJ@J}>TJRix53p}y+4W;? zuMKxC-X_Vk3r|;WQl<@^x%Hf4L;qYr@UW?or+F1U(Q2wpTvSXf%dFHe{iVIMYZ9-^ zz)ZF3ORLfRC9Rng8Rh=clnx-G6c!eiIdtxtJSym!d@Gsu4nm+@GyPC*;E?&U__g2j zp6J4mYHsxOSIpu9C^%cy*F^BWf(9tSGm1m6e(A}t@W#aEk?&vB7ECa@JmuAB4CK&j zP|&q%82D4B=feFH!Fv^c15QlZfDT-oQ*d#zL?UzMWA#U507KT~XNCE{-o6D|Hkfs( zA8w7Tt|(UqE-BpJo52;u=^$!sv6RK3-5QP}KBwOr2;(+68(eY7m?MJ6c%ANhp(as! zd#fX>p((|%>E?GT0jx;zr^pzYSklz{4J*?Ynq?+$Y=#@2Y*ujPupvVS9Sq$pB5aCs z>?~kKgj@J6c}OJ6l9>w}@n!gko|`<_#=LyqlKU2z%@M2w+RLMwAGPspv6_0mY4NuEa-ZW< zUxpN2-+eZbC9|8?+uM-}bPC}X1kByVPn&OtNI#H8Ib#40Ei~?hKlmJ2*fV4l z*51LRI1dK#Ye?nb%%JDY6o+lBYSz{rlTBo*EG$M;8`M^CDX7H4WT>#%fVa60u81-0 zQK;xOAGtdvoCt>(n@l{O)6N)Ogp8y42fY4cr?2|7vJ8q5@~yW>%? zz~`|Bjo@50)CC_ePMrR7UdXVelU{IGn6D;&`r2rq7Y|7YxZG`OI$h{3q8rCS_v+#A zJKe$po*4QX<^(l6BP3Mz{mO;CWXie5eHD+Khv*Tr>C-4kD4ZJJFqs>#cORqRe8z_? z_O!Y$_Q9o9Y}j}ft+s#80~1eve4h$*;4Ca>j1JO(4d9e0gMZ`8CW61I|DfPC!%R5$ zN-MP3BE{oC^UpI$`h?Ml1@m$t#{bw*D|*wXa#m6WEko8uG#fj( zUHTOXQH6HST8Z_mci{F)cD}%pz*Ez{Zgn9AZzIqKjVK2puPg@nQn`C9KbR&b8jd|23pzqK{M|JYT_5w=j2GurLpXbBHN zy?c+WEo_8=Roq2QKYSAY<2wnBy0JZ@vr$y(hrBRYpmYG|?^hcbUAGr}4OvsXr5o0r z9ZeylWA)B2+KlR%|K?|=r>3OnnGC|;sKoE-dWVh%C_@G$16~bA9g0$e7YL%SY{h|9 zmBa$8b}NdVkOa@Q!TkA19{IXtaQIAWaI7+IV9y(hrMP_MH`kEK!G(P#JVOZGdf^x% zD4bLM4(GzF$oBU3brHL6ae3A6Zy=**(%?A0$ZIFnWJr59nrShyq?{kK>fy_fho^*u zgu;RcLm1++Oi+Q3!7E`xI2_MnjMi?D2#jnw{G#P5GmJ^#el5}x2`p5B>2l)Zk`U$> z=$*YI1TP=<1iXCp(0{%B$6koj?aw3gEA(S09$O^p?*=>wyT^p7998$-E?=0jg9kp) zVwXsKi}$zmIN3YWoWrP5yfDz9y1LGA6WK?W~9nQBhN`Vd2_ZMqz7rI*9a90=Wg z92)5CF@yhlch|rbP=+0hzkGY)mhNfnpYV(3`3K(>SALPG7p48^NGNAeCWMW6;R8-Y zuO%PWy<((2-xA{QdNG>69}%|2uQ>^z-r(HNu%`cy`|)9@8BuOKYB+k|zQI##j@+Y2 z=V{L=9m0@@0~^|_v^fexqyMuHI z#m!V&f#3H#3B0}XzwS5q<~W}feU>pDOuj3ge~uv7h&dB4$XeS@RY;=!+OSn;LqbNz zx*AK%bM=~W?mjSm2O%Xv&|Bz^uZ$7obZgSWBOzf1kf|7;3#fU*!Yc_rGzpo5g9DG8 z`~$nt@s^XzPN~`#s?=ukpOx?@INQv;&SSo2H=Hz*H?c82i zF1-T@C3J!HsNV-;x*?-?Ma3e03W4I1pyEj&TF=^H(dwEjFvL}UoJL8sq zl~>i(UF##Ph7Vm3g8z{3O5k+3FShErE?iC)ZPtvlob~sQnO1N=8usX%)ijE5Ue;&Sjofe{SwQ z(F?rlo?1tuOy|wX9iW|^Re*gDx;^Fu40;VUq&yCAz15vKKy>Ocw@%4E5jeq$J(QG> zf`pcVJnO%#0*nKxfjmd_=g;E~tKS0mUPcy9fV;oY5|X-iZWUcGEfunN?$u&U=6D?` z2>NC|e+4RZ4aRA5_{yMJZggljo<{(rUR|0`m$Zgc`i{FAWkNcvNs%yGv>% zs#-tWLT+U?)Aq*A1%3U;?sDHUyogUT#&c#&~*43iJu zNKR%lhyKYCNR**6a7ziq`cQ8!1rQUWxa^fiO_7c0(UZ1N5!zNndTH=D+GT@9%pr{?(G*J?RE|e<2T_~og+uqREEBn=AZASah2tRQ~U3E zioRSbB|Fx=^n#@0UF@f--5|kv4U!pbhH=rWn70E(9a+DB1aL9fMmJ+^-GadR@~p|4 zbSoZrmgU{Q!yq3d$v;x8Uw4vrbsrLh0pi&hNaH}!VYGAx4G>$OTgaa&dv4E~Ge zOIK=FJn)^i19$v9F>_l-Z}xB!)|{a*@#?z$=Ny5R3Mgm-3DV4iN7JM*6GE1YG#`WFV-c4gN}B>O*5-ffMRs+leSm z2@kb-8wC~BdA2((Ft9Nns6sI@0xAoU+i0O9{SPJ{^T)*Ta5YuBr;ZHj0_?q1h>qO4hR zd%khtFuyER$MY;|k73{jRHiQfD9wOa6hzMJTi)-8!+H4FomL;gKY2b<4V?p;ThTyE zDx1rAgBpqqcy`!n_{>^TYG?c+GO3gn{<0WVpHRm)Ue^+c)8Mygk8qbR4r z(Gi+T|B2N9Xn6gX1R!o_PRAwN_N;0&K>dQMmWoPlh*9jC4@g9nBE0RO$`)pT33*eK zKXoJcQt@;+M6BwMni%oiRBz(fi^xRThHa#=oGxIS5AX0CA9kxwbOO$FmVR^ZvB~xe z1>ZN|Zf2nX`6*hU^%eufxL52e>o#rT5Bl8Vc|Ya8oG=+a6k6i|sCX5LP;yovRq%C? zW7`gt3e_!u_dh?RKIiozj@s=}Jm0BN?QTfoId5L`Wdak?SF&(W4AN-(KR^4)olN=v zE9<*&bb;(rrcR-2a>*`BYn#HKy&6U7EsTc*>c@Wu`~nd0>Ep>_uiTms6I4!>{mCzZ zbv!^d#QG8*=j9n07N(eY)|^Aj!Y^4DkkQ8QD`k1%Cvld|MBM-&H<%CQtJa-nQX-?H zq_zNmZ`_W+P50zET^%~I)2x&oHoJVGe{8xF>PiDPD11+=2mf5U$^E#j zW%({Lus?AF0Q2Pp`~XN2pS5{zyxr~d5Op2>I^Bt6i4uAS9^g_nMh~vCc zqBC)kMlRYvP%SfKX?e<()Od;|9lK%M6}lT+e*(6G1VW;_t0TqifKwO?bR%RnG~x=9 z?x5hH+xP$+OgGTJF#(LIGJ{s+cmShe_D(mx(L5>c+B{AvOL?2@BEI3|gkdC31-9UW zMji&#{$v3dItx(TBAC_L)OqMZaWxJV4-Q9L&qizPGgx%%R3PanuvFSUZG0><<(+GB zXcU`jo6}c)deCQxd~msrgYlJhv|xKi^THu3^&QkaIr#Hj|7@Os+O|5K4jhRr$Qc@k zdp0s?5r&5Z#%FXsJVCLaGuRso3)atE((u{Brc{zaAuUA(`T!W{zYVGCD!-=tb8Epx z8Aa}|Z;tshHJfO|%tBdgr9kK{x*nrnp)j~xr*Oy+( zAWS4o%(3b7Q}T^?Wb}OuoTPo$v4JJyMQ7~=UHFIXf2U9XY83sKXLad`=@HYdUtt>a zOknT0NyPa-2@_Sq>$SRg=Z8eDcRPB9BYkOYcE-Z8`_81Z`*dKtL>Ej;Uv#&$n_u`{ zL-t`*JU%HKNZ0gmnQt}KeB>RWqKB$XCm+x3xX2b=H1?97b@3h)4ry?Rg3b4 zxL=;t(ksO`vtw=O(By>J5Mp42TdBH9BaGDXu~61QucEEN;?EuapS4=Hz6TQE4doSl zD07(%RW8#|`k%xGH5|mnsq9;U>hGn@GUS~f7!L)~c-MEwpJuzl@|m9lnP#w9!?6yK*X zetx-|gf$Y~v5ji^szqUx=&|f))O?ponW+S7M_3rl{WM}JJz_W|P{h(C_}|5TPrX_h zEukrC_2ae9&8!!1@&5QmUj}L68YutADe(spc9#=szztp^^HteIp1U1>UWv@1p`-hG ziTz#@{FN->F9>u-or>J3Vhts)$^{x0(u$jDx%UHk17n(0Z|ZB0wdM3bgi?vC6cHpQ ze_cVl^*4BnKW;A&blNbu6uOgoP#fey=_~vHE}*k$pVyBct~=Is*KIzRu3h`^Cx-#O z7)_A3dm4g`=aKxQhdn?Fu`By^fk{^kaa}o7;Y~6MTz#v51pHMBpJRXl+igmvZf4PA zA^MVfsF1S<8hl91ieGRgY74dn1{$0!^K^=|TE09ex)U_H8{D2UN|ly21IpzCyc7Xv zt@`(Ze?P7;9cGeHqr!nzLXjk{+8!GQ^Gj#CP(&y7bRv|zQ2g(nweZNOXnbsjSl6Vl za7DRPj`+VC=xSoiJL#$JoD9jHl;+EWA4+Csxt*uu@M}KPcM!qB`;S-XShb`&ZP@Xo z?3dehd1=(Ey)u(`h>GZFnYUzv$o22pT;)SoslLYaW^;CThodA7jkaEwT2}oe0WBtW zY#L=)K6Gff|M5X0%A#FEZR%F&)csF4>J^$!H~2=JWau*_f+K)f;OZ<;F<4(cX1-++9A zd}>SDbu?qe)TXi*GotEfKrtgchE+T8=lKU9xd}<#U|?c8MmvIoZ)LUHo)rf`&uVD# z6CsNR3|eRbI_GtYb^9ySUtjKTEZzSgf%FQ`aZB>;@$;+{&3Fq|+OH3@knLjRFu?Bx z^9c~^~c}^2NGCP zmYr3L*>jDDlaYW+q^S-Ozq3N;NX}b5b1B{cIo?@pRsal|BzWI(21mg;12p5h^E%E=+_TBMV_u;=K$|&wsMB&Z| zS%p%zvdNChYLHb#*;x&vL79q)q1jm zesi5lvIw-eBc9Qj?e7`$@8N(yd>+Mp#gEE1Xwv5vVXO5a!qCGm?)TsoeEm5 zrO=J|a2E-VIeKERq-r{fO+gb%p}k z9bQT>bi(4<_K{U(pDRs~$x+e)Wx>LX^gf#a+kP%|x5aaiVSIs*@Y;7IF_k%gMywD432^}YaKdtt%P;edV;p2oS>ob&GrC@aRM8%Pm^h0>8kPyd(G0DAusB@ z_wV;|Ihle4M!91L%BT?9grV}uY1BHqr zCk}i1hO$IqRxEOdn_*Kn|hJhPAccdR7-}clTC24{v+;iX=U%onGIPmE~*49IN z$J$UGv7Jm9)K7UYe6gmj5 z2P*E^ycBQq3!y~N9T*SUm&v}Lq#G7vzvk+SoQS|qis<=`TFO%iv<@#5SEWLo z%BjlTy}D<<(a!yRAyIBtd6gI!IXp-&nYl9C!U7`plhAWKwEc+q1W1(2+1c5plIQHg zaq8#kAdJPVAt~VA4hngooc4g|n?FR|L&>FrHmxcxF>CN2DR=Ka1e~-0VqcGLD zhS4b=vMse&r-_;d=A&9b5bWH6FkpLU$Jv8uQy6_iTa&&+_}KOMyf~xS{y1wGZ1;FC zho)l4i5o`-!_;qScB>Vi6=;j>f5X$dDqp?G)(=DPB<678uM;#H2Vp4#=!9%a9`WR{ z0b}U4<3kZ85?tfeFakq=LRA7omS7K7w;S2EuuJ z<1I&4_}=i_>^@pw@6BdvwAZ?aLq{$tzK;1)-xtYsF9Zfd9OL=uQT-wRa%yiVjLW~5 z=aH4I!nqwi-skFy@ZLwCx=BRoFJvHmz`zrw2iH&?*#faGtSE3Xmx_%doDRbPDy!rB zVaU<#f!ZSL5n(wlPuyu50Jr>6ZfdOp)CDn>=BwtKiK4e7uAd@Ehc+dl)hGr9O@j*YX3{bVGPP@=bGQ?=H3Dm|j7 z7N@~(v}dJW#1r>r6{ftE!%0joZ+95t8fa^oV&!lFplq`7s?UG}An5hlC2ODqw%DwW zG3+dG$SBj>B+m445=Ii}A)!bjZYb6M9@ZtjE(0>9~ZPj^D?pl3QI(IIIaHxSrSloM=l zlLRqw*4Z$BGjW(aeN)fXV#`42N%FyA4cX83!?%{NylK8sxN?+8RRi0NMuX*BkcBXzHA`fj>7!!yb-I58sutN2XX7o-3;$%WNr~@Y)hHuVsKk1jd$Cj7il9?_P_&XN7YlKj=@(HQI11Vr9ak_T?y-#6UshZrNnGCDUa! z>*N7Ggu~9Dnn_4j!JT4{g`DZ@GP;%^jIy}RL(M{J7jmB~1g6FFs1bE{G54^-_r$X< zGFxkT9U7=99i4;1E3F#@0`5FGvc06@ITXM*e4)PE)g`U+6sP{&0tV??TTN%TOxs+l=gAn`!NJbUB>-HA+qsbUxe zO z^|Nlv`M;Qg<6_F{2h&M22#yZYsR*UU%xIFM>6K`L!~)yOarlIw8A}S>Ne0|^&BRy- z3e&onAEe}`%16cn=v0T_%DeGN-(_=43#?$yELbg+iF8Ptx0qI1yXntwwd_Jo4z(z~ z0uj&JWk0WWf$7vY^=qqbw{NC%Hc_rwg!fqsj~V>zRfz?*1OT;62)8LhK&{Cj!IAs8 zPi&C0SUM%2n$fI7)}xl^rRaPD1pQg}QuJL|W=8XbR>FwH%QNDQm>r5)ae3}w?3)fW z%O;g{Z9U5OW<48+AKj?lS(n0Pb+h=i$o$umNlLv@5=W)`s!W|I_vfSho!3DvDU5bk z`lRXw+!*FATVC=u34i}xBCr8B_Ptlh4ms%qDxl>nbHy(58CgMUnBMt`Zo!jX*P|D; zwmypVSgP88BmvjlTk`CT)-CWOn1`e{PZrWvIm1}P!?}*dYj+zV(c?r#K`At1r>kgf z>99ksu7pNZ+B&r47k z9>}#16!*UOZrefbkGNbBLTgsGc5`jEy}d#DO2<6AL`NY_@+3837HKWU&#_JCSoKTN z$c+SWe?MeTS~zZvab}3;lN?8X(C9}bhew@0GZ+K)D}*hAUdgCKpddsGwvlkI;Cm$Y z>Nl{OV5Eo=@>UnkygWT`id1_;F?u+|be4`!V((HC9h0(d=XgrDTBhYP&k;qM88`k| zTbaQpF<{rZAqC+kRl*zV>&z$}Jde*&bzdqK$yleQ8&iEO>X`QTo`^dZ` zhjk+PTz~Z5?uroz{e2mT7aY!SLuUkFt`<=Q86nofik97xNs6 zCEHZiYOEQ$@HMSP7S-$$$ZWA~h{OslP=s*@9pI?5UaZQjw4{Jdx54fe$p zHeqIwpZI~xVY?5^i$?H8Wuy7xbETG6#dNkM5Zg{CLd{~x%=*XB)VW5PN*TJrJ&6zy z<`L!aa%#U%h!1zf6gAAq(MrO^02SO|5uq zH=b{J!QUm4`9WeuqeTVSORIaE5A=Mt}1j*$d>Ks2OMI?jq75M9FZSecAnz;Q1bZ#pVQdUEe@U{ zD?yTDVR1&jOj;5$`=g=^%ERaHH4{9ym28%}LalRzT^9+eV$R%{!#+$N>ZX^pq~Kw3%4PwQTK z7#3ltrlr6b2RtGvcvvFztF-g2&)IY|rGQdN5{7zKPjxGdpwoKbl< zyY7rANp)a3)m5XX8xe%7YZwuCxCpc32^XG}V_MVvpUOqJUp?D5EX?x78+f{qa47zb zLzM%EBL5nS{CUBu#)ExV00x5&T>^-RquKFSz~mi#qx57=BMRW3QZ8@hQ27Csk5v1N zRf{3rigKJAU2GNcM1>i4nCFl;wi?u|se2ZTVE^kf4{XsA_*K9T?n+ z3?W(5k=8O9(FWaE2G<KUQj?d-gBaxHor(DOpF=`^Ovy@6^0+OqEt zPB1VAvTy5pwYiJpu4FM`DzoOnQ~JbF6-<;N$)>K=Ap?gnhy}WQ__rDV&6d5(#;zSj zC8^4VQW`#^FBbYqHly><1#ayrK_plABaf*JMv-%ZfA$7T?$x})71kNm*m(zyV_@A?19aQPFMT)ZwnBbMS)gj_`}C@C}EfJp|7`wd>k6$ zkUg0fQ`d-g2lwk19n?K?OonQ(w8xXJllV2i-@(i-7x#Vp`3wLET@SIuzhh3?T74L95!CAH z>RLN{P;c=NN$%m*Z8~XRh-rujz9X{RQrBM`&UKD6+BN$yr#A^)(GWx6ts1)?5L3n zh~6u?(Br2pInwh(*gSv52ASv{$o}dN(WXle?#T=NNa(Ud^^W~2;3zCGJo@Vyt;@jx znVgJ%HXQFbUP>b=XZj+1=8&iFA+Z4sn8>~;Ap1fsYLjA4e4Z7`t=28i zujZe$kq%Dga5t)EX*g$kBy%c2G565%jo=6NH;3}1_4P*wTX!?8p4;`QiKK`_;0RG5 zGPDl=!_uoJ)^i`M7F)}SXG%Bw0w!f99hM%f8j>6yS^_!0XFKTa3hECJcsX`TK6wr4 zO4h@rm3P}!^&AFRXpUXEKWa4GnBsN!z-V=Zuzf1W(QlxnxpIAOO9=>=M;gdgcih(6 z>IVqb&?rQe+%Tl!Yrk9}B?Oe|3Z+aw!nmQC(KhX|z1=$lVvZ_-CWubqErw#?kVL`| zy(~o{C6pjlci46B8h~*$@lU3DAn3-~n5cT>LuxC$2Hw~T#K?YHLb4zSsq~v_k(G0x zo~Amb>A~lTt7_A&O%o+l^}o^#3Y{hbWIa@XQrTMvx77bMX4hDv+BNaxz_y;6z`1+> z_xn*K)Pe}4iv@E@Weu8HGD++@P1cnpn|Z9O_#&bAh(1^G>&rSmS)IAYdX%hVX&?qv`uceE|_Fo2bCgS-0xY$07YPEjeoy<`tlbBB;H-A7^ zmCB>$kH_~>KB zZdni4dWpU9Yb)6s-813#Q-ZnQ4v7Pq0<4%2ShQowwD`7?&9(*c0ztSq?JZxz+nJ%< z;Q6^|P+BS}o=Hl+eg;r_{N2J^stm%egKH6komEm+i;bF2Jj^l@Bs?oGAr`z@|AWx& z5+&ja-`M0btTT|(7pX00xwJVC9QJNdHfw#I9AIW@-vRN$;n@?OIEO|cW3=8Z+*K+F z3Ex3sI~9cY04^XV2Nl53phdHH-Fu1|P^<+*T=F!tV|Fr#ww@~v!j_4xEx)!sV7Z+h zU=t<~%CVhERBA0e0#zJ8a8Lu2Ffl?7RKlk-NiCPbjroeXIHODuWcm>cRm;;5>Rq*O zFQ3u94iO-!X%%3`);3Z34y5HMBrF@1@CJ5>Y;T#DSg`y9MBr}j(+M)eAnw~uaqG#R2lgQ}9Yc9#89@-YJI-AA`4K5WFYAxA>lD$#}FxciDe{ za&C;I?Wl#Dl^PDle1?zYM|4Cc%0O!Y0s-L5N7kDI%c?TOhABFEH+7Un`BQW52Ruam z03SU*KHe>h7$?sA{-y#2q5dWsNY)c;DJ4~NckVwb4&6=Q+#y&!Vh1{nJ+Oqf^{PVd ztsrKFil20&h_!zQM1+&9_UW;!cI7K?8E5gt3DTXo{(O3Lr6YQOK7`e^FD15>2J=NP zj~7xPl&2vLy#Gk^N2!rT)a%ut#BwAOS7rhAUsa(`2^Z7l8_s3>$DEmoy~_q5|Ds?z zwhZXwERec1Sg%H%J_ZJkZa=z@biXt((ryx@AgbP zliuRWcY7RiSB(3HM7H-qL)baSpo9uaBX@2cpiJQKxG*t zehF|$_!Dtgq4V>r87sRv-iF9R()xh6zFuNS8_t!G5J=#0fX2VW@r_m?sPdWY!s!4= z6{nRv+H8GhCY0Y3(rZ;W518~9x!if5a-XPOr`rz7`l;h^BoDz%owpqCp2ghyKsM8g z#HD0qJ%^H-O(cmFLoe^qlJNColzLbKQ8guzu^JhETpP@0TQ=EYN{!j~)lv+?xtRXg zarc1?sN(lRAf0sdNn8sO^A)@uQw`upMDiD27*lW3mX$6zV<#ysUG_wv{ilPi^V*7S ztZw%E_#~d8Gnk^H=Wq6ao9QB*FSBqG)^v9kR;r$=h;SiXz7u?DoMdlq?}^Oiv3%Zl z{T!2bvSsd4xY96nA`ULYxG|n!{L}=X*otZRCF&mng!c7Dx*=$Ni0nAgSHkFZD(iE- z#K$fH`4nDTSy|)d9jTe5Cx0zB<|#)|b;+}~{E{X=mtr#j#OBlIphN3L4Sb6S3I@#n zy|*dydQ>}8dbfw5#+Iwlhrq6-genr9AMIo4WF2OQ2XgB4&+R`w5()@or{r81wdsdv z!2TQj>NXWVHAH9I`h%1)X578Gl4;RdbxEkoBPdbsf}S>gh?`CRs1!ID5Ue56ww011$3O z7)K$5gDmlocb)s7G^6FAVFDr}9^=9s-r&_9xOKt!l}7B1U_(Fj6D!IGZ=B z9?eZ(oEm7g42$JJ489j?B@G|y=35(@gZhOcQlRB=B`+pV!&r_E@KM3IIjIrK*ETrS zVh{uGh3O#;{Z;w3*`j7JAp^j)pXT5#hnr`Lnv!+%1@CDv_}n=g?wp#~5iNl!8jE~C z3Y}(&K|UWH52;MPcd%;TZA>>gsZhI+vNnYyItNs1;Aj`If7Dv{V?a(kmQ3|8ek`x) zOL!aiu^s)gtpVy;uZK@f$pi0DF7Na{r=jQHe}&vzNJ39eM;~mOiiZ;8&kGNF*qMH? zXrnsUR(^#ycU>(|nBn}dmkZqRYSIG4d?irwG=$;~&PE+1qC?tMqhOYSmkr~@+^w*c zSnz!d5{)&P-v!HU`g8#OP%?9fS= z2R$&6KT*{ZTg4RJz3mGrHP?||4$V4!^&6O-`>rI*PQS{ebiDG!>^&H>AjT;3XQ7#- zS)-N^AFeMy;fsQWZ%aLmc^y4nnM_Hs9{bGLE=wKANIE64#mx?(*aBOB14{oSsh?*# z3iD1*Suw9NbekIOS9YUM_k#dd=e4c8YIaUcoARemjgxKf4il;>3i>Z-!)xVB4e-R1 zAWTImT$F1i`?hb8kZ?e~d$An`il`gC$New`&naIhreJxK05*mQU@J7gTYPZO8y;*f z5D88(Oz>P?1niw->&IqcGU!#uHWHSd`ov~?JWnR%gE?0K9YX@uu*`5%BIPYRx6itw zqd2znU5DB4j8syFa|I3211)tU0enfOlQ-^jQ0%RA)pAOa!}W<}@HOMRepuj*NHMN%j>zJ0%CvCB;4p&)xWf z0^5m;obGtT+6i5OUAS>O=;>x66Ug0LGK?*QOu`U`(WE*p+4wM#@7gtE7XeMwP-S#S5P|R&)U|1DG#71Q$ zUttHTrp;M)AdvwT?!$emj3#Rzh+bv6p|>>CYl-eo>+zH5%<^g?_(A|R`wBz+stpPb z@q`=Xm0Q+g0JWO@n3qtxf3;-^Dv=5(`bU|nPOr=ALNp8#DYUNiGJ<6c*Ud0{f|f#O z;P?=+hIy+7IfD>)uAnG~Q^eSF>+N4;F>l@A-w$w7p22e-We-D2Nh60l0Ly53^O>|; z1u1U0En5qW95a%JGyD9DET)^hK^C*QY%_qmfT?-({6Vp;9LmcEAMX-5P)8x2*rj!z z*hp6v`FFnzj%b#?Ml~;ylrK-PlB87m5{PAQ)pMlNCPIA!l@%{&$HTIIGAEduw@RJ< z#GFtPMyXksax1$#6siCfV7|tWk>Q(e48l=~-Vv4P?{6@8HA&!7mxI9j5lB$wW_Ck) z&mTc%7kx;*$1LvOH+J`t$vdnp*7SXh`M+CSZQM*NL(1I>WqJalg-XoA^kp4)yc5TI zg4-pW=;E`6XGQ6nYQ-ZN)bAa80n2w6O`8rtgP^<*p2F>j&dYCHC&dTYzr{l+=9|ng z&*r8!8d;N?H&1{V_D(yoQ{+kZZOJR%$xj>AT@Ii2kmZC)1R@9YOYMS-1&O zQfg3oQXIi$HKDVd&oR?Tmk+YUKW#|3tg`Rl?@uYey`PmJm>Y~=4&i?p_&Uh~c{d37 zwM1b^I*sU^jDtcpoHef*nV5QEQh`5WE`X9>V9eu3{_wVu*UxyZ!SC}O{`6^q;!pbK z%ERyN=#65Hc-o-fG%d@`o{46?W5%<%bsWiE5XxMib{7n+H91%V#H zb~c26_soin^-g->^DuodXx8l;5)_feG^U#cp&nU)zoN(ZO}{Hjd#~+`Aau(pFJ|tG z=r|}8nV@6<+|r;P4h_{EYF7PR&te|`S{5t^X{b=9c2#I&tgV>WqbCa%oT&v-!Hev7?lXdH_o27It#X{wzO*{>*S)A zu3LcIaEym>!;wRmf3XikLx=WlZ}Ab=Nk|0Cz4ow9C&GXfc?}K!wCBlSGF_DkARR|l zp#f2P(+<7uI}Z%1yKHSZxp?<;s18Spx0vPHs-H0k4ob=!tn&J@y0Dk}jR}(MDi4ea z{k#m<8#RbX^K$-e1j9K>}j?4<*vy`C3fBEzN#7GYoO$ zfM?81xhMZjz>?xEDXJhH`$uw;^fS?KVM<7K?(n1iNX@c$<8m)sa+zQk6k8n0ZnN|y--PJV35$d2DAg5dHrzTs) zNJ)D^_4JfxAikaO2R&Yu=!MyAeYkCGN0+W6?ev#=XhQ!+8q+Nrw56cnYGwSDs`K83$t@T@BB3{%VWfZ z1m|F{?F~2kc{lnZ*U^E!V~L2QIE&;Il4nwvjG=PnL`36aO0cVWB_g3EM=IR7MOxJE ziE_=^%12g&t+1aNW;fy7137^jrNIGE^hDU~B|{AAfv?SXS(DuM9FU!Nru9c^L_o@9 z%T^b%jh^u+*_11(25lEzY#I1higZu0SO$5^w)VntEoK=lBY_QJtf9X5#no#ApmMb) zIMl=_l`3?a)%&HKY}F@kF)0>iTm~}vqpzl+#k>@%q|8imx3@(|9@Ig5PIClvTf!e2 zjK0`Yw&yuzYs6`ksz1{o9npS&{)FPeO7a?+9>!n zh(jnO-Q0adxXn&n_g^!sSNoC^J|7f9V3`Lca~D!57=^g-)1-5r21PkkD9S09T#s@J2C-$38TPs#F#me*xsYv=nFqmC4Bm#_q4s?E&=*); z<&_^=8TS}fPUoI+K*gnvAQ=8cpn`6o>hBu}9sBmZc@)cwY%@!&gFqY^ZZ!J%EPNHe zC6vRSUD=1AM@9TQLY2t_&72zV<7t>9ncA)G&6J{Y*Zd>OM`2A9@Kuprr1_!Yj zdBi=yZwLO1_$54Dko7ko2zA@0GU1`c|27_p;bY8?w32)SpU{@wx9w0$6znC&cB1Fn zb#Fb~ZNbL~`!>!E^ksGz`vd{r`cndtMW9u1^KMZ7p(JA1{c)S~V1W7Wl|}DcfXAqn z|Hi2CvT*;|B^wbUt`VIy35{R1T}j&~XO;@po&l%Xval0HO5z14&;d}8`h5U^ z#U2S=6^qm#uU@%QaStC*jlXuC%6HKS0%5$#tJUj*PrufW&>Nvk7yrG~gimgOTMmn& zH)J?hLn)cEM9RBbM@T=|e728EoBQlo0;?ZLO#h!2Z(XQJydV#rcR1SyxPgBhJzga^ zdQG%{JNo~*KRo*I_)i6%^3WoMp70inAd{=oZ#2WKppgcl+U_5b(iGC^1IHfpa6NSf zhqf-=r4RRSR#!+G?;kdofrb@~(Dh9ToWH9(|LI4K*W{Ihb8kLtbu!ZpUZ{D#=|}(X zgRM=Ra0!fY%2@L;c!S@!vg9Np?VJ65X8xN+^?b8p zkSxjzt;U&CF4jFumJB;;Ku?(<589I^+Md$mKaE!pK`>C}K@iOUhh?&RGZxR=TbyaN zRGHpWTrDd1pN9qA;7W9&k$9r36S%xa+mZdKi(+%1hz&vu+^vTq^&6;Xws|~W7B`Q% zz}HQ0evfsxWXeazW0KI$bRIUCL;)evw)ooBzlm3g9e3;3JAn0rX1Wip8fU2P?9S)A zWO{>51`h(TrnipsWOuMH=2kZb8@i zn%kwFxa+MMs;JS4RVno8&!5J87$l&l?FQ7faxMKLmyVxLY}=Kr=}$2+M&7IeZNe*3 zE63}%BkjCDZUcchyuJNye3Xtt)IZv0D+aOh0WU^_=(1Lb9qcrn!?+57Ej6q4hG?=(bYcf$tHgjtHPOvavr~Y zl5j6Rb&$D&jv7OlgXiE6`Ym&X#(Qin2WnZG@HAN7Gt~Ua--IlQlJHlEKodDn6XZNi zsfYuyWp%OYQY*nQ>=#vMAD;$$M3^gnN@jm=(w8~esqcwVR_Ue^V_SbaG58Z<5(>JT zDN)dkHvf+xI2a@V-;ZRK50AM7Zj_0081{pV#FniLgn7%83ie%IthXt4*l_z_ks@38 z`l25sD21~Lhd^lWW7gzHzA>aBlj3(+p`LV~LGQcLk9?Nb9=bBXNt@sL3?Kgz^6J1l z1Rq@AHgO8vV+JujM1Tc6Z;p63E$!fhr~qJ%^MqHfUKLTwl6yo|o6_=#P)&FcWr)A+ z)-WF7xVv$S|0#jmoBM1}q*4Cdw5vCR821Cxg|(oMxe;9OD%kUc^iI>N3wkf;C|079$Tys!%1M4i$ALRxNclJNTnlLBej?Xt->*Kh=O53S2gIblDa*4&G;M z8ORIu!fOV?+=ri~4T;)Xa9miRxX61If2J}>pnXAF`tg3?FYVlIgpHDVabj}zd5wAc zdgAx%(hZ|F%pB+c*hQ%)k)Ytz+s~3O7bPEH0IHnr6y8V=Ra}q|3b<_Bw(tDP)sPg* zD4?0_@2#h1aT>TVuP?PA#T~DER;u%#@-_te&)mu*QzE?fL|hOIe&inS zYk1omjHE6qd=TFvP5dQr{D`BVv_1)3$U!fdUW-sFBWWbSi8)F<39p&e zjMt1MkhaY)$AP`X0Dhq_9iIyR17=ElObh{N+WBVDNnd*Z#l5cqXLAq}$5RkYFpZhF zqBW9qF4UQ`ZAw77e>aJj$FSVcbJKf)m4BIhbm{>A;u-t7Z`D0nT}1}ntqfbBq`(jH zque&CbL%v&$0*KHLmW6rMEkL26Wzs9D|a)dRD@m%uS|clf@z*kX6qU?y_|g<@a&y_ z;=pG%Y|XID^4VxiT&!aN&80sqqgw(}YnBf9w|QTQG{n6_wW|JHchFD~HCr>^AC1 zElR!IWw-L~i^yie-)j&utbS#G@?P8Nm0x_mZ0py_g~O^J6vVZeZ3G{XDD z{0w*PQZIQRinaV3Y{Ecsq|NtOCqHS9$mkxL$sfgPk(WUI$XJ3_Tb<6W6LBb8hpLCs za%baZ-wv+FCvN*CX*QbOge{R&u-k3Yy0~-DE2GUyL`EG*l%MG9>FIfUR+8@zvj}%} z3eNZQhD|U2mq;Zq5HzIut-lc1_e_L4+&uCa4Z=y|dpM_nq$`gSXSf`>xUSNYXA(0K z!3fePmOK6RAPX*&=k@U?bay$Sx80kTi6|*k+J@(XzuIxo@p0V&C!SsrR zd@s&5H*qpt9T*4ABps7*e(=Xg$oLTzm#_2_+5!5k>0$Qj{JKhy_VwEKuRCObJXD(4 zMkMX}r;?MQ0Y>V{px?x|o(1Y1+1pRzD?ttI*<~4r3xQx|kWm2BX`_IIF$sL5L8A{F zIy^MIcloZaEU|`k0;vqqeZ5940azfO*GAm)H_8#*QV;j}u?&4* z%ywMFqu{@85U(O^M{vkSVDuFH%+tAh z(QuCl6ANI>c@I#B>c#A=7;odnm1?T(O%}B7vIXvGK^N+Jy3WoMbOf(iomp1g^Lgy8 zdVTNZb1TbG@JnFr(3_1l^C6J5pbEWNJRZ(VLvQw9n9QgD0h7TCf&a1)B~aI7yLRgj z2L+0SUGs#?Cpje42bU@q)2*(5q{zy!q;MSTdqyL%m*|62zurL8m`LzccdcXvbkF)h z%}5^NAQl*_>Qx3zaJSBV8Q>LBU+dZ>(8%hw8g4vBEuDgU&{HXpCBGyyX4_Wo3498g zSJxwqU}LK<9;=-uxiekKJg_pG?aL=aermBLd0^I)_zt4Mbocz7BeloJl8X>7F++mB@SR`;`l+!)fp6DDwPoh%K`%&8`gW zMQEIw4oGS&Ta}fvmMuh82bKktm7f*Rd=?_0?-zfBP}M3xthy}}D<7^+x!wPgo9dp! zrB|Jnh2l{>ADL+Rt!dM9csF?-k{54LveTR|CNUw966%f^CYfSjNbLoVNdc)mnUHB~A`r@$J>_t8=gFxG~e%GGHM` zL61w{lTH|7nyMU#UqUy6syT)ct3ryFJ&k(9f|FecD-C;Mi20v%sj>qsEE?y`=02WU5U2^|xFmt)=sC~zd% zf&O>IxX&aqX$8cJ5lhcnmn3)awI}yg2ly$S1Pu|Rm&85qVUJt&wvPJXO)mfkWZAUq zruWw>q`+c+_WdFF=QSgggH>=!|Mld{2zE|FAkS4mP_vPw;+Cyw*1(7DK$f)I?yK9m zvOw08B*P%^ZTZUR^;0uFetu466%=mw;hp97v(Vx7qkCS$0|=e?|MCErzT=8&GjtvK zD$k~gJ@t*IQl4e!6C_-(@Y-W|iFU$PIAg7}p?f5M(8$`jonmm|+(mD0^d{51 z&(TV=l=A=ASuHn{fT5l)zE57fFPo*yHdxC8VX6CYc%Rl05Rvu-`6&xZ$Vb=)`g3Rt zDpv%6)jsbo%tw5e&Hftueoti>xah<^=Yd(}Spa zlW4gCUc-t8#RI6j@sIOfvK8G?gUx%oRSd32 zGXJ{k<{vS!&cX^{C3$M;8OgRo^C-qgZOZbOc zl9%a1sA?Fs-zbNGA^9R#I=!(;2u}pBD!1@lt6esZj({EYyz~Z!lAzC*I|K=Q-s9g# z+dxy$w2qDDL|qv{q8wPP^6P_KU%{UE8^R1on+nvU0--?87fGOHZwiIULm8BUXTPg-ySvYEw?OEbzaXkw_y zIF0-5a=uwl-?hrKg;9Ho6*8x)s~uQ@aU_L~%Fj=HH{d*BJJC%h^Ynob2+<3&l@n@F zJ1I;nVFKX+y%>4u=!nwGb--nB(~MD(K*8i<_IBvB7Z)d*9cf|JcbW+R4PrIWhrD5< zTHA5_Wbtcd5tc-Hlm46@6dL{tIj~Qe;GPdx{4$t-xQ+5B*fJ-s>=Nzn4uN}h`lQxl z?YgL=_0*61dvYj3(Vd(mpp~XMddc<9WGU+xoPk%@$yw9|KMfvinFlK z*JAe@hZ002Y4g;NW>&w`6JF(twfphF5@oe&%3ym26HoD>T;CUIUpeiYz{e@*pn7R$ zfnKIbZKT)2OIogEP}#gaSSL5wP`#k*`}&EG8ARMW-H^J?b`Ycja{NBlr)vG)LOo5F zd5EqOJl+%s!Cz6|)5z@8po%}fkokw%5Bw(K?|zmcD3(u@cUuB*RCA_l6|6)fVn&=k zBEA3(;dGER$ez5*bgnoiQ(h6v(=WUK0ao5UN_Kz@8bKTu)UQlN+-PM!HVZEw- zwKvtuQ2k1~BBh%oLT>Iet^*Q1?~s!^`P)Z4i=sVU)4_t;JKn@7M~K#@n>Cb}=Agw8 zCPN0P`TY$Jg!q}L=W24%@D3iY9*M;Zw*T5f0~vTPT^R51D`5T=c$}hvS*ynSG!xB) zd>PP0RqDB$DTl%ze=(&lb$#|iy431tY^5(u))=2!O7IP&YT{w^^mQsU7<9wR^Clj? z<#qV2`P8+{Hxs&Vj7Ogf^gevJ4|lGcmVj7tH#ioe2MX&JMh|VA*QSM`Y%v1#9A|;C zg&SfcTOP<|2vmT++WRDXA}<%ZD;>j&dR-@ZXWn*E+WVl%V#ZY7Qe<(#)}}$9FMpm+ zS64*3uwnUEgQI~loX!}SED+0n;no&3TiA*eE0(aaNYlp-bJIiBJkdT(G2&?5nfUp5 z2u?b1NkJu;pGNgB0d{Jof z0VFxVzG&3ivl)%0I3Yw-#9`X=q8mnDgNhq^oKFxzihCIN&L?uG9WCG1S={OA*KZmQ z?ECAr#1-MSj+rQK{YR|7;>=X_fvmr@`Pl1qi6al!#=rnP9Dgu!B>!fg?(@F;m5BKoWNJ${emgn0nzaS~kQrz6p`2R}H^ zh3RO{$!1u5DfwZw5)hz%;C>U+QzBT;3kA3%$hL`xqrqwVq?`Wz^Q;$@WKF~jmu?on z4U;^I0Iri(gb4{uXP4W6TH6^Pk&sGylfU!t&j_ghMUw$NabN zqAdZ1nA{D_`XB+)O$33gws&_Nr*GAc&%WsX$ub2@Ze9WTC|a-;Ch6+8k~*$;a8q|& zY*2JA<0y=5u0N-?=k5h240LDspZsc!r@A~HLQX)zb;AkxH;U#u&IN*su*bRQyoL|! zlE*rdiZ2Uv6G04-APy9M!`etWD^o8@UYD6Tf9p$Ke;&BbeB?%s{c+mZsU@2}SafvM zhznS>b5iTvlz4}`ud`(HL->NwHUEJj2+JvJjm)jPAp5>Y5hNQX)cky)GW3)>>WJ4? z@67}2f11FsJTTzwixW`~RLq}!kP#ayuYeNEC)!4k10%E<*ql^SZH%k2`HWD#s@9M%KsX)fJuSU%OtdKlz01x zai?9Yq+FrtfTGeBftPp<`KPYV)t1g4r>=nFR?@|E!WqSXP&+bUac}yRXc4M1O4-2( zAmW}-z*K7AEV_nfTXMGzu-#>A3Yvqzc~w3&`RVI1tHIdlGLZR56T5`xw+Isp&(x_S zfi39rj~QNdPVu0+kPOv`p=+h6JB}B1$GOpEJNuGZBwarGg~DFKRL@1^C}7lR7K031 z+d^`E=%DlQGz zgXV0j7C!$)rCuvdZ0}t*gd%w&-Lf*4ARWp?ww8w3u?`;KbXcm&!>wwWR9<*Qcp+A*TDu9qRzmcwEw*!3xKQYR8^s)B4K$ z#ku1-b(s_Hb-}`XQrH&+qgeUE6t6Xbn!7|~6~v&j5K{T<+V!NhRYMv7$J{!|#Hit8 zfPnQF;QV{L6ydKiDY38|g6#TvIk^&43M=Ff=iBl_G!o9&RD|e$Ps^CsfLi-?68`Ir zDu<&U5OL^Q2RsfIWYKo2+5cB~?g^M0OJK#bp+BOXjC*X#-<^)V`cOL;@l!S9=8yZc zL$|4v*JO4}TF!T^4bFM98HMZX+6*tt0lWNguEWejmzVEQK{ypV-e%iT3Uc>1E-KnP zzO74iIzx5Q5sEoQFVy4ez>OZ^2+Nvkof=A3i!(jG?dYO@wS4ZNKos|OJ{d4}KtCgv z#;40}!ua@h=X!iQEZ=e}XD})#Sl%LM!X27^E84M-qMUa~EswfD1gHkwEj}|i`@u%x z!BSiCEqW6qw;?ujm>cC{rRL#&^nF<%Pstb$)&GtXK(f1t9Ozw}cp}_}+qyO=HCdpO zJk|GE-fFz_ko`bZ5Xd^8XkQ`4x z6c5BU1HH;#rDH2Awx@=gnX$68M*Hthyxy;su;t{yLEFPzlS>3fvs7#v_AOG zK)o~OwKuQGPKMgE7f)C`t!(E#!RqN-!yJ$dZ`WI|{3LTsp@lxBr@kSiG_N_?hd(b} z(^N6^0^`#yaIHwhBk_c6w}WWD7i%%xYm+{L>bU`?WE9vn9jQRtY3;LI+u>&g;a-{A4%&FwmM2zD#!-;$JHXx2xR*eA@8E&_*@ z5OG+q5xA_3xmXPbXuU8kbe!|g9{gUKKmtUxr%*+IAhS+T_C!u4-hF)wP9*B{*lOfA zX@Is=G@KxjDQSAMlNOQRm8YTgHdpuFD%NSo2%2PvJr&iAPpT)4$Yep>mZm7mS zy@e8p?|)n=Shc@#Ck!X7)5nX+FJUBy{8t#sVRZQB(UD38R;{dB4ab4tQ7elThv4I{ zfUr^vY0x+uK0hH;Md3(23P%RdcBbsmE={oQ2!OL#3RWK}GPcuRQ!BS;Iu11Lmux6v zW+V(9i*N|W$`g|FAPi?SHOIn4Le*iAru=Vc?0c05} z-p~rLEP3va(LZlMfb{cIbmKeaten(?f_Khux3-tR$Z!7qN}5p?@n;^ee9l4_@%z>T z%`{}$A}9&TC3}33S7ZC!m<27|2ze;x|H!p`98z^4mIU{COBXMMQk5c3Sp%D5BxLRX-L`EYio_b0R;|I!I`idl!uplYntzV^S{-0?Z6LB3$Ixpz+0H%w+I?d_HQs z9ycmpqdvuNC<@ghnOaMWYfQ6$Cfv@Z^IukK$!7BW)KV`0 zD;RGS3Gedb82(}sO9u2qWYLn9o@7HI22ctuUd0?gM+-C2LHYpZ6 zD*pJSCOooa_3vPvEF!tN?EJR?e-j4ABB1?lx}F3~*71J{lXd18RTjStPJRm)sZAUy zoHQt>+Fbl)avbORw*@D)fGhB$9nH*}X$dS}e&TnwBb~!mX

    #I#=ET6*`j1(B(^G zeYv)4_RIM0YqtIjw!@y;VB0Of1-tJ#tcY3Z0EHR@i)Ihrn`lc={6FrKj!Lfk@bUnw{ot$bwVBo&JZEE|B!&9V?RMgS z@?A7xBF_{>CTBwna6Y2GQDoGm&DElQ$sf!EL`;ON4vOAs{I(1D*jLI_po>G5_hzR! z8j$ABoBJ{ehVi+&l73!v)_JW&XR>1KNWd<9_|M~oIS2MjBk(KGo(|!~0g)T^^i@Jq z-)YcthezZ8Z5!T8b2a5n$qY2cMcsCqKlDF6c%`lz$<<*|_a@6wACoX|OzAUf3mPql%57;PiRPK|TL&K9lZkCb$#aCv$GZ$GH%pQwc zS*eU{c&K08QXcT^AX-K|1GDL@5R%U`s8l#mN2Ab2&z6-uW zGaEZ88{uZ7>2RoZ@m9J+;zeGAI6|J;v9k6XE}*X#K_$8jF# zanQy7QFq*z;Y0yGOX`oN7L7}R?CsSE#}V&nLx3iA*-G_AyT0Nyeh<-75$=-}RsK-gp2FM+*m@UKMu6 z8wTDDaIDlAo%);-7LSTB>23Y9{fLl9_#?xA!XN*KcysRy!(-$2uW#oy+p)$nHEe%H z(p3h9xsCpcslqeSYsc7L)-SH|7$t2)0!6eW@nJtB+m!h3S1mxt@?o2S^R-cvj))8r-1!0Gz7uSYhrJ1Znd zHzcWJ)@vv8_Z;ioWvuO($T?+vSoLPY=T7{H*G?BM_MIJo#OgsnhbL5eyQmR{S+L2= zb?oe&fZqEQsM40*vo4tmN{A_i_R}sZ@y3b1sQ)vpP7dQ<$F8bf5AP62H_KjfgTNuy$sN6BO!RGf;HMO%1$$S;tN=> zG9@qqP>|<9c5^^Tn_@-Nok}O~2v*g40M&=L^JWtn5(eZA-S>|X{_)O+wa^{#J@NM) z_zUQf`Hw(PPNhxs^LplUkHTO+;PPv)41gK{Ck`ktoQ9`UM?v#+FQ+EfgzIYQytc)a zjFi%^71lCl@3YBkT@a2p@GbBFV(hK5GPyn<88cC|Y~tXRW6Y7CV|* z`R-Hji1)e2O-zU$1gw3H@%x*9qdCuzlS`hwtX%jwVk8Hg#2?T|YU(%kUoP>RPDZi| z72!wSf3?Z!h_G5-|3_o@zrZ>5A?$PC5oR!tfbY^Wsk*ab57_GpFpX@_EAPH#jM$fO zI{LeH@zp-(vulM$k4!6t2nNxhBb4s$uQ-5Q=sfoQzFt^IT;%I$LsLS~?X*@#n4}mJ zboibt(jf1F__2Izzga*R(n#YF{Fg%jSCJbbxle*=q7^N-k7dwx{v+(xp_+l_*}si* z0F&F|BUT|B0nL`ium^Pf#sPVjoz3mWuxri(8}|n?ux=|>q7%taK4i|FG~0(L%rK!8 z6!rkk;3m=^c8&x+XMm%HVOf|QEh{EhsB^RY5J16mucqp*39d$Uq~OKtx@Thvs+%O^ zCsE3cUNcy=>e z5*(&|{)#v#_EdtQ$q_8&A3^6|h06nah1RQ9F!uwA28k&jueA{xQ80%P=m2p^Z7F+^dX#f~V~;8?W;%wg8G!p<5rX(iCNE4b5*q*mrTL z#BwAqk;k-b?=_|{3|#Ju_5(4f(jvQu%CdbQ@nsqD9hHr%;|yP{&+eW04G7(MXxpd! zHeo!AaZltp^Y|89_rq<7t1bYvSc@^k&B@JdMCkkPn%DacB8LV4r=I)txNM}?)|Aow zM@o$=Y?}!?n@V6d@;vddY~&#pQBRmQhCFdAKOr00nEv$)?QPCD+f5Q%{czhD;g{zw zqW3U4Vq!b7XGLN=xpCDzUT3F9+PJMjseJzfXjo$42kLqP=ze8D4Rl4-@K;or;J91% z(?-`71H`hu^DP@3NV(&}yhW{(!7YbOT@1?lBNPB2Ohy8J((*yz(!ah7f|H0a3ilOC zSpq0_e^7=0!GzLT@-3K1ZFlSgxmXy5HKZnZ-j4eTLK>$8OdD%8{h3qe z>lZ@^M6nuSoCY5c;6U*Z!V zJxU@Ae)rvUBVoo^4+LdOe%`Ui9e}WYIFGWe9Pr~b;`n7Fk6d$3!PkPn0;LSdzD5#- z1w_N>L&h16M-f*k(*DlB7jt#*S=Be+J~*l%3X_hJ55zo?ptwaF*7QPH6)bWvgMbq% zsf$gpXam_>6y0=l56PSRw6?c5tdT4Y^2bRGYoOBAKe3~{u{aA?UKPlNY8&QW^dk3U z`aC!8BCk*Pxlc4HDj-F9L43=^2$aT>gakT~1R{`Rg=Xw~#0<;&NrZctXbkMN8Xd1? zgE~9NRKL5^TXM;Bbzr|J{Hl>Rxy=#CW#?^S-)*U-=C9rbdf}82oj>X+@LEXXat)4>`%FLqqwq4FA9bY)0Ys!{w@v4#m$9;9l_|O7?-+sBg6KQUgO?s{i8rtShqWdx)^oUCq?-v-#C!5FB{rta4a z3+`NX0S!C;4hP{!X6`^1=ABBZAp2@&4FewJuO8#@)l6aMFcLO}eGX=}*n4v0j&rLX z@cZUll^A0x1VAR9zdYK&G3M%yo>ehxN8tv`acL(vo-ri`hsgA^?#jXzU8Ua9r>?%1 zCu3FBKW_vvuZ@R~@&cuKYjN;}&FfM6x@!krR=$uwgI*nNlpjw_!@Dtrr6NQ#dM|?F zT$HX4hb8hCd3g!E{6!?_+9{01<8Ur!akNmv5#Vt`)Mq^sx)u3HMY4*=vSBLnkI4hV z33HhUwL-*kB50+3B+>skKjloqa&TUAT#^_6?6;g-BYkeOLQ5bY!n7`LNMbNfekK6f zIf45^KcmBbs=Ib@kY2pY{Vb(t0tkQWEcAbIp%z-^+V|fVogXvLEEp(3Q{%nukfi`3hGYT_WZw zy)MT{m)R;mrF5K*y0s;U@@L>_>+ZbtO_-RS9f+*u*CTrc`}r8l47^(q^0NmchBNO# zZWjg>^Dy3iv5?@oUPrguTKSmJK9;#}ZfDA9Cj$1qpILzl4jWI|V#HOWR3j2&^KbH@ zsF;07D#boqx)7orJCJcrdVM^JHnT=tisZh?=g9R5OOH|JP;e0d!K0XybOmk9T%PL^ zsD9#qP_GzV;bp~ zX74|Ge&b}=1|$PpFOs9bu-C5$du_r;&O!pQ0t>F$6pw)L<9}hVU34$;Z@lYfG9RFM zFJU48({3`>eT=*Q9AC(kKziFqg3|22zVVlYTK4-1%?c0niYhn}1UimekpiPBo}-OH z#j14f+!`njH%-+t1>rUaxI0zoTw8}gC|kg2iIl{#6l57qg%6KmmM=kRoGrXQRTLsR zdNfxxKwF~%mUXUV7LU@|op&+^A-iklPBdj{@9*0+izK614>PNEL429 zRN!>ak355S#(~FaOynle2svlBN5irjht2i$_9p+*e}pt>Dd*3LO**pD#>>Oo=#zMy>Vmp#aWaJYj9AT znwi68!{*iB1CsNtV*C#V>^uB)E+*@W? z;t33{OW#VImx!k%f_Xr>gZ$BC7YuwN&PdViSNM^L`&_HnZdUs=TK_a-`I@WDxh7un zS`WCp#TBrKfD$qjo<3lTfV(CrjU-y+Mw7RuwMcvGR>4-_$qTCzj!bVclm;ni7$3vW z`@%FTK?M?*FC#(9-&_cwctLp$+}eMV((xz@B#PE93nn=)tz{I8>TZ)MK4iq*f`-$! zo+I^{D%dv`yF>kH`}L}s@1DKkvPYcE6`iEOV`|M4Cn zaqA6dCD#`xn1NO&Fa`{8WVqprduv_WxvLKThT0mEaL+aSe0B`&7)@nW^u<~#%kO1T zzoIakA%1`S#a0~DNBG|AS+wg85cgv2Jd$=`iB>I5k;l9ei5;FYe+ObM+HAJEPeJ?c z#gE4v7dDarBRQpm38AZRHMkf{7OGvtpwMa{1uZk>!8io1A%xww@L7{-b9-}Ie5=&)3s@1;9b~bhmq`(c?^K2Q)#h3^u>&lVfjJBNLE zqt}qof1GddgqjaDMjhBMBo7?%__|n&TRr)Z{q{@o zn$01`9p0^}+&8i;HM1pCnNNI)X`b`*c$So_zf?IkvGCUNjb+m3%x#bMB^$Z(U?IgT zKJ@HZ^47qY&*_YxbaoL%1lmw`#h>J|rU?A+n)9 z`6NO2()5|6)C*5lsOlS(ZYe26&O^`iC&Syj^fUs7#qj6r#U4p>)Ha0GB=roW0sIHk%4s9DWt`@30%aP^Cbd^PMLJKb$_ zfZJl;__4<_1qitHPRRG0XZe>;Yz4B#2hb|CUJqCx7AA=q4>??O-0e;K)3w*{?}Hgz zH-W_B1HbEnnlF{Wqp~T4(Y5^g`v;mu3Pw{o*8Nf(S{McMXd;iK^78Y24A)yLKfuD3 zN3!?SXH-=I?A}P_Q6R*Uet zx-@BbGH^ou*KO3lW*QuGHC%e`r!9CS#h*r6o9~zx6wZXl)p9|%i?zX6kmzM)lE-@8 z6eU|7s|inp?+z_ZB`vQpfh}+hRd7Xic;!;>X%I=t-oVdpW)EKQ7-MiL*D&geTNXG! z){>w%wZD1%v*yxR#Ja3NfxNW71!%*M%0GvsXPiN&8?$h3<|U!Q;B!F~bXf6?#8sG# zo`iIjj%Rplv!w-ZN$AZHO z-$Qn%9vgpfY4{}Q!8Q|Z6MkcN>Sx)9gfTL~<&LvIe|WZg!6?45nW@=|L;X7lT?Y{I zEf#@3j2f9@6|+H!JzuBbQH(dGlcqdz`PQ;t?nY3&F0g*{n1lS3V;N*{VBgZB&Ux*# zD7@Ph=Ze)qVl4qlLFXhXsAX-R`<7=KmWdsqZwXc>Q>-W%E4=&ttSD^b%Fpz$;ULaO z$GG8&*>t9b0@^_Ph*p?;=$N68laSJav5d>jpKXlEXg;>NEC}Vf@(UqE;s@o7Ahn%7rljRd#|nQPYoQF@7lEQ zj0)y1sm*KM73OCa8|T`n*vUv|`ke2UUoob_*af`7nu=+pb%kx>C=@_T@0<l~+1a(WvU=d+zytnw!*PXsg&YZkWvmVY-rUMmdK@7qFoRiZ1rqBq#0%kYDOio5LRTo*sW&2lkz8qT_RI&a)-e# zqH}T{!oCVL6HRNrG=}WpjeB;i#IBmwEcQk-^G?fkzg*%VKT>=D{gOT6FUBoN%Eqlu zg9VnbY>4>@(zk_xCT9yjns~AP0@#}j8~A1u6CR{qb`_D01Q!?oM}oEQzMqfl?BOXitY3@P22$f#8O~1!V%mL8PG60oni{@T&ErjAA-RI|1tq<4{ zY&i^nSPqFY)ZTlPZoLIx6IwSKy)!=VYOxA z1$0FCuIf|Hr-?zHgFRl`3yi3f9LKSVg%CW4;=F>pf!ABYPv#gW~feP z(uz^E-CF9bxkH&zDM|QtNGO2cW>CQb^xitGdQY6pl8sb&)X$LYJoUD4I1`Jj=anMy z8b2)Vdg$2M3-)7_JW404#|~r0tW< zk2i*}*Oh&31RF;RG|0$_U&J?izmWn>gg)wq{2TiC3ymYi{MG*p-01ZkZs4gn;;~S? zp|%PH{QOubwNupdn2=OAbF19(7>;B?zhRXd&AeWkTKGnRj9*A>B2Fk7X z1MSR<YBvo#C? zN+Nr=0Y%#RQFBqAyZ*&r1X2i1dk!7(?g7e2#CNXBEj;K8*s}QzUHnwk7J*#2B@;)O zf5H~=k)1mef6#5bnec-OPz#5v2+j5H-OyiU_;H2Sn8}b6Ai*H;+tID%Z z#HNP+^ts&@^EEOPIN-L^IW>NhzSa>)+$u|){5eqUO9Sr(f%UBRTP7b9*X;*Tpq!G}^xbfw4c6-eHp z${IAkBhm*CV~U*eoDne6%%U!h%kn2>jG~0yJwZ>l01P&($9lKGS-Y9ZwAe z>JzZe@0oVnYM&MbpC^y(5t4(zH*Rn2q)s{Dot(gO(;dfDPh;dxK8h<(AdJZ@U%w6A zUY*OxQ{6^*L72~va*69-%03*agQZ$2{%4pF(WV^K1Ah>W~UL@?H>G=C6g2YrH**? z_Y|xKMh+VqnL-xZhPN{JIV%1S1phzpJmMLMr)eLsTUTrq^f+`Hn6{N@Kg2z1dwq#( zVI7LLh_iRQePl5EwDMX!44ed7D;4tOA0DmP*~W5k0(435vDiv6^Bg+^eXN2!5l}Qq z_KAU&GXoONG$$H`i*srf^PYMoaqD&%THsAI&{))W(r@J($8k23TNaX#J|Hk;N(5A@Z*xI_=*|C=XhiH$&RM>Tl&WODBfHw?Q^Z~7- zEP0yn*<<{aR6M*{^61Pz-)tDdHE#Y#bQ|6*7$!XhnrF=UDJ%ApW3`Zs8mDSC1I6!Q zu#d+xPq-F2WoGXqgy?hz*6sxE#%c!O&L(0Xj3;6vF2qZ8#VTzlZcT9 z0rM%wKtoXH9n5t&u4G>~768@8GMzNd_xf4Dn;s82gNswYBfHO|eJAXM`~^LDvrcyq zMY`A%5!b;|{0tpMphSRJ>O1wnVrSu!;;Ei^0dIVfbzt_W;$ymvU zRw$BNdKCrJ5^Lamvca1_)YL25${Qh-+l&)lmw;(E=l60LkHQ;GhHkm}OjWs|+f4pD z(1NjRDjNzp6Y$Qoi7s~`G3Q(bz_6F|Z& z`kB85YY$HGUSCyiH7iq?(;i+RHQRT0^%0G?{y({v$Jd0_VHL-&Df}3|Vnn<0#8}~9 z=?%)p>7_3T@0Z70nH_xzqVR0!<>{Ep<2w~xE3*=@8SCPK4cyp9mpWYnTZJD0I)-s* zr}*F;ena?lt_*pUzyZ|btHzt$|H_8gb>}iwDDM^pF5V#vgQ%L6ZVxn zjdW+nO8Ju$0T|`S$Aqa#M2kYrtrKW75B;SDuo+6FU^9C#@dmX=QW;KVK+1D_&5Q#q z+{e|H>_!{I0gE|*Ql6v&w71xg4p{-)M0WxlAd3NYU}s$m+ z%Wzn&6qT=AUM(ZwK+bl#xpff2OmS0(T}AfV_+RQt#7wW3JY;v}F$jj5xxV=Ani$kd zxdNefT6ckhn3a4|9NdV9)zX34IPuuz2=Z z8gQ-XQLt^K>L8ESQn4> zvhu(R2)>DA^=Lvtr%;z5T`{o^!#Y9PLmpZ%6>$N2nA&&5m>2Gc=)G|x!3P}4@Qonq z1Lj-gNn@n!%?^+_n%|d^=cS`)jpIaGWi}5Eq0J#!hcY3mFegifhG4XBz0R2Kw#$Go z&4r3)MpQk5kXqmL2aGp)Z`=n4_g3CeIs_)9GqD;o)a?L1IY09RtjzvJHxYGbMY2qzczh7k3W9uaAcQtG`EY zr?!!YKP_3j!u;F$PA}N`Eghdlpf#wKq*e;oYVc{2K^Oty zV^;&$!!GC5FMJQgP3>dcXEFYW%3B|0-i*y2ys{^gI?B8vsH4PZ-fvUDGA$rsCHjbj z1dj{Bo;JV(zyBj+2<*X|MkoFg9x6*v?>JFC13OppD*v z2i$&+tg_|j@qQtwM3V_JtZiN`BjiBayD-iV2aMFGnrud)Q}>~qy7NiwQ1Bs)0yfo7 ztxApVNT3A&f+ZMbfJ+q1yQ_YkNJ<_!BK|YVLtl90&8`;xxN`XSGJ|ha-|I|0{tg|9 zk=0|vMJGo}g)o=fAgiA5er0l#+xvudNR$;%DSJ)omT;$2FinvP5^qEE=@*Ah@K4nR zzZGcmM^d$hMXV~RST@I|>FC9o@46-S6A@b>n8lx;XpEkb(%aHZ%<^($r}tT}Y@fWkG7t79m5A2#`Xr;fte1IEGv>ufP z8%}uxOLhgP@6M1|h&IiYUf_ihX?Ggb5I>e0TZAe=%Vrti?gA) z?m0jN>!0cxS~!{oj+Ec1A}odhmBJXK%eaXBqxFUdXlb2V73>ZhCG%vwEK+Vc9*)c1 z9#kjo^%zZgVPzZip&SSghW3YC&6(=T&aOA`k@Skl(!Cvm)^f_ZCQH0oM7$iFVNXPcepQ{LLa4E;V0LnVmC~+)zPyK0I&d)W(g8 z!BQ#xYJXU>ytiNLc7@offuZ?7sE9V5nLVNdL#aqrdY5-82f~TD@dRR2ap!dEdRZqj zP7jY91zWAPYz`-bEzyhx0kf4Q^Rad8;jONBjQeGeNb5`p9ETsD`>h1}7iVi8KU+HZ zM-2u#MS1B`m7n!S0?R{T>1xY?2;}rO1e&gqt~Z?Qy=n$f`YHN*fCN2bQpgjY!n%E} zd=HS?2q4A$JMF!^&7x!UsC!X+$!yz6?erZ+#uur13{UsFFFZE?ISLX!k!XsbK`Rbm zUhk!_ymC`gi*)kQ~+h;FYA zsTDVm`B19!o_J_GQeOvZg93T&!~hUcl=(lO@KBdpGZvVIn4=2ggQSAG^kB4e1?Wz< zPjsw}==8Nr?<3mn}5MU@(7(__N3@Td&7v=+y!$$OM@-3{0G_B9^=! zP_se2u>sl&PO}7$f{n|x(E3c+Wqz&(lC24JcDAjGG=YRZFx_~PF*W-}KpbOylTX|~2|EOj zqe5~K7#MsV*7*M5lE@GNnQP0hl%49Ex8R*#B8-pCPb5fItA!62GeqPLN=G~dHeq#f zka!#7pD%+}X*;zD?xMEK#{hEEPSV*k=@Y5<{nYK%7PG=|A6jAVo>tg?PZm)RuKr$Z z)S9y4n?0aFj2SM|S{FxRc|O)m`|;QT)-LHZkvW!oFk3|bV;D*mVyVZzVO4fXQXwhllL)Z4cO$`ix>q1)95o)ok1p z+>QSAlZY?LHdX$tHdC?R3*+w@P{F7qvBe0w=^Lu=Lx8Y&=q4$hOe+IFvJ4V%?`0hV z_cf9iK{(sQ8-BoQe>Qci`cXInq~9FonMYcDR8e>)uCXZ|Yzxkqh9om+6 z0YGmA?1K155N!$yfp05DD$icbDak>cgM3)~P=PHTDn#cL%+34zsxQQF-gR3(E3oSF zCKg#lZ(4`Y8aeikrF6(+2Y0YD>;~sOar|j8lLzGvLO=8=H|j@ez)c6 zLt6>(ifq4J(lsfCv9i;fvfGhD;V2i<$9#3g`ZaOiAT;zbC zGAfFC)XnAZ)+t-y%f|`7EZ^naqM_I<6vQU!)~WA22Y*1d$OBv{vaO%F(1wU9j*4~^ zPug99C{!QG?71MWMmZdR)| z+|>J?yZ!TsAYTuoL;rR}@cKJwS?TE=p{3}fCB#A7Onr{}_ulVA!Y!gRdF^+;us7U- zqYY%`93}ni;;(a#Q~94Hm?@RR7+qP>-4`H7!HC!2{I&^aVfx1Z%T{#*{jiJ)F) zeUAuq^TZPUsiCE3r%gDXEzinriQ1iXx^%BEEskfViWJ6Qk@qgZl^6S=K%ga<#)nib zJJO$|exE!x=dcYmU(VN1wgA-aQ}SNPHC6K~A8U@Ytmi+HY|!#k5vU8Oh6%h(@2DnE ziTIUYA4veAkJwd*hd$dMJ}~6ICN;GwEjHNn{2W` zcy*TP3H4MI{hFIy{hV;EjbgpY#TSFdXw7Jvt8r83`lj2gYDQ-7p=#2GDCO{5A-h3) zTml-%x%&!K_!>q6UG#Dme4_L8R@ zXwIY}cDqAcBW9PX>B=hHtdTmlgh-fqDo$0qs!0>f09zstrxNj$sUC>q7t(56+u41^ z4wJM+g1(=M#Z4a3{{B3W77WaPCH%+8=6}(WZ*~vrHHkKeig@p9 ztaodRHSD-L6LZ&SbeDT9*t*wU2%7&(0cY63`#fV~#C|a+zN$^nIyq6?w_6MAVYG~U zTtJ!!guDm|k<=@W@Y&jPsZ3>SnH)w7t`EBse`=;GCtO^KN z7a4(q*0f4YA7!#&0A(~g+WGQ)`{XnUVZcJqN5ZflrqsZz1+h%pQb zZ9(V!+{{V-0E+ww|KJjVAXk=~HLLI%NaX{ry#n>x`S<%770$E=8+oq1(g#+?JPevX zy?Js~7JzoOA2pX}fl3%nW9a<;GHW|O3GbyhSNLvAW&v(3e<@A#L}trlyIWgZ&$i2c zE+8hbB=@*b$HncR;BE}VOel~p!u)%|TRd~+eF`dyp`}6U9YH1ERc5;L zM|$&kb@G^VnSuzf9(Vq+8()aqm3;=KpvL`HdM`CUX-;uH6#T?Vt1|*t&pe4)8f%^L%dES zE&d*bRMwu5H@Ua7ZTcb5m9lW*++A3sO-Mr0SCqR5O`*wa4h|>|4nZ?yUr+OGn3pN6< znKL~g({uk53>im&Ox)b!OBiH@ojD8E2cB1A2&G_U#LThSiN<|%uEz8@&e9d#em%he ziW!l6KkiEaOa4^YAa^H&986MJYR+|0>F(vEqp)QZBQ0|TI$9Brf3uK+EsShUzZJ7w z{#FCtM|AdqhjR2G_szo*t_KbqLrLL=@lf^SQwpzS=~w39R)B-or=DmESDd?7JE+>Q zL`F6L4P=lJMWXy=``_g+q=xz*mdvk@KJaZz-nx}CIVzevoOjfk^Jg241DP@_#Dny_ z?nWebp$y$G^>RL*nSc9${hjv9eR1x_`z1-l&=!2x9;hqe;))@%9kQOf;Y-J@DJ+!B z081Yr5L4wO+F`&fSoCA_^ri1+)CyhT$a?@ydxWMPL2xYF$B+Cb1Bz>r9NMSeT=@9=Pg8U$Diz^hxh0?A1z38;9qlj1Z5ce+l(sIGjW&Hc;V zOfOb=`kDj}(7@Ftmvo^1^Jx6(*9Y*F$3=K_hr|oUaUzq0^vHSMoah#SZq2L;MkxK1)<%$qyVXjrO1m+$dWuusG? zCDyY$ea=CFi{K)tf2#zY5ot#%#}Nu>1>pqJuzBwKn|xW}vIQCe0$76{`*t-OSrO|F z*gy!kh9Zx)FD)w{=v*cwd?Jzzpn1|PxuTDluyLxR8HB3p(p!ry`R3NsM!=mP@Ad>@ zfGJy``H9F+!8B&y3|KoX*3Sc}5y?N@h~5E0x-ty8KV&MpC1M@N4>N>guT1w>7y(uG zS@tQQQ+#=SNdTMgbLr9iAS^94W^V-aiGQ^c&?*UV<+w~X@_Q7iaCfL&1SQPtej5R? z?LazVbC~R~(dB!8kmQQ9C}y9p{n%3&nMu5H5$uNzJR@j3=*6~2VnoTMFtd&HBG`qf5qt2E z)E#^|r{*0WC)Tjqnk4_ky5*&}#OjZS7eRlfMTm#3`B?q|jB&?vNjFEr&+q_r&tZE6 z3Jz9auzH7%@-j^iLS_5GF)e^f0j*tKD63@(#+l{_&X^G*mfw`{yf5xH1?^}N#7{-9 z)UhRJ=t`48h5g1CpTYry<;1)7Ku_$QWCo%ne<`dwJ9I!?} zlrawz!1IZ6zK!|)UOTo5y1yKtqUdZ(!w2lJ z<-j|@?j-MVYN^C8^^X7ZlF&v+D%;M-V?ArzDWEX&ky-iJA8+XY-$rxxk0&FxdQ<)v zzI-;l@Wk%3So`k+2G)|c$#)?Lh$tDUL%hQ?3?25RlrMxpXO%Ur{yniuR3(!AhTI<1 z!?&x8tAW1G_z}ge*NFi+w`vZ`Mm~}Nl7El{5dLrM3qKK&{ehha8l_Xvh&o(3Z>)LZ z8cazukO8T{bP9$6fPXFSl5tG7R8m<0^+)s0%s7OpUt3D+9Bq!{f^i!umm6d+MW=7~ z7=gY_atb_>I}KPz*I?;@3%1M-a&?9&reA#ZA=6|@F>g%?XC84ifsWl}=&|sJ*ToM{ zLs1fSfbx{j(;euEVV|Tm+p>VBb+iJOXJP*M$f5wQ{UPyw1>*2;xWxBSwFY-EzOUix zpfLb&TJLmxpAds|ro(yp4SVw}G3Ih(VldFNh@OA{yQp9at3iV;n*TW1`b&EH0qc*= zn-;5KR&DQG9{P}a_C_S8eE!A$y~sVV)qW!zP!NzpIeOQ9Pq3~hXTDwm|6}R6vsas? z$6{B-FjRXuPJ!I4qV&k6P(-ZKcl<*Jegf+_(tMy|KYrnpXjlzpE(d%|e4BXOOTL`X z-KUFTq=rF!uo~)}a2$Z-g)<8{w zK-g2;Kx^m)xT-Ee#E!C`8li)LNg) z(&q0LX!dIHEjtlzm&eZ5$}6CAkGlWjXO(5oi`tDEU-_PWP|HvsbWAb3X~v3x3OE9w zri0=0EVxP6<_f-BJwZd9e20pbxLfv4r?#9Hp!(r*o$V0;n88nM1@FU+r)tSC&EnZT zU@Q4w***V*ltI+n?F+XBt#7>cd;=Rw>p>87^Ff?C^`L(lA^Uj54iTET14?F3?3cg2-+optD>$kd{ZVu?kujk@>(l=vcMUQ-A{E&;l|aTuPZP=5q;b_0<(|yG z*>o-4vwth4u7)KjAYD{JVf^Vk6q2@yYj(2~F3oK=03j17DaV1mSU10YbYg0{o z!{qmpxW7Te^e4ETjUoIvSCAzQGmCer*1z2j{^M{waW~iCapQ^S*r={x7()a%_j{lP zTiAr7FByiHOd|NG4ID@gdH9J1+hDM-7N?D57! zvU2}hWkq}m$$u5T3<3EsP2CV1GsWv))=6xKdRLyGBJMxV7Oiiub@{nA4d|4>(S4`- z`6EC?;46dRWkv)qlh=Z?WMt~C`H5p&Ua)kdxrV0i01pzEE!)n+4zMyXHmhEr!#%%2 zj6uL2276usXPk)5MHC3g8023IHxywcjT#U;BbC}U>76wV#2ovu9t7u?`{WZgjl&s~ zQ;O<@T7p+Dg2~kt`MP@^P*SylAwu>P;2fC}4;7~l5!ck0shw|FN|6_nJE232 z4ZO>}wecQJhF?=^DNY>l4ba?4kW=h>=NlQIaN=D`KyA4(P52os%SL%k;}z3UuL`r# zK3tjISdr6cyv=NJ)`IhJ{K8iJ?23EE=h-!v&3pX|3?~^q7Q^Mcs<D516 z_eAk+f*5cTSb9E_kPdLNfn#7gRrBSrbUcC98-^Ju_&Vrb$6cS^S-JT( zbXMC}3t|_gQNC_H%=Uc4|8ySv=?15HT~(P(vETn1B=<^X_;XGP@WH&AKrYhyQyf5^ zMgWd(T9$1h6{<}To2wAt<8@r>WWJ%r+ujnZa;BheZ{(DB z?FY;Oz=e3YAIdC|-TU-Xqn?0t@cEtXkOggQjKs!t?sB1vJ1kIkiP+f|%zt63hr!)R zNVtw}%^(x?^thy}NKb`H19iG#Sqb=F$pZ^%P;-nkdFbB5;9!gP6btd-Z@O;{%eo6F zgS$;o@PHsC@n1q)@e2hSjCp_)1k`K z%NX3!*?ny3_%R2t1y+gj`~%wj$>Y5hC7rQ2^VQ(k;!mE6NPepNjZT6?$Ir+fdFVZH z9AZZcQWgl7CsQ0dWAplCz#zc~);&be5Jq4T)y8uQl*4(V0%cEK{80&|+!A$`dD)v7 zKDE~pT4%#0+vvS3L5!W^=v3or^jmXbC!@tk>+fex|B!Au3h5ew%~@Z$@^J}gCXS2A z_t@L9kRTtX#pz6k!l_m_^xAUJ3(vs2ax2bMCpx~>tO3gwg_-0*_tW}Cny{ojssF~{ z^9x~(YXx^EG{-jY_}44wud0$Ez~4rW(X|~1%i@pdgz5*V^C?xJ7|P=xGq9WN%;JGM z^j^`<4H_t8bJFfbY$f&u!dSsvvEOs!tv#-%tNa?McyR)1;sBqj$ZaK)VE=yc9+V2S zP8{7}2D#b|&yF-iy$dy#Z^36(dmB!s*$tftOP>H0?Xrc)UQ>>xdVUeG93)(IDL-y>zir z!&iT<_egrRhN+GJV>dFgq=)S1cGgxZyJp^Px9qvgdhF6fQxKjSPY?isf6KR830)fs z#6{U=ss|>X@sCRH!==l+cl!r9bL-ET=73O{|Gl6LCZr|%3J8J)hDk|D`3(H9jbq8B z%?7nZBuLiRbj8SjN$=&D-q17w4oNta`x)AWp=oLC{%#PQaQEJFZ?Xnp9DQhot@LB( zYIKn{hD~4B5Wpe@_gmofo`Fr^cS5>THrtynHYUc{x`~fn>X(!h6qMmb<%@sWxCpdz z|I6`&K^^oR`qQNOT%mTms=;VyVdLetLFKyj-sP?D2^nWO35My@v}7{?&y&h4^Dv4B z4~RL1V7EWcHg6U@!L5AwJhSr1k^MT<>ycLsk}3l1ZV!od3ERD1&T}nWrz=kJTY=?` zdpC~*1Qx1XxgM(4@4gmpKiSeVmGrHGb(E1P*UbGKfAZtCKs!S(B8GKj7GH6dlkho_ z_boOJl~*Y|7Lup893wj3=yQ;R&a`(Wx-%k{O&8F|5x^gMwZ9KN1Q;X(1GGe;{osba zQ4i6ZzJ3rJ@aRz_U{(!qq3Nw)X6BU)8({_fy1xih04?8HNqYi9EXn{h(ARe;Msph= z)mxkTFEpD1X3f)@+aOy|3z%ll_F%;p&DvXrbT3Mst#6FYH-bQ4rtZN$zTIvc8~Smf z;B=`Y^Kn}fYbF7c|7FGF2?=?dWkF@RlT6lqrMByf7KQ6jI)&XGqqKYo3@mf3`;{zl zQ0syLU5?@H1XwqZ1QM8N{Z-?b(;&O2E(@B=GLo1T^o5x?SjOj+Yl{y!4oj8{NNBHze`< zqEPdXXEDnj@nF1-9w#&O5g#Wh6l`{cK5B6*hKZ{jGLDN|y%2tE0dNPCQR{p~7|~C|TucePUn*fmX-MXlVEVnkcPW zH88LrZ;^%d=uyoPdIdUh$2W`PtyKfZzZAOqiPr#U8V!VPi!Qy*@#q34Bo=n|+JWN^ zISx~o(;>^o+K%nX54qhtP3rLWff)Sm9G)oueOet&aEhYf$Gf{f(fGXUz3#+s+IST0 zYs{!9G{;M3>?@!@SY{8Cebul(4W8~N0K>o4NCvX4R0j$n=K$3W`~rZ+wj~IFd2r#N zBiMln=AhBk$Sf?<56*&?VlTPK-L;#lF=Iw8RtCHST zg_)EbATNPq=41Kdg-;-Om;WQ!qqw`+xTok@T*gep7DvEEn0;u;GM4eSLbsg^H)2`4 zqZ!Q-K{TP@X@-Fr?5~Yw%LlyPgppvf%}{j#+?9_jk6>W<=|F%x?EfPKR?I$0P7R!e zqZTLH#UsBPrID$knhmaN0Z$Z=&KrO~0=Lsw9L|yiTI7-c-Vn{B3ao90dVK>VU&?uxaWk98`zH%L5hAcD~^@ zk_FvHnwt#Xb~HTa>(=?C6YctnaxP|F?%|OsYA1zLZ;np=-A^$*C=4D(r+zBnU#C9E zlT6W9Jl=UQP~;;b>4Awy^@uuEXORiLtg_Y zUQ>1-RalPnNoM9(a27Fpjx75hOah5XnfcKsOQSb&84QAG7fj^F-b=-1pO16sX6nbD z-9DnA^-xzl@btAjWgW5)YtLW@290u?KV8dK*mof|G?0?59_GCx`lmSwT8r(*L`Gg; z2MD>_N)))NS@LBEcMj1B)+Sys@bUFM4@0t%M?UKVI%QTsep<2x_@z1Vk$^b*9 z()#mef42}st8Y;reN~0eqp1A!zE6y~vi(4`Te)R*y}Z~dTK`(UPDW;DhP8X)n&O%? zO?km1forxjp6A|;a!xJrnH@^My+%AiL<=a`GU+};uU&W?f}5a2THUlZOg1BCdxqDd z{dIUSmcsA|0|V=R&tq8*VUq2+5hv8@e4NgyYQwOX?-M_Npg)m*sqLj8NnH)BW%IYz zHeSKS6KB#uTA1}ZqXI|w6mx~VsM|&WeQAN>F{dQXvMsC4LwJdCq%eGDvG*scI=nv; zosO3_l5*c*cpEJ4g!|Z~#mwiCQSg=L0h>m=z7G4K76a$YR**dOuYsv`OYU8M{^;ju{o&(zGNA01U zKMR?H94K!4(@>FJ6!(vn^0@Y$quOOZ{Z!d)nx{~pU*Wl%09&4&j_IPVi)n8gT``V| zT3dSG5j^d=F(Z5xMy|02Iyx^PUnxTk{-%jRY7Ew+0b_Aw*QVjTkW~L=;~AUAaV_!J zXvu{5w5We#$JTAOBl*lh8C6hq9Q+h{M(^v0IKTb4=3RQuFpQ(J)w@2d(i<&jdmze($VNt+Z4Em_kQ_T}?%_vAc9@uyG2lf#IgNoPm}s~Dfq`W zy@IIMb}3Bo4Y>_Uj+lAksM9K|K#NPi4>u9Q{+d$gRKC35LI@qF4(0(H)Z@0!UlHd9 z1Rx#R7ltt~#lbl4)tVZg{MpGAlu=y7`2v(Kkeb+~rAcUv{g+l4 zmw<$GPNiM=53ryd)ZgX2Jn(k}Uzt}*1+?YnI8`iUm3v`A0C79Y@9VRuLH3DQ)n>9y zF!0gAC$Vb@5wUBf8;W;@N=M)JKT!d6%c|K`DOURFi2J^@J(0T$p4?c)W zHNs71b81HCr5yX@e*aH2gUZlXOUljg&%xrdsHB=P0w+O&)!!C2KRTkff$2G}iEH*f znAjLEsn?OoGsmz^p`bOee@Weyg7f0;llgw6;yRT{phiTBZ8F(HrnIo!#XU7m{Kbj| zLEUJdwEWv!J1V)W1$Sa#K)~9!(My6!JB(B%Kzzoc)MMfj(%46OGqSR>u7#{6&FdSX zlL1UB7}1HpE)u#;6)-POtgv4l-_S%$Fh`NI<7J>U0ua!wAH%%Ds2_bN^y!nDgOW3z z^1`$9TO)_oUK%xONHMZ%=^}Z=0iRx&gKTw*_462ymGb z>9PA!xm#;yDWtYm8PsH+7wipM@E|8Aj}UXXJ$ADz&*I5wHk2+R4$b>eq3Jk_X5iKV z)!ivj`T)z6dg_(ZY#UTn$m6%5U~(Af6cK0i&ieCf@TkX2aO@+dwl_a}tNPGgU2>`) zSM$un<>MB752`+*7rhAk7?b)`vrFLVoqyl&;MF2KL93oC-_uhdo8o#hdy~Ez?9-Ln z{3&0!M~If+xTS9ihVUwodL0sOZMk_)sR`Zg2y2QmcrqxivpS0KE=&5?p^(5W65l{U z__6bqZo^xMr!dTRe)^AL_D?Q+(e8^cU!Xk*htlRI=;;>iJddj=P(F!^dwQWOSfzZh zZzuSxyi$m2S3Qr#-itfgfUFCz?5_c!=)TMz0;`^)MBly+>HAC5b0y%}HpggB*J)kQf{^#fN)F*p^MKAp7f;pCe)5)UMWOab(k!{-I($My!!wvUPGb=`hAw%&Kf7 z%dm_SB}^pra4*LJ1BBL<#0 z)!Wl2D(J->FMvc^y01vbhE40c1!yxvm4t(&UFJax$LVeB+6(mT z40N!BFY>d`a&%%0TT8b+Q-X<{GMe8T^u5)IICAZLDXvGAluwj%78Q??WS3`FAHfo-tLm%v=|y zm)$Ifi_a}lmQU-Hfdr2m;)(U}yV<73{8^uSHpf1UY(KKxdN{a}N#^{~rQ;KqWSzYi*Bz^!cj7T}S~2$#5^wUg!8Dxf=y!vuWXv|8BsZBWXMGo-dhAwC4@?EbeTsjft*~H?YqY zb@a?`K1#5Fb7~q(k9TE!QdOL}T1d~%E(LI|8D8qO08Seu@(jRLsjp#qpY+Q++PMrk>HS~+@I~A{r_ZEf zPu#vLqg3S2%i!_i!iyWb^W$#VIxPh&;$MbyueAca)ez}NI!QZ#@88E5uCj;F*!*L7)#G!AQ3{vq8Z7#|o4O=oz5I17 zDhEk_I^dOC*axk)wuhaLYd7(cf({6E3nrLSpaUD7;2@D@Q}tE;|z(j!PZJ3JI(!(Yf7SWliVb z7_5YDHl1FIc>Nly&>4WRGC`~Y2xzQZKmiloJrg2pOl$<5)M?P1g&5FAvXQf79A?My z-j&uFs+=!|8ROK}BBon36#ODoBCc?$F1j1ewfaU?gw^kG2GHgbVFSOKICyDbnLl~7zo5B4UbJ-j!4svS@h#vwFDAm#jW|YN1 zxklV;`al@!ulaSQBczteI{$Xeqml@35E7uw-`pfyxXxbb>By6=2VB zF*m0#M{-gmwRwzRBXZ*uba{y{2ItrMh}`(YY1GGlCCX5U<3`C6*BCG2_NQ zXTO6&_Ol^{aDIzYh)}{?r&P|v`~($a>YPSzA|}DIHHB*wmk5|~iHR9OZWjgG9tJoN zJ0>BQ@ueec}h|kdba>IW_;u1wf7a7v$(jNWW+KtbQui1FikflguVwh&oQ~J5+n` z z?$%NLuWx7V!dV3}=2E^u{`FdQV~e!X^n~^4&HR_-a3%xnsLt30H)tmu0mtf&rC;}@ ztE~yxBpise+B-u;Gd@TWqNXqjI4J%r@K{lzNY^JJSpH%BcY)@@ZcpM>I=g!)0R&`| zm75Qv9i)pNlb2dweHT*5!QrlJL6UmqACh`ty-U3rmRv7lWPRm_q;9F+gTVjswc^5p)Bi zALn*8QDL&)a8nOU72+5hu8InuSXm9%G-=18uLeJ-XPWavJtA164dRsVb>jU};8$SA z6iq?C{~J<{zneJrbYF>c>~ zmt+su&-vwlHfT+2IF03pdC7_$y^a&Vn7~cD-i#S~IsMAX+{BOC*^N(f+V0|xYG+Z8 z8F2&BtCS5?-xmg6daAA9{UGi&K-NR(RLoTdc8>lG6dM8SB=Mof-*cgXd9JDC;Ww(g zpOf=N3yq8G<%;gZ_q@LCQaPUNx~x>owl>hdU2vp7xblb^XyT+bI@4wL=n;NZrCTBG zaDI7f7#Zca4QT(n*lVndGzu72<(}HRRHCdY`jrvtUI$X{@RwV-4FDc7wWrh!eH1@m zLdZib|5PYY37qM>V}liM05raOAa3Z7(Y8r2p^5Fq@}C;d@U>V^OY3oR%?+b;1`VD$ zb{4m1VsYyo_aJK#FERNej6cjo z{A3*4S^t?}MSrNX7(kA(@~>1rFZ2v<0yEGG$SFBJe0Fka}16M9;{9O8JmdGTqOH#KP) zQS33p)x+-fE7;%zM3|xT7n4Wz$j4fDn({}}o9?xp19OIL=B8iHTl zy(!ay?SS3=zT7nBtGf;wB5+IU$vyBw$KK}?Ab*4#0X=yf#rLeu-0$PoTwAbxL&l{I zfOPg;q=>)9fmJB_UP;t7t8gs?gjGo-xUMlk)JQ_n}_ZQ zLm?u9=C*|D7n#_c__$jZ@bh5L8~hr-{y}OZcFIJwiZC)__R?ZoFW&nTd-TvNe)81d zP2Al2)r_g$0yd;_F==V(y78*REiU2oM=3Fvp~$NNGT05uP5>|y9Vz5JRIYw%0b1rj zS1N7C*`X?ZQ@PKnHw)l*RC^x&7Ko-BCbZ}S8nKx6Id;(77$M$LjZXMOrG0%Noi?KU z9ulE&S4Y%}olT~7hs--C1kQjxzNz3uUs&npDR{`+2cZYG1P;o;;Ac6%ptEN<&vI)l z{#+LuWQ$DEzgBUzOnCV8%Ej=#iFj;gH)%>|CQuIz0}bdr-nhcBK4owklS@;riT`@!U2PT&jzBu3m2)i*V%V{HHE)^lacZ?uM9~;RAah(FhLI1p_3pP@Xiogw7>G!TRa+P)Wba zjsuV;?e2W#5d%l?YXqGPdO*Q4tn7a23N;0Cjf0>)gymO)3H>TC6|O&D@Q?DzxW{MO zjCa%RF;w)dtWp{|Ewq7c4YVy$IosoB=FdYWjoS}Yf?8*;``pWDjV*~aQ#R=TB-i}F z6WRgIRdm6WN9v_{6=kX8H%2$H?fVCJmPzD9{KfFDfnoq*4+jeY6l9=7K_8Om2Z{+s za)tL{t}>~(q`$xaH0Y$mSqQ`*Hw_GgZqQ7wp+hnT5nd%VO@6clK>V+$nggsk^)1 z{lEy-b3WK_L~~oHt{J{|4lrq-VMh?4HXF)ah-Oxo3L_V!)wb@B&fA*3dcb@LEpz>4 z<)}y?-IMscyN3AmU}XiTc990IyH*sz)5WZUo7x*l>3Jyqe)Jd}?~d-weyX^F*0iWX z0&T!_N57N?J&yNdx~VQCl*Xm%JS$<8o2=OLXyIxoiW%<9Z|#JIt10W2%c4{Pqg~^= zI%Fobz?rt=qNqb4D9e68BO(RS+{&Ot52oP3#$-vT%_@E|i5oy=s4iTj5;Fw7%be$) zqpq4+ssU%c1+atuwv==n$_lxj{%0F>&F-_u6T%tJMWEA)$Ut3=1@4pb$7;wS zei-elVOMq(n>B$#6l*bQb`v=q0NoVvCAZ?`IoA)*)y>Rl7cgwMFwMj%z{EEQ7@}(G zxB{%34+fvjAa$q6Rw&=3S<(EG&vU)ieE4)%Sv$j1Q^MH-NDb$GwH%=qrZ7I+6wH@&W?P-zN5L3Lv-+ z-nMef{FXb6P^cfa_Us>TwU;MGhpuOiiC@}DYBTH&&X_xA9-`G`#QKAlh=)T z@7rej`%H&5d2$Nq^>{?g*9jKJL%~_v-{iNq#55+IoNLBWidF2pFk?RBs%bbT1x7Xn zfc0`f|B9l)ZsbClW3VF#WsaHraBAu~l!!kp|20@-B%IJ;hlwor3?)KKCAuY?2CY}Z zPRo@Hd$Irg#=Y(jmY>=hf2j|2xeJgnGx+wOm>0Qv3)(xbYONoalq!Ph)gtvTM7#T4 z3n`i22K@hL&nJtOO4%77C@qNwn3F^=$Bx|+z`gl9&q4A(c-?Ni{Y=X({T0Baex}N4 zjK{m_2m(U|)s8c$dPOZDl#!*1{GmHZ5>;XL&51K@6?b%VZ%N7lGy<3@+o-yK%^28C zJU;+=R08YiY%)l*&trxI zhe;WHTIAqjPTt?B+6kb0u*Z^-Zv#&<-Cyxd-+rMdI)XgG$|J+_5bGBBv}iT!XaXyC z(m}1;nBqzwyR*#3mJ`sJ8>8{o4S_(-S%3|ikWJZ!48Z^-Vvr%oXq?3HXbZn?F&G5s zIGi9Zgx+Gwq;e8olTDb91pKcoyD%8`-p z{_Sy2cWkNT)U({4^+mM{hMc;dfp9avI2T0TxXP9M%lrS!?g(Wof2yjakqB4?4_ zWCG_wmg|S|a-*+ZK9b4qI8u1QtZvA6vhH=aCY=Kv4Z^9K#3nw4Dpc73YnI-S3{C~` z*^MwvVleWQ5p+4KAdYJ!JAzG@GfzDuD4JDUQA$b*g2w55f+~lVjUX790o^Q!ssd_- zo@pxESyb#qJ2SoUE|8+N8g*O0zJM2NIP(wN9a)@UIsrsa-$hQ3256DK>`i1ooDN3x zDd`R506k@>m;2oWw+5`LNgOoE)SJrHZdQi!dYL`E_&ybih_@EGUDPn#pYLlio?O#a zB;lZK_lOjBErukt5*W8H4omV z=DZuklbFQA(kj%`9IowBU%YW|9qUC0-5-@WiAE|&vx@QmO(d(<5PMwu@0bf_B&RtF zHC964h?}+wFGS2olUSe~gp`qu71&2JqZ3OuYMpQ-OG|P+d<86!MPZ4#-OG2F{Ko0T zVwhq5Mgio!#v+7Nh}~Y@$_4d^PUka?JhJLfCaWB9%E=u_Olz~4h^^&pD)0Z+y7)P%yK8gSqr;O;VsD19}hn(YPij!kom7Z(1re8??z9`9b} z!j-pMbNIdIz>X}T&bD6i7FKj*5s5j$Nk8E4c+&%&7l^ z{Kywo@_X-epk#=xGmCpN~0)Ox5$P!jZF03t6>0anj`&201$DX)3{w8t{{P=n`FE}WPWn#t?n z=bjcUSFj+b?|TlifhFJ+-ytIL+7c^4cSQ$@KC*61FiA$AvJ3oCX8{*K1wa~jsmjWN z|DqtX#uJh1cN};6iPh5xmm;|h?zBW!m4fO(kNyXM(x;x(_M4x-SM52AQ|;*P=N;z?%egeLr@>t$*2-LD(KXjrro9jb|eM)?tvda z>V&^Q$pBmxGTlG&8z2iP9{(y8f+DS)El1;7hnx_ zJ6B@Z=3LqWJX~#z%oTNwOEZgE0Z6AR#=##nM?kUTR+bu!aR1?y87XpyA0N(WD)_rIA;FEtj2$`Rd0czS3pf+hyR4_Gwui-&1~6?jyjH#DdBnmw-MK{;hLjMa$~-6A6q>Vb~6sOEEcmD%?>5UFMgx_TOz=BVTSuI20> zkFacR=n~Ky#I`$njuqG6xY6YA3s$4bYz$@HF+oLdLf|qUK491W?vB6(wlhwGPW2M` z5Rfh!Dcl)x?2g}O0pEdUB^Hnr0?n|0L}&+z47F>`xmeY1mQ|xQTRAdHnS~j>_sbM! z$v-k^?xsVP@xo+isVudaUy^QE%V#!u5U({**eOH_HRKxI>dtIky48V+E(iLx-1_lI zFIkgz*B-OUK?k^?=~=;Qhq~g6&m5>Hd%%bGba%T#4rzyk2>7olzo#6G->or-1o_Z( z5ox#Qnv0lq&Vx+`3aD%Um6u_C;F9=4>rJNpz2y(y@F(Qv3OGUi8nY7hjLx8UHIer% zP)8Mh7|&;F*AkKSa;D)JKbbRFnt}v`8gI~XR)gDC$Z}?OcL*GphQ;xT+&ai_@SA3DQ;EuT=O{5*R@r#=zW;iFwI2xVY{PBFv#379 zB$OeY|F8h34k5sbgB1TM=C+G;iE5IO`d#`#ypM-+>wh#PfGGXTNzh1S&SPUgbHQ}q zo>ynlc@vA@A1+nfLi(>|Y+}`uTZa?^2i$=^t)_MVIw>o=_Zx5?|C8u-3Z#$%I_r z?Ot8J%*QirI$3eY{f0h%8Sp^k>{XjO0S*Y#}dCh#y9W?txEmdv~U zL`e5-^fZe zt^k^p9H*joLnqTEkJd8K{W3uT9Ns%6vZj7s`S7d!0`Jsy1tLQFI9D4Ft@o4FSo<;1 zbL(@SMX_DuvH?qSs!jb%Y>Cla!E1NK7^%yE($mCQsJsSU$oDUP`ydYgV4q?2yVOfP z>CYUSnz-gD9}UK}6amB1#gfZ7I3zAI+>iVF?`v&~K7He%^KLCQ3bDu8Ja%Nogb}A? zYyBPsl<}I><{_bQA!ZruluU&fd4CNH?m3x+mU5lZwLCw<#Sq`v@1b3$BQKJmu=+Tr4gvd7!0;2~o=ms7i9 zueB0YpH9|{hS$>I(Aw)E5p=+%;S)LQrl+qdJ={Knjeduytl@lnr!smAy?ynO zRR$#nQ1Xr>Wa(CDonGL$6Q!&_Nw3{%qhFn1@!7B)JjTab>$Y}s%GT5Po? zM>uV3-dS0B8v5>lq|%#-mjkR0w|SEVEp}%(A%Z| z{q0aVDB*Nqa=L!Pbp^oPI}m>zeuZ8}jHER>cd0+y)p^bZC|96fPHQdhdLj^?V)br3 zl-UE2Ef9k8Y2wZ-fyKZMsn5$*ZlB1UPF$vpc=?jrAYokLB)@NZyCtg9V0`{i+^xaK zXT*7gQN?^9EPjlzic*LY*OCNfMktQfgSvrhl!K~SkrC*_L!7SapOYrtnTn#YS2-sy@6bAjO1SZm*6k7{)c8ZLQ8haum&uM;t@6gWkI&p^Ssk`jD2B0Jx(t! z(ajAiKay}Spb%ozEg&$O*Gv+9(p|e#u(^?|eux#TUlA2Dto{*svz5BFfa^wVov^D_ z_=KZLgIP;rpEq;z2&hh!yq_dQ_!HF^+l=j{my{A%11ZKq0oAp|Z9;dkN0% zWM-NpEq(DHZ6kydi1LW%Rp1?VE z)l>nRJFf3!;0#ge3?WJY!$q;G){Y4#KX-nNG1FV{6BZc1TnzyTi^H@3{|*cTg?{~a zy?EAt%(~+4{ZeJ^Lr?{rL6h<4$Nu}k=;sUw1mTp1ItSVW5X1BaF$sK`rHfJh2 zPds)%NMiRIsRK=RBVzv3G=qp6fTNyBPu=njKXVR*2fh+;pq)==_zs^5z0!N`hFeE#LJOXQQC~S5 z+Qfzdt-(0?$Y+h4<^8Rx)N$jk?WT&cx1L<+5s&c`P;jFKNVc55kt(Ol>C59A!J{>9 z(um^O>zy}4qFE}oKwqJ?@^ezfmLn0H0`e1fYo3p4^QyQ@^LPqkx@l)gKv zvP%c%h|iHqlJw>@OQw1m2?H&y)U1#Ar@QOHnWf7&uRq+rH^;cyIpJg7DYQQa5Ee6~ z<~a#)jfFg>tmuzy0s;aZC;5#j)U7c}ab}$zDUOd$(FC2RsNC4qDD(EGqcrLr&0E0A z-@5TMm*%0$`(?-V=4Dwc3e`?WmD5-)Ea5X9biAova;@6=nFEFpjQ!Q?T8~AFHxE{m zr(5FGLTdSsVa2eO$AJ>X(varn3=t4!!gB%fFp>D5lnY~u~lP0-$gHS zkycNG>k2=NVB|2k*u#2ZM*m%r-MxRb&CvV)JGRfsa4isq(5u=mt0_xng zG1rQtN!#0ruD zthRd|vvBzYdBUK_6WJ+FX@!{krk;`Mwxnx2u#r+blwD|}kI*SFuCmT~_^3KCS-{&6 zp#$@t*ckBH3iVu;uy81-6z-6U; z4sl^VHYV<$jV;PC|Wsy~oyN7ha8TCe@DaP}sVk z(_xRQttM}fG3$4`&h@J(1qDX9k5E04na@{c4(6l24%?CS-)elbmaUj__7Zr~vA^_r zZ8BpT21~QFaJ=-z<_{}fQX+uuF0CAveD5v*E7){N5ms8G38*kg?8~E*zudHJc-PkS z=+cLK5+$9N@>URC2B}V>VxXpe&Z~gUW_Rf9Tdvo0%HK^6>embCk`b`jT zGyv$USweSr<-)V867NZpTIXOs6z5FKXX@=6t`>sFJ-`^^%B+gY~=A zH^X@g4C_4g#8!KBdsQj=P4}Mql=}wM=pagSueBpZJ<6>rMnbIOlx0_P? z#GLdWm11I(?J)LMTxCjjduE@9X{0$4wZt58L&j5o!xgNQqdSMw)zKF>Eq=7f=2oL> z%h8+WLZ5JBS1IATZDIwsUiA)ti|*@}D?;@Y>dVryi?gmryDg!&w(tfR-O&w^wijziLC!sS5eH#69<^y zsFJ?Rz*9JZ&#CQD)|}`N!YN0m_?=V(vP2rrq-JN`c^{rE4fZj9hSKa1f=tFxemmQifVO=(eYUSDz$2X%bZgm2W&t>brb~d zRf`a-#K%wAdR*okK|7EE@YjXiv%$V3?M< zk+*E6zT2`H*R9ZrsnB|kI%M%%+4*k_0s{MY!d-G*FQ>N~?w4t~FR}!C0FzC-Q=nZH zDCmvc(dBq>$0zE-tmiiJsMMqbM}K3a&b{??+@sUw8L)s>TZs%0%iA{RM4T@kKYW~P zq?Q~myEUtjYByGKmzR%MZi)M~C07E!N2QCP!!CQCHlnhkb@!mJxzqgJeAjTr1-?Ar zC?VwQw!%PEPBMTA+QKy3|NWEz zIz$g4XA-`{)j+fSCrt?*?E0_nwutWQUp3AU>p3J;GIogy##v7?>b>&Y~DU2T< zR1C*FBWWwikgrI&C)BVNhJlIsvGQ=ubkvd#%1Xan5IeC-zF{|RD6ETirJ{cER$4Yy z97l|l>@%x@ewfyk`S~>IVRMj{*&^B>F6{@s(yKRQbM=-lwC$TKe@ZY@CK*tXK3fQj z373CfT0BdR77pdzQNL>Wzk~2w(8Erg`R|goeXmaAyghe$TlbOK&KP(gc9L^`J2qM| z6hd8Ppg`4m>A@@kp_fhBIbhd_cdqhwyI_}ugp!NMyrPLwnCOg6>=a9yr&bJLR59EB z5I^~BN3g&1E!A!;m1X-EPNvgq@>YX^_5@dDpkPyrMPGU8I%M#$nhr(gIwz`ZA}@1Q zeF=FM$I4>GkMBH4CaPVQ?a6Onq_eufwJS*o>X*4lEiBnU^c zynTwXr9`LR)342%3S`v zBIt1ZMkmLmwS}~^j@4$%eJifwNHKR4>2Lb7 zWOS_UNbAeU)S=al=?_40mZ*fMOGMnJZmfMt&pHM%NAhMc(W`MJ0!k1NpS5w#rv^)S zTt4LBEHSFqdBw|Uk0V^wyb}Say(5LmN|(6qef3H{gHopa94BWIVdb$~nV&iTi!U{u z3JH!gHhZI0%U?7)?1G66K1!=5yFPVmUeThPgn~yUVgnjULNZLIKMk0#1lZ!mF_qQD z`nw8i?ySY`nT^q{PHV($=EVzeC(DjzC+!yx-BOM3^e+#YZ`F(M*ri?e3x=v> zOuuT8zw5>?p%!w(xqs=AlLGE(Siqx7V=uNqIG2NBAtHx$^Cz`AUWl?DCb>IPux*VDA$%UyQr z;WRvUTzDtzmMw)@n2oB!DYbXd`>YN#6yI={WaAfllKxJd6(cju_>35wXQs`14(BLK zYNj>apKS2~k<5YB^c)Wj-{YP)Zcc91Doer6d3_`-#)hS4pIPs?uHMYhR~wOHwu(y* zQb|(W`I3`m@|70O?<1yeex1pOE%oA+mle)LATr$USQ**;RB2nfwKpLf7}(pvyDOhl zg=qCSIaB~~nijj(pw7-%Z8cm(_QHs>C)54zOotK9dNF1&K^lS-hT38%D!bn`YYC`* z>Vxy&iR$EJiK)iQjLz`3j>@U(3)a2I|6|ef@?&bnhY!ndy0Z0kWvIcO8_%f-D!RM zsdw1!s5%IDJNa$#*B-rp{|>+m6*X@AlfI3e4BP>CTmq}o9j=N)qZ2C`r<~hb9YbtR zBE1SlY-=9E+4Xoh*zb<%$*u75`1C2p3D*psi(d|4-u23F4B2u(F6(hHo2DSVaGSm3 z;++w$3O9=kJ3d!f?@$&rh6?#>WWlv!PXWd!6mmGCzj%s%tGyxwRq^osmwwy7grM@L z2lDwhJoJ*rH}fVGcS5+uNe5qTL2-*Th+F=KOuGk=Y5X_mQILa1RF|AfgBn9Ux^Z7U zL&hubHigxvi$sREJ{1%jEv+WlFOG>jO{ep$5xvm%?}KdS&L% z1YuRGHRX00DXt6SD(>4ZC#TngcGkGca+Ld4laAk$=ivcv!~&SHS6a#PShXf%98@_g zm4XX5X_&M_hzTmr1Pjfw>#@(UYC8_4+wW19K3Fv@EVAz0%PL?XOb^Svn68|1O;YUi zQSR<&5EoxeX9H4S*cCZ5z2P%`aFw_G?$MVZR`6EpF0HpHSZ|iP%u#U$T;1b9izZgiAb1IpI6IK3$nVi(}&4U761qBje zyL{@FsE;8d{ZVka`L}B1bx58mN?mN7WDhoe-#l#rIuZPxT%#zU=!IxW}RV;mYyN?QxZ6+nP z52bL;XZk1TVQ>8%ny$k9PB;!voKy=_R6S4gH6|ulqk7`vdEvA)ug+(wCy=B zeYZ!m$$iU(_XqnOrPyuFZ>7tpLbUUnU%`m)&xwCV8lT->&P!=n*SLOQbNnbcn^k7> zb38ZCYFT8Z;}O`_&~WOpChCUJRfbh2aWGZcjYsD*C|b$xeof30=ZZEyJxbM~+#ED5 zy*H-c63-IlrCIIvE$Bum#=TxnvBh|+^Mu-k+C5(>IiX=F5T;!DzYS9eEISpe<+x!V z^!GnwxK%D{{*N6D;amR9if_I7v7J*mz1)Xf=3iE_1=i?%%D4b(Avzij4yJA;=GZJc zrI{kJOls|o554OgPHK9+Hd#hg$zoo(E4ptl6jn4itRya%EEDr&x>6a`ZK-l8kjkj{ zygqfTs-Xmw8nM@IIV+@cXF%n*P*UX6<>3-(?fcf{Hd~Aa_vB)#FQn&g+9vTSeTwDi z%X0zv{DK=+yYP?Ks***$^u3eCq-Q%4%?n+yoR%jLy83*N#&s-hlf)DEL7H9I22yliQrnK&e0usHcd6S8RB4t~dkejcSJ z7N;J4064U5pAC^m{toIPpdj%fcKCm1`7AjNBfvo2{hlOo?_?3ngDHY@=vechr}hK4 z^s}+7M2)G=7)HTnD(`7^=KhwP`~v^O+!g&4k$mcq6Q{y6iwEjH3s(@DK^5%vo#xmi z3Z17%4g2}FGghCXy9k(smfuA7N=83ff3VQINMtbhflq*hNz?mSJzvzQEsYUSsn#g0 zxTL!OD_D-s&Unc$??8)Q!|jSJ`{mD*@fi zm+2gBwhF#}k8p@j#Urnp!{#oBE3!RN6v2MGPTz4hWax8K^$TEH02gC=@qc4lp#Jck zJ9oN@B*OK*(Qkv9WJ7JYtmWP&=TiGwt-@kJ7U`a)CIsPTpj$r$Jit>8)}NY12?Xp9 z^2!+&`MzBJeBv0|>w4%IWm)IIkM2kFbCQP1c01JvCwYu>35VlL(^#&eeQ|gyYHH&r zU@V^H3D2GFdr){X{8;?Z>`m?A;nL+Oaqs2$+FMKa4TjnS#h(p}en8$n+>%-#B17Iv zJ41A~gc8bm1DU*qA4%|7wxny@0$knry*@?ZHNbAxT`_mm&v-dC^)fkq50grFYkd;G z?u&fA9vz>prb})GE7rrSB>hsLkdyy8^2|92Xe}dPcJ?#A1@5{Z+MpE)lM`tw58aA zvLH)<*!~yuD{?F2;CJpufI`U42Z=ZOSNCP8)j?*oeE?$i?{KhRr7A3DNL|*@eixll zb4hcD6SSe8-Wq!V38APF^$d`$$%c`i%J;_MzNe#wd;cW@!26yW01pri=XGLq6M>1b z=)H+h3yYMbfha}^>6{lv;xIUk>KJ90di#R5Pe?K{yUIHEQS(@0&;Tk^T%aT>YZj3K z)>bSc0l1*+J14_npt#y|Bi*q6p@P;rH4J$S=V5Nn@GI~QzK~8X`fzabplZ4`#ULb> znI`ZVam;TpYZjuC@iowh5^t;))-LP_;ODY{*_ zTJYdXAu;S=$h|^QEU!;eUI-l7X~`6+MBogOP|b~3#-0f3~J$RU(cLlUkQhp zTtVU6P@_VJBiP8sCg3Z^-vOY%Lp3bwf8-Uo4?Wdd&7n#He zo_WIzRq8CK0Sz0UU9S}LQ@PADpeR)#A=f5;IFM(oV*KhTc{eqWscjnf3DC`V1-Q)U z19qd)pHlM*Ra|FtBfB$I+udHar@GNb;G%&9tF6pi@g_-)EdK28Vg+%#kNNrkPMF;JD3|)=^VU*x>7Gjp$1`P~nt>#}rpZA_ z6D>M2DyR8fpY>EP1RKJ7LwBp(1Z`o%-Q)hzT}@ZJIZBLUXi{K;lj6+Yt;yMjQ$?hH z=e@%EBb&#yT3i;cggA(=E*R*FAf1)q;E#e@9?B5b&W9zgJ(Vk}>BBMR@vDywH$hi+ zhYUrPMQw5cignt4k!b&!dDu*p$_DMOX58@jxQ7;-$Dn(d~w($oXue8sd@_P6-ueC1&l>EreT}{qz7Tss#7`!{;tp9$>^qKZct}$AcEj-#=g2(4R}m^JSbSM?S0uVhs(gsCj^FH?@Cmhp4x1)E#a&q2Am9B3Qa$Q6jY=lj4hJNs~$T$qfkc7L2oV8X&GD0 zD;d2>>k0j(cTB(~*@8V?>q&M<1EuNl?Gmd`Kx^9oWhy$=V@hy`5)A0|ccP2b)i;}> z6=KR~3DNsOBzm{doqOa92C~@M;9%l3tfeeNzUAfk`Ls)N_88>UCJ%8x&ae4YEpx^m z!)2|q?v7*$yu8Z}O}GA!pus*+NQbUGNlmxX=t77?&=5=he2gDAilifNO2aj zqdYu3^c);2f$>6oMu#7F{=!5v0Mc9{ORD!+&acL{IGRpAytRh~M`_B|>&9+6DS8JK z362hzK@&5Lt-u217me4sZbyv?yDAp!uFRCYvdmwVz(&1A8}?{S1ogz)iKUw$DN-BedO$p(t!>_qJ%)9B>1dfQ7r0R(vEHal49p$u)oHo^e3 zgk#SMvK#10dtT@YbHM5ig!MGxKqw411*2%`m41+u^6axW2h1e zEFSuW*A*d*MIDY_3eW5cuZfgIz7Ge6V*gU(CY}U!I=H&gV*n38;21otQ{R2#?XT(S zSvx&Dd$vEJACf~~bT>D*?lMcYih)--sqi5up75ORCjklBjI@ZQN`D9U`vv2xvi!%lRnB} z+}4>~;%bP#bLP}tVm@Cr#Z0S-Al4`xkAUgP-N&q^e}ZX!Q!rvdA4j>xQ_-k9laxy- z%Hs2KxrkA}6s|0Z+*wEo{lV)_S%A@(6QmyU?KybF4ds>By*uGKfH<~iJOLt`kcdF% z&@Ybwl$i>h@tizPQWg;zUoN3-0iokonJPtFk;2+jFvn{Uz450IHrk}9(gAkIu4l+3w5Kgk&PPY zRIl_I)Uw3$I}W;XQe%19bn_)Y5Em66sa4k_w}ij}0)^53w3E2Gw~Ewo55QYU;7jYvW_Ya#RW*;ZO?~DphjRBGXerJIiFUm*E^q-$I73bpv&94T(Yhh zFNFRT+K51DSp;G8s9!>x8EjwpAP;gb)~~o66qRe)Q9aBV^`1-lvgb2;3w6~j z*xO^m2MVJ;$%(xx`r0!0BC1WlqP*8VG?87BFvEGTo1H#^iE=jwNy*oJBLqkLG=;+KkIu2+W3>O2M z^#&ZJx8#2~0jxVWYG`rYfZ>cRM!Sxc+Gx(-)LLY(Wd30+z^vWt`1I3yixWcuXrGi= z&BQ|xvLYsiI^Wh97N@gu*&!F9_@n+(dx20(G}R5Kf3Y}w73vy? zi=C90FFeRPME2<#?hribFuiqGj_Q zVz_9$2ZbzmfaKWof-i*-NzNhElpBcZq6N>uP>M7Ztwmq)U~IO8c`-<@&9i-zXAJ)5 zdBBrWulnUsQLq*07HN4fJ}0L!vae=%qCSsOK@(y>ev8h?YOeZR)g0}kU69FNXHs67 z^g9E8G_ta}6)xWTzgT>>3cdDw zaRh9%YK}IV zK?i@2FPJ*)#di{+V9Umdrj@G-kf7i-x@W}jx#cLQR)4a`g>0KO+ctMHr@@h+$A?Q! ze5NyS+KaHtE?b2=YVy$0F81q$ym)(_LN5K_0YGnr5~(7 z3~YKU5B3yIPqdp*hJ3jH-J)uRM`W{JKRVb67%BXeMm!)Rdj*`VmF+X0t-eT#?-tbQwx*stB` zt=H*WpC5QOThm@)H0O2rR%lbbuv&Wlq)vX3y1AK)jr3cUcZsd9Sv&k`ed(*e#_x1i zfN=)-l5h*GjnEY`caE7%&vzVFnz~7_F&VJwe!x+5PAUS~TqW#yxTi3V=BEY>J=s`< zQvZK%Cb%$T^(~)SzT5QEYUka5(d}%NS~R`q2SHexF2eIfitBr-md`G*L(swx<@f+Oxrm?OF?M=6|h)p^gGO_|3#xdPO z%?U;xrGZ59C&w$-k` zLKV95ocEt=i4-@PTa>;F8~8&Bo1H5yZN>%Hx{LC=?=R^#E+(f`og8*Q4@d5dyonlT zkDu!QKwAa79iLI`)ouwZy}c??a&^(alNG{3^;$)z-rM3qjg6`u1vV)#aaMY9s_*VC zp|g+o;JhXvv`yMv`(hjFpYGzCGHzqJFlwn0C20A4Ea`FXhYzyGiUN|B91{y&wiI$Vm)%yGa&>)& ze${(mnfZwLfz4Nz*-@5^H&J~$y2ra|=T-4aHfQA*+=idEkyZ|;Z%t}%+I03Qz35DO zbqe&^y5^mwsjA^o22GB>$a<{KI)Qs+Jqsd+1H!;o-7*4=2UY=UkS{A{iy~)2hh8H zetcx*q5ew5Qt|9YqGkGe%B3VmvyR-fYm~%vNgES)hc3@)qdc9T@;TJJL5P_?9BXaH z|IL*p%>3J}ifbG$YKGDzF3g+H!cTd}Hk)s*ufW>7V@ym;GomW~$XHsqp>TmxP>=q; zu3$>3t9Th9XrUTqyk8i0w+Q0LGS_FM8&k}m7R@#<-_s2lqczap+ea(+sry<_n~Jh> zj6VexRoYrREG`IOD||vcIM9wxw!SgjaXh9nVADL%ZC$=Td7N7 zVdIP(%I{1R+a}MX4f*EYX@2Z+f|qOZF%6ZaNaXvOxM$5&TAKr_AE^tkiSo9kXTZ`p zl_349l(*(f9D4s+3nZ33cbI~D*3lqn_^WWo4L?F)CR zuXja!3r) z@L`Y3>W>2*n;oXH>ze~aqRFK!Q!c9w3)KrN(rs&T(*DOqkESCd->xjyp+34*cj4-W zO>2j#ecx7}wrRC?`ao#TEs894Sl4VfyRbNsyS{oELvNTzN{-bCyXIsc?yV>d`JgGf zt<_Cc`>nR6ur2EiSNGADjs~r}4v!ceo^VqG5n^qPT_VA`Lw|KFAQiL;*L_*-2O9H-p#~*m zVT$~=4>GtaFkguQHh-!yyv0>+Y-%!wjT)+tCq~|r`y(&NONE<yRh>Q4Se{*@ggMUpHMHwVI>G~qsS*| z9o?nI#>VEjq}EiXCyBSUgI&={ zoR#^p16z@(ZL4z(v}^^rez=Lkl;7})@>*Fqpp!8yn1xM4mJm)%8J$%K>p%SZ%-OSY zN=p7qC-1_$yD8&BV4h$%)jNu*s$*m^sSgDH6B)~_p5Fb&+xOiz>8L~a`t(n=*?dr) z)eAG3Y2kFjeF_n;VG)-mR%pNLgD7q$KHY}1yAtEF-?c=$Bik4 zx7$#pK)KBC=%j2=ULIqkGrWQsn*Q-wwJC?ktyB~C^BBW$olT|tXf6Z3P8r|RMqXyQ z-Y{;a-&w!C#bQ9E;gH4^2jlG*;g%yS$x{%_F=vt2JEL`bNQZlA8Xr4~eywjugZYwn zvC|9RyoQ}(NBa{#d|D6Z>^Ava>G6ccgW?B`WKTT5UCGP29jW}|+_`;&ES^uKh$gzC z;Ob26{ZC3XIbo{k-T@WZoykFDh`LYKaQT?SS z#f*^6{2G;lgu@r;y5t03u}0$!=Yh%k?65Vs^@2DyV%~cYEz0xt^^MmakjlO=wS0N% z$UXd*beK#eIF-K*uDhMOK^?3aTEwQQci)pW!bUjq&W|BZ8(c!fXnrnoETcIQKxpq9 z!tL1ruKREkFT9{vdzT&WRN>EUbv=EbM$NH5-728jJnHRCI(q|2vm4Ozz9V3&od-O4 zypPe)aOCH&OPfx#yoURNOBWCt$^etvuN2lftTOqGU0h~6F1?Bi({SiHIdraG?Jvn1 zFjDG`Xk47FHY$(QZq*}vCryj2+b7o=dhAuUMm0wvrhVJDr5}IqWsIcuc*6Qa34^&NrLqAkx+Uo)mt1kK$NnNg;G@ z7dW?t8d8_+bnc8*tbs3H7{d}t)eJpoM6t_Q^g)q424CC&CXfe)hclTrr?VBdl6Y_) z(>?kfs3{pioHl-nbG=f*e#H;Za-}b#`emDbPDQL19?pJv4i_f$HTGbH&^Bs#oNeDW zNY%j6O`b9`DV?iw;jV`)UErNkJ+i<0S3o;M-IHX4l>*I4#7AhTtI$Zlc(nr1>#%vp zXkoNvo9FqR3{vv&DzvzJjSnOO#4&{~_38&Poon4^JQ^S))&e|DJ|FApgiGyw>(OA* zYQg)P4q2(yPM5wgiNs zc|rnXpLRx8XFe)xHqAD=r4b_7lGZnw^(iR)Z{_6bDhoF%EFPl(+3u4FZlG%mbe?j7 zK>F~Ba{=Jq!pirjPbvA7*1lk8@Osd~o*;I#NM7($%8RpdOXdqMoID;Q4J}^q4!5Ct9RkCv(`tEPy*f_B z$k#=LD4`6#*#sU|xqn@x5<(U;SD)h$)};O`uisG-m+mxkZ|VmncDYBBCtrRdZ3CERK!qFhSWhokbw zbNDsfUD5goLNQ|*Ea^U@Yo%0!w@s(aoIQoH?FB`wXh7w^C*nlw4X(c@MCS1dVymJA zCZWo)ybFFE`iKuaa~`-;=ULuVhF-#y58@d*6dV+e7Ez40A2H64adzsMowBp0iuj1h zM83I@MldhZW{XHOZk>2{ar;qE$)?ABW3NefkVAn%UtJ^~P+}N}M zea#TOyH<$@>$awF^FFjZ=^N{z3~90dp+A`6DyxPc8Ae380U!I|ghKX)-H=^N9w?DB zYP`?^Yp@;g!d+-_b}D0`R&|2%xf$1}Wi&fa_sjezrDRSHDW&JUM%d#J!}s!MjizGL z6npk=;Ni#pzFXxDC;i7yadnM?KWfh}NQFgWHK7YyZGMH%s(-ACsd!C?ql6sLovcim9*}oj{j$b(eOl}c z-u|x)GT@Mok_1Jmc%3C8AF}&9;DGZ50W($gJWvQI26KmEKcpc7jr?B-^un|*a9*~) zGCZj*Br4?)&i?~@U>NVRmr9UN?X@uZUY2Sh4qNFN)#<-BEkgbjI$u1mqI83Ir0c*VM%X?t`s>*m zY%vXm-EwO}3DsFqo+(Cikrbm^Ty$zS6g;Z#;2Q-Aw}GCB13n#Rt644q+CSudaM#Xl zc(|0Ai8%VX8jO7{mNcIzxz_qv>>Eyrcu+g}u!peT3QWk}w5y&ptmM#+*E^r9E4NZT zhn1bOMEH{1I$9yy^SZ=5@TwlG1dTAdkqq&kv;VME?BKffSCJl4eUU((ir`2*Ksfl| zK6Gc4jp9)}$8#f5)sI&0cc#*z*r1S*Dp;j$Tpum+v%uxz0V7booM~nKAKhE>7knnz zsjlWFTSqf!X0V$=&oa60gV*mNHIZ;fz{eFi3Y%B>O*Gxe^<6GWJ#~>&y0Buja^2~< zZfIoz=DQ+X9*ZDCtWSDI^>x_@_g2`Q ztc^1JkNL!?z-NyR4gZ92_1@kJJQe?Zz0F%CW=&`FfBLelM;%;gciVRW_FcZ`aj-q} z4O^U$n4q$`{kEHE4*IEKiJ6S7tdBn(4+*jl{ZBh{hW59KUMaU3N!`pIIHCPw69_xc zXDl&yu;!aCBaz5VJmZ$=)bQc4S|Jq^FR*?dToO&!q_Kxv-hXGL}-#sD5G`e{bl)`d6KI56)NQ?0gMYK_6j5{6ETf zxwTQ!iV_>R!vdFDCmgfmHOnoK*}OPjniggENA$k+WEfSRls(0u5I^|QZC^atFlHUg z&JlQ(Naq9m<{R(GhblJ)s5Qwqniyy*Wf`IdS@&o>fqFN@2)J>u{R31b6S`fogbF*6 zoixFNPmFS$| ze4f=|CF>~E#*dwPz>b~o1PZnQ|G_7glEO5MRD)-T_#d_ph<*v(&8q5t_@Gzrgyd%klqd^V7wkwQ=`Dd%&Z#G zBAS$5^X(*uW}ca@Hea0pattmVn)+^By0|FB&CjN*>txoT^A`FGFVSnA$LR!`-?WM) z#WEltF(8GyW>@DtA`e?t2vMl5QavCerxX%@wDKd7)a5^o_W$+ZS1}2&nK=8wjG>Jm zY?uljAHQt|JN?3W=aBxwm)MQG*^>&WbM?-#MR3Z|x*jou9V(|hO~RAKCL3LpN` zrtC6w*>Wxm9fktZ8$guG(ep>5`J~&KuBH$#A8Zs3gu~!?s5}yjLuwPzT#58|lU za3GQ~wAO(VkWq`G#2TnAHdFivmEfT6xCf-+PX&GXB2igcITH=J6^J){#Vjn+=O=rv zQeEtzFfJe0wiI_?eN8B<9|26x(iYcNO2By%$`Gg9vK_h4 zbOu_Ly##KiYV(=+fuNydksbmYlj~fV^wTTyKN`|I3?e=62CM7vIjA9gxQm1A%Q-Dx zZ_DNB>u*Oo!^`?oT(&m3&0ASrlK4>t2bZm%QflM`Dg9lAaFTf~>-WgLUuy{>RcD=U z^$niQ7<_)qooa<;a9q%a*`fwWi21wX#6r;y)kglWXHr$No8t3}x;<#&QkC;PuvW1a#4yOkdnGEa!e}x7Z>6Oi~&*62XB8 z)J^;l4>v$e+cOeVvF(cRof5*=gLXXKfIs+-Bp?hqm6ZoSSpy#sPP%&t#sY4XOt}-7UZAr;w zgAhTi{itUI5=ODIKzIPF_W85Bj8?~g0KFgYAc}b#%bT=KQMfSM_vaHBa{BI{*NEW1 zmyu`J^@z4gpHEVKYMeyE=h?H+?rY8tD(bw$!hkY4yBl>M2w#|2JJ#koef4JS;%`Mv zIkk-uX(w*4{@Uv=M8%iytdBJ24Sm{w_`OX$DPU#{q)8r=MH{2okPI-9j`&EL1@AQ@E zYCtCak{6*0IV?t29Rb7L@+1)t-JDplCuD3$fj06aKB!xnAaEhl{_*dhh+kD4}nIdL!ux={csnsW1U+PS_0m&soWh4O}=N9A{imLeF3BKZt3&y zz#stbMIRm>ZYed z8p&`~HVc@N9ZVPg6MU~X$0m=~!nb~x7VB_(3#|d824iIG0c7NS4WQ36vR>gzl^@2hU@k-$K2T9 z;UmF-|9zUn3V90BRAInqeiXVFPC|IJwKvlNlOXQCUsXqk`Nr3$&mp00_79b9Cpzg5 zQ&RWs?cYV!EF)CSiCx8fl$f!1o@Ru*Uuj{LhW&vq`<>QvhE_j5;cKC-bfn2&PGT=l z6$Hdg9G}qM6m*L+Uz8;ru2Tzr5fsS^sg8;F=UTC)e{}D$YCsE6-M$Ic6@xHEALSFf z@t{t>p_J=@83KF#99D75+1lowp{M`%r2jiuOeZ=7Rr0qJ?+-p)A0f*x(RayN8EqS` z7TwykOVc%b>`Dg$$DcjUini%w79rMz2H@>zA~AY+GV{kD;O+gPn=q)%c=XF~BY2Sy z;Kxa1mlj12X%NL;NzqW$y$$JK$O8W(sCdHqE@z)nuD`+CyTY-{z*DAF+;i(3P-~qXebWe74kJ~}qomlIWKO^a$ z`^Vwb|EML5H_B4uf3(tuUzVYG*NGCso6TW2T3=fhY?^W>dbo`7bS#s_dF8z6dCh6; z&S;=!O*qpXj?!+~YST1)T*$!F8*mF^-#H9rBnf=WNOqo6#_9I9-l(!UmDQ{-E3W2R zn0dR+@xPA&>ptPsZuSj`rr(jAU4?0Ei(S6|hhxy|PX-*BDQ=-J<+Jj#zG?6IBBWmD zC_cc2{BxhD9FLbLaCm?bJx88 z56{(qxRLYT?}=vU`eZdnRm&Y6A+wcKQa9J_HCY=|AwA`R`q?tNcDD?Y= zrIJi~!gzON;wJGl^x3vvE$xX*BToB+8R*=9=60FEPX0{fS{0An4f0wHr4lu?Ff5Uv zhdi0Nq`@gd=?@+adP}R*-p2$S(@#3PQ5D+CrbG-hA1dYD!1J-_V_$#K?~AVm%PV|6 zeao+4FBc3FP$?oQ+I2`M(Gjn!X#ct16u%t>7Hn1DPJ?K~q6_7TaGyuOq+)CAuC568 zrhmAXSmFouy}+_M5y!#VNxl?$z4i4g`J2f{lyokb!(tC0@ZJ{<*phh}E_{uGGH&AT zrS&2p$a~sf-9twc9ck)W6z`Wz_bHKbz|sJNg8R*>^fg@z?er%y*vO4yN(pwLo zA9a3RI#|n%&b;d{@9vL zJ&5#yLy;|?wKs+g4qj!0c~5Com4?Zf<&jYRg!}U|)0N`@xu#CfFogn9 zjNx{{z1x>^zkOm%jMxN}+^GifN$u21wv45Ne4Y4F=Bgb{{ESMe?%cVwuCxc2cFoVW z^cWzF{;$+S@4)*t#b4g9BGoOd-6qLW|B5jKGOZ(m>86}J&%r!Ykau+@1v{mcb*pA4`S)kRV%IH&d_U3z zpT=ri&@1V~;Vll^O3W0qF}qCJ-)l`43X!-a9W*mgA%E*uGI<^>MsG~IOalyfe*R9U z46F@J$Te@_I!OeiDEoHZ{Ne^hUK6Q%!fmLNZ8&F|x32@c$osJMp0LiEM8C;&)}VLh;; zwX47-Vfy@WTeSGI&JOtNE5olWH6j*Al{;=U4e8$(nLi%Fg~>$Ap}ImsJW=?Z zi#*w}*=+u8`kh2+$(g)8d;Ywe2C5(qXW0mwK$fN9weE+8BiqLTDh>Ye1$J~ z!b|IeTwstNW_Z^>CZIJifybGoAF;xYNPUBLElF~p+y&7JA-Y~7)y6^~ckdjw;6jyB z^%5);GqO;@007$vSrC?x0W3iW^yeicnw#RdWbE|+tVjLCq8r}3-aVcG=!zmPW7Y3B z8o1VRqDwCm#Cr5avq(wxr=Fh}tQXy4(0$XTrD!`TD53tSYn%=|ZkKFVtUJ9JT) zUmlKcED7_7*sl6!t6^&gW%#?@Wsjq`J9#*Naz8b5bse69!sGsa?sz7=I<-qr0NHK<*-|yQe(ff$umbQ$>K^M~ z*r|ibEfomi9>u<*IuP+^dgj65`^sE*Qh&o-X_(4%cyM5IO zaZI$D2+sY!moqN6!4nUL2Tt1m5_74Y}+fal7k#v6vs;katJY3kcc266f#-16&I zi}$Tztu3TU>;<|D?LnVGs0ng<~JSTUOpViUG_pXKYQO;Q7mUF-7N*iqeKEI=19l$c}1DG0_K131TB} z<~ps}YG)aG5>jwWh~#gF(_KD?1(5jsX8j&3c?cnZ=AVw7=3y`z6&CzVaSD5Le2*49 zHIs6aib{X+%4I|S>ybiz>J#U_KUFhQ!ViOOv%Y3>A0@W=435sRJ!Fcze6|EWvubjm zMfJ9SNO%O5XaX+2Qvg2_4UM(aMtl~fwEm#8NF&Ust*y=daQWT@6>n~;M%v5H#$@r( z!9k;N{`;}bDVmoTCwo%vw_rhW7m1Ja-U>1@F{z@+F|SVN#e=T7sZ1aN!66=UuIFXt zZ8jlJq8n#!1bS6@J5F*p)Px>EuVy|AlTx@J?Jfx)^rTy5_s3pw4$GD+V zNf_4+BUmGJLQ|0kzJ>Oj8)R8!0ZY^(t`~Jqr9eMr%RS+BZ9p%oK?afkc-MocV?Dv{ z2>nAMkq`2oQafbygjTO&!yGx8ht^ne{WJbUhr@pY@n9yW)zR&9?)W)>I`Q98X(a-- zR4h8)su~vvJbyp1^T*m$X(+%kZcU}WPH1swOp3JhJt^XF1-fJDnV4ih`&?C`nNmxqt_srghR&nh!0-t-8kEkKYW$Kxh-n;_r_BAJud}W5;l#K8lPKv9#~b!{>@nSm7?>^ui&^|s0?`vGrt(s^Iz!#@v(#cFP6umPw8 z2YaG`q0cNVuIP89FMXr+lJ742E2l+mgQ%376ZQdu3=Go8h>25fQZ1XMJfm6m9f6#k z($VRMPITUee!j#KSyEA93C=io1{^A(3P!iIk@CvujA(pc*;5bK!|0}DzF|eUk9)2_ zj{_v(^g9?F6p|fbzaYPBTd_w}gD{E9#y$+1%i7Tnw!$)~)f6`MX$NyS(a32C85x0MUvM;WhWIMBu!fEreKJO-x*wJj>Uu{bV-+!3<<7EqE`tw!{W zb6$tg-?asfgzD(nK7d5TqSh$&?duIA?xAPq?YXhPa0@9Y@vc)I#sNn{v3cQ3I8tfa zUB~`Y+B(W_Y-{T4Lx2DNU3Orm=`%VKi75X`lyzp_K9VXyppVi~2`&|`FgYz;!Nn5A z+=nxs-A%(9_9o4A*YnSkiyH2JJs6xfz0)Svlpy$W7c3psiTRpmxIN)>yX z%fu0+J(o_~OW)c0Md>rzq=^*k@GF;+ zqNQHP*=H{6bc0Ox)bVG%k8#uQ1Nr`pE37XHc!M~|5u~axn7n-@mee&FpxBjL8RPN5 z{(LR-v~Mj}LrEM`c8l85?~x8c`hP6j%>^uoB( zhuOwY=BFqa)TpU$3?>|>+*=J|l=YB68$Lt}*o1#8-{5O-Axf#;B14hhKQ@RA-QcW8 zTqtlx8&d292%wunzZ5pNQ9nHWSx8Ju$}2u`|CU<12$3qW#7y8Us#kpnPZAC!Nv!z= zM!otxAP5r+!xLPhVWinGeb;@zx|aJ+w^psD{=3Z^`H6QZYbVUSU8&&4O(zS)?al&d zf9;!!(h~Qg;jzOlk)%7ah*CmI$>+_nP@7$q&4Of6H75+3hT0X&?u!R)tS!;ZX?_7m z@fzIQ$*Car3R|-Dz*;MlH#f?k5?+XZU2Q~oTmni-H&?YfT&80L3k<`9g3dU>jAT%i z`>iGG-J3zY4CAqSLmNK+gIcY zmAEHPKG`u)O~~WYl?}t}@ZdMvydkaNg_Wb-x5c$a5J9@Lmym(ldl2H-Kta>}?OhJF zkWk=Czu8r~BGq_SDKG)g)0q7jDJgxLPEH_X*JURlsf#% z^%#jyv5<y4w}?sJGfI9EMEC31S#aSu*s`Q*RYN6uLlXfM)pG zrn8$PO+1dGtCAdJ;~jycy@>HF#NOL~{^3jl_FJ`jYD4tQgL{%(Lg1If3d=;IV#J^? zOZv1O^WY6Y-eU@i;r*=)ouYs^FA^@$<(YW~^=zIbuPJ>kR$DRLb1? zVUxPv+$QRK$?x9ir8S`2Z3WQO__r0HYN>P_P?aoLOkD`dY58z-$?ljMd^FfN;GXqA z&NJ4E6QYQZlk+nY^5C7!M1Ek1+bh**Q5C(MTP+8R-g!}fe5&t9>$_h&>gB`S0T%6C z6Tj5153+K(E=+ySOHs&upZkrga!$>jl6h|sOuNv|G;muwjs-4@;lAXxI74*gB<;pe z2i!)#Tyf<8;rOv95(5fL)!A?p=S;CzF9S=fGb3N$z2cf$hXRGr*}Ww7vbL9IWTp$7 z;C}L_{Y*s-u$j=rN#fZ2TzyARxFUq*rY`?qssmpF4RVQRDO-TFNhK(k?iN#NlDT!R zY2h$=Fsv_k0r*k>f1m+Y4?fr|nOiC=DbX}M2b+qfdq@-3gC9;!^)89hR%>KDpKOz= z2EbvmBFn)TMh2&~5Sq|>{C3n5u-nAth#Uq}UF{v`Pzj@a@hl|8Qmx-Y(O~Gu--vt+ z7rgS(xZzJonjo0y!-bxaxulPC2B>9?ccd-jRZRrn<%yVoG5JYKR1@ys0cv`ZBgSJF zm7ntmD!+5)ywo0eje+Zqbk-C+kvOCizCVQy3|-i&&#fQqS;rYUVdM9HwIU&K<&$;a zS%xB0z93>5{(f3G$`R)C@<=7#MvKa%%8i(|uN1!mf-ucCJf^AoKKO%lzbXzv?1Qfn z`J8Rn16lv-WyatG&^%~5!b%bZwG3TvHgQb3mAu5JUA=ogghws0|6dayNyzh?Ivx%-UnTS+N;u zlq|f~*)MFf0ATw~93~wo;qEa;a8&eMU*hq)S~j;tMbvF2-!3jzozCc%`l3e}ry(|t3VCr^$*IVT%S15!wYD(Q zZ5t12t`FmrT{r6%R0UUK74`!~O_8{Fx97TQu}gfilhRRgZ>4fkt)C!xWCS}XUE)!kb@rhS%|qzD=Bau z8c{@sIws;D?kR7ox9Xh>-yVOn6L5f-Jw<*&BpV&lSL$H1?jNGqpslO>q@HbGN4Rhc z&~7QoPvYtw5z$o_&%a^xZp=28SFx4*fk=J)RKWA+r_9XEM!&07B+5g7k<_)X&u=(@ z=)ZQ94(SVd(rT_r0t?rMCO*dEfU!G9d%PCw)+wM&1BtQ0v2F2&;Rs@qACDP-li!>n z>c};IBIwYamM7Osd3U)u@YuEMd?cmkPX6V!;u1nsZHUj}j`;KvgzZB(1a}4cpBlfR zs~eQvO^UbM3&7qLb{WZ}KMs|kbwF(FX|vW3&r|D#Hk)c~PWEP9!V34#_N!$fhlp%6 zNj8PsXLAiyb`>l3glNvev6*9>AR$-*{VrbC2NFbBZNcbvv*AA@6+s!v{q}ka2gAoj zmXS>wL*IT?X3IJHfE7V(P|gDRHW;D1JNxix0e+@%=kvd3PjSZK`ZGA{Qe|;Sr}}DWiMCrEEvuYq9kj~yZ@jM z-p>85J6Q+!2?ZE^bty+|fpDztE9nMz+(7>lTzR^PJ(CGCn_kSEyLsgAmuTB{RoV|r z5;=YS#}C5N6bD4{SQvR4I8>S|maop?JIXl5|C;7`OmcvRY^Q{mKHHoa?kEzrWBh7DLr0Nyx{2Umd=i}3~ zquGySd7Xe!h|^}OS63v*;s*{?frwpd`N<%P4BC@<^Ok_y49B3%uR~3|^${3f6Xp|w z5-?m?PWzfb$SS@P?RP|SdVW&}M4TO2 zfuCL@PN@fM!f(W;k!81qc&5~6e$u{T`snOpl{#`dJv}`gi0-by9RB@>de)6L?V5p(*ejO*})jN1pnZE5-usRm!lpEH|^W)^4W!o$qlo^@;oQ?6w`I6AhH z*TIeG;onV;Z?oA0%KUQtIr%7iqO1V~>~g1->!74-eC0q`qB;A-H^F}H*KCLBs}Vse z2$ci`1faz5W~{x+K!Zl#4ub@>3;#h$3G^-{#YZ2Qx5w9~xh%z%B&J>%dv7b^okb1v z?f@ICXknncBdDzQ_b%}17x|l8$OLe?91cJAhv?zAqhf0DSoJ7)Dcwl+79iwJr(B3q zUuj%=ZDga0Dlji!CU@atBhm)HAUF8SQ#jZVZk~xBrVXE@D2JMYV^5y~!FEgKX(&-2 z!ir5Q@nb3%TECtDo^gj#;;->sq2QtA36zBlo#OyPx#JOe|=Ufbl=1ast=IP zJihS{V1e}MozP?Avg}wa8+OjvkLF)GJJ%7TT^~eMO`!g|Zc!aUYG8WbSclRhbEoFG?6TY9o>IpTX!C3#Qa886{ zIGX$vb;#XB85&!t5>0p!*rk+Lhg6q6ezt|HOaBxQw?zSVQZvFbFgvchWe{Ln1~z-^ z+hCgP>XpVhg9}6hV*{0pzsR&8rvUM2R?V4?!wKMAVi>`d#r}XE$%-nMr#%f{?h-FZ zYz3?07^Se21b2Q75?KJ=QA1P^R#nv^F}nhRRUgmwyUTKur|qYG2&Zg#V00TV@3O8j zmPG#}^%3j`DRWtgeGvqV;w1C|u|@a>9jPB!rT7J%r!tS|02G34Py)nzT&ism;QOD(|v4?(#6&_-}>$5yuWnU zTGmd$6n`^fhRViApSabavoa9P^Nf@7iw8)Waox%q=Ywg31x|4i7r~P#IA(^BST#$L z(=-ywS}T^1AHq1O_2s#G%lUdy_t&w{{BWTSi$#%=H;6J$sN<$OEB$ddoup{y!*v4E zo4tdl1^CJg>^a-s>Ciyp<=yiespp+KHr7nD7b=KQ+C@IAdp#UMvi_Tn(;#bKSm2vo z@aGtM?6fxc?Z;;gJ>SIq49kuFq6}CfCG_~@R-Tk%)J+f9eRxW5RW8-pZt#_URebr) z(~nX}*_HlZzWuF4%lNz-6Mn>GGu&Bz+sV~d-B$p6qhI+7JS%?3te;rASTIOV`uLpq zF5(G=MUs87T>{>LdFxIp&S_d}uh&=CrdB_3odDghBt{TtJ=QF1G105YZUw6V<-hQG z2Xca!5cud3j!g}0itnkoaIfF>_D-rP3)~{58f5BS%|J1P<(`ApgxH&?i`SZ_O(zc{ z#ScQ)vZK7b4QkyID|5zK7;OvvO=%H8Ip84k80I4O;b)X?wxrm;fry#wT^0MYa{9PKR6#djVjo*$K5`# zM;Q-_*a=(+xQL+-D}21|$36#%IW}_e-VUtxDXCVmWrBi>h3~^_R|c0ZGDKMi_6?wL zV3=Ti%4KV=@b`I5Jtm*elc8_MGL{^p-GMecw+)(W;R+n*T}8iHMb$zfKww_r3nB#_ zv<#^DgDr;spo7kW&Rf;^Jh$|m3bvVVbi7z~s@!_KZGm~SiaVLZD! zzGN&ZI?A$&sdo+myG#$QPj<46jAfLDJcHeEP)a_VQMy@xzyW$e(o?0Ez4~mDmfkh> z!lQM{wIRt)Yd{1KTYN*8vaLL0ipsKXR1D6j#0}ttbx60~ka!mqM8fM~IC2`{bn#QlAVtes zFR~N~J)(7#G6-Wb`}4(R4;yNed}uFzcjb{imMORhQ;cEj+zGD_yETe98ZGyq%D%th zVDkxHGf*X6xeA(-(z5oLfGtTps=Rr}d3||iwwABL?#f*l8KO{QFFyLpF52wZH;I1@ zP%7#jduel{b%(%{f&eI~IGkooigi7aQ^^mVqg6gDOV`0i{^-0e%G z=Qg!C8SH3Ls9VyWt0)ozAPu!dh3mt_85l^~(JJpXP6~qJoqpowSLwEQY%BYQ%G>l_ zIHc=_Jov-XV^FQZVCXk01$ZDZ>Kz#j{d`0vGaWQgeo&=^6>XO$AN#OaB-DpPs8$UP zKk@YjLsBZ#2Hknk*#1jXN!PkTGWIrc{UNt|2iIpRXtM3+Os42lpi2j(j$d59(BW8f z>n;pm(&Q2XnDpA6x82`eTd z*ETq!95F2y#oZCA*_dqsyW-|HL!eq@o3?s^hewUte(Iq>9Y=HM=@9H0D7Se=sVJL-Rb-H z*W88*FYV7(DEup)tO)k2I%Jp);)!~0Cm)^oPom|HEv2@(0Ite<+Y?$}7jpm8JMs|O zz_B{z%IvT7~5xi5Hiae@VgkMOkN zhC`oDyHpIcNA+fKWt6V@Uz=RL>$W|HYWsaqhr3*i;d|sr&m&ha7ck&`ipGo2!B5S= z01w$uO44efPe0rk;I5>eakD3dtM6;LIL%Tk3Pshen53J;(X)jzd4b z6w+}&yQdG}r4Qx#Xx59XD>cZgnT)J=%Tvoy-|CC->!7C~^#Jf=dtYAT`umnxf z;-oub2*)2Lu)_?2`cZ9)d3Cb~7P^P?nEKnj{#)pv<3Kt07jICMauBWWtST%eww26k zWVySt#%(Z2HyT9Fp~rgv{(X&?7px$cd+6YqGiSbi@;o$DWHlyR=_t?k;Za!<)THn6 zIAC?6gdWgy(7cRrhrH@AOV&*n)&p<6)Vdk{x=C_}3kZw6Y zm9EX^$5HYDHAev>c0?@(&`vrl3n>+-~<3F*Qj*`X3BohVVMsW5tU$m zwHVq13HQ6XY_0WK4*2mUt5rs=Mq1~u-r`ZH{w@I7l%UX$SU-~xrARTXpSQI>M#^oZ zUh%o?Kt+lsD;t|JUl3=f6%%eGa|~24N}Zi-R*3vh(1SgVn+IbfzpD)I!&R}~Z~OsP3dG`;|MFIIzN~B+mr1Ws1GLpy`B1?dnvF3q&;*JphOWAe#pv(G86*cU4}-Y zJSl~Z3EUPe=ykFHs5*T3)|XVBzDBi@?tC@WxA=nLa_h!1sRQUO58;cGu*to@kKoZs zeS0_CrV1%{rY2@?d7Tx}nH@SZg6X>&)l)cCGS>6DEWXJYVo(D*HxCb7?GN`}!)z8g zn9Wit#WGh)f^B%g8}*Efi`%$N>k;>7(n${B_t>Ed=$Zxt0kz)h)R1mV;ucOC$F0)` zbVX|>d>Enw8sena?tW1LAr&)q17TC$cxg5IHmQn1f8x8nwb#Ejw9G;{cA;k20+b2S z%B2q}Fqfbv?`?@y;f-Z{d&ePW9|$-;eY)s$z|POaTKUWGnH*P`d9yMUsy}$wW$o(s z!W0dd5vQ1RyL1+)H?!K;57K~Fx=XBG}y1uG%PW>YP zHbF$)r+7PwrP&_5EuCAN3XsxGWeJFmW(TkCL*&)G^oN_9j;*@hU&8@zjxUL@L3^OH z9k`(`5JtG|2JAf)G}%GdmS>i-SY2KHf?C7@S9m{y)w>zs_CB0b^m+0`tuTH4L2Qv=_Kg|ls9c*e`7iP~UexUix?ZfnLSf=xf>}XEO)~4gzF^4e4 z`p^dPqj42&hObRAlJ@QTD{oijLs*};q-a+AQ@LyeML--T3j?qQXRA3v!7V&>eo)izfvZ@oX{Ct@2%`4KiXBSpw$k=qwym~n6^Khzy6L z^m+9SnhF`S2T?j zJg(gQ#dU64v~(i9r*}BgaY|rmoTs_i6YSAuZVz%pUsVr>RiH9*X zs>KdAX!-~VhhF!Ez7$Vh^H%TuVl~#lzAAy?$Qx;!;Qnym|0#h)`gZ4gS=-5OGm#i5 z!KybnUvZb`C~l5C(JFjm$=e05S$$1^>T|x;u+BnX-rZL=T5nYo;tk7vRZAY)=dX^Y z&^Plv9zN$COSF_S1Oow3aNN4}o_$mcR*h6=DTH%d_Sm#(FNM2Yjm@`k-g^2V_1XK| z?PV|INAOQw_Oq8g7xaAeh1EHd!!c)WL@<=jrCU!fd9kj5zNkwx@<)S(YDMLLGDzTApr|~b2|x)APGmiK3-hH2* zX;^-6Y;KxS&p#IHp&ATT1-IJy6kPu*O(QpwZ9L(`x+82z;sT<;OpJT9Bcmd58O)Ct zn|RRg9wQ%(*~GN2!Q}mRS}iBI3_Ywz8q1rQUmnQOcNn2JYfFzxGB&^7z%Cke(2-Q4 zfm0Ho(`o%ujBOK8C!HT{sXq9?$mXHaBSs+63xK8XC%FpxJp6)FK_ocYd)KVrKdpSh zAP=Jm&^Usu<`>EzFmrg~LxC-87+E5xaEW!~vXK$u$WYLZ`v!(qC}-YMi(7bLGcK>)gj03Zx@# zn##O;AD{3zXnd>r&GV-x1yp@Wm;#4>{MfJJys@B}(szJ}I?_1b#MJX3sS!L#HQPw` z9n+}Q+*$?rU<5J0i!>kG&dNMqRLO8D;s_Xzd;O+wIS(c%A0W(TTqwm;fU7H(imT_m zVrP*`99a4QXpR+y{}{MRhS8{M0o|zjMjDUC9VGDJkl1 zf;@VA!KUXJYyg1%br*=`Nb*#s6syLjQlGVGh*wOAS6pRyx zal2mMJq$8C>^@P|kZT|wH1JGR?_9vK(RjMJqM5Ih9scddCLF&sYhIE%!Af8!2>pPm zdz8SZoVXX}Lh%Fato2zcuCqa6FXjYwh&JrMJMxmfSlJ+x1p_C>Wm9*Uh-B;yhkM0I z$_4sxcRnb?>sG_k0zPNi`F4O;xxoAfv=$&7udzPQWsUssQc2^@q6-ejJSI|%z}&N z{UrPb@{(4nht+?7qkXPm-kSQnn!S+q=21Al)H7-}7%X;#QTj6hM0W&&4v)Q*!Ox(t z4&@-?=V(4Gh$9aw)SY^gMuNaW*_%>yefkmvGA7>ArcPll82Yg|p1zbHJ`i2Xe|&_; zBf{9Z(14( z7<#Qel4B7yub(OxN1X~vCd~-yxbX~6^`eOAbALMTK$&83UCcLKaGHxIrplj?U&TvI zNU*<}nepEJ01<45O*!NAnJ{I%AlSj)`S3xk<0zv5#PsRlXvU6-huL`8d_nnrfR^Qe zHO`P^LQyeR<6ytoQq!eL2Nxs53Lm4`5XaDGS=4AXC*E(f;I^ANHl{i zuYPaVgyY|G7%Y+O_vgCVhhlFA#6kU1wZPg;V4+z}(#54VoQL5ir^cRkT= zzYaVVxb<{?lzbte?tQ#$-eG+# z%PHR4TuXCqI8_EMIMyBcR!O8f4bwqe-t-Pd{>j#L0>ilP>6>X0kT@Q^?DV;o=>}<< z;E1~=+Ms<-uPsizxLdl>T99-uK5nc|*2NimycxoK-qqcp(>`C?_lY3Zh)j%YL1rPZ zQ|J<7r^(^hH;>b6GdyCf?6hj8bQ?sG=p7oVwJH5ajJ=EG2`Gb5iLxr%4!#aM4mLnb ze+I5_aF zO2zgW_*^SxD>+J$+|zR9$VtI7kY)-7{FOW~iY`6dUO57uP}P}Zezmo(n3VZSW-k2m zEx$t#b~)rMh?ThDi_!Go?JFsEiqyu3cAM8YPBDEhjkJ~RSvPo`VzwY1k~c}dHFr*H z<_q!VZ)kW)Y4t&(D=^EARyd{$oC=bA4>hppa_t}f>nn4GbxkU~FVC5szFWKyVqTd3 z`|8`dp=$C>k?zCccq-@q7j^#~k9GUTkK<8FNk&EyE*Tl2q^yj}Rx(P+N+g+?*{O_> zWXsBBZ<*Ot$`(Q>B(f3rBpYK2S!yVUko!9v~&tp7~=kYxJ zJNs8gUeYVW`xffH>*Mvh)olxQ%LtzE@&mjrV_#snb&AmMe#)2<{IE@#T(Kl$WP>f z>y{6T#l~*gr5%V-@X<31(qLD(NNs{&_iX(F{*()zi~LA`k~ui)F}TY7P8_{tL-21+ zOrDWUE*v~e6GoSnULla_;T=P&`Ddq~<|d9COL#o|hThV4`rWsC7JM4H&rHj34Ra%n zNnoY2n^&tV1D;}8WQ0V89Oee zsn$By-!;OCw`~`A|5-xo{Lz^wz{FAb{L)j$?!B}8cJ>;X$=i&8{!1uE@*5G#$V7@d zWK%!8%}9TXd}J!W)jl+3Io>Ni@2S8KH4ty>W`5;O7M`tBR$Am(Vc=F}L@l+O?XJN@ zXnI2Yk6p?I74_njzT+qEamd^QxtrHORP!w!`hS1hKQeiCC$|Rf+PN=}`+!1fwYX5- zJ^T&8w1i&KHF>me=;H~%rqa|>0&LWh8_{T>-TT>JESUzL*-qM0FR@@XnN{2%I$M67 zVeY-!MIzEiwo@Nebnkp765jmrB}Td=Y;pNDWH2+m$?-c#5208od%8w_Ar|Rpn1*+y zT*uhs$hGNkTY}&Nx#J#6vjHf>o^5lo2zQYXlEbX%Uo)69f zEtsVCeU2W!ba-WDlN&^Qp39t9xpG46TlID<%Z8K#+kBvMijde4fG#%fm~YF{cnkG;dABjLJ!uF?pmut43U7#pQ5RZC$+C$k;di6~ zujih5Mt-@8_46G40A(nk5^hBu!kfI0L zPfwcSivk&RSBuP^0D)Dj&%o}nwq56CEK8fvkqyggX^`dr7&1PG?2K{rZ7);YVmIgu z(j2uiCt>p$TC)sVAC2z50FwSh);8oxGu*+ay91U6svx(R<;TYX zK~TU|P_^A3x`ifT)Zh_Cw&y~X7mHj*Lp9a!m?{w!`Kf00p8{09n`dw@);9ZKZ{y(p z(lb4mW`w{f5|0dhy6Tc};k1bDizc1&*GbP<&@KjE#B4+DsYJ_slkjZS3{lSY5PXNa4=9S{w%T60e1A z?m#>lhWmFr^!qC^3ArbSrM3I=w9>Q+(~s&^eiTo%`usA_dD+5QhZc@2>Z1fpZ_hw$ zhB!{v%_qBG*k5=mAdhI}ytH6*;C8cPT%1~Y^{_L?{1L8t>;buqhQsW(vO zZH@95W5gJ`H^dI(njDe3XKIeJTl)rQLyI-mg&1@(@8k^`Zy z4xY7QidpHcrPVvSIv5?vbtx5-aixsu!7>>(;`;sOSx8YG@p-_W4_}!Mw{3^A2BVd> zI=$2K%yfDcqjQ}gWh*#z!#J9wK66#Ljf-=mt(Hu|J@+%Yk9U!BmT*lJV-v=H3KR-clM| zkx0X_DVwIVNAGhW2h^?W+^j9qx6)tXEG@h5wo-3b&HcxuZ>jy9hx1#-gW-*YGxQ%> zcNCdl?Jk;9w-tz!WpaIQ7qJs7z-o}Je4oP!2at&-u)VG;HCwwiaHjYK)Ip}QJq^IH zF{e!S{ZeVJIwvEG4NWq6qsY5&2Mij7Wn9jTC}1fYrV7OL$Q z>%t%7a*8{+>Ee-*&u_)`V^2?t2`?^mRB%S9Zk=&S3_F~7gO^RxP&q?cFNVYHH*`-< ztf}8QH^QIW&C>OqxxM2OF#9O6Y^ff9uN=I%J``worach?F~(`V3i>eqF98f`)1YP0 z@1zRk49wl?;~tBqT?%{yesZ=GqQfR>V{3c85lPZUJnnh-ju%D3Zz$lU<$PI#~h+n|r&l2OQ9AMp- z2h6f?NRyyl{z%D^2{F4yYOS5}DehIW!K;=PopzV_bkWx zM6(rZ&aSghw?u9c%tL;`qdvz!6gWu=@h?3`I*U_e=T$@SEW1INQ_8me0n9{>sks#Z zx$q7$tUrUO`b@>LZulfrA`XXgU$HlDyoEIQgZT8syO{x5AST|ig9HnQQq+F%+&MNV zlWA7_?1uz55dQjxh=O8$5StNTJxhxuYn$KGSv2m5u_=;|fISI&Sn2-STf`({h^ES0 zc_CiaMh~*jo)@!Mx=Z|L99Pr=#=!d9;F<1J zHm7S9yB2l#+O47*P}7N4TLxViSJ&p;AnXZo+1-bmt>Lg~(5HYaDuy*O*rB+NF?ZX1gn%U=+?ekcFPZB*CG%(^mmWrNgJ}%R!ab zye^L;^z5pm0^X*|-Sl`CL#R2A(Ts^M9|*4=i7#!zTn5ct_a(6-Yux?ve0X5nM^XBo7R{k>0RQU-xRM$1wsXK?0WjAMKvvZbMYy zbe4V~N?6Zz@k47;{#}Hq^Ok=*JIZca0;n!F!B{8-D%@HG)T2dBVJCOQe||Juxz-|{ z2u=Q7#I#F02hM`oC}n3hNpyY!0K&U>*b zqoOIOD3E`nIXddJ&OSjO1K!xn7*7=ye^u+I-B?yx2^Ga1sz~*{xPorF${jkN`t(8& zubVYk^6iagqwW9(>)Oj#U$V<7;Fog-%>nBC;K{1Bt?4buPvym^2t zO{$C=4!)RZJ<>qXw;?z+P$i*1Ou_Kb5O6&-%)I+EAh=62pG-YjfTJ@iQUzi@Xc!Ml z^mY19E?|vBQ}$4E)frd1*FD{}5VN)(?hO@O@L3M#jKbE5AKh^q+2-|BQf*c(Y8S;u z(%o}IAA(^6?MLl0TUQ`LEfv9j*T@thNNZuLrz2ZYokZ}X)%~LjNn)Q znQ(iz_VPTWI>7*1KkYm^3M`;7Uuy2sfXGwkPX%thuPbbBq_&Ck7CG#TE4)vH?6e-| z^KRI1dz`Z94ppSWR9r#-?+uUR)iIhLjcbImE=LEgOUU`lDcM`rde{kKgOW{}ZQDFv zKw^x(Nkxwmam~ zmlvx>Ae`&A zyTebUQZNJ-J(%C9;YIJD_R8kkEE4S}uz>b5V&Ww*;z&tE+ot(s3zu&|OP@IM$0eF&*G`OXpL)?l@@bEvn)Gt$1=d_Fq9+MXtf! z*;) z+?AYy8)2v+yLRT#J&xyPX>205PwUxAI5-48~ciY4fW4U{vbN3gRf z-6d+)a<*&PPAPffw>g1YNQm~Q4FN`v7hoYCa!b(uP630op1HTi<~h|W2p4M{KX_ts zG0}n~6#Y5~%$9;ojx>Iw>wkQCk}ndcR^od|$W{)IEkSnHvZsFN=se~{fY&0BRacRvuf?b^U1{?2+>^B9{T)qO-~tm&)lo8G`-%SkG-mT6|@Af1CGucc$ik ztMY&cSQhM#D5xQft%zW~18j#RJ~>Th%|Qw2hh^ARi;`Np+FEzn7!f-(tQ^%*z@io2 zqY+tsGnun%ljTZZncIew@O;yW4Zr6ykJ_G`i4K11%|AYy*9an%cBx);zu*#xjrcH9 z!$)N+kP{akPYll7Tm%1lzeuOGtujlyByZl3$MCT$+)`D@ zLD{^?n8JX$;I~sk9Li;70XO2|U%SNfXQI8qd4GvIX-e~6URD$l0#61h9Uov)6nPr3 z^NKBNr2g{zy9C>Zp|)bDUNdhrzh?aUx@)4*t4vvfJ)=W(a%t+%u{SZEoX^35zpiqZ z@jt)})l1_#>bAg`O@}kMz7Prb&A`?#k~=7o*h;Y&jy~zYf6_}h zra{a!)4Og%e&=k;KKq^8qC}^%=lMCH%pG3MP3;bLBtNZrpF@PO{*hq+%}39ksL_)i z8>^#UwKC7;{D|=lYXkCzBNWcI`*u($+745W7JxOJjMpXIIc%#{=~ANYJY9I^;>98g zm3yZS`#r*=?V9VaBxsg>)GY_AJ?0=~Gg9fubQs?#wjNQKRE*V^^`etnfzz4wPLXw4 z4O-eWDNpgY&ivm^GRqovK##H1Kkneo_tzA^fi&4Zs|R_DZsBI5B4k7$x}q% z$GhY^idCRvo*_x9;w;8+`i?RLT3HG}DZ49ay*pF8^!(1n8S~3db$$s+wt?a9tXKR} zd64niM);lf9Yz5hQIdRyx{C81pk1x6t$dBL3@fRWv{Xu_WK+->FkW2R5S@Y~yZPtm z8318nTf_Tq7v>O-P2NZJhyM(pvyQJ`>lg?NKM~vNV(>w^Ham(UJU*ac;2Y?M z^wIN$=5%E`lR3J7KHRqJ6=3c|j%v-@Q|sxZR02V$2+8!_58w)7i11Q|nl1}4YMU0` zMMLnU1QzvnwGR{BDX6kst*&ERl}V4XCvb^9T=d2 zO2nJYfKH9S=7~dl@@D;zjOzZ4*>0%jA6b3#+Asp3I*Ug%$#$IsRU+v$YBPwvX$}tP zdslEfK4Seyh+Ch3TwwW8YUzh=`7_IdUEbvpTd}Mp#+rZ>u9S4j&C^m)CZ7}cEqEXY zSzfQm%hJld)9drCf>D%C*#kA>W8ZGH&x-QC7$nSZI2}$bCF)~9$l*0#k<{<*ZP{?+ zw}--zi+XH|IX6sDbB|~b44k>1T*+8QV#9`y;1I616Bxm3vHHwsJw}fx1<88vD^@_G zo~XDkalEAbloGW|IT*yKdD^`x*)Kdb6w@euD|lYlK6vNZSWx&u@u#8S#JRViaNQJf z-2Tahs8gYwYRMlaBY6<_7w8wXxohJv3f-I0i9>%40EcUxCe?Qd2-emGZ*DlRZhnW2 zTUG#MdEKF`YYpb}K{=tgc)Y|ZOF0>;#ykDreTP6n@l&bYIbpHJ>jGonpybl?_NHF> zk0HPIVoN=hgv?|JDe7Pt(TEqlMcu@)?#i3}EG;A^`oM#=z%p5T^NWFN>yqP2iLuuT z^R@)_{DMy{@>P=cO@lz*q9Iku(s=&TQ6ag}N$)fivb)B1g3WGT5aM%)7?6PM@6sa+ z%@iHCq=kuhN{r+0`h!U*q`p5mjy>Dd8c&0b_s^6$@eXJ20!$f7v)61J6@oAj&1Zr# zBY1J(H1tE~^3t}r@4tRoB6~kQgcAKCe;o!wB3(w%%5q;bH+_3Z`u%!!WneCwmhP=UgpT z;UF)^tef+vc8?8VSHq^S-V|KVE<2Og&d6Ra=(+}n*f*o^s7G& zZe~$Y;SQ`N){Ows9x2 zD`C7kT(D)qz_n^5lUT>Ve3$TinC^o*EjTsv65nU*Tm`UR>tW}srO!pPfR;Z&N+b7( zNHWRRajTPj!q9SY@~mg&?FmGwL%bQt&1o&#cH6n+Vo=#MQzX3x;65X$QFIaW_j*H$ zwDb4^$%9E(vS>qEOhe{#KnIZyHU!~CUgfwUKfcU0<-Wvg`$_jv1B30>{UVmKZ3;K0 ziH*v-&XI;g7YPLXlnjoe#RG1^ghYGfVBTq#inBrp2lJ}L#@Pw~6D`C^8m$4xtK7kA z%Fr#|i=~?n+6x6AI|e>N&K)Y)exn}U>h(ht9)M>ALW$4Vxdp&aK5+d(4g;>;cA1;8 zjkg{g@2e83<4lQtT26}n zikt!^9)>u5k3-&t_K1F`rTKtL`<3iG#@7P{Cc!Bu1<0NygE*(!p*?=-lE55D)s1+$ zU#1#a#Gqq3l&aFUm#9XmEwIgGc+r5|?&8bWgfkgRpCWSPM1#WS*m zC)V~G0mP!>bhvU63}luB?2H&EipC`|FRFJ{x?5Hr8$M`iT*93b0+VftBm$v~k8*kp zd7fmhib^y{ipimA+5WB8P}xaNek`^WvGS==5)k7h!|BsOm{%uOj?&pf7}{x%;^#=$tDtO-VDNzJl1 zK4NRt4dJ~|CU*0r>$_)X+RGd)TMsmCPlehZOVTrPh<_dshraZVMCKwWBRD1jD`XlQ zEV%~=!ul>@&8_jeV$m31Mlk%XWiq#%zt_?x0p425-61cV)SG+l{zxa?M`V<-aWicRnr;2Sz8f04aa7Ilp%gb_>eS1k#YjQwI$6@LN^J?u2C77qOd-PJk zB5K^;KIVIWv~A>3sbKWn>bVP~-@#8$UE8x1 zecBA>F>oG;8v#EP=e}8TDOI^9`$vpJKc^+2s}+o9%oO5le!v4~d1LnRg$mRT%^q1m zM}dhj#9{YOp6oLhaaw@->oCxG(S!`ddCe2^-d?`nN5CgYXIt(2kTzxi9X7wW+>uD; z^h(Il2+{6ak`8*9DyJ;^;Ns)&frv&fM}W*u3^e5s&3xTqdiG29C&QT`HubE9=`XAC zNwmR^cR;X@_Gt)30GxEI0@Znq`897qh!=BksT?gd5BB5FgkNjkitzgkZ+fYfEy4zF zgZu^*`r850eMZ{GX9aN*H{z6)BJ6^3a3=R>K-oCmbq3&b=2e+DP06UA2r&pu z9f0a9&vwO#)|&$?twW!R@5S6k_>eX56MXAZuV3HVn)M77Y3Oik+(7mn zu#+QD>dWtrA$j7qGC=p5W=gSjkkgQWB9+cUa4Z!IoZ*!q7fi#}n%mTRHwSVMo^2Wofdv>47Vo5|~LehJh#ggT$f&}{MEd+;!V zRSy_R$tnSZt->zb?fV+UzeZXC^No6=QFJ-wa|&&Im=jU9mnb)0_6Q5hUc7CwtjBvL zJDU0^rwaA~ju$cIrnmX+)G646#n~~)lGoN!1XDv;zz^r(Z^9Yxw^t4W@@woDrf-B) zE~u8w#>ZN3648F>)4=1N5ITR`aTdY@O#==x{ryt6eQS+{;dZ#WT?USA+0g3YFz5;B zo4iru*ScBiFv|<1m3-gKOKCxwT7?Z%OvmCt{&Z0|dB)01ap6QUgvBC*cSd*OS_e^w zB`N)>y~NLiTHA~&S{BATk^uhPEX!2(_quM|{_SCxD_HStD7d~5GRUK}AZLr-=4-Mo zA^yN_g#y#MIJ6}QAT=&YQK7BMtGhc?cY>Ho};D{^zvz_Ong98p@S;{t`MPWa~P{%2nkKm_}nLVpM&mcn|p#~Us3ZuuQ6!>DQs{+1HZv*VpC0A4p1TI0Ez6KEPZCz zt=t5a149UMvR&!UqJdi@5FuEZJM2`^7CpqhsdrD*{`mnmIJf;T|A~5}VR8oqRX?!+ zv8%7xB0s7Fd(PQpYy0x6tcw>s_l zzu7Iu61or+!g(Bd|WF+(2;r<9ti7LbonU zx3)vf7_ATDr{klNQpp$a1Qqu!DZ@zn6lIq%8vs{mlR?>x50e;A@EAhfUefP#`4W5( ztr)Bl9^7bZJ`Xj6&_#oT`PnubF8R>qkgehenH0BqZ^3gi(L3LsEv}>-Op|u_Xxnii z?2&7rB{R^|By3!uIZayjCa-Fu&!Tk{s9cI%ye`~82vl2ZI?3amU(I{)M3rrz14_uqgUgAx?5n+DDzdL*d(r)D zc)fK$?F<8#B3AI|xM4tKta2X`)GgIYXJjV#B z->D315T0p-yl#3?W0%UWN>lGO4{Q@0Z+5n52@d^zAv}?GXG&^MBX0->FitQ{!+8;|% zmczkpiiV56p?QuQt9J?Ka7U`Bghnn2kG#K*;|@IDy|{lan%wF%{T9+vmqkeOwIx(c zV*LQLpP!kwu5825b!MA~7CJ57N>h$M`+7uG@($r9==`;a)0}Nh`_s>ckZqOcRRi5@=>lgR& zj3D{3OQq|F+pY_)(u>vM{ndX+AhN~OFBZ%Bot zzGF9v&!e~lyYuspw<^-}+R)!LI73xpM$xtq902szx{eH{h zBY&u5#8u1!FEebvlF*W}KG35OgM5+woEinL_|Vho8`(9Kqc=HQ#n&=V0}^wiSg0zb z3S@(&x09d$PFvS}CPb9|;&SFt zHzSOXj7~v*{7uKtfe(~&gSoTuOs+n9K;Qp99sv$rYZAzT@=$5gA^o0^I+57ru00?MYcY7;|So;P%Ghl~CKUx1%%jG?-r^N|dKwaa&Y+|sI z??vesTw91JTF6JDbf6%1{~+WTaU}@pxL2-!Vum_#>-W3_#^gz|8x+~DPqN46kBG#$ z%+)`kp}Nz2SQk&j;tiUvCwh%It0Lcg)Ww)$2-z5 zXAA=lekvoce_4G(k+)iE&Qfc zoW(x81lquLOSeIfU53E>TPi)_Gl$aEm#3D_9DR+Hw2O!TP)Z19cerh=8299v1dpwU z$GJcMTDm^TSBYEca{tbQ+vwKo*9i>z32Ii;yc28+U=ZuoI^tuH|Jt@j!lxZ8?RP%M z9h#!r?#iQr>Tx6|4CThYzKYE$zA&(u%`d<<*WDn3=wV`=0r6#0uG==1mfWw# zA0|g!SZtn#>m}<>njnpqKr|MJe>IdsMRk7X#ai_k`;}1jd|+=F%(k=dpuAdrdYi-+ zgW>+`?4yMwT;JYDgd2W~_$KQx))^mjx;?(a-`&~Emf=_(7xZi>52acPNO(IjZya`l zVsekJ+5lauM<}#Uet0{v3JKNJBG|WAi|jQ6Zfh5mM5hIu-E)a>e7TD?OOx4UEg}M8 zXF{O&Sr+hCs!U&I^LeJl*YLosfnCL@Dtw4a2id<>s9*jS6W-agWFCPozKSj@$4A7Gx{m z)s>m!F=*=h3a}5f&9#axVo;fPsVJv%Rbe4t`UKE!O$k`aBV6N~He|(a!`4HO52U-K zNe2QR=7Hat3!5d9GinSEPRpreS99H98W*@ZOk6VM%YB%~YyKCZ7FjVw;n-p!?gfnV z%*?)1Y%owUOeo(!a|%bgyO41y-c4Gx@zLNxlW)hR4 zx1$P58upQ;&p!77o~qGz&s9^WZ~5+nfNwz^X`l;()w>z>5aatqE>jrbskOg=yR94t z0>9ViFzwz27Xame!Awtl22LM2LzR`~7Us}-`N~7_Cd*`mhywTAFw1G9M^ETXh)RM? z56iw?Yi4|9n1(>+bHks#nNBtDah|~mbHK!c-Pf(p=3;zHtP-mx1s-6pQT>7ff98C! zTi=kDffwf)s#!~31^gKD?mBLZ#VCB0d02iVx=k5y-(;N~D*jUI zUjd9WC07D44uKrN-qxng8V5m{5C|W&8fVMr13rSF!$D^$w;!K(aYAGXz|Xb0;d*N@ z?tNv^38}!3MH3GaQ&O&u472*QgCTMR7;D$(n=2c*3d*VqB;xKIf#o1#|a` zKY=Rl)r(skp5MzKVh-%sS{MvqL<1#UY+tJze;Epgl|2}5l)X~Pl z1G2O{s^AA==^cU+`lm*wt&LyW@PY8IFz4kHOnx4Z^_P~V|q}j)KT1bP!8m2`E zgPAr0Dn-{O)T=;ZlNSma`Hce*yP~#(=iRS#fLV~OVFt&0C<{pYzraxZ^+5meDU?)V ztZO+6tvO2MwQ{d58KJ9F!VC$vpr)A41340FHf}8%@n?xNp>aF;CTgZSA9bp^cNTXL zYtdvOMa5GFEqL}T&;lI)K2x(pm(0NfIvNa~3yXusMw+~m8}2xlZ`<`hdEnM5zgvvV z<7waoIbT=NTG-Ka|FyplrPy@^nQb0}gkK3@T5OFgrK72RLcAfZhSA=THWUW z94Z*u_0WL|=VB^e?GIYr7@yrqV>?OhBLW|~-n;%81rFd28e+wqGqWzIUwQ&JuSZtf zaU>M0$2egNeLcQz6pUtbxWmHG1JjdltOzL7)X->440oYvcTx8SE%NW&h6yY$#{^8; zS<^0Ogt>wsQq5)1mwLB|(D z#HSko;<&I06w}_xmTx{5>%ipG)|>0ywMqj8OJ0az^8_z|oGJjhH*&n^l2(BEikjN& z^`$Siz?ZwvM(2Ax*q!5znczIoOi=4(Q~EmCS?f0k!J`5&B&xT>%C@kFTaGs(@nSf_kdoi?VG39v8DyUIA2so>jE`b+kIp4MlnF z$SThtUoE^9dMW)>MhGjXnZ;i<|A8VJnA5jId}ns%zaE^F9vg3E}rFq z$?ip>SbSD%x#qW3V*V8n5Tr=Lt$aW)dE98f)N#u1QL+F^P)H(ptZYui;Ng6dfUet8 zN&phYwkGHb+TPp9X zirtLq*yhU_wG}f2VHyAj&`Dq_HtkkgNV0FK&uHCTnjNt8RERd3G`6RsK`j(ePwy*f z)ZIrTCG512y14QY4Cd4qppjp9wI6kP*bE67j|f+OI)|4)vJyGfXwk<1B40_2Lr$Wd1HJ91&=0?!)R1UP=D;+ zx*<7aFDvp6lCrhK4FM7VzitS=*|h0cVGi7BWJ2B4;w_+=dp2vZ9tyh6*EC!5>Eg41 z63?$+efMZk}mH9+KGiH@viLV#haqXa$WWpi|^ z8sNpbqlZR}-RVw&{z9y4MH9_VGRC9eUGnUAkzmIHpkr5yCG|&mJTvtPxPTYCMtxvL zr(jfGv;^?CvY$L@uGv~f#a?Vgm=O)01os*hvi>}5d|D4ozymUPg4&aT%n+;dgV7C_ zhwsidi`RH1zd`fheZua}lNv*Ai*e|z5Y`IEYLgKO_#j=3*ibq0+7k_jXovS=fg33E zCV+w7T65D<`u+aygg_cL&6r9cp0=f_uh zlV{%jJGBqYCM~GLIUE5`aPU8-MhbO^ygG(AH4oQsBt5uJ_&4*5MaKUwnoR5S@U9z$ zZI4m7X7|&@xdSCL=?ce7cxmO4FvG)6rnc;6B+6*oon5$DeEW+G0vSTMuPC8PE+|8U zL;571$c3_zJOCzF0CE@x;WHGmYB7^<7@UrlZ~X*aI%9ogi_;Hjb!?wdaVTSMQmop` zx_(Ir2*O(4e{c0rHwPvfSR>H`G4DqYL7Tp|Z&S1U&hyLqT3SzwiPjW4;x0qCZoVq! zH&B5t0p^APRnB$}uP}HTbqqE+;%jO=q=91&({%j8U;IyGwoU_)mZc?p!Z0PBIe2lh z+plX9iXBBV)@_3dx$+XT9j!czPf>L+pu6?ZVv_JzXMg?C=RCKGum`1%XW8Rpm(*kb zj$JVP$aJ{vP&r)oL`c-0u(@NPLZre}oh>a7HXJiohSULy{(Ij%R`)~KfaWe<{ z5j9yY(uTi~RBw)m^<%Sk=-7=Np4m)UBz}#?c^9w#g@OFK=NM{Oc;Z>U_MJO|)G&~} z4^v@5B=dKYi2sQ-84?bEH=s&H2yzteq54o@7p2`fxX<*h4+Tpi_#Ka3&(V?lraTDM z{`|9+h$Uug-g7qg&fNh~#yR%OD!?sBFH1d2$cdB=`(|KRS=JG}IK`jO`qKm+7!BVy zD1RXJohkraM$@|G<`TboJ;a4G-#-w|JVhGGW`4+c?|7-;i z{$A{Y8CI`=nGP7GVuuBp)@4S#D8eVv$n=XkAeQ=YN0C|2VL*Op7)VEo=uI0Q7{@AM zd(|%Ipl%T!L}DZdGIxk_(pgc!wr?sOLgO<2?D;U#n=MHzHsL0Gi2CK9uio$d^V_YT z@NcjeW;De2^B)T5AbeD2A6()WuF)wE{e1-m1yX5ri(tR0C{uOHihyuFaEl@#K2iDY z*IcLoSQEbm(FyYBum+#qIz$lm{wm^kokT_a(o@`jEeCzzL!>Hne9cpf8Q2%Fm0r5Z zkN)*1X`p1xmT)BjgewEs{0yfPuViI(PSlT4r~PG6PjoULUCm*-W*j#+4dR-(_tjlg{g0C>%dA?BQ{L>J}NDfSl9v zjrR=n4`4_-vEm?V`ht+D0l1>qVy@s;>G&PT@~?%~)TD94rrWKBg)!r$K+31%Z{jvU zxVUcD zJLbVOsw4hXK@aZ+__wE7N+9Nf-Glx{=o|_ASyJN{_G^Y6udX6QOgd=5Z$O0GB{1+O?!Y4dHt|{;paXs+$+UZK)PHu*3L(}u z%{9Aq`|2_r0HcPn*UZO>ip&OhAMaz}wV~y^eL4590#On)&}O@4!UATfe?XjVxIFVI z56JAArM79%*!cF1P#>-SWcP@;iIbwMGd&4$Dp-jbXqNX0N9JM#g0)F`xHEqpDoHLR z+2X02NJ`8KZAT%1WE#XSg=w}ask?G0{p{D--pU3)rb~F)FvDdo- zo+TPv+~50ug2Vr>H{=YJ+kszq#{*d?!|7MLaBk5+MN9MlAI~kamCkoDdnES$I`WcT zunT!h*Fd5iDFXTy7yVyAQ$D`%Mya`~93WYZmx^WGhp+Gc-eoXG1Zc^&3I$BBd!8FU z$&6V@w=2{Vb3QVdB^mm^zt>hN{6C<9hXztW^yKdb*QXB)zL%Cu`mbZ;@fuEHP@611 zK~xyR9aBE{^EA|fK#)S0_>}ZEk1^;_``-1>R;xdY_VI+TrNLoC3TGeb$3^Vv`?bd|36Fq(|mOeK;YQ!6(%) zeQl&>7gNak%3M7ecbM~~TSGMSpTgrBSINF=QI{k8#r@Nt_Zv~+B^rL;Ybl+c$=Ip{?^@06@e|@o8eSP~#8n7(WEku(ioUr^ z1=V#6#puYWw^~qGr?RAL|M9Rr&J%6^*l;Xl&j;UXQ*NMgiGoeW3r1?@Q45c^u^qdVGR$-AT9l4GWD?XD97B z&JIaBV07%}wgQEPdNhNpfAOSY!#m^sMX|bse2UL?%bJvr>nCfs| z9mCf?6rZCTp2L1g1`stV-fZD?%0BvID*sUUtA~GW;+CxfsA#K!r&1-;+f3+mb{76xog|4abgZfE^pYVf?$HM%9r20 zU;;<{G|&sFtG5K@)%`+_Dl!^|uOS68SpsOHp6^BcZT4Q%<0`T600 z-9a?R&|e(FEL_wRx}UaHa)@MsL0nbFKMr#w+UnletIvqUF?8iA9e4;;5+w1tkmVzi z_4K$7FYoO$s>Me_8lYcY`r-9|J(6;o2r--Fg{k*FT&IBg-QM0_UbzD={le=3NaBYo z)7XPz3KRWqWu_AU4wa#l^#VQ4RWFRfP=Dh4pW`=nP|6Nwz@cu4xsbUB&H4jP^(djx z1a|oQAVSnuX|}X6ljgQ~d2U9LFWHcOgI=1vR_}q`KfgLyI5gEeJ*482+uGt4ByxK` zPF##8e1s0($d3qGEDSfYg)8*WXjaZ}3(vgxV*PyQh5ux_CEzX%7ib}BDZQQcvu}#{ z^~Gn>t==OsWD3{<&_wPj7 zr?A=&rohjii+#?!2F-a`D`$&ge@v67Nz6tk)T$#z}G+xXQg}hQQdM47%gg1SfQHkPQBJ*7$k>aGsExF78Iy0~ueC^}xziS^cI#s!7 z-ZuX5f*?Tr7v12^)++tZ=TN|&YggoBvvo~71ePnj8fcnQ_bpK4F*2L&f_mX3ezX^} zWu%m^0tII9_8&e6KE{)LO-SOx7h6(w*)$^>p1cMh7BSmdc*6r%+^hiOEmO2 zjqA;@J~!Pv_&W~ywHuN_;O*+ijzQ~${irI;fW|M>r>wf7f+^I*=Bw7?i_utTLjXN) z=j^8j&pJ%|?ujz0wt%SN$uHh}!}?4=MXZyOBoOUTd09QA{I3(6N?a~v7I9i)_+Z8q zf>IDI*<~PgOCOh&P}C)X=cHx7HuT}#qPD@E6HB^YZ1IGuzU0^XeuuN&q1;2Z zyR0>TZRjnJub-UjGCkk+YuSU)cOz1e0K&rgiBl>td&DOW4PM}MU0rz2eQdo=ynP~I z=aQ3!Cd2?&ou1nN^bJ2h;vvtssk;Po6JxYl3bA%wnq9{3&>tf=rJyDXr$NI5xI+q{ z6l4h6km?Lq9VR%$7@dz^n^gR#N5ETjQ?yiZ2$?EXKKT9m28QhKT;Hkj&t#1+%|IKp z0&w|};>6M^L}v78+5zHwM;xIhjmWY{o@O!^9fPqWt0SdPl>I3H3aAQXq;t&YWegRFi2DUo!(aot&OpSgdtPHIz_|K>uJ4)Mv^n@4{GDlkWQJ8L~RhTE9^( zHXy@bW9ygI>vYxx>sR%{u5Mf@R?X4wdo1wJuPR6FL9H0xkiUIr!)l@FH2X+voF4Gp zML3}Vf_U_EE4o}Yh&_{94aEaPke<%#S{A(yD zJ&MOLV&PbvuClWhWPi}hH0u0C<{bvIv>}RhxwXEV9nC%a) zeKLjKi;yT?&o#8b)Fm9*MJr?8zM;LKBDOL>ky38(Zr3(j1x3aAbh)zVzhrhz>7nfB z1^NBYCE$*^ zsu~7x>-%fDRc-l+L1I;>a%1W0q@+eh)tJwew*~DUIQASz%dME5jCe_Kj{e7hGVRAG+>AUjiui0rI3;j5)Hfc$2_nmRUe@jtoMBsl~pP@N2KDrLdXdOYVzM&y1(xDuTaEb z&-y^#NM5a=NRbi__(*Ae1@Z>!AzJ?dcj1M1P!@3?8X%09sfhmi19Hr>g!qVupmhR0 zNcWJm%gjsle;gR}@Ij#&dgam>pjhyyhvCn1Bqvap@)$UfH0R(B{@*Y6__0Sw_T2H4 zNd2JZkcTAfn+Lnuzw{4S$*Zk5!JqVh{6`hd zuav2R`cyQ7B29g-e2&(YjLv+ATm2Ubw)CpE{H}zDK5XQ@CS-^k|GFDnult6YB;0v4{%ay%Q`K1rP^p;$L5cD| z1SRla?_rEfP+Qy%71hZ%$tVAO?ssZpBY54pt=9>`S@#r0%`|`6J=k1IO$;>Ko!|JM zyQ7G9#~pSji$1FB&nbk>N3SE@dfi}zWWjw7B-_Xv0%Tla#04?>rOadxNA7ghPNF}z z`qyQ3Av()ITKhg|>!$r{WpI}5@ZmDsnUMD-X(qdWhpUnq53(Cj}TM?VpwX zdUNca2XH@4w*Sxj37AFwm?GRy8?_F~-}?gh6TL2tbL(|mW$b@#o5yQvVg~`L4$A-e zOc1Wt_86YY7q4XMzn@86{qM6fYEK{|RX^>pZTdfX!f_&NepvhN|F!m8__fQz+Harh z*z@<=hYjJGU&pV@25I(wbldgL?e`!2{2p*6Qs82C9pn1D*Z0pBvTkL0tUf{Of+u+X z92lP*Nmh8>(-Y`*u~7ga4S(%Vnf~+rwtj*OjsA=VxM6>_68~Sl{f&h9F}Wk2Fhxq; za^+3B{z!XL<_cK=miPSjgFv)*&lE@3X9Spt6_Aqxp;cKUM=~-TP8%*NT6A(Tl-!?pPqN#?9|%X?F^a;6BWBt(H_29F-?K$W>=We+MqsPP)ihYf1wH2 z!oGbjX8r4{2qyl@n3cGQW0V2MC?hpY>UjNo6L>W_rT+vHsItrick4C4Uhg8F_fHuJ zl!`v2>c*}VwMEI!sFX}CakXKGx&%{9Vy_7s~0+(k`(`@l`&q5CPr;b%*o!K zyS$BVqucmOGc`NARsIADzKgM>3KV#d273U8c0V_QL%R)NIQg-Zl2Q9;%%jo@PpaOm z>(y_<&IGgXAwI&N40AT+gDA&r-M!MYu|H4t+sMPXD;Ecu`a+P9amzyD>WX6c1Cn`} zz!UoVua+1uyW!e9^9~;#(Ps2>se0@5&`;RwqYCecFHi{CO^ad>Grzphj=fi276Hzh;0> ziT!41^A`cOU|x_T%Sf)DeYmhIS^A+KCnx8_tjkuG65}c$5;Mz+1f@ZTyOG@G9Zzq% zfCcW)=${rQh{+~w#`JWud>1k+pZ~3HQ+MIv1Lvk>8F5NPJm^f{z<&lTNUdkOR>Jnk4Xat|bVi-f{Lk2oow&0fq-}vF+y}kx@>YhO(;0&hFUfKT=sQVCm9Y!5-#$4Q?rt?eERUARmqr!3|e|;1GAj}n5zdy}# zyYj!*R|3mX(md*UJn5yt&O~j&1uT703#z2S8wjG~2Hbe?Z`+AUP~oMG6-`{{JE8 z=%jnRy1KeYjZI8UdZXRk+#>QEv@g}A^WMN)yTu5ZKjB8BE`tuVCVJQYi>hsVfU0WD zvSwu?v9yF=VbVZk0yAd@CAk3M>G%^~e-ZV}S)dQU(>nbhk_=3$1Fj~tP(?;N(2u?* z{3v`0(ZJOAYzKh60UJ7pY16viAj~hG=Ab^Jo1MrsL2CK#G1@NBa z>HWoBxZagK(zm)&?O)(Y0Nfghur*<*zU7z2PZNM;<|*0qUx4VPY0wz{a%3A)D-Y(9 zP4Vl{zt-!;3+2HF>iN&we;LIz1gtkYtcnX{I-Ig*^Xt|QlWFgwP1L9*O`7t5-rK!r z6K?{#HDGa+F1YUeTUE*X)j{Favn~pL(k{4dd+CFXOh^0A53{$N(pZlX*T75z^L@3d zY>gSgsv9;|68X5Xe!mv*z9>`p=3i95Q|yS?zngINnWQI&0s$EGRU_cW)5kw$!Vv|2 zKJ~YPe!U0KawQtUX7oR$6Jvy|7Yd#7&`UbMe1R%rS5kWv|Gah8LwZU()l&3|z~V&X*l;C?B0n!gpH6 z>ubmM+VxbP$bD6bGJih7-wXgd_pi+>lgjLXVP`tiLw9`pq#PoAW=%5H0M zYzqTE4b1*xH-ucIYHcRTaciJ9{Y75a2{wEawhBb8W6gsP{l!r94>EXo#p@prd9lxl zc%W)d!hf4u%|AFI)+H%{?N3@^{-Nq&3Sa345_q!H1_s-+}{{N^ncl-+j(iKF` z;$T|NgZtNq8RtP)?6PzOLV;e>=H~K$if8y&60rqu)rkq(C|N<7z<;#b{=KjV9T>w) zS~r$zlJHXPkUcH@ezA(PeC)SRI+ecHqIbcf2Q@9{PlYs|W$}Ja#qz13GE}^XeCWxEU#icV3Gq^V!p}1(I4p_c z7enyhz(`PBamA8l_E1JP@aF$*Sjib7c!*KglL5sX1JL6(&##9gPwZM2~-Zwryugg1=Z$ilk7=&->-VxZ=aaH5T=#v>FKp3&ep z{A=L>=HWtHr(wN9*DZHZ6)kf3t8 z*VIH`wP`4ZSxgyaABK9-d#dICMIoTN&mmYeAsMA)t8!DAXgJRxG0i$VtBgAW?1e*n z{{q&SC1+`kik&{hX+fJNyZsEoCK0t%l^T&0PN)mpo(d)-a2G8Kf|aJt5>*kq8J0|c z5*HU|*fBgdM%7vHtt22+&bA$d=4?Lgzs)2al4y^9jpT`xRgwRnWF3h*V^ToYB|cXA z5F`n;8&sz?{+?R@X~2owP6%cTekX&fJqC`f=i<7Oetk=+K;Aerm(y^>@%#TlErbOL zz=ESHHtD}u-~|sB9lgr9jIcoAjqhJ92-FV8n(?l3-#n9(7soUBYI(G;bS6ftY*Lab z=DW#*4}XWlax7pAG%nG_49Ddz6E!{>o*fWdSU7tCUbB7J1PN5#z?3(v`16pyYVcfw zwX0#y&DzMN#o=|IvD8#aJ~`HyFa0!sejSAlR|Ud6zeyR%IGQiYMj#5t7rchiTa?$c z|JjP8N64VGaC7+kYlBg#Rci7`iP`Uyr2*dr{NC7yofMHZU=$=QMSLLU8WO9F@;y+0 z%g}B~Bz_wBt$<`_R^=>2Ds;Kws*XS8$e5Xxo18Yo+gz{dC z6PMn66K;y&;sdyhH;8f*0KgnZa7keQ5@7dN{v%xdT10TH;|o#kH=pdQ9xio79T)vf z9_F;lhZA^dQ?wbfxg<~Qr%ZMva)PLtj381m>Sce&NRMn6UJ+$}3q}ozk?1RK;C)BP z_CKT#YClb+qo?=Rwp2;1zHOuPri_#oZ{XJA)=S|0`7f5;K?@-62R49}4=h{M5LY^Z znCtnf!l{IE~`#-{!Ks6MlpG1be6`amezU+2-1vkp^NYE|K4nOh`>8Bdh9Cl)zeG7r0Qjf-R|DdWrRr9iPk^3N^@1aM{_aV5k4@A{c4f9#wAH z6GMU3#)hi=9G@X9V;(gRBG{Wd#dN@g)5R_4!ZARxZH&Q0fxo$zj^8N7L+(*f0rEeT z3rTJL`NY(ZxT3sVw`i!J71eHs`WY?LnFM#P`P~JPHa;wP1Wcc!8SlLH&`gz{Z_g)k z1ckn8im4-03!U^3>Am#7S`R`!BWaZTmMu`kr_pV4GkiNfJ2Iq?7bxMJpy0i?o5O-G z2D`)?Nbh;=%Gps(JWQBlWRVsIBGgX9YQps#K83$x3L_nG_ctd-^p$SEtzCIG+*n)t z)HJX0%a?jA5bt1E7*UW(|0}6RtC2;@mE7f#OHKhvQayk%Z;3uRWcuD}E_v!+ww5&a zh>5UF;7V51*tvN{ohYYkXV>3%;q5BsA|=PkTi5B7%wpbU5n-C)MPxjPC$fKfPUJd4 zT7DBRa9@WtKEegko6dKX%!?{qgN0wAJ47Fscq6rY5MSzHynspoZ(#Qw?{CrsRB;+9 z=BPB6vBdgH4Kq9`>&RF%3Z#aNFWQXoKuXjR zjV=2rU(0@EFnC77*vbf?_}>AEB6$#mz=Ziup%K==BpH(=^_HGS1GWFwfDnp^2qO|b z4d3PE3vtUO)+l)&!_Uo>tRg8ui}u}#ryzbkmMqu$3fFcIs&}6+DyN$xX4n(S=!~?L z@raF*My^H;YkK(gW8-&zC1w;Dbueuj6;K(enC*@x61NS4^ST43os6fzJkl8-BRmJ4 zLblyo_3*n2yAw2_@CbhJb7m*r@5C#^UXpuZ>?3AR+4y`72s9v%MyhTGEO5Q&T0Jp$ zLn{JuO6sQd=VZehWdbjD ziGs?91WSTC1R|lGaNo9H1|k<)O(FSBexavHAzV3d_`}bcwoiD!;bM&!)M6X>Md`?r zFS3NsVO4JV6SoJy+kiqolK8zudISvsmF#&S^doQeX%E!d~;MM7E&{0BsHN%e>?%AK|Gm>n0$A-y5 zib-#-cq0J#9|bH9s>qdJvZeMW@F3h6)?m_+34HO!ko{MUgbwP2q@?nKHKQmcEiEmH zS5;M2wY27eE(`PXo}1av(gVo%AJ3f0BYM8*{i;P*M{8aSmqsX5p0nUxL859*2Zb{8fr|@)2@_{cNvuFu&Gu%c z5Wj!QjqY>3Y6u;I*OA}ray|#%^{0I+y=T$%seVQyFjBMGmG~oeBudjDRbzj{l|_V^ z?uroM{&n0}{r-v9+kVM#1Y-DvzyZJcCyT&$aynBz0N&{|f1m=qN@R*&ARy63 z(kUiD+xhKfS?O^Qj5@9-SVWOgae&MT{tyE^GQIG}!)NCH1ff8c!att(LTtHoSmfB| zQd=+`NU5Um{(%}KOBTI0Mo2+aZ(_{pK4;IrSd%@1lpl{lAYZpHycBs*_z{wMl{btF zg6FiA?-SO)N)8K9`l2f6OdeDsEZm?6J!BV(Thth0cA47I#WXG!5i+KN!S6v@LAkGa zH_3qVBVh^ikdgR#+N6rwn@dF4@4^whkNb-FkL^BJ$?@_|frL;Labe7nHANe72Hvkk zA~yYC``?v*wQ8PUm2^~%DiCtdqsOG|@a^B5r{QEk8-8@-K7d6Dak3?m!9oaJ)O$|V2AWs5G3;WBzzxZ1Gi)LV*6VQ~A`)kHIaY=@nryi*BTEOokL7yo10!dz}2O%M?I=B$U0@Cex?y}LxZ&yPysGaL3 zrlwxMnNT$(#=8L*$PF>qLCnHkrDOuv9s7Oi4UB*U&E(jruYd|Vaw=dxpzJf=!pc(qT z`s0qRY0ZgN@udEPZHH`yUpS9`#Z6?fBl38fRj~H_B$nI%pG|`V0pe!z)$fhL0PtP@T={a7hW<|w9yR2l zlunA&AVq5*B(e=u3fh5?bKf4k3@Dzu0Go+74Wu^Gzt&Ko+y5;t;XT28koW6?08cU< z!`g#xW?Z<*HGhy?8JtU-Hg>C#?fD6fub=2P<)e+c}z4pzu73@pk$RZ zp)MP!8=iao;7uUgYU@=j0BwpC)lWz(;9c;0(!@m_sO%*swQkafl-v?Lg!<84vaM_V z?>q^z3j11s2#Sj4an$f?9G`ZAAbxc$@d8hLS|={`LF&7uv7b`<>-EYrb8a4dCZRszIjv=PUmBj?NW4Y1Qrc|w#7pS`NO988sG z=wgoBi7>zeqM=zE;FT+ds3aRu?b)CHUaN!0}$7E23(_^k{L1Hy;D303kL_c zoVv;j{EaZOB$gY_s3QzAzd*NNQQHaxGTaruIgs=LKc)gE4gZ9Q$F4-z^?zFf2Kf*j zyQZ;;93~QP1!ln(>ey8x5RJpQky&bX7hb~JHy&WwTs}-t5z-)}P|8XfdCWt|>{pMW zSQP*}UEXs3>McN_QrVIqVsvNp@F-}*eW3dMAQ$21;G4#YSsxG?DL%9Dgs0IP=?4Oq zzXPnGL`J4I<9={Au^WPZ0hT!J3a8<>AV8t%;57*X3fJ&jn9d-}cl|NG1U-%z%9k1L zcob+i9w4Fdjg??1NfCpQFbqc--eUh{aPJgP0br%8OM&PDq)`4_g)8nDRJc|WoCwAr z<-Z3r+8b{QH$Jc(^o>B6?G3*@aX4rXUU9x{C=UPLCgPk1S{@NCPt(6zE7E%h#Hb0f z55z|-nP0k|57PAaJsCtOXrjjOhTu4vTAChz9}*z_UcSXFP=enCKQ)#@97n?}fWy-G zPNvr8F*8D(vJ000Fb5JcUyFh}t;>h=-3W>;&x|PQ0;4Qj>o+chvPZx+SJa3~A$-Kl zAdVT@Q(7*iR(?!C0hT%Y1LNK7xytQ+Jbxx;ho3olA8coIyW-J4-s9W%gj18-{vTCF zVi8m4Hx~b^hzTJT5qjhbuXD%gR0X>s59m zYvY4TGYZ+o^R*Tk&7VgLnl9btt+hMqELZkh#rNwY!m!#)13#A#WLV8=2>nY4wvh^a z7;M8HsmQhYem3qg>lrriBJ5~3tM+Z%2UtkRAS2;J?@}h{p8s8RhK1OM|o)z4(cU8!V-jeqBaO;j})Rqd<_VWg#n>DIne8X-!tM&>@ z(xMKG+T{q`khdaccjzaiN-VNY5Ou~&!M)k!^>HfJb87YNV0iEHL>{Y*M|>%s1<=Ki z#XOyy_f|_x?IGcVl^S-aCR(}wP&uDkIR6Z7MvP5oe~V53o{GDwK~hT+Yg#*H3ONDI zMX=wK3NTA3;NNCdEvazDpCfYwUl?6xj@Q#lOlO@~5rWIr=1;<5M}_jY))OYic<>ON zxe$)U^0AlM03QlrL~^@6i?@YfrPEk2(Q85F1||}3so?5t@}4ZGo31O)jSdg9&c2U2 zaTPyf$3~OvM$`~;-}B)s8i6YXyUEnOs3MP1hRcqNn8y`zPg49*YXYl=9wSTa*5jT( zR(C2Eu@l`r%p{jlOcY2xK0JhEzWI3~I%@2jjZEOj=BGVv3GRa%Fn^6i&nNKC8(Q4f zecNRrLJ6#B8vD)aY#2t#UHd2F(ukS`PUpxH@~e1SWR#Se37wGDW5%mVA^mMLwj@Ne zs1q1dwF?=hIoL*11C2Q+2#)3o)#zesNfIL3eA=e)$w)87vD_356KxM==wO=N=1kz) zy>5AXJOS6?f@ie92vlt1KN=<#30z!EqK%|>(0wayZW5j^lfw^`KV*lk_ zU%aT5wZXn8G|k=iE;+a!yZJmCM}6*VY*QG0@<60oMk*&N zw<%p{Dl&FA7q^DaAD@+xxY%U=5r*I2M;6~*4L^9K!7gUS>9*VJ+-j+w3b{wU$_ktw zu9w`Jb@$|kQqQxyDzlqQx8ofE^nUPg_|}RDINL$y6Ny3^6XZ~MFSmQoRlb2HV)aTO zn$u8%4%(|*ZL&l;XghqQ-Ew=Fj%%EUMFV<=L2aEsKjX0_V4Pp!s^DSuc|L+ig2pOLnXahFA2OCkmi(Gnd`3l%?OTp6 zOIf5bao`g3KZj&9`~3Sas7cW5S9vbhbn&k#gjd&L)-f4XcYt6Wipfb7JzNSttL?qB zilkg*EN5nNd(C*sq_xla!QcDoSifCR^Xjt+6A5`zO(gaVLfr)QB$nQ{db!8nUdcgC zSS@rcI~^DEB|5b`#ji*M91r@$Mfg7Ks3L>-h0oMLd86{UA}i zqIEcje@XG0Ga$_S6iu%pXRCX-mclTRV8!kN5j7|eJy5R^?#Lhl(sscA6M}7w)j*vZ zY?xCMy25dqP!#MxgG#VY%|3omK~78qD4C&(dN>B~WV}NMA^sARMR{yhgK<&YivML5 zaY-FyoCd=rYgWq^t4(C7I>oVB4UjFq#)NBWr67US_xkn{KRrsZw6Jp2wiQ3}B~NEM zn0xKxIC+i~{wW>!pEiH)c;0@880)YjLaYh}#t=?XVn##98if{y*_C5~N3XRPyaUEWsb&$fDuFjUo*pVfLE^tlJPZ_;^U-W@aXgv+aomt>Xd-ZW~HG<2s4fF#!CCdv2%$0 z@=^H?CGe&^;$u->Brf+5DVOq+snLta9V19N3Tl1R5=>BgRdTO;h24U*opW<@d$A|Q z#dpjFe-iwC{_+OMrQ)$9e1?Xvyd3~s#^;$8L@*PofC}TKs}jvjK>jHT19NyR?}y?` zVLrW5N&P&&BZOdv5;3fN@hGK_RhIR?0$t6khw(JkI2$ud4N_$Ej@OF-f!?DWLB=Qx*I8IDZ9W*(gpqY3fj87Epge$0V>{`eqo9XRKng+qfSqI$yE|yj ztI>$fNIW=zcmBTeS99>#$=66BORDa}L?GBDozWC!A!6qYWb~2$+Z@h|Od+kk4M@-t zh@S;*pwzwj%mNuGRYZFeB$u4}5a8-PFpVEc^;HY6MUXxEPa8fTr`%fu4W*Pvo_whf z5!t}6NsXkecfbyv6kbyz&=ZZ?gOSGz`+Xac3ugeTQ!g5$H&_6a*u^^9KF0r~;@m@O zq~7*{-t@LE7@I54Ypx<9f|9{}1fqsLN2SCPenTn*v&ZUuaFP9BmGU-XL4(&Hy^goL zXit&nFTj>%+}DgElH87@u%K{fDPFiub;7Y=4Xx@!@UxVd5UK`gM5l&6A9E$r&wvbq zSvXaqZ}zb)T*<`*r-w8RN6BU-Z+e#-7T{eTW+dz)`~oT#yW%|%=h7cz{^j)x2;GgV znpqA=`To`d?F)q(Z*N~SipYaml6!bX98}H(GGc_N8uSr8{BCj=KX`=Rr|NdlXZ7$9 zA!@jTt|f!Y?NG?fhe#E%bKt^UA1iNq|F8bVhJMnVqLxc;j-w+(C2-r#_iZMo8D4ef znBa;0LqGFNcN*X%^%_P~GQw;z$ypu$+`eteWFMMgwI=dBhcN3 zZU%i(yGtj=mNkI6xR&`3-mg;RofiYUr9J!yURb6odA`0HWuB0C0WElh$3Tf*5bLi zdD*~E+9LRd83lzz+Dh$IUb_biSK(04)Et8fPebB$@_wx!t^BJcD-SJBl?mtFf6}c| zH7ToeY{oRACU8CWJ`3ksbS%`J9l>Q|Fr!YYS8o{zx(iT zVua&qBt}~3bcwV1WN<-=`^+v`wt6!|6TFZgi7d`_Y4&uvks~J2w0f!3jpy8}8k@Yw zq!p-l?$@kaay@EopaDFJ>l*#iZOm-%K3!!{6tzf`H<5kl07(p!jU>O-h;m5rE3zvp zW#b)OTDM86M#YF6uD3apM{lMu?KyPTBYH!pWKa21SMokHRXn<#!Xd zso@JA2~j+ejD7b-sWy}^e4Ru^YWZ9aR;!4HcJ4;JU14eTcqy05B(r^|;n2Ij{_)Z* z&UP>Utamv{+xuxS0aOz0xQysRo|O{AG12?p&fF9h6U&`<$n=GubVzcz4+qvAq=*d6 znmd4ZOZ;>><1E>pJ1)*O>2zfo2EQAU%Jb%PIlohUJlAlzMJiXTHFDttv>*a6Uxgv5 zh{^J}(iN=BbMIy;_NK1ItB$#oiz0z9&w1E7j+6@~uTRim(#Uf{U&Pc6Dx%o7HrE?* zWCkc>%D5a4ci1I-9*~#PCxfn!m-&%mPz9w$XlJz=Ad0ZG7C7Aj?8AhX$ z(#^`{X6oiRg|S=5E!xl+k3GEXc~3r@(vamuXxe>!hE#f?JnMAQ>hb2juCG4D zlUyCFxhW$wZf@0|PPaK_EB1t!E>gJsOuu~5%antZydRBP@ta!gaQ3)lH!GQmuE4G; zQQ)mA>1l$lUjk&Ly<_zRw zc@9f17`gUKr7uwI;Pm*xdigz)rXl_jKRWJHgi^}oiR?lgD7X|?3W?=@;T{F)F`Q^k z#WU6Gp^lEPawjL2gYMVTqx`ioa9?zCR`J-6dk4G?p9nN_&q46zV$RNrtl2Mnb$Rgy zrC%4$RHE(llaog{T5t{W$f(S|JvKuXtEZ|TJA6@A?y|V~YI%?iA1}XVw2`btLO%2! z(km)dYG2fquXPrTm87zCa#TCzah@zuv5gXyA~zI|WSM_qFk z<~YYtV7#fPrMZ$^T)8VEz8;w@Qm1Q~>xi`(S6M027>FqA z>+*9Sd;6}QOFZTXy)MCQf5Ep*EdHwedi;ETla#>Uy(A7D^OtfKRz#*v5C5zw!PuRdDr z-ur!6;&z6283iO+Sdw=c0iy8lJiWQYSS)L{4-uQTB&z?O{9=wsY_^Kwpu zdF7-&Z7#dIT?W-|_J@{ymHoD0j**5sx*A?`9--;^fK{y!aG9jP9x^?1%qv1=LoC6m zAc3&aU0y>e2ae5fF;L^j4xEG5rJ|mZce6L1l}yKRYO0gfA3%q5lGH|hO1l$mrM(-lK@xj&D(Wdd9K~i!yHBZ4v%R8$wQMr)V6T49UTQPB~ z?%XLW*vy_*to7F}x3-C%2lYFvi{q&=Xd%F+{J6R277Vyj6$Q~WgYH^q$y#@$;<^Y?;FS&Yiqv-Jd9RHJ)uG^!uU0n!pHB zNotbEx5-6is*XHox8d9sOwJqa_3pI{Z) zL9u3ck$}Vpcf(g{-GMg!yJNEpPfOzM1Ux5-~`g71e3z+SsZ|+t8jx5 ziSvLJ_j%X8qcN}26~S(#6yF1-rqSx)pzRH0SllTXntM8ToB8QU$j#7A_VITUA$9b;?BFt+STjU{_?V5<5J=bNz=ic zDT93!RgT9nQ?A|om>DtozHq8{U7zv#ZLX%0&|@%-g<&C`xZ1AKFlz?U4 zdKPh~*lVOe8wmZ``k@5Ecn90ArS3=8wAB)`SB_6jxs~ow;Pij0#s-9!W69}l*Yb`F zTXA!2-IM2~Ev%<8H?mzOu;gV6DPl%pZsuE&!v)7VtU~F8V3$b#wS}kr!!pl+LM>NN zl$8oS%jGW0JB7O?3}-nl_xK9~CqkIM+fXpd7SCs(JP)@V3%#^xl!Gl9>(j23n4UUf z*WF1adKzj1s7E9!H-@RSbZ=ToWR&VTn6~u!OQsz^XGq9w8jyYv+}M?Qt7P}4I-yTP zwBT{_it{p6_mMT93x3pjMMlkDtE~{3Vxq}z$@_i$7 zPxRuOSB|Uf`)Y0gw)T(4z!ID(o^NpSm&0Ucr_gjt7l?4RSzv!Q8U#PQY-0QBi|ifr zRx3NG=o7EDXJvO*)yGt~67t55x zZVo1$DqCQDrQxB^9t@uEWUx4Fxqh~Yav`}i}?Zvy(GZ%9NpT%Q41Xxo%V&fr*) z@8WB_nOz2c1rEFIJ-9(tQGA&06nEaWQI_mam7I$cTAmNZSFHCdwwlMSgAk63HA5CJ z2uAQELmID5bEbp0OG**XxsDs{HlvrHeCwrq{BR5AF6H6XWuK|MRqmY^7J})YxR%b{ zt*YCs1%iKq64XJc3I|?jli2iG7b!Yyn+Ry(aK8a(1Zkdb(393Z-Sr?^0p z_WtwcZmz6XNA~28Cwo&by?s#hTctLcv1O{p%ciu%*p{X2jlIUJ{PyUJ_HkAq77e6G zFqktqqyM?6sMkuto718F{laT8(itQNLpG#fdI1~exEFFkIU) zJC{v!CcHAIZ^RY#^*^;=JOPG-o*`#)q08o5X7=atg7s?s7nkz1t>ChGLK_bX$Sd8+ zwBN8po}NEa-Pdak>Qb2Rnq*%5A_tpA{8HQLUSPYaWOAZ#t`}QI*m?7EGkW1l1744@cE4tpz2EG9Ya+!Q01C-T`q_(>>vgpxx&gzpMCXYSj z%~DR1n^^QA9o=|}NZ+A3TWY+C`)x0{5waP&)%mua-Detmd;0_JHXatg*98CAlYQh; zaY^gPf1sTau1msPm33A}dYsNi(#ksx0uT|G}&T z`me9xyJ=*w4LTKG=j+&!6?_k0?fLmtegW7hf>8B~X3_}AZERnP76}-_kZrAiT={if zUmr9Z{9U1Hd~2gR_ZeYqLs}!1EljJ<3O;_lVFC#I-<45rKvW}(n$cB#c>SLcg&pX9 ziH*0xoz~kn!xYe6-YSeGQk_i~ke3VpV_*ez33S`M6~-`O>}C1omveaiMr#A9D|DP@ z5BL`%xQUqlH*R-%lWiN#PlBx($r*zvSB7zjxB>4U{OGihMk@zi&0qqTSd6O3{;k8U zOt*iRJfW@42cSkjNVOo@&%%3aqxPh?4z(vp)%1k$`}Lr;!d&%aOTQrrsSXsT>x6V@ z;!t26@N=3EARKx_u8mOlnx^kV^a+HzY9{F$)Rn{U4Zc+|h{ z=%lc{DDy`88K6MgSAf8hnfR!4gzD1qV0RkdJ3yMlA^a8tk4{)O*I#RDd`sRh16oY0 zd9a%mM(MO}2_Nuh0uH^^C^^1qD{IN&c$pbjT+*)ZK1_#7=0@swyEV*Z!Hgp8A66E| z?}I?x5^U()KR_}Zihf8|!6AF1FY+vXsw>QWcU(sfRj^W6EDD8D#w7eG<5kkFR3-{r zW{$%C28MSwS;iUc=Mgx_ZbKAK2QkOVU1?BG5BQwO%7D2EOb(2yy1sFIiqEg2O7dn0 z_)JEpxnZA~$6b`t^J-$O+X9sPGH7fKV@og(q*x_nt_Va?Nk%LXdIeYztG{h8O7$W@ z@=a&?T2=de#w$CKLnKaMJt|K>uMmUnZ8MD>z7$5tmi0r=kL=vgoU6w`B$@WB$g)+A zT-)467ycdoXPi>_f#D3YnP1!Ee~a`W-hrfQ^0#tZHm8qx(?OzNCs|LB)&aW}oAm!T zagqtF4G~z_bomv?IQ`&gusG&6s8hf^bT*nUSRlp>w8}Gmq`8d<%-TtlA@~zzu#xQa{p3Xrf@u^^?u8DIMvN(cz8Su3kKe4ILHVy^V9u+slx|Mr z{7qZy|29y68{bnll6K5SY9M8gG>;x289=5>6y8*B?51S|QH@bAhrO1&WcezJga&2s z4S)({|8iGb@Cgj!2m_MQNs}HxpW~5}=HtX;6Gg-UU<^NzqYO0A=KKD4>US zZZ8LZND)7TR)Ms4y$)_}BjJ4lyo`APUS{tD^$-uU?;FGUzozy^fU)~7-`lW$mj&^v zSNs*RewIeyhjf5Lb?jQnv3tS#;g1QSleOJxbOCS+wmW)|#2CTt^z+J%&M_l0&8q%w z1GlQ8W7juk=qivyFq$fY#V~Vt++_Y6H<;D>!-c|j_#J7;hT+OwRwj%PVrC*L1~>L$ z_#o1gU<{ob2>gch*@ZW>!WijRTMSeNg9U+eG@8O;hXL|>7Oxmb(m+=B?ryz@lvAMf z@xSgh;aCZ=7DyZ{OV^XAz4ccCgmISf-nC}xnE zfBw%hqbL&?8B(_?FXS1>K}MQsZTrzz_klNfdjHG92UJB%{!je=n^u;0HlnK{LZ?XN z5Uq@V&OelYMdh2eL;3-KGSEt7PvCZ7JvH+*q>#T)_d#B?547~44@{qioNwFIR3ET3 z0h6P8nf(=0T9Zzz51t)gU@G(6yEBYyr}W$dn~wKy4B|K)*r!>==}h4;1EsVQpt&<# zoB}qY4gqGJ{g^Px;z5|l7PSIlu7^J#jl(qC-i_xLQFqAJ|O*E zRE)<;bM<{HW>>qG6o*b@rB}B7-?2pxIoWo)wD$BY!CR{j120OsV6cB2#Lx^MP9pGP zq7eiF0D(8^ZJVYNIY}vCvO;hAQJ7acZt#s^&?hKcG8DRZd3c)b;F5^#`*{w9Y!x?> z`l(Z`P!1WA_jdGRx*>dQl?=yKVe>QA+ zNX5%q&++4{T&aZFz$s4;?9Eph_0dN;O-x7>5sl+d+#Jshe-1**1cxkK487jAX?l?P zmw?HGJF$jy6lGz@uAWknT-UhN>UI`6s(rhqpZf{iH>#4K&-C+J?RS%BAfdRn*}vRb z5F5tj`Sm%D;4F}MGc7bu5u)D%39Z;HFp}0OW&L0*pQSgb-$b-TJGNHcjc&j5OnHwt z*U_u2eiAEZat6f2Xj_=q>D^@7#R{Dbjt}243wFD{4P%eY96%6{I2v%&^auuWaQe`B z9xHq(31tFgB-z1k49B`YGa_6XX|3O6bE?Q?%E6$#PXE4B*l~yAA!+Q#>e4+siY$vo zi|9;WA~I9=|6OLF8|8vqS?@VLxjJ>d)Df<=D_N&~yOYIjsAQ{(%EP;dn%7*lUmdsY zyeUK@(eJl&dHp>D*VEPisvz+%-5zZCtf^!ACEju{~LkOmM zfMR<&!??{`58o#zanscTR70*mezqMKz+stsYEJJ=TGw-%ZMdM~8K$=!H5GhW%d2s* zn?+Qzi0|ieWP(BJ%b!e8C<$3o8*Fq-l5V!X#C;>*OnYr?>nbPfLaR%6&8^ks9-RB! zJ)7zR2XFrDj)Ui71wJ`}1Y&vJX#U zKS_V5r7Bw2pJt7Wi@dTvyZcnxrzcB`D;^U06A@EUVS3CH`D0I}(39&Cusi4Hhq4Bn znyvLEV|urA5Y1lc>|3nuuA0bSeX_Lv{be2lrM9D3T0OyZ#7oK6KgIBU|*wSm)%@*b$Ejp6wZ{-^NmQniNf@mcY6AN3Xi93tBs_v-Qk| zEoZ-Lym+};R1i1+xW`x8!)>#(zBEleM$w6w;8JKANBeaUj4N>GO`rJyHh>#Byw!-=C&MM;fCL6U`q z{2O?!v$Jg;9yYZDbk;`>A3(r)MYEgd3VlU(6-kX<#&I{QNREi~+)Z^& zYBO>i?%7fLFjf2pntb2^)|#wq>eI?n!huZA)$X-{u%f-LqmxpX+cmgl6Rh6mx4N%# zZqHz|a)sO4~Z57H~!D=CO6f?Y^lxKctV{a67c=Bnc%kvdf z`PFRs#e=nC0|EuTx$ipd+spFAT-JU_t%o8GG#w5a*&Ph@Y{^f{%Er^PY1B}n6f(1& zlYRBK!3EaYsw6f~!+dgKwQKwClGGR7bhLd8-0Qa;%i6m%ch|{ve>md0R?iL8?d0aV zIkjiqgEo)ntxJDT+rn_AlfH!XTCK(TRI4P~fCkZvUB_~(*BZ*Cc4KFfJ(f=0zwXD~ z5!am#hin9luds4%n9w80e#+ije73($MWSf4mb8p)_t38#RgmbCmd8!a$n|XFcDL?m za9^E(_QN!HVZ_Kfw-gVQX=!__BdtwVzVl!cvX(|`%eZJ>;`-~r+SKl>^*E#d;pf5; zgOdA>IC+@>+Jec_9%YZ4*Vo8rGmCT?3Rl;yy#?PaT2EtZrLl{byQxxLKPSNTVLauK3dz| zkWx6~b;N0?e0s8yOMmwRJhs0bp%jml2X4+*ib;pb&vWbBUT~c9;r^^!9V#yUc+W85 zu(Hh)^b)uc9(7M8jg^EIt}ACwcYm0{z8iRP`AbnVPGK=Pb&}$leUL_b>dIiH$8=fG zmtc1$oO5UIfPo*&I9m}nhwO4+eHR^eeRfEbHfi0L*+F-q?`&UpR2_jq(i>*}ZRo+br%HtQfr@YWSJ54?B*@p3zTQ9{2SeNvd=Yd3~iVQ0YKpn0U&X2ko2oRnD7$@g6L|w+52{@laxAHVlK3|=_xsU)%o zwa$HZp9=@5NZ!je>sN~pZ}mlRh!|d6>XH+5RnuXV)m|FMC0a_K%pZMTW-ZzQyH{W{ zxSeXgqtSAYgNKGokdj^4@K802{;n>!DjbXT$-!a6(rnzAXA$i& z7uSw(kACDB0I?V$WH1$+Yq&n)NSB6vf1c#WBAYNuJPw#O3U=_DB77jLsf9$5#6c3+? z#g-pB>+WpTVlwHr0}5Zaz?QFpEr+;qZ101Bw{iGXAF8jA9i_?$??wFV4^)NSBkNJx z?#WskpIIqv#8l^`hdB19zSQbxn=iY&(zNM}-sVWkLtI~mc@c5? zipmZ>KVc2_(`=rI+x7ohXAjTHddAb%<9Lsk3cEVi!!5PAIDH8_EE4BETj+@O?`vzx zKKfR7wWPcBqO^^E&ee||O`+G}q@@8t?A$nfeOiU4y#R-4>}gE*dnny*_mZ#Yi^YwH z-OW1yAJ@_<%kOW&d0szjcy%*=Ms}!E`oON1=VM8tTg1;VKFjo!{l<33D`G`r^d0v#VfXHLuFaW$AP8p}uax zl|hF->!3uBe<~cGq>4;{=0oDh{|v&)&xkqd%OqN6Au!L^iK>&3>H1EQaRcDOvV-S>Xm^K$H`xZ!;nW1YI#DkP;W>n{=Uo%Opp` zs|gK#%B?=i382o=dUs>DAL&9>m`LLirXJ&*_qfhf6}dVrE#<4wu$HCmPNjV$u&y_p zdtGtuv*k9ax2wiEsERVFner(uYw4sLlhXNaNQQ#(p44o&8B=!feDaVpLh6A~D1=SU z5H`sKUI{EmZFZ25h5^|ry3a)n8?@cBc^YW>N*rPz6r>hD+Du1IeySIrk8ZwCRXCH} zrXjfe(V?`XXcaxa_|f`$rK?=deAdJi+^PMEn}$jDA@-ij9CwwsbEC(%DKXq^QK{ma zIBG|Pp4^Fo?deG2#ZnikEdEjJgM3&!Pb+~IHth5@SI>LDbdz@dvDbsadS%Sv4TIFo z$D-X(=B}QeA9o2uq&Z!G?_Q1qkip^Pw46A6sKRVvbnY|~s#x_sn?pjCbd|^<2vtO_ z+8FihX5Q))_Y(pYCR(0cm9?cfX?E;T9yTpX&cOU$f;bXP5l+!kq5PYl@gFs19UEx4CU zAvqCeR+sY_guvaqQu0SlrrovlolZNJKhj@15Vyh;6f*6VecxmGCyRv@jr;6EdKdeP z1&=(9xm?E{+Ea`+W(!L>M{!?~vTIrlT!isw4LAJtE+jsIgC@rWE|ffO?hxvqtHKRx zl@4LYg{OzOSK9sV!_8~i+u#t|6YgKDT>TY+=EB;{_t@ir=Er-4Zob+Gw=1r(MnTDi zbAMoG83(B->m{!e_Q!w?9AiL_iMchTHfo6;wbF8c=u}9RBch%<<+0@Z0RNC zJl}T;KM7&ObsnM&l~t+hm^8l7=LUPWWIbpfVFj9oHF2_mh=abp{xjDxdxZzuhD-8p ztuK%hI)65O`HC+UY{67Q#&hrhbe_XFvNmf4q@(b^QIVNNcOX6XBTkoI>iDEvX1P4o zyGT!s+Ob*vwX&t%uOb(DI6TykBb5))c1wo!lRrdO=NL*j9g=;rL6n_FK6>8|Tl>MX z?MV_Y2HPIy?$()XFr+9>3y0PXEv+mRRBtqz{+qt^m1BcrE+x@#4v2*GuBo^mcU|p$ z)LUJ++(=cb$P;oB&Rc>DlkANQuOoiV(u~@Y0}MnT`diH&ykBEG_&CD%RPp?6#xwS2 z#5`LcQPRHryLw z1Fq3}{d?@ul?j&#%2erDyFJbamF9wG+nT*oU3)At&6=cR`tt=txe-UuER|H~gycB2 zsZwbx7MGkq&rd&7kEEGbIrh-KXuzwzA!J@-pK>XkuGDs25|flqYEkI_L^hF6pbDF`c;AV8MzT`_!HfC{ zn!hjBaG2T5dPr{~XMg7f(6COKLM5!@R<##ywU)LNyv4}7iKpHcR#%Gpn_>2(D1Kpe zRoeA@&fE<5ry`GudK`P#%`cZN!sM()Z@3EOTTi%@2r}zyw@WoJs6}$(3r||O^|9%w zZ%I33_q@t37^^n#7MjO(t#?iJ(B@AS#q0ow?ChFJD?JNc=K#w$|A$=uhn##ZNhCM! z$B@BH)iVpj@3(BqSVg4bC=tnHdpdKnHk-suv^q2+}7zq@y1@nc8fV8#k?P>gBQPh~%9=!h5#b z`Pe}(Hc79l&WG$2QC8U;I?r=l;$*3#tVEQvKYsKHW>z|c^iv!RwsK@)=de0^V`uB$ zv&UvH)@BD_pP5inzQI11^SnK>e6M-&s#fzweW#R^i4OSd)QP#z8=k0`MwXzcmcHqI;@x`~)Z`*i}7#VV6)mZ5?XiV^X)@e1o8} z?|!(4y5Ig|>GH*~R%_kL-tX*3@-)5cwbGAl^yk4h%JeF;6YAyjKX{j{FF!=CMy&XH zP|aAUA=9YYr)MY1)}qiHaQ9ah33tk8VQ$OPv>9b{y)Q>FgGdx}A1-gk!pg>0_7RVn zt2>(?oSQ9HKT#=(!j+)Ml8^_S ztnjX1SM%|LJ?oA7h^chAakORMUF(4;YzQ+6sT3Xna-Tlls#o?mbNxeSIq)xEWTblt*X6X@n_%_zH{?R>|`fsf+tzz(tSI~-D2Esk(vN_y00Gd8wKE=c2ovdKf&X^1lRCufABp zMa}w_t=FWhNU_2gYcH^q3&mfHzq*^ai@jF}h>*~6HI&~=>JQD#M3q-@0A%`{(O(6V zQ|5^JioMf@^b{x_YP6mDD&?v7u_%LebX9q6nPmVzZ77IEj^<-4QHYFEY-@*)a_{_^ z`8til}e$Q<0sFmSAgTE!RP&Uvj8BkC%S2bdVv)e5+ zP43x8tmj;%C6nmE++{#xP3Gp$2ki!|gvU)n+Q9BZOsu-j%3UcIxYTLOm;fFzn{f!*h#tSsn-St~$Y#&FJXy}Y@){WS17;C?^`!xDIP44+81PxtwAo7iW7(0E7 zpW6KQ_Eu+=fT#zvEg{4hRjV5%&yd{yzJ0f3lZ`%g`C#8Q;?GnmTSboFLGQX!={<60 zzh$5O#e(VH4pHgk1zy_ukegN*ZGxT>WTftVwdE*lzAp*h5xNRFH`D?^6W>ffKF`BYW_|*m-$4KeIbF z>&|+W7~W=e=6cyII_RNfK8o6NwWd$9P%4#r2#&=eAD;0T@*j|{N_QyF?I@PQb{KA? zzges>P1it-EX#%56!*M-_KdlDludvR`QSmzL2NF@^mRLGaNhjazxsFRmBfU=P+3N^o`Zne09=gMXQq- zL=eu=FUt{yZ>&zb6eEPy7^**g{itTCqiMLPEw3iet<0MIZ_XJ$fE4Z%A#32KAMlr* zuyKEtufMu888Kc^lT`{Cm3fRZJnQ|+EZaKcj7BUA&armYU}(PHfL=-e-t9fsnKe%2 zZ{yp6$>(!$`Q63`n0!I<)Q{5{Ny1$B-dhyL(p}$?)JzLh=%dZB~b;-I!RlXCtqiwk)=_vOS5ZVnxwr=#?bSiRMg6 zPXF$N%3&)W4-l-pRImAPHJw){2x#eJ3w;-$Od&sRthomy+9Hx*(iKJqb4Z6NUOxv2 z-~OCB`Lgl$$%v2PZc?77MzU?^0IlcK-}m<$vGtdiui7%!4e(yPc=0@&!qI2OP#9c( zl^m!$4d1#FdrSILlavA7Za1mY!!`E8;JF?`f?;S82v^dGN#+>EqN~*8(&`wZ)xZ=~ zn(4|u5$I9%j2WUwon@v_;WoQ?tWyQkObATd}4hZ9JdSr1^j6nPMwZAhVI(lO0( zF7QgMgL0@tCgNntQ6%@7J8gS!$$sq60E!YDPbkBggD79Rdqe0?16%j0rB%=Dw2P;K z|GgMG5&Uw(!sE6SQ^Ya>q|Vw;;`6{5H8!ig!U9t|XwId!w?yRGqH8hZwJQL`+;P*l z#H`CSAV{Pjc+?B09VG2dU1g7>HswCvZGNJ~lI?P4O|wbbG9N*8g#mLjlWsvjRVfDg z=bw2VhKTE6G6Xb2@=iSQXEL8q8Cn}0b=5`cHp?ZJ7*GMii`=~zhy_$z$f4zeLC#I* z@hj>N%;6D$MG-EYq@ER=ngEJ6LpFshnopgiFnXTymMj+>ks?%Kz;xMFs#HOK_}6X}d^h#`OtV|gus zy6@e_GGzQ-@DIZA@9_t5^_ke}03X!EoS;NR3?;C^&ul3G#V5E3Dn@$-sMt5l7G<_u zWphjMraTqquv}BQu_ae*fRfor1q8b@#qY=DL7tkK-+Lc{U8_tash8@w z+F0kug)<`VC$N32IL84KIF5sM|bSR&sRN)qNaW)vOHs9PG-|c^ZH}pe`F(`b1Y&aZLcV ztCRst3KWD%-l2+l^GIO-2Un+HUV?gFU@UI!@v83{-}x)MF{MfUi-H>Mql z)o~qZx?wZ@1ZIQN0EUJT zYK;;BFK_EQlWL6~L#Bf6H1LV*c{T?mMQmmJDu;k^NX=LIz67 z@0Zg8lE#qLg1(~9fO1}z`l%}9}GAUWoM!@T zQM1G9k6iw55v0Yh_1ZjeYZ2eeBFA}w<~Mx~lk|cj;K7MZYIZ~APY`F~oB^tIgrZU{ z@aaqL{6<9nga!PI2Iv9|3IlY#xj)+m01UP48E82Dfv3p+QDr*@q}_tsLN=o5UKSN; zIbaUhLqW>}&@zMrGvfM~uwDLvvfxf0H8ON#F_)%^dP6A@aTV0G5tVv{lIf zW!O3YJbv(XGGJXKok15d+=z#e^uFT3)>N7vRT+q2Vl>w)arC&9MGu;u2U#t%b zAf9fK@c?q!p1&->q4E|0>dy1z?;>RAPyr*5(!~G3CPK5B5@&0sLXc|h^`Y5v=jTs> z=n2eb`HR^QoEFzF@yP)zbi~P=9eDJ|;wnmjszYi1s?@I^fS*fT(+MO}6%K?}$TDJ0 zjv2wZv2c+M>edJ%G%ZLa(u<2JXh8tVj$(Y}3F^|>QLc{&YM~C)!tpj6=pXw;4hT7; zma0D##a8#~P#kRWGd>Wa4xWlb-4w@<0ZBce@f@5k0^^Rdf?*qV6QLZ60v_8^ODtq< z*XV!m8@tc2z#7iBG2uBmb)#?2enR0mC@DA7>3<)yUeRQ|;_b2!NXfeT^oki~G6!BL zpNC?Y#!RLoXi&}zeDA1^5xniYu&aaxQ}~7cmiHIY_3)+8Y6C69m1?^+9seY;3aIh) zAe-H6c`!Op&(@aQt$t7DK1wCSC(1^udubutv7=D^(6JU!nl4OT$N9#se)`Q!pl>CY zKm9|e;+YhI1E0bH8tPt>dDFkIvx*(0L*|HG$FSK>w(%yAZtYuyERGqwI+SuqF!VGT zB-(>#0SR7gx?P)A5}4lJZuD1 zu9fe9y3V@a$rBwb_r?n^b}$fTVIb{w>A1>$An(78DqX%Wa}k_eljVF_-j_MEf5p0_ zZ0?2CTxBOD*k|>~4A;Om;hZgup{aPaVYW*+toe&Y%w|_kyQ`2MS~02yTHwS;cVNDL zTHey)kA~ZJ_11oE)EDM1zD5xu6Sst%zS5+3r0>p@3;Pk(uH(QnPw+@U&@U#H)7!48 ziOn}WwL>S2c-Nzf<6*%ehkqkWpt&X7haE!H_9{KrdntA(;GOTO^Uh*@(PH; zc^!&t$Qf1lA^kUl-D@)atgs~+Lh}&uE6w|Cj})Ylv5Cl%k*A!V#oC_%yFF3q2%!x3 z$_R9JN3_9GNFsBYTnN{rNn*4tK|YOJY_jX`+j#^1Z5MiKrYPlR(P1#zAIIMev6dc+ zb(vQYn|PK}F@zeyUsgNfFJ1&$yNM|)aPS9MyGROCT4!`EWhJUud>-E#mQl#bTjYM3 z!Pnv{AW=m5O_b|7cZ}h*mC2G1Q|8_zKJoNsfsg}4uhn7;@!{}izgAmyJwj(3P{p~= zt9u5kRInafQxPq0Ur~gg%0;iz3@3;o!U0%E4m*#=`d-9dt6FuQS*ou{PKp&POgE$l zR?X6Mh#f!rdnazg1s@mJxkUr9ABuQSVOl$j~;i(`A3 zcF-GU38gugWbVwEv3erz)k(dIMZv|HUDxcy*3)*~Sdwf;#st&3(;+x_(U*@wfl*u} znf%2g*qn5<_Y3-pPWoc*>zKd}O+l)cr)1&;$P7`%Z08C`B-upwZcNVZzhKWTcyA|r zi#{-(MF>7{?jJe`R>6Hsi7cpZ;nr77gd5{0O^@b@3Y`(;Q+1OY0PGenyU~ajvlu-a zODpa9YW5o+$}h!8>TEWo;DpwyX6Hd{U}eTgVxEew7oVZ?$;sZ8djoo^eRB_NDJbb0 z&rE6W57^;#o3dvGA%*ViX1#TCF3@YC;+Z|YrsNBYKm)cqp%;@xi9WUW++wJ2#m;<$ zP*bMs$gJXpD?KNLylTOX2zL*Oy_qROTO!xx*t)V)!+a<+=g+f8mBqQP+gGO8eY?yNVr1e2q#Q zI$|Q$f5M{I{63bVArK_^CdDML%#iJIWZCP4D$Jq2HD(G7PT$-3mADg7;QVKKpY1di zs$i!-g#}$#%u~VXHx$7AZHT9K7Eiu&as^sesgocr@B)!Q{S+u)98D%V2gc| zUoqMR0~s?y%LdusqThgJ*wqEXWgAAfz0709XiMiiB`cp+HWR#<==FRdUfpZRs6T|` zuS&^-5CK|y7gD&d;AVWL@Iv!^yE4zMA4WH(X6~(dcfOb@YzYujrGE(Rlb?B@Ov`2R z69=Pw1{T-hE%R{e%gEzX7b$03sSM&!`CaD#QjSFwfUKV^WOS)rkO{<^Mu#5F* z&%!mf_x52iEExsMtvE$ZGXPMe4E9vW>e4_K1-ta_3~|xxcDQ&QNjQVjE9!*bHO}sa zbozC6`9(t)&U1F%4-m9UlJ<9;D|5rVF_ow%-vHKL2IM{mSSXwTPU5Rm985Q!>z4>! zcmC{M^6(z7ml`N7cwTsJw|rbSKrWO|KYb6b)&GodH-36~b}=7mBbMg8;f?;r^ZZMf z>^$VyXJ~Fxo zR(P5c#Jy@3F3>7UM!{=6ua9-v)5CUvmLvL}`+&M-v!178o%&_oIIC4=sf35Uzw2!JGk7l{s&vsz%UEF0lqI3{gxfq)VF6S zl-N-1b*Rh~qv`=xX?LO2iXx|(1E5uHZC6Nrp@*KRFAI~Xka4;}k#t!2pOE#1q_FPT zY^ZgRk8R&d)u>97G+yJz#}AnYG9^Y9KRG~Mky{k|F(U?hq1fkW*U}$ii;L)Ln*|>{ zI4Gl4Qs{_!*eY<_R#wNpt@_J&PpoUAQq~K25P_g_#-QiJNt6V5cvU;Po^uDgEq5TMmdJ zct~uqLB)BnRNfbVYT3>ijiG0%IW1;=zF<-+%;%ChMoNI~swAl&T*5(UN!(H-t@)Tg zfw>CA##}BRP7x_I&TWT(pzI?#ja51#Au!Ks_6hwkSZQw(6>8L>4uk=(FdPrXYZ{Yz zg1`*~;m2ly$a+^cAEi)caX)nqH^ot7Ej82QjjrQq`rV%{=B$lJi~(2_s^<<7s#ubD z9Yw7;`yq#M4NkEPQlEQV>?_C2`40FS+))r48>FecV;{uSYvu(`O;Z+QTkFxa=#h#x z<#S92jyelet(;D;snFuHa;JQ({M!1Fb4D;Q1~DmoT4W_anU-xhFTC4zbZtC#wmhu5 zv{N$B@qK)7B~O#K5OzNohwp$gGcGC|_9(Q-Pfp&5ZkKW8M>Me59IS4Ib52>y>d2z` zX!J@1z4yDCW@|(1&Fhs_7`(cKdiqKMVRY3u3dV@=kNUy3yL?C608NVP^}bDerV7qXhfp)SIH3>39k*5tBCu=r;F&U2N%&1=CM@rv2I-V z#`Y+Q?tMyekTbo!*rmohc%+%qpB{O{z@hphxb>;GQ>XMdyeW-yP$re3Y~r_4Vy0qg5M3yOK37Ve(7w>V z?K))@Ca|o_<;s;Mq|_h;AX7_BDF5|CD9Agu@I4IQy{G= zel`F!c8eAi`wq4HwQ4Qs{DW%PrbC1Cj0u-YB}g!CX&)5;6h zQo4BNKYq061fr8b4RSb5JVe7-c zM`(u^0~GccgOuR=v@Ga0lppLqN%KdqpMaRy*CXqY4HEx-|9A`xNZOr6}* zEB1Ry+VPXYiNmQtQke+QHRg!V`QCCA`boLpeK}ge&6f4Q5C|D?^c~3j=TG3QxW#R- zfc!DxYe-hs+I17RKHMVCTZGGt8`{RuRAf^)oRrDG6_PkS;OnBHqUmO1-oGD!fX^rg zl*YMzTXrnTf{%VH!LDfm8{zQdGM#PI`~fjEHeuhvLQ{uLfhDns*!Y3OY86i~{7~jo z>a9At1&OVL60*cP9w1qT;|G`GY=NbY?MWdu`_ejUlVLJoGf3;GHXG?I=@tV1E2_27 zo=Y(QUw3=n(JCL@G6l#4L3@%LTIvj&#bUo0b?q`_KO=#U3yzuRAv#JQiA)o{>)1k+Ux0o(uE`EfKvO3pFR7;ZE_XYA^JV7wp~X5%8$5f zWS}60^&NWPT_9f{{1EHHNOQBW4bRuCDkMnueHhsciHOtIaRRd%0Cf-e_o#S5MF)uw zZDlPKDVn#vuJQ_eb7Cpx$NdaHH;G2vKpqv3BRJI+4->okZ@z0J0`$AVC)@tl7!uWt zITZpX8q}i1TnHpB_=$q)bq?B$N#>&aD{1~lKV|wLS&avo_*mU<+Z3cc3z%GSI^mjs z0!#yeGH>NVIwS8kZ6;NSDjQ7k%0~9`2F_^&XMLkSLlHp>bX-&?Wy_6`|Ek-YPp+vz z`gjZMbas-&e!wcVBO|l_8vpmM*#s=Zp{lx^7n7h%=)Z@zh8yslD~WnYJL$>5w)c-I zgJE25KPIJ#e>v2Xe24+B7>IDnL_mqX zRG=gcZS7yT(nW>Us~y4l;K76agk4QlUmu@}rj723=lW5MSfNCOj!sE7% z@U6j63mg!AEi+Nzp9E{cKmyE!L9o{L_BrJio|30P!CGOi;N7k8{XGX|SfF4n6$EPs z+VqJVJ|s9f%fRsS9kqM6!uJyrLECDr;1Zb-3H*^-LO=9P{tZ!s_~_Z%#>^(e;=mf8 zhbryq--ENAXoJuu=Ev|gx#-PYL{pyY)Y|pO9Dj8?090IRa=_-SzmWWmlVD68Mc|W# z(ucOj*H;usG0jjbGk^*i^+2qQ5VZ@Cq((83lH5L|X$ngspNCF>2 zkb+FGhYj0(_s1PDAXVf7m=cmiC$|;8tqk6ZXA2kP--@OSCvI_EToYEd24|B;a_~K3 zpMZyML$)w%eOU(70|NgH}nSIY3t*56t8x(2QVeIXLbMPjgCKIGXZX+yI!CK zaYlb$J$R;PkKPEhsvkl#sb*hG+wKQC=|G0$-Q2L=UD(EtMfx`76^+o29J9n9J5x;tp`jH&9Pg;uQ=3jtg;6X&eOr zAA5Bhqd_kBjXS$J-n0WgvvOJ-69Ma-L7JGReY17DHDbp1QhzxZ(N56Gix|BFX$q2-5e zfBEsta7CbDImuJkw?6zC0R=&H+)CT#C(xFB6TWSjKaPXFY3~$hYwKq}{{EE<$SznY zfRZ6gg-6?ih!PNsj9qHZ`u^%KJ|sg*?JXStD)#obt*fW|<@W&jugZTUZN&XmhPKPu zB?y)}OIfbl`y@8+pd!lOTTmZj(eZ|G&&w~sfWA@@fvnVHpbXvZLPxjKrCl8)9_oNn z?sPOVI_A{>;>C+Mq>4DXNvIyf^8le_=;tC&1otsS_{9!CwMp4~j$0=x6NIz=)*iNwRJAZ9m~<`*}zT>cDo%*$bscg2%%p1I_TDW;muz60_xcH;!)1+XVw;8XzQj`xjn1;w8~-JZ-c?4OFmiu0 zk4_W?kchJ>#ysy?U}k2vs$xEJq*lt&9p8;ZaK1yz{G+wF8U-=09s8@iHj$&8ML^H8 zwQ5&?sNQ#^|N3DGgp1E+nN+{EbF0fYT}@oex`%Bz>DeQ?B-&bKKO3~KlM2^)`c66q z)oUi=zPfE4+=I6Y z`_e_2=Uf9`Q&W!n5H6);4o=)f6`%b*fZ>@T3Nd)c%~+fvw@qem=kW zaZS=Wb}pxywIc%GYtmX)HUJ^Sk6&2fnq*Qn=C-LCGf*k>E9zdo)Y5y(hB)YZEQvJf zxdc#M!tv?19iajI$SKUJiPl7P8tdyIX=9RDsSbw!#OSjti zoR*YlyD*?*))qR#alw>VONE!P$*$PfBWv9r2NE*QfNj(}lz3y0?JVd(P1|!icwn6J zgY;JECn}NnL9$?5MJag7QP}u9oFnpL@r6=eW?tPildECo}q3DRk|##zcn+}1R=5~UVY>C#MqsGO*lZ%A%E6m|D0eo&Tx zZzrIYWkXq!V$U-IZVxc5hqGC+Ir_Sm>g%rpSr^XY^*&F!52GwvOHbu0kFWBFrQz>e zHfMzmwGU*vVsA~XD6cR)FD%6tb=UA={g=?q@Vj0g^AlrX8bPc}*Wuem>%T#g`2ggS z)9kqcr{KFAQ>O-2;7$=w`I1M>0c`$-ji8QHy>UEX>Xh+rh3*uBC|w(0_K!<P^)s&$0Hoz@Gy;aSpHjPmKTm@n-MN#k=bV<&7^#6$keBmt6*I}mG* zwNc9`>ovjRW=;!cvoB$jjupYF z^GrQWl5Ujif}<6Xi3cY4cHvbYH+U0pd)0t%Xcf_%|L@r(qHqb|bGRk51L00l1?&W< z_AJ1-O<=3$MQ^_(5^UcMTz*O?rlG9um4_mMHK&K+ZkKA#EU?b-&uI{zNDt$yQUXhc zVP;QrLkOB0j6rI2K6L|U2*2Q+M9I+tW+ND|O!Ftk z_y0*m8}Mm$foZ@={Lg%W1Ftkl=5Z?xEM>_kvrQK0V^18Z;h)}xzr)OOhCmP+0lZ|L zMB$%!&P&4=2wYSfhMQS1@%%@Y=l_bb5dG^%Y;($Ftpx6W=lqGDNX$QJu1hwWnP@eN z3O7!K7sn6e&;Q>L@&6^~w?zS%ARQAvq7gH}nQJ(ju>6lL?9Dk0o;;Z0_=C{mh8^JF N + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contracts/src/v0.8/ccip/interfaces/IAny2EVMMessageReceiver.sol b/contracts/src/v0.8/ccip/interfaces/IAny2EVMMessageReceiver.sol new file mode 100644 index 0000000000..6305311050 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IAny2EVMMessageReceiver.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Client} from "../libraries/Client.sol"; + +/// @notice Application contracts that intend to receive messages from +/// the router should implement this interface. +interface IAny2EVMMessageReceiver { + /// @notice Called by the Router to deliver a message. + /// If this reverts, any token transfers also revert. The message + /// will move to a FAILED state and become available for manual execution. + /// @param message CCIP Message + /// @dev Note ensure you check the msg.sender is the OffRampRouter + function ccipReceive(Client.Any2EVMMessage calldata message) external; +} diff --git a/contracts/src/v0.8/ccip/interfaces/IAny2EVMOffRamp.sol b/contracts/src/v0.8/ccip/interfaces/IAny2EVMOffRamp.sol new file mode 100644 index 0000000000..1881dede2e --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IAny2EVMOffRamp.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IAny2EVMOffRamp { + /// @notice Returns the the current nonce for a receiver. + /// @param sender The sender address + /// @return nonce The nonce value belonging to the sender address. + function getSenderNonce(address sender) external view returns (uint64 nonce); +} diff --git a/contracts/src/v0.8/ccip/interfaces/ICommitStore.sol b/contracts/src/v0.8/ccip/interfaces/ICommitStore.sol new file mode 100644 index 0000000000..1183eb277b --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/ICommitStore.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface ICommitStore { + /// @notice Returns timestamp of when root was accepted or 0 if verification fails. + /// @dev This method uses a merkle tree within a merkle tree, with the hashedLeaves, + /// proofs and proofFlagBits being used to get the root of the inner tree. + /// This root is then used as the singular leaf of the outer tree. + function verify( + bytes32[] calldata hashedLeaves, + bytes32[] calldata proofs, + uint256 proofFlagBits + ) external view returns (uint256 timestamp); + + /// @notice Returns the expected next sequence number + function getExpectedNextSequenceNumber() external view returns (uint64 sequenceNumber); +} diff --git a/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRamp.sol b/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRamp.sol new file mode 100644 index 0000000000..d657e148cb --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRamp.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IEVM2AnyOnRampClient} from "./IEVM2AnyOnRampClient.sol"; + +interface IEVM2AnyOnRamp is IEVM2AnyOnRampClient { + /// @notice Gets the next sequence number to be used in the onRamp + /// @return the next sequence number to be used + function getExpectedNextSequenceNumber() external view returns (uint64); + + /// @notice Get the next nonce for a given sender + /// @param sender The sender to get the nonce for + /// @return nonce The next nonce for the sender + function getSenderNonce(address sender) external view returns (uint64 nonce); +} diff --git a/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRampClient.sol b/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRampClient.sol new file mode 100644 index 0000000000..1744d6c229 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRampClient.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IPoolV1} from "./IPool.sol"; + +import {Client} from "../libraries/Client.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +interface IEVM2AnyOnRampClient { + /// @notice Get the fee for a given ccip message + /// @param destChainSelector The destination chain selector + /// @param message The message to calculate the cost for + /// @return fee The calculated fee + function getFee(uint64 destChainSelector, Client.EVM2AnyMessage calldata message) external view returns (uint256 fee); + + /// @notice Get the pool for a specific token + /// @param destChainSelector The destination chain selector + /// @param sourceToken The source chain token to get the pool for + /// @return pool Token pool + function getPoolBySourceToken(uint64 destChainSelector, IERC20 sourceToken) external view returns (IPoolV1); + + /// @notice Gets a list of all supported source chain tokens. + /// @param destChainSelector The destination chain selector + /// @return tokens The addresses of all tokens that this onRamp supports the given destination chain + function getSupportedTokens(uint64 destChainSelector) external view returns (address[] memory tokens); + + /// @notice Send a message to the remote chain + /// @dev only callable by the Router + /// @dev approve() must have already been called on the token using the this ramp address as the spender. + /// @dev if the contract is paused, this function will revert. + /// @param destChainSelector The destination chain selector + /// @param message Message struct to send + /// @param feeTokenAmount Amount of fee tokens for payment + /// @param originalSender The original initiator of the CCIP request + function forwardFromRouter( + uint64 destChainSelector, + Client.EVM2AnyMessage memory message, + uint256 feeTokenAmount, + address originalSender + ) external returns (bytes32); +} diff --git a/contracts/src/v0.8/ccip/interfaces/IGetCCIPAdmin.sol b/contracts/src/v0.8/ccip/interfaces/IGetCCIPAdmin.sol new file mode 100644 index 0000000000..d83a1f34e8 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IGetCCIPAdmin.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IGetCCIPAdmin { + /// @notice Returns the admin of the token. + /// @dev This method is named to never conflict with existing methods. + function getCCIPAdmin() external view returns (address); +} diff --git a/contracts/src/v0.8/ccip/interfaces/IMessageInterceptor.sol b/contracts/src/v0.8/ccip/interfaces/IMessageInterceptor.sol new file mode 100644 index 0000000000..c2b432426b --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IMessageInterceptor.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Client} from "../libraries/Client.sol"; + +/// @notice Interface for plug-in message hook contracts that intercept OffRamp & OnRamp messages +/// and perform validations / state changes on top of the messages. The interceptor functions are expected to +/// revert on validation failures. +interface IMessageInterceptor { + /// @notice Common error that can be thrown on validation failures and used by consumers + /// @param errorReason abi encoded revert reason + error MessageValidationError(bytes errorReason); + + /// @notice Intercepts & validates the given OffRamp message. Reverts on validation failure + /// @param message to validate + function onInboundMessage(Client.Any2EVMMessage memory message) external; + + /// @notice Intercepts & validates the given OnRamp message. Reverts on validation failure + /// @param destChainSelector remote destination chain selector where the message is being sent to + /// @param message to validate + function onOutboundMessage(uint64 destChainSelector, Client.EVM2AnyMessage memory message) external; +} diff --git a/contracts/src/v0.8/ccip/interfaces/INonceManager.sol b/contracts/src/v0.8/ccip/interfaces/INonceManager.sol new file mode 100644 index 0000000000..52408ae4f5 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/INonceManager.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @notice Contract interface that allows managing sender nonces +interface INonceManager { + /// @notice Increments the outbound nonce for a given sender on a given destination chain + /// @param destChainSelector The destination chain selector + /// @param sender The sender address + /// @return The new outbound nonce + function getIncrementedOutboundNonce(uint64 destChainSelector, address sender) external returns (uint64); + + /// @notice Increments the inbound nonce for a given sender on a given source chain + /// @notice The increment is only applied if the resulting nonce matches the expectedNonce + /// @param sourceChainSelector The destination chain selector + /// @param expectedNonce The expected inbound nonce + /// @param sender The encoded sender address + /// @return True if the nonce was incremented, false otherwise + function incrementInboundNonce( + uint64 sourceChainSelector, + uint64 expectedNonce, + bytes calldata sender + ) external returns (bool); +} diff --git a/contracts/src/v0.8/ccip/interfaces/IOwner.sol b/contracts/src/v0.8/ccip/interfaces/IOwner.sol new file mode 100644 index 0000000000..ccb1039e55 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IOwner.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IOwner { + /// @notice Returns the owner of the contract. + /// @dev This method is named to match with the OpenZeppelin Ownable contract. + function owner() external view returns (address); +} diff --git a/contracts/src/v0.8/ccip/interfaces/IPool.sol b/contracts/src/v0.8/ccip/interfaces/IPool.sol new file mode 100644 index 0000000000..5d5c95e03c --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IPool.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Pool} from "../libraries/Pool.sol"; + +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; + +/// @notice Shared public interface for multiple V1 pool types. +/// Each pool type handles a different child token model (lock/unlock, mint/burn.) +interface IPoolV1 is IERC165 { + /// @notice Lock tokens into the pool or burn the tokens. + /// @param lockOrBurnIn Encoded data fields for the processing of tokens on the source chain. + /// @return lockOrBurnOut Encoded data fields for the processing of tokens on the destination chain. + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + external + returns (Pool.LockOrBurnOutV1 memory lockOrBurnOut); + + /// @notice Releases or mints tokens to the receiver address. + /// @param releaseOrMintIn All data required to release or mint tokens. + /// @return releaseOrMintOut The amount of tokens released or minted on the local chain, denominated + /// in the local token's decimals. + function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + external + returns (Pool.ReleaseOrMintOutV1 memory); + + /// @notice Checks whether a remote chain is supported in the token pool. + /// @param remoteChainSelector The selector of the remote chain. + /// @return true if the given chain is a permissioned remote chain. + function isSupportedChain(uint64 remoteChainSelector) external view returns (bool); + + /// @notice Returns if the token pool supports the given token. + /// @param token The address of the token. + /// @return true if the token is supported by the pool. + function isSupportedToken(address token) external view returns (bool); +} diff --git a/contracts/src/v0.8/ccip/interfaces/IPoolPriorTo1_5.sol b/contracts/src/v0.8/ccip/interfaces/IPoolPriorTo1_5.sol new file mode 100644 index 0000000000..d8a2f15fd2 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IPoolPriorTo1_5.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +// Shared public interface for multiple pool types. +// Each pool type handles a different child token model (lock/unlock, mint/burn.) +interface IPoolPriorTo1_5 { + /// @notice Lock tokens into the pool or burn the tokens. + /// @param originalSender Original sender of the tokens. + /// @param receiver Receiver of the tokens on destination chain. + /// @param amount Amount to lock or burn. + /// @param remoteChainSelector Destination chain Id. + /// @param extraArgs Additional data passed in by sender for lockOrBurn processing + /// in custom pools on source chain. + /// @return retData Optional field that contains bytes. Unused for now but already + /// implemented to allow future upgrades while preserving the interface. + function lockOrBurn( + address originalSender, + bytes calldata receiver, + uint256 amount, + uint64 remoteChainSelector, + bytes calldata extraArgs + ) external returns (bytes memory); + + /// @notice Releases or mints tokens to the receiver address. + /// @param originalSender Original sender of the tokens. + /// @param receiver Receiver of the tokens. + /// @param amount Amount to release or mint. + /// @param remoteChainSelector Source chain Id. + /// @param extraData Additional data supplied offchain for releaseOrMint processing in + /// custom pools on dest chain. This could be an attestation that was retrieved through a + /// third party API. + /// @dev offchainData can come from any untrusted source. + function releaseOrMint( + bytes memory originalSender, + address receiver, + uint256 amount, + uint64 remoteChainSelector, + bytes memory extraData + ) external; + + /// @notice Gets the IERC20 token that this pool can lock or burn. + /// @return token The IERC20 token representation. + function getToken() external view returns (IERC20 token); +} diff --git a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol new file mode 100644 index 0000000000..8a20299371 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Client} from "../libraries/Client.sol"; +import {Internal} from "../libraries/Internal.sol"; + +interface IPriceRegistry { + /// @notice Token price data feed configuration + struct TokenPriceFeedConfig { + address dataFeedAddress; // ──╮ AggregatorV3Interface contract (0 - feed is unset) + uint8 tokenDecimals; // ──────╯ Decimals of the token that the feed represents + } + + /// @notice Update the price for given tokens and gas prices for given chains. + /// @param priceUpdates The price updates to apply. + function updatePrices(Internal.PriceUpdates memory priceUpdates) external; + + /// @notice Get the `tokenPrice` for a given token. + /// @param token The token to get the price for. + /// @return tokenPrice The tokenPrice for the given token. + function getTokenPrice(address token) external view returns (Internal.TimestampedPackedUint224 memory); + + /// @notice Get the `tokenPrice` for a given token, checks if the price is valid. + /// @param token The token to get the price for. + /// @return tokenPrice The tokenPrice for the given token if it exists and is valid. + function getValidatedTokenPrice(address token) external view returns (uint224); + + /// @notice Get the `tokenPrice` for an array of tokens. + /// @param tokens The tokens to get prices for. + /// @return tokenPrices The tokenPrices for the given tokens. + function getTokenPrices(address[] calldata tokens) external view returns (Internal.TimestampedPackedUint224[] memory); + + /// @notice Returns the token price data feed configuration + /// @param token The token to retrieve the feed config for + /// @return dataFeedAddress The token price data feed config (if feed address is 0, the feed config is disabled) + function getTokenPriceFeedConfig(address token) external view returns (TokenPriceFeedConfig memory); + + /// @notice Get an encoded `gasPrice` for a given destination chain ID. + /// The 224-bit result encodes necessary gas price components. + /// On L1 chains like Ethereum or Avax, the only component is the gas price. + /// On Optimistic Rollups, there are two components - the L2 gas price, and L1 base fee for data availability. + /// On future chains, there could be more or differing price components. + /// PriceRegistry does not contain chain-specific logic to parse destination chain price components. + /// @param destChainSelector The destination chain to get the price for. + /// @return gasPrice The encoded gasPrice for the given destination chain ID. + function getDestinationChainGasPrice(uint64 destChainSelector) + external + view + returns (Internal.TimestampedPackedUint224 memory); + + /// @notice Gets the fee token price and the gas price, both denominated in dollars. + /// @param token The source token to get the price for. + /// @param destChainSelector The destination chain to get the gas price for. + /// @return tokenPrice The price of the feeToken in 1e18 dollars per base unit. + /// @return gasPrice The price of gas in 1e18 dollars per base unit. + function getTokenAndGasPrices( + address token, + uint64 destChainSelector + ) external view returns (uint224 tokenPrice, uint224 gasPrice); + + /// @notice Convert a given token amount to target token amount. + /// @param fromToken The given token address. + /// @param fromTokenAmount The given token amount. + /// @param toToken The target token address. + /// @return toTokenAmount The target token amount. + function convertTokenAmount( + address fromToken, + uint256 fromTokenAmount, + address toToken + ) external view returns (uint256 toTokenAmount); + + /// @notice Get the list of fee tokens. + /// @return The tokens set as fee tokens. + function getFeeTokens() external view returns (address[] memory); + + /// @notice Validates the ccip message & returns the fee + /// @param destChainSelector The destination chain selector. + /// @param message The message to get quote for. + /// @return feeTokenAmount The amount of fee token needed for the fee, in smallest denomination of the fee token. + function getValidatedFee( + uint64 destChainSelector, + Client.EVM2AnyMessage calldata message + ) external view returns (uint256 feeTokenAmount); + + /// @notice Converts the extraArgs to the latest version and returns the converted message fee in juels + /// @param destChainSelector destination chain selector to process + /// @param feeToken Fee token address used to pay for message fees + /// @param feeTokenAmount Fee token amount + /// @param extraArgs Message extra args that were passed in by the client + /// @return msgFeeJuels message fee in juels + /// @return isOutOfOrderExecution true if the message should be executed out of order + /// @return convertedExtraArgs extra args converted to the latest family-specific args version + function processMessageArgs( + uint64 destChainSelector, + address feeToken, + uint256 feeTokenAmount, + bytes memory extraArgs + ) external view returns (uint256 msgFeeJuels, bool isOutOfOrderExecution, bytes memory convertedExtraArgs); + + /// @notice Validates pool return data + /// @param destChainSelector Destination chain selector to which the token amounts are sent to + /// @param rampTokenAmounts Token amounts with populated pool return data + /// @param sourceTokenAmounts Token amounts originally sent in a Client.EVM2AnyMessage message + function validatePoolReturnData( + uint64 destChainSelector, + Internal.RampTokenAmount[] calldata rampTokenAmounts, + Client.EVMTokenAmount[] calldata sourceTokenAmounts + ) external view; +} diff --git a/contracts/src/v0.8/ccip/interfaces/IRMN.sol b/contracts/src/v0.8/ccip/interfaces/IRMN.sol new file mode 100644 index 0000000000..a409731549 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IRMN.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @notice This interface contains the only RMN-related functions that might be used on-chain by other CCIP contracts. +interface IRMN { + /// @notice A Merkle root tagged with the address of the commit store contract it is destined for. + struct TaggedRoot { + address commitStore; + bytes32 root; + } + + /// @notice Callers MUST NOT cache the return value as a blessed tagged root could become unblessed. + function isBlessed(TaggedRoot calldata taggedRoot) external view returns (bool); + + /// @notice Iff there is an active global or legacy curse, this function returns true. + function isCursed() external view returns (bool); + + /// @notice Iff there is an active global curse, or an active curse for `subject`, this function returns true. + /// @param subject To check whether a particular chain is cursed, set to bytes16(uint128(chainSelector)). + function isCursed(bytes16 subject) external view returns (bool); +} diff --git a/contracts/src/v0.8/ccip/interfaces/IRouter.sol b/contracts/src/v0.8/ccip/interfaces/IRouter.sol new file mode 100644 index 0000000000..7f4544fd0f --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IRouter.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Client} from "../libraries/Client.sol"; + +interface IRouter { + error OnlyOffRamp(); + + /// @notice Route the message to its intended receiver contract. + /// @param message Client.Any2EVMMessage struct. + /// @param gasForCallExactCheck of params for exec + /// @param gasLimit set of params for exec + /// @param receiver set of params for exec + /// @dev if the receiver is a contracts that signals support for CCIP execution through EIP-165. + /// the contract is called. If not, only tokens are transferred. + /// @return success A boolean value indicating whether the ccip message was received without errors. + /// @return retBytes A bytes array containing return data form CCIP receiver. + /// @return gasUsed the gas used by the external customer call. Does not include any overhead. + function routeMessage( + Client.Any2EVMMessage calldata message, + uint16 gasForCallExactCheck, + uint256 gasLimit, + address receiver + ) external returns (bool success, bytes memory retBytes, uint256 gasUsed); + + /// @notice Returns the configured onramp for a specific destination chain. + /// @param destChainSelector The destination chain Id to get the onRamp for. + /// @return onRampAddress The address of the onRamp. + function getOnRamp(uint64 destChainSelector) external view returns (address onRampAddress); + + /// @notice Return true if the given offRamp is a configured offRamp for the given source chain. + /// @param sourceChainSelector The source chain selector to check. + /// @param offRamp The address of the offRamp to check. + function isOffRamp(uint64 sourceChainSelector, address offRamp) external view returns (bool isOffRamp); +} diff --git a/contracts/src/v0.8/ccip/interfaces/IRouterClient.sol b/contracts/src/v0.8/ccip/interfaces/IRouterClient.sol new file mode 100644 index 0000000000..9805a41bbd --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IRouterClient.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Client} from "../libraries/Client.sol"; + +interface IRouterClient { + error UnsupportedDestinationChain(uint64 destChainSelector); + error InsufficientFeeTokenAmount(); + error InvalidMsgValue(); + + /// @notice Checks if the given chain ID is supported for sending/receiving. + /// @param destChainSelector The chain to check. + /// @return supported is true if it is supported, false if not. + function isChainSupported(uint64 destChainSelector) external view returns (bool supported); + + /// @param destinationChainSelector The destination chainSelector + /// @param message The cross-chain CCIP message including data and/or tokens + /// @return fee returns execution fee for the message + /// delivery to destination chain, denominated in the feeToken specified in the message. + /// @dev Reverts with appropriate reason upon invalid message. + function getFee( + uint64 destinationChainSelector, + Client.EVM2AnyMessage memory message + ) external view returns (uint256 fee); + + /// @notice Request a message to be sent to the destination chain + /// @param destinationChainSelector The destination chain ID + /// @param message The cross-chain CCIP message including data and/or tokens + /// @return messageId The message ID + /// @dev Note if msg.value is larger than the required fee (from getFee) we accept + /// the overpayment with no refund. + /// @dev Reverts with appropriate reason upon invalid message. + function ccipSend( + uint64 destinationChainSelector, + Client.EVM2AnyMessage calldata message + ) external payable returns (bytes32); +} diff --git a/contracts/src/v0.8/ccip/interfaces/ITokenAdminRegistry.sol b/contracts/src/v0.8/ccip/interfaces/ITokenAdminRegistry.sol new file mode 100644 index 0000000000..0e44122901 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/ITokenAdminRegistry.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +interface ITokenAdminRegistry { + /// @notice Returns the pool for the given token. + function getPool(address token) external view returns (address); + + /// @notice Proposes an administrator for the given token as pending administrator. + /// @param localToken The token to register the administrator for. + /// @param administrator The administrator to register. + function proposeAdministrator(address localToken, address administrator) external; +} diff --git a/contracts/src/v0.8/ccip/interfaces/IWrappedNative.sol b/contracts/src/v0.8/ccip/interfaces/IWrappedNative.sol new file mode 100644 index 0000000000..4225827a61 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IWrappedNative.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +interface IWrappedNative is IERC20 { + function deposit() external payable; + + function withdraw(uint256 wad) external; +} diff --git a/contracts/src/v0.8/ccip/interfaces/automation/ILinkAvailable.sol b/contracts/src/v0.8/ccip/interfaces/automation/ILinkAvailable.sol new file mode 100644 index 0000000000..b0dad9a5e7 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/automation/ILinkAvailable.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @notice Implement this contract so that a keeper-compatible contract can monitor +/// and fund the implementation contract with LINK if it falls below a defined threshold. +interface ILinkAvailable { + function linkAvailableForPayment() external view returns (int256 availableBalance); +} diff --git a/contracts/src/v0.8/ccip/libraries/Client.sol b/contracts/src/v0.8/ccip/libraries/Client.sol new file mode 100644 index 0000000000..a985371bef --- /dev/null +++ b/contracts/src/v0.8/ccip/libraries/Client.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +// End consumer library. +library Client { + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct EVMTokenAmount { + address token; // token address on the local chain. + uint256 amount; // Amount of tokens. + } + + struct Any2EVMMessage { + bytes32 messageId; // MessageId corresponding to ccipSend on source. + uint64 sourceChainSelector; // Source chain selector. + bytes sender; // abi.decode(sender) if coming from an EVM chain. + bytes data; // payload sent in original message. + EVMTokenAmount[] destTokenAmounts; // Tokens and their amounts in their destination chain representation. + } + + // If extraArgs is empty bytes, the default is 200k gas limit. + struct EVM2AnyMessage { + bytes receiver; // abi.encode(receiver address) for dest EVM chains + bytes data; // Data payload + EVMTokenAmount[] tokenAmounts; // Token transfers + address feeToken; // Address of feeToken. address(0) means you will send msg.value. + bytes extraArgs; // Populate this with _argsToBytes(EVMExtraArgsV2) + } + + // bytes4(keccak256("CCIP EVMExtraArgsV1")); + bytes4 public constant EVM_EXTRA_ARGS_V1_TAG = 0x97a657c9; + + struct EVMExtraArgsV1 { + uint256 gasLimit; + } + + function _argsToBytes(EVMExtraArgsV1 memory extraArgs) internal pure returns (bytes memory bts) { + return abi.encodeWithSelector(EVM_EXTRA_ARGS_V1_TAG, extraArgs); + } + + // bytes4(keccak256("CCIP EVMExtraArgsV2")); + bytes4 public constant EVM_EXTRA_ARGS_V2_TAG = 0x181dcf10; + + /// @param gasLimit: gas limit for the callback on the destination chain. + /// @param allowOutOfOrderExecution: if true, it indicates that the message can be executed in any order relative to other messages from the same sender. + /// This value's default varies by chain. On some chains, a particular value is enforced, meaning if the expected value + /// is not set, the message request will revert. + struct EVMExtraArgsV2 { + uint256 gasLimit; + bool allowOutOfOrderExecution; + } + + function _argsToBytes(EVMExtraArgsV2 memory extraArgs) internal pure returns (bytes memory bts) { + return abi.encodeWithSelector(EVM_EXTRA_ARGS_V2_TAG, extraArgs); + } +} diff --git a/contracts/src/v0.8/ccip/libraries/Internal.sol b/contracts/src/v0.8/ccip/libraries/Internal.sol new file mode 100644 index 0000000000..db2bc05ee5 --- /dev/null +++ b/contracts/src/v0.8/ccip/libraries/Internal.sol @@ -0,0 +1,319 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {MerkleMultiProof} from "../libraries/MerkleMultiProof.sol"; +import {Client} from "./Client.sol"; + +// Library for CCIP internal definitions common to multiple contracts. +library Internal { + error InvalidEVMAddress(bytes encodedAddress); + + /// @dev The minimum amount of gas to perform the call with exact gas. + /// We include this in the offramp so that we can redeploy to adjust it + /// should a hardfork change the gas costs of relevant opcodes in callWithExactGas. + uint16 internal constant GAS_FOR_CALL_EXACT_CHECK = 5_000; + // @dev We limit return data to a selector plus 4 words. This is to avoid + // malicious contracts from returning large amounts of data and causing + // repeated out-of-gas scenarios. + uint16 internal constant MAX_RET_BYTES = 4 + 4 * 32; + + /// @notice A collection of token price and gas price updates. + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct PriceUpdates { + TokenPriceUpdate[] tokenPriceUpdates; + GasPriceUpdate[] gasPriceUpdates; + } + + /// @notice Token price in USD. + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct TokenPriceUpdate { + address sourceToken; // Source token + uint224 usdPerToken; // 1e18 USD per 1e18 of the smallest token denomination. + } + + /// @notice Gas price for a given chain in USD, its value may contain tightly packed fields. + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct GasPriceUpdate { + uint64 destChainSelector; // Destination chain selector + uint224 usdPerUnitGas; // 1e18 USD per smallest unit (e.g. wei) of destination chain gas + } + + /// @notice A timestamped uint224 value that can contain several tightly packed fields. + struct TimestampedPackedUint224 { + uint224 value; // ───────╮ Value in uint224, packed. + uint32 timestamp; // ────╯ Timestamp of the most recent price update. + } + + /// @dev Gas price is stored in 112-bit unsigned int. uint224 can pack 2 prices. + /// When packing L1 and L2 gas prices, L1 gas price is left-shifted to the higher-order bits. + /// Using uint8 type, which cannot be higher than other bit shift operands, to avoid shift operand type warning. + uint8 public constant GAS_PRICE_BITS = 112; + + struct PoolUpdate { + address token; // The IERC20 token address + address pool; // The token pool address + } + + struct SourceTokenData { + // The source pool address, abi encoded. This value is trusted as it was obtained through the onRamp. It can be + // relied upon by the destination pool to validate the source pool. + bytes sourcePoolAddress; + // The address of the destination token, abi encoded in the case of EVM chains + // This value is UNTRUSTED as any pool owner can return whatever value they want. + bytes destTokenAddress; + // Optional pool data to be transferred to the destination chain. Be default this is capped at + // CCIP_LOCK_OR_BURN_V1_RET_BYTES bytes. If more data is required, the TokenTransferFeeConfig.destBytesOverhead + // has to be set for the specific token. + bytes extraData; + } + + /// @notice Report that is submitted by the execution DON at the execution phase. (including chain selector data) + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct ExecutionReportSingleChain { + uint64 sourceChainSelector; // Source chain selector for which the report is submitted + Any2EVMRampMessage[] messages; + // Contains a bytes array for each message, each inner bytes array contains bytes per transferred token + bytes[][] offchainTokenData; + bytes32[] proofs; + uint256 proofFlagBits; + } + + /// @notice Report that is submitted by the execution DON at the execution phase. + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct ExecutionReport { + EVM2EVMMessage[] messages; + // Contains a bytes array for each message, each inner bytes array contains bytes per transferred token + bytes[][] offchainTokenData; + bytes32[] proofs; + uint256 proofFlagBits; + } + + /// @notice The cross chain message that gets committed to EVM chains. + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct EVM2EVMMessage { + uint64 sourceChainSelector; // ───────────╮ the chain selector of the source chain, note: not chainId + address sender; // ───────────────────────╯ sender address on the source chain + address receiver; // ─────────────────────╮ receiver address on the destination chain + uint64 sequenceNumber; // ────────────────╯ sequence number, not unique across lanes + uint256 gasLimit; // user supplied maximum gas amount available for dest chain execution + bool strict; // ──────────────────────────╮ DEPRECATED + uint64 nonce; // │ nonce for this lane for this sender, not unique across senders/lanes + address feeToken; // ─────────────────────╯ fee token + uint256 feeTokenAmount; // fee token amount + bytes data; // arbitrary data payload supplied by the message sender + Client.EVMTokenAmount[] tokenAmounts; // array of tokens and amounts to transfer + bytes[] sourceTokenData; // array of token data, one per token + bytes32 messageId; // a hash of the message data + } + + /// @dev EVM2EVMMessage struct has 13 fields, including 3 variable arrays. + /// Each variable array takes 1 more slot to store its length. + /// When abi encoded, excluding array contents, + /// EVM2EVMMessage takes up a fixed number of 16 lots, 32 bytes each. + /// For structs that contain arrays, 1 more slot is added to the front, reaching a total of 17. + uint256 public constant MESSAGE_FIXED_BYTES = 32 * 17; + + /// @dev Each token transfer adds 1 EVMTokenAmount and 1 bytes. + /// When abiEncoded, each EVMTokenAmount takes 2 slots, each bytes takes 2 slots, excl bytes contents + uint256 public constant MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * 4; + + /// @dev Any2EVMRampMessage struct has 10 fields, including 3 variable unnested arrays (data, receiver and tokenAmounts). + /// Each variable array takes 1 more slot to store its length. + /// When abi encoded, excluding array contents, + /// Any2EVMMessage takes up a fixed number of 13 slots, 32 bytes each. + /// For structs that contain arrays, 1 more slot is added to the front, reaching a total of 14. + /// The fixed bytes does not cover struct data (this is represented by ANY_2_EVM_MESSAGE_FIXED_BYTES_PER_TOKEN) + uint256 public constant ANY_2_EVM_MESSAGE_FIXED_BYTES = 32 * 14; + + /// @dev Each token transfer adds 1 RampTokenAmount + /// RampTokenAmount has 4 fields, including 3 bytes. + /// Each bytes takes 1 more slot to store its length. + /// When abi encoded, each token transfer takes up 7 slots, excl bytes contents. + uint256 public constant ANY_2_EVM_MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * 7; + + bytes32 internal constant EVM_2_EVM_MESSAGE_HASH = keccak256("EVM2EVMMessageHashV2"); + + /// @dev Used to hash messages for single-lane ramps. + /// OnRamp hash(EVM2EVMMessage) = OffRamp hash(EVM2EVMMessage) + /// The EVM2EVMMessage's messageId is expected to be the output of this hash function + /// @param original Message to hash + /// @param metadataHash Immutable metadata hash representing a lane with a fixed OnRamp + /// @return hashedMessage hashed message as a keccak256 + function _hash(EVM2EVMMessage memory original, bytes32 metadataHash) internal pure returns (bytes32) { + // Fixed-size message fields are included in nested hash to reduce stack pressure. + // This hashing scheme is also used by RMN. If changing it, please notify the RMN maintainers. + return keccak256( + abi.encode( + MerkleMultiProof.LEAF_DOMAIN_SEPARATOR, + metadataHash, + keccak256( + abi.encode( + original.sender, + original.receiver, + original.sequenceNumber, + original.gasLimit, + original.strict, + original.nonce, + original.feeToken, + original.feeTokenAmount + ) + ), + keccak256(original.data), + keccak256(abi.encode(original.tokenAmounts)), + keccak256(abi.encode(original.sourceTokenData)) + ) + ); + } + + bytes32 internal constant ANY_2_EVM_MESSAGE_HASH = keccak256("Any2EVMMessageHashV1"); + bytes32 internal constant EVM_2_ANY_MESSAGE_HASH = keccak256("EVM2AnyMessageHashV1"); + + /// @dev Used to hash messages for multi-lane family-agnostic OffRamps. + /// OnRamp hash(EVM2AnyMessage) != Any2EVMRampMessage.messageId + /// OnRamp hash(EVM2AnyMessage) != OffRamp hash(Any2EVMRampMessage) + /// @param original OffRamp message to hash + /// @param onRamp OnRamp to hash the message with - used to compute the metadataHash + /// @return hashedMessage hashed message as a keccak256 + function _hash(Any2EVMRampMessage memory original, bytes memory onRamp) internal pure returns (bytes32) { + // Fixed-size message fields are included in nested hash to reduce stack pressure. + // This hashing scheme is also used by RMN. If changing it, please notify the RMN maintainers. + return keccak256( + abi.encode( + MerkleMultiProof.LEAF_DOMAIN_SEPARATOR, + // Implicit metadata hash + keccak256( + abi.encode( + ANY_2_EVM_MESSAGE_HASH, original.header.sourceChainSelector, original.header.destChainSelector, onRamp + ) + ), + keccak256( + abi.encode( + original.header.messageId, + original.sender, + original.receiver, + original.header.sequenceNumber, + original.gasLimit, + original.header.nonce + ) + ), + keccak256(original.data), + keccak256(abi.encode(original.tokenAmounts)) + ) + ); + } + + function _hash(EVM2AnyRampMessage memory original, bytes32 metadataHash) internal pure returns (bytes32) { + // Fixed-size message fields are included in nested hash to reduce stack pressure. + // This hashing scheme is also used by RMN. If changing it, please notify the RMN maintainers. + return keccak256( + abi.encode( + MerkleMultiProof.LEAF_DOMAIN_SEPARATOR, + metadataHash, + keccak256( + abi.encode( + original.sender, + original.receiver, + original.header.sequenceNumber, + original.header.nonce, + original.feeToken, + original.feeTokenAmount + ) + ), + keccak256(original.data), + keccak256(abi.encode(original.tokenAmounts)), + keccak256(original.extraArgs) + ) + ); + } + + /// @dev We disallow the first 1024 addresses to never allow calling precompiles. It is extremely unlikely that + /// anyone would ever be able to generate an address in this range. + uint256 public constant PRECOMPILE_SPACE = 1024; + + /// @notice This methods provides validation for parsing abi encoded addresses by ensuring the + /// address is within the EVM address space. If it isn't it will revert with an InvalidEVMAddress error, which + /// we can catch and handle more gracefully than a revert from abi.decode. + /// @return The address if it is valid, the function will revert otherwise. + function _validateEVMAddress(bytes memory encodedAddress) internal pure returns (address) { + if (encodedAddress.length != 32) revert InvalidEVMAddress(encodedAddress); + uint256 encodedAddressUint = abi.decode(encodedAddress, (uint256)); + if (encodedAddressUint > type(uint160).max || encodedAddressUint < PRECOMPILE_SPACE) { + revert InvalidEVMAddress(encodedAddress); + } + return address(uint160(encodedAddressUint)); + } + + /// @notice Enum listing the possible message execution states within + /// the offRamp contract. + /// UNTOUCHED never executed + /// IN_PROGRESS currently being executed, used a replay protection + /// SUCCESS successfully executed. End state + /// FAILURE unsuccessfully executed, manual execution is now enabled. + /// @dev RMN depends on this enum, if changing, please notify the RMN maintainers. + enum MessageExecutionState { + UNTOUCHED, + IN_PROGRESS, + SUCCESS, + FAILURE + } + + /// @notice CCIP OCR plugin type, used to separate execution & commit transmissions and configs + enum OCRPluginType { + Commit, + Execution + } + + /// @notice Family-agnostic token amounts used for both OnRamp & OffRamp messages + struct RampTokenAmount { + // The source pool address, abi encoded. This value is trusted as it was obtained through the onRamp. It can be + // relied upon by the destination pool to validate the source pool. + bytes sourcePoolAddress; + // The address of the destination token, abi encoded in the case of EVM chains + // This value is UNTRUSTED as any pool owner can return whatever value they want. + bytes destTokenAddress; + // Optional pool data to be transferred to the destination chain. Be default this is capped at + // CCIP_LOCK_OR_BURN_V1_RET_BYTES bytes. If more data is required, the TokenTransferFeeConfig.destBytesOverhead + // has to be set for the specific token. + bytes extraData; + uint256 amount; // Amount of tokens. + } + + /// @notice Family-agnostic header for OnRamp & OffRamp messages. + /// The messageId is not expected to match hash(message), since it may originate from another ramp family + struct RampMessageHeader { + bytes32 messageId; // Unique identifier for the message, generated with the source chain's encoding scheme (i.e. not necessarily abi.encoded) + uint64 sourceChainSelector; // ───────╮ the chain selector of the source chain, note: not chainId + uint64 destChainSelector; // | the chain selector of the destination chain, note: not chainId + uint64 sequenceNumber; // │ sequence number, not unique across lanes + uint64 nonce; // ─────────────────────╯ nonce for this lane for this sender, not unique across senders/lanes + } + + /// @notice Family-agnostic message routed to an OffRamp + /// Note: hash(Any2EVMRampMessage) != hash(EVM2AnyRampMessage), hash(Any2EVMRampMessage) != messageId + /// due to encoding & parameter differences + struct Any2EVMRampMessage { + RampMessageHeader header; // Message header + bytes sender; // sender address on the source chain + bytes data; // arbitrary data payload supplied by the message sender + address receiver; // receiver address on the destination chain + uint256 gasLimit; // user supplied maximum gas amount available for dest chain execution + RampTokenAmount[] tokenAmounts; // array of tokens and amounts to transfer + } + + /// @notice Family-agnostic message emitted from the OnRamp + /// Note: hash(Any2EVMRampMessage) != hash(EVM2AnyRampMessage) due to encoding & parameter differences + /// messageId = hash(EVM2AnyRampMessage) using the source EVM chain's encoding format + struct EVM2AnyRampMessage { + RampMessageHeader header; // Message header + address sender; // sender address on the source chain + bytes data; // arbitrary data payload supplied by the message sender + bytes receiver; // receiver address on the destination chain + bytes extraArgs; // destination-chain specific extra args, such as the gasLimit for EVM chains + address feeToken; // fee token + uint256 feeTokenAmount; // fee token amount + RampTokenAmount[] tokenAmounts; // array of tokens and amounts to transfer + } + + // bytes4(keccak256("CCIP ChainFamilySelector EVM")) + bytes4 public constant CHAIN_FAMILY_SELECTOR_EVM = 0x2812d52c; +} diff --git a/contracts/src/v0.8/ccip/libraries/MerkleMultiProof.sol b/contracts/src/v0.8/ccip/libraries/MerkleMultiProof.sol new file mode 100644 index 0000000000..fed8a1165b --- /dev/null +++ b/contracts/src/v0.8/ccip/libraries/MerkleMultiProof.sol @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +library MerkleMultiProof { + /// @notice Leaf domain separator, should be used as the first 32 bytes of a leaf's preimage. + bytes32 internal constant LEAF_DOMAIN_SEPARATOR = 0x0000000000000000000000000000000000000000000000000000000000000000; + /// @notice Internal domain separator, should be used as the first 32 bytes of an internal node's preiimage. + bytes32 internal constant INTERNAL_DOMAIN_SEPARATOR = + 0x0000000000000000000000000000000000000000000000000000000000000001; + + uint256 internal constant MAX_NUM_HASHES = 256; + + error InvalidProof(); + error LeavesCannotBeEmpty(); + + /// @notice Computes the root based on provided pre-hashed leaf nodes in + /// leaves, internal nodes in proofs, and using proofFlagBits' i-th bit to + /// determine if an element of proofs or one of the previously computed leafs + /// or internal nodes will be used for the i-th hash. + /// @param leaves Should be pre-hashed and the first 32 bytes of a leaf's + /// preimage should match LEAF_DOMAIN_SEPARATOR. + /// @param proofs The hashes to be used instead of a leaf hash when the proofFlagBits + /// indicates a proof should be used. + /// @param proofFlagBits A single uint256 of which each bit indicates whether a leaf or + /// a proof needs to be used in a hash operation. + /// @dev the maximum number of hash operations it set to 256. Any input that would require + /// more than 256 hashes to get to a root will revert. + /// @dev For given input `leaves` = [a,b,c] `proofs` = [D] and `proofFlagBits` = 5 + /// totalHashes = 3 + 1 - 1 = 3 + /// ** round 1 ** + /// proofFlagBits = (5 >> 0) & 1 = true + /// hashes[0] = hashPair(a, b) + /// (leafPos, hashPos, proofPos) = (2, 0, 0); + /// + /// ** round 2 ** + /// proofFlagBits = (5 >> 1) & 1 = false + /// hashes[1] = hashPair(D, c) + /// (leafPos, hashPos, proofPos) = (3, 0, 1); + /// + /// ** round 3 ** + /// proofFlagBits = (5 >> 2) & 1 = true + /// hashes[2] = hashPair(hashes[0], hashes[1]) + /// (leafPos, hashPos, proofPos) = (3, 2, 1); + /// + /// i = 3 and no longer < totalHashes. The algorithm is done + /// return hashes[totalHashes - 1] = hashes[2]; the last hash we computed. + // We mark this function as internal to force it to be inlined in contracts + // that use it, but semantically it is public. + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function merkleRoot( + bytes32[] memory leaves, + bytes32[] memory proofs, + uint256 proofFlagBits + ) internal pure returns (bytes32) { + unchecked { + uint256 leavesLen = leaves.length; + uint256 proofsLen = proofs.length; + if (leavesLen == 0) revert LeavesCannotBeEmpty(); + if (!(leavesLen <= MAX_NUM_HASHES + 1 && proofsLen <= MAX_NUM_HASHES + 1)) revert InvalidProof(); + uint256 totalHashes = leavesLen + proofsLen - 1; + if (!(totalHashes <= MAX_NUM_HASHES)) revert InvalidProof(); + if (totalHashes == 0) { + return leaves[0]; + } + bytes32[] memory hashes = new bytes32[](totalHashes); + (uint256 leafPos, uint256 hashPos, uint256 proofPos) = (0, 0, 0); + + for (uint256 i = 0; i < totalHashes; ++i) { + // Checks if the bit flag signals the use of a supplied proof or a leaf/previous hash. + bytes32 a; + if (proofFlagBits & (1 << i) == (1 << i)) { + // Use a leaf or a previously computed hash. + if (leafPos < leavesLen) { + a = leaves[leafPos++]; + } else { + a = hashes[hashPos++]; + } + } else { + // Use a supplied proof. + a = proofs[proofPos++]; + } + + // The second part of the hashed pair is never a proof as hashing two proofs would result in a + // hash that can already be computed offchain. + bytes32 b; + if (leafPos < leavesLen) { + b = leaves[leafPos++]; + } else { + b = hashes[hashPos++]; + } + + if (!(hashPos <= i)) revert InvalidProof(); + + hashes[i] = _hashPair(a, b); + } + if (!(hashPos == totalHashes - 1 && leafPos == leavesLen && proofPos == proofsLen)) revert InvalidProof(); + // Return the last hash. + return hashes[totalHashes - 1]; + } + } + + /// @notice Hashes two bytes32 objects in their given order, prepended by the + /// INTERNAL_DOMAIN_SEPARATOR. + function _hashInternalNode(bytes32 left, bytes32 right) private pure returns (bytes32 hash) { + return keccak256(abi.encode(INTERNAL_DOMAIN_SEPARATOR, left, right)); + } + + /// @notice Hashes two bytes32 objects. The order is taken into account, + /// using the lower value first. + function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { + return a < b ? _hashInternalNode(a, b) : _hashInternalNode(b, a); + } +} diff --git a/contracts/src/v0.8/ccip/libraries/Pool.sol b/contracts/src/v0.8/ccip/libraries/Pool.sol new file mode 100644 index 0000000000..3f1895dcf5 --- /dev/null +++ b/contracts/src/v0.8/ccip/libraries/Pool.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @notice This library contains various token pool functions to aid constructing the return data. +library Pool { + // The tag used to signal support for the pool v1 standard + // bytes4(keccak256("CCIP_POOL_V1")) + bytes4 public constant CCIP_POOL_V1 = 0xaff2afbf; + + // The number of bytes in the return data for a pool v1 releaseOrMint call. + // This should match the size of the ReleaseOrMintOutV1 struct. + uint16 public constant CCIP_POOL_V1_RET_BYTES = 32; + + // The default max number of bytes in the return data for a pool v1 lockOrBurn call. + // This data can be used to send information to the destination chain token pool. Can be overwritten + // in the TokenTransferFeeConfig.destBytesOverhead if more data is required. + uint256 public constant CCIP_LOCK_OR_BURN_V1_RET_BYTES = 32; + + struct LockOrBurnInV1 { + bytes receiver; // The recipient of the tokens on the destination chain, abi encoded + uint64 remoteChainSelector; // ─╮ The chain ID of the destination chain + address originalSender; // ─────╯ The original sender of the tx on the source chain + uint256 amount; // The amount of tokens to lock or burn, denominated in the source token's decimals + address localToken; // The address on this chain of the token to lock or burn + } + + struct LockOrBurnOutV1 { + // The address of the destination token pool, abi encoded in the case of EVM chains + // This value is UNTRUSTED as any pool owner can return whatever value they want. + bytes destTokenAddress; + // Optional pool data to be transferred to the destination chain. Be default this is capped at + // CCIP_LOCK_OR_BURN_V1_RET_BYTES bytes. If more data is required, the TokenTransferFeeConfig.destBytesOverhead + // has to be set for the specific token. + bytes destPoolData; + } + + struct ReleaseOrMintInV1 { + bytes originalSender; // The original sender of the tx on the source chain + uint64 remoteChainSelector; // ─╮ The chain ID of the source chain + address receiver; // ───────────╯ The recipient of the tokens on the destination chain. This is *NOT* the address to + // send the tokens to, but the address that will receive the tokens via the offRamp. + uint256 amount; // The amount of tokens to release or mint, denominated in the source token's decimals + address localToken; // The address on this chain of the token to release or mint + /// @dev WARNING: sourcePoolAddress should be checked prior to any processing of funds. Make sure it matches the + /// expected pool address for the given remoteChainSelector. + bytes sourcePoolAddress; // The address of the source pool, abi encoded in the case of EVM chains + bytes sourcePoolData; // The data received from the source pool to process the release or mint + /// @dev WARNING: offchainTokenData is untrusted data. + bytes offchainTokenData; // The offchain data to process the release or mint + } + + struct ReleaseOrMintOutV1 { + // The number of tokens released or minted on the destination chain, denominated in the local token's decimals. + // This value is expected to be equal to the ReleaseOrMintInV1.amount in the case where the source and destination + // chain have the same number of decimals. + uint256 destinationAmount; + } +} diff --git a/contracts/src/v0.8/ccip/libraries/RateLimiter.sol b/contracts/src/v0.8/ccip/libraries/RateLimiter.sol new file mode 100644 index 0000000000..40ac3ca213 --- /dev/null +++ b/contracts/src/v0.8/ccip/libraries/RateLimiter.sol @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +/// @notice Implements Token Bucket rate limiting. +/// @dev uint128 is safe for rate limiter state. +/// For USD value rate limiting, it can adequately store USD value in 18 decimals. +/// For ERC20 token amount rate limiting, all tokens that will be listed will have at most +/// a supply of uint128.max tokens, and it will therefore not overflow the bucket. +/// In exceptional scenarios where tokens consumed may be larger than uint128, +/// e.g. compromised issuer, an enabled RateLimiter will check and revert. +library RateLimiter { + error BucketOverfilled(); + error OnlyCallableByAdminOrOwner(); + error TokenMaxCapacityExceeded(uint256 capacity, uint256 requested, address tokenAddress); + error TokenRateLimitReached(uint256 minWaitInSeconds, uint256 available, address tokenAddress); + error AggregateValueMaxCapacityExceeded(uint256 capacity, uint256 requested); + error AggregateValueRateLimitReached(uint256 minWaitInSeconds, uint256 available); + error InvalidRateLimitRate(Config rateLimiterConfig); + error DisabledNonZeroRateLimit(Config config); + error RateLimitMustBeDisabled(); + + event TokensConsumed(uint256 tokens); + event ConfigChanged(Config config); + + struct TokenBucket { + uint128 tokens; // ──────╮ Current number of tokens that are in the bucket. + uint32 lastUpdated; // │ Timestamp in seconds of the last token refill, good for 100+ years. + bool isEnabled; // ──────╯ Indication whether the rate limiting is enabled or not + uint128 capacity; // ────╮ Maximum number of tokens that can be in the bucket. + uint128 rate; // ────────╯ Number of tokens per second that the bucket is refilled. + } + + struct Config { + bool isEnabled; // Indication whether the rate limiting should be enabled + uint128 capacity; // ────╮ Specifies the capacity of the rate limiter + uint128 rate; // ───────╯ Specifies the rate of the rate limiter + } + + /// @notice _consume removes the given tokens from the pool, lowering the + /// rate tokens allowed to be consumed for subsequent calls. + /// @param requestTokens The total tokens to be consumed from the bucket. + /// @param tokenAddress The token to consume capacity for, use 0x0 to indicate aggregate value capacity. + /// @dev Reverts when requestTokens exceeds bucket capacity or available tokens in the bucket + /// @dev emits removal of requestTokens if requestTokens is > 0 + function _consume(TokenBucket storage s_bucket, uint256 requestTokens, address tokenAddress) internal { + // If there is no value to remove or rate limiting is turned off, skip this step to reduce gas usage + if (!s_bucket.isEnabled || requestTokens == 0) { + return; + } + + uint256 tokens = s_bucket.tokens; + uint256 capacity = s_bucket.capacity; + uint256 timeDiff = block.timestamp - s_bucket.lastUpdated; + + if (timeDiff != 0) { + if (tokens > capacity) revert BucketOverfilled(); + + // Refill tokens when arriving at a new block time + tokens = _calculateRefill(capacity, tokens, timeDiff, s_bucket.rate); + + s_bucket.lastUpdated = uint32(block.timestamp); + } + + if (capacity < requestTokens) { + // Token address 0 indicates consuming aggregate value rate limit capacity. + if (tokenAddress == address(0)) revert AggregateValueMaxCapacityExceeded(capacity, requestTokens); + revert TokenMaxCapacityExceeded(capacity, requestTokens, tokenAddress); + } + if (tokens < requestTokens) { + uint256 rate = s_bucket.rate; + // Wait required until the bucket is refilled enough to accept this value, round up to next higher second + // Consume is not guaranteed to succeed after wait time passes if there is competing traffic. + // This acts as a lower bound of wait time. + uint256 minWaitInSeconds = ((requestTokens - tokens) + (rate - 1)) / rate; + + if (tokenAddress == address(0)) revert AggregateValueRateLimitReached(minWaitInSeconds, tokens); + revert TokenRateLimitReached(minWaitInSeconds, tokens, tokenAddress); + } + tokens -= requestTokens; + + // Downcast is safe here, as tokens is not larger than capacity + s_bucket.tokens = uint128(tokens); + emit TokensConsumed(requestTokens); + } + + /// @notice Gets the token bucket with its values for the block it was requested at. + /// @return The token bucket. + function _currentTokenBucketState(TokenBucket memory bucket) internal view returns (TokenBucket memory) { + // We update the bucket to reflect the status at the exact time of the + // call. This means we might need to refill a part of the bucket based + // on the time that has passed since the last update. + bucket.tokens = + uint128(_calculateRefill(bucket.capacity, bucket.tokens, block.timestamp - bucket.lastUpdated, bucket.rate)); + bucket.lastUpdated = uint32(block.timestamp); + return bucket; + } + + /// @notice Sets the rate limited config. + /// @param s_bucket The token bucket + /// @param config The new config + function _setTokenBucketConfig(TokenBucket storage s_bucket, Config memory config) internal { + // First update the bucket to make sure the proper rate is used for all the time + // up until the config change. + uint256 timeDiff = block.timestamp - s_bucket.lastUpdated; + if (timeDiff != 0) { + s_bucket.tokens = uint128(_calculateRefill(s_bucket.capacity, s_bucket.tokens, timeDiff, s_bucket.rate)); + + s_bucket.lastUpdated = uint32(block.timestamp); + } + + s_bucket.tokens = uint128(_min(config.capacity, s_bucket.tokens)); + s_bucket.isEnabled = config.isEnabled; + s_bucket.capacity = config.capacity; + s_bucket.rate = config.rate; + + emit ConfigChanged(config); + } + + /// @notice Validates the token bucket config + function _validateTokenBucketConfig(Config memory config, bool mustBeDisabled) internal pure { + if (config.isEnabled) { + if (config.rate >= config.capacity || config.rate == 0) { + revert InvalidRateLimitRate(config); + } + if (mustBeDisabled) { + revert RateLimitMustBeDisabled(); + } + } else { + if (config.rate != 0 || config.capacity != 0) { + revert DisabledNonZeroRateLimit(config); + } + } + } + + /// @notice Calculate refilled tokens + /// @param capacity bucket capacity + /// @param tokens current bucket tokens + /// @param timeDiff block time difference since last refill + /// @param rate bucket refill rate + /// @return the value of tokens after refill + function _calculateRefill( + uint256 capacity, + uint256 tokens, + uint256 timeDiff, + uint256 rate + ) private pure returns (uint256) { + return _min(capacity, tokens + timeDiff * rate); + } + + /// @notice Return the smallest of two integers + /// @param a first int + /// @param b second int + /// @return smallest + function _min(uint256 a, uint256 b) internal pure returns (uint256) { + return a < b ? a : b; + } +} diff --git a/contracts/src/v0.8/ccip/libraries/USDPriceWith18Decimals.sol b/contracts/src/v0.8/ccip/libraries/USDPriceWith18Decimals.sol new file mode 100644 index 0000000000..3508276d76 --- /dev/null +++ b/contracts/src/v0.8/ccip/libraries/USDPriceWith18Decimals.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +library USDPriceWith18Decimals { + /// @notice Takes a price in USD, with 18 decimals per 1e18 token amount, + /// and amount of the smallest token denomination, + /// calculates the value in USD with 18 decimals. + /// @param tokenPrice The USD price of the token. + /// @param tokenAmount Amount of the smallest token denomination. + /// @return USD value with 18 decimals. + /// @dev this function assumes that no more than 1e59 US dollar worth of token is passed in. + /// If more is sent, this function will overflow and revert. + /// Since there isn't even close to 1e59 dollars, this is ok for all legit tokens. + function _calcUSDValueFromTokenAmount(uint224 tokenPrice, uint256 tokenAmount) internal pure returns (uint256) { + /// LINK Example: + /// tokenPrice: 8e18 -> $8/LINK, as 1e18 token amount is 1 LINK, worth 8 USD, or 8e18 with 18 decimals + /// tokenAmount: 2e18 -> 2 LINK + /// result: 8e18 * 2e18 / 1e18 -> 16e18 with 18 decimals = $16 + + /// USDC Example: + /// tokenPrice: 1e30 -> $1/USDC, as 1e18 token amount is 1e12 USDC, worth 1e12 USD, or 1e30 with 18 decimals + /// tokenAmount: 5e6 -> 5 USDC + /// result: 1e30 * 5e6 / 1e18 -> 5e18 with 18 decimals = $5 + return (tokenPrice * tokenAmount) / 1e18; + } + + /// @notice Takes a price in USD, with 18 decimals per 1e18 token amount, + /// and USD value with 18 decimals, + /// calculates amount of the smallest token denomination. + /// @param tokenPrice The USD price of the token. + /// @param usdValue USD value with 18 decimals. + /// @return Amount of the smallest token denomination. + function _calcTokenAmountFromUSDValue(uint224 tokenPrice, uint256 usdValue) internal pure returns (uint256) { + /// LINK Example: + /// tokenPrice: 8e18 -> $8/LINK, as 1e18 token amount is 1 LINK, worth 8 USD, or 8e18 with 18 decimals + /// usdValue: 16e18 -> $16 + /// result: 16e18 * 1e18 / 8e18 -> 2e18 = 2 LINK + + /// USDC Example: + /// tokenPrice: 1e30 -> $1/USDC, as 1e18 token amount is 1e12 USDC, worth 1e12 USD, or 1e30 with 18 decimals + /// usdValue: 5e18 -> $5 + /// result: 5e18 * 1e18 / 1e30 -> 5e6 = 5 USDC + return (usdValue * 1e18) / tokenPrice; + } +} diff --git a/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol b/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol new file mode 100644 index 0000000000..1872ae276c --- /dev/null +++ b/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; + +/// @notice Onchain verification of reports from the offchain reporting protocol +/// with multiple OCR plugin support. +abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { + // Maximum number of oracles the offchain reporting protocol is designed for + uint256 internal constant MAX_NUM_ORACLES = 31; + + /// @notice triggers a new run of the offchain reporting protocol + /// @param ocrPluginType OCR plugin type for which the config was set + /// @param configDigest configDigest of this configuration + /// @param signers ith element is address ith oracle uses to sign a report + /// @param transmitters ith element is address ith oracle uses to transmit a report via the transmit method + /// @param F maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly + event ConfigSet(uint8 ocrPluginType, bytes32 configDigest, address[] signers, address[] transmitters, uint8 F); + + /// @notice optionally emitted to indicate the latest configDigest and sequence number + /// for which a report was successfully transmitted. Alternatively, the contract may + /// use latestConfigDigestAndEpoch with scanLogs set to false. + event Transmitted(uint8 indexed ocrPluginType, bytes32 configDigest, uint64 sequenceNumber); + + enum InvalidConfigErrorType { + F_MUST_BE_POSITIVE, + TOO_MANY_TRANSMITTERS, + TOO_MANY_SIGNERS, + F_TOO_HIGH, + REPEATED_ORACLE_ADDRESS + } + + error InvalidConfig(InvalidConfigErrorType errorType); + error WrongMessageLength(uint256 expected, uint256 actual); + error ConfigDigestMismatch(bytes32 expected, bytes32 actual); + error ForkedChain(uint256 expected, uint256 actual); + error WrongNumberOfSignatures(); + error SignaturesOutOfRegistration(); + error UnauthorizedTransmitter(); + error UnauthorizedSigner(); + error NonUniqueSignatures(); + error OracleCannotBeZeroAddress(); + error StaticConfigCannotBeChanged(uint8 ocrPluginType); + + /// @dev Packing these fields used on the hot path in a ConfigInfo variable reduces the + /// retrieval of all of them to a minimum number of SLOADs. + struct ConfigInfo { + bytes32 configDigest; + uint8 F; // ──────────────────────────────╮ maximum number of faulty/dishonest oracles the system can tolerate + uint8 n; // │ number of signers / transmitters + bool isSignatureVerificationEnabled; // ──╯ if true, requires signers and verifies signatures on transmission verification + } + + /// @notice Used for s_oracles[a].role, where a is an address, to track the purpose + /// of the address, or to indicate that the address is unset. + enum Role { + // No oracle role has been set for address a + Unset, + // Signing address for the s_oracles[a].index'th oracle. I.e., report + // signatures from this oracle should ecrecover back to address a. + Signer, + // Transmission address for the s_oracles[a].index'th oracle. I.e., if a + // report is received by OCR2Aggregator.transmit in which msg.sender is + // a, it is attributed to the s_oracles[a].index'th oracle. + Transmitter + } + + struct Oracle { + uint8 index; // ───╮ Index of oracle in s_signers/s_transmitters + Role role; // ─────╯ Role of the address which mapped to this struct + } + + /// @notice OCR configuration for a single OCR plugin within a DON + struct OCRConfig { + ConfigInfo configInfo; // latest OCR config + address[] signers; // addresses oracles use to sign the reports + address[] transmitters; // addresses oracles use to transmit the reports + } + + /// @notice Args to update an OCR Config + struct OCRConfigArgs { + bytes32 configDigest; // Config digest to update to + uint8 ocrPluginType; // ──────────────────╮ OCR plugin type to update config for + uint8 F; // │ maximum number of faulty/dishonest oracles + bool isSignatureVerificationEnabled; // ──╯ if true, requires signers and verifies signatures on transmission verification + address[] signers; // signing address of each oracle + address[] transmitters; // transmission address of each oracle (i.e. the address the oracle actually sends transactions to the contract from) + } + + /// @notice mapping of OCR plugin type -> DON config + mapping(uint8 ocrPluginType => OCRConfig config) internal s_ocrConfigs; + + /// @notice OCR plugin type => signer OR transmitter address mapping + mapping(uint8 ocrPluginType => mapping(address signerOrTransmiter => Oracle oracle)) internal s_oracles; + + // Constant-length components of the msg.data sent to transmit. + // See the "If we wanted to call sam" example on for example reasoning + // https://solidity.readthedocs.io/en/v0.7.2/abi-spec.html + + /// @notice constant length component for transmit functions with no signatures. + /// The signatures are expected to match transmitPlugin(reportContext, report) + uint16 private constant TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT_NO_SIGNATURES = 4 // function selector + + 3 * 32 // 3 words containing reportContext + + 32 // word containing start location of abiencoded report value + + 32; // word containing length of report + + /// @notice extra constant length component for transmit functions with signatures (relative to no signatures) + /// The signatures are expected to match transmitPlugin(reportContext, report, rs, ss, rawVs) + uint16 private constant TRANSMIT_MSGDATA_EXTRA_CONSTANT_LENGTH_COMPONENT_FOR_SIGNATURES = 32 // word containing location start of abiencoded rs value + + 32 // word containing start location of abiencoded ss value + + 32 // rawVs value + + 32 // word containing length rs + + 32; // word containing length of ss + + uint256 internal immutable i_chainID; + + constructor() { + i_chainID = block.chainid; + } + + /// @notice sets offchain reporting protocol configuration incl. participating oracles + /// NOTE: The OCR3 config must be sanity-checked against the home-chain registry configuration, to ensure + /// home-chain and remote-chain parity! + /// @param ocrConfigArgs OCR config update args + function setOCR3Configs(OCRConfigArgs[] memory ocrConfigArgs) external onlyOwner { + for (uint256 i; i < ocrConfigArgs.length; ++i) { + _setOCR3Config(ocrConfigArgs[i]); + } + } + + /// @notice sets offchain reporting protocol configuration incl. participating oracles for a single OCR plugin type + /// @param ocrConfigArgs OCR config update args + function _setOCR3Config(OCRConfigArgs memory ocrConfigArgs) internal { + if (ocrConfigArgs.F == 0) revert InvalidConfig(InvalidConfigErrorType.F_MUST_BE_POSITIVE); + + uint8 ocrPluginType = ocrConfigArgs.ocrPluginType; + OCRConfig storage ocrConfig = s_ocrConfigs[ocrPluginType]; + ConfigInfo storage configInfo = ocrConfig.configInfo; + + // If F is 0, then the config is not yet set + if (configInfo.F == 0) { + configInfo.isSignatureVerificationEnabled = ocrConfigArgs.isSignatureVerificationEnabled; + } else if (configInfo.isSignatureVerificationEnabled != ocrConfigArgs.isSignatureVerificationEnabled) { + revert StaticConfigCannotBeChanged(ocrPluginType); + } + + address[] memory transmitters = ocrConfigArgs.transmitters; + // Transmitters are expected to never exceed 255 (since this is bounded by MAX_NUM_ORACLES) + uint8 newTransmittersLength = uint8(transmitters.length); + + if (newTransmittersLength > MAX_NUM_ORACLES) revert InvalidConfig(InvalidConfigErrorType.TOO_MANY_TRANSMITTERS); + + _clearOracleRoles(ocrPluginType, ocrConfig.transmitters); + + if (ocrConfigArgs.isSignatureVerificationEnabled) { + _clearOracleRoles(ocrPluginType, ocrConfig.signers); + + address[] memory signers = ocrConfigArgs.signers; + ocrConfig.signers = signers; + + uint8 signersLength = uint8(signers.length); + configInfo.n = signersLength; + + if (signersLength > MAX_NUM_ORACLES) revert InvalidConfig(InvalidConfigErrorType.TOO_MANY_SIGNERS); + if (signersLength <= 3 * ocrConfigArgs.F) revert InvalidConfig(InvalidConfigErrorType.F_TOO_HIGH); + + _assignOracleRoles(ocrPluginType, signers, Role.Signer); + } + + _assignOracleRoles(ocrPluginType, transmitters, Role.Transmitter); + + ocrConfig.transmitters = transmitters; + configInfo.F = ocrConfigArgs.F; + configInfo.configDigest = ocrConfigArgs.configDigest; + + emit ConfigSet( + ocrPluginType, ocrConfigArgs.configDigest, ocrConfig.signers, ocrConfigArgs.transmitters, ocrConfigArgs.F + ); + _afterOCR3ConfigSet(ocrPluginType); + } + + /// @notice Hook that is called after a plugin's OCR3 config changes + /// @param ocrPluginType Plugin type for which the config changed + function _afterOCR3ConfigSet(uint8 ocrPluginType) internal virtual; + + /// @notice Clears oracle roles for the provided oracle addresses + /// @param ocrPluginType OCR plugin type to clear roles for + /// @param oracleAddresses Oracle addresses to clear roles for + function _clearOracleRoles(uint8 ocrPluginType, address[] memory oracleAddresses) internal { + for (uint256 i = 0; i < oracleAddresses.length; ++i) { + delete s_oracles[ocrPluginType][oracleAddresses[i]]; + } + } + + /// @notice Assigns oracles roles for the provided oracle addresses with uniqueness verification + /// @param ocrPluginType OCR plugin type to assign roles for + /// @param oracleAddresses Oracle addresses to assign roles to + /// @param role Role to assign + function _assignOracleRoles(uint8 ocrPluginType, address[] memory oracleAddresses, Role role) internal { + for (uint8 i = 0; i < oracleAddresses.length; ++i) { + address oracle = oracleAddresses[i]; + if (s_oracles[ocrPluginType][oracle].role != Role.Unset) { + revert InvalidConfig(InvalidConfigErrorType.REPEATED_ORACLE_ADDRESS); + } + if (oracle == address(0)) revert OracleCannotBeZeroAddress(); + s_oracles[ocrPluginType][oracle] = Oracle(i, role); + } + } + + /// @notice _transmit is called to post a new report to the contract. + /// The function should be called after the per-DON reporting logic is completed. + /// @param ocrPluginType OCR plugin type to transmit report for + /// @param report serialized report, which the signatures are signing. + /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param rawVs ith element is the the V component of the ith signature + function _transmit( + uint8 ocrPluginType, + // NOTE: If these parameters are changed, expectedMsgDataLength and/or + // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly + bytes32[3] calldata reportContext, + bytes calldata report, + bytes32[] memory rs, + bytes32[] memory ss, + bytes32 rawVs // signatures + ) internal { + // reportContext consists of: + // reportContext[0]: ConfigDigest + // reportContext[1]: 24 byte padding, 8 byte sequence number + // reportContext[2]: ExtraHash + ConfigInfo memory configInfo = s_ocrConfigs[ocrPluginType].configInfo; + bytes32 configDigest = reportContext[0]; + + // Scoping this reduces stack pressure and gas usage + { + uint256 expectedDataLength = uint256(TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT_NO_SIGNATURES) + report.length; // one byte pure entry in _report + + if (configInfo.isSignatureVerificationEnabled) { + expectedDataLength += TRANSMIT_MSGDATA_EXTRA_CONSTANT_LENGTH_COMPONENT_FOR_SIGNATURES + rs.length * 32 // 32 bytes per entry in _rs + + ss.length * 32; // 32 bytes per entry in _ss) + } + + if (msg.data.length != expectedDataLength) revert WrongMessageLength(expectedDataLength, msg.data.length); + } + + if (configInfo.configDigest != configDigest) { + revert ConfigDigestMismatch(configInfo.configDigest, configDigest); + } + // If the cached chainID at time of deployment doesn't match the current chainID, we reject all signed reports. + // This avoids a (rare) scenario where chain A forks into chain A and A', A' still has configDigest + // calculated from chain A and so OCR reports will be valid on both forks. + _whenChainNotForked(); + + // Scoping this reduces stack pressure and gas usage + { + Oracle memory transmitter = s_oracles[ocrPluginType][msg.sender]; + // Check that sender is authorized to report + if ( + !( + transmitter.role == Role.Transmitter + && msg.sender == s_ocrConfigs[ocrPluginType].transmitters[transmitter.index] + ) + ) { + revert UnauthorizedTransmitter(); + } + } + + if (configInfo.isSignatureVerificationEnabled) { + // Scoping to reduce stack pressure + { + if (rs.length != configInfo.F + 1) revert WrongNumberOfSignatures(); + if (rs.length != ss.length) revert SignaturesOutOfRegistration(); + } + + bytes32 h = keccak256(abi.encodePacked(keccak256(report), reportContext)); + _verifySignatures(ocrPluginType, h, rs, ss, rawVs); + } + + emit Transmitted(ocrPluginType, configDigest, uint64(uint256(reportContext[1]))); + } + + /// @notice verifies the signatures of a hashed report value for one OCR plugin type + /// @param ocrPluginType OCR plugin type to transmit report for + /// @param hashedReport hashed encoded packing of report + reportContext + /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param rawVs ith element is the the V component of the ith signature + function _verifySignatures( + uint8 ocrPluginType, + bytes32 hashedReport, + bytes32[] memory rs, + bytes32[] memory ss, + bytes32 rawVs // signatures + ) internal view { + // Verify signatures attached to report + bool[MAX_NUM_ORACLES] memory signed; + + uint256 numberOfSignatures = rs.length; + for (uint256 i; i < numberOfSignatures; ++i) { + // Safe from ECDSA malleability here since we check for duplicate signers. + address signer = ecrecover(hashedReport, uint8(rawVs[i]) + 27, rs[i], ss[i]); + // Since we disallow address(0) as a valid signer address, it can + // never have a signer role. + Oracle memory oracle = s_oracles[ocrPluginType][signer]; + if (oracle.role != Role.Signer) revert UnauthorizedSigner(); + if (signed[oracle.index]) revert NonUniqueSignatures(); + signed[oracle.index] = true; + } + } + + /// @notice Validates that the chain ID has not diverged after deployment. Reverts if the chain IDs do not match + function _whenChainNotForked() internal view { + if (i_chainID != block.chainid) revert ForkedChain(i_chainID, block.chainid); + } + + /// @notice information about current offchain reporting protocol configuration + /// @param ocrPluginType OCR plugin type to return config details for + /// @return ocrConfig OCR config for the plugin type + function latestConfigDetails(uint8 ocrPluginType) external view returns (OCRConfig memory ocrConfig) { + return s_ocrConfigs[ocrPluginType]; + } +} diff --git a/contracts/src/v0.8/ccip/ocr/OCR2Abstract.sol b/contracts/src/v0.8/ccip/ocr/OCR2Abstract.sol new file mode 100644 index 0000000000..741433bd5a --- /dev/null +++ b/contracts/src/v0.8/ccip/ocr/OCR2Abstract.sol @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; + +abstract contract OCR2Abstract is ITypeAndVersion { + // Maximum number of oracles the offchain reporting protocol is designed for + uint256 internal constant MAX_NUM_ORACLES = 31; + + /// @notice triggers a new run of the offchain reporting protocol + /// @param previousConfigBlockNumber block in which the previous config was set, to simplify historic analysis + /// @param configDigest configDigest of this configuration + /// @param configCount ordinal number of this config setting among all config settings over the life of this contract + /// @param signers ith element is address ith oracle uses to sign a report + /// @param transmitters ith element is address ith oracle uses to transmit a report via the transmit method + /// @param f maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly + /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) + /// @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter + /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + event ConfigSet( + uint32 previousConfigBlockNumber, + bytes32 configDigest, + uint64 configCount, + address[] signers, + address[] transmitters, + uint8 f, + bytes onchainConfig, + uint64 offchainConfigVersion, + bytes offchainConfig + ); + + /// @notice sets offchain reporting protocol configuration incl. participating oracles + /// @param signers addresses with which oracles sign the reports + /// @param transmitters addresses oracles use to transmit the reports + /// @param f number of faulty oracles the system can tolerate + /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) + /// @param offchainConfigVersion version number for offchainEncoding schema + /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + function setOCR2Config( + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external virtual; + + /// @notice information about current offchain reporting protocol configuration + /// @return configCount ordinal number of current config, out of all configs applied to this contract so far + /// @return blockNumber block at which this config was set + /// @return configDigest domain-separation tag for current config (see _configDigestFromConfigData) + function latestConfigDetails() + external + view + virtual + returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest); + + function _configDigestFromConfigData( + uint256 chainId, + address contractAddress, + uint64 configCount, + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + chainId, + contractAddress, + configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + uint256 prefix = 0x0001 << (256 - 16); // 0x000100..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + /// @notice optionally emitted to indicate the latest configDigest and epoch for + /// which a report was successfully transmitted. Alternatively, the contract may + /// use latestConfigDigestAndEpoch with scanLogs set to false. + event Transmitted(bytes32 configDigest, uint32 epoch); + + /// @notice optionally returns the latest configDigest and epoch for which a + /// report was successfully transmitted. Alternatively, the contract may return + /// scanLogs set to true and use Transmitted events to provide this information + /// to offchain watchers. + /// @return scanLogs indicates whether to rely on the configDigest and epoch + /// returned or whether to scan logs for the Transmitted event instead. + /// @return configDigest + /// @return epoch + function latestConfigDigestAndEpoch() + external + view + virtual + returns (bool scanLogs, bytes32 configDigest, uint32 epoch); + + /// @notice transmit is called to post a new report to the contract + /// @param report serialized report, which the signatures are signing. + /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param rawVs ith element is the the V component of the ith signature + function transmit( + // NOTE: If these parameters are changed, expectedMsgDataLength and/or + // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly + bytes32[3] calldata reportContext, + bytes calldata report, + bytes32[] calldata rs, + bytes32[] calldata ss, + bytes32 rawVs // signatures + ) external virtual; +} diff --git a/contracts/src/v0.8/ccip/ocr/OCR2Base.sol b/contracts/src/v0.8/ccip/ocr/OCR2Base.sol new file mode 100644 index 0000000000..52a6df2f3a --- /dev/null +++ b/contracts/src/v0.8/ccip/ocr/OCR2Base.sol @@ -0,0 +1,291 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; +import {OCR2Abstract} from "./OCR2Abstract.sol"; + +/// @notice Onchain verification of reports from the offchain reporting protocol +/// @dev For details on its operation, see the offchain reporting protocol design +/// doc, which refers to this contract as simply the "contract". +abstract contract OCR2Base is OwnerIsCreator, OCR2Abstract { + error InvalidConfig(InvalidConfigErrorType errorType); + error WrongMessageLength(uint256 expected, uint256 actual); + error ConfigDigestMismatch(bytes32 expected, bytes32 actual); + error ForkedChain(uint256 expected, uint256 actual); + error WrongNumberOfSignatures(); + error SignaturesOutOfRegistration(); + error UnauthorizedTransmitter(); + error UnauthorizedSigner(); + error NonUniqueSignatures(); + error OracleCannotBeZeroAddress(); + + enum InvalidConfigErrorType { + F_MUST_BE_POSITIVE, + TOO_MANY_SIGNERS, + F_TOO_HIGH, + REPEATED_ORACLE_ADDRESS, + NUM_SIGNERS_NOT_NUM_TRANSMITTERS + } + + // Packing these fields used on the hot path in a ConfigInfo variable reduces the + // retrieval of all of them to a minimum number of SLOADs. + struct ConfigInfo { + bytes32 latestConfigDigest; + uint8 f; + uint8 n; + } + + // Used for s_oracles[a].role, where a is an address, to track the purpose + // of the address, or to indicate that the address is unset. + enum Role { + // No oracle role has been set for address a + Unset, + // Signing address for the s_oracles[a].index'th oracle. I.e., report + // signatures from this oracle should ecrecover back to address a. + Signer, + // Transmission address for the s_oracles[a].index'th oracle. I.e., if a + // report is received by OCR2Aggregator.transmit in which msg.sender is + // a, it is attributed to the s_oracles[a].index'th oracle. + Transmitter + } + + struct Oracle { + uint8 index; // Index of oracle in s_signers/s_transmitters + Role role; // Role of the address which mapped to this struct + } + + // The current config + ConfigInfo internal s_configInfo; + + // incremented each time a new config is posted. This count is incorporated + // into the config digest, to prevent replay attacks. + uint32 internal s_configCount; + // makes it easier for offchain systems to extract config from logs. + uint32 internal s_latestConfigBlockNumber; + + // signer OR transmitter address + mapping(address signerOrTransmitter => Oracle oracle) internal s_oracles; + + // s_signers contains the signing address of each oracle + address[] internal s_signers; + + // s_transmitters contains the transmission address of each oracle, + // i.e. the address the oracle actually sends transactions to the contract from + address[] internal s_transmitters; + + // The constant-length components of the msg.data sent to transmit. + // See the "If we wanted to call sam" example on for example reasoning + // https://solidity.readthedocs.io/en/v0.7.2/abi-spec.html + uint16 private constant TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT = 4 // function selector + + 32 * 3 // 3 words containing reportContext + + 32 // word containing start location of abiencoded report value + + 32 // word containing location start of abiencoded rs value + + 32 // word containing start location of abiencoded ss value + + 32 // rawVs value + + 32 // word containing length of report + + 32 // word containing length rs + + 32; // word containing length of ss + + bool internal immutable i_uniqueReports; + uint256 internal immutable i_chainID; + + constructor(bool uniqueReports) { + i_uniqueReports = uniqueReports; + i_chainID = block.chainid; + } + + // Reverts transaction if config args are invalid + modifier checkConfigValid(uint256 numSigners, uint256 numTransmitters, uint256 f) { + if (numSigners > MAX_NUM_ORACLES) revert InvalidConfig(InvalidConfigErrorType.TOO_MANY_SIGNERS); + if (f == 0) revert InvalidConfig(InvalidConfigErrorType.F_MUST_BE_POSITIVE); + if (numSigners != numTransmitters) revert InvalidConfig(InvalidConfigErrorType.NUM_SIGNERS_NOT_NUM_TRANSMITTERS); + if (numSigners <= 3 * f) revert InvalidConfig(InvalidConfigErrorType.F_TOO_HIGH); + _; + } + + /// @notice sets offchain reporting protocol configuration incl. participating oracles + /// @param signers addresses with which oracles sign the reports + /// @param transmitters addresses oracles use to transmit the reports + /// @param f number of faulty oracles the system can tolerate + /// @param onchainConfig encoded on-chain contract configuration + /// @param offchainConfigVersion version number for offchainEncoding schema + /// @param offchainConfig encoded off-chain oracle configuration + function setOCR2Config( + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external override checkConfigValid(signers.length, transmitters.length, f) onlyOwner { + _beforeSetConfig(onchainConfig); + uint256 oldSignerLength = s_signers.length; + for (uint256 i = 0; i < oldSignerLength; ++i) { + delete s_oracles[s_signers[i]]; + delete s_oracles[s_transmitters[i]]; + } + + uint256 newSignersLength = signers.length; + for (uint256 i = 0; i < newSignersLength; ++i) { + // add new signer/transmitter addresses + address signer = signers[i]; + if (s_oracles[signer].role != Role.Unset) revert InvalidConfig(InvalidConfigErrorType.REPEATED_ORACLE_ADDRESS); + if (signer == address(0)) revert OracleCannotBeZeroAddress(); + s_oracles[signer] = Oracle(uint8(i), Role.Signer); + + address transmitter = transmitters[i]; + if (s_oracles[transmitter].role != Role.Unset) { + revert InvalidConfig(InvalidConfigErrorType.REPEATED_ORACLE_ADDRESS); + } + if (transmitter == address(0)) revert OracleCannotBeZeroAddress(); + s_oracles[transmitter] = Oracle(uint8(i), Role.Transmitter); + } + + s_signers = signers; + s_transmitters = transmitters; + + s_configInfo.f = f; + s_configInfo.n = uint8(newSignersLength); + s_configInfo.latestConfigDigest = _configDigestFromConfigData( + block.chainid, + address(this), + ++s_configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + + uint32 previousConfigBlockNumber = s_latestConfigBlockNumber; + s_latestConfigBlockNumber = uint32(block.number); + + emit ConfigSet( + previousConfigBlockNumber, + s_configInfo.latestConfigDigest, + s_configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + } + + /// @dev Hook that is run from setOCR2Config() right after validating configuration. + /// Empty by default, please provide an implementation in a child contract if you need additional configuration processing + function _beforeSetConfig(bytes memory _onchainConfig) internal virtual; + + /// @return list of addresses permitted to transmit reports to this contract + /// @dev The list will match the order used to specify the transmitter during setConfig + function getTransmitters() external view returns (address[] memory) { + return s_transmitters; + } + + /// @notice transmit is called to post a new report to the contract + /// @param report serialized report, which the signatures are signing. + /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param rawVs ith element is the the V component of the ith signature + function transmit( + // NOTE: If these parameters are changed, expectedMsgDataLength and/or + // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly + bytes32[3] calldata reportContext, + bytes calldata report, + bytes32[] calldata rs, + bytes32[] calldata ss, + bytes32 rawVs // signatures + ) external override { + // Scoping this reduces stack pressure and gas usage + { + // report and epochAndRound + _report(report, uint40(uint256(reportContext[1]))); + } + + // reportContext consists of: + // reportContext[0]: ConfigDigest + // reportContext[1]: 27 byte padding, 4-byte epoch and 1-byte round + // reportContext[2]: ExtraHash + bytes32 configDigest = reportContext[0]; + ConfigInfo memory configInfo = s_configInfo; + + if (configInfo.latestConfigDigest != configDigest) { + revert ConfigDigestMismatch(configInfo.latestConfigDigest, configDigest); + } + // If the cached chainID at time of deployment doesn't match the current chainID, we reject all signed reports. + // This avoids a (rare) scenario where chain A forks into chain A and A', A' still has configDigest + // calculated from chain A and so OCR reports will be valid on both forks. + if (i_chainID != block.chainid) revert ForkedChain(i_chainID, block.chainid); + + emit Transmitted(configDigest, uint32(uint256(reportContext[1]) >> 8)); + + uint256 expectedNumSignatures; + if (i_uniqueReports) { + expectedNumSignatures = (configInfo.n + configInfo.f) / 2 + 1; + } else { + expectedNumSignatures = configInfo.f + 1; + } + if (rs.length != expectedNumSignatures) revert WrongNumberOfSignatures(); + if (rs.length != ss.length) revert SignaturesOutOfRegistration(); + + // Scoping this reduces stack pressure and gas usage + { + Oracle memory transmitter = s_oracles[msg.sender]; + // Check that sender is authorized to report + if (!(transmitter.role == Role.Transmitter && msg.sender == s_transmitters[transmitter.index])) { + revert UnauthorizedTransmitter(); + } + } + // Scoping this reduces stack pressure and gas usage + { + uint256 expectedDataLength = uint256(TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT) + report.length // one byte pure entry in _report + + rs.length * 32 // 32 bytes per entry in _rs + + ss.length * 32; // 32 bytes per entry in _ss) + if (msg.data.length != expectedDataLength) revert WrongMessageLength(expectedDataLength, msg.data.length); + } + + // Verify signatures attached to report + bytes32 h = keccak256(abi.encodePacked(keccak256(report), reportContext)); + bool[MAX_NUM_ORACLES] memory signed; + + uint256 numberOfSignatures = rs.length; + for (uint256 i = 0; i < numberOfSignatures; ++i) { + // Safe from ECDSA malleability here since we check for duplicate signers. + address signer = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]); + // Since we disallow address(0) as a valid signer address, it can + // never have a signer role. + Oracle memory oracle = s_oracles[signer]; + if (oracle.role != Role.Signer) revert UnauthorizedSigner(); + if (signed[oracle.index]) revert NonUniqueSignatures(); + signed[oracle.index] = true; + } + } + + /// @notice information about current offchain reporting protocol configuration + /// @return configCount ordinal number of current config, out of all configs applied to this contract so far + /// @return blockNumber block at which this config was set + /// @return configDigest domain-separation tag for current config (see _configDigestFromConfigData) + function latestConfigDetails() + external + view + override + returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) + { + return (s_configCount, s_latestConfigBlockNumber, s_configInfo.latestConfigDigest); + } + + /// @inheritdoc OCR2Abstract + function latestConfigDigestAndEpoch() + external + view + virtual + override + returns (bool scanLogs, bytes32 configDigest, uint32 epoch) + { + return (true, bytes32(0), uint32(0)); + } + + function _report(bytes calldata report, uint40 epochAndRound) internal virtual; +} diff --git a/contracts/src/v0.8/ccip/ocr/OCR2BaseNoChecks.sol b/contracts/src/v0.8/ccip/ocr/OCR2BaseNoChecks.sol new file mode 100644 index 0000000000..a79df8d589 --- /dev/null +++ b/contracts/src/v0.8/ccip/ocr/OCR2BaseNoChecks.sol @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; +import {OCR2Abstract} from "./OCR2Abstract.sol"; + +/// @notice Onchain verification of reports from the offchain reporting protocol +/// @dev For details on its operation, see the offchain reporting protocol design +/// doc, which refers to this contract as simply the "contract". +/// @dev This contract does ***NOT*** check the supplied signatures on `transmit` +/// This is intentional. +abstract contract OCR2BaseNoChecks is OwnerIsCreator, OCR2Abstract { + error InvalidConfig(InvalidConfigErrorType errorType); + error WrongMessageLength(uint256 expected, uint256 actual); + error ConfigDigestMismatch(bytes32 expected, bytes32 actual); + error ForkedChain(uint256 expected, uint256 actual); + error UnauthorizedTransmitter(); + error OracleCannotBeZeroAddress(); + + enum InvalidConfigErrorType { + F_MUST_BE_POSITIVE, + TOO_MANY_TRANSMITTERS, + REPEATED_ORACLE_ADDRESS + } + + // Packing these fields used on the hot path in a ConfigInfo variable reduces the + // retrieval of all of them to a minimum number of SLOADs. + struct ConfigInfo { + bytes32 latestConfigDigest; + uint8 f; + uint8 n; + } + + // Used for s_oracles[a].role, where a is an address, to track the purpose + // of the address, or to indicate that the address is unset. + enum Role { + // No oracle role has been set for address a + Unset, + // Unused + Signer, + // Transmission address for the s_oracles[a].index'th oracle. I.e., if a + // report is received by OCR2Aggregator.transmit in which msg.sender is + // a, it is attributed to the s_oracles[a].index'th oracle. + Transmitter + } + + struct Oracle { + uint8 index; // Index of oracle in s_transmitters + Role role; // Role of the address which mapped to this struct + } + + // The current config + ConfigInfo internal s_configInfo; + + // incremented each time a new config is posted. This count is incorporated + // into the config digest, to prevent replay attacks. + uint32 internal s_configCount; + // makes it easier for offchain systems to extract config from logs. + uint32 internal s_latestConfigBlockNumber; + + // Transmitter address + mapping(address transmitter => Oracle oracle) internal s_oracles; + + // s_transmitters contains the transmission address of each oracle, + // i.e. the address the oracle actually sends transactions to the contract from + address[] internal s_transmitters; + + // The constant-length components of the msg.data sent to transmit. + // See the "If we wanted to call sam" example on for example reasoning + // https://solidity.readthedocs.io/en/v0.7.2/abi-spec.html + uint16 private constant TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT = 4 // function selector + + 32 * 3 // 3 words containing reportContext + + 32 // word containing start location of abiencoded report value + + 32 // word containing location start of abiencoded rs value + + 32 // word containing start location of abiencoded ss value + + 32 // rawVs value + + 32 // word containing length of report + + 32 // word containing length rs + + 32; // word containing length of ss + + uint256 internal immutable i_chainID; + + // Reverts transaction if config args are invalid + modifier checkConfigValid(uint256 numTransmitters, uint256 f) { + if (numTransmitters > MAX_NUM_ORACLES) revert InvalidConfig(InvalidConfigErrorType.TOO_MANY_TRANSMITTERS); + if (f == 0) revert InvalidConfig(InvalidConfigErrorType.F_MUST_BE_POSITIVE); + _; + } + + constructor() { + i_chainID = block.chainid; + } + + /// @notice sets offchain reporting protocol configuration incl. participating oracles + /// @param signers addresses with which oracles sign the reports + /// @param transmitters addresses oracles use to transmit the reports + /// @param f number of faulty oracles the system can tolerate + /// @param onchainConfig encoded on-chain contract configuration + /// @param offchainConfigVersion version number for offchainEncoding schema + /// @param offchainConfig encoded off-chain oracle configuration + function setOCR2Config( + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external override checkConfigValid(transmitters.length, f) onlyOwner { + _beforeSetConfig(onchainConfig); + // Scoped to reduce contract size + { + uint256 oldTransmitterLength = s_transmitters.length; + for (uint256 i = 0; i < oldTransmitterLength; ++i) { + delete s_oracles[s_transmitters[i]]; + } + } + uint256 newTransmitterLength = transmitters.length; + for (uint256 i = 0; i < newTransmitterLength; ++i) { + address transmitter = transmitters[i]; + if (s_oracles[transmitter].role != Role.Unset) { + revert InvalidConfig(InvalidConfigErrorType.REPEATED_ORACLE_ADDRESS); + } + if (transmitter == address(0)) revert OracleCannotBeZeroAddress(); + s_oracles[transmitter] = Oracle(uint8(i), Role.Transmitter); + } + + s_transmitters = transmitters; + + s_configInfo.f = f; + s_configInfo.n = uint8(newTransmitterLength); + s_configInfo.latestConfigDigest = _configDigestFromConfigData( + block.chainid, + address(this), + ++s_configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + + uint32 previousConfigBlockNumber = s_latestConfigBlockNumber; + s_latestConfigBlockNumber = uint32(block.number); + + emit ConfigSet( + previousConfigBlockNumber, + s_configInfo.latestConfigDigest, + s_configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + } + + /// @dev Hook that is run from setOCR2Config() right after validating configuration. + /// Empty by default, please provide an implementation in a child contract if you need additional configuration processing + function _beforeSetConfig(bytes memory _onchainConfig) internal virtual; + + /// @return list of addresses permitted to transmit reports to this contract + /// @dev The list will match the order used to specify the transmitter during setConfig + function getTransmitters() external view returns (address[] memory) { + return s_transmitters; + } + + /// @notice transmit is called to post a new report to the contract + /// @param report serialized report, which the signatures are signing. + /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + function transmit( + // NOTE: If these parameters are changed, expectedMsgDataLength and/or + // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly + bytes32[3] calldata reportContext, + bytes calldata report, + bytes32[] calldata rs, + bytes32[] calldata ss, + bytes32 // signatures + ) external override { + _report(report); + + // reportContext consists of: + // reportContext[0]: ConfigDigest + // reportContext[1]: 27 byte padding, 4-byte epoch and 1-byte round + // reportContext[2]: ExtraHash + bytes32 configDigest = reportContext[0]; + bytes32 latestConfigDigest = s_configInfo.latestConfigDigest; + if (latestConfigDigest != configDigest) revert ConfigDigestMismatch(latestConfigDigest, configDigest); + _checkChainForked(); + + emit Transmitted(configDigest, uint32(uint256(reportContext[1]) >> 8)); + + // Scoping this reduces stack pressure and gas usage + { + Oracle memory transmitter = s_oracles[msg.sender]; + // Check that sender is authorized to report + if (!(transmitter.role == Role.Transmitter && msg.sender == s_transmitters[transmitter.index])) { + revert UnauthorizedTransmitter(); + } + } + + uint256 expectedDataLength = uint256(TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT) + report.length // one byte pure entry in _report + + rs.length * 32 // 32 bytes per entry in _rs + + ss.length * 32; // 32 bytes per entry in _ss) + if (msg.data.length != expectedDataLength) revert WrongMessageLength(expectedDataLength, msg.data.length); + } + + function _checkChainForked() internal view { + // If the cached chainID at time of deployment doesn't match the current chainID, we reject all signed reports. + // This avoids a (rare) scenario where chain A forks into chain A and A', A' still has configDigest + // calculated from chain A and so OCR reports will be valid on both forks. + if (i_chainID != block.chainid) revert ForkedChain(i_chainID, block.chainid); + } + + /// @notice information about current offchain reporting protocol configuration + /// @return configCount ordinal number of current config, out of all configs applied to this contract so far + /// @return blockNumber block at which this config was set + /// @return configDigest domain-separation tag for current config (see _configDigestFromConfigData) + function latestConfigDetails() + external + view + override + returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) + { + return (s_configCount, s_latestConfigBlockNumber, s_configInfo.latestConfigDigest); + } + + /// @inheritdoc OCR2Abstract + function latestConfigDigestAndEpoch() + external + view + virtual + override + returns (bool scanLogs, bytes32 configDigest, uint32 epoch) + { + return (true, bytes32(0), uint32(0)); + } + + function _report(bytes calldata report) internal virtual; +} diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol new file mode 100644 index 0000000000..809e4e22a4 --- /dev/null +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -0,0 +1,914 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IAny2EVMMessageReceiver} from "../interfaces/IAny2EVMMessageReceiver.sol"; +import {IMessageInterceptor} from "../interfaces/IMessageInterceptor.sol"; +import {INonceManager} from "../interfaces/INonceManager.sol"; +import {IPoolV1} from "../interfaces/IPool.sol"; +import {IPriceRegistry} from "../interfaces/IPriceRegistry.sol"; +import {IRMN} from "../interfaces/IRMN.sol"; +import {IRouter} from "../interfaces/IRouter.sol"; +import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol"; + +import {CallWithExactGas} from "../../shared/call/CallWithExactGas.sol"; +import {EnumerableMapAddresses} from "../../shared/enumerable/EnumerableMapAddresses.sol"; +import {Client} from "../libraries/Client.sol"; +import {Internal} from "../libraries/Internal.sol"; +import {MerkleMultiProof} from "../libraries/MerkleMultiProof.sol"; +import {Pool} from "../libraries/Pool.sol"; +import {MultiOCR3Base} from "../ocr/MultiOCR3Base.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {ERC165Checker} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol"; + +/// @notice EVM2EVMOffRamp enables OCR networks to execute multiple messages +/// in an OffRamp in a single transaction. +/// @dev The EVM2EVMMultiOnRamp and EVM2EVMMultiOffRamp form an xchain upgradeable unit. Any change to one of them +/// results an onchain upgrade of both contracts. +/// @dev MultiOCR3Base is used to store multiple OCR configs for both the OffRamp and the CommitStore. +/// The execution plugin type has to be configured without signature verification, and the commit +/// plugin type with verification. +contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { + using ERC165Checker for address; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; + + error AlreadyAttempted(uint64 sourceChainSelector, uint64 sequenceNumber); + error AlreadyExecuted(uint64 sourceChainSelector, uint64 sequenceNumber); + error ZeroChainSelectorNotAllowed(); + error ExecutionError(bytes32 messageId, bytes err); + error SourceChainNotEnabled(uint64 sourceChainSelector); + error TokenDataMismatch(uint64 sourceChainSelector, uint64 sequenceNumber); + error UnexpectedTokenData(); + error ManualExecutionNotYetEnabled(uint64 sourceChainSelector); + error ManualExecutionGasLimitMismatch(); + error InvalidManualExecutionGasLimit(uint64 sourceChainSelector, uint256 index, uint256 newLimit); + error RootNotCommitted(uint64 sourceChainSelector); + error RootAlreadyCommitted(uint64 sourceChainSelector, bytes32 merkleRoot); + error InvalidRoot(); + error CanOnlySelfCall(); + error ReceiverError(bytes err); + error TokenHandlingError(bytes err); + error EmptyReport(); + error CursedByRMN(uint64 sourceChainSelector); + error NotACompatiblePool(address notPool); + error InvalidDataLength(uint256 expected, uint256 got); + error InvalidNewState(uint64 sourceChainSelector, uint64 sequenceNumber, Internal.MessageExecutionState newState); + error InvalidStaticConfig(uint64 sourceChainSelector); + error StaleCommitReport(); + error InvalidInterval(uint64 sourceChainSelector, Interval interval); + error ZeroAddressNotAllowed(); + error InvalidMessageDestChainSelector(uint64 messageDestChainSelector); + + /// @dev Atlas depends on this event, if changing, please notify Atlas. + event StaticConfigSet(StaticConfig staticConfig); + event DynamicConfigSet(DynamicConfig dynamicConfig); + /// @dev RMN depends on this event, if changing, please notify the RMN maintainers. + event ExecutionStateChanged( + uint64 indexed sourceChainSelector, + uint64 indexed sequenceNumber, + bytes32 indexed messageId, + Internal.MessageExecutionState state, + bytes returnData + ); + event SourceChainSelectorAdded(uint64 sourceChainSelector); + event SourceChainConfigSet(uint64 indexed sourceChainSelector, SourceChainConfig sourceConfig); + event SkippedAlreadyExecutedMessage(uint64 sourceChainSelector, uint64 sequenceNumber); + /// @dev RMN depends on this event, if changing, please notify the RMN maintainers. + event CommitReportAccepted(CommitReport report); + event RootRemoved(bytes32 root); + + /// @notice Static offRamp config + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct StaticConfig { + uint64 chainSelector; // ───╮ Destination chainSelector + address rmnProxy; // ───────╯ RMN proxy address + address tokenAdminRegistry; // Token admin registry address + address nonceManager; // Address of the nonce manager + } + + /// @notice Per-chain source config (defining a lane from a Source Chain -> Dest OffRamp) + struct SourceChainConfig { + bool isEnabled; // ──────────╮ Flag whether the source chain is enabled or not + uint64 minSeqNr; // ─────────╯ The min sequence number expected for future messages + bytes onRamp; // OnRamp address on the source chain + } + + /// @notice SourceChainConfig update args scoped to one source chain + struct SourceChainConfigArgs { + uint64 sourceChainSelector; // ───╮ Source chain selector of the config to update + bool isEnabled; // ────────────────╯ Flag whether the source chain is enabled or not + bytes onRamp; // OnRamp address on the source chain + } + + /// @notice Dynamic offRamp config + /// @dev since OffRampConfig is part of OffRampConfigChanged event, if changing it, we should update the ABI on Atlas + struct DynamicConfig { + address router; // ─────────────────────────────────╮ Router address + uint32 permissionLessExecutionThresholdSeconds; // │ Waiting time before manual execution is enabled + uint32 maxTokenTransferGas; // │ Maximum amount of gas passed on to token `transfer` call + uint32 maxPoolReleaseOrMintGas; // ─────────────────╯ Maximum amount of gas passed on to token pool when calling releaseOrMint + address messageValidator; // Optional message validator to validate incoming messages (zero address = no validator) + address priceRegistry; // Price registry address on the local chain + } + + /// @notice a sequenceNumber interval + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct Interval { + uint64 min; // ───╮ Minimum sequence number, inclusive + uint64 max; // ───╯ Maximum sequence number, inclusive + } + + /// @dev Struct to hold a merkle root and an interval for a source chain so that an array of these can be passed in the CommitReport. + struct MerkleRoot { + uint64 sourceChainSelector; // Remote source chain selector that the Merkle Root is scoped to + Interval interval; // Report interval of the merkle root + bytes32 merkleRoot; // Merkle root covering the interval & source chain messages + } + + /// @notice Report that is committed by the observing DON at the committing phase + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct CommitReport { + Internal.PriceUpdates priceUpdates; // Collection of gas and price updates to commit + MerkleRoot[] merkleRoots; // Collection of merkle roots per source chain to commit + } + + /// @dev Struct to hold a merkle root for a source chain so that an array of these can be passed in the resetUblessedRoots function. + struct UnblessedRoot { + uint64 sourceChainSelector; // Remote source chain selector that the Merkle Root is scoped to + bytes32 merkleRoot; // Merkle root of a single remote source chain + } + + // STATIC CONFIG + string public constant override typeAndVersion = "EVM2EVMMultiOffRamp 1.6.0-dev"; + /// @dev ChainSelector of this chain + uint64 internal immutable i_chainSelector; + /// @dev The address of the RMN proxy + address internal immutable i_rmnProxy; + /// @dev The address of the token admin registry + address internal immutable i_tokenAdminRegistry; + /// @dev The address of the nonce manager + address internal immutable i_nonceManager; + + // DYNAMIC CONFIG + DynamicConfig internal s_dynamicConfig; + + /// @notice SourceConfig per chain + /// (forms lane configurations from sourceChainSelector => StaticConfig.chainSelector) + mapping(uint64 sourceChainSelector => SourceChainConfig sourceChainConfig) internal s_sourceChainConfigs; + + // STATE + /// @dev A mapping of sequence numbers (per source chain) to execution state using a bitmap with each execution + /// state only taking up 2 bits of the uint256, packing 128 states into a single slot. + /// Message state is tracked to ensure message can only be executed successfully once. + mapping(uint64 sourceChainSelector => mapping(uint64 seqNum => uint256 executionStateBitmap)) internal + s_executionStates; + + // sourceChainSelector => merkleRoot => timestamp when received + mapping(uint64 sourceChainSelector => mapping(bytes32 merkleRoot => uint256 timestamp)) internal s_roots; + /// @dev The sequence number of the last price update + uint64 private s_latestPriceSequenceNumber; + + constructor( + StaticConfig memory staticConfig, + DynamicConfig memory dynamicConfig, + SourceChainConfigArgs[] memory sourceChainConfigs + ) MultiOCR3Base() { + if ( + staticConfig.rmnProxy == address(0) || staticConfig.tokenAdminRegistry == address(0) + || staticConfig.nonceManager == address(0) + ) { + revert ZeroAddressNotAllowed(); + } + + if (staticConfig.chainSelector == 0) { + revert ZeroChainSelectorNotAllowed(); + } + + i_chainSelector = staticConfig.chainSelector; + i_rmnProxy = staticConfig.rmnProxy; + i_tokenAdminRegistry = staticConfig.tokenAdminRegistry; + i_nonceManager = staticConfig.nonceManager; + emit StaticConfigSet(staticConfig); + + _setDynamicConfig(dynamicConfig); + _applySourceChainConfigUpdates(sourceChainConfigs); + } + + // ================================================================ + // │ Messaging │ + // ================================================================ + + // The size of the execution state in bits + uint256 private constant MESSAGE_EXECUTION_STATE_BIT_WIDTH = 2; + // The mask for the execution state bits + uint256 private constant MESSAGE_EXECUTION_STATE_MASK = (1 << MESSAGE_EXECUTION_STATE_BIT_WIDTH) - 1; + + // ================================================================ + // │ Execution │ + // ================================================================ + + /// @notice Returns the current execution state of a message based on its sequenceNumber. + /// @param sourceChainSelector The source chain to get the execution state for + /// @param sequenceNumber The sequence number of the message to get the execution state for. + /// @return The current execution state of the message. + /// @dev we use the literal number 128 because using a constant increased gas usage. + function getExecutionState( + uint64 sourceChainSelector, + uint64 sequenceNumber + ) public view returns (Internal.MessageExecutionState) { + return Internal.MessageExecutionState( + ( + _getSequenceNumberBitmap(sourceChainSelector, sequenceNumber) + >> ((sequenceNumber % 128) * MESSAGE_EXECUTION_STATE_BIT_WIDTH) + ) & MESSAGE_EXECUTION_STATE_MASK + ); + } + + /// @notice Sets a new execution state for a given sequence number. It will overwrite any existing state. + /// @param sourceChainSelector The source chain to set the execution state for + /// @param sequenceNumber The sequence number for which the state will be saved. + /// @param newState The new value the state will be in after this function is called. + /// @dev we use the literal number 128 because using a constant increased gas usage. + function _setExecutionState( + uint64 sourceChainSelector, + uint64 sequenceNumber, + Internal.MessageExecutionState newState + ) internal { + uint256 offset = (sequenceNumber % 128) * MESSAGE_EXECUTION_STATE_BIT_WIDTH; + uint256 bitmap = _getSequenceNumberBitmap(sourceChainSelector, sequenceNumber); + // to unset any potential existing state we zero the bits of the section the state occupies, + // then we do an AND operation to blank out any existing state for the section. + bitmap &= ~(MESSAGE_EXECUTION_STATE_MASK << offset); + // Set the new state + bitmap |= uint256(newState) << offset; + + s_executionStates[sourceChainSelector][sequenceNumber / 128] = bitmap; + } + + /// @param sourceChainSelector remote source chain selector to get sequence number bitmap for + /// @param sequenceNumber sequence number to get bitmap for + /// @return bitmap Bitmap of the given sequence number for the provided source chain selector. One bitmap represents 128 sequence numbers + function _getSequenceNumberBitmap( + uint64 sourceChainSelector, + uint64 sequenceNumber + ) internal view returns (uint256 bitmap) { + return s_executionStates[sourceChainSelector][sequenceNumber / 128]; + } + + /// @notice Manually executes a set of reports. + /// @param reports Internal.ExecutionReportSingleChain[] - list of reports to execute + /// @param gasLimitOverrides New gasLimit for each message per report + // The outer array represents each report, inner array represents each message in the report. + // i.e. gasLimitOverrides[report1][report1Message1] -> access message1 from report1 + /// @dev We permit gas limit overrides so that users may manually execute messages which failed due to + /// insufficient gas provided. + /// The reports do not have to contain all the messages (they can be omitted). Multiple reports can be passed in simultaneously. + function manuallyExecute( + Internal.ExecutionReportSingleChain[] memory reports, + uint256[][] memory gasLimitOverrides + ) external { + // We do this here because the other _execute path is already covered by MultiOCR3Base. + _whenChainNotForked(); + + uint256 numReports = reports.length; + if (numReports != gasLimitOverrides.length) revert ManualExecutionGasLimitMismatch(); + + for (uint256 reportIndex = 0; reportIndex < numReports; ++reportIndex) { + Internal.ExecutionReportSingleChain memory report = reports[reportIndex]; + + uint256 numMsgs = report.messages.length; + uint256[] memory msgGasLimitOverrides = gasLimitOverrides[reportIndex]; + if (numMsgs != msgGasLimitOverrides.length) revert ManualExecutionGasLimitMismatch(); + + for (uint256 msgIndex = 0; msgIndex < numMsgs; ++msgIndex) { + uint256 newLimit = msgGasLimitOverrides[msgIndex]; + // Checks to ensure message cannot be executed with less gas than specified. + if (newLimit != 0) { + if (newLimit < report.messages[msgIndex].gasLimit) { + revert InvalidManualExecutionGasLimit(report.sourceChainSelector, msgIndex, newLimit); + } + } + } + } + + _batchExecute(reports, gasLimitOverrides); + } + + /// @notice Transmit function for execution reports. The function takes no signatures, + /// and expects the exec plugin type to be configured with no signatures. + /// @param report serialized execution report + function execute(bytes32[3] calldata reportContext, bytes calldata report) external { + _batchExecute(abi.decode(report, (Internal.ExecutionReportSingleChain[])), new uint256[][](0)); + + bytes32[] memory emptySigs = new bytes32[](0); + _transmit(uint8(Internal.OCRPluginType.Execution), reportContext, report, emptySigs, emptySigs, bytes32("")); + } + + /// @notice Batch executes a set of reports, each report matching one single source chain + /// @param reports Set of execution reports (one per chain) containing the messages and proofs + /// @param manualExecGasLimits An array of gas limits to use for manual execution + // The outer array represents each report, inner array represents each message in the report. + // i.e. gasLimitOverrides[report1][report1Message1] -> access message1 from report1 + /// @dev The manualExecGasLimits array should either be empty, or match the length of the reports array + /// @dev If called from manual execution, each inner array's length has to match the number of messages. + function _batchExecute( + Internal.ExecutionReportSingleChain[] memory reports, + uint256[][] memory manualExecGasLimits + ) internal { + if (reports.length == 0) revert EmptyReport(); + + bool areManualGasLimitsEmpty = manualExecGasLimits.length == 0; + // Cache array for gas savings in the loop's condition + uint256[] memory emptyGasLimits = new uint256[](0); + + for (uint256 i = 0; i < reports.length; ++i) { + _executeSingleReport(reports[i], areManualGasLimitsEmpty ? emptyGasLimits : manualExecGasLimits[i]); + } + } + + /// @notice Executes a report, executing each message in order. + /// @param report The execution report containing the messages and proofs. + /// @param manualExecGasLimits An array of gas limits to use for manual execution. + /// @dev If called from the DON, this array is always empty. + /// @dev If called from manual execution, this array is always same length as messages. + function _executeSingleReport( + Internal.ExecutionReportSingleChain memory report, + uint256[] memory manualExecGasLimits + ) internal { + uint64 sourceChainSelector = report.sourceChainSelector; + _whenNotCursed(sourceChainSelector); + + SourceChainConfig storage sourceChainConfig = _getEnabledSourceChainConfig(sourceChainSelector); + + uint256 numMsgs = report.messages.length; + if (numMsgs == 0) revert EmptyReport(); + if (numMsgs != report.offchainTokenData.length) revert UnexpectedTokenData(); + + bytes32[] memory hashedLeaves = new bytes32[](numMsgs); + + for (uint256 i = 0; i < numMsgs; ++i) { + Internal.Any2EVMRampMessage memory message = report.messages[i]; + + // Commits do not verify the destChainSelector in the message, since only the root is committed, + // so we have to check it explicitly + if (message.header.destChainSelector != i_chainSelector) { + revert InvalidMessageDestChainSelector(message.header.destChainSelector); + } + + // We do this hash here instead of in _verifyMessages to avoid two separate loops + // over the same data, which increases gas cost. + // Hashing all of the message fields ensures that the message being executed is correct and not tampered with. + // Including the known OnRamp ensures that the message originates from the correct on ramp version + hashedLeaves[i] = Internal._hash(message, sourceChainConfig.onRamp); + } + + // SECURITY CRITICAL CHECK + // NOTE: This check also verifies that all messages match the report's sourceChainSelector + uint256 timestampCommitted = _verify(sourceChainSelector, hashedLeaves, report.proofs, report.proofFlagBits); + if (timestampCommitted == 0) revert RootNotCommitted(sourceChainSelector); + + // Execute messages + bool manualExecution = manualExecGasLimits.length != 0; + for (uint256 i = 0; i < numMsgs; ++i) { + Internal.Any2EVMRampMessage memory message = report.messages[i]; + + Internal.MessageExecutionState originalState = + getExecutionState(sourceChainSelector, message.header.sequenceNumber); + if (originalState == Internal.MessageExecutionState.SUCCESS) { + // If the message has already been executed, we skip it. We want to not revert on race conditions between + // executing parties. This will allow us to open up manual exec while also attempting with the DON, without + // reverting an entire DON batch when a user manually executes while the tx is inflight. + emit SkippedAlreadyExecutedMessage(sourceChainSelector, message.header.sequenceNumber); + continue; + } + // Two valid cases here, we either have never touched this message before, or we tried to execute + // and failed. This check protects against reentry and re-execution because the other state is + // IN_PROGRESS which should not be allowed to execute. + if ( + !( + originalState == Internal.MessageExecutionState.UNTOUCHED + || originalState == Internal.MessageExecutionState.FAILURE + ) + ) revert AlreadyExecuted(sourceChainSelector, message.header.sequenceNumber); + + if (manualExecution) { + bool isOldCommitReport = + (block.timestamp - timestampCommitted) > s_dynamicConfig.permissionLessExecutionThresholdSeconds; + // Manually execution is fine if we previously failed or if the commit report is just too old + // Acceptable state transitions: FAILURE->SUCCESS, UNTOUCHED->SUCCESS, FAILURE->FAILURE + if (!(isOldCommitReport || originalState == Internal.MessageExecutionState.FAILURE)) { + revert ManualExecutionNotYetEnabled(sourceChainSelector); + } + + // Manual execution gas limit can override gas limit specified in the message. Value of 0 indicates no override. + if (manualExecGasLimits[i] != 0) { + message.gasLimit = manualExecGasLimits[i]; + } + } else { + // DON can only execute a message once + // Acceptable state transitions: UNTOUCHED->SUCCESS, UNTOUCHED->FAILURE + if (originalState != Internal.MessageExecutionState.UNTOUCHED) { + revert AlreadyAttempted(sourceChainSelector, message.header.sequenceNumber); + } + } + + // Nonce changes per state transition (these only apply for ordered messages): + // UNTOUCHED -> FAILURE nonce bump + // UNTOUCHED -> SUCCESS nonce bump + // FAILURE -> FAILURE no nonce bump + // FAILURE -> SUCCESS no nonce bump + // UNTOUCHED messages MUST be executed in order always + if (message.header.nonce != 0) { + if (originalState == Internal.MessageExecutionState.UNTOUCHED) { + // If a nonce is not incremented, that means it was skipped, and we can ignore the message + if ( + !INonceManager(i_nonceManager).incrementInboundNonce( + sourceChainSelector, message.header.nonce, message.sender + ) + ) continue; + } + } + + // Although we expect only valid messages will be committed, we check again + // when executing as a defense in depth measure. + bytes[] memory offchainTokenData = report.offchainTokenData[i]; + if (message.tokenAmounts.length != offchainTokenData.length) { + revert TokenDataMismatch(sourceChainSelector, message.header.sequenceNumber); + } + + _setExecutionState(sourceChainSelector, message.header.sequenceNumber, Internal.MessageExecutionState.IN_PROGRESS); + + (Internal.MessageExecutionState newState, bytes memory returnData) = _trialExecute(message, offchainTokenData); + _setExecutionState(sourceChainSelector, message.header.sequenceNumber, newState); + + // Since it's hard to estimate whether manual execution will succeed, we + // revert the entire transaction if it fails. This will show the user if + // their manual exec will fail before they submit it. + if (manualExecution) { + if (newState == Internal.MessageExecutionState.FAILURE) { + if (originalState != Internal.MessageExecutionState.UNTOUCHED) { + // If manual execution fails, we revert the entire transaction, unless the originalState is UNTOUCHED as we + // would still be making progress by changing the state from UNTOUCHED to FAILURE. + revert ExecutionError(message.header.messageId, returnData); + } + } + } + + // The only valid prior states are UNTOUCHED and FAILURE (checked above) + // The only valid post states are FAILURE and SUCCESS (checked below) + if (newState != Internal.MessageExecutionState.SUCCESS) { + if (newState != Internal.MessageExecutionState.FAILURE) { + revert InvalidNewState(sourceChainSelector, message.header.sequenceNumber, newState); + } + } + + emit ExecutionStateChanged( + sourceChainSelector, message.header.sequenceNumber, message.header.messageId, newState, returnData + ); + } + } + + /// @notice Try executing a message. + /// @param message Internal.Any2EVMRampMessage memory message. + /// @param offchainTokenData Data provided by the DON for token transfers. + /// @return the new state of the message, being either SUCCESS or FAILURE. + /// @return revert data in bytes if CCIP receiver reverted during execution. + function _trialExecute( + Internal.Any2EVMRampMessage memory message, + bytes[] memory offchainTokenData + ) internal returns (Internal.MessageExecutionState, bytes memory) { + try this.executeSingleMessage(message, offchainTokenData) {} + catch (bytes memory err) { + // return the message execution state as FAILURE and the revert data + // Max length of revert data is Router.MAX_RET_BYTES, max length of err is 4 + Router.MAX_RET_BYTES + return (Internal.MessageExecutionState.FAILURE, err); + } + // If message execution succeeded, no CCIP receiver return data is expected, return with empty bytes. + return (Internal.MessageExecutionState.SUCCESS, ""); + } + + /// @notice Execute a single message. + /// @param message The message that will be executed. + /// @param offchainTokenData Token transfer data to be passed to TokenPool. + /// @dev We make this external and callable by the contract itself, in order to try/catch + /// its execution and enforce atomicity among successful message processing and token transfer. + /// @dev We use ERC-165 to check for the ccipReceive interface to permit sending tokens to contracts + /// (for example smart contract wallets) without an associated message. + function executeSingleMessage(Internal.Any2EVMRampMessage memory message, bytes[] memory offchainTokenData) external { + if (msg.sender != address(this)) revert CanOnlySelfCall(); + Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](0); + if (message.tokenAmounts.length > 0) { + destTokenAmounts = _releaseOrMintTokens( + message.tokenAmounts, message.sender, message.receiver, message.header.sourceChainSelector, offchainTokenData + ); + } + + Client.Any2EVMMessage memory any2EvmMessage = Client.Any2EVMMessage({ + messageId: message.header.messageId, + sourceChainSelector: message.header.sourceChainSelector, + sender: abi.encode(message.sender), + data: message.data, + destTokenAmounts: destTokenAmounts + }); + + address messageValidator = s_dynamicConfig.messageValidator; + if (messageValidator != address(0)) { + try IMessageInterceptor(messageValidator).onInboundMessage(any2EvmMessage) {} + catch (bytes memory err) { + revert IMessageInterceptor.MessageValidationError(err); + } + } + + // There are three cases in which we skip calling the receiver: + // 1. If the message data is empty AND the gas limit is 0. + // This indicates a message that only transfers tokens. It is valid to only send tokens to a contract + // that supports the IAny2EVMMessageReceiver interface, but without this first check we would call the + // receiver without any gas, which would revert the transaction. + // 2. If the receiver is not a contract. + // 3. If the receiver is a contract but it does not support the IAny2EVMMessageReceiver interface. + // + // The ordering of these checks is important, as the first check is the cheapest to execute. + if ( + (message.data.length == 0 && message.gasLimit == 0) || message.receiver.code.length == 0 + || !message.receiver.supportsInterface(type(IAny2EVMMessageReceiver).interfaceId) + ) return; + + (bool success, bytes memory returnData,) = IRouter(s_dynamicConfig.router).routeMessage( + any2EvmMessage, Internal.GAS_FOR_CALL_EXACT_CHECK, message.gasLimit, message.receiver + ); + // If CCIP receiver execution is not successful, revert the call including token transfers + if (!success) revert ReceiverError(returnData); + } + + // ================================================================ + // │ Commit │ + // ================================================================ + + /// @notice Transmit function for commit reports. The function requires signatures, + /// and expects the commit plugin type to be configured with signatures. + /// @param report serialized commit report + /// @dev A commitReport can have two distinct parts (batched together to amortize the cost of checking sigs): + /// 1. Price updates + /// 2. A batch of merkle root and sequence number intervals (per-source) + /// Both have their own, separate, staleness checks, with price updates using the epoch and round + /// number of the latest price update. The merkle root checks for staleness based on the seqNums. + /// They need to be separate because a price report for round t+2 might be included before a report + /// containing a merkle root for round t+1. This merkle root report for round t+1 is still valid + /// and should not be rejected. When a report with a stale root but valid price updates is submitted, + /// we are OK to revert to preserve the invariant that we always revert on invalid sequence number ranges. + /// If that happens, prices will be updates in later rounds. + function commit( + bytes32[3] calldata reportContext, + bytes calldata report, + bytes32[] calldata rs, + bytes32[] calldata ss, + bytes32 rawVs // signatures + ) external { + CommitReport memory commitReport = abi.decode(report, (CommitReport)); + + // Check if the report contains price updates + if (commitReport.priceUpdates.tokenPriceUpdates.length > 0 || commitReport.priceUpdates.gasPriceUpdates.length > 0) + { + uint64 sequenceNumber = uint64(uint256(reportContext[1])); + + // Check for price staleness based on the epoch and round + if (s_latestPriceSequenceNumber < sequenceNumber) { + // If prices are not stale, update the latest epoch and round + s_latestPriceSequenceNumber = sequenceNumber; + // And update the prices in the price registry + IPriceRegistry(s_dynamicConfig.priceRegistry).updatePrices(commitReport.priceUpdates); + } else { + // If prices are stale and the report doesn't contain a root, this report + // does not have any valid information and we revert. + // If it does contain a merkle root, continue to the root checking section. + if (commitReport.merkleRoots.length == 0) revert StaleCommitReport(); + } + } + + for (uint256 i = 0; i < commitReport.merkleRoots.length; ++i) { + MerkleRoot memory root = commitReport.merkleRoots[i]; + uint64 sourceChainSelector = root.sourceChainSelector; + + _whenNotCursed(sourceChainSelector); + SourceChainConfig storage sourceChainConfig = _getEnabledSourceChainConfig(sourceChainSelector); + + // If we reached this section, the report should contain a valid root + if (sourceChainConfig.minSeqNr != root.interval.min || root.interval.min > root.interval.max) { + revert InvalidInterval(root.sourceChainSelector, root.interval); + } + + // TODO: confirm how RMN offchain blessing impacts commit report + bytes32 merkleRoot = root.merkleRoot; + if (merkleRoot == bytes32(0)) revert InvalidRoot(); + // Disallow duplicate roots as that would reset the timestamp and + // delay potential manual execution. + if (s_roots[root.sourceChainSelector][merkleRoot] != 0) { + revert RootAlreadyCommitted(root.sourceChainSelector, merkleRoot); + } + + sourceChainConfig.minSeqNr = root.interval.max + 1; + s_roots[root.sourceChainSelector][merkleRoot] = block.timestamp; + } + + emit CommitReportAccepted(commitReport); + + _transmit(uint8(Internal.OCRPluginType.Commit), reportContext, report, rs, ss, rawVs); + } + + /// @notice Returns the sequence number of the last price update. + /// @return the latest price update sequence number. + function getLatestPriceSequenceNumber() public view returns (uint64) { + return s_latestPriceSequenceNumber; + } + + /// @notice Returns the timestamp of a potentially previously committed merkle root. + /// If the root was never committed 0 will be returned. + /// @param sourceChainSelector The source chain selector. + /// @param root The merkle root to check the commit status for. + /// @return the timestamp of the committed root or zero in the case that it was never + /// committed. + function getMerkleRoot(uint64 sourceChainSelector, bytes32 root) external view returns (uint256) { + return s_roots[sourceChainSelector][root]; + } + + /// @notice Returns if a root is blessed or not. + /// @param root The merkle root to check the blessing status for. + /// @return whether the root is blessed or not. + function isBlessed(bytes32 root) public view returns (bool) { + // TODO: update RMN to also consider the source chain selector for blessing + return IRMN(i_rmnProxy).isBlessed(IRMN.TaggedRoot({commitStore: address(this), root: root})); + } + + /// @notice Used by the owner in case an invalid sequence of roots has been + /// posted and needs to be removed. The interval in the report is trusted. + /// @param rootToReset The roots that will be reset. This function will only + /// reset roots that are not blessed. + function resetUnblessedRoots(UnblessedRoot[] calldata rootToReset) external onlyOwner { + for (uint256 i = 0; i < rootToReset.length; ++i) { + UnblessedRoot memory root = rootToReset[i]; + if (!isBlessed(root.merkleRoot)) { + delete s_roots[root.sourceChainSelector][root.merkleRoot]; + emit RootRemoved(root.merkleRoot); + } + } + } + + /// @notice Returns timestamp of when root was accepted or 0 if verification fails. + /// @dev This method uses a merkle tree within a merkle tree, with the hashedLeaves, + /// proofs and proofFlagBits being used to get the root of the inner tree. + /// This root is then used as the singular leaf of the outer tree. + function _verify( + uint64 sourceChainSelector, + bytes32[] memory hashedLeaves, + bytes32[] memory proofs, + uint256 proofFlagBits + ) internal view virtual returns (uint256 timestamp) { + bytes32 root = MerkleMultiProof.merkleRoot(hashedLeaves, proofs, proofFlagBits); + // Only return non-zero if present and blessed. + if (!isBlessed(root)) { + return 0; + } + return s_roots[sourceChainSelector][root]; + } + + /// @inheritdoc MultiOCR3Base + function _afterOCR3ConfigSet(uint8 ocrPluginType) internal override { + if (ocrPluginType == uint8(Internal.OCRPluginType.Commit)) { + // When the OCR config changes, we reset the sequence number + // since it is scoped per config digest. + // Note that s_minSeqNr/roots do not need to be reset as the roots persist + // across reconfigurations and are de-duplicated separately. + s_latestPriceSequenceNumber = 0; + } + } + + // ================================================================ + // │ Config │ + // ================================================================ + + /// @notice Returns the static config. + /// @dev This function will always return the same struct as the contents is static and can never change. + /// RMN depends on this function, if changing, please notify the RMN maintainers. + function getStaticConfig() external view returns (StaticConfig memory) { + return StaticConfig({ + chainSelector: i_chainSelector, + rmnProxy: i_rmnProxy, + tokenAdminRegistry: i_tokenAdminRegistry, + nonceManager: i_nonceManager + }); + } + + /// @notice Returns the current dynamic config. + /// @return The current config. + function getDynamicConfig() external view returns (DynamicConfig memory) { + return s_dynamicConfig; + } + + /// @notice Returns the source chain config for the provided source chain selector + /// @param sourceChainSelector chain to retrieve configuration for + /// @return SourceChainConfig config for the source chain + function getSourceChainConfig(uint64 sourceChainSelector) external view returns (SourceChainConfig memory) { + return s_sourceChainConfigs[sourceChainSelector]; + } + + /// @notice Updates source configs + /// @param sourceChainConfigUpdates Source chain configs + function applySourceChainConfigUpdates(SourceChainConfigArgs[] memory sourceChainConfigUpdates) external onlyOwner { + _applySourceChainConfigUpdates(sourceChainConfigUpdates); + } + + /// @notice Updates source configs + /// @param sourceChainConfigUpdates Source chain configs + function _applySourceChainConfigUpdates(SourceChainConfigArgs[] memory sourceChainConfigUpdates) internal { + for (uint256 i = 0; i < sourceChainConfigUpdates.length; ++i) { + SourceChainConfigArgs memory sourceConfigUpdate = sourceChainConfigUpdates[i]; + uint64 sourceChainSelector = sourceConfigUpdate.sourceChainSelector; + + if (sourceChainSelector == 0) { + revert ZeroChainSelectorNotAllowed(); + } + + SourceChainConfig storage currentConfig = s_sourceChainConfigs[sourceChainSelector]; + bytes memory currentOnRamp = currentConfig.onRamp; + bytes memory newOnRamp = sourceConfigUpdate.onRamp; + + // OnRamp can never be zero - if it is, then the source chain has been added for the first time + if (currentOnRamp.length == 0) { + if (newOnRamp.length == 0) { + revert ZeroAddressNotAllowed(); + } + + currentConfig.onRamp = newOnRamp; + currentConfig.minSeqNr = 1; + emit SourceChainSelectorAdded(sourceChainSelector); + } else if (keccak256(currentOnRamp) != keccak256(newOnRamp)) { + revert InvalidStaticConfig(sourceChainSelector); + } + + // The only dynamic config is the isEnabled flag + currentConfig.isEnabled = sourceConfigUpdate.isEnabled; + emit SourceChainConfigSet(sourceChainSelector, currentConfig); + } + } + + /// @notice Sets the dynamic config. + /// @param dynamicConfig The new dynamic config. + function setDynamicConfig(DynamicConfig memory dynamicConfig) external onlyOwner { + _setDynamicConfig(dynamicConfig); + } + + /// @notice Sets the dynamic config. + /// @param dynamicConfig The dynamic config. + function _setDynamicConfig(DynamicConfig memory dynamicConfig) internal { + if (dynamicConfig.priceRegistry == address(0) || dynamicConfig.router == address(0)) { + revert ZeroAddressNotAllowed(); + } + + s_dynamicConfig = dynamicConfig; + + emit DynamicConfigSet(dynamicConfig); + } + + /// @notice Returns a source chain config with a check that the config is enabled + /// @param sourceChainSelector Source chain selector to check for cursing + /// @return sourceChainConfig Source chain config + function _getEnabledSourceChainConfig(uint64 sourceChainSelector) internal view returns (SourceChainConfig storage) { + SourceChainConfig storage sourceChainConfig = s_sourceChainConfigs[sourceChainSelector]; + if (!sourceChainConfig.isEnabled) { + revert SourceChainNotEnabled(sourceChainSelector); + } + + return sourceChainConfig; + } + + // ================================================================ + // │ Tokens and pools │ + // ================================================================ + + /// @notice Uses a pool to release or mint a token to a receiver address in two steps. First, the pool is called + /// to release the tokens to the offRamp, then the offRamp calls the token contract to transfer the tokens to the + /// receiver. This is done to ensure the exact number of tokens, the pool claims to release are actually transferred. + /// @dev The local token address is validated through the TokenAdminRegistry. If, due to some misconfiguration, the + /// token is unknown to the registry, the offRamp will revert. The tx, and the tokens, can be retrieved by + /// registering the token on this chain, and re-trying the msg. + /// @param sourceTokenAmount Amount and source data of the token to be released/minted. + /// @param originalSender The message sender on the source chain. + /// @param receiver The address that will receive the tokens. + /// @param sourceChainSelector The remote source chain selector + /// @param offchainTokenData Data fetched offchain by the DON. + /// @return destTokenAmount local token address with amount + function _releaseOrMintSingleToken( + Internal.RampTokenAmount memory sourceTokenAmount, + bytes memory originalSender, + address receiver, + uint64 sourceChainSelector, + bytes memory offchainTokenData + ) internal returns (Client.EVMTokenAmount memory destTokenAmount) { + // We need to safely decode the token address from the sourceTokenData, as it could be wrong, + // in which case it doesn't have to be a valid EVM address. + address localToken = Internal._validateEVMAddress(sourceTokenAmount.destTokenAddress); + // We check with the token admin registry if the token has a pool on this chain. + address localPoolAddress = ITokenAdminRegistry(i_tokenAdminRegistry).getPool(localToken); + // This will call the supportsInterface through the ERC165Checker, and not directly on the pool address. + // This is done to prevent a pool from reverting the entire transaction if it doesn't support the interface. + // The call gets a max or 30k gas per instance, of which there are three. This means gas estimations should + // account for 90k gas overhead due to the interface check. + if (localPoolAddress == address(0) || !localPoolAddress.supportsInterface(Pool.CCIP_POOL_V1)) { + revert NotACompatiblePool(localPoolAddress); + } + + // We determined that the pool address is a valid EVM address, but that does not mean the code at this + // address is a (compatible) pool contract. _callWithExactGasSafeReturnData will check if the location + // contains a contract. If it doesn't it reverts with a known error, which we catch gracefully. + // We call the pool with exact gas to increase resistance against malicious tokens or token pools. + // We protects against return data bombs by capping the return data size at MAX_RET_BYTES. + (bool success, bytes memory returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( + abi.encodeCall( + IPoolV1.releaseOrMint, + Pool.ReleaseOrMintInV1({ + originalSender: originalSender, + receiver: receiver, + amount: sourceTokenAmount.amount, + localToken: localToken, + remoteChainSelector: sourceChainSelector, + sourcePoolAddress: sourceTokenAmount.sourcePoolAddress, + sourcePoolData: sourceTokenAmount.extraData, + offchainTokenData: offchainTokenData + }) + ), + localPoolAddress, + s_dynamicConfig.maxPoolReleaseOrMintGas, + Internal.GAS_FOR_CALL_EXACT_CHECK, + Internal.MAX_RET_BYTES + ); + + // wrap and rethrow the error so we can catch it lower in the stack + if (!success) revert TokenHandlingError(returnData); + + // If the call was successful, the returnData should be the local token address. + if (returnData.length != Pool.CCIP_POOL_V1_RET_BYTES) { + revert InvalidDataLength(Pool.CCIP_POOL_V1_RET_BYTES, returnData.length); + } + uint256 localAmount = abi.decode(returnData, (uint256)); + // Since token pools send the tokens to the msg.sender, which is this offRamp, we need to + // transfer them to the final receiver. We use the _callWithExactGasSafeReturnData function because + // the token contracts are not considered trusted. + (success, returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( + abi.encodeCall(IERC20.transfer, (receiver, localAmount)), + localToken, + s_dynamicConfig.maxTokenTransferGas, + Internal.GAS_FOR_CALL_EXACT_CHECK, + Internal.MAX_RET_BYTES + ); + + if (!success) revert TokenHandlingError(returnData); + + return Client.EVMTokenAmount({token: localToken, amount: localAmount}); + } + + /// @notice Uses pools to release or mint a number of different tokens to a receiver address. + /// @param sourceTokenAmounts List of token amounts with source data of the tokens to be released/minted. + /// @param originalSender The message sender on the source chain. + /// @param receiver The address that will receive the tokens. + /// @param sourceChainSelector The remote source chain selector + /// @param offchainTokenData Array of token data fetched offchain by the DON. + /// @return destTokenAmounts local token addresses with amounts + /// @dev This function wrappes the token pool call in a try catch block to gracefully handle + /// any non-rate limiting errors that may occur. If we encounter a rate limiting related error + /// we bubble it up. If we encounter a non-rate limiting error we wrap it in a TokenHandlingError. + function _releaseOrMintTokens( + Internal.RampTokenAmount[] memory sourceTokenAmounts, + bytes memory originalSender, + address receiver, + uint64 sourceChainSelector, + bytes[] memory offchainTokenData + ) internal returns (Client.EVMTokenAmount[] memory destTokenAmounts) { + destTokenAmounts = new Client.EVMTokenAmount[](sourceTokenAmounts.length); + for (uint256 i = 0; i < sourceTokenAmounts.length; ++i) { + destTokenAmounts[i] = _releaseOrMintSingleToken( + sourceTokenAmounts[i], originalSender, receiver, sourceChainSelector, offchainTokenData[i] + ); + } + + return destTokenAmounts; + } + + // ================================================================ + // │ Access and RMN │ + // ================================================================ + + /// @notice Reverts as this contract should not access CCIP messages + function ccipReceive(Client.Any2EVMMessage calldata) external pure { + // solhint-disable-next-line + revert(); + } + + /// @notice Validates that the source chain -> this chain lane, and reverts if it is cursed + /// @param sourceChainSelector Source chain selector to check for cursing + function _whenNotCursed(uint64 sourceChainSelector) internal view { + if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(sourceChainSelector)))) { + revert CursedByRMN(sourceChainSelector); + } + } +} diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol new file mode 100644 index 0000000000..1aec436ef8 --- /dev/null +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol @@ -0,0 +1,721 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IAny2EVMMessageReceiver} from "../interfaces/IAny2EVMMessageReceiver.sol"; +import {IAny2EVMOffRamp} from "../interfaces/IAny2EVMOffRamp.sol"; +import {ICommitStore} from "../interfaces/ICommitStore.sol"; +import {IPoolV1} from "../interfaces/IPool.sol"; +import {IPriceRegistry} from "../interfaces/IPriceRegistry.sol"; +import {IRMN} from "../interfaces/IRMN.sol"; +import {IRouter} from "../interfaces/IRouter.sol"; +import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol"; + +import {CallWithExactGas} from "../../shared/call/CallWithExactGas.sol"; +import {EnumerableMapAddresses} from "../../shared/enumerable/EnumerableMapAddresses.sol"; +import {AggregateRateLimiter} from "../AggregateRateLimiter.sol"; +import {Client} from "../libraries/Client.sol"; +import {Internal} from "../libraries/Internal.sol"; +import {Pool} from "../libraries/Pool.sol"; +import {RateLimiter} from "../libraries/RateLimiter.sol"; +import {OCR2BaseNoChecks} from "../ocr/OCR2BaseNoChecks.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {ERC165Checker} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol"; + +/// @notice EVM2EVMOffRamp enables OCR networks to execute multiple messages +/// in an OffRamp in a single transaction. +/// @dev The EVM2EVMOnRamp, CommitStore and EVM2EVMOffRamp form an xchain upgradeable unit. Any change to one of them +/// results an onchain upgrade of all 3. +/// @dev OCR2BaseNoChecks is used to save gas, signatures are not required as the offramp can only execute +/// messages which are committed in the commitStore. We still make use of OCR2 as an executor whitelist +/// and turn-taking mechanism. +contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersion, OCR2BaseNoChecks { + using ERC165Checker for address; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; + + error AlreadyAttempted(uint64 sequenceNumber); + error AlreadyExecuted(uint64 sequenceNumber); + error ZeroAddressNotAllowed(); + error CommitStoreAlreadyInUse(); + error ExecutionError(bytes err); + error InvalidSourceChain(uint64 sourceChainSelector); + error MessageTooLarge(uint256 maxSize, uint256 actualSize); + error TokenDataMismatch(uint64 sequenceNumber); + error UnexpectedTokenData(); + error UnsupportedNumberOfTokens(uint64 sequenceNumber); + error ManualExecutionNotYetEnabled(); + error ManualExecutionGasLimitMismatch(); + error InvalidManualExecutionGasLimit(uint256 index, uint256 newLimit); + error RootNotCommitted(); + error CanOnlySelfCall(); + error ReceiverError(bytes err); + error TokenHandlingError(bytes err); + error EmptyReport(); + error CursedByRMN(); + error InvalidMessageId(); + error NotACompatiblePool(address notPool); + error InvalidDataLength(uint256 expected, uint256 got); + error InvalidNewState(uint64 sequenceNumber, Internal.MessageExecutionState newState); + + /// @dev Atlas depends on this event, if changing, please notify Atlas. + event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig); + event SkippedIncorrectNonce(uint64 indexed nonce, address indexed sender); + event SkippedSenderWithPreviousRampMessageInflight(uint64 indexed nonce, address indexed sender); + /// @dev RMN depends on this event, if changing, please notify the RMN maintainers. + event ExecutionStateChanged( + uint64 indexed sequenceNumber, bytes32 indexed messageId, Internal.MessageExecutionState state, bytes returnData + ); + event TokenAggregateRateLimitAdded(address sourceToken, address destToken); + event TokenAggregateRateLimitRemoved(address sourceToken, address destToken); + event SkippedAlreadyExecutedMessage(uint64 indexed sequenceNumber); + + /// @notice Static offRamp config + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + //solhint-disable gas-struct-packing + struct StaticConfig { + address commitStore; // ────────╮ CommitStore address on the destination chain + uint64 chainSelector; // ───────╯ Destination chainSelector + uint64 sourceChainSelector; // ─╮ Source chainSelector + address onRamp; // ─────────────╯ OnRamp address on the source chain + address prevOffRamp; // Address of previous-version OffRamp + address rmnProxy; // RMN proxy address + address tokenAdminRegistry; // Token admin registry address + } + + /// @notice Dynamic offRamp config + /// @dev since OffRampConfig is part of OffRampConfigChanged event, if changing it, we should update the ABI on Atlas + struct DynamicConfig { + uint32 permissionLessExecutionThresholdSeconds; // ─╮ Waiting time before manual execution is enabled + uint32 maxDataBytes; // │ Maximum payload data size in bytes + uint16 maxNumberOfTokensPerMsg; // │ Maximum number of ERC20 token transfers that can be included per message + address router; // ─────────────────────────────────╯ Router address + address priceRegistry; // ──────────╮ Price registry address + uint32 maxPoolReleaseOrMintGas; // │ Maximum amount of gas passed on to token pool `releaseOrMint` call + uint32 maxTokenTransferGas; // ─────╯ Maximum amount of gas passed on to token `transfer` call + } + + /// @notice RateLimitToken struct containing both the source and destination token addresses + struct RateLimitToken { + address sourceToken; + address destToken; + } + + // STATIC CONFIG + string public constant override typeAndVersion = "EVM2EVMOffRamp 1.5.0-dev"; + + /// @dev Commit store address on the destination chain + address internal immutable i_commitStore; + /// @dev ChainSelector of the source chain + uint64 internal immutable i_sourceChainSelector; + /// @dev ChainSelector of this chain + uint64 internal immutable i_chainSelector; + /// @dev OnRamp address on the source chain + address internal immutable i_onRamp; + /// @dev metadataHash is a lane-specific prefix for a message hash preimage which ensures global uniqueness. + /// Ensures that 2 identical messages sent to 2 different lanes will have a distinct hash. + /// Must match the metadataHash used in computing leaf hashes offchain for the root committed in + /// the commitStore and i_metadataHash in the onRamp. + bytes32 internal immutable i_metadataHash; + /// @dev The address of previous-version OffRamp for this lane. + /// Used to be able to provide sequencing continuity during a zero downtime upgrade. + address internal immutable i_prevOffRamp; + /// @dev The address of the RMN proxy + address internal immutable i_rmnProxy; + /// @dev The address of the token admin registry + address internal immutable i_tokenAdminRegistry; + + // DYNAMIC CONFIG + DynamicConfig internal s_dynamicConfig; + /// @dev Tokens that should be included in Aggregate Rate Limiting + /// An (address => address) map is used for backwards compatability of offchain code + EnumerableMapAddresses.AddressToAddressMap internal s_rateLimitedTokensDestToSource; + + // STATE + /// @dev The expected nonce for a given sender. + /// Corresponds to s_senderNonce in the OnRamp, used to enforce that messages are + /// executed in the same order they are sent (assuming they are DON). Note that re-execution + /// of FAILED messages however, can be out of order. + mapping(address sender => uint64 nonce) internal s_senderNonce; + /// @dev A mapping of sequence numbers to execution state using a bitmap with each execution + /// state only taking up 2 bits of the uint256, packing 128 states into a single slot. + /// Message state is tracked to ensure message can only be executed successfully once. + mapping(uint64 seqNum => uint256 executionStateBitmap) internal s_executionStates; + + constructor( + StaticConfig memory staticConfig, + RateLimiter.Config memory rateLimiterConfig + ) OCR2BaseNoChecks() AggregateRateLimiter(rateLimiterConfig) { + if ( + staticConfig.onRamp == address(0) || staticConfig.commitStore == address(0) + || staticConfig.tokenAdminRegistry == address(0) + ) revert ZeroAddressNotAllowed(); + // Ensures we can never deploy a new offRamp that points to a commitStore that + // already has roots committed. + if (ICommitStore(staticConfig.commitStore).getExpectedNextSequenceNumber() != 1) revert CommitStoreAlreadyInUse(); + + i_commitStore = staticConfig.commitStore; + i_sourceChainSelector = staticConfig.sourceChainSelector; + i_chainSelector = staticConfig.chainSelector; + i_onRamp = staticConfig.onRamp; + i_prevOffRamp = staticConfig.prevOffRamp; + i_rmnProxy = staticConfig.rmnProxy; + i_tokenAdminRegistry = staticConfig.tokenAdminRegistry; + + i_metadataHash = _metadataHash(Internal.EVM_2_EVM_MESSAGE_HASH); + } + + // ================================================================ + // │ Messaging │ + // ================================================================ + + // The size of the execution state in bits + uint256 private constant MESSAGE_EXECUTION_STATE_BIT_WIDTH = 2; + // The mask for the execution state bits + uint256 private constant MESSAGE_EXECUTION_STATE_MASK = (1 << MESSAGE_EXECUTION_STATE_BIT_WIDTH) - 1; + + /// @notice Returns the current execution state of a message based on its sequenceNumber. + /// @param sequenceNumber The sequence number of the message to get the execution state for. + /// @return The current execution state of the message. + /// @dev we use the literal number 128 because using a constant increased gas usage. + function getExecutionState(uint64 sequenceNumber) public view returns (Internal.MessageExecutionState) { + return Internal.MessageExecutionState( + (s_executionStates[sequenceNumber / 128] >> ((sequenceNumber % 128) * MESSAGE_EXECUTION_STATE_BIT_WIDTH)) + & MESSAGE_EXECUTION_STATE_MASK + ); + } + + /// @notice Sets a new execution state for a given sequence number. It will overwrite any existing state. + /// @param sequenceNumber The sequence number for which the state will be saved. + /// @param newState The new value the state will be in after this function is called. + /// @dev we use the literal number 128 because using a constant increased gas usage. + function _setExecutionState(uint64 sequenceNumber, Internal.MessageExecutionState newState) internal { + uint256 offset = (sequenceNumber % 128) * MESSAGE_EXECUTION_STATE_BIT_WIDTH; + uint256 bitmap = s_executionStates[sequenceNumber / 128]; + // to unset any potential existing state we zero the bits of the section the state occupies, + // then we do an AND operation to blank out any existing state for the section. + bitmap &= ~(MESSAGE_EXECUTION_STATE_MASK << offset); + // Set the new state + bitmap |= uint256(newState) << offset; + + s_executionStates[sequenceNumber / 128] = bitmap; + } + + /// @inheritdoc IAny2EVMOffRamp + function getSenderNonce(address sender) external view returns (uint64 nonce) { + uint256 senderNonce = s_senderNonce[sender]; + + if (senderNonce == 0) { + if (i_prevOffRamp != address(0)) { + // If OffRamp was upgraded, check if sender has a nonce from the previous OffRamp. + return IAny2EVMOffRamp(i_prevOffRamp).getSenderNonce(sender); + } + } + return uint64(senderNonce); + } + + /// @notice Manually execute a message. + /// @param report Internal.ExecutionReport. + /// @param gasLimitOverrides New gasLimit for each message in the report. + /// @dev We permit gas limit overrides so that users may manually execute messages which failed due to + /// insufficient gas provided. + function manuallyExecute(Internal.ExecutionReport memory report, uint256[] memory gasLimitOverrides) external { + // We do this here because the other _execute path is already covered OCR2BaseXXX. + _checkChainForked(); + + uint256 numMsgs = report.messages.length; + if (numMsgs != gasLimitOverrides.length) revert ManualExecutionGasLimitMismatch(); + for (uint256 i = 0; i < numMsgs; ++i) { + uint256 newLimit = gasLimitOverrides[i]; + // Checks to ensure message cannot be executed with less gas than specified. + if (newLimit != 0) { + if (newLimit < report.messages[i].gasLimit) { + revert InvalidManualExecutionGasLimit(i, newLimit); + } + } + } + + _execute(report, gasLimitOverrides); + } + + /// @notice Entrypoint for execution, called by the OCR network + /// @dev Expects an encoded ExecutionReport + function _report(bytes calldata report) internal override { + _execute(abi.decode(report, (Internal.ExecutionReport)), new uint256[](0)); + } + + /// @notice Executes a report, executing each message in order. + /// @param report The execution report containing the messages and proofs. + /// @param manualExecGasLimits An array of gas limits to use for manual execution. + /// @dev If called from the DON, this array is always empty. + /// @dev If called from manual execution, this array is always same length as messages. + function _execute(Internal.ExecutionReport memory report, uint256[] memory manualExecGasLimits) internal { + if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(i_sourceChainSelector)))) revert CursedByRMN(); + + uint256 numMsgs = report.messages.length; + if (numMsgs == 0) revert EmptyReport(); + if (numMsgs != report.offchainTokenData.length) revert UnexpectedTokenData(); + + bytes32[] memory hashedLeaves = new bytes32[](numMsgs); + + for (uint256 i = 0; i < numMsgs; ++i) { + Internal.EVM2EVMMessage memory message = report.messages[i]; + // We do this hash here instead of in _verifyMessages to avoid two separate loops + // over the same data, which increases gas cost + hashedLeaves[i] = Internal._hash(message, i_metadataHash); + // For EVM2EVM offramps, the messageID is the leaf hash. + // Asserting that this is true ensures we don't accidentally commit and then execute + // a message with an unexpected hash. + if (hashedLeaves[i] != message.messageId) revert InvalidMessageId(); + } + + // SECURITY CRITICAL CHECK + uint256 timestampCommitted = ICommitStore(i_commitStore).verify(hashedLeaves, report.proofs, report.proofFlagBits); + if (timestampCommitted == 0) revert RootNotCommitted(); + + // Execute messages + bool manualExecution = manualExecGasLimits.length != 0; + for (uint256 i = 0; i < numMsgs; ++i) { + Internal.EVM2EVMMessage memory message = report.messages[i]; + Internal.MessageExecutionState originalState = getExecutionState(message.sequenceNumber); + if (originalState == Internal.MessageExecutionState.SUCCESS) { + // If the message has already been executed, we skip it. We want to not revert on race conditions between + // executing parties. This will allow us to open up manual exec while also attempting with the DON, without + // reverting an entire DON batch when a user manually executes while the tx is inflight. + emit SkippedAlreadyExecutedMessage(message.sequenceNumber); + continue; + } + // Two valid cases here, we either have never touched this message before, or we tried to execute + // and failed. This check protects against reentry and re-execution because the other state is + // IN_PROGRESS which should not be allowed to execute. + if ( + !( + originalState == Internal.MessageExecutionState.UNTOUCHED + || originalState == Internal.MessageExecutionState.FAILURE + ) + ) revert AlreadyExecuted(message.sequenceNumber); + + if (manualExecution) { + bool isOldCommitReport = + (block.timestamp - timestampCommitted) > s_dynamicConfig.permissionLessExecutionThresholdSeconds; + // Manually execution is fine if we previously failed or if the commit report is just too old + // Acceptable state transitions: FAILURE->SUCCESS, UNTOUCHED->SUCCESS, FAILURE->FAILURE + if (!(isOldCommitReport || originalState == Internal.MessageExecutionState.FAILURE)) { + revert ManualExecutionNotYetEnabled(); + } + + // Manual execution gas limit can override gas limit specified in the message. Value of 0 indicates no override. + if (manualExecGasLimits[i] != 0) { + message.gasLimit = manualExecGasLimits[i]; + } + } else { + // DON can only execute a message once + // Acceptable state transitions: UNTOUCHED->SUCCESS, UNTOUCHED->FAILURE + if (originalState != Internal.MessageExecutionState.UNTOUCHED) revert AlreadyAttempted(message.sequenceNumber); + } + + if (message.nonce != 0) { + // In the scenario where we upgrade offRamps, we still want to have sequential nonces. + // Referencing the old offRamp to check the expected nonce if none is set for a + // given sender allows us to skip the current message if it would not be the next according + // to the old offRamp. This preserves sequencing between updates. + uint64 prevNonce = s_senderNonce[message.sender]; + if (prevNonce == 0) { + if (i_prevOffRamp != address(0)) { + prevNonce = IAny2EVMOffRamp(i_prevOffRamp).getSenderNonce(message.sender); + if (prevNonce + 1 != message.nonce) { + // the starting v2 onramp nonce, i.e. the 1st message nonce v2 offramp is expected to receive, + // is guaranteed to equal (largest v1 onramp nonce + 1). + // if this message's nonce isn't (v1 offramp nonce + 1), then v1 offramp nonce != largest v1 onramp nonce, + // it tells us there are still messages inflight for v1 offramp + emit SkippedSenderWithPreviousRampMessageInflight(message.nonce, message.sender); + continue; + } + // Otherwise this nonce is indeed the "transitional nonce", that is + // all messages sent to v1 ramp have been executed by the DON and the sequence can resume in V2. + // Note if first time user in V2, then prevNonce will be 0, and message.nonce = 1, so this will be a no-op. + s_senderNonce[message.sender] = prevNonce; + } + } + + // UNTOUCHED messages MUST be executed in order always IF message.nonce > 0. + if (originalState == Internal.MessageExecutionState.UNTOUCHED) { + if (prevNonce + 1 != message.nonce) { + // We skip the message if the nonce is incorrect, since message.nonce > 0. + emit SkippedIncorrectNonce(message.nonce, message.sender); + continue; + } + } + } + + // Although we expect only valid messages will be committed, we check again + // when executing as a defense in depth measure. + bytes[] memory offchainTokenData = report.offchainTokenData[i]; + _isWellFormed( + message.sequenceNumber, + message.sourceChainSelector, + message.tokenAmounts.length, + message.data.length, + offchainTokenData.length + ); + + _setExecutionState(message.sequenceNumber, Internal.MessageExecutionState.IN_PROGRESS); + (Internal.MessageExecutionState newState, bytes memory returnData) = _trialExecute(message, offchainTokenData); + _setExecutionState(message.sequenceNumber, newState); + + // Since it's hard to estimate whether manual execution will succeed, we + // revert the entire transaction if it fails. This will show the user if + // their manual exec will fail before they submit it. + if (manualExecution) { + if (newState == Internal.MessageExecutionState.FAILURE) { + if (originalState != Internal.MessageExecutionState.UNTOUCHED) { + // If manual execution fails, we revert the entire transaction, unless the originalState is UNTOUCHED as we + // would still be making progress by changing the state from UNTOUCHED to FAILURE. + revert ExecutionError(returnData); + } + } + } + + // The only valid prior states are UNTOUCHED and FAILURE (checked above) + // The only valid post states are SUCCESS and FAILURE (checked below) + if (newState != Internal.MessageExecutionState.SUCCESS) { + if (newState != Internal.MessageExecutionState.FAILURE) { + revert InvalidNewState(message.sequenceNumber, newState); + } + } + + // Nonce changes per state transition. + // These only apply for ordered messages. + // UNTOUCHED -> FAILURE nonce bump + // UNTOUCHED -> SUCCESS nonce bump + // FAILURE -> FAILURE no nonce bump + // FAILURE -> SUCCESS no nonce bump + if (message.nonce != 0) { + if (originalState == Internal.MessageExecutionState.UNTOUCHED) { + s_senderNonce[message.sender]++; + } + } + + emit ExecutionStateChanged(message.sequenceNumber, message.messageId, newState, returnData); + } + } + + /// @notice Does basic message validation. Should never fail. + /// @param sequenceNumber Sequence number of the message. + /// @param sourceChainSelector SourceChainSelector of the message. + /// @param numberOfTokens Length of tokenAmounts array in the message. + /// @param dataLength Length of data field in the message. + /// @param offchainTokenDataLength Length of offchainTokenData array. + /// @dev reverts on validation failures. + function _isWellFormed( + uint64 sequenceNumber, + uint64 sourceChainSelector, + uint256 numberOfTokens, + uint256 dataLength, + uint256 offchainTokenDataLength + ) private view { + if (sourceChainSelector != i_sourceChainSelector) revert InvalidSourceChain(sourceChainSelector); + if (numberOfTokens > uint256(s_dynamicConfig.maxNumberOfTokensPerMsg)) { + revert UnsupportedNumberOfTokens(sequenceNumber); + } + if (numberOfTokens != offchainTokenDataLength) revert TokenDataMismatch(sequenceNumber); + if (dataLength > uint256(s_dynamicConfig.maxDataBytes)) { + revert MessageTooLarge(uint256(s_dynamicConfig.maxDataBytes), dataLength); + } + } + + /// @notice Try executing a message. + /// @param message Internal.EVM2EVMMessage memory message. + /// @param offchainTokenData Data provided by the DON for token transfers. + /// @return the new state of the message, being either SUCCESS or FAILURE. + /// @return revert data in bytes if CCIP receiver reverted during execution. + function _trialExecute( + Internal.EVM2EVMMessage memory message, + bytes[] memory offchainTokenData + ) internal returns (Internal.MessageExecutionState, bytes memory) { + try this.executeSingleMessage(message, offchainTokenData) {} + catch (bytes memory err) { + if ( + ReceiverError.selector == bytes4(err) || TokenHandlingError.selector == bytes4(err) + || Internal.InvalidEVMAddress.selector == bytes4(err) || InvalidDataLength.selector == bytes4(err) + || CallWithExactGas.NoContract.selector == bytes4(err) || NotACompatiblePool.selector == bytes4(err) + ) { + // If CCIP receiver execution is not successful, bubble up receiver revert data, + // prepended by the 4 bytes of ReceiverError.selector, TokenHandlingError.selector or InvalidPoolAddress.selector. + // Max length of revert data is Router.MAX_RET_BYTES, max length of err is 4 + Router.MAX_RET_BYTES + return (Internal.MessageExecutionState.FAILURE, err); + } + // If revert is not caused by CCIP receiver, it is unexpected, bubble up the revert. + revert ExecutionError(err); + } + // If message execution succeeded, no CCIP receiver return data is expected, return with empty bytes. + return (Internal.MessageExecutionState.SUCCESS, ""); + } + + /// @notice Execute a single message. + /// @param message The message that will be executed. + /// @param offchainTokenData Token transfer data to be passed to TokenPool. + /// @dev We make this external and callable by the contract itself, in order to try/catch + /// its execution and enforce atomicity among successful message processing and token transfer. + /// @dev We use ERC-165 to check for the ccipReceive interface to permit sending tokens to contracts + /// (for example smart contract wallets) without an associated message. + function executeSingleMessage(Internal.EVM2EVMMessage memory message, bytes[] memory offchainTokenData) external { + if (msg.sender != address(this)) revert CanOnlySelfCall(); + Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](0); + if (message.tokenAmounts.length > 0) { + destTokenAmounts = _releaseOrMintTokens( + message.tokenAmounts, abi.encode(message.sender), message.receiver, message.sourceTokenData, offchainTokenData + ); + } + // There are three cases in which we skip calling the receiver: + // 1. If the message data is empty AND the gas limit is 0. + // This indicates a message that only transfers tokens. It is valid to only send tokens to a contract + // that supports the IAny2EVMMessageReceiver interface, but without this first check we would call the + // receiver without any gas, which would revert the transaction. + // 2. If the receiver is not a contract. + // 3. If the receiver is a contract but it does not support the IAny2EVMMessageReceiver interface. + // + // The ordering of these checks is important, as the first check is the cheapest to execute. + if ( + (message.data.length == 0 && message.gasLimit == 0) || message.receiver.code.length == 0 + || !message.receiver.supportsInterface(type(IAny2EVMMessageReceiver).interfaceId) + ) return; + + (bool success, bytes memory returnData,) = IRouter(s_dynamicConfig.router).routeMessage( + Client.Any2EVMMessage({ + messageId: message.messageId, + sourceChainSelector: message.sourceChainSelector, + sender: abi.encode(message.sender), + data: message.data, + destTokenAmounts: destTokenAmounts + }), + Internal.GAS_FOR_CALL_EXACT_CHECK, + message.gasLimit, + message.receiver + ); + // If CCIP receiver execution is not successful, revert the call including token transfers + if (!success) revert ReceiverError(returnData); + } + + /// @notice creates a unique hash to be used in message hashing. + function _metadataHash(bytes32 prefix) internal view returns (bytes32) { + return keccak256(abi.encode(prefix, i_sourceChainSelector, i_chainSelector, i_onRamp)); + } + + // ================================================================ + // │ Config │ + // ================================================================ + + /// @notice Returns the static config. + /// @dev This function will always return the same struct as the contents is static and can never change. + /// RMN depends on this function, if changing, please notify the RMN maintainers. + function getStaticConfig() external view returns (StaticConfig memory) { + return StaticConfig({ + commitStore: i_commitStore, + chainSelector: i_chainSelector, + sourceChainSelector: i_sourceChainSelector, + onRamp: i_onRamp, + prevOffRamp: i_prevOffRamp, + rmnProxy: i_rmnProxy, + tokenAdminRegistry: i_tokenAdminRegistry + }); + } + + /// @notice Returns the current dynamic config. + /// @return The current config. + function getDynamicConfig() external view returns (DynamicConfig memory) { + return s_dynamicConfig; + } + + /// @notice Sets the dynamic config. This function is called during `setOCR2Config` flow + function _beforeSetConfig(bytes memory onchainConfig) internal override { + DynamicConfig memory dynamicConfig = abi.decode(onchainConfig, (DynamicConfig)); + + if (dynamicConfig.router == address(0)) revert ZeroAddressNotAllowed(); + + s_dynamicConfig = dynamicConfig; + + emit ConfigSet( + StaticConfig({ + commitStore: i_commitStore, + chainSelector: i_chainSelector, + sourceChainSelector: i_sourceChainSelector, + onRamp: i_onRamp, + prevOffRamp: i_prevOffRamp, + rmnProxy: i_rmnProxy, + tokenAdminRegistry: i_tokenAdminRegistry + }), + dynamicConfig + ); + } + + /// @notice Get all tokens which are included in Aggregate Rate Limiting. + /// @return sourceTokens The source representation of the tokens that are rate limited. + /// @return destTokens The destination representation of the tokens that are rate limited. + /// @dev the order of IDs in the list is **not guaranteed**, therefore, if ordering matters when + /// making successive calls, one should keep the block height constant to ensure a consistent result. + function getAllRateLimitTokens() external view returns (address[] memory sourceTokens, address[] memory destTokens) { + uint256 numRateLimitedTokens = s_rateLimitedTokensDestToSource.length(); + sourceTokens = new address[](numRateLimitedTokens); + destTokens = new address[](numRateLimitedTokens); + + for (uint256 i = 0; i < numRateLimitedTokens; ++i) { + (address destToken, address sourceToken) = s_rateLimitedTokensDestToSource.at(i); + sourceTokens[i] = sourceToken; + destTokens[i] = destToken; + } + return (sourceTokens, destTokens); + } + + /// @notice Adds or removes tokens from being used in Aggregate Rate Limiting. + /// @param removes - A list of one or more tokens to be removed. + /// @param adds - A list of one or more tokens to be added. + function updateRateLimitTokens(RateLimitToken[] memory removes, RateLimitToken[] memory adds) external onlyOwner { + for (uint256 i = 0; i < removes.length; ++i) { + if (s_rateLimitedTokensDestToSource.remove(removes[i].destToken)) { + emit TokenAggregateRateLimitRemoved(removes[i].sourceToken, removes[i].destToken); + } + } + + for (uint256 i = 0; i < adds.length; ++i) { + if (s_rateLimitedTokensDestToSource.set(adds[i].destToken, adds[i].sourceToken)) { + emit TokenAggregateRateLimitAdded(adds[i].sourceToken, adds[i].destToken); + } + } + } + + // ================================================================ + // │ Tokens and pools │ + // ================================================================ + + /// @notice Uses a pool to release or mint a token to a receiver address in two steps. First, the pool is called + /// to release the tokens to the offRamp, then the offRamp calls the token contract to transfer the tokens to the + /// receiver. This is done to ensure the exact number of tokens, the pool claims to release are actually transferred. + /// @dev The local token address is validated through the TokenAdminRegistry. If, due to some misconfiguration, the + /// token is unknown to the registry, the offRamp will revert. The tx, and the tokens, can be retrieved by + /// registering the token on this chain, and re-trying the msg. + /// @param sourceAmount The amount of tokens to be released/minted. + /// @param originalSender The message sender on the source chain. + /// @param receiver The address that will receive the tokens. + /// @param sourceTokenData A struct containing the local token address, the source pool address and optional data + /// returned from the source pool. + /// @param offchainTokenData Data fetched offchain by the DON. + function _releaseOrMintToken( + uint256 sourceAmount, + bytes memory originalSender, + address receiver, + Internal.SourceTokenData memory sourceTokenData, + bytes memory offchainTokenData + ) internal returns (Client.EVMTokenAmount memory destTokenAmount) { + // We need to safely decode the token address from the sourceTokenData, as it could be wrong, + // in which case it doesn't have to be a valid EVM address. + address localToken = Internal._validateEVMAddress(sourceTokenData.destTokenAddress); + // We check with the token admin registry if the token has a pool on this chain. + address localPoolAddress = ITokenAdminRegistry(i_tokenAdminRegistry).getPool(localToken); + // This will call the supportsInterface through the ERC165Checker, and not directly on the pool address. + // This is done to prevent a pool from reverting the entire transaction if it doesn't support the interface. + // The call gets a max or 30k gas per instance, of which there are three. This means gas estimations should + // account for 90k gas overhead due to the interface check. + if (localPoolAddress == address(0) || !localPoolAddress.supportsInterface(Pool.CCIP_POOL_V1)) { + revert NotACompatiblePool(localPoolAddress); + } + + // We determined that the pool address is a valid EVM address, but that does not mean the code at this + // address is a (compatible) pool contract. _callWithExactGasSafeReturnData will check if the location + // contains a contract. If it doesn't it reverts with a known error, which we catch gracefully. + // We call the pool with exact gas to increase resistance against malicious tokens or token pools. + // We protects against return data bombs by capping the return data size at MAX_RET_BYTES. + (bool success, bytes memory returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( + abi.encodeCall( + IPoolV1.releaseOrMint, + Pool.ReleaseOrMintInV1({ + originalSender: originalSender, + receiver: receiver, + amount: sourceAmount, + localToken: localToken, + remoteChainSelector: i_sourceChainSelector, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData + }) + ), + localPoolAddress, + s_dynamicConfig.maxPoolReleaseOrMintGas, + Internal.GAS_FOR_CALL_EXACT_CHECK, + Internal.MAX_RET_BYTES + ); + + // wrap and rethrow the error so we can catch it lower in the stack + if (!success) revert TokenHandlingError(returnData); + + // If the call was successful, the returnData should contain only the local token amount. + if (returnData.length != Pool.CCIP_POOL_V1_RET_BYTES) { + revert InvalidDataLength(Pool.CCIP_POOL_V1_RET_BYTES, returnData.length); + } + uint256 localAmount = abi.decode(returnData, (uint256)); + // Since token pools send the tokens to the msg.sender, which is this offRamp, we need to + // transfer them to the final receiver. We use the _callWithExactGasSafeReturnData function because + // the token contracts are not considered trusted. + (success, returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( + abi.encodeCall(IERC20.transfer, (receiver, localAmount)), + localToken, + s_dynamicConfig.maxTokenTransferGas, + Internal.GAS_FOR_CALL_EXACT_CHECK, + Internal.MAX_RET_BYTES + ); + + if (!success) revert TokenHandlingError(returnData); + + return Client.EVMTokenAmount({token: localToken, amount: localAmount}); + } + + /// @notice Uses pools to release or mint a number of different tokens to a receiver address. + /// @param sourceTokenAmounts List of tokens and amount values to be released/minted. + /// @param originalSender The message sender. + /// @param receiver The address that will receive the tokens. + /// @param encodedSourceTokenData Array of token data returned by token pools on the source chain. + /// @param offchainTokenData Array of token data fetched offchain by the DON. + /// @dev This function wrappes the token pool call in a try catch block to gracefully handle + /// any non-rate limiting errors that may occur. If we encounter a rate limiting related error + /// we bubble it up. If we encounter a non-rate limiting error we wrap it in a TokenHandlingError. + function _releaseOrMintTokens( + Client.EVMTokenAmount[] memory sourceTokenAmounts, + bytes memory originalSender, + address receiver, + bytes[] memory encodedSourceTokenData, + bytes[] memory offchainTokenData + ) internal returns (Client.EVMTokenAmount[] memory destTokenAmounts) { + // Creating a copy is more gas efficient than initializing a new array. + destTokenAmounts = sourceTokenAmounts; + uint256 value = 0; + for (uint256 i = 0; i < sourceTokenAmounts.length; ++i) { + destTokenAmounts[i] = _releaseOrMintToken( + sourceTokenAmounts[i].amount, + originalSender, + receiver, + // This should never revert as the onRamp encodes the sourceTokenData struct. Only the inner components from + // this struct come from untrusted sources. + abi.decode(encodedSourceTokenData[i], (Internal.SourceTokenData)), + offchainTokenData[i] + ); + + if (s_rateLimitedTokensDestToSource.contains(destTokenAmounts[i].token)) { + value += _getTokenValue(destTokenAmounts[i], IPriceRegistry(s_dynamicConfig.priceRegistry)); + } + } + + if (value > 0) _rateLimitValue(value); + + return destTokenAmounts; + } + + // ================================================================ + // │ Access │ + // ================================================================ + + /// @notice Reverts as this contract should not access CCIP messages + function ccipReceive(Client.Any2EVMMessage calldata) external pure { + // solhint-disable-next-line + revert(); + } +} diff --git a/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol b/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol new file mode 100644 index 0000000000..fc455cc869 --- /dev/null +++ b/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol @@ -0,0 +1,339 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IEVM2AnyOnRampClient} from "../interfaces/IEVM2AnyOnRampClient.sol"; +import {IMessageInterceptor} from "../interfaces/IMessageInterceptor.sol"; +import {INonceManager} from "../interfaces/INonceManager.sol"; +import {IPoolV1} from "../interfaces/IPool.sol"; +import {IPriceRegistry} from "../interfaces/IPriceRegistry.sol"; +import {IRMN} from "../interfaces/IRMN.sol"; +import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol"; + +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; +import {Client} from "../libraries/Client.sol"; +import {Internal} from "../libraries/Internal.sol"; +import {Pool} from "../libraries/Pool.sol"; +import {USDPriceWith18Decimals} from "../libraries/USDPriceWith18Decimals.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +/// @notice The EVM2EVMMultiOnRamp is a contract that handles lane-specific fee logic +/// @dev The EVM2EVMMultiOnRamp, MultiCommitStore and EVM2EVMMultiOffRamp form an xchain upgradeable unit. Any change to one of them +/// results an onchain upgrade of all 3. +contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { + using SafeERC20 for IERC20; + using USDPriceWith18Decimals for uint224; + + error CannotSendZeroTokens(); + error InvalidExtraArgsTag(); + error ExtraArgOutOfOrderExecutionMustBeTrue(); + error OnlyCallableByOwnerOrAdmin(); + error MessageGasLimitTooHigh(); + error UnsupportedToken(address token); + error MustBeCalledByRouter(); + error RouterMustSetOriginalSender(); + error InvalidConfig(); + error CursedByRMN(uint64 sourceChainSelector); + error GetSupportedTokensFunctionalityRemovedCheckAdminRegistry(); + + event AdminSet(address newAdmin); + event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig); + event FeePaid(address indexed feeToken, uint256 feeValueJuels); + event FeeTokenWithdrawn(address indexed feeAggregator, address indexed feeToken, uint256 amount); + /// RMN depends on this event, if changing, please notify the RMN maintainers. + event CCIPSendRequested(uint64 indexed destChainSelector, Internal.EVM2AnyRampMessage message); + + /// @dev Struct that contains the static configuration + /// RMN depends on this struct, if changing, please notify the RMN maintainers. + // solhint-disable-next-line gas-struct-packing + struct StaticConfig { + uint64 chainSelector; // ─────╮ Source chainSelector + address rmnProxy; // ─────────╯ Address of RMN proxy + address nonceManager; // Address of the nonce manager + address tokenAdminRegistry; // Token admin registry address + } + + /// @dev Struct to contains the dynamic configuration + // solhint-disable-next-line gas-struct-packing + struct DynamicConfig { + address router; // Router address + address priceRegistry; // Price registry address + address messageValidator; // Optional message validator to validate outbound messages (zero address = no validator) + address feeAggregator; // Fee aggregator address + } + + // STATIC CONFIG + string public constant override typeAndVersion = "EVM2EVMMultiOnRamp 1.6.0-dev"; + /// @dev The chain ID of the source chain that this contract is deployed to + uint64 internal immutable i_chainSelector; + /// @dev The address of the rmn proxy + address internal immutable i_rmnProxy; + /// @dev The address of the nonce manager + address internal immutable i_nonceManager; + /// @dev The address of the token admin registry + address internal immutable i_tokenAdminRegistry; + /// @dev the maximum number of nops that can be configured at the same time. + /// Used to bound gas for loops over nops. + uint256 private constant MAX_NUMBER_OF_NOPS = 64; + + // DYNAMIC CONFIG + /// @dev The config for the onRamp + DynamicConfig internal s_dynamicConfig; + + /// @dev Last used sequence number per destination chain. + /// This is zero in the case where no messages have been sent yet. + /// 0 is not a valid sequence number for any real transaction. + mapping(uint64 destChainSelector => uint64 sequenceNumber) internal s_destChainSequenceNumbers; + + // STATE + /// @dev The amount of LINK available to pay NOPS + uint96 internal s_nopFeesJuels; + /// @dev The combined weight of all NOPs weights + uint32 internal s_nopWeightsTotal; + + constructor(StaticConfig memory staticConfig, DynamicConfig memory dynamicConfig) { + if ( + staticConfig.chainSelector == 0 || staticConfig.rmnProxy == address(0) || staticConfig.nonceManager == address(0) + || staticConfig.tokenAdminRegistry == address(0) + ) { + revert InvalidConfig(); + } + + i_chainSelector = staticConfig.chainSelector; + i_rmnProxy = staticConfig.rmnProxy; + i_nonceManager = staticConfig.nonceManager; + i_tokenAdminRegistry = staticConfig.tokenAdminRegistry; + + _setDynamicConfig(dynamicConfig); + } + + // ================================================================ + // │ Messaging │ + // ================================================================ + + /// @notice Gets the next sequence number to be used in the onRamp + /// @param destChainSelector The destination chain selector + /// @return the next sequence number to be used + function getExpectedNextSequenceNumber(uint64 destChainSelector) external view returns (uint64) { + return s_destChainSequenceNumbers[destChainSelector] + 1; + } + + /// @inheritdoc IEVM2AnyOnRampClient + function forwardFromRouter( + uint64 destChainSelector, + Client.EVM2AnyMessage calldata message, + uint256 feeTokenAmount, + address originalSender + ) external returns (bytes32) { + // NOTE: assumes the message has already been validated through the getFee call + // Validate message sender is set and allowed. Not validated in `getFee` since it is not user-driven. + if (originalSender == address(0)) revert RouterMustSetOriginalSender(); + // Router address may be zero intentionally to pause. + if (msg.sender != s_dynamicConfig.router) revert MustBeCalledByRouter(); + + address messageValidator = s_dynamicConfig.messageValidator; + if (messageValidator != address(0)) { + IMessageInterceptor(messageValidator).onOutboundMessage(destChainSelector, message); + } + + // Convert message fee to juels and retrieve converted args + (uint256 msgFeeJuels, bool isOutOfOrderExecution, bytes memory convertedExtraArgs) = IPriceRegistry( + s_dynamicConfig.priceRegistry + ).processMessageArgs(destChainSelector, message.feeToken, feeTokenAmount, message.extraArgs); + + emit FeePaid(message.feeToken, msgFeeJuels); + + Internal.EVM2AnyRampMessage memory newMessage = Internal.EVM2AnyRampMessage({ + header: Internal.RampMessageHeader({ + // Should be generated after the message is complete + messageId: "", + sourceChainSelector: i_chainSelector, + destChainSelector: destChainSelector, + // We need the next available sequence number so we increment before we use the value + sequenceNumber: ++s_destChainSequenceNumbers[destChainSelector], + // Only bump nonce for messages that specify allowOutOfOrderExecution == false. Otherwise, we + // may block ordered message nonces, which is not what we want. + nonce: isOutOfOrderExecution + ? 0 + : INonceManager(i_nonceManager).getIncrementedOutboundNonce(destChainSelector, originalSender) + }), + sender: originalSender, + data: message.data, + extraArgs: message.extraArgs, + receiver: message.receiver, + feeToken: message.feeToken, + feeTokenAmount: feeTokenAmount, + // Should be populated via lock / burn pool calls + tokenAmounts: new Internal.RampTokenAmount[](message.tokenAmounts.length) + }); + + // Lock the tokens as last step. TokenPools may not always be trusted. + // There should be no state changes after external call to TokenPools. + for (uint256 i = 0; i < message.tokenAmounts.length; ++i) { + newMessage.tokenAmounts[i] = + _lockOrBurnSingleToken(message.tokenAmounts[i], destChainSelector, message.receiver, originalSender); + } + + // Validate pool return data after it is populated (view function - no state changes) + IPriceRegistry(s_dynamicConfig.priceRegistry).validatePoolReturnData( + destChainSelector, newMessage.tokenAmounts, message.tokenAmounts + ); + + // Override extraArgs with latest version + newMessage.extraArgs = convertedExtraArgs; + + // Hash only after all fields have been set + newMessage.header.messageId = Internal._hash( + newMessage, + // Metadata hash preimage to ensure global uniqueness, ensuring 2 identical messages sent to 2 different + // lanes will have a distinct hash. + keccak256(abi.encode(Internal.EVM_2_ANY_MESSAGE_HASH, i_chainSelector, destChainSelector, address(this))) + ); + + // Emit message request + // This must happen after any pool events as some tokens (e.g. USDC) emit events that we expect to precede this + // event in the offchain code. + emit CCIPSendRequested(destChainSelector, newMessage); + return newMessage.header.messageId; + } + + /// @notice Uses a pool to lock or burn a token + /// @param tokenAndAmount Token address and amount to lock or burn + /// @param destChainSelector Target dest chain selector of the message + /// @param receiver Message receiver + /// @param originalSender Message sender + /// @return rampTokenAndAmount Ramp token and amount data + function _lockOrBurnSingleToken( + Client.EVMTokenAmount memory tokenAndAmount, + uint64 destChainSelector, + bytes memory receiver, + address originalSender + ) internal returns (Internal.RampTokenAmount memory) { + if (tokenAndAmount.amount == 0) revert CannotSendZeroTokens(); + + IPoolV1 sourcePool = getPoolBySourceToken(destChainSelector, IERC20(tokenAndAmount.token)); + // We don't have to check if it supports the pool version in a non-reverting way here because + // if we revert here, there is no effect on CCIP. Therefore we directly call the supportsInterface + // function and not through the ERC165Checker. + if (address(sourcePool) == address(0) || !sourcePool.supportsInterface(Pool.CCIP_POOL_V1)) { + revert UnsupportedToken(tokenAndAmount.token); + } + + Pool.LockOrBurnOutV1 memory poolReturnData = sourcePool.lockOrBurn( + Pool.LockOrBurnInV1({ + receiver: receiver, + remoteChainSelector: destChainSelector, + originalSender: originalSender, + amount: tokenAndAmount.amount, + localToken: tokenAndAmount.token + }) + ); + + // NOTE: pool data validations are outsourced to the PriceRegistry to handle family-specific logic handling + + return Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(sourcePool), + destTokenAddress: poolReturnData.destTokenAddress, + extraData: poolReturnData.destPoolData, + amount: tokenAndAmount.amount + }); + } + + // ================================================================ + // │ Config │ + // ================================================================ + + /// @notice Returns the static onRamp config. + /// @dev RMN depends on this function, if changing, please notify the RMN maintainers. + /// @return the configuration. + function getStaticConfig() external view returns (StaticConfig memory) { + return StaticConfig({ + chainSelector: i_chainSelector, + rmnProxy: i_rmnProxy, + nonceManager: i_nonceManager, + tokenAdminRegistry: i_tokenAdminRegistry + }); + } + + /// @notice Returns the dynamic onRamp config. + /// @return dynamicConfig the configuration. + function getDynamicConfig() external view returns (DynamicConfig memory dynamicConfig) { + return s_dynamicConfig; + } + + /// @notice Sets the dynamic configuration. + /// @param dynamicConfig The configuration. + function setDynamicConfig(DynamicConfig memory dynamicConfig) external onlyOwner { + _setDynamicConfig(dynamicConfig); + } + + /// @notice Internal version of setDynamicConfig to allow for reuse in the constructor. + function _setDynamicConfig(DynamicConfig memory dynamicConfig) internal { + // We permit router to be set to zero as a way to pause the contract. + if (dynamicConfig.priceRegistry == address(0) || dynamicConfig.feeAggregator == address(0)) revert InvalidConfig(); + + s_dynamicConfig = dynamicConfig; + + emit ConfigSet( + StaticConfig({ + chainSelector: i_chainSelector, + rmnProxy: i_rmnProxy, + nonceManager: i_nonceManager, + tokenAdminRegistry: i_tokenAdminRegistry + }), + dynamicConfig + ); + } + + // ================================================================ + // │ Tokens and pools │ + // ================================================================ + + /// @inheritdoc IEVM2AnyOnRampClient + function getPoolBySourceToken(uint64, /*destChainSelector*/ IERC20 sourceToken) public view returns (IPoolV1) { + return IPoolV1(ITokenAdminRegistry(i_tokenAdminRegistry).getPool(address(sourceToken))); + } + + /// @inheritdoc IEVM2AnyOnRampClient + function getSupportedTokens(uint64 /*destChainSelector*/ ) external pure returns (address[] memory) { + revert GetSupportedTokensFunctionalityRemovedCheckAdminRegistry(); + } + + // ================================================================ + // │ Fees │ + // ================================================================ + + /// @inheritdoc IEVM2AnyOnRampClient + /// @dev getFee MUST revert if the feeToken is not listed in the fee token config, as the router assumes it does. + /// @param destChainSelector The destination chain selector. + /// @param message The message to get quote for. + /// @return feeTokenAmount The amount of fee token needed for the fee, in smallest denomination of the fee token. + function getFee( + uint64 destChainSelector, + Client.EVM2AnyMessage calldata message + ) external view returns (uint256 feeTokenAmount) { + if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(destChainSelector)))) revert CursedByRMN(destChainSelector); + + return IPriceRegistry(s_dynamicConfig.priceRegistry).getValidatedFee(destChainSelector, message); + } + + /// @notice Withdraws the outstanding fee token balances to the fee aggregator. + /// @dev This function can be permissionless as it only transfers accepted fee tokens to the fee aggregator which is a trusted address. + function withdrawFeeTokens() external { + address[] memory feeTokens = IPriceRegistry(s_dynamicConfig.priceRegistry).getFeeTokens(); + address feeAggregator = s_dynamicConfig.feeAggregator; + + for (uint256 i = 0; i < feeTokens.length; ++i) { + IERC20 feeToken = IERC20(feeTokens[i]); + uint256 feeTokenBalance = feeToken.balanceOf(address(this)); + + if (feeTokenBalance > 0) { + feeToken.safeTransfer(feeAggregator, feeTokenBalance); + + emit FeeTokenWithdrawn(feeAggregator, address(feeToken), feeTokenBalance); + } + } + } +} diff --git a/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol b/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol new file mode 100644 index 0000000000..0e978596e4 --- /dev/null +++ b/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol @@ -0,0 +1,916 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IEVM2AnyOnRamp} from "../interfaces/IEVM2AnyOnRamp.sol"; +import {IEVM2AnyOnRampClient} from "../interfaces/IEVM2AnyOnRampClient.sol"; +import {IPoolV1} from "../interfaces/IPool.sol"; +import {IPriceRegistry} from "../interfaces/IPriceRegistry.sol"; +import {IRMN} from "../interfaces/IRMN.sol"; +import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol"; +import {ILinkAvailable} from "../interfaces/automation/ILinkAvailable.sol"; + +import {AggregateRateLimiter} from "../AggregateRateLimiter.sol"; +import {Client} from "../libraries/Client.sol"; +import {Internal} from "../libraries/Internal.sol"; +import {Pool} from "../libraries/Pool.sol"; +import {RateLimiter} from "../libraries/RateLimiter.sol"; +import {USDPriceWith18Decimals} from "../libraries/USDPriceWith18Decimals.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {EnumerableMap} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableMap.sol"; + +/// @notice The onRamp is a contract that handles lane-specific fee logic, NOP payments and +/// bridgeable token support. +/// @dev The EVM2EVMOnRamp, CommitStore and EVM2EVMOffRamp form an xchain upgradeable unit. Any change to one of them +/// results an onchain upgrade of all 3. +contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, ITypeAndVersion { + using SafeERC20 for IERC20; + using EnumerableMap for EnumerableMap.AddressToUintMap; + using USDPriceWith18Decimals for uint224; + + error InvalidExtraArgsTag(); + error ExtraArgOutOfOrderExecutionMustBeTrue(); + error OnlyCallableByOwnerOrAdmin(); + error OnlyCallableByOwnerOrAdminOrNop(); + error InvalidWithdrawParams(); + error NoFeesToPay(); + error NoNopsToPay(); + error InsufficientBalance(); + error TooManyNops(); + error MaxFeeBalanceReached(); + error MessageTooLarge(uint256 maxSize, uint256 actualSize); + error MessageGasLimitTooHigh(); + error UnsupportedNumberOfTokens(); + error UnsupportedToken(address token); + error MustBeCalledByRouter(); + error RouterMustSetOriginalSender(); + error InvalidConfig(); + error CursedByRMN(); + error LinkBalanceNotSettled(); + error InvalidNopAddress(address nop); + error NotAFeeToken(address token); + error CannotSendZeroTokens(); + error SourceTokenDataTooLarge(address token); + error InvalidChainSelector(uint64 chainSelector); + error GetSupportedTokensFunctionalityRemovedCheckAdminRegistry(); + error InvalidDestBytesOverhead(address token, uint32 destBytesOverhead); + + event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig); + event NopPaid(address indexed nop, uint256 amount); + event FeeConfigSet(FeeTokenConfigArgs[] feeConfig); + event TokenTransferFeeConfigSet(TokenTransferFeeConfigArgs[] transferFeeConfig); + event TokenTransferFeeConfigDeleted(address[] tokens); + /// RMN depends on this event, if changing, please notify the RMN maintainers. + event CCIPSendRequested(Internal.EVM2EVMMessage message); + event NopsSet(uint256 nopWeightsTotal, NopAndWeight[] nopsAndWeights); + + /// @dev Struct that contains the static configuration + /// RMN depends on this struct, if changing, please notify the RMN maintainers. + //solhint-disable gas-struct-packing + struct StaticConfig { + address linkToken; // ────────╮ Link token address + uint64 chainSelector; // ─────╯ Source chainSelector + uint64 destChainSelector; // ─╮ Destination chainSelector + uint64 defaultTxGasLimit; // │ Default gas limit for a tx + uint96 maxNopFeesJuels; // ───╯ Max nop fee balance onramp can have + address prevOnRamp; // Address of previous-version OnRamp + address rmnProxy; // Address of RMN proxy + address tokenAdminRegistry; // Address of the token admin registry + } + + /// @dev Struct to contains the dynamic configuration + struct DynamicConfig { + address router; // ──────────────────────────╮ Router address + uint16 maxNumberOfTokensPerMsg; // │ Maximum number of distinct ERC20 token transferred per message + uint32 destGasOverhead; // │ Gas charged on top of the gasLimit to cover destination chain costs + uint16 destGasPerPayloadByte; // │ Destination chain gas charged for passing each byte of `data` payload to receiver + uint32 destDataAvailabilityOverheadGas; // ──╯ Extra data availability gas charged on top of the message, e.g. for OCR + uint16 destGasPerDataAvailabilityByte; // ───╮ Amount of gas to charge per byte of message data that needs availability + uint16 destDataAvailabilityMultiplierBps; // │ Multiplier for data availability gas, multiples of bps, or 0.0001 + address priceRegistry; // │ Price registry address + uint32 maxDataBytes; // │ Maximum payload data size in bytes + uint32 maxPerMsgGasLimit; // ────────────────╯ Maximum gas limit for messages targeting EVMs + // │ + // The following three properties are defaults, they can be overridden by setting the TokenTransferFeeConfig for a token + uint16 defaultTokenFeeUSDCents; // ──────────╮ Default token fee charged per token transfer + uint32 defaultTokenDestGasOverhead; // │ Default gas charged to execute the token transfer on the destination chain + // │ Default data availability bytes that are returned from the source pool and sent + uint32 defaultTokenDestBytesOverhead; // | to the destination pool. Must be >= Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + bool enforceOutOfOrder; // ──────────────────╯ Whether to enforce the allowOutOfOrderExecution extraArg value to be true. + } + + /// @dev Struct to hold the execution fee configuration for a fee token + struct FeeTokenConfig { + uint32 networkFeeUSDCents; // ─────────╮ Flat network fee to charge for messages, multiples of 0.01 USD + uint64 gasMultiplierWeiPerEth; // │ Multiplier for gas costs, 1e18 based so 11e17 = 10% extra cost. + uint64 premiumMultiplierWeiPerEth; // │ Multiplier for fee-token-specific premiums + bool enabled; // ──────────────────────╯ Whether this fee token is enabled + } + + /// @dev Struct to hold the fee configuration for a fee token, same as the FeeTokenConfig but with + /// token included so that an array of these can be passed in to setFeeTokenConfig to set the mapping + struct FeeTokenConfigArgs { + address token; // ─────────────────────╮ Token address + uint32 networkFeeUSDCents; // │ Flat network fee to charge for messages, multiples of 0.01 USD + uint64 gasMultiplierWeiPerEth; // ─────╯ Multiplier for gas costs, 1e18 based so 11e17 = 10% extra cost + uint64 premiumMultiplierWeiPerEth; // ─╮ Multiplier for fee-token-specific premiums, 1e18 based + bool enabled; // ──────────────────────╯ Whether this fee token is enabled + } + + /// @dev Struct to hold the transfer fee configuration for token transfers + struct TokenTransferFeeConfig { + uint32 minFeeUSDCents; // ──────────╮ Minimum fee to charge per token transfer, multiples of 0.01 USD + uint32 maxFeeUSDCents; // │ Maximum fee to charge per token transfer, multiples of 0.01 USD + uint16 deciBps; // │ Basis points charged on token transfers, multiples of 0.1bps, or 1e-5 + uint32 destGasOverhead; // │ Gas charged to execute the token transfer on the destination chain + // │ Extra data availability bytes that are returned from the source pool and sent + uint32 destBytesOverhead; // │ to the destination pool. Must be >= Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + bool aggregateRateLimitEnabled; // │ Whether this transfer token is to be included in Aggregate Rate Limiting + bool isEnabled; // ─────────────────╯ Whether this token has custom transfer fees + } + + /// @dev Same as TokenTransferFeeConfig + /// token included so that an array of these can be passed in to setTokenTransferFeeConfig + struct TokenTransferFeeConfigArgs { + address token; // ──────────────────╮ Token address + uint32 minFeeUSDCents; // │ Minimum fee to charge per token transfer, multiples of 0.01 USD + uint32 maxFeeUSDCents; // │ Maximum fee to charge per token transfer, multiples of 0.01 USD + uint16 deciBps; // ─────────────────╯ Basis points charged on token transfers, multiples of 0.1bps, or 1e-5 + uint32 destGasOverhead; // ─────────╮ Gas charged to execute the token transfer on the destination chain + // │ Extra data availability bytes that are returned from the source pool and sent + uint32 destBytesOverhead; // │ to the destination pool. Must be >= Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + bool aggregateRateLimitEnabled; // ─╯ Whether this transfer token is to be included in Aggregate Rate Limiting + } + + /// @dev Nop address and weight, used to set the nops and their weights + struct NopAndWeight { + address nop; // ────╮ Address of the node operator + uint16 weight; // ──╯ Weight for nop rewards + } + + // STATIC CONFIG + string public constant override typeAndVersion = "EVM2EVMOnRamp 1.5.0-dev"; + /// @dev metadataHash is a lane-specific prefix for a message hash preimage which ensures global uniqueness + /// Ensures that 2 identical messages sent to 2 different lanes will have a distinct hash. + /// Must match the metadataHash used in computing leaf hashes offchain for the root committed in + /// the commitStore and i_metadataHash in the offRamp. + bytes32 internal immutable i_metadataHash; + /// @dev Default gas limit for a transactions that did not specify + /// a gas limit in the extraArgs. + uint64 internal immutable i_defaultTxGasLimit; + /// @dev Maximum nop fee that can accumulate in this onramp + uint96 internal immutable i_maxNopFeesJuels; + /// @dev The link token address - known to pay nops for their work + address internal immutable i_linkToken; + /// @dev The chain ID of the source chain that this contract is deployed to + uint64 internal immutable i_chainSelector; + /// @dev The chain ID of the destination chain + uint64 internal immutable i_destChainSelector; + /// @dev The address of previous-version OnRamp for this lane + /// Used to be able to provide sequencing continuity during a zero downtime upgrade. + address internal immutable i_prevOnRamp; + /// @dev The address of the RMN proxy + address internal immutable i_rmnProxy; + /// @dev The address of the token admin registry + address internal immutable i_tokenAdminRegistry; + /// @dev the maximum number of nops that can be configured at the same time. + /// Used to bound gas for loops over nops. + uint256 private constant MAX_NUMBER_OF_NOPS = 64; + + // DYNAMIC CONFIG + /// @dev The config for the onRamp + DynamicConfig internal s_dynamicConfig; + /// @dev (address nop => uint256 weight) + EnumerableMap.AddressToUintMap internal s_nops; + + /// @dev The execution fee token config that can be set by the owner or fee admin + mapping(address token => FeeTokenConfig feeTokenConfig) internal s_feeTokenConfig; + /// @dev The token transfer fee config that can be set by the owner or fee admin + mapping(address token => TokenTransferFeeConfig tranferFeeConfig) internal s_tokenTransferFeeConfig; + + // STATE + /// @dev The current nonce per sender. + /// The offramp has a corresponding s_senderNonce mapping to ensure messages + /// are executed in the same order they are sent. + mapping(address sender => uint64 nonce) internal s_senderNonce; + /// @dev The amount of LINK available to pay NOPS + uint96 internal s_nopFeesJuels; + /// @dev The combined weight of all NOPs weights + uint32 internal s_nopWeightsTotal; + /// @dev The last used sequence number. This is zero in the case where no + /// messages has been sent yet. 0 is not a valid sequence number for any + /// real transaction. + uint64 internal s_sequenceNumber; + + constructor( + StaticConfig memory staticConfig, + DynamicConfig memory dynamicConfig, + RateLimiter.Config memory rateLimiterConfig, + FeeTokenConfigArgs[] memory feeTokenConfigs, + TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs, + NopAndWeight[] memory nopsAndWeights + ) AggregateRateLimiter(rateLimiterConfig) { + if ( + staticConfig.linkToken == address(0) || staticConfig.chainSelector == 0 || staticConfig.destChainSelector == 0 + || staticConfig.defaultTxGasLimit == 0 || staticConfig.rmnProxy == address(0) + || staticConfig.tokenAdminRegistry == address(0) + ) revert InvalidConfig(); + + i_metadataHash = keccak256( + abi.encode( + Internal.EVM_2_EVM_MESSAGE_HASH, staticConfig.chainSelector, staticConfig.destChainSelector, address(this) + ) + ); + i_linkToken = staticConfig.linkToken; + i_chainSelector = staticConfig.chainSelector; + i_destChainSelector = staticConfig.destChainSelector; + i_defaultTxGasLimit = staticConfig.defaultTxGasLimit; + i_maxNopFeesJuels = staticConfig.maxNopFeesJuels; + i_prevOnRamp = staticConfig.prevOnRamp; + i_rmnProxy = staticConfig.rmnProxy; + i_tokenAdminRegistry = staticConfig.tokenAdminRegistry; + + _setDynamicConfig(dynamicConfig); + _setFeeTokenConfig(feeTokenConfigs); + _setTokenTransferFeeConfig(tokenTransferFeeConfigArgs, new address[](0)); + _setNops(nopsAndWeights); + } + + // ================================================================ + // │ Messaging │ + // ================================================================ + + /// @inheritdoc IEVM2AnyOnRamp + function getExpectedNextSequenceNumber() external view returns (uint64) { + return s_sequenceNumber + 1; + } + + /// @inheritdoc IEVM2AnyOnRamp + function getSenderNonce(address sender) external view returns (uint64) { + uint256 senderNonce = s_senderNonce[sender]; + + if (i_prevOnRamp != address(0)) { + if (senderNonce == 0) { + // If OnRamp was upgraded, check if sender has a nonce from the previous OnRamp. + return IEVM2AnyOnRamp(i_prevOnRamp).getSenderNonce(sender); + } + } + return uint64(senderNonce); + } + + /// @inheritdoc IEVM2AnyOnRampClient + function forwardFromRouter( + uint64 destChainSelector, + Client.EVM2AnyMessage calldata message, + uint256 feeTokenAmount, + address originalSender + ) external returns (bytes32) { + if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(destChainSelector)))) revert CursedByRMN(); + // Validate message sender is set and allowed. Not validated in `getFee` since it is not user-driven. + if (originalSender == address(0)) revert RouterMustSetOriginalSender(); + // Router address may be zero intentionally to pause. + if (msg.sender != s_dynamicConfig.router) revert MustBeCalledByRouter(); + if (destChainSelector != i_destChainSelector) revert InvalidChainSelector(destChainSelector); + + Client.EVMExtraArgsV2 memory extraArgs = _fromBytes(message.extraArgs); + // Validate the message with various checks + uint256 numberOfTokens = message.tokenAmounts.length; + _validateMessage(message.data.length, extraArgs.gasLimit, numberOfTokens, extraArgs.allowOutOfOrderExecution); + + // Only check token value if there are tokens + if (numberOfTokens > 0) { + uint256 value; + for (uint256 i = 0; i < numberOfTokens; ++i) { + if (message.tokenAmounts[i].amount == 0) revert CannotSendZeroTokens(); + if (s_tokenTransferFeeConfig[message.tokenAmounts[i].token].aggregateRateLimitEnabled) { + value += _getTokenValue(message.tokenAmounts[i], IPriceRegistry(s_dynamicConfig.priceRegistry)); + } + } + // Rate limit on aggregated token value + if (value > 0) _rateLimitValue(value); + } + + // Convert feeToken to link if not already in link + if (message.feeToken == i_linkToken) { + // Since there is only 1b link this is safe + s_nopFeesJuels += uint96(feeTokenAmount); + } else { + // the cast from uint256 to uint96 is considered safe, uint96 can store more than max supply of link token + s_nopFeesJuels += uint96( + IPriceRegistry(s_dynamicConfig.priceRegistry).convertTokenAmount(message.feeToken, feeTokenAmount, i_linkToken) + ); + } + if (s_nopFeesJuels > i_maxNopFeesJuels) revert MaxFeeBalanceReached(); + + if (i_prevOnRamp != address(0)) { + if (s_senderNonce[originalSender] == 0) { + // If this is first time send for a sender in new OnRamp, check if they have a nonce + // from the previous OnRamp and start from there instead of zero. + s_senderNonce[originalSender] = IEVM2AnyOnRamp(i_prevOnRamp).getSenderNonce(originalSender); + } + } + + // We need the next available sequence number so we increment before we use the value + Internal.EVM2EVMMessage memory newMessage = Internal.EVM2EVMMessage({ + sourceChainSelector: i_chainSelector, + sender: originalSender, + // EVM destination addresses should be abi encoded and therefore always 32 bytes long + // Not duplicately validated in `getFee`. Invalid address is uncommon, gas cost outweighs UX gain. + receiver: Internal._validateEVMAddress(message.receiver), + sequenceNumber: ++s_sequenceNumber, + gasLimit: extraArgs.gasLimit, + strict: false, + // Only bump nonce for messages that specify allowOutOfOrderExecution == false. Otherwise, we + // may block ordered message nonces, which is not what we want. + nonce: extraArgs.allowOutOfOrderExecution ? 0 : ++s_senderNonce[originalSender], + feeToken: message.feeToken, + feeTokenAmount: feeTokenAmount, + data: message.data, + tokenAmounts: message.tokenAmounts, + sourceTokenData: new bytes[](numberOfTokens), // will be populated below + messageId: "" + }); + + // Lock the tokens as last step. TokenPools may not always be trusted. + // There should be no state changes after external call to TokenPools. + for (uint256 i = 0; i < numberOfTokens; ++i) { + Client.EVMTokenAmount memory tokenAndAmount = message.tokenAmounts[i]; + IPoolV1 sourcePool = getPoolBySourceToken(destChainSelector, IERC20(tokenAndAmount.token)); + // We don't have to check if it supports the pool version in a non-reverting way here because + // if we revert here, there is no effect on CCIP. Therefore we directly call the supportsInterface + // function and not through the ERC165Checker. + if (address(sourcePool) == address(0) || !sourcePool.supportsInterface(Pool.CCIP_POOL_V1)) { + revert UnsupportedToken(tokenAndAmount.token); + } + + Pool.LockOrBurnOutV1 memory poolReturnData = sourcePool.lockOrBurn( + Pool.LockOrBurnInV1({ + receiver: message.receiver, + remoteChainSelector: i_destChainSelector, + originalSender: originalSender, + amount: tokenAndAmount.amount, + localToken: tokenAndAmount.token + }) + ); + + // Since the DON has to pay for the extraData to be included on the destination chain, we cap the length of the + // extraData. This prevents gas bomb attacks on the NOPs. As destBytesOverhead accounts for both + // extraData and offchainData, this caps the worst case abuse to the number of bytes reserved for offchainData. + if (poolReturnData.destPoolData.length > Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) { + if (poolReturnData.destPoolData.length > s_tokenTransferFeeConfig[tokenAndAmount.token].destBytesOverhead) { + revert SourceTokenDataTooLarge(tokenAndAmount.token); + } + } + // We validate the token address to ensure it is a valid EVM address + Internal._validateEVMAddress(poolReturnData.destTokenAddress); + + newMessage.sourceTokenData[i] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(sourcePool), + destTokenAddress: poolReturnData.destTokenAddress, + extraData: poolReturnData.destPoolData + }) + ); + } + + // Hash only after the sourceTokenData has been set + newMessage.messageId = Internal._hash(newMessage, i_metadataHash); + + // Emit message request + // This must happen after any pool events as some tokens (e.g. USDC) emit events that we expect to precede this + // event in the offchain code. + emit CCIPSendRequested(newMessage); + return newMessage.messageId; + } + + /// @dev Convert the extra args bytes into a struct + /// @param extraArgs The extra args bytes + /// @return The extra args struct + function _fromBytes(bytes calldata extraArgs) internal view returns (Client.EVMExtraArgsV2 memory) { + if (extraArgs.length == 0) { + return Client.EVMExtraArgsV2({gasLimit: i_defaultTxGasLimit, allowOutOfOrderExecution: false}); + } + + bytes4 extraArgsTag = bytes4(extraArgs); + if (extraArgsTag == Client.EVM_EXTRA_ARGS_V2_TAG) { + return abi.decode(extraArgs[4:], (Client.EVMExtraArgsV2)); + } else if (extraArgsTag == Client.EVM_EXTRA_ARGS_V1_TAG) { + // EVMExtraArgsV1 originally included a second boolean (strict) field which has been deprecated. + // Clients may still include it but it will be ignored. + return Client.EVMExtraArgsV2({gasLimit: abi.decode(extraArgs[4:], (uint256)), allowOutOfOrderExecution: false}); + } + + revert InvalidExtraArgsTag(); + } + + /// @notice Validate the forwarded message with various checks. + /// @dev This function can be called multiple times during a CCIPSend, + /// only common user-driven mistakes are validated here to minimize duplicate validation cost. + /// @param dataLength The length of the data field of the message. + /// @param gasLimit The gasLimit set in message for destination execution. + /// @param numberOfTokens The number of tokens to be sent. + function _validateMessage( + uint256 dataLength, + uint256 gasLimit, + uint256 numberOfTokens, + bool allowOutOfOrderExecution + ) internal view { + uint256 maxDataBytes = uint256(s_dynamicConfig.maxDataBytes); + if (dataLength > maxDataBytes) revert MessageTooLarge(maxDataBytes, dataLength); + if (gasLimit > uint256(s_dynamicConfig.maxPerMsgGasLimit)) revert MessageGasLimitTooHigh(); + if (numberOfTokens > uint256(s_dynamicConfig.maxNumberOfTokensPerMsg)) revert UnsupportedNumberOfTokens(); + if (!allowOutOfOrderExecution) { + if (s_dynamicConfig.enforceOutOfOrder) { + revert ExtraArgOutOfOrderExecutionMustBeTrue(); + } + } + } + + // ================================================================ + // │ Config │ + // ================================================================ + + /// @notice Returns the static onRamp config. + /// @dev RMN depends on this function, if changing, please notify the RMN maintainers. + /// @return the configuration. + function getStaticConfig() external view returns (StaticConfig memory) { + return StaticConfig({ + linkToken: i_linkToken, + chainSelector: i_chainSelector, + destChainSelector: i_destChainSelector, + defaultTxGasLimit: i_defaultTxGasLimit, + maxNopFeesJuels: i_maxNopFeesJuels, + prevOnRamp: i_prevOnRamp, + rmnProxy: i_rmnProxy, + tokenAdminRegistry: i_tokenAdminRegistry + }); + } + + /// @notice Returns the dynamic onRamp config. + /// @return dynamicConfig the configuration. + function getDynamicConfig() external view returns (DynamicConfig memory dynamicConfig) { + return s_dynamicConfig; + } + + /// @notice Sets the dynamic configuration. + /// @param dynamicConfig The configuration. + function setDynamicConfig(DynamicConfig memory dynamicConfig) external onlyOwner { + _setDynamicConfig(dynamicConfig); + } + + /// @notice Internal version of setDynamicConfig to allow for reuse in the constructor. + function _setDynamicConfig(DynamicConfig memory dynamicConfig) internal { + // We permit router to be set to zero as a way to pause the contract. + if (dynamicConfig.priceRegistry == address(0)) revert InvalidConfig(); + if (dynamicConfig.defaultTokenDestBytesOverhead < Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) { + revert InvalidDestBytesOverhead(address(0), dynamicConfig.defaultTokenDestBytesOverhead); + } + + s_dynamicConfig = dynamicConfig; + + emit ConfigSet( + StaticConfig({ + linkToken: i_linkToken, + chainSelector: i_chainSelector, + destChainSelector: i_destChainSelector, + defaultTxGasLimit: i_defaultTxGasLimit, + maxNopFeesJuels: i_maxNopFeesJuels, + prevOnRamp: i_prevOnRamp, + rmnProxy: i_rmnProxy, + tokenAdminRegistry: i_tokenAdminRegistry + }), + dynamicConfig + ); + } + + // ================================================================ + // │ Tokens and pools │ + // ================================================================ + + /// @inheritdoc IEVM2AnyOnRampClient + function getPoolBySourceToken(uint64, /*destChainSelector*/ IERC20 sourceToken) public view returns (IPoolV1) { + return IPoolV1(ITokenAdminRegistry(i_tokenAdminRegistry).getPool(address(sourceToken))); + } + + /// @inheritdoc IEVM2AnyOnRampClient + function getSupportedTokens(uint64) external pure returns (address[] memory) { + revert GetSupportedTokensFunctionalityRemovedCheckAdminRegistry(); + } + + // ================================================================ + // │ Fees │ + // ================================================================ + + /// @inheritdoc IEVM2AnyOnRampClient + /// @dev getFee MUST revert if the feeToken is not listed in the fee token config, as the router assumes it does. + /// @param destChainSelector The destination chain selector. + /// @param message The message to get quote for. + /// @return feeTokenAmount The amount of fee token needed for the fee, in smallest denomination of the fee token. + function getFee( + uint64 destChainSelector, + Client.EVM2AnyMessage calldata message + ) external view returns (uint256 feeTokenAmount) { + if (destChainSelector != i_destChainSelector) revert InvalidChainSelector(destChainSelector); + + Client.EVMExtraArgsV2 memory extraArgs = _fromBytes(message.extraArgs); + // Validate the message with various checks + _validateMessage( + message.data.length, extraArgs.gasLimit, message.tokenAmounts.length, extraArgs.allowOutOfOrderExecution + ); + + FeeTokenConfig memory feeTokenConfig = s_feeTokenConfig[message.feeToken]; + if (!feeTokenConfig.enabled) revert NotAFeeToken(message.feeToken); + + (uint224 feeTokenPrice, uint224 packedGasPrice) = + IPriceRegistry(s_dynamicConfig.priceRegistry).getTokenAndGasPrices(message.feeToken, destChainSelector); + + // Calculate premiumFee in USD with 18 decimals precision first. + // If message-only and no token transfers, a flat network fee is charged. + // If there are token transfers, premiumFee is calculated from token transfer fee. + // If there are both token transfers and message, premiumFee is only calculated from token transfer fee. + uint256 premiumFee = 0; + uint32 tokenTransferGas = 0; + uint32 tokenTransferBytesOverhead = 0; + if (message.tokenAmounts.length > 0) { + (premiumFee, tokenTransferGas, tokenTransferBytesOverhead) = + _getTokenTransferCost(message.feeToken, feeTokenPrice, message.tokenAmounts); + } else { + // Convert USD cents with 2 decimals to 18 decimals. + premiumFee = uint256(feeTokenConfig.networkFeeUSDCents) * 1e16; + } + + // Calculate data availability cost in USD with 36 decimals. Data availability cost exists on rollups that need to post + // transaction calldata onto another storage layer, e.g. Eth mainnet, incurring additional storage gas costs. + uint256 dataAvailabilityCost = 0; + // Only calculate data availability cost if data availability multiplier is non-zero. + // The multiplier should be set to 0 if destination chain does not charge data availability cost. + if (s_dynamicConfig.destDataAvailabilityMultiplierBps > 0) { + dataAvailabilityCost = _getDataAvailabilityCost( + // Parse the data availability gas price stored in the higher-order 112 bits of the encoded gas price. + uint112(packedGasPrice >> Internal.GAS_PRICE_BITS), + message.data.length, + message.tokenAmounts.length, + tokenTransferBytesOverhead + ); + } + + // Calculate execution gas fee on destination chain in USD with 36 decimals. + // We add the message gas limit, the overhead gas, the gas of passing message data to receiver, and token transfer gas together. + // We then multiply this gas total with the gas multiplier and gas price, converting it into USD with 36 decimals. + // uint112(packedGasPrice) = executionGasPrice + uint256 executionCost = uint112(packedGasPrice) + * ( + extraArgs.gasLimit + s_dynamicConfig.destGasOverhead + + (message.data.length * s_dynamicConfig.destGasPerPayloadByte) + tokenTransferGas + ) * feeTokenConfig.gasMultiplierWeiPerEth; + + // Calculate number of fee tokens to charge. + // Total USD fee is in 36 decimals, feeTokenPrice is in 18 decimals USD for 1e18 smallest token denominations. + // Result of the division is the number of smallest token denominations. + return + ((premiumFee * feeTokenConfig.premiumMultiplierWeiPerEth) + executionCost + dataAvailabilityCost) / feeTokenPrice; + } + + /// @notice Returns the estimated data availability cost of the message. + /// @dev To save on gas, we use a single destGasPerDataAvailabilityByte value for both zero and non-zero bytes. + /// @param dataAvailabilityGasPrice USD per data availability gas in 18 decimals. + /// @param messageDataLength length of the data field in the message. + /// @param numberOfTokens number of distinct token transfers in the message. + /// @param tokenTransferBytesOverhead additional token transfer data passed to destination, e.g. USDC attestation. + /// @return dataAvailabilityCostUSD36Decimal total data availability cost in USD with 36 decimals. + function _getDataAvailabilityCost( + uint112 dataAvailabilityGasPrice, + uint256 messageDataLength, + uint256 numberOfTokens, + uint32 tokenTransferBytesOverhead + ) internal view returns (uint256 dataAvailabilityCostUSD36Decimal) { + // dataAvailabilityLengthBytes sums up byte lengths of fixed message fields and dynamic message fields. + // Fixed message fields do account for the offset and length slot of the dynamic fields. + uint256 dataAvailabilityLengthBytes = Internal.MESSAGE_FIXED_BYTES + messageDataLength + + (numberOfTokens * Internal.MESSAGE_FIXED_BYTES_PER_TOKEN) + tokenTransferBytesOverhead; + + // destDataAvailabilityOverheadGas is a separate config value for flexibility to be updated independently of message cost. + // Its value is determined by CCIP lane implementation, e.g. the overhead data posted for OCR. + uint256 dataAvailabilityGas = (dataAvailabilityLengthBytes * s_dynamicConfig.destGasPerDataAvailabilityByte) + + s_dynamicConfig.destDataAvailabilityOverheadGas; + + // dataAvailabilityGasPrice is in 18 decimals, destDataAvailabilityMultiplierBps is in 4 decimals + // We pad 14 decimals to bring the result to 36 decimals, in line with token bps and execution fee. + return ((dataAvailabilityGas * dataAvailabilityGasPrice) * s_dynamicConfig.destDataAvailabilityMultiplierBps) * 1e14; + } + + /// @notice Returns the token transfer cost parameters. + /// A basis point fee is calculated from the USD value of each token transfer. + /// For each individual transfer, this fee is between [minFeeUSD, maxFeeUSD]. + /// Total transfer fee is the sum of each individual token transfer fee. + /// @dev Assumes that tokenAmounts are validated to be listed tokens elsewhere. + /// @dev Splitting one token transfer into multiple transfers is discouraged, + /// as it will result in a transferFee equal or greater than the same amount aggregated/de-duped. + /// @param feeToken address of the feeToken. + /// @param feeTokenPrice price of feeToken in USD with 18 decimals. + /// @param tokenAmounts token transfers in the message. + /// @return tokenTransferFeeUSDWei total token transfer bps fee in USD with 18 decimals. + /// @return tokenTransferGas total execution gas of the token transfers. + /// @return tokenTransferBytesOverhead additional token transfer data passed to destination, e.g. USDC attestation. + function _getTokenTransferCost( + address feeToken, + uint224 feeTokenPrice, + Client.EVMTokenAmount[] calldata tokenAmounts + ) internal view returns (uint256 tokenTransferFeeUSDWei, uint32 tokenTransferGas, uint32 tokenTransferBytesOverhead) { + uint256 numberOfTokens = tokenAmounts.length; + + for (uint256 i = 0; i < numberOfTokens; ++i) { + Client.EVMTokenAmount memory tokenAmount = tokenAmounts[i]; + + // Validate if the token is supported, do not calculate fee for unsupported tokens. + if (address(getPoolBySourceToken(i_destChainSelector, IERC20(tokenAmount.token))) == address(0)) { + revert UnsupportedToken(tokenAmount.token); + } + + TokenTransferFeeConfig memory transferFeeConfig = s_tokenTransferFeeConfig[tokenAmount.token]; + + // If the token has no specific overrides configured, we use the global defaults. + if (!transferFeeConfig.isEnabled) { + tokenTransferFeeUSDWei += uint256(s_dynamicConfig.defaultTokenFeeUSDCents) * 1e16; + tokenTransferGas += s_dynamicConfig.defaultTokenDestGasOverhead; + tokenTransferBytesOverhead += s_dynamicConfig.defaultTokenDestBytesOverhead; + continue; + } + + uint256 bpsFeeUSDWei = 0; + // Only calculate bps fee if ratio is greater than 0. Ratio of 0 means no bps fee for a token. + // Useful for when the PriceRegistry cannot return a valid price for the token. + if (transferFeeConfig.deciBps > 0) { + uint224 tokenPrice = 0; + if (tokenAmount.token != feeToken) { + tokenPrice = IPriceRegistry(s_dynamicConfig.priceRegistry).getValidatedTokenPrice(tokenAmount.token); + } else { + tokenPrice = feeTokenPrice; + } + + // Calculate token transfer value, then apply fee ratio + // ratio represents multiples of 0.1bps, or 1e-5 + bpsFeeUSDWei = (tokenPrice._calcUSDValueFromTokenAmount(tokenAmount.amount) * transferFeeConfig.deciBps) / 1e5; + } + + tokenTransferGas += transferFeeConfig.destGasOverhead; + tokenTransferBytesOverhead += transferFeeConfig.destBytesOverhead; + + // Bps fees should be kept within range of [minFeeUSD, maxFeeUSD]. + // Convert USD values with 2 decimals to 18 decimals. + uint256 minFeeUSDWei = uint256(transferFeeConfig.minFeeUSDCents) * 1e16; + if (bpsFeeUSDWei < minFeeUSDWei) { + tokenTransferFeeUSDWei += minFeeUSDWei; + continue; + } + + uint256 maxFeeUSDWei = uint256(transferFeeConfig.maxFeeUSDCents) * 1e16; + if (bpsFeeUSDWei > maxFeeUSDWei) { + tokenTransferFeeUSDWei += maxFeeUSDWei; + continue; + } + + tokenTransferFeeUSDWei += bpsFeeUSDWei; + } + + return (tokenTransferFeeUSDWei, tokenTransferGas, tokenTransferBytesOverhead); + } + + /// @notice Gets the fee configuration for a token + /// @param token The token to get the fee configuration for + /// @return feeTokenConfig FeeTokenConfig struct + function getFeeTokenConfig(address token) external view returns (FeeTokenConfig memory feeTokenConfig) { + return s_feeTokenConfig[token]; + } + + /// @notice Sets the fee configuration for a token + /// @param feeTokenConfigArgs Array of FeeTokenConfigArgs structs. + function setFeeTokenConfig(FeeTokenConfigArgs[] memory feeTokenConfigArgs) external { + _onlyOwnerOrAdmin(); + _setFeeTokenConfig(feeTokenConfigArgs); + } + + /// @dev Set the fee config + /// @param feeTokenConfigArgs The fee token configs. + function _setFeeTokenConfig(FeeTokenConfigArgs[] memory feeTokenConfigArgs) internal { + for (uint256 i = 0; i < feeTokenConfigArgs.length; ++i) { + FeeTokenConfigArgs memory configArg = feeTokenConfigArgs[i]; + + s_feeTokenConfig[configArg.token] = FeeTokenConfig({ + networkFeeUSDCents: configArg.networkFeeUSDCents, + gasMultiplierWeiPerEth: configArg.gasMultiplierWeiPerEth, + premiumMultiplierWeiPerEth: configArg.premiumMultiplierWeiPerEth, + enabled: configArg.enabled + }); + } + emit FeeConfigSet(feeTokenConfigArgs); + } + + /// @notice Gets the transfer fee config for a given token. + function getTokenTransferFeeConfig(address token) + external + view + returns (TokenTransferFeeConfig memory tokenTransferFeeConfig) + { + return s_tokenTransferFeeConfig[token]; + } + + /// @notice Sets the transfer fee config. + /// @dev only callable by the owner or admin. + function setTokenTransferFeeConfig( + TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs, + address[] memory tokensToUseDefaultFeeConfigs + ) external { + _onlyOwnerOrAdmin(); + _setTokenTransferFeeConfig(tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs); + } + + /// @notice internal helper to set the token transfer fee config. + function _setTokenTransferFeeConfig( + TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs, + address[] memory tokensToUseDefaultFeeConfigs + ) internal { + for (uint256 i = 0; i < tokenTransferFeeConfigArgs.length; ++i) { + TokenTransferFeeConfigArgs memory configArg = tokenTransferFeeConfigArgs[i]; + + if (configArg.destBytesOverhead < Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) { + revert InvalidDestBytesOverhead(configArg.token, configArg.destBytesOverhead); + } + + s_tokenTransferFeeConfig[configArg.token] = TokenTransferFeeConfig({ + minFeeUSDCents: configArg.minFeeUSDCents, + maxFeeUSDCents: configArg.maxFeeUSDCents, + deciBps: configArg.deciBps, + destGasOverhead: configArg.destGasOverhead, + destBytesOverhead: configArg.destBytesOverhead, + aggregateRateLimitEnabled: configArg.aggregateRateLimitEnabled, + isEnabled: true + }); + } + emit TokenTransferFeeConfigSet(tokenTransferFeeConfigArgs); + + // Remove the custom fee configs for the tokens that are in the tokensToUseDefaultFeeConfigs array + for (uint256 i = 0; i < tokensToUseDefaultFeeConfigs.length; ++i) { + delete s_tokenTransferFeeConfig[tokensToUseDefaultFeeConfigs[i]]; + } + if (tokensToUseDefaultFeeConfigs.length > 0) { + emit TokenTransferFeeConfigDeleted(tokensToUseDefaultFeeConfigs); + } + } + + // ================================================================ + // │ NOP payments │ + // ================================================================ + + /// @notice Get the total amount of fees to be paid to the Nops (in LINK) + /// @return totalNopFees + function getNopFeesJuels() external view returns (uint96) { + return s_nopFeesJuels; + } + + /// @notice Gets the Nops and their weights + /// @return nopsAndWeights Array of NopAndWeight structs + /// @return weightsTotal The sum weight of all Nops + function getNops() external view returns (NopAndWeight[] memory nopsAndWeights, uint256 weightsTotal) { + uint256 length = s_nops.length(); + nopsAndWeights = new NopAndWeight[](length); + for (uint256 i = 0; i < length; ++i) { + (address nopAddress, uint256 nopWeight) = s_nops.at(i); + nopsAndWeights[i] = NopAndWeight({nop: nopAddress, weight: uint16(nopWeight)}); + } + weightsTotal = s_nopWeightsTotal; + return (nopsAndWeights, weightsTotal); + } + + /// @notice Sets the Nops and their weights + /// @param nopsAndWeights Array of NopAndWeight structs + function setNops(NopAndWeight[] calldata nopsAndWeights) external { + _onlyOwnerOrAdmin(); + _setNops(nopsAndWeights); + } + + /// @param nopsAndWeights New set of nops and weights + /// @dev Clears existing nops, sets new nops and weights + /// @dev We permit fees to accrue before nops are configured, in which case + /// they will go to the first set of configured nops. + function _setNops(NopAndWeight[] memory nopsAndWeights) internal { + uint256 numberOfNops = nopsAndWeights.length; + if (numberOfNops > MAX_NUMBER_OF_NOPS) revert TooManyNops(); + + // Make sure all nops have been paid before removing nops + // We only have to pay when there are nops and there is enough + // outstanding NOP balance to trigger a payment. + if (s_nopWeightsTotal > 0) { + if (s_nopFeesJuels >= s_nopWeightsTotal) { + payNops(); + } + } + + // Remove all previous nops, move from end to start to avoid shifting + for (uint256 i = s_nops.length(); i > 0; --i) { + (address nop,) = s_nops.at(i - 1); + s_nops.remove(nop); + } + + // Add new + uint32 nopWeightsTotal = 0; + // nopWeightsTotal is bounded by the MAX_NUMBER_OF_NOPS and the weight of + // a single nop being of type uint16. This ensures nopWeightsTotal will + // always fit into the uint32 type. + for (uint256 i = 0; i < numberOfNops; ++i) { + // Make sure the LINK token is not a nop because the link token doesn't allow + // self transfers. If set as nop, payNops would always revert. Since setNops + // calls payNops, we can never remove the LINK token as a nop. + address nop = nopsAndWeights[i].nop; + uint16 weight = nopsAndWeights[i].weight; + if (nop == i_linkToken || nop == address(0)) revert InvalidNopAddress(nop); + s_nops.set(nop, weight); + nopWeightsTotal += weight; + } + s_nopWeightsTotal = nopWeightsTotal; + emit NopsSet(nopWeightsTotal, nopsAndWeights); + } + + /// @notice Pays the Node Ops their outstanding balances. + /// @dev some balance can remain after payments are done. This is at most the sum + /// of the weight of all nops. Since nop weights are uint16s and we can have at + /// most MAX_NUMBER_OF_NOPS NOPs, the highest possible value is 2**22 or 0.04 gjuels. + function payNops() public { + if (msg.sender != owner()) { + if (msg.sender != s_admin) { + if (!s_nops.contains(msg.sender)) { + revert OnlyCallableByOwnerOrAdminOrNop(); + } + } + } + uint256 weightsTotal = s_nopWeightsTotal; + if (weightsTotal == 0) revert NoNopsToPay(); + + uint96 totalFeesToPay = s_nopFeesJuels; + if (totalFeesToPay < weightsTotal) revert NoFeesToPay(); + if (linkAvailableForPayment() < 0) revert InsufficientBalance(); + + uint96 fundsLeft = totalFeesToPay; + uint256 numberOfNops = s_nops.length(); + for (uint256 i = 0; i < numberOfNops; ++i) { + (address nop, uint256 weight) = s_nops.at(i); + // amount can never be higher than totalFeesToPay so the cast to uint96 is safe + uint96 amount = uint96((totalFeesToPay * weight) / weightsTotal); + fundsLeft -= amount; + IERC20(i_linkToken).safeTransfer(nop, amount); + emit NopPaid(nop, amount); + } + // Some funds can remain, since this is an incredibly small + // amount we consider this OK. + s_nopFeesJuels = fundsLeft; + } + + /// @notice Allows the owner to withdraw any ERC20 token from the contract. + /// The NOP link balance is not withdrawable. + /// @param feeToken The token to withdraw + /// @param to The address to send the tokens to + function withdrawNonLinkFees(address feeToken, address to) external { + _onlyOwnerOrAdmin(); + if (to == address(0)) revert InvalidWithdrawParams(); + + // We require the link balance to be settled before allowing withdrawal of non-link fees. + int256 linkAfterNopFees = linkAvailableForPayment(); + if (linkAfterNopFees < 0) revert LinkBalanceNotSettled(); + + if (feeToken == i_linkToken) { + // Withdraw only the left over link balance + IERC20(feeToken).safeTransfer(to, uint256(linkAfterNopFees)); + } else { + // Withdrawal all non-link tokens in the contract + IERC20(feeToken).safeTransfer(to, IERC20(feeToken).balanceOf(address(this))); + } + } + + // ================================================================ + // │ Link monitoring │ + // ================================================================ + + /// @notice Calculate remaining LINK balance after paying nops + /// @dev Allow keeper to monitor funds available for paying nops + /// @return balance if nops were to be paid + function linkAvailableForPayment() public view returns (int256) { + // Since LINK caps at uint96, casting to int256 is safe + return int256(IERC20(i_linkToken).balanceOf(address(this))) - int256(uint256(s_nopFeesJuels)); + } + + // ================================================================ + // │ Access │ + // ================================================================ + + /// @dev Require that the sender is the owner or the fee admin + /// Not a modifier to save on contract size + function _onlyOwnerOrAdmin() internal view { + if (msg.sender != owner()) { + if (msg.sender != s_admin) { + revert OnlyCallableByOwnerOrAdmin(); + } + } + } +} diff --git a/contracts/src/v0.8/ccip/pools/BurnFromMintTokenPool.sol b/contracts/src/v0.8/ccip/pools/BurnFromMintTokenPool.sol new file mode 100644 index 0000000000..de68b18a30 --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/BurnFromMintTokenPool.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IBurnMintERC20} from "../../shared/token/ERC20/IBurnMintERC20.sol"; + +import {BurnMintTokenPoolAbstract} from "./BurnMintTokenPoolAbstract.sol"; +import {TokenPool} from "./TokenPool.sol"; + +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +/// @notice This pool mints and burns a 3rd-party token. +/// @dev Pool whitelisting mode is set in the constructor and cannot be modified later. +/// It either accepts any address as originalSender, or only accepts whitelisted originalSender. +/// The only way to change whitelisting mode is to deploy a new pool. +/// If that is expected, please make sure the token's burner/minter roles are adjustable. +/// @dev This contract is a variant of BurnMintTokenPool that uses `burnFrom(from, amount)`. +contract BurnFromMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion { + using SafeERC20 for IBurnMintERC20; + + string public constant override typeAndVersion = "BurnFromMintTokenPool 1.5.0-dev"; + + constructor( + IBurnMintERC20 token, + address[] memory allowlist, + address rmnProxy, + address router + ) TokenPool(token, allowlist, rmnProxy, router) { + // Some tokens allow burning from the sender without approval, but not all do. + // To be safe, we approve the pool to burn from the pool. + token.safeIncreaseAllowance(address(this), type(uint256).max); + } + + /// @inheritdoc BurnMintTokenPoolAbstract + function _burn(uint256 amount) internal virtual override { + IBurnMintERC20(address(i_token)).burnFrom(address(this), amount); + } +} diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol new file mode 100644 index 0000000000..a8562ae4d3 --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IBurnMintERC20} from "../../shared/token/ERC20/IBurnMintERC20.sol"; + +import {BurnMintTokenPoolAbstract} from "./BurnMintTokenPoolAbstract.sol"; +import {TokenPool} from "./TokenPool.sol"; + +/// @notice This pool mints and burns a 3rd-party token. +/// @dev Pool whitelisting mode is set in the constructor and cannot be modified later. +/// It either accepts any address as originalSender, or only accepts whitelisted originalSender. +/// The only way to change whitelisting mode is to deploy a new pool. +/// If that is expected, please make sure the token's burner/minter roles are adjustable. +/// @dev This contract is a variant of BurnMintTokenPool that uses `burn(amount)`. +contract BurnMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion { + string public constant override typeAndVersion = "BurnMintTokenPool 1.5.0-dev"; + + constructor( + IBurnMintERC20 token, + address[] memory allowlist, + address rmnProxy, + address router + ) TokenPool(token, allowlist, rmnProxy, router) {} + + /// @inheritdoc BurnMintTokenPoolAbstract + function _burn(uint256 amount) internal virtual override { + IBurnMintERC20(address(i_token)).burn(amount); + } +} diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol new file mode 100644 index 0000000000..2085c9427b --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IBurnMintERC20} from "../../shared/token/ERC20/IBurnMintERC20.sol"; + +import {Pool} from "../libraries/Pool.sol"; +import {TokenPool} from "./TokenPool.sol"; + +abstract contract BurnMintTokenPoolAbstract is TokenPool { + /// @notice Contains the specific burn call for a pool. + /// @dev overriding this method allows us to create pools with different burn signatures + /// without duplicating the underlying logic. + function _burn(uint256 amount) internal virtual; + + /// @notice Burn the token in the pool + /// @dev The _validateLockOrBurn check is an essential security check + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + external + virtual + override + returns (Pool.LockOrBurnOutV1 memory) + { + _validateLockOrBurn(lockOrBurnIn); + + _burn(lockOrBurnIn.amount); + + emit Burned(msg.sender, lockOrBurnIn.amount); + + return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); + } + + /// @notice Mint tokens from the pool to the recipient + /// @dev The _validateReleaseOrMint check is an essential security check + function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + external + virtual + override + returns (Pool.ReleaseOrMintOutV1 memory) + { + _validateReleaseOrMint(releaseOrMintIn); + + // Mint to the offRamp, which forwards it to the recipient + IBurnMintERC20(address(i_token)).mint(msg.sender, releaseOrMintIn.amount); + + emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); + + return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + } +} diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol new file mode 100644 index 0000000000..a3a7e082cc --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IBurnMintERC20} from "../../shared/token/ERC20/IBurnMintERC20.sol"; + +import {Pool} from "../libraries/Pool.sol"; +import {LegacyPoolWrapper} from "./LegacyPoolWrapper.sol"; + +contract BurnMintTokenPoolAndProxy is ITypeAndVersion, LegacyPoolWrapper { + string public constant override typeAndVersion = "BurnMintTokenPoolAndProxy 1.5.0-dev"; + + constructor( + IBurnMintERC20 token, + address[] memory allowlist, + address rmnProxy, + address router + ) LegacyPoolWrapper(token, allowlist, rmnProxy, router) {} + + /// @notice Burn the token in the pool + /// @dev The _validateLockOrBurn check is an essential security check + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + external + virtual + override + returns (Pool.LockOrBurnOutV1 memory) + { + _validateLockOrBurn(lockOrBurnIn); + + if (!_hasLegacyPool()) { + IBurnMintERC20(address(i_token)).burn(lockOrBurnIn.amount); + } else { + _lockOrBurnLegacy(lockOrBurnIn); + } + + emit Burned(msg.sender, lockOrBurnIn.amount); + + return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); + } + + /// @notice Mint tokens from the pool to the recipient + /// @dev The _validateReleaseOrMint check is an essential security check + function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + external + virtual + override + returns (Pool.ReleaseOrMintOutV1 memory) + { + _validateReleaseOrMint(releaseOrMintIn); + + if (!_hasLegacyPool()) { + // Mint to the offRamp, which forwards it to the recipient + IBurnMintERC20(address(i_token)).mint(msg.sender, releaseOrMintIn.amount); + } else { + _releaseOrMintLegacy(releaseOrMintIn); + } + + emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); + + return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + } +} diff --git a/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol b/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol new file mode 100644 index 0000000000..33f6c43c5b --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IBurnMintERC20} from "../../shared/token/ERC20/IBurnMintERC20.sol"; + +import {BurnMintTokenPoolAbstract} from "./BurnMintTokenPoolAbstract.sol"; +import {TokenPool} from "./TokenPool.sol"; + +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +/// @notice This pool mints and burns a 3rd-party token. +/// @dev Pool whitelisting mode is set in the constructor and cannot be modified later. +/// It either accepts any address as originalSender, or only accepts whitelisted originalSender. +/// The only way to change whitelisting mode is to deploy a new pool. +/// If that is expected, please make sure the token's burner/minter roles are adjustable. +/// @dev This contract is a variant of BurnMintTokenPool that uses `burn(from, amount)`. +contract BurnWithFromMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion { + using SafeERC20 for IBurnMintERC20; + + string public constant override typeAndVersion = "BurnWithFromMintTokenPool 1.5.0-dev"; + + constructor( + IBurnMintERC20 token, + address[] memory allowlist, + address rmnProxy, + address router + ) TokenPool(token, allowlist, rmnProxy, router) { + // Some tokens allow burning from the sender without approval, but not all do. + // To be safe, we approve the pool to burn from the pool. + token.safeIncreaseAllowance(address(this), type(uint256).max); + } + + /// @inheritdoc BurnMintTokenPoolAbstract + function _burn(uint256 amount) internal virtual override { + IBurnMintERC20(address(i_token)).burn(address(this), amount); + } +} diff --git a/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol b/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol new file mode 100644 index 0000000000..125a3a28ee --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {IPoolPriorTo1_5} from "../interfaces/IPoolPriorTo1_5.sol"; + +import {Pool} from "../libraries/Pool.sol"; +import {TokenPool} from "./TokenPool.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +abstract contract LegacyPoolWrapper is TokenPool { + using SafeERC20 for IERC20; + + event LegacyPoolChanged(IPoolPriorTo1_5 oldPool, IPoolPriorTo1_5 newPool); + + /// @dev The previous pool, if there is any. This is a property to make the older 1.0-1.4 pools + /// compatible with the current 1.5 pool. To achieve this, we set the previous pool address to the + /// currently deployed legacy pool. Then we configure this new pool as onRamp and offRamp on the legacy pools. + /// In the case of a 1.4 pool, this new pool contract has to be set to the Router as well, as it validates + /// who can call it through the router calls. This contract will always return itself as the only allowed ramp. + /// @dev Can be address(0), this would indicate that this pool is operating as a normal pool as opposed to + /// a proxy pool. + IPoolPriorTo1_5 internal s_previousPool; + + constructor( + IERC20 token, + address[] memory allowlist, + address rmnProxy, + address router + ) TokenPool(token, allowlist, rmnProxy, router) {} + + // ================================================================ + // │ Legacy Fallbacks │ + // ================================================================ + // Legacy fallbacks for older token pools that do not implement the new interface. + + /// @notice Legacy fallback for the 1.4 token pools. + function getOnRamp(uint64) external view returns (address onRampAddress) { + return address(this); + } + + /// @notice Return true if the given offRamp is a configured offRamp for the given source chain. + function isOffRamp(uint64 sourceChainSelector, address offRamp) external view returns (bool) { + return offRamp == address(this) || s_router.isOffRamp(sourceChainSelector, offRamp); + } + + /// @notice Configures the legacy fallback option. If the previous pool is set, this pool will act as a proxy for + /// the legacy pool. + /// @param prevPool The address of the previous pool. + function setPreviousPool(IPoolPriorTo1_5 prevPool) external onlyOwner { + IPoolPriorTo1_5 oldPrevPool = s_previousPool; + s_previousPool = prevPool; + + emit LegacyPoolChanged(oldPrevPool, prevPool); + } + + function _hasLegacyPool() internal view returns (bool) { + return address(s_previousPool) != address(0); + } + + function _lockOrBurnLegacy(Pool.LockOrBurnInV1 memory lockOrBurnIn) internal { + i_token.safeTransfer(address(s_previousPool), lockOrBurnIn.amount); + s_previousPool.lockOrBurn( + lockOrBurnIn.originalSender, lockOrBurnIn.receiver, lockOrBurnIn.amount, lockOrBurnIn.remoteChainSelector, "" + ); + } + + /// @notice This call converts the arguments from a >=1.5 pool call to those of a <1.5 pool call, and uses these + /// to call the previous pool. + /// @param releaseOrMintIn The 1.5 style release or mint arguments. + /// @dev Overwrites the receiver so the previous pool sends the tokens to the sender of this call, which is the + /// offRamp. This is due to the older pools sending funds directly to the receiver, while the new pools do a hop + /// through the offRamp to ensure the correct tokens are sent. + /// @dev Since extraData has never been used in LockRelease or MintBurn token pools, we can safely ignore it. + function _releaseOrMintLegacy(Pool.ReleaseOrMintInV1 memory releaseOrMintIn) internal { + s_previousPool.releaseOrMint( + releaseOrMintIn.originalSender, msg.sender, releaseOrMintIn.amount, releaseOrMintIn.remoteChainSelector, "" + ); + } +} diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol new file mode 100644 index 0000000000..5716777fb5 --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ILiquidityContainer} from "../../liquiditymanager/interfaces/ILiquidityContainer.sol"; +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; + +import {Pool} from "../libraries/Pool.sol"; +import {RateLimiter} from "../libraries/RateLimiter.sol"; +import {TokenPool} from "./TokenPool.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +/// @notice Token pool used for tokens on their native chain. This uses a lock and release mechanism. +/// Because of lock/unlock requiring liquidity, this pool contract also has function to add and remove +/// liquidity. This allows for proper bookkeeping for both user and liquidity provider balances. +/// @dev One token per LockReleaseTokenPool. +contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion { + using SafeERC20 for IERC20; + + error InsufficientLiquidity(); + error LiquidityNotAccepted(); + error Unauthorized(address caller); + + string public constant override typeAndVersion = "LockReleaseTokenPool 1.5.0-dev"; + + /// @dev Whether or not the pool accepts liquidity. + /// External liquidity is not required when there is one canonical token deployed to a chain, + /// and CCIP is facilitating mint/burn on all the other chains, in which case the invariant + /// balanceOf(pool) on home chain == sum(totalSupply(mint/burn "wrapped" token) on all remote chains) should always hold + bool internal immutable i_acceptLiquidity; + /// @notice The address of the rebalancer. + address internal s_rebalancer; + /// @notice The address of the rate limiter admin. + /// @dev Can be address(0) if none is configured. + address internal s_rateLimitAdmin; + + constructor( + IERC20 token, + address[] memory allowlist, + address rmnProxy, + bool acceptLiquidity, + address router + ) TokenPool(token, allowlist, rmnProxy, router) { + i_acceptLiquidity = acceptLiquidity; + } + + /// @notice Locks the token in the pool + /// @dev The _validateLockOrBurn check is an essential security check + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + external + virtual + override + returns (Pool.LockOrBurnOutV1 memory) + { + _validateLockOrBurn(lockOrBurnIn); + + emit Locked(msg.sender, lockOrBurnIn.amount); + + return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); + } + + /// @notice Release tokens from the pool to the recipient + /// @dev The _validateReleaseOrMint check is an essential security check + function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + external + virtual + override + returns (Pool.ReleaseOrMintOutV1 memory) + { + _validateReleaseOrMint(releaseOrMintIn); + + // Release to the offRamp, which forwards it to the recipient + getToken().safeTransfer(msg.sender, releaseOrMintIn.amount); + + emit Released(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); + + return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + } + + // @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) { + return interfaceId == type(ILiquidityContainer).interfaceId || super.supportsInterface(interfaceId); + } + + /// @notice Gets LiquidityManager, can be address(0) if none is configured. + /// @return The current liquidity manager. + function getRebalancer() external view returns (address) { + return s_rebalancer; + } + + /// @notice Sets the LiquidityManager address. + /// @dev Only callable by the owner. + function setRebalancer(address rebalancer) external onlyOwner { + s_rebalancer = rebalancer; + } + + /// @notice Sets the rate limiter admin address. + /// @dev Only callable by the owner. + /// @param rateLimitAdmin The new rate limiter admin address. + function setRateLimitAdmin(address rateLimitAdmin) external onlyOwner { + s_rateLimitAdmin = rateLimitAdmin; + } + + /// @notice Gets the rate limiter admin address. + function getRateLimitAdmin() external view returns (address) { + return s_rateLimitAdmin; + } + + /// @notice Checks if the pool can accept liquidity. + /// @return true if the pool can accept liquidity, false otherwise. + function canAcceptLiquidity() external view returns (bool) { + return i_acceptLiquidity; + } + + /// @notice Adds liquidity to the pool. The tokens should be approved first. + /// @param amount The amount of liquidity to provide. + function provideLiquidity(uint256 amount) external { + if (!i_acceptLiquidity) revert LiquidityNotAccepted(); + if (s_rebalancer != msg.sender) revert Unauthorized(msg.sender); + + i_token.safeTransferFrom(msg.sender, address(this), amount); + emit LiquidityAdded(msg.sender, amount); + } + + /// @notice Removed liquidity to the pool. The tokens will be sent to msg.sender. + /// @param amount The amount of liquidity to remove. + function withdrawLiquidity(uint256 amount) external { + if (s_rebalancer != msg.sender) revert Unauthorized(msg.sender); + + if (i_token.balanceOf(address(this)) < amount) revert InsufficientLiquidity(); + i_token.safeTransfer(msg.sender, amount); + emit LiquidityRemoved(msg.sender, amount); + } + + /// @notice Sets the rate limiter admin address. + /// @dev Only callable by the owner or the rate limiter admin. NOTE: overwrites the normal + /// onlyAdmin check in the base implementation to also allow the rate limiter admin. + /// @param remoteChainSelector The remote chain selector for which the rate limits apply. + /// @param outboundConfig The new outbound rate limiter config. + /// @param inboundConfig The new inbound rate limiter config. + function setChainRateLimiterConfig( + uint64 remoteChainSelector, + RateLimiter.Config memory outboundConfig, + RateLimiter.Config memory inboundConfig + ) external override { + if (msg.sender != s_rateLimitAdmin && msg.sender != owner()) revert Unauthorized(msg.sender); + + _setRateLimitConfig(remoteChainSelector, outboundConfig, inboundConfig); + } +} diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol new file mode 100644 index 0000000000..91766d5f26 --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ILiquidityContainer} from "../../liquiditymanager/interfaces/ILiquidityContainer.sol"; +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; + +import {Pool} from "../libraries/Pool.sol"; +import {RateLimiter} from "../libraries/RateLimiter.sol"; +import {LegacyPoolWrapper} from "./LegacyPoolWrapper.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +/// @notice Token pool used for tokens on their native chain. This uses a lock and release mechanism. +/// Because of lock/unlock requiring liquidity, this pool contract also has function to add and remove +/// liquidity. This allows for proper bookkeeping for both user and liquidity provider balances. +/// @dev One token per LockReleaseTokenPool. +contract LockReleaseTokenPoolAndProxy is LegacyPoolWrapper, ILiquidityContainer, ITypeAndVersion { + using SafeERC20 for IERC20; + + error InsufficientLiquidity(); + error LiquidityNotAccepted(); + error Unauthorized(address caller); + + string public constant override typeAndVersion = "LockReleaseTokenPoolAndProxy 1.5.0-dev"; + + /// @dev Whether or not the pool accepts liquidity. + /// External liquidity is not required when there is one canonical token deployed to a chain, + /// and CCIP is facilitating mint/burn on all the other chains, in which case the invariant + /// balanceOf(pool) on home chain == sum(totalSupply(mint/burn "wrapped" token) on all remote chains) should always hold + bool internal immutable i_acceptLiquidity; + /// @notice The address of the rebalancer. + address internal s_rebalancer; + /// @notice The address of the rate limiter admin. + /// @dev Can be address(0) if none is configured. + address internal s_rateLimitAdmin; + + constructor( + IERC20 token, + address[] memory allowlist, + address rmnProxy, + bool acceptLiquidity, + address router + ) LegacyPoolWrapper(token, allowlist, rmnProxy, router) { + i_acceptLiquidity = acceptLiquidity; + } + + /// @notice Locks the token in the pool + /// @dev The _validateLockOrBurn check is an essential security check + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + external + virtual + override + returns (Pool.LockOrBurnOutV1 memory) + { + _validateLockOrBurn(lockOrBurnIn); + + if (_hasLegacyPool()) { + _lockOrBurnLegacy(lockOrBurnIn); + } + + emit Locked(msg.sender, lockOrBurnIn.amount); + + return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); + } + + /// @notice Release tokens from the pool to the recipient + /// @dev The _validateReleaseOrMint check is an essential security check + function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + external + virtual + override + returns (Pool.ReleaseOrMintOutV1 memory) + { + _validateReleaseOrMint(releaseOrMintIn); + + if (!_hasLegacyPool()) { + // Release to the offRamp, which forwards it to the recipient + getToken().safeTransfer(msg.sender, releaseOrMintIn.amount); + } else { + _releaseOrMintLegacy(releaseOrMintIn); + } + + emit Released(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); + + return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + } + + // @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) { + return interfaceId == type(ILiquidityContainer).interfaceId || super.supportsInterface(interfaceId); + } + + /// @notice Gets LiquidityManager, can be address(0) if none is configured. + /// @return The current liquidity manager. + function getRebalancer() external view returns (address) { + return s_rebalancer; + } + + /// @notice Sets the LiquidityManager address. + /// @dev Only callable by the owner. + function setRebalancer(address rebalancer) external onlyOwner { + s_rebalancer = rebalancer; + } + + /// @notice Sets the rate limiter admin address. + /// @dev Only callable by the owner. + /// @param rateLimitAdmin The new rate limiter admin address. + function setRateLimitAdmin(address rateLimitAdmin) external onlyOwner { + s_rateLimitAdmin = rateLimitAdmin; + } + + /// @notice Gets the rate limiter admin address. + function getRateLimitAdmin() external view returns (address) { + return s_rateLimitAdmin; + } + + /// @notice Checks if the pool can accept liquidity. + /// @return true if the pool can accept liquidity, false otherwise. + function canAcceptLiquidity() external view returns (bool) { + return i_acceptLiquidity; + } + + /// @notice Adds liquidity to the pool. The tokens should be approved first. + /// @param amount The amount of liquidity to provide. + function provideLiquidity(uint256 amount) external { + if (!i_acceptLiquidity) revert LiquidityNotAccepted(); + if (s_rebalancer != msg.sender) revert Unauthorized(msg.sender); + + i_token.safeTransferFrom(msg.sender, address(this), amount); + emit LiquidityAdded(msg.sender, amount); + } + + /// @notice Removed liquidity to the pool. The tokens will be sent to msg.sender. + /// @param amount The amount of liquidity to remove. + function withdrawLiquidity(uint256 amount) external { + if (s_rebalancer != msg.sender) revert Unauthorized(msg.sender); + + if (i_token.balanceOf(address(this)) < amount) revert InsufficientLiquidity(); + i_token.safeTransfer(msg.sender, amount); + emit LiquidityRemoved(msg.sender, amount); + } + + /// @notice Sets the rate limiter admin address. + /// @dev Only callable by the owner or the rate limiter admin. NOTE: overwrites the normal + /// onlyAdmin check in the base implementation to also allow the rate limiter admin. + /// @param remoteChainSelector The remote chain selector for which the rate limits apply. + /// @param outboundConfig The new outbound rate limiter config. + /// @param inboundConfig The new inbound rate limiter config. + function setChainRateLimiterConfig( + uint64 remoteChainSelector, + RateLimiter.Config memory outboundConfig, + RateLimiter.Config memory inboundConfig + ) external override { + if (msg.sender != s_rateLimitAdmin && msg.sender != owner()) revert Unauthorized(msg.sender); + + _setRateLimitConfig(remoteChainSelector, outboundConfig, inboundConfig); + } +} diff --git a/contracts/src/v0.8/ccip/pools/TokenPool.sol b/contracts/src/v0.8/ccip/pools/TokenPool.sol new file mode 100644 index 0000000000..fb1f8c49e6 --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/TokenPool.sol @@ -0,0 +1,424 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IPoolV1} from "../interfaces/IPool.sol"; +import {IRMN} from "../interfaces/IRMN.sol"; +import {IRouter} from "../interfaces/IRouter.sol"; + +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; +import {Pool} from "../libraries/Pool.sol"; +import {RateLimiter} from "../libraries/RateLimiter.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +/// @notice Base abstract class with common functions for all token pools. +/// A token pool serves as isolated place for holding tokens and token specific logic +/// that may execute as tokens move across the bridge. +abstract contract TokenPool is IPoolV1, OwnerIsCreator { + using EnumerableSet for EnumerableSet.AddressSet; + using EnumerableSet for EnumerableSet.UintSet; + using RateLimiter for RateLimiter.TokenBucket; + + error CallerIsNotARampOnRouter(address caller); + error ZeroAddressNotAllowed(); + error SenderNotAllowed(address sender); + error AllowListNotEnabled(); + error NonExistentChain(uint64 remoteChainSelector); + error ChainNotAllowed(uint64 remoteChainSelector); + error CursedByRMN(); + error ChainAlreadyExists(uint64 chainSelector); + error InvalidSourcePoolAddress(bytes sourcePoolAddress); + error InvalidToken(address token); + + event Locked(address indexed sender, uint256 amount); + event Burned(address indexed sender, uint256 amount); + event Released(address indexed sender, address indexed recipient, uint256 amount); + event Minted(address indexed sender, address indexed recipient, uint256 amount); + event ChainAdded( + uint64 remoteChainSelector, + bytes remoteToken, + RateLimiter.Config outboundRateLimiterConfig, + RateLimiter.Config inboundRateLimiterConfig + ); + event ChainConfigured( + uint64 remoteChainSelector, + RateLimiter.Config outboundRateLimiterConfig, + RateLimiter.Config inboundRateLimiterConfig + ); + event ChainRemoved(uint64 remoteChainSelector); + event RemotePoolSet(uint64 indexed remoteChainSelector, bytes previousPoolAddress, bytes remotePoolAddress); + event AllowListAdd(address sender); + event AllowListRemove(address sender); + event RouterUpdated(address oldRouter, address newRouter); + + struct ChainUpdate { + uint64 remoteChainSelector; // ──╮ Remote chain selector + bool allowed; // ────────────────╯ Whether the chain should be enabled + bytes remotePoolAddress; // Address of the remote pool, ABI encoded in the case of a remove EVM chain. + bytes remoteTokenAddress; // Address of the remote token, ABI encoded in the case of a remote EVM chain. + RateLimiter.Config outboundRateLimiterConfig; // Outbound rate limited config, meaning the rate limits for all of the onRamps for the given chain + RateLimiter.Config inboundRateLimiterConfig; // Inbound rate limited config, meaning the rate limits for all of the offRamps for the given chain + } + + struct RemoteChainConfig { + RateLimiter.TokenBucket outboundRateLimiterConfig; // Outbound rate limited config, meaning the rate limits for all of the onRamps for the given chain + RateLimiter.TokenBucket inboundRateLimiterConfig; // Inbound rate limited config, meaning the rate limits for all of the offRamps for the given chain + bytes remotePoolAddress; // Address of the remote pool, ABI encoded in the case of a remote EVM chain. + bytes remoteTokenAddress; // Address of the remote token, ABI encoded in the case of a remote EVM chain. + } + + /// @dev The bridgeable token that is managed by this pool. + IERC20 internal immutable i_token; + /// @dev The address of the RMN proxy + address internal immutable i_rmnProxy; + /// @dev The immutable flag that indicates if the pool is access-controlled. + bool internal immutable i_allowlistEnabled; + /// @dev A set of addresses allowed to trigger lockOrBurn as original senders. + /// Only takes effect if i_allowlistEnabled is true. + /// This can be used to ensure only token-issuer specified addresses can + /// move tokens. + EnumerableSet.AddressSet internal s_allowList; + /// @dev The address of the router + IRouter internal s_router; + /// @dev A set of allowed chain selectors. We want the allowlist to be enumerable to + /// be able to quickly determine (without parsing logs) who can access the pool. + /// @dev The chain selectors are in uint256 format because of the EnumerableSet implementation. + EnumerableSet.UintSet internal s_remoteChainSelectors; + mapping(uint64 remoteChainSelector => RemoteChainConfig) internal s_remoteChainConfigs; + + constructor(IERC20 token, address[] memory allowlist, address rmnProxy, address router) { + if (address(token) == address(0) || router == address(0) || rmnProxy == address(0)) revert ZeroAddressNotAllowed(); + i_token = token; + i_rmnProxy = rmnProxy; + s_router = IRouter(router); + + // Pool can be set as permissioned or permissionless at deployment time only to save hot-path gas. + i_allowlistEnabled = allowlist.length > 0; + if (i_allowlistEnabled) { + _applyAllowListUpdates(new address[](0), allowlist); + } + } + + /// @notice Get RMN proxy address + /// @return rmnProxy Address of RMN proxy + function getRmnProxy() public view returns (address rmnProxy) { + return i_rmnProxy; + } + + /// @inheritdoc IPoolV1 + function isSupportedToken(address token) public view virtual returns (bool) { + return token == address(i_token); + } + + /// @notice Gets the IERC20 token that this pool can lock or burn. + /// @return token The IERC20 token representation. + function getToken() public view returns (IERC20 token) { + return i_token; + } + + /// @notice Gets the pool's Router + /// @return router The pool's Router + function getRouter() public view returns (address router) { + return address(s_router); + } + + /// @notice Sets the pool's Router + /// @param newRouter The new Router + function setRouter(address newRouter) public onlyOwner { + if (newRouter == address(0)) revert ZeroAddressNotAllowed(); + address oldRouter = address(s_router); + s_router = IRouter(newRouter); + + emit RouterUpdated(oldRouter, newRouter); + } + + /// @notice Signals which version of the pool interface is supported + function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) { + return interfaceId == Pool.CCIP_POOL_V1 || interfaceId == type(IPoolV1).interfaceId + || interfaceId == type(IERC165).interfaceId; + } + + // ================================================================ + // │ Validation │ + // ================================================================ + + /// @notice Validates the lock or burn input for correctness on + /// - token to be locked or burned + /// - RMN curse status + /// - allowlist status + /// - if the sender is a valid onRamp + /// - rate limit status + /// @param lockOrBurnIn The input to validate. + /// @dev This function should always be called before executing a lock or burn. Not doing so would allow + /// for various exploits. + function _validateLockOrBurn(Pool.LockOrBurnInV1 memory lockOrBurnIn) internal { + if (!isSupportedToken(lockOrBurnIn.localToken)) revert InvalidToken(lockOrBurnIn.localToken); + if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(lockOrBurnIn.remoteChainSelector)))) revert CursedByRMN(); + _checkAllowList(lockOrBurnIn.originalSender); + + _onlyOnRamp(lockOrBurnIn.remoteChainSelector); + _consumeOutboundRateLimit(lockOrBurnIn.remoteChainSelector, lockOrBurnIn.amount); + } + + /// @notice Validates the release or mint input for correctness on + /// - token to be released or minted + /// - RMN curse status + /// - if the sender is a valid offRamp + /// - if the source pool is valid + /// - rate limit status + /// @param releaseOrMintIn The input to validate. + /// @dev This function should always be called before executing a lock or burn. Not doing so would allow + /// for various exploits. + function _validateReleaseOrMint(Pool.ReleaseOrMintInV1 memory releaseOrMintIn) internal { + if (!isSupportedToken(releaseOrMintIn.localToken)) revert InvalidToken(releaseOrMintIn.localToken); + if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(releaseOrMintIn.remoteChainSelector)))) revert CursedByRMN(); + _onlyOffRamp(releaseOrMintIn.remoteChainSelector); + + // Validates that the source pool address is configured on this pool. + bytes memory configuredRemotePool = getRemotePool(releaseOrMintIn.remoteChainSelector); + if ( + configuredRemotePool.length == 0 + || keccak256(releaseOrMintIn.sourcePoolAddress) != keccak256(configuredRemotePool) + ) { + revert InvalidSourcePoolAddress(releaseOrMintIn.sourcePoolAddress); + } + _consumeInboundRateLimit(releaseOrMintIn.remoteChainSelector, releaseOrMintIn.amount); + } + + // ================================================================ + // │ Chain permissions │ + // ================================================================ + + /// @notice Gets the pool address on the remote chain. + /// @param remoteChainSelector Remote chain selector. + /// @dev To support non-evm chains, this value is encoded into bytes + function getRemotePool(uint64 remoteChainSelector) public view returns (bytes memory) { + return s_remoteChainConfigs[remoteChainSelector].remotePoolAddress; + } + + /// @notice Gets the token address on the remote chain. + /// @param remoteChainSelector Remote chain selector. + /// @dev To support non-evm chains, this value is encoded into bytes + function getRemoteToken(uint64 remoteChainSelector) public view returns (bytes memory) { + return s_remoteChainConfigs[remoteChainSelector].remoteTokenAddress; + } + + /// @notice Sets the remote pool address for a given chain selector. + /// @param remoteChainSelector The remote chain selector for which the remote pool address is being set. + /// @param remotePoolAddress The address of the remote pool. + function setRemotePool(uint64 remoteChainSelector, bytes calldata remotePoolAddress) external onlyOwner { + if (!isSupportedChain(remoteChainSelector)) revert NonExistentChain(remoteChainSelector); + + bytes memory prevAddress = s_remoteChainConfigs[remoteChainSelector].remotePoolAddress; + s_remoteChainConfigs[remoteChainSelector].remotePoolAddress = remotePoolAddress; + + emit RemotePoolSet(remoteChainSelector, prevAddress, remotePoolAddress); + } + + /// @inheritdoc IPoolV1 + function isSupportedChain(uint64 remoteChainSelector) public view returns (bool) { + return s_remoteChainSelectors.contains(remoteChainSelector); + } + + /// @notice Get list of allowed chains + /// @return list of chains. + function getSupportedChains() public view returns (uint64[] memory) { + uint256[] memory uint256ChainSelectors = s_remoteChainSelectors.values(); + uint64[] memory chainSelectors = new uint64[](uint256ChainSelectors.length); + for (uint256 i = 0; i < uint256ChainSelectors.length; ++i) { + chainSelectors[i] = uint64(uint256ChainSelectors[i]); + } + + return chainSelectors; + } + + /// @notice Sets the permissions for a list of chains selectors. Actual senders for these chains + /// need to be allowed on the Router to interact with this pool. + /// @dev Only callable by the owner + /// @param chains A list of chains and their new permission status & rate limits. Rate limits + /// are only used when the chain is being added through `allowed` being true. + function applyChainUpdates(ChainUpdate[] calldata chains) external virtual onlyOwner { + for (uint256 i = 0; i < chains.length; ++i) { + ChainUpdate memory update = chains[i]; + RateLimiter._validateTokenBucketConfig(update.outboundRateLimiterConfig, !update.allowed); + RateLimiter._validateTokenBucketConfig(update.inboundRateLimiterConfig, !update.allowed); + + if (update.allowed) { + // If the chain already exists, revert + if (!s_remoteChainSelectors.add(update.remoteChainSelector)) { + revert ChainAlreadyExists(update.remoteChainSelector); + } + + if (update.remotePoolAddress.length == 0 || update.remoteTokenAddress.length == 0) { + revert ZeroAddressNotAllowed(); + } + + s_remoteChainConfigs[update.remoteChainSelector] = RemoteChainConfig({ + outboundRateLimiterConfig: RateLimiter.TokenBucket({ + rate: update.outboundRateLimiterConfig.rate, + capacity: update.outboundRateLimiterConfig.capacity, + tokens: update.outboundRateLimiterConfig.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: update.outboundRateLimiterConfig.isEnabled + }), + inboundRateLimiterConfig: RateLimiter.TokenBucket({ + rate: update.inboundRateLimiterConfig.rate, + capacity: update.inboundRateLimiterConfig.capacity, + tokens: update.inboundRateLimiterConfig.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: update.inboundRateLimiterConfig.isEnabled + }), + remotePoolAddress: update.remotePoolAddress, + remoteTokenAddress: update.remoteTokenAddress + }); + + emit ChainAdded( + update.remoteChainSelector, + update.remoteTokenAddress, + update.outboundRateLimiterConfig, + update.inboundRateLimiterConfig + ); + } else { + // If the chain doesn't exist, revert + if (!s_remoteChainSelectors.remove(update.remoteChainSelector)) { + revert NonExistentChain(update.remoteChainSelector); + } + + delete s_remoteChainConfigs[update.remoteChainSelector]; + + emit ChainRemoved(update.remoteChainSelector); + } + } + } + + // ================================================================ + // │ Rate limiting │ + // ================================================================ + + /// @notice Consumes outbound rate limiting capacity in this pool + function _consumeOutboundRateLimit(uint64 remoteChainSelector, uint256 amount) internal { + s_remoteChainConfigs[remoteChainSelector].outboundRateLimiterConfig._consume(amount, address(i_token)); + } + + /// @notice Consumes inbound rate limiting capacity in this pool + function _consumeInboundRateLimit(uint64 remoteChainSelector, uint256 amount) internal { + s_remoteChainConfigs[remoteChainSelector].inboundRateLimiterConfig._consume(amount, address(i_token)); + } + + /// @notice Gets the token bucket with its values for the block it was requested at. + /// @return The token bucket. + function getCurrentOutboundRateLimiterState(uint64 remoteChainSelector) + external + view + returns (RateLimiter.TokenBucket memory) + { + return s_remoteChainConfigs[remoteChainSelector].outboundRateLimiterConfig._currentTokenBucketState(); + } + + /// @notice Gets the token bucket with its values for the block it was requested at. + /// @return The token bucket. + function getCurrentInboundRateLimiterState(uint64 remoteChainSelector) + external + view + returns (RateLimiter.TokenBucket memory) + { + return s_remoteChainConfigs[remoteChainSelector].inboundRateLimiterConfig._currentTokenBucketState(); + } + + /// @notice Sets the chain rate limiter config. + /// @param remoteChainSelector The remote chain selector for which the rate limits apply. + /// @param outboundConfig The new outbound rate limiter config, meaning the onRamp rate limits for the given chain. + /// @param inboundConfig The new inbound rate limiter config, meaning the offRamp rate limits for the given chain. + function setChainRateLimiterConfig( + uint64 remoteChainSelector, + RateLimiter.Config memory outboundConfig, + RateLimiter.Config memory inboundConfig + ) external virtual onlyOwner { + _setRateLimitConfig(remoteChainSelector, outboundConfig, inboundConfig); + } + + function _setRateLimitConfig( + uint64 remoteChainSelector, + RateLimiter.Config memory outboundConfig, + RateLimiter.Config memory inboundConfig + ) internal { + if (!isSupportedChain(remoteChainSelector)) revert NonExistentChain(remoteChainSelector); + RateLimiter._validateTokenBucketConfig(outboundConfig, false); + s_remoteChainConfigs[remoteChainSelector].outboundRateLimiterConfig._setTokenBucketConfig(outboundConfig); + RateLimiter._validateTokenBucketConfig(inboundConfig, false); + s_remoteChainConfigs[remoteChainSelector].inboundRateLimiterConfig._setTokenBucketConfig(inboundConfig); + emit ChainConfigured(remoteChainSelector, outboundConfig, inboundConfig); + } + + // ================================================================ + // │ Access │ + // ================================================================ + + /// @notice Checks whether remote chain selector is configured on this contract, and if the msg.sender + /// is a permissioned onRamp for the given chain on the Router. + function _onlyOnRamp(uint64 remoteChainSelector) internal view { + if (!isSupportedChain(remoteChainSelector)) revert ChainNotAllowed(remoteChainSelector); + if (!(msg.sender == s_router.getOnRamp(remoteChainSelector))) revert CallerIsNotARampOnRouter(msg.sender); + } + + /// @notice Checks whether remote chain selector is configured on this contract, and if the msg.sender + /// is a permissioned offRamp for the given chain on the Router. + function _onlyOffRamp(uint64 remoteChainSelector) internal view { + if (!isSupportedChain(remoteChainSelector)) revert ChainNotAllowed(remoteChainSelector); + if (!s_router.isOffRamp(remoteChainSelector, msg.sender)) revert CallerIsNotARampOnRouter(msg.sender); + } + + // ================================================================ + // │ Allowlist │ + // ================================================================ + + function _checkAllowList(address sender) internal view { + if (i_allowlistEnabled) { + if (!s_allowList.contains(sender)) { + revert SenderNotAllowed(sender); + } + } + } + + /// @notice Gets whether the allowList functionality is enabled. + /// @return true is enabled, false if not. + function getAllowListEnabled() external view returns (bool) { + return i_allowlistEnabled; + } + + /// @notice Gets the allowed addresses. + /// @return The allowed addresses. + function getAllowList() external view returns (address[] memory) { + return s_allowList.values(); + } + + /// @notice Apply updates to the allow list. + /// @param removes The addresses to be removed. + /// @param adds The addresses to be added. + function applyAllowListUpdates(address[] calldata removes, address[] calldata adds) external onlyOwner { + _applyAllowListUpdates(removes, adds); + } + + /// @notice Internal version of applyAllowListUpdates to allow for reuse in the constructor. + function _applyAllowListUpdates(address[] memory removes, address[] memory adds) internal { + if (!i_allowlistEnabled) revert AllowListNotEnabled(); + + for (uint256 i = 0; i < removes.length; ++i) { + address toRemove = removes[i]; + if (s_allowList.remove(toRemove)) { + emit AllowListRemove(toRemove); + } + } + for (uint256 i = 0; i < adds.length; ++i) { + address toAdd = adds[i]; + if (toAdd == address(0)) { + continue; + } + if (s_allowList.add(toAdd)) { + emit AllowListAdd(toAdd); + } + } + } +} diff --git a/contracts/src/v0.8/ccip/pools/USDC/IMessageTransmitter.sol b/contracts/src/v0.8/ccip/pools/USDC/IMessageTransmitter.sol new file mode 100644 index 0000000000..1b2a0f9021 --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/USDC/IMessageTransmitter.sol @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022, Circle Internet Financial Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +pragma solidity ^0.8.0; + +interface IMessageTransmitter { + /// @notice Unlocks USDC tokens on the destination chain + /// @param message The original message on the source chain + /// * Message format: + /// * Field Bytes Type Index + /// * version 4 uint32 0 + /// * sourceDomain 4 uint32 4 + /// * destinationDomain 4 uint32 8 + /// * nonce 8 uint64 12 + /// * sender 32 bytes32 20 + /// * recipient 32 bytes32 52 + /// * destinationCaller 32 bytes32 84 + /// * messageBody dynamic bytes 116 + /// param attestation A valid attestation is the concatenated 65-byte signature(s) of + /// exactly `thresholdSignature` signatures, in increasing order of attester address. + /// ***If the attester addresses recovered from signatures are not in increasing order, + /// signature verification will fail.*** + /// If incorrect number of signatures or duplicate signatures are supplied, + /// signature verification will fail. + function receiveMessage(bytes calldata message, bytes calldata attestation) external returns (bool success); + + /// Returns domain of chain on which the contract is deployed. + /// @dev immutable + function localDomain() external view returns (uint32); + + /// Returns message format version. + /// @dev immutable + function version() external view returns (uint32); +} diff --git a/contracts/src/v0.8/ccip/pools/USDC/ITokenMessenger.sol b/contracts/src/v0.8/ccip/pools/USDC/ITokenMessenger.sol new file mode 100644 index 0000000000..ce5923cfdc --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/USDC/ITokenMessenger.sol @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022, Circle Internet Financial Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +pragma solidity ^0.8.0; + +interface ITokenMessenger { + /// @notice Emitted when a DepositForBurn message is sent + /// @param nonce Unique nonce reserved by message + /// @param burnToken Address of token burnt on source domain + /// @param amount Deposit amount + /// @param depositor Address where deposit is transferred from + /// @param mintRecipient Address receiving minted tokens on destination domain as bytes32 + /// @param destinationDomain Destination domain + /// @param destinationTokenMessenger Address of TokenMessenger on destination domain as bytes32 + /// @param destinationCaller Authorized caller as bytes32 of receiveMessage() on destination domain, + /// if not equal to bytes32(0). If equal to bytes32(0), any address can call receiveMessage(). + event DepositForBurn( + uint64 indexed nonce, + address indexed burnToken, + uint256 amount, + address indexed depositor, + bytes32 mintRecipient, + uint32 destinationDomain, + bytes32 destinationTokenMessenger, + bytes32 destinationCaller + ); + + /// @notice Burns the tokens on the source side to produce a nonce through + /// Circles Cross Chain Transfer Protocol. + /// @param amount Amount of tokens to deposit and burn. + /// @param destinationDomain Destination domain identifier. + /// @param mintRecipient Address of mint recipient on destination domain. + /// @param burnToken Address of contract to burn deposited tokens, on local domain. + /// @param destinationCaller Caller on the destination domain, as bytes32. + /// @return nonce The unique nonce used in unlocking the funds on the destination chain. + /// @dev emits DepositForBurn + function depositForBurnWithCaller( + uint256 amount, + uint32 destinationDomain, + bytes32 mintRecipient, + address burnToken, + bytes32 destinationCaller + ) external returns (uint64 nonce); + + /// Returns the version of the message body format. + /// @dev immutable + function messageBodyVersion() external view returns (uint32); + + /// Returns local Message Transmitter responsible for sending and receiving messages + /// to/from remote domainsmessage transmitter for this token messenger. + /// @dev immutable + function localMessageTransmitter() external view returns (address); +} diff --git a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol new file mode 100644 index 0000000000..339ed09992 --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; +import {IMessageTransmitter} from "./IMessageTransmitter.sol"; +import {ITokenMessenger} from "./ITokenMessenger.sol"; + +import {Pool} from "../../libraries/Pool.sol"; +import {TokenPool} from "../TokenPool.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +/// @notice This pool mints and burns USDC tokens through the Cross Chain Transfer +/// Protocol (CCTP). +contract USDCTokenPool is TokenPool, ITypeAndVersion { + using SafeERC20 for IERC20; + + event DomainsSet(DomainUpdate[]); + event ConfigSet(address tokenMessenger); + + error UnknownDomain(uint64 domain); + error UnlockingUSDCFailed(); + error InvalidConfig(); + error InvalidDomain(DomainUpdate domain); + error InvalidMessageVersion(uint32 version); + error InvalidTokenMessengerVersion(uint32 version); + error InvalidNonce(uint64 expected, uint64 got); + error InvalidSourceDomain(uint32 expected, uint32 got); + error InvalidDestinationDomain(uint32 expected, uint32 got); + error InvalidReceiver(bytes receiver); + + // This data is supplied from offchain and contains everything needed + // to receive the USDC tokens. + struct MessageAndAttestation { + bytes message; + bytes attestation; + } + + // A domain is a USDC representation of a chain. + struct DomainUpdate { + bytes32 allowedCaller; // Address allowed to mint on the domain + uint32 domainIdentifier; // ──╮ Unique domain ID + uint64 destChainSelector; // │ The destination chain for this domain + bool enabled; // ─────────────╯ Whether the domain is enabled + } + + struct SourceTokenDataPayload { + uint64 nonce; + uint32 sourceDomain; + } + + string public constant override typeAndVersion = "USDCTokenPool 1.4.0"; + + // We restrict to the first version. New pool may be required for subsequent versions. + uint32 public constant SUPPORTED_USDC_VERSION = 0; + + // The local USDC config + ITokenMessenger public immutable i_tokenMessenger; + IMessageTransmitter public immutable i_messageTransmitter; + uint32 public immutable i_localDomainIdentifier; + + /// A domain is a USDC representation of a destination chain. + /// @dev Zero is a valid domain identifier. + /// @dev The address to mint on the destination chain is the corresponding USDC pool. + struct Domain { + bytes32 allowedCaller; // Address allowed to mint on the domain + uint32 domainIdentifier; // ─╮ Unique domain ID + bool enabled; // ────────────╯ Whether the domain is enabled + } + + // A mapping of CCIP chain identifiers to destination domains + mapping(uint64 chainSelector => Domain CCTPDomain) private s_chainToDomain; + + constructor( + ITokenMessenger tokenMessenger, + IERC20 token, + address[] memory allowlist, + address rmnProxy, + address router + ) TokenPool(token, allowlist, rmnProxy, router) { + if (address(tokenMessenger) == address(0)) revert InvalidConfig(); + IMessageTransmitter transmitter = IMessageTransmitter(tokenMessenger.localMessageTransmitter()); + uint32 transmitterVersion = transmitter.version(); + if (transmitterVersion != SUPPORTED_USDC_VERSION) revert InvalidMessageVersion(transmitterVersion); + uint32 tokenMessengerVersion = tokenMessenger.messageBodyVersion(); + if (tokenMessengerVersion != SUPPORTED_USDC_VERSION) revert InvalidTokenMessengerVersion(tokenMessengerVersion); + + i_tokenMessenger = tokenMessenger; + i_messageTransmitter = transmitter; + i_localDomainIdentifier = transmitter.localDomain(); + i_token.safeIncreaseAllowance(address(i_tokenMessenger), type(uint256).max); + emit ConfigSet(address(tokenMessenger)); + } + + /// @notice Burn the token in the pool + /// @dev Burn is not rate limited at per-pool level. Burn does not contribute to honey pot risk. + /// Benefits of rate limiting here does not justify the extra gas cost. + /// @dev emits ITokenMessenger.DepositForBurn + /// @dev Assumes caller has validated destinationReceiver + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + external + virtual + override + returns (Pool.LockOrBurnOutV1 memory) + { + _validateLockOrBurn(lockOrBurnIn); + + Domain memory domain = s_chainToDomain[lockOrBurnIn.remoteChainSelector]; + if (!domain.enabled) revert UnknownDomain(lockOrBurnIn.remoteChainSelector); + if (lockOrBurnIn.receiver.length != 32) { + revert InvalidReceiver(lockOrBurnIn.receiver); + } + + // Since this pool is the msg sender of the CCTP transaction, only this contract + // is able to call replaceDepositForBurn. Since this contract does not implement + // replaceDepositForBurn, the tokens cannot be maliciously re-routed to another address. + uint64 nonce = i_tokenMessenger.depositForBurnWithCaller( + // We set the domain.allowedCaller as the receiver of the funds, as this is the token pool. Since 1.5 the + // token pools receiver the funds to hop them through the offRamps. + lockOrBurnIn.amount, + domain.domainIdentifier, + domain.allowedCaller, + address(i_token), + domain.allowedCaller + ); + + emit Burned(msg.sender, lockOrBurnIn.amount); + + return Pool.LockOrBurnOutV1({ + destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), + destPoolData: abi.encode(SourceTokenDataPayload({nonce: nonce, sourceDomain: i_localDomainIdentifier})) + }); + } + + /// @notice Mint tokens from the pool to the recipient + /// * sourceTokenData is part of the verified message and passed directly from + /// the offramp so it is guaranteed to be what the lockOrBurn pool released on the + /// source chain. It contains (nonce, sourceDomain) which is guaranteed by CCTP + /// to be unique. + /// * offchainTokenData is untrusted (can be supplied by manual execution), but we assert + /// that (nonce, sourceDomain) is equal to the message's (nonce, sourceDomain) and + /// receiveMessage will assert that Attestation contains a valid attestation signature + /// for that message, including its (nonce, sourceDomain). This way, the only + /// non-reverting offchainTokenData that can be supplied is a valid attestation for the + /// specific message that was sent on source. + function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + external + override + returns (Pool.ReleaseOrMintOutV1 memory) + { + _validateReleaseOrMint(releaseOrMintIn); + SourceTokenDataPayload memory sourceTokenDataPayload = + abi.decode(releaseOrMintIn.sourcePoolData, (SourceTokenDataPayload)); + MessageAndAttestation memory msgAndAttestation = + abi.decode(releaseOrMintIn.offchainTokenData, (MessageAndAttestation)); + + _validateMessage(msgAndAttestation.message, sourceTokenDataPayload); + + if (!i_messageTransmitter.receiveMessage(msgAndAttestation.message, msgAndAttestation.attestation)) { + revert UnlockingUSDCFailed(); + } + // Since the tokens are minted to the pool, the pool has to send it to the offRamp + getToken().safeTransfer(msg.sender, releaseOrMintIn.amount); + + emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); + return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + } + + /// @notice Validates the USDC encoded message against the given parameters. + /// @param usdcMessage The USDC encoded message + /// @param sourceTokenData The expected source chain token data to check against + /// @dev Only supports version SUPPORTED_USDC_VERSION of the CCTP message format + /// @dev Message format for USDC: + /// * Field Bytes Type Index + /// * version 4 uint32 0 + /// * sourceDomain 4 uint32 4 + /// * destinationDomain 4 uint32 8 + /// * nonce 8 uint64 12 + /// * sender 32 bytes32 20 + /// * recipient 32 bytes32 52 + /// * destinationCaller 32 bytes32 84 + /// * messageBody dynamic bytes 116 + function _validateMessage(bytes memory usdcMessage, SourceTokenDataPayload memory sourceTokenData) internal view { + uint32 version; + // solhint-disable-next-line no-inline-assembly + assembly { + // We truncate using the datatype of the version variable, meaning + // we will only be left with the first 4 bytes of the message. + version := mload(add(usdcMessage, 4)) // 0 + 4 = 4 + } + // This token pool only supports version 0 of the CCTP message format + // We check the version prior to loading the rest of the message + // to avoid unexpected reverts due to out-of-bounds reads. + if (version != SUPPORTED_USDC_VERSION) revert InvalidMessageVersion(version); + + uint32 sourceDomain; + uint32 destinationDomain; + uint64 nonce; + + // solhint-disable-next-line no-inline-assembly + assembly { + sourceDomain := mload(add(usdcMessage, 8)) // 4 + 4 = 8 + destinationDomain := mload(add(usdcMessage, 12)) // 8 + 4 = 12 + nonce := mload(add(usdcMessage, 20)) // 12 + 8 = 20 + } + + if (sourceDomain != sourceTokenData.sourceDomain) { + revert InvalidSourceDomain(sourceTokenData.sourceDomain, sourceDomain); + } + if (destinationDomain != i_localDomainIdentifier) { + revert InvalidDestinationDomain(i_localDomainIdentifier, destinationDomain); + } + if (nonce != sourceTokenData.nonce) revert InvalidNonce(sourceTokenData.nonce, nonce); + } + + // ================================================================ + // │ Config │ + // ================================================================ + + /// @notice Gets the CCTP domain for a given CCIP chain selector. + function getDomain(uint64 chainSelector) external view returns (Domain memory) { + return s_chainToDomain[chainSelector]; + } + + /// @notice Sets the CCTP domain for a CCIP chain selector. + /// @dev Must verify mapping of selectors -> (domain, caller) offchain. + function setDomains(DomainUpdate[] calldata domains) external onlyOwner { + for (uint256 i = 0; i < domains.length; ++i) { + DomainUpdate memory domain = domains[i]; + if (domain.allowedCaller == bytes32(0) || domain.destChainSelector == 0) revert InvalidDomain(domain); + + s_chainToDomain[domain.destChainSelector] = Domain({ + domainIdentifier: domain.domainIdentifier, + allowedCaller: domain.allowedCaller, + enabled: domain.enabled + }); + } + emit DomainsSet(domains); + } +} diff --git a/contracts/src/v0.8/ccip/test/BaseTest.t.sol b/contracts/src/v0.8/ccip/test/BaseTest.t.sol new file mode 100644 index 0000000000..ee3f3e6fd4 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/BaseTest.t.sol @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +// Imports to any non-library are not allowed due to the significant cascading +// compile time increase they cause when imported into this base test. +import {Internal} from "../libraries/Internal.sol"; +import {RateLimiter} from "../libraries/RateLimiter.sol"; +import {MockRMN} from "./mocks/MockRMN.sol"; +import {Test} from "forge-std/Test.sol"; + +contract BaseTest is Test { + // Addresses + address internal constant OWNER = 0x00007e64E1fB0C487F25dd6D3601ff6aF8d32e4e; + address internal constant STRANGER = address(999999); + address internal constant DUMMY_CONTRACT_ADDRESS = 0x1111111111111111111111111111111111111112; + address internal constant ON_RAMP_ADDRESS = 0x11118e64e1FB0c487f25dD6D3601FF6aF8d32E4e; + address internal constant ZERO_ADDRESS = address(0); + address internal constant FEE_AGGREGATOR = 0xa33CDB32eAEce34F6affEfF4899cef45744EDea3; + + address internal constant USER_1 = address(1); + address internal constant USER_2 = address(2); + address internal constant USER_3 = address(3); + address internal constant USER_4 = address(4); + + // Message info + uint64 internal constant SOURCE_CHAIN_SELECTOR = 1; + uint64 internal constant DEST_CHAIN_SELECTOR = 2; + uint32 internal constant GAS_LIMIT = 200_000; + + // Timing + uint256 internal constant BLOCK_TIME = 1234567890; + uint32 internal constant TWELVE_HOURS = 60 * 60 * 12; + + // Onramp + uint96 internal constant MAX_NOP_FEES_JUELS = 1e27; + uint96 internal constant MAX_MSG_FEES_JUELS = 1e18; + uint32 internal constant DEST_GAS_OVERHEAD = 350_000; + uint16 internal constant DEST_GAS_PER_PAYLOAD_BYTE = 16; + + uint16 internal constant DEFAULT_TOKEN_FEE_USD_CENTS = 50; + uint32 internal constant DEFAULT_TOKEN_DEST_GAS_OVERHEAD = 34_000; + uint32 internal constant DEFAULT_TOKEN_BYTES_OVERHEAD = 50; + + bool private s_baseTestInitialized; + + // Use 16 gas per data availability byte in our tests. + // This is an overestimation in OP stack, it ignores 4 gas per 0 byte rule. + // Arbitrum on the other hand, does always use 16 gas per data availability byte. + // This value may be substantially decreased after EIP 4844. + uint16 internal constant DEST_GAS_PER_DATA_AVAILABILITY_BYTE = 16; + + // Total L1 data availability overhead estimate is 33_596 gas. + // This value includes complete CommitStore and OffRamp call data. + uint32 internal constant DEST_DATA_AVAILABILITY_OVERHEAD_GAS = 188 // Fixed data availability overhead in OP stack. + + (32 * 31 + 4) * DEST_GAS_PER_DATA_AVAILABILITY_BYTE // CommitStore single-root transmission takes up about 31 slots, plus selector. + + (32 * 34 + 4) * DEST_GAS_PER_DATA_AVAILABILITY_BYTE; // OffRamp transmission excluding EVM2EVMMessage takes up about 34 slots, plus selector. + + // Multiples of bps, or 0.0001, use 6840 to be same as OP mainnet compression factor of 0.684. + uint16 internal constant DEST_GAS_DATA_AVAILABILITY_MULTIPLIER_BPS = 6840; + + // OffRamp + uint32 internal constant MAX_DATA_SIZE = 30_000; + uint16 internal constant MAX_TOKENS_LENGTH = 5; + uint32 internal constant MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS = 200_000; + uint32 internal constant MAX_TOKEN_POOL_TRANSFER_GAS = 50_000; + uint16 internal constant GAS_FOR_CALL_EXACT_CHECK = 5000; + uint32 internal constant PERMISSION_LESS_EXECUTION_THRESHOLD_SECONDS = 500; + uint32 internal constant MAX_GAS_LIMIT = 4_000_000; + + // Rate limiter + address internal constant ADMIN = 0x11118e64e1FB0c487f25dD6D3601FF6aF8d32E4e; + + MockRMN internal s_mockRMN; + + function setUp() public virtual { + // BaseTest.setUp is often called multiple times from tests' setUp due to inheritance. + if (s_baseTestInitialized) return; + s_baseTestInitialized = true; + + // Set the sender to OWNER permanently + vm.startPrank(OWNER); + deal(OWNER, 1e20); + vm.label(OWNER, "Owner"); + vm.label(STRANGER, "Stranger"); + + // Set the block time to a constant known value + vm.warp(BLOCK_TIME); + + s_mockRMN = new MockRMN(); + } + + function getOutboundRateLimiterConfig() internal pure returns (RateLimiter.Config memory) { + return RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e15}); + } + + function getInboundRateLimiterConfig() internal pure returns (RateLimiter.Config memory) { + return RateLimiter.Config({isEnabled: true, capacity: 222e30, rate: 1e18}); + } + + function getSingleTokenPriceUpdateStruct( + address token, + uint224 price + ) internal pure returns (Internal.PriceUpdates memory) { + Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](1); + tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: token, usdPerToken: price}); + + Internal.PriceUpdates memory priceUpdates = + Internal.PriceUpdates({tokenPriceUpdates: tokenPriceUpdates, gasPriceUpdates: new Internal.GasPriceUpdate[](0)}); + + return priceUpdates; + } + + function getSingleGasPriceUpdateStruct( + uint64 chainSelector, + uint224 usdPerUnitGas + ) internal pure returns (Internal.PriceUpdates memory) { + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: chainSelector, usdPerUnitGas: usdPerUnitGas}); + + Internal.PriceUpdates memory priceUpdates = + Internal.PriceUpdates({tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), gasPriceUpdates: gasPriceUpdates}); + + return priceUpdates; + } +} diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol new file mode 100644 index 0000000000..75de4db8c5 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -0,0 +1,649 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {NonceManager} from "../NonceManager.sol"; +import {ICommitStore} from "../interfaces/ICommitStore.sol"; +import {Client} from "../libraries/Client.sol"; +import {Internal} from "../libraries/Internal.sol"; +import {Pool} from "../libraries/Pool.sol"; +import {RateLimiter} from "../libraries/RateLimiter.sol"; +import {EVM2EVMMultiOffRamp} from "../offRamp/EVM2EVMMultiOffRamp.sol"; +import {EVM2EVMMultiOnRamp} from "../onRamp/EVM2EVMMultiOnRamp.sol"; +import {EVM2EVMOnRamp} from "../onRamp/EVM2EVMOnRamp.sol"; + +import {BaseTest} from "./BaseTest.t.sol"; +import {EVM2EVMMultiOnRampHelper} from "./helpers/EVM2EVMMultiOnRampHelper.sol"; +import {EVM2EVMOffRampHelper} from "./helpers/EVM2EVMOffRampHelper.sol"; +import {EVM2EVMOnRampHelper} from "./helpers/EVM2EVMOnRampHelper.sol"; +import {MockCommitStore} from "./mocks/MockCommitStore.sol"; +import {EVM2EVMMultiOffRampSetup} from "./offRamp/EVM2EVMMultiOffRampSetup.t.sol"; +import {EVM2EVMMultiOnRampSetup} from "./onRamp/EVM2EVMMultiOnRampSetup.t.sol"; + +contract NonceManager_NonceIncrementation is BaseTest { + NonceManager private s_nonceManager; + + function setUp() public override { + address[] memory authorizedCallers = new address[](1); + authorizedCallers[0] = address(this); + s_nonceManager = new NonceManager(authorizedCallers); + } + + function test_getIncrementedOutboundNonce_Success() public { + address sender = address(this); + + assertEq(s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, sender), 0); + + uint64 outboundNonce = s_nonceManager.getIncrementedOutboundNonce(DEST_CHAIN_SELECTOR, sender); + assertEq(outboundNonce, 1); + } + + function test_incrementInboundNonce_Success() public { + address sender = address(this); + + s_nonceManager.incrementInboundNonce(SOURCE_CHAIN_SELECTOR, 1, abi.encode(sender)); + + assertEq(s_nonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR, abi.encode(sender)), 1); + } + + function test_incrementInboundNonce_Skip() public { + address sender = address(this); + uint64 expectedNonce = 2; + + vm.expectEmit(); + emit NonceManager.SkippedIncorrectNonce(SOURCE_CHAIN_SELECTOR, expectedNonce, abi.encode(sender)); + + s_nonceManager.incrementInboundNonce(SOURCE_CHAIN_SELECTOR, expectedNonce, abi.encode(sender)); + + assertEq(s_nonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR, abi.encode(sender)), 0); + } + + function test_incrementNoncesInboundAndOutbound_Success() public { + address sender = address(this); + + assertEq(s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, sender), 0); + uint64 outboundNonce = s_nonceManager.getIncrementedOutboundNonce(DEST_CHAIN_SELECTOR, sender); + assertEq(outboundNonce, 1); + + // Inbound nonce unchanged + assertEq(s_nonceManager.getInboundNonce(DEST_CHAIN_SELECTOR, abi.encode(sender)), 0); + + s_nonceManager.incrementInboundNonce(DEST_CHAIN_SELECTOR, 1, abi.encode(sender)); + assertEq(s_nonceManager.getInboundNonce(DEST_CHAIN_SELECTOR, abi.encode(sender)), 1); + + // Outbound nonce unchanged + assertEq(s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, sender), 1); + } +} + +contract NonceManager_applyPreviousRampsUpdates is EVM2EVMMultiOnRampSetup { + function test_SingleRampUpdate() public { + address prevOnRamp = makeAddr("prevOnRamp"); + address prevOffRamp = makeAddr("prevOffRamp"); + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + previousRamps[0] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(prevOnRamp, prevOffRamp)); + + vm.expectEmit(); + emit NonceManager.PreviousRampsUpdated(DEST_CHAIN_SELECTOR, previousRamps[0].prevRamps); + + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + _assertPreviousRampsEqual(s_outboundNonceManager.getPreviousRamps(DEST_CHAIN_SELECTOR), previousRamps[0].prevRamps); + } + + function test_MultipleRampsUpdates() public { + address prevOnRamp1 = makeAddr("prevOnRamp1"); + address prevOnRamp2 = makeAddr("prevOnRamp2"); + address prevOffRamp1 = makeAddr("prevOffRamp1"); + address prevOffRamp2 = makeAddr("prevOffRamp2"); + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](2); + previousRamps[0] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(prevOnRamp1, prevOffRamp1)); + previousRamps[1] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR + 1, NonceManager.PreviousRamps(prevOnRamp2, prevOffRamp2)); + + vm.expectEmit(); + emit NonceManager.PreviousRampsUpdated(DEST_CHAIN_SELECTOR, previousRamps[0].prevRamps); + vm.expectEmit(); + emit NonceManager.PreviousRampsUpdated(DEST_CHAIN_SELECTOR + 1, previousRamps[1].prevRamps); + + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + _assertPreviousRampsEqual(s_outboundNonceManager.getPreviousRamps(DEST_CHAIN_SELECTOR), previousRamps[0].prevRamps); + _assertPreviousRampsEqual( + s_outboundNonceManager.getPreviousRamps(DEST_CHAIN_SELECTOR + 1), previousRamps[1].prevRamps + ); + } + + function test_ZeroInput() public { + vm.recordLogs(); + s_outboundNonceManager.applyPreviousRampsUpdates(new NonceManager.PreviousRampsArgs[](0)); + + assertEq(vm.getRecordedLogs().length, 0); + } + + function test_PreviousRampAlreadySetOnRamp_Revert() public { + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + address prevOnRamp = makeAddr("prevOnRamp"); + previousRamps[0] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(prevOnRamp, address(0))); + + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + previousRamps[0] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(prevOnRamp, address(0))); + + vm.expectRevert(NonceManager.PreviousRampAlreadySet.selector); + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + } + + function test_PreviousRampAlreadySetOffRamp_Revert() public { + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + address prevOffRamp = makeAddr("prevOffRamp"); + previousRamps[0] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(address(0), prevOffRamp)); + + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + previousRamps[0] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(address(0), prevOffRamp)); + + vm.expectRevert(NonceManager.PreviousRampAlreadySet.selector); + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + } + + function test_PreviousRampAlreadySetOnRampAndOffRamp_Revert() public { + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + address prevOnRamp = makeAddr("prevOnRamp"); + address prevOffRamp = makeAddr("prevOffRamp"); + previousRamps[0] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(prevOnRamp, prevOffRamp)); + + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + previousRamps[0] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(prevOnRamp, prevOffRamp)); + + vm.expectRevert(NonceManager.PreviousRampAlreadySet.selector); + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + } + + function _assertPreviousRampsEqual( + NonceManager.PreviousRamps memory a, + NonceManager.PreviousRamps memory b + ) internal pure { + assertEq(a.prevOnRamp, b.prevOnRamp); + assertEq(a.prevOffRamp, b.prevOffRamp); + } +} + +contract NonceManager_OnRampUpgrade is EVM2EVMMultiOnRampSetup { + uint256 internal constant FEE_AMOUNT = 1234567890; + EVM2EVMOnRampHelper internal s_prevOnRamp; + + function setUp() public virtual override { + super.setUp(); + + EVM2EVMOnRamp.FeeTokenConfigArgs[] memory feeTokenConfigArgs = new EVM2EVMOnRamp.FeeTokenConfigArgs[](1); + feeTokenConfigArgs[0] = EVM2EVMOnRamp.FeeTokenConfigArgs({ + token: s_sourceFeeToken, + networkFeeUSDCents: 1_00, // 1 USD + gasMultiplierWeiPerEth: 1e18, // 1x + premiumMultiplierWeiPerEth: 5e17, // 0.5x + enabled: true + }); + + EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfig = + new EVM2EVMOnRamp.TokenTransferFeeConfigArgs[](1); + + tokenTransferFeeConfig[0] = EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ + token: s_sourceFeeToken, + minFeeUSDCents: 1_00, // 1 USD + maxFeeUSDCents: 1000_00, // 1,000 USD + deciBps: 2_5, // 2.5 bps, or 0.025% + destGasOverhead: 40_000, + destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES), + aggregateRateLimitEnabled: true + }); + + s_prevOnRamp = new EVM2EVMOnRampHelper( + EVM2EVMOnRamp.StaticConfig({ + linkToken: s_sourceTokens[0], + chainSelector: SOURCE_CHAIN_SELECTOR, + destChainSelector: DEST_CHAIN_SELECTOR, + defaultTxGasLimit: GAS_LIMIT, + maxNopFeesJuels: MAX_NOP_FEES_JUELS, + prevOnRamp: address(0), + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }), + EVM2EVMOnRamp.DynamicConfig({ + router: address(s_sourceRouter), + maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, + destGasOverhead: DEST_GAS_OVERHEAD, + destGasPerPayloadByte: DEST_GAS_PER_PAYLOAD_BYTE, + destDataAvailabilityOverheadGas: DEST_DATA_AVAILABILITY_OVERHEAD_GAS, + destGasPerDataAvailabilityByte: DEST_GAS_PER_DATA_AVAILABILITY_BYTE, + destDataAvailabilityMultiplierBps: DEST_GAS_DATA_AVAILABILITY_MULTIPLIER_BPS, + priceRegistry: address(s_priceRegistry), + maxDataBytes: MAX_DATA_SIZE, + maxPerMsgGasLimit: MAX_GAS_LIMIT, + defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, + defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, + defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, + enforceOutOfOrder: false + }), + RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e15}), + feeTokenConfigArgs, + tokenTransferFeeConfig, + new EVM2EVMOnRamp.NopAndWeight[](0) + ); + + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + previousRamps[0] = + NonceManager.PreviousRampsArgs(DEST_CHAIN_SELECTOR, NonceManager.PreviousRamps(address(s_prevOnRamp), address(0))); + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + (s_onRamp, s_metadataHash) = _deployOnRamp( + SOURCE_CHAIN_SELECTOR, address(s_sourceRouter), address(s_outboundNonceManager), address(s_tokenAdminRegistry) + ); + + vm.startPrank(address(s_sourceRouter)); + } + + function test_Upgrade_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, OWNER)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + } + + function test_UpgradeSenderNoncesReadsPreviousRamp_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + uint64 startNonce = s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); + + for (uint64 i = 1; i < 4; ++i) { + s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + assertEq(startNonce + i, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); + } + } + + function test_UpgradeNonceStartsAtV1Nonce_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint64 startNonce = s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); + + // send 1 message from previous onramp + s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + assertEq(startNonce + 1, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); + + // new onramp nonce should start from 2, while sequence number start from 1 + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested( + DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, startNonce + 2, FEE_AMOUNT, OWNER) + ); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + assertEq(startNonce + 2, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); + + // after another send, nonce should be 3, and sequence number be 2 + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested( + DEST_CHAIN_SELECTOR, _messageToEvent(message, 2, startNonce + 3, FEE_AMOUNT, OWNER) + ); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + assertEq(startNonce + 3, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); + } + + function test_UpgradeNonceNewSenderStartsAtZero_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + // send 1 message from previous onramp from OWNER + s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + address newSender = address(1234567); + // new onramp nonce should start from 1 for new sender + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested( + DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, newSender) + ); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, newSender); + } +} + +contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { + EVM2EVMOffRampHelper internal s_prevOffRamp; + EVM2EVMOffRampHelper[] internal s_nestedPrevOffRamps; + + address internal constant SINGLE_LANE_ON_RAMP_ADDRESS_1 = abi.decode(ON_RAMP_ADDRESS_1, (address)); + address internal constant SINGLE_LANE_ON_RAMP_ADDRESS_2 = abi.decode(ON_RAMP_ADDRESS_2, (address)); + address internal constant SINGLE_LANE_ON_RAMP_ADDRESS_3 = abi.decode(ON_RAMP_ADDRESS_3, (address)); + + function setUp() public virtual override { + super.setUp(); + + ICommitStore mockPrevCommitStore = new MockCommitStore(); + s_prevOffRamp = _deploySingleLaneOffRamp( + mockPrevCommitStore, s_destRouter, address(0), SOURCE_CHAIN_SELECTOR_1, SINGLE_LANE_ON_RAMP_ADDRESS_1 + ); + + s_nestedPrevOffRamps = new EVM2EVMOffRampHelper[](2); + s_nestedPrevOffRamps[0] = _deploySingleLaneOffRamp( + mockPrevCommitStore, s_destRouter, address(0), SOURCE_CHAIN_SELECTOR_2, SINGLE_LANE_ON_RAMP_ADDRESS_2 + ); + s_nestedPrevOffRamps[1] = _deploySingleLaneOffRamp( + mockPrevCommitStore, + s_destRouter, + address(s_nestedPrevOffRamps[0]), + SOURCE_CHAIN_SELECTOR_2, + SINGLE_LANE_ON_RAMP_ADDRESS_2 + ); + + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](3); + previousRamps[0] = NonceManager.PreviousRampsArgs( + SOURCE_CHAIN_SELECTOR_1, NonceManager.PreviousRamps(address(0), address(s_prevOffRamp)) + ); + previousRamps[1] = NonceManager.PreviousRampsArgs( + SOURCE_CHAIN_SELECTOR_2, NonceManager.PreviousRamps(address(0), address(s_nestedPrevOffRamps[1])) + ); + previousRamps[2] = NonceManager.PreviousRampsArgs( + SOURCE_CHAIN_SELECTOR_3, NonceManager.PreviousRamps(SINGLE_LANE_ON_RAMP_ADDRESS_3, address(0)) + ); + s_inboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](3); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + isEnabled: true, + onRamp: ON_RAMP_ADDRESS_1 + }); + sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_2, + isEnabled: true, + onRamp: ON_RAMP_ADDRESS_2 + }); + sourceChainConfigs[2] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_3, + isEnabled: true, + onRamp: ON_RAMP_ADDRESS_3 + }); + + _setupMultipleOffRampsFromConfigs(sourceChainConfigs); + + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 1); + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_3, 1); + } + + function test_Upgraded_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + } + + function test_NoPrevOffRampForChain_Success() public { + Internal.EVM2EVMMessage[] memory messages = + _generateSingleLaneSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, SINGLE_LANE_ON_RAMP_ADDRESS_1); + uint64 startNonceChain3 = + s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, abi.encode(messages[0].sender)); + s_prevOffRamp.execute(_generateSingleLaneRampReportFromMessages(messages), new uint256[](0)); + + // Nonce unchanged for chain 3 + assertEq( + startNonceChain3, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, abi.encode(messages[0].sender)) + ); + + Internal.Any2EVMRampMessage[] memory messagesChain3 = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_3, ON_RAMP_ADDRESS_3); + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_3, + messagesChain3[0].header.sequenceNumber, + messagesChain3[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messagesChain3), new uint256[](0) + ); + assertEq( + startNonceChain3 + 1, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, messagesChain3[0].sender) + ); + } + + function test_UpgradedSenderNoncesReadsPreviousRamp_Success() public { + Internal.EVM2EVMMessage[] memory messages = + _generateSingleLaneSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, SINGLE_LANE_ON_RAMP_ADDRESS_1); + uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(messages[0].sender)); + + for (uint64 i = 1; i < 4; ++i) { + s_prevOffRamp.execute(_generateSingleLaneRampReportFromMessages(messages), new uint256[](0)); + + // messages contains a single message - update for the next execution + messages[0].nonce++; + messages[0].sequenceNumber++; + messages[0].messageId = Internal._hash(messages[0], s_prevOffRamp.metadataHash()); + + assertEq( + startNonce + i, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(messages[0].sender)) + ); + } + } + + function test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() public { + Internal.EVM2EVMMessage[] memory messages = + _generateSingleLaneSingleBasicMessage(SOURCE_CHAIN_SELECTOR_2, SINGLE_LANE_ON_RAMP_ADDRESS_2); + uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_2, abi.encode(messages[0].sender)); + + for (uint64 i = 1; i < 4; ++i) { + s_nestedPrevOffRamps[0].execute(_generateSingleLaneRampReportFromMessages(messages), new uint256[](0)); + + // messages contains a single message - update for the next execution + messages[0].nonce++; + messages[0].sequenceNumber++; + messages[0].messageId = Internal._hash(messages[0], s_nestedPrevOffRamps[0].metadataHash()); + + // Read through prev sender nonce through prevOffRamp -> prevPrevOffRamp + assertEq( + startNonce + i, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_2, abi.encode(messages[0].sender)) + ); + } + } + + function test_UpgradedNonceStartsAtV1Nonce_Success() public { + Internal.EVM2EVMMessage[] memory messages = + _generateSingleLaneSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, SINGLE_LANE_ON_RAMP_ADDRESS_1); + + uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(messages[0].sender)); + s_prevOffRamp.execute(_generateSingleLaneRampReportFromMessages(messages), new uint256[](0)); + + assertEq( + startNonce + 1, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(messages[0].sender)) + ); + + Internal.Any2EVMRampMessage[] memory messagesMultiRamp = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + messagesMultiRamp[0].header.nonce++; + messagesMultiRamp[0].header.messageId = Internal._hash(messagesMultiRamp[0], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messagesMultiRamp[0].header.sequenceNumber, + messagesMultiRamp[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new uint256[](0) + ); + assertEq( + startNonce + 2, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].sender) + ); + + messagesMultiRamp[0].header.nonce++; + messagesMultiRamp[0].header.sequenceNumber++; + messagesMultiRamp[0].header.messageId = Internal._hash(messagesMultiRamp[0], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messagesMultiRamp[0].header.sequenceNumber, + messagesMultiRamp[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new uint256[](0) + ); + assertEq( + startNonce + 3, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].sender) + ); + } + + function test_UpgradedNonceNewSenderStartsAtZero_Success() public { + Internal.EVM2EVMMessage[] memory messages = + _generateSingleLaneSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, SINGLE_LANE_ON_RAMP_ADDRESS_1); + + s_prevOffRamp.execute(_generateSingleLaneRampReportFromMessages(messages), new uint256[](0)); + + Internal.Any2EVMRampMessage[] memory messagesMultiRamp = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + bytes memory newSender = abi.encode(address(1234567)); + messagesMultiRamp[0].sender = newSender; + messagesMultiRamp[0].header.messageId = Internal._hash(messagesMultiRamp[0], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messagesMultiRamp[0].header.sequenceNumber, + messagesMultiRamp[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + // new sender nonce in new offramp should go from 0 -> 1 + assertEq(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, newSender), 0); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new uint256[](0) + ); + assertEq(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, newSender), 1); + } + + function test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + address newSender = address(1234567); + messages[0].sender = abi.encode(newSender); + messages[0].header.nonce = 2; + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); + + // new offramp sees msg nonce higher than senderNonce + // it waits for previous offramp to execute + vm.expectEmit(); + emit NonceManager.SkippedIncorrectNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].header.nonce, messages[0].sender); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertEq(startNonce, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender)); + + Internal.EVM2EVMMessage[] memory messagesSingleLane = + _generateSingleLaneSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, SINGLE_LANE_ON_RAMP_ADDRESS_1); + + messagesSingleLane[0].nonce = 1; + messagesSingleLane[0].sender = newSender; + messagesSingleLane[0].messageId = Internal._hash(messagesSingleLane[0], s_prevOffRamp.metadataHash()); + + // previous offramp executes msg and increases nonce + s_prevOffRamp.execute(_generateSingleLaneRampReportFromMessages(messagesSingleLane), new uint256[](0)); + assertEq( + startNonce + 1, + s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(messagesSingleLane[0].sender)) + ); + + messages[0].header.nonce = 2; + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + // new offramp is able to execute + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertEq(startNonce + 2, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender)); + } + + function _generateSingleLaneRampReportFromMessages(Internal.EVM2EVMMessage[] memory messages) + internal + pure + returns (Internal.ExecutionReport memory) + { + bytes[][] memory offchainTokenData = new bytes[][](messages.length); + + for (uint256 i = 0; i < messages.length; ++i) { + offchainTokenData[i] = new bytes[](messages[i].tokenAmounts.length); + } + + return Internal.ExecutionReport({ + proofs: new bytes32[](0), + proofFlagBits: 2 ** 256 - 1, + messages: messages, + offchainTokenData: offchainTokenData + }); + } + + function _generateSingleLaneSingleBasicMessage( + uint64 sourceChainSelector, + address onRamp + ) internal view returns (Internal.EVM2EVMMessage[] memory) { + Internal.EVM2EVMMessage[] memory messages = new Internal.EVM2EVMMessage[](1); + + bytes memory data = abi.encode(0); + messages[0] = Internal.EVM2EVMMessage({ + sequenceNumber: 1, + sender: OWNER, + nonce: 1, + gasLimit: GAS_LIMIT, + strict: false, + sourceChainSelector: sourceChainSelector, + receiver: address(s_receiver), + data: data, + tokenAmounts: new Client.EVMTokenAmount[](0), + sourceTokenData: new bytes[](0), + feeToken: s_destFeeToken, + feeTokenAmount: uint256(0), + messageId: "" + }); + + messages[0].messageId = Internal._hash( + messages[0], + keccak256(abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, sourceChainSelector, DEST_CHAIN_SELECTOR, onRamp)) + ); + + return messages; + } +} diff --git a/contracts/src/v0.8/ccip/test/README.md b/contracts/src/v0.8/ccip/test/README.md new file mode 100644 index 0000000000..99223e1a63 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/README.md @@ -0,0 +1,89 @@ +# Foundry Test Guidelines + +We're using Foundry to test our CCIP smart contracts here. This enables us to test in Solidity. If you need to add tests for anything outside the CCIP contracts, please write them in hardhat (for the time being). + +## Directory Structure + +The test directory structure mimics the source contract file structure as closely as possible. Example: + +`./offRamp/SomeOffRamp.sol` should have a test contract `./test/offRamp/SomeOffRamp.t.sol`. + +## Test File Structure + +Break the test file down into multiple contracts, each contract testing a specific function inside the source contract. + +For Example, here's a source contract `SomeOffRamp`: + +``` +contract SomeOffRamp { + + constructor() { + ... set some state + } + + function firstFunction() public { + ... + } + + function theNextFunction() public { + ... + } + + function _anInternalFunction() internal { + ... + } +} +``` + +Our test file `SomeOffRamp.t.sol` should be structured like this: + +``` +contract SomeOffRamp_constructor { + // constructor state setup tests here +} + +contract SomeOffRamp_firstFunction { + // first function tests here +} + +contract SomeOffRamp_theNextFunction { + // tests here too... +} + +contract SomeOffRamp_anInternalFunction { + // This function will require a helper contract to expose it. +} +``` + +## Test Structure + +Inside each test contract, group tests into `Success` and `Reverts` by starting with all the success cases and then adding a `// Reverts` comments to indicate the failure cases below. + +``` +contract SomeOffRamp_firstFunction { + function testZeroValueSuccess() public { + ... + } + + ... + + + // Reverts + + function testOwnerReverts() public { + // test that an ownable function reverts when not called by the owner + ... + } + + ... + +} +``` + +Function naming should follow this structure, where the `_fuzz_` section denotes whether it's a fuzz test. Do not write tests that are named `testSuccess`, always include the description of the test, even if it's just the name of the function that is being called. + +`test{_fuzz_}{description of test}[Success|Reverts]` + +Try to cover all the code paths present in each function being tested. In most cases, this will result in many more failure tests than success tests. + +If a test file requires a complicated setUp, or if it requires many helper functions (like `_generateAMessageWithNoTokensStruct()`), create a separate file to perform this setup in. Using the example above, `SomeOffRampSetup.t.sol`. Inherit this and call the setUp function in the test file. diff --git a/contracts/src/v0.8/ccip/test/TokenSetup.t.sol b/contracts/src/v0.8/ccip/test/TokenSetup.t.sol new file mode 100644 index 0000000000..182d92c5c9 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/TokenSetup.t.sol @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IPoolV1} from "../interfaces/IPool.sol"; + +import {BurnMintERC677} from "../../shared/token/ERC677/BurnMintERC677.sol"; +import {Client} from "../libraries/Client.sol"; +import {BurnMintTokenPool} from "../pools/BurnMintTokenPool.sol"; +import {LockReleaseTokenPool} from "../pools/LockReleaseTokenPool.sol"; +import {TokenPool} from "../pools/TokenPool.sol"; +import {TokenAdminRegistry} from "../tokenAdminRegistry/TokenAdminRegistry.sol"; +import {MaybeRevertingBurnMintTokenPool} from "./helpers/MaybeRevertingBurnMintTokenPool.sol"; +import {RouterSetup} from "./router/RouterSetup.t.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract TokenSetup is RouterSetup { + address[] internal s_sourceTokens; + address[] internal s_destTokens; + + address internal s_sourceFeeToken; + address internal s_destFeeToken; + + TokenAdminRegistry internal s_tokenAdminRegistry; + + mapping(address sourceToken => address sourcePool) internal s_sourcePoolByToken; + mapping(address sourceToken => address destPool) internal s_destPoolBySourceToken; + mapping(address destToken => address destPool) internal s_destPoolByToken; + mapping(address sourceToken => address destToken) internal s_destTokenBySourceToken; + + function _deploySourceToken(string memory tokenName, uint256 dealAmount, uint8 decimals) internal returns (address) { + BurnMintERC677 token = new BurnMintERC677(tokenName, tokenName, decimals, 0); + s_sourceTokens.push(address(token)); + deal(address(token), OWNER, dealAmount); + return address(token); + } + + function _deployDestToken(string memory tokenName, uint256 dealAmount) internal returns (address) { + BurnMintERC677 token = new BurnMintERC677(tokenName, tokenName, 18, 0); + s_destTokens.push(address(token)); + deal(address(token), OWNER, dealAmount); + return address(token); + } + + function _deployLockReleasePool(address token, bool isSourcePool) internal { + address router = address(s_sourceRouter); + if (!isSourcePool) { + router = address(s_destRouter); + } + + LockReleaseTokenPool pool = + new LockReleaseTokenPool(IERC20(token), new address[](0), address(s_mockRMN), true, router); + + if (isSourcePool) { + s_sourcePoolByToken[address(token)] = address(pool); + } else { + s_destPoolByToken[address(token)] = address(pool); + s_destPoolBySourceToken[s_sourceTokens[s_destTokens.length - 1]] = address(pool); + } + } + + function _deployTokenAndBurnMintPool(address token, bool isSourcePool) internal { + address router = address(s_sourceRouter); + if (!isSourcePool) { + router = address(s_destRouter); + } + + BurnMintTokenPool pool = + new MaybeRevertingBurnMintTokenPool(BurnMintERC677(token), new address[](0), address(s_mockRMN), router); + BurnMintERC677(token).grantMintAndBurnRoles(address(pool)); + + if (isSourcePool) { + s_sourcePoolByToken[address(token)] = address(pool); + } else { + s_destPoolByToken[address(token)] = address(pool); + s_destPoolBySourceToken[s_sourceTokens[s_destTokens.length - 1]] = address(pool); + } + } + + function setUp() public virtual override { + RouterSetup.setUp(); + + bool isSetup = s_sourceTokens.length != 0; + if (isSetup) { + return; + } + + // Source tokens & pools + address sourceLink = _deploySourceToken("sLINK", type(uint256).max, 18); + _deployLockReleasePool(sourceLink, true); + s_sourceFeeToken = sourceLink; + + address sourceEth = _deploySourceToken("sETH", 2 ** 128, 18); + _deployTokenAndBurnMintPool(sourceEth, true); + + // Destination tokens & pools + address destLink = _deployDestToken("dLINK", type(uint256).max); + _deployLockReleasePool(destLink, false); + s_destFeeToken = destLink; + + s_destTokenBySourceToken[sourceLink] = destLink; + + address destEth = _deployDestToken("dETH", 2 ** 128); + _deployTokenAndBurnMintPool(destEth, false); + + s_destTokenBySourceToken[sourceEth] = destEth; + + // Float the dest link lock release pool with funds + IERC20(destLink).transfer(s_destPoolByToken[destLink], 1000 ether); + + s_tokenAdminRegistry = new TokenAdminRegistry(); + + // Set pools in the registry + for (uint256 i = 0; i < s_sourceTokens.length; ++i) { + address token = s_sourceTokens[i]; + address pool = s_sourcePoolByToken[token]; + + _setPool( + s_tokenAdminRegistry, token, pool, DEST_CHAIN_SELECTOR, s_destPoolByToken[s_destTokens[i]], s_destTokens[i] + ); + } + + for (uint256 i = 0; i < s_destTokens.length; ++i) { + address token = s_destTokens[i]; + address pool = s_destPoolByToken[token]; + s_tokenAdminRegistry.proposeAdministrator(token, OWNER); + s_tokenAdminRegistry.acceptAdminRole(token); + s_tokenAdminRegistry.setPool(token, pool); + + _setPool( + s_tokenAdminRegistry, + token, + pool, + SOURCE_CHAIN_SELECTOR, + s_sourcePoolByToken[s_sourceTokens[i]], + s_sourceTokens[i] + ); + } + } + + function getCastedSourceEVMTokenAmountsWithZeroAmounts() + internal + view + returns (Client.EVMTokenAmount[] memory tokenAmounts) + { + tokenAmounts = new Client.EVMTokenAmount[](s_sourceTokens.length); + for (uint256 i = 0; i < tokenAmounts.length; ++i) { + tokenAmounts[i].token = s_sourceTokens[i]; + } + } + + function _setPool( + TokenAdminRegistry tokenAdminRegistry, + address token, + address pool, + uint64 remoteChainSelector, + address remotePoolAddress, + address remoteToken + ) internal { + if (!tokenAdminRegistry.isAdministrator(token, OWNER)) { + tokenAdminRegistry.proposeAdministrator(token, OWNER); + tokenAdminRegistry.acceptAdminRole(token); + } + + tokenAdminRegistry.setPool(token, pool); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: remoteChainSelector, + remotePoolAddress: abi.encode(remotePoolAddress), + remoteTokenAddress: abi.encode(remoteToken), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + + TokenPool(pool).applyChainUpdates(chainUpdates); + } +} diff --git a/contracts/src/v0.8/ccip/test/WETH9.sol b/contracts/src/v0.8/ccip/test/WETH9.sol new file mode 100644 index 0000000000..fbc19ee2c4 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/WETH9.sol @@ -0,0 +1,82 @@ +// Submitted for verification at Etherscan.io on 2017-12-12 + +// Copyright (C) 2015, 2016, 2017 Dapphub + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +pragma solidity 0.8.24; + +// solhint-disable +contract WETH9 { + string public name = "Wrapped Ether"; + string public symbol = "WETH"; + uint8 public decimals = 18; + + event Approval(address indexed src, address indexed guy, uint256 wad); + event Transfer(address indexed src, address indexed dst, uint256 wad); + event Deposit(address indexed dst, uint256 wad); + event Withdrawal(address indexed src, uint256 wad); + + mapping(address => uint256) public balanceOf; + mapping(address => mapping(address => uint256)) public allowance; + + receive() external payable { + _deposit(); + } + + function _deposit() internal { + balanceOf[msg.sender] += msg.value; + emit Deposit(msg.sender, msg.value); + } + + function deposit() external payable { + _deposit(); + } + + function withdraw(uint256 wad) external { + require(balanceOf[msg.sender] >= wad); + balanceOf[msg.sender] -= wad; + payable(msg.sender).transfer(wad); + emit Withdrawal(msg.sender, wad); + } + + function totalSupply() public view returns (uint256) { + return address(this).balance; + } + + function approve(address guy, uint256 wad) public returns (bool) { + allowance[msg.sender][guy] = wad; + emit Approval(msg.sender, guy, wad); + return true; + } + + function transfer(address dst, uint256 wad) public returns (bool) { + return transferFrom(msg.sender, dst, wad); + } + + function transferFrom(address src, address dst, uint256 wad) public returns (bool) { + require(balanceOf[src] >= wad); + + if (src != msg.sender && allowance[src][msg.sender] != type(uint128).max) { + require(allowance[src][msg.sender] >= wad); + allowance[src][msg.sender] -= wad; + } + + balanceOf[src] -= wad; + balanceOf[dst] += wad; + + emit Transfer(src, dst, wad); + + return true; + } +} diff --git a/contracts/src/v0.8/ccip/test/applications/DefensiveExample.t.sol b/contracts/src/v0.8/ccip/test/applications/DefensiveExample.t.sol new file mode 100644 index 0000000000..18453f9f52 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/applications/DefensiveExample.t.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {DefensiveExample} from "../../applications/DefensiveExample.sol"; +import {Client} from "../../libraries/Client.sol"; +import {EVM2EVMOnRampSetup} from "../onRamp/EVM2EVMOnRampSetup.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract DefensiveExampleTest is EVM2EVMOnRampSetup { + event MessageFailed(bytes32 indexed messageId, bytes reason); + event MessageSucceeded(bytes32 indexed messageId); + event MessageRecovered(bytes32 indexed messageId); + + DefensiveExample internal s_receiver; + uint64 internal sourceChainSelector = 7331; + + function setUp() public virtual override { + EVM2EVMOnRampSetup.setUp(); + + s_receiver = new DefensiveExample(s_destRouter, IERC20(s_destFeeToken)); + s_receiver.enableChain(sourceChainSelector, abi.encode("")); + } + + function test_Recovery() public { + bytes32 messageId = keccak256("messageId"); + address token = address(s_destFeeToken); + uint256 amount = 111333333777; + Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](1); + destTokenAmounts[0] = Client.EVMTokenAmount({token: token, amount: amount}); + + // Make sure we give the receiver contract enough tokens like CCIP would. + deal(token, address(s_receiver), amount); + + // Make sure the contract call reverts so we can test recovery. + s_receiver.setSimRevert(true); + + // The receiver contract will revert if the router is not the sender. + vm.startPrank(address(s_destRouter)); + + vm.expectEmit(); + emit MessageFailed(messageId, abi.encodeWithSelector(DefensiveExample.ErrorCase.selector)); + + s_receiver.ccipReceive( + Client.Any2EVMMessage({ + messageId: messageId, + sourceChainSelector: sourceChainSelector, + sender: abi.encode(address(0)), // wrong sender, will revert internally + data: "", + destTokenAmounts: destTokenAmounts + }) + ); + + address tokenReceiver = address(0x000001337); + uint256 tokenReceiverBalancePre = IERC20(token).balanceOf(tokenReceiver); + uint256 receiverBalancePre = IERC20(token).balanceOf(address(s_receiver)); + + // Recovery can only be done by the owner. + vm.startPrank(OWNER); + + vm.expectEmit(); + emit MessageRecovered(messageId); + + s_receiver.retryFailedMessage(messageId, tokenReceiver); + + // Assert the tokens have successfully been rescued from the contract. + assertEq(IERC20(token).balanceOf(tokenReceiver), tokenReceiverBalancePre + amount); + assertEq(IERC20(token).balanceOf(address(s_receiver)), receiverBalancePre - amount); + } + + function test_HappyPath_Success() public { + bytes32 messageId = keccak256("messageId"); + address token = address(s_destFeeToken); + uint256 amount = 111333333777; + Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](1); + destTokenAmounts[0] = Client.EVMTokenAmount({token: token, amount: amount}); + + // Make sure we give the receiver contract enough tokens like CCIP would. + deal(token, address(s_receiver), amount); + + // The receiver contract will revert if the router is not the sender. + vm.startPrank(address(s_destRouter)); + + vm.expectEmit(); + emit MessageSucceeded(messageId); + + s_receiver.ccipReceive( + Client.Any2EVMMessage({ + messageId: messageId, + sourceChainSelector: sourceChainSelector, + sender: abi.encode(address(s_receiver)), // correct sender + data: "", + destTokenAmounts: destTokenAmounts + }) + ); + } +} diff --git a/contracts/src/v0.8/ccip/test/applications/EtherSenderReceiver.t.sol b/contracts/src/v0.8/ccip/test/applications/EtherSenderReceiver.t.sol new file mode 100644 index 0000000000..cfd402d910 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/applications/EtherSenderReceiver.t.sol @@ -0,0 +1,718 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Test} from "forge-std/Test.sol"; + +import {CCIPRouter} from "../../applications/EtherSenderReceiver.sol"; + +import {IRouterClient} from "../../interfaces/IRouterClient.sol"; +import {Client} from "../../libraries/Client.sol"; +import {WETH9} from "../WETH9.sol"; +import {EtherSenderReceiverHelper} from "./../helpers/EtherSenderReceiverHelper.sol"; + +import {ERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/ERC20.sol"; + +contract EtherSenderReceiverTest is Test { + EtherSenderReceiverHelper internal s_etherSenderReceiver; + WETH9 internal s_weth; + WETH9 internal s_someOtherWeth; + ERC20 internal s_linkToken; + + address internal constant OWNER = 0x00007e64E1fB0C487F25dd6D3601ff6aF8d32e4e; + address internal constant ROUTER = 0x0F3779ee3a832D10158073ae2F5e61ac7FBBF880; + address internal constant XCHAIN_RECEIVER = 0xBd91b2073218AF872BF73b65e2e5950ea356d147; + + function setUp() public { + vm.startPrank(OWNER); + + s_linkToken = new ERC20("Chainlink Token", "LINK"); + s_someOtherWeth = new WETH9(); + s_weth = new WETH9(); + vm.mockCall(ROUTER, abi.encodeWithSelector(CCIPRouter.getWrappedNative.selector), abi.encode(address(s_weth))); + s_etherSenderReceiver = new EtherSenderReceiverHelper(ROUTER); + + deal(OWNER, 1_000_000 ether); + deal(address(s_linkToken), OWNER, 1_000_000 ether); + + // deposit some eth into the weth contract. + s_weth.deposit{value: 10 ether}(); + uint256 wethSupply = s_weth.totalSupply(); + assertEq(wethSupply, 10 ether, "total weth supply must be 10 ether"); + } +} + +contract EtherSenderReceiverTest_constructor is EtherSenderReceiverTest { + function test_constructor() public view { + assertEq(s_etherSenderReceiver.getRouter(), ROUTER, "router must be set correctly"); + uint256 allowance = s_weth.allowance(address(s_etherSenderReceiver), ROUTER); + assertEq(allowance, type(uint256).max, "allowance must be set infinite"); + } +} + +contract EtherSenderReceiverTest_validateFeeToken is EtherSenderReceiverTest { + uint256 internal constant amount = 100; + + error InsufficientMsgValue(uint256 gotAmount, uint256 msgValue); + error TokenAmountNotEqualToMsgValue(uint256 gotAmount, uint256 msgValue); + + function test_validateFeeToken_valid_native() public { + Client.EVMTokenAmount[] memory tokenAmount = new Client.EVMTokenAmount[](1); + tokenAmount[0] = Client.EVMTokenAmount({token: address(s_weth), amount: amount}); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmount, + feeToken: address(0), + extraArgs: "" + }); + + s_etherSenderReceiver.validateFeeToken{value: amount + 1}(message); + } + + function test_validateFeeToken_valid_feeToken() public { + Client.EVMTokenAmount[] memory tokenAmount = new Client.EVMTokenAmount[](1); + tokenAmount[0] = Client.EVMTokenAmount({token: address(s_weth), amount: amount}); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmount, + feeToken: address(s_weth), + extraArgs: "" + }); + + s_etherSenderReceiver.validateFeeToken{value: amount}(message); + } + + function test_validateFeeToken_reverts_feeToken_tokenAmountNotEqualToMsgValue() public { + Client.EVMTokenAmount[] memory tokenAmount = new Client.EVMTokenAmount[](1); + tokenAmount[0] = Client.EVMTokenAmount({token: address(s_weth), amount: amount}); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmount, + feeToken: address(s_weth), + extraArgs: "" + }); + + vm.expectRevert(abi.encodeWithSelector(TokenAmountNotEqualToMsgValue.selector, amount, amount + 1)); + s_etherSenderReceiver.validateFeeToken{value: amount + 1}(message); + } +} + +contract EtherSenderReceiverTest_validatedMessage is EtherSenderReceiverTest { + error InvalidDestinationReceiver(bytes destReceiver); + error InvalidTokenAmounts(uint256 gotAmounts); + error InvalidWethAddress(address want, address got); + error GasLimitTooLow(uint256 minLimit, uint256 gotLimit); + + uint256 internal constant amount = 100; + + function test_Fuzz_validatedMessage_msgSenderOverwrite(bytes memory data) public view { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: data, + tokenAmounts: tokenAmounts, + feeToken: address(0), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + assertEq(validatedMessage.receiver, abi.encode(XCHAIN_RECEIVER), "receiver must be XCHAIN_RECEIVER"); + assertEq(validatedMessage.data, abi.encode(OWNER), "data must be msg.sender"); + assertEq(validatedMessage.tokenAmounts[0].token, address(s_weth), "token must be weth"); + assertEq(validatedMessage.tokenAmounts[0].amount, amount, "amount must be correct"); + assertEq(validatedMessage.feeToken, address(0), "feeToken must be 0"); + assertEq(validatedMessage.extraArgs, bytes(""), "extraArgs must be empty"); + } + + function test_Fuzz_validatedMessage_tokenAddressOverwrite(address token) public view { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({token: token, amount: amount}); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(0), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + assertEq(validatedMessage.receiver, abi.encode(XCHAIN_RECEIVER), "receiver must be XCHAIN_RECEIVER"); + assertEq(validatedMessage.data, abi.encode(OWNER), "data must be msg.sender"); + assertEq(validatedMessage.tokenAmounts[0].token, address(s_weth), "token must be weth"); + assertEq(validatedMessage.tokenAmounts[0].amount, amount, "amount must be correct"); + assertEq(validatedMessage.feeToken, address(0), "feeToken must be 0"); + assertEq(validatedMessage.extraArgs, bytes(""), "extraArgs must be empty"); + } + + function test_validatedMessage_emptyDataOverwrittenToMsgSender() public view { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(0), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + assertEq(validatedMessage.receiver, abi.encode(XCHAIN_RECEIVER), "receiver must be XCHAIN_RECEIVER"); + assertEq(validatedMessage.data, abi.encode(OWNER), "data must be msg.sender"); + assertEq(validatedMessage.tokenAmounts[0].token, address(s_weth), "token must be weth"); + assertEq(validatedMessage.tokenAmounts[0].amount, amount, "amount must be correct"); + assertEq(validatedMessage.feeToken, address(0), "feeToken must be 0"); + assertEq(validatedMessage.extraArgs, bytes(""), "extraArgs must be empty"); + } + + function test_validatedMessage_dataOverwrittenToMsgSender() public view { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: abi.encode(address(42)), + tokenAmounts: tokenAmounts, + feeToken: address(0), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + assertEq(validatedMessage.receiver, abi.encode(XCHAIN_RECEIVER), "receiver must be XCHAIN_RECEIVER"); + assertEq(validatedMessage.data, abi.encode(OWNER), "data must be msg.sender"); + assertEq(validatedMessage.tokenAmounts[0].token, address(s_weth), "token must be weth"); + assertEq(validatedMessage.tokenAmounts[0].amount, amount, "amount must be correct"); + assertEq(validatedMessage.feeToken, address(0), "feeToken must be 0"); + assertEq(validatedMessage.extraArgs, bytes(""), "extraArgs must be empty"); + } + + function test_validatedMessage_tokenOverwrittenToWeth() public view { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(42), // incorrect token. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(0), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + assertEq(validatedMessage.receiver, abi.encode(XCHAIN_RECEIVER), "receiver must be XCHAIN_RECEIVER"); + assertEq(validatedMessage.data, abi.encode(OWNER), "data must be msg.sender"); + assertEq(validatedMessage.tokenAmounts[0].token, address(s_weth), "token must be weth"); + assertEq(validatedMessage.tokenAmounts[0].amount, amount, "amount must be correct"); + assertEq(validatedMessage.feeToken, address(0), "feeToken must be 0"); + assertEq(validatedMessage.extraArgs, bytes(""), "extraArgs must be empty"); + } + + function test_validatedMessage_validMessage_extraArgs() public view { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(0), + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000})) + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + assertEq(validatedMessage.receiver, abi.encode(XCHAIN_RECEIVER), "receiver must be XCHAIN_RECEIVER"); + assertEq(validatedMessage.data, abi.encode(OWNER), "data must be msg.sender"); + assertEq(validatedMessage.tokenAmounts[0].token, address(s_weth), "token must be weth"); + assertEq(validatedMessage.tokenAmounts[0].amount, amount, "amount must be correct"); + assertEq(validatedMessage.feeToken, address(0), "feeToken must be 0"); + assertEq( + validatedMessage.extraArgs, + Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000})), + "extraArgs must be correct" + ); + } + + function test_validatedMessage_invalidTokenAmounts() public { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: address(0), amount: amount}); + tokenAmounts[1] = Client.EVMTokenAmount({token: address(0), amount: amount}); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(0), + extraArgs: "" + }); + + vm.expectRevert(abi.encodeWithSelector(InvalidTokenAmounts.selector, uint256(2))); + s_etherSenderReceiver.validatedMessage(message); + } +} + +contract EtherSenderReceiverTest_getFee is EtherSenderReceiverTest { + uint64 internal constant destinationChainSelector = 424242; + uint256 internal constant feeWei = 121212; + uint256 internal constant amount = 100; + + function test_getFee() public { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({token: address(0), amount: amount}); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(0), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.getFee.selector, destinationChainSelector, validatedMessage), + abi.encode(feeWei) + ); + + uint256 fee = s_etherSenderReceiver.getFee(destinationChainSelector, message); + assertEq(fee, feeWei, "fee must be feeWei"); + } +} + +contract EtherSenderReceiverTest_ccipReceive is EtherSenderReceiverTest { + uint256 internal constant amount = 100; + uint64 internal constant sourceChainSelector = 424242; + address internal constant XCHAIN_SENDER = 0x9951529C13B01E542f7eE3b6D6665D292e9BA2E0; + + error InvalidTokenAmounts(uint256 gotAmounts); + error InvalidToken(address gotToken, address expectedToken); + + function test_Fuzz_ccipReceive(uint256 tokenAmount) public { + // cap to 10 ether because OWNER only has 10 ether. + if (tokenAmount > 10 ether) { + return; + } + + Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](1); + destTokenAmounts[0] = Client.EVMTokenAmount({token: address(s_weth), amount: tokenAmount}); + Client.Any2EVMMessage memory message = Client.Any2EVMMessage({ + messageId: keccak256(abi.encode("ccip send")), + sourceChainSelector: sourceChainSelector, + sender: abi.encode(XCHAIN_SENDER), + data: abi.encode(OWNER), + destTokenAmounts: destTokenAmounts + }); + + // simulate a cross-chain token transfer, just transfer the weth to s_etherSenderReceiver. + s_weth.transfer(address(s_etherSenderReceiver), tokenAmount); + + uint256 balanceBefore = OWNER.balance; + s_etherSenderReceiver.publicCcipReceive(message); + uint256 balanceAfter = OWNER.balance; + assertEq(balanceAfter, balanceBefore + tokenAmount, "balance must be correct"); + } + + function test_ccipReceive_happyPath() public { + Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](1); + destTokenAmounts[0] = Client.EVMTokenAmount({token: address(s_weth), amount: amount}); + Client.Any2EVMMessage memory message = Client.Any2EVMMessage({ + messageId: keccak256(abi.encode("ccip send")), + sourceChainSelector: 424242, + sender: abi.encode(XCHAIN_SENDER), + data: abi.encode(OWNER), + destTokenAmounts: destTokenAmounts + }); + + // simulate a cross-chain token transfer, just transfer the weth to s_etherSenderReceiver. + s_weth.transfer(address(s_etherSenderReceiver), amount); + + uint256 balanceBefore = OWNER.balance; + s_etherSenderReceiver.publicCcipReceive(message); + uint256 balanceAfter = OWNER.balance; + assertEq(balanceAfter, balanceBefore + amount, "balance must be correct"); + } + + function test_ccipReceive_fallbackToWethTransfer() public { + Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](1); + destTokenAmounts[0] = Client.EVMTokenAmount({token: address(s_weth), amount: amount}); + Client.Any2EVMMessage memory message = Client.Any2EVMMessage({ + messageId: keccak256(abi.encode("ccip send")), + sourceChainSelector: 424242, + sender: abi.encode(XCHAIN_SENDER), + data: abi.encode(address(s_linkToken)), // ERC20 cannot receive() ether. + destTokenAmounts: destTokenAmounts + }); + + // simulate a cross-chain token transfer, just transfer the weth to s_etherSenderReceiver. + s_weth.transfer(address(s_etherSenderReceiver), amount); + + uint256 balanceBefore = address(s_linkToken).balance; + s_etherSenderReceiver.publicCcipReceive(message); + uint256 balanceAfter = address(s_linkToken).balance; + assertEq(balanceAfter, balanceBefore, "balance must be unchanged"); + uint256 wethBalance = s_weth.balanceOf(address(s_linkToken)); + assertEq(wethBalance, amount, "weth balance must be correct"); + } + + function test_ccipReceive_wrongTokenAmount() public { + Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](2); + destTokenAmounts[0] = Client.EVMTokenAmount({token: address(s_weth), amount: amount}); + destTokenAmounts[1] = Client.EVMTokenAmount({token: address(s_weth), amount: amount}); + Client.Any2EVMMessage memory message = Client.Any2EVMMessage({ + messageId: keccak256(abi.encode("ccip send")), + sourceChainSelector: 424242, + sender: abi.encode(XCHAIN_SENDER), + data: abi.encode(OWNER), + destTokenAmounts: destTokenAmounts + }); + + vm.expectRevert(abi.encodeWithSelector(InvalidTokenAmounts.selector, uint256(2))); + s_etherSenderReceiver.publicCcipReceive(message); + } + + function test_ccipReceive_wrongToken() public { + Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](1); + destTokenAmounts[0] = Client.EVMTokenAmount({token: address(s_someOtherWeth), amount: amount}); + Client.Any2EVMMessage memory message = Client.Any2EVMMessage({ + messageId: keccak256(abi.encode("ccip send")), + sourceChainSelector: 424242, + sender: abi.encode(XCHAIN_SENDER), + data: abi.encode(OWNER), + destTokenAmounts: destTokenAmounts + }); + + vm.expectRevert(abi.encodeWithSelector(InvalidToken.selector, address(s_someOtherWeth), address(s_weth))); + s_etherSenderReceiver.publicCcipReceive(message); + } +} + +contract EtherSenderReceiverTest_ccipSend is EtherSenderReceiverTest { + error InsufficientFee(uint256 gotFee, uint256 fee); + + uint256 internal constant amount = 100; + uint64 internal constant destinationChainSelector = 424242; + uint256 internal constant feeWei = 121212; + uint256 internal constant feeJuels = 232323; + + function test_Fuzz_ccipSend(uint256 feeFromRouter, uint256 feeSupplied) public { + // cap the fuzzer because OWNER only has a million ether. + vm.assume(feeSupplied < 1_000_000 ether - amount); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(0), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.getFee.selector, destinationChainSelector, validatedMessage), + abi.encode(feeFromRouter) + ); + + if (feeSupplied < feeFromRouter) { + vm.expectRevert(); + s_etherSenderReceiver.ccipSend{value: amount + feeSupplied}(destinationChainSelector, message); + } else { + bytes32 expectedMsgId = keccak256(abi.encode("ccip send")); + vm.mockCall( + ROUTER, + feeSupplied, + abi.encodeWithSelector(IRouterClient.ccipSend.selector, destinationChainSelector, validatedMessage), + abi.encode(expectedMsgId) + ); + + bytes32 actualMsgId = + s_etherSenderReceiver.ccipSend{value: amount + feeSupplied}(destinationChainSelector, message); + assertEq(actualMsgId, expectedMsgId, "message id must be correct"); + } + } + + function test_Fuzz_ccipSend_feeToken(uint256 feeFromRouter, uint256 feeSupplied) public { + // cap the fuzzer because OWNER only has a million LINK. + vm.assume(feeSupplied < 1_000_000 ether - amount); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(s_linkToken), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.getFee.selector, destinationChainSelector, validatedMessage), + abi.encode(feeFromRouter) + ); + + s_linkToken.approve(address(s_etherSenderReceiver), feeSupplied); + + if (feeSupplied < feeFromRouter) { + vm.expectRevert(); + s_etherSenderReceiver.ccipSend{value: amount}(destinationChainSelector, message); + } else { + bytes32 expectedMsgId = keccak256(abi.encode("ccip send")); + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.ccipSend.selector, destinationChainSelector, validatedMessage), + abi.encode(expectedMsgId) + ); + + bytes32 actualMsgId = s_etherSenderReceiver.ccipSend{value: amount}(destinationChainSelector, message); + assertEq(actualMsgId, expectedMsgId, "message id must be correct"); + } + } + + function test_ccipSend_reverts_insufficientFee_weth() public { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(s_weth), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.getFee.selector, destinationChainSelector, validatedMessage), + abi.encode(feeWei) + ); + + s_weth.approve(address(s_etherSenderReceiver), feeWei - 1); + + vm.expectRevert("SafeERC20: low-level call failed"); + s_etherSenderReceiver.ccipSend{value: amount}(destinationChainSelector, message); + } + + function test_ccipSend_reverts_insufficientFee_feeToken() public { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(s_linkToken), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.getFee.selector, destinationChainSelector, validatedMessage), + abi.encode(feeJuels) + ); + + s_linkToken.approve(address(s_etherSenderReceiver), feeJuels - 1); + + vm.expectRevert("ERC20: insufficient allowance"); + s_etherSenderReceiver.ccipSend{value: amount}(destinationChainSelector, message); + } + + function test_ccipSend_reverts_insufficientFee_native() public { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(0), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.getFee.selector, destinationChainSelector, validatedMessage), + abi.encode(feeWei) + ); + + vm.expectRevert(); + s_etherSenderReceiver.ccipSend{value: amount + feeWei - 1}(destinationChainSelector, message); + } + + function test_ccipSend_success_nativeExcess() public { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(0), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + + bytes32 expectedMsgId = keccak256(abi.encode("ccip send")); + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.getFee.selector, destinationChainSelector, validatedMessage), + abi.encode(feeWei) + ); + + // we assert that the correct value is sent to the router call, which should be + // the msg.value - feeWei. + vm.mockCall( + ROUTER, + feeWei + 1, + abi.encodeWithSelector(IRouterClient.ccipSend.selector, destinationChainSelector, validatedMessage), + abi.encode(expectedMsgId) + ); + + bytes32 actualMsgId = s_etherSenderReceiver.ccipSend{value: amount + feeWei + 1}(destinationChainSelector, message); + assertEq(actualMsgId, expectedMsgId, "message id must be correct"); + } + + function test_ccipSend_success_native() public { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(0), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + + bytes32 expectedMsgId = keccak256(abi.encode("ccip send")); + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.getFee.selector, destinationChainSelector, validatedMessage), + abi.encode(feeWei) + ); + vm.mockCall( + ROUTER, + feeWei, + abi.encodeWithSelector(IRouterClient.ccipSend.selector, destinationChainSelector, validatedMessage), + abi.encode(expectedMsgId) + ); + + bytes32 actualMsgId = s_etherSenderReceiver.ccipSend{value: amount + feeWei}(destinationChainSelector, message); + assertEq(actualMsgId, expectedMsgId, "message id must be correct"); + } + + function test_ccipSend_success_feeToken() public { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(s_linkToken), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + + bytes32 expectedMsgId = keccak256(abi.encode("ccip send")); + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.getFee.selector, destinationChainSelector, validatedMessage), + abi.encode(feeJuels) + ); + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.ccipSend.selector, destinationChainSelector, validatedMessage), + abi.encode(expectedMsgId) + ); + + s_linkToken.approve(address(s_etherSenderReceiver), feeJuels); + + bytes32 actualMsgId = s_etherSenderReceiver.ccipSend{value: amount}(destinationChainSelector, message); + assertEq(actualMsgId, expectedMsgId, "message id must be correct"); + uint256 routerAllowance = s_linkToken.allowance(address(s_etherSenderReceiver), ROUTER); + assertEq(routerAllowance, feeJuels, "router allowance must be feeJuels"); + } + + function test_ccipSend_success_weth() public { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({ + token: address(0), // callers may not specify this. + amount: amount + }); + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(XCHAIN_RECEIVER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: address(s_weth), + extraArgs: "" + }); + + Client.EVM2AnyMessage memory validatedMessage = s_etherSenderReceiver.validatedMessage(message); + + bytes32 expectedMsgId = keccak256(abi.encode("ccip send")); + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.getFee.selector, destinationChainSelector, validatedMessage), + abi.encode(feeWei) + ); + vm.mockCall( + ROUTER, + abi.encodeWithSelector(IRouterClient.ccipSend.selector, destinationChainSelector, validatedMessage), + abi.encode(expectedMsgId) + ); + + s_weth.approve(address(s_etherSenderReceiver), feeWei); + + bytes32 actualMsgId = s_etherSenderReceiver.ccipSend{value: amount}(destinationChainSelector, message); + assertEq(actualMsgId, expectedMsgId, "message id must be correct"); + uint256 routerAllowance = s_weth.allowance(address(s_etherSenderReceiver), ROUTER); + assertEq(routerAllowance, type(uint256).max, "router allowance must be max for weth"); + } +} diff --git a/contracts/src/v0.8/ccip/test/applications/ImmutableExample.t.sol b/contracts/src/v0.8/ccip/test/applications/ImmutableExample.t.sol new file mode 100644 index 0000000000..eb12e6205a --- /dev/null +++ b/contracts/src/v0.8/ccip/test/applications/ImmutableExample.t.sol @@ -0,0 +1,61 @@ +pragma solidity ^0.8.0; + +import {IAny2EVMMessageReceiver} from "../../interfaces/IAny2EVMMessageReceiver.sol"; + +import {CCIPClientExample} from "../../applications/CCIPClientExample.sol"; +import {Client} from "../../libraries/Client.sol"; +import {EVM2EVMOnRampSetup} from "../onRamp/EVM2EVMOnRampSetup.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {ERC165Checker} from + "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol"; + +contract CCIPClientExample_sanity is EVM2EVMOnRampSetup { + function test_ImmutableExamples_Success() public { + CCIPClientExample exampleContract = new CCIPClientExample(s_sourceRouter, IERC20(s_sourceFeeToken)); + deal(address(exampleContract), 100 ether); + deal(s_sourceFeeToken, address(exampleContract), 100 ether); + + // feeToken approval works + assertEq(IERC20(s_sourceFeeToken).allowance(address(exampleContract), address(s_sourceRouter)), 2 ** 256 - 1); + + // Can set chain + Client.EVMExtraArgsV1 memory extraArgs = Client.EVMExtraArgsV1({gasLimit: 300_000}); + bytes memory encodedExtraArgs = Client._argsToBytes(extraArgs); + exampleContract.enableChain(DEST_CHAIN_SELECTOR, encodedExtraArgs); + assertEq(exampleContract.s_chains(DEST_CHAIN_SELECTOR), encodedExtraArgs); + + address toAddress = makeAddr("toAddress"); + + // Can send data pay native + exampleContract.sendDataPayNative(DEST_CHAIN_SELECTOR, abi.encode(toAddress), bytes("hello")); + + // Can send data pay feeToken + exampleContract.sendDataPayFeeToken(DEST_CHAIN_SELECTOR, abi.encode(toAddress), bytes("hello")); + + // Can send data tokens + address sourceToken = s_sourceTokens[1]; + assertEq( + address(s_onRamp.getPoolBySourceToken(DEST_CHAIN_SELECTOR, IERC20(sourceToken))), + address(s_sourcePoolByToken[sourceToken]) + ); + deal(sourceToken, OWNER, 100 ether); + IERC20(sourceToken).approve(address(exampleContract), 1 ether); + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({token: sourceToken, amount: 1 ether}); + exampleContract.sendDataAndTokens(DEST_CHAIN_SELECTOR, abi.encode(toAddress), bytes("hello"), tokenAmounts); + // Tokens transferred from owner to router then burned in pool. + assertEq(IERC20(sourceToken).balanceOf(OWNER), 99 ether); + assertEq(IERC20(sourceToken).balanceOf(address(s_sourceRouter)), 0); + + // Can send just tokens + IERC20(sourceToken).approve(address(exampleContract), 1 ether); + exampleContract.sendTokens(DEST_CHAIN_SELECTOR, abi.encode(toAddress), tokenAmounts); + + // Can receive + assertTrue(ERC165Checker.supportsInterface(address(exampleContract), type(IAny2EVMMessageReceiver).interfaceId)); + + // Can disable chain + exampleContract.disableChain(DEST_CHAIN_SELECTOR); + } +} diff --git a/contracts/src/v0.8/ccip/test/applications/PingPongDemo.t.sol b/contracts/src/v0.8/ccip/test/applications/PingPongDemo.t.sol new file mode 100644 index 0000000000..3297e1f4fb --- /dev/null +++ b/contracts/src/v0.8/ccip/test/applications/PingPongDemo.t.sol @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {PingPongDemo} from "../../applications/PingPongDemo.sol"; +import {Client} from "../../libraries/Client.sol"; +import "../onRamp/EVM2EVMOnRampSetup.t.sol"; + +// setup +contract PingPongDappSetup is EVM2EVMOnRampSetup { + PingPongDemo internal s_pingPong; + IERC20 internal s_feeToken; + + address internal immutable i_pongContract = makeAddr("ping_pong_counterpart"); + + function setUp() public virtual override { + EVM2EVMOnRampSetup.setUp(); + + s_feeToken = IERC20(s_sourceTokens[0]); + s_pingPong = new PingPongDemo(address(s_sourceRouter), s_feeToken); + s_pingPong.setCounterpart(DEST_CHAIN_SELECTOR, i_pongContract); + + uint256 fundingAmount = 1e18; + + // Fund the contract with LINK tokens + s_feeToken.transfer(address(s_pingPong), fundingAmount); + } +} + +contract PingPong_startPingPong is PingPongDappSetup { + function test_StartPingPong_Success() public { + uint256 pingPongNumber = 1; + bytes memory data = abi.encode(pingPongNumber); + + Client.EVM2AnyMessage memory sentMessage = Client.EVM2AnyMessage({ + receiver: abi.encode(i_pongContract), + data: data, + tokenAmounts: new Client.EVMTokenAmount[](0), + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 2e5})) + }); + + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, sentMessage); + + Internal.EVM2EVMMessage memory message = Internal.EVM2EVMMessage({ + sequenceNumber: 1, + feeTokenAmount: expectedFee, + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + sender: address(s_pingPong), + receiver: i_pongContract, + nonce: 1, + data: data, + tokenAmounts: sentMessage.tokenAmounts, + sourceTokenData: new bytes[](sentMessage.tokenAmounts.length), + gasLimit: 2e5, + feeToken: sentMessage.feeToken, + strict: false, + messageId: "" + }); + message.messageId = Internal._hash(message, s_metadataHash); + + vm.expectEmit(); + emit PingPongDemo.Ping(pingPongNumber); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(message); + + s_pingPong.startPingPong(); + } +} + +contract PingPong_ccipReceive is PingPongDappSetup { + function test_CcipReceive_Success() public { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](0); + + uint256 pingPongNumber = 5; + + Client.Any2EVMMessage memory message = Client.Any2EVMMessage({ + messageId: bytes32("a"), + sourceChainSelector: DEST_CHAIN_SELECTOR, + sender: abi.encode(i_pongContract), + data: abi.encode(pingPongNumber), + destTokenAmounts: tokenAmounts + }); + + vm.startPrank(address(s_sourceRouter)); + + vm.expectEmit(); + emit PingPongDemo.Pong(pingPongNumber + 1); + + s_pingPong.ccipReceive(message); + } +} + +contract PingPong_plumbing is PingPongDappSetup { + function test_Fuzz_CounterPartChainSelector_Success(uint64 chainSelector) public { + s_pingPong.setCounterpartChainSelector(chainSelector); + + assertEq(s_pingPong.getCounterpartChainSelector(), chainSelector); + } + + function test_Fuzz_CounterPartAddress_Success(address counterpartAddress) public { + s_pingPong.setCounterpartAddress(counterpartAddress); + + assertEq(s_pingPong.getCounterpartAddress(), counterpartAddress); + } + + function test_Fuzz_CounterPartAddress_Success(uint64 chainSelector, address counterpartAddress) public { + s_pingPong.setCounterpart(chainSelector, counterpartAddress); + + assertEq(s_pingPong.getCounterpartAddress(), counterpartAddress); + assertEq(s_pingPong.getCounterpartChainSelector(), chainSelector); + } + + function test_Pausing_Success() public { + assertFalse(s_pingPong.isPaused()); + + s_pingPong.setPaused(true); + + assertTrue(s_pingPong.isPaused()); + } +} diff --git a/contracts/src/v0.8/ccip/test/applications/SelfFundedPingPong.t.sol b/contracts/src/v0.8/ccip/test/applications/SelfFundedPingPong.t.sol new file mode 100644 index 0000000000..d5db9d1f9d --- /dev/null +++ b/contracts/src/v0.8/ccip/test/applications/SelfFundedPingPong.t.sol @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {SelfFundedPingPong} from "../../applications/SelfFundedPingPong.sol"; +import {Client} from "../../libraries/Client.sol"; +import {EVM2EVMOnRamp} from "../../onRamp/EVM2EVMOnRamp.sol"; +import {EVM2EVMOnRampSetup} from "../onRamp/EVM2EVMOnRampSetup.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract SelfFundedPingPongDappSetup is EVM2EVMOnRampSetup { + SelfFundedPingPong internal s_pingPong; + IERC20 internal s_feeToken; + uint8 internal constant s_roundTripsBeforeFunding = 0; + + address internal immutable i_pongContract = makeAddr("ping_pong_counterpart"); + + function setUp() public virtual override { + EVM2EVMOnRampSetup.setUp(); + + s_feeToken = IERC20(s_sourceTokens[0]); + s_pingPong = new SelfFundedPingPong(address(s_sourceRouter), s_feeToken, s_roundTripsBeforeFunding); + s_pingPong.setCounterpart(DEST_CHAIN_SELECTOR, i_pongContract); + + uint256 fundingAmount = 5e18; + + // set ping pong as an onRamp nop to make sure that funding runs + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = new EVM2EVMOnRamp.NopAndWeight[](1); + nopsAndWeights[0] = EVM2EVMOnRamp.NopAndWeight({nop: address(s_pingPong), weight: 1}); + s_onRamp.setNops(nopsAndWeights); + + // Fund the contract with LINK tokens + s_feeToken.transfer(address(s_pingPong), fundingAmount); + } +} + +contract SelfFundedPingPong_ccipReceive is SelfFundedPingPongDappSetup { + function test_Funding_Success() public { + Client.Any2EVMMessage memory message = Client.Any2EVMMessage({ + messageId: keccak256("msg id"), + sourceChainSelector: DEST_CHAIN_SELECTOR, + sender: abi.encode(i_pongContract), + data: "", + destTokenAmounts: new Client.EVMTokenAmount[](0) + }); + + uint8 countIncrBeforeFunding = 5; + + vm.expectEmit(); + emit SelfFundedPingPong.CountIncrBeforeFundingSet(countIncrBeforeFunding); + + s_pingPong.setCountIncrBeforeFunding(countIncrBeforeFunding); + + vm.startPrank(address(s_sourceRouter)); + for (uint256 pingPongNumber = 0; pingPongNumber <= countIncrBeforeFunding; ++pingPongNumber) { + message.data = abi.encode(pingPongNumber); + if (pingPongNumber == countIncrBeforeFunding - 1) { + vm.expectEmit(); + emit SelfFundedPingPong.Funded(); + vm.expectCall(address(s_onRamp), ""); + } + s_pingPong.ccipReceive(message); + } + } + + function test_FundingIfNotANop_Revert() public { + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = new EVM2EVMOnRamp.NopAndWeight[](0); + s_onRamp.setNops(nopsAndWeights); + + uint8 countIncrBeforeFunding = 3; + s_pingPong.setCountIncrBeforeFunding(countIncrBeforeFunding); + + vm.startPrank(address(s_sourceRouter)); + Client.Any2EVMMessage memory message = Client.Any2EVMMessage({ + messageId: bytes32("a"), + sourceChainSelector: DEST_CHAIN_SELECTOR, + sender: abi.encode(i_pongContract), + data: abi.encode(countIncrBeforeFunding), + destTokenAmounts: new Client.EVMTokenAmount[](0) + }); + + // because pingPong is not set as a nop + vm.expectRevert(EVM2EVMOnRamp.OnlyCallableByOwnerOrAdminOrNop.selector); + s_pingPong.ccipReceive(message); + } +} + +contract SelfFundedPingPong_setCountIncrBeforeFunding is SelfFundedPingPongDappSetup { + function test_setCountIncrBeforeFunding() public { + uint8 c = s_pingPong.getCountIncrBeforeFunding(); + + vm.expectEmit(); + emit SelfFundedPingPong.CountIncrBeforeFundingSet(c + 1); + + s_pingPong.setCountIncrBeforeFunding(c + 1); + uint8 c2 = s_pingPong.getCountIncrBeforeFunding(); + assertEq(c2, c + 1); + } +} diff --git a/contracts/src/v0.8/ccip/test/applications/TokenProxy.t.sol b/contracts/src/v0.8/ccip/test/applications/TokenProxy.t.sol new file mode 100644 index 0000000000..9e78f6e369 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/applications/TokenProxy.t.sol @@ -0,0 +1,211 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {TokenProxy} from "../../applications/TokenProxy.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {EVM2EVMOnRamp} from "../../onRamp/EVM2EVMOnRamp.sol"; +import {EVM2EVMOnRampSetup} from "../onRamp/EVM2EVMOnRampSetup.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract TokenProxySetup is EVM2EVMOnRampSetup { + TokenProxy internal s_tokenProxy; + IERC20 internal s_feeToken; + IERC20 internal s_transferToken; + + function setUp() public virtual override { + EVM2EVMOnRampSetup.setUp(); + + s_feeToken = IERC20(s_sourceTokens[0]); + s_transferToken = IERC20(s_sourceTokens[1]); + s_tokenProxy = new TokenProxy(address(s_sourceRouter), address(s_transferToken)); + + s_transferToken.approve(address(s_tokenProxy), type(uint256).max); + s_feeToken.approve(address(s_tokenProxy), type(uint256).max); + } +} + +contract TokenProxy_constructor is TokenProxySetup { + function test_Constructor() public view { + assertEq(address(s_tokenProxy.getRouter()), address(s_sourceRouter)); + assertEq(address(s_tokenProxy.getToken()), address(s_transferToken)); + } +} + +contract TokenProxy_getFee is TokenProxySetup { + function test_GetFee_Success() public view { + Client.EVMTokenAmount[] memory tokens = new Client.EVMTokenAmount[](1); + tokens[0] = Client.EVMTokenAmount({token: address(s_transferToken), amount: 1e18}); + + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(s_tokenProxy), + data: "", + tokenAmounts: tokens, + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 0})) + }); + + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + uint256 actualFee = s_tokenProxy.getFee(DEST_CHAIN_SELECTOR, message); + assertEq(expectedFee, actualFee); + } + + // Reverts + + function test_GetFeeInvalidToken_Revert() public { + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(s_tokenProxy), + data: "", + tokenAmounts: new Client.EVMTokenAmount[](0), + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 0})) + }); + + vm.expectRevert(TokenProxy.InvalidToken.selector); + + s_tokenProxy.getFee(DEST_CHAIN_SELECTOR, message); + } + + function test_GetFeeNoDataAllowed_Revert() public { + Client.EVMTokenAmount[] memory tokens = new Client.EVMTokenAmount[](1); + tokens[0] = Client.EVMTokenAmount({token: address(s_transferToken), amount: 1e18}); + + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(s_tokenProxy), + data: "not empty", + tokenAmounts: tokens, + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 0})) + }); + + vm.expectRevert(TokenProxy.NoDataAllowed.selector); + + s_tokenProxy.getFee(DEST_CHAIN_SELECTOR, message); + } + + function test_GetFeeGasShouldBeZero_Revert() public { + Client.EVMTokenAmount[] memory tokens = new Client.EVMTokenAmount[](1); + tokens[0] = Client.EVMTokenAmount({token: address(s_transferToken), amount: 1e18}); + + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(s_tokenProxy), + data: "", + tokenAmounts: tokens, + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 10})) + }); + + vm.expectRevert(TokenProxy.GasShouldBeZero.selector); + + s_tokenProxy.getFee(DEST_CHAIN_SELECTOR, message); + } +} + +contract TokenProxy_ccipSend is TokenProxySetup { + function test_CcipSend_Success() public { + vm.pauseGasMetering(); + Client.EVMTokenAmount[] memory tokens = new Client.EVMTokenAmount[](1); + tokens[0] = Client.EVMTokenAmount({token: address(s_transferToken), amount: 1e18}); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = tokens; + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 0})); + + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + + s_feeToken.approve(address(s_tokenProxy), expectedFee); + + Internal.EVM2EVMMessage memory msgEvent = _messageToEvent(message, 1, 1, expectedFee, OWNER); + msgEvent.sender = address(s_tokenProxy); + msgEvent.messageId = Internal._hash(msgEvent, s_metadataHash); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(msgEvent); + + vm.resumeGasMetering(); + s_tokenProxy.ccipSend(DEST_CHAIN_SELECTOR, message); + } + + function test_CcipSendNative_Success() public { + vm.pauseGasMetering(); + Client.EVMTokenAmount[] memory tokens = new Client.EVMTokenAmount[](1); + tokens[0] = Client.EVMTokenAmount({token: address(s_transferToken), amount: 1e18}); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = tokens; + message.feeToken = address(0); + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 0})); + + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + + Internal.EVM2EVMMessage memory msgEvent = _messageToEvent(message, 1, 1, expectedFee, OWNER); + msgEvent.sender = address(s_tokenProxy); + msgEvent.feeToken = s_sourceRouter.getWrappedNative(); + msgEvent.messageId = Internal._hash(msgEvent, s_metadataHash); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(msgEvent); + + vm.resumeGasMetering(); + s_tokenProxy.ccipSend{value: expectedFee}(DEST_CHAIN_SELECTOR, message); + } + + // Reverts + + function test_CcipSendInsufficientAllowance_Revert() public { + Client.EVMTokenAmount[] memory tokens = new Client.EVMTokenAmount[](1); + tokens[0] = Client.EVMTokenAmount({token: address(s_transferToken), amount: 1e18}); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = tokens; + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 0})); + + // Revoke allowance + s_transferToken.approve(address(s_tokenProxy), 0); + + vm.expectRevert("ERC20: insufficient allowance"); + + s_tokenProxy.ccipSend(DEST_CHAIN_SELECTOR, message); + } + + function test_CcipSendInvalidToken_Revert() public { + Client.EVMTokenAmount[] memory tokens = new Client.EVMTokenAmount[](1); + tokens[0] = Client.EVMTokenAmount({token: address(s_feeToken), amount: 1e18}); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = tokens; + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 0})); + + vm.expectRevert(TokenProxy.InvalidToken.selector); + + s_tokenProxy.ccipSend(DEST_CHAIN_SELECTOR, message); + } + + function test_CcipSendNoDataAllowed_Revert() public { + Client.EVMTokenAmount[] memory tokens = new Client.EVMTokenAmount[](1); + tokens[0] = Client.EVMTokenAmount({token: address(s_transferToken), amount: 1e18}); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = tokens; + message.data = "not empty"; + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 0})); + + vm.expectRevert(TokenProxy.NoDataAllowed.selector); + + s_tokenProxy.ccipSend(DEST_CHAIN_SELECTOR, message); + } + + function test_CcipSendGasShouldBeZero_Revert() public { + Client.EVMTokenAmount[] memory tokens = new Client.EVMTokenAmount[](1); + tokens[0] = Client.EVMTokenAmount({token: address(s_transferToken), amount: 1e18}); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = tokens; + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 1})); + + vm.expectRevert(TokenProxy.GasShouldBeZero.selector); + + s_tokenProxy.ccipSend(DEST_CHAIN_SELECTOR, message); + } +} diff --git a/contracts/src/v0.8/ccip/test/arm/ARMProxy.t.sol b/contracts/src/v0.8/ccip/test/arm/ARMProxy.t.sol new file mode 100644 index 0000000000..24b617c82a --- /dev/null +++ b/contracts/src/v0.8/ccip/test/arm/ARMProxy.t.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IRMN} from "../../interfaces/IRMN.sol"; + +import {ARMProxy} from "../../ARMProxy.sol"; +import {RMN} from "../../RMN.sol"; +import {MockRMN} from "../mocks/MockRMN.sol"; +import {RMNSetup, makeSubjects} from "./RMNSetup.t.sol"; + +contract ARMProxyTest is RMNSetup { + MockRMN internal s_mockRMN; + ARMProxy internal s_armProxy; + + function setUp() public virtual override { + RMNSetup.setUp(); + s_mockRMN = new MockRMN(); + s_armProxy = new ARMProxy(address(s_rmn)); + } + + function test_ARMIsCursed_Success() public { + s_armProxy.setARM(address(s_mockRMN)); + assertFalse(IRMN(address(s_armProxy)).isCursed()); + s_mockRMN.setGlobalCursed(true); + assertTrue(IRMN(address(s_armProxy)).isCursed()); + } + + function test_ARMIsBlessed_Success() public { + s_armProxy.setARM(address(s_mockRMN)); + s_mockRMN.setTaggedRootBlessed(IRMN.TaggedRoot({commitStore: address(0), root: bytes32(0)}), true); + assertTrue(IRMN(address(s_armProxy)).isBlessed(IRMN.TaggedRoot({commitStore: address(0), root: bytes32(0)}))); + s_mockRMN.setTaggedRootBlessed(IRMN.TaggedRoot({commitStore: address(0), root: bytes32(0)}), false); + assertFalse(IRMN(address(s_armProxy)).isBlessed(IRMN.TaggedRoot({commitStore: address(0), root: bytes32(0)}))); + } + + function test_ARMCallRevertReasonForwarded() public { + bytes memory err = bytes("revert"); + s_mockRMN.setIsCursedRevert(err); + s_armProxy.setARM(address(s_mockRMN)); + vm.expectRevert(abi.encodeWithSelector(MockRMN.CustomError.selector, err)); + IRMN(address(s_armProxy)).isCursed(); + } +} diff --git a/contracts/src/v0.8/ccip/test/arm/ARMProxy_standalone.t.sol b/contracts/src/v0.8/ccip/test/arm/ARMProxy_standalone.t.sol new file mode 100644 index 0000000000..4f3e96fafa --- /dev/null +++ b/contracts/src/v0.8/ccip/test/arm/ARMProxy_standalone.t.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ARMProxy} from "../../ARMProxy.sol"; +import {Test} from "forge-std/Test.sol"; + +contract ARMProxyStandaloneTest is Test { + address internal constant EMPTY_ADDRESS = address(0x1); + address internal constant OWNER_ADDRESS = 0xC0ffeeEeC0fFeeeEc0ffeEeEc0ffEEEEC0FfEEee; + address internal constant MOCK_RMN_ADDRESS = 0x1337133713371337133713371337133713371337; + + ARMProxy internal s_armProxy; + + function setUp() public virtual { + // needed so that the extcodesize check in ARMProxy.fallback doesn't revert + vm.etch(MOCK_RMN_ADDRESS, bytes("fake bytecode")); + + vm.prank(OWNER_ADDRESS); + s_armProxy = new ARMProxy(MOCK_RMN_ADDRESS); + } + + function test_Constructor() public { + vm.expectEmit(); + emit ARMProxy.ARMSet(MOCK_RMN_ADDRESS); + ARMProxy proxy = new ARMProxy(MOCK_RMN_ADDRESS); + assertEq(proxy.getARM(), MOCK_RMN_ADDRESS); + } + + function test_SetARM() public { + vm.expectEmit(); + emit ARMProxy.ARMSet(MOCK_RMN_ADDRESS); + vm.prank(OWNER_ADDRESS); + s_armProxy.setARM(MOCK_RMN_ADDRESS); + assertEq(s_armProxy.getARM(), MOCK_RMN_ADDRESS); + } + + function test_SetARMzero() public { + vm.expectRevert(abi.encodeWithSelector(ARMProxy.ZeroAddressNotAllowed.selector)); + vm.prank(OWNER_ADDRESS); + s_armProxy.setARM(address(0x0)); + } + + /* + function test_Fuzz_ARMCall(bool expectedSuccess, bytes memory call, bytes memory ret) public { + // filter out calls to functions that will be handled on the ARMProxy instead + // of the underlying ARM contract + vm.assume( + call.length < 4 || + (bytes4(call) != s_armProxy.getARM.selector && + bytes4(call) != s_armProxy.setARM.selector && + bytes4(call) != s_armProxy.owner.selector && + bytes4(call) != s_armProxy.acceptOwnership.selector && + bytes4(call) != s_armProxy.transferOwnership.selector && + bytes4(call) != s_armProxy.typeAndVersion.selector) + ); + + if (expectedSuccess) { + vm.mockCall(MOCK_RMN_ADDRESS, 0, call, ret); + } else { + vm.mockCallRevert(MOCK_RMN_ADDRESS, 0, call, ret); + } + (bool actualSuccess, bytes memory result) = address(s_armProxy).call(call); + vm.clearMockedCalls(); + + assertEq(result, ret); + assertEq(expectedSuccess, actualSuccess); + } + */ + + function test_ARMCallEmptyContractRevert() public { + vm.prank(OWNER_ADDRESS); + s_armProxy.setARM(EMPTY_ADDRESS); // No code at address 1, should revert. + vm.expectRevert(); + bytes memory b = new bytes(0); + (bool success,) = address(s_armProxy).call(b); + success; + } +} diff --git a/contracts/src/v0.8/ccip/test/arm/RMN.t.sol b/contracts/src/v0.8/ccip/test/arm/RMN.t.sol new file mode 100644 index 0000000000..d3237592f2 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/arm/RMN.t.sol @@ -0,0 +1,1068 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IRMN} from "../../interfaces/IRMN.sol"; + +import {GLOBAL_CURSE_SUBJECT, LIFT_CURSE_VOTE_ADDR, OWNER_CURSE_VOTE_ADDR, RMN} from "../../RMN.sol"; +import {RMNSetup, makeCursesHash, makeSubjects} from "./RMNSetup.t.sol"; + +import {Test} from "forge-std/Test.sol"; + +bytes28 constant GARBAGE_CURSES_HASH = bytes28(keccak256("GARBAGE_CURSES_HASH")); + +contract ConfigCompare is Test { + function assertConfigEq(RMN.Config memory actualConfig, RMN.Config memory expectedConfig) public pure { + assertEq(actualConfig.voters.length, expectedConfig.voters.length); + for (uint256 i = 0; i < expectedConfig.voters.length; ++i) { + RMN.Voter memory expectedVoter = expectedConfig.voters[i]; + RMN.Voter memory actualVoter = actualConfig.voters[i]; + assertEq(actualVoter.blessVoteAddr, expectedVoter.blessVoteAddr); + assertEq(actualVoter.curseVoteAddr, expectedVoter.curseVoteAddr); + assertEq(actualVoter.blessWeight, expectedVoter.blessWeight); + assertEq(actualVoter.curseWeight, expectedVoter.curseWeight); + } + assertEq(actualConfig.blessWeightThreshold, expectedConfig.blessWeightThreshold); + assertEq(actualConfig.curseWeightThreshold, expectedConfig.curseWeightThreshold); + } +} + +contract RMN_constructor is ConfigCompare, RMNSetup { + function test_Constructor_Success() public view { + RMN.Config memory expectedConfig = rmnConstructorArgs(); + (uint32 actualVersion,, RMN.Config memory actualConfig) = s_rmn.getConfigDetails(); + assertEq(actualVersion, 1); + assertConfigEq(actualConfig, expectedConfig); + } +} + +contract RMN_voteToBless is RMNSetup { + function _getFirstBlessVoterAndWeight() internal pure returns (address, uint8) { + RMN.Config memory cfg = rmnConstructorArgs(); + return (cfg.voters[0].blessVoteAddr, cfg.voters[0].blessWeight); + } + + // Success + + function test_RootSuccess() public { + uint256 numRoots = 10; + + (address voter, uint8 voterWeight) = _getFirstBlessVoterAndWeight(); + + for (uint256 i = 1; i <= numRoots; ++i) { + vm.expectEmit(); + emit RMN.VotedToBless(1, voter, makeTaggedRoot(i), voterWeight); + } + + vm.prank(voter); + s_rmn.voteToBless(makeTaggedRootsInclusive(1, numRoots)); + + for (uint256 i = 1; i <= numRoots; ++i) { + assertFalse(s_rmn.isBlessed(makeTaggedRoot(i))); + assertEq(voterWeight, getWeightOfVotesToBlessRoot(makeTaggedRoot(i))); + assertTrue(hasVotedToBlessRoot(voter, makeTaggedRoot(1))); + } + } + + // Reverts + + function test_SenderAlreadyVoted_Revert() public { + (address voter,) = _getFirstBlessVoterAndWeight(); + + vm.startPrank(voter); + s_rmn.voteToBless(makeTaggedRootSingleton(1)); + assertTrue(hasVotedToBlessRoot(voter, makeTaggedRoot(1))); + + uint256 votesToBlessBefore = getWeightOfVotesToBlessRoot(makeTaggedRoot(1)); + vm.expectRevert(RMN.VoteToBlessNoop.selector); + s_rmn.voteToBless(makeTaggedRootSingleton(1)); + assertEq(votesToBlessBefore, getWeightOfVotesToBlessRoot(makeTaggedRoot(1))); + } + + function test_IsAlreadyBlessed_Revert() public { + RMN.Config memory cfg = rmnConstructorArgs(); + + // Bless voters 2,3,4 vote to bless + for (uint256 i = 1; i < cfg.voters.length; i++) { + vm.startPrank(cfg.voters[i].blessVoteAddr); + s_rmn.voteToBless(makeTaggedRootSingleton(1)); + } + + uint256 votesToBlessBefore = getWeightOfVotesToBlessRoot(makeTaggedRoot(1)); + vm.startPrank(cfg.voters[0].blessVoteAddr); + vm.expectRevert(RMN.VoteToBlessNoop.selector); + s_rmn.voteToBless(makeTaggedRootSingleton(1)); + assertEq(votesToBlessBefore, getWeightOfVotesToBlessRoot(makeTaggedRoot(1))); + } + + function test_Curse_Revert() public { + RMN.Config memory cfg = rmnConstructorArgs(); + + for (uint256 i = 0; i < cfg.voters.length; i++) { + vm.startPrank(cfg.voters[i].curseVoteAddr); + s_rmn.voteToCurse(makeCurseId(i), makeSubjects(GLOBAL_CURSE_SUBJECT)); + } + + vm.startPrank(cfg.voters[0].blessVoteAddr); + vm.expectRevert(RMN.VoteToBlessForbiddenDuringActiveGlobalCurse.selector); + s_rmn.voteToBless(makeTaggedRootSingleton(12903)); + } + + function test_UnauthorizedVoter_Revert() public { + vm.startPrank(STRANGER); + vm.expectRevert(abi.encodeWithSelector(RMN.UnauthorizedVoter.selector, STRANGER)); + s_rmn.voteToBless(makeTaggedRootSingleton(12321)); + } +} + +contract RMN_ownerUnbless is RMNSetup { + function test_Unbless_Success() public { + RMN.Config memory cfg = rmnConstructorArgs(); + for (uint256 i = 0; i < cfg.voters.length; ++i) { + vm.startPrank(cfg.voters[i].blessVoteAddr); + s_rmn.voteToBless(makeTaggedRootSingleton(1)); + } + assertTrue(s_rmn.isBlessed(makeTaggedRoot(1))); + + vm.startPrank(OWNER); + s_rmn.ownerResetBlessVotes(makeTaggedRootSingleton(1)); + assertFalse(s_rmn.isBlessed(makeTaggedRoot(1))); + } +} + +contract RMN_unvoteToCurse is RMNSetup { + uint256 internal s_curser; + bytes28 internal s_cursesHash; + + function setUp() public override { + RMNSetup.setUp(); + RMN.Config memory cfg = rmnConstructorArgs(); + + s_curser = 0; + vm.startPrank(cfg.voters[s_curser].curseVoteAddr); + s_rmn.voteToCurse(makeCurseId(1), makeSubjects(0)); + bytes28 expectedCursesHash = makeCursesHash(makeCurseId(1)); + assertFalse(s_rmn.isCursed()); + (address[] memory cursers, bytes28[] memory cursesHashes, uint16 weight, bool cursed) = s_rmn.getCurseProgress(0); + assertEq(1, cursers.length); + assertEq(cfg.voters[s_curser].curseVoteAddr, cursers[0]); + assertEq(cfg.voters[s_curser].curseWeight, weight); + assertEq(1, cursesHashes.length); + assertEq(expectedCursesHash, cursesHashes[0]); + assertFalse(cursed); + + s_cursesHash = expectedCursesHash; + } + + function test_UnauthorizedVoter() public { + RMN.Config memory cfg = rmnConstructorArgs(); + // Someone else cannot unvote to curse on the curser's behalf. + address[] memory unauthorized = new address[](3); + unauthorized[0] = cfg.voters[s_curser].blessVoteAddr; + unauthorized[1] = cfg.voters[s_curser ^ 1].blessVoteAddr; + unauthorized[2] = OWNER; + + for (uint256 i = 0; i < unauthorized.length; ++i) { + bytes memory expectedRevert = abi.encodeWithSelector(RMN.UnauthorizedVoter.selector, unauthorized[i]); + vm.startPrank(unauthorized[i]); + { + // should fail when using the correct curses hash + RMN.UnvoteToCurseRequest[] memory reqs = new RMN.UnvoteToCurseRequest[](1); + reqs[0] = RMN.UnvoteToCurseRequest({subject: 0, cursesHash: s_cursesHash}); + vm.expectRevert(expectedRevert); + s_rmn.unvoteToCurse(reqs); + } + { + // should fail when using garbage curses hash + RMN.UnvoteToCurseRequest[] memory reqs = new RMN.UnvoteToCurseRequest[](1); + reqs[0] = RMN.UnvoteToCurseRequest({subject: 0, cursesHash: GARBAGE_CURSES_HASH}); + vm.expectRevert(expectedRevert); + s_rmn.unvoteToCurse(reqs); + } + } + } + + function test_InvalidCursesHash() public { + RMN.Config memory cfg = rmnConstructorArgs(); + vm.startPrank(cfg.voters[s_curser].curseVoteAddr); + RMN.UnvoteToCurseRequest[] memory reqs = new RMN.UnvoteToCurseRequest[](1); + reqs[0] = RMN.UnvoteToCurseRequest({subject: 0, cursesHash: GARBAGE_CURSES_HASH}); + vm.expectRevert(RMN.UnvoteToCurseNoop.selector); + s_rmn.unvoteToCurse(reqs); + } + + function test_ValidCursesHash() public { + RMN.Config memory cfg = rmnConstructorArgs(); + vm.startPrank(cfg.voters[s_curser].curseVoteAddr); + RMN.UnvoteToCurseRequest[] memory reqs = new RMN.UnvoteToCurseRequest[](1); + reqs[0] = RMN.UnvoteToCurseRequest({subject: 0, cursesHash: s_cursesHash}); + s_rmn.unvoteToCurse(reqs); // succeeds + } + + function test_OwnerSucceeds() public { + RMN.Config memory cfg = rmnConstructorArgs(); + vm.startPrank(OWNER); + RMN.OwnerUnvoteToCurseRequest[] memory reqs = new RMN.OwnerUnvoteToCurseRequest[](1); + reqs[0] = RMN.OwnerUnvoteToCurseRequest({ + curseVoteAddr: cfg.voters[s_curser].curseVoteAddr, + unit: RMN.UnvoteToCurseRequest({subject: 0, cursesHash: s_cursesHash}), + forceUnvote: false + }); + s_rmn.ownerUnvoteToCurse(reqs); + } + + function test_OwnerSkips() public { + RMN.Config memory cfg = rmnConstructorArgs(); + vm.startPrank(OWNER); + RMN.OwnerUnvoteToCurseRequest[] memory reqs = new RMN.OwnerUnvoteToCurseRequest[](1); + reqs[0] = RMN.OwnerUnvoteToCurseRequest({ + curseVoteAddr: cfg.voters[s_curser].curseVoteAddr, + unit: RMN.UnvoteToCurseRequest({subject: 0, cursesHash: GARBAGE_CURSES_HASH}), + forceUnvote: false + }); + + vm.expectEmit(); + emit RMN.SkippedUnvoteToCurse(cfg.voters[s_curser].curseVoteAddr, 0, s_cursesHash, GARBAGE_CURSES_HASH); + vm.expectRevert(RMN.UnvoteToCurseNoop.selector); + s_rmn.ownerUnvoteToCurse(reqs); + } + + function test_VotersCantLiftCurseButOwnerCan() public { + vm.stopPrank(); + RMN.Config memory cfg = rmnConstructorArgs(); + // s_curser has voted to curse during setUp + { + (address[] memory voters, bytes28[] memory cursesHashes, uint16 accWeight, bool cursed) = + s_rmn.getCurseProgress(0); + assertEq(accWeight, cfg.voters[s_curser].curseWeight); + assertFalse(cursed); + assertEq(voters.length, 1); + assertEq(cursesHashes.length, 1); + assertEq(voters[0], cfg.voters[s_curser].curseVoteAddr); + assertEq(cursesHashes[0], makeCursesHash(makeCurseId(1))); + } + // everyone else votes now, same curse id, same subject + { + for (uint256 i = 0; i < cfg.voters.length; ++i) { + if (i == s_curser) continue; // already voted to curse + vm.prank(cfg.voters[i].curseVoteAddr); + s_rmn.voteToCurse(makeCurseId(1), makeSubjects(0)); + } + } + // subject must be cursed now + { + assertTrue(s_rmn.isCursed(0)); + } + // curse progress should be as full as it can get + { + (address[] memory voters, bytes28[] memory cursesHashes, uint16 accWeight, bool cursed) = + s_rmn.getCurseProgress(0); + uint256 allWeights; + for (uint256 i = 0; i < cfg.voters.length; i++) { + allWeights += cfg.voters[i].curseWeight; + } + assertEq(accWeight, allWeights); + assertTrue(cursed); + assertEq(voters.length, cfg.voters.length); + assertEq(cursesHashes.length, cfg.voters.length); + for (uint256 i = 0; i < cfg.voters.length; ++i) { + assertEq(voters[i], cfg.voters[i].curseVoteAddr); + assertEq(cursesHashes[i], makeCursesHash(makeCurseId(1))); + } + } + // everyone unvotes to curse, successfully + { + for (uint256 i = 0; i < cfg.voters.length; ++i) { + vm.prank(cfg.voters[i].curseVoteAddr); + RMN.UnvoteToCurseRequest[] memory reqs = new RMN.UnvoteToCurseRequest[](1); + reqs[0] = RMN.UnvoteToCurseRequest({subject: 0, cursesHash: makeCursesHash(makeCurseId(1))}); + s_rmn.unvoteToCurse(reqs); + } + } + // curse should still be in place as only the owner can lift it + { + assertTrue(s_rmn.isCursed(0)); + } + // curse progress should be empty, expect for the cursed flag + { + (address[] memory voters, bytes28[] memory cursesHashes, uint16 accWeight, bool cursed) = + s_rmn.getCurseProgress(0); + assertEq(accWeight, 0); + assertTrue(cursed); + assertEq(voters.length, 0); + assertEq(cursesHashes.length, 0); + } + // owner lifts curse + { + RMN.OwnerUnvoteToCurseRequest[] memory ownerReq = new RMN.OwnerUnvoteToCurseRequest[](1); + ownerReq[0] = RMN.OwnerUnvoteToCurseRequest({ + curseVoteAddr: LIFT_CURSE_VOTE_ADDR, + unit: RMN.UnvoteToCurseRequest({subject: 0, cursesHash: 0}), + forceUnvote: false + }); + vm.prank(OWNER); + s_rmn.ownerUnvoteToCurse(ownerReq); + } + // curse should now be lifted + { + assertFalse(s_rmn.isCursed(0)); + } + } +} + +contract RMN_voteToCurse_2 is RMNSetup { + function initialConfig() internal pure returns (RMN.Config memory) { + RMN.Config memory cfg = RMN.Config({voters: new RMN.Voter[](3), blessWeightThreshold: 1, curseWeightThreshold: 3}); + cfg.voters[0] = + RMN.Voter({blessVoteAddr: BLESS_VOTER_1, curseVoteAddr: CURSE_VOTER_1, blessWeight: 1, curseWeight: 1}); + cfg.voters[1] = + RMN.Voter({blessVoteAddr: BLESS_VOTER_2, curseVoteAddr: CURSE_VOTER_2, blessWeight: 1, curseWeight: 1}); + cfg.voters[2] = + RMN.Voter({blessVoteAddr: BLESS_VOTER_3, curseVoteAddr: CURSE_VOTER_3, blessWeight: 1, curseWeight: 1}); + return cfg; + } + + function setUp() public override { + vm.prank(OWNER); + s_rmn = new RMN(initialConfig()); + } + + function test_VotesAreDroppedIfSubjectIsNotCursedDuringConfigChange() public { + // vote to curse the subject from an insufficient number of voters, one voter + { + RMN.Config memory cfg = initialConfig(); + vm.prank(cfg.voters[0].curseVoteAddr); + s_rmn.voteToCurse(makeCurseId(1), makeSubjects(0)); + } + // vote must be in place + { + (address[] memory voters, bytes28[] memory cursesHashes, uint16 accWeight, bool cursed) = + s_rmn.getCurseProgress(0); + assertEq(voters.length, 1); + assertEq(cursesHashes.length, 1); + assertEq(accWeight, 1); + assertFalse(cursed); + } + // change config to include only the first voter, i.e., initialConfig().voters[0] + { + RMN.Config memory cfg = initialConfig(); + RMN.Voter[] memory voters = cfg.voters; + assembly { + mstore(voters, 1) + } + cfg.curseWeightThreshold = 1; + vm.prank(OWNER); + s_rmn.setConfig(cfg); + } + // vote must be dropped + { + (address[] memory voters, bytes28[] memory cursesHashes, uint16 accWeight, bool cursed) = + s_rmn.getCurseProgress(0); + assertEq(voters.length, 0); + assertEq(cursesHashes.length, 0); + assertEq(accWeight, 0); + assertFalse(cursed); + } + // cause an owner curse now + { + vm.prank(OWNER); + s_rmn.ownerCurse(makeCurseId(1), makeSubjects(0)); + } + // only the owner curse must be visible + { + (address[] memory voters, bytes28[] memory cursesHashes, uint16 accWeight, bool cursed) = + s_rmn.getCurseProgress(0); + assertEq(voters.length, 1); + assertEq(voters[0], OWNER_CURSE_VOTE_ADDR); + assertEq(cursesHashes.length, 1); + assertEq(cursesHashes[0], makeCursesHash(makeCurseId(1))); + assertEq(accWeight, 0); + assertTrue(cursed); + } + } + + function test_VotesAreRetainedIfSubjectIsCursedDuringConfigChange() public { + uint256 numVotersInitially = initialConfig().voters.length; + // curse the subject with votes from all voters + { + RMN.Config memory cfg = initialConfig(); + for (uint256 i = 0; i < cfg.voters.length; ++i) { + vm.prank(cfg.voters[i].curseVoteAddr); + s_rmn.voteToCurse(makeCurseId(1), makeSubjects(0)); + } + } + // subject is now cursed + { + assertTrue(s_rmn.isCursed(0)); + } + // throw in an owner curse + { + vm.prank(OWNER); + s_rmn.ownerCurse(makeCurseId(1), makeSubjects(0)); + } + + uint256 snapshot = vm.snapshot(); + + for (uint256 keepVoters = 1; keepVoters <= numVotersInitially; ++keepVoters) { + vm.revertTo(snapshot); + + // change config to include only the first #keepVoters voters, i.e., initialConfig().voters[0..keepVoters] + { + RMN.Config memory cfg = initialConfig(); + RMN.Voter[] memory voters = cfg.voters; + assembly { + mstore(voters, keepVoters) + } + cfg.curseWeightThreshold = uint16(keepVoters); + vm.prank(OWNER); + s_rmn.setConfig(cfg); + } + // subject is still cursed + { + assertTrue(s_rmn.isCursed(0)); + } + // all votes from the first keepVoters & owner must be present + { + (address[] memory voters, bytes28[] memory cursesHashes, uint16 accWeight, bool cursed) = + s_rmn.getCurseProgress(0); + assertEq(voters.length, keepVoters + 1 /* owner */ ); + assertEq(cursesHashes.length, keepVoters + 1 /* owner */ ); + assertEq(accWeight, keepVoters /* 1 per voter */ ); + assertTrue(cursed); + for (uint256 i = 0; i < keepVoters; ++i) { + assertEq(voters[i], initialConfig().voters[i].curseVoteAddr); + assertEq(cursesHashes[i], makeCursesHash(makeCurseId(1))); + } + assertEq(voters[voters.length - 1], OWNER_CURSE_VOTE_ADDR); + assertEq(cursesHashes[cursesHashes.length - 1], makeCursesHash(makeCurseId(1))); + } + // the owner unvoting for all is not enough to lift the curse, because remember that the owner has an active vote + // also + { + for (uint256 i = 0; i < keepVoters; ++i) { + RMN.OwnerUnvoteToCurseRequest[] memory ownerReq = new RMN.OwnerUnvoteToCurseRequest[](1); + ownerReq[0] = RMN.OwnerUnvoteToCurseRequest({ + curseVoteAddr: initialConfig().voters[i].curseVoteAddr, + unit: RMN.UnvoteToCurseRequest({subject: 0, cursesHash: makeCursesHash(makeCurseId(1))}), + forceUnvote: false + }); + vm.prank(OWNER); + s_rmn.ownerUnvoteToCurse(ownerReq); + + assertTrue(s_rmn.isCursed(0)); + } + } + // after owner unvotes for themselves, finally, the curse will be lifted + { + RMN.OwnerUnvoteToCurseRequest[] memory ownerReq = new RMN.OwnerUnvoteToCurseRequest[](1); + ownerReq[0] = RMN.OwnerUnvoteToCurseRequest({ + curseVoteAddr: OWNER_CURSE_VOTE_ADDR, + unit: RMN.UnvoteToCurseRequest({subject: 0, cursesHash: makeCursesHash(makeCurseId(1))}), + forceUnvote: false + }); + vm.prank(OWNER); + s_rmn.ownerUnvoteToCurse(ownerReq); + + assertFalse(s_rmn.isCursed(0)); + } + } + } +} + +contract RMN_voteToCurse is RMNSetup { + function _getFirstCurseVoterAndWeight() internal pure returns (address, uint8) { + RMN.Config memory cfg = rmnConstructorArgs(); + return (cfg.voters[0].curseVoteAddr, cfg.voters[0].curseWeight); + } + + // Success + + function test_CurseOnlyWhenThresholdReached_Success() public { + uint256 numSubjects = 3; + uint256 maxNumRevotes = 2; + + RMN.Config memory cfg = rmnConstructorArgs(); + bytes16[] memory subjects = new bytes16[](numSubjects); + for (uint256 i = 0; i < numSubjects; ++i) { + subjects[i] = bytes16(uint128(i)); + } + for (uint256 numRevotes = 1; numRevotes <= maxNumRevotes; ++numRevotes) { + // all voters but the last vote, but can't surpass the curse weight threshold + for (uint256 i = 0; i < cfg.voters.length - 1; ++i) { + vm.prank(cfg.voters[i].curseVoteAddr); + s_rmn.voteToCurse(makeCurseId(numRevotes), subjects); + } + // no curse is yet active, last voter also needs to vote for any curse to be active + { + // ensure every subject is not cursed + for (uint256 i = 0; i < numSubjects; ++i) { + assertFalse(s_rmn.isCursed(subjects[i])); + } + // ensure every vote has been recorded + assertEq( + s_rmn.getRecordedCurseRelatedOpsCount(), + 1 /* setConfig */ + (cfg.voters.length - 1) * numRevotes * numSubjects + ); + } + } + + // last voter now votes + vm.prank(cfg.voters[cfg.voters.length - 1].curseVoteAddr); + s_rmn.voteToCurse(makeCurseId(0), subjects); + // curses should be now active + { + // ensure every subject is now cursed + for (uint256 i = 0; i < numSubjects; ++i) { + assertTrue(s_rmn.isCursed(subjects[i])); + } + // ensure every vote has been recorded + assertEq( + s_rmn.getRecordedCurseRelatedOpsCount(), + 1 /* setConfig */ + ((cfg.voters.length - 1) * maxNumRevotes + 1) * numSubjects + ); + } + } + + function test_VoteToCurse_NoCurse_Success() public { + (address voter, uint8 weight) = _getFirstCurseVoterAndWeight(); + vm.startPrank(voter); + vm.expectEmit(); + emit RMN.VotedToCurse( + 1, // configVersion + voter, + GLOBAL_CURSE_SUBJECT, + makeCurseId(123), + weight, + 1234567890, // blockTimestamp + makeCursesHash(makeCurseId(123)), // cursesHash + weight + ); + + s_rmn.voteToCurse(makeCurseId(123), makeSubjects(GLOBAL_CURSE_SUBJECT)); + + (address[] memory voters,, uint16 votes, bool cursed) = s_rmn.getCurseProgress(GLOBAL_CURSE_SUBJECT); + assertEq(1, voters.length); + assertEq(voter, voters[0]); + assertEq(weight, votes); + assertFalse(cursed); + } + + function test_VoteToCurse_YesCurse_Success() public { + RMN.Config memory cfg = rmnConstructorArgs(); + for (uint256 i = 0; i < cfg.voters.length - 1; ++i) { + vm.startPrank(cfg.voters[i].curseVoteAddr); + s_rmn.voteToCurse(makeCurseId(1), makeSubjects(0)); + } + + vm.expectEmit(); + emit RMN.Cursed(1, 0, uint64(block.timestamp)); + + vm.startPrank(cfg.voters[cfg.voters.length - 1].curseVoteAddr); + vm.resumeGasMetering(); + s_rmn.voteToCurse(makeCurseId(1), makeSubjects(0)); + } + + function test_EvenIfAlreadyCursed_Success() public { + RMN.Config memory cfg = rmnConstructorArgs(); + uint16 weightSum = 0; + for (uint256 i = 0; i < cfg.voters.length; ++i) { + vm.startPrank(cfg.voters[i].curseVoteAddr); + s_rmn.voteToCurse(makeCurseId(i), makeSubjects(0)); + weightSum += cfg.voters[i].curseWeight; + } + + // Not part of the assertion of this test but good to have as a sanity + // check. We want a curse to be active in order for the ultimate assertion + // to make sense. + assert(s_rmn.isCursed(0)); + + vm.expectEmit(); + emit RMN.VotedToCurse( + 1, // configVersion + cfg.voters[cfg.voters.length - 1].curseVoteAddr, + 0, // subject + makeCurseId(cfg.voters.length + 1), // this curse id + cfg.voters[cfg.voters.length - 1].curseWeight, + uint64(block.timestamp), // blockTimestamp + makeCursesHash(makeCurseId(cfg.voters.length - 1), makeCurseId(cfg.voters.length + 1)), // cursesHash + weightSum // accumulatedWeight + ); + // Asserts that this call to vote with a new curse id goes through with no + // reverts even when the RMN contract is cursed. + s_rmn.voteToCurse(makeCurseId(cfg.voters.length + 1), makeSubjects(0)); + } + + function test_OwnerCanCurseAndUncurse() public { + vm.startPrank(OWNER); + bytes28 expectedCursesHash = makeCursesHash(makeCurseId(0)); + vm.expectEmit(); + emit RMN.VotedToCurse( + 1, // configVersion + OWNER_CURSE_VOTE_ADDR, // owner + 0, // subject + makeCurseId(0), // curse id + 0, // weight + uint64(block.timestamp), // blockTimestamp + expectedCursesHash, // cursesHash + 0 // accumulatedWeight + ); + vm.expectEmit(); + emit RMN.Cursed( + 1, // configVersion + 0, // subject + uint64(block.timestamp) // blockTimestamp + ); + s_rmn.ownerCurse(makeCurseId(0), makeSubjects(0)); + + { + (address[] memory voters, bytes28[] memory cursesHashes, uint24 accWeight, bool cursed) = + s_rmn.getCurseProgress(0); + assertEq(voters.length, 1); + assertEq(voters[0], OWNER_CURSE_VOTE_ADDR /* owner */ ); + assertEq(cursesHashes.length, 1); + assertEq(cursesHashes[0], expectedCursesHash); + assertEq(accWeight, 0); + assertTrue(cursed); + } + + // ownerCurse again, should cause a vote to appear and a change in curses hash + expectedCursesHash = makeCursesHash(makeCurseId(0), makeCurseId(1)); + vm.expectEmit(); + emit RMN.VotedToCurse( + 1, // configVersion + OWNER_CURSE_VOTE_ADDR, // owner + 0, // subject + makeCurseId(1), // curse id + 0, // weight + uint64(block.timestamp), // blockTimestamp + expectedCursesHash, // cursesHash + 0 // accumulatedWeight + ); + s_rmn.ownerCurse(makeCurseId(1), makeSubjects(0)); + + { + (address[] memory voters, bytes28[] memory cursesHashes, uint24 accWeight, bool cursed) = + s_rmn.getCurseProgress(0); + assertEq(voters.length, 1); + assertEq(voters[0], OWNER_CURSE_VOTE_ADDR /* owner */ ); + assertEq(cursesHashes.length, 1); + assertEq(cursesHashes[0], expectedCursesHash); + assertEq(accWeight, 0); + assertTrue(cursed); + } + + RMN.OwnerUnvoteToCurseRequest[] memory unvoteReqs = new RMN.OwnerUnvoteToCurseRequest[](1); + unvoteReqs[0] = RMN.OwnerUnvoteToCurseRequest({ + curseVoteAddr: OWNER_CURSE_VOTE_ADDR, + unit: RMN.UnvoteToCurseRequest({subject: 0, cursesHash: 0}), + forceUnvote: true // TODO: test with forceUnvote false also + }); + vm.expectEmit(); + emit RMN.CurseLifted(0); + s_rmn.ownerUnvoteToCurse(unvoteReqs); + { + (address[] memory voters, bytes28[] memory cursesHashes, uint24 accWeight, bool cursed) = + s_rmn.getCurseProgress(0); + assertEq(voters.length, 0); + assertEq(cursesHashes.length, 0); + assertEq(accWeight, 0); + assertFalse(cursed); + } + } + + // Reverts + + function test_UnauthorizedVoter_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert(abi.encodeWithSelector(RMN.UnauthorizedVoter.selector, STRANGER)); + s_rmn.voteToCurse(makeCurseId(12312), makeSubjects(0)); + } + + function test_ReusedCurseId_Revert() public { + (address voter,) = _getFirstCurseVoterAndWeight(); + vm.startPrank(voter); + s_rmn.voteToCurse(makeCurseId(1), makeSubjects(0)); + + vm.expectRevert(abi.encodeWithSelector(RMN.ReusedCurseId.selector, voter, makeCurseId(1))); + s_rmn.voteToCurse(makeCurseId(1), makeSubjects(0)); + } + + function test_RepeatedSubject_Revert() public { + (address voter,) = _getFirstCurseVoterAndWeight(); + vm.prank(voter); + + bytes16 subject = bytes16(uint128(1)); + + vm.expectRevert(RMN.SubjectsMustBeStrictlyIncreasing.selector); + s_rmn.voteToCurse(makeCurseId(1), makeSubjects(subject, subject)); + } + + function test_EmptySubjects_Revert() public { + (address voter,) = _getFirstCurseVoterAndWeight(); + vm.prank(voter); + + vm.expectRevert(RMN.VoteToCurseNoop.selector); + s_rmn.voteToCurse(makeCurseId(1), new bytes16[](0)); + } +} + +contract RMN_ownerUnvoteToCurse is RMNSetup { + // These cursers are going to curse in setUp curseCount times. + function getCursersAndCurseCounts() internal pure returns (address[] memory cursers, uint32[] memory curseCounts) { + // NOTE: Change this when changing setUp or rmnConstructorArgs. + // This is a bit ugly and error prone but if we read from storage we would + // not get an accurate gas reading for ownerUnvoteToCurse when we need it. + cursers = new address[](4); + cursers[0] = CURSE_VOTER_1; + cursers[1] = CURSE_VOTER_2; + cursers[2] = CURSE_VOTER_3; + cursers[3] = CURSE_VOTER_4; + curseCounts = new uint32[](cursers.length); + for (uint256 i = 0; i < cursers.length; ++i) { + curseCounts[i] = 1; + } + } + + function setUp() public virtual override { + RMNSetup.setUp(); + (address[] memory cursers, uint32[] memory curseCounts) = getCursersAndCurseCounts(); + for (uint256 i = 0; i < cursers.length; ++i) { + vm.startPrank(cursers[i]); + for (uint256 j = 0; j < curseCounts[i]; ++j) { + s_rmn.voteToCurse(makeCurseId(j), makeSubjects(GLOBAL_CURSE_SUBJECT)); + } + } + } + + function ownerUnvoteToCurse() internal { + s_rmn.ownerUnvoteToCurse(makeOwnerUnvoteToCurseRequests()); + } + + function makeOwnerUnvoteToCurseRequests() internal pure returns (RMN.OwnerUnvoteToCurseRequest[] memory) { + (address[] memory cursers,) = getCursersAndCurseCounts(); + RMN.OwnerUnvoteToCurseRequest[] memory reqs = new RMN.OwnerUnvoteToCurseRequest[](cursers.length); + for (uint256 i = 0; i < cursers.length; ++i) { + reqs[i] = RMN.OwnerUnvoteToCurseRequest({ + curseVoteAddr: cursers[i], + unit: RMN.UnvoteToCurseRequest({subject: GLOBAL_CURSE_SUBJECT, cursesHash: bytes28(0)}), + forceUnvote: true + }); + } + return reqs; + } + + // Success + + function test_OwnerUnvoteToCurseSuccess_gas() public { + vm.pauseGasMetering(); + vm.startPrank(OWNER); + + vm.expectEmit(); + emit RMN.CurseLifted(GLOBAL_CURSE_SUBJECT); + + vm.resumeGasMetering(); + ownerUnvoteToCurse(); + vm.pauseGasMetering(); + + assertFalse(s_rmn.isCursed()); + (address[] memory voters, bytes28[] memory cursesHashes, uint256 weight, bool cursed) = + s_rmn.getCurseProgress(GLOBAL_CURSE_SUBJECT); + assertEq(voters.length, 0); + assertEq(cursesHashes.length, 0); + assertEq(weight, 0); + assertFalse(cursed); + vm.resumeGasMetering(); + } + + function test_IsIdempotent() public { + vm.startPrank(OWNER); + ownerUnvoteToCurse(); + vm.expectRevert(RMN.UnvoteToCurseNoop.selector); + ownerUnvoteToCurse(); + + assertFalse(s_rmn.isCursed()); + (address[] memory voters, bytes28[] memory cursesHashes, uint256 weight, bool cursed) = + s_rmn.getCurseProgress(GLOBAL_CURSE_SUBJECT); + assertEq(voters.length, 0); + assertEq(cursesHashes.length, 0); + assertEq(weight, 0); + assertFalse(cursed); + } + + function test_CanBlessAndCurseAfterGlobalCurseIsLifted() public { + // Contract is already cursed due to setUp. + + // Owner unvotes to curse. + vm.startPrank(OWNER); + vm.expectEmit(); + emit RMN.CurseLifted(GLOBAL_CURSE_SUBJECT); + ownerUnvoteToCurse(); + + // Contract is now uncursed. + assertFalse(s_rmn.isCursed()); + + // Vote to bless should go through. + vm.startPrank(BLESS_VOTER_1); + s_rmn.voteToBless(makeTaggedRootSingleton(2387489729)); + + // Vote to curse should go through. + vm.startPrank(CURSE_VOTER_1); + s_rmn.voteToCurse(makeCurseId(73894728973), makeSubjects(GLOBAL_CURSE_SUBJECT)); + } + + // Reverts + + function test_NonOwner_Revert() public { + vm.startPrank(STRANGER); + vm.expectRevert("Only callable by owner"); + ownerUnvoteToCurse(); + } + + function test_UnknownVoter_Revert() public { + vm.stopPrank(); + RMN.OwnerUnvoteToCurseRequest[] memory reqs = new RMN.OwnerUnvoteToCurseRequest[](1); + reqs[0] = RMN.OwnerUnvoteToCurseRequest({ + curseVoteAddr: STRANGER, + unit: RMN.UnvoteToCurseRequest({subject: GLOBAL_CURSE_SUBJECT, cursesHash: bytes28(0)}), + forceUnvote: true + }); + + vm.prank(OWNER); + vm.expectEmit(); + emit RMN.SkippedUnvoteToCurse(STRANGER, GLOBAL_CURSE_SUBJECT, bytes28(0), bytes28(0)); + vm.expectRevert(RMN.UnvoteToCurseNoop.selector); + s_rmn.ownerUnvoteToCurse(reqs); + + // no effect on cursedness + assertTrue(s_rmn.isCursed(GLOBAL_CURSE_SUBJECT)); + } +} + +contract RMN_setConfig is ConfigCompare, RMNSetup { + /// @notice Test-specific function to use only in setConfig tests + function getDifferentConfigArgs() private pure returns (RMN.Config memory) { + RMN.Voter[] memory voters = new RMN.Voter[](2); + voters[0] = RMN.Voter({ + blessVoteAddr: BLESS_VOTER_1, + curseVoteAddr: CURSE_VOTER_1, + blessWeight: WEIGHT_1, + curseWeight: WEIGHT_1 + }); + voters[1] = RMN.Voter({ + blessVoteAddr: BLESS_VOTER_2, + curseVoteAddr: CURSE_VOTER_2, + blessWeight: WEIGHT_10, + curseWeight: WEIGHT_10 + }); + return RMN.Config({ + voters: voters, + blessWeightThreshold: WEIGHT_1 + WEIGHT_10, + curseWeightThreshold: WEIGHT_1 + WEIGHT_10 + }); + } + + function setUp() public virtual override { + RMNSetup.setUp(); + RMN.Config memory cfg = rmnConstructorArgs(); + + // Setup some partial state + vm.startPrank(cfg.voters[0].blessVoteAddr); + s_rmn.voteToBless(makeTaggedRootSingleton(1)); + vm.startPrank(cfg.voters[1].blessVoteAddr); + s_rmn.voteToBless(makeTaggedRootSingleton(1)); + vm.startPrank(cfg.voters[1].curseVoteAddr); + s_rmn.voteToCurse(makeCurseId(1), makeSubjects(0)); + } + + // Success + + event ConfigSet(uint32 indexed configVersion, RMN.Config config); + + function test_VoteToBlessByEjectedVoter_Revert() public { + // Previous config included BLESS_VOTER_4. Change to new config that doesn't. + RMN.Config memory cfg = getDifferentConfigArgs(); + vm.startPrank(OWNER); + s_rmn.setConfig(cfg); + + // BLESS_VOTER_4 is not part of cfg anymore, vote to bless should revert. + vm.startPrank(BLESS_VOTER_4); + vm.expectRevert(abi.encodeWithSelector(RMN.UnauthorizedVoter.selector, BLESS_VOTER_4)); + s_rmn.voteToBless(makeTaggedRootSingleton(2)); + } + + function test_SetConfigSuccess_gas() public { + vm.pauseGasMetering(); + RMN.Config memory cfg = getDifferentConfigArgs(); + + vm.startPrank(OWNER); + vm.expectEmit(); + emit ConfigSet(2, cfg); + + (uint32 configVersionBefore,,) = s_rmn.getConfigDetails(); + vm.resumeGasMetering(); + s_rmn.setConfig(cfg); + vm.pauseGasMetering(); + // Assert VersionedConfig has changed correctly + (uint32 configVersionAfter,, RMN.Config memory configAfter) = s_rmn.getConfigDetails(); + assertEq(configVersionBefore + 1, configVersionAfter); + assertConfigEq(configAfter, cfg); + + // Assert that curse votes have been cleared + + (address[] memory curseVoters, bytes28[] memory cursesHashes, uint256 curseWeight, bool cursed) = + s_rmn.getCurseProgress(0); + assertEq(0, curseVoters.length); + assertEq(0, cursesHashes.length); + assertEq(0, curseWeight); + assertFalse(cursed); + + // Assert that good votes have been cleared + uint256 votesToBlessRoot = getWeightOfVotesToBlessRoot(makeTaggedRoot(1)); + assertEq(ZERO, votesToBlessRoot); + assertFalse(hasVotedToBlessRoot(cfg.voters[0].blessVoteAddr, makeTaggedRoot(1))); + assertFalse(hasVotedToBlessRoot(cfg.voters[1].blessVoteAddr, makeTaggedRoot(1))); + vm.resumeGasMetering(); + } + + // Reverts + + function test_NonOwner_Revert() public { + RMN.Config memory cfg = getDifferentConfigArgs(); + + vm.startPrank(STRANGER); + vm.expectRevert("Only callable by owner"); + s_rmn.setConfig(cfg); + } + + function test_VotersLengthIsZero_Revert() public { + vm.startPrank(OWNER); + vm.expectRevert(RMN.InvalidConfig.selector); + s_rmn.setConfig(RMN.Config({voters: new RMN.Voter[](0), blessWeightThreshold: 1, curseWeightThreshold: 1})); + } + + function test_EitherThresholdIsZero_Revert() public { + RMN.Config memory cfg = getDifferentConfigArgs(); + + vm.startPrank(OWNER); + vm.expectRevert(RMN.InvalidConfig.selector); + s_rmn.setConfig( + RMN.Config({voters: cfg.voters, blessWeightThreshold: ZERO, curseWeightThreshold: cfg.curseWeightThreshold}) + ); + vm.expectRevert(RMN.InvalidConfig.selector); + s_rmn.setConfig( + RMN.Config({voters: cfg.voters, blessWeightThreshold: cfg.blessWeightThreshold, curseWeightThreshold: ZERO}) + ); + } + + function test_BlessVoterIsZeroAddress_Revert() public { + RMN.Config memory cfg = getDifferentConfigArgs(); + + vm.startPrank(OWNER); + cfg.voters[0].blessVoteAddr = ZERO_ADDRESS; + vm.expectRevert(RMN.InvalidConfig.selector); + s_rmn.setConfig(cfg); + } + + function test_WeightIsZeroAddress_Revert() public { + RMN.Config memory cfg = getDifferentConfigArgs(); + + vm.startPrank(OWNER); + cfg.voters[0].blessWeight = ZERO; + cfg.voters[0].curseWeight = ZERO; + vm.expectRevert(RMN.InvalidConfig.selector); + s_rmn.setConfig(cfg); + } + + function test_TotalWeightsSmallerThanEachThreshold_Revert() public { + RMN.Config memory cfg = getDifferentConfigArgs(); + + vm.startPrank(OWNER); + vm.expectRevert(RMN.InvalidConfig.selector); + s_rmn.setConfig( + RMN.Config({voters: cfg.voters, blessWeightThreshold: WEIGHT_40, curseWeightThreshold: cfg.curseWeightThreshold}) + ); + vm.expectRevert(RMN.InvalidConfig.selector); + s_rmn.setConfig( + RMN.Config({voters: cfg.voters, blessWeightThreshold: cfg.blessWeightThreshold, curseWeightThreshold: WEIGHT_40}) + ); + } + + function test_RepeatedAddress_Revert() public { + RMN.Config memory cfg = getDifferentConfigArgs(); + + vm.startPrank(OWNER); + cfg.voters[0].blessVoteAddr = cfg.voters[1].curseVoteAddr; + vm.expectRevert(RMN.InvalidConfig.selector); + s_rmn.setConfig(cfg); + } +} + +contract RMN_permaBlessing is RMNSetup { + function addresses() private pure returns (address[] memory) { + return new address[](0); + } + + function addresses(address a) private pure returns (address[] memory) { + address[] memory arr = new address[](1); + arr[0] = a; + return arr; + } + + function addresses(address a, address b) private pure returns (address[] memory) { + address[] memory arr = new address[](2); + arr[0] = a; + arr[1] = b; + return arr; + } + + function test_PermaBlessing() public { + bytes32 SOME_ROOT = bytes32(~uint256(0)); + address COMMIT_STORE_1 = makeAddr("COMMIT_STORE_1"); + address COMMIT_STORE_2 = makeAddr("COMMIT_STORE_2"); + IRMN.TaggedRoot memory taggedRootCommitStore1 = IRMN.TaggedRoot({root: SOME_ROOT, commitStore: COMMIT_STORE_1}); + IRMN.TaggedRoot memory taggedRootCommitStore2 = IRMN.TaggedRoot({root: SOME_ROOT, commitStore: COMMIT_STORE_2}); + + assertFalse(s_rmn.isBlessed(taggedRootCommitStore1)); + assertFalse(s_rmn.isBlessed(taggedRootCommitStore2)); + assertEq(s_rmn.getPermaBlessedCommitStores(), addresses()); + + // only owner can mutate permaBlessedCommitStores + vm.prank(STRANGER); + vm.expectRevert("Only callable by owner"); + s_rmn.ownerRemoveThenAddPermaBlessedCommitStores(addresses(), addresses(COMMIT_STORE_1)); + + vm.prank(OWNER); + s_rmn.ownerRemoveThenAddPermaBlessedCommitStores(addresses(), addresses(COMMIT_STORE_1)); + assertTrue(s_rmn.isBlessed(taggedRootCommitStore1)); + assertFalse(s_rmn.isBlessed(taggedRootCommitStore2)); + assertEq(s_rmn.getPermaBlessedCommitStores(), addresses(COMMIT_STORE_1)); + + vm.prank(OWNER); + s_rmn.ownerRemoveThenAddPermaBlessedCommitStores(addresses(COMMIT_STORE_1), addresses(COMMIT_STORE_2)); + assertFalse(s_rmn.isBlessed(taggedRootCommitStore1)); + assertTrue(s_rmn.isBlessed(taggedRootCommitStore2)); + assertEq(s_rmn.getPermaBlessedCommitStores(), addresses(COMMIT_STORE_2)); + + vm.prank(OWNER); + s_rmn.ownerRemoveThenAddPermaBlessedCommitStores(addresses(), addresses(COMMIT_STORE_1)); + assertTrue(s_rmn.isBlessed(taggedRootCommitStore1)); + assertTrue(s_rmn.isBlessed(taggedRootCommitStore2)); + assertEq(s_rmn.getPermaBlessedCommitStores(), addresses(COMMIT_STORE_2, COMMIT_STORE_1)); + + vm.prank(OWNER); + s_rmn.ownerRemoveThenAddPermaBlessedCommitStores(addresses(COMMIT_STORE_1, COMMIT_STORE_2), addresses()); + assertFalse(s_rmn.isBlessed(taggedRootCommitStore1)); + assertFalse(s_rmn.isBlessed(taggedRootCommitStore2)); + assertEq(s_rmn.getPermaBlessedCommitStores(), addresses()); + } +} + +contract RMN_getRecordedCurseRelatedOps is RMNSetup { + function test_OpsPostDeployment() public { + // The constructor call includes a setConfig, so that's the only thing we should expect to find. + assertEq(s_rmn.getRecordedCurseRelatedOpsCount(), 1); + RMN.RecordedCurseRelatedOp[] memory recordedCurseRelatedOps = s_rmn.getRecordedCurseRelatedOps(0, type(uint256).max); + assertEq(recordedCurseRelatedOps.length, 1); + assertEq(uint8(recordedCurseRelatedOps[0].tag), uint8(RMN.RecordedCurseRelatedOpTag.SetConfig)); + } +} diff --git a/contracts/src/v0.8/ccip/test/arm/RMNSetup.t.sol b/contracts/src/v0.8/ccip/test/arm/RMNSetup.t.sol new file mode 100644 index 0000000000..8feacb95f4 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/arm/RMNSetup.t.sol @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {RMN} from "../../RMN.sol"; +import {IRMN} from "../../interfaces/IRMN.sol"; + +import {Test} from "forge-std/Test.sol"; + +function makeSubjects(bytes16 a) pure returns (bytes16[] memory) { + bytes16[] memory subjects = new bytes16[](1); + subjects[0] = a; + return subjects; +} + +function makeSubjects(bytes16 a, bytes16 b) pure returns (bytes16[] memory) { + bytes16[] memory subjects = new bytes16[](2); + subjects[0] = a; + subjects[1] = b; + return subjects; +} + +// in order from earliest to latest curse ids +function makeCursesHashFromList(bytes32[] memory curseIds) pure returns (bytes28 cursesHash) { + for (uint256 i = 0; i < curseIds.length; ++i) { + cursesHash = bytes28(keccak256(abi.encode(cursesHash, curseIds[i]))); + } +} + +// hides the ugliness from tests +function makeCursesHash(bytes32 a) pure returns (bytes28) { + bytes32[] memory curseIds = new bytes32[](1); + curseIds[0] = a; + return makeCursesHashFromList(curseIds); +} + +function makeCursesHash(bytes32 a, bytes32 b) pure returns (bytes28) { + bytes32[] memory curseIds = new bytes32[](2); + curseIds[0] = a; + curseIds[1] = b; + return makeCursesHashFromList(curseIds); +} + +contract RMNSetup is Test { + // Addresses + address internal constant OWNER = 0x00007e64E1fB0C487F25dd6D3601ff6aF8d32e4e; + address internal constant STRANGER = address(999999); + address internal constant ZERO_ADDRESS = address(0); + address internal constant BLESS_VOTER_1 = address(1); + address internal constant CURSE_VOTER_1 = address(10); + address internal constant BLESS_VOTER_2 = address(2); + address internal constant CURSE_VOTER_2 = address(12); + address internal constant BLESS_VOTER_3 = address(3); + address internal constant CURSE_VOTER_3 = address(13); + address internal constant BLESS_VOTER_4 = address(4); + address internal constant CURSE_VOTER_4 = address(14); + + // Arm + function rmnConstructorArgs() internal pure returns (RMN.Config memory) { + RMN.Voter[] memory voters = new RMN.Voter[](4); + voters[0] = RMN.Voter({ + blessVoteAddr: BLESS_VOTER_1, + curseVoteAddr: CURSE_VOTER_1, + blessWeight: WEIGHT_1, + curseWeight: WEIGHT_1 + }); + voters[1] = RMN.Voter({ + blessVoteAddr: BLESS_VOTER_2, + curseVoteAddr: CURSE_VOTER_2, + blessWeight: WEIGHT_10, + curseWeight: WEIGHT_10 + }); + voters[2] = RMN.Voter({ + blessVoteAddr: BLESS_VOTER_3, + curseVoteAddr: CURSE_VOTER_3, + blessWeight: WEIGHT_20, + curseWeight: WEIGHT_20 + }); + voters[3] = RMN.Voter({ + blessVoteAddr: BLESS_VOTER_4, + curseVoteAddr: CURSE_VOTER_4, + blessWeight: WEIGHT_40, + curseWeight: WEIGHT_40 + }); + return RMN.Config({ + voters: voters, + blessWeightThreshold: WEIGHT_10 + WEIGHT_20 + WEIGHT_40, + curseWeightThreshold: WEIGHT_1 + WEIGHT_10 + WEIGHT_20 + WEIGHT_40 + }); + } + + uint8 internal constant ZERO = 0; + uint8 internal constant WEIGHT_1 = 1; + uint8 internal constant WEIGHT_10 = 10; + uint8 internal constant WEIGHT_20 = 20; + uint8 internal constant WEIGHT_40 = 40; + + function makeTaggedRootsInclusive(uint256 from, uint256 to) internal pure returns (IRMN.TaggedRoot[] memory) { + IRMN.TaggedRoot[] memory votes = new IRMN.TaggedRoot[](to - from + 1); + for (uint256 i = from; i <= to; ++i) { + votes[i - from] = IRMN.TaggedRoot({commitStore: address(1), root: bytes32(uint256(i))}); + } + return votes; + } + + function makeTaggedRootSingleton(uint256 index) internal pure returns (IRMN.TaggedRoot[] memory) { + return makeTaggedRootsInclusive(index, index); + } + + function makeTaggedRoot(uint256 index) internal pure returns (IRMN.TaggedRoot memory) { + return makeTaggedRootSingleton(index)[0]; + } + + function makeTaggedRootHash(uint256 index) internal pure returns (bytes32) { + IRMN.TaggedRoot memory taggedRoot = makeTaggedRootSingleton(index)[0]; + return keccak256(abi.encode(taggedRoot.commitStore, taggedRoot.root)); + } + + function makeCurseId(uint256 index) internal pure returns (bytes16) { + return bytes16(uint128(index)); + } + + RMN internal s_rmn; + + function setUp() public virtual { + vm.startPrank(OWNER); + s_rmn = new RMN(rmnConstructorArgs()); + vm.stopPrank(); + } + + function hasVotedToBlessRoot(address voter, IRMN.TaggedRoot memory taggedRoot_) internal view returns (bool) { + (address[] memory voters,,) = s_rmn.getBlessProgress(taggedRoot_); + for (uint256 i = 0; i < voters.length; ++i) { + if (voters[i] == voter) { + return true; + } + } + return false; + } + + function getWeightOfVotesToBlessRoot(IRMN.TaggedRoot memory taggedRoot_) internal view returns (uint16) { + (, uint16 weight,) = s_rmn.getBlessProgress(taggedRoot_); + return weight; + } +} diff --git a/contracts/src/v0.8/ccip/test/arm/RMN_benchmark.t.sol b/contracts/src/v0.8/ccip/test/arm/RMN_benchmark.t.sol new file mode 100644 index 0000000000..8564614a74 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/arm/RMN_benchmark.t.sol @@ -0,0 +1,217 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {GLOBAL_CURSE_SUBJECT, OWNER_CURSE_VOTE_ADDR, RMN} from "../../RMN.sol"; +import {RMNSetup, makeCursesHash, makeSubjects} from "./RMNSetup.t.sol"; + +contract RMN_voteToBless_Benchmark is RMNSetup { + function test_RootSuccess_gas(uint256 n) internal { + vm.prank(BLESS_VOTER_1); + s_rmn.voteToBless(makeTaggedRootsInclusive(1, n)); + } + + function test_1RootSuccess_gas() public { + test_RootSuccess_gas(1); + } + + function test_3RootSuccess_gas() public { + test_RootSuccess_gas(3); + } + + function test_5RootSuccess_gas() public { + test_RootSuccess_gas(5); + } +} + +contract RMN_voteToBless_Blessed_Benchmark is RMN_voteToBless_Benchmark { + function setUp() public virtual override { + RMNSetup.setUp(); + vm.prank(BLESS_VOTER_2); + s_rmn.voteToBless(makeTaggedRootsInclusive(1, 1)); + vm.prank(BLESS_VOTER_3); + s_rmn.voteToBless(makeTaggedRootsInclusive(1, 1)); + } + + function test_1RootSuccessBecameBlessed_gas() public { + vm.prank(BLESS_VOTER_4); + s_rmn.voteToBless(makeTaggedRootsInclusive(1, 1)); + } +} + +abstract contract RMN_voteToCurse_Benchmark is RMNSetup { + struct PreVote { + address voter; + bytes16 subject; + } + + PreVote[] internal s_preVotes; + + function setUp() public virtual override { + // Intentionally does not inherit RMNSetup setUp(), because we set up a simpler config here. + // The only way to ensure that storage slots are cold for the actual functions to be benchmarked is to perform the + // setup in setUp(). + + RMN.Config memory cfg = RMN.Config({voters: new RMN.Voter[](3), blessWeightThreshold: 3, curseWeightThreshold: 3}); + cfg.voters[0] = + RMN.Voter({blessVoteAddr: BLESS_VOTER_1, curseVoteAddr: CURSE_VOTER_1, blessWeight: 1, curseWeight: 1}); + cfg.voters[1] = + RMN.Voter({blessVoteAddr: BLESS_VOTER_2, curseVoteAddr: CURSE_VOTER_2, blessWeight: 1, curseWeight: 1}); + cfg.voters[2] = + RMN.Voter({blessVoteAddr: BLESS_VOTER_3, curseVoteAddr: CURSE_VOTER_3, blessWeight: 1, curseWeight: 1}); + vm.prank(OWNER); + s_rmn = new RMN(cfg); + + for (uint256 i = 0; i < s_preVotes.length; ++i) { + vm.prank(s_preVotes[i].voter); + s_rmn.voteToCurse(makeCurseId(i), makeSubjects(s_preVotes[i].subject)); + } + } +} + +contract RMN_voteToCurse_Benchmark_1 is RMN_voteToCurse_Benchmark { + constructor() { + // some irrelevant subject & voter so that we don't pay for the nonzero->zero SSTORE of + // s_recordedVotesToCurse.length in the benchmark below + s_preVotes.push(PreVote({voter: CURSE_VOTER_3, subject: bytes16(~uint128(0))})); + } + + function test_VoteToCurse_NewSubject_NewVoter_NoCurse_gas() public { + vm.prank(CURSE_VOTER_1); + s_rmn.voteToCurse(makeCurseId(0xffff), makeSubjects(GLOBAL_CURSE_SUBJECT)); + } + + function test_VoteToCurse_NewSubject_NewVoter_YesCurse_gas() public { + vm.prank(OWNER); + s_rmn.ownerCurse(makeCurseId(0xffff), makeSubjects(GLOBAL_CURSE_SUBJECT)); + } +} + +contract RMN_voteToCurse_Benchmark_2 is RMN_voteToCurse_Benchmark { + constructor() { + s_preVotes.push(PreVote({voter: CURSE_VOTER_1, subject: GLOBAL_CURSE_SUBJECT})); + } + + function test_VoteToCurse_OldSubject_OldVoter_NoCurse_gas() public { + vm.prank(CURSE_VOTER_1); + s_rmn.voteToCurse(makeCurseId(0xffff), makeSubjects(GLOBAL_CURSE_SUBJECT)); + } + + function test_VoteToCurse_OldSubject_NewVoter_NoCurse_gas() public { + vm.prank(CURSE_VOTER_2); + s_rmn.voteToCurse(makeCurseId(0xffff), makeSubjects(GLOBAL_CURSE_SUBJECT)); + } +} + +contract RMN_voteToCurse_Benchmark_3 is RMN_voteToCurse_Benchmark { + constructor() { + s_preVotes.push(PreVote({voter: CURSE_VOTER_1, subject: GLOBAL_CURSE_SUBJECT})); + s_preVotes.push(PreVote({voter: CURSE_VOTER_2, subject: GLOBAL_CURSE_SUBJECT})); + } + + function test_VoteToCurse_OldSubject_NewVoter_YesCurse_gas() public { + vm.prank(CURSE_VOTER_3); + s_rmn.voteToCurse(makeCurseId(0xffff), makeSubjects(GLOBAL_CURSE_SUBJECT)); + } +} + +contract RMN_lazyVoteToCurseUpdate_Benchmark is RMN_voteToCurse_Benchmark { + constructor() { + s_preVotes.push(PreVote({voter: CURSE_VOTER_1, subject: GLOBAL_CURSE_SUBJECT})); + s_preVotes.push(PreVote({voter: CURSE_VOTER_2, subject: GLOBAL_CURSE_SUBJECT})); + s_preVotes.push(PreVote({voter: CURSE_VOTER_3, subject: GLOBAL_CURSE_SUBJECT})); + } + + function setUp() public override { + RMN_voteToCurse_Benchmark.setUp(); // sends the prevotes + // initial config includes voters CURSE_VOTER_1, CURSE_VOTER_2, CURSE_VOTER_3 + // include a new voter in the config + { + (,, RMN.Config memory cfg) = s_rmn.getConfigDetails(); + RMN.Voter[] memory newVoters = new RMN.Voter[](cfg.voters.length + 1); + for (uint256 i = 0; i < cfg.voters.length; ++i) { + newVoters[i] = cfg.voters[i]; + } + newVoters[newVoters.length - 1] = + RMN.Voter({blessVoteAddr: BLESS_VOTER_4, curseVoteAddr: CURSE_VOTER_4, blessWeight: 1, curseWeight: 1}); + cfg.voters = newVoters; + + vm.prank(OWNER); + s_rmn.setConfig(cfg); + } + } + + function test_VoteToCurseLazilyRetain3VotersUponConfigChange_gas() public { + // send a vote as the new voter, should cause a lazy update and votes from CURSE_VOTER_1, CURSE_VOTER_2, + // CURSE_VOTER_3 to be retained, which is the worst case for the prior config + vm.prank(CURSE_VOTER_4); + s_rmn.voteToCurse(makeCurseId(0xffff), makeSubjects(GLOBAL_CURSE_SUBJECT)); + } +} + +contract RMN_setConfig_Benchmark is RMNSetup { + uint256 s_numVoters; + + function configWithVoters(uint256 numVoters) internal pure returns (RMN.Config memory) { + RMN.Config memory cfg = + RMN.Config({voters: new RMN.Voter[](numVoters), blessWeightThreshold: 1, curseWeightThreshold: 1}); + for (uint256 i = 1; i <= numVoters; ++i) { + cfg.voters[i - 1] = RMN.Voter({ + blessVoteAddr: address(uint160(2 * i)), + curseVoteAddr: address(uint160(2 * i + 1)), + blessWeight: 1, + curseWeight: 1 + }); + } + return cfg; + } + + function setUp() public virtual override { + vm.prank(OWNER); + s_rmn = new RMN(configWithVoters(s_numVoters)); + } +} + +contract RMN_setConfig_Benchmark_1 is RMN_setConfig_Benchmark { + constructor() { + s_numVoters = 1; + } + + function test_SetConfig_7Voters_gas() public { + vm.prank(OWNER); + s_rmn.setConfig(configWithVoters(7)); + } +} + +contract RMN_setConfig_Benchmark_2 is RMN_setConfig_Benchmark { + constructor() { + s_numVoters = 7; + } + + function test_ResetConfig_7Voters_gas() public { + vm.prank(OWNER); + s_rmn.setConfig(configWithVoters(7)); + } +} + +contract RMN_ownerUnvoteToCurse_Benchmark is RMN_setConfig_Benchmark { + constructor() { + s_numVoters = 7; + } + + function setUp() public override { + RMN_setConfig_Benchmark.setUp(); + vm.prank(OWNER); + s_rmn.ownerCurse(makeCurseId(0xffff), makeSubjects(GLOBAL_CURSE_SUBJECT)); + } + + function test_OwnerUnvoteToCurse_1Voter_LiftsCurse_gas() public { + RMN.OwnerUnvoteToCurseRequest[] memory reqs = new RMN.OwnerUnvoteToCurseRequest[](1); + reqs[0] = RMN.OwnerUnvoteToCurseRequest({ + curseVoteAddr: OWNER_CURSE_VOTE_ADDR, + unit: RMN.UnvoteToCurseRequest({cursesHash: makeCursesHash(makeCurseId(0xffff)), subject: GLOBAL_CURSE_SUBJECT}), + forceUnvote: false + }); + vm.prank(OWNER); + s_rmn.ownerUnvoteToCurse(reqs); + } +} diff --git a/contracts/src/v0.8/ccip/test/attacks/onRamp/FacadeClient.sol b/contracts/src/v0.8/ccip/test/attacks/onRamp/FacadeClient.sol new file mode 100644 index 0000000000..ad549e6ccc --- /dev/null +++ b/contracts/src/v0.8/ccip/test/attacks/onRamp/FacadeClient.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IRouterClient} from "../../../interfaces/IRouterClient.sol"; + +import {Client} from "../../../libraries/Client.sol"; + +import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +/// @title FacadeClient - A simple proxy for calling Router +contract FacadeClient { + address private immutable i_router; + uint64 private immutable i_destChainSelector; + IERC20 private immutable i_sourceToken; + IERC20 private immutable i_feeToken; + address private immutable i_receiver; + + uint256 private s_msg_sequence = 1; + + constructor(address router, uint64 destChainSelector, IERC20 sourceToken, IERC20 feeToken, address receiver) { + i_router = router; + i_destChainSelector = destChainSelector; + i_sourceToken = sourceToken; + i_feeToken = feeToken; + i_receiver = receiver; + + sourceToken.approve(address(router), 2 ** 256 - 1); + feeToken.approve(address(router), 2 ** 256 - 1); + } + + /// @dev Calls Router to initiate CCIP send. + /// The expectation is that s_msg_sequence will always match the sequence in emitted CCIP messages. + function send(uint256 amount) public { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0].token = address(i_sourceToken); + tokenAmounts[0].amount = amount; + + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(i_receiver), + data: abi.encodePacked(s_msg_sequence), + tokenAmounts: tokenAmounts, + extraArgs: "", + feeToken: address(i_feeToken) + }); + + s_msg_sequence++; + + IRouterClient(i_router).ccipSend(i_destChainSelector, message); + } + + function getSequence() public view returns (uint256) { + return s_msg_sequence; + } +} diff --git a/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol b/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol new file mode 100644 index 0000000000..5deeda6406 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {Client} from "../../../libraries/Client.sol"; +import {Internal} from "../../../libraries/Internal.sol"; +import {EVM2EVMMultiOnRamp} from "../../../onRamp/EVM2EVMMultiOnRamp.sol"; +import {TokenPool} from "../../../pools/TokenPool.sol"; +import {EVM2EVMMultiOnRampSetup} from "../../onRamp/EVM2EVMMultiOnRampSetup.t.sol"; +import {FacadeClient} from "./FacadeClient.sol"; +import {ReentrantMaliciousTokenPool} from "./ReentrantMaliciousTokenPool.sol"; + +import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +import {console} from "forge-std/console.sol"; + +/// @title MultiOnRampTokenPoolReentrancy +/// Attempts to perform a reentrancy exploit on Onramp with a malicious TokenPool +contract MultiOnRampTokenPoolReentrancy is EVM2EVMMultiOnRampSetup { + FacadeClient internal s_facadeClient; + ReentrantMaliciousTokenPool internal s_maliciousTokenPool; + IERC20 internal s_sourceToken; + IERC20 internal s_feeToken; + address internal immutable i_receiver = makeAddr("receiver"); + + function setUp() public virtual override { + EVM2EVMMultiOnRampSetup.setUp(); + + s_sourceToken = IERC20(s_sourceTokens[0]); + s_feeToken = IERC20(s_sourceTokens[0]); + + s_facadeClient = + new FacadeClient(address(s_sourceRouter), DEST_CHAIN_SELECTOR, s_sourceToken, s_feeToken, i_receiver); + + s_maliciousTokenPool = new ReentrantMaliciousTokenPool( + address(s_facadeClient), s_sourceToken, address(s_mockRMN), address(s_sourceRouter) + ); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(s_destPoolBySourceToken[s_sourceTokens[0]]), + remoteTokenAddress: abi.encode(s_destTokens[0]), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_maliciousTokenPool.applyChainUpdates(chainUpdates); + s_sourcePoolByToken[address(s_sourceToken)] = address(s_maliciousTokenPool); + + Internal.PoolUpdate[] memory removes = new Internal.PoolUpdate[](1); + removes[0].token = address(s_sourceToken); + removes[0].pool = address(s_sourcePoolByToken[address(s_sourceToken)]); + Internal.PoolUpdate[] memory adds = new Internal.PoolUpdate[](1); + adds[0].token = address(s_sourceToken); + adds[0].pool = address(s_maliciousTokenPool); + + s_tokenAdminRegistry.setPool(address(s_sourceToken), address(s_maliciousTokenPool)); + + s_sourceToken.transfer(address(s_facadeClient), 1e18); + s_feeToken.transfer(address(s_facadeClient), 1e18); + } + + /// @dev This test was used to showcase a reentrancy exploit on OnRamp with malicious TokenPool. + /// How it worked: OnRamp used to construct EVM2Any messages after calling TokenPool's lockOrBurn. + /// This allowed the malicious TokenPool to break message sequencing expectations as follows: + /// Any user -> Facade -> 1st call to ccipSend -> pool’s lockOrBurn —> + /// (reenter)-> Facade -> 2nd call to ccipSend + /// In this case, Facade's second call would produce an EVM2Any msg with a lower sequence number. + /// The issue was fixed by moving state updates and event construction to before TokenPool calls. + /// This test is kept to verify message sequence expectations are not broken. + function test_OnRampTokenPoolReentrancy_Success() public { + uint256 amount = 1; + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0].token = address(s_sourceToken); + tokenAmounts[0].amount = amount; + + Client.EVM2AnyMessage memory message1 = Client.EVM2AnyMessage({ + receiver: abi.encode(i_receiver), + data: abi.encodePacked(uint256(1)), // message 1 contains data 1 + tokenAmounts: tokenAmounts, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000})), + feeToken: address(s_feeToken) + }); + + Client.EVM2AnyMessage memory message2 = Client.EVM2AnyMessage({ + receiver: abi.encode(i_receiver), + data: abi.encodePacked(uint256(2)), // message 2 contains data 2 + tokenAmounts: tokenAmounts, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000})), + feeToken: address(s_feeToken) + }); + + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message1); + assertGt(expectedFee, 0); + + // Outcome of a successful exploit: + // Message 1 event from OnRamp contains sequence/nonce 2, message 2 contains sequence/nonce 1 + // Internal.EVM2EVMMessage memory msgEvent1 = _messageToEvent(message1, 2, 2, expectedFee, address(s_facadeClient)); + // Internal.EVM2EVMMessage memory msgEvent2 = _messageToEvent(message2, 1, 1, expectedFee, address(s_facadeClient)); + + // vm.expectEmit(); + // emit CCIPSendRequested(msgEvent2); + // vm.expectEmit(); + // emit CCIPSendRequested(msgEvent1); + + // After issue is fixed, sequence now increments as expected + Internal.EVM2AnyRampMessage memory msgEvent1 = _messageToEvent(message1, 1, 1, expectedFee, address(s_facadeClient)); + Internal.EVM2AnyRampMessage memory msgEvent2 = _messageToEvent(message2, 2, 2, expectedFee, address(s_facadeClient)); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, msgEvent2); + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, msgEvent1); + + s_facadeClient.send(amount); + } +} diff --git a/contracts/src/v0.8/ccip/test/attacks/onRamp/OnRampTokenPoolReentrancy.t.sol b/contracts/src/v0.8/ccip/test/attacks/onRamp/OnRampTokenPoolReentrancy.t.sol new file mode 100644 index 0000000000..8fc71be857 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/attacks/onRamp/OnRampTokenPoolReentrancy.t.sol @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {Client} from "../../../libraries/Client.sol"; +import {Internal} from "../../../libraries/Internal.sol"; +import {EVM2EVMOnRamp} from "../../../onRamp/EVM2EVMOnRamp.sol"; +import {TokenPool} from "../../../pools/TokenPool.sol"; +import {EVM2EVMOnRampSetup} from "../../onRamp/EVM2EVMOnRampSetup.t.sol"; +import {FacadeClient} from "./FacadeClient.sol"; +import {ReentrantMaliciousTokenPool} from "./ReentrantMaliciousTokenPool.sol"; + +import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +/// @title OnRampTokenPoolReentrancy +/// Attempts to perform a reentrancy exploit on Onramp with a malicious TokenPool +contract OnRampTokenPoolReentrancy is EVM2EVMOnRampSetup { + FacadeClient internal s_facadeClient; + ReentrantMaliciousTokenPool internal s_maliciousTokenPool; + IERC20 internal s_sourceToken; + IERC20 internal s_feeToken; + address internal immutable i_receiver = makeAddr("receiver"); + + function setUp() public virtual override { + EVM2EVMOnRampSetup.setUp(); + + s_sourceToken = IERC20(s_sourceTokens[0]); + s_feeToken = IERC20(s_sourceTokens[0]); + + s_facadeClient = + new FacadeClient(address(s_sourceRouter), DEST_CHAIN_SELECTOR, s_sourceToken, s_feeToken, i_receiver); + + s_maliciousTokenPool = new ReentrantMaliciousTokenPool( + address(s_facadeClient), s_sourceToken, address(s_mockRMN), address(s_sourceRouter) + ); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(s_destPoolBySourceToken[s_sourceTokens[0]]), + remoteTokenAddress: abi.encode(s_destTokens[0]), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_maliciousTokenPool.applyChainUpdates(chainUpdates); + s_sourcePoolByToken[address(s_sourceToken)] = address(s_maliciousTokenPool); + + Internal.PoolUpdate[] memory removes = new Internal.PoolUpdate[](1); + removes[0].token = address(s_sourceToken); + removes[0].pool = address(s_sourcePoolByToken[address(s_sourceToken)]); + Internal.PoolUpdate[] memory adds = new Internal.PoolUpdate[](1); + adds[0].token = address(s_sourceToken); + adds[0].pool = address(s_maliciousTokenPool); + + s_tokenAdminRegistry.setPool(address(s_sourceToken), address(s_maliciousTokenPool)); + + s_sourceToken.transfer(address(s_facadeClient), 1e18); + s_feeToken.transfer(address(s_facadeClient), 1e18); + } + + /// @dev This test was used to showcase a reentrancy exploit on OnRamp with malicious TokenPool. + /// How it worked: OnRamp used to construct EVM2EVM messages after calling TokenPool's lockOrBurn. + /// This allowed the malicious TokenPool to break message sequencing expectations as follows: + /// Any user -> Facade -> 1st call to ccipSend -> pool’s lockOrBurn —> + /// (reenter)-> Facade -> 2nd call to ccipSend + /// In this case, Facade's second call would produce an EVM2EVM msg with a lower sequence number. + /// The issue was fixed by moving state updates and event construction to before TokenPool calls. + /// This test is kept to verify message sequence expectations are not broken. + function test_OnRampTokenPoolReentrancy_Success() public { + uint256 amount = 1; + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0].token = address(s_sourceToken); + tokenAmounts[0].amount = amount; + + Client.EVM2AnyMessage memory message1 = Client.EVM2AnyMessage({ + receiver: abi.encode(i_receiver), + data: abi.encodePacked(uint256(1)), // message 1 contains data 1 + tokenAmounts: tokenAmounts, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000})), + feeToken: address(s_feeToken) + }); + + Client.EVM2AnyMessage memory message2 = Client.EVM2AnyMessage({ + receiver: abi.encode(i_receiver), + data: abi.encodePacked(uint256(2)), // message 2 contains data 2 + tokenAmounts: tokenAmounts, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000})), + feeToken: address(s_feeToken) + }); + + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message1); + assertGt(expectedFee, 0); + + // Outcome of a successful exploit: + // Message 1 event from OnRamp contains sequence/nonce 2, message 2 contains sequence/nonce 1 + // Internal.EVM2EVMMessage memory msgEvent1 = _messageToEvent(message1, 2, 2, expectedFee, address(s_facadeClient)); + // Internal.EVM2EVMMessage memory msgEvent2 = _messageToEvent(message2, 1, 1, expectedFee, address(s_facadeClient)); + + // vm.expectEmit(); + // emit CCIPSendRequested(msgEvent2); + // vm.expectEmit(); + // emit CCIPSendRequested(msgEvent1); + + // After issue is fixed, sequence now increments as expected + Internal.EVM2EVMMessage memory msgEvent1 = _messageToEvent(message1, 1, 1, expectedFee, address(s_facadeClient)); + Internal.EVM2EVMMessage memory msgEvent2 = _messageToEvent(message2, 2, 2, expectedFee, address(s_facadeClient)); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(msgEvent2); + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(msgEvent1); + + s_facadeClient.send(amount); + } +} diff --git a/contracts/src/v0.8/ccip/test/attacks/onRamp/ReentrantMaliciousTokenPool.sol b/contracts/src/v0.8/ccip/test/attacks/onRamp/ReentrantMaliciousTokenPool.sol new file mode 100644 index 0000000000..17c13a8148 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/attacks/onRamp/ReentrantMaliciousTokenPool.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {Pool} from "../../../libraries/Pool.sol"; +import {TokenPool} from "../../../pools/TokenPool.sol"; +import {FacadeClient} from "./FacadeClient.sol"; + +import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract ReentrantMaliciousTokenPool is TokenPool { + address private i_facade; + + bool private s_attacked; + + constructor( + address facade, + IERC20 token, + address rmnProxy, + address router + ) TokenPool(token, new address[](0), rmnProxy, router) { + i_facade = facade; + } + + /// @dev Calls into Facade to reenter Router exactly 1 time + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + external + override + returns (Pool.LockOrBurnOutV1 memory) + { + if (s_attacked) { + return + Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); + } + + s_attacked = true; + + FacadeClient(i_facade).send(lockOrBurnIn.amount); + emit Burned(msg.sender, lockOrBurnIn.amount); + return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); + } + + function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + external + pure + override + returns (Pool.ReleaseOrMintOutV1 memory) + { + return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + } +} diff --git a/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol b/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol new file mode 100644 index 0000000000..0c3108d279 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol @@ -0,0 +1,1681 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.24; + +import {Test} from "forge-std/Test.sol"; + +import {SortedSetValidationUtil} from "../../../shared/util/SortedSetValidationUtil.sol"; +import {CCIPConfig} from "../../capability/CCIPConfig.sol"; +import {ICapabilitiesRegistry} from "../../capability/interfaces/ICapabilitiesRegistry.sol"; +import {CCIPConfigTypes} from "../../capability/libraries/CCIPConfigTypes.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {CCIPConfigHelper} from "../helpers/CCIPConfigHelper.sol"; + +contract CCIPConfigSetup is Test { + address public constant OWNER = 0x82ae2B4F57CA5C1CBF8f744ADbD3697aD1a35AFe; + address public constant CAPABILITIES_REGISTRY = 0x272aF4BF7FBFc4944Ed59F914Cd864DfD912D55e; + + CCIPConfigHelper public s_ccipCC; + + function setUp() public { + changePrank(OWNER); + s_ccipCC = new CCIPConfigHelper(CAPABILITIES_REGISTRY); + } + + function _makeBytes32Array(uint256 length, uint256 seed) internal pure returns (bytes32[] memory arr) { + arr = new bytes32[](length); + for (uint256 i = 0; i < length; i++) { + arr[i] = keccak256(abi.encode(i, 1, seed)); + } + return arr; + } + + function _makeBytesArray(uint256 length, uint256 seed) internal pure returns (bytes[] memory arr) { + arr = new bytes[](length); + for (uint256 i = 0; i < length; i++) { + arr[i] = abi.encodePacked(keccak256(abi.encode(i, 1, seed))); + } + return arr; + } + + function _subset(bytes32[] memory arr, uint256 start, uint256 end) internal pure returns (bytes32[] memory) { + bytes32[] memory subset = new bytes32[](end - start); + for (uint256 i = start; i < end; i++) { + subset[i - start] = arr[i]; + } + return subset; + } + + //TODO: Use OZ's Arrays.sort when we upgrade to OZ v5 + function _sort(bytes32[] memory arr, int256 left, int256 right) private pure { + int256 i = left; + int256 j = right; + if (i == j) return; + bytes32 pivot = arr[uint256(left + (right - left) / 2)]; + while (i <= j) { + while (arr[uint256(i)] < pivot) i++; + while (pivot < arr[uint256(j)]) j--; + if (i <= j) { + (arr[uint256(i)], arr[uint256(j)]) = (arr[uint256(j)], arr[uint256(i)]); + i++; + j--; + } + } + if (left < j) _sort(arr, left, j); + if (i < right) _sort(arr, i, right); + } + + function _addChainConfig(uint256 numNodes) + internal + returns (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) + { + p2pIds = _makeBytes32Array(numNodes, 0); + _sort(p2pIds, 0, int256(numNodes - 1)); + signers = _makeBytesArray(numNodes, 10); + transmitters = _makeBytesArray(numNodes, 20); + for (uint256 i = 0; i < numNodes; i++) { + vm.mockCall( + CAPABILITIES_REGISTRY, + abi.encodeWithSelector(ICapabilitiesRegistry.getNode.selector, p2pIds[i]), + abi.encode( + ICapabilitiesRegistry.NodeInfo({ + nodeOperatorId: 1, + signer: bytes32(signers[i]), + p2pId: p2pIds[i], + hashedCapabilityIds: new bytes32[](0), + configCount: uint32(1), + workflowDONId: uint32(1), + capabilitiesDONIds: new uint256[](0) + }) + ) + ); + } + // Add chain selector for chain 1. + CCIPConfigTypes.ChainConfigInfo[] memory adds = new CCIPConfigTypes.ChainConfigInfo[](1); + adds[0] = CCIPConfigTypes.ChainConfigInfo({ + chainSelector: 1, + chainConfig: CCIPConfigTypes.ChainConfig({readers: p2pIds, fChain: 1, config: bytes("config1")}) + }); + + vm.expectEmit(); + emit CCIPConfig.ChainConfigSet(1, adds[0].chainConfig); + s_ccipCC.applyChainConfigUpdates(new uint64[](0), adds); + + return (p2pIds, signers, transmitters); + } + + function test_getCapabilityConfiguration_Success() public { + bytes memory capConfig = s_ccipCC.getCapabilityConfiguration(42 /* doesn't matter, not used */ ); + assertEq(capConfig.length, 0, "capability config length must be 0"); + } +} + +contract CCIPConfig_chainConfig is CCIPConfigSetup { + // Successes. + + function test_applyChainConfigUpdates_addChainConfigs_Success() public { + bytes32[] memory chainReaders = new bytes32[](1); + chainReaders[0] = keccak256(abi.encode(1)); + CCIPConfigTypes.ChainConfigInfo[] memory adds = new CCIPConfigTypes.ChainConfigInfo[](2); + adds[0] = CCIPConfigTypes.ChainConfigInfo({ + chainSelector: 1, + chainConfig: CCIPConfigTypes.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config1")}) + }); + adds[1] = CCIPConfigTypes.ChainConfigInfo({ + chainSelector: 2, + chainConfig: CCIPConfigTypes.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config2")}) + }); + + vm.mockCall( + CAPABILITIES_REGISTRY, + abi.encodeWithSelector(ICapabilitiesRegistry.getNode.selector, chainReaders[0]), + abi.encode( + ICapabilitiesRegistry.NodeInfo({ + nodeOperatorId: 1, + signer: bytes32(uint256(1)), + p2pId: chainReaders[0], + hashedCapabilityIds: new bytes32[](0), + configCount: uint32(1), + workflowDONId: uint32(1), + capabilitiesDONIds: new uint256[](0) + }) + ) + ); + + vm.expectEmit(); + emit CCIPConfig.ChainConfigSet(1, adds[0].chainConfig); + vm.expectEmit(); + emit CCIPConfig.ChainConfigSet(2, adds[1].chainConfig); + s_ccipCC.applyChainConfigUpdates(new uint64[](0), adds); + + CCIPConfigTypes.ChainConfigInfo[] memory configs = s_ccipCC.getAllChainConfigs(); + assertEq(configs.length, 2, "chain configs length must be 2"); + assertEq(configs[0].chainSelector, 1, "chain selector must match"); + assertEq(configs[1].chainSelector, 2, "chain selector must match"); + } + + function test_applyChainConfigUpdates_removeChainConfigs_Success() public { + bytes32[] memory chainReaders = new bytes32[](1); + chainReaders[0] = keccak256(abi.encode(1)); + CCIPConfigTypes.ChainConfigInfo[] memory adds = new CCIPConfigTypes.ChainConfigInfo[](2); + adds[0] = CCIPConfigTypes.ChainConfigInfo({ + chainSelector: 1, + chainConfig: CCIPConfigTypes.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config1")}) + }); + adds[1] = CCIPConfigTypes.ChainConfigInfo({ + chainSelector: 2, + chainConfig: CCIPConfigTypes.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config2")}) + }); + + vm.mockCall( + CAPABILITIES_REGISTRY, + abi.encodeWithSelector(ICapabilitiesRegistry.getNode.selector, chainReaders[0]), + abi.encode( + ICapabilitiesRegistry.NodeInfo({ + nodeOperatorId: 1, + signer: bytes32(uint256(1)), + p2pId: chainReaders[0], + hashedCapabilityIds: new bytes32[](0), + configCount: uint32(1), + workflowDONId: uint32(1), + capabilitiesDONIds: new uint256[](0) + }) + ) + ); + + vm.expectEmit(); + emit CCIPConfig.ChainConfigSet(1, adds[0].chainConfig); + vm.expectEmit(); + emit CCIPConfig.ChainConfigSet(2, adds[1].chainConfig); + s_ccipCC.applyChainConfigUpdates(new uint64[](0), adds); + + uint64[] memory removes = new uint64[](1); + removes[0] = uint64(1); + + vm.expectEmit(); + emit CCIPConfig.ChainConfigRemoved(1); + s_ccipCC.applyChainConfigUpdates(removes, new CCIPConfigTypes.ChainConfigInfo[](0)); + } + + // Reverts. + + function test_applyChainConfigUpdates_selectorNotFound_Reverts() public { + uint64[] memory removes = new uint64[](1); + removes[0] = uint64(1); + + vm.expectRevert(abi.encodeWithSelector(CCIPConfig.ChainSelectorNotFound.selector, 1)); + s_ccipCC.applyChainConfigUpdates(removes, new CCIPConfigTypes.ChainConfigInfo[](0)); + } + + function test_applyChainConfigUpdates_nodeNotInRegistry_Reverts() public { + bytes32[] memory chainReaders = new bytes32[](1); + chainReaders[0] = keccak256(abi.encode(1)); + CCIPConfigTypes.ChainConfigInfo[] memory adds = new CCIPConfigTypes.ChainConfigInfo[](1); + adds[0] = CCIPConfigTypes.ChainConfigInfo({ + chainSelector: 1, + chainConfig: CCIPConfigTypes.ChainConfig({readers: chainReaders, fChain: 1, config: abi.encode(1, 2, 3)}) + }); + + vm.mockCall( + CAPABILITIES_REGISTRY, + abi.encodeWithSelector(ICapabilitiesRegistry.getNode.selector, chainReaders[0]), + abi.encode( + ICapabilitiesRegistry.NodeInfo({ + nodeOperatorId: 0, + signer: bytes32(0), + p2pId: bytes32(uint256(0)), + hashedCapabilityIds: new bytes32[](0), + configCount: uint32(1), + workflowDONId: uint32(1), + capabilitiesDONIds: new uint256[](0) + }) + ) + ); + + vm.expectRevert(abi.encodeWithSelector(CCIPConfig.NodeNotInRegistry.selector, chainReaders[0])); + s_ccipCC.applyChainConfigUpdates(new uint64[](0), adds); + } + + function test__applyChainConfigUpdates_FChainNotPositive_Reverts() public { + bytes32[] memory chainReaders = new bytes32[](1); + chainReaders[0] = keccak256(abi.encode(1)); + CCIPConfigTypes.ChainConfigInfo[] memory adds = new CCIPConfigTypes.ChainConfigInfo[](2); + adds[0] = CCIPConfigTypes.ChainConfigInfo({ + chainSelector: 1, + chainConfig: CCIPConfigTypes.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config1")}) + }); + adds[1] = CCIPConfigTypes.ChainConfigInfo({ + chainSelector: 2, + chainConfig: CCIPConfigTypes.ChainConfig({readers: chainReaders, fChain: 0, config: bytes("config2")}) // bad fChain + }); + + vm.mockCall( + CAPABILITIES_REGISTRY, + abi.encodeWithSelector(ICapabilitiesRegistry.getNode.selector, chainReaders[0]), + abi.encode( + ICapabilitiesRegistry.NodeInfo({ + nodeOperatorId: 1, + signer: bytes32(uint256(1)), + p2pId: chainReaders[0], + hashedCapabilityIds: new bytes32[](0), + configCount: uint32(1), + workflowDONId: uint32(1), + capabilitiesDONIds: new uint256[](0) + }) + ) + ); + + vm.expectRevert(CCIPConfig.FChainMustBePositive.selector); + s_ccipCC.applyChainConfigUpdates(new uint64[](0), adds); + } +} + +contract CCIPConfig_validateConfig is CCIPConfigSetup { + // Successes. + + function test__validateConfig_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + // Config is for 4 nodes, so f == 1. + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + s_ccipCC.validateConfig(config); + } + + // Reverts. + + function test__validateConfig_ChainSelectorNotSet_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + // Config is for 4 nodes, so f == 1. + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 0, // invalid + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPConfig.ChainSelectorNotSet.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_OfframpAddressCannotBeZero_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + // Config is for 4 nodes, so f == 1. + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: bytes(""), // invalid + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPConfig.OfframpAddressCannotBeZero.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_ChainSelectorNotFound_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + // Config is for 4 nodes, so f == 1. + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 2, // not set + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(abi.encodeWithSelector(CCIPConfig.ChainSelectorNotFound.selector, 2)); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_TooManySigners_Reverts() public { + // 32 > 31 (max num oracles) + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(32); + + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPConfig.TooManySigners.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_TooManyTransmitters_Reverts() public { + // 32 > 31 (max num oracles) + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(32); + + // truncate signers but keep transmitters > 31 + assembly { + mstore(signers, 30) + } + + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPConfig.TooManyTransmitters.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_NotEnoughTransmitters_Reverts() public { + // 32 > 31 (max num oracles) + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(31); + + // truncate transmitters to < 3 * fChain + 1 + // since fChain is 1 in this case, we need to truncate to 3 transmitters. + assembly { + mstore(transmitters, 3) + } + + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(abi.encodeWithSelector(CCIPConfig.NotEnoughTransmitters.selector, 3, 4)); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_FMustBePositive_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + // Config is for 4 nodes, so f == 1. + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 0, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPConfig.FMustBePositive.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_FTooHigh_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 2, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPConfig.FTooHigh.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_P2PIdsLengthNotMatching_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + // truncate the p2pIds length + assembly { + mstore(p2pIds, 3) + } + + // Config is for 4 nodes, so f == 1. + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert( + abi.encodeWithSelector(CCIPConfig.P2PIdsLengthNotMatching.selector, uint256(3), uint256(4), uint256(4)) + ); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_TooManyBootstrapP2PIds_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + + // Config is for 4 nodes, so f == 1. + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _makeBytes32Array(5, 0), // too many bootstrap p2pIds, 5 > 4 + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(CCIPConfig.TooManyBootstrapP2PIds.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_NodeNotInRegistry_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + bytes32 nonExistentP2PId = keccak256("notInRegistry"); + p2pIds[0] = nonExistentP2PId; + + vm.mockCall( + CAPABILITIES_REGISTRY, + abi.encodeWithSelector(ICapabilitiesRegistry.getNode.selector, nonExistentP2PId), + abi.encode( + ICapabilitiesRegistry.NodeInfo({ + nodeOperatorId: 0, + signer: bytes32(0), + p2pId: bytes32(uint256(0)), + hashedCapabilityIds: new bytes32[](0), + configCount: uint32(1), + workflowDONId: uint32(1), + capabilitiesDONIds: new uint256[](0) + }) + ) + ); + + // Config is for 4 nodes, so f == 1. + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(abi.encodeWithSelector(CCIPConfig.NodeNotInRegistry.selector, nonExistentP2PId)); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_P2PIdsNotSorted_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + // Config is for 4 nodes, so f == 1. + + //swapping two adjacent p2pIds to make it unsorted + (p2pIds[2], p2pIds[3]) = (p2pIds[3], p2pIds[2]); + + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(abi.encodeWithSelector(SortedSetValidationUtil.NotASortedSet.selector, p2pIds)); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_BootstrapP2PIdsNotSorted_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + // Config is for 4 nodes, so f == 1. + + bytes32[] memory bootstrapP2PIds = _subset(p2pIds, 0, 2); + + //swapping bootstrapP2PIds to make it unsorted + (bootstrapP2PIds[0], bootstrapP2PIds[1]) = (bootstrapP2PIds[1], bootstrapP2PIds[0]); + + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: bootstrapP2PIds, + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(abi.encodeWithSelector(SortedSetValidationUtil.NotASortedSet.selector, bootstrapP2PIds)); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_P2PIdsHasDuplicates_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + // Config is for 4 nodes, so f == 1. + + //forcing duplicate p2pIds + p2pIds[1] = p2pIds[2]; + + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 2), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(abi.encodeWithSelector(SortedSetValidationUtil.NotASortedSet.selector, p2pIds)); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_BootstrapP2PIdsHasDuplicates_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + // Config is for 4 nodes, so f == 1. + + bytes32[] memory bootstrapP2PIds = _subset(p2pIds, 0, 2); + //forcing duplicate bootstrapP2PIds + bootstrapP2PIds[1] = bootstrapP2PIds[0]; + + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: bootstrapP2PIds, + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(abi.encodeWithSelector(SortedSetValidationUtil.NotASortedSet.selector, bootstrapP2PIds)); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_BootstrapP2PIdsNotASubsetOfP2PIds_Reverts() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + // Config is for 4 nodes, so f == 1. + + //forcing invalid bootstrapP2PIds where the bootstrapP2PIds is sorted, but one of the element is not in the p2pIdsSet + bytes32[] memory bootstrapP2PIds = _subset(p2pIds, 0, 2); + p2pIds[1] = bytes32(uint256(p2pIds[0]) + 100); + + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: bootstrapP2PIds, + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + + vm.expectRevert(abi.encodeWithSelector(SortedSetValidationUtil.NotASubset.selector, bootstrapP2PIds, p2pIds)); + s_ccipCC.validateConfig(config); + } +} + +contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { + // Successful cases. + + function test__stateFromConfigLength_Success() public { + uint256 configLen = 0; + CCIPConfigTypes.ConfigState state = s_ccipCC.stateFromConfigLength(configLen); + assertEq(uint256(state), uint256(CCIPConfigTypes.ConfigState.Init)); + + configLen = 1; + state = s_ccipCC.stateFromConfigLength(configLen); + assertEq(uint256(state), uint256(CCIPConfigTypes.ConfigState.Running)); + + configLen = 2; + state = s_ccipCC.stateFromConfigLength(configLen); + assertEq(uint256(state), uint256(CCIPConfigTypes.ConfigState.Staging)); + } + + function test__validateConfigStateTransition_Success() public { + s_ccipCC.validateConfigStateTransition(CCIPConfigTypes.ConfigState.Init, CCIPConfigTypes.ConfigState.Running); + + s_ccipCC.validateConfigStateTransition(CCIPConfigTypes.ConfigState.Running, CCIPConfigTypes.ConfigState.Staging); + + s_ccipCC.validateConfigStateTransition(CCIPConfigTypes.ConfigState.Staging, CCIPConfigTypes.ConfigState.Running); + } + + function test__computeConfigDigest_Success() public { + // config digest must change upon: + // - ocr config change (e.g plugin type, chain selector, etc.) + // - don id change + // - config count change + bytes32[] memory p2pIds = _makeBytes32Array(4, 0); + bytes[] memory signers = _makeBytesArray(2, 10); + bytes[] memory transmitters = _makeBytesArray(2, 20); + CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("offchainConfig") + }); + uint32 donId = 1; + uint32 configCount = 1; + + bytes32 configDigest1 = s_ccipCC.computeConfigDigest(donId, configCount, config); + + donId = 2; + bytes32 configDigest2 = s_ccipCC.computeConfigDigest(donId, configCount, config); + + donId = 1; + configCount = 2; + bytes32 configDigest3 = s_ccipCC.computeConfigDigest(donId, configCount, config); + + configCount = 1; + config.pluginType = Internal.OCRPluginType.Execution; + bytes32 configDigest4 = s_ccipCC.computeConfigDigest(donId, configCount, config); + + assertNotEq(configDigest1, configDigest2, "config digests 1 and 2 must not match"); + assertNotEq(configDigest1, configDigest3, "config digests 1 and 3 must not match"); + assertNotEq(configDigest1, configDigest4, "config digests 1 and 4 must not match"); + + assertNotEq(configDigest2, configDigest3, "config digests 2 and 3 must not match"); + assertNotEq(configDigest2, configDigest4, "config digests 2 and 4 must not match"); + } + + function test_Fuzz__groupByPluginType_Success(uint256 numCommitCfgs, uint256 numExecCfgs) public { + numCommitCfgs = bound(numCommitCfgs, 0, 2); + numExecCfgs = bound(numExecCfgs, 0, 2); + + bytes32[] memory p2pIds = _makeBytes32Array(4, 0); + bytes[] memory signers = _makeBytesArray(4, 10); + bytes[] memory transmitters = _makeBytesArray(4, 20); + CCIPConfigTypes.OCR3Config[] memory cfgs = new CCIPConfigTypes.OCR3Config[](numCommitCfgs + numExecCfgs); + for (uint256 i = 0; i < numCommitCfgs; i++) { + cfgs[i] = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: abi.encode("commit", i) + }); + } + for (uint256 i = 0; i < numExecCfgs; i++) { + cfgs[numCommitCfgs + i] = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Execution, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: abi.encode("exec", numCommitCfgs + i) + }); + } + (CCIPConfigTypes.OCR3Config[] memory commitCfgs, CCIPConfigTypes.OCR3Config[] memory execCfgs) = + s_ccipCC.groupByPluginType(cfgs); + + assertEq(commitCfgs.length, numCommitCfgs, "commitCfgs length must match"); + assertEq(execCfgs.length, numExecCfgs, "execCfgs length must match"); + for (uint256 i = 0; i < commitCfgs.length; i++) { + assertEq(uint8(commitCfgs[i].pluginType), uint8(Internal.OCRPluginType.Commit), "plugin type must be commit"); + assertEq(commitCfgs[i].offchainConfig, abi.encode("commit", i), "offchain config must match"); + } + for (uint256 i = 0; i < execCfgs.length; i++) { + assertEq(uint8(execCfgs[i].pluginType), uint8(Internal.OCRPluginType.Execution), "plugin type must be execution"); + assertEq(execCfgs[i].offchainConfig, abi.encode("exec", numCommitCfgs + i), "offchain config must match"); + } + } + + function test__computeNewConfigWithMeta_InitToRunning_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](0); + CCIPConfigTypes.OCR3Config[] memory newConfig = new CCIPConfigTypes.OCR3Config[](1); + newConfig[0] = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.ConfigState currentState = CCIPConfigTypes.ConfigState.Init; + CCIPConfigTypes.ConfigState newState = CCIPConfigTypes.ConfigState.Running; + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfigWithMeta = + s_ccipCC.computeNewConfigWithMeta(donId, currentConfig, newConfig, currentState, newState); + assertEq(newConfigWithMeta.length, 1, "new config with meta length must be 1"); + assertEq(newConfigWithMeta[0].configCount, uint64(1), "config count must be 1"); + assertEq(uint8(newConfigWithMeta[0].config.pluginType), uint8(newConfig[0].pluginType), "plugin type must match"); + assertEq(newConfigWithMeta[0].config.offchainConfig, newConfig[0].offchainConfig, "offchain config must match"); + assertEq( + newConfigWithMeta[0].configDigest, + s_ccipCC.computeConfigDigest(donId, 1, newConfig[0]), + "config digest must match" + ); + + // This ensures that the test case is using correct inputs. + s_ccipCC.validateConfigTransition(currentConfig, newConfigWithMeta); + } + + function test__computeNewConfigWithMeta_RunningToStaging_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.OCR3Config memory greenConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](1); + currentConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + + CCIPConfigTypes.OCR3Config[] memory newConfig = new CCIPConfigTypes.OCR3Config[](2); + // existing blue config first. + newConfig[0] = blueConfig; + // green config next. + newConfig[1] = greenConfig; + + CCIPConfigTypes.ConfigState currentState = CCIPConfigTypes.ConfigState.Running; + CCIPConfigTypes.ConfigState newState = CCIPConfigTypes.ConfigState.Staging; + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfigWithMeta = + s_ccipCC.computeNewConfigWithMeta(donId, currentConfig, newConfig, currentState, newState); + assertEq(newConfigWithMeta.length, 2, "new config with meta length must be 2"); + + assertEq(newConfigWithMeta[0].configCount, uint64(1), "config count of blue must be 1"); + assertEq( + uint8(newConfigWithMeta[0].config.pluginType), uint8(blueConfig.pluginType), "plugin type of blue must match" + ); + assertEq( + newConfigWithMeta[0].config.offchainConfig, blueConfig.offchainConfig, "offchain config of blue must match" + ); + assertEq( + newConfigWithMeta[0].configDigest, + s_ccipCC.computeConfigDigest(donId, 1, blueConfig), + "config digest of blue must match" + ); + + assertEq(newConfigWithMeta[1].configCount, uint64(2), "config count of green must be 2"); + assertEq( + uint8(newConfigWithMeta[1].config.pluginType), uint8(greenConfig.pluginType), "plugin type of green must match" + ); + assertEq( + newConfigWithMeta[1].config.offchainConfig, greenConfig.offchainConfig, "offchain config of green must match" + ); + assertEq( + newConfigWithMeta[1].configDigest, + s_ccipCC.computeConfigDigest(donId, 2, greenConfig), + "config digest of green must match" + ); + + // This ensures that the test case is using correct inputs. + s_ccipCC.validateConfigTransition(currentConfig, newConfigWithMeta); + } + + function test__computeNewConfigWithMeta_StagingToRunning_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.OCR3Config memory greenConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](2); + currentConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + currentConfig[1] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + }); + CCIPConfigTypes.OCR3Config[] memory newConfig = new CCIPConfigTypes.OCR3Config[](1); + newConfig[0] = greenConfig; + + CCIPConfigTypes.ConfigState currentState = CCIPConfigTypes.ConfigState.Staging; + CCIPConfigTypes.ConfigState newState = CCIPConfigTypes.ConfigState.Running; + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfigWithMeta = + s_ccipCC.computeNewConfigWithMeta(donId, currentConfig, newConfig, currentState, newState); + + assertEq(newConfigWithMeta.length, 1, "new config with meta length must be 1"); + assertEq(newConfigWithMeta[0].configCount, uint64(2), "config count must be 2"); + assertEq(uint8(newConfigWithMeta[0].config.pluginType), uint8(greenConfig.pluginType), "plugin type must match"); + assertEq(newConfigWithMeta[0].config.offchainConfig, greenConfig.offchainConfig, "offchain config must match"); + assertEq( + newConfigWithMeta[0].configDigest, s_ccipCC.computeConfigDigest(donId, 2, greenConfig), "config digest must match" + ); + + // This ensures that the test case is using correct inputs. + s_ccipCC.validateConfigTransition(currentConfig, newConfigWithMeta); + } + + function test__validateConfigTransition_InitToRunning_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](1); + newConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](0); + + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + function test__validateConfigTransition_RunningToStaging_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.OCR3Config memory greenConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](2); + newConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + newConfig[1] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](1); + currentConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + function test__validateConfigTransition_StagingToRunning_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.OCR3Config memory greenConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](2); + currentConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + currentConfig[1] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](1); + newConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + }); + + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + // Reverts. + + function test_Fuzz__stateFromConfigLength_Reverts(uint256 configLen) public { + vm.assume(configLen > 2); + vm.expectRevert(abi.encodeWithSelector(CCIPConfig.InvalidConfigLength.selector, configLen)); + s_ccipCC.stateFromConfigLength(configLen); + } + + function test__groupByPluginType_threeCommitConfigs_Reverts() public { + bytes32[] memory p2pIds = _makeBytes32Array(4, 0); + bytes[] memory signers = _makeBytesArray(4, 10); + bytes[] memory transmitters = _makeBytesArray(4, 20); + CCIPConfigTypes.OCR3Config[] memory cfgs = new CCIPConfigTypes.OCR3Config[](3); + for (uint256 i = 0; i < 3; i++) { + cfgs[i] = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: abi.encode("commit", i) + }); + } + vm.expectRevert(); + s_ccipCC.groupByPluginType(cfgs); + } + + function test__groupByPluginType_threeExecutionConfigs_Reverts() public { + bytes32[] memory p2pIds = _makeBytes32Array(4, 0); + bytes[] memory signers = _makeBytesArray(4, 10); + bytes[] memory transmitters = _makeBytesArray(4, 20); + CCIPConfigTypes.OCR3Config[] memory cfgs = new CCIPConfigTypes.OCR3Config[](3); + for (uint256 i = 0; i < 3; i++) { + cfgs[i] = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Execution, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: abi.encode("exec", i) + }); + } + vm.expectRevert(); + s_ccipCC.groupByPluginType(cfgs); + } + + function test__groupByPluginType_TooManyOCR3Configs_Reverts() public { + CCIPConfigTypes.OCR3Config[] memory cfgs = new CCIPConfigTypes.OCR3Config[](5); + vm.expectRevert(CCIPConfig.TooManyOCR3Configs.selector); + s_ccipCC.groupByPluginType(cfgs); + } + + function test__validateConfigTransition_InitToRunning_WrongConfigCount_Reverts() public { + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](1); + newConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 0, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](0); + + vm.expectRevert(abi.encodeWithSelector(CCIPConfig.WrongConfigCount.selector, 0, 1)); + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + function test__validateConfigTransition_RunningToStaging_WrongConfigDigestBlueGreen_Reverts() public { + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.OCR3Config memory greenConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](1); + currentConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](2); + newConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 3, blueConfig) // wrong config digest (due to diff config count) + }); + newConfig[1] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + }); + + vm.expectRevert( + abi.encodeWithSelector( + CCIPConfig.WrongConfigDigestBlueGreen.selector, + s_ccipCC.computeConfigDigest(donId, 3, blueConfig), + s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + ) + ); + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + function test__validateConfigTransition_RunningToStaging_WrongConfigCount_Reverts() public { + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.OCR3Config memory greenConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](1); + currentConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](2); + newConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + newConfig[1] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 3, // wrong config count + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 3, greenConfig) + }); + + vm.expectRevert(abi.encodeWithSelector(CCIPConfig.WrongConfigCount.selector, 3, 2)); + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + function test__validateConfigTransition_StagingToRunning_WrongConfigDigest_Reverts() public { + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.OCR3Config memory greenConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), + p2pIds: _makeBytes32Array(4, 0), + signers: _makeBytesArray(4, 10), + transmitters: _makeBytesArray(4, 20), + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](2); + currentConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 1, + config: blueConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 1, blueConfig) + }); + currentConfig[1] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + }); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](1); + newConfig[0] = CCIPConfigTypes.OCR3ConfigWithMeta({ + configCount: 2, + config: greenConfig, + configDigest: s_ccipCC.computeConfigDigest(donId, 3, greenConfig) // wrong config digest + }); + + vm.expectRevert( + abi.encodeWithSelector( + CCIPConfig.WrongConfigDigest.selector, + s_ccipCC.computeConfigDigest(donId, 3, greenConfig), + s_ccipCC.computeConfigDigest(donId, 2, greenConfig) + ) + ); + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } + + function test__validateConfigTransition_NonExistentConfigTransition_Reverts() public { + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](3); + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfig = new CCIPConfigTypes.OCR3ConfigWithMeta[](1); + vm.expectRevert(CCIPConfig.NonExistentConfigTransition.selector); + s_ccipCC.validateConfigTransition(currentConfig, newConfig); + } +} + +contract CCIPConfig__updatePluginConfig is CCIPConfigSetup { + // Successes. + + function test__updatePluginConfig_InitToRunning_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.OCR3Config[] memory configs = new CCIPConfigTypes.OCR3Config[](1); + configs[0] = blueConfig; + + s_ccipCC.updatePluginConfig(donId, Internal.OCRPluginType.Commit, configs); + + // should see the updated config in the contract state. + CCIPConfigTypes.OCR3ConfigWithMeta[] memory storedConfig = + s_ccipCC.getOCRConfig(donId, Internal.OCRPluginType.Commit); + assertEq(storedConfig.length, 1, "don config length must be 1"); + assertEq(storedConfig[0].configCount, uint64(1), "config count must be 1"); + assertEq(uint256(storedConfig[0].config.pluginType), uint256(blueConfig.pluginType), "plugin type must match"); + } + + function test__updatePluginConfig_RunningToStaging_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + // add blue config. + uint32 donId = 1; + Internal.OCRPluginType pluginType = Internal.OCRPluginType.Commit; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.OCR3Config[] memory startConfigs = new CCIPConfigTypes.OCR3Config[](1); + startConfigs[0] = blueConfig; + + // add blue AND green config to indicate an update. + s_ccipCC.updatePluginConfig(donId, Internal.OCRPluginType.Commit, startConfigs); + CCIPConfigTypes.OCR3Config memory greenConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + CCIPConfigTypes.OCR3Config[] memory blueAndGreen = new CCIPConfigTypes.OCR3Config[](2); + blueAndGreen[0] = blueConfig; + blueAndGreen[1] = greenConfig; + + s_ccipCC.updatePluginConfig(donId, Internal.OCRPluginType.Commit, blueAndGreen); + + // should see the updated config in the contract state. + CCIPConfigTypes.OCR3ConfigWithMeta[] memory storedConfig = + s_ccipCC.getOCRConfig(donId, Internal.OCRPluginType.Commit); + assertEq(storedConfig.length, 2, "don config length must be 2"); + // 0 index is blue config, 1 index is green config. + assertEq(storedConfig[1].configCount, uint64(2), "config count must be 2"); + assertEq( + uint256(storedConfig[0].config.pluginType), uint256(Internal.OCRPluginType.Commit), "plugin type must match" + ); + assertEq( + uint256(storedConfig[1].config.pluginType), uint256(Internal.OCRPluginType.Commit), "plugin type must match" + ); + assertEq(storedConfig[0].config.offchainConfig, bytes("commit"), "blue offchain config must match"); + assertEq(storedConfig[1].config.offchainConfig, bytes("commit-new"), "green offchain config must match"); + } + + function test__updatePluginConfig_StagingToRunning_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + // add blue config. + uint32 donId = 1; + Internal.OCRPluginType pluginType = Internal.OCRPluginType.Commit; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.OCR3Config[] memory startConfigs = new CCIPConfigTypes.OCR3Config[](1); + startConfigs[0] = blueConfig; + + // add blue AND green config to indicate an update. + s_ccipCC.updatePluginConfig(donId, Internal.OCRPluginType.Commit, startConfigs); + CCIPConfigTypes.OCR3Config memory greenConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit-new") + }); + CCIPConfigTypes.OCR3Config[] memory blueAndGreen = new CCIPConfigTypes.OCR3Config[](2); + blueAndGreen[0] = blueConfig; + blueAndGreen[1] = greenConfig; + + s_ccipCC.updatePluginConfig(donId, Internal.OCRPluginType.Commit, blueAndGreen); + + // should see the updated config in the contract state. + CCIPConfigTypes.OCR3ConfigWithMeta[] memory storedConfig = + s_ccipCC.getOCRConfig(donId, Internal.OCRPluginType.Commit); + assertEq(storedConfig.length, 2, "don config length must be 2"); + // 0 index is blue config, 1 index is green config. + assertEq(storedConfig[1].configCount, uint64(2), "config count must be 2"); + assertEq( + uint256(storedConfig[0].config.pluginType), uint256(Internal.OCRPluginType.Commit), "plugin type must match" + ); + assertEq( + uint256(storedConfig[1].config.pluginType), uint256(Internal.OCRPluginType.Commit), "plugin type must match" + ); + assertEq(storedConfig[0].config.offchainConfig, bytes("commit"), "blue offchain config must match"); + assertEq(storedConfig[1].config.offchainConfig, bytes("commit-new"), "green offchain config must match"); + + // promote green to blue. + CCIPConfigTypes.OCR3Config[] memory promote = new CCIPConfigTypes.OCR3Config[](1); + promote[0] = greenConfig; + + s_ccipCC.updatePluginConfig(donId, Internal.OCRPluginType.Commit, promote); + + // should see the updated config in the contract state. + storedConfig = s_ccipCC.getOCRConfig(donId, Internal.OCRPluginType.Commit); + assertEq(storedConfig.length, 1, "don config length must be 1"); + assertEq(storedConfig[0].configCount, uint64(2), "config count must be 2"); + assertEq( + uint256(storedConfig[0].config.pluginType), uint256(Internal.OCRPluginType.Commit), "plugin type must match" + ); + assertEq(storedConfig[0].config.offchainConfig, bytes("commit-new"), "green offchain config must match"); + } + + // Reverts. + function test__updatePluginConfig_InvalidConfigLength_Reverts() public { + uint32 donId = 1; + CCIPConfigTypes.OCR3Config[] memory newConfig = new CCIPConfigTypes.OCR3Config[](3); + vm.expectRevert(abi.encodeWithSelector(CCIPConfig.InvalidConfigLength.selector, uint256(3))); + s_ccipCC.updatePluginConfig(donId, Internal.OCRPluginType.Commit, newConfig); + } + + function test__updatePluginConfig_InvalidConfigStateTransition_Reverts() public { + uint32 donId = 1; + CCIPConfigTypes.OCR3Config[] memory newConfig = new CCIPConfigTypes.OCR3Config[](2); + // 0 -> 2 is an invalid state transition. + vm.expectRevert(abi.encodeWithSelector(CCIPConfig.InvalidConfigStateTransition.selector, 0, 2)); + s_ccipCC.updatePluginConfig(donId, Internal.OCRPluginType.Commit, newConfig); + } +} + +contract CCIPConfig_beforeCapabilityConfigSet is CCIPConfigSetup { + // Successes. + function test_beforeCapabilityConfigSet_ZeroLengthConfig_Success() public { + changePrank(CAPABILITIES_REGISTRY); + + CCIPConfigTypes.OCR3Config[] memory configs = new CCIPConfigTypes.OCR3Config[](0); + bytes memory encodedConfigs = abi.encode(configs); + s_ccipCC.beforeCapabilityConfigSet(new bytes32[](0), encodedConfigs, 1, 1); + } + + function test_beforeCapabilityConfigSet_CommitConfigOnly_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + changePrank(CAPABILITIES_REGISTRY); + + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.OCR3Config[] memory configs = new CCIPConfigTypes.OCR3Config[](1); + configs[0] = blueConfig; + + bytes memory encoded = abi.encode(configs); + s_ccipCC.beforeCapabilityConfigSet(new bytes32[](0), encoded, 1, donId); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory storedConfigs = + s_ccipCC.getOCRConfig(donId, Internal.OCRPluginType.Commit); + assertEq(storedConfigs.length, 1, "config length must be 1"); + assertEq(storedConfigs[0].configCount, uint64(1), "config count must be 1"); + assertEq( + uint256(storedConfigs[0].config.pluginType), uint256(Internal.OCRPluginType.Commit), "plugin type must be commit" + ); + } + + function test_beforeCapabilityConfigSet_ExecConfigOnly_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + changePrank(CAPABILITIES_REGISTRY); + + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Execution, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("exec") + }); + CCIPConfigTypes.OCR3Config[] memory configs = new CCIPConfigTypes.OCR3Config[](1); + configs[0] = blueConfig; + + bytes memory encoded = abi.encode(configs); + s_ccipCC.beforeCapabilityConfigSet(new bytes32[](0), encoded, 1, donId); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory storedConfigs = + s_ccipCC.getOCRConfig(donId, Internal.OCRPluginType.Execution); + assertEq(storedConfigs.length, 1, "config length must be 1"); + assertEq(storedConfigs[0].configCount, uint64(1), "config count must be 1"); + assertEq( + uint256(storedConfigs[0].config.pluginType), + uint256(Internal.OCRPluginType.Execution), + "plugin type must be execution" + ); + } + + function test_beforeCapabilityConfigSet_CommitAndExecConfig_Success() public { + (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + changePrank(CAPABILITIES_REGISTRY); + + uint32 donId = 1; + CCIPConfigTypes.OCR3Config memory blueCommitConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Commit, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("commit") + }); + CCIPConfigTypes.OCR3Config memory blueExecConfig = CCIPConfigTypes.OCR3Config({ + pluginType: Internal.OCRPluginType.Execution, + offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), + chainSelector: 1, + bootstrapP2PIds: _subset(p2pIds, 0, 1), + p2pIds: p2pIds, + signers: signers, + transmitters: transmitters, + F: 1, + offchainConfigVersion: 30, + offchainConfig: bytes("exec") + }); + CCIPConfigTypes.OCR3Config[] memory configs = new CCIPConfigTypes.OCR3Config[](2); + configs[0] = blueExecConfig; + configs[1] = blueCommitConfig; + + bytes memory encoded = abi.encode(configs); + s_ccipCC.beforeCapabilityConfigSet(new bytes32[](0), encoded, 1, donId); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory storedExecConfigs = + s_ccipCC.getOCRConfig(donId, Internal.OCRPluginType.Execution); + assertEq(storedExecConfigs.length, 1, "config length must be 1"); + assertEq(storedExecConfigs[0].configCount, uint64(1), "config count must be 1"); + assertEq( + uint256(storedExecConfigs[0].config.pluginType), + uint256(Internal.OCRPluginType.Execution), + "plugin type must be execution" + ); + + CCIPConfigTypes.OCR3ConfigWithMeta[] memory storedCommitConfigs = + s_ccipCC.getOCRConfig(donId, Internal.OCRPluginType.Commit); + assertEq(storedCommitConfigs.length, 1, "config length must be 1"); + assertEq(storedCommitConfigs[0].configCount, uint64(1), "config count must be 1"); + assertEq( + uint256(storedCommitConfigs[0].config.pluginType), + uint256(Internal.OCRPluginType.Commit), + "plugin type must be commit" + ); + } + + // Reverts. + + function test_beforeCapabilityConfigSet_OnlyCapabilitiesRegistryCanCall_Reverts() public { + bytes32[] memory nodes = new bytes32[](0); + bytes memory config = bytes(""); + uint64 configCount = 1; + uint32 donId = 1; + vm.expectRevert(CCIPConfig.OnlyCapabilitiesRegistryCanCall.selector); + s_ccipCC.beforeCapabilityConfigSet(nodes, config, configCount, donId); + } +} diff --git a/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol b/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol new file mode 100644 index 0000000000..7598f9ccb6 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol @@ -0,0 +1,618 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; +import {IRMN} from "../../interfaces/IRMN.sol"; + +import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; +import {CommitStore} from "../../CommitStore.sol"; +import {PriceRegistry} from "../../PriceRegistry.sol"; +import {RMN} from "../../RMN.sol"; +import {MerkleMultiProof} from "../../libraries/MerkleMultiProof.sol"; +import {OCR2Abstract} from "../../ocr/OCR2Abstract.sol"; +import {CommitStoreHelper} from "../helpers/CommitStoreHelper.sol"; +import {OCR2BaseSetup} from "../ocr/OCR2Base.t.sol"; +import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; + +contract CommitStoreSetup is PriceRegistrySetup, OCR2BaseSetup { + CommitStoreHelper internal s_commitStore; + + function setUp() public virtual override(PriceRegistrySetup, OCR2BaseSetup) { + PriceRegistrySetup.setUp(); + OCR2BaseSetup.setUp(); + + s_commitStore = new CommitStoreHelper( + CommitStore.StaticConfig({ + chainSelector: DEST_CHAIN_SELECTOR, + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + onRamp: ON_RAMP_ADDRESS, + rmnProxy: address(s_mockRMN) + }) + ); + CommitStore.DynamicConfig memory dynamicConfig = + CommitStore.DynamicConfig({priceRegistry: address(s_priceRegistry)}); + s_commitStore.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, abi.encode(dynamicConfig), s_offchainConfigVersion, abi.encode("") + ); + + address[] memory priceUpdaters = new address[](1); + priceUpdaters[0] = address(s_commitStore); + s_priceRegistry.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: priceUpdaters, removedCallers: new address[](0)}) + ); + } +} + +contract CommitStoreRealRMNSetup is PriceRegistrySetup, OCR2BaseSetup { + CommitStoreHelper internal s_commitStore; + + RMN internal s_rmn; + + address internal constant BLESS_VOTE_ADDR = address(8888); + + function setUp() public virtual override(PriceRegistrySetup, OCR2BaseSetup) { + PriceRegistrySetup.setUp(); + OCR2BaseSetup.setUp(); + + RMN.Voter[] memory voters = new RMN.Voter[](1); + voters[0] = + RMN.Voter({blessVoteAddr: BLESS_VOTE_ADDR, curseVoteAddr: address(9999), blessWeight: 1, curseWeight: 1}); + // Overwrite base mock rmn with real. + s_rmn = new RMN(RMN.Config({voters: voters, blessWeightThreshold: 1, curseWeightThreshold: 1})); + s_commitStore = new CommitStoreHelper( + CommitStore.StaticConfig({ + chainSelector: DEST_CHAIN_SELECTOR, + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + onRamp: ON_RAMP_ADDRESS, + rmnProxy: address(s_rmn) + }) + ); + CommitStore.DynamicConfig memory dynamicConfig = + CommitStore.DynamicConfig({priceRegistry: address(s_priceRegistry)}); + s_commitStore.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, abi.encode(dynamicConfig), s_offchainConfigVersion, abi.encode("") + ); + } +} + +contract CommitStore_constructor is PriceRegistrySetup, OCR2BaseSetup { + function setUp() public virtual override(PriceRegistrySetup, OCR2BaseSetup) { + PriceRegistrySetup.setUp(); + OCR2BaseSetup.setUp(); + } + + function test_Constructor_Success() public { + CommitStore.StaticConfig memory staticConfig = CommitStore.StaticConfig({ + chainSelector: DEST_CHAIN_SELECTOR, + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + onRamp: 0x2C44CDDdB6a900Fa2B585dd299E03D12Fa4293Bc, + rmnProxy: address(s_mockRMN) + }); + CommitStore.DynamicConfig memory dynamicConfig = + CommitStore.DynamicConfig({priceRegistry: address(s_priceRegistry)}); + + vm.expectEmit(); + emit CommitStore.ConfigSet(staticConfig, dynamicConfig); + + CommitStore commitStore = new CommitStore(staticConfig); + commitStore.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, abi.encode(dynamicConfig), s_offchainConfigVersion, abi.encode("") + ); + + CommitStore.StaticConfig memory gotStaticConfig = commitStore.getStaticConfig(); + + assertEq(staticConfig.chainSelector, gotStaticConfig.chainSelector); + assertEq(staticConfig.sourceChainSelector, gotStaticConfig.sourceChainSelector); + assertEq(staticConfig.onRamp, gotStaticConfig.onRamp); + assertEq(staticConfig.rmnProxy, gotStaticConfig.rmnProxy); + + CommitStore.DynamicConfig memory gotDynamicConfig = commitStore.getDynamicConfig(); + + assertEq(dynamicConfig.priceRegistry, gotDynamicConfig.priceRegistry); + + // CommitStore initial values + assertEq(0, commitStore.getLatestPriceEpochAndRound()); + assertEq(1, commitStore.getExpectedNextSequenceNumber()); + assertEq(commitStore.typeAndVersion(), "CommitStore 1.5.0-dev"); + assertEq(OWNER, commitStore.owner()); + assertTrue(commitStore.isUnpausedAndNotCursed()); + } +} + +contract CommitStore_setMinSeqNr is CommitStoreSetup { + function test_Fuzz_SetMinSeqNr_Success(uint64 minSeqNr) public { + vm.expectEmit(); + emit CommitStore.SequenceNumberSet(s_commitStore.getExpectedNextSequenceNumber(), minSeqNr); + + s_commitStore.setMinSeqNr(minSeqNr); + + assertEq(s_commitStore.getExpectedNextSequenceNumber(), minSeqNr); + } + + // Reverts + function test_OnlyOwner_Revert() public { + vm.stopPrank(); + vm.expectRevert("Only callable by owner"); + s_commitStore.setMinSeqNr(6723); + } +} + +contract CommitStore_setDynamicConfig is CommitStoreSetup { + function test_Fuzz_SetDynamicConfig_Success(address priceRegistry) public { + vm.assume(priceRegistry != address(0)); + CommitStore.StaticConfig memory staticConfig = s_commitStore.getStaticConfig(); + CommitStore.DynamicConfig memory dynamicConfig = CommitStore.DynamicConfig({priceRegistry: priceRegistry}); + bytes memory onchainConfig = abi.encode(dynamicConfig); + + vm.expectEmit(); + emit CommitStore.ConfigSet(staticConfig, dynamicConfig); + + uint32 configCount = 1; + + vm.expectEmit(); + emit OCR2Abstract.ConfigSet( + uint32(block.number), + getBasicConfigDigest(address(s_commitStore), s_f, configCount, onchainConfig), + configCount + 1, + s_valid_signers, + s_valid_transmitters, + s_f, + onchainConfig, + s_offchainConfigVersion, + abi.encode("") + ); + + s_commitStore.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, onchainConfig, s_offchainConfigVersion, abi.encode("") + ); + + CommitStore.DynamicConfig memory gotDynamicConfig = s_commitStore.getDynamicConfig(); + assertEq(gotDynamicConfig.priceRegistry, dynamicConfig.priceRegistry); + } + + function test_PriceEpochCleared_Success() public { + // Set latest price epoch and round to non-zero. + uint40 latestEpochAndRound = 1782155; + s_commitStore.setLatestPriceEpochAndRound(latestEpochAndRound); + assertEq(latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); + + CommitStore.DynamicConfig memory dynamicConfig = CommitStore.DynamicConfig({priceRegistry: address(1)}); + // New config should clear it. + s_commitStore.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, abi.encode(dynamicConfig), s_offchainConfigVersion, abi.encode("") + ); + // Assert cleared. + assertEq(0, s_commitStore.getLatestPriceEpochAndRound()); + } + + // Reverts + function test_OnlyOwner_Revert() public { + CommitStore.DynamicConfig memory dynamicConfig = CommitStore.DynamicConfig({priceRegistry: address(23784264)}); + + vm.stopPrank(); + vm.expectRevert("Only callable by owner"); + s_commitStore.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, abi.encode(dynamicConfig), s_offchainConfigVersion, abi.encode("") + ); + } + + function test_InvalidCommitStoreConfig_Revert() public { + CommitStore.DynamicConfig memory dynamicConfig = CommitStore.DynamicConfig({priceRegistry: address(0)}); + + vm.expectRevert(CommitStore.InvalidCommitStoreConfig.selector); + s_commitStore.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, abi.encode(dynamicConfig), s_offchainConfigVersion, abi.encode("") + ); + } +} + +contract CommitStore_resetUnblessedRoots is CommitStoreRealRMNSetup { + function test_ResetUnblessedRoots_Success() public { + bytes32[] memory rootsToReset = new bytes32[](3); + rootsToReset[0] = "1"; + rootsToReset[1] = "2"; + rootsToReset[2] = "3"; + + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getEmptyPriceUpdates(), + interval: CommitStore.Interval(1, 2), + merkleRoot: rootsToReset[0] + }); + + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + + report = CommitStore.CommitReport({ + priceUpdates: getEmptyPriceUpdates(), + interval: CommitStore.Interval(3, 4), + merkleRoot: rootsToReset[1] + }); + + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + + report = CommitStore.CommitReport({ + priceUpdates: getEmptyPriceUpdates(), + interval: CommitStore.Interval(5, 5), + merkleRoot: rootsToReset[2] + }); + + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + + IRMN.TaggedRoot[] memory blessedTaggedRoots = new IRMN.TaggedRoot[](1); + blessedTaggedRoots[0] = IRMN.TaggedRoot({commitStore: address(s_commitStore), root: rootsToReset[1]}); + + vm.startPrank(BLESS_VOTE_ADDR); + s_rmn.voteToBless(blessedTaggedRoots); + + vm.expectEmit(false, false, false, true); + emit CommitStore.RootRemoved(rootsToReset[0]); + + vm.expectEmit(false, false, false, true); + emit CommitStore.RootRemoved(rootsToReset[2]); + + vm.startPrank(OWNER); + s_commitStore.resetUnblessedRoots(rootsToReset); + + assertEq(0, s_commitStore.getMerkleRoot(rootsToReset[0])); + assertEq(BLOCK_TIME, s_commitStore.getMerkleRoot(rootsToReset[1])); + assertEq(0, s_commitStore.getMerkleRoot(rootsToReset[2])); + } + + // Reverts + + function test_OnlyOwner_Revert() public { + vm.stopPrank(); + vm.expectRevert("Only callable by owner"); + bytes32[] memory rootToReset; + s_commitStore.resetUnblessedRoots(rootToReset); + } +} + +contract CommitStore_report is CommitStoreSetup { + function test_ReportOnlyRootSuccess_gas() public { + vm.pauseGasMetering(); + uint64 max1 = 931; + bytes32 root = "Only a single root"; + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getEmptyPriceUpdates(), + interval: CommitStore.Interval(1, max1), + merkleRoot: root + }); + + vm.expectEmit(); + emit CommitStore.ReportAccepted(report); + + bytes memory encodedReport = abi.encode(report); + + vm.resumeGasMetering(); + s_commitStore.report(encodedReport, ++s_latestEpochAndRound); + vm.pauseGasMetering(); + + assertEq(max1 + 1, s_commitStore.getExpectedNextSequenceNumber()); + assertEq(block.timestamp, s_commitStore.getMerkleRoot(root)); + vm.resumeGasMetering(); + } + + function test_ReportAndPriceUpdate_Success() public { + uint64 max1 = 12; + + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + interval: CommitStore.Interval(1, max1), + merkleRoot: "test #2" + }); + + vm.expectEmit(); + emit CommitStore.ReportAccepted(report); + + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + + assertEq(max1 + 1, s_commitStore.getExpectedNextSequenceNumber()); + assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); + } + + function test_StaleReportWithRoot_Success() public { + uint64 maxSeq = 12; + uint224 tokenStartPrice = + IPriceRegistry(s_commitStore.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value; + + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + interval: CommitStore.Interval(1, maxSeq), + merkleRoot: "stale report 1" + }); + + vm.expectEmit(); + emit CommitStore.ReportAccepted(report); + + s_commitStore.report(abi.encode(report), s_latestEpochAndRound); + assertEq(maxSeq + 1, s_commitStore.getExpectedNextSequenceNumber()); + assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); + + report = CommitStore.CommitReport({ + priceUpdates: getEmptyPriceUpdates(), + interval: CommitStore.Interval(maxSeq + 1, maxSeq * 2), + merkleRoot: "stale report 2" + }); + + vm.expectEmit(); + emit CommitStore.ReportAccepted(report); + + s_commitStore.report(abi.encode(report), s_latestEpochAndRound); + assertEq(maxSeq * 2 + 1, s_commitStore.getExpectedNextSequenceNumber()); + assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); + assertEq( + tokenStartPrice, + IPriceRegistry(s_commitStore.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value + ); + } + + function test_OnlyTokenPriceUpdates_Success() public { + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + interval: CommitStore.Interval(0, 0), + merkleRoot: "" + }); + + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); + } + + function test_OnlyGasPriceUpdates_Success() public { + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + interval: CommitStore.Interval(0, 0), + merkleRoot: "" + }); + + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); + } + + function test_ValidPriceUpdateThenStaleReportWithRoot_Success() public { + uint64 maxSeq = 12; + uint224 tokenPrice1 = 4e18; + uint224 tokenPrice2 = 5e18; + + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice1), + interval: CommitStore.Interval(0, 0), + merkleRoot: "" + }); + + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, tokenPrice1, block.timestamp); + + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); + + report = CommitStore.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice2), + interval: CommitStore.Interval(1, maxSeq), + merkleRoot: "stale report" + }); + + vm.expectEmit(); + emit CommitStore.ReportAccepted(report); + + s_commitStore.report(abi.encode(report), s_latestEpochAndRound); + + assertEq(maxSeq + 1, s_commitStore.getExpectedNextSequenceNumber()); + assertEq( + tokenPrice1, IPriceRegistry(s_commitStore.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value + ); + assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); + } + + // Reverts + + function test_Paused_Revert() public { + s_commitStore.pause(); + bytes memory report; + vm.expectRevert(CommitStore.PausedError.selector); + s_commitStore.report(report, ++s_latestEpochAndRound); + } + + function test_Unhealthy_Revert() public { + s_mockRMN.setGlobalCursed(true); + vm.expectRevert(CommitStore.CursedByRMN.selector); + bytes memory report; + s_commitStore.report(report, ++s_latestEpochAndRound); + } + + function test_InvalidRootRevert() public { + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getEmptyPriceUpdates(), + interval: CommitStore.Interval(1, 4), + merkleRoot: bytes32(0) + }); + + vm.expectRevert(CommitStore.InvalidRoot.selector); + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + } + + function test_InvalidInterval_Revert() public { + CommitStore.Interval memory interval = CommitStore.Interval(2, 2); + CommitStore.CommitReport memory report = + CommitStore.CommitReport({priceUpdates: getEmptyPriceUpdates(), interval: interval, merkleRoot: bytes32(0)}); + + vm.expectRevert(abi.encodeWithSelector(CommitStore.InvalidInterval.selector, interval)); + + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + } + + function test_InvalidIntervalMinLargerThanMax_Revert() public { + CommitStore.Interval memory interval = CommitStore.Interval(1, 0); + CommitStore.CommitReport memory report = + CommitStore.CommitReport({priceUpdates: getEmptyPriceUpdates(), interval: interval, merkleRoot: bytes32(0)}); + + vm.expectRevert(abi.encodeWithSelector(CommitStore.InvalidInterval.selector, interval)); + + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + } + + function test_ZeroEpochAndRound_Revert() public { + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + interval: CommitStore.Interval(0, 0), + merkleRoot: bytes32(0) + }); + + vm.expectRevert(CommitStore.StaleReport.selector); + + s_commitStore.report(abi.encode(report), 0); + } + + function test_OnlyPriceUpdateStaleReport_Revert() public { + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + interval: CommitStore.Interval(0, 0), + merkleRoot: bytes32(0) + }); + + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + + vm.expectRevert(CommitStore.StaleReport.selector); + s_commitStore.report(abi.encode(report), s_latestEpochAndRound); + } + + function test_RootAlreadyCommitted_Revert() public { + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getEmptyPriceUpdates(), + interval: CommitStore.Interval(1, 2), + merkleRoot: "Only a single root" + }); + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + + report = CommitStore.CommitReport({ + priceUpdates: getEmptyPriceUpdates(), + interval: CommitStore.Interval(3, 3), + merkleRoot: "Only a single root" + }); + + vm.expectRevert(CommitStore.RootAlreadyCommitted.selector); + + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + } +} + +contract CommitStore_verify is CommitStoreRealRMNSetup { + function test_NotBlessed_Success() public { + bytes32[] memory leaves = new bytes32[](1); + leaves[0] = "root"; + s_commitStore.report( + abi.encode( + CommitStore.CommitReport({ + priceUpdates: getEmptyPriceUpdates(), + interval: CommitStore.Interval(1, 2), + merkleRoot: leaves[0] + }) + ), + ++s_latestEpochAndRound + ); + bytes32[] memory proofs = new bytes32[](0); + // We have not blessed this root, should return 0. + uint256 timestamp = s_commitStore.verify(leaves, proofs, 0); + assertEq(uint256(0), timestamp); + } + + function test_Blessed_Success() public { + bytes32[] memory leaves = new bytes32[](1); + leaves[0] = "root"; + s_commitStore.report( + abi.encode( + CommitStore.CommitReport({ + priceUpdates: getEmptyPriceUpdates(), + interval: CommitStore.Interval(1, 2), + merkleRoot: leaves[0] + }) + ), + ++s_latestEpochAndRound + ); + // Bless that root. + IRMN.TaggedRoot[] memory taggedRoots = new IRMN.TaggedRoot[](1); + taggedRoots[0] = IRMN.TaggedRoot({commitStore: address(s_commitStore), root: leaves[0]}); + vm.startPrank(BLESS_VOTE_ADDR); + s_rmn.voteToBless(taggedRoots); + bytes32[] memory proofs = new bytes32[](0); + uint256 timestamp = s_commitStore.verify(leaves, proofs, 0); + assertEq(BLOCK_TIME, timestamp); + } + + // Reverts + + function test_Paused_Revert() public { + s_commitStore.pause(); + + bytes32[] memory hashedLeaves = new bytes32[](0); + bytes32[] memory proofs = new bytes32[](0); + uint256 proofFlagBits = 0; + + vm.expectRevert(CommitStore.PausedError.selector); + s_commitStore.verify(hashedLeaves, proofs, proofFlagBits); + } + + function test_TooManyLeaves_Revert() public { + bytes32[] memory leaves = new bytes32[](258); + bytes32[] memory proofs = new bytes32[](0); + + vm.expectRevert(MerkleMultiProof.InvalidProof.selector); + + s_commitStore.verify(leaves, proofs, 0); + } +} + +contract CommitStore_isUnpausedAndRMNHealthy is CommitStoreSetup { + function test_RMN_Success() public { + // Test pausing + assertFalse(s_commitStore.paused()); + assertTrue(s_commitStore.isUnpausedAndNotCursed()); + s_commitStore.pause(); + assertTrue(s_commitStore.paused()); + assertFalse(s_commitStore.isUnpausedAndNotCursed()); + s_commitStore.unpause(); + assertFalse(s_commitStore.paused()); + assertTrue(s_commitStore.isUnpausedAndNotCursed()); + + // Test rmn + s_mockRMN.setGlobalCursed(true); + assertFalse(s_commitStore.isUnpausedAndNotCursed()); + s_mockRMN.setGlobalCursed(false); + // TODO: also test with s_mockRMN.setChainCursed(sourceChainSelector), + // also for other similar tests (e.g., OffRamp, OnRamp) + assertTrue(s_commitStore.isUnpausedAndNotCursed()); + + s_mockRMN.setGlobalCursed(true); + s_commitStore.pause(); + assertFalse(s_commitStore.isUnpausedAndNotCursed()); + } +} + +contract CommitStore_setLatestPriceEpochAndRound is CommitStoreSetup { + function test_SetLatestPriceEpochAndRound_Success() public { + uint40 latestRoundAndEpoch = 1782155; + + vm.expectEmit(); + emit CommitStore.LatestPriceEpochAndRoundSet( + uint40(s_commitStore.getLatestPriceEpochAndRound()), latestRoundAndEpoch + ); + + s_commitStore.setLatestPriceEpochAndRound(latestRoundAndEpoch); + + assertEq(uint40(s_commitStore.getLatestPriceEpochAndRound()), latestRoundAndEpoch); + } + + // Reverts + function test_OnlyOwner_Revert() public { + vm.stopPrank(); + vm.expectRevert("Only callable by owner"); + s_commitStore.setLatestPriceEpochAndRound(6723); + } +} diff --git a/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol b/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol new file mode 100644 index 0000000000..816862cbdf --- /dev/null +++ b/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import "../commitStore/CommitStore.t.sol"; +import "../helpers/MerkleHelper.sol"; +import "../offRamp/EVM2EVMOffRampSetup.t.sol"; +import "../onRamp/EVM2EVMOnRampSetup.t.sol"; + +contract E2E is EVM2EVMOnRampSetup, CommitStoreSetup, EVM2EVMOffRampSetup { + using Internal for Internal.EVM2EVMMessage; + + function setUp() public virtual override(EVM2EVMOnRampSetup, CommitStoreSetup, EVM2EVMOffRampSetup) { + EVM2EVMOnRampSetup.setUp(); + CommitStoreSetup.setUp(); + EVM2EVMOffRampSetup.setUp(); + + deployOffRamp(s_commitStore, s_destRouter, address(0)); + } + + function test_E2E_3MessagesSuccess_gas() public { + vm.pauseGasMetering(); + IERC20 token0 = IERC20(s_sourceTokens[0]); + IERC20 token1 = IERC20(s_sourceTokens[1]); + uint256 balance0Pre = token0.balanceOf(OWNER); + uint256 balance1Pre = token1.balanceOf(OWNER); + + Internal.EVM2EVMMessage[] memory messages = new Internal.EVM2EVMMessage[](3); + messages[0] = sendRequest(1); + messages[1] = sendRequest(2); + messages[2] = sendRequest(3); + + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, _generateTokenMessage()); + // Asserts that the tokens have been sent and the fee has been paid. + assertEq(balance0Pre - messages.length * (i_tokenAmount0 + expectedFee), token0.balanceOf(OWNER)); + assertEq(balance1Pre - messages.length * i_tokenAmount1, token1.balanceOf(OWNER)); + + bytes32 metaDataHash = s_offRamp.metadataHash(); + + bytes32[] memory hashedMessages = new bytes32[](3); + hashedMessages[0] = messages[0]._hash(metaDataHash); + messages[0].messageId = hashedMessages[0]; + hashedMessages[1] = messages[1]._hash(metaDataHash); + messages[1].messageId = hashedMessages[1]; + hashedMessages[2] = messages[2]._hash(metaDataHash); + messages[2].messageId = hashedMessages[2]; + + bytes32[] memory merkleRoots = new bytes32[](1); + merkleRoots[0] = MerkleHelper.getMerkleRoot(hashedMessages); + + address[] memory onRamps = new address[](1); + onRamps[0] = ON_RAMP_ADDRESS; + + bytes memory commitReport = abi.encode( + CommitStore.CommitReport({ + priceUpdates: getEmptyPriceUpdates(), + interval: CommitStore.Interval(messages[0].sequenceNumber, messages[2].sequenceNumber), + merkleRoot: merkleRoots[0] + }) + ); + + vm.resumeGasMetering(); + s_commitStore.report(commitReport, ++s_latestEpochAndRound); + vm.pauseGasMetering(); + + s_mockRMN.setTaggedRootBlessed(IRMN.TaggedRoot({commitStore: address(s_commitStore), root: merkleRoots[0]}), true); + + bytes32[] memory proofs = new bytes32[](0); + uint256 timestamp = s_commitStore.verify(merkleRoots, proofs, 2 ** 2 - 1); + assertEq(BLOCK_TIME, timestamp); + + // We change the block time so when execute would e.g. use the current + // block time instead of the committed block time the value would be + // incorrect in the checks below. + vm.warp(BLOCK_TIME + 2000); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[1].sequenceNumber, messages[1].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[2].sequenceNumber, messages[2].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + Internal.ExecutionReport memory execReport = _generateReportFromMessages(messages); + vm.resumeGasMetering(); + s_offRamp.execute(execReport, new uint256[](0)); + } + + function sendRequest(uint64 expectedSeqNum) public returns (Internal.EVM2EVMMessage memory) { + Client.EVM2AnyMessage memory message = _generateTokenMessage(); + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + + IERC20(s_sourceTokens[0]).approve(address(s_sourceRouter), i_tokenAmount0 + expectedFee); + IERC20(s_sourceTokens[1]).approve(address(s_sourceRouter), i_tokenAmount1); + + message.receiver = abi.encode(address(s_receiver)); + Internal.EVM2EVMMessage memory msgEvent = + _messageToEvent(message, expectedSeqNum, expectedSeqNum, expectedFee, OWNER); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(msgEvent); + + vm.resumeGasMetering(); + s_sourceRouter.ccipSend(DEST_CHAIN_SELECTOR, message); + vm.pauseGasMetering(); + + return msgEvent; + } +} diff --git a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol new file mode 100644 index 0000000000..cbe8a35dce --- /dev/null +++ b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; +import {NonceManager} from "../../NonceManager.sol"; +import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; +import "../helpers/MerkleHelper.sol"; +import "../offRamp/EVM2EVMMultiOffRampSetup.t.sol"; +import "../onRamp/EVM2EVMMultiOnRampSetup.t.sol"; + +/// @notice This E2E test implements the following scenario: +/// 1. Send multiple messages from multiple source chains to a single destination chain (2 messages from source chain 1 and 1 from +/// source chain 2). +/// 2. Commit multiple merkle roots (1 for each source chain). +/// 3. Batch execute all the committed messages. +contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { + using Internal for Internal.Any2EVMRampMessage; + + Router internal s_sourceRouter2; + EVM2EVMMultiOnRampHelper internal s_onRamp2; + TokenAdminRegistry internal s_tokenAdminRegistry2; + NonceManager internal s_nonceManager2; + + bytes32 internal s_metadataHash2; + + mapping(address destPool => address sourcePool) internal s_sourcePoolByDestPool; + + function setUp() public virtual override(EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup) { + EVM2EVMMultiOnRampSetup.setUp(); + EVM2EVMMultiOffRampSetup.setUp(); + + // Deploy new source router for the new source chain + s_sourceRouter2 = new Router(s_sourceRouter.getWrappedNative(), address(s_mockRMN)); + + // Deploy new TokenAdminRegistry for the new source chain + s_tokenAdminRegistry2 = new TokenAdminRegistry(); + + // Deploy new token pools and set them on the new TokenAdminRegistry + for (uint256 i = 0; i < s_sourceTokens.length; ++i) { + address token = s_sourceTokens[i]; + address pool = address( + new LockReleaseTokenPool(IERC20(token), new address[](0), address(s_mockRMN), true, address(s_sourceRouter2)) + ); + + s_sourcePoolByDestPool[s_destPoolBySourceToken[token]] = pool; + + _setPool( + s_tokenAdminRegistry2, token, pool, DEST_CHAIN_SELECTOR, s_destPoolByToken[s_destTokens[i]], s_destTokens[i] + ); + } + + for (uint256 i = 0; i < s_destTokens.length; ++i) { + address token = s_destTokens[i]; + address pool = s_destPoolByToken[token]; + + _setPool( + s_tokenAdminRegistry2, token, pool, SOURCE_CHAIN_SELECTOR + 1, s_sourcePoolByDestPool[pool], s_sourceTokens[i] + ); + } + + s_nonceManager2 = new NonceManager(new address[](0)); + + ( + // Deploy the new source chain onramp + // Outsource to shared helper function with EVM2EVMMultiOnRampSetup + s_onRamp2, + s_metadataHash2 + ) = _deployOnRamp( + SOURCE_CHAIN_SELECTOR + 1, address(s_sourceRouter2), address(s_nonceManager2), address(s_tokenAdminRegistry2) + ); + + address[] memory authorizedCallers = new address[](1); + authorizedCallers[0] = address(s_onRamp2); + s_nonceManager2.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: authorizedCallers, removedCallers: new address[](0)}) + ); + + // Enable destination chain on new source chain router + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: address(s_onRamp2)}); + s_sourceRouter2.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), new Router.OffRamp[](0)); + + // Deploy offramp + _deployOffRamp(s_destRouter, s_mockRMN, s_inboundNonceManager); + + // Enable source chains on offramp + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](2); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + isEnabled: true, + // Must match OnRamp address + onRamp: abi.encode(address(s_onRamp)) + }); + sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR + 1, + isEnabled: true, + onRamp: abi.encode(address(s_onRamp2)) + }); + + _setupMultipleOffRampsFromConfigs(sourceChainConfigs); + } + + function test_E2E_3MessagesSuccess_gas() public { + vm.pauseGasMetering(); + IERC20 token0 = IERC20(s_sourceTokens[0]); + IERC20 token1 = IERC20(s_sourceTokens[1]); + uint256 balance0Pre = token0.balanceOf(OWNER); + uint256 balance1Pre = token1.balanceOf(OWNER); + + // Send messages + Internal.Any2EVMRampMessage[] memory messages1 = new Internal.Any2EVMRampMessage[](2); + messages1[0] = _sendRequest(1, SOURCE_CHAIN_SELECTOR, 1, s_metadataHash, s_sourceRouter, s_tokenAdminRegistry); + messages1[1] = _sendRequest(2, SOURCE_CHAIN_SELECTOR, 2, s_metadataHash, s_sourceRouter, s_tokenAdminRegistry); + Internal.Any2EVMRampMessage[] memory messages2 = new Internal.Any2EVMRampMessage[](1); + messages2[0] = + _sendRequest(1, SOURCE_CHAIN_SELECTOR + 1, 1, s_metadataHash2, s_sourceRouter2, s_tokenAdminRegistry2); + + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, _generateTokenMessage()); + // Asserts that the tokens have been sent and the fee has been paid. + assertEq( + balance0Pre - (messages1.length + messages2.length) * (i_tokenAmount0 + expectedFee), token0.balanceOf(OWNER) + ); + assertEq(balance1Pre - (messages1.length + messages2.length) * i_tokenAmount1, token1.balanceOf(OWNER)); + + // Commit + bytes32[] memory hashedMessages1 = new bytes32[](2); + hashedMessages1[0] = messages1[0]._hash(abi.encode(address(s_onRamp))); + hashedMessages1[1] = messages1[1]._hash(abi.encode(address(s_onRamp))); + bytes32[] memory hashedMessages2 = new bytes32[](1); + hashedMessages2[0] = messages2[0]._hash(abi.encode(address(s_onRamp2))); + + bytes32[] memory merkleRoots = new bytes32[](2); + merkleRoots[0] = MerkleHelper.getMerkleRoot(hashedMessages1); + merkleRoots[1] = MerkleHelper.getMerkleRoot(hashedMessages2); + + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](2); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + interval: EVM2EVMMultiOffRamp.Interval(messages1[0].header.sequenceNumber, messages1[1].header.sequenceNumber), + merkleRoot: merkleRoots[0] + }); + roots[1] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR + 1, + interval: EVM2EVMMultiOffRamp.Interval(messages2[0].header.sequenceNumber, messages2[0].header.sequenceNumber), + merkleRoot: merkleRoots[1] + }); + + EVM2EVMMultiOffRamp.CommitReport memory report = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + + vm.resumeGasMetering(); + _commit(report, ++s_latestSequenceNumber); + vm.pauseGasMetering(); + + s_mockRMN.setTaggedRootBlessed(IRMN.TaggedRoot({commitStore: address(s_offRamp), root: merkleRoots[0]}), true); + s_mockRMN.setTaggedRootBlessed(IRMN.TaggedRoot({commitStore: address(s_offRamp), root: merkleRoots[1]}), true); + + bytes32[] memory proofs = new bytes32[](0); + bytes32[] memory hashedLeaves = new bytes32[](1); + hashedLeaves[0] = merkleRoots[0]; + uint256 timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR, hashedLeaves, proofs, 2 ** 2 - 1); + assertEq(BLOCK_TIME, timestamp); + hashedLeaves[0] = merkleRoots[1]; + timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR + 1, hashedLeaves, proofs, 2 ** 2 - 1); + assertEq(BLOCK_TIME, timestamp); + + // We change the block time so when execute would e.g. use the current + // block time instead of the committed block time the value would be + // incorrect in the checks below. + vm.warp(BLOCK_TIME + 2000); + + // Execute + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR, + messages1[0].header.sequenceNumber, + messages1[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR, + messages1[1].header.sequenceNumber, + messages1[1].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR + 1, + messages2[0].header.sequenceNumber, + messages2[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); + reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR, messages1); + reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR + 1, messages2); + + vm.resumeGasMetering(); + _execute(reports); + } + + function _sendRequest( + uint64 expectedSeqNum, + uint64 sourceChainSelector, + uint64 nonce, + bytes32 metadataHash, + Router router, + TokenAdminRegistry tokenAdminRegistry + ) public returns (Internal.Any2EVMRampMessage memory) { + Client.EVM2AnyMessage memory message = _generateTokenMessage(); + uint256 expectedFee = router.getFee(DEST_CHAIN_SELECTOR, message); + + IERC20(s_sourceTokens[0]).approve(address(router), i_tokenAmount0 + expectedFee); + IERC20(s_sourceTokens[1]).approve(address(router), i_tokenAmount1); + + message.receiver = abi.encode(address(s_receiver)); + Internal.EVM2AnyRampMessage memory msgEvent = _messageToEvent( + message, + sourceChainSelector, + DEST_CHAIN_SELECTOR, + expectedSeqNum, + nonce, + expectedFee, + OWNER, + metadataHash, + tokenAdminRegistry + ); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, msgEvent); + + vm.resumeGasMetering(); + router.ccipSend(DEST_CHAIN_SELECTOR, message); + vm.pauseGasMetering(); + + uint256 gasLimit = s_priceRegistry.parseEVMExtraArgsFromBytes(msgEvent.extraArgs, DEST_CHAIN_SELECTOR).gasLimit; + + return Internal.Any2EVMRampMessage({ + header: Internal.RampMessageHeader({ + messageId: msgEvent.header.messageId, + sourceChainSelector: sourceChainSelector, + destChainSelector: DEST_CHAIN_SELECTOR, + sequenceNumber: msgEvent.header.sequenceNumber, + nonce: msgEvent.header.nonce + }), + sender: abi.encode(msgEvent.sender), + data: msgEvent.data, + receiver: abi.decode(msgEvent.receiver, (address)), + gasLimit: gasLimit, + tokenAmounts: msgEvent.tokenAmounts + }); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/AggregateRateLimiterHelper.sol b/contracts/src/v0.8/ccip/test/helpers/AggregateRateLimiterHelper.sol new file mode 100644 index 0000000000..ced605a752 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/AggregateRateLimiterHelper.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import "../../AggregateRateLimiter.sol"; + +contract AggregateRateLimiterHelper is AggregateRateLimiter { + constructor(RateLimiter.Config memory config) AggregateRateLimiter(config) {} + + function rateLimitValue(uint256 value) public { + _rateLimitValue(value); + } + + function getTokenValue( + Client.EVMTokenAmount memory tokenAmount, + IPriceRegistry priceRegistry + ) public view returns (uint256) { + return _getTokenValue(tokenAmount, priceRegistry); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/BurnMintERC677Helper.sol b/contracts/src/v0.8/ccip/test/helpers/BurnMintERC677Helper.sol new file mode 100644 index 0000000000..9d2346996a --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/BurnMintERC677Helper.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; +import {IGetCCIPAdmin} from "../../interfaces/IGetCCIPAdmin.sol"; + +contract BurnMintERC677Helper is BurnMintERC677, IGetCCIPAdmin { + constructor(string memory name, string memory symbol) BurnMintERC677(name, symbol, 18, 0) {} + + // Gives one full token to any given address. + function drip(address to) external { + _mint(to, 1e18); + } + + function getCCIPAdmin() external view override returns (address) { + return owner(); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/BurnMintMultiTokenPool.sol b/contracts/src/v0.8/ccip/test/helpers/BurnMintMultiTokenPool.sol new file mode 100644 index 0000000000..a21fcde835 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/BurnMintMultiTokenPool.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; + +import {Pool} from "../../libraries/Pool.sol"; +import {MultiTokenPool} from "./MultiTokenPool.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract BurnMintMultiTokenPool is MultiTokenPool { + constructor( + IERC20[] memory tokens, + address[] memory allowlist, + address rmnProxy, + address router + ) MultiTokenPool(tokens, allowlist, rmnProxy, router) {} + + /// @notice Burn the token in the pool + /// @dev The _validateLockOrBurn check is an essential security check + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + external + virtual + override + returns (Pool.LockOrBurnOutV1 memory) + { + _validateLockOrBurn(lockOrBurnIn); + + IBurnMintERC20(lockOrBurnIn.localToken).burn(lockOrBurnIn.amount); + + emit Burned(msg.sender, lockOrBurnIn.amount); + + return Pool.LockOrBurnOutV1({ + destTokenAddress: getRemoteToken(lockOrBurnIn.localToken, lockOrBurnIn.remoteChainSelector), + destPoolData: "" + }); + } + + /// @notice Mint tokens from the pool to the recipient + /// @dev The _validateReleaseOrMint check is an essential security check + function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + external + virtual + override + returns (Pool.ReleaseOrMintOutV1 memory) + { + _validateReleaseOrMint(releaseOrMintIn); + + // Mint to the offRamp, which forwards it to the recipient + IBurnMintERC20(releaseOrMintIn.localToken).mint(msg.sender, releaseOrMintIn.amount); + + emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); + + return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/CCIPConfigHelper.sol b/contracts/src/v0.8/ccip/test/helpers/CCIPConfigHelper.sol new file mode 100644 index 0000000000..74f03890d3 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/CCIPConfigHelper.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.24; + +import {CCIPConfig} from "../../capability/CCIPConfig.sol"; +import {CCIPConfigTypes} from "../../capability/libraries/CCIPConfigTypes.sol"; +import {Internal} from "../../libraries/Internal.sol"; + +contract CCIPConfigHelper is CCIPConfig { + constructor(address capabilitiesRegistry) CCIPConfig(capabilitiesRegistry) {} + + function stateFromConfigLength(uint256 configLength) public pure returns (CCIPConfigTypes.ConfigState) { + return _stateFromConfigLength(configLength); + } + + function validateConfigStateTransition( + CCIPConfigTypes.ConfigState currentState, + CCIPConfigTypes.ConfigState newState + ) public pure { + _validateConfigStateTransition(currentState, newState); + } + + function validateConfigTransition( + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig, + CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfigWithMeta + ) public pure { + _validateConfigTransition(currentConfig, newConfigWithMeta); + } + + function computeNewConfigWithMeta( + uint32 donId, + CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig, + CCIPConfigTypes.OCR3Config[] memory newConfig, + CCIPConfigTypes.ConfigState currentState, + CCIPConfigTypes.ConfigState newState + ) public view returns (CCIPConfigTypes.OCR3ConfigWithMeta[] memory) { + return _computeNewConfigWithMeta(donId, currentConfig, newConfig, currentState, newState); + } + + function groupByPluginType(CCIPConfigTypes.OCR3Config[] memory ocr3Configs) + public + pure + returns (CCIPConfigTypes.OCR3Config[] memory commitConfigs, CCIPConfigTypes.OCR3Config[] memory execConfigs) + { + return _groupByPluginType(ocr3Configs); + } + + function computeConfigDigest( + uint32 donId, + uint64 configCount, + CCIPConfigTypes.OCR3Config memory ocr3Config + ) public pure returns (bytes32) { + return _computeConfigDigest(donId, configCount, ocr3Config); + } + + function validateConfig(CCIPConfigTypes.OCR3Config memory cfg) public view { + _validateConfig(cfg); + } + + function updatePluginConfig( + uint32 donId, + Internal.OCRPluginType pluginType, + CCIPConfigTypes.OCR3Config[] memory newConfig + ) public { + _updatePluginConfig(donId, pluginType, newConfig); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/CommitStoreHelper.sol b/contracts/src/v0.8/ccip/test/helpers/CommitStoreHelper.sol new file mode 100644 index 0000000000..c8d66b8d72 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/CommitStoreHelper.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import "../../CommitStore.sol"; + +contract CommitStoreHelper is CommitStore { + constructor(StaticConfig memory staticConfig) CommitStore(staticConfig) {} + + /// @dev Expose _report for tests + function report(bytes calldata commitReport, uint40 epochAndRound) external { + _report(commitReport, epochAndRound); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol new file mode 100644 index 0000000000..581d9bd705 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {EVM2EVMMultiOffRamp} from "../../offRamp/EVM2EVMMultiOffRamp.sol"; +import {IgnoreContractSize} from "./IgnoreContractSize.sol"; + +contract EVM2EVMMultiOffRampHelper is EVM2EVMMultiOffRamp, IgnoreContractSize { + mapping(uint64 sourceChainSelector => uint256 overrideTimestamp) private s_sourceChainVerificationOverride; + + constructor( + StaticConfig memory staticConfig, + DynamicConfig memory dynamicConfig, + SourceChainConfigArgs[] memory sourceChainConfigs + ) EVM2EVMMultiOffRamp(staticConfig, dynamicConfig, sourceChainConfigs) {} + + function setExecutionStateHelper( + uint64 sourceChainSelector, + uint64 sequenceNumber, + Internal.MessageExecutionState state + ) public { + _setExecutionState(sourceChainSelector, sequenceNumber, state); + } + + function getExecutionStateBitMap(uint64 sourceChainSelector, uint64 bitmapIndex) public view returns (uint256) { + return s_executionStates[sourceChainSelector][bitmapIndex]; + } + + function releaseOrMintSingleToken( + Internal.RampTokenAmount memory sourceTokenAmount, + bytes calldata originalSender, + address receiver, + uint64 sourceChainSelector, + bytes calldata offchainTokenData + ) external returns (Client.EVMTokenAmount memory) { + return + _releaseOrMintSingleToken(sourceTokenAmount, originalSender, receiver, sourceChainSelector, offchainTokenData); + } + + function releaseOrMintTokens( + Internal.RampTokenAmount[] memory sourceTokenAmounts, + bytes memory originalSender, + address receiver, + uint64 sourceChainSelector, + bytes[] calldata offchainTokenData + ) external returns (Client.EVMTokenAmount[] memory) { + return _releaseOrMintTokens(sourceTokenAmounts, originalSender, receiver, sourceChainSelector, offchainTokenData); + } + + function trialExecute( + Internal.Any2EVMRampMessage memory message, + bytes[] memory offchainTokenData + ) external returns (Internal.MessageExecutionState, bytes memory) { + return _trialExecute(message, offchainTokenData); + } + + function executeSingleReport( + Internal.ExecutionReportSingleChain memory rep, + uint256[] memory manualExecGasLimits + ) external { + _executeSingleReport(rep, manualExecGasLimits); + } + + function batchExecute( + Internal.ExecutionReportSingleChain[] memory reports, + uint256[][] memory manualExecGasLimits + ) external { + _batchExecute(reports, manualExecGasLimits); + } + + function verify( + uint64 sourceChainSelector, + bytes32[] memory hashedLeaves, + bytes32[] memory proofs, + uint256 proofFlagBits + ) external view returns (uint256 timestamp) { + return super._verify(sourceChainSelector, hashedLeaves, proofs, proofFlagBits); + } + + function _verify( + uint64 sourceChainSelector, + bytes32[] memory hashedLeaves, + bytes32[] memory proofs, + uint256 proofFlagBits + ) internal view override returns (uint256 timestamp) { + uint256 overrideTimestamp = s_sourceChainVerificationOverride[sourceChainSelector]; + + return overrideTimestamp == 0 + ? super._verify(sourceChainSelector, hashedLeaves, proofs, proofFlagBits) + : overrideTimestamp; + } + + /// @dev Test helper to override _verify result for easier exec testing + function setVerifyOverrideResult(uint64 sourceChainSelector, uint256 overrideTimestamp) external { + s_sourceChainVerificationOverride[sourceChainSelector] = overrideTimestamp; + } + + /// @dev Test helper to directly set a root's timestamp + function setRootTimestamp(uint64 sourceChainSelector, bytes32 root, uint256 timestamp) external { + s_roots[sourceChainSelector][root] = timestamp; + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOnRampHelper.sol b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOnRampHelper.sol new file mode 100644 index 0000000000..0532697d64 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOnRampHelper.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import "../../onRamp/EVM2EVMMultiOnRamp.sol"; +import {IgnoreContractSize} from "./IgnoreContractSize.sol"; + +contract EVM2EVMMultiOnRampHelper is EVM2EVMMultiOnRamp, IgnoreContractSize { + constructor( + StaticConfig memory staticConfig, + DynamicConfig memory dynamicConfig + ) EVM2EVMMultiOnRamp(staticConfig, dynamicConfig) {} +} diff --git a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOffRampHelper.sol b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOffRampHelper.sol new file mode 100644 index 0000000000..e328f0ade2 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOffRampHelper.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import "../../offRamp/EVM2EVMOffRamp.sol"; +import {IgnoreContractSize} from "./IgnoreContractSize.sol"; + +contract EVM2EVMOffRampHelper is EVM2EVMOffRamp, IgnoreContractSize { + constructor( + StaticConfig memory staticConfig, + RateLimiter.Config memory rateLimiterConfig + ) EVM2EVMOffRamp(staticConfig, rateLimiterConfig) {} + + function setExecutionStateHelper(uint64 sequenceNumber, Internal.MessageExecutionState state) public { + _setExecutionState(sequenceNumber, state); + } + + function getExecutionStateBitMap(uint64 bitmapIndex) public view returns (uint256) { + return s_executionStates[bitmapIndex]; + } + + function releaseOrMintToken( + uint256 sourceTokenAmount, + bytes calldata originalSender, + address receiver, + Internal.SourceTokenData calldata sourceTokenData, + bytes calldata offchainTokenData + ) external returns (Client.EVMTokenAmount memory) { + return _releaseOrMintToken(sourceTokenAmount, originalSender, receiver, sourceTokenData, offchainTokenData); + } + + function releaseOrMintTokens( + Client.EVMTokenAmount[] memory sourceTokenAmounts, + bytes calldata originalSender, + address receiver, + bytes[] calldata sourceTokenData, + bytes[] calldata offchainTokenData + ) external returns (Client.EVMTokenAmount[] memory) { + return _releaseOrMintTokens(sourceTokenAmounts, originalSender, receiver, sourceTokenData, offchainTokenData); + } + + function trialExecute( + Internal.EVM2EVMMessage memory message, + bytes[] memory offchainTokenData + ) external returns (Internal.MessageExecutionState, bytes memory) { + return _trialExecute(message, offchainTokenData); + } + + function report(bytes calldata executableMessages) external { + _report(executableMessages); + } + + function execute(Internal.ExecutionReport memory rep, uint256[] memory manualExecGasLimits) external { + _execute(rep, manualExecGasLimits); + } + + function metadataHash() external view returns (bytes32) { + return _metadataHash(Internal.EVM_2_EVM_MESSAGE_HASH); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOnRampHelper.sol b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOnRampHelper.sol new file mode 100644 index 0000000000..5cce6aaa44 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOnRampHelper.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import "../../onRamp/EVM2EVMOnRamp.sol"; +import {IgnoreContractSize} from "./IgnoreContractSize.sol"; + +contract EVM2EVMOnRampHelper is EVM2EVMOnRamp, IgnoreContractSize { + constructor( + StaticConfig memory staticConfig, + DynamicConfig memory dynamicConfig, + RateLimiter.Config memory rateLimiterConfig, + FeeTokenConfigArgs[] memory feeTokenConfigs, + TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs, + NopAndWeight[] memory nopsAndWeights + ) + EVM2EVMOnRamp( + staticConfig, + dynamicConfig, + rateLimiterConfig, + feeTokenConfigs, + tokenTransferFeeConfigArgs, + nopsAndWeights + ) + {} + + function getDataAvailabilityCost( + uint112 dataAvailabilityGasPrice, + uint256 messageDataLength, + uint256 numberOfTokens, + uint32 tokenTransferBytesOverhead + ) external view returns (uint256) { + return + _getDataAvailabilityCost(dataAvailabilityGasPrice, messageDataLength, numberOfTokens, tokenTransferBytesOverhead); + } + + function getTokenTransferCost( + address feeToken, + uint224 feeTokenPrice, + Client.EVMTokenAmount[] calldata tokenAmounts + ) external view returns (uint256, uint32, uint32) { + return _getTokenTransferCost(feeToken, feeTokenPrice, tokenAmounts); + } + + function getSequenceNumber() external view returns (uint64) { + return s_sequenceNumber; + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/EtherSenderReceiverHelper.sol b/contracts/src/v0.8/ccip/test/helpers/EtherSenderReceiverHelper.sol new file mode 100644 index 0000000000..71a5cdc7ab --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/EtherSenderReceiverHelper.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {EtherSenderReceiver} from "../../applications/EtherSenderReceiver.sol"; +import {Client} from "../../libraries/Client.sol"; + +contract EtherSenderReceiverHelper is EtherSenderReceiver { + constructor(address router) EtherSenderReceiver(router) {} + + function validatedMessage(Client.EVM2AnyMessage calldata message) public view returns (Client.EVM2AnyMessage memory) { + return _validatedMessage(message); + } + + function validateFeeToken(Client.EVM2AnyMessage calldata message) public payable { + _validateFeeToken(message); + } + + function publicCcipReceive(Client.Any2EVMMessage memory message) public { + _ccipReceive(message); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/IgnoreContractSize.sol b/contracts/src/v0.8/ccip/test/helpers/IgnoreContractSize.sol new file mode 100644 index 0000000000..b30124069f --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/IgnoreContractSize.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +contract IgnoreContractSize { + // test contracts are excluded from forge build --sizes by default + // --sizes exits with code 1 if any contract is over limit, which fails CI + // for helper contracts that are not explicit test contracts + // use this flag to exclude from --sizes + bool public IS_SCRIPT = true; +} diff --git a/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol b/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol new file mode 100644 index 0000000000..e572f798ad --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; + +import {Pool} from "../../libraries/Pool.sol"; +import {BurnMintTokenPool} from "../../pools/BurnMintTokenPool.sol"; + +contract MaybeRevertingBurnMintTokenPool is BurnMintTokenPool { + bytes public s_revertReason = ""; + bytes public s_sourceTokenData = ""; + + constructor( + IBurnMintERC20 token, + address[] memory allowlist, + address rmnProxy, + address router + ) BurnMintTokenPool(token, allowlist, rmnProxy, router) {} + + function setShouldRevert(bytes calldata revertReason) external { + s_revertReason = revertReason; + } + + function setSourceTokenData(bytes calldata sourceTokenData) external { + s_sourceTokenData = sourceTokenData; + } + + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + external + virtual + override + returns (Pool.LockOrBurnOutV1 memory) + { + _validateLockOrBurn(lockOrBurnIn); + + bytes memory revertReason = s_revertReason; + if (revertReason.length != 0) { + assembly { + revert(add(32, revertReason), mload(revertReason)) + } + } + + IBurnMintERC20(address(i_token)).burn(lockOrBurnIn.amount); + emit Burned(msg.sender, lockOrBurnIn.amount); + return Pool.LockOrBurnOutV1({ + destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), + destPoolData: s_sourceTokenData + }); + } + + /// @notice Reverts depending on the value of `s_revertReason` + function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + external + virtual + override + returns (Pool.ReleaseOrMintOutV1 memory) + { + _validateReleaseOrMint(releaseOrMintIn); + + bytes memory revertReason = s_revertReason; + if (revertReason.length != 0) { + assembly { + revert(add(32, revertReason), mload(revertReason)) + } + } + IBurnMintERC20(address(i_token)).mint(msg.sender, releaseOrMintIn.amount); + emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); + return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/MerkleHelper.sol b/contracts/src/v0.8/ccip/test/helpers/MerkleHelper.sol new file mode 100644 index 0000000000..ccb05681f1 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/MerkleHelper.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {MerkleMultiProof} from "../../libraries/MerkleMultiProof.sol"; + +library MerkleHelper { + /// @notice Generate a Merkle Root from a full set of leaves. When a tree is unbalanced + /// the value is brought up in the tree. For example consider (a,b,c) as leaves. This would + /// result in the following tree with d being computed from hash(a,c) and the root r from + /// hash(d,c). Notice c is not being rehashed when it is brought up in the tree, so the + /// root is NOT hash(d,hash(c)) but instead hash(d,c) == hash(hash(a,b),c). + /// r + /// / \ + /// d c + /// / \ + /// a b + function getMerkleRoot(bytes32[] memory hashedLeaves) public pure returns (bytes32) { + require(hashedLeaves.length <= 256); + while (hashedLeaves.length > 1) { + hashedLeaves = computeNextLayer(hashedLeaves); + } + return hashedLeaves[0]; + } + + /// @notice Computes a single layer of a merkle proof by hashing each pair (i, i+1) for + /// each i, i+2, i+4.. n. When an uneven number of leaves is supplied the last item + /// is simply included as the last element in the result set and not hashed. + function computeNextLayer(bytes32[] memory layer) public pure returns (bytes32[] memory) { + uint256 leavesLen = layer.length; + if (leavesLen == 1) return layer; + + unchecked { + bytes32[] memory nextLayer = new bytes32[]((leavesLen + 1) / 2); + for (uint256 i = 0; i < leavesLen; i += 2) { + if (i == leavesLen - 1) { + nextLayer[i / 2] = layer[i]; + } else { + nextLayer[i / 2] = hashPair(layer[i], layer[i + 1]); + } + } + return nextLayer; + } + } + + function hashPair(bytes32 a, bytes32 b) public pure returns (bytes32) { + return a < b ? hashInternalNode(a, b) : hashInternalNode(b, a); + } + + function hashInternalNode(bytes32 left, bytes32 right) public pure returns (bytes32 hash) { + return keccak256(abi.encode(MerkleMultiProof.INTERNAL_DOMAIN_SEPARATOR, left, right)); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/MessageHasher.sol b/contracts/src/v0.8/ccip/test/helpers/MessageHasher.sol new file mode 100644 index 0000000000..19f35df796 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/MessageHasher.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; + +/// @notice MessageHasher is a contract that utility functions to hash an Any2EVMRampMessage +/// and encode various preimages for the final hash of the message. +/// @dev This is only deployed in tests and is not part of the production contracts. +contract MessageHasher { + function hash(Internal.Any2EVMRampMessage memory message, bytes memory onRamp) public pure returns (bytes32) { + return Internal._hash(message, onRamp); + } + + function encodeTokenAmountsHashPreimage(Internal.RampTokenAmount[] memory rampTokenAmounts) + public + pure + returns (bytes memory) + { + return abi.encode(rampTokenAmounts); + } + + function encodeMetadataHashPreimage( + bytes32 any2EVMMessageHash, + uint64 sourceChainSelector, + uint64 destChainSelector, + bytes memory onRamp + ) public pure returns (bytes memory) { + return abi.encode(any2EVMMessageHash, sourceChainSelector, destChainSelector, onRamp); + } + + function encodeFixedSizeFieldsHashPreimage( + bytes32 messageId, + bytes memory sender, + address receiver, + uint64 sequenceNumber, + uint256 gasLimit, + uint64 nonce + ) public pure returns (bytes memory) { + return abi.encode(messageId, sender, receiver, sequenceNumber, gasLimit, nonce); + } + + function encodeFinalHashPreimage( + bytes32 leafDomainSeparator, + bytes32 implicitMetadataHash, + bytes32 fixedSizeFieldsHash, + bytes32 dataHash, + bytes32 tokenAmountsHash + ) public pure returns (bytes memory) { + return abi.encode(leafDomainSeparator, implicitMetadataHash, fixedSizeFieldsHash, dataHash, tokenAmountsHash); + } + + function encodeEVMExtraArgsV1(Client.EVMExtraArgsV1 memory extraArgs) public pure returns (bytes memory) { + return Client._argsToBytes(extraArgs); + } + + function encodeEVMExtraArgsV2(Client.EVMExtraArgsV2 memory extraArgs) public pure returns (bytes memory) { + return Client._argsToBytes(extraArgs); + } + + function decodeEVMExtraArgsV1(uint256 gasLimit) public pure returns (Client.EVMExtraArgsV1 memory) { + return Client.EVMExtraArgsV1(gasLimit); + } + + function decodeEVMExtraArgsV2( + uint256 gasLimit, + bool allowOutOfOrderExecution + ) public pure returns (Client.EVMExtraArgsV2 memory) { + return Client.EVMExtraArgsV2(gasLimit, allowOutOfOrderExecution); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/MessageInterceptorHelper.sol b/contracts/src/v0.8/ccip/test/helpers/MessageInterceptorHelper.sol new file mode 100644 index 0000000000..a54145da84 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/MessageInterceptorHelper.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IMessageInterceptor} from "../../interfaces/IMessageInterceptor.sol"; +import {Client} from "../../libraries/Client.sol"; + +contract MessageInterceptorHelper is IMessageInterceptor { + mapping(bytes32 messageId => bool isInvalid) internal s_invalidMessageIds; + + constructor() {} + + function setMessageIdValidationState(bytes32 messageId, bool isInvalid) external { + s_invalidMessageIds[messageId] = isInvalid; + } + + /// @inheritdoc IMessageInterceptor + function onInboundMessage(Client.Any2EVMMessage memory message) external view { + if (s_invalidMessageIds[message.messageId]) { + revert MessageValidationError(bytes("Invalid message")); + } + } + + /// @inheritdoc IMessageInterceptor + function onOutboundMessage(uint64, Client.EVM2AnyMessage calldata message) external view { + if (s_invalidMessageIds[keccak256(abi.encode(message))]) { + revert MessageValidationError(bytes("Invalid message")); + } + return; + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/MultiAggregateRateLimiterHelper.sol b/contracts/src/v0.8/ccip/test/helpers/MultiAggregateRateLimiterHelper.sol new file mode 100644 index 0000000000..d9386ca7db --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/MultiAggregateRateLimiterHelper.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {MultiAggregateRateLimiter} from "../../MultiAggregateRateLimiter.sol"; +import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; +import {Client} from "../../libraries/Client.sol"; + +contract MultiAggregateRateLimiterHelper is MultiAggregateRateLimiter { + constructor( + address priceRegistry, + address[] memory authorizedCallers + ) MultiAggregateRateLimiter(priceRegistry, authorizedCallers) {} + + function getTokenValue(Client.EVMTokenAmount memory tokenAmount) public view returns (uint256) { + return _getTokenValue(tokenAmount); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/MultiOCR3Helper.sol b/contracts/src/v0.8/ccip/test/helpers/MultiOCR3Helper.sol new file mode 100644 index 0000000000..003a5326b8 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/MultiOCR3Helper.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {MultiOCR3Base} from "../../ocr/MultiOCR3Base.sol"; + +contract MultiOCR3Helper is MultiOCR3Base { + event AfterConfigSet(uint8 ocrPluginType); + + /// @dev OCR plugin type used for transmit. + /// Defined in storage since it cannot be passed as calldata due to strict transmit checks + uint8 internal s_transmitOcrPluginType; + + function setTransmitOcrPluginType(uint8 ocrPluginType) external { + s_transmitOcrPluginType = ocrPluginType; + } + + /// @dev transmit function with signatures + function transmitWithSignatures( + bytes32[3] calldata reportContext, + bytes calldata report, + bytes32[] calldata rs, + bytes32[] calldata ss, + bytes32 rawVs + ) external { + _transmit(s_transmitOcrPluginType, reportContext, report, rs, ss, rawVs); + } + + /// @dev transmit function with no signatures + function transmitWithoutSignatures(bytes32[3] calldata reportContext, bytes calldata report) external { + bytes32[] memory emptySigs = new bytes32[](0); + _transmit(s_transmitOcrPluginType, reportContext, report, emptySigs, emptySigs, bytes32("")); + } + + function getOracle(uint8 ocrPluginType, address oracleAddress) external view returns (Oracle memory) { + return s_oracles[ocrPluginType][oracleAddress]; + } + + function typeAndVersion() public pure override returns (string memory) { + return "MultiOCR3BaseHelper 1.0.0"; + } + + function _afterOCR3ConfigSet(uint8 ocrPluginType) internal virtual override { + emit AfterConfigSet(ocrPluginType); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/MultiTokenPool.sol b/contracts/src/v0.8/ccip/test/helpers/MultiTokenPool.sol new file mode 100644 index 0000000000..0f7c312f71 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/MultiTokenPool.sol @@ -0,0 +1,420 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IPoolV1} from "../../interfaces/IPool.sol"; +import {IRMN} from "../../interfaces/IRMN.sol"; +import {IRouter} from "../../interfaces/IRouter.sol"; + +import {OwnerIsCreator} from "../../../shared/access/OwnerIsCreator.sol"; +import {Pool} from "../../libraries/Pool.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +/// @notice This contract is a proof of concept and should NOT be used in production. +abstract contract MultiTokenPool is IPoolV1, OwnerIsCreator { + using EnumerableSet for EnumerableSet.AddressSet; + using EnumerableSet for EnumerableSet.UintSet; + using RateLimiter for RateLimiter.TokenBucket; + + error CallerIsNotARampOnRouter(address caller); + error ZeroAddressNotAllowed(); + error SenderNotAllowed(address sender); + error AllowListNotEnabled(); + error NonExistentChain(uint64 remoteChainSelector); + error ChainNotAllowed(uint64 remoteChainSelector); + error CursedByRMN(); + error ChainAlreadyExists(uint64 chainSelector); + error InvalidSourcePoolAddress(bytes sourcePoolAddress); + error InvalidToken(address token); + + event Locked(address indexed sender, uint256 amount); + event Burned(address indexed sender, uint256 amount); + event Released(address indexed sender, address indexed recipient, uint256 amount); + event Minted(address indexed sender, address indexed recipient, uint256 amount); + event ChainAdded( + uint64 remoteChainSelector, + bytes remoteToken, + RateLimiter.Config outboundRateLimiterConfig, + RateLimiter.Config inboundRateLimiterConfig + ); + event ChainConfigured( + uint64 remoteChainSelector, + RateLimiter.Config outboundRateLimiterConfig, + RateLimiter.Config inboundRateLimiterConfig + ); + event ChainRemoved(uint64 remoteChainSelector); + event RemotePoolSet(uint64 indexed remoteChainSelector, bytes previousPoolAddress, bytes remotePoolAddress); + event AllowListAdd(address sender); + event AllowListRemove(address sender); + event RouterUpdated(address oldRouter, address newRouter); + + struct ChainUpdate { + uint64 remoteChainSelector; // ──╮ Remote chain selector + bool allowed; // ────────────────╯ Whether the chain is allowed + bytes remotePoolAddress; // Address of the remote pool, ABI encoded in the case of a remove EVM chain. + bytes remoteTokenAddress; // Address of the remote token, ABI encoded in the case of a remote EVM chain. + RateLimiter.Config outboundRateLimiterConfig; // Outbound rate limited config, meaning the rate limits for all of the onRamps for the given chain + RateLimiter.Config inboundRateLimiterConfig; // Inbound rate limited config, meaning the rate limits for all of the offRamps for the given chain + } + + struct RemoteChainConfig { + RateLimiter.TokenBucket outboundRateLimiterConfig; // Outbound rate limited config, meaning the rate limits for all of the onRamps for the given chain + RateLimiter.TokenBucket inboundRateLimiterConfig; // Inbound rate limited config, meaning the rate limits for all of the offRamps for the given chain + bytes remotePoolAddress; // Address of the remote pool, ABI encoded in the case of a remote EVM chain. + bytes remoteTokenAddress; // Address of the remote token, ABI encoded in the case of a remote EVM chain. + } + + /// @dev The IERC20 token that this pool supports + EnumerableSet.AddressSet internal s_tokens; + /// @dev The address of the RMN proxy + address internal immutable i_rmnProxy; + /// @dev The immutable flag that indicates if the pool is access-controlled. + bool internal immutable i_allowlistEnabled; + /// @dev A set of addresses allowed to trigger lockOrBurn as original senders. + /// Only takes effect if i_allowlistEnabled is true. + /// This can be used to ensure only token-issuer specified addresses can + /// move tokens. + EnumerableSet.AddressSet internal s_allowList; + /// @dev The address of the router + IRouter internal s_router; + /// @dev A set of allowed chain selectors. We want the allowlist to be enumerable to + /// be able to quickly determine (without parsing logs) who can access the pool. + /// @dev The chain selectors are in uin256 format because of the EnumerableSet implementation. + EnumerableSet.UintSet internal s_remoteChainSelectors; + mapping(address token => mapping(uint64 remoteChainSelector => RemoteChainConfig)) internal s_remoteChainConfigs; + + constructor(IERC20[] memory token, address[] memory allowlist, address rmnProxy, address router) { + if (router == address(0) || rmnProxy == address(0)) revert ZeroAddressNotAllowed(); + for (uint256 i = 0; i < token.length; ++i) { + s_tokens.add(address(token[i])); + } + i_rmnProxy = rmnProxy; + s_router = IRouter(router); + + // Pool can be set as permissioned or permissionless at deployment time only to save hot-path gas. + i_allowlistEnabled = allowlist.length > 0; + if (i_allowlistEnabled) { + _applyAllowListUpdates(new address[](0), allowlist); + } + } + + /// @notice Get RMN proxy address + /// @return rmnProxy Address of RMN proxy + function getRmnProxy() public view returns (address rmnProxy) { + return i_rmnProxy; + } + + /// @inheritdoc IPoolV1 + function isSupportedToken(address token) public view virtual returns (bool) { + return s_tokens.contains(token); + } + + /// @notice Gets the IERC20 token that this pool can lock or burn. + /// @return tokens The IERC20 token representation. + function getTokens() public view returns (IERC20[] memory tokens) { + tokens = new IERC20[](s_tokens.length()); + for (uint256 i = 0; i < s_tokens.length(); ++i) { + tokens[i] = IERC20(s_tokens.at(i)); + } + return tokens; + } + + /// @notice Gets the pool's Router + /// @return router The pool's Router + function getRouter() public view returns (address router) { + return address(s_router); + } + + /// @notice Sets the pool's Router + /// @param newRouter The new Router + function setRouter(address newRouter) public onlyOwner { + if (newRouter == address(0)) revert ZeroAddressNotAllowed(); + address oldRouter = address(s_router); + s_router = IRouter(newRouter); + + emit RouterUpdated(oldRouter, newRouter); + } + + /// @notice Signals which version of the pool interface is supported + function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) { + return interfaceId == Pool.CCIP_POOL_V1 || interfaceId == type(IPoolV1).interfaceId + || interfaceId == type(IERC165).interfaceId; + } + + // ================================================================ + // │ Validation │ + // ================================================================ + + /// @notice Validates the lock or burn input for correctness on + /// - token to be locked or burned + /// - RMN curse status + /// - allowlist status + /// - if the sender is a valid onRamp + /// - rate limit status + /// @param lockOrBurnIn The input to validate. + /// @dev This function should always be called before executing a lock or burn. Not doing so would allow + /// for various exploits. + function _validateLockOrBurn(Pool.LockOrBurnInV1 memory lockOrBurnIn) internal { + if (!isSupportedToken(lockOrBurnIn.localToken)) revert InvalidToken(lockOrBurnIn.localToken); + if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(lockOrBurnIn.remoteChainSelector)))) revert CursedByRMN(); + _checkAllowList(lockOrBurnIn.originalSender); + + _onlyOnRamp(lockOrBurnIn.remoteChainSelector); + _consumeOutboundRateLimit(lockOrBurnIn.localToken, lockOrBurnIn.remoteChainSelector, lockOrBurnIn.amount); + } + + /// @notice Validates the release or mint input for correctness on + /// - token to be released or minted + /// - RMN curse status + /// - if the sender is a valid offRamp + /// - if the source pool is valid + /// - rate limit status + /// @param releaseOrMintIn The input to validate. + /// @dev This function should always be called before executing a lock or burn. Not doing so would allow + /// for various exploits. + function _validateReleaseOrMint(Pool.ReleaseOrMintInV1 memory releaseOrMintIn) internal { + if (!isSupportedToken(releaseOrMintIn.localToken)) revert InvalidToken(releaseOrMintIn.localToken); + if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(releaseOrMintIn.remoteChainSelector)))) revert CursedByRMN(); + _onlyOffRamp(releaseOrMintIn.remoteChainSelector); + + // Validates that the source pool address is configured on this pool. + bytes memory configuredRemotePool = getRemotePool(releaseOrMintIn.localToken, releaseOrMintIn.remoteChainSelector); + if ( + configuredRemotePool.length == 0 + || keccak256(releaseOrMintIn.sourcePoolAddress) != keccak256(configuredRemotePool) + ) { + revert InvalidSourcePoolAddress(releaseOrMintIn.sourcePoolAddress); + } + _consumeInboundRateLimit(releaseOrMintIn.localToken, releaseOrMintIn.remoteChainSelector, releaseOrMintIn.amount); + } + + // ================================================================ + // │ Chain permissions │ + // ================================================================ + + /// @notice Gets the pool address on the remote chain. + /// @param remoteChainSelector Remote chain selector. + /// @dev To support non-evm chains, this value is encoded into bytes + function getRemotePool(address token, uint64 remoteChainSelector) public view returns (bytes memory) { + return s_remoteChainConfigs[token][remoteChainSelector].remotePoolAddress; + } + + /// @notice Gets the token address on the remote chain. + /// @param remoteChainSelector Remote chain selector. + /// @dev To support non-evm chains, this value is encoded into bytes + function getRemoteToken(address token, uint64 remoteChainSelector) public view returns (bytes memory) { + return s_remoteChainConfigs[token][remoteChainSelector].remoteTokenAddress; + } + + /// @notice Sets the remote pool address for a given chain selector. + /// @param remoteChainSelector The remote chain selector for which the remote pool address is being set. + /// @param remotePoolAddress The address of the remote pool. + function setRemotePool( + address token, + uint64 remoteChainSelector, + bytes calldata remotePoolAddress + ) external onlyOwner { + if (!isSupportedChain(remoteChainSelector)) revert NonExistentChain(remoteChainSelector); + + bytes memory prevAddress = s_remoteChainConfigs[token][remoteChainSelector].remotePoolAddress; + s_remoteChainConfigs[token][remoteChainSelector].remotePoolAddress = remotePoolAddress; + + emit RemotePoolSet(remoteChainSelector, prevAddress, remotePoolAddress); + } + + /// @inheritdoc IPoolV1 + function isSupportedChain(uint64 remoteChainSelector) public view returns (bool) { + return s_remoteChainSelectors.contains(remoteChainSelector); + } + + /// @notice Get list of allowed chains + /// @return list of chains. + function getSupportedChains() public view returns (uint64[] memory) { + uint256[] memory uint256ChainSelectors = s_remoteChainSelectors.values(); + uint64[] memory chainSelectors = new uint64[](uint256ChainSelectors.length); + for (uint256 i = 0; i < uint256ChainSelectors.length; ++i) { + chainSelectors[i] = uint64(uint256ChainSelectors[i]); + } + + return chainSelectors; + } + + /// @notice Sets the permissions for a list of chains selectors. Actual senders for these chains + /// need to be allowed on the Router to interact with this pool. + /// @dev Only callable by the owner + /// @param chains A list of chains and their new permission status & rate limits. Rate limits + /// are only used when the chain is being added through `allowed` being true. + function applyChainUpdates(address token, ChainUpdate[] calldata chains) external virtual onlyOwner { + for (uint256 i = 0; i < chains.length; ++i) { + ChainUpdate memory update = chains[i]; + RateLimiter._validateTokenBucketConfig(update.outboundRateLimiterConfig, !update.allowed); + RateLimiter._validateTokenBucketConfig(update.inboundRateLimiterConfig, !update.allowed); + + if (update.allowed) { + // If the chain already exists, revert + if (!s_remoteChainSelectors.add(update.remoteChainSelector)) { + revert ChainAlreadyExists(update.remoteChainSelector); + } + + if (update.remotePoolAddress.length == 0 || update.remoteTokenAddress.length == 0) { + revert ZeroAddressNotAllowed(); + } + + s_remoteChainConfigs[token][update.remoteChainSelector] = RemoteChainConfig({ + outboundRateLimiterConfig: RateLimiter.TokenBucket({ + rate: update.outboundRateLimiterConfig.rate, + capacity: update.outboundRateLimiterConfig.capacity, + tokens: update.outboundRateLimiterConfig.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: update.outboundRateLimiterConfig.isEnabled + }), + inboundRateLimiterConfig: RateLimiter.TokenBucket({ + rate: update.inboundRateLimiterConfig.rate, + capacity: update.inboundRateLimiterConfig.capacity, + tokens: update.inboundRateLimiterConfig.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: update.inboundRateLimiterConfig.isEnabled + }), + remotePoolAddress: update.remotePoolAddress, + remoteTokenAddress: update.remoteTokenAddress + }); + + emit ChainAdded( + update.remoteChainSelector, + update.remoteTokenAddress, + update.outboundRateLimiterConfig, + update.inboundRateLimiterConfig + ); + } else { + // If the chain doesn't exist, revert + if (!s_remoteChainSelectors.remove(update.remoteChainSelector)) { + revert NonExistentChain(update.remoteChainSelector); + } + + delete s_remoteChainConfigs[token][update.remoteChainSelector]; + + emit ChainRemoved(update.remoteChainSelector); + } + } + } + + // ================================================================ + // │ Rate limiting │ + // ================================================================ + + /// @notice Consumes outbound rate limiting capacity in this pool + function _consumeOutboundRateLimit(address token, uint64 remoteChainSelector, uint256 amount) internal { + s_remoteChainConfigs[token][remoteChainSelector].outboundRateLimiterConfig._consume(amount, token); + } + + /// @notice Consumes inbound rate limiting capacity in this pool + function _consumeInboundRateLimit(address token, uint64 remoteChainSelector, uint256 amount) internal { + s_remoteChainConfigs[token][remoteChainSelector].inboundRateLimiterConfig._consume(amount, token); + } + + /// @notice Gets the token bucket with its values for the block it was requested at. + /// @return The token bucket. + function getCurrentOutboundRateLimiterState( + address token, + uint64 remoteChainSelector + ) external view returns (RateLimiter.TokenBucket memory) { + return s_remoteChainConfigs[token][remoteChainSelector].outboundRateLimiterConfig._currentTokenBucketState(); + } + + /// @notice Gets the token bucket with its values for the block it was requested at. + /// @return The token bucket. + function getCurrentInboundRateLimiterState( + address token, + uint64 remoteChainSelector + ) external view returns (RateLimiter.TokenBucket memory) { + return s_remoteChainConfigs[token][remoteChainSelector].inboundRateLimiterConfig._currentTokenBucketState(); + } + + /// @notice Sets the chain rate limiter config. + /// @param remoteChainSelector The remote chain selector for which the rate limits apply. + /// @param outboundConfig The new outbound rate limiter config, meaning the onRamp rate limits for the given chain. + /// @param inboundConfig The new inbound rate limiter config, meaning the offRamp rate limits for the given chain. + function setChainRateLimiterConfig( + address token, + uint64 remoteChainSelector, + RateLimiter.Config memory outboundConfig, + RateLimiter.Config memory inboundConfig + ) internal { + if (!isSupportedChain(remoteChainSelector)) revert NonExistentChain(remoteChainSelector); + RateLimiter._validateTokenBucketConfig(outboundConfig, false); + s_remoteChainConfigs[token][remoteChainSelector].outboundRateLimiterConfig._setTokenBucketConfig(outboundConfig); + RateLimiter._validateTokenBucketConfig(inboundConfig, false); + s_remoteChainConfigs[token][remoteChainSelector].inboundRateLimiterConfig._setTokenBucketConfig(inboundConfig); + emit ChainConfigured(remoteChainSelector, outboundConfig, inboundConfig); + } + + // ================================================================ + // │ Access │ + // ================================================================ + + /// @notice Checks whether remote chain selector is configured on this contract, and if the msg.sender + /// is a permissioned onRamp for the given chain on the Router. + function _onlyOnRamp(uint64 remoteChainSelector) internal view { + if (!isSupportedChain(remoteChainSelector)) revert ChainNotAllowed(remoteChainSelector); + if (!(msg.sender == s_router.getOnRamp(remoteChainSelector))) revert CallerIsNotARampOnRouter(msg.sender); + } + + /// @notice Checks whether remote chain selector is configured on this contract, and if the msg.sender + /// is a permissioned offRamp for the given chain on the Router. + function _onlyOffRamp(uint64 remoteChainSelector) internal view { + if (!isSupportedChain(remoteChainSelector)) revert ChainNotAllowed(remoteChainSelector); + if (!s_router.isOffRamp(remoteChainSelector, msg.sender)) revert CallerIsNotARampOnRouter(msg.sender); + } + + // ================================================================ + // │ Allowlist │ + // ================================================================ + + function _checkAllowList(address sender) internal view { + if (i_allowlistEnabled && !s_allowList.contains(sender)) revert SenderNotAllowed(sender); + } + + /// @notice Gets whether the allowList functionality is enabled. + /// @return true is enabled, false if not. + function getAllowListEnabled() external view returns (bool) { + return i_allowlistEnabled; + } + + /// @notice Gets the allowed addresses. + /// @return The allowed addresses. + function getAllowList() external view returns (address[] memory) { + return s_allowList.values(); + } + + /// @notice Apply updates to the allow list. + /// @param removes The addresses to be removed. + /// @param adds The addresses to be added. + /// @dev allowListing will be removed before public launch + function applyAllowListUpdates(address[] calldata removes, address[] calldata adds) external onlyOwner { + _applyAllowListUpdates(removes, adds); + } + + /// @notice Internal version of applyAllowListUpdates to allow for reuse in the constructor. + function _applyAllowListUpdates(address[] memory removes, address[] memory adds) internal { + if (!i_allowlistEnabled) revert AllowListNotEnabled(); + + for (uint256 i = 0; i < removes.length; ++i) { + address toRemove = removes[i]; + if (s_allowList.remove(toRemove)) { + emit AllowListRemove(toRemove); + } + } + for (uint256 i = 0; i < adds.length; ++i) { + address toAdd = adds[i]; + if (toAdd == address(0)) { + continue; + } + if (s_allowList.add(toAdd)) { + emit AllowListAdd(toAdd); + } + } + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/OCR2Helper.sol b/contracts/src/v0.8/ccip/test/helpers/OCR2Helper.sol new file mode 100644 index 0000000000..cb66352ff6 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/OCR2Helper.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {OCR2Base} from "../../ocr/OCR2Base.sol"; + +contract OCR2Helper is OCR2Base(false) { + function configDigestFromConfigData( + uint256 chainSelector, + address contractAddress, + uint64 configCount, + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) public pure returns (bytes32) { + return _configDigestFromConfigData( + chainSelector, + contractAddress, + configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + } + + function _report(bytes calldata report, uint40 epochAndRound) internal override {} + + function typeAndVersion() public pure override returns (string memory) { + return "OCR2BaseHelper 1.0.0"; + } + + function _beforeSetConfig(bytes memory _onchainConfig) internal override {} +} diff --git a/contracts/src/v0.8/ccip/test/helpers/OCR2NoChecksHelper.sol b/contracts/src/v0.8/ccip/test/helpers/OCR2NoChecksHelper.sol new file mode 100644 index 0000000000..a1ececa326 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/OCR2NoChecksHelper.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {OCR2BaseNoChecks} from "../../ocr/OCR2BaseNoChecks.sol"; + +contract OCR2NoChecksHelper is OCR2BaseNoChecks { + function configDigestFromConfigData( + uint256 chainSelector, + address contractAddress, + uint64 configCount, + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) public pure returns (bytes32) { + return _configDigestFromConfigData( + chainSelector, + contractAddress, + configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + } + + function _report(bytes calldata report) internal override {} + + function typeAndVersion() public pure override returns (string memory) { + return "OCR2BaseHelper 1.0.0"; + } + + function _beforeSetConfig(bytes memory _onchainConfig) internal override {} +} diff --git a/contracts/src/v0.8/ccip/test/helpers/PriceRegistryHelper.sol b/contracts/src/v0.8/ccip/test/helpers/PriceRegistryHelper.sol new file mode 100644 index 0000000000..8524df12cc --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/PriceRegistryHelper.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {PriceRegistry} from "../../PriceRegistry.sol"; +import {Client} from "../../libraries/Client.sol"; + +contract PriceRegistryHelper is PriceRegistry { + constructor( + StaticConfig memory staticConfig, + address[] memory priceUpdaters, + address[] memory feeTokens, + TokenPriceFeedUpdate[] memory tokenPriceFeeds, + TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs, + PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs, + DestChainConfigArgs[] memory destChainConfigArgs + ) + PriceRegistry( + staticConfig, + priceUpdaters, + feeTokens, + tokenPriceFeeds, + tokenTransferFeeConfigArgs, + premiumMultiplierWeiPerEthArgs, + destChainConfigArgs + ) + {} + + function getDataAvailabilityCost( + uint64 destChainSelector, + uint112 dataAvailabilityGasPrice, + uint256 messageDataLength, + uint256 numberOfTokens, + uint32 tokenTransferBytesOverhead + ) external view returns (uint256) { + return _getDataAvailabilityCost( + s_destChainConfigs[destChainSelector], + dataAvailabilityGasPrice, + messageDataLength, + numberOfTokens, + tokenTransferBytesOverhead + ); + } + + function getTokenTransferCost( + uint64 destChainSelector, + address feeToken, + uint224 feeTokenPrice, + Client.EVMTokenAmount[] calldata tokenAmounts + ) external view returns (uint256, uint32, uint32) { + return _getTokenTransferCost( + s_destChainConfigs[destChainSelector], destChainSelector, feeToken, feeTokenPrice, tokenAmounts + ); + } + + function parseEVMExtraArgsFromBytes( + bytes calldata extraArgs, + uint64 destChainSelector + ) external view returns (Client.EVMExtraArgsV2 memory) { + return _parseEVMExtraArgsFromBytes(extraArgs, s_destChainConfigs[destChainSelector]); + } + + function parseEVMExtraArgsFromBytes( + bytes calldata extraArgs, + DestChainConfig memory destChainConfig + ) external pure returns (Client.EVMExtraArgsV2 memory) { + return _parseEVMExtraArgsFromBytes(extraArgs, destChainConfig); + } + + function validateDestFamilyAddress(bytes4 chainFamilySelector, bytes memory destAddress) external pure { + _validateDestFamilyAddress(chainFamilySelector, destAddress); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/RateLimiterHelper.sol b/contracts/src/v0.8/ccip/test/helpers/RateLimiterHelper.sol new file mode 100644 index 0000000000..8fb96a0c1c --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/RateLimiterHelper.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {RateLimiter} from "../../libraries/RateLimiter.sol"; + +contract RateLimiterHelper { + using RateLimiter for RateLimiter.TokenBucket; + + RateLimiter.TokenBucket internal s_rateLimiter; + + constructor(RateLimiter.Config memory config) { + s_rateLimiter = RateLimiter.TokenBucket({ + rate: config.rate, + capacity: config.capacity, + tokens: config.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: config.isEnabled + }); + } + + function consume(uint256 requestTokens, address tokenAddress) external { + s_rateLimiter._consume(requestTokens, tokenAddress); + } + + function currentTokenBucketState() external view returns (RateLimiter.TokenBucket memory) { + return s_rateLimiter._currentTokenBucketState(); + } + + function setTokenBucketConfig(RateLimiter.Config memory config) external { + s_rateLimiter._setTokenBucketConfig(config); + } + + function getRateLimiter() external view returns (RateLimiter.TokenBucket memory) { + return s_rateLimiter; + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/ReportCodec.sol b/contracts/src/v0.8/ccip/test/helpers/ReportCodec.sol new file mode 100644 index 0000000000..ca53d512c0 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/ReportCodec.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Internal} from "../../libraries/Internal.sol"; +import {EVM2EVMMultiOffRamp} from "../../offRamp/EVM2EVMMultiOffRamp.sol"; + +contract ReportCodec { + event ExecuteReportDecoded(Internal.ExecutionReportSingleChain[] report); + event CommitReportDecoded(EVM2EVMMultiOffRamp.CommitReport report); + + function decodeExecuteReport(bytes memory report) public pure returns (Internal.ExecutionReportSingleChain[] memory) { + return abi.decode(report, (Internal.ExecutionReportSingleChain[])); + } + + function decodeCommitReport(bytes memory report) public pure returns (EVM2EVMMultiOffRamp.CommitReport memory) { + return abi.decode(report, (EVM2EVMMultiOffRamp.CommitReport)); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/TokenPoolHelper.sol b/contracts/src/v0.8/ccip/test/helpers/TokenPoolHelper.sol new file mode 100644 index 0000000000..c57bfa3311 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/TokenPoolHelper.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {Pool} from "../../libraries/Pool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract TokenPoolHelper is TokenPool { + constructor( + IERC20 token, + address[] memory allowlist, + address rmnProxy, + address router + ) TokenPool(token, allowlist, rmnProxy, router) {} + + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + external + view + override + returns (Pool.LockOrBurnOutV1 memory) + { + return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); + } + + function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + external + pure + override + returns (Pool.ReleaseOrMintOutV1 memory) + { + return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + } + + function onlyOnRampModifier(uint64 remoteChainSelector) external view { + _onlyOnRamp(remoteChainSelector); + } + + function onlyOffRampModifier(uint64 remoteChainSelector) external view { + _onlyOffRamp(remoteChainSelector); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/USDCTokenPoolHelper.sol b/contracts/src/v0.8/ccip/test/helpers/USDCTokenPoolHelper.sol new file mode 100644 index 0000000000..7a3400588a --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/USDCTokenPoolHelper.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; + +import {ITokenMessenger} from "../../pools/USDC/ITokenMessenger.sol"; +import {USDCTokenPool} from "../../pools/USDC/USDCTokenPool.sol"; + +contract USDCTokenPoolHelper is USDCTokenPool { + constructor( + ITokenMessenger tokenMessenger, + IBurnMintERC20 token, + address[] memory allowlist, + address rmnProxy, + address router + ) USDCTokenPool(tokenMessenger, token, allowlist, rmnProxy, router) {} + + function validateMessage(bytes memory usdcMessage, SourceTokenDataPayload memory sourceTokenData) external view { + return _validateMessage(usdcMessage, sourceTokenData); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/receivers/ConformingReceiver.sol b/contracts/src/v0.8/ccip/test/helpers/receivers/ConformingReceiver.sol new file mode 100644 index 0000000000..159cd7a851 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/receivers/ConformingReceiver.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {CCIPReceiver} from "../../../applications/CCIPReceiver.sol"; +import {Client} from "../../../libraries/Client.sol"; + +contract ConformingReceiver is CCIPReceiver { + event MessageReceived(); + + constructor(address router, address feeToken) CCIPReceiver(router) {} + + function _ccipReceive(Client.Any2EVMMessage memory) internal virtual override { + emit MessageReceived(); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol b/contracts/src/v0.8/ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol new file mode 100644 index 0000000000..dd65f202df --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IAny2EVMMessageReceiver} from "../../../interfaces/IAny2EVMMessageReceiver.sol"; +import {Client} from "../../../libraries/Client.sol"; + +import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; + +contract MaybeRevertMessageReceiver is IAny2EVMMessageReceiver, IERC165 { + error ReceiveRevert(); + error CustomError(bytes err); + + event ValueReceived(uint256 amount); + event MessageReceived(); + + address private s_manager; + bool public s_toRevert; + bytes private s_err; + + constructor(bool toRevert) { + s_manager = msg.sender; + s_toRevert = toRevert; + } + + function setRevert(bool toRevert) external { + s_toRevert = toRevert; + } + + function setErr(bytes memory err) external { + s_err = err; + } + + /// @notice IERC165 supports an interfaceId + /// @param interfaceId The interfaceId to check + /// @return true if the interfaceId is supported + function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { + return interfaceId == type(IAny2EVMMessageReceiver).interfaceId || interfaceId == type(IERC165).interfaceId; + } + + function ccipReceive(Client.Any2EVMMessage calldata) external override { + if (s_toRevert) { + revert CustomError(s_err); + } + emit MessageReceived(); + } + + receive() external payable { + if (s_toRevert) { + revert ReceiveRevert(); + } + + emit ValueReceived(msg.value); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/receivers/MaybeRevertMessageReceiverNo165.sol b/contracts/src/v0.8/ccip/test/helpers/receivers/MaybeRevertMessageReceiverNo165.sol new file mode 100644 index 0000000000..4f56394c4e --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/receivers/MaybeRevertMessageReceiverNo165.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import "../../../interfaces/IAny2EVMMessageReceiver.sol"; + +contract MaybeRevertMessageReceiverNo165 is IAny2EVMMessageReceiver { + address private s_manager; + bool public s_toRevert; + + event MessageReceived(); + + constructor(bool toRevert) { + s_manager = msg.sender; + s_toRevert = toRevert; + } + + function setRevert(bool toRevert) external { + s_toRevert = toRevert; + } + + function ccipReceive(Client.Any2EVMMessage calldata) external override { + if (s_toRevert) { + revert(); + } + emit MessageReceived(); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol b/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol new file mode 100644 index 0000000000..ae8759099c --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {CCIPReceiver} from "../../../applications/CCIPReceiver.sol"; +import {Client} from "../../../libraries/Client.sol"; +import {Internal} from "../../../libraries/Internal.sol"; +import {EVM2EVMOffRamp} from "../../../offRamp/EVM2EVMOffRamp.sol"; + +contract ReentrancyAbuser is CCIPReceiver { + event ReentrancySucceeded(); + + bool internal s_ReentrancyDone = false; + Internal.ExecutionReport internal s_payload; + EVM2EVMOffRamp internal s_offRamp; + + constructor(address router, EVM2EVMOffRamp offRamp) CCIPReceiver(router) { + s_offRamp = offRamp; + } + + function setPayload(Internal.ExecutionReport calldata payload) public { + s_payload = payload; + } + + function _ccipReceive(Client.Any2EVMMessage memory) internal override { + // Use original message gas limits in manual execution + uint256 numMsgs = s_payload.messages.length; + uint256[] memory gasOverrides = new uint256[](numMsgs); + for (uint256 i = 0; i < numMsgs; ++i) { + gasOverrides[i] = 0; + } + + if (!s_ReentrancyDone) { + // Could do more rounds but a PoC one is enough + s_ReentrancyDone = true; + s_offRamp.manuallyExecute(s_payload, gasOverrides); + } else { + emit ReentrancySucceeded(); + } + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuserMultiRamp.sol b/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuserMultiRamp.sol new file mode 100644 index 0000000000..c9e7d7e8ad --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuserMultiRamp.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.19; + +import {CCIPReceiver} from "../../../applications/CCIPReceiver.sol"; +import {Client} from "../../../libraries/Client.sol"; +import {Internal} from "../../../libraries/Internal.sol"; +import {EVM2EVMMultiOffRamp} from "../../../offRamp/EVM2EVMMultiOffRamp.sol"; + +contract ReentrancyAbuserMultiRamp is CCIPReceiver { + event ReentrancySucceeded(); + + bool internal s_ReentrancyDone = false; + Internal.ExecutionReportSingleChain internal s_payload; + EVM2EVMMultiOffRamp internal s_offRamp; + + constructor(address router, EVM2EVMMultiOffRamp offRamp) CCIPReceiver(router) { + s_offRamp = offRamp; + } + + function setPayload(Internal.ExecutionReportSingleChain calldata payload) public { + s_payload = payload; + } + + function _ccipReceive(Client.Any2EVMMessage memory) internal override { + // Use original message gas limits in manual execution + uint256 numMsgs = s_payload.messages.length; + uint256[][] memory gasOverrides = new uint256[][](1); + gasOverrides[0] = new uint256[](numMsgs); + for (uint256 i = 0; i < numMsgs; ++i) { + gasOverrides[0][i] = 0; + } + + Internal.ExecutionReportSingleChain[] memory batchPayload = new Internal.ExecutionReportSingleChain[](1); + batchPayload[0] = s_payload; + + if (!s_ReentrancyDone) { + // Could do more rounds but a PoC one is enough + s_ReentrancyDone = true; + s_offRamp.manuallyExecute(batchPayload, gasOverrides); + } else { + emit ReentrancySucceeded(); + } + } +} diff --git a/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_2.sol b/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_2.sol new file mode 100644 index 0000000000..2e7878730e --- /dev/null +++ b/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_2.sol @@ -0,0 +1,353 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; +import {IPoolPriorTo1_5} from "../../interfaces/IPoolPriorTo1_5.sol"; +import {IRMN} from "../../interfaces/IRMN.sol"; + +import {OwnerIsCreator} from "../../../shared/access/OwnerIsCreator.sol"; +import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +/// @notice Base abstract class with common functions for all token pools. +/// A token pool serves as isolated place for holding tokens and token specific logic +/// that may execute as tokens move across the bridge. +abstract contract TokenPool1_2 is IPoolPriorTo1_5, OwnerIsCreator, IERC165 { + using EnumerableSet for EnumerableSet.AddressSet; + using RateLimiter for RateLimiter.TokenBucket; + + error PermissionsError(); + error ZeroAddressNotAllowed(); + error SenderNotAllowed(address sender); + error AllowListNotEnabled(); + error NonExistentRamp(address ramp); + error BadARMSignal(); + error RampAlreadyExists(address ramp); + + event Locked(address indexed sender, uint256 amount); + event Burned(address indexed sender, uint256 amount); + event Released(address indexed sender, address indexed recipient, uint256 amount); + event Minted(address indexed sender, address indexed recipient, uint256 amount); + event OnRampAdded(address onRamp, RateLimiter.Config rateLimiterConfig); + event OnRampConfigured(address onRamp, RateLimiter.Config rateLimiterConfig); + event OnRampRemoved(address onRamp); + event OffRampAdded(address offRamp, RateLimiter.Config rateLimiterConfig); + event OffRampConfigured(address offRamp, RateLimiter.Config rateLimiterConfig); + event OffRampRemoved(address offRamp); + event AllowListAdd(address sender); + event AllowListRemove(address sender); + + struct RampUpdate { + address ramp; + bool allowed; + RateLimiter.Config rateLimiterConfig; + } + + /// @dev The bridgeable token that is managed by this pool. + IERC20 internal immutable i_token; + /// @dev The address of the arm proxy + address internal immutable i_armProxy; + /// @dev The immutable flag that indicates if the pool is access-controlled. + bool internal immutable i_allowlistEnabled; + /// @dev A set of addresses allowed to trigger lockOrBurn as original senders. + /// Only takes effect if i_allowlistEnabled is true. + /// This can be used to ensure only token-issuer specified addresses can + /// move tokens. + EnumerableSet.AddressSet internal s_allowList; + + /// @dev A set of allowed onRamps. We want the whitelist to be enumerable to + /// be able to quickly determine (without parsing logs) who can access the pool. + EnumerableSet.AddressSet internal s_onRamps; + /// @dev Inbound rate limits. This allows per destination chain + /// token issuer specified rate limiting (e.g. issuers may trust chains to varying + /// degrees and prefer different limits) + mapping(address => RateLimiter.TokenBucket) internal s_onRampRateLimits; + /// @dev A set of allowed offRamps. + EnumerableSet.AddressSet internal s_offRamps; + /// @dev Outbound rate limits. Corresponds to the inbound rate limit for the pool + /// on the remote chain. + mapping(address => RateLimiter.TokenBucket) internal s_offRampRateLimits; + + constructor(IERC20 token, address[] memory allowlist, address armProxy) { + if (address(token) == address(0)) revert ZeroAddressNotAllowed(); + i_token = token; + i_armProxy = armProxy; + + // Pool can be set as permissioned or permissionless at deployment time only to save hot-path gas. + i_allowlistEnabled = allowlist.length > 0; + if (i_allowlistEnabled) { + _applyAllowListUpdates(new address[](0), allowlist); + } + } + + /// @notice Get ARM proxy address + /// @return armProxy Address of arm proxy + function getArmProxy() public view returns (address armProxy) { + return i_armProxy; + } + + /// @inheritdoc IPoolPriorTo1_5 + function getToken() public view override returns (IERC20 token) { + return i_token; + } + + /// @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) { + return interfaceId == type(IPoolPriorTo1_5).interfaceId || interfaceId == type(IERC165).interfaceId; + } + + // ================================================================ + // │ Ramp permissions │ + // ================================================================ + + /// @notice Checks whether something is a permissioned onRamp on this contract. + /// @return true if the given address is a permissioned onRamp. + function isOnRamp(address onRamp) public view returns (bool) { + return s_onRamps.contains(onRamp); + } + + /// @notice Checks whether something is a permissioned offRamp on this contract. + /// @return true if the given address is a permissioned offRamp. + function isOffRamp(address offRamp) public view returns (bool) { + return s_offRamps.contains(offRamp); + } + + /// @notice Get onRamp whitelist + /// @return list of onRamps. + function getOnRamps() public view returns (address[] memory) { + return s_onRamps.values(); + } + + /// @notice Get offRamp whitelist + /// @return list of offramps + function getOffRamps() public view returns (address[] memory) { + return s_offRamps.values(); + } + + /// @notice Sets permissions for all on and offRamps. + /// @dev Only callable by the owner + /// @param onRamps A list of onRamps and their new permission status/rate limits + /// @param offRamps A list of offRamps and their new permission status/rate limits + function applyRampUpdates(RampUpdate[] calldata onRamps, RampUpdate[] calldata offRamps) external virtual onlyOwner { + _applyRampUpdates(onRamps, offRamps); + } + + function _applyRampUpdates(RampUpdate[] calldata onRamps, RampUpdate[] calldata offRamps) internal onlyOwner { + for (uint256 i = 0; i < onRamps.length; ++i) { + RampUpdate memory update = onRamps[i]; + if (update.allowed) { + if (s_onRamps.add(update.ramp)) { + s_onRampRateLimits[update.ramp] = RateLimiter.TokenBucket({ + rate: update.rateLimiterConfig.rate, + capacity: update.rateLimiterConfig.capacity, + tokens: update.rateLimiterConfig.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: update.rateLimiterConfig.isEnabled + }); + emit OnRampAdded(update.ramp, update.rateLimiterConfig); + } else { + revert RampAlreadyExists(update.ramp); + } + } else { + if (s_onRamps.remove(update.ramp)) { + delete s_onRampRateLimits[update.ramp]; + emit OnRampRemoved(update.ramp); + } else { + // Cannot remove a non-existent onRamp. + revert NonExistentRamp(update.ramp); + } + } + } + + for (uint256 i = 0; i < offRamps.length; ++i) { + RampUpdate memory update = offRamps[i]; + if (update.allowed) { + if (s_offRamps.add(update.ramp)) { + s_offRampRateLimits[update.ramp] = RateLimiter.TokenBucket({ + rate: update.rateLimiterConfig.rate, + capacity: update.rateLimiterConfig.capacity, + tokens: update.rateLimiterConfig.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: update.rateLimiterConfig.isEnabled + }); + emit OffRampAdded(update.ramp, update.rateLimiterConfig); + } else { + revert RampAlreadyExists(update.ramp); + } + } else { + if (s_offRamps.remove(update.ramp)) { + delete s_offRampRateLimits[update.ramp]; + emit OffRampRemoved(update.ramp); + } else { + // Cannot remove a non-existent offRamp. + revert NonExistentRamp(update.ramp); + } + } + } + } + + // ================================================================ + // │ Rate limiting │ + // ================================================================ + + /// @notice Consumes outbound rate limiting capacity in this pool + function _consumeOnRampRateLimit(uint256 amount) internal { + s_onRampRateLimits[msg.sender]._consume(amount, address(i_token)); + } + + /// @notice Consumes inbound rate limiting capacity in this pool + function _consumeOffRampRateLimit(uint256 amount) internal { + s_offRampRateLimits[msg.sender]._consume(amount, address(i_token)); + } + + /// @notice Gets the token bucket with its values for the block it was requested at. + /// @return The token bucket. + function currentOnRampRateLimiterState(address onRamp) external view returns (RateLimiter.TokenBucket memory) { + return s_onRampRateLimits[onRamp]._currentTokenBucketState(); + } + + /// @notice Gets the token bucket with its values for the block it was requested at. + /// @return The token bucket. + function currentOffRampRateLimiterState(address offRamp) external view returns (RateLimiter.TokenBucket memory) { + return s_offRampRateLimits[offRamp]._currentTokenBucketState(); + } + + /// @notice Sets the onramp rate limited config. + /// @param config The new rate limiter config. + function setOnRampRateLimiterConfig(address onRamp, RateLimiter.Config memory config) external onlyOwner { + if (!isOnRamp(onRamp)) revert NonExistentRamp(onRamp); + s_onRampRateLimits[onRamp]._setTokenBucketConfig(config); + emit OnRampConfigured(onRamp, config); + } + + /// @notice Sets the offramp rate limited config. + /// @param config The new rate limiter config. + function setOffRampRateLimiterConfig(address offRamp, RateLimiter.Config memory config) external onlyOwner { + if (!isOffRamp(offRamp)) revert NonExistentRamp(offRamp); + s_offRampRateLimits[offRamp]._setTokenBucketConfig(config); + emit OffRampConfigured(offRamp, config); + } + + // ================================================================ + // │ Access │ + // ================================================================ + + /// @notice Checks whether the msg.sender is a permissioned onRamp on this contract + /// @dev Reverts with a PermissionsError if check fails + modifier onlyOnRamp() { + if (!isOnRamp(msg.sender)) revert PermissionsError(); + _; + } + + /// @notice Checks whether the msg.sender is a permissioned offRamp on this contract + /// @dev Reverts with a PermissionsError if check fails + modifier onlyOffRamp() { + if (!isOffRamp(msg.sender)) revert PermissionsError(); + _; + } + + // ================================================================ + // │ Allowlist │ + // ================================================================ + + modifier checkAllowList(address sender) { + if (i_allowlistEnabled && !s_allowList.contains(sender)) revert SenderNotAllowed(sender); + _; + } + + /// @notice Gets whether the allowList functionality is enabled. + /// @return true is enabled, false if not. + function getAllowListEnabled() external view returns (bool) { + return i_allowlistEnabled; + } + + /// @notice Gets the allowed addresses. + /// @return The allowed addresses. + function getAllowList() external view returns (address[] memory) { + return s_allowList.values(); + } + + /// @notice Apply updates to the allow list. + /// @param removes The addresses to be removed. + /// @param adds The addresses to be added. + /// @dev allowListing will be removed before public launch + function applyAllowListUpdates(address[] calldata removes, address[] calldata adds) external onlyOwner { + _applyAllowListUpdates(removes, adds); + } + + /// @notice Internal version of applyAllowListUpdates to allow for reuse in the constructor. + function _applyAllowListUpdates(address[] memory removes, address[] memory adds) internal { + if (!i_allowlistEnabled) revert AllowListNotEnabled(); + + for (uint256 i = 0; i < removes.length; ++i) { + address toRemove = removes[i]; + if (s_allowList.remove(toRemove)) { + emit AllowListRemove(toRemove); + } + } + for (uint256 i = 0; i < adds.length; ++i) { + address toAdd = adds[i]; + if (toAdd == address(0)) { + continue; + } + if (s_allowList.add(toAdd)) { + emit AllowListAdd(toAdd); + } + } + } + + /// @notice Ensure that there is no active curse. + modifier whenHealthy() { + if (IRMN(i_armProxy).isCursed()) revert BadARMSignal(); + _; + } +} + +contract BurnMintTokenPool1_2 is ITypeAndVersion, TokenPool1_2 { + // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables + string public constant override typeAndVersion = "BurnMintTokenPool 1.2.0"; + + constructor( + IBurnMintERC20 token, + address[] memory allowlist, + address armProxy + ) TokenPool1_2(token, allowlist, armProxy) {} + + /// @notice Burn the token in the pool + /// @param amount Amount to burn + /// @dev The whenHealthy check is important to ensure that even if a ramp is compromised + /// we're able to stop token movement via ARM. + function lockOrBurn( + address originalSender, + bytes calldata, + uint256 amount, + uint64, + bytes calldata + ) external virtual override onlyOnRamp checkAllowList(originalSender) whenHealthy returns (bytes memory) { + _consumeOnRampRateLimit(amount); + IBurnMintERC20(address(i_token)).burn(amount); + emit Burned(msg.sender, amount); + return ""; + } + + /// @notice Mint tokens from the pool to the recipient + /// @param receiver Recipient address + /// @param amount Amount to mint + /// @dev The whenHealthy check is important to ensure that even if a ramp is compromised + /// we're able to stop token movement via ARM. + function releaseOrMint( + bytes memory, + address receiver, + uint256 amount, + uint64, + bytes memory + ) external virtual override whenHealthy onlyOffRamp { + _consumeOffRampRateLimit(amount); + IBurnMintERC20(address(i_token)).mint(receiver, amount); + emit Minted(msg.sender, receiver, amount); + } +} diff --git a/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_4.sol b/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_4.sol new file mode 100644 index 0000000000..9ac5d66b1c --- /dev/null +++ b/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_4.sol @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; +import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; +import {IPoolPriorTo1_5} from "../../interfaces/IPoolPriorTo1_5.sol"; +import {IRMN} from "../../interfaces/IRMN.sol"; +import {IRouter} from "../../interfaces/IRouter.sol"; + +import {OwnerIsCreator} from "../../../shared/access/OwnerIsCreator.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +/// @notice Base abstract class with common functions for all token pools. +/// A token pool serves as isolated place for holding tokens and token specific logic +/// that may execute as tokens move across the bridge. +abstract contract TokenPool1_4 is IPoolPriorTo1_5, OwnerIsCreator, IERC165 { + using EnumerableSet for EnumerableSet.AddressSet; + using EnumerableSet for EnumerableSet.UintSet; + using RateLimiter for RateLimiter.TokenBucket; + + error CallerIsNotARampOnRouter(address caller); + error ZeroAddressNotAllowed(); + error SenderNotAllowed(address sender); + error AllowListNotEnabled(); + error NonExistentChain(uint64 remoteChainSelector); + error ChainNotAllowed(uint64 remoteChainSelector); + error BadARMSignal(); + error ChainAlreadyExists(uint64 chainSelector); + + event Locked(address indexed sender, uint256 amount); + event Burned(address indexed sender, uint256 amount); + event Released(address indexed sender, address indexed recipient, uint256 amount); + event Minted(address indexed sender, address indexed recipient, uint256 amount); + event ChainAdded( + uint64 remoteChainSelector, + RateLimiter.Config outboundRateLimiterConfig, + RateLimiter.Config inboundRateLimiterConfig + ); + event ChainConfigured( + uint64 remoteChainSelector, + RateLimiter.Config outboundRateLimiterConfig, + RateLimiter.Config inboundRateLimiterConfig + ); + event ChainRemoved(uint64 remoteChainSelector); + event AllowListAdd(address sender); + event AllowListRemove(address sender); + event RouterUpdated(address oldRouter, address newRouter); + + struct ChainUpdate { + uint64 remoteChainSelector; // ──╮ Remote chain selector + bool allowed; // ────────────────╯ Whether the chain is allowed + RateLimiter.Config outboundRateLimiterConfig; // Outbound rate limited config, meaning the rate limits for all of the onRamps for the given chain + RateLimiter.Config inboundRateLimiterConfig; // Inbound rate limited config, meaning the rate limits for all of the offRamps for the given chain + } + + /// @dev The bridgeable token that is managed by this pool. + IERC20 internal immutable i_token; + /// @dev The address of the arm proxy + address internal immutable i_armProxy; + /// @dev The immutable flag that indicates if the pool is access-controlled. + bool internal immutable i_allowlistEnabled; + /// @dev A set of addresses allowed to trigger lockOrBurn as original senders. + /// Only takes effect if i_allowlistEnabled is true. + /// This can be used to ensure only token-issuer specified addresses can + /// move tokens. + EnumerableSet.AddressSet internal s_allowList; + /// @dev The address of the router + IRouter internal s_router; + /// @dev A set of allowed chain selectors. We want the allowlist to be enumerable to + /// be able to quickly determine (without parsing logs) who can access the pool. + /// @dev The chain selectors are in uin256 format because of the EnumerableSet implementation. + EnumerableSet.UintSet internal s_remoteChainSelectors; + /// @dev Outbound rate limits. Corresponds to the inbound rate limit for the pool + /// on the remote chain. + mapping(uint64 remoteChainSelector => RateLimiter.TokenBucket) internal s_outboundRateLimits; + /// @dev Inbound rate limits. This allows per destination chain + /// token issuer specified rate limiting (e.g. issuers may trust chains to varying + /// degrees and prefer different limits) + mapping(uint64 remoteChainSelector => RateLimiter.TokenBucket) internal s_inboundRateLimits; + + constructor(IERC20 token, address[] memory allowlist, address armProxy, address router) { + if (address(token) == address(0) || router == address(0)) revert ZeroAddressNotAllowed(); + i_token = token; + i_armProxy = armProxy; + s_router = IRouter(router); + + // Pool can be set as permissioned or permissionless at deployment time only to save hot-path gas. + i_allowlistEnabled = allowlist.length > 0; + if (i_allowlistEnabled) { + _applyAllowListUpdates(new address[](0), allowlist); + } + } + + /// @notice Get ARM proxy address + /// @return armProxy Address of arm proxy + function getArmProxy() public view returns (address armProxy) { + return i_armProxy; + } + + /// @inheritdoc IPoolPriorTo1_5 + function getToken() public view override returns (IERC20 token) { + return i_token; + } + + /// @notice Gets the pool's Router + /// @return router The pool's Router + function getRouter() public view returns (address router) { + return address(s_router); + } + + /// @notice Sets the pool's Router + /// @param newRouter The new Router + function setRouter(address newRouter) public onlyOwner { + if (newRouter == address(0)) revert ZeroAddressNotAllowed(); + address oldRouter = address(s_router); + s_router = IRouter(newRouter); + + emit RouterUpdated(oldRouter, newRouter); + } + + /// @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) { + return interfaceId == type(IPoolPriorTo1_5).interfaceId || interfaceId == type(IERC165).interfaceId; + } + + // ================================================================ + // │ Chain permissions │ + // ================================================================ + + /// @notice Checks whether a chain selector is permissioned on this contract. + /// @return true if the given chain selector is a permissioned remote chain. + function isSupportedChain(uint64 remoteChainSelector) public view returns (bool) { + return s_remoteChainSelectors.contains(remoteChainSelector); + } + + /// @notice Get list of allowed chains + /// @return list of chains. + function getSupportedChains() public view returns (uint64[] memory) { + uint256[] memory uint256ChainSelectors = s_remoteChainSelectors.values(); + uint64[] memory chainSelectors = new uint64[](uint256ChainSelectors.length); + for (uint256 i = 0; i < uint256ChainSelectors.length; ++i) { + chainSelectors[i] = uint64(uint256ChainSelectors[i]); + } + + return chainSelectors; + } + + /// @notice Sets the permissions for a list of chains selectors. Actual senders for these chains + /// need to be allowed on the Router to interact with this pool. + /// @dev Only callable by the owner + /// @param chains A list of chains and their new permission status & rate limits. Rate limits + /// are only used when the chain is being added through `allowed` being true. + function applyChainUpdates(ChainUpdate[] calldata chains) external virtual onlyOwner { + for (uint256 i = 0; i < chains.length; ++i) { + ChainUpdate memory update = chains[i]; + RateLimiter._validateTokenBucketConfig(update.outboundRateLimiterConfig, !update.allowed); + RateLimiter._validateTokenBucketConfig(update.inboundRateLimiterConfig, !update.allowed); + + if (update.allowed) { + // If the chain already exists, revert + if (!s_remoteChainSelectors.add(update.remoteChainSelector)) { + revert ChainAlreadyExists(update.remoteChainSelector); + } + + s_outboundRateLimits[update.remoteChainSelector] = RateLimiter.TokenBucket({ + rate: update.outboundRateLimiterConfig.rate, + capacity: update.outboundRateLimiterConfig.capacity, + tokens: update.outboundRateLimiterConfig.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: update.outboundRateLimiterConfig.isEnabled + }); + + s_inboundRateLimits[update.remoteChainSelector] = RateLimiter.TokenBucket({ + rate: update.inboundRateLimiterConfig.rate, + capacity: update.inboundRateLimiterConfig.capacity, + tokens: update.inboundRateLimiterConfig.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: update.inboundRateLimiterConfig.isEnabled + }); + emit ChainAdded(update.remoteChainSelector, update.outboundRateLimiterConfig, update.inboundRateLimiterConfig); + } else { + // If the chain doesn't exist, revert + if (!s_remoteChainSelectors.remove(update.remoteChainSelector)) { + revert NonExistentChain(update.remoteChainSelector); + } + + delete s_inboundRateLimits[update.remoteChainSelector]; + delete s_outboundRateLimits[update.remoteChainSelector]; + emit ChainRemoved(update.remoteChainSelector); + } + } + } + + // ================================================================ + // │ Rate limiting │ + // ================================================================ + + /// @notice Consumes outbound rate limiting capacity in this pool + function _consumeOutboundRateLimit(uint64 remoteChainSelector, uint256 amount) internal { + s_outboundRateLimits[remoteChainSelector]._consume(amount, address(i_token)); + } + + /// @notice Consumes inbound rate limiting capacity in this pool + function _consumeInboundRateLimit(uint64 remoteChainSelector, uint256 amount) internal { + s_inboundRateLimits[remoteChainSelector]._consume(amount, address(i_token)); + } + + /// @notice Gets the token bucket with its values for the block it was requested at. + /// @return The token bucket. + function getCurrentOutboundRateLimiterState(uint64 remoteChainSelector) + external + view + returns (RateLimiter.TokenBucket memory) + { + return s_outboundRateLimits[remoteChainSelector]._currentTokenBucketState(); + } + + /// @notice Gets the token bucket with its values for the block it was requested at. + /// @return The token bucket. + function getCurrentInboundRateLimiterState(uint64 remoteChainSelector) + external + view + returns (RateLimiter.TokenBucket memory) + { + return s_inboundRateLimits[remoteChainSelector]._currentTokenBucketState(); + } + + /// @notice Sets the chain rate limiter config. + /// @param remoteChainSelector The remote chain selector for which the rate limits apply. + /// @param outboundConfig The new outbound rate limiter config, meaning the onRamp rate limits for the given chain. + /// @param inboundConfig The new inbound rate limiter config, meaning the offRamp rate limits for the given chain. + function setChainRateLimiterConfig( + uint64 remoteChainSelector, + RateLimiter.Config memory outboundConfig, + RateLimiter.Config memory inboundConfig + ) external virtual onlyOwner { + _setRateLimitConfig(remoteChainSelector, outboundConfig, inboundConfig); + } + + function _setRateLimitConfig( + uint64 remoteChainSelector, + RateLimiter.Config memory outboundConfig, + RateLimiter.Config memory inboundConfig + ) internal { + if (!isSupportedChain(remoteChainSelector)) revert NonExistentChain(remoteChainSelector); + RateLimiter._validateTokenBucketConfig(outboundConfig, false); + s_outboundRateLimits[remoteChainSelector]._setTokenBucketConfig(outboundConfig); + RateLimiter._validateTokenBucketConfig(inboundConfig, false); + s_inboundRateLimits[remoteChainSelector]._setTokenBucketConfig(inboundConfig); + emit ChainConfigured(remoteChainSelector, outboundConfig, inboundConfig); + } + + // ================================================================ + // │ Access │ + // ================================================================ + + /// @notice Checks whether remote chain selector is configured on this contract, and if the msg.sender + /// is a permissioned onRamp for the given chain on the Router. + modifier onlyOnRamp(uint64 remoteChainSelector) { + if (!isSupportedChain(remoteChainSelector)) revert ChainNotAllowed(remoteChainSelector); + if (!(msg.sender == s_router.getOnRamp(remoteChainSelector))) revert CallerIsNotARampOnRouter(msg.sender); + _; + } + + /// @notice Checks whether remote chain selector is configured on this contract, and if the msg.sender + /// is a permissioned offRamp for the given chain on the Router. + modifier onlyOffRamp(uint64 remoteChainSelector) { + if (!isSupportedChain(remoteChainSelector)) revert ChainNotAllowed(remoteChainSelector); + if (!s_router.isOffRamp(remoteChainSelector, msg.sender)) revert CallerIsNotARampOnRouter(msg.sender); + _; + } + + // ================================================================ + // │ Allowlist │ + // ================================================================ + + modifier checkAllowList(address sender) { + if (i_allowlistEnabled && !s_allowList.contains(sender)) revert SenderNotAllowed(sender); + _; + } + + /// @notice Gets whether the allowList functionality is enabled. + /// @return true is enabled, false if not. + function getAllowListEnabled() external view returns (bool) { + return i_allowlistEnabled; + } + + /// @notice Gets the allowed addresses. + /// @return The allowed addresses. + function getAllowList() external view returns (address[] memory) { + return s_allowList.values(); + } + + /// @notice Apply updates to the allow list. + /// @param removes The addresses to be removed. + /// @param adds The addresses to be added. + /// @dev allowListing will be removed before public launch + function applyAllowListUpdates(address[] calldata removes, address[] calldata adds) external onlyOwner { + _applyAllowListUpdates(removes, adds); + } + + /// @notice Internal version of applyAllowListUpdates to allow for reuse in the constructor. + function _applyAllowListUpdates(address[] memory removes, address[] memory adds) internal { + if (!i_allowlistEnabled) revert AllowListNotEnabled(); + + for (uint256 i = 0; i < removes.length; ++i) { + address toRemove = removes[i]; + if (s_allowList.remove(toRemove)) { + emit AllowListRemove(toRemove); + } + } + for (uint256 i = 0; i < adds.length; ++i) { + address toAdd = adds[i]; + if (toAdd == address(0)) { + continue; + } + if (s_allowList.add(toAdd)) { + emit AllowListAdd(toAdd); + } + } + } + + /// @notice Ensure that there is no active curse. + modifier whenHealthy() { + if (IRMN(i_armProxy).isCursed()) revert BadARMSignal(); + _; + } +} + +abstract contract BurnMintTokenPoolAbstract is TokenPool1_4 { + /// @notice Contains the specific burn call for a pool. + /// @dev overriding this method allows us to create pools with different burn signatures + /// without duplicating the underlying logic. + function _burn(uint256 amount) internal virtual; + + /// @notice Burn the token in the pool + /// @param amount Amount to burn + /// @dev The whenHealthy check is important to ensure that even if a ramp is compromised + /// we're able to stop token movement via ARM. + function lockOrBurn( + address originalSender, + bytes calldata, + uint256 amount, + uint64 remoteChainSelector, + bytes calldata + ) + external + virtual + override + onlyOnRamp(remoteChainSelector) + checkAllowList(originalSender) + whenHealthy + returns (bytes memory) + { + _consumeOutboundRateLimit(remoteChainSelector, amount); + _burn(amount); + emit Burned(msg.sender, amount); + return ""; + } + + /// @notice Mint tokens from the pool to the recipient + /// @param receiver Recipient address + /// @param amount Amount to mint + /// @dev The whenHealthy check is important to ensure that even if a ramp is compromised + /// we're able to stop token movement via ARM. + function releaseOrMint( + bytes memory, + address receiver, + uint256 amount, + uint64 remoteChainSelector, + bytes memory + ) external virtual override whenHealthy onlyOffRamp(remoteChainSelector) { + _consumeInboundRateLimit(remoteChainSelector, amount); + IBurnMintERC20(address(i_token)).mint(receiver, amount); + emit Minted(msg.sender, receiver, amount); + } +} + +/// @notice This pool mints and burns a 3rd-party token. +/// @dev Pool whitelisting mode is set in the constructor and cannot be modified later. +/// It either accepts any address as originalSender, or only accepts whitelisted originalSender. +/// The only way to change whitelisting mode is to deploy a new pool. +/// If that is expected, please make sure the token's burner/minter roles are adjustable. +contract BurnMintTokenPool1_4 is BurnMintTokenPoolAbstract, ITypeAndVersion { + string public constant override typeAndVersion = "BurnMintTokenPool 1.4.0"; + + constructor( + IBurnMintERC20 token, + address[] memory allowlist, + address armProxy, + address router + ) TokenPool1_4(token, allowlist, armProxy, router) {} + + /// @inheritdoc BurnMintTokenPoolAbstract + function _burn(uint256 amount) internal virtual override { + IBurnMintERC20(address(i_token)).burn(amount); + } +} diff --git a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol new file mode 100644 index 0000000000..292ac9a3bf --- /dev/null +++ b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol @@ -0,0 +1,771 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {IPoolV1} from "../../interfaces/IPool.sol"; +import {IPoolPriorTo1_5} from "../../interfaces/IPoolPriorTo1_5.sol"; + +import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; +import {PriceRegistry} from "../../PriceRegistry.sol"; +import {Router} from "../../Router.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Pool} from "../../libraries/Pool.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {BurnMintTokenPoolAndProxy} from "../../pools/BurnMintTokenPoolAndProxy.sol"; +import {LockReleaseTokenPoolAndProxy} from "../../pools/LockReleaseTokenPoolAndProxy.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {TokenSetup} from "../TokenSetup.t.sol"; +import {EVM2EVMOnRampHelper} from "../helpers/EVM2EVMOnRampHelper.sol"; +import {EVM2EVMOnRampSetup} from "../onRamp/EVM2EVMOnRampSetup.t.sol"; +import {RouterSetup} from "../router/RouterSetup.t.sol"; +import {BurnMintTokenPool1_2, TokenPool1_2} from "./BurnMintTokenPool1_2.sol"; +import {BurnMintTokenPool1_4, TokenPool1_4} from "./BurnMintTokenPool1_4.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; + +contract TokenPoolAndProxyMigration is EVM2EVMOnRampSetup { + BurnMintTokenPoolAndProxy internal s_newPool; + IPoolPriorTo1_5 internal s_legacyPool; + BurnMintERC677 internal s_token; + + address internal s_offRamp; + address internal s_sourcePool = makeAddr("source_pool"); + address internal s_sourceToken = makeAddr("source_token"); + uint256 internal constant AMOUNT = 1; + + function setUp() public virtual override { + super.setUp(); + // Create a system with a token and a legacy pool + s_token = new BurnMintERC677("Test", "TEST", 18, type(uint256).max); + // dealing doesn't update the total supply, meaning the first time we burn a token we underflow, which isn't + // guarded against. Then, when we mint a token, we overflow, which is guarded against and will revert. + s_token.grantMintAndBurnRoles(OWNER); + s_token.mint(OWNER, 1e18); + + s_offRamp = s_offRamps[0]; + // Approve enough for a few calls + s_token.approve(address(s_sourceRouter), AMOUNT * 100); + + // Approve infinite fee tokens + IERC20(s_sourceFeeToken).approve(address(s_sourceRouter), type(uint256).max); + } + + /// @notice This test covers the entire migration plan for 1.0-1.2 pools to 1.5 pools. For simplicity + /// we will refer to the 1.0/1.2 pools as 1.2 pools, as they are functionally the same. + function test_tokenPoolMigration_Success_1_2() public { + // ================================================================ + // | 1 1.2 prior to upgrade | + // ================================================================ + _deployPool1_2(); + + // Ensure everything works on the 1.2 pool + _ccipSend_OLD(); + _fakeReleaseOrMintFromOffRamp_OLD(); + + // ================================================================ + // | 2 Deploy self serve | + // ================================================================ + _deploySelfServe(); + + // This doesn't impact the 1.2 pool, so it should still be functional + _ccipSend_OLD(); + _fakeReleaseOrMintFromOffRamp_OLD(); + + // ================================================================ + // | 3 Configure new pool on old pool | + // ================================================================ + // In the 1.2 case, everything keeps working on both the 1.2 and 1.5 pools. This config can be + // done in advance of the actual swap to 1.5 lanes. + vm.startPrank(OWNER); + TokenPool1_2.RampUpdate[] memory rampUpdates = new TokenPool1_2.RampUpdate[](1); + rampUpdates[0] = TokenPool1_2.RampUpdate({ + ramp: address(s_newPool), + allowed: true, + // The rate limits should be turned off for this fake ramp, as the 1.5 pool will handle all the + // rate limiting for us. + rateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}) + }); + // Since this call doesn't impact the usability of the old pool, we can do it whenever we want + BurnMintTokenPool1_2(address(s_legacyPool)).applyRampUpdates(rampUpdates, rampUpdates); + + // Assert the 1.2 lanes still work + _ccipSend_OLD(); + _fakeReleaseOrMintFromOffRamp_OLD(); + + // ================================================================ + // | 4 Update the router with to 1.5 | + // ================================================================ + + // This will stop any new messages entering the old lanes, and will direct all traffic to the + // new 1.5 lanes, and therefore to the 1.5 pools. Note that the old pools will still receive + // inflight messages, and will need to continue functioning until all of those are processed. + _fakeReleaseOrMintFromOffRamp_OLD(); + + // Everything is configured, we can now send a ccip tx to the new pool + _ccipSend1_5(); + _fakeReleaseOrMintFromOffRamp1_5(); + + // ================================================================ + // | 5 Migrate to using 1.5 the pool | + // ================================================================ + // Turn off the legacy pool, this enabled the 1.5 pool logic. This should be done AFTER the new pool + // has gotten permissions to mint/burn. We see the case where that isn't done below. + vm.startPrank(OWNER); + s_newPool.setPreviousPool(IPoolPriorTo1_5(address(0))); + + // The new pool is now active, but is has not been given permissions to burn/mint yet + vm.expectRevert(abi.encodeWithSelector(BurnMintERC677.SenderNotBurner.selector, address(s_newPool))); + _ccipSend1_5(); + vm.expectRevert(abi.encodeWithSelector(BurnMintERC677.SenderNotMinter.selector, address(s_newPool))); + _fakeReleaseOrMintFromOffRamp1_5(); + + // When we do give burn/mint, the new pool is fully active + vm.startPrank(OWNER); + s_token.grantMintAndBurnRoles(address(s_newPool)); + _ccipSend1_5(); + _fakeReleaseOrMintFromOffRamp1_5(); + + // Even after the pool has taken over as primary, the old pool can still process messages from the old lane + _fakeReleaseOrMintFromOffRamp_OLD(); + } + + function test_tokenPoolMigration_Success_1_4() public { + // ================================================================ + // | 1 1.4 prior to upgrade | + // ================================================================ + _deployPool1_4(); + + // Ensure everything works on the 1.4 pool + _ccipSend_OLD(); + _fakeReleaseOrMintFromOffRamp_OLD(); + + // ================================================================ + // | 2 Deploy self serve | + // ================================================================ + _deploySelfServe(); + + // This doesn't impact the 1.4 pool, so it should still be functional + _ccipSend_OLD(); + _fakeReleaseOrMintFromOffRamp_OLD(); + + // ================================================================ + // | 3 Configure new pool on old pool | + // | AND | + // | Update the router with to 1.5 | + // ================================================================ + // NOTE: when this call is made, the SENDING SIDE of old lanes stop working. + vm.startPrank(OWNER); + BurnMintTokenPool1_4(address(s_legacyPool)).setRouter(address(s_newPool)); + + // This will stop any new messages entering the old lanes, and will direct all traffic to the + // new 1.5 lanes, and therefore to the 1.5 pools. Note that the old pools will still receive + // inflight messages, and will need to continue functioning until all of those are processed. + _fakeReleaseOrMintFromOffRamp_OLD(); + + // Sending to the old 1.4 pool no longer works + _ccipSend_OLD_Reverts(); + + // Everything is configured, we can now send a ccip tx + _ccipSend1_5(); + _fakeReleaseOrMintFromOffRamp1_5(); + + // ================================================================ + // | 4 Migrate to using 1.5 the pool | + // ================================================================ + // Turn off the legacy pool, this enabled the 1.5 pool logic. This should be done AFTER the new pool + // has gotten permissions to mint/burn. We see the case where that isn't done below. + vm.startPrank(OWNER); + s_newPool.setPreviousPool(IPoolPriorTo1_5(address(0))); + + // The new pool is now active, but is has not been given permissions to burn/mint yet + vm.expectRevert(abi.encodeWithSelector(BurnMintERC677.SenderNotBurner.selector, address(s_newPool))); + _ccipSend1_5(); + vm.expectRevert(abi.encodeWithSelector(BurnMintERC677.SenderNotMinter.selector, address(s_newPool))); + _fakeReleaseOrMintFromOffRamp1_5(); + + // When we do give burn/mint, the new pool is fully active + vm.startPrank(OWNER); + s_token.grantMintAndBurnRoles(address(s_newPool)); + _ccipSend1_5(); + _fakeReleaseOrMintFromOffRamp1_5(); + + // Even after the pool has taken over as primary, the old pool can still process messages from the old lane + _fakeReleaseOrMintFromOffRamp_OLD(); + } + + function _ccipSend_OLD() internal { + // We send the funds to the pool manually, as the ramp normally does that + deal(address(s_token), address(s_legacyPool), AMOUNT); + vm.startPrank(address(s_onRamp)); + s_legacyPool.lockOrBurn(OWNER, abi.encode(OWNER), AMOUNT, DEST_CHAIN_SELECTOR, ""); + } + + function _ccipSend_OLD_Reverts() internal { + // We send the funds to the pool manually, as the ramp normally does that + deal(address(s_token), address(s_legacyPool), AMOUNT); + vm.startPrank(address(s_onRamp)); + + vm.expectRevert(abi.encodeWithSelector(TokenPool1_4.CallerIsNotARampOnRouter.selector, address(s_onRamp))); + + s_legacyPool.lockOrBurn(OWNER, abi.encode(OWNER), AMOUNT, DEST_CHAIN_SELECTOR, ""); + } + + function _ccipSend1_5() internal { + vm.startPrank(address(OWNER)); + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({token: address(s_token), amount: AMOUNT}); + + s_sourceRouter.ccipSend( + DEST_CHAIN_SELECTOR, + Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: s_sourceFeeToken, + extraArgs: "" + }) + ); + } + + function _fakeReleaseOrMintFromOffRamp1_5() internal { + // This is a fake call to simulate the release or mint from the "offRamp" + vm.startPrank(s_offRamp); + s_newPool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + receiver: OWNER, + amount: AMOUNT, + localToken: address(s_token), + sourcePoolAddress: abi.encode(s_sourcePool), + sourcePoolData: "", + offchainTokenData: "" + }) + ); + } + + function _fakeReleaseOrMintFromOffRamp_OLD() internal { + // This is a fake call to simulate the release or mint from the "offRamp" + vm.startPrank(s_offRamp); + s_legacyPool.releaseOrMint(abi.encode(OWNER), OWNER, AMOUNT, SOURCE_CHAIN_SELECTOR, ""); + } + + function _deployPool1_2() internal { + vm.startPrank(OWNER); + s_legacyPool = new BurnMintTokenPool1_2(s_token, new address[](0), address(s_mockRMN)); + s_token.grantMintAndBurnRoles(address(s_legacyPool)); + + TokenPool1_2.RampUpdate[] memory onRampUpdates = new TokenPool1_2.RampUpdate[](1); + onRampUpdates[0] = TokenPool1_2.RampUpdate({ + ramp: address(s_onRamp), + allowed: true, + rateLimiterConfig: getInboundRateLimiterConfig() + }); + TokenPool1_2.RampUpdate[] memory offRampUpdates = new TokenPool1_2.RampUpdate[](1); + offRampUpdates[0] = TokenPool1_2.RampUpdate({ + ramp: address(s_offRamp), + allowed: true, + rateLimiterConfig: getInboundRateLimiterConfig() + }); + BurnMintTokenPool1_2(address(s_legacyPool)).applyRampUpdates(onRampUpdates, offRampUpdates); + } + + function _deployPool1_4() internal { + vm.startPrank(OWNER); + s_legacyPool = new BurnMintTokenPool1_4(s_token, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + s_token.grantMintAndBurnRoles(address(s_legacyPool)); + + TokenPool1_4.ChainUpdate[] memory legacyChainUpdates = new TokenPool1_4.ChainUpdate[](2); + legacyChainUpdates[0] = TokenPool1_4.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + legacyChainUpdates[1] = TokenPool1_4.ChainUpdate({ + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + BurnMintTokenPool1_4(address(s_legacyPool)).applyChainUpdates(legacyChainUpdates); + } + + function _deploySelfServe() internal { + vm.startPrank(OWNER); + // Deploy the new pool + s_newPool = new BurnMintTokenPoolAndProxy(s_token, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + // Set the previous pool on the new pool + s_newPool.setPreviousPool(s_legacyPool); + + // Configure the lanes just like the legacy pool + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(s_destTokenPool), + remoteTokenAddress: abi.encode(s_destToken), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + chainUpdates[1] = TokenPool.ChainUpdate({ + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(s_sourcePool), + remoteTokenAddress: abi.encode(s_sourceToken), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_newPool.applyChainUpdates(chainUpdates); + + // Register the token on the token admin registry + s_tokenAdminRegistry.proposeAdministrator(address(s_token), OWNER); + // Accept ownership of the token + s_tokenAdminRegistry.acceptAdminRole(address(s_token)); + // Set the pool on the admin registry + s_tokenAdminRegistry.setPool(address(s_token), address(s_newPool)); + } +} + +contract TokenPoolAndProxy is EVM2EVMOnRampSetup { + event Burned(address indexed sender, uint256 amount); + event Minted(address indexed sender, address indexed recipient, uint256 amount); + + IPoolV1 internal s_pool; + BurnMintERC677 internal s_token; + IPoolPriorTo1_5 internal s_legacyPool; + address internal s_fakeOffRamp = makeAddr("off_ramp"); + + address internal s_destPool = makeAddr("dest_pool"); + + function setUp() public virtual override { + super.setUp(); + s_token = BurnMintERC677(s_sourceFeeToken); + + Router.OffRamp[] memory fakeOffRamps = new Router.OffRamp[](1); + fakeOffRamps[0] = Router.OffRamp({sourceChainSelector: DEST_CHAIN_SELECTOR, offRamp: s_fakeOffRamp}); + s_sourceRouter.applyRampUpdates(new Router.OnRamp[](0), new Router.OffRamp[](0), fakeOffRamps); + + s_token.grantMintAndBurnRoles(OWNER); + s_token.mint(OWNER, 1e18); + } + + function test_lockOrBurn_burnMint_Success() public { + s_pool = new BurnMintTokenPoolAndProxy(s_token, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + _configurePool(); + _deployOldPool(); + _assertLockOrBurnCorrect(); + + vm.startPrank(OWNER); + BurnMintTokenPoolAndProxy(address(s_pool)).setPreviousPool(IPoolPriorTo1_5(address(0))); + + _assertReleaseOrMintCorrect(); + } + + function test_lockOrBurn_lockRelease_Success() public { + s_pool = + new LockReleaseTokenPoolAndProxy(s_token, new address[](0), address(s_mockRMN), false, address(s_sourceRouter)); + _configurePool(); + _deployOldPool(); + _assertLockOrBurnCorrect(); + + vm.startPrank(OWNER); + BurnMintTokenPoolAndProxy(address(s_pool)).setPreviousPool(IPoolPriorTo1_5(address(0))); + + _assertReleaseOrMintCorrect(); + } + + function _deployOldPool() internal { + s_legacyPool = new BurnMintTokenPool1_2(s_token, new address[](0), address(s_mockRMN)); + s_token.grantMintAndBurnRoles(address(s_legacyPool)); + + TokenPool1_2.RampUpdate[] memory onRampUpdates = new TokenPool1_2.RampUpdate[](1); + onRampUpdates[0] = + TokenPool1_2.RampUpdate({ramp: address(s_pool), allowed: true, rateLimiterConfig: getInboundRateLimiterConfig()}); + TokenPool1_2.RampUpdate[] memory offRampUpdates = new TokenPool1_2.RampUpdate[](1); + offRampUpdates[0] = + TokenPool1_2.RampUpdate({ramp: address(s_pool), allowed: true, rateLimiterConfig: getInboundRateLimiterConfig()}); + BurnMintTokenPool1_2(address(s_legacyPool)).applyRampUpdates(onRampUpdates, offRampUpdates); + } + + function _configurePool() internal { + TokenPool.ChainUpdate[] memory chains = new TokenPool.ChainUpdate[](1); + chains[0] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(s_destPool), + remoteTokenAddress: abi.encode(s_destToken), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + + BurnMintTokenPoolAndProxy(address(s_pool)).applyChainUpdates(chains); + + // CCIP Token Admin has already been registered from TokenSetup + s_tokenAdminRegistry.setPool(address(s_token), address(s_pool)); + + s_token.grantMintAndBurnRoles(address(s_pool)); + } + + function _assertLockOrBurnCorrect() internal { + uint256 amount = 1234; + vm.startPrank(address(s_onRamp)); + + // lockOrBurn, assert normal path is taken + deal(address(s_token), address(s_pool), amount); + + s_pool.lockOrBurn( + Pool.LockOrBurnInV1({ + receiver: abi.encode(OWNER), + remoteChainSelector: DEST_CHAIN_SELECTOR, + originalSender: OWNER, + amount: amount, + localToken: address(s_token) + }) + ); + + // set legacy pool + + vm.startPrank(OWNER); + BurnMintTokenPoolAndProxy(address(s_pool)).setPreviousPool(s_legacyPool); + + // lockOrBurn, assert legacy pool is called + + vm.startPrank(address(s_onRamp)); + deal(address(s_token), address(s_pool), amount); + + vm.expectEmit(address(s_legacyPool)); + emit Burned(address(s_pool), amount); + + s_pool.lockOrBurn( + Pool.LockOrBurnInV1({ + receiver: abi.encode(OWNER), + remoteChainSelector: DEST_CHAIN_SELECTOR, + originalSender: OWNER, + amount: amount, + localToken: address(s_token) + }) + ); + } + + function _assertReleaseOrMintCorrect() internal { + uint256 amount = 1234; + vm.startPrank(s_fakeOffRamp); + + // releaseOrMint, assert normal path is taken + deal(address(s_token), address(s_pool), amount); + + s_pool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + receiver: OWNER, + remoteChainSelector: DEST_CHAIN_SELECTOR, + originalSender: abi.encode(OWNER), + amount: amount, + localToken: address(s_token), + sourcePoolAddress: abi.encode(s_destPool), + sourcePoolData: "", + offchainTokenData: "" + }) + ); + + // set legacy pool + + vm.startPrank(OWNER); + BurnMintTokenPoolAndProxy(address(s_pool)).setPreviousPool(s_legacyPool); + + // releaseOrMint, assert legacy pool is called + + vm.startPrank(address(s_fakeOffRamp)); + + vm.expectEmit(address(s_legacyPool)); + emit Minted(address(s_pool), s_fakeOffRamp, amount); + + s_pool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + receiver: OWNER, + remoteChainSelector: DEST_CHAIN_SELECTOR, + originalSender: abi.encode(OWNER), + amount: amount, + localToken: address(s_token), + sourcePoolAddress: abi.encode(s_destPool), + sourcePoolData: "", + offchainTokenData: "" + }) + ); + } +} + +//// +/// Duplicated tests from LockReleaseTokenPool.t.sol +/// + +contract LockReleaseTokenPoolAndProxySetup is RouterSetup { + IERC20 internal s_token; + LockReleaseTokenPoolAndProxy internal s_lockReleaseTokenPoolAndProxy; + LockReleaseTokenPoolAndProxy internal s_lockReleaseTokenPoolAndProxyWithAllowList; + address[] internal s_allowedList; + + address internal s_allowedOnRamp = address(123); + address internal s_allowedOffRamp = address(234); + + address internal s_destPoolAddress = address(2736782345); + address internal s_sourcePoolAddress = address(53852352095); + + function setUp() public virtual override { + RouterSetup.setUp(); + s_token = new BurnMintERC677("LINK", "LNK", 18, 0); + deal(address(s_token), OWNER, type(uint256).max); + s_lockReleaseTokenPoolAndProxy = + new LockReleaseTokenPoolAndProxy(s_token, new address[](0), address(s_mockRMN), true, address(s_sourceRouter)); + + s_allowedList.push(USER_1); + s_allowedList.push(DUMMY_CONTRACT_ADDRESS); + s_lockReleaseTokenPoolAndProxyWithAllowList = + new LockReleaseTokenPoolAndProxy(s_token, s_allowedList, address(s_mockRMN), true, address(s_sourceRouter)); + + TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(s_destPoolAddress), + remoteTokenAddress: abi.encode(address(s_token)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + + s_lockReleaseTokenPoolAndProxy.applyChainUpdates(chainUpdate); + s_lockReleaseTokenPoolAndProxyWithAllowList.applyChainUpdates(chainUpdate); + s_lockReleaseTokenPoolAndProxy.setRebalancer(OWNER); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_allowedOnRamp}); + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: s_allowedOffRamp}); + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } +} + +contract LockReleaseTokenPoolAndProxy_setRebalancer is LockReleaseTokenPoolAndProxySetup { + function test_SetRebalancer_Success() public { + assertEq(address(s_lockReleaseTokenPoolAndProxy.getRebalancer()), OWNER); + s_lockReleaseTokenPoolAndProxy.setRebalancer(STRANGER); + assertEq(address(s_lockReleaseTokenPoolAndProxy.getRebalancer()), STRANGER); + } + + function test_SetRebalancer_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert("Only callable by owner"); + s_lockReleaseTokenPoolAndProxy.setRebalancer(STRANGER); + } +} + +contract LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity is LockReleaseTokenPoolAndProxySetup { + function test_CanAcceptLiquidity_Success() public { + assertEq(true, s_lockReleaseTokenPoolAndProxy.canAcceptLiquidity()); + + s_lockReleaseTokenPoolAndProxy = + new LockReleaseTokenPoolAndProxy(s_token, new address[](0), address(s_mockRMN), false, address(s_sourceRouter)); + assertEq(false, s_lockReleaseTokenPoolAndProxy.canAcceptLiquidity()); + } +} + +contract LockReleaseTokenPoolPoolAndProxy_provideLiquidity is LockReleaseTokenPoolAndProxySetup { + function test_Fuzz_ProvideLiquidity_Success(uint256 amount) public { + uint256 balancePre = s_token.balanceOf(OWNER); + s_token.approve(address(s_lockReleaseTokenPoolAndProxy), amount); + + s_lockReleaseTokenPoolAndProxy.provideLiquidity(amount); + + assertEq(s_token.balanceOf(OWNER), balancePre - amount); + assertEq(s_token.balanceOf(address(s_lockReleaseTokenPoolAndProxy)), amount); + } + + // Reverts + + function test_Unauthorized_Revert() public { + vm.startPrank(STRANGER); + vm.expectRevert(abi.encodeWithSelector(LockReleaseTokenPoolAndProxy.Unauthorized.selector, STRANGER)); + + s_lockReleaseTokenPoolAndProxy.provideLiquidity(1); + } + + function test_Fuzz_ExceedsAllowance(uint256 amount) public { + vm.assume(amount > 0); + vm.expectRevert("ERC20: insufficient allowance"); + s_lockReleaseTokenPoolAndProxy.provideLiquidity(amount); + } + + function test_LiquidityNotAccepted_Revert() public { + s_lockReleaseTokenPoolAndProxy = + new LockReleaseTokenPoolAndProxy(s_token, new address[](0), address(s_mockRMN), false, address(s_sourceRouter)); + + vm.expectRevert(LockReleaseTokenPoolAndProxy.LiquidityNotAccepted.selector); + s_lockReleaseTokenPoolAndProxy.provideLiquidity(1); + } +} + +contract LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity is LockReleaseTokenPoolAndProxySetup { + function test_Fuzz_WithdrawalLiquidity_Success(uint256 amount) public { + uint256 balancePre = s_token.balanceOf(OWNER); + s_token.approve(address(s_lockReleaseTokenPoolAndProxy), amount); + s_lockReleaseTokenPoolAndProxy.provideLiquidity(amount); + + s_lockReleaseTokenPoolAndProxy.withdrawLiquidity(amount); + + assertEq(s_token.balanceOf(OWNER), balancePre); + } + + // Reverts + + function test_Unauthorized_Revert() public { + vm.startPrank(STRANGER); + vm.expectRevert(abi.encodeWithSelector(LockReleaseTokenPoolAndProxy.Unauthorized.selector, STRANGER)); + + s_lockReleaseTokenPoolAndProxy.withdrawLiquidity(1); + } + + function test_InsufficientLiquidity_Revert() public { + uint256 maxUint256 = 2 ** 256 - 1; + s_token.approve(address(s_lockReleaseTokenPoolAndProxy), maxUint256); + s_lockReleaseTokenPoolAndProxy.provideLiquidity(maxUint256); + + vm.startPrank(address(s_lockReleaseTokenPoolAndProxy)); + s_token.transfer(OWNER, maxUint256); + vm.startPrank(OWNER); + + vm.expectRevert(LockReleaseTokenPoolAndProxy.InsufficientLiquidity.selector); + s_lockReleaseTokenPoolAndProxy.withdrawLiquidity(1); + } +} + +contract LockReleaseTokenPoolPoolAndProxy_supportsInterface is LockReleaseTokenPoolAndProxySetup { + function test_SupportsInterface_Success() public view { + assertTrue(s_lockReleaseTokenPoolAndProxy.supportsInterface(type(IPoolV1).interfaceId)); + assertTrue(s_lockReleaseTokenPoolAndProxy.supportsInterface(type(IERC165).interfaceId)); + } +} + +contract LockReleaseTokenPoolPoolAndProxy_setChainRateLimiterConfig is LockReleaseTokenPoolAndProxySetup { + event ConfigChanged(RateLimiter.Config); + event ChainConfigured( + uint64 chainSelector, RateLimiter.Config outboundRateLimiterConfig, RateLimiter.Config inboundRateLimiterConfig + ); + + uint64 internal s_remoteChainSelector; + + function setUp() public virtual override { + LockReleaseTokenPoolAndProxySetup.setUp(); + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + s_remoteChainSelector = 123124; + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: s_remoteChainSelector, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_lockReleaseTokenPoolAndProxy.applyChainUpdates(chainUpdates); + } + + function test_Fuzz_SetChainRateLimiterConfig_Success(uint128 capacity, uint128 rate, uint32 newTime) public { + // Cap the lower bound to 4 so 4/2 is still >= 2 + vm.assume(capacity >= 4); + // Cap the lower bound to 2 so 2/2 is still >= 1 + rate = uint128(bound(rate, 2, capacity - 2)); + // Bucket updates only work on increasing time + newTime = uint32(bound(newTime, block.timestamp + 1, type(uint32).max)); + vm.warp(newTime); + + uint256 oldOutboundTokens = + s_lockReleaseTokenPoolAndProxy.getCurrentOutboundRateLimiterState(s_remoteChainSelector).tokens; + uint256 oldInboundTokens = + s_lockReleaseTokenPoolAndProxy.getCurrentInboundRateLimiterState(s_remoteChainSelector).tokens; + + RateLimiter.Config memory newOutboundConfig = RateLimiter.Config({isEnabled: true, capacity: capacity, rate: rate}); + RateLimiter.Config memory newInboundConfig = + RateLimiter.Config({isEnabled: true, capacity: capacity / 2, rate: rate / 2}); + + vm.expectEmit(); + emit ConfigChanged(newOutboundConfig); + vm.expectEmit(); + emit ConfigChanged(newInboundConfig); + vm.expectEmit(); + emit ChainConfigured(s_remoteChainSelector, newOutboundConfig, newInboundConfig); + + s_lockReleaseTokenPoolAndProxy.setChainRateLimiterConfig(s_remoteChainSelector, newOutboundConfig, newInboundConfig); + + uint256 expectedTokens = RateLimiter._min(newOutboundConfig.capacity, oldOutboundTokens); + + RateLimiter.TokenBucket memory bucket = + s_lockReleaseTokenPoolAndProxy.getCurrentOutboundRateLimiterState(s_remoteChainSelector); + assertEq(bucket.capacity, newOutboundConfig.capacity); + assertEq(bucket.rate, newOutboundConfig.rate); + assertEq(bucket.tokens, expectedTokens); + assertEq(bucket.lastUpdated, newTime); + + expectedTokens = RateLimiter._min(newInboundConfig.capacity, oldInboundTokens); + + bucket = s_lockReleaseTokenPoolAndProxy.getCurrentInboundRateLimiterState(s_remoteChainSelector); + assertEq(bucket.capacity, newInboundConfig.capacity); + assertEq(bucket.rate, newInboundConfig.rate); + assertEq(bucket.tokens, expectedTokens); + assertEq(bucket.lastUpdated, newTime); + } + + function test_OnlyOwnerOrRateLimitAdmin_Revert() public { + address rateLimiterAdmin = address(28973509103597907); + + s_lockReleaseTokenPoolAndProxy.setRateLimitAdmin(rateLimiterAdmin); + + vm.startPrank(rateLimiterAdmin); + + s_lockReleaseTokenPoolAndProxy.setChainRateLimiterConfig( + s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() + ); + + vm.startPrank(OWNER); + + s_lockReleaseTokenPoolAndProxy.setChainRateLimiterConfig( + s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() + ); + } + + // Reverts + + function test_OnlyOwner_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert(abi.encodeWithSelector(LockReleaseTokenPoolAndProxy.Unauthorized.selector, STRANGER)); + s_lockReleaseTokenPoolAndProxy.setChainRateLimiterConfig( + s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() + ); + } + + function test_NonExistentChain_Revert() public { + uint64 wrongChainSelector = 9084102894; + + vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, wrongChainSelector)); + s_lockReleaseTokenPoolAndProxy.setChainRateLimiterConfig( + wrongChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() + ); + } +} + +contract LockReleaseTokenPoolAndProxy_setRateLimitAdmin is LockReleaseTokenPoolAndProxySetup { + function test_SetRateLimitAdmin_Success() public { + assertEq(address(0), s_lockReleaseTokenPoolAndProxy.getRateLimitAdmin()); + s_lockReleaseTokenPoolAndProxy.setRateLimitAdmin(OWNER); + assertEq(OWNER, s_lockReleaseTokenPoolAndProxy.getRateLimitAdmin()); + } + + // Reverts + + function test_SetRateLimitAdmin_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert("Only callable by owner"); + s_lockReleaseTokenPoolAndProxy.setRateLimitAdmin(STRANGER); + } +} diff --git a/contracts/src/v0.8/ccip/test/libraries/MerkleMultiProof.t.sol b/contracts/src/v0.8/ccip/test/libraries/MerkleMultiProof.t.sol new file mode 100644 index 0000000000..e2fc9814d0 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/libraries/MerkleMultiProof.t.sol @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {MerkleMultiProof} from "../../libraries/MerkleMultiProof.sol"; +import {MerkleHelper} from "../helpers/MerkleHelper.sol"; +import {Test} from "forge-std/Test.sol"; + +contract MerkleMultiProofTest is Test { + // This must match the spec + function test_SpecSync_gas() public pure { + bytes32 expectedRoot = 0xd4f0f3c40a4d583d98c17d89e550b1143fe4d3d759f25ccc63131c90b183928e; + + bytes32[] memory leaves = new bytes32[](10); + leaves[0] = 0xa20c0244af79697a4ef4e2378c9d5d14cbd49ddab3427b12594c7cfa67a7f240; + leaves[1] = 0x3de96afb24ce2ac45a5595aa13d1a5163ae0b3c94cef6b2dc306b5966f32dfa5; + leaves[2] = 0xacadf7b4d13cd57c5d25f1d27be39b656347fe8f8e0de8db9c76d979dff57736; + leaves[3] = 0xc21c26a709802fe1ae52a9cd8ad94d15bf142ded26314339cd87a13e5b468165; + leaves[4] = 0x55f6df03562738c9a6437cd9ad221c52b76906a175ae96188cff60e0a2a59933; + leaves[5] = 0x2dbbe66452e43fec839dc65d5945aad6433d410c65863eaf1d876e1e0b06343c; + leaves[6] = 0x8beab00297b94bf079fcd5893b0a33ebf6b0ce862cd06be07c87d3c63e1c4acf; + leaves[7] = 0xcabdd3ad25daeb1e0541042f2ea4cd177f54e67aa4a2c697acd4bb682e94de59; + leaves[8] = 0x7e01d497203685e99e34df33d55465c66b2253fa1630ee2fe5c4997968e4a6fa; + leaves[9] = 0x1a03d013f1e2fa9cc04f89c7528ac3216e3e096a1185d7247304e97c59f9661f; + + bytes32[] memory proofs = new bytes32[](33); + proofs[0] = 0xde96f24fcf9ddd20c803dc9c5fba7c478a5598a08a0faa5f032c65823b8e26a3; + proofs[1] = 0xe1303cffc3958a6b93e2dc04caf21f200ff5aa5be090c5013f37804b91488bc2; + proofs[2] = 0x90d80c76bccb44a91f4e16604976163aaa39e9a1588b0b24b33a61f1d4ba7bb5; + proofs[3] = 0x012a299b25539d513c8677ecf37968774e9e4b045e79737f48defd350224cdfd; + proofs[4] = 0x420a36c5a73f87d8fb98e70c48d0d6f9dd83f50b7b91416a6f5f91fac4db800f; + proofs[5] = 0x5857d8d1b56abcd7f863cedd3c3f8677256f54d675be61f05efa45d6495fc30a; + proofs[6] = 0xbf176d20166fdeb72593ff97efec1ce6244af41ca46cf0bc902d19d50c446f7b; + proofs[7] = 0xa9221608e4380250a1815fb308632bce99f611a673d2e17fc617123fdc6afcd2; + proofs[8] = 0xbd14f3366c73186314f182027217d0f70eba55817561de9e9a1f2c78bf5cbead; + proofs[9] = 0x2f9aa48c0c9f82aaac65d7a9374a52d9dc138ed100a5809ede57e70697f48b56; + proofs[10] = 0x2ae60afa54271cb421c12e4441c2dac0a25f25c9433a6d07cb32419e993fe344; + proofs[11] = 0xc765c091680f0434b74c44507b932e5c80f6e995a975a275e5b130af1de1064c; + proofs[12] = 0x59d2d6e0c4a5d07b169dbcdfa39dad7aea7b7783a814399f4f44c4a36b6336d3; + proofs[13] = 0xdd14d1387d10740187d71ad9500475399559c0922dbe2576882e61f1edd84692; + proofs[14] = 0x5412b8395509935406811ab3da43ab80be7acd8ffb5f398ab70f056ff3740f46; + proofs[15] = 0xeadab258ae7d779ce5f10fbb1bb0273116b8eccbf738ed878db570de78bed1e4; + proofs[16] = 0x6133aa40e6db75373b7cfc79e6f8b8ce80e441e6c1f98b85a593464dda3cf9c0; + proofs[17] = 0x5418948467112660639b932af9b1b212e40d71b24326b4606679d168a765af4f; + proofs[18] = 0x44f618505355c7e4e7c0f81d6bb15d2ec9cf9b366f9e1dc37db52745486e6b0f; + proofs[19] = 0xa410ee174a66a4d64f3c000b93efe15b5b1f3e39e962af2580fcd30bce07d039; + proofs[20] = 0x09c3eb05ac9552022a45c00d01a47cd56f95f94afdd4402299dba1291a17f976; + proofs[21] = 0x0e780f6acd081b07320a55208fa3e1d884e2e95cb13d1c98c74b7e853372c813; + proofs[22] = 0x2b60e8c21f78ef22fa4297f28f1d8c747181edfc465121b39c16be97d4fb8a04; + proofs[23] = 0xf24da95060a8598c06e9dfb3926e1a8c8bd8ec2c65be10e69323442840724888; + proofs[24] = 0x7e220fc095bcd2b0f5ef134d9620d89f6d7a1e8719ce8893bb9aff15e847578f; + proofs[25] = 0xcfe9e475c4bd32f1e36b2cc65a959c403c59979ff914fb629a64385b0c680a71; + proofs[26] = 0x25237fb8d1bfdc01ca5363ec3166a2b40789e38d5adcc8627801da683d2e1d76; + proofs[27] = 0x42647949fed0250139c01212d739d8c83d2852589ebc892d3490ae52e411432c; + proofs[28] = 0x34397a30930e6dd4fb5af48084afc5cfbe02c18dd9544b3faff4e2e90bf00cb9; + proofs[29] = 0xa028f33226adc3d1cb72b19eb6808dab9190b25066a45cacb5dfe5d640e57cf2; + proofs[30] = 0x7cff66ba47a05f932d06d168c294266dcb0d3943a4f2a4a75c860b9fd6e53092; + proofs[31] = 0x5ca1b32f1dbfadd83205882be5eb76f34c49e834726f5239905a0e70d0a5e0eb; + proofs[32] = 0x1b4b087a89e4eca6cdd237210932559dc8fd167d5f4f2d9acb13264e1e305479; + + uint256 flagsUint256 = 0x2f3c0000000; + + bytes32 root = MerkleMultiProof.merkleRoot(leaves, proofs, flagsUint256); + + assertEq(expectedRoot, root); + } + + function test_Fuzz_MerkleRoot2(bytes32 left, bytes32 right) public pure { + bytes32[] memory leaves = new bytes32[](2); + leaves[0] = left; + leaves[1] = right; + bytes32[] memory proofs = new bytes32[](0); + + bytes32 expectedRoot = MerkleHelper.hashPair(left, right); + + bytes32 root = MerkleMultiProof.merkleRoot(leaves, proofs, 2 ** 2 - 1); + + assertEq(root, expectedRoot); + } + + function test_MerkleRoot256() public pure { + bytes32[] memory leaves = new bytes32[](256); + for (uint256 i = 0; i < leaves.length; ++i) { + leaves[i] = keccak256("a"); + } + bytes32[] memory proofs = new bytes32[](0); + + bytes32 expectedRoot = MerkleHelper.getMerkleRoot(leaves); + + bytes32 root = MerkleMultiProof.merkleRoot(leaves, proofs, 2 ** 256 - 1); + + assertEq(root, expectedRoot); + } + + function test_Fuzz_MerkleMulti1of4(bytes32 leaf1, bytes32 proof1, bytes32 proof2) public pure { + bytes32[] memory leaves = new bytes32[](1); + leaves[0] = leaf1; + bytes32[] memory proofs = new bytes32[](2); + proofs[0] = proof1; + proofs[1] = proof2; + + // Proof flag = false + bytes32 result = MerkleHelper.hashPair(leaves[0], proofs[0]); + // Proof flag = false + result = MerkleHelper.hashPair(result, proofs[1]); + + assertEq(MerkleMultiProof.merkleRoot(leaves, proofs, 0), result); + } + + function test_Fuzz_MerkleMulti2of4(bytes32 leaf1, bytes32 leaf2, bytes32 proof1, bytes32 proof2) public pure { + bytes32[] memory leaves = new bytes32[](2); + leaves[0] = leaf1; + leaves[1] = leaf2; + bytes32[] memory proofs = new bytes32[](2); + proofs[0] = proof1; + proofs[1] = proof2; + + // Proof flag = false + bytes32 result1 = MerkleHelper.hashPair(leaves[0], proofs[0]); + // Proof flag = false + bytes32 result2 = MerkleHelper.hashPair(leaves[1], proofs[1]); + // Proof flag = true + bytes32 finalResult = MerkleHelper.hashPair(result1, result2); + + assertEq(MerkleMultiProof.merkleRoot(leaves, proofs, 4), finalResult); + } + + function test_Fuzz_MerkleMulti3of4(bytes32 leaf1, bytes32 leaf2, bytes32 leaf3, bytes32 proof) public pure { + bytes32[] memory leaves = new bytes32[](3); + leaves[0] = leaf1; + leaves[1] = leaf2; + leaves[2] = leaf3; + bytes32[] memory proofs = new bytes32[](1); + proofs[0] = proof; + + // Proof flag = true + bytes32 result1 = MerkleHelper.hashPair(leaves[0], leaves[1]); + // Proof flag = false + bytes32 result2 = MerkleHelper.hashPair(leaves[2], proofs[0]); + // Proof flag = true + bytes32 finalResult = MerkleHelper.hashPair(result1, result2); + + assertEq(MerkleMultiProof.merkleRoot(leaves, proofs, 5), finalResult); + } + + function test_Fuzz_MerkleMulti4of4(bytes32 leaf1, bytes32 leaf2, bytes32 leaf3, bytes32 leaf4) public pure { + bytes32[] memory leaves = new bytes32[](4); + leaves[0] = leaf1; + leaves[1] = leaf2; + leaves[2] = leaf3; + leaves[3] = leaf4; + bytes32[] memory proofs = new bytes32[](0); + + // Proof flag = true + bytes32 result1 = MerkleHelper.hashPair(leaves[0], leaves[1]); + // Proof flag = true + bytes32 result2 = MerkleHelper.hashPair(leaves[2], leaves[3]); + // Proof flag = true + bytes32 finalResult = MerkleHelper.hashPair(result1, result2); + + assertEq(MerkleMultiProof.merkleRoot(leaves, proofs, 7), finalResult); + } + + function test_MerkleRootSingleLeaf_Success() public pure { + bytes32[] memory leaves = new bytes32[](1); + leaves[0] = "root"; + bytes32[] memory proofs = new bytes32[](0); + assertEq(MerkleMultiProof.merkleRoot(leaves, proofs, 0), leaves[0]); + } + + function test_EmptyLeaf_Revert() public { + bytes32[] memory leaves = new bytes32[](0); + bytes32[] memory proofs = new bytes32[](0); + + vm.expectRevert(abi.encodeWithSelector(MerkleMultiProof.LeavesCannotBeEmpty.selector)); + MerkleMultiProof.merkleRoot(leaves, proofs, 0); + } + + function test_CVE_2023_34459() public { + bytes32[] memory leaves = new bytes32[](2); + // leaves[0] stays uninitialized, i.e., 0x000...0 + leaves[1] = "leaf"; + + bytes32[] memory proof = new bytes32[](2); + proof[0] = leaves[1]; + proof[1] = "will never be used"; + + bytes32[] memory malicious = new bytes32[](2); + malicious[0] = "malicious leaf"; + malicious[1] = "another malicious leaf"; + + vm.expectRevert(abi.encodeWithSelector(MerkleMultiProof.InvalidProof.selector)); + MerkleMultiProof.merkleRoot(malicious, proof, 3); + // Note, that without the revert the above computed root + // would equal MerkleHelper.hashPair(leaves[0], leaves[1]). + } +} diff --git a/contracts/src/v0.8/ccip/test/libraries/RateLimiter.t.sol b/contracts/src/v0.8/ccip/test/libraries/RateLimiter.t.sol new file mode 100644 index 0000000000..da6a6f9ada --- /dev/null +++ b/contracts/src/v0.8/ccip/test/libraries/RateLimiter.t.sol @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {RateLimiterHelper} from "../helpers/RateLimiterHelper.sol"; +import {Test} from "forge-std/Test.sol"; + +contract RateLimiterSetup is Test { + RateLimiterHelper internal s_helper; + RateLimiter.Config internal s_config; + + uint256 internal constant BLOCK_TIME = 1234567890; + + function setUp() public virtual { + s_config = RateLimiter.Config({isEnabled: true, rate: 5, capacity: 100}); + s_helper = new RateLimiterHelper(s_config); + } +} + +contract RateLimiter_constructor is RateLimiterSetup { + function test_Constructor_Success() public view { + RateLimiter.TokenBucket memory rateLimiter = s_helper.getRateLimiter(); + assertEq(s_config.rate, rateLimiter.rate); + assertEq(s_config.capacity, rateLimiter.capacity); + assertEq(s_config.capacity, rateLimiter.tokens); + assertEq(s_config.isEnabled, rateLimiter.isEnabled); + assertEq(BLOCK_TIME, rateLimiter.lastUpdated); + } +} + +contract RateLimiter_setTokenBucketConfig is RateLimiterSetup { + function test_SetRateLimiterConfig_Success() public { + RateLimiter.TokenBucket memory rateLimiter = s_helper.getRateLimiter(); + assertEq(s_config.rate, rateLimiter.rate); + assertEq(s_config.capacity, rateLimiter.capacity); + + s_config = + RateLimiter.Config({isEnabled: true, rate: uint128(rateLimiter.rate * 2), capacity: rateLimiter.capacity * 8}); + + vm.expectEmit(); + emit RateLimiter.ConfigChanged(s_config); + + s_helper.setTokenBucketConfig(s_config); + + rateLimiter = s_helper.getRateLimiter(); + assertEq(s_config.rate, rateLimiter.rate); + assertEq(s_config.capacity, rateLimiter.capacity); + assertEq(s_config.capacity / 8, rateLimiter.tokens); + assertEq(s_config.isEnabled, rateLimiter.isEnabled); + assertEq(BLOCK_TIME, rateLimiter.lastUpdated); + } +} + +contract RateLimiter_currentTokenBucketState is RateLimiterSetup { + function test_CurrentTokenBucketState_Success() public { + RateLimiter.TokenBucket memory bucket = s_helper.currentTokenBucketState(); + assertEq(s_config.rate, bucket.rate); + assertEq(s_config.capacity, bucket.capacity); + assertEq(s_config.capacity, bucket.tokens); + assertEq(s_config.isEnabled, bucket.isEnabled); + assertEq(BLOCK_TIME, bucket.lastUpdated); + + s_config = RateLimiter.Config({isEnabled: true, rate: uint128(bucket.rate * 2), capacity: bucket.capacity * 8}); + + s_helper.setTokenBucketConfig(s_config); + + bucket = s_helper.currentTokenBucketState(); + assertEq(s_config.rate, bucket.rate); + assertEq(s_config.capacity, bucket.capacity); + assertEq(s_config.capacity / 8, bucket.tokens); + assertEq(s_config.isEnabled, bucket.isEnabled); + assertEq(BLOCK_TIME, bucket.lastUpdated); + } + + function test_Refill_Success() public { + RateLimiter.TokenBucket memory bucket = s_helper.currentTokenBucketState(); + assertEq(s_config.rate, bucket.rate); + assertEq(s_config.capacity, bucket.capacity); + assertEq(s_config.capacity, bucket.tokens); + assertEq(s_config.isEnabled, bucket.isEnabled); + assertEq(BLOCK_TIME, bucket.lastUpdated); + + s_config = RateLimiter.Config({isEnabled: true, rate: uint128(bucket.rate * 2), capacity: bucket.capacity * 8}); + + s_helper.setTokenBucketConfig(s_config); + + bucket = s_helper.currentTokenBucketState(); + assertEq(s_config.rate, bucket.rate); + assertEq(s_config.capacity, bucket.capacity); + assertEq(s_config.capacity / 8, bucket.tokens); + assertEq(s_config.isEnabled, bucket.isEnabled); + assertEq(BLOCK_TIME, bucket.lastUpdated); + + uint256 warpTime = 4; + vm.warp(BLOCK_TIME + warpTime); + + bucket = s_helper.currentTokenBucketState(); + + assertEq(s_config.capacity / 8 + warpTime * s_config.rate, bucket.tokens); + + vm.warp(BLOCK_TIME + warpTime * 100); + + // Bucket overflow + bucket = s_helper.currentTokenBucketState(); + assertEq(s_config.capacity, bucket.tokens); + } +} + +contract RateLimiter_consume is RateLimiterSetup { + address internal s_token = address(100); + + function test_ConsumeAggregateValue_Success() public { + RateLimiter.TokenBucket memory rateLimiter = s_helper.getRateLimiter(); + assertEq(s_config.rate, rateLimiter.rate); + assertEq(s_config.capacity, rateLimiter.capacity); + assertEq(s_config.capacity, rateLimiter.tokens); + assertEq(s_config.isEnabled, rateLimiter.isEnabled); + assertEq(BLOCK_TIME, rateLimiter.lastUpdated); + + uint256 requestTokens = 50; + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(requestTokens); + + s_helper.consume(requestTokens, address(0)); + + rateLimiter = s_helper.getRateLimiter(); + assertEq(s_config.rate, rateLimiter.rate); + assertEq(s_config.capacity, rateLimiter.capacity); + assertEq(s_config.capacity - requestTokens, rateLimiter.tokens); + assertEq(s_config.isEnabled, rateLimiter.isEnabled); + assertEq(BLOCK_TIME, rateLimiter.lastUpdated); + } + + function test_ConsumeTokens_Success() public { + uint256 requestTokens = 50; + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(requestTokens); + + s_helper.consume(requestTokens, s_token); + } + + function test_Refill_Success() public { + uint256 requestTokens = 50; + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(requestTokens); + + s_helper.consume(requestTokens, address(0)); + + RateLimiter.TokenBucket memory rateLimiter = s_helper.getRateLimiter(); + assertEq(s_config.rate, rateLimiter.rate); + assertEq(s_config.capacity, rateLimiter.capacity); + assertEq(s_config.capacity - requestTokens, rateLimiter.tokens); + assertEq(s_config.isEnabled, rateLimiter.isEnabled); + assertEq(BLOCK_TIME, rateLimiter.lastUpdated); + + uint256 warpTime = 4; + vm.warp(BLOCK_TIME + warpTime); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(requestTokens); + + s_helper.consume(requestTokens, address(0)); + + rateLimiter = s_helper.getRateLimiter(); + assertEq(s_config.rate, rateLimiter.rate); + assertEq(s_config.capacity, rateLimiter.capacity); + assertEq(s_config.capacity - requestTokens * 2 + warpTime * s_config.rate, rateLimiter.tokens); + assertEq(s_config.isEnabled, rateLimiter.isEnabled); + assertEq(BLOCK_TIME + warpTime, rateLimiter.lastUpdated); + } + + function test_ConsumeUnlimited_Success() public { + s_helper.consume(0, address(0)); + + RateLimiter.TokenBucket memory rateLimiter = s_helper.getRateLimiter(); + assertEq(s_config.capacity, rateLimiter.tokens); + assertEq(s_config.isEnabled, rateLimiter.isEnabled); + + RateLimiter.Config memory disableConfig = RateLimiter.Config({isEnabled: false, rate: 0, capacity: 0}); + + s_helper.setTokenBucketConfig(disableConfig); + + uint256 requestTokens = 50; + s_helper.consume(requestTokens, address(0)); + + rateLimiter = s_helper.getRateLimiter(); + assertEq(disableConfig.capacity, rateLimiter.tokens); + assertEq(disableConfig.isEnabled, rateLimiter.isEnabled); + + s_helper.setTokenBucketConfig(s_config); + + vm.expectRevert(abi.encodeWithSelector(RateLimiter.AggregateValueRateLimitReached.selector, 10, 0)); + s_helper.consume(requestTokens, address(0)); + + rateLimiter = s_helper.getRateLimiter(); + assertEq(s_config.rate, rateLimiter.rate); + assertEq(s_config.capacity, rateLimiter.capacity); + assertEq(0, rateLimiter.tokens); + assertEq(s_config.isEnabled, rateLimiter.isEnabled); + } + + // Reverts + + function test_AggregateValueMaxCapacityExceeded_Revert() public { + RateLimiter.TokenBucket memory rateLimiter = s_helper.getRateLimiter(); + + vm.expectRevert( + abi.encodeWithSelector( + RateLimiter.AggregateValueMaxCapacityExceeded.selector, rateLimiter.capacity, rateLimiter.capacity + 1 + ) + ); + s_helper.consume(rateLimiter.capacity + 1, address(0)); + } + + function test_TokenMaxCapacityExceeded_Revert() public { + RateLimiter.TokenBucket memory rateLimiter = s_helper.getRateLimiter(); + + vm.expectRevert( + abi.encodeWithSelector( + RateLimiter.TokenMaxCapacityExceeded.selector, rateLimiter.capacity, rateLimiter.capacity + 1, s_token + ) + ); + s_helper.consume(rateLimiter.capacity + 1, s_token); + } + + function test_ConsumingMoreThanUint128_Revert() public { + RateLimiter.TokenBucket memory rateLimiter = s_helper.getRateLimiter(); + + uint256 request = uint256(type(uint128).max) + 1; + + vm.expectRevert( + abi.encodeWithSelector(RateLimiter.AggregateValueMaxCapacityExceeded.selector, rateLimiter.capacity, request) + ); + s_helper.consume(request, address(0)); + } + + function test_AggregateValueRateLimitReached_Revert() public { + RateLimiter.TokenBucket memory rateLimiter = s_helper.getRateLimiter(); + + uint256 overLimit = 20; + uint256 requestTokens1 = rateLimiter.capacity / 2; + uint256 requestTokens2 = rateLimiter.capacity / 2 + overLimit; + + uint256 waitInSeconds = overLimit / rateLimiter.rate; + + s_helper.consume(requestTokens1, address(0)); + + vm.expectRevert( + abi.encodeWithSelector( + RateLimiter.AggregateValueRateLimitReached.selector, waitInSeconds, rateLimiter.capacity - requestTokens1 + ) + ); + s_helper.consume(requestTokens2, address(0)); + } + + function test_TokenRateLimitReached_Revert() public { + RateLimiter.TokenBucket memory rateLimiter = s_helper.getRateLimiter(); + + uint256 overLimit = 20; + uint256 requestTokens1 = rateLimiter.capacity / 2; + uint256 requestTokens2 = rateLimiter.capacity / 2 + overLimit; + + uint256 waitInSeconds = overLimit / rateLimiter.rate; + + s_helper.consume(requestTokens1, s_token); + + vm.expectRevert( + abi.encodeWithSelector( + RateLimiter.TokenRateLimitReached.selector, waitInSeconds, rateLimiter.capacity - requestTokens1, s_token + ) + ); + s_helper.consume(requestTokens2, s_token); + } + + function test_RateLimitReachedOverConsecutiveBlocks_Revert() public { + uint256 initBlockTime = BLOCK_TIME + 10000; + vm.warp(initBlockTime); + + RateLimiter.TokenBucket memory rateLimiter = s_helper.getRateLimiter(); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(rateLimiter.capacity); + + s_helper.consume(rateLimiter.capacity, address(0)); + + vm.warp(initBlockTime + 1); + + // Over rate limit by 1, force 1 second wait + uint256 overLimit = 1; + + vm.expectRevert(abi.encodeWithSelector(RateLimiter.AggregateValueRateLimitReached.selector, 1, rateLimiter.rate)); + s_helper.consume(rateLimiter.rate + overLimit, address(0)); + } +} diff --git a/contracts/src/v0.8/ccip/test/mocks/MockCommitStore.sol b/contracts/src/v0.8/ccip/test/mocks/MockCommitStore.sol new file mode 100644 index 0000000000..aff06016fa --- /dev/null +++ b/contracts/src/v0.8/ccip/test/mocks/MockCommitStore.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ICommitStore} from "../../interfaces/ICommitStore.sol"; + +contract MockCommitStore is ICommitStore { + error PausedError(); + + uint64 private s_expectedNextSequenceNumber = 1; + + bool private s_paused = false; + + /// @inheritdoc ICommitStore + function verify( + bytes32[] calldata, + bytes32[] calldata, + uint256 + ) external view whenNotPaused returns (uint256 timestamp) { + return 1; + } + + function getExpectedNextSequenceNumber() external view returns (uint64) { + return s_expectedNextSequenceNumber; + } + + function setExpectedNextSequenceNumber(uint64 nextSeqNum) external { + s_expectedNextSequenceNumber = nextSeqNum; + } + + modifier whenNotPaused() { + if (paused()) revert PausedError(); + _; + } + + function paused() public view returns (bool) { + return s_paused; + } + + function pause() external { + s_paused = true; + } +} diff --git a/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTokenMessenger.sol b/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTokenMessenger.sol new file mode 100644 index 0000000000..9fa5cd1a66 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTokenMessenger.sol @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022, Circle Internet Financial Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +pragma solidity 0.8.24; + +import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; +import {ITokenMessenger} from "../../pools/USDC/ITokenMessenger.sol"; +import {IMessageTransmitterWithRelay} from "./interfaces/IMessageTransmitterWithRelay.sol"; + +// This contract mocks both the ITokenMessenger and IMessageTransmitter +// contracts involved with the Cross Chain Token Protocol. +contract MockE2EUSDCTokenMessenger is ITokenMessenger { + uint32 private immutable i_messageBodyVersion; + address private immutable i_transmitter; + + bytes32 public constant DESTINATION_TOKEN_MESSENGER = keccak256("i_destinationTokenMessenger"); + + uint64 public s_nonce; + + // Local Message Transmitter responsible for sending and receiving messages to/from remote domains + IMessageTransmitterWithRelay public immutable localMessageTransmitterWithRelay; + + constructor(uint32 version, address transmitter) { + i_messageBodyVersion = version; + s_nonce = 1; + i_transmitter = transmitter; + localMessageTransmitterWithRelay = IMessageTransmitterWithRelay(transmitter); + } + + // The mock function is based on the same function in https://github.com/circlefin/evm-cctp-contracts/blob/master/src/TokenMessenger.sol + function depositForBurnWithCaller( + uint256 amount, + uint32 destinationDomain, + bytes32 mintRecipient, + address burnToken, + bytes32 destinationCaller + ) external returns (uint64) { + IBurnMintERC20(burnToken).transferFrom(msg.sender, address(this), amount); + IBurnMintERC20(burnToken).burn(amount); + // Format message body + bytes memory _burnMessage = + abi.encodePacked(i_messageBodyVersion, burnToken, mintRecipient, amount, bytes32(uint256(uint160((msg.sender))))); + s_nonce = + _sendDepositForBurnMessage(destinationDomain, DESTINATION_TOKEN_MESSENGER, destinationCaller, _burnMessage); + emit DepositForBurn( + s_nonce, + burnToken, + amount, + msg.sender, + mintRecipient, + destinationDomain, + DESTINATION_TOKEN_MESSENGER, + destinationCaller + ); + return s_nonce; + } + + function messageBodyVersion() external view returns (uint32) { + return i_messageBodyVersion; + } + + function localMessageTransmitter() external view returns (address) { + return i_transmitter; + } + + /** + * @notice Sends a BurnMessage through the local message transmitter + * @dev calls local message transmitter's sendMessage() function if `_destinationCaller` == bytes32(0), + * or else calls sendMessageWithCaller(). + * @param _destinationDomain destination domain + * @param _destinationTokenMessenger address of registered TokenMessenger contract on destination domain, as bytes32 + * @param _destinationCaller caller on the destination domain, as bytes32. If `_destinationCaller` == bytes32(0), + * any address can call receiveMessage() on destination domain. + * @param _burnMessage formatted BurnMessage bytes (message body) + * @return nonce unique nonce reserved by message + */ + function _sendDepositForBurnMessage( + uint32 _destinationDomain, + bytes32 _destinationTokenMessenger, + bytes32 _destinationCaller, + bytes memory _burnMessage + ) internal returns (uint64 nonce) { + if (_destinationCaller == bytes32(0)) { + return localMessageTransmitterWithRelay.sendMessage(_destinationDomain, _destinationTokenMessenger, _burnMessage); + } else { + return localMessageTransmitterWithRelay.sendMessageWithCaller( + _destinationDomain, _destinationTokenMessenger, _destinationCaller, _burnMessage + ); + } + } +} diff --git a/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTransmitter.sol b/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTransmitter.sol new file mode 100644 index 0000000000..8e50bedea9 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTransmitter.sol @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2022, Circle Internet Financial Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +pragma solidity ^0.8.0; + +import {IMessageTransmitterWithRelay} from "./interfaces/IMessageTransmitterWithRelay.sol"; + +import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; + +contract MockE2EUSDCTransmitter is IMessageTransmitterWithRelay { + // Indicated whether the receiveMessage() call should succeed. + bool public s_shouldSucceed; + uint32 private immutable i_version; + uint32 private immutable i_localDomain; + // Next available nonce from this source domain + uint64 public nextAvailableNonce; + + BurnMintERC677 internal immutable i_token; + + /** + * @notice Emitted when a new message is dispatched + * @param message Raw bytes of message + */ + event MessageSent(bytes message); + + constructor(uint32 _version, uint32 _localDomain, address token) { + i_version = _version; + i_localDomain = _localDomain; + s_shouldSucceed = true; + + i_token = BurnMintERC677(token); + } + + /// @param message The original message on the source chain + /// * Message format: + /// * Field Bytes Type Index + /// * version 4 uint32 0 + /// * sourceDomain 4 uint32 4 + /// * destinationDomain 4 uint32 8 + /// * nonce 8 uint64 12 + /// * sender 32 bytes32 20 + /// * recipient 32 bytes32 52 + /// * destinationCaller 32 bytes32 84 + /// * messageBody dynamic bytes 116 + function receiveMessage(bytes calldata message, bytes calldata) external returns (bool success) { + address recipient = address(bytes20(message[64:84])); + + // We always mint 1000e18 tokens to not complicate the test. + i_token.mint(recipient, 1000e18); + + return s_shouldSucceed; + } + + function setShouldSucceed(bool shouldSucceed) external { + s_shouldSucceed = shouldSucceed; + } + + function version() external view returns (uint32) { + return i_version; + } + + function localDomain() external view returns (uint32) { + return i_localDomain; + } + + /** + * This is based on similar function in https://github.com/circlefin/evm-cctp-contracts/blob/master/src/MessageTransmitter.sol + * @notice Send the message to the destination domain and recipient + * @dev Increment nonce, format the message, and emit `MessageSent` event with message information. + * @param destinationDomain Domain of destination chain + * @param recipient Address of message recipient on destination chain as bytes32 + * @param messageBody Raw bytes content of message + * @return nonce reserved by message + */ + function sendMessage( + uint32 destinationDomain, + bytes32 recipient, + bytes calldata messageBody + ) external returns (uint64) { + bytes32 _emptyDestinationCaller = bytes32(0); + uint64 _nonce = _reserveAndIncrementNonce(); + bytes32 _messageSender = bytes32(uint256(uint160((msg.sender)))); + + _sendMessage(destinationDomain, recipient, _emptyDestinationCaller, _messageSender, _nonce, messageBody); + + return _nonce; + } + + /** + * @notice Send the message to the destination domain and recipient, for a specified `destinationCaller` on the + * destination domain. + * @dev Increment nonce, format the message, and emit `MessageSent` event with message information. + * WARNING: if the `destinationCaller` does not represent a valid address, then it will not be possible + * to broadcast the message on the destination domain. This is an advanced feature, and the standard + * sendMessage() should be preferred for use cases where a specific destination caller is not required. + * @param destinationDomain Domain of destination chain + * @param recipient Address of message recipient on destination domain as bytes32 + * @param destinationCaller caller on the destination domain, as bytes32 + * @param messageBody Raw bytes content of message + * @return nonce reserved by message + */ + function sendMessageWithCaller( + uint32 destinationDomain, + bytes32 recipient, + bytes32 destinationCaller, + bytes calldata messageBody + ) external returns (uint64) { + require(destinationCaller != bytes32(0), "Destination caller must be nonzero"); + + uint64 _nonce = _reserveAndIncrementNonce(); + bytes32 _messageSender = bytes32(uint256(uint160((msg.sender)))); + + _sendMessage(destinationDomain, recipient, destinationCaller, _messageSender, _nonce, messageBody); + + return _nonce; + } + + /** + * Reserve and increment next available nonce + * @return nonce reserved + */ + function _reserveAndIncrementNonce() internal returns (uint64) { + uint64 _nonceReserved = nextAvailableNonce; + nextAvailableNonce = nextAvailableNonce + 1; + return _nonceReserved; + } + + /** + * @notice Send the message to the destination domain and recipient. If `_destinationCaller` is not equal to bytes32(0), + * the message can only be received on the destination chain when called by `_destinationCaller`. + * @dev Format the message and emit `MessageSent` event with message information. + * @param _destinationDomain Domain of destination chain + * @param _recipient Address of message recipient on destination domain as bytes32 + * @param _destinationCaller caller on the destination domain, as bytes32 + * @param _sender message sender, as bytes32 + * @param _nonce nonce reserved for message + * @param _messageBody Raw bytes content of message + */ + function _sendMessage( + uint32 _destinationDomain, + bytes32 _recipient, + bytes32 _destinationCaller, + bytes32 _sender, + uint64 _nonce, + bytes calldata _messageBody + ) internal { + require(_recipient != bytes32(0), "Recipient must be nonzero"); + // serialize message + bytes memory _message = abi.encodePacked( + i_version, i_localDomain, _destinationDomain, _nonce, _sender, _recipient, _destinationCaller, _messageBody + ); + + // Emit MessageSent event + emit MessageSent(_message); + } +} diff --git a/contracts/src/v0.8/ccip/test/mocks/MockRMN.sol b/contracts/src/v0.8/ccip/test/mocks/MockRMN.sol new file mode 100644 index 0000000000..3f7b0200e6 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/mocks/MockRMN.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {RMN} from "../../RMN.sol"; +import {IRMN} from "../../interfaces/IRMN.sol"; +import {OwnerIsCreator} from "./../../../shared/access/OwnerIsCreator.sol"; + +/// @notice WARNING: This contract is to be only used for testing, all methods are unprotected. +contract MockRMN is IRMN { + error CustomError(bytes err); + + bytes private s_isCursedRevert; + + bool private s_globalCursed; + mapping(bytes16 subject => bool cursed) private s_cursedBySubject; + mapping(address commitStore => mapping(bytes32 root => bool blessed)) private s_blessedByRoot; + + function setTaggedRootBlessed(IRMN.TaggedRoot calldata taggedRoot, bool blessed) external { + s_blessedByRoot[taggedRoot.commitStore][taggedRoot.root] = blessed; + } + + function setGlobalCursed(bool cursed) external { + s_globalCursed = cursed; + } + + function setChainCursed(uint64 chainSelector, bool cursed) external { + s_cursedBySubject[bytes16(uint128(chainSelector))] = cursed; + } + + /// @notice Setting a revert error with length of 0 will disable reverts + /// @dev Useful to test revert handling of ARMProxy + function setIsCursedRevert(bytes calldata revertErr) external { + s_isCursedRevert = revertErr; + } + + // IRMN implementation follows + + function isCursed() external view returns (bool) { + if (s_isCursedRevert.length > 0) { + revert CustomError(s_isCursedRevert); + } + return s_globalCursed; + } + + function isCursed(bytes16 subject) external view returns (bool) { + if (s_isCursedRevert.length > 0) { + revert CustomError(s_isCursedRevert); + } + return s_globalCursed || s_cursedBySubject[subject]; + } + + function isBlessed(IRMN.TaggedRoot calldata taggedRoot) external view returns (bool) { + return s_blessedByRoot[taggedRoot.commitStore][taggedRoot.root]; + } +} diff --git a/contracts/src/v0.8/ccip/test/mocks/MockRMN1_0.sol b/contracts/src/v0.8/ccip/test/mocks/MockRMN1_0.sol new file mode 100644 index 0000000000..44ffc23b78 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/mocks/MockRMN1_0.sol @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IRMN} from "../../interfaces/IRMN.sol"; +import {OwnerIsCreator} from "./../../../shared/access/OwnerIsCreator.sol"; + +// Inlined from RMN 1.0 contract. +// solhint-disable gas-struct-packing +contract RMN { + struct Voter { + address blessVoteAddr; + address curseVoteAddr; + address curseUnvoteAddr; + uint8 blessWeight; + uint8 curseWeight; + } + + struct Config { + Voter[] voters; + uint16 blessWeightThreshold; + uint16 curseWeightThreshold; + } + + struct VersionedConfig { + Config config; + uint32 configVersion; + uint32 blockNumber; + } + + struct UnvoteToCurseRecord { + address curseVoteAddr; + bytes32 cursesHash; + bool forceUnvote; + } +} + +/// @dev Retained almost as-is from commit 88f285b94c23d0c684d337064758a5edde380fe2 for compatibility with offchain +/// tests and scripts. Internal structs of the RMN 1.0 contract that were depended on have been inlined. +/// @dev This contract should no longer be used for any new tests or scripts. +/// @notice WARNING: This contract is to be only used for testing, all methods are unprotected. +// TODO: remove this contract when tests and scripts are updated +contract MockRMN is IRMN, OwnerIsCreator { + error CustomError(bytes err); + + bool private s_curse; + bytes private s_err; + RMN.VersionedConfig private s_versionedConfig; + mapping(bytes16 subject => bool cursed) private s_curseBySubject; + + function isCursed() external view override returns (bool) { + if (s_err.length != 0) { + revert CustomError(s_err); + } + return s_curse; + } + + function isCursed(bytes16 subject) external view override returns (bool) { + if (s_err.length != 0) { + revert CustomError(s_err); + } + return s_curse || s_curseBySubject[subject]; + } + + function voteToCurse(bytes32) external { + s_curse = true; + } + + function voteToCurse(bytes32, bytes16 subject) external { + s_curseBySubject[subject] = true; + } + + function ownerUnvoteToCurse(RMN.UnvoteToCurseRecord[] memory) external { + s_curse = false; + } + + function ownerUnvoteToCurse(RMN.UnvoteToCurseRecord[] memory, bytes16 subject) external { + s_curseBySubject[subject] = false; + } + + function setRevert(bytes memory err) external { + s_err = err; + } + + function isBlessed(IRMN.TaggedRoot calldata) external view override returns (bool) { + return !s_curse; + } + + function getConfigDetails() external view returns (uint32 version, uint32 blockNumber, RMN.Config memory config) { + return (s_versionedConfig.configVersion, s_versionedConfig.blockNumber, s_versionedConfig.config); + } +} diff --git a/contracts/src/v0.8/ccip/test/mocks/MockRouter.sol b/contracts/src/v0.8/ccip/test/mocks/MockRouter.sol new file mode 100644 index 0000000000..87db031951 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/mocks/MockRouter.sol @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IAny2EVMMessageReceiver} from "../../interfaces/IAny2EVMMessageReceiver.sol"; +import {IRouter} from "../../interfaces/IRouter.sol"; +import {IRouterClient} from "../../interfaces/IRouterClient.sol"; + +import {CallWithExactGas} from "../../../shared/call/CallWithExactGas.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {ERC165Checker} from + "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol"; + +contract MockCCIPRouter is IRouter, IRouterClient { + using SafeERC20 for IERC20; + using ERC165Checker for address; + + error InvalidAddress(bytes encodedAddress); + error InvalidExtraArgsTag(); + error ReceiverError(bytes err); + + event MessageExecuted(bytes32 messageId, uint64 sourceChainSelector, address offRamp, bytes32 calldataHash); + event MsgExecuted(bool success, bytes retData, uint256 gasUsed); + + uint16 public constant GAS_FOR_CALL_EXACT_CHECK = 5_000; + uint32 public constant DEFAULT_GAS_LIMIT = 200_000; + + uint256 internal s_mockFeeTokenAmount; //use setFee() to change to non-zero to test fees + + function routeMessage( + Client.Any2EVMMessage calldata message, + uint16 gasForCallExactCheck, + uint256 gasLimit, + address receiver + ) external returns (bool success, bytes memory retData, uint256 gasUsed) { + return _routeMessage(message, gasForCallExactCheck, gasLimit, receiver); + } + + function _routeMessage( + Client.Any2EVMMessage memory message, + uint16 gasForCallExactCheck, + uint256 gasLimit, + address receiver + ) internal returns (bool success, bytes memory retData, uint256 gasUsed) { + // Only send through the router if the receiver is a contract and implements the IAny2EVMMessageReceiver interface. + if (receiver.code.length == 0 || !receiver.supportsInterface(type(IAny2EVMMessageReceiver).interfaceId)) { + return (true, "", 0); + } + + bytes memory data = abi.encodeWithSelector(IAny2EVMMessageReceiver.ccipReceive.selector, message); + + (success, retData, gasUsed) = CallWithExactGas._callWithExactGasSafeReturnData( + data, receiver, gasLimit, gasForCallExactCheck, Internal.MAX_RET_BYTES + ); + + // Event to assist testing, does not exist on real deployments + emit MsgExecuted(success, retData, gasUsed); + + // Real router event + emit MessageExecuted(message.messageId, message.sourceChainSelector, msg.sender, keccak256(data)); + return (success, retData, gasUsed); + } + + /// @notice Sends the tx locally to the receiver instead of on the destination chain. + /// @dev Ignores destinationChainSelector + /// @dev Returns a mock message ID, which is not calculated from the message contents in the + /// same way as the real message ID. + function ccipSend( + uint64 destinationChainSelector, + Client.EVM2AnyMessage calldata message + ) external payable returns (bytes32) { + if (message.receiver.length != 32) revert InvalidAddress(message.receiver); + uint256 decodedReceiver = abi.decode(message.receiver, (uint256)); + // We want to disallow sending to address(0) and to precompiles, which exist on address(1) through address(9). + if (decodedReceiver > type(uint160).max || decodedReceiver < 10) revert InvalidAddress(message.receiver); + + uint256 feeTokenAmount = getFee(destinationChainSelector, message); + if (message.feeToken == address(0)) { + if (msg.value < feeTokenAmount) revert InsufficientFeeTokenAmount(); + } else { + if (msg.value > 0) revert InvalidMsgValue(); + IERC20(message.feeToken).safeTransferFrom(msg.sender, address(this), feeTokenAmount); + } + + address receiver = address(uint160(decodedReceiver)); + uint256 gasLimit = _fromBytes(message.extraArgs).gasLimit; + bytes32 mockMsgId = keccak256(abi.encode(message)); + + Client.Any2EVMMessage memory executableMsg = Client.Any2EVMMessage({ + messageId: mockMsgId, + sourceChainSelector: 16015286601757825753, // Sepolia + sender: abi.encode(msg.sender), + data: message.data, + destTokenAmounts: message.tokenAmounts + }); + + for (uint256 i = 0; i < message.tokenAmounts.length; ++i) { + IERC20(message.tokenAmounts[i].token).safeTransferFrom(msg.sender, receiver, message.tokenAmounts[i].amount); + } + + (bool success, bytes memory retData,) = _routeMessage(executableMsg, GAS_FOR_CALL_EXACT_CHECK, gasLimit, receiver); + + if (!success) revert ReceiverError(retData); + + return mockMsgId; + } + + function _fromBytes(bytes calldata extraArgs) internal pure returns (Client.EVMExtraArgsV1 memory) { + if (extraArgs.length == 0) { + return Client.EVMExtraArgsV1({gasLimit: DEFAULT_GAS_LIMIT}); + } + if (bytes4(extraArgs) != Client.EVM_EXTRA_ARGS_V1_TAG) revert InvalidExtraArgsTag(); + return abi.decode(extraArgs[4:], (Client.EVMExtraArgsV1)); + } + + /// @notice Always returns true to make sure this check can be performed on any chain. + function isChainSupported(uint64) external pure returns (bool supported) { + return true; + } + + /// @notice Returns an empty array. + function getSupportedTokens(uint64) external pure returns (address[] memory tokens) { + return new address[](0); + } + + /// @notice Returns 0 as the fee is not supported in this mock contract. + function getFee(uint64, Client.EVM2AnyMessage memory) public view returns (uint256) { + return s_mockFeeTokenAmount; + } + + /// @notice Sets the fees returned by getFee but is only checked when using native fee tokens + function setFee(uint256 feeAmount) external { + s_mockFeeTokenAmount = feeAmount; + } + + /// @notice Always returns address(1234567890) + function getOnRamp(uint64 /* destChainSelector */ ) external pure returns (address onRampAddress) { + return address(1234567890); + } + + /// @notice Always returns true + function isOffRamp(uint64, /* sourceChainSelector */ address /* offRamp */ ) external pure returns (bool) { + return true; + } +} diff --git a/contracts/src/v0.8/ccip/test/mocks/MockUSDCTokenMessenger.sol b/contracts/src/v0.8/ccip/test/mocks/MockUSDCTokenMessenger.sol new file mode 100644 index 0000000000..562a9f467f --- /dev/null +++ b/contracts/src/v0.8/ccip/test/mocks/MockUSDCTokenMessenger.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; +import {ITokenMessenger} from "../../pools/USDC/ITokenMessenger.sol"; + +// This contract mocks both the ITokenMessenger and IMessageTransmitter +// contracts involved with the Cross Chain Token Protocol. +contract MockUSDCTokenMessenger is ITokenMessenger { + uint32 private immutable i_messageBodyVersion; + address private immutable i_transmitter; + + bytes32 public constant DESTINATION_TOKEN_MESSENGER = keccak256("i_destinationTokenMessenger"); + + uint64 public s_nonce; + + constructor(uint32 version, address transmitter) { + i_messageBodyVersion = version; + s_nonce = 1; + i_transmitter = transmitter; + } + + function depositForBurnWithCaller( + uint256 amount, + uint32 destinationDomain, + bytes32 mintRecipient, + address burnToken, + bytes32 destinationCaller + ) external returns (uint64) { + IBurnMintERC20(burnToken).transferFrom(msg.sender, address(this), amount); + IBurnMintERC20(burnToken).burn(amount); + emit DepositForBurn( + s_nonce, + burnToken, + amount, + msg.sender, + mintRecipient, + destinationDomain, + DESTINATION_TOKEN_MESSENGER, + destinationCaller + ); + return s_nonce++; + } + + function messageBodyVersion() external view returns (uint32) { + return i_messageBodyVersion; + } + + function localMessageTransmitter() external view returns (address) { + return i_transmitter; + } +} diff --git a/contracts/src/v0.8/ccip/test/mocks/interfaces/IMessageTransmitterWithRelay.sol b/contracts/src/v0.8/ccip/test/mocks/interfaces/IMessageTransmitterWithRelay.sol new file mode 100644 index 0000000000..dc9c644e07 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/mocks/interfaces/IMessageTransmitterWithRelay.sol @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022, Circle Internet Financial Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +pragma solidity ^0.8.0; + +import {IMessageTransmitter} from "../../../pools/USDC/IMessageTransmitter.sol"; + +// This follows https://github.com/circlefin/evm-cctp-contracts/blob/master/src/interfaces/IMessageTransmitter.sol +interface IMessageTransmitterWithRelay is IMessageTransmitter { + /** + * @notice Sends an outgoing message from the source domain. + * @dev Increment nonce, format the message, and emit `MessageSent` event with message information. + * @param destinationDomain Domain of destination chain + * @param recipient Address of message recipient on destination domain as bytes32 + * @param messageBody Raw bytes content of message + * @return nonce reserved by message + */ + function sendMessage( + uint32 destinationDomain, + bytes32 recipient, + bytes calldata messageBody + ) external returns (uint64); + + /** + * @notice Sends an outgoing message from the source domain, with a specified caller on the + * destination domain. + * @dev Increment nonce, format the message, and emit `MessageSent` event with message information. + * WARNING: if the `destinationCaller` does not represent a valid address as bytes32, then it will not be possible + * to broadcast the message on the destination domain. This is an advanced feature, and the standard + * sendMessage() should be preferred for use cases where a specific destination caller is not required. + * @param destinationDomain Domain of destination chain + * @param recipient Address of message recipient on destination domain as bytes32 + * @param destinationCaller caller on the destination domain, as bytes32 + * @param messageBody Raw bytes content of message + * @return nonce reserved by message + */ + function sendMessageWithCaller( + uint32 destinationDomain, + bytes32 recipient, + bytes32 destinationCaller, + bytes calldata messageBody + ) external returns (uint64); +} diff --git a/contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol b/contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol new file mode 100644 index 0000000000..91798b494d --- /dev/null +++ b/contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol @@ -0,0 +1,68 @@ +pragma solidity ^0.8.0; + +import {Client} from "../../../libraries/Client.sol"; + +import {TokenSetup} from "../../TokenSetup.t.sol"; +import {IRouter, IRouterClient, MockCCIPRouter} from "../MockRouter.sol"; + +import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +contract MockRouterTest is TokenSetup { + using SafeERC20 for IERC20; + + MockCCIPRouter public mockRouter; + + uint64 public constant mockChainSelector = 123456; + + Client.EVM2AnyMessage public message; + + function setUp() public override { + mockRouter = new MockCCIPRouter(); + + //Configure the Fee to 0.1 ether for native token fees + mockRouter.setFee(0.1 ether); + + deal(address(this), 100 ether); + + message.receiver = abi.encode(address(0x12345)); + message.data = abi.encode("Hello World"); + + s_sourceFeeToken = _deploySourceToken("sLINK", type(uint256).max, 18); + } + + function test_ccipSendWithInsufficientNativeTokens_Revert() public { + //Should revert because did not include sufficient eth to pay for fees + vm.expectRevert(IRouterClient.InsufficientFeeTokenAmount.selector); + mockRouter.ccipSend(mockChainSelector, message); + } + + function test_ccipSendWithSufficientNativeFeeTokens_Success() public { + //ccipSend with sufficient native tokens for fees + mockRouter.ccipSend{value: 0.1 ether}(mockChainSelector, message); + } + + function test_ccipSendWithInvalidMsgValue_Revert() public { + message.feeToken = address(1); //Set to non native-token fees + + vm.expectRevert(IRouterClient.InvalidMsgValue.selector); + mockRouter.ccipSend{value: 0.1 ether}(mockChainSelector, message); + } + + function test_ccipSendWithLinkFeeTokenbutInsufficientAllowance_Revert() public { + message.feeToken = s_sourceFeeToken; + + vm.expectRevert(bytes("ERC20: insufficient allowance")); + mockRouter.ccipSend(mockChainSelector, message); + } + + function test_ccipSendWithLinkFeeTokenAndValidMsgValue_Success() public { + message.feeToken = s_sourceFeeToken; + + vm.startPrank(OWNER, OWNER); + + IERC20(s_sourceFeeToken).safeApprove(address(mockRouter), type(uint256).max); + + mockRouter.ccipSend(mockChainSelector, message); + } +} diff --git a/contracts/src/v0.8/ccip/test/ocr/MultiOCR3Base.t.sol b/contracts/src/v0.8/ccip/test/ocr/MultiOCR3Base.t.sol new file mode 100644 index 0000000000..5b784bf721 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/ocr/MultiOCR3Base.t.sol @@ -0,0 +1,921 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {MultiOCR3Base} from "../../ocr/MultiOCR3Base.sol"; +import {MultiOCR3Helper} from "../helpers/MultiOCR3Helper.sol"; +import {MultiOCR3BaseSetup} from "./MultiOCR3BaseSetup.t.sol"; + +import {Vm} from "forge-std/Vm.sol"; + +contract MultiOCR3Base_transmit is MultiOCR3BaseSetup { + bytes32 internal s_configDigest1; + bytes32 internal s_configDigest2; + bytes32 internal s_configDigest3; + + function setUp() public virtual override { + super.setUp(); + + s_configDigest1 = _getBasicConfigDigest(1, s_validSigners, s_validTransmitters); + s_configDigest2 = _getBasicConfigDigest(1, s_validSigners, s_validTransmitters); + s_configDigest3 = _getBasicConfigDigest(2, s_emptySigners, s_validTransmitters); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](3); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: s_configDigest1, + F: 1, + isSignatureVerificationEnabled: true, + signers: s_validSigners, + transmitters: s_validTransmitters + }); + ocrConfigs[1] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 1, + configDigest: s_configDigest2, + F: 2, + isSignatureVerificationEnabled: true, + signers: s_validSigners, + transmitters: s_validTransmitters + }); + ocrConfigs[2] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 2, + configDigest: s_configDigest3, + F: 1, + isSignatureVerificationEnabled: false, + signers: s_emptySigners, + transmitters: s_validTransmitters + }); + + s_multiOCR3.setOCR3Configs(ocrConfigs); + } + + function test_TransmitSigners_gas_Success() public { + vm.pauseGasMetering(); + bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; + + // F = 2, need 2 signatures + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 2); + + s_multiOCR3.setTransmitOcrPluginType(0); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(0, s_configDigest1, uint64(uint256(s_configDigest1))); + + vm.startPrank(s_validTransmitters[1]); + vm.resumeGasMetering(); + s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, rawVs); + } + + function test_TransmitWithoutSignatureVerification_gas_Success() public { + vm.pauseGasMetering(); + bytes32[3] memory reportContext = [s_configDigest3, s_configDigest3, s_configDigest3]; + + s_multiOCR3.setTransmitOcrPluginType(2); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(2, s_configDigest3, uint64(uint256(s_configDigest3))); + + vm.startPrank(s_validTransmitters[0]); + vm.resumeGasMetering(); + s_multiOCR3.transmitWithoutSignatures(reportContext, REPORT); + } + + function test_Fuzz_TransmitSignersWithSignatures_Success(uint8 F, uint64 randomAddressOffset) public { + vm.pauseGasMetering(); + + F = uint8(bound(F, 1, 3)); + + // condition: signers.length > 3F + uint8 signersLength = 3 * F + 1; + address[] memory signers = new address[](signersLength); + address[] memory transmitters = new address[](signersLength); + uint256[] memory signerKeys = new uint256[](signersLength); + + // Force addresses to be unique (with a random offset for broader testing) + for (uint160 i = 0; i < signersLength; ++i) { + transmitters[i] = vm.addr(PRIVATE0 + randomAddressOffset + i); + // condition: non-zero oracle address + vm.assume(transmitters[i] != address(0)); + + // condition: non-repeating addresses (no clashes with transmitters) + signerKeys[i] = PRIVATE0 + randomAddressOffset + i + signersLength; + signers[i] = vm.addr(signerKeys[i]); + vm.assume(signers[i] != address(0)); + } + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 3, + configDigest: s_configDigest1, + F: F, + isSignatureVerificationEnabled: true, + signers: signers, + transmitters: transmitters + }); + s_multiOCR3.setOCR3Configs(ocrConfigs); + s_multiOCR3.setTransmitOcrPluginType(3); + + // Randomise picked transmitter with random offset + vm.startPrank(transmitters[randomAddressOffset % signersLength]); + + bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; + + // condition: matches signature expectation for transmit + uint8 numSignatures = F + 1; + uint256[] memory pickedSignerKeys = new uint256[](numSignatures); + + // Randomise picked signers with random offset + for (uint256 i; i < numSignatures; ++i) { + pickedSignerKeys[i] = signerKeys[(i + randomAddressOffset) % numSignatures]; + } + + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(pickedSignerKeys, REPORT, reportContext, numSignatures); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(3, s_configDigest1, uint64(uint256(s_configDigest1))); + + vm.resumeGasMetering(); + s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, rawVs); + } + + // Reverts + function test_ForkedChain_Revert() public { + bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; + + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 2); + + s_multiOCR3.setTransmitOcrPluginType(0); + + uint256 chain1 = block.chainid; + uint256 chain2 = chain1 + 1; + vm.chainId(chain2); + vm.expectRevert(abi.encodeWithSelector(MultiOCR3Base.ForkedChain.selector, chain1, chain2)); + + vm.startPrank(s_validTransmitters[0]); + s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, rawVs); + } + + function test_ZeroSignatures_Revert() public { + bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; + + s_multiOCR3.setTransmitOcrPluginType(0); + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(MultiOCR3Base.WrongNumberOfSignatures.selector); + s_multiOCR3.transmitWithSignatures(reportContext, REPORT, new bytes32[](0), new bytes32[](0), bytes32("")); + } + + function test_TooManySignatures_Revert() public { + bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; + + // 1 signature too many + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 6); + + s_multiOCR3.setTransmitOcrPluginType(1); + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(MultiOCR3Base.WrongNumberOfSignatures.selector); + s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, rawVs); + } + + function test_InsufficientSignatures_Revert() public { + bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; + + // Missing 1 signature for unique report + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 4); + + s_multiOCR3.setTransmitOcrPluginType(1); + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(MultiOCR3Base.WrongNumberOfSignatures.selector); + s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, rawVs); + } + + function test_ConfigDigestMismatch_Revert() public { + bytes32 configDigest; + bytes32[3] memory reportContext = [configDigest, configDigest, configDigest]; + + (,,, bytes32 rawVs) = _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 2); + + s_multiOCR3.setTransmitOcrPluginType(0); + + vm.expectRevert(abi.encodeWithSelector(MultiOCR3Base.ConfigDigestMismatch.selector, s_configDigest1, configDigest)); + s_multiOCR3.transmitWithSignatures(reportContext, REPORT, new bytes32[](0), new bytes32[](0), rawVs); + } + + function test_SignatureOutOfRegistration_Revert() public { + bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; + + bytes32[] memory rs = new bytes32[](2); + bytes32[] memory ss = new bytes32[](1); + + s_multiOCR3.setTransmitOcrPluginType(0); + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(MultiOCR3Base.SignaturesOutOfRegistration.selector); + s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, bytes32("")); + } + + function test_UnAuthorizedTransmitter_Revert() public { + bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; + bytes32[] memory rs = new bytes32[](2); + bytes32[] memory ss = new bytes32[](2); + + s_multiOCR3.setTransmitOcrPluginType(0); + + vm.expectRevert(MultiOCR3Base.UnauthorizedTransmitter.selector); + s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, bytes32("")); + } + + function test_NonUniqueSignature_Revert() public { + bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; + + (bytes32[] memory rs, bytes32[] memory ss, uint8[] memory vs, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 2); + + rs[1] = rs[0]; + ss[1] = ss[0]; + // Need to reset the rawVs to be valid + rawVs = bytes32(bytes1(vs[0] - 27)) | (bytes32(bytes1(vs[0] - 27)) >> 8); + + s_multiOCR3.setTransmitOcrPluginType(0); + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(MultiOCR3Base.NonUniqueSignatures.selector); + s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, rawVs); + } + + function test_UnauthorizedSigner_Revert() public { + bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; + + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, REPORT, reportContext, 2); + + rs[0] = s_configDigest1; + ss = rs; + + s_multiOCR3.setTransmitOcrPluginType(0); + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(MultiOCR3Base.UnauthorizedSigner.selector); + s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, rawVs); + } + + function test_UnconfiguredPlugin_Revert() public { + bytes32 configDigest; + bytes32[3] memory reportContext = [configDigest, configDigest, configDigest]; + + s_multiOCR3.setTransmitOcrPluginType(42); + + vm.expectRevert(MultiOCR3Base.UnauthorizedTransmitter.selector); + s_multiOCR3.transmitWithoutSignatures(reportContext, REPORT); + } + + function test_TransmitWithLessCalldataArgs_Revert() public { + bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; + + s_multiOCR3.setTransmitOcrPluginType(0); + + // The transmit should fail, since we are trying to transmit without signatures when signatures are enabled + vm.startPrank(s_validTransmitters[1]); + + // report length + function selector + report length + abiencoded location of report value + report context words + uint256 receivedLength = REPORT.length + 4 + 5 * 32; + vm.expectRevert( + abi.encodeWithSelector( + MultiOCR3Base.WrongMessageLength.selector, + // Expecting inclusion of signature constant length components + receivedLength + 5 * 32, + receivedLength + ) + ); + s_multiOCR3.transmitWithoutSignatures(reportContext, REPORT); + } + + function test_TransmitWithExtraCalldataArgs_Revert() public { + bytes32[3] memory reportContext = [s_configDigest1, s_configDigest1, s_configDigest1]; + bytes32[] memory rs = new bytes32[](2); + bytes32[] memory ss = new bytes32[](2); + + s_multiOCR3.setTransmitOcrPluginType(2); + + // The transmit should fail, since we are trying to transmit with signatures when signatures are disabled + vm.startPrank(s_validTransmitters[1]); + + // dynamic length + function selector + report length + abiencoded location of report value + report context words + // rawVs value, lengths of rs, ss, and start locations of rs & ss -> 5 words + uint256 receivedLength = REPORT.length + 4 + (5 * 32) + (5 * 32) + (2 * 32) + (2 * 32); + vm.expectRevert( + abi.encodeWithSelector( + MultiOCR3Base.WrongMessageLength.selector, + // Expecting exclusion of signature constant length components and rs, ss words + receivedLength - (5 * 32) - (4 * 32), + receivedLength + ) + ); + s_multiOCR3.transmitWithSignatures(reportContext, REPORT, rs, ss, bytes32("")); + } +} + +contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { + function test_SetConfigsZeroInput_Success() public { + vm.recordLogs(); + s_multiOCR3.setOCR3Configs(new MultiOCR3Base.OCRConfigArgs[](0)); + + // No logs emitted + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + assertEq(logEntries.length, 0); + } + + function test_SetConfigWithSigners_Success() public { + uint8 F = 2; + + _assertOCRConfigUnconfigured(s_multiOCR3.latestConfigDetails(0)); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(F, s_validSigners, s_validTransmitters), + F: F, + isSignatureVerificationEnabled: true, + signers: s_validSigners, + transmitters: s_validTransmitters + }); + + vm.expectEmit(); + emit MultiOCR3Base.ConfigSet( + ocrConfigs[0].ocrPluginType, + ocrConfigs[0].configDigest, + ocrConfigs[0].signers, + ocrConfigs[0].transmitters, + ocrConfigs[0].F + ); + + vm.expectEmit(); + emit MultiOCR3Helper.AfterConfigSet(ocrConfigs[0].ocrPluginType); + + s_multiOCR3.setOCR3Configs(ocrConfigs); + + MultiOCR3Base.OCRConfig memory expectedConfig = MultiOCR3Base.OCRConfig({ + configInfo: MultiOCR3Base.ConfigInfo({ + configDigest: ocrConfigs[0].configDigest, + F: ocrConfigs[0].F, + n: uint8(ocrConfigs[0].signers.length), + isSignatureVerificationEnabled: ocrConfigs[0].isSignatureVerificationEnabled + }), + signers: s_validSigners, + transmitters: s_validTransmitters + }); + _assertOCRConfigEquality(s_multiOCR3.latestConfigDetails(0), expectedConfig); + } + + function test_SetConfigWithoutSigners_Success() public { + uint8 F = 1; + address[] memory signers = new address[](0); + + _assertOCRConfigUnconfigured(s_multiOCR3.latestConfigDetails(0)); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(F, signers, s_validTransmitters), + F: F, + isSignatureVerificationEnabled: false, + signers: signers, + transmitters: s_validTransmitters + }); + + vm.expectEmit(); + emit MultiOCR3Base.ConfigSet( + ocrConfigs[0].ocrPluginType, + ocrConfigs[0].configDigest, + ocrConfigs[0].signers, + ocrConfigs[0].transmitters, + ocrConfigs[0].F + ); + + vm.expectEmit(); + emit MultiOCR3Helper.AfterConfigSet(ocrConfigs[0].ocrPluginType); + + s_multiOCR3.setOCR3Configs(ocrConfigs); + + MultiOCR3Base.OCRConfig memory expectedConfig = MultiOCR3Base.OCRConfig({ + configInfo: MultiOCR3Base.ConfigInfo({ + configDigest: ocrConfigs[0].configDigest, + F: ocrConfigs[0].F, + n: uint8(ocrConfigs[0].signers.length), + isSignatureVerificationEnabled: ocrConfigs[0].isSignatureVerificationEnabled + }), + signers: signers, + transmitters: s_validTransmitters + }); + _assertOCRConfigEquality(s_multiOCR3.latestConfigDetails(0), expectedConfig); + } + + function test_SetConfigIgnoreSigners_Success() public { + uint8 F = 1; + + _assertOCRConfigUnconfigured(s_multiOCR3.latestConfigDetails(0)); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(F, new address[](0), s_validTransmitters), + F: F, + isSignatureVerificationEnabled: false, + signers: s_validSigners, + transmitters: s_validTransmitters + }); + + vm.expectEmit(); + emit MultiOCR3Base.ConfigSet( + ocrConfigs[0].ocrPluginType, + ocrConfigs[0].configDigest, + s_emptySigners, + ocrConfigs[0].transmitters, + ocrConfigs[0].F + ); + + vm.expectEmit(); + emit MultiOCR3Helper.AfterConfigSet(ocrConfigs[0].ocrPluginType); + + s_multiOCR3.setOCR3Configs(ocrConfigs); + + MultiOCR3Base.OCRConfig memory expectedConfig = MultiOCR3Base.OCRConfig({ + configInfo: MultiOCR3Base.ConfigInfo({ + configDigest: ocrConfigs[0].configDigest, + F: ocrConfigs[0].F, + n: 0, + isSignatureVerificationEnabled: ocrConfigs[0].isSignatureVerificationEnabled + }), + signers: s_emptySigners, + transmitters: s_validTransmitters + }); + _assertOCRConfigEquality(s_multiOCR3.latestConfigDetails(0), expectedConfig); + + // Verify no signer role is set + for (uint256 i = 0; i < s_validSigners.length; ++i) { + MultiOCR3Base.Oracle memory signerOracle = s_multiOCR3.getOracle(0, s_validSigners[i]); + assertEq(uint8(signerOracle.role), uint8(MultiOCR3Base.Role.Unset)); + } + } + + function test_SetMultipleConfigs_Success() public { + _assertOCRConfigUnconfigured(s_multiOCR3.latestConfigDetails(0)); + _assertOCRConfigUnconfigured(s_multiOCR3.latestConfigDetails(1)); + _assertOCRConfigUnconfigured(s_multiOCR3.latestConfigDetails(2)); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](3); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(2, s_validSigners, s_validTransmitters), + F: 2, + isSignatureVerificationEnabled: true, + signers: s_validSigners, + transmitters: s_validTransmitters + }); + ocrConfigs[1] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 1, + configDigest: _getBasicConfigDigest(1, s_validSigners, s_validTransmitters), + F: 1, + isSignatureVerificationEnabled: true, + signers: s_validSigners, + transmitters: s_validTransmitters + }); + ocrConfigs[2] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 2, + configDigest: _getBasicConfigDigest(1, s_partialSigners, s_partialTransmitters), + F: 1, + isSignatureVerificationEnabled: true, + signers: s_partialSigners, + transmitters: s_partialTransmitters + }); + + for (uint256 i; i < ocrConfigs.length; ++i) { + vm.expectEmit(); + emit MultiOCR3Base.ConfigSet( + ocrConfigs[i].ocrPluginType, + ocrConfigs[i].configDigest, + ocrConfigs[i].signers, + ocrConfigs[i].transmitters, + ocrConfigs[i].F + ); + + vm.expectEmit(); + emit MultiOCR3Helper.AfterConfigSet(ocrConfigs[i].ocrPluginType); + } + s_multiOCR3.setOCR3Configs(ocrConfigs); + + for (uint256 i; i < ocrConfigs.length; ++i) { + MultiOCR3Base.OCRConfig memory expectedConfig = MultiOCR3Base.OCRConfig({ + configInfo: MultiOCR3Base.ConfigInfo({ + configDigest: ocrConfigs[i].configDigest, + F: ocrConfigs[i].F, + n: uint8(ocrConfigs[i].signers.length), + isSignatureVerificationEnabled: ocrConfigs[i].isSignatureVerificationEnabled + }), + signers: ocrConfigs[i].signers, + transmitters: ocrConfigs[i].transmitters + }); + _assertOCRConfigEquality(s_multiOCR3.latestConfigDetails(ocrConfigs[i].ocrPluginType), expectedConfig); + } + + // pluginType 3 remains unconfigured + _assertOCRConfigUnconfigured(s_multiOCR3.latestConfigDetails(3)); + } + + function test_Fuzz_SetConfig_Success(MultiOCR3Base.OCRConfigArgs memory ocrConfig, uint64 randomAddressOffset) public { + // condition: cannot assume max oracle count + vm.assume(ocrConfig.transmitters.length <= 31); + vm.assume(ocrConfig.signers.length <= 31); + + // condition: F > 0 + ocrConfig.F = uint8(bound(ocrConfig.F, 1, 3)); + + uint256 transmittersLength = ocrConfig.transmitters.length; + + // Force addresses to be unique (with a random offset for broader testing) + for (uint160 i = 0; i < transmittersLength; ++i) { + ocrConfig.transmitters[i] = vm.addr(PRIVATE0 + randomAddressOffset + i); + // condition: non-zero oracle address + vm.assume(ocrConfig.transmitters[i] != address(0)); + } + + if (ocrConfig.signers.length == 0) { + ocrConfig.isSignatureVerificationEnabled = false; + } else { + ocrConfig.isSignatureVerificationEnabled = true; + + // condition: number of signers > 3F + vm.assume(ocrConfig.signers.length > 3 * ocrConfig.F); + + uint256 signersLength = ocrConfig.signers.length; + + // Force addresses to be unique - continuing generation with an offset after the transmitter addresses + for (uint160 i = 0; i < signersLength; ++i) { + ocrConfig.signers[i] = vm.addr(PRIVATE0 + randomAddressOffset + i + transmittersLength); + // condition: non-zero oracle address + vm.assume(ocrConfig.signers[i] != address(0)); + } + } + + _assertOCRConfigUnconfigured(s_multiOCR3.latestConfigDetails(ocrConfig.ocrPluginType)); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = ocrConfig; + + vm.expectEmit(); + emit MultiOCR3Base.ConfigSet( + ocrConfig.ocrPluginType, ocrConfig.configDigest, ocrConfig.signers, ocrConfig.transmitters, ocrConfig.F + ); + vm.expectEmit(); + emit MultiOCR3Helper.AfterConfigSet(ocrConfig.ocrPluginType); + s_multiOCR3.setOCR3Configs(ocrConfigs); + + MultiOCR3Base.OCRConfig memory expectedConfig = MultiOCR3Base.OCRConfig({ + configInfo: MultiOCR3Base.ConfigInfo({ + configDigest: ocrConfig.configDigest, + F: ocrConfig.F, + n: ocrConfig.isSignatureVerificationEnabled ? uint8(ocrConfig.signers.length) : 0, + isSignatureVerificationEnabled: ocrConfig.isSignatureVerificationEnabled + }), + signers: ocrConfig.signers, + transmitters: ocrConfig.transmitters + }); + _assertOCRConfigEquality(s_multiOCR3.latestConfigDetails(ocrConfig.ocrPluginType), expectedConfig); + } + + function test_UpdateConfigTransmittersWithoutSigners_Success() public { + _assertOCRConfigUnconfigured(s_multiOCR3.latestConfigDetails(0)); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(1, s_emptySigners, s_validTransmitters), + F: 1, + isSignatureVerificationEnabled: false, + signers: s_emptySigners, + transmitters: s_validTransmitters + }); + s_multiOCR3.setOCR3Configs(ocrConfigs); + + address[] memory newTransmitters = s_partialSigners; + + ocrConfigs[0].F = 2; + ocrConfigs[0].configDigest = _getBasicConfigDigest(2, s_emptySigners, newTransmitters); + ocrConfigs[0].transmitters = newTransmitters; + + vm.expectEmit(); + emit MultiOCR3Base.ConfigSet( + ocrConfigs[0].ocrPluginType, + ocrConfigs[0].configDigest, + ocrConfigs[0].signers, + ocrConfigs[0].transmitters, + ocrConfigs[0].F + ); + vm.expectEmit(); + emit MultiOCR3Helper.AfterConfigSet(ocrConfigs[0].ocrPluginType); + + s_multiOCR3.setOCR3Configs(ocrConfigs); + + MultiOCR3Base.OCRConfig memory expectedConfig = MultiOCR3Base.OCRConfig({ + configInfo: MultiOCR3Base.ConfigInfo({ + configDigest: ocrConfigs[0].configDigest, + F: ocrConfigs[0].F, + n: uint8(ocrConfigs[0].signers.length), + isSignatureVerificationEnabled: ocrConfigs[0].isSignatureVerificationEnabled + }), + signers: s_emptySigners, + transmitters: newTransmitters + }); + _assertOCRConfigEquality(s_multiOCR3.latestConfigDetails(0), expectedConfig); + + // Verify oracle roles get correctly re-assigned + for (uint256 i; i < newTransmitters.length; ++i) { + MultiOCR3Base.Oracle memory transmitterOracle = s_multiOCR3.getOracle(0, newTransmitters[i]); + assertEq(transmitterOracle.index, i); + assertEq(uint8(transmitterOracle.role), uint8(MultiOCR3Base.Role.Transmitter)); + } + + // Verify old transmitters get correctly unset + for (uint256 i = newTransmitters.length; i < s_validTransmitters.length; ++i) { + MultiOCR3Base.Oracle memory transmitterOracle = s_multiOCR3.getOracle(0, s_validTransmitters[i]); + assertEq(uint8(transmitterOracle.role), uint8(MultiOCR3Base.Role.Unset)); + } + } + + function test_UpdateConfigSigners_Success() public { + _assertOCRConfigUnconfigured(s_multiOCR3.latestConfigDetails(0)); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(2, s_validSigners, s_validTransmitters), + F: 2, + isSignatureVerificationEnabled: true, + signers: s_validSigners, + transmitters: s_validTransmitters + }); + s_multiOCR3.setOCR3Configs(ocrConfigs); + + address[] memory newSigners = s_partialTransmitters; + address[] memory newTransmitters = s_partialSigners; + + ocrConfigs[0].F = 1; + ocrConfigs[0].configDigest = _getBasicConfigDigest(1, newSigners, newTransmitters); + ocrConfigs[0].signers = newSigners; + ocrConfigs[0].transmitters = newTransmitters; + + vm.expectEmit(); + emit MultiOCR3Base.ConfigSet( + ocrConfigs[0].ocrPluginType, + ocrConfigs[0].configDigest, + ocrConfigs[0].signers, + ocrConfigs[0].transmitters, + ocrConfigs[0].F + ); + vm.expectEmit(); + emit MultiOCR3Helper.AfterConfigSet(ocrConfigs[0].ocrPluginType); + + s_multiOCR3.setOCR3Configs(ocrConfigs); + + MultiOCR3Base.OCRConfig memory expectedConfig = MultiOCR3Base.OCRConfig({ + configInfo: MultiOCR3Base.ConfigInfo({ + configDigest: ocrConfigs[0].configDigest, + F: ocrConfigs[0].F, + n: uint8(ocrConfigs[0].signers.length), + isSignatureVerificationEnabled: ocrConfigs[0].isSignatureVerificationEnabled + }), + signers: newSigners, + transmitters: newTransmitters + }); + _assertOCRConfigEquality(s_multiOCR3.latestConfigDetails(0), expectedConfig); + + // Verify oracle roles get correctly re-assigned + for (uint256 i; i < newSigners.length; ++i) { + MultiOCR3Base.Oracle memory signerOracle = s_multiOCR3.getOracle(0, newSigners[i]); + assertEq(signerOracle.index, i); + assertEq(uint8(signerOracle.role), uint8(MultiOCR3Base.Role.Signer)); + + MultiOCR3Base.Oracle memory transmitterOracle = s_multiOCR3.getOracle(0, newTransmitters[i]); + assertEq(transmitterOracle.index, i); + assertEq(uint8(transmitterOracle.role), uint8(MultiOCR3Base.Role.Transmitter)); + } + + // Verify old signers / transmitters get correctly unset + for (uint256 i = newSigners.length; i < s_validSigners.length; ++i) { + MultiOCR3Base.Oracle memory signerOracle = s_multiOCR3.getOracle(0, s_validSigners[i]); + assertEq(uint8(signerOracle.role), uint8(MultiOCR3Base.Role.Unset)); + + MultiOCR3Base.Oracle memory transmitterOracle = s_multiOCR3.getOracle(0, s_validTransmitters[i]); + assertEq(uint8(transmitterOracle.role), uint8(MultiOCR3Base.Role.Unset)); + } + } + + // Reverts + + function test_RepeatTransmitterAddress_Revert() public { + address[] memory signers = s_validSigners; + address[] memory transmitters = s_validTransmitters; + transmitters[0] = signers[0]; + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(1, signers, transmitters), + F: 1, + isSignatureVerificationEnabled: true, + signers: signers, + transmitters: transmitters + }); + + vm.expectRevert( + abi.encodeWithSelector( + MultiOCR3Base.InvalidConfig.selector, MultiOCR3Base.InvalidConfigErrorType.REPEATED_ORACLE_ADDRESS + ) + ); + s_multiOCR3.setOCR3Configs(ocrConfigs); + } + + function test_RepeatSignerAddress_Revert() public { + address[] memory signers = s_validSigners; + address[] memory transmitters = s_validTransmitters; + signers[1] = signers[0]; + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(1, signers, transmitters), + F: 1, + isSignatureVerificationEnabled: true, + signers: signers, + transmitters: transmitters + }); + + vm.expectRevert( + abi.encodeWithSelector( + MultiOCR3Base.InvalidConfig.selector, MultiOCR3Base.InvalidConfigErrorType.REPEATED_ORACLE_ADDRESS + ) + ); + s_multiOCR3.setOCR3Configs(ocrConfigs); + } + + function test_SignerCannotBeZeroAddress_Revert() public { + uint8 F = 1; + address[] memory signers = new address[](3 * F + 1); + address[] memory transmitters = new address[](3 * F + 1); + for (uint160 i = 0; i < 3 * F + 1; ++i) { + signers[i] = address(i + 1); + transmitters[i] = address(i + 1000); + } + + signers[0] = address(0); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(F, signers, transmitters), + F: F, + isSignatureVerificationEnabled: true, + signers: signers, + transmitters: transmitters + }); + + vm.expectRevert(MultiOCR3Base.OracleCannotBeZeroAddress.selector); + s_multiOCR3.setOCR3Configs(ocrConfigs); + } + + function test_TransmitterCannotBeZeroAddress_Revert() public { + uint8 F = 1; + address[] memory signers = new address[](3 * F + 1); + address[] memory transmitters = new address[](3 * F + 1); + for (uint160 i = 0; i < 3 * F + 1; ++i) { + signers[i] = address(i + 1); + transmitters[i] = address(i + 1000); + } + + transmitters[0] = address(0); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(F, signers, transmitters), + F: F, + isSignatureVerificationEnabled: true, + signers: signers, + transmitters: transmitters + }); + + vm.expectRevert(MultiOCR3Base.OracleCannotBeZeroAddress.selector); + s_multiOCR3.setOCR3Configs(ocrConfigs); + } + + function test_StaticConfigChange_Revert() public { + uint8 F = 1; + + _assertOCRConfigUnconfigured(s_multiOCR3.latestConfigDetails(0)); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(F, s_validSigners, s_validTransmitters), + F: F, + isSignatureVerificationEnabled: true, + signers: s_validSigners, + transmitters: s_validTransmitters + }); + + s_multiOCR3.setOCR3Configs(ocrConfigs); + + // signature verification cannot change + ocrConfigs[0].isSignatureVerificationEnabled = false; + vm.expectRevert(abi.encodeWithSelector(MultiOCR3Base.StaticConfigCannotBeChanged.selector, 0)); + s_multiOCR3.setOCR3Configs(ocrConfigs); + } + + function test_FTooHigh_Revert() public { + address[] memory signers = new address[](0); + address[] memory transmitters = new address[](0); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(1, signers, transmitters), + F: 1, + isSignatureVerificationEnabled: true, + signers: signers, + transmitters: transmitters + }); + + vm.expectRevert( + abi.encodeWithSelector(MultiOCR3Base.InvalidConfig.selector, MultiOCR3Base.InvalidConfigErrorType.F_TOO_HIGH) + ); + s_multiOCR3.setOCR3Configs(ocrConfigs); + } + + function test_FMustBePositive_Revert() public { + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(0, s_validSigners, s_validTransmitters), + F: 0, + isSignatureVerificationEnabled: true, + signers: s_validSigners, + transmitters: s_validTransmitters + }); + + vm.expectRevert( + abi.encodeWithSelector( + MultiOCR3Base.InvalidConfig.selector, MultiOCR3Base.InvalidConfigErrorType.F_MUST_BE_POSITIVE + ) + ); + s_multiOCR3.setOCR3Configs(ocrConfigs); + } + + function test_TooManyTransmitters_Revert() public { + address[] memory signers = new address[](0); + address[] memory transmitters = new address[](32); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(10, signers, transmitters), + F: 10, + isSignatureVerificationEnabled: false, + signers: signers, + transmitters: transmitters + }); + + vm.expectRevert( + abi.encodeWithSelector( + MultiOCR3Base.InvalidConfig.selector, MultiOCR3Base.InvalidConfigErrorType.TOO_MANY_TRANSMITTERS + ) + ); + s_multiOCR3.setOCR3Configs(ocrConfigs); + } + + function test_TooManySigners_Revert() public { + address[] memory signers = new address[](32); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: 0, + configDigest: _getBasicConfigDigest(1, signers, s_validTransmitters), + F: 1, + isSignatureVerificationEnabled: true, + signers: signers, + transmitters: s_validTransmitters + }); + + vm.expectRevert( + abi.encodeWithSelector( + MultiOCR3Base.InvalidConfig.selector, MultiOCR3Base.InvalidConfigErrorType.TOO_MANY_SIGNERS + ) + ); + s_multiOCR3.setOCR3Configs(ocrConfigs); + } +} diff --git a/contracts/src/v0.8/ccip/test/ocr/MultiOCR3BaseSetup.t.sol b/contracts/src/v0.8/ccip/test/ocr/MultiOCR3BaseSetup.t.sol new file mode 100644 index 0000000000..6f6219bc9b --- /dev/null +++ b/contracts/src/v0.8/ccip/test/ocr/MultiOCR3BaseSetup.t.sol @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {MultiOCR3Base} from "../../ocr/MultiOCR3Base.sol"; +import {BaseTest} from "../BaseTest.t.sol"; +import {MultiOCR3Helper} from "../helpers/MultiOCR3Helper.sol"; + +contract MultiOCR3BaseSetup is BaseTest { + // Signer private keys used for these test + uint256 internal constant PRIVATE0 = 0x7b2e97fe057e6de99d6872a2ef2abf52c9b4469bc848c2465ac3fcd8d336e81d; + + address[] internal s_validSigners; + address[] internal s_validTransmitters; + uint256[] internal s_validSignerKeys; + + address[] internal s_partialSigners; + address[] internal s_partialTransmitters; + uint256[] internal s_partialSignerKeys; + + address[] internal s_emptySigners; + + bytes internal constant REPORT = abi.encode("testReport"); + MultiOCR3Helper internal s_multiOCR3; + + function setUp() public virtual override { + BaseTest.setUp(); + + uint160 numSigners = 7; + s_validSignerKeys = new uint256[](numSigners); + s_validSigners = new address[](numSigners); + s_validTransmitters = new address[](numSigners); + + for (uint160 i; i < numSigners; ++i) { + s_validTransmitters[i] = address(4 + i); + s_validSignerKeys[i] = PRIVATE0 + i; + s_validSigners[i] = vm.addr(s_validSignerKeys[i]); + } + + s_partialSigners = new address[](4); + s_partialSignerKeys = new uint256[](4); + s_partialTransmitters = new address[](4); + for (uint256 i; i < s_partialSigners.length; ++i) { + s_partialSigners[i] = s_validSigners[i]; + s_partialSignerKeys[i] = s_validSignerKeys[i]; + s_partialTransmitters[i] = s_validTransmitters[i]; + } + + s_emptySigners = new address[](0); + + s_multiOCR3 = new MultiOCR3Helper(); + } + + /// @dev returns a mock config digest with config digest computation logic similar to OCR2Base + function _getBasicConfigDigest( + uint8 F, + address[] memory signers, + address[] memory transmitters + ) internal view returns (bytes32) { + bytes memory configBytes = abi.encode(""); + uint256 configVersion = 1; + + uint256 h = uint256( + keccak256( + abi.encode( + block.chainid, address(s_multiOCR3), signers, transmitters, F, configBytes, configVersion, configBytes + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + uint256 prefix = 0x0001 << (256 - 16); // 0x000100..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + function _assertOCRConfigEquality( + MultiOCR3Base.OCRConfig memory configA, + MultiOCR3Base.OCRConfig memory configB + ) internal pure { + vm.assertEq(configA.configInfo.configDigest, configB.configInfo.configDigest); + vm.assertEq(configA.configInfo.F, configB.configInfo.F); + vm.assertEq(configA.configInfo.n, configB.configInfo.n); + vm.assertEq(configA.configInfo.isSignatureVerificationEnabled, configB.configInfo.isSignatureVerificationEnabled); + + vm.assertEq(configA.signers, configB.signers); + vm.assertEq(configA.transmitters, configB.transmitters); + } + + function _assertOCRConfigUnconfigured(MultiOCR3Base.OCRConfig memory config) internal pure { + assertEq(config.configInfo.configDigest, bytes32("")); + assertEq(config.signers.length, 0); + assertEq(config.transmitters.length, 0); + } + + function _getSignaturesForDigest( + uint256[] memory signerPrivateKeys, + bytes memory report, + bytes32[3] memory reportContext, + uint8 signatureCount + ) internal pure returns (bytes32[] memory rs, bytes32[] memory ss, uint8[] memory vs, bytes32 rawVs) { + rs = new bytes32[](signatureCount); + ss = new bytes32[](signatureCount); + vs = new uint8[](signatureCount); + + bytes32 reportDigest = keccak256(abi.encodePacked(keccak256(report), reportContext)); + + // Calculate signatures + for (uint256 i; i < signatureCount; ++i) { + (vs[i], rs[i], ss[i]) = vm.sign(signerPrivateKeys[i], reportDigest); + rawVs = rawVs | (bytes32(bytes1(vs[i] - 27)) >> (8 * i)); + } + + return (rs, ss, vs, rawVs); + } +} diff --git a/contracts/src/v0.8/ccip/test/ocr/OCR2Base.t.sol b/contracts/src/v0.8/ccip/test/ocr/OCR2Base.t.sol new file mode 100644 index 0000000000..7511ebdffa --- /dev/null +++ b/contracts/src/v0.8/ccip/test/ocr/OCR2Base.t.sol @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {OCR2Abstract} from "../../ocr/OCR2Abstract.sol"; +import {OCR2Base} from "../../ocr/OCR2Base.sol"; +import {OCR2Helper} from "../helpers/OCR2Helper.sol"; +import {OCR2Setup} from "./OCR2Setup.t.sol"; + +contract OCR2BaseSetup is OCR2Setup { + OCR2Helper internal s_OCR2Base; + + bytes32[] internal s_rs; + bytes32[] internal s_ss; + bytes32 internal s_rawVs; + + uint40 internal s_latestEpochAndRound; + + function setUp() public virtual override { + OCR2Setup.setUp(); + s_OCR2Base = new OCR2Helper(); + + bytes32 testReportDigest = getTestReportDigest(); + + bytes32[] memory rs = new bytes32[](2); + bytes32[] memory ss = new bytes32[](2); + uint8[] memory vs = new uint8[](2); + + // Calculate signatures + (vs[0], rs[0], ss[0]) = vm.sign(PRIVATE0, testReportDigest); + (vs[1], rs[1], ss[1]) = vm.sign(PRIVATE1, testReportDigest); + + s_rs = rs; + s_ss = ss; + s_rawVs = bytes32(bytes1(vs[0] - 27)) | (bytes32(bytes1(vs[1] - 27)) >> 8); + } + + function getBasicConfigDigest(uint8 f, uint64 currentConfigCount) internal view returns (bytes32) { + bytes memory configBytes = abi.encode(""); + return s_OCR2Base.configDigestFromConfigData( + block.chainid, + address(s_OCR2Base), + currentConfigCount + 1, + s_valid_signers, + s_valid_transmitters, + f, + configBytes, + s_offchainConfigVersion, + configBytes + ); + } + + function getTestReportDigest() internal view returns (bytes32) { + bytes32 configDigest = getBasicConfigDigest(s_f, 0); + bytes32[3] memory reportContext = [configDigest, configDigest, configDigest]; + return keccak256(abi.encodePacked(keccak256(REPORT), reportContext)); + } + + function getBasicConfigDigest( + address contractAddress, + uint8 f, + uint64 currentConfigCount, + bytes memory onchainConfig + ) internal view returns (bytes32) { + return s_OCR2Base.configDigestFromConfigData( + block.chainid, + contractAddress, + currentConfigCount + 1, + s_valid_signers, + s_valid_transmitters, + f, + onchainConfig, + s_offchainConfigVersion, + abi.encode("") + ); + } +} + +contract OCR2Base_transmit is OCR2BaseSetup { + bytes32 internal s_configDigest; + + function setUp() public virtual override { + OCR2BaseSetup.setUp(); + bytes memory configBytes = abi.encode(""); + + s_configDigest = getBasicConfigDigest(s_f, 0); + s_OCR2Base.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, configBytes, s_offchainConfigVersion, configBytes + ); + } + + function test_Transmit2SignersSuccess_gas() public { + vm.pauseGasMetering(); + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + + vm.startPrank(s_valid_transmitters[0]); + vm.resumeGasMetering(); + s_OCR2Base.transmit(reportContext, REPORT, s_rs, s_ss, s_rawVs); + } + + // Reverts + + function test_ForkedChain_Revert() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + + uint256 chain1 = block.chainid; + uint256 chain2 = chain1 + 1; + vm.chainId(chain2); + vm.expectRevert(abi.encodeWithSelector(OCR2Base.ForkedChain.selector, chain1, chain2)); + vm.startPrank(s_valid_transmitters[0]); + s_OCR2Base.transmit(reportContext, REPORT, s_rs, s_ss, s_rawVs); + } + + function test_WrongNumberOfSignatures_Revert() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + + vm.expectRevert(OCR2Base.WrongNumberOfSignatures.selector); + s_OCR2Base.transmit(reportContext, REPORT, new bytes32[](0), new bytes32[](0), s_rawVs); + } + + function test_ConfigDigestMismatch_Revert() public { + bytes32 configDigest; + bytes32[3] memory reportContext = [configDigest, configDigest, configDigest]; + + vm.expectRevert(abi.encodeWithSelector(OCR2Base.ConfigDigestMismatch.selector, s_configDigest, configDigest)); + s_OCR2Base.transmit(reportContext, REPORT, new bytes32[](0), new bytes32[](0), s_rawVs); + } + + function test_SignatureOutOfRegistration_Revert() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + + bytes32[] memory rs = new bytes32[](2); + bytes32[] memory ss = new bytes32[](1); + + vm.expectRevert(OCR2Base.SignaturesOutOfRegistration.selector); + s_OCR2Base.transmit(reportContext, REPORT, rs, ss, s_rawVs); + } + + function test_UnAuthorizedTransmitter_Revert() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + bytes32[] memory rs = new bytes32[](2); + bytes32[] memory ss = new bytes32[](2); + + vm.expectRevert(OCR2Base.UnauthorizedTransmitter.selector); + s_OCR2Base.transmit(reportContext, REPORT, rs, ss, s_rawVs); + } + + function test_NonUniqueSignature_Revert() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + bytes32[] memory rs = s_rs; + bytes32[] memory ss = s_ss; + + rs[1] = rs[0]; + ss[1] = ss[0]; + // Need to reset the rawVs to be valid + bytes32 rawVs = bytes32(bytes1(uint8(28) - 27)) | (bytes32(bytes1(uint8(28) - 27)) >> 8); + + vm.startPrank(s_valid_transmitters[0]); + vm.expectRevert(OCR2Base.NonUniqueSignatures.selector); + s_OCR2Base.transmit(reportContext, REPORT, rs, ss, rawVs); + } + + function test_UnauthorizedSigner_Revert() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + bytes32[] memory rs = new bytes32[](2); + rs[0] = s_configDigest; + bytes32[] memory ss = rs; + + vm.startPrank(s_valid_transmitters[0]); + vm.expectRevert(OCR2Base.UnauthorizedSigner.selector); + s_OCR2Base.transmit(reportContext, REPORT, rs, ss, s_rawVs); + } +} + +contract OCR2Base_setOCR2Config is OCR2BaseSetup { + function test_SetConfigSuccess_gas() public { + vm.pauseGasMetering(); + bytes memory configBytes = abi.encode(""); + uint32 configCount = 0; + + bytes32 configDigest = getBasicConfigDigest(s_f, configCount++); + + address[] memory transmitters = s_OCR2Base.getTransmitters(); + assertEq(0, transmitters.length); + + vm.expectEmit(); + emit OCR2Abstract.ConfigSet( + 0, + configDigest, + configCount, + s_valid_signers, + s_valid_transmitters, + s_f, + configBytes, + s_offchainConfigVersion, + configBytes + ); + + s_OCR2Base.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, configBytes, s_offchainConfigVersion, configBytes + ); + + transmitters = s_OCR2Base.getTransmitters(); + assertEq(s_valid_transmitters, transmitters); + + configDigest = getBasicConfigDigest(s_f, configCount++); + + vm.expectEmit(); + emit OCR2Abstract.ConfigSet( + uint32(block.number), + configDigest, + configCount, + s_valid_signers, + s_valid_transmitters, + s_f, + configBytes, + s_offchainConfigVersion, + configBytes + ); + vm.resumeGasMetering(); + s_OCR2Base.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, configBytes, s_offchainConfigVersion, configBytes + ); + } + + // Reverts + function test_RepeatAddress_Revert() public { + address[] memory signers = new address[](10); + signers[0] = address(1245678); + address[] memory transmitters = new address[](10); + transmitters[0] = signers[0]; + + vm.expectRevert( + abi.encodeWithSelector(OCR2Base.InvalidConfig.selector, OCR2Base.InvalidConfigErrorType.REPEATED_ORACLE_ADDRESS) + ); + s_OCR2Base.setOCR2Config(signers, transmitters, 2, abi.encode(""), 100, abi.encode("")); + } + + function test_SingerCannotBeZeroAddress_Revert() public { + uint256 f = 1; + address[] memory signers = new address[](3 * f + 1); + address[] memory transmitters = new address[](3 * f + 1); + for (uint160 i = 0; i < 3 * f + 1; ++i) { + signers[i] = address(i + 1); + transmitters[i] = address(i + 1000); + } + + signers[0] = address(0); + + vm.expectRevert(OCR2Base.OracleCannotBeZeroAddress.selector); + s_OCR2Base.setOCR2Config(signers, transmitters, uint8(f), abi.encode(""), 100, abi.encode("")); + } + + function test_TransmitterCannotBeZeroAddress_Revert() public { + uint256 f = 1; + address[] memory signers = new address[](3 * f + 1); + address[] memory transmitters = new address[](3 * f + 1); + for (uint160 i = 0; i < 3 * f + 1; ++i) { + signers[i] = address(i + 1); + transmitters[i] = address(i + 1000); + } + + transmitters[0] = address(0); + + vm.expectRevert(OCR2Base.OracleCannotBeZeroAddress.selector); + s_OCR2Base.setOCR2Config(signers, transmitters, uint8(f), abi.encode(""), 100, abi.encode("")); + } + + function test_OracleOutOfRegister_Revert() public { + address[] memory signers = new address[](10); + address[] memory transmitters = new address[](0); + + vm.expectRevert( + abi.encodeWithSelector( + OCR2Base.InvalidConfig.selector, OCR2Base.InvalidConfigErrorType.NUM_SIGNERS_NOT_NUM_TRANSMITTERS + ) + ); + s_OCR2Base.setOCR2Config(signers, transmitters, 2, abi.encode(""), 100, abi.encode("")); + } + + function test_FTooHigh_Revert() public { + address[] memory signers = new address[](0); + uint8 f = 1; + + vm.expectRevert(abi.encodeWithSelector(OCR2Base.InvalidConfig.selector, OCR2Base.InvalidConfigErrorType.F_TOO_HIGH)); + s_OCR2Base.setOCR2Config(signers, new address[](0), f, abi.encode(""), 100, abi.encode("")); + } + + function test_FMustBePositive_Revert() public { + uint8 f = 0; + + vm.expectRevert( + abi.encodeWithSelector(OCR2Base.InvalidConfig.selector, OCR2Base.InvalidConfigErrorType.F_MUST_BE_POSITIVE) + ); + s_OCR2Base.setOCR2Config(new address[](0), new address[](0), f, abi.encode(""), 100, abi.encode("")); + } + + function test_TooManySigners_Revert() public { + address[] memory signers = new address[](32); + + vm.expectRevert( + abi.encodeWithSelector(OCR2Base.InvalidConfig.selector, OCR2Base.InvalidConfigErrorType.TOO_MANY_SIGNERS) + ); + s_OCR2Base.setOCR2Config(signers, new address[](0), 0, abi.encode(""), 100, abi.encode("")); + } +} diff --git a/contracts/src/v0.8/ccip/test/ocr/OCR2BaseNoChecks.t.sol b/contracts/src/v0.8/ccip/test/ocr/OCR2BaseNoChecks.t.sol new file mode 100644 index 0000000000..fd4cf3fc9e --- /dev/null +++ b/contracts/src/v0.8/ccip/test/ocr/OCR2BaseNoChecks.t.sol @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {OCR2BaseNoChecks} from "../../ocr/OCR2BaseNoChecks.sol"; +import {OCR2NoChecksHelper} from "../helpers/OCR2NoChecksHelper.sol"; +import {OCR2Setup} from "./OCR2Setup.t.sol"; + +contract OCR2BaseNoChecksSetup is OCR2Setup { + OCR2NoChecksHelper internal s_OCR2Base; + + bytes32[] internal s_rs; + bytes32[] internal s_ss; + bytes32 internal s_rawVs; + + function setUp() public virtual override { + OCR2Setup.setUp(); + s_OCR2Base = new OCR2NoChecksHelper(); + } + + function getBasicConfigDigest(uint8 f, uint64 currentConfigCount) internal view returns (bytes32) { + bytes memory configBytes = abi.encode(""); + return s_OCR2Base.configDigestFromConfigData( + block.chainid, + address(s_OCR2Base), + currentConfigCount + 1, + s_valid_signers, + s_valid_transmitters, + f, + configBytes, + s_offchainConfigVersion, + configBytes + ); + } +} + +contract OCR2BaseNoChecks_transmit is OCR2BaseNoChecksSetup { + bytes32 internal s_configDigest; + + function setUp() public virtual override { + OCR2BaseNoChecksSetup.setUp(); + bytes memory configBytes = abi.encode(""); + + s_configDigest = getBasicConfigDigest(s_f, 0); + s_OCR2Base.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, configBytes, s_offchainConfigVersion, configBytes + ); + } + + function test_TransmitSuccess_gas() public { + vm.pauseGasMetering(); + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + + vm.startPrank(s_valid_transmitters[0]); + vm.resumeGasMetering(); + s_OCR2Base.transmit(reportContext, REPORT, s_rs, s_ss, s_rawVs); + } + + // Reverts + + function test_ForkedChain_Revert() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + + uint256 chain1 = block.chainid; + uint256 chain2 = chain1 + 1; + vm.chainId(chain2); + vm.expectRevert(abi.encodeWithSelector(OCR2BaseNoChecks.ForkedChain.selector, chain1, chain2)); + vm.startPrank(s_valid_transmitters[0]); + s_OCR2Base.transmit(reportContext, REPORT, s_rs, s_ss, s_rawVs); + } + + function test_ConfigDigestMismatch_Revert() public { + bytes32 configDigest; + + bytes32[3] memory reportContext = [configDigest, configDigest, configDigest]; + + vm.expectRevert( + abi.encodeWithSelector(OCR2BaseNoChecks.ConfigDigestMismatch.selector, s_configDigest, configDigest) + ); + s_OCR2Base.transmit(reportContext, REPORT, new bytes32[](0), new bytes32[](0), s_rawVs); + } + + function test_UnAuthorizedTransmitter_Revert() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + bytes32[] memory rs = new bytes32[](3); + bytes32[] memory ss = new bytes32[](3); + + vm.expectRevert(OCR2BaseNoChecks.UnauthorizedTransmitter.selector); + s_OCR2Base.transmit(reportContext, REPORT, rs, ss, s_rawVs); + } +} + +contract OCR2BaseNoChecks_setOCR2Config is OCR2BaseNoChecksSetup { + event ConfigSet( + uint32 previousConfigBlockNumber, + bytes32 configDigest, + uint64 configCount, + address[] signers, + address[] transmitters, + uint8 f, + bytes onchainConfig, + uint64 offchainConfigVersion, + bytes offchainConfig + ); + + function test_SetConfigSuccess_gas() public { + vm.pauseGasMetering(); + bytes memory configBytes = abi.encode(""); + uint32 configCount = 0; + + bytes32 configDigest = getBasicConfigDigest(s_f, configCount++); + + address[] memory transmitters = s_OCR2Base.getTransmitters(); + assertEq(0, transmitters.length); + + vm.expectEmit(); + emit ConfigSet( + 0, + configDigest, + configCount, + s_valid_signers, + s_valid_transmitters, + s_f, + configBytes, + s_offchainConfigVersion, + configBytes + ); + + s_OCR2Base.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, configBytes, s_offchainConfigVersion, configBytes + ); + + transmitters = s_OCR2Base.getTransmitters(); + assertEq(s_valid_transmitters, transmitters); + + configDigest = getBasicConfigDigest(s_f, configCount++); + + vm.expectEmit(); + emit ConfigSet( + uint32(block.number), + configDigest, + configCount, + s_valid_signers, + s_valid_transmitters, + s_f, + configBytes, + s_offchainConfigVersion, + configBytes + ); + vm.resumeGasMetering(); + s_OCR2Base.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, configBytes, s_offchainConfigVersion, configBytes + ); + } + + // Reverts + function test_RepeatAddress_Revert() public { + address[] memory signers = new address[](4); + address[] memory transmitters = new address[](4); + transmitters[0] = address(1245678); + transmitters[1] = address(1245678); + transmitters[2] = address(1245678); + transmitters[3] = address(1245678); + + vm.expectRevert( + abi.encodeWithSelector( + OCR2BaseNoChecks.InvalidConfig.selector, OCR2BaseNoChecks.InvalidConfigErrorType.REPEATED_ORACLE_ADDRESS + ) + ); + s_OCR2Base.setOCR2Config(signers, transmitters, 1, abi.encode(""), 100, abi.encode("")); + } + + function test_FMustBePositive_Revert() public { + uint8 f = 0; + + vm.expectRevert( + abi.encodeWithSelector( + OCR2BaseNoChecks.InvalidConfig.selector, OCR2BaseNoChecks.InvalidConfigErrorType.F_MUST_BE_POSITIVE + ) + ); + s_OCR2Base.setOCR2Config(new address[](0), new address[](0), f, abi.encode(""), 100, abi.encode("")); + } + + function test_TransmitterCannotBeZeroAddress_Revert() public { + uint256 f = 1; + address[] memory signers = new address[](3 * f + 1); + address[] memory transmitters = new address[](3 * f + 1); + for (uint160 i = 0; i < 3 * f + 1; ++i) { + signers[i] = address(i + 1); + transmitters[i] = address(i + 1000); + } + + transmitters[0] = address(0); + + vm.expectRevert(OCR2BaseNoChecks.OracleCannotBeZeroAddress.selector); + s_OCR2Base.setOCR2Config(signers, transmitters, uint8(f), abi.encode(""), 100, abi.encode("")); + } + + function test_TooManyTransmitter_Revert() public { + address[] memory transmitters = new address[](100); + + vm.expectRevert( + abi.encodeWithSelector( + OCR2BaseNoChecks.InvalidConfig.selector, OCR2BaseNoChecks.InvalidConfigErrorType.TOO_MANY_TRANSMITTERS + ) + ); + s_OCR2Base.setOCR2Config(new address[](0), transmitters, 0, abi.encode(""), 100, abi.encode("")); + } +} diff --git a/contracts/src/v0.8/ccip/test/ocr/OCR2Setup.t.sol b/contracts/src/v0.8/ccip/test/ocr/OCR2Setup.t.sol new file mode 100644 index 0000000000..e4be8ffa29 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/ocr/OCR2Setup.t.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {Test} from "forge-std/Test.sol"; + +contract OCR2Setup is Test { + uint256 internal constant PRIVATE0 = 0x7b2e97fe057e6de99d6872a2ef2abf52c9b4469bc848c2465ac3fcd8d336e81d; + uint256 internal constant PRIVATE1 = 0xab56160806b05ef1796789248e1d7f34a6465c5280899159d645218cd216cee6; + uint256 internal constant PRIVATE2 = 0x6ec7caa8406a49b76736602810e0a2871959fbbb675e23a8590839e4717f1f7f; + uint256 internal constant PRIVATE3 = 0x80f14b11da94ae7f29d9a7713ea13dc838e31960a5c0f2baf45ed458947b730a; + + address[] internal s_valid_signers; + address[] internal s_valid_transmitters; + + uint64 internal constant s_offchainConfigVersion = 3; + uint8 internal constant s_f = 1; + bytes internal constant REPORT = abi.encode("testReport"); + + function setUp() public virtual { + s_valid_transmitters = new address[](4); + for (uint160 i = 0; i < 4; ++i) { + s_valid_transmitters[i] = address(4 + i); + } + + s_valid_signers = new address[](4); + s_valid_signers[0] = vm.addr(PRIVATE0); //0xc110458BE52CaA6bB68E66969C3218A4D9Db0211 + s_valid_signers[1] = vm.addr(PRIVATE1); //0xc110a19c08f1da7F5FfB281dc93630923F8E3719 + s_valid_signers[2] = vm.addr(PRIVATE2); //0xc110fdF6e8fD679C7Cc11602d1cd829211A18e9b + s_valid_signers[3] = vm.addr(PRIVATE3); //0xc11028017c9b445B6bF8aE7da951B5cC28B326C0 + } +} diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol new file mode 100644 index 0000000000..43899cbfd6 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol @@ -0,0 +1,3429 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ICommitStore} from "../../interfaces/ICommitStore.sol"; +import {IMessageInterceptor} from "../../interfaces/IMessageInterceptor.sol"; +import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; +import {IRMN} from "../../interfaces/IRMN.sol"; +import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; + +import {CallWithExactGas} from "../../../shared/call/CallWithExactGas.sol"; +import {NonceManager} from "../../NonceManager.sol"; +import {PriceRegistry} from "../../PriceRegistry.sol"; +import {RMN} from "../../RMN.sol"; +import {Router} from "../../Router.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {MerkleMultiProof} from "../../libraries/MerkleMultiProof.sol"; +import {Pool} from "../../libraries/Pool.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {MultiOCR3Base} from "../../ocr/MultiOCR3Base.sol"; +import {EVM2EVMMultiOffRamp} from "../../offRamp/EVM2EVMMultiOffRamp.sol"; +import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {EVM2EVMMultiOffRampHelper} from "../helpers/EVM2EVMMultiOffRampHelper.sol"; +import {EVM2EVMOffRampHelper} from "../helpers/EVM2EVMOffRampHelper.sol"; +import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; +import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; +import {ConformingReceiver} from "../helpers/receivers/ConformingReceiver.sol"; +import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; +import {MaybeRevertMessageReceiverNo165} from "../helpers/receivers/MaybeRevertMessageReceiverNo165.sol"; +import {ReentrancyAbuserMultiRamp} from "../helpers/receivers/ReentrancyAbuserMultiRamp.sol"; +import {EVM2EVMMultiOffRampSetup} from "./EVM2EVMMultiOffRampSetup.t.sol"; +import {Vm} from "forge-std/Vm.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { + function test_Constructor_Success() public { + EVM2EVMMultiOffRamp.StaticConfig memory staticConfig = EVM2EVMMultiOffRamp.StaticConfig({ + chainSelector: DEST_CHAIN_SELECTOR, + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry), + nonceManager: address(s_inboundNonceManager) + }); + EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = + _generateDynamicMultiOffRampConfig(address(s_destRouter), address(s_priceRegistry)); + + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](2); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + onRamp: ON_RAMP_ADDRESS_1, + isEnabled: true + }); + sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1 + 1, + onRamp: ON_RAMP_ADDRESS_2, + isEnabled: true + }); + + EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig1 = + EVM2EVMMultiOffRamp.SourceChainConfig({isEnabled: true, minSeqNr: 1, onRamp: sourceChainConfigs[0].onRamp}); + + EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig2 = + EVM2EVMMultiOffRamp.SourceChainConfig({isEnabled: true, minSeqNr: 1, onRamp: sourceChainConfigs[1].onRamp}); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.StaticConfigSet(staticConfig); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.DynamicConfigSet(dynamicConfig); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SourceChainSelectorAdded(SOURCE_CHAIN_SELECTOR_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1, expectedSourceChainConfig1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SourceChainSelectorAdded(SOURCE_CHAIN_SELECTOR_1 + 1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1 + 1, expectedSourceChainConfig2); + + s_offRamp = new EVM2EVMMultiOffRampHelper(staticConfig, dynamicConfig, sourceChainConfigs); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: uint8(Internal.OCRPluginType.Execution), + configDigest: s_configDigestExec, + F: s_F, + isSignatureVerificationEnabled: false, + signers: s_emptySigners, + transmitters: s_validTransmitters + }); + + s_offRamp.setOCR3Configs(ocrConfigs); + + // Static config + EVM2EVMMultiOffRamp.StaticConfig memory gotStaticConfig = s_offRamp.getStaticConfig(); + assertEq(staticConfig.chainSelector, gotStaticConfig.chainSelector); + assertEq(staticConfig.rmnProxy, gotStaticConfig.rmnProxy); + assertEq(staticConfig.tokenAdminRegistry, gotStaticConfig.tokenAdminRegistry); + + // Dynamic config + EVM2EVMMultiOffRamp.DynamicConfig memory gotDynamicConfig = s_offRamp.getDynamicConfig(); + _assertSameConfig(dynamicConfig, gotDynamicConfig); + + // OCR Config + MultiOCR3Base.OCRConfig memory expectedOCRConfig = MultiOCR3Base.OCRConfig({ + configInfo: MultiOCR3Base.ConfigInfo({ + configDigest: ocrConfigs[0].configDigest, + F: ocrConfigs[0].F, + n: 0, + isSignatureVerificationEnabled: ocrConfigs[0].isSignatureVerificationEnabled + }), + signers: s_emptySigners, + transmitters: s_validTransmitters + }); + MultiOCR3Base.OCRConfig memory gotOCRConfig = s_offRamp.latestConfigDetails(uint8(Internal.OCRPluginType.Execution)); + _assertOCRConfigEquality(expectedOCRConfig, gotOCRConfig); + + _assertSourceChainConfigEquality( + s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR_1), expectedSourceChainConfig1 + ); + _assertSourceChainConfigEquality( + s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR_1 + 1), expectedSourceChainConfig2 + ); + + // OffRamp initial values + assertEq("EVM2EVMMultiOffRamp 1.6.0-dev", s_offRamp.typeAndVersion()); + assertEq(OWNER, s_offRamp.owner()); + assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); + } + + // Revert + function test_ZeroOnRampAddress_Revert() public { + uint64[] memory sourceChainSelectors = new uint64[](1); + sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; + + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + onRamp: new bytes(0), + isEnabled: true + }); + + vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + + s_offRamp = new EVM2EVMMultiOffRampHelper( + EVM2EVMMultiOffRamp.StaticConfig({ + chainSelector: DEST_CHAIN_SELECTOR, + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry), + nonceManager: address(s_inboundNonceManager) + }), + _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)), + sourceChainConfigs + ); + } + + function test_SourceChainSelector_Revert() public { + uint64[] memory sourceChainSelectors = new uint64[](1); + sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; + + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = + EVM2EVMMultiOffRamp.SourceChainConfigArgs({sourceChainSelector: 0, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true}); + + vm.expectRevert(EVM2EVMMultiOffRamp.ZeroChainSelectorNotAllowed.selector); + + s_offRamp = new EVM2EVMMultiOffRampHelper( + EVM2EVMMultiOffRamp.StaticConfig({ + chainSelector: DEST_CHAIN_SELECTOR, + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry), + nonceManager: address(s_inboundNonceManager) + }), + _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)), + sourceChainConfigs + ); + } + + function test_ZeroRMNProxy_Revert() public { + uint64[] memory sourceChainSelectors = new uint64[](1); + sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; + + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); + + vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + + s_offRamp = new EVM2EVMMultiOffRampHelper( + EVM2EVMMultiOffRamp.StaticConfig({ + chainSelector: DEST_CHAIN_SELECTOR, + rmnProxy: ZERO_ADDRESS, + tokenAdminRegistry: address(s_tokenAdminRegistry), + nonceManager: address(s_inboundNonceManager) + }), + _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)), + sourceChainConfigs + ); + } + + function test_ZeroChainSelector_Revert() public { + uint64[] memory sourceChainSelectors = new uint64[](1); + sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; + + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); + + vm.expectRevert(EVM2EVMMultiOffRamp.ZeroChainSelectorNotAllowed.selector); + + s_offRamp = new EVM2EVMMultiOffRampHelper( + EVM2EVMMultiOffRamp.StaticConfig({ + chainSelector: 0, + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry), + nonceManager: address(s_inboundNonceManager) + }), + _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)), + sourceChainConfigs + ); + } + + function test_ZeroTokenAdminRegistry_Revert() public { + uint64[] memory sourceChainSelectors = new uint64[](1); + sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; + + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); + + vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + + s_offRamp = new EVM2EVMMultiOffRampHelper( + EVM2EVMMultiOffRamp.StaticConfig({ + chainSelector: DEST_CHAIN_SELECTOR, + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: ZERO_ADDRESS, + nonceManager: address(s_inboundNonceManager) + }), + _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)), + sourceChainConfigs + ); + } + + function test_ZeroNonceManager_Revert() public { + uint64[] memory sourceChainSelectors = new uint64[](1); + sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; + + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); + + vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + + s_offRamp = new EVM2EVMMultiOffRampHelper( + EVM2EVMMultiOffRamp.StaticConfig({ + chainSelector: DEST_CHAIN_SELECTOR, + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry), + nonceManager: ZERO_ADDRESS + }), + _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)), + sourceChainConfigs + ); + } +} + +contract EVM2EVMMultiOffRamp_setDynamicConfig is EVM2EVMMultiOffRampSetup { + function test_SetDynamicConfig_Success() public { + EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = + _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.DynamicConfigSet(dynamicConfig); + + s_offRamp.setDynamicConfig(dynamicConfig); + + EVM2EVMMultiOffRamp.DynamicConfig memory newConfig = s_offRamp.getDynamicConfig(); + _assertSameConfig(dynamicConfig, newConfig); + } + + function test_SetDynamicConfigWithValidator_Success() public { + EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = + _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)); + dynamicConfig.messageValidator = address(s_inboundMessageValidator); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.DynamicConfigSet(dynamicConfig); + + s_offRamp.setDynamicConfig(dynamicConfig); + + EVM2EVMMultiOffRamp.DynamicConfig memory newConfig = s_offRamp.getDynamicConfig(); + _assertSameConfig(dynamicConfig, newConfig); + } + + // Reverts + + function test_NonOwner_Revert() public { + vm.startPrank(STRANGER); + EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = + _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)); + + vm.expectRevert("Only callable by owner"); + + s_offRamp.setDynamicConfig(dynamicConfig); + } + + function test_RouterZeroAddress_Revert() public { + EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = + _generateDynamicMultiOffRampConfig(ZERO_ADDRESS, address(s_priceRegistry)); + + vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + + s_offRamp.setDynamicConfig(dynamicConfig); + } + + function test_PriceRegistryZeroAddress_Revert() public { + EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = _generateDynamicMultiOffRampConfig(USER_3, ZERO_ADDRESS); + + vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + + s_offRamp.setDynamicConfig(dynamicConfig); + } +} + +contract EVM2EVMMultiOffRamp_ccipReceive is EVM2EVMMultiOffRampSetup { + // Reverts + + function test_Reverts() public { + Client.Any2EVMMessage memory message = + _convertToGeneralMessage(_generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1)); + vm.expectRevert(); + s_offRamp.ccipReceive(message); + } +} + +contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { + function setUp() public virtual override { + super.setUp(); + _setupMultipleOffRamps(); + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 1); + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_3, 1); + } + + function test_SingleMessageNoTokens_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + + messages[0].header.nonce++; + messages[0].header.sequenceNumber++; + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertGt(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender), nonceBefore); + } + + function test_SingleMessageNoTokensUnordered_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + messages[0].header.nonce = 0; + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + // Nonce never increments on unordered messages. + uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertEq( + s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender), + nonceBefore, + "nonce must remain unchanged on unordered messages" + ); + + messages[0].header.sequenceNumber++; + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + // Nonce never increments on unordered messages. + nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertEq( + s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender), + nonceBefore, + "nonce must remain unchanged on unordered messages" + ); + } + + function test_SingleMessageNoTokensOtherChain_Success() public { + Internal.Any2EVMRampMessage[] memory messagesChain1 = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesChain1), new uint256[](0) + ); + + uint64 nonceChain1 = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messagesChain1[0].sender); + assertGt(nonceChain1, 0); + + Internal.Any2EVMRampMessage[] memory messagesChain2 = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_3, ON_RAMP_ADDRESS_3); + assertEq(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, messagesChain2[0].sender), 0); + + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messagesChain2), new uint256[](0) + ); + assertGt(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, messagesChain2[0].sender), 0); + + // Other chain's nonce is unaffected + assertEq(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messagesChain1[0].sender), nonceChain1); + } + + function test_ReceiverError_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + bytes memory realError1 = new bytes(2); + realError1[0] = 0xbe; + realError1[1] = 0xef; + s_reverting_receiver.setErr(realError1); + + messages[0].receiver = address(s_reverting_receiver); + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.ReceiverError.selector, + abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, realError1) + ) + ); + // Nonce should increment on non-strict + assertEq(uint64(0), s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER))); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertEq(uint64(1), s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER))); + } + + function test_SkippedIncorrectNonce_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + messages[0].header.nonce++; + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit NonceManager.SkippedIncorrectNonce( + messages[0].header.sourceChainSelector, messages[0].header.nonce, messages[0].sender + ); + + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + } + + function test_SkippedIncorrectNonceStillExecutes_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + messages[1].header.nonce++; + messages[1].header.messageId = Internal._hash(messages[1], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit NonceManager.SkippedIncorrectNonce(SOURCE_CHAIN_SELECTOR_1, messages[1].header.nonce, messages[1].sender); + + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + } + + function test__execute_SkippedAlreadyExecutedMessage_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); + + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + } + + function test__execute_SkippedAlreadyExecutedMessageUnordered_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + messages[0].header.nonce = 0; + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); + + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + } + + // Send a message to a contract that does not implement the CCIPReceiver interface + // This should execute successfully. + function test_SingleMessageToNonCCIPReceiver_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + MaybeRevertMessageReceiverNo165 newReceiver = new MaybeRevertMessageReceiverNo165(true); + messages[0].receiver = address(newReceiver); + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + } + + function test_SingleMessagesNoTokensSuccess_gas() public { + vm.pauseGasMetering(); + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + vm.resumeGasMetering(); + s_offRamp.executeSingleReport(report, new uint256[](0)); + } + + function test_TwoMessagesWithTokensSuccess_gas() public { + vm.pauseGasMetering(); + Internal.Any2EVMRampMessage[] memory messages = + _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + // Set message 1 to use another receiver to simulate more fair gas costs + messages[1].receiver = address(s_secondary_receiver); + messages[1].header.messageId = Internal._hash(messages[1], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[1].header.sequenceNumber, + messages[1].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + vm.resumeGasMetering(); + s_offRamp.executeSingleReport(report, new uint256[](0)); + } + + function test_TwoMessagesWithTokensAndGE_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + // Set message 1 to use another receiver to simulate more fair gas costs + messages[1].receiver = address(s_secondary_receiver); + messages[1].header.messageId = Internal._hash(messages[1], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[1].header.sequenceNumber, + messages[1].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + assertEq(uint64(0), s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER))); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), _getGasLimitsFromMessages(messages) + ); + assertEq(uint64(2), s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER))); + } + + function test_Fuzz_InterleavingOrderedAndUnorderedMessages_Success(bool[7] memory orderings) public { + Internal.Any2EVMRampMessage[] memory messages = new Internal.Any2EVMRampMessage[](orderings.length); + // number of tokens needs to be capped otherwise we hit UnsupportedNumberOfTokens. + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](3); + for (uint256 i = 0; i < 3; ++i) { + tokenAmounts[i].token = s_sourceTokens[i % s_sourceTokens.length]; + tokenAmounts[i].amount = 1e18; + } + uint64 expectedNonce = 0; + for (uint256 i = 0; i < orderings.length; ++i) { + messages[i] = + _generateAny2EVMMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, uint64(i + 1), tokenAmounts, !orderings[i]); + if (orderings[i]) { + messages[i].header.nonce = ++expectedNonce; + } + messages[i].header.messageId = Internal._hash(messages[i], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[i].header.sequenceNumber, + messages[i].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + } + + uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER)); + assertEq(uint64(0), nonceBefore, "nonce before exec should be 0"); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), _getGasLimitsFromMessages(messages) + ); + // all executions should succeed. + for (uint256 i = 0; i < orderings.length; ++i) { + assertEq( + uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1, messages[i].header.sequenceNumber)), + uint256(Internal.MessageExecutionState.SUCCESS) + ); + } + assertEq( + nonceBefore + expectedNonce, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER)) + ); + } + + function test_InvalidSourcePoolAddress_Success() public { + address fakePoolAddress = address(0x0000000000333333); + + Internal.Any2EVMRampMessage[] memory messages = + _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + messages[0].tokenAmounts[0].sourcePoolAddress = abi.encode(fakePoolAddress); + + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + messages[1].header.messageId = Internal._hash(messages[1], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.TokenHandlingError.selector, + abi.encodeWithSelector(TokenPool.InvalidSourcePoolAddress.selector, abi.encode(fakePoolAddress)) + ) + ); + + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + } + + function test_WithCurseOnAnotherSourceChain_Success() public { + s_mockRMN.setChainCursed(SOURCE_CHAIN_SELECTOR_2, true); + s_offRamp.executeSingleReport( + _generateReportFromMessages( + SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) + ), + new uint256[](0) + ); + } + + // Reverts + + function test_MismatchingDestChainSelector_Revert() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_3, ON_RAMP_ADDRESS_3); + messages[0].header.destChainSelector = DEST_CHAIN_SELECTOR + 1; + + Internal.ExecutionReportSingleChain memory executionReport = + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.InvalidMessageDestChainSelector.selector, messages[0].header.destChainSelector + ) + ); + s_offRamp.executeSingleReport(executionReport, new uint256[](0)); + } + + function test_MismatchingOnRampRoot_Revert() public { + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 0); + + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport( + // Root against mismatching on ramp + Internal._hash(messages[0], ON_RAMP_ADDRESS_3) + ); + _commit(commitReport, s_latestSequenceNumber); + + Internal.ExecutionReportSingleChain memory executionReport = + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.RootNotCommitted.selector, SOURCE_CHAIN_SELECTOR_1)); + s_offRamp.executeSingleReport(executionReport, new uint256[](0)); + } + + function test_Unhealthy_Revert() public { + s_mockRMN.setGlobalCursed(true); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_1)); + s_offRamp.executeSingleReport( + _generateReportFromMessages( + SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) + ), + new uint256[](0) + ); + // Uncurse should succeed + s_mockRMN.setGlobalCursed(false); + s_offRamp.executeSingleReport( + _generateReportFromMessages( + SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) + ), + new uint256[](0) + ); + } + + function test_UnhealthySingleChainCurse_Revert() public { + s_mockRMN.setChainCursed(SOURCE_CHAIN_SELECTOR_1, true); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_1)); + s_offRamp.executeSingleReport( + _generateReportFromMessages( + SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) + ), + new uint256[](0) + ); + // Uncurse should succeed + s_mockRMN.setChainCursed(SOURCE_CHAIN_SELECTOR_1, false); + s_offRamp.executeSingleReport( + _generateReportFromMessages( + SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) + ), + new uint256[](0) + ); + } + + function test_UnexpectedTokenData_Revert() public { + Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages( + SOURCE_CHAIN_SELECTOR_1, _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) + ); + report.offchainTokenData = new bytes[][](report.messages.length + 1); + + vm.expectRevert(EVM2EVMMultiOffRamp.UnexpectedTokenData.selector); + + s_offRamp.executeSingleReport(report, new uint256[](0)); + } + + function test_EmptyReport_Revert() public { + vm.expectRevert(EVM2EVMMultiOffRamp.EmptyReport.selector); + s_offRamp.executeSingleReport( + Internal.ExecutionReportSingleChain({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + proofs: new bytes32[](0), + proofFlagBits: 0, + messages: new Internal.Any2EVMRampMessage[](0), + offchainTokenData: new bytes[][](0) + }), + new uint256[](0) + ); + } + + function test_RootNotCommitted_Revert() public { + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 0); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.RootNotCommitted.selector, SOURCE_CHAIN_SELECTOR_1)); + + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), _getGasLimitsFromMessages(messages) + ); + } + + function test_ManualExecutionNotYetEnabled_Revert() public { + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, BLOCK_TIME); + + vm.expectRevert( + abi.encodeWithSelector(EVM2EVMMultiOffRamp.ManualExecutionNotYetEnabled.selector, SOURCE_CHAIN_SELECTOR_1) + ); + + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), _getGasLimitsFromMessages(messages) + ); + } + + function test_NonExistingSourceChain_Revert() public { + uint64 newSourceChainSelector = SOURCE_CHAIN_SELECTOR_1 + 1; + bytes memory newOnRamp = abi.encode(ON_RAMP_ADDRESS, 1); + + Internal.Any2EVMRampMessage[] memory messages = _generateSingleBasicMessage(newSourceChainSelector, newOnRamp); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.SourceChainNotEnabled.selector, newSourceChainSelector)); + s_offRamp.executeSingleReport(_generateReportFromMessages(newSourceChainSelector, messages), new uint256[](0)); + } + + function test_DisabledSourceChain_Revert() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_2, ON_RAMP_ADDRESS_2); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.SourceChainNotEnabled.selector, SOURCE_CHAIN_SELECTOR_2)); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_2, messages), new uint256[](0)); + } + + function test_TokenDataMismatch_Revert() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + report.offchainTokenData[0] = new bytes[](messages[0].tokenAmounts.length + 1); + + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.TokenDataMismatch.selector, SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber + ) + ); + s_offRamp.executeSingleReport(report, new uint256[](0)); + } + + function test_RouterYULCall_Revert() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + // gas limit too high, Router's external call should revert + messages[0].gasLimit = 1e36; + messages[0].receiver = address(new ConformingReceiver(address(s_destRouter), s_destFeeToken)); + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + Internal.ExecutionReportSingleChain memory executionReport = + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector(CallWithExactGas.NotEnoughGasForCall.selector) + ); + s_offRamp.executeSingleReport(executionReport, new uint256[](0)); + } + + function test_RetryFailedMessageWithoutManualExecution_Revert() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + bytes memory realError1 = new bytes(2); + realError1[0] = 0xbe; + realError1[1] = 0xef; + s_reverting_receiver.setErr(realError1); + + messages[0].receiver = address(s_reverting_receiver); + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.ReceiverError.selector, + abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, realError1) + ) + ); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.AlreadyAttempted.selector, SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber + ) + ); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + } + + function _constructCommitReport(bytes32 merkleRoot) internal view returns (EVM2EVMMultiOffRamp.CommitReport memory) { + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + interval: EVM2EVMMultiOffRamp.Interval(1, 2), + merkleRoot: merkleRoot + }); + + return EVM2EVMMultiOffRamp.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots + }); + } +} + +contract EVM2EVMMultiOffRamp_executeSingleMessage is EVM2EVMMultiOffRampSetup { + function setUp() public virtual override { + super.setUp(); + _setupMultipleOffRamps(); + vm.startPrank(address(s_offRamp)); + } + + function test_executeSingleMessage_NoTokens_Success() public { + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + function test_executeSingleMessage_WithTokens_Success() public { + Internal.Any2EVMRampMessage memory message = + _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1)[0]; + bytes[] memory offchainTokenData = new bytes[](message.tokenAmounts.length); + + vm.expectCall( + s_destPoolByToken[s_destTokens[0]], + abi.encodeWithSelector( + LockReleaseTokenPool.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: message.sender, + receiver: message.receiver, + amount: message.tokenAmounts[0].amount, + localToken: abi.decode(message.tokenAmounts[0].destTokenAddress, (address)), + remoteChainSelector: SOURCE_CHAIN_SELECTOR_1, + sourcePoolAddress: message.tokenAmounts[0].sourcePoolAddress, + sourcePoolData: message.tokenAmounts[0].extraData, + offchainTokenData: offchainTokenData[0] + }) + ) + ); + + s_offRamp.executeSingleMessage(message, offchainTokenData); + } + + function test_executeSingleMessage_WithValidation_Success() public { + vm.stopPrank(); + vm.startPrank(OWNER); + _enableInboundMessageValidator(); + vm.startPrank(address(s_offRamp)); + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + function test_NonContract_Success() public { + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + message.receiver = STRANGER; + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + function test_NonContractWithTokens_Success() public { + uint256[] memory amounts = new uint256[](2); + amounts[0] = 1000; + amounts[1] = 50; + vm.expectEmit(); + emit TokenPool.Released(address(s_offRamp), STRANGER, amounts[0]); + vm.expectEmit(); + emit TokenPool.Minted(address(s_offRamp), STRANGER, amounts[1]); + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1, amounts); + message.receiver = STRANGER; + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + // Reverts + + function test_TokenHandlingError_Revert() public { + uint256[] memory amounts = new uint256[](2); + amounts[0] = 1000; + amounts[1] = 50; + + bytes memory errorMessage = "Random token pool issue"; + + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1, amounts); + s_maybeRevertingPool.setShouldRevert(errorMessage); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, errorMessage)); + + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + function test_ZeroGasDONExecution_Revert() public { + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + message.gasLimit = 0; + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.ReceiverError.selector, "")); + + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + function test_MessageSender_Revert() public { + vm.stopPrank(); + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + vm.expectRevert(EVM2EVMMultiOffRamp.CanOnlySelfCall.selector); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + function test_executeSingleMessage_WithFailingValidation_Revert() public { + vm.stopPrank(); + vm.startPrank(OWNER); + _enableInboundMessageValidator(); + vm.startPrank(address(s_offRamp)); + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + s_inboundMessageValidator.setMessageIdValidationState(message.header.messageId, true); + vm.expectRevert( + abi.encodeWithSelector( + IMessageInterceptor.MessageValidationError.selector, + abi.encodeWithSelector(IMessageInterceptor.MessageValidationError.selector, bytes("Invalid message")) + ) + ); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + function test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() public { + vm.stopPrank(); + vm.startPrank(OWNER); + _enableInboundMessageValidator(); + vm.startPrank(address(s_offRamp)); + + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + + // Setup the receiver to a non-CCIP Receiver, which will skip the Router call (but should still perform the validation) + MaybeRevertMessageReceiverNo165 newReceiver = new MaybeRevertMessageReceiverNo165(true); + message.receiver = address(newReceiver); + message.header.messageId = Internal._hash(message, ON_RAMP_ADDRESS_1); + + s_inboundMessageValidator.setMessageIdValidationState(message.header.messageId, true); + vm.expectRevert( + abi.encodeWithSelector( + IMessageInterceptor.MessageValidationError.selector, + abi.encodeWithSelector(IMessageInterceptor.MessageValidationError.selector, bytes("Invalid message")) + ) + ); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } +} + +contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { + function setUp() public virtual override { + super.setUp(); + _setupMultipleOffRamps(); + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 1); + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_3, 1); + } + + function test_SingleReport_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); + s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); + + assertGt(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender), nonceBefore); + } + + function test_MultipleReportsSameChain_Success() public { + Internal.Any2EVMRampMessage[] memory messages1 = new Internal.Any2EVMRampMessage[](2); + Internal.Any2EVMRampMessage[] memory messages2 = new Internal.Any2EVMRampMessage[](1); + + messages1[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + messages1[1] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 2); + messages2[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 3); + + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); + reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages1); + reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages2); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages1[0].header.sourceChainSelector, + messages1[0].header.sequenceNumber, + messages1[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages1[1].header.sourceChainSelector, + messages1[1].header.sequenceNumber, + messages1[1].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages2[0].header.sourceChainSelector, + messages2[0].header.sequenceNumber, + messages2[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages1[0].sender); + s_offRamp.batchExecute(reports, new uint256[][](2)); + assertGt(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages1[0].sender), nonceBefore); + } + + function test_MultipleReportsDifferentChains_Success() public { + Internal.Any2EVMRampMessage[] memory messages1 = new Internal.Any2EVMRampMessage[](2); + Internal.Any2EVMRampMessage[] memory messages2 = new Internal.Any2EVMRampMessage[](1); + + messages1[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + messages1[1] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 2); + messages2[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_3, ON_RAMP_ADDRESS_3, 1); + + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); + reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages1); + reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messages2); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages1[0].header.sourceChainSelector, + messages1[0].header.sequenceNumber, + messages1[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages1[1].header.sourceChainSelector, + messages1[1].header.sequenceNumber, + messages1[1].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages2[0].header.sourceChainSelector, + messages2[0].header.sequenceNumber, + messages2[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + s_offRamp.batchExecute(reports, new uint256[][](2)); + + uint64 nonceChain1 = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages1[0].sender); + uint64 nonceChain3 = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, messages2[0].sender); + + assertTrue(nonceChain1 != nonceChain3); + assertGt(nonceChain1, 0); + assertGt(nonceChain3, 0); + } + + function test_MultipleReportsSkipDuplicate_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); + reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); + + s_offRamp.batchExecute(reports, new uint256[][](2)); + } + + // Reverts + function test_ZeroReports_Revert() public { + vm.expectRevert(EVM2EVMMultiOffRamp.EmptyReport.selector); + s_offRamp.batchExecute(new Internal.ExecutionReportSingleChain[](0), new uint256[][](1)); + } + + function test_Unhealthy_Revert() public { + s_mockRMN.setGlobalCursed(true); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_1)); + s_offRamp.batchExecute( + _generateBatchReportFromMessages( + SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) + ), + new uint256[][](1) + ); + // Uncurse should succeed + s_mockRMN.setGlobalCursed(false); + s_offRamp.batchExecute( + _generateBatchReportFromMessages( + SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) + ), + new uint256[][](1) + ); + } + + function test_OutOfBoundsGasLimitsAccess_Revert() public { + Internal.Any2EVMRampMessage[] memory messages1 = new Internal.Any2EVMRampMessage[](2); + Internal.Any2EVMRampMessage[] memory messages2 = new Internal.Any2EVMRampMessage[](1); + + messages1[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + messages1[1] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 2); + messages2[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 3); + + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); + reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages1); + reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages2); + + vm.expectRevert(); + s_offRamp.batchExecute(reports, new uint256[][](1)); + } +} + +contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { + function setUp() public virtual override { + super.setUp(); + _setupMultipleOffRamps(); + + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 1); + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_3, 1); + } + + function test_manuallyExecute_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + messages[0].receiver = address(s_reverting_receiver); + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); + + s_reverting_receiver.setRevert(false); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + uint256[][] memory gasLimitOverrides = new uint256[][](1); + gasLimitOverrides[0] = new uint256[](messages.length); + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); + } + + function test_manuallyExecute_WithGasOverride_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + messages[0].receiver = address(s_reverting_receiver); + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); + + s_reverting_receiver.setRevert(false); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + uint256[][] memory gasLimitOverrides = new uint256[][](1); + gasLimitOverrides[0] = _getGasLimitsFromMessages(messages); + gasLimitOverrides[0][0] += 1; + + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); + } + + function test_manuallyExecute_DoesNotRevertIfUntouched_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + messages[0].receiver = address(s_reverting_receiver); + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + assertEq( + messages[0].header.nonce - 1, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender) + ); + + s_reverting_receiver.setRevert(true); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.ReceiverError.selector, + abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, "") + ) + ); + + uint256[][] memory gasLimitOverrides = new uint256[][](1); + gasLimitOverrides[0] = _getGasLimitsFromMessages(messages); + + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); + + assertEq( + messages[0].header.nonce, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender) + ); + } + + function test_manuallyExecute_WithMultiReportGasOverride_Success() public { + Internal.Any2EVMRampMessage[] memory messages1 = new Internal.Any2EVMRampMessage[](3); + Internal.Any2EVMRampMessage[] memory messages2 = new Internal.Any2EVMRampMessage[](2); + + for (uint64 i = 0; i < 3; ++i) { + messages1[i] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, i + 1); + messages1[i].receiver = address(s_reverting_receiver); + messages1[i].header.messageId = Internal._hash(messages1[i], ON_RAMP_ADDRESS_1); + } + + for (uint64 i = 0; i < 2; ++i) { + messages2[i] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_3, ON_RAMP_ADDRESS_3, i + 1); + messages2[i].receiver = address(s_reverting_receiver); + messages2[i].header.messageId = Internal._hash(messages2[i], ON_RAMP_ADDRESS_3); + } + + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); + reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages1); + reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messages2); + + s_offRamp.batchExecute(reports, new uint256[][](2)); + + s_reverting_receiver.setRevert(false); + + uint256[][] memory gasLimitOverrides = new uint256[][](2); + gasLimitOverrides[0] = _getGasLimitsFromMessages(messages1); + gasLimitOverrides[1] = _getGasLimitsFromMessages(messages2); + + for (uint256 i = 0; i < 3; ++i) { + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages1[i].header.sequenceNumber, + messages1[i].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + gasLimitOverrides[0][i] += 1; + } + + for (uint256 i = 0; i < 2; ++i) { + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_3, + messages2[i].header.sequenceNumber, + messages2[i].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + gasLimitOverrides[1][i] += 1; + } + + s_offRamp.manuallyExecute(reports, gasLimitOverrides); + } + + function test_manuallyExecute_WithPartialMessages_Success() public { + Internal.Any2EVMRampMessage[] memory messages = new Internal.Any2EVMRampMessage[](3); + + for (uint64 i = 0; i < 3; ++i) { + messages[i] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, i + 1); + } + messages[1].receiver = address(s_reverting_receiver); + messages[1].header.messageId = Internal._hash(messages[1], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[1].header.sequenceNumber, + messages[1].header.messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.ReceiverError.selector, + abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, bytes("")) + ) + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[2].header.sequenceNumber, + messages[2].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); + + s_reverting_receiver.setRevert(false); + + // Only the 2nd message reverted + Internal.Any2EVMRampMessage[] memory newMessages = new Internal.Any2EVMRampMessage[](1); + newMessages[0] = messages[1]; + + uint256[][] memory gasLimitOverrides = new uint256[][](1); + gasLimitOverrides[0] = _getGasLimitsFromMessages(newMessages); + gasLimitOverrides[0][0] += 1; + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + newMessages[0].header.sequenceNumber, + newMessages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, newMessages), gasLimitOverrides); + } + + function test_manuallyExecute_LowGasLimit_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + messages[0].gasLimit = 1; + messages[0].receiver = address(new ConformingReceiver(address(s_destRouter), s_destFeeToken)); + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector(EVM2EVMMultiOffRamp.ReceiverError.selector, "") + ); + s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); + + uint256[][] memory gasLimitOverrides = new uint256[][](1); + gasLimitOverrides[0] = new uint256[](1); + gasLimitOverrides[0][0] = 100_000; + + vm.expectEmit(); + emit ConformingReceiver.MessageReceived(); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); + } + + // Reverts + + function test_manuallyExecute_ForkedChain_Revert() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + Internal.ExecutionReportSingleChain[] memory reports = + _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + uint256 chain1 = block.chainid; + uint256 chain2 = chain1 + 1; + vm.chainId(chain2); + vm.expectRevert(abi.encodeWithSelector(MultiOCR3Base.ForkedChain.selector, chain1, chain2)); + + uint256[][] memory gasLimitOverrides = new uint256[][](1); + gasLimitOverrides[0] = _getGasLimitsFromMessages(messages); + + s_offRamp.manuallyExecute(reports, gasLimitOverrides); + } + + function test_ManualExecGasLimitMismatchSingleReport_Revert() public { + Internal.Any2EVMRampMessage[] memory messages = new Internal.Any2EVMRampMessage[](2); + messages[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + messages[1] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 2); + + Internal.ExecutionReportSingleChain[] memory reports = + _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + // No overrides for report + vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(reports, new uint256[][](0)); + + // No messages + uint256[][] memory gasLimitOverrides = new uint256[][](1); + + vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(reports, gasLimitOverrides); + + // 1 message missing + gasLimitOverrides[0] = new uint256[](1); + + vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(reports, gasLimitOverrides); + + // 1 message in excess + gasLimitOverrides[0] = new uint256[](3); + + vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(reports, gasLimitOverrides); + } + + function test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() public { + Internal.Any2EVMRampMessage[] memory messages1 = new Internal.Any2EVMRampMessage[](2); + Internal.Any2EVMRampMessage[] memory messages2 = new Internal.Any2EVMRampMessage[](1); + + messages1[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + messages1[1] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 2); + messages2[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_3, ON_RAMP_ADDRESS_3, 1); + + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); + reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages1); + reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messages2); + + vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(reports, new uint256[][](0)); + + vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(reports, new uint256[][](1)); + + uint256[][] memory gasLimitOverrides = new uint256[][](2); + + vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(reports, gasLimitOverrides); + + // 2nd report empty + gasLimitOverrides[0] = new uint256[](2); + + vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(reports, gasLimitOverrides); + + // 1st report empty + gasLimitOverrides[0] = new uint256[](0); + gasLimitOverrides[1] = new uint256[](1); + + vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(reports, gasLimitOverrides); + + // 1st report oversized + gasLimitOverrides[0] = new uint256[](3); + + vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(reports, gasLimitOverrides); + } + + function test_ManualExecInvalidGasLimit_Revert() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + uint256[][] memory gasLimitOverrides = new uint256[][](1); + gasLimitOverrides[0] = _getGasLimitsFromMessages(messages); + gasLimitOverrides[0][0]--; + + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.InvalidManualExecutionGasLimit.selector, SOURCE_CHAIN_SELECTOR_1, 0, gasLimitOverrides[0][0] + ) + ); + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); + } + + function test_manuallyExecute_FailedTx_Revert() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + messages[0].receiver = address(s_reverting_receiver); + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); + + s_reverting_receiver.setRevert(true); + + uint256[][] memory gasLimitOverrides = new uint256[][](1); + gasLimitOverrides[0] = _getGasLimitsFromMessages(messages); + + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.ExecutionError.selector, + messages[0].header.messageId, + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.ReceiverError.selector, + abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, bytes("")) + ) + ) + ); + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); + } + + function test_manuallyExecute_ReentrancyFails() public { + uint256 tokenAmount = 1e9; + IERC20 tokenToAbuse = IERC20(s_destFeeToken); + + // This needs to be deployed before the source chain message is sent + // because we need the address for the receiver. + ReentrancyAbuserMultiRamp receiver = new ReentrancyAbuserMultiRamp(address(s_destRouter), s_offRamp); + uint256 balancePre = tokenToAbuse.balanceOf(address(receiver)); + + // For this test any message will be flagged as correct by the + // commitStore. In a real scenario the abuser would have to actually + // send the message that they want to replay. + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + messages[0].tokenAmounts = new Internal.RampTokenAmount[](1); + messages[0].tokenAmounts[0] = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[s_sourceFeeToken]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[s_sourceFeeToken]), + extraData: "", + amount: tokenAmount + }); + + messages[0].receiver = address(receiver); + + messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); + + Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + // sets the report to be repeated on the ReentrancyAbuser to be able to replay + receiver.setPayload(report); + + uint256[][] memory gasLimitOverrides = new uint256[][](1); + gasLimitOverrides[0] = _getGasLimitsFromMessages(messages); + + // The first entry should be fine and triggers the second entry. This one fails + // but since it's an inner tx of the first one it is caught in the try-catch. + // This means the first tx is marked `FAILURE` with the error message of the second tx. + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.ReceiverError.selector, + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.AlreadyExecuted.selector, + messages[0].header.sourceChainSelector, + messages[0].header.sequenceNumber + ) + ) + ); + + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); + + // Since the tx failed we don't release the tokens + assertEq(tokenToAbuse.balanceOf(address(receiver)), balancePre); + } +} + +contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { + function setUp() public virtual override { + super.setUp(); + _setupMultipleOffRamps(); + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 1); + } + + // Asserts that execute completes + function test_SingleReport_Success() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + Internal.ExecutionReportSingleChain[] memory reports = + _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted( + uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) + ); + + _execute(reports); + } + + function test_MultipleReports_Success() public { + Internal.Any2EVMRampMessage[] memory messages1 = new Internal.Any2EVMRampMessage[](2); + Internal.Any2EVMRampMessage[] memory messages2 = new Internal.Any2EVMRampMessage[](1); + + messages1[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + messages1[1] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 2); + messages2[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 3); + + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); + reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages1); + reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages2); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages1[0].header.sourceChainSelector, + messages1[0].header.sequenceNumber, + messages1[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages1[1].header.sourceChainSelector, + messages1[1].header.sequenceNumber, + messages1[1].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages2[0].header.sourceChainSelector, + messages2[0].header.sequenceNumber, + messages2[0].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted( + uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) + ); + + _execute(reports); + } + + function test_LargeBatch_Success() public { + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](10); + for (uint64 i = 0; i < reports.length; ++i) { + Internal.Any2EVMRampMessage[] memory messages = new Internal.Any2EVMRampMessage[](3); + messages[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1 + i * 3); + messages[1] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 2 + i * 3); + messages[2] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 3 + i * 3); + + reports[i] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + } + + for (uint64 i = 0; i < reports.length; ++i) { + for (uint64 j = 0; j < reports[i].messages.length; ++j) { + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + reports[i].messages[j].header.sourceChainSelector, + reports[i].messages[j].header.sequenceNumber, + reports[i].messages[j].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + } + } + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted( + uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) + ); + + _execute(reports); + } + + function test_MultipleReportsWithPartialValidationFailures_Success() public { + _enableInboundMessageValidator(); + + Internal.Any2EVMRampMessage[] memory messages1 = new Internal.Any2EVMRampMessage[](2); + Internal.Any2EVMRampMessage[] memory messages2 = new Internal.Any2EVMRampMessage[](1); + + messages1[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + messages1[1] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 2); + messages2[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 3); + + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); + reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages1); + reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages2); + + s_inboundMessageValidator.setMessageIdValidationState(messages1[0].header.messageId, true); + s_inboundMessageValidator.setMessageIdValidationState(messages2[0].header.messageId, true); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages1[0].header.sourceChainSelector, + messages1[0].header.sequenceNumber, + messages1[0].header.messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + IMessageInterceptor.MessageValidationError.selector, + abi.encodeWithSelector(IMessageInterceptor.MessageValidationError.selector, bytes("Invalid message")) + ) + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages1[1].header.sourceChainSelector, + messages1[1].header.sequenceNumber, + messages1[1].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + messages2[0].header.sourceChainSelector, + messages2[0].header.sequenceNumber, + messages2[0].header.messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + IMessageInterceptor.MessageValidationError.selector, + abi.encodeWithSelector(IMessageInterceptor.MessageValidationError.selector, bytes("Invalid message")) + ) + ); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted( + uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) + ); + + _execute(reports); + } + + // Reverts + + function test_UnauthorizedTransmitter_Revert() public { + bytes32[3] memory reportContext = [s_configDigestExec, s_configDigestExec, s_configDigestExec]; + + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + Internal.ExecutionReportSingleChain[] memory reports = + _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + vm.expectRevert(MultiOCR3Base.UnauthorizedTransmitter.selector); + s_offRamp.execute(reportContext, abi.encode(reports)); + } + + function test_NoConfig_Revert() public { + _redeployOffRampWithNoOCRConfigs(); + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 1); + + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + Internal.ExecutionReportSingleChain[] memory reports = + _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + bytes32[3] memory reportContext = [bytes32(""), s_configDigestExec, s_configDigestExec]; + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(MultiOCR3Base.UnauthorizedTransmitter.selector); + s_offRamp.execute(reportContext, abi.encode(reports)); + } + + function test_NoConfigWithOtherConfigPresent_Revert() public { + _redeployOffRampWithNoOCRConfigs(); + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 1); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: uint8(Internal.OCRPluginType.Commit), + configDigest: s_configDigestCommit, + F: s_F, + isSignatureVerificationEnabled: false, + signers: s_emptySigners, + transmitters: s_validTransmitters + }); + s_offRamp.setOCR3Configs(ocrConfigs); + + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + Internal.ExecutionReportSingleChain[] memory reports = + _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + bytes32[3] memory reportContext = [bytes32(""), s_configDigestExec, s_configDigestExec]; + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(MultiOCR3Base.UnauthorizedTransmitter.selector); + s_offRamp.execute(reportContext, abi.encode(reports)); + } + + function test_WrongConfigWithSigners_Revert() public { + _redeployOffRampWithNoOCRConfigs(); + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 1); + + s_configDigestExec = _getBasicConfigDigest(1, s_validSigners, s_validTransmitters); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: uint8(Internal.OCRPluginType.Execution), + configDigest: s_configDigestExec, + F: s_F, + isSignatureVerificationEnabled: true, + signers: s_validSigners, + transmitters: s_validTransmitters + }); + s_offRamp.setOCR3Configs(ocrConfigs); + + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + Internal.ExecutionReportSingleChain[] memory reports = + _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + vm.expectRevert(); + _execute(reports); + } + + function test_ZeroReports_Revert() public { + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](0); + + vm.expectRevert(EVM2EVMMultiOffRamp.EmptyReport.selector); + _execute(reports); + } + + function test_IncorrectArrayType_Revert() public { + bytes32[3] memory reportContext = [s_configDigestExec, s_configDigestExec, s_configDigestExec]; + + uint256[] memory wrongData = new uint256[](1); + wrongData[0] = 1; + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(); + s_offRamp.execute(reportContext, abi.encode(wrongData)); + } + + function test_NonArray_Revert() public { + bytes32[3] memory reportContext = [s_configDigestExec, s_configDigestExec, s_configDigestExec]; + + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(); + s_offRamp.execute(reportContext, abi.encode(report)); + } +} + +contract EVM2EVMMultiOffRamp_getExecutionState is EVM2EVMMultiOffRampSetup { + mapping(uint64 sourceChainSelector => mapping(uint64 seqNum => Internal.MessageExecutionState state)) internal + s_differentialExecutionState; + + /// forge-config: default.fuzz.runs = 32 + /// forge-config: ccip.fuzz.runs = 32 + function test_Fuzz_Differential_Success( + uint64 sourceChainSelector, + uint16[500] memory seqNums, + uint8[500] memory values + ) public { + for (uint256 i = 0; i < seqNums.length; ++i) { + // Only use the first three slots. This makes sure existing slots get overwritten + // as the tests uses 500 sequence numbers. + uint16 seqNum = seqNums[i] % 386; + Internal.MessageExecutionState state = Internal.MessageExecutionState(values[i] % 4); + s_differentialExecutionState[sourceChainSelector][seqNum] = state; + s_offRamp.setExecutionStateHelper(sourceChainSelector, seqNum, state); + assertEq(uint256(state), uint256(s_offRamp.getExecutionState(sourceChainSelector, seqNum))); + } + + for (uint256 i = 0; i < seqNums.length; ++i) { + uint16 seqNum = seqNums[i] % 386; + Internal.MessageExecutionState expectedState = s_differentialExecutionState[sourceChainSelector][seqNum]; + assertEq(uint256(expectedState), uint256(s_offRamp.getExecutionState(sourceChainSelector, seqNum))); + } + } + + function test_GetExecutionState_Success() public { + s_offRamp.setExecutionStateHelper(SOURCE_CHAIN_SELECTOR_1, 0, Internal.MessageExecutionState.FAILURE); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 0), 3); + + s_offRamp.setExecutionStateHelper(SOURCE_CHAIN_SELECTOR_1, 1, Internal.MessageExecutionState.FAILURE); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 0), 3 + (3 << 2)); + + s_offRamp.setExecutionStateHelper(SOURCE_CHAIN_SELECTOR_1, 1, Internal.MessageExecutionState.IN_PROGRESS); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 0), 3 + (1 << 2)); + + s_offRamp.setExecutionStateHelper(SOURCE_CHAIN_SELECTOR_1, 2, Internal.MessageExecutionState.FAILURE); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 0), 3 + (1 << 2) + (3 << 4)); + + s_offRamp.setExecutionStateHelper(SOURCE_CHAIN_SELECTOR_1, 127, Internal.MessageExecutionState.IN_PROGRESS); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 0), 3 + (1 << 2) + (3 << 4) + (1 << 254)); + + s_offRamp.setExecutionStateHelper(SOURCE_CHAIN_SELECTOR_1, 128, Internal.MessageExecutionState.SUCCESS); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 0), 3 + (1 << 2) + (3 << 4) + (1 << 254)); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 1), 2); + + assertEq( + uint256(Internal.MessageExecutionState.FAILURE), uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1, 0)) + ); + assertEq( + uint256(Internal.MessageExecutionState.IN_PROGRESS), + uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1, 1)) + ); + assertEq( + uint256(Internal.MessageExecutionState.FAILURE), uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1, 2)) + ); + assertEq( + uint256(Internal.MessageExecutionState.IN_PROGRESS), + uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1, 127)) + ); + assertEq( + uint256(Internal.MessageExecutionState.SUCCESS), + uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1, 128)) + ); + } + + function test_GetDifferentChainExecutionState_Success() public { + s_offRamp.setExecutionStateHelper(SOURCE_CHAIN_SELECTOR_1, 0, Internal.MessageExecutionState.FAILURE); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 0), 3); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1 + 1, 0), 0); + + s_offRamp.setExecutionStateHelper(SOURCE_CHAIN_SELECTOR_1, 127, Internal.MessageExecutionState.IN_PROGRESS); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 0), 3 + (1 << 254)); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1 + 1, 0), 0); + + s_offRamp.setExecutionStateHelper(SOURCE_CHAIN_SELECTOR_1, 128, Internal.MessageExecutionState.SUCCESS); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 0), 3 + (1 << 254)); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 1), 2); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1 + 1, 0), 0); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1 + 1, 1), 0); + + s_offRamp.setExecutionStateHelper(SOURCE_CHAIN_SELECTOR_1 + 1, 127, Internal.MessageExecutionState.FAILURE); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 0), 3 + (1 << 254)); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, 1), 2); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1 + 1, 0), (3 << 254)); + assertEq(s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1 + 1, 1), 0); + + assertEq( + uint256(Internal.MessageExecutionState.FAILURE), uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1, 0)) + ); + assertEq( + uint256(Internal.MessageExecutionState.IN_PROGRESS), + uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1, 127)) + ); + assertEq( + uint256(Internal.MessageExecutionState.SUCCESS), + uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1, 128)) + ); + + assertEq( + uint256(Internal.MessageExecutionState.UNTOUCHED), + uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1 + 1, 0)) + ); + assertEq( + uint256(Internal.MessageExecutionState.FAILURE), + uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1 + 1, 127)) + ); + assertEq( + uint256(Internal.MessageExecutionState.UNTOUCHED), + uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1 + 1, 128)) + ); + } + + function test_FillExecutionState_Success() public { + for (uint64 i = 0; i < 384; ++i) { + s_offRamp.setExecutionStateHelper(SOURCE_CHAIN_SELECTOR_1, i, Internal.MessageExecutionState.FAILURE); + } + + for (uint64 i = 0; i < 384; ++i) { + assertEq( + uint256(Internal.MessageExecutionState.FAILURE), + uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1, i)) + ); + } + + for (uint64 i = 0; i < 3; ++i) { + assertEq(type(uint256).max, s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, i)); + } + + for (uint64 i = 0; i < 384; ++i) { + s_offRamp.setExecutionStateHelper(SOURCE_CHAIN_SELECTOR_1, i, Internal.MessageExecutionState.IN_PROGRESS); + } + + for (uint64 i = 0; i < 384; ++i) { + assertEq( + uint256(Internal.MessageExecutionState.IN_PROGRESS), + uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1, i)) + ); + } + + for (uint64 i = 0; i < 3; ++i) { + // 0x555... == 0b101010101010..... + assertEq( + 0x5555555555555555555555555555555555555555555555555555555555555555, + s_offRamp.getExecutionStateBitMap(SOURCE_CHAIN_SELECTOR_1, i) + ); + } + } +} + +contract EVM2EVMMultiOffRamp_trialExecute is EVM2EVMMultiOffRampSetup { + function setUp() public virtual override { + super.setUp(); + _setupMultipleOffRamps(); + } + + function test_trialExecute_Success() public { + uint256[] memory amounts = new uint256[](2); + amounts[0] = 1000; + amounts[1] = 50; + + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1, amounts); + IERC20 dstToken0 = IERC20(s_destTokens[0]); + uint256 startingBalance = dstToken0.balanceOf(message.receiver); + + (Internal.MessageExecutionState newState, bytes memory err) = + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); + assertEq("", err); + + // Check that the tokens were transferred + assertEq(startingBalance + amounts[0], dstToken0.balanceOf(message.receiver)); + } + + function test_TokenHandlingErrorIsCaught_Success() public { + uint256[] memory amounts = new uint256[](2); + amounts[0] = 1000; + amounts[1] = 50; + + IERC20 dstToken0 = IERC20(s_destTokens[0]); + uint256 startingBalance = dstToken0.balanceOf(OWNER); + + bytes memory errorMessage = "Random token pool issue"; + + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1, amounts); + s_maybeRevertingPool.setShouldRevert(errorMessage); + + (Internal.MessageExecutionState newState, bytes memory err) = + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); + assertEq(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, errorMessage), err); + + // Expect the balance to remain the same + assertEq(startingBalance, dstToken0.balanceOf(OWNER)); + } + + function test_RateLimitError_Success() public { + uint256[] memory amounts = new uint256[](2); + amounts[0] = 1000; + amounts[1] = 50; + + bytes memory errorMessage = abi.encodeWithSelector(RateLimiter.BucketOverfilled.selector); + + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1, amounts); + s_maybeRevertingPool.setShouldRevert(errorMessage); + + (Internal.MessageExecutionState newState, bytes memory err) = + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); + assertEq(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, errorMessage), err); + } + + // TODO test actual pool exists but isn't compatible instead of just no pool + function test_TokenPoolIsNotAContract_Success() public { + uint256[] memory amounts = new uint256[](2); + amounts[0] = 10000; + Internal.Any2EVMRampMessage memory message = + _generateAny2EVMMessageWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1, amounts); + + // Happy path, pool is correct + (Internal.MessageExecutionState newState, bytes memory err) = + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + + assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); + assertEq("", err); + + // address 0 has no contract + assertEq(address(0).code.length, 0); + + message.tokenAmounts[0] = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(address(0)), + destTokenAddress: abi.encode(address(0)), + extraData: "", + amount: message.tokenAmounts[0].amount + }); + + message.header.messageId = Internal._hash(message, ON_RAMP_ADDRESS_1); + + // Unhappy path, no revert but marked as failed. + (newState, err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); + assertEq(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, abi.encode(address(0))), err); + + address notAContract = makeAddr("not_a_contract"); + + message.tokenAmounts[0] = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(address(0)), + destTokenAddress: abi.encode(notAContract), + extraData: "", + amount: message.tokenAmounts[0].amount + }); + + message.header.messageId = Internal._hash(message, ON_RAMP_ADDRESS_1); + + (newState, err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); + assertEq(abi.encodeWithSelector(EVM2EVMMultiOffRamp.NotACompatiblePool.selector, address(0)), err); + } +} + +contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSetup { + function setUp() public virtual override { + super.setUp(); + _setupMultipleOffRamps(); + } + + function test__releaseOrMintSingleToken_Success() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + bytes memory originalSender = abi.encode(OWNER); + bytes memory offchainTokenData = abi.encode(keccak256("offchainTokenData")); + + IERC20 dstToken1 = IERC20(s_destTokenBySourceToken[token]); + uint256 startingBalance = dstToken1.balanceOf(OWNER); + + Internal.RampTokenAmount memory tokenAmount = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), + extraData: "", + amount: amount + }); + + vm.expectCall( + s_destPoolBySourceToken[token], + abi.encodeWithSelector( + LockReleaseTokenPool.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: originalSender, + receiver: OWNER, + amount: amount, + localToken: s_destTokenBySourceToken[token], + remoteChainSelector: SOURCE_CHAIN_SELECTOR_1, + sourcePoolAddress: tokenAmount.sourcePoolAddress, + sourcePoolData: tokenAmount.extraData, + offchainTokenData: offchainTokenData + }) + ) + ); + + s_offRamp.releaseOrMintSingleToken(tokenAmount, originalSender, OWNER, SOURCE_CHAIN_SELECTOR_1, offchainTokenData); + + assertEq(startingBalance + amount, dstToken1.balanceOf(OWNER)); + } + + function test__releaseOrMintSingleToken_NotACompatiblePool_Revert() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + address destToken = s_destTokenBySourceToken[token]; + vm.label(destToken, "destToken"); + bytes memory originalSender = abi.encode(OWNER); + bytes memory offchainTokenData = abi.encode(keccak256("offchainTokenData")); + + Internal.RampTokenAmount memory tokenAmount = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(destToken), + extraData: "", + amount: amount + }); + + // Address(0) should always revert + address returnedPool = address(0); + + vm.mockCall( + address(s_tokenAdminRegistry), + abi.encodeWithSelector(ITokenAdminRegistry.getPool.selector, destToken), + abi.encode(returnedPool) + ); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.NotACompatiblePool.selector, returnedPool)); + + s_offRamp.releaseOrMintSingleToken(tokenAmount, originalSender, OWNER, SOURCE_CHAIN_SELECTOR_1, offchainTokenData); + + // A contract that doesn't support the interface should also revert + returnedPool = address(s_offRamp); + + vm.mockCall( + address(s_tokenAdminRegistry), + abi.encodeWithSelector(ITokenAdminRegistry.getPool.selector, destToken), + abi.encode(returnedPool) + ); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.NotACompatiblePool.selector, returnedPool)); + + s_offRamp.releaseOrMintSingleToken(tokenAmount, originalSender, OWNER, SOURCE_CHAIN_SELECTOR_1, offchainTokenData); + } + + function test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() public { + address receiver = makeAddr("receiver"); + uint256 amount = 123123; + address token = s_sourceTokens[0]; + address destToken = s_destTokenBySourceToken[token]; + bytes memory originalSender = abi.encode(OWNER); + bytes memory offchainTokenData = abi.encode(keccak256("offchainTokenData")); + + Internal.RampTokenAmount memory tokenAmount = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(destToken), + extraData: "", + amount: amount + }); + + bytes memory revertData = "call reverted :o"; + + vm.mockCallRevert(destToken, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount), revertData); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, revertData)); + s_offRamp.releaseOrMintSingleToken( + tokenAmount, originalSender, receiver, SOURCE_CHAIN_SELECTOR_1, offchainTokenData + ); + } +} + +contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { + function setUp() public virtual override { + super.setUp(); + _setupMultipleOffRamps(); + } + + function test_releaseOrMintTokens_Success() public { + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + IERC20 dstToken1 = IERC20(s_destFeeToken); + uint256 startingBalance = dstToken1.balanceOf(OWNER); + uint256 amount1 = 100; + srcTokenAmounts[0].amount = amount1; + + bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); + offchainTokenData[0] = abi.encode(0x12345678); + + Internal.RampTokenAmount[] memory sourceTokenAmounts = _getDefaultSourceTokenData(srcTokenAmounts); + + vm.expectCall( + s_destPoolBySourceToken[srcTokenAmounts[0].token], + abi.encodeWithSelector( + LockReleaseTokenPool.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + receiver: OWNER, + amount: srcTokenAmounts[0].amount, + localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], + remoteChainSelector: SOURCE_CHAIN_SELECTOR_1, + sourcePoolAddress: sourceTokenAmounts[0].sourcePoolAddress, + sourcePoolData: sourceTokenAmounts[0].extraData, + offchainTokenData: offchainTokenData[0] + }) + ) + ); + + s_offRamp.releaseOrMintTokens( + sourceTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, offchainTokenData + ); + + assertEq(startingBalance + amount1, dstToken1.balanceOf(OWNER)); + } + + function test_releaseOrMintTokens_destDenominatedDecimals_Success() public { + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + address destToken = s_destFeeToken; + uint256 amount = 100; + uint256 destinationDenominationMultiplier = 1000; + srcTokenAmounts[0].amount = amount; + + bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); + + Internal.RampTokenAmount[] memory sourceTokenAmounts = _getDefaultSourceTokenData(srcTokenAmounts); + + // Since the pool call is mocked, we manually release funds to the offRamp + deal(destToken, address(s_offRamp), amount * destinationDenominationMultiplier); + + vm.mockCall( + s_destPoolBySourceToken[srcTokenAmounts[0].token], + abi.encodeWithSelector( + LockReleaseTokenPool.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + receiver: OWNER, + amount: amount, + localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], + remoteChainSelector: SOURCE_CHAIN_SELECTOR_1, + sourcePoolAddress: sourceTokenAmounts[0].sourcePoolAddress, + sourcePoolData: sourceTokenAmounts[0].extraData, + offchainTokenData: offchainTokenData[0] + }) + ), + abi.encode(amount * destinationDenominationMultiplier) + ); + + Client.EVMTokenAmount[] memory destTokenAmounts = s_offRamp.releaseOrMintTokens( + sourceTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, offchainTokenData + ); + + assertEq(destTokenAmounts[0].amount, amount * destinationDenominationMultiplier); + assertEq(destTokenAmounts[0].token, destToken); + } + + // Revert + + function test_TokenHandlingError_Reverts() public { + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + + bytes memory unknownError = bytes("unknown error"); + s_maybeRevertingPool.setShouldRevert(unknownError); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, unknownError)); + + s_offRamp.releaseOrMintTokens( + _getDefaultSourceTokenData(srcTokenAmounts), + abi.encode(OWNER), + OWNER, + SOURCE_CHAIN_SELECTOR_1, + new bytes[](srcTokenAmounts.length) + ); + } + + function test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() public { + uint256 amount = 100; + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + srcTokenAmounts[0].amount = amount; + + bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); + Internal.RampTokenAmount[] memory sourceTokenAmounts = _getDefaultSourceTokenData(srcTokenAmounts); + + vm.mockCall( + s_destPoolBySourceToken[srcTokenAmounts[0].token], + abi.encodeWithSelector( + LockReleaseTokenPool.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + receiver: OWNER, + amount: amount, + localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], + remoteChainSelector: SOURCE_CHAIN_SELECTOR_1, + sourcePoolAddress: sourceTokenAmounts[0].sourcePoolAddress, + sourcePoolData: sourceTokenAmounts[0].extraData, + offchainTokenData: offchainTokenData[0] + }) + ), + // Includes the amount twice, this will revert due to the return data being to long + abi.encode(amount, amount) + ); + + vm.expectRevert( + abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidDataLength.selector, Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, 64) + ); + + s_offRamp.releaseOrMintTokens( + sourceTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, offchainTokenData + ); + } + + function test_releaseOrMintTokens_InvalidEVMAddress_Revert() public { + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + + bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); + Internal.RampTokenAmount[] memory sourceTokenAmounts = _getDefaultSourceTokenData(srcTokenAmounts); + bytes memory wrongAddress = abi.encode(address(1000), address(10000), address(10000)); + + sourceTokenAmounts[0].destTokenAddress = wrongAddress; + + vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, wrongAddress)); + + s_offRamp.releaseOrMintTokens( + sourceTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, offchainTokenData + ); + } + + function test__releaseOrMintTokens_PoolIsNotAPool_Reverts() public { + // The offRamp is a contract, but not a pool + address fakePoolAddress = address(s_offRamp); + + Internal.RampTokenAmount[] memory sourceTokenAmounts = new Internal.RampTokenAmount[](1); + sourceTokenAmounts[0] = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(fakePoolAddress), + destTokenAddress: abi.encode(s_offRamp), + extraData: "", + amount: 1 + }); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.NotACompatiblePool.selector, address(0))); + s_offRamp.releaseOrMintTokens(sourceTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, new bytes[](1)); + } + + function test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() public { + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + uint256 amount1 = 100; + srcTokenAmounts[0].amount = amount1; + + bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); + offchainTokenData[0] = abi.encode(0x12345678); + + Internal.RampTokenAmount[] memory sourceTokenAmounts = _getDefaultSourceTokenData(srcTokenAmounts); + + vm.expectCall( + s_destPoolBySourceToken[srcTokenAmounts[0].token], + abi.encodeWithSelector( + LockReleaseTokenPool.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + receiver: OWNER, + amount: srcTokenAmounts[0].amount, + localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], + remoteChainSelector: SOURCE_CHAIN_SELECTOR_3, + sourcePoolAddress: sourceTokenAmounts[0].sourcePoolAddress, + sourcePoolData: sourceTokenAmounts[0].extraData, + offchainTokenData: offchainTokenData[0] + }) + ) + ); + vm.expectRevert(); + s_offRamp.releaseOrMintTokens( + sourceTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_3, offchainTokenData + ); + } + + /// forge-config: default.fuzz.runs = 32 + /// forge-config: ccip.fuzz.runs = 1024 + // Uint256 gives a good range of values to test, both inside and outside of the eth address space. + function test_Fuzz__releaseOrMintTokens_AnyRevertIsCaught_Success(uint256 destPool) public { + // Input 447301751254033913445893214690834296930546521452, which is 0x4E59B44847B379578588920CA78FBF26C0B4956C + // triggers some Create2Deployer and causes it to fail + vm.assume(destPool != 447301751254033913445893214690834296930546521452); + bytes memory unusedVar = abi.encode(makeAddr("unused")); + Internal.RampTokenAmount[] memory sourceTokenAmounts = new Internal.RampTokenAmount[](1); + sourceTokenAmounts[0] = Internal.RampTokenAmount({ + sourcePoolAddress: unusedVar, + destTokenAddress: abi.encode(destPool), + extraData: unusedVar, + amount: 1 + }); + + try s_offRamp.releaseOrMintTokens( + sourceTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, new bytes[](1) + ) {} catch (bytes memory reason) { + // Any revert should be a TokenHandlingError, InvalidEVMAddress, InvalidDataLength or NoContract as those are caught by the offramp + assertTrue( + bytes4(reason) == EVM2EVMMultiOffRamp.TokenHandlingError.selector + || bytes4(reason) == Internal.InvalidEVMAddress.selector + || bytes4(reason) == EVM2EVMMultiOffRamp.InvalidDataLength.selector + || bytes4(reason) == CallWithExactGas.NoContract.selector + || bytes4(reason) == EVM2EVMMultiOffRamp.NotACompatiblePool.selector, + "Expected TokenHandlingError or InvalidEVMAddress" + ); + + if (destPool > type(uint160).max) { + assertEq(reason, abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, abi.encode(destPool))); + } + } + } +} + +contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRampSetup { + function test_ApplyZeroUpdates_Success() public { + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); + + vm.recordLogs(); + s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); + + // No logs emitted + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + assertEq(logEntries.length, 0); + + // assertEq(s_offRamp.getSourceChainSelectors().length, 0); + } + + function test_AddNewChain_Success() public { + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + onRamp: ON_RAMP_ADDRESS_1, + isEnabled: true + }); + + EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig = + EVM2EVMMultiOffRamp.SourceChainConfig({isEnabled: true, minSeqNr: 1, onRamp: ON_RAMP_ADDRESS_1}); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SourceChainSelectorAdded(SOURCE_CHAIN_SELECTOR_1); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1, expectedSourceChainConfig); + + s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); + + _assertSourceChainConfigEquality(s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR_1), expectedSourceChainConfig); + } + + function test_ReplaceExistingChain_Success() public { + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + onRamp: ON_RAMP_ADDRESS_1, + isEnabled: true + }); + + s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); + + sourceChainConfigs[0].isEnabled = false; + EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig = + EVM2EVMMultiOffRamp.SourceChainConfig({isEnabled: false, minSeqNr: 1, onRamp: ON_RAMP_ADDRESS_1}); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1, expectedSourceChainConfig); + + vm.recordLogs(); + s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); + + // No log emitted for chain selector added (only for setting the config) + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + assertEq(logEntries.length, 1); + + _assertSourceChainConfigEquality(s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR_1), expectedSourceChainConfig); + + // uint64[] memory resultSourceChainSelectors = s_offRamp.getSourceChainSelectors(); + // assertEq(resultSourceChainSelectors.length, 1); + // assertEq(resultSourceChainSelectors[0], SOURCE_CHAIN_SELECTOR_1); + } + + function test_AddMultipleChains_Success() public { + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](3); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + onRamp: abi.encode(ON_RAMP_ADDRESS_1, 0), + isEnabled: true + }); + sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1 + 1, + onRamp: abi.encode(ON_RAMP_ADDRESS_1, 1), + isEnabled: false + }); + sourceChainConfigs[2] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1 + 2, + onRamp: abi.encode(ON_RAMP_ADDRESS_1, 2), + isEnabled: true + }); + + EVM2EVMMultiOffRamp.SourceChainConfig[] memory expectedSourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfig[](3); + for (uint256 i = 0; i < 3; ++i) { + expectedSourceChainConfigs[i] = EVM2EVMMultiOffRamp.SourceChainConfig({ + isEnabled: sourceChainConfigs[i].isEnabled, + minSeqNr: 1, + onRamp: abi.encode(ON_RAMP_ADDRESS_1, i) + }); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SourceChainSelectorAdded(sourceChainConfigs[i].sourceChainSelector); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SourceChainConfigSet( + sourceChainConfigs[i].sourceChainSelector, expectedSourceChainConfigs[i] + ); + } + + s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); + + for (uint256 i = 0; i < 3; ++i) { + _assertSourceChainConfigEquality( + s_offRamp.getSourceChainConfig(sourceChainConfigs[i].sourceChainSelector), expectedSourceChainConfigs[i] + ); + } + } + + function test_Fuzz_applySourceChainConfigUpdate_Success( + EVM2EVMMultiOffRamp.SourceChainConfigArgs memory sourceChainConfigArgs + ) public { + // Skip invalid inputs + vm.assume(sourceChainConfigArgs.sourceChainSelector != 0); + vm.assume(sourceChainConfigArgs.onRamp.length != 0); + + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](2); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + onRamp: ON_RAMP_ADDRESS_1, + isEnabled: true + }); + sourceChainConfigs[1] = sourceChainConfigArgs; + + // Handle cases when an update occurs + bool isNewChain = sourceChainConfigs[1].sourceChainSelector != SOURCE_CHAIN_SELECTOR_1; + if (!isNewChain) { + sourceChainConfigs[1].onRamp = sourceChainConfigs[0].onRamp; + } + + EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig = EVM2EVMMultiOffRamp.SourceChainConfig({ + isEnabled: sourceChainConfigArgs.isEnabled, + minSeqNr: 1, + onRamp: sourceChainConfigArgs.onRamp + }); + + if (isNewChain) { + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SourceChainSelectorAdded(sourceChainConfigArgs.sourceChainSelector); + } + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SourceChainConfigSet(sourceChainConfigArgs.sourceChainSelector, expectedSourceChainConfig); + + s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); + + _assertSourceChainConfigEquality( + s_offRamp.getSourceChainConfig(sourceChainConfigArgs.sourceChainSelector), expectedSourceChainConfig + ); + } + + // Reverts + + function test_ZeroOnRampAddress_Revert() public { + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + onRamp: new bytes(0), + isEnabled: true + }); + + vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); + } + + function test_ZeroSourceChainSelector_Revert() public { + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = + EVM2EVMMultiOffRamp.SourceChainConfigArgs({sourceChainSelector: 0, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true}); + + vm.expectRevert(EVM2EVMMultiOffRamp.ZeroChainSelectorNotAllowed.selector); + s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); + } + + function test_ReplaceExistingChainOnRamp_Revert() public { + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + onRamp: ON_RAMP_ADDRESS_1, + isEnabled: true + }); + + s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); + + sourceChainConfigs[0].onRamp = ON_RAMP_ADDRESS_2; + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidStaticConfig.selector, SOURCE_CHAIN_SELECTOR_1)); + s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); + } +} + +contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { + uint64 internal s_maxInterval = 12; + + function setUp() public virtual override { + super.setUp(); + _setupMultipleOffRamps(); + + s_latestSequenceNumber = uint64(uint256(s_configDigestCommit)); + } + + function test_ReportAndPriceUpdate_Success() public { + EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + + assertEq(s_maxInterval + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); + assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); + } + + function test_ReportOnlyRootSuccess_gas() public { + uint64 max1 = 931; + bytes32 root = "Only a single root"; + + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + interval: EVM2EVMMultiOffRamp.Interval(1, max1), + merkleRoot: root + }); + + EVM2EVMMultiOffRamp.CommitReport memory commitReport = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + + assertEq(max1 + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); + assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); + assertEq(block.timestamp, s_offRamp.getMerkleRoot(SOURCE_CHAIN_SELECTOR_1, root)); + } + + function test_StaleReportWithRoot_Success() public { + uint64 maxSeq = 12; + uint224 tokenStartPrice = + IPriceRegistry(s_offRamp.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value; + + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + interval: EVM2EVMMultiOffRamp.Interval(1, maxSeq), + merkleRoot: "stale report 1" + }); + EVM2EVMMultiOffRamp.CommitReport memory commitReport = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + + assertEq(maxSeq + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); + assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); + + commitReport.merkleRoots[0].interval = EVM2EVMMultiOffRamp.Interval(maxSeq + 1, maxSeq * 2); + commitReport.merkleRoots[0].merkleRoot = "stale report 2"; + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + + assertEq(maxSeq * 2 + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); + assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); + assertEq( + tokenStartPrice, IPriceRegistry(s_offRamp.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value + ); + } + + function test_OnlyTokenPriceUpdates_Success() public { + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots + }); + + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + + assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); + } + + function test_OnlyGasPriceUpdates_Success() public { + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots + }); + + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); + } + + function test_PriceSequenceNumberCleared_Success() public { + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots + }); + + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + _commit(commitReport, s_latestSequenceNumber); + + assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); + + vm.startPrank(OWNER); + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: uint8(Internal.OCRPluginType.Execution), + configDigest: s_configDigestExec, + F: s_F, + isSignatureVerificationEnabled: false, + signers: s_emptySigners, + transmitters: s_validTransmitters + }); + s_offRamp.setOCR3Configs(ocrConfigs); + + // Execution plugin OCR config should not clear latest epoch and round + assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); + + // Commit plugin config should clear latest epoch & round + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: uint8(Internal.OCRPluginType.Commit), + configDigest: s_configDigestCommit, + F: s_F, + isSignatureVerificationEnabled: true, + signers: s_validSigners, + transmitters: s_validTransmitters + }); + s_offRamp.setOCR3Configs(ocrConfigs); + + assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); + + // The same sequence number can be reported again + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + + _commit(commitReport, s_latestSequenceNumber); + } + + function test_ValidPriceUpdateThenStaleReportWithRoot_Success() public { + uint64 maxSeq = 12; + uint224 tokenPrice1 = 4e18; + uint224 tokenPrice2 = 5e18; + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice1), + merkleRoots: roots + }); + + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, tokenPrice1, block.timestamp); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); + + roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + interval: EVM2EVMMultiOffRamp.Interval(1, maxSeq), + merkleRoot: "stale report" + }); + commitReport.priceUpdates = getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice2); + commitReport.merkleRoots = roots; + + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + + vm.expectEmit(); + emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); + + _commit(commitReport, s_latestSequenceNumber); + + assertEq(maxSeq + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); + assertEq( + tokenPrice1, IPriceRegistry(s_offRamp.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value + ); + assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); + } + + // Reverts + + function test_UnauthorizedTransmitter_Revert() public { + EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + + bytes32[3] memory reportContext = + [s_configDigestCommit, bytes32(uint256(s_latestSequenceNumber)), s_configDigestCommit]; + + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, abi.encode(commitReport), reportContext, s_F + 1); + + vm.expectRevert(MultiOCR3Base.UnauthorizedTransmitter.selector); + s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); + } + + function test_NoConfig_Revert() public { + _redeployOffRampWithNoOCRConfigs(); + + EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + + bytes32[3] memory reportContext = [bytes32(""), s_configDigestCommit, s_configDigestCommit]; + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, abi.encode(commitReport), reportContext, s_F + 1); + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(); + s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); + } + + function test_NoConfigWithOtherConfigPresent_Revert() public { + _redeployOffRampWithNoOCRConfigs(); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: uint8(Internal.OCRPluginType.Execution), + configDigest: s_configDigestExec, + F: s_F, + isSignatureVerificationEnabled: false, + signers: s_emptySigners, + transmitters: s_validTransmitters + }); + s_offRamp.setOCR3Configs(ocrConfigs); + + EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + + bytes32[3] memory reportContext = [bytes32(""), s_configDigestCommit, s_configDigestCommit]; + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, abi.encode(commitReport), reportContext, s_F + 1); + + vm.startPrank(s_validTransmitters[0]); + vm.expectRevert(); + s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); + } + + function test_WrongConfigWithoutSigners_Revert() public { + _redeployOffRampWithNoOCRConfigs(); + + EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: uint8(Internal.OCRPluginType.Commit), + configDigest: s_configDigestCommit, + F: s_F, + isSignatureVerificationEnabled: false, + signers: s_emptySigners, + transmitters: s_validTransmitters + }); + s_offRamp.setOCR3Configs(ocrConfigs); + + vm.expectRevert(); + _commit(commitReport, s_latestSequenceNumber); + } + + function test_Unhealthy_Revert() public { + s_mockRMN.setGlobalCursed(true); + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + interval: EVM2EVMMultiOffRamp.Interval(1, 2), + merkleRoot: "Only a single root" + }); + + EVM2EVMMultiOffRamp.CommitReport memory commitReport = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.CursedByRMN.selector, roots[0].sourceChainSelector)); + _commit(commitReport, s_latestSequenceNumber); + } + + function test_InvalidRootRevert() public { + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + interval: EVM2EVMMultiOffRamp.Interval(1, 4), + merkleRoot: bytes32(0) + }); + EVM2EVMMultiOffRamp.CommitReport memory commitReport = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + + vm.expectRevert(EVM2EVMMultiOffRamp.InvalidRoot.selector); + _commit(commitReport, s_latestSequenceNumber); + } + + function test_InvalidInterval_Revert() public { + EVM2EVMMultiOffRamp.Interval memory interval = EVM2EVMMultiOffRamp.Interval(2, 2); + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + interval: interval, + merkleRoot: bytes32(0) + }); + EVM2EVMMultiOffRamp.CommitReport memory commitReport = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + + vm.expectRevert( + abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, interval) + ); + _commit(commitReport, s_latestSequenceNumber); + } + + function test_InvalidIntervalMinLargerThanMax_Revert() public { + s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR); + EVM2EVMMultiOffRamp.Interval memory interval = EVM2EVMMultiOffRamp.Interval(1, 0); + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + interval: interval, + merkleRoot: bytes32(0) + }); + EVM2EVMMultiOffRamp.CommitReport memory commitReport = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + + vm.expectRevert( + abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, interval) + ); + _commit(commitReport, s_latestSequenceNumber); + } + + function test_ZeroEpochAndRound_Revert() public { + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots + }); + + vm.expectRevert(EVM2EVMMultiOffRamp.StaleCommitReport.selector); + _commit(commitReport, 0); + } + + function test_OnlyPriceUpdateStaleReport_Revert() public { + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); + EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots + }); + + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + _commit(commitReport, s_latestSequenceNumber); + + vm.expectRevert(EVM2EVMMultiOffRamp.StaleCommitReport.selector); + _commit(commitReport, s_latestSequenceNumber); + } + + function test_SourceChainNotEnabled_Revert() public { + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: 0, + interval: EVM2EVMMultiOffRamp.Interval(1, 2), + merkleRoot: "Only a single root" + }); + + EVM2EVMMultiOffRamp.CommitReport memory commitReport = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.SourceChainNotEnabled.selector, 0)); + _commit(commitReport, s_latestSequenceNumber); + } + + function test_RootAlreadyCommitted_Revert() public { + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + interval: EVM2EVMMultiOffRamp.Interval(1, 2), + merkleRoot: "Only a single root" + }); + EVM2EVMMultiOffRamp.CommitReport memory commitReport = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + + _commit(commitReport, s_latestSequenceNumber); + commitReport.merkleRoots[0].interval = EVM2EVMMultiOffRamp.Interval(3, 3); + + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.RootAlreadyCommitted.selector, roots[0].sourceChainSelector, roots[0].merkleRoot + ) + ); + _commit(commitReport, ++s_latestSequenceNumber); + } + + function _constructCommitReport() internal view returns (EVM2EVMMultiOffRamp.CommitReport memory) { + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + interval: EVM2EVMMultiOffRamp.Interval(1, s_maxInterval), + merkleRoot: "test #2" + }); + + return EVM2EVMMultiOffRamp.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots + }); + } +} + +contract EVM2EVMMultiOffRamp_resetUnblessedRoots is EVM2EVMMultiOffRampSetup { + function setUp() public virtual override { + super.setUp(); + _setupRealRMN(); + _deployOffRamp(s_destRouter, s_realRMN, s_inboundNonceManager); + _setupMultipleOffRamps(); + } + + function test_ResetUnblessedRoots_Success() public { + EVM2EVMMultiOffRamp.UnblessedRoot[] memory rootsToReset = new EVM2EVMMultiOffRamp.UnblessedRoot[](3); + rootsToReset[0] = EVM2EVMMultiOffRamp.UnblessedRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR, merkleRoot: "1"}); + rootsToReset[1] = EVM2EVMMultiOffRamp.UnblessedRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR, merkleRoot: "2"}); + rootsToReset[2] = EVM2EVMMultiOffRamp.UnblessedRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR, merkleRoot: "3"}); + + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](3); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + interval: EVM2EVMMultiOffRamp.Interval(1, 2), + merkleRoot: rootsToReset[0].merkleRoot + }); + roots[1] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + interval: EVM2EVMMultiOffRamp.Interval(3, 4), + merkleRoot: rootsToReset[1].merkleRoot + }); + roots[2] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + interval: EVM2EVMMultiOffRamp.Interval(5, 5), + merkleRoot: rootsToReset[2].merkleRoot + }); + + EVM2EVMMultiOffRamp.CommitReport memory report = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + + _commit(report, ++s_latestSequenceNumber); + + IRMN.TaggedRoot[] memory blessedTaggedRoots = new IRMN.TaggedRoot[](1); + blessedTaggedRoots[0] = IRMN.TaggedRoot({commitStore: address(s_offRamp), root: rootsToReset[1].merkleRoot}); + + vm.startPrank(BLESS_VOTE_ADDR); + s_realRMN.voteToBless(blessedTaggedRoots); + + vm.expectEmit(false, false, false, true); + emit EVM2EVMMultiOffRamp.RootRemoved(rootsToReset[0].merkleRoot); + + vm.expectEmit(false, false, false, true); + emit EVM2EVMMultiOffRamp.RootRemoved(rootsToReset[2].merkleRoot); + + vm.startPrank(OWNER); + s_offRamp.resetUnblessedRoots(rootsToReset); + + assertEq(0, s_offRamp.getMerkleRoot(SOURCE_CHAIN_SELECTOR, rootsToReset[0].merkleRoot)); + assertEq(BLOCK_TIME, s_offRamp.getMerkleRoot(SOURCE_CHAIN_SELECTOR, rootsToReset[1].merkleRoot)); + assertEq(0, s_offRamp.getMerkleRoot(SOURCE_CHAIN_SELECTOR, rootsToReset[2].merkleRoot)); + } + + // Reverts + + function test_OnlyOwner_Revert() public { + vm.stopPrank(); + vm.expectRevert("Only callable by owner"); + EVM2EVMMultiOffRamp.UnblessedRoot[] memory rootsToReset = new EVM2EVMMultiOffRamp.UnblessedRoot[](0); + s_offRamp.resetUnblessedRoots(rootsToReset); + } +} + +contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { + function setUp() public virtual override { + super.setUp(); + _setupRealRMN(); + _deployOffRamp(s_destRouter, s_realRMN, s_inboundNonceManager); + _setupMultipleOffRamps(); + } + + function test_NotBlessed_Success() public { + bytes32[] memory leaves = new bytes32[](1); + leaves[0] = "root"; + + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + interval: EVM2EVMMultiOffRamp.Interval(1, 2), + merkleRoot: leaves[0] + }); + EVM2EVMMultiOffRamp.CommitReport memory report = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + _commit(report, ++s_latestSequenceNumber); + bytes32[] memory proofs = new bytes32[](0); + // We have not blessed this root, should return 0. + uint256 timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR, leaves, proofs, 0); + assertEq(uint256(0), timestamp); + } + + function test_Blessed_Success() public { + bytes32[] memory leaves = new bytes32[](1); + leaves[0] = "root"; + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + interval: EVM2EVMMultiOffRamp.Interval(1, 2), + merkleRoot: leaves[0] + }); + EVM2EVMMultiOffRamp.CommitReport memory report = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + _commit(report, ++s_latestSequenceNumber); + // Bless that root. + IRMN.TaggedRoot[] memory taggedRoots = new IRMN.TaggedRoot[](1); + taggedRoots[0] = IRMN.TaggedRoot({commitStore: address(s_offRamp), root: leaves[0]}); + vm.startPrank(BLESS_VOTE_ADDR); + s_realRMN.voteToBless(taggedRoots); + bytes32[] memory proofs = new bytes32[](0); + uint256 timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR, leaves, proofs, 0); + assertEq(BLOCK_TIME, timestamp); + } + + function test_NotBlessedWrongChainSelector_Success() public { + bytes32[] memory leaves = new bytes32[](1); + leaves[0] = "root"; + EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); + roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + interval: EVM2EVMMultiOffRamp.Interval(1, 2), + merkleRoot: leaves[0] + }); + + EVM2EVMMultiOffRamp.CommitReport memory report = + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + _commit(report, ++s_latestSequenceNumber); + + // Bless that root. + IRMN.TaggedRoot[] memory taggedRoots = new IRMN.TaggedRoot[](1); + taggedRoots[0] = IRMN.TaggedRoot({commitStore: address(s_offRamp), root: leaves[0]}); + vm.startPrank(BLESS_VOTE_ADDR); + s_realRMN.voteToBless(taggedRoots); + + bytes32[] memory proofs = new bytes32[](0); + uint256 timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR + 1, leaves, proofs, 0); + assertEq(uint256(0), timestamp); + } + + // Reverts + + function test_TooManyLeaves_Revert() public { + bytes32[] memory leaves = new bytes32[](258); + bytes32[] memory proofs = new bytes32[](0); + vm.expectRevert(MerkleMultiProof.InvalidProof.selector); + s_offRamp.verify(SOURCE_CHAIN_SELECTOR, leaves, proofs, 0); + } +} diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol new file mode 100644 index 0000000000..507e966a70 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol @@ -0,0 +1,491 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IAny2EVMMessageReceiver} from "../../interfaces/IAny2EVMMessageReceiver.sol"; + +import {IAny2EVMOffRamp} from "../../interfaces/IAny2EVMOffRamp.sol"; +import {ICommitStore} from "../../interfaces/ICommitStore.sol"; +import {IRMN} from "../../interfaces/IRMN.sol"; + +import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; +import {NonceManager} from "../../NonceManager.sol"; +import {RMN} from "../../RMN.sol"; +import {Router} from "../../Router.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {MultiOCR3Base} from "../../ocr/MultiOCR3Base.sol"; +import {EVM2EVMMultiOffRamp} from "../../offRamp/EVM2EVMMultiOffRamp.sol"; +import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; +import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {TokenSetup} from "../TokenSetup.t.sol"; +import {EVM2EVMMultiOffRampHelper} from "../helpers/EVM2EVMMultiOffRampHelper.sol"; +import {EVM2EVMOffRampHelper} from "../helpers/EVM2EVMOffRampHelper.sol"; +import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; +import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; +import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; +import {MockCommitStore} from "../mocks/MockCommitStore.sol"; +import {MultiOCR3BaseSetup} from "../ocr/MultiOCR3BaseSetup.t.sol"; +import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3BaseSetup { + uint64 internal constant SOURCE_CHAIN_SELECTOR_1 = SOURCE_CHAIN_SELECTOR; + uint64 internal constant SOURCE_CHAIN_SELECTOR_2 = 6433500567565415381; + uint64 internal constant SOURCE_CHAIN_SELECTOR_3 = 4051577828743386545; + + bytes internal constant ON_RAMP_ADDRESS_1 = abi.encode(ON_RAMP_ADDRESS); + bytes internal constant ON_RAMP_ADDRESS_2 = abi.encode(0xaA3f843Cf8E33B1F02dd28303b6bD87B1aBF8AE4); + bytes internal constant ON_RAMP_ADDRESS_3 = abi.encode(0x71830C37Cb193e820de488Da111cfbFcC680a1b9); + + address internal constant BLESS_VOTE_ADDR = address(8888); + + IAny2EVMMessageReceiver internal s_receiver; + IAny2EVMMessageReceiver internal s_secondary_receiver; + MaybeRevertMessageReceiver internal s_reverting_receiver; + + MaybeRevertingBurnMintTokenPool internal s_maybeRevertingPool; + + EVM2EVMMultiOffRampHelper internal s_offRamp; + MessageInterceptorHelper internal s_inboundMessageValidator; + NonceManager internal s_inboundNonceManager; + RMN internal s_realRMN; + address internal s_sourceTokenPool = makeAddr("sourceTokenPool"); + + bytes32 internal s_configDigestExec; + bytes32 internal s_configDigestCommit; + uint64 internal constant s_offchainConfigVersion = 3; + uint8 internal constant s_F = 1; + + uint64 internal s_latestSequenceNumber; + + function setUp() public virtual override(TokenSetup, PriceRegistrySetup, MultiOCR3BaseSetup) { + TokenSetup.setUp(); + PriceRegistrySetup.setUp(); + MultiOCR3BaseSetup.setUp(); + + s_inboundMessageValidator = new MessageInterceptorHelper(); + s_receiver = new MaybeRevertMessageReceiver(false); + s_secondary_receiver = new MaybeRevertMessageReceiver(false); + s_reverting_receiver = new MaybeRevertMessageReceiver(true); + + s_maybeRevertingPool = MaybeRevertingBurnMintTokenPool(s_destPoolByToken[s_destTokens[1]]); + s_inboundNonceManager = new NonceManager(new address[](0)); + + _deployOffRamp(s_destRouter, s_mockRMN, s_inboundNonceManager); + } + + function _deployOffRamp(Router router, IRMN rmnProxy, NonceManager nonceManager) internal { + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); + + s_offRamp = new EVM2EVMMultiOffRampHelper( + EVM2EVMMultiOffRamp.StaticConfig({ + chainSelector: DEST_CHAIN_SELECTOR, + rmnProxy: address(rmnProxy), + tokenAdminRegistry: address(s_tokenAdminRegistry), + nonceManager: address(nonceManager) + }), + _generateDynamicMultiOffRampConfig(address(router), address(s_priceRegistry)), + sourceChainConfigs + ); + + s_configDigestExec = _getBasicConfigDigest(s_F, s_emptySigners, s_validTransmitters); + s_configDigestCommit = _getBasicConfigDigest(s_F, s_validSigners, s_validTransmitters); + + MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](2); + ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: uint8(Internal.OCRPluginType.Execution), + configDigest: s_configDigestExec, + F: s_F, + isSignatureVerificationEnabled: false, + signers: s_emptySigners, + transmitters: s_validTransmitters + }); + ocrConfigs[1] = MultiOCR3Base.OCRConfigArgs({ + ocrPluginType: uint8(Internal.OCRPluginType.Commit), + configDigest: s_configDigestCommit, + F: s_F, + isSignatureVerificationEnabled: true, + signers: s_validSigners, + transmitters: s_validTransmitters + }); + + s_offRamp.setDynamicConfig(_generateDynamicMultiOffRampConfig(address(router), address(s_priceRegistry))); + s_offRamp.setOCR3Configs(ocrConfigs); + + address[] memory authorizedCallers = new address[](1); + authorizedCallers[0] = address(s_offRamp); + NonceManager(nonceManager).applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: authorizedCallers, removedCallers: new address[](0)}) + ); + + address[] memory priceUpdaters = new address[](1); + priceUpdaters[0] = address(s_offRamp); + s_priceRegistry.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: priceUpdaters, removedCallers: new address[](0)}) + ); + } + + // TODO: function can be made common across OffRampSetup and MultiOffRampSetup + function _deploySingleLaneOffRamp( + ICommitStore commitStore, + Router router, + address prevOffRamp, + uint64 sourceChainSelector, + address onRampAddress + ) internal returns (EVM2EVMOffRampHelper) { + EVM2EVMOffRampHelper offRamp = new EVM2EVMOffRampHelper( + EVM2EVMOffRamp.StaticConfig({ + commitStore: address(commitStore), + chainSelector: DEST_CHAIN_SELECTOR, + sourceChainSelector: sourceChainSelector, + onRamp: onRampAddress, + prevOffRamp: prevOffRamp, + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }), + getInboundRateLimiterConfig() + ); + offRamp.setOCR2Config( + s_validSigners, + s_validTransmitters, + s_F, + abi.encode(_generateDynamicOffRampConfig(address(router), address(s_priceRegistry))), + s_offchainConfigVersion, + abi.encode("") + ); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](0); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](2); + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: sourceChainSelector, offRamp: address(s_offRamp)}); + offRampUpdates[1] = Router.OffRamp({sourceChainSelector: sourceChainSelector, offRamp: address(prevOffRamp)}); + s_destRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + EVM2EVMOffRamp.RateLimitToken[] memory tokensToAdd = new EVM2EVMOffRamp.RateLimitToken[](s_sourceTokens.length); + for (uint256 i = 0; i < s_sourceTokens.length; ++i) { + tokensToAdd[i] = EVM2EVMOffRamp.RateLimitToken({sourceToken: s_sourceTokens[i], destToken: s_destTokens[i]}); + } + offRamp.updateRateLimitTokens(new EVM2EVMOffRamp.RateLimitToken[](0), tokensToAdd); + + return offRamp; + } + + function _setupMultipleOffRamps() internal { + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](3); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + onRamp: ON_RAMP_ADDRESS_1, + isEnabled: true + }); + sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_2, + onRamp: ON_RAMP_ADDRESS_2, + isEnabled: false + }); + sourceChainConfigs[2] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_3, + onRamp: ON_RAMP_ADDRESS_3, + isEnabled: true + }); + _setupMultipleOffRampsFromConfigs(sourceChainConfigs); + } + + function _setupMultipleOffRampsFromConfigs(EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs) + internal + { + s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](0); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](2 * sourceChainConfigs.length); + + for (uint256 i = 0; i < sourceChainConfigs.length; ++i) { + uint64 sourceChainSelector = sourceChainConfigs[i].sourceChainSelector; + + offRampUpdates[2 * i] = Router.OffRamp({sourceChainSelector: sourceChainSelector, offRamp: address(s_offRamp)}); + offRampUpdates[2 * i + 1] = Router.OffRamp({ + sourceChainSelector: sourceChainSelector, + offRamp: s_inboundNonceManager.getPreviousRamps(sourceChainSelector).prevOffRamp + }); + } + + s_destRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } + + function _generateDynamicOffRampConfig( + address router, + address priceRegistry + ) internal pure returns (EVM2EVMOffRamp.DynamicConfig memory) { + return EVM2EVMOffRamp.DynamicConfig({ + permissionLessExecutionThresholdSeconds: PERMISSION_LESS_EXECUTION_THRESHOLD_SECONDS, + router: router, + priceRegistry: priceRegistry, + maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, + maxDataBytes: MAX_DATA_SIZE, + maxPoolReleaseOrMintGas: MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS, + maxTokenTransferGas: MAX_TOKEN_POOL_TRANSFER_GAS + }); + } + + function _generateDynamicMultiOffRampConfig( + address router, + address priceRegistry + ) internal pure returns (EVM2EVMMultiOffRamp.DynamicConfig memory) { + return EVM2EVMMultiOffRamp.DynamicConfig({ + permissionLessExecutionThresholdSeconds: PERMISSION_LESS_EXECUTION_THRESHOLD_SECONDS, + router: router, + priceRegistry: priceRegistry, + messageValidator: address(0), + maxPoolReleaseOrMintGas: MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS, + maxTokenTransferGas: MAX_TOKEN_POOL_TRANSFER_GAS + }); + } + + function _convertToGeneralMessage(Internal.Any2EVMRampMessage memory original) + internal + view + returns (Client.Any2EVMMessage memory message) + { + uint256 numberOfTokens = original.tokenAmounts.length; + Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](numberOfTokens); + + for (uint256 i = 0; i < numberOfTokens; ++i) { + Internal.RampTokenAmount memory tokenAmount = original.tokenAmounts[i]; + + address destPoolAddress = abi.decode(tokenAmount.destTokenAddress, (address)); + TokenPool pool = TokenPool(destPoolAddress); + destTokenAmounts[i].token = address(pool.getToken()); + destTokenAmounts[i].amount = tokenAmount.amount; + } + + return Client.Any2EVMMessage({ + messageId: original.header.messageId, + sourceChainSelector: original.header.sourceChainSelector, + sender: abi.encode(original.sender), + data: original.data, + destTokenAmounts: destTokenAmounts + }); + } + + function _generateAny2EVMMessageNoTokens( + uint64 sourceChainSelector, + bytes memory onRamp, + uint64 sequenceNumber + ) internal view returns (Internal.Any2EVMRampMessage memory) { + return _generateAny2EVMMessage(sourceChainSelector, onRamp, sequenceNumber, new Client.EVMTokenAmount[](0), false); + } + + function _generateAny2EVMMessageWithTokens( + uint64 sourceChainSelector, + bytes memory onRamp, + uint64 sequenceNumber, + uint256[] memory amounts + ) internal view returns (Internal.Any2EVMRampMessage memory) { + Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + for (uint256 i = 0; i < tokenAmounts.length; ++i) { + tokenAmounts[i].amount = amounts[i]; + } + return _generateAny2EVMMessage(sourceChainSelector, onRamp, sequenceNumber, tokenAmounts, false); + } + + function _generateAny2EVMMessage( + uint64 sourceChainSelector, + bytes memory onRamp, + uint64 sequenceNumber, + Client.EVMTokenAmount[] memory tokenAmounts, + bool allowOutOfOrderExecution + ) internal view returns (Internal.Any2EVMRampMessage memory) { + bytes memory data = abi.encode(0); + + Internal.RampTokenAmount[] memory rampTokenAmounts = new Internal.RampTokenAmount[](tokenAmounts.length); + + // Correctly set the TokenDataPayload for each token. Tokens have to be set up in the TokenSetup. + for (uint256 i = 0; i < tokenAmounts.length; ++i) { + rampTokenAmounts[i] = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[tokenAmounts[i].token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[tokenAmounts[i].token]), + extraData: "", + amount: tokenAmounts[i].amount + }); + } + + Internal.Any2EVMRampMessage memory message = Internal.Any2EVMRampMessage({ + header: Internal.RampMessageHeader({ + messageId: "", + sourceChainSelector: sourceChainSelector, + destChainSelector: DEST_CHAIN_SELECTOR, + sequenceNumber: sequenceNumber, + nonce: allowOutOfOrderExecution ? 0 : sequenceNumber + }), + sender: abi.encode(OWNER), + data: data, + receiver: address(s_receiver), + tokenAmounts: rampTokenAmounts, + gasLimit: GAS_LIMIT + }); + + message.header.messageId = Internal._hash(message, onRamp); + + return message; + } + + function _generateSingleBasicMessage( + uint64 sourceChainSelector, + bytes memory onRamp + ) internal view returns (Internal.Any2EVMRampMessage[] memory) { + Internal.Any2EVMRampMessage[] memory messages = new Internal.Any2EVMRampMessage[](1); + messages[0] = _generateAny2EVMMessageNoTokens(sourceChainSelector, onRamp, 1); + return messages; + } + + function _generateMessagesWithTokens( + uint64 sourceChainSelector, + bytes memory onRamp + ) internal view returns (Internal.Any2EVMRampMessage[] memory) { + Internal.Any2EVMRampMessage[] memory messages = new Internal.Any2EVMRampMessage[](2); + Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + tokenAmounts[0].amount = 1e18; + tokenAmounts[1].amount = 5e18; + messages[0] = _generateAny2EVMMessage(sourceChainSelector, onRamp, 1, tokenAmounts, false); + messages[1] = _generateAny2EVMMessage(sourceChainSelector, onRamp, 2, tokenAmounts, false); + + return messages; + } + + function _generateReportFromMessages( + uint64 sourceChainSelector, + Internal.Any2EVMRampMessage[] memory messages + ) internal pure returns (Internal.ExecutionReportSingleChain memory) { + bytes[][] memory offchainTokenData = new bytes[][](messages.length); + + for (uint256 i = 0; i < messages.length; ++i) { + offchainTokenData[i] = new bytes[](messages[i].tokenAmounts.length); + } + + return Internal.ExecutionReportSingleChain({ + sourceChainSelector: sourceChainSelector, + proofs: new bytes32[](0), + proofFlagBits: 2 ** 256 - 1, + messages: messages, + offchainTokenData: offchainTokenData + }); + } + + function _generateBatchReportFromMessages( + uint64 sourceChainSelector, + Internal.Any2EVMRampMessage[] memory messages + ) internal pure returns (Internal.ExecutionReportSingleChain[] memory) { + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](1); + reports[0] = _generateReportFromMessages(sourceChainSelector, messages); + return reports; + } + + function _getGasLimitsFromMessages(Internal.Any2EVMRampMessage[] memory messages) + internal + pure + returns (uint256[] memory) + { + uint256[] memory gasLimits = new uint256[](messages.length); + for (uint256 i = 0; i < messages.length; ++i) { + gasLimits[i] = messages[i].gasLimit; + } + + return gasLimits; + } + + function _assertSameConfig( + EVM2EVMMultiOffRamp.DynamicConfig memory a, + EVM2EVMMultiOffRamp.DynamicConfig memory b + ) public pure { + assertEq(a.permissionLessExecutionThresholdSeconds, b.permissionLessExecutionThresholdSeconds); + assertEq(a.router, b.router); + assertEq(a.maxPoolReleaseOrMintGas, b.maxPoolReleaseOrMintGas); + assertEq(a.maxTokenTransferGas, b.maxTokenTransferGas); + assertEq(a.messageValidator, b.messageValidator); + assertEq(a.priceRegistry, b.priceRegistry); + } + + function _assertSourceChainConfigEquality( + EVM2EVMMultiOffRamp.SourceChainConfig memory config1, + EVM2EVMMultiOffRamp.SourceChainConfig memory config2 + ) internal pure { + assertEq(config1.isEnabled, config2.isEnabled); + assertEq(config1.minSeqNr, config2.minSeqNr); + assertEq(config1.onRamp, config2.onRamp); + } + + function _getDefaultSourceTokenData(Client.EVMTokenAmount[] memory srcTokenAmounts) + internal + view + returns (Internal.RampTokenAmount[] memory) + { + Internal.RampTokenAmount[] memory sourceTokenData = new Internal.RampTokenAmount[](srcTokenAmounts.length); + for (uint256 i = 0; i < srcTokenAmounts.length; ++i) { + sourceTokenData[i] = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[srcTokenAmounts[i].token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[srcTokenAmounts[i].token]), + extraData: "", + amount: srcTokenAmounts[i].amount + }); + } + return sourceTokenData; + } + + function _enableInboundMessageValidator() internal { + EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = s_offRamp.getDynamicConfig(); + dynamicConfig.messageValidator = address(s_inboundMessageValidator); + s_offRamp.setDynamicConfig(dynamicConfig); + } + + function _redeployOffRampWithNoOCRConfigs() internal { + s_offRamp = new EVM2EVMMultiOffRampHelper( + EVM2EVMMultiOffRamp.StaticConfig({ + chainSelector: DEST_CHAIN_SELECTOR, + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry), + nonceManager: address(s_inboundNonceManager) + }), + _generateDynamicMultiOffRampConfig(address(s_destRouter), address(s_priceRegistry)), + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0) + ); + + address[] memory authorizedCallers = new address[](1); + authorizedCallers[0] = address(s_offRamp); + s_inboundNonceManager.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: authorizedCallers, removedCallers: new address[](0)}) + ); + _setupMultipleOffRamps(); + + address[] memory priceUpdaters = new address[](1); + priceUpdaters[0] = address(s_offRamp); + s_priceRegistry.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: priceUpdaters, removedCallers: new address[](0)}) + ); + } + + function _setupRealRMN() internal { + RMN.Voter[] memory voters = new RMN.Voter[](1); + voters[0] = + RMN.Voter({blessVoteAddr: BLESS_VOTE_ADDR, curseVoteAddr: address(9999), blessWeight: 1, curseWeight: 1}); + // Overwrite base mock rmn with real. + s_realRMN = new RMN(RMN.Config({voters: voters, blessWeightThreshold: 1, curseWeightThreshold: 1})); + } + + function _commit(EVM2EVMMultiOffRamp.CommitReport memory commitReport, uint64 sequenceNumber) internal { + bytes32[3] memory reportContext = [s_configDigestCommit, bytes32(uint256(sequenceNumber)), s_configDigestCommit]; + + (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = + _getSignaturesForDigest(s_validSignerKeys, abi.encode(commitReport), reportContext, s_F + 1); + + vm.startPrank(s_validTransmitters[0]); + s_offRamp.commit(reportContext, abi.encode(commitReport), rs, ss, rawVs); + } + + function _execute(Internal.ExecutionReportSingleChain[] memory reports) internal { + bytes32[3] memory reportContext = [s_configDigestExec, s_configDigestExec, s_configDigestExec]; + + vm.startPrank(s_validTransmitters[0]); + s_offRamp.execute(reportContext, abi.encode(reports)); + } +} diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol new file mode 100644 index 0000000000..e94184e3c5 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol @@ -0,0 +1,1986 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ICommitStore} from "../../interfaces/ICommitStore.sol"; +import {IPoolV1} from "../../interfaces/IPool.sol"; +import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; + +import {CallWithExactGas} from "../../../shared/call/CallWithExactGas.sol"; + +import {GenericReceiver} from "../../../shared/test/testhelpers/GenericReceiver.sol"; +import {AggregateRateLimiter} from "../../AggregateRateLimiter.sol"; +import {RMN} from "../../RMN.sol"; +import {Router} from "../../Router.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {Pool} from "../../libraries/Pool.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {OCR2Abstract} from "../../ocr/OCR2Abstract.sol"; +import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; +import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {EVM2EVMOffRampHelper} from "../helpers/EVM2EVMOffRampHelper.sol"; +import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; +import {ConformingReceiver} from "../helpers/receivers/ConformingReceiver.sol"; +import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; +import {MaybeRevertMessageReceiverNo165} from "../helpers/receivers/MaybeRevertMessageReceiverNo165.sol"; +import {ReentrancyAbuser} from "../helpers/receivers/ReentrancyAbuser.sol"; +import {MockCommitStore} from "../mocks/MockCommitStore.sol"; +import {OCR2Base} from "../ocr/OCR2Base.t.sol"; +import {OCR2BaseNoChecks} from "../ocr/OCR2BaseNoChecks.t.sol"; +import {EVM2EVMOffRampSetup} from "./EVM2EVMOffRampSetup.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract EVM2EVMOffRamp_constructor is EVM2EVMOffRampSetup { + function test_Constructor_Success() public { + EVM2EVMOffRamp.StaticConfig memory staticConfig = EVM2EVMOffRamp.StaticConfig({ + commitStore: address(s_mockCommitStore), + chainSelector: DEST_CHAIN_SELECTOR, + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + onRamp: ON_RAMP_ADDRESS, + prevOffRamp: address(0), + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }); + EVM2EVMOffRamp.DynamicConfig memory dynamicConfig = + generateDynamicOffRampConfig(address(s_destRouter), address(s_priceRegistry)); + + s_offRamp = new EVM2EVMOffRampHelper(staticConfig, getInboundRateLimiterConfig()); + + s_offRamp.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, abi.encode(dynamicConfig), s_offchainConfigVersion, abi.encode("") + ); + + // Static config + EVM2EVMOffRamp.StaticConfig memory gotStaticConfig = s_offRamp.getStaticConfig(); + assertEq(staticConfig.commitStore, gotStaticConfig.commitStore); + assertEq(staticConfig.sourceChainSelector, gotStaticConfig.sourceChainSelector); + assertEq(staticConfig.chainSelector, gotStaticConfig.chainSelector); + assertEq(staticConfig.onRamp, gotStaticConfig.onRamp); + assertEq(staticConfig.prevOffRamp, gotStaticConfig.prevOffRamp); + assertEq(staticConfig.tokenAdminRegistry, gotStaticConfig.tokenAdminRegistry); + + // Dynamic config + EVM2EVMOffRamp.DynamicConfig memory gotDynamicConfig = s_offRamp.getDynamicConfig(); + _assertSameConfig(dynamicConfig, gotDynamicConfig); + + (uint32 configCount, uint32 blockNumber,) = s_offRamp.latestConfigDetails(); + assertEq(1, configCount); + assertEq(block.number, blockNumber); + + // OffRamp initial values + assertEq("EVM2EVMOffRamp 1.5.0-dev", s_offRamp.typeAndVersion()); + assertEq(OWNER, s_offRamp.owner()); + } + + // Revert + function test_ZeroOnRampAddress_Revert() public { + vm.expectRevert(EVM2EVMOffRamp.ZeroAddressNotAllowed.selector); + + s_offRamp = new EVM2EVMOffRampHelper( + EVM2EVMOffRamp.StaticConfig({ + commitStore: address(s_mockCommitStore), + chainSelector: DEST_CHAIN_SELECTOR, + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + onRamp: ZERO_ADDRESS, + prevOffRamp: address(0), + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }), + RateLimiter.Config({isEnabled: true, rate: 1e20, capacity: 1e20}) + ); + } + + function test_CommitStoreAlreadyInUse_Revert() public { + s_mockCommitStore.setExpectedNextSequenceNumber(2); + + vm.expectRevert(EVM2EVMOffRamp.CommitStoreAlreadyInUse.selector); + + s_offRamp = new EVM2EVMOffRampHelper( + EVM2EVMOffRamp.StaticConfig({ + commitStore: address(s_mockCommitStore), + chainSelector: DEST_CHAIN_SELECTOR, + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + onRamp: ON_RAMP_ADDRESS, + prevOffRamp: address(0), + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }), + getInboundRateLimiterConfig() + ); + } +} + +contract EVM2EVMOffRamp_setDynamicConfig is EVM2EVMOffRampSetup { + function test_SetDynamicConfig_Success() public { + EVM2EVMOffRamp.StaticConfig memory staticConfig = s_offRamp.getStaticConfig(); + EVM2EVMOffRamp.DynamicConfig memory dynamicConfig = generateDynamicOffRampConfig(USER_3, address(s_priceRegistry)); + bytes memory onchainConfig = abi.encode(dynamicConfig); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ConfigSet(staticConfig, dynamicConfig); + + vm.expectEmit(); + uint32 configCount = 1; + emit OCR2Abstract.ConfigSet( + uint32(block.number), + getBasicConfigDigest(address(s_offRamp), s_f, configCount, onchainConfig), + configCount + 1, + s_valid_signers, + s_valid_transmitters, + s_f, + onchainConfig, + s_offchainConfigVersion, + abi.encode("") + ); + + s_offRamp.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, onchainConfig, s_offchainConfigVersion, abi.encode("") + ); + + EVM2EVMOffRamp.DynamicConfig memory newConfig = s_offRamp.getDynamicConfig(); + _assertSameConfig(dynamicConfig, newConfig); + } + + function test_NonOwner_Revert() public { + vm.startPrank(STRANGER); + EVM2EVMOffRamp.DynamicConfig memory dynamicConfig = generateDynamicOffRampConfig(USER_3, address(s_priceRegistry)); + + vm.expectRevert("Only callable by owner"); + + s_offRamp.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, abi.encode(dynamicConfig), s_offchainConfigVersion, abi.encode("") + ); + } + + function test_RouterZeroAddress_Revert() public { + EVM2EVMOffRamp.DynamicConfig memory dynamicConfig = generateDynamicOffRampConfig(ZERO_ADDRESS, ZERO_ADDRESS); + + vm.expectRevert(EVM2EVMOffRamp.ZeroAddressNotAllowed.selector); + + s_offRamp.setOCR2Config( + s_valid_signers, s_valid_transmitters, s_f, abi.encode(dynamicConfig), s_offchainConfigVersion, abi.encode("") + ); + } +} + +contract EVM2EVMOffRamp_metadataHash is EVM2EVMOffRampSetup { + function test_MetadataHash_Success() public view { + bytes32 h = s_offRamp.metadataHash(); + assertEq( + h, + keccak256( + abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, SOURCE_CHAIN_SELECTOR, DEST_CHAIN_SELECTOR, ON_RAMP_ADDRESS) + ) + ); + } +} + +contract EVM2EVMOffRamp_ccipReceive is EVM2EVMOffRampSetup { + // Reverts + + function test_Reverts() public { + Client.Any2EVMMessage memory message = _convertToGeneralMessage(_generateAny2EVMMessageNoTokens(1)); + vm.expectRevert(); + s_offRamp.ccipReceive(message); + } +} + +contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { + error PausedError(); + + function _generateMsgWithoutTokens( + uint256 gasLimit, + bytes memory messageData + ) internal view returns (Internal.EVM2EVMMessage memory) { + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageNoTokens(1); + message.gasLimit = gasLimit; + message.data = messageData; + message.messageId = Internal._hash( + message, + keccak256( + abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, SOURCE_CHAIN_SELECTOR, DEST_CHAIN_SELECTOR, ON_RAMP_ADDRESS) + ) + ); + return message; + } + + function test_Fuzz_trialExecuteWithoutTokens_Success(bytes4 funcSelector, bytes memory messageData) public { + vm.assume( + funcSelector != GenericReceiver.setRevert.selector && funcSelector != GenericReceiver.setErr.selector + && funcSelector != 0x5100fc21 && funcSelector != 0x00000000 // s_toRevert(), which is public and therefore has a function selector + ); + + // Convert bytes4 into bytes memory to use in the message + Internal.EVM2EVMMessage memory message = _generateMsgWithoutTokens(GAS_LIMIT, messageData); + + // Convert an Internal.EVM2EVMMessage into a Client.Any2EVMMessage digestable by the client + Client.Any2EVMMessage memory receivedMessage = _convertToGeneralMessage(message); + bytes memory expectedCallData = + abi.encodeWithSelector(MaybeRevertMessageReceiver.ccipReceive.selector, receivedMessage); + + vm.expectCall(address(s_receiver), expectedCallData); + (Internal.MessageExecutionState newState, bytes memory err) = + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); + assertEq("", err); + } + + function test_Fuzz_trialExecuteWithTokens_Success(uint16 tokenAmount, bytes calldata messageData) public { + vm.assume(tokenAmount != 0); + + uint256[] memory amounts = new uint256[](2); + amounts[0] = uint256(tokenAmount); + amounts[1] = uint256(tokenAmount); + + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageWithTokens(1, amounts); + // console.log(message.length); + message.data = messageData; + + IERC20 dstToken0 = IERC20(s_destTokens[0]); + uint256 startingBalance = dstToken0.balanceOf(message.receiver); + + vm.expectCall(s_destTokens[0], abi.encodeWithSelector(IERC20.transfer.selector, address(s_receiver), amounts[0])); + + (Internal.MessageExecutionState newState, bytes memory err) = + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); + assertEq("", err); + + // Check that the tokens were transferred + assertEq(startingBalance + amounts[0], dstToken0.balanceOf(message.receiver)); + } + + function test_Fuzz_getSenderNonce(uint8 trialExecutions) public { + vm.assume(trialExecutions > 1); + + Internal.EVM2EVMMessage[] memory messages; + + if (trialExecutions == 1) { + messages = new Internal.EVM2EVMMessage[](1); + messages[0] = _generateAny2EVMMessageNoTokens(0); + } else { + messages = _generateSingleBasicMessage(); + } + + // Fuzz the number of calls from the sender to ensure that getSenderNonce works + for (uint256 i = 1; i < trialExecutions; ++i) { + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + messages[0].nonce++; + messages[0].sequenceNumber++; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + } + + messages[0].nonce = 0; + messages[0].sequenceNumber = 0; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + uint64 nonceBefore = s_offRamp.getSenderNonce(messages[0].sender); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertEq(s_offRamp.getSenderNonce(messages[0].sender), nonceBefore, "sender nonce is not as expected"); + } + + function test_Fuzz_getSenderNonceWithPrevOffRamp_Success(uint8 trialExecutions) public { + vm.assume(trialExecutions > 1); + // Fuzz a random nonce for getSenderNonce + test_Fuzz_getSenderNonce(trialExecutions); + + address prevOffRamp = address(s_offRamp); + deployOffRamp(s_mockCommitStore, s_destRouter, prevOffRamp); + + // Make sure the off-ramp address has changed by querying the static config + assertNotEq(address(s_offRamp), prevOffRamp); + EVM2EVMOffRamp.StaticConfig memory staticConfig = s_offRamp.getStaticConfig(); + assertEq(staticConfig.prevOffRamp, prevOffRamp, "Previous offRamp does not match expected address"); + + // Since i_prevOffRamp != address(0) and senderNonce == 0, there should be a call to the previous offRamp + vm.expectCall(prevOffRamp, abi.encodeWithSelector(s_offRamp.getSenderNonce.selector, OWNER)); + uint256 currentSenderNonce = s_offRamp.getSenderNonce(OWNER); + assertNotEq(currentSenderNonce, 0, "Sender nonce should not be zero"); + assertEq(currentSenderNonce, trialExecutions - 1, "Sender Nonce does not match expected trial executions"); + + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + currentSenderNonce = s_offRamp.getSenderNonce(OWNER); + assertEq(currentSenderNonce, trialExecutions - 1, "Sender Nonce on new offramp does not match expected executions"); + } + + function test_SingleMessageNoTokens_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + messages[0].nonce++; + messages[0].sequenceNumber++; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + uint64 nonceBefore = s_offRamp.getSenderNonce(messages[0].sender); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertGt(s_offRamp.getSenderNonce(messages[0].sender), nonceBefore); + } + + function test_SingleMessageNoTokensUnordered_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + messages[0].nonce = 0; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + // Nonce never increments on unordered messages. + uint64 nonceBefore = s_offRamp.getSenderNonce(messages[0].sender); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertEq( + s_offRamp.getSenderNonce(messages[0].sender), nonceBefore, "nonce must remain unchanged on unordered messages" + ); + + messages[0].sequenceNumber++; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + // Nonce never increments on unordered messages. + nonceBefore = s_offRamp.getSenderNonce(messages[0].sender); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertEq( + s_offRamp.getSenderNonce(messages[0].sender), nonceBefore, "nonce must remain unchanged on unordered messages" + ); + } + + function test_ReceiverError_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + bytes memory realError1 = new bytes(2); + realError1[0] = 0xbe; + realError1[1] = 0xef; + s_reverting_receiver.setErr(realError1); + + messages[0].receiver = address(s_reverting_receiver); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, + messages[0].messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + EVM2EVMOffRamp.ReceiverError.selector, + abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, realError1) + ) + ); + // Nonce should increment on non-strict + assertEq(uint64(0), s_offRamp.getSenderNonce(address(OWNER))); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertEq(uint64(1), s_offRamp.getSenderNonce(address(OWNER))); + } + + function test_StrictUntouchedToSuccess_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + messages[0].strict = true; + messages[0].receiver = address(s_receiver); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + // Nonce should increment on a strict untouched -> success. + assertEq(uint64(0), s_offRamp.getSenderNonce(address(OWNER))); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertEq(uint64(1), s_offRamp.getSenderNonce(address(OWNER))); + } + + function test_SkippedIncorrectNonce_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + messages[0].nonce++; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.SkippedIncorrectNonce(messages[0].nonce, messages[0].sender); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + } + + function test_SkippedIncorrectNonceStillExecutes_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateMessagesWithTokens(); + + messages[1].nonce++; + messages[1].messageId = Internal._hash(messages[1], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + vm.expectEmit(); + emit EVM2EVMOffRamp.SkippedIncorrectNonce(messages[1].nonce, messages[1].sender); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + } + + function test__execute_SkippedAlreadyExecutedMessage_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + vm.expectEmit(); + emit EVM2EVMOffRamp.SkippedAlreadyExecutedMessage(messages[0].sequenceNumber); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + } + + function test__execute_SkippedAlreadyExecutedMessageUnordered_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + messages[0].nonce = 0; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + vm.expectEmit(); + emit EVM2EVMOffRamp.SkippedAlreadyExecutedMessage(messages[0].sequenceNumber); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + } + + // Send a message to a contract that does not implement the CCIPReceiver interface + // This should execute successfully. + function test_SingleMessageToNonCCIPReceiver_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + MaybeRevertMessageReceiverNo165 newReceiver = new MaybeRevertMessageReceiverNo165(true); + messages[0].receiver = address(newReceiver); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + } + + function test_SingleMessagesNoTokensSuccess_gas() public { + vm.pauseGasMetering(); + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + Internal.ExecutionReport memory report = _generateReportFromMessages(messages); + + vm.resumeGasMetering(); + s_offRamp.execute(report, new uint256[](0)); + } + + function test_TwoMessagesWithTokensSuccess_gas() public { + vm.pauseGasMetering(); + Internal.EVM2EVMMessage[] memory messages = _generateMessagesWithTokens(); + // Set message 1 to use another receiver to simulate more fair gas costs + messages[1].receiver = address(s_secondary_receiver); + messages[1].messageId = Internal._hash(messages[1], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[1].sequenceNumber, messages[1].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + Internal.ExecutionReport memory report = _generateReportFromMessages(messages); + + vm.resumeGasMetering(); + s_offRamp.execute(report, new uint256[](0)); + } + + function test_TwoMessagesWithTokensAndGE_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateMessagesWithTokens(); + // Set message 1 to use another receiver to simulate more fair gas costs + messages[1].receiver = address(s_secondary_receiver); + messages[1].messageId = Internal._hash(messages[1], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[1].sequenceNumber, messages[1].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + assertEq(uint64(0), s_offRamp.getSenderNonce(OWNER)); + s_offRamp.execute(_generateReportFromMessages(messages), _getGasLimitsFromMessages(messages)); + assertEq(uint64(2), s_offRamp.getSenderNonce(OWNER)); + } + + function test_Fuzz_InterleavingOrderedAndUnorderedMessages_Success(bool[7] memory orderings) public { + Internal.EVM2EVMMessage[] memory messages = new Internal.EVM2EVMMessage[](orderings.length); + // number of tokens needs to be capped otherwise we hit UnsupportedNumberOfTokens. + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](3); + for (uint256 i = 0; i < 3; ++i) { + tokenAmounts[i].token = s_sourceTokens[i % s_sourceTokens.length]; + tokenAmounts[i].amount = 1e18; + } + uint64 expectedNonce = 0; + for (uint256 i = 0; i < orderings.length; ++i) { + messages[i] = _generateAny2EVMMessage(uint64(i + 1), tokenAmounts, !orderings[i]); + if (orderings[i]) { + messages[i].nonce = ++expectedNonce; + } + messages[i].messageId = Internal._hash(messages[i], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[i].sequenceNumber, messages[i].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + } + + uint64 nonceBefore = s_offRamp.getSenderNonce(OWNER); + assertEq(uint64(0), nonceBefore, "nonce before exec should be 0"); + s_offRamp.execute(_generateReportFromMessages(messages), _getGasLimitsFromMessages(messages)); + // all executions should succeed. + for (uint256 i = 0; i < orderings.length; ++i) { + assertEq( + uint256(s_offRamp.getExecutionState(messages[i].sequenceNumber)), + uint256(Internal.MessageExecutionState.SUCCESS) + ); + } + assertEq(nonceBefore + expectedNonce, s_offRamp.getSenderNonce(OWNER)); + } + + function test_InvalidSourcePoolAddress_Success() public { + address fakePoolAddress = address(0x0000000000333333); + + Internal.EVM2EVMMessage[] memory messages = _generateMessagesWithTokens(); + messages[0].sourceTokenData[0] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(fakePoolAddress), + destTokenAddress: abi.encode(s_destTokenBySourceToken[messages[0].tokenAmounts[0].token]), + extraData: "" + }) + ); + + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + messages[1].messageId = Internal._hash(messages[1], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, + messages[0].messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + EVM2EVMOffRamp.TokenHandlingError.selector, + abi.encodeWithSelector(TokenPool.InvalidSourcePoolAddress.selector, abi.encode(fakePoolAddress)) + ) + ); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + } + + // Reverts + + function test_InvalidMessageId_Revert() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + messages[0].nonce++; + // MessageID no longer matches hash. + Internal.ExecutionReport memory executionReport = _generateReportFromMessages(messages); + vm.expectRevert(EVM2EVMOffRamp.InvalidMessageId.selector); + s_offRamp.execute(executionReport, new uint256[](0)); + } + + function test_Paused_Revert() public { + s_mockCommitStore.pause(); + vm.expectRevert(PausedError.selector); + s_offRamp.execute(_generateReportFromMessages(_generateMessagesWithTokens()), new uint256[](0)); + } + + function test_Unhealthy_Revert() public { + s_mockRMN.setGlobalCursed(true); + vm.expectRevert(EVM2EVMOffRamp.CursedByRMN.selector); + s_offRamp.execute(_generateReportFromMessages(_generateMessagesWithTokens()), new uint256[](0)); + // Uncurse should succeed + s_mockRMN.setGlobalCursed(false); + s_offRamp.execute(_generateReportFromMessages(_generateMessagesWithTokens()), new uint256[](0)); + } + + function test_UnexpectedTokenData_Revert() public { + Internal.ExecutionReport memory report = _generateReportFromMessages(_generateSingleBasicMessage()); + report.offchainTokenData = new bytes[][](report.messages.length + 1); + + vm.expectRevert(EVM2EVMOffRamp.UnexpectedTokenData.selector); + + s_offRamp.execute(report, new uint256[](0)); + } + + function test_EmptyReport_Revert() public { + vm.expectRevert(EVM2EVMOffRamp.EmptyReport.selector); + s_offRamp.execute( + Internal.ExecutionReport({ + proofs: new bytes32[](0), + proofFlagBits: 0, + messages: new Internal.EVM2EVMMessage[](0), + offchainTokenData: new bytes[][](0) + }), + new uint256[](0) + ); + } + + function test_RootNotCommitted_Revert() public { + vm.mockCall(address(s_mockCommitStore), abi.encodeWithSelector(ICommitStore.verify.selector), abi.encode(0)); + vm.expectRevert(EVM2EVMOffRamp.RootNotCommitted.selector); + + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + s_offRamp.execute(_generateReportFromMessages(messages), _getGasLimitsFromMessages(messages)); + vm.clearMockedCalls(); + } + + function test_ManualExecutionNotYetEnabled_Revert() public { + vm.mockCall( + address(s_mockCommitStore), abi.encodeWithSelector(ICommitStore.verify.selector), abi.encode(BLOCK_TIME) + ); + vm.expectRevert(EVM2EVMOffRamp.ManualExecutionNotYetEnabled.selector); + + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + s_offRamp.execute(_generateReportFromMessages(messages), _getGasLimitsFromMessages(messages)); + vm.clearMockedCalls(); + } + + function test_InvalidSourceChain_Revert() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + messages[0].sourceChainSelector = SOURCE_CHAIN_SELECTOR + 1; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.InvalidSourceChain.selector, SOURCE_CHAIN_SELECTOR + 1)); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + } + + function test_UnsupportedNumberOfTokens_Revert() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + Client.EVMTokenAmount[] memory newTokens = new Client.EVMTokenAmount[](MAX_TOKENS_LENGTH + 1); + messages[0].tokenAmounts = newTokens; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + Internal.ExecutionReport memory report = _generateReportFromMessages(messages); + + vm.expectRevert( + abi.encodeWithSelector(EVM2EVMOffRamp.UnsupportedNumberOfTokens.selector, messages[0].sequenceNumber) + ); + s_offRamp.execute(report, new uint256[](0)); + } + + function test_TokenDataMismatch_Revert() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + Internal.ExecutionReport memory report = _generateReportFromMessages(messages); + + report.offchainTokenData[0] = new bytes[](messages[0].tokenAmounts.length + 1); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.TokenDataMismatch.selector, messages[0].sequenceNumber)); + s_offRamp.execute(report, new uint256[](0)); + } + + function test_MessageTooLarge_Revert() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + messages[0].data = new bytes(MAX_DATA_SIZE + 1); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + Internal.ExecutionReport memory executionReport = _generateReportFromMessages(messages); + vm.expectRevert( + abi.encodeWithSelector(EVM2EVMOffRamp.MessageTooLarge.selector, MAX_DATA_SIZE, messages[0].data.length) + ); + s_offRamp.execute(executionReport, new uint256[](0)); + } + + function test_RouterYULCall_Revert() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + // gas limit too high, Router's external call should revert + messages[0].gasLimit = 1e36; + messages[0].receiver = address(new ConformingReceiver(address(s_destRouter), s_destFeeToken)); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + Internal.ExecutionReport memory executionReport = _generateReportFromMessages(messages); + + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMOffRamp.ExecutionError.selector, abi.encodeWithSelector(CallWithExactGas.NotEnoughGasForCall.selector) + ) + ); + s_offRamp.execute(executionReport, new uint256[](0)); + } + + function test_RetryFailedMessageWithoutManualExecution_Revert() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + bytes memory realError1 = new bytes(2); + realError1[0] = 0xbe; + realError1[1] = 0xef; + s_reverting_receiver.setErr(realError1); + + messages[0].receiver = address(s_reverting_receiver); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, + messages[0].messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + EVM2EVMOffRamp.ReceiverError.selector, + abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, realError1) + ) + ); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.AlreadyAttempted.selector, messages[0].sequenceNumber)); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + } +} + +contract EVM2EVMOffRamp_execute_upgrade is EVM2EVMOffRampSetup { + EVM2EVMOffRampHelper internal s_prevOffRamp; + + function setUp() public virtual override { + super.setUp(); + + s_prevOffRamp = s_offRamp; + + deployOffRamp(s_mockCommitStore, s_destRouter, address(s_prevOffRamp)); + } + + function test_V2_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + } + + function test_V2SenderNoncesReadsPreviousRamp_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + uint64 startNonce = s_offRamp.getSenderNonce(messages[0].sender); + + for (uint64 i = 1; i < 4; ++i) { + s_prevOffRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + messages[0].nonce++; + messages[0].sequenceNumber++; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + assertEq(startNonce + i, s_offRamp.getSenderNonce(messages[0].sender)); + } + } + + function test_V2NonceStartsAtV1Nonce_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + uint64 startNonce = s_offRamp.getSenderNonce(messages[0].sender); + + s_prevOffRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + assertEq(startNonce + 1, s_offRamp.getSenderNonce(messages[0].sender)); + + messages[0].nonce++; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertEq(startNonce + 2, s_offRamp.getSenderNonce(messages[0].sender)); + + messages[0].nonce++; + messages[0].sequenceNumber++; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertEq(startNonce + 3, s_offRamp.getSenderNonce(messages[0].sender)); + } + + function test_V2NonceNewSenderStartsAtZero_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + s_prevOffRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + address newSender = address(1234567); + messages[0].sender = newSender; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + // new sender nonce in new offramp should go from 0 -> 1 + assertEq(s_offRamp.getSenderNonce(newSender), 0); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertEq(s_offRamp.getSenderNonce(newSender), 1); + } + + function test_V2OffRampNonceSkipsIfMsgInFlight_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + address newSender = address(1234567); + messages[0].sender = newSender; + messages[0].nonce = 2; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + uint64 startNonce = s_offRamp.getSenderNonce(messages[0].sender); + + // new offramp sees msg nonce higher than senderNonce + // it waits for previous offramp to execute + vm.expectEmit(); + emit EVM2EVMOffRamp.SkippedSenderWithPreviousRampMessageInflight(messages[0].nonce, newSender); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertEq(startNonce, s_offRamp.getSenderNonce(messages[0].sender)); + + messages[0].nonce = 1; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + // previous offramp executes msg and increases nonce + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + s_prevOffRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertEq(startNonce + 1, s_offRamp.getSenderNonce(messages[0].sender)); + + messages[0].nonce = 2; + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + // new offramp is able to execute + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + assertEq(startNonce + 2, s_offRamp.getSenderNonce(messages[0].sender)); + } +} + +contract EVM2EVMOffRamp_executeSingleMessage is EVM2EVMOffRampSetup { + function setUp() public virtual override { + super.setUp(); + vm.startPrank(address(s_offRamp)); + } + + function test_executeSingleMessage_NoTokens_Success() public { + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageNoTokens(1); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + function test_executeSingleMessage_WithTokens_Success() public { + Internal.EVM2EVMMessage memory message = _generateMessagesWithTokens()[0]; + bytes[] memory offchainTokenData = new bytes[](message.tokenAmounts.length); + Internal.SourceTokenData memory sourceTokenData = abi.decode(message.sourceTokenData[0], (Internal.SourceTokenData)); + + vm.expectCall( + s_destPoolByToken[s_destTokens[0]], + abi.encodeWithSelector( + LockReleaseTokenPool.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(message.sender), + receiver: message.receiver, + amount: message.tokenAmounts[0].amount, + localToken: s_destTokenBySourceToken[message.tokenAmounts[0].token], + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: "" + }) + ) + ); + + s_offRamp.executeSingleMessage(message, offchainTokenData); + } + + function test_executeSingleMessage_ZeroGasZeroData_Success() public { + uint256 gasLimit = 0; + Internal.EVM2EVMMessage memory message = _generateMsgWithoutTokens(gasLimit); + Client.Any2EVMMessage memory receiverMsg = _convertToGeneralMessage(message); + + // expect 0 calls to be made as no gas is provided + vm.expectCall( + address(s_destRouter), + abi.encodeCall(Router.routeMessage, (receiverMsg, Internal.GAS_FOR_CALL_EXACT_CHECK, gasLimit, message.receiver)), + 0 + ); + + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + + // Ensure we encoded it properly, and didn't simply expect the wrong call + gasLimit = 200_000; + message = _generateMsgWithoutTokens(gasLimit); + receiverMsg = _convertToGeneralMessage(message); + + vm.expectCall( + address(s_destRouter), + abi.encodeCall(Router.routeMessage, (receiverMsg, Internal.GAS_FOR_CALL_EXACT_CHECK, gasLimit, message.receiver)), + 1 + ); + + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + function _generateMsgWithoutTokens(uint256 gasLimit) internal view returns (Internal.EVM2EVMMessage memory) { + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageNoTokens(1); + message.gasLimit = gasLimit; + message.data = ""; + message.messageId = Internal._hash( + message, + keccak256( + abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, SOURCE_CHAIN_SELECTOR, DEST_CHAIN_SELECTOR, ON_RAMP_ADDRESS) + ) + ); + return message; + } + + function test_NonContract_Success() public { + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageNoTokens(1); + message.receiver = STRANGER; + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + function test_NonContractWithTokens_Success() public { + uint256[] memory amounts = new uint256[](2); + amounts[0] = 1000; + amounts[1] = 50; + vm.expectEmit(); + emit TokenPool.Released(address(s_offRamp), STRANGER, amounts[0]); + vm.expectEmit(); + emit TokenPool.Minted(address(s_offRamp), STRANGER, amounts[1]); + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageWithTokens(1, amounts); + message.receiver = STRANGER; + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + // Reverts + + function test_TokenHandlingError_Revert() public { + uint256[] memory amounts = new uint256[](2); + amounts[0] = 1000; + amounts[1] = 50; + + bytes memory errorMessage = "Random token pool issue"; + + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageWithTokens(1, amounts); + s_maybeRevertingPool.setShouldRevert(errorMessage); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, errorMessage)); + + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + function test_ZeroGasDONExecution_Revert() public { + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageNoTokens(1); + message.gasLimit = 0; + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.ReceiverError.selector, "")); + + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } + + function test_MessageSender_Revert() public { + vm.stopPrank(); + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageNoTokens(1); + vm.expectRevert(EVM2EVMOffRamp.CanOnlySelfCall.selector); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + } +} + +contract EVM2EVMOffRamp__report is EVM2EVMOffRampSetup { + // Asserts that execute completes + function test_Report_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + Internal.ExecutionReport memory report = _generateReportFromMessages(messages); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + s_offRamp.report(abi.encode(report)); + } +} + +contract EVM2EVMOffRamp_manuallyExecute is EVM2EVMOffRampSetup { + function test_ManualExec_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + messages[0].receiver = address(s_reverting_receiver); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + s_reverting_receiver.setRevert(false); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), new uint256[](messages.length)); + } + + function test_manuallyExecute_DoesNotRevertIfUntouched_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + messages[0].receiver = address(s_reverting_receiver); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + assertEq(messages[0].nonce - 1, s_offRamp.getSenderNonce(messages[0].sender)); + + s_reverting_receiver.setRevert(true); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, + messages[0].messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + EVM2EVMOffRamp.ReceiverError.selector, + abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, "") + ) + ); + + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), new uint256[](1)); + + assertEq(messages[0].nonce, s_offRamp.getSenderNonce(messages[0].sender)); + } + + function test_ManualExecWithGasOverride_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + messages[0].receiver = address(s_reverting_receiver); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + s_reverting_receiver.setRevert(false); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + uint256[] memory gasLimitOverrides = _getGasLimitsFromMessages(messages); + gasLimitOverrides[0] += 1; + + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimitOverrides); + } + + function test_LowGasLimitManualExec_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + messages[0].gasLimit = 1; + messages[0].receiver = address(new ConformingReceiver(address(s_destRouter), s_destFeeToken)); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, + messages[0].messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector(EVM2EVMOffRamp.ReceiverError.selector, "") + ); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + uint256[] memory gasLimitOverrides = new uint256[](1); + gasLimitOverrides[0] = 100_000; + + vm.expectEmit(); + emit MaybeRevertMessageReceiver.MessageReceived(); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimitOverrides); + } + + function test_ManualExecForkedChain_Revert() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + Internal.ExecutionReport memory report = _generateReportFromMessages(messages); + uint256 chain1 = block.chainid; + uint256 chain2 = chain1 + 1; + vm.chainId(chain2); + vm.expectRevert(abi.encodeWithSelector(OCR2BaseNoChecks.ForkedChain.selector, chain1, chain2)); + + s_offRamp.manuallyExecute(report, _getGasLimitsFromMessages(messages)); + } + + function test_ManualExecGasLimitMismatch_Revert() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + vm.expectRevert(EVM2EVMOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), new uint256[](0)); + + vm.expectRevert(EVM2EVMOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), new uint256[](messages.length - 1)); + + vm.expectRevert(EVM2EVMOffRamp.ManualExecutionGasLimitMismatch.selector); + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), new uint256[](messages.length + 1)); + } + + function test_ManualExecInvalidGasLimit_Revert() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + uint256[] memory gasLimits = _getGasLimitsFromMessages(messages); + gasLimits[0]--; + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.InvalidManualExecutionGasLimit.selector, 0, gasLimits[0])); + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimits); + } + + function test_ManualExecFailedTx_Revert() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + messages[0].receiver = address(s_reverting_receiver); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + s_reverting_receiver.setRevert(true); + + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMOffRamp.ExecutionError.selector, + abi.encodeWithSelector( + EVM2EVMOffRamp.ReceiverError.selector, + abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, bytes("")) + ) + ) + ); + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), _getGasLimitsFromMessages(messages)); + } + + function test_ReentrancyManualExecuteFails() public { + uint256 tokenAmount = 1e9; + IERC20 tokenToAbuse = IERC20(s_destFeeToken); + + // This needs to be deployed before the source chain message is sent + // because we need the address for the receiver. + ReentrancyAbuser receiver = new ReentrancyAbuser(address(s_destRouter), s_offRamp); + uint256 balancePre = tokenToAbuse.balanceOf(address(receiver)); + + // For this test any message will be flagged as correct by the + // commitStore. In a real scenario the abuser would have to actually + // send the message that they want to replay. + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + messages[0].tokenAmounts = new Client.EVMTokenAmount[](1); + messages[0].tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceFeeToken, amount: tokenAmount}); + messages[0].receiver = address(receiver); + messages[0].sourceTokenData = new bytes[](1); + messages[0].sourceTokenData[0] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[s_sourceFeeToken]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[s_sourceFeeToken]), + extraData: "" + }) + ); + + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + Internal.ExecutionReport memory report = _generateReportFromMessages(messages); + + // sets the report to be repeated on the ReentrancyAbuser to be able to replay + receiver.setPayload(report); + + // The first entry should be fine and triggers the second entry. This one fails + // but since it's an inner tx of the first one it is caught in the try-catch. + // This means the first tx is marked `FAILURE` with the error message of the second tx. + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, + messages[0].messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + EVM2EVMOffRamp.ReceiverError.selector, + abi.encodeWithSelector(EVM2EVMOffRamp.AlreadyExecuted.selector, messages[0].sequenceNumber) + ) + ); + + s_offRamp.manuallyExecute(report, _getGasLimitsFromMessages(messages)); + + // Since the tx failed we don't release the tokens + assertEq(tokenToAbuse.balanceOf(address(receiver)), balancePre); + } +} + +contract EVM2EVMOffRamp_getExecutionState is EVM2EVMOffRampSetup { + mapping(uint64 seqNum => Internal.MessageExecutionState state) internal s_differentialExecutionState; + + /// forge-config: default.fuzz.runs = 32 + /// forge-config: ccip.fuzz.runs = 32 + function test_Fuzz_Differential_Success(uint16[500] memory seqNums, uint8[500] memory values) public { + for (uint256 i = 0; i < seqNums.length; ++i) { + // Only use the first three slots. This makes sure existing slots get overwritten + // as the tests uses 500 sequence numbers. + uint16 seqNum = seqNums[i] % 386; + Internal.MessageExecutionState state = Internal.MessageExecutionState(values[i] % 4); + s_differentialExecutionState[seqNum] = state; + s_offRamp.setExecutionStateHelper(seqNum, state); + assertEq(uint256(state), uint256(s_offRamp.getExecutionState(seqNum))); + } + + for (uint256 i = 0; i < seqNums.length; ++i) { + uint16 seqNum = seqNums[i] % 386; + Internal.MessageExecutionState expectedState = s_differentialExecutionState[seqNum]; + assertEq(uint256(expectedState), uint256(s_offRamp.getExecutionState(seqNum))); + } + } + + function test_GetExecutionState_Success() public { + s_offRamp.setExecutionStateHelper(0, Internal.MessageExecutionState.FAILURE); + assertEq(s_offRamp.getExecutionStateBitMap(0), 3); + + s_offRamp.setExecutionStateHelper(1, Internal.MessageExecutionState.FAILURE); + assertEq(s_offRamp.getExecutionStateBitMap(0), 3 + (3 << 2)); + + s_offRamp.setExecutionStateHelper(1, Internal.MessageExecutionState.IN_PROGRESS); + assertEq(s_offRamp.getExecutionStateBitMap(0), 3 + (1 << 2)); + + s_offRamp.setExecutionStateHelper(2, Internal.MessageExecutionState.FAILURE); + assertEq(s_offRamp.getExecutionStateBitMap(0), 3 + (1 << 2) + (3 << 4)); + + s_offRamp.setExecutionStateHelper(127, Internal.MessageExecutionState.IN_PROGRESS); + assertEq(s_offRamp.getExecutionStateBitMap(0), 3 + (1 << 2) + (3 << 4) + (1 << 254)); + + s_offRamp.setExecutionStateHelper(128, Internal.MessageExecutionState.SUCCESS); + assertEq(s_offRamp.getExecutionStateBitMap(0), 3 + (1 << 2) + (3 << 4) + (1 << 254)); + assertEq(s_offRamp.getExecutionStateBitMap(1), 2); + + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(s_offRamp.getExecutionState(0))); + assertEq(uint256(Internal.MessageExecutionState.IN_PROGRESS), uint256(s_offRamp.getExecutionState(1))); + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(s_offRamp.getExecutionState(2))); + assertEq(uint256(Internal.MessageExecutionState.IN_PROGRESS), uint256(s_offRamp.getExecutionState(127))); + assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(s_offRamp.getExecutionState(128))); + } + + function test_FillExecutionState_Success() public { + for (uint64 i = 0; i < 384; ++i) { + s_offRamp.setExecutionStateHelper(i, Internal.MessageExecutionState.FAILURE); + } + + for (uint64 i = 0; i < 384; ++i) { + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(s_offRamp.getExecutionState(i))); + } + + for (uint64 i = 0; i < 3; ++i) { + assertEq(type(uint256).max, s_offRamp.getExecutionStateBitMap(i)); + } + + for (uint64 i = 0; i < 384; ++i) { + s_offRamp.setExecutionStateHelper(i, Internal.MessageExecutionState.IN_PROGRESS); + } + + for (uint64 i = 0; i < 384; ++i) { + assertEq(uint256(Internal.MessageExecutionState.IN_PROGRESS), uint256(s_offRamp.getExecutionState(i))); + } + + for (uint64 i = 0; i < 3; ++i) { + // 0x555... == 0b101010101010..... + assertEq(0x5555555555555555555555555555555555555555555555555555555555555555, s_offRamp.getExecutionStateBitMap(i)); + } + } +} + +contract EVM2EVMOffRamp__trialExecute is EVM2EVMOffRampSetup { + function test_trialExecute_Success() public { + uint256[] memory amounts = new uint256[](2); + amounts[0] = 1000; + amounts[1] = 50; + + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageWithTokens(1, amounts); + IERC20 dstToken0 = IERC20(s_destTokens[0]); + uint256 startingBalance = dstToken0.balanceOf(message.receiver); + + (Internal.MessageExecutionState newState, bytes memory err) = + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); + assertEq("", err); + + // Check that the tokens were transferred + assertEq(startingBalance + amounts[0], dstToken0.balanceOf(message.receiver)); + } + + function test_TokenHandlingErrorIsCaught_Success() public { + uint256[] memory amounts = new uint256[](2); + amounts[0] = 1000; + amounts[1] = 50; + + IERC20 dstToken0 = IERC20(s_destTokens[0]); + uint256 startingBalance = dstToken0.balanceOf(OWNER); + + bytes memory errorMessage = "Random token pool issue"; + + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageWithTokens(1, amounts); + s_maybeRevertingPool.setShouldRevert(errorMessage); + + (Internal.MessageExecutionState newState, bytes memory err) = + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); + assertEq(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, errorMessage), err); + + // Expect the balance to remain the same + assertEq(startingBalance, dstToken0.balanceOf(OWNER)); + } + + function test_RateLimitError_Success() public { + uint256[] memory amounts = new uint256[](2); + amounts[0] = 1000; + amounts[1] = 50; + + bytes memory errorMessage = abi.encodeWithSelector(RateLimiter.BucketOverfilled.selector); + + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageWithTokens(1, amounts); + s_maybeRevertingPool.setShouldRevert(errorMessage); + + (Internal.MessageExecutionState newState, bytes memory err) = + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); + assertEq(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, errorMessage), err); + } + + function test_TokenPoolIsNotAContract_Success() public { + uint256[] memory amounts = new uint256[](2); + amounts[0] = 10000; + Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageWithTokens(1, amounts); + + // Happy path, pool is correct + (Internal.MessageExecutionState newState, bytes memory err) = + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + + assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); + assertEq("", err); + + // address 0 has no contract + assertEq(address(0).code.length, 0); + message.sourceTokenData[0] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(address(0)), + destTokenAddress: abi.encode(address(0)), + extraData: "" + }) + ); + + message.messageId = Internal._hash( + message, + keccak256( + abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, SOURCE_CHAIN_SELECTOR, DEST_CHAIN_SELECTOR, ON_RAMP_ADDRESS) + ) + ); + + // Unhappy path, no revert but marked as failed. + (newState, err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); + assertEq(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, abi.encode(address(0))), err); + + address notAContract = makeAddr("not_a_contract"); + + message.sourceTokenData[0] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(address(0)), + destTokenAddress: abi.encode(notAContract), + extraData: "" + }) + ); + + message.messageId = Internal._hash( + message, + keccak256( + abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, SOURCE_CHAIN_SELECTOR, DEST_CHAIN_SELECTOR, ON_RAMP_ADDRESS) + ) + ); + + (newState, err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); + assertEq(abi.encodeWithSelector(EVM2EVMOffRamp.NotACompatiblePool.selector, address(0)), err); + } +} + +contract EVM2EVMOffRamp__releaseOrMintToken is EVM2EVMOffRampSetup { + function test__releaseOrMintToken_Success() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + bytes memory originalSender = abi.encode(OWNER); + bytes memory offchainTokenData = abi.encode(keccak256("offchainTokenData")); + + IERC20 dstToken1 = IERC20(s_destTokenBySourceToken[token]); + uint256 startingBalance = dstToken1.balanceOf(OWNER); + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), + extraData: "" + }); + + vm.expectCall( + s_destPoolBySourceToken[token], + abi.encodeWithSelector( + LockReleaseTokenPool.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: originalSender, + receiver: OWNER, + amount: amount, + localToken: s_destTokenBySourceToken[token], + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData + }) + ) + ); + + s_offRamp.releaseOrMintToken(amount, originalSender, OWNER, sourceTokenData, offchainTokenData); + + assertEq(startingBalance + amount, dstToken1.balanceOf(OWNER)); + } + + function test__releaseOrMintToken_NotACompatiblePool_Revert() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + address destToken = s_destTokenBySourceToken[token]; + vm.label(destToken, "destToken"); + bytes memory originalSender = abi.encode(OWNER); + bytes memory offchainTokenData = abi.encode(keccak256("offchainTokenData")); + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(destToken), + extraData: "" + }); + + // Address(0) should always revert + address returnedPool = address(0); + + vm.mockCall( + address(s_tokenAdminRegistry), + abi.encodeWithSelector(ITokenAdminRegistry.getPool.selector, destToken), + abi.encode(returnedPool) + ); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.NotACompatiblePool.selector, returnedPool)); + + s_offRamp.releaseOrMintToken(amount, originalSender, OWNER, sourceTokenData, offchainTokenData); + + // A contract that doesn't support the interface should also revert + returnedPool = address(s_offRamp); + + vm.mockCall( + address(s_tokenAdminRegistry), + abi.encodeWithSelector(ITokenAdminRegistry.getPool.selector, destToken), + abi.encode(returnedPool) + ); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.NotACompatiblePool.selector, returnedPool)); + + s_offRamp.releaseOrMintToken(amount, originalSender, OWNER, sourceTokenData, offchainTokenData); + } + + function test__releaseOrMintToken_TokenHandlingError_revert_Revert() public { + address receiver = makeAddr("receiver"); + uint256 amount = 123123; + address token = s_sourceTokens[0]; + address destToken = s_destTokenBySourceToken[token]; + bytes memory originalSender = abi.encode(OWNER); + bytes memory offchainTokenData = abi.encode(keccak256("offchainTokenData")); + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(destToken), + extraData: "" + }); + + bytes memory revertData = "call reverted :o"; + + vm.mockCallRevert(destToken, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount), revertData); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, revertData)); + s_offRamp.releaseOrMintToken(amount, originalSender, receiver, sourceTokenData, offchainTokenData); + } +} + +contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { + function test_releaseOrMintTokens_Success() public { + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + IERC20 dstToken1 = IERC20(s_destFeeToken); + uint256 startingBalance = dstToken1.balanceOf(OWNER); + uint256 amount1 = 100; + srcTokenAmounts[0].amount = amount1; + + bytes memory originalSender = abi.encode(OWNER); + + bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); + offchainTokenData[0] = abi.encode(0x12345678); + + bytes[] memory encodedSourceTokenData = _getDefaultSourceTokenData(srcTokenAmounts); + Internal.SourceTokenData memory sourceTokenData = abi.decode(encodedSourceTokenData[0], (Internal.SourceTokenData)); + + vm.expectCall( + s_destPoolBySourceToken[srcTokenAmounts[0].token], + abi.encodeWithSelector( + LockReleaseTokenPool.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: originalSender, + receiver: OWNER, + amount: srcTokenAmounts[0].amount, + localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData[0] + }) + ) + ); + + s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, encodedSourceTokenData, offchainTokenData); + + assertEq(startingBalance + amount1, dstToken1.balanceOf(OWNER)); + } + + function test_releaseOrMintTokens_destDenominatedDecimals_Success() public { + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + address destToken = s_destFeeToken; + uint256 amount = 100; + uint256 destinationDenominationMultiplier = 1000; + srcTokenAmounts[0].amount = amount; + + bytes memory originalSender = abi.encode(OWNER); + bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); + bytes[] memory encodedSourceTokenData = _getDefaultSourceTokenData(srcTokenAmounts); + Internal.SourceTokenData memory sourceTokenData = abi.decode(encodedSourceTokenData[0], (Internal.SourceTokenData)); + + // Since the pool call is mocked, we manually release funds to the offRamp + deal(destToken, address(s_offRamp), amount * destinationDenominationMultiplier); + + vm.mockCall( + s_destPoolBySourceToken[srcTokenAmounts[0].token], + abi.encodeWithSelector( + LockReleaseTokenPool.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: originalSender, + receiver: OWNER, + amount: amount, + localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData[0] + }) + ), + abi.encode(amount * destinationDenominationMultiplier) + ); + + Client.EVMTokenAmount[] memory destTokenAmounts = + s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, encodedSourceTokenData, offchainTokenData); + + assertEq(destTokenAmounts[0].amount, amount * destinationDenominationMultiplier); + assertEq(destTokenAmounts[0].token, destToken); + } + + function test_OverValueWithARLOff_Success() public { + // Set a high price to trip the ARL + uint224 tokenPrice = 3 ** 128; + Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(s_destFeeToken, tokenPrice); + s_priceRegistry.updatePrices(priceUpdates); + + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + uint256 amount1 = 100; + srcTokenAmounts[0].amount = amount1; + + bytes memory originalSender = abi.encode(OWNER); + + bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); + offchainTokenData[0] = abi.encode(0x12345678); + + bytes[] memory sourceTokenData = _getDefaultSourceTokenData(srcTokenAmounts); + + vm.expectRevert( + abi.encodeWithSelector( + RateLimiter.AggregateValueMaxCapacityExceeded.selector, + getInboundRateLimiterConfig().capacity, + (amount1 * tokenPrice) / 1e18 + ) + ); + + // // Expect to fail from ARL + s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, sourceTokenData, offchainTokenData); + + // Configure ARL off for token + EVM2EVMOffRamp.RateLimitToken[] memory removes = new EVM2EVMOffRamp.RateLimitToken[](1); + removes[0] = EVM2EVMOffRamp.RateLimitToken({sourceToken: s_sourceFeeToken, destToken: s_destFeeToken}); + s_offRamp.updateRateLimitTokens(removes, new EVM2EVMOffRamp.RateLimitToken[](0)); + + // Expect the call now succeeds + s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, sourceTokenData, offchainTokenData); + } + + // Revert + + function test_TokenHandlingError_Reverts() public { + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + + bytes memory unknownError = bytes("unknown error"); + s_maybeRevertingPool.setShouldRevert(unknownError); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, unknownError)); + + s_offRamp.releaseOrMintTokens( + srcTokenAmounts, + abi.encode(OWNER), + OWNER, + _getDefaultSourceTokenData(srcTokenAmounts), + new bytes[](srcTokenAmounts.length) + ); + } + + function test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() public { + uint256 amount = 100; + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + srcTokenAmounts[0].amount = amount; + + bytes memory originalSender = abi.encode(OWNER); + bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); + bytes[] memory encodedSourceTokenData = _getDefaultSourceTokenData(srcTokenAmounts); + Internal.SourceTokenData memory sourceTokenData = abi.decode(encodedSourceTokenData[0], (Internal.SourceTokenData)); + + vm.mockCall( + s_destPoolBySourceToken[srcTokenAmounts[0].token], + abi.encodeWithSelector( + LockReleaseTokenPool.releaseOrMint.selector, + Pool.ReleaseOrMintInV1({ + originalSender: originalSender, + receiver: OWNER, + amount: amount, + localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData[0] + }) + ), + // Includes the amount twice, this will revert due to the return data being to long + abi.encode(amount, amount) + ); + + vm.expectRevert( + abi.encodeWithSelector(EVM2EVMOffRamp.InvalidDataLength.selector, Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, 64) + ); + + s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, encodedSourceTokenData, offchainTokenData); + } + + function test_releaseOrMintTokens_InvalidEVMAddress_Revert() public { + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + + bytes memory originalSender = abi.encode(OWNER); + bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); + bytes[] memory sourceTokenData = _getDefaultSourceTokenData(srcTokenAmounts); + bytes memory wrongAddress = abi.encode(address(1000), address(10000), address(10000)); + + sourceTokenData[0] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[srcTokenAmounts[0].token]), + destTokenAddress: wrongAddress, + extraData: "" + }) + ); + + vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, wrongAddress)); + + s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, sourceTokenData, offchainTokenData); + } + + function test_RateLimitErrors_Reverts() public { + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + + bytes[] memory rateLimitErrors = new bytes[](5); + rateLimitErrors[0] = abi.encodeWithSelector(RateLimiter.BucketOverfilled.selector); + rateLimitErrors[1] = + abi.encodeWithSelector(RateLimiter.AggregateValueMaxCapacityExceeded.selector, uint256(100), uint256(1000)); + rateLimitErrors[2] = + abi.encodeWithSelector(RateLimiter.AggregateValueRateLimitReached.selector, uint256(42), 1, s_sourceTokens[0]); + rateLimitErrors[3] = abi.encodeWithSelector( + RateLimiter.TokenMaxCapacityExceeded.selector, uint256(100), uint256(1000), s_sourceTokens[0] + ); + rateLimitErrors[4] = + abi.encodeWithSelector(RateLimiter.TokenRateLimitReached.selector, uint256(42), 1, s_sourceTokens[0]); + + for (uint256 i = 0; i < rateLimitErrors.length; ++i) { + s_maybeRevertingPool.setShouldRevert(rateLimitErrors[i]); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, rateLimitErrors[i])); + + s_offRamp.releaseOrMintTokens( + srcTokenAmounts, + abi.encode(OWNER), + OWNER, + _getDefaultSourceTokenData(srcTokenAmounts), + new bytes[](srcTokenAmounts.length) + ); + } + } + + function test__releaseOrMintTokens_NotACompatiblePool_Reverts() public { + address fakePoolAddress = makeAddr("Doesn't exist"); + + bytes[] memory sourceTokenData = new bytes[](1); + sourceTokenData[0] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(fakePoolAddress), + destTokenAddress: abi.encode(fakePoolAddress), + extraData: "" + }) + ); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.NotACompatiblePool.selector, address(0))); + s_offRamp.releaseOrMintTokens( + new Client.EVMTokenAmount[](1), abi.encode(makeAddr("original_sender")), OWNER, sourceTokenData, new bytes[](1) + ); + } + + function test_PriceNotFoundForToken_Reverts() public { + // Set token price to 0 + s_priceRegistry.updatePrices(getSingleTokenPriceUpdateStruct(s_destFeeToken, 0)); + + Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + uint256 amount1 = 100; + srcTokenAmounts[0].amount = amount1; + + bytes memory originalSender = abi.encode(OWNER); + + bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); + offchainTokenData[0] = abi.encode(0x12345678); + + bytes[] memory sourceTokenData = _getDefaultSourceTokenData(srcTokenAmounts); + + vm.expectRevert(abi.encodeWithSelector(AggregateRateLimiter.PriceNotFoundForToken.selector, s_destFeeToken)); + + s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, sourceTokenData, offchainTokenData); + } + + /// forge-config: default.fuzz.runs = 32 + /// forge-config: ccip.fuzz.runs = 1024 + // Uint256 gives a good range of values to test, both inside and outside of the eth address space. + function test_Fuzz__releaseOrMintTokens_AnyRevertIsCaught_Success(uint256 destPool) public { + // Input 447301751254033913445893214690834296930546521452, which is 0x4E59B44847B379578588920CA78FBF26C0B4956C + // triggers some Create2Deployer and causes it to fail + vm.assume(destPool != 447301751254033913445893214690834296930546521452); + bytes memory unusedVar = abi.encode(makeAddr("unused")); + bytes[] memory sourceTokenData = new bytes[](1); + sourceTokenData[0] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: unusedVar, + destTokenAddress: abi.encode(destPool), + extraData: unusedVar + }) + ); + + try s_offRamp.releaseOrMintTokens(new Client.EVMTokenAmount[](1), unusedVar, OWNER, sourceTokenData, new bytes[](1)) + {} catch (bytes memory reason) { + // Any revert should be a TokenHandlingError, InvalidEVMAddress, InvalidDataLength or NoContract as those are caught by the offramp + assertTrue( + bytes4(reason) == EVM2EVMOffRamp.TokenHandlingError.selector + || bytes4(reason) == Internal.InvalidEVMAddress.selector + || bytes4(reason) == EVM2EVMOffRamp.InvalidDataLength.selector + || bytes4(reason) == CallWithExactGas.NoContract.selector + || bytes4(reason) == EVM2EVMOffRamp.NotACompatiblePool.selector, + "Expected TokenHandlingError or InvalidEVMAddress" + ); + + if (destPool > type(uint160).max) { + assertEq(reason, abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, abi.encode(destPool))); + } + } + } +} + +contract EVM2EVMOffRamp_getAllRateLimitTokens is EVM2EVMOffRampSetup { + function test_GetAllRateLimitTokens_Success() public view { + (address[] memory sourceTokens, address[] memory destTokens) = s_offRamp.getAllRateLimitTokens(); + + for (uint256 i = 0; i < s_sourceTokens.length; ++i) { + assertEq(s_sourceTokens[i], sourceTokens[i]); + assertEq(s_destTokens[i], destTokens[i]); + } + } +} + +contract EVM2EVMOffRamp_updateRateLimitTokens is EVM2EVMOffRampSetup { + function setUp() public virtual override { + super.setUp(); + // Clear rate limit tokens state + EVM2EVMOffRamp.RateLimitToken[] memory remove = new EVM2EVMOffRamp.RateLimitToken[](s_sourceTokens.length); + for (uint256 i = 0; i < s_sourceTokens.length; ++i) { + remove[i] = EVM2EVMOffRamp.RateLimitToken({sourceToken: s_sourceTokens[i], destToken: s_destTokens[i]}); + } + s_offRamp.updateRateLimitTokens(remove, new EVM2EVMOffRamp.RateLimitToken[](0)); + } + + function test_updateRateLimitTokens_Success() public { + EVM2EVMOffRamp.RateLimitToken[] memory adds = new EVM2EVMOffRamp.RateLimitToken[](2); + adds[0] = EVM2EVMOffRamp.RateLimitToken({sourceToken: s_sourceTokens[0], destToken: s_destTokens[0]}); + adds[1] = EVM2EVMOffRamp.RateLimitToken({sourceToken: s_sourceTokens[1], destToken: s_destTokens[1]}); + + for (uint256 i = 0; i < adds.length; ++i) { + vm.expectEmit(); + emit EVM2EVMOffRamp.TokenAggregateRateLimitAdded(adds[i].sourceToken, adds[i].destToken); + } + + s_offRamp.updateRateLimitTokens(new EVM2EVMOffRamp.RateLimitToken[](0), adds); + + (address[] memory sourceTokens, address[] memory destTokens) = s_offRamp.getAllRateLimitTokens(); + + for (uint256 i = 0; i < adds.length; ++i) { + assertEq(adds[i].sourceToken, sourceTokens[i]); + assertEq(adds[i].destToken, destTokens[i]); + } + } + + function test_updateRateLimitTokens_AddsAndRemoves_Success() public { + EVM2EVMOffRamp.RateLimitToken[] memory adds = new EVM2EVMOffRamp.RateLimitToken[](3); + adds[0] = EVM2EVMOffRamp.RateLimitToken({sourceToken: s_sourceTokens[0], destToken: s_destTokens[0]}); + adds[1] = EVM2EVMOffRamp.RateLimitToken({sourceToken: s_sourceTokens[1], destToken: s_destTokens[1]}); + // Add a duplicate, this should not revert the tx + adds[2] = EVM2EVMOffRamp.RateLimitToken({sourceToken: s_sourceTokens[1], destToken: s_destTokens[1]}); + + EVM2EVMOffRamp.RateLimitToken[] memory removes = new EVM2EVMOffRamp.RateLimitToken[](1); + removes[0] = adds[0]; + + for (uint256 i = 0; i < adds.length - 1; ++i) { + vm.expectEmit(); + emit EVM2EVMOffRamp.TokenAggregateRateLimitAdded(adds[i].sourceToken, adds[i].destToken); + } + + s_offRamp.updateRateLimitTokens(removes, adds); + + for (uint256 i = 0; i < removes.length; ++i) { + vm.expectEmit(); + emit EVM2EVMOffRamp.TokenAggregateRateLimitRemoved(removes[i].sourceToken, removes[i].destToken); + } + + s_offRamp.updateRateLimitTokens(removes, new EVM2EVMOffRamp.RateLimitToken[](0)); + + (address[] memory sourceTokens, address[] memory destTokens) = s_offRamp.getAllRateLimitTokens(); + + assertEq(1, sourceTokens.length); + assertEq(adds[1].sourceToken, sourceTokens[0]); + + assertEq(1, destTokens.length); + assertEq(adds[1].destToken, destTokens[0]); + } + + function test_Fuzz_UpdateRateLimitTokens(uint8 numTokens) public { + // Needs to be more than 1 so that the division doesn't round down and the even makes the comparisons simpler + vm.assume(numTokens > 1 && numTokens % 2 == 0); + + // Clear the Rate limit tokens array so the test can start from a baseline + (address[] memory sourceTokens, address[] memory destTokens) = s_offRamp.getAllRateLimitTokens(); + EVM2EVMOffRamp.RateLimitToken[] memory removes = new EVM2EVMOffRamp.RateLimitToken[](sourceTokens.length); + for (uint256 x = 0; x < removes.length; x++) { + removes[x] = EVM2EVMOffRamp.RateLimitToken({sourceToken: sourceTokens[x], destToken: destTokens[x]}); + } + s_offRamp.updateRateLimitTokens(removes, new EVM2EVMOffRamp.RateLimitToken[](0)); + + // Sanity check that the rateLimitTokens were successfully cleared + (sourceTokens, destTokens) = s_offRamp.getAllRateLimitTokens(); + assertEq(sourceTokens.length, 0, "sourceTokenLength should be zero"); + + EVM2EVMOffRamp.RateLimitToken[] memory adds = new EVM2EVMOffRamp.RateLimitToken[](numTokens); + + for (uint256 x = 0; x < numTokens; x++) { + address tokenAddr = vm.addr(x + 1); + + // Create an array of several fake tokens to add which are deployed on the same address on both chains for simplicity + adds[x] = EVM2EVMOffRamp.RateLimitToken({sourceToken: tokenAddr, destToken: tokenAddr}); + } + + // Attempt to add the tokens to the RateLimitToken Array + s_offRamp.updateRateLimitTokens(new EVM2EVMOffRamp.RateLimitToken[](0), adds); + + // Retrieve them from storage and make sure that they all match the expected adds + (sourceTokens, destTokens) = s_offRamp.getAllRateLimitTokens(); + + for (uint256 x = 0; x < sourceTokens.length; x++) { + // Check that the tokens match the ones we generated earlier + assertEq(sourceTokens[x], adds[x].sourceToken, "Source token doesn't match add"); + assertEq(destTokens[x], adds[x].sourceToken, "dest Token doesn't match add"); + } + + // Attempt to remove half of the numTokens by removing the second half of the list and copying it to a removes array + removes = new EVM2EVMOffRamp.RateLimitToken[](adds.length / 2); + + for (uint256 x = 0; x < adds.length / 2; x++) { + removes[x] = adds[x + (adds.length / 2)]; + } + + // Attempt to update again, this time adding nothing and removing the second half of the tokens + s_offRamp.updateRateLimitTokens(removes, new EVM2EVMOffRamp.RateLimitToken[](0)); + + (sourceTokens, destTokens) = s_offRamp.getAllRateLimitTokens(); + assertEq(sourceTokens.length, adds.length / 2, "Current Rate limit token length is not half of the original adds"); + for (uint256 x = 0; x < sourceTokens.length; x++) { + // Check that the tokens match the ones we generated earlier and didn't remove in the previous step + assertEq(sourceTokens[x], adds[x].sourceToken, "Source token doesn't match add after removes"); + assertEq(destTokens[x], adds[x].destToken, "dest Token doesn't match add after removes"); + } + } + + // Reverts + + function test_updateRateLimitTokens_NonOwner_Revert() public { + EVM2EVMOffRamp.RateLimitToken[] memory addsAndRemoves = new EVM2EVMOffRamp.RateLimitToken[](4); + + vm.startPrank(STRANGER); + + vm.expectRevert("Only callable by owner"); + + s_offRamp.updateRateLimitTokens(addsAndRemoves, addsAndRemoves); + } +} diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol new file mode 100644 index 0000000000..053869b88a --- /dev/null +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IAny2EVMMessageReceiver} from "../../interfaces/IAny2EVMMessageReceiver.sol"; +import {ICommitStore} from "../../interfaces/ICommitStore.sol"; +import {IPoolV1} from "../../interfaces/IPool.sol"; + +import {Router} from "../../Router.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; +import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {TokenSetup} from "../TokenSetup.t.sol"; +import {EVM2EVMOffRampHelper} from "../helpers/EVM2EVMOffRampHelper.sol"; +import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; +import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; +import {MockCommitStore} from "../mocks/MockCommitStore.sol"; +import {OCR2BaseSetup} from "../ocr/OCR2Base.t.sol"; +import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { + MockCommitStore internal s_mockCommitStore; + IAny2EVMMessageReceiver internal s_receiver; + IAny2EVMMessageReceiver internal s_secondary_receiver; + MaybeRevertMessageReceiver internal s_reverting_receiver; + + MaybeRevertingBurnMintTokenPool internal s_maybeRevertingPool; + + EVM2EVMOffRampHelper internal s_offRamp; + address internal s_sourceTokenPool = makeAddr("sourceTokenPool"); + + function setUp() public virtual override(TokenSetup, PriceRegistrySetup, OCR2BaseSetup) { + TokenSetup.setUp(); + PriceRegistrySetup.setUp(); + OCR2BaseSetup.setUp(); + + s_mockCommitStore = new MockCommitStore(); + s_receiver = new MaybeRevertMessageReceiver(false); + s_secondary_receiver = new MaybeRevertMessageReceiver(false); + s_reverting_receiver = new MaybeRevertMessageReceiver(true); + + s_maybeRevertingPool = MaybeRevertingBurnMintTokenPool(s_destPoolByToken[s_destTokens[1]]); + + deployOffRamp(s_mockCommitStore, s_destRouter, address(0)); + } + + function deployOffRamp(ICommitStore commitStore, Router router, address prevOffRamp) internal { + s_offRamp = new EVM2EVMOffRampHelper( + EVM2EVMOffRamp.StaticConfig({ + commitStore: address(commitStore), + chainSelector: DEST_CHAIN_SELECTOR, + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + onRamp: ON_RAMP_ADDRESS, + prevOffRamp: prevOffRamp, + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }), + getInboundRateLimiterConfig() + ); + s_offRamp.setOCR2Config( + s_valid_signers, + s_valid_transmitters, + s_f, + abi.encode(generateDynamicOffRampConfig(address(router), address(s_priceRegistry))), + s_offchainConfigVersion, + abi.encode("") + ); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](0); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](2); + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: address(s_offRamp)}); + offRampUpdates[1] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: address(prevOffRamp)}); + s_destRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + EVM2EVMOffRamp.RateLimitToken[] memory tokensToAdd = new EVM2EVMOffRamp.RateLimitToken[](s_sourceTokens.length); + for (uint256 i = 0; i < s_sourceTokens.length; ++i) { + tokensToAdd[i] = EVM2EVMOffRamp.RateLimitToken({sourceToken: s_sourceTokens[i], destToken: s_destTokens[i]}); + } + s_offRamp.updateRateLimitTokens(new EVM2EVMOffRamp.RateLimitToken[](0), tokensToAdd); + } + + function generateDynamicOffRampConfig( + address router, + address priceRegistry + ) internal pure returns (EVM2EVMOffRamp.DynamicConfig memory) { + return EVM2EVMOffRamp.DynamicConfig({ + permissionLessExecutionThresholdSeconds: PERMISSION_LESS_EXECUTION_THRESHOLD_SECONDS, + router: router, + priceRegistry: priceRegistry, + maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, + maxDataBytes: MAX_DATA_SIZE, + maxPoolReleaseOrMintGas: MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS, + maxTokenTransferGas: MAX_TOKEN_POOL_TRANSFER_GAS + }); + } + + function _convertToGeneralMessage(Internal.EVM2EVMMessage memory original) + internal + view + returns (Client.Any2EVMMessage memory message) + { + uint256 numberOfTokens = original.tokenAmounts.length; + Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](numberOfTokens); + + for (uint256 i = 0; i < numberOfTokens; ++i) { + Internal.SourceTokenData memory sourceTokenData = + abi.decode(original.sourceTokenData[i], (Internal.SourceTokenData)); + + address destPoolAddress = abi.decode(sourceTokenData.destTokenAddress, (address)); + TokenPool pool = TokenPool(destPoolAddress); + destTokenAmounts[i].token = address(pool.getToken()); + destTokenAmounts[i].amount = original.tokenAmounts[i].amount; + } + + return Client.Any2EVMMessage({ + messageId: original.messageId, + sourceChainSelector: original.sourceChainSelector, + sender: abi.encode(original.sender), + data: original.data, + destTokenAmounts: destTokenAmounts + }); + } + + function _generateAny2EVMMessageNoTokens(uint64 sequenceNumber) + internal + view + returns (Internal.EVM2EVMMessage memory) + { + return _generateAny2EVMMessage(sequenceNumber, new Client.EVMTokenAmount[](0), false); + } + + function _generateAny2EVMMessageWithTokens( + uint64 sequenceNumber, + uint256[] memory amounts + ) internal view returns (Internal.EVM2EVMMessage memory) { + Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + for (uint256 i = 0; i < tokenAmounts.length; ++i) { + tokenAmounts[i].amount = amounts[i]; + } + return _generateAny2EVMMessage(sequenceNumber, tokenAmounts, false); + } + + function _generateAny2EVMMessage( + uint64 sequenceNumber, + Client.EVMTokenAmount[] memory tokenAmounts, + bool allowOutOfOrderExecution + ) internal view returns (Internal.EVM2EVMMessage memory) { + bytes memory data = abi.encode(0); + Internal.EVM2EVMMessage memory message = Internal.EVM2EVMMessage({ + sequenceNumber: sequenceNumber, + sender: OWNER, + nonce: allowOutOfOrderExecution ? 0 : sequenceNumber, + gasLimit: GAS_LIMIT, + strict: false, + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + receiver: address(s_receiver), + data: data, + tokenAmounts: tokenAmounts, + sourceTokenData: new bytes[](tokenAmounts.length), + feeToken: s_destFeeToken, + feeTokenAmount: uint256(0), + messageId: "" + }); + + // Correctly set the TokenDataPayload for each token. Tokens have to be set up in the TokenSetup. + for (uint256 i = 0; i < tokenAmounts.length; ++i) { + message.sourceTokenData[i] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[tokenAmounts[i].token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[tokenAmounts[i].token]), + extraData: "" + }) + ); + } + + message.messageId = Internal._hash( + message, + keccak256( + abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, SOURCE_CHAIN_SELECTOR, DEST_CHAIN_SELECTOR, ON_RAMP_ADDRESS) + ) + ); + + return message; + } + + function _generateSingleBasicMessage() internal view returns (Internal.EVM2EVMMessage[] memory) { + Internal.EVM2EVMMessage[] memory messages = new Internal.EVM2EVMMessage[](1); + messages[0] = _generateAny2EVMMessageNoTokens(1); + return messages; + } + + function _generateMessagesWithTokens() internal view returns (Internal.EVM2EVMMessage[] memory) { + Internal.EVM2EVMMessage[] memory messages = new Internal.EVM2EVMMessage[](2); + Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + tokenAmounts[0].amount = 1e18; + tokenAmounts[1].amount = 5e18; + messages[0] = _generateAny2EVMMessage(1, tokenAmounts, false); + messages[1] = _generateAny2EVMMessage(2, tokenAmounts, false); + + return messages; + } + + function _generateReportFromMessages(Internal.EVM2EVMMessage[] memory messages) + internal + pure + returns (Internal.ExecutionReport memory) + { + bytes[][] memory offchainTokenData = new bytes[][](messages.length); + + for (uint256 i = 0; i < messages.length; ++i) { + offchainTokenData[i] = new bytes[](messages[i].tokenAmounts.length); + } + + return Internal.ExecutionReport({ + proofs: new bytes32[](0), + proofFlagBits: 2 ** 256 - 1, + messages: messages, + offchainTokenData: offchainTokenData + }); + } + + function _getGasLimitsFromMessages(Internal.EVM2EVMMessage[] memory messages) + internal + pure + returns (uint256[] memory) + { + uint256[] memory gasLimits = new uint256[](messages.length); + for (uint256 i = 0; i < messages.length; ++i) { + gasLimits[i] = messages[i].gasLimit; + } + + return gasLimits; + } + + function _assertSameConfig(EVM2EVMOffRamp.DynamicConfig memory a, EVM2EVMOffRamp.DynamicConfig memory b) public pure { + assertEq(a.permissionLessExecutionThresholdSeconds, b.permissionLessExecutionThresholdSeconds); + assertEq(a.router, b.router); + assertEq(a.priceRegistry, b.priceRegistry); + assertEq(a.maxNumberOfTokensPerMsg, b.maxNumberOfTokensPerMsg); + assertEq(a.maxDataBytes, b.maxDataBytes); + assertEq(a.maxPoolReleaseOrMintGas, b.maxPoolReleaseOrMintGas); + assertEq(a.maxTokenTransferGas, b.maxTokenTransferGas); + } + + function _getDefaultSourceTokenData(Client.EVMTokenAmount[] memory srcTokenAmounts) + internal + view + returns (bytes[] memory) + { + bytes[] memory sourceTokenData = new bytes[](srcTokenAmounts.length); + for (uint256 i = 0; i < srcTokenAmounts.length; ++i) { + sourceTokenData[i] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[srcTokenAmounts[i].token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[srcTokenAmounts[i].token]), + extraData: "" + }) + ); + } + return sourceTokenData; + } +} diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol new file mode 100644 index 0000000000..bc7fac95be --- /dev/null +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol @@ -0,0 +1,720 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IMessageInterceptor} from "../../interfaces/IMessageInterceptor.sol"; +import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; + +import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; +import {MultiAggregateRateLimiter} from "../../MultiAggregateRateLimiter.sol"; +import {Pool} from "../../libraries/Pool.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {USDPriceWith18Decimals} from "../../libraries/USDPriceWith18Decimals.sol"; +import {EVM2EVMMultiOnRamp} from "../../onRamp/EVM2EVMMultiOnRamp.sol"; +import {EVM2EVMOnRamp} from "../../onRamp/EVM2EVMOnRamp.sol"; +import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; +import {EVM2EVMOnRampHelper} from "../helpers/EVM2EVMOnRampHelper.sol"; +import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; +import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; +import "./EVM2EVMMultiOnRampSetup.t.sol"; + +contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { + function test_Constructor_Success() public { + EVM2EVMMultiOnRamp.StaticConfig memory staticConfig = EVM2EVMMultiOnRamp.StaticConfig({ + chainSelector: SOURCE_CHAIN_SELECTOR, + rmnProxy: address(s_mockRMN), + nonceManager: address(s_outboundNonceManager), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }); + EVM2EVMMultiOnRamp.DynamicConfig memory dynamicConfig = + _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.ConfigSet(staticConfig, dynamicConfig); + + _deployOnRamp( + SOURCE_CHAIN_SELECTOR, address(s_sourceRouter), address(s_outboundNonceManager), address(s_tokenAdminRegistry) + ); + + EVM2EVMMultiOnRamp.StaticConfig memory gotStaticConfig = s_onRamp.getStaticConfig(); + _assertStaticConfigsEqual(staticConfig, gotStaticConfig); + + EVM2EVMMultiOnRamp.DynamicConfig memory gotDynamicConfig = s_onRamp.getDynamicConfig(); + _assertDynamicConfigsEqual(dynamicConfig, gotDynamicConfig); + + // Initial values + assertEq("EVM2EVMMultiOnRamp 1.6.0-dev", s_onRamp.typeAndVersion()); + assertEq(OWNER, s_onRamp.owner()); + assertEq(1, s_onRamp.getExpectedNextSequenceNumber(DEST_CHAIN_SELECTOR)); + } + + function test_Constructor_InvalidConfigChainSelectorEqZero_Revert() public { + vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); + new EVM2EVMMultiOnRampHelper( + EVM2EVMMultiOnRamp.StaticConfig({ + chainSelector: 0, + rmnProxy: address(s_mockRMN), + nonceManager: address(s_outboundNonceManager), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }), + _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)) + ); + } + + function test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() public { + vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); + s_onRamp = new EVM2EVMMultiOnRampHelper( + EVM2EVMMultiOnRamp.StaticConfig({ + chainSelector: SOURCE_CHAIN_SELECTOR, + rmnProxy: address(0), + nonceManager: address(s_outboundNonceManager), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }), + _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)) + ); + } + + function test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() public { + vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); + new EVM2EVMMultiOnRampHelper( + EVM2EVMMultiOnRamp.StaticConfig({ + chainSelector: SOURCE_CHAIN_SELECTOR, + rmnProxy: address(s_mockRMN), + nonceManager: address(0), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }), + _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)) + ); + } + + function test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() public { + vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); + new EVM2EVMMultiOnRampHelper( + EVM2EVMMultiOnRamp.StaticConfig({ + chainSelector: SOURCE_CHAIN_SELECTOR, + rmnProxy: address(s_mockRMN), + nonceManager: address(s_outboundNonceManager), + tokenAdminRegistry: address(0) + }), + _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)) + ); + } +} + +contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { + struct LegacyExtraArgs { + uint256 gasLimit; + bool strict; + } + + function setUp() public virtual override { + super.setUp(); + + address[] memory feeTokens = new address[](1); + feeTokens[0] = s_sourceTokens[1]; + s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + + // Since we'll mostly be testing for valid calls from the router we'll + // mock all calls to be originating from the router and re-mock in + // tests that require failure. + vm.startPrank(address(s_sourceRouter)); + } + + function test_ForwardFromRouterSuccessCustomExtraArgs() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT * 2})); + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + function test_ForwardFromRouterSuccessLegacyExtraArgs() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = + abi.encodeWithSelector(Client.EVM_EXTRA_ARGS_V1_TAG, LegacyExtraArgs({gasLimit: GAS_LIMIT * 2, strict: true})); + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectEmit(); + // We expect the message to be emitted with strict = false. + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + function test_ForwardFromRouterSuccessEmptyExtraArgs() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = ""; + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectEmit(); + // We expect the message to be emitted with strict = false. + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + function test_ForwardFromRouter_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + function test_ForwardFromRouterExtraArgsV2_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = abi.encodeWithSelector( + Client.EVM_EXTRA_ARGS_V2_TAG, Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT * 2, allowOutOfOrderExecution: false}) + ); + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + function test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = abi.encodeWithSelector( + Client.EVM_EXTRA_ARGS_V2_TAG, Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT * 2, allowOutOfOrderExecution: true}) + ); + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + function test_ShouldIncrementSeqNumAndNonce_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + for (uint64 i = 1; i < 4; ++i) { + uint64 nonceBefore = s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); + uint64 sequenceNumberBefore = s_onRamp.getExpectedNextSequenceNumber(DEST_CHAIN_SELECTOR) - 1; + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, i, i, 0, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + uint64 nonceAfter = s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); + uint64 sequenceNumberAfter = s_onRamp.getExpectedNextSequenceNumber(DEST_CHAIN_SELECTOR) - 1; + assertEq(nonceAfter, nonceBefore + 1); + assertEq(sequenceNumberAfter, sequenceNumberBefore + 1); + } + } + + function test_ShouldIncrementNonceOnlyOnOrdered_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = abi.encodeWithSelector( + Client.EVM_EXTRA_ARGS_V2_TAG, Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT * 2, allowOutOfOrderExecution: true}) + ); + + for (uint64 i = 1; i < 4; ++i) { + uint64 nonceBefore = s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); + uint64 sequenceNumberBefore = s_onRamp.getExpectedNextSequenceNumber(DEST_CHAIN_SELECTOR) - 1; + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, i, i, 0, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + uint64 nonceAfter = s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); + uint64 sequenceNumberAfter = s_onRamp.getExpectedNextSequenceNumber(DEST_CHAIN_SELECTOR) - 1; + assertEq(nonceAfter, nonceBefore); + assertEq(sequenceNumberAfter, sequenceNumberBefore + 1); + } + } + + function test_ShouldStoreLinkFees() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.FeePaid(s_sourceFeeToken, feeAmount); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + + assertEq(IERC20(s_sourceFeeToken).balanceOf(address(s_onRamp)), feeAmount); + } + + function test_ShouldStoreNonLinkFees() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = s_sourceTokens[1]; + + uint256 feeAmount = 1234567890; + IERC20(s_sourceTokens[1]).transferFrom(OWNER, address(s_onRamp), feeAmount); + + // Calculate conversion done by prices contract + uint256 feeTokenPrice = s_priceRegistry.getTokenPrice(s_sourceTokens[1]).value; + uint256 linkTokenPrice = s_priceRegistry.getTokenPrice(s_sourceFeeToken).value; + uint256 conversionRate = (feeTokenPrice * 1e18) / linkTokenPrice; + uint256 expectedJuels = (feeAmount * conversionRate) / 1e18; + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.FeePaid(s_sourceTokens[1], expectedJuels); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + + assertEq(IERC20(s_sourceTokens[1]).balanceOf(address(s_onRamp)), feeAmount); + } + + // Make sure any valid sender, receiver and feeAmount can be handled. + // @TODO Temporarily setting lower fuzz run as 256 triggers snapshot gas off by 1 error. + // https://github.com/foundry-rs/foundry/issues/5689 + /// forge-dynamicConfig: default.fuzz.runs = 32 + /// forge-dynamicConfig: ccip.fuzz.runs = 32 + function test_Fuzz_ForwardFromRouter_Success(address originalSender, address receiver, uint96 feeTokenAmount) public { + // To avoid RouterMustSetOriginalSender + vm.assume(originalSender != address(0)); + vm.assume(uint160(receiver) >= Internal.PRECOMPILE_SPACE); + feeTokenAmount = uint96(bound(feeTokenAmount, 0, MAX_MSG_FEES_JUELS)); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.receiver = abi.encode(receiver); + + // Make sure the tokens are in the contract + deal(s_sourceFeeToken, address(s_onRamp), feeTokenAmount); + + Internal.EVM2AnyRampMessage memory expectedEvent = _messageToEvent(message, 1, 1, feeTokenAmount, originalSender); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.FeePaid(s_sourceFeeToken, feeTokenAmount); + vm.expectEmit(false, false, false, true); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, expectedEvent); + + // Assert the message Id is correct + assertEq( + expectedEvent.header.messageId, + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeTokenAmount, originalSender) + ); + } + + function test_forwardFromRouter_WithValidation_Success() public { + _enableOutboundMessageValidator(); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT * 2})); + uint256 feeAmount = 1234567890; + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].amount = 1e18; + message.tokenAmounts[0].token = s_sourceTokens[0]; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + s_outboundMessageValidator.setMessageIdValidationState(keccak256(abi.encode(message)), false); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + // Reverts + + function test_Paused_Revert() public { + // We pause by disabling the whitelist + vm.stopPrank(); + vm.startPrank(OWNER); + address router = address(0); + s_onRamp.setDynamicConfig(_generateDynamicMultiOnRampConfig(router, address(2))); + vm.expectRevert(EVM2EVMMultiOnRamp.MustBeCalledByRouter.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, OWNER); + } + + function test_InvalidExtraArgsTag_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = bytes("bad args"); + + vm.expectRevert(EVM2EVMMultiOnRamp.InvalidExtraArgsTag.selector); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + } + + function test_Permissions_Revert() public { + vm.stopPrank(); + vm.startPrank(OWNER); + vm.expectRevert(EVM2EVMMultiOnRamp.MustBeCalledByRouter.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, OWNER); + } + + function test_OriginalSender_Revert() public { + vm.expectRevert(EVM2EVMMultiOnRamp.RouterMustSetOriginalSender.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, address(0)); + } + + function test_MessageValidationError_Revert() public { + _enableOutboundMessageValidator(); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT * 2})); + uint256 feeAmount = 1234567890; + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].amount = 1e18; + message.tokenAmounts[0].token = s_sourceTokens[0]; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + s_outboundMessageValidator.setMessageIdValidationState(keccak256(abi.encode(message)), true); + + vm.expectRevert( + abi.encodeWithSelector(IMessageInterceptor.MessageValidationError.selector, bytes("Invalid message")) + ); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + function test_CannotSendZeroTokens_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].amount = 0; + message.tokenAmounts[0].token = s_sourceTokens[0]; + vm.expectRevert(EVM2EVMMultiOnRamp.CannotSendZeroTokens.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, STRANGER); + } + + function test_UnsupportedToken_Revert() public { + address wrongToken = address(1); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].token = wrongToken; + message.tokenAmounts[0].amount = 1; + + // We need to set the price of this new token to be able to reach + // the proper revert point. This must be called by the owner. + vm.stopPrank(); + vm.startPrank(OWNER); + + Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(wrongToken, 1); + s_priceRegistry.updatePrices(priceUpdates); + + // Change back to the router + vm.startPrank(address(s_sourceRouter)); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOnRamp.UnsupportedToken.selector, wrongToken)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + } + + function test_forwardFromRouter_UnsupportedToken_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].amount = 1; + message.tokenAmounts[0].token = address(1); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOnRamp.UnsupportedToken.selector, message.tokenAmounts[0].token)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + } + + function test_MesssageFeeTooHigh_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + vm.expectRevert( + abi.encodeWithSelector(PriceRegistry.MessageFeeTooHigh.selector, MAX_MSG_FEES_JUELS + 1, MAX_MSG_FEES_JUELS) + ); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, MAX_MSG_FEES_JUELS + 1, OWNER); + } + + function test_SourceTokenDataTooLarge_Revert() public { + address sourceETH = s_sourceTokens[1]; + vm.stopPrank(); + vm.startPrank(OWNER); + + MaybeRevertingBurnMintTokenPool newPool = new MaybeRevertingBurnMintTokenPool( + BurnMintERC677(sourceETH), new address[](0), address(s_mockRMN), address(s_sourceRouter) + ); + BurnMintERC677(sourceETH).grantMintAndBurnRoles(address(newPool)); + deal(address(sourceETH), address(newPool), type(uint256).max); + + // Add TokenPool to OnRamp + s_tokenAdminRegistry.setPool(sourceETH, address(newPool)); + + // Allow chain in TokenPool + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(s_destTokenPool), + remoteTokenAddress: abi.encode(s_destToken), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + newPool.applyChainUpdates(chainUpdates); + + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(address(sourceETH), 1000); + + // No data set, should succeed + vm.startPrank(address(s_sourceRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + // Set max data length, should succeed + vm.startPrank(OWNER); + newPool.setSourceTokenData(new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES)); + + vm.startPrank(address(s_sourceRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + // Set data to max length +1, should revert + vm.startPrank(OWNER); + newPool.setSourceTokenData(new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + 1)); + + vm.startPrank(address(s_sourceRouter)); + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.SourceTokenDataTooLarge.selector, sourceETH)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + // Set token config to allow larger data + vm.startPrank(OWNER); + PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + _generateTokenTransferFeeConfigArgs(1, 1); + tokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token = sourceETH; + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = PriceRegistry + .TokenTransferFeeConfig({ + minFeeUSDCents: 1, + maxFeeUSDCents: 0, + deciBps: 0, + destGasOverhead: 0, + destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) + 32, + isEnabled: true + }); + s_priceRegistry.applyTokenTransferFeeConfigUpdates( + tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + ); + + vm.startPrank(address(s_sourceRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + // Set the token data larger than the configured token data, should revert + vm.startPrank(OWNER); + newPool.setSourceTokenData(new bytes(uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) + 32 + 1)); + + vm.startPrank(address(s_sourceRouter)); + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.SourceTokenDataTooLarge.selector, sourceETH)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + } +} + +contract EVM2EVMMultiOnRamp_getSupportedTokens is EVM2EVMMultiOnRampSetup { + function test_GetSupportedTokens_Revert() public { + vm.expectRevert(EVM2EVMMultiOnRamp.GetSupportedTokensFunctionalityRemovedCheckAdminRegistry.selector); + s_onRamp.getSupportedTokens(DEST_CHAIN_SELECTOR); + } +} + +contract EVM2EVMMultiOnRamp_getFee is EVM2EVMMultiOnRampSetup { + using USDPriceWith18Decimals for uint224; + + function test_EmptyMessage_Success() public view { + address[2] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative()]; + uint224[2] memory feeTokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice]; + + for (uint256 i = 0; i < feeTokenPrices.length; ++i) { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = testTokens[i]; + + uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + uint256 expectedFeeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + + assertEq(expectedFeeAmount, feeAmount); + } + } + + function test_SingleTokenMessage_Success() public view { + address[2] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative()]; + uint224[2] memory feeTokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice]; + + uint256 tokenAmount = 10000e18; + for (uint256 i = 0; i < feeTokenPrices.length; ++i) { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, tokenAmount); + message.feeToken = testTokens[i]; + + uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + uint256 expectedFeeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + + assertEq(expectedFeeAmount, feeAmount); + } + } + + // Reverts + + function test_Unhealthy_Revert() public { + s_mockRMN.setGlobalCursed(true); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOnRamp.CursedByRMN.selector, DEST_CHAIN_SELECTOR)); + s_onRamp.getFee(DEST_CHAIN_SELECTOR, _generateEmptyMessage()); + } + + function test_EnforceOutOfOrder_Revert() public { + // Update dynamic config to enforce allowOutOfOrderExecution = true. + vm.stopPrank(); + vm.startPrank(OWNER); + + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + destChainConfigArgs[0].destChainConfig.enforceOutOfOrder = true; + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + vm.stopPrank(); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + // Empty extraArgs to should revert since it enforceOutOfOrder is true. + message.extraArgs = ""; + + vm.expectRevert(PriceRegistry.ExtraArgOutOfOrderExecutionMustBeTrue.selector); + s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + } +} + +contract EVM2EVMMultiOnRamp_setDynamicConfig is EVM2EVMMultiOnRampSetup { + function test_SetDynamicConfig_Success() public { + EVM2EVMMultiOnRamp.StaticConfig memory staticConfig = s_onRamp.getStaticConfig(); + EVM2EVMMultiOnRamp.DynamicConfig memory newConfig = EVM2EVMMultiOnRamp.DynamicConfig({ + router: address(2134), + priceRegistry: address(23423), + messageValidator: makeAddr("messageValidator"), + feeAggregator: FEE_AGGREGATOR + }); + + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.ConfigSet(staticConfig, newConfig); + + s_onRamp.setDynamicConfig(newConfig); + + EVM2EVMMultiOnRamp.DynamicConfig memory gotDynamicConfig = s_onRamp.getDynamicConfig(); + assertEq(newConfig.router, gotDynamicConfig.router); + assertEq(newConfig.priceRegistry, gotDynamicConfig.priceRegistry); + } + + // Reverts + + function test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() public { + EVM2EVMMultiOnRamp.DynamicConfig memory newConfig = EVM2EVMMultiOnRamp.DynamicConfig({ + router: address(2134), + priceRegistry: address(0), + feeAggregator: FEE_AGGREGATOR, + messageValidator: makeAddr("messageValidator") + }); + + vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); + s_onRamp.setDynamicConfig(newConfig); + } + + function test_SetConfigInvalidConfig_Revert() public { + EVM2EVMMultiOnRamp.DynamicConfig memory newConfig = EVM2EVMMultiOnRamp.DynamicConfig({ + router: address(1), + priceRegistry: address(23423), + messageValidator: address(0), + feeAggregator: FEE_AGGREGATOR + }); + + // Invalid price reg reverts. + newConfig.priceRegistry = address(0); + vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); + s_onRamp.setDynamicConfig(newConfig); + } + + function test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() public { + EVM2EVMMultiOnRamp.DynamicConfig memory newConfig = EVM2EVMMultiOnRamp.DynamicConfig({ + router: address(2134), + priceRegistry: address(23423), + messageValidator: address(0), + feeAggregator: address(0) + }); + vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); + s_onRamp.setDynamicConfig(newConfig); + } + + function test_SetConfigOnlyOwner_Revert() public { + vm.startPrank(STRANGER); + vm.expectRevert("Only callable by owner"); + s_onRamp.setDynamicConfig(_generateDynamicMultiOnRampConfig(address(1), address(2))); + vm.startPrank(ADMIN); + vm.expectRevert("Only callable by owner"); + s_onRamp.setDynamicConfig(_generateDynamicMultiOnRampConfig(address(1), address(2))); + } +} + +contract EVM2EVMMultiOnRamp_withdrawFeeTokens is EVM2EVMMultiOnRampSetup { + mapping(address => uint256) internal s_nopFees; + + function setUp() public virtual override { + super.setUp(); + + // Since we'll mostly be testing for valid calls from the router we'll + // mock all calls to be originating from the router and re-mock in + // tests that require failure. + vm.startPrank(address(s_sourceRouter)); + + uint256 feeAmount = 1234567890; + + // Send a bunch of messages, increasing the juels in the contract + for (uint256 i = 0; i < s_sourceFeeTokens.length; ++i) { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = s_sourceFeeTokens[i % s_sourceFeeTokens.length]; + uint256 newFeeTokenBalance = IERC20(message.feeToken).balanceOf(address(s_onRamp)) + feeAmount; + deal(message.feeToken, address(s_onRamp), newFeeTokenBalance); + s_nopFees[message.feeToken] = newFeeTokenBalance; + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + } + + function test_Fuzz_WithdrawFeeTokens_Success(uint256[5] memory amounts) public { + vm.startPrank(OWNER); + address[] memory feeTokens = new address[](amounts.length); + for (uint256 i = 0; i < amounts.length; ++i) { + vm.assume(amounts[i] > 0); + feeTokens[i] = _deploySourceToken("", amounts[i], 18); + IERC20(feeTokens[i]).transfer(address(s_onRamp), amounts[i]); + } + + s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + + for (uint256 i = 0; i < feeTokens.length; ++i) { + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.FeeTokenWithdrawn(FEE_AGGREGATOR, feeTokens[i], amounts[i]); + } + + s_onRamp.withdrawFeeTokens(); + + for (uint256 i = 0; i < feeTokens.length; ++i) { + assertEq(IERC20(feeTokens[i]).balanceOf(FEE_AGGREGATOR), amounts[i]); + assertEq(IERC20(feeTokens[i]).balanceOf(address(s_onRamp)), 0); + } + } + + function test_WithdrawFeeTokens_Success() public { + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.FeeTokenWithdrawn(FEE_AGGREGATOR, s_sourceFeeToken, s_nopFees[s_sourceFeeToken]); + + s_onRamp.withdrawFeeTokens(); + + assertEq(IERC20(s_sourceFeeToken).balanceOf(FEE_AGGREGATOR), s_nopFees[s_sourceFeeToken]); + assertEq(IERC20(s_sourceFeeToken).balanceOf(address(s_onRamp)), 0); + } +} + +contract EVM2EVMMultiOnRamp_getTokenPool is EVM2EVMMultiOnRampSetup { + function test_GetTokenPool_Success() public view { + assertEq( + s_sourcePoolByToken[s_sourceTokens[0]], + address(s_onRamp.getPoolBySourceToken(DEST_CHAIN_SELECTOR, IERC20(s_sourceTokens[0]))) + ); + assertEq( + s_sourcePoolByToken[s_sourceTokens[1]], + address(s_onRamp.getPoolBySourceToken(DEST_CHAIN_SELECTOR, IERC20(s_sourceTokens[1]))) + ); + + address wrongToken = address(123); + address nonExistentPool = address(s_onRamp.getPoolBySourceToken(DEST_CHAIN_SELECTOR, IERC20(wrongToken))); + + assertEq(address(0), nonExistentPool); + } +} diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol new file mode 100644 index 0000000000..f085185753 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IPoolV1} from "../../interfaces/IPool.sol"; + +import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; +import {NonceManager} from "../../NonceManager.sol"; +import {PriceRegistry} from "../../PriceRegistry.sol"; +import {Router} from "../../Router.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {EVM2EVMMultiOnRamp} from "../../onRamp/EVM2EVMMultiOnRamp.sol"; +import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; +import {TokenSetup} from "../TokenSetup.t.sol"; +import {EVM2EVMMultiOnRampHelper} from "../helpers/EVM2EVMMultiOnRampHelper.sol"; +import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; +import {PriceRegistryFeeSetup} from "../priceRegistry/PriceRegistry.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistryFeeSetup { + uint256 internal immutable i_tokenAmount0 = 9; + uint256 internal immutable i_tokenAmount1 = 7; + + bytes32 internal s_metadataHash; + + EVM2EVMMultiOnRampHelper internal s_onRamp; + MessageInterceptorHelper internal s_outboundMessageValidator; + address[] internal s_offRamps; + NonceManager internal s_outboundNonceManager; + + function setUp() public virtual override(TokenSetup, PriceRegistryFeeSetup) { + TokenSetup.setUp(); + PriceRegistryFeeSetup.setUp(); + + s_outboundMessageValidator = new MessageInterceptorHelper(); + s_outboundNonceManager = new NonceManager(new address[](0)); + (s_onRamp, s_metadataHash) = _deployOnRamp( + SOURCE_CHAIN_SELECTOR, address(s_sourceRouter), address(s_outboundNonceManager), address(s_tokenAdminRegistry) + ); + + s_offRamps = new address[](2); + s_offRamps[0] = address(10); + s_offRamps[1] = address(11); + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](2); + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: address(s_onRamp)}); + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: s_offRamps[0]}); + offRampUpdates[1] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: s_offRamps[1]}); + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + + // Pre approve the first token so the gas estimates of the tests + // only cover actual gas usage from the ramps + IERC20(s_sourceTokens[0]).approve(address(s_sourceRouter), 2 ** 128); + IERC20(s_sourceTokens[1]).approve(address(s_sourceRouter), 2 ** 128); + } + + function _generateTokenMessage() public view returns (Client.EVM2AnyMessage memory) { + Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + tokenAmounts[0].amount = i_tokenAmount0; + tokenAmounts[1].amount = i_tokenAmount1; + return Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + } + + function _messageToEvent( + Client.EVM2AnyMessage memory message, + uint64 seqNum, + uint64 nonce, + uint256 feeTokenAmount, + address originalSender + ) public view returns (Internal.EVM2AnyRampMessage memory) { + return _messageToEvent( + message, + SOURCE_CHAIN_SELECTOR, + DEST_CHAIN_SELECTOR, + seqNum, + nonce, + feeTokenAmount, + originalSender, + s_metadataHash, + s_tokenAdminRegistry + ); + } + + function _generateDynamicMultiOnRampConfig( + address router, + address priceRegistry + ) internal pure returns (EVM2EVMMultiOnRamp.DynamicConfig memory) { + return EVM2EVMMultiOnRamp.DynamicConfig({ + router: router, + priceRegistry: priceRegistry, + messageValidator: address(0), + feeAggregator: FEE_AGGREGATOR + }); + } + + // Slicing is only available for calldata. So we have to build a new bytes array. + function _removeFirst4Bytes(bytes memory data) internal pure returns (bytes memory) { + bytes memory result = new bytes(data.length - 4); + for (uint256 i = 4; i < data.length; ++i) { + result[i - 4] = data[i]; + } + return result; + } + + function _deployOnRamp( + uint64 sourceChainSelector, + address sourceRouter, + address nonceManager, + address tokenAdminRegistry + ) internal returns (EVM2EVMMultiOnRampHelper, bytes32 metadataHash) { + EVM2EVMMultiOnRampHelper onRamp = new EVM2EVMMultiOnRampHelper( + EVM2EVMMultiOnRamp.StaticConfig({ + chainSelector: sourceChainSelector, + rmnProxy: address(s_mockRMN), + nonceManager: nonceManager, + tokenAdminRegistry: tokenAdminRegistry + }), + _generateDynamicMultiOnRampConfig(sourceRouter, address(s_priceRegistry)) + ); + + address[] memory authorizedCallers = new address[](1); + authorizedCallers[0] = address(onRamp); + + NonceManager(nonceManager).applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: authorizedCallers, removedCallers: new address[](0)}) + ); + + return ( + onRamp, + keccak256(abi.encode(Internal.EVM_2_ANY_MESSAGE_HASH, sourceChainSelector, DEST_CHAIN_SELECTOR, address(onRamp))) + ); + } + + function _enableOutboundMessageValidator() internal { + (, address msgSender,) = vm.readCallers(); + + bool resetPrank = false; + + if (msgSender != OWNER) { + vm.stopPrank(); + vm.startPrank(OWNER); + resetPrank = true; + } + + EVM2EVMMultiOnRamp.DynamicConfig memory dynamicConfig = s_onRamp.getDynamicConfig(); + dynamicConfig.messageValidator = address(s_outboundMessageValidator); + s_onRamp.setDynamicConfig(dynamicConfig); + + if (resetPrank) { + vm.stopPrank(); + vm.startPrank(msgSender); + } + } + + function _assertStaticConfigsEqual( + EVM2EVMMultiOnRamp.StaticConfig memory a, + EVM2EVMMultiOnRamp.StaticConfig memory b + ) internal pure { + assertEq(a.chainSelector, b.chainSelector); + assertEq(a.rmnProxy, b.rmnProxy); + assertEq(a.tokenAdminRegistry, b.tokenAdminRegistry); + } + + function _assertDynamicConfigsEqual( + EVM2EVMMultiOnRamp.DynamicConfig memory a, + EVM2EVMMultiOnRamp.DynamicConfig memory b + ) internal pure { + assertEq(a.router, b.router); + assertEq(a.priceRegistry, b.priceRegistry); + } +} diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol new file mode 100644 index 0000000000..197a87b708 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol @@ -0,0 +1,1986 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; + +import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; +import {AggregateRateLimiter} from "../../AggregateRateLimiter.sol"; +import {Pool} from "../../libraries/Pool.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {USDPriceWith18Decimals} from "../../libraries/USDPriceWith18Decimals.sol"; +import {EVM2EVMOnRamp} from "../../onRamp/EVM2EVMOnRamp.sol"; +import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; +import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; +import "./EVM2EVMOnRampSetup.t.sol"; + +contract EVM2EVMOnRamp_constructor is EVM2EVMOnRampSetup { + function test_Constructor_Success() public { + EVM2EVMOnRamp.StaticConfig memory staticConfig = EVM2EVMOnRamp.StaticConfig({ + linkToken: s_sourceTokens[0], + chainSelector: SOURCE_CHAIN_SELECTOR, + destChainSelector: DEST_CHAIN_SELECTOR, + defaultTxGasLimit: GAS_LIMIT, + maxNopFeesJuels: MAX_NOP_FEES_JUELS, + prevOnRamp: address(0), + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }); + EVM2EVMOnRamp.DynamicConfig memory dynamicConfig = + generateDynamicOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)); + + vm.expectEmit(); + emit EVM2EVMOnRamp.ConfigSet(staticConfig, dynamicConfig); + + s_onRamp = new EVM2EVMOnRampHelper( + staticConfig, + dynamicConfig, + getOutboundRateLimiterConfig(), + s_feeTokenConfigArgs, + s_tokenTransferFeeConfigArgs, + getNopsAndWeights() + ); + + EVM2EVMOnRamp.StaticConfig memory gotStaticConfig = s_onRamp.getStaticConfig(); + assertEq(staticConfig.linkToken, gotStaticConfig.linkToken); + assertEq(staticConfig.chainSelector, gotStaticConfig.chainSelector); + assertEq(staticConfig.destChainSelector, gotStaticConfig.destChainSelector); + assertEq(staticConfig.defaultTxGasLimit, gotStaticConfig.defaultTxGasLimit); + assertEq(staticConfig.maxNopFeesJuels, gotStaticConfig.maxNopFeesJuels); + assertEq(staticConfig.prevOnRamp, gotStaticConfig.prevOnRamp); + assertEq(staticConfig.rmnProxy, gotStaticConfig.rmnProxy); + + EVM2EVMOnRamp.DynamicConfig memory gotDynamicConfig = s_onRamp.getDynamicConfig(); + assertEq(dynamicConfig.router, gotDynamicConfig.router); + assertEq(dynamicConfig.maxNumberOfTokensPerMsg, gotDynamicConfig.maxNumberOfTokensPerMsg); + assertEq(dynamicConfig.destGasOverhead, gotDynamicConfig.destGasOverhead); + assertEq(dynamicConfig.destGasPerPayloadByte, gotDynamicConfig.destGasPerPayloadByte); + assertEq(dynamicConfig.priceRegistry, gotDynamicConfig.priceRegistry); + assertEq(dynamicConfig.maxDataBytes, gotDynamicConfig.maxDataBytes); + assertEq(dynamicConfig.maxPerMsgGasLimit, gotDynamicConfig.maxPerMsgGasLimit); + + // Initial values + assertEq("EVM2EVMOnRamp 1.5.0-dev", s_onRamp.typeAndVersion()); + assertEq(OWNER, s_onRamp.owner()); + assertEq(1, s_onRamp.getExpectedNextSequenceNumber()); + } +} + +contract EVM2EVMOnRamp_payNops_fuzz is EVM2EVMOnRampSetup { + function test_Fuzz_NopPayNops_Success(uint96 nopFeesJuels) public { + (EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights, uint256 weightsTotal) = s_onRamp.getNops(); + // To avoid NoFeesToPay + vm.assume(nopFeesJuels > weightsTotal); + vm.assume(nopFeesJuels < MAX_NOP_FEES_JUELS); + + // Set Nop fee juels + deal(s_sourceFeeToken, address(s_onRamp), nopFeesJuels); + vm.startPrank(address(s_sourceRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), nopFeesJuels, OWNER); + + vm.startPrank(OWNER); + + uint256 totalJuels = s_onRamp.getNopFeesJuels(); + s_onRamp.payNops(); + for (uint256 i = 0; i < nopsAndWeights.length; ++i) { + uint256 expectedPayout = (totalJuels * nopsAndWeights[i].weight) / weightsTotal; + assertEq(IERC20(s_sourceFeeToken).balanceOf(nopsAndWeights[i].nop), expectedPayout); + } + } +} + +contract EVM2EVMNopsFeeSetup is EVM2EVMOnRampSetup { + function setUp() public virtual override { + EVM2EVMOnRampSetup.setUp(); + + // Since we'll mostly be testing for valid calls from the router we'll + // mock all calls to be originating from the router and re-mock in + // tests that require failure. + vm.startPrank(address(s_sourceRouter)); + + uint256 feeAmount = 1234567890; + uint256 numberOfMessages = 5; + + // Send a bunch of messages, increasing the juels in the contract + for (uint256 i = 0; i < numberOfMessages; ++i) { + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), feeAmount, OWNER); + } + + assertEq(s_onRamp.getNopFeesJuels(), feeAmount * numberOfMessages); + assertEq(IERC20(s_sourceFeeToken).balanceOf(address(s_onRamp)), feeAmount * numberOfMessages); + } +} + +contract EVM2EVMOnRamp_payNops is EVM2EVMNopsFeeSetup { + function test_OwnerPayNops_Success() public { + vm.startPrank(OWNER); + + uint256 totalJuels = s_onRamp.getNopFeesJuels(); + s_onRamp.payNops(); + (EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights, uint256 weightsTotal) = s_onRamp.getNops(); + for (uint256 i = 0; i < nopsAndWeights.length; ++i) { + uint256 expectedPayout = (nopsAndWeights[i].weight * totalJuels) / weightsTotal; + assertEq(IERC20(s_sourceFeeToken).balanceOf(nopsAndWeights[i].nop), expectedPayout); + } + } + + function test_AdminPayNops_Success() public { + vm.startPrank(ADMIN); + + uint256 totalJuels = s_onRamp.getNopFeesJuels(); + s_onRamp.payNops(); + (EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights, uint256 weightsTotal) = s_onRamp.getNops(); + for (uint256 i = 0; i < nopsAndWeights.length; ++i) { + uint256 expectedPayout = (nopsAndWeights[i].weight * totalJuels) / weightsTotal; + assertEq(IERC20(s_sourceFeeToken).balanceOf(nopsAndWeights[i].nop), expectedPayout); + } + } + + function test_NopPayNops_Success() public { + vm.startPrank(getNopsAndWeights()[0].nop); + + uint256 totalJuels = s_onRamp.getNopFeesJuels(); + s_onRamp.payNops(); + (EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights, uint256 weightsTotal) = s_onRamp.getNops(); + for (uint256 i = 0; i < nopsAndWeights.length; ++i) { + uint256 expectedPayout = (nopsAndWeights[i].weight * totalJuels) / weightsTotal; + assertEq(IERC20(s_sourceFeeToken).balanceOf(nopsAndWeights[i].nop), expectedPayout); + } + } + + function test_PayNopsSuccessAfterSetNops() public { + vm.startPrank(OWNER); + + // set 2 nops, 1 from previous, 1 new + address prevNop = getNopsAndWeights()[0].nop; + address newNop = STRANGER; + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = new EVM2EVMOnRamp.NopAndWeight[](2); + nopsAndWeights[0] = EVM2EVMOnRamp.NopAndWeight({nop: prevNop, weight: 1}); + nopsAndWeights[1] = EVM2EVMOnRamp.NopAndWeight({nop: newNop, weight: 1}); + s_onRamp.setNops(nopsAndWeights); + + // refill OnRamp nops fees + vm.startPrank(address(s_sourceRouter)); + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), feeAmount, OWNER); + + vm.startPrank(newNop); + uint256 prevNopBalance = IERC20(s_sourceFeeToken).balanceOf(prevNop); + uint256 totalJuels = s_onRamp.getNopFeesJuels(); + + s_onRamp.payNops(); + + assertEq(totalJuels / 2 + prevNopBalance, IERC20(s_sourceFeeToken).balanceOf(prevNop)); + assertEq(totalJuels / 2, IERC20(s_sourceFeeToken).balanceOf(newNop)); + } + + // Reverts + + function test_InsufficientBalance_Revert() public { + vm.startPrank(address(s_onRamp)); + IERC20(s_sourceFeeToken).transfer(OWNER, IERC20(s_sourceFeeToken).balanceOf(address(s_onRamp))); + vm.startPrank(OWNER); + vm.expectRevert(EVM2EVMOnRamp.InsufficientBalance.selector); + s_onRamp.payNops(); + } + + function test_WrongPermissions_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert(EVM2EVMOnRamp.OnlyCallableByOwnerOrAdminOrNop.selector); + s_onRamp.payNops(); + } + + function test_NoFeesToPay_Revert() public { + vm.startPrank(OWNER); + s_onRamp.payNops(); + vm.expectRevert(EVM2EVMOnRamp.NoFeesToPay.selector); + s_onRamp.payNops(); + } + + function test_NoNopsToPay_Revert() public { + vm.startPrank(OWNER); + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = new EVM2EVMOnRamp.NopAndWeight[](0); + s_onRamp.setNops(nopsAndWeights); + vm.expectRevert(EVM2EVMOnRamp.NoNopsToPay.selector); + s_onRamp.payNops(); + } +} + +contract EVM2EVMOnRamp_linkAvailableForPayment is EVM2EVMNopsFeeSetup { + function test_LinkAvailableForPayment_Success() public { + uint256 totalJuels = s_onRamp.getNopFeesJuels(); + uint256 linkBalance = IERC20(s_sourceFeeToken).balanceOf(address(s_onRamp)); + + assertEq(int256(linkBalance - totalJuels), s_onRamp.linkAvailableForPayment()); + + vm.startPrank(OWNER); + s_onRamp.payNops(); + + assertEq(int256(linkBalance - totalJuels), s_onRamp.linkAvailableForPayment()); + } + + function test_InsufficientLinkBalance_Success() public { + uint256 totalJuels = s_onRamp.getNopFeesJuels(); + uint256 linkBalance = IERC20(s_sourceFeeToken).balanceOf(address(s_onRamp)); + + vm.startPrank(address(s_onRamp)); + + uint256 linkRemaining = 1; + IERC20(s_sourceFeeToken).transfer(OWNER, linkBalance - linkRemaining); + + vm.startPrank(STRANGER); + assertEq(int256(linkRemaining) - int256(totalJuels), s_onRamp.linkAvailableForPayment()); + } +} + +contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { + struct LegacyExtraArgs { + uint256 gasLimit; + bool strict; + } + + function setUp() public virtual override { + EVM2EVMOnRampSetup.setUp(); + + address[] memory feeTokens = new address[](1); + feeTokens[0] = s_sourceTokens[1]; + s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + + // Since we'll mostly be testing for valid calls from the router we'll + // mock all calls to be originating from the router and re-mock in + // tests that require failure. + vm.startPrank(address(s_sourceRouter)); + } + + function test_ForwardFromRouterSuccessCustomExtraArgs() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT * 2})); + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, 1, 1, feeAmount, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + function test_ForwardFromRouterSuccessLegacyExtraArgs() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = + abi.encodeWithSelector(Client.EVM_EXTRA_ARGS_V1_TAG, LegacyExtraArgs({gasLimit: GAS_LIMIT * 2, strict: true})); + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectEmit(); + // We expect the message to be emitted with strict = false. + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, 1, 1, feeAmount, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + function test_ForwardFromRouter_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, 1, 1, feeAmount, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + function test_ForwardFromRouterExtraArgsV2_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = abi.encodeWithSelector( + Client.EVM_EXTRA_ARGS_V2_TAG, Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT * 2, allowOutOfOrderExecution: true}) + ); + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, 1, 1, feeAmount, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + function test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = abi.encodeWithSelector( + Client.EVM_EXTRA_ARGS_V2_TAG, Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT * 2, allowOutOfOrderExecution: true}) + ); + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, 1, 1, feeAmount, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + + function test_Fuzz_EnforceOutOfOrder(bool enforce, bool allowOutOfOrderExecution) public { + // Update dynamic config to enforce allowOutOfOrderExecution = defaultVal. + vm.stopPrank(); + vm.startPrank(OWNER); + EVM2EVMOnRamp.DynamicConfig memory dynamicConfig = s_onRamp.getDynamicConfig(); + s_onRamp.setDynamicConfig( + EVM2EVMOnRamp.DynamicConfig({ + router: dynamicConfig.router, + maxNumberOfTokensPerMsg: dynamicConfig.maxNumberOfTokensPerMsg, + destGasOverhead: dynamicConfig.destGasOverhead, + destGasPerPayloadByte: dynamicConfig.destGasPerPayloadByte, + destDataAvailabilityOverheadGas: dynamicConfig.destDataAvailabilityOverheadGas, + destGasPerDataAvailabilityByte: dynamicConfig.destGasPerDataAvailabilityByte, + destDataAvailabilityMultiplierBps: dynamicConfig.destDataAvailabilityMultiplierBps, + priceRegistry: dynamicConfig.priceRegistry, + maxDataBytes: dynamicConfig.maxDataBytes, + maxPerMsgGasLimit: dynamicConfig.maxPerMsgGasLimit, + defaultTokenFeeUSDCents: dynamicConfig.defaultTokenFeeUSDCents, + defaultTokenDestGasOverhead: dynamicConfig.defaultTokenDestGasOverhead, + defaultTokenDestBytesOverhead: dynamicConfig.defaultTokenDestBytesOverhead, + enforceOutOfOrder: enforce + }) + ); + vm.stopPrank(); + + vm.startPrank(address(s_sourceRouter)); + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = abi.encodeWithSelector( + Client.EVM_EXTRA_ARGS_V2_TAG, + Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT * 2, allowOutOfOrderExecution: allowOutOfOrderExecution}) + ); + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + if (enforce) { + // If enforcement is on, only true should be allowed. + if (allowOutOfOrderExecution) { + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, 1, 1, feeAmount, OWNER)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } else { + vm.expectRevert(EVM2EVMOnRamp.ExtraArgOutOfOrderExecutionMustBeTrue.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + } else { + // no enforcement should allow any value. + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, 1, 1, feeAmount, OWNER)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + } + + function test_ShouldIncrementSeqNumAndNonce_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + for (uint64 i = 1; i < 4; ++i) { + uint64 nonceBefore = s_onRamp.getSenderNonce(OWNER); + uint64 sequenceNumberBefore = s_onRamp.getSequenceNumber(); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, i, i, 0, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + uint64 nonceAfter = s_onRamp.getSenderNonce(OWNER); + uint64 sequenceNumberAfter = s_onRamp.getSequenceNumber(); + assertEq(nonceAfter, nonceBefore + 1); + assertEq(sequenceNumberAfter, sequenceNumberBefore + 1); + } + } + + function test_ShouldIncrementNonceOnlyOnOrdered_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = abi.encodeWithSelector( + Client.EVM_EXTRA_ARGS_V2_TAG, Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT * 2, allowOutOfOrderExecution: true}) + ); + + for (uint64 i = 1; i < 4; ++i) { + uint64 nonceBefore = s_onRamp.getSenderNonce(OWNER); + uint64 sequenceNumberBefore = s_onRamp.getSequenceNumber(); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, i, i, 0, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + uint64 nonceAfter = s_onRamp.getSenderNonce(OWNER); + uint64 sequenceNumberAfter = s_onRamp.getSequenceNumber(); + assertEq(nonceAfter, nonceBefore); + assertEq(sequenceNumberAfter, sequenceNumberBefore + 1); + } + } + + function test_forwardFromRouter_ShouldStoreLinkFees_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + + assertEq(IERC20(s_sourceFeeToken).balanceOf(address(s_onRamp)), feeAmount); + assertEq(s_onRamp.getNopFeesJuels(), feeAmount); + } + + function test_ShouldStoreNonLinkFees() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = s_sourceTokens[1]; + + uint256 feeAmount = 1234567890; + IERC20(s_sourceTokens[1]).transferFrom(OWNER, address(s_onRamp), feeAmount); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + + assertEq(IERC20(s_sourceTokens[1]).balanceOf(address(s_onRamp)), feeAmount); + + // Calculate conversion done by prices contract + uint256 feeTokenPrice = s_priceRegistry.getTokenPrice(s_sourceTokens[1]).value; + uint256 linkTokenPrice = s_priceRegistry.getTokenPrice(s_sourceFeeToken).value; + uint256 conversionRate = (feeTokenPrice * 1e18) / linkTokenPrice; + uint256 expectedJuels = (feeAmount * conversionRate) / 1e18; + + assertEq(s_onRamp.getNopFeesJuels(), expectedJuels); + } + + // Make sure any valid sender, receiver and feeAmount can be handled. + // @TODO Temporarily setting lower fuzz run as 256 triggers snapshot gas off by 1 error. + // https://github.com/foundry-rs/foundry/issues/5689 + /// forge-config: default.fuzz.runs = 32 + /// forge-config: ccip.fuzz.runs = 32 + function test_Fuzz_ForwardFromRouter_Success(address originalSender, address receiver, uint96 feeTokenAmount) public { + // To avoid RouterMustSetOriginalSender + vm.assume(originalSender != address(0)); + vm.assume(uint160(receiver) >= Internal.PRECOMPILE_SPACE); + vm.assume(feeTokenAmount <= MAX_NOP_FEES_JUELS); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.receiver = abi.encode(receiver); + + // Make sure the tokens are in the contract + deal(s_sourceFeeToken, address(s_onRamp), feeTokenAmount); + + Internal.EVM2EVMMessage memory expectedEvent = _messageToEvent(message, 1, 1, feeTokenAmount, originalSender); + + vm.expectEmit(false, false, false, true); + emit EVM2EVMOnRamp.CCIPSendRequested(expectedEvent); + + // Assert the message Id is correct + assertEq( + expectedEvent.messageId, s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeTokenAmount, originalSender) + ); + // Assert the fee token amount is correctly assigned to the nop fee pool + assertEq(feeTokenAmount, s_onRamp.getNopFeesJuels()); + } + + function test_OverValueWithARLOff_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].amount = 10; + message.tokenAmounts[0].token = s_sourceTokens[0]; + + IERC20(s_sourceTokens[0]).approve(address(s_onRamp), 10); + + vm.startPrank(OWNER); + // Set a high price to trip the ARL + uint224 tokenPrice = 3 ** 128; + Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(s_sourceTokens[0], tokenPrice); + s_priceRegistry.updatePrices(priceUpdates); + vm.startPrank(address(s_sourceRouter)); + + vm.expectRevert( + abi.encodeWithSelector( + RateLimiter.AggregateValueMaxCapacityExceeded.selector, + getOutboundRateLimiterConfig().capacity, + (message.tokenAmounts[0].amount * tokenPrice) / 1e18 + ) + ); + // Expect to fail from ARL + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + // Configure ARL off for token + EVM2EVMOnRamp.TokenTransferFeeConfig memory tokenTransferFeeConfig = + s_onRamp.getTokenTransferFeeConfig(s_sourceTokens[0]); + EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + new EVM2EVMOnRamp.TokenTransferFeeConfigArgs[](1); + tokenTransferFeeConfigArgs[0] = EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ + token: s_sourceTokens[0], + minFeeUSDCents: tokenTransferFeeConfig.minFeeUSDCents, + maxFeeUSDCents: tokenTransferFeeConfig.maxFeeUSDCents, + deciBps: tokenTransferFeeConfig.deciBps, + destGasOverhead: tokenTransferFeeConfig.destGasOverhead, + destBytesOverhead: tokenTransferFeeConfig.destBytesOverhead, + aggregateRateLimitEnabled: false + }); + vm.startPrank(OWNER); + s_onRamp.setTokenTransferFeeConfig(tokenTransferFeeConfigArgs, new address[](0)); + + vm.startPrank(address(s_sourceRouter)); + // Expect the call now succeeds + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + } + + // Reverts + + function test_Paused_Revert() public { + // We pause by disabling the whitelist + vm.stopPrank(); + vm.startPrank(OWNER); + address router = address(0); + s_onRamp.setDynamicConfig(generateDynamicOnRampConfig(router, address(2))); + vm.expectRevert(EVM2EVMOnRamp.MustBeCalledByRouter.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, OWNER); + } + + function test_InvalidExtraArgsTag_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = bytes("bad args"); + + vm.expectRevert(EVM2EVMOnRamp.InvalidExtraArgsTag.selector); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + } + + function test_Unhealthy_Revert() public { + s_mockRMN.setGlobalCursed(true); + vm.expectRevert(EVM2EVMOnRamp.CursedByRMN.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, OWNER); + } + + function test_Permissions_Revert() public { + vm.stopPrank(); + vm.startPrank(OWNER); + vm.expectRevert(EVM2EVMOnRamp.MustBeCalledByRouter.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, OWNER); + } + + function test_OriginalSender_Revert() public { + vm.expectRevert(EVM2EVMOnRamp.RouterMustSetOriginalSender.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, address(0)); + } + + function test_MessageTooLarge_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.data = new bytes(MAX_DATA_SIZE + 1); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.MessageTooLarge.selector, MAX_DATA_SIZE, message.data.length)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, STRANGER); + } + + function test_TooManyTokens_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + uint256 tooMany = MAX_TOKENS_LENGTH + 1; + message.tokenAmounts = new Client.EVMTokenAmount[](tooMany); + vm.expectRevert(EVM2EVMOnRamp.UnsupportedNumberOfTokens.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, STRANGER); + } + + function test_CannotSendZeroTokens_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].amount = 0; + message.tokenAmounts[0].token = s_sourceTokens[0]; + vm.expectRevert(EVM2EVMOnRamp.CannotSendZeroTokens.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, STRANGER); + } + + function test_UnsupportedToken_Revert() public { + address wrongToken = address(1); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].token = wrongToken; + message.tokenAmounts[0].amount = 1; + + // We need to set the price of this new token to be able to reach + // the proper revert point. This must be called by the owner. + vm.stopPrank(); + vm.startPrank(OWNER); + + Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(wrongToken, 1); + s_priceRegistry.updatePrices(priceUpdates); + + // Change back to the router + vm.startPrank(address(s_sourceRouter)); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.UnsupportedToken.selector, wrongToken)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + } + + function test_MaxCapacityExceeded_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].amount = 2 ** 128; + message.tokenAmounts[0].token = s_sourceTokens[0]; + + IERC20(s_sourceTokens[0]).approve(address(s_onRamp), 2 ** 128); + + vm.expectRevert( + abi.encodeWithSelector( + RateLimiter.AggregateValueMaxCapacityExceeded.selector, + getOutboundRateLimiterConfig().capacity, + (message.tokenAmounts[0].amount * s_sourceTokenPrices[0]) / 1e18 + ) + ); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + } + + function test_PriceNotFoundForToken_Revert() public { + // Set token price to 0 + vm.stopPrank(); + vm.startPrank(OWNER); + s_priceRegistry.updatePrices(getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, 0)); + + vm.startPrank(address(s_sourceRouter)); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].token = CUSTOM_TOKEN; + message.tokenAmounts[0].amount = 1; + + vm.expectRevert(abi.encodeWithSelector(AggregateRateLimiter.PriceNotFoundForToken.selector, CUSTOM_TOKEN)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + } + + // Asserts gasLimit must be <=maxGasLimit + function test_MessageGasLimitTooHigh_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: MAX_GAS_LIMIT + 1})); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.MessageGasLimitTooHigh.selector)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + } + + function test_InvalidAddressEncodePacked_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.receiver = abi.encodePacked(address(234)); + + vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, message.receiver)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 1, OWNER); + } + + function test_InvalidAddress_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.receiver = abi.encode(type(uint208).max); + + vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, message.receiver)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 1, OWNER); + } + + // We disallow sending to addresses 0-9. + function test_ZeroAddressReceiver_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + for (uint160 i = 0; i < 10; ++i) { + message.receiver = abi.encode(address(i)); + + vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, message.receiver)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 1, OWNER); + } + } + + function test_MaxFeeBalanceReached_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + vm.expectRevert(EVM2EVMOnRamp.MaxFeeBalanceReached.selector); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, MAX_NOP_FEES_JUELS + 1, OWNER); + } + + function test_InvalidChainSelector_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint64 wrongChainSelector = DEST_CHAIN_SELECTOR + 1; + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.InvalidChainSelector.selector, wrongChainSelector)); + + s_onRamp.forwardFromRouter(wrongChainSelector, message, 1, OWNER); + } + + function test_SourceTokenDataTooLarge_Revert() public { + address sourceETH = s_sourceTokens[1]; + vm.stopPrank(); + vm.startPrank(OWNER); + + MaybeRevertingBurnMintTokenPool newPool = new MaybeRevertingBurnMintTokenPool( + BurnMintERC677(sourceETH), new address[](0), address(s_mockRMN), address(s_sourceRouter) + ); + BurnMintERC677(sourceETH).grantMintAndBurnRoles(address(newPool)); + deal(address(sourceETH), address(newPool), type(uint256).max); + + // Add TokenPool to OnRamp + s_tokenAdminRegistry.setPool(sourceETH, address(newPool)); + + // Allow chain in TokenPool + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(s_destTokenPool), + remoteTokenAddress: abi.encode(s_destToken), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + newPool.applyChainUpdates(chainUpdates); + + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(address(sourceETH), 1000); + + // No data set, should succeed + vm.startPrank(address(s_sourceRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + // Set max data length, should succeed + vm.startPrank(OWNER); + newPool.setSourceTokenData(new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES)); + + vm.startPrank(address(s_sourceRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + // Set data to max length +1, should revert + vm.startPrank(OWNER); + newPool.setSourceTokenData(new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + 1)); + + vm.startPrank(address(s_sourceRouter)); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.SourceTokenDataTooLarge.selector, sourceETH)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + // Set token config to allow larger data + vm.startPrank(OWNER); + EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + new EVM2EVMOnRamp.TokenTransferFeeConfigArgs[](1); + tokenTransferFeeConfigArgs[0] = EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ + token: sourceETH, + minFeeUSDCents: 1, + maxFeeUSDCents: 0, + deciBps: 0, + destGasOverhead: 0, + destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) + 32, + aggregateRateLimitEnabled: false + }); + s_onRamp.setTokenTransferFeeConfig(tokenTransferFeeConfigArgs, new address[](0)); + + vm.startPrank(address(s_sourceRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + // Set the token data larger than the configured token data, should revert + vm.startPrank(OWNER); + newPool.setSourceTokenData(new bytes(uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) + 32 + 1)); + + vm.startPrank(address(s_sourceRouter)); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.SourceTokenDataTooLarge.selector, sourceETH)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + } + + function test_forwardFromRouter_UnsupportedToken_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].amount = 1; + message.tokenAmounts[0].token = address(1); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.UnsupportedToken.selector, message.tokenAmounts[0].token)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + } + + function test_EnforceOutOfOrder_Revert() public { + // Update dynamic config to enforce allowOutOfOrderExecution = true. + vm.stopPrank(); + vm.startPrank(OWNER); + EVM2EVMOnRamp.DynamicConfig memory dynamicConfig = s_onRamp.getDynamicConfig(); + s_onRamp.setDynamicConfig( + EVM2EVMOnRamp.DynamicConfig({ + router: dynamicConfig.router, + maxNumberOfTokensPerMsg: dynamicConfig.maxNumberOfTokensPerMsg, + destGasOverhead: dynamicConfig.destGasOverhead, + destGasPerPayloadByte: dynamicConfig.destGasPerPayloadByte, + destDataAvailabilityOverheadGas: dynamicConfig.destDataAvailabilityOverheadGas, + destGasPerDataAvailabilityByte: dynamicConfig.destGasPerDataAvailabilityByte, + destDataAvailabilityMultiplierBps: dynamicConfig.destDataAvailabilityMultiplierBps, + priceRegistry: dynamicConfig.priceRegistry, + maxDataBytes: dynamicConfig.maxDataBytes, + maxPerMsgGasLimit: dynamicConfig.maxPerMsgGasLimit, + defaultTokenFeeUSDCents: dynamicConfig.defaultTokenFeeUSDCents, + defaultTokenDestGasOverhead: dynamicConfig.defaultTokenDestGasOverhead, + defaultTokenDestBytesOverhead: dynamicConfig.defaultTokenDestBytesOverhead, + enforceOutOfOrder: true + }) + ); + vm.stopPrank(); + + vm.startPrank(address(s_sourceRouter)); + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + // Empty extraArgs to should revert since it enforceOutOfOrder is true. + message.extraArgs = ""; + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + vm.expectRevert(EVM2EVMOnRamp.ExtraArgOutOfOrderExecutionMustBeTrue.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } +} + +contract EVM2EVMOnRamp_forwardFromRouter_upgrade is EVM2EVMOnRampSetup { + uint256 internal constant FEE_AMOUNT = 1234567890; + EVM2EVMOnRampHelper internal s_prevOnRamp; + + function setUp() public virtual override { + EVM2EVMOnRampSetup.setUp(); + + s_prevOnRamp = s_onRamp; + + s_onRamp = new EVM2EVMOnRampHelper( + EVM2EVMOnRamp.StaticConfig({ + linkToken: s_sourceTokens[0], + chainSelector: SOURCE_CHAIN_SELECTOR, + destChainSelector: DEST_CHAIN_SELECTOR, + defaultTxGasLimit: GAS_LIMIT, + maxNopFeesJuels: MAX_NOP_FEES_JUELS, + prevOnRamp: address(s_prevOnRamp), + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }), + generateDynamicOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)), + getOutboundRateLimiterConfig(), + s_feeTokenConfigArgs, + s_tokenTransferFeeConfigArgs, + getNopsAndWeights() + ); + s_onRamp.setAdmin(ADMIN); + + s_metadataHash = keccak256( + abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, SOURCE_CHAIN_SELECTOR, DEST_CHAIN_SELECTOR, address(s_onRamp)) + ); + + vm.startPrank(address(s_sourceRouter)); + } + + function test_V2_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, 1, 1, FEE_AMOUNT, OWNER)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + } + + function test_V2SenderNoncesReadsPreviousRamp_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + uint64 startNonce = s_onRamp.getSenderNonce(OWNER); + + for (uint64 i = 1; i < 4; ++i) { + s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + assertEq(startNonce + i, s_onRamp.getSenderNonce(OWNER)); + } + } + + function test_V2NonceStartsAtV1Nonce_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint64 startNonce = s_onRamp.getSenderNonce(OWNER); + + // send 1 message from previous onramp + s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + assertEq(startNonce + 1, s_onRamp.getSenderNonce(OWNER)); + + // new onramp nonce should start from 2, while sequence number start from 1 + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, 1, startNonce + 2, FEE_AMOUNT, OWNER)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + assertEq(startNonce + 2, s_onRamp.getSenderNonce(OWNER)); + + // after another send, nonce should be 3, and sequence number be 2 + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, 2, startNonce + 3, FEE_AMOUNT, OWNER)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + assertEq(startNonce + 3, s_onRamp.getSenderNonce(OWNER)); + } + + function test_V2NonceNewSenderStartsAtZero_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + // send 1 message from previous onramp from OWNER + s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + address newSender = address(1234567); + // new onramp nonce should start from 1 for new sender + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(_messageToEvent(message, 1, 1, FEE_AMOUNT, newSender)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, newSender); + } +} + +contract EVM2EVMOnRamp_getFeeSetup is EVM2EVMOnRampSetup { + uint224 internal s_feeTokenPrice; + uint224 internal s_wrappedTokenPrice; + uint224 internal s_customTokenPrice; + + address internal s_selfServeTokenDefaultPricing = makeAddr("self-serve-token-default-pricing"); + + function setUp() public virtual override { + EVM2EVMOnRampSetup.setUp(); + + // Add additional pool addresses for test tokens to mark them as supported + s_tokenAdminRegistry.proposeAdministrator(s_sourceRouter.getWrappedNative(), OWNER); + s_tokenAdminRegistry.acceptAdminRole(s_sourceRouter.getWrappedNative()); + s_tokenAdminRegistry.proposeAdministrator(CUSTOM_TOKEN, OWNER); + s_tokenAdminRegistry.acceptAdminRole(CUSTOM_TOKEN); + + LockReleaseTokenPool wrappedNativePool = new LockReleaseTokenPool( + IERC20(s_sourceRouter.getWrappedNative()), new address[](0), address(s_mockRMN), true, address(s_sourceRouter) + ); + + TokenPool.ChainUpdate[] memory wrappedNativeChainUpdate = new TokenPool.ChainUpdate[](1); + wrappedNativeChainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(address(111111)), + remoteTokenAddress: abi.encode(s_destToken), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + wrappedNativePool.applyChainUpdates(wrappedNativeChainUpdate); + s_tokenAdminRegistry.setPool(s_sourceRouter.getWrappedNative(), address(wrappedNativePool)); + + LockReleaseTokenPool customPool = new LockReleaseTokenPool( + IERC20(CUSTOM_TOKEN), new address[](0), address(s_mockRMN), true, address(s_sourceRouter) + ); + TokenPool.ChainUpdate[] memory customChainUpdate = new TokenPool.ChainUpdate[](1); + customChainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(makeAddr("random")), + remoteTokenAddress: abi.encode(s_destToken), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + customPool.applyChainUpdates(customChainUpdate); + s_tokenAdminRegistry.setPool(CUSTOM_TOKEN, address(customPool)); + + s_feeTokenPrice = s_sourceTokenPrices[0]; + s_wrappedTokenPrice = s_sourceTokenPrices[2]; + s_customTokenPrice = CUSTOM_TOKEN_PRICE; + + // Ensure the self-serve token is set up on the admin registry + vm.mockCall( + address(s_tokenAdminRegistry), + abi.encodeWithSelector(ITokenAdminRegistry.getPool.selector, s_selfServeTokenDefaultPricing), + abi.encode(makeAddr("self-serve-pool")) + ); + } + + function calcUSDValueFromTokenAmount(uint224 tokenPrice, uint256 tokenAmount) internal pure returns (uint256) { + return (tokenPrice * tokenAmount) / 1e18; + } + + function applyBpsRatio(uint256 tokenAmount, uint16 ratio) internal pure returns (uint256) { + return (tokenAmount * ratio) / 1e5; + } + + function configUSDCentToWei(uint256 usdCent) internal pure returns (uint256) { + return usdCent * 1e16; + } +} + +contract EVM2EVMOnRamp_getDataAvailabilityCost is EVM2EVMOnRamp_getFeeSetup { + function test_EmptyMessageCalculatesDataAvailabilityCost_Success() public view { + uint256 dataAvailabilityCostUSD = s_onRamp.getDataAvailabilityCost(USD_PER_DATA_AVAILABILITY_GAS, 0, 0, 0); + + EVM2EVMOnRamp.DynamicConfig memory dynamicConfig = s_onRamp.getDynamicConfig(); + + uint256 dataAvailabilityGas = dynamicConfig.destDataAvailabilityOverheadGas + + dynamicConfig.destGasPerDataAvailabilityByte * Internal.MESSAGE_FIXED_BYTES; + uint256 expectedDataAvailabilityCostUSD = + USD_PER_DATA_AVAILABILITY_GAS * dataAvailabilityGas * dynamicConfig.destDataAvailabilityMultiplierBps * 1e14; + + assertEq(expectedDataAvailabilityCostUSD, dataAvailabilityCostUSD); + } + + function test_SimpleMessageCalculatesDataAvailabilityCost_Success() public view { + uint256 dataAvailabilityCostUSD = s_onRamp.getDataAvailabilityCost(USD_PER_DATA_AVAILABILITY_GAS, 100, 5, 50); + + EVM2EVMOnRamp.DynamicConfig memory dynamicConfig = s_onRamp.getDynamicConfig(); + + uint256 dataAvailabilityLengthBytes = + Internal.MESSAGE_FIXED_BYTES + 100 + (5 * Internal.MESSAGE_FIXED_BYTES_PER_TOKEN) + 50; + uint256 dataAvailabilityGas = dynamicConfig.destDataAvailabilityOverheadGas + + dynamicConfig.destGasPerDataAvailabilityByte * dataAvailabilityLengthBytes; + uint256 expectedDataAvailabilityCostUSD = + USD_PER_DATA_AVAILABILITY_GAS * dataAvailabilityGas * dynamicConfig.destDataAvailabilityMultiplierBps * 1e14; + + assertEq(expectedDataAvailabilityCostUSD, dataAvailabilityCostUSD); + } + + function test_Fuzz_ZeroDataAvailabilityGasPriceAlwaysCalculatesZeroDataAvailabilityCost_Success( + uint64 messageDataLength, + uint32 numberOfTokens, + uint32 tokenTransferBytesOverhead + ) public view { + uint256 dataAvailabilityCostUSD = + s_onRamp.getDataAvailabilityCost(0, messageDataLength, numberOfTokens, tokenTransferBytesOverhead); + + assertEq(0, dataAvailabilityCostUSD); + } + + function test_Fuzz_CalculateDataAvailabilityCost_Success( + uint32 destDataAvailabilityOverheadGas, + uint16 destGasPerDataAvailabilityByte, + uint16 destDataAvailabilityMultiplierBps, + uint112 dataAvailabilityGasPrice, + uint64 messageDataLength, + uint32 numberOfTokens, + uint32 tokenTransferBytesOverhead + ) public { + EVM2EVMOnRamp.DynamicConfig memory dynamicConfig = s_onRamp.getDynamicConfig(); + dynamicConfig.destDataAvailabilityOverheadGas = destDataAvailabilityOverheadGas; + dynamicConfig.destGasPerDataAvailabilityByte = destGasPerDataAvailabilityByte; + dynamicConfig.destDataAvailabilityMultiplierBps = destDataAvailabilityMultiplierBps; + s_onRamp.setDynamicConfig(dynamicConfig); + + uint256 dataAvailabilityCostUSD = s_onRamp.getDataAvailabilityCost( + dataAvailabilityGasPrice, messageDataLength, numberOfTokens, tokenTransferBytesOverhead + ); + + uint256 dataAvailabilityLengthBytes = Internal.MESSAGE_FIXED_BYTES + messageDataLength + + (numberOfTokens * Internal.MESSAGE_FIXED_BYTES_PER_TOKEN) + tokenTransferBytesOverhead; + + uint256 dataAvailabilityGas = + destDataAvailabilityOverheadGas + destGasPerDataAvailabilityByte * dataAvailabilityLengthBytes; + uint256 expectedDataAvailabilityCostUSD = + dataAvailabilityGasPrice * dataAvailabilityGas * destDataAvailabilityMultiplierBps * 1e14; + + assertEq(expectedDataAvailabilityCostUSD, dataAvailabilityCostUSD); + } +} + +contract EVM2EVMOnRamp_getSupportedTokens is EVM2EVMOnRampSetup { + function test_GetSupportedTokens_Revert() public { + vm.expectRevert(EVM2EVMOnRamp.GetSupportedTokensFunctionalityRemovedCheckAdminRegistry.selector); + s_onRamp.getSupportedTokens(DEST_CHAIN_SELECTOR); + } +} + +contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { + using USDPriceWith18Decimals for uint224; + + function test_NoTokenTransferChargesZeroFee_Success() public view { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + assertEq(0, feeUSDWei); + assertEq(0, destGasOverhead); + assertEq(0, destBytesOverhead); + } + + function test__getTokenTransferCost_selfServeUsesDefaults_Success() public view { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_selfServeTokenDefaultPricing, 1000); + + // Get config to assert it isn't set + EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = + s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[0].token); + + assertFalse(transferFeeConfig.isEnabled); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + // Assert that the default values are used + assertEq(uint256(DEFAULT_TOKEN_FEE_USD_CENTS) * 1e16, feeUSDWei); + assertEq(DEFAULT_TOKEN_DEST_GAS_OVERHEAD, destGasOverhead); + assertEq(DEFAULT_TOKEN_BYTES_OVERHEAD, destBytesOverhead); + } + + function test_SmallTokenTransferChargesMinFeeAndGas_Success() public view { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1000); + EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = + s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[0].token); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + assertEq(configUSDCentToWei(transferFeeConfig.minFeeUSDCents), feeUSDWei); + assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); + assertEq(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, destBytesOverhead); + } + + function test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() public view { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 0); + EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = + s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[0].token); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + assertEq(configUSDCentToWei(transferFeeConfig.minFeeUSDCents), feeUSDWei); + assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); + assertEq(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, destBytesOverhead); + } + + function test_LargeTokenTransferChargesMaxFeeAndGas_Success() public view { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1e36); + EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = + s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[0].token); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + assertEq(configUSDCentToWei(transferFeeConfig.maxFeeUSDCents), feeUSDWei); + assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); + assertEq(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, destBytesOverhead); + } + + function test_FeeTokenBpsFee_Success() public view { + uint256 tokenAmount = 10000e18; + + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, tokenAmount); + EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = + s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[0].token); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + uint256 usdWei = calcUSDValueFromTokenAmount(s_feeTokenPrice, tokenAmount); + uint256 bpsUSDWei = applyBpsRatio(usdWei, s_tokenTransferFeeConfigArgs[0].deciBps); + + assertEq(bpsUSDWei, feeUSDWei); + assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); + assertEq(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, destBytesOverhead); + } + + function test_WETHTokenBpsFee_Success() public view { + uint256 tokenAmount = 100e18; + + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: new Client.EVMTokenAmount[](1), + feeToken: s_sourceRouter.getWrappedNative(), + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + message.tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceRouter.getWrappedNative(), amount: tokenAmount}); + + EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = + s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[0].token); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_wrappedTokenPrice, message.tokenAmounts); + + uint256 usdWei = calcUSDValueFromTokenAmount(s_wrappedTokenPrice, tokenAmount); + uint256 bpsUSDWei = applyBpsRatio(usdWei, s_tokenTransferFeeConfigArgs[1].deciBps); + + assertEq(bpsUSDWei, feeUSDWei); + assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); + assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); + } + + function test_CustomTokenBpsFee_Success() public view { + uint256 tokenAmount = 200000e18; + + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: new Client.EVMTokenAmount[](1), + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + message.tokenAmounts[0] = Client.EVMTokenAmount({token: CUSTOM_TOKEN, amount: tokenAmount}); + + EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = + s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[0].token); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + uint256 usdWei = calcUSDValueFromTokenAmount(s_customTokenPrice, tokenAmount); + uint256 bpsUSDWei = applyBpsRatio(usdWei, s_tokenTransferFeeConfigArgs[2].deciBps); + + assertEq(bpsUSDWei, feeUSDWei); + assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); + assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); + } + + function test_ZeroFeeConfigChargesMinFee_Success() public { + EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + new EVM2EVMOnRamp.TokenTransferFeeConfigArgs[](1); + tokenTransferFeeConfigArgs[0] = EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ + token: s_sourceFeeToken, + minFeeUSDCents: 1, + maxFeeUSDCents: 0, + deciBps: 0, + destGasOverhead: 0, + destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES), + aggregateRateLimitEnabled: true + }); + s_onRamp.setTokenTransferFeeConfig(tokenTransferFeeConfigArgs, new address[](0)); + + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1e36); + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + // if token charges 0 bps, it should cost minFee to transfer + assertEq(configUSDCentToWei(tokenTransferFeeConfigArgs[0].minFeeUSDCents), feeUSDWei); + assertEq(0, destGasOverhead); + assertEq(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, destBytesOverhead); + } + + function test_Fuzz_TokenTransferFeeDuplicateTokens_Success(uint256 transfers, uint256 amount) public view { + // It shouldn't be possible to pay materially lower fees by splitting up the transfers. + // Note it is possible to pay higher fees since the minimum fees are added. + EVM2EVMOnRamp.DynamicConfig memory dynamicConfig = s_onRamp.getDynamicConfig(); + transfers = bound(transfers, 1, dynamicConfig.maxNumberOfTokensPerMsg); + // Cap amount to avoid overflow + amount = bound(amount, 0, 1e36); + Client.EVMTokenAmount[] memory multiple = new Client.EVMTokenAmount[](transfers); + for (uint256 i = 0; i < transfers; ++i) { + multiple[i] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: amount}); + } + Client.EVMTokenAmount[] memory single = new Client.EVMTokenAmount[](1); + single[0] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: amount * transfers}); + + address feeToken = s_sourceRouter.getWrappedNative(); + + (uint256 feeSingleUSDWei, uint32 gasOverheadSingle, uint32 bytesOverheadSingle) = + s_onRamp.getTokenTransferCost(feeToken, s_wrappedTokenPrice, single); + (uint256 feeMultipleUSDWei, uint32 gasOverheadMultiple, uint32 bytesOverheadMultiple) = + s_onRamp.getTokenTransferCost(feeToken, s_wrappedTokenPrice, multiple); + + // Note that there can be a rounding error once per split. + assertTrue(feeMultipleUSDWei >= (feeSingleUSDWei - dynamicConfig.maxNumberOfTokensPerMsg)); + assertEq(gasOverheadMultiple, gasOverheadSingle * transfers); + assertEq(bytesOverheadMultiple, bytesOverheadSingle * transfers); + } + + function test_MixedTokenTransferFee_Success() public view { + address[3] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative(), CUSTOM_TOKEN]; + uint224[3] memory tokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice, s_customTokenPrice]; + EVM2EVMOnRamp.TokenTransferFeeConfig[3] memory tokenTransferFeeConfigs = [ + s_onRamp.getTokenTransferFeeConfig(testTokens[0]), + s_onRamp.getTokenTransferFeeConfig(testTokens[1]), + s_onRamp.getTokenTransferFeeConfig(testTokens[2]) + ]; + + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: new Client.EVMTokenAmount[](3), + feeToken: s_sourceRouter.getWrappedNative(), + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + uint256 expectedTotalGas = 0; + uint256 expectedTotalBytes = 0; + + // Start with small token transfers, total bps fee is lower than min token transfer fee + for (uint256 i = 0; i < testTokens.length; ++i) { + message.tokenAmounts[i] = Client.EVMTokenAmount({token: testTokens[i], amount: 1e14}); + expectedTotalGas += s_onRamp.getTokenTransferFeeConfig(testTokens[i]).destGasOverhead; + uint32 dstBytesOverhead = s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[i].token).destBytesOverhead; + expectedTotalBytes += dstBytesOverhead == 0 ? uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) : dstBytesOverhead; + } + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_wrappedTokenPrice, message.tokenAmounts); + + uint256 expectedFeeUSDWei = 0; + for (uint256 i = 0; i < testTokens.length; ++i) { + expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[i].minFeeUSDCents); + } + + assertEq(expectedFeeUSDWei, feeUSDWei); + assertEq(expectedTotalGas, destGasOverhead); + assertEq(expectedTotalBytes, destBytesOverhead); + + // Set 1st token transfer to a meaningful amount so its bps fee is now between min and max fee + message.tokenAmounts[0] = Client.EVMTokenAmount({token: testTokens[0], amount: 10000e18}); + + (feeUSDWei, destGasOverhead, destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_wrappedTokenPrice, message.tokenAmounts); + expectedFeeUSDWei = applyBpsRatio( + calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), tokenTransferFeeConfigs[0].deciBps + ); + expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[1].minFeeUSDCents); + expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); + + assertEq(expectedFeeUSDWei, feeUSDWei); + assertEq(expectedTotalGas, destGasOverhead); + assertEq(expectedTotalBytes, destBytesOverhead); + + // Set 2nd token transfer to a large amount that is higher than maxFeeUSD + message.tokenAmounts[1] = Client.EVMTokenAmount({token: testTokens[1], amount: 1e36}); + + (feeUSDWei, destGasOverhead, destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_wrappedTokenPrice, message.tokenAmounts); + expectedFeeUSDWei = applyBpsRatio( + calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), tokenTransferFeeConfigs[0].deciBps + ); + expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[1].maxFeeUSDCents); + expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); + + assertEq(expectedFeeUSDWei, feeUSDWei); + assertEq(expectedTotalGas, destGasOverhead); + assertEq(expectedTotalBytes, destBytesOverhead); + } + + // reverts + + function test_UnsupportedToken_Revert() public { + address NOT_SUPPORTED_TOKEN = address(123); + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(NOT_SUPPORTED_TOKEN, 200); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.UnsupportedToken.selector, NOT_SUPPORTED_TOKEN)); + + s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts); + } +} + +contract EVM2EVMOnRamp_getFee is EVM2EVMOnRamp_getFeeSetup { + using USDPriceWith18Decimals for uint224; + + function test_EmptyMessage_Success() public view { + address[2] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative()]; + uint224[2] memory feeTokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice]; + + for (uint256 i = 0; i < feeTokenPrices.length; ++i) { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = testTokens[i]; + EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); + + uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + + uint256 gasUsed = GAS_LIMIT + DEST_GAS_OVERHEAD; + uint256 gasFeeUSD = (gasUsed * feeTokenConfig.gasMultiplierWeiPerEth * USD_PER_GAS); + uint256 messageFeeUSD = + (configUSDCentToWei(feeTokenConfig.networkFeeUSDCents) * feeTokenConfig.premiumMultiplierWeiPerEth); + uint256 dataAvailabilityFeeUSD = s_onRamp.getDataAvailabilityCost( + USD_PER_DATA_AVAILABILITY_GAS, message.data.length, message.tokenAmounts.length, 0 + ); + + uint256 totalPriceInFeeToken = (gasFeeUSD + messageFeeUSD + dataAvailabilityFeeUSD) / feeTokenPrices[i]; + assertEq(totalPriceInFeeToken, feeAmount); + } + } + + function test_ZeroDataAvailabilityMultiplier_Success() public { + EVM2EVMOnRamp.DynamicConfig memory dynamicConfig = s_onRamp.getDynamicConfig(); + dynamicConfig.destDataAvailabilityMultiplierBps = 0; + s_onRamp.setDynamicConfig(dynamicConfig); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); + + uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + + uint256 gasUsed = GAS_LIMIT + DEST_GAS_OVERHEAD; + uint256 gasFeeUSD = (gasUsed * feeTokenConfig.gasMultiplierWeiPerEth * USD_PER_GAS); + uint256 messageFeeUSD = + (configUSDCentToWei(feeTokenConfig.networkFeeUSDCents) * feeTokenConfig.premiumMultiplierWeiPerEth); + + uint256 totalPriceInFeeToken = (gasFeeUSD + messageFeeUSD) / s_feeTokenPrice; + assertEq(totalPriceInFeeToken, feeAmount); + } + + function test_HighGasMessage_Success() public view { + address[2] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative()]; + uint224[2] memory feeTokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice]; + + uint256 customGasLimit = MAX_GAS_LIMIT; + uint256 customDataSize = MAX_DATA_SIZE; + for (uint256 i = 0; i < feeTokenPrices.length; ++i) { + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: new bytes(customDataSize), + tokenAmounts: new Client.EVMTokenAmount[](0), + feeToken: testTokens[i], + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: customGasLimit})) + }); + + EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); + uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + + uint256 gasUsed = customGasLimit + DEST_GAS_OVERHEAD + customDataSize * DEST_GAS_PER_PAYLOAD_BYTE; + uint256 gasFeeUSD = (gasUsed * feeTokenConfig.gasMultiplierWeiPerEth * USD_PER_GAS); + uint256 messageFeeUSD = + (configUSDCentToWei(feeTokenConfig.networkFeeUSDCents) * feeTokenConfig.premiumMultiplierWeiPerEth); + uint256 dataAvailabilityFeeUSD = s_onRamp.getDataAvailabilityCost( + USD_PER_DATA_AVAILABILITY_GAS, message.data.length, message.tokenAmounts.length, 0 + ); + + uint256 totalPriceInFeeToken = (gasFeeUSD + messageFeeUSD + dataAvailabilityFeeUSD) / feeTokenPrices[i]; + assertEq(totalPriceInFeeToken, feeAmount); + } + } + + function test_SingleTokenMessage_Success() public view { + address[2] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative()]; + uint224[2] memory feeTokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice]; + + uint256 tokenAmount = 10000e18; + for (uint256 i = 0; i < feeTokenPrices.length; ++i) { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, tokenAmount); + message.feeToken = testTokens[i]; + EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); + uint32 tokenGasOverhead = s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[0].token).destGasOverhead; + uint32 destBytesOverhead = s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[0].token).destBytesOverhead; + uint32 tokenBytesOverhead = + destBytesOverhead == 0 ? uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) : destBytesOverhead; + + uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + + uint256 gasUsed = GAS_LIMIT + DEST_GAS_OVERHEAD + tokenGasOverhead; + uint256 gasFeeUSD = (gasUsed * feeTokenConfig.gasMultiplierWeiPerEth * USD_PER_GAS); + (uint256 transferFeeUSD,,) = + s_onRamp.getTokenTransferCost(message.feeToken, feeTokenPrices[i], message.tokenAmounts); + uint256 messageFeeUSD = (transferFeeUSD * feeTokenConfig.premiumMultiplierWeiPerEth); + uint256 dataAvailabilityFeeUSD = s_onRamp.getDataAvailabilityCost( + USD_PER_DATA_AVAILABILITY_GAS, message.data.length, message.tokenAmounts.length, tokenBytesOverhead + ); + + uint256 totalPriceInFeeToken = (gasFeeUSD + messageFeeUSD + dataAvailabilityFeeUSD) / feeTokenPrices[i]; + assertEq(totalPriceInFeeToken, feeAmount); + } + } + + function test_MessageWithDataAndTokenTransfer_Success() public view { + address[2] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative()]; + uint224[2] memory feeTokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice]; + + uint256 customGasLimit = 1_000_000; + uint256 feeTokenAmount = 10000e18; + uint256 customTokenAmount = 200000e18; + for (uint256 i = 0; i < feeTokenPrices.length; ++i) { + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: new Client.EVMTokenAmount[](2), + feeToken: testTokens[i], + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: customGasLimit})) + }); + EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); + + message.tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceFeeToken, amount: feeTokenAmount}); + message.tokenAmounts[1] = Client.EVMTokenAmount({token: CUSTOM_TOKEN, amount: customTokenAmount}); + message.data = "random bits and bytes that should be factored into the cost of the message"; + + uint32 tokenGasOverhead = 0; + uint32 tokenBytesOverhead = 0; + for (uint256 j = 0; j < message.tokenAmounts.length; ++j) { + tokenGasOverhead += s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[j].token).destGasOverhead; + uint32 destBytesOverhead = s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[j].token).destBytesOverhead; + tokenBytesOverhead += destBytesOverhead == 0 ? uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) : destBytesOverhead; + } + + uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + + uint256 gasUsed = + customGasLimit + DEST_GAS_OVERHEAD + message.data.length * DEST_GAS_PER_PAYLOAD_BYTE + tokenGasOverhead; + uint256 gasFeeUSD = (gasUsed * feeTokenConfig.gasMultiplierWeiPerEth * USD_PER_GAS); + (uint256 transferFeeUSD,,) = + s_onRamp.getTokenTransferCost(message.feeToken, feeTokenPrices[i], message.tokenAmounts); + uint256 messageFeeUSD = (transferFeeUSD * feeTokenConfig.premiumMultiplierWeiPerEth); + uint256 dataAvailabilityFeeUSD = s_onRamp.getDataAvailabilityCost( + USD_PER_DATA_AVAILABILITY_GAS, message.data.length, message.tokenAmounts.length, tokenBytesOverhead + ); + + uint256 totalPriceInFeeToken = (gasFeeUSD + messageFeeUSD + dataAvailabilityFeeUSD) / feeTokenPrices[i]; + assertEq(totalPriceInFeeToken, feeAmount); + } + } + + // Reverts + + function test_NotAFeeToken_Revert() public { + address notAFeeToken = address(0x111111); + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(notAFeeToken, 1); + message.feeToken = notAFeeToken; + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.NotAFeeToken.selector, notAFeeToken)); + + s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + } + + function test_MessageTooLarge_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.data = new bytes(MAX_DATA_SIZE + 1); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.MessageTooLarge.selector, MAX_DATA_SIZE, message.data.length)); + + s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + } + + function test_TooManyTokens_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + uint256 tooMany = MAX_TOKENS_LENGTH + 1; + message.tokenAmounts = new Client.EVMTokenAmount[](tooMany); + vm.expectRevert(EVM2EVMOnRamp.UnsupportedNumberOfTokens.selector); + s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + } + + // Asserts gasLimit must be <=maxGasLimit + function test_MessageGasLimitTooHigh_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: MAX_GAS_LIMIT + 1})); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.MessageGasLimitTooHigh.selector)); + s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + } +} + +contract EVM2EVMOnRamp_setNops is EVM2EVMOnRampSetup { + // Used because EnumerableMap doesn't guarantee order + mapping(address nop => uint256 weight) internal s_nopsToWeights; + + function test_SetNops_Success() public { + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = getNopsAndWeights(); + nopsAndWeights[1].nop = USER_4; + nopsAndWeights[1].weight = 20; + for (uint256 i = 0; i < nopsAndWeights.length; ++i) { + s_nopsToWeights[nopsAndWeights[i].nop] = nopsAndWeights[i].weight; + } + + s_onRamp.setNops(nopsAndWeights); + + (EVM2EVMOnRamp.NopAndWeight[] memory actual,) = s_onRamp.getNops(); + for (uint256 i = 0; i < actual.length; ++i) { + assertEq(actual[i].weight, s_nopsToWeights[actual[i].nop]); + } + } + + function test_AdminCanSetNops_Success() public { + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = getNopsAndWeights(); + // Should not revert + vm.startPrank(ADMIN); + s_onRamp.setNops(nopsAndWeights); + } + + function test_IncludesPayment_Success() public { + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = getNopsAndWeights(); + nopsAndWeights[1].nop = USER_4; + nopsAndWeights[1].weight = 20; + uint32 totalWeight; + for (uint256 i = 0; i < nopsAndWeights.length; ++i) { + totalWeight += nopsAndWeights[i].weight; + s_nopsToWeights[nopsAndWeights[i].nop] = nopsAndWeights[i].weight; + } + + // Make sure a payout happens regardless of what the weights are set to + uint96 nopFeesJuels = totalWeight * 5; + // Set Nop fee juels + deal(s_sourceFeeToken, address(s_onRamp), nopFeesJuels); + vm.startPrank(address(s_sourceRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), nopFeesJuels, OWNER); + vm.startPrank(OWNER); + + // We don't care about the fee calculation logic in this test + // so we don't verify the amounts. We do verify the addresses to + // make sure the existing nops get paid and not the new ones. + EVM2EVMOnRamp.NopAndWeight[] memory existingNopsAndWeights = getNopsAndWeights(); + for (uint256 i = 0; i < existingNopsAndWeights.length; ++i) { + vm.expectEmit(true, false, false, false); + emit EVM2EVMOnRamp.NopPaid(existingNopsAndWeights[i].nop, 0); + } + + s_onRamp.setNops(nopsAndWeights); + + (EVM2EVMOnRamp.NopAndWeight[] memory actual,) = s_onRamp.getNops(); + for (uint256 i = 0; i < actual.length; ++i) { + assertEq(actual[i].weight, s_nopsToWeights[actual[i].nop]); + } + } + + function test_SetNopsRemovesOldNopsCompletely_Success() public { + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = new EVM2EVMOnRamp.NopAndWeight[](0); + s_onRamp.setNops(nopsAndWeights); + (EVM2EVMOnRamp.NopAndWeight[] memory actual, uint256 totalWeight) = s_onRamp.getNops(); + assertEq(actual.length, 0); + assertEq(totalWeight, 0); + + address prevNop = getNopsAndWeights()[0].nop; + vm.startPrank(prevNop); + + // prev nop should not have permission to call payNops + vm.expectRevert(EVM2EVMOnRamp.OnlyCallableByOwnerOrAdminOrNop.selector); + s_onRamp.payNops(); + } + + // Reverts + + function test_NotEnoughFundsForPayout_Revert() public { + uint96 nopFeesJuels = MAX_NOP_FEES_JUELS; + // Set Nop fee juels but don't transfer LINK. This can happen when users + // pay in non-link tokens. + vm.startPrank(address(s_sourceRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), nopFeesJuels, OWNER); + vm.startPrank(OWNER); + + vm.expectRevert(EVM2EVMOnRamp.InsufficientBalance.selector); + + s_onRamp.setNops(getNopsAndWeights()); + } + + function test_NonOwnerOrAdmin_Revert() public { + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = getNopsAndWeights(); + vm.startPrank(STRANGER); + vm.expectRevert(EVM2EVMOnRamp.OnlyCallableByOwnerOrAdmin.selector); + s_onRamp.setNops(nopsAndWeights); + } + + function test_LinkTokenCannotBeNop_Revert() public { + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = getNopsAndWeights(); + nopsAndWeights[0].nop = address(s_sourceTokens[0]); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.InvalidNopAddress.selector, address(s_sourceTokens[0]))); + + s_onRamp.setNops(nopsAndWeights); + } + + function test_ZeroAddressCannotBeNop_Revert() public { + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = getNopsAndWeights(); + nopsAndWeights[0].nop = address(0); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.InvalidNopAddress.selector, address(0))); + + s_onRamp.setNops(nopsAndWeights); + } + + function test_TooManyNops_Revert() public { + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = new EVM2EVMOnRamp.NopAndWeight[](257); + + vm.expectRevert(EVM2EVMOnRamp.TooManyNops.selector); + + s_onRamp.setNops(nopsAndWeights); + } +} + +contract EVM2EVMOnRamp_withdrawNonLinkFees is EVM2EVMOnRampSetup { + IERC20 internal s_token; + + function setUp() public virtual override { + EVM2EVMOnRampSetup.setUp(); + // Send some non-link tokens to the onRamp + s_token = IERC20(s_sourceTokens[1]); + deal(s_sourceTokens[1], address(s_onRamp), 100); + } + + function test_WithdrawNonLinkFees_Success() public { + s_onRamp.withdrawNonLinkFees(address(s_token), address(this)); + + assertEq(0, s_token.balanceOf(address(s_onRamp))); + assertEq(100, s_token.balanceOf(address(this))); + } + + function test_SettlingBalance_Success() public { + // Set Nop fee juels + uint96 nopFeesJuels = 10000000; + vm.startPrank(address(s_sourceRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), nopFeesJuels, OWNER); + vm.startPrank(OWNER); + + vm.expectRevert(EVM2EVMOnRamp.LinkBalanceNotSettled.selector); + s_onRamp.withdrawNonLinkFees(address(s_token), address(this)); + + // It doesnt matter how the link tokens get to the onRamp + // In this case we simply deal them to the ramp to show + // anyone can settle the balance + deal(s_sourceTokens[0], address(s_onRamp), nopFeesJuels); + + s_onRamp.withdrawNonLinkFees(address(s_token), address(this)); + } + + function test_Fuzz_FuzzWithdrawalOnlyLeftoverLink_Success(uint96 nopFeeJuels, uint64 extraJuels) public { + nopFeeJuels = uint96(bound(nopFeeJuels, 1, MAX_NOP_FEES_JUELS)); + + // Set Nop fee juels + vm.startPrank(address(s_sourceRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), nopFeeJuels, OWNER); + vm.startPrank(OWNER); + + vm.expectRevert(EVM2EVMOnRamp.LinkBalanceNotSettled.selector); + s_onRamp.withdrawNonLinkFees(address(s_token), address(this)); + + address linkToken = s_sourceTokens[0]; + // It doesnt matter how the link tokens get to the onRamp + // In this case we simply deal them to the ramp to show + // anyone can settle the balance + deal(linkToken, address(s_onRamp), nopFeeJuels + uint96(extraJuels)); + + // Now that we've sent nopFeesJuels + extraJuels, we should be able to withdraw extraJuels + address linkRecipient = address(0x123456789); + assertEq(0, IERC20(linkToken).balanceOf(linkRecipient)); + + s_onRamp.withdrawNonLinkFees(linkToken, linkRecipient); + + assertEq(extraJuels, IERC20(linkToken).balanceOf(linkRecipient)); + } + + // Reverts + + function test_LinkBalanceNotSettled_Revert() public { + // Set Nop fee juels + uint96 nopFeesJuels = 10000000; + vm.startPrank(address(s_sourceRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), nopFeesJuels, OWNER); + vm.startPrank(OWNER); + + vm.expectRevert(EVM2EVMOnRamp.LinkBalanceNotSettled.selector); + + s_onRamp.withdrawNonLinkFees(address(s_token), address(this)); + } + + function test_NonOwnerOrAdmin_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert(EVM2EVMOnRamp.OnlyCallableByOwnerOrAdmin.selector); + s_onRamp.withdrawNonLinkFees(address(s_token), address(this)); + } + + function test_WithdrawToZeroAddress_Revert() public { + vm.expectRevert(EVM2EVMOnRamp.InvalidWithdrawParams.selector); + s_onRamp.withdrawNonLinkFees(address(s_token), address(0)); + } +} + +contract EVM2EVMOnRamp_setFeeTokenConfig is EVM2EVMOnRampSetup { + function test_SetFeeTokenConfig_Success() public { + EVM2EVMOnRamp.FeeTokenConfigArgs[] memory feeConfig; + + vm.expectEmit(); + emit EVM2EVMOnRamp.FeeConfigSet(feeConfig); + + s_onRamp.setFeeTokenConfig(feeConfig); + } + + function test_SetFeeTokenConfigByAdmin_Success() public { + EVM2EVMOnRamp.FeeTokenConfigArgs[] memory feeConfig; + + vm.startPrank(ADMIN); + + vm.expectEmit(); + emit EVM2EVMOnRamp.FeeConfigSet(feeConfig); + + s_onRamp.setFeeTokenConfig(feeConfig); + } + + // Reverts + + function test_OnlyCallableByOwnerOrAdmin_Revert() public { + EVM2EVMOnRamp.FeeTokenConfigArgs[] memory feeConfig; + vm.startPrank(STRANGER); + + vm.expectRevert(EVM2EVMOnRamp.OnlyCallableByOwnerOrAdmin.selector); + + s_onRamp.setFeeTokenConfig(feeConfig); + } +} + +contract EVM2EVMOnRamp_setTokenTransferFeeConfig is EVM2EVMOnRampSetup { + function test__setTokenTransferFeeConfig_Success() public { + EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] memory tokenTransferFeeArgs = + new EVM2EVMOnRamp.TokenTransferFeeConfigArgs[](2); + tokenTransferFeeArgs[0] = EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ + token: address(5), + minFeeUSDCents: 6, + maxFeeUSDCents: 7, + deciBps: 8, + destGasOverhead: 9, + destBytesOverhead: 312, + aggregateRateLimitEnabled: true + }); + tokenTransferFeeArgs[1] = EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ + token: address(11), + minFeeUSDCents: 12, + maxFeeUSDCents: 13, + deciBps: 14, + destGasOverhead: 15, + destBytesOverhead: 394, + aggregateRateLimitEnabled: false + }); + + vm.expectEmit(); + emit EVM2EVMOnRamp.TokenTransferFeeConfigSet(tokenTransferFeeArgs); + + s_onRamp.setTokenTransferFeeConfig(tokenTransferFeeArgs, new address[](0)); + + EVM2EVMOnRamp.TokenTransferFeeConfig memory config0 = + s_onRamp.getTokenTransferFeeConfig(tokenTransferFeeArgs[0].token); + + assertEq(tokenTransferFeeArgs[0].minFeeUSDCents, config0.minFeeUSDCents); + assertEq(tokenTransferFeeArgs[0].maxFeeUSDCents, config0.maxFeeUSDCents); + assertEq(tokenTransferFeeArgs[0].deciBps, config0.deciBps); + assertEq(tokenTransferFeeArgs[0].destGasOverhead, config0.destGasOverhead); + assertEq(tokenTransferFeeArgs[0].destBytesOverhead, config0.destBytesOverhead); + assertEq(tokenTransferFeeArgs[0].aggregateRateLimitEnabled, config0.aggregateRateLimitEnabled); + assertTrue(config0.isEnabled); + + EVM2EVMOnRamp.TokenTransferFeeConfig memory config1 = + s_onRamp.getTokenTransferFeeConfig(tokenTransferFeeArgs[1].token); + + assertEq(tokenTransferFeeArgs[1].minFeeUSDCents, config1.minFeeUSDCents); + assertEq(tokenTransferFeeArgs[1].maxFeeUSDCents, config1.maxFeeUSDCents); + assertEq(tokenTransferFeeArgs[1].deciBps, config1.deciBps); + assertEq(tokenTransferFeeArgs[1].destGasOverhead, config1.destGasOverhead); + assertEq(tokenTransferFeeArgs[1].destBytesOverhead, config1.destBytesOverhead); + assertEq(tokenTransferFeeArgs[1].aggregateRateLimitEnabled, config1.aggregateRateLimitEnabled); + assertTrue(config0.isEnabled); + + // Remove only the first token and validate only the first token is removed + address[] memory tokensToRemove = new address[](1); + tokensToRemove[0] = tokenTransferFeeArgs[0].token; + + vm.expectEmit(); + emit EVM2EVMOnRamp.TokenTransferFeeConfigDeleted(tokensToRemove); + + s_onRamp.setTokenTransferFeeConfig(new EVM2EVMOnRamp.TokenTransferFeeConfigArgs[](0), tokensToRemove); + + config0 = s_onRamp.getTokenTransferFeeConfig(tokenTransferFeeArgs[0].token); + + assertEq(0, config0.minFeeUSDCents); + assertEq(0, config0.maxFeeUSDCents); + assertEq(0, config0.deciBps); + assertEq(0, config0.destGasOverhead); + assertEq(0, config0.destBytesOverhead); + assertFalse(config0.aggregateRateLimitEnabled); + assertFalse(config0.isEnabled); + + config1 = s_onRamp.getTokenTransferFeeConfig(tokenTransferFeeArgs[1].token); + + assertEq(tokenTransferFeeArgs[1].minFeeUSDCents, config1.minFeeUSDCents); + assertEq(tokenTransferFeeArgs[1].maxFeeUSDCents, config1.maxFeeUSDCents); + assertEq(tokenTransferFeeArgs[1].deciBps, config1.deciBps); + assertEq(tokenTransferFeeArgs[1].destGasOverhead, config1.destGasOverhead); + assertEq(tokenTransferFeeArgs[1].destBytesOverhead, config1.destBytesOverhead); + assertEq(tokenTransferFeeArgs[1].aggregateRateLimitEnabled, config1.aggregateRateLimitEnabled); + assertTrue(config1.isEnabled); + } + + function test__setTokenTransferFeeConfig_byAdmin_Success() public { + EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] memory transferFeeConfig; + vm.startPrank(ADMIN); + + vm.expectEmit(); + emit EVM2EVMOnRamp.TokenTransferFeeConfigSet(transferFeeConfig); + + s_onRamp.setTokenTransferFeeConfig(transferFeeConfig, new address[](0)); + } + + // Reverts + + function test__setTokenTransferFeeConfig_InvalidDestBytesOverhead_Revert() public { + EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] memory transferFeeConfig = + new EVM2EVMOnRamp.TokenTransferFeeConfigArgs[](1); + transferFeeConfig[0].destBytesOverhead = uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) - 1; + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMOnRamp.InvalidDestBytesOverhead.selector, + transferFeeConfig[0].token, + transferFeeConfig[0].destBytesOverhead + ) + ); + s_onRamp.setTokenTransferFeeConfig(transferFeeConfig, new address[](0)); + } + + function test__setTokenTransferFeeConfig_OnlyCallableByOwnerOrAdmin_Revert() public { + EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] memory transferFeeConfig; + vm.startPrank(STRANGER); + + vm.expectRevert(EVM2EVMOnRamp.OnlyCallableByOwnerOrAdmin.selector); + + s_onRamp.setTokenTransferFeeConfig(transferFeeConfig, new address[](0)); + } +} + +contract EVM2EVMOnRamp_getTokenPool is EVM2EVMOnRampSetup { + function test_GetTokenPool_Success() public view { + assertEq( + s_sourcePoolByToken[s_sourceTokens[0]], + address(s_onRamp.getPoolBySourceToken(DEST_CHAIN_SELECTOR, IERC20(s_sourceTokens[0]))) + ); + assertEq( + s_sourcePoolByToken[s_sourceTokens[1]], + address(s_onRamp.getPoolBySourceToken(DEST_CHAIN_SELECTOR, IERC20(s_sourceTokens[1]))) + ); + + address wrongToken = address(123); + address nonExistentPool = address(s_onRamp.getPoolBySourceToken(DEST_CHAIN_SELECTOR, IERC20(wrongToken))); + + assertEq(address(0), nonExistentPool); + } +} + +contract EVM2EVMOnRamp_setDynamicConfig is EVM2EVMOnRampSetup { + function test_SetDynamicConfig_Success() public { + EVM2EVMOnRamp.StaticConfig memory staticConfig = s_onRamp.getStaticConfig(); + EVM2EVMOnRamp.DynamicConfig memory newConfig = EVM2EVMOnRamp.DynamicConfig({ + router: address(2134), + maxNumberOfTokensPerMsg: 14, + destGasOverhead: DEST_GAS_OVERHEAD / 2, + destGasPerPayloadByte: DEST_GAS_PER_PAYLOAD_BYTE / 2, + destDataAvailabilityOverheadGas: DEST_DATA_AVAILABILITY_OVERHEAD_GAS, + destGasPerDataAvailabilityByte: DEST_GAS_PER_DATA_AVAILABILITY_BYTE, + destDataAvailabilityMultiplierBps: DEST_GAS_DATA_AVAILABILITY_MULTIPLIER_BPS, + priceRegistry: address(23423), + maxDataBytes: 400, + maxPerMsgGasLimit: MAX_GAS_LIMIT / 2, + defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, + defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, + defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, + enforceOutOfOrder: false + }); + + vm.expectEmit(); + emit EVM2EVMOnRamp.ConfigSet(staticConfig, newConfig); + + s_onRamp.setDynamicConfig(newConfig); + + EVM2EVMOnRamp.DynamicConfig memory gotDynamicConfig = s_onRamp.getDynamicConfig(); + assertEq(newConfig.router, gotDynamicConfig.router); + assertEq(newConfig.maxNumberOfTokensPerMsg, gotDynamicConfig.maxNumberOfTokensPerMsg); + assertEq(newConfig.destGasOverhead, gotDynamicConfig.destGasOverhead); + assertEq(newConfig.destGasPerPayloadByte, gotDynamicConfig.destGasPerPayloadByte); + assertEq(newConfig.priceRegistry, gotDynamicConfig.priceRegistry); + assertEq(newConfig.maxDataBytes, gotDynamicConfig.maxDataBytes); + assertEq(newConfig.maxPerMsgGasLimit, gotDynamicConfig.maxPerMsgGasLimit); + } + + // Reverts + + function test_SetConfigInvalidConfig_Revert() public { + EVM2EVMOnRamp.DynamicConfig memory newConfig = EVM2EVMOnRamp.DynamicConfig({ + router: address(1), + maxNumberOfTokensPerMsg: 14, + destGasOverhead: DEST_GAS_OVERHEAD / 2, + destGasPerPayloadByte: DEST_GAS_PER_PAYLOAD_BYTE / 2, + destDataAvailabilityOverheadGas: DEST_DATA_AVAILABILITY_OVERHEAD_GAS, + destGasPerDataAvailabilityByte: DEST_GAS_PER_DATA_AVAILABILITY_BYTE, + destDataAvailabilityMultiplierBps: DEST_GAS_DATA_AVAILABILITY_MULTIPLIER_BPS, + priceRegistry: address(23423), + maxDataBytes: 400, + maxPerMsgGasLimit: MAX_GAS_LIMIT / 2, + defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, + defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, + defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, + enforceOutOfOrder: false + }); + + // Invalid price reg reverts. + newConfig.priceRegistry = address(0); + vm.expectRevert(EVM2EVMOnRamp.InvalidConfig.selector); + s_onRamp.setDynamicConfig(newConfig); + + // Succeeds if valid + newConfig.priceRegistry = address(23423); + s_onRamp.setDynamicConfig(newConfig); + } + + function test_SetConfigOnlyOwner_Revert() public { + vm.startPrank(STRANGER); + vm.expectRevert("Only callable by owner"); + s_onRamp.setDynamicConfig(generateDynamicOnRampConfig(address(1), address(2))); + vm.startPrank(ADMIN); + vm.expectRevert("Only callable by owner"); + s_onRamp.setDynamicConfig(generateDynamicOnRampConfig(address(1), address(2))); + } +} diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol new file mode 100644 index 0000000000..6659b1217f --- /dev/null +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IPoolV1} from "../../interfaces/IPool.sol"; + +import {PriceRegistry} from "../../PriceRegistry.sol"; +import {Router} from "../../Router.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {Pool} from "../../libraries/Pool.sol"; +import {EVM2EVMOnRamp} from "../../onRamp/EVM2EVMOnRamp.sol"; +import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {TokenSetup} from "../TokenSetup.t.sol"; +import {EVM2EVMOnRampHelper} from "../helpers/EVM2EVMOnRampHelper.sol"; +import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { + uint256 internal immutable i_tokenAmount0 = 9; + uint256 internal immutable i_tokenAmount1 = 7; + + bytes32 internal s_metadataHash; + + EVM2EVMOnRampHelper internal s_onRamp; + address[] internal s_offRamps; + + address internal s_destTokenPool = makeAddr("destTokenPool"); + address internal s_destToken = makeAddr("destToken"); + + EVM2EVMOnRamp.FeeTokenConfigArgs[] internal s_feeTokenConfigArgs; + EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] internal s_tokenTransferFeeConfigArgs; + + function setUp() public virtual override(TokenSetup, PriceRegistrySetup) { + TokenSetup.setUp(); + PriceRegistrySetup.setUp(); + + s_priceRegistry.updatePrices(getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); + + address WETH = s_sourceRouter.getWrappedNative(); + + s_feeTokenConfigArgs.push( + EVM2EVMOnRamp.FeeTokenConfigArgs({ + token: s_sourceFeeToken, + networkFeeUSDCents: 1_00, // 1 USD + gasMultiplierWeiPerEth: 1e18, // 1x + premiumMultiplierWeiPerEth: 5e17, // 0.5x + enabled: true + }) + ); + s_feeTokenConfigArgs.push( + EVM2EVMOnRamp.FeeTokenConfigArgs({ + token: WETH, + networkFeeUSDCents: 5_00, // 5 USD + gasMultiplierWeiPerEth: 2e18, // 2x + premiumMultiplierWeiPerEth: 2e18, // 2x + enabled: true + }) + ); + + s_tokenTransferFeeConfigArgs.push( + EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ + token: s_sourceFeeToken, + minFeeUSDCents: 1_00, // 1 USD + maxFeeUSDCents: 1000_00, // 1,000 USD + deciBps: 2_5, // 2.5 bps, or 0.025% + destGasOverhead: 40_000, + destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES), + aggregateRateLimitEnabled: true + }) + ); + s_tokenTransferFeeConfigArgs.push( + EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ + token: s_sourceRouter.getWrappedNative(), + minFeeUSDCents: 50, // 0.5 USD + maxFeeUSDCents: 500_00, // 500 USD + deciBps: 5_0, // 5 bps, or 0.05% + destGasOverhead: 10_000, + destBytesOverhead: 100, + aggregateRateLimitEnabled: true + }) + ); + s_tokenTransferFeeConfigArgs.push( + EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ + token: CUSTOM_TOKEN, + minFeeUSDCents: 2_00, // 1 USD + maxFeeUSDCents: 2000_00, // 1,000 USD + deciBps: 10_0, // 10 bps, or 0.1% + destGasOverhead: 1, + destBytesOverhead: 200, + aggregateRateLimitEnabled: true + }) + ); + + s_onRamp = new EVM2EVMOnRampHelper( + EVM2EVMOnRamp.StaticConfig({ + linkToken: s_sourceTokens[0], + chainSelector: SOURCE_CHAIN_SELECTOR, + destChainSelector: DEST_CHAIN_SELECTOR, + defaultTxGasLimit: GAS_LIMIT, + maxNopFeesJuels: MAX_NOP_FEES_JUELS, + prevOnRamp: address(0), + rmnProxy: address(s_mockRMN), + tokenAdminRegistry: address(s_tokenAdminRegistry) + }), + generateDynamicOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)), + getOutboundRateLimiterConfig(), + s_feeTokenConfigArgs, + s_tokenTransferFeeConfigArgs, + getNopsAndWeights() + ); + s_onRamp.setAdmin(ADMIN); + + s_metadataHash = keccak256( + abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, SOURCE_CHAIN_SELECTOR, DEST_CHAIN_SELECTOR, address(s_onRamp)) + ); + + s_offRamps = new address[](2); + s_offRamps[0] = address(10); + s_offRamps[1] = address(11); + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](2); + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: address(s_onRamp)}); + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: s_offRamps[0]}); + offRampUpdates[1] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: s_offRamps[1]}); + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + + // Pre approve the first token so the gas estimates of the tests + // only cover actual gas usage from the ramps + IERC20(s_sourceTokens[0]).approve(address(s_sourceRouter), 2 ** 128); + IERC20(s_sourceTokens[1]).approve(address(s_sourceRouter), 2 ** 128); + } + + function getNopsAndWeights() internal pure returns (EVM2EVMOnRamp.NopAndWeight[] memory) { + EVM2EVMOnRamp.NopAndWeight[] memory nopsAndWeights = new EVM2EVMOnRamp.NopAndWeight[](3); + nopsAndWeights[0] = EVM2EVMOnRamp.NopAndWeight({nop: USER_1, weight: 19284}); + nopsAndWeights[1] = EVM2EVMOnRamp.NopAndWeight({nop: USER_2, weight: 52935}); + nopsAndWeights[2] = EVM2EVMOnRamp.NopAndWeight({nop: USER_3, weight: 8}); + return nopsAndWeights; + } + + function generateDynamicOnRampConfig( + address router, + address priceRegistry + ) internal pure returns (EVM2EVMOnRamp.DynamicConfig memory) { + return EVM2EVMOnRamp.DynamicConfig({ + router: router, + maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, + destGasOverhead: DEST_GAS_OVERHEAD, + destGasPerPayloadByte: DEST_GAS_PER_PAYLOAD_BYTE, + destDataAvailabilityOverheadGas: DEST_DATA_AVAILABILITY_OVERHEAD_GAS, + destGasPerDataAvailabilityByte: DEST_GAS_PER_DATA_AVAILABILITY_BYTE, + destDataAvailabilityMultiplierBps: DEST_GAS_DATA_AVAILABILITY_MULTIPLIER_BPS, + priceRegistry: priceRegistry, + maxDataBytes: MAX_DATA_SIZE, + maxPerMsgGasLimit: MAX_GAS_LIMIT, + defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, + defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, + defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, + enforceOutOfOrder: false + }); + } + + function _generateTokenMessage() public view returns (Client.EVM2AnyMessage memory) { + Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + tokenAmounts[0].amount = i_tokenAmount0; + tokenAmounts[1].amount = i_tokenAmount1; + return Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + } + + function _generateSingleTokenMessage( + address token, + uint256 amount + ) public view returns (Client.EVM2AnyMessage memory) { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({token: token, amount: amount}); + + return Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + } + + function _generateEmptyMessage() public view returns (Client.EVM2AnyMessage memory) { + return Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: new Client.EVMTokenAmount[](0), + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + } + + function _messageToEvent( + Client.EVM2AnyMessage memory message, + uint64 seqNum, + uint64 nonce, + uint256 feeTokenAmount, + address originalSender + ) public view returns (Internal.EVM2EVMMessage memory) { + // Slicing is only available for calldata. So we have to build a new bytes array. + bytes memory args = new bytes(message.extraArgs.length - 4); + for (uint256 i = 4; i < message.extraArgs.length; ++i) { + args[i - 4] = message.extraArgs[i]; + } + uint256 numberOfTokens = message.tokenAmounts.length; + Client.EVMExtraArgsV2 memory extraArgs = _extraArgsFromBytes(bytes4(message.extraArgs), args); + Internal.EVM2EVMMessage memory messageEvent = Internal.EVM2EVMMessage({ + sequenceNumber: seqNum, + feeTokenAmount: feeTokenAmount, + sender: originalSender, + nonce: extraArgs.allowOutOfOrderExecution ? 0 : nonce, + gasLimit: extraArgs.gasLimit, + strict: false, + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + receiver: abi.decode(message.receiver, (address)), + data: message.data, + tokenAmounts: message.tokenAmounts, + sourceTokenData: new bytes[](numberOfTokens), + feeToken: message.feeToken, + messageId: "" + }); + + for (uint256 i = 0; i < numberOfTokens; ++i) { + messageEvent.sourceTokenData[i] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[message.tokenAmounts[i].token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[message.tokenAmounts[i].token]), + extraData: "" + }) + ); + } + + messageEvent.messageId = Internal._hash(messageEvent, s_metadataHash); + return messageEvent; + } + + function _extraArgsFromBytes( + bytes4 sig, + bytes memory extraArgData + ) public pure returns (Client.EVMExtraArgsV2 memory) { + if (sig == Client.EVM_EXTRA_ARGS_V1_TAG) { + Client.EVMExtraArgsV1 memory extraArgsV1 = abi.decode(extraArgData, (Client.EVMExtraArgsV1)); + return Client.EVMExtraArgsV2({gasLimit: extraArgsV1.gasLimit, allowOutOfOrderExecution: false}); + } else if (sig == Client.EVM_EXTRA_ARGS_V2_TAG) { + return abi.decode(extraArgData, (Client.EVMExtraArgsV2)); + } else { + revert("Invalid extraArgs tag"); + } + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool.t.sol new file mode 100644 index 0000000000..290c4ae153 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool.t.sol @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {Pool} from "../../libraries/Pool.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {BurnFromMintTokenPool} from "../../pools/BurnFromMintTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {BaseTest} from "../BaseTest.t.sol"; +import {BurnMintSetup} from "./BurnMintSetup.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract BurnFromMintTokenPoolSetup is BurnMintSetup { + BurnFromMintTokenPool internal s_pool; + + function setUp() public virtual override { + BurnMintSetup.setUp(); + + s_pool = new BurnFromMintTokenPool(s_burnMintERC677, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + s_burnMintERC677.grantMintAndBurnRoles(address(s_pool)); + + _applyChainUpdates(address(s_pool)); + } +} + +contract BurnFromMintTokenPool_lockOrBurn is BurnFromMintTokenPoolSetup { + function test_Setup_Success() public view { + assertEq(address(s_burnMintERC677), address(s_pool.getToken())); + assertEq(address(s_mockRMN), s_pool.getRmnProxy()); + assertEq(false, s_pool.getAllowListEnabled()); + assertEq(type(uint256).max, s_burnMintERC677.allowance(address(s_pool), address(s_pool))); + assertEq("BurnFromMintTokenPool 1.5.0-dev", s_pool.typeAndVersion()); + } + + function test_PoolBurn_Success() public { + uint256 burnAmount = 20_000e18; + + deal(address(s_burnMintERC677), address(s_pool), burnAmount); + assertEq(s_burnMintERC677.balanceOf(address(s_pool)), burnAmount); + + vm.startPrank(s_burnMintOnRamp); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(burnAmount); + + vm.expectEmit(); + emit IERC20.Transfer(address(s_pool), address(0), burnAmount); + + vm.expectEmit(); + emit TokenPool.Burned(address(s_burnMintOnRamp), burnAmount); + + bytes4 expectedSignature = bytes4(keccak256("burnFrom(address,uint256)")); + vm.expectCall(address(s_burnMintERC677), abi.encodeWithSelector(expectedSignature, address(s_pool), burnAmount)); + + s_pool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: bytes(""), + amount: burnAmount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_burnMintERC677) + }) + ); + + assertEq(s_burnMintERC677.balanceOf(address(s_pool)), 0); + } + + // Should not burn tokens if cursed. + function test_PoolBurnRevertNotHealthy_Revert() public { + s_mockRMN.setGlobalCursed(true); + uint256 before = s_burnMintERC677.balanceOf(address(s_pool)); + vm.startPrank(s_burnMintOnRamp); + + vm.expectRevert(TokenPool.CursedByRMN.selector); + s_pool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: bytes(""), + amount: 1e5, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_burnMintERC677) + }) + ); + + assertEq(s_burnMintERC677.balanceOf(address(s_pool)), before); + } + + function test_ChainNotAllowed_Revert() public { + uint64 wrongChainSelector = 8838833; + vm.expectRevert(abi.encodeWithSelector(TokenPool.ChainNotAllowed.selector, wrongChainSelector)); + s_pool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: bytes(""), + receiver: OWNER, + amount: 1, + localToken: address(s_burnMintERC677), + remoteChainSelector: wrongChainSelector, + sourcePoolAddress: generateSourceTokenData().sourcePoolAddress, + sourcePoolData: generateSourceTokenData().extraData, + offchainTokenData: "" + }) + ); + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/BurnMintSetup.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnMintSetup.t.sol new file mode 100644 index 0000000000..a39fd1bb9f --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/BurnMintSetup.t.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; +import {Router} from "../../Router.sol"; +import {BurnMintTokenPool} from "../../pools/BurnMintTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {RouterSetup} from "../router/RouterSetup.t.sol"; + +contract BurnMintSetup is RouterSetup { + BurnMintERC677 internal s_burnMintERC677; + address internal s_burnMintOffRamp = makeAddr("burn_mint_offRamp"); + address internal s_burnMintOnRamp = makeAddr("burn_mint_onRamp"); + + address internal s_remoteBurnMintPool = makeAddr("remote_burn_mint_pool"); + address internal s_remoteToken = makeAddr("remote_token"); + + function setUp() public virtual override { + RouterSetup.setUp(); + + s_burnMintERC677 = new BurnMintERC677("Chainlink Token", "LINK", 18, 0); + } + + function _applyChainUpdates(address pool) internal { + TokenPool.ChainUpdate[] memory chains = new TokenPool.ChainUpdate[](1); + chains[0] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(s_remoteBurnMintPool), + remoteTokenAddress: abi.encode(s_remoteToken), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + + BurnMintTokenPool(pool).applyChainUpdates(chains); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_burnMintOnRamp}); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: DEST_CHAIN_SELECTOR, offRamp: s_burnMintOffRamp}); + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol new file mode 100644 index 0000000000..c628c510d4 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IPoolV1} from "../../interfaces/IPool.sol"; + +import {Internal} from "../../libraries/Internal.sol"; +import {Pool} from "../../libraries/Pool.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; +import {BurnMintTokenPool} from "../../pools/BurnMintTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {BaseTest} from "../BaseTest.t.sol"; +import {BurnMintSetup} from "./BurnMintSetup.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract BurnMintTokenPoolSetup is BurnMintSetup { + BurnMintTokenPool internal s_pool; + + function setUp() public virtual override { + BurnMintSetup.setUp(); + + s_pool = new BurnMintTokenPool(s_burnMintERC677, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + s_burnMintERC677.grantMintAndBurnRoles(address(s_pool)); + + _applyChainUpdates(address(s_pool)); + } +} + +contract BurnMintTokenPool_lockOrBurn is BurnMintTokenPoolSetup { + function test_Setup_Success() public view { + assertEq(address(s_burnMintERC677), address(s_pool.getToken())); + assertEq(address(s_mockRMN), s_pool.getRmnProxy()); + assertEq(false, s_pool.getAllowListEnabled()); + assertEq("BurnMintTokenPool 1.5.0-dev", s_pool.typeAndVersion()); + } + + function test_PoolBurn_Success() public { + uint256 burnAmount = 20_000e18; + + deal(address(s_burnMintERC677), address(s_pool), burnAmount); + assertEq(s_burnMintERC677.balanceOf(address(s_pool)), burnAmount); + + vm.startPrank(s_burnMintOnRamp); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(burnAmount); + + vm.expectEmit(); + emit IERC20.Transfer(address(s_pool), address(0), burnAmount); + + vm.expectEmit(); + emit TokenPool.Burned(address(s_burnMintOnRamp), burnAmount); + + bytes4 expectedSignature = bytes4(keccak256("burn(uint256)")); + vm.expectCall(address(s_burnMintERC677), abi.encodeWithSelector(expectedSignature, burnAmount)); + + s_pool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: bytes(""), + amount: burnAmount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_burnMintERC677) + }) + ); + + assertEq(s_burnMintERC677.balanceOf(address(s_pool)), 0); + } + + // Should not burn tokens if cursed. + function test_PoolBurnRevertNotHealthy_Revert() public { + s_mockRMN.setGlobalCursed(true); + uint256 before = s_burnMintERC677.balanceOf(address(s_pool)); + vm.startPrank(s_burnMintOnRamp); + + vm.expectRevert(TokenPool.CursedByRMN.selector); + s_pool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: bytes(""), + amount: 1e5, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_burnMintERC677) + }) + ); + + assertEq(s_burnMintERC677.balanceOf(address(s_pool)), before); + } + + function test_ChainNotAllowed_Revert() public { + uint64 wrongChainSelector = 8838833; + + vm.expectRevert(abi.encodeWithSelector(TokenPool.ChainNotAllowed.selector, wrongChainSelector)); + s_pool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: bytes(""), + amount: 1, + remoteChainSelector: wrongChainSelector, + localToken: address(s_burnMintERC677) + }) + ); + } +} + +contract BurnMintTokenPool_releaseOrMint is BurnMintTokenPoolSetup { + function test_PoolMint_Success() public { + uint256 amount = 1e19; + + vm.startPrank(s_burnMintOffRamp); + + vm.expectEmit(); + emit IERC20.Transfer(address(0), address(s_burnMintOffRamp), amount); + s_pool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: bytes(""), + receiver: OWNER, + amount: amount, + localToken: address(s_burnMintERC677), + remoteChainSelector: DEST_CHAIN_SELECTOR, + sourcePoolAddress: abi.encode(s_remoteBurnMintPool), + sourcePoolData: "", + offchainTokenData: "" + }) + ); + + assertEq(s_burnMintERC677.balanceOf(s_burnMintOffRamp), amount); + } + + function test_PoolMintNotHealthy_Revert() public { + // Should not mint tokens if cursed. + s_mockRMN.setGlobalCursed(true); + uint256 before = s_burnMintERC677.balanceOf(OWNER); + vm.startPrank(s_burnMintOffRamp); + + vm.expectRevert(TokenPool.CursedByRMN.selector); + s_pool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: bytes(""), + receiver: OWNER, + amount: 1e5, + localToken: address(s_burnMintERC677), + remoteChainSelector: DEST_CHAIN_SELECTOR, + sourcePoolAddress: generateSourceTokenData().sourcePoolAddress, + sourcePoolData: generateSourceTokenData().extraData, + offchainTokenData: "" + }) + ); + + assertEq(s_burnMintERC677.balanceOf(OWNER), before); + } + + function test_ChainNotAllowed_Revert() public { + uint64 wrongChainSelector = 8838833; + + vm.expectRevert(abi.encodeWithSelector(TokenPool.ChainNotAllowed.selector, wrongChainSelector)); + s_pool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: bytes(""), + receiver: OWNER, + amount: 1, + localToken: address(s_burnMintERC677), + remoteChainSelector: wrongChainSelector, + sourcePoolAddress: generateSourceTokenData().sourcePoolAddress, + sourcePoolData: generateSourceTokenData().extraData, + offchainTokenData: "" + }) + ); + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool.t.sol new file mode 100644 index 0000000000..22362ee4a5 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool.t.sol @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {Pool} from "../../libraries/Pool.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {BurnWithFromMintTokenPool} from "../../pools/BurnWithFromMintTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {BaseTest} from "../BaseTest.t.sol"; +import {BurnMintSetup} from "./BurnMintSetup.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract BurnWithFromMintTokenPoolSetup is BurnMintSetup { + BurnWithFromMintTokenPool internal s_pool; + + function setUp() public virtual override { + BurnMintSetup.setUp(); + + s_pool = + new BurnWithFromMintTokenPool(s_burnMintERC677, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + s_burnMintERC677.grantMintAndBurnRoles(address(s_pool)); + + _applyChainUpdates(address(s_pool)); + } +} + +contract BurnWithFromMintTokenPool_lockOrBurn is BurnWithFromMintTokenPoolSetup { + function test_Setup_Success() public view { + assertEq(address(s_burnMintERC677), address(s_pool.getToken())); + assertEq(address(s_mockRMN), s_pool.getRmnProxy()); + assertEq(false, s_pool.getAllowListEnabled()); + assertEq(type(uint256).max, s_burnMintERC677.allowance(address(s_pool), address(s_pool))); + assertEq("BurnWithFromMintTokenPool 1.5.0-dev", s_pool.typeAndVersion()); + } + + function test_PoolBurn_Success() public { + uint256 burnAmount = 20_000e18; + + deal(address(s_burnMintERC677), address(s_pool), burnAmount); + assertEq(s_burnMintERC677.balanceOf(address(s_pool)), burnAmount); + + vm.startPrank(s_burnMintOnRamp); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(burnAmount); + + vm.expectEmit(); + emit IERC20.Transfer(address(s_pool), address(0), burnAmount); + + vm.expectEmit(); + emit TokenPool.Burned(address(s_burnMintOnRamp), burnAmount); + + bytes4 expectedSignature = bytes4(keccak256("burn(address,uint256)")); + vm.expectCall(address(s_burnMintERC677), abi.encodeWithSelector(expectedSignature, address(s_pool), burnAmount)); + + s_pool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: bytes(""), + amount: burnAmount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_burnMintERC677) + }) + ); + + assertEq(s_burnMintERC677.balanceOf(address(s_pool)), 0); + } + + // Should not burn tokens if cursed. + function test_PoolBurnRevertNotHealthy_Revert() public { + s_mockRMN.setGlobalCursed(true); + uint256 before = s_burnMintERC677.balanceOf(address(s_pool)); + vm.startPrank(s_burnMintOnRamp); + + vm.expectRevert(TokenPool.CursedByRMN.selector); + s_pool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: bytes(""), + amount: 1e5, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_burnMintERC677) + }) + ); + + assertEq(s_burnMintERC677.balanceOf(address(s_pool)), before); + } + + function test_ChainNotAllowed_Revert() public { + uint64 wrongChainSelector = 8838833; + vm.expectRevert(abi.encodeWithSelector(TokenPool.ChainNotAllowed.selector, wrongChainSelector)); + s_pool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: bytes(""), + receiver: OWNER, + amount: 1, + localToken: address(s_burnMintERC677), + remoteChainSelector: wrongChainSelector, + sourcePoolAddress: generateSourceTokenData().sourcePoolAddress, + sourcePoolData: generateSourceTokenData().extraData, + offchainTokenData: "" + }) + ); + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol new file mode 100644 index 0000000000..97d0d4e894 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol @@ -0,0 +1,512 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IPoolV1} from "../../interfaces/IPool.sol"; + +import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; +import {Router} from "../../Router.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {Pool} from "../../libraries/Pool.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; +import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {BaseTest} from "../BaseTest.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; +import {RouterSetup} from "../router/RouterSetup.t.sol"; + +contract LockReleaseTokenPoolSetup is RouterSetup { + IERC20 internal s_token; + LockReleaseTokenPool internal s_lockReleaseTokenPool; + LockReleaseTokenPool internal s_lockReleaseTokenPoolWithAllowList; + address[] internal s_allowedList; + + address internal s_allowedOnRamp = address(123); + address internal s_allowedOffRamp = address(234); + + address internal s_destPoolAddress = address(2736782345); + address internal s_sourcePoolAddress = address(53852352095); + + function setUp() public virtual override { + RouterSetup.setUp(); + s_token = new BurnMintERC677("LINK", "LNK", 18, 0); + deal(address(s_token), OWNER, type(uint256).max); + s_lockReleaseTokenPool = + new LockReleaseTokenPool(s_token, new address[](0), address(s_mockRMN), true, address(s_sourceRouter)); + + s_allowedList.push(USER_1); + s_allowedList.push(DUMMY_CONTRACT_ADDRESS); + s_lockReleaseTokenPoolWithAllowList = + new LockReleaseTokenPool(s_token, s_allowedList, address(s_mockRMN), true, address(s_sourceRouter)); + + TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(s_destPoolAddress), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + + s_lockReleaseTokenPool.applyChainUpdates(chainUpdate); + s_lockReleaseTokenPoolWithAllowList.applyChainUpdates(chainUpdate); + s_lockReleaseTokenPool.setRebalancer(OWNER); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_allowedOnRamp}); + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: s_allowedOffRamp}); + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } +} + +contract LockReleaseTokenPool_setRebalancer is LockReleaseTokenPoolSetup { + function test_SetRebalancer_Success() public { + assertEq(address(s_lockReleaseTokenPool.getRebalancer()), OWNER); + s_lockReleaseTokenPool.setRebalancer(STRANGER); + assertEq(address(s_lockReleaseTokenPool.getRebalancer()), STRANGER); + } + + function test_SetRebalancer_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert("Only callable by owner"); + s_lockReleaseTokenPool.setRebalancer(STRANGER); + } +} + +contract LockReleaseTokenPool_lockOrBurn is LockReleaseTokenPoolSetup { + function test_Fuzz_LockOrBurnNoAllowList_Success(uint256 amount) public { + amount = bound(amount, 1, getOutboundRateLimiterConfig().capacity); + vm.startPrank(s_allowedOnRamp); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(amount); + vm.expectEmit(); + emit TokenPool.Locked(s_allowedOnRamp, amount); + + s_lockReleaseTokenPool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: STRANGER, + receiver: bytes(""), + amount: amount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + } + + function test_LockOrBurnWithAllowList_Success() public { + uint256 amount = 100; + vm.startPrank(s_allowedOnRamp); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(amount); + vm.expectEmit(); + emit TokenPool.Locked(s_allowedOnRamp, amount); + + s_lockReleaseTokenPoolWithAllowList.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: s_allowedList[0], + receiver: bytes(""), + amount: amount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + + vm.expectEmit(); + emit TokenPool.Locked(s_allowedOnRamp, amount); + + s_lockReleaseTokenPoolWithAllowList.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: s_allowedList[1], + receiver: bytes(""), + amount: amount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + } + + function test_LockOrBurnWithAllowList_Revert() public { + vm.startPrank(s_allowedOnRamp); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.SenderNotAllowed.selector, STRANGER)); + + s_lockReleaseTokenPoolWithAllowList.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: STRANGER, + receiver: bytes(""), + amount: 100, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + } + + function test_PoolBurnRevertNotHealthy_Revert() public { + // Should not burn tokens if cursed. + s_mockRMN.setGlobalCursed(true); + uint256 before = s_token.balanceOf(address(s_lockReleaseTokenPoolWithAllowList)); + + vm.startPrank(s_allowedOnRamp); + vm.expectRevert(TokenPool.CursedByRMN.selector); + + s_lockReleaseTokenPoolWithAllowList.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: s_allowedList[0], + receiver: bytes(""), + amount: 1e5, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + + assertEq(s_token.balanceOf(address(s_lockReleaseTokenPoolWithAllowList)), before); + } +} + +contract LockReleaseTokenPool_releaseOrMint is LockReleaseTokenPoolSetup { + function setUp() public virtual override { + LockReleaseTokenPoolSetup.setUp(); + TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(s_sourcePoolAddress), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + + s_lockReleaseTokenPool.applyChainUpdates(chainUpdate); + s_lockReleaseTokenPoolWithAllowList.applyChainUpdates(chainUpdate); + } + + function test_ReleaseOrMint_Success() public { + vm.startPrank(s_allowedOffRamp); + + uint256 amount = 100; + deal(address(s_token), address(s_lockReleaseTokenPool), amount); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(amount); + vm.expectEmit(); + emit TokenPool.Released(s_allowedOffRamp, OWNER, amount); + + s_lockReleaseTokenPool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: bytes(""), + receiver: OWNER, + amount: amount, + localToken: address(s_token), + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: abi.encode(s_sourcePoolAddress), + sourcePoolData: "", + offchainTokenData: "" + }) + ); + } + + function test_Fuzz_ReleaseOrMint_Success(address recipient, uint256 amount) public { + // Since the owner already has tokens this would break the checks + vm.assume(recipient != OWNER); + vm.assume(recipient != address(0)); + vm.assume(recipient != address(s_token)); + + // Makes sure the pool always has enough funds + deal(address(s_token), address(s_lockReleaseTokenPool), amount); + vm.startPrank(s_allowedOffRamp); + + uint256 capacity = getInboundRateLimiterConfig().capacity; + // Determine if we hit the rate limit or the txs should succeed. + if (amount > capacity) { + vm.expectRevert( + abi.encodeWithSelector(RateLimiter.TokenMaxCapacityExceeded.selector, capacity, amount, address(s_token)) + ); + } else { + // Only rate limit if the amount is >0 + if (amount > 0) { + vm.expectEmit(); + emit RateLimiter.TokensConsumed(amount); + } + + vm.expectEmit(); + emit TokenPool.Released(s_allowedOffRamp, recipient, amount); + } + + s_lockReleaseTokenPool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: bytes(""), + receiver: recipient, + amount: amount, + localToken: address(s_token), + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: abi.encode(s_sourcePoolAddress), + sourcePoolData: "", + offchainTokenData: "" + }) + ); + } + + function test_ChainNotAllowed_Revert() public { + address notAllowedRemotePoolAddress = address(1); + + TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(notAllowedRemotePoolAddress), + remoteTokenAddress: abi.encode(address(2)), + allowed: false, + outboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}), + inboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}) + }); + + s_lockReleaseTokenPool.applyChainUpdates(chainUpdate); + + vm.startPrank(s_allowedOffRamp); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.ChainNotAllowed.selector, SOURCE_CHAIN_SELECTOR)); + s_lockReleaseTokenPool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: bytes(""), + receiver: OWNER, + amount: 1e5, + localToken: address(s_token), + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: abi.encode(s_sourcePoolAddress), + sourcePoolData: "", + offchainTokenData: "" + }) + ); + } + + function test_PoolMintNotHealthy_Revert() public { + // Should not mint tokens if cursed. + s_mockRMN.setGlobalCursed(true); + uint256 before = s_token.balanceOf(OWNER); + vm.startPrank(s_allowedOffRamp); + vm.expectRevert(TokenPool.CursedByRMN.selector); + s_lockReleaseTokenPool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: bytes(""), + receiver: OWNER, + amount: 1e5, + localToken: address(s_token), + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: generateSourceTokenData().sourcePoolAddress, + sourcePoolData: generateSourceTokenData().extraData, + offchainTokenData: "" + }) + ); + + assertEq(s_token.balanceOf(OWNER), before); + } +} + +contract LockReleaseTokenPool_canAcceptLiquidity is LockReleaseTokenPoolSetup { + function test_CanAcceptLiquidity_Success() public { + assertEq(true, s_lockReleaseTokenPool.canAcceptLiquidity()); + + s_lockReleaseTokenPool = + new LockReleaseTokenPool(s_token, new address[](0), address(s_mockRMN), false, address(s_sourceRouter)); + assertEq(false, s_lockReleaseTokenPool.canAcceptLiquidity()); + } +} + +contract LockReleaseTokenPool_provideLiquidity is LockReleaseTokenPoolSetup { + function test_Fuzz_ProvideLiquidity_Success(uint256 amount) public { + uint256 balancePre = s_token.balanceOf(OWNER); + s_token.approve(address(s_lockReleaseTokenPool), amount); + + s_lockReleaseTokenPool.provideLiquidity(amount); + + assertEq(s_token.balanceOf(OWNER), balancePre - amount); + assertEq(s_token.balanceOf(address(s_lockReleaseTokenPool)), amount); + } + + // Reverts + + function test_Unauthorized_Revert() public { + vm.startPrank(STRANGER); + vm.expectRevert(abi.encodeWithSelector(LockReleaseTokenPool.Unauthorized.selector, STRANGER)); + + s_lockReleaseTokenPool.provideLiquidity(1); + } + + function test_Fuzz_ExceedsAllowance(uint256 amount) public { + vm.assume(amount > 0); + vm.expectRevert("ERC20: insufficient allowance"); + s_lockReleaseTokenPool.provideLiquidity(amount); + } + + function test_LiquidityNotAccepted_Revert() public { + s_lockReleaseTokenPool = + new LockReleaseTokenPool(s_token, new address[](0), address(s_mockRMN), false, address(s_sourceRouter)); + + vm.expectRevert(LockReleaseTokenPool.LiquidityNotAccepted.selector); + s_lockReleaseTokenPool.provideLiquidity(1); + } +} + +contract LockReleaseTokenPool_withdrawalLiquidity is LockReleaseTokenPoolSetup { + function test_Fuzz_WithdrawalLiquidity_Success(uint256 amount) public { + uint256 balancePre = s_token.balanceOf(OWNER); + s_token.approve(address(s_lockReleaseTokenPool), amount); + s_lockReleaseTokenPool.provideLiquidity(amount); + + s_lockReleaseTokenPool.withdrawLiquidity(amount); + + assertEq(s_token.balanceOf(OWNER), balancePre); + } + + // Reverts + + function test_Unauthorized_Revert() public { + vm.startPrank(STRANGER); + vm.expectRevert(abi.encodeWithSelector(LockReleaseTokenPool.Unauthorized.selector, STRANGER)); + + s_lockReleaseTokenPool.withdrawLiquidity(1); + } + + function test_InsufficientLiquidity_Revert() public { + uint256 maxUint256 = 2 ** 256 - 1; + s_token.approve(address(s_lockReleaseTokenPool), maxUint256); + s_lockReleaseTokenPool.provideLiquidity(maxUint256); + + vm.startPrank(address(s_lockReleaseTokenPool)); + s_token.transfer(OWNER, maxUint256); + vm.startPrank(OWNER); + + vm.expectRevert(LockReleaseTokenPool.InsufficientLiquidity.selector); + s_lockReleaseTokenPool.withdrawLiquidity(1); + } +} + +contract LockReleaseTokenPool_supportsInterface is LockReleaseTokenPoolSetup { + function test_SupportsInterface_Success() public view { + assertTrue(s_lockReleaseTokenPool.supportsInterface(type(IPoolV1).interfaceId)); + assertTrue(s_lockReleaseTokenPool.supportsInterface(type(IERC165).interfaceId)); + } +} + +contract LockReleaseTokenPool_setChainRateLimiterConfig is LockReleaseTokenPoolSetup { + uint64 internal s_remoteChainSelector; + + function setUp() public virtual override { + LockReleaseTokenPoolSetup.setUp(); + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + s_remoteChainSelector = 123124; + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: s_remoteChainSelector, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_lockReleaseTokenPool.applyChainUpdates(chainUpdates); + } + + function test_Fuzz_SetChainRateLimiterConfig_Success(uint128 capacity, uint128 rate, uint32 newTime) public { + // Cap the lower bound to 4 so 4/2 is still >= 2 + vm.assume(capacity >= 4); + // Cap the lower bound to 2 so 2/2 is still >= 1 + rate = uint128(bound(rate, 2, capacity - 2)); + // Bucket updates only work on increasing time + newTime = uint32(bound(newTime, block.timestamp + 1, type(uint32).max)); + vm.warp(newTime); + + uint256 oldOutboundTokens = s_lockReleaseTokenPool.getCurrentOutboundRateLimiterState(s_remoteChainSelector).tokens; + uint256 oldInboundTokens = s_lockReleaseTokenPool.getCurrentInboundRateLimiterState(s_remoteChainSelector).tokens; + + RateLimiter.Config memory newOutboundConfig = RateLimiter.Config({isEnabled: true, capacity: capacity, rate: rate}); + RateLimiter.Config memory newInboundConfig = + RateLimiter.Config({isEnabled: true, capacity: capacity / 2, rate: rate / 2}); + + vm.expectEmit(); + emit RateLimiter.ConfigChanged(newOutboundConfig); + vm.expectEmit(); + emit RateLimiter.ConfigChanged(newInboundConfig); + vm.expectEmit(); + emit TokenPool.ChainConfigured(s_remoteChainSelector, newOutboundConfig, newInboundConfig); + + s_lockReleaseTokenPool.setChainRateLimiterConfig(s_remoteChainSelector, newOutboundConfig, newInboundConfig); + + uint256 expectedTokens = RateLimiter._min(newOutboundConfig.capacity, oldOutboundTokens); + + RateLimiter.TokenBucket memory bucket = + s_lockReleaseTokenPool.getCurrentOutboundRateLimiterState(s_remoteChainSelector); + assertEq(bucket.capacity, newOutboundConfig.capacity); + assertEq(bucket.rate, newOutboundConfig.rate); + assertEq(bucket.tokens, expectedTokens); + assertEq(bucket.lastUpdated, newTime); + + expectedTokens = RateLimiter._min(newInboundConfig.capacity, oldInboundTokens); + + bucket = s_lockReleaseTokenPool.getCurrentInboundRateLimiterState(s_remoteChainSelector); + assertEq(bucket.capacity, newInboundConfig.capacity); + assertEq(bucket.rate, newInboundConfig.rate); + assertEq(bucket.tokens, expectedTokens); + assertEq(bucket.lastUpdated, newTime); + } + + function test_OnlyOwnerOrRateLimitAdmin_Revert() public { + address rateLimiterAdmin = address(28973509103597907); + + s_lockReleaseTokenPool.setRateLimitAdmin(rateLimiterAdmin); + + vm.startPrank(rateLimiterAdmin); + + s_lockReleaseTokenPool.setChainRateLimiterConfig( + s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() + ); + + vm.startPrank(OWNER); + + s_lockReleaseTokenPool.setChainRateLimiterConfig( + s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() + ); + } + + // Reverts + + function test_OnlyOwner_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert(abi.encodeWithSelector(LockReleaseTokenPool.Unauthorized.selector, STRANGER)); + s_lockReleaseTokenPool.setChainRateLimiterConfig( + s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() + ); + } + + function test_NonExistentChain_Revert() public { + uint64 wrongChainSelector = 9084102894; + + vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, wrongChainSelector)); + s_lockReleaseTokenPool.setChainRateLimiterConfig( + wrongChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() + ); + } +} + +contract LockReleaseTokenPool_setRateLimitAdmin is LockReleaseTokenPoolSetup { + function test_SetRateLimitAdmin_Success() public { + assertEq(address(0), s_lockReleaseTokenPool.getRateLimitAdmin()); + s_lockReleaseTokenPool.setRateLimitAdmin(OWNER); + assertEq(OWNER, s_lockReleaseTokenPool.getRateLimitAdmin()); + } + + // Reverts + + function test_SetRateLimitAdmin_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert("Only callable by owner"); + s_lockReleaseTokenPool.setRateLimitAdmin(STRANGER); + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool.t.sol new file mode 100644 index 0000000000..e5eb04b741 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool.t.sol @@ -0,0 +1,767 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; +import {Router} from "../../Router.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {BaseTest} from "../BaseTest.t.sol"; +import {TokenPoolHelper} from "../helpers/TokenPoolHelper.sol"; +import {RouterSetup} from "../router/RouterSetup.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract TokenPoolSetup is RouterSetup { + IERC20 internal s_token; + TokenPoolHelper internal s_tokenPool; + + function setUp() public virtual override { + RouterSetup.setUp(); + s_token = new BurnMintERC677("LINK", "LNK", 18, 0); + deal(address(s_token), OWNER, type(uint256).max); + + s_tokenPool = new TokenPoolHelper(s_token, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + } +} + +contract TokenPool_constructor is TokenPoolSetup { + function test_immutableFields_Success() public view { + assertEq(address(s_token), address(s_tokenPool.getToken())); + assertEq(address(s_mockRMN), s_tokenPool.getRmnProxy()); + assertEq(false, s_tokenPool.getAllowListEnabled()); + assertEq(address(s_sourceRouter), s_tokenPool.getRouter()); + } + + // Reverts + function test_ZeroAddressNotAllowed_Revert() public { + vm.expectRevert(TokenPool.ZeroAddressNotAllowed.selector); + + s_tokenPool = new TokenPoolHelper(IERC20(address(0)), new address[](0), address(s_mockRMN), address(s_sourceRouter)); + } +} + +contract TokenPool_getRemotePool is TokenPoolSetup { + function test_getRemotePool_Success() public { + uint64 chainSelector = 123124; + address remotePool = makeAddr("remotePool"); + address remoteToken = makeAddr("remoteToken"); + + // Zero indicates nothing is set + assertEq(0, s_tokenPool.getRemotePool(chainSelector).length); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + remotePoolAddress: abi.encode(remotePool), + remoteTokenAddress: abi.encode(remoteToken), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_tokenPool.applyChainUpdates(chainUpdates); + + assertEq(remotePool, abi.decode(s_tokenPool.getRemotePool(chainSelector), (address))); + } +} + +contract TokenPool_setRemotePool is TokenPoolSetup { + function test_setRemotePool_Success() public { + uint64 chainSelector = DEST_CHAIN_SELECTOR; + address initialPool = makeAddr("remotePool"); + address remoteToken = makeAddr("remoteToken"); + // The new pool is a non-evm pool, as it doesn't fit in the normal 160 bits + bytes memory newPool = abi.encode(type(uint256).max); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + remotePoolAddress: abi.encode(initialPool), + remoteTokenAddress: abi.encode(remoteToken), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_tokenPool.applyChainUpdates(chainUpdates); + + vm.expectEmit(); + emit TokenPool.RemotePoolSet(chainSelector, abi.encode(initialPool), newPool); + + s_tokenPool.setRemotePool(chainSelector, newPool); + + assertEq(keccak256(newPool), keccak256(s_tokenPool.getRemotePool(chainSelector))); + } + + // Reverts + + function test_setRemotePool_NonExistentChain_Reverts() public { + uint64 chainSelector = 123124; + bytes memory remotePool = abi.encode(makeAddr("remotePool")); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, chainSelector)); + s_tokenPool.setRemotePool(chainSelector, remotePool); + } + + function test_setRemotePool_OnlyOwner_Reverts() public { + vm.startPrank(STRANGER); + + vm.expectRevert("Only callable by owner"); + s_tokenPool.setRemotePool(123124, abi.encode(makeAddr("remotePool"))); + } +} + +contract TokenPool_applyChainUpdates is TokenPoolSetup { + function assertState(TokenPool.ChainUpdate[] memory chainUpdates) public view { + uint64[] memory chainSelectors = s_tokenPool.getSupportedChains(); + for (uint256 i = 0; i < chainUpdates.length; i++) { + assertEq(chainUpdates[i].remoteChainSelector, chainSelectors[i]); + } + + for (uint256 i = 0; i < chainUpdates.length; ++i) { + assertTrue(s_tokenPool.isSupportedChain(chainUpdates[i].remoteChainSelector)); + RateLimiter.TokenBucket memory bkt = + s_tokenPool.getCurrentOutboundRateLimiterState(chainUpdates[i].remoteChainSelector); + assertEq(bkt.capacity, chainUpdates[i].outboundRateLimiterConfig.capacity); + assertEq(bkt.rate, chainUpdates[i].outboundRateLimiterConfig.rate); + assertEq(bkt.isEnabled, chainUpdates[i].outboundRateLimiterConfig.isEnabled); + + bkt = s_tokenPool.getCurrentInboundRateLimiterState(chainUpdates[i].remoteChainSelector); + assertEq(bkt.capacity, chainUpdates[i].inboundRateLimiterConfig.capacity); + assertEq(bkt.rate, chainUpdates[i].inboundRateLimiterConfig.rate); + assertEq(bkt.isEnabled, chainUpdates[i].inboundRateLimiterConfig.isEnabled); + } + } + + function test_applyChainUpdates_Success() public { + RateLimiter.Config memory outboundRateLimit1 = RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e18}); + RateLimiter.Config memory inboundRateLimit1 = RateLimiter.Config({isEnabled: true, capacity: 100e29, rate: 1e19}); + RateLimiter.Config memory outboundRateLimit2 = RateLimiter.Config({isEnabled: true, capacity: 100e26, rate: 1e16}); + RateLimiter.Config memory inboundRateLimit2 = RateLimiter.Config({isEnabled: true, capacity: 100e27, rate: 1e17}); + + // EVM chain, which uses the 160 bit evm address space + uint64 evmChainSelector = 1; + bytes memory evmRemotePool = abi.encode(makeAddr("evm_remote_pool")); + bytes memory evmRemoteToken = abi.encode(makeAddr("evm_remote_token")); + + // Non EVM chain, which uses the full 256 bits + uint64 nonEvmChainSelector = type(uint64).max; + bytes memory nonEvmRemotePool = abi.encode(keccak256("non_evm_remote_pool")); + bytes memory nonEvmRemoteToken = abi.encode(keccak256("non_evm_remote_token")); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: evmChainSelector, + remotePoolAddress: evmRemotePool, + remoteTokenAddress: evmRemoteToken, + allowed: true, + outboundRateLimiterConfig: outboundRateLimit1, + inboundRateLimiterConfig: inboundRateLimit1 + }); + chainUpdates[1] = TokenPool.ChainUpdate({ + remoteChainSelector: nonEvmChainSelector, + remotePoolAddress: nonEvmRemotePool, + remoteTokenAddress: nonEvmRemoteToken, + allowed: true, + outboundRateLimiterConfig: outboundRateLimit2, + inboundRateLimiterConfig: inboundRateLimit2 + }); + + // Assert configuration is applied + vm.expectEmit(); + emit TokenPool.ChainAdded( + chainUpdates[0].remoteChainSelector, + chainUpdates[0].remoteTokenAddress, + chainUpdates[0].outboundRateLimiterConfig, + chainUpdates[0].inboundRateLimiterConfig + ); + vm.expectEmit(); + emit TokenPool.ChainAdded( + chainUpdates[1].remoteChainSelector, + chainUpdates[1].remoteTokenAddress, + chainUpdates[1].outboundRateLimiterConfig, + chainUpdates[1].inboundRateLimiterConfig + ); + s_tokenPool.applyChainUpdates(chainUpdates); + // on1: rateLimit1, on2: rateLimit2, off1: rateLimit1, off2: rateLimit3 + assertState(chainUpdates); + + // Removing an non-existent chain should revert + TokenPool.ChainUpdate[] memory chainRemoves = new TokenPool.ChainUpdate[](1); + uint64 strangerChainSelector = 120938; + chainRemoves[0] = TokenPool.ChainUpdate({ + remoteChainSelector: strangerChainSelector, + remotePoolAddress: evmRemotePool, + remoteTokenAddress: evmRemoteToken, + allowed: false, + outboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}), + inboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}) + }); + vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, strangerChainSelector)); + s_tokenPool.applyChainUpdates(chainRemoves); + // State remains + assertState(chainUpdates); + + // Can remove a chain + chainRemoves[0].remoteChainSelector = evmChainSelector; + + vm.expectEmit(); + emit TokenPool.ChainRemoved(chainRemoves[0].remoteChainSelector); + + s_tokenPool.applyChainUpdates(chainRemoves); + + // State updated, only chain 2 remains + TokenPool.ChainUpdate[] memory singleChainConfigured = new TokenPool.ChainUpdate[](1); + singleChainConfigured[0] = chainUpdates[1]; + assertState(singleChainConfigured); + + // Cannot reset already configured ramp + vm.expectRevert( + abi.encodeWithSelector(TokenPool.ChainAlreadyExists.selector, singleChainConfigured[0].remoteChainSelector) + ); + s_tokenPool.applyChainUpdates(singleChainConfigured); + } + + // Reverts + + function test_applyChainUpdates_OnlyCallableByOwner_Revert() public { + vm.startPrank(STRANGER); + vm.expectRevert("Only callable by owner"); + s_tokenPool.applyChainUpdates(new TokenPool.ChainUpdate[](0)); + } + + function test_applyChainUpdates_ZeroAddressNotAllowed_Revert() public { + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: 1, + remotePoolAddress: "", + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e18}), + inboundRateLimiterConfig: RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e18}) + }); + + vm.expectRevert(TokenPool.ZeroAddressNotAllowed.selector); + s_tokenPool.applyChainUpdates(chainUpdates); + + chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: 1, + remotePoolAddress: abi.encode(address(2)), + remoteTokenAddress: "", + allowed: true, + outboundRateLimiterConfig: RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e18}), + inboundRateLimiterConfig: RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e18}) + }); + + vm.expectRevert(TokenPool.ZeroAddressNotAllowed.selector); + s_tokenPool.applyChainUpdates(chainUpdates); + } + + function test_applyChainUpdates_DisabledNonZeroRateLimit_Revert() public { + RateLimiter.Config memory outboundRateLimit = RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e18}); + RateLimiter.Config memory inboundRateLimit = RateLimiter.Config({isEnabled: true, capacity: 100e22, rate: 1e12}); + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: 1, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: outboundRateLimit, + inboundRateLimiterConfig: inboundRateLimit + }); + + s_tokenPool.applyChainUpdates(chainUpdates); + + chainUpdates[0].allowed = false; + chainUpdates[0].outboundRateLimiterConfig = RateLimiter.Config({isEnabled: false, capacity: 10, rate: 1}); + chainUpdates[0].inboundRateLimiterConfig = RateLimiter.Config({isEnabled: false, capacity: 10, rate: 1}); + + vm.expectRevert( + abi.encodeWithSelector(RateLimiter.DisabledNonZeroRateLimit.selector, chainUpdates[0].outboundRateLimiterConfig) + ); + s_tokenPool.applyChainUpdates(chainUpdates); + } + + function test_applyChainUpdates_NonExistentChain_Revert() public { + RateLimiter.Config memory outboundRateLimit = RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}); + RateLimiter.Config memory inboundRateLimit = RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}); + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: 1, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: false, + outboundRateLimiterConfig: outboundRateLimit, + inboundRateLimiterConfig: inboundRateLimit + }); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, chainUpdates[0].remoteChainSelector)); + s_tokenPool.applyChainUpdates(chainUpdates); + } + + function test_applyChainUpdates_InvalidRateLimitRate_Revert() public { + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: 1, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: RateLimiter.Config({isEnabled: true, capacity: 0, rate: 0}), + inboundRateLimiterConfig: RateLimiter.Config({isEnabled: true, capacity: 100e22, rate: 1e12}) + }); + + // Outbound + + vm.expectRevert( + abi.encodeWithSelector(RateLimiter.InvalidRateLimitRate.selector, chainUpdates[0].outboundRateLimiterConfig) + ); + s_tokenPool.applyChainUpdates(chainUpdates); + + chainUpdates[0].outboundRateLimiterConfig.rate = 100; + + vm.expectRevert( + abi.encodeWithSelector(RateLimiter.InvalidRateLimitRate.selector, chainUpdates[0].outboundRateLimiterConfig) + ); + s_tokenPool.applyChainUpdates(chainUpdates); + + chainUpdates[0].outboundRateLimiterConfig.capacity = 100; + + vm.expectRevert( + abi.encodeWithSelector(RateLimiter.InvalidRateLimitRate.selector, chainUpdates[0].outboundRateLimiterConfig) + ); + s_tokenPool.applyChainUpdates(chainUpdates); + + chainUpdates[0].outboundRateLimiterConfig.capacity = 101; + + s_tokenPool.applyChainUpdates(chainUpdates); + + // Change the chain selector as adding the same one would revert + chainUpdates[0].remoteChainSelector = 2; + + // Inbound + + chainUpdates[0].inboundRateLimiterConfig.capacity = 0; + chainUpdates[0].inboundRateLimiterConfig.rate = 0; + + vm.expectRevert( + abi.encodeWithSelector(RateLimiter.InvalidRateLimitRate.selector, chainUpdates[0].inboundRateLimiterConfig) + ); + s_tokenPool.applyChainUpdates(chainUpdates); + + chainUpdates[0].inboundRateLimiterConfig.rate = 100; + + vm.expectRevert( + abi.encodeWithSelector(RateLimiter.InvalidRateLimitRate.selector, chainUpdates[0].inboundRateLimiterConfig) + ); + s_tokenPool.applyChainUpdates(chainUpdates); + + chainUpdates[0].inboundRateLimiterConfig.capacity = 100; + + vm.expectRevert( + abi.encodeWithSelector(RateLimiter.InvalidRateLimitRate.selector, chainUpdates[0].inboundRateLimiterConfig) + ); + s_tokenPool.applyChainUpdates(chainUpdates); + + chainUpdates[0].inboundRateLimiterConfig.capacity = 101; + + s_tokenPool.applyChainUpdates(chainUpdates); + } +} + +contract TokenPool_setChainRateLimiterConfig is TokenPoolSetup { + uint64 internal s_remoteChainSelector; + + function setUp() public virtual override { + TokenPoolSetup.setUp(); + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + s_remoteChainSelector = 123124; + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: s_remoteChainSelector, + remotePoolAddress: abi.encode(address(2)), + remoteTokenAddress: abi.encode(address(3)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_tokenPool.applyChainUpdates(chainUpdates); + } + + function test_Fuzz_SetChainRateLimiterConfig_Success(uint128 capacity, uint128 rate, uint32 newTime) public { + // Cap the lower bound to 4 so 4/2 is still >= 2 + vm.assume(capacity >= 4); + // Cap the lower bound to 2 so 2/2 is still >= 1 + rate = uint128(bound(rate, 2, capacity - 2)); + // Bucket updates only work on increasing time + newTime = uint32(bound(newTime, block.timestamp + 1, type(uint32).max)); + vm.warp(newTime); + + uint256 oldOutboundTokens = s_tokenPool.getCurrentOutboundRateLimiterState(s_remoteChainSelector).tokens; + uint256 oldInboundTokens = s_tokenPool.getCurrentInboundRateLimiterState(s_remoteChainSelector).tokens; + + RateLimiter.Config memory newOutboundConfig = RateLimiter.Config({isEnabled: true, capacity: capacity, rate: rate}); + RateLimiter.Config memory newInboundConfig = + RateLimiter.Config({isEnabled: true, capacity: capacity / 2, rate: rate / 2}); + + vm.expectEmit(); + emit RateLimiter.ConfigChanged(newOutboundConfig); + vm.expectEmit(); + emit RateLimiter.ConfigChanged(newInboundConfig); + vm.expectEmit(); + emit TokenPool.ChainConfigured(s_remoteChainSelector, newOutboundConfig, newInboundConfig); + + s_tokenPool.setChainRateLimiterConfig(s_remoteChainSelector, newOutboundConfig, newInboundConfig); + + uint256 expectedTokens = RateLimiter._min(newOutboundConfig.capacity, oldOutboundTokens); + + RateLimiter.TokenBucket memory bucket = s_tokenPool.getCurrentOutboundRateLimiterState(s_remoteChainSelector); + assertEq(bucket.capacity, newOutboundConfig.capacity); + assertEq(bucket.rate, newOutboundConfig.rate); + assertEq(bucket.tokens, expectedTokens); + assertEq(bucket.lastUpdated, newTime); + + expectedTokens = RateLimiter._min(newInboundConfig.capacity, oldInboundTokens); + + bucket = s_tokenPool.getCurrentInboundRateLimiterState(s_remoteChainSelector); + assertEq(bucket.capacity, newInboundConfig.capacity); + assertEq(bucket.rate, newInboundConfig.rate); + assertEq(bucket.tokens, expectedTokens); + assertEq(bucket.lastUpdated, newTime); + } + + // Reverts + + function test_OnlyOwner_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert("Only callable by owner"); + s_tokenPool.setChainRateLimiterConfig( + s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() + ); + } + + function test_NonExistentChain_Revert() public { + uint64 wrongChainSelector = 9084102894; + + vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, wrongChainSelector)); + s_tokenPool.setChainRateLimiterConfig( + wrongChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() + ); + } +} + +contract TokenPool_onlyOnRamp is TokenPoolSetup { + function test_onlyOnRamp_Success() public { + uint64 chainSelector = 13377; + address onRamp = makeAddr("onRamp"); + + TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_tokenPool.applyChainUpdates(chainUpdate); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + onRampUpdates[0] = Router.OnRamp({destChainSelector: chainSelector, onRamp: onRamp}); + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), new Router.OffRamp[](0)); + + vm.startPrank(onRamp); + + s_tokenPool.onlyOnRampModifier(chainSelector); + } + + function test_ChainNotAllowed_Revert() public { + uint64 chainSelector = 13377; + address onRamp = makeAddr("onRamp"); + + vm.startPrank(onRamp); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.ChainNotAllowed.selector, chainSelector)); + s_tokenPool.onlyOnRampModifier(chainSelector); + + vm.startPrank(OWNER); + + TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_tokenPool.applyChainUpdates(chainUpdate); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + onRampUpdates[0] = Router.OnRamp({destChainSelector: chainSelector, onRamp: onRamp}); + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), new Router.OffRamp[](0)); + + vm.startPrank(onRamp); + // Should succeed now that we've added the chain + s_tokenPool.onlyOnRampModifier(chainSelector); + + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: false, + outboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}), + inboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}) + }); + + vm.startPrank(OWNER); + s_tokenPool.applyChainUpdates(chainUpdate); + + vm.startPrank(onRamp); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.ChainNotAllowed.selector, chainSelector)); + s_tokenPool.onlyOffRampModifier(chainSelector); + } + + function test_CallerIsNotARampOnRouter_Revert() public { + uint64 chainSelector = 13377; + address onRamp = makeAddr("onRamp"); + + TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_tokenPool.applyChainUpdates(chainUpdate); + + vm.startPrank(onRamp); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.CallerIsNotARampOnRouter.selector, onRamp)); + + s_tokenPool.onlyOnRampModifier(chainSelector); + } +} + +contract TokenPool_onlyOffRamp is TokenPoolSetup { + function test_onlyOffRamp_Success() public { + uint64 chainSelector = 13377; + address offRamp = makeAddr("onRamp"); + + TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_tokenPool.applyChainUpdates(chainUpdate); + + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: chainSelector, offRamp: offRamp}); + s_sourceRouter.applyRampUpdates(new Router.OnRamp[](0), new Router.OffRamp[](0), offRampUpdates); + + vm.startPrank(offRamp); + + s_tokenPool.onlyOffRampModifier(chainSelector); + } + + function test_ChainNotAllowed_Revert() public { + uint64 chainSelector = 13377; + address offRamp = makeAddr("onRamp"); + + vm.startPrank(offRamp); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.ChainNotAllowed.selector, chainSelector)); + s_tokenPool.onlyOffRampModifier(chainSelector); + + vm.startPrank(OWNER); + + TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_tokenPool.applyChainUpdates(chainUpdate); + + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: chainSelector, offRamp: offRamp}); + s_sourceRouter.applyRampUpdates(new Router.OnRamp[](0), new Router.OffRamp[](0), offRampUpdates); + + vm.startPrank(offRamp); + // Should succeed now that we've added the chain + s_tokenPool.onlyOffRampModifier(chainSelector); + + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: false, + outboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}), + inboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}) + }); + + vm.startPrank(OWNER); + s_tokenPool.applyChainUpdates(chainUpdate); + + vm.startPrank(offRamp); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.ChainNotAllowed.selector, chainSelector)); + s_tokenPool.onlyOffRampModifier(chainSelector); + } + + function test_CallerIsNotARampOnRouter_Revert() public { + uint64 chainSelector = 13377; + address offRamp = makeAddr("offRamp"); + + TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + s_tokenPool.applyChainUpdates(chainUpdate); + + vm.startPrank(offRamp); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.CallerIsNotARampOnRouter.selector, offRamp)); + + s_tokenPool.onlyOffRampModifier(chainSelector); + } +} + +contract TokenPoolWithAllowListSetup is TokenPoolSetup { + address[] internal s_allowedSenders; + + function setUp() public virtual override { + TokenPoolSetup.setUp(); + + s_allowedSenders.push(STRANGER); + s_allowedSenders.push(DUMMY_CONTRACT_ADDRESS); + + s_tokenPool = new TokenPoolHelper(s_token, s_allowedSenders, address(s_mockRMN), address(s_sourceRouter)); + } +} + +contract TokenPoolWithAllowList_getAllowListEnabled is TokenPoolWithAllowListSetup { + function test_GetAllowListEnabled_Success() public view { + assertTrue(s_tokenPool.getAllowListEnabled()); + } +} + +contract TokenPoolWithAllowList_setRouter is TokenPoolWithAllowListSetup { + function test_SetRouter_Success() public { + assertEq(address(s_sourceRouter), s_tokenPool.getRouter()); + + address newRouter = makeAddr("newRouter"); + + vm.expectEmit(); + emit TokenPool.RouterUpdated(address(s_sourceRouter), newRouter); + + s_tokenPool.setRouter(newRouter); + + assertEq(newRouter, s_tokenPool.getRouter()); + } +} + +contract TokenPoolWithAllowList_getAllowList is TokenPoolWithAllowListSetup { + function test_GetAllowList_Success() public view { + address[] memory setAddresses = s_tokenPool.getAllowList(); + assertEq(2, setAddresses.length); + assertEq(s_allowedSenders[0], setAddresses[0]); + assertEq(s_allowedSenders[1], setAddresses[1]); + } +} + +contract TokenPoolWithAllowList_applyAllowListUpdates is TokenPoolWithAllowListSetup { + function test_SetAllowList_Success() public { + address[] memory newAddresses = new address[](2); + newAddresses[0] = address(1); + newAddresses[1] = address(2); + + for (uint256 i = 0; i < 2; ++i) { + vm.expectEmit(); + emit TokenPool.AllowListAdd(newAddresses[i]); + } + + s_tokenPool.applyAllowListUpdates(new address[](0), newAddresses); + address[] memory setAddresses = s_tokenPool.getAllowList(); + + assertEq(s_allowedSenders[0], setAddresses[0]); + assertEq(s_allowedSenders[1], setAddresses[1]); + assertEq(address(1), setAddresses[2]); + assertEq(address(2), setAddresses[3]); + + // address(2) exists noop, add address(3), remove address(1) + newAddresses = new address[](2); + newAddresses[0] = address(2); + newAddresses[1] = address(3); + + address[] memory removeAddresses = new address[](1); + removeAddresses[0] = address(1); + + vm.expectEmit(); + emit TokenPool.AllowListRemove(address(1)); + + vm.expectEmit(); + emit TokenPool.AllowListAdd(address(3)); + + s_tokenPool.applyAllowListUpdates(removeAddresses, newAddresses); + setAddresses = s_tokenPool.getAllowList(); + + assertEq(s_allowedSenders[0], setAddresses[0]); + assertEq(s_allowedSenders[1], setAddresses[1]); + assertEq(address(2), setAddresses[2]); + assertEq(address(3), setAddresses[3]); + + // remove all from allowList + for (uint256 i = 0; i < setAddresses.length; ++i) { + vm.expectEmit(); + emit TokenPool.AllowListRemove(setAddresses[i]); + } + + s_tokenPool.applyAllowListUpdates(setAddresses, new address[](0)); + setAddresses = s_tokenPool.getAllowList(); + + assertEq(0, setAddresses.length); + } + + function test_SetAllowListSkipsZero_Success() public { + uint256 setAddressesLength = s_tokenPool.getAllowList().length; + + address[] memory newAddresses = new address[](1); + newAddresses[0] = address(0); + + s_tokenPool.applyAllowListUpdates(new address[](0), newAddresses); + address[] memory setAddresses = s_tokenPool.getAllowList(); + + assertEq(setAddresses.length, setAddressesLength); + } + + // Reverts + + function test_OnlyOwner_Revert() public { + vm.stopPrank(); + vm.expectRevert("Only callable by owner"); + address[] memory newAddresses = new address[](2); + s_tokenPool.applyAllowListUpdates(new address[](0), newAddresses); + } + + function test_AllowListNotEnabled_Revert() public { + s_tokenPool = new TokenPoolHelper(s_token, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + + vm.expectRevert(TokenPool.AllowListNotEnabled.selector); + + s_tokenPool.applyAllowListUpdates(new address[](0), new address[](2)); + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol new file mode 100644 index 0000000000..200ffb4f6d --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol @@ -0,0 +1,690 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; +import {IPoolV1} from "../../interfaces/IPool.sol"; +import {ITokenMessenger} from "../../pools/USDC/ITokenMessenger.sol"; + +import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; +import {Router} from "../../Router.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {Pool} from "../../libraries/Pool.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {USDCTokenPool} from "../../pools/USDC/USDCTokenPool.sol"; +import {BaseTest} from "../BaseTest.t.sol"; +import {USDCTokenPoolHelper} from "../helpers/USDCTokenPoolHelper.sol"; +import {MockE2EUSDCTransmitter} from "../mocks/MockE2EUSDCTransmitter.sol"; +import {MockUSDCTokenMessenger} from "../mocks/MockUSDCTokenMessenger.sol"; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; + +contract USDCTokenPoolSetup is BaseTest { + IBurnMintERC20 internal s_token; + MockUSDCTokenMessenger internal s_mockUSDC; + MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; + + struct USDCMessage { + uint32 version; + uint32 sourceDomain; + uint32 destinationDomain; + uint64 nonce; + bytes32 sender; + bytes32 recipient; + bytes32 destinationCaller; + bytes messageBody; + } + + uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; + uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; + + bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); + address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); + address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); + address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); + + address internal s_routerAllowedOnRamp = address(3456); + address internal s_routerAllowedOffRamp = address(234); + Router internal s_router; + + USDCTokenPoolHelper internal s_usdcTokenPool; + USDCTokenPoolHelper internal s_usdcTokenPoolWithAllowList; + address[] internal s_allowedList; + + function setUp() public virtual override { + BaseTest.setUp(); + BurnMintERC677 usdcToken = new BurnMintERC677("LINK", "LNK", 18, 0); + s_token = usdcToken; + deal(address(s_token), OWNER, type(uint256).max); + setUpRamps(); + + s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); + s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); + + usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); + + s_usdcTokenPool = + new USDCTokenPoolHelper(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); + usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); + + s_allowedList.push(USER_1); + s_usdcTokenPoolWithAllowList = + new USDCTokenPoolHelper(s_mockUSDC, s_token, s_allowedList, address(s_mockRMN), address(s_router)); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), + remoteTokenAddress: abi.encode(address(s_token)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + chainUpdates[1] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), + remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + + s_usdcTokenPool.applyChainUpdates(chainUpdates); + s_usdcTokenPoolWithAllowList.applyChainUpdates(chainUpdates); + + USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); + domains[0] = USDCTokenPool.DomainUpdate({ + destChainSelector: DEST_CHAIN_SELECTOR, + domainIdentifier: 9999, + allowedCaller: keccak256("allowedCaller"), + enabled: true + }); + + s_usdcTokenPool.setDomains(domains); + s_usdcTokenPoolWithAllowList.setDomains(domains); + } + + function setUpRamps() internal { + s_router = new Router(address(s_token), address(s_mockRMN)); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + address[] memory offRamps = new address[](1); + offRamps[0] = s_routerAllowedOffRamp; + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); + + s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } + + function _generateUSDCMessage(USDCMessage memory usdcMessage) internal pure returns (bytes memory) { + return abi.encodePacked( + usdcMessage.version, + usdcMessage.sourceDomain, + usdcMessage.destinationDomain, + usdcMessage.nonce, + usdcMessage.sender, + usdcMessage.recipient, + usdcMessage.destinationCaller, + usdcMessage.messageBody + ); + } +} + +contract USDCTokenPool_lockOrBurn is USDCTokenPoolSetup { + // Base test case, included for PR gas comparisons as fuzz tests are excluded from forge snapshot due to being flaky. + function test_LockOrBurn_Success() public { + bytes32 receiver = bytes32(uint256(uint160(STRANGER))); + uint256 amount = 1; + s_token.transfer(address(s_usdcTokenPool), amount); + vm.startPrank(s_routerAllowedOnRamp); + + USDCTokenPool.Domain memory expectedDomain = s_usdcTokenPool.getDomain(DEST_CHAIN_SELECTOR); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(amount); + + vm.expectEmit(); + emit ITokenMessenger.DepositForBurn( + s_mockUSDC.s_nonce(), + address(s_token), + amount, + address(s_usdcTokenPool), + expectedDomain.allowedCaller, + expectedDomain.domainIdentifier, + s_mockUSDC.DESTINATION_TOKEN_MESSENGER(), + expectedDomain.allowedCaller + ); + + vm.expectEmit(); + emit TokenPool.Burned(s_routerAllowedOnRamp, amount); + + Pool.LockOrBurnOutV1 memory poolReturnDataV1 = s_usdcTokenPool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: abi.encodePacked(receiver), + amount: amount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + + uint64 nonce = abi.decode(poolReturnDataV1.destPoolData, (uint64)); + assertEq(s_mockUSDC.s_nonce() - 1, nonce); + } + + function test_Fuzz_LockOrBurn_Success(bytes32 destinationReceiver, uint256 amount) public { + vm.assume(destinationReceiver != bytes32(0)); + amount = bound(amount, 1, getOutboundRateLimiterConfig().capacity); + s_token.transfer(address(s_usdcTokenPool), amount); + vm.startPrank(s_routerAllowedOnRamp); + + USDCTokenPool.Domain memory expectedDomain = s_usdcTokenPool.getDomain(DEST_CHAIN_SELECTOR); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(amount); + + vm.expectEmit(); + emit ITokenMessenger.DepositForBurn( + s_mockUSDC.s_nonce(), + address(s_token), + amount, + address(s_usdcTokenPool), + expectedDomain.allowedCaller, + expectedDomain.domainIdentifier, + s_mockUSDC.DESTINATION_TOKEN_MESSENGER(), + expectedDomain.allowedCaller + ); + + vm.expectEmit(); + emit TokenPool.Burned(s_routerAllowedOnRamp, amount); + + Pool.LockOrBurnOutV1 memory poolReturnDataV1 = s_usdcTokenPool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: abi.encodePacked(destinationReceiver), + amount: amount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + + uint64 nonce = abi.decode(poolReturnDataV1.destPoolData, (uint64)); + assertEq(s_mockUSDC.s_nonce() - 1, nonce); + assertEq(poolReturnDataV1.destTokenAddress, abi.encode(DEST_CHAIN_USDC_TOKEN)); + } + + function test_Fuzz_LockOrBurnWithAllowList_Success(bytes32 destinationReceiver, uint256 amount) public { + vm.assume(destinationReceiver != bytes32(0)); + amount = bound(amount, 1, getOutboundRateLimiterConfig().capacity); + s_token.transfer(address(s_usdcTokenPoolWithAllowList), amount); + vm.startPrank(s_routerAllowedOnRamp); + + USDCTokenPool.Domain memory expectedDomain = s_usdcTokenPoolWithAllowList.getDomain(DEST_CHAIN_SELECTOR); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(amount); + vm.expectEmit(); + emit ITokenMessenger.DepositForBurn( + s_mockUSDC.s_nonce(), + address(s_token), + amount, + address(s_usdcTokenPoolWithAllowList), + expectedDomain.allowedCaller, + expectedDomain.domainIdentifier, + s_mockUSDC.DESTINATION_TOKEN_MESSENGER(), + expectedDomain.allowedCaller + ); + vm.expectEmit(); + emit TokenPool.Burned(s_routerAllowedOnRamp, amount); + + Pool.LockOrBurnOutV1 memory poolReturnDataV1 = s_usdcTokenPoolWithAllowList.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: s_allowedList[0], + receiver: abi.encodePacked(destinationReceiver), + amount: amount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + uint64 nonce = abi.decode(poolReturnDataV1.destPoolData, (uint64)); + assertEq(s_mockUSDC.s_nonce() - 1, nonce); + assertEq(poolReturnDataV1.destTokenAddress, abi.encode(DEST_CHAIN_USDC_TOKEN)); + } + + // Reverts + function test_UnknownDomain_Revert() public { + uint64 wrongDomain = DEST_CHAIN_SELECTOR + 1; + // We need to setup the wrong chainSelector so it reaches the domain check + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + onRampUpdates[0] = Router.OnRamp({destChainSelector: wrongDomain, onRamp: s_routerAllowedOnRamp}); + s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), new Router.OffRamp[](0)); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: wrongDomain, + remotePoolAddress: abi.encode(address(1)), + remoteTokenAddress: abi.encode(address(2)), + allowed: true, + outboundRateLimiterConfig: getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: getInboundRateLimiterConfig() + }); + + s_usdcTokenPool.applyChainUpdates(chainUpdates); + + uint256 amount = 1000; + vm.startPrank(s_routerAllowedOnRamp); + deal(address(s_token), s_routerAllowedOnRamp, amount); + s_token.approve(address(s_usdcTokenPool), amount); + + vm.expectRevert(abi.encodeWithSelector(USDCTokenPool.UnknownDomain.selector, wrongDomain)); + + s_usdcTokenPool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: abi.encodePacked(address(0)), + amount: amount, + remoteChainSelector: wrongDomain, + localToken: address(s_token) + }) + ); + } + + function test_CallerIsNotARampOnRouter_Revert() public { + vm.expectRevert(abi.encodeWithSelector(TokenPool.CallerIsNotARampOnRouter.selector, OWNER)); + + s_usdcTokenPool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: abi.encodePacked(address(0)), + amount: 0, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + } + + function test_LockOrBurnWithAllowList_Revert() public { + vm.startPrank(s_routerAllowedOnRamp); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.SenderNotAllowed.selector, STRANGER)); + + s_usdcTokenPoolWithAllowList.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: STRANGER, + receiver: abi.encodePacked(address(0)), + amount: 1000, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + } + + function test_lockOrBurn_InvalidReceiver_Revert() public { + vm.startPrank(s_routerAllowedOnRamp); + + bytes memory receiver = abi.encodePacked(address(0), address(1)); + + vm.expectRevert(abi.encodeWithSelector(USDCTokenPool.InvalidReceiver.selector, receiver)); + + s_usdcTokenPool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: receiver, + amount: 1, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + } +} + +contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { + function test_Fuzz_ReleaseOrMint_Success(address recipient, uint256 amount) public { + vm.assume(recipient != address(0) && recipient != address(s_token)); + amount = bound(amount, 0, getInboundRateLimiterConfig().capacity); + + USDCMessage memory usdcMessage = USDCMessage({ + version: 0, + sourceDomain: SOURCE_DOMAIN_IDENTIFIER, + destinationDomain: DEST_DOMAIN_IDENTIFIER, + nonce: 0x060606060606, + sender: SOURCE_CHAIN_TOKEN_SENDER, + recipient: bytes32(uint256(uint160(recipient))), + destinationCaller: bytes32(uint256(uint160(address(s_usdcTokenPool)))), + messageBody: bytes("") + }); + + bytes memory message = _generateUSDCMessage(usdcMessage); + bytes memory attestation = bytes("attestation bytes"); + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), + destTokenAddress: abi.encode(address(s_usdcTokenPool)), + extraData: abi.encode( + USDCTokenPool.SourceTokenDataPayload({nonce: usdcMessage.nonce, sourceDomain: SOURCE_DOMAIN_IDENTIFIER}) + ) + }); + + bytes memory offchainTokenData = + abi.encode(USDCTokenPool.MessageAndAttestation({message: message, attestation: attestation})); + + // The mocked receiver does not release the token to the pool, so we manually do it here + deal(address(s_token), address(s_usdcTokenPool), amount); + + vm.expectEmit(); + emit TokenPool.Minted(s_routerAllowedOffRamp, recipient, amount); + + vm.expectCall( + address(s_mockUSDCTransmitter), + abi.encodeWithSelector(MockE2EUSDCTransmitter.receiveMessage.selector, message, attestation) + ); + + vm.startPrank(s_routerAllowedOffRamp); + s_usdcTokenPool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + receiver: recipient, + amount: amount, + localToken: address(s_token), + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData + }) + ); + } + + // https://etherscan.io/tx/0xac9f501fe0b76df1f07a22e1db30929fd12524bc7068d74012dff948632f0883 + function test_ReleaseOrMintRealTx_Success() public { + bytes memory encodedUsdcMessage = + hex"000000000000000300000000000000000000127a00000000000000000000000019330d10d9cc8751218eaf51e8885d058642e08a000000000000000000000000bd3fa81b58ba92a82136038b25adec7066af3155000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e58310000000000000000000000004af08f56978be7dce2d1be3c65c005b41e79401c000000000000000000000000000000000000000000000000000000002057ff7a0000000000000000000000003a23f943181408eac424116af7b7790c94cb97a50000000000000000000000000000000000000000000000000000000000000000000000000000008274119237535fd659626b090f87e365ff89ebc7096bb32e8b0e85f155626b73ae7c4bb2485c184b7cc3cf7909045487890b104efb62ae74a73e32901bdcec91df1bb9ee08ccb014fcbcfe77b74d1263fd4e0b0e8de05d6c9a5913554364abfd5ea768b222f50c715908183905d74044bb2b97527c7e70ae7983c443a603557cac3b1c000000000000000000000000000000000000000000000000000000000000"; + bytes memory attestation = bytes("attestation bytes"); + + uint32 nonce = 4730; + uint32 sourceDomain = 3; + uint256 amount = 100; + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), + destTokenAddress: abi.encode(address(s_usdcTokenPool)), + extraData: abi.encode(USDCTokenPool.SourceTokenDataPayload({nonce: nonce, sourceDomain: sourceDomain})) + }); + + // The mocked receiver does not release the token to the pool, so we manually do it here + deal(address(s_token), address(s_usdcTokenPool), amount); + + bytes memory offchainTokenData = + abi.encode(USDCTokenPool.MessageAndAttestation({message: encodedUsdcMessage, attestation: attestation})); + + vm.expectCall( + address(s_mockUSDCTransmitter), + abi.encodeWithSelector(MockE2EUSDCTransmitter.receiveMessage.selector, encodedUsdcMessage, attestation) + ); + + vm.startPrank(s_routerAllowedOffRamp); + s_usdcTokenPool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + receiver: OWNER, + amount: amount, + localToken: address(s_token), + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData + }) + ); + } + + // Reverts + function test_UnlockingUSDCFailed_Revert() public { + vm.startPrank(s_routerAllowedOffRamp); + s_mockUSDCTransmitter.setShouldSucceed(false); + + uint256 amount = 13255235235; + + USDCMessage memory usdcMessage = USDCMessage({ + version: 0, + sourceDomain: SOURCE_DOMAIN_IDENTIFIER, + destinationDomain: DEST_DOMAIN_IDENTIFIER, + nonce: 0x060606060606, + sender: SOURCE_CHAIN_TOKEN_SENDER, + recipient: bytes32(uint256(uint160(address(s_mockUSDC)))), + destinationCaller: bytes32(uint256(uint160(address(s_usdcTokenPool)))), + messageBody: bytes("") + }); + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), + destTokenAddress: abi.encode(address(s_usdcTokenPool)), + extraData: abi.encode( + USDCTokenPool.SourceTokenDataPayload({nonce: usdcMessage.nonce, sourceDomain: SOURCE_DOMAIN_IDENTIFIER}) + ) + }); + + bytes memory offchainTokenData = abi.encode( + USDCTokenPool.MessageAndAttestation({message: _generateUSDCMessage(usdcMessage), attestation: bytes("")}) + ); + + vm.expectRevert(USDCTokenPool.UnlockingUSDCFailed.selector); + + s_usdcTokenPool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + receiver: OWNER, + amount: amount, + localToken: address(s_token), + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData + }) + ); + } + + function test_TokenMaxCapacityExceeded_Revert() public { + uint256 capacity = getInboundRateLimiterConfig().capacity; + uint256 amount = 10 * capacity; + address recipient = address(1); + vm.startPrank(s_routerAllowedOffRamp); + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), + destTokenAddress: abi.encode(address(s_usdcTokenPool)), + extraData: abi.encode(USDCTokenPool.SourceTokenDataPayload({nonce: 1, sourceDomain: SOURCE_DOMAIN_IDENTIFIER})) + }); + + bytes memory offchainTokenData = + abi.encode(USDCTokenPool.MessageAndAttestation({message: bytes(""), attestation: bytes("")})); + + vm.expectRevert( + abi.encodeWithSelector(RateLimiter.TokenMaxCapacityExceeded.selector, capacity, amount, address(s_token)) + ); + + s_usdcTokenPool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + receiver: recipient, + amount: amount, + localToken: address(s_token), + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData + }) + ); + } +} + +contract USDCTokenPool_supportsInterface is USDCTokenPoolSetup { + function test_SupportsInterface_Success() public view { + assertTrue(s_usdcTokenPool.supportsInterface(type(IPoolV1).interfaceId)); + assertTrue(s_usdcTokenPool.supportsInterface(type(IERC165).interfaceId)); + } +} + +contract USDCTokenPool_setDomains is USDCTokenPoolSetup { + mapping(uint64 destChainSelector => USDCTokenPool.Domain domain) private s_chainToDomain; + + // Setting lower fuzz run as 256 runs was causing differing gas results in snapshot. + /// forge-config: default.fuzz.runs = 32 + /// forge-config: ccip.fuzz.runs = 32 + function test_Fuzz_SetDomains_Success( + bytes32[5] calldata allowedCallers, + uint32[5] calldata domainIdentifiers, + uint64[5] calldata destChainSelectors + ) public { + uint256 numberOfDomains = allowedCallers.length; + USDCTokenPool.DomainUpdate[] memory domainUpdates = new USDCTokenPool.DomainUpdate[](numberOfDomains); + for (uint256 i = 0; i < numberOfDomains; ++i) { + vm.assume(allowedCallers[i] != bytes32(0) && domainIdentifiers[i] != 0 && destChainSelectors[i] != 0); + + domainUpdates[i] = USDCTokenPool.DomainUpdate({ + allowedCaller: allowedCallers[i], + domainIdentifier: domainIdentifiers[i], + destChainSelector: destChainSelectors[i], + enabled: true + }); + + s_chainToDomain[destChainSelectors[i]] = + USDCTokenPool.Domain({domainIdentifier: domainIdentifiers[i], allowedCaller: allowedCallers[i], enabled: true}); + } + + vm.expectEmit(); + emit USDCTokenPool.DomainsSet(domainUpdates); + + s_usdcTokenPool.setDomains(domainUpdates); + + for (uint256 i = 0; i < numberOfDomains; ++i) { + USDCTokenPool.Domain memory expected = s_chainToDomain[destChainSelectors[i]]; + USDCTokenPool.Domain memory got = s_usdcTokenPool.getDomain(destChainSelectors[i]); + assertEq(got.allowedCaller, expected.allowedCaller); + assertEq(got.domainIdentifier, expected.domainIdentifier); + } + } + + // Reverts + + function test_OnlyOwner_Revert() public { + USDCTokenPool.DomainUpdate[] memory domainUpdates = new USDCTokenPool.DomainUpdate[](0); + + vm.startPrank(STRANGER); + vm.expectRevert("Only callable by owner"); + + s_usdcTokenPool.setDomains(domainUpdates); + } + + function test_InvalidDomain_Revert() public { + bytes32 validCaller = bytes32(uint256(25)); + // Ensure valid domain works + USDCTokenPool.DomainUpdate[] memory domainUpdates = new USDCTokenPool.DomainUpdate[](1); + domainUpdates[0] = USDCTokenPool.DomainUpdate({ + allowedCaller: validCaller, + domainIdentifier: 0, // ensures 0 is valid, as this is eth mainnet + destChainSelector: 45690, + enabled: true + }); + + s_usdcTokenPool.setDomains(domainUpdates); + + // Make update invalid on allowedCaller + domainUpdates[0].allowedCaller = bytes32(0); + vm.expectRevert(abi.encodeWithSelector(USDCTokenPool.InvalidDomain.selector, domainUpdates[0])); + + s_usdcTokenPool.setDomains(domainUpdates); + + // Make valid again + domainUpdates[0].allowedCaller = validCaller; + + // Make invalid on destChainSelector + domainUpdates[0].destChainSelector = 0; + vm.expectRevert(abi.encodeWithSelector(USDCTokenPool.InvalidDomain.selector, domainUpdates[0])); + + s_usdcTokenPool.setDomains(domainUpdates); + } +} + +contract USDCTokenPool__validateMessage is USDCTokenPoolSetup { + function test_Fuzz_ValidateMessage_Success(uint32 sourceDomain, uint64 nonce) public { + vm.pauseGasMetering(); + USDCMessage memory usdcMessage = USDCMessage({ + version: 0, + sourceDomain: sourceDomain, + destinationDomain: DEST_DOMAIN_IDENTIFIER, + nonce: nonce, + sender: SOURCE_CHAIN_TOKEN_SENDER, + recipient: bytes32(uint256(299999)), + destinationCaller: bytes32(uint256(uint160(address(s_usdcTokenPool)))), + messageBody: bytes("") + }); + + bytes memory encodedUsdcMessage = _generateUSDCMessage(usdcMessage); + + vm.resumeGasMetering(); + s_usdcTokenPool.validateMessage( + encodedUsdcMessage, USDCTokenPool.SourceTokenDataPayload({nonce: nonce, sourceDomain: sourceDomain}) + ); + } + + // Reverts + + function test_ValidateInvalidMessage_Revert() public { + USDCMessage memory usdcMessage = USDCMessage({ + version: 0, + sourceDomain: 1553252, + destinationDomain: DEST_DOMAIN_IDENTIFIER, + nonce: 387289284924, + sender: SOURCE_CHAIN_TOKEN_SENDER, + recipient: bytes32(uint256(92398429395823)), + destinationCaller: bytes32(uint256(uint160(address(s_usdcTokenPool)))), + messageBody: bytes("") + }); + + USDCTokenPool.SourceTokenDataPayload memory sourceTokenData = + USDCTokenPool.SourceTokenDataPayload({nonce: usdcMessage.nonce, sourceDomain: usdcMessage.sourceDomain}); + + bytes memory encodedUsdcMessage = _generateUSDCMessage(usdcMessage); + + s_usdcTokenPool.validateMessage(encodedUsdcMessage, sourceTokenData); + + uint32 expectedSourceDomain = usdcMessage.sourceDomain + 1; + + vm.expectRevert( + abi.encodeWithSelector(USDCTokenPool.InvalidSourceDomain.selector, expectedSourceDomain, usdcMessage.sourceDomain) + ); + s_usdcTokenPool.validateMessage( + encodedUsdcMessage, + USDCTokenPool.SourceTokenDataPayload({nonce: usdcMessage.nonce, sourceDomain: expectedSourceDomain}) + ); + + uint64 expectedNonce = usdcMessage.nonce + 1; + + vm.expectRevert(abi.encodeWithSelector(USDCTokenPool.InvalidNonce.selector, expectedNonce, usdcMessage.nonce)); + s_usdcTokenPool.validateMessage( + encodedUsdcMessage, + USDCTokenPool.SourceTokenDataPayload({nonce: expectedNonce, sourceDomain: usdcMessage.sourceDomain}) + ); + + usdcMessage.destinationDomain = DEST_DOMAIN_IDENTIFIER + 1; + vm.expectRevert( + abi.encodeWithSelector( + USDCTokenPool.InvalidDestinationDomain.selector, DEST_DOMAIN_IDENTIFIER, usdcMessage.destinationDomain + ) + ); + + s_usdcTokenPool.validateMessage( + _generateUSDCMessage(usdcMessage), + USDCTokenPool.SourceTokenDataPayload({nonce: usdcMessage.nonce, sourceDomain: usdcMessage.sourceDomain}) + ); + usdcMessage.destinationDomain = DEST_DOMAIN_IDENTIFIER; + + uint32 wrongVersion = usdcMessage.version + 1; + + usdcMessage.version = wrongVersion; + encodedUsdcMessage = _generateUSDCMessage(usdcMessage); + + vm.expectRevert(abi.encodeWithSelector(USDCTokenPool.InvalidMessageVersion.selector, wrongVersion)); + s_usdcTokenPool.validateMessage(encodedUsdcMessage, sourceTokenData); + } +} diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol new file mode 100644 index 0000000000..c3c22ef290 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol @@ -0,0 +1,2542 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; +import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; + +import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; +import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; +import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol"; +import {PriceRegistry} from "../../PriceRegistry.sol"; + +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {Pool} from "../../libraries/Pool.sol"; +import {USDPriceWith18Decimals} from "../../libraries/USDPriceWith18Decimals.sol"; +import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; + +import {TokenSetup} from "../TokenSetup.t.sol"; +import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; +import {PriceRegistryHelper} from "../helpers/PriceRegistryHelper.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +import {Vm} from "forge-std/Vm.sol"; +import {console} from "forge-std/console.sol"; + +contract PriceRegistrySetup is TokenSetup { + uint112 internal constant USD_PER_GAS = 1e6; // 0.001 gwei + uint112 internal constant USD_PER_DATA_AVAILABILITY_GAS = 1e9; // 1 gwei + + address internal constant CUSTOM_TOKEN = address(12345); + uint224 internal constant CUSTOM_TOKEN_PRICE = 1e17; // $0.1 CUSTOM + + // Encode L1 gas price and L2 gas price into a packed price. + // L1 gas price is left-shifted to the higher-order bits. + uint224 internal constant PACKED_USD_PER_GAS = + (uint224(USD_PER_DATA_AVAILABILITY_GAS) << Internal.GAS_PRICE_BITS) + USD_PER_GAS; + + PriceRegistryHelper internal s_priceRegistry; + // Cheat to store the price updates in storage since struct arrays aren't supported. + bytes internal s_encodedInitialPriceUpdates; + address internal s_weth; + + address[] internal s_sourceFeeTokens; + uint224[] internal s_sourceTokenPrices; + address[] internal s_destFeeTokens; + uint224[] internal s_destTokenPrices; + + PriceRegistry.PremiumMultiplierWeiPerEthArgs[] internal s_priceRegistryPremiumMultiplierWeiPerEthArgs; + PriceRegistry.TokenTransferFeeConfigArgs[] internal s_priceRegistryTokenTransferFeeConfigArgs; + + mapping(address token => address dataFeedAddress) internal s_dataFeedByToken; + + function setUp() public virtual override { + TokenSetup.setUp(); + + _deployTokenPriceDataFeed(s_sourceFeeToken, 8, 1e8); + + s_weth = s_sourceRouter.getWrappedNative(); + _deployTokenPriceDataFeed(s_weth, 8, 1e11); + + address[] memory sourceFeeTokens = new address[](3); + sourceFeeTokens[0] = s_sourceTokens[0]; + sourceFeeTokens[1] = s_sourceTokens[1]; + sourceFeeTokens[2] = s_sourceRouter.getWrappedNative(); + s_sourceFeeTokens = sourceFeeTokens; + + uint224[] memory sourceTokenPrices = new uint224[](3); + sourceTokenPrices[0] = 5e18; + sourceTokenPrices[1] = 2000e18; + sourceTokenPrices[2] = 2000e18; + s_sourceTokenPrices = sourceTokenPrices; + + address[] memory destFeeTokens = new address[](3); + destFeeTokens[0] = s_destTokens[0]; + destFeeTokens[1] = s_destTokens[1]; + destFeeTokens[2] = s_destRouter.getWrappedNative(); + s_destFeeTokens = destFeeTokens; + + uint224[] memory destTokenPrices = new uint224[](3); + destTokenPrices[0] = 5e18; + destTokenPrices[1] = 2000e18; + destTokenPrices[2] = 2000e18; + s_destTokenPrices = destTokenPrices; + + uint256 sourceTokenCount = sourceFeeTokens.length; + uint256 destTokenCount = destFeeTokens.length; + address[] memory pricedTokens = new address[](sourceTokenCount + destTokenCount); + uint224[] memory tokenPrices = new uint224[](sourceTokenCount + destTokenCount); + for (uint256 i = 0; i < sourceTokenCount; ++i) { + pricedTokens[i] = sourceFeeTokens[i]; + tokenPrices[i] = sourceTokenPrices[i]; + } + for (uint256 i = 0; i < destTokenCount; ++i) { + pricedTokens[i + sourceTokenCount] = destFeeTokens[i]; + tokenPrices[i + sourceTokenCount] = destTokenPrices[i]; + } + + Internal.PriceUpdates memory priceUpdates = getPriceUpdatesStruct(pricedTokens, tokenPrices); + priceUpdates.gasPriceUpdates = + getSingleGasPriceUpdateStruct(DEST_CHAIN_SELECTOR, PACKED_USD_PER_GAS).gasPriceUpdates; + + s_encodedInitialPriceUpdates = abi.encode(priceUpdates); + + address[] memory priceUpdaters = new address[](1); + priceUpdaters[0] = OWNER; + address[] memory feeTokens = new address[](2); + feeTokens[0] = s_sourceTokens[0]; + feeTokens[1] = s_weth; + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](0); + + s_priceRegistryPremiumMultiplierWeiPerEthArgs.push( + PriceRegistry.PremiumMultiplierWeiPerEthArgs({ + token: s_sourceFeeToken, + premiumMultiplierWeiPerEth: 5e17 // 0.5x + }) + ); + s_priceRegistryPremiumMultiplierWeiPerEthArgs.push( + PriceRegistry.PremiumMultiplierWeiPerEthArgs({ + token: s_sourceRouter.getWrappedNative(), + premiumMultiplierWeiPerEth: 2e18 // 2x + }) + ); + + s_priceRegistryTokenTransferFeeConfigArgs.push(); + s_priceRegistryTokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; + s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( + PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ + token: s_sourceFeeToken, + tokenTransferFeeConfig: PriceRegistry.TokenTransferFeeConfig({ + minFeeUSDCents: 1_00, // 1 USD + maxFeeUSDCents: 1000_00, // 1,000 USD + deciBps: 2_5, // 2.5 bps, or 0.025% + destGasOverhead: 40_000, + destBytesOverhead: 32, + isEnabled: true + }) + }) + ); + s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( + PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ + token: s_sourceRouter.getWrappedNative(), + tokenTransferFeeConfig: PriceRegistry.TokenTransferFeeConfig({ + minFeeUSDCents: 50, // 0.5 USD + maxFeeUSDCents: 500_00, // 500 USD + deciBps: 5_0, // 5 bps, or 0.05% + destGasOverhead: 10_000, + destBytesOverhead: 100, + isEnabled: true + }) + }) + ); + s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( + PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ + token: CUSTOM_TOKEN, + tokenTransferFeeConfig: PriceRegistry.TokenTransferFeeConfig({ + minFeeUSDCents: 2_00, // 1 USD + maxFeeUSDCents: 2000_00, // 1,000 USD + deciBps: 10_0, // 10 bps, or 0.1% + destGasOverhead: 1, + destBytesOverhead: 200, + isEnabled: true + }) + }) + ); + + s_priceRegistry = new PriceRegistryHelper( + PriceRegistry.StaticConfig({ + linkToken: s_sourceTokens[0], + maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS, + stalenessThreshold: uint32(TWELVE_HOURS) + }), + priceUpdaters, + feeTokens, + tokenPriceFeedUpdates, + s_priceRegistryTokenTransferFeeConfigArgs, + s_priceRegistryPremiumMultiplierWeiPerEthArgs, + _generatePriceRegistryDestChainConfigArgs() + ); + s_priceRegistry.updatePrices(priceUpdates); + } + + function _deployTokenPriceDataFeed(address token, uint8 decimals, int256 initialAnswer) internal returns (address) { + MockV3Aggregator dataFeed = new MockV3Aggregator(decimals, initialAnswer); + s_dataFeedByToken[token] = address(dataFeed); + return address(dataFeed); + } + + function getPriceUpdatesStruct( + address[] memory tokens, + uint224[] memory prices + ) internal pure returns (Internal.PriceUpdates memory) { + uint256 length = tokens.length; + + Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](length); + for (uint256 i = 0; i < length; ++i) { + tokenPriceUpdates[i] = Internal.TokenPriceUpdate({sourceToken: tokens[i], usdPerToken: prices[i]}); + } + Internal.PriceUpdates memory priceUpdates = + Internal.PriceUpdates({tokenPriceUpdates: tokenPriceUpdates, gasPriceUpdates: new Internal.GasPriceUpdate[](0)}); + + return priceUpdates; + } + + function getEmptyPriceUpdates() internal pure returns (Internal.PriceUpdates memory priceUpdates) { + return Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + gasPriceUpdates: new Internal.GasPriceUpdate[](0) + }); + } + + function getSingleTokenPriceFeedUpdateStruct( + address sourceToken, + address dataFeedAddress, + uint8 tokenDecimals + ) internal pure returns (PriceRegistry.TokenPriceFeedUpdate memory) { + return PriceRegistry.TokenPriceFeedUpdate({ + sourceToken: sourceToken, + feedConfig: IPriceRegistry.TokenPriceFeedConfig({dataFeedAddress: dataFeedAddress, tokenDecimals: tokenDecimals}) + }); + } + + function _initialiseSingleTokenPriceFeed() internal returns (address) { + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = + getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + return s_sourceTokens[0]; + } + + function _generateTokenTransferFeeConfigArgs( + uint256 destChainSelectorLength, + uint256 tokenLength + ) internal pure returns (PriceRegistry.TokenTransferFeeConfigArgs[] memory) { + PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + new PriceRegistry.TokenTransferFeeConfigArgs[](destChainSelectorLength); + for (uint256 i = 0; i < destChainSelectorLength; ++i) { + tokenTransferFeeConfigArgs[i].tokenTransferFeeConfigs = + new PriceRegistry.TokenTransferFeeConfigSingleTokenArgs[](tokenLength); + } + return tokenTransferFeeConfigArgs; + } + + function _generatePriceRegistryDestChainConfigArgs() + internal + pure + returns (PriceRegistry.DestChainConfigArgs[] memory) + { + PriceRegistry.DestChainConfigArgs[] memory destChainConfigs = new PriceRegistry.DestChainConfigArgs[](1); + destChainConfigs[0] = PriceRegistry.DestChainConfigArgs({ + destChainSelector: DEST_CHAIN_SELECTOR, + destChainConfig: PriceRegistry.DestChainConfig({ + isEnabled: true, + maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, + destGasOverhead: DEST_GAS_OVERHEAD, + destGasPerPayloadByte: DEST_GAS_PER_PAYLOAD_BYTE, + destDataAvailabilityOverheadGas: DEST_DATA_AVAILABILITY_OVERHEAD_GAS, + destGasPerDataAvailabilityByte: DEST_GAS_PER_DATA_AVAILABILITY_BYTE, + destDataAvailabilityMultiplierBps: DEST_GAS_DATA_AVAILABILITY_MULTIPLIER_BPS, + maxDataBytes: MAX_DATA_SIZE, + maxPerMsgGasLimit: MAX_GAS_LIMIT, + defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, + defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, + defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, + defaultTxGasLimit: GAS_LIMIT, + gasMultiplierWeiPerEth: 5e17, + networkFeeUSDCents: 1_00, + enforceOutOfOrder: false, + chainFamilySelector: Internal.CHAIN_FAMILY_SELECTOR_EVM + }) + }); + return destChainConfigs; + } + + function _assertTokenPriceFeedConfigEquality( + IPriceRegistry.TokenPriceFeedConfig memory config1, + IPriceRegistry.TokenPriceFeedConfig memory config2 + ) internal pure virtual { + assertEq(config1.dataFeedAddress, config2.dataFeedAddress); + assertEq(config1.tokenDecimals, config2.tokenDecimals); + } + + function _assertTokenPriceFeedConfigUnconfigured(IPriceRegistry.TokenPriceFeedConfig memory config) + internal + pure + virtual + { + _assertTokenPriceFeedConfigEquality( + config, IPriceRegistry.TokenPriceFeedConfig({dataFeedAddress: address(0), tokenDecimals: 0}) + ); + } + + function _assertTokenTransferFeeConfigEqual( + PriceRegistry.TokenTransferFeeConfig memory a, + PriceRegistry.TokenTransferFeeConfig memory b + ) internal pure { + assertEq(a.minFeeUSDCents, b.minFeeUSDCents); + assertEq(a.maxFeeUSDCents, b.maxFeeUSDCents); + assertEq(a.deciBps, b.deciBps); + assertEq(a.destGasOverhead, b.destGasOverhead); + assertEq(a.destBytesOverhead, b.destBytesOverhead); + assertEq(a.isEnabled, b.isEnabled); + } + + function _assertPriceRegistryStaticConfigsEqual( + PriceRegistry.StaticConfig memory a, + PriceRegistry.StaticConfig memory b + ) internal pure { + assertEq(a.linkToken, b.linkToken); + assertEq(a.maxFeeJuelsPerMsg, b.maxFeeJuelsPerMsg); + } + + function _assertPriceRegistryDestChainConfigsEqual( + PriceRegistry.DestChainConfig memory a, + PriceRegistry.DestChainConfig memory b + ) internal pure { + assertEq(a.isEnabled, b.isEnabled); + assertEq(a.maxNumberOfTokensPerMsg, b.maxNumberOfTokensPerMsg); + assertEq(a.maxDataBytes, b.maxDataBytes); + assertEq(a.maxPerMsgGasLimit, b.maxPerMsgGasLimit); + assertEq(a.destGasOverhead, b.destGasOverhead); + assertEq(a.destGasPerPayloadByte, b.destGasPerPayloadByte); + assertEq(a.destDataAvailabilityOverheadGas, b.destDataAvailabilityOverheadGas); + assertEq(a.destGasPerDataAvailabilityByte, b.destGasPerDataAvailabilityByte); + assertEq(a.destDataAvailabilityMultiplierBps, b.destDataAvailabilityMultiplierBps); + assertEq(a.defaultTokenFeeUSDCents, b.defaultTokenFeeUSDCents); + assertEq(a.defaultTokenDestGasOverhead, b.defaultTokenDestGasOverhead); + assertEq(a.defaultTokenDestBytesOverhead, b.defaultTokenDestBytesOverhead); + assertEq(a.defaultTxGasLimit, b.defaultTxGasLimit); + } +} + +contract PriceRegistryFeeSetup is PriceRegistrySetup { + uint224 internal s_feeTokenPrice; + uint224 internal s_wrappedTokenPrice; + uint224 internal s_customTokenPrice; + + address internal s_selfServeTokenDefaultPricing = makeAddr("self-serve-token-default-pricing"); + + address internal s_destTokenPool = makeAddr("destTokenPool"); + address internal s_destToken = makeAddr("destToken"); + + function setUp() public virtual override { + super.setUp(); + + s_feeTokenPrice = s_sourceTokenPrices[0]; + s_wrappedTokenPrice = s_sourceTokenPrices[2]; + s_customTokenPrice = CUSTOM_TOKEN_PRICE; + + s_priceRegistry.updatePrices(getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); + } + + function _generateEmptyMessage() public view returns (Client.EVM2AnyMessage memory) { + return Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: new Client.EVMTokenAmount[](0), + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + } + + function _generateSingleTokenMessage( + address token, + uint256 amount + ) public view returns (Client.EVM2AnyMessage memory) { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({token: token, amount: amount}); + + return Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + } + + function _messageToEvent( + Client.EVM2AnyMessage memory message, + uint64 sourceChainSelector, + uint64 destChainSelector, + uint64 seqNum, + uint64 nonce, + uint256 feeTokenAmount, + address originalSender, + bytes32 metadataHash, + TokenAdminRegistry tokenAdminRegistry + ) internal view returns (Internal.EVM2AnyRampMessage memory) { + Client.EVMExtraArgsV2 memory extraArgs = + s_priceRegistry.parseEVMExtraArgsFromBytes(message.extraArgs, destChainSelector); + + Internal.EVM2AnyRampMessage memory messageEvent = Internal.EVM2AnyRampMessage({ + header: Internal.RampMessageHeader({ + messageId: "", + sourceChainSelector: sourceChainSelector, + destChainSelector: destChainSelector, + sequenceNumber: seqNum, + nonce: extraArgs.allowOutOfOrderExecution ? 0 : nonce + }), + sender: originalSender, + data: message.data, + receiver: message.receiver, + extraArgs: Client._argsToBytes(extraArgs), + feeToken: message.feeToken, + feeTokenAmount: feeTokenAmount, + tokenAmounts: new Internal.RampTokenAmount[](message.tokenAmounts.length) + }); + + for (uint256 i = 0; i < message.tokenAmounts.length; ++i) { + messageEvent.tokenAmounts[i] = _getSourceTokenData(message.tokenAmounts[i], tokenAdminRegistry); + } + + messageEvent.header.messageId = Internal._hash(messageEvent, metadataHash); + return messageEvent; + } + + function _getSourceTokenData( + Client.EVMTokenAmount memory tokenAmount, + TokenAdminRegistry tokenAdminRegistry + ) internal view returns (Internal.RampTokenAmount memory) { + address destToken = s_destTokenBySourceToken[tokenAmount.token]; + + return Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(tokenAdminRegistry.getTokenConfig(tokenAmount.token).tokenPool), + destTokenAddress: abi.encode(destToken), + extraData: "", + amount: tokenAmount.amount + }); + } + + function calcUSDValueFromTokenAmount(uint224 tokenPrice, uint256 tokenAmount) internal pure returns (uint256) { + return (tokenPrice * tokenAmount) / 1e18; + } + + function applyBpsRatio(uint256 tokenAmount, uint16 ratio) internal pure returns (uint256) { + return (tokenAmount * ratio) / 1e5; + } + + function configUSDCentToWei(uint256 usdCent) internal pure returns (uint256) { + return usdCent * 1e16; + } +} + +contract PriceRegistry_constructor is PriceRegistrySetup { + function test_Setup_Success() public virtual { + address[] memory priceUpdaters = new address[](2); + priceUpdaters[0] = STRANGER; + priceUpdaters[1] = OWNER; + address[] memory feeTokens = new address[](2); + feeTokens[0] = s_sourceTokens[0]; + feeTokens[1] = s_sourceTokens[1]; + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](2); + tokenPriceFeedUpdates[0] = + getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); + tokenPriceFeedUpdates[1] = + getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[1], s_dataFeedByToken[s_sourceTokens[1]], 6); + + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + + PriceRegistry.StaticConfig memory staticConfig = PriceRegistry.StaticConfig({ + linkToken: s_sourceTokens[0], + maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS, + stalenessThreshold: uint32(TWELVE_HOURS) + }); + s_priceRegistry = new PriceRegistryHelper( + staticConfig, + priceUpdaters, + feeTokens, + tokenPriceFeedUpdates, + s_priceRegistryTokenTransferFeeConfigArgs, + s_priceRegistryPremiumMultiplierWeiPerEthArgs, + destChainConfigArgs + ); + + _assertPriceRegistryStaticConfigsEqual(s_priceRegistry.getStaticConfig(), staticConfig); + assertEq(feeTokens, s_priceRegistry.getFeeTokens()); + assertEq(priceUpdaters, s_priceRegistry.getAllAuthorizedCallers()); + assertEq(s_priceRegistry.typeAndVersion(), "PriceRegistry 1.6.0-dev"); + + _assertTokenPriceFeedConfigEquality( + tokenPriceFeedUpdates[0].feedConfig, s_priceRegistry.getTokenPriceFeedConfig(s_sourceTokens[0]) + ); + + _assertTokenPriceFeedConfigEquality( + tokenPriceFeedUpdates[1].feedConfig, s_priceRegistry.getTokenPriceFeedConfig(s_sourceTokens[1]) + ); + + assertEq( + s_priceRegistryPremiumMultiplierWeiPerEthArgs[0].premiumMultiplierWeiPerEth, + s_priceRegistry.getPremiumMultiplierWeiPerEth(s_priceRegistryPremiumMultiplierWeiPerEthArgs[0].token) + ); + + assertEq( + s_priceRegistryPremiumMultiplierWeiPerEthArgs[1].premiumMultiplierWeiPerEth, + s_priceRegistry.getPremiumMultiplierWeiPerEth(s_priceRegistryPremiumMultiplierWeiPerEthArgs[1].token) + ); + + PriceRegistry.TokenTransferFeeConfigArgs memory tokenTransferFeeConfigArg = + s_priceRegistryTokenTransferFeeConfigArgs[0]; + for (uint256 i = 0; i < tokenTransferFeeConfigArg.tokenTransferFeeConfigs.length; ++i) { + PriceRegistry.TokenTransferFeeConfigSingleTokenArgs memory tokenFeeArgs = + s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[i]; + + _assertTokenTransferFeeConfigEqual( + tokenFeeArgs.tokenTransferFeeConfig, + s_priceRegistry.getTokenTransferFeeConfig(tokenTransferFeeConfigArg.destChainSelector, tokenFeeArgs.token) + ); + } + + for (uint256 i = 0; i < destChainConfigArgs.length; ++i) { + PriceRegistry.DestChainConfig memory expectedConfig = destChainConfigArgs[i].destChainConfig; + uint64 destChainSelector = destChainConfigArgs[i].destChainSelector; + + _assertPriceRegistryDestChainConfigsEqual(expectedConfig, s_priceRegistry.getDestChainConfig(destChainSelector)); + } + } + + function test_InvalidStalenessThreshold_Revert() public { + PriceRegistry.StaticConfig memory staticConfig = PriceRegistry.StaticConfig({ + linkToken: s_sourceTokens[0], + maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS, + stalenessThreshold: 0 + }); + + vm.expectRevert(PriceRegistry.InvalidStaticConfig.selector); + + s_priceRegistry = new PriceRegistryHelper( + staticConfig, + new address[](0), + new address[](0), + new PriceRegistry.TokenPriceFeedUpdate[](0), + s_priceRegistryTokenTransferFeeConfigArgs, + s_priceRegistryPremiumMultiplierWeiPerEthArgs, + new PriceRegistry.DestChainConfigArgs[](0) + ); + } + + function test_InvalidLinkTokenEqZeroAddress_Revert() public { + PriceRegistry.StaticConfig memory staticConfig = PriceRegistry.StaticConfig({ + linkToken: address(0), + maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS, + stalenessThreshold: uint32(TWELVE_HOURS) + }); + + vm.expectRevert(PriceRegistry.InvalidStaticConfig.selector); + + s_priceRegistry = new PriceRegistryHelper( + staticConfig, + new address[](0), + new address[](0), + new PriceRegistry.TokenPriceFeedUpdate[](0), + s_priceRegistryTokenTransferFeeConfigArgs, + s_priceRegistryPremiumMultiplierWeiPerEthArgs, + new PriceRegistry.DestChainConfigArgs[](0) + ); + } + + function test_InvalidMaxFeeJuelsPerMsg_Revert() public { + PriceRegistry.StaticConfig memory staticConfig = PriceRegistry.StaticConfig({ + linkToken: s_sourceTokens[0], + maxFeeJuelsPerMsg: 0, + stalenessThreshold: uint32(TWELVE_HOURS) + }); + + vm.expectRevert(PriceRegistry.InvalidStaticConfig.selector); + + s_priceRegistry = new PriceRegistryHelper( + staticConfig, + new address[](0), + new address[](0), + new PriceRegistry.TokenPriceFeedUpdate[](0), + s_priceRegistryTokenTransferFeeConfigArgs, + s_priceRegistryPremiumMultiplierWeiPerEthArgs, + new PriceRegistry.DestChainConfigArgs[](0) + ); + } +} + +contract PriceRegistry_getTokenPrices is PriceRegistrySetup { + function test_GetTokenPrices_Success() public view { + Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedInitialPriceUpdates, (Internal.PriceUpdates)); + + address[] memory tokens = new address[](3); + tokens[0] = s_sourceTokens[0]; + tokens[1] = s_sourceTokens[1]; + tokens[2] = s_weth; + + Internal.TimestampedPackedUint224[] memory tokenPrices = s_priceRegistry.getTokenPrices(tokens); + + assertEq(tokenPrices.length, 3); + assertEq(tokenPrices[0].value, priceUpdates.tokenPriceUpdates[0].usdPerToken); + assertEq(tokenPrices[1].value, priceUpdates.tokenPriceUpdates[1].usdPerToken); + assertEq(tokenPrices[2].value, priceUpdates.tokenPriceUpdates[2].usdPerToken); + } +} + +contract PriceRegistry_getTokenPrice is PriceRegistrySetup { + function test_GetTokenPriceFromFeed_Success() public { + uint256 originalTimestampValue = block.timestamp; + + // Below staleness threshold + vm.warp(originalTimestampValue + 1 hours); + + address sourceToken = _initialiseSingleTokenPriceFeed(); + Internal.TimestampedPackedUint224 memory tokenPriceAnswer = s_priceRegistry.getTokenPrice(sourceToken); + + // Price answer is 1e8 (18 decimal token) - unit is (1e18 * 1e18 / 1e18) -> expected 1e18 + assertEq(tokenPriceAnswer.value, uint224(1e18)); + assertEq(tokenPriceAnswer.timestamp, uint32(block.timestamp)); + } +} + +contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { + function test_GetValidatedTokenPrice_Success() public view { + Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedInitialPriceUpdates, (Internal.PriceUpdates)); + address token = priceUpdates.tokenPriceUpdates[0].sourceToken; + + uint224 tokenPrice = s_priceRegistry.getValidatedTokenPrice(token); + + assertEq(priceUpdates.tokenPriceUpdates[0].usdPerToken, tokenPrice); + } + + function test_GetValidatedTokenPriceFromFeed_Success() public { + uint256 originalTimestampValue = block.timestamp; + + // Right below staleness threshold + vm.warp(originalTimestampValue + TWELVE_HOURS); + + address sourceToken = _initialiseSingleTokenPriceFeed(); + uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(sourceToken); + + // Price answer is 1e8 (18 decimal token) - unit is (1e18 * 1e18 / 1e18) -> expected 1e18 + assertEq(tokenPriceAnswer, uint224(1e18)); + } + + function test_GetValidatedTokenPriceFromFeedOverStalenessPeriod_Success() public { + uint256 originalTimestampValue = block.timestamp; + + // Right above staleness threshold + vm.warp(originalTimestampValue + TWELVE_HOURS + 1); + + address sourceToken = _initialiseSingleTokenPriceFeed(); + uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(sourceToken); + + // Price answer is 1e8 (18 decimal token) - unit is (1e18 * 1e18 / 1e18) -> expected 1e18 + assertEq(tokenPriceAnswer, uint224(1e18)); + } + + function test_GetValidatedTokenPriceFromFeedMaxInt224Value_Success() public { + address tokenAddress = _deploySourceToken("testToken", 0, 18); + address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 18, int256(uint256(type(uint224).max))); + + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + + uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); + + // Price answer is: uint224.MAX_VALUE * (10 ** (36 - 18 - 18)) + assertEq(tokenPriceAnswer, uint224(type(uint224).max)); + } + + function test_GetValidatedTokenPriceFromFeedErc20Below18Decimals_Success() public { + address tokenAddress = _deploySourceToken("testToken", 0, 6); + address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 8, 1e8); + + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 6); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + + uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); + + // Price answer is 1e8 (6 decimal token) - unit is (1e18 * 1e18 / 1e6) -> expected 1e30 + assertEq(tokenPriceAnswer, uint224(1e30)); + } + + function test_GetValidatedTokenPriceFromFeedErc20Above18Decimals_Success() public { + address tokenAddress = _deploySourceToken("testToken", 0, 24); + address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 8, 1e8); + + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 24); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + + uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); + + // Price answer is 1e8 (6 decimal token) - unit is (1e18 * 1e18 / 1e24) -> expected 1e12 + assertEq(tokenPriceAnswer, uint224(1e12)); + } + + function test_GetValidatedTokenPriceFromFeedFeedAt18Decimals_Success() public { + address tokenAddress = _deploySourceToken("testToken", 0, 18); + address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 18, 1e18); + + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + + uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); + + // Price answer is 1e8 (6 decimal token) - unit is (1e18 * 1e18 / 1e18) -> expected 1e18 + assertEq(tokenPriceAnswer, uint224(1e18)); + } + + function test_GetValidatedTokenPriceFromFeedFeedAt0Decimals_Success() public { + address tokenAddress = _deploySourceToken("testToken", 0, 0); + address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 0, 1e31); + + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 0); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + + uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); + + // Price answer is 1e31 (0 decimal token) - unit is (1e18 * 1e18 / 1e0) -> expected 1e36 + assertEq(tokenPriceAnswer, uint224(1e67)); + } + + function test_GetValidatedTokenPriceFromFeedFlippedDecimals_Success() public { + address tokenAddress = _deploySourceToken("testToken", 0, 20); + address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 20, 1e18); + + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 20); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + + uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); + + // Price answer is 1e8 (6 decimal token) - unit is (1e18 * 1e18 / 1e20) -> expected 1e14 + assertEq(tokenPriceAnswer, uint224(1e14)); + } + + function test_StaleFeeToken_Success() public { + vm.warp(block.timestamp + TWELVE_HOURS + 1); + + Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedInitialPriceUpdates, (Internal.PriceUpdates)); + address token = priceUpdates.tokenPriceUpdates[0].sourceToken; + + uint224 tokenPrice = s_priceRegistry.getValidatedTokenPrice(token); + + assertEq(priceUpdates.tokenPriceUpdates[0].usdPerToken, tokenPrice); + } + + // Reverts + + function test_OverflowFeedPrice_Revert() public { + address tokenAddress = _deploySourceToken("testToken", 0, 18); + address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 18, int256(uint256(type(uint224).max) + 1)); + + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + + vm.expectRevert(PriceRegistry.DataFeedValueOutOfUint224Range.selector); + s_priceRegistry.getValidatedTokenPrice(tokenAddress); + } + + function test_UnderflowFeedPrice_Revert() public { + address tokenAddress = _deploySourceToken("testToken", 0, 18); + address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 18, -1); + + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + + vm.expectRevert(PriceRegistry.DataFeedValueOutOfUint224Range.selector); + s_priceRegistry.getValidatedTokenPrice(tokenAddress); + } + + function test_TokenNotSupported_Revert() public { + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.TokenNotSupported.selector, DUMMY_CONTRACT_ADDRESS)); + s_priceRegistry.getValidatedTokenPrice(DUMMY_CONTRACT_ADDRESS); + } + + function test_TokenNotSupportedFeed_Revert() public { + address sourceToken = _initialiseSingleTokenPriceFeed(); + MockV3Aggregator(s_dataFeedByToken[sourceToken]).updateAnswer(0); + + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.TokenNotSupported.selector, sourceToken)); + s_priceRegistry.getValidatedTokenPrice(sourceToken); + } +} + +contract PriceRegistry_applyFeeTokensUpdates is PriceRegistrySetup { + function test_ApplyFeeTokensUpdates_Success() public { + address[] memory feeTokens = new address[](1); + feeTokens[0] = s_sourceTokens[1]; + + vm.expectEmit(); + emit PriceRegistry.FeeTokenAdded(feeTokens[0]); + + s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + assertEq(s_priceRegistry.getFeeTokens().length, 3); + assertEq(s_priceRegistry.getFeeTokens()[2], feeTokens[0]); + + // add same feeToken is no-op + s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + assertEq(s_priceRegistry.getFeeTokens().length, 3); + assertEq(s_priceRegistry.getFeeTokens()[2], feeTokens[0]); + + vm.expectEmit(); + emit PriceRegistry.FeeTokenRemoved(feeTokens[0]); + + s_priceRegistry.applyFeeTokensUpdates(new address[](0), feeTokens); + assertEq(s_priceRegistry.getFeeTokens().length, 2); + + // removing already removed feeToken is no-op + s_priceRegistry.applyFeeTokensUpdates(new address[](0), feeTokens); + assertEq(s_priceRegistry.getFeeTokens().length, 2); + } + + function test_OnlyCallableByOwner_Revert() public { + address[] memory feeTokens = new address[](1); + feeTokens[0] = STRANGER; + vm.startPrank(STRANGER); + vm.expectRevert("Only callable by owner"); + s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + } +} + +contract PriceRegistry_updatePrices is PriceRegistrySetup { + function test_OnlyTokenPrice_Success() public { + Internal.PriceUpdates memory update = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](1), + gasPriceUpdates: new Internal.GasPriceUpdate[](0) + }); + update.tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[0], usdPerToken: 4e18}); + + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated( + update.tokenPriceUpdates[0].sourceToken, update.tokenPriceUpdates[0].usdPerToken, block.timestamp + ); + + s_priceRegistry.updatePrices(update); + + assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[0]).value, update.tokenPriceUpdates[0].usdPerToken); + } + + function test_OnlyGasPrice_Success() public { + Internal.PriceUpdates memory update = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + gasPriceUpdates: new Internal.GasPriceUpdate[](1) + }); + update.gasPriceUpdates[0] = + Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_SELECTOR, usdPerUnitGas: 2000e18}); + + vm.expectEmit(); + emit PriceRegistry.UsdPerUnitGasUpdated( + update.gasPriceUpdates[0].destChainSelector, update.gasPriceUpdates[0].usdPerUnitGas, block.timestamp + ); + + s_priceRegistry.updatePrices(update); + + assertEq( + s_priceRegistry.getDestinationChainGasPrice(DEST_CHAIN_SELECTOR).value, update.gasPriceUpdates[0].usdPerUnitGas + ); + } + + function test_UpdateMultiplePrices_Success() public { + Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](3); + tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[0], usdPerToken: 4e18}); + tokenPriceUpdates[1] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[1], usdPerToken: 1800e18}); + tokenPriceUpdates[2] = Internal.TokenPriceUpdate({sourceToken: address(12345), usdPerToken: 1e18}); + + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](3); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_SELECTOR, usdPerUnitGas: 2e6}); + gasPriceUpdates[1] = Internal.GasPriceUpdate({destChainSelector: SOURCE_CHAIN_SELECTOR, usdPerUnitGas: 2000e18}); + gasPriceUpdates[2] = Internal.GasPriceUpdate({destChainSelector: 12345, usdPerUnitGas: 1e18}); + + Internal.PriceUpdates memory update = + Internal.PriceUpdates({tokenPriceUpdates: tokenPriceUpdates, gasPriceUpdates: gasPriceUpdates}); + + for (uint256 i = 0; i < tokenPriceUpdates.length; ++i) { + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated( + update.tokenPriceUpdates[i].sourceToken, update.tokenPriceUpdates[i].usdPerToken, block.timestamp + ); + } + for (uint256 i = 0; i < gasPriceUpdates.length; ++i) { + vm.expectEmit(); + emit PriceRegistry.UsdPerUnitGasUpdated( + update.gasPriceUpdates[i].destChainSelector, update.gasPriceUpdates[i].usdPerUnitGas, block.timestamp + ); + } + + s_priceRegistry.updatePrices(update); + + for (uint256 i = 0; i < tokenPriceUpdates.length; ++i) { + assertEq( + s_priceRegistry.getTokenPrice(update.tokenPriceUpdates[i].sourceToken).value, tokenPriceUpdates[i].usdPerToken + ); + } + for (uint256 i = 0; i < gasPriceUpdates.length; ++i) { + assertEq( + s_priceRegistry.getDestinationChainGasPrice(update.gasPriceUpdates[i].destChainSelector).value, + gasPriceUpdates[i].usdPerUnitGas + ); + } + } + + function test_UpdatableByAuthorizedCaller_Success() public { + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](1), + gasPriceUpdates: new Internal.GasPriceUpdate[](0) + }); + priceUpdates.tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[0], usdPerToken: 4e18}); + + // Revert when caller is not authorized + vm.startPrank(STRANGER); + vm.expectRevert(abi.encodeWithSelector(AuthorizedCallers.UnauthorizedCaller.selector, STRANGER)); + s_priceRegistry.updatePrices(priceUpdates); + + address[] memory priceUpdaters = new address[](1); + priceUpdaters[0] = STRANGER; + vm.startPrank(OWNER); + s_priceRegistry.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: priceUpdaters, removedCallers: new address[](0)}) + ); + + // Stranger is now an authorized caller to update prices + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated( + priceUpdates.tokenPriceUpdates[0].sourceToken, priceUpdates.tokenPriceUpdates[0].usdPerToken, block.timestamp + ); + s_priceRegistry.updatePrices(priceUpdates); + + assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[0]).value, priceUpdates.tokenPriceUpdates[0].usdPerToken); + + vm.startPrank(OWNER); + s_priceRegistry.applyAuthorizedCallerUpdates( + AuthorizedCallers.AuthorizedCallerArgs({addedCallers: new address[](0), removedCallers: priceUpdaters}) + ); + + // Revert when authorized caller is removed + vm.startPrank(STRANGER); + vm.expectRevert(abi.encodeWithSelector(AuthorizedCallers.UnauthorizedCaller.selector, STRANGER)); + s_priceRegistry.updatePrices(priceUpdates); + } + + // Reverts + + function test_OnlyCallableByUpdater_Revert() public { + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + gasPriceUpdates: new Internal.GasPriceUpdate[](0) + }); + + vm.startPrank(STRANGER); + vm.expectRevert(abi.encodeWithSelector(AuthorizedCallers.UnauthorizedCaller.selector, STRANGER)); + s_priceRegistry.updatePrices(priceUpdates); + } +} + +contract PriceRegistry_convertTokenAmount is PriceRegistrySetup { + function test_ConvertTokenAmount_Success() public view { + Internal.PriceUpdates memory initialPriceUpdates = abi.decode(s_encodedInitialPriceUpdates, (Internal.PriceUpdates)); + uint256 amount = 3e16; + uint256 conversionRate = (uint256(initialPriceUpdates.tokenPriceUpdates[2].usdPerToken) * 1e18) + / uint256(initialPriceUpdates.tokenPriceUpdates[0].usdPerToken); + uint256 expected = (amount * conversionRate) / 1e18; + assertEq(s_priceRegistry.convertTokenAmount(s_weth, amount, s_sourceTokens[0]), expected); + } + + function test_Fuzz_ConvertTokenAmount_Success( + uint256 feeTokenAmount, + uint224 usdPerFeeToken, + uint160 usdPerLinkToken, + uint224 usdPerUnitGas + ) public { + vm.assume(usdPerFeeToken > 0); + vm.assume(usdPerLinkToken > 0); + // We bound the max fees to be at most uint96.max link. + feeTokenAmount = bound(feeTokenAmount, 0, (uint256(type(uint96).max) * usdPerLinkToken) / usdPerFeeToken); + + address feeToken = address(1); + address linkToken = address(2); + address[] memory feeTokens = new address[](1); + feeTokens[0] = feeToken; + s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + + Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](2); + tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: feeToken, usdPerToken: usdPerFeeToken}); + tokenPriceUpdates[1] = Internal.TokenPriceUpdate({sourceToken: linkToken, usdPerToken: usdPerLinkToken}); + + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_SELECTOR, usdPerUnitGas: usdPerUnitGas}); + + Internal.PriceUpdates memory priceUpdates = + Internal.PriceUpdates({tokenPriceUpdates: tokenPriceUpdates, gasPriceUpdates: gasPriceUpdates}); + + s_priceRegistry.updatePrices(priceUpdates); + + uint256 linkFee = s_priceRegistry.convertTokenAmount(feeToken, feeTokenAmount, linkToken); + assertEq(linkFee, (feeTokenAmount * usdPerFeeToken) / usdPerLinkToken); + } + + // Reverts + + function test_LinkTokenNotSupported_Revert() public { + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.TokenNotSupported.selector, DUMMY_CONTRACT_ADDRESS)); + s_priceRegistry.convertTokenAmount(DUMMY_CONTRACT_ADDRESS, 3e16, s_sourceTokens[0]); + + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.TokenNotSupported.selector, DUMMY_CONTRACT_ADDRESS)); + s_priceRegistry.convertTokenAmount(s_sourceTokens[0], 3e16, DUMMY_CONTRACT_ADDRESS); + } +} + +contract PriceRegistry_getTokenAndGasPrices is PriceRegistrySetup { + function test_GetFeeTokenAndGasPrices_Success() public view { + (uint224 feeTokenPrice, uint224 gasPrice) = + s_priceRegistry.getTokenAndGasPrices(s_sourceFeeToken, DEST_CHAIN_SELECTOR); + + Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedInitialPriceUpdates, (Internal.PriceUpdates)); + + assertEq(feeTokenPrice, s_sourceTokenPrices[0]); + assertEq(gasPrice, priceUpdates.gasPriceUpdates[0].usdPerUnitGas); + } + + function test_ZeroGasPrice_Success() public { + uint64 zeroGasDestChainSelector = 345678; + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: zeroGasDestChainSelector, usdPerUnitGas: 0}); + + Internal.PriceUpdates memory priceUpdates = + Internal.PriceUpdates({tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), gasPriceUpdates: gasPriceUpdates}); + s_priceRegistry.updatePrices(priceUpdates); + + (, uint224 gasPrice) = s_priceRegistry.getTokenAndGasPrices(s_sourceFeeToken, zeroGasDestChainSelector); + + assertEq(gasPrice, priceUpdates.gasPriceUpdates[0].usdPerUnitGas); + } + + function test_UnsupportedChain_Revert() public { + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.ChainNotSupported.selector, DEST_CHAIN_SELECTOR + 1)); + s_priceRegistry.getTokenAndGasPrices(s_sourceTokens[0], DEST_CHAIN_SELECTOR + 1); + } + + function test_StaleGasPrice_Revert() public { + uint256 diff = TWELVE_HOURS + 1; + vm.warp(block.timestamp + diff); + vm.expectRevert( + abi.encodeWithSelector(PriceRegistry.StaleGasPrice.selector, DEST_CHAIN_SELECTOR, TWELVE_HOURS, diff) + ); + s_priceRegistry.getTokenAndGasPrices(s_sourceTokens[0], DEST_CHAIN_SELECTOR); + } +} + +contract PriceRegistry_updateTokenPriceFeeds is PriceRegistrySetup { + function test_ZeroFeeds_Success() public { + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](0); + vm.recordLogs(); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + + // Verify no log emissions + assertEq(logEntries.length, 0); + } + + function test_SingleFeedUpdate_Success() public { + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = + getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); + + _assertTokenPriceFeedConfigUnconfigured( + s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken) + ); + + vm.expectEmit(); + emit PriceRegistry.PriceFeedPerTokenUpdated( + tokenPriceFeedUpdates[0].sourceToken, tokenPriceFeedUpdates[0].feedConfig + ); + + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + + _assertTokenPriceFeedConfigEquality( + s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig + ); + } + + function test_MultipleFeedUpdate_Success() public { + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](2); + + for (uint256 i = 0; i < 2; ++i) { + tokenPriceFeedUpdates[i] = + getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[i], s_dataFeedByToken[s_sourceTokens[i]], 18); + + _assertTokenPriceFeedConfigUnconfigured( + s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[i].sourceToken) + ); + + vm.expectEmit(); + emit PriceRegistry.PriceFeedPerTokenUpdated( + tokenPriceFeedUpdates[i].sourceToken, tokenPriceFeedUpdates[i].feedConfig + ); + } + + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + + _assertTokenPriceFeedConfigEquality( + s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig + ); + _assertTokenPriceFeedConfigEquality( + s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[1].sourceToken), tokenPriceFeedUpdates[1].feedConfig + ); + } + + function test_FeedUnset_Success() public { + Internal.TimestampedPackedUint224 memory priceQueryInitial = s_priceRegistry.getTokenPrice(s_sourceTokens[0]); + assertFalse(priceQueryInitial.value == 0); + assertFalse(priceQueryInitial.timestamp == 0); + + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = + getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); + + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + _assertTokenPriceFeedConfigEquality( + s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig + ); + + tokenPriceFeedUpdates[0].feedConfig.dataFeedAddress = address(0); + vm.expectEmit(); + emit PriceRegistry.PriceFeedPerTokenUpdated( + tokenPriceFeedUpdates[0].sourceToken, tokenPriceFeedUpdates[0].feedConfig + ); + + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + _assertTokenPriceFeedConfigEquality( + s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig + ); + + // Price data should remain after a feed has been set->unset + Internal.TimestampedPackedUint224 memory priceQueryPostUnsetFeed = s_priceRegistry.getTokenPrice(s_sourceTokens[0]); + assertEq(priceQueryPostUnsetFeed.value, priceQueryInitial.value); + assertEq(priceQueryPostUnsetFeed.timestamp, priceQueryInitial.timestamp); + } + + function test_FeedNotUpdated() public { + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = + getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); + + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + + _assertTokenPriceFeedConfigEquality( + s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig + ); + } + + // Reverts + + function test_FeedUpdatedByNonOwner_Revert() public { + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = + getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); + + vm.startPrank(STRANGER); + vm.expectRevert("Only callable by owner"); + + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + } +} + +contract PriceRegistry_applyDestChainConfigUpdates is PriceRegistrySetup { + function test_Fuzz_applyDestChainConfigUpdates_Success(PriceRegistry.DestChainConfigArgs memory destChainConfigArgs) + public + { + vm.assume(destChainConfigArgs.destChainSelector != 0); + vm.assume(destChainConfigArgs.destChainConfig.maxPerMsgGasLimit != 0); + destChainConfigArgs.destChainConfig.defaultTxGasLimit = uint32( + bound( + destChainConfigArgs.destChainConfig.defaultTxGasLimit, 1, destChainConfigArgs.destChainConfig.maxPerMsgGasLimit + ) + ); + destChainConfigArgs.destChainConfig.defaultTokenDestBytesOverhead = uint32( + bound( + destChainConfigArgs.destChainConfig.defaultTokenDestBytesOverhead, + Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, + type(uint32).max + ) + ); + destChainConfigArgs.destChainConfig.chainFamilySelector = Internal.CHAIN_FAMILY_SELECTOR_EVM; + + bool isNewChain = destChainConfigArgs.destChainSelector != DEST_CHAIN_SELECTOR; + + PriceRegistry.DestChainConfigArgs[] memory newDestChainConfigArgs = new PriceRegistry.DestChainConfigArgs[](1); + newDestChainConfigArgs[0] = destChainConfigArgs; + + if (isNewChain) { + vm.expectEmit(); + emit PriceRegistry.DestChainAdded(destChainConfigArgs.destChainSelector, destChainConfigArgs.destChainConfig); + } else { + vm.expectEmit(); + emit PriceRegistry.DestChainConfigUpdated( + destChainConfigArgs.destChainSelector, destChainConfigArgs.destChainConfig + ); + } + + s_priceRegistry.applyDestChainConfigUpdates(newDestChainConfigArgs); + + _assertPriceRegistryDestChainConfigsEqual( + destChainConfigArgs.destChainConfig, s_priceRegistry.getDestChainConfig(destChainConfigArgs.destChainSelector) + ); + } + + function test_applyDestChainConfigUpdates_Success() public { + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = new PriceRegistry.DestChainConfigArgs[](2); + destChainConfigArgs[0] = _generatePriceRegistryDestChainConfigArgs()[0]; + destChainConfigArgs[0].destChainConfig.isEnabled = false; + destChainConfigArgs[1] = _generatePriceRegistryDestChainConfigArgs()[0]; + destChainConfigArgs[1].destChainSelector = DEST_CHAIN_SELECTOR + 1; + + vm.expectEmit(); + emit PriceRegistry.DestChainConfigUpdated(DEST_CHAIN_SELECTOR, destChainConfigArgs[0].destChainConfig); + vm.expectEmit(); + emit PriceRegistry.DestChainAdded(DEST_CHAIN_SELECTOR + 1, destChainConfigArgs[1].destChainConfig); + + vm.recordLogs(); + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + + PriceRegistry.DestChainConfig memory gotDestChainConfig0 = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + PriceRegistry.DestChainConfig memory gotDestChainConfig1 = + s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR + 1); + + assertEq(vm.getRecordedLogs().length, 2); + _assertPriceRegistryDestChainConfigsEqual(destChainConfigArgs[0].destChainConfig, gotDestChainConfig0); + _assertPriceRegistryDestChainConfigsEqual(destChainConfigArgs[1].destChainConfig, gotDestChainConfig1); + } + + function test_applyDestChainConfigUpdatesZeroIntput_Success() public { + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = new PriceRegistry.DestChainConfigArgs[](0); + + vm.recordLogs(); + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + + assertEq(vm.getRecordedLogs().length, 0); + } + + // Reverts + + function test_applyDestChainConfigUpdatesDefaultTxGasLimitEqZero_Revert() public { + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + PriceRegistry.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; + + destChainConfigArg.destChainConfig.defaultTxGasLimit = 0; + vm.expectRevert( + abi.encodeWithSelector(PriceRegistry.InvalidDestChainConfig.selector, destChainConfigArg.destChainSelector) + ); + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + } + + function test_applyDestChainConfigUpdatesDefaultTxGasLimitGtMaxPerMessageGasLimit_Revert() public { + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + PriceRegistry.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; + + // Allow setting to the max value + destChainConfigArg.destChainConfig.defaultTxGasLimit = destChainConfigArg.destChainConfig.maxPerMsgGasLimit; + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + + // Revert when exceeding max value + destChainConfigArg.destChainConfig.defaultTxGasLimit = destChainConfigArg.destChainConfig.maxPerMsgGasLimit + 1; + vm.expectRevert( + abi.encodeWithSelector(PriceRegistry.InvalidDestChainConfig.selector, destChainConfigArg.destChainSelector) + ); + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + } + + function test_InvalidDestChainConfigDestChainSelectorEqZero_Revert() public { + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + PriceRegistry.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; + + destChainConfigArg.destChainSelector = 0; + vm.expectRevert( + abi.encodeWithSelector(PriceRegistry.InvalidDestChainConfig.selector, destChainConfigArg.destChainSelector) + ); + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + } + + function test_InvalidDestBytesOverhead_Revert() public { + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + PriceRegistry.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; + + destChainConfigArg.destChainConfig.defaultTokenDestBytesOverhead = uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES - 1); + + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.InvalidDestChainConfig.selector, DEST_CHAIN_SELECTOR)); + + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + } + + function test_InvalidChainFamilySelector_Revert() public { + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + PriceRegistry.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; + + destChainConfigArg.destChainConfig.chainFamilySelector = bytes4(uint32(1)); + + vm.expectRevert( + abi.encodeWithSelector(PriceRegistry.InvalidDestChainConfig.selector, destChainConfigArg.destChainSelector) + ); + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + } +} + +contract PriceRegistry_getDataAvailabilityCost is PriceRegistrySetup { + function test_EmptyMessageCalculatesDataAvailabilityCost_Success() public { + uint256 dataAvailabilityCostUSD = + s_priceRegistry.getDataAvailabilityCost(DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, 0, 0, 0); + + PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + + uint256 dataAvailabilityGas = destChainConfig.destDataAvailabilityOverheadGas + + destChainConfig.destGasPerDataAvailabilityByte * Internal.ANY_2_EVM_MESSAGE_FIXED_BYTES; + uint256 expectedDataAvailabilityCostUSD = + USD_PER_DATA_AVAILABILITY_GAS * dataAvailabilityGas * destChainConfig.destDataAvailabilityMultiplierBps * 1e14; + + assertEq(expectedDataAvailabilityCostUSD, dataAvailabilityCostUSD); + + // Test that the cost is destnation chain specific + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + destChainConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR + 1; + destChainConfigArgs[0].destChainConfig.destDataAvailabilityOverheadGas = + destChainConfig.destDataAvailabilityOverheadGas * 2; + destChainConfigArgs[0].destChainConfig.destGasPerDataAvailabilityByte = + destChainConfig.destGasPerDataAvailabilityByte * 2; + destChainConfigArgs[0].destChainConfig.destDataAvailabilityMultiplierBps = + destChainConfig.destDataAvailabilityMultiplierBps * 2; + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + + destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR + 1); + uint256 dataAvailabilityCostUSD2 = + s_priceRegistry.getDataAvailabilityCost(DEST_CHAIN_SELECTOR + 1, USD_PER_DATA_AVAILABILITY_GAS, 0, 0, 0); + dataAvailabilityGas = destChainConfig.destDataAvailabilityOverheadGas + + destChainConfig.destGasPerDataAvailabilityByte * Internal.ANY_2_EVM_MESSAGE_FIXED_BYTES; + expectedDataAvailabilityCostUSD = + USD_PER_DATA_AVAILABILITY_GAS * dataAvailabilityGas * destChainConfig.destDataAvailabilityMultiplierBps * 1e14; + + assertEq(expectedDataAvailabilityCostUSD, dataAvailabilityCostUSD2); + assertFalse(dataAvailabilityCostUSD == dataAvailabilityCostUSD2); + } + + function test_SimpleMessageCalculatesDataAvailabilityCost_Success() public view { + uint256 dataAvailabilityCostUSD = + s_priceRegistry.getDataAvailabilityCost(DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, 100, 5, 50); + + PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + + uint256 dataAvailabilityLengthBytes = + Internal.ANY_2_EVM_MESSAGE_FIXED_BYTES + 100 + (5 * Internal.ANY_2_EVM_MESSAGE_FIXED_BYTES_PER_TOKEN) + 50; + uint256 dataAvailabilityGas = destChainConfig.destDataAvailabilityOverheadGas + + destChainConfig.destGasPerDataAvailabilityByte * dataAvailabilityLengthBytes; + uint256 expectedDataAvailabilityCostUSD = + USD_PER_DATA_AVAILABILITY_GAS * dataAvailabilityGas * destChainConfig.destDataAvailabilityMultiplierBps * 1e14; + + assertEq(expectedDataAvailabilityCostUSD, dataAvailabilityCostUSD); + } + + function test_SimpleMessageCalculatesDataAvailabilityCostUnsupportedDestChainSelector_Success() public view { + uint256 dataAvailabilityCostUSD = + s_priceRegistry.getDataAvailabilityCost(0, USD_PER_DATA_AVAILABILITY_GAS, 100, 5, 50); + + assertEq(dataAvailabilityCostUSD, 0); + } + + function test_Fuzz_ZeroDataAvailabilityGasPriceAlwaysCalculatesZeroDataAvailabilityCost_Success( + uint64 messageDataLength, + uint32 numberOfTokens, + uint32 tokenTransferBytesOverhead + ) public view { + uint256 dataAvailabilityCostUSD = s_priceRegistry.getDataAvailabilityCost( + DEST_CHAIN_SELECTOR, 0, messageDataLength, numberOfTokens, tokenTransferBytesOverhead + ); + + assertEq(0, dataAvailabilityCostUSD); + } + + function test_Fuzz_CalculateDataAvailabilityCost_Success( + uint64 destChainSelector, + uint32 destDataAvailabilityOverheadGas, + uint16 destGasPerDataAvailabilityByte, + uint16 destDataAvailabilityMultiplierBps, + uint112 dataAvailabilityGasPrice, + uint64 messageDataLength, + uint32 numberOfTokens, + uint32 tokenTransferBytesOverhead + ) public { + vm.assume(destChainSelector != 0); + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = new PriceRegistry.DestChainConfigArgs[](1); + PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(destChainSelector); + destChainConfigArgs[0] = + PriceRegistry.DestChainConfigArgs({destChainSelector: destChainSelector, destChainConfig: destChainConfig}); + destChainConfigArgs[0].destChainConfig.destDataAvailabilityOverheadGas = destDataAvailabilityOverheadGas; + destChainConfigArgs[0].destChainConfig.destGasPerDataAvailabilityByte = destGasPerDataAvailabilityByte; + destChainConfigArgs[0].destChainConfig.destDataAvailabilityMultiplierBps = destDataAvailabilityMultiplierBps; + destChainConfigArgs[0].destChainConfig.defaultTxGasLimit = GAS_LIMIT; + destChainConfigArgs[0].destChainConfig.maxPerMsgGasLimit = GAS_LIMIT; + destChainConfigArgs[0].destChainConfig.chainFamilySelector = Internal.CHAIN_FAMILY_SELECTOR_EVM; + destChainConfigArgs[0].destChainConfig.defaultTokenDestBytesOverhead = DEFAULT_TOKEN_BYTES_OVERHEAD; + + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + + uint256 dataAvailabilityCostUSD = s_priceRegistry.getDataAvailabilityCost( + destChainConfigArgs[0].destChainSelector, + dataAvailabilityGasPrice, + messageDataLength, + numberOfTokens, + tokenTransferBytesOverhead + ); + + uint256 dataAvailabilityLengthBytes = Internal.ANY_2_EVM_MESSAGE_FIXED_BYTES + messageDataLength + + (numberOfTokens * Internal.ANY_2_EVM_MESSAGE_FIXED_BYTES_PER_TOKEN) + tokenTransferBytesOverhead; + + uint256 dataAvailabilityGas = + destDataAvailabilityOverheadGas + destGasPerDataAvailabilityByte * dataAvailabilityLengthBytes; + uint256 expectedDataAvailabilityCostUSD = + dataAvailabilityGasPrice * dataAvailabilityGas * destDataAvailabilityMultiplierBps * 1e14; + + assertEq(expectedDataAvailabilityCostUSD, dataAvailabilityCostUSD); + } +} + +contract PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates is PriceRegistrySetup { + function test_Fuzz_applyPremiumMultiplierWeiPerEthUpdates_Success( + PriceRegistry.PremiumMultiplierWeiPerEthArgs memory premiumMultiplierWeiPerEthArg + ) public { + PriceRegistry.PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs = + new PriceRegistry.PremiumMultiplierWeiPerEthArgs[](1); + premiumMultiplierWeiPerEthArgs[0] = premiumMultiplierWeiPerEthArg; + + vm.expectEmit(); + emit PriceRegistry.PremiumMultiplierWeiPerEthUpdated( + premiumMultiplierWeiPerEthArg.token, premiumMultiplierWeiPerEthArg.premiumMultiplierWeiPerEth + ); + + s_priceRegistry.applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); + + assertEq( + premiumMultiplierWeiPerEthArg.premiumMultiplierWeiPerEth, + s_priceRegistry.getPremiumMultiplierWeiPerEth(premiumMultiplierWeiPerEthArg.token) + ); + } + + function test_applyPremiumMultiplierWeiPerEthUpdatesSingleToken_Success() public { + PriceRegistry.PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs = + new PriceRegistry.PremiumMultiplierWeiPerEthArgs[](1); + premiumMultiplierWeiPerEthArgs[0] = s_priceRegistryPremiumMultiplierWeiPerEthArgs[0]; + premiumMultiplierWeiPerEthArgs[0].token = vm.addr(1); + + vm.expectEmit(); + emit PriceRegistry.PremiumMultiplierWeiPerEthUpdated( + vm.addr(1), premiumMultiplierWeiPerEthArgs[0].premiumMultiplierWeiPerEth + ); + + s_priceRegistry.applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); + + assertEq( + s_priceRegistryPremiumMultiplierWeiPerEthArgs[0].premiumMultiplierWeiPerEth, + s_priceRegistry.getPremiumMultiplierWeiPerEth(vm.addr(1)) + ); + } + + function test_applyPremiumMultiplierWeiPerEthUpdatesMultipleTokens_Success() public { + PriceRegistry.PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs = + new PriceRegistry.PremiumMultiplierWeiPerEthArgs[](2); + premiumMultiplierWeiPerEthArgs[0] = s_priceRegistryPremiumMultiplierWeiPerEthArgs[0]; + premiumMultiplierWeiPerEthArgs[0].token = vm.addr(1); + premiumMultiplierWeiPerEthArgs[1].token = vm.addr(2); + + vm.expectEmit(); + emit PriceRegistry.PremiumMultiplierWeiPerEthUpdated( + vm.addr(1), premiumMultiplierWeiPerEthArgs[0].premiumMultiplierWeiPerEth + ); + vm.expectEmit(); + emit PriceRegistry.PremiumMultiplierWeiPerEthUpdated( + vm.addr(2), premiumMultiplierWeiPerEthArgs[1].premiumMultiplierWeiPerEth + ); + + s_priceRegistry.applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); + + assertEq( + premiumMultiplierWeiPerEthArgs[0].premiumMultiplierWeiPerEth, + s_priceRegistry.getPremiumMultiplierWeiPerEth(vm.addr(1)) + ); + assertEq( + premiumMultiplierWeiPerEthArgs[1].premiumMultiplierWeiPerEth, + s_priceRegistry.getPremiumMultiplierWeiPerEth(vm.addr(2)) + ); + } + + function test_applyPremiumMultiplierWeiPerEthUpdatesZeroInput() public { + vm.recordLogs(); + s_priceRegistry.applyPremiumMultiplierWeiPerEthUpdates(new PriceRegistry.PremiumMultiplierWeiPerEthArgs[](0)); + + assertEq(vm.getRecordedLogs().length, 0); + } + + // Reverts + + function test_OnlyCallableByOwnerOrAdmin_Revert() public { + PriceRegistry.PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs; + vm.startPrank(STRANGER); + + vm.expectRevert("Only callable by owner"); + + s_priceRegistry.applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); + } +} + +contract PriceRegistry_applyTokenTransferFeeConfigUpdates is PriceRegistrySetup { + function test_Fuzz_ApplyTokenTransferFeeConfig_Success( + PriceRegistry.TokenTransferFeeConfig[2] memory tokenTransferFeeConfigs + ) public { + PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + _generateTokenTransferFeeConfigArgs(2, 2); + tokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; + tokenTransferFeeConfigArgs[1].destChainSelector = DEST_CHAIN_SELECTOR + 1; + + for (uint256 i = 0; i < tokenTransferFeeConfigArgs.length; ++i) { + for (uint256 j = 0; j < tokenTransferFeeConfigs.length; ++j) { + tokenTransferFeeConfigs[j].destBytesOverhead = uint32( + bound(tokenTransferFeeConfigs[j].destBytesOverhead, Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, type(uint32).max) + ); + address feeToken = s_sourceTokens[j]; + tokenTransferFeeConfigArgs[i].tokenTransferFeeConfigs[j].token = feeToken; + tokenTransferFeeConfigArgs[i].tokenTransferFeeConfigs[j].tokenTransferFeeConfig = tokenTransferFeeConfigs[j]; + + vm.expectEmit(); + emit PriceRegistry.TokenTransferFeeConfigUpdated( + tokenTransferFeeConfigArgs[i].destChainSelector, feeToken, tokenTransferFeeConfigs[j] + ); + } + } + + s_priceRegistry.applyTokenTransferFeeConfigUpdates( + tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + ); + + for (uint256 i = 0; i < tokenTransferFeeConfigs.length; ++i) { + _assertTokenTransferFeeConfigEqual( + tokenTransferFeeConfigs[i], + s_priceRegistry.getTokenTransferFeeConfig( + tokenTransferFeeConfigArgs[0].destChainSelector, + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[i].token + ) + ); + } + } + + function test_ApplyTokenTransferFeeConfig_Success() public { + PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + _generateTokenTransferFeeConfigArgs(1, 2); + tokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token = address(5); + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = PriceRegistry + .TokenTransferFeeConfig({ + minFeeUSDCents: 6, + maxFeeUSDCents: 7, + deciBps: 8, + destGasOverhead: 9, + destBytesOverhead: 312, + isEnabled: true + }); + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].token = address(11); + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig = PriceRegistry + .TokenTransferFeeConfig({ + minFeeUSDCents: 12, + maxFeeUSDCents: 13, + deciBps: 14, + destGasOverhead: 15, + destBytesOverhead: 394, + isEnabled: true + }); + + vm.expectEmit(); + emit PriceRegistry.TokenTransferFeeConfigUpdated( + tokenTransferFeeConfigArgs[0].destChainSelector, + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token, + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig + ); + vm.expectEmit(); + emit PriceRegistry.TokenTransferFeeConfigUpdated( + tokenTransferFeeConfigArgs[0].destChainSelector, + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].token, + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig + ); + + PriceRegistry.TokenTransferFeeConfigRemoveArgs[] memory tokensToRemove = + new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0); + s_priceRegistry.applyTokenTransferFeeConfigUpdates(tokenTransferFeeConfigArgs, tokensToRemove); + + PriceRegistry.TokenTransferFeeConfig memory config0 = s_priceRegistry.getTokenTransferFeeConfig( + tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token + ); + PriceRegistry.TokenTransferFeeConfig memory config1 = s_priceRegistry.getTokenTransferFeeConfig( + tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].token + ); + + _assertTokenTransferFeeConfigEqual( + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig, config0 + ); + _assertTokenTransferFeeConfigEqual( + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig, config1 + ); + + // Remove only the first token and validate only the first token is removed + tokensToRemove = new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](1); + tokensToRemove[0] = PriceRegistry.TokenTransferFeeConfigRemoveArgs({ + destChainSelector: tokenTransferFeeConfigArgs[0].destChainSelector, + token: tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token + }); + + vm.expectEmit(); + emit PriceRegistry.TokenTransferFeeConfigDeleted( + tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token + ); + + s_priceRegistry.applyTokenTransferFeeConfigUpdates( + new PriceRegistry.TokenTransferFeeConfigArgs[](0), tokensToRemove + ); + + config0 = s_priceRegistry.getTokenTransferFeeConfig( + tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token + ); + config1 = s_priceRegistry.getTokenTransferFeeConfig( + tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].token + ); + + PriceRegistry.TokenTransferFeeConfig memory emptyConfig; + + _assertTokenTransferFeeConfigEqual(emptyConfig, config0); + _assertTokenTransferFeeConfigEqual( + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig, config1 + ); + } + + function test_ApplyTokenTransferFeeZeroInput() public { + vm.recordLogs(); + s_priceRegistry.applyTokenTransferFeeConfigUpdates( + new PriceRegistry.TokenTransferFeeConfigArgs[](0), new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + ); + + assertEq(vm.getRecordedLogs().length, 0); + } + + // Reverts + + function test_OnlyCallableByOwnerOrAdmin_Revert() public { + vm.startPrank(STRANGER); + PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs; + + vm.expectRevert("Only callable by owner"); + + s_priceRegistry.applyTokenTransferFeeConfigUpdates( + tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + ); + } + + function test_InvalidDestBytesOverhead_Revert() public { + PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + _generateTokenTransferFeeConfigArgs(1, 1); + tokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token = address(5); + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = PriceRegistry + .TokenTransferFeeConfig({ + minFeeUSDCents: 6, + maxFeeUSDCents: 7, + deciBps: 8, + destGasOverhead: 9, + destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES - 1), + isEnabled: true + }); + + vm.expectRevert( + abi.encodeWithSelector( + PriceRegistry.InvalidDestBytesOverhead.selector, + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token, + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig.destBytesOverhead + ) + ); + + s_priceRegistry.applyTokenTransferFeeConfigUpdates( + tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + ); + } +} + +contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { + using USDPriceWith18Decimals for uint224; + + function test_NoTokenTransferChargesZeroFee_Success() public view { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + assertEq(0, feeUSDWei); + assertEq(0, destGasOverhead); + assertEq(0, destBytesOverhead); + } + + function test_getTokenTransferCost_selfServeUsesDefaults_Success() public view { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_selfServeTokenDefaultPricing, 1000); + + // Get config to assert it isn't set + PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + + assertFalse(transferFeeConfig.isEnabled); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + // Assert that the default values are used + assertEq(uint256(DEFAULT_TOKEN_FEE_USD_CENTS) * 1e16, feeUSDWei); + assertEq(DEFAULT_TOKEN_DEST_GAS_OVERHEAD, destGasOverhead); + assertEq(DEFAULT_TOKEN_BYTES_OVERHEAD, destBytesOverhead); + } + + function test_SmallTokenTransferChargesMinFeeAndGas_Success() public view { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1000); + PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + assertEq(configUSDCentToWei(transferFeeConfig.minFeeUSDCents), feeUSDWei); + assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); + assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); + } + + function test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() public view { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 0); + PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + assertEq(configUSDCentToWei(transferFeeConfig.minFeeUSDCents), feeUSDWei); + assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); + assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); + } + + function test_LargeTokenTransferChargesMaxFeeAndGas_Success() public view { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1e36); + PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + assertEq(configUSDCentToWei(transferFeeConfig.maxFeeUSDCents), feeUSDWei); + assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); + assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); + } + + function test_FeeTokenBpsFee_Success() public view { + uint256 tokenAmount = 10000e18; + + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, tokenAmount); + PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + uint256 usdWei = calcUSDValueFromTokenAmount(s_feeTokenPrice, tokenAmount); + uint256 bpsUSDWei = applyBpsRatio( + usdWei, s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig.deciBps + ); + + assertEq(bpsUSDWei, feeUSDWei); + assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); + assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); + } + + function test_WETHTokenBpsFee_Success() public view { + uint256 tokenAmount = 100e18; + + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: new Client.EVMTokenAmount[](1), + feeToken: s_sourceRouter.getWrappedNative(), + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + message.tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceRouter.getWrappedNative(), amount: tokenAmount}); + + PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = s_priceRegistry.getTokenTransferCost( + DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts + ); + + uint256 usdWei = calcUSDValueFromTokenAmount(s_wrappedTokenPrice, tokenAmount); + uint256 bpsUSDWei = applyBpsRatio( + usdWei, s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig.deciBps + ); + + assertEq(bpsUSDWei, feeUSDWei); + assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); + assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); + } + + function test_CustomTokenBpsFee_Success() public view { + uint256 tokenAmount = 200000e18; + + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: new Client.EVMTokenAmount[](1), + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + message.tokenAmounts[0] = Client.EVMTokenAmount({token: CUSTOM_TOKEN, amount: tokenAmount}); + + PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + uint256 usdWei = calcUSDValueFromTokenAmount(s_customTokenPrice, tokenAmount); + uint256 bpsUSDWei = applyBpsRatio( + usdWei, s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[2].tokenTransferFeeConfig.deciBps + ); + + assertEq(bpsUSDWei, feeUSDWei); + assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); + assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); + } + + function test_ZeroFeeConfigChargesMinFee_Success() public { + PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + _generateTokenTransferFeeConfigArgs(1, 1); + tokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token = s_sourceFeeToken; + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = PriceRegistry + .TokenTransferFeeConfig({ + minFeeUSDCents: 1, + maxFeeUSDCents: 0, + deciBps: 0, + destGasOverhead: 0, + destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES), + isEnabled: true + }); + s_priceRegistry.applyTokenTransferFeeConfigUpdates( + tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + ); + + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1e36); + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + + // if token charges 0 bps, it should cost minFee to transfer + assertEq( + configUSDCentToWei(tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig.minFeeUSDCents), + feeUSDWei + ); + assertEq(0, destGasOverhead); + assertEq(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, destBytesOverhead); + } + + function test_Fuzz_TokenTransferFeeDuplicateTokens_Success(uint256 transfers, uint256 amount) public view { + // It shouldn't be possible to pay materially lower fees by splitting up the transfers. + // Note it is possible to pay higher fees since the minimum fees are added. + PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + transfers = bound(transfers, 1, destChainConfig.maxNumberOfTokensPerMsg); + // Cap amount to avoid overflow + amount = bound(amount, 0, 1e36); + Client.EVMTokenAmount[] memory multiple = new Client.EVMTokenAmount[](transfers); + for (uint256 i = 0; i < transfers; ++i) { + multiple[i] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: amount}); + } + Client.EVMTokenAmount[] memory single = new Client.EVMTokenAmount[](1); + single[0] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: amount * transfers}); + + address feeToken = s_sourceRouter.getWrappedNative(); + + (uint256 feeSingleUSDWei, uint32 gasOverheadSingle, uint32 bytesOverheadSingle) = + s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, feeToken, s_wrappedTokenPrice, single); + (uint256 feeMultipleUSDWei, uint32 gasOverheadMultiple, uint32 bytesOverheadMultiple) = + s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, feeToken, s_wrappedTokenPrice, multiple); + + // Note that there can be a rounding error once per split. + assertGe(feeMultipleUSDWei, (feeSingleUSDWei - destChainConfig.maxNumberOfTokensPerMsg)); + assertEq(gasOverheadMultiple, gasOverheadSingle * transfers); + assertEq(bytesOverheadMultiple, bytesOverheadSingle * transfers); + } + + function test_MixedTokenTransferFee_Success() public view { + address[3] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative(), CUSTOM_TOKEN]; + uint224[3] memory tokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice, s_customTokenPrice]; + PriceRegistry.TokenTransferFeeConfig[3] memory tokenTransferFeeConfigs = [ + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[0]), + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[1]), + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[2]) + ]; + + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: new Client.EVMTokenAmount[](3), + feeToken: s_sourceRouter.getWrappedNative(), + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + uint256 expectedTotalGas = 0; + uint256 expectedTotalBytes = 0; + + // Start with small token transfers, total bps fee is lower than min token transfer fee + for (uint256 i = 0; i < testTokens.length; ++i) { + message.tokenAmounts[i] = Client.EVMTokenAmount({token: testTokens[i], amount: 1e14}); + expectedTotalGas += s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[i]).destGasOverhead; + expectedTotalBytes += + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[i]).destBytesOverhead; + } + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = s_priceRegistry.getTokenTransferCost( + DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts + ); + + uint256 expectedFeeUSDWei = 0; + for (uint256 i = 0; i < testTokens.length; ++i) { + expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[i].minFeeUSDCents); + } + + assertEq(expectedFeeUSDWei, feeUSDWei); + assertEq(expectedTotalGas, destGasOverhead); + assertEq(expectedTotalBytes, destBytesOverhead); + + // Set 1st token transfer to a meaningful amount so its bps fee is now between min and max fee + message.tokenAmounts[0] = Client.EVMTokenAmount({token: testTokens[0], amount: 10000e18}); + + (feeUSDWei, destGasOverhead, destBytesOverhead) = s_priceRegistry.getTokenTransferCost( + DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts + ); + expectedFeeUSDWei = applyBpsRatio( + calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), tokenTransferFeeConfigs[0].deciBps + ); + expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[1].minFeeUSDCents); + expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); + + assertEq(expectedFeeUSDWei, feeUSDWei); + assertEq(expectedTotalGas, destGasOverhead); + assertEq(expectedTotalBytes, destBytesOverhead); + + // Set 2nd token transfer to a large amount that is higher than maxFeeUSD + message.tokenAmounts[1] = Client.EVMTokenAmount({token: testTokens[1], amount: 1e36}); + + (feeUSDWei, destGasOverhead, destBytesOverhead) = s_priceRegistry.getTokenTransferCost( + DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts + ); + expectedFeeUSDWei = applyBpsRatio( + calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), tokenTransferFeeConfigs[0].deciBps + ); + expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[1].maxFeeUSDCents); + expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); + + assertEq(expectedFeeUSDWei, feeUSDWei); + assertEq(expectedTotalGas, destGasOverhead); + assertEq(expectedTotalBytes, destBytesOverhead); + } +} + +contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { + using USDPriceWith18Decimals for uint224; + + function test_EmptyMessage_Success() public view { + address[2] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative()]; + uint224[2] memory feeTokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice]; + + for (uint256 i = 0; i < feeTokenPrices.length; ++i) { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = testTokens[i]; + uint64 premiumMultiplierWeiPerEth = s_priceRegistry.getPremiumMultiplierWeiPerEth(message.feeToken); + PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + + uint256 feeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + + uint256 gasUsed = GAS_LIMIT + DEST_GAS_OVERHEAD; + uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); + uint256 messageFeeUSD = (configUSDCentToWei(destChainConfig.networkFeeUSDCents) * premiumMultiplierWeiPerEth); + uint256 dataAvailabilityFeeUSD = s_priceRegistry.getDataAvailabilityCost( + DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, message.data.length, message.tokenAmounts.length, 0 + ); + + uint256 totalPriceInFeeToken = (gasFeeUSD + messageFeeUSD + dataAvailabilityFeeUSD) / feeTokenPrices[i]; + assertEq(totalPriceInFeeToken, feeAmount); + } + } + + function test_ZeroDataAvailabilityMultiplier_Success() public { + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = new PriceRegistry.DestChainConfigArgs[](1); + PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + destChainConfigArgs[0] = + PriceRegistry.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, destChainConfig: destChainConfig}); + destChainConfigArgs[0].destChainConfig.destDataAvailabilityMultiplierBps = 0; + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + uint64 premiumMultiplierWeiPerEth = s_priceRegistry.getPremiumMultiplierWeiPerEth(message.feeToken); + + uint256 feeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + + uint256 gasUsed = GAS_LIMIT + DEST_GAS_OVERHEAD; + uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); + uint256 messageFeeUSD = (configUSDCentToWei(destChainConfig.networkFeeUSDCents) * premiumMultiplierWeiPerEth); + + uint256 totalPriceInFeeToken = (gasFeeUSD + messageFeeUSD) / s_feeTokenPrice; + assertEq(totalPriceInFeeToken, feeAmount); + } + + function test_HighGasMessage_Success() public view { + address[2] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative()]; + uint224[2] memory feeTokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice]; + + uint256 customGasLimit = MAX_GAS_LIMIT; + uint256 customDataSize = MAX_DATA_SIZE; + for (uint256 i = 0; i < feeTokenPrices.length; ++i) { + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: new bytes(customDataSize), + tokenAmounts: new Client.EVMTokenAmount[](0), + feeToken: testTokens[i], + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: customGasLimit})) + }); + + uint64 premiumMultiplierWeiPerEth = s_priceRegistry.getPremiumMultiplierWeiPerEth(message.feeToken); + PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + + uint256 feeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + uint256 gasUsed = customGasLimit + DEST_GAS_OVERHEAD + customDataSize * DEST_GAS_PER_PAYLOAD_BYTE; + uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); + uint256 messageFeeUSD = (configUSDCentToWei(destChainConfig.networkFeeUSDCents) * premiumMultiplierWeiPerEth); + uint256 dataAvailabilityFeeUSD = s_priceRegistry.getDataAvailabilityCost( + DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, message.data.length, message.tokenAmounts.length, 0 + ); + + uint256 totalPriceInFeeToken = (gasFeeUSD + messageFeeUSD + dataAvailabilityFeeUSD) / feeTokenPrices[i]; + assertEq(totalPriceInFeeToken, feeAmount); + } + } + + function test_SingleTokenMessage_Success() public view { + address[2] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative()]; + uint224[2] memory feeTokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice]; + + uint256 tokenAmount = 10000e18; + for (uint256 i = 0; i < feeTokenPrices.length; ++i) { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, tokenAmount); + message.feeToken = testTokens[i]; + PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + uint32 destBytesOverhead = + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token).destBytesOverhead; + uint32 tokenBytesOverhead = + destBytesOverhead == 0 ? uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) : destBytesOverhead; + + uint256 feeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + + uint256 gasUsed = GAS_LIMIT + DEST_GAS_OVERHEAD + + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token).destGasOverhead; + uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); + (uint256 transferFeeUSD,,) = s_priceRegistry.getTokenTransferCost( + DEST_CHAIN_SELECTOR, message.feeToken, feeTokenPrices[i], message.tokenAmounts + ); + uint256 messageFeeUSD = (transferFeeUSD * s_priceRegistry.getPremiumMultiplierWeiPerEth(message.feeToken)); + uint256 dataAvailabilityFeeUSD = s_priceRegistry.getDataAvailabilityCost( + DEST_CHAIN_SELECTOR, + USD_PER_DATA_AVAILABILITY_GAS, + message.data.length, + message.tokenAmounts.length, + tokenBytesOverhead + ); + + uint256 totalPriceInFeeToken = (gasFeeUSD + messageFeeUSD + dataAvailabilityFeeUSD) / feeTokenPrices[i]; + assertEq(totalPriceInFeeToken, feeAmount); + } + } + + function test_MessageWithDataAndTokenTransfer_Success() public view { + address[2] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative()]; + uint224[2] memory feeTokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice]; + + uint256 customGasLimit = 1_000_000; + for (uint256 i = 0; i < feeTokenPrices.length; ++i) { + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: new Client.EVMTokenAmount[](2), + feeToken: testTokens[i], + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: customGasLimit})) + }); + uint64 premiumMultiplierWeiPerEth = s_priceRegistry.getPremiumMultiplierWeiPerEth(message.feeToken); + PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + + message.tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceFeeToken, amount: 10000e18}); // feeTokenAmount + message.tokenAmounts[1] = Client.EVMTokenAmount({token: CUSTOM_TOKEN, amount: 200000e18}); // customTokenAmount + message.data = "random bits and bytes that should be factored into the cost of the message"; + + uint32 tokenGasOverhead = 0; + uint32 tokenBytesOverhead = 0; + for (uint256 j = 0; j < message.tokenAmounts.length; ++j) { + tokenGasOverhead += + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[j].token).destGasOverhead; + uint32 destBytesOverhead = s_priceRegistry.getTokenTransferFeeConfig( + DEST_CHAIN_SELECTOR, message.tokenAmounts[j].token + ).destBytesOverhead; + tokenBytesOverhead += destBytesOverhead == 0 ? uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) : destBytesOverhead; + } + + uint256 gasUsed = + customGasLimit + DEST_GAS_OVERHEAD + message.data.length * DEST_GAS_PER_PAYLOAD_BYTE + tokenGasOverhead; + uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); + (uint256 transferFeeUSD,,) = s_priceRegistry.getTokenTransferCost( + DEST_CHAIN_SELECTOR, message.feeToken, feeTokenPrices[i], message.tokenAmounts + ); + uint256 messageFeeUSD = (transferFeeUSD * premiumMultiplierWeiPerEth); + uint256 dataAvailabilityFeeUSD = s_priceRegistry.getDataAvailabilityCost( + DEST_CHAIN_SELECTOR, + USD_PER_DATA_AVAILABILITY_GAS, + message.data.length, + message.tokenAmounts.length, + tokenBytesOverhead + ); + + uint256 totalPriceInFeeToken = (gasFeeUSD + messageFeeUSD + dataAvailabilityFeeUSD) / feeTokenPrices[i]; + assertEq(totalPriceInFeeToken, s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message)); + } + } + + function test_Fuzz_EnforceOutOfOrder(bool enforce, bool allowOutOfOrderExecution) public { + // Update config to enforce allowOutOfOrderExecution = defaultVal. + vm.stopPrank(); + vm.startPrank(OWNER); + + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + destChainConfigArgs[0].destChainConfig.enforceOutOfOrder = enforce; + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = abi.encodeWithSelector( + Client.EVM_EXTRA_ARGS_V2_TAG, + Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT * 2, allowOutOfOrderExecution: allowOutOfOrderExecution}) + ); + + // If enforcement is on, only true should be allowed. + if (enforce && !allowOutOfOrderExecution) { + vm.expectRevert(PriceRegistry.ExtraArgOutOfOrderExecutionMustBeTrue.selector); + } + s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + } + + // Reverts + + function test_DestinationChainNotEnabled_Revert() public { + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.DestinationChainNotEnabled.selector, DEST_CHAIN_SELECTOR + 1)); + s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR + 1, _generateEmptyMessage()); + } + + function test_EnforceOutOfOrder_Revert() public { + // Update config to enforce allowOutOfOrderExecution = true. + vm.stopPrank(); + vm.startPrank(OWNER); + + PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + destChainConfigArgs[0].destChainConfig.enforceOutOfOrder = true; + s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + vm.stopPrank(); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + // Empty extraArgs to should revert since it enforceOutOfOrder is true. + message.extraArgs = ""; + + vm.expectRevert(PriceRegistry.ExtraArgOutOfOrderExecutionMustBeTrue.selector); + s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + } + + function test_MessageTooLarge_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.data = new bytes(MAX_DATA_SIZE + 1); + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.MessageTooLarge.selector, MAX_DATA_SIZE, message.data.length)); + + s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + } + + function test_TooManyTokens_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + uint256 tooMany = MAX_TOKENS_LENGTH + 1; + message.tokenAmounts = new Client.EVMTokenAmount[](tooMany); + vm.expectRevert(PriceRegistry.UnsupportedNumberOfTokens.selector); + s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + } + + // Asserts gasLimit must be <=maxGasLimit + function test_MessageGasLimitTooHigh_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: MAX_GAS_LIMIT + 1})); + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.MessageGasLimitTooHigh.selector)); + s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + } + + function test_NotAFeeToken_Revert() public { + address notAFeeToken = address(0x111111); + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(notAFeeToken, 1); + message.feeToken = notAFeeToken; + + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.TokenNotSupported.selector, notAFeeToken)); + + s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + } + + function test_InvalidEVMAddress_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.receiver = abi.encode(type(uint208).max); + + vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, message.receiver)); + + s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + } +} + +contract PriceRegistry_processMessageArgs is PriceRegistryFeeSetup { + using USDPriceWith18Decimals for uint224; + + function setUp() public virtual override { + super.setUp(); + } + + function test_WithLinkTokenAmount_Success() public view { + ( + uint256 msgFeeJuels, + /* bool isOutOfOrderExecution */ + , + /* bytes memory convertedExtraArgs */ + ) = s_priceRegistry.processMessageArgs( + DEST_CHAIN_SELECTOR, + // LINK + s_sourceTokens[0], + MAX_MSG_FEES_JUELS, + "" + ); + + assertEq(msgFeeJuels, MAX_MSG_FEES_JUELS); + } + + function test_WithConvertedTokenAmount_Success() public view { + address feeToken = s_sourceTokens[1]; + uint256 feeTokenAmount = 10_000 gwei; + uint256 expectedConvertedAmount = s_priceRegistry.convertTokenAmount(feeToken, feeTokenAmount, s_sourceTokens[0]); + + ( + uint256 msgFeeJuels, + /* bool isOutOfOrderExecution */ + , + /* bytes memory convertedExtraArgs */ + ) = s_priceRegistry.processMessageArgs(DEST_CHAIN_SELECTOR, feeToken, feeTokenAmount, ""); + + assertEq(msgFeeJuels, expectedConvertedAmount); + } + + function test_WithEmptyEVMExtraArgs_Success() public view { + ( + /* uint256 msgFeeJuels */ + , + bool isOutOfOrderExecution, + bytes memory convertedExtraArgs + ) = s_priceRegistry.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, ""); + + assertEq(isOutOfOrderExecution, false); + assertEq( + convertedExtraArgs, Client._argsToBytes(s_priceRegistry.parseEVMExtraArgsFromBytes("", DEST_CHAIN_SELECTOR)) + ); + } + + function test_WithEVMExtraArgsV1_Success() public view { + bytes memory extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 1000})); + + ( + /* uint256 msgFeeJuels */ + , + bool isOutOfOrderExecution, + bytes memory convertedExtraArgs + ) = s_priceRegistry.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, extraArgs); + + assertEq(isOutOfOrderExecution, false); + assertEq( + convertedExtraArgs, + Client._argsToBytes(s_priceRegistry.parseEVMExtraArgsFromBytes(extraArgs, DEST_CHAIN_SELECTOR)) + ); + } + + function test_WitEVMExtraArgsV2_Success() public view { + bytes memory extraArgs = Client._argsToBytes(Client.EVMExtraArgsV2({gasLimit: 0, allowOutOfOrderExecution: true})); + + ( + /* uint256 msgFeeJuels */ + , + bool isOutOfOrderExecution, + bytes memory convertedExtraArgs + ) = s_priceRegistry.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, extraArgs); + + assertEq(isOutOfOrderExecution, true); + assertEq( + convertedExtraArgs, + Client._argsToBytes(s_priceRegistry.parseEVMExtraArgsFromBytes(extraArgs, DEST_CHAIN_SELECTOR)) + ); + } + + // Reverts + + function test_MessageFeeTooHigh_Revert() public { + vm.expectRevert( + abi.encodeWithSelector(PriceRegistry.MessageFeeTooHigh.selector, MAX_MSG_FEES_JUELS + 1, MAX_MSG_FEES_JUELS) + ); + + s_priceRegistry.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], MAX_MSG_FEES_JUELS + 1, ""); + } + + function test_InvalidExtraArgs_Revert() public { + vm.expectRevert(PriceRegistry.InvalidExtraArgsTag.selector); + + s_priceRegistry.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, "abcde"); + } + + function test_MalformedEVMExtraArgs_Revert() public { + // abi.decode error + vm.expectRevert(); + + s_priceRegistry.processMessageArgs( + DEST_CHAIN_SELECTOR, + s_sourceTokens[0], + 0, + abi.encodeWithSelector(Client.EVM_EXTRA_ARGS_V2_TAG, Client.EVMExtraArgsV1({gasLimit: 100})) + ); + } +} + +contract PriceRegistry_validatePoolReturnData is PriceRegistryFeeSetup { + function test_WithSingleToken_Success() public view { + Client.EVMTokenAmount[] memory sourceTokenAmounts = new Client.EVMTokenAmount[](1); + sourceTokenAmounts[0].amount = 1e18; + sourceTokenAmounts[0].token = s_sourceTokens[0]; + + Internal.RampTokenAmount[] memory rampTokenAmounts = new Internal.RampTokenAmount[](1); + rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry); + + // No revert - successful + s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + } + + function test_TokenAmountArraysMismatching_Revert() public { + Client.EVMTokenAmount[] memory sourceTokenAmounts = new Client.EVMTokenAmount[](1); + sourceTokenAmounts[0].amount = 1e18; + sourceTokenAmounts[0].token = s_sourceTokens[0]; + + Internal.RampTokenAmount[] memory rampTokenAmounts = new Internal.RampTokenAmount[](1); + rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry); + + // Revert due to index out of bounds access + vm.expectRevert(); + + s_priceRegistry.validatePoolReturnData( + DEST_CHAIN_SELECTOR, new Internal.RampTokenAmount[](1), new Client.EVMTokenAmount[](0) + ); + } + + function test_SourceTokenDataTooLarge_Revert() public { + address sourceETH = s_sourceTokens[1]; + + Client.EVMTokenAmount[] memory sourceTokenAmounts = new Client.EVMTokenAmount[](1); + sourceTokenAmounts[0].amount = 1000; + sourceTokenAmounts[0].token = sourceETH; + + Internal.RampTokenAmount[] memory rampTokenAmounts = new Internal.RampTokenAmount[](1); + rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry); + + // No data set, should succeed + s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + + // Set max data length, should succeed + rampTokenAmounts[0].extraData = new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES); + s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + + // Set data to max length +1, should revert + rampTokenAmounts[0].extraData = new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + 1); + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.SourceTokenDataTooLarge.selector, sourceETH)); + s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + + // Set token config to allow larger data + PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + _generateTokenTransferFeeConfigArgs(1, 1); + tokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token = sourceETH; + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = PriceRegistry + .TokenTransferFeeConfig({ + minFeeUSDCents: 1, + maxFeeUSDCents: 0, + deciBps: 0, + destGasOverhead: 0, + destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) + 32, + isEnabled: true + }); + s_priceRegistry.applyTokenTransferFeeConfigUpdates( + tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + ); + + s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + + // Set the token data larger than the configured token data, should revert + rampTokenAmounts[0].extraData = new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + 32 + 1); + + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.SourceTokenDataTooLarge.selector, sourceETH)); + s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + } + + function test_InvalidEVMAddressDestToken_Revert() public { + bytes memory nonEvmAddress = abi.encode(type(uint208).max); + + Client.EVMTokenAmount[] memory sourceTokenAmounts = new Client.EVMTokenAmount[](1); + sourceTokenAmounts[0].amount = 1e18; + sourceTokenAmounts[0].token = s_sourceTokens[0]; + + Internal.RampTokenAmount[] memory rampTokenAmounts = new Internal.RampTokenAmount[](1); + rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry); + rampTokenAmounts[0].destTokenAddress = nonEvmAddress; + + vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, nonEvmAddress)); + s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + } +} + +contract PriceRegistry_validateDestFamilyAddress is PriceRegistrySetup { + function test_ValidEVMAddress_Success() public view { + bytes memory encodedAddress = abi.encode(address(10000)); + s_priceRegistry.validateDestFamilyAddress(Internal.CHAIN_FAMILY_SELECTOR_EVM, encodedAddress); + } + + function test_ValidNonEVMAddress_Success() public view { + s_priceRegistry.validateDestFamilyAddress(bytes4(uint32(1)), abi.encode(type(uint208).max)); + } + + // Reverts + + function test_InvalidEVMAddress_Revert() public { + bytes memory invalidAddress = abi.encode(type(uint208).max); + vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, invalidAddress)); + s_priceRegistry.validateDestFamilyAddress(Internal.CHAIN_FAMILY_SELECTOR_EVM, invalidAddress); + } + + function test_InvalidEVMAddressEncodePacked_Revert() public { + bytes memory invalidAddress = abi.encodePacked(address(234)); + vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, invalidAddress)); + s_priceRegistry.validateDestFamilyAddress(Internal.CHAIN_FAMILY_SELECTOR_EVM, invalidAddress); + } + + function test_InvalidEVMAddressPrecompiles_Revert() public { + for (uint160 i = 0; i < Internal.PRECOMPILE_SPACE; ++i) { + bytes memory invalidAddress = abi.encode(address(i)); + vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, invalidAddress)); + s_priceRegistry.validateDestFamilyAddress(Internal.CHAIN_FAMILY_SELECTOR_EVM, invalidAddress); + } + + s_priceRegistry.validateDestFamilyAddress( + Internal.CHAIN_FAMILY_SELECTOR_EVM, abi.encode(address(uint160(Internal.PRECOMPILE_SPACE))) + ); + } +} + +contract PriceRegistry_parseEVMExtraArgsFromBytes is PriceRegistrySetup { + PriceRegistry.DestChainConfig private s_destChainConfig; + + function setUp() public virtual override { + super.setUp(); + s_destChainConfig = _generatePriceRegistryDestChainConfigArgs()[0].destChainConfig; + } + + function test_EVMExtraArgsV1_Success() public view { + Client.EVMExtraArgsV1 memory inputArgs = Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT}); + bytes memory inputExtraArgs = Client._argsToBytes(inputArgs); + Client.EVMExtraArgsV2 memory expectedOutputArgs = + Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT, allowOutOfOrderExecution: false}); + + vm.assertEq( + abi.encode(s_priceRegistry.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig)), + abi.encode(expectedOutputArgs) + ); + } + + function test_EVMExtraArgsV2_Success() public view { + Client.EVMExtraArgsV2 memory inputArgs = + Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT, allowOutOfOrderExecution: true}); + bytes memory inputExtraArgs = Client._argsToBytes(inputArgs); + + vm.assertEq( + abi.encode(s_priceRegistry.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig)), abi.encode(inputArgs) + ); + } + + function test_EVMExtraArgsDefault_Success() public view { + Client.EVMExtraArgsV2 memory expectedOutputArgs = + Client.EVMExtraArgsV2({gasLimit: s_destChainConfig.defaultTxGasLimit, allowOutOfOrderExecution: false}); + + vm.assertEq( + abi.encode(s_priceRegistry.parseEVMExtraArgsFromBytes("", s_destChainConfig)), abi.encode(expectedOutputArgs) + ); + } + + // Reverts + + function test_EVMExtraArgsInvalidExtraArgsTag_Revert() public { + Client.EVMExtraArgsV2 memory inputArgs = + Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT, allowOutOfOrderExecution: true}); + bytes memory inputExtraArgs = Client._argsToBytes(inputArgs); + // Invalidate selector + inputExtraArgs[0] = bytes1(uint8(0)); + + vm.expectRevert(PriceRegistry.InvalidExtraArgsTag.selector); + s_priceRegistry.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig); + } + + function test_EVMExtraArgsEnforceOutOfOrder_Revert() public { + Client.EVMExtraArgsV2 memory inputArgs = + Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT, allowOutOfOrderExecution: false}); + bytes memory inputExtraArgs = Client._argsToBytes(inputArgs); + s_destChainConfig.enforceOutOfOrder = true; + + vm.expectRevert(PriceRegistry.ExtraArgOutOfOrderExecutionMustBeTrue.selector); + s_priceRegistry.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig); + } + + function test_EVMExtraArgsGasLimitTooHigh_Revert() public { + Client.EVMExtraArgsV2 memory inputArgs = + Client.EVMExtraArgsV2({gasLimit: s_destChainConfig.maxPerMsgGasLimit + 1, allowOutOfOrderExecution: true}); + bytes memory inputExtraArgs = Client._argsToBytes(inputArgs); + + vm.expectRevert(PriceRegistry.MessageGasLimitTooHigh.selector); + s_priceRegistry.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig); + } +} diff --git a/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol b/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol new file mode 100644 index 0000000000..d3a07ef11e --- /dev/null +++ b/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {AggregateRateLimiter} from "../../AggregateRateLimiter.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {AggregateRateLimiterHelper} from "../helpers/AggregateRateLimiterHelper.sol"; +import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; + +import {stdError} from "forge-std/Test.sol"; + +contract AggregateTokenLimiterSetup is PriceRegistrySetup { + AggregateRateLimiterHelper internal s_rateLimiter; + RateLimiter.Config internal s_config; + + address internal immutable TOKEN = 0x21118E64E1fB0c487F25Dd6d3601FF6af8D32E4e; + uint224 internal constant TOKEN_PRICE = 4e18; + + function setUp() public virtual override { + PriceRegistrySetup.setUp(); + + Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(TOKEN, TOKEN_PRICE); + s_priceRegistry.updatePrices(priceUpdates); + + s_config = RateLimiter.Config({isEnabled: true, rate: 5, capacity: 100}); + s_rateLimiter = new AggregateRateLimiterHelper(s_config); + s_rateLimiter.setAdmin(ADMIN); + } +} + +contract AggregateTokenLimiter_constructor is AggregateTokenLimiterSetup { + function test_Constructor_Success() public view { + assertEq(ADMIN, s_rateLimiter.getTokenLimitAdmin()); + assertEq(OWNER, s_rateLimiter.owner()); + + RateLimiter.TokenBucket memory bucket = s_rateLimiter.currentRateLimiterState(); + assertEq(s_config.rate, bucket.rate); + assertEq(s_config.capacity, bucket.capacity); + assertEq(s_config.capacity, bucket.tokens); + assertEq(s_config.isEnabled, bucket.isEnabled); + assertEq(BLOCK_TIME, bucket.lastUpdated); + } +} + +contract AggregateTokenLimiter_getTokenLimitAdmin is AggregateTokenLimiterSetup { + function test_GetTokenLimitAdmin_Success() public view { + assertEq(ADMIN, s_rateLimiter.getTokenLimitAdmin()); + } +} + +contract AggregateTokenLimiter_setAdmin is AggregateTokenLimiterSetup { + function test_Owner_Success() public { + vm.expectEmit(); + emit AggregateRateLimiter.AdminSet(STRANGER); + + s_rateLimiter.setAdmin(STRANGER); + assertEq(STRANGER, s_rateLimiter.getTokenLimitAdmin()); + } + + // Reverts + + function test_OnlyOwnerOrAdmin_Revert() public { + vm.startPrank(STRANGER); + vm.expectRevert(RateLimiter.OnlyCallableByAdminOrOwner.selector); + + s_rateLimiter.setAdmin(STRANGER); + } +} + +contract AggregateTokenLimiter_getTokenBucket is AggregateTokenLimiterSetup { + function test_GetTokenBucket_Success() public view { + RateLimiter.TokenBucket memory bucket = s_rateLimiter.currentRateLimiterState(); + assertEq(s_config.rate, bucket.rate); + assertEq(s_config.capacity, bucket.capacity); + assertEq(s_config.capacity, bucket.tokens); + assertEq(BLOCK_TIME, bucket.lastUpdated); + } + + function test_Refill_Success() public { + s_config.capacity = s_config.capacity * 2; + s_rateLimiter.setRateLimiterConfig(s_config); + + RateLimiter.TokenBucket memory bucket = s_rateLimiter.currentRateLimiterState(); + + assertEq(s_config.rate, bucket.rate); + assertEq(s_config.capacity, bucket.capacity); + assertEq(s_config.capacity / 2, bucket.tokens); + assertEq(BLOCK_TIME, bucket.lastUpdated); + + uint256 warpTime = 4; + vm.warp(BLOCK_TIME + warpTime); + + bucket = s_rateLimiter.currentRateLimiterState(); + + assertEq(s_config.rate, bucket.rate); + assertEq(s_config.capacity, bucket.capacity); + assertEq(s_config.capacity / 2 + warpTime * s_config.rate, bucket.tokens); + assertEq(BLOCK_TIME + warpTime, bucket.lastUpdated); + + vm.warp(BLOCK_TIME + warpTime * 100); + + // Bucket overflow + bucket = s_rateLimiter.currentRateLimiterState(); + assertEq(s_config.capacity, bucket.tokens); + } + + // Reverts + + function test_TimeUnderflow_Revert() public { + vm.warp(BLOCK_TIME - 1); + + vm.expectRevert(stdError.arithmeticError); + s_rateLimiter.currentRateLimiterState(); + } +} + +contract AggregateTokenLimiter_setRateLimiterConfig is AggregateTokenLimiterSetup { + function test_Owner_Success() public { + setConfig(); + } + + function test_TokenLimitAdmin_Success() public { + vm.startPrank(ADMIN); + setConfig(); + } + + function setConfig() private { + RateLimiter.TokenBucket memory bucket = s_rateLimiter.currentRateLimiterState(); + assertEq(s_config.rate, bucket.rate); + assertEq(s_config.capacity, bucket.capacity); + + if (bucket.isEnabled) { + s_config = RateLimiter.Config({isEnabled: false, rate: 0, capacity: 0}); + } else { + s_config = RateLimiter.Config({isEnabled: true, rate: 100, capacity: 200}); + } + + vm.expectEmit(); + emit RateLimiter.ConfigChanged(s_config); + + s_rateLimiter.setRateLimiterConfig(s_config); + + bucket = s_rateLimiter.currentRateLimiterState(); + assertEq(s_config.rate, bucket.rate); + assertEq(s_config.capacity, bucket.capacity); + assertEq(s_config.isEnabled, bucket.isEnabled); + } + + // Reverts + + function test_OnlyOnlyCallableByAdminOrOwner_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert(RateLimiter.OnlyCallableByAdminOrOwner.selector); + + s_rateLimiter.setRateLimiterConfig(s_config); + } +} + +contract AggregateTokenLimiter_rateLimitValue is AggregateTokenLimiterSetup { + function test_RateLimitValueSuccess_gas() public { + vm.pauseGasMetering(); + // start from blocktime that does not equal rate limiter init timestamp + vm.warp(BLOCK_TIME + 1); + + // 15 (tokens) * 4 (price) * 2 (number of times) > 100 (capacity) + uint256 numberOfTokens = 15; + uint256 value = (numberOfTokens * TOKEN_PRICE) / 1e18; + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(value); + + vm.resumeGasMetering(); + s_rateLimiter.rateLimitValue(value); + vm.pauseGasMetering(); + + // Get the updated bucket status + RateLimiter.TokenBucket memory bucket = s_rateLimiter.currentRateLimiterState(); + // Assert the proper value has been taken out of the bucket + assertEq(bucket.capacity - value, bucket.tokens); + + // Since value * 2 > bucket.capacity we cannot take it out twice. + // Expect a revert when we try, with a wait time. + uint256 waitTime = 4; + vm.expectRevert( + abi.encodeWithSelector(RateLimiter.AggregateValueRateLimitReached.selector, waitTime, bucket.tokens) + ); + s_rateLimiter.rateLimitValue(value); + + // Move the block time forward by 10 so the bucket refills by 10 * rate + vm.warp(BLOCK_TIME + 1 + waitTime); + + // The bucket has filled up enough so we can take out more tokens + s_rateLimiter.rateLimitValue(value); + bucket = s_rateLimiter.currentRateLimiterState(); + assertEq(bucket.capacity - value + waitTime * s_config.rate - value, bucket.tokens); + vm.resumeGasMetering(); + } + + // Reverts + + function test_AggregateValueMaxCapacityExceeded_Revert() public { + RateLimiter.TokenBucket memory bucket = s_rateLimiter.currentRateLimiterState(); + + uint256 numberOfTokens = 100; + uint256 value = (numberOfTokens * TOKEN_PRICE) / 1e18; + + vm.expectRevert( + abi.encodeWithSelector( + RateLimiter.AggregateValueMaxCapacityExceeded.selector, bucket.capacity, (numberOfTokens * TOKEN_PRICE) / 1e18 + ) + ); + s_rateLimiter.rateLimitValue(value); + } +} + +contract AggregateTokenLimiter_getTokenValue is AggregateTokenLimiterSetup { + function test_GetTokenValue_Success() public view { + uint256 numberOfTokens = 10; + Client.EVMTokenAmount memory tokenAmount = Client.EVMTokenAmount({token: TOKEN, amount: 10}); + uint256 value = s_rateLimiter.getTokenValue(tokenAmount, s_priceRegistry); + assertEq(value, (numberOfTokens * TOKEN_PRICE) / 1e18); + } + + // Reverts + function test_NoTokenPrice_Reverts() public { + address tokenWithNoPrice = makeAddr("Token with no price"); + Client.EVMTokenAmount memory tokenAmount = Client.EVMTokenAmount({token: tokenWithNoPrice, amount: 10}); + + vm.expectRevert(abi.encodeWithSelector(AggregateRateLimiter.PriceNotFoundForToken.selector, tokenWithNoPrice)); + s_rateLimiter.getTokenValue(tokenAmount, s_priceRegistry); + } +} diff --git a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol new file mode 100644 index 0000000000..2bd31452f0 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol @@ -0,0 +1,1201 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; +import {MultiAggregateRateLimiter} from "../../MultiAggregateRateLimiter.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; +import {BaseTest} from "../BaseTest.t.sol"; +import {MultiAggregateRateLimiterHelper} from "../helpers/MultiAggregateRateLimiterHelper.sol"; +import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; +import {stdError} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; + +contract MultiAggregateRateLimiterSetup is BaseTest, PriceRegistrySetup { + MultiAggregateRateLimiterHelper internal s_rateLimiter; + + address internal immutable TOKEN = 0x21118E64E1fB0c487F25Dd6d3601FF6af8D32E4e; + uint224 internal constant TOKEN_PRICE = 4e18; + + uint64 internal constant CHAIN_SELECTOR_1 = 5009297550715157269; + uint64 internal constant CHAIN_SELECTOR_2 = 4949039107694359620; + + RateLimiter.Config internal RATE_LIMITER_CONFIG_1 = RateLimiter.Config({isEnabled: true, rate: 5, capacity: 100}); + RateLimiter.Config internal RATE_LIMITER_CONFIG_2 = RateLimiter.Config({isEnabled: true, rate: 10, capacity: 200}); + + address internal immutable MOCK_OFFRAMP = address(1111); + address internal immutable MOCK_ONRAMP = address(1112); + + address[] internal s_authorizedCallers; + + function setUp() public virtual override(BaseTest, PriceRegistrySetup) { + BaseTest.setUp(); + PriceRegistrySetup.setUp(); + + Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(TOKEN, TOKEN_PRICE); + s_priceRegistry.updatePrices(priceUpdates); + + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](4); + configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_1, + isOutboundLane: false, + rateLimiterConfig: RATE_LIMITER_CONFIG_1 + }); + configUpdates[1] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_2, + isOutboundLane: false, + rateLimiterConfig: RATE_LIMITER_CONFIG_2 + }); + configUpdates[2] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_1, + isOutboundLane: true, + rateLimiterConfig: RATE_LIMITER_CONFIG_1 + }); + configUpdates[3] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_2, + isOutboundLane: true, + rateLimiterConfig: RATE_LIMITER_CONFIG_2 + }); + + s_authorizedCallers = new address[](2); + s_authorizedCallers[0] = MOCK_OFFRAMP; + s_authorizedCallers[1] = MOCK_ONRAMP; + + s_rateLimiter = new MultiAggregateRateLimiterHelper(address(s_priceRegistry), s_authorizedCallers); + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + } + + function _assertConfigWithTokenBucketEquality( + RateLimiter.Config memory config, + RateLimiter.TokenBucket memory tokenBucket + ) internal pure { + assertEq(config.rate, tokenBucket.rate); + assertEq(config.capacity, tokenBucket.capacity); + assertEq(config.capacity, tokenBucket.tokens); + assertEq(config.isEnabled, tokenBucket.isEnabled); + } + + function _assertTokenBucketEquality( + RateLimiter.TokenBucket memory tokenBucketA, + RateLimiter.TokenBucket memory tokenBucketB + ) internal pure { + assertEq(tokenBucketA.rate, tokenBucketB.rate); + assertEq(tokenBucketA.capacity, tokenBucketB.capacity); + assertEq(tokenBucketA.tokens, tokenBucketB.tokens); + assertEq(tokenBucketA.isEnabled, tokenBucketB.isEnabled); + } + + function _generateAny2EVMMessage( + uint64 sourceChainSelector, + Client.EVMTokenAmount[] memory tokenAmounts + ) internal pure returns (Client.Any2EVMMessage memory) { + return Client.Any2EVMMessage({ + messageId: keccak256(bytes("messageId")), + sourceChainSelector: sourceChainSelector, + sender: abi.encode(OWNER), + data: abi.encode(0), + destTokenAmounts: tokenAmounts + }); + } + + function _generateAny2EVMMessageNoTokens(uint64 sourceChainSelector) + internal + pure + returns (Client.Any2EVMMessage memory) + { + return _generateAny2EVMMessage(sourceChainSelector, new Client.EVMTokenAmount[](0)); + } +} + +contract MultiAggregateRateLimiter_constructor is MultiAggregateRateLimiterSetup { + function test_ConstructorNoAuthorizedCallers_Success() public { + address[] memory authorizedCallers = new address[](0); + + vm.recordLogs(); + s_rateLimiter = new MultiAggregateRateLimiterHelper(address(s_priceRegistry), authorizedCallers); + + // PriceRegistrySet + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + assertEq(logEntries.length, 1); + + assertEq(OWNER, s_rateLimiter.owner()); + assertEq(address(s_priceRegistry), s_rateLimiter.getPriceRegistry()); + } + + function test_Constructor_Success() public { + address[] memory authorizedCallers = new address[](2); + authorizedCallers[0] = MOCK_OFFRAMP; + authorizedCallers[1] = MOCK_ONRAMP; + + vm.expectEmit(); + emit MultiAggregateRateLimiter.PriceRegistrySet(address(s_priceRegistry)); + + s_rateLimiter = new MultiAggregateRateLimiterHelper(address(s_priceRegistry), authorizedCallers); + + assertEq(OWNER, s_rateLimiter.owner()); + assertEq(address(s_priceRegistry), s_rateLimiter.getPriceRegistry()); + } +} + +contract MultiAggregateRateLimiter_setPriceRegistry is MultiAggregateRateLimiterSetup { + function test_Owner_Success() public { + address newAddress = address(42); + + vm.expectEmit(); + emit MultiAggregateRateLimiter.PriceRegistrySet(newAddress); + + s_rateLimiter.setPriceRegistry(newAddress); + assertEq(newAddress, s_rateLimiter.getPriceRegistry()); + } + + // Reverts + + function test_OnlyOwner_Revert() public { + vm.startPrank(STRANGER); + vm.expectRevert(bytes("Only callable by owner")); + + s_rateLimiter.setPriceRegistry(STRANGER); + } + + function test_ZeroAddress_Revert() public { + vm.expectRevert(AuthorizedCallers.ZeroAddressNotAllowed.selector); + s_rateLimiter.setPriceRegistry(address(0)); + } +} + +contract MultiAggregateRateLimiter_getTokenBucket is MultiAggregateRateLimiterSetup { + function test_GetTokenBucket_Success() public view { + RateLimiter.TokenBucket memory bucketInbound = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); + _assertConfigWithTokenBucketEquality(RATE_LIMITER_CONFIG_1, bucketInbound); + assertEq(BLOCK_TIME, bucketInbound.lastUpdated); + + RateLimiter.TokenBucket memory bucketOutbound = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, true); + _assertConfigWithTokenBucketEquality(RATE_LIMITER_CONFIG_1, bucketOutbound); + assertEq(BLOCK_TIME, bucketOutbound.lastUpdated); + } + + function test_Refill_Success() public { + RATE_LIMITER_CONFIG_1.capacity = RATE_LIMITER_CONFIG_1.capacity * 2; + + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); + configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_1, + isOutboundLane: false, + rateLimiterConfig: RATE_LIMITER_CONFIG_1 + }); + + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + + RateLimiter.TokenBucket memory bucket = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); + + assertEq(RATE_LIMITER_CONFIG_1.rate, bucket.rate); + assertEq(RATE_LIMITER_CONFIG_1.capacity, bucket.capacity); + assertEq(RATE_LIMITER_CONFIG_1.capacity / 2, bucket.tokens); + assertEq(BLOCK_TIME, bucket.lastUpdated); + + uint256 warpTime = 4; + vm.warp(BLOCK_TIME + warpTime); + + bucket = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); + + assertEq(RATE_LIMITER_CONFIG_1.rate, bucket.rate); + assertEq(RATE_LIMITER_CONFIG_1.capacity, bucket.capacity); + assertEq(RATE_LIMITER_CONFIG_1.capacity / 2 + warpTime * RATE_LIMITER_CONFIG_1.rate, bucket.tokens); + assertEq(BLOCK_TIME + warpTime, bucket.lastUpdated); + + vm.warp(BLOCK_TIME + warpTime * 100); + + // Bucket overflow + bucket = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); + assertEq(RATE_LIMITER_CONFIG_1.capacity, bucket.tokens); + } + + // Reverts + + function test_TimeUnderflow_Revert() public { + vm.warp(BLOCK_TIME - 1); + + vm.expectRevert(stdError.arithmeticError); + s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); + } +} + +contract MultiAggregateRateLimiter_applyRateLimiterConfigUpdates is MultiAggregateRateLimiterSetup { + function test_ZeroConfigs_Success() public { + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](0); + + vm.recordLogs(); + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + assertEq(logEntries.length, 0); + } + + function test_SingleConfig_Success() public { + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); + configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_1 + 1, + isOutboundLane: false, + rateLimiterConfig: RATE_LIMITER_CONFIG_1 + }); + + vm.expectEmit(); + emit MultiAggregateRateLimiter.RateLimiterConfigUpdated( + configUpdates[0].remoteChainSelector, false, configUpdates[0].rateLimiterConfig + ); + + vm.recordLogs(); + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + assertEq(logEntries.length, 1); + + RateLimiter.TokenBucket memory bucket1 = + s_rateLimiter.currentRateLimiterState(configUpdates[0].remoteChainSelector, false); + _assertConfigWithTokenBucketEquality(configUpdates[0].rateLimiterConfig, bucket1); + assertEq(BLOCK_TIME, bucket1.lastUpdated); + } + + function test_SingleConfigOutbound_Success() public { + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); + configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_1 + 1, + isOutboundLane: true, + rateLimiterConfig: RATE_LIMITER_CONFIG_2 + }); + + vm.expectEmit(); + emit MultiAggregateRateLimiter.RateLimiterConfigUpdated( + configUpdates[0].remoteChainSelector, true, configUpdates[0].rateLimiterConfig + ); + + vm.recordLogs(); + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + assertEq(logEntries.length, 1); + + RateLimiter.TokenBucket memory bucket1 = + s_rateLimiter.currentRateLimiterState(configUpdates[0].remoteChainSelector, true); + _assertConfigWithTokenBucketEquality(configUpdates[0].rateLimiterConfig, bucket1); + assertEq(BLOCK_TIME, bucket1.lastUpdated); + } + + function test_MultipleConfigs_Success() public { + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](5); + + for (uint64 i; i < configUpdates.length; ++i) { + configUpdates[i] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_1 + i + 1, + isOutboundLane: i % 2 == 0 ? false : true, + rateLimiterConfig: RateLimiter.Config({isEnabled: true, rate: 5 + i, capacity: 100 + i}) + }); + + vm.expectEmit(); + emit MultiAggregateRateLimiter.RateLimiterConfigUpdated( + configUpdates[i].remoteChainSelector, configUpdates[i].isOutboundLane, configUpdates[i].rateLimiterConfig + ); + } + + vm.recordLogs(); + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + assertEq(logEntries.length, configUpdates.length); + + for (uint256 i; i < configUpdates.length; ++i) { + RateLimiter.TokenBucket memory bucket = + s_rateLimiter.currentRateLimiterState(configUpdates[i].remoteChainSelector, configUpdates[i].isOutboundLane); + _assertConfigWithTokenBucketEquality(configUpdates[i].rateLimiterConfig, bucket); + assertEq(BLOCK_TIME, bucket.lastUpdated); + } + } + + function test_MultipleConfigsBothLanes_Success() public { + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](2); + + for (uint64 i; i < configUpdates.length; ++i) { + configUpdates[i] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_1 + 1, + isOutboundLane: i % 2 == 0 ? false : true, + rateLimiterConfig: RateLimiter.Config({isEnabled: true, rate: 5 + i, capacity: 100 + i}) + }); + + vm.expectEmit(); + emit MultiAggregateRateLimiter.RateLimiterConfigUpdated( + configUpdates[i].remoteChainSelector, configUpdates[i].isOutboundLane, configUpdates[i].rateLimiterConfig + ); + } + + vm.recordLogs(); + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + assertEq(logEntries.length, configUpdates.length); + + for (uint256 i; i < configUpdates.length; ++i) { + RateLimiter.TokenBucket memory bucket = + s_rateLimiter.currentRateLimiterState(configUpdates[i].remoteChainSelector, configUpdates[i].isOutboundLane); + _assertConfigWithTokenBucketEquality(configUpdates[i].rateLimiterConfig, bucket); + assertEq(BLOCK_TIME, bucket.lastUpdated); + } + } + + function test_UpdateExistingConfig_Success() public { + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); + configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_1, + isOutboundLane: false, + rateLimiterConfig: RATE_LIMITER_CONFIG_2 + }); + + RateLimiter.TokenBucket memory bucket1 = + s_rateLimiter.currentRateLimiterState(configUpdates[0].remoteChainSelector, false); + + // Capacity equals tokens + assertEq(bucket1.capacity, bucket1.tokens); + + vm.expectEmit(); + emit MultiAggregateRateLimiter.RateLimiterConfigUpdated( + configUpdates[0].remoteChainSelector, false, configUpdates[0].rateLimiterConfig + ); + + vm.recordLogs(); + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + + vm.warp(BLOCK_TIME + 1); + bucket1 = s_rateLimiter.currentRateLimiterState(configUpdates[0].remoteChainSelector, false); + assertEq(BLOCK_TIME + 1, bucket1.lastUpdated); + + // Tokens < capacity since capacity doubled + assertTrue(bucket1.capacity != bucket1.tokens); + + // Outbound lane config remains unchanged + _assertConfigWithTokenBucketEquality( + RATE_LIMITER_CONFIG_1, s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, true) + ); + } + + function test_UpdateExistingConfigWithNoDifference_Success() public { + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); + configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_1, + isOutboundLane: false, + rateLimiterConfig: RATE_LIMITER_CONFIG_1 + }); + + RateLimiter.TokenBucket memory bucketPreUpdate = + s_rateLimiter.currentRateLimiterState(configUpdates[0].remoteChainSelector, false); + + vm.expectEmit(); + emit MultiAggregateRateLimiter.RateLimiterConfigUpdated( + configUpdates[0].remoteChainSelector, false, configUpdates[0].rateLimiterConfig + ); + + vm.recordLogs(); + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + + vm.warp(BLOCK_TIME + 1); + RateLimiter.TokenBucket memory bucketPostUpdate = + s_rateLimiter.currentRateLimiterState(configUpdates[0].remoteChainSelector, false); + _assertTokenBucketEquality(bucketPreUpdate, bucketPostUpdate); + assertEq(BLOCK_TIME + 1, bucketPostUpdate.lastUpdated); + } + + // Reverts + function test_ZeroChainSelector_Revert() public { + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); + configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: 0, + isOutboundLane: false, + rateLimiterConfig: RATE_LIMITER_CONFIG_1 + }); + + vm.expectRevert(MultiAggregateRateLimiter.ZeroChainSelectorNotAllowed.selector); + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + } + + function test_OnlyCallableByOwner_Revert() public { + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); + configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_1 + 1, + isOutboundLane: false, + rateLimiterConfig: RATE_LIMITER_CONFIG_1 + }); + vm.startPrank(STRANGER); + + vm.expectRevert(bytes("Only callable by owner")); + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + } +} + +contract MultiAggregateRateLimiter_getTokenValue is MultiAggregateRateLimiterSetup { + function test_GetTokenValue_Success() public view { + uint256 numberOfTokens = 10; + Client.EVMTokenAmount memory tokenAmount = Client.EVMTokenAmount({token: TOKEN, amount: 10}); + uint256 value = s_rateLimiter.getTokenValue(tokenAmount); + assertEq(value, (numberOfTokens * TOKEN_PRICE) / 1e18); + } + + // Reverts + function test_NoTokenPrice_Reverts() public { + address tokenWithNoPrice = makeAddr("Token with no price"); + Client.EVMTokenAmount memory tokenAmount = Client.EVMTokenAmount({token: tokenWithNoPrice, amount: 10}); + + vm.expectRevert(abi.encodeWithSelector(MultiAggregateRateLimiter.PriceNotFoundForToken.selector, tokenWithNoPrice)); + s_rateLimiter.getTokenValue(tokenAmount); + } +} + +contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLimiterSetup { + function setUp() public virtual override { + super.setUp(); + + // Clear rate limit tokens state + MultiAggregateRateLimiter.LocalRateLimitToken[] memory removes = + new MultiAggregateRateLimiter.LocalRateLimitToken[](s_sourceTokens.length); + for (uint256 i = 0; i < s_sourceTokens.length; ++i) { + removes[i] = MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: s_destTokens[i] + }); + } + s_rateLimiter.updateRateLimitTokens(removes, new MultiAggregateRateLimiter.RateLimitTokenArgs[](0)); + } + + function test_UpdateRateLimitTokensSingleChain_Success() public { + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory adds = new MultiAggregateRateLimiter.RateLimitTokenArgs[](2); + adds[0] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: s_destTokens[0] + }), + remoteToken: bytes32(bytes20(s_sourceTokens[0])) + }); + adds[1] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: s_destTokens[1] + }), + remoteToken: bytes32(bytes20(s_sourceTokens[1])) + }); + + for (uint256 i = 0; i < adds.length; ++i) { + vm.expectEmit(); + emit MultiAggregateRateLimiter.TokenAggregateRateLimitAdded( + CHAIN_SELECTOR_1, adds[i].remoteToken, adds[i].localTokenArgs.localToken + ); + } + + s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), adds); + + (address[] memory localTokens, bytes32[] memory remoteTokens) = + s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_1); + + assertEq(localTokens.length, adds.length); + assertEq(localTokens.length, remoteTokens.length); + + for (uint256 i = 0; i < adds.length; ++i) { + assertEq(adds[i].remoteToken, remoteTokens[i]); + assertEq(adds[i].localTokenArgs.localToken, localTokens[i]); + } + } + + function test_UpdateRateLimitTokensMultipleChains_Success() public { + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory adds = new MultiAggregateRateLimiter.RateLimitTokenArgs[](2); + adds[0] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: s_destTokens[0] + }), + remoteToken: bytes32(bytes20(s_sourceTokens[0])) + }); + adds[1] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_2, + localToken: s_destTokens[1] + }), + remoteToken: bytes32(bytes20(s_sourceTokens[1])) + }); + + for (uint256 i = 0; i < adds.length; ++i) { + vm.expectEmit(); + emit MultiAggregateRateLimiter.TokenAggregateRateLimitAdded( + adds[i].localTokenArgs.remoteChainSelector, adds[i].remoteToken, adds[i].localTokenArgs.localToken + ); + } + + s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), adds); + + (address[] memory localTokensChain1, bytes32[] memory remoteTokensChain1) = + s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_1); + + assertEq(localTokensChain1.length, 1); + assertEq(localTokensChain1.length, remoteTokensChain1.length); + assertEq(localTokensChain1[0], adds[0].localTokenArgs.localToken); + assertEq(remoteTokensChain1[0], adds[0].remoteToken); + + (address[] memory localTokensChain2, bytes32[] memory remoteTokensChain2) = + s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_2); + + assertEq(localTokensChain2.length, 1); + assertEq(localTokensChain2.length, remoteTokensChain2.length); + assertEq(localTokensChain2[0], adds[1].localTokenArgs.localToken); + assertEq(remoteTokensChain2[0], adds[1].remoteToken); + } + + function test_UpdateRateLimitTokens_AddsAndRemoves_Success() public { + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory adds = new MultiAggregateRateLimiter.RateLimitTokenArgs[](2); + adds[0] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: s_destTokens[0] + }), + remoteToken: bytes32(bytes20(s_sourceTokens[0])) + }); + adds[1] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: s_destTokens[1] + }), + remoteToken: bytes32(bytes20(s_sourceTokens[1])) + }); + + MultiAggregateRateLimiter.LocalRateLimitToken[] memory removes = + new MultiAggregateRateLimiter.LocalRateLimitToken[](1); + removes[0] = adds[0].localTokenArgs; + + for (uint256 i = 0; i < adds.length; ++i) { + vm.expectEmit(); + emit MultiAggregateRateLimiter.TokenAggregateRateLimitAdded( + CHAIN_SELECTOR_1, adds[i].remoteToken, adds[i].localTokenArgs.localToken + ); + } + + s_rateLimiter.updateRateLimitTokens(removes, adds); + + for (uint256 i = 0; i < removes.length; ++i) { + vm.expectEmit(); + emit MultiAggregateRateLimiter.TokenAggregateRateLimitRemoved(CHAIN_SELECTOR_1, removes[i].localToken); + } + + s_rateLimiter.updateRateLimitTokens(removes, new MultiAggregateRateLimiter.RateLimitTokenArgs[](0)); + + (address[] memory localTokens, bytes32[] memory remoteTokens) = + s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_1); + + assertEq(1, remoteTokens.length); + assertEq(adds[1].remoteToken, remoteTokens[0]); + + assertEq(1, localTokens.length); + assertEq(adds[1].localTokenArgs.localToken, localTokens[0]); + } + + function test_UpdateRateLimitTokens_RemoveNonExistentToken_Success() public { + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory adds = new MultiAggregateRateLimiter.RateLimitTokenArgs[](0); + + MultiAggregateRateLimiter.LocalRateLimitToken[] memory removes = + new MultiAggregateRateLimiter.LocalRateLimitToken[](1); + removes[0] = MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: s_destTokens[0] + }); + + vm.recordLogs(); + s_rateLimiter.updateRateLimitTokens(removes, adds); + + // No event since no remove occurred + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + assertEq(logEntries.length, 0); + + (address[] memory localTokens, bytes32[] memory remoteTokens) = + s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_1); + + assertEq(localTokens.length, 0); + assertEq(localTokens.length, remoteTokens.length); + } + + // Reverts + + function test_ZeroSourceToken_Revert() public { + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory adds = new MultiAggregateRateLimiter.RateLimitTokenArgs[](1); + adds[0] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: s_destTokens[0] + }), + remoteToken: bytes32(bytes20(address(0))) + }); + + vm.expectRevert(AuthorizedCallers.ZeroAddressNotAllowed.selector); + s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), adds); + } + + function test_ZeroDestToken_Revert() public { + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory adds = new MultiAggregateRateLimiter.RateLimitTokenArgs[](1); + adds[0] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: address(0) + }), + remoteToken: bytes32(bytes20(s_destTokens[0])) + }); + + vm.expectRevert(AuthorizedCallers.ZeroAddressNotAllowed.selector); + s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), adds); + } + + function test_NonOwner_Revert() public { + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory adds = new MultiAggregateRateLimiter.RateLimitTokenArgs[](4); + + vm.startPrank(STRANGER); + + vm.expectRevert(bytes("Only callable by owner")); + s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), adds); + } +} + +contract MultiAggregateRateLimiter_onInboundMessage is MultiAggregateRateLimiterSetup { + address internal immutable MOCK_RECEIVER = address(1113); + + function setUp() public virtual override { + super.setUp(); + + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory tokensToAdd = + new MultiAggregateRateLimiter.RateLimitTokenArgs[](s_sourceTokens.length); + for (uint224 i = 0; i < s_sourceTokens.length; ++i) { + tokensToAdd[i] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: s_destTokens[i] + }), + remoteToken: bytes32(bytes20(s_sourceTokens[i])) + }); + + Internal.PriceUpdates memory priceUpdates = + getSingleTokenPriceUpdateStruct(s_destTokens[i], TOKEN_PRICE * (i + 1)); + s_priceRegistry.updatePrices(priceUpdates); + } + s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); + } + + function test_ValidateMessageWithNoTokens_Success() public { + vm.startPrank(MOCK_OFFRAMP); + + vm.recordLogs(); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessageNoTokens(CHAIN_SELECTOR_1)); + + // No consumed rate limit events + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + assertEq(logEntries.length, 0); + } + + function test_ValidateMessageWithTokens_Success() public { + vm.startPrank(MOCK_OFFRAMP); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_destTokens[0], amount: 3}); + tokenAmounts[1] = Client.EVMTokenAmount({token: s_destTokens[1], amount: 1}); + + // 3 tokens * TOKEN_PRICE + 1 token * (2 * TOKEN_PRICE) + vm.expectEmit(); + emit RateLimiter.TokensConsumed((5 * TOKEN_PRICE) / 1e18); + + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + } + + function test_ValidateMessageWithDisabledRateLimitToken_Success() public { + MultiAggregateRateLimiter.LocalRateLimitToken[] memory removes = + new MultiAggregateRateLimiter.LocalRateLimitToken[](1); + removes[0] = MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: s_destTokens[1] + }); + s_rateLimiter.updateRateLimitTokens(removes, new MultiAggregateRateLimiter.RateLimitTokenArgs[](0)); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_destTokens[0], amount: 5}); + tokenAmounts[1] = Client.EVMTokenAmount({token: s_destTokens[1], amount: 1}); + + vm.startPrank(MOCK_OFFRAMP); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed((5 * TOKEN_PRICE) / 1e18); + + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + } + + function test_ValidateMessageWithRateLimitDisabled_Success() public { + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); + configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_1, + isOutboundLane: false, + rateLimiterConfig: RATE_LIMITER_CONFIG_1 + }); + configUpdates[0].rateLimiterConfig.isEnabled = false; + + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_destTokens[0], amount: 1000}); + tokenAmounts[1] = Client.EVMTokenAmount({token: s_destTokens[1], amount: 50}); + + vm.startPrank(MOCK_OFFRAMP); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + + // No consumed rate limit events + Vm.Log[] memory logEntries = vm.getRecordedLogs(); + assertEq(logEntries.length, 0); + } + + function test_ValidateMessageWithTokensOnDifferentChains_Success() public { + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory tokensToAdd = + new MultiAggregateRateLimiter.RateLimitTokenArgs[](s_sourceTokens.length); + for (uint224 i = 0; i < s_sourceTokens.length; ++i) { + tokensToAdd[i] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_2, + localToken: s_destTokens[i] + }), + // Create a remote token address that is different from CHAIN_SELECTOR_1 + remoteToken: bytes32(uint256(uint160(s_sourceTokens[i])) + type(uint160).max + 1) + }); + } + s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); + + vm.startPrank(MOCK_OFFRAMP); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_destTokens[0], amount: 2}); + tokenAmounts[1] = Client.EVMTokenAmount({token: s_destTokens[1], amount: 1}); + + // 2 tokens * (TOKEN_PRICE) + 1 token * (2 * TOKEN_PRICE) + uint256 totalValue = (4 * TOKEN_PRICE) / 1e18; + + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + + // Chain 1 changed + RateLimiter.TokenBucket memory bucketChain1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); + assertEq(bucketChain1.capacity - totalValue, bucketChain1.tokens); + + // Chain 2 unchanged + RateLimiter.TokenBucket memory bucketChain2 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_2, false); + assertEq(bucketChain2.capacity, bucketChain2.tokens); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(totalValue); + + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_2, tokenAmounts)); + + // Chain 1 unchanged + bucketChain1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); + assertEq(bucketChain1.capacity - totalValue, bucketChain1.tokens); + + // Chain 2 changed + bucketChain2 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_2, false); + assertEq(bucketChain2.capacity - totalValue, bucketChain2.tokens); + } + + function test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() public { + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory tokensToAdd = + new MultiAggregateRateLimiter.RateLimitTokenArgs[](1); + + // Only 1 rate limited token on different chain + tokensToAdd[0] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_2, + localToken: s_destTokens[0] + }), + // Create a remote token address that is different from CHAIN_SELECTOR_1 + remoteToken: bytes32(uint256(uint160(s_sourceTokens[0])) + type(uint160).max + 1) + }); + s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); + + vm.startPrank(MOCK_OFFRAMP); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_destTokens[0], amount: 3}); + tokenAmounts[1] = Client.EVMTokenAmount({token: s_destTokens[1], amount: 1}); + + // 3 tokens * (TOKEN_PRICE) + 1 token * (2 * TOKEN_PRICE) + uint256 totalValue = (5 * TOKEN_PRICE) / 1e18; + + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + + // Chain 1 changed + RateLimiter.TokenBucket memory bucketChain1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); + assertEq(bucketChain1.capacity - totalValue, bucketChain1.tokens); + + // Chain 2 unchanged + RateLimiter.TokenBucket memory bucketChain2 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_2, false); + assertEq(bucketChain2.capacity, bucketChain2.tokens); + + // 3 tokens * (TOKEN_PRICE) + uint256 totalValue2 = (3 * TOKEN_PRICE) / 1e18; + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(totalValue2); + + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_2, tokenAmounts)); + + // Chain 1 unchanged + bucketChain1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); + assertEq(bucketChain1.capacity - totalValue, bucketChain1.tokens); + + // Chain 2 changed + bucketChain2 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_2, false); + assertEq(bucketChain2.capacity - totalValue2, bucketChain2.tokens); + } + + function test_ValidateMessageWithRateLimitReset_Success() public { + vm.startPrank(MOCK_OFFRAMP); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_destTokens[0], amount: 20}); + + // Remaining capacity: 100 -> 20 + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + + // Cannot fit 80 rate limit value (need to wait at least 12 blocks, current capacity is 20) + vm.expectRevert(abi.encodeWithSelector(RateLimiter.AggregateValueRateLimitReached.selector, 12, 20)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + + // Remaining capacity: 20 -> 35 (need to wait 9 more blocks) + vm.warp(BLOCK_TIME + 3); + vm.expectRevert(abi.encodeWithSelector(RateLimiter.AggregateValueRateLimitReached.selector, 9, 35)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + + // Remaining capacity: 35 -> 80 (can fit exactly 80) + vm.warp(BLOCK_TIME + 12); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + } + + // Reverts + + function test_ValidateMessageWithRateLimitExceeded_Revert() public { + vm.startPrank(MOCK_OFFRAMP); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_destTokens[0], amount: 80}); + tokenAmounts[1] = Client.EVMTokenAmount({token: s_destTokens[1], amount: 30}); + + uint256 totalValue = (80 * TOKEN_PRICE + 2 * (30 * TOKEN_PRICE)) / 1e18; + vm.expectRevert(abi.encodeWithSelector(RateLimiter.AggregateValueMaxCapacityExceeded.selector, 100, totalValue)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + } + + function test_ValidateMessageFromUnauthorizedCaller_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert(abi.encodeWithSelector(AuthorizedCallers.UnauthorizedCaller.selector, STRANGER)); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessageNoTokens(CHAIN_SELECTOR_1)); + } +} + +contract MultiAggregateRateLimiter_onOutboundMessage is MultiAggregateRateLimiterSetup { + function setUp() public virtual override { + super.setUp(); + + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory tokensToAdd = + new MultiAggregateRateLimiter.RateLimitTokenArgs[](s_sourceTokens.length); + for (uint224 i = 0; i < s_sourceTokens.length; ++i) { + tokensToAdd[i] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: s_sourceTokens[i] + }), + remoteToken: bytes32(bytes20(s_destTokenBySourceToken[s_sourceTokens[i]])) + }); + + Internal.PriceUpdates memory priceUpdates = + getSingleTokenPriceUpdateStruct(s_sourceTokens[i], TOKEN_PRICE * (i + 1)); + s_priceRegistry.updatePrices(priceUpdates); + } + s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); + } + + function test_ValidateMessageWithNoTokens_Success() public { + vm.startPrank(MOCK_ONRAMP); + + vm.recordLogs(); + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessageNoTokens()); + + // No consumed rate limit events + assertEq(vm.getRecordedLogs().length, 0); + } + + function test_onOutboundMessage_ValidateMessageWithTokens_Success() public { + vm.startPrank(MOCK_ONRAMP); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: 3}); + tokenAmounts[1] = Client.EVMTokenAmount({token: s_sourceTokens[1], amount: 1}); + + // 3 tokens * TOKEN_PRICE + 1 token * (2 * TOKEN_PRICE) + vm.expectEmit(); + emit RateLimiter.TokensConsumed((5 * TOKEN_PRICE) / 1e18); + + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessage(tokenAmounts)); + } + + function test_onOutboundMessage_ValidateMessageWithDisabledRateLimitToken_Success() public { + MultiAggregateRateLimiter.LocalRateLimitToken[] memory removes = + new MultiAggregateRateLimiter.LocalRateLimitToken[](1); + removes[0] = MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_1, + localToken: s_sourceTokens[1] + }); + s_rateLimiter.updateRateLimitTokens(removes, new MultiAggregateRateLimiter.RateLimitTokenArgs[](0)); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: 5}); + tokenAmounts[1] = Client.EVMTokenAmount({token: s_sourceTokens[1], amount: 1}); + + vm.startPrank(MOCK_ONRAMP); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed((5 * TOKEN_PRICE) / 1e18); + + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessage(tokenAmounts)); + } + + function test_onOutboundMessage_ValidateMessageWithRateLimitDisabled_Success() public { + MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = + new MultiAggregateRateLimiter.RateLimiterConfigArgs[](1); + configUpdates[0] = MultiAggregateRateLimiter.RateLimiterConfigArgs({ + remoteChainSelector: CHAIN_SELECTOR_1, + isOutboundLane: true, + rateLimiterConfig: RATE_LIMITER_CONFIG_1 + }); + configUpdates[0].rateLimiterConfig.isEnabled = false; + + s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: 1000}); + tokenAmounts[1] = Client.EVMTokenAmount({token: s_sourceTokens[1], amount: 50}); + + vm.startPrank(MOCK_ONRAMP); + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessage(tokenAmounts)); + + // No consumed rate limit events + assertEq(vm.getRecordedLogs().length, 0); + } + + function test_onOutboundMessage_ValidateMessageWithTokensOnDifferentChains_Success() public { + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory tokensToAdd = + new MultiAggregateRateLimiter.RateLimitTokenArgs[](s_sourceTokens.length); + for (uint224 i = 0; i < s_sourceTokens.length; ++i) { + tokensToAdd[i] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_2, + localToken: s_sourceTokens[i] + }), + // Create a remote token address that is different from CHAIN_SELECTOR_1 + remoteToken: bytes32(uint256(uint160(s_destTokenBySourceToken[s_sourceTokens[i]])) + type(uint160).max + 1) + }); + } + s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); + + vm.startPrank(MOCK_ONRAMP); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: 2}); + tokenAmounts[1] = Client.EVMTokenAmount({token: s_sourceTokens[1], amount: 1}); + + // 2 tokens * (TOKEN_PRICE) + 1 token * (2 * TOKEN_PRICE) + uint256 totalValue = (4 * TOKEN_PRICE) / 1e18; + + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessage(tokenAmounts)); + + // Chain 1 changed + RateLimiter.TokenBucket memory bucketChain1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, true); + assertEq(bucketChain1.capacity - totalValue, bucketChain1.tokens); + + // Chain 2 unchanged + RateLimiter.TokenBucket memory bucketChain2 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_2, true); + assertEq(bucketChain2.capacity, bucketChain2.tokens); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(totalValue); + + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_2, _generateEVM2AnyMessage(tokenAmounts)); + + // Chain 1 unchanged + bucketChain1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, true); + assertEq(bucketChain1.capacity - totalValue, bucketChain1.tokens); + + // Chain 2 changed + bucketChain2 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_2, true); + assertEq(bucketChain2.capacity - totalValue, bucketChain2.tokens); + } + + function test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() public { + MultiAggregateRateLimiter.RateLimitTokenArgs[] memory tokensToAdd = + new MultiAggregateRateLimiter.RateLimitTokenArgs[](1); + + // Only 1 rate limited token on different chain + tokensToAdd[0] = MultiAggregateRateLimiter.RateLimitTokenArgs({ + localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ + remoteChainSelector: CHAIN_SELECTOR_2, + localToken: s_sourceTokens[0] + }), + // Create a remote token address that is different from CHAIN_SELECTOR_1 + remoteToken: bytes32(uint256(uint160(s_destTokenBySourceToken[s_sourceTokens[0]])) + type(uint160).max + 1) + }); + s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); + + vm.startPrank(MOCK_ONRAMP); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: 3}); + tokenAmounts[1] = Client.EVMTokenAmount({token: s_sourceTokens[1], amount: 1}); + + // 3 tokens * (TOKEN_PRICE) + 1 token * (2 * TOKEN_PRICE) + uint256 totalValue = (5 * TOKEN_PRICE) / 1e18; + + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessage(tokenAmounts)); + + // Chain 1 changed + RateLimiter.TokenBucket memory bucketChain1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, true); + assertEq(bucketChain1.capacity - totalValue, bucketChain1.tokens); + + // Chain 2 unchanged + RateLimiter.TokenBucket memory bucketChain2 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_2, true); + assertEq(bucketChain2.capacity, bucketChain2.tokens); + + // 3 tokens * (TOKEN_PRICE) + uint256 totalValue2 = (3 * TOKEN_PRICE) / 1e18; + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(totalValue2); + + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_2, _generateEVM2AnyMessage(tokenAmounts)); + + // Chain 1 unchanged + bucketChain1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, true); + assertEq(bucketChain1.capacity - totalValue, bucketChain1.tokens); + + // Chain 2 changed + bucketChain2 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_2, true); + assertEq(bucketChain2.capacity - totalValue2, bucketChain2.tokens); + } + + function test_onOutboundMessage_ValidateMessageWithRateLimitReset_Success() public { + vm.startPrank(MOCK_ONRAMP); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: 20}); + + // Remaining capacity: 100 -> 20 + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessage(tokenAmounts)); + + // Cannot fit 80 rate limit value (need to wait at least 12 blocks, current capacity is 20) + vm.expectRevert(abi.encodeWithSelector(RateLimiter.AggregateValueRateLimitReached.selector, 12, 20)); + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessage(tokenAmounts)); + + // Remaining capacity: 20 -> 35 (need to wait 9 more blocks) + vm.warp(BLOCK_TIME + 3); + vm.expectRevert(abi.encodeWithSelector(RateLimiter.AggregateValueRateLimitReached.selector, 9, 35)); + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessage(tokenAmounts)); + + // Remaining capacity: 35 -> 80 (can fit exactly 80) + vm.warp(BLOCK_TIME + 12); + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessage(tokenAmounts)); + } + + function test_RateLimitValueDifferentLanes_Success() public { + vm.pauseGasMetering(); + // start from blocktime that does not equal rate limiter init timestamp + vm.warp(BLOCK_TIME + 1); + + // 10 (tokens) * 4 (price) * 2 (number of times) = 80 < 100 (capacity) + uint256 numberOfTokens = 10; + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: numberOfTokens}); + uint256 value = (numberOfTokens * TOKEN_PRICE) / 1e18; + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(value); + + vm.resumeGasMetering(); + vm.startPrank(MOCK_ONRAMP); + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessage(tokenAmounts)); + vm.pauseGasMetering(); + + // Get the updated bucket status + RateLimiter.TokenBucket memory bucket1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, true); + RateLimiter.TokenBucket memory bucket2 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); + + // Assert the proper value has been taken out of the bucket + assertEq(bucket1.capacity - value, bucket1.tokens); + // Inbound lane should remain unchanged + assertEq(bucket2.capacity, bucket2.tokens); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(value); + + vm.resumeGasMetering(); + s_rateLimiter.onInboundMessage(_generateAny2EVMMessage(CHAIN_SELECTOR_1, tokenAmounts)); + vm.pauseGasMetering(); + + bucket1 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, true); + bucket2 = s_rateLimiter.currentRateLimiterState(CHAIN_SELECTOR_1, false); + + // Inbound lane should remain unchanged + assertEq(bucket1.capacity - value, bucket1.tokens); + assertEq(bucket2.capacity - value, bucket2.tokens); + } + + // Reverts + + function test_onOutboundMessage_ValidateMessageWithRateLimitExceeded_Revert() public { + vm.startPrank(MOCK_OFFRAMP); + + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](2); + tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: 80}); + tokenAmounts[1] = Client.EVMTokenAmount({token: s_sourceTokens[1], amount: 30}); + + uint256 totalValue = (80 * TOKEN_PRICE + 2 * (30 * TOKEN_PRICE)) / 1e18; + vm.expectRevert(abi.encodeWithSelector(RateLimiter.AggregateValueMaxCapacityExceeded.selector, 100, totalValue)); + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessage(tokenAmounts)); + } + + function test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert(abi.encodeWithSelector(AuthorizedCallers.UnauthorizedCaller.selector, STRANGER)); + s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessageNoTokens()); + } + + function _generateEVM2AnyMessage(Client.EVMTokenAmount[] memory tokenAmounts) + public + view + returns (Client.EVM2AnyMessage memory) + { + return Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + } + + function _generateEVM2AnyMessageNoTokens() internal view returns (Client.EVM2AnyMessage memory) { + return _generateEVM2AnyMessage(new Client.EVMTokenAmount[](0)); + } +} diff --git a/contracts/src/v0.8/ccip/test/router/Router.t.sol b/contracts/src/v0.8/ccip/test/router/Router.t.sol new file mode 100644 index 0000000000..cfe01e3c41 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/router/Router.t.sol @@ -0,0 +1,889 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IAny2EVMMessageReceiver} from "../../interfaces/IAny2EVMMessageReceiver.sol"; +import {IRouter} from "../../interfaces/IRouter.sol"; +import {IRouterClient} from "../../interfaces/IRouterClient.sol"; +import {IWrappedNative} from "../../interfaces/IWrappedNative.sol"; + +import {Router} from "../../Router.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {EVM2EVMOnRamp} from "../../onRamp/EVM2EVMOnRamp.sol"; +import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; +import {EVM2EVMOffRampSetup} from "../offRamp/EVM2EVMOffRampSetup.t.sol"; +import {EVM2EVMOnRampSetup} from "../onRamp/EVM2EVMOnRampSetup.t.sol"; +import {RouterSetup} from "../router/RouterSetup.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract Router_constructor is EVM2EVMOnRampSetup { + function test_Constructor_Success() public view { + assertEq("Router 1.2.0", s_sourceRouter.typeAndVersion()); + assertEq(OWNER, s_sourceRouter.owner()); + } +} + +contract Router_recoverTokens is EVM2EVMOnRampSetup { + function test_RecoverTokens_Success() public { + // Assert we can recover sourceToken + IERC20 token = IERC20(s_sourceTokens[0]); + uint256 balanceBefore = token.balanceOf(OWNER); + token.transfer(address(s_sourceRouter), 1); + assertEq(token.balanceOf(address(s_sourceRouter)), 1); + s_sourceRouter.recoverTokens(address(token), OWNER, 1); + assertEq(token.balanceOf(address(s_sourceRouter)), 0); + assertEq(token.balanceOf(OWNER), balanceBefore); + + // Assert we can recover native + balanceBefore = OWNER.balance; + deal(address(s_sourceRouter), 10); + assertEq(address(s_sourceRouter).balance, 10); + s_sourceRouter.recoverTokens(address(0), OWNER, 10); + assertEq(OWNER.balance, balanceBefore + 10); + assertEq(address(s_sourceRouter).balance, 0); + } + + function test_RecoverTokensNonOwner_Revert() public { + // Reverts if not owner + vm.startPrank(STRANGER); + vm.expectRevert("Only callable by owner"); + s_sourceRouter.recoverTokens(address(0), STRANGER, 1); + } + + function test_RecoverTokensInvalidRecipient_Revert() public { + vm.expectRevert(abi.encodeWithSelector(Router.InvalidRecipientAddress.selector, address(0))); + s_sourceRouter.recoverTokens(address(0), address(0), 1); + } + + function test_RecoverTokensNoFunds_Revert() public { + // Reverts if no funds present + vm.expectRevert(); + s_sourceRouter.recoverTokens(address(0), OWNER, 10); + } + + function test_RecoverTokensValueReceiver_Revert() public { + MaybeRevertMessageReceiver revertingValueReceiver = new MaybeRevertMessageReceiver(true); + deal(address(s_sourceRouter), 10); + + // Value receiver reverts + vm.expectRevert(Router.FailedToSendValue.selector); + s_sourceRouter.recoverTokens(address(0), address(revertingValueReceiver), 10); + } +} + +contract Router_ccipSend is EVM2EVMOnRampSetup { + event Burned(address indexed sender, uint256 amount); + + function test_CCIPSendLinkFeeOneTokenSuccess_gas() public { + vm.pauseGasMetering(); + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + IERC20 sourceToken1 = IERC20(s_sourceTokens[1]); + sourceToken1.approve(address(s_sourceRouter), 2 ** 64); + + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].amount = 2 ** 64; + message.tokenAmounts[0].token = s_sourceTokens[1]; + + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + assertGt(expectedFee, 0); + + uint256 balanceBefore = sourceToken1.balanceOf(OWNER); + + // Assert that the tokens are burned + vm.expectEmit(); + emit Burned(address(s_onRamp), message.tokenAmounts[0].amount); + + Internal.EVM2EVMMessage memory msgEvent = _messageToEvent(message, 1, 1, expectedFee, OWNER); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(msgEvent); + + vm.resumeGasMetering(); + bytes32 messageId = s_sourceRouter.ccipSend(DEST_CHAIN_SELECTOR, message); + vm.pauseGasMetering(); + + assertEq(msgEvent.messageId, messageId); + // Assert the user balance is lowered by the tokenAmounts sent and the fee amount + uint256 expectedBalance = balanceBefore - (message.tokenAmounts[0].amount); + assertEq(expectedBalance, sourceToken1.balanceOf(OWNER)); + vm.resumeGasMetering(); + } + + function test_CCIPSendLinkFeeNoTokenSuccess_gas() public { + vm.pauseGasMetering(); + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + assertGt(expectedFee, 0); + + Internal.EVM2EVMMessage memory msgEvent = _messageToEvent(message, 1, 1, expectedFee, OWNER); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(msgEvent); + + vm.resumeGasMetering(); + bytes32 messageId = s_sourceRouter.ccipSend(DEST_CHAIN_SELECTOR, message); + vm.pauseGasMetering(); + + assertEq(msgEvent.messageId, messageId); + vm.resumeGasMetering(); + } + + function test_CCIPSendNativeFeeOneTokenSuccess_gas() public { + vm.pauseGasMetering(); + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + IERC20 sourceToken1 = IERC20(s_sourceTokens[1]); + sourceToken1.approve(address(s_sourceRouter), 2 ** 64); + + message.tokenAmounts = new Client.EVMTokenAmount[](1); + message.tokenAmounts[0].amount = 2 ** 64; + message.tokenAmounts[0].token = s_sourceTokens[1]; + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + assertGt(expectedFee, 0); + + uint256 balanceBefore = sourceToken1.balanceOf(OWNER); + + // Assert that the tokens are burned + vm.expectEmit(); + emit Burned(address(s_onRamp), message.tokenAmounts[0].amount); + + // Native fees will be wrapped so we need to calculate the event with + // the wrapped native feeCoin address. + message.feeToken = s_sourceRouter.getWrappedNative(); + Internal.EVM2EVMMessage memory msgEvent = _messageToEvent(message, 1, 1, expectedFee, OWNER); + // Set it to address(0) to indicate native + message.feeToken = address(0); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(msgEvent); + + vm.resumeGasMetering(); + bytes32 messageId = s_sourceRouter.ccipSend{value: expectedFee}(DEST_CHAIN_SELECTOR, message); + vm.pauseGasMetering(); + + assertEq(msgEvent.messageId, messageId); + // Assert the user balance is lowered by the tokenAmounts sent and the fee amount + uint256 expectedBalance = balanceBefore - (message.tokenAmounts[0].amount); + assertEq(expectedBalance, sourceToken1.balanceOf(OWNER)); + vm.resumeGasMetering(); + } + + function test_CCIPSendNativeFeeNoTokenSuccess_gas() public { + vm.pauseGasMetering(); + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + assertGt(expectedFee, 0); + + // Native fees will be wrapped so we need to calculate the event with + // the wrapped native feeCoin address. + message.feeToken = s_sourceRouter.getWrappedNative(); + Internal.EVM2EVMMessage memory msgEvent = _messageToEvent(message, 1, 1, expectedFee, OWNER); + // Set it to address(0) to indicate native + message.feeToken = address(0); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(msgEvent); + + vm.resumeGasMetering(); + bytes32 messageId = s_sourceRouter.ccipSend{value: expectedFee}(DEST_CHAIN_SELECTOR, message); + vm.pauseGasMetering(); + + assertEq(msgEvent.messageId, messageId); + // Assert the user balance is lowered by the tokenAmounts sent and the fee amount + vm.resumeGasMetering(); + } + + function test_NonLinkFeeToken_Success() public { + EVM2EVMOnRamp.FeeTokenConfigArgs[] memory feeTokenConfigArgs = new EVM2EVMOnRamp.FeeTokenConfigArgs[](1); + feeTokenConfigArgs[0] = EVM2EVMOnRamp.FeeTokenConfigArgs({ + token: s_sourceTokens[1], + networkFeeUSDCents: 1, + gasMultiplierWeiPerEth: 108e16, + premiumMultiplierWeiPerEth: 1e18, + enabled: true + }); + s_onRamp.setFeeTokenConfig(feeTokenConfigArgs); + + address[] memory feeTokens = new address[](1); + feeTokens[0] = s_sourceTokens[1]; + s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = s_sourceTokens[1]; + IERC20(s_sourceTokens[1]).approve(address(s_sourceRouter), 2 ** 64); + s_sourceRouter.ccipSend(DEST_CHAIN_SELECTOR, message); + } + + function test_NativeFeeToken_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = address(0); // Raw native + uint256 nativeQuote = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + vm.stopPrank(); + hoax(address(1), 100 ether); + s_sourceRouter.ccipSend{value: nativeQuote}(DEST_CHAIN_SELECTOR, message); + } + + function test_NativeFeeTokenOverpay_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = address(0); // Raw native + uint256 nativeQuote = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + vm.stopPrank(); + hoax(address(1), 100 ether); + s_sourceRouter.ccipSend{value: nativeQuote + 1}(DEST_CHAIN_SELECTOR, message); + // We expect the overpayment to be taken in full. + assertEq(address(1).balance, 100 ether - (nativeQuote + 1)); + assertEq(address(s_sourceRouter).balance, 0); + } + + function test_WrappedNativeFeeToken_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = s_sourceRouter.getWrappedNative(); + uint256 nativeQuote = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + vm.stopPrank(); + hoax(address(1), 100 ether); + // Now address(1) has nativeQuote wrapped. + IWrappedNative(s_sourceRouter.getWrappedNative()).deposit{value: nativeQuote}(); + IWrappedNative(s_sourceRouter.getWrappedNative()).approve(address(s_sourceRouter), nativeQuote); + s_sourceRouter.ccipSend(DEST_CHAIN_SELECTOR, message); + } + + // Since sending with zero fees is a legitimate use case for some destination + // chains, e.g. private chains, we want to make sure that we can still send even + // when the configured fee is 0. + function test_ZeroFeeAndGasPrice_Success() public { + // Configure a new fee token that has zero gas and zero fees but is still + // enabled and valid to pay with. + address feeTokenWithZeroFeeAndGas = s_sourceTokens[1]; + + // Set the new token as feeToken + address[] memory feeTokens = new address[](1); + feeTokens[0] = feeTokenWithZeroFeeAndGas; + s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + + // Update the price of the newly set feeToken + Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(feeTokenWithZeroFeeAndGas, 2_000 ether); + priceUpdates.gasPriceUpdates = getSingleGasPriceUpdateStruct(DEST_CHAIN_SELECTOR, 0).gasPriceUpdates; + s_priceRegistry.updatePrices(priceUpdates); + + // Set the feeToken args on the onRamp + EVM2EVMOnRamp.FeeTokenConfigArgs[] memory feeTokenConfigArgs = new EVM2EVMOnRamp.FeeTokenConfigArgs[](1); + feeTokenConfigArgs[0] = EVM2EVMOnRamp.FeeTokenConfigArgs({ + token: s_sourceTokens[1], + networkFeeUSDCents: 0, + gasMultiplierWeiPerEth: 108e16, + premiumMultiplierWeiPerEth: 1e18, + enabled: true + }); + + s_onRamp.setFeeTokenConfig(feeTokenConfigArgs); + + // Send a message with the new feeToken + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = feeTokenWithZeroFeeAndGas; + + // Fee should be 0 and sending should not revert + uint256 fee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + assertEq(fee, 0); + + s_sourceRouter.ccipSend(DEST_CHAIN_SELECTOR, message); + } + + // Reverts + + function test_WhenNotHealthy_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + s_mockRMN.setGlobalCursed(true); + vm.expectRevert(Router.BadARMSignal.selector); + s_sourceRouter.ccipSend(DEST_CHAIN_SELECTOR, message); + } + + function test_UnsupportedDestinationChain_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + uint64 wrongChain = DEST_CHAIN_SELECTOR + 1; + + vm.expectRevert(abi.encodeWithSelector(IRouterClient.UnsupportedDestinationChain.selector, wrongChain)); + + s_sourceRouter.ccipSend(wrongChain, message); + } + + function test_Fuzz_UnsupportedFeeToken_Reverts(address wrongFeeToken) public { + // We have three fee tokens set, all others should revert. + vm.assume(address(s_sourceFeeToken) != wrongFeeToken); + vm.assume(address(s_sourceRouter.getWrappedNative()) != wrongFeeToken); + vm.assume(address(0) != wrongFeeToken); + + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = wrongFeeToken; + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.NotAFeeToken.selector, wrongFeeToken)); + + s_sourceRouter.ccipSend(DEST_CHAIN_SELECTOR, message); + } + + function test_Fuzz_UnsupportedToken_Reverts(address wrongToken) public { + for (uint256 i = 0; i < s_sourceTokens.length; ++i) { + vm.assume(address(s_sourceTokens[i]) != wrongToken); + } + + for (uint256 i = 0; i < s_destTokens.length; ++i) { + vm.assume(address(s_destTokens[i]) != wrongToken); + } + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({token: wrongToken, amount: 1}); + message.tokenAmounts = tokenAmounts; + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.UnsupportedToken.selector, wrongToken)); + + s_sourceRouter.ccipSend(DEST_CHAIN_SELECTOR, message); + } + + function test_FeeTokenAmountTooLow_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + IERC20(s_sourceTokens[0]).approve(address(s_sourceRouter), 0); + + vm.expectRevert("ERC20: insufficient allowance"); + + s_sourceRouter.ccipSend(DEST_CHAIN_SELECTOR, message); + } + + function test_InvalidMsgValue() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + // Non-empty feeToken but with msg.value should revert + vm.stopPrank(); + hoax(address(1), 1); + vm.expectRevert(IRouterClient.InvalidMsgValue.selector); + s_sourceRouter.ccipSend{value: 1}(DEST_CHAIN_SELECTOR, message); + } + + function test_NativeFeeTokenZeroValue() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = address(0); // Raw native + // Include no value, should revert + vm.expectRevert(); + s_sourceRouter.ccipSend(DEST_CHAIN_SELECTOR, message); + } + + function test_NativeFeeTokenInsufficientValue() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = address(0); // Raw native + // Include insufficient, should also revert + vm.stopPrank(); + + s_onRamp.getFeeTokenConfig(s_sourceRouter.getWrappedNative()); + + hoax(address(1), 1); + vm.expectRevert(IRouterClient.InsufficientFeeTokenAmount.selector); + s_sourceRouter.ccipSend{value: 1}(DEST_CHAIN_SELECTOR, message); + } +} + +contract Router_getArmProxy is RouterSetup { + function test_getArmProxy() public view { + assertEq(s_sourceRouter.getArmProxy(), address(s_mockRMN)); + } +} + +contract Router_applyRampUpdates is RouterSetup { + MaybeRevertMessageReceiver internal s_receiver; + + function setUp() public virtual override(RouterSetup) { + RouterSetup.setUp(); + s_receiver = new MaybeRevertMessageReceiver(false); + } + + function assertOffRampRouteSucceeds(Router.OffRamp memory offRamp) internal { + vm.startPrank(offRamp.offRamp); + + Client.Any2EVMMessage memory message = generateReceiverMessage(offRamp.sourceChainSelector); + vm.expectCall(address(s_receiver), abi.encodeWithSelector(IAny2EVMMessageReceiver.ccipReceive.selector, message)); + s_sourceRouter.routeMessage(message, GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver)); + } + + function assertOffRampRouteReverts(Router.OffRamp memory offRamp) internal { + vm.startPrank(offRamp.offRamp); + + vm.expectRevert(IRouter.OnlyOffRamp.selector); + s_sourceRouter.routeMessage( + generateReceiverMessage(offRamp.sourceChainSelector), GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver) + ); + } + + function test_Fuzz_OffRampUpdates(address[20] memory offRampsInput) public { + Router.OffRamp[] memory offRamps = new Router.OffRamp[](20); + + for (uint256 i = 0; i < offRampsInput.length; ++i) { + offRamps[i] = Router.OffRamp({sourceChainSelector: uint64(i), offRamp: offRampsInput[i]}); + } + + // Test adding offRamps + s_sourceRouter.applyRampUpdates(new Router.OnRamp[](0), new Router.OffRamp[](0), offRamps); + + // There is no uniqueness guarantee on fuzz input, offRamps will not emit in case of a duplicate, + // hence cannot assert on number of offRamps event emissions, we need to use isOffRa + for (uint256 i = 0; i < offRamps.length; ++i) { + assertTrue(s_sourceRouter.isOffRamp(offRamps[i].sourceChainSelector, offRamps[i].offRamp)); + } + + // Test removing offRamps + s_sourceRouter.applyRampUpdates(new Router.OnRamp[](0), s_sourceRouter.getOffRamps(), new Router.OffRamp[](0)); + + assertEq(0, s_sourceRouter.getOffRamps().length); + for (uint256 i = 0; i < offRamps.length; ++i) { + assertFalse(s_sourceRouter.isOffRamp(offRamps[i].sourceChainSelector, offRamps[i].offRamp)); + } + + // Testing removing and adding in same call + s_sourceRouter.applyRampUpdates(new Router.OnRamp[](0), new Router.OffRamp[](0), offRamps); + s_sourceRouter.applyRampUpdates(new Router.OnRamp[](0), offRamps, offRamps); + for (uint256 i = 0; i < offRamps.length; ++i) { + assertTrue(s_sourceRouter.isOffRamp(offRamps[i].sourceChainSelector, offRamps[i].offRamp)); + } + } + + function test_OffRampUpdatesWithRouting() public { + // Explicitly construct chain selectors and ramp addresses so we have ramp uniqueness for the various test scenarios. + uint256 numberOfSelectors = 10; + uint64[] memory sourceChainSelectors = new uint64[](numberOfSelectors); + for (uint256 i = 0; i < numberOfSelectors; ++i) { + sourceChainSelectors[i] = uint64(i); + } + + uint256 numberOfOffRamps = 5; + address[] memory offRamps = new address[](numberOfOffRamps); + for (uint256 i = 0; i < numberOfOffRamps; ++i) { + offRamps[i] = address(uint160(i * 10)); + } + + // 1st test scenario: add offramps. + // Check all the offramps are added correctly, and can route messages. + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](0); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](numberOfSelectors * numberOfOffRamps); + + // Ensure there are multi-offramp source and multi-source offramps + for (uint256 i = 0; i < numberOfSelectors; ++i) { + for (uint256 j = 0; j < numberOfOffRamps; ++j) { + offRampUpdates[(i * numberOfOffRamps) + j] = Router.OffRamp(sourceChainSelectors[i], offRamps[j]); + } + } + + for (uint256 i = 0; i < offRampUpdates.length; ++i) { + vm.expectEmit(); + emit Router.OffRampAdded(offRampUpdates[i].sourceChainSelector, offRampUpdates[i].offRamp); + } + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + + Router.OffRamp[] memory gotOffRamps = s_sourceRouter.getOffRamps(); + assertEq(offRampUpdates.length, gotOffRamps.length); + + for (uint256 i = 0; i < offRampUpdates.length; ++i) { + assertEq(offRampUpdates[i].offRamp, gotOffRamps[i].offRamp); + assertTrue(s_sourceRouter.isOffRamp(offRampUpdates[i].sourceChainSelector, offRampUpdates[i].offRamp)); + assertOffRampRouteSucceeds(offRampUpdates[i]); + } + + vm.startPrank(OWNER); + + // 2nd test scenario: partially remove existing offramps, add new offramps. + // Check offramps are removed correctly. Removed offramps cannot route messages. + // Check new offramps are added correctly. New offramps can route messages. + // Check unmodified offramps remain correct, and can still route messages. + uint256 numberOfPartialUpdates = offRampUpdates.length / 2; + Router.OffRamp[] memory partialOffRampRemoves = new Router.OffRamp[](numberOfPartialUpdates); + Router.OffRamp[] memory partialOffRampAdds = new Router.OffRamp[](numberOfPartialUpdates); + for (uint256 i = 0; i < numberOfPartialUpdates; ++i) { + partialOffRampRemoves[i] = offRampUpdates[i]; + partialOffRampAdds[i] = Router.OffRamp({ + sourceChainSelector: offRampUpdates[i].sourceChainSelector, + offRamp: address(uint160(offRampUpdates[i].offRamp) + 1e18) // Ensure unique new offRamps addresses + }); + } + + for (uint256 i = 0; i < numberOfPartialUpdates; ++i) { + vm.expectEmit(); + emit Router.OffRampRemoved(partialOffRampRemoves[i].sourceChainSelector, partialOffRampRemoves[i].offRamp); + } + for (uint256 i = 0; i < numberOfPartialUpdates; ++i) { + vm.expectEmit(); + emit Router.OffRampAdded(partialOffRampAdds[i].sourceChainSelector, partialOffRampAdds[i].offRamp); + } + s_sourceRouter.applyRampUpdates(onRampUpdates, partialOffRampRemoves, partialOffRampAdds); + + gotOffRamps = s_sourceRouter.getOffRamps(); + assertEq(offRampUpdates.length, gotOffRamps.length); + + for (uint256 i = 0; i < numberOfPartialUpdates; ++i) { + assertFalse( + s_sourceRouter.isOffRamp(partialOffRampRemoves[i].sourceChainSelector, partialOffRampRemoves[i].offRamp) + ); + assertOffRampRouteReverts(partialOffRampRemoves[i]); + + assertTrue(s_sourceRouter.isOffRamp(partialOffRampAdds[i].sourceChainSelector, partialOffRampAdds[i].offRamp)); + assertOffRampRouteSucceeds(partialOffRampAdds[i]); + } + for (uint256 i = numberOfPartialUpdates; i < offRampUpdates.length; ++i) { + assertTrue(s_sourceRouter.isOffRamp(offRampUpdates[i].sourceChainSelector, offRampUpdates[i].offRamp)); + assertOffRampRouteSucceeds(offRampUpdates[i]); + } + + vm.startPrank(OWNER); + + // 3rd test scenario: remove all offRamps. + // Check all offramps have been removed, no offramp is able to route messages. + for (uint256 i = 0; i < numberOfPartialUpdates; ++i) { + vm.expectEmit(); + emit Router.OffRampRemoved(partialOffRampAdds[i].sourceChainSelector, partialOffRampAdds[i].offRamp); + } + s_sourceRouter.applyRampUpdates(onRampUpdates, partialOffRampAdds, new Router.OffRamp[](0)); + + uint256 numberOfRemainingOfframps = offRampUpdates.length - numberOfPartialUpdates; + Router.OffRamp[] memory remainingOffRampRemoves = new Router.OffRamp[](numberOfRemainingOfframps); + for (uint256 i = 0; i < numberOfRemainingOfframps; ++i) { + remainingOffRampRemoves[i] = offRampUpdates[i + numberOfPartialUpdates]; + } + + for (uint256 i = 0; i < numberOfRemainingOfframps; ++i) { + vm.expectEmit(); + emit Router.OffRampRemoved(remainingOffRampRemoves[i].sourceChainSelector, remainingOffRampRemoves[i].offRamp); + } + s_sourceRouter.applyRampUpdates(onRampUpdates, remainingOffRampRemoves, new Router.OffRamp[](0)); + + // Check there are no offRamps. + assertEq(0, s_sourceRouter.getOffRamps().length); + + for (uint256 i = 0; i < numberOfPartialUpdates; ++i) { + assertFalse(s_sourceRouter.isOffRamp(partialOffRampAdds[i].sourceChainSelector, partialOffRampAdds[i].offRamp)); + assertOffRampRouteReverts(partialOffRampAdds[i]); + } + for (uint256 i = 0; i < offRampUpdates.length; ++i) { + assertFalse(s_sourceRouter.isOffRamp(offRampUpdates[i].sourceChainSelector, offRampUpdates[i].offRamp)); + assertOffRampRouteReverts(offRampUpdates[i]); + } + + vm.startPrank(OWNER); + + // 4th test scenario: add initial onRamps back. + // Check the offramps are added correctly, and can route messages. + // Check offramps that were not added back remain unset, and cannot route messages. + for (uint256 i = 0; i < offRampUpdates.length; ++i) { + vm.expectEmit(); + emit Router.OffRampAdded(offRampUpdates[i].sourceChainSelector, offRampUpdates[i].offRamp); + } + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + + // Check initial offRamps are added back and can route to receiver. + gotOffRamps = s_sourceRouter.getOffRamps(); + assertEq(offRampUpdates.length, gotOffRamps.length); + + for (uint256 i = 0; i < offRampUpdates.length; ++i) { + assertEq(offRampUpdates[i].offRamp, gotOffRamps[i].offRamp); + assertTrue(s_sourceRouter.isOffRamp(offRampUpdates[i].sourceChainSelector, offRampUpdates[i].offRamp)); + assertOffRampRouteSucceeds(offRampUpdates[i]); + } + + // Check offramps that were not added back remain unset. + for (uint256 i = 0; i < numberOfPartialUpdates; ++i) { + assertFalse(s_sourceRouter.isOffRamp(partialOffRampAdds[i].sourceChainSelector, partialOffRampAdds[i].offRamp)); + assertOffRampRouteReverts(partialOffRampAdds[i]); + } + } + + function test_Fuzz_OnRampUpdates(Router.OnRamp[] memory onRamps) public { + // Test adding onRamps + for (uint256 i = 0; i < onRamps.length; ++i) { + vm.expectEmit(); + emit Router.OnRampSet(onRamps[i].destChainSelector, onRamps[i].onRamp); + } + + s_sourceRouter.applyRampUpdates(onRamps, new Router.OffRamp[](0), new Router.OffRamp[](0)); + + // Test setting onRamps to unsupported + for (uint256 i = 0; i < onRamps.length; ++i) { + onRamps[i].onRamp = address(0); + + vm.expectEmit(); + emit Router.OnRampSet(onRamps[i].destChainSelector, onRamps[i].onRamp); + } + s_sourceRouter.applyRampUpdates(onRamps, new Router.OffRamp[](0), new Router.OffRamp[](0)); + for (uint256 i = 0; i < onRamps.length; ++i) { + assertEq(address(0), s_sourceRouter.getOnRamp(onRamps[i].destChainSelector)); + assertFalse(s_sourceRouter.isChainSupported(onRamps[i].destChainSelector)); + } + } + + function test_OnRampDisable() public { + // Add onRamp + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](0); + address onRamp = address(uint160(2)); + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: onRamp}); + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + assertEq(onRamp, s_sourceRouter.getOnRamp(DEST_CHAIN_SELECTOR)); + assertTrue(s_sourceRouter.isChainSupported(DEST_CHAIN_SELECTOR)); + + // Disable onRamp + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: address(0)}); + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), new Router.OffRamp[](0)); + assertEq(address(0), s_sourceRouter.getOnRamp(DEST_CHAIN_SELECTOR)); + assertFalse(s_sourceRouter.isChainSupported(DEST_CHAIN_SELECTOR)); + + // Re-enable onRamp + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: onRamp}); + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), new Router.OffRamp[](0)); + assertEq(onRamp, s_sourceRouter.getOnRamp(DEST_CHAIN_SELECTOR)); + assertTrue(s_sourceRouter.isChainSupported(DEST_CHAIN_SELECTOR)); + } + + function test_OnlyOwner_Revert() public { + vm.stopPrank(); + vm.expectRevert("Only callable by owner"); + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](0); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](0); + s_sourceRouter.applyRampUpdates(onRampUpdates, offRampUpdates, offRampUpdates); + } + + function test_OffRampMismatch_Revert() public { + address offRamp = address(uint160(2)); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](0); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + offRampUpdates[0] = Router.OffRamp(DEST_CHAIN_SELECTOR, offRamp); + + vm.expectEmit(); + emit Router.OffRampAdded(DEST_CHAIN_SELECTOR, offRamp); + s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + + offRampUpdates[0] = Router.OffRamp(SOURCE_CHAIN_SELECTOR, offRamp); + + vm.expectRevert(abi.encodeWithSelector(Router.OffRampMismatch.selector, SOURCE_CHAIN_SELECTOR, offRamp)); + s_sourceRouter.applyRampUpdates(onRampUpdates, offRampUpdates, offRampUpdates); + } +} + +contract Router_setWrappedNative is EVM2EVMOnRampSetup { + function test_Fuzz_SetWrappedNative_Success(address wrappedNative) public { + s_sourceRouter.setWrappedNative(wrappedNative); + assertEq(wrappedNative, s_sourceRouter.getWrappedNative()); + } + + // Reverts + function test_OnlyOwner_Revert() public { + vm.stopPrank(); + vm.expectRevert("Only callable by owner"); + s_sourceRouter.setWrappedNative(address(1)); + } +} + +contract Router_getSupportedTokens is EVM2EVMOnRampSetup { + function test_GetSupportedTokens_Revert() public { + vm.expectRevert(EVM2EVMOnRamp.GetSupportedTokensFunctionalityRemovedCheckAdminRegistry.selector); + s_onRamp.getSupportedTokens(DEST_CHAIN_SELECTOR); + } +} + +contract Router_routeMessage is EVM2EVMOffRampSetup { + function setUp() public virtual override { + EVM2EVMOffRampSetup.setUp(); + vm.startPrank(address(s_offRamp)); + } + + function generateManualGasLimit(uint256 callDataLength) internal view returns (uint256) { + return ((gasleft() - 2 * (16 * callDataLength + GAS_FOR_CALL_EXACT_CHECK)) * 62) / 64; + } + + function test_ManualExec_Success() public { + Client.Any2EVMMessage memory message = generateReceiverMessage(SOURCE_CHAIN_SELECTOR); + // Manuel execution cannot run out of gas + + (bool success, bytes memory retData, uint256 gasUsed) = s_destRouter.routeMessage( + generateReceiverMessage(SOURCE_CHAIN_SELECTOR), + GAS_FOR_CALL_EXACT_CHECK, + generateManualGasLimit(message.data.length), + address(s_receiver) + ); + assertTrue(success); + assertEq("", retData); + assertGt(gasUsed, 3_000); + } + + function test_ExecutionEvent_Success() public { + Client.Any2EVMMessage memory message = generateReceiverMessage(SOURCE_CHAIN_SELECTOR); + // Should revert with reason + bytes memory realError1 = new bytes(2); + realError1[0] = 0xbe; + realError1[1] = 0xef; + s_reverting_receiver.setErr(realError1); + + vm.expectEmit(); + emit Router.MessageExecuted( + message.messageId, + message.sourceChainSelector, + address(s_offRamp), + keccak256(abi.encodeWithSelector(IAny2EVMMessageReceiver.ccipReceive.selector, message)) + ); + + (bool success, bytes memory retData, uint256 gasUsed) = s_destRouter.routeMessage( + generateReceiverMessage(SOURCE_CHAIN_SELECTOR), + GAS_FOR_CALL_EXACT_CHECK, + generateManualGasLimit(message.data.length), + address(s_reverting_receiver) + ); + + assertFalse(success); + assertEq(abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, realError1), retData); + assertGt(gasUsed, 3_000); + + // Reason is truncated + // Over the MAX_RET_BYTES limit (including offset and length word since we have a dynamic values), should be ignored + bytes memory realError2 = new bytes(32 * 2 + 1); + realError2[32 * 2 - 1] = 0xAA; + realError2[32 * 2] = 0xFF; + s_reverting_receiver.setErr(realError2); + + vm.expectEmit(); + emit Router.MessageExecuted( + message.messageId, + message.sourceChainSelector, + address(s_offRamp), + keccak256(abi.encodeWithSelector(IAny2EVMMessageReceiver.ccipReceive.selector, message)) + ); + + (success, retData, gasUsed) = s_destRouter.routeMessage( + generateReceiverMessage(SOURCE_CHAIN_SELECTOR), + GAS_FOR_CALL_EXACT_CHECK, + generateManualGasLimit(message.data.length), + address(s_reverting_receiver) + ); + + assertFalse(success); + assertEq( + abi.encodeWithSelector( + MaybeRevertMessageReceiver.CustomError.selector, + uint256(32), + uint256(realError2.length), + uint256(0), + uint256(0xAA) + ), + retData + ); + assertGt(gasUsed, 3_000); + + // Should emit success + vm.expectEmit(); + emit Router.MessageExecuted( + message.messageId, + message.sourceChainSelector, + address(s_offRamp), + keccak256(abi.encodeWithSelector(IAny2EVMMessageReceiver.ccipReceive.selector, message)) + ); + + (success, retData, gasUsed) = s_destRouter.routeMessage( + generateReceiverMessage(SOURCE_CHAIN_SELECTOR), + GAS_FOR_CALL_EXACT_CHECK, + generateManualGasLimit(message.data.length), + address(s_receiver) + ); + + assertTrue(success); + assertEq("", retData); + assertGt(gasUsed, 3_000); + } + + function test_Fuzz_ExecutionEvent_Success(bytes calldata error) public { + Client.Any2EVMMessage memory message = generateReceiverMessage(SOURCE_CHAIN_SELECTOR); + s_reverting_receiver.setErr(error); + + bytes memory expectedRetData; + + if (error.length >= 33) { + uint256 cutOff = error.length > 64 ? 64 : error.length; + vm.expectEmit(); + emit Router.MessageExecuted( + message.messageId, + message.sourceChainSelector, + address(s_offRamp), + keccak256(abi.encodeWithSelector(IAny2EVMMessageReceiver.ccipReceive.selector, message)) + ); + expectedRetData = abi.encodeWithSelector( + MaybeRevertMessageReceiver.CustomError.selector, + uint256(32), + uint256(error.length), + bytes32(error[:32]), + bytes32(error[32:cutOff]) + ); + } else { + vm.expectEmit(); + emit Router.MessageExecuted( + message.messageId, + message.sourceChainSelector, + address(s_offRamp), + keccak256(abi.encodeWithSelector(IAny2EVMMessageReceiver.ccipReceive.selector, message)) + ); + expectedRetData = abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, error); + } + + (bool success, bytes memory retData,) = s_destRouter.routeMessage( + generateReceiverMessage(SOURCE_CHAIN_SELECTOR), + GAS_FOR_CALL_EXACT_CHECK, + generateManualGasLimit(message.data.length), + address(s_reverting_receiver) + ); + + assertFalse(success); + assertEq(expectedRetData, retData); + } + + function test_AutoExec_Success() public { + (bool success,,) = s_destRouter.routeMessage( + generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver) + ); + + assertTrue(success); + + (success,,) = s_destRouter.routeMessage( + generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, 1, address(s_receiver) + ); + + // Can run out of gas, should return false + assertFalse(success); + } + + // Reverts + function test_OnlyOffRamp_Revert() public { + vm.stopPrank(); + vm.startPrank(STRANGER); + + vm.expectRevert(IRouter.OnlyOffRamp.selector); + s_destRouter.routeMessage( + generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver) + ); + } + + function test_WhenNotHealthy_Revert() public { + s_mockRMN.setGlobalCursed(true); + vm.expectRevert(Router.BadARMSignal.selector); + s_destRouter.routeMessage( + generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver) + ); + } +} + +contract Router_getFee is EVM2EVMOnRampSetup { + function test_GetFeeSupportedChain_Success() public view { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, message); + assertGt(expectedFee, 10e9); + } + + // Reverts + function test_UnsupportedDestinationChain_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + vm.expectRevert(abi.encodeWithSelector(IRouterClient.UnsupportedDestinationChain.selector, 999)); + s_sourceRouter.getFee(999, message); + } +} diff --git a/contracts/src/v0.8/ccip/test/router/RouterSetup.t.sol b/contracts/src/v0.8/ccip/test/router/RouterSetup.t.sol new file mode 100644 index 0000000000..de75161761 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/router/RouterSetup.t.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {Router} from "../../Router.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {BaseTest} from "../BaseTest.t.sol"; +import {WETH9} from "../WETH9.sol"; + +contract RouterSetup is BaseTest { + Router internal s_sourceRouter; + Router internal s_destRouter; + + function setUp() public virtual override { + BaseTest.setUp(); + + if (address(s_sourceRouter) == address(0)) { + WETH9 weth = new WETH9(); + s_sourceRouter = new Router(address(weth), address(s_mockRMN)); + vm.label(address(s_sourceRouter), "sourceRouter"); + } + if (address(s_destRouter) == address(0)) { + WETH9 weth = new WETH9(); + s_destRouter = new Router(address(weth), address(s_mockRMN)); + vm.label(address(s_destRouter), "destRouter"); + } + } + + function generateReceiverMessage(uint64 chainSelector) internal pure returns (Client.Any2EVMMessage memory) { + Client.EVMTokenAmount[] memory ta = new Client.EVMTokenAmount[](0); + return Client.Any2EVMMessage({ + messageId: bytes32("a"), + sourceChainSelector: chainSelector, + sender: bytes("a"), + data: bytes("a"), + destTokenAmounts: ta + }); + } + + function generateSourceTokenData() internal pure returns (Internal.SourceTokenData memory) { + return Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(address(12312412312)), + destTokenAddress: abi.encode(address(9809808909)), + extraData: "" + }); + } +} diff --git a/contracts/src/v0.8/ccip/test/tokenAdminRegistry/RegistryModuleOwnerCustom.t.sol b/contracts/src/v0.8/ccip/test/tokenAdminRegistry/RegistryModuleOwnerCustom.t.sol new file mode 100644 index 0000000000..dfb599bd30 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/tokenAdminRegistry/RegistryModuleOwnerCustom.t.sol @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {IGetCCIPAdmin} from "../../interfaces/IGetCCIPAdmin.sol"; +import {IOwner} from "../../interfaces/IOwner.sol"; + +import {RegistryModuleOwnerCustom} from "../../tokenAdminRegistry/RegistryModuleOwnerCustom.sol"; +import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; +import {BurnMintERC677Helper} from "../helpers/BurnMintERC677Helper.sol"; + +import {Test} from "forge-std/Test.sol"; + +contract RegistryModuleOwnerCustomSetup is Test { + address internal constant OWNER = 0x00007e64E1fB0C487F25dd6D3601ff6aF8d32e4e; + + RegistryModuleOwnerCustom internal s_registryModuleOwnerCustom; + TokenAdminRegistry internal s_tokenAdminRegistry; + address internal s_token; + + function setUp() public virtual { + vm.startPrank(OWNER); + + s_tokenAdminRegistry = new TokenAdminRegistry(); + s_token = address(new BurnMintERC677Helper("Test", "TST")); + s_registryModuleOwnerCustom = new RegistryModuleOwnerCustom(address(s_tokenAdminRegistry)); + s_tokenAdminRegistry.addRegistryModule(address(s_registryModuleOwnerCustom)); + } +} + +contract RegistryModuleOwnerCustom_constructor is RegistryModuleOwnerCustomSetup { + function test_constructor_Revert() public { + vm.expectRevert(abi.encodeWithSelector(RegistryModuleOwnerCustom.AddressZero.selector)); + + new RegistryModuleOwnerCustom(address(0)); + } +} + +contract RegistryModuleOwnerCustom_registerAdminViaGetCCIPAdmin is RegistryModuleOwnerCustomSetup { + function test_registerAdminViaGetCCIPAdmin_Success() public { + assertEq(s_tokenAdminRegistry.getTokenConfig(s_token).administrator, address(0)); + + address expectedOwner = IGetCCIPAdmin(s_token).getCCIPAdmin(); + + vm.expectCall(s_token, abi.encodeWithSelector(IGetCCIPAdmin.getCCIPAdmin.selector), 1); + vm.expectCall( + address(s_tokenAdminRegistry), + abi.encodeWithSelector(TokenAdminRegistry.proposeAdministrator.selector, s_token, expectedOwner), + 1 + ); + + vm.expectEmit(); + emit RegistryModuleOwnerCustom.AdministratorRegistered(s_token, expectedOwner); + + s_registryModuleOwnerCustom.registerAdminViaGetCCIPAdmin(s_token); + + assertEq(s_tokenAdminRegistry.getTokenConfig(s_token).pendingAdministrator, OWNER); + } + + function test_registerAdminViaGetCCIPAdmin_Revert() public { + address expectedOwner = IGetCCIPAdmin(s_token).getCCIPAdmin(); + + vm.startPrank(makeAddr("Not_expected_owner")); + + vm.expectRevert( + abi.encodeWithSelector(RegistryModuleOwnerCustom.CanOnlySelfRegister.selector, expectedOwner, s_token) + ); + + s_registryModuleOwnerCustom.registerAdminViaGetCCIPAdmin(s_token); + } +} + +contract RegistryModuleOwnerCustom_registerAdminViaOwner is RegistryModuleOwnerCustomSetup { + function test_registerAdminViaOwner_Success() public { + assertEq(s_tokenAdminRegistry.getTokenConfig(s_token).administrator, address(0)); + + address expectedOwner = IOwner(s_token).owner(); + + vm.expectCall(s_token, abi.encodeWithSelector(IOwner.owner.selector), 1); + vm.expectCall( + address(s_tokenAdminRegistry), + abi.encodeWithSelector(TokenAdminRegistry.proposeAdministrator.selector, s_token, expectedOwner), + 1 + ); + + vm.expectEmit(); + emit RegistryModuleOwnerCustom.AdministratorRegistered(s_token, expectedOwner); + + s_registryModuleOwnerCustom.registerAdminViaOwner(s_token); + + assertEq(s_tokenAdminRegistry.getTokenConfig(s_token).pendingAdministrator, OWNER); + } + + function test_registerAdminViaOwner_Revert() public { + address expectedOwner = IOwner(s_token).owner(); + + vm.startPrank(makeAddr("Not_expected_owner")); + + vm.expectRevert( + abi.encodeWithSelector(RegistryModuleOwnerCustom.CanOnlySelfRegister.selector, expectedOwner, s_token) + ); + + s_registryModuleOwnerCustom.registerAdminViaOwner(s_token); + } +} diff --git a/contracts/src/v0.8/ccip/test/tokenAdminRegistry/TokenAdminRegistry.t.sol b/contracts/src/v0.8/ccip/test/tokenAdminRegistry/TokenAdminRegistry.t.sol new file mode 100644 index 0000000000..ada0369045 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/tokenAdminRegistry/TokenAdminRegistry.t.sol @@ -0,0 +1,393 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {IPoolV1} from "../../interfaces/IPool.sol"; + +import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; +import {TokenSetup} from "../TokenSetup.t.sol"; + +contract TokenAdminRegistrySetup is TokenSetup { + address internal s_registryModule = makeAddr("registryModule"); + + function setUp() public virtual override { + TokenSetup.setUp(); + + s_tokenAdminRegistry.addRegistryModule(s_registryModule); + } +} + +contract TokenAdminRegistry_getPools is TokenAdminRegistrySetup { + function test_getPools_Success() public { + address[] memory tokens = new address[](1); + tokens[0] = s_sourceTokens[0]; + + address[] memory got = s_tokenAdminRegistry.getPools(tokens); + assertEq(got.length, 1); + assertEq(got[0], s_sourcePoolByToken[tokens[0]]); + + got = s_tokenAdminRegistry.getPools(s_sourceTokens); + assertEq(got.length, s_sourceTokens.length); + for (uint256 i = 0; i < s_sourceTokens.length; i++) { + assertEq(got[i], s_sourcePoolByToken[s_sourceTokens[i]]); + } + + address doesNotExist = makeAddr("doesNotExist"); + tokens[0] = doesNotExist; + got = s_tokenAdminRegistry.getPools(tokens); + assertEq(got.length, 1); + assertEq(got[0], address(0)); + } +} + +contract TokenAdminRegistry_getPool is TokenAdminRegistrySetup { + function test_getPool_Success() public view { + address got = s_tokenAdminRegistry.getPool(s_sourceTokens[0]); + assertEq(got, s_sourcePoolByToken[s_sourceTokens[0]]); + } +} + +contract TokenAdminRegistry_setPool is TokenAdminRegistrySetup { + function test_setPool_Success() public { + address pool = makeAddr("pool"); + vm.mockCall(pool, abi.encodeWithSelector(IPoolV1.isSupportedToken.selector), abi.encode(true)); + + vm.expectEmit(); + emit TokenAdminRegistry.PoolSet(s_sourceTokens[0], s_sourcePoolByToken[s_sourceTokens[0]], pool); + + s_tokenAdminRegistry.setPool(s_sourceTokens[0], pool); + + assertEq(s_tokenAdminRegistry.getPool(s_sourceTokens[0]), pool); + + // Assert the event is not emitted if the pool is the same as the current pool. + vm.recordLogs(); + s_tokenAdminRegistry.setPool(s_sourceTokens[0], pool); + + vm.assertEq(vm.getRecordedLogs().length, 0); + } + + function test_setPool_ZeroAddressRemovesPool_Success() public { + address pool = makeAddr("pool"); + vm.mockCall(pool, abi.encodeWithSelector(IPoolV1.isSupportedToken.selector), abi.encode(true)); + s_tokenAdminRegistry.setPool(s_sourceTokens[0], pool); + + assertEq(s_tokenAdminRegistry.getPool(s_sourceTokens[0]), pool); + + vm.expectEmit(); + emit TokenAdminRegistry.PoolSet(s_sourceTokens[0], pool, address(0)); + + s_tokenAdminRegistry.setPool(s_sourceTokens[0], address(0)); + + assertEq(s_tokenAdminRegistry.getPool(s_sourceTokens[0]), address(0)); + } + + function test_setPool_InvalidTokenPoolToken_Revert() public { + address pool = makeAddr("pool"); + vm.mockCall(pool, abi.encodeWithSelector(IPoolV1.isSupportedToken.selector), abi.encode(false)); + + vm.expectRevert(abi.encodeWithSelector(TokenAdminRegistry.InvalidTokenPoolToken.selector, s_sourceTokens[0])); + s_tokenAdminRegistry.setPool(s_sourceTokens[0], pool); + } + + function test_setPool_OnlyAdministrator_Revert() public { + vm.stopPrank(); + + vm.expectRevert( + abi.encodeWithSelector(TokenAdminRegistry.OnlyAdministrator.selector, address(this), s_sourceTokens[0]) + ); + s_tokenAdminRegistry.setPool(s_sourceTokens[0], makeAddr("pool")); + } +} + +contract TokenAdminRegistry_getAllConfiguredTokens is TokenAdminRegistrySetup { + function test_Fuzz_getAllConfiguredTokens_Success(uint8 numberOfTokens) public { + TokenAdminRegistry cleanTokenAdminRegistry = new TokenAdminRegistry(); + for (uint160 i = 0; i < numberOfTokens; ++i) { + cleanTokenAdminRegistry.proposeAdministrator(address(i), address(i + 1000)); + } + + uint160 count = 0; + for (uint160 start = 0; start < numberOfTokens; start += count++) { + address[] memory got = cleanTokenAdminRegistry.getAllConfiguredTokens(uint64(start), uint64(count)); + if (start + count > numberOfTokens) { + assertEq(got.length, numberOfTokens - start); + } else { + assertEq(got.length, count); + } + + for (uint160 j = 0; j < got.length; ++j) { + assertEq(got[j], address(j + start)); + } + } + } + + function test_getAllConfiguredTokens_outOfBounds_Success() public view { + address[] memory tokens = s_tokenAdminRegistry.getAllConfiguredTokens(type(uint64).max, 10); + assertEq(tokens.length, 0); + } +} + +contract TokenAdminRegistry_transferAdminRole is TokenAdminRegistrySetup { + function test_transferAdminRole_Success() public { + address token = s_sourceTokens[0]; + + address currentAdmin = s_tokenAdminRegistry.getTokenConfig(token).administrator; + address newAdmin = makeAddr("newAdmin"); + + vm.expectEmit(); + emit TokenAdminRegistry.AdministratorTransferRequested(token, currentAdmin, newAdmin); + + s_tokenAdminRegistry.transferAdminRole(token, newAdmin); + + TokenAdminRegistry.TokenConfig memory config = s_tokenAdminRegistry.getTokenConfig(token); + + // Assert only the pending admin updates, without affecting the pending admin. + assertEq(config.pendingAdministrator, newAdmin); + assertEq(config.administrator, currentAdmin); + } + + function test_transferAdminRole_OnlyAdministrator_Revert() public { + vm.stopPrank(); + + vm.expectRevert( + abi.encodeWithSelector(TokenAdminRegistry.OnlyAdministrator.selector, address(this), s_sourceTokens[0]) + ); + s_tokenAdminRegistry.transferAdminRole(s_sourceTokens[0], makeAddr("newAdmin")); + } +} + +contract TokenAdminRegistry_acceptAdminRole is TokenAdminRegistrySetup { + function test_acceptAdminRole_Success() public { + address token = s_sourceTokens[0]; + + address currentAdmin = s_tokenAdminRegistry.getTokenConfig(token).administrator; + address newAdmin = makeAddr("newAdmin"); + + vm.expectEmit(); + emit TokenAdminRegistry.AdministratorTransferRequested(token, currentAdmin, newAdmin); + + s_tokenAdminRegistry.transferAdminRole(token, newAdmin); + + TokenAdminRegistry.TokenConfig memory config = s_tokenAdminRegistry.getTokenConfig(token); + + // Assert only the pending admin updates, without affecting the pending admin. + assertEq(config.pendingAdministrator, newAdmin); + assertEq(config.administrator, currentAdmin); + + vm.startPrank(newAdmin); + + vm.expectEmit(); + emit TokenAdminRegistry.AdministratorTransferred(token, newAdmin); + + s_tokenAdminRegistry.acceptAdminRole(token); + + config = s_tokenAdminRegistry.getTokenConfig(token); + + // Assert only the pending admin updates, without affecting the pending admin. + assertEq(config.pendingAdministrator, address(0)); + assertEq(config.administrator, newAdmin); + } + + function test_acceptAdminRole_OnlyPendingAdministrator_Revert() public { + address token = s_sourceTokens[0]; + address currentAdmin = s_tokenAdminRegistry.getTokenConfig(token).administrator; + address newAdmin = makeAddr("newAdmin"); + + s_tokenAdminRegistry.transferAdminRole(token, newAdmin); + + TokenAdminRegistry.TokenConfig memory config = s_tokenAdminRegistry.getTokenConfig(token); + + // Assert only the pending admin updates, without affecting the pending admin. + assertEq(config.pendingAdministrator, newAdmin); + assertEq(config.administrator, currentAdmin); + + address notNewAdmin = makeAddr("notNewAdmin"); + vm.startPrank(notNewAdmin); + + vm.expectRevert(abi.encodeWithSelector(TokenAdminRegistry.OnlyPendingAdministrator.selector, notNewAdmin, token)); + s_tokenAdminRegistry.acceptAdminRole(token); + } +} + +contract TokenAdminRegistry_isAdministrator is TokenAdminRegistrySetup { + function test_isAdministrator_Success() public { + address newAdmin = makeAddr("newAdmin"); + address newToken = makeAddr("newToken"); + assertFalse(s_tokenAdminRegistry.isAdministrator(newToken, newAdmin)); + assertFalse(s_tokenAdminRegistry.isAdministrator(newToken, OWNER)); + + s_tokenAdminRegistry.proposeAdministrator(newToken, newAdmin); + changePrank(newAdmin); + s_tokenAdminRegistry.acceptAdminRole(newToken); + + assertTrue(s_tokenAdminRegistry.isAdministrator(newToken, newAdmin)); + assertFalse(s_tokenAdminRegistry.isAdministrator(newToken, OWNER)); + } +} + +contract TokenAdminRegistry_proposeAdministrator is TokenAdminRegistrySetup { + function test_proposeAdministrator_module_Success() public { + vm.startPrank(s_registryModule); + address newAdmin = makeAddr("newAdmin"); + address newToken = makeAddr("newToken"); + + vm.expectEmit(); + emit TokenAdminRegistry.AdministratorTransferRequested(newToken, address(0), newAdmin); + + s_tokenAdminRegistry.proposeAdministrator(newToken, newAdmin); + + assertEq(s_tokenAdminRegistry.getTokenConfig(newToken).pendingAdministrator, newAdmin); + assertEq(s_tokenAdminRegistry.getTokenConfig(newToken).administrator, address(0)); + assertEq(s_tokenAdminRegistry.getTokenConfig(newToken).tokenPool, address(0)); + + changePrank(newAdmin); + s_tokenAdminRegistry.acceptAdminRole(newToken); + + assertTrue(s_tokenAdminRegistry.isAdministrator(newToken, newAdmin)); + } + + function test_proposeAdministrator_owner_Success() public { + address newAdmin = makeAddr("newAdmin"); + address newToken = makeAddr("newToken"); + + vm.expectEmit(); + emit TokenAdminRegistry.AdministratorTransferRequested(newToken, address(0), newAdmin); + + s_tokenAdminRegistry.proposeAdministrator(newToken, newAdmin); + + assertEq(s_tokenAdminRegistry.getTokenConfig(newToken).pendingAdministrator, newAdmin); + + changePrank(newAdmin); + s_tokenAdminRegistry.acceptAdminRole(newToken); + + assertTrue(s_tokenAdminRegistry.isAdministrator(newToken, newAdmin)); + } + + function test_proposeAdministrator_reRegisterWhileUnclaimed_Success() public { + address newAdmin = makeAddr("wrongAddress"); + address newToken = makeAddr("newToken"); + + vm.expectEmit(); + emit TokenAdminRegistry.AdministratorTransferRequested(newToken, address(0), newAdmin); + + s_tokenAdminRegistry.proposeAdministrator(newToken, newAdmin); + + assertEq(s_tokenAdminRegistry.getTokenConfig(newToken).pendingAdministrator, newAdmin); + + newAdmin = makeAddr("correctAddress"); + + vm.expectEmit(); + emit TokenAdminRegistry.AdministratorTransferRequested(newToken, address(0), newAdmin); + + // Ensure we can still register the correct admin while the previous admin is unclaimed. + s_tokenAdminRegistry.proposeAdministrator(newToken, newAdmin); + + changePrank(newAdmin); + s_tokenAdminRegistry.acceptAdminRole(newToken); + + assertTrue(s_tokenAdminRegistry.isAdministrator(newToken, newAdmin)); + } + + mapping(address token => address admin) internal s_AdminByToken; + + function test_Fuzz_proposeAdministrator_Success(address[50] memory tokens, address[50] memory admins) public { + TokenAdminRegistry cleanTokenAdminRegistry = new TokenAdminRegistry(); + for (uint256 i = 0; i < tokens.length; i++) { + if (admins[i] == address(0)) { + continue; + } + if (cleanTokenAdminRegistry.getTokenConfig(tokens[i]).administrator != address(0)) { + continue; + } + cleanTokenAdminRegistry.proposeAdministrator(tokens[i], admins[i]); + s_AdminByToken[tokens[i]] = admins[i]; + } + + for (uint256 i = 0; i < tokens.length; i++) { + assertEq(cleanTokenAdminRegistry.getTokenConfig(tokens[i]).pendingAdministrator, s_AdminByToken[tokens[i]]); + } + } + + function test_proposeAdministrator_OnlyRegistryModule_Revert() public { + address newToken = makeAddr("newToken"); + vm.stopPrank(); + + vm.expectRevert(abi.encodeWithSelector(TokenAdminRegistry.OnlyRegistryModuleOrOwner.selector, address(this))); + s_tokenAdminRegistry.proposeAdministrator(newToken, OWNER); + } + + function test_proposeAdministrator_ZeroAddress_Revert() public { + address newToken = makeAddr("newToken"); + + vm.expectRevert(abi.encodeWithSelector(TokenAdminRegistry.ZeroAddress.selector)); + s_tokenAdminRegistry.proposeAdministrator(newToken, address(0)); + } + + function test_proposeAdministrator_AlreadyRegistered_Revert() public { + address newAdmin = makeAddr("newAdmin"); + address newToken = makeAddr("newToken"); + + s_tokenAdminRegistry.proposeAdministrator(newToken, newAdmin); + changePrank(newAdmin); + s_tokenAdminRegistry.acceptAdminRole(newToken); + + changePrank(OWNER); + + vm.expectRevert(abi.encodeWithSelector(TokenAdminRegistry.AlreadyRegistered.selector, newToken)); + s_tokenAdminRegistry.proposeAdministrator(newToken, newAdmin); + } +} + +contract TokenAdminRegistry_addRegistryModule is TokenAdminRegistrySetup { + function test_addRegistryModule_Success() public { + address newModule = makeAddr("newModule"); + + s_tokenAdminRegistry.addRegistryModule(newModule); + + assertTrue(s_tokenAdminRegistry.isRegistryModule(newModule)); + + // Assert the event is not emitted if the module is already added. + vm.recordLogs(); + s_tokenAdminRegistry.addRegistryModule(newModule); + + vm.assertEq(vm.getRecordedLogs().length, 0); + } + + function test_addRegistryModule_OnlyOwner_Revert() public { + address newModule = makeAddr("newModule"); + vm.stopPrank(); + + vm.expectRevert("Only callable by owner"); + s_tokenAdminRegistry.addRegistryModule(newModule); + } +} + +contract TokenAdminRegistry_removeRegistryModule is TokenAdminRegistrySetup { + function test_removeRegistryModule_Success() public { + address newModule = makeAddr("newModule"); + + s_tokenAdminRegistry.addRegistryModule(newModule); + + assertTrue(s_tokenAdminRegistry.isRegistryModule(newModule)); + + vm.expectEmit(); + emit TokenAdminRegistry.RegistryModuleRemoved(newModule); + + s_tokenAdminRegistry.removeRegistryModule(newModule); + + assertFalse(s_tokenAdminRegistry.isRegistryModule(newModule)); + + // Assert the event is not emitted if the module is already removed. + vm.recordLogs(); + s_tokenAdminRegistry.removeRegistryModule(newModule); + + vm.assertEq(vm.getRecordedLogs().length, 0); + } + + function test_removeRegistryModule_OnlyOwner_Revert() public { + address newModule = makeAddr("newModule"); + vm.stopPrank(); + + vm.expectRevert("Only callable by owner"); + s_tokenAdminRegistry.removeRegistryModule(newModule); + } +} diff --git a/contracts/src/v0.8/ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol b/contracts/src/v0.8/ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol new file mode 100644 index 0000000000..3cd17df05f --- /dev/null +++ b/contracts/src/v0.8/ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IGetCCIPAdmin} from "../interfaces/IGetCCIPAdmin.sol"; +import {IOwner} from "../interfaces/IOwner.sol"; +import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol"; + +contract RegistryModuleOwnerCustom is ITypeAndVersion { + error CanOnlySelfRegister(address admin, address token); + error AddressZero(); + + event AdministratorRegistered(address indexed token, address indexed administrator); + + string public constant override typeAndVersion = "RegistryModuleOwnerCustom 1.5.0-dev"; + + // The TokenAdminRegistry contract + ITokenAdminRegistry internal immutable i_tokenAdminRegistry; + + constructor(address tokenAdminRegistry) { + if (tokenAdminRegistry == address(0)) { + revert AddressZero(); + } + i_tokenAdminRegistry = ITokenAdminRegistry(tokenAdminRegistry); + } + + /// @notice Registers the admin of the token using the `getCCIPAdmin` method. + /// @param token The token to register the admin for. + /// @dev The caller must be the admin returned by the `getCCIPAdmin` method. + function registerAdminViaGetCCIPAdmin(address token) external { + _registerAdmin(token, IGetCCIPAdmin(token).getCCIPAdmin()); + } + + /// @notice Registers the admin of the token using the `owner` method. + /// @param token The token to register the admin for. + /// @dev The caller must be the admin returned by the `owner` method. + function registerAdminViaOwner(address token) external { + _registerAdmin(token, IOwner(token).owner()); + } + + /// @notice Registers the admin of the token to msg.sender given that the + /// admin is equal to msg.sender. + /// @param token The token to register the admin for. + /// @param admin The caller must be the admin. + function _registerAdmin(address token, address admin) internal { + if (admin != msg.sender) { + revert CanOnlySelfRegister(admin, token); + } + + i_tokenAdminRegistry.proposeAdministrator(token, admin); + + emit AdministratorRegistered(token, admin); + } +} diff --git a/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenAdminRegistry.sol b/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenAdminRegistry.sol new file mode 100644 index 0000000000..32394a396e --- /dev/null +++ b/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenAdminRegistry.sol @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IPoolV1} from "../interfaces/IPool.sol"; +import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol"; + +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; + +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +/// @notice This contract stores the token pool configuration for all CCIP enabled tokens. It works +/// on a self-serve basis, where tokens can be registered without intervention from the CCIP owner. +/// @dev This contract is not considered upgradable, as it is a customer facing contract that will store +/// significant amounts of data. +contract TokenAdminRegistry is ITokenAdminRegistry, ITypeAndVersion, OwnerIsCreator { + using EnumerableSet for EnumerableSet.AddressSet; + + error OnlyRegistryModuleOrOwner(address sender); + error OnlyAdministrator(address sender, address token); + error OnlyPendingAdministrator(address sender, address token); + error AlreadyRegistered(address token); + error ZeroAddress(); + error InvalidTokenPoolToken(address token); + + event PoolSet(address indexed token, address indexed previousPool, address indexed newPool); + event AdministratorTransferRequested(address indexed token, address indexed currentAdmin, address indexed newAdmin); + event AdministratorTransferred(address indexed token, address indexed newAdmin); + event DisableReRegistrationSet(address indexed token, bool disabled); + event RemovedAdministrator(address token); + event RegistryModuleAdded(address module); + event RegistryModuleRemoved(address indexed module); + + // The struct is packed in a way that optimizes the attributes that are accessed together. + // solhint-disable-next-line gas-struct-packing + struct TokenConfig { + address administrator; // the current administrator of the token + address pendingAdministrator; // the address that is pending to become the new administrator + address tokenPool; // the token pool for this token. Can be address(0) if not deployed or not configured. + } + + string public constant override typeAndVersion = "TokenAdminRegistry 1.5.0-dev"; + + // Mapping of token address to token configuration + mapping(address token => TokenConfig) internal s_tokenConfig; + + // All tokens that have been configured + EnumerableSet.AddressSet internal s_tokens; + + // Registry modules are allowed to register administrators for tokens + EnumerableSet.AddressSet internal s_registryModules; + + /// @notice Returns all pools for the given tokens. + /// @dev Will return address(0) for tokens that do not have a pool. + function getPools(address[] calldata tokens) external view returns (address[] memory) { + address[] memory pools = new address[](tokens.length); + for (uint256 i = 0; i < tokens.length; ++i) { + pools[i] = s_tokenConfig[tokens[i]].tokenPool; + } + return pools; + } + + /// @inheritdoc ITokenAdminRegistry + function getPool(address token) external view returns (address) { + return s_tokenConfig[token].tokenPool; + } + + /// @notice Returns the configuration for a token. + /// @param token The token to get the configuration for. + /// @return config The configuration for the token. + function getTokenConfig(address token) external view returns (TokenConfig memory) { + return s_tokenConfig[token]; + } + + /// @notice Returns a list of tokens that are configured in the token admin registry. + /// @param startIndex Starting index in list, can be 0 if you want to start from the beginning. + /// @param maxCount Maximum number of tokens to retrieve. Since the list can be large, + /// it is recommended to use a paging mechanism to retrieve all tokens. If querying for very + /// large lists, RPCs can time out. If you want all tokens, use type(uint64).max. + /// @return tokens List of configured tokens. + /// @dev The function is paginated to avoid RPC timeouts. + /// @dev The ordering is guaranteed to remain the same as it is not possible to remove tokens + /// from s_tokens. + function getAllConfiguredTokens(uint64 startIndex, uint64 maxCount) external view returns (address[] memory tokens) { + uint256 numberOfTokens = s_tokens.length(); + if (startIndex >= numberOfTokens) { + return tokens; + } + uint256 count = maxCount; + if (count + startIndex > numberOfTokens) { + count = numberOfTokens - startIndex; + } + tokens = new address[](count); + for (uint256 i = 0; i < count; ++i) { + tokens[i] = s_tokens.at(startIndex + i); + } + + return tokens; + } + + // ================================================================ + // │ Administrator functions │ + // ================================================================ + + /// @notice Sets the pool for a token. Setting the pool to address(0) effectively delists the token + /// from CCIP. Setting the pool to any other address enables the token on CCIP. + /// @param localToken The token to set the pool for. + /// @param pool The pool to set for the token. + function setPool(address localToken, address pool) external onlyTokenAdmin(localToken) { + // The pool has to support the token, but we want to allow removing the pool, so we only check + // if the pool supports the token if it is not address(0). + if (pool != address(0) && !IPoolV1(pool).isSupportedToken(localToken)) { + revert InvalidTokenPoolToken(localToken); + } + + TokenConfig storage config = s_tokenConfig[localToken]; + + address previousPool = config.tokenPool; + config.tokenPool = pool; + + if (previousPool != pool) { + emit PoolSet(localToken, previousPool, pool); + } + } + + /// @notice Transfers the administrator role for a token to a new address with a 2-step process. + /// @param localToken The token to transfer the administrator role for. + /// @param newAdmin The address to transfer the administrator role to. Can be address(0) to cancel + /// a pending transfer. + /// @dev The new admin must call `acceptAdminRole` to accept the role. + function transferAdminRole(address localToken, address newAdmin) external onlyTokenAdmin(localToken) { + TokenConfig storage config = s_tokenConfig[localToken]; + config.pendingAdministrator = newAdmin; + + emit AdministratorTransferRequested(localToken, msg.sender, newAdmin); + } + + /// @notice Accepts the administrator role for a token. + /// @param localToken The token to accept the administrator role for. + /// @dev This function can only be called by the pending administrator. + function acceptAdminRole(address localToken) external { + TokenConfig storage config = s_tokenConfig[localToken]; + if (config.pendingAdministrator != msg.sender) { + revert OnlyPendingAdministrator(msg.sender, localToken); + } + + config.administrator = msg.sender; + config.pendingAdministrator = address(0); + + emit AdministratorTransferred(localToken, msg.sender); + } + + // ================================================================ + // │ Administrator config │ + // ================================================================ + + /// @notice Public getter to check for permissions of an administrator + function isAdministrator(address localToken, address administrator) external view returns (bool) { + return s_tokenConfig[localToken].administrator == administrator; + } + + /// @inheritdoc ITokenAdminRegistry + /// @dev Can only be called by a registry module. + function proposeAdministrator(address localToken, address administrator) external { + if (!isRegistryModule(msg.sender) && msg.sender != owner()) { + revert OnlyRegistryModuleOrOwner(msg.sender); + } + if (administrator == address(0)) { + revert ZeroAddress(); + } + TokenConfig storage config = s_tokenConfig[localToken]; + + if (config.administrator != address(0)) { + revert AlreadyRegistered(localToken); + } + + config.pendingAdministrator = administrator; + + // We don't care if it's already in the set, as it's a no-op. + s_tokens.add(localToken); + + emit AdministratorTransferRequested(localToken, address(0), administrator); + } + + // ================================================================ + // │ Registry Modules │ + // ================================================================ + + /// @notice Checks if an address is a registry module. + /// @param module The address to check. + /// @return True if the address is a registry module, false otherwise. + function isRegistryModule(address module) public view returns (bool) { + return s_registryModules.contains(module); + } + + /// @notice Adds a new registry module to the list of allowed modules. + /// @param module The module to add. + function addRegistryModule(address module) external onlyOwner { + if (s_registryModules.add(module)) { + emit RegistryModuleAdded(module); + } + } + + /// @notice Removes a registry module from the list of allowed modules. + /// @param module The module to remove. + function removeRegistryModule(address module) external onlyOwner { + if (s_registryModules.remove(module)) { + emit RegistryModuleRemoved(module); + } + } + + // ================================================================ + // │ Access │ + // ================================================================ + + /// @notice Checks if an address is the administrator of the given token. + modifier onlyTokenAdmin(address token) { + if (s_tokenConfig[token].administrator != msg.sender) { + revert OnlyAdministrator(msg.sender, token); + } + _; + } +} diff --git a/contracts/src/v0.8/ccip/v1.4-CCIP-License-grants.md b/contracts/src/v0.8/ccip/v1.4-CCIP-License-grants.md new file mode 100644 index 0000000000..f206b8adcc --- /dev/null +++ b/contracts/src/v0.8/ccip/v1.4-CCIP-License-grants.md @@ -0,0 +1,5 @@ +v1.4-CCIP-License-grants + +Additional Use Grant(s): + +You may make use of the Cross-Chain Interoperability Protocol v1.4 (which is available subject to the license here the “Licensed Work ”) solely for purposes of importing client-side libraries or example clients to facilitate the integration of the Licensed Work into your application. \ No newline at end of file diff --git a/contracts/src/v0.8/liquiditymanager/LiquidityManager.sol b/contracts/src/v0.8/liquiditymanager/LiquidityManager.sol new file mode 100644 index 0000000000..070930b904 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/LiquidityManager.sol @@ -0,0 +1,575 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IBridgeAdapter} from "./interfaces/IBridge.sol"; +import {ILiquidityManager} from "./interfaces/ILiquidityManager.sol"; +import {ILiquidityContainer} from "./interfaces/ILiquidityContainer.sol"; +import {IWrappedNative} from "../ccip/interfaces/IWrappedNative.sol"; + +import {OCR3Base} from "./ocr/OCR3Base.sol"; + +import {IERC20} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +/// @notice LiquidityManager for a single token over multiple chains. +/// @dev This contract is designed to be used with the LockReleaseTokenPool contract but +/// isn't constrained to it. It can be used with any contract that implements the ILiquidityContainer +/// interface. +/// @dev The OCR3 DON should only be able to transfer funds to other pre-approved contracts +/// on other chains. Under no circumstances should it be able to transfer funds to arbitrary +/// addresses. The owner is therefore in full control of the funds in this contract, not the DON. +/// This is a security feature. The worst that can happen is that the DON can lock up funds in +/// bridges, but it can't steal them. +/// @dev References to local mean logic on the same chain as this contract is deployed on. +/// References to remote mean logic on other chains. +contract LiquidityManager is ILiquidityManager, OCR3Base { + using SafeERC20 for IERC20; + + error ZeroAddress(); + error InvalidRemoteChain(uint64 chainSelector); + error ZeroChainSelector(); + error InsufficientLiquidity(uint256 requested, uint256 available, uint256 reserve); + error EmptyReport(); + error TransferFailed(); + error OnlyFinanceRole(); + + /// @notice Emitted when a finalization step is completed without funds being available. + /// @param ocrSeqNum The OCR sequence number of the report. + /// @param remoteChainSelector The chain selector of the remote chain funds are coming from. + /// @param bridgeSpecificData The bridge specific data that was used to finalize the transfer. + event FinalizationStepCompleted( + uint64 indexed ocrSeqNum, + uint64 indexed remoteChainSelector, + bytes bridgeSpecificData + ); + + /// @notice Emitted when the CLL finance role is set. + /// @param financeRole The address of the new finance role. + event FinanceRoleSet(address financeRole); + + /// @notice Emitted when liquidity is transferred to another chain, or received from another chain. + /// @param ocrSeqNum The OCR sequence number of the report. + /// @param fromChainSelector The chain selector of the chain the funds are coming from. + /// In the event fromChainSelector == i_localChainSelector, this is an outgoing transfer. + /// Otherwise, it is an incoming transfer. + /// @param toChainSelector The chain selector of the chain the funds are going to. + /// In the event toChainSelector == i_localChainSelector, this is an incoming transfer. + /// Otherwise, it is an outgoing transfer. + /// @param to The address the funds are going to. + /// If this is address(this), the funds are arriving in this contract. + /// @param amount The amount of tokens being transferred. + /// @param bridgeSpecificData The bridge specific data that was passed to the local bridge adapter + /// when transferring the funds. + /// @param bridgeReturnData The return data from the local bridge adapter when transferring the funds. + event LiquidityTransferred( + uint64 indexed ocrSeqNum, + uint64 indexed fromChainSelector, + uint64 indexed toChainSelector, + address to, + uint256 amount, + bytes bridgeSpecificData, + bytes bridgeReturnData + ); + + /// @notice Emitted when liquidity is added to the local liquidity container. + /// @param provider The address of the provider that added the liquidity. + /// @param amount The amount of liquidity that was added. + event LiquidityAddedToContainer(address indexed provider, uint256 indexed amount); + + /// @notice Emitted when liquidity is removed from the local liquidity container. + /// @param remover The address of the remover that removed the liquidity. + /// @param amount The amount of liquidity that was removed. + event LiquidityRemovedFromContainer(address indexed remover, uint256 indexed amount); + + /// @notice Emitted when the local liquidity container is set. + /// @param newLiquidityContainer The address of the new liquidity container. + event LiquidityContainerSet(address indexed newLiquidityContainer); + + /// @notice Emitted when the minimum liquidity is set. + /// @param oldBalance The old minimum liquidity. + /// @param newBalance The new minimum liquidity. + event MinimumLiquiditySet(uint256 oldBalance, uint256 newBalance); + + /// @notice Emitted when someone sends native to this contract + /// @param amount The amount of native deposited + /// @param depositor The address that deposited the native + event NativeDeposited(uint256 amount, address depositor); + + /// @notice Emitted when native balance is withdrawn by contract owner + /// @param amount The amount of native withdrawn + /// @param destination The address the native is sent to + event NativeWithdrawn(uint256 amount, address destination); + + /// @notice Emitted when a cross chain rebalancer is set. + /// @param remoteChainSelector The chain selector of the remote chain. + /// @param localBridge The local bridge adapter that will be used to transfer funds. + /// @param remoteToken The address of the token on the remote chain. + /// @param remoteRebalancer The address of the remote rebalancer contract. + /// @param enabled Whether the rebalancer is enabled. + event CrossChainRebalancerSet( + uint64 indexed remoteChainSelector, + IBridgeAdapter localBridge, + address remoteToken, + address remoteRebalancer, + bool enabled + ); + + /// @notice Emitted when a finalization step fails. + /// @param ocrSeqNum The OCR sequence number of the report. + /// @param remoteChainSelector The chain selector of the remote chain funds are coming from. + /// @param bridgeSpecificData The bridge specific data that was used to finalize the transfer. + /// @param reason The reason the finalization failed. + event FinalizationFailed( + uint64 indexed ocrSeqNum, + uint64 indexed remoteChainSelector, + bytes bridgeSpecificData, + bytes reason + ); + + struct CrossChainRebalancer { + address remoteRebalancer; + IBridgeAdapter localBridge; + address remoteToken; + bool enabled; + } + + string public constant override typeAndVersion = "LiquidityManager 1.0.0-dev"; + + /// @notice The token that this pool manages liquidity for. + IERC20 public immutable i_localToken; + + /// @notice The chain selector belonging to the chain this pool is deployed on. + uint64 internal immutable i_localChainSelector; + + /// @notice The target balance defines the expected amount of tokens for this network. + /// Setting the balance to 0 will disable any automated rebalancing operations. + uint256 internal s_minimumLiquidity; + + /// @notice Mapping of chain selector to liquidity container on other chains + mapping(uint64 chainSelector => CrossChainRebalancer) private s_crossChainRebalancer; + + uint64[] private s_supportedDestChains; + + /// @notice The liquidity container on the local chain + /// @dev In the case of CCIP, this would be the token pool. + ILiquidityContainer private s_localLiquidityContainer; + + /// @notice The CLL finance team multisig + address private s_finance; + + constructor( + IERC20 token, + uint64 localChainSelector, + ILiquidityContainer localLiquidityContainer, + uint256 minimumLiquidity, + address finance + ) OCR3Base() { + if (localChainSelector == 0) { + revert ZeroChainSelector(); + } + + if (address(token) == address(0) || address(localLiquidityContainer) == address(0)) { + revert ZeroAddress(); + } + i_localToken = token; + i_localChainSelector = localChainSelector; + s_localLiquidityContainer = localLiquidityContainer; + s_minimumLiquidity = minimumLiquidity; + s_finance = finance; + } + + // ================================================================ + // │ Native Management │ + // ================================================================ + + receive() external payable { + emit NativeDeposited(msg.value, msg.sender); + } + + /// @notice withdraw native balance + function withdrawNative(uint256 amount, address payable destination) external onlyFinance { + (bool success, ) = destination.call{value: amount}(""); + if (!success) revert TransferFailed(); + + emit NativeWithdrawn(amount, destination); + } + + // ================================================================ + // │ Liquidity Management │ + // ================================================================ + + /// @inheritdoc ILiquidityManager + function getLiquidity() public view returns (uint256 currentLiquidity) { + return i_localToken.balanceOf(address(s_localLiquidityContainer)); + } + + /// @notice Adds liquidity to the multi-chain system. + /// @dev Anyone can call this function, but anyone other than the owner should regard + /// adding liquidity as a donation to the system, as there is no way to get it out. + /// This function is open to anyone to be able to quickly add funds to the system + /// without having to go through potentially complicated multisig schemes to do it from + /// the owner address. + function addLiquidity(uint256 amount) external { + i_localToken.safeTransferFrom(msg.sender, address(this), amount); + + // Make sure this is tether compatible, as they have strange approval requirements + // Should be good since all approvals are always immediately used. + i_localToken.safeApprove(address(s_localLiquidityContainer), amount); + s_localLiquidityContainer.provideLiquidity(amount); + + emit LiquidityAddedToContainer(msg.sender, amount); + } + + /// @notice Removes liquidity from the system and sends it to the caller, so the owner. + /// @dev Only the owner can call this function. + function removeLiquidity(uint256 amount) external onlyFinance { + uint256 currentBalance = getLiquidity(); + if (currentBalance < amount) { + revert InsufficientLiquidity(amount, currentBalance, 0); + } + + s_localLiquidityContainer.withdrawLiquidity(amount); + i_localToken.safeTransfer(msg.sender, amount); + + emit LiquidityRemovedFromContainer(msg.sender, amount); + } + + /// @notice escape hatch to manually withdraw any ERC20 token from the LM contract + /// @param token The address of the token to withdraw + /// @param amount The amount of tokens to withdraw + /// @param destination The address to send the tokens to + function withdrawERC20(address token, uint256 amount, address destination) external onlyFinance { + IERC20(token).safeTransfer(destination, amount); + } + + /// @notice Transfers liquidity to another chain. + /// @dev This function is a public version of the internal _rebalanceLiquidity function. + /// to allow the owner to also initiate a rebalancing when needed. + function rebalanceLiquidity( + uint64 chainSelector, + uint256 amount, + uint256 nativeBridgeFee, + bytes calldata bridgeSpecificPayload + ) external onlyFinance { + _rebalanceLiquidity(chainSelector, amount, nativeBridgeFee, type(uint64).max, bridgeSpecificPayload); + } + + /// @notice Finalizes liquidity from another chain. + /// @dev This function is a public version of the internal _receiveLiquidity function. + /// to allow the owner to also initiate a finalization when needed. + function receiveLiquidity( + uint64 remoteChainSelector, + uint256 amount, + bool shouldWrapNative, + bytes calldata bridgeSpecificPayload + ) external onlyFinance { + _receiveLiquidity(remoteChainSelector, amount, bridgeSpecificPayload, shouldWrapNative, type(uint64).max); + } + + /// @notice Transfers liquidity to another chain. + /// @dev Called by both the owner and the DON. + /// @param chainSelector The chain selector of the chain to transfer liquidity to. + /// @param tokenAmount The amount of tokens to transfer. + /// @param nativeBridgeFee The fee to pay to the bridge. + /// @param ocrSeqNum The OCR sequence number of the report. + /// @param bridgeSpecificPayload The bridge specific data to pass to the bridge adapter. + function _rebalanceLiquidity( + uint64 chainSelector, + uint256 tokenAmount, + uint256 nativeBridgeFee, + uint64 ocrSeqNum, + bytes memory bridgeSpecificPayload + ) internal { + uint256 currentBalance = getLiquidity(); + uint256 minBalance = s_minimumLiquidity; + if (currentBalance < minBalance || currentBalance - minBalance < tokenAmount) { + revert InsufficientLiquidity(tokenAmount, currentBalance, minBalance); + } + + CrossChainRebalancer memory remoteLiqManager = s_crossChainRebalancer[chainSelector]; + + if (!remoteLiqManager.enabled) { + revert InvalidRemoteChain(chainSelector); + } + + // XXX: Could be optimized by withdrawing once and then sending to all destinations + s_localLiquidityContainer.withdrawLiquidity(tokenAmount); + i_localToken.safeApprove(address(remoteLiqManager.localBridge), tokenAmount); + + bytes memory bridgeReturnData = remoteLiqManager.localBridge.sendERC20{value: nativeBridgeFee}( + address(i_localToken), + remoteLiqManager.remoteToken, + remoteLiqManager.remoteRebalancer, + tokenAmount, + bridgeSpecificPayload + ); + + emit LiquidityTransferred( + ocrSeqNum, + i_localChainSelector, + chainSelector, + remoteLiqManager.remoteRebalancer, + tokenAmount, + bridgeSpecificPayload, + bridgeReturnData + ); + } + + /// @notice Receives liquidity from another chain. + /// @dev Called by both the owner and the DON. + /// @param remoteChainSelector The chain selector of the chain to receive liquidity from. + /// @param amount The amount of tokens to receive. + /// @param bridgeSpecificPayload The bridge specific data to pass to the bridge adapter finalizeWithdrawERC20 call. + /// @param shouldWrapNative Whether the token should be wrapped before injecting it into the liquidity container. + /// This only applies to native tokens wrapper contracts, e.g WETH. + /// @param ocrSeqNum The OCR sequence number of the report. + function _receiveLiquidity( + uint64 remoteChainSelector, + uint256 amount, + bytes memory bridgeSpecificPayload, + bool shouldWrapNative, + uint64 ocrSeqNum + ) internal { + // check if the remote chain is supported + CrossChainRebalancer memory remoteRebalancer = s_crossChainRebalancer[remoteChainSelector]; + if (!remoteRebalancer.enabled) { + revert InvalidRemoteChain(remoteChainSelector); + } + + // finalize the withdrawal through the bridge adapter + try + remoteRebalancer.localBridge.finalizeWithdrawERC20( + remoteRebalancer.remoteRebalancer, // remoteSender: the remote rebalancer + address(this), // localReceiver: this contract + bridgeSpecificPayload + ) + returns (bool fundsAvailable) { + if (fundsAvailable) { + // finalization was successful and we can inject the liquidity into the container. + // approve and liquidity container should transferFrom. + _injectLiquidity(amount, ocrSeqNum, remoteChainSelector, bridgeSpecificPayload, shouldWrapNative); + } else { + // a finalization step was completed, but funds are not available. + // hence, we cannot inject any liquidity yet. + emit FinalizationStepCompleted(ocrSeqNum, remoteChainSelector, bridgeSpecificPayload); + } + + // return here on the happy path. + // sad path is when finalizeWithdrawERC20 reverts, which is handled after the catch block. + return; + } catch (bytes memory lowLevelData) { + // failed to finalize the withdrawal. + // this could mean that the withdrawal was already finalized + // or that the withdrawal failed. + // we assume the former and continue + emit FinalizationFailed(ocrSeqNum, remoteChainSelector, bridgeSpecificPayload, lowLevelData); + } + + // if we reach this point, the finalization failed. + // since we don't have enough information to know why it failed, + // we assume that it failed because the withdrawal was already finalized, + // and that the funds are available. + _injectLiquidity(amount, ocrSeqNum, remoteChainSelector, bridgeSpecificPayload, shouldWrapNative); + } + + /// @notice Injects liquidity into the local liquidity container. + /// @param amount The amount of tokens to inject. + /// @param ocrSeqNum The OCR sequence number of the report. + /// @param remoteChainSelector The chain selector of the remote chain. + /// @param bridgeSpecificPayload The bridge specific data passed to the bridge adapter finalizeWithdrawERC20 call. + /// @param shouldWrapNative Whether the token should be wrapped before injecting it into the liquidity container. + function _injectLiquidity( + uint256 amount, + uint64 ocrSeqNum, + uint64 remoteChainSelector, + bytes memory bridgeSpecificPayload, + bool shouldWrapNative + ) private { + // We trust the DON or the owner (the only two actors who can end up calling this function) + // to correctly set the shouldWrapNative flag. + // Some bridges only bridge native and not wrapped native. + // In such a case we need to re-wrap the native in order to inject it into the liquidity container. + // TODO: escape hatch in case of bug? + if (shouldWrapNative) { + IWrappedNative(address(i_localToken)).deposit{value: amount}(); + } + + i_localToken.safeIncreaseAllowance(address(s_localLiquidityContainer), amount); + s_localLiquidityContainer.provideLiquidity(amount); + + emit LiquidityTransferred( + ocrSeqNum, + remoteChainSelector, + i_localChainSelector, + address(this), + amount, + bridgeSpecificPayload, + bytes("") // no bridge return data when receiving + ); + } + + /// @notice Process the OCR report. + /// @dev Called by OCR3Base's transmit() function. + function _report(bytes calldata report, uint64 ocrSeqNum) internal override { + ILiquidityManager.LiquidityInstructions memory instructions = abi.decode( + report, + (ILiquidityManager.LiquidityInstructions) + ); + + uint256 sendInstructions = instructions.sendLiquidityParams.length; + uint256 receiveInstructions = instructions.receiveLiquidityParams.length; + + // There should always be instructions to send or receive, if not, the report is invalid + // and we revert to save the gas of the signature validation of OCR. + if (sendInstructions == 0 && receiveInstructions == 0) { + revert EmptyReport(); + } + + for (uint256 i = 0; i < sendInstructions; ++i) { + _rebalanceLiquidity( + instructions.sendLiquidityParams[i].remoteChainSelector, + instructions.sendLiquidityParams[i].amount, + instructions.sendLiquidityParams[i].nativeBridgeFee, + ocrSeqNum, + instructions.sendLiquidityParams[i].bridgeData + ); + } + + for (uint256 i = 0; i < receiveInstructions; ++i) { + _receiveLiquidity( + instructions.receiveLiquidityParams[i].remoteChainSelector, + instructions.receiveLiquidityParams[i].amount, + instructions.receiveLiquidityParams[i].bridgeData, + instructions.receiveLiquidityParams[i].shouldWrapNative, + ocrSeqNum + ); + } + } + + // ================================================================ + // │ Config │ + // ================================================================ + + function getSupportedDestChains() external view returns (uint64[] memory) { + return s_supportedDestChains; + } + + /// @notice Gets the cross chain liquidity manager + function getCrossChainRebalancer(uint64 chainSelector) external view returns (CrossChainRebalancer memory) { + return s_crossChainRebalancer[chainSelector]; + } + + /// @notice Gets all cross chain liquidity managers + /// @dev We don't care too much about gas since this function is intended for offchain usage. + function getAllCrossChainRebalancers() external view returns (CrossChainRebalancerArgs[] memory) { + uint256 numChains = s_supportedDestChains.length; + CrossChainRebalancerArgs[] memory managers = new CrossChainRebalancerArgs[](numChains); + for (uint256 i = 0; i < numChains; ++i) { + uint64 chainSelector = s_supportedDestChains[i]; + CrossChainRebalancer memory currentManager = s_crossChainRebalancer[chainSelector]; + managers[i] = CrossChainRebalancerArgs({ + remoteRebalancer: currentManager.remoteRebalancer, + localBridge: currentManager.localBridge, + remoteToken: currentManager.remoteToken, + remoteChainSelector: chainSelector, + enabled: currentManager.enabled + }); + } + + return managers; + } + + /// @notice Sets a list of cross chain liquidity managers. + /// @dev Will update the list of supported dest chains if the chain is new. + function setCrossChainRebalancers(CrossChainRebalancerArgs[] calldata crossChainRebalancers) external onlyOwner { + for (uint256 i = 0; i < crossChainRebalancers.length; ++i) { + _setCrossChainRebalancer(crossChainRebalancers[i]); + } + } + + function setCrossChainRebalancer(CrossChainRebalancerArgs calldata crossChainLiqManager) external onlyOwner { + _setCrossChainRebalancer(crossChainLiqManager); + } + + /// @notice Sets a single cross chain liquidity manager. + /// @dev Will update the list of supported dest chains if the chain is new. + function _setCrossChainRebalancer(CrossChainRebalancerArgs calldata crossChainLiqManager) internal { + if (crossChainLiqManager.remoteChainSelector == 0) { + revert ZeroChainSelector(); + } + + if ( + crossChainLiqManager.remoteRebalancer == address(0) || + address(crossChainLiqManager.localBridge) == address(0) || + crossChainLiqManager.remoteToken == address(0) + ) { + revert ZeroAddress(); + } + + // If the destination chain is new, add it to the list of supported chains + if (s_crossChainRebalancer[crossChainLiqManager.remoteChainSelector].remoteToken == address(0)) { + s_supportedDestChains.push(crossChainLiqManager.remoteChainSelector); + } + + s_crossChainRebalancer[crossChainLiqManager.remoteChainSelector] = CrossChainRebalancer({ + remoteRebalancer: crossChainLiqManager.remoteRebalancer, + localBridge: crossChainLiqManager.localBridge, + remoteToken: crossChainLiqManager.remoteToken, + enabled: crossChainLiqManager.enabled + }); + + emit CrossChainRebalancerSet( + crossChainLiqManager.remoteChainSelector, + crossChainLiqManager.localBridge, + crossChainLiqManager.remoteToken, + crossChainLiqManager.remoteRebalancer, + crossChainLiqManager.enabled + ); + } + + /// @notice Gets the local liquidity container. + function getLocalLiquidityContainer() external view returns (address) { + return address(s_localLiquidityContainer); + } + + /// @notice Sets the local liquidity container. + /// @dev Only the owner can call this function. + function setLocalLiquidityContainer(ILiquidityContainer localLiquidityContainer) external onlyOwner { + if (address(localLiquidityContainer) == address(0)) { + revert ZeroAddress(); + } + s_localLiquidityContainer = localLiquidityContainer; + + emit LiquidityContainerSet(address(localLiquidityContainer)); + } + + /// @notice Gets the target tokens balance. + function getMinimumLiquidity() external view returns (uint256) { + return s_minimumLiquidity; + } + + /// @notice Sets the target tokens balance. + /// @dev Only the owner can call this function. + function setMinimumLiquidity(uint256 minimumLiquidity) external onlyOwner { + uint256 oldLiquidity = s_minimumLiquidity; + s_minimumLiquidity = minimumLiquidity; + emit MinimumLiquiditySet(oldLiquidity, s_minimumLiquidity); + } + + /// @notice Gets the CLL finance team multisig address + function getFinanceRole() external view returns (address) { + return s_finance; + } + + /// @notice Sets the finance team multisig address + /// @dev Only the owner can call this function. + function setFinanceRole(address finance) external onlyOwner { + s_finance = finance; + emit FinanceRoleSet(finance); + } + + modifier onlyFinance() { + if (msg.sender != s_finance) revert OnlyFinanceRole(); + _; + } +} diff --git a/contracts/src/v0.8/liquiditymanager/bridge-adapters/ArbitrumL1BridgeAdapter.sol b/contracts/src/v0.8/liquiditymanager/bridge-adapters/ArbitrumL1BridgeAdapter.sol new file mode 100644 index 0000000000..9ab7376c27 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/bridge-adapters/ArbitrumL1BridgeAdapter.sol @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IBridgeAdapter} from "../interfaces/IBridge.sol"; + +import {IL1GatewayRouter} from "@arbitrum/token-bridge-contracts/contracts/tokenbridge/ethereum/gateway/IL1GatewayRouter.sol"; +import {IGatewayRouter} from "@arbitrum/token-bridge-contracts/contracts/tokenbridge/libraries/gateway/IGatewayRouter.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +interface IOutbox { + /** + * @notice Executes a messages in an Outbox entry. + * @dev Reverts if dispute period hasn't expired, since the outbox entry + * is only created once the rollup confirms the respective assertion. + * @dev it is not possible to execute any L2-to-L1 transaction which contains data + * to a contract address without any code (as enforced by the Bridge contract). + * @param proof Merkle proof of message inclusion in send root + * @param index Merkle path to message + * @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1) + * @param to destination address for L1 contract call + * @param l2Block l2 block number at which sendTxToL1 call was made + * @param l1Block l1 block number at which sendTxToL1 call was made + * @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made + * @param value wei in L1 message + * @param data abi-encoded L1 message data + */ + function executeTransaction( + bytes32[] calldata proof, + uint256 index, + address l2Sender, + address to, + uint256 l2Block, + uint256 l1Block, + uint256 l2Timestamp, + uint256 value, + bytes calldata data + ) external; +} + +/// @notice Arbitrum L1 Bridge adapter +/// @dev Auto unwraps and re-wraps wrapped eth in the bridge. +contract ArbitrumL1BridgeAdapter is IBridgeAdapter { + using SafeERC20 for IERC20; + + IL1GatewayRouter internal immutable i_l1GatewayRouter; + IOutbox internal immutable i_l1Outbox; + + error NoGatewayForToken(address token); + error Unimplemented(); + + constructor(IL1GatewayRouter l1GatewayRouter, IOutbox l1Outbox) { + if (address(l1GatewayRouter) == address(0) || address(l1Outbox) == address(0)) { + revert BridgeAddressCannotBeZero(); + } + i_l1GatewayRouter = l1GatewayRouter; + i_l1Outbox = l1Outbox; + } + + /// @dev these are parameters provided by the caller of the sendERC20 function + /// and must be determined offchain. + struct SendERC20Params { + uint256 gasLimit; + uint256 maxSubmissionCost; + uint256 maxFeePerGas; + } + + /// @inheritdoc IBridgeAdapter + function sendERC20( + address localToken, + address /* remoteToken */, + address recipient, + uint256 amount, + bytes calldata bridgeSpecificPayload + ) external payable override returns (bytes memory) { + // receive the token transfer from the msg.sender + IERC20(localToken).safeTransferFrom(msg.sender, address(this), amount); + + // Note: the gateway router could return 0x0 for the gateway address + // if that token is not yet registered + address gateway = IGatewayRouter(address(i_l1GatewayRouter)).getGateway(localToken); + if (gateway == address(0)) { + revert NoGatewayForToken(localToken); + } + + // approve the gateway to transfer the token amount sent to the adapter + IERC20(localToken).safeApprove(gateway, amount); + + SendERC20Params memory params = abi.decode(bridgeSpecificPayload, (SendERC20Params)); + + uint256 expectedMsgValue = (params.gasLimit * params.maxFeePerGas) + params.maxSubmissionCost; + if (msg.value < expectedMsgValue) { + revert MsgValueDoesNotMatchAmount(msg.value, expectedMsgValue); + } + + // The router will route the call to the gateway that we approved + // above. The gateway will then transfer the tokens to the L2. + // outboundTransferCustomRefund will return the abi encoded inbox sequence number + // which is 256 bits, so we can cap the return data to 256 bits. + bytes memory inboxSequenceNumber = i_l1GatewayRouter.outboundTransferCustomRefund{value: msg.value}( + localToken, + recipient, + recipient, + amount, + params.gasLimit, + params.maxFeePerGas, + abi.encode(params.maxSubmissionCost, bytes("")) + ); + + return inboxSequenceNumber; + } + + /// @dev This function is so that we can easily abi-encode the arbitrum-specific payload for the sendERC20 function. + function exposeSendERC20Params(SendERC20Params memory params) public pure {} + + /// @dev fees have to be determined offchain for arbitrum, therefore revert here to discourage usage. + function getBridgeFeeInNative() public pure override returns (uint256) { + revert Unimplemented(); + } + + /// @param proof Merkle proof of message inclusion in send root + /// @param index Merkle path to message + /// @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1) + /// @param to destination address for L1 contract call + /// @param l2Block l2 block number at which sendTxToL1 call was made + /// @param l1Block l1 block number at which sendTxToL1 call was made + /// @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made + /// @param value wei in L1 message + /// @param data abi-encoded L1 message data + struct ArbitrumFinalizationPayload { + bytes32[] proof; + uint256 index; + address l2Sender; + address to; + uint256 l2Block; + uint256 l1Block; + uint256 l2Timestamp; + uint256 value; + bytes data; + } + + /// @dev This function is so that we can easily abi-encode the arbitrum-specific payload for the finalizeWithdrawERC20 function. + function exposeArbitrumFinalizationPayload(ArbitrumFinalizationPayload memory payload) public pure {} + + /// @notice Finalize an L2 -> L1 transfer. + /// Arbitrum finalizations are single-step, so we always return true. + /// Calls to this function will revert in two cases, 1) if the finalization payload is wrong, + /// i.e incorrect merkle proof, or index and 2) if the withdrawal was already finalized. + /// @return true iff the finalization does not revert. + function finalizeWithdrawERC20( + address /* remoteSender */, + address /* localReceiver */, + bytes calldata arbitrumFinalizationPayload + ) external override returns (bool) { + ArbitrumFinalizationPayload memory payload = abi.decode(arbitrumFinalizationPayload, (ArbitrumFinalizationPayload)); + i_l1Outbox.executeTransaction( + payload.proof, + payload.index, + payload.l2Sender, + payload.to, + payload.l2Block, + payload.l1Block, + payload.l2Timestamp, + payload.value, + payload.data + ); + return true; + } + + /// @notice Convenience function to get the L2 token address from the L1 token address. + /// @return The L2 token address for the given L1 token address. + function getL2Token(address l1Token) external view returns (address) { + return i_l1GatewayRouter.calculateL2TokenAddress(l1Token); + } +} diff --git a/contracts/src/v0.8/liquiditymanager/bridge-adapters/ArbitrumL2BridgeAdapter.sol b/contracts/src/v0.8/liquiditymanager/bridge-adapters/ArbitrumL2BridgeAdapter.sol new file mode 100644 index 0000000000..6ee97163f6 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/bridge-adapters/ArbitrumL2BridgeAdapter.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IBridgeAdapter} from "../interfaces/IBridge.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +interface IArbSys { + function withdrawEth(address destination) external payable returns (uint256); +} + +interface IL2GatewayRouter { + function outboundTransfer( + address l1Token, + address to, + uint256 amount, + bytes calldata data + ) external payable returns (bytes memory); +} + +/// @notice Arbitrum L2 Bridge adapter +/// @dev Auto unwraps and re-wraps wrapped eth in the bridge. +contract ArbitrumL2BridgeAdapter is IBridgeAdapter { + using SafeERC20 for IERC20; + + IL2GatewayRouter internal immutable i_l2GatewayRouter; + // address internal immutable i_l1ERC20Gateway; + IArbSys internal constant ARB_SYS = IArbSys(address(0x64)); + + constructor(IL2GatewayRouter l2GatewayRouter) { + if (address(l2GatewayRouter) == address(0)) { + revert BridgeAddressCannotBeZero(); + } + i_l2GatewayRouter = l2GatewayRouter; + } + + /// @inheritdoc IBridgeAdapter + function sendERC20( + address localToken, + address remoteToken, + address recipient, + uint256 amount, + bytes calldata /* bridgeSpecificPayload */ + ) external payable override returns (bytes memory) { + if (msg.value != 0) { + revert MsgShouldNotContainValue(msg.value); + } + + IERC20(localToken).safeTransferFrom(msg.sender, address(this), amount); + + // the data returned is the unique id of the L2 to L1 transfer + // see https://github.com/OffchainLabs/token-bridge-contracts/blob/bf9ad3d7f25c0eaf0a5f89eec7a0a370833cea16/contracts/tokenbridge/arbitrum/gateway/L2ArbitrumGateway.sol#L169-L191 + // No approval needed, the bridge will burn the tokens from this contract. + bytes memory l2ToL1TxId = i_l2GatewayRouter.outboundTransfer(remoteToken, recipient, amount, bytes("")); + + return l2ToL1TxId; + } + + /// @notice No-op since L1 -> L2 transfers do not need finalization. + /// @return true always. + function finalizeWithdrawERC20( + address /* remoteSender */, + address /* localReceiver */, + bytes calldata /* bridgeSpecificPayload */ + ) external pure override returns (bool) { + return true; + } + + /// @notice There are no fees to bridge back to L1 + function getBridgeFeeInNative() external pure returns (uint256) { + return 0; + } + + function depositNativeToL1(address recipient) external payable { + ARB_SYS.withdrawEth{value: msg.value}(recipient); + } +} diff --git a/contracts/src/v0.8/liquiditymanager/bridge-adapters/OptimismL1BridgeAdapter.sol b/contracts/src/v0.8/liquiditymanager/bridge-adapters/OptimismL1BridgeAdapter.sol new file mode 100644 index 0000000000..6734c74bd8 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/bridge-adapters/OptimismL1BridgeAdapter.sol @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IBridgeAdapter} from "../interfaces/IBridge.sol"; +import {IWrappedNative} from "../../ccip/interfaces/IWrappedNative.sol"; +import {Types} from "../interfaces/optimism/Types.sol"; +import {IOptimismPortal} from "../interfaces/optimism/IOptimismPortal.sol"; + +import {IL1StandardBridge} from "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +/// @notice OptimismL1BridgeAdapter implements IBridgeAdapter for the Optimism L1<=>L2 bridge. +/// @dev L1 -> L2 deposits are done via the depositERC20To and depositETHTo functions on the L1StandardBridge. +/// The amount of gas provided for the transaction must be buffered - the Optimism SDK recommends a 20% buffer. +/// The Optimism Bridge implements 2-step withdrawals from L2 to L1. Once a withdrawal transaction is included +/// in the L2 chain, it must be proven on L1 before it can be finalized. There is a buffer between the transaction +/// being posted on L2 before it can be proven, and similarly, there is a buffer in the time it takes to prove +/// the transaction before it can be finalized. +/// See https://blog.oplabs.co/two-step-withdrawals/ for more details on this mechanism. +/// @dev We have to unwrap WETH into ether before depositing it to L2. Therefore this bridge adapter bridges +/// WETH to ether. The receiver on L2 must wrap the ether back into WETH. +contract OptimismL1BridgeAdapter is IBridgeAdapter { + using SafeERC20 for IERC20; + + /// @notice used when the action in the payload is invalid. + error InvalidFinalizationAction(); + + /// @notice Payload for proving a withdrawal from L2 on L1 via finalizeWithdrawERC20. + /// @param withdrawalTransaction The withdrawal transaction, see its docstring for more details. + /// @param l2OutputIndex The index of the output in the L2 block, or the dispute game index post fault proof upgrade. + /// @param outputRootProof The inclusion proof of the L2ToL1MessagePasser contract's storage root. + /// @param withdrawalProof The Merkle proof of the withdrawal key presence in the L2ToL1MessagePasser contract's state trie. + struct OptimismProveWithdrawalPayload { + Types.WithdrawalTransaction withdrawalTransaction; + uint256 l2OutputIndex; + Types.OutputRootProof outputRootProof; + bytes[] withdrawalProof; + } + + /// @notice Payload for finalizing a withdrawal from L2 on L1. + /// Note that the withdrawal must be proven first before it can be finalized. + /// @param withdrawalTransaction The withdrawal transaction, see its docstring for more details. + struct OptimismFinalizationPayload { + Types.WithdrawalTransaction withdrawalTransaction; + } + + /// @notice The action to take when finalizing a withdrawal. + /// Optimism implements two-step withdrawals, so we need to specify the action to take + /// each time the finalizeWithdrawERC20 function is called. + enum FinalizationAction { + ProveWithdrawal, + FinalizeWithdrawal + } + + /// @notice Payload for interacting with the finalizeWithdrawERC20 function. + /// Since Optimism has 2-step withdrawals, we cannot finalize and get the funds on L1 in the same transaction. + /// @param action The action to take; either ProveWithdrawal or FinalizeWithdrawal. + /// @param data The payload for the action. If ProveWithdrawal, it must be an abi-encoded OptimismProveWithdrawalPayload. + /// If FinalizeWithdrawal, it must be an abi-encoded OptimismFinalizationPayload. + struct FinalizeWithdrawERC20Payload { + FinalizationAction action; + bytes data; + } + + /// @dev Reference to the L1StandardBridge contract. Deposits to L2 go through this contract. + IL1StandardBridge internal immutable i_L1Bridge; + + /// @dev Reference to the WrappedNative contract. Optimism bridges ether directly rather than WETH, + /// so we need to unwrap WETH into ether before depositing it to L2. + IWrappedNative internal immutable i_wrappedNative; + + /// @dev Reference to the OptimismPortal contract, which is used to prove and finalize withdrawals. + IOptimismPortal internal immutable i_optimismPortal; + + /// @dev Nonce to use for L2 deposits to allow for better tracking offchain. + uint64 private s_nonce = 0; + + constructor(IL1StandardBridge l1Bridge, IWrappedNative wrappedNative, IOptimismPortal optimismPortal) { + if ( + address(l1Bridge) == address(0) || address(wrappedNative) == address(0) || address(optimismPortal) == address(0) + ) { + revert BridgeAddressCannotBeZero(); + } + i_L1Bridge = l1Bridge; + i_wrappedNative = wrappedNative; + i_optimismPortal = optimismPortal; + } + + /// @notice The WETH withdraw requires this be present otherwise withdraws will fail. + receive() external payable {} + + /// @inheritdoc IBridgeAdapter + function sendERC20( + address localToken, + address remoteToken, + address recipient, + uint256 amount, + bytes calldata /* bridgeSpecificPayload */ + ) external payable override returns (bytes memory) { + IERC20(localToken).safeTransferFrom(msg.sender, address(this), amount); + + if (msg.value != 0) { + revert MsgShouldNotContainValue(msg.value); + } + + // Extra data for the L2 deposit. + // We encode the nonce in the extra data so that we can track the L2 deposit offchain. + bytes memory extraData = abi.encode(s_nonce++); + + // If the token is the wrapped native, we unwrap it and deposit native + if (localToken == address(i_wrappedNative)) { + i_wrappedNative.withdraw(amount); + i_L1Bridge.depositETHTo{value: amount}(recipient, 0, extraData); + return extraData; + } + + // Token is a normal ERC20. + IERC20(localToken).safeApprove(address(i_L1Bridge), amount); + i_L1Bridge.depositERC20To(localToken, remoteToken, recipient, amount, 0, extraData); + + return extraData; + } + + /// @notice Bridging to Optimism is paid for with gas + /// @dev Since the gas amount charged is dynamic, the gas burn can change from block to block. + /// You should always add a buffer of at least 20% to the gas limit for your L1 to L2 transaction + /// to avoid running out of gas. + function getBridgeFeeInNative() public pure returns (uint256) { + return 0; + } + + /// @notice Prove or finalize an ERC20 withdrawal from L2. + /// The action to take is specified in the payload. See the docstring of FinalizeWithdrawERC20Payload for more details. + /// @param data The payload for the action. This is an abi.encode'd FinalizeWithdrawERC20Payload with the appropriate data. + /// @return true iff finalization is successful, and false for proving a withdrawal. If either of these fail, + /// the call to this function will revert. + function finalizeWithdrawERC20( + address /* remoteSender */, + address /* localReceiver */, + bytes calldata data + ) external override returns (bool) { + // decode the data into FinalizeWithdrawERC20Payload first and extract the action. + FinalizeWithdrawERC20Payload memory payload = abi.decode(data, (FinalizeWithdrawERC20Payload)); + if (payload.action == FinalizationAction.ProveWithdrawal) { + // The action being ProveWithdrawal indicates that this is a withdrawal proof payload. + // Decode the data into OptimismProveWithdrawalPayload and call the proveWithdrawal function. + OptimismProveWithdrawalPayload memory provePayload = abi.decode(payload.data, (OptimismProveWithdrawalPayload)); + _proveWithdrawal(provePayload); + return false; + } else if (payload.action == FinalizationAction.FinalizeWithdrawal) { + // decode the data into OptimismFinalizationPayload and call the finalizeWithdrawal function. + OptimismFinalizationPayload memory finalizePayload = abi.decode(payload.data, (OptimismFinalizationPayload)); + // NOTE: finalizing ether withdrawals will currently send ether to the receiver address as indicated by the + // withdrawal tx. However, this is problematic because we need to re-wrap it into WETH. + // However, we can't do that from within this adapter because it doesn't actually have the ether. + // So its up to the caller to rectify this by re-wrapping the ether. + _finalizeWithdrawal(finalizePayload); + return true; + } else { + revert InvalidFinalizationAction(); + } + } + + function _proveWithdrawal(OptimismProveWithdrawalPayload memory payload) internal { + // will revert if the proof is invalid or the output index is not yet included on L1. + i_optimismPortal.proveWithdrawalTransaction( + payload.withdrawalTransaction, + payload.l2OutputIndex, + payload.outputRootProof, + payload.withdrawalProof + ); + } + + function _finalizeWithdrawal(OptimismFinalizationPayload memory payload) internal { + i_optimismPortal.finalizeWithdrawalTransaction(payload.withdrawalTransaction); + } + + /// @notice returns the address of the WETH token used by this adapter. + /// @return the address of the WETH token used by this adapter. + function getWrappedNative() external view returns (address) { + return address(i_wrappedNative); + } + + /// @notice returns the address of the Optimism portal contract. + /// @return the address of the Optimism portal contract. + function getOptimismPortal() external view returns (address) { + return address(i_optimismPortal); + } + + /// @notice returns the address of the Optimism L1StandardBridge bridge contract. + /// @return the address of the Optimism L1StandardBridge bridge contract. + function getL1Bridge() external view returns (address) { + return address(i_L1Bridge); + } +} diff --git a/contracts/src/v0.8/liquiditymanager/bridge-adapters/OptimismL2BridgeAdapter.sol b/contracts/src/v0.8/liquiditymanager/bridge-adapters/OptimismL2BridgeAdapter.sol new file mode 100644 index 0000000000..fd1218f670 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/bridge-adapters/OptimismL2BridgeAdapter.sol @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IBridgeAdapter} from "../interfaces/IBridge.sol"; +import {IWrappedNative} from "../../ccip/interfaces/IWrappedNative.sol"; + +import {Lib_PredeployAddresses} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +/// @dev copy/pasted from https://github.com/ethereum-optimism/optimism/blob/f707883038d527cbf1e9f8ea513fe33255deadbc/packages/contracts-bedrock/src/L2/L2StandardBridge.sol#L114-L122. +/// We can't import it because of hard pin solidity version in the pragma (0.8.15). +interface IL2StandardBridge { + /// @custom:legacy + /// @notice Initiates a withdrawal from L2 to L1 to a target account on L1. + /// Note that if ETH is sent to a contract on L1 and the call fails, then that ETH will + /// be locked in the L1StandardBridge. ETH may be recoverable if the call can be + /// successfully replayed by increasing the amount of gas supplied to the call. If the + /// call will fail for any amount of gas, then the ETH will be locked permanently. + /// This function only works with OptimismMintableERC20 tokens or ether. Use the + /// `bridgeERC20To` function to bridge native L2 tokens to L1. + /// @param _l2Token Address of the L2 token to withdraw. + /// @param _to Recipient account on L1. + /// @param _amount Amount of the L2 token to withdraw. + /// @param _minGasLimit Minimum gas limit to use for the transaction. + /// @param _extraData Extra data attached to the withdrawal. + function withdrawTo( + address _l2Token, + address _to, + uint256 _amount, + uint32 _minGasLimit, + bytes calldata _extraData + ) external payable; +} + +/// @notice OptimismL2BridgeAdapter implements IBridgeAdapter for the Optimism L2<=>L1 bridge. +/// @dev We have to unwrap WETH into ether before withdrawing it to L1. Therefore this bridge adapter bridges +/// WETH to ether. The receiver on L1 must wrap the ether back into WETH. +contract OptimismL2BridgeAdapter is IBridgeAdapter { + using SafeERC20 for IERC20; + + IL2StandardBridge internal immutable i_L2Bridge = IL2StandardBridge(Lib_PredeployAddresses.L2_STANDARD_BRIDGE); + IWrappedNative internal immutable i_wrappedNative; + + // Nonce to use for L1 withdrawals to allow for better tracking offchain. + uint64 private s_nonce = 0; + + constructor(IWrappedNative wrappedNative) { + // Wrapped native can be address zero, this means that auto-wrapping is disabled. + i_wrappedNative = wrappedNative; + } + + /// @notice The WETH withdraw requires this be present otherwise withdraws will fail. + receive() external payable {} + + /// @inheritdoc IBridgeAdapter + function sendERC20( + address localToken, + address /* remoteToken */, + address recipient, + uint256 amount, + bytes calldata /* bridgeSpecificPayload */ + ) external payable override returns (bytes memory) { + if (msg.value != 0) { + revert MsgShouldNotContainValue(msg.value); + } + + IERC20(localToken).safeTransferFrom(msg.sender, address(this), amount); + + // Extra data for the L2 withdraw. + // We encode the nonce in the extra data so that we can track the L2 withdraw offchain. + bytes memory extraData = abi.encode(s_nonce++); + + // If the token is the wrapped native, we unwrap it and withdraw native + if (localToken == address(i_wrappedNative)) { + i_wrappedNative.withdraw(amount); + // XXX: Lib_PredeployAddresses.OVM_ETH is actually 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000. + // This code path still works because the L2 bridge is hardcoded to handle this specific address. + // The better approach might be to use the bridgeEthTo function, which is on the StandardBridge + // abstract contract, inherited by both L1StandardBridge and L2StandardBridge. + // This is also marked as legacy, so it might mean that this will be deprecated soon. + i_L2Bridge.withdrawTo{value: amount}(Lib_PredeployAddresses.OVM_ETH, recipient, amount, 0, extraData); + return extraData; + } + + // Token is normal ERC20 + IERC20(localToken).approve(address(i_L2Bridge), amount); + i_L2Bridge.withdrawTo(localToken, recipient, amount, 0, extraData); + return extraData; + } + + /// @notice No-op since L1 -> L2 transfers do not need finalization. + /// @return true always. + function finalizeWithdrawERC20( + address /* remoteSender */, + address /* localReceiver */, + bytes calldata /* bridgeSpecificPayload */ + ) external pure override returns (bool) { + return true; + } + + /// @notice There are no fees to bridge back to L1 + function getBridgeFeeInNative() external pure returns (uint256) { + return 0; + } + + /// @notice returns the address of the WETH token used by this adapter. + /// @return the address of the WETH token used by this adapter. + function getWrappedNative() external view returns (address) { + return address(i_wrappedNative); + } + + /// @notice returns the address of the L2 bridge used by this adapter. + /// @return the address of the L2 bridge used by this adapter. + function getL2Bridge() external view returns (address) { + return address(i_L2Bridge); + } +} diff --git a/contracts/src/v0.8/liquiditymanager/encoders/OptimismL1BridgeAdapterEncoder.sol b/contracts/src/v0.8/liquiditymanager/encoders/OptimismL1BridgeAdapterEncoder.sol new file mode 100644 index 0000000000..888b48732d --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/encoders/OptimismL1BridgeAdapterEncoder.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {OptimismL1BridgeAdapter} from "../bridge-adapters/OptimismL1BridgeAdapter.sol"; + +/// @dev to generate abi's for the OptimismL1BridgeAdapter's various payload types. +/// @dev for usage examples see core/scripts/ccip/liquiditymanager/opstack/prove_withdrawal.go +/// @dev or core/scripts/ccip/liquiditymanager/opstack/finalize.go. +abstract contract OptimismL1BridgeAdapterEncoder { + function encodeFinalizeWithdrawalERC20Payload( + OptimismL1BridgeAdapter.FinalizeWithdrawERC20Payload memory payload + ) public pure {} + + function encodeOptimismProveWithdrawalPayload( + OptimismL1BridgeAdapter.OptimismProveWithdrawalPayload memory payload + ) public pure {} + + function encodeOptimismFinalizationPayload( + OptimismL1BridgeAdapter.OptimismFinalizationPayload memory payload + ) public pure {} +} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/IBridge.sol b/contracts/src/v0.8/liquiditymanager/interfaces/IBridge.sol new file mode 100644 index 0000000000..83e64edce4 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/IBridge.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +/// @dev IBridgeAdapter provides a common interface to interact with the native bridge. +interface IBridgeAdapter { + error BridgeAddressCannotBeZero(); + error MsgValueDoesNotMatchAmount(uint256 msgValue, uint256 amount); + error InsufficientEthValue(uint256 wanted, uint256 got); + error MsgShouldNotContainValue(uint256 value); + + /// @notice Send the specified amount of the local token cross-chain to the remote chain. + /// The tokens on the remote chain will then be sourced from the remoteToken address. + /// The amount to be sent must be approved by the caller beforehand on the localToken contract. + /// The caller must provide the bridging fee in native currency, i.e msg.value. + /// @param localToken The address of the local ERC-20 token. + /// @param remoteToken The address of the remote ERC-20 token. + /// @param recipient The address of the recipient on the remote chain. + /// @param amount The amount of the local token to send. + /// @param bridgeSpecificPayload The payload of the cross-chain transfer. Bridge-specific. + function sendERC20( + address localToken, + address remoteToken, + address recipient, + uint256 amount, + bytes calldata bridgeSpecificPayload + ) external payable returns (bytes memory); + + /// @notice Get the bridging fee in native currency. This fee must be provided upon sending tokens via + /// the sendERC20 function. + /// @return The bridging fee in native currency. + function getBridgeFeeInNative() external view returns (uint256); + + /// @notice Finalize the withdrawal of a cross-chain transfer. + /// Not all implementations will finalize a transfer in a single call to this function. + /// Optimism, for example, requires a two-step process to finalize a transfer. The first + /// step requires proving the withdrawal that occurred on L2 on L1. The second step is then + /// the finalization, whereby funds become available to the recipient. So, in that particular + /// scenario, `false` is returned from `finalizeWithdrawERC20` when the first step is completed, + /// and `true` is returned when the second step is completed. + /// @param remoteSender The address of the sender on the remote chain. + /// @param localReceiver The address of the receiver on the local chain. + /// @param bridgeSpecificPayload The payload of the cross-chain transfer, bridge-specific, i.e a proof of some kind. + /// @return true iff the funds are available, false otherwise. + function finalizeWithdrawERC20( + address remoteSender, + address localReceiver, + bytes calldata bridgeSpecificPayload + ) external returns (bool); +} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/ILiquidityContainer.sol b/contracts/src/v0.8/liquiditymanager/interfaces/ILiquidityContainer.sol new file mode 100644 index 0000000000..062325d953 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/ILiquidityContainer.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +/// @notice Interface for a liquidity container, this can be a CCIP token pool. +interface ILiquidityContainer { + event LiquidityAdded(address indexed provider, uint256 indexed amount); + event LiquidityRemoved(address indexed provider, uint256 indexed amount); + + /// @notice Provide additional liquidity to the container. + /// @dev Should emit LiquidityAdded + function provideLiquidity(uint256 amount) external; + + /// @notice Withdraws liquidity from the container to the msg sender + /// @dev Should emit LiquidityRemoved + function withdrawLiquidity(uint256 amount) external; +} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/ILiquidityManager.sol b/contracts/src/v0.8/liquiditymanager/interfaces/ILiquidityManager.sol new file mode 100644 index 0000000000..19fd1014a4 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/ILiquidityManager.sol @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {IBridgeAdapter} from "./IBridge.sol"; + +interface ILiquidityManager { + /// @notice Parameters for sending liquidity to a remote chain. + /// @param amount The amount of tokens to be sent to the remote chain. + /// @param nativeBridgeFee The amount of native that should be sent by the liquiditymanager in the sendERC20 call. + /// Used to pay for the bridge fees. + /// @param remoteChainSelector The selector of the remote chain. + /// @param bridgeData The bridge data that should be passed to the sendERC20 call. + struct SendLiquidityParams { + uint256 amount; + uint256 nativeBridgeFee; + uint64 remoteChainSelector; + bytes bridgeData; + } + + /// @notice Parameters for receiving liquidity from a remote chain. + /// @param amount The amount of tokens to be received from the remote chain. + /// @param remoteChainSelector The selector of the remote chain. + /// @param bridgeData The bridge data that should be passed to the finalizeWithdrawERC20 call. + /// @param shouldWrapNative Whether the received native token should be wrapped into wrapped native. + /// This is needed for when the bridge being used doesn't bridge wrapped native but native directly. + struct ReceiveLiquidityParams { + uint256 amount; + uint64 remoteChainSelector; + bool shouldWrapNative; + bytes bridgeData; + } + + /// @notice Instructions for the rebalancer on what to do with the available liquidity. + /// @param sendLiquidityParams The parameters for sending liquidity to a remote chain. + /// @param receiveLiquidityParams The parameters for receiving liquidity from a remote chain. + struct LiquidityInstructions { + SendLiquidityParams[] sendLiquidityParams; + ReceiveLiquidityParams[] receiveLiquidityParams; + } + + /// @notice Parameters for adding a cross-chain rebalancer. + /// @param remoteRebalancer The address of the remote rebalancer. + /// @param localBridge The local bridge adapter address. + /// @param remoteToken The address of the remote token. + /// @param remoteChainSelector The selector of the remote chain. + /// @param enabled Whether the rebalancer is enabled. + struct CrossChainRebalancerArgs { + address remoteRebalancer; + IBridgeAdapter localBridge; + address remoteToken; + uint64 remoteChainSelector; + bool enabled; + } + + /// @notice Returns the current liquidity in the liquidity container. + /// @return currentLiquidity The current liquidity in the liquidity container. + function getLiquidity() external view returns (uint256 currentLiquidity); + + /// @notice Returns all the cross-chain rebalancers. + /// @return All the cross-chain rebalancers. + function getAllCrossChainRebalancers() external view returns (CrossChainRebalancerArgs[] memory); +} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IAbstractArbitrumTokenGateway.sol b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IAbstractArbitrumTokenGateway.sol new file mode 100644 index 0000000000..c695729fa9 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IAbstractArbitrumTokenGateway.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {TokenGateway} from "@arbitrum/token-bridge-contracts/contracts/tokenbridge/libraries/gateway/TokenGateway.sol"; + +/// @dev to generate gethwrappers +abstract contract IAbstractArbitrumTokenGateway is TokenGateway {} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbRollupCore.sol b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbRollupCore.sol new file mode 100644 index 0000000000..a5d0e5e8e6 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbRollupCore.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {IRollupCore} from "@arbitrum/nitro-contracts/src/rollup/IRollupCore.sol"; + +/// @dev to generate gethwrappers +interface IArbRollupCore is IRollupCore {} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbSys.sol b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbSys.sol new file mode 100644 index 0000000000..7d6afbc18e --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbSys.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {ArbSys} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; + +/// @dev to generate gethwrappers +interface IArbSys is ArbSys {} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumGatewayRouter.sol b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumGatewayRouter.sol new file mode 100644 index 0000000000..81fc2cb1b5 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumGatewayRouter.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {IGatewayRouter} from "@arbitrum/token-bridge-contracts/contracts/tokenbridge/libraries/gateway/IGatewayRouter.sol"; + +/// @dev to generate gethwrappers +interface IArbitrumGatewayRouter is IGatewayRouter {} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumInbox.sol b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumInbox.sol new file mode 100644 index 0000000000..a306ef21b1 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumInbox.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {IInboxBase} from "@arbitrum/nitro-contracts/src/bridge/IInboxBase.sol"; + +/// @dev to generate gethwrappers +interface IArbitrumInbox is IInboxBase {} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumL1GatewayRouter.sol b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumL1GatewayRouter.sol new file mode 100644 index 0000000000..49e7e45dd7 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumL1GatewayRouter.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {IL1GatewayRouter} from "@arbitrum/token-bridge-contracts/contracts/tokenbridge/ethereum/gateway/IL1GatewayRouter.sol"; + +/// @dev to generate gethwrappers +interface IArbitrumL1GatewayRouter is IL1GatewayRouter {} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumTokenGateway.sol b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumTokenGateway.sol new file mode 100644 index 0000000000..0c1f228189 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IArbitrumTokenGateway.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {ITokenGateway} from "@arbitrum/token-bridge-contracts/contracts/tokenbridge/libraries/gateway/ITokenGateway.sol"; + +/// @dev to generate gethwrappers +interface IArbitrumTokenGateway is ITokenGateway {} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IL2ArbitrumGateway.sol b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IL2ArbitrumGateway.sol new file mode 100644 index 0000000000..96a63a0dcd --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IL2ArbitrumGateway.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {L2ArbitrumGateway} from "@arbitrum/token-bridge-contracts/contracts/tokenbridge/arbitrum/gateway/L2ArbitrumGateway.sol"; + +/// @dev to generate gethwrappers +abstract contract IL2ArbitrumGateway is L2ArbitrumGateway {} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IL2ArbitrumMessenger.sol b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IL2ArbitrumMessenger.sol new file mode 100644 index 0000000000..115882a211 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/IL2ArbitrumMessenger.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {L2ArbitrumMessenger} from "@arbitrum/token-bridge-contracts/contracts/tokenbridge/arbitrum/L2ArbitrumMessenger.sol"; + +/// @dev to generate gethwrappers +abstract contract IL2ArbitrumMessenger is L2ArbitrumMessenger {} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/INodeInterface.sol b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/INodeInterface.sol new file mode 100644 index 0000000000..79475cdf5d --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/arbitrum/INodeInterface.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {NodeInterface} from "@arbitrum/nitro-contracts/src/node-interface/NodeInterface.sol"; + +/// @dev to generate gethwrappers +interface INodeInterface is NodeInterface {} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/optimism/DisputeTypes.sol b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/DisputeTypes.sol new file mode 100644 index 0000000000..f0bd99fbcd --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/DisputeTypes.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +// Copied from https://github.com/ethereum-optimism/optimism/blob/v1.7.0/packages/contracts-bedrock/src/libraries/DisputeTypes.sol +pragma solidity ^0.8.0; + +/// @notice A `GameType` represents the type of game being played. +type GameType is uint32; + +/// @notice A `GameId` represents a packed 1 byte game ID, an 11 byte timestamp, and a 20 byte address. +/// @dev The packed layout of this type is as follows: +/// ┌───────────┬───────────┐ +/// │ Bits │ Value │ +/// ├───────────┼───────────┤ +/// │ [0, 8) │ Game Type │ +/// │ [8, 96) │ Timestamp │ +/// │ [96, 256) │ Address │ +/// └───────────┴───────────┘ +type GameId is bytes32; + +/// @notice A dedicated timestamp type. +type Timestamp is uint64; + +/// @notice A claim represents an MPT root representing the state of the fault proof program. +type Claim is bytes32; diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismCrossDomainMessenger.sol b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismCrossDomainMessenger.sol new file mode 100644 index 0000000000..2b5cc65072 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismCrossDomainMessenger.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +// Copied from https://github.com/ethereum-optimism/optimism/blob/f707883038d527cbf1e9f8ea513fe33255deadbc/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol#L153 +pragma solidity ^0.8.0; + +interface IOptimismCrossDomainMessenger { + /// @notice Emitted whenever a message is sent to the other chain. + /// @param target Address of the recipient of the message. + /// @param sender Address of the sender of the message. + /// @param message Message to trigger the recipient address with. + /// @param messageNonce Unique nonce attached to the message. + /// @param gasLimit Minimum gas limit that the message can be executed with. + event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); + + /// @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only + /// be executed via cross-chain call from the other messenger OR if the message was + /// already received once and is currently being replayed. + /// @param _nonce Nonce of the message being relayed. + /// @param _sender Address of the user who sent the message. + /// @param _target Address that the message is targeted at. + /// @param _value ETH value to send with the message. + /// @param _minGasLimit Minimum amount of gas that the message can be executed with. + /// @param _message Message to send to the target. + function relayMessage( + uint256 _nonce, + address _sender, + address _target, + uint256 _value, + uint256 _minGasLimit, + bytes calldata _message + ) external payable; +} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismDisputeGameFactory.sol b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismDisputeGameFactory.sol new file mode 100644 index 0000000000..f72e6456d3 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismDisputeGameFactory.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +// Copied from https://github.com/ethereum-optimism/optimism/blob/v1.7.0/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol +pragma solidity ^0.8.0; + +import {GameType, GameId, Timestamp, Claim} from "./DisputeTypes.sol"; + +interface IOptimismDisputeGameFactory { + /// @notice Information about a dispute game found in a `findLatestGames` search. + struct GameSearchResult { + uint256 index; + GameId metadata; + Timestamp timestamp; + Claim rootClaim; + bytes extraData; + } + + /// @notice Finds the `_n` most recent `GameId`'s of type `_gameType` starting at `_start`. If there are less than + /// `_n` games of type `_gameType` starting at `_start`, then the returned array will be shorter than `_n`. + /// @param _gameType The type of game to find. + /// @param _start The index to start the reverse search from. + /// @param _n The number of games to find. + function findLatestGames( + GameType _gameType, + uint256 _start, + uint256 _n + ) external view returns (GameSearchResult[] memory games_); + + /// @notice The total number of dispute games created by this factory. + /// @return gameCount_ The total number of dispute games created by this factory. + function gameCount() external view returns (uint256 gameCount_); +} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismL1StandardBridge.sol b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismL1StandardBridge.sol new file mode 100644 index 0000000000..3a518fcf79 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismL1StandardBridge.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +// Copied from https://github.com/ethereum-optimism/optimism/blob/f707883038d527cbf1e9f8ea513fe33255deadbc/packages/contracts-bedrock/src/L1/L1StandardBridge.sol +pragma solidity ^0.8.0; + +interface IOptimismL1StandardBridge { + /// @custom:legacy + /// @notice Deposits some amount of ETH into a target account on L2. + /// Note that if ETH is sent to a contract on L2 and the call fails, then that ETH will + /// be locked in the L2StandardBridge. ETH may be recoverable if the call can be + /// successfully replayed by increasing the amount of gas supplied to the call. If the + /// call will fail for any amount of gas, then the ETH will be locked permanently. + /// @param _to Address of the recipient on L2. + /// @param _minGasLimit Minimum gas limit for the deposit message on L2. + /// @param _extraData Optional data to forward to L2. + /// Data supplied here will not be used to execute any code on L2 and is + /// only emitted as extra data for the convenience of off-chain tooling. + function depositETHTo(address _to, uint32 _minGasLimit, bytes calldata _extraData) external payable; +} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismL2OutputOracle.sol b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismL2OutputOracle.sol new file mode 100644 index 0000000000..fa36863c5b --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismL2OutputOracle.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +// Copied from https://github.com/ethereum-optimism/optimism/blob/v1.7.0/packages/contracts-bedrock/src/L1/L2OutputOracle.sol +pragma solidity ^0.8.0; + +import {Types} from "./Types.sol"; + +interface IOptimismL2OutputOracle { + /// @notice Returns the index of the L2 output that checkpoints a given L2 block number. + /// Uses a binary search to find the first output greater than or equal to the given + /// block. + /// @param _l2BlockNumber L2 block number to find a checkpoint for. + /// @return Index of the first checkpoint that commits to the given L2 block number. + function getL2OutputIndexAfter(uint256 _l2BlockNumber) external view returns (uint256); + + /// @notice Returns an output by index. Needed to return a struct instead of a tuple. + /// @param _l2OutputIndex Index of the output to return. + /// @return The output at the given index. + function getL2Output(uint256 _l2OutputIndex) external view returns (Types.OutputProposal memory); +} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismL2ToL1MessagePasser.sol b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismL2ToL1MessagePasser.sol new file mode 100644 index 0000000000..9ac6aebfb2 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismL2ToL1MessagePasser.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +// Copied from https://github.com/ethereum-optimism/optimism/blob/v1.7.0/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol +pragma solidity ^0.8.0; + +interface IOptimismL2ToL1MessagePasser { + /// @notice Emitted any time a withdrawal is initiated. + /// @param nonce Unique value corresponding to each withdrawal. + /// @param sender The L2 account address which initiated the withdrawal. + /// @param target The L1 account address the call will be send to. + /// @param value The ETH value submitted for withdrawal, to be forwarded to the target. + /// @param gasLimit The minimum amount of gas that must be provided when withdrawing. + /// @param data The data to be forwarded to the target on L1. + /// @param withdrawalHash The hash of the withdrawal. + event MessagePassed( + uint256 indexed nonce, + address indexed sender, + address indexed target, + uint256 value, + uint256 gasLimit, + bytes data, + bytes32 withdrawalHash + ); +} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismPortal.sol b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismPortal.sol new file mode 100644 index 0000000000..887025bac7 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismPortal.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +// Copied from https://github.com/ethereum-optimism/optimism/blob/v1.7.0/packages/contracts-bedrock/src/L1/OptimismPortal.sol +pragma solidity ^0.8.0; + +import {Types} from "./Types.sol"; + +interface IOptimismPortal { + /// @notice Semantic version. + function version() external view returns (string memory); + + /// @notice Proves a withdrawal transaction. + /// @param _tx Withdrawal transaction to finalize. + /// @param _l2OutputIndex L2 output index to prove against. + /// @param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contract's storage root. + /// @param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract. + function proveWithdrawalTransaction( + Types.WithdrawalTransaction memory _tx, + uint256 _l2OutputIndex, + Types.OutputRootProof calldata _outputRootProof, + bytes[] calldata _withdrawalProof + ) external; + + /// @notice Finalizes a withdrawal transaction. + /// @param _tx Withdrawal transaction to finalize. + function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx) external; +} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismPortal2.sol b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismPortal2.sol new file mode 100644 index 0000000000..165922b5aa --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismPortal2.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +// Copied from https://github.com/ethereum-optimism/optimism/blob/v1.7.0/packages/contracts-bedrock/src/L1/OptimismPortal2.sol +pragma solidity ^0.8.0; +import {GameType} from "./DisputeTypes.sol"; + +interface IOptimismPortal2 { + /// @notice The dispute game factory address. + /// @dev See https://github.com/ethereum-optimism/optimism/blob/f707883038d527cbf1e9f8ea513fe33255deadbc/packages/contracts-bedrock/src/L1/OptimismPortal2.sol#L79. + function disputeGameFactory() external view returns (address); + /// @notice The game type that the OptimismPortal consults for output proposals. + function respectedGameType() external view returns (GameType); +} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismStandardBridge.sol b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismStandardBridge.sol new file mode 100644 index 0000000000..2f9ef91d7c --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/IOptimismStandardBridge.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +// Copied from https://github.com/ethereum-optimism/optimism/blob/f707883038d527cbf1e9f8ea513fe33255deadbc/packages/contracts-bedrock/src/universal/StandardBridge.sol#L88 +pragma solidity ^0.8.0; + +interface IOptimismStandardBridge { + /// @notice Emitted when an ERC20 bridge is finalized on this chain. + /// @param localToken Address of the ERC20 on this chain. + /// @param remoteToken Address of the ERC20 on the remote chain. + /// @param from Address of the sender. + /// @param to Address of the receiver. + /// @param amount Amount of the ERC20 sent. + /// @param extraData Extra data sent with the transaction. + event ERC20BridgeFinalized( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 amount, + bytes extraData + ); + + /// @notice Finalizes an ERC20 bridge on this chain. Can only be triggered by the other + /// StandardBridge contract on the remote chain. + /// @param _localToken Address of the ERC20 on this chain. + /// @param _remoteToken Address of the corresponding token on the remote chain. + /// @param _from Address of the sender. + /// @param _to Address of the receiver. + /// @param _amount Amount of the ERC20 being bridged. + /// @param _extraData Extra data to be sent with the transaction. Note that the recipient will + /// not be triggered with this data, but it will be emitted and can be used + /// to identify the transaction. + function finalizeBridgeERC20( + address _localToken, + address _remoteToken, + address _from, + address _to, + uint256 _amount, + bytes calldata _extraData + ) external; +} diff --git a/contracts/src/v0.8/liquiditymanager/interfaces/optimism/Types.sol b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/Types.sol new file mode 100644 index 0000000000..bd8d5d3b63 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/interfaces/optimism/Types.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT +// Copied from https://github.com/ethereum-optimism/optimism/blob/v1.7.0/packages/contracts-bedrock/src/libraries/Types.sol +pragma solidity ^0.8.0; + +/// @title Types +/// @notice Contains various types used throughout the Optimism contract system. +library Types { + /// @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1 + /// timestamp that the output root is posted. This timestamp is used to verify that the + /// finalization period has passed since the output root was submitted. + /// @custom:field outputRoot Hash of the L2 output. + /// @custom:field timestamp Timestamp of the L1 block that the output root was submitted in. + /// @custom:field l2BlockNumber L2 block number that the output corresponds to. + struct OutputProposal { + bytes32 outputRoot; + uint128 timestamp; + uint128 l2BlockNumber; + } + + /// @notice Struct representing the elements that are hashed together to generate an output root + /// which itself represents a snapshot of the L2 state. + /// @custom:field version Version of the output root. + /// @custom:field stateRoot Root of the state trie at the block of this output. + /// @custom:field messagePasserStorageRoot Root of the message passer storage trie. + /// @custom:field latestBlockhash Hash of the block this output was generated from. + struct OutputRootProof { + bytes32 version; + bytes32 stateRoot; + bytes32 messagePasserStorageRoot; + bytes32 latestBlockhash; + } + + /// @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end + /// user (as opposed to a system deposit transaction generated by the system). + /// @custom:field from Address of the sender of the transaction. + /// @custom:field to Address of the recipient of the transaction. + /// @custom:field isCreation True if the transaction is a contract creation. + /// @custom:field value Value to send to the recipient. + /// @custom:field mint Amount of ETH to mint. + /// @custom:field gasLimit Gas limit of the transaction. + /// @custom:field data Data of the transaction. + /// @custom:field l1BlockHash Hash of the block the transaction was submitted in. + /// @custom:field logIndex Index of the log in the block the transaction was submitted in. + //solhint-disable gas-struct-packing + struct UserDepositTransaction { + address from; + address to; + bool isCreation; + uint256 value; + uint256 mint; + uint64 gasLimit; + bytes data; + bytes32 l1BlockHash; + uint256 logIndex; + } + + /// @notice Struct representing a withdrawal transaction. + /// @custom:field nonce Nonce of the withdrawal transaction + /// @custom:field sender Address of the sender of the transaction. + /// @custom:field target Address of the recipient of the transaction. + /// @custom:field value Value to send to the recipient. + /// @custom:field gasLimit Gas limit of the transaction. + /// @custom:field data Data of the transaction. + struct WithdrawalTransaction { + uint256 nonce; + address sender; + address target; + uint256 value; + uint256 gasLimit; + bytes data; + } +} diff --git a/contracts/src/v0.8/liquiditymanager/ocr/OCR3Abstract.sol b/contracts/src/v0.8/liquiditymanager/ocr/OCR3Abstract.sol new file mode 100644 index 0000000000..44e5d89f7f --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/ocr/OCR3Abstract.sol @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; + +abstract contract OCR3Abstract is ITypeAndVersion { + // Maximum number of oracles the offchain reporting protocol is designed for + uint256 internal constant MAX_NUM_ORACLES = 31; + + /// @notice triggers a new run of the offchain reporting protocol + /// @param previousConfigBlockNumber block in which the previous config was set, to simplify historic analysis + /// @param configDigest configDigest of this configuration + /// @param configCount ordinal number of this config setting among all config settings over the life of this contract + /// @param signers ith element is address ith oracle uses to sign a report + /// @param transmitters ith element is address ith oracle uses to transmit a report via the transmit method + /// @param f maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly + /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) + /// @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter + /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + event ConfigSet( + uint32 previousConfigBlockNumber, + bytes32 configDigest, + uint64 configCount, + address[] signers, + address[] transmitters, + uint8 f, + bytes onchainConfig, + uint64 offchainConfigVersion, + bytes offchainConfig + ); + + /// @notice sets offchain reporting protocol configuration incl. participating oracles + /// @param signers addresses with which oracles sign the reports + /// @param transmitters addresses oracles use to transmit the reports + /// @param f number of faulty oracles the system can tolerate + /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) + /// @param offchainConfigVersion version number for offchainEncoding schema + /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + function setOCR3Config( + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external virtual; + + /// @notice information about current offchain reporting protocol configuration + /// @return configCount ordinal number of current config, out of all configs applied to this contract so far + /// @return blockNumber block at which this config was set + /// @return configDigest domain-separation tag for current config (see _configDigestFromConfigData) + function latestConfigDetails() + external + view + virtual + returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest); + + function _configDigestFromConfigData( + uint256 chainId, + address contractAddress, + uint64 configCount, + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + chainId, + contractAddress, + configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + uint256 prefix = 0x0001 << (256 - 16); // 0x000100..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + /// @notice optionally emitted to indicate the latest configDigest and sequence number + /// for which a report was successfully transmitted. Alternatively, the contract may + /// use latestConfigDigestAndEpoch with scanLogs set to false. + event Transmitted(bytes32 configDigest, uint64 sequenceNumber); + + /// @notice transmit is called to post a new report to the contract + /// @param report serialized report, which the signatures are signing. + /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param rawVs ith element is the the V component of the ith signature + function transmit( + // NOTE: If these parameters are changed, expectedMsgDataLength and/or + // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly + bytes32[3] calldata reportContext, + bytes calldata report, + bytes32[] calldata rs, + bytes32[] calldata ss, + bytes32 rawVs // signatures + ) external virtual; +} diff --git a/contracts/src/v0.8/liquiditymanager/ocr/OCR3Base.sol b/contracts/src/v0.8/liquiditymanager/ocr/OCR3Base.sol new file mode 100644 index 0000000000..b856f734e7 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/ocr/OCR3Base.sol @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; +import {OCR3Abstract} from "./OCR3Abstract.sol"; + +/// @notice Onchain verification of reports from the offchain reporting protocol +/// @dev For details on its operation, see the offchain reporting protocol design +/// doc, which refers to this contract as simply the "contract". +abstract contract OCR3Base is OwnerIsCreator, OCR3Abstract { + error InvalidConfig(string message); + error WrongMessageLength(uint256 expected, uint256 actual); + error ConfigDigestMismatch(bytes32 expected, bytes32 actual); + error ForkedChain(uint256 expected, uint256 actual); + error WrongNumberOfSignatures(); + error SignaturesOutOfRegistration(); + error UnauthorizedTransmitter(); + error UnauthorizedSigner(); + error NonUniqueSignatures(); + error OracleCannotBeZeroAddress(); + error NonIncreasingSequenceNumber(uint64 sequenceNumber, uint64 latestSequenceNumber); + + // Packing these fields used on the hot path in a ConfigInfo variable reduces the + // retrieval of all of them to a minimum number of SLOADs. + struct ConfigInfo { + bytes32 latestConfigDigest; + uint8 f; + uint8 n; + } + + // Used for s_oracles[a].role, where a is an address, to track the purpose + // of the address, or to indicate that the address is unset. + enum Role { + // No oracle role has been set for address a + Unset, + // Signing address for the s_oracles[a].index'th oracle. I.e., report + // signatures from this oracle should ecrecover back to address a. + Signer, + // Transmission address for the s_oracles[a].index'th oracle. I.e., if a + // report is received by OCR3Aggregator.transmit in which msg.sender is + // a, it is attributed to the s_oracles[a].index'th oracle. + Transmitter + } + + struct Oracle { + uint8 index; // Index of oracle in s_signers/s_transmitters + Role role; // Role of the address which mapped to this struct + } + + // The current config + ConfigInfo internal s_configInfo; + + // incremented each time a new config is posted. This count is incorporated + // into the config digest, to prevent replay attacks. + uint32 internal s_configCount; + // makes it easier for offchain systems to extract config from logs. + uint32 internal s_latestConfigBlockNumber; + + uint64 internal s_latestSequenceNumber; + + // signer OR transmitter address + mapping(address signerOrTransmitter => Oracle oracle) internal s_oracles; + + // s_signers contains the signing address of each oracle + address[] internal s_signers; + + // s_transmitters contains the transmission address of each oracle, + // i.e. the address the oracle actually sends transactions to the contract from + address[] internal s_transmitters; + + // The constant-length components of the msg.data sent to transmit. + // See the "If we wanted to call sam" example on for example reasoning + // https://solidity.readthedocs.io/en/v0.7.2/abi-spec.html + uint16 private constant TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT = + 4 + // function selector + 32 * + 3 + // 3 words containing reportContext + 32 + // word containing start location of abiencoded report value + 32 + // word containing location start of abiencoded rs value + 32 + // word containing start location of abiencoded ss value + 32 + // rawVs value + 32 + // word containing length of report + 32 + // word containing length rs + 32; // word containing length of ss + + uint256 internal immutable i_chainID; + + constructor() { + i_chainID = block.chainid; + } + + // Reverts transaction if config args are invalid + modifier checkConfigValid( + uint256 numSigners, + uint256 numTransmitters, + uint256 f + ) { + if (numSigners > MAX_NUM_ORACLES) revert InvalidConfig("too many signers"); + if (f == 0) revert InvalidConfig("f must be positive"); + if (numSigners != numTransmitters) revert InvalidConfig("oracle addresses out of registration"); + if (numSigners <= 3 * f) revert InvalidConfig("faulty-oracle f too high"); + _; + } + + /// @notice sets offchain reporting protocol configuration incl. participating oracles + /// @param signers addresses with which oracles sign the reports + /// @param transmitters addresses oracles use to transmit the reports + /// @param f number of faulty oracles the system can tolerate + /// @param onchainConfig encoded on-chain contract configuration + /// @param offchainConfigVersion version number for offchainEncoding schema + /// @param offchainConfig encoded off-chain oracle configuration + function setOCR3Config( + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external override checkConfigValid(signers.length, transmitters.length, f) onlyOwner { + _beforeSetConfig(onchainConfig); + uint256 oldSignerLength = s_signers.length; + for (uint256 i = 0; i < oldSignerLength; ++i) { + delete s_oracles[s_signers[i]]; + delete s_oracles[s_transmitters[i]]; + } + + uint256 newSignersLength = signers.length; + for (uint256 i = 0; i < newSignersLength; ++i) { + // add new signer/transmitter addresses + address signer = signers[i]; + if (s_oracles[signer].role != Role.Unset) revert InvalidConfig("repeated signer address"); + if (signer == address(0)) revert OracleCannotBeZeroAddress(); + s_oracles[signer] = Oracle(uint8(i), Role.Signer); + + address transmitter = transmitters[i]; + if (s_oracles[transmitter].role != Role.Unset) revert InvalidConfig("repeated transmitter address"); + if (transmitter == address(0)) revert OracleCannotBeZeroAddress(); + s_oracles[transmitter] = Oracle(uint8(i), Role.Transmitter); + } + + s_signers = signers; + s_transmitters = transmitters; + + s_configInfo.f = f; + s_configInfo.n = uint8(newSignersLength); + s_configInfo.latestConfigDigest = _configDigestFromConfigData( + block.chainid, + address(this), + ++s_configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + + uint32 previousConfigBlockNumber = s_latestConfigBlockNumber; + s_latestConfigBlockNumber = uint32(block.number); + s_latestSequenceNumber = 0; + + emit ConfigSet( + previousConfigBlockNumber, + s_configInfo.latestConfigDigest, + s_configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + } + + /// @dev Hook that is run from setOCR3Config() right after validating configuration. + /// Empty by default, please provide an implementation in a child contract if you need additional configuration processing + function _beforeSetConfig(bytes memory _onchainConfig) internal virtual {} + + /// @return list of addresses permitted to transmit reports to this contract + /// @dev The list will match the order used to specify the transmitter during setConfig + function getTransmitters() external view returns (address[] memory) { + return s_transmitters; + } + + /// @notice transmit is called to post a new report to the contract + /// @param report serialized report, which the signatures are signing. + /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param rawVs ith element is the the V component of the ith signature + function transmit( + // NOTE: If these parameters are changed, expectedMsgDataLength and/or + // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly + bytes32[3] calldata reportContext, + bytes calldata report, + bytes32[] calldata rs, + bytes32[] calldata ss, + bytes32 rawVs // signatures + ) external override { + uint64 sequenceNumber = uint64(uint256(reportContext[1])); + if (sequenceNumber <= s_latestSequenceNumber) { + revert NonIncreasingSequenceNumber(sequenceNumber, s_latestSequenceNumber); + } + + // Scoping this reduces stack pressure and gas usage + { + _report(report, sequenceNumber); + } + + s_latestSequenceNumber = sequenceNumber; + // reportContext consists of: + // reportContext[0]: ConfigDigest + // reportContext[1]: 24 byte padding, 8 byte sequence number + bytes32 configDigest = reportContext[0]; + ConfigInfo memory configInfo = s_configInfo; + + if (configInfo.latestConfigDigest != configDigest) { + revert ConfigDigestMismatch(configInfo.latestConfigDigest, configDigest); + } + // If the cached chainID at time of deployment doesn't match the current chainID, we reject all signed reports. + // This avoids a (rare) scenario where chain A forks into chain A and A', A' still has configDigest + // calculated from chain A and so OCR reports will be valid on both forks. + if (i_chainID != block.chainid) revert ForkedChain(i_chainID, block.chainid); + + emit Transmitted(configDigest, sequenceNumber); + + if (rs.length != configInfo.f + 1) revert WrongNumberOfSignatures(); + if (rs.length != ss.length) revert SignaturesOutOfRegistration(); + + // Scoping this reduces stack pressure and gas usage + { + Oracle memory transmitter = s_oracles[msg.sender]; + // Check that sender is authorized to report + if (!(transmitter.role == Role.Transmitter && msg.sender == s_transmitters[transmitter.index])) + revert UnauthorizedTransmitter(); + } + // Scoping this reduces stack pressure and gas usage + { + uint256 expectedDataLength = uint256(TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT) + + report.length + // one byte pure entry in _report + rs.length * + 32 + // 32 bytes per entry in _rs + ss.length * + 32; // 32 bytes per entry in _ss) + if (msg.data.length != expectedDataLength) revert WrongMessageLength(expectedDataLength, msg.data.length); + } + + // Verify signatures attached to report + bytes32 h = keccak256(abi.encodePacked(keccak256(report), reportContext)); + bool[MAX_NUM_ORACLES] memory signed; + + uint256 numberOfSignatures = rs.length; + for (uint256 i = 0; i < numberOfSignatures; ++i) { + // Safe from ECDSA malleability here since we check for duplicate signers. + address signer = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]); + // Since we disallow address(0) as a valid signer address, it can + // never have a signer role. + Oracle memory oracle = s_oracles[signer]; + if (oracle.role != Role.Signer) revert UnauthorizedSigner(); + if (signed[oracle.index]) revert NonUniqueSignatures(); + signed[oracle.index] = true; + } + } + + /// @notice information about current offchain reporting protocol configuration + /// @return configCount ordinal number of current config, out of all configs applied to this contract so far + /// @return blockNumber block at which this config was set + /// @return configDigest domain-separation tag for current config (see _configDigestFromConfigData) + function latestConfigDetails() + external + view + override + returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) + { + return (s_configCount, s_latestConfigBlockNumber, s_configInfo.latestConfigDigest); + } + + /// @notice gets the latest sequence number accepted by the contract + /// @return sequenceNumber the monotomically incremenenting number associated with OCR reports + function latestSequenceNumber() external view virtual returns (uint64 sequenceNumber) { + return s_latestSequenceNumber; + } + + function _report(bytes calldata report, uint64 sequenceNumber) internal virtual; +} diff --git a/contracts/src/v0.8/liquiditymanager/test/LiquidityManager.t.sol b/contracts/src/v0.8/liquiditymanager/test/LiquidityManager.t.sol new file mode 100644 index 0000000000..73c9ba7445 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/test/LiquidityManager.t.sol @@ -0,0 +1,945 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ILiquidityManager} from "../interfaces/ILiquidityManager.sol"; +import {IBridgeAdapter} from "../interfaces/IBridge.sol"; + +import {LockReleaseTokenPool} from "../../ccip/pools/LockReleaseTokenPool.sol"; +import {LiquidityManager} from "../LiquidityManager.sol"; +import {MockL1BridgeAdapter} from "./mocks/MockBridgeAdapter.sol"; +import {LiquidityManagerBaseTest} from "./LiquidityManagerBaseTest.t.sol"; +import {LiquidityManagerHelper} from "./helpers/LiquidityManagerHelper.sol"; + +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +// FOUNDRY_PROFILE=liquiditymanager forge test --match-path src/v0.8/liquiditymanager/test/LiquidityManager.t.sol + +contract LiquidityManagerSetup is LiquidityManagerBaseTest { + event FinalizationStepCompleted( + uint64 indexed ocrSeqNum, + uint64 indexed remoteChainSelector, + bytes bridgeSpecificData + ); + event LiquidityTransferred( + uint64 indexed ocrSeqNum, + uint64 indexed fromChainSelector, + uint64 indexed toChainSelector, + address to, + uint256 amount, + bytes bridgeSpecificPayload, + bytes bridgeReturnData + ); + event FinalizationFailed( + uint64 indexed ocrSeqNum, + uint64 indexed remoteChainSelector, + bytes bridgeSpecificData, + bytes reason + ); + event FinanceRoleSet(address financeRole); + event LiquidityAddedToContainer(address indexed provider, uint256 indexed amount); + event LiquidityRemovedFromContainer(address indexed remover, uint256 indexed amount); + // Liquidity container event + event LiquidityAdded(address indexed provider, uint256 indexed amount); + event LiquidityRemoved(address indexed remover, uint256 indexed amount); + + error NonceAlreadyUsed(uint256 nonce); + + LiquidityManagerHelper internal s_liquidityManager; + LockReleaseTokenPool internal s_lockReleaseTokenPool; + MockL1BridgeAdapter internal s_bridgeAdapter; + + // LiquidityManager that rebalances weth. + LiquidityManagerHelper internal s_wethRebalancer; + LockReleaseTokenPool internal s_wethLockReleaseTokenPool; + MockL1BridgeAdapter internal s_wethBridgeAdapter; + + function setUp() public virtual override { + LiquidityManagerBaseTest.setUp(); + + s_bridgeAdapter = new MockL1BridgeAdapter(s_l1Token, false); + s_lockReleaseTokenPool = new LockReleaseTokenPool(s_l1Token, new address[](0), address(1), true, address(123)); + s_liquidityManager = new LiquidityManagerHelper( + s_l1Token, + i_localChainSelector, + s_lockReleaseTokenPool, + 0, + FINANCE + ); + + s_lockReleaseTokenPool.setRebalancer(address(s_liquidityManager)); + + s_wethBridgeAdapter = new MockL1BridgeAdapter(IERC20(address(s_l1Weth)), true); + s_wethLockReleaseTokenPool = new LockReleaseTokenPool( + IERC20(address(s_l1Weth)), + new address[](0), + address(1), + true, + address(123) + ); + s_wethRebalancer = new LiquidityManagerHelper( + IERC20(address(s_l1Weth)), + i_localChainSelector, + s_wethLockReleaseTokenPool, + 0, + FINANCE + ); + + s_wethLockReleaseTokenPool.setRebalancer(address(s_wethRebalancer)); + } +} + +contract LiquidityManager_addLiquidity is LiquidityManagerSetup { + function test_addLiquiditySuccess() external { + address caller = STRANGER; + vm.startPrank(caller); + + uint256 amount = 12345679; + deal(address(s_l1Token), caller, amount); + + s_l1Token.approve(address(s_liquidityManager), amount); + + vm.expectEmit(); + emit LiquidityAddedToContainer(caller, amount); + + s_liquidityManager.addLiquidity(amount); + + assertEq(s_l1Token.balanceOf(address(s_lockReleaseTokenPool)), amount); + } +} + +contract LiquidityManager_removeLiquidity is LiquidityManagerSetup { + function test_removeLiquiditySuccess() external { + uint256 amount = 12345679; + deal(address(s_l1Token), address(s_lockReleaseTokenPool), amount); + + vm.expectEmit(); + emit LiquidityRemovedFromContainer(FINANCE, amount); + + vm.startPrank(FINANCE); + s_liquidityManager.removeLiquidity(amount); + + assertEq(s_l1Token.balanceOf(address(s_liquidityManager)), 0); + } + + function test_InsufficientLiquidityReverts() external { + uint256 balance = 923; + uint256 requested = balance + 1; + + deal(address(s_l1Token), address(s_lockReleaseTokenPool), balance); + + vm.expectRevert(abi.encodeWithSelector(LiquidityManager.InsufficientLiquidity.selector, requested, balance, 0)); + + vm.startPrank(FINANCE); + s_liquidityManager.removeLiquidity(requested); + } + + function test_OnlyFinanceRoleReverts() external { + vm.stopPrank(); + + vm.expectRevert(LiquidityManager.OnlyFinanceRole.selector); + + s_liquidityManager.removeLiquidity(123); + } +} + +contract LiquidityManager__report is LiquidityManagerSetup { + function test_EmptyReportReverts() external { + ILiquidityManager.LiquidityInstructions memory instructions = ILiquidityManager.LiquidityInstructions({ + sendLiquidityParams: new ILiquidityManager.SendLiquidityParams[](0), + receiveLiquidityParams: new ILiquidityManager.ReceiveLiquidityParams[](0) + }); + + vm.expectRevert(LiquidityManager.EmptyReport.selector); + + s_liquidityManager.report(abi.encode(instructions), 123); + } +} + +contract LiquidityManager_rebalanceLiquidity is LiquidityManagerSetup { + uint256 internal constant AMOUNT = 12345679; + + function test_rebalanceLiquiditySuccess() external { + deal(address(s_l1Token), address(s_lockReleaseTokenPool), AMOUNT); + + LiquidityManager.CrossChainRebalancerArgs[] memory args = new LiquidityManager.CrossChainRebalancerArgs[](1); + args[0] = ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: address(s_liquidityManager), + localBridge: s_bridgeAdapter, + remoteToken: address(s_l2Token), + remoteChainSelector: i_remoteChainSelector, + enabled: true + }); + s_liquidityManager.setCrossChainRebalancers(args); + + vm.expectEmit(); + emit Transfer(address(s_lockReleaseTokenPool), address(s_liquidityManager), AMOUNT); + + vm.expectEmit(); + emit Approval(address(s_liquidityManager), address(s_bridgeAdapter), AMOUNT); + + vm.expectEmit(); + emit Transfer(address(s_liquidityManager), address(s_bridgeAdapter), AMOUNT); + + vm.expectEmit(); + bytes memory encodedNonce = abi.encode(uint256(1)); + emit LiquidityTransferred( + type(uint64).max, + i_localChainSelector, + i_remoteChainSelector, + address(s_liquidityManager), + AMOUNT, + bytes(""), + encodedNonce + ); + + vm.startPrank(FINANCE); + s_liquidityManager.rebalanceLiquidity(i_remoteChainSelector, AMOUNT, 0, bytes("")); + + assertEq(s_l1Token.balanceOf(address(s_liquidityManager)), 0); + assertEq(s_l1Token.balanceOf(address(s_bridgeAdapter)), AMOUNT); + assertEq(s_l1Token.allowance(address(s_liquidityManager), address(s_bridgeAdapter)), 0); + } + + /// @notice this test sets up a circular system where the liquidity container of + /// the local Liquidity manager is the bridge adapter of the remote liquidity manager + /// and the other way around for the remote liquidity manager. This allows us to + /// rebalance funds between the two liquidity managers on the same chain. + function test_rebalanceBetweenPoolsSuccess() external { + uint256 amount = 12345670; + + s_liquidityManager = new LiquidityManagerHelper(s_l1Token, i_localChainSelector, s_bridgeAdapter, 0, FINANCE); + + MockL1BridgeAdapter mockRemoteBridgeAdapter = new MockL1BridgeAdapter(s_l1Token, false); + LiquidityManager mockRemoteRebalancer = new LiquidityManager( + s_l1Token, + i_remoteChainSelector, + mockRemoteBridgeAdapter, + 0, + FINANCE + ); + + LiquidityManager.CrossChainRebalancerArgs[] memory args = new LiquidityManager.CrossChainRebalancerArgs[](1); + args[0] = ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: address(mockRemoteRebalancer), + localBridge: mockRemoteBridgeAdapter, + remoteToken: address(s_l1Token), + remoteChainSelector: i_remoteChainSelector, + enabled: true + }); + + s_liquidityManager.setCrossChainRebalancers(args); + + args[0] = ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: address(s_liquidityManager), + localBridge: s_bridgeAdapter, + remoteToken: address(s_l1Token), + remoteChainSelector: i_localChainSelector, + enabled: true + }); + + mockRemoteRebalancer.setCrossChainRebalancers(args); + + deal(address(s_l1Token), address(s_bridgeAdapter), amount); + + vm.startPrank(FINANCE); + s_liquidityManager.rebalanceLiquidity(i_remoteChainSelector, amount, 0, bytes("")); + + assertEq(s_l1Token.balanceOf(address(s_bridgeAdapter)), 0); + assertEq(s_l1Token.balanceOf(address(mockRemoteBridgeAdapter)), amount); + assertEq(s_l1Token.allowance(address(s_liquidityManager), address(s_bridgeAdapter)), 0); + + // attach a bridge fee and see the relevant adapter's ether balance change. + // the bridge fee is sent along with the sendERC20 call. + uint256 bridgeFee = 123; + vm.deal(address(mockRemoteRebalancer), bridgeFee); + mockRemoteRebalancer.rebalanceLiquidity(i_localChainSelector, amount, bridgeFee, bytes("")); + + assertEq(s_l1Token.balanceOf(address(s_bridgeAdapter)), amount); + assertEq(s_l1Token.balanceOf(address(mockRemoteBridgeAdapter)), 0); + assertEq(address(s_bridgeAdapter).balance, bridgeFee); + + // Assert partial rebalancing works correctly + s_liquidityManager.rebalanceLiquidity(i_remoteChainSelector, amount / 2, 0, bytes("")); + + assertEq(s_l1Token.balanceOf(address(s_bridgeAdapter)), amount / 2); + assertEq(s_l1Token.balanceOf(address(mockRemoteBridgeAdapter)), amount / 2); + } + + function test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() external { + // set up a rebalancer on another chain, an "L2". + // note we use the L1 bridge adapter because it has the reverting logic + // when finalization is already done. + MockL1BridgeAdapter remoteBridgeAdapter = new MockL1BridgeAdapter(s_l2Token, false); + LockReleaseTokenPool remotePool = new LockReleaseTokenPool( + s_l2Token, + new address[](0), + address(1), + true, + address(123) + ); + LiquidityManager remoteRebalancer = new LiquidityManager(s_l2Token, i_remoteChainSelector, remotePool, 0, FINANCE); + + // set rebalancer role on the pool. + remotePool.setRebalancer(address(remoteRebalancer)); + + // set up the cross chain rebalancer on "L1". + LiquidityManager.CrossChainRebalancerArgs[] memory args = new LiquidityManager.CrossChainRebalancerArgs[](1); + args[0] = ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: address(remoteRebalancer), + localBridge: s_bridgeAdapter, + remoteToken: address(s_l2Token), + remoteChainSelector: i_remoteChainSelector, + enabled: true + }); + + s_liquidityManager.setCrossChainRebalancers(args); + + // set up the cross chain rebalancer on "L2". + args[0] = ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: address(s_liquidityManager), + localBridge: remoteBridgeAdapter, + remoteToken: address(s_l1Token), + remoteChainSelector: i_localChainSelector, + enabled: true + }); + + remoteRebalancer.setCrossChainRebalancers(args); + + // deal some L1 tokens to the L1 bridge adapter so that it can send them to the rebalancer + // when the withdrawal gets finalized. + deal(address(s_l1Token), address(s_bridgeAdapter), AMOUNT); + // deal some L2 tokens to the remote token pool so that we can withdraw it when we rebalance. + deal(address(s_l2Token), address(remotePool), AMOUNT); + + uint256 nonce = 1; + uint64 maxSeqNum = type(uint64).max; + bytes memory bridgeSendReturnData = abi.encode(nonce); + bytes memory bridgeSpecificPayload = bytes(""); + vm.expectEmit(); + emit LiquidityRemoved(address(remoteRebalancer), AMOUNT); + vm.expectEmit(); + emit LiquidityTransferred( + maxSeqNum, + i_remoteChainSelector, + i_localChainSelector, + address(s_liquidityManager), + AMOUNT, + bridgeSpecificPayload, + bridgeSendReturnData + ); + vm.startPrank(FINANCE); + remoteRebalancer.rebalanceLiquidity(i_localChainSelector, AMOUNT, 0, bridgeSpecificPayload); + + // available liquidity has been moved to the remote bridge adapter from the token pool. + assertEq(s_l2Token.balanceOf(address(remoteBridgeAdapter)), AMOUNT, "remoteBridgeAdapter balance"); + assertEq(s_l2Token.balanceOf(address(remotePool)), 0, "remotePool balance"); + + // prove and finalize manually on the L1 bridge adapter. + // this should transfer the funds to the rebalancer. + MockL1BridgeAdapter.ProvePayload memory provePayload = MockL1BridgeAdapter.ProvePayload({nonce: nonce}); + MockL1BridgeAdapter.Payload memory payload = MockL1BridgeAdapter.Payload({ + action: MockL1BridgeAdapter.FinalizationAction.ProveWithdrawal, + data: abi.encode(provePayload) + }); + bool fundsAvailable = s_bridgeAdapter.finalizeWithdrawERC20( + address(0), + address(s_liquidityManager), + abi.encode(payload) + ); + assertFalse(fundsAvailable, "fundsAvailable must be false"); + MockL1BridgeAdapter.FinalizePayload memory finalizePayload = MockL1BridgeAdapter.FinalizePayload({ + nonce: nonce, + amount: AMOUNT + }); + payload = MockL1BridgeAdapter.Payload({ + action: MockL1BridgeAdapter.FinalizationAction.FinalizeWithdrawal, + data: abi.encode(finalizePayload) + }); + fundsAvailable = s_bridgeAdapter.finalizeWithdrawERC20( + address(0), + address(s_liquidityManager), + abi.encode(payload) + ); + assertTrue(fundsAvailable, "fundsAvailable must be true"); + + // available balance on the L1 bridge adapter has been moved to the rebalancer. + assertEq(s_l1Token.balanceOf(address(s_liquidityManager)), AMOUNT, "rebalancer balance 1"); + assertEq(s_l1Token.balanceOf(address(s_bridgeAdapter)), 0, "bridgeAdapter balance"); + + // try to finalize on L1 again + // bytes memory revertData = abi.encodeWithSelector(NonceAlreadyUsed.selector, nonce); + vm.expectEmit(); + emit FinalizationFailed( + maxSeqNum, + i_remoteChainSelector, + abi.encode(payload), + abi.encodeWithSelector(NonceAlreadyUsed.selector, nonce) + ); + vm.expectEmit(); + emit LiquidityAdded(address(s_liquidityManager), AMOUNT); + vm.expectEmit(); + emit LiquidityTransferred( + maxSeqNum, + i_remoteChainSelector, + i_localChainSelector, + address(s_liquidityManager), + AMOUNT, + abi.encode(payload), + bytes("") + ); + s_liquidityManager.receiveLiquidity(i_remoteChainSelector, AMOUNT, false, abi.encode(payload)); + + // available balance on the rebalancer has been injected into the token pool. + assertEq(s_l1Token.balanceOf(address(s_liquidityManager)), 0, "rebalancer balance 2"); + assertEq(s_l1Token.balanceOf(address(s_lockReleaseTokenPool)), AMOUNT, "lockReleaseTokenPool balance"); + } + + function test_rebalanceBetweenPools_MultiStageFinalization() external { + // set up a rebalancer on another chain, an "L2". + // note we use the L1 bridge adapter because it has the reverting logic + // when finalization is already done. + MockL1BridgeAdapter remoteBridgeAdapter = new MockL1BridgeAdapter(s_l2Token, false); + LockReleaseTokenPool remotePool = new LockReleaseTokenPool( + s_l2Token, + new address[](0), + address(1), + true, + address(123) + ); + LiquidityManager remoteRebalancer = new LiquidityManager(s_l2Token, i_remoteChainSelector, remotePool, 0, FINANCE); + + // set rebalancer role on the pool. + remotePool.setRebalancer(address(remoteRebalancer)); + + // set up the cross chain rebalancer on "L1". + LiquidityManager.CrossChainRebalancerArgs[] memory args = new LiquidityManager.CrossChainRebalancerArgs[](1); + args[0] = ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: address(remoteRebalancer), + localBridge: s_bridgeAdapter, + remoteToken: address(s_l2Token), + remoteChainSelector: i_remoteChainSelector, + enabled: true + }); + + s_liquidityManager.setCrossChainRebalancers(args); + + // set up the cross chain rebalancer on "L2". + args[0] = ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: address(s_liquidityManager), + localBridge: remoteBridgeAdapter, + remoteToken: address(s_l1Token), + remoteChainSelector: i_localChainSelector, + enabled: true + }); + + remoteRebalancer.setCrossChainRebalancers(args); + + // deal some L1 tokens to the L1 bridge adapter so that it can send them to the rebalancer + // when the withdrawal gets finalized. + deal(address(s_l1Token), address(s_bridgeAdapter), AMOUNT); + // deal some L2 tokens to the remote token pool so that we can withdraw it when we rebalance. + deal(address(s_l2Token), address(remotePool), AMOUNT); + + // initiate a send from remote rebalancer to s_liquidityManager. + uint256 nonce = 1; + uint64 maxSeqNum = type(uint64).max; + bytes memory bridgeSendReturnData = abi.encode(nonce); + bytes memory bridgeSpecificPayload = bytes(""); + vm.expectEmit(); + emit LiquidityRemoved(address(remoteRebalancer), AMOUNT); + vm.expectEmit(); + emit LiquidityTransferred( + maxSeqNum, + i_remoteChainSelector, + i_localChainSelector, + address(s_liquidityManager), + AMOUNT, + bridgeSpecificPayload, + bridgeSendReturnData + ); + vm.startPrank(FINANCE); + remoteRebalancer.rebalanceLiquidity(i_localChainSelector, AMOUNT, 0, bridgeSpecificPayload); + + // available liquidity has been moved to the remote bridge adapter from the token pool. + assertEq(s_l2Token.balanceOf(address(remoteBridgeAdapter)), AMOUNT, "remoteBridgeAdapter balance"); + assertEq(s_l2Token.balanceOf(address(remotePool)), 0, "remotePool balance"); + + // prove withdrawal on the L1 bridge adapter, through the rebalancer. + uint256 balanceBeforeProve = s_l1Token.balanceOf(address(s_lockReleaseTokenPool)); + MockL1BridgeAdapter.ProvePayload memory provePayload = MockL1BridgeAdapter.ProvePayload({nonce: nonce}); + MockL1BridgeAdapter.Payload memory payload = MockL1BridgeAdapter.Payload({ + action: MockL1BridgeAdapter.FinalizationAction.ProveWithdrawal, + data: abi.encode(provePayload) + }); + vm.expectEmit(); + emit FinalizationStepCompleted(maxSeqNum, i_remoteChainSelector, abi.encode(payload)); + s_liquidityManager.receiveLiquidity(i_remoteChainSelector, AMOUNT, false, abi.encode(payload)); + + // s_liquidityManager should have no tokens. + assertEq(s_l1Token.balanceOf(address(s_liquidityManager)), 0, "rebalancer balance 1"); + // balance of s_lockReleaseTokenPool should be unchanged since no liquidity got added yet. + assertEq( + s_l1Token.balanceOf(address(s_lockReleaseTokenPool)), + balanceBeforeProve, + "s_lockReleaseTokenPool balance should be unchanged" + ); + + // finalize withdrawal on the L1 bridge adapter, through the rebalancer. + MockL1BridgeAdapter.FinalizePayload memory finalizePayload = MockL1BridgeAdapter.FinalizePayload({ + nonce: nonce, + amount: AMOUNT + }); + payload = MockL1BridgeAdapter.Payload({ + action: MockL1BridgeAdapter.FinalizationAction.FinalizeWithdrawal, + data: abi.encode(finalizePayload) + }); + vm.expectEmit(); + emit LiquidityAdded(address(s_liquidityManager), AMOUNT); + vm.expectEmit(); + emit LiquidityTransferred( + maxSeqNum, + i_remoteChainSelector, + i_localChainSelector, + address(s_liquidityManager), + AMOUNT, + abi.encode(payload), + bytes("") + ); + s_liquidityManager.receiveLiquidity(i_remoteChainSelector, AMOUNT, false, abi.encode(payload)); + + // s_liquidityManager should have no tokens. + assertEq(s_l1Token.balanceOf(address(s_liquidityManager)), 0, "rebalancer balance 2"); + // balance of s_lockReleaseTokenPool should be updated + assertEq( + s_l1Token.balanceOf(address(s_lockReleaseTokenPool)), + balanceBeforeProve + AMOUNT, + "s_lockReleaseTokenPool balance should be updated" + ); + } + + function test_rebalanceBetweenPools_NativeRewrap() external { + // set up a rebalancer similar to the above on another chain, an "L2". + MockL1BridgeAdapter remoteBridgeAdapter = new MockL1BridgeAdapter(IERC20(address(s_l2Weth)), true); + LockReleaseTokenPool remotePool = new LockReleaseTokenPool( + IERC20(address(s_l2Weth)), + new address[](0), + address(1), + true, + address(123) + ); + LiquidityManager remoteRebalancer = new LiquidityManager( + IERC20(address(s_l2Weth)), + i_remoteChainSelector, + remotePool, + 0, + FINANCE + ); + + // set rebalancer role on the pool. + remotePool.setRebalancer(address(remoteRebalancer)); + + // set up the cross chain rebalancer on "L1". + LiquidityManager.CrossChainRebalancerArgs[] memory args = new LiquidityManager.CrossChainRebalancerArgs[](1); + args[0] = ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: address(remoteRebalancer), + localBridge: s_wethBridgeAdapter, + remoteToken: address(s_l2Weth), + remoteChainSelector: i_remoteChainSelector, + enabled: true + }); + + s_wethRebalancer.setCrossChainRebalancers(args); + + // set up the cross chain rebalancer on "L2". + args[0] = ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: address(s_wethRebalancer), + localBridge: remoteBridgeAdapter, + remoteToken: address(s_l1Weth), + remoteChainSelector: i_localChainSelector, + enabled: true + }); + + remoteRebalancer.setCrossChainRebalancers(args); + + // deal some ether to the L1 bridge adapter so that it can send them to the rebalancer + // when the withdrawal gets finalized. + vm.deal(address(s_wethBridgeAdapter), AMOUNT); + // deal some L2 tokens to the remote token pool so that we can withdraw it when we rebalance. + deal(address(s_l2Weth), address(remotePool), AMOUNT); + // deposit some eth to the weth contract on L2 from the remote bridge adapter + // so that the withdraw() call succeeds. + vm.deal(address(remoteBridgeAdapter), AMOUNT); + vm.startPrank(address(remoteBridgeAdapter)); + s_l2Weth.deposit{value: AMOUNT}(); + vm.stopPrank(); + + // switch to finance for the rest of the test to avoid reverts. + vm.startPrank(FINANCE); + + // initiate a send from remote rebalancer to s_wethRebalancer. + uint256 nonce = 1; + uint64 maxSeqNum = type(uint64).max; + bytes memory bridgeSendReturnData = abi.encode(nonce); + bytes memory bridgeSpecificPayload = bytes(""); + vm.expectEmit(); + emit LiquidityRemoved(address(remoteRebalancer), AMOUNT); + vm.expectEmit(); + emit LiquidityTransferred( + maxSeqNum, + i_remoteChainSelector, + i_localChainSelector, + address(s_wethRebalancer), + AMOUNT, + bridgeSpecificPayload, + bridgeSendReturnData + ); + remoteRebalancer.rebalanceLiquidity(i_localChainSelector, AMOUNT, 0, bridgeSpecificPayload); + + // available liquidity has been moved to the remote bridge adapter from the token pool. + assertEq(s_l2Weth.balanceOf(address(remoteBridgeAdapter)), AMOUNT, "remoteBridgeAdapter balance"); + assertEq(s_l2Weth.balanceOf(address(remotePool)), 0, "remotePool balance"); + + // prove withdrawal on the L1 bridge adapter, through the rebalancer. + uint256 balanceBeforeProve = s_l1Weth.balanceOf(address(s_wethLockReleaseTokenPool)); + MockL1BridgeAdapter.ProvePayload memory provePayload = MockL1BridgeAdapter.ProvePayload({nonce: nonce}); + MockL1BridgeAdapter.Payload memory payload = MockL1BridgeAdapter.Payload({ + action: MockL1BridgeAdapter.FinalizationAction.ProveWithdrawal, + data: abi.encode(provePayload) + }); + vm.expectEmit(); + emit FinalizationStepCompleted(maxSeqNum, i_remoteChainSelector, abi.encode(payload)); + s_wethRebalancer.receiveLiquidity(i_remoteChainSelector, AMOUNT, false, abi.encode(payload)); + + // s_wethRebalancer should have no tokens. + assertEq(s_l1Weth.balanceOf(address(s_wethRebalancer)), 0, "rebalancer balance 1"); + // balance of s_wethLockReleaseTokenPool should be unchanged since no liquidity got added yet. + assertEq( + s_l1Weth.balanceOf(address(s_wethLockReleaseTokenPool)), + balanceBeforeProve, + "s_wethLockReleaseTokenPool balance should be unchanged" + ); + + // finalize withdrawal on the L1 bridge adapter, through the rebalancer. + MockL1BridgeAdapter.FinalizePayload memory finalizePayload = MockL1BridgeAdapter.FinalizePayload({ + nonce: nonce, + amount: AMOUNT + }); + payload = MockL1BridgeAdapter.Payload({ + action: MockL1BridgeAdapter.FinalizationAction.FinalizeWithdrawal, + data: abi.encode(finalizePayload) + }); + vm.expectEmit(); + emit LiquidityAdded(address(s_wethRebalancer), AMOUNT); + vm.expectEmit(); + emit LiquidityTransferred( + maxSeqNum, + i_remoteChainSelector, + i_localChainSelector, + address(s_wethRebalancer), + AMOUNT, + abi.encode(payload), + bytes("") + ); + s_wethRebalancer.receiveLiquidity(i_remoteChainSelector, AMOUNT, true, abi.encode(payload)); + + // s_wethRebalancer should have no tokens. + assertEq(s_l1Weth.balanceOf(address(s_wethRebalancer)), 0, "rebalancer balance 2"); + // s_wethRebalancer should have no native tokens. + assertEq(address(s_wethRebalancer).balance, 0, "rebalancer native balance should be zero"); + // balance of s_wethLockReleaseTokenPool should be updated + assertEq( + s_l1Weth.balanceOf(address(s_wethLockReleaseTokenPool)), + balanceBeforeProve + AMOUNT, + "s_wethLockReleaseTokenPool balance should be updated" + ); + } + + // Reverts + + function test_InsufficientLiquidityReverts() external { + s_liquidityManager.setMinimumLiquidity(3); + deal(address(s_l1Token), address(s_lockReleaseTokenPool), AMOUNT); + vm.expectRevert(abi.encodeWithSelector(LiquidityManager.InsufficientLiquidity.selector, AMOUNT, AMOUNT, 3)); + + vm.startPrank(FINANCE); + s_liquidityManager.rebalanceLiquidity(0, AMOUNT, 0, bytes("")); + } + + function test_InvalidRemoteChainReverts() external { + deal(address(s_l1Token), address(s_lockReleaseTokenPool), AMOUNT); + + vm.expectRevert(abi.encodeWithSelector(LiquidityManager.InvalidRemoteChain.selector, i_remoteChainSelector)); + + vm.startPrank(FINANCE); + s_liquidityManager.rebalanceLiquidity(i_remoteChainSelector, AMOUNT, 0, bytes("")); + } +} + +contract LiquidityManager_setCrossChainRebalancer is LiquidityManagerSetup { + event CrossChainRebalancerSet( + uint64 indexed remoteChainSelector, + IBridgeAdapter localBridge, + address remoteToken, + address remoteRebalancer, + bool enabled + ); + + function test_setCrossChainRebalancerSuccess() external { + address newRebalancer = address(23892423); + uint64 remoteChainSelector = 12301293; + + uint64[] memory supportedChains = s_liquidityManager.getSupportedDestChains(); + assertEq(supportedChains.length, 0); + + LiquidityManager.CrossChainRebalancerArgs[] memory args = new LiquidityManager.CrossChainRebalancerArgs[](1); + args[0] = ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: newRebalancer, + localBridge: s_bridgeAdapter, + remoteToken: address(190490124908), + remoteChainSelector: remoteChainSelector, + enabled: true + }); + + vm.expectEmit(); + emit CrossChainRebalancerSet( + remoteChainSelector, + args[0].localBridge, + args[0].remoteToken, + newRebalancer, + args[0].enabled + ); + + s_liquidityManager.setCrossChainRebalancers(args); + + assertEq(s_liquidityManager.getCrossChainRebalancer(remoteChainSelector).remoteRebalancer, newRebalancer); + + LiquidityManager.CrossChainRebalancerArgs[] memory got = s_liquidityManager.getAllCrossChainRebalancers(); + assertEq(got.length, 1); + assertEq(got[0].remoteRebalancer, args[0].remoteRebalancer); + assertEq(address(got[0].localBridge), address(args[0].localBridge)); + assertEq(got[0].remoteToken, args[0].remoteToken); + assertEq(got[0].remoteChainSelector, args[0].remoteChainSelector); + assertEq(got[0].enabled, args[0].enabled); + + supportedChains = s_liquidityManager.getSupportedDestChains(); + assertEq(supportedChains.length, 1); + assertEq(supportedChains[0], remoteChainSelector); + + address anotherRebalancer = address(123); + args[0].remoteRebalancer = anotherRebalancer; + + vm.expectEmit(); + emit CrossChainRebalancerSet( + remoteChainSelector, + args[0].localBridge, + args[0].remoteToken, + anotherRebalancer, + args[0].enabled + ); + + s_liquidityManager.setCrossChainRebalancer(args[0]); + + assertEq(s_liquidityManager.getCrossChainRebalancer(remoteChainSelector).remoteRebalancer, anotherRebalancer); + + supportedChains = s_liquidityManager.getSupportedDestChains(); + assertEq(supportedChains.length, 1); + assertEq(supportedChains[0], remoteChainSelector); + } + + function test_ZeroChainSelectorReverts() external { + LiquidityManager.CrossChainRebalancerArgs memory arg = ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: address(9), + localBridge: s_bridgeAdapter, + remoteToken: address(190490124908), + remoteChainSelector: 0, + enabled: true + }); + + vm.expectRevert(LiquidityManager.ZeroChainSelector.selector); + + s_liquidityManager.setCrossChainRebalancer(arg); + } + + function test_ZeroAddressReverts() external { + LiquidityManager.CrossChainRebalancerArgs memory arg = ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: address(0), + localBridge: s_bridgeAdapter, + remoteToken: address(190490124908), + remoteChainSelector: 123, + enabled: true + }); + + vm.expectRevert(LiquidityManager.ZeroAddress.selector); + + s_liquidityManager.setCrossChainRebalancer(arg); + + arg.remoteRebalancer = address(9); + arg.localBridge = IBridgeAdapter(address(0)); + + vm.expectRevert(LiquidityManager.ZeroAddress.selector); + + s_liquidityManager.setCrossChainRebalancer(arg); + + arg.localBridge = s_bridgeAdapter; + arg.remoteToken = address(0); + + vm.expectRevert(LiquidityManager.ZeroAddress.selector); + + s_liquidityManager.setCrossChainRebalancer(arg); + } + + function test_OnlyOwnerReverts() external { + vm.stopPrank(); + + vm.expectRevert("Only callable by owner"); + + // Test the entrypoint that takes a list + s_liquidityManager.setCrossChainRebalancers(new LiquidityManager.CrossChainRebalancerArgs[](0)); + + vm.expectRevert("Only callable by owner"); + + // Test the entrypoint that takes a single item + s_liquidityManager.setCrossChainRebalancer( + ILiquidityManager.CrossChainRebalancerArgs({ + remoteRebalancer: address(9), + localBridge: s_bridgeAdapter, + remoteToken: address(190490124908), + remoteChainSelector: 124, + enabled: true + }) + ); + } +} + +contract LiquidityManager_setLocalLiquidityContainer is LiquidityManagerSetup { + event LiquidityContainerSet(address indexed newLiquidityContainer); + + function test_setLocalLiquidityContainerSuccess() external { + LockReleaseTokenPool newPool = new LockReleaseTokenPool( + s_l1Token, + new address[](0), + address(1), + true, + address(123) + ); + + vm.expectEmit(); + emit LiquidityContainerSet(address(newPool)); + + s_liquidityManager.setLocalLiquidityContainer(newPool); + + assertEq(s_liquidityManager.getLocalLiquidityContainer(), address(newPool)); + } + + function test_OnlyOwnerReverts() external { + vm.stopPrank(); + + vm.expectRevert("Only callable by owner"); + + s_liquidityManager.setLocalLiquidityContainer(LockReleaseTokenPool(address(1))); + } + + function test_ReverstWhen_CalledWithTheZeroAddress() external { + vm.expectRevert(LiquidityManager.ZeroAddress.selector); + s_liquidityManager.setLocalLiquidityContainer(LockReleaseTokenPool(address(0))); + } +} + +contract LiquidityManager_setMinimumLiquidity is LiquidityManagerSetup { + event MinimumLiquiditySet(uint256 oldBalance, uint256 newBalance); + + function test_setMinimumLiquiditySuccess() external { + vm.expectEmit(); + emit MinimumLiquiditySet(uint256(0), uint256(1000)); + s_liquidityManager.setMinimumLiquidity(1000); + assertEq(s_liquidityManager.getMinimumLiquidity(), uint256(1000)); + } + + function test_OnlyOwnerReverts() external { + vm.stopPrank(); + vm.expectRevert("Only callable by owner"); + s_liquidityManager.setMinimumLiquidity(uint256(1000)); + } +} + +contract LiquidityManager_setFinanceRole is LiquidityManagerSetup { + event MinimumLiquiditySet(uint256 oldBalance, uint256 newBalance); + + function test_setFinanceRoleSuccess() external { + vm.expectEmit(); + address newFinanceRole = makeAddr("newFinanceRole"); + assertEq(s_liquidityManager.getFinanceRole(), FINANCE); + emit FinanceRoleSet(newFinanceRole); + s_liquidityManager.setFinanceRole(newFinanceRole); + assertEq(s_liquidityManager.getFinanceRole(), newFinanceRole); + } + + function test_OnlyOwnerReverts() external { + vm.stopPrank(); + vm.expectRevert("Only callable by owner"); + s_liquidityManager.setFinanceRole(address(1)); + } +} + +contract LiquidityManager_withdrawNative is LiquidityManagerSetup { + event NativeWithdrawn(uint256 amount, address destination); + + address private receiver = makeAddr("receiver"); + + function setUp() public override { + super.setUp(); + vm.deal(address(s_liquidityManager), 1); + } + + function test_withdrawNative_success() external { + assertEq(receiver.balance, 0); + vm.expectEmit(); + emit NativeWithdrawn(1, receiver); + vm.startPrank(FINANCE); + s_liquidityManager.withdrawNative(1, payable(receiver)); + assertEq(receiver.balance, 1); + } + + function test_OnlyFinanceRoleReverts() external { + vm.stopPrank(); + vm.expectRevert(LiquidityManager.OnlyFinanceRole.selector); + s_liquidityManager.withdrawNative(1, payable(receiver)); + } +} + +contract LiquidityManager_receive is LiquidityManagerSetup { + event NativeDeposited(uint256 amount, address depositor); + + address private depositor = makeAddr("depositor"); + + function test_receive_success() external { + vm.deal(depositor, 100); + uint256 before = address(s_liquidityManager).balance; + vm.expectEmit(); + emit NativeDeposited(100, depositor); + vm.startPrank(depositor); + payable(address(s_liquidityManager)).transfer(100); + assertEq(address(s_liquidityManager).balance, before + 100); + } +} + +contract LiquidityManager_withdrawERC20 is LiquidityManagerSetup { + function test_withdrawERC20Success() external { + uint256 amount = 100; + deal(address(s_otherToken), address(s_liquidityManager), amount); + assertEq(s_otherToken.balanceOf(address(1)), 0); + assertEq(s_otherToken.balanceOf(address(s_liquidityManager)), amount); + vm.startPrank(FINANCE); + s_liquidityManager.withdrawERC20(address(s_otherToken), amount, address(1)); + assertEq(s_otherToken.balanceOf(address(1)), amount); + assertEq(s_otherToken.balanceOf(address(s_liquidityManager)), 0); + } + + function test_withdrawERC20Reverts() external { + uint256 amount = 100; + deal(address(s_otherToken), address(s_liquidityManager), amount); + vm.startPrank(STRANGER); + vm.expectRevert(LiquidityManager.OnlyFinanceRole.selector); + s_liquidityManager.withdrawERC20(address(s_otherToken), amount, address(1)); + } +} diff --git a/contracts/src/v0.8/liquiditymanager/test/LiquidityManagerBaseTest.t.sol b/contracts/src/v0.8/liquiditymanager/test/LiquidityManagerBaseTest.t.sol new file mode 100644 index 0000000000..128a03f255 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/test/LiquidityManagerBaseTest.t.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {Test} from "forge-std/Test.sol"; + +import {WETH9} from "../../ccip/test/WETH9.sol"; + +import {ERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/ERC20.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract LiquidityManagerBaseTest is Test { + // ERC20 events + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + + IERC20 internal s_l1Token; + IERC20 internal s_l2Token; + IERC20 internal s_otherToken; + WETH9 internal s_l1Weth; + WETH9 internal s_l2Weth; + + uint64 internal immutable i_localChainSelector = 1234; + uint64 internal immutable i_remoteChainSelector = 9876; + + address internal constant FINANCE = address(0x00000fffffffffffffffffffff); + address internal constant OWNER = address(0x00000078772732723782873283); + address internal constant STRANGER = address(0x00000999999911111111222222); + + function setUp() public virtual { + s_l1Token = new ERC20("l1", "L1"); + s_l2Token = new ERC20("l2", "L2"); + s_otherToken = new ERC20("other", "OTHER"); + + s_l1Weth = new WETH9(); + s_l2Weth = new WETH9(); + + vm.startPrank(OWNER); + + vm.label(FINANCE, "FINANCE"); + vm.label(OWNER, "OWNER"); + vm.label(STRANGER, "STRANGER"); + } +} diff --git a/contracts/src/v0.8/liquiditymanager/test/bridge-adapters/ArbitrumL1BridgeAdapter.t.sol b/contracts/src/v0.8/liquiditymanager/test/bridge-adapters/ArbitrumL1BridgeAdapter.t.sol new file mode 100644 index 0000000000..8afea2d680 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/test/bridge-adapters/ArbitrumL1BridgeAdapter.t.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IWrappedNative} from "../../../ccip/interfaces/IWrappedNative.sol"; + +import {ArbitrumL1BridgeAdapter, IOutbox} from "../../bridge-adapters/ArbitrumL1BridgeAdapter.sol"; +import "forge-std/Test.sol"; + +import {IL1GatewayRouter} from "@arbitrum/token-bridge-contracts/contracts/tokenbridge/ethereum/gateway/IL1GatewayRouter.sol"; +import {IGatewayRouter} from "@arbitrum/token-bridge-contracts/contracts/tokenbridge/libraries/gateway/IGatewayRouter.sol"; +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +//contract ArbitrumL1BridgeAdapterSetup is Test { +// uint256 internal mainnetFork; +// uint256 internal arbitrumFork; +// +// string internal constant MAINNET_RPC_URL = ""; +// +// address internal constant L1_GATEWAY_ROUTER = 0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef; +// address internal constant L1_ERC20_GATEWAY = 0xa3A7B6F88361F48403514059F1F16C8E78d60EeC; +// address internal constant L1_INBOX = 0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f; +// // inbox 0x5aED5f8A1e3607476F1f81c3d8fe126deB0aFE94? +// address internal constant L1_OUTBOX = 0x0B9857ae2D4A3DBe74ffE1d7DF045bb7F96E4840; +// +// IERC20 internal constant L1_LINK = IERC20(0x514910771AF9Ca656af840dff83E8264EcF986CA); +// IWrappedNative internal constant L1_WRAPPED_NATIVE = IWrappedNative(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); +// +// address internal constant L2_GATEWAY_ROUTER = 0x5288c571Fd7aD117beA99bF60FE0846C4E84F933; +// address internal constant L2_ETH_WITHDRAWAL_PRECOMPILE = 0x0000000000000000000000000000000000000064; +// +// IERC20 internal constant L2_LINK = IERC20(0xf97f4df75117a78c1A5a0DBb814Af92458539FB4); +// IWrappedNative internal constant L2_WRAPPED_NATIVE = IWrappedNative(0x82aF49447D8a07e3bd95BD0d56f35241523fBab1); +// +// ArbitrumL1BridgeAdapter internal s_l1BridgeAdapter; +// +// uint256 internal constant TOKEN_BALANCE = 10e18; +// address internal constant OWNER = address(0xdead); +// +// function setUp() public { +// vm.startPrank(OWNER); +// +// mainnetFork = vm.createFork(MAINNET_RPC_URL); +// vm.selectFork(mainnetFork); +// +// s_l1BridgeAdapter = new ArbitrumL1BridgeAdapter( +// IL1GatewayRouter(L1_GATEWAY_ROUTER), +// IOutbox(L1_OUTBOX), +// L1_ERC20_GATEWAY +// ); +// +// deal(address(L1_LINK), OWNER, TOKEN_BALANCE); +// deal(address(L1_WRAPPED_NATIVE), OWNER, TOKEN_BALANCE); +// +// vm.label(OWNER, "Owner"); +// vm.label(L1_GATEWAY_ROUTER, "L1GatewayRouter"); +// vm.label(L1_ERC20_GATEWAY, "L1 ERC20 Gateway"); +// } +//} +// +//contract ArbitrumL1BridgeAdapter_sendERC20 is ArbitrumL1BridgeAdapterSetup { +// event TransferRouted(address indexed token, address indexed _userFrom, address indexed _userTo, address gateway); +// +// function test_sendERC20Success() public { +// L1_LINK.approve(address(s_l1BridgeAdapter), TOKEN_BALANCE); +// +// vm.expectEmit(); +// emit TransferRouted(address(L1_LINK), address(s_l1BridgeAdapter), OWNER, L1_ERC20_GATEWAY); +// +// uint256 expectedCost = s_l1BridgeAdapter.MAX_GAS() * +// s_l1BridgeAdapter.GAS_PRICE_BID() + +// s_l1BridgeAdapter.MAX_SUBMISSION_COST(); +// +// s_l1BridgeAdapter.sendERC20{value: expectedCost}(address(L1_LINK), OWNER, OWNER, TOKEN_BALANCE); +// } +// +// function test_BridgeFeeTooLowReverts() public { +// L1_LINK.approve(address(s_l1BridgeAdapter), TOKEN_BALANCE); +// uint256 expectedCost = s_l1BridgeAdapter.MAX_GAS() * +// s_l1BridgeAdapter.GAS_PRICE_BID() + +// s_l1BridgeAdapter.MAX_SUBMISSION_COST(); +// +// vm.expectRevert( +// abi.encodeWithSelector(ArbitrumL1BridgeAdapter.InsufficientEthValue.selector, expectedCost, expectedCost - 1) +// ); +// +// s_l1BridgeAdapter.sendERC20{value: expectedCost - 1}(address(L1_LINK), OWNER, OWNER, TOKEN_BALANCE); +// } +// +// function test_noApprovalReverts() public { +// uint256 expectedCost = s_l1BridgeAdapter.MAX_GAS() * +// s_l1BridgeAdapter.GAS_PRICE_BID() + +// s_l1BridgeAdapter.MAX_SUBMISSION_COST(); +// +// vm.expectRevert("SafeERC20: low-level call failed"); +// +// s_l1BridgeAdapter.sendERC20{value: expectedCost}(address(L1_LINK), OWNER, OWNER, TOKEN_BALANCE); +// } +//} diff --git a/contracts/src/v0.8/liquiditymanager/test/bridge-adapters/ArbitrumL2BridgeAdapter.t.sol b/contracts/src/v0.8/liquiditymanager/test/bridge-adapters/ArbitrumL2BridgeAdapter.t.sol new file mode 100644 index 0000000000..e34ff0480c --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/test/bridge-adapters/ArbitrumL2BridgeAdapter.t.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IWrappedNative} from "../../../ccip/interfaces/IWrappedNative.sol"; + +import {ArbitrumL2BridgeAdapter, IL2GatewayRouter} from "../../bridge-adapters/ArbitrumL2BridgeAdapter.sol"; +import "forge-std/Test.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +//contract ArbitrumL2BridgeAdapterSetup is Test { +// uint256 internal arbitrumFork; +// +// string internal constant ARBITRUM_RPC_URL = ""; +// +// address internal constant L2_GATEWAY_ROUTER = 0x5288c571Fd7aD117beA99bF60FE0846C4E84F933; +// address internal constant L2_ETH_WITHDRAWAL_PRECOMPILE = 0x0000000000000000000000000000000000000064; +// +// IERC20 internal constant L1_LINK = IERC20(0x514910771AF9Ca656af840dff83E8264EcF986CA); +// IERC20 internal constant L2_LINK = IERC20(0xf97f4df75117a78c1A5a0DBb814Af92458539FB4); +// IWrappedNative internal constant L2_WRAPPED_NATIVE = IWrappedNative(0x82aF49447D8a07e3bd95BD0d56f35241523fBab1); +// +// uint256 internal constant TOKEN_BALANCE = 10e18; +// address internal constant OWNER = address(0xdead); +// +// ArbitrumL2BridgeAdapter internal s_l2BridgeAdapter; +// +// function setUp() public { +// vm.startPrank(OWNER); +// +// arbitrumFork = vm.createFork(ARBITRUM_RPC_URL); +// +// vm.selectFork(arbitrumFork); +// s_l2BridgeAdapter = new ArbitrumL2BridgeAdapter(IL2GatewayRouter(L2_GATEWAY_ROUTER)); +// deal(address(L2_LINK), OWNER, TOKEN_BALANCE); +// deal(address(L2_WRAPPED_NATIVE), OWNER, TOKEN_BALANCE); +// +// vm.label(OWNER, "Owner"); +// vm.label(L2_GATEWAY_ROUTER, "L2GatewayRouterProxy"); +// vm.label(0xe80eb0238029333e368e0bDDB7acDf1b9cb28278, "L2GatewayRouter"); +// vm.label(L2_ETH_WITHDRAWAL_PRECOMPILE, "Precompile: ArbSys"); +// } +//} +// +//contract ArbitrumL2BridgeAdapter_sendERC20 is ArbitrumL2BridgeAdapterSetup { +// function test_sendERC20Success() public { +// L2_LINK.approve(address(s_l2BridgeAdapter), TOKEN_BALANCE); +// +// s_l2BridgeAdapter.sendERC20(address(L1_LINK), address(L2_LINK), OWNER, TOKEN_BALANCE); +// } +//} diff --git a/contracts/src/v0.8/liquiditymanager/test/bridge-adapters/OptimismL1BridgeAdapter.t.sol b/contracts/src/v0.8/liquiditymanager/test/bridge-adapters/OptimismL1BridgeAdapter.t.sol new file mode 100644 index 0000000000..cface1d506 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/test/bridge-adapters/OptimismL1BridgeAdapter.t.sol @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import "forge-std/Test.sol"; + +import {IWrappedNative} from "../../../ccip/interfaces/IWrappedNative.sol"; +import {WETH9} from "../../../ccip/test/WETH9.sol"; +import {OptimismL1BridgeAdapter} from "../../bridge-adapters/OptimismL1BridgeAdapter.sol"; +import {Types} from "../../interfaces/optimism/Types.sol"; +import {IOptimismPortal} from "../../interfaces/optimism/IOptimismPortal.sol"; + +import {IL1StandardBridge} from "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract OptimismL1BridgeAdapterSetup is Test { + // addresses below are fake + address internal constant L1_STANDARD_BRIDGE = address(1234); + address internal constant OP_PORTAL = address(4567); + address internal constant OWNER = address(0xdead); + + OptimismL1BridgeAdapter internal s_adapter; + + function setUp() public { + vm.startPrank(OWNER); + + // deploy wrapped native + WETH9 weth = new WETH9(); + + // deploy bridge adapter + s_adapter = new OptimismL1BridgeAdapter( + IL1StandardBridge(L1_STANDARD_BRIDGE), + IWrappedNative(address(weth)), + IOptimismPortal(OP_PORTAL) + ); + } +} + +contract OptimismL1BridgeAdapter_finalizeWithdrawERC20 is OptimismL1BridgeAdapterSetup { + function testfinalizeWithdrawERC20proveWithdrawalSuccess() public { + // prepare payload + OptimismL1BridgeAdapter.OptimismProveWithdrawalPayload memory provePayload = OptimismL1BridgeAdapter + .OptimismProveWithdrawalPayload({ + withdrawalTransaction: Types.WithdrawalTransaction({ + nonce: 1, + sender: address(0xdead), + target: address(0xbeef), + value: 1234, + gasLimit: 4567, + data: hex"deadbeef" + }), + l2OutputIndex: 1234, + outputRootProof: Types.OutputRootProof({ + version: bytes32(0), + stateRoot: bytes32(uint256(500)), + messagePasserStorageRoot: bytes32(uint256(600)), + latestBlockhash: bytes32(uint256(700)) + }), + withdrawalProof: new bytes[](0) + }); + OptimismL1BridgeAdapter.FinalizeWithdrawERC20Payload memory payload; + payload.action = OptimismL1BridgeAdapter.FinalizationAction.ProveWithdrawal; + payload.data = abi.encode(provePayload); + + bytes memory encodedPayload = abi.encode(payload); + + // mock out call to optimism portal + vm.mockCall( + OP_PORTAL, + abi.encodeWithSelector( + IOptimismPortal.proveWithdrawalTransaction.selector, + provePayload.withdrawalTransaction, + provePayload.l2OutputIndex, + provePayload.outputRootProof, + provePayload.withdrawalProof + ), + "" + ); + + // call finalizeWithdrawERC20 + s_adapter.finalizeWithdrawERC20(address(0), address(0), encodedPayload); + } + + function testfinalizeWithdrawERC20FinalizeSuccess() public { + // prepare payload + OptimismL1BridgeAdapter.OptimismFinalizationPayload memory finalizePayload = OptimismL1BridgeAdapter + .OptimismFinalizationPayload({ + withdrawalTransaction: Types.WithdrawalTransaction({ + nonce: 1, + sender: address(0xdead), + target: address(0xbeef), + value: 1234, + gasLimit: 4567, + data: hex"deadbeef" + }) + }); + OptimismL1BridgeAdapter.FinalizeWithdrawERC20Payload memory payload; + payload.action = OptimismL1BridgeAdapter.FinalizationAction.FinalizeWithdrawal; + payload.data = abi.encode(finalizePayload); + + bytes memory encodedPayload = abi.encode(payload); + + // mock out call to optimism portal + vm.mockCall( + OP_PORTAL, + abi.encodeWithSelector( + IOptimismPortal.finalizeWithdrawalTransaction.selector, + finalizePayload.withdrawalTransaction + ), + "" + ); + + // call finalizeWithdrawERC20 + s_adapter.finalizeWithdrawERC20(address(0), address(0), encodedPayload); + } + + function testFinalizeWithdrawERC20Reverts() public { + // case 1: badly encoded payload + bytes memory payload = abi.encode(1, 2, 3); + vm.expectRevert(); + s_adapter.finalizeWithdrawERC20(address(0), address(0), payload); + + // case 2: invalid action + // can't prepare the payload in solidity + payload = hex"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000"; + vm.expectRevert(); + s_adapter.finalizeWithdrawERC20(address(0), address(0), payload); + } +} diff --git a/contracts/src/v0.8/liquiditymanager/test/helpers/LiquidityManagerHelper.sol b/contracts/src/v0.8/liquiditymanager/test/helpers/LiquidityManagerHelper.sol new file mode 100644 index 0000000000..9b4654a07f --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/test/helpers/LiquidityManagerHelper.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {ILiquidityContainer} from "../../interfaces/ILiquidityContainer.sol"; + +import {LiquidityManager} from "../../LiquidityManager.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract LiquidityManagerHelper is LiquidityManager { + constructor( + IERC20 token, + uint64 localChainSelector, + ILiquidityContainer localLiquidityContainer, + uint256 targetTokens, + address finance + ) LiquidityManager(token, localChainSelector, localLiquidityContainer, targetTokens, finance) {} + + function report(bytes calldata rep, uint64 ocrSeqNum) external { + _report(rep, ocrSeqNum); + } +} diff --git a/contracts/src/v0.8/liquiditymanager/test/helpers/OCR3Helper.sol b/contracts/src/v0.8/liquiditymanager/test/helpers/OCR3Helper.sol new file mode 100644 index 0000000000..b2cd2ef371 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/test/helpers/OCR3Helper.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {OCR3Base} from "../../ocr/OCR3Base.sol"; + +contract OCR3Helper is OCR3Base { + function configDigestFromConfigData( + uint256 chainSelector, + address contractAddress, + uint64 configCount, + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) public pure returns (bytes32) { + return + _configDigestFromConfigData( + chainSelector, + contractAddress, + configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + } + + function _report(bytes calldata report, uint64 sequenceNumber) internal override {} + + function typeAndVersion() public pure override returns (string memory) { + return "OCR3BaseHelper 1.0.0"; + } + + function setLatestSeqNum(uint64 newSeqNum) external { + s_latestSequenceNumber = newSeqNum; + } +} diff --git a/contracts/src/v0.8/liquiditymanager/test/helpers/ReportEncoder.sol b/contracts/src/v0.8/liquiditymanager/test/helpers/ReportEncoder.sol new file mode 100644 index 0000000000..ff5e21f2e1 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/test/helpers/ReportEncoder.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {ILiquidityManager} from "../../interfaces/ILiquidityManager.sol"; + +/// @dev this is needed to generate the types to help encode the report offchain +abstract contract ReportEncoder is ILiquidityManager { + /// @dev exposed so that we can encode the report for OCR offchain + function exposeForEncoding(ILiquidityManager.LiquidityInstructions memory instructions) public pure {} +} diff --git a/contracts/src/v0.8/liquiditymanager/test/mocks/MockBridgeAdapter.sol b/contracts/src/v0.8/liquiditymanager/test/mocks/MockBridgeAdapter.sol new file mode 100644 index 0000000000..f51c60fcf3 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/test/mocks/MockBridgeAdapter.sol @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: BUSL-1.1 +// solhint-disable one-contract-per-file +pragma solidity ^0.8.0; + +import {IBridgeAdapter} from "../../interfaces/IBridge.sol"; +import {ILiquidityContainer} from "../../interfaces/ILiquidityContainer.sol"; +import {IWrappedNative} from "../../../ccip/interfaces/IWrappedNative.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +/// @notice Mock multiple-stage finalization bridge adapter implementation. +/// @dev Funds are only made available after both the prove and finalization steps are completed. +/// Sends the L1 tokens from the msg sender to address(this). +contract MockL1BridgeAdapter is IBridgeAdapter, ILiquidityContainer { + using SafeERC20 for IERC20; + + error InsufficientLiquidity(); + error NonceAlreadyUsed(uint256 nonce); + error InvalidFinalizationAction(); + error NonceNotProven(uint256 nonce); + error NativeSendFailed(); + + /// @notice Payload to "prove" the withdrawal. + /// @dev This is just a mock setup, there's no real proving. This is so that + /// we can test the multi-step finalization code path. + /// @param nonce the nonce emitted on the remote chain. + struct ProvePayload { + uint256 nonce; + } + + /// @notice Payload to "finalize" the withdrawal. + /// @dev This is just a mock setup, there's no real finalization. This is so that + /// we can test the multi-step finalization code path. + /// @param nonce the nonce emitted on the remote chain. + struct FinalizePayload { + uint256 nonce; + uint256 amount; + } + + /// @notice The finalization action to take. + /// @dev This emulates Optimism's two-step withdrawal process. + enum FinalizationAction { + ProveWithdrawal, + FinalizeWithdrawal + } + + /// @notice The payload to use for the bridgeSpecificPayload in the finalizeWithdrawERC20 function. + struct Payload { + FinalizationAction action; + bytes data; + } + + IERC20 internal immutable i_token; + uint256 internal s_nonce = 1; + mapping(uint256 => bool) internal s_nonceProven; + mapping(uint256 => bool) internal s_nonceFinalized; + + /// @dev For test cases where we want to send pure native upon finalizeWithdrawERC20 being called. + /// This is to emulate the behavior of bridges that do not bridge wrapped native. + bool internal immutable i_holdNative; + + constructor(IERC20 token, bool holdNative) { + i_token = token; + i_holdNative = holdNative; + } + + /// @dev The receive function is needed for IWrappedNative.withdraw() to work. + receive() external payable {} + + /// @notice Simply transferFrom msg.sender the tokens that are to be bridged to address(this). + function sendERC20( + address localToken, + address /* remoteToken */, + address /* remoteReceiver */, + uint256 amount, + bytes calldata /* bridgeSpecificPayload */ + ) external payable override returns (bytes memory) { + IERC20(localToken).transferFrom(msg.sender, address(this), amount); + + // If the flag to hold native is set we assume that i_token points to a WETH contract + // and withdraw native. + // This way we can transfer the raw native back to the sender upon finalization. + if (i_holdNative) { + IWrappedNative(address(i_token)).withdraw(amount); + } + + bytes memory encodedNonce = abi.encode(s_nonce++); + return encodedNonce; + } + + function getBridgeFeeInNative() external pure returns (uint256) { + return 0; + } + + function provideLiquidity(uint256 amount) external { + i_token.safeTransferFrom(msg.sender, address(this), amount); + emit LiquidityAdded(msg.sender, amount); + } + + function withdrawLiquidity(uint256 amount) external { + if (i_token.balanceOf(address(this)) < amount) revert InsufficientLiquidity(); + i_token.safeTransfer(msg.sender, amount); + emit LiquidityRemoved(msg.sender, amount); + } + + /// @dev for easy encoding offchain + function encodeProvePayload(ProvePayload memory payload) external pure {} + + function encodeFinalizePayload(FinalizePayload memory payload) external pure {} + + function encodePayload(Payload memory payload) external pure {} + + /// @dev Test setup is trusted, so just transfer the tokens to the localReceiver, + /// which should be the local rebalancer. Infer the amount from the bridgeSpecificPayload. + /// Note that this means that this bridge adapter will need to have some tokens, + /// however this is ok in a test environment since we will have infinite tokens. + /// @param localReceiver the address to transfer the tokens to. + /// @param bridgeSpecificPayload the payload to use for the finalization or proving. + /// @return true if the transfer was successful, revert otherwise. + function finalizeWithdrawERC20( + address /* remoteSender */, + address localReceiver, + bytes calldata bridgeSpecificPayload + ) external override returns (bool) { + Payload memory payload = abi.decode(bridgeSpecificPayload, (Payload)); + if (payload.action == FinalizationAction.ProveWithdrawal) { + return _proveWithdrawal(payload); + } else if (payload.action == FinalizationAction.FinalizeWithdrawal) { + return _finalizeWithdrawal(payload, localReceiver); + } + revert InvalidFinalizationAction(); + } + + function _proveWithdrawal(Payload memory payload) internal returns (bool) { + ProvePayload memory provePayload = abi.decode(payload.data, (ProvePayload)); + if (s_nonceProven[provePayload.nonce]) revert NonceAlreadyUsed(provePayload.nonce); + s_nonceProven[provePayload.nonce] = true; + return false; + } + + function _finalizeWithdrawal(Payload memory payload, address localReceiver) internal returns (bool) { + FinalizePayload memory finalizePayload = abi.decode(payload.data, (FinalizePayload)); + if (!s_nonceProven[finalizePayload.nonce]) revert NonceNotProven(finalizePayload.nonce); + if (s_nonceFinalized[finalizePayload.nonce]) revert NonceAlreadyUsed(finalizePayload.nonce); + s_nonceFinalized[finalizePayload.nonce] = true; + // re-entrancy prevented by nonce checks above. + _transferTokens(finalizePayload.amount, localReceiver); + return true; + } + + function _transferTokens(uint256 amount, address localReceiver) internal { + if (i_holdNative) { + (bool success, ) = payable(localReceiver).call{value: amount}(""); + if (!success) { + revert NativeSendFailed(); + } + } else { + i_token.safeTransfer(localReceiver, amount); + } + } +} + +/// @notice Mock L2 Bridge adapter +/// @dev Sends the L2 tokens from the msg sender to address(this) +contract MockL2BridgeAdapter is IBridgeAdapter { + /// @notice Simply transferFrom msg.sender the tokens that are to be bridged. + function sendERC20( + address localToken, + address /* remoteToken */, + address /* recipient */, + uint256 amount, + bytes calldata /* bridgeSpecificPayload */ + ) external payable override returns (bytes memory) { + IERC20(localToken).transferFrom(msg.sender, address(this), amount); + return ""; + } + + function getBridgeFeeInNative() external pure returns (uint256) { + return 0; + } + + // No-op + function finalizeWithdrawERC20( + address /* remoteSender */, + address /* localReceiver */, + bytes calldata /* bridgeSpecificData */ + ) external pure override returns (bool) { + return true; + } +} diff --git a/contracts/src/v0.8/liquiditymanager/test/mocks/NoOpOCR3.sol b/contracts/src/v0.8/liquiditymanager/test/mocks/NoOpOCR3.sol new file mode 100644 index 0000000000..5e771f0ccd --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/test/mocks/NoOpOCR3.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {OCR3Base} from "../../ocr/OCR3Base.sol"; + +// NoOpOCR3 is a mock implementation of the OCR3Base contract that does nothing +// This is so that we can generate gethwrappers for the contract and use the OCR3 ABI in +// Go code. +contract NoOpOCR3 is OCR3Base { + // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables + string public constant override typeAndVersion = "NoOpOCR3 1.0.0"; + + constructor() OCR3Base() {} + + function _report(bytes calldata, uint64) internal override { + // do nothing + } +} diff --git a/contracts/src/v0.8/liquiditymanager/test/ocr/OCR3Base.t.sol b/contracts/src/v0.8/liquiditymanager/test/ocr/OCR3Base.t.sol new file mode 100644 index 0000000000..840e90fb87 --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/test/ocr/OCR3Base.t.sol @@ -0,0 +1,337 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {OCR3Setup} from "./OCR3Setup.t.sol"; +import {OCR3Base} from "../../ocr/OCR3Base.sol"; +import {OCR3Helper} from "../helpers/OCR3Helper.sol"; + +contract OCR3BaseSetup is OCR3Setup { + event ConfigSet( + uint32 previousConfigBlockNumber, + bytes32 configDigest, + uint64 configCount, + address[] signers, + address[] transmitters, + uint8 f, + bytes onchainConfig, + uint64 offchainConfigVersion, + bytes offchainConfig + ); + + OCR3Helper internal s_OCR3Base; + + bytes32[] internal s_rs; + bytes32[] internal s_ss; + bytes32 internal s_rawVs; + + uint40 internal s_latestEpochAndRound; + + function setUp() public virtual override { + OCR3Setup.setUp(); + s_OCR3Base = new OCR3Helper(); + + bytes32 testReportDigest = getTestReportDigest(); + + bytes32[] memory rs = new bytes32[](2); + bytes32[] memory ss = new bytes32[](2); + uint8[] memory vs = new uint8[](2); + + // Calculate signatures + (vs[0], rs[0], ss[0]) = vm.sign(PRIVATE0, testReportDigest); + (vs[1], rs[1], ss[1]) = vm.sign(PRIVATE1, testReportDigest); + + s_rs = rs; + s_ss = ss; + s_rawVs = bytes32(bytes1(vs[0] - 27)) | (bytes32(bytes1(vs[1] - 27)) >> 8); + } + + function getBasicConfigDigest(uint8 f, uint64 currentConfigCount) internal view returns (bytes32) { + bytes memory configBytes = abi.encode(""); + return + s_OCR3Base.configDigestFromConfigData( + block.chainid, + address(s_OCR3Base), + currentConfigCount + 1, + s_valid_signers, + s_valid_transmitters, + f, + configBytes, + s_offchainConfigVersion, + configBytes + ); + } + + function getTestReportDigest() internal view returns (bytes32) { + bytes32 configDigest = getBasicConfigDigest(s_f, 0); + bytes32[3] memory reportContext = [configDigest, configDigest, configDigest]; + return keccak256(abi.encodePacked(keccak256(REPORT), reportContext)); + } + + function getBasicConfigDigest( + address contractAddress, + uint8 f, + uint64 currentConfigCount, + bytes memory onchainConfig + ) internal view returns (bytes32) { + return + s_OCR3Base.configDigestFromConfigData( + block.chainid, + contractAddress, + currentConfigCount + 1, + s_valid_signers, + s_valid_transmitters, + f, + onchainConfig, + s_offchainConfigVersion, + abi.encode("") + ); + } +} + +contract OCR3Base_transmit is OCR3BaseSetup { + bytes32 internal s_configDigest; + + function setUp() public virtual override { + OCR3BaseSetup.setUp(); + bytes memory configBytes = abi.encode(""); + + s_configDigest = getBasicConfigDigest(s_f, 0); + s_OCR3Base.setOCR3Config( + s_valid_signers, + s_valid_transmitters, + s_f, + configBytes, + s_offchainConfigVersion, + configBytes + ); + } + + function testTransmit2SignersSuccess_gas() public { + vm.pauseGasMetering(); + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + + vm.startPrank(s_valid_transmitters[0]); + vm.resumeGasMetering(); + s_OCR3Base.transmit(reportContext, REPORT, s_rs, s_ss, s_rawVs); + } + + // Reverts + + function testNonIncreasingSequenceNumberReverts() public { + bytes32[3] memory reportContext = [s_configDigest, bytes32(uint256(0)) /* sequence number */, s_configDigest]; + + vm.expectRevert(abi.encodeWithSelector(OCR3Base.NonIncreasingSequenceNumber.selector, 0, 0)); + s_OCR3Base.transmit(reportContext, REPORT, s_rs, s_ss, s_rawVs); + } + + function testForkedChainReverts() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + + uint256 chain1 = block.chainid; + uint256 chain2 = chain1 + 1; + vm.chainId(chain2); + vm.expectRevert(abi.encodeWithSelector(OCR3Base.ForkedChain.selector, chain1, chain2)); + vm.startPrank(s_valid_transmitters[0]); + s_OCR3Base.transmit(reportContext, REPORT, s_rs, s_ss, s_rawVs); + } + + function testWrongNumberOfSignaturesReverts() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + + vm.expectRevert(OCR3Base.WrongNumberOfSignatures.selector); + s_OCR3Base.transmit(reportContext, REPORT, new bytes32[](0), new bytes32[](0), s_rawVs); + } + + function testConfigDigestMismatchReverts() public { + bytes32 configDigest; + bytes32[3] memory reportContext = [configDigest, bytes32(uint256(1)) /* sequence number */, configDigest]; + + vm.expectRevert(abi.encodeWithSelector(OCR3Base.ConfigDigestMismatch.selector, s_configDigest, configDigest)); + s_OCR3Base.transmit(reportContext, REPORT, new bytes32[](0), new bytes32[](0), s_rawVs); + } + + function testSignatureOutOfRegistrationReverts() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + + bytes32[] memory rs = new bytes32[](2); + bytes32[] memory ss = new bytes32[](1); + + vm.expectRevert(OCR3Base.SignaturesOutOfRegistration.selector); + s_OCR3Base.transmit(reportContext, REPORT, rs, ss, s_rawVs); + } + + function testUnAuthorizedTransmitterReverts() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + bytes32[] memory rs = new bytes32[](2); + bytes32[] memory ss = new bytes32[](2); + + vm.expectRevert(OCR3Base.UnauthorizedTransmitter.selector); + s_OCR3Base.transmit(reportContext, REPORT, rs, ss, s_rawVs); + } + + function testNonUniqueSignatureReverts() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + bytes32[] memory rs = s_rs; + bytes32[] memory ss = s_ss; + + rs[1] = rs[0]; + ss[1] = ss[0]; + // Need to reset the rawVs to be valid + bytes32 rawVs = bytes32(bytes1(uint8(28) - 27)) | (bytes32(bytes1(uint8(28) - 27)) >> 8); + + vm.startPrank(s_valid_transmitters[0]); + vm.expectRevert(OCR3Base.NonUniqueSignatures.selector); + s_OCR3Base.transmit(reportContext, REPORT, rs, ss, rawVs); + } + + function testUnauthorizedSignerReverts() public { + bytes32[3] memory reportContext = [s_configDigest, s_configDigest, s_configDigest]; + bytes32[] memory rs = new bytes32[](2); + rs[0] = s_configDigest; + bytes32[] memory ss = rs; + + vm.startPrank(s_valid_transmitters[0]); + vm.expectRevert(OCR3Base.UnauthorizedSigner.selector); + s_OCR3Base.transmit(reportContext, REPORT, rs, ss, s_rawVs); + } +} + +contract OCR3Base_setOCR3Config is OCR3BaseSetup { + function testSetConfigSuccess() public { + vm.pauseGasMetering(); + bytes memory configBytes = abi.encode(""); + uint32 configCount = 0; + + bytes32 configDigest = getBasicConfigDigest(s_f, configCount++); + + address[] memory transmitters = s_OCR3Base.getTransmitters(); + assertEq(0, transmitters.length); + + s_OCR3Base.setLatestSeqNum(3); + uint64 seqNum = s_OCR3Base.latestSequenceNumber(); + assertEq(seqNum, 3); + + vm.expectEmit(); + emit ConfigSet( + 0, + configDigest, + configCount, + s_valid_signers, + s_valid_transmitters, + s_f, + configBytes, + s_offchainConfigVersion, + configBytes + ); + + s_OCR3Base.setOCR3Config( + s_valid_signers, + s_valid_transmitters, + s_f, + configBytes, + s_offchainConfigVersion, + configBytes + ); + + transmitters = s_OCR3Base.getTransmitters(); + assertEq(s_valid_transmitters, transmitters); + + configDigest = getBasicConfigDigest(s_f, configCount++); + + seqNum = s_OCR3Base.latestSequenceNumber(); + assertEq(seqNum, 0); + + vm.expectEmit(); + emit ConfigSet( + uint32(block.number), + configDigest, + configCount, + s_valid_signers, + s_valid_transmitters, + s_f, + configBytes, + s_offchainConfigVersion, + configBytes + ); + vm.resumeGasMetering(); + s_OCR3Base.setOCR3Config( + s_valid_signers, + s_valid_transmitters, + s_f, + configBytes, + s_offchainConfigVersion, + configBytes + ); + } + + // Reverts + function testRepeatAddressReverts() public { + address[] memory signers = new address[](10); + signers[0] = address(1245678); + address[] memory transmitters = new address[](10); + transmitters[0] = signers[0]; + + vm.expectRevert(abi.encodeWithSelector(OCR3Base.InvalidConfig.selector, "repeated transmitter address")); + s_OCR3Base.setOCR3Config(signers, transmitters, 2, abi.encode(""), 100, abi.encode("")); + } + + function testSignerCannotBeZeroAddressReverts() public { + uint256 f = 1; + address[] memory signers = new address[](3 * f + 1); + address[] memory transmitters = new address[](3 * f + 1); + for (uint160 i = 0; i < 3 * f + 1; ++i) { + signers[i] = address(i + 1); + transmitters[i] = address(i + 1000); + } + + signers[0] = address(0); + + vm.expectRevert(OCR3Base.OracleCannotBeZeroAddress.selector); + s_OCR3Base.setOCR3Config(signers, transmitters, uint8(f), abi.encode(""), 100, abi.encode("")); + } + + function testTransmitterCannotBeZeroAddressReverts() public { + uint256 f = 1; + address[] memory signers = new address[](3 * f + 1); + address[] memory transmitters = new address[](3 * f + 1); + for (uint160 i = 0; i < 3 * f + 1; ++i) { + signers[i] = address(i + 1); + transmitters[i] = address(i + 1000); + } + + transmitters[0] = address(0); + + vm.expectRevert(OCR3Base.OracleCannotBeZeroAddress.selector); + s_OCR3Base.setOCR3Config(signers, transmitters, uint8(f), abi.encode(""), 100, abi.encode("")); + } + + function testOracleOutOfRegisterReverts() public { + address[] memory signers = new address[](10); + address[] memory transmitters = new address[](0); + + vm.expectRevert(abi.encodeWithSelector(OCR3Base.InvalidConfig.selector, "oracle addresses out of registration")); + s_OCR3Base.setOCR3Config(signers, transmitters, 2, abi.encode(""), 100, abi.encode("")); + } + + function testFTooHighReverts() public { + address[] memory signers = new address[](0); + uint8 f = 1; + + vm.expectRevert(abi.encodeWithSelector(OCR3Base.InvalidConfig.selector, "faulty-oracle f too high")); + s_OCR3Base.setOCR3Config(signers, new address[](0), f, abi.encode(""), 100, abi.encode("")); + } + + function testFMustBePositiveReverts() public { + uint8 f = 0; + + vm.expectRevert(abi.encodeWithSelector(OCR3Base.InvalidConfig.selector, "f must be positive")); + s_OCR3Base.setOCR3Config(new address[](0), new address[](0), f, abi.encode(""), 100, abi.encode("")); + } + + function testTooManySignersReverts() public { + address[] memory signers = new address[](32); + + vm.expectRevert(abi.encodeWithSelector(OCR3Base.InvalidConfig.selector, "too many signers")); + s_OCR3Base.setOCR3Config(signers, new address[](0), 0, abi.encode(""), 100, abi.encode("")); + } +} diff --git a/contracts/src/v0.8/liquiditymanager/test/ocr/OCR3Setup.t.sol b/contracts/src/v0.8/liquiditymanager/test/ocr/OCR3Setup.t.sol new file mode 100644 index 0000000000..ee60c58dcc --- /dev/null +++ b/contracts/src/v0.8/liquiditymanager/test/ocr/OCR3Setup.t.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import {LiquidityManagerBaseTest} from "../LiquidityManagerBaseTest.t.sol"; + +contract OCR3Setup is LiquidityManagerBaseTest { + // Signer private keys used for these test + uint256 internal constant PRIVATE0 = 0x7b2e97fe057e6de99d6872a2ef2abf52c9b4469bc848c2465ac3fcd8d336e81d; + uint256 internal constant PRIVATE1 = 0xab56160806b05ef1796789248e1d7f34a6465c5280899159d645218cd216cee6; + uint256 internal constant PRIVATE2 = 0x6ec7caa8406a49b76736602810e0a2871959fbbb675e23a8590839e4717f1f7f; + uint256 internal constant PRIVATE3 = 0x80f14b11da94ae7f29d9a7713ea13dc838e31960a5c0f2baf45ed458947b730a; + + address[] internal s_valid_signers; + address[] internal s_valid_transmitters; + + uint64 internal constant s_offchainConfigVersion = 3; + uint8 internal constant s_f = 1; + bytes internal constant REPORT = abi.encode("testReport"); + + function setUp() public virtual override { + LiquidityManagerBaseTest.setUp(); + + s_valid_transmitters = new address[](4); + for (uint160 i = 0; i < 4; ++i) { + s_valid_transmitters[i] = address(4 + i); + } + + s_valid_signers = new address[](4); + s_valid_signers[0] = vm.addr(PRIVATE0); //0xc110458BE52CaA6bB68E66969C3218A4D9Db0211 + s_valid_signers[1] = vm.addr(PRIVATE1); //0xc110a19c08f1da7F5FfB281dc93630923F8E3719 + s_valid_signers[2] = vm.addr(PRIVATE2); //0xc110fdF6e8fD679C7Cc11602d1cd829211A18e9b + s_valid_signers[3] = vm.addr(PRIVATE3); //0xc11028017c9b445B6bF8aE7da951B5cC28B326C0 + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol new file mode 100644 index 0000000000..4daefc5d4f --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.2) (utils/introspection/ERC165Checker.sol) + +pragma solidity ^0.8.0; + +import "./IERC165.sol"; + +/** + * @dev Library used to query support of an interface declared via {IERC165}. + * + * Note that these functions return the actual result of the query: they do not + * `revert` if an interface is not supported. It is up to the caller to decide + * what to do in these cases. + */ +library ERC165Checker { + // As per the EIP-165 spec, no interface should ever match 0xffffffff + bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; + + /** + * @dev Returns true if `account` supports the {IERC165} interface. + */ + function supportsERC165(address account) internal view returns (bool) { + // Any contract that implements ERC165 must explicitly indicate support of + // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid + return + supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) && + !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID); + } + + /** + * @dev Returns true if `account` supports the interface defined by + * `interfaceId`. Support for {IERC165} itself is queried automatically. + * + * See {IERC165-supportsInterface}. + */ + function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { + // query support of both ERC165 as per the spec and support of _interfaceId + return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId); + } + + /** + * @dev Returns a boolean array where each value corresponds to the + * interfaces passed in and whether they're supported or not. This allows + * you to batch check interfaces for a contract where your expectation + * is that some interfaces may not be supported. + * + * See {IERC165-supportsInterface}. + * + * _Available since v3.4._ + */ + function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) + internal + view + returns (bool[] memory) + { + // an array of booleans corresponding to interfaceIds and whether they're supported or not + bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); + + // query support of ERC165 itself + if (supportsERC165(account)) { + // query support of each interface in interfaceIds + for (uint256 i = 0; i < interfaceIds.length; i++) { + interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]); + } + } + + return interfaceIdsSupported; + } + + /** + * @dev Returns true if `account` supports all the interfaces defined in + * `interfaceIds`. Support for {IERC165} itself is queried automatically. + * + * Batch-querying can lead to gas savings by skipping repeated checks for + * {IERC165} support. + * + * See {IERC165-supportsInterface}. + */ + function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { + // query support of ERC165 itself + if (!supportsERC165(account)) { + return false; + } + + // query support of each interface in interfaceIds + for (uint256 i = 0; i < interfaceIds.length; i++) { + if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) { + return false; + } + } + + // all interfaces supported + return true; + } + + /** + * @notice Query if a contract implements an interface, does not check ERC165 support + * @param account The address of the contract to query for support of an interface + * @param interfaceId The interface identifier, as specified in ERC-165 + * @return true if the contract at account indicates support of the interface with + * identifier interfaceId, false otherwise + * @dev Assumes that account contains a contract that supports ERC165, otherwise + * the behavior of this method is undefined. This precondition can be checked + * with {supportsERC165}. + * + * Some precompiled contracts will falsely indicate support for a given interface, so caution + * should be exercised when using this function. + * + * Interface identification is specified in ERC-165. + */ + function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) { + // prepare call + bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId); + + // perform static call + bool success; + uint256 returnSize; + uint256 returnValue; + assembly { + success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) + returnSize := returndatasize() + returnValue := mload(0x00) + } + + return success && returnSize >= 0x20 && returnValue > 0; + } +} From 6b3f6e271ad32998ed81db4adecbf734b084195c Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:58:22 +0530 Subject: [PATCH 009/432] update tests Dockerfile to copy only required files (#13961) --- integration-tests/test.Dockerfile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/integration-tests/test.Dockerfile b/integration-tests/test.Dockerfile index fc6eefd650..2e928ab29f 100644 --- a/integration-tests/test.Dockerfile +++ b/integration-tests/test.Dockerfile @@ -1,10 +1,18 @@ ARG BASE_IMAGE ARG IMAGE_VERSION=latest -FROM ${BASE_IMAGE}:${IMAGE_VERSION} +FROM ${BASE_IMAGE}:${IMAGE_VERSION} AS build-env ARG SUITES=chaos migration performance reorg smoke soak benchmark COPY . testdir/ WORKDIR /go/testdir RUN /go/testdir/integration-tests/scripts/buildTests "${SUITES}" + +FROM ${BASE_IMAGE}:${IMAGE_VERSION} + +RUN mkdir -p /go/testdir/integration-tests/scripts +COPY --from=build-env /go/pkg /go/pkg +COPY --from=build-env /go/testdir/integration-tests/*.test /go/testdir/integration-tests/ +COPY --from=build-env /go/testdir/integration-tests/scripts /go/testdir/integration-tests/scripts/ + ENTRYPOINT ["/go/testdir/integration-tests/scripts/entrypoint"] From c4ffbfbf9c54881e3fb9a80538ddbb81b9101c4a Mon Sep 17 00:00:00 2001 From: Michael Fletcher <36506122+Fletch153@users.noreply.github.com> Date: Wed, 31 Jul 2024 12:33:33 +0100 Subject: [PATCH 010/432] Initial Impl of SBRV (#13813) * Initial Impl of SBRV * Generate wrappers/ABI * Removed ZeroAddress check for feemanager & AC * Update gethwrappers * Rename RewardManager=>DestinationRewardManager * Remove circular dependency between proxy and verifier * Fixes to init logic * Update gethwrappers * llo-feeds: v0.4.0 reward manager tests * Add check to remove assumption that feeManager cannot be nil * Generate * Fixed poolIdMismatch not being thrown * Fix logic error when looking up the activeDonConfig * Update gethwrappers * Update interface sanity checks when setting verifier * Add remaining interface functionality * Update gethwrappers * llo-feeds: verifier SetConfig tests * llo-feeds: adding verifier contract get methods for easier testing * adding rewards wire up for testing * incomeplte fix for test_setConfigWithAddressesAndWeightsAreSetCorrectly * llo-feeds: adjusting setConfig tests due to changes * llo-feeds: fee manager v0.4.0 tests: making v0.3.0 tests pass * llo-feeds: fee manager v0.4.0 tests: fee manager - adding test for PoolIdMismatch * llo-feeds: fee manager v0.4.0 tests: nits * llo-feeds: feeManager bulk reverts when PoolId is 0 * llo-feeds: feeManager tests revertOnSettingAnAddressZeroVerifier onlyCallableByOwnerReverts * llo-feeds: feeManager test poolIdsCannotBeZeroAddress * llo-feeds: rewardManager test_rewardsAreCorrectlySentToEachAssociatedPoolWhenVerifyingInBulk * llo-feeds: verifier proxy tests * llo-feeds: fixing DestinationProxy error handling * llo-feeds: fixing DestinationProxy test remove verifiercontract zero check * llo-feeds: remove interface checks for verifierProxy * llo-feeds: clean up setConfig tests from checking internal state * fix issue when processing rewards * Apply suggestions from code review * Update contracts/src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol * Update contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifierProxy.sol * llo-feeds: verifier proxy remove test test_setVerifierZeroVerifier * llo-feeds: tests for verify and verifyBulk * clean up * temporal fix for compile error * llo: v0.4.0 removing V1 report tests * better comments * llo-feeds: verify test test_rollingOutConfiguration * llo-feeds: verify test test_verifyFailsWhenReportIsOlderThanConfig * llo-feeds: verify test test_verifyFailsWhenReportIsOlderThanConfig * llo-feeds: tests for billing / billing bulk * fixing tests * fixing tests names * llo-feeds: fix proxy contract should send value in call to verify * llo-feeds: fix billing tests * squash me * llo-feeds: billing bulk verify tests * llo-feeds: clean up * llo-feeds: VerifierSetAccessControllerTest * llo-feeds: clean up * llo-feeds: extra proxy tests * Update contracts/src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol * Fix issue with oldest config verifying incorrectly * Fix issue with oldest config verifying incorrectly * llo-feeds: fix underflow and test_verifyFailsWhenReportIsOlderThanConfig * Update gethwrappers * Update gethwrappers * llo-feeds: DestinationVerifier setFeeManager tests * llo-feeds: Tests for Rewards and configs * llo-feeds: Tests for DestinationVerifier constructor * llo-feeds: reverse looping efficiently * Update contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifier.sol * Update gethwrappers * llo-feeds: fmt contract tests * llo-feeds: npx prettify contract tests * llo-feeds: npx prettify v0.4.0 contracts * se --Add ability to amend config array * Update gethwrappers * Fix issue with future timestamps * Update gethwrappers * Small fix * Fix broken tests * Update gethwrappers * llo-feeds: Tests setConfigWithActivationTime * llo-feeds: Tests setConfigWithActivationTime * llo-feeds: Tests VerifierRemoveLatestConfigTest * llo-feeds: fixing linter errors (unused imports) * llo-feeds: tests better filenaming * Improve upgradability of contracts * Update gethwrappers * Small fix when setting rewardManager * Update gethwrappers * Fix var name to honour same interface * Update gethwrappers * Improve getter consistency * Update gethwrappers * Fix comments & conventions * Update DON Config to camal case * Update gethwrappers * solhint + gas snapshot * prettier * Solhint fixes * Update gethwrappers * gas snapshot * Fixed gas issue * Gas snapshot * llo-feeds: testing multiple fee managers and verifiers * llo: fixing tests * Update contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestRewardsMultiVefifierFeeManager.t.sol Co-authored-by: msuchacz-cll <170782674+msuchacz-cll@users.noreply.github.com> * llo: v0.4.0 interfaces test * Fixed gas snaposhot * prettier * Generate --------- Co-authored-by: Sam Davies Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> Co-authored-by: David Przybilla Co-authored-by: ad0ll <20057155+ad0ll@users.noreply.github.com> Co-authored-by: msuchacz-cll <170782674+msuchacz-cll@users.noreply.github.com> --- .../gas-snapshots/llo-feeds.gas-snapshot | 241 +++ .../scripts/native_solc_compile_all_llo-feeds | 16 +- .../src/v0.8/llo-feeds/libraries/Common.sol | 46 + .../{ => libraries}/test/ByteUtilTest.t.sol | 2 +- .../llo-feeds/{ => v0.3.0}/FeeManager.sol | 16 +- .../llo-feeds/{ => v0.3.0}/RewardManager.sol | 10 +- .../v0.8/llo-feeds/{ => v0.3.0}/Verifier.sol | 8 +- .../llo-feeds/{ => v0.3.0}/VerifierProxy.sol | 10 +- .../{ => v0.3.0}/interfaces/IFeeManager.sol | 4 +- .../interfaces/IRewardManager.sol | 4 +- .../{ => v0.3.0}/interfaces/IVerifier.sol | 4 +- .../interfaces/IVerifierFeeManager.sol | 4 +- .../interfaces/IVerifierProxy.sol | 4 +- .../test/fee-manager/BaseFeeManager.t.sol | 6 +- .../test/fee-manager/FeeManager.general.t.sol | 0 .../FeeManager.getFeeAndReward.t.sol | 12 +- .../fee-manager/FeeManager.processFee.t.sol | 2 +- .../FeeManager.processFeeBulk.t.sol | 0 .../test/gas/Gas_VerifierTest.t.sol | 4 +- .../test/mocks/ErroredVerifier.sol | 31 +- .../test/mocks/ExposedVerifier.sol | 0 .../test/mocks/FeeManagerProxy.sol | 10 +- .../reward-manager/BaseRewardManager.t.sol | 6 +- .../reward-manager/RewardManager.claim.t.sol | 4 +- .../RewardManager.general.t.sol | 4 +- .../RewardManager.payRecipients.t.sol | 0 .../RewardManager.setRecipients.t.sol | 2 +- ...RewardManager.updateRewardRecipients.t.sol | 2 +- .../test/verifier/BaseVerifierTest.t.sol | 11 +- .../verifier/VerifierActivateConfigTest.t.sol | 2 +- .../verifier/VerifierDeactivateFeedTest.t.sol | 2 +- .../VerifierProxyConstructorTest.t.sol | 6 +- .../VerifierProxyInitializeVerifierTest.t.sol | 2 +- ...VerifierProxySetAccessControllerTest.t.sol | 2 +- .../VerifierProxySetVerifierTest.t.sol | 6 +- .../test/verifier/VerifierProxyTest.t.sol | 4 +- .../VerifierProxyUnsetVerifierTest.t.sol | 2 +- .../VerifierSetConfigFromSourceTest.t.sol | 2 +- .../test/verifier/VerifierSetConfigTest.t.sol | 4 +- .../test/verifier/VerifierTest.t.sol | 6 +- .../verifier/VerifierTestBillingReport.t.sol | 0 .../verifier/VerifierUnsetConfigTest.t.sol | 2 +- .../test/verifier/VerifierVerifyTest.t.sol | 10 +- .../v0.4.0/DestinationFeeManager.sol | 557 +++++ .../v0.4.0/DestinationRewardManager.sol | 336 ++++ .../llo-feeds/v0.4.0/DestinationVerifier.sol | 434 ++++ .../v0.4.0/DestinationVerifierProxy.sol | 79 + .../interfaces/IDestinationFeeManager.sol | 133 ++ .../interfaces/IDestinationRewardManager.sol | 75 + .../interfaces/IDestinationVerifier.sol | 98 + .../interfaces/IDestinationVerifierProxy.sol | 50 + .../BaseDestinationFeeManager.t.sol | 394 ++++ .../DestinationFeeManager.general.t.sol | 299 +++ ...estinationFeeManager.getFeeAndReward.t.sol | 606 ++++++ .../DestinationFeeManager.processFee.t.sol | 492 +++++ ...DestinationFeeManager.processFeeBulk.t.sol | 310 +++ .../test/mocks/DestinationFeeManagerProxy.sol | 24 + .../BaseDestinationRewardManager.t.sol | 264 +++ .../DestinationRewardManager.claim.t.sol | 790 ++++++++ .../DestinationRewardManager.general.t.sol | 99 + ...stinationRewardManager.payRecipients.t.sol | 194 ++ ...stinationRewardManager.setRecipients.t.sol | 148 ++ ...RewardManager.updateRewardRecipients.t.sol | 450 +++++ .../BaseDestinationVerifierTest.t.sol | 347 ++++ .../DestinationVerifierInterfacesTest.t.sol | 128 ++ .../DestinationVerifierProxyTest.t.sol | 38 + ...nationVerifierRemoveLatestConfigTest.t.sol | 126 ++ ...ationVerifierSetAccessControllerTest.t.sol | 33 + .../DestinationVerifierSetConfigTest.t.sol | 159 ++ ...DestinationVerifierSetFeeManagerTest.t.sol | 28 + .../verifier/DestinationVerifierTest.t.sol | 31 + ...DestinationVerifierTestBillingReport.t.sol | 189 ++ .../DestinationVerifierTestRewards.t.sol | 227 +++ ...erTestRewardsMultiVefifierFeeManager.t.sol | 141 ++ .../DestinationVerifierVerifyBulkTest.t.sol | 140 ++ .../DestinationVerifierVerifyTest.t.sol | 711 +++++++ .../destination_fee_manager.go | 1790 +++++++++++++++++ .../destination_reward_manager.go | 1434 +++++++++++++ .../destination_verifier.go | 1576 +++++++++++++++ .../destination_verifier_proxy.go | 676 +++++++ .../errored_verifier/errored_verifier.go | 4 +- ...rapper-dependency-versions-do-not-edit.txt | 6 +- core/gethwrappers/llo-feeds/go_generate.go | 5 + 83 files changed, 14025 insertions(+), 109 deletions(-) rename contracts/src/v0.8/llo-feeds/{ => libraries}/test/ByteUtilTest.t.sol (99%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/FeeManager.sol (96%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/RewardManager.sol (96%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/Verifier.sol (98%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/VerifierProxy.sol (95%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/interfaces/IFeeManager.sol (94%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/interfaces/IRewardManager.sol (94%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/interfaces/IVerifier.sol (97%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/interfaces/IVerifierFeeManager.sol (88%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/interfaces/IVerifierProxy.sol (95%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/fee-manager/BaseFeeManager.t.sol (98%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/fee-manager/FeeManager.general.t.sol (100%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/fee-manager/FeeManager.getFeeAndReward.t.sol (98%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/fee-manager/FeeManager.processFee.t.sol (99%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/fee-manager/FeeManager.processFeeBulk.t.sol (100%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/gas/Gas_VerifierTest.t.sol (98%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/mocks/ErroredVerifier.sol (66%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/mocks/ExposedVerifier.sol (100%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/mocks/FeeManagerProxy.sol (61%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/reward-manager/BaseRewardManager.t.sol (97%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/reward-manager/RewardManager.claim.t.sol (99%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/reward-manager/RewardManager.general.t.sol (92%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/reward-manager/RewardManager.payRecipients.t.sol (100%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/reward-manager/RewardManager.setRecipients.t.sol (98%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/reward-manager/RewardManager.updateRewardRecipients.t.sol (99%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/BaseVerifierTest.t.sol (97%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierActivateConfigTest.t.sol (97%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierDeactivateFeedTest.t.sol (98%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierProxyConstructorTest.t.sol (77%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierProxyInitializeVerifierTest.t.sol (93%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierProxySetAccessControllerTest.t.sol (92%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierProxySetVerifierTest.t.sol (88%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierProxyTest.t.sol (87%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierProxyUnsetVerifierTest.t.sol (95%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierSetConfigFromSourceTest.t.sol (98%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierSetConfigTest.t.sol (98%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierTest.t.sol (88%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierTestBillingReport.t.sol (100%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierUnsetConfigTest.t.sol (97%) rename contracts/src/v0.8/llo-feeds/{ => v0.3.0}/test/verifier/VerifierVerifyTest.t.sol (97%) create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/DestinationRewardManager.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifier.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifierProxy.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationFeeManager.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationRewardManager.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifier.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierProxy.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/BaseDestinationFeeManager.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.general.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.getFeeAndReward.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.processFee.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.processFeeBulk.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/mocks/DestinationFeeManagerProxy.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/BaseDestinationRewardManager.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.claim.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.general.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.payRecipients.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.setRecipients.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.updateRewardRecipients.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/BaseDestinationVerifierTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierInterfacesTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierProxyTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierRemoveLatestConfigTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetAccessControllerTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetConfigTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetFeeManagerTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestBillingReport.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestRewards.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestRewardsMultiVefifierFeeManager.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierVerifyBulkTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierVerifyTest.t.sol create mode 100644 core/gethwrappers/llo-feeds/generated/destination_fee_manager/destination_fee_manager.go create mode 100644 core/gethwrappers/llo-feeds/generated/destination_reward_manager/destination_reward_manager.go create mode 100644 core/gethwrappers/llo-feeds/generated/destination_verifier/destination_verifier.go create mode 100644 core/gethwrappers/llo-feeds/generated/destination_verifier_proxy/destination_verifier_proxy.go diff --git a/contracts/gas-snapshots/llo-feeds.gas-snapshot b/contracts/gas-snapshots/llo-feeds.gas-snapshot index 0162809e90..89073a7846 100644 --- a/contracts/gas-snapshots/llo-feeds.gas-snapshot +++ b/contracts/gas-snapshots/llo-feeds.gas-snapshot @@ -18,6 +18,220 @@ ByteUtilTest:test_readUint32MultiWord() (gas: 3393) ByteUtilTest:test_readUint32WithEmptyArray() (gas: 3253) ByteUtilTest:test_readUint32WithNotEnoughBytes() (gas: 3272) ByteUtilTest:test_readZeroAddress() (gas: 3365) +DestinationFeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52669) +DestinationFeeManagerProcessFeeTest:test_DiscountIsReturnedForNative() (gas: 52685) +DestinationFeeManagerProcessFeeTest:test_DiscountIsReturnedForNativeWithSurcharge() (gas: 78876) +DestinationFeeManagerProcessFeeTest:test_V1PayloadVerifies() (gas: 29324) +DestinationFeeManagerProcessFeeTest:test_V1PayloadVerifiesAndReturnsChange() (gas: 61187) +DestinationFeeManagerProcessFeeTest:test_V2PayloadVerifies() (gas: 121137) +DestinationFeeManagerProcessFeeTest:test_V2PayloadWithoutQuoteFails() (gas: 29669) +DestinationFeeManagerProcessFeeTest:test_V2PayloadWithoutZeroFee() (gas: 74797) +DestinationFeeManagerProcessFeeTest:test_WithdrawERC20() (gas: 72796) +DestinationFeeManagerProcessFeeTest:test_WithdrawNonAdminAddr() (gas: 56334) +DestinationFeeManagerProcessFeeTest:test_WithdrawUnwrappedNative() (gas: 26411) +DestinationFeeManagerProcessFeeTest:test_addVerifier() (gas: 131079) +DestinationFeeManagerProcessFeeTest:test_addVerifierExistingAddress() (gas: 34148) +DestinationFeeManagerProcessFeeTest:test_baseFeeIsAppliedForLink() (gas: 17214) +DestinationFeeManagerProcessFeeTest:test_baseFeeIsAppliedForNative() (gas: 20152) +DestinationFeeManagerProcessFeeTest:test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() (gas: 91103) +DestinationFeeManagerProcessFeeTest:test_discountAIsNotAppliedWhenSetForOtherUsers() (gas: 56580) +DestinationFeeManagerProcessFeeTest:test_discountFeeRoundsDownWhenUneven() (gas: 52871) +DestinationFeeManagerProcessFeeTest:test_discountIsAppliedForLink() (gas: 49682) +DestinationFeeManagerProcessFeeTest:test_discountIsAppliedWith100PercentSurcharge() (gas: 78949) +DestinationFeeManagerProcessFeeTest:test_discountIsNoLongerAppliedAfterRemoving() (gas: 46567) +DestinationFeeManagerProcessFeeTest:test_discountIsNotAppliedForInvalidTokenAddress() (gas: 17582) +DestinationFeeManagerProcessFeeTest:test_discountIsNotAppliedToOtherFeeds() (gas: 54628) +DestinationFeeManagerProcessFeeTest:test_discountIsReturnedForLink() (gas: 49654) +DestinationFeeManagerProcessFeeTest:test_emptyQuoteRevertsWithError() (gas: 12231) +DestinationFeeManagerProcessFeeTest:test_eventIsEmittedAfterSurchargeIsSet() (gas: 41424) +DestinationFeeManagerProcessFeeTest:test_eventIsEmittedIfNotEnoughLink() (gas: 179229) +DestinationFeeManagerProcessFeeTest:test_eventIsEmittedUponWithdraw() (gas: 69057) +DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterDiscountIsRemoved() (gas: 49831) +DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewDiscountIsApplied() (gas: 67769) +DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewSurchargeIsApplied() (gas: 64460) +DestinationFeeManagerProcessFeeTest:test_feeIsZeroWith100PercentDiscount() (gas: 52091) +DestinationFeeManagerProcessFeeTest:test_getBaseRewardWithLinkQuote() (gas: 17231) +DestinationFeeManagerProcessFeeTest:test_getLinkFeeIsRoundedUp() (gas: 49853) +DestinationFeeManagerProcessFeeTest:test_getLinkRewardIsSameAsFee() (gas: 55711) +DestinationFeeManagerProcessFeeTest:test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() (gas: 82833) +DestinationFeeManagerProcessFeeTest:test_getRewardWithLinkDiscount() (gas: 49700) +DestinationFeeManagerProcessFeeTest:test_getRewardWithLinkQuoteAndLinkDiscount() (gas: 49681) +DestinationFeeManagerProcessFeeTest:test_getRewardWithNativeQuote() (gas: 20150) +DestinationFeeManagerProcessFeeTest:test_getRewardWithNativeQuoteAndSurcharge() (gas: 50885) +DestinationFeeManagerProcessFeeTest:test_linkAvailableForPaymentReturnsLinkBalance() (gas: 53172) +DestinationFeeManagerProcessFeeTest:test_nativeSurcharge0Percent() (gas: 30937) +DestinationFeeManagerProcessFeeTest:test_nativeSurcharge100Percent() (gas: 50887) +DestinationFeeManagerProcessFeeTest:test_nativeSurchargeCannotExceed100Percent() (gas: 17220) +DestinationFeeManagerProcessFeeTest:test_nativeSurchargeEventIsEmittedOnUpdate() (gas: 41402) +DestinationFeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFee() (gas: 51914) +DestinationFeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() (gas: 78172) +DestinationFeeManagerProcessFeeTest:test_nonAdminProxyUserCannotProcessFee() (gas: 24185) +DestinationFeeManagerProcessFeeTest:test_nonAdminUserCanNotSetDiscount() (gas: 19871) +DestinationFeeManagerProcessFeeTest:test_onlyCallableByOwnerReverts() (gas: 15453) +DestinationFeeManagerProcessFeeTest:test_payLinkDeficit() (gas: 198072) +DestinationFeeManagerProcessFeeTest:test_payLinkDeficitOnlyCallableByAdmin() (gas: 17415) +DestinationFeeManagerProcessFeeTest:test_payLinkDeficitPaysAllFeesProcessed() (gas: 218691) +DestinationFeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 202446) +DestinationFeeManagerProcessFeeTest:test_poolIdsCannotBeZeroAddress() (gas: 115317) +DestinationFeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 121475) +DestinationFeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 29745) +DestinationFeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 165393) +DestinationFeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 30063) +DestinationFeeManagerProcessFeeTest:test_processFeeNative() (gas: 178204) +DestinationFeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 122766) +DestinationFeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 31822) +DestinationFeeManagerProcessFeeTest:test_processFeeWithDiscountEmitsEvent() (gas: 245890) +DestinationFeeManagerProcessFeeTest:test_processFeeWithInvalidReportVersionFailsToDecode() (gas: 30770) +DestinationFeeManagerProcessFeeTest:test_processFeeWithNoDiscountDoesNotEmitEvent() (gas: 171109) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNative() (gas: 186069) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddress() (gas: 135874) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() (gas: 161459) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeShortFunds() (gas: 94841) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeWithExcessiveFee() (gas: 193032) +DestinationFeeManagerProcessFeeTest:test_processFeeWithWithCorruptQuotePayload() (gas: 75084) +DestinationFeeManagerProcessFeeTest:test_processFeeWithWithEmptyQuotePayload() (gas: 30006) +DestinationFeeManagerProcessFeeTest:test_processFeeWithWithZeroQuotePayload() (gas: 30056) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() (gas: 35320) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() (gas: 158081) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkReturnsChange() (gas: 56059) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() (gas: 121473) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() (gas: 38024) +DestinationFeeManagerProcessFeeTest:test_processMultipleLinkReports() (gas: 230434) +DestinationFeeManagerProcessFeeTest:test_processMultipleUnwrappedNativeReports() (gas: 264223) +DestinationFeeManagerProcessFeeTest:test_processMultipleV1Reports() (gas: 81155) +DestinationFeeManagerProcessFeeTest:test_processMultipleWrappedNativeReports() (gas: 247072) +DestinationFeeManagerProcessFeeTest:test_processPoolIdsPassedMismatched() (gas: 98793) +DestinationFeeManagerProcessFeeTest:test_processV1V2V3Reports() (gas: 215445) +DestinationFeeManagerProcessFeeTest:test_processV1V2V3ReportsWithUnwrapped() (gas: 257087) +DestinationFeeManagerProcessFeeTest:test_removeVerifierNonExistentAddress() (gas: 12822) +DestinationFeeManagerProcessFeeTest:test_removeVerifierZeroAaddress() (gas: 10678) +DestinationFeeManagerProcessFeeTest:test_reportWithNoExpiryOrFeeReturnsZero() (gas: 13615) +DestinationFeeManagerProcessFeeTest:test_revertOnSettingAnAddressZeroVerifier() (gas: 10614) +DestinationFeeManagerProcessFeeTest:test_rewardsAreCorrectlySentToEachAssociatedPoolWhenVerifyingInBulk() (gas: 263181) +DestinationFeeManagerProcessFeeTest:test_setDiscountOver100Percent() (gas: 19562) +DestinationFeeManagerProcessFeeTest:test_setRewardManagerZeroAddress() (gas: 10626) +DestinationFeeManagerProcessFeeTest:test_subscriberDiscountEventIsEmittedOnUpdate() (gas: 46329) +DestinationFeeManagerProcessFeeTest:test_surchargeFeeRoundsUpWhenUneven() (gas: 51261) +DestinationFeeManagerProcessFeeTest:test_surchargeIsApplied() (gas: 51165) +DestinationFeeManagerProcessFeeTest:test_surchargeIsAppliedForNativeFeeWithDiscount() (gas: 79356) +DestinationFeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 47132) +DestinationFeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 49962) +DestinationFeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 78352) +DestinationFeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 14943) +DestinationRewardManagerClaimTest:test_claimAllRecipients() (gas: 277191) +DestinationRewardManagerClaimTest:test_claimMultipleRecipients() (gas: 154371) +DestinationRewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 330208) +DestinationRewardManagerClaimTest:test_claimSingleRecipient() (gas: 89039) +DestinationRewardManagerClaimTest:test_claimUnevenAmountRoundsDown() (gas: 315411) +DestinationRewardManagerClaimTest:test_claimUnregisteredPoolId() (gas: 35164) +DestinationRewardManagerClaimTest:test_claimUnregisteredRecipient() (gas: 41201) +DestinationRewardManagerClaimTest:test_eventIsEmittedUponClaim() (gas: 86084) +DestinationRewardManagerClaimTest:test_eventIsNotEmittedUponUnsuccessfulClaim() (gas: 25050) +DestinationRewardManagerClaimTest:test_recipientsClaimMultipleDeposits() (gas: 386857) +DestinationRewardManagerClaimTest:test_singleRecipientClaimMultipleDeposits() (gas: 137777) +DestinationRewardManagerNoRecipientSet:test_claimAllRecipientsAfterRecipientsSet() (gas: 492227) +DestinationRewardManagerPayRecipientsTest:test_addFundsToPoolAsNonOwnerOrFeeManager() (gas: 11503) +DestinationRewardManagerPayRecipientsTest:test_addFundsToPoolAsOwner() (gas: 53944) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipients() (gas: 250829) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsFromNonAdminUser() (gas: 20496) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsFromRecipientInPool() (gas: 251075) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalInvalidRecipient() (gas: 262275) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalUnregisteredRecipient() (gas: 265760) +DestinationRewardManagerPayRecipientsTest:test_payRecipientWithInvalidPool() (gas: 28908) +DestinationRewardManagerPayRecipientsTest:test_payRecipientsEmptyRecipientList() (gas: 25333) +DestinationRewardManagerPayRecipientsTest:test_payRecipientsWithInvalidPoolId() (gas: 31402) +DestinationRewardManagerPayRecipientsTest:test_paySingleRecipient() (gas: 84709) +DestinationRewardManagerPayRecipientsTest:test_paySubsetOfRecipientsInPool() (gas: 198474) +DestinationRewardManagerRecipientClaimDifferentWeightsTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 280853) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsMultiplePools() (gas: 512489) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsSinglePool() (gas: 283649) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimEmptyPoolWhenSecondPoolContainsFunds() (gas: 293497) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsMultiplePools() (gas: 263075) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsSinglePool() (gas: 154537) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleRecipientMultiplePools() (gas: 132653) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleUniqueRecipient() (gas: 106056) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimUnevenAmountRoundsDown() (gas: 579776) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimUnregisteredRecipient() (gas: 64664) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorAndTotalPoolsEqual() (gas: 13074) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorCannotBeGreaterThanTotalPools() (gas: 12703) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorSingleResult() (gas: 22471) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPools() (gas: 32248) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() (gas: 148629) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInNoPools() (gas: 21728) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInSinglePool() (gas: 27765) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_recipientsClaimMultipleDeposits() (gas: 391427) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_singleRecipientClaimMultipleDeposits() (gas: 137862) +DestinationRewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 199546) +DestinationRewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() (gas: 219419) +DestinationRewardManagerSetRecipientsTest:test_eventIsEmittedUponSetRecipients() (gas: 191707) +DestinationRewardManagerSetRecipientsTest:test_setRecipientContainsDuplicateRecipients() (gas: 126060) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientFromManagerAddress() (gas: 214117) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() (gas: 21496) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientTwice() (gas: 193280) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWeights() (gas: 180608) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroAddress() (gas: 90202) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroWeight() (gas: 191312) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipients() (gas: 185567) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientsIsEmpty() (gas: 87091) +DestinationRewardManagerSetRecipientsTest:test_setSingleRewardRecipient() (gas: 110349) +DestinationRewardManagerSetupTest:test_addFeeManagerExistingAddress() (gas: 35281) +DestinationRewardManagerSetupTest:test_addFeeManagerZeroAddress() (gas: 10580) +DestinationRewardManagerSetupTest:test_addRemoveFeeManager() (gas: 48248) +DestinationRewardManagerSetupTest:test_eventEmittedUponFeeManagerUpdate() (gas: 41581) +DestinationRewardManagerSetupTest:test_eventEmittedUponFeePaid() (gas: 259172) +DestinationRewardManagerSetupTest:test_rejectsZeroLinkAddressOnConstruction() (gas: 59610) +DestinationRewardManagerSetupTest:test_removeFeeManagerNonExistentAddress() (gas: 12778) +DestinationRewardManagerSetupTest:test_setFeeManagerZeroAddress() (gas: 17084) +DestinationRewardManagerUpdateRewardRecipientsMultiplePoolsTest:test_updatePrimaryRecipientWeights() (gas: 376674) +DestinationRewardManagerUpdateRewardRecipientsTest:test_eventIsEmittedUponUpdateRecipients() (gas: 280411) +DestinationRewardManagerUpdateRewardRecipientsTest:test_onlyAdminCanUpdateRecipients() (gas: 19705) +DestinationRewardManagerUpdateRewardRecipientsTest:test_partialUpdateRecipientWeights() (gas: 221004) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateAllRecipientsWithSameAddressAndWeight() (gas: 274233) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsToSubset() (gas: 254156) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithExcessiveWeight() (gas: 259143) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithSameAddressAndWeight() (gas: 149856) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithUnderWeightSet() (gas: 259217) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientWeights() (gas: 372155) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientWithNewZeroAddress() (gas: 270700) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsContainsDuplicateRecipients() (gas: 288483) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentLargerSet() (gas: 407780) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentPartialSet() (gas: 317945) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSet() (gas: 377692) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSetWithInvalidWeights() (gas: 312038) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForLargerSet() (gas: 399603) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() (gas: 289433) +DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 639153) +DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNative() (gas: 640232) +DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrapped() (gas: 661796) +DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrappedReturnsChange() (gas: 661751) +DestinationVerifierConstructorTest:test_falseIfIsNotCorrectInterface() (gas: 8719) +DestinationVerifierConstructorTest:test_revertsIfInitializedWithEmptyVerifierProxy() (gas: 61121) +DestinationVerifierConstructorTest:test_trueIfIsCorrectInterface() (gas: 8604) +DestinationVerifierConstructorTest:test_typeAndVersion() (gas: 2818189) +DestinationVerifierProxyInitializeVerifierTest:test_correctlySetsTheOwner() (gas: 1035181) +DestinationVerifierProxyInitializeVerifierTest:test_correctlySetsVersion() (gas: 9841) +DestinationVerifierProxyInitializeVerifierTest:test_setVerifierCalledByNoOwner() (gas: 17483) +DestinationVerifierProxyInitializeVerifierTest:test_setVerifierOk() (gas: 30622) +DestinationVerifierProxyInitializeVerifierTest:test_setVerifierWhichDoesntHonourInterface() (gas: 16851) +DestinationVerifierSetAccessControllerTest:test_emitsTheCorrectEvent() (gas: 35391) +DestinationVerifierSetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 15089) +DestinationVerifierSetAccessControllerTest:test_successfullySetsNewAccessController() (gas: 34885) +DestinationVerifierSetAccessControllerTest:test_successfullySetsNewAccessControllerIsEmpty() (gas: 15007) +DestinationVerifierSetConfigTest:test_NoDonConfigAlreadyExists() (gas: 2874492) +DestinationVerifierSetConfigTest:test_addressesAndWeightsDoNotProduceSideEffectsInDonConfigIds() (gas: 1323177) +DestinationVerifierSetConfigTest:test_donConfigIdIsSameForSignersInDifferentOrder() (gas: 1290374) +DestinationVerifierSetConfigTest:test_removeLatestConfig() (gas: 786275) +DestinationVerifierSetConfigTest:test_removeLatestConfigWhenNoConfigShouldFail() (gas: 12870) +DestinationVerifierSetConfigTest:test_revertsIfCalledByNonOwner() (gas: 174936) +DestinationVerifierSetConfigTest:test_revertsIfDuplicateSigners() (gas: 171604) +DestinationVerifierSetConfigTest:test_revertsIfFaultToleranceIsZero() (gas: 168484) +DestinationVerifierSetConfigTest:test_revertsIfNotEnoughSigners() (gas: 11571) +DestinationVerifierSetConfigTest:test_revertsIfSetWithTooManySigners() (gas: 17943) +DestinationVerifierSetConfigTest:test_revertsIfSignerContainsZeroAddress() (gas: 324333) +DestinationVerifierSetConfigTest:test_setConfigActiveUnknownDonConfigId() (gas: 13102) +DestinationVerifierSetConfigTest:test_setConfigWithActivationTime() (gas: 1088176) +DestinationVerifierSetConfigTest:test_setConfigWithActivationTimeEarlierThanLatestConfigShouldFail() (gas: 1963414) +DestinationVerifierSetConfigTest:test_setConfigWithActivationTimeNoFutureTimeShouldFail() (gas: 259797) FeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52645) FeeManagerProcessFeeTest:test_DiscountIsReturnedForNative() (gas: 52595) FeeManagerProcessFeeTest:test_DiscountIsReturnedForNativeWithSurcharge() (gas: 78808) @@ -108,6 +322,7 @@ FeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 47 FeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 49938) FeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 78261) FeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 14919) +MultiVerifierBillingTests:test_multipleFeeManagersAndVerifiers() (gas: 4586990) RewardManagerClaimTest:test_claimAllRecipients() (gas: 277131) RewardManagerClaimTest:test_claimMultipleRecipients() (gas: 154341) RewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 330086) @@ -200,6 +415,13 @@ VerifierActivateFeedTest:test_revertsIfNoFeedExistsActivate() (gas: 13179) VerifierActivateFeedTest:test_revertsIfNoFeedExistsDeactivate() (gas: 13157) VerifierActivateFeedTest:test_revertsIfNotOwnerActivateFeed() (gas: 17109) VerifierActivateFeedTest:test_revertsIfNotOwnerDeactivateFeed() (gas: 17164) +VerifierBillingTests:test_rewardsAreDistributedAccordingToWeights() (gas: 1731717) +VerifierBillingTests:test_rewardsAreDistributedAccordingToWeightsMultipleWeigths() (gas: 4460715) +VerifierBillingTests:test_rewardsAreDistributedAccordingToWeightsUsingHistoricalConfigs() (gas: 2098833) +VerifierBillingTests:test_verifyWithLinkV3Report() (gas: 1591346) +VerifierBillingTests:test_verifyWithNativeERC20() (gas: 1467256) +VerifierBillingTests:test_verifyWithNativeUnwrapped() (gas: 1376447) +VerifierBillingTests:test_verifyWithNativeUnwrappedReturnsChange() (gas: 1383493) VerifierBulkVerifyBillingReport:test_verifyMultiVersions() (gas: 476595) VerifierBulkVerifyBillingReport:test_verifyMultiVersionsReturnsVerifiedReports() (gas: 474853) VerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 557541) @@ -212,6 +434,7 @@ VerifierDeactivateFeedWithVerifyTest:test_currentReportAllowsVerification() (gas VerifierDeactivateFeedWithVerifyTest:test_currentReportFailsVerification() (gas: 113388) VerifierDeactivateFeedWithVerifyTest:test_previousReportAllowsVerification() (gas: 99624) VerifierDeactivateFeedWithVerifyTest:test_previousReportFailsVerification() (gas: 69943) +VerifierInterfacesTest:test_DestinationContractInterfaces() (gas: 623467) VerifierProxyAccessControlledVerificationTest:test_proxiesToTheVerifierIfHasAccess() (gas: 208529) VerifierProxyAccessControlledVerificationTest:test_revertsIfNoAccess() (gas: 112345) VerifierProxyConstructorTest:test_correctlySetsTheCorrectAccessControllerInterface() (gas: 1485359) @@ -236,6 +459,9 @@ VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_correctlyUnsetsVeri VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_emitsAnEventAfterUnsettingVerifier() (gas: 17961) VerifierProxyVerifyTest:test_proxiesToTheCorrectVerifier() (gas: 204342) VerifierProxyVerifyTest:test_revertsIfNoVerifierConfigured() (gas: 117264) +VerifierSetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 17196) +VerifierSetAccessControllerTest:test_setFeeManagerWhichDoesntHonourInterface() (gas: 16571) +VerifierSetAccessControllerTest:test_successfullySetsNewFeeManager() (gas: 44855) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 542302) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 967768) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 523251) @@ -256,6 +482,9 @@ VerifierTestBillingReport:test_verifyWithLink() (gas: 275293) VerifierTestBillingReport:test_verifyWithNative() (gas: 316326) VerifierTestBillingReport:test_verifyWithNativeUnwrapped() (gas: 318574) VerifierTestBillingReport:test_verifyWithNativeUnwrappedReturnsChange() (gas: 325642) +VerifierVerifyBulkTest:test_revertsVerifyBulkIfNoAccess() (gas: 112867) +VerifierVerifyBulkTest:test_verifyBulkSingleCaseWithSingleConfig() (gas: 745046) +VerifierVerifyBulkTest:test_verifyBulkWithSingleConfigOneVerifyFails() (gas: 698203) VerifierVerifyMultipleConfigDigestTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 133961) VerifierVerifyMultipleConfigDigestTest:test_canVerifyOlderReportsWithOlderConfigs() (gas: 189865) VerifierVerifyMultipleConfigDigestTest:test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() (gas: 88216) @@ -270,6 +499,18 @@ VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedByNonProxy() (gas: 10 VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedWithIncorrectAddresses() (gas: 184077) VerifierVerifySingleConfigDigestTest:test_revertsIfWrongNumberOfSigners() (gas: 110042) VerifierVerifySingleConfigDigestTest:test_setsTheCorrectEpoch() (gas: 194592) +VerifierVerifyTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 861741) +VerifierVerifyTest:test_canVerifyOlderV3ReportsWithOlderConfigs() (gas: 815984) +VerifierVerifyTest:test_failToVerifyReportIfDupSigners() (gas: 450715) +VerifierVerifyTest:test_failToVerifyReportIfNoSigners() (gas: 426492) +VerifierVerifyTest:test_failToVerifyReportIfNotEnoughSigners() (gas: 434814) +VerifierVerifyTest:test_failToVerifyReportIfSignerNotInConfig() (gas: 456866) +VerifierVerifyTest:test_revertsVerifyIfNoAccess() (gas: 109465) +VerifierVerifyTest:test_rollingOutConfiguration() (gas: 1497254) +VerifierVerifyTest:test_scenarioRollingNewChainWithHistoricConfigs() (gas: 976162) +VerifierVerifyTest:test_verifyFailsWhenReportIsOlderThanConfig() (gas: 2303366) +VerifierVerifyTest:test_verifyReport() (gas: 1434811) +VerifierVerifyTest:test_verifyTooglingActiveFlagsDonConfigs() (gas: 1918797) Verifier_accessControlledVerify:testVerifyWithAccessControl_gas() (gas: 212077) Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithLinkFeeSuccess_gas() (gas: 519389) Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithNativeFeeSuccess_gas() (gas: 542808) diff --git a/contracts/scripts/native_solc_compile_all_llo-feeds b/contracts/scripts/native_solc_compile_all_llo-feeds index eb17f93b0d..f0224d962c 100755 --- a/contracts/scripts/native_solc_compile_all_llo-feeds +++ b/contracts/scripts/native_solc_compile_all_llo-feeds @@ -28,15 +28,19 @@ compileContract () { "$ROOT"/contracts/src/v0.8/"$1" } -compileContract llo-feeds/Verifier.sol -compileContract llo-feeds/VerifierProxy.sol -compileContract llo-feeds/FeeManager.sol -compileContract llo-feeds/RewardManager.sol +compileContract llo-feeds/v0.3.0/Verifier.sol +compileContract llo-feeds/v0.3.0/VerifierProxy.sol +compileContract llo-feeds/v0.3.0/FeeManager.sol +compileContract llo-feeds/v0.3.0/RewardManager.sol +compileContract llo-feeds/v0.4.0/DestinationVerifier.sol +compileContract llo-feeds/v0.4.0/DestinationVerifierProxy.sol +compileContract llo-feeds/v0.4.0/DestinationFeeManager.sol +compileContract llo-feeds/v0.4.0/DestinationRewardManager.sol # Test | Mocks -compileContract llo-feeds/test/mocks/ErroredVerifier.sol -compileContract llo-feeds/test/mocks/ExposedVerifier.sol +compileContract llo-feeds/v0.3.0/test/mocks/ErroredVerifier.sol +compileContract llo-feeds/v0.3.0/test/mocks/ExposedVerifier.sol # LLO compileContract llo-feeds/dev/ChannelConfigStore.sol diff --git a/contracts/src/v0.8/llo-feeds/libraries/Common.sol b/contracts/src/v0.8/llo-feeds/libraries/Common.sol index f732ced004..23418bf41a 100644 --- a/contracts/src/v0.8/llo-feeds/libraries/Common.sol +++ b/contracts/src/v0.8/llo-feeds/libraries/Common.sol @@ -19,6 +19,28 @@ library Common { uint64 weight; } + /** + * @notice Checks if an array of AddressAndWeight has duplicate addresses + * @param recipients The array of AddressAndWeight to check + * @return bool True if there are duplicates, false otherwise + */ + function _hasDuplicateAddresses(address[] memory recipients) internal pure returns (bool) { + for (uint256 i = 0; i < recipients.length; ) { + for (uint256 j = i + 1; j < recipients.length; ) { + if (recipients[i] == recipients[j]) { + return true; + } + unchecked { + ++j; + } + } + unchecked { + ++i; + } + } + return false; + } + /** * @notice Checks if an array of AddressAndWeight has duplicate addresses * @param recipients The array of AddressAndWeight to check @@ -40,4 +62,28 @@ library Common { } return false; } + + /** + * @notice sorts a list of addresses numerically + * @param arr The array of addresses to sort + * @param left the start index + * @param right the end index + */ + function _quickSort(address[] memory arr, int256 left, int256 right) internal pure { + int256 i = left; + int256 j = right; + if (i == j) return; + address pivot = arr[uint256(left + (right - left) / 2)]; + while (i <= j) { + while (uint160(arr[uint256(i)]) < uint160(pivot)) i++; + while (uint160(pivot) < uint160(arr[uint256(j)])) j--; + if (i <= j) { + (arr[uint256(i)], arr[uint256(j)]) = (arr[uint256(j)], arr[uint256(i)]); + i++; + j--; + } + } + if (left < j) _quickSort(arr, left, j); + if (i < right) _quickSort(arr, i, right); + } } diff --git a/contracts/src/v0.8/llo-feeds/test/ByteUtilTest.t.sol b/contracts/src/v0.8/llo-feeds/libraries/test/ByteUtilTest.t.sol similarity index 99% rename from contracts/src/v0.8/llo-feeds/test/ByteUtilTest.t.sol rename to contracts/src/v0.8/llo-feeds/libraries/test/ByteUtilTest.t.sol index 21bd957e4e..8b5343866f 100644 --- a/contracts/src/v0.8/llo-feeds/test/ByteUtilTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/libraries/test/ByteUtilTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {Test} from "forge-std/Test.sol"; -import {ByteUtil} from "../libraries/ByteUtil.sol"; +import {ByteUtil} from "../ByteUtil.sol"; contract ByteUtilTest is Test { using ByteUtil for bytes; diff --git a/contracts/src/v0.8/llo-feeds/FeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/FeeManager.sol similarity index 96% rename from contracts/src/v0.8/llo-feeds/FeeManager.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/FeeManager.sol index 665940d467..44f550e325 100644 --- a/contracts/src/v0.8/llo-feeds/FeeManager.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/FeeManager.sol @@ -1,16 +1,16 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; import {IFeeManager} from "./interfaces/IFeeManager.sol"; -import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; -import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -import {Common} from "./libraries/Common.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../libraries/Common.sol"; import {IRewardManager} from "./interfaces/IRewardManager.sol"; -import {IWERC20} from "../shared/interfaces/IWERC20.sol"; -import {IERC20} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC20.sol"; -import {Math} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/Math.sol"; -import {SafeERC20} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IWERC20} from "../../shared/interfaces/IWERC20.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC20.sol"; +import {Math} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/Math.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; import {IVerifierFeeManager} from "./interfaces/IVerifierFeeManager.sol"; /** diff --git a/contracts/src/v0.8/llo-feeds/RewardManager.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/RewardManager.sol similarity index 96% rename from contracts/src/v0.8/llo-feeds/RewardManager.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/RewardManager.sol index 1929289a36..49fef51c56 100644 --- a/contracts/src/v0.8/llo-feeds/RewardManager.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/RewardManager.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; import {IRewardManager} from "./interfaces/IRewardManager.sol"; -import {IERC20} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC20.sol"; -import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; -import {Common} from "./libraries/Common.sol"; -import {SafeERC20} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC20.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {Common} from "../libraries/Common.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; /** * @title RewardManager diff --git a/contracts/src/v0.8/llo-feeds/Verifier.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/Verifier.sol similarity index 98% rename from contracts/src/v0.8/llo-feeds/Verifier.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/Verifier.sol index c8858999da..fe5742108a 100644 --- a/contracts/src/v0.8/llo-feeds/Verifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/Verifier.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; import {IVerifier} from "./interfaces/IVerifier.sol"; import {IVerifierProxy} from "./interfaces/IVerifierProxy.sol"; -import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; -import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -import {Common} from "./libraries/Common.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../libraries/Common.sol"; // OCR2 standard uint256 constant MAX_NUM_ORACLES = 31; diff --git a/contracts/src/v0.8/llo-feeds/VerifierProxy.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/VerifierProxy.sol similarity index 95% rename from contracts/src/v0.8/llo-feeds/VerifierProxy.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/VerifierProxy.sol index c32a27178c..c06312dd7b 100644 --- a/contracts/src/v0.8/llo-feeds/VerifierProxy.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/VerifierProxy.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; import {IVerifierProxy} from "./interfaces/IVerifierProxy.sol"; import {IVerifier} from "./interfaces/IVerifier.sol"; -import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; -import {AccessControllerInterface} from "../shared/interfaces/AccessControllerInterface.sol"; -import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {AccessControllerInterface} from "../../shared/interfaces/AccessControllerInterface.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; import {IVerifierFeeManager} from "./interfaces/IVerifierFeeManager.sol"; -import {Common} from "./libraries/Common.sol"; +import {Common} from "../libraries/Common.sol"; /** * The verifier proxy contract is the gateway for all report verification requests diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IFeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IFeeManager.sol similarity index 94% rename from contracts/src/v0.8/llo-feeds/interfaces/IFeeManager.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IFeeManager.sol index 4095607b91..818a3a09a4 100644 --- a/contracts/src/v0.8/llo-feeds/interfaces/IFeeManager.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IFeeManager.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -import {Common} from "../libraries/Common.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; import {IVerifierFeeManager} from "./IVerifierFeeManager.sol"; interface IFeeManager is IERC165, IVerifierFeeManager { diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IRewardManager.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IRewardManager.sol similarity index 94% rename from contracts/src/v0.8/llo-feeds/interfaces/IRewardManager.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IRewardManager.sol index 5a6e03f1c9..f08ce34db2 100644 --- a/contracts/src/v0.8/llo-feeds/interfaces/IRewardManager.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IRewardManager.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -import {Common} from "../libraries/Common.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; interface IRewardManager is IERC165 { /** diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IVerifier.sol similarity index 97% rename from contracts/src/v0.8/llo-feeds/interfaces/IVerifier.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IVerifier.sol index 617d702d3f..94b260399e 100644 --- a/contracts/src/v0.8/llo-feeds/interfaces/IVerifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IVerifier.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -import {Common} from "../libraries/Common.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; interface IVerifier is IERC165 { /** diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IVerifierFeeManager.sol similarity index 88% rename from contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IVerifierFeeManager.sol index 522db952e5..da3fdfac15 100644 --- a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IVerifierFeeManager.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -import {Common} from "../libraries/Common.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; interface IVerifierFeeManager is IERC165 { /** diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IVerifierProxy.sol similarity index 95% rename from contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IVerifierProxy.sol index 2eb1b4aff4..6609e4869a 100644 --- a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/interfaces/IVerifierProxy.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import {Common} from "../libraries/Common.sol"; -import {AccessControllerInterface} from "../../shared/interfaces/AccessControllerInterface.sol"; +import {Common} from "../../libraries/Common.sol"; +import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol"; import {IVerifierFeeManager} from "./IVerifierFeeManager.sol"; interface IVerifierProxy { diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/BaseFeeManager.t.sol similarity index 98% rename from contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/BaseFeeManager.t.sol index edde26b2ee..0d598cdac5 100644 --- a/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/BaseFeeManager.t.sol @@ -4,9 +4,9 @@ pragma solidity 0.8.19; import {Test} from "forge-std/Test.sol"; import {FeeManager} from "../../FeeManager.sol"; import {RewardManager} from "../../RewardManager.sol"; -import {Common} from "../../libraries/Common.sol"; -import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; -import {WERC20Mock} from "../../../shared/mocks/WERC20Mock.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {ERC20Mock} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {WERC20Mock} from "../../../../shared/mocks/WERC20Mock.sol"; import {IRewardManager} from "../../interfaces/IRewardManager.sol"; import {FeeManagerProxy} from "../mocks/FeeManagerProxy.sol"; diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/FeeManager.general.t.sol similarity index 100% rename from contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/FeeManager.general.t.sol diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/FeeManager.getFeeAndReward.t.sol similarity index 98% rename from contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/FeeManager.getFeeAndReward.t.sol index 299a7f09d5..1b0f95d51b 100644 --- a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/FeeManager.getFeeAndReward.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.19; -import {Common} from "../../libraries/Common.sol"; +import {Common} from "../../../libraries/Common.sol"; import "./BaseFeeManager.t.sol"; /** @@ -10,7 +10,7 @@ import "./BaseFeeManager.t.sol"; * @notice This contract will test the functionality of the feeManager's getFeeAndReward */ contract FeeManagerProcessFeeTest is BaseFeeManagerTest { - function test_baseFeeIsAppliedForNative() public { + function test_baseFeeIsAppliedForNative() public view { //get the fee required by the feeManager Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); @@ -18,7 +18,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest { assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); } - function test_baseFeeIsAppliedForLink() public { + function test_baseFeeIsAppliedForLink() public view { //get the fee required by the feeManager Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); @@ -378,7 +378,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest { assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); } - function test_reportWithNoExpiryOrFeeReturnsZero() public { + function test_reportWithNoExpiryOrFeeReturnsZero() public view { //get the fee required by the feeManager Common.Asset memory fee = getFee(getV1Report(DEFAULT_FEED_1_V1), getNativeQuote(), USER); @@ -462,7 +462,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest { setNativeSurcharge(nativeSurcharge, ADMIN); } - function test_getBaseRewardWithLinkQuote() public { + function test_getBaseRewardWithLinkQuote() public view { //get the fee required by the feeManager Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); @@ -481,7 +481,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest { assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE / 2); } - function test_getRewardWithNativeQuote() public { + function test_getRewardWithNativeQuote() public view { //get the fee required by the feeManager Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/FeeManager.processFee.t.sol similarity index 99% rename from contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/FeeManager.processFee.t.sol index f8c1d47d4d..0e0ed8977b 100644 --- a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/FeeManager.processFee.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.19; -import {Common} from "../../libraries/Common.sol"; +import {Common} from "../../../libraries/Common.sol"; import "./BaseFeeManager.t.sol"; import {IRewardManager} from "../../interfaces/IRewardManager.sol"; diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFeeBulk.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/FeeManager.processFeeBulk.t.sol similarity index 100% rename from contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFeeBulk.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/fee-manager/FeeManager.processFeeBulk.t.sol diff --git a/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/gas/Gas_VerifierTest.t.sol similarity index 98% rename from contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/gas/Gas_VerifierTest.t.sol index 29b488fb32..ee8ba4c3e3 100644 --- a/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/gas/Gas_VerifierTest.t.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.19; import {BaseTest, BaseTestWithConfiguredVerifierAndFeeManager} from "../verifier/BaseVerifierTest.t.sol"; -import {SimpleWriteAccessController} from "../../../shared/access/SimpleWriteAccessController.sol"; -import {Common} from "../../libraries/Common.sol"; +import {SimpleWriteAccessController} from "../../../../shared/access/SimpleWriteAccessController.sol"; +import {Common} from "../../../libraries/Common.sol"; import {IRewardManager} from "../../interfaces/IRewardManager.sol"; contract Verifier_setConfig is BaseTest { diff --git a/contracts/src/v0.8/llo-feeds/test/mocks/ErroredVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/mocks/ErroredVerifier.sol similarity index 66% rename from contracts/src/v0.8/llo-feeds/test/mocks/ErroredVerifier.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/mocks/ErroredVerifier.sol index 01cb1a5061..e9dcd589e2 100644 --- a/contracts/src/v0.8/llo-feeds/test/mocks/ErroredVerifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/mocks/ErroredVerifier.sol @@ -2,13 +2,24 @@ pragma solidity 0.8.19; import {IVerifier} from "../../interfaces/IVerifier.sol"; -import {Common} from "../../libraries/Common.sol"; +import {Common} from "../../../libraries/Common.sol"; contract ErroredVerifier is IVerifier { function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { return interfaceId == this.verify.selector; } + //define each of the errors thrown in the revert below + + error FailedToVerify(); + error FailedToSetConfig(); + error FailedToActivateConfig(); + error FailedToDeactivateConfig(); + error FailedToActivateFeed(); + error FailedToDeactivateFeed(); + error FailedToGetLatestConfigDigestAndEpoch(); + error FailedToGetLatestConfigDetails(); + function verify( bytes memory, /** @@ -26,7 +37,7 @@ contract ErroredVerifier is IVerifier { bytes memory ) { - revert("Failed to verify"); + revert FailedToVerify(); } function setConfig( @@ -39,7 +50,7 @@ contract ErroredVerifier is IVerifier { bytes memory, Common.AddressAndWeight[] memory ) external pure override { - revert("Failed to set config"); + revert FailedToSetConfig(); } function setConfigFromSource( @@ -55,30 +66,30 @@ contract ErroredVerifier is IVerifier { bytes memory, Common.AddressAndWeight[] memory ) external pure override { - revert("Failed to set config"); + revert FailedToSetConfig(); } function activateConfig(bytes32, bytes32) external pure { - revert("Failed to activate config"); + revert FailedToActivateConfig(); } function deactivateConfig(bytes32, bytes32) external pure { - revert("Failed to deactivate config"); + revert FailedToDeactivateConfig(); } function activateFeed(bytes32) external pure { - revert("Failed to activate feed"); + revert FailedToActivateFeed(); } function deactivateFeed(bytes32) external pure { - revert("Failed to deactivate feed"); + revert FailedToDeactivateFeed(); } function latestConfigDigestAndEpoch(bytes32) external pure override returns (bool, bytes32, uint32) { - revert("Failed to get latest config digest and epoch"); + revert FailedToGetLatestConfigDigestAndEpoch(); } function latestConfigDetails(bytes32) external pure override returns (uint32, uint32, bytes32) { - revert("Failed to get latest config details"); + revert FailedToGetLatestConfigDetails(); } } diff --git a/contracts/src/v0.8/llo-feeds/test/mocks/ExposedVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/mocks/ExposedVerifier.sol similarity index 100% rename from contracts/src/v0.8/llo-feeds/test/mocks/ExposedVerifier.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/mocks/ExposedVerifier.sol diff --git a/contracts/src/v0.8/llo-feeds/test/mocks/FeeManagerProxy.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/mocks/FeeManagerProxy.sol similarity index 61% rename from contracts/src/v0.8/llo-feeds/test/mocks/FeeManagerProxy.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/mocks/FeeManagerProxy.sol index 16935f69d6..9abb4c50c2 100644 --- a/contracts/src/v0.8/llo-feeds/test/mocks/FeeManagerProxy.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/mocks/FeeManagerProxy.sol @@ -1,20 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import "../../interfaces/IFeeManager.sol"; +import {IFeeManager} from "../../interfaces/IFeeManager.sol"; contract FeeManagerProxy { - IFeeManager internal i_feeManager; + IFeeManager internal s_feeManager; function processFee(bytes calldata payload, bytes calldata parameterPayload) public payable { - i_feeManager.processFee{value: msg.value}(payload, parameterPayload, msg.sender); + s_feeManager.processFee{value: msg.value}(payload, parameterPayload, msg.sender); } function processFeeBulk(bytes[] calldata payloads, bytes calldata parameterPayload) public payable { - i_feeManager.processFeeBulk{value: msg.value}(payloads, parameterPayload, msg.sender); + s_feeManager.processFeeBulk{value: msg.value}(payloads, parameterPayload, msg.sender); } function setFeeManager(IFeeManager feeManager) public { - i_feeManager = feeManager; + s_feeManager = feeManager; } } diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/BaseRewardManager.t.sol similarity index 97% rename from contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/BaseRewardManager.t.sol index 65481513f0..c7bd7528c3 100644 --- a/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/BaseRewardManager.t.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.19; import {Test} from "forge-std/Test.sol"; -import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; -import {RewardManager} from "../../RewardManager.sol"; -import {Common} from "../../libraries/Common.sol"; +import {ERC20Mock} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {RewardManager} from "../../../v0.3.0/RewardManager.sol"; +import {Common} from "../../../libraries/Common.sol"; import {IRewardManager} from "../../interfaces/IRewardManager.sol"; /** diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.claim.t.sol similarity index 99% rename from contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.claim.t.sol index 5f07d36c72..efbe9fd6b3 100644 --- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.claim.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; -import {Common} from "../../libraries/Common.sol"; +import {Common} from "../../../libraries/Common.sol"; /** * @title BaseRewardManagerTest @@ -574,7 +574,7 @@ contract RewardManagerRecipientClaimMultiplePoolsTest is BaseRewardManagerTest { assertEq(poolIds[1], ZERO_POOL_ID); } - function test_getRewardsAvailableToRecipientInNoPools() public { + function test_getRewardsAvailableToRecipientInNoPools() public view { //get index 0 as this recipient is in both default pools bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(FEE_MANAGER, 0, type(uint256).max); diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.general.t.sol similarity index 92% rename from contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.general.t.sol index 7fde76d528..baff388769 100644 --- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.general.t.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.19; import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; -import {RewardManager} from "../../RewardManager.sol"; -import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {RewardManager} from "../../../v0.3.0/RewardManager.sol"; +import {ERC20Mock} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; import {IRewardManager} from "../../interfaces/IRewardManager.sol"; /** diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.payRecipients.t.sol similarity index 100% rename from contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.payRecipients.t.sol diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.setRecipients.t.sol similarity index 98% rename from contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.setRecipients.t.sol index 1cf5b51f62..d3e6990bd9 100644 --- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.setRecipients.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; -import {Common} from "../../libraries/Common.sol"; +import {Common} from "../../../libraries/Common.sol"; /** * @title BaseRewardManagerTest diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.updateRewardRecipients.t.sol similarity index 99% rename from contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.updateRewardRecipients.t.sol index 6c51a0fbfd..0d3a2b69b3 100644 --- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/reward-manager/RewardManager.updateRewardRecipients.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; -import {Common} from "../../libraries/Common.sol"; +import {Common} from "../../../libraries/Common.sol"; /** * @title BaseRewardManagerTest diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/BaseVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/BaseVerifierTest.t.sol similarity index 97% rename from contracts/src/v0.8/llo-feeds/test/verifier/BaseVerifierTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/BaseVerifierTest.t.sol index daf3187503..4d65414676 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/BaseVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/BaseVerifierTest.t.sol @@ -3,17 +3,16 @@ pragma solidity 0.8.19; import {Test} from "forge-std/Test.sol"; import {VerifierProxy} from "../../VerifierProxy.sol"; -import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; import {IVerifier} from "../../interfaces/IVerifier.sol"; import {ErroredVerifier} from "../mocks/ErroredVerifier.sol"; import {Verifier} from "../../Verifier.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; -import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol"; -import {FeeManager} from "../../FeeManager.sol"; -import {Common} from "../../libraries/Common.sol"; -import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; -import {WERC20Mock} from "../../../shared/mocks/WERC20Mock.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; import {FeeManager} from "../../FeeManager.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {ERC20Mock} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {WERC20Mock} from "../../../../shared/mocks/WERC20Mock.sol"; import {RewardManager} from "../../RewardManager.sol"; contract BaseTest is Test { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierActivateConfigTest.t.sol similarity index 97% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierActivateConfigTest.t.sol index f53c26ba19..99daabe206 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierActivateConfigTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTestWithConfiguredVerifierAndFeeManager, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../Verifier.sol"; +import {Verifier} from "../../../v0.3.0/Verifier.sol"; contract VerifierActivateConfigTest is BaseTestWithConfiguredVerifierAndFeeManager { function test_revertsIfNotOwner() public { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierDeactivateFeedTest.t.sol similarity index 98% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierDeactivateFeedTest.t.sol index 97647c8863..fb52c1c93e 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierDeactivateFeedTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTestWithConfiguredVerifierAndFeeManager, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../Verifier.sol"; +import {Verifier} from "../../../v0.3.0/Verifier.sol"; contract VerifierActivateFeedTest is BaseTestWithConfiguredVerifierAndFeeManager { function test_revertsIfNotOwnerActivateFeed() public { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxyConstructorTest.t.sol similarity index 77% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxyConstructorTest.t.sol index b085dc8a65..82efd8907b 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxyConstructorTest.t.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.19; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; -import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol"; +import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; contract VerifierProxyConstructorTest is BaseTest { function test_correctlySetsTheOwner() public { @@ -17,7 +17,7 @@ contract VerifierProxyConstructorTest is BaseTest { assertEq(address(proxy.s_accessController()), accessControllerAddr); } - function test_correctlySetsVersion() public { + function test_correctlySetsVersion() public view { string memory version = s_verifierProxy.typeAndVersion(); assertEq(version, "VerifierProxy 2.0.0"); } diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxyInitializeVerifierTest.t.sol similarity index 93% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxyInitializeVerifierTest.t.sol index e02b14fe56..5537d273be 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxyInitializeVerifierTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; +import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; contract VerifierProxyInitializeVerifierTest is BaseTest { bytes32 latestDigest; diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetAccessControllerTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxySetAccessControllerTest.t.sol similarity index 92% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetAccessControllerTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxySetAccessControllerTest.t.sol index 04889e0d5f..03bd6d97ee 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetAccessControllerTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxySetAccessControllerTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; contract VerifierProxySetAccessControllerTest is BaseTest { event AccessControllerSet(address oldAccessController, address newAccessController); diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxySetVerifierTest.t.sol similarity index 88% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxySetVerifierTest.t.sol index ea23f880ba..78e5ff0766 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxySetVerifierTest.t.sol @@ -3,9 +3,9 @@ pragma solidity 0.8.19; import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; import {IVerifier} from "../../interfaces/IVerifier.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; -import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -import {Common} from "../../libraries/Common.sol"; +import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; +import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../../libraries/Common.sol"; contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifierAndFeeManager { function test_revertsIfNotCorrectVerifier() public { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxyTest.t.sol similarity index 87% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxyTest.t.sol index ea7e02d740..441626e575 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxyTest.t.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.19; import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; -import {FeeManager} from "../../FeeManager.sol"; +import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; +import {FeeManager} from "../../../v0.3.0/FeeManager.sol"; contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifierAndFeeManager { function test_setFeeManagerZeroAddress() public { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyUnsetVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxyUnsetVerifierTest.t.sol similarity index 95% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyUnsetVerifierTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxyUnsetVerifierTest.t.sol index 746aa95574..a51c67e336 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyUnsetVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierProxyUnsetVerifierTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTest, BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; +import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; contract VerifierProxyUnsetVerifierTest is BaseTest { function test_revertsIfNotAdmin() public { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierSetConfigFromSourceTest.t.sol similarity index 98% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierSetConfigFromSourceTest.t.sol index 0cd5902161..9ee9b5272a 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierSetConfigFromSourceTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTest, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Common} from "../../libraries/Common.sol"; +import {Common} from "../../../libraries/Common.sol"; contract VerifierSetConfigFromSourceTest is BaseTest { function setUp() public virtual override { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierSetConfigTest.t.sol similarity index 98% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierSetConfigTest.t.sol index a4e15dcdd4..972ead8123 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierSetConfigTest.t.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.19; import {BaseTest, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../Verifier.sol"; -import {Common} from "../../libraries/Common.sol"; +import {Verifier} from "../../../v0.3.0/Verifier.sol"; +import {Common} from "../../../libraries/Common.sol"; contract VerifierSetConfigTest is BaseTest { function setUp() public virtual override { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierTest.t.sol similarity index 88% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierTest.t.sol index 2857b8f4d3..81f65f0c6e 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../Verifier.sol"; +import {Verifier} from "../../../v0.3.0/Verifier.sol"; contract VerifierConstructorTest is BaseTest { function test_revertsIfInitializedWithEmptyVerifierProxy() public { @@ -30,12 +30,12 @@ contract VerifierConstructorTest is BaseTest { } contract VerifierSupportsInterfaceTest is BaseTest { - function test_falseIfIsNotCorrectInterface() public { + function test_falseIfIsNotCorrectInterface() public view { bool isInterface = s_verifier.supportsInterface(bytes4("abcd")); assertEq(isInterface, false); } - function test_trueIfIsCorrectInterface() public { + function test_trueIfIsCorrectInterface() public view { bool isInterface = s_verifier.supportsInterface(Verifier.verify.selector); assertEq(isInterface, true); } diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierTestBillingReport.t.sol similarity index 100% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierTestBillingReport.t.sol diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierUnsetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierUnsetConfigTest.t.sol similarity index 97% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierUnsetConfigTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierUnsetConfigTest.t.sol index cc3c33331d..e192a2e9e0 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierUnsetConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierUnsetConfigTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../Verifier.sol"; +import {Verifier} from "../../../v0.3.0/Verifier.sol"; contract VerificationdeactivateConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipleConfiguredDigests { function test_revertsIfCalledByNonOwner() public { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierVerifyTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierVerifyTest.t.sol similarity index 97% rename from contracts/src/v0.8/llo-feeds/test/verifier/VerifierVerifyTest.t.sol rename to contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierVerifyTest.t.sol index db7be5ca54..1c14ba974c 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierVerifyTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.3.0/test/verifier/VerifierVerifyTest.t.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.19; import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../Verifier.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; -import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol"; -import {Common} from "../../libraries/Common.sol"; +import {Verifier} from "../../../v0.3.0/Verifier.sol"; +import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; +import {Common} from "../../../libraries/Common.sol"; contract VerifierVerifyTest is BaseTestWithConfiguredVerifierAndFeeManager { bytes32[3] internal s_reportContext; @@ -32,7 +32,7 @@ contract VerifierVerifyTest is BaseTestWithConfiguredVerifierAndFeeManager { ); } - function assertReportsEqual(bytes memory response, V1Report memory testReport) public { + function assertReportsEqual(bytes memory response, V1Report memory testReport) public pure { ( bytes32 feedId, uint32 timestamp, diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol new file mode 100644 index 0000000000..38d93de5cb --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol @@ -0,0 +1,557 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../libraries/Common.sol"; +import {IWERC20} from "../../shared/interfaces/IWERC20.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC20.sol"; +import {Math} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/Math.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IDestinationRewardManager} from "./interfaces/IDestinationRewardManager.sol"; +import {IDestinationFeeManager} from "./interfaces/IDestinationFeeManager.sol"; + +/** + * @title FeeManager + * @author Michael Fletcher + * @author Austin Born + * @notice This contract is used for the handling of fees required for users verifying reports. + */ +contract DestinationFeeManager is IDestinationFeeManager, ConfirmedOwner, TypeAndVersionInterface { + using SafeERC20 for IERC20; + + /// @notice list of subscribers and their discounts subscriberDiscounts[subscriber][feedId][token] + mapping(address => mapping(bytes32 => mapping(address => uint256))) public s_subscriberDiscounts; + + /// @notice keep track of any subsidised link that is owed to the reward manager. + mapping(bytes32 => uint256) public s_linkDeficit; + + /// @notice the total discount that can be applied to a fee, 1e18 = 100% discount + uint64 private constant PERCENTAGE_SCALAR = 1e18; + + /// @notice the LINK token address + address public immutable i_linkAddress; + + /// @notice the native token address + address public immutable i_nativeAddress; + + /// @notice the verifier address + mapping(address => address) public s_verifierAddressList; + + /// @notice the reward manager address + IDestinationRewardManager public i_rewardManager; + + // @notice the mask to apply to get the report version + bytes32 private constant REPORT_VERSION_MASK = 0xffff000000000000000000000000000000000000000000000000000000000000; + + // @notice the different report versions + bytes32 private constant REPORT_V1 = 0x0001000000000000000000000000000000000000000000000000000000000000; + + /// @notice the surcharge fee to be paid if paying in native + uint256 public s_nativeSurcharge; + + /// @notice the error thrown if the discount or surcharge is invalid + error InvalidSurcharge(); + + /// @notice the error thrown if the discount is invalid + error InvalidDiscount(); + + /// @notice the error thrown if the address is invalid + error InvalidAddress(); + + /// @notice thrown if msg.value is supplied with a bad quote + error InvalidDeposit(); + + /// @notice thrown if a report has expired + error ExpiredReport(); + + /// @notice thrown if a report has no quote + error InvalidQuote(); + + // @notice thrown when the caller is not authorized + error Unauthorized(); + + // @notice thrown when trying to clear a zero deficit + error ZeroDeficit(); + + /// @notice thrown when trying to pay an address that cannot except funds + error InvalidReceivingAddress(); + + /// @notice thrown when trying to bulk verify reports where theres not a matching number of poolIds + error PoolIdMismatch(); + + /// @notice Emitted whenever a subscriber's discount is updated + /// @param subscriber address of the subscriber to update discounts for + /// @param feedId Feed ID for the discount + /// @param token Token address for the discount + /// @param discount Discount to apply, in relation to the PERCENTAGE_SCALAR + event SubscriberDiscountUpdated(address indexed subscriber, bytes32 indexed feedId, address token, uint64 discount); + + /// @notice Emitted when updating the native surcharge + /// @param newSurcharge Surcharge amount to apply relative to PERCENTAGE_SCALAR + event NativeSurchargeUpdated(uint64 newSurcharge); + + /// @notice Emits when this contract does not have enough LINK to send to the reward manager when paying in native + /// @param rewards Config digest and link fees which could not be subsidised + event InsufficientLink(IDestinationRewardManager.FeePayment[] rewards); + + /// @notice Emitted when funds are withdrawn + /// @param adminAddress Address of the admin + /// @param recipient Address of the recipient + /// @param assetAddress Address of the asset withdrawn + /// @param quantity Amount of the asset withdrawn + event Withdraw(address adminAddress, address recipient, address assetAddress, uint192 quantity); + + /// @notice Emits when a deficit has been cleared for a particular config digest + /// @param configDigest Config digest of the deficit cleared + /// @param linkQuantity Amount of LINK required to pay the deficit + event LinkDeficitCleared(bytes32 indexed configDigest, uint256 linkQuantity); + + /// @notice Emits when a fee has been processed + /// @param configDigest Config digest of the fee processed + /// @param subscriber Address of the subscriber who paid the fee + /// @param fee Fee paid + /// @param reward Reward paid + /// @param appliedDiscount Discount applied to the fee + event DiscountApplied( + bytes32 indexed configDigest, + address indexed subscriber, + Common.Asset fee, + Common.Asset reward, + uint256 appliedDiscount + ); + + /** + * @notice Construct the FeeManager contract + * @param _linkAddress The address of the LINK token + * @param _nativeAddress The address of the wrapped ERC-20 version of the native token (represents fee in native or wrapped) + * @param _verifierAddress The address of the verifier contract + * @param _rewardManagerAddress The address of the reward manager contract + */ + constructor( + address _linkAddress, + address _nativeAddress, + address _verifierAddress, + address _rewardManagerAddress + ) ConfirmedOwner(msg.sender) { + if ( + _linkAddress == address(0) || + _nativeAddress == address(0) || + _verifierAddress == address(0) || + _rewardManagerAddress == address(0) + ) revert InvalidAddress(); + + i_linkAddress = _linkAddress; + i_nativeAddress = _nativeAddress; + s_verifierAddressList[_verifierAddress] = _verifierAddress; + i_rewardManager = IDestinationRewardManager(_rewardManagerAddress); + + IERC20(i_linkAddress).approve(address(i_rewardManager), type(uint256).max); + } + + modifier onlyOwnerOrVerifier() { + if (msg.sender != s_verifierAddressList[msg.sender] && msg.sender != owner()) revert Unauthorized(); + _; + } + + modifier onlyVerifier() { + if (msg.sender != s_verifierAddressList[msg.sender]) revert Unauthorized(); + _; + } + + /// @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "DestinationFeeManager 1.0.0"; + } + + /// @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { + //for each function in IDestinationFeeManager we need to check if it matches the selector + return + interfaceId == this.getFeeAndReward.selector || + interfaceId == this.setNativeSurcharge.selector || + interfaceId == this.updateSubscriberDiscount.selector || + interfaceId == this.withdraw.selector || + interfaceId == this.linkAvailableForPayment.selector || + interfaceId == this.payLinkDeficit.selector || + interfaceId == this.addVerifier.selector || + interfaceId == this.removeVerifier.selector || + interfaceId == this.processFee.selector || + interfaceId == this.processFeeBulk.selector || + interfaceId == this.setFeeRecipients.selector; + } + + function processFee( + bytes32 recipient, + bytes calldata payload, + bytes calldata parameterPayload, + address subscriber + ) external payable override onlyVerifier { + (Common.Asset memory fee, Common.Asset memory reward, uint256 appliedDiscount) = _calculateFee( + payload, + parameterPayload, + subscriber + ); + + if (fee.amount == 0) { + _tryReturnChange(subscriber, msg.value); + return; + } + + IDestinationFeeManager.FeeAndReward[] memory feeAndReward = new IDestinationFeeManager.FeeAndReward[](1); + feeAndReward[0] = IDestinationFeeManager.FeeAndReward(recipient, fee, reward, appliedDiscount); + + if (fee.assetAddress == i_linkAddress) { + _handleFeesAndRewards(subscriber, feeAndReward, 1, 0); + } else { + _handleFeesAndRewards(subscriber, feeAndReward, 0, 1); + } + } + + /// @inheritdoc IDestinationFeeManager + function processFeeBulk( + bytes32[] memory poolIds, + bytes[] calldata payloads, + bytes calldata parameterPayload, + address subscriber + ) external payable override onlyVerifier { + //poolIDs are mapped to payloads, so they should be the same length + if (poolIds.length != payloads.length) revert PoolIdMismatch(); + + IDestinationFeeManager.FeeAndReward[] memory feesAndRewards = new IDestinationFeeManager.FeeAndReward[]( + payloads.length + ); + + //keep track of the number of fees to prevent over initialising the FeePayment array within _convertToLinkAndNativeFees + uint256 numberOfLinkFees; + uint256 numberOfNativeFees; + + uint256 feesAndRewardsIndex; + for (uint256 i; i < payloads.length; ++i) { + if (poolIds[i] == bytes32(0)) revert InvalidAddress(); + + (Common.Asset memory fee, Common.Asset memory reward, uint256 appliedDiscount) = _calculateFee( + payloads[i], + parameterPayload, + subscriber + ); + + if (fee.amount != 0) { + feesAndRewards[feesAndRewardsIndex++] = IDestinationFeeManager.FeeAndReward( + poolIds[i], + fee, + reward, + appliedDiscount + ); + + unchecked { + //keep track of some tallys to make downstream calculations more efficient + if (fee.assetAddress == i_linkAddress) { + ++numberOfLinkFees; + } else { + ++numberOfNativeFees; + } + } + } + } + + if (numberOfLinkFees != 0 || numberOfNativeFees != 0) { + _handleFeesAndRewards(subscriber, feesAndRewards, numberOfLinkFees, numberOfNativeFees); + } else { + _tryReturnChange(subscriber, msg.value); + } + } + + /// @inheritdoc IDestinationFeeManager + function getFeeAndReward( + address subscriber, + bytes memory report, + address quoteAddress + ) public view returns (Common.Asset memory, Common.Asset memory, uint256) { + Common.Asset memory fee; + Common.Asset memory reward; + + //get the feedId from the report + bytes32 feedId = bytes32(report); + + //the report needs to be a support version + bytes32 reportVersion = _getReportVersion(feedId); + + //version 1 of the reports don't require quotes, so the fee will be 0 + if (reportVersion == REPORT_V1) { + fee.assetAddress = i_nativeAddress; + reward.assetAddress = i_linkAddress; + return (fee, reward, 0); + } + + //verify the quote payload is a supported token + if (quoteAddress != i_nativeAddress && quoteAddress != i_linkAddress) { + revert InvalidQuote(); + } + + //decode the report depending on the version + uint256 linkQuantity; + uint256 nativeQuantity; + uint256 expiresAt; + (, , , nativeQuantity, linkQuantity, expiresAt) = abi.decode( + report, + (bytes32, uint32, uint32, uint192, uint192, uint32) + ); + + //read the timestamp bytes from the report data and verify it has not expired + if (expiresAt < block.timestamp) { + revert ExpiredReport(); + } + + //get the discount being applied + uint256 discount = s_subscriberDiscounts[subscriber][feedId][quoteAddress]; + + //the reward is always set in LINK + reward.assetAddress = i_linkAddress; + reward.amount = Math.ceilDiv(linkQuantity * (PERCENTAGE_SCALAR - discount), PERCENTAGE_SCALAR); + + //calculate either the LINK fee or native fee if it's within the report + if (quoteAddress == i_linkAddress) { + fee.assetAddress = i_linkAddress; + fee.amount = reward.amount; + } else { + uint256 surchargedFee = Math.ceilDiv(nativeQuantity * (PERCENTAGE_SCALAR + s_nativeSurcharge), PERCENTAGE_SCALAR); + + fee.assetAddress = i_nativeAddress; + fee.amount = Math.ceilDiv(surchargedFee * (PERCENTAGE_SCALAR - discount), PERCENTAGE_SCALAR); + } + + //return the fee + return (fee, reward, discount); + } + + /// @inheritdoc IDestinationFeeManager + function setFeeRecipients( + bytes32 configDigest, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights + ) external onlyOwnerOrVerifier { + i_rewardManager.setRewardRecipients(configDigest, rewardRecipientAndWeights); + } + + /// @inheritdoc IDestinationFeeManager + function setNativeSurcharge(uint64 surcharge) external onlyOwner { + if (surcharge > PERCENTAGE_SCALAR) revert InvalidSurcharge(); + + s_nativeSurcharge = surcharge; + + emit NativeSurchargeUpdated(surcharge); + } + + /// @inheritdoc IDestinationFeeManager + function updateSubscriberDiscount( + address subscriber, + bytes32 feedId, + address token, + uint64 discount + ) external onlyOwner { + //make sure the discount is not greater than the total discount that can be applied + if (discount > PERCENTAGE_SCALAR) revert InvalidDiscount(); + //make sure the token is either LINK or native + if (token != i_linkAddress && token != i_nativeAddress) revert InvalidAddress(); + + s_subscriberDiscounts[subscriber][feedId][token] = discount; + + emit SubscriberDiscountUpdated(subscriber, feedId, token, discount); + } + + /// @inheritdoc IDestinationFeeManager + function withdraw(address assetAddress, address recipient, uint192 quantity) external onlyOwner { + //address 0 is used to withdraw native in the context of withdrawing + if (assetAddress == address(0)) { + (bool success, ) = payable(recipient).call{value: quantity}(""); + + if (!success) revert InvalidReceivingAddress(); + return; + } + + //withdraw the requested asset + IERC20(assetAddress).safeTransfer(recipient, quantity); + + //emit event when funds are withdrawn + emit Withdraw(msg.sender, recipient, assetAddress, uint192(quantity)); + } + + /// @inheritdoc IDestinationFeeManager + function linkAvailableForPayment() external view returns (uint256) { + //return the amount of LINK this contact has available to pay rewards + return IERC20(i_linkAddress).balanceOf(address(this)); + } + + /** + * @notice Gets the current version of the report that is encoded as the last two bytes of the feed + * @param feedId feed id to get the report version for + */ + function _getReportVersion(bytes32 feedId) internal pure returns (bytes32) { + return REPORT_VERSION_MASK & feedId; + } + + function _calculateFee( + bytes calldata payload, + bytes calldata parameterPayload, + address subscriber + ) internal view returns (Common.Asset memory, Common.Asset memory, uint256) { + if (subscriber == address(this)) revert InvalidAddress(); + + //decode the report from the payload + (, bytes memory report) = abi.decode(payload, (bytes32[3], bytes)); + + //get the feedId from the report + bytes32 feedId = bytes32(report); + + //v1 doesn't need a quote payload, so skip the decoding + address quote; + if (_getReportVersion(feedId) != REPORT_V1) { + //decode the quote from the bytes + (quote) = abi.decode(parameterPayload, (address)); + } + + //decode the fee, it will always be native or LINK + return getFeeAndReward(subscriber, report, quote); + } + + function _handleFeesAndRewards( + address subscriber, + IDestinationFeeManager.FeeAndReward[] memory feesAndRewards, + uint256 numberOfLinkFees, + uint256 numberOfNativeFees + ) internal { + IDestinationRewardManager.FeePayment[] memory linkRewards = new IDestinationRewardManager.FeePayment[]( + numberOfLinkFees + ); + IDestinationRewardManager.FeePayment[] memory nativeFeeLinkRewards = new IDestinationRewardManager.FeePayment[]( + numberOfNativeFees + ); + + uint256 totalNativeFee; + uint256 totalNativeFeeLinkValue; + + uint256 linkRewardsIndex; + uint256 nativeFeeLinkRewardsIndex; + + uint256 totalNumberOfFees = numberOfLinkFees + numberOfNativeFees; + for (uint256 i; i < totalNumberOfFees; ++i) { + if (feesAndRewards[i].fee.assetAddress == i_linkAddress) { + linkRewards[linkRewardsIndex++] = IDestinationRewardManager.FeePayment( + feesAndRewards[i].configDigest, + uint192(feesAndRewards[i].reward.amount) + ); + } else { + nativeFeeLinkRewards[nativeFeeLinkRewardsIndex++] = IDestinationRewardManager.FeePayment( + feesAndRewards[i].configDigest, + uint192(feesAndRewards[i].reward.amount) + ); + totalNativeFee += feesAndRewards[i].fee.amount; + totalNativeFeeLinkValue += feesAndRewards[i].reward.amount; + } + + if (feesAndRewards[i].appliedDiscount != 0) { + emit DiscountApplied( + feesAndRewards[i].configDigest, + subscriber, + feesAndRewards[i].fee, + feesAndRewards[i].reward, + feesAndRewards[i].appliedDiscount + ); + } + } + + //keep track of change in case of any over payment + uint256 change; + + if (msg.value != 0) { + //there must be enough to cover the fee + if (totalNativeFee > msg.value) revert InvalidDeposit(); + + //wrap the amount required to pay the fee & approve as the subscriber paid in wrapped native + IWERC20(i_nativeAddress).deposit{value: totalNativeFee}(); + + unchecked { + //msg.value is always >= to fee.amount + change = msg.value - totalNativeFee; + } + } else { + if (totalNativeFee != 0) { + //subscriber has paid in wrapped native, so transfer the native to this contract + IERC20(i_nativeAddress).safeTransferFrom(subscriber, address(this), totalNativeFee); + } + } + + if (linkRewards.length != 0) { + i_rewardManager.onFeePaid(linkRewards, subscriber); + } + + if (nativeFeeLinkRewards.length != 0) { + //distribute subsidised fees paid in Native + if (totalNativeFeeLinkValue > IERC20(i_linkAddress).balanceOf(address(this))) { + // If not enough LINK on this contract to forward for rewards, tally the deficit to be paid by out-of-band LINK + for (uint256 i; i < nativeFeeLinkRewards.length; ++i) { + unchecked { + //we have previously tallied the fees, any overflows would have already reverted + s_linkDeficit[nativeFeeLinkRewards[i].poolId] += nativeFeeLinkRewards[i].amount; + } + } + + emit InsufficientLink(nativeFeeLinkRewards); + } else { + //distribute the fees + i_rewardManager.onFeePaid(nativeFeeLinkRewards, address(this)); + } + } + + // a refund may be needed if the payee has paid in excess of the fee + _tryReturnChange(subscriber, change); + } + + function _tryReturnChange(address subscriber, uint256 quantity) internal { + if (quantity != 0) { + payable(subscriber).transfer(quantity); + } + } + + /// @inheritdoc IDestinationFeeManager + function payLinkDeficit(bytes32 configDigest) external onlyOwner { + uint256 deficit = s_linkDeficit[configDigest]; + + if (deficit == 0) revert ZeroDeficit(); + + delete s_linkDeficit[configDigest]; + + IDestinationRewardManager.FeePayment[] memory deficitFeePayment = new IDestinationRewardManager.FeePayment[](1); + + deficitFeePayment[0] = IDestinationRewardManager.FeePayment(configDigest, uint192(deficit)); + + i_rewardManager.onFeePaid(deficitFeePayment, address(this)); + + emit LinkDeficitCleared(configDigest, deficit); + } + + /// @inheritdoc IDestinationFeeManager + function addVerifier(address verifierAddress) external onlyOwner { + if (verifierAddress == address(0)) revert InvalidAddress(); + //check doesn't already exist + if (s_verifierAddressList[verifierAddress] != address(0)) revert InvalidAddress(); + s_verifierAddressList[verifierAddress] = verifierAddress; + } + + /// @inheritdoc IDestinationFeeManager + function removeVerifier(address verifierAddress) external onlyOwner { + if (verifierAddress == address(0)) revert InvalidAddress(); + //check doesn't already exist + if (s_verifierAddressList[verifierAddress] == address(0)) revert InvalidAddress(); + delete s_verifierAddressList[verifierAddress]; + } + + /// @inheritdoc IDestinationFeeManager + function setRewardManager(address rewardManagerAddress) external onlyOwner { + if (rewardManagerAddress == address(0)) revert InvalidAddress(); + IERC20(i_linkAddress).approve(address(i_rewardManager), 0); + i_rewardManager = IDestinationRewardManager(rewardManagerAddress); + IERC20(i_linkAddress).approve(address(i_rewardManager), type(uint256).max); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationRewardManager.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationRewardManager.sol new file mode 100644 index 0000000000..ae40a2385c --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationRewardManager.sol @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {IDestinationRewardManager} from "./interfaces/IDestinationRewardManager.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC20.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {Common} from "../libraries/Common.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +/** + * @title DestinationRewardManager + * @author Michael Fletcher + * @author Austin Born + * @notice This contract will be used to reward any configured recipients within a pool. Recipients will receive a share of their pool relative to their configured weight. + */ +contract DestinationRewardManager is IDestinationRewardManager, ConfirmedOwner, TypeAndVersionInterface { + using SafeERC20 for IERC20; + + // @dev The mapping of total fees collected for a particular pot: s_totalRewardRecipientFees[poolId] + mapping(bytes32 => uint256) public s_totalRewardRecipientFees; + + // @dev The mapping of fee balances for each pot last time the recipient claimed: s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient] + mapping(bytes32 => mapping(address => uint256)) public s_totalRewardRecipientFeesLastClaimedAmounts; + + // @dev The mapping of RewardRecipient weights for a particular poolId: s_rewardRecipientWeights[poolId][rewardRecipient]. + mapping(bytes32 => mapping(address => uint256)) public s_rewardRecipientWeights; + + // @dev Keep track of the reward recipient weights that have been set to prevent duplicates + mapping(bytes32 => bool) public s_rewardRecipientWeightsSet; + + // @dev Store a list of pool ids that have been registered, to make off chain lookups easier + bytes32[] public s_registeredPoolIds; + + // @dev The address for the LINK contract + address public immutable i_linkAddress; + + // The total weight of all RewardRecipients. 1e18 = 100% of the pool fees + uint64 private constant PERCENTAGE_SCALAR = 1e18; + + // The fee manager address + mapping(address => address) public s_feeManagerAddressList; + + // @notice Thrown whenever the RewardRecipient weights are invalid + error InvalidWeights(); + + // @notice Thrown when any given address is invalid + error InvalidAddress(); + + // @notice Thrown when the pool id is invalid + error InvalidPoolId(); + + // @notice Thrown when the calling contract is not within the authorized contracts + error Unauthorized(); + + // @notice Thrown when getAvailableRewardPoolIds parameters are incorrectly set + error InvalidPoolLength(); + + // Events emitted upon state change + event RewardRecipientsUpdated(bytes32 indexed poolId, Common.AddressAndWeight[] newRewardRecipients); + event RewardsClaimed(bytes32 indexed poolId, address indexed recipient, uint192 quantity); + event FeeManagerUpdated(address newFeeManagerAddress); + event FeePaid(FeePayment[] payments, address payer); + + /** + * @notice Constructor + * @param linkAddress address of the wrapped LINK token + */ + constructor(address linkAddress) ConfirmedOwner(msg.sender) { + //ensure that the address ia not zero + if (linkAddress == address(0)) revert InvalidAddress(); + + i_linkAddress = linkAddress; + } + + // @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "RewardManager 1.0.0"; + } + + // @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { + return + interfaceId == this.claimRewards.selector || + interfaceId == this.setRewardRecipients.selector || + interfaceId == this.updateRewardRecipients.selector || + interfaceId == this.payRecipients.selector || + interfaceId == this.addFeeManager.selector || + interfaceId == this.removeFeeManager.selector || + interfaceId == this.getAvailableRewardPoolIds.selector || + interfaceId == this.onFeePaid.selector; + } + + modifier onlyOwnerOrFeeManager() { + if (msg.sender != owner() && msg.sender != s_feeManagerAddressList[msg.sender]) revert Unauthorized(); + _; + } + + modifier onlyOwnerOrRecipientInPool(bytes32 poolId) { + if (msg.sender != owner() && s_rewardRecipientWeights[poolId][msg.sender] == 0) revert Unauthorized(); + _; + } + + modifier onlyFeeManager() { + if (msg.sender != s_feeManagerAddressList[msg.sender]) revert Unauthorized(); + _; + } + + /// @inheritdoc IDestinationRewardManager + function onFeePaid(FeePayment[] calldata payments, address payer) external override onlyFeeManager { + uint256 totalFeeAmount; + for (uint256 i; i < payments.length; ++i) { + unchecked { + //the total amount for any ERC-20 asset cannot exceed 2^256 - 1 + //see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/36bf1e46fa811f0f07d38eb9cfbc69a955f300ce/contracts/token/ERC20/ERC20.sol#L266 + //for example implementation. + s_totalRewardRecipientFees[payments[i].poolId] += payments[i].amount; + + //tally the total payable fees + totalFeeAmount += payments[i].amount; + } + } + + //transfer the fees to this contract + IERC20(i_linkAddress).safeTransferFrom(payer, address(this), totalFeeAmount); + + emit FeePaid(payments, payer); + } + + /// @inheritdoc IDestinationRewardManager + function claimRewards(bytes32[] memory poolIds) external override { + _claimRewards(msg.sender, poolIds); + } + + // wrapper impl for claimRewards + function _claimRewards(address recipient, bytes32[] memory poolIds) internal returns (uint256) { + //get the total amount claimable for this recipient + uint256 claimAmount; + + //loop and claim all the rewards in the poolId pot + for (uint256 i; i < poolIds.length; ++i) { + //get the poolId to be claimed + bytes32 poolId = poolIds[i]; + + //get the total fees for the pot + uint256 totalFeesInPot = s_totalRewardRecipientFees[poolId]; + + unchecked { + //avoid unnecessary storage reads if there's no fees in the pot + if (totalFeesInPot == 0) continue; + + //get the claimable amount for this recipient, this calculation will never exceed the amount in the pot + uint256 claimableAmount = totalFeesInPot - s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient]; + + //calculate the recipients share of the fees, which is their weighted share of the difference between the last amount they claimed and the current amount in the pot. This can never be more than the total amount in existence + uint256 recipientShare = (claimableAmount * s_rewardRecipientWeights[poolId][recipient]) / PERCENTAGE_SCALAR; + + //if there's no fees to claim, continue as there's nothing to update + if (recipientShare == 0) continue; + + //keep track of the total amount claimable, this can never be more than the total amount in existence + claimAmount += recipientShare; + + //set the current total amount of fees in the pot as it's used to calculate future claims + s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient] = totalFeesInPot; + + //emit event if the recipient has rewards to claim + emit RewardsClaimed(poolIds[i], recipient, uint192(recipientShare)); + } + } + + //check if there's any rewards to claim in the given poolId + if (claimAmount != 0) { + //transfer the reward to the recipient + IERC20(i_linkAddress).safeTransfer(recipient, claimAmount); + } + + return claimAmount; + } + + /// @inheritdoc IDestinationRewardManager + function setRewardRecipients( + bytes32 poolId, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights + ) external override onlyOwnerOrFeeManager { + //revert if there are no recipients to set + if (rewardRecipientAndWeights.length == 0) revert InvalidAddress(); + + //check that the weights have not been previously set + if (s_rewardRecipientWeightsSet[poolId]) revert InvalidPoolId(); + + //keep track of the registered poolIds to make off chain lookups easier + s_registeredPoolIds.push(poolId); + + //keep track of which pools have had their reward recipients set + s_rewardRecipientWeightsSet[poolId] = true; + + //set the reward recipients, this will only be called once and contain the full set of RewardRecipients with a total weight of 100% + _setRewardRecipientWeights(poolId, rewardRecipientAndWeights, PERCENTAGE_SCALAR); + + emit RewardRecipientsUpdated(poolId, rewardRecipientAndWeights); + } + + function _setRewardRecipientWeights( + bytes32 poolId, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights, + uint256 expectedWeight + ) internal { + //we can't update the weights if it contains duplicates + if (Common._hasDuplicateAddresses(rewardRecipientAndWeights)) revert InvalidAddress(); + + //loop all the reward recipients and validate the weight and address + uint256 totalWeight; + for (uint256 i; i < rewardRecipientAndWeights.length; ++i) { + //get the weight + uint256 recipientWeight = rewardRecipientAndWeights[i].weight; + //get the address + address recipientAddress = rewardRecipientAndWeights[i].addr; + + //ensure the reward recipient address is not zero + if (recipientAddress == address(0)) revert InvalidAddress(); + + //save/overwrite the weight for the reward recipient + s_rewardRecipientWeights[poolId][recipientAddress] = recipientWeight; + + unchecked { + //keep track of the cumulative weight, this cannot overflow as the total weight is restricted at 1e18 + totalWeight += recipientWeight; + } + } + + //if total weight is not met, the fees will either be under or over distributed + if (totalWeight != expectedWeight) revert InvalidWeights(); + } + + /// @inheritdoc IDestinationRewardManager + function updateRewardRecipients( + bytes32 poolId, + Common.AddressAndWeight[] calldata newRewardRecipients + ) external override onlyOwner { + //create an array of poolIds to pass to _claimRewards if required + bytes32[] memory poolIds = new bytes32[](1); + poolIds[0] = poolId; + + //loop all the reward recipients and claim their rewards before updating their weights + uint256 existingTotalWeight; + for (uint256 i; i < newRewardRecipients.length; ++i) { + //get the address + address recipientAddress = newRewardRecipients[i].addr; + //get the existing weight + uint256 existingWeight = s_rewardRecipientWeights[poolId][recipientAddress]; + + //if a recipient is updated, the rewards must be claimed first as they can't claim previous fees at the new weight + _claimRewards(newRewardRecipients[i].addr, poolIds); + + unchecked { + //keep tally of the weights so that the expected collective weight is known + existingTotalWeight += existingWeight; + } + } + + //update the reward recipients, if the new collective weight isn't equal to the previous collective weight, the fees will either be under or over distributed + _setRewardRecipientWeights(poolId, newRewardRecipients, existingTotalWeight); + + //emit event + emit RewardRecipientsUpdated(poolId, newRewardRecipients); + } + + /// @inheritdoc IDestinationRewardManager + function payRecipients(bytes32 poolId, address[] calldata recipients) external onlyOwnerOrRecipientInPool(poolId) { + //convert poolIds to an array to match the interface of _claimRewards + bytes32[] memory poolIdsArray = new bytes32[](1); + poolIdsArray[0] = poolId; + + //loop each recipient and claim the rewards for each of the pools and assets + for (uint256 i; i < recipients.length; ++i) { + _claimRewards(recipients[i], poolIdsArray); + } + } + + /// @inheritdoc IDestinationRewardManager + function addFeeManager(address newFeeManagerAddress) external onlyOwner { + if (newFeeManagerAddress == address(0)) revert InvalidAddress(); + if (s_feeManagerAddressList[newFeeManagerAddress] != address(0)) revert InvalidAddress(); + + s_feeManagerAddressList[newFeeManagerAddress] = newFeeManagerAddress; + + emit FeeManagerUpdated(newFeeManagerAddress); + } + + /// @inheritdoc IDestinationRewardManager + function removeFeeManager(address feeManagerAddress) external onlyOwner { + if (s_feeManagerAddressList[feeManagerAddress] == address(0)) revert InvalidAddress(); + delete s_feeManagerAddressList[feeManagerAddress]; + } + + /// @inheritdoc IDestinationRewardManager + function getAvailableRewardPoolIds( + address recipient, + uint256 startIndex, + uint256 endIndex + ) external view returns (bytes32[] memory) { + //get the length of the pool ids which we will loop through and potentially return + uint256 registeredPoolIdsLength = s_registeredPoolIds.length; + + uint256 lastIndex = endIndex > registeredPoolIdsLength ? registeredPoolIdsLength : endIndex; + + if (startIndex > lastIndex) revert InvalidPoolLength(); + + //create a new array with the maximum amount of potential pool ids + bytes32[] memory claimablePoolIds = new bytes32[](lastIndex - startIndex); + //we want the pools which a recipient has funds for to be sequential, so we need to keep track of the index + uint256 poolIdArrayIndex; + + //loop all the pool ids, and check if the recipient has a registered weight and a claimable amount + for (uint256 i = startIndex; i < lastIndex; ++i) { + //get the poolId + bytes32 poolId = s_registeredPoolIds[i]; + + //if the recipient has a weight, they are a recipient of this poolId + if (s_rewardRecipientWeights[poolId][recipient] != 0) { + //get the total in this pool + uint256 totalPoolAmount = s_totalRewardRecipientFees[poolId]; + //if the recipient has any LINK, then add the poolId to the array + unchecked { + //s_totalRewardRecipientFeesLastClaimedAmounts can never exceed total pool amount, and the number of pools can't exceed the max array length + if (totalPoolAmount - s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient] != 0) { + claimablePoolIds[poolIdArrayIndex++] = poolId; + } + } + } + } + + return claimablePoolIds; + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifier.sol new file mode 100644 index 0000000000..52b2bd7c9a --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifier.sol @@ -0,0 +1,434 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {IDestinationVerifier} from "./interfaces/IDestinationVerifier.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../libraries/Common.sol"; +import {IAccessController} from "../../shared/interfaces/IAccessController.sol"; +import {IDestinationVerifierProxy} from "./interfaces/IDestinationVerifierProxy.sol"; +import {IDestinationFeeManager} from "./interfaces/IDestinationFeeManager.sol"; + +// OCR2 standard +uint256 constant MAX_NUM_ORACLES = 31; + +/** + * @title DestinationVerifier + * @author Michael Fletcher + * @notice This contract will be used to verify reports based on the oracle signatures. This is not the source verifier which required individual fee configurations, instead, this checks that a report has been signed by one of the configured oracles. + */ +contract DestinationVerifier is IDestinationVerifier, ConfirmedOwner, TypeAndVersionInterface, IERC165 { + /// @notice The list of DON configurations by hash(address|donConfigId) - set to true if the signer is part of the config + mapping(bytes32 => bool) private s_signerByAddressAndDonConfigId; + + /// array of DON configs + DonConfig[] private s_donConfigs; + + /// @notice The address of the verifierProxy + address public s_feeManager; + + /// @notice The address of the access controller + address public s_accessController; + + /// @notice The address of the verifierProxy + IDestinationVerifierProxy public immutable i_verifierProxy; + + /// @notice This error is thrown whenever trying to set a config + /// with a fault tolerance of 0 + error FaultToleranceMustBePositive(); + + /// @notice This error is thrown whenever a report is signed + /// with more than the max number of signers + /// @param numSigners The number of signers who have signed the report + /// @param maxSigners The maximum number of signers that can sign a report + error ExcessSigners(uint256 numSigners, uint256 maxSigners); + + /// @notice This error is thrown whenever a report is signed or expected to be signed with less than the minimum number of signers + /// @param numSigners The number of signers who have signed the report + /// @param minSigners The minimum number of signers that need to sign a report + error InsufficientSigners(uint256 numSigners, uint256 minSigners); + + /// @notice This error is thrown whenever a report is submitted with no signatures + error NoSigners(); + + /// @notice This error is thrown whenever a DonConfig already exists + /// @param donConfigId The ID of the DonConfig that already exists + error DonConfigAlreadyExists(bytes24 donConfigId); + + /// @notice This error is thrown whenever the R and S signer components + /// have different lengths + /// @param rsLength The number of r signature components + /// @param ssLength The number of s signature components + error MismatchedSignatures(uint256 rsLength, uint256 ssLength); + + /// @notice This error is thrown whenever setting a config with duplicate signatures + error NonUniqueSignatures(); + + /* @notice This error is thrown whenever a report fails to verify. This error be thrown for multiple reasons and it's purposely like + * this to prevent information being leaked about the verification process which could be used to enable free verifications maliciously + */ + error BadVerification(); + + /// @notice This error is thrown whenever a zero address is passed + error ZeroAddress(); + + /// @notice This error is thrown when the fee manager at an address does + /// not conform to the fee manager interface + error FeeManagerInvalid(); + + /// @notice This error is thrown whenever an address tries + /// to execute a verification that it is not authorized to do so + error AccessForbidden(); + + /// @notice This error is thrown whenever a config does not exist + error DonConfigDoesNotExist(); + + /// @notice this error is thrown when the verifierProxy is incorrect when initialising + error VerifierProxyInvalid(); + + /// @notice This error is thrown when the activation time is either in the future or less than the current configs + error BadActivationTime(); + + /// @notice This event is emitted when a new report is verified. + /// It is used to keep a historical record of verified reports. + event ReportVerified(bytes32 indexed feedId, address requester); + + /// @notice This event is emitted whenever a configuration is activated or deactivated + event ConfigActivated(bytes24 donConfigId, bool isActive); + + /// @notice This event is emitted whenever a configuration is removed + event ConfigRemoved(bytes24 donConfigId); + + /// @notice event is emitted whenever a new DON Config is set + event ConfigSet( + bytes24 indexed donConfigId, + address[] signers, + uint8 f, + Common.AddressAndWeight[] recipientAddressesAndWeights + ); + + /// @notice This event is emitted when a new fee manager is set + /// @param oldFeeManager The old fee manager address + /// @param newFeeManager The new fee manager address + event FeeManagerSet(address oldFeeManager, address newFeeManager); + + /// @notice This event is emitted when a new access controller is set + /// @param oldAccessController The old access controller address + /// @param newAccessController The new access controller address + event AccessControllerSet(address oldAccessController, address newAccessController); + + struct DonConfig { + // The ID of the DonConfig + bytes24 donConfigId; + // Fault tolerance of the DON + uint8 f; + // Whether the config is active + bool isActive; + // The time the config was set + uint32 activationTime; + } + + constructor(address verifierProxy) ConfirmedOwner(msg.sender) { + if (verifierProxy == address(0)) { + revert ZeroAddress(); + } + + i_verifierProxy = IDestinationVerifierProxy(verifierProxy); + } + + /// @inheritdoc IDestinationVerifier + function verify( + bytes calldata signedReport, + bytes calldata parameterPayload, + address sender + ) external payable override checkValidProxy checkAccess(sender) returns (bytes memory) { + (bytes memory verifierResponse, bytes32 donConfigId) = _verify(signedReport, sender); + + address fm = s_feeManager; + if (fm != address(0)) { + //process the fee and catch the error + try IDestinationFeeManager(fm).processFee{value: msg.value}(donConfigId, signedReport, parameterPayload, sender) { + //do nothing + } catch { + // we purposefully obfuscate the error here to prevent information leaking leading to free verifications + revert BadVerification(); + } + } + + return verifierResponse; + } + + /// @inheritdoc IDestinationVerifier + function verifyBulk( + bytes[] calldata signedReports, + bytes calldata parameterPayload, + address sender + ) external payable override checkValidProxy checkAccess(sender) returns (bytes[] memory) { + bytes[] memory verifierResponses = new bytes[](signedReports.length); + bytes32[] memory donConfigs = new bytes32[](signedReports.length); + + for (uint256 i; i < signedReports.length; ++i) { + (bytes memory report, bytes32 config) = _verify(signedReports[i], sender); + verifierResponses[i] = report; + donConfigs[i] = config; + } + + address fm = s_feeManager; + if (fm != address(0)) { + //process the fee and catch the error + try + IDestinationFeeManager(fm).processFeeBulk{value: msg.value}(donConfigs, signedReports, parameterPayload, sender) + { + //do nothing + } catch { + // we purposefully obfuscate the error here to prevent information leaking leading to free verifications + revert BadVerification(); + } + } + + return verifierResponses; + } + + function _verify(bytes calldata signedReport, address sender) internal returns (bytes memory, bytes32) { + ( + bytes32[3] memory reportContext, + bytes memory reportData, + bytes32[] memory rs, + bytes32[] memory ss, + bytes32 rawVs + ) = abi.decode(signedReport, (bytes32[3], bytes, bytes32[], bytes32[], bytes32)); + + // Signature lengths must match + if (rs.length != ss.length) revert MismatchedSignatures(rs.length, ss.length); + + //Must always be at least 1 signer + if (rs.length == 0) revert NoSigners(); + + // The payload is hashed and signed by the oracles - we need to recover the addresses + bytes32 signedPayload = keccak256(abi.encodePacked(keccak256(reportData), reportContext)); + address[] memory signers = new address[](rs.length); + for (uint256 i; i < rs.length; ++i) { + signers[i] = ecrecover(signedPayload, uint8(rawVs[i]) + 27, rs[i], ss[i]); + } + + // Duplicate signatures are not allowed + if (Common._hasDuplicateAddresses(signers)) { + revert BadVerification(); + } + + //We need to know the timestamp the report was generated to lookup the active activeDonConfig + uint256 reportTimestamp = _decodeReportTimestamp(reportData); + + // Find the latest config for this report + DonConfig memory activeDonConfig = _findActiveConfig(reportTimestamp); + + // Check a config has been set + if (activeDonConfig.donConfigId == bytes24(0)) { + revert BadVerification(); + } + + //check the config is active + if (!activeDonConfig.isActive) { + revert BadVerification(); + } + + //check we have enough signatures + if (signers.length <= activeDonConfig.f) { + revert BadVerification(); + } + + //check each signer is registered against the active DON + bytes32 signerDonConfigKey; + for (uint256 i; i < signers.length; ++i) { + signerDonConfigKey = keccak256(abi.encodePacked(signers[i], activeDonConfig.donConfigId)); + if (!s_signerByAddressAndDonConfigId[signerDonConfigKey]) { + revert BadVerification(); + } + } + + emit ReportVerified(bytes32(reportData), sender); + + return (reportData, activeDonConfig.donConfigId); + } + + /// @inheritdoc IDestinationVerifier + function setConfigWithActivationTime( + address[] memory signers, + uint8 f, + Common.AddressAndWeight[] memory recipientAddressesAndWeights, + uint32 activationTime + ) external override checkConfigValid(signers.length, f) onlyOwner { + _setConfig(signers, f, recipientAddressesAndWeights, activationTime); + } + + /// @inheritdoc IDestinationVerifier + function setConfig( + address[] memory signers, + uint8 f, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external override checkConfigValid(signers.length, f) onlyOwner { + _setConfig(signers, f, recipientAddressesAndWeights, uint32(block.timestamp)); + } + + function _setConfig( + address[] memory signers, + uint8 f, + Common.AddressAndWeight[] memory recipientAddressesAndWeights, + uint32 activationTime + ) internal checkConfigValid(signers.length, f) onlyOwner { + // Duplicate addresses would break protocol rules + if (Common._hasDuplicateAddresses(signers)) { + revert NonUniqueSignatures(); + } + + //activation time cannot be in the future + if (activationTime > block.timestamp) { + revert BadActivationTime(); + } + + // Sort signers to ensure donConfigId is deterministic + Common._quickSort(signers, 0, int256(signers.length - 1)); + + //DonConfig is made up of hash(signers|f) + bytes24 donConfigId = bytes24(keccak256(abi.encodePacked(signers, f))); + + // Register the signers for this DON + for (uint256 i; i < signers.length; ++i) { + if (signers[i] == address(0)) revert ZeroAddress(); + /** This index is registered so we can efficiently lookup whether a NOP is part of a config without having to + loop through the entire config each verification. It's effectively a DonConfig <-> Signer + composite key which keys track of all historic configs for a signer */ + s_signerByAddressAndDonConfigId[keccak256(abi.encodePacked(signers[i], donConfigId))] = true; + } + + // Check the activation time is greater than the latest config + uint256 donConfigLength = s_donConfigs.length; + if (donConfigLength > 0 && s_donConfigs[donConfigLength - 1].activationTime > activationTime) { + revert BadActivationTime(); + } + + // Check the config we're setting isn't already set as the current active config as this will increase search costs unnecessarily when verifying historic reports + if (donConfigLength > 0 && s_donConfigs[donConfigLength - 1].donConfigId == donConfigId) { + revert DonConfigAlreadyExists(donConfigId); + } + + // We may want to register these later or skip this step in the unlikely scenario they've previously been registered in the RewardsManager + if (recipientAddressesAndWeights.length != 0) { + IDestinationFeeManager(s_feeManager).setFeeRecipients(donConfigId, recipientAddressesAndWeights); + } + + // push the DonConfig + s_donConfigs.push(DonConfig(donConfigId, f, true, activationTime)); + + emit ConfigSet(donConfigId, signers, f, recipientAddressesAndWeights); + } + + /// @inheritdoc IDestinationVerifier + function setFeeManager(address feeManager) external override onlyOwner { + if ( + !IERC165(feeManager).supportsInterface(IDestinationFeeManager.processFee.selector) || + !IERC165(feeManager).supportsInterface(IDestinationFeeManager.processFeeBulk.selector) || + !IERC165(feeManager).supportsInterface(IDestinationFeeManager.setFeeRecipients.selector) + ) revert FeeManagerInvalid(); + + address oldFeeManager = s_feeManager; + s_feeManager = feeManager; + + emit FeeManagerSet(oldFeeManager, feeManager); + } + + /// @inheritdoc IDestinationVerifier + function setAccessController(address accessController) external override onlyOwner { + address oldAccessController = s_accessController; + s_accessController = accessController; + emit AccessControllerSet(oldAccessController, accessController); + } + + /// @inheritdoc IDestinationVerifier + function setConfigActive(uint256 donConfigIndex, bool isActive) external onlyOwner { + // Config must exist + if (donConfigIndex >= s_donConfigs.length) { + revert DonConfigDoesNotExist(); + } + + // Update the config + DonConfig storage config = s_donConfigs[donConfigIndex]; + config.isActive = isActive; + + emit ConfigActivated(config.donConfigId, isActive); + } + + /// @inheritdoc IDestinationVerifier + function removeLatestConfig() external onlyOwner { + if (s_donConfigs.length == 0) { + revert DonConfigDoesNotExist(); + } + + DonConfig memory config = s_donConfigs[s_donConfigs.length - 1]; + + s_donConfigs.pop(); + + emit ConfigRemoved(config.donConfigId); + } + + function _decodeReportTimestamp(bytes memory reportPayload) internal pure returns (uint256) { + (, , uint256 timestamp) = abi.decode(reportPayload, (bytes32, uint32, uint32)); + + return timestamp; + } + + function _findActiveConfig(uint256 timestamp) internal view returns (DonConfig memory) { + DonConfig memory activeDonConfig; + + // 99% of the time the signer config will be the last index, however for historic reports generated by a previous configuration we'll need to cycle back + uint256 i = s_donConfigs.length; + while (i > 0) { + --i; + if (s_donConfigs[i].activationTime <= timestamp) { + activeDonConfig = s_donConfigs[i]; + break; + } + } + return activeDonConfig; + } + + modifier checkConfigValid(uint256 numSigners, uint256 f) { + if (f == 0) revert FaultToleranceMustBePositive(); + if (numSigners > MAX_NUM_ORACLES) revert ExcessSigners(numSigners, MAX_NUM_ORACLES); + if (numSigners <= 3 * f) revert InsufficientSigners(numSigners, 3 * f + 1); + _; + } + + modifier checkValidProxy() { + if (address(i_verifierProxy) != msg.sender) { + revert AccessForbidden(); + } + _; + } + + modifier checkAccess(address sender) { + address ac = s_accessController; + if (address(ac) != address(0) && !IAccessController(ac).hasAccess(sender, msg.data)) revert AccessForbidden(); + _; + } + + /// @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { + return + interfaceId == this.verify.selector || + interfaceId == this.verifyBulk.selector || + interfaceId == this.s_accessController.selector || + interfaceId == this.s_feeManager.selector || + interfaceId == this.setConfig.selector || + interfaceId == this.setConfigWithActivationTime.selector || + interfaceId == this.setFeeManager.selector || + interfaceId == this.setAccessController.selector || + interfaceId == this.setConfigActive.selector; + } + + /// @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "DestinationVerifier 1.0.0"; + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifierProxy.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifierProxy.sol new file mode 100644 index 0000000000..1a5c62b429 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifierProxy.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {IDestinationVerifierProxy} from "./interfaces/IDestinationVerifierProxy.sol"; +import {IDestinationVerifier} from "./interfaces/IDestinationVerifier.sol"; + +/** + * @title DestinationVerifierProxy + * @author Michael Fletcher + * @notice This contract will be used to route all requests through to the assigned verifier contract. This contract does not support individual feed configurations and is aimed at being a simple proxy for the verifier contract on any destination chain. + */ +contract DestinationVerifierProxy is IDestinationVerifierProxy, ConfirmedOwner, TypeAndVersionInterface, IERC165 { + /// @notice The active verifier for this proxy + IDestinationVerifier private s_verifier; + + /// @notice This error is thrown whenever a zero address is passed + error ZeroAddress(); + + /// @notice This error is thrown when trying to set a verifier address that does not implement the expected interface + error VerifierInvalid(address verifierAddress); + + constructor() ConfirmedOwner(msg.sender) {} + + /// @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "DestinationVerifierProxy 1.0.0"; + } + + /// @inheritdoc IDestinationVerifierProxy + function verify(bytes calldata payload, bytes calldata parameterPayload) external payable returns (bytes memory) { + return s_verifier.verify{value: msg.value}(payload, parameterPayload, msg.sender); + } + + /// @inheritdoc IDestinationVerifierProxy + function verifyBulk( + bytes[] calldata payloads, + bytes calldata parameterPayload + ) external payable returns (bytes[] memory verifiedReports) { + return s_verifier.verifyBulk{value: msg.value}(payloads, parameterPayload, msg.sender); + } + + /// @inheritdoc IDestinationVerifierProxy + function setVerifier(address verifierAddress) external onlyOwner { + //check it supports the functions we need + if ( + !IERC165(verifierAddress).supportsInterface(IDestinationVerifier.s_accessController.selector) || + !IERC165(verifierAddress).supportsInterface(IDestinationVerifier.s_feeManager.selector) || + !IERC165(verifierAddress).supportsInterface(IDestinationVerifier.verify.selector) || + !IERC165(verifierAddress).supportsInterface(IDestinationVerifier.verifyBulk.selector) + ) revert VerifierInvalid(verifierAddress); + + s_verifier = IDestinationVerifier(verifierAddress); + } + + /// @inheritdoc IDestinationVerifierProxy + // solhint-disable-next-line func-name-mixedcase + function s_feeManager() external view override returns (address) { + return s_verifier.s_feeManager(); + } + + /// @inheritdoc IDestinationVerifierProxy + // solhint-disable-next-line func-name-mixedcase + function s_accessController() external view override returns (address) { + return s_verifier.s_accessController(); + } + + /// @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { + return + interfaceId == this.setVerifier.selector || + interfaceId == this.verify.selector || + interfaceId == this.verifyBulk.selector || + interfaceId == this.s_feeManager.selector || + interfaceId == this.s_accessController.selector; + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationFeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationFeeManager.sol new file mode 100644 index 0000000000..f92e7cd146 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationFeeManager.sol @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; + +interface IDestinationFeeManager is IERC165 { + /** + * @notice Calculate the applied fee and the reward from a report. If the sender is a subscriber, they will receive a discount. + * @param subscriber address trying to verify + * @param report report to calculate the fee for + * @param quoteAddress address of the quote payment token + * @return (fee, reward, totalDiscount) fee and the reward data with the discount applied + */ + function getFeeAndReward( + address subscriber, + bytes memory report, + address quoteAddress + ) external returns (Common.Asset memory, Common.Asset memory, uint256); + + /** + * @notice Sets the native surcharge + * @param surcharge surcharge to be paid if paying in native + */ + function setNativeSurcharge(uint64 surcharge) external; + + /** + * @notice Adds a subscriber to the fee manager + * @param subscriber address of the subscriber + * @param feedId feed id to apply the discount to + * @param token token to apply the discount to + * @param discount discount to be applied to the fee + */ + function updateSubscriberDiscount(address subscriber, bytes32 feedId, address token, uint64 discount) external; + + /** + * @notice Withdraws any native or LINK rewards to the owner address + * @param assetAddress address of the asset to withdraw + * @param recipientAddress address to withdraw to + * @param quantity quantity to withdraw + */ + function withdraw(address assetAddress, address recipientAddress, uint192 quantity) external; + + /** + * @notice Returns the link balance of the fee manager + * @return link balance of the fee manager + */ + function linkAvailableForPayment() external returns (uint256); + + /** + * @notice Admin function to pay the LINK deficit for a given config digest + * @param configDigest the config digest to pay the deficit for + */ + function payLinkDeficit(bytes32 configDigest) external; + + /** + * @notice Adds the verifier to the list of verifiers able to use the feeManager + * @param verifier address of the verifier + */ + function addVerifier(address verifier) external; + + /** + * @notice Removes the verifier from the list of verifiers able to use the feeManager + * @param verifier address of the verifier + */ + function removeVerifier(address verifier) external; + + /** + * @notice Sets the reward manager to the address + * @param rewardManager address of the reward manager + */ + function setRewardManager(address rewardManager) external; + + /** + * @notice Handles fees for a report from the subscriber and manages rewards + * @param poolId pool id of the pool to pay into + * @param payload report to process the fee for + * @param parameterPayload fee payload + * @param subscriber address of the fee will be applied + */ + function processFee( + bytes32 poolId, + bytes calldata payload, + bytes calldata parameterPayload, + address subscriber + ) external payable; + + /** + * @notice Processes the fees for each report in the payload, billing the subscriber and paying the reward manager + * @param poolIds pool ids of the pool to pay into + * @param payloads reports to process + * @param parameterPayload fee payload + * @param subscriber address of the user to process fee for + */ + function processFeeBulk( + bytes32[] memory poolIds, + bytes[] calldata payloads, + bytes calldata parameterPayload, + address subscriber + ) external payable; + + /** + * @notice Sets the fee recipients according to the fee manager + * @param configDigest digest of the configuration + * @param rewardRecipientAndWeights the address and weights of all the recipients to receive rewards + */ + function setFeeRecipients( + bytes32 configDigest, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights + ) external; + + /** + * @notice The structure to hold a fee and reward to verify a report + * @param digest the digest linked to the fee and reward + * @param fee the fee paid to verify the report + * @param reward the reward paid upon verification + & @param appliedDiscount the discount applied to the reward + */ + struct FeeAndReward { + bytes32 configDigest; + Common.Asset fee; + Common.Asset reward; + uint256 appliedDiscount; + } + + /** + * @notice The structure to hold quote metadata + * @param quoteAddress the address of the quote + */ + struct Quote { + address quoteAddress; + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationRewardManager.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationRewardManager.sol new file mode 100644 index 0000000000..95f07937ae --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationRewardManager.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; + +interface IDestinationRewardManager is IERC165 { + /** + * @notice Record the fee received for a particular pool + * @param payments array of structs containing pool id and amount + * @param payee the user the funds should be retrieved from + */ + function onFeePaid(FeePayment[] calldata payments, address payee) external; + + /** + * @notice Claims the rewards in a specific pool + * @param poolIds array of poolIds to claim rewards for + */ + function claimRewards(bytes32[] calldata poolIds) external; + + /** + * @notice Set the RewardRecipients and weights for a specific pool. This should only be called once per pool Id. Else updateRewardRecipients should be used. + * @param poolId poolId to set RewardRecipients and weights for + * @param rewardRecipientAndWeights array of each RewardRecipient and associated weight + */ + function setRewardRecipients(bytes32 poolId, Common.AddressAndWeight[] calldata rewardRecipientAndWeights) external; + + /** + * @notice Updates a subset the reward recipients for a specific poolId. The collective weight of the recipients should add up to the recipients existing weights. Any recipients with a weight of 0 will be removed. + * @param poolId the poolId to update + * @param newRewardRecipients array of new reward recipients + */ + function updateRewardRecipients(bytes32 poolId, Common.AddressAndWeight[] calldata newRewardRecipients) external; + + /** + * @notice Pays all the recipients for each of the pool ids + * @param poolId the pool id to pay recipients for + * @param recipients array of recipients to pay within the pool + */ + function payRecipients(bytes32 poolId, address[] calldata recipients) external; + + /** + * @notice Add the fee manager to the list of feeManagers able to call the reward manager + * @param newFeeManager address of the new verifier proxy + */ + function addFeeManager(address newFeeManager) external; + + /** + * @notice Removes the fee manager. This needs to be done post construction to prevent a circular dependency. + * @param feeManager address of the verifier proxy to remove + */ + function removeFeeManager(address feeManager) external; + + /** + * @notice Gets a list of pool ids which have reward for a specific recipient. + * @param recipient address of the recipient to get pool ids for + * @param startIndex the index to start from + * @param endIndex the index to stop at + */ + function getAvailableRewardPoolIds( + address recipient, + uint256 startIndex, + uint256 endIndex + ) external view returns (bytes32[] memory); + + /** + * @notice The structure to hold a fee payment notice + * @param poolId the poolId receiving the payment + * @param amount the amount being paid + */ + struct FeePayment { + bytes32 poolId; + uint192 amount; + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifier.sol new file mode 100644 index 0000000000..69516f6e92 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifier.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {Common} from "../../libraries/Common.sol"; + +interface IDestinationVerifier { + /** + * @notice Verifies that the data encoded has been signed correctly using the signatures included within the payload. + * @param signedReport The encoded data to be verified. + * @param parameterPayload The encoded parameters to be used in the verification and billing process. + * @param sender The address that requested to verify the contract.Used for logging and applying the fee. + * @dev Verification is typically only done through the proxy contract so we can't just use msg.sender. + * @return verifierResponse The encoded verified response. + */ + function verify( + bytes calldata signedReport, + bytes calldata parameterPayload, + address sender + ) external payable returns (bytes memory verifierResponse); + + /** + * @notice Bulk verifies that the data encoded has been signed correctly using the signatures included within the payload. + * @param signedReports The encoded data to be verified. + * @param parameterPayload The encoded parameters to be used in the verification and billing process. + * @param sender The address that requested to verify the contract. Used for logging and applying the fee. + * @dev Verification is typically only done through the proxy contract so we can't just use msg.sender. + * @return verifiedReports The encoded verified responses. + */ + function verifyBulk( + bytes[] calldata signedReports, + bytes calldata parameterPayload, + address sender + ) external payable returns (bytes[] memory verifiedReports); + + /** + * @notice sets off-chain reporting protocol configuration incl. participating oracles + * @param signers addresses with which oracles sign the reports + * @param f number of faulty oracles the system can tolerate + * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards + */ + function setConfig( + address[] memory signers, + uint8 f, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external; + + /** + * @notice sets off-chain reporting protocol configuration incl. participating oracles + * @param signers addresses with which oracles sign the reports + * @param f number of faulty oracles the system can tolerate + * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards + * @param activationTime the time at which the config was activated + */ + function setConfigWithActivationTime( + address[] memory signers, + uint8 f, + Common.AddressAndWeight[] memory recipientAddressesAndWeights, + uint32 activationTime + ) external; + + /** + * @notice Sets the fee manager address + * @param feeManager The address of the fee manager + */ + function setFeeManager(address feeManager) external; + + /** + * @notice Sets the access controller address + * @param accessController The address of the access controller + */ + function setAccessController(address accessController) external; + + /** + * @notice Updates the config active status + * @param donConfigId The ID of the config to update + * @param isActive The new config active status + */ + function setConfigActive(uint256 donConfigId, bool isActive) external; + + /** + * @notice Removes the latest config + */ + function removeLatestConfig() external; + + /* + * @notice Returns the reward manager + * @return IDestinationRewardManager + */ + // solhint-disable-next-line func-name-mixedcase + function s_feeManager() external view returns (address); + + /** + * @notice Returns the access controller + * @return IDestinationFeeManager + */ + // solhint-disable-next-line func-name-mixedcase + function s_accessController() external view returns (address); +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierProxy.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierProxy.sol new file mode 100644 index 0000000000..a88349b301 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierProxy.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +interface IDestinationVerifierProxy { + /** + * @notice Verifies that the data encoded has been signed + * correctly by routing to the verifier, and bills the user if applicable. + * @param payload The encoded data to be verified, including the signed + * report. + * @param parameterPayload fee metadata for billing + * @return verifierResponse The encoded report from the verifier. + */ + function verify( + bytes calldata payload, + bytes calldata parameterPayload + ) external payable returns (bytes memory verifierResponse); + + /** + * @notice Bulk verifies that the data encoded has been signed + * correctly by routing to the correct verifier, and bills the user if applicable. + * @param payloads The encoded payloads to be verified, including the signed + * report. + * @param parameterPayload fee metadata for billing + * @return verifiedReports The encoded reports from the verifier. + */ + function verifyBulk( + bytes[] calldata payloads, + bytes calldata parameterPayload + ) external payable returns (bytes[] memory verifiedReports); + + /** + * @notice Sets the active verifier for this proxy + * @param verifierAddress The address of the verifier contract + */ + function setVerifier(address verifierAddress) external; + + /** + * @notice Used to honor the source verifierProxy feeManager interface + * @return IVerifierFeeManager + */ + // solhint-disable-next-line func-name-mixedcase + function s_feeManager() external view returns (address); + + /** + * @notice Used to honor the source verifierProxy feeManager interface + * @return AccessControllerInterface + */ + // solhint-disable-next-line func-name-mixedcase + function s_accessController() external view returns (address); +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/BaseDestinationFeeManager.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/BaseDestinationFeeManager.t.sol new file mode 100644 index 0000000000..8b70e5b2b3 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/BaseDestinationFeeManager.t.sol @@ -0,0 +1,394 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {Test} from "forge-std/Test.sol"; +import {DestinationFeeManager} from "../../DestinationFeeManager.sol"; +import {DestinationRewardManager} from "../../DestinationRewardManager.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {ERC20Mock} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {WERC20Mock} from "../../../../shared/mocks/WERC20Mock.sol"; +import {IDestinationRewardManager} from "../../interfaces/IDestinationRewardManager.sol"; +import {DestinationFeeManagerProxy} from "../mocks/DestinationFeeManagerProxy.sol"; + +/** + * @title BaseDestinationFeeManagerTest + * @author Michael Fletcher + * @notice Base class for all feeManager tests + * @dev This contract is intended to be inherited from and not used directly. It contains functionality to setup the feeManager + */ +contract BaseDestinationFeeManagerTest is Test { + //contracts + DestinationFeeManager internal feeManager; + DestinationRewardManager internal rewardManager; + DestinationFeeManagerProxy internal feeManagerProxy; + + ERC20Mock internal link; + WERC20Mock internal native; + + //erc20 config + uint256 internal constant DEFAULT_LINK_MINT_QUANTITY = 100 ether; + uint256 internal constant DEFAULT_NATIVE_MINT_QUANTITY = 100 ether; + + //contract owner + address internal constant INVALID_ADDRESS = address(0); + address internal constant ADMIN = address(uint160(uint256(keccak256("ADMIN")))); + address internal constant USER = address(uint160(uint256(keccak256("USER")))); + address internal constant PROXY = address(uint160(uint256(keccak256("PROXY")))); + + //version masks + bytes32 internal constant V_MASK = 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 internal constant V1_BITMASK = 0x0001000000000000000000000000000000000000000000000000000000000000; + bytes32 internal constant V2_BITMASK = 0x0002000000000000000000000000000000000000000000000000000000000000; + bytes32 internal constant V3_BITMASK = 0x0003000000000000000000000000000000000000000000000000000000000000; + + //feed ids & config digests + bytes32 internal constant DEFAULT_FEED_1_V1 = (keccak256("ETH-USD") & V_MASK) | V1_BITMASK; + bytes32 internal constant DEFAULT_FEED_1_V2 = (keccak256("ETH-USD") & V_MASK) | V2_BITMASK; + bytes32 internal constant DEFAULT_FEED_1_V3 = (keccak256("ETH-USD") & V_MASK) | V3_BITMASK; + + bytes32 internal constant DEFAULT_FEED_2_V3 = (keccak256("LINK-USD") & V_MASK) | V3_BITMASK; + bytes32 internal constant DEFAULT_CONFIG_DIGEST = keccak256("DEFAULT_CONFIG_DIGEST"); + bytes32 internal constant DEFAULT_CONFIG_DIGEST2 = keccak256("DEFAULT_CONFIG_DIGEST2"); + + //report + uint256 internal constant DEFAULT_REPORT_LINK_FEE = 1e10; + uint256 internal constant DEFAULT_REPORT_NATIVE_FEE = 1e12; + + //rewards + uint64 internal constant FEE_SCALAR = 1e18; + + address internal constant NATIVE_WITHDRAW_ADDRESS = address(0); + + //the selector for each error + bytes4 internal immutable INVALID_DISCOUNT_ERROR = DestinationFeeManager.InvalidDiscount.selector; + bytes4 internal immutable INVALID_ADDRESS_ERROR = DestinationFeeManager.InvalidAddress.selector; + bytes4 internal immutable INVALID_SURCHARGE_ERROR = DestinationFeeManager.InvalidSurcharge.selector; + bytes4 internal immutable EXPIRED_REPORT_ERROR = DestinationFeeManager.ExpiredReport.selector; + bytes4 internal immutable INVALID_DEPOSIT_ERROR = DestinationFeeManager.InvalidDeposit.selector; + bytes4 internal immutable INVALID_QUOTE_ERROR = DestinationFeeManager.InvalidQuote.selector; + bytes4 internal immutable UNAUTHORIZED_ERROR = DestinationFeeManager.Unauthorized.selector; + bytes4 internal immutable POOLID_MISMATCH_ERROR = DestinationFeeManager.PoolIdMismatch.selector; + bytes internal constant ONLY_CALLABLE_BY_OWNER_ERROR = "Only callable by owner"; + bytes internal constant INSUFFICIENT_ALLOWANCE_ERROR = "ERC20: insufficient allowance"; + bytes4 internal immutable ZERO_DEFICIT = DestinationFeeManager.ZeroDeficit.selector; + + //events emitted + event SubscriberDiscountUpdated(address indexed subscriber, bytes32 indexed feedId, address token, uint64 discount); + event NativeSurchargeUpdated(uint64 newSurcharge); + event InsufficientLink(IDestinationRewardManager.FeePayment[] feesAndRewards); + event Withdraw(address adminAddress, address recipient, address assetAddress, uint192 quantity); + event LinkDeficitCleared(bytes32 indexed configDigest, uint256 linkQuantity); + event DiscountApplied( + bytes32 indexed configDigest, + address indexed subscriber, + Common.Asset fee, + Common.Asset reward, + uint256 appliedDiscountQuantity + ); + + function setUp() public virtual { + //change to admin user + vm.startPrank(ADMIN); + + //init required contracts + _initializeContracts(); + } + + function _initializeContracts() internal { + link = new ERC20Mock("LINK", "LINK", ADMIN, 0); + native = new WERC20Mock(); + + feeManagerProxy = new DestinationFeeManagerProxy(); + rewardManager = new DestinationRewardManager(address(link)); + feeManager = new DestinationFeeManager( + address(link), + address(native), + address(feeManagerProxy), + address(rewardManager) + ); + + //link the feeManager to the proxy + feeManagerProxy.setDestinationFeeManager(feeManager); + + //link the feeManager to the reward manager + rewardManager.addFeeManager(address(feeManager)); + + //mint some tokens to the admin + link.mint(ADMIN, DEFAULT_LINK_MINT_QUANTITY); + native.mint(ADMIN, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(ADMIN, DEFAULT_NATIVE_MINT_QUANTITY); + + //mint some tokens to the user + link.mint(USER, DEFAULT_LINK_MINT_QUANTITY); + native.mint(USER, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(USER, DEFAULT_NATIVE_MINT_QUANTITY); + + //mint some tokens to the proxy + link.mint(PROXY, DEFAULT_LINK_MINT_QUANTITY); + native.mint(PROXY, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(PROXY, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function setSubscriberDiscount( + address subscriber, + bytes32 feedId, + address token, + uint256 discount, + address sender + ) internal { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //set the discount + feeManager.updateSubscriberDiscount(subscriber, feedId, token, uint64(discount)); + + //change back to the original address + changePrank(originalAddr); + } + + function setNativeSurcharge(uint256 surcharge, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //set the surcharge + feeManager.setNativeSurcharge(uint64(surcharge)); + + //change back to the original address + changePrank(originalAddr); + } + + // solium-disable-next-line no-unused-vars + function getFee(bytes memory report, address quote, address subscriber) public view returns (Common.Asset memory) { + //get the fee + (Common.Asset memory fee, , ) = feeManager.getFeeAndReward(subscriber, report, quote); + + return fee; + } + + function getReward(bytes memory report, address quote, address subscriber) public view returns (Common.Asset memory) { + //get the reward + (, Common.Asset memory reward, ) = feeManager.getFeeAndReward(subscriber, report, quote); + + return reward; + } + + function getAppliedDiscount(bytes memory report, address quote, address subscriber) public view returns (uint256) { + //get the reward + (, , uint256 appliedDiscount) = feeManager.getFeeAndReward(subscriber, report, quote); + + return appliedDiscount; + } + + function getV1Report(bytes32 feedId) public pure returns (bytes memory) { + return abi.encode(feedId, uint32(0), int192(0), int192(0), int192(0), uint64(0), bytes32(0), uint64(0), uint64(0)); + } + + function getV2Report(bytes32 feedId) public view returns (bytes memory) { + return + abi.encode( + feedId, + uint32(0), + uint32(0), + uint192(DEFAULT_REPORT_NATIVE_FEE), + uint192(DEFAULT_REPORT_LINK_FEE), + uint32(block.timestamp), + int192(0) + ); + } + + function getV3Report(bytes32 feedId) public view returns (bytes memory) { + return + abi.encode( + feedId, + uint32(0), + uint32(0), + uint192(DEFAULT_REPORT_NATIVE_FEE), + uint192(DEFAULT_REPORT_LINK_FEE), + uint32(block.timestamp), + int192(0), + int192(0), + int192(0) + ); + } + + function getV3ReportWithCustomExpiryAndFee( + bytes32 feedId, + uint256 expiry, + uint256 linkFee, + uint256 nativeFee + ) public pure returns (bytes memory) { + return + abi.encode( + feedId, + uint32(0), + uint32(0), + uint192(nativeFee), + uint192(linkFee), + uint32(expiry), + int192(0), + int192(0), + int192(0) + ); + } + + function getLinkQuote() public view returns (address) { + return address(link); + } + + function getNativeQuote() public view returns (address) { + return address(native); + } + + function withdraw(address assetAddress, address recipient, uint256 amount, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //set the surcharge + feeManager.withdraw(assetAddress, recipient, uint192(amount)); + + //change back to the original address + changePrank(originalAddr); + } + + function getLinkBalance(address balanceAddress) public view returns (uint256) { + return link.balanceOf(balanceAddress); + } + + function getNativeBalance(address balanceAddress) public view returns (uint256) { + return native.balanceOf(balanceAddress); + } + + function getNativeUnwrappedBalance(address balanceAddress) public view returns (uint256) { + return balanceAddress.balance; + } + + function mintLink(address recipient, uint256 amount) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(ADMIN); + + //mint the link to the recipient + link.mint(recipient, amount); + + //change back to the original address + changePrank(originalAddr); + } + + function mintNative(address recipient, uint256 amount, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //mint the native to the recipient + native.mint(recipient, amount); + + //change back to the original address + changePrank(originalAddr); + } + + function issueUnwrappedNative(address recipient, uint256 quantity) public { + vm.deal(recipient, quantity); + } + + function ProcessFeeAsUser( + bytes32 poolId, + bytes memory payload, + address subscriber, + address tokenAddress, + uint256 wrappedNativeValue, + address sender + ) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //process the fee + feeManager.processFee{value: wrappedNativeValue}(poolId, payload, abi.encode(tokenAddress), subscriber); + + //change ProcessFeeAsUserback to the original address + changePrank(originalAddr); + } + + function processFee( + bytes32 poolId, + bytes memory payload, + address subscriber, + address feeAddress, + uint256 wrappedNativeValue + ) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(subscriber); + + //process the fee + feeManagerProxy.processFee{value: wrappedNativeValue}(poolId, payload, abi.encode(feeAddress)); + + //change back to the original address + changePrank(originalAddr); + } + + function processFee( + bytes32[] memory poolIds, + bytes[] memory payloads, + address subscriber, + address feeAddress, + uint256 wrappedNativeValue + ) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(subscriber); + + //process the fee + feeManagerProxy.processFeeBulk{value: wrappedNativeValue}(poolIds, payloads, abi.encode(feeAddress)); + + //change back to the original address + changePrank(originalAddr); + } + + function getPayload(bytes memory reportPayload) public pure returns (bytes memory) { + return abi.encode([DEFAULT_CONFIG_DIGEST, 0, 0], reportPayload, new bytes32[](1), new bytes32[](1), bytes32("")); + } + + function approveLink(address spender, uint256 quantity, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //approve the link to be transferred + link.approve(spender, quantity); + + //change back to the original address + changePrank(originalAddr); + } + + function approveNative(address spender, uint256 quantity, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //approve the link to be transferred + native.approve(spender, quantity); + + //change back to the original address + changePrank(originalAddr); + } + + function payLinkDeficit(bytes32 configDigest, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //approve the link to be transferred + feeManager.payLinkDeficit(configDigest); + + //change back to the original address + changePrank(originalAddr); + } + + function getLinkDeficit(bytes32 configDigest) public view returns (uint256) { + return feeManager.s_linkDeficit(configDigest); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.general.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.general.t.sol new file mode 100644 index 0000000000..305125c332 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.general.t.sol @@ -0,0 +1,299 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import "./BaseDestinationFeeManager.t.sol"; + +/** + * @title BaseDestinationFeeManagerTest + * @author Michael Fletcher + * @notice This contract will test the setup functionality of the feemanager + */ +contract DestinationFeeManagerProcessFeeTest is BaseDestinationFeeManagerTest { + function setUp() public override { + super.setUp(); + } + + function test_WithdrawERC20() public { + //simulate a fee + mintLink(address(feeManager), DEFAULT_LINK_MINT_QUANTITY); + + //get the balances to ne used for comparison + uint256 contractBalance = getLinkBalance(address(feeManager)); + uint256 adminBalance = getLinkBalance(ADMIN); + + //the amount to withdraw + uint256 withdrawAmount = contractBalance / 2; + + //withdraw some balance + withdraw(address(link), ADMIN, withdrawAmount, ADMIN); + + //check the balance has been reduced + uint256 newContractBalance = getLinkBalance(address(feeManager)); + uint256 newAdminBalance = getLinkBalance(ADMIN); + + //check the balance is greater than zero + assertGt(newContractBalance, 0); + //check the balance has been reduced by the correct amount + assertEq(newContractBalance, contractBalance - withdrawAmount); + //check the admin balance has increased by the correct amount + assertEq(newAdminBalance, adminBalance + withdrawAmount); + } + + function test_WithdrawUnwrappedNative() public { + //issue funds straight to the contract to bypass the lack of fallback function + issueUnwrappedNative(address(feeManager), DEFAULT_NATIVE_MINT_QUANTITY); + + //get the balances to be used for comparison + uint256 contractBalance = getNativeUnwrappedBalance(address(feeManager)); + uint256 adminBalance = getNativeUnwrappedBalance(ADMIN); + + //the amount to withdraw + uint256 withdrawAmount = contractBalance / 2; + + //withdraw some balance + withdraw(NATIVE_WITHDRAW_ADDRESS, ADMIN, withdrawAmount, ADMIN); + + //check the balance has been reduced + uint256 newContractBalance = getNativeUnwrappedBalance(address(feeManager)); + uint256 newAdminBalance = getNativeUnwrappedBalance(ADMIN); + + //check the balance is greater than zero + assertGt(newContractBalance, 0); + //check the balance has been reduced by the correct amount + assertEq(newContractBalance, contractBalance - withdrawAmount); + //check the admin balance has increased by the correct amount + assertEq(newAdminBalance, adminBalance + withdrawAmount); + } + + function test_WithdrawNonAdminAddr() public { + //simulate a fee + mintLink(address(feeManager), DEFAULT_LINK_MINT_QUANTITY); + + //should revert if not admin + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + //withdraw some balance + withdraw(address(link), ADMIN, DEFAULT_LINK_MINT_QUANTITY, USER); + } + + function test_eventIsEmittedAfterSurchargeIsSet() public { + //native surcharge + uint64 nativeSurcharge = FEE_SCALAR / 5; + + //expect an emit + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit NativeSurchargeUpdated(nativeSurcharge); + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + } + + function test_subscriberDiscountEventIsEmittedOnUpdate() public { + //native surcharge + uint64 discount = FEE_SCALAR / 3; + + //an event should be emitted + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit SubscriberDiscountUpdated(USER, DEFAULT_FEED_1_V3, address(native), discount); + + //set the surcharge + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), discount, ADMIN); + } + + function test_eventIsEmittedUponWithdraw() public { + //simulate a fee + mintLink(address(feeManager), DEFAULT_LINK_MINT_QUANTITY); + + //the amount to withdraw + uint192 withdrawAmount = 1; + + //expect an emit + vm.expectEmit(); + + //the event to be emitted + emit Withdraw(ADMIN, ADMIN, address(link), withdrawAmount); + + //withdraw some balance + withdraw(address(link), ADMIN, withdrawAmount, ADMIN); + } + + function test_linkAvailableForPaymentReturnsLinkBalance() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //check there's a balance + assertGt(getLinkBalance(address(feeManager)), 0); + + //check the link available for payment is the link balance + assertEq(feeManager.linkAvailableForPayment(), getLinkBalance(address(feeManager))); + } + + function test_payLinkDeficit() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3)); + + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //not enough funds in the reward pool should trigger an insufficient link event + vm.expectEmit(); + + IDestinationRewardManager.FeePayment[] memory contractFees = new IDestinationRewardManager.FeePayment[](1); + contractFees[0] = IDestinationRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + + emit InsufficientLink(contractFees); + + //process the fee + processFee(contractFees[0].poolId, payload, USER, address(native), 0); + + //double check the rewardManager balance is 0 + assertEq(getLinkBalance(address(rewardManager)), 0); + + //simulate a deposit of link to cover the deficit + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + vm.expectEmit(); + emit LinkDeficitCleared(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE); + + //pay the deficit which will transfer link from the rewardManager to the rewardManager + payLinkDeficit(DEFAULT_CONFIG_DIGEST, ADMIN); + + //check the rewardManager received the link + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + } + + function test_payLinkDeficitTwice() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3)); + + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //not enough funds in the reward pool should trigger an insufficient link event + vm.expectEmit(); + + IDestinationRewardManager.FeePayment[] memory contractFees = new IDestinationRewardManager.FeePayment[](1); + contractFees[0] = IDestinationRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + + //emit the event that is expected to be emitted + emit InsufficientLink(contractFees); + + //process the fee + processFee(contractFees[0].poolId, payload, USER, address(native), 0); + + //double check the rewardManager balance is 0 + assertEq(getLinkBalance(address(rewardManager)), 0); + + //simulate a deposit of link to cover the deficit + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + vm.expectEmit(); + emit LinkDeficitCleared(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE); + + //pay the deficit which will transfer link from the rewardManager to the rewardManager + payLinkDeficit(DEFAULT_CONFIG_DIGEST, ADMIN); + + //check the rewardManager received the link + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //paying again should revert with 0 + vm.expectRevert(ZERO_DEFICIT); + + payLinkDeficit(DEFAULT_CONFIG_DIGEST, ADMIN); + } + + function test_payLinkDeficitPaysAllFeesProcessed() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3)); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * 2, USER); + + //processing the fee will transfer the native from the user to the feeManager + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(native), 0); + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(native), 0); + + //check the deficit has been increased twice + assertEq(getLinkDeficit(DEFAULT_CONFIG_DIGEST), DEFAULT_REPORT_LINK_FEE * 2); + + //double check the rewardManager balance is 0 + assertEq(getLinkBalance(address(rewardManager)), 0); + + //simulate a deposit of link to cover the deficit + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * 2); + + vm.expectEmit(); + emit LinkDeficitCleared(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE * 2); + + //pay the deficit which will transfer link from the rewardManager to the rewardManager + payLinkDeficit(DEFAULT_CONFIG_DIGEST, ADMIN); + + //check the rewardManager received the link + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * 2); + } + + function test_payLinkDeficitOnlyCallableByAdmin() public { + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + payLinkDeficit(DEFAULT_CONFIG_DIGEST, USER); + } + + function test_revertOnSettingAnAddressZeroVerifier() public { + vm.expectRevert(INVALID_ADDRESS_ERROR); + feeManager.addVerifier(address(0)); + } + + function test_onlyCallableByOwnerReverts() public { + address STRANGER = address(999); + changePrank(STRANGER); + vm.expectRevert(bytes("Only callable by owner")); + feeManager.addVerifier(address(0)); + } + + function test_addVerifierExistingAddress() public { + address dummyAddress = address(998); + feeManager.addVerifier(dummyAddress); + vm.expectRevert(INVALID_ADDRESS_ERROR); + feeManager.addVerifier(dummyAddress); + } + + function test_addVerifier() public { + address dummyAddress = address(998); + feeManager.addVerifier(dummyAddress); + vm.expectRevert(INVALID_ADDRESS_ERROR); + feeManager.addVerifier(dummyAddress); + + // check calls to setFeeRecipients it should not error unauthorized + changePrank(dummyAddress); + bytes32 dummyConfigDigest = 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef; + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](1); + recipients[0] = Common.AddressAndWeight(address(991), 1e18); + feeManager.setFeeRecipients(dummyConfigDigest, recipients); + + // removing this verifier should result in unauthorized when calling setFeeRecipients + changePrank(ADMIN); + feeManager.removeVerifier(dummyAddress); + changePrank(dummyAddress); + vm.expectRevert(UNAUTHORIZED_ERROR); + feeManager.setFeeRecipients(dummyConfigDigest, recipients); + } + + function test_removeVerifierZeroAaddress() public { + address dummyAddress = address(0); + vm.expectRevert(INVALID_ADDRESS_ERROR); + feeManager.removeVerifier(dummyAddress); + } + + function test_removeVerifierNonExistentAddress() public { + address dummyAddress = address(991); + vm.expectRevert(INVALID_ADDRESS_ERROR); + feeManager.removeVerifier(dummyAddress); + } + + function test_setRewardManagerZeroAddress() public { + vm.expectRevert(INVALID_ADDRESS_ERROR); + feeManager.setRewardManager(address(0)); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.getFeeAndReward.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.getFeeAndReward.t.sol new file mode 100644 index 0000000000..30be694df2 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.getFeeAndReward.t.sol @@ -0,0 +1,606 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {Common} from "../../../libraries/Common.sol"; +import "./BaseDestinationFeeManager.t.sol"; + +/** + * @title BaseFeeManagerTest + * @author Michael Fletcher + * @notice This contract will test the functionality of the feeManager's getFeeAndReward + */ +contract DestinationFeeManagerProcessFeeTest is BaseDestinationFeeManagerTest { + function test_baseFeeIsAppliedForNative() public view { + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_baseFeeIsAppliedForLink() public view { + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_discountAIsNotAppliedWhenSetForOtherUsers() public { + //set the subscriber discount for another user + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), INVALID_ADDRESS); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_discountIsNotAppliedForInvalidTokenAddress() public { + //should revert with invalid address as it's not a configured token + vm.expectRevert(INVALID_ADDRESS_ERROR); + + //set the subscriber discount for another user + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, INVALID_ADDRESS, FEE_SCALAR / 2, ADMIN); + } + + function test_discountIsAppliedForLink() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE / 2); + } + + function test_DiscountIsAppliedForNative() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE / 2); + } + + function test_discountIsNoLongerAppliedAfterRemoving() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE / 2); + + //remove the discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), 0, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_surchargeIsApplied() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge + uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //expected fee should the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge); + } + + function test_surchargeIsNotAppliedForLinkFee() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_surchargeIsNoLongerAppliedAfterRemoving() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge + uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //expected fee should be the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge); + + //remove the surcharge + setNativeSurcharge(0, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_feeIsUpdatedAfterNewSurchargeIsApplied() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge + uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //expected fee should the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge); + + //change the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge + expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //expected fee should the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge); + } + + function test_surchargeIsAppliedForNativeFeeWithDiscount() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge quantity + uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //calculate the expected discount quantity + uint256 expectedDiscount = ((DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge) / 2); + + //expected fee should the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge - expectedDiscount); + } + + function test_emptyQuoteRevertsWithError() public { + //expect a revert + vm.expectRevert(INVALID_QUOTE_ERROR); + + //get the fee required by the feeManager + getFee(getV3Report(DEFAULT_FEED_1_V3), address(0), USER); + } + + function test_nativeSurcharge100Percent() public { + //set the surcharge + setNativeSurcharge(FEE_SCALAR, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be twice the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE * 2); + } + + function test_nativeSurcharge0Percent() public { + //set the surcharge + setNativeSurcharge(0, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_nativeSurchargeCannotExceed100Percent() public { + //should revert if surcharge is greater than 100% + vm.expectRevert(INVALID_SURCHARGE_ERROR); + + //set the surcharge above the max + setNativeSurcharge(FEE_SCALAR + 1, ADMIN); + } + + function test_discountIsAppliedWith100PercentSurcharge() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //set the surcharge + setNativeSurcharge(FEE_SCALAR, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected discount quantity + uint256 expectedDiscount = DEFAULT_REPORT_NATIVE_FEE; + + //fee should be twice the surcharge minus the discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE * 2 - expectedDiscount); + } + + function test_feeIsZeroWith100PercentDiscount() public { + //set the subscriber discount to 100% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_feeIsUpdatedAfterDiscountIsRemoved() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected discount quantity + uint256 expectedDiscount = DEFAULT_REPORT_NATIVE_FEE / 2; + + //fee should be 50% of the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); + + //remove the discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), 0, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_feeIsUpdatedAfterNewDiscountIsApplied() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected discount quantity + uint256 expectedDiscount = DEFAULT_REPORT_NATIVE_FEE / 2; + + //fee should be 50% of the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); + + //change the discount to 25% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 4, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //expected discount is now 25% + expectedDiscount = DEFAULT_REPORT_NATIVE_FEE / 4; + + //fee should be the base fee minus the expected discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); + } + + function test_setDiscountOver100Percent() public { + //should revert with invalid discount + vm.expectRevert(INVALID_DISCOUNT_ERROR); + + //set the subscriber discount to over 100% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR + 1, ADMIN); + } + + function test_surchargeIsNotAppliedWith100PercentDiscount() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the subscriber discount to 100% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR, ADMIN); + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_nonAdminUserCanNotSetDiscount() public { + //should revert with unauthorized + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR, USER); + } + + function test_surchargeFeeRoundsUpWhenUneven() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 3; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge quantity + uint256 expectedSurcharge = (DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR; + + //expected fee should the base fee offset by the expected surcharge + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge + 1); + } + + function test_discountFeeRoundsDownWhenUneven() public { + //native surcharge + uint256 discount = FEE_SCALAR / 3; + + //set the subscriber discount to 33.333% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), discount, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected quantity + uint256 expectedDiscount = ((DEFAULT_REPORT_NATIVE_FEE * discount) / FEE_SCALAR); + + //expected fee should the base fee offset by the expected surcharge + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); + } + + function test_reportWithNoExpiryOrFeeReturnsZero() public view { + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV1Report(DEFAULT_FEED_1_V1), getNativeQuote(), USER); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() public { + //set the subscriber and native discounts + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 4, ADMIN); + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager for both tokens + Common.Asset memory linkFee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + Common.Asset memory nativeFee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected discount quantity for each token + uint256 expectedDiscountLink = (DEFAULT_REPORT_LINK_FEE * FEE_SCALAR) / 4 / FEE_SCALAR; + uint256 expectedDiscountNative = (DEFAULT_REPORT_NATIVE_FEE * FEE_SCALAR) / 2 / FEE_SCALAR; + + //check the fee calculation for each token + assertEq(linkFee.amount, DEFAULT_REPORT_LINK_FEE - expectedDiscountLink); + assertEq(nativeFee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscountNative); + } + + function test_discountIsNotAppliedToOtherFeeds() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_2_V3), getNativeQuote(), USER); + + //fee should be the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_noFeeIsAppliedWhenReportHasZeroFee() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, uint32(block.timestamp), 0, 0), + getNativeQuote(), + USER + ); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //set the surcharge + setNativeSurcharge(FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, uint32(block.timestamp), 0, 0), + getNativeQuote(), + USER + ); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_nativeSurchargeEventIsEmittedOnUpdate() public { + //native surcharge + uint64 nativeSurcharge = FEE_SCALAR / 3; + + //an event should be emitted + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit NativeSurchargeUpdated(nativeSurcharge); + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + } + + function test_getBaseRewardWithLinkQuote() public view { + //get the fee required by the feeManager + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal the base fee + assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_getRewardWithLinkQuoteAndLinkDiscount() public { + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal the discounted base fee + assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE / 2); + } + + function test_getRewardWithNativeQuote() public view { + //get the fee required by the feeManager + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //the reward should equal the base fee in link + assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_getRewardWithNativeQuoteAndSurcharge() public { + //set the native surcharge + setNativeSurcharge(FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //the reward should equal the base fee in link regardless of the surcharge + assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_getRewardWithLinkDiscount() public { + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal the discounted base fee + assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE / 2); + } + + function test_getLinkFeeIsRoundedUp() public { + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 3, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal .66% + 1 of the base fee due to a 33% discount rounded up + assertEq(fee.amount, (DEFAULT_REPORT_LINK_FEE * 2) / 3 + 1); + } + + function test_getLinkRewardIsSameAsFee() public { + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 3, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //check the reward is in link + assertEq(fee.assetAddress, address(link)); + + //the reward should equal .66% of the base fee due to a 33% discount rounded down + assertEq(reward.amount, fee.amount); + } + + function test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() public { + //set the native surcharge + setNativeSurcharge(FEE_SCALAR / 2, ADMIN); + + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 3, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //the reward should equal the base fee in link regardless of the surcharge + assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_testRevertIfReportHasExpired() public { + //expect a revert + vm.expectRevert(EXPIRED_REPORT_ERROR); + + //get the fee required by the feeManager + getFee( + getV3ReportWithCustomExpiryAndFee( + DEFAULT_FEED_1_V3, + block.timestamp - 1, + DEFAULT_REPORT_LINK_FEE, + DEFAULT_REPORT_NATIVE_FEE + ), + getNativeQuote(), + USER + ); + } + + function test_discountIsReturnedForLink() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN); + + //get the fee applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } + + function test_DiscountIsReturnedForNative() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } + + function test_DiscountIsReturnedForNativeWithSurcharge() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //set the surcharge + setNativeSurcharge(FEE_SCALAR / 5, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.processFee.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.processFee.t.sol new file mode 100644 index 0000000000..0880352dca --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.processFee.t.sol @@ -0,0 +1,492 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {Common} from "../../../libraries/Common.sol"; +import "./BaseDestinationFeeManager.t.sol"; +import {IDestinationRewardManager} from "../../interfaces/IDestinationRewardManager.sol"; + +/** + * @title BaseFeeManagerTest + * @author Michael Fletcher + * @notice This contract will test the functionality of the feeManager processFee + */ +contract DestinationFeeManagerProcessFeeTest is BaseDestinationFeeManagerTest { + function setUp() public override { + super.setUp(); + } + + function test_nonAdminProxyUserCannotProcessFee() public { + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //should revert as the user is not the owner + vm.expectRevert(UNAUTHORIZED_ERROR); + + //process the fee + ProcessFeeAsUser(DEFAULT_CONFIG_DIGEST, payload, USER, address(link), 0, USER); + } + + function test_processFeeAsProxy() public { + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(link), 0); + + //check the link has been transferred + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the user has had the link fee deducted + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + } + + function test_processFeeIfSubscriberIsSelf() public { + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //expect a revert due to the feeManager being the subscriber + vm.expectRevert(INVALID_ADDRESS_ERROR); + + //process the fee will fail due to assertion + processFee(DEFAULT_CONFIG_DIGEST, payload, address(feeManager), address(native), 0); + } + + function test_processFeeWithWithEmptyQuotePayload() public { + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //expect a revert as the quote is invalid + vm.expectRevert(); + + //processing the fee will transfer the link by default + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(0), 0); + } + + function test_processFeeWithWithZeroQuotePayload() public { + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //expect a revert as the quote is invalid + vm.expectRevert(INVALID_QUOTE_ERROR); + + //processing the fee will transfer the link by default + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, INVALID_ADDRESS, 0); + } + + function test_processFeeWithWithCorruptQuotePayload() public { + //get the default payload + bytes memory payload = abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + getV3Report(DEFAULT_FEED_1_V3), + new bytes32[](1), + new bytes32[](1), + bytes32("") + ); + + //expect an evm revert as the quote is corrupt + vm.expectRevert(); + + //processing the fee will not withdraw anything as there is no fee to collect + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(link), 0); + } + + function test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() public { + //get the default payload + bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V1)); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(0), 0); + } + + function test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() public { + //get the default payload + bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V1)); + + //processing the fee will not withdraw anything as there is no fee to collect + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(link), 0); + } + + function test_processFeeNative() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //processing the fee will transfer the native from the user to the feeManager + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(native), 0); + + //check the native has been transferred + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + + //check the link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the feeManager has had the link deducted, the remaining balance should be 0 + assertEq(getLinkBalance(address(feeManager)), 0); + + //check the subscriber has had the native deducted + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeEmitsEventIfNotEnoughLink() public { + //simulate a deposit of half the link required for the fee + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE / 2); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //expect an emit as there's not enough link + vm.expectEmit(); + + IDestinationRewardManager.FeePayment[] memory contractFees = new IDestinationRewardManager.FeePayment[](1); + contractFees[0] = IDestinationRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + + //emit the event that is expected to be emitted + emit InsufficientLink(contractFees); + + //processing the fee will transfer the native from the user to the feeManager + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(native), 0); + + //check the native has been transferred + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + + //check no link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), 0); + assertEq(getLinkBalance(address(feeManager)), DEFAULT_REPORT_LINK_FEE / 2); + + //check the subscriber has had the native deducted + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeWithUnwrappedNative() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //only the proxy or admin can call processFee, they will pass in the native value on the users behalf + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(native), DEFAULT_REPORT_NATIVE_FEE); + + //check the native has been transferred and converted to wrapped native + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + assertEq(getNativeUnwrappedBalance(address(feeManager)), 0); + + //check the link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the feeManager has had the link deducted, the remaining balance should be 0 + assertEq(getLinkBalance(address(feeManager)), 0); + + //check the subscriber has had the native deducted + assertEq(getNativeUnwrappedBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeWithUnwrappedNativeShortFunds() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //expect a revert as not enough funds + vm.expectRevert(INVALID_DEPOSIT_ERROR); + + //only the proxy or admin can call processFee, they will pass in the native value on the users behalf + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(native), DEFAULT_REPORT_NATIVE_FEE - 1); + } + + function test_processFeeWithUnwrappedNativeLinkAddress() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //expect a revert as not enough funds + vm.expectRevert(INSUFFICIENT_ALLOWANCE_ERROR); + + //the change will be returned and the user will attempted to be billed in LINK + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(link), DEFAULT_REPORT_NATIVE_FEE - 1); + } + + function test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() public { + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, PROXY); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //call processFee from the proxy to test whether the funds are returned to the subscriber. In reality, the funds would be returned to the caller of the proxy. + processFee(DEFAULT_CONFIG_DIGEST, payload, PROXY, address(link), DEFAULT_REPORT_NATIVE_FEE); + + //check the native unwrapped is no longer in the account + assertEq(getNativeBalance(address(feeManager)), 0); + assertEq(getNativeUnwrappedBalance(address(feeManager)), 0); + + //check the link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the feeManager has had the link deducted, the remaining balance should be 0 + assertEq(getLinkBalance(address(feeManager)), 0); + + //native should not be deducted + assertEq(getNativeUnwrappedBalance(PROXY), DEFAULT_NATIVE_MINT_QUANTITY); + } + + function test_processFeeWithUnwrappedNativeWithExcessiveFee() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //call processFee from the proxy to test whether the funds are returned to the subscriber. In reality, the funds would be returned to the caller of the proxy. + processFee(DEFAULT_CONFIG_DIGEST, payload, PROXY, address(native), DEFAULT_REPORT_NATIVE_FEE * 2); + + //check the native has been transferred and converted to wrapped native + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + assertEq(getNativeUnwrappedBalance(address(feeManager)), 0); + + //check the link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the feeManager has had the link deducted, the remaining balance should be 0 + assertEq(getLinkBalance(address(feeManager)), 0); + + //check the subscriber has had the native deducted + assertEq(getNativeUnwrappedBalance(PROXY), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeUsesCorrectDigest() public { + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(link), 0); + + //check the link has been transferred + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the user has had the link fee deducted + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + + //check funds have been paid to the reward manager + assertEq(rewardManager.s_totalRewardRecipientFees(DEFAULT_CONFIG_DIGEST), DEFAULT_REPORT_LINK_FEE); + } + + function test_V1PayloadVerifies() public { + //replicate a default payload + bytes memory payload = abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + getV2Report(DEFAULT_FEED_1_V1), + new bytes32[](1), + new bytes32[](1), + bytes32("") + ); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(0), 0); + } + + function test_V2PayloadVerifies() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V2)); + + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(link), 0); + + //check the link has been transferred + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the user has had the link fee deducted + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + } + + function test_V2PayloadWithoutQuoteFails() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V2)); + + //expect a revert as the quote is invalid + vm.expectRevert(); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(0), 0); + } + + function test_V2PayloadWithoutZeroFee() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V2)); + + //expect a revert as the quote is invalid + vm.expectRevert(); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(link), 0); + } + + function test_processFeeWithInvalidReportVersionFailsToDecode() public { + bytes memory data = abi.encode(0x0000100000000000000000000000000000000000000000000000000000000000); + + //get the default payload + bytes memory payload = getPayload(data); + + //serialization will fail as there is no report to decode + vm.expectRevert(); + + //processing the fee will not withdraw anything as there is no fee to collect + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(link), 0); + } + + function test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() public { + //get the default payload + bytes memory payload = getPayload( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, DEFAULT_REPORT_LINK_FEE, 0) + ); + + //call processFee should not revert as the fee is 0 + processFee(DEFAULT_CONFIG_DIGEST, payload, PROXY, address(native), 0); + } + + function test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() public { + //get the default payload + bytes memory payload = getPayload( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, DEFAULT_REPORT_LINK_FEE, 0) + ); + + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + //processing the fee will transfer the link to the rewardManager from the user + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(link), 0); + + //check the link has been transferred + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the user has had the link fee deducted + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + } + + function test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, 0, DEFAULT_REPORT_NATIVE_FEE) + ); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //processing the fee will transfer the native from the user to the feeManager + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(native), 0); + + //check the native has been transferred + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + + //check no link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), 0); + + //check the feeManager has had no link deducted + assertEq(getLinkBalance(address(feeManager)), DEFAULT_REPORT_LINK_FEE); + + //check the subscriber has had the native deducted + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() public { + //get the default payload + bytes memory payload = getPayload( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, 0, DEFAULT_REPORT_NATIVE_FEE) + ); + + //call processFee should not revert as the fee is 0 + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(link), 0); + } + + function test_processFeeWithZeroNativeNonZeroLinkReturnsChange() public { + //get the default payload + bytes memory payload = getPayload( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, 0, DEFAULT_REPORT_NATIVE_FEE) + ); + + //call processFee should not revert as the fee is 0 + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(link), DEFAULT_REPORT_NATIVE_FEE); + + //check the change has been returned + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function test_V1PayloadVerifiesAndReturnsChange() public { + //emulate a V1 payload with no quote + bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V1)); + + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(0), DEFAULT_REPORT_NATIVE_FEE); + + //Fee manager should not contain any native + assertEq(address(feeManager).balance, 0); + assertEq(getNativeBalance(address(feeManager)), 0); + + //check the unused native passed in is returned + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function test_processFeeWithDiscountEmitsEvent() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE / 2, USER); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + uint256 appliedDiscount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + vm.expectEmit(); + + emit DiscountApplied(DEFAULT_CONFIG_DIGEST, USER, fee, reward, appliedDiscount); + + //call processFee should not revert as the fee is 0 + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(native), 0); + } + + function test_processFeeWithNoDiscountDoesNotEmitEvent() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //call processFee should not revert as the fee is 0 + processFee(DEFAULT_CONFIG_DIGEST, payload, USER, address(native), 0); + + //no logs should have been emitted + assertEq(vm.getRecordedLogs().length, 0); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.processFeeBulk.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.processFeeBulk.t.sol new file mode 100644 index 0000000000..a50441bed6 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.processFeeBulk.t.sol @@ -0,0 +1,310 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import "./BaseDestinationFeeManager.t.sol"; +import {IDestinationRewardManager} from "../../interfaces/IDestinationRewardManager.sol"; + +/** + * @title BaseFeeManagerTest + * @author Michael Fletcher + * @notice This contract will test the functionality of the feeManager processFee + */ +contract DestinationFeeManagerProcessFeeTest is BaseDestinationFeeManagerTest { + uint256 internal constant NUMBER_OF_REPORTS = 5; + + function setUp() public override { + super.setUp(); + } + + function test_processMultipleLinkReports() public { + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS); + for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) { + payloads[i] = payload; + } + + bytes32[] memory poolIds = new bytes32[](NUMBER_OF_REPORTS); + for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) { + poolIds[i] = DEFAULT_CONFIG_DIGEST; + } + + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS, USER); + + processFee(poolIds, payloads, USER, address(link), DEFAULT_NATIVE_MINT_QUANTITY); + + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS); + assertEq(getLinkBalance(address(feeManager)), 0); + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS); + + //the subscriber (user) should receive funds back and not the proxy, although when live the proxy will forward the funds sent and not cover it seen here + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY); + assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function test_processMultipleWrappedNativeReports() public { + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS + 1); + + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS); + for (uint256 i; i < NUMBER_OF_REPORTS; ++i) { + payloads[i] = payload; + } + + bytes32[] memory poolIds = new bytes32[](NUMBER_OF_REPORTS); + for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) { + poolIds[i] = DEFAULT_CONFIG_DIGEST; + } + + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS, USER); + + processFee(poolIds, payloads, USER, address(native), 0); + + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS); + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS); + assertEq(getLinkBalance(address(feeManager)), 1); + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS); + } + + function test_processMultipleUnwrappedNativeReports() public { + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS + 1); + + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS); + for (uint256 i; i < NUMBER_OF_REPORTS; ++i) { + payloads[i] = payload; + } + + bytes32[] memory poolIds = new bytes32[](NUMBER_OF_REPORTS); + for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) { + poolIds[i] = DEFAULT_CONFIG_DIGEST; + } + + processFee(poolIds, payloads, USER, address(native), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS * 2); + + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS); + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS); + assertEq(getLinkBalance(address(feeManager)), 1); + + assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY); + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS); + } + + function test_processV1V2V3Reports() public { + mintLink(address(feeManager), 1); + + bytes memory payloadV1 = abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + getV1Report(DEFAULT_FEED_1_V1), + new bytes32[](1), + new bytes32[](1), + bytes32("") + ); + + bytes memory linkPayloadV2 = getPayload(getV2Report(DEFAULT_FEED_1_V2)); + bytes memory linkPayloadV3 = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](5); + payloads[0] = payloadV1; + payloads[1] = linkPayloadV2; + payloads[2] = linkPayloadV2; + payloads[3] = linkPayloadV3; + payloads[4] = linkPayloadV3; + + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE * 4, USER); + + bytes32[] memory poolIds = new bytes32[](5); + for (uint256 i = 0; i < 5; ++i) { + poolIds[i] = DEFAULT_CONFIG_DIGEST; + } + + processFee(poolIds, payloads, USER, address(link), 0); + + assertEq(getNativeBalance(address(feeManager)), 0); + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * 4); + assertEq(getLinkBalance(address(feeManager)), 1); + + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE * 4); + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - 0); + } + + function test_processV1V2V3ReportsWithUnwrapped() public { + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * 4 + 1); + + bytes memory payloadV1 = abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + getV1Report(DEFAULT_FEED_1_V1), + new bytes32[](1), + new bytes32[](1), + bytes32("") + ); + + bytes memory nativePayloadV2 = getPayload(getV2Report(DEFAULT_FEED_1_V2)); + bytes memory nativePayloadV3 = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](5); + payloads[0] = payloadV1; + payloads[1] = nativePayloadV2; + payloads[2] = nativePayloadV2; + payloads[3] = nativePayloadV3; + payloads[4] = nativePayloadV3; + + bytes32[] memory poolIds = new bytes32[](5); + for (uint256 i = 0; i < 5; ++i) { + poolIds[i] = DEFAULT_CONFIG_DIGEST; + } + + processFee(poolIds, payloads, USER, address(native), DEFAULT_REPORT_NATIVE_FEE * 4); + + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE * 4); + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * 4); + assertEq(getLinkBalance(address(feeManager)), 1); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * 4); + assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function test_processMultipleV1Reports() public { + bytes memory payload = abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + getV1Report(DEFAULT_FEED_1_V1), + new bytes32[](1), + new bytes32[](1), + bytes32("") + ); + + bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS); + for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) { + payloads[i] = payload; + } + + bytes32[] memory poolIds = new bytes32[](NUMBER_OF_REPORTS); + for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) { + poolIds[i] = DEFAULT_CONFIG_DIGEST; + } + + processFee(poolIds, payloads, USER, address(native), DEFAULT_REPORT_NATIVE_FEE * 5); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY); + assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function test_eventIsEmittedIfNotEnoughLink() public { + bytes memory nativePayload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](5); + payloads[0] = nativePayload; + payloads[1] = nativePayload; + payloads[2] = nativePayload; + payloads[3] = nativePayload; + payloads[4] = nativePayload; + + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * 5, USER); + + IDestinationRewardManager.FeePayment[] memory payments = new IDestinationRewardManager.FeePayment[](5); + payments[0] = IDestinationRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + payments[1] = IDestinationRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + payments[2] = IDestinationRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + payments[3] = IDestinationRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + payments[4] = IDestinationRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + + vm.expectEmit(); + + bytes32[] memory poolIds = new bytes32[](5); + for (uint256 i = 0; i < 5; ++i) { + poolIds[i] = payments[i].poolId; + } + + emit InsufficientLink(payments); + + processFee(poolIds, payloads, USER, address(native), 0); + + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE * 5); + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * 5); + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY); + } + + function test_processPoolIdsPassedMismatched() public { + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS + 1); + + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS); + for (uint256 i; i < NUMBER_OF_REPORTS; ++i) { + payloads[i] = payload; + } + + // poolIds passed are different that number of reports in payload + bytes32[] memory poolIds = new bytes32[](NUMBER_OF_REPORTS - 1); + for (uint256 i = 0; i < NUMBER_OF_REPORTS - 1; ++i) { + poolIds[i] = DEFAULT_CONFIG_DIGEST; + } + + vm.expectRevert(POOLID_MISMATCH_ERROR); + processFee(poolIds, payloads, USER, address(native), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS * 2); + } + + function test_poolIdsCannotBeZeroAddress() public { + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS + 1); + + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS); + for (uint256 i; i < NUMBER_OF_REPORTS; ++i) { + payloads[i] = payload; + } + + bytes32[] memory poolIds = new bytes32[](NUMBER_OF_REPORTS); + for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) { + poolIds[i] = DEFAULT_CONFIG_DIGEST; + } + + poolIds[2] = 0x000; + vm.expectRevert(INVALID_ADDRESS_ERROR); + processFee(poolIds, payloads, USER, address(native), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS * 2); + } + + function test_rewardsAreCorrectlySentToEachAssociatedPoolWhenVerifyingInBulk() public { + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS); + for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) { + payloads[i] = payload; + } + + bytes32[] memory poolIds = new bytes32[](NUMBER_OF_REPORTS); + for (uint256 i = 0; i < NUMBER_OF_REPORTS - 1; ++i) { + poolIds[i] = DEFAULT_CONFIG_DIGEST; + } + poolIds[NUMBER_OF_REPORTS - 1] = DEFAULT_CONFIG_DIGEST2; + + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS, USER); + + // Checking no rewards yet for each pool + for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) { + bytes32 p_id = poolIds[i]; + uint256 poolDeficit = rewardManager.s_totalRewardRecipientFees(p_id); + assertEq(poolDeficit, 0); + } + + processFee(poolIds, payloads, USER, address(link), DEFAULT_NATIVE_MINT_QUANTITY); + + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS); + assertEq(getLinkBalance(address(feeManager)), 0); + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY); + assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY); + + // Checking each pool got the correct rewards + uint256 expectedRewards = DEFAULT_REPORT_LINK_FEE * (NUMBER_OF_REPORTS - 1); + uint256 poolRewards = rewardManager.s_totalRewardRecipientFees(DEFAULT_CONFIG_DIGEST); + assertEq(poolRewards, expectedRewards); + + expectedRewards = DEFAULT_REPORT_LINK_FEE; + poolRewards = rewardManager.s_totalRewardRecipientFees(DEFAULT_CONFIG_DIGEST2); + assertEq(poolRewards, expectedRewards); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/mocks/DestinationFeeManagerProxy.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/mocks/DestinationFeeManagerProxy.sol new file mode 100644 index 0000000000..46ec7fff3b --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/mocks/DestinationFeeManagerProxy.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IDestinationFeeManager} from "../../interfaces/IDestinationFeeManager.sol"; + +contract DestinationFeeManagerProxy { + IDestinationFeeManager internal s_feeManager; + + function processFee(bytes32 poolId, bytes calldata payload, bytes calldata parameterPayload) public payable { + s_feeManager.processFee{value: msg.value}(poolId, payload, parameterPayload, msg.sender); + } + + function processFeeBulk( + bytes32[] memory poolIds, + bytes[] calldata payloads, + bytes calldata parameterPayload + ) public payable { + s_feeManager.processFeeBulk{value: msg.value}(poolIds, payloads, parameterPayload, msg.sender); + } + + function setDestinationFeeManager(IDestinationFeeManager feeManager) public { + s_feeManager = feeManager; + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/BaseDestinationRewardManager.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/BaseDestinationRewardManager.t.sol new file mode 100644 index 0000000000..7cafb1629d --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/BaseDestinationRewardManager.t.sol @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {Test} from "forge-std/Test.sol"; +import {ERC20Mock} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {DestinationRewardManager} from "../../../v0.4.0/DestinationRewardManager.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {IDestinationRewardManager} from "../../interfaces/IDestinationRewardManager.sol"; + +/** + * @title DestinationRewardManagerTest + * @author Michael Fletcher + * @notice Base class for all reward manager tests + * @dev This contract is intended to be inherited from and not used directly. It contains functionality to setup a primary and secondary pool + */ +contract BaseDestinationRewardManagerTest is Test { + //contracts + ERC20Mock internal asset; + ERC20Mock internal unsupported; + DestinationRewardManager internal rewardManager; + + //default address for unregistered recipient + address internal constant INVALID_ADDRESS = address(0); + //contract owner + address internal constant ADMIN = address(uint160(uint256(keccak256("ADMIN")))); + //address to represent feeManager contract + address internal constant FEE_MANAGER = address(uint160(uint256(keccak256("FEE_MANAGER")))); + //address to represent another feeManager + address internal constant FEE_MANAGER_2 = address(uint160(uint256(keccak256("FEE_MANAGER_2")))); + //a general user + address internal constant USER = address(uint160(uint256(keccak256("USER")))); + + //default recipients configured in reward manager + address internal constant DEFAULT_RECIPIENT_1 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_1")))); + address internal constant DEFAULT_RECIPIENT_2 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_2")))); + address internal constant DEFAULT_RECIPIENT_3 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_3")))); + address internal constant DEFAULT_RECIPIENT_4 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_4")))); + address internal constant DEFAULT_RECIPIENT_5 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_5")))); + address internal constant DEFAULT_RECIPIENT_6 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_6")))); + address internal constant DEFAULT_RECIPIENT_7 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_7")))); + + //additional recipients not in the reward manager + address internal constant DEFAULT_RECIPIENT_8 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_8")))); + address internal constant DEFAULT_RECIPIENT_9 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_9")))); + + //two pools should be enough to test all edge cases + bytes32 internal constant PRIMARY_POOL_ID = keccak256("primary_pool"); + bytes32 internal constant SECONDARY_POOL_ID = keccak256("secondary_pool"); + bytes32 internal constant INVALID_POOL_ID = keccak256("invalid_pool"); + bytes32 internal constant ZERO_POOL_ID = bytes32(0); + + //convenience arrays of all pool combinations used for testing + bytes32[] internal PRIMARY_POOL_ARRAY = [PRIMARY_POOL_ID]; + bytes32[] internal SECONDARY_POOL_ARRAY = [SECONDARY_POOL_ID]; + bytes32[] internal ALL_POOLS = [PRIMARY_POOL_ID, SECONDARY_POOL_ID]; + + //erc20 config + uint256 internal constant DEFAULT_MINT_QUANTITY = 100 ether; + + //reward scalar (this should match the const in the contract) + uint64 internal constant POOL_SCALAR = 1e18; + uint64 internal constant ONE_PERCENT = POOL_SCALAR / 100; + uint64 internal constant FIFTY_PERCENT = POOL_SCALAR / 2; + uint64 internal constant TEN_PERCENT = POOL_SCALAR / 10; + + //the selector for each error + bytes4 internal immutable UNAUTHORIZED_ERROR_SELECTOR = DestinationRewardManager.Unauthorized.selector; + bytes4 internal immutable INVALID_ADDRESS_ERROR_SELECTOR = DestinationRewardManager.InvalidAddress.selector; + bytes4 internal immutable INVALID_WEIGHT_ERROR_SELECTOR = DestinationRewardManager.InvalidWeights.selector; + bytes4 internal immutable INVALID_POOL_ID_ERROR_SELECTOR = DestinationRewardManager.InvalidPoolId.selector; + bytes internal constant ONLY_CALLABLE_BY_OWNER_ERROR = "Only callable by owner"; + bytes4 internal immutable INVALID_POOL_LENGTH_SELECTOR = DestinationRewardManager.InvalidPoolLength.selector; + + // Events emitted within the reward manager + event RewardRecipientsUpdated(bytes32 indexed poolId, Common.AddressAndWeight[] newRewardRecipients); + event RewardsClaimed(bytes32 indexed poolId, address indexed recipient, uint192 quantity); + event FeeManagerUpdated(address newProxyAddress); + event FeePaid(IDestinationRewardManager.FeePayment[] payments, address payee); + + function setUp() public virtual { + //change to admin user + vm.startPrank(ADMIN); + + //init required contracts + _initializeERC20Contracts(); + _initializeRewardManager(); + } + + function _initializeERC20Contracts() internal { + //create the contracts + asset = new ERC20Mock("ASSET", "AST", ADMIN, 0); + unsupported = new ERC20Mock("UNSUPPORTED", "UNS", ADMIN, 0); + + //mint some tokens to the admin + asset.mint(ADMIN, DEFAULT_MINT_QUANTITY); + unsupported.mint(ADMIN, DEFAULT_MINT_QUANTITY); + + //mint some tokens to the user + asset.mint(FEE_MANAGER, DEFAULT_MINT_QUANTITY); + unsupported.mint(FEE_MANAGER, DEFAULT_MINT_QUANTITY); + } + + function _initializeRewardManager() internal { + //create the contract + rewardManager = new DestinationRewardManager(address(asset)); + + rewardManager.addFeeManager(FEE_MANAGER); + } + + function createPrimaryPool() public { + rewardManager.setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients()); + } + + function createSecondaryPool() public { + rewardManager.setRewardRecipients(SECONDARY_POOL_ID, getSecondaryRecipients()); + } + + //override this to test variations of different recipients. changing this function will require existing tests to be updated as constants are hardcoded to be explicit + function getPrimaryRecipients() public virtual returns (Common.AddressAndWeight[] memory) { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //init each recipient with even weights. 2500 = 25% of pool + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, POOL_SCALAR / 4); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, POOL_SCALAR / 4); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, POOL_SCALAR / 4); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, POOL_SCALAR / 4); + + return recipients; + } + + function getPrimaryRecipientAddresses() public pure returns (address[] memory) { + //array of recipients + address[] memory recipients = new address[](4); + + recipients[0] = DEFAULT_RECIPIENT_1; + recipients[1] = DEFAULT_RECIPIENT_2; + recipients[2] = DEFAULT_RECIPIENT_3; + recipients[3] = DEFAULT_RECIPIENT_4; + + return recipients; + } + + //override this to test variations of different recipients. + function getSecondaryRecipients() public virtual returns (Common.AddressAndWeight[] memory) { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //init each recipient with even weights. 2500 = 25% of pool + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, POOL_SCALAR / 4); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, POOL_SCALAR / 4); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, POOL_SCALAR / 4); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, POOL_SCALAR / 4); + + return recipients; + } + + function getSecondaryRecipientAddresses() public pure returns (address[] memory) { + //array of recipients + address[] memory recipients = new address[](4); + + recipients[0] = DEFAULT_RECIPIENT_1; + recipients[1] = DEFAULT_RECIPIENT_5; + recipients[2] = DEFAULT_RECIPIENT_6; + recipients[3] = DEFAULT_RECIPIENT_7; + + return recipients; + } + + function addFundsToPool(bytes32 poolId, Common.Asset memory amount, address sender) public { + IDestinationRewardManager.FeePayment[] memory payments = new IDestinationRewardManager.FeePayment[](1); + payments[0] = IDestinationRewardManager.FeePayment(poolId, uint192(amount.amount)); + + addFundsToPool(payments, sender); + } + + function addFundsToPool(IDestinationRewardManager.FeePayment[] memory payments, address sender) public { + //record the current address and switch to the sender + address originalAddr = msg.sender; + changePrank(sender); + + uint256 totalPayment; + for (uint256 i; i < payments.length; ++i) { + totalPayment += payments[i].amount; + } + + //approve the amount being paid into the pool + ERC20Mock(address(asset)).approve(address(rewardManager), totalPayment); + + //this represents the verifier adding some funds to the pool + rewardManager.onFeePaid(payments, sender); + + //change back to the original address + changePrank(originalAddr); + } + + function getAsset(uint256 quantity) public view returns (Common.Asset memory) { + return Common.Asset(address(asset), quantity); + } + + function getAssetBalance(address addr) public view returns (uint256) { + return asset.balanceOf(addr); + } + + function claimRewards(bytes32[] memory poolIds, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //claim the rewards + rewardManager.claimRewards(poolIds); + + //change back to the original address + changePrank(originalAddr); + } + + function payRecipients(bytes32 poolId, address[] memory recipients, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //pay the recipients + rewardManager.payRecipients(poolId, recipients); + + //change back to the original address + changePrank(originalAddr); + } + + function setRewardRecipients(bytes32 poolId, Common.AddressAndWeight[] memory recipients, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //pay the recipients + rewardManager.setRewardRecipients(poolId, recipients); + + //change back to the original address + changePrank(originalAddr); + } + + function setFeeManager(address feeManager, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //update the proxy + rewardManager.addFeeManager(feeManager); + + //change back to the original address + changePrank(originalAddr); + } + + function updateRewardRecipients(bytes32 poolId, Common.AddressAndWeight[] memory recipients, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //pay the recipients + rewardManager.updateRewardRecipients(poolId, recipients); + + //change back to the original address + changePrank(originalAddr); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.claim.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.claim.t.sol new file mode 100644 index 0000000000..c0a67d0875 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.claim.t.sol @@ -0,0 +1,790 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseDestinationRewardManagerTest} from "./BaseDestinationRewardManager.t.sol"; +import {Common} from "../../../libraries/Common.sol"; + +/** + * @title DestinationRewardManagerClaimTest + * @author Michael Fletcher + * @notice This contract will test the claim functionality of the RewardManager contract. + */ +contract DestinationRewardManagerClaimTest is BaseDestinationRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_claimAllRecipients() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + } + + function test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() public { + //add funds to a different pool to ensure they're not claimed + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //create an array containing duplicate poolIds + bytes32[] memory poolIds = new bytes32[](2); + poolIds[0] = PRIMARY_POOL_ID; + poolIds[1] = PRIMARY_POOL_ID; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(poolIds, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //the pool should still have the remaining + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimSingleRecipient() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT - expectedRecipientAmount); + } + + function test_claimMultipleRecipients() public { + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[0].addr); + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[1].addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getPrimaryRecipients()[0].addr), expectedRecipientAmount); + assertEq(getAssetBalance(getPrimaryRecipients()[1].addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT - (expectedRecipientAmount * 2)); + } + + function test_claimUnregisteredRecipient() public { + //claim the rewards for a recipient who isn't in this pool + claimRewards(PRIMARY_POOL_ARRAY, getSecondaryRecipients()[1].addr); + + //check the recipients didn't receive any fees from this pool + assertEq(getAssetBalance(getSecondaryRecipients()[1].addr), 0); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimUnevenAmountRoundsDown() public { + //adding 1 to the pool should leave 1 wei worth of dust, which the contract doesn't handle due to it being economically infeasible + addFundsToPool(PRIMARY_POOL_ID, getAsset(1), FEE_MANAGER); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //check the rewardManager has the remaining quantity equals 1 wei + assertEq(getAssetBalance(address(rewardManager)), 1); + } + + function test_claimUnregisteredPoolId() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //check the recipients balance is still 0 as there's no pool to receive fees from + assertEq(getAssetBalance(recipient.addr), 0); + + //check the rewardManager has the full amount + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_singleRecipientClaimMultipleDeposits() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity, which is 3/4 of the initial deposit + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT - expectedRecipientAmount); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the recipients balance matches the ratio the recipient should have received, which is 1/4 of each deposit + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount * 2); + + //check the rewardManager has the remaining quantity, which is now 3/4 of both deposits + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - (expectedRecipientAmount * 2)); + } + + function test_recipientsClaimMultipleDeposits() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //the reward manager balance should be 0 as all of the funds have been claimed + assertEq(getAssetBalance(address(rewardManager)), 0); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //expected recipient amount is 1/4 of the pool deposit + expectedRecipientAmount = (POOL_DEPOSIT_AMOUNT / 4) * 2; + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //the reward manager balance should again be 0 as all of the funds have been claimed + assertEq(getAssetBalance(address(rewardManager)), 0); + } + + function test_eventIsEmittedUponClaim() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //expect an emit + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit RewardsClaimed(PRIMARY_POOL_ID, recipient.addr, uint192(POOL_DEPOSIT_AMOUNT / 4)); + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + } + + function test_eventIsNotEmittedUponUnsuccessfulClaim() public { + //record logs to check no events were emitted + vm.recordLogs(); + + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //no logs should have been emitted + assertEq(vm.getRecordedLogs().length, 0); + } +} + +contract DestinationRewardManagerRecipientClaimMultiplePoolsTest is BaseDestinationRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a two pools + createPrimaryPool(); + createSecondaryPool(); + + //add funds to each of the pools to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_claimAllRecipientsSinglePool() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //check the pool balance is still equal to DEPOSIT_AMOUNT as the test only claims for one of the pools + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimMultipleRecipientsSinglePool() public { + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[1].addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getSecondaryRecipients()[0].addr), expectedRecipientAmount); + assertEq(getAssetBalance(getSecondaryRecipients()[1].addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - (expectedRecipientAmount * 2)); + } + + function test_claimMultipleRecipientsMultiplePools() public { + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[0].addr); + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[1].addr); + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[1].addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received. The first recipient is shared across both pools so should receive 1/4 of each pool + assertEq(getAssetBalance(getPrimaryRecipients()[0].addr), expectedRecipientAmount * 2); + assertEq(getAssetBalance(getPrimaryRecipients()[1].addr), expectedRecipientAmount); + assertEq(getAssetBalance(getSecondaryRecipients()[1].addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimAllRecipientsMultiplePools() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i = 1; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //claim funds for each recipient within the pool + for (uint256 i = 1; i < getSecondaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory secondaryRecipient = getSecondaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, secondaryRecipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(secondaryRecipient.addr), expectedRecipientAmount); + } + + //special case to handle the first recipient of each pool as they're the same address + Common.AddressAndWeight memory commonRecipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for each pool + claimRewards(PRIMARY_POOL_ARRAY, commonRecipient.addr); + claimRewards(SECONDARY_POOL_ARRAY, commonRecipient.addr); + + //check the balance matches the ratio the recipient should have received, which is 1/4 of each deposit for each pool + assertEq(getAssetBalance(commonRecipient.addr), expectedRecipientAmount * 2); + } + + function test_claimSingleUniqueRecipient() public { + //the first recipient of the secondary pool is in both pools, so take the second recipient which is unique + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[1]; + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received 1/4 of the deposit amount + uint256 recipientExpectedAmount = POOL_DEPOSIT_AMOUNT / 4; + + //the recipient should have received 1/4 of the deposit amount + assertEq(getAssetBalance(recipient.addr), recipientExpectedAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - recipientExpectedAmount); + } + + function test_claimSingleRecipientMultiplePools() public { + //the first recipient of the secondary pool is in both pools + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received 1/4 of the deposit amount for each pool + uint256 recipientExpectedAmount = (POOL_DEPOSIT_AMOUNT / 4) * 2; + + //this recipient belongs in both pools so should have received 1/4 of each + assertEq(getAssetBalance(recipient.addr), recipientExpectedAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - recipientExpectedAmount); + } + + function test_claimUnregisteredRecipient() public { + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, getSecondaryRecipients()[1].addr); + claimRewards(SECONDARY_POOL_ARRAY, getPrimaryRecipients()[1].addr); + + //check the recipients didn't receive any fees from this pool + assertEq(getAssetBalance(getSecondaryRecipients()[1].addr), 0); + assertEq(getAssetBalance(getPrimaryRecipients()[1].addr), 0); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2); + } + + function test_claimUnevenAmountRoundsDown() public { + //adding an uneven amount of dust to each pool, this should round down to the nearest whole number with 4 remaining in the contract + addFundsToPool(PRIMARY_POOL_ID, getAsset(3), FEE_MANAGER); + addFundsToPool(SECONDARY_POOL_ID, getAsset(1), FEE_MANAGER); + + //the recipient should have received 1/4 of the deposit amount for each pool + uint256 recipientExpectedAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), recipientExpectedAmount); + } + + //special case to handle the first recipient of each pool as they're the same address + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getSecondaryRecipients()[0].addr), recipientExpectedAmount * 2); + + //claim funds for each recipient of the secondary pool except the first + for (uint256 i = 1; i < getSecondaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), recipientExpectedAmount); + } + + //contract should have 4 remaining + assertEq(getAssetBalance(address(rewardManager)), 4); + } + + function test_singleRecipientClaimMultipleDeposits() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received 1/4 of the deposit amount + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity, which is 3/4 of the initial deposit plus the deposit from the second pool + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - expectedRecipientAmount); + + //add funds to the pool to be split among the recipients + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //claim the individual rewards for this recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received 1/4 of the next deposit amount + expectedRecipientAmount += POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received, which is 1/4 of each deposit + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity, which is now 3/4 of both deposits + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 3 - expectedRecipientAmount); + } + + function test_recipientsClaimMultipleDeposits() public { + //the recipient should have received 1/4 of the deposit amount + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getSecondaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //the reward manager balance should contain only the funds of the secondary pool + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + + //add funds to the pool to be split among the recipients + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //special case to handle the first recipient of each pool as they're the same address + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getSecondaryRecipients()[0].addr), expectedRecipientAmount * 2); + + //claim funds for each recipient within the pool except the first + for (uint256 i = 1; i < getSecondaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount * 2); + } + + //the reward manager balance should again be the balance of the secondary pool as the primary pool has been emptied twice + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimEmptyPoolWhenSecondPoolContainsFunds() public { + //the recipient should have received 1/4 of the deposit amount + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim all rewards for each recipient in the primary pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //claim all the rewards again for the first recipient as that address is a member of both pools + claimRewards(PRIMARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + + //check the balance + assertEq(getAssetBalance(getSecondaryRecipients()[0].addr), expectedRecipientAmount); + } + + function test_getRewardsAvailableToRecipientInBothPools() public { + //get index 0 as this recipient is in both default pools + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds( + getPrimaryRecipients()[0].addr, + 0, + type(uint256).max + ); + + //check the recipient is in both pools + assertEq(poolIds[0], PRIMARY_POOL_ID); + assertEq(poolIds[1], SECONDARY_POOL_ID); + } + + function test_getRewardsAvailableToRecipientInSinglePool() public { + //get index 0 as this recipient is in both default pools + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds( + getPrimaryRecipients()[1].addr, + 0, + type(uint256).max + ); + + //check the recipient is in both pools + assertEq(poolIds[0], PRIMARY_POOL_ID); + assertEq(poolIds[1], ZERO_POOL_ID); + } + + function test_getRewardsAvailableToRecipientInNoPools() public view { + //get index 0 as this recipient is in both default pools + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(FEE_MANAGER, 0, type(uint256).max); + + //check the recipient is in neither pool + assertEq(poolIds[0], ZERO_POOL_ID); + assertEq(poolIds[1], ZERO_POOL_ID); + } + + function test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() public { + //get index 0 as this recipient is in both default pools + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds( + getPrimaryRecipients()[0].addr, + 0, + type(uint256).max + ); + + //check the recipient is in both pools + assertEq(poolIds[0], PRIMARY_POOL_ID); + assertEq(poolIds[1], SECONDARY_POOL_ID); + + //claim the rewards for each pool + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[0].addr); + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + + //get the available pools again + poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr, 0, type(uint256).max); + + //user should not be in any pool + assertEq(poolIds[0], ZERO_POOL_ID); + assertEq(poolIds[1], ZERO_POOL_ID); + } + + function test_getAvailableRewardsCursorCannotBeGreaterThanTotalPools() public { + vm.expectRevert(INVALID_POOL_LENGTH_SELECTOR); + + rewardManager.getAvailableRewardPoolIds(FEE_MANAGER, type(uint256).max, 0); + } + + function test_getAvailableRewardsCursorAndTotalPoolsEqual() public { + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr, 2, 2); + + assertEq(poolIds.length, 0); + } + + function test_getAvailableRewardsCursorSingleResult() public { + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr, 0, 1); + + assertEq(poolIds[0], PRIMARY_POOL_ID); + } +} + +contract DestinationRewardManagerRecipientClaimDifferentWeightsTest is BaseDestinationRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function getPrimaryRecipients() public virtual override returns (Common.AddressAndWeight[] memory) { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //init each recipient with uneven weights + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT * 8); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, ONE_PERCENT * 6); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, ONE_PERCENT * 4); + + return recipients; + } + + function test_allRecipientsClaimingReceiveExpectedAmount() public { + //loop all the recipients and claim their expected amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received a share proportional to their weight + uint256 expectedRecipientAmount = (POOL_DEPOSIT_AMOUNT * recipient.weight) / POOL_SCALAR; + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + } +} + +contract DestinationRewardManagerRecipientClaimUnevenWeightTest is BaseDestinationRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + } + + function getPrimaryRecipients() public virtual override returns (Common.AddressAndWeight[] memory) { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](2); + + uint64 oneThird = POOL_SCALAR / 3; + + //init each recipient with even weights. + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, oneThird); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, 2 * oneThird + 1); + + return recipients; + } + + function test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() public { + //add a smaller amount of funds to the pool + uint256 smallDeposit = 1e8; + + //add a smaller amount of funds to the pool + addFundsToPool(PRIMARY_POOL_ID, getAsset(smallDeposit), FEE_MANAGER); + + //loop all the recipients and claim their expected amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received a share proportional to their weight + uint256 expectedRecipientAmount = (smallDeposit * recipient.weight) / POOL_SCALAR; + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //smaller deposits will consequently have less precision and will not be able to be split as evenly, the remaining 1 will be lost due to 333...|... being paid out instead of 333...4| + assertEq(getAssetBalance(address(rewardManager)), 1); + } + + function test_allRecipientsClaimingReceiveExpectedAmount() public { + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //loop all the recipients and claim their expected amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received a share proportional to their weight + uint256 expectedRecipientAmount = (POOL_DEPOSIT_AMOUNT * recipient.weight) / POOL_SCALAR; + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //their should be 0 wei left over indicating a successful split + assertEq(getAssetBalance(address(rewardManager)), 0); + } +} + +contract DestinationRewardManagerNoRecipientSet is BaseDestinationRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //add funds to the pool to be split among the recipients once registered + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_claimAllRecipientsAfterRecipientsSet() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //try and claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //there should be no rewards claimed as the recipient is not registered + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the recipient received nothing + assertEq(getAssetBalance(recipient.addr), 0); + } + + //Set the recipients after the rewards have been paid into the pool + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //there should be no rewards claimed as the recipient is registered + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.general.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.general.t.sol new file mode 100644 index 0000000000..4c79d2cba5 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.general.t.sol @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseDestinationRewardManagerTest} from "./BaseDestinationRewardManager.t.sol"; +import {DestinationRewardManager} from "../../../v0.4.0/DestinationRewardManager.sol"; +import {ERC20Mock} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {IDestinationRewardManager} from "../../interfaces/IDestinationRewardManager.sol"; + +/** + * @title DestinationRewardManagerSetupTest + * @author Michael Fletcher + * @notice This contract will test the core functionality of the DestinationRewardManager contract + */ +contract DestinationRewardManagerSetupTest is BaseDestinationRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + } + + function test_rejectsZeroLinkAddressOnConstruction() public { + //should revert if the contract is a zero address + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //create a rewardManager with a zero link address + new DestinationRewardManager(address(0)); + } + + function test_eventEmittedUponFeeManagerUpdate() public { + //expect the event to be emitted + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit FeeManagerUpdated(FEE_MANAGER_2); + + //set the verifier proxy + setFeeManager(FEE_MANAGER_2, ADMIN); + } + + function test_eventEmittedUponFeePaid() public { + //create pool and add funds + createPrimaryPool(); + + //change to the feeManager who is the one who will be paying the fees + changePrank(FEE_MANAGER); + + //approve the amount being paid into the pool + ERC20Mock(getAsset(POOL_DEPOSIT_AMOUNT).assetAddress).approve(address(rewardManager), POOL_DEPOSIT_AMOUNT); + + IDestinationRewardManager.FeePayment[] memory payments = new IDestinationRewardManager.FeePayment[](1); + payments[0] = IDestinationRewardManager.FeePayment(PRIMARY_POOL_ID, uint192(POOL_DEPOSIT_AMOUNT)); + + //event is emitted when funds are added + vm.expectEmit(); + emit FeePaid(payments, FEE_MANAGER); + + //this represents the verifier adding some funds to the pool + rewardManager.onFeePaid(payments, FEE_MANAGER); + } + + function test_setFeeManagerZeroAddress() public { + //should revert if the contract is a zero address + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //set the verifier proxy + setFeeManager(address(0), ADMIN); + } + + function test_addFeeManagerZeroAddress() public { + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + rewardManager.addFeeManager(address(0)); + } + + function test_addFeeManagerExistingAddress() public { + address dummyAddress = address(998); + rewardManager.addFeeManager(dummyAddress); + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + rewardManager.addFeeManager(dummyAddress); + } + + function test_removeFeeManagerNonExistentAddress() public { + address dummyAddress = address(991); + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + rewardManager.removeFeeManager(dummyAddress); + } + + function test_addRemoveFeeManager() public { + address dummyAddress1 = address(1); + address dummyAddress2 = address(2); + rewardManager.addFeeManager(dummyAddress1); + rewardManager.addFeeManager(dummyAddress2); + assertEq(rewardManager.s_feeManagerAddressList(dummyAddress1), dummyAddress1); + assertEq(rewardManager.s_feeManagerAddressList(dummyAddress2), dummyAddress2); + rewardManager.removeFeeManager(dummyAddress1); + assertEq(rewardManager.s_feeManagerAddressList(dummyAddress1), address(0)); + assertEq(rewardManager.s_feeManagerAddressList(dummyAddress2), dummyAddress2); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.payRecipients.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.payRecipients.t.sol new file mode 100644 index 0000000000..4aa3c868b3 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.payRecipients.t.sol @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseDestinationRewardManagerTest} from "./BaseDestinationRewardManager.t.sol"; +import {IDestinationRewardManager} from "../../interfaces/IDestinationRewardManager.sol"; + +/** + * @title DestinationRewardManagerPayRecipientsTest + * @author Michael Fletcher + * @notice This contract will test the payRecipients functionality of the RewardManager contract + */ +contract DestinationRewardManagerPayRecipientsTest is BaseDestinationRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_payAllRecipients() public { + //pay all the recipients in the pool + payRecipients(PRIMARY_POOL_ID, getPrimaryRecipientAddresses(), ADMIN); + + //each recipient should receive 1/4 of the pool + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each recipient received the correct amount + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + assertEq(getAssetBalance(getPrimaryRecipientAddresses()[i]), expectedRecipientAmount); + } + } + + function test_paySingleRecipient() public { + //get the first individual recipient + address recipient = getPrimaryRecipientAddresses()[0]; + + //get a single recipient as an array + address[] memory recipients = new address[](1); + recipients[0] = recipient; + + //pay a single recipient + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //the recipient should have received 1/4 of the deposit amount + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + assertEq(getAssetBalance(recipient), expectedRecipientAmount); + } + + function test_payRecipientWithInvalidPool() public { + //get the first individual recipient + address recipient = getPrimaryRecipientAddresses()[0]; + + //get a single recipient as an array + address[] memory recipients = new address[](1); + recipients[0] = recipient; + + //pay a single recipient + payRecipients(SECONDARY_POOL_ID, recipients, ADMIN); + + //the recipient should have received nothing + assertEq(getAssetBalance(recipient), 0); + } + + function test_payRecipientsEmptyRecipientList() public { + //get a single recipient + address[] memory recipients = new address[](0); + + //pay a single recipient + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //rewardManager should have the full balance + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_payAllRecipientsWithAdditionalUnregisteredRecipient() public { + //load all the recipients and add an additional one who is not in the pool + address[] memory recipients = new address[](getPrimaryRecipientAddresses().length + 1); + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + recipients[i] = getPrimaryRecipientAddresses()[i]; + } + recipients[recipients.length - 1] = DEFAULT_RECIPIENT_5; + + //pay the recipients + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //each recipient should receive 1/4 of the pool except the last + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each recipient received the correct amount + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + assertEq(getAssetBalance(getPrimaryRecipientAddresses()[i]), expectedRecipientAmount); + } + + //the unregistered recipient should receive nothing + assertEq(getAssetBalance(DEFAULT_RECIPIENT_5), 0); + } + + function test_payAllRecipientsWithAdditionalInvalidRecipient() public { + //load all the recipients and add an additional one which is invalid, that should receive nothing + address[] memory recipients = new address[](getPrimaryRecipientAddresses().length + 1); + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + recipients[i] = getPrimaryRecipientAddresses()[i]; + } + recipients[recipients.length - 1] = INVALID_ADDRESS; + + //pay the recipients + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //each recipient should receive 1/4 of the pool except the last + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each recipient received the correct amount + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + assertEq(getAssetBalance(getPrimaryRecipientAddresses()[i]), expectedRecipientAmount); + } + } + + function test_paySubsetOfRecipientsInPool() public { + //load a subset of the recipients into an array + address[] memory recipients = new address[](getPrimaryRecipientAddresses().length - 1); + for (uint256 i = 0; i < recipients.length; i++) { + recipients[i] = getPrimaryRecipientAddresses()[i]; + } + + //pay the subset of recipients + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //each recipient should receive 1/4 of the pool except the last + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each subset of recipients received the correct amount + for (uint256 i = 0; i < recipients.length - 1; i++) { + assertEq(getAssetBalance(recipients[i]), expectedRecipientAmount); + } + + //check the pool has the remaining balance + assertEq( + getAssetBalance(address(rewardManager)), + POOL_DEPOSIT_AMOUNT - expectedRecipientAmount * recipients.length + ); + } + + function test_payAllRecipientsFromNonAdminUser() public { + //should revert if the caller isn't an admin or recipient within the pool + vm.expectRevert(UNAUTHORIZED_ERROR_SELECTOR); + + //pay all the recipients in the pool + payRecipients(PRIMARY_POOL_ID, getPrimaryRecipientAddresses(), FEE_MANAGER); + } + + function test_payAllRecipientsFromRecipientInPool() public { + //pay all the recipients in the pool + payRecipients(PRIMARY_POOL_ID, getPrimaryRecipientAddresses(), DEFAULT_RECIPIENT_1); + + //each recipient should receive 1/4 of the pool + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each recipient received the correct amount + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + assertEq(getAssetBalance(getPrimaryRecipientAddresses()[i]), expectedRecipientAmount); + } + } + + function test_payRecipientsWithInvalidPoolId() public { + //pay all the recipients in the pool + payRecipients(INVALID_POOL_ID, getPrimaryRecipientAddresses(), ADMIN); + + //pool should still contain the full balance + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_addFundsToPoolAsOwner() public { + //add funds to the pool + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_addFundsToPoolAsNonOwnerOrFeeManager() public { + //should revert if the caller isn't an admin or recipient within the pool + vm.expectRevert(UNAUTHORIZED_ERROR_SELECTOR); + + IDestinationRewardManager.FeePayment[] memory payments = new IDestinationRewardManager.FeePayment[](1); + payments[0] = IDestinationRewardManager.FeePayment(PRIMARY_POOL_ID, uint192(POOL_DEPOSIT_AMOUNT)); + + //add funds to the pool + rewardManager.onFeePaid(payments, USER); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.setRecipients.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.setRecipients.t.sol new file mode 100644 index 0000000000..facbaa1ab7 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.setRecipients.t.sol @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseDestinationRewardManagerTest} from "./BaseDestinationRewardManager.t.sol"; +import {Common} from "../../../libraries/Common.sol"; + +/** + * @title DestinationRewardManagerSetRecipientsTest + * @author Michael Fletcher + * @notice This contract will test the setRecipient functionality of the RewardManager contract + */ +contract DestinationRewardManagerSetRecipientsTest is BaseDestinationRewardManagerTest { + function setUp() public override { + //setup contracts + super.setUp(); + } + + function test_setRewardRecipients() public { + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + } + + function test_setRewardRecipientsIsEmpty() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //should revert if the recipients array is empty + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setRewardRecipientWithZeroWeight() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](5); + + //init each recipient with even weights + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, ONE_PERCENT * 25); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, ONE_PERCENT * 25); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, ONE_PERCENT * 25); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, ONE_PERCENT * 25); + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, 0); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setRewardRecipientWithZeroAddress() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = getPrimaryRecipients(); + + //override the first recipient with a zero address + recipients[0].addr = address(0); + + //should revert if the recipients array is empty + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setRewardRecipientWeights() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //init each recipient with even weights + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, 25); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, 25); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, 25); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, 25); + + //should revert if the recipients array is empty + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //set the recipients with a recipient with a weight of 100% + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setSingleRewardRecipient() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](1); + + //init each recipient with even weights + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, POOL_SCALAR); + + //set the recipients with a recipient with a weight of 100% + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setRewardRecipientTwice() public { + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + + //should revert if recipients for this pool have already been set + vm.expectRevert(INVALID_POOL_ID_ERROR_SELECTOR); + + //set the recipients again + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + } + + function test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() public { + //should revert if the sender is not the owner or proxy + vm.expectRevert(UNAUTHORIZED_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), USER); + } + + function test_setRewardRecipientFromManagerAddress() public { + //update the proxy address + setFeeManager(FEE_MANAGER_2, ADMIN); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), FEE_MANAGER_2); + } + + function test_eventIsEmittedUponSetRecipients() public { + //expect an emit + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit RewardRecipientsUpdated(PRIMARY_POOL_ID, getPrimaryRecipients()); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + } + + function test_setRecipientContainsDuplicateRecipients() public { + //create a new array to hold the existing recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length * 2); + + //add all the existing recipients + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i] = getPrimaryRecipients()[i]; + } + //add all the existing recipients again + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i + getPrimaryRecipients().length] = getPrimaryRecipients()[i]; + } + + //should revert as the list contains a duplicate + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.updateRewardRecipients.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.updateRewardRecipients.t.sol new file mode 100644 index 0000000000..226be8ed32 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/reward-manager/DestinationRewardManager.updateRewardRecipients.t.sol @@ -0,0 +1,450 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseDestinationRewardManagerTest} from "./BaseDestinationRewardManager.t.sol"; +import {Common} from "../../../libraries/Common.sol"; + +/** + * @title DestinationRewardManagerUpdateRewardRecipientsTest + * @author Michael Fletcher + * @notice This contract will test the updateRecipient functionality of the RewardManager contract + */ +contract DestinationRewardManagerUpdateRewardRecipientsTest is BaseDestinationRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_onlyAdminCanUpdateRecipients() public { + //should revert if the caller is not the admin + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + //updating a recipient should force the funds to be paid out + updateRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), FEE_MANAGER); + } + + function test_updateAllRecipientsWithSameAddressAndWeight() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //updating a recipient should force the funds to be paid out + updateRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getPrimaryRecipients()[i].addr), expectedRecipientAmount); + } + } + + function test_updatePartialRecipientsWithSameAddressAndWeight() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //get a subset of the recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](2); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, ONE_PERCENT * 25); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, ONE_PERCENT * 25); + + //updating a recipient should force the funds to be paid out + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < recipients.length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipients[i].addr), expectedRecipientAmount); + } + + //the reward manager should still have half remaining funds + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT / 2); + } + + function test_updateRecipientWithNewZeroAddress() public { + //create a new array to hold the existing recipients plus a new zero address + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 1); + + //add all the existing recipients + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i] = getPrimaryRecipients()[i]; + } + //add a new address to the primary recipients + recipients[recipients.length - 1] = Common.AddressAndWeight(address(0), 0); + + //should revert if the recipient is a zero address + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //update the recipients with invalid address + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsContainsDuplicateRecipients() public { + //create a new array to hold the existing recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length * 2); + + //add all the existing recipients + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i] = getPrimaryRecipients()[i]; + } + //add all the existing recipients again + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i + getPrimaryRecipients().length] = getPrimaryRecipients()[i]; + } + + //should revert as the list contains a duplicate + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //update the recipients with the duplicate addresses + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsToDifferentSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 4); + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //copy the recipient and set the weight to 0 which implies the recipient is being replaced + recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0); + } + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, ONE_PERCENT * 25); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, ONE_PERCENT * 25); + recipients[6] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, ONE_PERCENT * 25); + recipients[7] = Common.AddressAndWeight(DEFAULT_RECIPIENT_8, ONE_PERCENT * 25); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsToDifferentPartialSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 2); + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //copy the recipient and set the weight to 0 which implies the recipient is being replaced + recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0); + } + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, FIFTY_PERCENT); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, FIFTY_PERCENT); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsToDifferentLargerSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 5); + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //copy the recipient and set the weight to 0 which implies the recipient is being replaced + recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0); + } + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT * 2); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, TEN_PERCENT * 2); + recipients[6] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, TEN_PERCENT * 2); + recipients[7] = Common.AddressAndWeight(DEFAULT_RECIPIENT_8, TEN_PERCENT * 2); + recipients[8] = Common.AddressAndWeight(DEFAULT_RECIPIENT_9, TEN_PERCENT * 2); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsUpdateAndRemoveExistingForLargerSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](9); + + //update the existing recipients + recipients[0] = Common.AddressAndWeight(getPrimaryRecipients()[0].addr, 0); + recipients[1] = Common.AddressAndWeight(getPrimaryRecipients()[1].addr, 0); + recipients[2] = Common.AddressAndWeight(getPrimaryRecipients()[2].addr, TEN_PERCENT * 3); + recipients[3] = Common.AddressAndWeight(getPrimaryRecipients()[3].addr, TEN_PERCENT * 3); + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, TEN_PERCENT); + recipients[6] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, TEN_PERCENT); + recipients[7] = Common.AddressAndWeight(DEFAULT_RECIPIENT_8, TEN_PERCENT); + recipients[8] = Common.AddressAndWeight(DEFAULT_RECIPIENT_9, TEN_PERCENT); + + //should revert as the weight does not equal 100% + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](5); + + //update the existing recipients + recipients[0] = Common.AddressAndWeight(getPrimaryRecipients()[0].addr, 0); + recipients[1] = Common.AddressAndWeight(getPrimaryRecipients()[1].addr, 0); + recipients[2] = Common.AddressAndWeight(getPrimaryRecipients()[2].addr, TEN_PERCENT * 3); + recipients[3] = Common.AddressAndWeight(getPrimaryRecipients()[3].addr, TEN_PERCENT * 2); + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT * 5); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsToDifferentSetWithInvalidWeights() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 2); + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //copy the recipient and set the weight to 0 which implies the recipient is being replaced + recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0); + } + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT * 5); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, TEN_PERCENT); + + //should revert as the weight will not equal 100% + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updatePartialRecipientsToSubset() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, 0); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, 0); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT * 5); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT * 5); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updatePartialRecipientsWithUnderWeightSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT); + + //should revert as the new weights exceed the previous weights being replaced + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updatePartialRecipientsWithExcessiveWeight() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, POOL_SCALAR); + + //should revert as the new weights exceed the previous weights being replaced + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientWeights() public { + //expected recipient amount is 1/4 of the pool deposit for original recipients + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //create a list of containing recipients from the primary configured set with their new weights + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT * 3); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT * 5); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < recipients.length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipients[i].addr), expectedRecipientAmount); + } + + //the reward manager should have no funds remaining + assertEq(getAssetBalance(address(rewardManager)), 0); + + //add more funds to the pool to check new distribution + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //loop each user and claim the rewards + for (uint256 i; i < recipients.length; i++) { + //claim the rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipients[i].addr); + } + + //manually check the balance of each recipient + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_1), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_2), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_3), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 3) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_4), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 5) / POOL_SCALAR + expectedRecipientAmount + ); + } + + function test_partialUpdateRecipientWeights() public { + //expected recipient amount is 1/4 of the pool deposit for original recipients + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //create a list of containing recipients from the primary configured set with their new weights + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](2); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT * 4); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < recipients.length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipients[i].addr), expectedRecipientAmount); + } + + //the reward manager should have half the funds remaining + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT / 2); + + //add more funds to the pool to check new distribution + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //loop each user and claim the rewards + for (uint256 i; i < recipients.length; i++) { + //claim the rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipients[i].addr); + } + + //manually check the balance of each recipient + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_1), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_2), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 4) / POOL_SCALAR + expectedRecipientAmount + ); + + //the reward manager should have half the funds remaining + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_eventIsEmittedUponUpdateRecipients() public { + //expect an emit + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit RewardRecipientsUpdated(PRIMARY_POOL_ID, getPrimaryRecipients()); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //updating a recipient should force the funds to be paid out + updateRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getPrimaryRecipients()[i].addr), expectedRecipientAmount); + } + } +} + +contract DestinationRewardManagerUpdateRewardRecipientsMultiplePoolsTest is BaseDestinationRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + createSecondaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function getSecondaryRecipients() public override returns (Common.AddressAndWeight[] memory) { + //for testing purposes, the primary and secondary pool to contain the same recipients + return getPrimaryRecipients(); + } + + function test_updatePrimaryRecipientWeights() public { + //expected recipient amount is 1/4 of the pool deposit for original recipients + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT * 4); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT * 4); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < recipients.length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipients[i].addr), expectedRecipientAmount); + } + + //the reward manager should still have the funds for the secondary pool + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + + //add more funds to the pool to check new distribution + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //claim the rewards for the updated recipients manually + claimRewards(PRIMARY_POOL_ARRAY, recipients[0].addr); + claimRewards(PRIMARY_POOL_ARRAY, recipients[1].addr); + claimRewards(PRIMARY_POOL_ARRAY, recipients[2].addr); + claimRewards(PRIMARY_POOL_ARRAY, recipients[3].addr); + + //check the balance matches the ratio the recipient who were updated should have received + assertEq( + getAssetBalance(recipients[0].addr), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 4) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(recipients[1].addr), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 4) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(recipients[2].addr), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(recipients[3].addr), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/BaseDestinationVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/BaseDestinationVerifierTest.t.sol new file mode 100644 index 0000000000..ec3b3a0eed --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/BaseDestinationVerifierTest.t.sol @@ -0,0 +1,347 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {Test} from "forge-std/Test.sol"; +import {DestinationVerifierProxy} from "../../DestinationVerifierProxy.sol"; +import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {IDestinationVerifier} from "../../interfaces/IDestinationVerifier.sol"; +import {IDestinationVerifierProxy} from "../../interfaces/IDestinationVerifierProxy.sol"; +import {DestinationVerifier} from "../../DestinationVerifier.sol"; +import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; +import {DestinationFeeManager} from "../../DestinationFeeManager.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {ERC20Mock} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {WERC20Mock} from "../../../../shared/mocks/WERC20Mock.sol"; +import {DestinationRewardManager} from "../../DestinationRewardManager.sol"; +import {IDestinationRewardManager} from "../../interfaces/IDestinationRewardManager.sol"; + +contract BaseTest is Test { + uint64 internal constant POOL_SCALAR = 1e18; + uint64 internal constant ONE_PERCENT = POOL_SCALAR / 100; + uint256 internal constant MAX_ORACLES = 31; + address internal constant ADMIN = address(1); + address internal constant USER = address(2); + + address internal constant MOCK_VERIFIER_ADDRESS = address(100); + address internal constant ACCESS_CONTROLLER_ADDRESS = address(300); + + uint256 internal constant DEFAULT_REPORT_LINK_FEE = 1e10; + uint256 internal constant DEFAULT_REPORT_NATIVE_FEE = 1e12; + + uint64 internal constant VERIFIER_VERSION = 1; + + uint8 internal constant FAULT_TOLERANCE = 10; + + DestinationVerifierProxy internal s_verifierProxy; + DestinationVerifier internal s_verifier; + DestinationFeeManager internal feeManager; + DestinationRewardManager internal rewardManager; + ERC20Mock internal link; + WERC20Mock internal native; + + struct Signer { + uint256 mockPrivateKey; + address signerAddress; + } + + Signer[MAX_ORACLES] internal s_signers; + bytes32[] internal s_offchaintransmitters; + bool private s_baseTestInitialized; + + struct V3Report { + // The feed ID the report has data for + bytes32 feedId; + // The time the median value was observed on + uint32 observationsTimestamp; + // The timestamp the report is valid from + uint32 validFromTimestamp; + // The link fee + uint192 linkFee; + // The native fee + uint192 nativeFee; + // The expiry of the report + uint32 expiresAt; + // The median value agreed in an OCR round + int192 benchmarkPrice; + // The best bid value agreed in an OCR round + int192 bid; + // The best ask value agreed in an OCR round + int192 ask; + } + + bytes32 internal constant V_MASK = 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 internal constant V1_BITMASK = 0x0001000000000000000000000000000000000000000000000000000000000000; + bytes32 internal constant V2_BITMASK = 0x0002000000000000000000000000000000000000000000000000000000000000; + bytes32 internal constant V3_BITMASK = 0x0003000000000000000000000000000000000000000000000000000000000000; + + bytes32 internal constant INVALID_FEED = keccak256("INVALID"); + uint32 internal constant OBSERVATIONS_TIMESTAMP = 1000; + uint64 internal constant BLOCKNUMBER_LOWER_BOUND = 1000; + uint64 internal constant BLOCKNUMBER_UPPER_BOUND = BLOCKNUMBER_LOWER_BOUND + 5; + int192 internal constant MEDIAN = 1 ether; + int192 internal constant BID = 500000000 gwei; + int192 internal constant ASK = 2 ether; + + //version 0 feeds + bytes32 internal constant FEED_ID = (keccak256("ETH-USD") & V_MASK) | V1_BITMASK; + bytes32 internal constant FEED_ID_2 = (keccak256("LINK-USD") & V_MASK) | V1_BITMASK; + bytes32 internal constant FEED_ID_3 = (keccak256("BTC-USD") & V_MASK) | V1_BITMASK; + + //version 3 feeds + bytes32 internal constant FEED_ID_V3 = (keccak256("ETH-USD") & V_MASK) | V3_BITMASK; + + function _encodeReport(V3Report memory report) internal pure returns (bytes memory) { + return + abi.encode( + report.feedId, + report.observationsTimestamp, + report.validFromTimestamp, + report.nativeFee, + report.linkFee, + report.expiresAt, + report.benchmarkPrice, + report.bid, + report.ask + ); + } + + function _generateSignerSignatures( + bytes memory report, + bytes32[3] memory reportContext, + Signer[] memory signers + ) internal pure returns (bytes32[] memory rawRs, bytes32[] memory rawSs, bytes32 rawVs) { + bytes32[] memory rs = new bytes32[](signers.length); + bytes32[] memory ss = new bytes32[](signers.length); + bytes memory vs = new bytes(signers.length); + + bytes32 hash = keccak256(abi.encodePacked(keccak256(report), reportContext)); + + for (uint256 i = 0; i < signers.length; i++) { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(signers[i].mockPrivateKey, hash); + rs[i] = r; + ss[i] = s; + vs[i] = bytes1(v - 27); + } + return (rs, ss, bytes32(vs)); + } + + function _generateV3EncodedBlob( + V3Report memory report, + bytes32[3] memory reportContext, + Signer[] memory signers + ) internal pure returns (bytes memory) { + bytes memory reportBytes = _encodeReport(report); + (bytes32[] memory rs, bytes32[] memory ss, bytes32 rawVs) = _generateSignerSignatures( + reportBytes, + reportContext, + signers + ); + return abi.encode(reportContext, reportBytes, rs, ss, rawVs); + } + + function _verify(bytes memory payload, address feeAddress, uint256 wrappedNativeValue, address sender) internal { + address originalAddr = msg.sender; + changePrank(sender); + + s_verifierProxy.verify{value: wrappedNativeValue}(payload, abi.encode(feeAddress)); + + changePrank(originalAddr); + } + + function _generateV3Report() internal view returns (V3Report memory) { + return + V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + } + + function _verifyBulk( + bytes[] memory payload, + address feeAddress, + uint256 wrappedNativeValue, + address sender + ) internal { + address originalAddr = msg.sender; + changePrank(sender); + + s_verifierProxy.verifyBulk{value: wrappedNativeValue}(payload, abi.encode(feeAddress)); + + changePrank(originalAddr); + } + + function _approveLink(address spender, uint256 quantity, address sender) internal { + address originalAddr = msg.sender; + changePrank(sender); + + link.approve(spender, quantity); + changePrank(originalAddr); + } + + function setUp() public virtual { + // BaseTest.setUp is often called multiple times from tests' setUp due to inheritance. + if (s_baseTestInitialized) return; + s_baseTestInitialized = true; + vm.startPrank(ADMIN); + + s_verifierProxy = new DestinationVerifierProxy(); + s_verifier = new DestinationVerifier(address(s_verifierProxy)); + s_verifierProxy.setVerifier(address(s_verifier)); + + // setting up FeeManager and RewardManager + native = new WERC20Mock(); + link = new ERC20Mock("LINK", "LINK", ADMIN, 0); + rewardManager = new DestinationRewardManager(address(link)); + feeManager = new DestinationFeeManager(address(link), address(native), address(s_verifier), address(rewardManager)); + + for (uint256 i; i < MAX_ORACLES; i++) { + uint256 mockPK = i + 1; + s_signers[i].mockPrivateKey = mockPK; + s_signers[i].signerAddress = vm.addr(mockPK); + } + } + + function _getSigners(uint256 numSigners) internal view returns (Signer[] memory) { + Signer[] memory signers = new Signer[](numSigners); + for (uint256 i; i < numSigners; i++) { + signers[i] = s_signers[i]; + } + return signers; + } + + function _getSignerAddresses(Signer[] memory signers) internal pure returns (address[] memory) { + address[] memory signerAddrs = new address[](signers.length); + for (uint256 i = 0; i < signerAddrs.length; i++) { + signerAddrs[i] = signers[i].signerAddress; + } + return signerAddrs; + } + + function _signerAddressAndDonConfigKey(address signer, bytes24 donConfigId) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(signer, donConfigId)); + } + + function _donConfigIdFromConfigData(address[] memory signers, uint8 f) internal pure returns (bytes24) { + Common._quickSort(signers, 0, int256(signers.length - 1)); + bytes24 donConfigId = bytes24(keccak256(abi.encodePacked(signers, f))); + return donConfigId; + } + + function assertReportsEqual(bytes memory response, V3Report memory testReport) public pure { + ( + bytes32 feedId, + uint32 observationsTimestamp, + uint32 validFromTimestamp, + uint192 nativeFee, + uint192 linkFee, + uint32 expiresAt, + int192 benchmarkPrice, + int192 bid, + int192 ask + ) = abi.decode(response, (bytes32, uint32, uint32, uint192, uint192, uint32, int192, int192, int192)); + assertEq(feedId, testReport.feedId); + assertEq(observationsTimestamp, testReport.observationsTimestamp); + assertEq(validFromTimestamp, testReport.validFromTimestamp); + assertEq(expiresAt, testReport.expiresAt); + assertEq(benchmarkPrice, testReport.benchmarkPrice); + assertEq(bid, testReport.bid); + assertEq(ask, testReport.ask); + assertEq(linkFee, testReport.linkFee); + assertEq(nativeFee, testReport.nativeFee); + } + + function _approveNative(address spender, uint256 quantity, address sender) internal { + address originalAddr = msg.sender; + changePrank(sender); + + native.approve(spender, quantity); + changePrank(originalAddr); + } +} + +contract VerifierWithFeeManager is BaseTest { + uint256 internal constant DEFAULT_LINK_MINT_QUANTITY = 100 ether; + uint256 internal constant DEFAULT_NATIVE_MINT_QUANTITY = 100 ether; + + function setUp() public virtual override { + BaseTest.setUp(); + + s_verifierProxy.setVerifier(address(s_verifier)); + s_verifier.setFeeManager(address(feeManager)); + rewardManager.addFeeManager(address(feeManager)); + + //mint some tokens to the user + link.mint(USER, DEFAULT_LINK_MINT_QUANTITY); + native.mint(USER, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(USER, DEFAULT_NATIVE_MINT_QUANTITY); + + //mint some link tokens to the feeManager pool + link.mint(address(feeManager), DEFAULT_REPORT_LINK_FEE); + } +} + +contract MultipleVerifierWithMultipleFeeManagers is BaseTest { + uint256 internal constant DEFAULT_LINK_MINT_QUANTITY = 100 ether; + uint256 internal constant DEFAULT_NATIVE_MINT_QUANTITY = 100 ether; + + DestinationVerifier internal s_verifier2; + DestinationVerifier internal s_verifier3; + + DestinationVerifierProxy internal s_verifierProxy2; + DestinationVerifierProxy internal s_verifierProxy3; + + DestinationFeeManager internal feeManager2; + + function setUp() public virtual override { + /* + - Sets up 3 verifiers + - Sets up 2 Fee managers, wire the fee managers and verifiers + - Sets up a Reward Manager which can be used by both fee managers + */ + BaseTest.setUp(); + + s_verifierProxy2 = new DestinationVerifierProxy(); + s_verifierProxy3 = new DestinationVerifierProxy(); + + s_verifier2 = new DestinationVerifier(address(s_verifierProxy2)); + s_verifier3 = new DestinationVerifier(address(s_verifierProxy3)); + + s_verifierProxy2.setVerifier(address(s_verifier2)); + s_verifierProxy3.setVerifier(address(s_verifier3)); + + feeManager2 = new DestinationFeeManager( + address(link), + address(native), + address(s_verifier), + address(rewardManager) + ); + + s_verifier.setFeeManager(address(feeManager)); + s_verifier2.setFeeManager(address(feeManager)); + s_verifier3.setFeeManager(address(feeManager2)); + + // this is already set in the base contract + // feeManager.addVerifier(address(s_verifier)); + feeManager.addVerifier(address(s_verifier2)); + feeManager2.addVerifier(address(s_verifier3)); + + rewardManager.addFeeManager(address(feeManager)); + rewardManager.addFeeManager(address(feeManager2)); + + //mint some tokens to the user + link.mint(USER, DEFAULT_LINK_MINT_QUANTITY); + native.mint(USER, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(USER, DEFAULT_NATIVE_MINT_QUANTITY); + + //mint some link tokens to the feeManager pool + link.mint(address(feeManager), DEFAULT_REPORT_LINK_FEE); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierInterfacesTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierInterfacesTest.t.sol new file mode 100644 index 0000000000..d4772ba185 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierInterfacesTest.t.sol @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {Test} from "forge-std/Test.sol"; +import {VerifierWithFeeManager} from "./BaseDestinationVerifierTest.t.sol"; +import {DestinationVerifier} from "../../../v0.4.0/DestinationVerifier.sol"; +import {DestinationVerifierProxy} from "../../../v0.4.0/DestinationVerifierProxy.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; +import {IDestinationFeeManager} from "../../../v0.4.0/interfaces/IDestinationFeeManager.sol"; +import {IDestinationRewardManager} from "../../../v0.4.0/interfaces/IDestinationRewardManager.sol"; +import {IDestinationVerifierProxy} from "../../../v0.4.0/interfaces/IDestinationVerifierProxy.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {BaseTest} from "./BaseDestinationVerifierTest.t.sol"; +import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC20.sol"; + +/* +This test checks the interfaces of destination verifier matches the expectations. +The code here comes from this example: + +https://docs.chain.link/chainlink-automation/guides/streams-lookup + +*/ + +// Custom interfaces for IVerifierProxy and IFeeManager +interface IVerifierProxy { + /** + * @notice Verifies that the data encoded has been signed. + * correctly by routing to the correct verifier, and bills the user if applicable. + * @param payload The encoded data to be verified, including the signed + * report. + * @param parameterPayload Fee metadata for billing. For the current implementation this is just the abi-encoded fee token ERC-20 address. + * @return verifierResponse The encoded report from the verifier. + */ + function verify( + bytes calldata payload, + bytes calldata parameterPayload + ) external payable returns (bytes memory verifierResponse); + + function s_feeManager() external view returns (IDestinationFeeManager); +} + +interface IFeeManager { + /** + * @notice Calculates the fee and reward associated with verifying a report, including discounts for subscribers. + * This function assesses the fee and reward for report verification, applying a discount for recognized subscriber addresses. + * @param subscriber The address attempting to verify the report. A discount is applied if this address + * is recognized as a subscriber. + * @param unverifiedReport The report data awaiting verification. The content of this report is used to + * determine the base fee and reward, before considering subscriber discounts. + * @param quoteAddress The payment token address used for quoting fees and rewards. + * @return fee The fee assessed for verifying the report, with subscriber discounts applied where applicable. + * @return reward The reward allocated to the caller for successfully verifying the report. + * @return totalDiscount The total discount amount deducted from the fee for subscribers. + */ + function getFeeAndReward( + address subscriber, + bytes memory unverifiedReport, + address quoteAddress + ) external returns (Common.Asset memory, Common.Asset memory, uint256); + + function i_linkAddress() external view returns (address); + + function i_nativeAddress() external view returns (address); + + function i_rewardManager() external view returns (address); +} + +//Tests +// https://docs.chain.link/chainlink-automation/guides/streams-lookup +contract VerifierInterfacesTest is VerifierWithFeeManager { + address internal constant DEFAULT_RECIPIENT_1 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_1")))); + + IVerifierProxy public verifier; + V3Report internal s_testReport; + + address public FEE_ADDRESS; + string public constant DATASTREAMS_FEEDLABEL = "feedIDs"; + string public constant DATASTREAMS_QUERYLABEL = "timestamp"; + int192 public last_retrieved_price; + bytes internal signedReport; + bytes32[3] internal s_reportContext; + uint8 MINIMAL_FAULT_TOLERANCE = 2; + + function setUp() public virtual override { + VerifierWithFeeManager.setUp(); + s_reportContext[0] = bytes32(abi.encode(uint32(5), uint8(1))); + Signer[] memory signers = _getSigners(MAX_ORACLES); + + s_testReport = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + address[] memory signerAddrs = _getSignerAddresses(signers); + Common.AddressAndWeight[] memory weights = new Common.AddressAndWeight[](1); + weights[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, ONE_PERCENT * 100); + s_verifier.setConfig(signerAddrs, MINIMAL_FAULT_TOLERANCE, weights); + signedReport = _generateV3EncodedBlob(s_testReport, s_reportContext, signers); + + verifier = IVerifierProxy(address(s_verifierProxy)); + } + + function test_DestinationContractInterfaces() public { + bytes memory unverifiedReport = signedReport; + + (, bytes memory reportData) = abi.decode(unverifiedReport, (bytes32[3], bytes)); + + // Report verification fees + IFeeManager feeManager = IFeeManager(address(verifier.s_feeManager())); + IDestinationRewardManager rewardManager = IDestinationRewardManager(address(feeManager.i_rewardManager())); + + address feeTokenAddress = feeManager.i_linkAddress(); + (Common.Asset memory fee, , ) = feeManager.getFeeAndReward(address(this), reportData, feeTokenAddress); + + // Approve rewardManager to spend this contract's balance in fees + _approveLink(address(rewardManager), fee.amount, USER); + _verify(unverifiedReport, address(feeTokenAddress), 0, USER); + + assertEq(link.balanceOf(USER), DEFAULT_LINK_MINT_QUANTITY - fee.amount); + assertEq(link.balanceOf(address(rewardManager)), fee.amount); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierProxyTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierProxyTest.t.sol new file mode 100644 index 0000000000..c93c9dc6d9 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierProxyTest.t.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest} from "./BaseDestinationVerifierTest.t.sol"; +import {DestinationVerifierProxy} from "../../../v0.4.0/DestinationVerifierProxy.sol"; +import {DestinationVerifier} from "../../../v0.4.0/DestinationVerifier.sol"; +import {DestinationFeeManager} from "../../../v0.4.0/DestinationFeeManager.sol"; +import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; + +contract DestinationVerifierProxyInitializeVerifierTest is BaseTest { + function test_setVerifierCalledByNoOwner() public { + address STRANGER = address(999); + changePrank(STRANGER); + vm.expectRevert(bytes("Only callable by owner")); + s_verifierProxy.setVerifier(address(s_verifier)); + } + + function test_setVerifierWhichDoesntHonourInterface() public { + vm.expectRevert(abi.encodeWithSelector(DestinationVerifierProxy.VerifierInvalid.selector, address(rewardManager))); + s_verifierProxy.setVerifier(address(rewardManager)); + } + + function test_setVerifierOk() public { + s_verifierProxy.setVerifier(address(s_verifier)); + assertEq(s_verifierProxy.s_feeManager(), s_verifier.s_feeManager()); + assertEq(s_verifierProxy.s_accessController(), s_verifier.s_accessController()); + } + + function test_correctlySetsTheOwner() public { + DestinationVerifierProxy proxy = new DestinationVerifierProxy(); + assertEq(proxy.owner(), ADMIN); + } + + function test_correctlySetsVersion() public view { + string memory version = s_verifierProxy.typeAndVersion(); + assertEq(version, "DestinationVerifierProxy 1.0.0"); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierRemoveLatestConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierRemoveLatestConfigTest.t.sol new file mode 100644 index 0000000000..6309efc995 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierRemoveLatestConfigTest.t.sol @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest} from "./BaseDestinationVerifierTest.t.sol"; +import {DestinationVerifier} from "../../../v0.4.0/DestinationVerifier.sol"; +import {DestinationRewardManager} from "../../../v0.4.0/DestinationRewardManager.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract DestinationVerifierSetConfigTest is BaseTest { + bytes32[3] internal s_reportContext; + V3Report internal s_testReport; + + function setUp() public virtual override { + BaseTest.setUp(); + s_reportContext[0] = bytes32(abi.encode(uint32(5), uint8(1))); + } + + function test_removeLatestConfigWhenNoConfigShouldFail() public { + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.DonConfigDoesNotExist.selector)); + s_verifier.removeLatestConfig(); + } + + function test_removeLatestConfig() public { + /* + This test sets two Configs: Config A and Config B. + - it removes and readds config B multiple times while trying Config A verifications + */ + Signer[] memory signers = _getSigners(MAX_ORACLES); + + uint8 MINIMAL_FAULT_TOLERANCE = 2; + BaseTest.Signer[] memory signersA = new BaseTest.Signer[](7); + signersA[0] = signers[0]; + signersA[1] = signers[1]; + signersA[2] = signers[2]; + signersA[3] = signers[3]; + signersA[4] = signers[4]; + signersA[5] = signers[5]; + signersA[6] = signers[6]; + + // ConfigA + address[] memory signersAddrA = _getSignerAddresses(signersA); + s_verifier.setConfig(signersAddrA, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + vm.warp(block.timestamp + 10); + V3Report memory s_testReportA = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + vm.warp(block.timestamp + 100); + // Config B + BaseTest.Signer[] memory signersB = new BaseTest.Signer[](7); + // signers in ConfigA + signersB[0] = signers[8]; + signersB[1] = signers[9]; + signersB[2] = signers[10]; + signersB[3] = signers[11]; + signersB[4] = signers[12]; + signersB[5] = signers[13]; + signersB[6] = signers[14]; + address[] memory signersAddrsB = _getSignerAddresses(signersB); + s_verifier.setConfig(signersAddrsB, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + V3Report memory s_testReportB = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + BaseTest.Signer[] memory reportSignersA = new BaseTest.Signer[](3); + reportSignersA[0] = signers[0]; + reportSignersA[1] = signers[1]; + reportSignersA[2] = signers[2]; + + BaseTest.Signer[] memory reportSignersB = new BaseTest.Signer[](3); + reportSignersB[0] = signers[8]; + reportSignersB[1] = signers[9]; + reportSignersB[2] = signers[10]; + + bytes memory signedReportA = _generateV3EncodedBlob(s_testReportA, s_reportContext, reportSignersA); + bytes memory signedReportB = _generateV3EncodedBlob(s_testReportB, s_reportContext, reportSignersB); + + // verifying should work + s_verifierProxy.verify(signedReportA, abi.encode(native)); + s_verifierProxy.verify(signedReportB, abi.encode(native)); + + s_verifier.removeLatestConfig(); + + // this should remove the latest config, so ConfigA should be able to verify reports still + s_verifierProxy.verify(signedReportA, abi.encode(native)); + // this report cannot be verified any longer because ConfigB is not there + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReportB, abi.encode(native)); + + // since ConfigB is removed we should be able to set it again with no errors + s_verifier.setConfig(signersAddrsB, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + // we should be able to remove ConfigB + s_verifier.removeLatestConfig(); + // removing configA + s_verifier.removeLatestConfig(); + + // verifigny should fail + // verifying should work + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReportA, abi.encode(native)); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReportB, abi.encode(native)); + + // removing again should fail. no other configs exist + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.DonConfigDoesNotExist.selector)); + s_verifier.removeLatestConfig(); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetAccessControllerTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetAccessControllerTest.t.sol new file mode 100644 index 0000000000..d40b674f23 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetAccessControllerTest.t.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest} from "./BaseDestinationVerifierTest.t.sol"; + +contract DestinationVerifierSetAccessControllerTest is BaseTest { + event AccessControllerSet(address oldAccessController, address newAccessController); + + function test_revertsIfCalledByNonOwner() public { + vm.expectRevert("Only callable by owner"); + + changePrank(USER); + s_verifier.setAccessController(ACCESS_CONTROLLER_ADDRESS); + } + + function test_successfullySetsNewAccessController() public { + s_verifier.setAccessController(ACCESS_CONTROLLER_ADDRESS); + address ac = s_verifier.s_accessController(); + assertEq(ac, ACCESS_CONTROLLER_ADDRESS); + } + + function test_successfullySetsNewAccessControllerIsEmpty() public { + s_verifier.setAccessController(address(0)); + address ac = s_verifier.s_accessController(); + assertEq(ac, address(0)); + } + + function test_emitsTheCorrectEvent() public { + vm.expectEmit(true, false, false, false); + emit AccessControllerSet(address(0), ACCESS_CONTROLLER_ADDRESS); + s_verifier.setAccessController(ACCESS_CONTROLLER_ADDRESS); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetConfigTest.t.sol new file mode 100644 index 0000000000..f6e5fd1f21 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetConfigTest.t.sol @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest} from "./BaseDestinationVerifierTest.t.sol"; +import {DestinationVerifier} from "../../../v0.4.0/DestinationVerifier.sol"; +import {DestinationRewardManager} from "../../../v0.4.0/DestinationRewardManager.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract DestinationVerifierSetConfigTest is BaseTest { + function setUp() public virtual override { + BaseTest.setUp(); + } + + function test_revertsIfCalledByNonOwner() public { + vm.expectRevert("Only callable by owner"); + Signer[] memory signers = _getSigners(MAX_ORACLES); + changePrank(USER); + s_verifier.setConfig(_getSignerAddresses(signers), FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + } + + function test_revertsIfSetWithTooManySigners() public { + address[] memory signers = new address[](MAX_ORACLES + 1); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.ExcessSigners.selector, signers.length, MAX_ORACLES)); + s_verifier.setConfig(signers, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + } + + function test_revertsIfFaultToleranceIsZero() public { + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.FaultToleranceMustBePositive.selector)); + Signer[] memory signers = _getSigners(MAX_ORACLES); + s_verifier.setConfig(_getSignerAddresses(signers), 0, new Common.AddressAndWeight[](0)); + } + + function test_revertsIfNotEnoughSigners() public { + address[] memory signers = new address[](2); + signers[0] = address(1000); + signers[1] = address(1001); + + vm.expectRevert( + abi.encodeWithSelector(DestinationVerifier.InsufficientSigners.selector, signers.length, FAULT_TOLERANCE * 3 + 1) + ); + s_verifier.setConfig(signers, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + } + + function test_revertsIfDuplicateSigners() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + signerAddrs[0] = signerAddrs[1]; + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.NonUniqueSignatures.selector)); + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + } + + function test_revertsIfSignerContainsZeroAddress() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + signerAddrs[0] = address(0); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.ZeroAddress.selector)); + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + } + + function test_donConfigIdIsSameForSignersInDifferentOrder() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + + bytes24 expectedDonConfigId = _donConfigIdFromConfigData(signerAddrs, FAULT_TOLERANCE); + + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + address temp = signerAddrs[0]; + signerAddrs[0] = signerAddrs[1]; + signerAddrs[1] = temp; + + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.DonConfigAlreadyExists.selector, expectedDonConfigId)); + + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + } + + function test_NoDonConfigAlreadyExists() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + // testing adding same set of Signers but different FAULT_TOLERENCE does not result in DonConfigAlreadyExists revert + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE - 1, new Common.AddressAndWeight[](0)); + + // testing adding a different set of Signers with same FAULT_TOLERENCE does not result in DonConfigAlreadyExists revert + address[] memory signerAddrsMinusOne = new address[](signerAddrs.length - 1); + for (uint256 i = 0; i < signerAddrs.length - 1; i++) { + signerAddrsMinusOne[i] = signerAddrs[i]; + } + s_verifier.setConfig(signerAddrsMinusOne, FAULT_TOLERANCE - 1, new Common.AddressAndWeight[](0)); + } + + function test_addressesAndWeightsDoNotProduceSideEffectsInDonConfigIds() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + bytes24 expectedDonConfigId = _donConfigIdFromConfigData(signerAddrs, FAULT_TOLERANCE); + + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.DonConfigAlreadyExists.selector, expectedDonConfigId)); + + // Same call to setConfig with different addressAndWeights do not entail a new DonConfigID + // Resulting in a DonConfigAlreadyExists error + Common.AddressAndWeight[] memory weights = new Common.AddressAndWeight[](1); + weights[0] = Common.AddressAndWeight(signers[0].signerAddress, 1); + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, weights); + } + + function test_setConfigActiveUnknownDonConfigId() public { + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.DonConfigDoesNotExist.selector)); + s_verifier.setConfigActive(3, true); + } + + function test_setConfigWithActivationTime() public { + // simple case setting a config with specific activation time + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + uint32 activationTime = 10; + s_verifier.setConfigWithActivationTime( + signerAddrs, + FAULT_TOLERANCE, + new Common.AddressAndWeight[](0), + activationTime + ); + } + + function test_setConfigWithActivationTimeNoFutureTimeShouldFail() public { + // calling setConfigWithActivationTime with a future timestamp should fail + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + uint32 activationTime = uint32(block.timestamp) + 100; + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadActivationTime.selector)); + s_verifier.setConfigWithActivationTime( + signerAddrs, + FAULT_TOLERANCE, + new Common.AddressAndWeight[](0), + activationTime + ); + } + + function test_setConfigWithActivationTimeEarlierThanLatestConfigShouldFail() public { + // setting a config older than the latest current config should fail + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + uint32 oldActivationTime = uint32(block.timestamp) - 1; + // sets a config with timestamp = block.timestamp + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + // setting a config with ealier timestamp retuls in failure + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadActivationTime.selector)); + s_verifier.setConfigWithActivationTime( + signerAddrs, + FAULT_TOLERANCE - 1, + new Common.AddressAndWeight[](0), + oldActivationTime + ); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetFeeManagerTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetFeeManagerTest.t.sol new file mode 100644 index 0000000000..fdf75d6845 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetFeeManagerTest.t.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest} from "./BaseDestinationVerifierTest.t.sol"; +import {DestinationVerifier} from "../../../v0.4.0/DestinationVerifier.sol"; + +contract VerifierSetAccessControllerTest is BaseTest { + event FeeManagerSet(address oldFeeManager, address newFeeManager); + + function test_revertsIfCalledByNonOwner() public { + vm.expectRevert("Only callable by owner"); + changePrank(USER); + s_verifier.setFeeManager(address(feeManager)); + } + + function test_successfullySetsNewFeeManager() public { + vm.expectEmit(true, false, false, false); + emit FeeManagerSet(address(0), ACCESS_CONTROLLER_ADDRESS); + s_verifier.setFeeManager(address(feeManager)); + address ac = s_verifier.s_feeManager(); + assertEq(ac, address(feeManager)); + } + + function test_setFeeManagerWhichDoesntHonourInterface() public { + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.FeeManagerInvalid.selector)); + s_verifier.setFeeManager(address(rewardManager)); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTest.t.sol new file mode 100644 index 0000000000..dd157d2a47 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTest.t.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest} from "./BaseDestinationVerifierTest.t.sol"; +import {DestinationVerifier} from "../../../v0.4.0/DestinationVerifier.sol"; + +contract DestinationVerifierConstructorTest is BaseTest { + bytes32[3] internal s_reportContext; + + function test_revertsIfInitializedWithEmptyVerifierProxy() public { + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.ZeroAddress.selector)); + new DestinationVerifier(address(0)); + } + + function test_typeAndVersion() public { + DestinationVerifier v = new DestinationVerifier(address(s_verifierProxy)); + assertEq(v.owner(), ADMIN); + string memory typeAndVersion = s_verifier.typeAndVersion(); + assertEq(typeAndVersion, "DestinationVerifier 1.0.0"); + } + + function test_falseIfIsNotCorrectInterface() public view { + bool isInterface = s_verifier.supportsInterface(bytes4("abcd")); + assertEq(isInterface, false); + } + + function test_trueIfIsCorrectInterface() public view { + bool isInterface = s_verifier.supportsInterface(DestinationVerifier.verify.selector); + assertEq(isInterface, true); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestBillingReport.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestBillingReport.t.sol new file mode 100644 index 0000000000..574e169cf2 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestBillingReport.t.sol @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {VerifierWithFeeManager} from "./BaseDestinationVerifierTest.t.sol"; +import {DestinationVerifier} from "../../../v0.4.0/DestinationVerifier.sol"; +import {DestinationVerifierProxy} from "../../../v0.4.0/DestinationVerifierProxy.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract VerifierBillingTests is VerifierWithFeeManager { + bytes32[3] internal s_reportContext; + V3Report internal s_testReportThree; + + function setUp() public virtual override { + VerifierWithFeeManager.setUp(); + s_reportContext[0] = bytes32(abi.encode(uint32(5), uint8(1))); + s_testReportThree = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + } + + function test_verifyWithLinkV3Report() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + Common.AddressAndWeight[] memory weights = new Common.AddressAndWeight[](0); + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, weights); + bytes memory signedReport = _generateV3EncodedBlob(s_testReportThree, s_reportContext, signers); + bytes32 expectedDonConfigId = _donConfigIdFromConfigData(signerAddrs, FAULT_TOLERANCE); + + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + _verify(signedReport, address(link), 0, USER); + assertEq(link.balanceOf(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + + // internal state checks + assertEq(feeManager.s_linkDeficit(expectedDonConfigId), 0); + assertEq(rewardManager.s_totalRewardRecipientFees(expectedDonConfigId), DEFAULT_REPORT_LINK_FEE); + assertEq(link.balanceOf(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + } + + function test_verifyWithNativeERC20() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + Common.AddressAndWeight[] memory weights = new Common.AddressAndWeight[](1); + weights[0] = Common.AddressAndWeight(signerAddrs[0], ONE_PERCENT * 100); + + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, weights); + bytes memory signedReport = _generateV3EncodedBlob( + s_testReportThree, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + _approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + _verify(signedReport, address(native), 0, USER); + assertEq(native.balanceOf(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + + assertEq(link.balanceOf(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + } + + function test_verifyWithNativeUnwrapped() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + Common.AddressAndWeight[] memory weights = new Common.AddressAndWeight[](0); + + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, weights); + bytes memory signedReport = _generateV3EncodedBlob( + s_testReportThree, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + _verify(signedReport, address(native), DEFAULT_REPORT_NATIVE_FEE, USER); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + assertEq(address(feeManager).balance, 0); + } + + function test_verifyWithNativeUnwrappedReturnsChange() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + Common.AddressAndWeight[] memory weights = new Common.AddressAndWeight[](0); + + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, weights); + bytes memory signedReport = _generateV3EncodedBlob( + s_testReportThree, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + + _verify(signedReport, address(native), DEFAULT_REPORT_NATIVE_FEE * 2, USER); + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + assertEq(address(feeManager).balance, 0); + } +} + +contract DestinationVerifierBulkVerifyBillingReport is VerifierWithFeeManager { + uint256 internal constant NUMBERS_OF_REPORTS = 5; + + bytes32[3] internal s_reportContext; + + function setUp() public virtual override { + VerifierWithFeeManager.setUp(); + // setting a DonConfig we can reuse in the rest of tests + s_reportContext[0] = bytes32(abi.encode(uint32(5), uint8(1))); + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + Common.AddressAndWeight[] memory weights = new Common.AddressAndWeight[](0); + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, weights); + } + + function test_verifyWithBulkLink() public { + bytes memory signedReport = _generateV3EncodedBlob( + _generateV3Report(), + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedReports = new bytes[](NUMBERS_OF_REPORTS); + for (uint256 i = 0; i < NUMBERS_OF_REPORTS; i++) { + signedReports[i] = signedReport; + } + + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE * NUMBERS_OF_REPORTS, USER); + + _verifyBulk(signedReports, address(link), 0, USER); + + assertEq(link.balanceOf(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE * NUMBERS_OF_REPORTS); + assertEq(link.balanceOf(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBERS_OF_REPORTS); + } + + function test_verifyWithBulkNative() public { + bytes memory signedReport = _generateV3EncodedBlob( + _generateV3Report(), + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedReports = new bytes[](NUMBERS_OF_REPORTS); + for (uint256 i = 0; i < NUMBERS_OF_REPORTS; i++) { + signedReports[i] = signedReport; + } + + _approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * NUMBERS_OF_REPORTS, USER); + _verifyBulk(signedReports, address(native), 0, USER); + assertEq(native.balanceOf(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * NUMBERS_OF_REPORTS); + } + + function test_verifyWithBulkNativeUnwrapped() public { + bytes memory signedReport = _generateV3EncodedBlob( + _generateV3Report(), + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedReports = new bytes[](NUMBERS_OF_REPORTS); + for (uint256 i; i < NUMBERS_OF_REPORTS; i++) { + signedReports[i] = signedReport; + } + + _verifyBulk(signedReports, address(native), 200 * DEFAULT_REPORT_NATIVE_FEE * NUMBERS_OF_REPORTS, USER); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * 5); + assertEq(address(feeManager).balance, 0); + } + + function test_verifyWithBulkNativeUnwrappedReturnsChange() public { + bytes memory signedReport = _generateV3EncodedBlob( + _generateV3Report(), + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedReports = new bytes[](NUMBERS_OF_REPORTS); + for (uint256 i = 0; i < NUMBERS_OF_REPORTS; i++) { + signedReports[i] = signedReport; + } + + _verifyBulk(signedReports, address(native), DEFAULT_REPORT_NATIVE_FEE * (NUMBERS_OF_REPORTS * 2), USER); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * NUMBERS_OF_REPORTS); + assertEq(address(feeManager).balance, 0); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestRewards.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestRewards.t.sol new file mode 100644 index 0000000000..8ca954b8ca --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestRewards.t.sol @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {VerifierWithFeeManager} from "./BaseDestinationVerifierTest.t.sol"; +import {DestinationVerifier} from "../../../v0.4.0/DestinationVerifier.sol"; +import {DestinationVerifierProxy} from "../../../v0.4.0/DestinationVerifierProxy.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract VerifierBillingTests is VerifierWithFeeManager { + uint8 MINIMAL_FAULT_TOLERANCE = 2; + address internal constant DEFAULT_RECIPIENT_1 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_1")))); + address internal constant DEFAULT_RECIPIENT_2 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_2")))); + address internal constant DEFAULT_RECIPIENT_3 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_3")))); + address internal constant DEFAULT_RECIPIENT_4 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_4")))); + address internal constant DEFAULT_RECIPIENT_5 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_5")))); + address internal constant DEFAULT_RECIPIENT_6 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_6")))); + address internal constant DEFAULT_RECIPIENT_7 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_7")))); + + function payRecipients(bytes32 poolId, address[] memory recipients, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //pay the recipients + rewardManager.payRecipients(poolId, recipients); + + //change back to the original address + changePrank(originalAddr); + } + + bytes32[3] internal s_reportContext; + V3Report internal s_testReport; + + function setUp() public virtual override { + VerifierWithFeeManager.setUp(); + s_reportContext[0] = bytes32(abi.encode(uint32(5), uint8(1))); + s_testReport = generateReportAtTimestamp(block.timestamp); + } + + function generateReportAtTimestamp(uint256 timestamp) public pure returns (V3Report memory) { + return + V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + // ask michael about this expires at, is it usually set at what blocks + expiresAt: uint32(timestamp) + 500, + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + } + + function getRecipientAndWeightsGroup2() public pure returns (Common.AddressAndWeight[] memory, address[] memory) { + address[] memory recipients = new address[](4); + recipients[0] = DEFAULT_RECIPIENT_4; + recipients[1] = DEFAULT_RECIPIENT_5; + recipients[2] = DEFAULT_RECIPIENT_6; + recipients[3] = DEFAULT_RECIPIENT_7; + + Common.AddressAndWeight[] memory weights = new Common.AddressAndWeight[](4); + //init each recipient with even weights. 2500 = 25% of pool + weights[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, POOL_SCALAR / 4); + weights[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, POOL_SCALAR / 4); + weights[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, POOL_SCALAR / 4); + weights[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, POOL_SCALAR / 4); + return (weights, recipients); + } + + function getRecipientAndWeightsGroup1() public pure returns (Common.AddressAndWeight[] memory, address[] memory) { + address[] memory recipients = new address[](4); + recipients[0] = DEFAULT_RECIPIENT_1; + recipients[1] = DEFAULT_RECIPIENT_2; + recipients[2] = DEFAULT_RECIPIENT_3; + recipients[3] = DEFAULT_RECIPIENT_4; + + Common.AddressAndWeight[] memory weights = new Common.AddressAndWeight[](4); + //init each recipient with even weights. 2500 = 25% of pool + weights[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, POOL_SCALAR / 4); + weights[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, POOL_SCALAR / 4); + weights[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, POOL_SCALAR / 4); + weights[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, POOL_SCALAR / 4); + return (weights, recipients); + } + + function test_rewardsAreDistributedAccordingToWeights() public { + /* + Simple test verifying that rewards are distributed according to address and weights + associated to the DonConfig used to verify the report + */ + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + Common.AddressAndWeight[] memory weights = new Common.AddressAndWeight[](1); + weights[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, ONE_PERCENT * 100); + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, weights); + bytes memory signedReport = _generateV3EncodedBlob(s_testReport, s_reportContext, signers); + bytes32 expectedDonConfigId = _donConfigIdFromConfigData(signerAddrs, FAULT_TOLERANCE); + + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + _verify(signedReport, address(link), 0, USER); + assertEq(link.balanceOf(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + + // internal state checks + assertEq(feeManager.s_linkDeficit(expectedDonConfigId), 0); + assertEq(rewardManager.s_totalRewardRecipientFees(expectedDonConfigId), DEFAULT_REPORT_LINK_FEE); + assertEq(link.balanceOf(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + // check the recipients are paid according to weights + address[] memory recipients = new address[](1); + recipients[0] = DEFAULT_RECIPIENT_1; + payRecipients(expectedDonConfigId, recipients, ADMIN); + assertEq(link.balanceOf(recipients[0]), DEFAULT_REPORT_LINK_FEE); + assertEq(link.balanceOf(address(rewardManager)), 0); + } + + function test_rewardsAreDistributedAccordingToWeightsMultipleWeigths() public { + /* + Rewards are distributed according to AddressAndWeight's + associated to the DonConfig used to verify the report: + - multiple recipients + - multiple verifications + */ + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + (Common.AddressAndWeight[] memory weights, address[] memory recipients) = getRecipientAndWeightsGroup1(); + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, weights); + + bytes memory signedReport = _generateV3EncodedBlob(s_testReport, s_reportContext, signers); + bytes32 expectedDonConfigId = _donConfigIdFromConfigData(signerAddrs, FAULT_TOLERANCE); + + uint256 number_of_reports_verified = 10; + + for (uint256 i = 0; i < number_of_reports_verified; i++) { + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + _verify(signedReport, address(link), 0, USER); + } + + uint256 expected_pool_amount = DEFAULT_REPORT_LINK_FEE * number_of_reports_verified; + + //each recipient should receive 1/4 of the pool + uint256 expectedRecipientAmount = expected_pool_amount / 4; + + payRecipients(expectedDonConfigId, recipients, ADMIN); + for (uint256 i = 0; i < recipients.length; i++) { + // checking each recipient got rewards as set by the weights + assertEq(link.balanceOf(recipients[i]), expectedRecipientAmount); + } + // checking nothing left in reward manager + assertEq(link.balanceOf(address(rewardManager)), 0); + } + + function test_rewardsAreDistributedAccordingToWeightsUsingHistoricalConfigs() public { + /* + Verifies that reports verified with historical give rewards according to the verifying config AddressAndWeight. + - Sets two Configs: ConfigA and ConfigB, These two Configs have different Recipient and Weights + - Verifies a couple reports with each config + - Pays recipients + - Asserts expected rewards for each recipient + */ + + Signer[] memory signers = _getSigners(10); + address[] memory signerAddrs = _getSignerAddresses(signers); + + (Common.AddressAndWeight[] memory weights, address[] memory recipients) = getRecipientAndWeightsGroup1(); + + // Create ConfigA + s_verifier.setConfig(signerAddrs, MINIMAL_FAULT_TOLERANCE, weights); + vm.warp(block.timestamp + 100); + + V3Report memory testReportAtT1 = generateReportAtTimestamp(block.timestamp); + bytes memory signedReportT1 = _generateV3EncodedBlob(testReportAtT1, s_reportContext, signers); + bytes32 expectedDonConfigIdA = _donConfigIdFromConfigData(signerAddrs, MINIMAL_FAULT_TOLERANCE); + + uint256 number_of_reports_verified = 2; + + // advancing the blocktimestamp so we can test verifying with configs + vm.warp(block.timestamp + 100); + + Signer[] memory signers2 = _getSigners(12); + address[] memory signerAddrs2 = _getSignerAddresses(signers2); + (Common.AddressAndWeight[] memory weights2, address[] memory recipients2) = getRecipientAndWeightsGroup2(); + + // Create ConfigB + s_verifier.setConfig(signerAddrs2, MINIMAL_FAULT_TOLERANCE, weights2); + bytes32 expectedDonConfigIdB = _donConfigIdFromConfigData(signerAddrs2, MINIMAL_FAULT_TOLERANCE); + + V3Report memory testReportAtT2 = generateReportAtTimestamp(block.timestamp); + + // verifiying using ConfigA (report with Old timestamp) + for (uint256 i = 0; i < number_of_reports_verified; i++) { + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + _verify(signedReportT1, address(link), 0, USER); + } + + // verifying using ConfigB (report with new timestamp) + for (uint256 i = 0; i < number_of_reports_verified; i++) { + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + _verify(_generateV3EncodedBlob(testReportAtT2, s_reportContext, signers2), address(link), 0, USER); + } + + uint256 expected_pool_amount = DEFAULT_REPORT_LINK_FEE * number_of_reports_verified; + assertEq(rewardManager.s_totalRewardRecipientFees(expectedDonConfigIdA), expected_pool_amount); + assertEq(rewardManager.s_totalRewardRecipientFees(expectedDonConfigIdB), expected_pool_amount); + + // check the recipients are paid according to weights + payRecipients(expectedDonConfigIdA, recipients, ADMIN); + + for (uint256 i = 0; i < recipients.length; i++) { + // //each recipient should receive 1/4 of the pool + assertEq(link.balanceOf(recipients[i]), expected_pool_amount / 4); + } + + payRecipients(expectedDonConfigIdB, recipients2, ADMIN); + + for (uint256 i = 1; i < recipients2.length; i++) { + // //each recipient should receive 1/4 of the pool + assertEq(link.balanceOf(recipients2[i]), expected_pool_amount / 4); + } + + // this recipient was part of the two config weights + assertEq(link.balanceOf(recipients2[0]), (expected_pool_amount / 4) * 2); + assertEq(link.balanceOf(address(rewardManager)), 0); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestRewardsMultiVefifierFeeManager.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestRewardsMultiVefifierFeeManager.t.sol new file mode 100644 index 0000000000..6a90cbf373 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestRewardsMultiVefifierFeeManager.t.sol @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {MultipleVerifierWithMultipleFeeManagers} from "./BaseDestinationVerifierTest.t.sol"; +import {DestinationVerifier} from "../../../v0.4.0/DestinationVerifier.sol"; +import {DestinationVerifierProxy} from "../../../v0.4.0/DestinationVerifierProxy.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract MultiVerifierBillingTests is MultipleVerifierWithMultipleFeeManagers { + uint8 MINIMAL_FAULT_TOLERANCE = 2; + address internal constant DEFAULT_RECIPIENT_1 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_1")))); + address internal constant DEFAULT_RECIPIENT_2 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_2")))); + address internal constant DEFAULT_RECIPIENT_3 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_3")))); + address internal constant DEFAULT_RECIPIENT_4 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_4")))); + address internal constant DEFAULT_RECIPIENT_5 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_5")))); + address internal constant DEFAULT_RECIPIENT_6 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_6")))); + address internal constant DEFAULT_RECIPIENT_7 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_7")))); + + bytes32[3] internal s_reportContext; + V3Report internal s_testReport; + + function setUp() public virtual override { + MultipleVerifierWithMultipleFeeManagers.setUp(); + s_reportContext[0] = bytes32(abi.encode(uint32(5), uint8(1))); + s_testReport = generateReportAtTimestamp(block.timestamp); + } + + function _verify( + DestinationVerifierProxy proxy, + bytes memory payload, + address feeAddress, + uint256 wrappedNativeValue, + address sender + ) internal { + address originalAddr = msg.sender; + changePrank(sender); + + proxy.verify{value: wrappedNativeValue}(payload, abi.encode(feeAddress)); + + changePrank(originalAddr); + } + + function generateReportAtTimestamp(uint256 timestamp) public pure returns (V3Report memory) { + return + V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + // ask michael about this expires at, is it usually set at what blocks + expiresAt: uint32(timestamp) + 500, + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + } + + function payRecipients(bytes32 poolId, address[] memory recipients, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //pay the recipients + rewardManager.payRecipients(poolId, recipients); + + //change back to the original address + changePrank(originalAddr); + } + + function test_multipleFeeManagersAndVerifiers() public { + /* + In this test we got: + - three verifiers (verifier, verifier2, verifier3). + - two fee managers (feeManager, feeManager2) + - one reward manager + + we glue: + - feeManager is used by verifier1 and verifier2 + - feeManager is used by verifier3 + - Rewardmanager is used by feeManager and feeManager2 + + In this test we do verificatons via verifier1, verifier2 and verifier3 and check that rewards are set accordingly + + */ + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + Common.AddressAndWeight[] memory weights = new Common.AddressAndWeight[](1); + weights[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, ONE_PERCENT * 100); + + Common.AddressAndWeight[] memory weights2 = new Common.AddressAndWeight[](1); + weights2[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, ONE_PERCENT * 100); + + Common.AddressAndWeight[] memory weights3 = new Common.AddressAndWeight[](1); + weights3[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, ONE_PERCENT * 100); + + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, weights); + s_verifier2.setConfig(signerAddrs, MINIMAL_FAULT_TOLERANCE, weights2); + s_verifier3.setConfig(signerAddrs, MINIMAL_FAULT_TOLERANCE + 1, weights3); + bytes memory signedReport = _generateV3EncodedBlob(s_testReport, s_reportContext, signers); + bytes32 expectedDonConfigID = _donConfigIdFromConfigData(signerAddrs, FAULT_TOLERANCE); + bytes32 expectedDonConfigID2 = _donConfigIdFromConfigData(signerAddrs, MINIMAL_FAULT_TOLERANCE); + bytes32 expectedDonConfigID3 = _donConfigIdFromConfigData(signerAddrs, MINIMAL_FAULT_TOLERANCE + 1); + + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + _verify(s_verifierProxy, signedReport, address(link), 0, USER); + assertEq(link.balanceOf(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + + // internal state checks + assertEq(feeManager.s_linkDeficit(expectedDonConfigID), 0); + assertEq(rewardManager.s_totalRewardRecipientFees(expectedDonConfigID), DEFAULT_REPORT_LINK_FEE); + assertEq(link.balanceOf(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + // check the recipients are paid according to weights + // These rewards happened through verifier1 and feeManager1 + address[] memory recipients = new address[](1); + recipients[0] = DEFAULT_RECIPIENT_1; + payRecipients(expectedDonConfigID, recipients, ADMIN); + assertEq(link.balanceOf(recipients[0]), DEFAULT_REPORT_LINK_FEE); + assertEq(link.balanceOf(address(rewardManager)), 0); + + // these rewards happaned through verifier2 and feeManager1 + address[] memory recipients2 = new address[](1); + recipients2[0] = DEFAULT_RECIPIENT_2; + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + _verify(s_verifierProxy2, signedReport, address(link), 0, USER); + payRecipients(expectedDonConfigID2, recipients2, ADMIN); + assertEq(link.balanceOf(recipients2[0]), DEFAULT_REPORT_LINK_FEE); + assertEq(link.balanceOf(address(rewardManager)), 0); + + // these rewards happened through verifier3 and feeManager2 + address[] memory recipients3 = new address[](1); + recipients3[0] = DEFAULT_RECIPIENT_3; + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + _verify(s_verifierProxy3, signedReport, address(link), 0, USER); + payRecipients(expectedDonConfigID3, recipients3, ADMIN); + assertEq(link.balanceOf(recipients3[0]), DEFAULT_REPORT_LINK_FEE); + assertEq(link.balanceOf(address(rewardManager)), 0); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierVerifyBulkTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierVerifyBulkTest.t.sol new file mode 100644 index 0000000000..1c57295bae --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierVerifyBulkTest.t.sol @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest} from "./BaseDestinationVerifierTest.t.sol"; +import {DestinationVerifier} from "../../../v0.4.0/DestinationVerifier.sol"; +import {DestinationVerifierProxy} from "../../../v0.4.0/DestinationVerifierProxy.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract VerifierVerifyBulkTest is BaseTest { + bytes32[3] internal s_reportContext; + V3Report internal s_testReportThree; + + function setUp() public virtual override { + BaseTest.setUp(); + s_reportContext[0] = bytes32(abi.encode(uint32(5), uint8(1))); + + s_testReportThree = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + } + + function test_revertsVerifyBulkIfNoAccess() public { + vm.mockCall( + ACCESS_CONTROLLER_ADDRESS, + abi.encodeWithSelector(AccessControllerInterface.hasAccess.selector, USER), + abi.encode(false) + ); + bytes memory signedReport = _generateV3EncodedBlob( + s_testReportThree, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedReports = new bytes[](2); + signedReports[0] = signedReport; + signedReports[1] = signedReport; + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.AccessForbidden.selector)); + changePrank(USER); + s_verifier.verifyBulk(signedReports, abi.encode(native), msg.sender); + } + + function test_verifyBulkSingleCaseWithSingleConfig() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + + uint8 MINIMAL_FAULT_TOLERANCE = 2; + BaseTest.Signer[] memory signersSubset1 = new BaseTest.Signer[](7); + signersSubset1[0] = signers[0]; + signersSubset1[1] = signers[1]; + signersSubset1[2] = signers[2]; + signersSubset1[3] = signers[3]; + signersSubset1[4] = signers[4]; + signersSubset1[5] = signers[5]; + signersSubset1[6] = signers[6]; + + address[] memory signersAddrSubset1 = _getSignerAddresses(signersSubset1); + // Config1 + s_verifier.setConfig(signersAddrSubset1, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + V3Report memory report = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + BaseTest.Signer[] memory reportSigners = new BaseTest.Signer[](3); + reportSigners[0] = signers[0]; + reportSigners[1] = signers[1]; + reportSigners[2] = signers[2]; + + bytes[] memory signedReports = new bytes[](10); + + bytes memory signedReport = _generateV3EncodedBlob(report, s_reportContext, reportSigners); + + for (uint256 i = 0; i < signedReports.length; i++) { + signedReports[i] = signedReport; + } + + bytes[] memory verifierResponses = s_verifierProxy.verifyBulk(signedReports, abi.encode(native)); + + for (uint256 i = 0; i < verifierResponses.length; i++) { + bytes memory verifierResponse = verifierResponses[i]; + assertReportsEqual(verifierResponse, report); + } + } + + function test_verifyBulkWithSingleConfigOneVerifyFails() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + + uint8 MINIMAL_FAULT_TOLERANCE = 2; + BaseTest.Signer[] memory signersSubset1 = new BaseTest.Signer[](7); + signersSubset1[0] = signers[0]; + signersSubset1[1] = signers[1]; + signersSubset1[2] = signers[2]; + signersSubset1[3] = signers[3]; + signersSubset1[4] = signers[4]; + signersSubset1[5] = signers[5]; + signersSubset1[6] = signers[6]; + + address[] memory signersAddrSubset1 = _getSignerAddresses(signersSubset1); + // Config1 + s_verifier.setConfig(signersAddrSubset1, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + BaseTest.Signer[] memory reportSigners = new BaseTest.Signer[](3); + reportSigners[0] = signers[0]; + reportSigners[1] = signers[1]; + reportSigners[2] = signers[2]; + + bytes[] memory signedReports = new bytes[](11); + bytes memory signedReport = _generateV3EncodedBlob(s_testReportThree, s_reportContext, reportSigners); + + for (uint256 i = 0; i < 10; i++) { + signedReports[i] = signedReport; + } + + // Making the last report in this batch not verifiable + BaseTest.Signer[] memory reportSigners2 = new BaseTest.Signer[](3); + reportSigners2[0] = signers[30]; + reportSigners2[1] = signers[29]; + reportSigners2[2] = signers[28]; + signedReports[10] = _generateV3EncodedBlob(s_testReportThree, s_reportContext, reportSigners2); + + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verifyBulk(signedReports, abi.encode(native)); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierVerifyTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierVerifyTest.t.sol new file mode 100644 index 0000000000..658bf4f127 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierVerifyTest.t.sol @@ -0,0 +1,711 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest} from "./BaseDestinationVerifierTest.t.sol"; +import {DestinationVerifier} from "../../../v0.4.0/DestinationVerifier.sol"; +import {DestinationVerifierProxy} from "../../../v0.4.0/DestinationVerifierProxy.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract VerifierVerifyTest is BaseTest { + bytes32[3] internal s_reportContext; + V3Report internal s_testReportThree; + + function setUp() public virtual override { + BaseTest.setUp(); + + s_testReportThree = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + } + + function test_verifyReport() public { + // Simple use case just setting a config and verifying a report + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + s_reportContext[0] = bytes32(abi.encode(uint32(5), uint8(1))); + + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + bytes memory signedReport = _generateV3EncodedBlob(s_testReportThree, s_reportContext, signers); + + bytes memory verifierResponse = s_verifierProxy.verify(signedReport, abi.encode(native)); + assertReportsEqual(verifierResponse, s_testReportThree); + } + + function test_verifyTooglingActiveFlagsDonConfigs() public { + // sets config + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + s_reportContext[0] = bytes32(abi.encode(uint32(5), uint8(1))); + bytes memory signedReport = _generateV3EncodedBlob(s_testReportThree, s_reportContext, signers); + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + // verifies report + bytes memory verifierResponse = s_verifierProxy.verify(signedReport, abi.encode(native)); + assertReportsEqual(verifierResponse, s_testReportThree); + + // test verifying via a config that is deactivated + s_verifier.setConfigActive(0, false); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + verifierResponse = s_verifierProxy.verify(signedReport, abi.encode(native)); + + // test verifying via a reactivated config + s_verifier.setConfigActive(0, true); + verifierResponse = s_verifierProxy.verify(signedReport, abi.encode(native)); + assertReportsEqual(verifierResponse, s_testReportThree); + } + + function test_failToVerifyReportIfNotEnoughSigners() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + + uint8 MINIMAL_FAULT_TOLERANCE = 2; + BaseTest.Signer[] memory signersSubset1 = new BaseTest.Signer[](7); + signersSubset1[0] = signers[0]; + signersSubset1[1] = signers[1]; + signersSubset1[2] = signers[2]; + signersSubset1[3] = signers[3]; + signersSubset1[4] = signers[4]; + signersSubset1[5] = signers[5]; + signersSubset1[6] = signers[6]; + address[] memory signersAddrSubset1 = _getSignerAddresses(signersSubset1); + s_verifier.setConfig(signersAddrSubset1, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + // only one signer, signers < MINIMAL_FAULT_TOLERANCE + BaseTest.Signer[] memory signersSubset2 = new BaseTest.Signer[](1); + signersSubset2[0] = signers[4]; + + bytes memory signedReport = _generateV3EncodedBlob(s_testReportThree, s_reportContext, signersSubset2); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReport, abi.encode(native)); + } + + function test_failToVerifyReportIfNoSigners() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + + uint8 MINIMAL_FAULT_TOLERANCE = 2; + BaseTest.Signer[] memory signersSubset1 = new BaseTest.Signer[](7); + signersSubset1[0] = signers[0]; + signersSubset1[1] = signers[1]; + signersSubset1[2] = signers[2]; + signersSubset1[3] = signers[3]; + signersSubset1[4] = signers[4]; + signersSubset1[5] = signers[5]; + signersSubset1[6] = signers[6]; + address[] memory signersAddrSubset1 = _getSignerAddresses(signersSubset1); + s_verifier.setConfig(signersAddrSubset1, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + // No signers for this report + BaseTest.Signer[] memory signersSubset2 = new BaseTest.Signer[](0); + bytes memory signedReport = _generateV3EncodedBlob(s_testReportThree, s_reportContext, signersSubset2); + + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.NoSigners.selector)); + s_verifierProxy.verify(signedReport, abi.encode(native)); + } + + function test_failToVerifyReportIfDupSigners() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + + uint8 MINIMAL_FAULT_TOLERANCE = 2; + BaseTest.Signer[] memory signersSubset1 = new BaseTest.Signer[](7); + signersSubset1[0] = signers[0]; + signersSubset1[1] = signers[1]; + signersSubset1[2] = signers[2]; + signersSubset1[3] = signers[3]; + signersSubset1[4] = signers[4]; + signersSubset1[5] = signers[5]; + signersSubset1[6] = signers[6]; + address[] memory signersAddrSubset1 = _getSignerAddresses(signersSubset1); + s_verifier.setConfig(signersAddrSubset1, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + // One signer is repeated + BaseTest.Signer[] memory signersSubset2 = new BaseTest.Signer[](4); + signersSubset2[0] = signers[0]; + signersSubset2[1] = signers[1]; + // repeated signers + signersSubset2[2] = signers[2]; + signersSubset2[3] = signers[2]; + + bytes memory signedReport = _generateV3EncodedBlob(s_testReportThree, s_reportContext, signersSubset2); + + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReport, abi.encode(native)); + } + + function test_failToVerifyReportIfSignerNotInConfig() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + + uint8 MINIMAL_FAULT_TOLERANCE = 2; + BaseTest.Signer[] memory signersSubset1 = new BaseTest.Signer[](7); + signersSubset1[0] = signers[0]; + signersSubset1[1] = signers[1]; + signersSubset1[2] = signers[2]; + signersSubset1[3] = signers[3]; + signersSubset1[4] = signers[4]; + signersSubset1[5] = signers[5]; + signersSubset1[6] = signers[6]; + address[] memory signersAddrSubset1 = _getSignerAddresses(signersSubset1); + s_verifier.setConfig(signersAddrSubset1, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + // one report whose signer is not in the config + BaseTest.Signer[] memory reportSigners = new BaseTest.Signer[](4); + // these signers are part ofm the config + reportSigners[0] = signers[4]; + reportSigners[1] = signers[5]; + reportSigners[2] = signers[6]; + // this single signer is not in the config + reportSigners[3] = signers[7]; + + bytes memory signedReport = _generateV3EncodedBlob(s_testReportThree, s_reportContext, reportSigners); + + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReport, abi.encode(native)); + } + + function test_canVerifyOlderV3ReportsWithOlderConfigs() public { + /* + This test is checking we can use historical Configs to verify reports: + - DonConfigA has signers {A, B, C, E} is set at time T1 + - DonConfigB has signers {A, B, C, D} is set at time T2 + - checks we can verify a report with {B, C, D} signers (via DonConfigB) + - checks we can verify a report with {B, C, E} signers and timestamp below T2 (via DonConfigA historical config) + - checks we can't verify a report with {B, C, E} signers and timestamp above T2 (it gets verivied via DonConfigB) + - sets DonConfigA as deactivated + - checks we can't verify a report with {B, C, E} signers and timestamp below T2 (via DonConfigA) + */ + Signer[] memory signers = _getSigners(MAX_ORACLES); + + uint8 MINIMAL_FAULT_TOLERANCE = 2; + BaseTest.Signer[] memory signersSubset1 = new BaseTest.Signer[](7); + signersSubset1[0] = signers[0]; + signersSubset1[1] = signers[1]; + signersSubset1[2] = signers[2]; + signersSubset1[3] = signers[3]; + signersSubset1[4] = signers[4]; + signersSubset1[5] = signers[5]; + signersSubset1[6] = signers[6]; + + address[] memory signersAddrSubset1 = _getSignerAddresses(signersSubset1); + // Config1 + s_verifier.setConfig(signersAddrSubset1, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + BaseTest.Signer[] memory signersSubset2 = new BaseTest.Signer[](7); + signersSubset2[0] = signers[0]; + signersSubset2[1] = signers[1]; + signersSubset2[2] = signers[2]; + signersSubset2[3] = signers[3]; + signersSubset2[4] = signers[4]; + signersSubset2[5] = signers[5]; + signersSubset2[6] = signers[29]; + address[] memory signersAddrSubset2 = _getSignerAddresses(signersSubset2); + + V3Report memory reportAtSetConfig1Timestmap = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + vm.warp(block.timestamp + 100); + + // Config2 + s_verifier.setConfig(signersAddrSubset2, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + V3Report memory reportAtSetConfig2Timestmap = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + BaseTest.Signer[] memory reportSigners = new BaseTest.Signer[](5); + reportSigners[0] = signers[0]; + reportSigners[1] = signers[1]; + reportSigners[2] = signers[2]; + reportSigners[3] = signers[3]; + reportSigners[4] = signers[29]; + + bytes memory signedReport = _generateV3EncodedBlob(reportAtSetConfig2Timestmap, s_reportContext, reportSigners); + + // this report is verified via Config2 + bytes memory verifierResponse = s_verifierProxy.verify(signedReport, abi.encode(native)); + assertReportsEqual(verifierResponse, reportAtSetConfig2Timestmap); + + BaseTest.Signer[] memory reportSigners2 = new BaseTest.Signer[](5); + reportSigners2[0] = signers[0]; + reportSigners2[1] = signers[1]; + reportSigners2[2] = signers[2]; + reportSigners2[3] = signers[3]; + reportSigners2[4] = signers[6]; + + bytes memory signedReport2 = _generateV3EncodedBlob(reportAtSetConfig1Timestmap, s_reportContext, reportSigners2); + + // this report is verified via Config1 (using a historical config) + bytes memory verifierResponse2 = s_verifierProxy.verify(signedReport2, abi.encode(native)); + assertReportsEqual(verifierResponse2, reportAtSetConfig1Timestmap); + + // same report with same signers but with a higher timestamp gets verified via Config2 + // which means verification fails + bytes memory signedReport3 = _generateV3EncodedBlob(reportAtSetConfig2Timestmap, s_reportContext, reportSigners2); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReport3, abi.encode(native)); + + // deactivating Config1 and trying a reverifications ends in failure + s_verifier.setConfigActive(0, false); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReport2, abi.encode(native)); + } + + function test_revertsVerifyIfNoAccess() public { + vm.mockCall( + ACCESS_CONTROLLER_ADDRESS, + abi.encodeWithSelector(AccessControllerInterface.hasAccess.selector, USER), + abi.encode(false) + ); + bytes memory signedReport = _generateV3EncodedBlob( + s_testReportThree, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.AccessForbidden.selector)); + + changePrank(USER); + s_verifier.verify(signedReport, abi.encode(native), msg.sender); + } + + function test_canVerifyNewerReportsWithNewerConfigs() public { + /* + This test is checking that we use prefer verifiying via newer configs instead of old ones. + - DonConfigA has signers {A, B, C, E} is set at time T1 + - DonConfigB has signers {F, G, H, I} is set at time T2 + - DonConfigC has signers {J, K, L, M } is set at time T3 + - checks we can verify a report with {K, L, M} signers (via DonConfigC) + */ + Signer[] memory signers = _getSigners(MAX_ORACLES); + + uint8 MINIMAL_FAULT_TOLERANCE = 2; + BaseTest.Signer[] memory signersSubset1 = new BaseTest.Signer[](7); + signersSubset1[0] = signers[0]; + signersSubset1[1] = signers[1]; + signersSubset1[2] = signers[2]; + signersSubset1[3] = signers[3]; + signersSubset1[4] = signers[4]; + signersSubset1[5] = signers[5]; + signersSubset1[6] = signers[6]; + + address[] memory signersAddrSubset1 = _getSignerAddresses(signersSubset1); + // Config1 + s_verifier.setConfig(signersAddrSubset1, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + BaseTest.Signer[] memory signersSubset2 = new BaseTest.Signer[](7); + signersSubset2[0] = signers[7]; + signersSubset2[1] = signers[8]; + signersSubset2[2] = signers[9]; + signersSubset2[3] = signers[10]; + signersSubset2[4] = signers[11]; + signersSubset2[5] = signers[12]; + signersSubset2[6] = signers[13]; + + address[] memory signersAddrSubset2 = _getSignerAddresses(signersSubset2); + // Config2 + s_verifier.setConfig(signersAddrSubset2, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + BaseTest.Signer[] memory signersSubset3 = new BaseTest.Signer[](7); + signersSubset3[0] = signers[30]; + signersSubset3[1] = signers[29]; + signersSubset3[2] = signers[28]; + signersSubset3[3] = signers[27]; + signersSubset3[4] = signers[26]; + signersSubset3[5] = signers[25]; + signersSubset3[6] = signers[24]; + + address[] memory signersAddrSubset3 = _getSignerAddresses(signersSubset3); + // Config3 + s_verifier.setConfig(signersAddrSubset3, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + V3Report memory report = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + BaseTest.Signer[] memory reportSigners = new BaseTest.Signer[](3); + reportSigners[0] = signers[30]; + reportSigners[1] = signers[29]; + reportSigners[2] = signers[28]; + + bytes memory signedReport = _generateV3EncodedBlob(report, s_reportContext, reportSigners); + + s_verifierProxy.verify(signedReport, abi.encode(native)); + } + + function test_rollingOutConfiguration() public { + /* + This test is checking that we can roll out to a new DON without downtime using a transition configuration + - DonConfigA has signers {A, B, C} is set at time T1 + - DonConfigB (transition config) has signers {A, B, C, D, E, F} is set at time T2 + - DonConfigC has signers {D, E, F} is set at time T3 + + - checks we can verify a report with {A, B, C} signers (via DonConfigA) at time between T1 and T2 + - checks we can verify a report with {A, B, C} signers (via DonConfigB) at time between T2 and T3 + - checks we can verify a report with {D, E, F} signers (via DonConfigB) at time between T2 and T3 + - checks we can verify a report with {D, E, F} signers (via DonConfigC) at time > T3 + - checks we can't verify a report with {A, B, C} signers (via DonConfigC) and timestamp >T3 at time > T3 + - checks we can verify a report with {A, B, C} signers (via DonConfigC) and timestamp between T2 and T3 at time > T3 (historical check) + + */ + + Signer[] memory signers = _getSigners(MAX_ORACLES); + + uint8 MINIMAL_FAULT_TOLERANCE = 2; + BaseTest.Signer[] memory signersSubset1 = new BaseTest.Signer[](7); + signersSubset1[0] = signers[0]; + signersSubset1[1] = signers[1]; + signersSubset1[2] = signers[2]; + signersSubset1[3] = signers[3]; + signersSubset1[4] = signers[4]; + signersSubset1[5] = signers[5]; + signersSubset1[6] = signers[6]; + + // ConfigA + address[] memory signersAddrSubset1 = _getSignerAddresses(signersSubset1); + s_verifier.setConfig(signersAddrSubset1, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + V3Report memory reportT1 = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + BaseTest.Signer[] memory reportSignersConfigA = new BaseTest.Signer[](3); + reportSignersConfigA[0] = signers[0]; + reportSignersConfigA[1] = signers[1]; + reportSignersConfigA[2] = signers[2]; + + // just testing ConfigA + bytes memory signedReport = _generateV3EncodedBlob(reportT1, s_reportContext, reportSignersConfigA); + s_verifierProxy.verify(signedReport, abi.encode(native)); + + vm.warp(block.timestamp + 100); + + BaseTest.Signer[] memory signersSuperset = new BaseTest.Signer[](14); + // signers in ConfigA + signersSuperset[0] = signers[0]; + signersSuperset[1] = signers[1]; + signersSuperset[2] = signers[2]; + signersSuperset[3] = signers[3]; + signersSuperset[4] = signers[4]; + signersSuperset[5] = signers[5]; + signersSuperset[6] = signers[6]; + // new signers + signersSuperset[7] = signers[7]; + signersSuperset[8] = signers[8]; + signersSuperset[9] = signers[9]; + signersSuperset[10] = signers[10]; + signersSuperset[11] = signers[11]; + signersSuperset[12] = signers[12]; + signersSuperset[13] = signers[13]; + + BaseTest.Signer[] memory reportSignersConfigC = new BaseTest.Signer[](3); + reportSignersConfigC[0] = signers[7]; + reportSignersConfigC[1] = signers[8]; + reportSignersConfigC[2] = signers[9]; + + // ConfigB (transition Config) + address[] memory signersAddrsSuperset = _getSignerAddresses(signersSuperset); + s_verifier.setConfig(signersAddrsSuperset, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + V3Report memory reportT2 = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + // testing we can verify a fresh (block timestamp) report with ConfigA signers. This should use ConfigB + signedReport = _generateV3EncodedBlob(reportT2, s_reportContext, reportSignersConfigA); + s_verifierProxy.verify(signedReport, abi.encode(native)); + + // testing we can verify an old ( non fresh block timestamp) report with ConfigA signers. This should use ConfigA + signedReport = _generateV3EncodedBlob(reportT1, s_reportContext, reportSignersConfigA); + s_verifierProxy.verify(signedReport, abi.encode(native)); + // deactivating to make sure we are really verifiying via ConfigA + s_verifier.setConfigActive(0, false); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReport, abi.encode(native)); + s_verifier.setConfigActive(0, true); + + // testing we can verify a fresh (block timestamp) report with the new signers. This should use ConfigB + signedReport = _generateV3EncodedBlob(reportT2, s_reportContext, reportSignersConfigC); + s_verifierProxy.verify(signedReport, abi.encode(native)); + + vm.warp(block.timestamp + 100); + + // Adding ConfigC + BaseTest.Signer[] memory signersSubset2 = new BaseTest.Signer[](7); + signersSubset2[0] = signers[7]; + signersSubset2[1] = signers[8]; + signersSubset2[2] = signers[9]; + signersSubset2[3] = signers[10]; + signersSubset2[4] = signers[11]; + signersSubset2[5] = signers[12]; + signersSubset2[6] = signers[13]; + address[] memory signersAddrsSubset2 = _getSignerAddresses(signersSubset2); + s_verifier.setConfig(signersAddrsSubset2, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + V3Report memory reportT3 = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + // testing we can verify reports with ConfigC signers + signedReport = _generateV3EncodedBlob(reportT3, s_reportContext, reportSignersConfigC); + s_verifierProxy.verify(signedReport, abi.encode(native)); + + // testing an old report (block timestamp) with ConfigC signers should verify via ConfigB + signedReport = _generateV3EncodedBlob(reportT2, s_reportContext, reportSignersConfigC); + s_verifierProxy.verify(signedReport, abi.encode(native)); + // deactivating to make sure we are really verifiying via ConfigB + s_verifier.setConfigActive(1, false); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReport, abi.encode(native)); + s_verifier.setConfigActive(1, true); + + // testing a recent report with ConfigA signers should not verify + signedReport = _generateV3EncodedBlob(reportT3, s_reportContext, reportSignersConfigA); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReport, abi.encode(native)); + + // testing an old report (block timestamp) with ConfigA signers should verify via ConfigB + signedReport = _generateV3EncodedBlob(reportT2, s_reportContext, reportSignersConfigA); + s_verifierProxy.verify(signedReport, abi.encode(native)); + // deactivating to make sure we are really verifiying via ConfigB + s_verifier.setConfigActive(1, false); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReport, abi.encode(native)); + s_verifier.setConfigActive(1, true); + + // testing an old report (block timestamp) with ConfigA signers should verify via ConfigA + signedReport = _generateV3EncodedBlob(reportT1, s_reportContext, reportSignersConfigA); + s_verifierProxy.verify(signedReport, abi.encode(native)); + // deactivating to make sure we are really verifiying via ConfigB + s_verifier.setConfigActive(0, false); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReport, abi.encode(native)); + s_verifier.setConfigActive(0, true); + } + + function test_verifyFailsWhenReportIsOlderThanConfig() public { + /* + - SetConfig A at time T0 + - SetConfig B at time T1 + - tries verifing report issued at blocktimestmap < T0 + + this test is failing: ToDo Ask Michael + */ + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + s_reportContext[0] = bytes32(abi.encode(uint32(5), uint8(1))); + + vm.warp(block.timestamp + 100); + + V3Report memory reportAtTMinus100 = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp - 100), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + vm.warp(block.timestamp + 100); + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE - 1, new Common.AddressAndWeight[](0)); + + bytes memory signedReport = _generateV3EncodedBlob(reportAtTMinus100, s_reportContext, signers); + + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedReport, abi.encode(native)); + } + + function test_scenarioRollingNewChainWithHistoricConfigs() public { + /* + This test is checking that we can roll out in a new network and set historic configurations : + - Stars with a chain at blocktimestamp 1000 + - SetConfigA with teimstamp 100 + - SetConfigB with timesmtap 200 + - SetConfigC with timestamp current + - tries verifying reports for all the configs + */ + + vm.warp(block.timestamp + 1000); + + Signer[] memory signers = _getSigners(MAX_ORACLES); + + uint8 MINIMAL_FAULT_TOLERANCE = 2; + BaseTest.Signer[] memory signersA = new BaseTest.Signer[](7); + signersA[0] = signers[0]; + signersA[1] = signers[1]; + signersA[2] = signers[2]; + signersA[3] = signers[3]; + signersA[4] = signers[4]; + signersA[5] = signers[5]; + signersA[6] = signers[6]; + + // ConfigA (historical config) + uint32 configATimestmap = 100; + address[] memory signersAddrA = _getSignerAddresses(signersA); + s_verifier.setConfigWithActivationTime( + signersAddrA, + MINIMAL_FAULT_TOLERANCE, + new Common.AddressAndWeight[](0), + configATimestmap + ); + + // ConfigB (historical config) + uint32 configBTimestmap = 200; + // Config B + BaseTest.Signer[] memory signersB = new BaseTest.Signer[](7); + // signers in ConfigA + signersB[0] = signers[8]; + signersB[1] = signers[9]; + signersB[2] = signers[10]; + signersB[3] = signers[11]; + signersB[4] = signers[12]; + signersB[5] = signers[13]; + signersB[6] = signers[14]; + address[] memory signersAddrsB = _getSignerAddresses(signersB); + s_verifier.setConfigWithActivationTime( + signersAddrsB, + MINIMAL_FAULT_TOLERANCE, + new Common.AddressAndWeight[](0), + configBTimestmap + ); + + // ConfigC (config at current timestamp) + // BaseTest.Signer[] memory signersC = new BaseTest.Signer[](7); + // signers in ConfigA + signersB[6] = signers[15]; + address[] memory signersAddrsC = _getSignerAddresses(signersB); + s_verifier.setConfig(signersAddrsC, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + + vm.warp(block.timestamp + 10); + + // historical report + V3Report memory s_testReportA = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(101), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp + 1000), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + // historical report + V3Report memory s_testReportB = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(201), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp + 1000), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + // report at recent timestamp + V3Report memory s_testReportC = V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp + 1000), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + + BaseTest.Signer[] memory reportSignersA = new BaseTest.Signer[](3); + reportSignersA[0] = signers[0]; + reportSignersA[1] = signers[1]; + reportSignersA[2] = signers[2]; + + BaseTest.Signer[] memory reportSignersB = new BaseTest.Signer[](3); + reportSignersB[0] = signers[8]; + reportSignersB[1] = signers[9]; + reportSignersB[2] = signers[14]; + + BaseTest.Signer[] memory reportSignersC = new BaseTest.Signer[](3); + reportSignersC[0] = signers[15]; + reportSignersC[1] = signers[13]; + reportSignersC[2] = signers[12]; + + bytes memory signedReportA = _generateV3EncodedBlob(s_testReportA, s_reportContext, reportSignersA); + bytes memory signedReportB = _generateV3EncodedBlob(s_testReportB, s_reportContext, reportSignersB); + bytes memory signedReportC = _generateV3EncodedBlob(s_testReportC, s_reportContext, reportSignersC); + + // verifying historical reports + s_verifierProxy.verify(signedReportA, abi.encode(native)); + s_verifierProxy.verify(signedReportB, abi.encode(native)); + // verifiying a current report + s_verifierProxy.verify(signedReportC, abi.encode(native)); + + // current report verified by historical report fails + bytes memory signedNewReportWithOldSignatures = _generateV3EncodedBlob( + s_testReportC, + s_reportContext, + reportSignersA + ); + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadVerification.selector)); + s_verifierProxy.verify(signedNewReportWithOldSignatures, abi.encode(native)); + } +} diff --git a/core/gethwrappers/llo-feeds/generated/destination_fee_manager/destination_fee_manager.go b/core/gethwrappers/llo-feeds/generated/destination_fee_manager/destination_fee_manager.go new file mode 100644 index 0000000000..b87cf068ac --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/destination_fee_manager/destination_fee_manager.go @@ -0,0 +1,1790 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package destination_fee_manager + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommonAddressAndWeight struct { + Addr common.Address + Weight uint64 +} + +type CommonAsset struct { + AssetAddress common.Address + Amount *big.Int +} + +type IDestinationRewardManagerFeePayment struct { + PoolId [32]byte + Amount *big.Int +} + +var DestinationFeeManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_linkAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_nativeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verifierAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ExpiredReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDiscount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidQuote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReceivingAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSurcharge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolIdMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroDeficit\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.Asset\",\"name\":\"fee\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.Asset\",\"name\":\"reward\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"appliedDiscount\",\"type\":\"uint256\"}],\"name\":\"DiscountApplied\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIDestinationRewardManager.FeePayment[]\",\"name\":\"rewards\",\"type\":\"tuple[]\"}],\"name\":\"InsufficientLink\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"}],\"name\":\"LinkDeficitCleared\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newSurcharge\",\"type\":\"uint64\"}],\"name\":\"NativeSurchargeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"SubscriberDiscountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"addVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"quoteAddress\",\"type\":\"address\"}],\"name\":\"getFeeAndReward\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_linkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_nativeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_rewardManager\",\"outputs\":[{\"internalType\":\"contractIDestinationRewardManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"payLinkDeficit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"recipient\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFee\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"poolIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFeeBulk\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"removeVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_linkDeficit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_nativeSurcharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_subscriberDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_verifierAddressList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setFeeRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"surcharge\",\"type\":\"uint64\"}],\"name\":\"setNativeSurcharge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rewardManagerAddress\",\"type\":\"address\"}],\"name\":\"setRewardManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"updateSubscriberDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b5060405162003c3238038062003c328339810160408190526200003491620002af565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620001e7565b5050506001600160a01b0384161580620000df57506001600160a01b038316155b80620000f257506001600160a01b038216155b806200010557506001600160a01b038116155b15620001245760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03848116608081905284821660a05283821660008181526004602081905260409182902080546001600160a01b03199081169094179055600580549093169486169485179092555163095ea7b360e01b81529081019290925260001960248301529063095ea7b3906044016020604051808303816000875af1158015620001b6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001dc91906200030c565b505050505062000337565b336001600160a01b03821603620002415760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620002aa57600080fd5b919050565b60008060008060808587031215620002c657600080fd5b620002d18562000292565b9350620002e16020860162000292565b9250620002f16040860162000292565b9150620003016060860162000292565b905092959194509250565b6000602082840312156200031f57600080fd5b815180151581146200033057600080fd5b9392505050565b60805160a051613850620003e26000396000818161033b0152818161151c0152818161177a015281816117d101528181611a7e0152818161248e01526125370152600081816105430152818161098e01528181610a9801528181610e9b015281816111f4015281816114c50152818161165c0152818161179f015281816118280152818161196d015281816119da01528181611a1a01528181612109015261262b01526138506000f3fe60806040526004361061018b5760003560e01c806386968cfd116100d6578063d09dc3391161007f578063ea4b861b11610059578063ea4b861b14610531578063f2fde38b14610565578063f65df9621461058557600080fd5b8063d09dc33914610491578063e03dab1a146104a6578063e389d9a41461051157600080fd5b80639000b3d6116100b05780639000b3d614610431578063ca2dfd0a14610451578063ce7817d11461047157600080fd5b806386968cfd146103b557806387d6d843146103c85780638da5cb5b1461040657600080fd5b80633690750911610138578063638786681161011257806363878668146103295780637700feeb1461035d57806379ba5097146103a057600080fd5b806336907509146102a45780633aa5ac07146102b7578063505380941461030957600080fd5b8063181f5a7711610169578063181f5a77146102225780631d4d84a21461026e57806332f5f7461461028e57600080fd5b8063013f542b1461019057806301ffc9a7146101d0578063153ee55414610200575b600080fd5b34801561019c57600080fd5b506101bd6101ab366004612d9a565b60036020526000908152604090205481565b6040519081526020015b60405180910390f35b3480156101dc57600080fd5b506101f06101eb366004612db3565b6105a5565b60405190151581526020016101c7565b34801561020c57600080fd5b5061022061021b366004612e27565b6108ea565b005b34801561022e57600080fd5b50604080518082018252601b81527f44657374696e6174696f6e4665654d616e6167657220312e302e300000000000602082015290516101c79190612e68565b34801561027a57600080fd5b50610220610289366004612edf565b610b0b565b34801561029a57600080fd5b506101bd60065481565b6102206102b2366004613036565b610c9f565b3480156102c357600080fd5b506005546102e49073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c7565b34801561031557600080fd5b50610220610324366004613156565b610f50565b34801561033557600080fd5b506102e47f000000000000000000000000000000000000000000000000000000000000000081565b34801561036957600080fd5b506102e4610378366004612e27565b60046020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103ac57600080fd5b50610220610fea565b6102206103c3366004613171565b6110ec565b3480156103d457600080fd5b506101bd6103e33660046131fd565b600260209081526000938452604080852082529284528284209052825290205481565b34801561041257600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166102e4565b34801561043d57600080fd5b5061022061044c366004612e27565b61126d565b34801561045d57600080fd5b5061022061046c366004612e27565b611370565b34801561047d57600080fd5b5061022061048c366004613234565b61146f565b34801561049d57600080fd5b506101bd61162b565b3480156104b257600080fd5b506104c66104c1366004613313565b6116e1565b60408051845173ffffffffffffffffffffffffffffffffffffffff9081168252602095860151868301528451169181019190915292909101516060830152608082015260a0016101c7565b34801561051d57600080fd5b5061022061052c366004612d9a565b611ae0565b34801561053d57600080fd5b506102e47f000000000000000000000000000000000000000000000000000000000000000081565b34801561057157600080fd5b50610220610580366004612e27565b611c95565b34801561059157600080fd5b506102206105a036600461336c565b611ca9565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe03dab1a00000000000000000000000000000000000000000000000000000000148061063857507fffffffff0000000000000000000000000000000000000000000000000000000082167f5053809400000000000000000000000000000000000000000000000000000000145b8061068457507fffffffff0000000000000000000000000000000000000000000000000000000082167fce7817d100000000000000000000000000000000000000000000000000000000145b806106d057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1d4d84a200000000000000000000000000000000000000000000000000000000145b8061071c57507fffffffff0000000000000000000000000000000000000000000000000000000082167fd09dc33900000000000000000000000000000000000000000000000000000000145b8061076857507fffffffff0000000000000000000000000000000000000000000000000000000082167fe389d9a400000000000000000000000000000000000000000000000000000000145b806107b457507fffffffff0000000000000000000000000000000000000000000000000000000082167f9000b3d600000000000000000000000000000000000000000000000000000000145b8061080057507fffffffff0000000000000000000000000000000000000000000000000000000082167fca2dfd0a00000000000000000000000000000000000000000000000000000000145b8061084c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f86968cfd00000000000000000000000000000000000000000000000000000000145b8061089857507fffffffff0000000000000000000000000000000000000000000000000000000082167f3690750900000000000000000000000000000000000000000000000000000000145b806108e457507fffffffff0000000000000000000000000000000000000000000000000000000082167ff65df96200000000000000000000000000000000000000000000000000000000145b92915050565b6108f2611dbd565b73ffffffffffffffffffffffffffffffffffffffff811661093f576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600060248201527f00000000000000000000000000000000000000000000000000000000000000009091169063095ea7b3906044016020604051808303816000875af11580156109d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fd91906133eb565b50600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8381169182179092556040517f095ea7b300000000000000000000000000000000000000000000000000000000815260048101919091527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248201527f00000000000000000000000000000000000000000000000000000000000000009091169063095ea7b3906044016020604051808303816000875af1158015610ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0791906133eb565b5050565b610b13611dbd565b73ffffffffffffffffffffffffffffffffffffffff8316610be85760008273ffffffffffffffffffffffffffffffffffffffff168277ffffffffffffffffffffffffffffffffffffffffffffffff1660405160006040518083038185875af1925050503d8060008114610ba2576040519150601f19603f3d011682016040523d82523d6000602084013e610ba7565b606091505b5050905080610be2576040517fef2af20100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b610c2373ffffffffffffffffffffffffffffffffffffffff84168377ffffffffffffffffffffffffffffffffffffffffffffffff8416611e40565b6040805133815273ffffffffffffffffffffffffffffffffffffffff848116602083015285168183015277ffffffffffffffffffffffffffffffffffffffffffffffff8316606082015290517f7ff78a71698bdb18dcca96f52ab25e0a1b146fb6a49adf8e6845299e49021f299181900360800190a15b505050565b3360008181526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1614610cfc576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85518414610d35576040517e154a0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008467ffffffffffffffff811115610d5057610d50612f2a565b604051908082528060200260200182016040528015610d8957816020015b610d76612d0d565b815260200190600190039081610d6e5790505b5090506000806000805b88811015610f16576000801b8b8281518110610db157610db161340d565b602002602001015103610df0576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000610e248d8d86818110610e0a57610e0a61340d565b9050602002810190610e1c919061343c565b8d8d8d611f14565b9250925092508260200151600014610f025760405180608001604052808f8681518110610e5357610e5361340d565b6020026020010151815260200184815260200183815260200182815250888680610e7c906134d0565b975081518110610e8e57610e8e61340d565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1603610efb57866001019650610f02565b8560010195505b50505080610f0f906134d0565b9050610d93565b5082151580610f2457508115155b15610f3a57610f3585858585612024565b610f44565b610f44853461281e565b50505050505050505050565b610f58611dbd565b670de0b6b3a764000067ffffffffffffffff82161115610fa4576040517f05e8ac2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660068190556040519081527f08f7c0d17932ddb8523bc06754d42ff19ebc77d76a8b9bfde02c28ab1ed3d6399060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff163314611070576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3360008181526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1614611149576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600061115b8888888888611f14565b925092509250826020015160000361117f57611177843461281e565b505050611265565b604080516001808252818301909252600091816020015b61119e612d0d565b81526020019060019003908161119657905050905060405180608001604052808b815260200185815260200184815260200183815250816000815181106111e7576111e761340d565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff160361125757610f35858260016000612024565b610f44858260006001612024565b505050505050565b611275611dbd565b73ffffffffffffffffffffffffffffffffffffffff81166112c2576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600460205260409020541615611321576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600081815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b611378611dbd565b73ffffffffffffffffffffffffffffffffffffffff81166113c5576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81811660009081526004602052604090205416611423576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b611477611dbd565b670de0b6b3a764000067ffffffffffffffff821611156114c3576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561156b57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156115a2576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff848116600081815260026020908152604080832088845282528083209487168084529482529182902067ffffffffffffffff86169081905582519485529084015285927f5eba5a8afa39780f0f99b6cbeb95f3da6a7040ca00abd46bdc91a0a060134139910160405180910390a350505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156116b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116dc9190613508565b905090565b604080518082018252600080825260208083018290528351808501855282815280820183905284518086018652838152808301849052855180870190965283865291850183905292938261173488613521565b90507fffff0000000000000000000000000000000000000000000000000000000000008082169081016117cf57505073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811683527f0000000000000000000000000000000000000000000000000000000000000000168152909350915060009050611ad7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161415801561187757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614155b156118ae576040517ff861803000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008b8060200190518101906118c7919061357a565b77ffffffffffffffffffffffffffffffffffffffffffffffff91821698509116955063ffffffff169350505042821015905061192f576040517fb6c405f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808e16600090815260026020908152604080832089845282528083208f851684529091529020547f000000000000000000000000000000000000000000000000000000000000000090911687526119be6119a682670de0b6b3a76400006135e0565b6119b090866135f3565b670de0b6b3a7640000612867565b602088015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116908d1603611a4b5773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016885260208088015190890152611ac8565b600654600090611a67906119a690670de0b6b3a764000061360a565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168a529050611ac1611ab783670de0b6b3a76400006135e0565b6119b090836135f3565b60208a0152505b96995094975094955050505050505b93509350939050565b611ae8611dbd565b60008181526003602052604081205490819003611b31576040517f03aad31200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600360205260408082208290558051600180825281830190925290816020015b6040805180820190915260008082526020820152815260200190600190039081611b5657905050905060405180604001604052808481526020018377ffffffffffffffffffffffffffffffffffffffffffffffff1681525081600081518110611bc157611bc161340d565b60209081029190910101526005546040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063b0d9fa1990611c24908490309060040161367d565b600060405180830381600087803b158015611c3e57600080fd5b505af1158015611c52573d6000803e3d6000fd5b50505050827f843f0b103e50b42b08f9d30f12f961845a6d02623730872e24644899c0dd989583604051611c8891815260200190565b60405180910390a2505050565b611c9d611dbd565b611ca68161289f565b50565b3360008181526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1614801590611cf5575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611d2c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517f14060f2300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906314060f2390611d86908690869086906004016136b5565b600060405180830381600087803b158015611da057600080fd5b505af1158015611db4573d6000803e3d6000fd5b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611e3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611067565b565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c9a9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612994565b6040805180820190915260008082526020820152604080518082019091526000808252602082015260003073ffffffffffffffffffffffffffffffffffffffff851603611f8d576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611f9b888a018a613735565b915050600081611faa90613521565b905060007e010000000000000000000000000000000000000000000000000000000000007fffff00000000000000000000000000000000000000000000000000000000000083161461200557612002888a018a612e27565b90505b6120108784836116e1565b955095509550505050955095509592505050565b60008267ffffffffffffffff81111561203f5761203f612f2a565b60405190808252806020026020018201604052801561208457816020015b604080518082019091526000808252602082015281526020019060019003908161205d5790505b50905060008267ffffffffffffffff8111156120a2576120a2612f2a565b6040519080825280602002602001820160405280156120e757816020015b60408051808201909152600080825260208201528152602001906001900390816120c05790505b5090506000808080806120fa888a61360a565b905060005b81811015612449577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168b82815181106121505761215061340d565b6020026020010151602001516000015173ffffffffffffffffffffffffffffffffffffffff16036122165760405180604001604052808c83815181106121985761219861340d565b60200260200101516000015181526020018c83815181106121bb576121bb61340d565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff168152508885806121f4906134d0565b9650815181106122065761220661340d565b602002602001018190525061230b565b60405180604001604052808c83815181106122335761223361340d565b60200260200101516000015181526020018c83815181106122565761225661340d565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff1681525087848061228f906134d0565b9550815181106122a1576122a161340d565b60200260200101819052508a81815181106122be576122be61340d565b60200260200101516020015160200151866122d9919061360a565b95508a81815181106122ed576122ed61340d565b6020026020010151604001516020015185612308919061360a565b94505b8a818151811061231d5761231d61340d565b602002602001015160600151600014612439578b73ffffffffffffffffffffffffffffffffffffffff168b82815181106123595761235961340d565b6020026020010151600001517f88b15eb682210089cddf967648e2cb2a4535aeadc8f8f36050922e33c04e71258d84815181106123985761239861340d565b6020026020010151602001518e85815181106123b6576123b661340d565b6020026020010151604001518f86815181106123d4576123d461340d565b60200260200101516060015160405161243093929190835173ffffffffffffffffffffffffffffffffffffffff908116825260209485015185830152835116604082015291909201516060820152608081019190915260a00190565b60405180910390a35b612442816134d0565b90506120ff565b5060003415612517573486111561248c576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0876040518263ffffffff1660e01b81526004016000604051808303818588803b1580156124f457600080fd5b505af1158015612508573d6000803e3d6000fd5b5050505050853403905061255f565b851561255f5761255f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168d3089612aa0565b8751156125f657600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b0d9fa19898e6040518363ffffffff1660e01b81526004016125c392919061367d565b600060405180830381600087803b1580156125dd57600080fd5b505af11580156125f1573d6000803e3d6000fd5b505050505b865115612806576040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612687573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ab9190613508565b85111561277b5760005b875181101561273e578781815181106126d0576126d061340d565b60200260200101516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16600360008a848151811061270c5761270c61340d565b60209081029190910181015151825281019190915260400160002080549091019055612737816134d0565b90506126b5565b507ff52e5907b69d97c33392936c12d78b494463b78c5b72df50b4c497eee5720b678760405161276e91906137d9565b60405180910390a1612806565b6005546040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063b0d9fa19906127d3908a90309060040161367d565b600060405180830381600087803b1580156127ed57600080fd5b505af1158015612801573d6000803e3d6000fd5b505050505b6128108c8261281e565b505050505050505050505050565b8015610b075760405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610c9a573d6000803e3d6000fd5b60008215612895578161287b6001856135e0565b61288591906137ec565b61289090600161360a565b612898565b60005b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361291e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611067565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006129f6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612afe9092919063ffffffff16565b805190915015610c9a5780806020019051810190612a1491906133eb565b610c9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611067565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610be29085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611e92565b6060612b0d8484600085612b15565b949350505050565b606082471015612ba7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611067565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612bd09190613827565b60006040518083038185875af1925050503d8060008114612c0d576040519150601f19603f3d011682016040523d82523d6000602084013e612c12565b606091505b5091509150612c2387838387612c2e565b979650505050505050565b60608315612cc4578251600003612cbd5773ffffffffffffffffffffffffffffffffffffffff85163b612cbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611067565b5081612b0d565b612b0d8383815115612cd95781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110679190612e68565b604051806080016040528060008019168152602001612d556040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b8152602001612d8d6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b8152602001600081525090565b600060208284031215612dac57600080fd5b5035919050565b600060208284031215612dc557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461289857600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611ca657600080fd5b8035612e2281612df5565b919050565b600060208284031215612e3957600080fd5b813561289881612df5565b60005b83811015612e5f578181015183820152602001612e47565b50506000910152565b6020815260008251806020840152612e87816040850160208701612e44565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b77ffffffffffffffffffffffffffffffffffffffffffffffff81168114611ca657600080fd5b600080600060608486031215612ef457600080fd5b8335612eff81612df5565b92506020840135612f0f81612df5565b91506040840135612f1f81612eb9565b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612fa057612fa0612f2a565b604052919050565b60008083601f840112612fba57600080fd5b50813567ffffffffffffffff811115612fd257600080fd5b6020830191508360208260051b8501011115612fed57600080fd5b9250929050565b60008083601f84011261300657600080fd5b50813567ffffffffffffffff81111561301e57600080fd5b602083019150836020828501011115612fed57600080fd5b6000806000806000806080878903121561304f57600080fd5b863567ffffffffffffffff8082111561306757600080fd5b818901915089601f83011261307b57600080fd5b813560208282111561308f5761308f612f2a565b8160051b61309e828201612f59565b928352848101820192828101908e8511156130b857600080fd5b958301955b848710156130d6578635825295830195908301906130bd565b9b5050508a0135925050808211156130ed57600080fd5b6130f98a838b01612fa8565b9097509550604089013591508082111561311257600080fd5b5061311f89828a01612ff4565b9094509250613132905060608801612e17565b90509295509295509295565b803567ffffffffffffffff81168114612e2257600080fd5b60006020828403121561316857600080fd5b6128988261313e565b6000806000806000806080878903121561318a57600080fd5b86359550602087013567ffffffffffffffff808211156131a957600080fd5b6131b58a838b01612ff4565b909750955060408901359150808211156131ce57600080fd5b506131db89828a01612ff4565b90945092505060608701356131ef81612df5565b809150509295509295509295565b60008060006060848603121561321257600080fd5b833561321d81612df5565b9250602084013591506040840135612f1f81612df5565b6000806000806080858703121561324a57600080fd5b843561325581612df5565b935060208501359250604085013561326c81612df5565b915061327a6060860161313e565b905092959194509250565b600082601f83011261329657600080fd5b813567ffffffffffffffff8111156132b0576132b0612f2a565b6132e160207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612f59565b8181528460208386010111156132f657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561332857600080fd5b833561333381612df5565b9250602084013567ffffffffffffffff81111561334f57600080fd5b61335b86828701613285565b9250506040840135612f1f81612df5565b60008060006040848603121561338157600080fd5b83359250602084013567ffffffffffffffff808211156133a057600080fd5b818601915086601f8301126133b457600080fd5b8135818111156133c357600080fd5b8760208260061b85010111156133d857600080fd5b6020830194508093505050509250925092565b6000602082840312156133fd57600080fd5b8151801515811461289857600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261347157600080fd5b83018035915067ffffffffffffffff82111561348c57600080fd5b602001915036819003821315612fed57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613501576135016134a1565b5060010190565b60006020828403121561351a57600080fd5b5051919050565b80516020808301519190811015613560577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b805163ffffffff81168114612e2257600080fd5b60008060008060008060c0878903121561359357600080fd5b865195506135a360208801613566565b94506135b160408801613566565b935060608701516135c181612eb9565b60808801519093506135d281612eb9565b915061313260a08801613566565b818103818111156108e4576108e46134a1565b80820281158282048414176108e4576108e46134a1565b808201808211156108e4576108e46134a1565b600081518084526020808501945080840160005b838110156136725781518051885283015177ffffffffffffffffffffffffffffffffffffffffffffffff168388015260409096019590820190600101613631565b509495945050505050565b604081526000613690604083018561361d565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b8381526040602080830182905282820184905260009190859060608501845b878110156137285783356136e781612df5565b73ffffffffffffffffffffffffffffffffffffffff16825267ffffffffffffffff61371385850161313e565b168284015292840192908401906001016136d4565b5098975050505050505050565b6000806080838503121561374857600080fd5b83601f84011261375757600080fd5b6040516060810167ffffffffffffffff828210818311171561377b5761377b612f2a565b81604052829150606086018781111561379357600080fd5b865b818110156137ad578035845260209384019301613795565b50929450913591808311156137c157600080fd5b50506137cf85828601613285565b9150509250929050565b602081526000612898602083018461361d565b600082613822577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613839818460208701612e44565b919091019291505056fea164736f6c6343000813000a", +} + +var DestinationFeeManagerABI = DestinationFeeManagerMetaData.ABI + +var DestinationFeeManagerBin = DestinationFeeManagerMetaData.Bin + +func DeployDestinationFeeManager(auth *bind.TransactOpts, backend bind.ContractBackend, _linkAddress common.Address, _nativeAddress common.Address, _verifierAddress common.Address, _rewardManagerAddress common.Address) (common.Address, *types.Transaction, *DestinationFeeManager, error) { + parsed, err := DestinationFeeManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DestinationFeeManagerBin), backend, _linkAddress, _nativeAddress, _verifierAddress, _rewardManagerAddress) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &DestinationFeeManager{address: address, abi: *parsed, DestinationFeeManagerCaller: DestinationFeeManagerCaller{contract: contract}, DestinationFeeManagerTransactor: DestinationFeeManagerTransactor{contract: contract}, DestinationFeeManagerFilterer: DestinationFeeManagerFilterer{contract: contract}}, nil +} + +type DestinationFeeManager struct { + address common.Address + abi abi.ABI + DestinationFeeManagerCaller + DestinationFeeManagerTransactor + DestinationFeeManagerFilterer +} + +type DestinationFeeManagerCaller struct { + contract *bind.BoundContract +} + +type DestinationFeeManagerTransactor struct { + contract *bind.BoundContract +} + +type DestinationFeeManagerFilterer struct { + contract *bind.BoundContract +} + +type DestinationFeeManagerSession struct { + Contract *DestinationFeeManager + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type DestinationFeeManagerCallerSession struct { + Contract *DestinationFeeManagerCaller + CallOpts bind.CallOpts +} + +type DestinationFeeManagerTransactorSession struct { + Contract *DestinationFeeManagerTransactor + TransactOpts bind.TransactOpts +} + +type DestinationFeeManagerRaw struct { + Contract *DestinationFeeManager +} + +type DestinationFeeManagerCallerRaw struct { + Contract *DestinationFeeManagerCaller +} + +type DestinationFeeManagerTransactorRaw struct { + Contract *DestinationFeeManagerTransactor +} + +func NewDestinationFeeManager(address common.Address, backend bind.ContractBackend) (*DestinationFeeManager, error) { + abi, err := abi.JSON(strings.NewReader(DestinationFeeManagerABI)) + if err != nil { + return nil, err + } + contract, err := bindDestinationFeeManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &DestinationFeeManager{address: address, abi: abi, DestinationFeeManagerCaller: DestinationFeeManagerCaller{contract: contract}, DestinationFeeManagerTransactor: DestinationFeeManagerTransactor{contract: contract}, DestinationFeeManagerFilterer: DestinationFeeManagerFilterer{contract: contract}}, nil +} + +func NewDestinationFeeManagerCaller(address common.Address, caller bind.ContractCaller) (*DestinationFeeManagerCaller, error) { + contract, err := bindDestinationFeeManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &DestinationFeeManagerCaller{contract: contract}, nil +} + +func NewDestinationFeeManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*DestinationFeeManagerTransactor, error) { + contract, err := bindDestinationFeeManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &DestinationFeeManagerTransactor{contract: contract}, nil +} + +func NewDestinationFeeManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*DestinationFeeManagerFilterer, error) { + contract, err := bindDestinationFeeManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &DestinationFeeManagerFilterer{contract: contract}, nil +} + +func bindDestinationFeeManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := DestinationFeeManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_DestinationFeeManager *DestinationFeeManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DestinationFeeManager.Contract.DestinationFeeManagerCaller.contract.Call(opts, result, method, params...) +} + +func (_DestinationFeeManager *DestinationFeeManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.DestinationFeeManagerTransactor.contract.Transfer(opts) +} + +func (_DestinationFeeManager *DestinationFeeManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.DestinationFeeManagerTransactor.contract.Transact(opts, method, params...) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DestinationFeeManager.Contract.contract.Call(opts, result, method, params...) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.contract.Transfer(opts) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.contract.Transact(opts, method, params...) +} + +func (_DestinationFeeManager *DestinationFeeManagerCaller) GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quoteAddress common.Address) (CommonAsset, CommonAsset, *big.Int, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "getFeeAndReward", subscriber, report, quoteAddress) + + if err != nil { + return *new(CommonAsset), *new(CommonAsset), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(CommonAsset)).(*CommonAsset) + out1 := *abi.ConvertType(out[1], new(CommonAsset)).(*CommonAsset) + out2 := *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + + return out0, out1, out2, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) GetFeeAndReward(subscriber common.Address, report []byte, quoteAddress common.Address) (CommonAsset, CommonAsset, *big.Int, error) { + return _DestinationFeeManager.Contract.GetFeeAndReward(&_DestinationFeeManager.CallOpts, subscriber, report, quoteAddress) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) GetFeeAndReward(subscriber common.Address, report []byte, quoteAddress common.Address) (CommonAsset, CommonAsset, *big.Int, error) { + return _DestinationFeeManager.Contract.GetFeeAndReward(&_DestinationFeeManager.CallOpts, subscriber, report, quoteAddress) +} + +func (_DestinationFeeManager *DestinationFeeManagerCaller) ILinkAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "i_linkAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) ILinkAddress() (common.Address, error) { + return _DestinationFeeManager.Contract.ILinkAddress(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) ILinkAddress() (common.Address, error) { + return _DestinationFeeManager.Contract.ILinkAddress(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCaller) INativeAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "i_nativeAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) INativeAddress() (common.Address, error) { + return _DestinationFeeManager.Contract.INativeAddress(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) INativeAddress() (common.Address, error) { + return _DestinationFeeManager.Contract.INativeAddress(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCaller) IRewardManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "i_rewardManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) IRewardManager() (common.Address, error) { + return _DestinationFeeManager.Contract.IRewardManager(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) IRewardManager() (common.Address, error) { + return _DestinationFeeManager.Contract.IRewardManager(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCaller) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "linkAvailableForPayment") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) LinkAvailableForPayment() (*big.Int, error) { + return _DestinationFeeManager.Contract.LinkAvailableForPayment(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) LinkAvailableForPayment() (*big.Int, error) { + return _DestinationFeeManager.Contract.LinkAvailableForPayment(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) Owner() (common.Address, error) { + return _DestinationFeeManager.Contract.Owner(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) Owner() (common.Address, error) { + return _DestinationFeeManager.Contract.Owner(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCaller) SLinkDeficit(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "s_linkDeficit", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) SLinkDeficit(arg0 [32]byte) (*big.Int, error) { + return _DestinationFeeManager.Contract.SLinkDeficit(&_DestinationFeeManager.CallOpts, arg0) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) SLinkDeficit(arg0 [32]byte) (*big.Int, error) { + return _DestinationFeeManager.Contract.SLinkDeficit(&_DestinationFeeManager.CallOpts, arg0) +} + +func (_DestinationFeeManager *DestinationFeeManagerCaller) SNativeSurcharge(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "s_nativeSurcharge") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) SNativeSurcharge() (*big.Int, error) { + return _DestinationFeeManager.Contract.SNativeSurcharge(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) SNativeSurcharge() (*big.Int, error) { + return _DestinationFeeManager.Contract.SNativeSurcharge(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCaller) SSubscriberDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "s_subscriberDiscounts", arg0, arg1, arg2) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) SSubscriberDiscounts(arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { + return _DestinationFeeManager.Contract.SSubscriberDiscounts(&_DestinationFeeManager.CallOpts, arg0, arg1, arg2) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) SSubscriberDiscounts(arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { + return _DestinationFeeManager.Contract.SSubscriberDiscounts(&_DestinationFeeManager.CallOpts, arg0, arg1, arg2) +} + +func (_DestinationFeeManager *DestinationFeeManagerCaller) SVerifierAddressList(opts *bind.CallOpts, arg0 common.Address) (common.Address, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "s_verifierAddressList", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) SVerifierAddressList(arg0 common.Address) (common.Address, error) { + return _DestinationFeeManager.Contract.SVerifierAddressList(&_DestinationFeeManager.CallOpts, arg0) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) SVerifierAddressList(arg0 common.Address) (common.Address, error) { + return _DestinationFeeManager.Contract.SVerifierAddressList(&_DestinationFeeManager.CallOpts, arg0) +} + +func (_DestinationFeeManager *DestinationFeeManagerCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _DestinationFeeManager.Contract.SupportsInterface(&_DestinationFeeManager.CallOpts, interfaceId) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _DestinationFeeManager.Contract.SupportsInterface(&_DestinationFeeManager.CallOpts, interfaceId) +} + +func (_DestinationFeeManager *DestinationFeeManagerCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) TypeAndVersion() (string, error) { + return _DestinationFeeManager.Contract.TypeAndVersion(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) TypeAndVersion() (string, error) { + return _DestinationFeeManager.Contract.TypeAndVersion(&_DestinationFeeManager.CallOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "acceptOwnership") +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) AcceptOwnership() (*types.Transaction, error) { + return _DestinationFeeManager.Contract.AcceptOwnership(&_DestinationFeeManager.TransactOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _DestinationFeeManager.Contract.AcceptOwnership(&_DestinationFeeManager.TransactOpts) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactor) AddVerifier(opts *bind.TransactOpts, verifierAddress common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "addVerifier", verifierAddress) +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) AddVerifier(verifierAddress common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.AddVerifier(&_DestinationFeeManager.TransactOpts, verifierAddress) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) AddVerifier(verifierAddress common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.AddVerifier(&_DestinationFeeManager.TransactOpts, verifierAddress) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactor) PayLinkDeficit(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "payLinkDeficit", configDigest) +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) PayLinkDeficit(configDigest [32]byte) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.PayLinkDeficit(&_DestinationFeeManager.TransactOpts, configDigest) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) PayLinkDeficit(configDigest [32]byte) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.PayLinkDeficit(&_DestinationFeeManager.TransactOpts, configDigest) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactor) ProcessFee(opts *bind.TransactOpts, recipient [32]byte, payload []byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "processFee", recipient, payload, parameterPayload, subscriber) +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) ProcessFee(recipient [32]byte, payload []byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.ProcessFee(&_DestinationFeeManager.TransactOpts, recipient, payload, parameterPayload, subscriber) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) ProcessFee(recipient [32]byte, payload []byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.ProcessFee(&_DestinationFeeManager.TransactOpts, recipient, payload, parameterPayload, subscriber) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactor) ProcessFeeBulk(opts *bind.TransactOpts, poolIds [][32]byte, payloads [][]byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "processFeeBulk", poolIds, payloads, parameterPayload, subscriber) +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) ProcessFeeBulk(poolIds [][32]byte, payloads [][]byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.ProcessFeeBulk(&_DestinationFeeManager.TransactOpts, poolIds, payloads, parameterPayload, subscriber) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) ProcessFeeBulk(poolIds [][32]byte, payloads [][]byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.ProcessFeeBulk(&_DestinationFeeManager.TransactOpts, poolIds, payloads, parameterPayload, subscriber) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactor) RemoveVerifier(opts *bind.TransactOpts, verifierAddress common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "removeVerifier", verifierAddress) +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) RemoveVerifier(verifierAddress common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.RemoveVerifier(&_DestinationFeeManager.TransactOpts, verifierAddress) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) RemoveVerifier(verifierAddress common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.RemoveVerifier(&_DestinationFeeManager.TransactOpts, verifierAddress) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactor) SetFeeRecipients(opts *bind.TransactOpts, configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "setFeeRecipients", configDigest, rewardRecipientAndWeights) +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) SetFeeRecipients(configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.SetFeeRecipients(&_DestinationFeeManager.TransactOpts, configDigest, rewardRecipientAndWeights) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) SetFeeRecipients(configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.SetFeeRecipients(&_DestinationFeeManager.TransactOpts, configDigest, rewardRecipientAndWeights) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactor) SetNativeSurcharge(opts *bind.TransactOpts, surcharge uint64) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "setNativeSurcharge", surcharge) +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) SetNativeSurcharge(surcharge uint64) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.SetNativeSurcharge(&_DestinationFeeManager.TransactOpts, surcharge) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) SetNativeSurcharge(surcharge uint64) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.SetNativeSurcharge(&_DestinationFeeManager.TransactOpts, surcharge) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactor) SetRewardManager(opts *bind.TransactOpts, rewardManagerAddress common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "setRewardManager", rewardManagerAddress) +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) SetRewardManager(rewardManagerAddress common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.SetRewardManager(&_DestinationFeeManager.TransactOpts, rewardManagerAddress) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) SetRewardManager(rewardManagerAddress common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.SetRewardManager(&_DestinationFeeManager.TransactOpts, rewardManagerAddress) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "transferOwnership", to) +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.TransferOwnership(&_DestinationFeeManager.TransactOpts, to) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.TransferOwnership(&_DestinationFeeManager.TransactOpts, to) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactor) UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "updateSubscriberDiscount", subscriber, feedId, token, discount) +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.UpdateSubscriberDiscount(&_DestinationFeeManager.TransactOpts, subscriber, feedId, token, discount) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.UpdateSubscriberDiscount(&_DestinationFeeManager.TransactOpts, subscriber, feedId, token, discount) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactor) Withdraw(opts *bind.TransactOpts, assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "withdraw", assetAddress, recipient, quantity) +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) Withdraw(assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.Withdraw(&_DestinationFeeManager.TransactOpts, assetAddress, recipient, quantity) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) Withdraw(assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.Withdraw(&_DestinationFeeManager.TransactOpts, assetAddress, recipient, quantity) +} + +type DestinationFeeManagerDiscountAppliedIterator struct { + Event *DestinationFeeManagerDiscountApplied + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationFeeManagerDiscountAppliedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerDiscountApplied) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerDiscountApplied) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationFeeManagerDiscountAppliedIterator) Error() error { + return it.fail +} + +func (it *DestinationFeeManagerDiscountAppliedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationFeeManagerDiscountApplied struct { + ConfigDigest [32]byte + Subscriber common.Address + Fee CommonAsset + Reward CommonAsset + AppliedDiscount *big.Int + Raw types.Log +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) FilterDiscountApplied(opts *bind.FilterOpts, configDigest [][32]byte, subscriber []common.Address) (*DestinationFeeManagerDiscountAppliedIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + + logs, sub, err := _DestinationFeeManager.contract.FilterLogs(opts, "DiscountApplied", configDigestRule, subscriberRule) + if err != nil { + return nil, err + } + return &DestinationFeeManagerDiscountAppliedIterator{contract: _DestinationFeeManager.contract, event: "DiscountApplied", logs: logs, sub: sub}, nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) WatchDiscountApplied(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerDiscountApplied, configDigest [][32]byte, subscriber []common.Address) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + + logs, sub, err := _DestinationFeeManager.contract.WatchLogs(opts, "DiscountApplied", configDigestRule, subscriberRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationFeeManagerDiscountApplied) + if err := _DestinationFeeManager.contract.UnpackLog(event, "DiscountApplied", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) ParseDiscountApplied(log types.Log) (*DestinationFeeManagerDiscountApplied, error) { + event := new(DestinationFeeManagerDiscountApplied) + if err := _DestinationFeeManager.contract.UnpackLog(event, "DiscountApplied", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationFeeManagerInsufficientLinkIterator struct { + Event *DestinationFeeManagerInsufficientLink + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationFeeManagerInsufficientLinkIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerInsufficientLink) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerInsufficientLink) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationFeeManagerInsufficientLinkIterator) Error() error { + return it.fail +} + +func (it *DestinationFeeManagerInsufficientLinkIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationFeeManagerInsufficientLink struct { + Rewards []IDestinationRewardManagerFeePayment + Raw types.Log +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) FilterInsufficientLink(opts *bind.FilterOpts) (*DestinationFeeManagerInsufficientLinkIterator, error) { + + logs, sub, err := _DestinationFeeManager.contract.FilterLogs(opts, "InsufficientLink") + if err != nil { + return nil, err + } + return &DestinationFeeManagerInsufficientLinkIterator{contract: _DestinationFeeManager.contract, event: "InsufficientLink", logs: logs, sub: sub}, nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerInsufficientLink) (event.Subscription, error) { + + logs, sub, err := _DestinationFeeManager.contract.WatchLogs(opts, "InsufficientLink") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationFeeManagerInsufficientLink) + if err := _DestinationFeeManager.contract.UnpackLog(event, "InsufficientLink", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) ParseInsufficientLink(log types.Log) (*DestinationFeeManagerInsufficientLink, error) { + event := new(DestinationFeeManagerInsufficientLink) + if err := _DestinationFeeManager.contract.UnpackLog(event, "InsufficientLink", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationFeeManagerLinkDeficitClearedIterator struct { + Event *DestinationFeeManagerLinkDeficitCleared + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationFeeManagerLinkDeficitClearedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerLinkDeficitCleared) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerLinkDeficitCleared) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationFeeManagerLinkDeficitClearedIterator) Error() error { + return it.fail +} + +func (it *DestinationFeeManagerLinkDeficitClearedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationFeeManagerLinkDeficitCleared struct { + ConfigDigest [32]byte + LinkQuantity *big.Int + Raw types.Log +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) FilterLinkDeficitCleared(opts *bind.FilterOpts, configDigest [][32]byte) (*DestinationFeeManagerLinkDeficitClearedIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _DestinationFeeManager.contract.FilterLogs(opts, "LinkDeficitCleared", configDigestRule) + if err != nil { + return nil, err + } + return &DestinationFeeManagerLinkDeficitClearedIterator{contract: _DestinationFeeManager.contract, event: "LinkDeficitCleared", logs: logs, sub: sub}, nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) WatchLinkDeficitCleared(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerLinkDeficitCleared, configDigest [][32]byte) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _DestinationFeeManager.contract.WatchLogs(opts, "LinkDeficitCleared", configDigestRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationFeeManagerLinkDeficitCleared) + if err := _DestinationFeeManager.contract.UnpackLog(event, "LinkDeficitCleared", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) ParseLinkDeficitCleared(log types.Log) (*DestinationFeeManagerLinkDeficitCleared, error) { + event := new(DestinationFeeManagerLinkDeficitCleared) + if err := _DestinationFeeManager.contract.UnpackLog(event, "LinkDeficitCleared", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationFeeManagerNativeSurchargeUpdatedIterator struct { + Event *DestinationFeeManagerNativeSurchargeUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationFeeManagerNativeSurchargeUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerNativeSurchargeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerNativeSurchargeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationFeeManagerNativeSurchargeUpdatedIterator) Error() error { + return it.fail +} + +func (it *DestinationFeeManagerNativeSurchargeUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationFeeManagerNativeSurchargeUpdated struct { + NewSurcharge uint64 + Raw types.Log +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) FilterNativeSurchargeUpdated(opts *bind.FilterOpts) (*DestinationFeeManagerNativeSurchargeUpdatedIterator, error) { + + logs, sub, err := _DestinationFeeManager.contract.FilterLogs(opts, "NativeSurchargeUpdated") + if err != nil { + return nil, err + } + return &DestinationFeeManagerNativeSurchargeUpdatedIterator{contract: _DestinationFeeManager.contract, event: "NativeSurchargeUpdated", logs: logs, sub: sub}, nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) WatchNativeSurchargeUpdated(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerNativeSurchargeUpdated) (event.Subscription, error) { + + logs, sub, err := _DestinationFeeManager.contract.WatchLogs(opts, "NativeSurchargeUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationFeeManagerNativeSurchargeUpdated) + if err := _DestinationFeeManager.contract.UnpackLog(event, "NativeSurchargeUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) ParseNativeSurchargeUpdated(log types.Log) (*DestinationFeeManagerNativeSurchargeUpdated, error) { + event := new(DestinationFeeManagerNativeSurchargeUpdated) + if err := _DestinationFeeManager.contract.UnpackLog(event, "NativeSurchargeUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationFeeManagerOwnershipTransferRequestedIterator struct { + Event *DestinationFeeManagerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationFeeManagerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationFeeManagerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *DestinationFeeManagerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationFeeManagerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationFeeManagerOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationFeeManager.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &DestinationFeeManagerOwnershipTransferRequestedIterator{contract: _DestinationFeeManager.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationFeeManager.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationFeeManagerOwnershipTransferRequested) + if err := _DestinationFeeManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) ParseOwnershipTransferRequested(log types.Log) (*DestinationFeeManagerOwnershipTransferRequested, error) { + event := new(DestinationFeeManagerOwnershipTransferRequested) + if err := _DestinationFeeManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationFeeManagerOwnershipTransferredIterator struct { + Event *DestinationFeeManagerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationFeeManagerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationFeeManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *DestinationFeeManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationFeeManagerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationFeeManagerOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationFeeManager.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &DestinationFeeManagerOwnershipTransferredIterator{contract: _DestinationFeeManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationFeeManager.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationFeeManagerOwnershipTransferred) + if err := _DestinationFeeManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) ParseOwnershipTransferred(log types.Log) (*DestinationFeeManagerOwnershipTransferred, error) { + event := new(DestinationFeeManagerOwnershipTransferred) + if err := _DestinationFeeManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationFeeManagerSubscriberDiscountUpdatedIterator struct { + Event *DestinationFeeManagerSubscriberDiscountUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationFeeManagerSubscriberDiscountUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerSubscriberDiscountUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerSubscriberDiscountUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationFeeManagerSubscriberDiscountUpdatedIterator) Error() error { + return it.fail +} + +func (it *DestinationFeeManagerSubscriberDiscountUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationFeeManagerSubscriberDiscountUpdated struct { + Subscriber common.Address + FeedId [32]byte + Token common.Address + Discount uint64 + Raw types.Log +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) FilterSubscriberDiscountUpdated(opts *bind.FilterOpts, subscriber []common.Address, feedId [][32]byte) (*DestinationFeeManagerSubscriberDiscountUpdatedIterator, error) { + + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _DestinationFeeManager.contract.FilterLogs(opts, "SubscriberDiscountUpdated", subscriberRule, feedIdRule) + if err != nil { + return nil, err + } + return &DestinationFeeManagerSubscriberDiscountUpdatedIterator{contract: _DestinationFeeManager.contract, event: "SubscriberDiscountUpdated", logs: logs, sub: sub}, nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) WatchSubscriberDiscountUpdated(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerSubscriberDiscountUpdated, subscriber []common.Address, feedId [][32]byte) (event.Subscription, error) { + + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _DestinationFeeManager.contract.WatchLogs(opts, "SubscriberDiscountUpdated", subscriberRule, feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationFeeManagerSubscriberDiscountUpdated) + if err := _DestinationFeeManager.contract.UnpackLog(event, "SubscriberDiscountUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) ParseSubscriberDiscountUpdated(log types.Log) (*DestinationFeeManagerSubscriberDiscountUpdated, error) { + event := new(DestinationFeeManagerSubscriberDiscountUpdated) + if err := _DestinationFeeManager.contract.UnpackLog(event, "SubscriberDiscountUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationFeeManagerWithdrawIterator struct { + Event *DestinationFeeManagerWithdraw + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationFeeManagerWithdrawIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerWithdraw) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationFeeManagerWithdraw) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationFeeManagerWithdrawIterator) Error() error { + return it.fail +} + +func (it *DestinationFeeManagerWithdrawIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationFeeManagerWithdraw struct { + AdminAddress common.Address + Recipient common.Address + AssetAddress common.Address + Quantity *big.Int + Raw types.Log +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) FilterWithdraw(opts *bind.FilterOpts) (*DestinationFeeManagerWithdrawIterator, error) { + + logs, sub, err := _DestinationFeeManager.contract.FilterLogs(opts, "Withdraw") + if err != nil { + return nil, err + } + return &DestinationFeeManagerWithdrawIterator{contract: _DestinationFeeManager.contract, event: "Withdraw", logs: logs, sub: sub}, nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) WatchWithdraw(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerWithdraw) (event.Subscription, error) { + + logs, sub, err := _DestinationFeeManager.contract.WatchLogs(opts, "Withdraw") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationFeeManagerWithdraw) + if err := _DestinationFeeManager.contract.UnpackLog(event, "Withdraw", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationFeeManager *DestinationFeeManagerFilterer) ParseWithdraw(log types.Log) (*DestinationFeeManagerWithdraw, error) { + event := new(DestinationFeeManagerWithdraw) + if err := _DestinationFeeManager.contract.UnpackLog(event, "Withdraw", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_DestinationFeeManager *DestinationFeeManager) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _DestinationFeeManager.abi.Events["DiscountApplied"].ID: + return _DestinationFeeManager.ParseDiscountApplied(log) + case _DestinationFeeManager.abi.Events["InsufficientLink"].ID: + return _DestinationFeeManager.ParseInsufficientLink(log) + case _DestinationFeeManager.abi.Events["LinkDeficitCleared"].ID: + return _DestinationFeeManager.ParseLinkDeficitCleared(log) + case _DestinationFeeManager.abi.Events["NativeSurchargeUpdated"].ID: + return _DestinationFeeManager.ParseNativeSurchargeUpdated(log) + case _DestinationFeeManager.abi.Events["OwnershipTransferRequested"].ID: + return _DestinationFeeManager.ParseOwnershipTransferRequested(log) + case _DestinationFeeManager.abi.Events["OwnershipTransferred"].ID: + return _DestinationFeeManager.ParseOwnershipTransferred(log) + case _DestinationFeeManager.abi.Events["SubscriberDiscountUpdated"].ID: + return _DestinationFeeManager.ParseSubscriberDiscountUpdated(log) + case _DestinationFeeManager.abi.Events["Withdraw"].ID: + return _DestinationFeeManager.ParseWithdraw(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (DestinationFeeManagerDiscountApplied) Topic() common.Hash { + return common.HexToHash("0x88b15eb682210089cddf967648e2cb2a4535aeadc8f8f36050922e33c04e7125") +} + +func (DestinationFeeManagerInsufficientLink) Topic() common.Hash { + return common.HexToHash("0xf52e5907b69d97c33392936c12d78b494463b78c5b72df50b4c497eee5720b67") +} + +func (DestinationFeeManagerLinkDeficitCleared) Topic() common.Hash { + return common.HexToHash("0x843f0b103e50b42b08f9d30f12f961845a6d02623730872e24644899c0dd9895") +} + +func (DestinationFeeManagerNativeSurchargeUpdated) Topic() common.Hash { + return common.HexToHash("0x08f7c0d17932ddb8523bc06754d42ff19ebc77d76a8b9bfde02c28ab1ed3d639") +} + +func (DestinationFeeManagerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (DestinationFeeManagerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (DestinationFeeManagerSubscriberDiscountUpdated) Topic() common.Hash { + return common.HexToHash("0x5eba5a8afa39780f0f99b6cbeb95f3da6a7040ca00abd46bdc91a0a060134139") +} + +func (DestinationFeeManagerWithdraw) Topic() common.Hash { + return common.HexToHash("0x7ff78a71698bdb18dcca96f52ab25e0a1b146fb6a49adf8e6845299e49021f29") +} + +func (_DestinationFeeManager *DestinationFeeManager) Address() common.Address { + return _DestinationFeeManager.address +} + +type DestinationFeeManagerInterface interface { + GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quoteAddress common.Address) (CommonAsset, CommonAsset, *big.Int, error) + + ILinkAddress(opts *bind.CallOpts) (common.Address, error) + + INativeAddress(opts *bind.CallOpts) (common.Address, error) + + IRewardManager(opts *bind.CallOpts) (common.Address, error) + + LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SLinkDeficit(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) + + SNativeSurcharge(opts *bind.CallOpts) (*big.Int, error) + + SSubscriberDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) + + SVerifierAddressList(opts *bind.CallOpts, arg0 common.Address) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AddVerifier(opts *bind.TransactOpts, verifierAddress common.Address) (*types.Transaction, error) + + PayLinkDeficit(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) + + ProcessFee(opts *bind.TransactOpts, recipient [32]byte, payload []byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) + + ProcessFeeBulk(opts *bind.TransactOpts, poolIds [][32]byte, payloads [][]byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) + + RemoveVerifier(opts *bind.TransactOpts, verifierAddress common.Address) (*types.Transaction, error) + + SetFeeRecipients(opts *bind.TransactOpts, configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + SetNativeSurcharge(opts *bind.TransactOpts, surcharge uint64) (*types.Transaction, error) + + SetRewardManager(opts *bind.TransactOpts, rewardManagerAddress common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) + + Withdraw(opts *bind.TransactOpts, assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) + + FilterDiscountApplied(opts *bind.FilterOpts, configDigest [][32]byte, subscriber []common.Address) (*DestinationFeeManagerDiscountAppliedIterator, error) + + WatchDiscountApplied(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerDiscountApplied, configDigest [][32]byte, subscriber []common.Address) (event.Subscription, error) + + ParseDiscountApplied(log types.Log) (*DestinationFeeManagerDiscountApplied, error) + + FilterInsufficientLink(opts *bind.FilterOpts) (*DestinationFeeManagerInsufficientLinkIterator, error) + + WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerInsufficientLink) (event.Subscription, error) + + ParseInsufficientLink(log types.Log) (*DestinationFeeManagerInsufficientLink, error) + + FilterLinkDeficitCleared(opts *bind.FilterOpts, configDigest [][32]byte) (*DestinationFeeManagerLinkDeficitClearedIterator, error) + + WatchLinkDeficitCleared(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerLinkDeficitCleared, configDigest [][32]byte) (event.Subscription, error) + + ParseLinkDeficitCleared(log types.Log) (*DestinationFeeManagerLinkDeficitCleared, error) + + FilterNativeSurchargeUpdated(opts *bind.FilterOpts) (*DestinationFeeManagerNativeSurchargeUpdatedIterator, error) + + WatchNativeSurchargeUpdated(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerNativeSurchargeUpdated) (event.Subscription, error) + + ParseNativeSurchargeUpdated(log types.Log) (*DestinationFeeManagerNativeSurchargeUpdated, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationFeeManagerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*DestinationFeeManagerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationFeeManagerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*DestinationFeeManagerOwnershipTransferred, error) + + FilterSubscriberDiscountUpdated(opts *bind.FilterOpts, subscriber []common.Address, feedId [][32]byte) (*DestinationFeeManagerSubscriberDiscountUpdatedIterator, error) + + WatchSubscriberDiscountUpdated(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerSubscriberDiscountUpdated, subscriber []common.Address, feedId [][32]byte) (event.Subscription, error) + + ParseSubscriberDiscountUpdated(log types.Log) (*DestinationFeeManagerSubscriberDiscountUpdated, error) + + FilterWithdraw(opts *bind.FilterOpts) (*DestinationFeeManagerWithdrawIterator, error) + + WatchWithdraw(opts *bind.WatchOpts, sink chan<- *DestinationFeeManagerWithdraw) (event.Subscription, error) + + ParseWithdraw(log types.Log) (*DestinationFeeManagerWithdraw, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/destination_reward_manager/destination_reward_manager.go b/core/gethwrappers/llo-feeds/generated/destination_reward_manager/destination_reward_manager.go new file mode 100644 index 0000000000..989482fc0e --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/destination_reward_manager/destination_reward_manager.go @@ -0,0 +1,1434 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package destination_reward_manager + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommonAddressAndWeight struct { + Addr common.Address + Weight uint64 +} + +type IDestinationRewardManagerFeePayment struct { + PoolId [32]byte + Amount *big.Int +} + +var DestinationRewardManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWeights\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"FeeManagerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIDestinationRewardManager.FeePayment[]\",\"name\":\"payments\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"RewardRecipientsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"RewardsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"addFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"poolIds\",\"type\":\"bytes32[]\"}],\"name\":\"claimRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endIndex\",\"type\":\"uint256\"}],\"name\":\"getAvailableRewardPoolIds\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_linkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"internalType\":\"structIDestinationRewardManager.FeePayment[]\",\"name\":\"payments\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"name\":\"onFeePaid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"recipients\",\"type\":\"address[]\"}],\"name\":\"payRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeManagerAddress\",\"type\":\"address\"}],\"name\":\"removeFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_feeManagerAddressList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_registeredPoolIds\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_rewardRecipientWeights\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_rewardRecipientWeightsSet\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_totalRewardRecipientFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_totalRewardRecipientFeesLastClaimedAmounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"updateRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200244c3803806200244c8339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b60805161224a62000202600039600081816103bb0152818161107601526112b1015261224a6000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c806360122608116100cd5780639604d05f11610081578063cd5f729211610066578063cd5f7292146103a3578063ea4b861b146103b6578063f2fde38b146103dd57600080fd5b80639604d05f1461035a578063b0d9fa191461039057600080fd5b80638115c9cc116100b25780638115c9cc146102dd5780638ac85a5c146102f05780638da5cb5b1461031b57600080fd5b806360122608146102aa57806379ba5097146102d557600080fd5b806339ee81e1116101245780634944832f116101095780634944832f146102615780634d32208414610274578063592562011461028757600080fd5b806339ee81e114610213578063472264751461024157600080fd5b806314060f231161015557806314060f23146101ae578063181f5a77146101c15780631f2d32c31461020057600080fd5b806301ffc9a7146101715780630f3c34d114610199575b600080fd5b61018461017f366004611b3d565b6103f0565b60405190151581526020015b60405180910390f35b6101ac6101a7366004611bfd565b610651565b005b6101ac6101bc366004611cef565b61065f565b604080518082018252601381527f5265776172644d616e6167657220312e302e3000000000000000000000000000602082015290516101909190611d5f565b6101ac61020e366004611dd9565b610821565b610233610221366004611df4565b60026020526000908152604090205481565b604051908152602001610190565b61025461024f366004611e0d565b610959565b6040516101909190611e40565b6101ac61026f366004611cef565b610ae3565b6101ac610282366004611e84565b610c2c565b610184610295366004611df4565b60056020526000908152604090205460ff1681565b6102336102b8366004611f03565b600360209081526000928352604080842090915290825290205481565b6101ac610d6b565b6101ac6102eb366004611dd9565b610e6d565b6102336102fe366004611f03565b600460209081526000928352604080842090915290825290205481565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610190565b610335610368366004611dd9565b60076020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6101ac61039e366004611f2f565b610f1f565b6102336103b1366004611df4565b6110df565b6103357f000000000000000000000000000000000000000000000000000000000000000081565b6101ac6103eb366004611dd9565b611100565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f0f3c34d100000000000000000000000000000000000000000000000000000000148061048357507fffffffff0000000000000000000000000000000000000000000000000000000082167f14060f2300000000000000000000000000000000000000000000000000000000145b806104cf57507fffffffff0000000000000000000000000000000000000000000000000000000082167f4944832f00000000000000000000000000000000000000000000000000000000145b8061051b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f4d32208400000000000000000000000000000000000000000000000000000000145b8061056757507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f2d32c300000000000000000000000000000000000000000000000000000000145b806105b357507fffffffff0000000000000000000000000000000000000000000000000000000082167f8115c9cc00000000000000000000000000000000000000000000000000000000145b806105ff57507fffffffff0000000000000000000000000000000000000000000000000000000082167f4722647500000000000000000000000000000000000000000000000000000000145b8061064b57507fffffffff0000000000000000000000000000000000000000000000000000000082167fb0d9fa1900000000000000000000000000000000000000000000000000000000145b92915050565b61065b3382611114565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906106ab57503360008181526007602052604090205473ffffffffffffffffffffffffffffffffffffffff1614155b156106e2576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081900361071d576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526005602052604090205460ff1615610766576040517f0afa7ee800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805460018181019092557ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01849055600084815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790556107e2838383670de0b6b3a76400006112df565b827f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe68383604051610814929190611f9b565b60405180910390a2505050565b6108296114b6565b73ffffffffffffffffffffffffffffffffffffffff8116610876576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81811660009081526007602052604090205416156108d5576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602090815260409182902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905590519182527fe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b4910160405180910390a150565b600654606090600081841161096e5783610970565b815b9050808511156109ac576040517fa22caccc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109b88683612032565b67ffffffffffffffff8111156109d0576109d0611b7f565b6040519080825280602002602001820160405280156109f9578160200160208202803683370190505b5090506000865b83811015610ad657600060068281548110610a1d57610a1d612045565b600091825260208083209091015480835260048252604080842073ffffffffffffffffffffffffffffffffffffffff8f16855290925291205490915015610ac5576000818152600260209081526040808320546003835281842073ffffffffffffffffffffffffffffffffffffffff8f168552909252909120548114610ac35781858580600101965081518110610ab657610ab6612045565b6020026020010181815250505b505b50610acf81612074565b9050610a00565b5090979650505050505050565b610aeb6114b6565b604080516001808252818301909252600091602080830190803683370190505090508381600081518110610b2157610b21612045565b6020026020010181815250506000805b83811015610bde576000858583818110610b4d57610b4d612045565b610b639260206040909202019081019150611dd9565b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902054909150610bc7878785818110610bab57610bab612045565b610bc19260206040909202019081019150611dd9565b86611114565b50929092019150610bd781612074565b9050610b31565b50610beb858585846112df565b847f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe68585604051610c1d929190611f9b565b60405180910390a25050505050565b82610c4c60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015610c9e57506000818152600460209081526040808320338452909152902054155b15610cd5576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001808252818301909252600091602080830190803683370190505090508481600081518110610d0b57610d0b612045565b60200260200101818152505060005b83811015610d6357610d52858583818110610d3757610d37612045565b9050602002016020810190610d4c9190611dd9565b83611114565b50610d5c81612074565b9050610d1a565b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610df1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e756114b6565b73ffffffffffffffffffffffffffffffffffffffff81811660009081526007602052604090205416610ed3576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260076020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b3360008181526007602052604090205473ffffffffffffffffffffffffffffffffffffffff1614610f7c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8381101561105b57848482818110610f9a57610f9a612045565b9050604002016020016020810190610fb291906120d4565b77ffffffffffffffffffffffffffffffffffffffffffffffff1660026000878785818110610fe257610fe2612045565b604090810292909201358352506020820192909252016000208054909101905584848281811061101457611014612045565b905060400201602001602081019061102c91906120d4565b77ffffffffffffffffffffffffffffffffffffffffffffffff16820191508061105490612074565b9050610f80565b5061109e73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016833084611539565b7fa1cc025ea76bacce5d740ee4bc331899375dc2c5f2ab33933aaacbd9ba001b668484846040516110d1939291906120ef565b60405180910390a150505050565b600681815481106110ef57600080fd5b600091825260209091200154905081565b6111086114b6565b6111118161161b565b50565b60008060005b835181101561129057600084828151811061113757611137612045565b6020026020010151905060006002600083815260200190815260200160002054905080600003611168575050611280565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b16808552908352818420548685526004845282852091855292528220549083039190670de0b6b3a7640000908302049050806000036111d15750505050611280565b600084815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d16808552925290912084905588519682019689908790811061121c5761121c612045565b60200260200101517f989969655bc1d593922527fe85d71347bb8e12fa423cc71f362dd8ef7cb10ef283604051611273919077ffffffffffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a3505050505b61128981612074565b905061111a565b5080156112d8576112d873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168583611710565b9392505050565b61133a8383808060200260200160405190810160405280939291908181526020016000905b828210156113305761132160408302860136819003810190612176565b81526020019060010190611304565b505050505061176b565b15611371576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8381101561147557600085858381811061139157611391612045565b90506040020160200160208101906113a991906121d1565b67ffffffffffffffff16905060008686848181106113c9576113c9612045565b6113df9260206040909202019081019150611dd9565b905073ffffffffffffffffffffffffffffffffffffffff811661142e576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff909416835292905220819055919091019061146e81612074565b9050611375565b508181146114af576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610de8565b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526116159085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611822565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361169a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610de8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526117669084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611593565b505050565b6000805b82518110156118195760006117858260016121ec565b90505b8351811015611810578381815181106117a3576117a3612045565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168483815181106117d7576117d7612045565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603611808575060019392505050565b600101611788565b5060010161176f565b50600092915050565b6000611884826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661192e9092919063ffffffff16565b80519091501561176657808060200190518101906118a291906121ff565b611766576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610de8565b606061193d8484600085611945565b949350505050565b6060824710156119d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610de8565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611a009190612221565b60006040518083038185875af1925050503d8060008114611a3d576040519150601f19603f3d011682016040523d82523d6000602084013e611a42565b606091505b5091509150611a5387838387611a5e565b979650505050505050565b60608315611af4578251600003611aed5773ffffffffffffffffffffffffffffffffffffffff85163b611aed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610de8565b508161193d565b61193d8383815115611b095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de89190611d5f565b600060208284031215611b4f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146112d857600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611bf557611bf5611b7f565b604052919050565b60006020808385031215611c1057600080fd5b823567ffffffffffffffff80821115611c2857600080fd5b818501915085601f830112611c3c57600080fd5b813581811115611c4e57611c4e611b7f565b8060051b9150611c5f848301611bae565b8181529183018401918481019088841115611c7957600080fd5b938501935b83851015611c9757843582529385019390850190611c7e565b98975050505050505050565b60008083601f840112611cb557600080fd5b50813567ffffffffffffffff811115611ccd57600080fd5b6020830191508360208260061b8501011115611ce857600080fd5b9250929050565b600080600060408486031215611d0457600080fd5b83359250602084013567ffffffffffffffff811115611d2257600080fd5b611d2e86828701611ca3565b9497909650939450505050565b60005b83811015611d56578181015183820152602001611d3e565b50506000910152565b6020815260008251806020840152611d7e816040850160208701611d3b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611dd457600080fd5b919050565b600060208284031215611deb57600080fd5b6112d882611db0565b600060208284031215611e0657600080fd5b5035919050565b600080600060608486031215611e2257600080fd5b611e2b84611db0565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015611e7857835183529284019291840191600101611e5c565b50909695505050505050565b600080600060408486031215611e9957600080fd5b83359250602084013567ffffffffffffffff80821115611eb857600080fd5b818601915086601f830112611ecc57600080fd5b813581811115611edb57600080fd5b8760208260051b8501011115611ef057600080fd5b6020830194508093505050509250925092565b60008060408385031215611f1657600080fd5b82359150611f2660208401611db0565b90509250929050565b600080600060408486031215611f4457600080fd5b833567ffffffffffffffff811115611f5b57600080fd5b611f6786828701611ca3565b9094509250611f7a905060208501611db0565b90509250925092565b803567ffffffffffffffff81168114611dd457600080fd5b6020808252818101839052600090604080840186845b87811015610ad65773ffffffffffffffffffffffffffffffffffffffff611fd783611db0565b16835267ffffffffffffffff611fee868401611f83565b16838601529183019190830190600101611fb1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561064b5761064b612003565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036120a5576120a5612003565b5060010190565b803577ffffffffffffffffffffffffffffffffffffffffffffffff81168114611dd457600080fd5b6000602082840312156120e657600080fd5b6112d8826120ac565b60408082528181018490526000908560608401835b8781101561214b5782358252602077ffffffffffffffffffffffffffffffffffffffffffffffff6121368286016120ac565b16908301529183019190830190600101612104565b5080935050505073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b60006040828403121561218857600080fd5b6040516040810181811067ffffffffffffffff821117156121ab576121ab611b7f565b6040526121b783611db0565b81526121c560208401611f83565b60208201529392505050565b6000602082840312156121e357600080fd5b6112d882611f83565b8082018082111561064b5761064b612003565b60006020828403121561221157600080fd5b815180151581146112d857600080fd5b60008251612233818460208701611d3b565b919091019291505056fea164736f6c6343000813000a", +} + +var DestinationRewardManagerABI = DestinationRewardManagerMetaData.ABI + +var DestinationRewardManagerBin = DestinationRewardManagerMetaData.Bin + +func DeployDestinationRewardManager(auth *bind.TransactOpts, backend bind.ContractBackend, linkAddress common.Address) (common.Address, *types.Transaction, *DestinationRewardManager, error) { + parsed, err := DestinationRewardManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DestinationRewardManagerBin), backend, linkAddress) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &DestinationRewardManager{address: address, abi: *parsed, DestinationRewardManagerCaller: DestinationRewardManagerCaller{contract: contract}, DestinationRewardManagerTransactor: DestinationRewardManagerTransactor{contract: contract}, DestinationRewardManagerFilterer: DestinationRewardManagerFilterer{contract: contract}}, nil +} + +type DestinationRewardManager struct { + address common.Address + abi abi.ABI + DestinationRewardManagerCaller + DestinationRewardManagerTransactor + DestinationRewardManagerFilterer +} + +type DestinationRewardManagerCaller struct { + contract *bind.BoundContract +} + +type DestinationRewardManagerTransactor struct { + contract *bind.BoundContract +} + +type DestinationRewardManagerFilterer struct { + contract *bind.BoundContract +} + +type DestinationRewardManagerSession struct { + Contract *DestinationRewardManager + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type DestinationRewardManagerCallerSession struct { + Contract *DestinationRewardManagerCaller + CallOpts bind.CallOpts +} + +type DestinationRewardManagerTransactorSession struct { + Contract *DestinationRewardManagerTransactor + TransactOpts bind.TransactOpts +} + +type DestinationRewardManagerRaw struct { + Contract *DestinationRewardManager +} + +type DestinationRewardManagerCallerRaw struct { + Contract *DestinationRewardManagerCaller +} + +type DestinationRewardManagerTransactorRaw struct { + Contract *DestinationRewardManagerTransactor +} + +func NewDestinationRewardManager(address common.Address, backend bind.ContractBackend) (*DestinationRewardManager, error) { + abi, err := abi.JSON(strings.NewReader(DestinationRewardManagerABI)) + if err != nil { + return nil, err + } + contract, err := bindDestinationRewardManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &DestinationRewardManager{address: address, abi: abi, DestinationRewardManagerCaller: DestinationRewardManagerCaller{contract: contract}, DestinationRewardManagerTransactor: DestinationRewardManagerTransactor{contract: contract}, DestinationRewardManagerFilterer: DestinationRewardManagerFilterer{contract: contract}}, nil +} + +func NewDestinationRewardManagerCaller(address common.Address, caller bind.ContractCaller) (*DestinationRewardManagerCaller, error) { + contract, err := bindDestinationRewardManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &DestinationRewardManagerCaller{contract: contract}, nil +} + +func NewDestinationRewardManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*DestinationRewardManagerTransactor, error) { + contract, err := bindDestinationRewardManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &DestinationRewardManagerTransactor{contract: contract}, nil +} + +func NewDestinationRewardManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*DestinationRewardManagerFilterer, error) { + contract, err := bindDestinationRewardManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &DestinationRewardManagerFilterer{contract: contract}, nil +} + +func bindDestinationRewardManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := DestinationRewardManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_DestinationRewardManager *DestinationRewardManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DestinationRewardManager.Contract.DestinationRewardManagerCaller.contract.Call(opts, result, method, params...) +} + +func (_DestinationRewardManager *DestinationRewardManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.DestinationRewardManagerTransactor.contract.Transfer(opts) +} + +func (_DestinationRewardManager *DestinationRewardManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.DestinationRewardManagerTransactor.contract.Transact(opts, method, params...) +} + +func (_DestinationRewardManager *DestinationRewardManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DestinationRewardManager.Contract.contract.Call(opts, result, method, params...) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.contract.Transfer(opts) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.contract.Transact(opts, method, params...) +} + +func (_DestinationRewardManager *DestinationRewardManagerCaller) GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) { + var out []interface{} + err := _DestinationRewardManager.contract.Call(opts, &out, "getAvailableRewardPoolIds", recipient, startIndex, endIndex) + + if err != nil { + return *new([][32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([][32]byte)).(*[][32]byte) + + return out0, err + +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) GetAvailableRewardPoolIds(recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) { + return _DestinationRewardManager.Contract.GetAvailableRewardPoolIds(&_DestinationRewardManager.CallOpts, recipient, startIndex, endIndex) +} + +func (_DestinationRewardManager *DestinationRewardManagerCallerSession) GetAvailableRewardPoolIds(recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) { + return _DestinationRewardManager.Contract.GetAvailableRewardPoolIds(&_DestinationRewardManager.CallOpts, recipient, startIndex, endIndex) +} + +func (_DestinationRewardManager *DestinationRewardManagerCaller) ILinkAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationRewardManager.contract.Call(opts, &out, "i_linkAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) ILinkAddress() (common.Address, error) { + return _DestinationRewardManager.Contract.ILinkAddress(&_DestinationRewardManager.CallOpts) +} + +func (_DestinationRewardManager *DestinationRewardManagerCallerSession) ILinkAddress() (common.Address, error) { + return _DestinationRewardManager.Contract.ILinkAddress(&_DestinationRewardManager.CallOpts) +} + +func (_DestinationRewardManager *DestinationRewardManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationRewardManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) Owner() (common.Address, error) { + return _DestinationRewardManager.Contract.Owner(&_DestinationRewardManager.CallOpts) +} + +func (_DestinationRewardManager *DestinationRewardManagerCallerSession) Owner() (common.Address, error) { + return _DestinationRewardManager.Contract.Owner(&_DestinationRewardManager.CallOpts) +} + +func (_DestinationRewardManager *DestinationRewardManagerCaller) SFeeManagerAddressList(opts *bind.CallOpts, arg0 common.Address) (common.Address, error) { + var out []interface{} + err := _DestinationRewardManager.contract.Call(opts, &out, "s_feeManagerAddressList", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) SFeeManagerAddressList(arg0 common.Address) (common.Address, error) { + return _DestinationRewardManager.Contract.SFeeManagerAddressList(&_DestinationRewardManager.CallOpts, arg0) +} + +func (_DestinationRewardManager *DestinationRewardManagerCallerSession) SFeeManagerAddressList(arg0 common.Address) (common.Address, error) { + return _DestinationRewardManager.Contract.SFeeManagerAddressList(&_DestinationRewardManager.CallOpts, arg0) +} + +func (_DestinationRewardManager *DestinationRewardManagerCaller) SRegisteredPoolIds(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _DestinationRewardManager.contract.Call(opts, &out, "s_registeredPoolIds", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) SRegisteredPoolIds(arg0 *big.Int) ([32]byte, error) { + return _DestinationRewardManager.Contract.SRegisteredPoolIds(&_DestinationRewardManager.CallOpts, arg0) +} + +func (_DestinationRewardManager *DestinationRewardManagerCallerSession) SRegisteredPoolIds(arg0 *big.Int) ([32]byte, error) { + return _DestinationRewardManager.Contract.SRegisteredPoolIds(&_DestinationRewardManager.CallOpts, arg0) +} + +func (_DestinationRewardManager *DestinationRewardManagerCaller) SRewardRecipientWeights(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + var out []interface{} + err := _DestinationRewardManager.contract.Call(opts, &out, "s_rewardRecipientWeights", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) SRewardRecipientWeights(arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + return _DestinationRewardManager.Contract.SRewardRecipientWeights(&_DestinationRewardManager.CallOpts, arg0, arg1) +} + +func (_DestinationRewardManager *DestinationRewardManagerCallerSession) SRewardRecipientWeights(arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + return _DestinationRewardManager.Contract.SRewardRecipientWeights(&_DestinationRewardManager.CallOpts, arg0, arg1) +} + +func (_DestinationRewardManager *DestinationRewardManagerCaller) SRewardRecipientWeightsSet(opts *bind.CallOpts, arg0 [32]byte) (bool, error) { + var out []interface{} + err := _DestinationRewardManager.contract.Call(opts, &out, "s_rewardRecipientWeightsSet", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) SRewardRecipientWeightsSet(arg0 [32]byte) (bool, error) { + return _DestinationRewardManager.Contract.SRewardRecipientWeightsSet(&_DestinationRewardManager.CallOpts, arg0) +} + +func (_DestinationRewardManager *DestinationRewardManagerCallerSession) SRewardRecipientWeightsSet(arg0 [32]byte) (bool, error) { + return _DestinationRewardManager.Contract.SRewardRecipientWeightsSet(&_DestinationRewardManager.CallOpts, arg0) +} + +func (_DestinationRewardManager *DestinationRewardManagerCaller) STotalRewardRecipientFees(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) { + var out []interface{} + err := _DestinationRewardManager.contract.Call(opts, &out, "s_totalRewardRecipientFees", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) STotalRewardRecipientFees(arg0 [32]byte) (*big.Int, error) { + return _DestinationRewardManager.Contract.STotalRewardRecipientFees(&_DestinationRewardManager.CallOpts, arg0) +} + +func (_DestinationRewardManager *DestinationRewardManagerCallerSession) STotalRewardRecipientFees(arg0 [32]byte) (*big.Int, error) { + return _DestinationRewardManager.Contract.STotalRewardRecipientFees(&_DestinationRewardManager.CallOpts, arg0) +} + +func (_DestinationRewardManager *DestinationRewardManagerCaller) STotalRewardRecipientFeesLastClaimedAmounts(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + var out []interface{} + err := _DestinationRewardManager.contract.Call(opts, &out, "s_totalRewardRecipientFeesLastClaimedAmounts", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) STotalRewardRecipientFeesLastClaimedAmounts(arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + return _DestinationRewardManager.Contract.STotalRewardRecipientFeesLastClaimedAmounts(&_DestinationRewardManager.CallOpts, arg0, arg1) +} + +func (_DestinationRewardManager *DestinationRewardManagerCallerSession) STotalRewardRecipientFeesLastClaimedAmounts(arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + return _DestinationRewardManager.Contract.STotalRewardRecipientFeesLastClaimedAmounts(&_DestinationRewardManager.CallOpts, arg0, arg1) +} + +func (_DestinationRewardManager *DestinationRewardManagerCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _DestinationRewardManager.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _DestinationRewardManager.Contract.SupportsInterface(&_DestinationRewardManager.CallOpts, interfaceId) +} + +func (_DestinationRewardManager *DestinationRewardManagerCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _DestinationRewardManager.Contract.SupportsInterface(&_DestinationRewardManager.CallOpts, interfaceId) +} + +func (_DestinationRewardManager *DestinationRewardManagerCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _DestinationRewardManager.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) TypeAndVersion() (string, error) { + return _DestinationRewardManager.Contract.TypeAndVersion(&_DestinationRewardManager.CallOpts) +} + +func (_DestinationRewardManager *DestinationRewardManagerCallerSession) TypeAndVersion() (string, error) { + return _DestinationRewardManager.Contract.TypeAndVersion(&_DestinationRewardManager.CallOpts) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationRewardManager.contract.Transact(opts, "acceptOwnership") +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) AcceptOwnership() (*types.Transaction, error) { + return _DestinationRewardManager.Contract.AcceptOwnership(&_DestinationRewardManager.TransactOpts) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _DestinationRewardManager.Contract.AcceptOwnership(&_DestinationRewardManager.TransactOpts) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactor) AddFeeManager(opts *bind.TransactOpts, newFeeManagerAddress common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.contract.Transact(opts, "addFeeManager", newFeeManagerAddress) +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) AddFeeManager(newFeeManagerAddress common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.AddFeeManager(&_DestinationRewardManager.TransactOpts, newFeeManagerAddress) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactorSession) AddFeeManager(newFeeManagerAddress common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.AddFeeManager(&_DestinationRewardManager.TransactOpts, newFeeManagerAddress) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactor) ClaimRewards(opts *bind.TransactOpts, poolIds [][32]byte) (*types.Transaction, error) { + return _DestinationRewardManager.contract.Transact(opts, "claimRewards", poolIds) +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) ClaimRewards(poolIds [][32]byte) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.ClaimRewards(&_DestinationRewardManager.TransactOpts, poolIds) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactorSession) ClaimRewards(poolIds [][32]byte) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.ClaimRewards(&_DestinationRewardManager.TransactOpts, poolIds) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactor) OnFeePaid(opts *bind.TransactOpts, payments []IDestinationRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.contract.Transact(opts, "onFeePaid", payments, payer) +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) OnFeePaid(payments []IDestinationRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.OnFeePaid(&_DestinationRewardManager.TransactOpts, payments, payer) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactorSession) OnFeePaid(payments []IDestinationRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.OnFeePaid(&_DestinationRewardManager.TransactOpts, payments, payer) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactor) PayRecipients(opts *bind.TransactOpts, poolId [32]byte, recipients []common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.contract.Transact(opts, "payRecipients", poolId, recipients) +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) PayRecipients(poolId [32]byte, recipients []common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.PayRecipients(&_DestinationRewardManager.TransactOpts, poolId, recipients) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactorSession) PayRecipients(poolId [32]byte, recipients []common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.PayRecipients(&_DestinationRewardManager.TransactOpts, poolId, recipients) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactor) RemoveFeeManager(opts *bind.TransactOpts, feeManagerAddress common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.contract.Transact(opts, "removeFeeManager", feeManagerAddress) +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) RemoveFeeManager(feeManagerAddress common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.RemoveFeeManager(&_DestinationRewardManager.TransactOpts, feeManagerAddress) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactorSession) RemoveFeeManager(feeManagerAddress common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.RemoveFeeManager(&_DestinationRewardManager.TransactOpts, feeManagerAddress) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactor) SetRewardRecipients(opts *bind.TransactOpts, poolId [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _DestinationRewardManager.contract.Transact(opts, "setRewardRecipients", poolId, rewardRecipientAndWeights) +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) SetRewardRecipients(poolId [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.SetRewardRecipients(&_DestinationRewardManager.TransactOpts, poolId, rewardRecipientAndWeights) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactorSession) SetRewardRecipients(poolId [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.SetRewardRecipients(&_DestinationRewardManager.TransactOpts, poolId, rewardRecipientAndWeights) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.contract.Transact(opts, "transferOwnership", to) +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.TransferOwnership(&_DestinationRewardManager.TransactOpts, to) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.TransferOwnership(&_DestinationRewardManager.TransactOpts, to) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactor) UpdateRewardRecipients(opts *bind.TransactOpts, poolId [32]byte, newRewardRecipients []CommonAddressAndWeight) (*types.Transaction, error) { + return _DestinationRewardManager.contract.Transact(opts, "updateRewardRecipients", poolId, newRewardRecipients) +} + +func (_DestinationRewardManager *DestinationRewardManagerSession) UpdateRewardRecipients(poolId [32]byte, newRewardRecipients []CommonAddressAndWeight) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.UpdateRewardRecipients(&_DestinationRewardManager.TransactOpts, poolId, newRewardRecipients) +} + +func (_DestinationRewardManager *DestinationRewardManagerTransactorSession) UpdateRewardRecipients(poolId [32]byte, newRewardRecipients []CommonAddressAndWeight) (*types.Transaction, error) { + return _DestinationRewardManager.Contract.UpdateRewardRecipients(&_DestinationRewardManager.TransactOpts, poolId, newRewardRecipients) +} + +type DestinationRewardManagerFeeManagerUpdatedIterator struct { + Event *DestinationRewardManagerFeeManagerUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationRewardManagerFeeManagerUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationRewardManagerFeeManagerUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationRewardManagerFeeManagerUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationRewardManagerFeeManagerUpdatedIterator) Error() error { + return it.fail +} + +func (it *DestinationRewardManagerFeeManagerUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationRewardManagerFeeManagerUpdated struct { + NewFeeManagerAddress common.Address + Raw types.Log +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) FilterFeeManagerUpdated(opts *bind.FilterOpts) (*DestinationRewardManagerFeeManagerUpdatedIterator, error) { + + logs, sub, err := _DestinationRewardManager.contract.FilterLogs(opts, "FeeManagerUpdated") + if err != nil { + return nil, err + } + return &DestinationRewardManagerFeeManagerUpdatedIterator{contract: _DestinationRewardManager.contract, event: "FeeManagerUpdated", logs: logs, sub: sub}, nil +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) WatchFeeManagerUpdated(opts *bind.WatchOpts, sink chan<- *DestinationRewardManagerFeeManagerUpdated) (event.Subscription, error) { + + logs, sub, err := _DestinationRewardManager.contract.WatchLogs(opts, "FeeManagerUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationRewardManagerFeeManagerUpdated) + if err := _DestinationRewardManager.contract.UnpackLog(event, "FeeManagerUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) ParseFeeManagerUpdated(log types.Log) (*DestinationRewardManagerFeeManagerUpdated, error) { + event := new(DestinationRewardManagerFeeManagerUpdated) + if err := _DestinationRewardManager.contract.UnpackLog(event, "FeeManagerUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationRewardManagerFeePaidIterator struct { + Event *DestinationRewardManagerFeePaid + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationRewardManagerFeePaidIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationRewardManagerFeePaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationRewardManagerFeePaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationRewardManagerFeePaidIterator) Error() error { + return it.fail +} + +func (it *DestinationRewardManagerFeePaidIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationRewardManagerFeePaid struct { + Payments []IDestinationRewardManagerFeePayment + Payer common.Address + Raw types.Log +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) FilterFeePaid(opts *bind.FilterOpts) (*DestinationRewardManagerFeePaidIterator, error) { + + logs, sub, err := _DestinationRewardManager.contract.FilterLogs(opts, "FeePaid") + if err != nil { + return nil, err + } + return &DestinationRewardManagerFeePaidIterator{contract: _DestinationRewardManager.contract, event: "FeePaid", logs: logs, sub: sub}, nil +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) WatchFeePaid(opts *bind.WatchOpts, sink chan<- *DestinationRewardManagerFeePaid) (event.Subscription, error) { + + logs, sub, err := _DestinationRewardManager.contract.WatchLogs(opts, "FeePaid") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationRewardManagerFeePaid) + if err := _DestinationRewardManager.contract.UnpackLog(event, "FeePaid", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) ParseFeePaid(log types.Log) (*DestinationRewardManagerFeePaid, error) { + event := new(DestinationRewardManagerFeePaid) + if err := _DestinationRewardManager.contract.UnpackLog(event, "FeePaid", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationRewardManagerOwnershipTransferRequestedIterator struct { + Event *DestinationRewardManagerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationRewardManagerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationRewardManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationRewardManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationRewardManagerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *DestinationRewardManagerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationRewardManagerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationRewardManagerOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationRewardManager.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &DestinationRewardManagerOwnershipTransferRequestedIterator{contract: _DestinationRewardManager.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *DestinationRewardManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationRewardManager.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationRewardManagerOwnershipTransferRequested) + if err := _DestinationRewardManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) ParseOwnershipTransferRequested(log types.Log) (*DestinationRewardManagerOwnershipTransferRequested, error) { + event := new(DestinationRewardManagerOwnershipTransferRequested) + if err := _DestinationRewardManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationRewardManagerOwnershipTransferredIterator struct { + Event *DestinationRewardManagerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationRewardManagerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationRewardManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationRewardManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationRewardManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *DestinationRewardManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationRewardManagerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationRewardManagerOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationRewardManager.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &DestinationRewardManagerOwnershipTransferredIterator{contract: _DestinationRewardManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DestinationRewardManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationRewardManager.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationRewardManagerOwnershipTransferred) + if err := _DestinationRewardManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) ParseOwnershipTransferred(log types.Log) (*DestinationRewardManagerOwnershipTransferred, error) { + event := new(DestinationRewardManagerOwnershipTransferred) + if err := _DestinationRewardManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationRewardManagerRewardRecipientsUpdatedIterator struct { + Event *DestinationRewardManagerRewardRecipientsUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationRewardManagerRewardRecipientsUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationRewardManagerRewardRecipientsUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationRewardManagerRewardRecipientsUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationRewardManagerRewardRecipientsUpdatedIterator) Error() error { + return it.fail +} + +func (it *DestinationRewardManagerRewardRecipientsUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationRewardManagerRewardRecipientsUpdated struct { + PoolId [32]byte + NewRewardRecipients []CommonAddressAndWeight + Raw types.Log +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) FilterRewardRecipientsUpdated(opts *bind.FilterOpts, poolId [][32]byte) (*DestinationRewardManagerRewardRecipientsUpdatedIterator, error) { + + var poolIdRule []interface{} + for _, poolIdItem := range poolId { + poolIdRule = append(poolIdRule, poolIdItem) + } + + logs, sub, err := _DestinationRewardManager.contract.FilterLogs(opts, "RewardRecipientsUpdated", poolIdRule) + if err != nil { + return nil, err + } + return &DestinationRewardManagerRewardRecipientsUpdatedIterator{contract: _DestinationRewardManager.contract, event: "RewardRecipientsUpdated", logs: logs, sub: sub}, nil +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) WatchRewardRecipientsUpdated(opts *bind.WatchOpts, sink chan<- *DestinationRewardManagerRewardRecipientsUpdated, poolId [][32]byte) (event.Subscription, error) { + + var poolIdRule []interface{} + for _, poolIdItem := range poolId { + poolIdRule = append(poolIdRule, poolIdItem) + } + + logs, sub, err := _DestinationRewardManager.contract.WatchLogs(opts, "RewardRecipientsUpdated", poolIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationRewardManagerRewardRecipientsUpdated) + if err := _DestinationRewardManager.contract.UnpackLog(event, "RewardRecipientsUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) ParseRewardRecipientsUpdated(log types.Log) (*DestinationRewardManagerRewardRecipientsUpdated, error) { + event := new(DestinationRewardManagerRewardRecipientsUpdated) + if err := _DestinationRewardManager.contract.UnpackLog(event, "RewardRecipientsUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationRewardManagerRewardsClaimedIterator struct { + Event *DestinationRewardManagerRewardsClaimed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationRewardManagerRewardsClaimedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationRewardManagerRewardsClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationRewardManagerRewardsClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationRewardManagerRewardsClaimedIterator) Error() error { + return it.fail +} + +func (it *DestinationRewardManagerRewardsClaimedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationRewardManagerRewardsClaimed struct { + PoolId [32]byte + Recipient common.Address + Quantity *big.Int + Raw types.Log +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) FilterRewardsClaimed(opts *bind.FilterOpts, poolId [][32]byte, recipient []common.Address) (*DestinationRewardManagerRewardsClaimedIterator, error) { + + var poolIdRule []interface{} + for _, poolIdItem := range poolId { + poolIdRule = append(poolIdRule, poolIdItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _DestinationRewardManager.contract.FilterLogs(opts, "RewardsClaimed", poolIdRule, recipientRule) + if err != nil { + return nil, err + } + return &DestinationRewardManagerRewardsClaimedIterator{contract: _DestinationRewardManager.contract, event: "RewardsClaimed", logs: logs, sub: sub}, nil +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) WatchRewardsClaimed(opts *bind.WatchOpts, sink chan<- *DestinationRewardManagerRewardsClaimed, poolId [][32]byte, recipient []common.Address) (event.Subscription, error) { + + var poolIdRule []interface{} + for _, poolIdItem := range poolId { + poolIdRule = append(poolIdRule, poolIdItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _DestinationRewardManager.contract.WatchLogs(opts, "RewardsClaimed", poolIdRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationRewardManagerRewardsClaimed) + if err := _DestinationRewardManager.contract.UnpackLog(event, "RewardsClaimed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationRewardManager *DestinationRewardManagerFilterer) ParseRewardsClaimed(log types.Log) (*DestinationRewardManagerRewardsClaimed, error) { + event := new(DestinationRewardManagerRewardsClaimed) + if err := _DestinationRewardManager.contract.UnpackLog(event, "RewardsClaimed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_DestinationRewardManager *DestinationRewardManager) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _DestinationRewardManager.abi.Events["FeeManagerUpdated"].ID: + return _DestinationRewardManager.ParseFeeManagerUpdated(log) + case _DestinationRewardManager.abi.Events["FeePaid"].ID: + return _DestinationRewardManager.ParseFeePaid(log) + case _DestinationRewardManager.abi.Events["OwnershipTransferRequested"].ID: + return _DestinationRewardManager.ParseOwnershipTransferRequested(log) + case _DestinationRewardManager.abi.Events["OwnershipTransferred"].ID: + return _DestinationRewardManager.ParseOwnershipTransferred(log) + case _DestinationRewardManager.abi.Events["RewardRecipientsUpdated"].ID: + return _DestinationRewardManager.ParseRewardRecipientsUpdated(log) + case _DestinationRewardManager.abi.Events["RewardsClaimed"].ID: + return _DestinationRewardManager.ParseRewardsClaimed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (DestinationRewardManagerFeeManagerUpdated) Topic() common.Hash { + return common.HexToHash("0xe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b4") +} + +func (DestinationRewardManagerFeePaid) Topic() common.Hash { + return common.HexToHash("0xa1cc025ea76bacce5d740ee4bc331899375dc2c5f2ab33933aaacbd9ba001b66") +} + +func (DestinationRewardManagerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (DestinationRewardManagerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (DestinationRewardManagerRewardRecipientsUpdated) Topic() common.Hash { + return common.HexToHash("0x8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe6") +} + +func (DestinationRewardManagerRewardsClaimed) Topic() common.Hash { + return common.HexToHash("0x989969655bc1d593922527fe85d71347bb8e12fa423cc71f362dd8ef7cb10ef2") +} + +func (_DestinationRewardManager *DestinationRewardManager) Address() common.Address { + return _DestinationRewardManager.address +} + +type DestinationRewardManagerInterface interface { + GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) + + ILinkAddress(opts *bind.CallOpts) (common.Address, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SFeeManagerAddressList(opts *bind.CallOpts, arg0 common.Address) (common.Address, error) + + SRegisteredPoolIds(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) + + SRewardRecipientWeights(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error) + + SRewardRecipientWeightsSet(opts *bind.CallOpts, arg0 [32]byte) (bool, error) + + STotalRewardRecipientFees(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) + + STotalRewardRecipientFeesLastClaimedAmounts(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AddFeeManager(opts *bind.TransactOpts, newFeeManagerAddress common.Address) (*types.Transaction, error) + + ClaimRewards(opts *bind.TransactOpts, poolIds [][32]byte) (*types.Transaction, error) + + OnFeePaid(opts *bind.TransactOpts, payments []IDestinationRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) + + PayRecipients(opts *bind.TransactOpts, poolId [32]byte, recipients []common.Address) (*types.Transaction, error) + + RemoveFeeManager(opts *bind.TransactOpts, feeManagerAddress common.Address) (*types.Transaction, error) + + SetRewardRecipients(opts *bind.TransactOpts, poolId [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdateRewardRecipients(opts *bind.TransactOpts, poolId [32]byte, newRewardRecipients []CommonAddressAndWeight) (*types.Transaction, error) + + FilterFeeManagerUpdated(opts *bind.FilterOpts) (*DestinationRewardManagerFeeManagerUpdatedIterator, error) + + WatchFeeManagerUpdated(opts *bind.WatchOpts, sink chan<- *DestinationRewardManagerFeeManagerUpdated) (event.Subscription, error) + + ParseFeeManagerUpdated(log types.Log) (*DestinationRewardManagerFeeManagerUpdated, error) + + FilterFeePaid(opts *bind.FilterOpts) (*DestinationRewardManagerFeePaidIterator, error) + + WatchFeePaid(opts *bind.WatchOpts, sink chan<- *DestinationRewardManagerFeePaid) (event.Subscription, error) + + ParseFeePaid(log types.Log) (*DestinationRewardManagerFeePaid, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationRewardManagerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *DestinationRewardManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*DestinationRewardManagerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationRewardManagerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DestinationRewardManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*DestinationRewardManagerOwnershipTransferred, error) + + FilterRewardRecipientsUpdated(opts *bind.FilterOpts, poolId [][32]byte) (*DestinationRewardManagerRewardRecipientsUpdatedIterator, error) + + WatchRewardRecipientsUpdated(opts *bind.WatchOpts, sink chan<- *DestinationRewardManagerRewardRecipientsUpdated, poolId [][32]byte) (event.Subscription, error) + + ParseRewardRecipientsUpdated(log types.Log) (*DestinationRewardManagerRewardRecipientsUpdated, error) + + FilterRewardsClaimed(opts *bind.FilterOpts, poolId [][32]byte, recipient []common.Address) (*DestinationRewardManagerRewardsClaimedIterator, error) + + WatchRewardsClaimed(opts *bind.WatchOpts, sink chan<- *DestinationRewardManagerRewardsClaimed, poolId [][32]byte, recipient []common.Address) (event.Subscription, error) + + ParseRewardsClaimed(log types.Log) (*DestinationRewardManagerRewardsClaimed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/destination_verifier/destination_verifier.go b/core/gethwrappers/llo-feeds/generated/destination_verifier/destination_verifier.go new file mode 100644 index 0000000000..2fa48b7249 --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/destination_verifier/destination_verifier.go @@ -0,0 +1,1576 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package destination_verifier + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommonAddressAndWeight struct { + Addr common.Address + Weight uint64 +} + +var DestinationVerifierMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierProxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadActivationTime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes24\",\"name\":\"donConfigId\",\"type\":\"bytes24\"}],\"name\":\"DonConfigAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DonConfigDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeeManagerInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"MismatchedSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerifierProxyInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessController\",\"type\":\"address\"}],\"name\":\"AccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes24\",\"name\":\"donConfigId\",\"type\":\"bytes24\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isActive\",\"type\":\"bool\"}],\"name\":\"ConfigActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes24\",\"name\":\"donConfigId\",\"type\":\"bytes24\"}],\"name\":\"ConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes24\",\"name\":\"donConfigId\",\"type\":\"bytes24\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldFeeManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManager\",\"type\":\"address\"}],\"name\":\"FeeManagerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"ReportVerified\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_verifierProxy\",\"outputs\":[{\"internalType\":\"contractIDestinationVerifierProxy\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"removeLatestConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_accessController\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessController\",\"type\":\"address\"}],\"name\":\"setAccessController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"donConfigIndex\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isActive\",\"type\":\"bool\"}],\"name\":\"setConfigActive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint32\",\"name\":\"activationTime\",\"type\":\"uint32\"}],\"name\":\"setConfigWithActivationTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeManager\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signedReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"signedReports\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verifyBulk\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200379d3803806200379d8339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b60805161359b62000202600039600081816102d70152818161062a0152611064015261359b6000f3fe6080604052600436106100f35760003560e01c80638da5cb5b1161008a578063d7c72e4e11610059578063d7c72e4e146102f9578063f08391d814610319578063f2fde38b14610339578063f9c7bf771461035957600080fd5b80638da5cb5b1461025857806394ba284614610283578063af4fed24146102b0578063b97455c7146102c557600080fd5b8063453ec61b116100c6578063453ec61b146101e1578063472d35b9146102035780635ad72fae1461022357806379ba50971461024357600080fd5b806301ffc9a7146100f8578063181f5a771461012d578063294d2bb11461017c57806338416b5b1461018f575b600080fd5b34801561010457600080fd5b50610118610113366004612622565b610379565b60405190151581526020015b60405180910390f35b34801561013957600080fd5b5060408051808201909152601981527f44657374696e6174696f6e566572696669657220312e302e300000000000000060208201525b60405161012491906126cf565b61016f61018a366004612754565b610626565b34801561019b57600080fd5b506004546101bc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b3480156101ed57600080fd5b506102016101fc3660046129e3565b610873565b005b34801561020f57600080fd5b5061020161021e366004612a57565b61097b565b34801561022f57600080fd5b5061020161023e366004612a80565b610c5c565b34801561024f57600080fd5b50610201610d72565b34801561026457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166101bc565b34801561028f57600080fd5b506005546101bc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102bc57600080fd5b50610201610e6f565b3480156102d157600080fd5b506101bc7f000000000000000000000000000000000000000000000000000000000000000081565b61030c610307366004612ab0565b611060565b6040516101249190612b33565b34801561032557600080fd5b50610201610334366004612a57565b611352565b34801561034557600080fd5b50610201610354366004612a57565b6113d9565b34801561036557600080fd5b50610201610374366004612bc5565b6113ed565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f294d2bb100000000000000000000000000000000000000000000000000000000148061040c57507fffffffff0000000000000000000000000000000000000000000000000000000082167fd7c72e4e00000000000000000000000000000000000000000000000000000000145b8061045857507fffffffff0000000000000000000000000000000000000000000000000000000082167f94ba284600000000000000000000000000000000000000000000000000000000145b806104a457507fffffffff0000000000000000000000000000000000000000000000000000000082167f38416b5b00000000000000000000000000000000000000000000000000000000145b806104f057507fffffffff0000000000000000000000000000000000000000000000000000000082167f453ec61b00000000000000000000000000000000000000000000000000000000145b8061053c57507fffffffff0000000000000000000000000000000000000000000000000000000082167ff9c7bf7700000000000000000000000000000000000000000000000000000000145b8061058857507fffffffff0000000000000000000000000000000000000000000000000000000082167f472d35b900000000000000000000000000000000000000000000000000000000145b806105d457507fffffffff0000000000000000000000000000000000000000000000000000000082167ff08391d800000000000000000000000000000000000000000000000000000000145b8061062057507fffffffff0000000000000000000000000000000000000000000000000000000082167f5ad72fae00000000000000000000000000000000000000000000000000000000145b92915050565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163314610697576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554829073ffffffffffffffffffffffffffffffffffffffff16801580159061075657506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf8906107139085906000903690600401612c95565b602060405180830381865afa158015610730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107549190612cce565b155b1561078d576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061079b8a8a886114ab565b600454919350915073ffffffffffffffffffffffffffffffffffffffff168015610864578073ffffffffffffffffffffffffffffffffffffffff166386968cfd34848e8e8e8e8e6040518863ffffffff1660e01b815260040161080396959493929190612ceb565b6000604051808303818588803b15801561081c57600080fd5b505af19350505050801561082e575060015b610864576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50909998505050505050505050565b82518260ff16806000036108b3576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8211156108fd576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044015b60405180910390fd5b610908816003612d71565b8211610960578161091a826003612d71565b610925906001612d88565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016108f4565b6109686119b0565b61097485858542611a33565b5050505050565b6109836119b0565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f86968cfd00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610a0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a319190612cce565b1580610ae857506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f3690750900000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610ac2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae69190612cce565b155b80610b9e57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527ff65df96200000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610b78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9c9190612cce565b155b15610bd5576040517f8238941900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f04628abcaa6b1674651352125cb94b65b289145bc2bc4d67720bb7d966372f0391015b60405180910390a15050565b610c646119b0565b6003548210610c9f576040517f5a0d6fe200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038381548110610cb457610cb4612d9b565b600091825260209182902001805484151579010000000000000000000000000000000000000000000000000081027fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff909216919091178083556040805191811b7fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000168252938101919091529092507f90186a1e77b498ec417ea88bd026cae00d7043c357cc45221777623bda582dd4910160405180910390a1505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610df3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f4565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e776119b0565b600354600003610eb3576040517f5a0d6fe200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6003805460009190610ec790600190612dca565b81548110610ed757610ed7612d9b565b600091825260209182902060408051608081018252929091015480821b7fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001683527801000000000000000000000000000000000000000000000000810460ff9081169484019490945279010000000000000000000000000000000000000000000000000081049093161515908201527a01000000000000000000000000000000000000000000000000000090910463ffffffff166060820152600380549192509080610fa557610fa5612ddd565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffff00000000000000000000000000000000000000000000000000000000000016905501905580516040517f970fd8f3ebdd9a271080aacf9807a5c709be0b448e4047a6fc212b8cc165368d91611055917fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000091909116815260200190565b60405180910390a150565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1633146110d1576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554829073ffffffffffffffffffffffffffffffffffffffff16801580159061119057506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf89061114d9085906000903690600401612c95565b602060405180830381865afa15801561116a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118e9190612cce565b155b156111c7576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008767ffffffffffffffff8111156111e2576111e26127d5565b60405190808252806020026020018201604052801561121557816020015b60608152602001906001900390816112005790505b50905060008867ffffffffffffffff811115611233576112336127d5565b60405190808252806020026020018201604052801561125c578160200160208202803683370190505b50905060005b898110156112ee5760008061129a8d8d8581811061128257611282612d9b565b90506020028101906112949190612e0c565b8b6114ab565b91509150818584815181106112b1576112b1612d9b565b6020026020010181905250808484815181106112cf576112cf612d9b565b6020026020010181815250505050806112e790612e71565b9050611262565b5060045473ffffffffffffffffffffffffffffffffffffffff168015610864578073ffffffffffffffffffffffffffffffffffffffff16633690750934848e8e8e8e8e6040518863ffffffff1660e01b815260040161080396959493929190612ea9565b61135a6119b0565b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b69101610c50565b6113e16119b0565b6113ea816120eb565b50565b83518360ff168060000361142d576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115611472576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044016108f4565b61147d816003612d71565b821161148f578161091a826003612d71565b6114976119b0565b6114a386868686611a33565b505050505050565b6060600080808080806114c0898b018b6130db565b94509450945094509450815183511461151257825182516040517ff0d31408000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016108f4565b825160000361154d576040517fc7af40f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008480519060200120866040516020016115699291906131b6565b6040516020818303038152906040528051906020012090506000845167ffffffffffffffff81111561159d5761159d6127d5565b6040519080825280602002602001820160405280156115c6578160200160208202803683370190505b50905060005b85518110156116d4576001838583602081106115ea576115ea612d9b565b6115f791901a601b6131f2565b88848151811061160957611609612d9b565b602002602001015188858151811061162357611623612d9b565b602002602001015160405160008152602001604052604051611661949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611683573d6000803e3d6000fd5b5050506020604051035182828151811061169f5761169f612d9b565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526116cd81612e71565b90506115cc565b506116de816121e0565b15611715576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006117208761228f565b9050600061172d826122b5565b80519091507fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001661178a576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80604001516117c5576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015160ff16835111611806576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b84518110156119245784818151811061182557611825612d9b565b6020026020010151836000015160405160200161189592919060609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001682527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166014820152602c0190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600290935291205490925060ff16611914576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61191d81612e71565b905061180a565b5061192e8961320b565b60405173ffffffffffffffffffffffffffffffffffffffff8f1681527f58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc59060200160405180910390a25051969d7fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009097169c50959a5050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f4565b565b83518360ff1680600003611a73576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115611ab8576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044016108f4565b611ac3816003612d71565b8211611ad5578161091a826003612d71565b611add6119b0565b611ae6866121e0565b15611b1d576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b428363ffffffff161115611b5d576040517f0114c7e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7686600060018951611b719190612dca565b61243a565b60008686604051602001611b8b929190613250565b60405160208183030381529060405280519060200120905060005b8751811015611d3257600073ffffffffffffffffffffffffffffffffffffffff16888281518110611bd957611bd9612d9b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611c2e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600260008a8481518110611c4657611c46612d9b565b602002602001015185604051602001611cb292919060609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001682527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166014820152602c0190565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291815281516020928301208352908201929092520160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055611d2b81612e71565b9050611ba6565b506003548015801590611d96575063ffffffff85166003611d54600184612dca565b81548110611d6457611d64612d9b565b6000918252602090912001547a010000000000000000000000000000000000000000000000000000900463ffffffff16115b15611dcd576040517f0114c7e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081118015611e4b57507fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000082166003611e08600184612dca565b81548110611e1857611e18612d9b565b60009182526020909120015460401b7fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016145b15611ea6576040517fc0178c860000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000831660048201526024016108f4565b855115611f3757600480546040517ff65df96200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169163f65df96291611f049186918b910161332e565b600060405180830381600087803b158015611f1e57600080fd5b505af1158015611f32573d6000803e3d6000fd5b505050505b604080516080810182527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000841680825260ff808b1660208401908152600184860181815263ffffffff808d166060880190815260038054948501815560005296517fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b90930180549451925197519091167a010000000000000000000000000000000000000000000000000000027fffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffff97151579010000000000000000000000000000000000000000000000000002979097167fffff0000000000ffffffffffffffffffffffffffffffffffffffffffffffffff929095167801000000000000000000000000000000000000000000000000027fffffffffffffff0000000000000000000000000000000000000000000000000090941692881c929092179290921791909116919091179290921790915590517f2d763a674a99583454a287d792819ffb9ff7e791c23e7745a082701136ce336c906120d9908b908b908b90613371565b60405180910390a25050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361216a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f4565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000805b82518110156122865760006121fa826001612d88565b90505b835181101561227d5783818151811061221857612218612d9b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1684838151811061224857612248612d9b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603612275575060019392505050565b6001016121fd565b506001016121e4565b50600092915050565b600080828060200190518101906122a691906133dd565b63ffffffff1695945050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091526003545b80156124335761231081613420565b9050836003828154811061232657612326612d9b565b6000918252602090912001547a010000000000000000000000000000000000000000000000000000900463ffffffff161161242e576003818154811061236e5761236e612d9b565b600091825260209182902060408051608081018252929091015480821b7fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001683527801000000000000000000000000000000000000000000000000810460ff9081169484019490945279010000000000000000000000000000000000000000000000000081049093161515908201527a01000000000000000000000000000000000000000000000000000090910463ffffffff1660608201529150612433565b612301565b5092915050565b818180820361244a575050505050565b60008560026124598787613455565b6124639190613475565b61246d9087613504565b8151811061247d5761247d612d9b565b602002602001015190505b8183136125fc575b8073ffffffffffffffffffffffffffffffffffffffff168684815181106124b9576124b9612d9b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610156124ef57826124e78161352c565b935050612490565b85828151811061250157612501612d9b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16101561254e57816125468161355d565b9250506124ef565b8183136125f75785828151811061256757612567612d9b565b602002602001015186848151811061258157612581612d9b565b602002602001015187858151811061259b5761259b612d9b565b602002602001018885815181106125b4576125b4612d9b565b73ffffffffffffffffffffffffffffffffffffffff938416602091820292909201015291169052826125e58161352c565b93505081806125f39061355d565b9250505b612488565b8185121561260f5761260f86868461243a565b838312156114a3576114a386848661243a565b60006020828403121561263457600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461266457600080fd5b9392505050565b6000815180845260005b8181101561269157602081850181015186830182015201612675565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000612664602083018461266b565b60008083601f8401126126f457600080fd5b50813567ffffffffffffffff81111561270c57600080fd5b60208301915083602082850101111561272457600080fd5b9250929050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461274f57600080fd5b919050565b60008060008060006060868803121561276c57600080fd5b853567ffffffffffffffff8082111561278457600080fd5b61279089838a016126e2565b909750955060208801359150808211156127a957600080fd5b506127b6888289016126e2565b90945092506127c990506040870161272b565b90509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612827576128276127d5565b60405290565b6040516060810167ffffffffffffffff81118282101715612827576128276127d5565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612897576128976127d5565b604052919050565b600067ffffffffffffffff8211156128b9576128b96127d5565b5060051b60200190565b600082601f8301126128d457600080fd5b813560206128e96128e48361289f565b612850565b82815260059290921b8401810191818101908684111561290857600080fd5b8286015b8481101561292a5761291d8161272b565b835291830191830161290c565b509695505050505050565b803560ff8116811461274f57600080fd5b600082601f83011261295757600080fd5b813560206129676128e48361289f565b82815260069290921b8401810191818101908684111561298657600080fd5b8286015b8481101561292a57604081890312156129a35760008081fd5b6129ab612804565b6129b48261272b565b81528482013567ffffffffffffffff811681146129d15760008081fd5b8186015283529183019160400161298a565b6000806000606084860312156129f857600080fd5b833567ffffffffffffffff80821115612a1057600080fd5b612a1c878388016128c3565b9450612a2a60208701612935565b93506040860135915080821115612a4057600080fd5b50612a4d86828701612946565b9150509250925092565b600060208284031215612a6957600080fd5b6126648261272b565b80151581146113ea57600080fd5b60008060408385031215612a9357600080fd5b823591506020830135612aa581612a72565b809150509250929050565b600080600080600060608688031215612ac857600080fd5b853567ffffffffffffffff80821115612ae057600080fd5b818801915088601f830112612af457600080fd5b813581811115612b0357600080fd5b8960208260051b8501011115612b1857600080fd5b6020928301975095509087013590808211156127a957600080fd5b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612ba6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452612b9485835161266b565b94509285019290850190600101612b5a565b5092979650505050505050565b63ffffffff811681146113ea57600080fd5b60008060008060808587031215612bdb57600080fd5b843567ffffffffffffffff80821115612bf357600080fd5b612bff888389016128c3565b9550612c0d60208801612935565b94506040870135915080821115612c2357600080fd5b50612c3087828801612946565b9250506060850135612c4181612bb3565b939692955090935050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff84168152604060208201526000612cc5604083018486612c4c565b95945050505050565b600060208284031215612ce057600080fd5b815161266481612a72565b868152608060208201526000612d05608083018789612c4c565b8281036040840152612d18818688612c4c565b91505073ffffffffffffffffffffffffffffffffffffffff83166060830152979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761062057610620612d42565b8082018082111561062057610620612d42565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561062057610620612d42565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612e4157600080fd5b83018035915067ffffffffffffffff821115612e5c57600080fd5b60200191503681900382131561272457600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612ea257612ea2612d42565b5060010190565b6080808252875190820181905260009060209060a0840190828b01845b82811015612ee257815184529284019290840190600101612ec6565b50505083810382850152878152818101600589901b820183018a60005b8b811015612faa577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085840301845281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18e3603018112612f6057600080fd5b8d01868101903567ffffffffffffffff811115612f7c57600080fd5b803603821315612f8b57600080fd5b612f96858284612c4c565b958801959450505090850190600101612eff565b50508581036040870152612fbf81898b612c4c565b945050505050612fe7606083018473ffffffffffffffffffffffffffffffffffffffff169052565b979650505050505050565b600082601f83011261300357600080fd5b813567ffffffffffffffff81111561301d5761301d6127d5565b61304e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612850565b81815284602083860101111561306357600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261309157600080fd5b813560206130a16128e48361289f565b82815260059290921b840181019181810190868411156130c057600080fd5b8286015b8481101561292a57803583529183019183016130c4565b600080600080600060e086880312156130f357600080fd5b86601f87011261310257600080fd5b61310a61282d565b80606088018981111561311c57600080fd5b885b8181101561313657803584526020938401930161311e565b5090965035905067ffffffffffffffff8082111561315357600080fd5b61315f89838a01612ff2565b9550608088013591508082111561317557600080fd5b61318189838a01613080565b945060a088013591508082111561319757600080fd5b506131a488828901613080565b9598949750929560c001359392505050565b828152600060208083018460005b60038110156131e1578151835291830191908301906001016131c4565b505050506080820190509392505050565b60ff818116838216019081111561062057610620612d42565b8051602080830151919081101561324a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b825160009082906020808701845b8381101561329057815173ffffffffffffffffffffffffffffffffffffffff168552938201939082019060010161325e565b5050505060f89390931b7fff000000000000000000000000000000000000000000000000000000000000001683525050600101919050565b600081518084526020808501945080840160005b83811015613323578151805173ffffffffffffffffffffffffffffffffffffffff16885283015167ffffffffffffffff1683880152604090960195908201906001016132dc565b509495945050505050565b7fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000008316815260406020820152600061336960408301846132c8565b949350505050565b606080825284519082018190526000906020906080840190828801845b828110156133c057815173ffffffffffffffffffffffffffffffffffffffff168452928401929084019060010161338e565b50505060ff8616828501528381036040850152612fe781866132c8565b6000806000606084860312156133f257600080fd5b83519250602084015161340481612bb3565b604085015190925061341581612bb3565b809150509250925092565b60008161342f5761342f612d42565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b818103600083128015838313168383128216171561243357612433612d42565b6000826134ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156134ff576134ff612d42565b500590565b808201828112600083128015821682158216171561352457613524612d42565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612ea257612ea2612d42565b60007f8000000000000000000000000000000000000000000000000000000000000000820361342f5761342f612d4256fea164736f6c6343000813000a", +} + +var DestinationVerifierABI = DestinationVerifierMetaData.ABI + +var DestinationVerifierBin = DestinationVerifierMetaData.Bin + +func DeployDestinationVerifier(auth *bind.TransactOpts, backend bind.ContractBackend, verifierProxy common.Address) (common.Address, *types.Transaction, *DestinationVerifier, error) { + parsed, err := DestinationVerifierMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DestinationVerifierBin), backend, verifierProxy) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &DestinationVerifier{address: address, abi: *parsed, DestinationVerifierCaller: DestinationVerifierCaller{contract: contract}, DestinationVerifierTransactor: DestinationVerifierTransactor{contract: contract}, DestinationVerifierFilterer: DestinationVerifierFilterer{contract: contract}}, nil +} + +type DestinationVerifier struct { + address common.Address + abi abi.ABI + DestinationVerifierCaller + DestinationVerifierTransactor + DestinationVerifierFilterer +} + +type DestinationVerifierCaller struct { + contract *bind.BoundContract +} + +type DestinationVerifierTransactor struct { + contract *bind.BoundContract +} + +type DestinationVerifierFilterer struct { + contract *bind.BoundContract +} + +type DestinationVerifierSession struct { + Contract *DestinationVerifier + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type DestinationVerifierCallerSession struct { + Contract *DestinationVerifierCaller + CallOpts bind.CallOpts +} + +type DestinationVerifierTransactorSession struct { + Contract *DestinationVerifierTransactor + TransactOpts bind.TransactOpts +} + +type DestinationVerifierRaw struct { + Contract *DestinationVerifier +} + +type DestinationVerifierCallerRaw struct { + Contract *DestinationVerifierCaller +} + +type DestinationVerifierTransactorRaw struct { + Contract *DestinationVerifierTransactor +} + +func NewDestinationVerifier(address common.Address, backend bind.ContractBackend) (*DestinationVerifier, error) { + abi, err := abi.JSON(strings.NewReader(DestinationVerifierABI)) + if err != nil { + return nil, err + } + contract, err := bindDestinationVerifier(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &DestinationVerifier{address: address, abi: abi, DestinationVerifierCaller: DestinationVerifierCaller{contract: contract}, DestinationVerifierTransactor: DestinationVerifierTransactor{contract: contract}, DestinationVerifierFilterer: DestinationVerifierFilterer{contract: contract}}, nil +} + +func NewDestinationVerifierCaller(address common.Address, caller bind.ContractCaller) (*DestinationVerifierCaller, error) { + contract, err := bindDestinationVerifier(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &DestinationVerifierCaller{contract: contract}, nil +} + +func NewDestinationVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*DestinationVerifierTransactor, error) { + contract, err := bindDestinationVerifier(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &DestinationVerifierTransactor{contract: contract}, nil +} + +func NewDestinationVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*DestinationVerifierFilterer, error) { + contract, err := bindDestinationVerifier(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &DestinationVerifierFilterer{contract: contract}, nil +} + +func bindDestinationVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := DestinationVerifierMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_DestinationVerifier *DestinationVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DestinationVerifier.Contract.DestinationVerifierCaller.contract.Call(opts, result, method, params...) +} + +func (_DestinationVerifier *DestinationVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationVerifier.Contract.DestinationVerifierTransactor.contract.Transfer(opts) +} + +func (_DestinationVerifier *DestinationVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DestinationVerifier.Contract.DestinationVerifierTransactor.contract.Transact(opts, method, params...) +} + +func (_DestinationVerifier *DestinationVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DestinationVerifier.Contract.contract.Call(opts, result, method, params...) +} + +func (_DestinationVerifier *DestinationVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationVerifier.Contract.contract.Transfer(opts) +} + +func (_DestinationVerifier *DestinationVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DestinationVerifier.Contract.contract.Transact(opts, method, params...) +} + +func (_DestinationVerifier *DestinationVerifierCaller) IVerifierProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationVerifier.contract.Call(opts, &out, "i_verifierProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationVerifier *DestinationVerifierSession) IVerifierProxy() (common.Address, error) { + return _DestinationVerifier.Contract.IVerifierProxy(&_DestinationVerifier.CallOpts) +} + +func (_DestinationVerifier *DestinationVerifierCallerSession) IVerifierProxy() (common.Address, error) { + return _DestinationVerifier.Contract.IVerifierProxy(&_DestinationVerifier.CallOpts) +} + +func (_DestinationVerifier *DestinationVerifierCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationVerifier.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationVerifier *DestinationVerifierSession) Owner() (common.Address, error) { + return _DestinationVerifier.Contract.Owner(&_DestinationVerifier.CallOpts) +} + +func (_DestinationVerifier *DestinationVerifierCallerSession) Owner() (common.Address, error) { + return _DestinationVerifier.Contract.Owner(&_DestinationVerifier.CallOpts) +} + +func (_DestinationVerifier *DestinationVerifierCaller) SAccessController(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationVerifier.contract.Call(opts, &out, "s_accessController") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationVerifier *DestinationVerifierSession) SAccessController() (common.Address, error) { + return _DestinationVerifier.Contract.SAccessController(&_DestinationVerifier.CallOpts) +} + +func (_DestinationVerifier *DestinationVerifierCallerSession) SAccessController() (common.Address, error) { + return _DestinationVerifier.Contract.SAccessController(&_DestinationVerifier.CallOpts) +} + +func (_DestinationVerifier *DestinationVerifierCaller) SFeeManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationVerifier.contract.Call(opts, &out, "s_feeManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationVerifier *DestinationVerifierSession) SFeeManager() (common.Address, error) { + return _DestinationVerifier.Contract.SFeeManager(&_DestinationVerifier.CallOpts) +} + +func (_DestinationVerifier *DestinationVerifierCallerSession) SFeeManager() (common.Address, error) { + return _DestinationVerifier.Contract.SFeeManager(&_DestinationVerifier.CallOpts) +} + +func (_DestinationVerifier *DestinationVerifierCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _DestinationVerifier.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_DestinationVerifier *DestinationVerifierSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _DestinationVerifier.Contract.SupportsInterface(&_DestinationVerifier.CallOpts, interfaceId) +} + +func (_DestinationVerifier *DestinationVerifierCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _DestinationVerifier.Contract.SupportsInterface(&_DestinationVerifier.CallOpts, interfaceId) +} + +func (_DestinationVerifier *DestinationVerifierCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _DestinationVerifier.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_DestinationVerifier *DestinationVerifierSession) TypeAndVersion() (string, error) { + return _DestinationVerifier.Contract.TypeAndVersion(&_DestinationVerifier.CallOpts) +} + +func (_DestinationVerifier *DestinationVerifierCallerSession) TypeAndVersion() (string, error) { + return _DestinationVerifier.Contract.TypeAndVersion(&_DestinationVerifier.CallOpts) +} + +func (_DestinationVerifier *DestinationVerifierTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationVerifier.contract.Transact(opts, "acceptOwnership") +} + +func (_DestinationVerifier *DestinationVerifierSession) AcceptOwnership() (*types.Transaction, error) { + return _DestinationVerifier.Contract.AcceptOwnership(&_DestinationVerifier.TransactOpts) +} + +func (_DestinationVerifier *DestinationVerifierTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _DestinationVerifier.Contract.AcceptOwnership(&_DestinationVerifier.TransactOpts) +} + +func (_DestinationVerifier *DestinationVerifierTransactor) RemoveLatestConfig(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationVerifier.contract.Transact(opts, "removeLatestConfig") +} + +func (_DestinationVerifier *DestinationVerifierSession) RemoveLatestConfig() (*types.Transaction, error) { + return _DestinationVerifier.Contract.RemoveLatestConfig(&_DestinationVerifier.TransactOpts) +} + +func (_DestinationVerifier *DestinationVerifierTransactorSession) RemoveLatestConfig() (*types.Transaction, error) { + return _DestinationVerifier.Contract.RemoveLatestConfig(&_DestinationVerifier.TransactOpts) +} + +func (_DestinationVerifier *DestinationVerifierTransactor) SetAccessController(opts *bind.TransactOpts, accessController common.Address) (*types.Transaction, error) { + return _DestinationVerifier.contract.Transact(opts, "setAccessController", accessController) +} + +func (_DestinationVerifier *DestinationVerifierSession) SetAccessController(accessController common.Address) (*types.Transaction, error) { + return _DestinationVerifier.Contract.SetAccessController(&_DestinationVerifier.TransactOpts, accessController) +} + +func (_DestinationVerifier *DestinationVerifierTransactorSession) SetAccessController(accessController common.Address) (*types.Transaction, error) { + return _DestinationVerifier.Contract.SetAccessController(&_DestinationVerifier.TransactOpts, accessController) +} + +func (_DestinationVerifier *DestinationVerifierTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, f uint8, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _DestinationVerifier.contract.Transact(opts, "setConfig", signers, f, recipientAddressesAndWeights) +} + +func (_DestinationVerifier *DestinationVerifierSession) SetConfig(signers []common.Address, f uint8, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _DestinationVerifier.Contract.SetConfig(&_DestinationVerifier.TransactOpts, signers, f, recipientAddressesAndWeights) +} + +func (_DestinationVerifier *DestinationVerifierTransactorSession) SetConfig(signers []common.Address, f uint8, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _DestinationVerifier.Contract.SetConfig(&_DestinationVerifier.TransactOpts, signers, f, recipientAddressesAndWeights) +} + +func (_DestinationVerifier *DestinationVerifierTransactor) SetConfigActive(opts *bind.TransactOpts, donConfigIndex *big.Int, isActive bool) (*types.Transaction, error) { + return _DestinationVerifier.contract.Transact(opts, "setConfigActive", donConfigIndex, isActive) +} + +func (_DestinationVerifier *DestinationVerifierSession) SetConfigActive(donConfigIndex *big.Int, isActive bool) (*types.Transaction, error) { + return _DestinationVerifier.Contract.SetConfigActive(&_DestinationVerifier.TransactOpts, donConfigIndex, isActive) +} + +func (_DestinationVerifier *DestinationVerifierTransactorSession) SetConfigActive(donConfigIndex *big.Int, isActive bool) (*types.Transaction, error) { + return _DestinationVerifier.Contract.SetConfigActive(&_DestinationVerifier.TransactOpts, donConfigIndex, isActive) +} + +func (_DestinationVerifier *DestinationVerifierTransactor) SetConfigWithActivationTime(opts *bind.TransactOpts, signers []common.Address, f uint8, recipientAddressesAndWeights []CommonAddressAndWeight, activationTime uint32) (*types.Transaction, error) { + return _DestinationVerifier.contract.Transact(opts, "setConfigWithActivationTime", signers, f, recipientAddressesAndWeights, activationTime) +} + +func (_DestinationVerifier *DestinationVerifierSession) SetConfigWithActivationTime(signers []common.Address, f uint8, recipientAddressesAndWeights []CommonAddressAndWeight, activationTime uint32) (*types.Transaction, error) { + return _DestinationVerifier.Contract.SetConfigWithActivationTime(&_DestinationVerifier.TransactOpts, signers, f, recipientAddressesAndWeights, activationTime) +} + +func (_DestinationVerifier *DestinationVerifierTransactorSession) SetConfigWithActivationTime(signers []common.Address, f uint8, recipientAddressesAndWeights []CommonAddressAndWeight, activationTime uint32) (*types.Transaction, error) { + return _DestinationVerifier.Contract.SetConfigWithActivationTime(&_DestinationVerifier.TransactOpts, signers, f, recipientAddressesAndWeights, activationTime) +} + +func (_DestinationVerifier *DestinationVerifierTransactor) SetFeeManager(opts *bind.TransactOpts, feeManager common.Address) (*types.Transaction, error) { + return _DestinationVerifier.contract.Transact(opts, "setFeeManager", feeManager) +} + +func (_DestinationVerifier *DestinationVerifierSession) SetFeeManager(feeManager common.Address) (*types.Transaction, error) { + return _DestinationVerifier.Contract.SetFeeManager(&_DestinationVerifier.TransactOpts, feeManager) +} + +func (_DestinationVerifier *DestinationVerifierTransactorSession) SetFeeManager(feeManager common.Address) (*types.Transaction, error) { + return _DestinationVerifier.Contract.SetFeeManager(&_DestinationVerifier.TransactOpts, feeManager) +} + +func (_DestinationVerifier *DestinationVerifierTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _DestinationVerifier.contract.Transact(opts, "transferOwnership", to) +} + +func (_DestinationVerifier *DestinationVerifierSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _DestinationVerifier.Contract.TransferOwnership(&_DestinationVerifier.TransactOpts, to) +} + +func (_DestinationVerifier *DestinationVerifierTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _DestinationVerifier.Contract.TransferOwnership(&_DestinationVerifier.TransactOpts, to) +} + +func (_DestinationVerifier *DestinationVerifierTransactor) Verify(opts *bind.TransactOpts, signedReport []byte, parameterPayload []byte, sender common.Address) (*types.Transaction, error) { + return _DestinationVerifier.contract.Transact(opts, "verify", signedReport, parameterPayload, sender) +} + +func (_DestinationVerifier *DestinationVerifierSession) Verify(signedReport []byte, parameterPayload []byte, sender common.Address) (*types.Transaction, error) { + return _DestinationVerifier.Contract.Verify(&_DestinationVerifier.TransactOpts, signedReport, parameterPayload, sender) +} + +func (_DestinationVerifier *DestinationVerifierTransactorSession) Verify(signedReport []byte, parameterPayload []byte, sender common.Address) (*types.Transaction, error) { + return _DestinationVerifier.Contract.Verify(&_DestinationVerifier.TransactOpts, signedReport, parameterPayload, sender) +} + +func (_DestinationVerifier *DestinationVerifierTransactor) VerifyBulk(opts *bind.TransactOpts, signedReports [][]byte, parameterPayload []byte, sender common.Address) (*types.Transaction, error) { + return _DestinationVerifier.contract.Transact(opts, "verifyBulk", signedReports, parameterPayload, sender) +} + +func (_DestinationVerifier *DestinationVerifierSession) VerifyBulk(signedReports [][]byte, parameterPayload []byte, sender common.Address) (*types.Transaction, error) { + return _DestinationVerifier.Contract.VerifyBulk(&_DestinationVerifier.TransactOpts, signedReports, parameterPayload, sender) +} + +func (_DestinationVerifier *DestinationVerifierTransactorSession) VerifyBulk(signedReports [][]byte, parameterPayload []byte, sender common.Address) (*types.Transaction, error) { + return _DestinationVerifier.Contract.VerifyBulk(&_DestinationVerifier.TransactOpts, signedReports, parameterPayload, sender) +} + +type DestinationVerifierAccessControllerSetIterator struct { + Event *DestinationVerifierAccessControllerSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationVerifierAccessControllerSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierAccessControllerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierAccessControllerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationVerifierAccessControllerSetIterator) Error() error { + return it.fail +} + +func (it *DestinationVerifierAccessControllerSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationVerifierAccessControllerSet struct { + OldAccessController common.Address + NewAccessController common.Address + Raw types.Log +} + +func (_DestinationVerifier *DestinationVerifierFilterer) FilterAccessControllerSet(opts *bind.FilterOpts) (*DestinationVerifierAccessControllerSetIterator, error) { + + logs, sub, err := _DestinationVerifier.contract.FilterLogs(opts, "AccessControllerSet") + if err != nil { + return nil, err + } + return &DestinationVerifierAccessControllerSetIterator{contract: _DestinationVerifier.contract, event: "AccessControllerSet", logs: logs, sub: sub}, nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) WatchAccessControllerSet(opts *bind.WatchOpts, sink chan<- *DestinationVerifierAccessControllerSet) (event.Subscription, error) { + + logs, sub, err := _DestinationVerifier.contract.WatchLogs(opts, "AccessControllerSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationVerifierAccessControllerSet) + if err := _DestinationVerifier.contract.UnpackLog(event, "AccessControllerSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) ParseAccessControllerSet(log types.Log) (*DestinationVerifierAccessControllerSet, error) { + event := new(DestinationVerifierAccessControllerSet) + if err := _DestinationVerifier.contract.UnpackLog(event, "AccessControllerSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationVerifierConfigActivatedIterator struct { + Event *DestinationVerifierConfigActivated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationVerifierConfigActivatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierConfigActivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierConfigActivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationVerifierConfigActivatedIterator) Error() error { + return it.fail +} + +func (it *DestinationVerifierConfigActivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationVerifierConfigActivated struct { + DonConfigId [24]byte + IsActive bool + Raw types.Log +} + +func (_DestinationVerifier *DestinationVerifierFilterer) FilterConfigActivated(opts *bind.FilterOpts) (*DestinationVerifierConfigActivatedIterator, error) { + + logs, sub, err := _DestinationVerifier.contract.FilterLogs(opts, "ConfigActivated") + if err != nil { + return nil, err + } + return &DestinationVerifierConfigActivatedIterator{contract: _DestinationVerifier.contract, event: "ConfigActivated", logs: logs, sub: sub}, nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) WatchConfigActivated(opts *bind.WatchOpts, sink chan<- *DestinationVerifierConfigActivated) (event.Subscription, error) { + + logs, sub, err := _DestinationVerifier.contract.WatchLogs(opts, "ConfigActivated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationVerifierConfigActivated) + if err := _DestinationVerifier.contract.UnpackLog(event, "ConfigActivated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) ParseConfigActivated(log types.Log) (*DestinationVerifierConfigActivated, error) { + event := new(DestinationVerifierConfigActivated) + if err := _DestinationVerifier.contract.UnpackLog(event, "ConfigActivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationVerifierConfigRemovedIterator struct { + Event *DestinationVerifierConfigRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationVerifierConfigRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierConfigRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierConfigRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationVerifierConfigRemovedIterator) Error() error { + return it.fail +} + +func (it *DestinationVerifierConfigRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationVerifierConfigRemoved struct { + DonConfigId [24]byte + Raw types.Log +} + +func (_DestinationVerifier *DestinationVerifierFilterer) FilterConfigRemoved(opts *bind.FilterOpts) (*DestinationVerifierConfigRemovedIterator, error) { + + logs, sub, err := _DestinationVerifier.contract.FilterLogs(opts, "ConfigRemoved") + if err != nil { + return nil, err + } + return &DestinationVerifierConfigRemovedIterator{contract: _DestinationVerifier.contract, event: "ConfigRemoved", logs: logs, sub: sub}, nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) WatchConfigRemoved(opts *bind.WatchOpts, sink chan<- *DestinationVerifierConfigRemoved) (event.Subscription, error) { + + logs, sub, err := _DestinationVerifier.contract.WatchLogs(opts, "ConfigRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationVerifierConfigRemoved) + if err := _DestinationVerifier.contract.UnpackLog(event, "ConfigRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) ParseConfigRemoved(log types.Log) (*DestinationVerifierConfigRemoved, error) { + event := new(DestinationVerifierConfigRemoved) + if err := _DestinationVerifier.contract.UnpackLog(event, "ConfigRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationVerifierConfigSetIterator struct { + Event *DestinationVerifierConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationVerifierConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationVerifierConfigSetIterator) Error() error { + return it.fail +} + +func (it *DestinationVerifierConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationVerifierConfigSet struct { + DonConfigId [24]byte + Signers []common.Address + F uint8 + RecipientAddressesAndWeights []CommonAddressAndWeight + Raw types.Log +} + +func (_DestinationVerifier *DestinationVerifierFilterer) FilterConfigSet(opts *bind.FilterOpts, donConfigId [][24]byte) (*DestinationVerifierConfigSetIterator, error) { + + var donConfigIdRule []interface{} + for _, donConfigIdItem := range donConfigId { + donConfigIdRule = append(donConfigIdRule, donConfigIdItem) + } + + logs, sub, err := _DestinationVerifier.contract.FilterLogs(opts, "ConfigSet", donConfigIdRule) + if err != nil { + return nil, err + } + return &DestinationVerifierConfigSetIterator{contract: _DestinationVerifier.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *DestinationVerifierConfigSet, donConfigId [][24]byte) (event.Subscription, error) { + + var donConfigIdRule []interface{} + for _, donConfigIdItem := range donConfigId { + donConfigIdRule = append(donConfigIdRule, donConfigIdItem) + } + + logs, sub, err := _DestinationVerifier.contract.WatchLogs(opts, "ConfigSet", donConfigIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationVerifierConfigSet) + if err := _DestinationVerifier.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) ParseConfigSet(log types.Log) (*DestinationVerifierConfigSet, error) { + event := new(DestinationVerifierConfigSet) + if err := _DestinationVerifier.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationVerifierFeeManagerSetIterator struct { + Event *DestinationVerifierFeeManagerSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationVerifierFeeManagerSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierFeeManagerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierFeeManagerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationVerifierFeeManagerSetIterator) Error() error { + return it.fail +} + +func (it *DestinationVerifierFeeManagerSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationVerifierFeeManagerSet struct { + OldFeeManager common.Address + NewFeeManager common.Address + Raw types.Log +} + +func (_DestinationVerifier *DestinationVerifierFilterer) FilterFeeManagerSet(opts *bind.FilterOpts) (*DestinationVerifierFeeManagerSetIterator, error) { + + logs, sub, err := _DestinationVerifier.contract.FilterLogs(opts, "FeeManagerSet") + if err != nil { + return nil, err + } + return &DestinationVerifierFeeManagerSetIterator{contract: _DestinationVerifier.contract, event: "FeeManagerSet", logs: logs, sub: sub}, nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) WatchFeeManagerSet(opts *bind.WatchOpts, sink chan<- *DestinationVerifierFeeManagerSet) (event.Subscription, error) { + + logs, sub, err := _DestinationVerifier.contract.WatchLogs(opts, "FeeManagerSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationVerifierFeeManagerSet) + if err := _DestinationVerifier.contract.UnpackLog(event, "FeeManagerSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) ParseFeeManagerSet(log types.Log) (*DestinationVerifierFeeManagerSet, error) { + event := new(DestinationVerifierFeeManagerSet) + if err := _DestinationVerifier.contract.UnpackLog(event, "FeeManagerSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationVerifierOwnershipTransferRequestedIterator struct { + Event *DestinationVerifierOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationVerifierOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationVerifierOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *DestinationVerifierOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationVerifierOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_DestinationVerifier *DestinationVerifierFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationVerifierOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationVerifier.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &DestinationVerifierOwnershipTransferRequestedIterator{contract: _DestinationVerifier.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *DestinationVerifierOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationVerifier.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationVerifierOwnershipTransferRequested) + if err := _DestinationVerifier.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) ParseOwnershipTransferRequested(log types.Log) (*DestinationVerifierOwnershipTransferRequested, error) { + event := new(DestinationVerifierOwnershipTransferRequested) + if err := _DestinationVerifier.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationVerifierOwnershipTransferredIterator struct { + Event *DestinationVerifierOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationVerifierOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationVerifierOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *DestinationVerifierOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationVerifierOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_DestinationVerifier *DestinationVerifierFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationVerifierOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationVerifier.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &DestinationVerifierOwnershipTransferredIterator{contract: _DestinationVerifier.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DestinationVerifierOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationVerifier.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationVerifierOwnershipTransferred) + if err := _DestinationVerifier.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) ParseOwnershipTransferred(log types.Log) (*DestinationVerifierOwnershipTransferred, error) { + event := new(DestinationVerifierOwnershipTransferred) + if err := _DestinationVerifier.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationVerifierReportVerifiedIterator struct { + Event *DestinationVerifierReportVerified + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationVerifierReportVerifiedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierReportVerified) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierReportVerified) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationVerifierReportVerifiedIterator) Error() error { + return it.fail +} + +func (it *DestinationVerifierReportVerifiedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationVerifierReportVerified struct { + FeedId [32]byte + Requester common.Address + Raw types.Log +} + +func (_DestinationVerifier *DestinationVerifierFilterer) FilterReportVerified(opts *bind.FilterOpts, feedId [][32]byte) (*DestinationVerifierReportVerifiedIterator, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _DestinationVerifier.contract.FilterLogs(opts, "ReportVerified", feedIdRule) + if err != nil { + return nil, err + } + return &DestinationVerifierReportVerifiedIterator{contract: _DestinationVerifier.contract, event: "ReportVerified", logs: logs, sub: sub}, nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) WatchReportVerified(opts *bind.WatchOpts, sink chan<- *DestinationVerifierReportVerified, feedId [][32]byte) (event.Subscription, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _DestinationVerifier.contract.WatchLogs(opts, "ReportVerified", feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationVerifierReportVerified) + if err := _DestinationVerifier.contract.UnpackLog(event, "ReportVerified", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationVerifier *DestinationVerifierFilterer) ParseReportVerified(log types.Log) (*DestinationVerifierReportVerified, error) { + event := new(DestinationVerifierReportVerified) + if err := _DestinationVerifier.contract.UnpackLog(event, "ReportVerified", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_DestinationVerifier *DestinationVerifier) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _DestinationVerifier.abi.Events["AccessControllerSet"].ID: + return _DestinationVerifier.ParseAccessControllerSet(log) + case _DestinationVerifier.abi.Events["ConfigActivated"].ID: + return _DestinationVerifier.ParseConfigActivated(log) + case _DestinationVerifier.abi.Events["ConfigRemoved"].ID: + return _DestinationVerifier.ParseConfigRemoved(log) + case _DestinationVerifier.abi.Events["ConfigSet"].ID: + return _DestinationVerifier.ParseConfigSet(log) + case _DestinationVerifier.abi.Events["FeeManagerSet"].ID: + return _DestinationVerifier.ParseFeeManagerSet(log) + case _DestinationVerifier.abi.Events["OwnershipTransferRequested"].ID: + return _DestinationVerifier.ParseOwnershipTransferRequested(log) + case _DestinationVerifier.abi.Events["OwnershipTransferred"].ID: + return _DestinationVerifier.ParseOwnershipTransferred(log) + case _DestinationVerifier.abi.Events["ReportVerified"].ID: + return _DestinationVerifier.ParseReportVerified(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (DestinationVerifierAccessControllerSet) Topic() common.Hash { + return common.HexToHash("0x953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b6") +} + +func (DestinationVerifierConfigActivated) Topic() common.Hash { + return common.HexToHash("0x90186a1e77b498ec417ea88bd026cae00d7043c357cc45221777623bda582dd4") +} + +func (DestinationVerifierConfigRemoved) Topic() common.Hash { + return common.HexToHash("0x970fd8f3ebdd9a271080aacf9807a5c709be0b448e4047a6fc212b8cc165368d") +} + +func (DestinationVerifierConfigSet) Topic() common.Hash { + return common.HexToHash("0x2d763a674a99583454a287d792819ffb9ff7e791c23e7745a082701136ce336c") +} + +func (DestinationVerifierFeeManagerSet) Topic() common.Hash { + return common.HexToHash("0x04628abcaa6b1674651352125cb94b65b289145bc2bc4d67720bb7d966372f03") +} + +func (DestinationVerifierOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (DestinationVerifierOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (DestinationVerifierReportVerified) Topic() common.Hash { + return common.HexToHash("0x58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc5") +} + +func (_DestinationVerifier *DestinationVerifier) Address() common.Address { + return _DestinationVerifier.address +} + +type DestinationVerifierInterface interface { + IVerifierProxy(opts *bind.CallOpts) (common.Address, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SAccessController(opts *bind.CallOpts) (common.Address, error) + + SFeeManager(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + RemoveLatestConfig(opts *bind.TransactOpts) (*types.Transaction, error) + + SetAccessController(opts *bind.TransactOpts, accessController common.Address) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, signers []common.Address, f uint8, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + SetConfigActive(opts *bind.TransactOpts, donConfigIndex *big.Int, isActive bool) (*types.Transaction, error) + + SetConfigWithActivationTime(opts *bind.TransactOpts, signers []common.Address, f uint8, recipientAddressesAndWeights []CommonAddressAndWeight, activationTime uint32) (*types.Transaction, error) + + SetFeeManager(opts *bind.TransactOpts, feeManager common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Verify(opts *bind.TransactOpts, signedReport []byte, parameterPayload []byte, sender common.Address) (*types.Transaction, error) + + VerifyBulk(opts *bind.TransactOpts, signedReports [][]byte, parameterPayload []byte, sender common.Address) (*types.Transaction, error) + + FilterAccessControllerSet(opts *bind.FilterOpts) (*DestinationVerifierAccessControllerSetIterator, error) + + WatchAccessControllerSet(opts *bind.WatchOpts, sink chan<- *DestinationVerifierAccessControllerSet) (event.Subscription, error) + + ParseAccessControllerSet(log types.Log) (*DestinationVerifierAccessControllerSet, error) + + FilterConfigActivated(opts *bind.FilterOpts) (*DestinationVerifierConfigActivatedIterator, error) + + WatchConfigActivated(opts *bind.WatchOpts, sink chan<- *DestinationVerifierConfigActivated) (event.Subscription, error) + + ParseConfigActivated(log types.Log) (*DestinationVerifierConfigActivated, error) + + FilterConfigRemoved(opts *bind.FilterOpts) (*DestinationVerifierConfigRemovedIterator, error) + + WatchConfigRemoved(opts *bind.WatchOpts, sink chan<- *DestinationVerifierConfigRemoved) (event.Subscription, error) + + ParseConfigRemoved(log types.Log) (*DestinationVerifierConfigRemoved, error) + + FilterConfigSet(opts *bind.FilterOpts, donConfigId [][24]byte) (*DestinationVerifierConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *DestinationVerifierConfigSet, donConfigId [][24]byte) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*DestinationVerifierConfigSet, error) + + FilterFeeManagerSet(opts *bind.FilterOpts) (*DestinationVerifierFeeManagerSetIterator, error) + + WatchFeeManagerSet(opts *bind.WatchOpts, sink chan<- *DestinationVerifierFeeManagerSet) (event.Subscription, error) + + ParseFeeManagerSet(log types.Log) (*DestinationVerifierFeeManagerSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationVerifierOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *DestinationVerifierOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*DestinationVerifierOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationVerifierOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DestinationVerifierOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*DestinationVerifierOwnershipTransferred, error) + + FilterReportVerified(opts *bind.FilterOpts, feedId [][32]byte) (*DestinationVerifierReportVerifiedIterator, error) + + WatchReportVerified(opts *bind.WatchOpts, sink chan<- *DestinationVerifierReportVerified, feedId [][32]byte) (event.Subscription, error) + + ParseReportVerified(log types.Log) (*DestinationVerifierReportVerified, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/destination_verifier_proxy/destination_verifier_proxy.go b/core/gethwrappers/llo-feeds/generated/destination_verifier_proxy/destination_verifier_proxy.go new file mode 100644 index 0000000000..a2ae546d9b --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/destination_verifier_proxy/destination_verifier_proxy.go @@ -0,0 +1,676 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package destination_verifier_proxy + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var DestinationVerifierProxyMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_accessController\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"setVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"}],\"name\":\"verifyBulk\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"verifiedReports\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61130b806101576000396000f3fe6080604052600436106100b15760003560e01c80638da5cb5b11610069578063f2fde38b1161004e578063f2fde38b146101eb578063f7e83aee1461020b578063f873a61c1461021e57600080fd5b80638da5cb5b146101ab57806394ba2846146101d657600080fd5b806338416b5b1161009a57806338416b5b1461013a5780635437988d1461017457806379ba50971461019657600080fd5b806301ffc9a7146100b6578063181f5a77146100eb575b600080fd5b3480156100c257600080fd5b506100d66100d1366004610c56565b61023e565b60405190151581526020015b60405180910390f35b3480156100f757600080fd5b5060408051808201909152601e81527f44657374696e6174696f6e566572696669657250726f787920312e302e30000060208201525b6040516100e29190610d0d565b34801561014657600080fd5b5061014f6103bb565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e2565b34801561018057600080fd5b5061019461018f366004610d42565b610454565b005b3480156101a257600080fd5b506101946107c8565b3480156101b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661014f565b3480156101e257600080fd5b5061014f6108c5565b3480156101f757600080fd5b50610194610206366004610d42565b610935565b61012d610219366004610da8565b610949565b61023161022c366004610e14565b610a18565b6040516100e29190610e95565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f5437988d0000000000000000000000000000000000000000000000000000000014806102d157507fffffffff0000000000000000000000000000000000000000000000000000000082167ff7e83aee00000000000000000000000000000000000000000000000000000000145b8061031d57507fffffffff0000000000000000000000000000000000000000000000000000000082167ff873a61c00000000000000000000000000000000000000000000000000000000145b8061036957507fffffffff0000000000000000000000000000000000000000000000000000000082167f38416b5b00000000000000000000000000000000000000000000000000000000145b806103b557507fffffffff0000000000000000000000000000000000000000000000000000000082167f94ba284600000000000000000000000000000000000000000000000000000000145b92915050565b600254604080517f38416b5b000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916338416b5b9160048083019260209291908290030181865afa15801561042b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061044f9190610f15565b905090565b61045c610ade565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f94ba284600000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156104e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050a9190610f32565b15806105c157506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f38416b5b00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa15801561059b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105bf9190610f32565b155b8061067757506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f294d2bb100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106759190610f32565b155b8061072d57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fd7c72e4e00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610707573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072b9190610f32565b155b15610781576040517f96ac86f300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024015b60405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610849576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610778565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600254604080517f94ba2846000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916394ba28469160048083019260209291908290030181865afa15801561042b573d6000803e3d6000fd5b61093d610ade565b61094681610b61565b50565b6002546040517f294d2bb100000000000000000000000000000000000000000000000000000000815260609173ffffffffffffffffffffffffffffffffffffffff169063294d2bb19034906109aa9089908990899089903390600401610f9d565b60006040518083038185885af11580156109c8573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a0f91908101906110f5565b95945050505050565b6002546040517fd7c72e4e00000000000000000000000000000000000000000000000000000000815260609173ffffffffffffffffffffffffffffffffffffffff169063d7c72e4e903490610a79908990899089908990339060040161112a565b60006040518083038185885af1158015610a97573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a0f919081019061123b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610778565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610be0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610778565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610c6857600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610c9857600080fd5b9392505050565b60005b83811015610cba578181015183820152602001610ca2565b50506000910152565b60008151808452610cdb816020860160208601610c9f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610c986020830184610cc3565b73ffffffffffffffffffffffffffffffffffffffff8116811461094657600080fd5b600060208284031215610d5457600080fd5b8135610c9881610d20565b60008083601f840112610d7157600080fd5b50813567ffffffffffffffff811115610d8957600080fd5b602083019150836020828501011115610da157600080fd5b9250929050565b60008060008060408587031215610dbe57600080fd5b843567ffffffffffffffff80821115610dd657600080fd5b610de288838901610d5f565b90965094506020870135915080821115610dfb57600080fd5b50610e0887828801610d5f565b95989497509550505050565b60008060008060408587031215610e2a57600080fd5b843567ffffffffffffffff80821115610e4257600080fd5b818701915087601f830112610e5657600080fd5b813581811115610e6557600080fd5b8860208260051b8501011115610e7a57600080fd5b602092830196509450908601359080821115610dfb57600080fd5b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015610f08577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452610ef6858351610cc3565b94509285019290850190600101610ebc565b5092979650505050505050565b600060208284031215610f2757600080fd5b8151610c9881610d20565b600060208284031215610f4457600080fd5b81518015158114610c9857600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000610fb1606083018789610f54565b8281036020840152610fc4818688610f54565b91505073ffffffffffffffffffffffffffffffffffffffff831660408301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561106357611063610fed565b604052919050565b600082601f83011261107c57600080fd5b815167ffffffffffffffff81111561109657611096610fed565b6110c760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161101c565b8181528460208386010111156110dc57600080fd5b6110ed826020830160208701610c9f565b949350505050565b60006020828403121561110757600080fd5b815167ffffffffffffffff81111561111e57600080fd5b6110ed8482850161106b565b6060808252810185905260006080600587901b8301810190830188835b898110156111f6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8086850301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18c36030181126111a857600080fd5b8b01602081810191359067ffffffffffffffff8211156111c757600080fd5b8136038313156111d657600080fd5b6111e1878385610f54565b96509485019493909301925050600101611147565b505050828103602084015261120c818688610f54565b915050611231604083018473ffffffffffffffffffffffffffffffffffffffff169052565b9695505050505050565b6000602080838503121561124e57600080fd5b825167ffffffffffffffff8082111561126657600080fd5b818501915085601f83011261127a57600080fd5b81518181111561128c5761128c610fed565b8060051b61129b85820161101c565b91825283810185019185810190898411156112b557600080fd5b86860192505b838310156112f1578251858111156112d35760008081fd5b6112e18b89838a010161106b565b83525091860191908601906112bb565b999850505050505050505056fea164736f6c6343000813000a", +} + +var DestinationVerifierProxyABI = DestinationVerifierProxyMetaData.ABI + +var DestinationVerifierProxyBin = DestinationVerifierProxyMetaData.Bin + +func DeployDestinationVerifierProxy(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *DestinationVerifierProxy, error) { + parsed, err := DestinationVerifierProxyMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DestinationVerifierProxyBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &DestinationVerifierProxy{address: address, abi: *parsed, DestinationVerifierProxyCaller: DestinationVerifierProxyCaller{contract: contract}, DestinationVerifierProxyTransactor: DestinationVerifierProxyTransactor{contract: contract}, DestinationVerifierProxyFilterer: DestinationVerifierProxyFilterer{contract: contract}}, nil +} + +type DestinationVerifierProxy struct { + address common.Address + abi abi.ABI + DestinationVerifierProxyCaller + DestinationVerifierProxyTransactor + DestinationVerifierProxyFilterer +} + +type DestinationVerifierProxyCaller struct { + contract *bind.BoundContract +} + +type DestinationVerifierProxyTransactor struct { + contract *bind.BoundContract +} + +type DestinationVerifierProxyFilterer struct { + contract *bind.BoundContract +} + +type DestinationVerifierProxySession struct { + Contract *DestinationVerifierProxy + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type DestinationVerifierProxyCallerSession struct { + Contract *DestinationVerifierProxyCaller + CallOpts bind.CallOpts +} + +type DestinationVerifierProxyTransactorSession struct { + Contract *DestinationVerifierProxyTransactor + TransactOpts bind.TransactOpts +} + +type DestinationVerifierProxyRaw struct { + Contract *DestinationVerifierProxy +} + +type DestinationVerifierProxyCallerRaw struct { + Contract *DestinationVerifierProxyCaller +} + +type DestinationVerifierProxyTransactorRaw struct { + Contract *DestinationVerifierProxyTransactor +} + +func NewDestinationVerifierProxy(address common.Address, backend bind.ContractBackend) (*DestinationVerifierProxy, error) { + abi, err := abi.JSON(strings.NewReader(DestinationVerifierProxyABI)) + if err != nil { + return nil, err + } + contract, err := bindDestinationVerifierProxy(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &DestinationVerifierProxy{address: address, abi: abi, DestinationVerifierProxyCaller: DestinationVerifierProxyCaller{contract: contract}, DestinationVerifierProxyTransactor: DestinationVerifierProxyTransactor{contract: contract}, DestinationVerifierProxyFilterer: DestinationVerifierProxyFilterer{contract: contract}}, nil +} + +func NewDestinationVerifierProxyCaller(address common.Address, caller bind.ContractCaller) (*DestinationVerifierProxyCaller, error) { + contract, err := bindDestinationVerifierProxy(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &DestinationVerifierProxyCaller{contract: contract}, nil +} + +func NewDestinationVerifierProxyTransactor(address common.Address, transactor bind.ContractTransactor) (*DestinationVerifierProxyTransactor, error) { + contract, err := bindDestinationVerifierProxy(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &DestinationVerifierProxyTransactor{contract: contract}, nil +} + +func NewDestinationVerifierProxyFilterer(address common.Address, filterer bind.ContractFilterer) (*DestinationVerifierProxyFilterer, error) { + contract, err := bindDestinationVerifierProxy(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &DestinationVerifierProxyFilterer{contract: contract}, nil +} + +func bindDestinationVerifierProxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := DestinationVerifierProxyMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DestinationVerifierProxy.Contract.DestinationVerifierProxyCaller.contract.Call(opts, result, method, params...) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.DestinationVerifierProxyTransactor.contract.Transfer(opts) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.DestinationVerifierProxyTransactor.contract.Transact(opts, method, params...) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DestinationVerifierProxy.Contract.contract.Call(opts, result, method, params...) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.contract.Transfer(opts) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.contract.Transact(opts, method, params...) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationVerifierProxy.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationVerifierProxy *DestinationVerifierProxySession) Owner() (common.Address, error) { + return _DestinationVerifierProxy.Contract.Owner(&_DestinationVerifierProxy.CallOpts) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyCallerSession) Owner() (common.Address, error) { + return _DestinationVerifierProxy.Contract.Owner(&_DestinationVerifierProxy.CallOpts) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyCaller) SAccessController(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationVerifierProxy.contract.Call(opts, &out, "s_accessController") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationVerifierProxy *DestinationVerifierProxySession) SAccessController() (common.Address, error) { + return _DestinationVerifierProxy.Contract.SAccessController(&_DestinationVerifierProxy.CallOpts) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyCallerSession) SAccessController() (common.Address, error) { + return _DestinationVerifierProxy.Contract.SAccessController(&_DestinationVerifierProxy.CallOpts) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyCaller) SFeeManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DestinationVerifierProxy.contract.Call(opts, &out, "s_feeManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DestinationVerifierProxy *DestinationVerifierProxySession) SFeeManager() (common.Address, error) { + return _DestinationVerifierProxy.Contract.SFeeManager(&_DestinationVerifierProxy.CallOpts) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyCallerSession) SFeeManager() (common.Address, error) { + return _DestinationVerifierProxy.Contract.SFeeManager(&_DestinationVerifierProxy.CallOpts) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _DestinationVerifierProxy.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_DestinationVerifierProxy *DestinationVerifierProxySession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _DestinationVerifierProxy.Contract.SupportsInterface(&_DestinationVerifierProxy.CallOpts, interfaceId) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _DestinationVerifierProxy.Contract.SupportsInterface(&_DestinationVerifierProxy.CallOpts, interfaceId) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _DestinationVerifierProxy.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_DestinationVerifierProxy *DestinationVerifierProxySession) TypeAndVersion() (string, error) { + return _DestinationVerifierProxy.Contract.TypeAndVersion(&_DestinationVerifierProxy.CallOpts) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyCallerSession) TypeAndVersion() (string, error) { + return _DestinationVerifierProxy.Contract.TypeAndVersion(&_DestinationVerifierProxy.CallOpts) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DestinationVerifierProxy.contract.Transact(opts, "acceptOwnership") +} + +func (_DestinationVerifierProxy *DestinationVerifierProxySession) AcceptOwnership() (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.AcceptOwnership(&_DestinationVerifierProxy.TransactOpts) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.AcceptOwnership(&_DestinationVerifierProxy.TransactOpts) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyTransactor) SetVerifier(opts *bind.TransactOpts, verifierAddress common.Address) (*types.Transaction, error) { + return _DestinationVerifierProxy.contract.Transact(opts, "setVerifier", verifierAddress) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxySession) SetVerifier(verifierAddress common.Address) (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.SetVerifier(&_DestinationVerifierProxy.TransactOpts, verifierAddress) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyTransactorSession) SetVerifier(verifierAddress common.Address) (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.SetVerifier(&_DestinationVerifierProxy.TransactOpts, verifierAddress) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _DestinationVerifierProxy.contract.Transact(opts, "transferOwnership", to) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxySession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.TransferOwnership(&_DestinationVerifierProxy.TransactOpts, to) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.TransferOwnership(&_DestinationVerifierProxy.TransactOpts, to) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyTransactor) Verify(opts *bind.TransactOpts, payload []byte, parameterPayload []byte) (*types.Transaction, error) { + return _DestinationVerifierProxy.contract.Transact(opts, "verify", payload, parameterPayload) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxySession) Verify(payload []byte, parameterPayload []byte) (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.Verify(&_DestinationVerifierProxy.TransactOpts, payload, parameterPayload) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyTransactorSession) Verify(payload []byte, parameterPayload []byte) (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.Verify(&_DestinationVerifierProxy.TransactOpts, payload, parameterPayload) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyTransactor) VerifyBulk(opts *bind.TransactOpts, payloads [][]byte, parameterPayload []byte) (*types.Transaction, error) { + return _DestinationVerifierProxy.contract.Transact(opts, "verifyBulk", payloads, parameterPayload) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxySession) VerifyBulk(payloads [][]byte, parameterPayload []byte) (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.VerifyBulk(&_DestinationVerifierProxy.TransactOpts, payloads, parameterPayload) +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyTransactorSession) VerifyBulk(payloads [][]byte, parameterPayload []byte) (*types.Transaction, error) { + return _DestinationVerifierProxy.Contract.VerifyBulk(&_DestinationVerifierProxy.TransactOpts, payloads, parameterPayload) +} + +type DestinationVerifierProxyOwnershipTransferRequestedIterator struct { + Event *DestinationVerifierProxyOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationVerifierProxyOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierProxyOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierProxyOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationVerifierProxyOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *DestinationVerifierProxyOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationVerifierProxyOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationVerifierProxyOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationVerifierProxy.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &DestinationVerifierProxyOwnershipTransferRequestedIterator{contract: _DestinationVerifierProxy.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *DestinationVerifierProxyOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationVerifierProxy.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationVerifierProxyOwnershipTransferRequested) + if err := _DestinationVerifierProxy.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyFilterer) ParseOwnershipTransferRequested(log types.Log) (*DestinationVerifierProxyOwnershipTransferRequested, error) { + event := new(DestinationVerifierProxyOwnershipTransferRequested) + if err := _DestinationVerifierProxy.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DestinationVerifierProxyOwnershipTransferredIterator struct { + Event *DestinationVerifierProxyOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DestinationVerifierProxyOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierProxyOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DestinationVerifierProxyOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DestinationVerifierProxyOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *DestinationVerifierProxyOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DestinationVerifierProxyOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationVerifierProxyOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationVerifierProxy.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &DestinationVerifierProxyOwnershipTransferredIterator{contract: _DestinationVerifierProxy.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DestinationVerifierProxyOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DestinationVerifierProxy.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DestinationVerifierProxyOwnershipTransferred) + if err := _DestinationVerifierProxy.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DestinationVerifierProxy *DestinationVerifierProxyFilterer) ParseOwnershipTransferred(log types.Log) (*DestinationVerifierProxyOwnershipTransferred, error) { + event := new(DestinationVerifierProxyOwnershipTransferred) + if err := _DestinationVerifierProxy.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_DestinationVerifierProxy *DestinationVerifierProxy) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _DestinationVerifierProxy.abi.Events["OwnershipTransferRequested"].ID: + return _DestinationVerifierProxy.ParseOwnershipTransferRequested(log) + case _DestinationVerifierProxy.abi.Events["OwnershipTransferred"].ID: + return _DestinationVerifierProxy.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (DestinationVerifierProxyOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (DestinationVerifierProxyOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_DestinationVerifierProxy *DestinationVerifierProxy) Address() common.Address { + return _DestinationVerifierProxy.address +} + +type DestinationVerifierProxyInterface interface { + Owner(opts *bind.CallOpts) (common.Address, error) + + SAccessController(opts *bind.CallOpts) (common.Address, error) + + SFeeManager(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + SetVerifier(opts *bind.TransactOpts, verifierAddress common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Verify(opts *bind.TransactOpts, payload []byte, parameterPayload []byte) (*types.Transaction, error) + + VerifyBulk(opts *bind.TransactOpts, payloads [][]byte, parameterPayload []byte) (*types.Transaction, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationVerifierProxyOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *DestinationVerifierProxyOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*DestinationVerifierProxyOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DestinationVerifierProxyOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DestinationVerifierProxyOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*DestinationVerifierProxyOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/errored_verifier/errored_verifier.go b/core/gethwrappers/llo-feeds/generated/errored_verifier/errored_verifier.go index 4d140ea064..f834686dfe 100644 --- a/core/gethwrappers/llo-feeds/generated/errored_verifier/errored_verifier.go +++ b/core/gethwrappers/llo-feeds/generated/errored_verifier/errored_verifier.go @@ -34,8 +34,8 @@ type CommonAddressAndWeight struct { } var ErroredVerifierMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"activateConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"activateFeed\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deactivateConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deactivateFeed\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"setConfigFromSource\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50610c2e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063b70d929d11610076578063e7db9c2a1161005b578063e7db9c2a146101d1578063e84f128e146101e4578063f01072211461021a57600080fd5b8063b70d929d14610188578063ded6307c146101be57600080fd5b80633dd86430116100a75780633dd864301461014d578063564a0a7a1461016257806394d959801461017557600080fd5b806301ffc9a7146100c35780633d3ac1b51461012d575b600080fd5b6101186100d136600461059a565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61014061013b366004610741565b610228565b604051610124919061078f565b61016061015b3660046107fb565b610292565b005b6101606101703660046107fb565b6102f4565b610160610183366004610814565b610356565b61019b6101963660046107fb565b6103b8565b604080519315158452602084019290925263ffffffff1690820152606001610124565b6101606101cc366004610814565b610447565b6101606101df3660046109f1565b6104a9565b6101f76101f23660046107fb565b61050b565b6040805163ffffffff948516815293909216602084015290820152606001610124565b6101606101df366004610b24565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4661696c656420746f207665726966790000000000000000000000000000000060448201526060906064015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4661696c656420746f20616374697661746520666565640000000000000000006044820152606401610289565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4661696c656420746f20646561637469766174652066656564000000000000006044820152606401610289565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4661696c656420746f206465616374697661746520636f6e66696700000000006044820152606401610289565b60008060006040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610289906020808252602c908201527f4661696c656420746f20676574206c617465737420636f6e666967206469676560408201527f737420616e642065706f63680000000000000000000000000000000000000000606082015260800190565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4661696c656420746f20616374697661746520636f6e666967000000000000006044820152606401610289565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4661696c656420746f2073657420636f6e6669670000000000000000000000006044820152606401610289565b60008060006040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102899060208082526023908201527f4661696c656420746f20676574206c617465737420636f6e666967206465746160408201527f696c730000000000000000000000000000000000000000000000000000000000606082015260800190565b6000602082840312156105ac57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146105dc57600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610635576106356105e3565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610682576106826105e3565b604052919050565b600082601f83011261069b57600080fd5b813567ffffffffffffffff8111156106b5576106b56105e3565b6106e660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161063b565b8181528460208386010111156106fb57600080fd5b816020850160208301376000918101602001919091529392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461073c57600080fd5b919050565b6000806040838503121561075457600080fd5b823567ffffffffffffffff81111561076b57600080fd5b6107778582860161068a565b92505061078660208401610718565b90509250929050565b600060208083528351808285015260005b818110156107bc578581018301518582016040015282016107a0565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561080d57600080fd5b5035919050565b6000806040838503121561082757600080fd5b50508035926020909101359150565b803563ffffffff8116811461073c57600080fd5b600067ffffffffffffffff821115610864576108646105e3565b5060051b60200190565b600082601f83011261087f57600080fd5b8135602061089461088f8361084a565b61063b565b82815260059290921b840181019181810190868411156108b357600080fd5b8286015b848110156108d5576108c881610718565b83529183019183016108b7565b509695505050505050565b600082601f8301126108f157600080fd5b8135602061090161088f8361084a565b82815260059290921b8401810191818101908684111561092057600080fd5b8286015b848110156108d55780358352918301918301610924565b803560ff8116811461073c57600080fd5b803567ffffffffffffffff8116811461073c57600080fd5b600082601f83011261097557600080fd5b8135602061098561088f8361084a565b82815260069290921b840181019181810190868411156109a457600080fd5b8286015b848110156108d557604081890312156109c15760008081fd5b6109c9610612565b6109d282610718565b81526109df85830161094c565b818601528352918301916040016109a8565b60008060008060008060008060008060006101608c8e031215610a1357600080fd5b8b359a5060208c01359950610a2a60408d01610718565b9850610a3860608d01610836565b975067ffffffffffffffff8060808e01351115610a5457600080fd5b610a648e60808f01358f0161086e565b97508060a08e01351115610a7757600080fd5b610a878e60a08f01358f016108e0565b9650610a9560c08e0161093b565b95508060e08e01351115610aa857600080fd5b610ab88e60e08f01358f0161068a565b9450610ac76101008e0161094c565b9350806101208e01351115610adb57600080fd5b610aec8e6101208f01358f0161068a565b9250806101408e01351115610b0057600080fd5b50610b128d6101408e01358e01610964565b90509295989b509295989b9093969950565b600080600080600080600080610100898b031215610b4157600080fd5b88359750602089013567ffffffffffffffff80821115610b6057600080fd5b610b6c8c838d0161086e565b985060408b0135915080821115610b8257600080fd5b610b8e8c838d016108e0565b9750610b9c60608c0161093b565b965060808b0135915080821115610bb257600080fd5b610bbe8c838d0161068a565b9550610bcc60a08c0161094c565b945060c08b0135915080821115610be257600080fd5b610bee8c838d0161068a565b935060e08b0135915080821115610c0457600080fd5b50610c118b828c01610964565b915050929598509295989093965056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"FailedToActivateConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToActivateFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToDeactivateConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToDeactivateFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToGetLatestConfigDetails\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToGetLatestConfigDigestAndEpoch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSetConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToVerify\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"activateConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"activateFeed\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deactivateConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deactivateFeed\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"setConfigFromSource\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610a58806100206000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063b70d929d11610076578063e7db9c2a1161005b578063e7db9c2a146101d1578063e84f128e146101e4578063f01072211461021a57600080fd5b8063b70d929d14610188578063ded6307c146101be57600080fd5b80633dd86430116100a75780633dd864301461014d578063564a0a7a1461016257806394d959801461017557600080fd5b806301ffc9a7146100c35780633d3ac1b51461012d575b600080fd5b6101186100d13660046103c4565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61014061013b36600461056b565b610228565b60405161012491906105b9565b61016061015b366004610625565b61025c565b005b610160610170366004610625565b61028e565b61016061018336600461063e565b6102c0565b61019b610196366004610625565b6102f2565b604080519315158452602084019290925263ffffffff1690820152606001610124565b6101606101cc36600461063e565b610329565b6101606101df36600461081b565b61035b565b6101f76101f2366004610625565b61038d565b6040805163ffffffff948516815293909216602084015290820152606001610124565b6101606101df36600461094e565b60606040517fcf2e344600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f9601b68300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa03564b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f8a406e4600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060006040517fbbc0083000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7adb7c9600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f35e91bf100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060006040517fa06d64a000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602082840312156103d657600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461040657600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561045f5761045f61040d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156104ac576104ac61040d565b604052919050565b600082601f8301126104c557600080fd5b813567ffffffffffffffff8111156104df576104df61040d565b61051060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610465565b81815284602083860101111561052557600080fd5b816020850160208301376000918101602001919091529392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461056657600080fd5b919050565b6000806040838503121561057e57600080fd5b823567ffffffffffffffff81111561059557600080fd5b6105a1858286016104b4565b9250506105b060208401610542565b90509250929050565b600060208083528351808285015260005b818110156105e6578581018301518582016040015282016105ca565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561063757600080fd5b5035919050565b6000806040838503121561065157600080fd5b50508035926020909101359150565b803563ffffffff8116811461056657600080fd5b600067ffffffffffffffff82111561068e5761068e61040d565b5060051b60200190565b600082601f8301126106a957600080fd5b813560206106be6106b983610674565b610465565b82815260059290921b840181019181810190868411156106dd57600080fd5b8286015b848110156106ff576106f281610542565b83529183019183016106e1565b509695505050505050565b600082601f83011261071b57600080fd5b8135602061072b6106b983610674565b82815260059290921b8401810191818101908684111561074a57600080fd5b8286015b848110156106ff578035835291830191830161074e565b803560ff8116811461056657600080fd5b803567ffffffffffffffff8116811461056657600080fd5b600082601f83011261079f57600080fd5b813560206107af6106b983610674565b82815260069290921b840181019181810190868411156107ce57600080fd5b8286015b848110156106ff57604081890312156107eb5760008081fd5b6107f361043c565b6107fc82610542565b8152610809858301610776565b818601528352918301916040016107d2565b60008060008060008060008060008060006101608c8e03121561083d57600080fd5b8b359a5060208c0135995061085460408d01610542565b985061086260608d01610660565b975067ffffffffffffffff8060808e0135111561087e57600080fd5b61088e8e60808f01358f01610698565b97508060a08e013511156108a157600080fd5b6108b18e60a08f01358f0161070a565b96506108bf60c08e01610765565b95508060e08e013511156108d257600080fd5b6108e28e60e08f01358f016104b4565b94506108f16101008e01610776565b9350806101208e0135111561090557600080fd5b6109168e6101208f01358f016104b4565b9250806101408e0135111561092a57600080fd5b5061093c8d6101408e01358e0161078e565b90509295989b509295989b9093969950565b600080600080600080600080610100898b03121561096b57600080fd5b88359750602089013567ffffffffffffffff8082111561098a57600080fd5b6109968c838d01610698565b985060408b01359150808211156109ac57600080fd5b6109b88c838d0161070a565b97506109c660608c01610765565b965060808b01359150808211156109dc57600080fd5b6109e88c838d016104b4565b95506109f660a08c01610776565b945060c08b0135915080821115610a0c57600080fd5b610a188c838d016104b4565b935060e08b0135915080821115610a2e57600080fd5b50610a3b8b828c0161078e565b915050929598509295989093965056fea164736f6c6343000813000a", } var ErroredVerifierABI = ErroredVerifierMetaData.ABI diff --git a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 729d3a295c..0eec657b4c 100644 --- a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -2,7 +2,11 @@ GETH_VERSION: 1.13.8 channel_config_store: ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin c90e29d9f1a885098982b6175e0447416431b28c605273c807694ac7141e9167 channel_config_verifier_proxy: ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.abi ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.bin 655658e5f61dfadfe3268de04f948b7e690ad03ca45676e645d6cd6018154661 channel_verifier: ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.abi ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.bin e6020553bd8e3e6b250fcaffe7efd22aea955c8c1a0eb05d282fdeb0ab6550b7 -errored_verifier: ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.abi ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.bin a3e5a77262e13ee30fe8d35551b32a3452d71929e43fd780bbfefeaf4aa62e43 +destination_fee_manager: ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.abi ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.bin c581af84832b8fd886685f59518bcdb11bd1c9b508d88b07c04d6226e6a2789e +destination_reward_manager: ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.abi ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.bin 6aed4313578f74ede71bcb60674391103d265d96d56d4736a79ef4128f0590f4 +destination_verifier: ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.abi ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.bin 2dc118aecd5c30d34a69354a9fb603beb98d46215a18d31c59f0f7902fd8f4c2 +destination_verifier_proxy: ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.abi ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.bin a4bf230bbba8a7b8e32a85a6161ca1343f7472b257c358a73ac37996809ce1c0 +errored_verifier: ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.abi ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.bin ad8ac8d6b99890081725e2304d79d1ba7dd5212b89d130aa9689f4269eed4691 exposed_channel_verifier: ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.abi ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.bin c21cde078900241c06de69e2bc5d906c5ef558b52db66caa68bed065940a2253 exposed_verifier: ../../../contracts/solc/v0.8.19/ExposedVerifier/ExposedVerifier.abi ../../../contracts/solc/v0.8.19/ExposedVerifier/ExposedVerifier.bin 00816ab345f768e522c79abadeadf9155c2c688067e18f8f73e5d6ab71037663 fee_manager: ../../../contracts/solc/v0.8.19/FeeManager/FeeManager.abi ../../../contracts/solc/v0.8.19/FeeManager/FeeManager.bin edc85f34294ae7c90d45c4c71eb5c105c60a4842dfbbf700c692870ffcc403a1 diff --git a/core/gethwrappers/llo-feeds/go_generate.go b/core/gethwrappers/llo-feeds/go_generate.go index 5e5b841b72..688b503cc1 100644 --- a/core/gethwrappers/llo-feeds/go_generate.go +++ b/core/gethwrappers/llo-feeds/go_generate.go @@ -12,3 +12,8 @@ package gethwrappers //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin ChannelConfigStore channel_config_store //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.abi ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.bin ChannelVerifier channel_verifier //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.abi ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.bin ExposedChannelVerifier exposed_channel_verifier + +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.abi ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.bin DestinationVerifier destination_verifier +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.abi ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.bin DestinationVerifierProxy destination_verifier_proxy +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.abi ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.bin DestinationFeeManager destination_fee_manager +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.abi ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.bin DestinationRewardManager destination_reward_manager From d59164563b68018ce53d0e7d0f1cb0260ef60578 Mon Sep 17 00:00:00 2001 From: Cedric Date: Wed, 31 Jul 2024 13:54:29 +0100 Subject: [PATCH 011/432] [KS-393] Handle nils values (#13945) * KS-393: Incorporate values lib improvements * Incorporate bytes Copy fix --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- core/services/registrysyncer/syncer.go | 7 ++++++- core/services/workflows/state.go | 6 ++---- core/services/workflows/store/store_db.go | 10 ++++++++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 11 files changed, 28 insertions(+), 19 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 3753cf92bc..5cd4aaf63c 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index f3276d5a62..c383b6bf81 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1184,8 +1184,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 h1:pdEpjgbZ5w/Sd5lzg/XiuC5gVyrmSovOo+3nUD46SP8= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 h1:6s4cTIE3NbATxWLrD5JLCq097PC5Y4GKK/Kk4fhURpY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= diff --git a/core/services/registrysyncer/syncer.go b/core/services/registrysyncer/syncer.go index 6a44ff561d..4bbfaef504 100644 --- a/core/services/registrysyncer/syncer.go +++ b/core/services/registrysyncer/syncer.go @@ -173,8 +173,13 @@ func unmarshalCapabilityConfig(data []byte) (capabilities.CapabilityConfiguratio rtc.MessageExpiry = prtc.MessageExpiry.AsDuration() } + dc, err := values.FromMapValueProto(cconf.DefaultConfig) + if err != nil { + return capabilities.CapabilityConfiguration{}, err + } + return capabilities.CapabilityConfiguration{ - DefaultConfig: values.FromMapValueProto(cconf.DefaultConfig), + DefaultConfig: dc, RemoteTriggerConfig: rtc, }, nil } diff --git a/core/services/workflows/state.go b/core/services/workflows/state.go index 6fc61af395..28eca199a4 100644 --- a/core/services/workflows/state.go +++ b/core/services/workflows/state.go @@ -17,12 +17,10 @@ func copyState(es store.WorkflowExecution) store.WorkflowExecution { for ref, step := range es.Steps { var mval *values.Map if step.Inputs != nil { - mp := values.Proto(step.Inputs).GetMapValue() - mval = values.FromMapValueProto(mp) + mval = step.Inputs.CopyMap() } - op := values.Proto(step.Outputs.Value) - copiedov := values.FromProto(op) + copiedov := step.Outputs.Value.Copy() newState := &store.WorkflowExecutionStep{ ExecutionID: step.ExecutionID, diff --git a/core/services/workflows/store/store_db.go b/core/services/workflows/store/store_db.go index e1d0862905..80ecfbb2d6 100644 --- a/core/services/workflows/store/store_db.go +++ b/core/services/workflows/store/store_db.go @@ -127,7 +127,10 @@ func stepToState(step workflowStepRow) (*WorkflowExecutionStep, error) { return nil, err } - inputs = values.FromMapValueProto(vmProto) + inputs, err = values.FromMapValueProto(vmProto) + if err != nil { + return nil, err + } } var ( @@ -146,7 +149,10 @@ func stepToState(step workflowStepRow) (*WorkflowExecutionStep, error) { return nil, err } - outputs = values.FromProto(vProto) + outputs, err = values.FromProto(vProto) + if err != nil { + return nil, err + } } return &WorkflowExecutionStep{ diff --git a/go.mod b/go.mod index 5dd79d3632..326c06396d 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index 4f0edd8701..2ec1753593 100644 --- a/go.sum +++ b/go.sum @@ -1136,8 +1136,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 h1:pdEpjgbZ5w/Sd5lzg/XiuC5gVyrmSovOo+3nUD46SP8= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 h1:6s4cTIE3NbATxWLrD5JLCq097PC5Y4GKK/Kk4fhURpY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 19a7218a3d..d76fb920d1 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -28,7 +28,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 github.com/smartcontractkit/chainlink-testing-framework v1.32.7 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 23f1d900d1..dd002a75d5 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1486,8 +1486,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 h1:pdEpjgbZ5w/Sd5lzg/XiuC5gVyrmSovOo+3nUD46SP8= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 h1:6s4cTIE3NbATxWLrD5JLCq097PC5Y4GKK/Kk4fhURpY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 75575382c7..95726e6371 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.31.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 github.com/smartcontractkit/chainlink-testing-framework v1.32.7 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 05af3d1b0a..0fbe5f832c 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1468,8 +1468,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 h1:pdEpjgbZ5w/Sd5lzg/XiuC5gVyrmSovOo+3nUD46SP8= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 h1:6s4cTIE3NbATxWLrD5JLCq097PC5Y4GKK/Kk4fhURpY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= From afe2b25ef102f5eb54c032b8b33b18015989d7ee Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Wed, 31 Jul 2024 15:22:55 +0200 Subject: [PATCH 012/432] add ccip and liq man gethwrappers (#13967) * add gethwrappers * liqMan wrappers * port mockery mocks --------- Co-authored-by: Abdelrahman Soliman (Boda) <2677789+asoliman92@users.noreply.github.com> --- .mockery.yaml | 144 +- LICENSE | 6 +- .../generated/arm_contract/arm_contract.go | 2849 +++++++++++ .../arm_proxy_contract/arm_proxy_contract.go | 743 +++ .../burn_from_mint_token_pool.go | 2780 ++++++++++ .../burn_mint_token_pool.go | 2780 ++++++++++ .../burn_mint_token_pool_1_2_0.go | 2544 +++++++++ .../burn_mint_token_pool_1_4_0.go | 2264 ++++++++ .../burn_mint_token_pool_and_proxy.go | 2972 +++++++++++ .../burn_with_from_mint_token_pool.go | 2780 ++++++++++ .../ccip/generated/ccip_config/ccip_config.go | 1103 ++++ .../ccip_reader_tester/ccip_reader_tester.go | 761 +++ .../generated/commit_store/commit_store.go | 2191 ++++++++ .../commit_store_1_0_0/commit_store_1_0_0.go | 1951 +++++++ .../commit_store_1_2_0/commit_store.go | 1955 +++++++ .../commit_store_helper.go | 2205 ++++++++ .../commit_store_helper_1_0_0.go | 1966 +++++++ .../commit_store_helper_1_2_0.go | 1969 +++++++ .../ether_sender_receiver.go | 361 ++ .../evm_2_evm_multi_offramp.go | 2367 +++++++++ .../evm_2_evm_multi_onramp.go | 1489 ++++++ .../evm_2_evm_offramp/evm_2_evm_offramp.go | 2673 ++++++++++ .../evm_2_evm_offramp_1_0_0.go | 2354 +++++++++ .../evm_2_evm_offramp_1_2_0.go | 2356 +++++++++ .../evm_2_evm_onramp/evm_2_evm_onramp.go | 2453 +++++++++ .../evm_2_evm_onramp_1_0_0.go | 2792 ++++++++++ .../evm_2_evm_onramp_1_1_0.go | 2794 ++++++++++ .../evm_2_evm_onramp_1_2_0.go | 2337 +++++++++ .../lock_release_token_pool.go | 3204 ++++++++++++ .../lock_release_token_pool.go | 2892 +++++++++++ .../lock_release_token_pool_1_4_0.go | 2712 ++++++++++ .../lock_release_token_pool_and_proxy.go | 3396 ++++++++++++ .../maybe_revert_message_receiver.go | 564 ++ .../message_hasher/message_hasher.go | 427 ++ .../mock_arm_contract/mock_arm_contract.go | 746 +++ .../mock_usdc_token_messenger.go | 488 ++ .../mock_usdc_token_transmitter.go | 471 ++ .../mock_v3_aggregator_contract.go | 797 +++ .../multi_aggregate_rate_limiter.go | 1836 +++++++ .../multi_ocr3_helper/multi_ocr3_helper.go | 1096 ++++ .../generated/nonce_manager/nonce_manager.go | 1234 +++++ .../ocr3_config_encoder.go | 196 + .../ping_pong_demo/ping_pong_demo.go | 1061 ++++ .../price_registry/price_registry.go | 3141 ++++++++++++ .../price_registry_1_0_0/price_registry.go | 1665 ++++++ .../price_registry_1_2_0/price_registry.go | 1693 ++++++ .../registry_module_owner_custom.go | 390 ++ .../generated/report_codec/report_codec.go | 559 ++ .../ccip/generated/router/router.go | 1431 ++++++ .../self_funded_ping_pong.go | 1370 +++++ .../token_admin_registry.go | 1795 +++++++ .../ccip/generated/token_pool/token_pool.go | 2608 ++++++++++ .../token_pool_1_4_0/token_pool_1_4_0.go | 2221 ++++++++ .../usdc_token_pool/usdc_token_pool.go | 3185 ++++++++++++ .../usdc_token_pool_1_4_0.go | 2693 ++++++++++ .../ccip/generated/weth9/weth9.go | 996 ++++ ...rapper-dependency-versions-do-not-edit.txt | 37 + core/gethwrappers/ccip/go_generate.go | 80 + .../ccip/mocks/commit_store_interface.go | 3418 +++++++++++++ .../ccip/mocks/evm2_evm_off_ramp_interface.go | 3893 ++++++++++++++ .../ccip/mocks/evm2_evm_on_ramp_interface.go | 3832 ++++++++++++++ .../ccip/mocks/link_token_interface.go | 1217 +++++ .../ccip/mocks/price_registry_interface.go | 4555 +++++++++++++++++ .../v1_0_0/evm2_evm_off_ramp_interface.go | 3603 +++++++++++++ .../v1_2_0/evm2_evm_off_ramp_interface.go | 3603 +++++++++++++ core/gethwrappers/go_generate.go | 15 +- .../abstract_arbitrum_token_gateway.go | 283 + .../arb_node_interface/arb_node_interface.go | 428 ++ .../arbitrum_gateway_router.go | 730 +++ .../arbitrum_inbox/arbitrum_inbox.go | 744 +++ .../arbitrum_l1_bridge_adapter.go | 316 ++ .../arbitrum_l1_gateway_router.go | 349 ++ .../arbitrum_l2_bridge_adapter.go | 254 + .../arbitrum_rollup_core.go | 2022 ++++++++ .../arbitrum_token_gateway.go | 235 + .../generated/arbsys/arbsys.go | 940 ++++ .../l2_arbitrum_gateway.go | 823 +++ .../l2_arbitrum_messenger.go | 329 ++ .../liquiditymanager/liquiditymanager.go | 2878 +++++++++++ .../mock_l1_bridge_adapter.go | 660 +++ .../mock_l2_bridge_adapter.go | 240 + .../generated/no_op_ocr3/no_op_ocr3.go | 946 ++++ .../optimism_cross_domain_messenger.go | 328 ++ .../optimism_dispute_game_factory.go | 215 + .../optimism_l1_bridge_adapter.go | 316 ++ .../optimism_l1_bridge_adapter_encoder.go | 257 + .../optimism_l1_standard_bridge.go | 173 + .../optimism_l2_bridge_adapter.go | 302 ++ .../optimism_l2_output_oracle.go | 213 + .../optimism_l2_to_l1_message_passer.go | 332 ++ .../optimism_portal/optimism_portal.go | 227 + .../optimism_portal_2/optimism_portal_2.go | 207 + .../optimism_standard_bridge.go | 345 ++ .../report_encoder/report_encoder.go | 256 + ...rapper-dependency-versions-do-not-edit.txt | 29 + .../liquiditymanager/go_generate.go | 37 + .../arbitrum_gateway_router_interface.go | 1054 ++++ .../arbitrum_inbox_interface.go | 1452 ++++++ .../arbitrum_l1_bridge_adapter_interface.go | 426 ++ .../arbitrum_l2_bridge_adapter_interface.go | 327 ++ .../arb_rollup_core_interface.go | 3347 ++++++++++++ .../mocks/mock_arbsys/arb_sys_interface.go | 1392 +++++ .../l2_arbitrum_gateway_interface.go | 1238 +++++ .../l2_arbitrum_messenger_interface.go | 333 ++ .../node_interface_interface.go | 680 +++ ...optimism_dispute_game_factory_interface.go | 207 + .../optimism_l2_output_oracle_interface.go | 204 + .../optimism_portal_interface.go | 267 + .../optimism_portal2_interface.go | 198 + 109 files changed, 151579 insertions(+), 19 deletions(-) create mode 100644 core/gethwrappers/ccip/generated/arm_contract/arm_contract.go create mode 100644 core/gethwrappers/ccip/generated/arm_proxy_contract/arm_proxy_contract.go create mode 100644 core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go create mode 100644 core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go create mode 100644 core/gethwrappers/ccip/generated/burn_mint_token_pool_1_2_0/burn_mint_token_pool_1_2_0.go create mode 100644 core/gethwrappers/ccip/generated/burn_mint_token_pool_1_4_0/burn_mint_token_pool_1_4_0.go create mode 100644 core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go create mode 100644 core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go create mode 100644 core/gethwrappers/ccip/generated/ccip_config/ccip_config.go create mode 100644 core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go create mode 100644 core/gethwrappers/ccip/generated/commit_store/commit_store.go create mode 100644 core/gethwrappers/ccip/generated/commit_store_1_0_0/commit_store_1_0_0.go create mode 100644 core/gethwrappers/ccip/generated/commit_store_1_2_0/commit_store.go create mode 100644 core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go create mode 100644 core/gethwrappers/ccip/generated/commit_store_helper_1_0_0/commit_store_helper_1_0_0.go create mode 100644 core/gethwrappers/ccip/generated/commit_store_helper_1_2_0/commit_store_helper_1_2_0.go create mode 100644 core/gethwrappers/ccip/generated/ether_sender_receiver/ether_sender_receiver.go create mode 100644 core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go create mode 100644 core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go create mode 100644 core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go create mode 100644 core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0/evm_2_evm_offramp_1_0_0.go create mode 100644 core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0/evm_2_evm_offramp_1_2_0.go create mode 100644 core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go create mode 100644 core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0/evm_2_evm_onramp_1_0_0.go create mode 100644 core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_1_0/evm_2_evm_onramp_1_1_0.go create mode 100644 core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0/evm_2_evm_onramp_1_2_0.go create mode 100644 core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go create mode 100644 core/gethwrappers/ccip/generated/lock_release_token_pool_1_0_0/lock_release_token_pool.go create mode 100644 core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0/lock_release_token_pool_1_4_0.go create mode 100644 core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go create mode 100644 core/gethwrappers/ccip/generated/maybe_revert_message_receiver/maybe_revert_message_receiver.go create mode 100644 core/gethwrappers/ccip/generated/message_hasher/message_hasher.go create mode 100644 core/gethwrappers/ccip/generated/mock_arm_contract/mock_arm_contract.go create mode 100644 core/gethwrappers/ccip/generated/mock_usdc_token_messenger/mock_usdc_token_messenger.go create mode 100644 core/gethwrappers/ccip/generated/mock_usdc_token_transmitter/mock_usdc_token_transmitter.go create mode 100644 core/gethwrappers/ccip/generated/mock_v3_aggregator_contract/mock_v3_aggregator_contract.go create mode 100644 core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go create mode 100644 core/gethwrappers/ccip/generated/multi_ocr3_helper/multi_ocr3_helper.go create mode 100644 core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go create mode 100644 core/gethwrappers/ccip/generated/ocr3_config_encoder/ocr3_config_encoder.go create mode 100644 core/gethwrappers/ccip/generated/ping_pong_demo/ping_pong_demo.go create mode 100644 core/gethwrappers/ccip/generated/price_registry/price_registry.go create mode 100644 core/gethwrappers/ccip/generated/price_registry_1_0_0/price_registry.go create mode 100644 core/gethwrappers/ccip/generated/price_registry_1_2_0/price_registry.go create mode 100644 core/gethwrappers/ccip/generated/registry_module_owner_custom/registry_module_owner_custom.go create mode 100644 core/gethwrappers/ccip/generated/report_codec/report_codec.go create mode 100644 core/gethwrappers/ccip/generated/router/router.go create mode 100644 core/gethwrappers/ccip/generated/self_funded_ping_pong/self_funded_ping_pong.go create mode 100644 core/gethwrappers/ccip/generated/token_admin_registry/token_admin_registry.go create mode 100644 core/gethwrappers/ccip/generated/token_pool/token_pool.go create mode 100644 core/gethwrappers/ccip/generated/token_pool_1_4_0/token_pool_1_4_0.go create mode 100644 core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go create mode 100644 core/gethwrappers/ccip/generated/usdc_token_pool_1_4_0/usdc_token_pool_1_4_0.go create mode 100644 core/gethwrappers/ccip/generated/weth9/weth9.go create mode 100644 core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt create mode 100644 core/gethwrappers/ccip/go_generate.go create mode 100644 core/gethwrappers/ccip/mocks/commit_store_interface.go create mode 100644 core/gethwrappers/ccip/mocks/evm2_evm_off_ramp_interface.go create mode 100644 core/gethwrappers/ccip/mocks/evm2_evm_on_ramp_interface.go create mode 100644 core/gethwrappers/ccip/mocks/link_token_interface.go create mode 100644 core/gethwrappers/ccip/mocks/price_registry_interface.go create mode 100644 core/gethwrappers/ccip/mocks/v1_0_0/evm2_evm_off_ramp_interface.go create mode 100644 core/gethwrappers/ccip/mocks/v1_2_0/evm2_evm_off_ramp_interface.go create mode 100644 core/gethwrappers/liquiditymanager/generated/abstract_arbitrum_token_gateway/abstract_arbitrum_token_gateway.go create mode 100644 core/gethwrappers/liquiditymanager/generated/arb_node_interface/arb_node_interface.go create mode 100644 core/gethwrappers/liquiditymanager/generated/arbitrum_gateway_router/arbitrum_gateway_router.go create mode 100644 core/gethwrappers/liquiditymanager/generated/arbitrum_inbox/arbitrum_inbox.go create mode 100644 core/gethwrappers/liquiditymanager/generated/arbitrum_l1_bridge_adapter/arbitrum_l1_bridge_adapter.go create mode 100644 core/gethwrappers/liquiditymanager/generated/arbitrum_l1_gateway_router/arbitrum_l1_gateway_router.go create mode 100644 core/gethwrappers/liquiditymanager/generated/arbitrum_l2_bridge_adapter/arbitrum_l2_bridge_adapter.go create mode 100644 core/gethwrappers/liquiditymanager/generated/arbitrum_rollup_core/arbitrum_rollup_core.go create mode 100644 core/gethwrappers/liquiditymanager/generated/arbitrum_token_gateway/arbitrum_token_gateway.go create mode 100644 core/gethwrappers/liquiditymanager/generated/arbsys/arbsys.go create mode 100644 core/gethwrappers/liquiditymanager/generated/l2_arbitrum_gateway/l2_arbitrum_gateway.go create mode 100644 core/gethwrappers/liquiditymanager/generated/l2_arbitrum_messenger/l2_arbitrum_messenger.go create mode 100644 core/gethwrappers/liquiditymanager/generated/liquiditymanager/liquiditymanager.go create mode 100644 core/gethwrappers/liquiditymanager/generated/mock_l1_bridge_adapter/mock_l1_bridge_adapter.go create mode 100644 core/gethwrappers/liquiditymanager/generated/mock_l2_bridge_adapter/mock_l2_bridge_adapter.go create mode 100644 core/gethwrappers/liquiditymanager/generated/no_op_ocr3/no_op_ocr3.go create mode 100644 core/gethwrappers/liquiditymanager/generated/optimism_cross_domain_messenger/optimism_cross_domain_messenger.go create mode 100644 core/gethwrappers/liquiditymanager/generated/optimism_dispute_game_factory/optimism_dispute_game_factory.go create mode 100644 core/gethwrappers/liquiditymanager/generated/optimism_l1_bridge_adapter/optimism_l1_bridge_adapter.go create mode 100644 core/gethwrappers/liquiditymanager/generated/optimism_l1_bridge_adapter_encoder/optimism_l1_bridge_adapter_encoder.go create mode 100644 core/gethwrappers/liquiditymanager/generated/optimism_l1_standard_bridge/optimism_l1_standard_bridge.go create mode 100644 core/gethwrappers/liquiditymanager/generated/optimism_l2_bridge_adapter/optimism_l2_bridge_adapter.go create mode 100644 core/gethwrappers/liquiditymanager/generated/optimism_l2_output_oracle/optimism_l2_output_oracle.go create mode 100644 core/gethwrappers/liquiditymanager/generated/optimism_l2_to_l1_message_passer/optimism_l2_to_l1_message_passer.go create mode 100644 core/gethwrappers/liquiditymanager/generated/optimism_portal/optimism_portal.go create mode 100644 core/gethwrappers/liquiditymanager/generated/optimism_portal_2/optimism_portal_2.go create mode 100644 core/gethwrappers/liquiditymanager/generated/optimism_standard_bridge/optimism_standard_bridge.go create mode 100644 core/gethwrappers/liquiditymanager/generated/report_encoder/report_encoder.go create mode 100644 core/gethwrappers/liquiditymanager/generation/generated-wrapper-dependency-versions-do-not-edit.txt create mode 100644 core/gethwrappers/liquiditymanager/go_generate.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_gateway_router/arbitrum_gateway_router_interface.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_inbox/arbitrum_inbox_interface.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_l1_bridge_adapter/arbitrum_l1_bridge_adapter_interface.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_l2_bridge_adapter/arbitrum_l2_bridge_adapter_interface.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_rollup_core/arb_rollup_core_interface.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_arbsys/arb_sys_interface.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_l2_arbitrum_gateway/l2_arbitrum_gateway_interface.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_l2_arbitrum_messenger/l2_arbitrum_messenger_interface.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_node_interface/node_interface_interface.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_optimism_dispute_game_factory/optimism_dispute_game_factory_interface.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_optimism_l2_output_oracle/optimism_l2_output_oracle_interface.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_optimism_portal/optimism_portal_interface.go create mode 100644 core/gethwrappers/liquiditymanager/mocks/mock_optimism_portal_2/optimism_portal2_interface.go diff --git a/.mockery.yaml b/.mockery.yaml index 17800e3609..77d2145a46 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -318,7 +318,143 @@ packages: dir: core/services/relay/evm/mocks ChainReader: ChainWriter: - - - - + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp: + config: + dir: core/gethwrappers/ccip/mocks/ + filename: evm2_evm_on_ramp_interface.go + outpkg: mock_contracts + interfaces: + EVM2EVMOnRampInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp: + config: + dir: core/gethwrappers/ccip/mocks/ + filename: evm2_evm_off_ramp_interface.go + outpkg: mock_contracts + interfaces: + EVM2EVMOffRampInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0: + config: + dir: core/gethwrappers/ccip/mocks/v1_2_0/ + filename: evm2_evm_off_ramp_interface.go + outpkg: mock_contracts + interfaces: + EVM2EVMOffRampInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0: + config: + dir: core/gethwrappers/ccip/mocks/v1_0_0/ + filename: evm2_evm_off_ramp_interface.go + outpkg: mock_contracts + interfaces: + EVM2EVMOffRampInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store: + config: + dir: core/gethwrappers/ccip/mocks/ + filename: commit_store_interface.go + outpkg: mock_contracts + interfaces: + CommitStoreInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry: + config: + dir: core/gethwrappers/ccip/mocks/ + filename: price_registry_interface.go + outpkg: mock_contracts + interfaces: + PriceRegistryInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface: + config: + dir: core/gethwrappers/ccip/mocks/ + filename: link_token_interface.go + outpkg: mock_contracts + interfaces: + LinkTokenInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_l1_bridge_adapter: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_l1_bridge_adapter/ + filename: arbitrum_l1_bridge_adapter_interface.go + outpkg: mock_arbitrum_l1_bridge_adapter + interfaces: + ArbitrumL1BridgeAdapterInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_l2_bridge_adapter: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_l2_bridge_adapter/ + filename: arbitrum_l2_bridge_adapter_interface.go + outpkg: mock_arbitrum_l2_bridge_adapter + interfaces: + ArbitrumL2BridgeAdapterInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_gateway_router: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_gateway_router/ + filename: arbitrum_gateway_router_interface.go + outpkg: mock_arbitrum_gateway_router + interfaces: + ArbitrumGatewayRouterInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_inbox: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_inbox/ + filename: arbitrum_inbox_interface.go + outpkg: mock_arbitrum_inbox + interfaces: + ArbitrumInboxInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/l2_arbitrum_gateway: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_l2_arbitrum_gateway/ + filename: l2_arbitrum_gateway_interface.go + outpkg: mock_l2_arbitrum_gateway + interfaces: + L2ArbitrumGatewayInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbsys: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_arbsys/ + filename: arb_sys_interface.go + outpkg: mock_arbsys + interfaces: + ArbSysInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arb_node_interface: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_node_interface/ + filename: node_interface_interface.go + outpkg: mock_node_interface + interfaces: + NodeInterfaceInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/l2_arbitrum_messenger: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_l2_arbitrum_messenger/ + filename: l2_arbitrum_messenger_interface.go + outpkg: mock_l2_arbitrum_messenger + interfaces: + L2ArbitrumMessengerInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_rollup_core: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_rollup_core/ + filename: arb_rollup_core_interface.go + outpkg: mock_arbitrum_rollup_core + interfaces: + ArbRollupCoreInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_portal: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_optimism_portal/ + filename: optimism_portal_interface.go + outpkg: mock_optimism_portal + interfaces: + OptimismPortalInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_l2_output_oracle: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_optimism_l2_output_oracle/ + filename: optimism_l2_output_oracle_interface.go + outpkg: mock_optimism_l2_output_oracle + interfaces: + OptimismL2OutputOracleInterface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_portal_2: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_optimism_portal_2/ + filename: optimism_portal2_interface.go + outpkg: mock_optimism_portal_2 + interfaces: + OptimismPortal2Interface: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_dispute_game_factory: + config: + dir: core/gethwrappers/liquiditymanager/mocks/mock_optimism_dispute_game_factory/ + filename: optimism_dispute_game_factory_interface.go + outpkg: mock_optimism_dispute_game_factory + interfaces: + OptimismDisputeGameFactoryInterface: diff --git a/LICENSE b/LICENSE index 9723bc8be9..4a10bfc38b 100644 --- a/LICENSE +++ b/LICENSE @@ -24,9 +24,9 @@ THE SOFTWARE. *All content residing under (1) “/contracts/src/v0.8/ccip”; (2) -“/core/services/ocr2/plugins/ccip” are licensed under “Business Source -License 1.1” with a Change Date of May 23, 2027 and Change License to - “MIT License” +“/core/gethwrappers/ccip”; (3) “/core/services/ocr2/plugins/ccip” are licensed +under “Business Source License 1.1” with a Change Date of May 23, 2027 and +Change License to “MIT License” * Content outside of the above mentioned directories or restrictions above is available under the "MIT" license as defined above. \ No newline at end of file diff --git a/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go b/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go new file mode 100644 index 0000000000..e5cb17ded0 --- /dev/null +++ b/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go @@ -0,0 +1,2849 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package arm_contract + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type IRMNTaggedRoot struct { + CommitStore common.Address + Root [32]byte +} + +type RMNConfig struct { + Voters []RMNVoter + BlessWeightThreshold uint16 + CurseWeightThreshold uint16 +} + +type RMNOwnerUnvoteToCurseRequest struct { + CurseVoteAddr common.Address + Unit RMNUnvoteToCurseRequest + ForceUnvote bool +} + +type RMNRecordedCurseRelatedOp struct { + Tag uint8 + BlockTimestamp uint64 + Cursed bool + CurseVoteAddr common.Address + Subject [16]byte + CurseId [16]byte +} + +type RMNUnvoteToCurseRequest struct { + Subject [16]byte + CursesHash [28]byte +} + +type RMNVoter struct { + BlessVoteAddr common.Address + CurseVoteAddr common.Address + BlessWeight uint8 + CurseWeight uint8 +} + +var ARMContractMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"}],\"name\":\"ReusedCurseId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubjectsMustBeStrictlyIncreasing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"}],\"name\":\"UnauthorizedVoter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnvoteToCurseNoop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VoteToBlessForbiddenDuringActiveGlobalCurse\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VoteToBlessNoop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VoteToCurseNoop\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"AlreadyBlessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"AlreadyVotedToBless\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"CurseLifted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"blockTimestamp\",\"type\":\"uint64\"}],\"name\":\"Cursed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"}],\"name\":\"PermaBlessedCommitStoreAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"}],\"name\":\"PermaBlessedCommitStoreRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"onchainCursesHash\",\"type\":\"bytes28\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"}],\"name\":\"SkippedUnvoteToCurse\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"wasBlessed\",\"type\":\"bool\"}],\"name\":\"TaggedRootBlessVotesReset\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"}],\"name\":\"TaggedRootBlessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"weight\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"remainingAccumulatedWeight\",\"type\":\"uint16\"}],\"name\":\"UnvotedToCurse\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"weight\",\"type\":\"uint8\"}],\"name\":\"VotedToBless\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"weight\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"blockTimestamp\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"}],\"name\":\"VotedToCurse\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"getBlessProgress\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"blessVoteAddrs\",\"type\":\"address[]\"},{\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"blessed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"getCurseProgress\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"curseVoteAddrs\",\"type\":\"address[]\"},{\"internalType\":\"bytes28[]\",\"name\":\"cursesHashes\",\"type\":\"bytes28[]\"},{\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"cursed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCursedSubjectsCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPermaBlessedCommitStores\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"getRecordedCurseRelatedOps\",\"outputs\":[{\"components\":[{\"internalType\":\"enumRMN.RecordedCurseRelatedOpTag\",\"name\":\"tag\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"blockTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"cursed\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"}],\"internalType\":\"structRMN.RecordedCurseRelatedOp[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRecordedCurseRelatedOpsCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16[]\",\"name\":\"subjects\",\"type\":\"bytes16[]\"}],\"name\":\"ownerCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"ownerRemoveThenAddPermaBlessedCommitStores\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot[]\",\"name\":\"taggedRoots\",\"type\":\"tuple[]\"}],\"name\":\"ownerResetBlessVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"}],\"internalType\":\"structRMN.UnvoteToCurseRequest\",\"name\":\"unit\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"forceUnvote\",\"type\":\"bool\"}],\"internalType\":\"structRMN.OwnerUnvoteToCurseRequest[]\",\"name\":\"ownerUnvoteToCurseRequests\",\"type\":\"tuple[]\"}],\"name\":\"ownerUnvoteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"}],\"internalType\":\"structRMN.UnvoteToCurseRequest[]\",\"name\":\"unvoteToCurseRequests\",\"type\":\"tuple[]\"}],\"name\":\"unvoteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot[]\",\"name\":\"taggedRoots\",\"type\":\"tuple[]\"}],\"name\":\"voteToBless\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16[]\",\"name\":\"subjects\",\"type\":\"bytes16[]\"}],\"name\":\"voteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b506040516200596238038062005962833981016040819052620000349162000aff565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000138565b505060408051608081018252600080825260208201819052918101919091526001600160c81b03606082015290506001620000fb81601062000c7d565b82606001516001600160c81b0316901c6001600160c81b0316101562000125576200012562000c99565b506200013181620001e3565b5062000e14565b336001600160a01b03821603620001925760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001ee816200071d565b6200020c576040516306b7c75960e31b815260040160405180910390fd5b602081015160038054604084015161ffff908116620100000263ffffffff199092169316929092179190911790555b60025415620003465760028054600091906200025a9060019062000c7d565b815481106200026d576200026d62000caf565b6000918252602080832060408051608081018252600294850290920180546001600160a01b0390811680855260019092015480821685870190815260ff600160a01b8304811687870152600160a81b909204909116606086015291875260058552828720805465ffffffffffff19169055905116855260099092529220805461ffff191690558054919250908062000309576200030962000cc5565b60008281526020902060026000199092019182020180546001600160a01b031916815560010180546001600160b01b03191690559055506200023b565b60005b81515181101562000403578151805160029190839081106200036f576200036f62000caf565b602090810291909101810151825460018181018555600094855293839020825160029092020180546001600160a01b039283166001600160a01b0319909116178155928201519284018054604084015160609094015160ff908116600160a81b0260ff60a81b1991909516600160a01b026001600160a81b0319909216959093169490941793909317161790550162000349565b50600480546000906200041c9063ffffffff1662000cdb565b82546101009290920a63ffffffff8181021990931691831602179091556004541660005b82515160ff821610156200054157600083600001518260ff16815181106200046c576200046c62000caf565b602090810291909101810151604080516060808201835263ffffffff80891683528385015160ff90811684880190815289821685870190815287516001600160a01b03908116600090815260058b5288812097518854945193518616650100000000000260ff60281b199487166401000000000264ffffffffff1990961691909716179390931791909116939093179094558587015190911683526009909552919020805491909201519092166101000261ffff1990921691909117600117905550620005398162000d01565b905062000440565b506001600160a01b0360005260096020527f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a7805461ffff191660011790556004805463ffffffff4381166401000000000263ffffffff60201b1990921691909117909155604051908216907f8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a990620005db90859062000d23565b60405180910390a26040805160c08101825260048082526001600160401b03421660208301526000928201839052606082018390526080820183905260a08201839052600c80546001808201835591909452825160029094027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018054939490939092849260ff19909216919084908111156200067c576200067c62000dce565b021790555060208201518154604084015160608501516001600160a01b03166a010000000000000000000002600160501b600160f01b031991151569010000000000000000000260ff60481b196001600160401b039095166101000294909416610100600160501b031990931692909217929092179190911617815560808083015160a090930151811c600160801b0292901c919091176001909101555050565b80515160009015806200073257508151516010105b80620007445750602082015161ffff16155b80620007565750604082015161ffff16155b156200076457506000919050565b600080600084600001515160026200077d919062000de4565b6001600160401b0381111562000797576200079762000a24565b604051908082528060200260200182016040528015620007c1578160200160208202803683370190505b50905060005b8551518110156200095457600086600001518281518110620007ed57620007ed62000caf565b6020026020010151905060006001600160a01b031681600001516001600160a01b0316148062000828575060208101516001600160a01b0316155b806200083f575060208101516001600160a01b0316155b8062000858575060208101516001600160a01b03908116145b806200087a5750604081015160ff161580156200087a5750606081015160ff16155b156200088d575060009695505050505050565b8051836200089d84600262000de4565b620008aa90600062000dfe565b81518110620008bd57620008bd62000caf565b6001600160a01b0390921660209283029190910182015281015183620008e584600262000de4565b620008f290600162000dfe565b8151811062000905576200090562000caf565b6001600160a01b03909216602092830291909101909101526040810151620009319060ff168662000dfe565b9450806060015160ff168462000948919062000dfe565b935050600101620007c7565b5060005b8151811015620009f957600082828151811062000979576200097962000caf565b60200260200101519050600082600162000994919062000dfe565b90505b8351811015620009ee57838181518110620009b657620009b662000caf565b60200260200101516001600160a01b0316826001600160a01b031603620009e557506000979650505050505050565b60010162000997565b505060010162000958565b50846020015161ffff16831015801562000a1b5750846040015161ffff168210155b95945050505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b038111828210171562000a5f5762000a5f62000a24565b60405290565b604051608081016001600160401b038111828210171562000a5f5762000a5f62000a24565b604051601f8201601f191681016001600160401b038111828210171562000ab55762000ab562000a24565b604052919050565b80516001600160a01b038116811462000ad557600080fd5b919050565b805160ff8116811462000ad557600080fd5b805161ffff8116811462000ad557600080fd5b6000602080838503121562000b1357600080fd5b82516001600160401b038082111562000b2b57600080fd5b8185019150606080838803121562000b4257600080fd5b62000b4c62000a3a565b83518381111562000b5c57600080fd5b8401601f8101891362000b6e57600080fd5b80518481111562000b835762000b8362000a24565b62000b93878260051b0162000a8a565b818152878101955060079190911b82018701908a82111562000bb457600080fd5b918701915b8183101562000c33576080838c03121562000bd45760008081fd5b62000bde62000a65565b62000be98462000abd565b815262000bf889850162000abd565b89820152604062000c0b81860162000ada565b9082015262000c1c84870162000ada565b818701528652948701946080929092019162000bb9565b83525062000c45905084860162000aec565b8582015262000c576040850162000aec565b6040820152979650505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000c935762000c9362000c67565b92915050565b634e487b7160e01b600052600160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600063ffffffff80831681810362000cf75762000cf762000c67565b6001019392505050565b600060ff821660ff810362000d1a5762000d1a62000c67565b60010192915050565b60006020808352608080840185516060808588015282825180855260a0890191508684019450600093505b8084101562000da157845180516001600160a01b03908116845288820151168884015260408082015160ff9081169185019190915290840151168383015293860193600193909301929085019062000d4e565b509488015161ffff8116604089015294604089015161ffff811660608a0152955098975050505050505050565b634e487b7160e01b600052602160045260246000fd5b808202811582820484141762000c935762000c9362000c67565b8082018082111562000c935762000c9362000c67565b614b3e8062000e246000396000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063631ec73e116100d8578063979986111161008c578063d927f26711610066578063d927f26714610354578063f2fde38b14610374578063f33f28951461038757600080fd5b8063979986111461030b578063ba86a1f01461031e578063bd147ef41461033157600080fd5b806379ba5097116100bd57806379ba5097146102d35780638da5cb5b146102db578063970b8fc21461030357600080fd5b8063631ec73e146102ad5780636ba0526d146102c057600080fd5b8063397796f71161013a5780634102e4f4116101145780634102e4f4146102745780634d61677114610287578063586abe3c1461029a57600080fd5b8063397796f7146102425780633d0cf6101461024a5780633f42ab731461025d57600080fd5b8063181f5a771161016b578063181f5a77146101ba5780632cbc26bb14610203578063328d716c1461022657600080fd5b80630b009be21461018757806315c65588146101a5575b600080fd5b61018f6103a9565b60405161019c9190613e3f565b60405180910390f35b6101b86101b3366004613fdd565b6103ba565b005b6101f66040518060400160405280600d81526020017f524d4e20312e352e302d6465760000000000000000000000000000000000000081525081565b60405161019c9190614083565b6102166102113660046140f0565b6104e6565b604051901515815260200161019c565b600b5467ffffffffffffffff165b60405190815260200161019c565b6102166105b1565b6101b86102583660046141a0565b61068b565b6102656107ff565b60405161019c939291906142b3565b6101b86102823660046142ff565b610929565b610216610295366004614439565b61093d565b6101b86102a8366004614451565b6109cd565b6101b86102bb3660046144fc565b610a87565b6101b86102ce366004614451565b610ca0565b6101b8610d13565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019c565b600c54610234565b6101b86103193660046145d0565b610e10565b6101b861032c3660046145d0565b611368565b61034461033f3660046140f0565b61150d565b60405161019c9493929190614645565b6103676103623660046146b6565b611946565b60405161019c9190614707565b6101b8610382366004614800565b611b68565b61039a610395366004614439565b611b79565b60405161019c9392919061481b565b60606103b56007611de1565b905090565b336000818152600960205260409020805460ff16610421576040517f85412e7f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b60045463ffffffff166000805b85518110156104a757600086828151811061044b5761044b614849565b602002602001015190506000610465858360000151611df5565b905060008061047b6001888b8760008d89611fd6565b91509150801561048d5761048d614878565b85806104965750815b95505050505080600101905061042e565b50806104df576040517ffb106b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b600b5460009067ffffffffffffffff16810361050457506000919050565b7f0100000000000000000000000000000100000000000000000000000000000000600052600a6020527fcf943f0e419056430919a3fdfd72276bc0b123ebdd670f4152b82bffbfb8bb385468010000000000000000900460ff16806105a657507fffffffffffffffffffffffffffffffff0000000000000000000000000000000082166000908152600a602052604090205468010000000000000000900460ff165b92915050565b919050565b600b5460009067ffffffffffffffff1681036105cd5750600090565b7f0100000000000000000000000000000100000000000000000000000000000000600052600a6020527fcf943f0e419056430919a3fdfd72276bc0b123ebdd670f4152b82bffbfb8bb385468010000000000000000900460ff16806103b55750507f0100000000000000000000000000000000000000000000000000000000000000600052600a6020527f1d4cd6d2639449a552dbfb463b59316946d78c518b3170daa4a4c217bef019ba5468010000000000000000900460ff1690565b6106936126a4565b60005b8251811015610746576106cc8382815181106106b4576106b4614849565b6020026020010151600761272790919063ffffffff16565b1561073e577fdca892154bbc36d0c05ccd01b3d0411875cb1b841fcdeebb384e5d0d6eb06b4483828151811061070457610704614849565b6020026020010151604051610735919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a15b600101610696565b5060005b81518110156107fa5761078082828151811061076857610768614849565b6020026020010151600761274990919063ffffffff16565b156107f2577f66b4b4752c65ae8cd2f3a0a48c7dc8b2118c60d5ea15514992eb2ddf56c9cb158282815181106107b8576107b8614849565b60200260200101516040516107e9919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a15b60010161074a565b505050565b6040805160608082018352808252600060208084018290528385018290526004548551600280549384028201608090810190985294810183815263ffffffff808416986401000000009094041696959194919385939192859285015b828210156108f95760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff740100000000000000000000000000000000000000008204811693850193909352750100000000000000000000000000000000000000000090049091166060830152908352909201910161085b565b505050908252506001919091015461ffff8082166020840152620100009091041660409091015292939192919050565b6109316126a4565b61093a8161276b565b50565b600060068161099b610954368690038601866148a7565b80516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b815260208101919091526040016000205460ff16806105a657506105a66109c56020840184614800565b600790612eef565b337fffffffffffffffffffffffff000000000000000000000000000000000000000181016109fd576109fd614878565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600960205260409020805460ff16610a75576040517f85412e7f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610418565b610a8182858584612f1e565b50505050565b610a8f6126a4565b600454600090819063ffffffff16815b8451811015610b66576000858281518110610abc57610abc614849565b602002602001015190506000610ada84836020015160000151611df5565b9050600080610b3d600087866000015187602001518860400151600960008b6000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002089611fd6565b915091508680610b4a5750815b96508780610b555750805b975050505050806001019050610a9f565b508215610c615760408051600280546080602082028401810190945260608301818152610c61948492849160009085015b82821015610c355760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff7401000000000000000000000000000000000000000082048116938501939093527501000000000000000000000000000000000000000000900490911660608301529083529092019101610b97565b505050908252506001919091015461ffff8082166020840152620100009091041660409091015261276b565b8180610c6a5750825b610a81576040517ffb106b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca86126a4565b73ffffffffffffffffffffffffffffffffffffffff60005260096020527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a7610a8182858584612f1e565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610418565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e397f01000000000000000000000000000001000000000000000000000000000000006104e6565b15610e70576040517fcde2d97c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454336000908152600560209081526040918290208251606081018452905463ffffffff81811680845260ff64010000000084048116958501959095526501000000000090920490931693820193909352921691908214610f00576040517f85412e7f000000000000000000000000000000000000000000000000000000008152336004820152602401610418565b600160005b8481101561132f576000868683818110610f2157610f21614849565b905060400201803603810190610f3791906148a7565b90506000610f868280516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b6000818152600660209081526040918290208251608081018452905460ff81161580158352610100820463ffffffff169383019390935265010000000000810461ffff169382019390935267010000000000000090920478ffffffffffffffffffffffffffffffffffffffffffffffffff16606083015291925090611062573373ffffffffffffffffffffffffffffffffffffffff168763ffffffff167f274d6d5b916b0a53974b7ab86c844b97a2e03a60f658cd9a4b1c028b604d7bf18560405161105291906148e0565b60405180910390a3505050611327565b8663ffffffff16816020015163ffffffff16146110a8575060408051608081018252600080825263ffffffff89166020830152918101829052606081019190915261110c565b6110ba816060015187604001516136d6565b1561110c573373ffffffffffffffffffffffffffffffffffffffff168763ffffffff167f6dfbb745226fa630aeb1b9557d17d508ddb789a04f0cb873ec16e58beb8beead8560405161105291906148e0565b6000945061112281606001518760400151613718565b78ffffffffffffffffffffffffffffffffffffffffffffffffff166060820152602086015160408201805160ff9092169161115e90839061493c565b61ffff1690525060208681015160408051865173ffffffffffffffffffffffffffffffffffffffff168152868401519381019390935260ff9091168282015251339163ffffffff8a16917f2a08a2bd2798f0aae9a843f0f4ad4de488c1b3d5f04049940cfed736ad69fb979181900360600190a3600354604082015161ffff91821691161061125757600181526040808201518151855173ffffffffffffffffffffffffffffffffffffffff1681526020808701519082015261ffff90911681830152905163ffffffff8916917f8257378aa73bf8e4ada848713526584a3dcee0fd3db3beed7397f7a7f5067cc9919081900360600190a25b60009182526006602090815260409283902082518154928401519484015160609094015178ffffffffffffffffffffffffffffffffffffffffffffffffff166701000000000000000266ffffffffffffff61ffff90951665010000000000029490941664ffffffffff63ffffffff909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090941693909317179390931617179055505b600101610f05565b5080156104df576040517f604c767700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113706126a4565b60045463ffffffff1660005b82811015610a8157600084848381811061139857611398614849565b9050604002018036038101906113ae91906148a7565b905060006113fd8280516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b60008181526006602081815260408084208151608081018352815460ff811615158252610100810463ffffffff90811683870190815265010000000000830461ffff169584019590955267010000000000000090910478ffffffffffffffffffffffffffffffffffffffffffffffffff16606083015287875294909352939093558051925193945092878216911614806114945750805b156114fe5760408051855173ffffffffffffffffffffffffffffffffffffffff1681526020808701519082015282151581830152905163ffffffff8816917f7d15a6eebaa019ea7d5b7d38937c51ebd3befbfdf51bb630a694fd28635bbcba919081900360600190a25b5050505080600101905061137c565b600454604080516002805460806020820284018101909452606083810182815290958695600095869563ffffffff9093169486949193928492918491879085015b828210156115ec5760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff740100000000000000000000000000000000000000008204811693850193909352750100000000000000000000000000000000000000000090049091166060830152908352909201910161154e565b505050908252506001919091015461ffff80821660208085019190915262010000909204166040928301527fffffffffffffffffffffffffffffffff000000000000000000000000000000008a166000908152600a909152908120805460ff6801000000000000000082041696509293509163ffffffff80861691161080156116725750845b6000965090508560015b60028111611939578451515b6000808760000151518310156116e35787518051849081106116ac576116ac614849565b6020026020010151602001519150876000015183815181106116d0576116d0614849565b602002602001015160600151905061170a565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905060005b73ffffffffffffffffffffffffffffffffffffffff82166000908152600188016020908152604080832081518083019092525463ffffffff811682526401000000009004821b63ffffffff19169181019190915290878061177a57508a63ffffffff16826000015163ffffffff16145b8061179a575073ffffffffffffffffffffffffffffffffffffffff848116145b80156117b05750602082015163ffffffff191615155b9050801561186d57856001036117d0576117c987614957565b965061186d565b85600203610182576117e560ff84168e61493c565b9c506117f08761498f565b9650838f888151811061180557611805614849565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505081602001518e888151811061185657611856614849565b63ffffffff19909216602092830291909101909101525b84156118835761187c8561498f565b945061188c565b50505050611895565b50505050611688565b81600103611928578267ffffffffffffffff8111156118b6576118b6613e52565b6040519080825280602002602001820160405280156118df578160200160208202803683370190505b509a508267ffffffffffffffff8111156118fb576118fb613e52565b604051908082528060200260200182016040528015611924578160200160208202803683370190505b5099505b5061193281614957565b905061167c565b5050505050509193509193565b600c5460609060009061195984866149c4565b11611965575081611988565b600c5484101561198457600c5461197d9085906149d7565b9050611988565b5060005b60008167ffffffffffffffff8111156119a3576119a3613e52565b604051908082528060200260200182016040528015611a2157816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816119c15790505b50905060005b82811015611b5f57600c611a3b82886149c4565b81548110611a4b57611a4b614849565b600091825260209091206040805160c081019091526002909202018054829060ff166004811115611a7e57611a7e6146d8565b6004811115611a8f57611a8f6146d8565b81528154610100810467ffffffffffffffff1660208301526901000000000000000000810460ff16151560408301526a0100000000000000000000900473ffffffffffffffffffffffffffffffffffffffff166060820152600190910154608081811b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000090811682850152700100000000000000000000000000000000909204901b1660a0909101528251839083908110611b4c57611b4c614849565b6020908102919091010152600101611a27565b50949350505050565b611b706126a4565b61093a8161373b565b606060008080611b91610954368790038701876148a7565b6000818152600660209081526040918290208251608081018452905460ff81161515808352610100820463ffffffff90811694840185905265010000000000830461ffff169584019590955267010000000000000090910478ffffffffffffffffffffffffffffffffffffffffffffffffff166060830152600454909650939450929091169003611dd85760408101516060820151909450611c3281613830565b60ff1667ffffffffffffffff811115611c4d57611c4d613e52565b604051908082528060200260200182016040528015611c76578160200160208202803683370190505b506002805460408051602080840282018101909252828152939950600093929190849084015b82821015611d3a5760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff7401000000000000000000000000000000000000000082048116938501939093527501000000000000000000000000000000000000000000900490911660608301529083529092019101611c9c565b5050505090506000805b82518160ff161015611dd357611d5a84826136d6565b15611dc357828160ff1681518110611d7457611d74614849565b602002602001015160000151898381518110611d9257611d92614849565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152611dc082614957565b91505b611dcc816149ea565b9050611d44565b505050505b50509193909250565b60606000611dee8361389f565b9392505050565b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166000908152600a60205260408120805463ffffffff858116911614611dee57805463ffffffff19811663ffffffff861690811783556003547fffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000909216176201000090910461ffff1664010000000002177fffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffff1680825568010000000000000000900460ff1615611dee57600260005b8154811015611fcd576000826000018281548110611ee657611ee6614849565b6000918252602080832060016002909302018281015473ffffffffffffffffffffffffffffffffffffffff1684529187019052604090912080549192509063ffffffff808a169116108015611f4d57508054640100000000900460201b63ffffffff191615155b15611fc357805463ffffffff191663ffffffff891617815560018201548554750100000000000000000000000000000000000000000090910460ff16908690600690611fa89084906601000000000000900461ffff1661493c565b92506101000a81548161ffff021916908361ffff1602179055505b5050600101611ec6565b50509392505050565b6000806001896001811115611fed57611fed6146d8565b148061200a57506000896001811115612008576120086146d8565b145b61201657612016614878565b8480612037575073ffffffffffffffffffffffffffffffffffffffff878116145b80612056575073ffffffffffffffffffffffffffffffffffffffff8716155b1561207c57600089600181111561206f5761206f6146d8565b1461207c5761207c614878565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260018401602090815260409182902082518084019093525463ffffffff811683526401000000009004811b63ffffffff191690820152845460ff16801561210d575073ffffffffffffffffffffffffffffffffffffffff888116148061210d57508863ffffffff16816000015163ffffffff16145b80156121235750602081015163ffffffff191615155b801561214b5750866020015163ffffffff1916816020015163ffffffff1916148061214b5750855b156122765773ffffffffffffffffffffffffffffffffffffffff881660009081526001858101602052604082209190915585548554919450610100900460ff169085906006906121aa9084906601000000000000900461ffff16614a09565b825461010092830a61ffff818102199092169282160291909117909255895188546020808d01518a54604080517fffffffffffffffffffffffffffffffff0000000000000000000000000000000090961686529590930460ff169184019190915263ffffffff1916828401526601000000000000900490921660608301525173ffffffffffffffffffffffffffffffffffffffff8b16925063ffffffff8c16917fa96a155bd67c927a6c056befbd979b78465e2b2f1276bf7d4e90a31d4f430aa8919081900360800190a35b6000808b600181111561228b5761228b6146d8565b1480156122b3575083806122b3575073ffffffffffffffffffffffffffffffffffffffff8916155b90508080156122cf5750845468010000000000000000900460ff165b80156122e157506122df856138fb565b155b156123b45784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555600b80546001945060009061232a9067ffffffffffffffff16614a24565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f65d0e78c3625f0956f58610cf0fb157eaf627683258875ef29af2f71d25ac8fd88600001516040516123ab91907fffffffffffffffffffffffffffffffff0000000000000000000000000000000091909116815260200190565b60405180910390a15b83806123bd5750825b15612605576000808c60018111156123d7576123d76146d8565b036123f25787156123ea5750600361240f565b50600261240f565b60018c6001811115612406576124066146d8565b03610182575060015b600c6040518060c0016040528083600481111561242e5761242e6146d8565b81526020014267ffffffffffffffff168152885468010000000000000000900460ff16151560208083019190915273ffffffffffffffffffffffffffffffffffffffff8e1660408301528c517fffffffffffffffffffffffffffffffff00000000000000000000000000000000166060830152600060809092018290528354600180820186559483529120825160029092020180549293909283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911690836004811115612500576125006146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c9190911760019091015550612696565b8751602080840151818b0151604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909516855263ffffffff1992831693850193909352169082015273ffffffffffffffffffffffffffffffffffffffff8a16907fbabb0d7099e6ca14a29fad2a2cfb4fda2bd30f97cb3c27e546174bfb4277c1cc9060600160405180910390a25b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612725576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610418565b565b6000611dee8373ffffffffffffffffffffffffffffffffffffffff841661395c565b6000611dee8373ffffffffffffffffffffffffffffffffffffffff8416613a56565b61277481613aa5565b6127aa576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015160038054604084015161ffff908116620100000263ffffffff199092169316929092179190911790555b6002541561298e5760028054600091906127f5906001906149d7565b8154811061280557612805614849565b60009182526020808320604080516080810182526002948502909201805473ffffffffffffffffffffffffffffffffffffffff90811680855260019092015480821685870190815260ff740100000000000000000000000000000000000000008304811687870152750100000000000000000000000000000000000000000090920490911660608601529187526005855282872080547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000016905590511685526009909252922080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690558054919250908061290457612904614a66565b60008281526020902060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019182020180547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560010180547fffffffffffffffffffff000000000000000000000000000000000000000000001690559055506127d9565b60005b815151811015612ac1578151805160029190839081106129b3576129b3614849565b6020908102919091018101518254600181810185556000948552938390208251600290920201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116178155928201519284018054604084015160609094015160ff9081167501000000000000000000000000000000000000000000027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff9190951674010000000000000000000000000000000000000000027fffffffffffffffffffffff0000000000000000000000000000000000000000009092169590931694909417939093171617905501612991565b5060048054600090612ad89063ffffffff16614a95565b82546101009290920a63ffffffff8181021990931691831602179091556004541660005b82515160ff82161015612c5557600083600001518260ff1681518110612b2457612b24614849565b602090810291909101810151604080516060808201835263ffffffff80891683528385015160ff908116848801908152898216858701908152875173ffffffffffffffffffffffffffffffffffffffff908116600090815260058b528881209751885494519351861665010000000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff948716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009096169190971617939093179190911693909317909455858701519091168352600990955291902080549190920151909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090921691909117600117905550612c4e816149ea565b9050612afc565b5073ffffffffffffffffffffffffffffffffffffffff60005260096020527f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660011790556004805463ffffffff438116640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff90921691909117909155604051908216907f8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a990612d2f908590614ab8565b60405180910390a26040805160c081018252600480825267ffffffffffffffff421660208301526000928201839052606082018390526080820183905260a08201839052600c80546001808201835591909452825160029094027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805493949093909284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090921691908490811115612dec57612dec6146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c919091176001909101555050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611dee565b8151600003612f59576040517f55e9b08b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008316600090815260018201602052604090205460ff1615613007576040517f078f340000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201527fffffffffffffffffffffffffffffffff0000000000000000000000000000000084166024820152604401610418565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008316600090815260018281016020526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905560045463ffffffff16905b83518110156136ce57600181101580156130ed575083818151811061309657613096614849565b60200260200101516fffffffffffffffffffffffffffffffff1916846001836130bf91906149d7565b815181106130cf576130cf614849565b60200260200101516fffffffffffffffffffffffffffffffff191610155b15613124576040517f2432d8ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084828151811061313857613138614849565b60200260200101519050600061314e8483611df5565b73ffffffffffffffffffffffffffffffffffffffff8981166000818152600184016020908152604080832081518083019092525463ffffffff811682526401000000009004821b63ffffffff19169181019190915293945091148015906131be5750815163ffffffff8088169116105b806131d25750602082015163ffffffff1916155b15613225575085548254600091610100900460ff169084906006906132069084906601000000000000900461ffff1661493c565b92506101000a81548161ffff021916908361ffff16021790555061322c565b5060208101515b60408051808201825263ffffffff88168152815163ffffffff1984166020828101919091527fffffffffffffffffffffffffffffffff000000000000000000000000000000008d16828501528351808303850181526060909201909352805190830120909182019063ffffffff1916905273ffffffffffffffffffffffffffffffffffffffff8b166000818152600186016020908152604090912083518285015190921c6401000000000263ffffffff92831617905589549294509091908816907f8137bc8a8d712aaa27bfc6506d5566ac405618bd53f9831b8ca6b6fe5442ee7a9087908d9060ff610100909104166133234290565b6020898101518b54604080517fffffffffffffffffffffffffffffffff000000000000000000000000000000009889168152979096169287019290925260ff9093169385019390935267ffffffffffffffff16606084015263ffffffff191660808301526601000000000000900461ffff1660a082015260c00160405180910390a363ffffffff1981161580156133c85750825468010000000000000000900460ff16155b80156133d857506133d8836138fb565b156134c35782547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff1668010000000000000000178355600b80546000906134289067ffffffffffffffff16614acb565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508563ffffffff167fcfdbfd8ce9a56b5f7c202c0e102184d24f47ca87121dc165063fc4c290957bde8561347e4290565b604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909316835267ffffffffffffffff90911660208301520160405180910390a25b6040805160c081018252600080825267ffffffffffffffff42166020830152855460ff680100000000000000009091041615159282019290925273ffffffffffffffffffffffffffffffffffffffff8c1660608201527fffffffffffffffffffffffffffffffff0000000000000000000000000000000086811660808301528b1660a0820152600c80546001808201835591909352815160029093027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805492939092909183917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908360048111156135c0576135c06146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c9190911760019182015594909401935061306f92505050565b505050505050565b600060108260ff16106136eb576136eb614878565b50600160ff82161b821678ffffffffffffffffffffffffffffffffffffffffffffffffff16151592915050565b600060108260ff161061372d5761372d614878565b50600160ff919091161b1790565b3373ffffffffffffffffffffffffffffffffffffffff8216036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610418565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006201000078ffffffffffffffffffffffffffffffffffffffffffffffffff83161061385f5761385f614878565b78ffffffffffffffffffffffffffffffffffffffffffffffffff8216156105ac5761388b600183614ae8565b90911690613898816149ea565b905061385f565b6060816000018054806020026020016040519081016040528092919081815260200182805480156138ef57602002820191906000526020600020905b8154815260200190600101908083116138db575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff600090815260018201602090815260408220546401000000009004901b63ffffffff19161515806105a65750505461ffff64010000000082048116660100000000000090920416101590565b60008181526001830160205260408120548015613a455760006139806001836149d7565b8554909150600090613994906001906149d7565b90508181146139f95760008660000182815481106139b4576139b4614849565b90600052602060002001549050808760000184815481106139d7576139d7614849565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613a0a57613a0a614a66565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105a6565b60009150506105a6565b5092915050565b6000818152600183016020526040812054613a9d575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105a6565b5060006105a6565b8051516000901580613ab957508151516010105b80613aca5750602082015161ffff16155b80613adb5750604082015161ffff16155b15613ae857506000919050565b60008060008460000151516002613aff9190614b1a565b67ffffffffffffffff811115613b1757613b17613e52565b604051908082528060200260200182016040528015613b40578160200160208202803683370190505b50905060005b855151811015613d1157600086600001518281518110613b6857613b68614849565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161480613bc95750602081015173ffffffffffffffffffffffffffffffffffffffff16155b80613bec5750602081015173ffffffffffffffffffffffffffffffffffffffff16155b80613c115750602081015173ffffffffffffffffffffffffffffffffffffffff908116145b80613c315750604081015160ff16158015613c315750606081015160ff16155b15613c43575060009695505050505050565b805183613c51846002614b1a565b613c5c9060006149c4565b81518110613c6c57613c6c614849565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015281015183613c9f846002614b1a565b613caa9060016149c4565b81518110613cba57613cba614849565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526040810151613cf19060ff16866149c4565b9450806060015160ff1684613d0691906149c4565b935050600101613b46565b5060005b8151811015613dc3576000828281518110613d3257613d32614849565b602002602001015190506000826001613d4b91906149c4565b90505b8351811015613db957838181518110613d6957613d69614849565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613db157506000979650505050505050565b600101613d4e565b5050600101613d15565b50846020015161ffff168310158015613de45750846040015161ffff168210155b95945050505050565b60008151808452602080850194506020840160005b83811015613e3457815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613e02565b509495945050505050565b602081526000611dee6020830184613ded565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613ea457613ea4613e52565b60405290565b6040516060810167ffffffffffffffff81118282101715613ea457613ea4613e52565b6040516080810167ffffffffffffffff81118282101715613ea457613ea4613e52565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613f3757613f37613e52565b604052919050565b600067ffffffffffffffff821115613f5957613f59613e52565b5060051b60200190565b80357fffffffffffffffffffffffffffffffff00000000000000000000000000000000811681146105ac57600080fd5b600060408284031215613fa557600080fd5b613fad613e81565b9050613fb882613f63565b8152602082013563ffffffff1981168114613fd257600080fd5b602082015292915050565b60006020808385031215613ff057600080fd5b823567ffffffffffffffff81111561400757600080fd5b8301601f8101851361401857600080fd5b803561402b61402682613f3f565b613ef0565b8082825260208201915060208360061b85010192508783111561404d57600080fd5b6020840193505b82841015614078576140668885613f93565b82528482019150604084019350614054565b979650505050505050565b60006020808352835180602085015260005b818110156140b157858101830151858201604001528201614095565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561410257600080fd5b611dee82613f63565b803573ffffffffffffffffffffffffffffffffffffffff811681146105ac57600080fd5b600082601f83011261414057600080fd5b8135602061415061402683613f3f565b8083825260208201915060208460051b87010193508684111561417257600080fd5b602086015b84811015614195576141888161410b565b8352918301918301614177565b509695505050505050565b600080604083850312156141b357600080fd5b823567ffffffffffffffff808211156141cb57600080fd5b6141d78683870161412f565b935060208501359150808211156141ed57600080fd5b506141fa8582860161412f565b9150509250929050565b8051606080845281518482018190526000926080916020918201918388019190865b82811015614280578451805173ffffffffffffffffffffffffffffffffffffffff908116865283820151168386015260408082015160ff908116918701919091529088015116878501529381019392850192600101614226565b508781015161ffff81168a83015295505050604086015193506142a9604088018561ffff169052565b9695505050505050565b600063ffffffff808616835280851660208401525060606040830152613de46060830184614204565b803560ff811681146105ac57600080fd5b803561ffff811681146105ac57600080fd5b6000602080838503121561431257600080fd5b823567ffffffffffffffff8082111561432a57600080fd5b8185019150606080838803121561434057600080fd5b614348613eaa565b83358381111561435757600080fd5b84019250601f8301881361436a57600080fd5b823561437861402682613f3f565b81815260079190911b8401860190868101908a83111561439757600080fd5b948701945b82861015614409576080868c0312156143b55760008081fd5b6143bd613ecd565b6143c68761410b565b81526143d389880161410b565b8982015260406143e48189016142dc565b908201526143f38787016142dc565b818701528252608095909501949087019061439c565b83525061441990508486016142ed565b85820152614429604085016142ed565b6040820152979650505050505050565b60006040828403121561444b57600080fd5b50919050565b6000806040838503121561446457600080fd5b61446d83613f63565b915060208084013567ffffffffffffffff81111561448a57600080fd5b8401601f8101861361449b57600080fd5b80356144a961402682613f3f565b81815260059190911b820183019083810190888311156144c857600080fd5b928401925b828410156144ed576144de84613f63565b825292840192908401906144cd565b80955050505050509250929050565b6000602080838503121561450f57600080fd5b823567ffffffffffffffff81111561452657600080fd5b8301601f8101851361453757600080fd5b803561454561402682613f3f565b81815260079190911b8201830190838101908783111561456457600080fd5b928401925b8284101561407857608084890312156145825760008081fd5b61458a613eaa565b6145938561410b565b81526145a189878701613f93565b86820152606085013580151581146145b95760008081fd5b604082015282526080939093019290840190614569565b600080602083850312156145e357600080fd5b823567ffffffffffffffff808211156145fb57600080fd5b818501915085601f83011261460f57600080fd5b81358181111561461e57600080fd5b8660208260061b850101111561463357600080fd5b60209290920196919550909350505050565b6080815260006146586080830187613ded565b82810360208481019190915286518083528782019282019060005b8181101561469657845163ffffffff191683529383019391830191600101614673565b505061ffff96909616604085015250505090151560609091015292915050565b600080604083850312156146c957600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208082528251828201819052600091906040908185019086840185805b838110156147f2578251805160058110614766577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b86528088015167ffffffffffffffff16888701528681015115158787015260608082015173ffffffffffffffffffffffffffffffffffffffff16908701526080808201517fffffffffffffffffffffffffffffffff000000000000000000000000000000009081169188019190915260a091820151169086015260c09094019391860191600101614725565b509298975050505050505050565b60006020828403121561481257600080fd5b611dee8261410b565b60608152600061482e6060830186613ded565b61ffff94909416602083015250901515604090910152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000604082840312156148b957600080fd5b6148c1613e81565b6148ca8361410b565b8152602083013560208201528091505092915050565b815173ffffffffffffffffffffffffffffffffffffffff16815260208083015190820152604081016105a6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff818116838216019080821115613a4f57613a4f61490d565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036149885761498861490d565b5060010190565b60008161499e5761499e61490d565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b808201808211156105a6576105a661490d565b818103818111156105a6576105a661490d565b600060ff821660ff8103614a0057614a0061490d565b60010192915050565b61ffff828116828216039080821115613a4f57613a4f61490d565b600067ffffffffffffffff821680614a3e57614a3e61490d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600063ffffffff808316818103614aae57614aae61490d565b6001019392505050565b602081526000611dee6020830184614204565b600067ffffffffffffffff808316818103614aae57614aae61490d565b78ffffffffffffffffffffffffffffffffffffffffffffffffff828116828216039080821115613a4f57613a4f61490d565b80820281158282048414176105a6576105a661490d56fea164736f6c6343000818000a", +} + +var ARMContractABI = ARMContractMetaData.ABI + +var ARMContractBin = ARMContractMetaData.Bin + +func DeployARMContract(auth *bind.TransactOpts, backend bind.ContractBackend, config RMNConfig) (common.Address, *types.Transaction, *ARMContract, error) { + parsed, err := ARMContractMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ARMContractBin), backend, config) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ARMContract{address: address, abi: *parsed, ARMContractCaller: ARMContractCaller{contract: contract}, ARMContractTransactor: ARMContractTransactor{contract: contract}, ARMContractFilterer: ARMContractFilterer{contract: contract}}, nil +} + +type ARMContract struct { + address common.Address + abi abi.ABI + ARMContractCaller + ARMContractTransactor + ARMContractFilterer +} + +type ARMContractCaller struct { + contract *bind.BoundContract +} + +type ARMContractTransactor struct { + contract *bind.BoundContract +} + +type ARMContractFilterer struct { + contract *bind.BoundContract +} + +type ARMContractSession struct { + Contract *ARMContract + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ARMContractCallerSession struct { + Contract *ARMContractCaller + CallOpts bind.CallOpts +} + +type ARMContractTransactorSession struct { + Contract *ARMContractTransactor + TransactOpts bind.TransactOpts +} + +type ARMContractRaw struct { + Contract *ARMContract +} + +type ARMContractCallerRaw struct { + Contract *ARMContractCaller +} + +type ARMContractTransactorRaw struct { + Contract *ARMContractTransactor +} + +func NewARMContract(address common.Address, backend bind.ContractBackend) (*ARMContract, error) { + abi, err := abi.JSON(strings.NewReader(ARMContractABI)) + if err != nil { + return nil, err + } + contract, err := bindARMContract(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ARMContract{address: address, abi: abi, ARMContractCaller: ARMContractCaller{contract: contract}, ARMContractTransactor: ARMContractTransactor{contract: contract}, ARMContractFilterer: ARMContractFilterer{contract: contract}}, nil +} + +func NewARMContractCaller(address common.Address, caller bind.ContractCaller) (*ARMContractCaller, error) { + contract, err := bindARMContract(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ARMContractCaller{contract: contract}, nil +} + +func NewARMContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ARMContractTransactor, error) { + contract, err := bindARMContract(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ARMContractTransactor{contract: contract}, nil +} + +func NewARMContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ARMContractFilterer, error) { + contract, err := bindARMContract(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ARMContractFilterer{contract: contract}, nil +} + +func bindARMContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ARMContractMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ARMContract *ARMContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ARMContract.Contract.ARMContractCaller.contract.Call(opts, result, method, params...) +} + +func (_ARMContract *ARMContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ARMContract.Contract.ARMContractTransactor.contract.Transfer(opts) +} + +func (_ARMContract *ARMContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ARMContract.Contract.ARMContractTransactor.contract.Transact(opts, method, params...) +} + +func (_ARMContract *ARMContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ARMContract.Contract.contract.Call(opts, result, method, params...) +} + +func (_ARMContract *ARMContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ARMContract.Contract.contract.Transfer(opts) +} + +func (_ARMContract *ARMContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ARMContract.Contract.contract.Transact(opts, method, params...) +} + +func (_ARMContract *ARMContractCaller) GetBlessProgress(opts *bind.CallOpts, taggedRoot IRMNTaggedRoot) (GetBlessProgress, + + error) { + var out []interface{} + err := _ARMContract.contract.Call(opts, &out, "getBlessProgress", taggedRoot) + + outstruct := new(GetBlessProgress) + if err != nil { + return *outstruct, err + } + + outstruct.BlessVoteAddrs = *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + outstruct.AccumulatedWeight = *abi.ConvertType(out[1], new(uint16)).(*uint16) + outstruct.Blessed = *abi.ConvertType(out[2], new(bool)).(*bool) + + return *outstruct, err + +} + +func (_ARMContract *ARMContractSession) GetBlessProgress(taggedRoot IRMNTaggedRoot) (GetBlessProgress, + + error) { + return _ARMContract.Contract.GetBlessProgress(&_ARMContract.CallOpts, taggedRoot) +} + +func (_ARMContract *ARMContractCallerSession) GetBlessProgress(taggedRoot IRMNTaggedRoot) (GetBlessProgress, + + error) { + return _ARMContract.Contract.GetBlessProgress(&_ARMContract.CallOpts, taggedRoot) +} + +func (_ARMContract *ARMContractCaller) GetConfigDetails(opts *bind.CallOpts) (GetConfigDetails, + + error) { + var out []interface{} + err := _ARMContract.contract.Call(opts, &out, "getConfigDetails") + + outstruct := new(GetConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.Version = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.Config = *abi.ConvertType(out[2], new(RMNConfig)).(*RMNConfig) + + return *outstruct, err + +} + +func (_ARMContract *ARMContractSession) GetConfigDetails() (GetConfigDetails, + + error) { + return _ARMContract.Contract.GetConfigDetails(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCallerSession) GetConfigDetails() (GetConfigDetails, + + error) { + return _ARMContract.Contract.GetConfigDetails(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCaller) GetCurseProgress(opts *bind.CallOpts, subject [16]byte) (GetCurseProgress, + + error) { + var out []interface{} + err := _ARMContract.contract.Call(opts, &out, "getCurseProgress", subject) + + outstruct := new(GetCurseProgress) + if err != nil { + return *outstruct, err + } + + outstruct.CurseVoteAddrs = *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + outstruct.CursesHashes = *abi.ConvertType(out[1], new([][28]byte)).(*[][28]byte) + outstruct.AccumulatedWeight = *abi.ConvertType(out[2], new(uint16)).(*uint16) + outstruct.Cursed = *abi.ConvertType(out[3], new(bool)).(*bool) + + return *outstruct, err + +} + +func (_ARMContract *ARMContractSession) GetCurseProgress(subject [16]byte) (GetCurseProgress, + + error) { + return _ARMContract.Contract.GetCurseProgress(&_ARMContract.CallOpts, subject) +} + +func (_ARMContract *ARMContractCallerSession) GetCurseProgress(subject [16]byte) (GetCurseProgress, + + error) { + return _ARMContract.Contract.GetCurseProgress(&_ARMContract.CallOpts, subject) +} + +func (_ARMContract *ARMContractCaller) GetCursedSubjectsCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ARMContract.contract.Call(opts, &out, "getCursedSubjectsCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ARMContract *ARMContractSession) GetCursedSubjectsCount() (*big.Int, error) { + return _ARMContract.Contract.GetCursedSubjectsCount(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCallerSession) GetCursedSubjectsCount() (*big.Int, error) { + return _ARMContract.Contract.GetCursedSubjectsCount(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCaller) GetPermaBlessedCommitStores(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _ARMContract.contract.Call(opts, &out, "getPermaBlessedCommitStores") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_ARMContract *ARMContractSession) GetPermaBlessedCommitStores() ([]common.Address, error) { + return _ARMContract.Contract.GetPermaBlessedCommitStores(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCallerSession) GetPermaBlessedCommitStores() ([]common.Address, error) { + return _ARMContract.Contract.GetPermaBlessedCommitStores(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCaller) GetRecordedCurseRelatedOps(opts *bind.CallOpts, offset *big.Int, limit *big.Int) ([]RMNRecordedCurseRelatedOp, error) { + var out []interface{} + err := _ARMContract.contract.Call(opts, &out, "getRecordedCurseRelatedOps", offset, limit) + + if err != nil { + return *new([]RMNRecordedCurseRelatedOp), err + } + + out0 := *abi.ConvertType(out[0], new([]RMNRecordedCurseRelatedOp)).(*[]RMNRecordedCurseRelatedOp) + + return out0, err + +} + +func (_ARMContract *ARMContractSession) GetRecordedCurseRelatedOps(offset *big.Int, limit *big.Int) ([]RMNRecordedCurseRelatedOp, error) { + return _ARMContract.Contract.GetRecordedCurseRelatedOps(&_ARMContract.CallOpts, offset, limit) +} + +func (_ARMContract *ARMContractCallerSession) GetRecordedCurseRelatedOps(offset *big.Int, limit *big.Int) ([]RMNRecordedCurseRelatedOp, error) { + return _ARMContract.Contract.GetRecordedCurseRelatedOps(&_ARMContract.CallOpts, offset, limit) +} + +func (_ARMContract *ARMContractCaller) GetRecordedCurseRelatedOpsCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ARMContract.contract.Call(opts, &out, "getRecordedCurseRelatedOpsCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ARMContract *ARMContractSession) GetRecordedCurseRelatedOpsCount() (*big.Int, error) { + return _ARMContract.Contract.GetRecordedCurseRelatedOpsCount(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCallerSession) GetRecordedCurseRelatedOpsCount() (*big.Int, error) { + return _ARMContract.Contract.GetRecordedCurseRelatedOpsCount(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCaller) IsBlessed(opts *bind.CallOpts, taggedRoot IRMNTaggedRoot) (bool, error) { + var out []interface{} + err := _ARMContract.contract.Call(opts, &out, "isBlessed", taggedRoot) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ARMContract *ARMContractSession) IsBlessed(taggedRoot IRMNTaggedRoot) (bool, error) { + return _ARMContract.Contract.IsBlessed(&_ARMContract.CallOpts, taggedRoot) +} + +func (_ARMContract *ARMContractCallerSession) IsBlessed(taggedRoot IRMNTaggedRoot) (bool, error) { + return _ARMContract.Contract.IsBlessed(&_ARMContract.CallOpts, taggedRoot) +} + +func (_ARMContract *ARMContractCaller) IsCursed(opts *bind.CallOpts, subject [16]byte) (bool, error) { + var out []interface{} + err := _ARMContract.contract.Call(opts, &out, "isCursed", subject) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ARMContract *ARMContractSession) IsCursed(subject [16]byte) (bool, error) { + return _ARMContract.Contract.IsCursed(&_ARMContract.CallOpts, subject) +} + +func (_ARMContract *ARMContractCallerSession) IsCursed(subject [16]byte) (bool, error) { + return _ARMContract.Contract.IsCursed(&_ARMContract.CallOpts, subject) +} + +func (_ARMContract *ARMContractCaller) IsCursed0(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _ARMContract.contract.Call(opts, &out, "isCursed0") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ARMContract *ARMContractSession) IsCursed0() (bool, error) { + return _ARMContract.Contract.IsCursed0(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCallerSession) IsCursed0() (bool, error) { + return _ARMContract.Contract.IsCursed0(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ARMContract.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ARMContract *ARMContractSession) Owner() (common.Address, error) { + return _ARMContract.Contract.Owner(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCallerSession) Owner() (common.Address, error) { + return _ARMContract.Contract.Owner(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ARMContract.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_ARMContract *ARMContractSession) TypeAndVersion() (string, error) { + return _ARMContract.Contract.TypeAndVersion(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractCallerSession) TypeAndVersion() (string, error) { + return _ARMContract.Contract.TypeAndVersion(&_ARMContract.CallOpts) +} + +func (_ARMContract *ARMContractTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ARMContract.contract.Transact(opts, "acceptOwnership") +} + +func (_ARMContract *ARMContractSession) AcceptOwnership() (*types.Transaction, error) { + return _ARMContract.Contract.AcceptOwnership(&_ARMContract.TransactOpts) +} + +func (_ARMContract *ARMContractTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _ARMContract.Contract.AcceptOwnership(&_ARMContract.TransactOpts) +} + +func (_ARMContract *ARMContractTransactor) OwnerCurse(opts *bind.TransactOpts, curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { + return _ARMContract.contract.Transact(opts, "ownerCurse", curseId, subjects) +} + +func (_ARMContract *ARMContractSession) OwnerCurse(curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { + return _ARMContract.Contract.OwnerCurse(&_ARMContract.TransactOpts, curseId, subjects) +} + +func (_ARMContract *ARMContractTransactorSession) OwnerCurse(curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { + return _ARMContract.Contract.OwnerCurse(&_ARMContract.TransactOpts, curseId, subjects) +} + +func (_ARMContract *ARMContractTransactor) OwnerRemoveThenAddPermaBlessedCommitStores(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _ARMContract.contract.Transact(opts, "ownerRemoveThenAddPermaBlessedCommitStores", removes, adds) +} + +func (_ARMContract *ARMContractSession) OwnerRemoveThenAddPermaBlessedCommitStores(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _ARMContract.Contract.OwnerRemoveThenAddPermaBlessedCommitStores(&_ARMContract.TransactOpts, removes, adds) +} + +func (_ARMContract *ARMContractTransactorSession) OwnerRemoveThenAddPermaBlessedCommitStores(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _ARMContract.Contract.OwnerRemoveThenAddPermaBlessedCommitStores(&_ARMContract.TransactOpts, removes, adds) +} + +func (_ARMContract *ARMContractTransactor) OwnerResetBlessVotes(opts *bind.TransactOpts, taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { + return _ARMContract.contract.Transact(opts, "ownerResetBlessVotes", taggedRoots) +} + +func (_ARMContract *ARMContractSession) OwnerResetBlessVotes(taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { + return _ARMContract.Contract.OwnerResetBlessVotes(&_ARMContract.TransactOpts, taggedRoots) +} + +func (_ARMContract *ARMContractTransactorSession) OwnerResetBlessVotes(taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { + return _ARMContract.Contract.OwnerResetBlessVotes(&_ARMContract.TransactOpts, taggedRoots) +} + +func (_ARMContract *ARMContractTransactor) OwnerUnvoteToCurse(opts *bind.TransactOpts, ownerUnvoteToCurseRequests []RMNOwnerUnvoteToCurseRequest) (*types.Transaction, error) { + return _ARMContract.contract.Transact(opts, "ownerUnvoteToCurse", ownerUnvoteToCurseRequests) +} + +func (_ARMContract *ARMContractSession) OwnerUnvoteToCurse(ownerUnvoteToCurseRequests []RMNOwnerUnvoteToCurseRequest) (*types.Transaction, error) { + return _ARMContract.Contract.OwnerUnvoteToCurse(&_ARMContract.TransactOpts, ownerUnvoteToCurseRequests) +} + +func (_ARMContract *ARMContractTransactorSession) OwnerUnvoteToCurse(ownerUnvoteToCurseRequests []RMNOwnerUnvoteToCurseRequest) (*types.Transaction, error) { + return _ARMContract.Contract.OwnerUnvoteToCurse(&_ARMContract.TransactOpts, ownerUnvoteToCurseRequests) +} + +func (_ARMContract *ARMContractTransactor) SetConfig(opts *bind.TransactOpts, config RMNConfig) (*types.Transaction, error) { + return _ARMContract.contract.Transact(opts, "setConfig", config) +} + +func (_ARMContract *ARMContractSession) SetConfig(config RMNConfig) (*types.Transaction, error) { + return _ARMContract.Contract.SetConfig(&_ARMContract.TransactOpts, config) +} + +func (_ARMContract *ARMContractTransactorSession) SetConfig(config RMNConfig) (*types.Transaction, error) { + return _ARMContract.Contract.SetConfig(&_ARMContract.TransactOpts, config) +} + +func (_ARMContract *ARMContractTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _ARMContract.contract.Transact(opts, "transferOwnership", to) +} + +func (_ARMContract *ARMContractSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _ARMContract.Contract.TransferOwnership(&_ARMContract.TransactOpts, to) +} + +func (_ARMContract *ARMContractTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _ARMContract.Contract.TransferOwnership(&_ARMContract.TransactOpts, to) +} + +func (_ARMContract *ARMContractTransactor) UnvoteToCurse(opts *bind.TransactOpts, unvoteToCurseRequests []RMNUnvoteToCurseRequest) (*types.Transaction, error) { + return _ARMContract.contract.Transact(opts, "unvoteToCurse", unvoteToCurseRequests) +} + +func (_ARMContract *ARMContractSession) UnvoteToCurse(unvoteToCurseRequests []RMNUnvoteToCurseRequest) (*types.Transaction, error) { + return _ARMContract.Contract.UnvoteToCurse(&_ARMContract.TransactOpts, unvoteToCurseRequests) +} + +func (_ARMContract *ARMContractTransactorSession) UnvoteToCurse(unvoteToCurseRequests []RMNUnvoteToCurseRequest) (*types.Transaction, error) { + return _ARMContract.Contract.UnvoteToCurse(&_ARMContract.TransactOpts, unvoteToCurseRequests) +} + +func (_ARMContract *ARMContractTransactor) VoteToBless(opts *bind.TransactOpts, taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { + return _ARMContract.contract.Transact(opts, "voteToBless", taggedRoots) +} + +func (_ARMContract *ARMContractSession) VoteToBless(taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { + return _ARMContract.Contract.VoteToBless(&_ARMContract.TransactOpts, taggedRoots) +} + +func (_ARMContract *ARMContractTransactorSession) VoteToBless(taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { + return _ARMContract.Contract.VoteToBless(&_ARMContract.TransactOpts, taggedRoots) +} + +func (_ARMContract *ARMContractTransactor) VoteToCurse(opts *bind.TransactOpts, curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { + return _ARMContract.contract.Transact(opts, "voteToCurse", curseId, subjects) +} + +func (_ARMContract *ARMContractSession) VoteToCurse(curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { + return _ARMContract.Contract.VoteToCurse(&_ARMContract.TransactOpts, curseId, subjects) +} + +func (_ARMContract *ARMContractTransactorSession) VoteToCurse(curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { + return _ARMContract.Contract.VoteToCurse(&_ARMContract.TransactOpts, curseId, subjects) +} + +type ARMContractAlreadyBlessedIterator struct { + Event *ARMContractAlreadyBlessed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractAlreadyBlessedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractAlreadyBlessed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractAlreadyBlessed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractAlreadyBlessedIterator) Error() error { + return it.fail +} + +func (it *ARMContractAlreadyBlessedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractAlreadyBlessed struct { + ConfigVersion uint32 + Voter common.Address + TaggedRoot IRMNTaggedRoot + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterAlreadyBlessed(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractAlreadyBlessedIterator, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + var voterRule []interface{} + for _, voterItem := range voter { + voterRule = append(voterRule, voterItem) + } + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "AlreadyBlessed", configVersionRule, voterRule) + if err != nil { + return nil, err + } + return &ARMContractAlreadyBlessedIterator{contract: _ARMContract.contract, event: "AlreadyBlessed", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchAlreadyBlessed(opts *bind.WatchOpts, sink chan<- *ARMContractAlreadyBlessed, configVersion []uint32, voter []common.Address) (event.Subscription, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + var voterRule []interface{} + for _, voterItem := range voter { + voterRule = append(voterRule, voterItem) + } + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "AlreadyBlessed", configVersionRule, voterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractAlreadyBlessed) + if err := _ARMContract.contract.UnpackLog(event, "AlreadyBlessed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseAlreadyBlessed(log types.Log) (*ARMContractAlreadyBlessed, error) { + event := new(ARMContractAlreadyBlessed) + if err := _ARMContract.contract.UnpackLog(event, "AlreadyBlessed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractAlreadyVotedToBlessIterator struct { + Event *ARMContractAlreadyVotedToBless + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractAlreadyVotedToBlessIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractAlreadyVotedToBless) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractAlreadyVotedToBless) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractAlreadyVotedToBlessIterator) Error() error { + return it.fail +} + +func (it *ARMContractAlreadyVotedToBlessIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractAlreadyVotedToBless struct { + ConfigVersion uint32 + Voter common.Address + TaggedRoot IRMNTaggedRoot + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterAlreadyVotedToBless(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractAlreadyVotedToBlessIterator, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + var voterRule []interface{} + for _, voterItem := range voter { + voterRule = append(voterRule, voterItem) + } + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "AlreadyVotedToBless", configVersionRule, voterRule) + if err != nil { + return nil, err + } + return &ARMContractAlreadyVotedToBlessIterator{contract: _ARMContract.contract, event: "AlreadyVotedToBless", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchAlreadyVotedToBless(opts *bind.WatchOpts, sink chan<- *ARMContractAlreadyVotedToBless, configVersion []uint32, voter []common.Address) (event.Subscription, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + var voterRule []interface{} + for _, voterItem := range voter { + voterRule = append(voterRule, voterItem) + } + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "AlreadyVotedToBless", configVersionRule, voterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractAlreadyVotedToBless) + if err := _ARMContract.contract.UnpackLog(event, "AlreadyVotedToBless", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseAlreadyVotedToBless(log types.Log) (*ARMContractAlreadyVotedToBless, error) { + event := new(ARMContractAlreadyVotedToBless) + if err := _ARMContract.contract.UnpackLog(event, "AlreadyVotedToBless", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractConfigSetIterator struct { + Event *ARMContractConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractConfigSetIterator) Error() error { + return it.fail +} + +func (it *ARMContractConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractConfigSet struct { + ConfigVersion uint32 + Config RMNConfig + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterConfigSet(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractConfigSetIterator, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "ConfigSet", configVersionRule) + if err != nil { + return nil, err + } + return &ARMContractConfigSetIterator{contract: _ARMContract.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *ARMContractConfigSet, configVersion []uint32) (event.Subscription, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "ConfigSet", configVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractConfigSet) + if err := _ARMContract.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseConfigSet(log types.Log) (*ARMContractConfigSet, error) { + event := new(ARMContractConfigSet) + if err := _ARMContract.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractCurseLiftedIterator struct { + Event *ARMContractCurseLifted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractCurseLiftedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractCurseLifted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractCurseLifted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractCurseLiftedIterator) Error() error { + return it.fail +} + +func (it *ARMContractCurseLiftedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractCurseLifted struct { + Subject [16]byte + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterCurseLifted(opts *bind.FilterOpts) (*ARMContractCurseLiftedIterator, error) { + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "CurseLifted") + if err != nil { + return nil, err + } + return &ARMContractCurseLiftedIterator{contract: _ARMContract.contract, event: "CurseLifted", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchCurseLifted(opts *bind.WatchOpts, sink chan<- *ARMContractCurseLifted) (event.Subscription, error) { + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "CurseLifted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractCurseLifted) + if err := _ARMContract.contract.UnpackLog(event, "CurseLifted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseCurseLifted(log types.Log) (*ARMContractCurseLifted, error) { + event := new(ARMContractCurseLifted) + if err := _ARMContract.contract.UnpackLog(event, "CurseLifted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractCursedIterator struct { + Event *ARMContractCursed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractCursedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractCursed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractCursed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractCursedIterator) Error() error { + return it.fail +} + +func (it *ARMContractCursedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractCursed struct { + ConfigVersion uint32 + Subject [16]byte + BlockTimestamp uint64 + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterCursed(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractCursedIterator, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "Cursed", configVersionRule) + if err != nil { + return nil, err + } + return &ARMContractCursedIterator{contract: _ARMContract.contract, event: "Cursed", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchCursed(opts *bind.WatchOpts, sink chan<- *ARMContractCursed, configVersion []uint32) (event.Subscription, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "Cursed", configVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractCursed) + if err := _ARMContract.contract.UnpackLog(event, "Cursed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseCursed(log types.Log) (*ARMContractCursed, error) { + event := new(ARMContractCursed) + if err := _ARMContract.contract.UnpackLog(event, "Cursed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractOwnershipTransferRequestedIterator struct { + Event *ARMContractOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *ARMContractOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMContractOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &ARMContractOwnershipTransferRequestedIterator{contract: _ARMContract.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ARMContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractOwnershipTransferRequested) + if err := _ARMContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseOwnershipTransferRequested(log types.Log) (*ARMContractOwnershipTransferRequested, error) { + event := new(ARMContractOwnershipTransferRequested) + if err := _ARMContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractOwnershipTransferredIterator struct { + Event *ARMContractOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *ARMContractOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMContractOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &ARMContractOwnershipTransferredIterator{contract: _ARMContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ARMContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractOwnershipTransferred) + if err := _ARMContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseOwnershipTransferred(log types.Log) (*ARMContractOwnershipTransferred, error) { + event := new(ARMContractOwnershipTransferred) + if err := _ARMContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractPermaBlessedCommitStoreAddedIterator struct { + Event *ARMContractPermaBlessedCommitStoreAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractPermaBlessedCommitStoreAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractPermaBlessedCommitStoreAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractPermaBlessedCommitStoreAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractPermaBlessedCommitStoreAddedIterator) Error() error { + return it.fail +} + +func (it *ARMContractPermaBlessedCommitStoreAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractPermaBlessedCommitStoreAdded struct { + CommitStore common.Address + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterPermaBlessedCommitStoreAdded(opts *bind.FilterOpts) (*ARMContractPermaBlessedCommitStoreAddedIterator, error) { + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "PermaBlessedCommitStoreAdded") + if err != nil { + return nil, err + } + return &ARMContractPermaBlessedCommitStoreAddedIterator{contract: _ARMContract.contract, event: "PermaBlessedCommitStoreAdded", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchPermaBlessedCommitStoreAdded(opts *bind.WatchOpts, sink chan<- *ARMContractPermaBlessedCommitStoreAdded) (event.Subscription, error) { + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "PermaBlessedCommitStoreAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractPermaBlessedCommitStoreAdded) + if err := _ARMContract.contract.UnpackLog(event, "PermaBlessedCommitStoreAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParsePermaBlessedCommitStoreAdded(log types.Log) (*ARMContractPermaBlessedCommitStoreAdded, error) { + event := new(ARMContractPermaBlessedCommitStoreAdded) + if err := _ARMContract.contract.UnpackLog(event, "PermaBlessedCommitStoreAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractPermaBlessedCommitStoreRemovedIterator struct { + Event *ARMContractPermaBlessedCommitStoreRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractPermaBlessedCommitStoreRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractPermaBlessedCommitStoreRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractPermaBlessedCommitStoreRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractPermaBlessedCommitStoreRemovedIterator) Error() error { + return it.fail +} + +func (it *ARMContractPermaBlessedCommitStoreRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractPermaBlessedCommitStoreRemoved struct { + CommitStore common.Address + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterPermaBlessedCommitStoreRemoved(opts *bind.FilterOpts) (*ARMContractPermaBlessedCommitStoreRemovedIterator, error) { + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "PermaBlessedCommitStoreRemoved") + if err != nil { + return nil, err + } + return &ARMContractPermaBlessedCommitStoreRemovedIterator{contract: _ARMContract.contract, event: "PermaBlessedCommitStoreRemoved", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchPermaBlessedCommitStoreRemoved(opts *bind.WatchOpts, sink chan<- *ARMContractPermaBlessedCommitStoreRemoved) (event.Subscription, error) { + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "PermaBlessedCommitStoreRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractPermaBlessedCommitStoreRemoved) + if err := _ARMContract.contract.UnpackLog(event, "PermaBlessedCommitStoreRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParsePermaBlessedCommitStoreRemoved(log types.Log) (*ARMContractPermaBlessedCommitStoreRemoved, error) { + event := new(ARMContractPermaBlessedCommitStoreRemoved) + if err := _ARMContract.contract.UnpackLog(event, "PermaBlessedCommitStoreRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractSkippedUnvoteToCurseIterator struct { + Event *ARMContractSkippedUnvoteToCurse + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractSkippedUnvoteToCurseIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractSkippedUnvoteToCurse) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractSkippedUnvoteToCurse) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractSkippedUnvoteToCurseIterator) Error() error { + return it.fail +} + +func (it *ARMContractSkippedUnvoteToCurseIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractSkippedUnvoteToCurse struct { + Voter common.Address + Subject [16]byte + OnchainCursesHash [28]byte + CursesHash [28]byte + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterSkippedUnvoteToCurse(opts *bind.FilterOpts, voter []common.Address) (*ARMContractSkippedUnvoteToCurseIterator, error) { + + var voterRule []interface{} + for _, voterItem := range voter { + voterRule = append(voterRule, voterItem) + } + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "SkippedUnvoteToCurse", voterRule) + if err != nil { + return nil, err + } + return &ARMContractSkippedUnvoteToCurseIterator{contract: _ARMContract.contract, event: "SkippedUnvoteToCurse", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchSkippedUnvoteToCurse(opts *bind.WatchOpts, sink chan<- *ARMContractSkippedUnvoteToCurse, voter []common.Address) (event.Subscription, error) { + + var voterRule []interface{} + for _, voterItem := range voter { + voterRule = append(voterRule, voterItem) + } + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "SkippedUnvoteToCurse", voterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractSkippedUnvoteToCurse) + if err := _ARMContract.contract.UnpackLog(event, "SkippedUnvoteToCurse", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseSkippedUnvoteToCurse(log types.Log) (*ARMContractSkippedUnvoteToCurse, error) { + event := new(ARMContractSkippedUnvoteToCurse) + if err := _ARMContract.contract.UnpackLog(event, "SkippedUnvoteToCurse", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractTaggedRootBlessVotesResetIterator struct { + Event *ARMContractTaggedRootBlessVotesReset + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractTaggedRootBlessVotesResetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractTaggedRootBlessVotesReset) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractTaggedRootBlessVotesReset) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractTaggedRootBlessVotesResetIterator) Error() error { + return it.fail +} + +func (it *ARMContractTaggedRootBlessVotesResetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractTaggedRootBlessVotesReset struct { + ConfigVersion uint32 + TaggedRoot IRMNTaggedRoot + WasBlessed bool + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterTaggedRootBlessVotesReset(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractTaggedRootBlessVotesResetIterator, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "TaggedRootBlessVotesReset", configVersionRule) + if err != nil { + return nil, err + } + return &ARMContractTaggedRootBlessVotesResetIterator{contract: _ARMContract.contract, event: "TaggedRootBlessVotesReset", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchTaggedRootBlessVotesReset(opts *bind.WatchOpts, sink chan<- *ARMContractTaggedRootBlessVotesReset, configVersion []uint32) (event.Subscription, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "TaggedRootBlessVotesReset", configVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractTaggedRootBlessVotesReset) + if err := _ARMContract.contract.UnpackLog(event, "TaggedRootBlessVotesReset", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseTaggedRootBlessVotesReset(log types.Log) (*ARMContractTaggedRootBlessVotesReset, error) { + event := new(ARMContractTaggedRootBlessVotesReset) + if err := _ARMContract.contract.UnpackLog(event, "TaggedRootBlessVotesReset", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractTaggedRootBlessedIterator struct { + Event *ARMContractTaggedRootBlessed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractTaggedRootBlessedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractTaggedRootBlessed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractTaggedRootBlessed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractTaggedRootBlessedIterator) Error() error { + return it.fail +} + +func (it *ARMContractTaggedRootBlessedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractTaggedRootBlessed struct { + ConfigVersion uint32 + TaggedRoot IRMNTaggedRoot + AccumulatedWeight uint16 + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterTaggedRootBlessed(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractTaggedRootBlessedIterator, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "TaggedRootBlessed", configVersionRule) + if err != nil { + return nil, err + } + return &ARMContractTaggedRootBlessedIterator{contract: _ARMContract.contract, event: "TaggedRootBlessed", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchTaggedRootBlessed(opts *bind.WatchOpts, sink chan<- *ARMContractTaggedRootBlessed, configVersion []uint32) (event.Subscription, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "TaggedRootBlessed", configVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractTaggedRootBlessed) + if err := _ARMContract.contract.UnpackLog(event, "TaggedRootBlessed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseTaggedRootBlessed(log types.Log) (*ARMContractTaggedRootBlessed, error) { + event := new(ARMContractTaggedRootBlessed) + if err := _ARMContract.contract.UnpackLog(event, "TaggedRootBlessed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractUnvotedToCurseIterator struct { + Event *ARMContractUnvotedToCurse + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractUnvotedToCurseIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractUnvotedToCurse) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractUnvotedToCurse) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractUnvotedToCurseIterator) Error() error { + return it.fail +} + +func (it *ARMContractUnvotedToCurseIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractUnvotedToCurse struct { + ConfigVersion uint32 + Voter common.Address + Subject [16]byte + Weight uint8 + CursesHash [28]byte + RemainingAccumulatedWeight uint16 + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterUnvotedToCurse(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractUnvotedToCurseIterator, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + var voterRule []interface{} + for _, voterItem := range voter { + voterRule = append(voterRule, voterItem) + } + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "UnvotedToCurse", configVersionRule, voterRule) + if err != nil { + return nil, err + } + return &ARMContractUnvotedToCurseIterator{contract: _ARMContract.contract, event: "UnvotedToCurse", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchUnvotedToCurse(opts *bind.WatchOpts, sink chan<- *ARMContractUnvotedToCurse, configVersion []uint32, voter []common.Address) (event.Subscription, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + var voterRule []interface{} + for _, voterItem := range voter { + voterRule = append(voterRule, voterItem) + } + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "UnvotedToCurse", configVersionRule, voterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractUnvotedToCurse) + if err := _ARMContract.contract.UnpackLog(event, "UnvotedToCurse", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseUnvotedToCurse(log types.Log) (*ARMContractUnvotedToCurse, error) { + event := new(ARMContractUnvotedToCurse) + if err := _ARMContract.contract.UnpackLog(event, "UnvotedToCurse", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractVotedToBlessIterator struct { + Event *ARMContractVotedToBless + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractVotedToBlessIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractVotedToBless) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractVotedToBless) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractVotedToBlessIterator) Error() error { + return it.fail +} + +func (it *ARMContractVotedToBlessIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractVotedToBless struct { + ConfigVersion uint32 + Voter common.Address + TaggedRoot IRMNTaggedRoot + Weight uint8 + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterVotedToBless(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractVotedToBlessIterator, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + var voterRule []interface{} + for _, voterItem := range voter { + voterRule = append(voterRule, voterItem) + } + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "VotedToBless", configVersionRule, voterRule) + if err != nil { + return nil, err + } + return &ARMContractVotedToBlessIterator{contract: _ARMContract.contract, event: "VotedToBless", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchVotedToBless(opts *bind.WatchOpts, sink chan<- *ARMContractVotedToBless, configVersion []uint32, voter []common.Address) (event.Subscription, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + var voterRule []interface{} + for _, voterItem := range voter { + voterRule = append(voterRule, voterItem) + } + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "VotedToBless", configVersionRule, voterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractVotedToBless) + if err := _ARMContract.contract.UnpackLog(event, "VotedToBless", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseVotedToBless(log types.Log) (*ARMContractVotedToBless, error) { + event := new(ARMContractVotedToBless) + if err := _ARMContract.contract.UnpackLog(event, "VotedToBless", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMContractVotedToCurseIterator struct { + Event *ARMContractVotedToCurse + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMContractVotedToCurseIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMContractVotedToCurse) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMContractVotedToCurse) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMContractVotedToCurseIterator) Error() error { + return it.fail +} + +func (it *ARMContractVotedToCurseIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMContractVotedToCurse struct { + ConfigVersion uint32 + Voter common.Address + Subject [16]byte + CurseId [16]byte + Weight uint8 + BlockTimestamp uint64 + CursesHash [28]byte + AccumulatedWeight uint16 + Raw types.Log +} + +func (_ARMContract *ARMContractFilterer) FilterVotedToCurse(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractVotedToCurseIterator, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + var voterRule []interface{} + for _, voterItem := range voter { + voterRule = append(voterRule, voterItem) + } + + logs, sub, err := _ARMContract.contract.FilterLogs(opts, "VotedToCurse", configVersionRule, voterRule) + if err != nil { + return nil, err + } + return &ARMContractVotedToCurseIterator{contract: _ARMContract.contract, event: "VotedToCurse", logs: logs, sub: sub}, nil +} + +func (_ARMContract *ARMContractFilterer) WatchVotedToCurse(opts *bind.WatchOpts, sink chan<- *ARMContractVotedToCurse, configVersion []uint32, voter []common.Address) (event.Subscription, error) { + + var configVersionRule []interface{} + for _, configVersionItem := range configVersion { + configVersionRule = append(configVersionRule, configVersionItem) + } + var voterRule []interface{} + for _, voterItem := range voter { + voterRule = append(voterRule, voterItem) + } + + logs, sub, err := _ARMContract.contract.WatchLogs(opts, "VotedToCurse", configVersionRule, voterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMContractVotedToCurse) + if err := _ARMContract.contract.UnpackLog(event, "VotedToCurse", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMContract *ARMContractFilterer) ParseVotedToCurse(log types.Log) (*ARMContractVotedToCurse, error) { + event := new(ARMContractVotedToCurse) + if err := _ARMContract.contract.UnpackLog(event, "VotedToCurse", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetBlessProgress struct { + BlessVoteAddrs []common.Address + AccumulatedWeight uint16 + Blessed bool +} +type GetConfigDetails struct { + Version uint32 + BlockNumber uint32 + Config RMNConfig +} +type GetCurseProgress struct { + CurseVoteAddrs []common.Address + CursesHashes [][28]byte + AccumulatedWeight uint16 + Cursed bool +} + +func (_ARMContract *ARMContract) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _ARMContract.abi.Events["AlreadyBlessed"].ID: + return _ARMContract.ParseAlreadyBlessed(log) + case _ARMContract.abi.Events["AlreadyVotedToBless"].ID: + return _ARMContract.ParseAlreadyVotedToBless(log) + case _ARMContract.abi.Events["ConfigSet"].ID: + return _ARMContract.ParseConfigSet(log) + case _ARMContract.abi.Events["CurseLifted"].ID: + return _ARMContract.ParseCurseLifted(log) + case _ARMContract.abi.Events["Cursed"].ID: + return _ARMContract.ParseCursed(log) + case _ARMContract.abi.Events["OwnershipTransferRequested"].ID: + return _ARMContract.ParseOwnershipTransferRequested(log) + case _ARMContract.abi.Events["OwnershipTransferred"].ID: + return _ARMContract.ParseOwnershipTransferred(log) + case _ARMContract.abi.Events["PermaBlessedCommitStoreAdded"].ID: + return _ARMContract.ParsePermaBlessedCommitStoreAdded(log) + case _ARMContract.abi.Events["PermaBlessedCommitStoreRemoved"].ID: + return _ARMContract.ParsePermaBlessedCommitStoreRemoved(log) + case _ARMContract.abi.Events["SkippedUnvoteToCurse"].ID: + return _ARMContract.ParseSkippedUnvoteToCurse(log) + case _ARMContract.abi.Events["TaggedRootBlessVotesReset"].ID: + return _ARMContract.ParseTaggedRootBlessVotesReset(log) + case _ARMContract.abi.Events["TaggedRootBlessed"].ID: + return _ARMContract.ParseTaggedRootBlessed(log) + case _ARMContract.abi.Events["UnvotedToCurse"].ID: + return _ARMContract.ParseUnvotedToCurse(log) + case _ARMContract.abi.Events["VotedToBless"].ID: + return _ARMContract.ParseVotedToBless(log) + case _ARMContract.abi.Events["VotedToCurse"].ID: + return _ARMContract.ParseVotedToCurse(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (ARMContractAlreadyBlessed) Topic() common.Hash { + return common.HexToHash("0x274d6d5b916b0a53974b7ab86c844b97a2e03a60f658cd9a4b1c028b604d7bf1") +} + +func (ARMContractAlreadyVotedToBless) Topic() common.Hash { + return common.HexToHash("0x6dfbb745226fa630aeb1b9557d17d508ddb789a04f0cb873ec16e58beb8beead") +} + +func (ARMContractConfigSet) Topic() common.Hash { + return common.HexToHash("0x8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a9") +} + +func (ARMContractCurseLifted) Topic() common.Hash { + return common.HexToHash("0x65d0e78c3625f0956f58610cf0fb157eaf627683258875ef29af2f71d25ac8fd") +} + +func (ARMContractCursed) Topic() common.Hash { + return common.HexToHash("0xcfdbfd8ce9a56b5f7c202c0e102184d24f47ca87121dc165063fc4c290957bde") +} + +func (ARMContractOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (ARMContractOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (ARMContractPermaBlessedCommitStoreAdded) Topic() common.Hash { + return common.HexToHash("0x66b4b4752c65ae8cd2f3a0a48c7dc8b2118c60d5ea15514992eb2ddf56c9cb15") +} + +func (ARMContractPermaBlessedCommitStoreRemoved) Topic() common.Hash { + return common.HexToHash("0xdca892154bbc36d0c05ccd01b3d0411875cb1b841fcdeebb384e5d0d6eb06b44") +} + +func (ARMContractSkippedUnvoteToCurse) Topic() common.Hash { + return common.HexToHash("0xbabb0d7099e6ca14a29fad2a2cfb4fda2bd30f97cb3c27e546174bfb4277c1cc") +} + +func (ARMContractTaggedRootBlessVotesReset) Topic() common.Hash { + return common.HexToHash("0x7d15a6eebaa019ea7d5b7d38937c51ebd3befbfdf51bb630a694fd28635bbcba") +} + +func (ARMContractTaggedRootBlessed) Topic() common.Hash { + return common.HexToHash("0x8257378aa73bf8e4ada848713526584a3dcee0fd3db3beed7397f7a7f5067cc9") +} + +func (ARMContractUnvotedToCurse) Topic() common.Hash { + return common.HexToHash("0xa96a155bd67c927a6c056befbd979b78465e2b2f1276bf7d4e90a31d4f430aa8") +} + +func (ARMContractVotedToBless) Topic() common.Hash { + return common.HexToHash("0x2a08a2bd2798f0aae9a843f0f4ad4de488c1b3d5f04049940cfed736ad69fb97") +} + +func (ARMContractVotedToCurse) Topic() common.Hash { + return common.HexToHash("0x8137bc8a8d712aaa27bfc6506d5566ac405618bd53f9831b8ca6b6fe5442ee7a") +} + +func (_ARMContract *ARMContract) Address() common.Address { + return _ARMContract.address +} + +type ARMContractInterface interface { + GetBlessProgress(opts *bind.CallOpts, taggedRoot IRMNTaggedRoot) (GetBlessProgress, + + error) + + GetConfigDetails(opts *bind.CallOpts) (GetConfigDetails, + + error) + + GetCurseProgress(opts *bind.CallOpts, subject [16]byte) (GetCurseProgress, + + error) + + GetCursedSubjectsCount(opts *bind.CallOpts) (*big.Int, error) + + GetPermaBlessedCommitStores(opts *bind.CallOpts) ([]common.Address, error) + + GetRecordedCurseRelatedOps(opts *bind.CallOpts, offset *big.Int, limit *big.Int) ([]RMNRecordedCurseRelatedOp, error) + + GetRecordedCurseRelatedOpsCount(opts *bind.CallOpts) (*big.Int, error) + + IsBlessed(opts *bind.CallOpts, taggedRoot IRMNTaggedRoot) (bool, error) + + IsCursed(opts *bind.CallOpts, subject [16]byte) (bool, error) + + IsCursed0(opts *bind.CallOpts) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + OwnerCurse(opts *bind.TransactOpts, curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) + + OwnerRemoveThenAddPermaBlessedCommitStores(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + OwnerResetBlessVotes(opts *bind.TransactOpts, taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) + + OwnerUnvoteToCurse(opts *bind.TransactOpts, ownerUnvoteToCurseRequests []RMNOwnerUnvoteToCurseRequest) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, config RMNConfig) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UnvoteToCurse(opts *bind.TransactOpts, unvoteToCurseRequests []RMNUnvoteToCurseRequest) (*types.Transaction, error) + + VoteToBless(opts *bind.TransactOpts, taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) + + VoteToCurse(opts *bind.TransactOpts, curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) + + FilterAlreadyBlessed(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractAlreadyBlessedIterator, error) + + WatchAlreadyBlessed(opts *bind.WatchOpts, sink chan<- *ARMContractAlreadyBlessed, configVersion []uint32, voter []common.Address) (event.Subscription, error) + + ParseAlreadyBlessed(log types.Log) (*ARMContractAlreadyBlessed, error) + + FilterAlreadyVotedToBless(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractAlreadyVotedToBlessIterator, error) + + WatchAlreadyVotedToBless(opts *bind.WatchOpts, sink chan<- *ARMContractAlreadyVotedToBless, configVersion []uint32, voter []common.Address) (event.Subscription, error) + + ParseAlreadyVotedToBless(log types.Log) (*ARMContractAlreadyVotedToBless, error) + + FilterConfigSet(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *ARMContractConfigSet, configVersion []uint32) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*ARMContractConfigSet, error) + + FilterCurseLifted(opts *bind.FilterOpts) (*ARMContractCurseLiftedIterator, error) + + WatchCurseLifted(opts *bind.WatchOpts, sink chan<- *ARMContractCurseLifted) (event.Subscription, error) + + ParseCurseLifted(log types.Log) (*ARMContractCurseLifted, error) + + FilterCursed(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractCursedIterator, error) + + WatchCursed(opts *bind.WatchOpts, sink chan<- *ARMContractCursed, configVersion []uint32) (event.Subscription, error) + + ParseCursed(log types.Log) (*ARMContractCursed, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMContractOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ARMContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*ARMContractOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMContractOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ARMContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*ARMContractOwnershipTransferred, error) + + FilterPermaBlessedCommitStoreAdded(opts *bind.FilterOpts) (*ARMContractPermaBlessedCommitStoreAddedIterator, error) + + WatchPermaBlessedCommitStoreAdded(opts *bind.WatchOpts, sink chan<- *ARMContractPermaBlessedCommitStoreAdded) (event.Subscription, error) + + ParsePermaBlessedCommitStoreAdded(log types.Log) (*ARMContractPermaBlessedCommitStoreAdded, error) + + FilterPermaBlessedCommitStoreRemoved(opts *bind.FilterOpts) (*ARMContractPermaBlessedCommitStoreRemovedIterator, error) + + WatchPermaBlessedCommitStoreRemoved(opts *bind.WatchOpts, sink chan<- *ARMContractPermaBlessedCommitStoreRemoved) (event.Subscription, error) + + ParsePermaBlessedCommitStoreRemoved(log types.Log) (*ARMContractPermaBlessedCommitStoreRemoved, error) + + FilterSkippedUnvoteToCurse(opts *bind.FilterOpts, voter []common.Address) (*ARMContractSkippedUnvoteToCurseIterator, error) + + WatchSkippedUnvoteToCurse(opts *bind.WatchOpts, sink chan<- *ARMContractSkippedUnvoteToCurse, voter []common.Address) (event.Subscription, error) + + ParseSkippedUnvoteToCurse(log types.Log) (*ARMContractSkippedUnvoteToCurse, error) + + FilterTaggedRootBlessVotesReset(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractTaggedRootBlessVotesResetIterator, error) + + WatchTaggedRootBlessVotesReset(opts *bind.WatchOpts, sink chan<- *ARMContractTaggedRootBlessVotesReset, configVersion []uint32) (event.Subscription, error) + + ParseTaggedRootBlessVotesReset(log types.Log) (*ARMContractTaggedRootBlessVotesReset, error) + + FilterTaggedRootBlessed(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractTaggedRootBlessedIterator, error) + + WatchTaggedRootBlessed(opts *bind.WatchOpts, sink chan<- *ARMContractTaggedRootBlessed, configVersion []uint32) (event.Subscription, error) + + ParseTaggedRootBlessed(log types.Log) (*ARMContractTaggedRootBlessed, error) + + FilterUnvotedToCurse(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractUnvotedToCurseIterator, error) + + WatchUnvotedToCurse(opts *bind.WatchOpts, sink chan<- *ARMContractUnvotedToCurse, configVersion []uint32, voter []common.Address) (event.Subscription, error) + + ParseUnvotedToCurse(log types.Log) (*ARMContractUnvotedToCurse, error) + + FilterVotedToBless(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractVotedToBlessIterator, error) + + WatchVotedToBless(opts *bind.WatchOpts, sink chan<- *ARMContractVotedToBless, configVersion []uint32, voter []common.Address) (event.Subscription, error) + + ParseVotedToBless(log types.Log) (*ARMContractVotedToBless, error) + + FilterVotedToCurse(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractVotedToCurseIterator, error) + + WatchVotedToCurse(opts *bind.WatchOpts, sink chan<- *ARMContractVotedToCurse, configVersion []uint32, voter []common.Address) (event.Subscription, error) + + ParseVotedToCurse(log types.Log) (*ARMContractVotedToCurse, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/arm_proxy_contract/arm_proxy_contract.go b/core/gethwrappers/ccip/generated/arm_proxy_contract/arm_proxy_contract.go new file mode 100644 index 0000000000..e2ba924621 --- /dev/null +++ b/core/gethwrappers/ccip/generated/arm_proxy_contract/arm_proxy_contract.go @@ -0,0 +1,743 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package arm_proxy_contract + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var ARMProxyContractMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"arm\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"arm\",\"type\":\"address\"}],\"name\":\"ARMSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getARM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"arm\",\"type\":\"address\"}],\"name\":\"setARM\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5060405161084138038061084183398101604081905261002f91610255565b33806000816100855760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100b5576100b5816100cd565b5050506100c78161017660201b60201c565b50610285565b336001600160a01b038216036101255760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161007c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61017e6101f9565b6001600160a01b0381166101a5576040516342bcdf7f60e11b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fef31f568d741a833c6a9dc85a6e1c65e06fa772740d5dc94d1da21827a4e0cab9060200160405180910390a150565b6000546001600160a01b031633146102535760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161007c565b565b60006020828403121561026757600080fd5b81516001600160a01b038116811461027e57600080fd5b9392505050565b6105ad806102946000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c806379ba50971161005057806379ba5097146101615780638da5cb5b14610169578063f2fde38b1461018757610072565b8063181f5a77146100bb5780632e90aa211461010d578063458fec3b1461014c575b60025473ffffffffffffffffffffffffffffffffffffffff16803b61009657600080fd5b366000803760008036600080855af13d6000803e80156100b5573d6000f35b503d6000fd5b6100f76040518060400160405280600e81526020017f41524d50726f787920312e302e3000000000000000000000000000000000000081525081565b60405161010491906104f6565b60405180910390f35b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610104565b61015f61015a366004610563565b61019a565b005b61015f610268565b60005473ffffffffffffffffffffffffffffffffffffffff16610127565b61015f610195366004610563565b61036a565b6101a261037e565b73ffffffffffffffffffffffffffffffffffffffff81166101ef576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fef31f568d741a833c6a9dc85a6e1c65e06fa772740d5dc94d1da21827a4e0cab9060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff1633146102ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61037261037e565b61037b81610401565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102e5565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102e5565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020808352835180602085015260005b8181101561052457858101830151858201604001528201610508565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561057557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461059957600080fd5b939250505056fea164736f6c6343000818000a", +} + +var ARMProxyContractABI = ARMProxyContractMetaData.ABI + +var ARMProxyContractBin = ARMProxyContractMetaData.Bin + +func DeployARMProxyContract(auth *bind.TransactOpts, backend bind.ContractBackend, arm common.Address) (common.Address, *types.Transaction, *ARMProxyContract, error) { + parsed, err := ARMProxyContractMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ARMProxyContractBin), backend, arm) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ARMProxyContract{address: address, abi: *parsed, ARMProxyContractCaller: ARMProxyContractCaller{contract: contract}, ARMProxyContractTransactor: ARMProxyContractTransactor{contract: contract}, ARMProxyContractFilterer: ARMProxyContractFilterer{contract: contract}}, nil +} + +type ARMProxyContract struct { + address common.Address + abi abi.ABI + ARMProxyContractCaller + ARMProxyContractTransactor + ARMProxyContractFilterer +} + +type ARMProxyContractCaller struct { + contract *bind.BoundContract +} + +type ARMProxyContractTransactor struct { + contract *bind.BoundContract +} + +type ARMProxyContractFilterer struct { + contract *bind.BoundContract +} + +type ARMProxyContractSession struct { + Contract *ARMProxyContract + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ARMProxyContractCallerSession struct { + Contract *ARMProxyContractCaller + CallOpts bind.CallOpts +} + +type ARMProxyContractTransactorSession struct { + Contract *ARMProxyContractTransactor + TransactOpts bind.TransactOpts +} + +type ARMProxyContractRaw struct { + Contract *ARMProxyContract +} + +type ARMProxyContractCallerRaw struct { + Contract *ARMProxyContractCaller +} + +type ARMProxyContractTransactorRaw struct { + Contract *ARMProxyContractTransactor +} + +func NewARMProxyContract(address common.Address, backend bind.ContractBackend) (*ARMProxyContract, error) { + abi, err := abi.JSON(strings.NewReader(ARMProxyContractABI)) + if err != nil { + return nil, err + } + contract, err := bindARMProxyContract(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ARMProxyContract{address: address, abi: abi, ARMProxyContractCaller: ARMProxyContractCaller{contract: contract}, ARMProxyContractTransactor: ARMProxyContractTransactor{contract: contract}, ARMProxyContractFilterer: ARMProxyContractFilterer{contract: contract}}, nil +} + +func NewARMProxyContractCaller(address common.Address, caller bind.ContractCaller) (*ARMProxyContractCaller, error) { + contract, err := bindARMProxyContract(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ARMProxyContractCaller{contract: contract}, nil +} + +func NewARMProxyContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ARMProxyContractTransactor, error) { + contract, err := bindARMProxyContract(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ARMProxyContractTransactor{contract: contract}, nil +} + +func NewARMProxyContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ARMProxyContractFilterer, error) { + contract, err := bindARMProxyContract(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ARMProxyContractFilterer{contract: contract}, nil +} + +func bindARMProxyContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ARMProxyContractMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ARMProxyContract *ARMProxyContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ARMProxyContract.Contract.ARMProxyContractCaller.contract.Call(opts, result, method, params...) +} + +func (_ARMProxyContract *ARMProxyContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ARMProxyContract.Contract.ARMProxyContractTransactor.contract.Transfer(opts) +} + +func (_ARMProxyContract *ARMProxyContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ARMProxyContract.Contract.ARMProxyContractTransactor.contract.Transact(opts, method, params...) +} + +func (_ARMProxyContract *ARMProxyContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ARMProxyContract.Contract.contract.Call(opts, result, method, params...) +} + +func (_ARMProxyContract *ARMProxyContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ARMProxyContract.Contract.contract.Transfer(opts) +} + +func (_ARMProxyContract *ARMProxyContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ARMProxyContract.Contract.contract.Transact(opts, method, params...) +} + +func (_ARMProxyContract *ARMProxyContractCaller) GetARM(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ARMProxyContract.contract.Call(opts, &out, "getARM") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ARMProxyContract *ARMProxyContractSession) GetARM() (common.Address, error) { + return _ARMProxyContract.Contract.GetARM(&_ARMProxyContract.CallOpts) +} + +func (_ARMProxyContract *ARMProxyContractCallerSession) GetARM() (common.Address, error) { + return _ARMProxyContract.Contract.GetARM(&_ARMProxyContract.CallOpts) +} + +func (_ARMProxyContract *ARMProxyContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ARMProxyContract.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ARMProxyContract *ARMProxyContractSession) Owner() (common.Address, error) { + return _ARMProxyContract.Contract.Owner(&_ARMProxyContract.CallOpts) +} + +func (_ARMProxyContract *ARMProxyContractCallerSession) Owner() (common.Address, error) { + return _ARMProxyContract.Contract.Owner(&_ARMProxyContract.CallOpts) +} + +func (_ARMProxyContract *ARMProxyContractCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ARMProxyContract.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_ARMProxyContract *ARMProxyContractSession) TypeAndVersion() (string, error) { + return _ARMProxyContract.Contract.TypeAndVersion(&_ARMProxyContract.CallOpts) +} + +func (_ARMProxyContract *ARMProxyContractCallerSession) TypeAndVersion() (string, error) { + return _ARMProxyContract.Contract.TypeAndVersion(&_ARMProxyContract.CallOpts) +} + +func (_ARMProxyContract *ARMProxyContractTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ARMProxyContract.contract.Transact(opts, "acceptOwnership") +} + +func (_ARMProxyContract *ARMProxyContractSession) AcceptOwnership() (*types.Transaction, error) { + return _ARMProxyContract.Contract.AcceptOwnership(&_ARMProxyContract.TransactOpts) +} + +func (_ARMProxyContract *ARMProxyContractTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _ARMProxyContract.Contract.AcceptOwnership(&_ARMProxyContract.TransactOpts) +} + +func (_ARMProxyContract *ARMProxyContractTransactor) SetARM(opts *bind.TransactOpts, arm common.Address) (*types.Transaction, error) { + return _ARMProxyContract.contract.Transact(opts, "setARM", arm) +} + +func (_ARMProxyContract *ARMProxyContractSession) SetARM(arm common.Address) (*types.Transaction, error) { + return _ARMProxyContract.Contract.SetARM(&_ARMProxyContract.TransactOpts, arm) +} + +func (_ARMProxyContract *ARMProxyContractTransactorSession) SetARM(arm common.Address) (*types.Transaction, error) { + return _ARMProxyContract.Contract.SetARM(&_ARMProxyContract.TransactOpts, arm) +} + +func (_ARMProxyContract *ARMProxyContractTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _ARMProxyContract.contract.Transact(opts, "transferOwnership", to) +} + +func (_ARMProxyContract *ARMProxyContractSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _ARMProxyContract.Contract.TransferOwnership(&_ARMProxyContract.TransactOpts, to) +} + +func (_ARMProxyContract *ARMProxyContractTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _ARMProxyContract.Contract.TransferOwnership(&_ARMProxyContract.TransactOpts, to) +} + +func (_ARMProxyContract *ARMProxyContractTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _ARMProxyContract.contract.RawTransact(opts, calldata) +} + +func (_ARMProxyContract *ARMProxyContractSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _ARMProxyContract.Contract.Fallback(&_ARMProxyContract.TransactOpts, calldata) +} + +func (_ARMProxyContract *ARMProxyContractTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _ARMProxyContract.Contract.Fallback(&_ARMProxyContract.TransactOpts, calldata) +} + +type ARMProxyContractARMSetIterator struct { + Event *ARMProxyContractARMSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMProxyContractARMSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMProxyContractARMSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMProxyContractARMSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMProxyContractARMSetIterator) Error() error { + return it.fail +} + +func (it *ARMProxyContractARMSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMProxyContractARMSet struct { + Arm common.Address + Raw types.Log +} + +func (_ARMProxyContract *ARMProxyContractFilterer) FilterARMSet(opts *bind.FilterOpts) (*ARMProxyContractARMSetIterator, error) { + + logs, sub, err := _ARMProxyContract.contract.FilterLogs(opts, "ARMSet") + if err != nil { + return nil, err + } + return &ARMProxyContractARMSetIterator{contract: _ARMProxyContract.contract, event: "ARMSet", logs: logs, sub: sub}, nil +} + +func (_ARMProxyContract *ARMProxyContractFilterer) WatchARMSet(opts *bind.WatchOpts, sink chan<- *ARMProxyContractARMSet) (event.Subscription, error) { + + logs, sub, err := _ARMProxyContract.contract.WatchLogs(opts, "ARMSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMProxyContractARMSet) + if err := _ARMProxyContract.contract.UnpackLog(event, "ARMSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMProxyContract *ARMProxyContractFilterer) ParseARMSet(log types.Log) (*ARMProxyContractARMSet, error) { + event := new(ARMProxyContractARMSet) + if err := _ARMProxyContract.contract.UnpackLog(event, "ARMSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMProxyContractOwnershipTransferRequestedIterator struct { + Event *ARMProxyContractOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMProxyContractOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMProxyContractOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMProxyContractOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMProxyContractOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *ARMProxyContractOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMProxyContractOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_ARMProxyContract *ARMProxyContractFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMProxyContractOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ARMProxyContract.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &ARMProxyContractOwnershipTransferRequestedIterator{contract: _ARMProxyContract.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_ARMProxyContract *ARMProxyContractFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ARMProxyContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ARMProxyContract.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMProxyContractOwnershipTransferRequested) + if err := _ARMProxyContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMProxyContract *ARMProxyContractFilterer) ParseOwnershipTransferRequested(log types.Log) (*ARMProxyContractOwnershipTransferRequested, error) { + event := new(ARMProxyContractOwnershipTransferRequested) + if err := _ARMProxyContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ARMProxyContractOwnershipTransferredIterator struct { + Event *ARMProxyContractOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ARMProxyContractOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ARMProxyContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ARMProxyContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ARMProxyContractOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *ARMProxyContractOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ARMProxyContractOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_ARMProxyContract *ARMProxyContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMProxyContractOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ARMProxyContract.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &ARMProxyContractOwnershipTransferredIterator{contract: _ARMProxyContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_ARMProxyContract *ARMProxyContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ARMProxyContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ARMProxyContract.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ARMProxyContractOwnershipTransferred) + if err := _ARMProxyContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ARMProxyContract *ARMProxyContractFilterer) ParseOwnershipTransferred(log types.Log) (*ARMProxyContractOwnershipTransferred, error) { + event := new(ARMProxyContractOwnershipTransferred) + if err := _ARMProxyContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_ARMProxyContract *ARMProxyContract) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _ARMProxyContract.abi.Events["ARMSet"].ID: + return _ARMProxyContract.ParseARMSet(log) + case _ARMProxyContract.abi.Events["OwnershipTransferRequested"].ID: + return _ARMProxyContract.ParseOwnershipTransferRequested(log) + case _ARMProxyContract.abi.Events["OwnershipTransferred"].ID: + return _ARMProxyContract.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (ARMProxyContractARMSet) Topic() common.Hash { + return common.HexToHash("0xef31f568d741a833c6a9dc85a6e1c65e06fa772740d5dc94d1da21827a4e0cab") +} + +func (ARMProxyContractOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (ARMProxyContractOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_ARMProxyContract *ARMProxyContract) Address() common.Address { + return _ARMProxyContract.address +} + +type ARMProxyContractInterface interface { + GetARM(opts *bind.CallOpts) (common.Address, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + SetARM(opts *bind.TransactOpts, arm common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) + + FilterARMSet(opts *bind.FilterOpts) (*ARMProxyContractARMSetIterator, error) + + WatchARMSet(opts *bind.WatchOpts, sink chan<- *ARMProxyContractARMSet) (event.Subscription, error) + + ParseARMSet(log types.Log) (*ARMProxyContractARMSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMProxyContractOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ARMProxyContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*ARMProxyContractOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMProxyContractOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ARMProxyContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*ARMProxyContractOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go new file mode 100644 index 0000000000..28e67b0dff --- /dev/null +++ b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go @@ -0,0 +1,2780 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package burn_from_mint_token_pool + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type PoolLockOrBurnInV1 struct { + Receiver []byte + RemoteChainSelector uint64 + OriginalSender common.Address + Amount *big.Int + LocalToken common.Address +} + +type PoolLockOrBurnOutV1 struct { + DestTokenAddress []byte + DestPoolData []byte +} + +type PoolReleaseOrMintInV1 struct { + OriginalSender []byte + RemoteChainSelector uint64 + Receiver common.Address + Amount *big.Int + LocalToken common.Address + SourcePoolAddress []byte + SourcePoolData []byte + OffchainTokenData []byte +} + +type PoolReleaseOrMintOutV1 struct { + DestinationAmount *big.Int +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + RemotePoolAddress []byte + RemoteTokenAddress []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +var BurnFromMintTokenPoolMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b50604051620043d9380380620043d98339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161386062000b79600039600081816104960152818161164501526120290152600081816104700152818161147601526118fb01526000818161022301528181610278015281816106ba015281816113960152818161181b01528181611a1301528181611fbf015261221401526138606000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c8063a7cd63b7116100e3578063c75eea9c1161008c578063dc0bd97111610066578063dc0bd9711461046e578063e0351e1314610494578063f2fde38b146104ba57600080fd5b8063c75eea9c14610435578063cf7401f314610448578063db6327dc1461045b57600080fd5b8063b7946580116100bd578063b7946580146103fa578063c0d786551461040d578063c4bffe2b1461042057600080fd5b8063a7cd63b714610358578063af58d59f1461036d578063b0f479a1146103dc57600080fd5b806354c8a4f3116101455780638926f54f1161011f5780638926f54f146103075780638da5cb5b1461031a5780639a4575b91461033857600080fd5b806354c8a4f3146102d757806378a010b2146102ec57806379ba5097146102ff57600080fd5b806321df0da71161017657806321df0da714610221578063240028e81461026857806339077537146102b557600080fd5b806301ffc9a71461019d5780630a2fd493146101c5578063181f5a77146101e5575b600080fd5b6101b06101ab3660046129b7565b6104cd565b60405190151581526020015b60405180910390f35b6101d86101d3366004612a16565b6105b2565b6040516101bc9190612a95565b6101d86040518060400160405280601f81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e302d6465760081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b6101b0610276366004612ad5565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102c86102c3366004612af2565b610662565b604051905181526020016101bc565b6102ea6102e5366004612b7a565b6107bd565b005b6102ea6102fa366004612be6565b610838565b6102ea6109ac565b6101b0610315366004612a16565b610aa9565b60005473ffffffffffffffffffffffffffffffffffffffff16610243565b61034b610346366004612c69565b610ac0565b6040516101bc9190612ca4565b610360610b67565b6040516101bc9190612d04565b61038061037b366004612a16565b610b78565b6040516101bc919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610243565b6101d8610408366004612a16565b610c4d565b6102ea61041b366004612ad5565b610c78565b610428610d53565b6040516101bc9190612d5e565b610380610443366004612a16565b610e0b565b6102ea610456366004612ec6565b610edd565b6102ea610469366004612f0b565b610ef5565b7f0000000000000000000000000000000000000000000000000000000000000000610243565b7f00000000000000000000000000000000000000000000000000000000000000006101b0565b6102ea6104c8366004612ad5565b61137b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061056057507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105ac57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906105dd90612f4d565b80601f016020809104026020016040519081016040528092919081815260200182805461060990612f4d565b80156106565780601f1061062b57610100808354040283529160200191610656565b820191906000526020600020905b81548152906001019060200180831161063957829003601f168201915b50505050509050919050565b60408051602081019091526000815261068261067d8361304b565b61138f565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561071357600080fd5b505af1158015610727573d6000803e3d6000fd5b5061073c925050506060830160408401612ad5565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161079e91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6107c56115c0565b6108328484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061164392505050565b50505050565b6108406115c0565b61084983610aa9565b610890576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546108b790612f4d565b80601f01602080910402602001604051908101604052809291908181526020018280546108e390612f4d565b80156109305780601f1061090557610100808354040283529160200191610930565b820191906000526020600020905b81548152906001019060200180831161091357829003601f168201915b5050505067ffffffffffffffff861660009081526007602052604090209192505060040161095f838583613190565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf82858560405161099e939291906132aa565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610887565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006105ac600567ffffffffffffffff84166117f9565b6040805180820190915260608082526020820152610ae5610ae08361330e565b611814565b610af282606001356119de565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b4c8460200160208101906104089190612a16565b81526040805160208181019092526000815291015292915050565b6060610b736002611a87565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105ac90611a94565b67ffffffffffffffff811660009081526007602052604090206005018054606091906105dd90612f4d565b610c806115c0565b73ffffffffffffffffffffffffffffffffffffffff8116610ccd576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610d616005611a87565b90506000815167ffffffffffffffff811115610d7f57610d7f612da0565b604051908082528060200260200182016040528015610da8578160200160208202803683370190505b50905060005b8251811015610e0457828181518110610dc957610dc96133b0565b6020026020010151828281518110610de357610de36133b0565b67ffffffffffffffff90921660209283029190910190910152600101610dae565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105ac90611a94565b610ee56115c0565b610ef0838383611b46565b505050565b610efd6115c0565b60005b81811015610ef0576000838383818110610f1c57610f1c6133b0565b9050602002810190610f2e91906133df565b610f379061341d565b9050610f4c8160800151826020015115611c30565b610f5f8160a00151826020015115611c30565b80602001511561125b578051610f819060059067ffffffffffffffff16611d69565b610fc65780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610887565b6040810151511580610fdb5750606081015151155b15611012576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906111f390826134d1565b506060820151600582019061120890826134d1565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061124e94939291906135eb565b60405180910390a1611372565b80516112739060059067ffffffffffffffff16611d75565b6112b85780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610887565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906113216004830182612969565b61132f600583016000612969565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101610f00565b6113836115c0565b61138c81611d81565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146114245760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610887565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f69190613684565b1561152d576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61153a8160200151611e76565b600061154982602001516105b2565b905080516000148061156d575080805190602001208260a001518051906020012014155b156115aa578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108879190612a95565b6115bc82602001518360600151611f9c565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611641576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610887565b565b7f000000000000000000000000000000000000000000000000000000000000000061169a576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156117305760008382815181106116ba576116ba6133b0565b602002602001015190506116d8816002611fe390919063ffffffff16565b156117275760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010161169d565b5060005b8151811015610ef0576000828281518110611751576117516133b0565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361179557506117f1565b6117a0600282612005565b156117ef5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611734565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146118a95760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610887565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197b9190613684565b156119b2576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119bf8160400151612027565b6119cc81602001516120a6565b61138c816020015182606001516121f4565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015611a6c57600080fd5b505af1158015611a80573d6000803e3d6000fd5b5050505050565b6060600061180d83612238565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611b2282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611b0691906136d0565b85608001516fffffffffffffffffffffffffffffffff16612293565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611b4f83610aa9565b611b91576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610887565b611b9c826000611c30565b67ffffffffffffffff83166000908152600760205260409020611bbf90836122bd565b611bca816000611c30565b67ffffffffffffffff83166000908152600760205260409020611bf090600201826122bd565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611c23939291906136e3565b60405180910390a1505050565b815115611cf75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611c86575060408201516fffffffffffffffffffffffffffffffff16155b15611cbf57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108879190613766565b80156115bc576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611d30575060208201516fffffffffffffffffffffffffffffffff1615155b156115bc57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108879190613766565b600061180d838361245f565b600061180d83836124ae565b3373ffffffffffffffffffffffffffffffffffffffff821603611e00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610887565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611e7f81610aa9565b611ec1576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610887565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015611f40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f649190613684565b61138c576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610887565b67ffffffffffffffff821660009081526007602052604090206115bc90600201827f00000000000000000000000000000000000000000000000000000000000000006125a1565b600061180d8373ffffffffffffffffffffffffffffffffffffffff84166124ae565b600061180d8373ffffffffffffffffffffffffffffffffffffffff841661245f565b7f00000000000000000000000000000000000000000000000000000000000000001561138c57612058600282612924565b61138c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610887565b6120af81610aa9565b6120f1576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610887565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561216a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061218e91906137a2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461138c576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610887565b67ffffffffffffffff821660009081526007602052604090206115bc90827f00000000000000000000000000000000000000000000000000000000000000006125a1565b60608160000180548060200260200160405190810160405280929190818152602001828054801561065657602002820191906000526020600020905b8154815260200190600101908083116122745750505050509050919050565b60006122b2856122a384866137bf565b6122ad90876137d6565b612953565b90505b949350505050565b81546000906122e690700100000000000000000000000000000000900463ffffffff16426136d0565b90508015612388576001830154835461232e916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612293565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546123ae916fffffffffffffffffffffffffffffffff9081169116612953565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611c23908490613766565b60008181526001830160205260408120546124a6575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105ac565b5060006105ac565b600081815260018301602052604081205480156125975760006124d26001836136d0565b85549091506000906124e6906001906136d0565b905081811461254b576000866000018281548110612506576125066133b0565b9060005260206000200154905080876000018481548110612529576125296133b0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061255c5761255c6137e9565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105ac565b60009150506105ac565b825474010000000000000000000000000000000000000000900460ff1615806125c8575081155b156125d257505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061261890700100000000000000000000000000000000900463ffffffff16426136d0565b905080156126d8578183111561265a576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546126949083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612293565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561278f5773ffffffffffffffffffffffffffffffffffffffff8416612737576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610887565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610887565b848310156128a25760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906127d390826136d0565b6127dd878a6136d0565b6127e791906137d6565b6127f19190613818565b905073ffffffffffffffffffffffffffffffffffffffff861661284a576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610887565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610887565b6128ac85846136d0565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561180d565b6000818310612962578161180d565b5090919050565b50805461297590612f4d565b6000825580601f10612985575050565b601f01602090049060005260206000209081019061138c91905b808211156129b3576000815560010161299f565b5090565b6000602082840312156129c957600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461180d57600080fd5b803567ffffffffffffffff81168114612a1157600080fd5b919050565b600060208284031215612a2857600080fd5b61180d826129f9565b6000815180845260005b81811015612a5757602081850181015186830182015201612a3b565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061180d6020830184612a31565b73ffffffffffffffffffffffffffffffffffffffff8116811461138c57600080fd5b8035612a1181612aa8565b600060208284031215612ae757600080fd5b813561180d81612aa8565b600060208284031215612b0457600080fd5b813567ffffffffffffffff811115612b1b57600080fd5b8201610100818503121561180d57600080fd5b60008083601f840112612b4057600080fd5b50813567ffffffffffffffff811115612b5857600080fd5b6020830191508360208260051b8501011115612b7357600080fd5b9250929050565b60008060008060408587031215612b9057600080fd5b843567ffffffffffffffff80821115612ba857600080fd5b612bb488838901612b2e565b90965094506020870135915080821115612bcd57600080fd5b50612bda87828801612b2e565b95989497509550505050565b600080600060408486031215612bfb57600080fd5b612c04846129f9565b9250602084013567ffffffffffffffff80821115612c2157600080fd5b818601915086601f830112612c3557600080fd5b813581811115612c4457600080fd5b876020828501011115612c5657600080fd5b6020830194508093505050509250925092565b600060208284031215612c7b57600080fd5b813567ffffffffffffffff811115612c9257600080fd5b820160a0818503121561180d57600080fd5b602081526000825160406020840152612cc06060840182612a31565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612cfb8282612a31565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d5257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612d20565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d5257835167ffffffffffffffff1683529284019291840191600101612d7a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612df357612df3612da0565b60405290565b60405160c0810167ffffffffffffffff81118282101715612df357612df3612da0565b801515811461138c57600080fd5b8035612a1181612e1c565b80356fffffffffffffffffffffffffffffffff81168114612a1157600080fd5b600060608284031215612e6757600080fd5b6040516060810181811067ffffffffffffffff82111715612e8a57612e8a612da0565b6040529050808235612e9b81612e1c565b8152612ea960208401612e35565b6020820152612eba60408401612e35565b60408201525092915050565b600080600060e08486031215612edb57600080fd5b612ee4846129f9565b9250612ef38560208601612e55565b9150612f028560808601612e55565b90509250925092565b60008060208385031215612f1e57600080fd5b823567ffffffffffffffff811115612f3557600080fd5b612f4185828601612b2e565b90969095509350505050565b600181811c90821680612f6157607f821691505b602082108103612f9a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f830112612fb157600080fd5b813567ffffffffffffffff80821115612fcc57612fcc612da0565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561301257613012612da0565b8160405283815286602085880101111561302b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561305e57600080fd5b613066612dcf565b823567ffffffffffffffff8082111561307e57600080fd5b61308a36838701612fa0565b8352613098602086016129f9565b60208401526130a960408601612aca565b6040840152606085013560608401526130c460808601612aca565b608084015260a08501359150808211156130dd57600080fd5b6130e936838701612fa0565b60a084015260c085013591508082111561310257600080fd5b61310e36838701612fa0565b60c084015260e085013591508082111561312757600080fd5b5061313436828601612fa0565b60e08301525092915050565b601f821115610ef0576000816000526020600020601f850160051c810160208610156131695750805b601f850160051c820191505b8181101561318857828155600101613175565b505050505050565b67ffffffffffffffff8311156131a8576131a8612da0565b6131bc836131b68354612f4d565b83613140565b6000601f84116001811461320e57600085156131d85750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a80565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561325d578685013582556020948501946001909201910161323d565b5086821015613298577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006132bd6040830186612a31565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561332057600080fd5b60405160a0810167ffffffffffffffff828210818311171561334457613344612da0565b81604052843591508082111561335957600080fd5b5061336636828601612fa0565b825250613375602084016129f9565b6020820152604083013561338881612aa8565b60408201526060838101359082015260808301356133a581612aa8565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261341357600080fd5b9190910192915050565b6000610140823603121561343057600080fd5b613438612df9565b613441836129f9565b815261344f60208401612e2a565b6020820152604083013567ffffffffffffffff8082111561346f57600080fd5b61347b36838701612fa0565b6040840152606085013591508082111561349457600080fd5b506134a136828601612fa0565b6060830152506134b43660808501612e55565b60808201526134c63660e08501612e55565b60a082015292915050565b815167ffffffffffffffff8111156134eb576134eb612da0565b6134ff816134f98454612f4d565b84613140565b602080601f831160018114613552576000841561351c5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613188565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561359f57888601518255948401946001909101908401613580565b50858210156135db57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261360f81840187612a31565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061364d9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612cfb565b60006020828403121561369657600080fd5b815161180d81612e1c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105ac576105ac6136a1565b67ffffffffffffffff8416815260e0810161372f60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526122b5565b606081016105ac82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156137b457600080fd5b815161180d81612aa8565b80820281158282048414176105ac576105ac6136a1565b808201808211156105ac576105ac6136a1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261384e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", +} + +var BurnFromMintTokenPoolABI = BurnFromMintTokenPoolMetaData.ABI + +var BurnFromMintTokenPoolBin = BurnFromMintTokenPoolMetaData.Bin + +func DeployBurnFromMintTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, rmnProxy common.Address, router common.Address) (common.Address, *types.Transaction, *BurnFromMintTokenPool, error) { + parsed, err := BurnFromMintTokenPoolMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnFromMintTokenPoolBin), backend, token, allowlist, rmnProxy, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &BurnFromMintTokenPool{address: address, abi: *parsed, BurnFromMintTokenPoolCaller: BurnFromMintTokenPoolCaller{contract: contract}, BurnFromMintTokenPoolTransactor: BurnFromMintTokenPoolTransactor{contract: contract}, BurnFromMintTokenPoolFilterer: BurnFromMintTokenPoolFilterer{contract: contract}}, nil +} + +type BurnFromMintTokenPool struct { + address common.Address + abi abi.ABI + BurnFromMintTokenPoolCaller + BurnFromMintTokenPoolTransactor + BurnFromMintTokenPoolFilterer +} + +type BurnFromMintTokenPoolCaller struct { + contract *bind.BoundContract +} + +type BurnFromMintTokenPoolTransactor struct { + contract *bind.BoundContract +} + +type BurnFromMintTokenPoolFilterer struct { + contract *bind.BoundContract +} + +type BurnFromMintTokenPoolSession struct { + Contract *BurnFromMintTokenPool + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type BurnFromMintTokenPoolCallerSession struct { + Contract *BurnFromMintTokenPoolCaller + CallOpts bind.CallOpts +} + +type BurnFromMintTokenPoolTransactorSession struct { + Contract *BurnFromMintTokenPoolTransactor + TransactOpts bind.TransactOpts +} + +type BurnFromMintTokenPoolRaw struct { + Contract *BurnFromMintTokenPool +} + +type BurnFromMintTokenPoolCallerRaw struct { + Contract *BurnFromMintTokenPoolCaller +} + +type BurnFromMintTokenPoolTransactorRaw struct { + Contract *BurnFromMintTokenPoolTransactor +} + +func NewBurnFromMintTokenPool(address common.Address, backend bind.ContractBackend) (*BurnFromMintTokenPool, error) { + abi, err := abi.JSON(strings.NewReader(BurnFromMintTokenPoolABI)) + if err != nil { + return nil, err + } + contract, err := bindBurnFromMintTokenPool(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &BurnFromMintTokenPool{address: address, abi: abi, BurnFromMintTokenPoolCaller: BurnFromMintTokenPoolCaller{contract: contract}, BurnFromMintTokenPoolTransactor: BurnFromMintTokenPoolTransactor{contract: contract}, BurnFromMintTokenPoolFilterer: BurnFromMintTokenPoolFilterer{contract: contract}}, nil +} + +func NewBurnFromMintTokenPoolCaller(address common.Address, caller bind.ContractCaller) (*BurnFromMintTokenPoolCaller, error) { + contract, err := bindBurnFromMintTokenPool(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolCaller{contract: contract}, nil +} + +func NewBurnFromMintTokenPoolTransactor(address common.Address, transactor bind.ContractTransactor) (*BurnFromMintTokenPoolTransactor, error) { + contract, err := bindBurnFromMintTokenPool(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolTransactor{contract: contract}, nil +} + +func NewBurnFromMintTokenPoolFilterer(address common.Address, filterer bind.ContractFilterer) (*BurnFromMintTokenPoolFilterer, error) { + contract, err := bindBurnFromMintTokenPool(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolFilterer{contract: contract}, nil +} + +func bindBurnFromMintTokenPool(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := BurnFromMintTokenPoolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnFromMintTokenPool.Contract.BurnFromMintTokenPoolCaller.contract.Call(opts, result, method, params...) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.BurnFromMintTokenPoolTransactor.contract.Transfer(opts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.BurnFromMintTokenPoolTransactor.contract.Transact(opts, method, params...) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnFromMintTokenPool.Contract.contract.Call(opts, result, method, params...) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.contract.Transfer(opts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.contract.Transact(opts, method, params...) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetAllowList() ([]common.Address, error) { + return _BurnFromMintTokenPool.Contract.GetAllowList(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetAllowList() ([]common.Address, error) { + return _BurnFromMintTokenPool.Contract.GetAllowList(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetAllowListEnabled() (bool, error) { + return _BurnFromMintTokenPool.Contract.GetAllowListEnabled(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetAllowListEnabled() (bool, error) { + return _BurnFromMintTokenPool.Contract.GetAllowListEnabled(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnFromMintTokenPool.Contract.GetCurrentInboundRateLimiterState(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnFromMintTokenPool.Contract.GetCurrentInboundRateLimiterState(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnFromMintTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnFromMintTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _BurnFromMintTokenPool.Contract.GetRemotePool(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _BurnFromMintTokenPool.Contract.GetRemotePool(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getRemoteToken", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _BurnFromMintTokenPool.Contract.GetRemoteToken(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _BurnFromMintTokenPool.Contract.GetRemoteToken(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetRmnProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getRmnProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetRmnProxy() (common.Address, error) { + return _BurnFromMintTokenPool.Contract.GetRmnProxy(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetRmnProxy() (common.Address, error) { + return _BurnFromMintTokenPool.Contract.GetRmnProxy(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetRouter() (common.Address, error) { + return _BurnFromMintTokenPool.Contract.GetRouter(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetRouter() (common.Address, error) { + return _BurnFromMintTokenPool.Contract.GetRouter(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetSupportedChains() ([]uint64, error) { + return _BurnFromMintTokenPool.Contract.GetSupportedChains(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetSupportedChains() ([]uint64, error) { + return _BurnFromMintTokenPool.Contract.GetSupportedChains(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetToken() (common.Address, error) { + return _BurnFromMintTokenPool.Contract.GetToken(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetToken() (common.Address, error) { + return _BurnFromMintTokenPool.Contract.GetToken(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _BurnFromMintTokenPool.Contract.IsSupportedChain(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _BurnFromMintTokenPool.Contract.IsSupportedChain(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "isSupportedToken", token) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) IsSupportedToken(token common.Address) (bool, error) { + return _BurnFromMintTokenPool.Contract.IsSupportedToken(&_BurnFromMintTokenPool.CallOpts, token) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) IsSupportedToken(token common.Address) (bool, error) { + return _BurnFromMintTokenPool.Contract.IsSupportedToken(&_BurnFromMintTokenPool.CallOpts, token) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) Owner() (common.Address, error) { + return _BurnFromMintTokenPool.Contract.Owner(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) Owner() (common.Address, error) { + return _BurnFromMintTokenPool.Contract.Owner(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnFromMintTokenPool.Contract.SupportsInterface(&_BurnFromMintTokenPool.CallOpts, interfaceId) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnFromMintTokenPool.Contract.SupportsInterface(&_BurnFromMintTokenPool.CallOpts, interfaceId) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) TypeAndVersion() (string, error) { + return _BurnFromMintTokenPool.Contract.TypeAndVersion(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) TypeAndVersion() (string, error) { + return _BurnFromMintTokenPool.Contract.TypeAndVersion(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "acceptOwnership") +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.AcceptOwnership(&_BurnFromMintTokenPool.TransactOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.AcceptOwnership(&_BurnFromMintTokenPool.TransactOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnFromMintTokenPool.TransactOpts, removes, adds) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnFromMintTokenPool.TransactOpts, removes, adds) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.ApplyChainUpdates(&_BurnFromMintTokenPool.TransactOpts, chains) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.ApplyChainUpdates(&_BurnFromMintTokenPool.TransactOpts, chains) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "lockOrBurn", lockOrBurnIn) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.LockOrBurn(&_BurnFromMintTokenPool.TransactOpts, lockOrBurnIn) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.LockOrBurn(&_BurnFromMintTokenPool.TransactOpts, lockOrBurnIn) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "releaseOrMint", releaseOrMintIn) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.ReleaseOrMint(&_BurnFromMintTokenPool.TransactOpts, releaseOrMintIn) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.ReleaseOrMint(&_BurnFromMintTokenPool.TransactOpts, releaseOrMintIn) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.SetRemotePool(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.SetRemotePool(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "setRouter", newRouter) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.SetRouter(&_BurnFromMintTokenPool.TransactOpts, newRouter) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.SetRouter(&_BurnFromMintTokenPool.TransactOpts, newRouter) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "transferOwnership", to) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.TransferOwnership(&_BurnFromMintTokenPool.TransactOpts, to) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.TransferOwnership(&_BurnFromMintTokenPool.TransactOpts, to) +} + +type BurnFromMintTokenPoolAllowListAddIterator struct { + Event *BurnFromMintTokenPoolAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolAllowListAddIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*BurnFromMintTokenPoolAllowListAddIterator, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolAllowListAddIterator{contract: _BurnFromMintTokenPool.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolAllowListAdd) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseAllowListAdd(log types.Log) (*BurnFromMintTokenPoolAllowListAdd, error) { + event := new(BurnFromMintTokenPoolAllowListAdd) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolAllowListRemoveIterator struct { + Event *BurnFromMintTokenPoolAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*BurnFromMintTokenPoolAllowListRemoveIterator, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolAllowListRemoveIterator{contract: _BurnFromMintTokenPool.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolAllowListRemove) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseAllowListRemove(log types.Log) (*BurnFromMintTokenPoolAllowListRemove, error) { + event := new(BurnFromMintTokenPoolAllowListRemove) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolBurnedIterator struct { + Event *BurnFromMintTokenPoolBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolBurnedIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnFromMintTokenPoolBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolBurnedIterator{contract: _BurnFromMintTokenPool.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolBurned) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseBurned(log types.Log) (*BurnFromMintTokenPoolBurned, error) { + event := new(BurnFromMintTokenPoolBurned) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolChainAddedIterator struct { + Event *BurnFromMintTokenPoolChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolChainAddedIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolChainAdded struct { + RemoteChainSelector uint64 + RemoteToken []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterChainAdded(opts *bind.FilterOpts) (*BurnFromMintTokenPoolChainAddedIterator, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolChainAddedIterator{contract: _BurnFromMintTokenPool.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolChainAdded) (event.Subscription, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolChainAdded) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseChainAdded(log types.Log) (*BurnFromMintTokenPoolChainAdded, error) { + event := new(BurnFromMintTokenPoolChainAdded) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolChainConfiguredIterator struct { + Event *BurnFromMintTokenPoolChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*BurnFromMintTokenPoolChainConfiguredIterator, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolChainConfiguredIterator{contract: _BurnFromMintTokenPool.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolChainConfigured) (event.Subscription, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolChainConfigured) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseChainConfigured(log types.Log) (*BurnFromMintTokenPoolChainConfigured, error) { + event := new(BurnFromMintTokenPoolChainConfigured) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolChainRemovedIterator struct { + Event *BurnFromMintTokenPoolChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolChainRemovedIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*BurnFromMintTokenPoolChainRemovedIterator, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolChainRemovedIterator{contract: _BurnFromMintTokenPool.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolChainRemoved) (event.Subscription, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolChainRemoved) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseChainRemoved(log types.Log) (*BurnFromMintTokenPoolChainRemoved, error) { + event := new(BurnFromMintTokenPoolChainRemoved) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolConfigChangedIterator struct { + Event *BurnFromMintTokenPoolConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolConfigChangedIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolConfigChanged struct { + Config RateLimiterConfig + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*BurnFromMintTokenPoolConfigChangedIterator, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolConfigChangedIterator{contract: _BurnFromMintTokenPool.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolConfigChanged) (event.Subscription, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolConfigChanged) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseConfigChanged(log types.Log) (*BurnFromMintTokenPoolConfigChanged, error) { + event := new(BurnFromMintTokenPoolConfigChanged) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolLockedIterator struct { + Event *BurnFromMintTokenPoolLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolLockedIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnFromMintTokenPoolLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolLockedIterator{contract: _BurnFromMintTokenPool.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolLocked) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseLocked(log types.Log) (*BurnFromMintTokenPoolLocked, error) { + event := new(BurnFromMintTokenPoolLocked) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolMintedIterator struct { + Event *BurnFromMintTokenPoolMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolMintedIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnFromMintTokenPoolMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolMintedIterator{contract: _BurnFromMintTokenPool.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolMinted) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseMinted(log types.Log) (*BurnFromMintTokenPoolMinted, error) { + event := new(BurnFromMintTokenPoolMinted) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolOwnershipTransferRequestedIterator struct { + Event *BurnFromMintTokenPoolOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnFromMintTokenPoolOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolOwnershipTransferRequestedIterator{contract: _BurnFromMintTokenPool.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolOwnershipTransferRequested) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseOwnershipTransferRequested(log types.Log) (*BurnFromMintTokenPoolOwnershipTransferRequested, error) { + event := new(BurnFromMintTokenPoolOwnershipTransferRequested) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolOwnershipTransferredIterator struct { + Event *BurnFromMintTokenPoolOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnFromMintTokenPoolOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolOwnershipTransferredIterator{contract: _BurnFromMintTokenPool.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolOwnershipTransferred) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseOwnershipTransferred(log types.Log) (*BurnFromMintTokenPoolOwnershipTransferred, error) { + event := new(BurnFromMintTokenPoolOwnershipTransferred) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolReleasedIterator struct { + Event *BurnFromMintTokenPoolReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolReleasedIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnFromMintTokenPoolReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolReleasedIterator{contract: _BurnFromMintTokenPool.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolReleased) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseReleased(log types.Log) (*BurnFromMintTokenPoolReleased, error) { + event := new(BurnFromMintTokenPoolReleased) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolRemotePoolSetIterator struct { + Event *BurnFromMintTokenPoolRemotePoolSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolRemotePoolSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolRemotePoolSetIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolRemotePoolSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolRemotePoolSet struct { + RemoteChainSelector uint64 + PreviousPoolAddress []byte + RemotePoolAddress []byte + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnFromMintTokenPoolRemotePoolSetIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolRemotePoolSetIterator{contract: _BurnFromMintTokenPool.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolRemotePoolSet) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseRemotePoolSet(log types.Log) (*BurnFromMintTokenPoolRemotePoolSet, error) { + event := new(BurnFromMintTokenPoolRemotePoolSet) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolRouterUpdatedIterator struct { + Event *BurnFromMintTokenPoolRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*BurnFromMintTokenPoolRouterUpdatedIterator, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolRouterUpdatedIterator{contract: _BurnFromMintTokenPool.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolRouterUpdated) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseRouterUpdated(log types.Log) (*BurnFromMintTokenPoolRouterUpdated, error) { + event := new(BurnFromMintTokenPoolRouterUpdated) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolTokensConsumedIterator struct { + Event *BurnFromMintTokenPoolTokensConsumed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolTokensConsumedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnFromMintTokenPoolTokensConsumedIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolTokensConsumedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolTokensConsumed struct { + Tokens *big.Int + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterTokensConsumed(opts *bind.FilterOpts) (*BurnFromMintTokenPoolTokensConsumedIterator, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolTokensConsumedIterator{contract: _BurnFromMintTokenPool.contract, event: "TokensConsumed", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolTokensConsumed) (event.Subscription, error) { + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolTokensConsumed) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseTokensConsumed(log types.Log) (*BurnFromMintTokenPoolTokensConsumed, error) { + event := new(BurnFromMintTokenPoolTokensConsumed) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPool) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _BurnFromMintTokenPool.abi.Events["AllowListAdd"].ID: + return _BurnFromMintTokenPool.ParseAllowListAdd(log) + case _BurnFromMintTokenPool.abi.Events["AllowListRemove"].ID: + return _BurnFromMintTokenPool.ParseAllowListRemove(log) + case _BurnFromMintTokenPool.abi.Events["Burned"].ID: + return _BurnFromMintTokenPool.ParseBurned(log) + case _BurnFromMintTokenPool.abi.Events["ChainAdded"].ID: + return _BurnFromMintTokenPool.ParseChainAdded(log) + case _BurnFromMintTokenPool.abi.Events["ChainConfigured"].ID: + return _BurnFromMintTokenPool.ParseChainConfigured(log) + case _BurnFromMintTokenPool.abi.Events["ChainRemoved"].ID: + return _BurnFromMintTokenPool.ParseChainRemoved(log) + case _BurnFromMintTokenPool.abi.Events["ConfigChanged"].ID: + return _BurnFromMintTokenPool.ParseConfigChanged(log) + case _BurnFromMintTokenPool.abi.Events["Locked"].ID: + return _BurnFromMintTokenPool.ParseLocked(log) + case _BurnFromMintTokenPool.abi.Events["Minted"].ID: + return _BurnFromMintTokenPool.ParseMinted(log) + case _BurnFromMintTokenPool.abi.Events["OwnershipTransferRequested"].ID: + return _BurnFromMintTokenPool.ParseOwnershipTransferRequested(log) + case _BurnFromMintTokenPool.abi.Events["OwnershipTransferred"].ID: + return _BurnFromMintTokenPool.ParseOwnershipTransferred(log) + case _BurnFromMintTokenPool.abi.Events["Released"].ID: + return _BurnFromMintTokenPool.ParseReleased(log) + case _BurnFromMintTokenPool.abi.Events["RemotePoolSet"].ID: + return _BurnFromMintTokenPool.ParseRemotePoolSet(log) + case _BurnFromMintTokenPool.abi.Events["RouterUpdated"].ID: + return _BurnFromMintTokenPool.ParseRouterUpdated(log) + case _BurnFromMintTokenPool.abi.Events["TokensConsumed"].ID: + return _BurnFromMintTokenPool.ParseTokensConsumed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (BurnFromMintTokenPoolAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (BurnFromMintTokenPoolAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (BurnFromMintTokenPoolBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (BurnFromMintTokenPoolChainAdded) Topic() common.Hash { + return common.HexToHash("0x8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2") +} + +func (BurnFromMintTokenPoolChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (BurnFromMintTokenPoolChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (BurnFromMintTokenPoolConfigChanged) Topic() common.Hash { + return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") +} + +func (BurnFromMintTokenPoolLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (BurnFromMintTokenPoolMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (BurnFromMintTokenPoolOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (BurnFromMintTokenPoolOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (BurnFromMintTokenPoolReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (BurnFromMintTokenPoolRemotePoolSet) Topic() common.Hash { + return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +} + +func (BurnFromMintTokenPoolRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (BurnFromMintTokenPoolTokensConsumed) Topic() common.Hash { + return common.HexToHash("0x1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a") +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPool) Address() common.Address { + return _BurnFromMintTokenPool.address +} + +type BurnFromMintTokenPoolInterface interface { + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRmnProxy(opts *bind.CallOpts) (common.Address, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*BurnFromMintTokenPoolAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*BurnFromMintTokenPoolAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*BurnFromMintTokenPoolAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*BurnFromMintTokenPoolAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnFromMintTokenPoolBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*BurnFromMintTokenPoolBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*BurnFromMintTokenPoolChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*BurnFromMintTokenPoolChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*BurnFromMintTokenPoolChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*BurnFromMintTokenPoolChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*BurnFromMintTokenPoolChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*BurnFromMintTokenPoolChainRemoved, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*BurnFromMintTokenPoolConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*BurnFromMintTokenPoolConfigChanged, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnFromMintTokenPoolLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*BurnFromMintTokenPoolLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnFromMintTokenPoolMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*BurnFromMintTokenPoolMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnFromMintTokenPoolOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*BurnFromMintTokenPoolOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnFromMintTokenPoolOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*BurnFromMintTokenPoolOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnFromMintTokenPoolReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*BurnFromMintTokenPoolReleased, error) + + FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnFromMintTokenPoolRemotePoolSetIterator, error) + + WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolSet(log types.Log) (*BurnFromMintTokenPoolRemotePoolSet, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*BurnFromMintTokenPoolRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*BurnFromMintTokenPoolRouterUpdated, error) + + FilterTokensConsumed(opts *bind.FilterOpts) (*BurnFromMintTokenPoolTokensConsumedIterator, error) + + WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolTokensConsumed) (event.Subscription, error) + + ParseTokensConsumed(log types.Log) (*BurnFromMintTokenPoolTokensConsumed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go new file mode 100644 index 0000000000..70e2f9393e --- /dev/null +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go @@ -0,0 +1,2780 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package burn_mint_token_pool + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type PoolLockOrBurnInV1 struct { + Receiver []byte + RemoteChainSelector uint64 + OriginalSender common.Address + Amount *big.Int + LocalToken common.Address +} + +type PoolLockOrBurnOutV1 struct { + DestTokenAddress []byte + DestPoolData []byte +} + +type PoolReleaseOrMintInV1 struct { + OriginalSender []byte + RemoteChainSelector uint64 + Receiver common.Address + Amount *big.Int + LocalToken common.Address + SourcePoolAddress []byte + SourcePoolData []byte + OffchainTokenData []byte +} + +type PoolReleaseOrMintOutV1 struct { + DestinationAmount *big.Int +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + RemotePoolAddress []byte + RemoteTokenAddress []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +var BurnMintTokenPoolMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b5060405162003f8138038062003f8183398101604081905262000034916200054c565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000176565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001685760408051600081526020810190915262000168908462000221565b5050505050505050620006aa565b336001600160a01b03821603620001d05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000242576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002cd5760008382815181106200026657620002666200065c565b60209081029190910101519050620002806002826200037e565b15620002c3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000245565b5060005b815181101562000379576000828281518110620002f257620002f26200065c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200031e575062000370565b6200032b6002826200039e565b156200036e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d1565b505050565b600062000395836001600160a01b038416620003b5565b90505b92915050565b600062000395836001600160a01b038416620004b9565b60008181526001830160205260408120548015620004ae576000620003dc60018362000672565b8554909150600090620003f29060019062000672565b90508181146200045e5760008660000182815481106200041657620004166200065c565b90600052602060002001549050808760000184815481106200043c576200043c6200065c565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000472576200047262000694565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000398565b600091505062000398565b6000818152600183016020526040812054620005025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000398565b50600062000398565b6001600160a01b03811681146200052157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000547816200050b565b919050565b600080600080608085870312156200056357600080fd5b845162000570816200050b565b602086810151919550906001600160401b03808211156200059057600080fd5b818801915088601f830112620005a557600080fd5b815181811115620005ba57620005ba62000524565b8060051b604051601f19603f83011681018181108582111715620005e257620005e262000524565b60405291825284820192508381018501918b8311156200060157600080fd5b938501935b828510156200062a576200061a856200053a565b8452938501939285019262000606565b80985050505050505062000641604086016200053a565b915062000651606086016200053a565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161385a62000727600039600081816104960152818161164501526120230152600081816104700152818161147601526118fb01526000818161022301528181610278015281816106ba015281816113960152818161181b01528181611a0d01528181611fb9015261220e015261385a6000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c8063a7cd63b7116100e3578063c75eea9c1161008c578063dc0bd97111610066578063dc0bd9711461046e578063e0351e1314610494578063f2fde38b146104ba57600080fd5b8063c75eea9c14610435578063cf7401f314610448578063db6327dc1461045b57600080fd5b8063b7946580116100bd578063b7946580146103fa578063c0d786551461040d578063c4bffe2b1461042057600080fd5b8063a7cd63b714610358578063af58d59f1461036d578063b0f479a1146103dc57600080fd5b806354c8a4f3116101455780638926f54f1161011f5780638926f54f146103075780638da5cb5b1461031a5780639a4575b91461033857600080fd5b806354c8a4f3146102d757806378a010b2146102ec57806379ba5097146102ff57600080fd5b806321df0da71161017657806321df0da714610221578063240028e81461026857806339077537146102b557600080fd5b806301ffc9a71461019d5780630a2fd493146101c5578063181f5a77146101e5575b600080fd5b6101b06101ab3660046129b1565b6104cd565b60405190151581526020015b60405180910390f35b6101d86101d3366004612a10565b6105b2565b6040516101bc9190612a8f565b6101d86040518060400160405280601b81526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e302d646576000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b6101b0610276366004612acf565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102c86102c3366004612aec565b610662565b604051905181526020016101bc565b6102ea6102e5366004612b74565b6107bd565b005b6102ea6102fa366004612be0565b610838565b6102ea6109ac565b6101b0610315366004612a10565b610aa9565b60005473ffffffffffffffffffffffffffffffffffffffff16610243565b61034b610346366004612c63565b610ac0565b6040516101bc9190612c9e565b610360610b67565b6040516101bc9190612cfe565b61038061037b366004612a10565b610b78565b6040516101bc919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610243565b6101d8610408366004612a10565b610c4d565b6102ea61041b366004612acf565b610c78565b610428610d53565b6040516101bc9190612d58565b610380610443366004612a10565b610e0b565b6102ea610456366004612ec0565b610edd565b6102ea610469366004612f05565b610ef5565b7f0000000000000000000000000000000000000000000000000000000000000000610243565b7f00000000000000000000000000000000000000000000000000000000000000006101b0565b6102ea6104c8366004612acf565b61137b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061056057507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105ac57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906105dd90612f47565b80601f016020809104026020016040519081016040528092919081815260200182805461060990612f47565b80156106565780601f1061062b57610100808354040283529160200191610656565b820191906000526020600020905b81548152906001019060200180831161063957829003601f168201915b50505050509050919050565b60408051602081019091526000815261068261067d83613045565b61138f565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561071357600080fd5b505af1158015610727573d6000803e3d6000fd5b5061073c925050506060830160408401612acf565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161079e91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6107c56115c0565b6108328484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061164392505050565b50505050565b6108406115c0565b61084983610aa9565b610890576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546108b790612f47565b80601f01602080910402602001604051908101604052809291908181526020018280546108e390612f47565b80156109305780601f1061090557610100808354040283529160200191610930565b820191906000526020600020905b81548152906001019060200180831161091357829003601f168201915b5050505067ffffffffffffffff861660009081526007602052604090209192505060040161095f83858361318a565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf82858560405161099e939291906132a4565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610887565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006105ac600567ffffffffffffffff84166117f9565b6040805180820190915260608082526020820152610ae5610ae083613308565b611814565b610af282606001356119de565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b4c8460200160208101906104089190612a10565b81526040805160208181019092526000815291015292915050565b6060610b736002611a81565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105ac90611a8e565b67ffffffffffffffff811660009081526007602052604090206005018054606091906105dd90612f47565b610c806115c0565b73ffffffffffffffffffffffffffffffffffffffff8116610ccd576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610d616005611a81565b90506000815167ffffffffffffffff811115610d7f57610d7f612d9a565b604051908082528060200260200182016040528015610da8578160200160208202803683370190505b50905060005b8251811015610e0457828181518110610dc957610dc96133aa565b6020026020010151828281518110610de357610de36133aa565b67ffffffffffffffff90921660209283029190910190910152600101610dae565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105ac90611a8e565b610ee56115c0565b610ef0838383611b40565b505050565b610efd6115c0565b60005b81811015610ef0576000838383818110610f1c57610f1c6133aa565b9050602002810190610f2e91906133d9565b610f3790613417565b9050610f4c8160800151826020015115611c2a565b610f5f8160a00151826020015115611c2a565b80602001511561125b578051610f819060059067ffffffffffffffff16611d63565b610fc65780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610887565b6040810151511580610fdb5750606081015151155b15611012576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906111f390826134cb565b506060820151600582019061120890826134cb565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061124e94939291906135e5565b60405180910390a1611372565b80516112739060059067ffffffffffffffff16611d6f565b6112b85780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610887565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906113216004830182612963565b61132f600583016000612963565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101610f00565b6113836115c0565b61138c81611d7b565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146114245760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610887565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f6919061367e565b1561152d576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61153a8160200151611e70565b600061154982602001516105b2565b905080516000148061156d575080805190602001208260a001518051906020012014155b156115aa578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108879190612a8f565b6115bc82602001518360600151611f96565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611641576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610887565b565b7f000000000000000000000000000000000000000000000000000000000000000061169a576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156117305760008382815181106116ba576116ba6133aa565b602002602001015190506116d8816002611fdd90919063ffffffff16565b156117275760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010161169d565b5060005b8151811015610ef0576000828281518110611751576117516133aa565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361179557506117f1565b6117a0600282611fff565b156117ef5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611734565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146118a95760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610887565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197b919061367e565b156119b2576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119bf8160400151612021565b6119cc81602001516120a0565b61138c816020015182606001516121ee565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611a6657600080fd5b505af1158015611a7a573d6000803e3d6000fd5b5050505050565b6060600061180d83612232565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611b1c82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611b0091906136ca565b85608001516fffffffffffffffffffffffffffffffff1661228d565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611b4983610aa9565b611b8b576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610887565b611b96826000611c2a565b67ffffffffffffffff83166000908152600760205260409020611bb990836122b7565b611bc4816000611c2a565b67ffffffffffffffff83166000908152600760205260409020611bea90600201826122b7565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611c1d939291906136dd565b60405180910390a1505050565b815115611cf15781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611c80575060408201516fffffffffffffffffffffffffffffffff16155b15611cb957816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108879190613760565b80156115bc576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611d2a575060208201516fffffffffffffffffffffffffffffffff1615155b156115bc57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108879190613760565b600061180d8383612459565b600061180d83836124a8565b3373ffffffffffffffffffffffffffffffffffffffff821603611dfa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610887565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611e7981610aa9565b611ebb576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610887565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015611f3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5e919061367e565b61138c576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610887565b67ffffffffffffffff821660009081526007602052604090206115bc90600201827f000000000000000000000000000000000000000000000000000000000000000061259b565b600061180d8373ffffffffffffffffffffffffffffffffffffffff84166124a8565b600061180d8373ffffffffffffffffffffffffffffffffffffffff8416612459565b7f00000000000000000000000000000000000000000000000000000000000000001561138c5761205260028261291e565b61138c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610887565b6120a981610aa9565b6120eb576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610887565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612164573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612188919061379c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461138c576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610887565b67ffffffffffffffff821660009081526007602052604090206115bc90827f000000000000000000000000000000000000000000000000000000000000000061259b565b60608160000180548060200260200160405190810160405280929190818152602001828054801561065657602002820191906000526020600020905b81548152602001906001019080831161226e5750505050509050919050565b60006122ac8561229d84866137b9565b6122a790876137d0565b61294d565b90505b949350505050565b81546000906122e090700100000000000000000000000000000000900463ffffffff16426136ca565b905080156123825760018301548354612328916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661228d565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546123a8916fffffffffffffffffffffffffffffffff908116911661294d565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611c1d908490613760565b60008181526001830160205260408120546124a0575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105ac565b5060006105ac565b600081815260018301602052604081205480156125915760006124cc6001836136ca565b85549091506000906124e0906001906136ca565b9050818114612545576000866000018281548110612500576125006133aa565b9060005260206000200154905080876000018481548110612523576125236133aa565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612556576125566137e3565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105ac565b60009150506105ac565b825474010000000000000000000000000000000000000000900460ff1615806125c2575081155b156125cc57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061261290700100000000000000000000000000000000900463ffffffff16426136ca565b905080156126d25781831115612654576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461268e9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661228d565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156127895773ffffffffffffffffffffffffffffffffffffffff8416612731576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610887565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610887565b8483101561289c5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906127cd90826136ca565b6127d7878a6136ca565b6127e191906137d0565b6127eb9190613812565b905073ffffffffffffffffffffffffffffffffffffffff8616612844576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610887565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610887565b6128a685846136ca565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561180d565b600081831061295c578161180d565b5090919050565b50805461296f90612f47565b6000825580601f1061297f575050565b601f01602090049060005260206000209081019061138c91905b808211156129ad5760008155600101612999565b5090565b6000602082840312156129c357600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461180d57600080fd5b803567ffffffffffffffff81168114612a0b57600080fd5b919050565b600060208284031215612a2257600080fd5b61180d826129f3565b6000815180845260005b81811015612a5157602081850181015186830182015201612a35565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061180d6020830184612a2b565b73ffffffffffffffffffffffffffffffffffffffff8116811461138c57600080fd5b8035612a0b81612aa2565b600060208284031215612ae157600080fd5b813561180d81612aa2565b600060208284031215612afe57600080fd5b813567ffffffffffffffff811115612b1557600080fd5b8201610100818503121561180d57600080fd5b60008083601f840112612b3a57600080fd5b50813567ffffffffffffffff811115612b5257600080fd5b6020830191508360208260051b8501011115612b6d57600080fd5b9250929050565b60008060008060408587031215612b8a57600080fd5b843567ffffffffffffffff80821115612ba257600080fd5b612bae88838901612b28565b90965094506020870135915080821115612bc757600080fd5b50612bd487828801612b28565b95989497509550505050565b600080600060408486031215612bf557600080fd5b612bfe846129f3565b9250602084013567ffffffffffffffff80821115612c1b57600080fd5b818601915086601f830112612c2f57600080fd5b813581811115612c3e57600080fd5b876020828501011115612c5057600080fd5b6020830194508093505050509250925092565b600060208284031215612c7557600080fd5b813567ffffffffffffffff811115612c8c57600080fd5b820160a0818503121561180d57600080fd5b602081526000825160406020840152612cba6060840182612a2b565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612cf58282612a2b565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d4c57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612d1a565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d4c57835167ffffffffffffffff1683529284019291840191600101612d74565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612ded57612ded612d9a565b60405290565b60405160c0810167ffffffffffffffff81118282101715612ded57612ded612d9a565b801515811461138c57600080fd5b8035612a0b81612e16565b80356fffffffffffffffffffffffffffffffff81168114612a0b57600080fd5b600060608284031215612e6157600080fd5b6040516060810181811067ffffffffffffffff82111715612e8457612e84612d9a565b6040529050808235612e9581612e16565b8152612ea360208401612e2f565b6020820152612eb460408401612e2f565b60408201525092915050565b600080600060e08486031215612ed557600080fd5b612ede846129f3565b9250612eed8560208601612e4f565b9150612efc8560808601612e4f565b90509250925092565b60008060208385031215612f1857600080fd5b823567ffffffffffffffff811115612f2f57600080fd5b612f3b85828601612b28565b90969095509350505050565b600181811c90821680612f5b57607f821691505b602082108103612f94577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f830112612fab57600080fd5b813567ffffffffffffffff80821115612fc657612fc6612d9a565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561300c5761300c612d9a565b8160405283815286602085880101111561302557600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561305857600080fd5b613060612dc9565b823567ffffffffffffffff8082111561307857600080fd5b61308436838701612f9a565b8352613092602086016129f3565b60208401526130a360408601612ac4565b6040840152606085013560608401526130be60808601612ac4565b608084015260a08501359150808211156130d757600080fd5b6130e336838701612f9a565b60a084015260c08501359150808211156130fc57600080fd5b61310836838701612f9a565b60c084015260e085013591508082111561312157600080fd5b5061312e36828601612f9a565b60e08301525092915050565b601f821115610ef0576000816000526020600020601f850160051c810160208610156131635750805b601f850160051c820191505b818110156131825782815560010161316f565b505050505050565b67ffffffffffffffff8311156131a2576131a2612d9a565b6131b6836131b08354612f47565b8361313a565b6000601f84116001811461320857600085156131d25750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a7a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156132575786850135825560209485019460019092019101613237565b5086821015613292577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006132b76040830186612a2b565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561331a57600080fd5b60405160a0810167ffffffffffffffff828210818311171561333e5761333e612d9a565b81604052843591508082111561335357600080fd5b5061336036828601612f9a565b82525061336f602084016129f3565b6020820152604083013561338281612aa2565b604082015260608381013590820152608083013561339f81612aa2565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261340d57600080fd5b9190910192915050565b6000610140823603121561342a57600080fd5b613432612df3565b61343b836129f3565b815261344960208401612e24565b6020820152604083013567ffffffffffffffff8082111561346957600080fd5b61347536838701612f9a565b6040840152606085013591508082111561348e57600080fd5b5061349b36828601612f9a565b6060830152506134ae3660808501612e4f565b60808201526134c03660e08501612e4f565b60a082015292915050565b815167ffffffffffffffff8111156134e5576134e5612d9a565b6134f9816134f38454612f47565b8461313a565b602080601f83116001811461354c57600084156135165750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613182565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156135995788860151825594840194600190910190840161357a565b50858210156135d557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261360981840187612a2b565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506136479050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612cf5565b60006020828403121561369057600080fd5b815161180d81612e16565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105ac576105ac61369b565b67ffffffffffffffff8416815260e0810161372960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526122af565b606081016105ac82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156137ae57600080fd5b815161180d81612aa2565b80820281158282048414176105ac576105ac61369b565b808201808211156105ac576105ac61369b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613848577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", +} + +var BurnMintTokenPoolABI = BurnMintTokenPoolMetaData.ABI + +var BurnMintTokenPoolBin = BurnMintTokenPoolMetaData.Bin + +func DeployBurnMintTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, rmnProxy common.Address, router common.Address) (common.Address, *types.Transaction, *BurnMintTokenPool, error) { + parsed, err := BurnMintTokenPoolMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnMintTokenPoolBin), backend, token, allowlist, rmnProxy, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &BurnMintTokenPool{address: address, abi: *parsed, BurnMintTokenPoolCaller: BurnMintTokenPoolCaller{contract: contract}, BurnMintTokenPoolTransactor: BurnMintTokenPoolTransactor{contract: contract}, BurnMintTokenPoolFilterer: BurnMintTokenPoolFilterer{contract: contract}}, nil +} + +type BurnMintTokenPool struct { + address common.Address + abi abi.ABI + BurnMintTokenPoolCaller + BurnMintTokenPoolTransactor + BurnMintTokenPoolFilterer +} + +type BurnMintTokenPoolCaller struct { + contract *bind.BoundContract +} + +type BurnMintTokenPoolTransactor struct { + contract *bind.BoundContract +} + +type BurnMintTokenPoolFilterer struct { + contract *bind.BoundContract +} + +type BurnMintTokenPoolSession struct { + Contract *BurnMintTokenPool + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type BurnMintTokenPoolCallerSession struct { + Contract *BurnMintTokenPoolCaller + CallOpts bind.CallOpts +} + +type BurnMintTokenPoolTransactorSession struct { + Contract *BurnMintTokenPoolTransactor + TransactOpts bind.TransactOpts +} + +type BurnMintTokenPoolRaw struct { + Contract *BurnMintTokenPool +} + +type BurnMintTokenPoolCallerRaw struct { + Contract *BurnMintTokenPoolCaller +} + +type BurnMintTokenPoolTransactorRaw struct { + Contract *BurnMintTokenPoolTransactor +} + +func NewBurnMintTokenPool(address common.Address, backend bind.ContractBackend) (*BurnMintTokenPool, error) { + abi, err := abi.JSON(strings.NewReader(BurnMintTokenPoolABI)) + if err != nil { + return nil, err + } + contract, err := bindBurnMintTokenPool(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &BurnMintTokenPool{address: address, abi: abi, BurnMintTokenPoolCaller: BurnMintTokenPoolCaller{contract: contract}, BurnMintTokenPoolTransactor: BurnMintTokenPoolTransactor{contract: contract}, BurnMintTokenPoolFilterer: BurnMintTokenPoolFilterer{contract: contract}}, nil +} + +func NewBurnMintTokenPoolCaller(address common.Address, caller bind.ContractCaller) (*BurnMintTokenPoolCaller, error) { + contract, err := bindBurnMintTokenPool(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolCaller{contract: contract}, nil +} + +func NewBurnMintTokenPoolTransactor(address common.Address, transactor bind.ContractTransactor) (*BurnMintTokenPoolTransactor, error) { + contract, err := bindBurnMintTokenPool(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolTransactor{contract: contract}, nil +} + +func NewBurnMintTokenPoolFilterer(address common.Address, filterer bind.ContractFilterer) (*BurnMintTokenPoolFilterer, error) { + contract, err := bindBurnMintTokenPool(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolFilterer{contract: contract}, nil +} + +func bindBurnMintTokenPool(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := BurnMintTokenPoolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnMintTokenPool.Contract.BurnMintTokenPoolCaller.contract.Call(opts, result, method, params...) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.BurnMintTokenPoolTransactor.contract.Transfer(opts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.BurnMintTokenPoolTransactor.contract.Transact(opts, method, params...) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnMintTokenPool.Contract.contract.Call(opts, result, method, params...) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.contract.Transfer(opts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.contract.Transact(opts, method, params...) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetAllowList() ([]common.Address, error) { + return _BurnMintTokenPool.Contract.GetAllowList(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetAllowList() ([]common.Address, error) { + return _BurnMintTokenPool.Contract.GetAllowList(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetAllowListEnabled() (bool, error) { + return _BurnMintTokenPool.Contract.GetAllowListEnabled(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetAllowListEnabled() (bool, error) { + return _BurnMintTokenPool.Contract.GetAllowListEnabled(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPool.Contract.GetCurrentInboundRateLimiterState(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPool.Contract.GetCurrentInboundRateLimiterState(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _BurnMintTokenPool.Contract.GetRemotePool(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _BurnMintTokenPool.Contract.GetRemotePool(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getRemoteToken", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _BurnMintTokenPool.Contract.GetRemoteToken(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _BurnMintTokenPool.Contract.GetRemoteToken(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetRmnProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getRmnProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetRmnProxy() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetRmnProxy(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetRmnProxy() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetRmnProxy(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetRouter() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetRouter(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetRouter() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetRouter(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetSupportedChains() ([]uint64, error) { + return _BurnMintTokenPool.Contract.GetSupportedChains(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetSupportedChains() ([]uint64, error) { + return _BurnMintTokenPool.Contract.GetSupportedChains(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetToken() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetToken(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetToken() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetToken(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _BurnMintTokenPool.Contract.IsSupportedChain(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _BurnMintTokenPool.Contract.IsSupportedChain(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "isSupportedToken", token) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) IsSupportedToken(token common.Address) (bool, error) { + return _BurnMintTokenPool.Contract.IsSupportedToken(&_BurnMintTokenPool.CallOpts, token) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) IsSupportedToken(token common.Address) (bool, error) { + return _BurnMintTokenPool.Contract.IsSupportedToken(&_BurnMintTokenPool.CallOpts, token) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) Owner() (common.Address, error) { + return _BurnMintTokenPool.Contract.Owner(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) Owner() (common.Address, error) { + return _BurnMintTokenPool.Contract.Owner(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnMintTokenPool.Contract.SupportsInterface(&_BurnMintTokenPool.CallOpts, interfaceId) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnMintTokenPool.Contract.SupportsInterface(&_BurnMintTokenPool.CallOpts, interfaceId) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) TypeAndVersion() (string, error) { + return _BurnMintTokenPool.Contract.TypeAndVersion(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) TypeAndVersion() (string, error) { + return _BurnMintTokenPool.Contract.TypeAndVersion(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "acceptOwnership") +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.AcceptOwnership(&_BurnMintTokenPool.TransactOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.AcceptOwnership(&_BurnMintTokenPool.TransactOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnMintTokenPool.TransactOpts, removes, adds) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnMintTokenPool.TransactOpts, removes, adds) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyChainUpdates(&_BurnMintTokenPool.TransactOpts, chains) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyChainUpdates(&_BurnMintTokenPool.TransactOpts, chains) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "lockOrBurn", lockOrBurnIn) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.LockOrBurn(&_BurnMintTokenPool.TransactOpts, lockOrBurnIn) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.LockOrBurn(&_BurnMintTokenPool.TransactOpts, lockOrBurnIn) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "releaseOrMint", releaseOrMintIn) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ReleaseOrMint(&_BurnMintTokenPool.TransactOpts, releaseOrMintIn) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ReleaseOrMint(&_BurnMintTokenPool.TransactOpts, releaseOrMintIn) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetRemotePool(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetRemotePool(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "setRouter", newRouter) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetRouter(&_BurnMintTokenPool.TransactOpts, newRouter) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetRouter(&_BurnMintTokenPool.TransactOpts, newRouter) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "transferOwnership", to) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.TransferOwnership(&_BurnMintTokenPool.TransactOpts, to) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.TransferOwnership(&_BurnMintTokenPool.TransactOpts, to) +} + +type BurnMintTokenPoolAllowListAddIterator struct { + Event *BurnMintTokenPoolAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAllowListAddIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*BurnMintTokenPoolAllowListAddIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAllowListAddIterator{contract: _BurnMintTokenPool.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAllowListAdd) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseAllowListAdd(log types.Log) (*BurnMintTokenPoolAllowListAdd, error) { + event := new(BurnMintTokenPoolAllowListAdd) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAllowListRemoveIterator struct { + Event *BurnMintTokenPoolAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*BurnMintTokenPoolAllowListRemoveIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAllowListRemoveIterator{contract: _BurnMintTokenPool.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAllowListRemove) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseAllowListRemove(log types.Log) (*BurnMintTokenPoolAllowListRemove, error) { + event := new(BurnMintTokenPoolAllowListRemove) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolBurnedIterator struct { + Event *BurnMintTokenPoolBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolBurnedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolBurnedIterator{contract: _BurnMintTokenPool.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolBurned) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseBurned(log types.Log) (*BurnMintTokenPoolBurned, error) { + event := new(BurnMintTokenPoolBurned) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolChainAddedIterator struct { + Event *BurnMintTokenPoolChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolChainAddedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolChainAdded struct { + RemoteChainSelector uint64 + RemoteToken []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterChainAdded(opts *bind.FilterOpts) (*BurnMintTokenPoolChainAddedIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolChainAddedIterator{contract: _BurnMintTokenPool.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolChainAdded) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolChainAdded) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseChainAdded(log types.Log) (*BurnMintTokenPoolChainAdded, error) { + event := new(BurnMintTokenPoolChainAdded) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolChainConfiguredIterator struct { + Event *BurnMintTokenPoolChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*BurnMintTokenPoolChainConfiguredIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolChainConfiguredIterator{contract: _BurnMintTokenPool.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolChainConfigured) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolChainConfigured) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseChainConfigured(log types.Log) (*BurnMintTokenPoolChainConfigured, error) { + event := new(BurnMintTokenPoolChainConfigured) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolChainRemovedIterator struct { + Event *BurnMintTokenPoolChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolChainRemovedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*BurnMintTokenPoolChainRemovedIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolChainRemovedIterator{contract: _BurnMintTokenPool.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolChainRemoved) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolChainRemoved) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseChainRemoved(log types.Log) (*BurnMintTokenPoolChainRemoved, error) { + event := new(BurnMintTokenPoolChainRemoved) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolConfigChangedIterator struct { + Event *BurnMintTokenPoolConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolConfigChangedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolConfigChanged struct { + Config RateLimiterConfig + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*BurnMintTokenPoolConfigChangedIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolConfigChangedIterator{contract: _BurnMintTokenPool.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolConfigChanged) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolConfigChanged) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseConfigChanged(log types.Log) (*BurnMintTokenPoolConfigChanged, error) { + event := new(BurnMintTokenPoolConfigChanged) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolLockedIterator struct { + Event *BurnMintTokenPoolLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolLockedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolLockedIterator{contract: _BurnMintTokenPool.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolLocked) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseLocked(log types.Log) (*BurnMintTokenPoolLocked, error) { + event := new(BurnMintTokenPoolLocked) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolMintedIterator struct { + Event *BurnMintTokenPoolMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolMintedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolMintedIterator{contract: _BurnMintTokenPool.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolMinted) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseMinted(log types.Log) (*BurnMintTokenPoolMinted, error) { + event := new(BurnMintTokenPoolMinted) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolOwnershipTransferRequestedIterator struct { + Event *BurnMintTokenPoolOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolOwnershipTransferRequestedIterator{contract: _BurnMintTokenPool.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolOwnershipTransferRequested) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseOwnershipTransferRequested(log types.Log) (*BurnMintTokenPoolOwnershipTransferRequested, error) { + event := new(BurnMintTokenPoolOwnershipTransferRequested) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolOwnershipTransferredIterator struct { + Event *BurnMintTokenPoolOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolOwnershipTransferredIterator{contract: _BurnMintTokenPool.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolOwnershipTransferred) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseOwnershipTransferred(log types.Log) (*BurnMintTokenPoolOwnershipTransferred, error) { + event := new(BurnMintTokenPoolOwnershipTransferred) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolReleasedIterator struct { + Event *BurnMintTokenPoolReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolReleasedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolReleasedIterator{contract: _BurnMintTokenPool.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolReleased) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseReleased(log types.Log) (*BurnMintTokenPoolReleased, error) { + event := new(BurnMintTokenPoolReleased) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolRemotePoolSetIterator struct { + Event *BurnMintTokenPoolRemotePoolSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolRemotePoolSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolRemotePoolSetIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolRemotePoolSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolRemotePoolSet struct { + RemoteChainSelector uint64 + PreviousPoolAddress []byte + RemotePoolAddress []byte + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnMintTokenPoolRemotePoolSetIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolRemotePoolSetIterator{contract: _BurnMintTokenPool.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolRemotePoolSet) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseRemotePoolSet(log types.Log) (*BurnMintTokenPoolRemotePoolSet, error) { + event := new(BurnMintTokenPoolRemotePoolSet) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolRouterUpdatedIterator struct { + Event *BurnMintTokenPoolRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*BurnMintTokenPoolRouterUpdatedIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolRouterUpdatedIterator{contract: _BurnMintTokenPool.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolRouterUpdated) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseRouterUpdated(log types.Log) (*BurnMintTokenPoolRouterUpdated, error) { + event := new(BurnMintTokenPoolRouterUpdated) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolTokensConsumedIterator struct { + Event *BurnMintTokenPoolTokensConsumed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolTokensConsumedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolTokensConsumedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolTokensConsumedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolTokensConsumed struct { + Tokens *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterTokensConsumed(opts *bind.FilterOpts) (*BurnMintTokenPoolTokensConsumedIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolTokensConsumedIterator{contract: _BurnMintTokenPool.contract, event: "TokensConsumed", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolTokensConsumed) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolTokensConsumed) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseTokensConsumed(log types.Log) (*BurnMintTokenPoolTokensConsumed, error) { + event := new(BurnMintTokenPoolTokensConsumed) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPool) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _BurnMintTokenPool.abi.Events["AllowListAdd"].ID: + return _BurnMintTokenPool.ParseAllowListAdd(log) + case _BurnMintTokenPool.abi.Events["AllowListRemove"].ID: + return _BurnMintTokenPool.ParseAllowListRemove(log) + case _BurnMintTokenPool.abi.Events["Burned"].ID: + return _BurnMintTokenPool.ParseBurned(log) + case _BurnMintTokenPool.abi.Events["ChainAdded"].ID: + return _BurnMintTokenPool.ParseChainAdded(log) + case _BurnMintTokenPool.abi.Events["ChainConfigured"].ID: + return _BurnMintTokenPool.ParseChainConfigured(log) + case _BurnMintTokenPool.abi.Events["ChainRemoved"].ID: + return _BurnMintTokenPool.ParseChainRemoved(log) + case _BurnMintTokenPool.abi.Events["ConfigChanged"].ID: + return _BurnMintTokenPool.ParseConfigChanged(log) + case _BurnMintTokenPool.abi.Events["Locked"].ID: + return _BurnMintTokenPool.ParseLocked(log) + case _BurnMintTokenPool.abi.Events["Minted"].ID: + return _BurnMintTokenPool.ParseMinted(log) + case _BurnMintTokenPool.abi.Events["OwnershipTransferRequested"].ID: + return _BurnMintTokenPool.ParseOwnershipTransferRequested(log) + case _BurnMintTokenPool.abi.Events["OwnershipTransferred"].ID: + return _BurnMintTokenPool.ParseOwnershipTransferred(log) + case _BurnMintTokenPool.abi.Events["Released"].ID: + return _BurnMintTokenPool.ParseReleased(log) + case _BurnMintTokenPool.abi.Events["RemotePoolSet"].ID: + return _BurnMintTokenPool.ParseRemotePoolSet(log) + case _BurnMintTokenPool.abi.Events["RouterUpdated"].ID: + return _BurnMintTokenPool.ParseRouterUpdated(log) + case _BurnMintTokenPool.abi.Events["TokensConsumed"].ID: + return _BurnMintTokenPool.ParseTokensConsumed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (BurnMintTokenPoolAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (BurnMintTokenPoolAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (BurnMintTokenPoolBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (BurnMintTokenPoolChainAdded) Topic() common.Hash { + return common.HexToHash("0x8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2") +} + +func (BurnMintTokenPoolChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (BurnMintTokenPoolChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (BurnMintTokenPoolConfigChanged) Topic() common.Hash { + return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") +} + +func (BurnMintTokenPoolLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (BurnMintTokenPoolMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (BurnMintTokenPoolOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (BurnMintTokenPoolOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (BurnMintTokenPoolReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (BurnMintTokenPoolRemotePoolSet) Topic() common.Hash { + return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +} + +func (BurnMintTokenPoolRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (BurnMintTokenPoolTokensConsumed) Topic() common.Hash { + return common.HexToHash("0x1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a") +} + +func (_BurnMintTokenPool *BurnMintTokenPool) Address() common.Address { + return _BurnMintTokenPool.address +} + +type BurnMintTokenPoolInterface interface { + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRmnProxy(opts *bind.CallOpts) (common.Address, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*BurnMintTokenPoolAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*BurnMintTokenPoolAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*BurnMintTokenPoolAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*BurnMintTokenPoolAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*BurnMintTokenPoolBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*BurnMintTokenPoolChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*BurnMintTokenPoolChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*BurnMintTokenPoolChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*BurnMintTokenPoolChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*BurnMintTokenPoolChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*BurnMintTokenPoolChainRemoved, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*BurnMintTokenPoolConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*BurnMintTokenPoolConfigChanged, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*BurnMintTokenPoolLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*BurnMintTokenPoolMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*BurnMintTokenPoolOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*BurnMintTokenPoolOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*BurnMintTokenPoolReleased, error) + + FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnMintTokenPoolRemotePoolSetIterator, error) + + WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolSet(log types.Log) (*BurnMintTokenPoolRemotePoolSet, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*BurnMintTokenPoolRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*BurnMintTokenPoolRouterUpdated, error) + + FilterTokensConsumed(opts *bind.FilterOpts) (*BurnMintTokenPoolTokensConsumedIterator, error) + + WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolTokensConsumed) (event.Subscription, error) + + ParseTokensConsumed(log types.Log) (*BurnMintTokenPoolTokensConsumed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_2_0/burn_mint_token_pool_1_2_0.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_2_0/burn_mint_token_pool_1_2_0.go new file mode 100644 index 0000000000..d11a7db6e6 --- /dev/null +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_2_0/burn_mint_token_pool_1_2_0.go @@ -0,0 +1,2544 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package burn_mint_token_pool_1_2_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolRampUpdate struct { + Ramp common.Address + Allowed bool + RateLimiterConfig RateLimiterConfig +} + +var BurnMintTokenPoolMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"NonExistentRamp\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermissionsError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"RampAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"OnRampRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"onRamps\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"offRamps\",\"type\":\"tuple[]\"}],\"name\":\"applyRampUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"currentOffRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"currentOnRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOffRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOnRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"isOnRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"releaseOrMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOffRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOnRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b5060405162002f3338038062002f3383398101604081905262000034916200051d565b82828233806000816200008e5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c157620000c18162000133565b5050506001600160a01b038316620000ec576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808416608052811660a052815115801560c0526200012757604080516000815260208101909152620001279083620001de565b5050505050506200068e565b336001600160a01b038216036200018d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000085565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620001ff576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002945760008382815181106200022357620002236200061a565b602090810291909101015190506200023d6002826200034f565b1562000280576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506200028c8162000646565b905062000202565b5060005b81518110156200034a576000828281518110620002b957620002b96200061a565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002e5575062000337565b620002f26002826200036f565b1562000335576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b620003428162000646565b905062000298565b505050565b600062000366836001600160a01b03841662000386565b90505b92915050565b600062000366836001600160a01b0384166200048a565b600081815260018301602052604081205480156200047f576000620003ad60018362000662565b8554909150600090620003c39060019062000662565b90508181146200042f576000866000018281548110620003e757620003e76200061a565b90600052602060002001549050808760000184815481106200040d576200040d6200061a565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000443576200044362000678565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000369565b600091505062000369565b6000818152600183016020526040812054620004d35750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000369565b50600062000369565b6001600160a01b0381168114620004f257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200051881620004dc565b919050565b6000806000606084860312156200053357600080fd5b83516200054081620004dc565b602085810151919450906001600160401b03808211156200056057600080fd5b818701915087601f8301126200057557600080fd5b8151818111156200058a576200058a620004f5565b8060051b604051601f19603f83011681018181108582111715620005b257620005b2620004f5565b60405291825284820192508381018501918a831115620005d157600080fd5b938501935b82851015620005fa57620005ea856200050b565b84529385019392850192620005d6565b80975050505050505062000611604085016200050b565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200065b576200065b62000630565b5060010190565b8181038181111562000369576200036962000630565b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161283d620006f6600039600081816103c301528181610a320152610e71015260008181610249015281816107d50152610ab60152600081816102020152818161092d015281816112b1015281816112f8015261134b015261283d6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80638627fad6116100d8578063a7cd63b71161008c578063d612b94511610066578063d612b945146103ae578063e0351e13146103c1578063f2fde38b146103e757600080fd5b8063a7cd63b714610380578063b3a3fb4114610388578063c49907b51461039b57600080fd5b80638da5cb5b116100bd5780638da5cb5b146103475780639687544514610365578063a40e69c71461037857600080fd5b80638627fad61461031f578063873813141461033257600080fd5b806354c8a4f31161012f5780637448b3c7116101145780637448b3c7146102955780637787e7ab146102a857806379ba50971461031757600080fd5b806354c8a4f31461026d5780636f32b8721461028257600080fd5b80631d7a74a0116101605780631d7a74a0146101ed57806321df0da7146102005780635246492f1461024757600080fd5b806301ffc9a71461017c578063181f5a77146101a4575b600080fd5b61018f61018a366004612000565b6103fa565b60405190151581526020015b60405180910390f35b6101e06040518060400160405280601781526020017f4275726e4d696e74546f6b656e506f6f6c20312e322e3000000000000000000081525081565b60405161019b91906120a6565b61018f6101fb3660046120e2565b610493565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b7f0000000000000000000000000000000000000000000000000000000000000000610222565b61028061027b366004612149565b6104a0565b005b61018f6102903660046120e2565b61051b565b6102806102a336600461228c565b610528565b6102bb6102b63660046120e2565b6105f8565b60405161019b919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6102806106d6565b61028061032d366004612383565b6107d3565b61033a6109dd565b60405161019b9190612412565b60005473ffffffffffffffffffffffffffffffffffffffff16610222565b6101e06103733660046124ae565b6109ee565b61033a610bdd565b61033a610be9565b6102bb6103963660046120e2565b610bf5565b6102806103a9366004612591565b610cd3565b6102806103bc36600461228c565b610ce7565b7f000000000000000000000000000000000000000000000000000000000000000061018f565b6102806103f53660046120e2565b610da6565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f317fa33400000000000000000000000000000000000000000000000000000000148061048d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b600061048d600783610dba565b6104a8610dec565b61051584848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250610e6f92505050565b50505050565b600061048d600483610dba565b610530610dec565b6105398261051b565b61058c576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526006602052604090206105bb908261103a565b7f578db78e348076074dbff64a94073a83e9a65aa6766b8c75fdc89282b0e30ed682826040516105ec9291906125f1565b60405180910390a15050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260066020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261048d906111e9565b60015473ffffffffffffffffffffffffffffffffffffffff163314610757576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610583565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561083e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108629190612649565b15610899576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108a233610493565b6108d8576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108e18361129b565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561097157600080fd5b505af1158015610985573d6000803e3d6000fd5b505060405185815273ffffffffffffffffffffffffffffffffffffffff871692503391507f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f09060200160405180910390a35050505050565b60606109e960046112d5565b905090565b60606109f93361051b565b610a2f576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b877f00000000000000000000000000000000000000000000000000000000000000008015610a655750610a63600282610dba565b155b15610ab4576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610583565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b439190612649565b15610b7a576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b83866112e2565b610b8c8661131c565b60405186815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a25050604080516020810190915260008152979650505050505050565b60606109e960076112d5565b60606109e960026112d5565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260096020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261048d906111e9565b610cdb610dec565b610515848484846113bf565b610cef610dec565b610cf882610493565b610d46576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610583565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600960205260409020610d75908261103a565b7fb3ba339cfbb8ef80d7a29ce5493051cb90e64fcfa85d7124efc1adfa4c68399f82826040516105ec9291906125f1565b610dae610dec565b610db781611968565b50565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610583565b565b7f0000000000000000000000000000000000000000000000000000000000000000610ec6576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015610f64576000838281518110610ee657610ee6612666565b60200260200101519050610f04816002611a5d90919063ffffffff16565b15610f535760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50610f5d816126c4565b9050610ec9565b5060005b8151811015611035576000828281518110610f8557610f85612666565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fc95750611025565b610fd4600282611a7f565b156110235760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b61102e816126c4565b9050610f68565b505050565b815460009061106390700100000000000000000000000000000000900463ffffffff16426126fc565b9050801561110557600183015483546110ab916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416611aa1565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461112b916fffffffffffffffffffffffffffffffff9081169116611ac9565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906111dc90849061270f565b60405180910390a1505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261127782606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261125b91906126fc565b85608001516fffffffffffffffffffffffffffffffff16611aa1565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b336000908152600960205260409020610db790827f0000000000000000000000000000000000000000000000000000000000000000611adf565b60606000610de583611e62565b336000908152600660205260409020610db790827f0000000000000000000000000000000000000000000000000000000000000000611adf565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b1580156113a457600080fd5b505af11580156113b8573d6000803e3d6000fd5b5050505050565b6113c7610dec565b60005b838110156116e45760008585838181106113e6576113e6612666565b905060a002018036038101906113fc919061274b565b90508060200151156115d457805161141690600490611a7f565b15611587576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526006909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f0b594bb0555ff7b252e0c789ccc9d8903fec294172064308727d570505cee1ac9261157a92916125f1565b60405180910390a16116d3565b80516040517fd3eb6bc500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610583565b80516115e290600490611a5d565b1561168657805173ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517f7fd064821314ad863a0714a3f1229375ace6b6427ed5544b7b2ba1c47b1b52949161157a9173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b80516040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610583565b506116dd816126c4565b90506113ca565b5060005b818110156113b857600083838381811061170457611704612666565b905060a0020180360381019061171a919061274b565b90508060200151156118a557805161173490600790611a7f565b15611587576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526009909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f395b7374909d2b54e5796f53c898ebf41d767c86c78ea86519acf2b805852d889261189892916125f1565b60405180910390a1611957565b80516118b390600790611a5d565b1561168657805173ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517fcf91daec21e3510e2f2aea4b09d08c235d5c6844980be709f282ef591dbf420c916118989173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b50611961816126c4565b90506116e8565b3373ffffffffffffffffffffffffffffffffffffffff8216036119e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610583565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000610de58373ffffffffffffffffffffffffffffffffffffffff8416611ebe565b6000610de58373ffffffffffffffffffffffffffffffffffffffff8416611fb1565b6000611ac085611ab1848661279c565b611abb90876127b3565b611ac9565b95945050505050565b6000818310611ad85781610de5565b5090919050565b825474010000000000000000000000000000000000000000900460ff161580611b06575081155b15611b1057505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090611b5690700100000000000000000000000000000000900463ffffffff16426126fc565b90508015611c165781831115611b98576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154611bd29083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16611aa1565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015611ccd5773ffffffffffffffffffffffffffffffffffffffff8416611c75576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610583565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610583565b84831015611de05760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290611d1190826126fc565b611d1b878a6126fc565b611d2591906127b3565b611d2f91906127c6565b905073ffffffffffffffffffffffffffffffffffffffff8616611d88576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610583565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610583565b611dea85846126fc565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611eb257602002820191906000526020600020905b815481526020019060010190808311611e9e575b50505050509050919050565b60008181526001830160205260408120548015611fa7576000611ee26001836126fc565b8554909150600090611ef6906001906126fc565b9050818114611f5b576000866000018281548110611f1657611f16612666565b9060005260206000200154905080876000018481548110611f3957611f39612666565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611f6c57611f6c612801565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061048d565b600091505061048d565b6000818152600183016020526040812054611ff85750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561048d565b50600061048d565b60006020828403121561201257600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610de557600080fd5b6000815180845260005b818110156120685760208185018101518683018201520161204c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610de56020830184612042565b803573ffffffffffffffffffffffffffffffffffffffff811681146120dd57600080fd5b919050565b6000602082840312156120f457600080fd5b610de5826120b9565b60008083601f84011261210f57600080fd5b50813567ffffffffffffffff81111561212757600080fd5b6020830191508360208260051b850101111561214257600080fd5b9250929050565b6000806000806040858703121561215f57600080fd5b843567ffffffffffffffff8082111561217757600080fd5b612183888389016120fd565b9096509450602087013591508082111561219c57600080fd5b506121a9878288016120fd565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612207576122076121b5565b60405290565b8015158114610db757600080fd5b80356fffffffffffffffffffffffffffffffff811681146120dd57600080fd5b60006060828403121561224d57600080fd5b6122556121e4565b905081356122628161220d565b81526122706020830161221b565b60208201526122816040830161221b565b604082015292915050565b6000806080838503121561229f57600080fd5b6122a8836120b9565b91506122b7846020850161223b565b90509250929050565b600082601f8301126122d157600080fd5b813567ffffffffffffffff808211156122ec576122ec6121b5565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612332576123326121b5565b8160405283815286602085880101111561234b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803567ffffffffffffffff811681146120dd57600080fd5b600080600080600060a0868803121561239b57600080fd5b853567ffffffffffffffff808211156123b357600080fd5b6123bf89838a016122c0565b96506123cd602089016120b9565b9550604088013594506123e26060890161236b565b935060808801359150808211156123f857600080fd5b50612405888289016122c0565b9150509295509295909350565b6020808252825182820181905260009190848201906040850190845b8181101561246057835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161242e565b50909695505050505050565b60008083601f84011261247e57600080fd5b50813567ffffffffffffffff81111561249657600080fd5b60208301915083602082850101111561214257600080fd5b600080600080600080600060a0888a0312156124c957600080fd5b6124d2886120b9565b9650602088013567ffffffffffffffff808211156124ef57600080fd5b6124fb8b838c0161246c565b909850965060408a0135955086915061251660608b0161236b565b945060808a013591508082111561252c57600080fd5b506125398a828b0161246c565b989b979a50959850939692959293505050565b60008083601f84011261255e57600080fd5b50813567ffffffffffffffff81111561257657600080fd5b60208301915083602060a08302850101111561214257600080fd5b600080600080604085870312156125a757600080fd5b843567ffffffffffffffff808211156125bf57600080fd5b6125cb8883890161254c565b909650945060208701359150808211156125e457600080fd5b506121a98782880161254c565b73ffffffffffffffffffffffffffffffffffffffff8316815260808101610de560208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561265b57600080fd5b8151610de58161220d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036126f5576126f5612695565b5060010190565b8181038181111561048d5761048d612695565b6060810161048d82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060a0828403121561275d57600080fd5b6127656121e4565b61276e836120b9565b8152602083013561277e8161220d565b6020820152612790846040850161223b565b60408201529392505050565b808202811582820484141761048d5761048d612695565b8082018082111561048d5761048d612695565b6000826127fc577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", +} + +var BurnMintTokenPoolABI = BurnMintTokenPoolMetaData.ABI + +var BurnMintTokenPoolBin = BurnMintTokenPoolMetaData.Bin + +func DeployBurnMintTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, armProxy common.Address) (common.Address, *types.Transaction, *BurnMintTokenPool, error) { + parsed, err := BurnMintTokenPoolMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnMintTokenPoolBin), backend, token, allowlist, armProxy) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &BurnMintTokenPool{address: address, abi: *parsed, BurnMintTokenPoolCaller: BurnMintTokenPoolCaller{contract: contract}, BurnMintTokenPoolTransactor: BurnMintTokenPoolTransactor{contract: contract}, BurnMintTokenPoolFilterer: BurnMintTokenPoolFilterer{contract: contract}}, nil +} + +type BurnMintTokenPool struct { + address common.Address + abi abi.ABI + BurnMintTokenPoolCaller + BurnMintTokenPoolTransactor + BurnMintTokenPoolFilterer +} + +type BurnMintTokenPoolCaller struct { + contract *bind.BoundContract +} + +type BurnMintTokenPoolTransactor struct { + contract *bind.BoundContract +} + +type BurnMintTokenPoolFilterer struct { + contract *bind.BoundContract +} + +type BurnMintTokenPoolSession struct { + Contract *BurnMintTokenPool + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type BurnMintTokenPoolCallerSession struct { + Contract *BurnMintTokenPoolCaller + CallOpts bind.CallOpts +} + +type BurnMintTokenPoolTransactorSession struct { + Contract *BurnMintTokenPoolTransactor + TransactOpts bind.TransactOpts +} + +type BurnMintTokenPoolRaw struct { + Contract *BurnMintTokenPool +} + +type BurnMintTokenPoolCallerRaw struct { + Contract *BurnMintTokenPoolCaller +} + +type BurnMintTokenPoolTransactorRaw struct { + Contract *BurnMintTokenPoolTransactor +} + +func NewBurnMintTokenPool(address common.Address, backend bind.ContractBackend) (*BurnMintTokenPool, error) { + abi, err := abi.JSON(strings.NewReader(BurnMintTokenPoolABI)) + if err != nil { + return nil, err + } + contract, err := bindBurnMintTokenPool(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &BurnMintTokenPool{address: address, abi: abi, BurnMintTokenPoolCaller: BurnMintTokenPoolCaller{contract: contract}, BurnMintTokenPoolTransactor: BurnMintTokenPoolTransactor{contract: contract}, BurnMintTokenPoolFilterer: BurnMintTokenPoolFilterer{contract: contract}}, nil +} + +func NewBurnMintTokenPoolCaller(address common.Address, caller bind.ContractCaller) (*BurnMintTokenPoolCaller, error) { + contract, err := bindBurnMintTokenPool(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolCaller{contract: contract}, nil +} + +func NewBurnMintTokenPoolTransactor(address common.Address, transactor bind.ContractTransactor) (*BurnMintTokenPoolTransactor, error) { + contract, err := bindBurnMintTokenPool(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolTransactor{contract: contract}, nil +} + +func NewBurnMintTokenPoolFilterer(address common.Address, filterer bind.ContractFilterer) (*BurnMintTokenPoolFilterer, error) { + contract, err := bindBurnMintTokenPool(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolFilterer{contract: contract}, nil +} + +func bindBurnMintTokenPool(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := BurnMintTokenPoolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnMintTokenPool.Contract.BurnMintTokenPoolCaller.contract.Call(opts, result, method, params...) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.BurnMintTokenPoolTransactor.contract.Transfer(opts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.BurnMintTokenPoolTransactor.contract.Transact(opts, method, params...) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnMintTokenPool.Contract.contract.Call(opts, result, method, params...) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.contract.Transfer(opts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.contract.Transact(opts, method, params...) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) CurrentOffRampRateLimiterState(opts *bind.CallOpts, offRamp common.Address) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "currentOffRampRateLimiterState", offRamp) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) CurrentOffRampRateLimiterState(offRamp common.Address) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPool.Contract.CurrentOffRampRateLimiterState(&_BurnMintTokenPool.CallOpts, offRamp) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) CurrentOffRampRateLimiterState(offRamp common.Address) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPool.Contract.CurrentOffRampRateLimiterState(&_BurnMintTokenPool.CallOpts, offRamp) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) CurrentOnRampRateLimiterState(opts *bind.CallOpts, onRamp common.Address) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "currentOnRampRateLimiterState", onRamp) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) CurrentOnRampRateLimiterState(onRamp common.Address) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPool.Contract.CurrentOnRampRateLimiterState(&_BurnMintTokenPool.CallOpts, onRamp) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) CurrentOnRampRateLimiterState(onRamp common.Address) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPool.Contract.CurrentOnRampRateLimiterState(&_BurnMintTokenPool.CallOpts, onRamp) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetAllowList() ([]common.Address, error) { + return _BurnMintTokenPool.Contract.GetAllowList(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetAllowList() ([]common.Address, error) { + return _BurnMintTokenPool.Contract.GetAllowList(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetAllowListEnabled() (bool, error) { + return _BurnMintTokenPool.Contract.GetAllowListEnabled(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetAllowListEnabled() (bool, error) { + return _BurnMintTokenPool.Contract.GetAllowListEnabled(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetArmProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getArmProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetArmProxy() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetArmProxy(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetArmProxy() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetArmProxy(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetOffRamps(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getOffRamps") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetOffRamps() ([]common.Address, error) { + return _BurnMintTokenPool.Contract.GetOffRamps(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetOffRamps() ([]common.Address, error) { + return _BurnMintTokenPool.Contract.GetOffRamps(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetOnRamps(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getOnRamps") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetOnRamps() ([]common.Address, error) { + return _BurnMintTokenPool.Contract.GetOnRamps(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetOnRamps() ([]common.Address, error) { + return _BurnMintTokenPool.Contract.GetOnRamps(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetToken() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetToken(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetToken() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetToken(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) IsOffRamp(opts *bind.CallOpts, offRamp common.Address) (bool, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "isOffRamp", offRamp) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) IsOffRamp(offRamp common.Address) (bool, error) { + return _BurnMintTokenPool.Contract.IsOffRamp(&_BurnMintTokenPool.CallOpts, offRamp) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) IsOffRamp(offRamp common.Address) (bool, error) { + return _BurnMintTokenPool.Contract.IsOffRamp(&_BurnMintTokenPool.CallOpts, offRamp) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) IsOnRamp(opts *bind.CallOpts, onRamp common.Address) (bool, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "isOnRamp", onRamp) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) IsOnRamp(onRamp common.Address) (bool, error) { + return _BurnMintTokenPool.Contract.IsOnRamp(&_BurnMintTokenPool.CallOpts, onRamp) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) IsOnRamp(onRamp common.Address) (bool, error) { + return _BurnMintTokenPool.Contract.IsOnRamp(&_BurnMintTokenPool.CallOpts, onRamp) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) Owner() (common.Address, error) { + return _BurnMintTokenPool.Contract.Owner(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) Owner() (common.Address, error) { + return _BurnMintTokenPool.Contract.Owner(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnMintTokenPool.Contract.SupportsInterface(&_BurnMintTokenPool.CallOpts, interfaceId) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnMintTokenPool.Contract.SupportsInterface(&_BurnMintTokenPool.CallOpts, interfaceId) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) TypeAndVersion() (string, error) { + return _BurnMintTokenPool.Contract.TypeAndVersion(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) TypeAndVersion() (string, error) { + return _BurnMintTokenPool.Contract.TypeAndVersion(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "acceptOwnership") +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.AcceptOwnership(&_BurnMintTokenPool.TransactOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.AcceptOwnership(&_BurnMintTokenPool.TransactOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnMintTokenPool.TransactOpts, removes, adds) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnMintTokenPool.TransactOpts, removes, adds) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) ApplyRampUpdates(opts *bind.TransactOpts, onRamps []TokenPoolRampUpdate, offRamps []TokenPoolRampUpdate) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "applyRampUpdates", onRamps, offRamps) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) ApplyRampUpdates(onRamps []TokenPoolRampUpdate, offRamps []TokenPoolRampUpdate) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyRampUpdates(&_BurnMintTokenPool.TransactOpts, onRamps, offRamps) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ApplyRampUpdates(onRamps []TokenPoolRampUpdate, offRamps []TokenPoolRampUpdate) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyRampUpdates(&_BurnMintTokenPool.TransactOpts, onRamps, offRamps) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, originalSender common.Address, arg1 []byte, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "lockOrBurn", originalSender, arg1, amount, arg3, arg4) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) LockOrBurn(originalSender common.Address, arg1 []byte, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.LockOrBurn(&_BurnMintTokenPool.TransactOpts, originalSender, arg1, amount, arg3, arg4) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) LockOrBurn(originalSender common.Address, arg1 []byte, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.LockOrBurn(&_BurnMintTokenPool.TransactOpts, originalSender, arg1, amount, arg3, arg4) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) ReleaseOrMint(opts *bind.TransactOpts, arg0 []byte, receiver common.Address, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "releaseOrMint", arg0, receiver, amount, arg3, arg4) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) ReleaseOrMint(arg0 []byte, receiver common.Address, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ReleaseOrMint(&_BurnMintTokenPool.TransactOpts, arg0, receiver, amount, arg3, arg4) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ReleaseOrMint(arg0 []byte, receiver common.Address, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ReleaseOrMint(&_BurnMintTokenPool.TransactOpts, arg0, receiver, amount, arg3, arg4) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetOffRampRateLimiterConfig(opts *bind.TransactOpts, offRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "setOffRampRateLimiterConfig", offRamp, config) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SetOffRampRateLimiterConfig(offRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetOffRampRateLimiterConfig(&_BurnMintTokenPool.TransactOpts, offRamp, config) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetOffRampRateLimiterConfig(offRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetOffRampRateLimiterConfig(&_BurnMintTokenPool.TransactOpts, offRamp, config) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetOnRampRateLimiterConfig(opts *bind.TransactOpts, onRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "setOnRampRateLimiterConfig", onRamp, config) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SetOnRampRateLimiterConfig(onRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetOnRampRateLimiterConfig(&_BurnMintTokenPool.TransactOpts, onRamp, config) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetOnRampRateLimiterConfig(onRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetOnRampRateLimiterConfig(&_BurnMintTokenPool.TransactOpts, onRamp, config) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "transferOwnership", to) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.TransferOwnership(&_BurnMintTokenPool.TransactOpts, to) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.TransferOwnership(&_BurnMintTokenPool.TransactOpts, to) +} + +type BurnMintTokenPoolAllowListAddIterator struct { + Event *BurnMintTokenPoolAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAllowListAddIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*BurnMintTokenPoolAllowListAddIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAllowListAddIterator{contract: _BurnMintTokenPool.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAllowListAdd) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseAllowListAdd(log types.Log) (*BurnMintTokenPoolAllowListAdd, error) { + event := new(BurnMintTokenPoolAllowListAdd) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAllowListRemoveIterator struct { + Event *BurnMintTokenPoolAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*BurnMintTokenPoolAllowListRemoveIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAllowListRemoveIterator{contract: _BurnMintTokenPool.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAllowListRemove) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseAllowListRemove(log types.Log) (*BurnMintTokenPoolAllowListRemove, error) { + event := new(BurnMintTokenPoolAllowListRemove) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolBurnedIterator struct { + Event *BurnMintTokenPoolBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolBurnedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolBurnedIterator{contract: _BurnMintTokenPool.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolBurned) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseBurned(log types.Log) (*BurnMintTokenPoolBurned, error) { + event := new(BurnMintTokenPoolBurned) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolLockedIterator struct { + Event *BurnMintTokenPoolLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolLockedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolLockedIterator{contract: _BurnMintTokenPool.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolLocked) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseLocked(log types.Log) (*BurnMintTokenPoolLocked, error) { + event := new(BurnMintTokenPoolLocked) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolMintedIterator struct { + Event *BurnMintTokenPoolMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolMintedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolMintedIterator{contract: _BurnMintTokenPool.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolMinted) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseMinted(log types.Log) (*BurnMintTokenPoolMinted, error) { + event := new(BurnMintTokenPoolMinted) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolOffRampAddedIterator struct { + Event *BurnMintTokenPoolOffRampAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolOffRampAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOffRampAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOffRampAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolOffRampAddedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolOffRampAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolOffRampAdded struct { + OffRamp common.Address + RateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterOffRampAdded(opts *bind.FilterOpts) (*BurnMintTokenPoolOffRampAddedIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "OffRampAdded") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolOffRampAddedIterator{contract: _BurnMintTokenPool.contract, event: "OffRampAdded", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchOffRampAdded(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOffRampAdded) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "OffRampAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolOffRampAdded) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OffRampAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseOffRampAdded(log types.Log) (*BurnMintTokenPoolOffRampAdded, error) { + event := new(BurnMintTokenPoolOffRampAdded) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OffRampAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolOffRampConfiguredIterator struct { + Event *BurnMintTokenPoolOffRampConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolOffRampConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOffRampConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOffRampConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolOffRampConfiguredIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolOffRampConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolOffRampConfigured struct { + OffRamp common.Address + RateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterOffRampConfigured(opts *bind.FilterOpts) (*BurnMintTokenPoolOffRampConfiguredIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "OffRampConfigured") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolOffRampConfiguredIterator{contract: _BurnMintTokenPool.contract, event: "OffRampConfigured", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchOffRampConfigured(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOffRampConfigured) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "OffRampConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolOffRampConfigured) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OffRampConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseOffRampConfigured(log types.Log) (*BurnMintTokenPoolOffRampConfigured, error) { + event := new(BurnMintTokenPoolOffRampConfigured) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OffRampConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolOffRampRemovedIterator struct { + Event *BurnMintTokenPoolOffRampRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolOffRampRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOffRampRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOffRampRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolOffRampRemovedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolOffRampRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolOffRampRemoved struct { + OffRamp common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterOffRampRemoved(opts *bind.FilterOpts) (*BurnMintTokenPoolOffRampRemovedIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "OffRampRemoved") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolOffRampRemovedIterator{contract: _BurnMintTokenPool.contract, event: "OffRampRemoved", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchOffRampRemoved(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOffRampRemoved) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "OffRampRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolOffRampRemoved) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OffRampRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseOffRampRemoved(log types.Log) (*BurnMintTokenPoolOffRampRemoved, error) { + event := new(BurnMintTokenPoolOffRampRemoved) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OffRampRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolOnRampAddedIterator struct { + Event *BurnMintTokenPoolOnRampAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolOnRampAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOnRampAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOnRampAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolOnRampAddedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolOnRampAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolOnRampAdded struct { + OnRamp common.Address + RateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterOnRampAdded(opts *bind.FilterOpts) (*BurnMintTokenPoolOnRampAddedIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "OnRampAdded") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolOnRampAddedIterator{contract: _BurnMintTokenPool.contract, event: "OnRampAdded", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchOnRampAdded(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOnRampAdded) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "OnRampAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolOnRampAdded) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OnRampAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseOnRampAdded(log types.Log) (*BurnMintTokenPoolOnRampAdded, error) { + event := new(BurnMintTokenPoolOnRampAdded) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OnRampAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolOnRampConfiguredIterator struct { + Event *BurnMintTokenPoolOnRampConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolOnRampConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOnRampConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOnRampConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolOnRampConfiguredIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolOnRampConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolOnRampConfigured struct { + OnRamp common.Address + RateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterOnRampConfigured(opts *bind.FilterOpts) (*BurnMintTokenPoolOnRampConfiguredIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "OnRampConfigured") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolOnRampConfiguredIterator{contract: _BurnMintTokenPool.contract, event: "OnRampConfigured", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchOnRampConfigured(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOnRampConfigured) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "OnRampConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolOnRampConfigured) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OnRampConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseOnRampConfigured(log types.Log) (*BurnMintTokenPoolOnRampConfigured, error) { + event := new(BurnMintTokenPoolOnRampConfigured) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OnRampConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolOnRampRemovedIterator struct { + Event *BurnMintTokenPoolOnRampRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolOnRampRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOnRampRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOnRampRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolOnRampRemovedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolOnRampRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolOnRampRemoved struct { + OnRamp common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterOnRampRemoved(opts *bind.FilterOpts) (*BurnMintTokenPoolOnRampRemovedIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "OnRampRemoved") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolOnRampRemovedIterator{contract: _BurnMintTokenPool.contract, event: "OnRampRemoved", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchOnRampRemoved(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOnRampRemoved) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "OnRampRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolOnRampRemoved) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OnRampRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseOnRampRemoved(log types.Log) (*BurnMintTokenPoolOnRampRemoved, error) { + event := new(BurnMintTokenPoolOnRampRemoved) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OnRampRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolOwnershipTransferRequestedIterator struct { + Event *BurnMintTokenPoolOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolOwnershipTransferRequestedIterator{contract: _BurnMintTokenPool.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolOwnershipTransferRequested) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseOwnershipTransferRequested(log types.Log) (*BurnMintTokenPoolOwnershipTransferRequested, error) { + event := new(BurnMintTokenPoolOwnershipTransferRequested) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolOwnershipTransferredIterator struct { + Event *BurnMintTokenPoolOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolOwnershipTransferredIterator{contract: _BurnMintTokenPool.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolOwnershipTransferred) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseOwnershipTransferred(log types.Log) (*BurnMintTokenPoolOwnershipTransferred, error) { + event := new(BurnMintTokenPoolOwnershipTransferred) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolReleasedIterator struct { + Event *BurnMintTokenPoolReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolReleasedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolReleasedIterator{contract: _BurnMintTokenPool.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolReleased) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseReleased(log types.Log) (*BurnMintTokenPoolReleased, error) { + event := new(BurnMintTokenPoolReleased) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPool) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _BurnMintTokenPool.abi.Events["AllowListAdd"].ID: + return _BurnMintTokenPool.ParseAllowListAdd(log) + case _BurnMintTokenPool.abi.Events["AllowListRemove"].ID: + return _BurnMintTokenPool.ParseAllowListRemove(log) + case _BurnMintTokenPool.abi.Events["Burned"].ID: + return _BurnMintTokenPool.ParseBurned(log) + case _BurnMintTokenPool.abi.Events["Locked"].ID: + return _BurnMintTokenPool.ParseLocked(log) + case _BurnMintTokenPool.abi.Events["Minted"].ID: + return _BurnMintTokenPool.ParseMinted(log) + case _BurnMintTokenPool.abi.Events["OffRampAdded"].ID: + return _BurnMintTokenPool.ParseOffRampAdded(log) + case _BurnMintTokenPool.abi.Events["OffRampConfigured"].ID: + return _BurnMintTokenPool.ParseOffRampConfigured(log) + case _BurnMintTokenPool.abi.Events["OffRampRemoved"].ID: + return _BurnMintTokenPool.ParseOffRampRemoved(log) + case _BurnMintTokenPool.abi.Events["OnRampAdded"].ID: + return _BurnMintTokenPool.ParseOnRampAdded(log) + case _BurnMintTokenPool.abi.Events["OnRampConfigured"].ID: + return _BurnMintTokenPool.ParseOnRampConfigured(log) + case _BurnMintTokenPool.abi.Events["OnRampRemoved"].ID: + return _BurnMintTokenPool.ParseOnRampRemoved(log) + case _BurnMintTokenPool.abi.Events["OwnershipTransferRequested"].ID: + return _BurnMintTokenPool.ParseOwnershipTransferRequested(log) + case _BurnMintTokenPool.abi.Events["OwnershipTransferred"].ID: + return _BurnMintTokenPool.ParseOwnershipTransferred(log) + case _BurnMintTokenPool.abi.Events["Released"].ID: + return _BurnMintTokenPool.ParseReleased(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (BurnMintTokenPoolAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (BurnMintTokenPoolAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (BurnMintTokenPoolBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (BurnMintTokenPoolLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (BurnMintTokenPoolMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (BurnMintTokenPoolOffRampAdded) Topic() common.Hash { + return common.HexToHash("0x395b7374909d2b54e5796f53c898ebf41d767c86c78ea86519acf2b805852d88") +} + +func (BurnMintTokenPoolOffRampConfigured) Topic() common.Hash { + return common.HexToHash("0xb3ba339cfbb8ef80d7a29ce5493051cb90e64fcfa85d7124efc1adfa4c68399f") +} + +func (BurnMintTokenPoolOffRampRemoved) Topic() common.Hash { + return common.HexToHash("0xcf91daec21e3510e2f2aea4b09d08c235d5c6844980be709f282ef591dbf420c") +} + +func (BurnMintTokenPoolOnRampAdded) Topic() common.Hash { + return common.HexToHash("0x0b594bb0555ff7b252e0c789ccc9d8903fec294172064308727d570505cee1ac") +} + +func (BurnMintTokenPoolOnRampConfigured) Topic() common.Hash { + return common.HexToHash("0x578db78e348076074dbff64a94073a83e9a65aa6766b8c75fdc89282b0e30ed6") +} + +func (BurnMintTokenPoolOnRampRemoved) Topic() common.Hash { + return common.HexToHash("0x7fd064821314ad863a0714a3f1229375ace6b6427ed5544b7b2ba1c47b1b5294") +} + +func (BurnMintTokenPoolOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (BurnMintTokenPoolOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (BurnMintTokenPoolReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (_BurnMintTokenPool *BurnMintTokenPool) Address() common.Address { + return _BurnMintTokenPool.address +} + +type BurnMintTokenPoolInterface interface { + CurrentOffRampRateLimiterState(opts *bind.CallOpts, offRamp common.Address) (RateLimiterTokenBucket, error) + + CurrentOnRampRateLimiterState(opts *bind.CallOpts, onRamp common.Address) (RateLimiterTokenBucket, error) + + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetArmProxy(opts *bind.CallOpts) (common.Address, error) + + GetOffRamps(opts *bind.CallOpts) ([]common.Address, error) + + GetOnRamps(opts *bind.CallOpts) ([]common.Address, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsOffRamp(opts *bind.CallOpts, offRamp common.Address) (bool, error) + + IsOnRamp(opts *bind.CallOpts, onRamp common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyRampUpdates(opts *bind.TransactOpts, onRamps []TokenPoolRampUpdate, offRamps []TokenPoolRampUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, originalSender common.Address, arg1 []byte, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, arg0 []byte, receiver common.Address, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) + + SetOffRampRateLimiterConfig(opts *bind.TransactOpts, offRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) + + SetOnRampRateLimiterConfig(opts *bind.TransactOpts, onRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*BurnMintTokenPoolAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*BurnMintTokenPoolAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*BurnMintTokenPoolAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*BurnMintTokenPoolAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*BurnMintTokenPoolBurned, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*BurnMintTokenPoolLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*BurnMintTokenPoolMinted, error) + + FilterOffRampAdded(opts *bind.FilterOpts) (*BurnMintTokenPoolOffRampAddedIterator, error) + + WatchOffRampAdded(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOffRampAdded) (event.Subscription, error) + + ParseOffRampAdded(log types.Log) (*BurnMintTokenPoolOffRampAdded, error) + + FilterOffRampConfigured(opts *bind.FilterOpts) (*BurnMintTokenPoolOffRampConfiguredIterator, error) + + WatchOffRampConfigured(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOffRampConfigured) (event.Subscription, error) + + ParseOffRampConfigured(log types.Log) (*BurnMintTokenPoolOffRampConfigured, error) + + FilterOffRampRemoved(opts *bind.FilterOpts) (*BurnMintTokenPoolOffRampRemovedIterator, error) + + WatchOffRampRemoved(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOffRampRemoved) (event.Subscription, error) + + ParseOffRampRemoved(log types.Log) (*BurnMintTokenPoolOffRampRemoved, error) + + FilterOnRampAdded(opts *bind.FilterOpts) (*BurnMintTokenPoolOnRampAddedIterator, error) + + WatchOnRampAdded(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOnRampAdded) (event.Subscription, error) + + ParseOnRampAdded(log types.Log) (*BurnMintTokenPoolOnRampAdded, error) + + FilterOnRampConfigured(opts *bind.FilterOpts) (*BurnMintTokenPoolOnRampConfiguredIterator, error) + + WatchOnRampConfigured(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOnRampConfigured) (event.Subscription, error) + + ParseOnRampConfigured(log types.Log) (*BurnMintTokenPoolOnRampConfigured, error) + + FilterOnRampRemoved(opts *bind.FilterOpts) (*BurnMintTokenPoolOnRampRemovedIterator, error) + + WatchOnRampRemoved(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOnRampRemoved) (event.Subscription, error) + + ParseOnRampRemoved(log types.Log) (*BurnMintTokenPoolOnRampRemoved, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*BurnMintTokenPoolOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*BurnMintTokenPoolOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*BurnMintTokenPoolReleased, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_4_0/burn_mint_token_pool_1_4_0.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_4_0/burn_mint_token_pool_1_4_0.go new file mode 100644 index 0000000000..5beb58e096 --- /dev/null +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_4_0/burn_mint_token_pool_1_4_0.go @@ -0,0 +1,2264 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package burn_mint_token_pool_1_4_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +var BurnMintTokenPoolMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRatelimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"releaseOrMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b50604051620034503803806200345083398101604081905262000034916200054d565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000163565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b1562000102576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000155576040805160008152602081019091526200015590846200020e565b5050505050505050620006d1565b336001600160a01b03821603620001bd5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200022f576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002c45760008382815181106200025357620002536200065d565b602090810291909101015190506200026d6002826200037f565b15620002b0576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50620002bc8162000689565b905062000232565b5060005b81518110156200037a576000828281518110620002e957620002e96200065d565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000315575062000367565b620003226002826200039f565b1562000365576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b620003728162000689565b9050620002c8565b505050565b600062000396836001600160a01b038416620003b6565b90505b92915050565b600062000396836001600160a01b038416620004ba565b60008181526001830160205260408120548015620004af576000620003dd600183620006a5565b8554909150600090620003f390600190620006a5565b90508181146200045f5760008660000182815481106200041757620004176200065d565b90600052602060002001549050808760000184815481106200043d576200043d6200065d565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004735762000473620006bb565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000399565b600091505062000399565b6000818152600183016020526040812054620005035750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000399565b50600062000399565b6001600160a01b03811681146200052257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000548816200050c565b919050565b600080600080608085870312156200056457600080fd5b845162000571816200050c565b602086810151919550906001600160401b03808211156200059157600080fd5b818801915088601f830112620005a657600080fd5b815181811115620005bb57620005bb62000525565b8060051b604051601f19603f83011681018181108582111715620005e357620005e362000525565b60405291825284820192508381018501918b8311156200060257600080fd5b938501935b828510156200062b576200061b856200053b565b8452938501939285019262000607565b80985050505050505062000642604086016200053b565b915062000652606086016200053b565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200069e576200069e62000673565b5060010190565b8181038181111562000399576200039962000673565b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051612d1762000739600039600081816103c80152818161100c01526115b501526000818161022b01528181610baf01526110900152600081816101e401528181610df0015281816118f50152818161198001526119d30152612d176000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c806396875445116100cd578063c4bffe2b11610081578063cf7401f311610066578063cf7401f3146103b3578063e0351e13146103c6578063f2fde38b146103ec57600080fd5b8063c4bffe2b1461038b578063c75eea9c146103a057600080fd5b8063af58d59f116100b2578063af58d59f146102eb578063b0f479a11461035a578063c0d786551461037857600080fd5b806396875445146102c3578063a7cd63b7146102d657600080fd5b80635995f063116101245780638627fad6116101095780638627fad61461027f5780638926f54f146102925780638da5cb5b146102a557600080fd5b80635995f0631461026457806379ba50971461027757600080fd5b806321df0da71161015557806321df0da7146101e25780635246492f1461022957806354c8a4f31461024f57600080fd5b806301ffc9a714610171578063181f5a7714610199575b600080fd5b61018461017f366004612425565b6103ff565b60405190151581526020015b60405180910390f35b6101d56040518060400160405280601781526020017f4275726e4d696e74546f6b656e506f6f6c20312e342e3000000000000000000081525081565b60405161019091906124cb565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610190565b7f0000000000000000000000000000000000000000000000000000000000000000610204565b61026261025d36600461252a565b610498565b005b610262610272366004612596565b610513565b610262610ab0565b61026261028d366004612724565b610bad565b6101846102a03660046127b8565b610ea1565b60005473ffffffffffffffffffffffffffffffffffffffff16610204565b6101d56102d1366004612815565b610eb8565b6102de6111b9565b60405161019091906128b5565b6102fe6102f93660046127b8565b6111ca565b604051610190919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610204565b61026261038636600461290f565b61129c565b610393611377565b604051610190919061292c565b6102fe6103ae3660046127b8565b611437565b6102626103c1366004612a0d565b611509565b7f0000000000000000000000000000000000000000000000000000000000000000610184565b6102626103fa36600461290f565b61151c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f317fa33400000000000000000000000000000000000000000000000000000000148061049257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6104a0611530565b61050d848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920191909152506115b392505050565b50505050565b61051b611530565b60005b81811015610aab57600083838381811061053a5761053a612a52565b905061010002018036038101906105519190612a81565b90506105668160400151826020015115611779565b6105798160600151826020015115611779565b80602001511561099f57805161059b9060059067ffffffffffffffff166118b6565b6105e55780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024015b60405180910390fd5b6040518060a001604052808260400151602001516fffffffffffffffffffffffffffffffff1681526020014263ffffffff168152602001826040015160000151151581526020018260400151602001516fffffffffffffffffffffffffffffffff1681526020018260400151604001516fffffffffffffffffffffffffffffffff1681525060076000836000015167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160146101000a81548160ff02191690831515021790555060608201518160010160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060808201518160010160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055509050506040518060a001604052808260600151602001516fffffffffffffffffffffffffffffffff1681526020014263ffffffff168152602001826060015160000151151581526020018260600151602001516fffffffffffffffffffffffffffffffff1681526020018260600151604001516fffffffffffffffffffffffffffffffff1681525060086000836000015167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160146101000a81548160ff02191690831515021790555060608201518160010160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060808201518160010160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055509050507f0f135cbb9afa12a8bf3bbd071c117bcca4ddeca6160ef7f33d012a81b9c0c47181600001518260400151836060015160405161099293929190612b03565b60405180910390a1610a9a565b80516109b79060059067ffffffffffffffff166118c9565b6109fc5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016105dc565b805167ffffffffffffffff908116600090815260086020908152604080832080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600191820185905586518616855260078452828520805490911681550192909255835191519190921681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916910160405180910390a15b50610aa481612bb5565b905061051e565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016105dc565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3c9190612bed565b15610c73576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81610c7d81610ea1565b610cbf576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016105dc565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015610d3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d629190612bed565b610d9a576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016105dc565b610da483856118d5565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152602482018690527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b158015610e3457600080fd5b505af1158015610e48573d6000803e3d6000fd5b505060405186815273ffffffffffffffffffffffffffffffffffffffff881692503391507f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f09060200160405180910390a3505050505050565b6000610492600567ffffffffffffffff8416611919565b606083610ec481610ea1565b610f06576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016105dc565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015610f7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa39190612c0a565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611009576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016105dc565b887f0000000000000000000000000000000000000000000000000000000000000000801561103f575061103d600282611931565b155b1561108e576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105dc565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111d9190612bed565b15611154576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61115e8688611960565b611167876119a4565b60405187815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a2505060408051602081019091526000815298975050505050505050565b60606111c56002611a47565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260086020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261049290611a54565b6112a4611530565b73ffffffffffffffffffffffffffffffffffffffff81166112f1576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006113856005611a47565b90506000815167ffffffffffffffff8111156113a3576113a361260b565b6040519080825280602002602001820160405280156113cc578160200160208202803683370190505b50905060005b8251811015611430578281815181106113ed576113ed612a52565b602002602001015182828151811061140757611407612a52565b67ffffffffffffffff9092166020928302919091019091015261142981612bb5565b90506113d2565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261049290611a54565b611511611530565b610aab838383611b06565b611524611530565b61152d81611bed565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146115b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105dc565b565b7f000000000000000000000000000000000000000000000000000000000000000061160a576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156116a857600083828151811061162a5761162a612a52565b60200260200101519050611648816002611ce290919063ffffffff16565b156116975760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506116a181612bb5565b905061160d565b5060005b8151811015610aab5760008282815181106116c9576116c9612a52565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361170d5750611769565b611718600282611d04565b156117675760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b61177281612bb5565b90506116ac565b8151156118445781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806117cf575060408201516fffffffffffffffffffffffffffffffff16155b1561180857816040517f70505e560000000000000000000000000000000000000000000000000000000081526004016105dc9190612c27565b8015611840576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff1615158061187d575060208201516fffffffffffffffffffffffffffffffff1615155b1561184057816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016105dc9190612c27565b60006118c28383611d22565b9392505050565b60006118c28383611d71565b67ffffffffffffffff8216600090815260086020526040902061184090827f0000000000000000000000000000000000000000000000000000000000000000611e64565b600081815260018301602052604081205415156118c2565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156118c2565b67ffffffffffffffff8216600090815260076020526040902061184090827f0000000000000000000000000000000000000000000000000000000000000000611e64565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611a2c57600080fd5b505af1158015611a40573d6000803e3d6000fd5b5050505050565b606060006118c2836121e7565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611ae282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611ac69190612c63565b85608001516fffffffffffffffffffffffffffffffff16612243565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611b0f83610ea1565b611b51576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016105dc565b611b5c826000611779565b67ffffffffffffffff83166000908152600760205260409020611b7f908361226d565b611b8a816000611779565b67ffffffffffffffff83166000908152600860205260409020611bad908261226d565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611be093929190612b03565b60405180910390a1505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611c6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105dc565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006118c28373ffffffffffffffffffffffffffffffffffffffff8416611d71565b60006118c28373ffffffffffffffffffffffffffffffffffffffff84165b6000818152600183016020526040812054611d6957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610492565b506000610492565b60008181526001830160205260408120548015611e5a576000611d95600183612c63565b8554909150600090611da990600190612c63565b9050818114611e0e576000866000018281548110611dc957611dc9612a52565b9060005260206000200154905080876000018481548110611dec57611dec612a52565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611e1f57611e1f612c76565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610492565b6000915050610492565b825474010000000000000000000000000000000000000000900460ff161580611e8b575081155b15611e9557505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090611edb90700100000000000000000000000000000000900463ffffffff1642612c63565b90508015611f9b5781831115611f1d576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154611f579083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612243565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156120525773ffffffffffffffffffffffffffffffffffffffff8416611ffa576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016105dc565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016105dc565b848310156121655760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906120969082612c63565b6120a0878a612c63565b6120aa9190612ca5565b6120b49190612cb8565b905073ffffffffffffffffffffffffffffffffffffffff861661210d576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016105dc565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016105dc565b61216f8584612c63565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561223757602002820191906000526020600020905b815481526020019060010190808311612223575b50505050509050919050565b6000612262856122538486612cf3565b61225d9087612ca5565b61240f565b90505b949350505050565b815460009061229690700100000000000000000000000000000000900463ffffffff1642612c63565b9050801561233857600183015483546122de916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612243565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461235e916fffffffffffffffffffffffffffffffff908116911661240f565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611be0908490612c27565b600081831061241e57816118c2565b5090919050565b60006020828403121561243757600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146118c257600080fd5b6000815180845260005b8181101561248d57602081850181015186830182015201612471565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006118c26020830184612467565b60008083601f8401126124f057600080fd5b50813567ffffffffffffffff81111561250857600080fd5b6020830191508360208260051b850101111561252357600080fd5b9250929050565b6000806000806040858703121561254057600080fd5b843567ffffffffffffffff8082111561255857600080fd5b612564888389016124de565b9096509450602087013591508082111561257d57600080fd5b5061258a878288016124de565b95989497509550505050565b600080602083850312156125a957600080fd5b823567ffffffffffffffff808211156125c157600080fd5b818501915085601f8301126125d557600080fd5b8135818111156125e457600080fd5b8660208260081b85010111156125f957600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261264b57600080fd5b813567ffffffffffffffff808211156126665761266661260b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156126ac576126ac61260b565b816040528381528660208588010111156126c557600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461152d57600080fd5b803567ffffffffffffffff8116811461271f57600080fd5b919050565b600080600080600060a0868803121561273c57600080fd5b853567ffffffffffffffff8082111561275457600080fd5b61276089838a0161263a565b965060208801359150612772826126e5565b8195506040880135945061278860608901612707565b9350608088013591508082111561279e57600080fd5b506127ab8882890161263a565b9150509295509295909350565b6000602082840312156127ca57600080fd5b6118c282612707565b60008083601f8401126127e557600080fd5b50813567ffffffffffffffff8111156127fd57600080fd5b60208301915083602082850101111561252357600080fd5b600080600080600080600060a0888a03121561283057600080fd5b873561283b816126e5565b9650602088013567ffffffffffffffff8082111561285857600080fd5b6128648b838c016127d3565b909850965060408a0135955086915061287f60608b01612707565b945060808a013591508082111561289557600080fd5b506128a28a828b016127d3565b989b979a50959850939692959293505050565b6020808252825182820181905260009190848201906040850190845b8181101561290357835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016128d1565b50909695505050505050565b60006020828403121561292157600080fd5b81356118c2816126e5565b6020808252825182820181905260009190848201906040850190845b8181101561290357835167ffffffffffffffff1683529284019291840191600101612948565b801515811461152d57600080fd5b80356fffffffffffffffffffffffffffffffff8116811461271f57600080fd5b6000606082840312156129ae57600080fd5b6040516060810181811067ffffffffffffffff821117156129d1576129d161260b565b60405290508082356129e28161296e565b81526129f06020840161297c565b6020820152612a016040840161297c565b60408201525092915050565b600080600060e08486031215612a2257600080fd5b612a2b84612707565b9250612a3a856020860161299c565b9150612a49856080860161299c565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006101008284031215612a9457600080fd5b6040516080810181811067ffffffffffffffff82111715612ab757612ab761260b565b604052612ac383612707565b81526020830135612ad38161296e565b6020820152612ae5846040850161299c565b6040820152612af78460a0850161299c565b60608201529392505050565b67ffffffffffffffff8416815260e08101612b4f60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612265565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612be657612be6612b86565b5060010190565b600060208284031215612bff57600080fd5b81516118c28161296e565b600060208284031215612c1c57600080fd5b81516118c2816126e5565b6060810161049282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b8181038181111561049257610492612b86565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561049257610492612b86565b600082612cee577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761049257610492612b8656fea164736f6c6343000813000a", +} + +var BurnMintTokenPoolABI = BurnMintTokenPoolMetaData.ABI + +var BurnMintTokenPoolBin = BurnMintTokenPoolMetaData.Bin + +func DeployBurnMintTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, armProxy common.Address, router common.Address) (common.Address, *types.Transaction, *BurnMintTokenPool, error) { + parsed, err := BurnMintTokenPoolMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnMintTokenPoolBin), backend, token, allowlist, armProxy, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &BurnMintTokenPool{address: address, abi: *parsed, BurnMintTokenPoolCaller: BurnMintTokenPoolCaller{contract: contract}, BurnMintTokenPoolTransactor: BurnMintTokenPoolTransactor{contract: contract}, BurnMintTokenPoolFilterer: BurnMintTokenPoolFilterer{contract: contract}}, nil +} + +type BurnMintTokenPool struct { + address common.Address + abi abi.ABI + BurnMintTokenPoolCaller + BurnMintTokenPoolTransactor + BurnMintTokenPoolFilterer +} + +type BurnMintTokenPoolCaller struct { + contract *bind.BoundContract +} + +type BurnMintTokenPoolTransactor struct { + contract *bind.BoundContract +} + +type BurnMintTokenPoolFilterer struct { + contract *bind.BoundContract +} + +type BurnMintTokenPoolSession struct { + Contract *BurnMintTokenPool + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type BurnMintTokenPoolCallerSession struct { + Contract *BurnMintTokenPoolCaller + CallOpts bind.CallOpts +} + +type BurnMintTokenPoolTransactorSession struct { + Contract *BurnMintTokenPoolTransactor + TransactOpts bind.TransactOpts +} + +type BurnMintTokenPoolRaw struct { + Contract *BurnMintTokenPool +} + +type BurnMintTokenPoolCallerRaw struct { + Contract *BurnMintTokenPoolCaller +} + +type BurnMintTokenPoolTransactorRaw struct { + Contract *BurnMintTokenPoolTransactor +} + +func NewBurnMintTokenPool(address common.Address, backend bind.ContractBackend) (*BurnMintTokenPool, error) { + abi, err := abi.JSON(strings.NewReader(BurnMintTokenPoolABI)) + if err != nil { + return nil, err + } + contract, err := bindBurnMintTokenPool(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &BurnMintTokenPool{address: address, abi: abi, BurnMintTokenPoolCaller: BurnMintTokenPoolCaller{contract: contract}, BurnMintTokenPoolTransactor: BurnMintTokenPoolTransactor{contract: contract}, BurnMintTokenPoolFilterer: BurnMintTokenPoolFilterer{contract: contract}}, nil +} + +func NewBurnMintTokenPoolCaller(address common.Address, caller bind.ContractCaller) (*BurnMintTokenPoolCaller, error) { + contract, err := bindBurnMintTokenPool(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolCaller{contract: contract}, nil +} + +func NewBurnMintTokenPoolTransactor(address common.Address, transactor bind.ContractTransactor) (*BurnMintTokenPoolTransactor, error) { + contract, err := bindBurnMintTokenPool(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolTransactor{contract: contract}, nil +} + +func NewBurnMintTokenPoolFilterer(address common.Address, filterer bind.ContractFilterer) (*BurnMintTokenPoolFilterer, error) { + contract, err := bindBurnMintTokenPool(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolFilterer{contract: contract}, nil +} + +func bindBurnMintTokenPool(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := BurnMintTokenPoolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnMintTokenPool.Contract.BurnMintTokenPoolCaller.contract.Call(opts, result, method, params...) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.BurnMintTokenPoolTransactor.contract.Transfer(opts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.BurnMintTokenPoolTransactor.contract.Transact(opts, method, params...) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnMintTokenPool.Contract.contract.Call(opts, result, method, params...) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.contract.Transfer(opts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.contract.Transact(opts, method, params...) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetAllowList() ([]common.Address, error) { + return _BurnMintTokenPool.Contract.GetAllowList(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetAllowList() ([]common.Address, error) { + return _BurnMintTokenPool.Contract.GetAllowList(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetAllowListEnabled() (bool, error) { + return _BurnMintTokenPool.Contract.GetAllowListEnabled(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetAllowListEnabled() (bool, error) { + return _BurnMintTokenPool.Contract.GetAllowListEnabled(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetArmProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getArmProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetArmProxy() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetArmProxy(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetArmProxy() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetArmProxy(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPool.Contract.GetCurrentInboundRateLimiterState(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPool.Contract.GetCurrentInboundRateLimiterState(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetRouter() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetRouter(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetRouter() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetRouter(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetSupportedChains() ([]uint64, error) { + return _BurnMintTokenPool.Contract.GetSupportedChains(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetSupportedChains() ([]uint64, error) { + return _BurnMintTokenPool.Contract.GetSupportedChains(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetToken() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetToken(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetToken() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetToken(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _BurnMintTokenPool.Contract.IsSupportedChain(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _BurnMintTokenPool.Contract.IsSupportedChain(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) Owner() (common.Address, error) { + return _BurnMintTokenPool.Contract.Owner(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) Owner() (common.Address, error) { + return _BurnMintTokenPool.Contract.Owner(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnMintTokenPool.Contract.SupportsInterface(&_BurnMintTokenPool.CallOpts, interfaceId) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnMintTokenPool.Contract.SupportsInterface(&_BurnMintTokenPool.CallOpts, interfaceId) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) TypeAndVersion() (string, error) { + return _BurnMintTokenPool.Contract.TypeAndVersion(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) TypeAndVersion() (string, error) { + return _BurnMintTokenPool.Contract.TypeAndVersion(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "acceptOwnership") +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.AcceptOwnership(&_BurnMintTokenPool.TransactOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.AcceptOwnership(&_BurnMintTokenPool.TransactOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnMintTokenPool.TransactOpts, removes, adds) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnMintTokenPool.TransactOpts, removes, adds) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyChainUpdates(&_BurnMintTokenPool.TransactOpts, chains) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyChainUpdates(&_BurnMintTokenPool.TransactOpts, chains) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, originalSender common.Address, arg1 []byte, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "lockOrBurn", originalSender, arg1, amount, remoteChainSelector, arg4) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) LockOrBurn(originalSender common.Address, arg1 []byte, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.LockOrBurn(&_BurnMintTokenPool.TransactOpts, originalSender, arg1, amount, remoteChainSelector, arg4) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) LockOrBurn(originalSender common.Address, arg1 []byte, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.LockOrBurn(&_BurnMintTokenPool.TransactOpts, originalSender, arg1, amount, remoteChainSelector, arg4) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) ReleaseOrMint(opts *bind.TransactOpts, arg0 []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "releaseOrMint", arg0, receiver, amount, remoteChainSelector, arg4) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) ReleaseOrMint(arg0 []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ReleaseOrMint(&_BurnMintTokenPool.TransactOpts, arg0, receiver, amount, remoteChainSelector, arg4) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ReleaseOrMint(arg0 []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ReleaseOrMint(&_BurnMintTokenPool.TransactOpts, arg0, receiver, amount, remoteChainSelector, arg4) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "setRouter", newRouter) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetRouter(&_BurnMintTokenPool.TransactOpts, newRouter) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetRouter(&_BurnMintTokenPool.TransactOpts, newRouter) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "transferOwnership", to) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.TransferOwnership(&_BurnMintTokenPool.TransactOpts, to) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.TransferOwnership(&_BurnMintTokenPool.TransactOpts, to) +} + +type BurnMintTokenPoolAllowListAddIterator struct { + Event *BurnMintTokenPoolAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAllowListAddIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*BurnMintTokenPoolAllowListAddIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAllowListAddIterator{contract: _BurnMintTokenPool.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAllowListAdd) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseAllowListAdd(log types.Log) (*BurnMintTokenPoolAllowListAdd, error) { + event := new(BurnMintTokenPoolAllowListAdd) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAllowListRemoveIterator struct { + Event *BurnMintTokenPoolAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*BurnMintTokenPoolAllowListRemoveIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAllowListRemoveIterator{contract: _BurnMintTokenPool.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAllowListRemove) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseAllowListRemove(log types.Log) (*BurnMintTokenPoolAllowListRemove, error) { + event := new(BurnMintTokenPoolAllowListRemove) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolBurnedIterator struct { + Event *BurnMintTokenPoolBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolBurnedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolBurnedIterator{contract: _BurnMintTokenPool.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolBurned) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseBurned(log types.Log) (*BurnMintTokenPoolBurned, error) { + event := new(BurnMintTokenPoolBurned) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolChainAddedIterator struct { + Event *BurnMintTokenPoolChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolChainAddedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolChainAdded struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterChainAdded(opts *bind.FilterOpts) (*BurnMintTokenPoolChainAddedIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolChainAddedIterator{contract: _BurnMintTokenPool.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolChainAdded) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolChainAdded) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseChainAdded(log types.Log) (*BurnMintTokenPoolChainAdded, error) { + event := new(BurnMintTokenPoolChainAdded) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolChainConfiguredIterator struct { + Event *BurnMintTokenPoolChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*BurnMintTokenPoolChainConfiguredIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolChainConfiguredIterator{contract: _BurnMintTokenPool.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolChainConfigured) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolChainConfigured) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseChainConfigured(log types.Log) (*BurnMintTokenPoolChainConfigured, error) { + event := new(BurnMintTokenPoolChainConfigured) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolChainRemovedIterator struct { + Event *BurnMintTokenPoolChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolChainRemovedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*BurnMintTokenPoolChainRemovedIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolChainRemovedIterator{contract: _BurnMintTokenPool.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolChainRemoved) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolChainRemoved) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseChainRemoved(log types.Log) (*BurnMintTokenPoolChainRemoved, error) { + event := new(BurnMintTokenPoolChainRemoved) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolLockedIterator struct { + Event *BurnMintTokenPoolLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolLockedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolLockedIterator{contract: _BurnMintTokenPool.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolLocked) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseLocked(log types.Log) (*BurnMintTokenPoolLocked, error) { + event := new(BurnMintTokenPoolLocked) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolMintedIterator struct { + Event *BurnMintTokenPoolMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolMintedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolMintedIterator{contract: _BurnMintTokenPool.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolMinted) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseMinted(log types.Log) (*BurnMintTokenPoolMinted, error) { + event := new(BurnMintTokenPoolMinted) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolOwnershipTransferRequestedIterator struct { + Event *BurnMintTokenPoolOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolOwnershipTransferRequestedIterator{contract: _BurnMintTokenPool.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolOwnershipTransferRequested) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseOwnershipTransferRequested(log types.Log) (*BurnMintTokenPoolOwnershipTransferRequested, error) { + event := new(BurnMintTokenPoolOwnershipTransferRequested) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolOwnershipTransferredIterator struct { + Event *BurnMintTokenPoolOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolOwnershipTransferredIterator{contract: _BurnMintTokenPool.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolOwnershipTransferred) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseOwnershipTransferred(log types.Log) (*BurnMintTokenPoolOwnershipTransferred, error) { + event := new(BurnMintTokenPoolOwnershipTransferred) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolReleasedIterator struct { + Event *BurnMintTokenPoolReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolReleasedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolReleasedIterator{contract: _BurnMintTokenPool.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolReleased) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseReleased(log types.Log) (*BurnMintTokenPoolReleased, error) { + event := new(BurnMintTokenPoolReleased) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolRouterUpdatedIterator struct { + Event *BurnMintTokenPoolRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*BurnMintTokenPoolRouterUpdatedIterator, error) { + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolRouterUpdatedIterator{contract: _BurnMintTokenPool.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolRouterUpdated) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseRouterUpdated(log types.Log) (*BurnMintTokenPoolRouterUpdated, error) { + event := new(BurnMintTokenPoolRouterUpdated) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPool) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _BurnMintTokenPool.abi.Events["AllowListAdd"].ID: + return _BurnMintTokenPool.ParseAllowListAdd(log) + case _BurnMintTokenPool.abi.Events["AllowListRemove"].ID: + return _BurnMintTokenPool.ParseAllowListRemove(log) + case _BurnMintTokenPool.abi.Events["Burned"].ID: + return _BurnMintTokenPool.ParseBurned(log) + case _BurnMintTokenPool.abi.Events["ChainAdded"].ID: + return _BurnMintTokenPool.ParseChainAdded(log) + case _BurnMintTokenPool.abi.Events["ChainConfigured"].ID: + return _BurnMintTokenPool.ParseChainConfigured(log) + case _BurnMintTokenPool.abi.Events["ChainRemoved"].ID: + return _BurnMintTokenPool.ParseChainRemoved(log) + case _BurnMintTokenPool.abi.Events["Locked"].ID: + return _BurnMintTokenPool.ParseLocked(log) + case _BurnMintTokenPool.abi.Events["Minted"].ID: + return _BurnMintTokenPool.ParseMinted(log) + case _BurnMintTokenPool.abi.Events["OwnershipTransferRequested"].ID: + return _BurnMintTokenPool.ParseOwnershipTransferRequested(log) + case _BurnMintTokenPool.abi.Events["OwnershipTransferred"].ID: + return _BurnMintTokenPool.ParseOwnershipTransferred(log) + case _BurnMintTokenPool.abi.Events["Released"].ID: + return _BurnMintTokenPool.ParseReleased(log) + case _BurnMintTokenPool.abi.Events["RouterUpdated"].ID: + return _BurnMintTokenPool.ParseRouterUpdated(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (BurnMintTokenPoolAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (BurnMintTokenPoolAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (BurnMintTokenPoolBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (BurnMintTokenPoolChainAdded) Topic() common.Hash { + return common.HexToHash("0x0f135cbb9afa12a8bf3bbd071c117bcca4ddeca6160ef7f33d012a81b9c0c471") +} + +func (BurnMintTokenPoolChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (BurnMintTokenPoolChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (BurnMintTokenPoolLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (BurnMintTokenPoolMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (BurnMintTokenPoolOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (BurnMintTokenPoolOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (BurnMintTokenPoolReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (BurnMintTokenPoolRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (_BurnMintTokenPool *BurnMintTokenPool) Address() common.Address { + return _BurnMintTokenPool.address +} + +type BurnMintTokenPoolInterface interface { + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetArmProxy(opts *bind.CallOpts) (common.Address, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, originalSender common.Address, arg1 []byte, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, arg0 []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*BurnMintTokenPoolAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*BurnMintTokenPoolAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*BurnMintTokenPoolAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*BurnMintTokenPoolAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*BurnMintTokenPoolBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*BurnMintTokenPoolChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*BurnMintTokenPoolChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*BurnMintTokenPoolChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*BurnMintTokenPoolChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*BurnMintTokenPoolChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*BurnMintTokenPoolChainRemoved, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*BurnMintTokenPoolLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*BurnMintTokenPoolMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*BurnMintTokenPoolOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*BurnMintTokenPoolOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*BurnMintTokenPoolReleased, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*BurnMintTokenPoolRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*BurnMintTokenPoolRouterUpdated, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go new file mode 100644 index 0000000000..b7ef316764 --- /dev/null +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go @@ -0,0 +1,2972 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package burn_mint_token_pool_and_proxy + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type PoolLockOrBurnInV1 struct { + Receiver []byte + RemoteChainSelector uint64 + OriginalSender common.Address + Amount *big.Int + LocalToken common.Address +} + +type PoolLockOrBurnOutV1 struct { + DestTokenAddress []byte + DestPoolData []byte +} + +type PoolReleaseOrMintInV1 struct { + OriginalSender []byte + RemoteChainSelector uint64 + Receiver common.Address + Amount *big.Int + LocalToken common.Address + SourcePoolAddress []byte + SourcePoolData []byte + OffchainTokenData []byte +} + +type PoolReleaseOrMintOutV1 struct { + DestinationAmount *big.Int +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + RemotePoolAddress []byte + RemoteTokenAddress []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +var BurnMintTokenPoolAndProxyMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b506040516200481e3803806200481e833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050818114620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c0516140e862000736600039600081816104bc0152818161197001526123c2015260008181610496015281816117080152611c23015260008181610210015281816102650152818161071901528181610d040152818161162801528181611b4301528181611d290152818161235801526125ad01526140e86000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80639a4575b9116100f9578063c4bffe2b11610097578063db6327dc11610071578063db6327dc14610481578063dc0bd97114610494578063e0351e13146104ba578063f2fde38b146104e057600080fd5b8063c4bffe2b14610446578063c75eea9c1461045b578063cf7401f31461046e57600080fd5b8063af58d59f116100d3578063af58d59f14610393578063b0f479a114610402578063b794658014610420578063c0d786551461043357600080fd5b80639a4575b91461034b578063a7cd63b71461036b578063a8d87a3b1461038057600080fd5b806354c8a4f31161016657806383826b2b1161014057806383826b2b146102f45780638926f54f146103075780638da5cb5b1461031a5780639766b9321461033857600080fd5b806354c8a4f3146102c457806378a010b2146102d957806379ba5097146102ec57600080fd5b806321df0da71161019757806321df0da71461020e578063240028e81461025557806339077537146102a257600080fd5b806301ffc9a7146101be5780630a2fd493146101e6578063181f5a7714610206575b600080fd5b6101d16101cc36600461305a565b6104f3565b60405190151581526020015b60405180910390f35b6101f96101f43660046130b9565b6105d8565b6040516101dd9190613142565b6101f9610688565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101dd565b6101d1610263366004613182565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102b56102b036600461319f565b6106a4565b604051905181526020016101dd565b6102d76102d2366004613227565b610831565b005b6102d76102e7366004613293565b6108ac565b6102d7610a20565b6101d1610302366004613316565b610b1d565b6101d16103153660046130b9565b610bea565b60005473ffffffffffffffffffffffffffffffffffffffff16610230565b6102d7610346366004613182565b610c01565b61035e61035936600461334d565b610c90565b6040516101dd9190613388565b610373610e00565b6040516101dd91906133e8565b61023061038e3660046130b9565b503090565b6103a66103a13660046130b9565b610e11565b6040516101dd919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610230565b6101f961042e3660046130b9565b610ee6565b6102d7610441366004613182565b610f11565b61044e610fe5565b6040516101dd9190613442565b6103a66104693660046130b9565b61109d565b6102d761047c3660046135f9565b61116f565b6102d761048f36600461363e565b611187565b7f0000000000000000000000000000000000000000000000000000000000000000610230565b7f00000000000000000000000000000000000000000000000000000000000000006101d1565b6102d76104ee366004613182565b61160d565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061058657507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105d257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061060390613680565b80601f016020809104026020016040519081016040528092919081815260200182805461062f90613680565b801561067c5780601f106106515761010080835404028352916020019161067c565b820191906000526020600020905b81548152906001019060200180831161065f57829003601f168201915b50505050509050919050565b6040518060600160405280602381526020016140b96023913981565b6040805160208101909152600081526106c46106bf8361376f565b611621565b60085473ffffffffffffffffffffffffffffffffffffffff1661078f576040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561077257600080fd5b505af1158015610786573d6000803e3d6000fd5b505050506107a0565b6107a061079b8361376f565b611852565b6107b06060830160408401613182565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081291815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108396118eb565b6108a68484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061196e92505050565b50505050565b6108b46118eb565b6108bd83610bea565b610904576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461092b90613680565b80601f016020809104026020016040519081016040528092919081815260200182805461095790613680565b80156109a45780601f10610979576101008083540402835291602001916109a4565b820191906000526020600020905b81548152906001019060200180831161098757829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d38385836138b4565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a12939291906139ce565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610aa1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108fb565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610be35750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610bbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be39190613a32565b9392505050565b60006105d2600567ffffffffffffffff8416611b24565b610c096118eb565b6008805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610cb5610cb083613a4f565b611b3c565b60085473ffffffffffffffffffffffffffffffffffffffff16610d7a576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610d5d57600080fd5b505af1158015610d71573d6000803e3d6000fd5b50505050610d8b565b610d8b610d8683613a4f565b611d06565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610de584602001602081019061042e91906130b9565b81526040805160208181019092526000815291015292915050565b6060610e0c6002611e20565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105d290611e2d565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061060390613680565b610f196118eb565b73ffffffffffffffffffffffffffffffffffffffff8116610f66576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610c84565b60606000610ff36005611e20565b90506000815167ffffffffffffffff81111561101157611011613484565b60405190808252806020026020018201604052801561103a578160200160208202803683370190505b50905060005b82518110156110965782818151811061105b5761105b613af1565b602002602001015182828151811061107557611075613af1565b67ffffffffffffffff90921660209283029190910190910152600101611040565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105d290611e2d565b6111776118eb565b611182838383611edf565b505050565b61118f6118eb565b60005b818110156111825760008383838181106111ae576111ae613af1565b90506020028101906111c09190613b20565b6111c990613b5e565b90506111de8160800151826020015115611fc9565b6111f18160a00151826020015115611fc9565b8060200151156114ed5780516112139060059067ffffffffffffffff16612102565b6112585780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108fb565b604081015151158061126d5750606081015151155b156112a4576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906114859082613c12565b506060820151600582019061149a9082613c12565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506114e09493929190613d2c565b60405180910390a1611604565b80516115059060059067ffffffffffffffff1661210e565b61154a5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108fb565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906115b3600483018261300c565b6115c160058301600061300c565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611192565b6116156118eb565b61161e8161211a565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146116b65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108fb565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611764573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117889190613a32565b156117bf576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6117cc816020015161220f565b60006117db82602001516105d8565b90508051600014806117ff575080805190602001208260a001518051906020012014155b1561183c578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108fb9190613142565b61184e82602001518360600151612335565b5050565b6008548151606083015160208401516040517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90941693638627fad6936118b69390923392600401613dc5565b600060405180830381600087803b1580156118d057600080fd5b505af11580156118e4573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461196c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108fb565b565b7f00000000000000000000000000000000000000000000000000000000000000006119c5576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611a5b5760008382815181106119e5576119e5613af1565b60200260200101519050611a0381600261237c90919063ffffffff16565b15611a525760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016119c8565b5060005b8151811015611182576000828281518110611a7c57611a7c613af1565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ac05750611b1c565b611acb60028261239e565b15611b1a5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611a5f565b60008181526001830160205260408120541515610be3565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611bd15760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108fb565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611c7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca39190613a32565b15611cda576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ce781604001516123c0565b611cf4816020015161243f565b61161e8160200151826060015161258d565b6008546060820151611d539173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116929116906125d1565b60085460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611dbb94939291600401613e26565b6000604051808303816000875af1158015611dda573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261184e9190810190613e86565b60606000610be38361265e565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611ebb82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611e9f9190613f23565b85608001516fffffffffffffffffffffffffffffffff166126b9565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611ee883610bea565b611f2a576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108fb565b611f35826000611fc9565b67ffffffffffffffff83166000908152600760205260409020611f5890836126e3565b611f63816000611fc9565b67ffffffffffffffff83166000908152600760205260409020611f8990600201826126e3565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611fbc93929190613f36565b60405180910390a1505050565b8151156120905781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061201f575060408201516fffffffffffffffffffffffffffffffff16155b1561205857816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108fb9190613fb9565b801561184e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806120c9575060208201516fffffffffffffffffffffffffffffffff1615155b1561184e57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108fb9190613fb9565b6000610be38383612885565b6000610be383836128d4565b3373ffffffffffffffffffffffffffffffffffffffff821603612199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108fb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61221881610bea565b61225a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108fb565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156122d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122fd9190613a32565b61161e576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108fb565b67ffffffffffffffff8216600090815260076020526040902061184e90600201827f00000000000000000000000000000000000000000000000000000000000000006129c7565b6000610be38373ffffffffffffffffffffffffffffffffffffffff84166128d4565b6000610be38373ffffffffffffffffffffffffffffffffffffffff8416612885565b7f00000000000000000000000000000000000000000000000000000000000000001561161e576123f1600282612d4a565b61161e576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108fb565b61244881610bea565b61248a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108fb565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612503573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125279190613ff5565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461161e576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108fb565b67ffffffffffffffff8216600090815260076020526040902061184e90827f00000000000000000000000000000000000000000000000000000000000000006129c7565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611182908490612d79565b60608160000180548060200260200160405190810160405280929190818152602001828054801561067c57602002820191906000526020600020905b81548152602001906001019080831161269a5750505050509050919050565b60006126d8856126c98486614012565b6126d39087614029565b612e85565b90505b949350505050565b815460009061270c90700100000000000000000000000000000000900463ffffffff1642613f23565b905080156127ae5760018301548354612754916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166126b9565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546127d4916fffffffffffffffffffffffffffffffff9081169116612e85565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611fbc908490613fb9565b60008181526001830160205260408120546128cc575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105d2565b5060006105d2565b600081815260018301602052604081205480156129bd5760006128f8600183613f23565b855490915060009061290c90600190613f23565b905081811461297157600086600001828154811061292c5761292c613af1565b906000526020600020015490508087600001848154811061294f5761294f613af1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806129825761298261403c565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105d2565b60009150506105d2565b825474010000000000000000000000000000000000000000900460ff1615806129ee575081155b156129f857505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612a3e90700100000000000000000000000000000000900463ffffffff1642613f23565b90508015612afe5781831115612a80576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612aba9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166126b9565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612bb55773ffffffffffffffffffffffffffffffffffffffff8416612b5d576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108fb565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108fb565b84831015612cc85760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612bf99082613f23565b612c03878a613f23565b612c0d9190614029565b612c17919061406b565b905073ffffffffffffffffffffffffffffffffffffffff8616612c70576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108fb565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108fb565b612cd28584613f23565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610be3565b6000612ddb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612e9b9092919063ffffffff16565b8051909150156111825780806020019051810190612df99190613a32565b611182576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108fb565b6000818310612e945781610be3565b5090919050565b60606126db8484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051612ecf91906140a6565b60006040518083038185875af1925050503d8060008114612f0c576040519150601f19603f3d011682016040523d82523d6000602084013e612f11565b606091505b5091509150612f2287838387612f2d565b979650505050505050565b60608315612fc3578251600003612fbc5773ffffffffffffffffffffffffffffffffffffffff85163b612fbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108fb565b50816126db565b6126db8383815115612fd85781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108fb9190613142565b50805461301890613680565b6000825580601f10613028575050565b601f01602090049060005260206000209081019061161e91905b808211156130565760008155600101613042565b5090565b60006020828403121561306c57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610be357600080fd5b803567ffffffffffffffff811681146130b457600080fd5b919050565b6000602082840312156130cb57600080fd5b610be38261309c565b60005b838110156130ef5781810151838201526020016130d7565b50506000910152565b600081518084526131108160208601602086016130d4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610be360208301846130f8565b73ffffffffffffffffffffffffffffffffffffffff8116811461161e57600080fd5b80356130b481613155565b60006020828403121561319457600080fd5b8135610be381613155565b6000602082840312156131b157600080fd5b813567ffffffffffffffff8111156131c857600080fd5b82016101008185031215610be357600080fd5b60008083601f8401126131ed57600080fd5b50813567ffffffffffffffff81111561320557600080fd5b6020830191508360208260051b850101111561322057600080fd5b9250929050565b6000806000806040858703121561323d57600080fd5b843567ffffffffffffffff8082111561325557600080fd5b613261888389016131db565b9096509450602087013591508082111561327a57600080fd5b50613287878288016131db565b95989497509550505050565b6000806000604084860312156132a857600080fd5b6132b18461309c565b9250602084013567ffffffffffffffff808211156132ce57600080fd5b818601915086601f8301126132e257600080fd5b8135818111156132f157600080fd5b87602082850101111561330357600080fd5b6020830194508093505050509250925092565b6000806040838503121561332957600080fd5b6133328361309c565b9150602083013561334281613155565b809150509250929050565b60006020828403121561335f57600080fd5b813567ffffffffffffffff81111561337657600080fd5b820160a08185031215610be357600080fd5b6020815260008251604060208401526133a460608401826130f8565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526133df82826130f8565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561343657835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613404565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561343657835167ffffffffffffffff168352928401929184019160010161345e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156134d7576134d7613484565b60405290565b60405160c0810167ffffffffffffffff811182821017156134d7576134d7613484565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561354757613547613484565b604052919050565b801515811461161e57600080fd5b80356130b48161354f565b80356fffffffffffffffffffffffffffffffff811681146130b457600080fd5b60006060828403121561359a57600080fd5b6040516060810181811067ffffffffffffffff821117156135bd576135bd613484565b60405290508082356135ce8161354f565b81526135dc60208401613568565b60208201526135ed60408401613568565b60408201525092915050565b600080600060e0848603121561360e57600080fd5b6136178461309c565b92506136268560208601613588565b91506136358560808601613588565b90509250925092565b6000806020838503121561365157600080fd5b823567ffffffffffffffff81111561366857600080fd5b613674858286016131db565b90969095509350505050565b600181811c9082168061369457607f821691505b6020821081036136cd577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff8211156136ed576136ed613484565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261372a57600080fd5b813561373d613738826136d3565b613500565b81815284602083860101111561375257600080fd5b816020850160208301376000918101602001919091529392505050565b6000610100823603121561378257600080fd5b61378a6134b3565b823567ffffffffffffffff808211156137a257600080fd5b6137ae36838701613719565b83526137bc6020860161309c565b60208401526137cd60408601613177565b6040840152606085013560608401526137e860808601613177565b608084015260a085013591508082111561380157600080fd5b61380d36838701613719565b60a084015260c085013591508082111561382657600080fd5b61383236838701613719565b60c084015260e085013591508082111561384b57600080fd5b5061385836828601613719565b60e08301525092915050565b601f821115611182576000816000526020600020601f850160051c8101602086101561388d5750805b601f850160051c820191505b818110156138ac57828155600101613899565b505050505050565b67ffffffffffffffff8311156138cc576138cc613484565b6138e0836138da8354613680565b83613864565b6000601f84116001811461393257600085156138fc5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556118e4565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156139815786850135825560209485019460019092019101613961565b50868210156139bc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006139e160408301866130f8565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613a4457600080fd5b8151610be38161354f565b600060a08236031215613a6157600080fd5b60405160a0810167ffffffffffffffff8282108183111715613a8557613a85613484565b816040528435915080821115613a9a57600080fd5b50613aa736828601613719565b825250613ab66020840161309c565b60208201526040830135613ac981613155565b6040820152606083810135908201526080830135613ae681613155565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613b5457600080fd5b9190910192915050565b60006101408236031215613b7157600080fd5b613b796134dd565b613b828361309c565b8152613b906020840161355d565b6020820152604083013567ffffffffffffffff80821115613bb057600080fd5b613bbc36838701613719565b60408401526060850135915080821115613bd557600080fd5b50613be236828601613719565b606083015250613bf53660808501613588565b6080820152613c073660e08501613588565b60a082015292915050565b815167ffffffffffffffff811115613c2c57613c2c613484565b613c4081613c3a8454613680565b84613864565b602080601f831160018114613c935760008415613c5d5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556138ac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613ce057888601518255948401946001909101908401613cc1565b5085821015613d1c57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613d50818401876130f8565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613d8e9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526133df565b60a081526000613dd860a08301876130f8565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613e5560a08301866130f8565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613e9857600080fd5b815167ffffffffffffffff811115613eaf57600080fd5b8201601f81018413613ec057600080fd5b8051613ece613738826136d3565b818152856020838501011115613ee357600080fd5b6133df8260208301602086016130d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105d2576105d2613ef4565b67ffffffffffffffff8416815260e08101613f8260208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526126db565b606081016105d282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561400757600080fd5b8151610be381613155565b80820281158282048414176105d2576105d2613ef4565b808201808211156105d2576105d2613ef4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826140a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613b548184602087016130d456fe4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", +} + +var BurnMintTokenPoolAndProxyABI = BurnMintTokenPoolAndProxyMetaData.ABI + +var BurnMintTokenPoolAndProxyBin = BurnMintTokenPoolAndProxyMetaData.Bin + +func DeployBurnMintTokenPoolAndProxy(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, rmnProxy common.Address, router common.Address) (common.Address, *types.Transaction, *BurnMintTokenPoolAndProxy, error) { + parsed, err := BurnMintTokenPoolAndProxyMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnMintTokenPoolAndProxyBin), backend, token, allowlist, rmnProxy, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &BurnMintTokenPoolAndProxy{address: address, abi: *parsed, BurnMintTokenPoolAndProxyCaller: BurnMintTokenPoolAndProxyCaller{contract: contract}, BurnMintTokenPoolAndProxyTransactor: BurnMintTokenPoolAndProxyTransactor{contract: contract}, BurnMintTokenPoolAndProxyFilterer: BurnMintTokenPoolAndProxyFilterer{contract: contract}}, nil +} + +type BurnMintTokenPoolAndProxy struct { + address common.Address + abi abi.ABI + BurnMintTokenPoolAndProxyCaller + BurnMintTokenPoolAndProxyTransactor + BurnMintTokenPoolAndProxyFilterer +} + +type BurnMintTokenPoolAndProxyCaller struct { + contract *bind.BoundContract +} + +type BurnMintTokenPoolAndProxyTransactor struct { + contract *bind.BoundContract +} + +type BurnMintTokenPoolAndProxyFilterer struct { + contract *bind.BoundContract +} + +type BurnMintTokenPoolAndProxySession struct { + Contract *BurnMintTokenPoolAndProxy + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type BurnMintTokenPoolAndProxyCallerSession struct { + Contract *BurnMintTokenPoolAndProxyCaller + CallOpts bind.CallOpts +} + +type BurnMintTokenPoolAndProxyTransactorSession struct { + Contract *BurnMintTokenPoolAndProxyTransactor + TransactOpts bind.TransactOpts +} + +type BurnMintTokenPoolAndProxyRaw struct { + Contract *BurnMintTokenPoolAndProxy +} + +type BurnMintTokenPoolAndProxyCallerRaw struct { + Contract *BurnMintTokenPoolAndProxyCaller +} + +type BurnMintTokenPoolAndProxyTransactorRaw struct { + Contract *BurnMintTokenPoolAndProxyTransactor +} + +func NewBurnMintTokenPoolAndProxy(address common.Address, backend bind.ContractBackend) (*BurnMintTokenPoolAndProxy, error) { + abi, err := abi.JSON(strings.NewReader(BurnMintTokenPoolAndProxyABI)) + if err != nil { + return nil, err + } + contract, err := bindBurnMintTokenPoolAndProxy(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxy{address: address, abi: abi, BurnMintTokenPoolAndProxyCaller: BurnMintTokenPoolAndProxyCaller{contract: contract}, BurnMintTokenPoolAndProxyTransactor: BurnMintTokenPoolAndProxyTransactor{contract: contract}, BurnMintTokenPoolAndProxyFilterer: BurnMintTokenPoolAndProxyFilterer{contract: contract}}, nil +} + +func NewBurnMintTokenPoolAndProxyCaller(address common.Address, caller bind.ContractCaller) (*BurnMintTokenPoolAndProxyCaller, error) { + contract, err := bindBurnMintTokenPoolAndProxy(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyCaller{contract: contract}, nil +} + +func NewBurnMintTokenPoolAndProxyTransactor(address common.Address, transactor bind.ContractTransactor) (*BurnMintTokenPoolAndProxyTransactor, error) { + contract, err := bindBurnMintTokenPoolAndProxy(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyTransactor{contract: contract}, nil +} + +func NewBurnMintTokenPoolAndProxyFilterer(address common.Address, filterer bind.ContractFilterer) (*BurnMintTokenPoolAndProxyFilterer, error) { + contract, err := bindBurnMintTokenPoolAndProxy(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyFilterer{contract: contract}, nil +} + +func bindBurnMintTokenPoolAndProxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := BurnMintTokenPoolAndProxyMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnMintTokenPoolAndProxy.Contract.BurnMintTokenPoolAndProxyCaller.contract.Call(opts, result, method, params...) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.BurnMintTokenPoolAndProxyTransactor.contract.Transfer(opts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.BurnMintTokenPoolAndProxyTransactor.contract.Transact(opts, method, params...) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnMintTokenPoolAndProxy.Contract.contract.Call(opts, result, method, params...) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.contract.Transfer(opts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.contract.Transact(opts, method, params...) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetAllowList() ([]common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetAllowList(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetAllowList() ([]common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetAllowList(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetAllowListEnabled() (bool, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetAllowListEnabled(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetAllowListEnabled() (bool, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetAllowListEnabled(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetCurrentInboundRateLimiterState(&_BurnMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetCurrentInboundRateLimiterState(&_BurnMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetCurrentOutboundRateLimiterState(&_BurnMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetCurrentOutboundRateLimiterState(&_BurnMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetOnRamp(opts *bind.CallOpts, arg0 uint64) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getOnRamp", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetOnRamp(arg0 uint64) (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetOnRamp(&_BurnMintTokenPoolAndProxy.CallOpts, arg0) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetOnRamp(arg0 uint64) (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetOnRamp(&_BurnMintTokenPoolAndProxy.CallOpts, arg0) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetRemotePool(&_BurnMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetRemotePool(&_BurnMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getRemoteToken", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetRemoteToken(&_BurnMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetRemoteToken(&_BurnMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetRmnProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getRmnProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetRmnProxy() (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetRmnProxy(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetRmnProxy() (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetRmnProxy(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetRouter() (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetRouter(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetRouter() (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetRouter(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetSupportedChains() ([]uint64, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetSupportedChains(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetSupportedChains() ([]uint64, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetSupportedChains(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetToken() (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetToken(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetToken() (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetToken(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) IsOffRamp(opts *bind.CallOpts, sourceChainSelector uint64, offRamp common.Address) (bool, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "isOffRamp", sourceChainSelector, offRamp) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) IsOffRamp(sourceChainSelector uint64, offRamp common.Address) (bool, error) { + return _BurnMintTokenPoolAndProxy.Contract.IsOffRamp(&_BurnMintTokenPoolAndProxy.CallOpts, sourceChainSelector, offRamp) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) IsOffRamp(sourceChainSelector uint64, offRamp common.Address) (bool, error) { + return _BurnMintTokenPoolAndProxy.Contract.IsOffRamp(&_BurnMintTokenPoolAndProxy.CallOpts, sourceChainSelector, offRamp) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _BurnMintTokenPoolAndProxy.Contract.IsSupportedChain(&_BurnMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _BurnMintTokenPoolAndProxy.Contract.IsSupportedChain(&_BurnMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "isSupportedToken", token) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) IsSupportedToken(token common.Address) (bool, error) { + return _BurnMintTokenPoolAndProxy.Contract.IsSupportedToken(&_BurnMintTokenPoolAndProxy.CallOpts, token) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) IsSupportedToken(token common.Address) (bool, error) { + return _BurnMintTokenPoolAndProxy.Contract.IsSupportedToken(&_BurnMintTokenPoolAndProxy.CallOpts, token) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) Owner() (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.Owner(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) Owner() (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.Owner(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnMintTokenPoolAndProxy.Contract.SupportsInterface(&_BurnMintTokenPoolAndProxy.CallOpts, interfaceId) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnMintTokenPoolAndProxy.Contract.SupportsInterface(&_BurnMintTokenPoolAndProxy.CallOpts, interfaceId) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) TypeAndVersion() (string, error) { + return _BurnMintTokenPoolAndProxy.Contract.TypeAndVersion(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) TypeAndVersion() (string, error) { + return _BurnMintTokenPoolAndProxy.Contract.TypeAndVersion(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.contract.Transact(opts, "acceptOwnership") +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) AcceptOwnership() (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.AcceptOwnership(&_BurnMintTokenPoolAndProxy.TransactOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.AcceptOwnership(&_BurnMintTokenPoolAndProxy.TransactOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.ApplyAllowListUpdates(&_BurnMintTokenPoolAndProxy.TransactOpts, removes, adds) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.ApplyAllowListUpdates(&_BurnMintTokenPoolAndProxy.TransactOpts, removes, adds) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.ApplyChainUpdates(&_BurnMintTokenPoolAndProxy.TransactOpts, chains) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.ApplyChainUpdates(&_BurnMintTokenPoolAndProxy.TransactOpts, chains) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.contract.Transact(opts, "lockOrBurn", lockOrBurnIn) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.LockOrBurn(&_BurnMintTokenPoolAndProxy.TransactOpts, lockOrBurnIn) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.LockOrBurn(&_BurnMintTokenPoolAndProxy.TransactOpts, lockOrBurnIn) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactor) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.contract.Transact(opts, "releaseOrMint", releaseOrMintIn) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.ReleaseOrMint(&_BurnMintTokenPoolAndProxy.TransactOpts, releaseOrMintIn) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.ReleaseOrMint(&_BurnMintTokenPoolAndProxy.TransactOpts, releaseOrMintIn) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.SetChainRateLimiterConfig(&_BurnMintTokenPoolAndProxy.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.SetChainRateLimiterConfig(&_BurnMintTokenPoolAndProxy.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactor) SetPreviousPool(opts *bind.TransactOpts, prevPool common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.contract.Transact(opts, "setPreviousPool", prevPool) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) SetPreviousPool(prevPool common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.SetPreviousPool(&_BurnMintTokenPoolAndProxy.TransactOpts, prevPool) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorSession) SetPreviousPool(prevPool common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.SetPreviousPool(&_BurnMintTokenPoolAndProxy.TransactOpts, prevPool) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.SetRemotePool(&_BurnMintTokenPoolAndProxy.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.SetRemotePool(&_BurnMintTokenPoolAndProxy.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.contract.Transact(opts, "setRouter", newRouter) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.SetRouter(&_BurnMintTokenPoolAndProxy.TransactOpts, newRouter) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.SetRouter(&_BurnMintTokenPoolAndProxy.TransactOpts, newRouter) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.contract.Transact(opts, "transferOwnership", to) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.TransferOwnership(&_BurnMintTokenPoolAndProxy.TransactOpts, to) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.TransferOwnership(&_BurnMintTokenPoolAndProxy.TransactOpts, to) +} + +type BurnMintTokenPoolAndProxyAllowListAddIterator struct { + Event *BurnMintTokenPoolAndProxyAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyAllowListAddIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyAllowListAddIterator, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyAllowListAddIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyAllowListAdd) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseAllowListAdd(log types.Log) (*BurnMintTokenPoolAndProxyAllowListAdd, error) { + event := new(BurnMintTokenPoolAndProxyAllowListAdd) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyAllowListRemoveIterator struct { + Event *BurnMintTokenPoolAndProxyAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyAllowListRemoveIterator, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyAllowListRemoveIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyAllowListRemove) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseAllowListRemove(log types.Log) (*BurnMintTokenPoolAndProxyAllowListRemove, error) { + event := new(BurnMintTokenPoolAndProxyAllowListRemove) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyBurnedIterator struct { + Event *BurnMintTokenPoolAndProxyBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyBurnedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolAndProxyBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyBurnedIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyBurned) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseBurned(log types.Log) (*BurnMintTokenPoolAndProxyBurned, error) { + event := new(BurnMintTokenPoolAndProxyBurned) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyChainAddedIterator struct { + Event *BurnMintTokenPoolAndProxyChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyChainAddedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyChainAdded struct { + RemoteChainSelector uint64 + RemoteToken []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterChainAdded(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyChainAddedIterator, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyChainAddedIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyChainAdded) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyChainAdded) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseChainAdded(log types.Log) (*BurnMintTokenPoolAndProxyChainAdded, error) { + event := new(BurnMintTokenPoolAndProxyChainAdded) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyChainConfiguredIterator struct { + Event *BurnMintTokenPoolAndProxyChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyChainConfiguredIterator, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyChainConfiguredIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyChainConfigured) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyChainConfigured) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseChainConfigured(log types.Log) (*BurnMintTokenPoolAndProxyChainConfigured, error) { + event := new(BurnMintTokenPoolAndProxyChainConfigured) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyChainRemovedIterator struct { + Event *BurnMintTokenPoolAndProxyChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyChainRemovedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyChainRemovedIterator, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyChainRemovedIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyChainRemoved) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyChainRemoved) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseChainRemoved(log types.Log) (*BurnMintTokenPoolAndProxyChainRemoved, error) { + event := new(BurnMintTokenPoolAndProxyChainRemoved) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyConfigChangedIterator struct { + Event *BurnMintTokenPoolAndProxyConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyConfigChangedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyConfigChanged struct { + Config RateLimiterConfig + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyConfigChangedIterator, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyConfigChangedIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyConfigChanged) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyConfigChanged) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseConfigChanged(log types.Log) (*BurnMintTokenPoolAndProxyConfigChanged, error) { + event := new(BurnMintTokenPoolAndProxyConfigChanged) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyLegacyPoolChangedIterator struct { + Event *BurnMintTokenPoolAndProxyLegacyPoolChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyLegacyPoolChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyLegacyPoolChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyLegacyPoolChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyLegacyPoolChangedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyLegacyPoolChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyLegacyPoolChanged struct { + OldPool common.Address + NewPool common.Address + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterLegacyPoolChanged(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyLegacyPoolChangedIterator, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "LegacyPoolChanged") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyLegacyPoolChangedIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "LegacyPoolChanged", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchLegacyPoolChanged(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyLegacyPoolChanged) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "LegacyPoolChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyLegacyPoolChanged) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "LegacyPoolChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseLegacyPoolChanged(log types.Log) (*BurnMintTokenPoolAndProxyLegacyPoolChanged, error) { + event := new(BurnMintTokenPoolAndProxyLegacyPoolChanged) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "LegacyPoolChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyLockedIterator struct { + Event *BurnMintTokenPoolAndProxyLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyLockedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolAndProxyLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyLockedIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyLocked) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseLocked(log types.Log) (*BurnMintTokenPoolAndProxyLocked, error) { + event := new(BurnMintTokenPoolAndProxyLocked) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyMintedIterator struct { + Event *BurnMintTokenPoolAndProxyMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyMintedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolAndProxyMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyMintedIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyMinted) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseMinted(log types.Log) (*BurnMintTokenPoolAndProxyMinted, error) { + event := new(BurnMintTokenPoolAndProxyMinted) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyOwnershipTransferRequestedIterator struct { + Event *BurnMintTokenPoolAndProxyOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolAndProxyOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyOwnershipTransferRequestedIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyOwnershipTransferRequested) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseOwnershipTransferRequested(log types.Log) (*BurnMintTokenPoolAndProxyOwnershipTransferRequested, error) { + event := new(BurnMintTokenPoolAndProxyOwnershipTransferRequested) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyOwnershipTransferredIterator struct { + Event *BurnMintTokenPoolAndProxyOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolAndProxyOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyOwnershipTransferredIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyOwnershipTransferred) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseOwnershipTransferred(log types.Log) (*BurnMintTokenPoolAndProxyOwnershipTransferred, error) { + event := new(BurnMintTokenPoolAndProxyOwnershipTransferred) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyReleasedIterator struct { + Event *BurnMintTokenPoolAndProxyReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyReleasedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolAndProxyReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyReleasedIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyReleased) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseReleased(log types.Log) (*BurnMintTokenPoolAndProxyReleased, error) { + event := new(BurnMintTokenPoolAndProxyReleased) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyRemotePoolSetIterator struct { + Event *BurnMintTokenPoolAndProxyRemotePoolSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyRemotePoolSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyRemotePoolSetIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyRemotePoolSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyRemotePoolSet struct { + RemoteChainSelector uint64 + PreviousPoolAddress []byte + RemotePoolAddress []byte + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnMintTokenPoolAndProxyRemotePoolSetIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyRemotePoolSetIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyRemotePoolSet) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseRemotePoolSet(log types.Log) (*BurnMintTokenPoolAndProxyRemotePoolSet, error) { + event := new(BurnMintTokenPoolAndProxyRemotePoolSet) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyRouterUpdatedIterator struct { + Event *BurnMintTokenPoolAndProxyRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyRouterUpdatedIterator, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyRouterUpdatedIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyRouterUpdated) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseRouterUpdated(log types.Log) (*BurnMintTokenPoolAndProxyRouterUpdated, error) { + event := new(BurnMintTokenPoolAndProxyRouterUpdated) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolAndProxyTokensConsumedIterator struct { + Event *BurnMintTokenPoolAndProxyTokensConsumed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolAndProxyTokensConsumedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolAndProxyTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnMintTokenPoolAndProxyTokensConsumedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolAndProxyTokensConsumedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolAndProxyTokensConsumed struct { + Tokens *big.Int + Raw types.Log +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) FilterTokensConsumed(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyTokensConsumedIterator, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.FilterLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return &BurnMintTokenPoolAndProxyTokensConsumedIterator{contract: _BurnMintTokenPoolAndProxy.contract, event: "TokensConsumed", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyTokensConsumed) (event.Subscription, error) { + + logs, sub, err := _BurnMintTokenPoolAndProxy.contract.WatchLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolAndProxyTokensConsumed) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyFilterer) ParseTokensConsumed(log types.Log) (*BurnMintTokenPoolAndProxyTokensConsumed, error) { + event := new(BurnMintTokenPoolAndProxyTokensConsumed) + if err := _BurnMintTokenPoolAndProxy.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxy) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _BurnMintTokenPoolAndProxy.abi.Events["AllowListAdd"].ID: + return _BurnMintTokenPoolAndProxy.ParseAllowListAdd(log) + case _BurnMintTokenPoolAndProxy.abi.Events["AllowListRemove"].ID: + return _BurnMintTokenPoolAndProxy.ParseAllowListRemove(log) + case _BurnMintTokenPoolAndProxy.abi.Events["Burned"].ID: + return _BurnMintTokenPoolAndProxy.ParseBurned(log) + case _BurnMintTokenPoolAndProxy.abi.Events["ChainAdded"].ID: + return _BurnMintTokenPoolAndProxy.ParseChainAdded(log) + case _BurnMintTokenPoolAndProxy.abi.Events["ChainConfigured"].ID: + return _BurnMintTokenPoolAndProxy.ParseChainConfigured(log) + case _BurnMintTokenPoolAndProxy.abi.Events["ChainRemoved"].ID: + return _BurnMintTokenPoolAndProxy.ParseChainRemoved(log) + case _BurnMintTokenPoolAndProxy.abi.Events["ConfigChanged"].ID: + return _BurnMintTokenPoolAndProxy.ParseConfigChanged(log) + case _BurnMintTokenPoolAndProxy.abi.Events["LegacyPoolChanged"].ID: + return _BurnMintTokenPoolAndProxy.ParseLegacyPoolChanged(log) + case _BurnMintTokenPoolAndProxy.abi.Events["Locked"].ID: + return _BurnMintTokenPoolAndProxy.ParseLocked(log) + case _BurnMintTokenPoolAndProxy.abi.Events["Minted"].ID: + return _BurnMintTokenPoolAndProxy.ParseMinted(log) + case _BurnMintTokenPoolAndProxy.abi.Events["OwnershipTransferRequested"].ID: + return _BurnMintTokenPoolAndProxy.ParseOwnershipTransferRequested(log) + case _BurnMintTokenPoolAndProxy.abi.Events["OwnershipTransferred"].ID: + return _BurnMintTokenPoolAndProxy.ParseOwnershipTransferred(log) + case _BurnMintTokenPoolAndProxy.abi.Events["Released"].ID: + return _BurnMintTokenPoolAndProxy.ParseReleased(log) + case _BurnMintTokenPoolAndProxy.abi.Events["RemotePoolSet"].ID: + return _BurnMintTokenPoolAndProxy.ParseRemotePoolSet(log) + case _BurnMintTokenPoolAndProxy.abi.Events["RouterUpdated"].ID: + return _BurnMintTokenPoolAndProxy.ParseRouterUpdated(log) + case _BurnMintTokenPoolAndProxy.abi.Events["TokensConsumed"].ID: + return _BurnMintTokenPoolAndProxy.ParseTokensConsumed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (BurnMintTokenPoolAndProxyAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (BurnMintTokenPoolAndProxyAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (BurnMintTokenPoolAndProxyBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (BurnMintTokenPoolAndProxyChainAdded) Topic() common.Hash { + return common.HexToHash("0x8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2") +} + +func (BurnMintTokenPoolAndProxyChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (BurnMintTokenPoolAndProxyChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (BurnMintTokenPoolAndProxyConfigChanged) Topic() common.Hash { + return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") +} + +func (BurnMintTokenPoolAndProxyLegacyPoolChanged) Topic() common.Hash { + return common.HexToHash("0x81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f228") +} + +func (BurnMintTokenPoolAndProxyLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (BurnMintTokenPoolAndProxyMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (BurnMintTokenPoolAndProxyOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (BurnMintTokenPoolAndProxyOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (BurnMintTokenPoolAndProxyReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (BurnMintTokenPoolAndProxyRemotePoolSet) Topic() common.Hash { + return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +} + +func (BurnMintTokenPoolAndProxyRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (BurnMintTokenPoolAndProxyTokensConsumed) Topic() common.Hash { + return common.HexToHash("0x1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a") +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxy) Address() common.Address { + return _BurnMintTokenPoolAndProxy.address +} + +type BurnMintTokenPoolAndProxyInterface interface { + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetOnRamp(opts *bind.CallOpts, arg0 uint64) (common.Address, error) + + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRmnProxy(opts *bind.CallOpts) (common.Address, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsOffRamp(opts *bind.CallOpts, sourceChainSelector uint64, offRamp common.Address) (bool, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetPreviousPool(opts *bind.TransactOpts, prevPool common.Address) (*types.Transaction, error) + + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*BurnMintTokenPoolAndProxyAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*BurnMintTokenPoolAndProxyAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolAndProxyBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*BurnMintTokenPoolAndProxyBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*BurnMintTokenPoolAndProxyChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*BurnMintTokenPoolAndProxyChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*BurnMintTokenPoolAndProxyChainRemoved, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*BurnMintTokenPoolAndProxyConfigChanged, error) + + FilterLegacyPoolChanged(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyLegacyPoolChangedIterator, error) + + WatchLegacyPoolChanged(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyLegacyPoolChanged) (event.Subscription, error) + + ParseLegacyPoolChanged(log types.Log) (*BurnMintTokenPoolAndProxyLegacyPoolChanged, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnMintTokenPoolAndProxyLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*BurnMintTokenPoolAndProxyLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolAndProxyMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*BurnMintTokenPoolAndProxyMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolAndProxyOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*BurnMintTokenPoolAndProxyOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintTokenPoolAndProxyOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*BurnMintTokenPoolAndProxyOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnMintTokenPoolAndProxyReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*BurnMintTokenPoolAndProxyReleased, error) + + FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnMintTokenPoolAndProxyRemotePoolSetIterator, error) + + WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolSet(log types.Log) (*BurnMintTokenPoolAndProxyRemotePoolSet, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*BurnMintTokenPoolAndProxyRouterUpdated, error) + + FilterTokensConsumed(opts *bind.FilterOpts) (*BurnMintTokenPoolAndProxyTokensConsumedIterator, error) + + WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolAndProxyTokensConsumed) (event.Subscription, error) + + ParseTokensConsumed(log types.Log) (*BurnMintTokenPoolAndProxyTokensConsumed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go new file mode 100644 index 0000000000..07489bbb01 --- /dev/null +++ b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go @@ -0,0 +1,2780 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package burn_with_from_mint_token_pool + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type PoolLockOrBurnInV1 struct { + Receiver []byte + RemoteChainSelector uint64 + OriginalSender common.Address + Amount *big.Int + LocalToken common.Address +} + +type PoolLockOrBurnOutV1 struct { + DestTokenAddress []byte + DestPoolData []byte +} + +type PoolReleaseOrMintInV1 struct { + OriginalSender []byte + RemoteChainSelector uint64 + Receiver common.Address + Amount *big.Int + LocalToken common.Address + SourcePoolAddress []byte + SourcePoolData []byte + OffchainTokenData []byte +} + +type PoolReleaseOrMintOutV1 struct { + DestinationAmount *big.Int +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + RemotePoolAddress []byte + RemoteTokenAddress []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +var BurnWithFromMintTokenPoolMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b50604051620043e4380380620043e48339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161386b62000b79600039600081816104620152818161162d015261201101526000818161043c0152818161145e01526118e30152600081816101ef01528181610244015281816106a20152818161137e01528181611803015281816119fb01528181611fa701526121fc015261386b6000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c8063a7cd63b7116100e3578063c75eea9c1161008c578063dc0bd97111610066578063dc0bd9711461043a578063e0351e1314610460578063f2fde38b1461048657600080fd5b8063c75eea9c14610401578063cf7401f314610414578063db6327dc1461042757600080fd5b8063b7946580116100bd578063b7946580146103c6578063c0d78655146103d9578063c4bffe2b146103ec57600080fd5b8063a7cd63b714610324578063af58d59f14610339578063b0f479a1146103a857600080fd5b806354c8a4f3116101455780638926f54f1161011f5780638926f54f146102d35780638da5cb5b146102e65780639a4575b91461030457600080fd5b806354c8a4f3146102a357806378a010b2146102b857806379ba5097146102cb57600080fd5b806321df0da71161017657806321df0da7146101ed578063240028e814610234578063390775371461028157600080fd5b806301ffc9a71461019d5780630a2fd493146101c5578063181f5a77146101e5575b600080fd5b6101b06101ab36600461299f565b610499565b60405190151581526020015b60405180910390f35b6101d86101d33660046129fe565b61057e565b6040516101bc9190612a7d565b6101d861062e565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b6101b0610242366004612abd565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61029461028f366004612ada565b61064a565b604051905181526020016101bc565b6102b66102b1366004612b62565b6107a5565b005b6102b66102c6366004612bce565b610820565b6102b6610994565b6101b06102e13660046129fe565b610a91565b60005473ffffffffffffffffffffffffffffffffffffffff1661020f565b610317610312366004612c51565b610aa8565b6040516101bc9190612c8c565b61032c610b4f565b6040516101bc9190612cec565b61034c6103473660046129fe565b610b60565b6040516101bc919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff1661020f565b6101d86103d43660046129fe565b610c35565b6102b66103e7366004612abd565b610c60565b6103f4610d3b565b6040516101bc9190612d46565b61034c61040f3660046129fe565b610df3565b6102b6610422366004612eae565b610ec5565b6102b6610435366004612ef3565b610edd565b7f000000000000000000000000000000000000000000000000000000000000000061020f565b7f00000000000000000000000000000000000000000000000000000000000000006101b0565b6102b6610494366004612abd565b611363565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061052c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061057857507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906105a990612f35565b80601f01602080910402602001604051908101604052809291908181526020018280546105d590612f35565b80156106225780601f106105f757610100808354040283529160200191610622565b820191906000526020600020905b81548152906001019060200180831161060557829003601f168201915b50505050509050919050565b60405180606001604052806023815260200161383c6023913981565b60408051602081019091526000815261066a61066583613033565b611377565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b1580156106fb57600080fd5b505af115801561070f573d6000803e3d6000fd5b50610724925050506060830160408401612abd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161078691815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6107ad6115a8565b61081a8484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061162b92505050565b50505050565b6108286115a8565b61083183610a91565b610878576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461089f90612f35565b80601f01602080910402602001604051908101604052809291908181526020018280546108cb90612f35565b80156109185780601f106108ed57610100808354040283529160200191610918565b820191906000526020600020905b8154815290600101906020018083116108fb57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610947838583613178565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf82858560405161098693929190613292565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161086f565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000610578600567ffffffffffffffff84166117e1565b6040805180820190915260608082526020820152610acd610ac8836132f6565b6117fc565b610ada82606001356119c6565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b348460200160208101906103d491906129fe565b81526040805160208181019092526000815291015292915050565b6060610b5b6002611a6f565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261057890611a7c565b67ffffffffffffffff811660009081526007602052604090206005018054606091906105a990612f35565b610c686115a8565b73ffffffffffffffffffffffffffffffffffffffff8116610cb5576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610d496005611a6f565b90506000815167ffffffffffffffff811115610d6757610d67612d88565b604051908082528060200260200182016040528015610d90578160200160208202803683370190505b50905060005b8251811015610dec57828181518110610db157610db1613398565b6020026020010151828281518110610dcb57610dcb613398565b67ffffffffffffffff90921660209283029190910190910152600101610d96565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261057890611a7c565b610ecd6115a8565b610ed8838383611b2e565b505050565b610ee56115a8565b60005b81811015610ed8576000838383818110610f0457610f04613398565b9050602002810190610f1691906133c7565b610f1f90613405565b9050610f348160800151826020015115611c18565b610f478160a00151826020015115611c18565b806020015115611243578051610f699060059067ffffffffffffffff16611d51565b610fae5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161086f565b6040810151511580610fc35750606081015151155b15610ffa576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906111db90826134b9565b50606082015160058201906111f090826134b9565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061123694939291906135d3565b60405180910390a161135a565b805161125b9060059067ffffffffffffffff16611d5d565b6112a05780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161086f565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906113096004830182612951565b611317600583016000612951565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101610ee8565b61136b6115a8565b61137481611d69565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461140c5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161086f565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156114ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114de919061366c565b15611515576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115228160200151611e5e565b6000611531826020015161057e565b9050805160001480611555575080805190602001208260a001518051906020012014155b15611592578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161086f9190612a7d565b6115a482602001518360600151611f84565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161086f565b565b7f0000000000000000000000000000000000000000000000000000000000000000611682576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156117185760008382815181106116a2576116a2613398565b602002602001015190506116c0816002611fcb90919063ffffffff16565b1561170f5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611685565b5060005b8151811015610ed857600082828151811061173957611739613398565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361177d57506117d9565b611788600282611fed565b156117d75760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161171c565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146118915760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161086f565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561193f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611963919061366c565b1561199a576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119a7816040015161200f565b6119b4816020015161208e565b611374816020015182606001516121dc565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b158015611a5457600080fd5b505af1158015611a68573d6000803e3d6000fd5b5050505050565b606060006117f583612220565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611b0a82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611aee91906136b8565b85608001516fffffffffffffffffffffffffffffffff1661227b565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611b3783610a91565b611b79576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161086f565b611b84826000611c18565b67ffffffffffffffff83166000908152600760205260409020611ba790836122a5565b611bb2816000611c18565b67ffffffffffffffff83166000908152600760205260409020611bd890600201826122a5565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611c0b939291906136cb565b60405180910390a1505050565b815115611cdf5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611c6e575060408201516fffffffffffffffffffffffffffffffff16155b15611ca757816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161086f919061374e565b80156115a4576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611d18575060208201516fffffffffffffffffffffffffffffffff1615155b156115a457816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161086f919061374e565b60006117f58383612447565b60006117f58383612496565b3373ffffffffffffffffffffffffffffffffffffffff821603611de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161086f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611e6781610a91565b611ea9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161086f565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015611f28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4c919061366c565b611374576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161086f565b67ffffffffffffffff821660009081526007602052604090206115a490600201827f0000000000000000000000000000000000000000000000000000000000000000612589565b60006117f58373ffffffffffffffffffffffffffffffffffffffff8416612496565b60006117f58373ffffffffffffffffffffffffffffffffffffffff8416612447565b7f0000000000000000000000000000000000000000000000000000000000000000156113745761204060028261290c565b611374576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161086f565b61209781610a91565b6120d9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161086f565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612152573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612176919061378a565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611374576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161086f565b67ffffffffffffffff821660009081526007602052604090206115a490827f0000000000000000000000000000000000000000000000000000000000000000612589565b60608160000180548060200260200160405190810160405280929190818152602001828054801561062257602002820191906000526020600020905b81548152602001906001019080831161225c5750505050509050919050565b600061229a8561228b84866137a7565b61229590876137be565b61293b565b90505b949350505050565b81546000906122ce90700100000000000000000000000000000000900463ffffffff16426136b8565b905080156123705760018301548354612316916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661227b565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612396916fffffffffffffffffffffffffffffffff908116911661293b565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611c0b90849061374e565b600081815260018301602052604081205461248e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610578565b506000610578565b6000818152600183016020526040812054801561257f5760006124ba6001836136b8565b85549091506000906124ce906001906136b8565b90508181146125335760008660000182815481106124ee576124ee613398565b906000526020600020015490508087600001848154811061251157612511613398565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612544576125446137d1565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610578565b6000915050610578565b825474010000000000000000000000000000000000000000900460ff1615806125b0575081155b156125ba57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061260090700100000000000000000000000000000000900463ffffffff16426136b8565b905080156126c05781831115612642576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461267c9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661227b565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156127775773ffffffffffffffffffffffffffffffffffffffff841661271f576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161086f565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161086f565b8483101561288a5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906127bb90826136b8565b6127c5878a6136b8565b6127cf91906137be565b6127d99190613800565b905073ffffffffffffffffffffffffffffffffffffffff8616612832576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161086f565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161086f565b61289485846136b8565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156117f5565b600081831061294a57816117f5565b5090919050565b50805461295d90612f35565b6000825580601f1061296d575050565b601f01602090049060005260206000209081019061137491905b8082111561299b5760008155600101612987565b5090565b6000602082840312156129b157600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146117f557600080fd5b803567ffffffffffffffff811681146129f957600080fd5b919050565b600060208284031215612a1057600080fd5b6117f5826129e1565b6000815180845260005b81811015612a3f57602081850181015186830182015201612a23565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006117f56020830184612a19565b73ffffffffffffffffffffffffffffffffffffffff8116811461137457600080fd5b80356129f981612a90565b600060208284031215612acf57600080fd5b81356117f581612a90565b600060208284031215612aec57600080fd5b813567ffffffffffffffff811115612b0357600080fd5b820161010081850312156117f557600080fd5b60008083601f840112612b2857600080fd5b50813567ffffffffffffffff811115612b4057600080fd5b6020830191508360208260051b8501011115612b5b57600080fd5b9250929050565b60008060008060408587031215612b7857600080fd5b843567ffffffffffffffff80821115612b9057600080fd5b612b9c88838901612b16565b90965094506020870135915080821115612bb557600080fd5b50612bc287828801612b16565b95989497509550505050565b600080600060408486031215612be357600080fd5b612bec846129e1565b9250602084013567ffffffffffffffff80821115612c0957600080fd5b818601915086601f830112612c1d57600080fd5b813581811115612c2c57600080fd5b876020828501011115612c3e57600080fd5b6020830194508093505050509250925092565b600060208284031215612c6357600080fd5b813567ffffffffffffffff811115612c7a57600080fd5b820160a081850312156117f557600080fd5b602081526000825160406020840152612ca86060840182612a19565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612ce38282612a19565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d3a57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612d08565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d3a57835167ffffffffffffffff1683529284019291840191600101612d62565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612ddb57612ddb612d88565b60405290565b60405160c0810167ffffffffffffffff81118282101715612ddb57612ddb612d88565b801515811461137457600080fd5b80356129f981612e04565b80356fffffffffffffffffffffffffffffffff811681146129f957600080fd5b600060608284031215612e4f57600080fd5b6040516060810181811067ffffffffffffffff82111715612e7257612e72612d88565b6040529050808235612e8381612e04565b8152612e9160208401612e1d565b6020820152612ea260408401612e1d565b60408201525092915050565b600080600060e08486031215612ec357600080fd5b612ecc846129e1565b9250612edb8560208601612e3d565b9150612eea8560808601612e3d565b90509250925092565b60008060208385031215612f0657600080fd5b823567ffffffffffffffff811115612f1d57600080fd5b612f2985828601612b16565b90969095509350505050565b600181811c90821680612f4957607f821691505b602082108103612f82577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f830112612f9957600080fd5b813567ffffffffffffffff80821115612fb457612fb4612d88565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ffa57612ffa612d88565b8160405283815286602085880101111561301357600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561304657600080fd5b61304e612db7565b823567ffffffffffffffff8082111561306657600080fd5b61307236838701612f88565b8352613080602086016129e1565b602084015261309160408601612ab2565b6040840152606085013560608401526130ac60808601612ab2565b608084015260a08501359150808211156130c557600080fd5b6130d136838701612f88565b60a084015260c08501359150808211156130ea57600080fd5b6130f636838701612f88565b60c084015260e085013591508082111561310f57600080fd5b5061311c36828601612f88565b60e08301525092915050565b601f821115610ed8576000816000526020600020601f850160051c810160208610156131515750805b601f850160051c820191505b818110156131705782815560010161315d565b505050505050565b67ffffffffffffffff83111561319057613190612d88565b6131a48361319e8354612f35565b83613128565b6000601f8411600181146131f657600085156131c05750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a68565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156132455786850135825560209485019460019092019101613225565b5086821015613280577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006132a56040830186612a19565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561330857600080fd5b60405160a0810167ffffffffffffffff828210818311171561332c5761332c612d88565b81604052843591508082111561334157600080fd5b5061334e36828601612f88565b82525061335d602084016129e1565b6020820152604083013561337081612a90565b604082015260608381013590820152608083013561338d81612a90565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126133fb57600080fd5b9190910192915050565b6000610140823603121561341857600080fd5b613420612de1565b613429836129e1565b815261343760208401612e12565b6020820152604083013567ffffffffffffffff8082111561345757600080fd5b61346336838701612f88565b6040840152606085013591508082111561347c57600080fd5b5061348936828601612f88565b60608301525061349c3660808501612e3d565b60808201526134ae3660e08501612e3d565b60a082015292915050565b815167ffffffffffffffff8111156134d3576134d3612d88565b6134e7816134e18454612f35565b84613128565b602080601f83116001811461353a57600084156135045750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613170565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561358757888601518255948401946001909101908401613568565b50858210156135c357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526135f781840187612a19565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506136359050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612ce3565b60006020828403121561367e57600080fd5b81516117f581612e04565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561057857610578613689565b67ffffffffffffffff8416815260e0810161371760208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261229d565b6060810161057882848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561379c57600080fd5b81516117f581612a90565b808202811582820484141761057857610578613689565b8082018082111561057857610578613689565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613836577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fe4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e302d646576a164736f6c6343000818000a", +} + +var BurnWithFromMintTokenPoolABI = BurnWithFromMintTokenPoolMetaData.ABI + +var BurnWithFromMintTokenPoolBin = BurnWithFromMintTokenPoolMetaData.Bin + +func DeployBurnWithFromMintTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, rmnProxy common.Address, router common.Address) (common.Address, *types.Transaction, *BurnWithFromMintTokenPool, error) { + parsed, err := BurnWithFromMintTokenPoolMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnWithFromMintTokenPoolBin), backend, token, allowlist, rmnProxy, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &BurnWithFromMintTokenPool{address: address, abi: *parsed, BurnWithFromMintTokenPoolCaller: BurnWithFromMintTokenPoolCaller{contract: contract}, BurnWithFromMintTokenPoolTransactor: BurnWithFromMintTokenPoolTransactor{contract: contract}, BurnWithFromMintTokenPoolFilterer: BurnWithFromMintTokenPoolFilterer{contract: contract}}, nil +} + +type BurnWithFromMintTokenPool struct { + address common.Address + abi abi.ABI + BurnWithFromMintTokenPoolCaller + BurnWithFromMintTokenPoolTransactor + BurnWithFromMintTokenPoolFilterer +} + +type BurnWithFromMintTokenPoolCaller struct { + contract *bind.BoundContract +} + +type BurnWithFromMintTokenPoolTransactor struct { + contract *bind.BoundContract +} + +type BurnWithFromMintTokenPoolFilterer struct { + contract *bind.BoundContract +} + +type BurnWithFromMintTokenPoolSession struct { + Contract *BurnWithFromMintTokenPool + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type BurnWithFromMintTokenPoolCallerSession struct { + Contract *BurnWithFromMintTokenPoolCaller + CallOpts bind.CallOpts +} + +type BurnWithFromMintTokenPoolTransactorSession struct { + Contract *BurnWithFromMintTokenPoolTransactor + TransactOpts bind.TransactOpts +} + +type BurnWithFromMintTokenPoolRaw struct { + Contract *BurnWithFromMintTokenPool +} + +type BurnWithFromMintTokenPoolCallerRaw struct { + Contract *BurnWithFromMintTokenPoolCaller +} + +type BurnWithFromMintTokenPoolTransactorRaw struct { + Contract *BurnWithFromMintTokenPoolTransactor +} + +func NewBurnWithFromMintTokenPool(address common.Address, backend bind.ContractBackend) (*BurnWithFromMintTokenPool, error) { + abi, err := abi.JSON(strings.NewReader(BurnWithFromMintTokenPoolABI)) + if err != nil { + return nil, err + } + contract, err := bindBurnWithFromMintTokenPool(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPool{address: address, abi: abi, BurnWithFromMintTokenPoolCaller: BurnWithFromMintTokenPoolCaller{contract: contract}, BurnWithFromMintTokenPoolTransactor: BurnWithFromMintTokenPoolTransactor{contract: contract}, BurnWithFromMintTokenPoolFilterer: BurnWithFromMintTokenPoolFilterer{contract: contract}}, nil +} + +func NewBurnWithFromMintTokenPoolCaller(address common.Address, caller bind.ContractCaller) (*BurnWithFromMintTokenPoolCaller, error) { + contract, err := bindBurnWithFromMintTokenPool(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolCaller{contract: contract}, nil +} + +func NewBurnWithFromMintTokenPoolTransactor(address common.Address, transactor bind.ContractTransactor) (*BurnWithFromMintTokenPoolTransactor, error) { + contract, err := bindBurnWithFromMintTokenPool(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolTransactor{contract: contract}, nil +} + +func NewBurnWithFromMintTokenPoolFilterer(address common.Address, filterer bind.ContractFilterer) (*BurnWithFromMintTokenPoolFilterer, error) { + contract, err := bindBurnWithFromMintTokenPool(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolFilterer{contract: contract}, nil +} + +func bindBurnWithFromMintTokenPool(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := BurnWithFromMintTokenPoolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnWithFromMintTokenPool.Contract.BurnWithFromMintTokenPoolCaller.contract.Call(opts, result, method, params...) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.BurnWithFromMintTokenPoolTransactor.contract.Transfer(opts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.BurnWithFromMintTokenPoolTransactor.contract.Transact(opts, method, params...) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnWithFromMintTokenPool.Contract.contract.Call(opts, result, method, params...) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.contract.Transfer(opts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.contract.Transact(opts, method, params...) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetAllowList() ([]common.Address, error) { + return _BurnWithFromMintTokenPool.Contract.GetAllowList(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetAllowList() ([]common.Address, error) { + return _BurnWithFromMintTokenPool.Contract.GetAllowList(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetAllowListEnabled() (bool, error) { + return _BurnWithFromMintTokenPool.Contract.GetAllowListEnabled(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetAllowListEnabled() (bool, error) { + return _BurnWithFromMintTokenPool.Contract.GetAllowListEnabled(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnWithFromMintTokenPool.Contract.GetCurrentInboundRateLimiterState(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnWithFromMintTokenPool.Contract.GetCurrentInboundRateLimiterState(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnWithFromMintTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnWithFromMintTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _BurnWithFromMintTokenPool.Contract.GetRemotePool(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _BurnWithFromMintTokenPool.Contract.GetRemotePool(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getRemoteToken", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _BurnWithFromMintTokenPool.Contract.GetRemoteToken(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _BurnWithFromMintTokenPool.Contract.GetRemoteToken(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetRmnProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getRmnProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetRmnProxy() (common.Address, error) { + return _BurnWithFromMintTokenPool.Contract.GetRmnProxy(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetRmnProxy() (common.Address, error) { + return _BurnWithFromMintTokenPool.Contract.GetRmnProxy(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetRouter() (common.Address, error) { + return _BurnWithFromMintTokenPool.Contract.GetRouter(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetRouter() (common.Address, error) { + return _BurnWithFromMintTokenPool.Contract.GetRouter(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetSupportedChains() ([]uint64, error) { + return _BurnWithFromMintTokenPool.Contract.GetSupportedChains(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetSupportedChains() ([]uint64, error) { + return _BurnWithFromMintTokenPool.Contract.GetSupportedChains(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetToken() (common.Address, error) { + return _BurnWithFromMintTokenPool.Contract.GetToken(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetToken() (common.Address, error) { + return _BurnWithFromMintTokenPool.Contract.GetToken(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _BurnWithFromMintTokenPool.Contract.IsSupportedChain(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _BurnWithFromMintTokenPool.Contract.IsSupportedChain(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "isSupportedToken", token) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) IsSupportedToken(token common.Address) (bool, error) { + return _BurnWithFromMintTokenPool.Contract.IsSupportedToken(&_BurnWithFromMintTokenPool.CallOpts, token) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) IsSupportedToken(token common.Address) (bool, error) { + return _BurnWithFromMintTokenPool.Contract.IsSupportedToken(&_BurnWithFromMintTokenPool.CallOpts, token) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) Owner() (common.Address, error) { + return _BurnWithFromMintTokenPool.Contract.Owner(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) Owner() (common.Address, error) { + return _BurnWithFromMintTokenPool.Contract.Owner(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnWithFromMintTokenPool.Contract.SupportsInterface(&_BurnWithFromMintTokenPool.CallOpts, interfaceId) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnWithFromMintTokenPool.Contract.SupportsInterface(&_BurnWithFromMintTokenPool.CallOpts, interfaceId) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) TypeAndVersion() (string, error) { + return _BurnWithFromMintTokenPool.Contract.TypeAndVersion(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) TypeAndVersion() (string, error) { + return _BurnWithFromMintTokenPool.Contract.TypeAndVersion(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "acceptOwnership") +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.AcceptOwnership(&_BurnWithFromMintTokenPool.TransactOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.AcceptOwnership(&_BurnWithFromMintTokenPool.TransactOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnWithFromMintTokenPool.TransactOpts, removes, adds) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnWithFromMintTokenPool.TransactOpts, removes, adds) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.ApplyChainUpdates(&_BurnWithFromMintTokenPool.TransactOpts, chains) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.ApplyChainUpdates(&_BurnWithFromMintTokenPool.TransactOpts, chains) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "lockOrBurn", lockOrBurnIn) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.LockOrBurn(&_BurnWithFromMintTokenPool.TransactOpts, lockOrBurnIn) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.LockOrBurn(&_BurnWithFromMintTokenPool.TransactOpts, lockOrBurnIn) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "releaseOrMint", releaseOrMintIn) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.ReleaseOrMint(&_BurnWithFromMintTokenPool.TransactOpts, releaseOrMintIn) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.ReleaseOrMint(&_BurnWithFromMintTokenPool.TransactOpts, releaseOrMintIn) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.SetRemotePool(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.SetRemotePool(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "setRouter", newRouter) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.SetRouter(&_BurnWithFromMintTokenPool.TransactOpts, newRouter) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.SetRouter(&_BurnWithFromMintTokenPool.TransactOpts, newRouter) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "transferOwnership", to) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.TransferOwnership(&_BurnWithFromMintTokenPool.TransactOpts, to) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.TransferOwnership(&_BurnWithFromMintTokenPool.TransactOpts, to) +} + +type BurnWithFromMintTokenPoolAllowListAddIterator struct { + Event *BurnWithFromMintTokenPoolAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAllowListAddIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAllowListAddIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAllowListAddIterator{contract: _BurnWithFromMintTokenPool.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAllowListAdd) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseAllowListAdd(log types.Log) (*BurnWithFromMintTokenPoolAllowListAdd, error) { + event := new(BurnWithFromMintTokenPoolAllowListAdd) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAllowListRemoveIterator struct { + Event *BurnWithFromMintTokenPoolAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAllowListRemoveIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAllowListRemoveIterator{contract: _BurnWithFromMintTokenPool.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAllowListRemove) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseAllowListRemove(log types.Log) (*BurnWithFromMintTokenPoolAllowListRemove, error) { + event := new(BurnWithFromMintTokenPoolAllowListRemove) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolBurnedIterator struct { + Event *BurnWithFromMintTokenPoolBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolBurnedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnWithFromMintTokenPoolBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolBurnedIterator{contract: _BurnWithFromMintTokenPool.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolBurned) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseBurned(log types.Log) (*BurnWithFromMintTokenPoolBurned, error) { + event := new(BurnWithFromMintTokenPoolBurned) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolChainAddedIterator struct { + Event *BurnWithFromMintTokenPoolChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolChainAddedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolChainAdded struct { + RemoteChainSelector uint64 + RemoteToken []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterChainAdded(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolChainAddedIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolChainAddedIterator{contract: _BurnWithFromMintTokenPool.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolChainAdded) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolChainAdded) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseChainAdded(log types.Log) (*BurnWithFromMintTokenPoolChainAdded, error) { + event := new(BurnWithFromMintTokenPoolChainAdded) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolChainConfiguredIterator struct { + Event *BurnWithFromMintTokenPoolChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolChainConfiguredIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolChainConfiguredIterator{contract: _BurnWithFromMintTokenPool.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolChainConfigured) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolChainConfigured) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseChainConfigured(log types.Log) (*BurnWithFromMintTokenPoolChainConfigured, error) { + event := new(BurnWithFromMintTokenPoolChainConfigured) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolChainRemovedIterator struct { + Event *BurnWithFromMintTokenPoolChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolChainRemovedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolChainRemovedIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolChainRemovedIterator{contract: _BurnWithFromMintTokenPool.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolChainRemoved) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolChainRemoved) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseChainRemoved(log types.Log) (*BurnWithFromMintTokenPoolChainRemoved, error) { + event := new(BurnWithFromMintTokenPoolChainRemoved) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolConfigChangedIterator struct { + Event *BurnWithFromMintTokenPoolConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolConfigChangedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolConfigChanged struct { + Config RateLimiterConfig + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolConfigChangedIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolConfigChangedIterator{contract: _BurnWithFromMintTokenPool.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolConfigChanged) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolConfigChanged) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseConfigChanged(log types.Log) (*BurnWithFromMintTokenPoolConfigChanged, error) { + event := new(BurnWithFromMintTokenPoolConfigChanged) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolLockedIterator struct { + Event *BurnWithFromMintTokenPoolLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolLockedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnWithFromMintTokenPoolLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolLockedIterator{contract: _BurnWithFromMintTokenPool.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolLocked) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseLocked(log types.Log) (*BurnWithFromMintTokenPoolLocked, error) { + event := new(BurnWithFromMintTokenPoolLocked) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolMintedIterator struct { + Event *BurnWithFromMintTokenPoolMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolMintedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnWithFromMintTokenPoolMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolMintedIterator{contract: _BurnWithFromMintTokenPool.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolMinted) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseMinted(log types.Log) (*BurnWithFromMintTokenPoolMinted, error) { + event := new(BurnWithFromMintTokenPoolMinted) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolOwnershipTransferRequestedIterator struct { + Event *BurnWithFromMintTokenPoolOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnWithFromMintTokenPoolOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolOwnershipTransferRequestedIterator{contract: _BurnWithFromMintTokenPool.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolOwnershipTransferRequested) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseOwnershipTransferRequested(log types.Log) (*BurnWithFromMintTokenPoolOwnershipTransferRequested, error) { + event := new(BurnWithFromMintTokenPoolOwnershipTransferRequested) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolOwnershipTransferredIterator struct { + Event *BurnWithFromMintTokenPoolOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnWithFromMintTokenPoolOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolOwnershipTransferredIterator{contract: _BurnWithFromMintTokenPool.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolOwnershipTransferred) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseOwnershipTransferred(log types.Log) (*BurnWithFromMintTokenPoolOwnershipTransferred, error) { + event := new(BurnWithFromMintTokenPoolOwnershipTransferred) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolReleasedIterator struct { + Event *BurnWithFromMintTokenPoolReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolReleasedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnWithFromMintTokenPoolReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolReleasedIterator{contract: _BurnWithFromMintTokenPool.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolReleased) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseReleased(log types.Log) (*BurnWithFromMintTokenPoolReleased, error) { + event := new(BurnWithFromMintTokenPoolReleased) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolRemotePoolSetIterator struct { + Event *BurnWithFromMintTokenPoolRemotePoolSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolRemotePoolSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolRemotePoolSetIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolRemotePoolSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolRemotePoolSet struct { + RemoteChainSelector uint64 + PreviousPoolAddress []byte + RemotePoolAddress []byte + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnWithFromMintTokenPoolRemotePoolSetIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolRemotePoolSetIterator{contract: _BurnWithFromMintTokenPool.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolRemotePoolSet) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseRemotePoolSet(log types.Log) (*BurnWithFromMintTokenPoolRemotePoolSet, error) { + event := new(BurnWithFromMintTokenPoolRemotePoolSet) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolRouterUpdatedIterator struct { + Event *BurnWithFromMintTokenPoolRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolRouterUpdatedIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolRouterUpdatedIterator{contract: _BurnWithFromMintTokenPool.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolRouterUpdated) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseRouterUpdated(log types.Log) (*BurnWithFromMintTokenPoolRouterUpdated, error) { + event := new(BurnWithFromMintTokenPoolRouterUpdated) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolTokensConsumedIterator struct { + Event *BurnWithFromMintTokenPoolTokensConsumed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolTokensConsumedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolTokensConsumedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolTokensConsumedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolTokensConsumed struct { + Tokens *big.Int + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterTokensConsumed(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolTokensConsumedIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolTokensConsumedIterator{contract: _BurnWithFromMintTokenPool.contract, event: "TokensConsumed", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolTokensConsumed) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolTokensConsumed) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseTokensConsumed(log types.Log) (*BurnWithFromMintTokenPoolTokensConsumed, error) { + event := new(BurnWithFromMintTokenPoolTokensConsumed) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPool) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _BurnWithFromMintTokenPool.abi.Events["AllowListAdd"].ID: + return _BurnWithFromMintTokenPool.ParseAllowListAdd(log) + case _BurnWithFromMintTokenPool.abi.Events["AllowListRemove"].ID: + return _BurnWithFromMintTokenPool.ParseAllowListRemove(log) + case _BurnWithFromMintTokenPool.abi.Events["Burned"].ID: + return _BurnWithFromMintTokenPool.ParseBurned(log) + case _BurnWithFromMintTokenPool.abi.Events["ChainAdded"].ID: + return _BurnWithFromMintTokenPool.ParseChainAdded(log) + case _BurnWithFromMintTokenPool.abi.Events["ChainConfigured"].ID: + return _BurnWithFromMintTokenPool.ParseChainConfigured(log) + case _BurnWithFromMintTokenPool.abi.Events["ChainRemoved"].ID: + return _BurnWithFromMintTokenPool.ParseChainRemoved(log) + case _BurnWithFromMintTokenPool.abi.Events["ConfigChanged"].ID: + return _BurnWithFromMintTokenPool.ParseConfigChanged(log) + case _BurnWithFromMintTokenPool.abi.Events["Locked"].ID: + return _BurnWithFromMintTokenPool.ParseLocked(log) + case _BurnWithFromMintTokenPool.abi.Events["Minted"].ID: + return _BurnWithFromMintTokenPool.ParseMinted(log) + case _BurnWithFromMintTokenPool.abi.Events["OwnershipTransferRequested"].ID: + return _BurnWithFromMintTokenPool.ParseOwnershipTransferRequested(log) + case _BurnWithFromMintTokenPool.abi.Events["OwnershipTransferred"].ID: + return _BurnWithFromMintTokenPool.ParseOwnershipTransferred(log) + case _BurnWithFromMintTokenPool.abi.Events["Released"].ID: + return _BurnWithFromMintTokenPool.ParseReleased(log) + case _BurnWithFromMintTokenPool.abi.Events["RemotePoolSet"].ID: + return _BurnWithFromMintTokenPool.ParseRemotePoolSet(log) + case _BurnWithFromMintTokenPool.abi.Events["RouterUpdated"].ID: + return _BurnWithFromMintTokenPool.ParseRouterUpdated(log) + case _BurnWithFromMintTokenPool.abi.Events["TokensConsumed"].ID: + return _BurnWithFromMintTokenPool.ParseTokensConsumed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (BurnWithFromMintTokenPoolAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (BurnWithFromMintTokenPoolAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (BurnWithFromMintTokenPoolBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (BurnWithFromMintTokenPoolChainAdded) Topic() common.Hash { + return common.HexToHash("0x8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2") +} + +func (BurnWithFromMintTokenPoolChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (BurnWithFromMintTokenPoolChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (BurnWithFromMintTokenPoolConfigChanged) Topic() common.Hash { + return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") +} + +func (BurnWithFromMintTokenPoolLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (BurnWithFromMintTokenPoolMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (BurnWithFromMintTokenPoolOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (BurnWithFromMintTokenPoolOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (BurnWithFromMintTokenPoolReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (BurnWithFromMintTokenPoolRemotePoolSet) Topic() common.Hash { + return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +} + +func (BurnWithFromMintTokenPoolRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (BurnWithFromMintTokenPoolTokensConsumed) Topic() common.Hash { + return common.HexToHash("0x1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a") +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPool) Address() common.Address { + return _BurnWithFromMintTokenPool.address +} + +type BurnWithFromMintTokenPoolInterface interface { + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRmnProxy(opts *bind.CallOpts) (common.Address, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*BurnWithFromMintTokenPoolAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*BurnWithFromMintTokenPoolAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnWithFromMintTokenPoolBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*BurnWithFromMintTokenPoolBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*BurnWithFromMintTokenPoolChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*BurnWithFromMintTokenPoolChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*BurnWithFromMintTokenPoolChainRemoved, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*BurnWithFromMintTokenPoolConfigChanged, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnWithFromMintTokenPoolLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*BurnWithFromMintTokenPoolLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnWithFromMintTokenPoolMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*BurnWithFromMintTokenPoolMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnWithFromMintTokenPoolOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*BurnWithFromMintTokenPoolOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnWithFromMintTokenPoolOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*BurnWithFromMintTokenPoolOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnWithFromMintTokenPoolReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*BurnWithFromMintTokenPoolReleased, error) + + FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnWithFromMintTokenPoolRemotePoolSetIterator, error) + + WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolSet(log types.Log) (*BurnWithFromMintTokenPoolRemotePoolSet, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*BurnWithFromMintTokenPoolRouterUpdated, error) + + FilterTokensConsumed(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolTokensConsumedIterator, error) + + WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolTokensConsumed) (event.Subscription, error) + + ParseTokensConsumed(log types.Log) (*BurnWithFromMintTokenPoolTokensConsumed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go b/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go new file mode 100644 index 0000000000..e35a8726de --- /dev/null +++ b/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go @@ -0,0 +1,1103 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package ccip_config + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CCIPConfigTypesChainConfig struct { + Readers [][32]byte + FChain uint8 + Config []byte +} + +type CCIPConfigTypesChainConfigInfo struct { + ChainSelector uint64 + ChainConfig CCIPConfigTypesChainConfig +} + +type CCIPConfigTypesOCR3Config struct { + PluginType uint8 + ChainSelector uint64 + F uint8 + OffchainConfigVersion uint64 + OfframpAddress []byte + BootstrapP2PIds [][32]byte + P2pIds [][32]byte + Signers [][]byte + Transmitters [][]byte + OffchainConfig []byte +} + +type CCIPConfigTypesOCR3ConfigWithMeta struct { + Config CCIPConfigTypesOCR3Config + ConfigCount uint64 + ConfigDigest [32]byte +} + +var CCIPConfigMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigNotSetForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidConfigLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"currentState\",\"type\":\"uint8\"},{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"proposedState\",\"type\":\"uint8\"}],\"name\":\"InvalidConfigStateTransition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeNotInRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonExistentConfigTransition\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"set\",\"type\":\"bytes32[]\"}],\"name\":\"NotASortedSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"subset\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"superset\",\"type\":\"bytes32[]\"}],\"name\":\"NotASubset\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"NotEnoughTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfframpAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p2pIdsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"signersLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transmittersLength\",\"type\":\"uint256\"}],\"name\":\"P2PIdsLengthNotMatching\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyBootstrapP2PIds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOCR3Configs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyTransmitters\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"}],\"name\":\"WrongConfigCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigestBlueGreen\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapabilityConfigurationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"chainSelectorRemoves\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllChainConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getOCRConfig\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"bootstrapP2PIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"internalType\":\"structCCIPConfigTypes.OCR3ConfigWithMeta[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b50604051620043cc380380620043cc83398101604081905262000034916200017e565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d3565b5050506001600160a01b0316608052620001b0565b336001600160a01b038216036200012d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019157600080fd5b81516001600160a01b0381168114620001a957600080fd5b9392505050565b6080516141f9620001d360003960008181610e4e01526110e301526141f96000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80638da5cb5b11610076578063f2fde38b1161005b578063f2fde38b146101bc578063f442c89a146101cf578063fba64a7c146101e257600080fd5b80638da5cb5b1461017f578063ddc042a8146101a757600080fd5b80634bd0473f116100a75780634bd0473f1461013457806379ba5097146101545780638318ed5d1461015e57600080fd5b806301ffc9a7146100c3578063181f5a77146100eb575b600080fd5b6100d66100d1366004612f77565b6101f5565b60405190151581526020015b60405180910390f35b6101276040518060400160405280601481526020017f43434950436f6e66696720312e362e302d64657600000000000000000000000081525081565b6040516100e2919061301d565b610147610142366004613061565b61028e565b6040516100e2919061318d565b61015c61075e565b005b61012761016c36600461336a565b5060408051602081019091526000815290565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e2565b6101af610860565b6040516100e291906133cb565b61015c6101ca36600461345b565b610a52565b61015c6101dd3660046134dd565b610a66565b61015c6101f0366004613561565b610e36565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea72100000000000000000000000000000000000000000000000000000000148061028857507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b63ffffffff821660009081526005602052604081206060918360018111156102b8576102b8613096565b60018111156102c9576102c9613096565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561075257600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff16600181111561033c5761033c613096565b600181111561034d5761034d613096565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916103a59061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546103d19061361e565b801561041e5780601f106103f35761010080835404028352916020019161041e565b820191906000526020600020905b81548152906001019060200180831161040157829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561047657602002820191906000526020600020905b815481526020019060010190808311610462575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156104ce57602002820191906000526020600020905b8154815260200190600101908083116104ba575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156105a857838290600052602060002001805461051b9061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546105479061361e565b80156105945780601f1061056957610100808354040283529160200191610594565b820191906000526020600020905b81548152906001019060200180831161057757829003601f168201915b5050505050815260200190600101906104fc565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156106815783829060005260206000200180546105f49061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546106209061361e565b801561066d5780601f106106425761010080835404028352916020019161066d565b820191906000526020600020905b81548152906001019060200180831161065057829003601f168201915b5050505050815260200190600101906105d5565b5050505081526020016006820180546106999061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546106c59061361e565b80156107125780601f106106e757610100808354040283529160200191610712565b820191906000526020600020905b8154815290600101906020018083116106f557829003601f168201915b505050919092525050508152600782015467ffffffffffffffff1660208083019190915260089092015460409091015290825260019290920191016102f7565b50505050905092915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6060600061086e6003610ef7565b9050600061087c6003610f0b565b67ffffffffffffffff81111561089457610894613671565b6040519080825280602002602001820160405280156108cd57816020015b6108ba612d08565b8152602001906001900390816108b25790505b50905060005b8251811015610a4b5760008382815181106108f0576108f06136a0565b60209081029190910181015160408051808201825267ffffffffffffffff83168082526000908152600285528290208251815460808188028301810190955260608201818152959750929586019490939192849284919084018282801561097657602002820191906000526020600020905b815481526020019060010190808311610962575b5050509183525050600182015460ff1660208201526002820180546040909201916109a09061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546109cc9061361e565b8015610a195780601f106109ee57610100808354040283529160200191610a19565b820191906000526020600020905b8154815290600101906020018083116109fc57829003601f168201915b505050505081525050815250838381518110610a3757610a376136a0565b6020908102919091010152506001016108d3565b5092915050565b610a5a610f15565b610a6381610f98565b50565b610a6e610f15565b60005b83811015610c5457610ab5858583818110610a8e57610a8e6136a0565b9050602002016020810190610aa391906136cf565b60039067ffffffffffffffff1661108d565b610b1f57848482818110610acb57610acb6136a0565b9050602002016020810190610ae091906136cf565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107db565b60026000868684818110610b3557610b356136a0565b9050602002016020810190610b4a91906136cf565b67ffffffffffffffff1681526020810191909152604001600090812090610b718282612d50565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610ba9600283016000612d6e565b5050610be7858583818110610bc057610bc06136a0565b9050602002016020810190610bd591906136cf565b60039067ffffffffffffffff166110a5565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110610c1b57610c1b6136a0565b9050602002016020810190610c3091906136cf565b60405167ffffffffffffffff909116815260200160405180910390a1600101610a71565b5060005b81811015610e2f576000838383818110610c7457610c746136a0565b9050602002810190610c8691906136ea565b610c94906020810190613728565b610c9d9061392a565b80519091506000858585818110610cb657610cb66136a0565b9050602002810190610cc891906136ea565b610cd69060208101906136cf565b905060005b8251811015610d0e57610d06838281518110610cf957610cf96136a0565b60200260200101516110b1565b600101610cdb565b50826020015160ff16600003610d50576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120845180518693610d80928492910190612da8565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560408201516002820190610dcd9082613a11565b50610de791506003905067ffffffffffffffff83166111ca565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e08184604051610e19929190613b2b565b60405180910390a1505050806001019050610c58565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610ea5576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610eb384860186613bd6565b9050600080610ec1836111d6565b8151919350915015610ed957610ed98460008461142f565b805115610eec57610eec8460018361142f565b505050505050505050565b60606000610f0483611c10565b9392505050565b6000610288825490565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107db565b565b3373ffffffffffffffffffffffffffffffffffffffff821603611017576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107db565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515610f04565b6000610f048383611c6c565b6040517f50c946fe000000000000000000000000000000000000000000000000000000008152600481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906350c946fe90602401600060405180830381865afa15801561113f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111859190810190613e47565b60808101519091506111c6576040517f8907a4fa000000000000000000000000000000000000000000000000000000008152600481018390526024016107db565b5050565b6000610f048383611d5f565b606080600460ff1683511115611218576040517f8854586400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160028082526060820190925290816020015b61129c6040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161122e57505060408051600280825260608201909252919350602082015b6113346040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b8152602001906001900390816112c657905050905060008060005b855181101561142257600086828151811061136c5761136c6136a0565b602002602001015160000151600181111561138957611389613096565b036113d6578581815181106113a0576113a06136a0565b60200260200101518584815181106113ba576113ba6136a0565b6020026020010181905250826113cf90613f4e565b925061141a565b8581815181106113e8576113e86136a0565b6020026020010151848381518110611402576114026136a0565b60200260200101819052508161141790613f4e565b91505b60010161134f565b5090835281529092909150565b63ffffffff831660009081526005602052604081208184600181111561145757611457613096565b600181111561146857611468613096565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156118f157600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff1660018111156114db576114db613096565b60018111156114ec576114ec613096565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916115449061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546115709061361e565b80156115bd5780601f10611592576101008083540402835291602001916115bd565b820191906000526020600020905b8154815290600101906020018083116115a057829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561161557602002820191906000526020600020905b815481526020019060010190808311611601575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561166d57602002820191906000526020600020905b815481526020019060010190808311611659575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156117475783829060005260206000200180546116ba9061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546116e69061361e565b80156117335780601f1061170857610100808354040283529160200191611733565b820191906000526020600020905b81548152906001019060200180831161171657829003601f168201915b50505050508152602001906001019061169b565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156118205783829060005260206000200180546117939061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546117bf9061361e565b801561180c5780601f106117e15761010080835404028352916020019161180c565b820191906000526020600020905b8154815290600101906020018083116117ef57829003601f168201915b505050505081526020019060010190611774565b5050505081526020016006820180546118389061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546118649061361e565b80156118b15780601f10611886576101008083540402835291602001916118b1565b820191906000526020600020905b81548152906001019060200180831161189457829003601f168201915b505050919092525050508152600782015467ffffffffffffffff166020808301919091526008909201546040909101529082526001929092019101611496565b50505050905060006119038251611dae565b905060006119118451611dae565b905061191d8282611e00565b600061192c8785878686611ebc565b905061193884826122a8565b63ffffffff871660009081526005602052604081209087600181111561196057611960613096565b600181111561197157611971613096565b8152602001908152602001600020600061198b9190612df3565b60005b8151811015611c065763ffffffff88166000908152600560205260408120908860018111156119bf576119bf613096565b60018111156119d0576119d0613096565b81526020019081526020016000208282815181106119f0576119f06136a0565b6020908102919091018101518254600181810185556000948552929093208151805160099095029091018054929490939192849283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908381811115611a5a57611a5a613096565b021790555060208201518154604084015160608501517fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90921661010067ffffffffffffffff948516027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1617690100000000000000000060ff90921691909102177fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a0100000000000000000000929091169190910217815560808201516001820190611b299082613a11565b5060a08201518051611b45916002840191602090910190612da8565b5060c08201518051611b61916003840191602090910190612da8565b5060e08201518051611b7d916004840191602090910190612e14565b506101008201518051611b9a916005840191602090910190612e14565b506101208201516006820190611bb09082613a11565b50505060208201516007820180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff90921691909117905560409091015160089091015560010161198e565b5050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611c6057602002820191906000526020600020905b815481526020019060010190808311611c4c575b50505050509050919050565b60008181526001830160205260408120548015611d55576000611c90600183613f86565b8554909150600090611ca490600190613f86565b9050818114611d09576000866000018281548110611cc457611cc46136a0565b9060005260206000200154905080876000018481548110611ce757611ce76136a0565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611d1a57611d1a613f99565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610288565b6000915050610288565b6000818152600183016020526040812054611da657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610288565b506000610288565b60006002821115611dee576040517f3e478526000000000000000000000000000000000000000000000000000000008152600481018390526024016107db565b81600281111561028857610288613096565b6000826002811115611e1457611e14613096565b826002811115611e2657611e26613096565b611e309190613fc8565b90508060011480611e7c5750807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff148015611e7c57506002836002811115611e7a57611e7a613096565b145b15611e8657505050565b82826040517f0a6b675b0000000000000000000000000000000000000000000000000000000081526004016107db929190613ff8565b60606000845167ffffffffffffffff811115611eda57611eda613671565b604051908082528060200260200182016040528015611f03578160200160208202803683370190505b5090506000846002811115611f1a57611f1a613096565b148015611f3857506001836002811115611f3657611f36613096565b145b15611f7957600181600081518110611f5257611f526136a0565b602002602001019067ffffffffffffffff16908167ffffffffffffffff16815250506120e1565b6001846002811115611f8d57611f8d613096565b148015611fab57506002836002811115611fa957611fa9613096565b145b156120425785600081518110611fc357611fc36136a0565b60200260200101516020015181600081518110611fe257611fe26136a0565b602002602001019067ffffffffffffffff16908167ffffffffffffffff168152505085600081518110612017576120176136a0565b602002602001015160200151600161202f9190614013565b81600181518110611f5257611f526136a0565b600284600281111561205657612056613096565b1480156120745750600183600281111561207257612072613096565b145b156120ab578560018151811061208c5761208c6136a0565b60200260200101516020015181600081518110611f5257611f526136a0565b83836040517f0a6b675b0000000000000000000000000000000000000000000000000000000081526004016107db929190613ff8565b6000855167ffffffffffffffff8111156120fd576120fd613671565b6040519080825280602002602001820160405280156121b357816020015b604080516101a081018252600060608083018281526080840183905260a0840183905260c0840183905260e084018290526101008401829052610120840182905261014084018290526101608401829052610180840191909152825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161211b5790505b50905060005b825181101561229c576121e48782815181106121d7576121d76136a0565b6020026020010151612627565b6040518060600160405280888381518110612201576122016136a0565b60200260200101518152602001848381518110612220576122206136a0565b602002602001015167ffffffffffffffff1681526020016122748b86858151811061224d5761224d6136a0565b60200260200101518b8681518110612267576122676136a0565b6020026020010151612a2d565b815250828281518110612289576122896136a0565b60209081029190910101526001016121b9565b50979650505050505050565b81518151811580156122ba5750806001145b1561235c57826000815181106122d2576122d26136a0565b60200260200101516020015167ffffffffffffffff166001146123565782600081518110612302576123026136a0565b60209081029190910181015101516040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152600160248201526044016107db565b50505050565b81600114801561236c5750806002145b156125225783600081518110612384576123846136a0565b602002602001015160400151836000815181106123a3576123a36136a0565b6020026020010151604001511461242f57826000815181106123c7576123c76136a0565b602002602001015160400151846000815181106123e6576123e66136a0565b6020026020010151604001516040517fc7ccdd7f0000000000000000000000000000000000000000000000000000000081526004016107db929190918252602082015260400190565b83600081518110612442576124426136a0565b602002602001015160200151600161245a9190614013565b67ffffffffffffffff1683600181518110612477576124776136a0565b60200260200101516020015167ffffffffffffffff161461235657826001815181106124a5576124a56136a0565b602002602001015160200151846000815181106124c4576124c46136a0565b60200260200101516020015160016124dc9190614013565b6040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9283166004820152911660248201526044016107db565b8160021480156125325750806001145b156125f5578360018151811061254a5761254a6136a0565b60200260200101516040015183600081518110612569576125696136a0565b60200260200101516040015114612356578260008151811061258d5761258d6136a0565b602002602001015160400151846001815181106125ac576125ac6136a0565b6020026020010151604001516040517f9e9756700000000000000000000000000000000000000000000000000000000081526004016107db929190918252602082015260400190565b6040517f1f1b2bb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015167ffffffffffffffff1660000361266f576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008151600181111561268457612684613096565b141580156126a557506001815160018111156126a2576126a2613096565b14155b156126dc576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80608001515160000361271b576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101516127369060039067ffffffffffffffff1661108d565b61277e5760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107db565b60e081015151601f10156127be576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010081015151601f10156127ff576040517f645960ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015167ffffffffffffffff1660009081526002909152604081206001015461282f9060ff166003614034565b61283a906001614050565b60ff1690508082610100015151101561289157610100820151516040517f548dd21f0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107db565b816040015160ff166000036128d2576040517f39d1a4d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516128e2906003614034565b60ff168260e001515111612922576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160e00151518260c00151511415806129465750816101000151518260c001515114155b156129a15760c08201515160e083015151610100840151516040517fba900f6d0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016107db565b8160c00151518260a001515111156129e5576040517f8473d80700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129f78260a001518360c00151612b02565b60005b8260e0015151811015612a2857612a208360c001518281518110610cf957610cf96136a0565b6001016129fa565b505050565b60008082602001518584600001518560800151878760a001518860c001518960e001518a61010001518b604001518c606001518d6101200151604051602001612a819c9b9a999897969594939291906140d4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0a000000000000000000000000000000000000000000000000000000000000179150509392505050565b81511580612b0f57508051155b15612b46576040517fe249684100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b4f82612c7d565b612b5881612c7d565b6000805b835182108015612b6c5750825181105b15612c3e57828181518110612b8357612b836136a0565b6020026020010151848381518110612b9d57612b9d6136a0565b60200260200101511115612bbb57612bb481613f4e565b9050612b5c565b828181518110612bcd57612bcd6136a0565b6020026020010151848381518110612be757612be76136a0565b602002602001015103612c0857612bfd82613f4e565b9150612bb481613f4e565b83836040517fd671700c0000000000000000000000000000000000000000000000000000000081526004016107db9291906141b4565b83518210156123565783836040517fd671700c0000000000000000000000000000000000000000000000000000000081526004016107db9291906141b4565b60015b81518110156111c65781612c95600183613f86565b81518110612ca557612ca56136a0565b6020026020010151828281518110612cbf57612cbf6136a0565b602002602001015111612d0057816040517f1bc41b420000000000000000000000000000000000000000000000000000000081526004016107db91906141d9565b600101612c80565b6040518060400160405280600067ffffffffffffffff168152602001612d4b604051806060016040528060608152602001600060ff168152602001606081525090565b905290565b5080546000825590600052602060002090810190610a639190612e66565b508054612d7a9061361e565b6000825580601f10612d8a575050565b601f016020900490600052602060002090810190610a639190612e66565b828054828255906000526020600020908101928215612de3579160200282015b82811115612de3578251825591602001919060010190612dc8565b50612def929150612e66565b5090565b5080546000825560090290600052602060002090810190610a639190612e7b565b828054828255906000526020600020908101928215612e5a579160200282015b82811115612e5a5782518290612e4a9082613a11565b5091602001919060010190612e34565b50612def929150612f3c565b5b80821115612def5760008155600101612e67565b80821115612def5780547fffffffffffffffffffffffffffff00000000000000000000000000000000000016815560008181612eba6001830182612d6e565b612ec8600283016000612d50565b612ed6600383016000612d50565b612ee4600483016000612f59565b612ef2600583016000612f59565b612f00600683016000612d6e565b5050506007810180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560006008820155600901612e7b565b80821115612def576000612f508282612d6e565b50600101612f3c565b5080546000825590600052602060002090810190610a639190612f3c565b600060208284031215612f8957600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f0457600080fd5b6000815180845260005b81811015612fdf57602081850181015186830182015201612fc3565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610f046020830184612fb9565b63ffffffff81168114610a6357600080fd5b803561304d81613030565b919050565b80356002811061304d57600080fd5b6000806040838503121561307457600080fd5b823561307f81613030565b915061308d60208401613052565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106130d5576130d5613096565b9052565b60008151808452602080850194506020840160005b8381101561310a578151875295820195908201906001016130ee565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015613180577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086840301895261316e838351612fb9565b98840198925090830190600101613134565b5090979650505050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b8381101561335c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08984030185528151606081518186526131fb82870182516130c5565b8981015160806132168189018367ffffffffffffffff169052565b8a830151915060a061322c818a018460ff169052565b938301519360c0925061324a8984018667ffffffffffffffff169052565b818401519450610140915060e082818b015261326a6101a08b0187612fb9565b95508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0610100818c890301818d01526132a988856130d9565b97508587015195506101209350818c890301848d01526132c988876130d9565b9750828701519550818c890301858d01526132e48887613115565b975080870151955050808b8803016101608c01526133028786613115565b9650828601519550808b8803016101808c015250505050506133248282612fb9565b915050888201516133408a87018267ffffffffffffffff169052565b50908701519387019390935293860193908601906001016131b6565b509098975050505050505050565b60006020828403121561337c57600080fd5b8135610f0481613030565b600081516060845261339c60608501826130d9565b905060ff6020840151166020850152604083015184820360408601526133c28282612fb9565b95945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b8381101561335c578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff16845287015187840187905261344887850182613387565b95880195935050908601906001016133f4565b60006020828403121561346d57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f0457600080fd5b60008083601f8401126134a357600080fd5b50813567ffffffffffffffff8111156134bb57600080fd5b6020830191508360208260051b85010111156134d657600080fd5b9250929050565b600080600080604085870312156134f357600080fd5b843567ffffffffffffffff8082111561350b57600080fd5b61351788838901613491565b9096509450602087013591508082111561353057600080fd5b5061353d87828801613491565b95989497509550505050565b803567ffffffffffffffff8116811461304d57600080fd5b6000806000806000806080878903121561357a57600080fd5b863567ffffffffffffffff8082111561359257600080fd5b61359e8a838b01613491565b909850965060208901359150808211156135b757600080fd5b818901915089601f8301126135cb57600080fd5b8135818111156135da57600080fd5b8a60208285010111156135ec57600080fd5b60208301965080955050505061360460408801613549565b915061361260608801613042565b90509295509295509295565b600181811c9082168061363257607f821691505b60208210810361366b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156136e157600080fd5b610f0482613549565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261371e57600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261371e57600080fd5b604051610140810167ffffffffffffffff8111828210171561378057613780613671565b60405290565b60405160e0810167ffffffffffffffff8111828210171561378057613780613671565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156137f0576137f0613671565b604052919050565b600067ffffffffffffffff82111561381257613812613671565b5060051b60200190565b600082601f83011261382d57600080fd5b8135602061384261383d836137f8565b6137a9565b8083825260208201915060208460051b87010193508684111561386457600080fd5b602086015b848110156138805780358352918301918301613869565b509695505050505050565b803560ff8116811461304d57600080fd5b600082601f8301126138ad57600080fd5b813567ffffffffffffffff8111156138c7576138c7613671565b6138f860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016137a9565b81815284602083860101111561390d57600080fd5b816020850160208301376000918101602001919091529392505050565b60006060823603121561393c57600080fd5b6040516060810167ffffffffffffffff828210818311171561396057613960613671565b81604052843591508082111561397557600080fd5b6139813683870161381c565b835261398f6020860161388b565b602084015260408501359150808211156139a857600080fd5b506139b53682860161389c565b60408301525092915050565b601f821115612a28576000816000526020600020601f850160051c810160208610156139ea5750805b601f850160051c820191505b81811015613a09578281556001016139f6565b505050505050565b815167ffffffffffffffff811115613a2b57613a2b613671565b613a3f81613a39845461361e565b846139c1565b602080601f831160018114613a925760008415613a5c5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613a09565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613adf57888601518255948401946001909101908401613ac0565b5085821015613b1b57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83168152604060208201526000613b4e6040830184613387565b949350505050565b600082601f830112613b6757600080fd5b81356020613b7761383d836137f8565b82815260059290921b84018101918181019086841115613b9657600080fd5b8286015b8481101561388057803567ffffffffffffffff811115613bba5760008081fd5b613bc88986838b010161389c565b845250918301918301613b9a565b60006020808385031215613be957600080fd5b823567ffffffffffffffff80821115613c0157600080fd5b818501915085601f830112613c1557600080fd5b8135613c2361383d826137f8565b81815260059190911b83018401908481019088831115613c4257600080fd5b8585015b83811015613dd057803585811115613c5d57600080fd5b8601610140818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215613c9257600080fd5b613c9a61375c565b613ca5898301613052565b8152613cb360408301613549565b89820152613cc36060830161388b565b6040820152613cd460808301613549565b606082015260a082013587811115613ceb57600080fd5b613cf98d8b8386010161389c565b60808301525060c082013587811115613d1157600080fd5b613d1f8d8b8386010161381c565b60a08301525060e082013587811115613d3757600080fd5b613d458d8b8386010161381c565b60c0830152506101008083013588811115613d5f57600080fd5b613d6d8e8c83870101613b56565b60e0840152506101208084013589811115613d8757600080fd5b613d958f8d83880101613b56565b8385015250610140840135915088821115613daf57600080fd5b613dbd8e8c8487010161389c565b9083015250845250918601918601613c46565b5098975050505050505050565b805161304d81613030565b600082601f830112613df957600080fd5b81516020613e0961383d836137f8565b8083825260208201915060208460051b870101935086841115613e2b57600080fd5b602086015b848110156138805780518352918301918301613e30565b600060208284031215613e5957600080fd5b815167ffffffffffffffff80821115613e7157600080fd5b9083019060e08286031215613e8557600080fd5b613e8d613786565b613e9683613ddd565b8152613ea460208401613ddd565b6020820152613eb560408401613ddd565b6040820152606083015160608201526080830151608082015260a083015182811115613ee057600080fd5b613eec87828601613de8565b60a08301525060c083015182811115613f0457600080fd5b613f1087828601613de8565b60c08301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613f7f57613f7f613f1f565b5060010190565b8181038181111561028857610288613f1f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8181036000831280158383131683831282161715610a4b57610a4b613f1f565b600381106130d5576130d5613096565b604081016140068285613fe8565b610f046020830184613fe8565b67ffffffffffffffff818116838216019080821115610a4b57610a4b613f1f565b60ff8181168382160290811690818114610a4b57610a4b613f1f565b60ff818116838216019081111561028857610288613f1f565b60008282518085526020808601955060208260051b8401016020860160005b84811015613180577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189526140c2838351612fb9565b98840198925090830190600101614088565b67ffffffffffffffff8d16815263ffffffff8c1660208201526140fa604082018c6130c5565b6101806060820152600061411261018083018c612fb9565b67ffffffffffffffff8b16608084015282810360a0840152614134818b6130d9565b905082810360c0840152614148818a6130d9565b905082810360e084015261415c8189614069565b90508281036101008401526141718188614069565b60ff8716610120850152905067ffffffffffffffff85166101408401528281036101608401526141a18185612fb9565b9f9e505050505050505050505050505050565b6040815260006141c760408301856130d9565b82810360208401526133c281856130d9565b602081526000610f0460208301846130d956fea164736f6c6343000818000a", +} + +var CCIPConfigABI = CCIPConfigMetaData.ABI + +var CCIPConfigBin = CCIPConfigMetaData.Bin + +func DeployCCIPConfig(auth *bind.TransactOpts, backend bind.ContractBackend, capabilitiesRegistry common.Address) (common.Address, *types.Transaction, *CCIPConfig, error) { + parsed, err := CCIPConfigMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CCIPConfigBin), backend, capabilitiesRegistry) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CCIPConfig{address: address, abi: *parsed, CCIPConfigCaller: CCIPConfigCaller{contract: contract}, CCIPConfigTransactor: CCIPConfigTransactor{contract: contract}, CCIPConfigFilterer: CCIPConfigFilterer{contract: contract}}, nil +} + +type CCIPConfig struct { + address common.Address + abi abi.ABI + CCIPConfigCaller + CCIPConfigTransactor + CCIPConfigFilterer +} + +type CCIPConfigCaller struct { + contract *bind.BoundContract +} + +type CCIPConfigTransactor struct { + contract *bind.BoundContract +} + +type CCIPConfigFilterer struct { + contract *bind.BoundContract +} + +type CCIPConfigSession struct { + Contract *CCIPConfig + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type CCIPConfigCallerSession struct { + Contract *CCIPConfigCaller + CallOpts bind.CallOpts +} + +type CCIPConfigTransactorSession struct { + Contract *CCIPConfigTransactor + TransactOpts bind.TransactOpts +} + +type CCIPConfigRaw struct { + Contract *CCIPConfig +} + +type CCIPConfigCallerRaw struct { + Contract *CCIPConfigCaller +} + +type CCIPConfigTransactorRaw struct { + Contract *CCIPConfigTransactor +} + +func NewCCIPConfig(address common.Address, backend bind.ContractBackend) (*CCIPConfig, error) { + abi, err := abi.JSON(strings.NewReader(CCIPConfigABI)) + if err != nil { + return nil, err + } + contract, err := bindCCIPConfig(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CCIPConfig{address: address, abi: abi, CCIPConfigCaller: CCIPConfigCaller{contract: contract}, CCIPConfigTransactor: CCIPConfigTransactor{contract: contract}, CCIPConfigFilterer: CCIPConfigFilterer{contract: contract}}, nil +} + +func NewCCIPConfigCaller(address common.Address, caller bind.ContractCaller) (*CCIPConfigCaller, error) { + contract, err := bindCCIPConfig(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CCIPConfigCaller{contract: contract}, nil +} + +func NewCCIPConfigTransactor(address common.Address, transactor bind.ContractTransactor) (*CCIPConfigTransactor, error) { + contract, err := bindCCIPConfig(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CCIPConfigTransactor{contract: contract}, nil +} + +func NewCCIPConfigFilterer(address common.Address, filterer bind.ContractFilterer) (*CCIPConfigFilterer, error) { + contract, err := bindCCIPConfig(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CCIPConfigFilterer{contract: contract}, nil +} + +func bindCCIPConfig(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CCIPConfigMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_CCIPConfig *CCIPConfigRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CCIPConfig.Contract.CCIPConfigCaller.contract.Call(opts, result, method, params...) +} + +func (_CCIPConfig *CCIPConfigRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CCIPConfig.Contract.CCIPConfigTransactor.contract.Transfer(opts) +} + +func (_CCIPConfig *CCIPConfigRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CCIPConfig.Contract.CCIPConfigTransactor.contract.Transact(opts, method, params...) +} + +func (_CCIPConfig *CCIPConfigCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CCIPConfig.Contract.contract.Call(opts, result, method, params...) +} + +func (_CCIPConfig *CCIPConfigTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CCIPConfig.Contract.contract.Transfer(opts) +} + +func (_CCIPConfig *CCIPConfigTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CCIPConfig.Contract.contract.Transact(opts, method, params...) +} + +func (_CCIPConfig *CCIPConfigCaller) GetAllChainConfigs(opts *bind.CallOpts) ([]CCIPConfigTypesChainConfigInfo, error) { + var out []interface{} + err := _CCIPConfig.contract.Call(opts, &out, "getAllChainConfigs") + + if err != nil { + return *new([]CCIPConfigTypesChainConfigInfo), err + } + + out0 := *abi.ConvertType(out[0], new([]CCIPConfigTypesChainConfigInfo)).(*[]CCIPConfigTypesChainConfigInfo) + + return out0, err + +} + +func (_CCIPConfig *CCIPConfigSession) GetAllChainConfigs() ([]CCIPConfigTypesChainConfigInfo, error) { + return _CCIPConfig.Contract.GetAllChainConfigs(&_CCIPConfig.CallOpts) +} + +func (_CCIPConfig *CCIPConfigCallerSession) GetAllChainConfigs() ([]CCIPConfigTypesChainConfigInfo, error) { + return _CCIPConfig.Contract.GetAllChainConfigs(&_CCIPConfig.CallOpts) +} + +func (_CCIPConfig *CCIPConfigCaller) GetCapabilityConfiguration(opts *bind.CallOpts, arg0 uint32) ([]byte, error) { + var out []interface{} + err := _CCIPConfig.contract.Call(opts, &out, "getCapabilityConfiguration", arg0) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_CCIPConfig *CCIPConfigSession) GetCapabilityConfiguration(arg0 uint32) ([]byte, error) { + return _CCIPConfig.Contract.GetCapabilityConfiguration(&_CCIPConfig.CallOpts, arg0) +} + +func (_CCIPConfig *CCIPConfigCallerSession) GetCapabilityConfiguration(arg0 uint32) ([]byte, error) { + return _CCIPConfig.Contract.GetCapabilityConfiguration(&_CCIPConfig.CallOpts, arg0) +} + +func (_CCIPConfig *CCIPConfigCaller) GetOCRConfig(opts *bind.CallOpts, donId uint32, pluginType uint8) ([]CCIPConfigTypesOCR3ConfigWithMeta, error) { + var out []interface{} + err := _CCIPConfig.contract.Call(opts, &out, "getOCRConfig", donId, pluginType) + + if err != nil { + return *new([]CCIPConfigTypesOCR3ConfigWithMeta), err + } + + out0 := *abi.ConvertType(out[0], new([]CCIPConfigTypesOCR3ConfigWithMeta)).(*[]CCIPConfigTypesOCR3ConfigWithMeta) + + return out0, err + +} + +func (_CCIPConfig *CCIPConfigSession) GetOCRConfig(donId uint32, pluginType uint8) ([]CCIPConfigTypesOCR3ConfigWithMeta, error) { + return _CCIPConfig.Contract.GetOCRConfig(&_CCIPConfig.CallOpts, donId, pluginType) +} + +func (_CCIPConfig *CCIPConfigCallerSession) GetOCRConfig(donId uint32, pluginType uint8) ([]CCIPConfigTypesOCR3ConfigWithMeta, error) { + return _CCIPConfig.Contract.GetOCRConfig(&_CCIPConfig.CallOpts, donId, pluginType) +} + +func (_CCIPConfig *CCIPConfigCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _CCIPConfig.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_CCIPConfig *CCIPConfigSession) Owner() (common.Address, error) { + return _CCIPConfig.Contract.Owner(&_CCIPConfig.CallOpts) +} + +func (_CCIPConfig *CCIPConfigCallerSession) Owner() (common.Address, error) { + return _CCIPConfig.Contract.Owner(&_CCIPConfig.CallOpts) +} + +func (_CCIPConfig *CCIPConfigCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _CCIPConfig.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CCIPConfig *CCIPConfigSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _CCIPConfig.Contract.SupportsInterface(&_CCIPConfig.CallOpts, interfaceId) +} + +func (_CCIPConfig *CCIPConfigCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _CCIPConfig.Contract.SupportsInterface(&_CCIPConfig.CallOpts, interfaceId) +} + +func (_CCIPConfig *CCIPConfigCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _CCIPConfig.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_CCIPConfig *CCIPConfigSession) TypeAndVersion() (string, error) { + return _CCIPConfig.Contract.TypeAndVersion(&_CCIPConfig.CallOpts) +} + +func (_CCIPConfig *CCIPConfigCallerSession) TypeAndVersion() (string, error) { + return _CCIPConfig.Contract.TypeAndVersion(&_CCIPConfig.CallOpts) +} + +func (_CCIPConfig *CCIPConfigTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CCIPConfig.contract.Transact(opts, "acceptOwnership") +} + +func (_CCIPConfig *CCIPConfigSession) AcceptOwnership() (*types.Transaction, error) { + return _CCIPConfig.Contract.AcceptOwnership(&_CCIPConfig.TransactOpts) +} + +func (_CCIPConfig *CCIPConfigTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _CCIPConfig.Contract.AcceptOwnership(&_CCIPConfig.TransactOpts) +} + +func (_CCIPConfig *CCIPConfigTransactor) ApplyChainConfigUpdates(opts *bind.TransactOpts, chainSelectorRemoves []uint64, chainConfigAdds []CCIPConfigTypesChainConfigInfo) (*types.Transaction, error) { + return _CCIPConfig.contract.Transact(opts, "applyChainConfigUpdates", chainSelectorRemoves, chainConfigAdds) +} + +func (_CCIPConfig *CCIPConfigSession) ApplyChainConfigUpdates(chainSelectorRemoves []uint64, chainConfigAdds []CCIPConfigTypesChainConfigInfo) (*types.Transaction, error) { + return _CCIPConfig.Contract.ApplyChainConfigUpdates(&_CCIPConfig.TransactOpts, chainSelectorRemoves, chainConfigAdds) +} + +func (_CCIPConfig *CCIPConfigTransactorSession) ApplyChainConfigUpdates(chainSelectorRemoves []uint64, chainConfigAdds []CCIPConfigTypesChainConfigInfo) (*types.Transaction, error) { + return _CCIPConfig.Contract.ApplyChainConfigUpdates(&_CCIPConfig.TransactOpts, chainSelectorRemoves, chainConfigAdds) +} + +func (_CCIPConfig *CCIPConfigTransactor) BeforeCapabilityConfigSet(opts *bind.TransactOpts, arg0 [][32]byte, config []byte, arg2 uint64, donId uint32) (*types.Transaction, error) { + return _CCIPConfig.contract.Transact(opts, "beforeCapabilityConfigSet", arg0, config, arg2, donId) +} + +func (_CCIPConfig *CCIPConfigSession) BeforeCapabilityConfigSet(arg0 [][32]byte, config []byte, arg2 uint64, donId uint32) (*types.Transaction, error) { + return _CCIPConfig.Contract.BeforeCapabilityConfigSet(&_CCIPConfig.TransactOpts, arg0, config, arg2, donId) +} + +func (_CCIPConfig *CCIPConfigTransactorSession) BeforeCapabilityConfigSet(arg0 [][32]byte, config []byte, arg2 uint64, donId uint32) (*types.Transaction, error) { + return _CCIPConfig.Contract.BeforeCapabilityConfigSet(&_CCIPConfig.TransactOpts, arg0, config, arg2, donId) +} + +func (_CCIPConfig *CCIPConfigTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _CCIPConfig.contract.Transact(opts, "transferOwnership", to) +} + +func (_CCIPConfig *CCIPConfigSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CCIPConfig.Contract.TransferOwnership(&_CCIPConfig.TransactOpts, to) +} + +func (_CCIPConfig *CCIPConfigTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CCIPConfig.Contract.TransferOwnership(&_CCIPConfig.TransactOpts, to) +} + +type CCIPConfigCapabilityConfigurationSetIterator struct { + Event *CCIPConfigCapabilityConfigurationSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPConfigCapabilityConfigurationSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPConfigCapabilityConfigurationSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPConfigCapabilityConfigurationSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPConfigCapabilityConfigurationSetIterator) Error() error { + return it.fail +} + +func (it *CCIPConfigCapabilityConfigurationSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPConfigCapabilityConfigurationSet struct { + Raw types.Log +} + +func (_CCIPConfig *CCIPConfigFilterer) FilterCapabilityConfigurationSet(opts *bind.FilterOpts) (*CCIPConfigCapabilityConfigurationSetIterator, error) { + + logs, sub, err := _CCIPConfig.contract.FilterLogs(opts, "CapabilityConfigurationSet") + if err != nil { + return nil, err + } + return &CCIPConfigCapabilityConfigurationSetIterator{contract: _CCIPConfig.contract, event: "CapabilityConfigurationSet", logs: logs, sub: sub}, nil +} + +func (_CCIPConfig *CCIPConfigFilterer) WatchCapabilityConfigurationSet(opts *bind.WatchOpts, sink chan<- *CCIPConfigCapabilityConfigurationSet) (event.Subscription, error) { + + logs, sub, err := _CCIPConfig.contract.WatchLogs(opts, "CapabilityConfigurationSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPConfigCapabilityConfigurationSet) + if err := _CCIPConfig.contract.UnpackLog(event, "CapabilityConfigurationSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPConfig *CCIPConfigFilterer) ParseCapabilityConfigurationSet(log types.Log) (*CCIPConfigCapabilityConfigurationSet, error) { + event := new(CCIPConfigCapabilityConfigurationSet) + if err := _CCIPConfig.contract.UnpackLog(event, "CapabilityConfigurationSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CCIPConfigChainConfigRemovedIterator struct { + Event *CCIPConfigChainConfigRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPConfigChainConfigRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPConfigChainConfigRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPConfigChainConfigRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPConfigChainConfigRemovedIterator) Error() error { + return it.fail +} + +func (it *CCIPConfigChainConfigRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPConfigChainConfigRemoved struct { + ChainSelector uint64 + Raw types.Log +} + +func (_CCIPConfig *CCIPConfigFilterer) FilterChainConfigRemoved(opts *bind.FilterOpts) (*CCIPConfigChainConfigRemovedIterator, error) { + + logs, sub, err := _CCIPConfig.contract.FilterLogs(opts, "ChainConfigRemoved") + if err != nil { + return nil, err + } + return &CCIPConfigChainConfigRemovedIterator{contract: _CCIPConfig.contract, event: "ChainConfigRemoved", logs: logs, sub: sub}, nil +} + +func (_CCIPConfig *CCIPConfigFilterer) WatchChainConfigRemoved(opts *bind.WatchOpts, sink chan<- *CCIPConfigChainConfigRemoved) (event.Subscription, error) { + + logs, sub, err := _CCIPConfig.contract.WatchLogs(opts, "ChainConfigRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPConfigChainConfigRemoved) + if err := _CCIPConfig.contract.UnpackLog(event, "ChainConfigRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPConfig *CCIPConfigFilterer) ParseChainConfigRemoved(log types.Log) (*CCIPConfigChainConfigRemoved, error) { + event := new(CCIPConfigChainConfigRemoved) + if err := _CCIPConfig.contract.UnpackLog(event, "ChainConfigRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CCIPConfigChainConfigSetIterator struct { + Event *CCIPConfigChainConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPConfigChainConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPConfigChainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPConfigChainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPConfigChainConfigSetIterator) Error() error { + return it.fail +} + +func (it *CCIPConfigChainConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPConfigChainConfigSet struct { + ChainSelector uint64 + ChainConfig CCIPConfigTypesChainConfig + Raw types.Log +} + +func (_CCIPConfig *CCIPConfigFilterer) FilterChainConfigSet(opts *bind.FilterOpts) (*CCIPConfigChainConfigSetIterator, error) { + + logs, sub, err := _CCIPConfig.contract.FilterLogs(opts, "ChainConfigSet") + if err != nil { + return nil, err + } + return &CCIPConfigChainConfigSetIterator{contract: _CCIPConfig.contract, event: "ChainConfigSet", logs: logs, sub: sub}, nil +} + +func (_CCIPConfig *CCIPConfigFilterer) WatchChainConfigSet(opts *bind.WatchOpts, sink chan<- *CCIPConfigChainConfigSet) (event.Subscription, error) { + + logs, sub, err := _CCIPConfig.contract.WatchLogs(opts, "ChainConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPConfigChainConfigSet) + if err := _CCIPConfig.contract.UnpackLog(event, "ChainConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPConfig *CCIPConfigFilterer) ParseChainConfigSet(log types.Log) (*CCIPConfigChainConfigSet, error) { + event := new(CCIPConfigChainConfigSet) + if err := _CCIPConfig.contract.UnpackLog(event, "ChainConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CCIPConfigOwnershipTransferRequestedIterator struct { + Event *CCIPConfigOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPConfigOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPConfigOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPConfigOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPConfigOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *CCIPConfigOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPConfigOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CCIPConfig *CCIPConfigFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CCIPConfigOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CCIPConfig.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &CCIPConfigOwnershipTransferRequestedIterator{contract: _CCIPConfig.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_CCIPConfig *CCIPConfigFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CCIPConfigOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CCIPConfig.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPConfigOwnershipTransferRequested) + if err := _CCIPConfig.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPConfig *CCIPConfigFilterer) ParseOwnershipTransferRequested(log types.Log) (*CCIPConfigOwnershipTransferRequested, error) { + event := new(CCIPConfigOwnershipTransferRequested) + if err := _CCIPConfig.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CCIPConfigOwnershipTransferredIterator struct { + Event *CCIPConfigOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPConfigOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPConfigOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPConfigOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPConfigOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *CCIPConfigOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPConfigOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CCIPConfig *CCIPConfigFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CCIPConfigOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CCIPConfig.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &CCIPConfigOwnershipTransferredIterator{contract: _CCIPConfig.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_CCIPConfig *CCIPConfigFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CCIPConfigOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CCIPConfig.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPConfigOwnershipTransferred) + if err := _CCIPConfig.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPConfig *CCIPConfigFilterer) ParseOwnershipTransferred(log types.Log) (*CCIPConfigOwnershipTransferred, error) { + event := new(CCIPConfigOwnershipTransferred) + if err := _CCIPConfig.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_CCIPConfig *CCIPConfig) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _CCIPConfig.abi.Events["CapabilityConfigurationSet"].ID: + return _CCIPConfig.ParseCapabilityConfigurationSet(log) + case _CCIPConfig.abi.Events["ChainConfigRemoved"].ID: + return _CCIPConfig.ParseChainConfigRemoved(log) + case _CCIPConfig.abi.Events["ChainConfigSet"].ID: + return _CCIPConfig.ParseChainConfigSet(log) + case _CCIPConfig.abi.Events["OwnershipTransferRequested"].ID: + return _CCIPConfig.ParseOwnershipTransferRequested(log) + case _CCIPConfig.abi.Events["OwnershipTransferred"].ID: + return _CCIPConfig.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (CCIPConfigCapabilityConfigurationSet) Topic() common.Hash { + return common.HexToHash("0x84ad7751b744c9e2ee77da1d902b428aec7f0a343d67a24bbe2142e6f58a8d0f") +} + +func (CCIPConfigChainConfigRemoved) Topic() common.Hash { + return common.HexToHash("0x2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0") +} + +func (CCIPConfigChainConfigSet) Topic() common.Hash { + return common.HexToHash("0x05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e0") +} + +func (CCIPConfigOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (CCIPConfigOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_CCIPConfig *CCIPConfig) Address() common.Address { + return _CCIPConfig.address +} + +type CCIPConfigInterface interface { + GetAllChainConfigs(opts *bind.CallOpts) ([]CCIPConfigTypesChainConfigInfo, error) + + GetCapabilityConfiguration(opts *bind.CallOpts, arg0 uint32) ([]byte, error) + + GetOCRConfig(opts *bind.CallOpts, donId uint32, pluginType uint8) ([]CCIPConfigTypesOCR3ConfigWithMeta, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyChainConfigUpdates(opts *bind.TransactOpts, chainSelectorRemoves []uint64, chainConfigAdds []CCIPConfigTypesChainConfigInfo) (*types.Transaction, error) + + BeforeCapabilityConfigSet(opts *bind.TransactOpts, arg0 [][32]byte, config []byte, arg2 uint64, donId uint32) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterCapabilityConfigurationSet(opts *bind.FilterOpts) (*CCIPConfigCapabilityConfigurationSetIterator, error) + + WatchCapabilityConfigurationSet(opts *bind.WatchOpts, sink chan<- *CCIPConfigCapabilityConfigurationSet) (event.Subscription, error) + + ParseCapabilityConfigurationSet(log types.Log) (*CCIPConfigCapabilityConfigurationSet, error) + + FilterChainConfigRemoved(opts *bind.FilterOpts) (*CCIPConfigChainConfigRemovedIterator, error) + + WatchChainConfigRemoved(opts *bind.WatchOpts, sink chan<- *CCIPConfigChainConfigRemoved) (event.Subscription, error) + + ParseChainConfigRemoved(log types.Log) (*CCIPConfigChainConfigRemoved, error) + + FilterChainConfigSet(opts *bind.FilterOpts) (*CCIPConfigChainConfigSetIterator, error) + + WatchChainConfigSet(opts *bind.WatchOpts, sink chan<- *CCIPConfigChainConfigSet) (event.Subscription, error) + + ParseChainConfigSet(log types.Log) (*CCIPConfigChainConfigSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CCIPConfigOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CCIPConfigOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*CCIPConfigOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CCIPConfigOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CCIPConfigOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*CCIPConfigOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go new file mode 100644 index 0000000000..fdef138528 --- /dev/null +++ b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go @@ -0,0 +1,761 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package ccip_reader_tester + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type EVM2EVMMultiOffRampCommitReport struct { + PriceUpdates InternalPriceUpdates + MerkleRoots []EVM2EVMMultiOffRampMerkleRoot +} + +type EVM2EVMMultiOffRampInterval struct { + Min uint64 + Max uint64 +} + +type EVM2EVMMultiOffRampMerkleRoot struct { + SourceChainSelector uint64 + Interval EVM2EVMMultiOffRampInterval + MerkleRoot [32]byte +} + +type EVM2EVMMultiOffRampSourceChainConfig struct { + IsEnabled bool + MinSeqNr uint64 + OnRamp []byte +} + +type InternalEVM2AnyRampMessage struct { + Header InternalRampMessageHeader + Sender common.Address + Data []byte + Receiver []byte + ExtraArgs []byte + FeeToken common.Address + FeeTokenAmount *big.Int + TokenAmounts []InternalRampTokenAmount +} + +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + +type InternalRampMessageHeader struct { + MessageId [32]byte + SourceChainSelector uint64 + DestChainSelector uint64 + SequenceNumber uint64 + Nonce uint64 +} + +type InternalRampTokenAmount struct { + SourcePoolAddress []byte + DestTokenAddress []byte + ExtraData []byte + Amount *big.Int +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var CCIPReaderTesterMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPSendRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506110cc806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80634cf66e361461005c578063a65558f614610071578063e44302b714610084578063e9d68a8e14610097578063f831af81146100c0575b600080fd5b61006f61006a366004610462565b6100d3565b005b61006f61007f3660046106c7565b610128565b61006f610092366004610965565b61016d565b6100aa6100a5366004610acd565b6101a7565b6040516100b79190610b35565b60405180910390f35b61006f6100ce366004610b76565b610297565b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051610119929190610c1e565b60405180910390a45050505050565b816001600160401b03167f0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab29826040516101619190610d06565b60405180910390a25050565b7f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161019c9190610ec0565b60405180910390a150565b6040805160608082018352600080835260208084018290528385018390526001600160401b0386811683528282529185902085519384018652805460ff81161515855261010090049092169083015260018101805493949293919284019161020e90610f75565b80601f016020809104026020016040519081016040528092919081815260200182805461023a90610f75565b80156102875780601f1061025c57610100808354040283529160200191610287565b820191906000526020600020905b81548152906001019060200180831161026a57829003601f168201915b5050505050815250509050919050565b6001600160401b038281166000908152602081815260409182902084518154928601516001600160481b0319909316901515610100600160481b03191617610100929094169190910292909217825582015182919060018201906102fb9082611000565b5050505050565b80356001600160401b038116811461031957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156103565761035661031e565b60405290565b60405161010081016001600160401b03811182821017156103565761035661031e565b604080519081016001600160401b03811182821017156103565761035661031e565b604051606081016001600160401b03811182821017156103565761035661031e565b604051601f8201601f191681016001600160401b03811182821017156103eb576103eb61031e565b604052919050565b600082601f83011261040457600080fd5b81356001600160401b0381111561041d5761041d61031e565b610430601f8201601f19166020016103c3565b81815284602083860101111561044557600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561047a57600080fd5b61048386610302565b945061049160208701610302565b9350604086013592506060860135600481106104ac57600080fd5b915060808601356001600160401b038111156104c757600080fd5b6104d3888289016103f3565b9150509295509295909350565b600060a082840312156104f257600080fd5b60405160a081016001600160401b03811182821017156105145761051461031e565b6040528235815290508061052a60208401610302565b602082015261053b60408401610302565b604082015261054c60608401610302565b606082015261055d60808401610302565b60808201525092915050565b80356001600160a01b038116811461031957600080fd5b60006001600160401b038211156105995761059961031e565b5060051b60200190565b600082601f8301126105b457600080fd5b813560206105c96105c483610580565b6103c3565b82815260059290921b840181019181810190868411156105e857600080fd5b8286015b848110156106bc5780356001600160401b038082111561060c5760008081fd5b908801906080828b03601f19018113156106265760008081fd5b61062e610334565b87840135838111156106405760008081fd5b61064e8d8a838801016103f3565b825250604080850135848111156106655760008081fd5b6106738e8b838901016103f3565b8a840152506060808601358581111561068c5760008081fd5b61069a8f8c838a01016103f3565b92840192909252949092013593810193909352505083529183019183016105ec565b509695505050505050565b600080604083850312156106da57600080fd5b6106e383610302565b915060208301356001600160401b03808211156106ff57600080fd5b90840190610180828703121561071457600080fd5b61071c61035c565b61072687846104e0565b815261073460a08401610569565b602082015260c08301358281111561074b57600080fd5b610757888286016103f3565b60408301525060e08301358281111561076f57600080fd5b61077b888286016103f3565b6060830152506101008301358281111561079457600080fd5b6107a0888286016103f3565b6080830152506107b36101208401610569565b60a082015261014083013560c0820152610160830135828111156107d657600080fd5b6107e2888286016105a3565b60e0830152508093505050509250929050565b80356001600160e01b038116811461031957600080fd5b600082601f83011261081d57600080fd5b8135602061082d6105c483610580565b82815260069290921b8401810191818101908684111561084c57600080fd5b8286015b848110156106bc57604081890312156108695760008081fd5b61087161037f565b61087a82610302565b81526108878583016107f5565b81860152835291830191604001610850565b600082601f8301126108aa57600080fd5b813560206108ba6105c483610580565b82815260079290921b840181019181810190868411156108d957600080fd5b8286015b848110156106bc5780880360808112156108f75760008081fd5b6108ff6103a1565b61090883610302565b8152604080601f198401121561091e5760008081fd5b61092661037f565b9250610933878501610302565b8352610940818501610302565b83880152818701929092526060830135918101919091528352918301916080016108dd565b6000602080838503121561097857600080fd5b82356001600160401b038082111561098f57600080fd5b818501915060408083880312156109a557600080fd5b6109ad61037f565b8335838111156109bc57600080fd5b84016040818a0312156109ce57600080fd5b6109d661037f565b8135858111156109e557600080fd5b8201601f81018b136109f657600080fd5b8035610a046105c482610580565b81815260069190911b8201890190898101908d831115610a2357600080fd5b928a01925b82841015610a715787848f031215610a405760008081fd5b610a4861037f565b610a5185610569565b8152610a5e8c86016107f5565b818d0152825292870192908a0190610a28565b845250505081870135935084841115610a8957600080fd5b610a958a85840161080c565b8188015282525083850135915082821115610aaf57600080fd5b610abb88838601610899565b85820152809550505050505092915050565b600060208284031215610adf57600080fd5b610ae882610302565b9392505050565b6000815180845260005b81811015610b1557602081850181015186830182015201610af9565b506000602082860101526020601f19601f83011685010191505092915050565b6020815281511515602082015260018060401b03602083015116604082015260006040830151606080840152610b6e6080840182610aef565b949350505050565b60008060408385031215610b8957600080fd5b610b9283610302565b915060208301356001600160401b0380821115610bae57600080fd5b9084019060608287031215610bc257600080fd5b610bca6103a1565b82358015158114610bda57600080fd5b8152610be860208401610302565b6020820152604083013582811115610bff57600080fd5b610c0b888286016103f3565b6040830152508093505050509250929050565b600060048410610c3e57634e487b7160e01b600052602160045260246000fd5b83825260406020830152610b6e6040830184610aef565b6001600160a01b03169052565b600082825180855260208086019550808260051b84010181860160005b84811015610cf957601f19868403018952815160808151818652610ca582870182610aef565b9150508582015185820387870152610cbd8282610aef565b91505060408083015186830382880152610cd78382610aef565b6060948501519790940196909652505098840198925090830190600101610c7f565b5090979650505050505050565b60208152610d53602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b60006020830151610d6760c0840182610c55565b5060408301516101808060e0850152610d846101a0850183610aef565b91506060850151601f198086850301610100870152610da38483610aef565b9350608087015191508086850301610120870152610dc18483610aef565b935060a08701519150610dd8610140870183610c55565b60c087015161016087015260e0870151915080868503018387015250610dfe8382610c62565b9695505050505050565b60008151808452602080850194506020840160005b83811015610e5657815180516001600160401b031688528301516001600160e01b03168388015260409096019590820190600101610e1d565b509495945050505050565b600081518084526020808501945080840160005b83811015610e5657815180516001600160401b0390811689528482015180518216868b0152850151166040898101919091520151606088015260809096019590820190600101610e75565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b80831015610f2e57835180516001600160a01b031683528701516001600160e01b031687830152928601926001929092019190840190610ef3565b5093850151878503605f1901608089015293610f4a8186610e08565b945050505050818501519150601f19848203016040850152610f6c8183610e61565b95945050505050565b600181811c90821680610f8957607f821691505b602082108103610fa957634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610ffb576000816000526020600020601f850160051c81016020861015610fd85750805b601f850160051c820191505b81811015610ff757828155600101610fe4565b5050505b505050565b81516001600160401b038111156110195761101961031e565b61102d816110278454610f75565b84610faf565b602080601f831160018114611062576000841561104a5750858301515b600019600386901b1c1916600185901b178555610ff7565b600085815260208120601f198616915b8281101561109157888601518255948401946001909101908401611072565b50858210156110af5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", +} + +var CCIPReaderTesterABI = CCIPReaderTesterMetaData.ABI + +var CCIPReaderTesterBin = CCIPReaderTesterMetaData.Bin + +func DeployCCIPReaderTester(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *CCIPReaderTester, error) { + parsed, err := CCIPReaderTesterMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CCIPReaderTesterBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CCIPReaderTester{address: address, abi: *parsed, CCIPReaderTesterCaller: CCIPReaderTesterCaller{contract: contract}, CCIPReaderTesterTransactor: CCIPReaderTesterTransactor{contract: contract}, CCIPReaderTesterFilterer: CCIPReaderTesterFilterer{contract: contract}}, nil +} + +type CCIPReaderTester struct { + address common.Address + abi abi.ABI + CCIPReaderTesterCaller + CCIPReaderTesterTransactor + CCIPReaderTesterFilterer +} + +type CCIPReaderTesterCaller struct { + contract *bind.BoundContract +} + +type CCIPReaderTesterTransactor struct { + contract *bind.BoundContract +} + +type CCIPReaderTesterFilterer struct { + contract *bind.BoundContract +} + +type CCIPReaderTesterSession struct { + Contract *CCIPReaderTester + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type CCIPReaderTesterCallerSession struct { + Contract *CCIPReaderTesterCaller + CallOpts bind.CallOpts +} + +type CCIPReaderTesterTransactorSession struct { + Contract *CCIPReaderTesterTransactor + TransactOpts bind.TransactOpts +} + +type CCIPReaderTesterRaw struct { + Contract *CCIPReaderTester +} + +type CCIPReaderTesterCallerRaw struct { + Contract *CCIPReaderTesterCaller +} + +type CCIPReaderTesterTransactorRaw struct { + Contract *CCIPReaderTesterTransactor +} + +func NewCCIPReaderTester(address common.Address, backend bind.ContractBackend) (*CCIPReaderTester, error) { + abi, err := abi.JSON(strings.NewReader(CCIPReaderTesterABI)) + if err != nil { + return nil, err + } + contract, err := bindCCIPReaderTester(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CCIPReaderTester{address: address, abi: abi, CCIPReaderTesterCaller: CCIPReaderTesterCaller{contract: contract}, CCIPReaderTesterTransactor: CCIPReaderTesterTransactor{contract: contract}, CCIPReaderTesterFilterer: CCIPReaderTesterFilterer{contract: contract}}, nil +} + +func NewCCIPReaderTesterCaller(address common.Address, caller bind.ContractCaller) (*CCIPReaderTesterCaller, error) { + contract, err := bindCCIPReaderTester(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CCIPReaderTesterCaller{contract: contract}, nil +} + +func NewCCIPReaderTesterTransactor(address common.Address, transactor bind.ContractTransactor) (*CCIPReaderTesterTransactor, error) { + contract, err := bindCCIPReaderTester(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CCIPReaderTesterTransactor{contract: contract}, nil +} + +func NewCCIPReaderTesterFilterer(address common.Address, filterer bind.ContractFilterer) (*CCIPReaderTesterFilterer, error) { + contract, err := bindCCIPReaderTester(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CCIPReaderTesterFilterer{contract: contract}, nil +} + +func bindCCIPReaderTester(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CCIPReaderTesterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_CCIPReaderTester *CCIPReaderTesterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CCIPReaderTester.Contract.CCIPReaderTesterCaller.contract.Call(opts, result, method, params...) +} + +func (_CCIPReaderTester *CCIPReaderTesterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.CCIPReaderTesterTransactor.contract.Transfer(opts) +} + +func (_CCIPReaderTester *CCIPReaderTesterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.CCIPReaderTesterTransactor.contract.Transact(opts, method, params...) +} + +func (_CCIPReaderTester *CCIPReaderTesterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CCIPReaderTester.Contract.contract.Call(opts, result, method, params...) +} + +func (_CCIPReaderTester *CCIPReaderTesterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.contract.Transfer(opts) +} + +func (_CCIPReaderTester *CCIPReaderTesterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.contract.Transact(opts, method, params...) +} + +func (_CCIPReaderTester *CCIPReaderTesterCaller) GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) { + var out []interface{} + err := _CCIPReaderTester.contract.Call(opts, &out, "getSourceChainConfig", sourceChainSelector) + + if err != nil { + return *new(EVM2EVMMultiOffRampSourceChainConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOffRampSourceChainConfig)).(*EVM2EVMMultiOffRampSourceChainConfig) + + return out0, err + +} + +func (_CCIPReaderTester *CCIPReaderTesterSession) GetSourceChainConfig(sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) { + return _CCIPReaderTester.Contract.GetSourceChainConfig(&_CCIPReaderTester.CallOpts, sourceChainSelector) +} + +func (_CCIPReaderTester *CCIPReaderTesterCallerSession) GetSourceChainConfig(sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) { + return _CCIPReaderTester.Contract.GetSourceChainConfig(&_CCIPReaderTester.CallOpts, sourceChainSelector) +} + +func (_CCIPReaderTester *CCIPReaderTesterTransactor) EmitCCIPSendRequested(opts *bind.TransactOpts, destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) { + return _CCIPReaderTester.contract.Transact(opts, "emitCCIPSendRequested", destChainSelector, message) +} + +func (_CCIPReaderTester *CCIPReaderTesterSession) EmitCCIPSendRequested(destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.EmitCCIPSendRequested(&_CCIPReaderTester.TransactOpts, destChainSelector, message) +} + +func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) EmitCCIPSendRequested(destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.EmitCCIPSendRequested(&_CCIPReaderTester.TransactOpts, destChainSelector, message) +} + +func (_CCIPReaderTester *CCIPReaderTesterTransactor) EmitCommitReportAccepted(opts *bind.TransactOpts, report EVM2EVMMultiOffRampCommitReport) (*types.Transaction, error) { + return _CCIPReaderTester.contract.Transact(opts, "emitCommitReportAccepted", report) +} + +func (_CCIPReaderTester *CCIPReaderTesterSession) EmitCommitReportAccepted(report EVM2EVMMultiOffRampCommitReport) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.EmitCommitReportAccepted(&_CCIPReaderTester.TransactOpts, report) +} + +func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) EmitCommitReportAccepted(report EVM2EVMMultiOffRampCommitReport) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.EmitCommitReportAccepted(&_CCIPReaderTester.TransactOpts, report) +} + +func (_CCIPReaderTester *CCIPReaderTesterTransactor) EmitExecutionStateChanged(opts *bind.TransactOpts, sourceChainSelector uint64, sequenceNumber uint64, messageId [32]byte, state uint8, returnData []byte) (*types.Transaction, error) { + return _CCIPReaderTester.contract.Transact(opts, "emitExecutionStateChanged", sourceChainSelector, sequenceNumber, messageId, state, returnData) +} + +func (_CCIPReaderTester *CCIPReaderTesterSession) EmitExecutionStateChanged(sourceChainSelector uint64, sequenceNumber uint64, messageId [32]byte, state uint8, returnData []byte) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.EmitExecutionStateChanged(&_CCIPReaderTester.TransactOpts, sourceChainSelector, sequenceNumber, messageId, state, returnData) +} + +func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) EmitExecutionStateChanged(sourceChainSelector uint64, sequenceNumber uint64, messageId [32]byte, state uint8, returnData []byte) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.EmitExecutionStateChanged(&_CCIPReaderTester.TransactOpts, sourceChainSelector, sequenceNumber, messageId, state, returnData) +} + +func (_CCIPReaderTester *CCIPReaderTesterTransactor) SetSourceChainConfig(opts *bind.TransactOpts, sourceChainSelector uint64, sourceChainConfig EVM2EVMMultiOffRampSourceChainConfig) (*types.Transaction, error) { + return _CCIPReaderTester.contract.Transact(opts, "setSourceChainConfig", sourceChainSelector, sourceChainConfig) +} + +func (_CCIPReaderTester *CCIPReaderTesterSession) SetSourceChainConfig(sourceChainSelector uint64, sourceChainConfig EVM2EVMMultiOffRampSourceChainConfig) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.SetSourceChainConfig(&_CCIPReaderTester.TransactOpts, sourceChainSelector, sourceChainConfig) +} + +func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) SetSourceChainConfig(sourceChainSelector uint64, sourceChainConfig EVM2EVMMultiOffRampSourceChainConfig) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.SetSourceChainConfig(&_CCIPReaderTester.TransactOpts, sourceChainSelector, sourceChainConfig) +} + +type CCIPReaderTesterCCIPSendRequestedIterator struct { + Event *CCIPReaderTesterCCIPSendRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPReaderTesterCCIPSendRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPReaderTesterCCIPSendRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPReaderTesterCCIPSendRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPReaderTesterCCIPSendRequestedIterator) Error() error { + return it.fail +} + +func (it *CCIPReaderTesterCCIPSendRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPReaderTesterCCIPSendRequested struct { + DestChainSelector uint64 + Message InternalEVM2AnyRampMessage + Raw types.Log +} + +func (_CCIPReaderTester *CCIPReaderTesterFilterer) FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*CCIPReaderTesterCCIPSendRequestedIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _CCIPReaderTester.contract.FilterLogs(opts, "CCIPSendRequested", destChainSelectorRule) + if err != nil { + return nil, err + } + return &CCIPReaderTesterCCIPSendRequestedIterator{contract: _CCIPReaderTester.contract, event: "CCIPSendRequested", logs: logs, sub: sub}, nil +} + +func (_CCIPReaderTester *CCIPReaderTesterFilterer) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *CCIPReaderTesterCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _CCIPReaderTester.contract.WatchLogs(opts, "CCIPSendRequested", destChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPReaderTesterCCIPSendRequested) + if err := _CCIPReaderTester.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPReaderTester *CCIPReaderTesterFilterer) ParseCCIPSendRequested(log types.Log) (*CCIPReaderTesterCCIPSendRequested, error) { + event := new(CCIPReaderTesterCCIPSendRequested) + if err := _CCIPReaderTester.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CCIPReaderTesterCommitReportAcceptedIterator struct { + Event *CCIPReaderTesterCommitReportAccepted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPReaderTesterCommitReportAcceptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPReaderTesterCommitReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPReaderTesterCommitReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPReaderTesterCommitReportAcceptedIterator) Error() error { + return it.fail +} + +func (it *CCIPReaderTesterCommitReportAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPReaderTesterCommitReportAccepted struct { + Report EVM2EVMMultiOffRampCommitReport + Raw types.Log +} + +func (_CCIPReaderTester *CCIPReaderTesterFilterer) FilterCommitReportAccepted(opts *bind.FilterOpts) (*CCIPReaderTesterCommitReportAcceptedIterator, error) { + + logs, sub, err := _CCIPReaderTester.contract.FilterLogs(opts, "CommitReportAccepted") + if err != nil { + return nil, err + } + return &CCIPReaderTesterCommitReportAcceptedIterator{contract: _CCIPReaderTester.contract, event: "CommitReportAccepted", logs: logs, sub: sub}, nil +} + +func (_CCIPReaderTester *CCIPReaderTesterFilterer) WatchCommitReportAccepted(opts *bind.WatchOpts, sink chan<- *CCIPReaderTesterCommitReportAccepted) (event.Subscription, error) { + + logs, sub, err := _CCIPReaderTester.contract.WatchLogs(opts, "CommitReportAccepted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPReaderTesterCommitReportAccepted) + if err := _CCIPReaderTester.contract.UnpackLog(event, "CommitReportAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPReaderTester *CCIPReaderTesterFilterer) ParseCommitReportAccepted(log types.Log) (*CCIPReaderTesterCommitReportAccepted, error) { + event := new(CCIPReaderTesterCommitReportAccepted) + if err := _CCIPReaderTester.contract.UnpackLog(event, "CommitReportAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CCIPReaderTesterExecutionStateChangedIterator struct { + Event *CCIPReaderTesterExecutionStateChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CCIPReaderTesterExecutionStateChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CCIPReaderTesterExecutionStateChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CCIPReaderTesterExecutionStateChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CCIPReaderTesterExecutionStateChangedIterator) Error() error { + return it.fail +} + +func (it *CCIPReaderTesterExecutionStateChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CCIPReaderTesterExecutionStateChanged struct { + SourceChainSelector uint64 + SequenceNumber uint64 + MessageId [32]byte + State uint8 + ReturnData []byte + Raw types.Log +} + +func (_CCIPReaderTester *CCIPReaderTesterFilterer) FilterExecutionStateChanged(opts *bind.FilterOpts, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (*CCIPReaderTesterExecutionStateChangedIterator, error) { + + var sourceChainSelectorRule []interface{} + for _, sourceChainSelectorItem := range sourceChainSelector { + sourceChainSelectorRule = append(sourceChainSelectorRule, sourceChainSelectorItem) + } + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + var messageIdRule []interface{} + for _, messageIdItem := range messageId { + messageIdRule = append(messageIdRule, messageIdItem) + } + + logs, sub, err := _CCIPReaderTester.contract.FilterLogs(opts, "ExecutionStateChanged", sourceChainSelectorRule, sequenceNumberRule, messageIdRule) + if err != nil { + return nil, err + } + return &CCIPReaderTesterExecutionStateChangedIterator{contract: _CCIPReaderTester.contract, event: "ExecutionStateChanged", logs: logs, sub: sub}, nil +} + +func (_CCIPReaderTester *CCIPReaderTesterFilterer) WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *CCIPReaderTesterExecutionStateChanged, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) { + + var sourceChainSelectorRule []interface{} + for _, sourceChainSelectorItem := range sourceChainSelector { + sourceChainSelectorRule = append(sourceChainSelectorRule, sourceChainSelectorItem) + } + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + var messageIdRule []interface{} + for _, messageIdItem := range messageId { + messageIdRule = append(messageIdRule, messageIdItem) + } + + logs, sub, err := _CCIPReaderTester.contract.WatchLogs(opts, "ExecutionStateChanged", sourceChainSelectorRule, sequenceNumberRule, messageIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CCIPReaderTesterExecutionStateChanged) + if err := _CCIPReaderTester.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CCIPReaderTester *CCIPReaderTesterFilterer) ParseExecutionStateChanged(log types.Log) (*CCIPReaderTesterExecutionStateChanged, error) { + event := new(CCIPReaderTesterExecutionStateChanged) + if err := _CCIPReaderTester.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_CCIPReaderTester *CCIPReaderTester) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _CCIPReaderTester.abi.Events["CCIPSendRequested"].ID: + return _CCIPReaderTester.ParseCCIPSendRequested(log) + case _CCIPReaderTester.abi.Events["CommitReportAccepted"].ID: + return _CCIPReaderTester.ParseCommitReportAccepted(log) + case _CCIPReaderTester.abi.Events["ExecutionStateChanged"].ID: + return _CCIPReaderTester.ParseExecutionStateChanged(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (CCIPReaderTesterCCIPSendRequested) Topic() common.Hash { + return common.HexToHash("0x0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab29") +} + +func (CCIPReaderTesterCommitReportAccepted) Topic() common.Hash { + return common.HexToHash("0x3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d") +} + +func (CCIPReaderTesterExecutionStateChanged) Topic() common.Hash { + return common.HexToHash("0x8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df2") +} + +func (_CCIPReaderTester *CCIPReaderTester) Address() common.Address { + return _CCIPReaderTester.address +} + +type CCIPReaderTesterInterface interface { + GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) + + EmitCCIPSendRequested(opts *bind.TransactOpts, destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) + + EmitCommitReportAccepted(opts *bind.TransactOpts, report EVM2EVMMultiOffRampCommitReport) (*types.Transaction, error) + + EmitExecutionStateChanged(opts *bind.TransactOpts, sourceChainSelector uint64, sequenceNumber uint64, messageId [32]byte, state uint8, returnData []byte) (*types.Transaction, error) + + SetSourceChainConfig(opts *bind.TransactOpts, sourceChainSelector uint64, sourceChainConfig EVM2EVMMultiOffRampSourceChainConfig) (*types.Transaction, error) + + FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*CCIPReaderTesterCCIPSendRequestedIterator, error) + + WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *CCIPReaderTesterCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) + + ParseCCIPSendRequested(log types.Log) (*CCIPReaderTesterCCIPSendRequested, error) + + FilterCommitReportAccepted(opts *bind.FilterOpts) (*CCIPReaderTesterCommitReportAcceptedIterator, error) + + WatchCommitReportAccepted(opts *bind.WatchOpts, sink chan<- *CCIPReaderTesterCommitReportAccepted) (event.Subscription, error) + + ParseCommitReportAccepted(log types.Log) (*CCIPReaderTesterCommitReportAccepted, error) + + FilterExecutionStateChanged(opts *bind.FilterOpts, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (*CCIPReaderTesterExecutionStateChangedIterator, error) + + WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *CCIPReaderTesterExecutionStateChanged, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) + + ParseExecutionStateChanged(log types.Log) (*CCIPReaderTesterExecutionStateChanged, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/commit_store/commit_store.go b/core/gethwrappers/ccip/generated/commit_store/commit_store.go new file mode 100644 index 0000000000..940f4208d4 --- /dev/null +++ b/core/gethwrappers/ccip/generated/commit_store/commit_store.go @@ -0,0 +1,2191 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package commit_store + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommitStoreCommitReport struct { + PriceUpdates InternalPriceUpdates + Interval CommitStoreInterval + MerkleRoot [32]byte +} + +type CommitStoreDynamicConfig struct { + PriceRegistry common.Address +} + +type CommitStoreInterval struct { + Min uint64 + Max uint64 +} + +type CommitStoreStaticConfig struct { + ChainSelector uint64 + SourceChainSelector uint64 + OnRamp common.Address + RmnProxy common.Address +} + +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var CommitStoreMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"oldEpochAndRound\",\"type\":\"uint40\"},{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"newEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"LatestPriceEpochAndRoundSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"oldSeqNum\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newSeqNum\",\"type\":\"uint64\"}],\"name\":\"SequenceNumberSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndNotCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b506040516200378e3803806200378e8339810160408190526200004d9162000272565b600033808281620000a55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d857620000d88162000192565b50505015156080524660a05260408101516001600160a01b0316158062000107575080516001600160401b0316155b806200011e575060208101516001600160401b0316155b8062000135575060608101516001600160a01b0316155b156200015457604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b0390811661010052606090910151166101205262000306565b336001600160a01b03821603620001ec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025557600080fd5b919050565b80516001600160a01b03811681146200025557600080fd5b6000608082840312156200028557600080fd5b604051608081016001600160401b0381118282101715620002b657634e487b7160e01b600052604160045260246000fd5b604052620002c4836200023d565b8152620002d4602084016200023d565b6020820152620002e7604084016200025a565b6040820152620002fa606084016200025a565b60608201529392505050565b60805160a05160c05160e05161010051610120516133f26200039c60003960008181610262015281816116c80152818161187c01528181611acb0152611fa50152600081816102260152611aa40152600081816101f60152818161168201528181611a7d0152611f620152600081816101c60152611a4e0152600081816110c801526111140152600061118f01526133f26000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806379ba5097116100e3578063afcb95d71161008c578063f2fde38b11610066578063f2fde38b146104e3578063f47a8690146104f6578063ff888fb11461050957600080fd5b8063afcb95d7146104a8578063b1dc65a4146104c8578063e89d039f146104db57600080fd5b80638da5cb5b116100bd5780638da5cb5b1461044d578063a7206cd614610475578063ad7a22f81461049557600080fd5b806379ba50971461040d57806381ff7048146104155780638456cb591461044557600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb14610391578063666cab8d146103b95780637437ff9f146103ce57600080fd5b806332048875146103565780633f4ba83a146103775780634120fccd1461037f57600080fd5b8063181f5a7711610176578063181f5a77146102e55780631ef381741461032e57806329b980e41461034357600080fd5b806306285c691461019257806310c374ed146102b5575b600080fd5b61029f60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102ac9190612583565b60405180910390f35b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102ac565b6103216040518060400160405280601581526020017f436f6d6d697453746f726520312e352e302d646576000000000000000000000081525081565b6040516102ac9190612640565b61034161033c366004612897565b61051c565b005b610341610351366004612964565b610c00565b6103696103643660046129d7565b610c90565b6040519081526020016102ac565b610341610d86565b60095467ffffffffffffffff166102cc565b6009546d0100000000000000000000000000900460ff165b60405190151581526020016102ac565b6103c1610dec565b6040516102ac9190612a9d565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102ac565b610341610e5b565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102ac565b610341610f58565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102ac565b610369610483366004612ab0565b6000908152600a602052604090205490565b6103416104a3366004612ac9565b610fc8565b6040805160018152600060208201819052918101919091526060016102ac565b6103416104d6366004612ae4565b611043565b6103a961165a565b6103416104f1366004612bc9565b61176e565b610341610504366004612be6565b611782565b6103a9610517366004612ab0565b611819565b855185518560ff16601f83111561056b5760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b60405180910390fd5b806000036105a85760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b8183146105e45760046040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b6105ef816003612cc7565b831161062a5760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b6106326118ed565b61063b86611970565b60065460005b8181101561072f57600560006006838154811061066057610660612cde565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600780546005929190849081106106d0576106d0612cde565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600101610641565b50895160005b81811015610aa85760008c828151811061075157610751612cde565b602002602001015190506000600281111561076e5761076e612c28565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff1660028111156107ad576107ad612c28565b146107e75760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b73ffffffffffffffffffffffffffffffffffffffff8116610834576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156108e4576108e4612c28565b021790555090505060008c838151811061090057610900612cde565b602002602001015190506000600281111561091d5761091d612c28565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561095c5761095c612c28565b146109965760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b73ffffffffffffffffffffffffffffffffffffffff81166109e3576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610a9357610a93612c28565b02179055509050505050806001019050610735565b508a51610abc9060069060208e01906124c5565b508951610ad09060079060208d01906124c5565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610b56914691309190600090610b289063ffffffff16612d0d565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611b20565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610bea99989796959493929190612d30565b60405180910390a1505050505050505050505050565b610c086118ed565b6009805464ffffffffff838116680100000000000000008181027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff85161790945560408051949093049091168084526020840191909152917ff0d557bfce33e354b41885eb9264448726cfe51f486ffa69809d2bf56545644491015b60405180910390a15050565b6009546000906d0100000000000000000000000000900460ff1615610ce1576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d5287878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250611bcb915050565b9050610d5d81611819565b610d6b576000915050610d7d565b6000908152600a602052604090205490505b95945050505050565b610d8e6118ed565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610e5157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e26575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314610edc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610562565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610f606118ed565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610de2565b610fd06118ed565b6009805467ffffffffffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168117909355604080519190921680825260208201939093527fea59e8027e41fda1525220008cf2416797405065eb21b0ebd417bfc6d361b8de9101610c84565b611052878760208b0135611eec565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146110c55780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610562565b467f000000000000000000000000000000000000000000000000000000000000000014611146576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610562565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f0000000000000000000000000000000000000000000000000000000000000000156111e8576002826020015183604001516111c99190612dc6565b6111d39190612ddf565b6111de906001612dc6565b60ff1690506111fe565b60208201516111f8906001612dc6565b60ff1690505b868114611237576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514611270576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156112b3576112b3612c28565b60028111156112c4576112c4612c28565b90525090506002816020015160028111156112e1576112e1612c28565b14801561132857506007816000015160ff168154811061130357611303612cde565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b61135e576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061136c866020612cc7565b611377896020612cc7565b6113838c610144612e28565b61138d9190612e28565b6113979190612e28565b90503681146113db576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610562565b5060008a8a6040516113ee929190612e3b565b604051908190038120611405918e90602001612e4b565b60405160208183030381529060405280519060200120905061142561254f565b8860005b818110156116495760006001858a846020811061144857611448612cde565b61145591901a601b612dc6565b8f8f8681811061146757611467612cde565b905060200201358e8e8781811061148057611480612cde565b90506020020135604051600081526020016040526040516114bd949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156114df573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561156257611562612c28565b600281111561157357611573612c28565b905250905060018160200151600281111561159057611590612c28565b146115c7576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f81106115de576115de612cde565b60200201511561161a576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061163557611635612cde565b911515602090920201525050600101611429565b505050505050505050505050505050565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611724573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117489190612e5f565b15801561176957506009546d0100000000000000000000000000900460ff16155b905090565b6117766118ed565b61177f81612355565b50565b61178a6118ed565b60005b818110156118145760008383838181106117a9576117a9612cde565b9050602002013590506117bb81611819565b61180b576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12906118029083815260200190565b60405180910390a15b5060010161178d565b505050565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156118c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e79190612e5f565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461196e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610562565b565b6000818060200190518101906119869190612e81565b805190915073ffffffffffffffffffffffffffffffffffffffff166119d7576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391610c84918490612ecd565b6000808a8a8a8a8a8a8a8a8a604051602001611b4499989796959493929190612f4a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303611c0c576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590611c2057506101018111155b611c56576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115611cb7576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611ce45786600081518110611cd257611cd2612cde565b60200260200101519350505050611ee5565b60008167ffffffffffffffff811115611cff57611cff612653565b604051908082528060200260200182016040528015611d28578160200160208202803683370190505b50905060008080805b85811015611e6b5760006001821b8b811603611d8c5788851015611d75578c5160018601958e918110611d6657611d66612cde565b60200260200101519050611dae565b8551600185019487918110611d6657611d66612cde565b8b5160018401938d918110611da357611da3612cde565b602002602001015190505b600089861015611dde578d5160018701968f918110611dcf57611dcf612cde565b60200260200101519050611e00565b8651600186019588918110611df557611df5612cde565b602002602001015190505b82851115611e3a576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e44828261244a565b878481518110611e5657611e56612cde565b60209081029190910101525050600101611d31565b506001850382148015611e7d57508683145b8015611e8857508581145b611ebe576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836001860381518110611ed357611ed3612cde565b60200260200101519750505050505050505b9392505050565b6009546d0100000000000000000000000000900460ff1615611f3a576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612001573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120259190612e5f565b1561205c576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061206a838501856130d6565b8051515190915015158061208357508051602001515115155b156121bb5760095464ffffffffff8084166801000000000000000090920416101561218057600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f9161213a91600401613329565b600060405180830381600087803b15801561215457600080fd5b505af1158015612168573d6000803e3d6000fd5b50505050604081015161217b5750505050565b6121bb565b60408101516121bb576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff90811691161415806121f6575060208082015190810151905167ffffffffffffffff9182169116115b156122335780602001516040517fbb1ae18d000000000000000000000000000000000000000000000000000000008152600401610562919061333c565b604081015161226e576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a6020522054156122b7576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015101516122ca906001613361565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf590612347908390613389565b60405180910390a150505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036123d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610562565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081831061248c5760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120611ee5565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120611ee5565b82805482825590600052602060002090810192821561253f579160200282015b8281111561253f57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906124e5565b5061254b92915061256e565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561254b576000815560010161256f565b608081016118e7828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b81811015612602576020818501810151868301820152016125e6565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611ee560208301846125dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156126a5576126a5612653565b60405290565b6040516060810167ffffffffffffffff811182821017156126a5576126a5612653565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561271557612715612653565b604052919050565b600067ffffffffffffffff82111561273757612737612653565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461177f57600080fd5b600082601f83011261277457600080fd5b813560206127896127848361271d565b6126ce565b8083825260208201915060208460051b8701019350868411156127ab57600080fd5b602086015b848110156127d05780356127c381612741565b83529183019183016127b0565b509695505050505050565b803560ff811681146127ec57600080fd5b919050565b600082601f83011261280257600080fd5b813567ffffffffffffffff81111561281c5761281c612653565b61284d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016126ce565b81815284602083860101111561286257600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146127ec57600080fd5b60008060008060008060c087890312156128b057600080fd5b863567ffffffffffffffff808211156128c857600080fd5b6128d48a838b01612763565b975060208901359150808211156128ea57600080fd5b6128f68a838b01612763565b965061290460408a016127db565b9550606089013591508082111561291a57600080fd5b6129268a838b016127f1565b945061293460808a0161287f565b935060a089013591508082111561294a57600080fd5b5061295789828a016127f1565b9150509295509295509295565b60006020828403121561297657600080fd5b813564ffffffffff81168114611ee557600080fd5b60008083601f84011261299d57600080fd5b50813567ffffffffffffffff8111156129b557600080fd5b6020830191508360208260051b85010111156129d057600080fd5b9250929050565b6000806000806000606086880312156129ef57600080fd5b853567ffffffffffffffff80821115612a0757600080fd5b612a1389838a0161298b565b90975095506020880135915080821115612a2c57600080fd5b50612a398882890161298b565b96999598509660400135949350505050565b60008151808452602080850194506020840160005b83811015612a9257815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612a60565b509495945050505050565b602081526000611ee56020830184612a4b565b600060208284031215612ac257600080fd5b5035919050565b600060208284031215612adb57600080fd5b611ee58261287f565b60008060008060008060008060e0898b031215612b0057600080fd5b606089018a811115612b1157600080fd5b8998503567ffffffffffffffff80821115612b2b57600080fd5b818b0191508b601f830112612b3f57600080fd5b813581811115612b4e57600080fd5b8c6020828501011115612b6057600080fd5b6020830199508098505060808b0135915080821115612b7e57600080fd5b612b8a8c838d0161298b565b909750955060a08b0135915080821115612ba357600080fd5b50612bb08b828c0161298b565b999c989b50969995989497949560c00135949350505050565b600060208284031215612bdb57600080fd5b8135611ee581612741565b60008060208385031215612bf957600080fd5b823567ffffffffffffffff811115612c1057600080fd5b612c1c8582860161298b565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160058310612c92577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176118e7576118e7612c98565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103612d2657612d26612c98565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612d608184018a612a4b565b90508281036080840152612d748189612a4b565b905060ff871660a084015282810360c0840152612d9181876125dc565b905067ffffffffffffffff851660e0840152828103610100840152612db681856125dc565b9c9b505050505050505050505050565b60ff81811683821601908111156118e7576118e7612c98565b600060ff831680612e19577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b808201808211156118e7576118e7612c98565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612e7157600080fd5b81518015158114611ee557600080fd5b600060208284031215612e9357600080fd5b6040516020810181811067ffffffffffffffff82111715612eb657612eb6612653565b6040528251612ec481612741565b81529392505050565b60a08101612f26828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152612f918285018b612a4b565b91508382036080850152612fa5828a612a4b565b915060ff881660a085015283820360c0850152612fc282886125dc565b90861660e08501528381036101008501529050612db681856125dc565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146127ec57600080fd5b600082601f83011261301c57600080fd5b8135602061302c6127848361271d565b82815260069290921b8401810191818101908684111561304b57600080fd5b8286015b848110156127d057604081890312156130685760008081fd5b613070612682565b6130798261287f565b8152613086858301612fdf565b8186015283529183019160400161304f565b6000604082840312156130aa57600080fd5b6130b2612682565b90506130bd8261287f565b81526130cb6020830161287f565b602082015292915050565b600060208083850312156130e957600080fd5b823567ffffffffffffffff8082111561310157600080fd5b908401906080828703121561311557600080fd5b61311d6126ab565b82358281111561312c57600080fd5b8301604081890381131561313f57600080fd5b613147612682565b82358581111561315657600080fd5b8301601f81018b1361316757600080fd5b80356131756127848261271d565b81815260069190911b8201890190898101908d83111561319457600080fd5b928a01925b828410156131e45785848f0312156131b15760008081fd5b6131b9612682565b84356131c481612741565b81526131d1858d01612fdf565b818d0152825292850192908a0190613199565b8452505050828701359150848211156131fc57600080fd5b6132088a83850161300b565b8188015283525061321d905087848601613098565b93810193909352506060013560408201529392505050565b805160408084528151848201819052600092602091908201906060870190855b818110156132ae578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858401529284019291850191600101613255565b50508583015187820388850152805180835290840192506000918401905b8083101561331d578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858301529284019260019290920191908501906132cc565b50979650505050505050565b602081526000611ee56020830184613235565b604081016118e78284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561338257613382612c98565b5092915050565b6020815260008251608060208401526133a560a0840182613235565b905060208401516133d06040850182805167ffffffffffffffff908116835260209182015116910152565b5060408401516080840152809150509291505056fea164736f6c6343000818000a", +} + +var CommitStoreABI = CommitStoreMetaData.ABI + +var CommitStoreBin = CommitStoreMetaData.Bin + +func DeployCommitStore(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig CommitStoreStaticConfig) (common.Address, *types.Transaction, *CommitStore, error) { + parsed, err := CommitStoreMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CommitStoreBin), backend, staticConfig) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CommitStore{address: address, abi: *parsed, CommitStoreCaller: CommitStoreCaller{contract: contract}, CommitStoreTransactor: CommitStoreTransactor{contract: contract}, CommitStoreFilterer: CommitStoreFilterer{contract: contract}}, nil +} + +type CommitStore struct { + address common.Address + abi abi.ABI + CommitStoreCaller + CommitStoreTransactor + CommitStoreFilterer +} + +type CommitStoreCaller struct { + contract *bind.BoundContract +} + +type CommitStoreTransactor struct { + contract *bind.BoundContract +} + +type CommitStoreFilterer struct { + contract *bind.BoundContract +} + +type CommitStoreSession struct { + Contract *CommitStore + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type CommitStoreCallerSession struct { + Contract *CommitStoreCaller + CallOpts bind.CallOpts +} + +type CommitStoreTransactorSession struct { + Contract *CommitStoreTransactor + TransactOpts bind.TransactOpts +} + +type CommitStoreRaw struct { + Contract *CommitStore +} + +type CommitStoreCallerRaw struct { + Contract *CommitStoreCaller +} + +type CommitStoreTransactorRaw struct { + Contract *CommitStoreTransactor +} + +func NewCommitStore(address common.Address, backend bind.ContractBackend) (*CommitStore, error) { + abi, err := abi.JSON(strings.NewReader(CommitStoreABI)) + if err != nil { + return nil, err + } + contract, err := bindCommitStore(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CommitStore{address: address, abi: abi, CommitStoreCaller: CommitStoreCaller{contract: contract}, CommitStoreTransactor: CommitStoreTransactor{contract: contract}, CommitStoreFilterer: CommitStoreFilterer{contract: contract}}, nil +} + +func NewCommitStoreCaller(address common.Address, caller bind.ContractCaller) (*CommitStoreCaller, error) { + contract, err := bindCommitStore(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CommitStoreCaller{contract: contract}, nil +} + +func NewCommitStoreTransactor(address common.Address, transactor bind.ContractTransactor) (*CommitStoreTransactor, error) { + contract, err := bindCommitStore(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CommitStoreTransactor{contract: contract}, nil +} + +func NewCommitStoreFilterer(address common.Address, filterer bind.ContractFilterer) (*CommitStoreFilterer, error) { + contract, err := bindCommitStore(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CommitStoreFilterer{contract: contract}, nil +} + +func bindCommitStore(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CommitStoreMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_CommitStore *CommitStoreRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStore.Contract.CommitStoreCaller.contract.Call(opts, result, method, params...) +} + +func (_CommitStore *CommitStoreRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.Contract.CommitStoreTransactor.contract.Transfer(opts) +} + +func (_CommitStore *CommitStoreRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStore.Contract.CommitStoreTransactor.contract.Transact(opts, method, params...) +} + +func (_CommitStore *CommitStoreCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStore.Contract.contract.Call(opts, result, method, params...) +} + +func (_CommitStore *CommitStoreTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.Contract.contract.Transfer(opts) +} + +func (_CommitStore *CommitStoreTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStore.Contract.contract.Transact(opts, method, params...) +} + +func (_CommitStore *CommitStoreCaller) GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(CommitStoreDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreDynamicConfig)).(*CommitStoreDynamicConfig) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStore.Contract.GetDynamicConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStore.Contract.GetDynamicConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getExpectedNextSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStore.Contract.GetExpectedNextSequenceNumber(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStore.Contract.GetExpectedNextSequenceNumber(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getLatestPriceEpochAndRound") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStore.Contract.GetLatestPriceEpochAndRound(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStore.Contract.GetLatestPriceEpochAndRound(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getMerkleRoot", root) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStore.Contract.GetMerkleRoot(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCallerSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStore.Contract.GetMerkleRoot(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCaller) GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(CommitStoreStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreStaticConfig)).(*CommitStoreStaticConfig) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStore.Contract.GetStaticConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStore.Contract.GetStaticConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetTransmitters() ([]common.Address, error) { + return _CommitStore.Contract.GetTransmitters(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetTransmitters() ([]common.Address, error) { + return _CommitStore.Contract.GetTransmitters(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "isBlessed", root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStore.Contract.IsBlessed(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCallerSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStore.Contract.IsBlessed(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCaller) IsUnpausedAndNotCursed(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "isUnpausedAndNotCursed") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) IsUnpausedAndNotCursed() (bool, error) { + return _CommitStore.Contract.IsUnpausedAndNotCursed(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) IsUnpausedAndNotCursed() (bool, error) { + return _CommitStore.Contract.IsUnpausedAndNotCursed(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_CommitStore *CommitStoreSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStore.Contract.LatestConfigDetails(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStore.Contract.LatestConfigDetails(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_CommitStore *CommitStoreSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStore.Contract.LatestConfigDigestAndEpoch(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStore.Contract.LatestConfigDigestAndEpoch(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) Owner() (common.Address, error) { + return _CommitStore.Contract.Owner(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) Owner() (common.Address, error) { + return _CommitStore.Contract.Owner(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) Paused() (bool, error) { + return _CommitStore.Contract.Paused(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) Paused() (bool, error) { + return _CommitStore.Contract.Paused(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) TypeAndVersion() (string, error) { + return _CommitStore.Contract.TypeAndVersion(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) TypeAndVersion() (string, error) { + return _CommitStore.Contract.TypeAndVersion(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "verify", hashedLeaves, proofs, proofFlagBits) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStore.Contract.Verify(&_CommitStore.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStore *CommitStoreCallerSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStore.Contract.Verify(&_CommitStore.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStore *CommitStoreTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "acceptOwnership") +} + +func (_CommitStore *CommitStoreSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStore.Contract.AcceptOwnership(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStore.Contract.AcceptOwnership(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "pause") +} + +func (_CommitStore *CommitStoreSession) Pause() (*types.Transaction, error) { + return _CommitStore.Contract.Pause(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactorSession) Pause() (*types.Transaction, error) { + return _CommitStore.Contract.Pause(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "resetUnblessedRoots", rootToReset) +} + +func (_CommitStore *CommitStoreSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.ResetUnblessedRoots(&_CommitStore.TransactOpts, rootToReset) +} + +func (_CommitStore *CommitStoreTransactorSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.ResetUnblessedRoots(&_CommitStore.TransactOpts, rootToReset) +} + +func (_CommitStore *CommitStoreTransactor) SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "setLatestPriceEpochAndRound", latestPriceEpochAndRound) +} + +func (_CommitStore *CommitStoreSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStore.Contract.SetLatestPriceEpochAndRound(&_CommitStore.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStore *CommitStoreTransactorSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStore.Contract.SetLatestPriceEpochAndRound(&_CommitStore.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStore *CommitStoreTransactor) SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "setMinSeqNr", minSeqNr) +} + +func (_CommitStore *CommitStoreSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStore.Contract.SetMinSeqNr(&_CommitStore.TransactOpts, minSeqNr) +} + +func (_CommitStore *CommitStoreTransactorSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStore.Contract.SetMinSeqNr(&_CommitStore.TransactOpts, minSeqNr) +} + +func (_CommitStore *CommitStoreTransactor) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "setOCR2Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStore *CommitStoreSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStore.Contract.SetOCR2Config(&_CommitStore.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStore *CommitStoreTransactorSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStore.Contract.SetOCR2Config(&_CommitStore.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStore *CommitStoreTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "transferOwnership", to) +} + +func (_CommitStore *CommitStoreSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStore.Contract.TransferOwnership(&_CommitStore.TransactOpts, to) +} + +func (_CommitStore *CommitStoreTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStore.Contract.TransferOwnership(&_CommitStore.TransactOpts, to) +} + +func (_CommitStore *CommitStoreTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) +} + +func (_CommitStore *CommitStoreSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.Transmit(&_CommitStore.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStore *CommitStoreTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.Transmit(&_CommitStore.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStore *CommitStoreTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "unpause") +} + +func (_CommitStore *CommitStoreSession) Unpause() (*types.Transaction, error) { + return _CommitStore.Contract.Unpause(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactorSession) Unpause() (*types.Transaction, error) { + return _CommitStore.Contract.Unpause(&_CommitStore.TransactOpts) +} + +type CommitStoreConfigSetIterator struct { + Event *CommitStoreConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreConfigSetIterator) Error() error { + return it.fail +} + +func (it *CommitStoreConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreConfigSet struct { + StaticConfig CommitStoreStaticConfig + DynamicConfig CommitStoreDynamicConfig + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreConfigSetIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &CommitStoreConfigSetIterator{contract: _CommitStore.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreConfigSet) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseConfigSet(log types.Log) (*CommitStoreConfigSet, error) { + event := new(CommitStoreConfigSet) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreConfigSet0Iterator struct { + Event *CommitStoreConfigSet0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreConfigSet0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreConfigSet0Iterator) Error() error { + return it.fail +} + +func (it *CommitStoreConfigSet0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreConfigSet0 struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreConfigSet0Iterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return &CommitStoreConfigSet0Iterator{contract: _CommitStore.contract, event: "ConfigSet0", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet0) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreConfigSet0) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseConfigSet0(log types.Log) (*CommitStoreConfigSet0, error) { + event := new(CommitStoreConfigSet0) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreLatestPriceEpochAndRoundSetIterator struct { + Event *CommitStoreLatestPriceEpochAndRoundSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreLatestPriceEpochAndRoundSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreLatestPriceEpochAndRoundSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreLatestPriceEpochAndRoundSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreLatestPriceEpochAndRoundSetIterator) Error() error { + return it.fail +} + +func (it *CommitStoreLatestPriceEpochAndRoundSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreLatestPriceEpochAndRoundSet struct { + OldEpochAndRound *big.Int + NewEpochAndRound *big.Int + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterLatestPriceEpochAndRoundSet(opts *bind.FilterOpts) (*CommitStoreLatestPriceEpochAndRoundSetIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "LatestPriceEpochAndRoundSet") + if err != nil { + return nil, err + } + return &CommitStoreLatestPriceEpochAndRoundSetIterator{contract: _CommitStore.contract, event: "LatestPriceEpochAndRoundSet", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchLatestPriceEpochAndRoundSet(opts *bind.WatchOpts, sink chan<- *CommitStoreLatestPriceEpochAndRoundSet) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "LatestPriceEpochAndRoundSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreLatestPriceEpochAndRoundSet) + if err := _CommitStore.contract.UnpackLog(event, "LatestPriceEpochAndRoundSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseLatestPriceEpochAndRoundSet(log types.Log) (*CommitStoreLatestPriceEpochAndRoundSet, error) { + event := new(CommitStoreLatestPriceEpochAndRoundSet) + if err := _CommitStore.contract.UnpackLog(event, "LatestPriceEpochAndRoundSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreOwnershipTransferRequestedIterator struct { + Event *CommitStoreOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreOwnershipTransferRequestedIterator{contract: _CommitStore.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreOwnershipTransferRequested) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseOwnershipTransferRequested(log types.Log) (*CommitStoreOwnershipTransferRequested, error) { + event := new(CommitStoreOwnershipTransferRequested) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreOwnershipTransferredIterator struct { + Event *CommitStoreOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *CommitStoreOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreOwnershipTransferredIterator{contract: _CommitStore.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreOwnershipTransferred) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseOwnershipTransferred(log types.Log) (*CommitStoreOwnershipTransferred, error) { + event := new(CommitStoreOwnershipTransferred) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStorePausedIterator struct { + Event *CommitStorePaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStorePausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStorePaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStorePaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStorePausedIterator) Error() error { + return it.fail +} + +func (it *CommitStorePausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStorePaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterPaused(opts *bind.FilterOpts) (*CommitStorePausedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &CommitStorePausedIterator{contract: _CommitStore.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStorePaused) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStorePaused) + if err := _CommitStore.contract.UnpackLog(event, "Paused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParsePaused(log types.Log) (*CommitStorePaused, error) { + event := new(CommitStorePaused) + if err := _CommitStore.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreReportAcceptedIterator struct { + Event *CommitStoreReportAccepted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreReportAcceptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreReportAcceptedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreReportAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreReportAccepted struct { + Report CommitStoreCommitReport + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreReportAcceptedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return &CommitStoreReportAcceptedIterator{contract: _CommitStore.contract, event: "ReportAccepted", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreReportAccepted) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreReportAccepted) + if err := _CommitStore.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseReportAccepted(log types.Log) (*CommitStoreReportAccepted, error) { + event := new(CommitStoreReportAccepted) + if err := _CommitStore.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreRootRemovedIterator struct { + Event *CommitStoreRootRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreRootRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreRootRemovedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreRootRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreRootRemoved struct { + Root [32]byte + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreRootRemovedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return &CommitStoreRootRemovedIterator{contract: _CommitStore.contract, event: "RootRemoved", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreRootRemoved) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreRootRemoved) + if err := _CommitStore.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseRootRemoved(log types.Log) (*CommitStoreRootRemoved, error) { + event := new(CommitStoreRootRemoved) + if err := _CommitStore.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreSequenceNumberSetIterator struct { + Event *CommitStoreSequenceNumberSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreSequenceNumberSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreSequenceNumberSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreSequenceNumberSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreSequenceNumberSetIterator) Error() error { + return it.fail +} + +func (it *CommitStoreSequenceNumberSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreSequenceNumberSet struct { + OldSeqNum uint64 + NewSeqNum uint64 + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterSequenceNumberSet(opts *bind.FilterOpts) (*CommitStoreSequenceNumberSetIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "SequenceNumberSet") + if err != nil { + return nil, err + } + return &CommitStoreSequenceNumberSetIterator{contract: _CommitStore.contract, event: "SequenceNumberSet", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchSequenceNumberSet(opts *bind.WatchOpts, sink chan<- *CommitStoreSequenceNumberSet) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "SequenceNumberSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreSequenceNumberSet) + if err := _CommitStore.contract.UnpackLog(event, "SequenceNumberSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseSequenceNumberSet(log types.Log) (*CommitStoreSequenceNumberSet, error) { + event := new(CommitStoreSequenceNumberSet) + if err := _CommitStore.contract.UnpackLog(event, "SequenceNumberSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreTransmittedIterator struct { + Event *CommitStoreTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreTransmittedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreTransmittedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &CommitStoreTransmittedIterator{contract: _CommitStore.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreTransmitted) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreTransmitted) + if err := _CommitStore.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseTransmitted(log types.Log) (*CommitStoreTransmitted, error) { + event := new(CommitStoreTransmitted) + if err := _CommitStore.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreUnpausedIterator struct { + Event *CommitStoreUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreUnpausedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreUnpausedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &CommitStoreUnpausedIterator{contract: _CommitStore.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreUnpaused) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreUnpaused) + if err := _CommitStore.contract.UnpackLog(event, "Unpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseUnpaused(log types.Log) (*CommitStoreUnpaused, error) { + event := new(CommitStoreUnpaused) + if err := _CommitStore.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_CommitStore *CommitStore) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _CommitStore.abi.Events["ConfigSet"].ID: + return _CommitStore.ParseConfigSet(log) + case _CommitStore.abi.Events["ConfigSet0"].ID: + return _CommitStore.ParseConfigSet0(log) + case _CommitStore.abi.Events["LatestPriceEpochAndRoundSet"].ID: + return _CommitStore.ParseLatestPriceEpochAndRoundSet(log) + case _CommitStore.abi.Events["OwnershipTransferRequested"].ID: + return _CommitStore.ParseOwnershipTransferRequested(log) + case _CommitStore.abi.Events["OwnershipTransferred"].ID: + return _CommitStore.ParseOwnershipTransferred(log) + case _CommitStore.abi.Events["Paused"].ID: + return _CommitStore.ParsePaused(log) + case _CommitStore.abi.Events["ReportAccepted"].ID: + return _CommitStore.ParseReportAccepted(log) + case _CommitStore.abi.Events["RootRemoved"].ID: + return _CommitStore.ParseRootRemoved(log) + case _CommitStore.abi.Events["SequenceNumberSet"].ID: + return _CommitStore.ParseSequenceNumberSet(log) + case _CommitStore.abi.Events["Transmitted"].ID: + return _CommitStore.ParseTransmitted(log) + case _CommitStore.abi.Events["Unpaused"].ID: + return _CommitStore.ParseUnpaused(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (CommitStoreConfigSet) Topic() common.Hash { + return common.HexToHash("0xc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec3") +} + +func (CommitStoreConfigSet0) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (CommitStoreLatestPriceEpochAndRoundSet) Topic() common.Hash { + return common.HexToHash("0xf0d557bfce33e354b41885eb9264448726cfe51f486ffa69809d2bf565456444") +} + +func (CommitStoreOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (CommitStoreOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (CommitStorePaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (CommitStoreReportAccepted) Topic() common.Hash { + return common.HexToHash("0x291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf5") +} + +func (CommitStoreRootRemoved) Topic() common.Hash { + return common.HexToHash("0x202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12") +} + +func (CommitStoreSequenceNumberSet) Topic() common.Hash { + return common.HexToHash("0xea59e8027e41fda1525220008cf2416797405065eb21b0ebd417bfc6d361b8de") +} + +func (CommitStoreTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (CommitStoreUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (_CommitStore *CommitStore) Address() common.Address { + return _CommitStore.address +} + +type CommitStoreInterface interface { + GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) + + GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) + + GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) + + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) + + IsUnpausedAndNotCursed(opts *bind.CallOpts) (bool, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + Paused(opts *bind.CallOpts) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Pause(opts *bind.TransactOpts) (*types.Transaction, error) + + ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) + + SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) + + SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) + + SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + Unpause(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*CommitStoreConfigSet, error) + + FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreConfigSet0Iterator, error) + + WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet0) (event.Subscription, error) + + ParseConfigSet0(log types.Log) (*CommitStoreConfigSet0, error) + + FilterLatestPriceEpochAndRoundSet(opts *bind.FilterOpts) (*CommitStoreLatestPriceEpochAndRoundSetIterator, error) + + WatchLatestPriceEpochAndRoundSet(opts *bind.WatchOpts, sink chan<- *CommitStoreLatestPriceEpochAndRoundSet) (event.Subscription, error) + + ParseLatestPriceEpochAndRoundSet(log types.Log) (*CommitStoreLatestPriceEpochAndRoundSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*CommitStoreOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*CommitStoreOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*CommitStorePausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStorePaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*CommitStorePaused, error) + + FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreReportAcceptedIterator, error) + + WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreReportAccepted) (event.Subscription, error) + + ParseReportAccepted(log types.Log) (*CommitStoreReportAccepted, error) + + FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreRootRemovedIterator, error) + + WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreRootRemoved) (event.Subscription, error) + + ParseRootRemoved(log types.Log) (*CommitStoreRootRemoved, error) + + FilterSequenceNumberSet(opts *bind.FilterOpts) (*CommitStoreSequenceNumberSetIterator, error) + + WatchSequenceNumberSet(opts *bind.WatchOpts, sink chan<- *CommitStoreSequenceNumberSet) (event.Subscription, error) + + ParseSequenceNumberSet(log types.Log) (*CommitStoreSequenceNumberSet, error) + + FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*CommitStoreTransmitted, error) + + FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*CommitStoreUnpaused, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/commit_store_1_0_0/commit_store_1_0_0.go b/core/gethwrappers/ccip/generated/commit_store_1_0_0/commit_store_1_0_0.go new file mode 100644 index 0000000000..30716b257c --- /dev/null +++ b/core/gethwrappers/ccip/generated/commit_store_1_0_0/commit_store_1_0_0.go @@ -0,0 +1,1951 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package commit_store_1_0_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommitStoreCommitReport struct { + PriceUpdates InternalPriceUpdates + Interval CommitStoreInterval + MerkleRoot [32]byte +} + +type CommitStoreDynamicConfig struct { + PriceRegistry common.Address +} + +type CommitStoreInterval struct { + Min uint64 + Max uint64 +} + +type CommitStoreStaticConfig struct { + ChainSelector uint64 + SourceChainSelector uint64 + OnRamp common.Address + ArmProxy common.Address +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var CommitStoreMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"usdPerToken\",\"type\":\"uint192\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint192\",\"name\":\"usdPerUnitGas\",\"type\":\"uint192\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b5060405162003788380380620037888339810160408190526200004d9162000272565b600033808281620000a55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d857620000d88162000192565b50505015156080524660a05260408101516001600160a01b0316158062000107575080516001600160401b0316155b806200011e575060208101516001600160401b0316155b8062000135575060608101516001600160a01b0316155b156200015457604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b0390811661010052606090910151166101205262000306565b336001600160a01b03821603620001ec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025557600080fd5b919050565b80516001600160a01b03811681146200025557600080fd5b6000608082840312156200028557600080fd5b604051608081016001600160401b0381118282101715620002b657634e487b7160e01b600052604160045260246000fd5b604052620002c4836200023d565b8152620002d4602084016200023d565b6020820152620002e7604084016200025a565b6040820152620002fa606084016200025a565b60608201529392505050565b60805160a05160c05160e05161010051610120516133f3620003956000396000818161026d01528181610537015281816111730152818161199f01528181611bee015261206b0152600081816102310152611bc70152600081816102010152611ba00152600081816101d10152611b710152600081816112ee015261133a015260006113b501526133f36000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806379ba5097116100e3578063ad7a22f81161008c578063f2fde38b11610066578063f2fde38b146104fa578063f47a86901461050d578063ff888fb11461052057600080fd5b8063ad7a22f8146104b4578063afcb95d7146104c7578063b1dc65a4146104e757600080fd5b80638da5cb5b116100bd5780638da5cb5b146104645780638db94e441461048c578063a7206cd61461049457600080fd5b806379ba50971461042457806381ff70481461042c5780638456cb591461045c57600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb146103b4578063666cab8d146103d05780637437ff9f146103e557600080fd5b806332048875146103795780633f4ba83a1461039a5780634120fccd146103a257600080fd5b8063181f5a7711610176578063181f5a77146103085780631ef381741461035157806329b980e41461036657600080fd5b806306285c691461019d5780630a6cd30d146102c057806310c374ed146102d8575b600080fd5b6102aa60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102b7919061265f565b60405180910390f35b6102c8610533565b60405190151581526020016102b7565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102b7565b6103446040518060400160405280601181526020017f436f6d6d697453746f726520312e302e3000000000000000000000000000000081525081565b6040516102b7919061271c565b61036461035f36600461296f565b6105ca565b005b610364610374366004612a3c565b610deb565b61038c610387366004612aaf565b610e37565b6040519081526020016102b7565b610364610f2d565b60095467ffffffffffffffff166102ef565b6009546d0100000000000000000000000000900460ff166102c8565b6103d8610f93565b6040516102b79190612b74565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102b7565b610364611002565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102b7565b6103646110ff565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b7565b6102c861116f565b61038c6104a2366004612b87565b6000908152600a602052604090205490565b6103646104c2366004612ba0565b611226565b6040805160018152600060208201819052918101919091526060016102b7565b6103646104f5366004612bbb565b611269565b610364610508366004612ca0565b611889565b61036461051b366004612cbd565b61189d565b6102c861052e366004612b87565b61193c565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c49190612cff565b15905090565b855185518560ff16601f831115610642576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106ac576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610639565b81831461073a576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610639565b610745816003612d50565b83116107ad576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610639565b6107b5611a10565b6107be86611a93565b60065460005b818110156108ba5760056000600683815481106107e3576107e3612d67565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061085357610853612d67565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108b381612d96565b90506107c4565b50895160005b81811015610c935760008c82815181106108dc576108dc612d67565b60200260200101519050600060028111156108f9576108f9612dce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561093857610938612dce565b1461099f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff81166109ec576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610a9c57610a9c612dce565b021790555090505060008c8381518110610ab857610ab8612d67565b6020026020010151905060006002811115610ad557610ad5612dce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b1457610b14612dce565b14610b7b576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff8116610bc8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610c7857610c78612dce565b0217905550905050505080610c8c90612d96565b90506108c0565b508a51610ca79060069060208e01906125a1565b508951610cbb9060079060208d01906125a1565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d41914691309190600090610d139063ffffffff16612dfd565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611c4f565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610dd599989796959493929190612e20565b60405180910390a1505050505050505050505050565b610df3611a10565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610e88576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610ef987878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250611cfa915050565b9050610f048161193c565b610f12576000915050610f24565b6000908152600a602052604090205490505b95945050505050565b610f35611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610ff857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610fcd575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314611083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610639565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611107611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610f89565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112009190612cff565b15801561122157506009546d0100000000000000000000000000900460ff16155b905090565b61122e611a10565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b611278878760208b013561201b565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146112eb5780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610639565b467f00000000000000000000000000000000000000000000000000000000000000001461136c576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610639565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561140e576002826020015183604001516113ef9190612eb6565b6113f99190612ecf565b611404906001612eb6565b60ff169050611424565b602082015161141e906001612eb6565b60ff1690505b86811461145d576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514611496576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156114d9576114d9612dce565b60028111156114ea576114ea612dce565b905250905060028160200151600281111561150757611507612dce565b14801561154e57506007816000015160ff168154811061152957611529612d67565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611584576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611592866020612d50565b61159d896020612d50565b6115a98c610144612f18565b6115b39190612f18565b6115bd9190612f18565b9050368114611601576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610639565b5060008a8a604051611614929190612f2b565b60405190819003812061162b918e90602001612f3b565b60405160208183030381529060405280519060200120905061164b61262b565b8860005b818110156118785760006001858a846020811061166e5761166e612d67565b61167b91901a601b612eb6565b8f8f8681811061168d5761168d612d67565b905060200201358e8e878181106116a6576116a6612d67565b90506020020135604051600081526020016040526040516116e3949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611705573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561178857611788612dce565b600281111561179957611799612dce565b90525090506001816020015160028111156117b6576117b6612dce565b146117ed576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061180457611804612d67565b602002015115611840576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061185b5761185b612d67565b9115156020909202015250611871905081612d96565b905061164f565b505050505050505050505050505050565b611891611a10565b61189a81612431565b50565b6118a5611a10565b60005b818110156119375760008383838181106118c4576118c4612d67565b9050602002013590506118d68161193c565b611926576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061191d9083815260200190565b60405180910390a15b5061193081612d96565b90506118a8565b505050565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156119e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0a9190612cff565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610639565b565b600081806020019051810190611aa99190612f4f565b805190915073ffffffffffffffffffffffffffffffffffffffff16611afa576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391611c43918490612f9b565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611c7399989796959493929190613018565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303611d3b576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590611d4f57506101018111155b611d85576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115611de6576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611e135786600081518110611e0157611e01612d67565b60200260200101519350505050612014565b60008167ffffffffffffffff811115611e2e57611e2e61272f565b604051908082528060200260200182016040528015611e57578160200160208202803683370190505b50905060008080805b85811015611f9a5760006001821b8b811603611ebb5788851015611ea4578c5160018601958e918110611e9557611e95612d67565b60200260200101519050611edd565b8551600185019487918110611e9557611e95612d67565b8b5160018401938d918110611ed257611ed2612d67565b602002602001015190505b600089861015611f0d578d5160018701968f918110611efe57611efe612d67565b60200260200101519050611f2f565b8651600186019588918110611f2457611f24612d67565b602002602001015190505b82851115611f69576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f738282612526565b878481518110611f8557611f85612d67565b60209081029190910101525050600101611e60565b506001850382148015611fac57508683145b8015611fb757508581145b611fed576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061200257612002612d67565b60200260200101519750505050505050505b9392505050565b6009546d0100000000000000000000000000900460ff1615612069576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f89190612cff565b1561212f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061213d83850185613113565b8051515190915015158061215f575080516020015167ffffffffffffffff1615155b156122975760095464ffffffffff8084166801000000000000000090920416101561225c57600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f866548c900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092169163866548c9916122169160040161332a565b600060405180830381600087803b15801561223057600080fd5b505af1158015612244573d6000803e3d6000fd5b5050505060408101516122575750505050565b612297565b6040810151612297576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff90811691161415806122d2575060208082015190810151905167ffffffffffffffff9182169116115b1561230f5780602001516040517fbb1ae18d000000000000000000000000000000000000000000000000000000008152600401610639919061333d565b604081015161234a576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415612393576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015101516123a6906001613362565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517fe81b49e583122eb290c46fc255c962b9a2dec468816c00fb7a2e6ebc42dc92d49061242390839061338a565b60405180910390a150505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610639565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008183106125685760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612014565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612014565b82805482825590600052602060002090810192821561261b579160200282015b8281111561261b57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125c1565b5061262792915061264a565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115612627576000815560010161264b565b60808101611a0a828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b818110156126de576020818501810151868301820152016126c2565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061201460208301846126b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156127815761278161272f565b60405290565b6040516060810167ffffffffffffffff811182821017156127815761278161272f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127f1576127f161272f565b604052919050565b600067ffffffffffffffff8211156128135761281361272f565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461189a57600080fd5b600082601f83011261285057600080fd5b81356020612865612860836127f9565b6127aa565b82815260059290921b8401810191818101908684111561288457600080fd5b8286015b848110156128a857803561289b8161281d565b8352918301918301612888565b509695505050505050565b803560ff811681146128c457600080fd5b919050565b600082601f8301126128da57600080fd5b813567ffffffffffffffff8111156128f4576128f461272f565b61292560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127aa565b81815284602083860101111561293a57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146128c457600080fd5b60008060008060008060c0878903121561298857600080fd5b863567ffffffffffffffff808211156129a057600080fd5b6129ac8a838b0161283f565b975060208901359150808211156129c257600080fd5b6129ce8a838b0161283f565b96506129dc60408a016128b3565b955060608901359150808211156129f257600080fd5b6129fe8a838b016128c9565b9450612a0c60808a01612957565b935060a0890135915080821115612a2257600080fd5b50612a2f89828a016128c9565b9150509295509295509295565b600060208284031215612a4e57600080fd5b813564ffffffffff8116811461201457600080fd5b60008083601f840112612a7557600080fd5b50813567ffffffffffffffff811115612a8d57600080fd5b6020830191508360208260051b8501011115612aa857600080fd5b9250929050565b600080600080600060608688031215612ac757600080fd5b853567ffffffffffffffff80821115612adf57600080fd5b612aeb89838a01612a63565b90975095506020880135915080821115612b0457600080fd5b50612b1188828901612a63565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612b6957815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612b37565b509495945050505050565b6020815260006120146020830184612b23565b600060208284031215612b9957600080fd5b5035919050565b600060208284031215612bb257600080fd5b61201482612957565b60008060008060008060008060e0898b031215612bd757600080fd5b606089018a811115612be857600080fd5b8998503567ffffffffffffffff80821115612c0257600080fd5b818b0191508b601f830112612c1657600080fd5b813581811115612c2557600080fd5b8c6020828501011115612c3757600080fd5b6020830199508098505060808b0135915080821115612c5557600080fd5b612c618c838d01612a63565b909750955060a08b0135915080821115612c7a57600080fd5b50612c878b828c01612a63565b999c989b50969995989497949560c00135949350505050565b600060208284031215612cb257600080fd5b81356120148161281d565b60008060208385031215612cd057600080fd5b823567ffffffffffffffff811115612ce757600080fd5b612cf385828601612a63565b90969095509350505050565b600060208284031215612d1157600080fd5b8151801515811461201457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a0a57611a0a612d21565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612dc757612dc7612d21565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612e1657612e16612d21565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612e508184018a612b23565b90508281036080840152612e648189612b23565b905060ff871660a084015282810360c0840152612e8181876126b8565b905067ffffffffffffffff851660e0840152828103610100840152612ea681856126b8565b9c9b505050505050505050505050565b60ff8181168382160190811115611a0a57611a0a612d21565b600060ff831680612f09577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a0a57611a0a612d21565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612f6157600080fd5b6040516020810181811067ffffffffffffffff82111715612f8457612f8461272f565b6040528251612f928161281d565b81529392505050565b60a08101612ff4828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b16604085015281606085015261305f8285018b612b23565b91508382036080850152613073828a612b23565b915060ff881660a085015283820360c085015261309082886126b8565b90861660e08501528381036101008501529050612ea681856126b8565b803577ffffffffffffffffffffffffffffffffffffffffffffffff811681146128c457600080fd5b6000604082840312156130e757600080fd5b6130ef61275e565b90506130fa82612957565b815261310860208301612957565b602082015292915050565b6000602080838503121561312657600080fd5b823567ffffffffffffffff8082111561313e57600080fd5b908401906080828703121561315257600080fd5b61315a612787565b82358281111561316957600080fd5b83016060818903121561317b57600080fd5b613183612787565b81358481111561319257600080fd5b82019350601f840189136131a557600080fd5b83356131b3612860826127f9565b81815260069190911b8501870190878101908b8311156131d257600080fd5b958801955b82871015613226576040878d0312156131f05760008081fd5b6131f861275e565b87356132038161281d565b8152613210888b016130ad565b818b0152825260409690960195908801906131d7565b8352506132369050828701612957565b86820152613246604083016130ad565b604082015282525061325a878486016130d5565b93810193909352506060013560408201529392505050565b805160608084528151908401819052600091602091908201906080860190845b818110156132e9578351805173ffffffffffffffffffffffffffffffffffffffff16845285015177ffffffffffffffffffffffffffffffffffffffffffffffff168584015292840192604090920191600101613292565b505067ffffffffffffffff83860151168387015260408501519250610f24604087018477ffffffffffffffffffffffffffffffffffffffffffffffff169052565b6020815260006120146020830184613272565b60408101611a0a8284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561338357613383612d21565b5092915050565b6020815260008251608060208401526133a660a0840182613272565b905060208401516133d16040850182805167ffffffffffffffff908116835260209182015116910152565b5060408401516080840152809150509291505056fea164736f6c6343000813000a", +} + +var CommitStoreABI = CommitStoreMetaData.ABI + +var CommitStoreBin = CommitStoreMetaData.Bin + +func DeployCommitStore(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig CommitStoreStaticConfig) (common.Address, *types.Transaction, *CommitStore, error) { + parsed, err := CommitStoreMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CommitStoreBin), backend, staticConfig) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CommitStore{CommitStoreCaller: CommitStoreCaller{contract: contract}, CommitStoreTransactor: CommitStoreTransactor{contract: contract}, CommitStoreFilterer: CommitStoreFilterer{contract: contract}}, nil +} + +type CommitStore struct { + address common.Address + abi abi.ABI + CommitStoreCaller + CommitStoreTransactor + CommitStoreFilterer +} + +type CommitStoreCaller struct { + contract *bind.BoundContract +} + +type CommitStoreTransactor struct { + contract *bind.BoundContract +} + +type CommitStoreFilterer struct { + contract *bind.BoundContract +} + +type CommitStoreSession struct { + Contract *CommitStore + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type CommitStoreCallerSession struct { + Contract *CommitStoreCaller + CallOpts bind.CallOpts +} + +type CommitStoreTransactorSession struct { + Contract *CommitStoreTransactor + TransactOpts bind.TransactOpts +} + +type CommitStoreRaw struct { + Contract *CommitStore +} + +type CommitStoreCallerRaw struct { + Contract *CommitStoreCaller +} + +type CommitStoreTransactorRaw struct { + Contract *CommitStoreTransactor +} + +func NewCommitStore(address common.Address, backend bind.ContractBackend) (*CommitStore, error) { + abi, err := abi.JSON(strings.NewReader(CommitStoreABI)) + if err != nil { + return nil, err + } + contract, err := bindCommitStore(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CommitStore{address: address, abi: abi, CommitStoreCaller: CommitStoreCaller{contract: contract}, CommitStoreTransactor: CommitStoreTransactor{contract: contract}, CommitStoreFilterer: CommitStoreFilterer{contract: contract}}, nil +} + +func NewCommitStoreCaller(address common.Address, caller bind.ContractCaller) (*CommitStoreCaller, error) { + contract, err := bindCommitStore(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CommitStoreCaller{contract: contract}, nil +} + +func NewCommitStoreTransactor(address common.Address, transactor bind.ContractTransactor) (*CommitStoreTransactor, error) { + contract, err := bindCommitStore(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CommitStoreTransactor{contract: contract}, nil +} + +func NewCommitStoreFilterer(address common.Address, filterer bind.ContractFilterer) (*CommitStoreFilterer, error) { + contract, err := bindCommitStore(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CommitStoreFilterer{contract: contract}, nil +} + +func bindCommitStore(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CommitStoreMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_CommitStore *CommitStoreRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStore.Contract.CommitStoreCaller.contract.Call(opts, result, method, params...) +} + +func (_CommitStore *CommitStoreRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.Contract.CommitStoreTransactor.contract.Transfer(opts) +} + +func (_CommitStore *CommitStoreRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStore.Contract.CommitStoreTransactor.contract.Transact(opts, method, params...) +} + +func (_CommitStore *CommitStoreCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStore.Contract.contract.Call(opts, result, method, params...) +} + +func (_CommitStore *CommitStoreTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.Contract.contract.Transfer(opts) +} + +func (_CommitStore *CommitStoreTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStore.Contract.contract.Transact(opts, method, params...) +} + +func (_CommitStore *CommitStoreCaller) GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(CommitStoreDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreDynamicConfig)).(*CommitStoreDynamicConfig) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStore.Contract.GetDynamicConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStore.Contract.GetDynamicConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getExpectedNextSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStore.Contract.GetExpectedNextSequenceNumber(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStore.Contract.GetExpectedNextSequenceNumber(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getLatestPriceEpochAndRound") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStore.Contract.GetLatestPriceEpochAndRound(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStore.Contract.GetLatestPriceEpochAndRound(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getMerkleRoot", root) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStore.Contract.GetMerkleRoot(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCallerSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStore.Contract.GetMerkleRoot(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCaller) GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(CommitStoreStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreStaticConfig)).(*CommitStoreStaticConfig) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStore.Contract.GetStaticConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStore.Contract.GetStaticConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetTransmitters() ([]common.Address, error) { + return _CommitStore.Contract.GetTransmitters(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetTransmitters() ([]common.Address, error) { + return _CommitStore.Contract.GetTransmitters(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) IsARMHealthy(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "isARMHealthy") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) IsARMHealthy() (bool, error) { + return _CommitStore.Contract.IsARMHealthy(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) IsARMHealthy() (bool, error) { + return _CommitStore.Contract.IsARMHealthy(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "isBlessed", root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStore.Contract.IsBlessed(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCallerSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStore.Contract.IsBlessed(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCaller) IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "isUnpausedAndARMHealthy") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) IsUnpausedAndARMHealthy() (bool, error) { + return _CommitStore.Contract.IsUnpausedAndARMHealthy(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) IsUnpausedAndARMHealthy() (bool, error) { + return _CommitStore.Contract.IsUnpausedAndARMHealthy(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_CommitStore *CommitStoreSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStore.Contract.LatestConfigDetails(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStore.Contract.LatestConfigDetails(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_CommitStore *CommitStoreSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStore.Contract.LatestConfigDigestAndEpoch(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStore.Contract.LatestConfigDigestAndEpoch(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) Owner() (common.Address, error) { + return _CommitStore.Contract.Owner(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) Owner() (common.Address, error) { + return _CommitStore.Contract.Owner(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) Paused() (bool, error) { + return _CommitStore.Contract.Paused(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) Paused() (bool, error) { + return _CommitStore.Contract.Paused(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) TypeAndVersion() (string, error) { + return _CommitStore.Contract.TypeAndVersion(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) TypeAndVersion() (string, error) { + return _CommitStore.Contract.TypeAndVersion(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "verify", hashedLeaves, proofs, proofFlagBits) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStore.Contract.Verify(&_CommitStore.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStore *CommitStoreCallerSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStore.Contract.Verify(&_CommitStore.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStore *CommitStoreTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "acceptOwnership") +} + +func (_CommitStore *CommitStoreSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStore.Contract.AcceptOwnership(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStore.Contract.AcceptOwnership(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "pause") +} + +func (_CommitStore *CommitStoreSession) Pause() (*types.Transaction, error) { + return _CommitStore.Contract.Pause(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactorSession) Pause() (*types.Transaction, error) { + return _CommitStore.Contract.Pause(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "resetUnblessedRoots", rootToReset) +} + +func (_CommitStore *CommitStoreSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.ResetUnblessedRoots(&_CommitStore.TransactOpts, rootToReset) +} + +func (_CommitStore *CommitStoreTransactorSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.ResetUnblessedRoots(&_CommitStore.TransactOpts, rootToReset) +} + +func (_CommitStore *CommitStoreTransactor) SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "setLatestPriceEpochAndRound", latestPriceEpochAndRound) +} + +func (_CommitStore *CommitStoreSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStore.Contract.SetLatestPriceEpochAndRound(&_CommitStore.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStore *CommitStoreTransactorSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStore.Contract.SetLatestPriceEpochAndRound(&_CommitStore.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStore *CommitStoreTransactor) SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "setMinSeqNr", minSeqNr) +} + +func (_CommitStore *CommitStoreSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStore.Contract.SetMinSeqNr(&_CommitStore.TransactOpts, minSeqNr) +} + +func (_CommitStore *CommitStoreTransactorSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStore.Contract.SetMinSeqNr(&_CommitStore.TransactOpts, minSeqNr) +} + +func (_CommitStore *CommitStoreTransactor) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "setOCR2Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStore *CommitStoreSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStore.Contract.SetOCR2Config(&_CommitStore.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStore *CommitStoreTransactorSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStore.Contract.SetOCR2Config(&_CommitStore.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStore *CommitStoreTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "transferOwnership", to) +} + +func (_CommitStore *CommitStoreSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStore.Contract.TransferOwnership(&_CommitStore.TransactOpts, to) +} + +func (_CommitStore *CommitStoreTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStore.Contract.TransferOwnership(&_CommitStore.TransactOpts, to) +} + +func (_CommitStore *CommitStoreTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) +} + +func (_CommitStore *CommitStoreSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.Transmit(&_CommitStore.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStore *CommitStoreTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.Transmit(&_CommitStore.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStore *CommitStoreTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "unpause") +} + +func (_CommitStore *CommitStoreSession) Unpause() (*types.Transaction, error) { + return _CommitStore.Contract.Unpause(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactorSession) Unpause() (*types.Transaction, error) { + return _CommitStore.Contract.Unpause(&_CommitStore.TransactOpts) +} + +type CommitStoreConfigSetIterator struct { + Event *CommitStoreConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreConfigSetIterator) Error() error { + return it.fail +} + +func (it *CommitStoreConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreConfigSet struct { + StaticConfig CommitStoreStaticConfig + DynamicConfig CommitStoreDynamicConfig + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreConfigSetIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &CommitStoreConfigSetIterator{contract: _CommitStore.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreConfigSet) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseConfigSet(log types.Log) (*CommitStoreConfigSet, error) { + event := new(CommitStoreConfigSet) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreConfigSet0Iterator struct { + Event *CommitStoreConfigSet0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreConfigSet0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreConfigSet0Iterator) Error() error { + return it.fail +} + +func (it *CommitStoreConfigSet0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreConfigSet0 struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreConfigSet0Iterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return &CommitStoreConfigSet0Iterator{contract: _CommitStore.contract, event: "ConfigSet0", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet0) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreConfigSet0) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseConfigSet0(log types.Log) (*CommitStoreConfigSet0, error) { + event := new(CommitStoreConfigSet0) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreOwnershipTransferRequestedIterator struct { + Event *CommitStoreOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreOwnershipTransferRequestedIterator{contract: _CommitStore.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreOwnershipTransferRequested) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseOwnershipTransferRequested(log types.Log) (*CommitStoreOwnershipTransferRequested, error) { + event := new(CommitStoreOwnershipTransferRequested) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreOwnershipTransferredIterator struct { + Event *CommitStoreOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *CommitStoreOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreOwnershipTransferredIterator{contract: _CommitStore.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreOwnershipTransferred) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseOwnershipTransferred(log types.Log) (*CommitStoreOwnershipTransferred, error) { + event := new(CommitStoreOwnershipTransferred) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStorePausedIterator struct { + Event *CommitStorePaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStorePausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStorePaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStorePaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStorePausedIterator) Error() error { + return it.fail +} + +func (it *CommitStorePausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStorePaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterPaused(opts *bind.FilterOpts) (*CommitStorePausedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &CommitStorePausedIterator{contract: _CommitStore.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStorePaused) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStorePaused) + if err := _CommitStore.contract.UnpackLog(event, "Paused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParsePaused(log types.Log) (*CommitStorePaused, error) { + event := new(CommitStorePaused) + if err := _CommitStore.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreReportAcceptedIterator struct { + Event *CommitStoreReportAccepted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreReportAcceptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreReportAcceptedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreReportAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreReportAccepted struct { + Report CommitStoreCommitReport + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreReportAcceptedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return &CommitStoreReportAcceptedIterator{contract: _CommitStore.contract, event: "ReportAccepted", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreReportAccepted) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreReportAccepted) + if err := _CommitStore.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseReportAccepted(log types.Log) (*CommitStoreReportAccepted, error) { + event := new(CommitStoreReportAccepted) + if err := _CommitStore.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreRootRemovedIterator struct { + Event *CommitStoreRootRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreRootRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreRootRemovedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreRootRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreRootRemoved struct { + Root [32]byte + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreRootRemovedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return &CommitStoreRootRemovedIterator{contract: _CommitStore.contract, event: "RootRemoved", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreRootRemoved) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreRootRemoved) + if err := _CommitStore.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseRootRemoved(log types.Log) (*CommitStoreRootRemoved, error) { + event := new(CommitStoreRootRemoved) + if err := _CommitStore.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreTransmittedIterator struct { + Event *CommitStoreTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreTransmittedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreTransmittedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &CommitStoreTransmittedIterator{contract: _CommitStore.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreTransmitted) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreTransmitted) + if err := _CommitStore.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseTransmitted(log types.Log) (*CommitStoreTransmitted, error) { + event := new(CommitStoreTransmitted) + if err := _CommitStore.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreUnpausedIterator struct { + Event *CommitStoreUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreUnpausedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreUnpausedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &CommitStoreUnpausedIterator{contract: _CommitStore.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreUnpaused) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreUnpaused) + if err := _CommitStore.contract.UnpackLog(event, "Unpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseUnpaused(log types.Log) (*CommitStoreUnpaused, error) { + event := new(CommitStoreUnpaused) + if err := _CommitStore.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_CommitStore *CommitStore) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _CommitStore.abi.Events["ConfigSet"].ID: + return _CommitStore.ParseConfigSet(log) + case _CommitStore.abi.Events["ConfigSet0"].ID: + return _CommitStore.ParseConfigSet0(log) + case _CommitStore.abi.Events["OwnershipTransferRequested"].ID: + return _CommitStore.ParseOwnershipTransferRequested(log) + case _CommitStore.abi.Events["OwnershipTransferred"].ID: + return _CommitStore.ParseOwnershipTransferred(log) + case _CommitStore.abi.Events["Paused"].ID: + return _CommitStore.ParsePaused(log) + case _CommitStore.abi.Events["ReportAccepted"].ID: + return _CommitStore.ParseReportAccepted(log) + case _CommitStore.abi.Events["RootRemoved"].ID: + return _CommitStore.ParseRootRemoved(log) + case _CommitStore.abi.Events["Transmitted"].ID: + return _CommitStore.ParseTransmitted(log) + case _CommitStore.abi.Events["Unpaused"].ID: + return _CommitStore.ParseUnpaused(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (CommitStoreConfigSet) Topic() common.Hash { + return common.HexToHash("0xc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec3") +} + +func (CommitStoreConfigSet0) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (CommitStoreOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (CommitStoreOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (CommitStorePaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (CommitStoreReportAccepted) Topic() common.Hash { + return common.HexToHash("0xe81b49e583122eb290c46fc255c962b9a2dec468816c00fb7a2e6ebc42dc92d4") +} + +func (CommitStoreRootRemoved) Topic() common.Hash { + return common.HexToHash("0x202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12") +} + +func (CommitStoreTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (CommitStoreUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (_CommitStore *CommitStore) Address() common.Address { + return _CommitStore.address +} + +type CommitStoreInterface interface { + GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) + + GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) + + GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) + + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + IsARMHealthy(opts *bind.CallOpts) (bool, error) + + IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) + + IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + Paused(opts *bind.CallOpts) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Pause(opts *bind.TransactOpts) (*types.Transaction, error) + + ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) + + SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) + + SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) + + SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + Unpause(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*CommitStoreConfigSet, error) + + FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreConfigSet0Iterator, error) + + WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet0) (event.Subscription, error) + + ParseConfigSet0(log types.Log) (*CommitStoreConfigSet0, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*CommitStoreOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*CommitStoreOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*CommitStorePausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStorePaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*CommitStorePaused, error) + + FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreReportAcceptedIterator, error) + + WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreReportAccepted) (event.Subscription, error) + + ParseReportAccepted(log types.Log) (*CommitStoreReportAccepted, error) + + FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreRootRemovedIterator, error) + + WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreRootRemoved) (event.Subscription, error) + + ParseRootRemoved(log types.Log) (*CommitStoreRootRemoved, error) + + FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*CommitStoreTransmitted, error) + + FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*CommitStoreUnpaused, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/commit_store_1_2_0/commit_store.go b/core/gethwrappers/ccip/generated/commit_store_1_2_0/commit_store.go new file mode 100644 index 0000000000..fa757f287d --- /dev/null +++ b/core/gethwrappers/ccip/generated/commit_store_1_2_0/commit_store.go @@ -0,0 +1,1955 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package commit_store_1_2_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommitStoreCommitReport struct { + PriceUpdates InternalPriceUpdates + Interval CommitStoreInterval + MerkleRoot [32]byte +} + +type CommitStoreDynamicConfig struct { + PriceRegistry common.Address +} + +type CommitStoreInterval struct { + Min uint64 + Max uint64 +} + +type CommitStoreStaticConfig struct { + ChainSelector uint64 + SourceChainSelector uint64 + OnRamp common.Address + ArmProxy common.Address +} + +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var CommitStoreMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b506040516200384c3803806200384c8339810160408190526200004d9162000272565b600033808281620000a55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d857620000d88162000192565b50505015156080524660a05260408101516001600160a01b0316158062000107575080516001600160401b0316155b806200011e575060208101516001600160401b0316155b8062000135575060608101516001600160a01b0316155b156200015457604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b0390811661010052606090910151166101205262000306565b336001600160a01b03821603620001ec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025557600080fd5b919050565b80516001600160a01b03811681146200025557600080fd5b6000608082840312156200028557600080fd5b604051608081016001600160401b0381118282101715620002b657634e487b7160e01b600052604160045260246000fd5b604052620002c4836200023d565b8152620002d4602084016200023d565b6020820152620002e7604084016200025a565b6040820152620002fa606084016200025a565b60608201529392505050565b60805160a05160c05160e05161010051610120516134b7620003956000396000818161026d01528181610537015281816111730152818161199f01528181611bee015261206b0152600081816102310152611bc70152600081816102010152611ba00152600081816101d10152611b710152600081816112ee015261133a015260006113b501526134b76000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806379ba5097116100e3578063ad7a22f81161008c578063f2fde38b11610066578063f2fde38b146104fa578063f47a86901461050d578063ff888fb11461052057600080fd5b8063ad7a22f8146104b4578063afcb95d7146104c7578063b1dc65a4146104e757600080fd5b80638da5cb5b116100bd5780638da5cb5b146104645780638db94e441461048c578063a7206cd61461049457600080fd5b806379ba50971461042457806381ff70481461042c5780638456cb591461045c57600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb146103b4578063666cab8d146103d05780637437ff9f146103e557600080fd5b806332048875146103795780633f4ba83a1461039a5780634120fccd146103a257600080fd5b8063181f5a7711610176578063181f5a77146103085780631ef381741461035157806329b980e41461036657600080fd5b806306285c691461019d5780630a6cd30d146102c057806310c374ed146102d8575b600080fd5b6102aa60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102b79190612656565b60405180910390f35b6102c8610533565b60405190151581526020016102b7565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102b7565b6103446040518060400160405280601181526020017f436f6d6d697453746f726520312e322e3000000000000000000000000000000081525081565b6040516102b79190612713565b61036461035f366004612966565b6105ca565b005b610364610374366004612a33565b610deb565b61038c610387366004612aa6565b610e37565b6040519081526020016102b7565b610364610f2d565b60095467ffffffffffffffff166102ef565b6009546d0100000000000000000000000000900460ff166102c8565b6103d8610f93565b6040516102b79190612b6b565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102b7565b610364611002565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102b7565b6103646110ff565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b7565b6102c861116f565b61038c6104a2366004612b7e565b6000908152600a602052604090205490565b6103646104c2366004612b97565b611226565b6040805160018152600060208201819052918101919091526060016102b7565b6103646104f5366004612bb2565b611269565b610364610508366004612c97565b611889565b61036461051b366004612cb4565b61189d565b6102c861052e366004612b7e565b61193c565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c49190612cf6565b15905090565b855185518560ff16601f831115610642576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106ac576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610639565b81831461073a576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610639565b610745816003612d47565b83116107ad576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610639565b6107b5611a10565b6107be86611a93565b60065460005b818110156108ba5760056000600683815481106107e3576107e3612d5e565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061085357610853612d5e565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108b381612d8d565b90506107c4565b50895160005b81811015610c935760008c82815181106108dc576108dc612d5e565b60200260200101519050600060028111156108f9576108f9612dc5565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561093857610938612dc5565b1461099f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff81166109ec576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610a9c57610a9c612dc5565b021790555090505060008c8381518110610ab857610ab8612d5e565b6020026020010151905060006002811115610ad557610ad5612dc5565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b1457610b14612dc5565b14610b7b576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff8116610bc8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610c7857610c78612dc5565b0217905550905050505080610c8c90612d8d565b90506108c0565b508a51610ca79060069060208e0190612598565b508951610cbb9060079060208d0190612598565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d41914691309190600090610d139063ffffffff16612df4565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611c4f565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610dd599989796959493929190612e17565b60405180910390a1505050505050505050505050565b610df3611a10565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610e88576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610ef987878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250611cfa915050565b9050610f048161193c565b610f12576000915050610f24565b6000908152600a602052604090205490505b95945050505050565b610f35611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610ff857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610fcd575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314611083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610639565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611107611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610f89565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112009190612cf6565b15801561122157506009546d0100000000000000000000000000900460ff16155b905090565b61122e611a10565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b611278878760208b013561201b565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146112eb5780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610639565b467f00000000000000000000000000000000000000000000000000000000000000001461136c576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610639565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561140e576002826020015183604001516113ef9190612ead565b6113f99190612ec6565b611404906001612ead565b60ff169050611424565b602082015161141e906001612ead565b60ff1690505b86811461145d576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514611496576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156114d9576114d9612dc5565b60028111156114ea576114ea612dc5565b905250905060028160200151600281111561150757611507612dc5565b14801561154e57506007816000015160ff168154811061152957611529612d5e565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611584576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611592866020612d47565b61159d896020612d47565b6115a98c610144612f0f565b6115b39190612f0f565b6115bd9190612f0f565b9050368114611601576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610639565b5060008a8a604051611614929190612f22565b60405190819003812061162b918e90602001612f32565b60405160208183030381529060405280519060200120905061164b612622565b8860005b818110156118785760006001858a846020811061166e5761166e612d5e565b61167b91901a601b612ead565b8f8f8681811061168d5761168d612d5e565b905060200201358e8e878181106116a6576116a6612d5e565b90506020020135604051600081526020016040526040516116e3949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611705573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561178857611788612dc5565b600281111561179957611799612dc5565b90525090506001816020015160028111156117b6576117b6612dc5565b146117ed576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061180457611804612d5e565b602002015115611840576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061185b5761185b612d5e565b9115156020909202015250611871905081612d8d565b905061164f565b505050505050505050505050505050565b611891611a10565b61189a81612428565b50565b6118a5611a10565b60005b818110156119375760008383838181106118c4576118c4612d5e565b9050602002013590506118d68161193c565b611926576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061191d9083815260200190565b60405180910390a15b5061193081612d8d565b90506118a8565b505050565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156119e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0a9190612cf6565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610639565b565b600081806020019051810190611aa99190612f46565b805190915073ffffffffffffffffffffffffffffffffffffffff16611afa576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391611c43918490612f92565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611c739998979695949392919061300f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303611d3b576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590611d4f57506101018111155b611d85576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115611de6576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611e135786600081518110611e0157611e01612d5e565b60200260200101519350505050612014565b60008167ffffffffffffffff811115611e2e57611e2e612726565b604051908082528060200260200182016040528015611e57578160200160208202803683370190505b50905060008080805b85811015611f9a5760006001821b8b811603611ebb5788851015611ea4578c5160018601958e918110611e9557611e95612d5e565b60200260200101519050611edd565b8551600185019487918110611e9557611e95612d5e565b8b5160018401938d918110611ed257611ed2612d5e565b602002602001015190505b600089861015611f0d578d5160018701968f918110611efe57611efe612d5e565b60200260200101519050611f2f565b8651600186019588918110611f2457611f24612d5e565b602002602001015190505b82851115611f69576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f73828261251d565b878481518110611f8557611f85612d5e565b60209081029190910101525050600101611e60565b506001850382148015611fac57508683145b8015611fb757508581145b611fed576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061200257612002612d5e565b60200260200101519750505050505050505b9392505050565b6009546d0100000000000000000000000000900460ff1615612069576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f89190612cf6565b1561212f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061213d8385018561319b565b8051515190915015158061215657508051602001515115155b1561228e5760095464ffffffffff8084166801000000000000000090920416101561225357600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f9161220d916004016133ee565b600060405180830381600087803b15801561222757600080fd5b505af115801561223b573d6000803e3d6000fd5b50505050604081015161224e5750505050565b61228e565b604081015161228e576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff90811691161415806122c9575060208082015190810151905167ffffffffffffffff9182169116115b156123065780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016106399190613401565b6040810151612341576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a60205220541561238a576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602080820151015161239d906001613426565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf59061241a90839061344e565b60405180910390a150505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610639565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081831061255f5760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612014565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612014565b828054828255906000526020600020908101928215612612579160200282015b8281111561261257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125b8565b5061261e929150612641565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561261e5760008155600101612642565b60808101611a0a828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b818110156126d5576020818501810151868301820152016126b9565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061201460208301846126af565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561277857612778612726565b60405290565b6040516060810167ffffffffffffffff8111828210171561277857612778612726565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127e8576127e8612726565b604052919050565b600067ffffffffffffffff82111561280a5761280a612726565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461189a57600080fd5b600082601f83011261284757600080fd5b8135602061285c612857836127f0565b6127a1565b82815260059290921b8401810191818101908684111561287b57600080fd5b8286015b8481101561289f57803561289281612814565b835291830191830161287f565b509695505050505050565b803560ff811681146128bb57600080fd5b919050565b600082601f8301126128d157600080fd5b813567ffffffffffffffff8111156128eb576128eb612726565b61291c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127a1565b81815284602083860101111561293157600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146128bb57600080fd5b60008060008060008060c0878903121561297f57600080fd5b863567ffffffffffffffff8082111561299757600080fd5b6129a38a838b01612836565b975060208901359150808211156129b957600080fd5b6129c58a838b01612836565b96506129d360408a016128aa565b955060608901359150808211156129e957600080fd5b6129f58a838b016128c0565b9450612a0360808a0161294e565b935060a0890135915080821115612a1957600080fd5b50612a2689828a016128c0565b9150509295509295509295565b600060208284031215612a4557600080fd5b813564ffffffffff8116811461201457600080fd5b60008083601f840112612a6c57600080fd5b50813567ffffffffffffffff811115612a8457600080fd5b6020830191508360208260051b8501011115612a9f57600080fd5b9250929050565b600080600080600060608688031215612abe57600080fd5b853567ffffffffffffffff80821115612ad657600080fd5b612ae289838a01612a5a565b90975095506020880135915080821115612afb57600080fd5b50612b0888828901612a5a565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612b6057815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612b2e565b509495945050505050565b6020815260006120146020830184612b1a565b600060208284031215612b9057600080fd5b5035919050565b600060208284031215612ba957600080fd5b6120148261294e565b60008060008060008060008060e0898b031215612bce57600080fd5b606089018a811115612bdf57600080fd5b8998503567ffffffffffffffff80821115612bf957600080fd5b818b0191508b601f830112612c0d57600080fd5b813581811115612c1c57600080fd5b8c6020828501011115612c2e57600080fd5b6020830199508098505060808b0135915080821115612c4c57600080fd5b612c588c838d01612a5a565b909750955060a08b0135915080821115612c7157600080fd5b50612c7e8b828c01612a5a565b999c989b50969995989497949560c00135949350505050565b600060208284031215612ca957600080fd5b813561201481612814565b60008060208385031215612cc757600080fd5b823567ffffffffffffffff811115612cde57600080fd5b612cea85828601612a5a565b90969095509350505050565b600060208284031215612d0857600080fd5b8151801515811461201457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a0a57611a0a612d18565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612dbe57612dbe612d18565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612e0d57612e0d612d18565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612e478184018a612b1a565b90508281036080840152612e5b8189612b1a565b905060ff871660a084015282810360c0840152612e7881876126af565b905067ffffffffffffffff851660e0840152828103610100840152612e9d81856126af565b9c9b505050505050505050505050565b60ff8181168382160190811115611a0a57611a0a612d18565b600060ff831680612f00577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a0a57611a0a612d18565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612f5857600080fd5b6040516020810181811067ffffffffffffffff82111715612f7b57612f7b612726565b6040528251612f8981612814565b81529392505050565b60a08101612feb828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526130568285018b612b1a565b9150838203608085015261306a828a612b1a565b915060ff881660a085015283820360c085015261308782886126af565b90861660e08501528381036101008501529050612e9d81856126af565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146128bb57600080fd5b600082601f8301126130e157600080fd5b813560206130f1612857836127f0565b82815260069290921b8401810191818101908684111561311057600080fd5b8286015b8481101561289f576040818903121561312d5760008081fd5b613135612755565b61313e8261294e565b815261314b8583016130a4565b81860152835291830191604001613114565b60006040828403121561316f57600080fd5b613177612755565b90506131828261294e565b81526131906020830161294e565b602082015292915050565b600060208083850312156131ae57600080fd5b823567ffffffffffffffff808211156131c657600080fd5b90840190608082870312156131da57600080fd5b6131e261277e565b8235828111156131f157600080fd5b8301604081890381131561320457600080fd5b61320c612755565b82358581111561321b57600080fd5b8301601f81018b1361322c57600080fd5b803561323a612857826127f0565b81815260069190911b8201890190898101908d83111561325957600080fd5b928a01925b828410156132a95785848f0312156132765760008081fd5b61327e612755565b843561328981612814565b8152613296858d016130a4565b818d0152825292850192908a019061325e565b845250505082870135858111156132bf57600080fd5b6132cb8b8286016130d0565b828901525083526132de8986880161315d565b8684015260608501358184015250508094505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b81811015613373578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685840152928401929185019160010161331a565b50508583015187820388850152805180835290840192506000918401905b808310156133e2578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685830152928401926001929092019190850190613391565b50979650505050505050565b60208152600061201460208301846132fa565b60408101611a0a8284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561344757613447612d18565b5092915050565b60208152600082516080602084015261346a60a08401826132fa565b905060208401516134956040850182805167ffffffffffffffff908116835260209182015116910152565b5060408401516080840152809150509291505056fea164736f6c6343000813000a", +} + +var CommitStoreABI = CommitStoreMetaData.ABI + +var CommitStoreBin = CommitStoreMetaData.Bin + +func DeployCommitStore(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig CommitStoreStaticConfig) (common.Address, *types.Transaction, *CommitStore, error) { + parsed, err := CommitStoreMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CommitStoreBin), backend, staticConfig) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CommitStore{address: address, abi: *parsed, CommitStoreCaller: CommitStoreCaller{contract: contract}, CommitStoreTransactor: CommitStoreTransactor{contract: contract}, CommitStoreFilterer: CommitStoreFilterer{contract: contract}}, nil +} + +type CommitStore struct { + address common.Address + abi abi.ABI + CommitStoreCaller + CommitStoreTransactor + CommitStoreFilterer +} + +type CommitStoreCaller struct { + contract *bind.BoundContract +} + +type CommitStoreTransactor struct { + contract *bind.BoundContract +} + +type CommitStoreFilterer struct { + contract *bind.BoundContract +} + +type CommitStoreSession struct { + Contract *CommitStore + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type CommitStoreCallerSession struct { + Contract *CommitStoreCaller + CallOpts bind.CallOpts +} + +type CommitStoreTransactorSession struct { + Contract *CommitStoreTransactor + TransactOpts bind.TransactOpts +} + +type CommitStoreRaw struct { + Contract *CommitStore +} + +type CommitStoreCallerRaw struct { + Contract *CommitStoreCaller +} + +type CommitStoreTransactorRaw struct { + Contract *CommitStoreTransactor +} + +func NewCommitStore(address common.Address, backend bind.ContractBackend) (*CommitStore, error) { + abi, err := abi.JSON(strings.NewReader(CommitStoreABI)) + if err != nil { + return nil, err + } + contract, err := bindCommitStore(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CommitStore{address: address, abi: abi, CommitStoreCaller: CommitStoreCaller{contract: contract}, CommitStoreTransactor: CommitStoreTransactor{contract: contract}, CommitStoreFilterer: CommitStoreFilterer{contract: contract}}, nil +} + +func NewCommitStoreCaller(address common.Address, caller bind.ContractCaller) (*CommitStoreCaller, error) { + contract, err := bindCommitStore(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CommitStoreCaller{contract: contract}, nil +} + +func NewCommitStoreTransactor(address common.Address, transactor bind.ContractTransactor) (*CommitStoreTransactor, error) { + contract, err := bindCommitStore(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CommitStoreTransactor{contract: contract}, nil +} + +func NewCommitStoreFilterer(address common.Address, filterer bind.ContractFilterer) (*CommitStoreFilterer, error) { + contract, err := bindCommitStore(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CommitStoreFilterer{contract: contract}, nil +} + +func bindCommitStore(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CommitStoreMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_CommitStore *CommitStoreRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStore.Contract.CommitStoreCaller.contract.Call(opts, result, method, params...) +} + +func (_CommitStore *CommitStoreRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.Contract.CommitStoreTransactor.contract.Transfer(opts) +} + +func (_CommitStore *CommitStoreRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStore.Contract.CommitStoreTransactor.contract.Transact(opts, method, params...) +} + +func (_CommitStore *CommitStoreCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStore.Contract.contract.Call(opts, result, method, params...) +} + +func (_CommitStore *CommitStoreTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.Contract.contract.Transfer(opts) +} + +func (_CommitStore *CommitStoreTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStore.Contract.contract.Transact(opts, method, params...) +} + +func (_CommitStore *CommitStoreCaller) GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(CommitStoreDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreDynamicConfig)).(*CommitStoreDynamicConfig) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStore.Contract.GetDynamicConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStore.Contract.GetDynamicConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getExpectedNextSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStore.Contract.GetExpectedNextSequenceNumber(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStore.Contract.GetExpectedNextSequenceNumber(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getLatestPriceEpochAndRound") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStore.Contract.GetLatestPriceEpochAndRound(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStore.Contract.GetLatestPriceEpochAndRound(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getMerkleRoot", root) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStore.Contract.GetMerkleRoot(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCallerSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStore.Contract.GetMerkleRoot(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCaller) GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(CommitStoreStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreStaticConfig)).(*CommitStoreStaticConfig) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStore.Contract.GetStaticConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStore.Contract.GetStaticConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetTransmitters() ([]common.Address, error) { + return _CommitStore.Contract.GetTransmitters(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetTransmitters() ([]common.Address, error) { + return _CommitStore.Contract.GetTransmitters(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) IsARMHealthy(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "isARMHealthy") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) IsARMHealthy() (bool, error) { + return _CommitStore.Contract.IsARMHealthy(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) IsARMHealthy() (bool, error) { + return _CommitStore.Contract.IsARMHealthy(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "isBlessed", root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStore.Contract.IsBlessed(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCallerSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStore.Contract.IsBlessed(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCaller) IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "isUnpausedAndARMHealthy") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) IsUnpausedAndARMHealthy() (bool, error) { + return _CommitStore.Contract.IsUnpausedAndARMHealthy(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) IsUnpausedAndARMHealthy() (bool, error) { + return _CommitStore.Contract.IsUnpausedAndARMHealthy(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_CommitStore *CommitStoreSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStore.Contract.LatestConfigDetails(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStore.Contract.LatestConfigDetails(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_CommitStore *CommitStoreSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStore.Contract.LatestConfigDigestAndEpoch(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStore.Contract.LatestConfigDigestAndEpoch(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) Owner() (common.Address, error) { + return _CommitStore.Contract.Owner(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) Owner() (common.Address, error) { + return _CommitStore.Contract.Owner(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) Paused() (bool, error) { + return _CommitStore.Contract.Paused(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) Paused() (bool, error) { + return _CommitStore.Contract.Paused(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) TypeAndVersion() (string, error) { + return _CommitStore.Contract.TypeAndVersion(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) TypeAndVersion() (string, error) { + return _CommitStore.Contract.TypeAndVersion(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "verify", hashedLeaves, proofs, proofFlagBits) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStore.Contract.Verify(&_CommitStore.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStore *CommitStoreCallerSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStore.Contract.Verify(&_CommitStore.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStore *CommitStoreTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "acceptOwnership") +} + +func (_CommitStore *CommitStoreSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStore.Contract.AcceptOwnership(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStore.Contract.AcceptOwnership(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "pause") +} + +func (_CommitStore *CommitStoreSession) Pause() (*types.Transaction, error) { + return _CommitStore.Contract.Pause(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactorSession) Pause() (*types.Transaction, error) { + return _CommitStore.Contract.Pause(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "resetUnblessedRoots", rootToReset) +} + +func (_CommitStore *CommitStoreSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.ResetUnblessedRoots(&_CommitStore.TransactOpts, rootToReset) +} + +func (_CommitStore *CommitStoreTransactorSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.ResetUnblessedRoots(&_CommitStore.TransactOpts, rootToReset) +} + +func (_CommitStore *CommitStoreTransactor) SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "setLatestPriceEpochAndRound", latestPriceEpochAndRound) +} + +func (_CommitStore *CommitStoreSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStore.Contract.SetLatestPriceEpochAndRound(&_CommitStore.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStore *CommitStoreTransactorSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStore.Contract.SetLatestPriceEpochAndRound(&_CommitStore.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStore *CommitStoreTransactor) SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "setMinSeqNr", minSeqNr) +} + +func (_CommitStore *CommitStoreSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStore.Contract.SetMinSeqNr(&_CommitStore.TransactOpts, minSeqNr) +} + +func (_CommitStore *CommitStoreTransactorSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStore.Contract.SetMinSeqNr(&_CommitStore.TransactOpts, minSeqNr) +} + +func (_CommitStore *CommitStoreTransactor) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "setOCR2Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStore *CommitStoreSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStore.Contract.SetOCR2Config(&_CommitStore.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStore *CommitStoreTransactorSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStore.Contract.SetOCR2Config(&_CommitStore.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStore *CommitStoreTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "transferOwnership", to) +} + +func (_CommitStore *CommitStoreSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStore.Contract.TransferOwnership(&_CommitStore.TransactOpts, to) +} + +func (_CommitStore *CommitStoreTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStore.Contract.TransferOwnership(&_CommitStore.TransactOpts, to) +} + +func (_CommitStore *CommitStoreTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) +} + +func (_CommitStore *CommitStoreSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.Transmit(&_CommitStore.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStore *CommitStoreTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.Transmit(&_CommitStore.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStore *CommitStoreTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "unpause") +} + +func (_CommitStore *CommitStoreSession) Unpause() (*types.Transaction, error) { + return _CommitStore.Contract.Unpause(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactorSession) Unpause() (*types.Transaction, error) { + return _CommitStore.Contract.Unpause(&_CommitStore.TransactOpts) +} + +type CommitStoreConfigSetIterator struct { + Event *CommitStoreConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreConfigSetIterator) Error() error { + return it.fail +} + +func (it *CommitStoreConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreConfigSet struct { + StaticConfig CommitStoreStaticConfig + DynamicConfig CommitStoreDynamicConfig + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreConfigSetIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &CommitStoreConfigSetIterator{contract: _CommitStore.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreConfigSet) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseConfigSet(log types.Log) (*CommitStoreConfigSet, error) { + event := new(CommitStoreConfigSet) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreConfigSet0Iterator struct { + Event *CommitStoreConfigSet0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreConfigSet0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreConfigSet0Iterator) Error() error { + return it.fail +} + +func (it *CommitStoreConfigSet0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreConfigSet0 struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreConfigSet0Iterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return &CommitStoreConfigSet0Iterator{contract: _CommitStore.contract, event: "ConfigSet0", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet0) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreConfigSet0) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseConfigSet0(log types.Log) (*CommitStoreConfigSet0, error) { + event := new(CommitStoreConfigSet0) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreOwnershipTransferRequestedIterator struct { + Event *CommitStoreOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreOwnershipTransferRequestedIterator{contract: _CommitStore.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreOwnershipTransferRequested) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseOwnershipTransferRequested(log types.Log) (*CommitStoreOwnershipTransferRequested, error) { + event := new(CommitStoreOwnershipTransferRequested) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreOwnershipTransferredIterator struct { + Event *CommitStoreOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *CommitStoreOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreOwnershipTransferredIterator{contract: _CommitStore.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreOwnershipTransferred) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseOwnershipTransferred(log types.Log) (*CommitStoreOwnershipTransferred, error) { + event := new(CommitStoreOwnershipTransferred) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStorePausedIterator struct { + Event *CommitStorePaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStorePausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStorePaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStorePaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStorePausedIterator) Error() error { + return it.fail +} + +func (it *CommitStorePausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStorePaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterPaused(opts *bind.FilterOpts) (*CommitStorePausedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &CommitStorePausedIterator{contract: _CommitStore.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStorePaused) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStorePaused) + if err := _CommitStore.contract.UnpackLog(event, "Paused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParsePaused(log types.Log) (*CommitStorePaused, error) { + event := new(CommitStorePaused) + if err := _CommitStore.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreReportAcceptedIterator struct { + Event *CommitStoreReportAccepted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreReportAcceptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreReportAcceptedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreReportAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreReportAccepted struct { + Report CommitStoreCommitReport + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreReportAcceptedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return &CommitStoreReportAcceptedIterator{contract: _CommitStore.contract, event: "ReportAccepted", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreReportAccepted) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreReportAccepted) + if err := _CommitStore.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseReportAccepted(log types.Log) (*CommitStoreReportAccepted, error) { + event := new(CommitStoreReportAccepted) + if err := _CommitStore.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreRootRemovedIterator struct { + Event *CommitStoreRootRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreRootRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreRootRemovedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreRootRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreRootRemoved struct { + Root [32]byte + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreRootRemovedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return &CommitStoreRootRemovedIterator{contract: _CommitStore.contract, event: "RootRemoved", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreRootRemoved) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreRootRemoved) + if err := _CommitStore.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseRootRemoved(log types.Log) (*CommitStoreRootRemoved, error) { + event := new(CommitStoreRootRemoved) + if err := _CommitStore.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreTransmittedIterator struct { + Event *CommitStoreTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreTransmittedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreTransmittedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &CommitStoreTransmittedIterator{contract: _CommitStore.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreTransmitted) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreTransmitted) + if err := _CommitStore.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseTransmitted(log types.Log) (*CommitStoreTransmitted, error) { + event := new(CommitStoreTransmitted) + if err := _CommitStore.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreUnpausedIterator struct { + Event *CommitStoreUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreUnpausedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreUnpausedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &CommitStoreUnpausedIterator{contract: _CommitStore.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreUnpaused) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreUnpaused) + if err := _CommitStore.contract.UnpackLog(event, "Unpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseUnpaused(log types.Log) (*CommitStoreUnpaused, error) { + event := new(CommitStoreUnpaused) + if err := _CommitStore.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_CommitStore *CommitStore) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _CommitStore.abi.Events["ConfigSet"].ID: + return _CommitStore.ParseConfigSet(log) + case _CommitStore.abi.Events["ConfigSet0"].ID: + return _CommitStore.ParseConfigSet0(log) + case _CommitStore.abi.Events["OwnershipTransferRequested"].ID: + return _CommitStore.ParseOwnershipTransferRequested(log) + case _CommitStore.abi.Events["OwnershipTransferred"].ID: + return _CommitStore.ParseOwnershipTransferred(log) + case _CommitStore.abi.Events["Paused"].ID: + return _CommitStore.ParsePaused(log) + case _CommitStore.abi.Events["ReportAccepted"].ID: + return _CommitStore.ParseReportAccepted(log) + case _CommitStore.abi.Events["RootRemoved"].ID: + return _CommitStore.ParseRootRemoved(log) + case _CommitStore.abi.Events["Transmitted"].ID: + return _CommitStore.ParseTransmitted(log) + case _CommitStore.abi.Events["Unpaused"].ID: + return _CommitStore.ParseUnpaused(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (CommitStoreConfigSet) Topic() common.Hash { + return common.HexToHash("0xc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec3") +} + +func (CommitStoreConfigSet0) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (CommitStoreOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (CommitStoreOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (CommitStorePaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (CommitStoreReportAccepted) Topic() common.Hash { + return common.HexToHash("0x291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf5") +} + +func (CommitStoreRootRemoved) Topic() common.Hash { + return common.HexToHash("0x202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12") +} + +func (CommitStoreTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (CommitStoreUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (_CommitStore *CommitStore) Address() common.Address { + return _CommitStore.address +} + +type CommitStoreInterface interface { + GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) + + GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) + + GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) + + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + IsARMHealthy(opts *bind.CallOpts) (bool, error) + + IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) + + IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + Paused(opts *bind.CallOpts) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Pause(opts *bind.TransactOpts) (*types.Transaction, error) + + ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) + + SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) + + SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) + + SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + Unpause(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*CommitStoreConfigSet, error) + + FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreConfigSet0Iterator, error) + + WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet0) (event.Subscription, error) + + ParseConfigSet0(log types.Log) (*CommitStoreConfigSet0, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*CommitStoreOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*CommitStoreOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*CommitStorePausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStorePaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*CommitStorePaused, error) + + FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreReportAcceptedIterator, error) + + WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreReportAccepted) (event.Subscription, error) + + ParseReportAccepted(log types.Log) (*CommitStoreReportAccepted, error) + + FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreRootRemovedIterator, error) + + WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreRootRemoved) (event.Subscription, error) + + ParseRootRemoved(log types.Log) (*CommitStoreRootRemoved, error) + + FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*CommitStoreTransmitted, error) + + FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*CommitStoreUnpaused, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go b/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go new file mode 100644 index 0000000000..b314d6c75b --- /dev/null +++ b/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go @@ -0,0 +1,2205 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package commit_store_helper + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommitStoreCommitReport struct { + PriceUpdates InternalPriceUpdates + Interval CommitStoreInterval + MerkleRoot [32]byte +} + +type CommitStoreDynamicConfig struct { + PriceRegistry common.Address +} + +type CommitStoreInterval struct { + Min uint64 + Max uint64 +} + +type CommitStoreStaticConfig struct { + ChainSelector uint64 + SourceChainSelector uint64 + OnRamp common.Address + RmnProxy common.Address +} + +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var CommitStoreHelperMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"oldEpochAndRound\",\"type\":\"uint40\"},{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"newEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"LatestPriceEpochAndRoundSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"oldSeqNum\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newSeqNum\",\"type\":\"uint64\"}],\"name\":\"SequenceNumberSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndNotCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"commitReport\",\"type\":\"bytes\"},{\"internalType\":\"uint40\",\"name\":\"epochAndRound\",\"type\":\"uint40\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b506040516200382a3803806200382a8339810160408190526200004d9162000274565b80600033808281620000a65760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d957620000d98162000194565b50505015156080524660a05260408101516001600160a01b0316158062000108575080516001600160401b0316155b806200011f575060208101516001600160401b0316155b8062000136575060608101516001600160a01b0316155b156200015557604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b039081166101005260609091015116610120525062000308565b336001600160a01b03821603620001ee5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025757600080fd5b919050565b80516001600160a01b03811681146200025757600080fd5b6000608082840312156200028757600080fd5b604051608081016001600160401b0381118282101715620002b857634e487b7160e01b600052604160045260246000fd5b604052620002c6836200023f565b8152620002d6602084016200023f565b6020820152620002e9604084016200025c565b6040820152620002fc606084016200025c565b60608201529392505050565b60805160a05160c05160e051610100516101205161348c6200039e6000396000818161026d015281816116f6015281816118a5015281816119cf0152611f5d0152600081816102310152611f36015260008181610201015281816116b00152818161198c0152611f0f0152600081816101d10152611ee00152600081816110f60152611142015260006111bd015261348c6000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806379ba5097116100e3578063afcb95d71161008c578063f2fde38b11610066578063f2fde38b14610501578063f47a869014610514578063ff888fb11461052757600080fd5b8063afcb95d7146104c6578063b1dc65a4146104e6578063e89d039f146104f957600080fd5b80638da5cb5b116100bd5780638da5cb5b1461046b578063a7206cd614610493578063ad7a22f8146104b357600080fd5b806379ba50971461042b57806381ff7048146104335780638456cb591461046357600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb146103af578063666cab8d146103d75780637437ff9f146103ec57600080fd5b806332048875146103745780633f4ba83a146103955780634120fccd1461039d57600080fd5b80631dc18e56116101765780631dc18e56146103395780631ef381741461034e57806329b980e41461036157600080fd5b806306285c691461019d57806310c374ed146102c0578063181f5a77146102f0575b600080fd5b6102aa60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102b791906125ac565b60405180910390f35b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102b7565b61032c6040518060400160405280601581526020017f436f6d6d697453746f726520312e352e302d646576000000000000000000000081525081565b6040516102b79190612669565b61034c6103473660046126df565b61053a565b005b61034c61035c366004612972565b61054a565b61034c61036f366004612a3f565b610c2e565b610387610382366004612a9f565b610cbe565b6040519081526020016102b7565b61034c610db4565b60095467ffffffffffffffff166102d7565b6009546d0100000000000000000000000000900460ff165b60405190151581526020016102b7565b6103df610e1a565b6040516102b79190612b65565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102b7565b61034c610e89565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102b7565b61034c610f86565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b7565b6103876104a1366004612b78565b6000908152600a602052604090205490565b61034c6104c1366004612b91565b610ff6565b6040805160018152600060208201819052918101919091526060016102b7565b61034c6104f4366004612bac565b611071565b6103c7611688565b61034c61050f366004612c63565b61179c565b61034c610522366004612c80565b6117b0565b6103c7610535366004612b78565b611842565b610545838383611916565b505050565b855185518560ff16601f8311156105995760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b60405180910390fd5b806000036105d65760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b8183146106125760046040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b61061d816003612d61565b83116106585760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b610660611d7f565b61066986611e02565b60065460005b8181101561075d57600560006006838154811061068e5761068e612d78565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600780546005929190849081106106fe576106fe612d78565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161066f565b50895160005b81811015610ad65760008c828151811061077f5761077f612d78565b602002602001015190506000600281111561079c5761079c612cc2565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff1660028111156107db576107db612cc2565b146108155760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b73ffffffffffffffffffffffffffffffffffffffff8116610862576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561091257610912612cc2565b021790555090505060008c838151811061092e5761092e612d78565b602002602001015190506000600281111561094b5761094b612cc2565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561098a5761098a612cc2565b146109c45760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b73ffffffffffffffffffffffffffffffffffffffff8116610a11576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ac157610ac1612cc2565b02179055509050505050806001019050610763565b508a51610aea9060069060208e01906124ee565b508951610afe9060079060208d01906124ee565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610b84914691309190600090610b569063ffffffff16612da7565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611fb2565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610c1899989796959493929190612dca565b60405180910390a1505050505050505050505050565b610c36611d7f565b6009805464ffffffffff838116680100000000000000008181027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff85161790945560408051949093049091168084526020840191909152917ff0d557bfce33e354b41885eb9264448726cfe51f486ffa69809d2bf56545644491015b60405180910390a15050565b6009546000906d0100000000000000000000000000900460ff1615610d0f576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d8087878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a92508991829185019084908082843760009201919091525088925061205d915050565b9050610d8b81611842565b610d99576000915050610dab565b6000908152600a602052604090205490505b95945050505050565b610dbc611d7f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610e7f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e54575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610590565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610f8e611d7f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610e10565b610ffe611d7f565b6009805467ffffffffffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168117909355604080519190921680825260208201939093527fea59e8027e41fda1525220008cf2416797405065eb21b0ebd417bfc6d361b8de9101610cb2565b611080878760208b0135611916565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146110f35780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610590565b467f000000000000000000000000000000000000000000000000000000000000000014611174576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610590565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f000000000000000000000000000000000000000000000000000000000000000015611216576002826020015183604001516111f79190612e60565b6112019190612e79565b61120c906001612e60565b60ff16905061122c565b6020820151611226906001612e60565b60ff1690505b868114611265576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86851461129e576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156112e1576112e1612cc2565b60028111156112f2576112f2612cc2565b905250905060028160200151600281111561130f5761130f612cc2565b14801561135657506007816000015160ff168154811061133157611331612d78565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b61138c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061139a866020612d61565b6113a5896020612d61565b6113b18c610144612ec2565b6113bb9190612ec2565b6113c59190612ec2565b9050368114611409576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610590565b5060008a8a60405161141c929190612ed5565b604051908190038120611433918e90602001612ee5565b604051602081830303815290604052805190602001209050611453612578565b8860005b818110156116775760006001858a846020811061147657611476612d78565b61148391901a601b612e60565b8f8f8681811061149557611495612d78565b905060200201358e8e878181106114ae576114ae612d78565b90506020020135604051600081526020016040526040516114eb949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561150d573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561159057611590612cc2565b60028111156115a1576115a1612cc2565b90525090506001816020015160028111156115be576115be612cc2565b146115f5576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061160c5761160c612d78565b602002015115611648576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061166357611663612d78565b911515602090920201525050600101611457565b505050505050505050505050505050565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611752573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117769190612ef9565b15801561179757506009546d0100000000000000000000000000900460ff16155b905090565b6117a4611d7f565b6117ad8161237e565b50565b6117b8611d7f565b60005b818110156105455760008383838181106117d7576117d7612d78565b9050602002013590506117e981611842565b611839576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12906118309083815260200190565b60405180910390a15b506001016117bb565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156118ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119109190612ef9565b92915050565b6009546d0100000000000000000000000000900460ff1615611964576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4f9190612ef9565b15611a86576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611a9483850185613012565b80515151909150151580611aad57508051602001515115155b15611be55760095464ffffffffff80841668010000000000000000909204161015611baa57600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f91611b6491600401613265565b600060405180830381600087803b158015611b7e57600080fd5b505af1158015611b92573d6000803e3d6000fd5b505050506040810151611ba55750505050565b611be5565b6040810151611be5576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff9081169116141580611c20575060208082015190810151905167ffffffffffffffff9182169116115b15611c5d5780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016105909190613278565b6040810151611c98576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415611ce1576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201510151611cf490600161329d565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf590611d719083906132c5565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611e00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610590565b565b600081806020019051810190611e189190613321565b805190915073ffffffffffffffffffffffffffffffffffffffff16611e69576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391610cb291849061336d565b6000808a8a8a8a8a8a8a8a8a604051602001611fd6999897969594939291906133ea565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b825182516000919081830361209e576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010182118015906120b257506101018111155b6120e8576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115612149576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003612176578660008151811061216457612164612d78565b60200260200101519350505050612377565b60008167ffffffffffffffff81111561219157612191612733565b6040519080825280602002602001820160405280156121ba578160200160208202803683370190505b50905060008080805b858110156122fd5760006001821b8b81160361221e5788851015612207578c5160018601958e9181106121f8576121f8612d78565b60200260200101519050612240565b85516001850194879181106121f8576121f8612d78565b8b5160018401938d91811061223557612235612d78565b602002602001015190505b600089861015612270578d5160018701968f91811061226157612261612d78565b60200260200101519050612292565b865160018601958891811061228757612287612d78565b602002602001015190505b828511156122cc576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122d68282612473565b8784815181106122e8576122e8612d78565b602090810291909101015250506001016121c3565b50600185038214801561230f57508683145b801561231a57508581145b612350576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061236557612365612d78565b60200260200101519750505050505050505b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036123fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610590565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008183106124b55760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612377565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612377565b828054828255906000526020600020908101928215612568579160200282015b8281111561256857825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061250e565b50612574929150612597565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b808211156125745760008155600101612598565b60808101611910828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b8181101561262b5760208185018101518683018201520161260f565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006123776020830184612605565b60008083601f84011261268e57600080fd5b50813567ffffffffffffffff8111156126a657600080fd5b6020830191508360208285010111156126be57600080fd5b9250929050565b803564ffffffffff811681146126da57600080fd5b919050565b6000806000604084860312156126f457600080fd5b833567ffffffffffffffff81111561270b57600080fd5b6127178682870161267c565b909450925061272a9050602085016126c5565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561278557612785612733565b60405290565b6040516060810167ffffffffffffffff8111828210171561278557612785612733565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127f5576127f5612733565b604052919050565b600067ffffffffffffffff82111561281757612817612733565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146117ad57600080fd5b600082601f83011261285457600080fd5b81356020612869612864836127fd565b6127ae565b8083825260208201915060208460051b87010193508684111561288b57600080fd5b602086015b848110156128b05780356128a381612821565b8352918301918301612890565b509695505050505050565b803560ff811681146126da57600080fd5b600082601f8301126128dd57600080fd5b813567ffffffffffffffff8111156128f7576128f7612733565b61292860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127ae565b81815284602083860101111561293d57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146126da57600080fd5b60008060008060008060c0878903121561298b57600080fd5b863567ffffffffffffffff808211156129a357600080fd5b6129af8a838b01612843565b975060208901359150808211156129c557600080fd5b6129d18a838b01612843565b96506129df60408a016128bb565b955060608901359150808211156129f557600080fd5b612a018a838b016128cc565b9450612a0f60808a0161295a565b935060a0890135915080821115612a2557600080fd5b50612a3289828a016128cc565b9150509295509295509295565b600060208284031215612a5157600080fd5b612377826126c5565b60008083601f840112612a6c57600080fd5b50813567ffffffffffffffff811115612a8457600080fd5b6020830191508360208260051b85010111156126be57600080fd5b600080600080600060608688031215612ab757600080fd5b853567ffffffffffffffff80821115612acf57600080fd5b612adb89838a01612a5a565b90975095506020880135915080821115612af457600080fd5b50612b0188828901612a5a565b96999598509660400135949350505050565b60008151808452602080850194506020840160005b83811015612b5a57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612b28565b509495945050505050565b6020815260006123776020830184612b13565b600060208284031215612b8a57600080fd5b5035919050565b600060208284031215612ba357600080fd5b6123778261295a565b60008060008060008060008060e0898b031215612bc857600080fd5b606089018a811115612bd957600080fd5b8998503567ffffffffffffffff80821115612bf357600080fd5b612bff8c838d0161267c565b909950975060808b0135915080821115612c1857600080fd5b612c248c838d01612a5a565b909750955060a08b0135915080821115612c3d57600080fd5b50612c4a8b828c01612a5a565b999c989b50969995989497949560c00135949350505050565b600060208284031215612c7557600080fd5b813561237781612821565b60008060208385031215612c9357600080fd5b823567ffffffffffffffff811115612caa57600080fd5b612cb685828601612a5a565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160058310612d2c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761191057611910612d32565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103612dc057612dc0612d32565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612dfa8184018a612b13565b90508281036080840152612e0e8189612b13565b905060ff871660a084015282810360c0840152612e2b8187612605565b905067ffffffffffffffff851660e0840152828103610100840152612e508185612605565b9c9b505050505050505050505050565b60ff818116838216019081111561191057611910612d32565b600060ff831680612eb3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b8082018082111561191057611910612d32565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612f0b57600080fd5b8151801515811461237757600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146126da57600080fd5b600082601f830112612f5857600080fd5b81356020612f68612864836127fd565b82815260069290921b84018101918181019086841115612f8757600080fd5b8286015b848110156128b05760408189031215612fa45760008081fd5b612fac612762565b612fb58261295a565b8152612fc2858301612f1b565b81860152835291830191604001612f8b565b600060408284031215612fe657600080fd5b612fee612762565b9050612ff98261295a565b81526130076020830161295a565b602082015292915050565b6000602080838503121561302557600080fd5b823567ffffffffffffffff8082111561303d57600080fd5b908401906080828703121561305157600080fd5b61305961278b565b82358281111561306857600080fd5b8301604081890381131561307b57600080fd5b613083612762565b82358581111561309257600080fd5b8301601f81018b136130a357600080fd5b80356130b1612864826127fd565b81815260069190911b8201890190898101908d8311156130d057600080fd5b928a01925b828410156131205785848f0312156130ed5760008081fd5b6130f5612762565b843561310081612821565b815261310d858d01612f1b565b818d0152825292850192908a01906130d5565b84525050508287013591508482111561313857600080fd5b6131448a838501612f47565b81880152835250613159905087848601612fd4565b93810193909352506060013560408201529392505050565b805160408084528151848201819052600092602091908201906060870190855b818110156131ea578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858401529284019291850191600101613191565b50508583015187820388850152805180835290840192506000918401905b80831015613259578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685830152928401926001929092019190850190613208565b50979650505050505050565b6020815260006123776020830184613171565b604081016119108284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff8181168382160190808211156132be576132be612d32565b5092915050565b6020815260008251608060208401526132e160a0840182613171565b9050602084015161330c6040850182805167ffffffffffffffff908116835260209182015116910152565b50604084015160808401528091505092915050565b60006020828403121561333357600080fd5b6040516020810181811067ffffffffffffffff8211171561335657613356612733565b604052825161336481612821565b81529392505050565b60a081016133c6828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526134318285018b612b13565b91508382036080850152613445828a612b13565b915060ff881660a085015283820360c08501526134628288612605565b90861660e08501528381036101008501529050612e50818561260556fea164736f6c6343000818000a", +} + +var CommitStoreHelperABI = CommitStoreHelperMetaData.ABI + +var CommitStoreHelperBin = CommitStoreHelperMetaData.Bin + +func DeployCommitStoreHelper(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig CommitStoreStaticConfig) (common.Address, *types.Transaction, *CommitStoreHelper, error) { + parsed, err := CommitStoreHelperMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CommitStoreHelperBin), backend, staticConfig) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CommitStoreHelper{address: address, abi: *parsed, CommitStoreHelperCaller: CommitStoreHelperCaller{contract: contract}, CommitStoreHelperTransactor: CommitStoreHelperTransactor{contract: contract}, CommitStoreHelperFilterer: CommitStoreHelperFilterer{contract: contract}}, nil +} + +type CommitStoreHelper struct { + address common.Address + abi abi.ABI + CommitStoreHelperCaller + CommitStoreHelperTransactor + CommitStoreHelperFilterer +} + +type CommitStoreHelperCaller struct { + contract *bind.BoundContract +} + +type CommitStoreHelperTransactor struct { + contract *bind.BoundContract +} + +type CommitStoreHelperFilterer struct { + contract *bind.BoundContract +} + +type CommitStoreHelperSession struct { + Contract *CommitStoreHelper + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type CommitStoreHelperCallerSession struct { + Contract *CommitStoreHelperCaller + CallOpts bind.CallOpts +} + +type CommitStoreHelperTransactorSession struct { + Contract *CommitStoreHelperTransactor + TransactOpts bind.TransactOpts +} + +type CommitStoreHelperRaw struct { + Contract *CommitStoreHelper +} + +type CommitStoreHelperCallerRaw struct { + Contract *CommitStoreHelperCaller +} + +type CommitStoreHelperTransactorRaw struct { + Contract *CommitStoreHelperTransactor +} + +func NewCommitStoreHelper(address common.Address, backend bind.ContractBackend) (*CommitStoreHelper, error) { + abi, err := abi.JSON(strings.NewReader(CommitStoreHelperABI)) + if err != nil { + return nil, err + } + contract, err := bindCommitStoreHelper(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CommitStoreHelper{address: address, abi: abi, CommitStoreHelperCaller: CommitStoreHelperCaller{contract: contract}, CommitStoreHelperTransactor: CommitStoreHelperTransactor{contract: contract}, CommitStoreHelperFilterer: CommitStoreHelperFilterer{contract: contract}}, nil +} + +func NewCommitStoreHelperCaller(address common.Address, caller bind.ContractCaller) (*CommitStoreHelperCaller, error) { + contract, err := bindCommitStoreHelper(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CommitStoreHelperCaller{contract: contract}, nil +} + +func NewCommitStoreHelperTransactor(address common.Address, transactor bind.ContractTransactor) (*CommitStoreHelperTransactor, error) { + contract, err := bindCommitStoreHelper(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CommitStoreHelperTransactor{contract: contract}, nil +} + +func NewCommitStoreHelperFilterer(address common.Address, filterer bind.ContractFilterer) (*CommitStoreHelperFilterer, error) { + contract, err := bindCommitStoreHelper(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CommitStoreHelperFilterer{contract: contract}, nil +} + +func bindCommitStoreHelper(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CommitStoreHelperMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_CommitStoreHelper *CommitStoreHelperRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStoreHelper.Contract.CommitStoreHelperCaller.contract.Call(opts, result, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.CommitStoreHelperTransactor.contract.Transfer(opts) +} + +func (_CommitStoreHelper *CommitStoreHelperRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.CommitStoreHelperTransactor.contract.Transact(opts, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStoreHelper.Contract.contract.Call(opts, result, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.contract.Transfer(opts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.contract.Transact(opts, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(CommitStoreDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreDynamicConfig)).(*CommitStoreDynamicConfig) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStoreHelper.Contract.GetDynamicConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStoreHelper.Contract.GetDynamicConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getExpectedNextSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStoreHelper.Contract.GetExpectedNextSequenceNumber(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStoreHelper.Contract.GetExpectedNextSequenceNumber(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getLatestPriceEpochAndRound") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStoreHelper.Contract.GetLatestPriceEpochAndRound(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStoreHelper.Contract.GetLatestPriceEpochAndRound(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getMerkleRoot", root) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStoreHelper.Contract.GetMerkleRoot(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStoreHelper.Contract.GetMerkleRoot(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(CommitStoreStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreStaticConfig)).(*CommitStoreStaticConfig) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStoreHelper.Contract.GetStaticConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStoreHelper.Contract.GetStaticConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetTransmitters() ([]common.Address, error) { + return _CommitStoreHelper.Contract.GetTransmitters(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetTransmitters() ([]common.Address, error) { + return _CommitStoreHelper.Contract.GetTransmitters(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "isBlessed", root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStoreHelper.Contract.IsBlessed(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStoreHelper.Contract.IsBlessed(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) IsUnpausedAndNotCursed(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "isUnpausedAndNotCursed") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) IsUnpausedAndNotCursed() (bool, error) { + return _CommitStoreHelper.Contract.IsUnpausedAndNotCursed(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) IsUnpausedAndNotCursed() (bool, error) { + return _CommitStoreHelper.Contract.IsUnpausedAndNotCursed(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDetails(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDetails(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDigestAndEpoch(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDigestAndEpoch(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Owner() (common.Address, error) { + return _CommitStoreHelper.Contract.Owner(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) Owner() (common.Address, error) { + return _CommitStoreHelper.Contract.Owner(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Paused() (bool, error) { + return _CommitStoreHelper.Contract.Paused(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) Paused() (bool, error) { + return _CommitStoreHelper.Contract.Paused(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) TypeAndVersion() (string, error) { + return _CommitStoreHelper.Contract.TypeAndVersion(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) TypeAndVersion() (string, error) { + return _CommitStoreHelper.Contract.TypeAndVersion(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "verify", hashedLeaves, proofs, proofFlagBits) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStoreHelper.Contract.Verify(&_CommitStoreHelper.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStoreHelper.Contract.Verify(&_CommitStoreHelper.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "acceptOwnership") +} + +func (_CommitStoreHelper *CommitStoreHelperSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.AcceptOwnership(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.AcceptOwnership(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "pause") +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Pause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Pause(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Pause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Pause(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Report(opts *bind.TransactOpts, commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "report", commitReport, epochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Report(commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Report(&_CommitStoreHelper.TransactOpts, commitReport, epochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Report(commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Report(&_CommitStoreHelper.TransactOpts, commitReport, epochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "resetUnblessedRoots", rootToReset) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.ResetUnblessedRoots(&_CommitStoreHelper.TransactOpts, rootToReset) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.ResetUnblessedRoots(&_CommitStoreHelper.TransactOpts, rootToReset) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "setLatestPriceEpochAndRound", latestPriceEpochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetLatestPriceEpochAndRound(&_CommitStoreHelper.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetLatestPriceEpochAndRound(&_CommitStoreHelper.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "setMinSeqNr", minSeqNr) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetMinSeqNr(&_CommitStoreHelper.TransactOpts, minSeqNr) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetMinSeqNr(&_CommitStoreHelper.TransactOpts, minSeqNr) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "setOCR2Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetOCR2Config(&_CommitStoreHelper.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetOCR2Config(&_CommitStoreHelper.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "transferOwnership", to) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.TransferOwnership(&_CommitStoreHelper.TransactOpts, to) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.TransferOwnership(&_CommitStoreHelper.TransactOpts, to) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Transmit(&_CommitStoreHelper.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Transmit(&_CommitStoreHelper.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "unpause") +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Unpause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Unpause(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Unpause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Unpause(&_CommitStoreHelper.TransactOpts) +} + +type CommitStoreHelperConfigSetIterator struct { + Event *CommitStoreHelperConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperConfigSetIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperConfigSet struct { + StaticConfig CommitStoreStaticConfig + DynamicConfig CommitStoreDynamicConfig + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreHelperConfigSetIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &CommitStoreHelperConfigSetIterator{contract: _CommitStoreHelper.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperConfigSet) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseConfigSet(log types.Log) (*CommitStoreHelperConfigSet, error) { + event := new(CommitStoreHelperConfigSet) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperConfigSet0Iterator struct { + Event *CommitStoreHelperConfigSet0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperConfigSet0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperConfigSet0Iterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperConfigSet0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperConfigSet0 struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreHelperConfigSet0Iterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return &CommitStoreHelperConfigSet0Iterator{contract: _CommitStoreHelper.contract, event: "ConfigSet0", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet0) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperConfigSet0) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseConfigSet0(log types.Log) (*CommitStoreHelperConfigSet0, error) { + event := new(CommitStoreHelperConfigSet0) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperLatestPriceEpochAndRoundSetIterator struct { + Event *CommitStoreHelperLatestPriceEpochAndRoundSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperLatestPriceEpochAndRoundSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperLatestPriceEpochAndRoundSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperLatestPriceEpochAndRoundSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperLatestPriceEpochAndRoundSetIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperLatestPriceEpochAndRoundSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperLatestPriceEpochAndRoundSet struct { + OldEpochAndRound *big.Int + NewEpochAndRound *big.Int + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterLatestPriceEpochAndRoundSet(opts *bind.FilterOpts) (*CommitStoreHelperLatestPriceEpochAndRoundSetIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "LatestPriceEpochAndRoundSet") + if err != nil { + return nil, err + } + return &CommitStoreHelperLatestPriceEpochAndRoundSetIterator{contract: _CommitStoreHelper.contract, event: "LatestPriceEpochAndRoundSet", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchLatestPriceEpochAndRoundSet(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperLatestPriceEpochAndRoundSet) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "LatestPriceEpochAndRoundSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperLatestPriceEpochAndRoundSet) + if err := _CommitStoreHelper.contract.UnpackLog(event, "LatestPriceEpochAndRoundSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseLatestPriceEpochAndRoundSet(log types.Log) (*CommitStoreHelperLatestPriceEpochAndRoundSet, error) { + event := new(CommitStoreHelperLatestPriceEpochAndRoundSet) + if err := _CommitStoreHelper.contract.UnpackLog(event, "LatestPriceEpochAndRoundSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperOwnershipTransferRequestedIterator struct { + Event *CommitStoreHelperOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreHelperOwnershipTransferRequestedIterator{contract: _CommitStoreHelper.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperOwnershipTransferRequested) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseOwnershipTransferRequested(log types.Log) (*CommitStoreHelperOwnershipTransferRequested, error) { + event := new(CommitStoreHelperOwnershipTransferRequested) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperOwnershipTransferredIterator struct { + Event *CommitStoreHelperOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreHelperOwnershipTransferredIterator{contract: _CommitStoreHelper.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperOwnershipTransferred) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseOwnershipTransferred(log types.Log) (*CommitStoreHelperOwnershipTransferred, error) { + event := new(CommitStoreHelperOwnershipTransferred) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperPausedIterator struct { + Event *CommitStoreHelperPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperPausedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperPaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterPaused(opts *bind.FilterOpts) (*CommitStoreHelperPausedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &CommitStoreHelperPausedIterator{contract: _CommitStoreHelper.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperPaused) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperPaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Paused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParsePaused(log types.Log) (*CommitStoreHelperPaused, error) { + event := new(CommitStoreHelperPaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperReportAcceptedIterator struct { + Event *CommitStoreHelperReportAccepted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperReportAcceptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperReportAcceptedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperReportAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperReportAccepted struct { + Report CommitStoreCommitReport + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreHelperReportAcceptedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return &CommitStoreHelperReportAcceptedIterator{contract: _CommitStoreHelper.contract, event: "ReportAccepted", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperReportAccepted) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperReportAccepted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseReportAccepted(log types.Log) (*CommitStoreHelperReportAccepted, error) { + event := new(CommitStoreHelperReportAccepted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperRootRemovedIterator struct { + Event *CommitStoreHelperRootRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperRootRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperRootRemovedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperRootRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperRootRemoved struct { + Root [32]byte + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreHelperRootRemovedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return &CommitStoreHelperRootRemovedIterator{contract: _CommitStoreHelper.contract, event: "RootRemoved", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperRootRemoved) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperRootRemoved) + if err := _CommitStoreHelper.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseRootRemoved(log types.Log) (*CommitStoreHelperRootRemoved, error) { + event := new(CommitStoreHelperRootRemoved) + if err := _CommitStoreHelper.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperSequenceNumberSetIterator struct { + Event *CommitStoreHelperSequenceNumberSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperSequenceNumberSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperSequenceNumberSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperSequenceNumberSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperSequenceNumberSetIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperSequenceNumberSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperSequenceNumberSet struct { + OldSeqNum uint64 + NewSeqNum uint64 + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterSequenceNumberSet(opts *bind.FilterOpts) (*CommitStoreHelperSequenceNumberSetIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "SequenceNumberSet") + if err != nil { + return nil, err + } + return &CommitStoreHelperSequenceNumberSetIterator{contract: _CommitStoreHelper.contract, event: "SequenceNumberSet", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchSequenceNumberSet(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperSequenceNumberSet) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "SequenceNumberSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperSequenceNumberSet) + if err := _CommitStoreHelper.contract.UnpackLog(event, "SequenceNumberSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseSequenceNumberSet(log types.Log) (*CommitStoreHelperSequenceNumberSet, error) { + event := new(CommitStoreHelperSequenceNumberSet) + if err := _CommitStoreHelper.contract.UnpackLog(event, "SequenceNumberSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperTransmittedIterator struct { + Event *CommitStoreHelperTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperTransmittedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreHelperTransmittedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &CommitStoreHelperTransmittedIterator{contract: _CommitStoreHelper.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperTransmitted) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperTransmitted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseTransmitted(log types.Log) (*CommitStoreHelperTransmitted, error) { + event := new(CommitStoreHelperTransmitted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperUnpausedIterator struct { + Event *CommitStoreHelperUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperUnpausedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreHelperUnpausedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &CommitStoreHelperUnpausedIterator{contract: _CommitStoreHelper.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperUnpaused) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperUnpaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Unpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseUnpaused(log types.Log) (*CommitStoreHelperUnpaused, error) { + event := new(CommitStoreHelperUnpaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_CommitStoreHelper *CommitStoreHelper) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _CommitStoreHelper.abi.Events["ConfigSet"].ID: + return _CommitStoreHelper.ParseConfigSet(log) + case _CommitStoreHelper.abi.Events["ConfigSet0"].ID: + return _CommitStoreHelper.ParseConfigSet0(log) + case _CommitStoreHelper.abi.Events["LatestPriceEpochAndRoundSet"].ID: + return _CommitStoreHelper.ParseLatestPriceEpochAndRoundSet(log) + case _CommitStoreHelper.abi.Events["OwnershipTransferRequested"].ID: + return _CommitStoreHelper.ParseOwnershipTransferRequested(log) + case _CommitStoreHelper.abi.Events["OwnershipTransferred"].ID: + return _CommitStoreHelper.ParseOwnershipTransferred(log) + case _CommitStoreHelper.abi.Events["Paused"].ID: + return _CommitStoreHelper.ParsePaused(log) + case _CommitStoreHelper.abi.Events["ReportAccepted"].ID: + return _CommitStoreHelper.ParseReportAccepted(log) + case _CommitStoreHelper.abi.Events["RootRemoved"].ID: + return _CommitStoreHelper.ParseRootRemoved(log) + case _CommitStoreHelper.abi.Events["SequenceNumberSet"].ID: + return _CommitStoreHelper.ParseSequenceNumberSet(log) + case _CommitStoreHelper.abi.Events["Transmitted"].ID: + return _CommitStoreHelper.ParseTransmitted(log) + case _CommitStoreHelper.abi.Events["Unpaused"].ID: + return _CommitStoreHelper.ParseUnpaused(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (CommitStoreHelperConfigSet) Topic() common.Hash { + return common.HexToHash("0xc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec3") +} + +func (CommitStoreHelperConfigSet0) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (CommitStoreHelperLatestPriceEpochAndRoundSet) Topic() common.Hash { + return common.HexToHash("0xf0d557bfce33e354b41885eb9264448726cfe51f486ffa69809d2bf565456444") +} + +func (CommitStoreHelperOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (CommitStoreHelperOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (CommitStoreHelperPaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (CommitStoreHelperReportAccepted) Topic() common.Hash { + return common.HexToHash("0x291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf5") +} + +func (CommitStoreHelperRootRemoved) Topic() common.Hash { + return common.HexToHash("0x202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12") +} + +func (CommitStoreHelperSequenceNumberSet) Topic() common.Hash { + return common.HexToHash("0xea59e8027e41fda1525220008cf2416797405065eb21b0ebd417bfc6d361b8de") +} + +func (CommitStoreHelperTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (CommitStoreHelperUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (_CommitStoreHelper *CommitStoreHelper) Address() common.Address { + return _CommitStoreHelper.address +} + +type CommitStoreHelperInterface interface { + GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) + + GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) + + GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) + + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) + + IsUnpausedAndNotCursed(opts *bind.CallOpts) (bool, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + Paused(opts *bind.CallOpts) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Pause(opts *bind.TransactOpts) (*types.Transaction, error) + + Report(opts *bind.TransactOpts, commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) + + ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) + + SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) + + SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) + + SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + Unpause(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreHelperConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*CommitStoreHelperConfigSet, error) + + FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreHelperConfigSet0Iterator, error) + + WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet0) (event.Subscription, error) + + ParseConfigSet0(log types.Log) (*CommitStoreHelperConfigSet0, error) + + FilterLatestPriceEpochAndRoundSet(opts *bind.FilterOpts) (*CommitStoreHelperLatestPriceEpochAndRoundSetIterator, error) + + WatchLatestPriceEpochAndRoundSet(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperLatestPriceEpochAndRoundSet) (event.Subscription, error) + + ParseLatestPriceEpochAndRoundSet(log types.Log) (*CommitStoreHelperLatestPriceEpochAndRoundSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*CommitStoreHelperOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*CommitStoreHelperOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*CommitStoreHelperPausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperPaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*CommitStoreHelperPaused, error) + + FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreHelperReportAcceptedIterator, error) + + WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperReportAccepted) (event.Subscription, error) + + ParseReportAccepted(log types.Log) (*CommitStoreHelperReportAccepted, error) + + FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreHelperRootRemovedIterator, error) + + WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperRootRemoved) (event.Subscription, error) + + ParseRootRemoved(log types.Log) (*CommitStoreHelperRootRemoved, error) + + FilterSequenceNumberSet(opts *bind.FilterOpts) (*CommitStoreHelperSequenceNumberSetIterator, error) + + WatchSequenceNumberSet(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperSequenceNumberSet) (event.Subscription, error) + + ParseSequenceNumberSet(log types.Log) (*CommitStoreHelperSequenceNumberSet, error) + + FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreHelperTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*CommitStoreHelperTransmitted, error) + + FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreHelperUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*CommitStoreHelperUnpaused, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/commit_store_helper_1_0_0/commit_store_helper_1_0_0.go b/core/gethwrappers/ccip/generated/commit_store_helper_1_0_0/commit_store_helper_1_0_0.go new file mode 100644 index 0000000000..5a1e15b253 --- /dev/null +++ b/core/gethwrappers/ccip/generated/commit_store_helper_1_0_0/commit_store_helper_1_0_0.go @@ -0,0 +1,1966 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package commit_store_helper_1_0_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommitStoreCommitReport struct { + PriceUpdates InternalPriceUpdates + Interval CommitStoreInterval + MerkleRoot [32]byte +} + +type CommitStoreDynamicConfig struct { + PriceRegistry common.Address +} + +type CommitStoreInterval struct { + Min uint64 + Max uint64 +} + +type CommitStoreStaticConfig struct { + ChainSelector uint64 + SourceChainSelector uint64 + OnRamp common.Address + ArmProxy common.Address +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var CommitStoreHelperMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"usdPerToken\",\"type\":\"uint192\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint192\",\"name\":\"usdPerUnitGas\",\"type\":\"uint192\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"commitReport\",\"type\":\"bytes\"},{\"internalType\":\"uint40\",\"name\":\"epochAndRound\",\"type\":\"uint40\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b5060405162003824380380620038248339810160408190526200004d9162000274565b80600033808281620000a65760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d957620000d98162000194565b50505015156080524660a05260408101516001600160a01b0316158062000108575080516001600160401b0316155b806200011f575060208101516001600160401b0316155b8062000136575060608101516001600160a01b0316155b156200015557604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b039081166101005260609091015116610120525062000308565b336001600160a01b03821603620001ee5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025757600080fd5b919050565b80516001600160a01b03811681146200025757600080fd5b6000608082840312156200028757600080fd5b604051608081016001600160401b0381118282101715620002b857634e487b7160e01b600052604160045260246000fd5b604052620002c6836200023f565b8152620002d6602084016200023f565b6020820152620002e9604084016200025c565b6040820152620002fc606084016200025c565b60608201529392505050565b60805160a05160c05160e051610100516101205161348d620003976000396000818161027801528181610555015281816111a1015281816119c801528181611a89015261202d01526000818161023c015261200601526000818161020c0152611fdf0152600081816101dc0152611fb001526000818161131c0152611368015260006113e3015261348d6000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c80637437ff9f116100ee578063a7206cd611610097578063b1dc65a411610071578063b1dc65a414610505578063f2fde38b14610518578063f47a86901461052b578063ff888fb11461053e57600080fd5b8063a7206cd6146104b2578063ad7a22f8146104d2578063afcb95d7146104e557600080fd5b80638456cb59116100c85780638456cb591461047a5780638da5cb5b146104825780638db94e44146104aa57600080fd5b80637437ff9f1461040357806379ba50971461044257806381ff70481461044a57600080fd5b806329b980e4116101505780634120fccd1161012a5780634120fccd146103c05780635c975abb146103d2578063666cab8d146103ee57600080fd5b806329b980e41461038457806332048875146103975780633f4ba83a146103b857600080fd5b8063181f5a7711610181578063181f5a77146103135780631dc18e561461035c5780631ef381741461037157600080fd5b806306285c69146101a85780630a6cd30d146102cb57806310c374ed146102e3575b600080fd5b6102b560408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102c29190612688565b60405180910390f35b6102d3610551565b60405190151581526020016102c2565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102c2565b61034f6040518060400160405280601181526020017f436f6d6d697453746f726520312e302e3000000000000000000000000000000081525081565b6040516102c29190612745565b61036f61036a3660046127bb565b6105e8565b005b61036f61037f366004612a4a565b6105f8565b61036f610392366004612b17565b610e19565b6103aa6103a5366004612b77565b610e65565b6040519081526020016102c2565b61036f610f5b565b60095467ffffffffffffffff166102fa565b6009546d0100000000000000000000000000900460ff166102d3565b6103f6610fc1565b6040516102c29190612c3c565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102c2565b61036f611030565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102c2565b61036f61112d565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102c2565b6102d361119d565b6103aa6104c0366004612c4f565b6000908152600a602052604090205490565b61036f6104e0366004612c68565b611254565b6040805160018152600060208201819052918101919091526060016102c2565b61036f610513366004612c83565b611297565b61036f610526366004612d3a565b6118b7565b61036f610539366004612d57565b6118cb565b6102d361054c366004612c4f565b611965565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e29190612d99565b15905090565b6105f3838383611a39565b505050565b855185518560ff16601f831115610670576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106da576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610667565b818314610768576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610667565b610773816003612dea565b83116107db576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610667565b6107e3611e4f565b6107ec86611ed2565b60065460005b818110156108e857600560006006838154811061081157610811612e01565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061088157610881612e01565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108e181612e30565b90506107f2565b50895160005b81811015610cc15760008c828151811061090a5761090a612e01565b602002602001015190506000600281111561092757610927612e68565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561096657610966612e68565b146109cd576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610a1a576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610aca57610aca612e68565b021790555090505060008c8381518110610ae657610ae6612e01565b6020026020010151905060006002811115610b0357610b03612e68565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b4257610b42612e68565b14610ba9576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610bf6576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ca657610ca6612e68565b0217905550905050505080610cba90612e30565b90506108ee565b508a51610cd59060069060208e01906125ca565b508951610ce99060079060208d01906125ca565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d6f914691309190600090610d419063ffffffff16612e97565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e61208e565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610e0399989796959493929190612eba565b60405180910390a1505050505050505050505050565b610e21611e4f565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610eb6576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610f2787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250612139915050565b9050610f3281611965565b610f40576000915050610f52565b6000908152600a602052604090205490505b95945050505050565b610f63611e4f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b6060600780548060200260200160405190810160405280929190818152602001828054801561102657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ffb575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610667565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611135611e4f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610fb7565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122e9190612d99565b15801561124f57506009546d0100000000000000000000000000900460ff16155b905090565b61125c611e4f565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b6112a6878760208b0135611a39565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146113195780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610667565b467f00000000000000000000000000000000000000000000000000000000000000001461139a576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610667565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561143c5760028260200151836040015161141d9190612f50565b6114279190612f69565b611432906001612f50565b60ff169050611452565b602082015161144c906001612f50565b60ff1690505b86811461148b576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8685146114c4576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561150757611507612e68565b600281111561151857611518612e68565b905250905060028160200151600281111561153557611535612e68565b14801561157c57506007816000015160ff168154811061155757611557612e01565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6115b2576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006115c0866020612dea565b6115cb896020612dea565b6115d78c610144612fb2565b6115e19190612fb2565b6115eb9190612fb2565b905036811461162f576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610667565b5060008a8a604051611642929190612fc5565b604051908190038120611659918e90602001612fd5565b604051602081830303815290604052805190602001209050611679612654565b8860005b818110156118a65760006001858a846020811061169c5761169c612e01565b6116a991901a601b612f50565b8f8f868181106116bb576116bb612e01565b905060200201358e8e878181106116d4576116d4612e01565b9050602002013560405160008152602001604052604051611711949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611733573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff80821686529397509195509293928401916101009091041660028111156117b6576117b6612e68565b60028111156117c7576117c7612e68565b90525090506001816020015160028111156117e4576117e4612e68565b1461181b576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061183257611832612e01565b60200201511561186e576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061188957611889612e01565b911515602090920201525061189f905081612e30565b905061167d565b505050505050505050505050505050565b6118bf611e4f565b6118c88161245a565b50565b6118d3611e4f565b60005b818110156105f35760008383838181106118f2576118f2612e01565b90506020020135905061190481611965565b611954576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061194b9083815260200190565b60405180910390a15b5061195e81612e30565b90506118d6565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a339190612d99565b92915050565b6009546d0100000000000000000000000000900460ff1615611a87576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190612d99565b15611b4d576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611b5b8385018561304f565b80515151909150151580611b7d575080516020015167ffffffffffffffff1615155b15611cb55760095464ffffffffff80841668010000000000000000909204161015611c7a57600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f866548c900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092169163866548c991611c3491600401613266565b600060405180830381600087803b158015611c4e57600080fd5b505af1158015611c62573d6000803e3d6000fd5b505050506040810151611c755750505050565b611cb5565b6040810151611cb5576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff9081169116141580611cf0575060208082015190810151905167ffffffffffffffff9182169116115b15611d2d5780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016106679190613279565b6040810151611d68576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415611db1576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201510151611dc490600161329e565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517fe81b49e583122eb290c46fc255c962b9a2dec468816c00fb7a2e6ebc42dc92d490611e419083906132c6565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ed0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610667565b565b600081806020019051810190611ee89190613322565b805190915073ffffffffffffffffffffffffffffffffffffffff16611f39576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec39161208291849061336e565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a6040516020016120b2999897969594939291906133eb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b825182516000919081830361217a576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610101821180159061218e57506101018111155b6121c4576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115612225576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003612252578660008151811061224057612240612e01565b60200260200101519350505050612453565b60008167ffffffffffffffff81111561226d5761226d61280f565b604051908082528060200260200182016040528015612296578160200160208202803683370190505b50905060008080805b858110156123d95760006001821b8b8116036122fa57888510156122e3578c5160018601958e9181106122d4576122d4612e01565b6020026020010151905061231c565b85516001850194879181106122d4576122d4612e01565b8b5160018401938d91811061231157612311612e01565b602002602001015190505b60008986101561234c578d5160018701968f91811061233d5761233d612e01565b6020026020010151905061236e565b865160018601958891811061236357612363612e01565b602002602001015190505b828511156123a8576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123b2828261254f565b8784815181106123c4576123c4612e01565b6020908102919091010152505060010161229f565b5060018503821480156123eb57508683145b80156123f657508581145b61242c576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061244157612441612e01565b60200260200101519750505050505050505b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610667565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008183106125915760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612453565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612453565b828054828255906000526020600020908101928215612644579160200282015b8281111561264457825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125ea565b50612650929150612673565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b808211156126505760008155600101612674565b60808101611a33828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b81811015612707576020818501810151868301820152016126eb565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061245360208301846126e1565b60008083601f84011261276a57600080fd5b50813567ffffffffffffffff81111561278257600080fd5b60208301915083602082850101111561279a57600080fd5b9250929050565b803564ffffffffff811681146127b657600080fd5b919050565b6000806000604084860312156127d057600080fd5b833567ffffffffffffffff8111156127e757600080fd5b6127f386828701612758565b90945092506128069050602085016127a1565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156128615761286161280f565b60405290565b6040516060810167ffffffffffffffff811182821017156128615761286161280f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156128d1576128d161280f565b604052919050565b600067ffffffffffffffff8211156128f3576128f361280f565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146118c857600080fd5b600082601f83011261293057600080fd5b81356020612945612940836128d9565b61288a565b82815260059290921b8401810191818101908684111561296457600080fd5b8286015b8481101561298857803561297b816128fd565b8352918301918301612968565b509695505050505050565b803560ff811681146127b657600080fd5b600082601f8301126129b557600080fd5b813567ffffffffffffffff8111156129cf576129cf61280f565b612a0060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161288a565b818152846020838601011115612a1557600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146127b657600080fd5b60008060008060008060c08789031215612a6357600080fd5b863567ffffffffffffffff80821115612a7b57600080fd5b612a878a838b0161291f565b97506020890135915080821115612a9d57600080fd5b612aa98a838b0161291f565b9650612ab760408a01612993565b95506060890135915080821115612acd57600080fd5b612ad98a838b016129a4565b9450612ae760808a01612a32565b935060a0890135915080821115612afd57600080fd5b50612b0a89828a016129a4565b9150509295509295509295565b600060208284031215612b2957600080fd5b612453826127a1565b60008083601f840112612b4457600080fd5b50813567ffffffffffffffff811115612b5c57600080fd5b6020830191508360208260051b850101111561279a57600080fd5b600080600080600060608688031215612b8f57600080fd5b853567ffffffffffffffff80821115612ba757600080fd5b612bb389838a01612b32565b90975095506020880135915080821115612bcc57600080fd5b50612bd988828901612b32565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612c3157815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612bff565b509495945050505050565b6020815260006124536020830184612beb565b600060208284031215612c6157600080fd5b5035919050565b600060208284031215612c7a57600080fd5b61245382612a32565b60008060008060008060008060e0898b031215612c9f57600080fd5b606089018a811115612cb057600080fd5b8998503567ffffffffffffffff80821115612cca57600080fd5b612cd68c838d01612758565b909950975060808b0135915080821115612cef57600080fd5b612cfb8c838d01612b32565b909750955060a08b0135915080821115612d1457600080fd5b50612d218b828c01612b32565b999c989b50969995989497949560c00135949350505050565b600060208284031215612d4c57600080fd5b8135612453816128fd565b60008060208385031215612d6a57600080fd5b823567ffffffffffffffff811115612d8157600080fd5b612d8d85828601612b32565b90969095509350505050565b600060208284031215612dab57600080fd5b8151801515811461245357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a3357611a33612dbb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e6157612e61612dbb565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612eb057612eb0612dbb565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612eea8184018a612beb565b90508281036080840152612efe8189612beb565b905060ff871660a084015282810360c0840152612f1b81876126e1565b905067ffffffffffffffff851660e0840152828103610100840152612f4081856126e1565b9c9b505050505050505050505050565b60ff8181168382160190811115611a3357611a33612dbb565b600060ff831680612fa3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a3357611a33612dbb565b8183823760009101908152919050565b828152606082602083013760800192915050565b803577ffffffffffffffffffffffffffffffffffffffffffffffff811681146127b657600080fd5b60006040828403121561302357600080fd5b61302b61283e565b905061303682612a32565b815261304460208301612a32565b602082015292915050565b6000602080838503121561306257600080fd5b823567ffffffffffffffff8082111561307a57600080fd5b908401906080828703121561308e57600080fd5b613096612867565b8235828111156130a557600080fd5b8301606081890312156130b757600080fd5b6130bf612867565b8135848111156130ce57600080fd5b82019350601f840189136130e157600080fd5b83356130ef612940826128d9565b81815260069190911b8501870190878101908b83111561310e57600080fd5b958801955b82871015613162576040878d03121561312c5760008081fd5b61313461283e565b873561313f816128fd565b815261314c888b01612fe9565b818b015282526040969096019590880190613113565b8352506131729050828701612a32565b8682015261318260408301612fe9565b604082015282525061319687848601613011565b93810193909352506060013560408201529392505050565b805160608084528151908401819052600091602091908201906080860190845b81811015613225578351805173ffffffffffffffffffffffffffffffffffffffff16845285015177ffffffffffffffffffffffffffffffffffffffffffffffff1685840152928401926040909201916001016131ce565b505067ffffffffffffffff83860151168387015260408501519250610f52604087018477ffffffffffffffffffffffffffffffffffffffffffffffff169052565b60208152600061245360208301846131ae565b60408101611a338284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff8181168382160190808211156132bf576132bf612dbb565b5092915050565b6020815260008251608060208401526132e260a08401826131ae565b9050602084015161330d6040850182805167ffffffffffffffff908116835260209182015116910152565b50604084015160808401528091505092915050565b60006020828403121561333457600080fd5b6040516020810181811067ffffffffffffffff821117156133575761335761280f565b6040528251613365816128fd565b81529392505050565b60a081016133c7828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526134328285018b612beb565b91508382036080850152613446828a612beb565b915060ff881660a085015283820360c085015261346382886126e1565b90861660e08501528381036101008501529050612f4081856126e156fea164736f6c6343000813000a", +} + +var CommitStoreHelperABI = CommitStoreHelperMetaData.ABI + +var CommitStoreHelperBin = CommitStoreHelperMetaData.Bin + +func DeployCommitStoreHelper(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig CommitStoreStaticConfig) (common.Address, *types.Transaction, *CommitStoreHelper, error) { + parsed, err := CommitStoreHelperMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CommitStoreHelperBin), backend, staticConfig) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CommitStoreHelper{CommitStoreHelperCaller: CommitStoreHelperCaller{contract: contract}, CommitStoreHelperTransactor: CommitStoreHelperTransactor{contract: contract}, CommitStoreHelperFilterer: CommitStoreHelperFilterer{contract: contract}}, nil +} + +type CommitStoreHelper struct { + address common.Address + abi abi.ABI + CommitStoreHelperCaller + CommitStoreHelperTransactor + CommitStoreHelperFilterer +} + +type CommitStoreHelperCaller struct { + contract *bind.BoundContract +} + +type CommitStoreHelperTransactor struct { + contract *bind.BoundContract +} + +type CommitStoreHelperFilterer struct { + contract *bind.BoundContract +} + +type CommitStoreHelperSession struct { + Contract *CommitStoreHelper + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type CommitStoreHelperCallerSession struct { + Contract *CommitStoreHelperCaller + CallOpts bind.CallOpts +} + +type CommitStoreHelperTransactorSession struct { + Contract *CommitStoreHelperTransactor + TransactOpts bind.TransactOpts +} + +type CommitStoreHelperRaw struct { + Contract *CommitStoreHelper +} + +type CommitStoreHelperCallerRaw struct { + Contract *CommitStoreHelperCaller +} + +type CommitStoreHelperTransactorRaw struct { + Contract *CommitStoreHelperTransactor +} + +func NewCommitStoreHelper(address common.Address, backend bind.ContractBackend) (*CommitStoreHelper, error) { + abi, err := abi.JSON(strings.NewReader(CommitStoreHelperABI)) + if err != nil { + return nil, err + } + contract, err := bindCommitStoreHelper(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CommitStoreHelper{address: address, abi: abi, CommitStoreHelperCaller: CommitStoreHelperCaller{contract: contract}, CommitStoreHelperTransactor: CommitStoreHelperTransactor{contract: contract}, CommitStoreHelperFilterer: CommitStoreHelperFilterer{contract: contract}}, nil +} + +func NewCommitStoreHelperCaller(address common.Address, caller bind.ContractCaller) (*CommitStoreHelperCaller, error) { + contract, err := bindCommitStoreHelper(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CommitStoreHelperCaller{contract: contract}, nil +} + +func NewCommitStoreHelperTransactor(address common.Address, transactor bind.ContractTransactor) (*CommitStoreHelperTransactor, error) { + contract, err := bindCommitStoreHelper(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CommitStoreHelperTransactor{contract: contract}, nil +} + +func NewCommitStoreHelperFilterer(address common.Address, filterer bind.ContractFilterer) (*CommitStoreHelperFilterer, error) { + contract, err := bindCommitStoreHelper(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CommitStoreHelperFilterer{contract: contract}, nil +} + +func bindCommitStoreHelper(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CommitStoreHelperMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_CommitStoreHelper *CommitStoreHelperRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStoreHelper.Contract.CommitStoreHelperCaller.contract.Call(opts, result, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.CommitStoreHelperTransactor.contract.Transfer(opts) +} + +func (_CommitStoreHelper *CommitStoreHelperRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.CommitStoreHelperTransactor.contract.Transact(opts, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStoreHelper.Contract.contract.Call(opts, result, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.contract.Transfer(opts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.contract.Transact(opts, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(CommitStoreDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreDynamicConfig)).(*CommitStoreDynamicConfig) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStoreHelper.Contract.GetDynamicConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStoreHelper.Contract.GetDynamicConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getExpectedNextSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStoreHelper.Contract.GetExpectedNextSequenceNumber(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStoreHelper.Contract.GetExpectedNextSequenceNumber(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getLatestPriceEpochAndRound") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStoreHelper.Contract.GetLatestPriceEpochAndRound(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStoreHelper.Contract.GetLatestPriceEpochAndRound(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getMerkleRoot", root) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStoreHelper.Contract.GetMerkleRoot(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStoreHelper.Contract.GetMerkleRoot(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(CommitStoreStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreStaticConfig)).(*CommitStoreStaticConfig) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStoreHelper.Contract.GetStaticConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStoreHelper.Contract.GetStaticConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetTransmitters() ([]common.Address, error) { + return _CommitStoreHelper.Contract.GetTransmitters(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetTransmitters() ([]common.Address, error) { + return _CommitStoreHelper.Contract.GetTransmitters(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) IsARMHealthy(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "isARMHealthy") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) IsARMHealthy() (bool, error) { + return _CommitStoreHelper.Contract.IsARMHealthy(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) IsARMHealthy() (bool, error) { + return _CommitStoreHelper.Contract.IsARMHealthy(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "isBlessed", root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStoreHelper.Contract.IsBlessed(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStoreHelper.Contract.IsBlessed(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "isUnpausedAndARMHealthy") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) IsUnpausedAndARMHealthy() (bool, error) { + return _CommitStoreHelper.Contract.IsUnpausedAndARMHealthy(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) IsUnpausedAndARMHealthy() (bool, error) { + return _CommitStoreHelper.Contract.IsUnpausedAndARMHealthy(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDetails(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDetails(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDigestAndEpoch(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDigestAndEpoch(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Owner() (common.Address, error) { + return _CommitStoreHelper.Contract.Owner(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) Owner() (common.Address, error) { + return _CommitStoreHelper.Contract.Owner(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Paused() (bool, error) { + return _CommitStoreHelper.Contract.Paused(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) Paused() (bool, error) { + return _CommitStoreHelper.Contract.Paused(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) TypeAndVersion() (string, error) { + return _CommitStoreHelper.Contract.TypeAndVersion(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) TypeAndVersion() (string, error) { + return _CommitStoreHelper.Contract.TypeAndVersion(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "verify", hashedLeaves, proofs, proofFlagBits) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStoreHelper.Contract.Verify(&_CommitStoreHelper.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStoreHelper.Contract.Verify(&_CommitStoreHelper.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "acceptOwnership") +} + +func (_CommitStoreHelper *CommitStoreHelperSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.AcceptOwnership(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.AcceptOwnership(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "pause") +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Pause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Pause(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Pause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Pause(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Report(opts *bind.TransactOpts, commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "report", commitReport, epochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Report(commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Report(&_CommitStoreHelper.TransactOpts, commitReport, epochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Report(commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Report(&_CommitStoreHelper.TransactOpts, commitReport, epochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "resetUnblessedRoots", rootToReset) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.ResetUnblessedRoots(&_CommitStoreHelper.TransactOpts, rootToReset) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.ResetUnblessedRoots(&_CommitStoreHelper.TransactOpts, rootToReset) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "setLatestPriceEpochAndRound", latestPriceEpochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetLatestPriceEpochAndRound(&_CommitStoreHelper.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetLatestPriceEpochAndRound(&_CommitStoreHelper.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "setMinSeqNr", minSeqNr) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetMinSeqNr(&_CommitStoreHelper.TransactOpts, minSeqNr) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetMinSeqNr(&_CommitStoreHelper.TransactOpts, minSeqNr) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "setOCR2Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetOCR2Config(&_CommitStoreHelper.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetOCR2Config(&_CommitStoreHelper.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "transferOwnership", to) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.TransferOwnership(&_CommitStoreHelper.TransactOpts, to) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.TransferOwnership(&_CommitStoreHelper.TransactOpts, to) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Transmit(&_CommitStoreHelper.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Transmit(&_CommitStoreHelper.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "unpause") +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Unpause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Unpause(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Unpause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Unpause(&_CommitStoreHelper.TransactOpts) +} + +type CommitStoreHelperConfigSetIterator struct { + Event *CommitStoreHelperConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperConfigSetIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperConfigSet struct { + StaticConfig CommitStoreStaticConfig + DynamicConfig CommitStoreDynamicConfig + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreHelperConfigSetIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &CommitStoreHelperConfigSetIterator{contract: _CommitStoreHelper.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperConfigSet) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseConfigSet(log types.Log) (*CommitStoreHelperConfigSet, error) { + event := new(CommitStoreHelperConfigSet) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperConfigSet0Iterator struct { + Event *CommitStoreHelperConfigSet0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperConfigSet0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperConfigSet0Iterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperConfigSet0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperConfigSet0 struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreHelperConfigSet0Iterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return &CommitStoreHelperConfigSet0Iterator{contract: _CommitStoreHelper.contract, event: "ConfigSet0", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet0) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperConfigSet0) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseConfigSet0(log types.Log) (*CommitStoreHelperConfigSet0, error) { + event := new(CommitStoreHelperConfigSet0) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperOwnershipTransferRequestedIterator struct { + Event *CommitStoreHelperOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreHelperOwnershipTransferRequestedIterator{contract: _CommitStoreHelper.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperOwnershipTransferRequested) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseOwnershipTransferRequested(log types.Log) (*CommitStoreHelperOwnershipTransferRequested, error) { + event := new(CommitStoreHelperOwnershipTransferRequested) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperOwnershipTransferredIterator struct { + Event *CommitStoreHelperOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreHelperOwnershipTransferredIterator{contract: _CommitStoreHelper.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperOwnershipTransferred) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseOwnershipTransferred(log types.Log) (*CommitStoreHelperOwnershipTransferred, error) { + event := new(CommitStoreHelperOwnershipTransferred) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperPausedIterator struct { + Event *CommitStoreHelperPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperPausedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperPaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterPaused(opts *bind.FilterOpts) (*CommitStoreHelperPausedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &CommitStoreHelperPausedIterator{contract: _CommitStoreHelper.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperPaused) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperPaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Paused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParsePaused(log types.Log) (*CommitStoreHelperPaused, error) { + event := new(CommitStoreHelperPaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperReportAcceptedIterator struct { + Event *CommitStoreHelperReportAccepted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperReportAcceptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperReportAcceptedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperReportAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperReportAccepted struct { + Report CommitStoreCommitReport + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreHelperReportAcceptedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return &CommitStoreHelperReportAcceptedIterator{contract: _CommitStoreHelper.contract, event: "ReportAccepted", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperReportAccepted) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperReportAccepted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseReportAccepted(log types.Log) (*CommitStoreHelperReportAccepted, error) { + event := new(CommitStoreHelperReportAccepted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperRootRemovedIterator struct { + Event *CommitStoreHelperRootRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperRootRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperRootRemovedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperRootRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperRootRemoved struct { + Root [32]byte + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreHelperRootRemovedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return &CommitStoreHelperRootRemovedIterator{contract: _CommitStoreHelper.contract, event: "RootRemoved", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperRootRemoved) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperRootRemoved) + if err := _CommitStoreHelper.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseRootRemoved(log types.Log) (*CommitStoreHelperRootRemoved, error) { + event := new(CommitStoreHelperRootRemoved) + if err := _CommitStoreHelper.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperTransmittedIterator struct { + Event *CommitStoreHelperTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperTransmittedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreHelperTransmittedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &CommitStoreHelperTransmittedIterator{contract: _CommitStoreHelper.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperTransmitted) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperTransmitted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseTransmitted(log types.Log) (*CommitStoreHelperTransmitted, error) { + event := new(CommitStoreHelperTransmitted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperUnpausedIterator struct { + Event *CommitStoreHelperUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperUnpausedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreHelperUnpausedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &CommitStoreHelperUnpausedIterator{contract: _CommitStoreHelper.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperUnpaused) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperUnpaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Unpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseUnpaused(log types.Log) (*CommitStoreHelperUnpaused, error) { + event := new(CommitStoreHelperUnpaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_CommitStoreHelper *CommitStoreHelper) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _CommitStoreHelper.abi.Events["ConfigSet"].ID: + return _CommitStoreHelper.ParseConfigSet(log) + case _CommitStoreHelper.abi.Events["ConfigSet0"].ID: + return _CommitStoreHelper.ParseConfigSet0(log) + case _CommitStoreHelper.abi.Events["OwnershipTransferRequested"].ID: + return _CommitStoreHelper.ParseOwnershipTransferRequested(log) + case _CommitStoreHelper.abi.Events["OwnershipTransferred"].ID: + return _CommitStoreHelper.ParseOwnershipTransferred(log) + case _CommitStoreHelper.abi.Events["Paused"].ID: + return _CommitStoreHelper.ParsePaused(log) + case _CommitStoreHelper.abi.Events["ReportAccepted"].ID: + return _CommitStoreHelper.ParseReportAccepted(log) + case _CommitStoreHelper.abi.Events["RootRemoved"].ID: + return _CommitStoreHelper.ParseRootRemoved(log) + case _CommitStoreHelper.abi.Events["Transmitted"].ID: + return _CommitStoreHelper.ParseTransmitted(log) + case _CommitStoreHelper.abi.Events["Unpaused"].ID: + return _CommitStoreHelper.ParseUnpaused(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (CommitStoreHelperConfigSet) Topic() common.Hash { + return common.HexToHash("0xc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec3") +} + +func (CommitStoreHelperConfigSet0) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (CommitStoreHelperOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (CommitStoreHelperOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (CommitStoreHelperPaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (CommitStoreHelperReportAccepted) Topic() common.Hash { + return common.HexToHash("0xe81b49e583122eb290c46fc255c962b9a2dec468816c00fb7a2e6ebc42dc92d4") +} + +func (CommitStoreHelperRootRemoved) Topic() common.Hash { + return common.HexToHash("0x202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12") +} + +func (CommitStoreHelperTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (CommitStoreHelperUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (_CommitStoreHelper *CommitStoreHelper) Address() common.Address { + return _CommitStoreHelper.address +} + +type CommitStoreHelperInterface interface { + GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) + + GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) + + GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) + + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + IsARMHealthy(opts *bind.CallOpts) (bool, error) + + IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) + + IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + Paused(opts *bind.CallOpts) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Pause(opts *bind.TransactOpts) (*types.Transaction, error) + + Report(opts *bind.TransactOpts, commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) + + ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) + + SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) + + SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) + + SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + Unpause(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreHelperConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*CommitStoreHelperConfigSet, error) + + FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreHelperConfigSet0Iterator, error) + + WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet0) (event.Subscription, error) + + ParseConfigSet0(log types.Log) (*CommitStoreHelperConfigSet0, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*CommitStoreHelperOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*CommitStoreHelperOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*CommitStoreHelperPausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperPaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*CommitStoreHelperPaused, error) + + FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreHelperReportAcceptedIterator, error) + + WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperReportAccepted) (event.Subscription, error) + + ParseReportAccepted(log types.Log) (*CommitStoreHelperReportAccepted, error) + + FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreHelperRootRemovedIterator, error) + + WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperRootRemoved) (event.Subscription, error) + + ParseRootRemoved(log types.Log) (*CommitStoreHelperRootRemoved, error) + + FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreHelperTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*CommitStoreHelperTransmitted, error) + + FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreHelperUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*CommitStoreHelperUnpaused, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/commit_store_helper_1_2_0/commit_store_helper_1_2_0.go b/core/gethwrappers/ccip/generated/commit_store_helper_1_2_0/commit_store_helper_1_2_0.go new file mode 100644 index 0000000000..be97466598 --- /dev/null +++ b/core/gethwrappers/ccip/generated/commit_store_helper_1_2_0/commit_store_helper_1_2_0.go @@ -0,0 +1,1969 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package commit_store_helper_1_2_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommitStoreCommitReport struct { + PriceUpdates InternalPriceUpdates + Interval CommitStoreInterval + MerkleRoot [32]byte +} + +type CommitStoreDynamicConfig struct { + PriceRegistry common.Address +} + +type CommitStoreInterval struct { + Min uint64 + Max uint64 +} + +type CommitStoreStaticConfig struct { + ChainSelector uint64 + SourceChainSelector uint64 + OnRamp common.Address + ArmProxy common.Address +} + +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var CommitStoreHelperMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"commitReport\",\"type\":\"bytes\"},{\"internalType\":\"uint40\",\"name\":\"epochAndRound\",\"type\":\"uint40\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b50604051620038e8380380620038e88339810160408190526200004d9162000274565b80600033808281620000a65760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d957620000d98162000194565b50505015156080524660a05260408101516001600160a01b0316158062000108575080516001600160401b0316155b806200011f575060208101516001600160401b0316155b8062000136575060608101516001600160a01b0316155b156200015557604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b039081166101005260609091015116610120525062000308565b336001600160a01b03821603620001ee5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025757600080fd5b919050565b80516001600160a01b03811681146200025757600080fd5b6000608082840312156200028757600080fd5b604051608081016001600160401b0381118282101715620002b857634e487b7160e01b600052604160045260246000fd5b604052620002c6836200023f565b8152620002d6602084016200023f565b6020820152620002e9604084016200025c565b6040820152620002fc606084016200025c565b60608201529392505050565b60805160a05160c05160e0516101005161012051613551620003976000396000818161027801528181610555015281816111a1015281816119c801528181611a89015261202401526000818161023c0152611ffd01526000818161020c0152611fd60152600081816101dc0152611fa701526000818161131c0152611368015260006113e301526135516000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c80637437ff9f116100ee578063a7206cd611610097578063b1dc65a411610071578063b1dc65a414610505578063f2fde38b14610518578063f47a86901461052b578063ff888fb11461053e57600080fd5b8063a7206cd6146104b2578063ad7a22f8146104d2578063afcb95d7146104e557600080fd5b80638456cb59116100c85780638456cb591461047a5780638da5cb5b146104825780638db94e44146104aa57600080fd5b80637437ff9f1461040357806379ba50971461044257806381ff70481461044a57600080fd5b806329b980e4116101505780634120fccd1161012a5780634120fccd146103c05780635c975abb146103d2578063666cab8d146103ee57600080fd5b806329b980e41461038457806332048875146103975780633f4ba83a146103b857600080fd5b8063181f5a7711610181578063181f5a77146103135780631dc18e561461035c5780631ef381741461037157600080fd5b806306285c69146101a85780630a6cd30d146102cb57806310c374ed146102e3575b600080fd5b6102b560408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102c2919061267f565b60405180910390f35b6102d3610551565b60405190151581526020016102c2565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102c2565b61034f6040518060400160405280601181526020017f436f6d6d697453746f726520312e322e3000000000000000000000000000000081525081565b6040516102c2919061273c565b61036f61036a3660046127b2565b6105e8565b005b61036f61037f366004612a41565b6105f8565b61036f610392366004612b0e565b610e19565b6103aa6103a5366004612b6e565b610e65565b6040519081526020016102c2565b61036f610f5b565b60095467ffffffffffffffff166102fa565b6009546d0100000000000000000000000000900460ff166102d3565b6103f6610fc1565b6040516102c29190612c33565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102c2565b61036f611030565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102c2565b61036f61112d565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102c2565b6102d361119d565b6103aa6104c0366004612c46565b6000908152600a602052604090205490565b61036f6104e0366004612c5f565b611254565b6040805160018152600060208201819052918101919091526060016102c2565b61036f610513366004612c7a565b611297565b61036f610526366004612d31565b6118b7565b61036f610539366004612d4e565b6118cb565b6102d361054c366004612c46565b611965565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e29190612d90565b15905090565b6105f3838383611a39565b505050565b855185518560ff16601f831115610670576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106da576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610667565b818314610768576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610667565b610773816003612de1565b83116107db576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610667565b6107e3611e46565b6107ec86611ec9565b60065460005b818110156108e857600560006006838154811061081157610811612df8565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061088157610881612df8565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108e181612e27565b90506107f2565b50895160005b81811015610cc15760008c828151811061090a5761090a612df8565b602002602001015190506000600281111561092757610927612e5f565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561096657610966612e5f565b146109cd576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610a1a576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610aca57610aca612e5f565b021790555090505060008c8381518110610ae657610ae6612df8565b6020026020010151905060006002811115610b0357610b03612e5f565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b4257610b42612e5f565b14610ba9576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610bf6576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ca657610ca6612e5f565b0217905550905050505080610cba90612e27565b90506108ee565b508a51610cd59060069060208e01906125c1565b508951610ce99060079060208d01906125c1565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d6f914691309190600090610d419063ffffffff16612e8e565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e612085565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610e0399989796959493929190612eb1565b60405180910390a1505050505050505050505050565b610e21611e46565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610eb6576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610f2787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250612130915050565b9050610f3281611965565b610f40576000915050610f52565b6000908152600a602052604090205490505b95945050505050565b610f63611e46565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b6060600780548060200260200160405190810160405280929190818152602001828054801561102657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ffb575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610667565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611135611e46565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610fb7565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122e9190612d90565b15801561124f57506009546d0100000000000000000000000000900460ff16155b905090565b61125c611e46565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b6112a6878760208b0135611a39565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146113195780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610667565b467f00000000000000000000000000000000000000000000000000000000000000001461139a576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610667565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561143c5760028260200151836040015161141d9190612f47565b6114279190612f60565b611432906001612f47565b60ff169050611452565b602082015161144c906001612f47565b60ff1690505b86811461148b576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8685146114c4576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561150757611507612e5f565b600281111561151857611518612e5f565b905250905060028160200151600281111561153557611535612e5f565b14801561157c57506007816000015160ff168154811061155757611557612df8565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6115b2576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006115c0866020612de1565b6115cb896020612de1565b6115d78c610144612fa9565b6115e19190612fa9565b6115eb9190612fa9565b905036811461162f576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610667565b5060008a8a604051611642929190612fbc565b604051908190038120611659918e90602001612fcc565b60405160208183030381529060405280519060200120905061167961264b565b8860005b818110156118a65760006001858a846020811061169c5761169c612df8565b6116a991901a601b612f47565b8f8f868181106116bb576116bb612df8565b905060200201358e8e878181106116d4576116d4612df8565b9050602002013560405160008152602001604052604051611711949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611733573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff80821686529397509195509293928401916101009091041660028111156117b6576117b6612e5f565b60028111156117c7576117c7612e5f565b90525090506001816020015160028111156117e4576117e4612e5f565b1461181b576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061183257611832612df8565b60200201511561186e576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061188957611889612df8565b911515602090920201525061189f905081612e27565b905061167d565b505050505050505050505050505050565b6118bf611e46565b6118c881612451565b50565b6118d3611e46565b60005b818110156105f35760008383838181106118f2576118f2612df8565b90506020020135905061190481611965565b611954576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061194b9083815260200190565b60405180910390a15b5061195e81612e27565b90506118d6565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a339190612d90565b92915050565b6009546d0100000000000000000000000000900460ff1615611a87576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190612d90565b15611b4d576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611b5b838501856130d7565b80515151909150151580611b7457508051602001515115155b15611cac5760095464ffffffffff80841668010000000000000000909204161015611c7157600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f91611c2b9160040161332a565b600060405180830381600087803b158015611c4557600080fd5b505af1158015611c59573d6000803e3d6000fd5b505050506040810151611c6c5750505050565b611cac565b6040810151611cac576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff9081169116141580611ce7575060208082015190810151905167ffffffffffffffff9182169116115b15611d245780602001516040517fbb1ae18d000000000000000000000000000000000000000000000000000000008152600401610667919061333d565b6040810151611d5f576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415611da8576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201510151611dbb906001613362565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf590611e3890839061338a565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ec7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610667565b565b600081806020019051810190611edf91906133e6565b805190915073ffffffffffffffffffffffffffffffffffffffff16611f30576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391612079918490613432565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a6040516020016120a9999897969594939291906134af565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303612171576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610101821180159061218557506101018111155b6121bb576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8282010161010081111561221c576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003612249578660008151811061223757612237612df8565b6020026020010151935050505061244a565b60008167ffffffffffffffff81111561226457612264612806565b60405190808252806020026020018201604052801561228d578160200160208202803683370190505b50905060008080805b858110156123d05760006001821b8b8116036122f157888510156122da578c5160018601958e9181106122cb576122cb612df8565b60200260200101519050612313565b85516001850194879181106122cb576122cb612df8565b8b5160018401938d91811061230857612308612df8565b602002602001015190505b600089861015612343578d5160018701968f91811061233457612334612df8565b60200260200101519050612365565b865160018601958891811061235a5761235a612df8565b602002602001015190505b8285111561239f576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123a98282612546565b8784815181106123bb576123bb612df8565b60209081029190910101525050600101612296565b5060018503821480156123e257508683145b80156123ed57508581145b612423576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061243857612438612df8565b60200260200101519750505050505050505b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610667565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818310612588576040805160016020808301919091528183018590526060808301879052835180840390910181526080909201909252805191012061244a565b6040805160016020808301919091528183018690526060808301869052835180840390910181526080909201909252805191012061244a565b82805482825590600052602060002090810192821561263b579160200282015b8281111561263b57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125e1565b5061264792915061266a565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115612647576000815560010161266b565b60808101611a33828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b818110156126fe576020818501810151868301820152016126e2565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061244a60208301846126d8565b60008083601f84011261276157600080fd5b50813567ffffffffffffffff81111561277957600080fd5b60208301915083602082850101111561279157600080fd5b9250929050565b803564ffffffffff811681146127ad57600080fd5b919050565b6000806000604084860312156127c757600080fd5b833567ffffffffffffffff8111156127de57600080fd5b6127ea8682870161274f565b90945092506127fd905060208501612798565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561285857612858612806565b60405290565b6040516060810167ffffffffffffffff8111828210171561285857612858612806565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156128c8576128c8612806565b604052919050565b600067ffffffffffffffff8211156128ea576128ea612806565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146118c857600080fd5b600082601f83011261292757600080fd5b8135602061293c612937836128d0565b612881565b82815260059290921b8401810191818101908684111561295b57600080fd5b8286015b8481101561297f578035612972816128f4565b835291830191830161295f565b509695505050505050565b803560ff811681146127ad57600080fd5b600082601f8301126129ac57600080fd5b813567ffffffffffffffff8111156129c6576129c6612806565b6129f760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612881565b818152846020838601011115612a0c57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146127ad57600080fd5b60008060008060008060c08789031215612a5a57600080fd5b863567ffffffffffffffff80821115612a7257600080fd5b612a7e8a838b01612916565b97506020890135915080821115612a9457600080fd5b612aa08a838b01612916565b9650612aae60408a0161298a565b95506060890135915080821115612ac457600080fd5b612ad08a838b0161299b565b9450612ade60808a01612a29565b935060a0890135915080821115612af457600080fd5b50612b0189828a0161299b565b9150509295509295509295565b600060208284031215612b2057600080fd5b61244a82612798565b60008083601f840112612b3b57600080fd5b50813567ffffffffffffffff811115612b5357600080fd5b6020830191508360208260051b850101111561279157600080fd5b600080600080600060608688031215612b8657600080fd5b853567ffffffffffffffff80821115612b9e57600080fd5b612baa89838a01612b29565b90975095506020880135915080821115612bc357600080fd5b50612bd088828901612b29565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612c2857815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612bf6565b509495945050505050565b60208152600061244a6020830184612be2565b600060208284031215612c5857600080fd5b5035919050565b600060208284031215612c7157600080fd5b61244a82612a29565b60008060008060008060008060e0898b031215612c9657600080fd5b606089018a811115612ca757600080fd5b8998503567ffffffffffffffff80821115612cc157600080fd5b612ccd8c838d0161274f565b909950975060808b0135915080821115612ce657600080fd5b612cf28c838d01612b29565b909750955060a08b0135915080821115612d0b57600080fd5b50612d188b828c01612b29565b999c989b50969995989497949560c00135949350505050565b600060208284031215612d4357600080fd5b813561244a816128f4565b60008060208385031215612d6157600080fd5b823567ffffffffffffffff811115612d7857600080fd5b612d8485828601612b29565b90969095509350505050565b600060208284031215612da257600080fd5b8151801515811461244a57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a3357611a33612db2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e5857612e58612db2565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612ea757612ea7612db2565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612ee18184018a612be2565b90508281036080840152612ef58189612be2565b905060ff871660a084015282810360c0840152612f1281876126d8565b905067ffffffffffffffff851660e0840152828103610100840152612f3781856126d8565b9c9b505050505050505050505050565b60ff8181168382160190811115611a3357611a33612db2565b600060ff831680612f9a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a3357611a33612db2565b8183823760009101908152919050565b828152606082602083013760800192915050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146127ad57600080fd5b600082601f83011261301d57600080fd5b8135602061302d612937836128d0565b82815260069290921b8401810191818101908684111561304c57600080fd5b8286015b8481101561297f57604081890312156130695760008081fd5b613071612835565b61307a82612a29565b8152613087858301612fe0565b81860152835291830191604001613050565b6000604082840312156130ab57600080fd5b6130b3612835565b90506130be82612a29565b81526130cc60208301612a29565b602082015292915050565b600060208083850312156130ea57600080fd5b823567ffffffffffffffff8082111561310257600080fd5b908401906080828703121561311657600080fd5b61311e61285e565b82358281111561312d57600080fd5b8301604081890381131561314057600080fd5b613148612835565b82358581111561315757600080fd5b8301601f81018b1361316857600080fd5b8035613176612937826128d0565b81815260069190911b8201890190898101908d83111561319557600080fd5b928a01925b828410156131e55785848f0312156131b25760008081fd5b6131ba612835565b84356131c5816128f4565b81526131d2858d01612fe0565b818d0152825292850192908a019061319a565b845250505082870135858111156131fb57600080fd5b6132078b82860161300c565b8289015250835261321a89868801613099565b8684015260608501358184015250508094505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b818110156132af578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858401529284019291850191600101613256565b50508583015187820388850152805180835290840192506000918401905b8083101561331e578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858301529284019260019290920191908501906132cd565b50979650505050505050565b60208152600061244a6020830184613236565b60408101611a338284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561338357613383612db2565b5092915050565b6020815260008251608060208401526133a660a0840182613236565b905060208401516133d16040850182805167ffffffffffffffff908116835260209182015116910152565b50604084015160808401528091505092915050565b6000602082840312156133f857600080fd5b6040516020810181811067ffffffffffffffff8211171561341b5761341b612806565b6040528251613429816128f4565b81529392505050565b60a0810161348b828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526134f68285018b612be2565b9150838203608085015261350a828a612be2565b915060ff881660a085015283820360c085015261352782886126d8565b90861660e08501528381036101008501529050612f3781856126d856fea164736f6c6343000813000a", +} + +var CommitStoreHelperABI = CommitStoreHelperMetaData.ABI + +var CommitStoreHelperBin = CommitStoreHelperMetaData.Bin + +func DeployCommitStoreHelper(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig CommitStoreStaticConfig) (common.Address, *types.Transaction, *CommitStoreHelper, error) { + parsed, err := CommitStoreHelperMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CommitStoreHelperBin), backend, staticConfig) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CommitStoreHelper{address: address, abi: *parsed, CommitStoreHelperCaller: CommitStoreHelperCaller{contract: contract}, CommitStoreHelperTransactor: CommitStoreHelperTransactor{contract: contract}, CommitStoreHelperFilterer: CommitStoreHelperFilterer{contract: contract}}, nil +} + +type CommitStoreHelper struct { + address common.Address + abi abi.ABI + CommitStoreHelperCaller + CommitStoreHelperTransactor + CommitStoreHelperFilterer +} + +type CommitStoreHelperCaller struct { + contract *bind.BoundContract +} + +type CommitStoreHelperTransactor struct { + contract *bind.BoundContract +} + +type CommitStoreHelperFilterer struct { + contract *bind.BoundContract +} + +type CommitStoreHelperSession struct { + Contract *CommitStoreHelper + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type CommitStoreHelperCallerSession struct { + Contract *CommitStoreHelperCaller + CallOpts bind.CallOpts +} + +type CommitStoreHelperTransactorSession struct { + Contract *CommitStoreHelperTransactor + TransactOpts bind.TransactOpts +} + +type CommitStoreHelperRaw struct { + Contract *CommitStoreHelper +} + +type CommitStoreHelperCallerRaw struct { + Contract *CommitStoreHelperCaller +} + +type CommitStoreHelperTransactorRaw struct { + Contract *CommitStoreHelperTransactor +} + +func NewCommitStoreHelper(address common.Address, backend bind.ContractBackend) (*CommitStoreHelper, error) { + abi, err := abi.JSON(strings.NewReader(CommitStoreHelperABI)) + if err != nil { + return nil, err + } + contract, err := bindCommitStoreHelper(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CommitStoreHelper{address: address, abi: abi, CommitStoreHelperCaller: CommitStoreHelperCaller{contract: contract}, CommitStoreHelperTransactor: CommitStoreHelperTransactor{contract: contract}, CommitStoreHelperFilterer: CommitStoreHelperFilterer{contract: contract}}, nil +} + +func NewCommitStoreHelperCaller(address common.Address, caller bind.ContractCaller) (*CommitStoreHelperCaller, error) { + contract, err := bindCommitStoreHelper(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CommitStoreHelperCaller{contract: contract}, nil +} + +func NewCommitStoreHelperTransactor(address common.Address, transactor bind.ContractTransactor) (*CommitStoreHelperTransactor, error) { + contract, err := bindCommitStoreHelper(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CommitStoreHelperTransactor{contract: contract}, nil +} + +func NewCommitStoreHelperFilterer(address common.Address, filterer bind.ContractFilterer) (*CommitStoreHelperFilterer, error) { + contract, err := bindCommitStoreHelper(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CommitStoreHelperFilterer{contract: contract}, nil +} + +func bindCommitStoreHelper(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CommitStoreHelperMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_CommitStoreHelper *CommitStoreHelperRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStoreHelper.Contract.CommitStoreHelperCaller.contract.Call(opts, result, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.CommitStoreHelperTransactor.contract.Transfer(opts) +} + +func (_CommitStoreHelper *CommitStoreHelperRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.CommitStoreHelperTransactor.contract.Transact(opts, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStoreHelper.Contract.contract.Call(opts, result, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.contract.Transfer(opts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.contract.Transact(opts, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(CommitStoreDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreDynamicConfig)).(*CommitStoreDynamicConfig) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStoreHelper.Contract.GetDynamicConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStoreHelper.Contract.GetDynamicConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getExpectedNextSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStoreHelper.Contract.GetExpectedNextSequenceNumber(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStoreHelper.Contract.GetExpectedNextSequenceNumber(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getLatestPriceEpochAndRound") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStoreHelper.Contract.GetLatestPriceEpochAndRound(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStoreHelper.Contract.GetLatestPriceEpochAndRound(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getMerkleRoot", root) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStoreHelper.Contract.GetMerkleRoot(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStoreHelper.Contract.GetMerkleRoot(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(CommitStoreStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreStaticConfig)).(*CommitStoreStaticConfig) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStoreHelper.Contract.GetStaticConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStoreHelper.Contract.GetStaticConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetTransmitters() ([]common.Address, error) { + return _CommitStoreHelper.Contract.GetTransmitters(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetTransmitters() ([]common.Address, error) { + return _CommitStoreHelper.Contract.GetTransmitters(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) IsARMHealthy(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "isARMHealthy") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) IsARMHealthy() (bool, error) { + return _CommitStoreHelper.Contract.IsARMHealthy(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) IsARMHealthy() (bool, error) { + return _CommitStoreHelper.Contract.IsARMHealthy(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "isBlessed", root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStoreHelper.Contract.IsBlessed(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStoreHelper.Contract.IsBlessed(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "isUnpausedAndARMHealthy") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) IsUnpausedAndARMHealthy() (bool, error) { + return _CommitStoreHelper.Contract.IsUnpausedAndARMHealthy(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) IsUnpausedAndARMHealthy() (bool, error) { + return _CommitStoreHelper.Contract.IsUnpausedAndARMHealthy(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDetails(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDetails(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDigestAndEpoch(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDigestAndEpoch(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Owner() (common.Address, error) { + return _CommitStoreHelper.Contract.Owner(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) Owner() (common.Address, error) { + return _CommitStoreHelper.Contract.Owner(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Paused() (bool, error) { + return _CommitStoreHelper.Contract.Paused(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) Paused() (bool, error) { + return _CommitStoreHelper.Contract.Paused(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) TypeAndVersion() (string, error) { + return _CommitStoreHelper.Contract.TypeAndVersion(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) TypeAndVersion() (string, error) { + return _CommitStoreHelper.Contract.TypeAndVersion(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "verify", hashedLeaves, proofs, proofFlagBits) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStoreHelper.Contract.Verify(&_CommitStoreHelper.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStoreHelper.Contract.Verify(&_CommitStoreHelper.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "acceptOwnership") +} + +func (_CommitStoreHelper *CommitStoreHelperSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.AcceptOwnership(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.AcceptOwnership(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "pause") +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Pause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Pause(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Pause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Pause(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Report(opts *bind.TransactOpts, commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "report", commitReport, epochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Report(commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Report(&_CommitStoreHelper.TransactOpts, commitReport, epochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Report(commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Report(&_CommitStoreHelper.TransactOpts, commitReport, epochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "resetUnblessedRoots", rootToReset) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.ResetUnblessedRoots(&_CommitStoreHelper.TransactOpts, rootToReset) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.ResetUnblessedRoots(&_CommitStoreHelper.TransactOpts, rootToReset) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "setLatestPriceEpochAndRound", latestPriceEpochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetLatestPriceEpochAndRound(&_CommitStoreHelper.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetLatestPriceEpochAndRound(&_CommitStoreHelper.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "setMinSeqNr", minSeqNr) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetMinSeqNr(&_CommitStoreHelper.TransactOpts, minSeqNr) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetMinSeqNr(&_CommitStoreHelper.TransactOpts, minSeqNr) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "setOCR2Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetOCR2Config(&_CommitStoreHelper.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetOCR2Config(&_CommitStoreHelper.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "transferOwnership", to) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.TransferOwnership(&_CommitStoreHelper.TransactOpts, to) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.TransferOwnership(&_CommitStoreHelper.TransactOpts, to) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Transmit(&_CommitStoreHelper.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Transmit(&_CommitStoreHelper.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "unpause") +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Unpause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Unpause(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Unpause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Unpause(&_CommitStoreHelper.TransactOpts) +} + +type CommitStoreHelperConfigSetIterator struct { + Event *CommitStoreHelperConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperConfigSetIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperConfigSet struct { + StaticConfig CommitStoreStaticConfig + DynamicConfig CommitStoreDynamicConfig + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreHelperConfigSetIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &CommitStoreHelperConfigSetIterator{contract: _CommitStoreHelper.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperConfigSet) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseConfigSet(log types.Log) (*CommitStoreHelperConfigSet, error) { + event := new(CommitStoreHelperConfigSet) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperConfigSet0Iterator struct { + Event *CommitStoreHelperConfigSet0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperConfigSet0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperConfigSet0Iterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperConfigSet0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperConfigSet0 struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreHelperConfigSet0Iterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return &CommitStoreHelperConfigSet0Iterator{contract: _CommitStoreHelper.contract, event: "ConfigSet0", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet0) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperConfigSet0) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseConfigSet0(log types.Log) (*CommitStoreHelperConfigSet0, error) { + event := new(CommitStoreHelperConfigSet0) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperOwnershipTransferRequestedIterator struct { + Event *CommitStoreHelperOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreHelperOwnershipTransferRequestedIterator{contract: _CommitStoreHelper.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperOwnershipTransferRequested) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseOwnershipTransferRequested(log types.Log) (*CommitStoreHelperOwnershipTransferRequested, error) { + event := new(CommitStoreHelperOwnershipTransferRequested) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperOwnershipTransferredIterator struct { + Event *CommitStoreHelperOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreHelperOwnershipTransferredIterator{contract: _CommitStoreHelper.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperOwnershipTransferred) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseOwnershipTransferred(log types.Log) (*CommitStoreHelperOwnershipTransferred, error) { + event := new(CommitStoreHelperOwnershipTransferred) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperPausedIterator struct { + Event *CommitStoreHelperPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperPausedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperPaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterPaused(opts *bind.FilterOpts) (*CommitStoreHelperPausedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &CommitStoreHelperPausedIterator{contract: _CommitStoreHelper.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperPaused) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperPaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Paused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParsePaused(log types.Log) (*CommitStoreHelperPaused, error) { + event := new(CommitStoreHelperPaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperReportAcceptedIterator struct { + Event *CommitStoreHelperReportAccepted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperReportAcceptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperReportAcceptedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperReportAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperReportAccepted struct { + Report CommitStoreCommitReport + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreHelperReportAcceptedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return &CommitStoreHelperReportAcceptedIterator{contract: _CommitStoreHelper.contract, event: "ReportAccepted", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperReportAccepted) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperReportAccepted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseReportAccepted(log types.Log) (*CommitStoreHelperReportAccepted, error) { + event := new(CommitStoreHelperReportAccepted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperRootRemovedIterator struct { + Event *CommitStoreHelperRootRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperRootRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperRootRemovedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperRootRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperRootRemoved struct { + Root [32]byte + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreHelperRootRemovedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return &CommitStoreHelperRootRemovedIterator{contract: _CommitStoreHelper.contract, event: "RootRemoved", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperRootRemoved) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperRootRemoved) + if err := _CommitStoreHelper.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseRootRemoved(log types.Log) (*CommitStoreHelperRootRemoved, error) { + event := new(CommitStoreHelperRootRemoved) + if err := _CommitStoreHelper.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperTransmittedIterator struct { + Event *CommitStoreHelperTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperTransmittedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreHelperTransmittedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &CommitStoreHelperTransmittedIterator{contract: _CommitStoreHelper.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperTransmitted) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperTransmitted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseTransmitted(log types.Log) (*CommitStoreHelperTransmitted, error) { + event := new(CommitStoreHelperTransmitted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperUnpausedIterator struct { + Event *CommitStoreHelperUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperUnpausedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreHelperUnpausedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &CommitStoreHelperUnpausedIterator{contract: _CommitStoreHelper.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperUnpaused) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperUnpaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Unpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseUnpaused(log types.Log) (*CommitStoreHelperUnpaused, error) { + event := new(CommitStoreHelperUnpaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_CommitStoreHelper *CommitStoreHelper) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _CommitStoreHelper.abi.Events["ConfigSet"].ID: + return _CommitStoreHelper.ParseConfigSet(log) + case _CommitStoreHelper.abi.Events["ConfigSet0"].ID: + return _CommitStoreHelper.ParseConfigSet0(log) + case _CommitStoreHelper.abi.Events["OwnershipTransferRequested"].ID: + return _CommitStoreHelper.ParseOwnershipTransferRequested(log) + case _CommitStoreHelper.abi.Events["OwnershipTransferred"].ID: + return _CommitStoreHelper.ParseOwnershipTransferred(log) + case _CommitStoreHelper.abi.Events["Paused"].ID: + return _CommitStoreHelper.ParsePaused(log) + case _CommitStoreHelper.abi.Events["ReportAccepted"].ID: + return _CommitStoreHelper.ParseReportAccepted(log) + case _CommitStoreHelper.abi.Events["RootRemoved"].ID: + return _CommitStoreHelper.ParseRootRemoved(log) + case _CommitStoreHelper.abi.Events["Transmitted"].ID: + return _CommitStoreHelper.ParseTransmitted(log) + case _CommitStoreHelper.abi.Events["Unpaused"].ID: + return _CommitStoreHelper.ParseUnpaused(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (CommitStoreHelperConfigSet) Topic() common.Hash { + return common.HexToHash("0xc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec3") +} + +func (CommitStoreHelperConfigSet0) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (CommitStoreHelperOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (CommitStoreHelperOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (CommitStoreHelperPaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (CommitStoreHelperReportAccepted) Topic() common.Hash { + return common.HexToHash("0x291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf5") +} + +func (CommitStoreHelperRootRemoved) Topic() common.Hash { + return common.HexToHash("0x202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12") +} + +func (CommitStoreHelperTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (CommitStoreHelperUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (_CommitStoreHelper *CommitStoreHelper) Address() common.Address { + return _CommitStoreHelper.address +} + +type CommitStoreHelperInterface interface { + GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) + + GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) + + GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) + + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + IsARMHealthy(opts *bind.CallOpts) (bool, error) + + IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) + + IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + Paused(opts *bind.CallOpts) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Pause(opts *bind.TransactOpts) (*types.Transaction, error) + + Report(opts *bind.TransactOpts, commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) + + ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) + + SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) + + SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) + + SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + Unpause(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreHelperConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*CommitStoreHelperConfigSet, error) + + FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreHelperConfigSet0Iterator, error) + + WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet0) (event.Subscription, error) + + ParseConfigSet0(log types.Log) (*CommitStoreHelperConfigSet0, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*CommitStoreHelperOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*CommitStoreHelperOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*CommitStoreHelperPausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperPaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*CommitStoreHelperPaused, error) + + FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreHelperReportAcceptedIterator, error) + + WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperReportAccepted) (event.Subscription, error) + + ParseReportAccepted(log types.Log) (*CommitStoreHelperReportAccepted, error) + + FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreHelperRootRemovedIterator, error) + + WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperRootRemoved) (event.Subscription, error) + + ParseRootRemoved(log types.Log) (*CommitStoreHelperRootRemoved, error) + + FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreHelperTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*CommitStoreHelperTransmitted, error) + + FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreHelperUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*CommitStoreHelperUnpaused, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/ether_sender_receiver/ether_sender_receiver.go b/core/gethwrappers/ccip/generated/ether_sender_receiver/ether_sender_receiver.go new file mode 100644 index 0000000000..505e42e98e --- /dev/null +++ b/core/gethwrappers/ccip/generated/ether_sender_receiver/ether_sender_receiver.go @@ -0,0 +1,361 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package ether_sender_receiver + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientAny2EVMMessage struct { + MessageId [32]byte + SourceChainSelector uint64 + Sender []byte + Data []byte + DestTokenAmounts []ClientEVMTokenAmount +} + +type ClientEVM2AnyMessage struct { + Receiver []byte + Data []byte + TokenAmounts []ClientEVMTokenAmount + FeeToken common.Address + ExtraArgs []byte +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +var EtherSenderReceiverMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"InvalidRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"gotToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"expectedToken\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gotAmounts\",\"type\":\"uint256\"}],\"name\":\"InvalidTokenAmounts\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gotAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"msgValue\",\"type\":\"uint256\"}],\"name\":\"TokenAmountNotEqualToMsgValue\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destinationChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ccipSend\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destinationChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_weth\",\"outputs\":[{\"internalType\":\"contractIWrappedNative\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60c06040523480156200001157600080fd5b5060405162001a9838038062001a98833981016040819052620000349162000169565b806001600160a01b03811662000064576040516335fdcccd60e21b81526000600482015260240160405180910390fd5b806001600160a01b03166080816001600160a01b03168152505050806001600160a01b031663e861e9076040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000be573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000e4919062000169565b6001600160a01b0390811660a081905260405163095ea7b360e01b8152918316600483015260001960248301529063095ea7b3906044016020604051808303816000875af11580156200013b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016191906200019b565b5050620001bf565b6000602082840312156200017c57600080fd5b81516001600160a01b03811681146200019457600080fd5b9392505050565b600060208284031215620001ae57600080fd5b815180151581146200019457600080fd5b60805160a051611851620002476000396000818161014b015281816104030152818161059401528181610905015281816109cc01528181610a6401528181610b0201528181610bf70152610cbf0152600081816101d6015281816102df01528181610377015281816104ab0152818161060b015281816106ff01526107bf01526118516000f3fe6080604052600436106100745760003560e01c80634dbe7e921161004e5780634dbe7e921461013957806385572ffb1461019257806396f4e9f9146101b4578063b0f479a1146101c757600080fd5b806301ffc9a714610080578063181f5a77146100b557806320487ded1461010b57600080fd5b3661007b57005b600080fd5b34801561008c57600080fd5b506100a061009b3660046110e3565b6101fa565b60405190151581526020015b60405180910390f35b3480156100c157600080fd5b506100fe6040518060400160405280601981526020017f457468657253656e646572526563656976657220312e352e300000000000000081525081565b6040516100ac919061119a565b34801561011757600080fd5b5061012b6101263660046111e2565b610293565b6040519081526020016100ac565b34801561014557600080fd5b5061016d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ac565b34801561019e57600080fd5b506101b26101ad366004611230565b61035f565b005b61012b6101c23660046111e2565b6103e9565b3480156101d357600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061016d565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f85572ffb00000000000000000000000000000000000000000000000000000000148061028d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60008061029f83610844565b6040517f20487ded00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906320487ded906103169087908590600401611265565b602060405180830381865afa158015610333573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610357919061137a565b949350505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146103d5576040517fd7f733340000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6103e66103e1826115c5565b610966565b50565b60006103f482610d38565b60006103ff83610844565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040015160008151811061045457610454611672565b6020026020010151602001516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561048b57600080fd5b505af115801561049f573d6000803e3d6000fd5b505050505060006104cd7f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166320487ded86846040518363ffffffff1660e01b8152600401610507929190611265565b602060405180830381865afa158015610524573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610548919061137a565b606083015190915073ffffffffffffffffffffffffffffffffffffffff16156107825760608201516105929073ffffffffffffffffffffffffffffffffffffffff16333084610df0565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16826060015173ffffffffffffffffffffffffffffffffffffffff16146106c257606082015173ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f00000000000000000000000000000000000000000000000000000000000000006040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af115801561069c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c091906116a1565b505b6040517f96f4e9f900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906396f4e9f9906107369088908690600401611265565b6020604051808303816000875af1158015610755573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610779919061137a565b9250505061028d565b6040517f96f4e9f900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906396f4e9f99047906107f89089908790600401611265565b60206040518083038185885af1158015610816573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061083b919061137a565b95945050505050565b61088c6040518060a00160405280606081526020016060815260200160608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b6000610897836116c3565b90508060400151516001146108e1578060400151516040517f83b9f0ae0000000000000000000000000000000000000000000000000000000081526004016103cc91815260200190565b604080513360208201520160405160208183030381529060405281602001819052507f0000000000000000000000000000000000000000000000000000000000000000816040015160008151811061093b5761093b611672565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905292915050565b60008160600151806020019051810190610980919061177f565b90508160800151516001146109ca578160800151516040517f83b9f0ae0000000000000000000000000000000000000000000000000000000081526004016103cc91815260200190565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260800151600081518110610a1857610a18611672565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1614610ad9578160800151600081518110610a5657610a56611672565b6020026020010151600001517f00000000000000000000000000000000000000000000000000000000000000006040517f0fc746a10000000000000000000000000000000000000000000000000000000081526004016103cc92919073ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b60008260800151600081518110610af257610af2611672565b60200260200101516020015190507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b8152600401610b5b91815260200190565b600060405180830381600087803b158015610b7557600080fd5b505af1158015610b89573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610be7576040519150601f19603f3d011682016040523d82523d6000602084013e610bec565b606091505b5050905080610d32577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b158015610c5d57600080fd5b505af1158015610c71573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152602482018790527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb925060440190506020604051808303816000875af1158015610d0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3091906116a1565b505b50505050565b6000610d47604083018361179c565b6000818110610d5857610d58611672565b905060400201602001359050600073ffffffffffffffffffffffffffffffffffffffff16826060016020810190610d8f919061180b565b73ffffffffffffffffffffffffffffffffffffffff1614610dec57803414610dec576040517fba2f7467000000000000000000000000000000000000000000000000000000008152600481018290523460248201526044016103cc565b5050565b6040805173ffffffffffffffffffffffffffffffffffffffff8581166024830152848116604483015260648083018590528351808403909101815260849092018352602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490840152610d3292879291600091610ec3918516908490610f72565b805190915015610f6d5780806020019051810190610ee191906116a1565b610f6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016103cc565b505050565b60606103578484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fa69190611828565b60006040518083038185875af1925050503d8060008114610fe3576040519150601f19603f3d011682016040523d82523d6000602084013e610fe8565b606091505b5091509150610ff987838387611004565b979650505050505050565b6060831561109a5782516000036110935773ffffffffffffffffffffffffffffffffffffffff85163b611093576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103cc565b5081610357565b61035783838151156110af5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103cc919061119a565b6000602082840312156110f557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461112557600080fd5b9392505050565b60005b8381101561114757818101518382015260200161112f565b50506000910152565b6000815180845261116881602086016020860161112c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006111256020830184611150565b803567ffffffffffffffff811681146111c557600080fd5b919050565b600060a082840312156111dc57600080fd5b50919050565b600080604083850312156111f557600080fd5b6111fe836111ad565b9150602083013567ffffffffffffffff81111561121a57600080fd5b611226858286016111ca565b9150509250929050565b60006020828403121561124257600080fd5b813567ffffffffffffffff81111561125957600080fd5b610357848285016111ca565b6000604067ffffffffffffffff851683526020604081850152845160a0604086015261129460e0860182611150565b9050818601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808784030160608801526112cf8383611150565b6040890151888203830160808a01528051808352908601945060009350908501905b80841015611330578451805173ffffffffffffffffffffffffffffffffffffffff168352860151868301529385019360019390930192908601906112f1565b50606089015173ffffffffffffffffffffffffffffffffffffffff1660a08901526080890151888203830160c08a0152955061136c8187611150565b9a9950505050505050505050565b60006020828403121561138c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156113e5576113e5611393565b60405290565b60405160a0810167ffffffffffffffff811182821017156113e5576113e5611393565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561145557611455611393565b604052919050565b600082601f83011261146e57600080fd5b813567ffffffffffffffff81111561148857611488611393565b6114b960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161140e565b8181528460208386010111156114ce57600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146103e657600080fd5b80356111c5816114eb565b600082601f83011261152957600080fd5b8135602067ffffffffffffffff82111561154557611545611393565b611553818360051b0161140e565b82815260069290921b8401810191818101908684111561157257600080fd5b8286015b848110156115ba576040818903121561158f5760008081fd5b6115976113c2565b81356115a2816114eb565b81528185013585820152835291830191604001611576565b509695505050505050565b600060a082360312156115d757600080fd5b6115df6113eb565b823581526115ef602084016111ad565b6020820152604083013567ffffffffffffffff8082111561160f57600080fd5b61161b3683870161145d565b6040840152606085013591508082111561163457600080fd5b6116403683870161145d565b6060840152608085013591508082111561165957600080fd5b5061166636828601611518565b60808301525092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156116b357600080fd5b8151801515811461112557600080fd5b600060a082360312156116d557600080fd5b6116dd6113eb565b823567ffffffffffffffff808211156116f557600080fd5b6117013683870161145d565b8352602085013591508082111561171757600080fd5b6117233683870161145d565b6020840152604085013591508082111561173c57600080fd5b61174836838701611518565b60408401526117596060860161150d565b6060840152608085013591508082111561177257600080fd5b506116663682860161145d565b60006020828403121561179157600080fd5b8151611125816114eb565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126117d157600080fd5b83018035915067ffffffffffffffff8211156117ec57600080fd5b6020019150600681901b360382131561180457600080fd5b9250929050565b60006020828403121561181d57600080fd5b8135611125816114eb565b6000825161183a81846020870161112c565b919091019291505056fea164736f6c6343000818000a", +} + +var EtherSenderReceiverABI = EtherSenderReceiverMetaData.ABI + +var EtherSenderReceiverBin = EtherSenderReceiverMetaData.Bin + +func DeployEtherSenderReceiver(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address) (common.Address, *types.Transaction, *EtherSenderReceiver, error) { + parsed, err := EtherSenderReceiverMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EtherSenderReceiverBin), backend, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EtherSenderReceiver{address: address, abi: *parsed, EtherSenderReceiverCaller: EtherSenderReceiverCaller{contract: contract}, EtherSenderReceiverTransactor: EtherSenderReceiverTransactor{contract: contract}, EtherSenderReceiverFilterer: EtherSenderReceiverFilterer{contract: contract}}, nil +} + +type EtherSenderReceiver struct { + address common.Address + abi abi.ABI + EtherSenderReceiverCaller + EtherSenderReceiverTransactor + EtherSenderReceiverFilterer +} + +type EtherSenderReceiverCaller struct { + contract *bind.BoundContract +} + +type EtherSenderReceiverTransactor struct { + contract *bind.BoundContract +} + +type EtherSenderReceiverFilterer struct { + contract *bind.BoundContract +} + +type EtherSenderReceiverSession struct { + Contract *EtherSenderReceiver + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type EtherSenderReceiverCallerSession struct { + Contract *EtherSenderReceiverCaller + CallOpts bind.CallOpts +} + +type EtherSenderReceiverTransactorSession struct { + Contract *EtherSenderReceiverTransactor + TransactOpts bind.TransactOpts +} + +type EtherSenderReceiverRaw struct { + Contract *EtherSenderReceiver +} + +type EtherSenderReceiverCallerRaw struct { + Contract *EtherSenderReceiverCaller +} + +type EtherSenderReceiverTransactorRaw struct { + Contract *EtherSenderReceiverTransactor +} + +func NewEtherSenderReceiver(address common.Address, backend bind.ContractBackend) (*EtherSenderReceiver, error) { + abi, err := abi.JSON(strings.NewReader(EtherSenderReceiverABI)) + if err != nil { + return nil, err + } + contract, err := bindEtherSenderReceiver(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &EtherSenderReceiver{address: address, abi: abi, EtherSenderReceiverCaller: EtherSenderReceiverCaller{contract: contract}, EtherSenderReceiverTransactor: EtherSenderReceiverTransactor{contract: contract}, EtherSenderReceiverFilterer: EtherSenderReceiverFilterer{contract: contract}}, nil +} + +func NewEtherSenderReceiverCaller(address common.Address, caller bind.ContractCaller) (*EtherSenderReceiverCaller, error) { + contract, err := bindEtherSenderReceiver(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EtherSenderReceiverCaller{contract: contract}, nil +} + +func NewEtherSenderReceiverTransactor(address common.Address, transactor bind.ContractTransactor) (*EtherSenderReceiverTransactor, error) { + contract, err := bindEtherSenderReceiver(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EtherSenderReceiverTransactor{contract: contract}, nil +} + +func NewEtherSenderReceiverFilterer(address common.Address, filterer bind.ContractFilterer) (*EtherSenderReceiverFilterer, error) { + contract, err := bindEtherSenderReceiver(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EtherSenderReceiverFilterer{contract: contract}, nil +} + +func bindEtherSenderReceiver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EtherSenderReceiverMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_EtherSenderReceiver *EtherSenderReceiverRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EtherSenderReceiver.Contract.EtherSenderReceiverCaller.contract.Call(opts, result, method, params...) +} + +func (_EtherSenderReceiver *EtherSenderReceiverRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EtherSenderReceiver.Contract.EtherSenderReceiverTransactor.contract.Transfer(opts) +} + +func (_EtherSenderReceiver *EtherSenderReceiverRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EtherSenderReceiver.Contract.EtherSenderReceiverTransactor.contract.Transact(opts, method, params...) +} + +func (_EtherSenderReceiver *EtherSenderReceiverCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EtherSenderReceiver.Contract.contract.Call(opts, result, method, params...) +} + +func (_EtherSenderReceiver *EtherSenderReceiverTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EtherSenderReceiver.Contract.contract.Transfer(opts) +} + +func (_EtherSenderReceiver *EtherSenderReceiverTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EtherSenderReceiver.Contract.contract.Transact(opts, method, params...) +} + +func (_EtherSenderReceiver *EtherSenderReceiverCaller) GetFee(opts *bind.CallOpts, destinationChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + var out []interface{} + err := _EtherSenderReceiver.contract.Call(opts, &out, "getFee", destinationChainSelector, message) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EtherSenderReceiver *EtherSenderReceiverSession) GetFee(destinationChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _EtherSenderReceiver.Contract.GetFee(&_EtherSenderReceiver.CallOpts, destinationChainSelector, message) +} + +func (_EtherSenderReceiver *EtherSenderReceiverCallerSession) GetFee(destinationChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _EtherSenderReceiver.Contract.GetFee(&_EtherSenderReceiver.CallOpts, destinationChainSelector, message) +} + +func (_EtherSenderReceiver *EtherSenderReceiverCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EtherSenderReceiver.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EtherSenderReceiver *EtherSenderReceiverSession) GetRouter() (common.Address, error) { + return _EtherSenderReceiver.Contract.GetRouter(&_EtherSenderReceiver.CallOpts) +} + +func (_EtherSenderReceiver *EtherSenderReceiverCallerSession) GetRouter() (common.Address, error) { + return _EtherSenderReceiver.Contract.GetRouter(&_EtherSenderReceiver.CallOpts) +} + +func (_EtherSenderReceiver *EtherSenderReceiverCaller) IWeth(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EtherSenderReceiver.contract.Call(opts, &out, "i_weth") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EtherSenderReceiver *EtherSenderReceiverSession) IWeth() (common.Address, error) { + return _EtherSenderReceiver.Contract.IWeth(&_EtherSenderReceiver.CallOpts) +} + +func (_EtherSenderReceiver *EtherSenderReceiverCallerSession) IWeth() (common.Address, error) { + return _EtherSenderReceiver.Contract.IWeth(&_EtherSenderReceiver.CallOpts) +} + +func (_EtherSenderReceiver *EtherSenderReceiverCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _EtherSenderReceiver.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_EtherSenderReceiver *EtherSenderReceiverSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _EtherSenderReceiver.Contract.SupportsInterface(&_EtherSenderReceiver.CallOpts, interfaceId) +} + +func (_EtherSenderReceiver *EtherSenderReceiverCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _EtherSenderReceiver.Contract.SupportsInterface(&_EtherSenderReceiver.CallOpts, interfaceId) +} + +func (_EtherSenderReceiver *EtherSenderReceiverCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _EtherSenderReceiver.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_EtherSenderReceiver *EtherSenderReceiverSession) TypeAndVersion() (string, error) { + return _EtherSenderReceiver.Contract.TypeAndVersion(&_EtherSenderReceiver.CallOpts) +} + +func (_EtherSenderReceiver *EtherSenderReceiverCallerSession) TypeAndVersion() (string, error) { + return _EtherSenderReceiver.Contract.TypeAndVersion(&_EtherSenderReceiver.CallOpts) +} + +func (_EtherSenderReceiver *EtherSenderReceiverTransactor) CcipReceive(opts *bind.TransactOpts, message ClientAny2EVMMessage) (*types.Transaction, error) { + return _EtherSenderReceiver.contract.Transact(opts, "ccipReceive", message) +} + +func (_EtherSenderReceiver *EtherSenderReceiverSession) CcipReceive(message ClientAny2EVMMessage) (*types.Transaction, error) { + return _EtherSenderReceiver.Contract.CcipReceive(&_EtherSenderReceiver.TransactOpts, message) +} + +func (_EtherSenderReceiver *EtherSenderReceiverTransactorSession) CcipReceive(message ClientAny2EVMMessage) (*types.Transaction, error) { + return _EtherSenderReceiver.Contract.CcipReceive(&_EtherSenderReceiver.TransactOpts, message) +} + +func (_EtherSenderReceiver *EtherSenderReceiverTransactor) CcipSend(opts *bind.TransactOpts, destinationChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) { + return _EtherSenderReceiver.contract.Transact(opts, "ccipSend", destinationChainSelector, message) +} + +func (_EtherSenderReceiver *EtherSenderReceiverSession) CcipSend(destinationChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) { + return _EtherSenderReceiver.Contract.CcipSend(&_EtherSenderReceiver.TransactOpts, destinationChainSelector, message) +} + +func (_EtherSenderReceiver *EtherSenderReceiverTransactorSession) CcipSend(destinationChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) { + return _EtherSenderReceiver.Contract.CcipSend(&_EtherSenderReceiver.TransactOpts, destinationChainSelector, message) +} + +func (_EtherSenderReceiver *EtherSenderReceiverTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EtherSenderReceiver.contract.RawTransact(opts, nil) +} + +func (_EtherSenderReceiver *EtherSenderReceiverSession) Receive() (*types.Transaction, error) { + return _EtherSenderReceiver.Contract.Receive(&_EtherSenderReceiver.TransactOpts) +} + +func (_EtherSenderReceiver *EtherSenderReceiverTransactorSession) Receive() (*types.Transaction, error) { + return _EtherSenderReceiver.Contract.Receive(&_EtherSenderReceiver.TransactOpts) +} + +func (_EtherSenderReceiver *EtherSenderReceiver) Address() common.Address { + return _EtherSenderReceiver.address +} + +type EtherSenderReceiverInterface interface { + GetFee(opts *bind.CallOpts, destinationChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + IWeth(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + CcipReceive(opts *bind.TransactOpts, message ClientAny2EVMMessage) (*types.Transaction, error) + + CcipSend(opts *bind.TransactOpts, destinationChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) + + Receive(opts *bind.TransactOpts) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go new file mode 100644 index 0000000000..9d5e7a4aa7 --- /dev/null +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go @@ -0,0 +1,2367 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package evm_2_evm_multi_offramp + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientAny2EVMMessage struct { + MessageId [32]byte + SourceChainSelector uint64 + Sender []byte + Data []byte + DestTokenAmounts []ClientEVMTokenAmount +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type EVM2EVMMultiOffRampCommitReport struct { + PriceUpdates InternalPriceUpdates + MerkleRoots []EVM2EVMMultiOffRampMerkleRoot +} + +type EVM2EVMMultiOffRampDynamicConfig struct { + Router common.Address + PermissionLessExecutionThresholdSeconds uint32 + MaxTokenTransferGas uint32 + MaxPoolReleaseOrMintGas uint32 + MessageValidator common.Address + PriceRegistry common.Address +} + +type EVM2EVMMultiOffRampInterval struct { + Min uint64 + Max uint64 +} + +type EVM2EVMMultiOffRampMerkleRoot struct { + SourceChainSelector uint64 + Interval EVM2EVMMultiOffRampInterval + MerkleRoot [32]byte +} + +type EVM2EVMMultiOffRampSourceChainConfig struct { + IsEnabled bool + MinSeqNr uint64 + OnRamp []byte +} + +type EVM2EVMMultiOffRampSourceChainConfigArgs struct { + SourceChainSelector uint64 + IsEnabled bool + OnRamp []byte +} + +type EVM2EVMMultiOffRampStaticConfig struct { + ChainSelector uint64 + RmnProxy common.Address + TokenAdminRegistry common.Address + NonceManager common.Address +} + +type EVM2EVMMultiOffRampUnblessedRoot struct { + SourceChainSelector uint64 + MerkleRoot [32]byte +} + +type InternalAny2EVMRampMessage struct { + Header InternalRampMessageHeader + Sender []byte + Data []byte + Receiver common.Address + GasLimit *big.Int + TokenAmounts []InternalRampTokenAmount +} + +type InternalExecutionReportSingleChain struct { + SourceChainSelector uint64 + Messages []InternalAny2EVMRampMessage + OffchainTokenData [][][]byte + Proofs [][32]byte + ProofFlagBits *big.Int +} + +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + +type InternalRampMessageHeader struct { + MessageId [32]byte + SourceChainSelector uint64 + DestChainSelector uint64 + SequenceNumber uint64 + Nonce uint64 +} + +type InternalRampTokenAmount struct { + SourcePoolAddress []byte + DestTokenAddress []byte + ExtraData []byte + Amount *big.Int +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +type MultiOCR3BaseConfigInfo struct { + ConfigDigest [32]byte + F uint8 + N uint8 + IsSignatureVerificationEnabled bool +} + +type MultiOCR3BaseOCRConfig struct { + ConfigInfo MultiOCR3BaseConfigInfo + Signers []common.Address + Transmitters []common.Address +} + +type MultiOCR3BaseOCRConfigArgs struct { + ConfigDigest [32]byte + OcrPluginType uint8 + F uint8 + IsSignatureVerificationEnabled bool + Signers []common.Address + Transmitters []common.Address +} + +var EVM2EVMMultiOffRampMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162006af738038062006af78339810160408190526200003591620008e2565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003fc565b50505062000c57565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60a08101516001600160a01b03161580620002c8575080516001600160a01b0316155b15620002e7576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b0319908116928e1692909217905560a0808e01805160068054909416908f161790925586519a8b5297518716988a0198909852925185169388019390935251909216958501959095525185169383019390935251909216908201527f0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c9060c00160405180910390a150565b60005b81518110156200064e57600082828151811062000420576200042062000a20565b60200260200101519050600081600001519050806001600160401b03166000036200045e5760405163c656089560e01b815260040160405180910390fd5b6001600160401b03811660009081526007602052604081206001810180549192916200048a9062000a36565b80601f0160208091040260200160405190810160405280929190818152602001828054620004b89062000a36565b8015620005095780601f10620004dd5761010080835404028352916020019162000509565b820191906000526020600020905b815481529060010190602001808311620004eb57829003601f168201915b505050505090506000846040015190508151600003620005ac57805160000362000546576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000556828262000ac7565b508254610100600160481b0319166101001783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005e7565b8080519060200120828051906020012014620005e75760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b6020850151835460ff19169015151783556040516001600160401b038516907f4f49973170c548fddd4a48341b75e131818913f38f44d47af57e8735eee588ba906200063590869062000b93565b60405180910390a25050505050806001019050620003ff565b5050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200068d576200068d62000652565b60405290565b604051608081016001600160401b03811182821017156200068d576200068d62000652565b60405160c081016001600160401b03811182821017156200068d576200068d62000652565b604051601f8201601f191681016001600160401b038111828210171562000708576200070862000652565b604052919050565b80516001600160401b03811681146200072857600080fd5b919050565b80516001600160a01b03811681146200072857600080fd5b805163ffffffff811681146200072857600080fd5b6000601f83601f8401126200076e57600080fd5b825160206001600160401b03808311156200078d576200078d62000652565b8260051b6200079e838201620006dd565b9384528681018301938381019089861115620007b957600080fd5b84890192505b85831015620008d557825184811115620007d95760008081fd5b89016060601f19828d038101821315620007f35760008081fd5b620007fd62000668565b6200080a89850162000710565b81526040808501518015158114620008225760008081fd5b828b01529284015192888411156200083a5760008081fd5b83850194508e603f8601126200085257600093508384fd5b898501519350888411156200086b576200086b62000652565b6200087c8a848e87011601620006dd565b92508383528e81858701011115620008945760008081fd5b60005b84811015620008b4578581018201518482018c01528a0162000897565b5060009383018a0193909352918201528352509184019190840190620007bf565b9998505050505050505050565b6000806000838503610160811215620008fa57600080fd5b60808112156200090957600080fd5b6200091362000693565b6200091e8662000710565b81526200092e602087016200072d565b602082015262000941604087016200072d565b604082015262000954606087016200072d565b6060820152935060c0607f19820112156200096e57600080fd5b5062000979620006b8565b62000987608086016200072d565b81526200099760a0860162000745565b6020820152620009aa60c0860162000745565b6040820152620009bd60e0860162000745565b6060820152620009d161010086016200072d565b6080820152620009e561012086016200072d565b60a08201526101408501519092506001600160401b0381111562000a0857600080fd5b62000a16868287016200075a565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4b57607f821691505b60208210810362000a6c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000ac2576000816000526020600020601f850160051c8101602086101562000a9d5750805b601f850160051c820191505b8181101562000abe5782815560010162000aa9565b5050505b505050565b81516001600160401b0381111562000ae35762000ae362000652565b62000afb8162000af4845462000a36565b8462000a72565b602080601f83116001811462000b33576000841562000b1a5750858301515b600019600386901b1c1916600185901b17855562000abe565b600085815260208120601f198616915b8281101562000b645788860151825594840194600190910190840162000b43565b508582101562000b835787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252825460ff811615158383015260081c6001600160401b0316604083015260608083015260018084018054600093929190849062000bd58162000a36565b80608089015260a0600183166000811462000bf9576001811462000c165762000c48565b60ff19841660a08b015260a083151560051b8b0101945062000c48565b85600052602060002060005b8481101562000c3f5781548c820185015290880190890162000c22565b8b0160a0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615e3162000cc66000396000818161023e0152612c5201526000818161020f0152612f2c0152600081816101e00152818161141801526114cf0152600081816101b001526127cc015260008181611caa0152611cf60152615e316000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b146105ca578063f716f99f146105dd578063ff888fb1146105f057600080fd5b8063d2a15d3514610584578063e9d68a8e14610597578063ece670b6146105b757600080fd5b8063a12a9870116100bd578063a12a98701461050c578063c673e5841461051f578063ccd37ba31461053f57600080fd5b806385572ffb146104e35780638da5cb5b146104f157600080fd5b8063403b2d631161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104c85780637d4eef60146104d057600080fd5b8063403b2d63146103525780635e36480c1461036557600080fd5b80632d04ab76116101605780632d04ab761461030e578063311cd513146103235780633f4b04aa1461033657600080fd5b806306285c691461017c578063181f5a77146102c5575b600080fd5b61026e60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102bc9190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103016040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102bc9190613e9e565b61032161031c366004613f49565b610613565b005b610321610331366004613ffc565b6109d9565b600a5460405167ffffffffffffffff90911681526020016102bc565b610321610360366004614185565b610a42565b610378610373366004614224565b610a56565b6040516102bc9190614281565b61045f6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c0810182526004546001600160a01b03808216835263ffffffff74010000000000000000000000000000000000000000830481166020850152780100000000000000000000000000000000000000000000000083048116948401949094527c010000000000000000000000000000000000000000000000000000000090910490921660608201526005548216608082015260065490911660a082015290565b6040516102bc9190600060c0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401528060a08501511660a08401525092915050565b610321610aac565b6103216104de366004614885565b610b6a565b6103216101773660046149b0565b6000546040516001600160a01b0390911681526020016102bc565b61032161051a366004614a04565b610d0a565b61053261052d366004614b1e565b610d1b565b6040516102bc9190614b7e565b61057661054d366004614bf3565b67ffffffffffffffff919091166000908152600960209081526040808320938352929052205490565b6040519081526020016102bc565b610321610592366004614c1d565b610e79565b6105aa6105a5366004614c92565b610f33565b6040516102bc9190614cad565b6103216105c5366004614ce8565b61101c565b6103216105d8366004614d4c565b61136f565b6103216105eb366004614dd1565b611380565b6106036105fe366004614f0f565b6113c2565b60405190151581526020016102bc565b6000610621878901896150ad565b8051515190915015158061063a57508051602001515115155b1561073a57600a5460208a01359067ffffffffffffffff808316911610156106f957600a805467ffffffffffffffff191667ffffffffffffffff831617905560065482516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921691633937306f916106c291600401615315565b600060405180830381600087803b1580156106dc57600080fd5b505af11580156106f0573d6000803e3d6000fd5b50505050610738565b816020015151600003610738576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109225760008260200151828151811061076257610762615218565b6020026020010151905060008160000151905061077e81611483565b600061078982611585565b602084015151815491925067ffffffffffffffff908116610100909204161415806107cb575060208084015190810151905167ffffffffffffffff9182169116115b1561081457825160208401516040517feefb0cac00000000000000000000000000000000000000000000000000000000815261080b929190600401615328565b60405180910390fd5b604083015180610850576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600960209081526040808320848452909152902054156108c35783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024810182905260440161080b565b60208085015101516108d6906001615373565b825468ffffffffffffffff00191661010067ffffffffffffffff92831602179092559251166000908152600960209081526040808320948352939052919091204290555060010161073d565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610952919061539b565b60405180910390a16109ce60008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506115e5915050565b505050505050505050565b610a196109e882840184615438565b6040805160008082526020820190925290610a13565b60608152602001906001900390816109fe5790505b5061195c565b604080516000808252602082019092529050610a3c6001858585858660006115e5565b50505050565b610a4a611a0c565b610a5381611a68565b50565b6000610a646001600461546d565b6002610a71608085615496565b67ffffffffffffffff16610a8591906154bd565b610a8f8585611c60565b901c166003811115610aa357610aa3614257565b90505b92915050565b6001546001600160a01b03163314610b065760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161080b565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b72611ca7565b815181518114610bae576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610cfa576000848281518110610bcd57610bcd615218565b60200260200101519050600081602001515190506000858481518110610bf557610bf5615218565b6020026020010151905080518214610c39576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610ceb576000828281518110610c5857610c58615218565b6020026020010151905080600014610ce25784602001518281518110610c8057610c80615218565b602002602001015160800151811015610ce25784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018390526044810182905260640161080b565b50600101610c3c565b50505050806001019050610bb1565b50610d05838361195c565b505050565b610d12611a0c565b610a5381611d28565b610d5e6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610e0757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610de9575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e6957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e4b575b5050505050815250509050919050565b610e81611a0c565b60005b81811015610d05576000838383818110610ea057610ea0615218565b905060400201803603810190610eb691906154d4565b9050610ec581602001516113c2565b610f2a57805167ffffffffffffffff1660009081526009602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e84565b60408051606080820183526000808352602080840182905283850183905267ffffffffffffffff8681168352600782529185902085519384018652805460ff811615158552610100900490921690830152600181018054939492939192840191610f9c9061550d565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc89061550d565b8015610e695780601f10610fea57610100808354040283529160200191610e69565b820191906000526020600020905b815481529060010190602001808311610ff857505050919092525091949350505050565b333014611055576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611092565b604080518082019091526000808252602082015281526020019060019003908161106b5790505b5060a084015151909150156110c5576110c28360a001518460200151856060015186600001516020015186611fb4565b90505b6040805160a0810182528451518152845160209081015167ffffffffffffffff1681830152808601518351600094840192611101929101613e9e565b60408051601f19818403018152918152908252868101516020830152018390526005549091506001600160a01b0316801561120e576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a19061117b9085906004016155e9565b600060405180830381600087803b15801561119557600080fd5b505af19250505080156111a6575060015b61120e573d8080156111d4576040519150601f19603f3d011682016040523d82523d6000602084013e6111d9565b606091505b50806040517f09c2532500000000000000000000000000000000000000000000000000000000815260040161080b9190613e9e565b60408501515115801561122357506080850151155b8061123a575060608501516001600160a01b03163b155b8061127a57506060850151611278906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612092565b155b15611286575050505050565b60048054608087015160608801516040517f3cf9798300000000000000000000000000000000000000000000000000000000815260009485946001600160a01b031693633cf97983936112e1938a93611388939291016155fc565b6000604051808303816000875af1158015611300573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113289190810190615638565b50915091508161136657806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161080b9190613e9e565b50505050505050565b611377611a0c565b610a53816120ae565b611388611a0c565b60005b81518110156113be576113b68282815181106113a9576113a9615218565b6020026020010151612164565b60010161138b565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa15801561145f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa691906156ce565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561151e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154291906156ce565b15610a53576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080b565b67ffffffffffffffff81166000908152600760205260408120805460ff16610aa6576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080b565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906116448760a46156eb565b905082606001511561168c57845161165d9060206154bd565b865161166a9060206154bd565b6116759060a06156eb565b61167f91906156eb565b61168990826156eb565b90505b3681146116ce576040517f8e1192e10000000000000000000000000000000000000000000000000000000081526004810182905236602482015260440161080b565b50815181146117165781516040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101919091526024810182905260440161080b565b61171e611ca7565b60ff808a166000908152600360209081526040808320338452825280832081518083019092528054808616835293949193909284019161010090910416600281111561176c5761176c614257565b600281111561177d5761177d614257565b905250905060028160200151600281111561179a5761179a614257565b1480156117ee5750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff16815481106117d6576117d6615218565b6000918252602090912001546001600160a01b031633145b611824576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5081606001511561190657602082015161183f9060016156fe565b60ff1685511461187b576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83518551146118b6576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600087876040516118c8929190615717565b6040519081900381206118df918b90602001615727565b6040516020818303038152906040528051906020012090506119048a828888886124a8565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611996576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611a05576119fd8582815181106119cb576119cb615218565b6020026020010151846119f7578583815181106119ea576119ea615218565b60200260200101516126bf565b836126bf565b6001016119ad565b5050505050565b6000546001600160a01b03163314611a665760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161080b565b565b60a08101516001600160a01b03161580611a8a575080516001600160a01b0316155b15611ac1576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a177401000000000000000000000000000000000000000063ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16939093177c010000000000000000000000000000000000000000000000000000000093871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff19908116928e1692909217905560a0808e01805160068054909416908f161790925586519a8b5297518716988a0198909852925185169388019390935251909216958501959095525185169383019390935251909216908201527f0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c9060c00160405180910390a150565b67ffffffffffffffff8216600090815260086020526040812081611c8560808561573b565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f000000000000000000000000000000000000000000000000000000000000000014611a66576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015246602482015260440161080b565b60005b81518110156113be576000828281518110611d4857611d48615218565b602002602001015190506000816000015190508067ffffffffffffffff16600003611d9f576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600760205260408120600181018054919291611dca9061550d565b80601f0160208091040260200160405190810160405280929190818152602001828054611df69061550d565b8015611e435780601f10611e1857610100808354040283529160200191611e43565b820191906000526020600020905b815481529060010190602001808311611e2657829003601f168201915b505050505090506000846040015190508151600003611efc578051600003611e97576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301611ea582826157aa565b50825468ffffffffffffffff00191661010017835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611f4f565b8080519060200120828051906020012014611f4f576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8516600482015260240161080b565b6020850151835460ff191690151517835560405167ffffffffffffffff8516907f4f49973170c548fddd4a48341b75e131818913f38f44d47af57e8735eee588ba90611f9c90869061586a565b60405180910390a25050505050806001019050611d2b565b6060855167ffffffffffffffff811115611fd057611fd0614050565b60405190808252806020026020018201604052801561201557816020015b6040805180820190915260008082526020820152815260200190600190039081611fee5790505b50905060005b86518110156120885761206387828151811061203957612039615218565b602002602001015187878787868151811061205657612056615218565b6020026020010151612ecb565b82828151811061207557612075615218565b602090810291909101015260010161201b565b5095945050505050565b600061209d836132da565b8015610aa35750610aa3838361333e565b336001600160a01b038216036121065760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161080b565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff1660000361218f576000604051631b3fab5160e11b815260040161080b9190615926565b60208082015160ff808216600090815260029093526040832060018101549293909283921690036121fc57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612251565b6060840151600182015460ff6201000090910416151590151514612251576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff8416600482015260240161080b565b60a08401518051601f60ff82161115612280576001604051631b3fab5160e11b815260040161080b9190615926565b6122e685856003018054806020026020016040519081016040528092919081815260200182805480156122dc57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122be575b505050505061340d565b8560600151156124155761235485856002018054806020026020016040519081016040528092919081815260200182805480156122dc576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122be57505050505061340d565b6080860151805161236e9060028701906020840190613da8565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f10156123ce576002604051631b3fab5160e11b815260040161080b9190615926565b60408801516123de906003615940565b60ff168160ff1611612406576003604051631b3fab5160e11b815260040161080b9190615926565b61241287836001613476565b50505b61242185836002613476565b81516124369060038601906020850190613da8565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f5479361248f938a939260028b0192919061595c565b60405180910390a16124a0856135f6565b505050505050565b6124b0613e1a565b835160005b818110156126b55760006001888684602081106124d4576124d4615218565b6124e191901a601b6156fe565b8985815181106124f3576124f3615218565b602002602001015189868151811061250d5761250d615218565b60200260200101516040516000815260200160405260405161254b949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561256d573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b038516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156125ce576125ce614257565b60028111156125df576125df614257565b90525090506001816020015160028111156125fc576125fc614257565b14612633576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061264a5761264a615218565b602002015115612686576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126a1576126a1615218565b9115156020909202015250506001016124b5565b5050505050505050565b81516126ca81611483565b60006126d582611585565b6020850151519091506000819003612718576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151518114612756576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561277157612771614050565b60405190808252806020026020018201604052801561279a578160200160208202803683370190505b50905060005b8281101561290f576000876020015182815181106127c0576127c0615218565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461285357805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161080b565b6128e9818660010180546128669061550d565b80601f01602080910402602001604051908101604052809291908181526020018280546128929061550d565b80156128df5780601f106128b4576101008083540402835291602001916128df565b820191906000526020600020905b8154815290600101906020018083116128c257829003601f168201915b5050505050613612565b8383815181106128fb576128fb615218565b6020908102919091010152506001016127a0565b506000612926858389606001518a60800151613734565b90508060000361296e576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015260240161080b565b8551151560005b848110156109ce5760008960200151828151811061299557612995615218565b6020026020010151905060006129b389836000015160600151610a56565b905060028160038111156129c9576129c9614257565b03612a20578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c910160405180910390a15050612ec3565b6000816003811115612a3457612a34614257565b1480612a5157506003816003811115612a4f57612a4f614257565b145b612aa2578151606001516040517f25507e7f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c166004830152909116602482015260440161080b565b8315612b835760045460009074010000000000000000000000000000000000000000900463ffffffff16612ad6874261546d565b1190508080612af657506003826003811115612af457612af4614257565b145b612b38576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b16600482015260240161080b565b8a8481518110612b4a57612b4a615218565b6020026020010151600014612b7d578a8481518110612b6b57612b6b615218565b60200260200101518360800181815250505b50612be9565b6000816003811115612b9757612b97614257565b14612be9578151606001516040517f3ef2a99c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c166004830152909116602482015260440161080b565b81516080015167ffffffffffffffff1615612cd7576000816003811115612c1257612c12614257565b03612cd75781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c89928e9291906004016159e2565b6020604051808303816000875af1158015612ca8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ccc91906156ce565b612cd7575050612ec3565b60008b604001518481518110612cef57612cef615218565b6020026020010151905080518360a001515114612d53578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d166004830152909116602482015260440161080b565b612d678a846000015160600151600161378a565b600080612d748584613832565b91509150612d8b8c8660000151606001518461378a565b8615612dfb576003826003811115612da557612da5614257565b03612dfb576000846003811115612dbe57612dbe614257565b14612dfb578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261080b91908390600401615a0f565b6002826003811115612e0f57612e0f614257565b14612e69576003826003811115612e2857612e28614257565b14612e69578451606001516040517f926c5a3e00000000000000000000000000000000000000000000000000000000815261080b918e918590600401615a28565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612eb59087908790615a4e565b60405180910390a450505050505b600101612975565b60408051808201909152600080825260208201526000612eee87602001516138fc565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f979190615a6e565b90506001600160a01b0381161580612fdf5750612fdd6001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612092565b155b15613021576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b038216600482015260240161080b565b6000806131276040518061010001604052808b81526020018967ffffffffffffffff1681526020018a6001600160a01b031681526020018c606001518152602001866001600160a01b031681526020018c6000015181526020018c604001518152602001888152506040516024016130999190615a8b565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3907753700000000000000000000000000000000000000000000000000000000179052600454859063ffffffff7c01000000000000000000000000000000000000000000000000000000009091041661138860846139a2565b50915091508161316557806040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161080b9190613e9e565b80516020146131ad5780516040517f78ef802400000000000000000000000000000000000000000000000000000000815260206004820152602481019190915260440161080b565b6000818060200190518101906131c39190615b62565b6040516001600160a01b038b166024820152604481018290529091506132709060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600454879063ffffffff78010000000000000000000000000000000000000000000000009091041661138860846139a2565b509093509150826132af57816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161080b9190613e9e565b604080518082019091526001600160a01b039095168552602085015250919250505095945050505050565b6000613306827f01ffc9a70000000000000000000000000000000000000000000000000000000061333e565b8015610aa65750613337827fffffffff0000000000000000000000000000000000000000000000000000000061333e565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156133f6575060208210155b80156134025750600081115b979650505050505050565b60005b8151811015610d055760ff83166000908152600360205260408120835190919084908490811061344257613442615218565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613410565b60005b82518160ff161015610a3c576000838260ff168151811061349c5761349c615218565b60200260200101519050600060028111156134b9576134b9614257565b60ff80871660009081526003602090815260408083206001600160a01b038716845290915290205461010090041660028111156134f8576134f8614257565b14613519576004604051631b3fab5160e11b815260040161080b9190615926565b6001600160a01b038116613559576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff16815260200184600281111561357f5761357f614257565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff1916176101008360028111156135dc576135dc614257565b021790555090505050806135ef90615b7b565b9050613479565b60ff8116610a5357600a805467ffffffffffffffff1916905550565b815160208082015160409283015192516000938493613658937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615b9a565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976136a19794969395929491939101615bcd565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136d89190615cc4565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b600080613742858585613ac8565b905061374d816113c2565b61375b576000915050613782565b67ffffffffffffffff86166000908152600960209081526040808320938352929052205490505b949350505050565b60006002613799608085615496565b67ffffffffffffffff166137ad91906154bd565b905060006137bb8585611c60565b9050816137ca6001600461546d565b901b1916818360038111156137e1576137e1614257565b67ffffffffffffffff871660009081526008602052604081209190921b9290921791829161381060808861573b565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906138769087908790600401615d24565b600060405180830381600087803b15801561389057600080fd5b505af19250505080156138a1575060015b6138e0573d8080156138cf576040519150601f19603f3d011682016040523d82523d6000602084013e6138d4565b606091505b506003925090506138f5565b50506040805160208101909152600081526002905b9250929050565b6000815160201461393b57816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161080b9190613e9e565b6000828060200190518101906139519190615b62565b90506001600160a01b03811180613969575061040081105b15610aa657826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161080b9190613e9e565b6000606060008361ffff1667ffffffffffffffff8111156139c5576139c5614050565b6040519080825280601f01601f1916602001820160405280156139ef576020820181803683370190505b509150863b613a22577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613a55577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613a8e577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613ab15750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b09576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b1d57506101018111155b613b3a576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613b64576040516309bde33960e01b815260040160405180910390fd5b80600003613b915786600081518110613b7f57613b7f615218565b60200260200101519350505050613d60565b60008167ffffffffffffffff811115613bac57613bac614050565b604051908082528060200260200182016040528015613bd5578160200160208202803683370190505b50905060008080805b85811015613cff5760006001821b8b811603613c395788851015613c22578c5160018601958e918110613c1357613c13615218565b60200260200101519050613c5b565b8551600185019487918110613c1357613c13615218565b8b5160018401938d918110613c5057613c50615218565b602002602001015190505b600089861015613c8b578d5160018701968f918110613c7c57613c7c615218565b60200260200101519050613cad565b8651600186019588918110613ca257613ca2615218565b602002602001015190505b82851115613cce576040516309bde33960e01b815260040160405180910390fd5b613cd88282613d67565b878481518110613cea57613cea615218565b60209081029190910101525050600101613bde565b506001850382148015613d1157508683145b8015613d1c57508581145b613d39576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613d4e57613d4e615218565b60200260200101519750505050505050505b9392505050565b6000818310613d7f57613d7a8284613d85565b610aa3565b610aa383835b604080516001602082015290810183905260608101829052600090608001613716565b828054828255906000526020600020908101928215613e0a579160200282015b82811115613e0a578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613dc8565b50613e16929150613e39565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e165760008155600101613e3a565b60005b83811015613e69578181015183820152602001613e51565b50506000910152565b60008151808452613e8a816020860160208601613e4e565b601f01601f19169290920160200192915050565b602081526000610aa36020830184613e72565b8060608101831015610aa657600080fd5b60008083601f840112613ed457600080fd5b50813567ffffffffffffffff811115613eec57600080fd5b6020830191508360208285010111156138f557600080fd5b60008083601f840112613f1657600080fd5b50813567ffffffffffffffff811115613f2e57600080fd5b6020830191508360208260051b85010111156138f557600080fd5b60008060008060008060008060e0898b031215613f6557600080fd5b613f6f8a8a613eb1565b9750606089013567ffffffffffffffff80821115613f8c57600080fd5b613f988c838d01613ec2565b909950975060808b0135915080821115613fb157600080fd5b613fbd8c838d01613f04565b909750955060a08b0135915080821115613fd657600080fd5b50613fe38b828c01613f04565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561401157600080fd5b61401b8585613eb1565b9250606084013567ffffffffffffffff81111561403757600080fd5b61404386828701613ec2565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff8111828210171561408957614089614050565b60405290565b60405160a0810167ffffffffffffffff8111828210171561408957614089614050565b6040516080810167ffffffffffffffff8111828210171561408957614089614050565b6040516060810167ffffffffffffffff8111828210171561408957614089614050565b6040805190810167ffffffffffffffff8111828210171561408957614089614050565b604051601f8201601f1916810167ffffffffffffffff8111828210171561414457614144614050565b604052919050565b6001600160a01b0381168114610a5357600080fd5b803561416c8161414c565b919050565b803563ffffffff8116811461416c57600080fd5b600060c0828403121561419757600080fd5b61419f614066565b82356141aa8161414c565b81526141b860208401614171565b60208201526141c960408401614171565b60408201526141da60608401614171565b606082015260808301356141ed8161414c565b608082015260a08301356142008161414c565b60a08201529392505050565b803567ffffffffffffffff8116811461416c57600080fd5b6000806040838503121561423757600080fd5b6142408361420c565b915061424e6020840161420c565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061427d5761427d614257565b9052565b60208101610aa6828461426d565b600067ffffffffffffffff8211156142a9576142a9614050565b5060051b60200190565b600060a082840312156142c557600080fd5b6142cd61408f565b9050813581526142df6020830161420c565b60208201526142f06040830161420c565b60408201526143016060830161420c565b60608201526143126080830161420c565b608082015292915050565b600067ffffffffffffffff82111561433757614337614050565b50601f01601f191660200190565b600082601f83011261435657600080fd5b81356143696143648261431d565b61411b565b81815284602083860101111561437e57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126143ac57600080fd5b813560206143bc6143648361428f565b82815260059290921b840181019181810190868411156143db57600080fd5b8286015b848110156144b157803567ffffffffffffffff808211156144005760008081fd5b8189019150608080601f19848d0301121561441b5760008081fd5b6144236140b2565b87840135838111156144355760008081fd5b6144438d8a83880101614345565b8252506040808501358481111561445a5760008081fd5b6144688e8b83890101614345565b8a84015250606080860135858111156144815760008081fd5b61448f8f8c838a0101614345565b92840192909252949092013593810193909352505083529183019183016143df565b509695505050505050565b600061014082840312156144cf57600080fd5b6144d7614066565b90506144e383836142b3565b815260a082013567ffffffffffffffff8082111561450057600080fd5b61450c85838601614345565b602084015260c084013591508082111561452557600080fd5b61453185838601614345565b604084015261454260e08501614161565b6060840152610100840135608084015261012084013591508082111561456757600080fd5b506145748482850161439b565b60a08301525092915050565b600082601f83011261459157600080fd5b813560206145a16143648361428f565b82815260059290921b840181019181810190868411156145c057600080fd5b8286015b848110156144b157803567ffffffffffffffff8111156145e45760008081fd5b6145f28986838b01016144bc565b8452509183019183016145c4565b600082601f83011261461157600080fd5b813560206146216143648361428f565b82815260059290921b8401810191818101908684111561464057600080fd5b8286015b848110156144b157803567ffffffffffffffff8111156146645760008081fd5b6146728986838b0101614345565b845250918301918301614644565b600082601f83011261469157600080fd5b813560206146a16143648361428f565b82815260059290921b840181019181810190868411156146c057600080fd5b8286015b848110156144b157803567ffffffffffffffff8111156146e45760008081fd5b6146f28986838b0101614600565b8452509183019183016146c4565b600082601f83011261471157600080fd5b813560206147216143648361428f565b8083825260208201915060208460051b87010193508684111561474357600080fd5b602086015b848110156144b15780358352918301918301614748565b600082601f83011261477057600080fd5b813560206147806143648361428f565b82815260059290921b8401810191818101908684111561479f57600080fd5b8286015b848110156144b157803567ffffffffffffffff808211156147c45760008081fd5b818901915060a080601f19848d030112156147df5760008081fd5b6147e761408f565b6147f288850161420c565b8152604080850135848111156148085760008081fd5b6148168e8b83890101614580565b8a840152506060808601358581111561482f5760008081fd5b61483d8f8c838a0101614680565b83850152506080915081860135858111156148585760008081fd5b6148668f8c838a0101614700565b91840191909152509190930135908301525083529183019183016147a3565b600080604080848603121561489957600080fd5b833567ffffffffffffffff808211156148b157600080fd5b6148bd8783880161475f565b94506020915081860135818111156148d457600080fd5b8601601f810188136148e557600080fd5b80356148f36143648261428f565b81815260059190911b8201840190848101908a83111561491257600080fd5b8584015b8381101561499e5780358681111561492e5760008081fd5b8501603f81018d136149405760008081fd5b878101356149506143648261428f565b81815260059190911b82018a0190898101908f8311156149705760008081fd5b928b01925b8284101561498e5783358252928a0192908a0190614975565b8652505050918601918601614916565b50809750505050505050509250929050565b6000602082840312156149c257600080fd5b813567ffffffffffffffff8111156149d957600080fd5b820160a08185031215613d6057600080fd5b8015158114610a5357600080fd5b803561416c816149eb565b60006020808385031215614a1757600080fd5b823567ffffffffffffffff80821115614a2f57600080fd5b818501915085601f830112614a4357600080fd5b8135614a516143648261428f565b81815260059190911b83018401908481019088831115614a7057600080fd5b8585015b83811015614b0057803585811115614a8c5760008081fd5b86016060818c03601f1901811315614aa45760008081fd5b614aac6140d5565b614ab78a840161420c565b8152604080840135614ac8816149eb565b828c0152918301359188831115614adf5760008081fd5b614aed8e8c85870101614345565b9082015285525050918601918601614a74565b5098975050505050505050565b803560ff8116811461416c57600080fd5b600060208284031215614b3057600080fd5b610aa382614b0d565b60008151808452602080850194506020840160005b83811015614b735781516001600160a01b031687529582019590820190600101614b4e565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614bcd60e0840182614b39565b90506040840151601f198483030160c0850152614bea8282614b39565b95945050505050565b60008060408385031215614c0657600080fd5b614c0f8361420c565b946020939093013593505050565b60008060208385031215614c3057600080fd5b823567ffffffffffffffff80821115614c4857600080fd5b818501915085601f830112614c5c57600080fd5b813581811115614c6b57600080fd5b8660208260061b8501011115614c8057600080fd5b60209290920196919550909350505050565b600060208284031215614ca457600080fd5b610aa38261420c565b6020815281511515602082015267ffffffffffffffff6020830151166040820152600060408301516060808401526137826080840182613e72565b60008060408385031215614cfb57600080fd5b823567ffffffffffffffff80821115614d1357600080fd5b614d1f868387016144bc565b93506020850135915080821115614d3557600080fd5b50614d4285828601614600565b9150509250929050565b600060208284031215614d5e57600080fd5b8135613d608161414c565b600082601f830112614d7a57600080fd5b81356020614d8a6143648361428f565b8083825260208201915060208460051b870101935086841115614dac57600080fd5b602086015b848110156144b1578035614dc48161414c565b8352918301918301614db1565b60006020808385031215614de457600080fd5b823567ffffffffffffffff80821115614dfc57600080fd5b818501915085601f830112614e1057600080fd5b8135614e1e6143648261428f565b81815260059190911b83018401908481019088831115614e3d57600080fd5b8585015b83811015614b0057803585811115614e5857600080fd5b860160c0818c03601f19011215614e6f5760008081fd5b614e77614066565b8882013581526040614e8a818401614b0d565b8a8301526060614e9b818501614b0d565b8284015260809150614eae8285016149f9565b9083015260a08381013589811115614ec65760008081fd5b614ed48f8d83880101614d69565b838501525060c0840135915088821115614eee5760008081fd5b614efc8e8c84870101614d69565b9083015250845250918601918601614e41565b600060208284031215614f2157600080fd5b5035919050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461416c57600080fd5b600082601f830112614f6557600080fd5b81356020614f756143648361428f565b82815260069290921b84018101918181019086841115614f9457600080fd5b8286015b848110156144b15760408189031215614fb15760008081fd5b614fb96140f8565b614fc28261420c565b8152614fcf858301614f28565b81860152835291830191604001614f98565b600082601f830112614ff257600080fd5b813560206150026143648361428f565b82815260079290921b8401810191818101908684111561502157600080fd5b8286015b848110156144b157808803608081121561503f5760008081fd5b6150476140d5565b6150508361420c565b8152604080601f19840112156150665760008081fd5b61506e6140f8565b925061507b87850161420c565b835261508881850161420c565b8388015281870192909252606083013591810191909152835291830191608001615025565b600060208083850312156150c057600080fd5b823567ffffffffffffffff808211156150d857600080fd5b818501915060408083880312156150ee57600080fd5b6150f66140f8565b83358381111561510557600080fd5b84016040818a03121561511757600080fd5b61511f6140f8565b81358581111561512e57600080fd5b8201601f81018b1361513f57600080fd5b803561514d6143648261428f565b81815260069190911b8201890190898101908d83111561516c57600080fd5b928a01925b828410156151bc5787848f0312156151895760008081fd5b6151916140f8565b843561519c8161414c565b81526151a9858d01614f28565b818d0152825292870192908a0190615171565b8452505050818701359350848411156151d457600080fd5b6151e08a858401614f54565b81880152825250838501359150828211156151fa57600080fd5b61520688838601614fe1565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561529a57835180516001600160a01b031684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685840152928401929185019160010161524e565b50508583015187820388850152805180835290840192506000918401905b80831015615309578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858301529284019260019290920191908501906152b8565b50979650505050505050565b602081526000610aa3602083018461522e565b67ffffffffffffffff8316815260608101613d606020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153945761539461535d565b5092915050565b6000602080835260608451604080848701526153ba606087018361522e565b87850151878203601f19016040890152805180835290860193506000918601905b80831015614b0057845167ffffffffffffffff81511683528781015161541a89850182805167ffffffffffffffff908116835260209182015116910152565b508401518287015293860193600192909201916080909101906153db565b60006020828403121561544a57600080fd5b813567ffffffffffffffff81111561546157600080fd5b6137828482850161475f565b81810381811115610aa657610aa661535d565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff808416806154b1576154b1615480565b92169190910692915050565b8082028115828204841417610aa657610aa661535d565b6000604082840312156154e657600080fd5b6154ee6140f8565b6154f78361420c565b8152602083013560208201528091505092915050565b600181811c9082168061552157607f821691505b60208210810361554157634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261557b60a0870182613e72565b9050606085015186820360608801526155948282613e72565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561530957835180516001600160a01b03168352860151868301529285019260019290920191908401906155b7565b602081526000610aa36020830184615547565b60808152600061560f6080830187615547565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561564d57600080fd5b8351615658816149eb565b602085015190935067ffffffffffffffff81111561567557600080fd5b8401601f8101861361568657600080fd5b80516156946143648261431d565b8181528760208385010111156156a957600080fd5b6156ba826020830160208601613e4e565b809450505050604084015190509250925092565b6000602082840312156156e057600080fd5b8151613d60816149eb565b80820180821115610aa657610aa661535d565b60ff8181168382160190811115610aa657610aa661535d565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061575657615756615480565b92169190910492915050565b601f821115610d05576000816000526020600020601f850160051c8101602086101561578b5750805b601f850160051c820191505b818110156124a057828155600101615797565b815167ffffffffffffffff8111156157c4576157c4614050565b6157d8816157d2845461550d565b84615762565b602080601f83116001811461580d57600084156157f55750858301515b600019600386901b1c1916600185901b1785556124a0565b600085815260208120601f198616915b8281101561583c5788860151825594840194600190910190840161581d565b508582101561585a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020808352835460ff81161515602085015267ffffffffffffffff8160081c166040850152506001808501606080860152600081546158aa8161550d565b80608089015260a060018316600081146158cb57600181146158e757615917565b60ff19841660a08b015260a083151560051b8b01019450615917565b85600052602060002060005b8481101561590e5781548c82018501529088019089016158f3565b8b0160a0019550505b50929998505050505050505050565b602081016005831061593a5761593a614257565b91905290565b60ff81811683821602908116908181146153945761539461535d565b600060a0820160ff88168352602087602085015260a0604085015281875480845260c086019150886000526020600020935060005b818110156159b65784546001600160a01b031683526001948501949284019201615991565b505084810360608601526159ca8188614b39565b935050505060ff831660808301529695505050505050565b600067ffffffffffffffff808616835280851660208401525060606040830152614bea6060830184613e72565b8281526040602082015260006137826040830184613e72565b67ffffffffffffffff84811682528316602082015260608101613782604083018461426d565b615a58818461426d565b6040602082015260006137826040830184613e72565b600060208284031215615a8057600080fd5b8151613d608161414c565b6020815260008251610100806020850152615aaa610120850183613e72565b91506020850151615ac7604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615b0160a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615b1e8483613e72565b935060c08701519150808685030160e0870152615b3b8483613e72565b935060e0870151915080868503018387015250615b588382613e72565b9695505050505050565b600060208284031215615b7457600080fd5b5051919050565b600060ff821660ff8103615b9157615b9161535d565b60010192915050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152615b586080830184613e72565b86815260c060208201526000615be660c0830188613e72565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615cb757601f19868403018952815160808151818652615c6382870182613e72565b9150508582015185820387870152615c7b8282613e72565b91505060408083015186830382880152615c958382613e72565b6060948501519790940196909652505098840198925090830190600101615c3d565b5090979650505050505050565b602081526000610aa36020830184615c20565b60008282518085526020808601955060208260051b8401016020860160005b84811015615cb757601f19868403018952615d12838351613e72565b98840198925090830190600101615cf6565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615d8c610180850183613e72565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615dc98483613e72565b935060608801519150615de86101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615e0f8282615c20565b9150508281036020840152614bea8185615cd756fea164736f6c6343000818000a", +} + +var EVM2EVMMultiOffRampABI = EVM2EVMMultiOffRampMetaData.ABI + +var EVM2EVMMultiOffRampBin = EVM2EVMMultiOffRampMetaData.Bin + +func DeployEVM2EVMMultiOffRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMMultiOffRampStaticConfig, dynamicConfig EVM2EVMMultiOffRampDynamicConfig, sourceChainConfigs []EVM2EVMMultiOffRampSourceChainConfigArgs) (common.Address, *types.Transaction, *EVM2EVMMultiOffRamp, error) { + parsed, err := EVM2EVMMultiOffRampMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMMultiOffRampBin), backend, staticConfig, dynamicConfig, sourceChainConfigs) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EVM2EVMMultiOffRamp{address: address, abi: *parsed, EVM2EVMMultiOffRampCaller: EVM2EVMMultiOffRampCaller{contract: contract}, EVM2EVMMultiOffRampTransactor: EVM2EVMMultiOffRampTransactor{contract: contract}, EVM2EVMMultiOffRampFilterer: EVM2EVMMultiOffRampFilterer{contract: contract}}, nil +} + +type EVM2EVMMultiOffRamp struct { + address common.Address + abi abi.ABI + EVM2EVMMultiOffRampCaller + EVM2EVMMultiOffRampTransactor + EVM2EVMMultiOffRampFilterer +} + +type EVM2EVMMultiOffRampCaller struct { + contract *bind.BoundContract +} + +type EVM2EVMMultiOffRampTransactor struct { + contract *bind.BoundContract +} + +type EVM2EVMMultiOffRampFilterer struct { + contract *bind.BoundContract +} + +type EVM2EVMMultiOffRampSession struct { + Contract *EVM2EVMMultiOffRamp + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type EVM2EVMMultiOffRampCallerSession struct { + Contract *EVM2EVMMultiOffRampCaller + CallOpts bind.CallOpts +} + +type EVM2EVMMultiOffRampTransactorSession struct { + Contract *EVM2EVMMultiOffRampTransactor + TransactOpts bind.TransactOpts +} + +type EVM2EVMMultiOffRampRaw struct { + Contract *EVM2EVMMultiOffRamp +} + +type EVM2EVMMultiOffRampCallerRaw struct { + Contract *EVM2EVMMultiOffRampCaller +} + +type EVM2EVMMultiOffRampTransactorRaw struct { + Contract *EVM2EVMMultiOffRampTransactor +} + +func NewEVM2EVMMultiOffRamp(address common.Address, backend bind.ContractBackend) (*EVM2EVMMultiOffRamp, error) { + abi, err := abi.JSON(strings.NewReader(EVM2EVMMultiOffRampABI)) + if err != nil { + return nil, err + } + contract, err := bindEVM2EVMMultiOffRamp(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRamp{address: address, abi: abi, EVM2EVMMultiOffRampCaller: EVM2EVMMultiOffRampCaller{contract: contract}, EVM2EVMMultiOffRampTransactor: EVM2EVMMultiOffRampTransactor{contract: contract}, EVM2EVMMultiOffRampFilterer: EVM2EVMMultiOffRampFilterer{contract: contract}}, nil +} + +func NewEVM2EVMMultiOffRampCaller(address common.Address, caller bind.ContractCaller) (*EVM2EVMMultiOffRampCaller, error) { + contract, err := bindEVM2EVMMultiOffRamp(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampCaller{contract: contract}, nil +} + +func NewEVM2EVMMultiOffRampTransactor(address common.Address, transactor bind.ContractTransactor) (*EVM2EVMMultiOffRampTransactor, error) { + contract, err := bindEVM2EVMMultiOffRamp(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampTransactor{contract: contract}, nil +} + +func NewEVM2EVMMultiOffRampFilterer(address common.Address, filterer bind.ContractFilterer) (*EVM2EVMMultiOffRampFilterer, error) { + contract, err := bindEVM2EVMMultiOffRamp(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampFilterer{contract: contract}, nil +} + +func bindEVM2EVMMultiOffRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EVM2EVMMultiOffRampMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMMultiOffRamp.Contract.EVM2EVMMultiOffRampCaller.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.EVM2EVMMultiOffRampTransactor.contract.Transfer(opts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.EVM2EVMMultiOffRampTransactor.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMMultiOffRamp.Contract.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.contract.Transfer(opts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) CcipReceive(opts *bind.CallOpts, arg0 ClientAny2EVMMessage) error { + var out []interface{} + err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "ccipReceive", arg0) + + if err != nil { + return err + } + + return err + +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) CcipReceive(arg0 ClientAny2EVMMessage) error { + return _EVM2EVMMultiOffRamp.Contract.CcipReceive(&_EVM2EVMMultiOffRamp.CallOpts, arg0) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) CcipReceive(arg0 ClientAny2EVMMessage) error { + return _EVM2EVMMultiOffRamp.Contract.CcipReceive(&_EVM2EVMMultiOffRamp.CallOpts, arg0) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMMultiOffRampDynamicConfig, error) { + var out []interface{} + err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(EVM2EVMMultiOffRampDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOffRampDynamicConfig)).(*EVM2EVMMultiOffRampDynamicConfig) + + return out0, err + +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetDynamicConfig() (EVM2EVMMultiOffRampDynamicConfig, error) { + return _EVM2EVMMultiOffRamp.Contract.GetDynamicConfig(&_EVM2EVMMultiOffRamp.CallOpts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetDynamicConfig() (EVM2EVMMultiOffRampDynamicConfig, error) { + return _EVM2EVMMultiOffRamp.Contract.GetDynamicConfig(&_EVM2EVMMultiOffRamp.CallOpts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetExecutionState(opts *bind.CallOpts, sourceChainSelector uint64, sequenceNumber uint64) (uint8, error) { + var out []interface{} + err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getExecutionState", sourceChainSelector, sequenceNumber) + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetExecutionState(sourceChainSelector uint64, sequenceNumber uint64) (uint8, error) { + return _EVM2EVMMultiOffRamp.Contract.GetExecutionState(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector, sequenceNumber) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetExecutionState(sourceChainSelector uint64, sequenceNumber uint64) (uint8, error) { + return _EVM2EVMMultiOffRamp.Contract.GetExecutionState(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector, sequenceNumber) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetLatestPriceSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getLatestPriceSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetLatestPriceSequenceNumber() (uint64, error) { + return _EVM2EVMMultiOffRamp.Contract.GetLatestPriceSequenceNumber(&_EVM2EVMMultiOffRamp.CallOpts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetLatestPriceSequenceNumber() (uint64, error) { + return _EVM2EVMMultiOffRamp.Contract.GetLatestPriceSequenceNumber(&_EVM2EVMMultiOffRamp.CallOpts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetMerkleRoot(opts *bind.CallOpts, sourceChainSelector uint64, root [32]byte) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getMerkleRoot", sourceChainSelector, root) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetMerkleRoot(sourceChainSelector uint64, root [32]byte) (*big.Int, error) { + return _EVM2EVMMultiOffRamp.Contract.GetMerkleRoot(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector, root) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetMerkleRoot(sourceChainSelector uint64, root [32]byte) (*big.Int, error) { + return _EVM2EVMMultiOffRamp.Contract.GetMerkleRoot(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector, root) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) { + var out []interface{} + err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getSourceChainConfig", sourceChainSelector) + + if err != nil { + return *new(EVM2EVMMultiOffRampSourceChainConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOffRampSourceChainConfig)).(*EVM2EVMMultiOffRampSourceChainConfig) + + return out0, err + +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetSourceChainConfig(sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) { + return _EVM2EVMMultiOffRamp.Contract.GetSourceChainConfig(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetSourceChainConfig(sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) { + return _EVM2EVMMultiOffRamp.Contract.GetSourceChainConfig(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMMultiOffRampStaticConfig, error) { + var out []interface{} + err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(EVM2EVMMultiOffRampStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOffRampStaticConfig)).(*EVM2EVMMultiOffRampStaticConfig) + + return out0, err + +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetStaticConfig() (EVM2EVMMultiOffRampStaticConfig, error) { + return _EVM2EVMMultiOffRamp.Contract.GetStaticConfig(&_EVM2EVMMultiOffRamp.CallOpts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetStaticConfig() (EVM2EVMMultiOffRampStaticConfig, error) { + return _EVM2EVMMultiOffRamp.Contract.GetStaticConfig(&_EVM2EVMMultiOffRamp.CallOpts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { + var out []interface{} + err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "isBlessed", root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) IsBlessed(root [32]byte) (bool, error) { + return _EVM2EVMMultiOffRamp.Contract.IsBlessed(&_EVM2EVMMultiOffRamp.CallOpts, root) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) IsBlessed(root [32]byte) (bool, error) { + return _EVM2EVMMultiOffRamp.Contract.IsBlessed(&_EVM2EVMMultiOffRamp.CallOpts, root) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) LatestConfigDetails(opts *bind.CallOpts, ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { + var out []interface{} + err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "latestConfigDetails", ocrPluginType) + + if err != nil { + return *new(MultiOCR3BaseOCRConfig), err + } + + out0 := *abi.ConvertType(out[0], new(MultiOCR3BaseOCRConfig)).(*MultiOCR3BaseOCRConfig) + + return out0, err + +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) LatestConfigDetails(ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { + return _EVM2EVMMultiOffRamp.Contract.LatestConfigDetails(&_EVM2EVMMultiOffRamp.CallOpts, ocrPluginType) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) LatestConfigDetails(ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { + return _EVM2EVMMultiOffRamp.Contract.LatestConfigDetails(&_EVM2EVMMultiOffRamp.CallOpts, ocrPluginType) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) Owner() (common.Address, error) { + return _EVM2EVMMultiOffRamp.Contract.Owner(&_EVM2EVMMultiOffRamp.CallOpts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) Owner() (common.Address, error) { + return _EVM2EVMMultiOffRamp.Contract.Owner(&_EVM2EVMMultiOffRamp.CallOpts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) TypeAndVersion() (string, error) { + return _EVM2EVMMultiOffRamp.Contract.TypeAndVersion(&_EVM2EVMMultiOffRamp.CallOpts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) TypeAndVersion() (string, error) { + return _EVM2EVMMultiOffRamp.Contract.TypeAndVersion(&_EVM2EVMMultiOffRamp.CallOpts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.contract.Transact(opts, "acceptOwnership") +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.AcceptOwnership(&_EVM2EVMMultiOffRamp.TransactOpts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.AcceptOwnership(&_EVM2EVMMultiOffRamp.TransactOpts) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) ApplySourceChainConfigUpdates(opts *bind.TransactOpts, sourceChainConfigUpdates []EVM2EVMMultiOffRampSourceChainConfigArgs) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.contract.Transact(opts, "applySourceChainConfigUpdates", sourceChainConfigUpdates) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) ApplySourceChainConfigUpdates(sourceChainConfigUpdates []EVM2EVMMultiOffRampSourceChainConfigArgs) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.ApplySourceChainConfigUpdates(&_EVM2EVMMultiOffRamp.TransactOpts, sourceChainConfigUpdates) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) ApplySourceChainConfigUpdates(sourceChainConfigUpdates []EVM2EVMMultiOffRampSourceChainConfigArgs) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.ApplySourceChainConfigUpdates(&_EVM2EVMMultiOffRamp.TransactOpts, sourceChainConfigUpdates) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) Commit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.contract.Transact(opts, "commit", reportContext, report, rs, ss, rawVs) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) Commit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.Commit(&_EVM2EVMMultiOffRamp.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) Commit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.Commit(&_EVM2EVMMultiOffRamp.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) Execute(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.contract.Transact(opts, "execute", reportContext, report) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) Execute(reportContext [3][32]byte, report []byte) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.Execute(&_EVM2EVMMultiOffRamp.TransactOpts, reportContext, report) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) Execute(reportContext [3][32]byte, report []byte) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.Execute(&_EVM2EVMMultiOffRamp.TransactOpts, reportContext, report) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) ExecuteSingleMessage(opts *bind.TransactOpts, message InternalAny2EVMRampMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.contract.Transact(opts, "executeSingleMessage", message, offchainTokenData) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) ExecuteSingleMessage(message InternalAny2EVMRampMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMMultiOffRamp.TransactOpts, message, offchainTokenData) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) ExecuteSingleMessage(message InternalAny2EVMRampMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMMultiOffRamp.TransactOpts, message, offchainTokenData) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) ManuallyExecute(opts *bind.TransactOpts, reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.contract.Transact(opts, "manuallyExecute", reports, gasLimitOverrides) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) ManuallyExecute(reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.ManuallyExecute(&_EVM2EVMMultiOffRamp.TransactOpts, reports, gasLimitOverrides) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) ManuallyExecute(reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.ManuallyExecute(&_EVM2EVMMultiOffRamp.TransactOpts, reports, gasLimitOverrides) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset []EVM2EVMMultiOffRampUnblessedRoot) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.contract.Transact(opts, "resetUnblessedRoots", rootToReset) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) ResetUnblessedRoots(rootToReset []EVM2EVMMultiOffRampUnblessedRoot) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.ResetUnblessedRoots(&_EVM2EVMMultiOffRamp.TransactOpts, rootToReset) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) ResetUnblessedRoots(rootToReset []EVM2EVMMultiOffRampUnblessedRoot) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.ResetUnblessedRoots(&_EVM2EVMMultiOffRamp.TransactOpts, rootToReset) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMMultiOffRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.contract.Transact(opts, "setDynamicConfig", dynamicConfig) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) SetDynamicConfig(dynamicConfig EVM2EVMMultiOffRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.SetDynamicConfig(&_EVM2EVMMultiOffRamp.TransactOpts, dynamicConfig) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) SetDynamicConfig(dynamicConfig EVM2EVMMultiOffRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.SetDynamicConfig(&_EVM2EVMMultiOffRamp.TransactOpts, dynamicConfig) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) SetOCR3Configs(opts *bind.TransactOpts, ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.contract.Transact(opts, "setOCR3Configs", ocrConfigArgs) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) SetOCR3Configs(ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.SetOCR3Configs(&_EVM2EVMMultiOffRamp.TransactOpts, ocrConfigArgs) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) SetOCR3Configs(ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.SetOCR3Configs(&_EVM2EVMMultiOffRamp.TransactOpts, ocrConfigArgs) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.contract.Transact(opts, "transferOwnership", to) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.TransferOwnership(&_EVM2EVMMultiOffRamp.TransactOpts, to) +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMMultiOffRamp.Contract.TransferOwnership(&_EVM2EVMMultiOffRamp.TransactOpts, to) +} + +type EVM2EVMMultiOffRampCommitReportAcceptedIterator struct { + Event *EVM2EVMMultiOffRampCommitReportAccepted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampCommitReportAcceptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampCommitReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampCommitReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampCommitReportAcceptedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampCommitReportAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampCommitReportAccepted struct { + Report EVM2EVMMultiOffRampCommitReport + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterCommitReportAccepted(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampCommitReportAcceptedIterator, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "CommitReportAccepted") + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampCommitReportAcceptedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "CommitReportAccepted", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchCommitReportAccepted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampCommitReportAccepted) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "CommitReportAccepted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampCommitReportAccepted) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "CommitReportAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseCommitReportAccepted(log types.Log) (*EVM2EVMMultiOffRampCommitReportAccepted, error) { + event := new(EVM2EVMMultiOffRampCommitReportAccepted) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "CommitReportAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOffRampConfigSetIterator struct { + Event *EVM2EVMMultiOffRampConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampConfigSet struct { + OcrPluginType uint8 + ConfigDigest [32]byte + Signers []common.Address + Transmitters []common.Address + F uint8 + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampConfigSetIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampConfigSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseConfigSet(log types.Log) (*EVM2EVMMultiOffRampConfigSet, error) { + event := new(EVM2EVMMultiOffRampConfigSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOffRampDynamicConfigSetIterator struct { + Event *EVM2EVMMultiOffRampDynamicConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampDynamicConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampDynamicConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampDynamicConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampDynamicConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampDynamicConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampDynamicConfigSet struct { + DynamicConfig EVM2EVMMultiOffRampDynamicConfig + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterDynamicConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampDynamicConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "DynamicConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampDynamicConfigSetIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "DynamicConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchDynamicConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampDynamicConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "DynamicConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampDynamicConfigSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "DynamicConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseDynamicConfigSet(log types.Log) (*EVM2EVMMultiOffRampDynamicConfigSet, error) { + event := new(EVM2EVMMultiOffRampDynamicConfigSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "DynamicConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOffRampExecutionStateChangedIterator struct { + Event *EVM2EVMMultiOffRampExecutionStateChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampExecutionStateChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampExecutionStateChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampExecutionStateChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampExecutionStateChangedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampExecutionStateChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampExecutionStateChanged struct { + SourceChainSelector uint64 + SequenceNumber uint64 + MessageId [32]byte + State uint8 + ReturnData []byte + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterExecutionStateChanged(opts *bind.FilterOpts, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (*EVM2EVMMultiOffRampExecutionStateChangedIterator, error) { + + var sourceChainSelectorRule []interface{} + for _, sourceChainSelectorItem := range sourceChainSelector { + sourceChainSelectorRule = append(sourceChainSelectorRule, sourceChainSelectorItem) + } + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + var messageIdRule []interface{} + for _, messageIdItem := range messageId { + messageIdRule = append(messageIdRule, messageIdItem) + } + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "ExecutionStateChanged", sourceChainSelectorRule, sequenceNumberRule, messageIdRule) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampExecutionStateChangedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "ExecutionStateChanged", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampExecutionStateChanged, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) { + + var sourceChainSelectorRule []interface{} + for _, sourceChainSelectorItem := range sourceChainSelector { + sourceChainSelectorRule = append(sourceChainSelectorRule, sourceChainSelectorItem) + } + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + var messageIdRule []interface{} + for _, messageIdItem := range messageId { + messageIdRule = append(messageIdRule, messageIdItem) + } + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "ExecutionStateChanged", sourceChainSelectorRule, sequenceNumberRule, messageIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampExecutionStateChanged) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseExecutionStateChanged(log types.Log) (*EVM2EVMMultiOffRampExecutionStateChanged, error) { + event := new(EVM2EVMMultiOffRampExecutionStateChanged) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOffRampOwnershipTransferRequestedIterator struct { + Event *EVM2EVMMultiOffRampOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOffRampOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampOwnershipTransferRequestedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampOwnershipTransferRequested) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMMultiOffRampOwnershipTransferRequested, error) { + event := new(EVM2EVMMultiOffRampOwnershipTransferRequested) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOffRampOwnershipTransferredIterator struct { + Event *EVM2EVMMultiOffRampOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOffRampOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampOwnershipTransferredIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampOwnershipTransferred) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseOwnershipTransferred(log types.Log) (*EVM2EVMMultiOffRampOwnershipTransferred, error) { + event := new(EVM2EVMMultiOffRampOwnershipTransferred) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOffRampRootRemovedIterator struct { + Event *EVM2EVMMultiOffRampRootRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampRootRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampRootRemovedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampRootRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampRootRemoved struct { + Root [32]byte + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterRootRemoved(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampRootRemovedIterator, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampRootRemovedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "RootRemoved", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampRootRemoved) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampRootRemoved) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseRootRemoved(log types.Log) (*EVM2EVMMultiOffRampRootRemoved, error) { + event := new(EVM2EVMMultiOffRampRootRemoved) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator struct { + Event *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage struct { + SourceChainSelector uint64 + SequenceNumber uint64 + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterSkippedAlreadyExecutedMessage(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "SkippedAlreadyExecutedMessage") + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "SkippedAlreadyExecutedMessage", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchSkippedAlreadyExecutedMessage(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "SkippedAlreadyExecutedMessage") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "SkippedAlreadyExecutedMessage", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseSkippedAlreadyExecutedMessage(log types.Log) (*EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage, error) { + event := new(EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "SkippedAlreadyExecutedMessage", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOffRampSourceChainConfigSetIterator struct { + Event *EVM2EVMMultiOffRampSourceChainConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampSourceChainConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampSourceChainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampSourceChainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampSourceChainConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampSourceChainConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampSourceChainConfigSet struct { + SourceChainSelector uint64 + SourceConfig EVM2EVMMultiOffRampSourceChainConfig + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterSourceChainConfigSet(opts *bind.FilterOpts, sourceChainSelector []uint64) (*EVM2EVMMultiOffRampSourceChainConfigSetIterator, error) { + + var sourceChainSelectorRule []interface{} + for _, sourceChainSelectorItem := range sourceChainSelector { + sourceChainSelectorRule = append(sourceChainSelectorRule, sourceChainSelectorItem) + } + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "SourceChainConfigSet", sourceChainSelectorRule) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampSourceChainConfigSetIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "SourceChainConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchSourceChainConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampSourceChainConfigSet, sourceChainSelector []uint64) (event.Subscription, error) { + + var sourceChainSelectorRule []interface{} + for _, sourceChainSelectorItem := range sourceChainSelector { + sourceChainSelectorRule = append(sourceChainSelectorRule, sourceChainSelectorItem) + } + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "SourceChainConfigSet", sourceChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampSourceChainConfigSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "SourceChainConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseSourceChainConfigSet(log types.Log) (*EVM2EVMMultiOffRampSourceChainConfigSet, error) { + event := new(EVM2EVMMultiOffRampSourceChainConfigSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "SourceChainConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOffRampSourceChainSelectorAddedIterator struct { + Event *EVM2EVMMultiOffRampSourceChainSelectorAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampSourceChainSelectorAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampSourceChainSelectorAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampSourceChainSelectorAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampSourceChainSelectorAddedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampSourceChainSelectorAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampSourceChainSelectorAdded struct { + SourceChainSelector uint64 + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterSourceChainSelectorAdded(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampSourceChainSelectorAddedIterator, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "SourceChainSelectorAdded") + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampSourceChainSelectorAddedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "SourceChainSelectorAdded", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchSourceChainSelectorAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampSourceChainSelectorAdded) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "SourceChainSelectorAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampSourceChainSelectorAdded) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "SourceChainSelectorAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseSourceChainSelectorAdded(log types.Log) (*EVM2EVMMultiOffRampSourceChainSelectorAdded, error) { + event := new(EVM2EVMMultiOffRampSourceChainSelectorAdded) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "SourceChainSelectorAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOffRampStaticConfigSetIterator struct { + Event *EVM2EVMMultiOffRampStaticConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampStaticConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampStaticConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampStaticConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampStaticConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampStaticConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampStaticConfigSet struct { + StaticConfig EVM2EVMMultiOffRampStaticConfig + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterStaticConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampStaticConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "StaticConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampStaticConfigSetIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "StaticConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchStaticConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampStaticConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "StaticConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampStaticConfigSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "StaticConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseStaticConfigSet(log types.Log) (*EVM2EVMMultiOffRampStaticConfigSet, error) { + event := new(EVM2EVMMultiOffRampStaticConfigSet) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "StaticConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOffRampTransmittedIterator struct { + Event *EVM2EVMMultiOffRampTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampTransmittedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampTransmitted struct { + OcrPluginType uint8 + ConfigDigest [32]byte + SequenceNumber uint64 + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterTransmitted(opts *bind.FilterOpts, ocrPluginType []uint8) (*EVM2EVMMultiOffRampTransmittedIterator, error) { + + var ocrPluginTypeRule []interface{} + for _, ocrPluginTypeItem := range ocrPluginType { + ocrPluginTypeRule = append(ocrPluginTypeRule, ocrPluginTypeItem) + } + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "Transmitted", ocrPluginTypeRule) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampTransmittedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampTransmitted, ocrPluginType []uint8) (event.Subscription, error) { + + var ocrPluginTypeRule []interface{} + for _, ocrPluginTypeItem := range ocrPluginType { + ocrPluginTypeRule = append(ocrPluginTypeRule, ocrPluginTypeItem) + } + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "Transmitted", ocrPluginTypeRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampTransmitted) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseTransmitted(log types.Log) (*EVM2EVMMultiOffRampTransmitted, error) { + event := new(EVM2EVMMultiOffRampTransmitted) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _EVM2EVMMultiOffRamp.abi.Events["CommitReportAccepted"].ID: + return _EVM2EVMMultiOffRamp.ParseCommitReportAccepted(log) + case _EVM2EVMMultiOffRamp.abi.Events["ConfigSet"].ID: + return _EVM2EVMMultiOffRamp.ParseConfigSet(log) + case _EVM2EVMMultiOffRamp.abi.Events["DynamicConfigSet"].ID: + return _EVM2EVMMultiOffRamp.ParseDynamicConfigSet(log) + case _EVM2EVMMultiOffRamp.abi.Events["ExecutionStateChanged"].ID: + return _EVM2EVMMultiOffRamp.ParseExecutionStateChanged(log) + case _EVM2EVMMultiOffRamp.abi.Events["OwnershipTransferRequested"].ID: + return _EVM2EVMMultiOffRamp.ParseOwnershipTransferRequested(log) + case _EVM2EVMMultiOffRamp.abi.Events["OwnershipTransferred"].ID: + return _EVM2EVMMultiOffRamp.ParseOwnershipTransferred(log) + case _EVM2EVMMultiOffRamp.abi.Events["RootRemoved"].ID: + return _EVM2EVMMultiOffRamp.ParseRootRemoved(log) + case _EVM2EVMMultiOffRamp.abi.Events["SkippedAlreadyExecutedMessage"].ID: + return _EVM2EVMMultiOffRamp.ParseSkippedAlreadyExecutedMessage(log) + case _EVM2EVMMultiOffRamp.abi.Events["SourceChainConfigSet"].ID: + return _EVM2EVMMultiOffRamp.ParseSourceChainConfigSet(log) + case _EVM2EVMMultiOffRamp.abi.Events["SourceChainSelectorAdded"].ID: + return _EVM2EVMMultiOffRamp.ParseSourceChainSelectorAdded(log) + case _EVM2EVMMultiOffRamp.abi.Events["StaticConfigSet"].ID: + return _EVM2EVMMultiOffRamp.ParseStaticConfigSet(log) + case _EVM2EVMMultiOffRamp.abi.Events["Transmitted"].ID: + return _EVM2EVMMultiOffRamp.ParseTransmitted(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (EVM2EVMMultiOffRampCommitReportAccepted) Topic() common.Hash { + return common.HexToHash("0x3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d") +} + +func (EVM2EVMMultiOffRampConfigSet) Topic() common.Hash { + return common.HexToHash("0xab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547") +} + +func (EVM2EVMMultiOffRampDynamicConfigSet) Topic() common.Hash { + return common.HexToHash("0x0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c") +} + +func (EVM2EVMMultiOffRampExecutionStateChanged) Topic() common.Hash { + return common.HexToHash("0x8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df2") +} + +func (EVM2EVMMultiOffRampOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (EVM2EVMMultiOffRampOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (EVM2EVMMultiOffRampRootRemoved) Topic() common.Hash { + return common.HexToHash("0x202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12") +} + +func (EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) Topic() common.Hash { + return common.HexToHash("0x3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c") +} + +func (EVM2EVMMultiOffRampSourceChainConfigSet) Topic() common.Hash { + return common.HexToHash("0x4f49973170c548fddd4a48341b75e131818913f38f44d47af57e8735eee588ba") +} + +func (EVM2EVMMultiOffRampSourceChainSelectorAdded) Topic() common.Hash { + return common.HexToHash("0xf4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb9") +} + +func (EVM2EVMMultiOffRampStaticConfigSet) Topic() common.Hash { + return common.HexToHash("0x683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d8") +} + +func (EVM2EVMMultiOffRampTransmitted) Topic() common.Hash { + return common.HexToHash("0x198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0") +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRamp) Address() common.Address { + return _EVM2EVMMultiOffRamp.address +} + +type EVM2EVMMultiOffRampInterface interface { + CcipReceive(opts *bind.CallOpts, arg0 ClientAny2EVMMessage) error + + GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMMultiOffRampDynamicConfig, error) + + GetExecutionState(opts *bind.CallOpts, sourceChainSelector uint64, sequenceNumber uint64) (uint8, error) + + GetLatestPriceSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetMerkleRoot(opts *bind.CallOpts, sourceChainSelector uint64, root [32]byte) (*big.Int, error) + + GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) + + GetStaticConfig(opts *bind.CallOpts) (EVM2EVMMultiOffRampStaticConfig, error) + + IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) + + LatestConfigDetails(opts *bind.CallOpts, ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplySourceChainConfigUpdates(opts *bind.TransactOpts, sourceChainConfigUpdates []EVM2EVMMultiOffRampSourceChainConfigArgs) (*types.Transaction, error) + + Commit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + Execute(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte) (*types.Transaction, error) + + ExecuteSingleMessage(opts *bind.TransactOpts, message InternalAny2EVMRampMessage, offchainTokenData [][]byte) (*types.Transaction, error) + + ManuallyExecute(opts *bind.TransactOpts, reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) + + ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset []EVM2EVMMultiOffRampUnblessedRoot) (*types.Transaction, error) + + SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMMultiOffRampDynamicConfig) (*types.Transaction, error) + + SetOCR3Configs(opts *bind.TransactOpts, ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterCommitReportAccepted(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampCommitReportAcceptedIterator, error) + + WatchCommitReportAccepted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampCommitReportAccepted) (event.Subscription, error) + + ParseCommitReportAccepted(log types.Log) (*EVM2EVMMultiOffRampCommitReportAccepted, error) + + FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*EVM2EVMMultiOffRampConfigSet, error) + + FilterDynamicConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampDynamicConfigSetIterator, error) + + WatchDynamicConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampDynamicConfigSet) (event.Subscription, error) + + ParseDynamicConfigSet(log types.Log) (*EVM2EVMMultiOffRampDynamicConfigSet, error) + + FilterExecutionStateChanged(opts *bind.FilterOpts, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (*EVM2EVMMultiOffRampExecutionStateChangedIterator, error) + + WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampExecutionStateChanged, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) + + ParseExecutionStateChanged(log types.Log) (*EVM2EVMMultiOffRampExecutionStateChanged, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOffRampOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMMultiOffRampOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOffRampOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*EVM2EVMMultiOffRampOwnershipTransferred, error) + + FilterRootRemoved(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampRootRemovedIterator, error) + + WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampRootRemoved) (event.Subscription, error) + + ParseRootRemoved(log types.Log) (*EVM2EVMMultiOffRampRootRemoved, error) + + FilterSkippedAlreadyExecutedMessage(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator, error) + + WatchSkippedAlreadyExecutedMessage(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) (event.Subscription, error) + + ParseSkippedAlreadyExecutedMessage(log types.Log) (*EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage, error) + + FilterSourceChainConfigSet(opts *bind.FilterOpts, sourceChainSelector []uint64) (*EVM2EVMMultiOffRampSourceChainConfigSetIterator, error) + + WatchSourceChainConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampSourceChainConfigSet, sourceChainSelector []uint64) (event.Subscription, error) + + ParseSourceChainConfigSet(log types.Log) (*EVM2EVMMultiOffRampSourceChainConfigSet, error) + + FilterSourceChainSelectorAdded(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampSourceChainSelectorAddedIterator, error) + + WatchSourceChainSelectorAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampSourceChainSelectorAdded) (event.Subscription, error) + + ParseSourceChainSelectorAdded(log types.Log) (*EVM2EVMMultiOffRampSourceChainSelectorAdded, error) + + FilterStaticConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampStaticConfigSetIterator, error) + + WatchStaticConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampStaticConfigSet) (event.Subscription, error) + + ParseStaticConfigSet(log types.Log) (*EVM2EVMMultiOffRampStaticConfigSet, error) + + FilterTransmitted(opts *bind.FilterOpts, ocrPluginType []uint8) (*EVM2EVMMultiOffRampTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampTransmitted, ocrPluginType []uint8) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*EVM2EVMMultiOffRampTransmitted, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go new file mode 100644 index 0000000000..e8c07cb93d --- /dev/null +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go @@ -0,0 +1,1489 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package evm_2_evm_multi_onramp + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientEVM2AnyMessage struct { + Receiver []byte + Data []byte + TokenAmounts []ClientEVMTokenAmount + FeeToken common.Address + ExtraArgs []byte +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type EVM2EVMMultiOnRampDynamicConfig struct { + Router common.Address + PriceRegistry common.Address + MessageValidator common.Address + FeeAggregator common.Address +} + +type EVM2EVMMultiOnRampStaticConfig struct { + ChainSelector uint64 + RmnProxy common.Address + NonceManager common.Address + TokenAdminRegistry common.Address +} + +type InternalEVM2AnyRampMessage struct { + Header InternalRampMessageHeader + Sender common.Address + Data []byte + Receiver []byte + ExtraArgs []byte + FeeToken common.Address + FeeTokenAmount *big.Int + TokenAmounts []InternalRampTokenAmount +} + +type InternalRampMessageHeader struct { + MessageId [32]byte + SourceChainSelector uint64 + DestChainSelector uint64 + SequenceNumber uint64 + Nonce uint64 +} + +type InternalRampTokenAmount struct { + SourcePoolAddress []byte + DestTokenAddress []byte + ExtraData []byte + Amount *big.Int +} + +var EVM2EVMMultiOnRampMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b5060405162003161380380620031618339810160408190526200003591620003db565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf816200017a565b505082516001600160401b031615905080620000e6575060208201516001600160a01b0316155b80620000fd575060408201516001600160a01b0316155b8062000114575060608201516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b81516001600160401b031660805260208201516001600160a01b0390811660a0526040830151811660c05260608301511660e052620001728162000225565b5050620004d1565b336001600160a01b03821603620001d45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60208101516001600160a01b031615806200024b575060608101516001600160a01b0316155b156200026a576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b0393841617909155602080840180516003805485169186169190911790556040808601805160048054871691881691909117905560608088018051600580549098169089161790965582516080808201855280516001600160401b031680835260a080518b16848a0190815260c080518d16868a0190815260e080518f169789019788528a5195865292518e169b85019b909b5299518c169783019790975292518a169381019390935289518916908301529351871693810193909352518516928201929092529151909216918101919091527f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32906101000160405180910390a150565b604051608081016001600160401b0381118282101715620003b857634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b0381168114620003d657600080fd5b919050565b600080828403610100811215620003f157600080fd5b60808112156200040057600080fd5b6200040a62000387565b84516001600160401b03811681146200042257600080fd5b81526200043260208601620003be565b60208201526200044560408601620003be565b60408201526200045860608601620003be565b606082015292506080607f19820112156200047257600080fd5b506200047d62000387565b6200048b60808501620003be565b81526200049b60a08501620003be565b6020820152620004ae60c08501620003be565b6040820152620004c160e08501620003be565b6060820152809150509250929050565b60805160a05160c05160e051612c176200054a600039600081816101c00152818161081b015261147901526000818161018401528181610d3801526114520152600081816101480152818161044e015261142801526000818161011801528181610c55015281816110ee01526113fb0152612c176000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806379ba50971161008c578063a6f3ab6c11610066578063a6f3ab6c14610391578063df0aa9e9146103a4578063f2fde38b146103b7578063fbca3b74146103ca57600080fd5b806379ba50971461033f5780638da5cb5b146103475780639041be3d1461036557600080fd5b80633a019940116100bd5780633a0199401461027d57806348a98aa4146102875780637437ff9f146102bf57600080fd5b806306285c69146100e4578063181f5a771461021357806320487ded1461025c575b600080fd5b6101fd60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161020a9190611cf8565b60405180910390f35b61024f6040518060400160405280601c81526020017f45564d3245564d4d756c74694f6e52616d7020312e362e302d6465760000000081525081565b60405161020a9190611dbd565b61026f61026a366004611dfe565b6103ea565b60405190815260200161020a565b6102856105a3565b005b61029a610295366004611e70565b6107d3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161020a565b610332604080516080810182526000808252602082018190529181018290526060810191909152506040805160808101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454811692820192909252600554909116606082015290565b60405161020a9190611ea9565b610285610888565b60005473ffffffffffffffffffffffffffffffffffffffff1661029a565b610378610373366004611ef2565b610985565b60405167ffffffffffffffff909116815260200161020a565b61028561039f366004611fc6565b6109ae565b61026f6103b236600461204b565b6109c2565b6102856103c53660046120b7565b6111a2565b6103dd6103d8366004611ef2565b6111b3565b60405161020a91906120d4565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa158015610495573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b9919061213e565b15610501576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6003546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd90610559908690869060040161226d565b602060405180830381865afa158015610576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a91906123b6565b90505b92915050565b600354604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610612573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261065891908101906123cf565b60055490915073ffffffffffffffffffffffffffffffffffffffff1660005b82518110156107ce57600083828151811061069457610694612481565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561070f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073391906123b6565b905080156107c45761075c73ffffffffffffffffffffffffffffffffffffffff831685836111e7565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e836040516107bb91815260200190565b60405180910390a35b5050600101610677565b505050565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610864573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a91906124b0565b60015473ffffffffffffffffffffffffffffffffffffffff163314610909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016104f8565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff808216600090815260066020526040812054909161059d911660016124fc565b6109b6611274565b6109bf816112f7565b50565b600073ffffffffffffffffffffffffffffffffffffffff8216610a11576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025473ffffffffffffffffffffffffffffffffffffffff163314610a62576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60045473ffffffffffffffffffffffffffffffffffffffff168015610b08576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610ad5908990899060040161226d565b600060405180830381600087803b158015610aef57600080fd5b505af1158015610b03573d6000803e3d6000fd5b505050505b6003546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a610b3e60808c0160608d016120b7565b8a610b4c60808e018e612524565b6040518663ffffffff1660e01b8152600401610b6c959493929190612589565b600060405180830381865afa158015610b89573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610bcf9190810190612651565b91945092509050610be66080890160608a016120b7565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f84604051610c2d91815260200190565b60405180910390a2604080516101a0810182526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528d8116610140850181905283526006602052938220805492948493610160850192918791610caa91166126a8565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200186610daa576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015610d81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da591906126cf565b610dad565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a8060200190610deb9190612524565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610e2f8b80612524565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610e7660808c018c612524565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610ec060808c0160608d016120b7565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190610ef191906126ec565b905067ffffffffffffffff811115610f0b57610f0b611f0f565b604051908082528060200260200182016040528015610f6757816020015b610f546040518060800160405280606081526020016060815260200160608152602001600081525090565b815260200190600190039081610f295790505b509052905060005b610f7c60408b018b6126ec565b905081101561102b57611002610f9560408c018c6126ec565b83818110610fa557610fa5612481565b905060400201803603810190610fbb9190612754565b8c610fc68d80612524565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92506114dc915050565b8260e00151828151811061101857611018612481565b6020908102919091010152600101610f6f565b5060035460e082015173ffffffffffffffffffffffffffffffffffffffff9091169063cc88924c908c9061106260408e018e6126ec565b6040518563ffffffff1660e01b81526004016110819493929190612850565b60006040518083038186803b15801561109957600080fd5b505afa1580156110ad573d6000803e3d6000fd5b505050506080808201839052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908c166060820152309181019190915261114a90829060a001604051602081830303815290604052805190602001206117e6565b81515260405167ffffffffffffffff8b16907f0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab2990611189908490612886565b60405180910390a251519450505050505b949350505050565b6111aa611274565b6109bf816118e6565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526107ce9084906119db565b60005473ffffffffffffffffffffffffffffffffffffffff1633146112f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104f8565b565b602081015173ffffffffffffffffffffffffffffffffffffffff1615806113365750606081015173ffffffffffffffffffffffffffffffffffffffff16155b1561136d576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480548516918616919091179055606080860151600580549095169086161790935580516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008516928101929092527f00000000000000000000000000000000000000000000000000000000000000008416828201527f00000000000000000000000000000000000000000000000000000000000000009093169181019190915290517f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32916114d19184906129d4565b60405180910390a150565b6115076040518060800160405280606081526020016060815260200160608152602001600081525090565b8460200151600003611545576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006115558587600001516107d3565b905073ffffffffffffffffffffffffffffffffffffffff8116158061162557506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156115ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611623919061213e565b155b156116775785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016104f8565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b81526004016117169190612a73565b6000604051808303816000875af1158015611735573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261177b9190810190612ae9565b604080516080810190915273ffffffffffffffffffffffffffffffffffffffff841660a08201529091508060c0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c0015160405160200161182896959493929190612b7a565b604051602081830303815290604052805190602001208560400151805190602001208660e0015160405160200161185f9190612bdb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611965576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104f8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611a3d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611ae79092919063ffffffff16565b8051909150156107ce5780806020019051810190611a5b919061213e565b6107ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016104f8565b6060611af68484600085611b00565b90505b9392505050565b606082471015611b92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016104f8565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbb9190612bee565b60006040518083038185875af1925050503d8060008114611bf8576040519150601f19603f3d011682016040523d82523d6000602084013e611bfd565b606091505b5091509150611c0e87838387611c19565b979650505050505050565b60608315611caf578251600003611ca85773ffffffffffffffffffffffffffffffffffffffff85163b611ca8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104f8565b508161119a565b61119a8383815115611cc45781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190611dbd565b6080810161059d828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b83811015611d6a578181015183820152602001611d52565b50506000910152565b60008151808452611d8b816020860160208601611d4f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061059a6020830184611d73565b67ffffffffffffffff811681146109bf57600080fd5b600060a08284031215611df857600080fd5b50919050565b60008060408385031215611e1157600080fd5b8235611e1c81611dd0565b9150602083013567ffffffffffffffff811115611e3857600080fd5b611e4485828601611de6565b9150509250929050565b73ffffffffffffffffffffffffffffffffffffffff811681146109bf57600080fd5b60008060408385031215611e8357600080fd5b8235611e8e81611dd0565b91506020830135611e9e81611e4e565b809150509250929050565b6080810161059d8284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260408083015182169084015260609182015116910152565b600060208284031215611f0457600080fd5b8135611af981611dd0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611f6157611f61611f0f565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611fae57611fae611f0f565b604052919050565b8035611fc181611e4e565b919050565b600060808284031215611fd857600080fd5b6040516080810181811067ffffffffffffffff82111715611ffb57611ffb611f0f565b604052823561200981611e4e565b8152602083013561201981611e4e565b6020820152604083013561202c81611e4e565b6040820152606083013561203f81611e4e565b60608201529392505050565b6000806000806080858703121561206157600080fd5b843561206c81611dd0565b9350602085013567ffffffffffffffff81111561208857600080fd5b61209487828801611de6565b9350506040850135915060608501356120ac81611e4e565b939692955090935050565b6000602082840312156120c957600080fd5b8135611af981611e4e565b6020808252825182820181905260009190848201906040850190845b8181101561212257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016120f0565b50909695505050505050565b80518015158114611fc157600080fd5b60006020828403121561215057600080fd5b61059a8261212e565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261218e57600080fd5b830160208101925035905067ffffffffffffffff8111156121ae57600080fd5b8036038213156121bd57600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b8581101561226257813561223081611e4e565b73ffffffffffffffffffffffffffffffffffffffff16875281830135838801526040968701969091019060010161221d565b509495945050505050565b600067ffffffffffffffff80851683526040602084015261228e8485612159565b60a060408601526122a360e0860182846121c4565b9150506122b36020860186612159565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808785030160608801526122e98483856121c4565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe188360301831261232257600080fd5b6020928801928301923591508482111561233b57600080fd5b8160061b360383131561234d57600080fd5b8087850301608088015261236284838561220d565b945061237060608901611fb6565b73ffffffffffffffffffffffffffffffffffffffff811660a0890152935061239b6080890189612159565b94509250808786030160c08801525050611c0e8383836121c4565b6000602082840312156123c857600080fd5b5051919050565b600060208083850312156123e257600080fd5b825167ffffffffffffffff808211156123fa57600080fd5b818501915085601f83011261240e57600080fd5b81518181111561242057612420611f0f565b8060051b9150612431848301611f67565b818152918301840191848101908884111561244b57600080fd5b938501935b83851015612475578451925061246583611e4e565b8282529385019390850190612450565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156124c257600080fd5b8151611af981611e4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561251d5761251d6124cd565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261255957600080fd5b83018035915067ffffffffffffffff82111561257457600080fd5b6020019150368190038213156121bd57600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152608060608201526000611c0e6080830184866121c4565b600082601f8301126125e057600080fd5b815167ffffffffffffffff8111156125fa576125fa611f0f565b61262b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611f67565b81815284602083860101111561264057600080fd5b61119a826020830160208701611d4f565b60008060006060848603121561266657600080fd5b835192506126766020850161212e565b9150604084015167ffffffffffffffff81111561269257600080fd5b61269e868287016125cf565b9150509250925092565b600067ffffffffffffffff8083168181036126c5576126c56124cd565b6001019392505050565b6000602082840312156126e157600080fd5b8151611af981611dd0565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261272157600080fd5b83018035915067ffffffffffffffff82111561273c57600080fd5b6020019150600681901b36038213156121bd57600080fd5b60006040828403121561276657600080fd5b61276e611f3e565b823561277981611e4e565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b84811015612843577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189528151608081518186526127ef82870182611d73565b91505085820151858203878701526128078282611d73565b915050604080830151868303828801526128218382611d73565b60609485015197909401969096525050988401989250908301906001016127ab565b5090979650505050505050565b67ffffffffffffffff85168152606060208201526000612873606083018661278e565b8281036040840152611c0e81858761220d565b602081526128d760208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b6000602083015161290060c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e085015261291d6101a0850183611d73565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808685030161010087015261295a8483611d73565b93506080870151915080868503016101208701526129788483611d73565b935060a087015191506129a461014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e08701519150808685030183870152506129ca838261278e565b9695505050505050565b6101008101612a2c828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a08401526040840151811660c084015260608401511660e0830152611af9565b602081526000825160a06020840152612a8f60c0840182611d73565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600060208284031215612afb57600080fd5b815167ffffffffffffffff80821115612b1357600080fd5b9083019060408286031215612b2757600080fd5b612b2f611f3e565b825182811115612b3e57600080fd5b612b4a878286016125cf565b825250602083015182811115612b5f57600080fd5b612b6b878286016125cf565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c06020840152612baa60c0840189611d73565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b60208152600061059a602083018461278e565b60008251612c00818460208701611d4f565b919091019291505056fea164736f6c6343000818000a", +} + +var EVM2EVMMultiOnRampABI = EVM2EVMMultiOnRampMetaData.ABI + +var EVM2EVMMultiOnRampBin = EVM2EVMMultiOnRampMetaData.Bin + +func DeployEVM2EVMMultiOnRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMMultiOnRampStaticConfig, dynamicConfig EVM2EVMMultiOnRampDynamicConfig) (common.Address, *types.Transaction, *EVM2EVMMultiOnRamp, error) { + parsed, err := EVM2EVMMultiOnRampMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMMultiOnRampBin), backend, staticConfig, dynamicConfig) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EVM2EVMMultiOnRamp{address: address, abi: *parsed, EVM2EVMMultiOnRampCaller: EVM2EVMMultiOnRampCaller{contract: contract}, EVM2EVMMultiOnRampTransactor: EVM2EVMMultiOnRampTransactor{contract: contract}, EVM2EVMMultiOnRampFilterer: EVM2EVMMultiOnRampFilterer{contract: contract}}, nil +} + +type EVM2EVMMultiOnRamp struct { + address common.Address + abi abi.ABI + EVM2EVMMultiOnRampCaller + EVM2EVMMultiOnRampTransactor + EVM2EVMMultiOnRampFilterer +} + +type EVM2EVMMultiOnRampCaller struct { + contract *bind.BoundContract +} + +type EVM2EVMMultiOnRampTransactor struct { + contract *bind.BoundContract +} + +type EVM2EVMMultiOnRampFilterer struct { + contract *bind.BoundContract +} + +type EVM2EVMMultiOnRampSession struct { + Contract *EVM2EVMMultiOnRamp + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type EVM2EVMMultiOnRampCallerSession struct { + Contract *EVM2EVMMultiOnRampCaller + CallOpts bind.CallOpts +} + +type EVM2EVMMultiOnRampTransactorSession struct { + Contract *EVM2EVMMultiOnRampTransactor + TransactOpts bind.TransactOpts +} + +type EVM2EVMMultiOnRampRaw struct { + Contract *EVM2EVMMultiOnRamp +} + +type EVM2EVMMultiOnRampCallerRaw struct { + Contract *EVM2EVMMultiOnRampCaller +} + +type EVM2EVMMultiOnRampTransactorRaw struct { + Contract *EVM2EVMMultiOnRampTransactor +} + +func NewEVM2EVMMultiOnRamp(address common.Address, backend bind.ContractBackend) (*EVM2EVMMultiOnRamp, error) { + abi, err := abi.JSON(strings.NewReader(EVM2EVMMultiOnRampABI)) + if err != nil { + return nil, err + } + contract, err := bindEVM2EVMMultiOnRamp(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOnRamp{address: address, abi: abi, EVM2EVMMultiOnRampCaller: EVM2EVMMultiOnRampCaller{contract: contract}, EVM2EVMMultiOnRampTransactor: EVM2EVMMultiOnRampTransactor{contract: contract}, EVM2EVMMultiOnRampFilterer: EVM2EVMMultiOnRampFilterer{contract: contract}}, nil +} + +func NewEVM2EVMMultiOnRampCaller(address common.Address, caller bind.ContractCaller) (*EVM2EVMMultiOnRampCaller, error) { + contract, err := bindEVM2EVMMultiOnRamp(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOnRampCaller{contract: contract}, nil +} + +func NewEVM2EVMMultiOnRampTransactor(address common.Address, transactor bind.ContractTransactor) (*EVM2EVMMultiOnRampTransactor, error) { + contract, err := bindEVM2EVMMultiOnRamp(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOnRampTransactor{contract: contract}, nil +} + +func NewEVM2EVMMultiOnRampFilterer(address common.Address, filterer bind.ContractFilterer) (*EVM2EVMMultiOnRampFilterer, error) { + contract, err := bindEVM2EVMMultiOnRamp(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOnRampFilterer{contract: contract}, nil +} + +func bindEVM2EVMMultiOnRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EVM2EVMMultiOnRampMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMMultiOnRamp.Contract.EVM2EVMMultiOnRampCaller.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.EVM2EVMMultiOnRampTransactor.contract.Transfer(opts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.EVM2EVMMultiOnRampTransactor.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMMultiOnRamp.Contract.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.contract.Transfer(opts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMMultiOnRampDynamicConfig, error) { + var out []interface{} + err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(EVM2EVMMultiOnRampDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOnRampDynamicConfig)).(*EVM2EVMMultiOnRampDynamicConfig) + + return out0, err + +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetDynamicConfig() (EVM2EVMMultiOnRampDynamicConfig, error) { + return _EVM2EVMMultiOnRamp.Contract.GetDynamicConfig(&_EVM2EVMMultiOnRamp.CallOpts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetDynamicConfig() (EVM2EVMMultiOnRampDynamicConfig, error) { + return _EVM2EVMMultiOnRamp.Contract.GetDynamicConfig(&_EVM2EVMMultiOnRamp.CallOpts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts, destChainSelector uint64) (uint64, error) { + var out []interface{} + err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getExpectedNextSequenceNumber", destChainSelector) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetExpectedNextSequenceNumber(destChainSelector uint64) (uint64, error) { + return _EVM2EVMMultiOnRamp.Contract.GetExpectedNextSequenceNumber(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetExpectedNextSequenceNumber(destChainSelector uint64) (uint64, error) { + return _EVM2EVMMultiOnRamp.Contract.GetExpectedNextSequenceNumber(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getFee", destChainSelector, message) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _EVM2EVMMultiOnRamp.Contract.GetFee(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector, message) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _EVM2EVMMultiOnRamp.Contract.GetFee(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector, message) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetPoolBySourceToken(opts *bind.CallOpts, arg0 uint64, sourceToken common.Address) (common.Address, error) { + var out []interface{} + err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getPoolBySourceToken", arg0, sourceToken) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetPoolBySourceToken(arg0 uint64, sourceToken common.Address) (common.Address, error) { + return _EVM2EVMMultiOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMMultiOnRamp.CallOpts, arg0, sourceToken) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetPoolBySourceToken(arg0 uint64, sourceToken common.Address) (common.Address, error) { + return _EVM2EVMMultiOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMMultiOnRamp.CallOpts, arg0, sourceToken) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMMultiOnRampStaticConfig, error) { + var out []interface{} + err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(EVM2EVMMultiOnRampStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOnRampStaticConfig)).(*EVM2EVMMultiOnRampStaticConfig) + + return out0, err + +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetStaticConfig() (EVM2EVMMultiOnRampStaticConfig, error) { + return _EVM2EVMMultiOnRamp.Contract.GetStaticConfig(&_EVM2EVMMultiOnRamp.CallOpts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetStaticConfig() (EVM2EVMMultiOnRampStaticConfig, error) { + return _EVM2EVMMultiOnRamp.Contract.GetStaticConfig(&_EVM2EVMMultiOnRamp.CallOpts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetSupportedTokens(opts *bind.CallOpts, arg0 uint64) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getSupportedTokens", arg0) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetSupportedTokens(arg0 uint64) ([]common.Address, error) { + return _EVM2EVMMultiOnRamp.Contract.GetSupportedTokens(&_EVM2EVMMultiOnRamp.CallOpts, arg0) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetSupportedTokens(arg0 uint64) ([]common.Address, error) { + return _EVM2EVMMultiOnRamp.Contract.GetSupportedTokens(&_EVM2EVMMultiOnRamp.CallOpts, arg0) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) Owner() (common.Address, error) { + return _EVM2EVMMultiOnRamp.Contract.Owner(&_EVM2EVMMultiOnRamp.CallOpts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) Owner() (common.Address, error) { + return _EVM2EVMMultiOnRamp.Contract.Owner(&_EVM2EVMMultiOnRamp.CallOpts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) TypeAndVersion() (string, error) { + return _EVM2EVMMultiOnRamp.Contract.TypeAndVersion(&_EVM2EVMMultiOnRamp.CallOpts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) TypeAndVersion() (string, error) { + return _EVM2EVMMultiOnRamp.Contract.TypeAndVersion(&_EVM2EVMMultiOnRamp.CallOpts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.contract.Transact(opts, "acceptOwnership") +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.AcceptOwnership(&_EVM2EVMMultiOnRamp.TransactOpts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.AcceptOwnership(&_EVM2EVMMultiOnRamp.TransactOpts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.contract.Transact(opts, "forwardFromRouter", destChainSelector, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) ForwardFromRouter(destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.ForwardFromRouter(&_EVM2EVMMultiOnRamp.TransactOpts, destChainSelector, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) ForwardFromRouter(destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.ForwardFromRouter(&_EVM2EVMMultiOnRamp.TransactOpts, destChainSelector, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMMultiOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.contract.Transact(opts, "setDynamicConfig", dynamicConfig) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) SetDynamicConfig(dynamicConfig EVM2EVMMultiOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.SetDynamicConfig(&_EVM2EVMMultiOnRamp.TransactOpts, dynamicConfig) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) SetDynamicConfig(dynamicConfig EVM2EVMMultiOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.SetDynamicConfig(&_EVM2EVMMultiOnRamp.TransactOpts, dynamicConfig) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.contract.Transact(opts, "transferOwnership", to) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.TransferOwnership(&_EVM2EVMMultiOnRamp.TransactOpts, to) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.TransferOwnership(&_EVM2EVMMultiOnRamp.TransactOpts, to) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) WithdrawFeeTokens(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.contract.Transact(opts, "withdrawFeeTokens") +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) WithdrawFeeTokens() (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.WithdrawFeeTokens(&_EVM2EVMMultiOnRamp.TransactOpts) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) WithdrawFeeTokens() (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.WithdrawFeeTokens(&_EVM2EVMMultiOnRamp.TransactOpts) +} + +type EVM2EVMMultiOnRampAdminSetIterator struct { + Event *EVM2EVMMultiOnRampAdminSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOnRampAdminSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOnRampAdminSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOnRampAdminSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOnRampAdminSet struct { + NewAdmin common.Address + Raw types.Log +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMMultiOnRampAdminSetIterator, error) { + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return &EVM2EVMMultiOnRampAdminSetIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "AdminSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampAdminSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOnRampAdminSet) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseAdminSet(log types.Log) (*EVM2EVMMultiOnRampAdminSet, error) { + event := new(EVM2EVMMultiOnRampAdminSet) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOnRampCCIPSendRequestedIterator struct { + Event *EVM2EVMMultiOnRampCCIPSendRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOnRampCCIPSendRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampCCIPSendRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampCCIPSendRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOnRampCCIPSendRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOnRampCCIPSendRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOnRampCCIPSendRequested struct { + DestChainSelector uint64 + Message InternalEVM2AnyRampMessage + Raw types.Log +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*EVM2EVMMultiOnRampCCIPSendRequestedIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "CCIPSendRequested", destChainSelectorRule) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOnRampCCIPSendRequestedIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "CCIPSendRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "CCIPSendRequested", destChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOnRampCCIPSendRequested) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseCCIPSendRequested(log types.Log) (*EVM2EVMMultiOnRampCCIPSendRequested, error) { + event := new(EVM2EVMMultiOnRampCCIPSendRequested) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOnRampConfigSetIterator struct { + Event *EVM2EVMMultiOnRampConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOnRampConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOnRampConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOnRampConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOnRampConfigSet struct { + StaticConfig EVM2EVMMultiOnRampStaticConfig + DynamicConfig EVM2EVMMultiOnRampDynamicConfig + Raw types.Log +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOnRampConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMMultiOnRampConfigSetIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOnRampConfigSet) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseConfigSet(log types.Log) (*EVM2EVMMultiOnRampConfigSet, error) { + event := new(EVM2EVMMultiOnRampConfigSet) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOnRampFeePaidIterator struct { + Event *EVM2EVMMultiOnRampFeePaid + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOnRampFeePaidIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampFeePaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampFeePaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOnRampFeePaidIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOnRampFeePaidIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOnRampFeePaid struct { + FeeToken common.Address + FeeValueJuels *big.Int + Raw types.Log +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterFeePaid(opts *bind.FilterOpts, feeToken []common.Address) (*EVM2EVMMultiOnRampFeePaidIterator, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "FeePaid", feeTokenRule) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOnRampFeePaidIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "FeePaid", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchFeePaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampFeePaid, feeToken []common.Address) (event.Subscription, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "FeePaid", feeTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOnRampFeePaid) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "FeePaid", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseFeePaid(log types.Log) (*EVM2EVMMultiOnRampFeePaid, error) { + event := new(EVM2EVMMultiOnRampFeePaid) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "FeePaid", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOnRampFeeTokenWithdrawnIterator struct { + Event *EVM2EVMMultiOnRampFeeTokenWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOnRampFeeTokenWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampFeeTokenWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampFeeTokenWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOnRampFeeTokenWithdrawnIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOnRampFeeTokenWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOnRampFeeTokenWithdrawn struct { + FeeAggregator common.Address + FeeToken common.Address + Amount *big.Int + Raw types.Log +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterFeeTokenWithdrawn(opts *bind.FilterOpts, feeAggregator []common.Address, feeToken []common.Address) (*EVM2EVMMultiOnRampFeeTokenWithdrawnIterator, error) { + + var feeAggregatorRule []interface{} + for _, feeAggregatorItem := range feeAggregator { + feeAggregatorRule = append(feeAggregatorRule, feeAggregatorItem) + } + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "FeeTokenWithdrawn", feeAggregatorRule, feeTokenRule) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOnRampFeeTokenWithdrawnIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "FeeTokenWithdrawn", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchFeeTokenWithdrawn(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampFeeTokenWithdrawn, feeAggregator []common.Address, feeToken []common.Address) (event.Subscription, error) { + + var feeAggregatorRule []interface{} + for _, feeAggregatorItem := range feeAggregator { + feeAggregatorRule = append(feeAggregatorRule, feeAggregatorItem) + } + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "FeeTokenWithdrawn", feeAggregatorRule, feeTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOnRampFeeTokenWithdrawn) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "FeeTokenWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseFeeTokenWithdrawn(log types.Log) (*EVM2EVMMultiOnRampFeeTokenWithdrawn, error) { + event := new(EVM2EVMMultiOnRampFeeTokenWithdrawn) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "FeeTokenWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOnRampOwnershipTransferRequestedIterator struct { + Event *EVM2EVMMultiOnRampOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOnRampOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOnRampOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOnRampOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOnRampOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOnRampOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOnRampOwnershipTransferRequestedIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOnRampOwnershipTransferRequested) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMMultiOnRampOwnershipTransferRequested, error) { + event := new(EVM2EVMMultiOnRampOwnershipTransferRequested) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMMultiOnRampOwnershipTransferredIterator struct { + Event *EVM2EVMMultiOnRampOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOnRampOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOnRampOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOnRampOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOnRampOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOnRampOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOnRampOwnershipTransferredIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOnRampOwnershipTransferred) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseOwnershipTransferred(log types.Log) (*EVM2EVMMultiOnRampOwnershipTransferred, error) { + event := new(EVM2EVMMultiOnRampOwnershipTransferred) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _EVM2EVMMultiOnRamp.abi.Events["AdminSet"].ID: + return _EVM2EVMMultiOnRamp.ParseAdminSet(log) + case _EVM2EVMMultiOnRamp.abi.Events["CCIPSendRequested"].ID: + return _EVM2EVMMultiOnRamp.ParseCCIPSendRequested(log) + case _EVM2EVMMultiOnRamp.abi.Events["ConfigSet"].ID: + return _EVM2EVMMultiOnRamp.ParseConfigSet(log) + case _EVM2EVMMultiOnRamp.abi.Events["FeePaid"].ID: + return _EVM2EVMMultiOnRamp.ParseFeePaid(log) + case _EVM2EVMMultiOnRamp.abi.Events["FeeTokenWithdrawn"].ID: + return _EVM2EVMMultiOnRamp.ParseFeeTokenWithdrawn(log) + case _EVM2EVMMultiOnRamp.abi.Events["OwnershipTransferRequested"].ID: + return _EVM2EVMMultiOnRamp.ParseOwnershipTransferRequested(log) + case _EVM2EVMMultiOnRamp.abi.Events["OwnershipTransferred"].ID: + return _EVM2EVMMultiOnRamp.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (EVM2EVMMultiOnRampAdminSet) Topic() common.Hash { + return common.HexToHash("0x8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c") +} + +func (EVM2EVMMultiOnRampCCIPSendRequested) Topic() common.Hash { + return common.HexToHash("0x0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab29") +} + +func (EVM2EVMMultiOnRampConfigSet) Topic() common.Hash { + return common.HexToHash("0x23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32") +} + +func (EVM2EVMMultiOnRampFeePaid) Topic() common.Hash { + return common.HexToHash("0x075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f") +} + +func (EVM2EVMMultiOnRampFeeTokenWithdrawn) Topic() common.Hash { + return common.HexToHash("0x508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e") +} + +func (EVM2EVMMultiOnRampOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (EVM2EVMMultiOnRampOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRamp) Address() common.Address { + return _EVM2EVMMultiOnRamp.address +} + +type EVM2EVMMultiOnRampInterface interface { + GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMMultiOnRampDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts, destChainSelector uint64) (uint64, error) + + GetFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) + + GetPoolBySourceToken(opts *bind.CallOpts, arg0 uint64, sourceToken common.Address) (common.Address, error) + + GetStaticConfig(opts *bind.CallOpts) (EVM2EVMMultiOnRampStaticConfig, error) + + GetSupportedTokens(opts *bind.CallOpts, arg0 uint64) ([]common.Address, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) + + SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMMultiOnRampDynamicConfig) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + WithdrawFeeTokens(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMMultiOnRampAdminSetIterator, error) + + WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampAdminSet) (event.Subscription, error) + + ParseAdminSet(log types.Log) (*EVM2EVMMultiOnRampAdminSet, error) + + FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*EVM2EVMMultiOnRampCCIPSendRequestedIterator, error) + + WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) + + ParseCCIPSendRequested(log types.Log) (*EVM2EVMMultiOnRampCCIPSendRequested, error) + + FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOnRampConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*EVM2EVMMultiOnRampConfigSet, error) + + FilterFeePaid(opts *bind.FilterOpts, feeToken []common.Address) (*EVM2EVMMultiOnRampFeePaidIterator, error) + + WatchFeePaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampFeePaid, feeToken []common.Address) (event.Subscription, error) + + ParseFeePaid(log types.Log) (*EVM2EVMMultiOnRampFeePaid, error) + + FilterFeeTokenWithdrawn(opts *bind.FilterOpts, feeAggregator []common.Address, feeToken []common.Address) (*EVM2EVMMultiOnRampFeeTokenWithdrawnIterator, error) + + WatchFeeTokenWithdrawn(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampFeeTokenWithdrawn, feeAggregator []common.Address, feeToken []common.Address) (event.Subscription, error) + + ParseFeeTokenWithdrawn(log types.Log) (*EVM2EVMMultiOnRampFeeTokenWithdrawn, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOnRampOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMMultiOnRampOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOnRampOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*EVM2EVMMultiOnRampOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go new file mode 100644 index 0000000000..e4f47eb0a5 --- /dev/null +++ b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go @@ -0,0 +1,2673 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package evm_2_evm_offramp + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientAny2EVMMessage struct { + MessageId [32]byte + SourceChainSelector uint64 + Sender []byte + Data []byte + DestTokenAmounts []ClientEVMTokenAmount +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type EVM2EVMOffRampDynamicConfig struct { + PermissionLessExecutionThresholdSeconds uint32 + MaxDataBytes uint32 + MaxNumberOfTokensPerMsg uint16 + Router common.Address + PriceRegistry common.Address + MaxPoolReleaseOrMintGas uint32 + MaxTokenTransferGas uint32 +} + +type EVM2EVMOffRampRateLimitToken struct { + SourceToken common.Address + DestToken common.Address +} + +type EVM2EVMOffRampStaticConfig struct { + CommitStore common.Address + ChainSelector uint64 + SourceChainSelector uint64 + OnRamp common.Address + PrevOffRamp common.Address + RmnProxy common.Address + TokenAdminRegistry common.Address +} + +type InternalEVM2EVMMessage struct { + SourceChainSelector uint64 + Sender common.Address + Receiver common.Address + SequenceNumber uint64 + GasLimit *big.Int + Strict bool + Nonce uint64 + FeeToken common.Address + FeeTokenAmount *big.Int + Data []byte + TokenAmounts []ClientEVMTokenAmount + SourceTokenData [][]byte + MessageId [32]byte +} + +type InternalExecutionReport struct { + Messages []InternalEVM2EVMMessage + OffchainTokenData [][][]byte + Proofs [][32]byte + ProofFlagBits *big.Int +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +var EVM2EVMOffRampMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101a06040523480156200001257600080fd5b5060405162006213380380620062138339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615b4a620006c9600039600081816102ec01528181611b1201526133890152600081816102bd01528181611aeb0152611d9d01526000818161028e01528181610ed201528181610f3701528181611ac40152818161234501526123af01526000611f3c01526000818161025f0152611a9a0152600081816101ff0152611a4801526000818161022f01528181611a7201528181611d5a01528181612dc101526134980152600081816101d001528181611a1a015261201c015260008181611cb40152611d000152615b4a6000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806381ff7048116100d8578063afcb95d71161008c578063f077b59211610066578063f077b59214610646578063f2fde38b1461065c578063f52121a51461066f57600080fd5b8063afcb95d714610600578063b1dc65a414610620578063c92b28321461063357600080fd5b8063856c8247116100bd578063856c8247146105b0578063873504d7146105dc5780638da5cb5b146105ef57600080fd5b806381ff70481461057257806385572ffb146105a257600080fd5b8063599f64311161013a578063740f415011610114578063740f4150146104615780637437ff9f1461047457806379ba50971461056a57600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60405161032991906141e7565b60405180910390f35b61034561034036600461427d565b610682565b60405161032991906142dd565b61038e6040518060400160405280601881526020017f45564d3245564d4f666652616d7020312e352e302d646576000000000000000081525081565b604051610329919061433b565b6103ae6103a93660046145aa565b6106fd565b005b6103b8610af1565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610ba6565b60405161032991906146bc565b6103ae61045c3660046146cf565b610c08565b6103ae61046f366004614b2f565b610cd1565b61055d6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152506040805160e081018252600a5463ffffffff808216835264010000000082048116602084015261ffff68010000000000000000830416938301939093526001600160a01b036a010000000000000000000090910481166060830152600b549081166080830152740100000000000000000000000000000000000000008104831660a08301527801000000000000000000000000000000000000000000000000900490911660c082015290565b6040516103299190614bea565b6103ae610dc3565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae610182366004614c58565b6105c36105be3660046146cf565b610ea6565b60405167ffffffffffffffff9091168152602001610329565b6103ae6105ea366004614d24565b610fa9565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae61062e366004614dcd565b611177565b6103ae610641366004614ed2565b611382565b61064e6113ed565b604051610329929190614f22565b6103ae61066a3660046146cf565b611513565b6103ae61067d366004614f47565b611524565b600061069060016004614fd0565b600261069d608085615012565b67ffffffffffffffff166106b19190615039565b601060006106c0608087615050565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106f7576106f761429a565b92915050565b84518460ff16601f82111561074a5760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016107419190615077565b60405180910390fd5b806000036107875760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016107419190615077565b61078f6117c4565b6107988561183a565b60095460005b8181101561080f5760086000600983815481106107bd576107bd615091565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161079e565b5050865160005b818110156109b257600089828151811061083257610832615091565b602002602001015190506000600281111561084f5761084f61429a565b6001600160a01b038216600090815260086020526040902054610100900460ff1660028111156108815761088161429a565b146108bb5760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016107419190615077565b6001600160a01b0381166108fb576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561099e5761099e61429a565b021790555090505050806001019050610816565b5087516109c69060099060208b0190614155565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a161717905560078054610a4c914691309190600090610a1e9063ffffffff166150c0565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611b72565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610add9487949293918316921691909117908f908f908f908f908f908f906150e3565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610ba190611bff565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bfe57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610be0575b5050505050905090565b6000546001600160a01b03163314801590610c2e57506002546001600160a01b03163314155b15610c65576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b610cd9611cb1565b81515181518114610d16576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610db3576000838281518110610d3557610d35615091565b6020026020010151905080600014610daa578451805183908110610d5b57610d5b615091565b602002602001015160800151811015610daa576040517f085e39cf0000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610741565b50600101610d19565b50610dbe8383611d32565b505050565b6001546001600160a01b03163314610e37576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610741565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106f7577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106f7576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa29190615179565b9392505050565b610fb16117c4565b60005b825181101561108457610fee838281518110610fd257610fd2615091565b602002602001015160200151600c6127b590919063ffffffff16565b1561107c577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d5878283828151811061102657611026615091565b60200260200101516000015184838151811061104457611044615091565b6020026020010151602001516040516110739291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610fb4565b5060005b8151811015610dbe576110e18282815181106110a6576110a6615091565b6020026020010151602001518383815181106110c4576110c4615091565b602002602001015160000151600c6127ca9092919063ffffffff16565b1561116f577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a82828151811061111957611119615091565b60200260200101516000015183838151811061113757611137615091565b6020026020010151602001516040516111669291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101611088565b61118187876127e8565b6005548835908082146111ca576040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610741565b6111d2611cb1565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561125a5761125a61429a565b600281111561126b5761126b61429a565b90525090506002816020015160028111156112885761128861429a565b1480156112c257506009816000015160ff16815481106112aa576112aa615091565b6000918252602090912001546001600160a01b031633145b6112f8576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611306856020615039565b611311886020615039565b61131d8b610144615196565b6113279190615196565b6113319190615196565b9050368114611375576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610741565b5050505050505050505050565b6000546001600160a01b031633148015906113a857506002546001600160a01b03163314155b156113df576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ea60038261280f565b50565b60608060006113fc600c6129f4565b90508067ffffffffffffffff8111156114175761141761434e565b604051908082528060200260200182016040528015611440578160200160208202803683370190505b5092508067ffffffffffffffff81111561145c5761145c61434e565b604051908082528060200260200182016040528015611485578160200160208202803683370190505b50915060005b8181101561150d576000806114a1600c846129ff565b91509150808684815181106114b8576114b8615091565b60200260200101906001600160a01b031690816001600160a01b031681525050818584815181106114eb576114eb615091565b6001600160a01b0390921660209283029190910190910152505060010161148b565b50509091565b61151b6117c4565b6113ea81612a1d565b33301461155d576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516000808252602082019092528161159a565b60408051808201909152600080825260208201528152602001906001900390816115735790505b5061014084015151909150156115fa576115f783610140015184602001516040516020016115d791906001600160a01b0391909116815260200190565b604051602081830303815290604052856040015186610160015186612af8565b90505b6101208301515115801561161057506080830151155b80611627575060408301516001600160a01b03163b155b8061166757506040830151611665906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612c29565b155b1561167157505050565b600080600a600001600a9054906101000a90046001600160a01b03166001600160a01b0316633cf979836040518060a001604052808861018001518152602001886000015167ffffffffffffffff16815260200188602001516040516020016116e991906001600160a01b0391909116815260200190565b6040516020818303038152906040528152602001886101200151815260200186815250611388886080015189604001516040518563ffffffff1660e01b815260040161173894939291906151ee565b6000604051808303816000875af1158015611757573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261177f91908101906152f8565b5091509150816117bd57806040517f0a8d6e8c000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b5050505050565b6000546001600160a01b03163314611838576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610741565b565b6000818060200190518101906118509190615371565b60608101519091506001600160a01b0316611897576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a80546020808501516040808701516060808901516001600160a01b039081166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff61ffff9094166801000000000000000002939093167fffff00000000000000000000000000000000000000000000ffffffffffffffff63ffffffff968716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009099169a87169a909a1797909717989098169590951717909455608080870151600b805460a0808b015160c0808d015188167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9290981674010000000000000000000000000000000000000000027fffffffffffffffff000000000000000000000000000000000000000000000000909416958c16959095179290921791909116949094179055855160e0810187527f00000000000000000000000000000000000000000000000000000000000000008816815267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116958201959095527f0000000000000000000000000000000000000000000000000000000000000000909416848701527f00000000000000000000000000000000000000000000000000000000000000008716948401949094527f00000000000000000000000000000000000000000000000000000000000000008616908301527f00000000000000000000000000000000000000000000000000000000000000008516908201527f000000000000000000000000000000000000000000000000000000000000000090931690830152517ff02fcc22535d64d92d17b995475893d63edd51da163fed74a6ee9b4bc4895cc491611b6691849061540c565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611b96999897969594939291906154e8565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c8d82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c719190614fd0565b85608001516fffffffffffffffffffffffffffffffff16612c45565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b467f000000000000000000000000000000000000000000000000000000000000000014611838576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610741565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611dec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e109190615570565b15611e47576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151516000819003611e84576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114611ec2576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff811115611edd57611edd61434e565b604051908082528060200260200182016040528015611f06578160200160208202803683370190505b50905060005b82811015611fde57600085600001518281518110611f2c57611f2c615091565b60200260200101519050611f60817f0000000000000000000000000000000000000000000000000000000000000000612c64565b838381518110611f7257611f72615091565b602002602001018181525050806101800151838381518110611f9657611f96615091565b602002602001015114611fd5576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101611f0c565b50604080850151606086015191517f320488750000000000000000000000000000000000000000000000000000000081526000926001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692633204887592612052928792916004016155be565b602060405180830381865afa15801561206f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209391906155f4565b9050806000036120cf576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b848110156127ac576000876000015182815181106120f6576120f6615091565b60200260200101519050600061210f8260600151610682565b905060028160038111156121255761212561429a565b0361216c57816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a250506127a4565b60008160038111156121805761218061429a565b148061219d5750600381600381111561219b5761219b61429a565b145b6121e55760608201516040517f50a6e05200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b83156122a257600a5460009063ffffffff166122018742614fd0565b11905080806122215750600382600381111561221f5761221f61429a565b145b612257576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88848151811061226957612269615091565b602002602001015160001461229c5788848151811061228a5761228a615091565b60200260200101518360800181815250505b506122ff565b60008160038111156122b6576122b661429a565b146122ff5760608201516040517f67d9ba0f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b60c082015167ffffffffffffffff161561257e576020808301516001600160a01b03166000908152600f909152604081205467ffffffffffffffff16908190036124e9577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156124e95760208301516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa1580156123f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241c9190615179565b60c084015190915067ffffffffffffffff1661243982600161560d565b67ffffffffffffffff16146124995782602001516001600160a01b03168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a35050506127a4565b6020838101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b60008260038111156124fd576124fd61429a565b0361257c5760c083015167ffffffffffffffff1661251c82600161560d565b67ffffffffffffffff161461257c5782602001516001600160a01b03168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a35050506127a4565b505b60008960200151848151811061259657612596615091565b602002602001015190506125c28360600151846000015185610140015151866101200151518551612dbf565b6125d183606001516001612f39565b6000806125de8584612fe3565b915091506125f0856060015183612f39565b861561265c57600382600381111561260a5761260a61429a565b0361265c5760008460038111156126235761262361429a565b1461265c57806040517fcf19edfd000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b60028260038111156126705761267061429a565b146126c85760038260038111156126895761268961429a565b146126c8578460600151826040517f9e26160300000000000000000000000000000000000000000000000000000000815260040161074192919061562e565b60c085015167ffffffffffffffff16156127505760008460038111156126f0576126f061429a565b03612750576020808601516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff16916127288361564c565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b846101800151856060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef658484604051612796929190615669565b60405180910390a350505050505b6001016120d6565b50505050505050565b6000610fa2836001600160a01b0384166132d6565b60006127e0846001600160a01b038516846132e2565b949350505050565b61280b6127f782840184615689565b604080516000815260208101909152611d32565b5050565b815460009061283890700100000000000000000000000000000000900463ffffffff1642614fd0565b905080156128da5760018301548354612880916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612c45565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612900916fffffffffffffffffffffffffffffffff90811691166132f8565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906129e79084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106f78261330e565b6000808080612a0e8686613319565b909450925050505b9250929050565b336001600160a01b03821603612a8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610741565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b846000805b8751811015612c0e57612b75888281518110612b1b57612b1b615091565b6020026020010151602001518888888581518110612b3b57612b3b615091565b6020026020010151806020019051810190612b5691906156be565b888681518110612b6857612b68615091565b6020026020010151613328565b838281518110612b8757612b87615091565b6020026020010181905250612bc3838281518110612ba757612ba7615091565b602002602001015160000151600c61374b90919063ffffffff16565b15612c0657612bf9838281518110612bdd57612bdd615091565b6020908102919091010151600b546001600160a01b0316613760565b612c039083615196565b91505b600101612afd565b508015612c1e57612c1e81613881565b505b95945050505050565b6000612c348361388e565b8015610fa25750610fa283836138f2565b6000612c2085612c558486615039565b612c5f9087615196565b6132f8565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612cfa9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612d339190615773565b60405160208183030381529060405280519060200120876101600151604051602001612d5f91906157e0565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff1614612e38576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610741565b600a5468010000000000000000900461ffff16831115612e90576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610741565b808314612ed5576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610741565b600a54640100000000900463ffffffff168211156117bd57600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff16600482015260248101839052604401610741565b60006002612f48608085615012565b67ffffffffffffffff16612f5c9190615039565b90506000601081612f6e608087615050565b67ffffffffffffffff168152602081019190915260400160002054905081612f9860016004614fd0565b901b191681836003811115612faf57612faf61429a565b901b178060106000612fc2608088615050565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a59061302790879087906004016157f3565b600060405180830381600087803b15801561304157600080fd5b505af1925050508015613052575060015b6132bb573d808015613080576040519150601f19603f3d011682016040523d82523d6000602084013e613085565b606091505b5061308f81615956565b7fffffffff00000000000000000000000000000000000000000000000000000000167f0a8d6e8c00000000000000000000000000000000000000000000000000000000148061312757506130e281615956565b7fffffffff00000000000000000000000000000000000000000000000000000000167fe1cd550900000000000000000000000000000000000000000000000000000000145b8061317b575061313681615956565b7fffffffff00000000000000000000000000000000000000000000000000000000167f8d666f6000000000000000000000000000000000000000000000000000000000145b806131cf575061318a81615956565b7fffffffff00000000000000000000000000000000000000000000000000000000167f78ef802400000000000000000000000000000000000000000000000000000000145b8061322357506131de81615956565b7fffffffff00000000000000000000000000000000000000000000000000000000167f0c3b563c00000000000000000000000000000000000000000000000000000000145b80613277575061323281615956565b7fffffffff00000000000000000000000000000000000000000000000000000000167fae9b4ce900000000000000000000000000000000000000000000000000000000145b1561328757600392509050612a16565b806040517fcf19edfd000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b50506040805160208101909152600081526002909250929050565b6000610fa283836139c1565b60006127e084846001600160a01b0385166139de565b60008183106133075781610fa2565b5090919050565b60006106f7826139fb565b6000808080612a0e8686613a06565b6040805180820190915260008082526020820152600061334b8460200151613a31565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa1580156133d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f491906159a6565b90506001600160a01b038116158061343c575061343a6001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612c29565b155b1561347e576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610741565b6000806135986040518061010001604052808b81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018a6001600160a01b031681526020018c8152602001866001600160a01b0316815260200189600001518152602001896040015181526020018881525060405160240161351291906159c3565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3907753700000000000000000000000000000000000000000000000000000000179052600b54859063ffffffff74010000000000000000000000000000000000000000909104166113886084613ad7565b5091509150816135d657806040517fe1cd5509000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b805160201461361e5780516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610741565b60008180602001905181019061363491906155f4565b6040516001600160a01b038b166024820152604481018290529091506136e19060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600b54879063ffffffff7801000000000000000000000000000000000000000000000000909104166113886084613ad7565b5090935091508261372057816040517fe1cd5509000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b604080518082019091526001600160a01b039095168552602085015250919250505095945050505050565b6000610fa2836001600160a01b038416613bfd565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa1580156137c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ea9190615a9a565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036138535783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610741565b60208401516127e0907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690613c09565b6113ea6003826000613c46565b60006138ba827f01ffc9a7000000000000000000000000000000000000000000000000000000006138f2565b80156106f757506138eb827fffffffff000000000000000000000000000000000000000000000000000000006138f2565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156139aa575060208210155b80156139b65750600081115b979650505050505050565b60008181526002830160205260408120819055610fa28383613f95565b600082815260028401602052604081208290556127e08484613fa1565b60006106f782613fad565b60008080613a148585613fb7565b600081815260029690960160205260409095205494959350505050565b60008151602014613a7057816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b600082806020019051810190613a8691906155f4565b90506001600160a01b03811180613a9e575061040081105b156106f757826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b6000606060008361ffff1667ffffffffffffffff811115613afa57613afa61434e565b6040519080825280601f01601f191660200182016040528015613b24576020820181803683370190505b509150863b613b57577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613b8a577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613bc3577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613be65750835b808352806000602085013e50955095509592505050565b6000610fa28383613fc3565b6000670de0b6b3a7640000613c3c837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616615039565b610fa29190615afa565b825474010000000000000000000000000000000000000000900460ff161580613c6d575081155b15613c7757505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090613cbd90700100000000000000000000000000000000900463ffffffff1642614fd0565b90508015613d7d5781831115613cff576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613d399083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612c45565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613e1a576001600160a01b038416613dcf576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610741565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610741565b84831015613f135760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613e5e9082614fd0565b613e68878a614fd0565b613e729190615196565b613e7c9190615afa565b90506001600160a01b038616613ec8576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610741565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610741565b613f1d8584614fd0565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610fa28383613fe2565b6000610fa283836140dc565b60006106f7825490565b6000610fa2838361412b565b6000610fa2838360008181526001830160205260408120541515610fa2565b600081815260018301602052604081205480156140cb576000614006600183614fd0565b855490915060009061401a90600190614fd0565b905081811461407f57600086600001828154811061403a5761403a615091565b906000526020600020015490508087600001848154811061405d5761405d615091565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061409057614090615b0e565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106f7565b60009150506106f7565b5092915050565b6000818152600183016020526040812054614123575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106f7565b5060006106f7565b600082600001828154811061414257614142615091565b9060005260206000200154905092915050565b8280548282559060005260206000209081019282156141c2579160200282015b828111156141c257825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190614175565b506141ce9291506141d2565b5090565b5b808211156141ce57600081556001016141d3565b60e081016106f782846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff811681146113ea57600080fd5b803561427881614257565b919050565b60006020828403121561428f57600080fd5b8135610fa281614257565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600481106142d9576142d961429a565b9052565b602081016106f782846142c9565b60005b838110156143065781810151838201526020016142ee565b50506000910152565b600081518084526143278160208601602086016142eb565b601f01601f19169290920160200192915050565b602081526000610fa2602083018461430f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156143a0576143a061434e565b60405290565b6040516101a0810167ffffffffffffffff811182821017156143a0576143a061434e565b6040516080810167ffffffffffffffff811182821017156143a0576143a061434e565b6040516060810167ffffffffffffffff811182821017156143a0576143a061434e565b60405160e0810167ffffffffffffffff811182821017156143a0576143a061434e565b604051601f8201601f1916810167ffffffffffffffff8111828210171561445c5761445c61434e565b604052919050565b600067ffffffffffffffff82111561447e5761447e61434e565b5060051b60200190565b6001600160a01b03811681146113ea57600080fd5b803561427881614488565b600082601f8301126144b957600080fd5b813560206144ce6144c983614464565b614433565b8083825260208201915060208460051b8701019350868411156144f057600080fd5b602086015b8481101561451557803561450881614488565b83529183019183016144f5565b509695505050505050565b803560ff8116811461427857600080fd5b600067ffffffffffffffff82111561454b5761454b61434e565b50601f01601f191660200190565b600082601f83011261456a57600080fd5b81356145786144c982614531565b81815284602083860101111561458d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156145c357600080fd5b863567ffffffffffffffff808211156145db57600080fd5b6145e78a838b016144a8565b975060208901359150808211156145fd57600080fd5b6146098a838b016144a8565b965061461760408a01614520565b9550606089013591508082111561462d57600080fd5b6146398a838b01614559565b945061464760808a0161426d565b935060a089013591508082111561465d57600080fd5b5061466a89828a01614559565b9150509295509295509295565b60008151808452602080850194506020840160005b838110156146b15781516001600160a01b03168752958201959082019060010161468c565b509495945050505050565b602081526000610fa26020830184614677565b6000602082840312156146e157600080fd5b8135610fa281614488565b80151581146113ea57600080fd5b8035614278816146ec565b600082601f83011261471657600080fd5b813560206147266144c983614464565b82815260069290921b8401810191818101908684111561474557600080fd5b8286015b8481101561451557604081890312156147625760008081fd5b61476a61437d565b813561477581614488565b81528185013585820152835291830191604001614749565b600082601f83011261479e57600080fd5b813560206147ae6144c983614464565b82815260059290921b840181019181810190868411156147cd57600080fd5b8286015b8481101561451557803567ffffffffffffffff8111156147f15760008081fd5b6147ff8986838b0101614559565b8452509183019183016147d1565b60006101a0828403121561482057600080fd5b6148286143a6565b90506148338261426d565b81526148416020830161449d565b60208201526148526040830161449d565b60408201526148636060830161426d565b60608201526080820135608082015261487e60a083016146fa565b60a082015261488f60c0830161426d565b60c08201526148a060e0830161449d565b60e082015261010082810135908201526101208083013567ffffffffffffffff808211156148cd57600080fd5b6148d986838701614559565b838501526101409250828501359150808211156148f557600080fd5b61490186838701614705565b8385015261016092508285013591508082111561491d57600080fd5b5061492a8582860161478d565b82840152505061018080830135818301525092915050565b600082601f83011261495357600080fd5b813560206149636144c983614464565b82815260059290921b8401810191818101908684111561498257600080fd5b8286015b8481101561451557803567ffffffffffffffff8111156149a65760008081fd5b6149b48986838b010161478d565b845250918301918301614986565b600082601f8301126149d357600080fd5b813560206149e36144c983614464565b8083825260208201915060208460051b870101935086841115614a0557600080fd5b602086015b848110156145155780358352918301918301614a0a565b600060808284031215614a3357600080fd5b614a3b6143ca565b9050813567ffffffffffffffff80821115614a5557600080fd5b818401915084601f830112614a6957600080fd5b81356020614a796144c983614464565b82815260059290921b84018101918181019088841115614a9857600080fd5b8286015b84811015614ad057803586811115614ab45760008081fd5b614ac28b86838b010161480d565b845250918301918301614a9c565b5086525085810135935082841115614ae757600080fd5b614af387858801614942565b90850152506040840135915080821115614b0c57600080fd5b50614b19848285016149c2565b6040830152506060820135606082015292915050565b60008060408385031215614b4257600080fd5b823567ffffffffffffffff80821115614b5a57600080fd5b614b6686838701614a21565b9350602091508185013581811115614b7d57600080fd5b85019050601f81018613614b9057600080fd5b8035614b9e6144c982614464565b81815260059190911b82018301908381019088831115614bbd57600080fd5b928401925b82841015614bdb57833582529284019290840190614bc2565b80955050505050509250929050565b60e081016106f7828463ffffffff80825116835280602083015116602084015261ffff604083015116604084015260608201516001600160a01b03808216606086015280608085015116608086015250508060a08301511660a08401528060c08301511660c0840152505050565b600060208284031215614c6a57600080fd5b813567ffffffffffffffff811115614c8157600080fd5b820160a08185031215610fa257600080fd5b600082601f830112614ca457600080fd5b81356020614cb46144c983614464565b82815260069290921b84018101918181019086841115614cd357600080fd5b8286015b848110156145155760408189031215614cf05760008081fd5b614cf861437d565b8135614d0381614488565b815281850135614d1281614488565b81860152835291830191604001614cd7565b60008060408385031215614d3757600080fd5b823567ffffffffffffffff80821115614d4f57600080fd5b614d5b86838701614c93565b93506020850135915080821115614d7157600080fd5b50614d7e85828601614c93565b9150509250929050565b60008083601f840112614d9a57600080fd5b50813567ffffffffffffffff811115614db257600080fd5b6020830191508360208260051b8501011115612a1657600080fd5b60008060008060008060008060e0898b031215614de957600080fd5b606089018a811115614dfa57600080fd5b8998503567ffffffffffffffff80821115614e1457600080fd5b818b0191508b601f830112614e2857600080fd5b813581811115614e3757600080fd5b8c6020828501011115614e4957600080fd5b6020830199508098505060808b0135915080821115614e6757600080fd5b614e738c838d01614d88565b909750955060a08b0135915080821115614e8c57600080fd5b50614e998b828c01614d88565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff8116811461427857600080fd5b600060608284031215614ee457600080fd5b614eec6143ed565b8235614ef7816146ec565b8152614f0560208401614eb2565b6020820152614f1660408401614eb2565b60408201529392505050565b604081526000614f356040830185614677565b8281036020840152612c208185614677565b60008060408385031215614f5a57600080fd5b823567ffffffffffffffff80821115614f7257600080fd5b614f7e8683870161480d565b93506020850135915080821115614f9457600080fd5b50614d7e8582860161478d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106f7576106f7614fa1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061502d5761502d614fe3565b92169190910692915050565b80820281158282048414176106f7576106f7614fa1565b600067ffffffffffffffff8084168061506b5761506b614fe3565b92169190910492915050565b602081016003831061508b5761508b61429a565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff8083168181036150d9576150d9614fa1565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526151138184018a614677565b905082810360808401526151278189614677565b905060ff871660a084015282810360c0840152615144818761430f565b905067ffffffffffffffff851660e0840152828103610100840152615169818561430f565b9c9b505050505050505050505050565b60006020828403121561518b57600080fd5b8151610fa281614257565b808201808211156106f7576106f7614fa1565b60008151808452602080850194506020840160005b838110156146b157815180516001600160a01b0316885283015183880152604090960195908201906001016151be565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c084015261522961012084018261430f565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e0860152615265838361430f565b92506080890151915080858403016101008601525061528482826151a9565b92505050615298602083018661ffff169052565b836040830152612c2060608301846001600160a01b03169052565b600082601f8301126152c457600080fd5b81516152d26144c982614531565b8181528460208386010111156152e757600080fd5b6127e08260208301602087016142eb565b60008060006060848603121561530d57600080fd5b8351615318816146ec565b602085015190935067ffffffffffffffff81111561533557600080fd5b615341868287016152b3565b925050604084015190509250925092565b805163ffffffff8116811461427857600080fd5b805161427881614488565b600060e0828403121561538357600080fd5b61538b614410565b61539483615352565b81526153a260208401615352565b6020820152604083015161ffff811681146153bc57600080fd5b60408201526153cd60608401615366565b60608201526153de60808401615366565b60808201526153ef60a08401615352565b60a082015261540060c08401615352565b60c08201529392505050565b6101c0810161547d82856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e084015260208401518116610100840152604084015161ffff1661012084015260608401516001600160a01b0390811661014085015260808501511661016084015260a0840151811661018084015260c0840151166101a0830152610fa2565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526155228285018b614677565b91508382036080850152615536828a614677565b915060ff881660a085015283820360c0850152615553828861430f565b90861660e08501528381036101008501529050615169818561430f565b60006020828403121561558257600080fd5b8151610fa2816146ec565b60008151808452602080850194506020840160005b838110156146b1578151875295820195908201906001016155a2565b6060815260006155d1606083018661558d565b82810360208401526155e3818661558d565b915050826040830152949350505050565b60006020828403121561560657600080fd5b5051919050565b67ffffffffffffffff8181168382160190808211156140d5576140d5614fa1565b67ffffffffffffffff8316815260408101610fa260208301846142c9565b600067ffffffffffffffff8083168181036150d9576150d9614fa1565b61567381846142c9565b6040602082015260006127e0604083018461430f565b60006020828403121561569b57600080fd5b813567ffffffffffffffff8111156156b257600080fd5b6127e084828501614a21565b6000602082840312156156d057600080fd5b815167ffffffffffffffff808211156156e857600080fd5b90830190606082860312156156fc57600080fd5b6157046143ed565b82518281111561571357600080fd5b61571f878286016152b3565b82525060208301518281111561573457600080fd5b615740878286016152b3565b60208301525060408301518281111561575857600080fd5b615764878286016152b3565b60408301525095945050505050565b602081526000610fa260208301846151a9565b60008282518085526020808601955060208260051b8401016020860160005b848110156157d357601f198684030189526157c183835161430f565b988401989250908301906001016157a5565b5090979650505050505050565b602081526000610fa26020830184615786565b6040815261580e60408201845167ffffffffffffffff169052565b6000602084015161582a60608401826001600160a01b03169052565b5060408401516001600160a01b038116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c084015161010061588b8185018367ffffffffffffffff169052565b60e086015191506101206158a9818601846001600160a01b03169052565b81870151925061014091508282860152808701519250506101a061016081818701526158d96101e087018561430f565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc061018081888703018189015261591886866151a9565b9550828a015194508188870301848901526159338686615786565b9550808a01516101c089015250505050508281036020840152612c208185615786565b6000815160208301517fffffffff000000000000000000000000000000000000000000000000000000008082169350600483101561599e5780818460040360031b1b83161693505b505050919050565b6000602082840312156159b857600080fd5b8151610fa281614488565b60208152600082516101008060208501526159e261012085018361430f565b915060208501516159ff604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615a3960a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615a56848361430f565b935060c08701519150808685030160e0870152615a73848361430f565b935060e0870151915080868503018387015250615a90838261430f565b9695505050505050565b600060408284031215615aac57600080fd5b615ab461437d565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114615ae057600080fd5b8152615aee60208401615352565b60208201529392505050565b600082615b0957615b09614fe3565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", +} + +var EVM2EVMOffRampABI = EVM2EVMOffRampMetaData.ABI + +var EVM2EVMOffRampBin = EVM2EVMOffRampMetaData.Bin + +func DeployEVM2EVMOffRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMOffRampStaticConfig, rateLimiterConfig RateLimiterConfig) (common.Address, *types.Transaction, *EVM2EVMOffRamp, error) { + parsed, err := EVM2EVMOffRampMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMOffRampBin), backend, staticConfig, rateLimiterConfig) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EVM2EVMOffRamp{address: address, abi: *parsed, EVM2EVMOffRampCaller: EVM2EVMOffRampCaller{contract: contract}, EVM2EVMOffRampTransactor: EVM2EVMOffRampTransactor{contract: contract}, EVM2EVMOffRampFilterer: EVM2EVMOffRampFilterer{contract: contract}}, nil +} + +type EVM2EVMOffRamp struct { + address common.Address + abi abi.ABI + EVM2EVMOffRampCaller + EVM2EVMOffRampTransactor + EVM2EVMOffRampFilterer +} + +type EVM2EVMOffRampCaller struct { + contract *bind.BoundContract +} + +type EVM2EVMOffRampTransactor struct { + contract *bind.BoundContract +} + +type EVM2EVMOffRampFilterer struct { + contract *bind.BoundContract +} + +type EVM2EVMOffRampSession struct { + Contract *EVM2EVMOffRamp + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type EVM2EVMOffRampCallerSession struct { + Contract *EVM2EVMOffRampCaller + CallOpts bind.CallOpts +} + +type EVM2EVMOffRampTransactorSession struct { + Contract *EVM2EVMOffRampTransactor + TransactOpts bind.TransactOpts +} + +type EVM2EVMOffRampRaw struct { + Contract *EVM2EVMOffRamp +} + +type EVM2EVMOffRampCallerRaw struct { + Contract *EVM2EVMOffRampCaller +} + +type EVM2EVMOffRampTransactorRaw struct { + Contract *EVM2EVMOffRampTransactor +} + +func NewEVM2EVMOffRamp(address common.Address, backend bind.ContractBackend) (*EVM2EVMOffRamp, error) { + abi, err := abi.JSON(strings.NewReader(EVM2EVMOffRampABI)) + if err != nil { + return nil, err + } + contract, err := bindEVM2EVMOffRamp(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &EVM2EVMOffRamp{address: address, abi: abi, EVM2EVMOffRampCaller: EVM2EVMOffRampCaller{contract: contract}, EVM2EVMOffRampTransactor: EVM2EVMOffRampTransactor{contract: contract}, EVM2EVMOffRampFilterer: EVM2EVMOffRampFilterer{contract: contract}}, nil +} + +func NewEVM2EVMOffRampCaller(address common.Address, caller bind.ContractCaller) (*EVM2EVMOffRampCaller, error) { + contract, err := bindEVM2EVMOffRamp(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampCaller{contract: contract}, nil +} + +func NewEVM2EVMOffRampTransactor(address common.Address, transactor bind.ContractTransactor) (*EVM2EVMOffRampTransactor, error) { + contract, err := bindEVM2EVMOffRamp(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampTransactor{contract: contract}, nil +} + +func NewEVM2EVMOffRampFilterer(address common.Address, filterer bind.ContractFilterer) (*EVM2EVMOffRampFilterer, error) { + contract, err := bindEVM2EVMOffRamp(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampFilterer{contract: contract}, nil +} + +func bindEVM2EVMOffRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EVM2EVMOffRampMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOffRamp.Contract.EVM2EVMOffRampCaller.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.EVM2EVMOffRampTransactor.contract.Transfer(opts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.EVM2EVMOffRampTransactor.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOffRamp.Contract.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.contract.Transfer(opts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) CcipReceive(opts *bind.CallOpts, arg0 ClientAny2EVMMessage) error { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "ccipReceive", arg0) + + if err != nil { + return err + } + + return err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) CcipReceive(arg0 ClientAny2EVMMessage) error { + return _EVM2EVMOffRamp.Contract.CcipReceive(&_EVM2EVMOffRamp.CallOpts, arg0) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) CcipReceive(arg0 ClientAny2EVMMessage) error { + return _EVM2EVMOffRamp.Contract.CcipReceive(&_EVM2EVMOffRamp.CallOpts, arg0) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "currentRateLimiterState") + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOffRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOffRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetAllRateLimitTokens(opts *bind.CallOpts) (GetAllRateLimitTokens, + + error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getAllRateLimitTokens") + + outstruct := new(GetAllRateLimitTokens) + if err != nil { + return *outstruct, err + } + + outstruct.SourceTokens = *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + outstruct.DestTokens = *abi.ConvertType(out[1], new([]common.Address)).(*[]common.Address) + + return *outstruct, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetAllRateLimitTokens() (GetAllRateLimitTokens, + + error) { + return _EVM2EVMOffRamp.Contract.GetAllRateLimitTokens(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetAllRateLimitTokens() (GetAllRateLimitTokens, + + error) { + return _EVM2EVMOffRamp.Contract.GetAllRateLimitTokens(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOffRampDynamicConfig, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(EVM2EVMOffRampDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOffRampDynamicConfig)).(*EVM2EVMOffRampDynamicConfig) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetDynamicConfig() (EVM2EVMOffRampDynamicConfig, error) { + return _EVM2EVMOffRamp.Contract.GetDynamicConfig(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetDynamicConfig() (EVM2EVMOffRampDynamicConfig, error) { + return _EVM2EVMOffRamp.Contract.GetDynamicConfig(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetExecutionState(opts *bind.CallOpts, sequenceNumber uint64) (uint8, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getExecutionState", sequenceNumber) + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetExecutionState(sequenceNumber uint64) (uint8, error) { + return _EVM2EVMOffRamp.Contract.GetExecutionState(&_EVM2EVMOffRamp.CallOpts, sequenceNumber) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetExecutionState(sequenceNumber uint64) (uint8, error) { + return _EVM2EVMOffRamp.Contract.GetExecutionState(&_EVM2EVMOffRamp.CallOpts, sequenceNumber) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getSenderNonce", sender) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOffRamp.Contract.GetSenderNonce(&_EVM2EVMOffRamp.CallOpts, sender) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOffRamp.Contract.GetSenderNonce(&_EVM2EVMOffRamp.CallOpts, sender) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOffRampStaticConfig, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(EVM2EVMOffRampStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOffRampStaticConfig)).(*EVM2EVMOffRampStaticConfig) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetStaticConfig() (EVM2EVMOffRampStaticConfig, error) { + return _EVM2EVMOffRamp.Contract.GetStaticConfig(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetStaticConfig() (EVM2EVMOffRampStaticConfig, error) { + return _EVM2EVMOffRamp.Contract.GetStaticConfig(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getTokenLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetTransmitters() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetTransmitters(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetTransmitters() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetTransmitters(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _EVM2EVMOffRamp.Contract.LatestConfigDetails(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _EVM2EVMOffRamp.Contract.LatestConfigDetails(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _EVM2EVMOffRamp.Contract.LatestConfigDigestAndEpoch(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _EVM2EVMOffRamp.Contract.LatestConfigDigestAndEpoch(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) Owner() (common.Address, error) { + return _EVM2EVMOffRamp.Contract.Owner(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) Owner() (common.Address, error) { + return _EVM2EVMOffRamp.Contract.Owner(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) TypeAndVersion() (string, error) { + return _EVM2EVMOffRamp.Contract.TypeAndVersion(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) TypeAndVersion() (string, error) { + return _EVM2EVMOffRamp.Contract.TypeAndVersion(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "acceptOwnership") +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.AcceptOwnership(&_EVM2EVMOffRamp.TransactOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.AcceptOwnership(&_EVM2EVMOffRamp.TransactOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) ExecuteSingleMessage(opts *bind.TransactOpts, message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "executeSingleMessage", message, offchainTokenData) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) ExecuteSingleMessage(message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMOffRamp.TransactOpts, message, offchainTokenData) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) ExecuteSingleMessage(message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMOffRamp.TransactOpts, message, offchainTokenData) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) ManuallyExecute(opts *bind.TransactOpts, report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "manuallyExecute", report, gasLimitOverrides) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) ManuallyExecute(report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ManuallyExecute(&_EVM2EVMOffRamp.TransactOpts, report, gasLimitOverrides) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) ManuallyExecute(report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ManuallyExecute(&_EVM2EVMOffRamp.TransactOpts, report, gasLimitOverrides) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "setAdmin", newAdmin) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetAdmin(&_EVM2EVMOffRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetAdmin(&_EVM2EVMOffRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "setOCR2Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetOCR2Config(&_EVM2EVMOffRamp.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetOCR2Config(&_EVM2EVMOffRamp.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "setRateLimiterConfig", config) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOffRamp.TransactOpts, config) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOffRamp.TransactOpts, config) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "transferOwnership", to) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.TransferOwnership(&_EVM2EVMOffRamp.TransactOpts, to) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.TransferOwnership(&_EVM2EVMOffRamp.TransactOpts, to) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "transmit", reportContext, report, rs, ss, arg4) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.Transmit(&_EVM2EVMOffRamp.TransactOpts, reportContext, report, rs, ss, arg4) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.Transmit(&_EVM2EVMOffRamp.TransactOpts, reportContext, report, rs, ss, arg4) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) UpdateRateLimitTokens(opts *bind.TransactOpts, removes []EVM2EVMOffRampRateLimitToken, adds []EVM2EVMOffRampRateLimitToken) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "updateRateLimitTokens", removes, adds) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) UpdateRateLimitTokens(removes []EVM2EVMOffRampRateLimitToken, adds []EVM2EVMOffRampRateLimitToken) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.UpdateRateLimitTokens(&_EVM2EVMOffRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) UpdateRateLimitTokens(removes []EVM2EVMOffRampRateLimitToken, adds []EVM2EVMOffRampRateLimitToken) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.UpdateRateLimitTokens(&_EVM2EVMOffRamp.TransactOpts, removes, adds) +} + +type EVM2EVMOffRampAdminSetIterator struct { + Event *EVM2EVMOffRampAdminSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampAdminSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampAdminSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampAdminSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampAdminSet struct { + NewAdmin common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOffRampAdminSetIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampAdminSetIterator{contract: _EVM2EVMOffRamp.contract, event: "AdminSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampAdminSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampAdminSet) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseAdminSet(log types.Log) (*EVM2EVMOffRampAdminSet, error) { + event := new(EVM2EVMOffRampAdminSet) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampConfigChangedIterator struct { + Event *EVM2EVMOffRampConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampConfigChangedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampConfigChanged struct { + Config RateLimiterConfig + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigChangedIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampConfigChangedIterator{contract: _EVM2EVMOffRamp.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigChanged) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampConfigChanged) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseConfigChanged(log types.Log) (*EVM2EVMOffRampConfigChanged, error) { + event := new(EVM2EVMOffRampConfigChanged) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampConfigSetIterator struct { + Event *EVM2EVMOffRampConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampConfigSet struct { + StaticConfig EVM2EVMOffRampStaticConfig + DynamicConfig EVM2EVMOffRampDynamicConfig + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampConfigSetIterator{contract: _EVM2EVMOffRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampConfigSet) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseConfigSet(log types.Log) (*EVM2EVMOffRampConfigSet, error) { + event := new(EVM2EVMOffRampConfigSet) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampConfigSet0Iterator struct { + Event *EVM2EVMOffRampConfigSet0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampConfigSet0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampConfigSet0Iterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampConfigSet0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampConfigSet0 struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterConfigSet0(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigSet0Iterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampConfigSet0Iterator{contract: _EVM2EVMOffRamp.contract, event: "ConfigSet0", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigSet0) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampConfigSet0) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseConfigSet0(log types.Log) (*EVM2EVMOffRampConfigSet0, error) { + event := new(EVM2EVMOffRampConfigSet0) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampExecutionStateChangedIterator struct { + Event *EVM2EVMOffRampExecutionStateChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampExecutionStateChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampExecutionStateChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampExecutionStateChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampExecutionStateChangedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampExecutionStateChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampExecutionStateChanged struct { + SequenceNumber uint64 + MessageId [32]byte + State uint8 + ReturnData []byte + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterExecutionStateChanged(opts *bind.FilterOpts, sequenceNumber []uint64, messageId [][32]byte) (*EVM2EVMOffRampExecutionStateChangedIterator, error) { + + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + var messageIdRule []interface{} + for _, messageIdItem := range messageId { + messageIdRule = append(messageIdRule, messageIdItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "ExecutionStateChanged", sequenceNumberRule, messageIdRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampExecutionStateChangedIterator{contract: _EVM2EVMOffRamp.contract, event: "ExecutionStateChanged", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampExecutionStateChanged, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) { + + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + var messageIdRule []interface{} + for _, messageIdItem := range messageId { + messageIdRule = append(messageIdRule, messageIdItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "ExecutionStateChanged", sequenceNumberRule, messageIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampExecutionStateChanged) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseExecutionStateChanged(log types.Log) (*EVM2EVMOffRampExecutionStateChanged, error) { + event := new(EVM2EVMOffRampExecutionStateChanged) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampOwnershipTransferRequestedIterator struct { + Event *EVM2EVMOffRampOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOffRampOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampOwnershipTransferRequestedIterator{contract: _EVM2EVMOffRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampOwnershipTransferRequested) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOffRampOwnershipTransferRequested, error) { + event := new(EVM2EVMOffRampOwnershipTransferRequested) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampOwnershipTransferredIterator struct { + Event *EVM2EVMOffRampOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOffRampOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampOwnershipTransferredIterator{contract: _EVM2EVMOffRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampOwnershipTransferred) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseOwnershipTransferred(log types.Log) (*EVM2EVMOffRampOwnershipTransferred, error) { + event := new(EVM2EVMOffRampOwnershipTransferred) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator struct { + Event *EVM2EVMOffRampSkippedAlreadyExecutedMessage + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedAlreadyExecutedMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedAlreadyExecutedMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampSkippedAlreadyExecutedMessage struct { + SequenceNumber uint64 + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterSkippedAlreadyExecutedMessage(opts *bind.FilterOpts, sequenceNumber []uint64) (*EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator, error) { + + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "SkippedAlreadyExecutedMessage", sequenceNumberRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator{contract: _EVM2EVMOffRamp.contract, event: "SkippedAlreadyExecutedMessage", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchSkippedAlreadyExecutedMessage(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedAlreadyExecutedMessage, sequenceNumber []uint64) (event.Subscription, error) { + + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "SkippedAlreadyExecutedMessage", sequenceNumberRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampSkippedAlreadyExecutedMessage) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedAlreadyExecutedMessage", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseSkippedAlreadyExecutedMessage(log types.Log) (*EVM2EVMOffRampSkippedAlreadyExecutedMessage, error) { + event := new(EVM2EVMOffRampSkippedAlreadyExecutedMessage) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedAlreadyExecutedMessage", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampSkippedIncorrectNonceIterator struct { + Event *EVM2EVMOffRampSkippedIncorrectNonce + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampSkippedIncorrectNonceIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedIncorrectNonce) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedIncorrectNonce) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampSkippedIncorrectNonceIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampSkippedIncorrectNonceIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampSkippedIncorrectNonce struct { + Nonce uint64 + Sender common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterSkippedIncorrectNonce(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*EVM2EVMOffRampSkippedIncorrectNonceIterator, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "SkippedIncorrectNonce", nonceRule, senderRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampSkippedIncorrectNonceIterator{contract: _EVM2EVMOffRamp.contract, event: "SkippedIncorrectNonce", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedIncorrectNonce, nonce []uint64, sender []common.Address) (event.Subscription, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "SkippedIncorrectNonce", nonceRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampSkippedIncorrectNonce) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedIncorrectNonce", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseSkippedIncorrectNonce(log types.Log) (*EVM2EVMOffRampSkippedIncorrectNonce, error) { + event := new(EVM2EVMOffRampSkippedIncorrectNonce) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedIncorrectNonce", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator struct { + Event *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight struct { + Nonce uint64 + Sender common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterSkippedSenderWithPreviousRampMessageInflight(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "SkippedSenderWithPreviousRampMessageInflight", nonceRule, senderRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator{contract: _EVM2EVMOffRamp.contract, event: "SkippedSenderWithPreviousRampMessageInflight", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchSkippedSenderWithPreviousRampMessageInflight(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, nonce []uint64, sender []common.Address) (event.Subscription, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "SkippedSenderWithPreviousRampMessageInflight", nonceRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedSenderWithPreviousRampMessageInflight", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseSkippedSenderWithPreviousRampMessageInflight(log types.Log) (*EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error) { + event := new(EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedSenderWithPreviousRampMessageInflight", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampTokenAggregateRateLimitAddedIterator struct { + Event *EVM2EVMOffRampTokenAggregateRateLimitAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampTokenAggregateRateLimitAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampTokenAggregateRateLimitAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampTokenAggregateRateLimitAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampTokenAggregateRateLimitAddedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampTokenAggregateRateLimitAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampTokenAggregateRateLimitAdded struct { + SourceToken common.Address + DestToken common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterTokenAggregateRateLimitAdded(opts *bind.FilterOpts) (*EVM2EVMOffRampTokenAggregateRateLimitAddedIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "TokenAggregateRateLimitAdded") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampTokenAggregateRateLimitAddedIterator{contract: _EVM2EVMOffRamp.contract, event: "TokenAggregateRateLimitAdded", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchTokenAggregateRateLimitAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampTokenAggregateRateLimitAdded) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "TokenAggregateRateLimitAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampTokenAggregateRateLimitAdded) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "TokenAggregateRateLimitAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseTokenAggregateRateLimitAdded(log types.Log) (*EVM2EVMOffRampTokenAggregateRateLimitAdded, error) { + event := new(EVM2EVMOffRampTokenAggregateRateLimitAdded) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "TokenAggregateRateLimitAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator struct { + Event *EVM2EVMOffRampTokenAggregateRateLimitRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampTokenAggregateRateLimitRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampTokenAggregateRateLimitRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampTokenAggregateRateLimitRemoved struct { + SourceToken common.Address + DestToken common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterTokenAggregateRateLimitRemoved(opts *bind.FilterOpts) (*EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "TokenAggregateRateLimitRemoved") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator{contract: _EVM2EVMOffRamp.contract, event: "TokenAggregateRateLimitRemoved", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchTokenAggregateRateLimitRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampTokenAggregateRateLimitRemoved) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "TokenAggregateRateLimitRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampTokenAggregateRateLimitRemoved) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "TokenAggregateRateLimitRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseTokenAggregateRateLimitRemoved(log types.Log) (*EVM2EVMOffRampTokenAggregateRateLimitRemoved, error) { + event := new(EVM2EVMOffRampTokenAggregateRateLimitRemoved) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "TokenAggregateRateLimitRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampTokensConsumedIterator struct { + Event *EVM2EVMOffRampTokensConsumed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampTokensConsumedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampTokensConsumedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampTokensConsumedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampTokensConsumed struct { + Tokens *big.Int + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterTokensConsumed(opts *bind.FilterOpts) (*EVM2EVMOffRampTokensConsumedIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampTokensConsumedIterator{contract: _EVM2EVMOffRamp.contract, event: "TokensConsumed", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampTokensConsumed) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampTokensConsumed) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseTokensConsumed(log types.Log) (*EVM2EVMOffRampTokensConsumed, error) { + event := new(EVM2EVMOffRampTokensConsumed) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampTransmittedIterator struct { + Event *EVM2EVMOffRampTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampTransmittedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterTransmitted(opts *bind.FilterOpts) (*EVM2EVMOffRampTransmittedIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampTransmittedIterator{contract: _EVM2EVMOffRamp.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampTransmitted) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampTransmitted) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseTransmitted(log types.Log) (*EVM2EVMOffRampTransmitted, error) { + event := new(EVM2EVMOffRampTransmitted) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetAllRateLimitTokens struct { + SourceTokens []common.Address + DestTokens []common.Address +} +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _EVM2EVMOffRamp.abi.Events["AdminSet"].ID: + return _EVM2EVMOffRamp.ParseAdminSet(log) + case _EVM2EVMOffRamp.abi.Events["ConfigChanged"].ID: + return _EVM2EVMOffRamp.ParseConfigChanged(log) + case _EVM2EVMOffRamp.abi.Events["ConfigSet"].ID: + return _EVM2EVMOffRamp.ParseConfigSet(log) + case _EVM2EVMOffRamp.abi.Events["ConfigSet0"].ID: + return _EVM2EVMOffRamp.ParseConfigSet0(log) + case _EVM2EVMOffRamp.abi.Events["ExecutionStateChanged"].ID: + return _EVM2EVMOffRamp.ParseExecutionStateChanged(log) + case _EVM2EVMOffRamp.abi.Events["OwnershipTransferRequested"].ID: + return _EVM2EVMOffRamp.ParseOwnershipTransferRequested(log) + case _EVM2EVMOffRamp.abi.Events["OwnershipTransferred"].ID: + return _EVM2EVMOffRamp.ParseOwnershipTransferred(log) + case _EVM2EVMOffRamp.abi.Events["SkippedAlreadyExecutedMessage"].ID: + return _EVM2EVMOffRamp.ParseSkippedAlreadyExecutedMessage(log) + case _EVM2EVMOffRamp.abi.Events["SkippedIncorrectNonce"].ID: + return _EVM2EVMOffRamp.ParseSkippedIncorrectNonce(log) + case _EVM2EVMOffRamp.abi.Events["SkippedSenderWithPreviousRampMessageInflight"].ID: + return _EVM2EVMOffRamp.ParseSkippedSenderWithPreviousRampMessageInflight(log) + case _EVM2EVMOffRamp.abi.Events["TokenAggregateRateLimitAdded"].ID: + return _EVM2EVMOffRamp.ParseTokenAggregateRateLimitAdded(log) + case _EVM2EVMOffRamp.abi.Events["TokenAggregateRateLimitRemoved"].ID: + return _EVM2EVMOffRamp.ParseTokenAggregateRateLimitRemoved(log) + case _EVM2EVMOffRamp.abi.Events["TokensConsumed"].ID: + return _EVM2EVMOffRamp.ParseTokensConsumed(log) + case _EVM2EVMOffRamp.abi.Events["Transmitted"].ID: + return _EVM2EVMOffRamp.ParseTransmitted(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (EVM2EVMOffRampAdminSet) Topic() common.Hash { + return common.HexToHash("0x8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c") +} + +func (EVM2EVMOffRampConfigChanged) Topic() common.Hash { + return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") +} + +func (EVM2EVMOffRampConfigSet) Topic() common.Hash { + return common.HexToHash("0xf02fcc22535d64d92d17b995475893d63edd51da163fed74a6ee9b4bc4895cc4") +} + +func (EVM2EVMOffRampConfigSet0) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (EVM2EVMOffRampExecutionStateChanged) Topic() common.Hash { + return common.HexToHash("0xd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef65") +} + +func (EVM2EVMOffRampOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (EVM2EVMOffRampOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (EVM2EVMOffRampSkippedAlreadyExecutedMessage) Topic() common.Hash { + return common.HexToHash("0xe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f") +} + +func (EVM2EVMOffRampSkippedIncorrectNonce) Topic() common.Hash { + return common.HexToHash("0xd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf41237") +} + +func (EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) Topic() common.Hash { + return common.HexToHash("0xe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d") +} + +func (EVM2EVMOffRampTokenAggregateRateLimitAdded) Topic() common.Hash { + return common.HexToHash("0xfc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a") +} + +func (EVM2EVMOffRampTokenAggregateRateLimitRemoved) Topic() common.Hash { + return common.HexToHash("0xcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d58782") +} + +func (EVM2EVMOffRampTokensConsumed) Topic() common.Hash { + return common.HexToHash("0x1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a") +} + +func (EVM2EVMOffRampTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRamp) Address() common.Address { + return _EVM2EVMOffRamp.address +} + +type EVM2EVMOffRampInterface interface { + CcipReceive(opts *bind.CallOpts, arg0 ClientAny2EVMMessage) error + + CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) + + GetAllRateLimitTokens(opts *bind.CallOpts) (GetAllRateLimitTokens, + + error) + + GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOffRampDynamicConfig, error) + + GetExecutionState(opts *bind.CallOpts, sequenceNumber uint64) (uint8, error) + + GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) + + GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOffRampStaticConfig, error) + + GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) + + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ExecuteSingleMessage(opts *bind.TransactOpts, message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) + + ManuallyExecute(opts *bind.TransactOpts, report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) + + SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) + + SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) + + UpdateRateLimitTokens(opts *bind.TransactOpts, removes []EVM2EVMOffRampRateLimitToken, adds []EVM2EVMOffRampRateLimitToken) (*types.Transaction, error) + + FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOffRampAdminSetIterator, error) + + WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampAdminSet) (event.Subscription, error) + + ParseAdminSet(log types.Log) (*EVM2EVMOffRampAdminSet, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*EVM2EVMOffRampConfigChanged, error) + + FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*EVM2EVMOffRampConfigSet, error) + + FilterConfigSet0(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigSet0Iterator, error) + + WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigSet0) (event.Subscription, error) + + ParseConfigSet0(log types.Log) (*EVM2EVMOffRampConfigSet0, error) + + FilterExecutionStateChanged(opts *bind.FilterOpts, sequenceNumber []uint64, messageId [][32]byte) (*EVM2EVMOffRampExecutionStateChangedIterator, error) + + WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampExecutionStateChanged, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) + + ParseExecutionStateChanged(log types.Log) (*EVM2EVMOffRampExecutionStateChanged, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOffRampOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOffRampOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOffRampOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*EVM2EVMOffRampOwnershipTransferred, error) + + FilterSkippedAlreadyExecutedMessage(opts *bind.FilterOpts, sequenceNumber []uint64) (*EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator, error) + + WatchSkippedAlreadyExecutedMessage(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedAlreadyExecutedMessage, sequenceNumber []uint64) (event.Subscription, error) + + ParseSkippedAlreadyExecutedMessage(log types.Log) (*EVM2EVMOffRampSkippedAlreadyExecutedMessage, error) + + FilterSkippedIncorrectNonce(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*EVM2EVMOffRampSkippedIncorrectNonceIterator, error) + + WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedIncorrectNonce, nonce []uint64, sender []common.Address) (event.Subscription, error) + + ParseSkippedIncorrectNonce(log types.Log) (*EVM2EVMOffRampSkippedIncorrectNonce, error) + + FilterSkippedSenderWithPreviousRampMessageInflight(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error) + + WatchSkippedSenderWithPreviousRampMessageInflight(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, nonce []uint64, sender []common.Address) (event.Subscription, error) + + ParseSkippedSenderWithPreviousRampMessageInflight(log types.Log) (*EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error) + + FilterTokenAggregateRateLimitAdded(opts *bind.FilterOpts) (*EVM2EVMOffRampTokenAggregateRateLimitAddedIterator, error) + + WatchTokenAggregateRateLimitAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampTokenAggregateRateLimitAdded) (event.Subscription, error) + + ParseTokenAggregateRateLimitAdded(log types.Log) (*EVM2EVMOffRampTokenAggregateRateLimitAdded, error) + + FilterTokenAggregateRateLimitRemoved(opts *bind.FilterOpts) (*EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator, error) + + WatchTokenAggregateRateLimitRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampTokenAggregateRateLimitRemoved) (event.Subscription, error) + + ParseTokenAggregateRateLimitRemoved(log types.Log) (*EVM2EVMOffRampTokenAggregateRateLimitRemoved, error) + + FilterTokensConsumed(opts *bind.FilterOpts) (*EVM2EVMOffRampTokensConsumedIterator, error) + + WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampTokensConsumed) (event.Subscription, error) + + ParseTokensConsumed(log types.Log) (*EVM2EVMOffRampTokensConsumed, error) + + FilterTransmitted(opts *bind.FilterOpts) (*EVM2EVMOffRampTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*EVM2EVMOffRampTransmitted, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0/evm_2_evm_offramp_1_0_0.go b/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0/evm_2_evm_offramp_1_0_0.go new file mode 100644 index 0000000000..3f140f8a3a --- /dev/null +++ b/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0/evm_2_evm_offramp_1_0_0.go @@ -0,0 +1,2354 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package evm_2_evm_offramp_1_0_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientAny2EVMMessage struct { + MessageId [32]byte + SourceChainSelector uint64 + Sender []byte + Data []byte + DestTokenAmounts []ClientEVMTokenAmount +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type EVM2EVMOffRampDynamicConfig struct { + PermissionLessExecutionThresholdSeconds uint32 + Router common.Address + PriceRegistry common.Address + MaxTokensLength uint16 + MaxDataSize uint32 +} + +type EVM2EVMOffRampStaticConfig struct { + CommitStore common.Address + ChainSelector uint64 + SourceChainSelector uint64 + OnRamp common.Address + PrevOffRamp common.Address + ArmProxy common.Address +} + +type InternalEVM2EVMMessage struct { + SourceChainSelector uint64 + SequenceNumber uint64 + FeeTokenAmount *big.Int + Sender common.Address + Nonce uint64 + GasLimit *big.Int + Strict bool + Receiver common.Address + Data []byte + TokenAmounts []ClientEVMTokenAmount + FeeToken common.Address + MessageId [32]byte +} + +type InternalExecutionReport struct { + Messages []InternalEVM2EVMMessage + OffchainTokenData [][][]byte + Proofs [][32]byte + ProofFlagBits *big.Int +} + +type InternalPoolUpdate struct { + Token common.Address + Pool common.Address +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +var EVM2EVMOffRampMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"contractIERC20[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"contractIPool[]\",\"name\":\"pools\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"TokenRateLimitError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getDestinationToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDestinationTokens\",\"outputs\":[{\"internalType\":\"contractIERC20[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"getPoolByDestToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"contractIERC20[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101806040523480156200001257600080fd5b506040516200698638038062006986833981016040819052620000359162000891565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c08162000478565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080938401819052600380546001600160a01b031916909517600160801b9384021760ff60a01b1916600160a01b90920291909117909355909102909217600455504690528151835114620001705760405162d8548360e71b815260040160405180910390fd5b60608401516001600160a01b0316158062000193575083516001600160a01b0316155b15620001b2576040516342bcdf7f60e11b815260040160405180910390fd5b83600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200021b9190620009a8565b6001600160401b03166001146200024557604051636fc2a20760e11b815260040160405180910390fd5b83516001600160a01b0390811660a090815260408601516001600160401b0390811660c05260208701511660e052606086015182166101005260808601518216610140528501511661016052620002bc7fbdd59ac4dd1d82276c9a9c5d2656546346b9dcdb1f9b4204aed4ec15c23d7d3a62000523565b6101205260005b83518110156200046d576200031d848281518110620002e657620002e6620009c6565b6020026020010151848381518110620003035762000303620009c6565b6020026020010151600c6200058a60201b9092919060201c565b50620003d2838281518110620003375762000337620009c6565b60200260200101516001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200037d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a39190620009dc565b848381518110620003b857620003b8620009c6565b6020026020010151600f6200058a60201b9092919060201c565b507f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c848281518110620004095762000409620009c6565b6020026020010151848381518110620004265762000426620009c6565b6020026020010151604051620004529291906001600160a01b0392831681529116602082015260400190565b60405180910390a1620004658162000a03565b9050620002c3565b505050505062000a2b565b336001600160a01b03821603620004d25760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e051610100516040516020016200056d94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b6000620005a2846001600160a01b03851684620005aa565b949350505050565b6000620005a284846001600160a01b03851660008281526002840160205260408120829055620005a284846000620005e38383620005ec565b90505b92915050565b60008181526001830160205260408120546200063557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005e6565b506000620005e6565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156200067957620006796200063e565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006aa57620006aa6200063e565b604052919050565b6001600160a01b0381168114620006c857600080fd5b50565b80516001600160401b0381168114620006e357600080fd5b919050565b60006001600160401b038211156200070457620007046200063e565b5060051b60200190565b600082601f8301126200072057600080fd5b81516020620007396200073383620006e8565b6200067f565b82815260059290921b840181019181810190868411156200075957600080fd5b8286015b84811015620007815780516200077381620006b2565b83529183019183016200075d565b509695505050505050565b600082601f8301126200079e57600080fd5b81516020620007b16200073383620006e8565b82815260059290921b84018101918181019086841115620007d157600080fd5b8286015b8481101562000781578051620007eb81620006b2565b8352918301918301620007d5565b80516001600160801b0381168114620006e357600080fd5b6000606082840312156200082457600080fd5b604051606081016001600160401b03811182821017156200084957620008496200063e565b8060405250809150825180151581146200086257600080fd5b81526200087260208401620007f9565b60208201526200088560408401620007f9565b60408201525092915050565b600080600080848603610160811215620008aa57600080fd5b60c0811215620008b957600080fd5b50620008c462000654565b8551620008d181620006b2565b8152620008e160208701620006cb565b6020820152620008f460408701620006cb565b604082015260608601516200090981620006b2565b606082015260808601516200091e81620006b2565b608082015260a08601516200093381620006b2565b60a082015260c08601519094506001600160401b03808211156200095657600080fd5b62000964888389016200070e565b945060e08701519150808211156200097b57600080fd5b506200098a878288016200078c565b9250506200099d86610100870162000811565b905092959194509250565b600060208284031215620009bb57600080fd5b620005e382620006cb565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009ef57600080fd5b8151620009fc81620006b2565b9392505050565b60006001820162000a2457634e487b7160e01b600052601160045260246000fd5b5060010190565b60805160a05160c05160e05161010051610120516101405161016051615e7e62000b0860003960008181610309015281816120ef0152612b0b0152600081816102cd015281816114a001528181611522015281816120c501528181613080015261310701526000612cc4015260008181610291015261209e015260008181610231015261204c01526000818161026101528181612076015281816124650152613a7c0152600081816101f50152818161201e0152612db901526000818161182f0152818161187b01528181611c8f0152611cdb0152615e7e6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806381ff7048116100ee578063b1dc65a411610097578063d3c7c2c711610071578063d3c7c2c7146106a7578063d7e2bb50146106af578063e65bf00a146106c2578063f2fde38b146106d557600080fd5b8063b1dc65a41461066e578063b4069b3114610681578063c92b28321461069457600080fd5b80638da5cb5b116100c85780638da5cb5b1461061d578063afa0d3791461063b578063afcb95d71461064e57600080fd5b806381ff7048146105b357806385572ffb146105e3578063856c8247146105f157600080fd5b8063599f64311161015b578063681fba1611610135578063681fba16146104b8578063704b6c02146104cd5780637437ff9f146104e057806379ba5097146105ab57600080fd5b8063599f6431146104515780635d86f14114610490578063666cab8d146104a357600080fd5b80631ef381741161018c5780631ef38174146103c55780633a87ac53146103da578063546719cd146103ed57600080fd5b806306285c69146101b3578063142a98fc1461035c578063181f5a771461037c575b600080fd5b6103466040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526040518060c001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161035391906145e8565b60405180910390f35b61036f61036a36600461467f565b6106e8565b6040516103539190614706565b6103b86040518060400160405280601481526020017f45564d3245564d4f666652616d7020312e302e3000000000000000000000000081525081565b6040516103539190614782565b6103d86103d33660046149f0565b610763565b005b6103d86103e8366004614b02565b610c22565b6103f5611032565b604051610353919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610353565b61046b61049e366004614b6e565b6110e7565b6104ab611150565b6040516103539190614bdc565b6104c06111bf565b6040516103539190614bef565b6103d86104db366004614b6e565b611278565b61059e6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff808216835273ffffffffffffffffffffffffffffffffffffffff64010000000090920482166020840152600b549182169383019390935261ffff7401000000000000000000000000000000000000000082041660608301527601000000000000000000000000000000000000000000009004909116608082015290565b6040516103539190614c49565b6103d8611368565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610353565b6103d86101ae366004614cac565b6106046105ff366004614b6e565b611465565b60405167ffffffffffffffff9091168152602001610353565b60005473ffffffffffffffffffffffffffffffffffffffff1661046b565b6103d8610649366004614f16565b61158d565b604080516001815260006020820181905291810191909152606001610353565b6103d861067c366004614fbf565b6117d9565b61046b61068f366004614b6e565b611a6a565b6103d86106a23660046150c4565b611b43565b6104c0611bc8565b61046b6106bd366004614b6e565b611c7d565b6103d86106d036600461531b565b611c8c565b6103d86106e3366004614b6e565b611e0e565b60006106f660016004615405565b6002610703608085615447565b67ffffffffffffffff16610717919061546e565b60136000610726608087615485565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c16600381111561075d5761075d61469c565b92915050565b84518460ff16601f8211156107d9576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f6f206d616e79207472616e736d697474657273000000000000000000000060448201526064015b60405180910390fd5b80600003610843576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f736974697665000000000000000000000000000060448201526064016107d0565b61084b611e1f565b61085485611ea2565b60095460005b818110156108e0576008600060098381548110610879576108796154ac565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108d9816154db565b905061085a565b50875160005b81811015610adc5760008a8281518110610902576109026154ac565b602002602001015190506000600281111561091f5761091f61469c565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260086020526040902054610100900460ff16600281111561095e5761095e61469c565b146109c5576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d697474657220616464726573730000000060448201526064016107d0565b73ffffffffffffffffffffffffffffffffffffffff8116610a12576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ac257610ac261469c565b02179055509050505080610ad5906154db565b90506108e6565b508851610af09060099060208c0190614552565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908b161717905560078054610b76914691309190600090610b489063ffffffff16615513565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168d8d8d8d8d8d61214f565b6005600001819055506000600760049054906101000a900463ffffffff16905043600760046101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600560000154600760009054906101000a900463ffffffff168e8e8e8e8e8e604051610c0d99989796959493929190615536565b60405180910390a15050505050505050505050565b610c2a611e1f565b60005b83811015610e29576000858583818110610c4957610c496154ac565b610c5f9260206040909202019081019150614b6e565b90506000868684818110610c7557610c756154ac565b9050604002016020016020810190610c8d9190614b6e565b9050610c9a600c836121fa565b610cd0576040517f9c8787c000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610cf2600c8461221c565b73ffffffffffffffffffffffffffffffffffffffff1614610d3f576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d4a600c8361223e565b50610dc58173ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbd91906155cc565b600f9061223e565b506040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a1505080610e22906154db565b9050610c2d565b5060005b8181101561102b576000838383818110610e4957610e496154ac565b610e5f9260206040909202019081019150614b6e565b90506000848484818110610e7557610e756154ac565b9050604002016020016020810190610e8d9190614b6e565b905073ffffffffffffffffffffffffffffffffffffffff82161580610ec6575073ffffffffffffffffffffffffffffffffffffffff8116155b15610efd576040517f6c2a418000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f08600c836121fa565b15610f3f576040517f3caf458500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f4b600c8383612260565b50610fc78173ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fbe91906155cc565b600f9083612260565b506040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a1505080611024906154db565b9050610e2d565b5050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff1615159383019390935260045480841660608401520490911660808201526110e290612283565b905090565b600080806110f6600c85612335565b9150915081611149576040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016107d0565b9392505050565b606060098054806020026020016040519081016040528092919081815260200182805480156111b557602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161118a575b5050505050905090565b60606111cb600f612364565b67ffffffffffffffff8111156111e3576111e3614795565b60405190808252806020026020018201604052801561120c578160200160208202803683370190505b50905060005b8151811015611274576000611228600f8361236f565b5090508083838151811061123e5761123e6154ac565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101525061126d816154db565b9050611212565b5090565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906112b8575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156112ef576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff1633146113e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107d0565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b73ffffffffffffffffffffffffffffffffffffffff811660009081526012602052604081205467ffffffffffffffff16801580156114d857507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615155b1561075d576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611569573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114991906155e9565b3330146115c6576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611603565b60408051808201909152600080825260208201528152602001906001900390816115dc5790505b5061012084015151909150156116625761012083015160608401516040805173ffffffffffffffffffffffffffffffffffffffff909216602083015261165f9291016040516020818303038152906040528560e001518561238b565b90505b60e083015173ffffffffffffffffffffffffffffffffffffffff163b15806116cc575060e08301516116ca9073ffffffffffffffffffffffffffffffffffffffff167f85572ffb00000000000000000000000000000000000000000000000000000000612831565b155b156116d657505050565b600a546000908190640100000000900473ffffffffffffffffffffffffffffffffffffffff16633cf9798361170b878661284d565b6113888860a001518960e001516040518563ffffffff1660e01b81526004016117379493929190615657565b6000604051808303816000875af1158015611756573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261179c9190810190615729565b915091508161102b57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107d09190614782565b6117e387876128fd565b60055488359080821461182c576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016107d0565b467f0000000000000000000000000000000000000000000000000000000000000000146118ad576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107d0565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156119355761193561469c565b60028111156119465761194661469c565b90525090506002816020015160028111156119635761196361469c565b1480156119aa57506009816000015160ff1681548110611985576119856154ac565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6119e0576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006119ee85602061546e565b6119f988602061546e565b611a058b6101446157b6565b611a0f91906157b6565b611a1991906157b6565b9050368114611a5d576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107d0565b5050505050505050505050565b60008080611a79600c85612335565b9150915081611acc576040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016107d0565b8073ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3b91906155cc565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611b83575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15611bba576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bc5600382612924565b50565b6060611bd4600c612364565b67ffffffffffffffff811115611bec57611bec614795565b604051908082528060200260200182016040528015611c15578160200160208202803683370190505b50905060005b8151811015611274576000611c31600c8361236f565b50905080838381518110611c4757611c476154ac565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250611c76816154db565b9050611c1b565b600080806110f6600f85612335565b467f000000000000000000000000000000000000000000000000000000000000000014611d17576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015267ffffffffffffffff461660248201526044016107d0565b81515181518114611d54576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015611dfe576000838281518110611d7357611d736154ac565b6020026020010151905080600014158015611dac57508451805183908110611d9d57611d9d6154ac565b602002602001015160a0015181105b15611ded576040517f085e39cf00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016107d0565b50611df7816154db565b9050611d57565b50611e098383612b09565b505050565b611e16611e1f565b611bc5816134b6565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ea0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107d0565b565b600081806020019051810190611eb891906157dd565b602081015190915073ffffffffffffffffffffffffffffffffffffffff16611f0c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090931663ffffffff9586161792909217909255604080850151600b80546060808901516080808b0151909916760100000000000000000000000000000000000000000000027fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff61ffff90921674010000000000000000000000000000000000000000027fffffffffffffffffffff00000000000000000000000000000000000000000000909416958816959095179290921791909116929092179055815160c0810183527f00000000000000000000000000000000000000000000000000000000000000008416815267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116958201959095527f0000000000000000000000000000000000000000000000000000000000000000909416848301527f00000000000000000000000000000000000000000000000000000000000000008316908401527f00000000000000000000000000000000000000000000000000000000000000008216938301939093527f00000000000000000000000000000000000000000000000000000000000000001660a082015290517f737ef22d3f6615e342ed21c69e06620dbc5c8a261ed7cfb2ce214806b1f76eda91612143918490615878565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a60405160200161217399989796959493929190615947565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b60006111498373ffffffffffffffffffffffffffffffffffffffff84166135ab565b60006111498373ffffffffffffffffffffffffffffffffffffffff84166135b7565b60006111498373ffffffffffffffffffffffffffffffffffffffff84166135c3565b6000611b3b8473ffffffffffffffffffffffffffffffffffffffff8516846135cf565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261231182606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426122f59190615405565b85608001516fffffffffffffffffffffffffffffffff166135f2565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6000806123588473ffffffffffffffffffffffffffffffffffffffff8516613611565b915091505b9250929050565b600061075d82613620565b600080808061237e868661362b565b9097909650945050505050565b60606000855167ffffffffffffffff8111156123a9576123a9614795565b6040519080825280602002602001820160405280156123ee57816020015b60408051808201909152600080825260208201528152602001906001900390816123c75790505b50905060005b8651811015612803576000612425888381518110612414576124146154ac565b6020026020010151600001516110e7565b90508073ffffffffffffffffffffffffffffffffffffffff16638627fad688888b8681518110612457576124576154ac565b6020026020010151602001517f00000000000000000000000000000000000000000000000000000000000000008a8881518110612496576124966154ac565b60200260200101516040518663ffffffff1660e01b81526004016124be9594939291906159dc565b600060405180830381600087803b1580156124d857600080fd5b505af19250505080156124e9575060015b61270c573d808015612517576040519150601f19603f3d011682016040523d82523d6000602084013e61251c565b606091505b50600061252882615a3f565b90507f9725942a000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821614806125bb57507ff94ebcd1000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b8061260757507f15279c08000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b8061265357507f1a76572a000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b8061269f57507fd0c8d23a000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b156126d857816040517f30dabb590000000000000000000000000000000000000000000000000000000081526004016107d09190614782565b816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107d09190614782565b8073ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612757573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277b91906155cc565b83838151811061278d5761278d6154ac565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905287518890839081106127c6576127c66154ac565b6020026020010151602001518383815181106127e4576127e46154ac565b6020908102919091018101510152506127fc816154db565b90506123f4565b50600b5461282890829073ffffffffffffffffffffffffffffffffffffffff1661363a565b95945050505050565b600061283c8361381a565b80156111495750611149838361387e565b6040805160a08101825260008082526020820152606091810182905281810182905260808101919091526040518060a001604052808461016001518152602001846000015167ffffffffffffffff16815260200184606001516040516020016128d2919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040528152602001846101000151815260200183815250905092915050565b61292061290c82840184615a8f565b604080516000815260208101909152612b09565b5050565b815460009061294d90700100000000000000000000000000000000900463ffffffff1642615405565b905080156129ef5760018301548354612995916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166135f2565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612a15916fffffffffffffffffffffffffffffffff908116911661394d565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612afc9084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b989190615ac4565b15612bcf576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151516000819003612c0c576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114612c4a576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff811115612c6557612c65614795565b604051908082528060200260200182016040528015612c8e578160200160208202803683370190505b50905060005b82811015612d6e57600085600001518281518110612cb457612cb46154ac565b60200260200101519050612ce8817f0000000000000000000000000000000000000000000000000000000000000000613963565b838381518110612cfa57612cfa6154ac565b602002602001018181525050806101600151838381518110612d1e57612d1e6154ac565b602002602001015114612d5d576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50612d67816154db565b9050612c94565b50604080850151606086015191517f3204887500000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001692633204887592612def92879291600401615b11565b602060405180830381865afa158015612e0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e309190615b47565b905080600003612e6c576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b848110156134ad57600087600001518281518110612e9357612e936154ac565b602002602001015190506000612eac82602001516106e8565b90506000816003811115612ec257612ec261469c565b1480612edf57506003816003811115612edd57612edd61469c565b145b612f275760208201516040517f50a6e05200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b8315612fe457600a5460009063ffffffff16612f438742615405565b1190508080612f6357506003826003811115612f6157612f6161469c565b145b612f99576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b888481518110612fab57612fab6154ac565b6020026020010151600014612fde57888481518110612fcc57612fcc6154ac565b60200260200101518360a00181815250505b50613041565b6000816003811115612ff857612ff861469c565b146130415760208201516040517f67d9ba0f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b606082015173ffffffffffffffffffffffffffffffffffffffff1660009081526012602052604090205467ffffffffffffffff16801580156130b857507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615155b1561325a5760608301516040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa158015613150573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061317491906155e9565b608084015190915067ffffffffffffffff16613191826001615b60565b67ffffffffffffffff16146131fe57826060015173ffffffffffffffffffffffffffffffffffffffff16836080015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a350505061349d565b606083015173ffffffffffffffffffffffffffffffffffffffff16600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b600082600381111561326e5761326e61469c565b036132fa57608083015167ffffffffffffffff1661328d826001615b60565b67ffffffffffffffff16146132fa57826060015173ffffffffffffffffffffffffffffffffffffffff16836080015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a350505061349d565b60008a602001518581518110613312576133126154ac565b60200260200101519050613327848251613a7a565b61333684602001516001613c50565b6000806133438684613cfa565b91509150613355866020015183613c50565b60038260038111156133695761336961469c565b14158015613389575060028260038111156133865761338661469c565b14155b156133c8578560200151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016107d0929190615b81565b60008560038111156133dc576133dc61469c565b0361344857606086015173ffffffffffffffffffffffffffffffffffffffff166000908152601260205260408120805467ffffffffffffffff169161342083615b9f565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b856101600151866020015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef65848460405161348e929190615bbc565b60405180910390a35050505050505b6134a6816154db565b9050612e73565b50505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107d0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006111498383613e9d565b60006111498383613ea9565b60006111498383613f33565b6000611b3b848473ffffffffffffffffffffffffffffffffffffffff8516613f50565b600061282885613602848661546e565b61360c90876157b6565b61394d565b600080808061237e8686613f6d565b600061075d82613fa7565b600080808061237e8686613fb2565b81516000805b828110156138065760008473ffffffffffffffffffffffffffffffffffffffff1663d02641a0878481518110613678576136786154ac565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016040805180830381865afa1580156136ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137109190615bdc565b51905077ffffffffffffffffffffffffffffffffffffffffffffffff811660000361379e57858281518110613747576137476154ac565b6020908102919091010151516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016107d0565b6137e88683815181106137b3576137b36154ac565b6020026020010151602001518277ffffffffffffffffffffffffffffffffffffffffffffffff16613fdd90919063ffffffff16565b6137f290846157b6565b925050806137ff906154db565b9050613640565b506138146003826000614016565b50505050565b6000613846827f01ffc9a70000000000000000000000000000000000000000000000000000000061387e565b801561075d5750613877827fffffffff0000000000000000000000000000000000000000000000000000000061387e565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613936575060208210155b80156139425750600081115b979650505050505050565b600081831061395c5781611149565b5090919050565b60008060001b828460200151856080015186606001518760e00151886101000151805190602001208961012001516040516020016139a19190615c3a565b604051602081830303815290604052805190602001208a60a001518b60c001518c61014001518d60400151604051602001613a5c9c9b9a999897969594939291909b8c5260208c019a909a5267ffffffffffffffff98891660408c01529690971660608a015273ffffffffffffffffffffffffffffffffffffffff94851660808a015292841660a089015260c088019190915260e0870152610100860152911515610120850152166101408301526101608201526101800190565b60405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16826000015167ffffffffffffffff1614613afa5781516040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b600b54610120830151517401000000000000000000000000000000000000000090910461ffff161015613b6b5760208201516040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b808261012001515114613bbc5760208201516040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b600b546101008301515176010000000000000000000000000000000000000000000090910463ffffffff16101561292057600b54610100830151516040517f8693378900000000000000000000000000000000000000000000000000000000815276010000000000000000000000000000000000000000000090920463ffffffff16600483015260248201526044016107d0565b60006002613c5f608085615447565b67ffffffffffffffff16613c73919061546e565b90506000601381613c85608087615485565b67ffffffffffffffff168152602081019190915260400160002054905081613caf60016004615405565b901b191681836003811115613cc657613cc661469c565b901b178060136000613cd9608088615485565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517fafa0d379000000000000000000000000000000000000000000000000000000008152600090606090309063afa0d37990613d3e9087908790600401615cc3565b600060405180830381600087803b158015613d5857600080fd5b505af1925050508015613d69575060015b613e82573d808015613d97576040519150601f19603f3d011682016040523d82523d6000602084013e613d9c565b606091505b50613da681615a3f565b7fffffffff00000000000000000000000000000000000000000000000000000000167f0a8d6e8c000000000000000000000000000000000000000000000000000000001480613e3e5750613df981615a3f565b7fffffffff00000000000000000000000000000000000000000000000000000000167fe1cd550900000000000000000000000000000000000000000000000000000000145b15613e4e5760039250905061235d565b806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016107d09190614782565b50506040805160208101909152600081526002909250929050565b60006111498383614399565b600081815260028301602052604081205480151580613ecd5750613ecd8484613e9d565b611149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b6579000060448201526064016107d0565b6000818152600283016020526040812081905561114983836143b1565b60008281526002840160205260408120829055611b3b84846143bd565b6000818152600283016020526040812054819080613f9c57613f8f8585613e9d565b92506000915061235d9050565b60019250905061235d565b600061075d826143c9565b60008080613fc085856143d3565b600081815260029690960160205260409095205494959350505050565b6000670de0b6b3a764000061400c8377ffffffffffffffffffffffffffffffffffffffffffffffff861661546e565b6111499190615e2e565b825474010000000000000000000000000000000000000000900460ff16158061403d575081155b1561404757505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061408d90700100000000000000000000000000000000900463ffffffff1642615405565b9050801561414d57818311156140cf576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546141099083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166135f2565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156142045773ffffffffffffffffffffffffffffffffffffffff84166141ac576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016107d0565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016107d0565b848310156143175760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906142489082615405565b614252878a615405565b61425c91906157b6565b6142669190615e2e565b905073ffffffffffffffffffffffffffffffffffffffff86166142bf576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016107d0565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016107d0565b6143218584615405565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60008181526001830160205260408120541515611149565b600061114983836143df565b600061114983836144d9565b600061075d825490565b60006111498383614528565b600081815260018301602052604081205480156144c8576000614403600183615405565b855490915060009061441790600190615405565b905081811461447c576000866000018281548110614437576144376154ac565b906000526020600020015490508087600001848154811061445a5761445a6154ac565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061448d5761448d615e42565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061075d565b600091505061075d565b5092915050565b60008181526001830160205260408120546145205750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561075d565b50600061075d565b600082600001828154811061453f5761453f6154ac565b9060005260206000200154905092915050565b8280548282559060005260206000209081019282156145cc579160200282015b828111156145cc57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614572565b506112749291505b8082111561127457600081556001016145d4565b60c0810161075d828473ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b67ffffffffffffffff81168114611bc557600080fd5b803561467a81614659565b919050565b60006020828403121561469157600080fd5b813561114981614659565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110614702577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6020810161075d82846146cb565b60005b8381101561472f578181015183820152602001614717565b50506000910152565b60008151808452614750816020860160208601614714565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006111496020830184614738565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156147e7576147e7614795565b60405290565b604051610180810167ffffffffffffffff811182821017156147e7576147e7614795565b6040516080810167ffffffffffffffff811182821017156147e7576147e7614795565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561487b5761487b614795565b604052919050565b600067ffffffffffffffff82111561489d5761489d614795565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611bc557600080fd5b803561467a816148a7565b600082601f8301126148e557600080fd5b813560206148fa6148f583614883565b614834565b82815260059290921b8401810191818101908684111561491957600080fd5b8286015b8481101561493d578035614930816148a7565b835291830191830161491d565b509695505050505050565b803560ff8116811461467a57600080fd5b600067ffffffffffffffff82111561497357614973614795565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149b057600080fd5b81356149be6148f582614959565b8181528460208386010111156149d357600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614a0957600080fd5b863567ffffffffffffffff80821115614a2157600080fd5b614a2d8a838b016148d4565b97506020890135915080821115614a4357600080fd5b614a4f8a838b016148d4565b9650614a5d60408a01614948565b95506060890135915080821115614a7357600080fd5b614a7f8a838b0161499f565b9450614a8d60808a0161466f565b935060a0890135915080821115614aa357600080fd5b50614ab089828a0161499f565b9150509295509295509295565b60008083601f840112614acf57600080fd5b50813567ffffffffffffffff811115614ae757600080fd5b6020830191508360208260061b850101111561235d57600080fd5b60008060008060408587031215614b1857600080fd5b843567ffffffffffffffff80821115614b3057600080fd5b614b3c88838901614abd565b90965094506020870135915080821115614b5557600080fd5b50614b6287828801614abd565b95989497509550505050565b600060208284031215614b8057600080fd5b8135611149816148a7565b600081518084526020808501945080840160005b83811015614bd157815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614b9f565b509495945050505050565b6020815260006111496020830184614b8b565b6020808252825182820181905260009190848201906040850190845b81811015614c3d57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614c0b565b50909695505050505050565b60a0810161075d828463ffffffff808251168352602082015173ffffffffffffffffffffffffffffffffffffffff8082166020860152806040850151166040860152505061ffff6060830151166060840152806080830151166080840152505050565b600060208284031215614cbe57600080fd5b813567ffffffffffffffff811115614cd557600080fd5b820160a0818503121561114957600080fd5b8015158114611bc557600080fd5b803561467a81614ce7565b600082601f830112614d1157600080fd5b81356020614d216148f583614883565b82815260069290921b84018101918181019086841115614d4057600080fd5b8286015b8481101561493d5760408189031215614d5d5760008081fd5b614d656147c4565b8135614d70816148a7565b81528185013585820152835291830191604001614d44565b60006101808284031215614d9b57600080fd5b614da36147ed565b9050614dae8261466f565b8152614dbc6020830161466f565b602082015260408201356040820152614dd7606083016148c9565b6060820152614de86080830161466f565b608082015260a082013560a0820152614e0360c08301614cf5565b60c0820152614e1460e083016148c9565b60e08201526101008083013567ffffffffffffffff80821115614e3657600080fd5b614e428683870161499f565b83850152610120925082850135915080821115614e5e57600080fd5b50614e6b85828601614d00565b828401525050610140614e7f8184016148c9565b818301525061016080830135818301525092915050565b600082601f830112614ea757600080fd5b81356020614eb76148f583614883565b82815260059290921b84018101918181019086841115614ed657600080fd5b8286015b8481101561493d57803567ffffffffffffffff811115614efa5760008081fd5b614f088986838b010161499f565b845250918301918301614eda565b60008060408385031215614f2957600080fd5b823567ffffffffffffffff80821115614f4157600080fd5b614f4d86838701614d88565b93506020850135915080821115614f6357600080fd5b50614f7085828601614e96565b9150509250929050565b60008083601f840112614f8c57600080fd5b50813567ffffffffffffffff811115614fa457600080fd5b6020830191508360208260051b850101111561235d57600080fd5b60008060008060008060008060e0898b031215614fdb57600080fd5b606089018a811115614fec57600080fd5b8998503567ffffffffffffffff8082111561500657600080fd5b818b0191508b601f83011261501a57600080fd5b81358181111561502957600080fd5b8c602082850101111561503b57600080fd5b6020830199508098505060808b013591508082111561505957600080fd5b6150658c838d01614f7a565b909750955060a08b013591508082111561507e57600080fd5b5061508b8b828c01614f7a565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff8116811461467a57600080fd5b6000606082840312156150d657600080fd5b6040516060810181811067ffffffffffffffff821117156150f9576150f9614795565b604052823561510781614ce7565b8152615115602084016150a4565b6020820152615126604084016150a4565b60408201529392505050565b600082601f83011261514357600080fd5b813560206151536148f583614883565b82815260059290921b8401810191818101908684111561517257600080fd5b8286015b8481101561493d57803567ffffffffffffffff8111156151965760008081fd5b6151a48986838b0101614e96565b845250918301918301615176565b600082601f8301126151c357600080fd5b813560206151d36148f583614883565b82815260059290921b840181019181810190868411156151f257600080fd5b8286015b8481101561493d57803583529183019183016151f6565b60006080828403121561521f57600080fd5b615227614811565b9050813567ffffffffffffffff8082111561524157600080fd5b818401915084601f83011261525557600080fd5b813560206152656148f583614883565b82815260059290921b8401810191818101908884111561528457600080fd5b8286015b848110156152bc578035868111156152a05760008081fd5b6152ae8b86838b0101614d88565b845250918301918301615288565b50865250858101359350828411156152d357600080fd5b6152df87858801615132565b908501525060408401359150808211156152f857600080fd5b50615305848285016151b2565b6040830152506060820135606082015292915050565b6000806040838503121561532e57600080fd5b823567ffffffffffffffff8082111561534657600080fd5b6153528683870161520d565b935060209150818501358181111561536957600080fd5b85019050601f8101861361537c57600080fd5b803561538a6148f582614883565b81815260059190911b820183019083810190888311156153a957600080fd5b928401925b828410156153c7578335825292840192908401906153ae565b80955050505050509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561075d5761075d6153d6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061546257615462615418565b92169190910692915050565b808202811582820484141761075d5761075d6153d6565b600067ffffffffffffffff808416806154a0576154a0615418565b92169190910492915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361550c5761550c6153d6565b5060010190565b600063ffffffff80831681810361552c5761552c6153d6565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526155668184018a614b8b565b9050828103608084015261557a8189614b8b565b905060ff871660a084015282810360c08401526155978187614738565b905067ffffffffffffffff851660e08401528281036101008401526155bc8185614738565b9c9b505050505050505050505050565b6000602082840312156155de57600080fd5b8151611149816148a7565b6000602082840312156155fb57600080fd5b815161114981614659565b600081518084526020808501945080840160005b83811015614bd1578151805173ffffffffffffffffffffffffffffffffffffffff168852830151838801526040909601959082019060010161561a565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152615692610120840182614738565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e08601526156ce8383614738565b9250608089015191508085840301610100860152506156ed8282615606565b92505050615701602083018661ffff169052565b836040830152612828606083018473ffffffffffffffffffffffffffffffffffffffff169052565b6000806040838503121561573c57600080fd5b825161574781614ce7565b602084015190925067ffffffffffffffff81111561576457600080fd5b8301601f8101851361577557600080fd5b80516157836148f582614959565b81815286602083850101111561579857600080fd5b6157a9826020830160208601614714565b8093505050509250929050565b8082018082111561075d5761075d6153d6565b805163ffffffff8116811461467a57600080fd5b600060a082840312156157ef57600080fd5b60405160a0810181811067ffffffffffffffff8211171561581257615812614795565b60405261581e836157c9565b8152602083015161582e816148a7565b60208201526040830151615841816148a7565b6040820152606083015161ffff8116811461585b57600080fd5b606082015261586c608084016157c9565b60808201529392505050565b61016081016158ea828573ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b825163ffffffff90811660c0840152602084015173ffffffffffffffffffffffffffffffffffffffff90811660e0850152604085015116610100840152606084015161ffff16610120840152608084015116610140830152611149565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b16604085015281606085015261598e8285018b614b8b565b915083820360808501526159a2828a614b8b565b915060ff881660a085015283820360c08501526159bf8288614738565b90861660e085015283810361010085015290506155bc8185614738565b60a0815260006159ef60a0830188614738565b73ffffffffffffffffffffffffffffffffffffffff8716602084015285604084015267ffffffffffffffff851660608401528281036080840152615a338185614738565b98975050505050505050565b6000815160208301517fffffffff0000000000000000000000000000000000000000000000000000000080821693506004831015615a875780818460040360031b1b83161693505b505050919050565b600060208284031215615aa157600080fd5b813567ffffffffffffffff811115615ab857600080fd5b611b3b8482850161520d565b600060208284031215615ad657600080fd5b815161114981614ce7565b600081518084526020808501945080840160005b83811015614bd157815187529582019590820190600101615af5565b606081526000615b246060830186615ae1565b8281036020840152615b368186615ae1565b915050826040830152949350505050565b600060208284031215615b5957600080fd5b5051919050565b67ffffffffffffffff8181168382160190808211156144d2576144d26153d6565b67ffffffffffffffff831681526040810161114960208301846146cb565b600067ffffffffffffffff80831681810361552c5761552c6153d6565b615bc681846146cb565b604060208201526000611b3b6040830184614738565b600060408284031215615bee57600080fd5b615bf66147c4565b825177ffffffffffffffffffffffffffffffffffffffffffffffff81168114615c1e57600080fd5b81526020830151615c2e81614659565b60208201529392505050565b6020815260006111496020830184615606565b600082825180855260208086019550808260051b84010181860160005b84811015615cb6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952615ca4838351614738565b98840198925090830190600101615c6a565b5090979650505050505050565b60408152615cde60408201845167ffffffffffffffff169052565b60006020840151615cfb606084018267ffffffffffffffff169052565b5060408401516080830152606084015173ffffffffffffffffffffffffffffffffffffffff811660a084015250608084015167ffffffffffffffff811660c08401525060a084015160e083015260c0840151610100615d5d8185018315159052565b60e08601519150610120615d888186018473ffffffffffffffffffffffffffffffffffffffff169052565b81870151925061018091506101408281870152615da96101c0870185614738565b93508188015191506101607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08786030181880152615de78584615606565b9450818901519250615e108488018473ffffffffffffffffffffffffffffffffffffffff169052565b8801516101a087015250505082810360208401526128288185615c4d565b600082615e3d57615e3d615418565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", +} + +var EVM2EVMOffRampABI = EVM2EVMOffRampMetaData.ABI + +var EVM2EVMOffRampBin = EVM2EVMOffRampMetaData.Bin + +func DeployEVM2EVMOffRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMOffRampStaticConfig, sourceTokens []common.Address, pools []common.Address, rateLimiterConfig RateLimiterConfig) (common.Address, *types.Transaction, *EVM2EVMOffRamp, error) { + parsed, err := EVM2EVMOffRampMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMOffRampBin), backend, staticConfig, sourceTokens, pools, rateLimiterConfig) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EVM2EVMOffRamp{EVM2EVMOffRampCaller: EVM2EVMOffRampCaller{contract: contract}, EVM2EVMOffRampTransactor: EVM2EVMOffRampTransactor{contract: contract}, EVM2EVMOffRampFilterer: EVM2EVMOffRampFilterer{contract: contract}}, nil +} + +type EVM2EVMOffRamp struct { + address common.Address + abi abi.ABI + EVM2EVMOffRampCaller + EVM2EVMOffRampTransactor + EVM2EVMOffRampFilterer +} + +type EVM2EVMOffRampCaller struct { + contract *bind.BoundContract +} + +type EVM2EVMOffRampTransactor struct { + contract *bind.BoundContract +} + +type EVM2EVMOffRampFilterer struct { + contract *bind.BoundContract +} + +type EVM2EVMOffRampSession struct { + Contract *EVM2EVMOffRamp + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type EVM2EVMOffRampCallerSession struct { + Contract *EVM2EVMOffRampCaller + CallOpts bind.CallOpts +} + +type EVM2EVMOffRampTransactorSession struct { + Contract *EVM2EVMOffRampTransactor + TransactOpts bind.TransactOpts +} + +type EVM2EVMOffRampRaw struct { + Contract *EVM2EVMOffRamp +} + +type EVM2EVMOffRampCallerRaw struct { + Contract *EVM2EVMOffRampCaller +} + +type EVM2EVMOffRampTransactorRaw struct { + Contract *EVM2EVMOffRampTransactor +} + +func NewEVM2EVMOffRamp(address common.Address, backend bind.ContractBackend) (*EVM2EVMOffRamp, error) { + abi, err := abi.JSON(strings.NewReader(EVM2EVMOffRampABI)) + if err != nil { + return nil, err + } + contract, err := bindEVM2EVMOffRamp(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &EVM2EVMOffRamp{address: address, abi: abi, EVM2EVMOffRampCaller: EVM2EVMOffRampCaller{contract: contract}, EVM2EVMOffRampTransactor: EVM2EVMOffRampTransactor{contract: contract}, EVM2EVMOffRampFilterer: EVM2EVMOffRampFilterer{contract: contract}}, nil +} + +func NewEVM2EVMOffRampCaller(address common.Address, caller bind.ContractCaller) (*EVM2EVMOffRampCaller, error) { + contract, err := bindEVM2EVMOffRamp(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampCaller{contract: contract}, nil +} + +func NewEVM2EVMOffRampTransactor(address common.Address, transactor bind.ContractTransactor) (*EVM2EVMOffRampTransactor, error) { + contract, err := bindEVM2EVMOffRamp(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampTransactor{contract: contract}, nil +} + +func NewEVM2EVMOffRampFilterer(address common.Address, filterer bind.ContractFilterer) (*EVM2EVMOffRampFilterer, error) { + contract, err := bindEVM2EVMOffRamp(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampFilterer{contract: contract}, nil +} + +func bindEVM2EVMOffRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EVM2EVMOffRampMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOffRamp.Contract.EVM2EVMOffRampCaller.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.EVM2EVMOffRampTransactor.contract.Transfer(opts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.EVM2EVMOffRampTransactor.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOffRamp.Contract.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.contract.Transfer(opts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) CcipReceive(opts *bind.CallOpts, arg0 ClientAny2EVMMessage) error { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "ccipReceive", arg0) + + if err != nil { + return err + } + + return err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) CcipReceive(arg0 ClientAny2EVMMessage) error { + return _EVM2EVMOffRamp.Contract.CcipReceive(&_EVM2EVMOffRamp.CallOpts, arg0) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) CcipReceive(arg0 ClientAny2EVMMessage) error { + return _EVM2EVMOffRamp.Contract.CcipReceive(&_EVM2EVMOffRamp.CallOpts, arg0) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "currentRateLimiterState") + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOffRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOffRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetDestinationToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getDestinationToken", sourceToken) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetDestinationToken(sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetDestinationToken(&_EVM2EVMOffRamp.CallOpts, sourceToken) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetDestinationToken(sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetDestinationToken(&_EVM2EVMOffRamp.CallOpts, sourceToken) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetDestinationTokens(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getDestinationTokens") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetDestinationTokens() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetDestinationTokens(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetDestinationTokens() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetDestinationTokens(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOffRampDynamicConfig, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(EVM2EVMOffRampDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOffRampDynamicConfig)).(*EVM2EVMOffRampDynamicConfig) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetDynamicConfig() (EVM2EVMOffRampDynamicConfig, error) { + return _EVM2EVMOffRamp.Contract.GetDynamicConfig(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetDynamicConfig() (EVM2EVMOffRampDynamicConfig, error) { + return _EVM2EVMOffRamp.Contract.GetDynamicConfig(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetExecutionState(opts *bind.CallOpts, sequenceNumber uint64) (uint8, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getExecutionState", sequenceNumber) + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetExecutionState(sequenceNumber uint64) (uint8, error) { + return _EVM2EVMOffRamp.Contract.GetExecutionState(&_EVM2EVMOffRamp.CallOpts, sequenceNumber) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetExecutionState(sequenceNumber uint64) (uint8, error) { + return _EVM2EVMOffRamp.Contract.GetExecutionState(&_EVM2EVMOffRamp.CallOpts, sequenceNumber) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetPoolByDestToken(opts *bind.CallOpts, destToken common.Address) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getPoolByDestToken", destToken) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetPoolByDestToken(destToken common.Address) (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetPoolByDestToken(&_EVM2EVMOffRamp.CallOpts, destToken) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetPoolByDestToken(destToken common.Address) (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetPoolByDestToken(&_EVM2EVMOffRamp.CallOpts, destToken) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetPoolBySourceToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getPoolBySourceToken", sourceToken) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetPoolBySourceToken(sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetPoolBySourceToken(&_EVM2EVMOffRamp.CallOpts, sourceToken) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetPoolBySourceToken(sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetPoolBySourceToken(&_EVM2EVMOffRamp.CallOpts, sourceToken) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getSenderNonce", sender) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOffRamp.Contract.GetSenderNonce(&_EVM2EVMOffRamp.CallOpts, sender) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOffRamp.Contract.GetSenderNonce(&_EVM2EVMOffRamp.CallOpts, sender) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOffRampStaticConfig, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(EVM2EVMOffRampStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOffRampStaticConfig)).(*EVM2EVMOffRampStaticConfig) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetStaticConfig() (EVM2EVMOffRampStaticConfig, error) { + return _EVM2EVMOffRamp.Contract.GetStaticConfig(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetStaticConfig() (EVM2EVMOffRampStaticConfig, error) { + return _EVM2EVMOffRamp.Contract.GetStaticConfig(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetSupportedTokens(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getSupportedTokens") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetSupportedTokens() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetSupportedTokens(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetSupportedTokens() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetSupportedTokens(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getTokenLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetTransmitters() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetTransmitters(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetTransmitters() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetTransmitters(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _EVM2EVMOffRamp.Contract.LatestConfigDetails(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _EVM2EVMOffRamp.Contract.LatestConfigDetails(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _EVM2EVMOffRamp.Contract.LatestConfigDigestAndEpoch(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _EVM2EVMOffRamp.Contract.LatestConfigDigestAndEpoch(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) Owner() (common.Address, error) { + return _EVM2EVMOffRamp.Contract.Owner(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) Owner() (common.Address, error) { + return _EVM2EVMOffRamp.Contract.Owner(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) TypeAndVersion() (string, error) { + return _EVM2EVMOffRamp.Contract.TypeAndVersion(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) TypeAndVersion() (string, error) { + return _EVM2EVMOffRamp.Contract.TypeAndVersion(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "acceptOwnership") +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.AcceptOwnership(&_EVM2EVMOffRamp.TransactOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.AcceptOwnership(&_EVM2EVMOffRamp.TransactOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) ApplyPoolUpdates(opts *bind.TransactOpts, removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "applyPoolUpdates", removes, adds) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) ApplyPoolUpdates(removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ApplyPoolUpdates(&_EVM2EVMOffRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) ApplyPoolUpdates(removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ApplyPoolUpdates(&_EVM2EVMOffRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) ExecuteSingleMessage(opts *bind.TransactOpts, message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "executeSingleMessage", message, offchainTokenData) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) ExecuteSingleMessage(message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMOffRamp.TransactOpts, message, offchainTokenData) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) ExecuteSingleMessage(message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMOffRamp.TransactOpts, message, offchainTokenData) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) ManuallyExecute(opts *bind.TransactOpts, report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "manuallyExecute", report, gasLimitOverrides) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) ManuallyExecute(report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ManuallyExecute(&_EVM2EVMOffRamp.TransactOpts, report, gasLimitOverrides) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) ManuallyExecute(report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ManuallyExecute(&_EVM2EVMOffRamp.TransactOpts, report, gasLimitOverrides) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "setAdmin", newAdmin) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetAdmin(&_EVM2EVMOffRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetAdmin(&_EVM2EVMOffRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "setOCR2Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetOCR2Config(&_EVM2EVMOffRamp.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetOCR2Config(&_EVM2EVMOffRamp.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "setRateLimiterConfig", config) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOffRamp.TransactOpts, config) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOffRamp.TransactOpts, config) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "transferOwnership", to) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.TransferOwnership(&_EVM2EVMOffRamp.TransactOpts, to) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.TransferOwnership(&_EVM2EVMOffRamp.TransactOpts, to) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "transmit", reportContext, report, rs, ss, arg4) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.Transmit(&_EVM2EVMOffRamp.TransactOpts, reportContext, report, rs, ss, arg4) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.Transmit(&_EVM2EVMOffRamp.TransactOpts, reportContext, report, rs, ss, arg4) +} + +type EVM2EVMOffRampAdminSetIterator struct { + Event *EVM2EVMOffRampAdminSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampAdminSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampAdminSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampAdminSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampAdminSet struct { + NewAdmin common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOffRampAdminSetIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampAdminSetIterator{contract: _EVM2EVMOffRamp.contract, event: "AdminSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampAdminSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampAdminSet) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseAdminSet(log types.Log) (*EVM2EVMOffRampAdminSet, error) { + event := new(EVM2EVMOffRampAdminSet) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampConfigSetIterator struct { + Event *EVM2EVMOffRampConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampConfigSet struct { + StaticConfig EVM2EVMOffRampStaticConfig + DynamicConfig EVM2EVMOffRampDynamicConfig + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampConfigSetIterator{contract: _EVM2EVMOffRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampConfigSet) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseConfigSet(log types.Log) (*EVM2EVMOffRampConfigSet, error) { + event := new(EVM2EVMOffRampConfigSet) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampConfigSet0Iterator struct { + Event *EVM2EVMOffRampConfigSet0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampConfigSet0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampConfigSet0Iterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampConfigSet0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampConfigSet0 struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterConfigSet0(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigSet0Iterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampConfigSet0Iterator{contract: _EVM2EVMOffRamp.contract, event: "ConfigSet0", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigSet0) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampConfigSet0) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseConfigSet0(log types.Log) (*EVM2EVMOffRampConfigSet0, error) { + event := new(EVM2EVMOffRampConfigSet0) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampExecutionStateChangedIterator struct { + Event *EVM2EVMOffRampExecutionStateChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampExecutionStateChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampExecutionStateChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampExecutionStateChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampExecutionStateChangedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampExecutionStateChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampExecutionStateChanged struct { + SequenceNumber uint64 + MessageId [32]byte + State uint8 + ReturnData []byte + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterExecutionStateChanged(opts *bind.FilterOpts, sequenceNumber []uint64, messageId [][32]byte) (*EVM2EVMOffRampExecutionStateChangedIterator, error) { + + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + var messageIdRule []interface{} + for _, messageIdItem := range messageId { + messageIdRule = append(messageIdRule, messageIdItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "ExecutionStateChanged", sequenceNumberRule, messageIdRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampExecutionStateChangedIterator{contract: _EVM2EVMOffRamp.contract, event: "ExecutionStateChanged", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampExecutionStateChanged, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) { + + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + var messageIdRule []interface{} + for _, messageIdItem := range messageId { + messageIdRule = append(messageIdRule, messageIdItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "ExecutionStateChanged", sequenceNumberRule, messageIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampExecutionStateChanged) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseExecutionStateChanged(log types.Log) (*EVM2EVMOffRampExecutionStateChanged, error) { + event := new(EVM2EVMOffRampExecutionStateChanged) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampOwnershipTransferRequestedIterator struct { + Event *EVM2EVMOffRampOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOffRampOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampOwnershipTransferRequestedIterator{contract: _EVM2EVMOffRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampOwnershipTransferRequested) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOffRampOwnershipTransferRequested, error) { + event := new(EVM2EVMOffRampOwnershipTransferRequested) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampOwnershipTransferredIterator struct { + Event *EVM2EVMOffRampOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOffRampOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampOwnershipTransferredIterator{contract: _EVM2EVMOffRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampOwnershipTransferred) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseOwnershipTransferred(log types.Log) (*EVM2EVMOffRampOwnershipTransferred, error) { + event := new(EVM2EVMOffRampOwnershipTransferred) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampPoolAddedIterator struct { + Event *EVM2EVMOffRampPoolAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampPoolAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampPoolAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampPoolAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampPoolAddedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampPoolAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampPoolAdded struct { + Token common.Address + Pool common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterPoolAdded(opts *bind.FilterOpts) (*EVM2EVMOffRampPoolAddedIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "PoolAdded") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampPoolAddedIterator{contract: _EVM2EVMOffRamp.contract, event: "PoolAdded", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchPoolAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampPoolAdded) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "PoolAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampPoolAdded) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "PoolAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParsePoolAdded(log types.Log) (*EVM2EVMOffRampPoolAdded, error) { + event := new(EVM2EVMOffRampPoolAdded) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "PoolAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampPoolRemovedIterator struct { + Event *EVM2EVMOffRampPoolRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampPoolRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampPoolRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampPoolRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampPoolRemovedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampPoolRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampPoolRemoved struct { + Token common.Address + Pool common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterPoolRemoved(opts *bind.FilterOpts) (*EVM2EVMOffRampPoolRemovedIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "PoolRemoved") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampPoolRemovedIterator{contract: _EVM2EVMOffRamp.contract, event: "PoolRemoved", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchPoolRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampPoolRemoved) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "PoolRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampPoolRemoved) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "PoolRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParsePoolRemoved(log types.Log) (*EVM2EVMOffRampPoolRemoved, error) { + event := new(EVM2EVMOffRampPoolRemoved) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "PoolRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampSkippedIncorrectNonceIterator struct { + Event *EVM2EVMOffRampSkippedIncorrectNonce + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampSkippedIncorrectNonceIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedIncorrectNonce) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedIncorrectNonce) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampSkippedIncorrectNonceIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampSkippedIncorrectNonceIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampSkippedIncorrectNonce struct { + Nonce uint64 + Sender common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterSkippedIncorrectNonce(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*EVM2EVMOffRampSkippedIncorrectNonceIterator, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "SkippedIncorrectNonce", nonceRule, senderRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampSkippedIncorrectNonceIterator{contract: _EVM2EVMOffRamp.contract, event: "SkippedIncorrectNonce", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedIncorrectNonce, nonce []uint64, sender []common.Address) (event.Subscription, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "SkippedIncorrectNonce", nonceRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampSkippedIncorrectNonce) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedIncorrectNonce", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseSkippedIncorrectNonce(log types.Log) (*EVM2EVMOffRampSkippedIncorrectNonce, error) { + event := new(EVM2EVMOffRampSkippedIncorrectNonce) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedIncorrectNonce", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator struct { + Event *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight struct { + Nonce uint64 + Sender common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterSkippedSenderWithPreviousRampMessageInflight(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "SkippedSenderWithPreviousRampMessageInflight", nonceRule, senderRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator{contract: _EVM2EVMOffRamp.contract, event: "SkippedSenderWithPreviousRampMessageInflight", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchSkippedSenderWithPreviousRampMessageInflight(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, nonce []uint64, sender []common.Address) (event.Subscription, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "SkippedSenderWithPreviousRampMessageInflight", nonceRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedSenderWithPreviousRampMessageInflight", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseSkippedSenderWithPreviousRampMessageInflight(log types.Log) (*EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error) { + event := new(EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedSenderWithPreviousRampMessageInflight", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampTransmittedIterator struct { + Event *EVM2EVMOffRampTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampTransmittedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterTransmitted(opts *bind.FilterOpts) (*EVM2EVMOffRampTransmittedIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampTransmittedIterator{contract: _EVM2EVMOffRamp.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampTransmitted) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampTransmitted) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseTransmitted(log types.Log) (*EVM2EVMOffRampTransmitted, error) { + event := new(EVM2EVMOffRampTransmitted) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _EVM2EVMOffRamp.abi.Events["AdminSet"].ID: + return _EVM2EVMOffRamp.ParseAdminSet(log) + case _EVM2EVMOffRamp.abi.Events["ConfigSet"].ID: + return _EVM2EVMOffRamp.ParseConfigSet(log) + case _EVM2EVMOffRamp.abi.Events["ConfigSet0"].ID: + return _EVM2EVMOffRamp.ParseConfigSet0(log) + case _EVM2EVMOffRamp.abi.Events["ExecutionStateChanged"].ID: + return _EVM2EVMOffRamp.ParseExecutionStateChanged(log) + case _EVM2EVMOffRamp.abi.Events["OwnershipTransferRequested"].ID: + return _EVM2EVMOffRamp.ParseOwnershipTransferRequested(log) + case _EVM2EVMOffRamp.abi.Events["OwnershipTransferred"].ID: + return _EVM2EVMOffRamp.ParseOwnershipTransferred(log) + case _EVM2EVMOffRamp.abi.Events["PoolAdded"].ID: + return _EVM2EVMOffRamp.ParsePoolAdded(log) + case _EVM2EVMOffRamp.abi.Events["PoolRemoved"].ID: + return _EVM2EVMOffRamp.ParsePoolRemoved(log) + case _EVM2EVMOffRamp.abi.Events["SkippedIncorrectNonce"].ID: + return _EVM2EVMOffRamp.ParseSkippedIncorrectNonce(log) + case _EVM2EVMOffRamp.abi.Events["SkippedSenderWithPreviousRampMessageInflight"].ID: + return _EVM2EVMOffRamp.ParseSkippedSenderWithPreviousRampMessageInflight(log) + case _EVM2EVMOffRamp.abi.Events["Transmitted"].ID: + return _EVM2EVMOffRamp.ParseTransmitted(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (EVM2EVMOffRampAdminSet) Topic() common.Hash { + return common.HexToHash("0x8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c") +} + +func (EVM2EVMOffRampConfigSet) Topic() common.Hash { + return common.HexToHash("0x737ef22d3f6615e342ed21c69e06620dbc5c8a261ed7cfb2ce214806b1f76eda") +} + +func (EVM2EVMOffRampConfigSet0) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (EVM2EVMOffRampExecutionStateChanged) Topic() common.Hash { + return common.HexToHash("0xd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef65") +} + +func (EVM2EVMOffRampOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (EVM2EVMOffRampOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (EVM2EVMOffRampPoolAdded) Topic() common.Hash { + return common.HexToHash("0x95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c") +} + +func (EVM2EVMOffRampPoolRemoved) Topic() common.Hash { + return common.HexToHash("0x987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c") +} + +func (EVM2EVMOffRampSkippedIncorrectNonce) Topic() common.Hash { + return common.HexToHash("0xd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf41237") +} + +func (EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) Topic() common.Hash { + return common.HexToHash("0xe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d") +} + +func (EVM2EVMOffRampTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRamp) Address() common.Address { + return _EVM2EVMOffRamp.address +} + +type EVM2EVMOffRampInterface interface { + CcipReceive(opts *bind.CallOpts, arg0 ClientAny2EVMMessage) error + + CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) + + GetDestinationToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) + + GetDestinationTokens(opts *bind.CallOpts) ([]common.Address, error) + + GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOffRampDynamicConfig, error) + + GetExecutionState(opts *bind.CallOpts, sequenceNumber uint64) (uint8, error) + + GetPoolByDestToken(opts *bind.CallOpts, destToken common.Address) (common.Address, error) + + GetPoolBySourceToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) + + GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) + + GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOffRampStaticConfig, error) + + GetSupportedTokens(opts *bind.CallOpts) ([]common.Address, error) + + GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) + + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyPoolUpdates(opts *bind.TransactOpts, removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) + + ExecuteSingleMessage(opts *bind.TransactOpts, message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) + + ManuallyExecute(opts *bind.TransactOpts, report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) + + SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) + + SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) + + FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOffRampAdminSetIterator, error) + + WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampAdminSet) (event.Subscription, error) + + ParseAdminSet(log types.Log) (*EVM2EVMOffRampAdminSet, error) + + FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*EVM2EVMOffRampConfigSet, error) + + FilterConfigSet0(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigSet0Iterator, error) + + WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigSet0) (event.Subscription, error) + + ParseConfigSet0(log types.Log) (*EVM2EVMOffRampConfigSet0, error) + + FilterExecutionStateChanged(opts *bind.FilterOpts, sequenceNumber []uint64, messageId [][32]byte) (*EVM2EVMOffRampExecutionStateChangedIterator, error) + + WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampExecutionStateChanged, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) + + ParseExecutionStateChanged(log types.Log) (*EVM2EVMOffRampExecutionStateChanged, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOffRampOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOffRampOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOffRampOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*EVM2EVMOffRampOwnershipTransferred, error) + + FilterPoolAdded(opts *bind.FilterOpts) (*EVM2EVMOffRampPoolAddedIterator, error) + + WatchPoolAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampPoolAdded) (event.Subscription, error) + + ParsePoolAdded(log types.Log) (*EVM2EVMOffRampPoolAdded, error) + + FilterPoolRemoved(opts *bind.FilterOpts) (*EVM2EVMOffRampPoolRemovedIterator, error) + + WatchPoolRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampPoolRemoved) (event.Subscription, error) + + ParsePoolRemoved(log types.Log) (*EVM2EVMOffRampPoolRemoved, error) + + FilterSkippedIncorrectNonce(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*EVM2EVMOffRampSkippedIncorrectNonceIterator, error) + + WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedIncorrectNonce, nonce []uint64, sender []common.Address) (event.Subscription, error) + + ParseSkippedIncorrectNonce(log types.Log) (*EVM2EVMOffRampSkippedIncorrectNonce, error) + + FilterSkippedSenderWithPreviousRampMessageInflight(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error) + + WatchSkippedSenderWithPreviousRampMessageInflight(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, nonce []uint64, sender []common.Address) (event.Subscription, error) + + ParseSkippedSenderWithPreviousRampMessageInflight(log types.Log) (*EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error) + + FilterTransmitted(opts *bind.FilterOpts) (*EVM2EVMOffRampTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*EVM2EVMOffRampTransmitted, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0/evm_2_evm_offramp_1_2_0.go b/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0/evm_2_evm_offramp_1_2_0.go new file mode 100644 index 0000000000..beeaee1bb7 --- /dev/null +++ b/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0/evm_2_evm_offramp_1_2_0.go @@ -0,0 +1,2356 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package evm_2_evm_offramp_1_2_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientAny2EVMMessage struct { + MessageId [32]byte + SourceChainSelector uint64 + Sender []byte + Data []byte + DestTokenAmounts []ClientEVMTokenAmount +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type EVM2EVMOffRampDynamicConfig struct { + PermissionLessExecutionThresholdSeconds uint32 + Router common.Address + PriceRegistry common.Address + MaxNumberOfTokensPerMsg uint16 + MaxDataBytes uint32 + MaxPoolReleaseOrMintGas uint32 +} + +type EVM2EVMOffRampStaticConfig struct { + CommitStore common.Address + ChainSelector uint64 + SourceChainSelector uint64 + OnRamp common.Address + PrevOffRamp common.Address + ArmProxy common.Address +} + +type InternalEVM2EVMMessage struct { + SourceChainSelector uint64 + Sender common.Address + Receiver common.Address + SequenceNumber uint64 + GasLimit *big.Int + Strict bool + Nonce uint64 + FeeToken common.Address + FeeTokenAmount *big.Int + Data []byte + TokenAmounts []ClientEVMTokenAmount + SourceTokenData [][]byte + MessageId [32]byte +} + +type InternalExecutionReport struct { + Messages []InternalEVM2EVMMessage + OffchainTokenData [][][]byte + Proofs [][32]byte + ProofFlagBits *big.Int +} + +type InternalPoolUpdate struct { + Token common.Address + Pool common.Address +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +var EVM2EVMOffRampMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"contractIERC20[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"contractIPool[]\",\"name\":\"pools\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getDestinationToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDestinationTokens\",\"outputs\":[{\"internalType\":\"contractIERC20[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"getPoolByDestToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"contractIERC20[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101806040523480156200001257600080fd5b5060405162006ac338038062006ac3833981016040819052620000359162000891565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c08162000478565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080938401819052600380546001600160a01b031916909517600160801b9384021760ff60a01b1916600160a01b90920291909117909355909102909217600455504690528151835114620001705760405162d8548360e71b815260040160405180910390fd5b60608401516001600160a01b0316158062000193575083516001600160a01b0316155b15620001b2576040516342bcdf7f60e11b815260040160405180910390fd5b83600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200021b9190620009a8565b6001600160401b03166001146200024557604051636fc2a20760e11b815260040160405180910390fd5b83516001600160a01b0390811660a090815260408601516001600160401b0390811660c05260208701511660e052606086015182166101005260808601518216610140528501511661016052620002bc7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000523565b6101205260005b83518110156200046d576200031d848281518110620002e657620002e6620009c6565b6020026020010151848381518110620003035762000303620009c6565b6020026020010151600c6200058a60201b9092919060201c565b50620003d2838281518110620003375762000337620009c6565b60200260200101516001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200037d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a39190620009dc565b848381518110620003b857620003b8620009c6565b6020026020010151600f6200058a60201b9092919060201c565b507f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c848281518110620004095762000409620009c6565b6020026020010151848381518110620004265762000426620009c6565b6020026020010151604051620004529291906001600160a01b0392831681529116602082015260400190565b60405180910390a1620004658162000a03565b9050620002c3565b505050505062000a2b565b336001600160a01b03821603620004d25760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e051610100516040516020016200056d94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b6000620005a2846001600160a01b03851684620005aa565b949350505050565b6000620005a284846001600160a01b03851660008281526002840160205260408120829055620005a284846000620005e38383620005ec565b90505b92915050565b60008181526001830160205260408120546200063557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005e6565b506000620005e6565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156200067957620006796200063e565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006aa57620006aa6200063e565b604052919050565b6001600160a01b0381168114620006c857600080fd5b50565b80516001600160401b0381168114620006e357600080fd5b919050565b60006001600160401b038211156200070457620007046200063e565b5060051b60200190565b600082601f8301126200072057600080fd5b81516020620007396200073383620006e8565b6200067f565b82815260059290921b840181019181810190868411156200075957600080fd5b8286015b84811015620007815780516200077381620006b2565b83529183019183016200075d565b509695505050505050565b600082601f8301126200079e57600080fd5b81516020620007b16200073383620006e8565b82815260059290921b84018101918181019086841115620007d157600080fd5b8286015b8481101562000781578051620007eb81620006b2565b8352918301918301620007d5565b80516001600160801b0381168114620006e357600080fd5b6000606082840312156200082457600080fd5b604051606081016001600160401b03811182821017156200084957620008496200063e565b8060405250809150825180151581146200086257600080fd5b81526200087260208401620007f9565b60208201526200088560408401620007f9565b60408201525092915050565b600080600080848603610160811215620008aa57600080fd5b60c0811215620008b957600080fd5b50620008c462000654565b8551620008d181620006b2565b8152620008e160208701620006cb565b6020820152620008f460408701620006cb565b604082015260608601516200090981620006b2565b606082015260808601516200091e81620006b2565b608082015260a08601516200093381620006b2565b60a082015260c08601519094506001600160401b03808211156200095657600080fd5b62000964888389016200070e565b945060e08701519150808211156200097b57600080fd5b506200098a878288016200078c565b9250506200099d86610100870162000811565b905092959194509250565b600060208284031215620009bb57600080fd5b620005e382620006cb565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009ef57600080fd5b8151620009fc81620006b2565b9392505050565b60006001820162000a2457634e487b7160e01b600052601160045260246000fd5b5060010190565b60805160a05160c05160e05161010051610120516101405161016051615fbb62000b08600039600081816103090152818161211a01526123c40152600081816102cd0152818161164e015281816116d0015281816120f30152818161293a01526129c10152600061257d01526000818161029101526120c90152600081816102310152612077015260008181610261015281816120a10152818161315b01526136f80152600081816101f5015281816120490152612672015260008181611397015281816113e30152818161179101526117dd0152615fbb6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806379ba5097116100ee578063b1dc65a411610097578063d3c7c2c711610071578063d3c7c2c7146106d3578063d7e2bb50146106db578063f2fde38b146106ee578063f52121a51461070157600080fd5b8063b1dc65a41461069a578063b4069b31146106ad578063c92b2832146106c057600080fd5b8063856c8247116100c8578063856c8247146106305780638da5cb5b1461065c578063afcb95d71461067a57600080fd5b806379ba5097146105ea57806381ff7048146105f257806385572ffb1461062257600080fd5b8063599f64311161015b578063681fba1611610135578063681fba16146104b8578063704b6c02146104cd578063740f4150146104e05780637437ff9f146104f357600080fd5b8063599f6431146104515780635d86f14114610490578063666cab8d146104a357600080fd5b80631ef381741161018c5780631ef38174146103c55780633a87ac53146103da578063546719cd146103ed57600080fd5b806306285c69146101b3578063142a98fc1461035c578063181f5a771461037c575b600080fd5b6103466040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526040518060c001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516103539190614693565b60405180910390f35b61036f61036a36600461472a565b610714565b60405161035391906147b1565b6103b86040518060400160405280601481526020017f45564d3245564d4f666652616d7020312e322e3000000000000000000000000081525081565b604051610353919061482d565b6103d86103d3366004614a9b565b61078f565b005b6103d86103e8366004614bad565b610c4e565b6103f561105e565b604051610353919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610353565b61046b61049e366004614c19565b611113565b6104ab61117c565b6040516103539190614c87565b6104c06111eb565b6040516103539190614c9a565b6103d86104db366004614c19565b6112a4565b6103d86104ee366004615133565b611394565b6105dd6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c081018252600a5463ffffffff808216835273ffffffffffffffffffffffffffffffffffffffff64010000000090920482166020840152600b549182169383019390935261ffff7401000000000000000000000000000000000000000082041660608301527601000000000000000000000000000000000000000000008104831660808301527a010000000000000000000000000000000000000000000000000000900490911660a082015290565b60405161035391906151ee565b6103d8611516565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610353565b6103d86101ae36600461525d565b61064361063e366004614c19565b611613565b60405167ffffffffffffffff9091168152602001610353565b60005473ffffffffffffffffffffffffffffffffffffffff1661046b565b604080516001815260006020820181905291810191909152606001610353565b6103d86106a83660046152dd565b61173b565b61046b6106bb366004614c19565b6119cc565b6103d86106ce3660046153e2565b611a45565b6104c0611aca565b61046b6106e9366004614c19565b611b7f565b6103d86106fc366004614c19565b611b8e565b6103d861070f366004615450565b611b9f565b6000610722600160046154e3565b600261072f608085615525565b67ffffffffffffffff16610743919061554c565b60136000610752608087615563565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c16600381111561078957610789614747565b92915050565b84518460ff16601f821115610805576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f6f206d616e79207472616e736d697474657273000000000000000000000060448201526064015b60405180910390fd5b8060000361086f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f736974697665000000000000000000000000000060448201526064016107fc565b610877611dfa565b61088085611e7d565b60095460005b8181101561090c5760086000600983815481106108a5576108a561558a565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055610905816155b9565b9050610886565b50875160005b81811015610b085760008a828151811061092e5761092e61558a565b602002602001015190506000600281111561094b5761094b614747565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260086020526040902054610100900460ff16600281111561098a5761098a614747565b146109f1576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d697474657220616464726573730000000060448201526064016107fc565b73ffffffffffffffffffffffffffffffffffffffff8116610a3e576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610aee57610aee614747565b02179055509050505080610b01906155b9565b9050610912565b508851610b1c9060099060208c01906145fd565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908b161717905560078054610ba2914691309190600090610b749063ffffffff166155f1565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168d8d8d8d8d8d61217e565b6005600001819055506000600760049054906101000a900463ffffffff16905043600760046101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600560000154600760009054906101000a900463ffffffff168e8e8e8e8e8e604051610c3999989796959493929190615614565b60405180910390a15050505050505050505050565b610c56611dfa565b60005b83811015610e55576000858583818110610c7557610c7561558a565b610c8b9260206040909202019081019150614c19565b90506000868684818110610ca157610ca161558a565b9050604002016020016020810190610cb99190614c19565b9050610cc6600c83612229565b610cfc576040517f9c8787c000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610d1e600c8461224b565b73ffffffffffffffffffffffffffffffffffffffff1614610d6b576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d76600c8361226d565b50610df18173ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de991906156aa565b600f9061226d565b506040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a1505080610e4e906155b9565b9050610c59565b5060005b81811015611057576000838383818110610e7557610e7561558a565b610e8b9260206040909202019081019150614c19565b90506000848484818110610ea157610ea161558a565b9050604002016020016020810190610eb99190614c19565b905073ffffffffffffffffffffffffffffffffffffffff82161580610ef2575073ffffffffffffffffffffffffffffffffffffffff8116155b15610f29576040517f6c2a418000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f34600c83612229565b15610f6b576040517f3caf458500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f77600c838361228f565b50610ff38173ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fea91906156aa565b600f908361228f565b506040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a1505080611050906155b9565b9050610e59565b5050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff16151593830193909352600454808416606084015204909116608082015261110e906122ba565b905090565b60008080611122600c8561236c565b9150915081611175576040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016107fc565b9392505050565b606060098054806020026020016040519081016040528092919081815260200182805480156111e157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116111b6575b5050505050905090565b60606111f7600f61239b565b67ffffffffffffffff81111561120f5761120f614840565b604051908082528060200260200182016040528015611238578160200160208202803683370190505b50905060005b81518110156112a0576000611254600f836123a6565b5090508083838151811061126a5761126a61558a565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250611299816155b9565b905061123e565b5090565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906112e4575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561131b576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b467f00000000000000000000000000000000000000000000000000000000000000001461141f576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015267ffffffffffffffff461660248201526044016107fc565b8151518151811461145c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8181101561150657600083828151811061147b5761147b61558a565b60200260200101519050806000141580156114b4575084518051839081106114a5576114a561558a565b60200260200101516080015181105b156114f5576040517f085e39cf00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016107fc565b506114ff816155b9565b905061145f565b5061151183836123c2565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611597576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107fc565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b73ffffffffffffffffffffffffffffffffffffffff811660009081526012602052604081205467ffffffffffffffff168015801561168657507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615155b15610789576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611717573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117591906156c7565b6117458787612d89565b60055488359080821461178e576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016107fc565b467f00000000000000000000000000000000000000000000000000000000000000001461180f576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107fc565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561189757611897614747565b60028111156118a8576118a8614747565b90525090506002816020015160028111156118c5576118c5614747565b14801561190c57506009816000015160ff16815481106118e7576118e761558a565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611942576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061195085602061554c565b61195b88602061554c565b6119678b6101446156e4565b61197191906156e4565b61197b91906156e4565b90503681146119bf576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107fc565b5050505050505050505050565b60006119d782611113565b73ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a21573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078991906156aa565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611a85575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15611abc576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ac7600382612db0565b50565b6060611ad6600c61239b565b67ffffffffffffffff811115611aee57611aee614840565b604051908082528060200260200182016040528015611b17578160200160208202803683370190505b50905060005b81518110156112a0576000611b33600c836123a6565b50905080838381518110611b4957611b4961558a565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250611b78816155b9565b9050611b1d565b60008080611122600f8561236c565b611b96611dfa565b611ac781612f95565b333014611bd8576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611c15565b6040805180820190915260008082526020820152815260200190600190039081611bee5790505b506101408401515190915015611c8257611c7f8361014001518460200151604051602001611c5f919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405160208183030381529060405285604001518661016001518661308a565b90505b604083015173ffffffffffffffffffffffffffffffffffffffff163b1580611cec57506040830151611cea9073ffffffffffffffffffffffffffffffffffffffff167f85572ffb00000000000000000000000000000000000000000000000000000000613415565b155b15611cf657505050565b600a546000908190640100000000900473ffffffffffffffffffffffffffffffffffffffff16633cf97983611d2b8786613431565b611388886080015189604001516040518563ffffffff1660e01b8152600401611d579493929190615748565b6000604051808303816000875af1158015611d76573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611dbc919081019061581a565b50915091508161105757806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107fc919061482d565b60005473ffffffffffffffffffffffffffffffffffffffff163314611e7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107fc565b565b600081806020019051810190611e9391906158c4565b602081015190915073ffffffffffffffffffffffffffffffffffffffff16611ee7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090931663ffffffff9586161792909217909255604080850151600b80546060808901516080808b015160a0808d01518c167a010000000000000000000000000000000000000000000000000000027fffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffff92909c1676010000000000000000000000000000000000000000000002919091167fffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffff61ffff90941674010000000000000000000000000000000000000000027fffffffffffffffffffff00000000000000000000000000000000000000000000909616978a169790971794909417919091169490941797909717909155825160c0810184527f00000000000000000000000000000000000000000000000000000000000000008516815267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116968201969096527f0000000000000000000000000000000000000000000000000000000000000000909516858401527f00000000000000000000000000000000000000000000000000000000000000008416958501959095527f00000000000000000000000000000000000000000000000000000000000000008316908401527f00000000000000000000000000000000000000000000000000000000000000009091169282019290925290517fe668e1a4644c1a030b909bbfd837f5cfa914994ed5e0bb2e9c34a5c37753128a91612172918490615970565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a6040516020016121a299989796959493929190615a4c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b60006111758373ffffffffffffffffffffffffffffffffffffffff84166134e1565b60006111758373ffffffffffffffffffffffffffffffffffffffff84166134ed565b60006111758373ffffffffffffffffffffffffffffffffffffffff84166134f9565b60006122b28473ffffffffffffffffffffffffffffffffffffffff851684613505565b949350505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261234882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261232c91906154e3565b85608001516fffffffffffffffffffffffffffffffff16613528565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60008061238f8473ffffffffffffffffffffffffffffffffffffffff8516613547565b915091505b9250929050565b600061078982613556565b60008080806123b58686613561565b9097909650945050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561242d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124519190615ae1565b15612488576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81515160008190036124c5576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114612503576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561251e5761251e614840565b604051908082528060200260200182016040528015612547578160200160208202803683370190505b50905060005b828110156126275760008560000151828151811061256d5761256d61558a565b602002602001015190506125a1817f0000000000000000000000000000000000000000000000000000000000000000613570565b8383815181106125b3576125b361558a565b6020026020010181815250508061018001518383815181106125d7576125d761558a565b602002602001015114612616576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50612620816155b9565b905061254d565b50604080850151606086015191517f3204887500000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926332048875926126a892879291600401615b2e565b602060405180830381865afa1580156126c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e99190615b64565b905080600003612725576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b84811015612d805760008760000151828151811061274c5761274c61558a565b6020026020010151905060006127658260600151610714565b9050600081600381111561277b5761277b614747565b14806127985750600381600381111561279657612796614747565b145b6127e05760608201516040517f50a6e05200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107fc565b831561289d57600a5460009063ffffffff166127fc87426154e3565b119050808061281c5750600382600381111561281a5761281a614747565b145b612852576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8884815181106128645761286461558a565b6020026020010151600014612897578884815181106128855761288561558a565b60200260200101518360800181815250505b506128fa565b60008160038111156128b1576128b1614747565b146128fa5760608201516040517f67d9ba0f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107fc565b60208083015173ffffffffffffffffffffffffffffffffffffffff1660009081526012909152604090205467ffffffffffffffff168015801561297257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615155b15612b155760208301516040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa158015612a0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a2e91906156c7565b60c084015190915067ffffffffffffffff16612a4b826001615b7d565b67ffffffffffffffff1614612ab857826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a3505050612d70565b60208381015173ffffffffffffffffffffffffffffffffffffffff16600090815260129091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b6000826003811115612b2957612b29614747565b03612bb55760c083015167ffffffffffffffff16612b48826001615b7d565b67ffffffffffffffff1614612bb557826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a3505050612d70565b60008a602001518581518110612bcd57612bcd61558a565b60200260200101519050612bf984606001518560000151866101400151518761012001515185516136f6565b612c08846060015160016138a0565b600080612c15868461394a565b91509150612c278660600151836138a0565b6003826003811115612c3b57612c3b614747565b14158015612c5b57506002826003811115612c5857612c58614747565b14155b15612c9a578560600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016107fc929190615b9e565b6000856003811115612cae57612cae614747565b03612d1b5760208087015173ffffffffffffffffffffffffffffffffffffffff166000908152601290915260408120805467ffffffffffffffff1691612cf383615bbc565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b856101800151866060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef658484604051612d61929190615bd9565b60405180910390a35050505050505b612d79816155b9565b905061272c565b50505050505050565b612dac612d9882840184615bf9565b6040805160008152602081019091526123c2565b5050565b8154600090612dd990700100000000000000000000000000000000900463ffffffff16426154e3565b90508015612e7b5760018301548354612e21916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416613528565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612ea1916fffffffffffffffffffffffffffffffff9081169116613aed565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612f889084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613014576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107fc565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60606000865167ffffffffffffffff8111156130a8576130a8614840565b6040519080825280602002602001820160405280156130ed57816020015b60408051808201909152600080825260208201528152602001906001900390816130c65790505b50905060005b87518110156133e45760006131248983815181106131135761311361558a565b602002602001015160000151611113565b9050600089838151811061313a5761313a61558a565b60200260200101516020015190506000806132af638627fad660e01b8c8c867f00000000000000000000000000000000000000000000000000000000000000008e8b8151811061318c5761318c61558a565b60200260200101518e8c815181106131a6576131a661558a565b60200260200101516040516020016131bf929190615c2e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526131fe9594939291602401615c53565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152600b54869063ffffffff7a010000000000000000000000000000000000000000000000000000909104166113886084613b03565b5091509150816132ed57806040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107fc919061482d565b8373ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015613338573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061335c91906156aa565b86868151811061336e5761336e61558a565b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050828686815181106133bf576133bf61558a565b6020026020010151602001818152505050505050806133dd906155b9565b90506130f3565b50600b5461340990829073ffffffffffffffffffffffffffffffffffffffff16613c29565b90505b95945050505050565b600061342083613e11565b801561117557506111758383613e75565b6040805160a08101825260008082526020820152606091810182905281810182905260808101919091526040518060a001604052808461018001518152602001846000015167ffffffffffffffff16815260200184602001516040516020016134b6919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040528152602001846101200151815260200183815250905092915050565b60006111758383613f44565b60006111758383613f50565b60006111758383613fda565b60006122b2848473ffffffffffffffffffffffffffffffffffffffff8516613ff7565b600061340c85613538848661554c565b61354290876156e4565b613aed565b60008080806123b58686614014565b60006107898261404e565b60008080806123b58686614059565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b610100015160405160200161361398979695949392919073ffffffffffffffffffffffffffffffffffffffff9889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b604051602081830303815290604052805190602001208561012001518051906020012086610140015160405160200161364c9190615cb6565b604051602081830303815290604052805190602001208761016001516040516020016136789190615d1e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff161461376f576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016107fc565b600b5474010000000000000000000000000000000000000000900461ffff168311156137d3576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107fc565b808314613818576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107fc565b600b54760100000000000000000000000000000000000000000000900463ffffffff1682111561105757600b546040517f8693378900000000000000000000000000000000000000000000000000000000815276010000000000000000000000000000000000000000000090910463ffffffff166004820152602481018390526044016107fc565b600060026138af608085615525565b67ffffffffffffffff166138c3919061554c565b905060006013816138d5608087615563565b67ffffffffffffffff1681526020810191909152604001600020549050816138ff600160046154e3565b901b19168183600381111561391657613916614747565b901b178060136000613929608088615563565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a59061398e9087908790600401615d31565b600060405180830381600087803b1580156139a857600080fd5b505af19250505080156139b9575060015b613ad2573d8080156139e7576040519150601f19603f3d011682016040523d82523d6000602084013e6139ec565b606091505b506139f681615ebb565b7fffffffff00000000000000000000000000000000000000000000000000000000167f0a8d6e8c000000000000000000000000000000000000000000000000000000001480613a8e5750613a4981615ebb565b7fffffffff00000000000000000000000000000000000000000000000000000000167fe1cd550900000000000000000000000000000000000000000000000000000000145b15613a9e57600392509050612394565b806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016107fc919061482d565b50506040805160208101909152600081526002909250929050565b6000818310613afc5781611175565b5090919050565b6000606060008361ffff1667ffffffffffffffff811115613b2657613b26614840565b6040519080825280601f01601f191660200182016040528015613b50576020820181803683370190505b509150863b613b83577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613bb6577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613bef577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613c125750835b808352806000602085013e50955095509592505050565b81516000805b82811015613dfd5760008473ffffffffffffffffffffffffffffffffffffffff1663d02641a0878481518110613c6757613c6761558a565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016040805180830381865afa158015613cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cff9190615f0b565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613d9157858281518110613d3a57613d3a61558a565b6020908102919091010151516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016107fc565b613ddf868381518110613da657613da661558a565b602002602001015160200151827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661408490919063ffffffff16565b613de990846156e4565b92505080613df6906155b9565b9050613c2f565b50613e0b60038260006140c1565b50505050565b6000613e3d827f01ffc9a700000000000000000000000000000000000000000000000000000000613e75565b80156107895750613e6e827fffffffff00000000000000000000000000000000000000000000000000000000613e75565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613f2d575060208210155b8015613f395750600081115b979650505050505050565b60006111758383614444565b600081815260028301602052604081205480151580613f745750613f748484613f44565b611175576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b6579000060448201526064016107fc565b60008181526002830160205260408120819055611175838361445c565b600082815260028401602052604081208290556122b28484614468565b6000818152600283016020526040812054819080614043576140368585613f44565b9250600091506123949050565b600192509050612394565b600061078982614474565b60008080614067858561447e565b600081815260029690960160205260409095205494959350505050565b6000670de0b6b3a76400006140b7837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff861661554c565b6111759190615f6b565b825474010000000000000000000000000000000000000000900460ff1615806140e8575081155b156140f257505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061413890700100000000000000000000000000000000900463ffffffff16426154e3565b905080156141f8578183111561417a576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546141b49083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16613528565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156142af5773ffffffffffffffffffffffffffffffffffffffff8416614257576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016107fc565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016107fc565b848310156143c25760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906142f390826154e3565b6142fd878a6154e3565b61430791906156e4565b6143119190615f6b565b905073ffffffffffffffffffffffffffffffffffffffff861661436a576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016107fc565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016107fc565b6143cc85846154e3565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60008181526001830160205260408120541515611175565b6000611175838361448a565b60006111758383614584565b6000610789825490565b600061117583836145d3565b600081815260018301602052604081205480156145735760006144ae6001836154e3565b85549091506000906144c2906001906154e3565b90508181146145275760008660000182815481106144e2576144e261558a565b90600052602060002001549050808760000184815481106145055761450561558a565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061453857614538615f7f565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610789565b6000915050610789565b5092915050565b60008181526001830160205260408120546145cb57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610789565b506000610789565b60008260000182815481106145ea576145ea61558a565b9060005260206000200154905092915050565b828054828255906000526020600020908101928215614677579160200282015b8281111561467757825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061461d565b506112a09291505b808211156112a0576000815560010161467f565b60c08101610789828473ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b67ffffffffffffffff81168114611ac757600080fd5b803561472581614704565b919050565b60006020828403121561473c57600080fd5b813561117581614704565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600481106147ad577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b602081016107898284614776565b60005b838110156147da5781810151838201526020016147c2565b50506000910152565b600081518084526147fb8160208601602086016147bf565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061117560208301846147e3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561489257614892614840565b60405290565b6040516101a0810167ffffffffffffffff8111828210171561489257614892614840565b6040516080810167ffffffffffffffff8111828210171561489257614892614840565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561492657614926614840565b604052919050565b600067ffffffffffffffff82111561494857614948614840565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611ac757600080fd5b803561472581614952565b600082601f83011261499057600080fd5b813560206149a56149a08361492e565b6148df565b82815260059290921b840181019181810190868411156149c457600080fd5b8286015b848110156149e85780356149db81614952565b83529183019183016149c8565b509695505050505050565b803560ff8116811461472557600080fd5b600067ffffffffffffffff821115614a1e57614a1e614840565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112614a5b57600080fd5b8135614a696149a082614a04565b818152846020838601011115614a7e57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614ab457600080fd5b863567ffffffffffffffff80821115614acc57600080fd5b614ad88a838b0161497f565b97506020890135915080821115614aee57600080fd5b614afa8a838b0161497f565b9650614b0860408a016149f3565b95506060890135915080821115614b1e57600080fd5b614b2a8a838b01614a4a565b9450614b3860808a0161471a565b935060a0890135915080821115614b4e57600080fd5b50614b5b89828a01614a4a565b9150509295509295509295565b60008083601f840112614b7a57600080fd5b50813567ffffffffffffffff811115614b9257600080fd5b6020830191508360208260061b850101111561239457600080fd5b60008060008060408587031215614bc357600080fd5b843567ffffffffffffffff80821115614bdb57600080fd5b614be788838901614b68565b90965094506020870135915080821115614c0057600080fd5b50614c0d87828801614b68565b95989497509550505050565b600060208284031215614c2b57600080fd5b813561117581614952565b600081518084526020808501945080840160005b83811015614c7c57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614c4a565b509495945050505050565b6020815260006111756020830184614c36565b6020808252825182820181905260009190848201906040850190845b81811015614ce857835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614cb6565b50909695505050505050565b8015158114611ac757600080fd5b803561472581614cf4565b600082601f830112614d1e57600080fd5b81356020614d2e6149a08361492e565b82815260069290921b84018101918181019086841115614d4d57600080fd5b8286015b848110156149e85760408189031215614d6a5760008081fd5b614d7261486f565b8135614d7d81614952565b81528185013585820152835291830191604001614d51565b600082601f830112614da657600080fd5b81356020614db66149a08361492e565b82815260059290921b84018101918181019086841115614dd557600080fd5b8286015b848110156149e857803567ffffffffffffffff811115614df95760008081fd5b614e078986838b0101614a4a565b845250918301918301614dd9565b60006101a08284031215614e2857600080fd5b614e30614898565b9050614e3b8261471a565b8152614e4960208301614974565b6020820152614e5a60408301614974565b6040820152614e6b6060830161471a565b606082015260808201356080820152614e8660a08301614d02565b60a0820152614e9760c0830161471a565b60c0820152614ea860e08301614974565b60e082015261010082810135908201526101208083013567ffffffffffffffff80821115614ed557600080fd5b614ee186838701614a4a565b83850152610140925082850135915080821115614efd57600080fd5b614f0986838701614d0d565b83850152610160925082850135915080821115614f2557600080fd5b50614f3285828601614d95565b82840152505061018080830135818301525092915050565b600082601f830112614f5b57600080fd5b81356020614f6b6149a08361492e565b82815260059290921b84018101918181019086841115614f8a57600080fd5b8286015b848110156149e857803567ffffffffffffffff811115614fae5760008081fd5b614fbc8986838b0101614d95565b845250918301918301614f8e565b600082601f830112614fdb57600080fd5b81356020614feb6149a08361492e565b82815260059290921b8401810191818101908684111561500a57600080fd5b8286015b848110156149e8578035835291830191830161500e565b60006080828403121561503757600080fd5b61503f6148bc565b9050813567ffffffffffffffff8082111561505957600080fd5b818401915084601f83011261506d57600080fd5b8135602061507d6149a08361492e565b82815260059290921b8401810191818101908884111561509c57600080fd5b8286015b848110156150d4578035868111156150b85760008081fd5b6150c68b86838b0101614e15565b8452509183019183016150a0565b50865250858101359350828411156150eb57600080fd5b6150f787858801614f4a565b9085015250604084013591508082111561511057600080fd5b5061511d84828501614fca565b6040830152506060820135606082015292915050565b6000806040838503121561514657600080fd5b823567ffffffffffffffff8082111561515e57600080fd5b61516a86838701615025565b935060209150818501358181111561518157600080fd5b85019050601f8101861361519457600080fd5b80356151a26149a08261492e565b81815260059190911b820183019083810190888311156151c157600080fd5b928401925b828410156151df578335825292840192908401906151c6565b80955050505050509250929050565b60c08101610789828463ffffffff808251168352602082015173ffffffffffffffffffffffffffffffffffffffff8082166020860152806040850151166040860152505061ffff60608301511660608401528060808301511660808401528060a08301511660a0840152505050565b60006020828403121561526f57600080fd5b813567ffffffffffffffff81111561528657600080fd5b820160a0818503121561117557600080fd5b60008083601f8401126152aa57600080fd5b50813567ffffffffffffffff8111156152c257600080fd5b6020830191508360208260051b850101111561239457600080fd5b60008060008060008060008060e0898b0312156152f957600080fd5b606089018a81111561530a57600080fd5b8998503567ffffffffffffffff8082111561532457600080fd5b818b0191508b601f83011261533857600080fd5b81358181111561534757600080fd5b8c602082850101111561535957600080fd5b6020830199508098505060808b013591508082111561537757600080fd5b6153838c838d01615298565b909750955060a08b013591508082111561539c57600080fd5b506153a98b828c01615298565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff8116811461472557600080fd5b6000606082840312156153f457600080fd5b6040516060810181811067ffffffffffffffff8211171561541757615417614840565b604052823561542581614cf4565b8152615433602084016153c2565b6020820152615444604084016153c2565b60408201529392505050565b6000806040838503121561546357600080fd5b823567ffffffffffffffff8082111561547b57600080fd5b61548786838701614e15565b9350602085013591508082111561549d57600080fd5b506154aa85828601614d95565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610789576107896154b4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680615540576155406154f6565b92169190910692915050565b8082028115828204841417610789576107896154b4565b600067ffffffffffffffff8084168061557e5761557e6154f6565b92169190910492915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036155ea576155ea6154b4565b5060010190565b600063ffffffff80831681810361560a5761560a6154b4565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526156448184018a614c36565b905082810360808401526156588189614c36565b905060ff871660a084015282810360c084015261567581876147e3565b905067ffffffffffffffff851660e084015282810361010084015261569a81856147e3565b9c9b505050505050505050505050565b6000602082840312156156bc57600080fd5b815161117581614952565b6000602082840312156156d957600080fd5b815161117581614704565b80820180821115610789576107896154b4565b600081518084526020808501945080840160005b83811015614c7c578151805173ffffffffffffffffffffffffffffffffffffffff168852830151838801526040909601959082019060010161570b565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c08401526157836101208401826147e3565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e08601526157bf83836147e3565b9250608089015191508085840301610100860152506157de82826156f7565b925050506157f2602083018661ffff169052565b83604083015261340c606083018473ffffffffffffffffffffffffffffffffffffffff169052565b60008060006060848603121561582f57600080fd5b835161583a81614cf4565b602085015190935067ffffffffffffffff81111561585757600080fd5b8401601f8101861361586857600080fd5b80516158766149a082614a04565b81815287602083850101111561588b57600080fd5b61589c8260208301602086016147bf565b809450505050604084015190509250925092565b805163ffffffff8116811461472557600080fd5b600060c082840312156158d657600080fd5b60405160c0810181811067ffffffffffffffff821117156158f9576158f9614840565b604052615905836158b0565b8152602083015161591581614952565b6020820152604083015161592881614952565b6040820152606083015161ffff8116811461594257600080fd5b6060820152615953608084016158b0565b608082015261596460a084016158b0565b60a08201529392505050565b61018081016159e2828573ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b825163ffffffff90811660c0840152602084015173ffffffffffffffffffffffffffffffffffffffff90811660e0850152604085015116610100840152606084015161ffff166101208401526080840151811661014084015260a084015116610160830152611175565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152615a938285018b614c36565b91508382036080850152615aa7828a614c36565b915060ff881660a085015283820360c0850152615ac482886147e3565b90861660e0850152838103610100850152905061569a81856147e3565b600060208284031215615af357600080fd5b815161117581614cf4565b600081518084526020808501945080840160005b83811015614c7c57815187529582019590820190600101615b12565b606081526000615b416060830186615afe565b8281036020840152615b538186615afe565b915050826040830152949350505050565b600060208284031215615b7657600080fd5b5051919050565b67ffffffffffffffff81811683821601908082111561457d5761457d6154b4565b67ffffffffffffffff83168152604081016111756020830184614776565b600067ffffffffffffffff80831681810361560a5761560a6154b4565b615be38184614776565b6040602082015260006122b260408301846147e3565b600060208284031215615c0b57600080fd5b813567ffffffffffffffff811115615c2257600080fd5b6122b284828501615025565b604081526000615c4160408301856147e3565b828103602084015261340c81856147e3565b60a081526000615c6660a08301886147e3565b73ffffffffffffffffffffffffffffffffffffffff8716602084015285604084015267ffffffffffffffff851660608401528281036080840152615caa81856147e3565b98975050505050505050565b60208152600061117560208301846156f7565b600081518084526020808501808196508360051b8101915082860160005b85811015615d11578284038952615cff8483516147e3565b98850198935090840190600101615ce7565b5091979650505050505050565b6020815260006111756020830184615cc9565b60408152615d4c60408201845167ffffffffffffffff169052565b60006020840151615d75606084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604084015173ffffffffffffffffffffffffffffffffffffffff8116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c0840151610100615de38185018367ffffffffffffffff169052565b60e08601519150610120615e0e8186018473ffffffffffffffffffffffffffffffffffffffff169052565b81870151925061014091508282860152808701519250506101a06101608181870152615e3e6101e08701856147e3565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0610180818887030181890152615e7d86866156f7565b9550828a01519450818887030184890152615e988686615cc9565b9550808a01516101c08901525050505050828103602084015261340c8185615cc9565b6000815160208301517fffffffff0000000000000000000000000000000000000000000000000000000080821693506004831015615f035780818460040360031b1b83161693505b505050919050565b600060408284031215615f1d57600080fd5b615f2561486f565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114615f5157600080fd5b8152615f5f602084016158b0565b60208201529392505050565b600082615f7a57615f7a6154f6565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", +} + +var EVM2EVMOffRampABI = EVM2EVMOffRampMetaData.ABI + +var EVM2EVMOffRampBin = EVM2EVMOffRampMetaData.Bin + +func DeployEVM2EVMOffRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMOffRampStaticConfig, sourceTokens []common.Address, pools []common.Address, rateLimiterConfig RateLimiterConfig) (common.Address, *types.Transaction, *EVM2EVMOffRamp, error) { + parsed, err := EVM2EVMOffRampMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMOffRampBin), backend, staticConfig, sourceTokens, pools, rateLimiterConfig) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EVM2EVMOffRamp{EVM2EVMOffRampCaller: EVM2EVMOffRampCaller{contract: contract}, EVM2EVMOffRampTransactor: EVM2EVMOffRampTransactor{contract: contract}, EVM2EVMOffRampFilterer: EVM2EVMOffRampFilterer{contract: contract}}, nil +} + +type EVM2EVMOffRamp struct { + address common.Address + abi abi.ABI + EVM2EVMOffRampCaller + EVM2EVMOffRampTransactor + EVM2EVMOffRampFilterer +} + +type EVM2EVMOffRampCaller struct { + contract *bind.BoundContract +} + +type EVM2EVMOffRampTransactor struct { + contract *bind.BoundContract +} + +type EVM2EVMOffRampFilterer struct { + contract *bind.BoundContract +} + +type EVM2EVMOffRampSession struct { + Contract *EVM2EVMOffRamp + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type EVM2EVMOffRampCallerSession struct { + Contract *EVM2EVMOffRampCaller + CallOpts bind.CallOpts +} + +type EVM2EVMOffRampTransactorSession struct { + Contract *EVM2EVMOffRampTransactor + TransactOpts bind.TransactOpts +} + +type EVM2EVMOffRampRaw struct { + Contract *EVM2EVMOffRamp +} + +type EVM2EVMOffRampCallerRaw struct { + Contract *EVM2EVMOffRampCaller +} + +type EVM2EVMOffRampTransactorRaw struct { + Contract *EVM2EVMOffRampTransactor +} + +func NewEVM2EVMOffRamp(address common.Address, backend bind.ContractBackend) (*EVM2EVMOffRamp, error) { + abi, err := abi.JSON(strings.NewReader(EVM2EVMOffRampABI)) + if err != nil { + return nil, err + } + contract, err := bindEVM2EVMOffRamp(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &EVM2EVMOffRamp{address: address, abi: abi, EVM2EVMOffRampCaller: EVM2EVMOffRampCaller{contract: contract}, EVM2EVMOffRampTransactor: EVM2EVMOffRampTransactor{contract: contract}, EVM2EVMOffRampFilterer: EVM2EVMOffRampFilterer{contract: contract}}, nil +} + +func NewEVM2EVMOffRampCaller(address common.Address, caller bind.ContractCaller) (*EVM2EVMOffRampCaller, error) { + contract, err := bindEVM2EVMOffRamp(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampCaller{contract: contract}, nil +} + +func NewEVM2EVMOffRampTransactor(address common.Address, transactor bind.ContractTransactor) (*EVM2EVMOffRampTransactor, error) { + contract, err := bindEVM2EVMOffRamp(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampTransactor{contract: contract}, nil +} + +func NewEVM2EVMOffRampFilterer(address common.Address, filterer bind.ContractFilterer) (*EVM2EVMOffRampFilterer, error) { + contract, err := bindEVM2EVMOffRamp(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampFilterer{contract: contract}, nil +} + +func bindEVM2EVMOffRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EVM2EVMOffRampMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOffRamp.Contract.EVM2EVMOffRampCaller.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.EVM2EVMOffRampTransactor.contract.Transfer(opts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.EVM2EVMOffRampTransactor.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOffRamp.Contract.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.contract.Transfer(opts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) CcipReceive(opts *bind.CallOpts, arg0 ClientAny2EVMMessage) error { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "ccipReceive", arg0) + + if err != nil { + return err + } + + return err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) CcipReceive(arg0 ClientAny2EVMMessage) error { + return _EVM2EVMOffRamp.Contract.CcipReceive(&_EVM2EVMOffRamp.CallOpts, arg0) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) CcipReceive(arg0 ClientAny2EVMMessage) error { + return _EVM2EVMOffRamp.Contract.CcipReceive(&_EVM2EVMOffRamp.CallOpts, arg0) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "currentRateLimiterState") + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOffRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOffRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetDestinationToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getDestinationToken", sourceToken) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetDestinationToken(sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetDestinationToken(&_EVM2EVMOffRamp.CallOpts, sourceToken) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetDestinationToken(sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetDestinationToken(&_EVM2EVMOffRamp.CallOpts, sourceToken) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetDestinationTokens(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getDestinationTokens") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetDestinationTokens() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetDestinationTokens(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetDestinationTokens() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetDestinationTokens(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOffRampDynamicConfig, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(EVM2EVMOffRampDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOffRampDynamicConfig)).(*EVM2EVMOffRampDynamicConfig) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetDynamicConfig() (EVM2EVMOffRampDynamicConfig, error) { + return _EVM2EVMOffRamp.Contract.GetDynamicConfig(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetDynamicConfig() (EVM2EVMOffRampDynamicConfig, error) { + return _EVM2EVMOffRamp.Contract.GetDynamicConfig(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetExecutionState(opts *bind.CallOpts, sequenceNumber uint64) (uint8, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getExecutionState", sequenceNumber) + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetExecutionState(sequenceNumber uint64) (uint8, error) { + return _EVM2EVMOffRamp.Contract.GetExecutionState(&_EVM2EVMOffRamp.CallOpts, sequenceNumber) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetExecutionState(sequenceNumber uint64) (uint8, error) { + return _EVM2EVMOffRamp.Contract.GetExecutionState(&_EVM2EVMOffRamp.CallOpts, sequenceNumber) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetPoolByDestToken(opts *bind.CallOpts, destToken common.Address) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getPoolByDestToken", destToken) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetPoolByDestToken(destToken common.Address) (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetPoolByDestToken(&_EVM2EVMOffRamp.CallOpts, destToken) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetPoolByDestToken(destToken common.Address) (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetPoolByDestToken(&_EVM2EVMOffRamp.CallOpts, destToken) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetPoolBySourceToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getPoolBySourceToken", sourceToken) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetPoolBySourceToken(sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetPoolBySourceToken(&_EVM2EVMOffRamp.CallOpts, sourceToken) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetPoolBySourceToken(sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetPoolBySourceToken(&_EVM2EVMOffRamp.CallOpts, sourceToken) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getSenderNonce", sender) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOffRamp.Contract.GetSenderNonce(&_EVM2EVMOffRamp.CallOpts, sender) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOffRamp.Contract.GetSenderNonce(&_EVM2EVMOffRamp.CallOpts, sender) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOffRampStaticConfig, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(EVM2EVMOffRampStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOffRampStaticConfig)).(*EVM2EVMOffRampStaticConfig) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetStaticConfig() (EVM2EVMOffRampStaticConfig, error) { + return _EVM2EVMOffRamp.Contract.GetStaticConfig(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetStaticConfig() (EVM2EVMOffRampStaticConfig, error) { + return _EVM2EVMOffRamp.Contract.GetStaticConfig(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetSupportedTokens(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getSupportedTokens") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetSupportedTokens() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetSupportedTokens(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetSupportedTokens() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetSupportedTokens(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getTokenLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) GetTransmitters() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetTransmitters(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) GetTransmitters() ([]common.Address, error) { + return _EVM2EVMOffRamp.Contract.GetTransmitters(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _EVM2EVMOffRamp.Contract.LatestConfigDetails(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _EVM2EVMOffRamp.Contract.LatestConfigDetails(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _EVM2EVMOffRamp.Contract.LatestConfigDigestAndEpoch(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _EVM2EVMOffRamp.Contract.LatestConfigDigestAndEpoch(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) Owner() (common.Address, error) { + return _EVM2EVMOffRamp.Contract.Owner(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) Owner() (common.Address, error) { + return _EVM2EVMOffRamp.Contract.Owner(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _EVM2EVMOffRamp.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) TypeAndVersion() (string, error) { + return _EVM2EVMOffRamp.Contract.TypeAndVersion(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampCallerSession) TypeAndVersion() (string, error) { + return _EVM2EVMOffRamp.Contract.TypeAndVersion(&_EVM2EVMOffRamp.CallOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "acceptOwnership") +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.AcceptOwnership(&_EVM2EVMOffRamp.TransactOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.AcceptOwnership(&_EVM2EVMOffRamp.TransactOpts) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) ApplyPoolUpdates(opts *bind.TransactOpts, removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "applyPoolUpdates", removes, adds) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) ApplyPoolUpdates(removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ApplyPoolUpdates(&_EVM2EVMOffRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) ApplyPoolUpdates(removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ApplyPoolUpdates(&_EVM2EVMOffRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) ExecuteSingleMessage(opts *bind.TransactOpts, message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "executeSingleMessage", message, offchainTokenData) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) ExecuteSingleMessage(message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMOffRamp.TransactOpts, message, offchainTokenData) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) ExecuteSingleMessage(message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMOffRamp.TransactOpts, message, offchainTokenData) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) ManuallyExecute(opts *bind.TransactOpts, report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "manuallyExecute", report, gasLimitOverrides) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) ManuallyExecute(report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ManuallyExecute(&_EVM2EVMOffRamp.TransactOpts, report, gasLimitOverrides) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) ManuallyExecute(report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ManuallyExecute(&_EVM2EVMOffRamp.TransactOpts, report, gasLimitOverrides) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "setAdmin", newAdmin) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetAdmin(&_EVM2EVMOffRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetAdmin(&_EVM2EVMOffRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "setOCR2Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetOCR2Config(&_EVM2EVMOffRamp.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetOCR2Config(&_EVM2EVMOffRamp.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "setRateLimiterConfig", config) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOffRamp.TransactOpts, config) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOffRamp.TransactOpts, config) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "transferOwnership", to) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.TransferOwnership(&_EVM2EVMOffRamp.TransactOpts, to) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.TransferOwnership(&_EVM2EVMOffRamp.TransactOpts, to) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "transmit", reportContext, report, rs, ss, arg4) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.Transmit(&_EVM2EVMOffRamp.TransactOpts, reportContext, report, rs, ss, arg4) +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.Transmit(&_EVM2EVMOffRamp.TransactOpts, reportContext, report, rs, ss, arg4) +} + +type EVM2EVMOffRampAdminSetIterator struct { + Event *EVM2EVMOffRampAdminSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampAdminSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampAdminSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampAdminSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampAdminSet struct { + NewAdmin common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOffRampAdminSetIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampAdminSetIterator{contract: _EVM2EVMOffRamp.contract, event: "AdminSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampAdminSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampAdminSet) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseAdminSet(log types.Log) (*EVM2EVMOffRampAdminSet, error) { + event := new(EVM2EVMOffRampAdminSet) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampConfigSetIterator struct { + Event *EVM2EVMOffRampConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampConfigSet struct { + StaticConfig EVM2EVMOffRampStaticConfig + DynamicConfig EVM2EVMOffRampDynamicConfig + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampConfigSetIterator{contract: _EVM2EVMOffRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampConfigSet) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseConfigSet(log types.Log) (*EVM2EVMOffRampConfigSet, error) { + event := new(EVM2EVMOffRampConfigSet) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampConfigSet0Iterator struct { + Event *EVM2EVMOffRampConfigSet0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampConfigSet0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampConfigSet0Iterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampConfigSet0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampConfigSet0 struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterConfigSet0(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigSet0Iterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampConfigSet0Iterator{contract: _EVM2EVMOffRamp.contract, event: "ConfigSet0", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigSet0) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampConfigSet0) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseConfigSet0(log types.Log) (*EVM2EVMOffRampConfigSet0, error) { + event := new(EVM2EVMOffRampConfigSet0) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampExecutionStateChangedIterator struct { + Event *EVM2EVMOffRampExecutionStateChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampExecutionStateChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampExecutionStateChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampExecutionStateChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampExecutionStateChangedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampExecutionStateChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampExecutionStateChanged struct { + SequenceNumber uint64 + MessageId [32]byte + State uint8 + ReturnData []byte + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterExecutionStateChanged(opts *bind.FilterOpts, sequenceNumber []uint64, messageId [][32]byte) (*EVM2EVMOffRampExecutionStateChangedIterator, error) { + + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + var messageIdRule []interface{} + for _, messageIdItem := range messageId { + messageIdRule = append(messageIdRule, messageIdItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "ExecutionStateChanged", sequenceNumberRule, messageIdRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampExecutionStateChangedIterator{contract: _EVM2EVMOffRamp.contract, event: "ExecutionStateChanged", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampExecutionStateChanged, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) { + + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + var messageIdRule []interface{} + for _, messageIdItem := range messageId { + messageIdRule = append(messageIdRule, messageIdItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "ExecutionStateChanged", sequenceNumberRule, messageIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampExecutionStateChanged) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseExecutionStateChanged(log types.Log) (*EVM2EVMOffRampExecutionStateChanged, error) { + event := new(EVM2EVMOffRampExecutionStateChanged) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampOwnershipTransferRequestedIterator struct { + Event *EVM2EVMOffRampOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOffRampOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampOwnershipTransferRequestedIterator{contract: _EVM2EVMOffRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampOwnershipTransferRequested) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOffRampOwnershipTransferRequested, error) { + event := new(EVM2EVMOffRampOwnershipTransferRequested) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampOwnershipTransferredIterator struct { + Event *EVM2EVMOffRampOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOffRampOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampOwnershipTransferredIterator{contract: _EVM2EVMOffRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampOwnershipTransferred) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseOwnershipTransferred(log types.Log) (*EVM2EVMOffRampOwnershipTransferred, error) { + event := new(EVM2EVMOffRampOwnershipTransferred) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampPoolAddedIterator struct { + Event *EVM2EVMOffRampPoolAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampPoolAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampPoolAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampPoolAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampPoolAddedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampPoolAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampPoolAdded struct { + Token common.Address + Pool common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterPoolAdded(opts *bind.FilterOpts) (*EVM2EVMOffRampPoolAddedIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "PoolAdded") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampPoolAddedIterator{contract: _EVM2EVMOffRamp.contract, event: "PoolAdded", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchPoolAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampPoolAdded) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "PoolAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampPoolAdded) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "PoolAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParsePoolAdded(log types.Log) (*EVM2EVMOffRampPoolAdded, error) { + event := new(EVM2EVMOffRampPoolAdded) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "PoolAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampPoolRemovedIterator struct { + Event *EVM2EVMOffRampPoolRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampPoolRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampPoolRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampPoolRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampPoolRemovedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampPoolRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampPoolRemoved struct { + Token common.Address + Pool common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterPoolRemoved(opts *bind.FilterOpts) (*EVM2EVMOffRampPoolRemovedIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "PoolRemoved") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampPoolRemovedIterator{contract: _EVM2EVMOffRamp.contract, event: "PoolRemoved", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchPoolRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampPoolRemoved) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "PoolRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampPoolRemoved) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "PoolRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParsePoolRemoved(log types.Log) (*EVM2EVMOffRampPoolRemoved, error) { + event := new(EVM2EVMOffRampPoolRemoved) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "PoolRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampSkippedIncorrectNonceIterator struct { + Event *EVM2EVMOffRampSkippedIncorrectNonce + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampSkippedIncorrectNonceIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedIncorrectNonce) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedIncorrectNonce) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampSkippedIncorrectNonceIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampSkippedIncorrectNonceIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampSkippedIncorrectNonce struct { + Nonce uint64 + Sender common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterSkippedIncorrectNonce(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*EVM2EVMOffRampSkippedIncorrectNonceIterator, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "SkippedIncorrectNonce", nonceRule, senderRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampSkippedIncorrectNonceIterator{contract: _EVM2EVMOffRamp.contract, event: "SkippedIncorrectNonce", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedIncorrectNonce, nonce []uint64, sender []common.Address) (event.Subscription, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "SkippedIncorrectNonce", nonceRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampSkippedIncorrectNonce) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedIncorrectNonce", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseSkippedIncorrectNonce(log types.Log) (*EVM2EVMOffRampSkippedIncorrectNonce, error) { + event := new(EVM2EVMOffRampSkippedIncorrectNonce) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedIncorrectNonce", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator struct { + Event *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight struct { + Nonce uint64 + Sender common.Address + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterSkippedSenderWithPreviousRampMessageInflight(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "SkippedSenderWithPreviousRampMessageInflight", nonceRule, senderRule) + if err != nil { + return nil, err + } + return &EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator{contract: _EVM2EVMOffRamp.contract, event: "SkippedSenderWithPreviousRampMessageInflight", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchSkippedSenderWithPreviousRampMessageInflight(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, nonce []uint64, sender []common.Address) (event.Subscription, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "SkippedSenderWithPreviousRampMessageInflight", nonceRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedSenderWithPreviousRampMessageInflight", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseSkippedSenderWithPreviousRampMessageInflight(log types.Log) (*EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error) { + event := new(EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "SkippedSenderWithPreviousRampMessageInflight", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOffRampTransmittedIterator struct { + Event *EVM2EVMOffRampTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampTransmittedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterTransmitted(opts *bind.FilterOpts) (*EVM2EVMOffRampTransmittedIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampTransmittedIterator{contract: _EVM2EVMOffRamp.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampTransmitted) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampTransmitted) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseTransmitted(log types.Log) (*EVM2EVMOffRampTransmitted, error) { + event := new(EVM2EVMOffRampTransmitted) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _EVM2EVMOffRamp.abi.Events["AdminSet"].ID: + return _EVM2EVMOffRamp.ParseAdminSet(log) + case _EVM2EVMOffRamp.abi.Events["ConfigSet"].ID: + return _EVM2EVMOffRamp.ParseConfigSet(log) + case _EVM2EVMOffRamp.abi.Events["ConfigSet0"].ID: + return _EVM2EVMOffRamp.ParseConfigSet0(log) + case _EVM2EVMOffRamp.abi.Events["ExecutionStateChanged"].ID: + return _EVM2EVMOffRamp.ParseExecutionStateChanged(log) + case _EVM2EVMOffRamp.abi.Events["OwnershipTransferRequested"].ID: + return _EVM2EVMOffRamp.ParseOwnershipTransferRequested(log) + case _EVM2EVMOffRamp.abi.Events["OwnershipTransferred"].ID: + return _EVM2EVMOffRamp.ParseOwnershipTransferred(log) + case _EVM2EVMOffRamp.abi.Events["PoolAdded"].ID: + return _EVM2EVMOffRamp.ParsePoolAdded(log) + case _EVM2EVMOffRamp.abi.Events["PoolRemoved"].ID: + return _EVM2EVMOffRamp.ParsePoolRemoved(log) + case _EVM2EVMOffRamp.abi.Events["SkippedIncorrectNonce"].ID: + return _EVM2EVMOffRamp.ParseSkippedIncorrectNonce(log) + case _EVM2EVMOffRamp.abi.Events["SkippedSenderWithPreviousRampMessageInflight"].ID: + return _EVM2EVMOffRamp.ParseSkippedSenderWithPreviousRampMessageInflight(log) + case _EVM2EVMOffRamp.abi.Events["Transmitted"].ID: + return _EVM2EVMOffRamp.ParseTransmitted(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (EVM2EVMOffRampAdminSet) Topic() common.Hash { + return common.HexToHash("0x8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c") +} + +func (EVM2EVMOffRampConfigSet) Topic() common.Hash { + return common.HexToHash("0xe668e1a4644c1a030b909bbfd837f5cfa914994ed5e0bb2e9c34a5c37753128a") +} + +func (EVM2EVMOffRampConfigSet0) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (EVM2EVMOffRampExecutionStateChanged) Topic() common.Hash { + return common.HexToHash("0xd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef65") +} + +func (EVM2EVMOffRampOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (EVM2EVMOffRampOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (EVM2EVMOffRampPoolAdded) Topic() common.Hash { + return common.HexToHash("0x95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c") +} + +func (EVM2EVMOffRampPoolRemoved) Topic() common.Hash { + return common.HexToHash("0x987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c") +} + +func (EVM2EVMOffRampSkippedIncorrectNonce) Topic() common.Hash { + return common.HexToHash("0xd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf41237") +} + +func (EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) Topic() common.Hash { + return common.HexToHash("0xe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d") +} + +func (EVM2EVMOffRampTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRamp) Address() common.Address { + return _EVM2EVMOffRamp.address +} + +type EVM2EVMOffRampInterface interface { + CcipReceive(opts *bind.CallOpts, arg0 ClientAny2EVMMessage) error + + CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) + + GetDestinationToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) + + GetDestinationTokens(opts *bind.CallOpts) ([]common.Address, error) + + GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOffRampDynamicConfig, error) + + GetExecutionState(opts *bind.CallOpts, sequenceNumber uint64) (uint8, error) + + GetPoolByDestToken(opts *bind.CallOpts, destToken common.Address) (common.Address, error) + + GetPoolBySourceToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) + + GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) + + GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOffRampStaticConfig, error) + + GetSupportedTokens(opts *bind.CallOpts) ([]common.Address, error) + + GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) + + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyPoolUpdates(opts *bind.TransactOpts, removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) + + ExecuteSingleMessage(opts *bind.TransactOpts, message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) + + ManuallyExecute(opts *bind.TransactOpts, report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) + + SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) + + SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) + + FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOffRampAdminSetIterator, error) + + WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampAdminSet) (event.Subscription, error) + + ParseAdminSet(log types.Log) (*EVM2EVMOffRampAdminSet, error) + + FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*EVM2EVMOffRampConfigSet, error) + + FilterConfigSet0(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigSet0Iterator, error) + + WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigSet0) (event.Subscription, error) + + ParseConfigSet0(log types.Log) (*EVM2EVMOffRampConfigSet0, error) + + FilterExecutionStateChanged(opts *bind.FilterOpts, sequenceNumber []uint64, messageId [][32]byte) (*EVM2EVMOffRampExecutionStateChangedIterator, error) + + WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampExecutionStateChanged, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) + + ParseExecutionStateChanged(log types.Log) (*EVM2EVMOffRampExecutionStateChanged, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOffRampOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOffRampOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOffRampOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*EVM2EVMOffRampOwnershipTransferred, error) + + FilterPoolAdded(opts *bind.FilterOpts) (*EVM2EVMOffRampPoolAddedIterator, error) + + WatchPoolAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampPoolAdded) (event.Subscription, error) + + ParsePoolAdded(log types.Log) (*EVM2EVMOffRampPoolAdded, error) + + FilterPoolRemoved(opts *bind.FilterOpts) (*EVM2EVMOffRampPoolRemovedIterator, error) + + WatchPoolRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampPoolRemoved) (event.Subscription, error) + + ParsePoolRemoved(log types.Log) (*EVM2EVMOffRampPoolRemoved, error) + + FilterSkippedIncorrectNonce(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*EVM2EVMOffRampSkippedIncorrectNonceIterator, error) + + WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedIncorrectNonce, nonce []uint64, sender []common.Address) (event.Subscription, error) + + ParseSkippedIncorrectNonce(log types.Log) (*EVM2EVMOffRampSkippedIncorrectNonce, error) + + FilterSkippedSenderWithPreviousRampMessageInflight(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error) + + WatchSkippedSenderWithPreviousRampMessageInflight(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, nonce []uint64, sender []common.Address) (event.Subscription, error) + + ParseSkippedSenderWithPreviousRampMessageInflight(log types.Log) (*EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error) + + FilterTransmitted(opts *bind.FilterOpts) (*EVM2EVMOffRampTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*EVM2EVMOffRampTransmitted, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go new file mode 100644 index 0000000000..be9c2395a0 --- /dev/null +++ b/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go @@ -0,0 +1,2453 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package evm_2_evm_onramp + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientEVM2AnyMessage struct { + Receiver []byte + Data []byte + TokenAmounts []ClientEVMTokenAmount + FeeToken common.Address + ExtraArgs []byte +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type EVM2EVMOnRampDynamicConfig struct { + Router common.Address + MaxNumberOfTokensPerMsg uint16 + DestGasOverhead uint32 + DestGasPerPayloadByte uint16 + DestDataAvailabilityOverheadGas uint32 + DestGasPerDataAvailabilityByte uint16 + DestDataAvailabilityMultiplierBps uint16 + PriceRegistry common.Address + MaxDataBytes uint32 + MaxPerMsgGasLimit uint32 + DefaultTokenFeeUSDCents uint16 + DefaultTokenDestGasOverhead uint32 + DefaultTokenDestBytesOverhead uint32 + EnforceOutOfOrder bool +} + +type EVM2EVMOnRampFeeTokenConfig struct { + NetworkFeeUSDCents uint32 + GasMultiplierWeiPerEth uint64 + PremiumMultiplierWeiPerEth uint64 + Enabled bool +} + +type EVM2EVMOnRampFeeTokenConfigArgs struct { + Token common.Address + NetworkFeeUSDCents uint32 + GasMultiplierWeiPerEth uint64 + PremiumMultiplierWeiPerEth uint64 + Enabled bool +} + +type EVM2EVMOnRampNopAndWeight struct { + Nop common.Address + Weight uint16 +} + +type EVM2EVMOnRampStaticConfig struct { + LinkToken common.Address + ChainSelector uint64 + DestChainSelector uint64 + DefaultTxGasLimit uint64 + MaxNopFeesJuels *big.Int + PrevOnRamp common.Address + RmnProxy common.Address + TokenAdminRegistry common.Address +} + +type EVM2EVMOnRampTokenTransferFeeConfig struct { + MinFeeUSDCents uint32 + MaxFeeUSDCents uint32 + DeciBps uint16 + DestGasOverhead uint32 + DestBytesOverhead uint32 + AggregateRateLimitEnabled bool + IsEnabled bool +} + +type EVM2EVMOnRampTokenTransferFeeConfigArgs struct { + Token common.Address + MinFeeUSDCents uint32 + MaxFeeUSDCents uint32 + DeciBps uint16 + DestGasOverhead uint32 + DestBytesOverhead uint32 + AggregateRateLimitEnabled bool +} + +type InternalEVM2EVMMessage struct { + SourceChainSelector uint64 + Sender common.Address + Receiver common.Address + SequenceNumber uint64 + GasLimit *big.Int + Strict bool + Nonce uint64 + FeeToken common.Address + FeeTokenAmount *big.Int + Data []byte + TokenAmounts []ClientEVMTokenAmount + SourceTokenData [][]byte + MessageId [32]byte +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +var EVM2EVMOnRampMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidChainSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"}],\"name\":\"InvalidNopAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWithdrawParams\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkBalanceNotSettled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeeBalanceReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoFeesToPay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoNopsToPay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdminOrNop\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyNops\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeConfig\",\"type\":\"tuple[]\"}],\"name\":\"FeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NopPaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nopWeightsTotal\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"NopsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"transferFeeConfig\",\"type\":\"tuple[]\"}],\"name\":\"TokenTransferFeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getFeeTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfig\",\"name\":\"feeTokenConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNopFeesJuels\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNops\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"weightsTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setFeeTokenConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"address[]\"}],\"name\":\"setTokenTransferFeeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawNonLinkFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101a06040523480156200001257600080fd5b50604051620082d4380380620082d4833981016040819052620000359162001b0e565b8333806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c0816200030b565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555085516001600160a01b0316158062000169575060208601516001600160401b0316155b8062000180575060408601516001600160401b0316155b8062000197575060608601516001600160401b0316155b80620001ae575060c08601516001600160a01b0316155b80620001c5575060e08601516001600160a01b0316155b15620001e4576040516306b7c75960e31b815260040160405180910390fd5b60208087015160408089015181517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3948101949094526001600160401b039283169184019190915216606082015230608082015260a00160408051601f198184030181529181528151602092830120608090815288516001600160a01b0390811660e0908152938a01516001600160401b0390811661010052928a015183166101205260608a015190921660a0908152908901516001600160601b031660c090815290890151821661014052880151811661016052908701511661018052620002cd85620003b6565b620002d8836200071a565b604080516000815260208101909152620002f49083906200084a565b620002ff8162000aea565b50505050505062002212565b336001600160a01b03821603620003655760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e08101516001600160a01b0316620003e2576040516306b7c75960e31b815260040160405180910390fd5b602081610180015163ffffffff16101562000427576101808101516040516312766e0160e11b81526000600482015263ffffffff909116602482015260440162000084565b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548163ffffffff021916908363ffffffff1602179055506101a082015181600201600a6101000a81548160ff0219169083151502179055509050507fe375c8cb6ea9807cd0371503b632b93da5ee0f1f64205db8b5b28b95d6b588b060405180610100016040528060e0516001600160a01b03168152602001610100516001600160401b03168152602001610120516001600160401b0316815260200160a0516001600160401b0316815260200160c0516001600160601b03168152602001610140516001600160a01b03168152602001610160516001600160a01b03168152602001610180516001600160a01b0316815250826040516200070f92919062001da4565b60405180910390a150565b60005b8151811015620008185760008282815181106200073e576200073e62001e69565b60209081029190910181015160408051608080820183528385015163ffffffff9081168352838501516001600160401b03908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b0260ff60a01b199688166c010000000000000000000000000296909616600160601b600160a81b031993909716640100000000026001600160601b0319909516911617929092179190911692909217179055506001016200071d565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e816040516200070f919062001e7f565b60005b825181101562000a095760008382815181106200086e576200086e62001e69565b6020026020010151905060208160a0015163ffffffff161015620008c457805160a08201516040516312766e0160e11b81526001600160a01b03909216600483015263ffffffff16602482015260440162000084565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087166001600160401b031990961695909517640100000000928716929092029190911765ffffffffffff60401b191668010000000000000000939092169290920263ffffffff60501b1916176a0100000000000000000000918416919091021764ffffffffff60701b1916600160701b939092169290920260ff60901b191617600160901b941515949094029390931760ff60981b1916600160981b9315159390930292909217909155016200084d565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d08260405162000a3b919062001f0e565b60405180910390a160005b815181101562000aa357600c600083838151811062000a695762000a6962001e69565b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160a01b031916905560010162000a46565b5080511562000ae6577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b8160405162000add919062001fa3565b60405180910390a15b5050565b8051604081111562000b0f57604051635ad0867d60e11b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff161562000b6257600e5463ffffffff6c010000000000000000000000008204166001600160601b039091161062000b625762000b6262000d05565b600062000b70600862000ef1565b90505b801562000bbc57600062000b9662000b8d60018462002008565b60089062000f04565b50905062000ba660088262000f22565b50508062000bb4906200201e565b905062000b73565b506000805b8281101562000c9c57600084828151811062000be15762000be162001e69565b6020026020010151600001519050600085838151811062000c065762000c0662001e69565b602002602001015160200151905060e0516001600160a01b0316826001600160a01b0316148062000c3e57506001600160a01b038216155b1562000c6957604051634de938d160e01b81526001600160a01b038316600482015260240162000084565b62000c7b60088361ffff841662000f40565b5062000c8c61ffff82168562002038565b9350505080600101905062000bc1565b50600e805463ffffffff60601b19166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249062000cf8908390869062002058565b60405180910390a1505050565b6000546001600160a01b0316331462000d56576002546001600160a01b0316331462000d565762000d3860083362000f60565b62000d565760405163032bb72b60e31b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff16600081900362000d925760405163990e30bf60e01b815260040160405180910390fd5b600e546001600160601b03168181101562000dc0576040516311a1ee3b60e31b815260040160405180910390fd5b600062000dcc62000f77565b121562000dec57604051631e9acf1760e31b815260040160405180910390fd5b80600062000dfb600862000ef1565b905060005b8181101562000ecb5760008062000e1960088462000f04565b909250905060008762000e36836001600160601b038a16620020c8565b62000e429190620020e2565b905062000e50818762002105565b60e05190965062000e75906001600160a01b0316846001600160601b03841662001005565b6040516001600160601b03821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a250505080600101905062000e00565b5050600e80546001600160601b0319166001600160601b03929092169190911790555050565b600062000efe8262001062565b92915050565b600080808062000f1586866200106f565b9097909650945050505050565b600062000f39836001600160a01b0384166200109c565b9392505050565b600062000f58846001600160a01b03851684620010bb565b949350505050565b600062000f39836001600160a01b038416620010da565b600e5460e0516040516370a0823160e01b81523060048201526000926001600160601b0316916001600160a01b0316906370a0823190602401602060405180830381865afa15801562000fce573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ff4919062002128565b62001000919062002142565b905090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b179091526200105d918591620010e816565b505050565b600062000efe82620011b9565b600080806200107f8585620011c4565b600081815260029690960160205260409095205494959350505050565b6000818152600283016020526040812081905562000f398383620011d2565b6000828152600284016020526040812082905562000f588484620011e0565b600062000f398383620011ee565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062001137906001600160a01b03851690849062001207565b8051909150156200105d578080602001905181019062001158919062002165565b6200105d5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000084565b600062000efe825490565b600062000f39838362001218565b600062000f39838362001245565b600062000f39838362001350565b6000818152600183016020526040812054151562000f39565b606062000f588484600085620013a2565b600082600001828154811062001232576200123262001e69565b9060005260206000200154905092915050565b600081815260018301602052604081205480156200133e5760006200126c60018362002008565b8554909150600090620012829060019062002008565b9050818114620012ee576000866000018281548110620012a657620012a662001e69565b9060005260206000200154905080876000018481548110620012cc57620012cc62001e69565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062001302576200130262002183565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000efe565b600091505062000efe565b5092915050565b6000818152600183016020526040812054620013995750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000efe565b50600062000efe565b606082471015620014055760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000084565b600080866001600160a01b03168587604051620014239190620021bf565b60006040518083038185875af1925050503d806000811462001462576040519150601f19603f3d011682016040523d82523d6000602084013e62001467565b606091505b5090925090506200147b8783838762001486565b979650505050505050565b60608315620014fa578251600003620014f2576001600160a01b0385163b620014f25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000084565b508162000f58565b62000f588383815115620015115781518083602001fd5b8060405162461bcd60e51b8152600401620000849190620021dd565b634e487b7160e01b600052604160045260246000fd5b6040516101c081016001600160401b03811182821017156200156957620015696200152d565b60405290565b60405160a081016001600160401b03811182821017156200156957620015696200152d565b60405160e081016001600160401b03811182821017156200156957620015696200152d565b604080519081016001600160401b03811182821017156200156957620015696200152d565b60405161010081016001600160401b03811182821017156200156957620015696200152d565b604051601f8201601f191681016001600160401b03811182821017156200162f576200162f6200152d565b604052919050565b80516001600160a01b03811681146200164f57600080fd5b919050565b80516001600160401b03811681146200164f57600080fd5b805161ffff811681146200164f57600080fd5b805163ffffffff811681146200164f57600080fd5b805180151581146200164f57600080fd5b60006101c08284031215620016b957600080fd5b620016c362001543565b9050620016d08262001637565b8152620016e0602083016200166c565b6020820152620016f3604083016200167f565b604082015262001706606083016200166c565b606082015262001719608083016200167f565b60808201526200172c60a083016200166c565b60a08201526200173f60c083016200166c565b60c08201526200175260e0830162001637565b60e0820152610100620017678184016200167f565b908201526101206200177b8382016200167f565b908201526101406200178f8382016200166c565b90820152610160620017a38382016200167f565b90820152610180620017b78382016200167f565b908201526101a0620017cb83820162001694565b9082015292915050565b80516001600160801b03811681146200164f57600080fd5b6000606082840312156200180057600080fd5b604051606081016001600160401b03811182821017156200182557620018256200152d565b604052905080620018368362001694565b81526200184660208401620017d5565b60208201526200185960408401620017d5565b60408201525092915050565b60006001600160401b038211156200188157620018816200152d565b5060051b60200190565b600082601f8301126200189d57600080fd5b81516020620018b6620018b08362001865565b62001604565b82815260a09283028501820192828201919087851115620018d657600080fd5b8387015b85811015620019635781818a031215620018f45760008081fd5b620018fe6200156f565b620019098262001637565b8152620019188683016200167f565b8682015260406200192b81840162001654565b9082015260606200193e83820162001654565b9082015260806200195183820162001694565b908201528452928401928101620018da565b5090979650505050505050565b600082601f8301126200198257600080fd5b8151602062001995620018b08362001865565b82815260e09283028501820192828201919087851115620019b557600080fd5b8387015b85811015620019635781818a031215620019d35760008081fd5b620019dd62001594565b620019e88262001637565b8152620019f78683016200167f565b86820152604062001a0a8184016200167f565b90820152606062001a1d8382016200166c565b90820152608062001a308382016200167f565b9082015260a062001a438382016200167f565b9082015260c062001a5683820162001694565b908201528452928401928101620019b9565b600082601f83011262001a7a57600080fd5b8151602062001a8d620018b08362001865565b82815260069290921b8401810191818101908684111562001aad57600080fd5b8286015b8481101562001b03576040818903121562001acc5760008081fd5b62001ad6620015b9565b62001ae18262001637565b815262001af08583016200166c565b8186015283529183019160400162001ab1565b509695505050505050565b60008060008060008086880361038081121562001b2a57600080fd5b6101008082121562001b3b57600080fd5b62001b45620015de565b915062001b528962001637565b825262001b6260208a0162001654565b602083015262001b7560408a0162001654565b604083015262001b8860608a0162001654565b606083015260808901516001600160601b038116811462001ba857600080fd5b608083015262001bbb60a08a0162001637565b60a083015262001bce60c08a0162001637565b60c083015262001be160e08a0162001637565b60e083015281975062001bf78a828b01620016a5565b9650505062001c0b886102c08901620017ed565b6103208801519094506001600160401b038082111562001c2a57600080fd5b62001c388a838b016200188b565b945061034089015191508082111562001c5057600080fd5b62001c5e8a838b0162001970565b935061036089015191508082111562001c7657600080fd5b5062001c8589828a0162001a68565b9150509295509295509295565b80516001600160a01b03168252602081015162001cb5602084018261ffff169052565b50604081015162001cce604084018263ffffffff169052565b50606081015162001ce5606084018261ffff169052565b50608081015162001cfe608084018263ffffffff169052565b5060a081015162001d1560a084018261ffff169052565b5060c081015162001d2c60c084018261ffff169052565b5060e081015162001d4860e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015182169084015261018080830151909116908301526101a0908101511515910152565b82516001600160a01b031681526020808401516001600160401b0390811691830191909152604080850151821690830152606080850151918216908301526102c082019050608084015162001e0460808401826001600160601b03169052565b5060a084015162001e2060a08401826001600160a01b03169052565b5060c084015162001e3c60c08401826001600160a01b03169052565b5060e084015162001e5860e08401826001600160a01b03169052565b5062000f3961010083018462001c92565b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000919060409081850190868401855b8281101562001f0157815180516001600160a01b031685528681015163ffffffff1687860152858101516001600160401b03908116878701526060808301519091169086015260809081015115159085015260a0909301929085019060010162001e9c565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b8281101562001f0157815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e0909301929085019060010162001f2b565b6020808252825182820181905260009190848201906040850190845b8181101562001fe65783516001600160a01b03168352928401929184019160010162001fbf565b50909695505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000efe5762000efe62001ff2565b60008162002030576200203062001ff2565b506000190190565b63ffffffff81811683821601908082111562001349576200134962001ff2565b6000604080830163ffffffff8616845260206040602086015281865180845260608701915060208801935060005b81811015620020ba57845180516001600160a01b0316845284015161ffff1684840152938301939185019160010162002086565b509098975050505050505050565b808202811582820484141762000efe5762000efe62001ff2565b6000826200210057634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b0382811682821603908082111562001349576200134962001ff2565b6000602082840312156200213b57600080fd5b5051919050565b818103600083128015838313168383128216171562001349576200134962001ff2565b6000602082840312156200217857600080fd5b62000f398262001694565b634e487b7160e01b600052603160045260246000fd5b60005b83811015620021b65781810151838201526020016200219c565b50506000910152565b60008251620021d381846020870162002199565b9190910192915050565b6020815260008251806020840152620021fe81604085016020870162002199565b601f01601f19169190910160400192915050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f94620023406000396000818161036101528181610f1801526137a3015260008181610332015281816117160152613774015260008181610303015281816113cc0152818161143101528181611c8901528181611d17015261374501526000818161026f01528181610a4e0152818161183e0152818161223701528181612acf01526136b101526000818161023f01528181611de80152613681015260008181610210015281816110c30152818161164201528181611a5f01528181611b6001528181612666015281816136520152613a410152600081816102cf01528181611c2c015261371101526000818161029f015281816127c101526136e10152600061243f0152615f946000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80637437ff9f116100f9578063c92b283211610097578063eff7cc4811610071578063eff7cc48146109fc578063f25561fd14610a04578063f2fde38b14610a17578063fbca3b7414610a2a57600080fd5b8063c92b2832146109ce578063d09dc339146109e1578063df0aa9e9146109e957600080fd5b8063856c8247116100d3578063856c8247146108a05780638da5cb5b146108b35780639a113c36146108c4578063b06d41bc146109b857600080fd5b80637437ff9f146106c057806376f6ae761461088557806379ba50971461089857600080fd5b806348a98aa411610166578063549e946f11610140578063549e946f1461066957806354b714681461067c578063599f64311461069c578063704b6c02146106ad57600080fd5b806348a98aa4146105c7578063528d4a92146105f2578063546719cd1461060557600080fd5b806320487ded1161019757806320487ded146105705780634120fccd146105915780634816f4f7146105b257600080fd5b806306285c69146101be5780631772047e146103a7578063181f5a7714610527575b600080fd5b6103916040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091526040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60405161039e9190614ba3565b60405180910390f35b6104bb6103b5366004614bd7565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152506001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c082015290565b60405161039e9190600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b6105636040518060400160405280601781526020017f45564d3245564d4f6e52616d7020312e352e302d64657600000000000000000081525081565b60405161039e9190614c44565b61058361057e366004614c85565b610a4a565b60405190815260200161039e565b610599610ea0565b60405167ffffffffffffffff909116815260200161039e565b6105c56105c0366004614e93565b610ec7565b005b6105da6105d5366004614fd0565b610edd565b6040516001600160a01b03909116815260200161039e565b6105c5610600366004615009565b610f8c565b61060d610fa0565b60405161039e919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6105c5610677366004615119565b611032565b600e546040516bffffffffffffffffffffffff909116815260200161039e565b6002546001600160a01b03166105da565b6105c56106bb366004614bd7565b6111ab565b610878604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915250604080516101c0810182526005546001600160a01b038082168352600160a01b820461ffff9081166020850152760100000000000000000000000000000000000000000000830463ffffffff908116958501959095527a0100000000000000000000000000000000000000000000000000008304811660608501527c0100000000000000000000000000000000000000000000000000000000928390048516608085015260065480821660a086015262010000808204831660c0870152640100000000820490931660e086015278010000000000000000000000000000000000000000000000008104861661010086015292909204841661012084015260075491821661014084015281048316610160830152660100000000000081049092166101808201526a010000000000000000000090910460ff1615156101a082015290565b60405161039e9190615242565b6105c5610893366004615251565b611275565b6105c56112d8565b6105996108ae366004614bd7565b6113a1565b6000546001600160a01b03166105da565b61096e6108d2366004614bd7565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b03166000908152600b60209081526040918290208251608081018452905463ffffffff8116825267ffffffffffffffff64010000000082048116938301939093526c0100000000000000000000000081049092169281019290925260ff600160a01b909104161515606082015290565b60408051825163ffffffff16815260208084015167ffffffffffffffff9081169183019190915283830151169181019190915260609182015115159181019190915260800161039e565b6109c061149c565b60405161039e92919061531a565b6105c56109dc36600461535c565b611597565b6105836115ff565b6105836109f73660046153ca565b6116bf565b6105c56124b3565b6105c5610a12366004615436565b612738565b6105c5610a25366004614bd7565b612749565b610a3d610a38366004615535565b61275a565b60405161039e9190615552565b60007f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168367ffffffffffffffff1614610aca576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6000610ae1610adc608085018561559f565b61278e565b9050610b11610af3602085018561559f565b8351909150610b056040870187615604565b9050846020015161291b565b6000600b81610b266080870160608801614bd7565b6001600160a01b0316815260208082019290925260409081016000208151608081018352905463ffffffff81168252640100000000810467ffffffffffffffff908116948301949094526c01000000000000000000000000810490931691810191909152600160a01b90910460ff16151560608201819052909150610bf357610bb56080850160608601614bd7565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610ac1565b600654600090819064010000000090046001600160a01b031663ffdb4b37610c216080890160608a01614bd7565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff8a1660248201526044016040805180830381865afa158015610c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb09190615698565b90925090506000808080610cc760408b018b615604565b90501115610d0157610cf5610ce260808b0160608c01614bd7565b86610cf060408d018d615604565b612a84565b91945092509050610d1d565b8551610d1a9063ffffffff16662386f26fc100006156e1565b92505b60065460009062010000900461ffff1615610d7157610d6e6dffffffffffffffffffffffffffff607087901c16610d5760208d018d61559f565b9050610d6660408e018e615604565b905085612e66565b90505b60208781015160055460009267ffffffffffffffff9092169163ffffffff8716917a010000000000000000000000000000000000000000000000000000900461ffff1690610dc1908f018f61559f565b610dcc9291506156e1565b6005548c51610dfb91760100000000000000000000000000000000000000000000900463ffffffff16906156f8565b610e0591906156f8565b610e0f91906156f8565b610e29906dffffffffffffffffffffffffffff89166156e1565b610e3391906156e1565b9050867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1682828a6040015167ffffffffffffffff1688610e7091906156e1565b610e7a91906156f8565b610e8491906156f8565b610e8e919061570b565b99505050505050505050505b92915050565b600e54600090610ec290600160801b900467ffffffffffffffff16600161572d565b905090565b610ecf612f36565b610ed98282612f8e565b5050565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610f61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f85919061574e565b9392505050565b610f9461330a565b610f9d81613364565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff8082168352600160801b80830463ffffffff166020850152600160a01b90920460ff161515938301939093526004548084166060840152049091166080820152610ec2906137dd565b61103a612f36565b6001600160a01b03811661107a576040517f232cb97f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006110846115ff565b905060008112156110c1576040517f02075e0000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316036111135761110e6001600160a01b038416838361388f565b505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015261110e9083906001600160a01b038616906370a0823190602401602060405180830381865afa158015611176573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119a919061576b565b6001600160a01b038616919061388f565b6000546001600160a01b031633148015906111d157506002546001600160a01b03163314155b15611208576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b61127d612f36565b610ed98282808060200260200160405190810160405280939291908181526020016000905b828210156112ce576112bf60408302860136819003810190615784565b815260200190600101906112a2565b505050505061390f565b6001546001600160a01b031633146113325760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610ac1565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b038082166000908152600d6020526040812054909167ffffffffffffffff909116907f00000000000000000000000000000000000000000000000000000000000000001615610e9a5780600003610e9a576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611478573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8591906157c3565b60606000806114ab6008613b75565b90508067ffffffffffffffff8111156114c6576114c6614cd5565b60405190808252806020026020018201604052801561150b57816020015b60408051808201909152600080825260208201528152602001906001900390816114e45790505b50925060005b8181101561157457600080611527600884613b80565b915091506040518060400160405280836001600160a01b031681526020018261ffff1681525086848151811061155f5761155f6157e0565b60209081029190910101525050600101611511565b5050600e5491926c0100000000000000000000000090920463ffffffff16919050565b6000546001600160a01b031633148015906115bd57506002546001600160a01b03163314155b156115f4576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f9d600382613b9e565b600e546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916bffffffffffffffffffffffff16907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611691573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b5919061576b565b610ec291906157f6565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608086901b1660048201526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561175d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117819190615816565b156117b8576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0382166117f8576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b0316331461183c576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168567ffffffffffffffff16146118b5576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610ac1565b60006118c7610adc608087018761559f565b905060006118d86040870187615604565b91506118fe90506118ec602088018861559f565b9050836000015183856020015161291b565b8015611a55576000805b82811015611a435761191d6040890189615604565b8281811061192d5761192d6157e0565b90506040020160200135600003611970576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c600061198160408b018b615604565b84818110611991576119916157e0565b6119a79260206040909202019081019150614bd7565b6001600160a01b031681526020810191909152604001600020547201000000000000000000000000000000000000900460ff1615611a3b57611a2e6119ef60408a018a615604565b838181106119ff576119ff6157e0565b905060400201803603810190611a159190615833565b60065464010000000090046001600160a01b0316613d31565b611a3890836156f8565b91505b600101611908565b508015611a5357611a5381613e52565b505b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016611a8f6080880160608901614bd7565b6001600160a01b031603611af357600e8054869190600090611ac09084906bffffffffffffffffffffffff1661586d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550611c1a565b60065464010000000090046001600160a01b03166241e5be611b1b6080890160608a01614bd7565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018990527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa158015611ba7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bcb919061576b565b600e8054600090611beb9084906bffffffffffffffffffffffff1661586d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b600e546bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811691161115611c87576040517fe5c7a49100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615611dd2576001600160a01b0384166000908152600d602052604081205467ffffffffffffffff169003611dd2576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d8291906157c3565b6001600160a01b0385166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790555b604080516101a08101825267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526001600160a01b03861660208201526000918101611e65611e2b8a8061559f565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613e5f92505050565b6001600160a01b03168152602001600e601081819054906101000a900467ffffffffffffffff16611e9590615892565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff168152602001846000015181526020016000151581526020018460200151611f3f576001600160a01b0387166000908152600d602052604081208054909190611f159067ffffffffffffffff16615892565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055611f42565b60005b67ffffffffffffffff168152602001611f6160808a0160608b01614bd7565b6001600160a01b03168152602001878152602001888060200190611f85919061559f565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001611fcc60408a018a615604565b808060200260200160405190810160405280939291908181526020016000905b828210156120185761200960408302860136819003810190615833565b81526020019060010190611fec565b505050505081526020018367ffffffffffffffff81111561203b5761203b614cd5565b60405190808252806020026020018201604052801561206e57816020015b60608152602001906001900390816120595790505b508152600060209091018190529091505b8281101561243857600061209660408a018a615604565b838181106120a6576120a66157e0565b9050604002018036038101906120bc9190615833565b905060006120ce8b8360000151610edd565b90506001600160a01b038116158061218457506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa15801561215e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121829190615816565b155b156121c95781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610ac1565b6000816001600160a01b0316639a4575b96040518060a001604052808e80600001906121f5919061559f565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525067ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166020808301919091526001600160a01b03808f16604080850191909152918901516060840152885116608090920191909152517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526122c091906004016158b9565b6000604051808303816000875af11580156122df573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526123079190810190615986565b9050602081602001515111156123985782516001600160a01b03166000908152600c602090815260409091205490820151516e01000000000000000000000000000090910463ffffffff1610156123985782516040517f36f536ca0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610ac1565b80516123a390613e5f565b5060408051606081019091526001600160a01b03831660808201528060a0810160405160208183030381529060405281526020018260000151815260200182602001518152506040516020016123f99190615a17565b604051602081830303815290604052856101600151858151811061241f5761241f6157e0565b602002602001018190525050505080600101905061207f565b50612463817f0000000000000000000000000000000000000000000000000000000000000000613f05565b6101808201526040517fd0c3c799bf9e2639de44391e7f524d229b2b55f5b1ea94b2bf7da42f7243dddd90612499908390615b0e565b60405180910390a16101800151925050505b949350505050565b6000546001600160a01b03163314612518576002546001600160a01b03163314612518576124e2600833614060565b612518576040517f195db95800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff16600081900361256c576040517f990e30bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546bffffffffffffffffffffffff16818110156125b7576040517f8d0f71d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006125c16115ff565b12156125f9576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060006126066008613b75565b905060005b818110156126f557600080612621600884613b80565b9092509050600087612641836bffffffffffffffffffffffff8a166156e1565b61264b919061570b565b90506126578187615c43565b955061269b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846bffffffffffffffffffffffff841661388f565b6040516bffffffffffffffffffffffff821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a250505080600101905061260b565b5050600e80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff929092169190911790555050565b612740612f36565b610f9d81614075565b61275161330a565b610f9d816141e7565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091526000808252602082015260008290036127ef57506040805180820190915267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260006020820152610e9a565b60006127fb8385615c68565b90507fe7e230f0000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601612868576128538360048187615cb0565b8101906128609190615cda565b915050610e9a565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016128e95760408051808201909152806128c98560048189615cb0565b8101906128d69190615d06565b815260006020909101529150610e9a9050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006547801000000000000000000000000000000000000000000000000900463ffffffff1680851115612984576040517f869337890000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610ac1565b6006547c0100000000000000000000000000000000000000000000000000000000900463ffffffff168411156129e6576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554600160a01b900461ffff16831115612a2d576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81612a7d576007546a0100000000000000000000900460ff1615612a7d576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000808083815b81811015612e5a576000878783818110612aa757612aa76157e0565b905060400201803603810190612abd9190615833565b905060006001600160a01b0316612af87f00000000000000000000000000000000000000000000000000000000000000008360000151610edd565b6001600160a01b031603612b465780516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610ac1565b80516001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c08201819052612c7e57600754612c2f9061ffff16662386f26fc100006156e1565b612c3990886156f8565b600754909750612c559062010000900463ffffffff1687615d1f565b600754909650612c75906601000000000000900463ffffffff1686615d1f565b94505050612e52565b604081015160009061ffff1615612da25760008c6001600160a01b031684600001516001600160a01b031614612d455760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526401000000009092041690634ab35b0b90602401602060405180830381865afa158015612d1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d3e9190615d3c565b9050612d48565b508a5b620186a0836040015161ffff16612d8a8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166142a890919063ffffffff16565b612d9491906156e1565b612d9e919061570b565b9150505b6060820151612db19088615d1f565b9650816080015186612dc39190615d1f565b8251909650600090612de29063ffffffff16662386f26fc100006156e1565b905080821015612e0157612df6818a6156f8565b985050505050612e52565b6000836020015163ffffffff16662386f26fc10000612e2091906156e1565b905080831115612e4057612e34818b6156f8565b99505050505050612e52565b612e4a838b6156f8565b995050505050505b600101612a8b565b50509450945094915050565b60008063ffffffff8316612e7b6080866156e1565b612e87876102206156f8565b612e9191906156f8565b612e9b91906156f8565b6005546006549192506000917c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690612edd9061ffff16846156e1565b612ee791906156f8565b60065490915062010000900461ffff16612f116dffffffffffffffffffffffffffff8916836156e1565b612f1b91906156e1565b612f2b90655af3107a40006156e1565b979650505050505050565b6000546001600160a01b03163314612f8c576002546001600160a01b03163314612f8c576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60005b825181101561321c576000838281518110612fae57612fae6157e0565b6020026020010151905060208160a0015163ffffffff16101561301b57805160a08201516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526001600160a01b03909216600483015263ffffffff166024820152604401610ac1565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009096169590951764010000000092871692909202919091177fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff166801000000000000000093909216929092027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff16176a010000000000000000000091841691909102177fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff166e01000000000000000000000000000093909216929092027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1617720100000000000000000000000000000000000094151594909402939093177fffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff16730100000000000000000000000000000000000000931515939093029290921790915501612f91565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d08260405161324c9190615d57565b60405180910390a160005b81518110156132c757600c6000838381518110613276576132766157e0565b6020908102919091018101516001600160a01b0316825281019190915260400160002080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055600101613257565b50805115610ed9577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b816040516132fe9190615552565b60405180910390a15050565b6000546001600160a01b03163314612f8c5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610ac1565b60e08101516001600160a01b03166133a8576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081610180015163ffffffff161015613404576101808101516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526000600482015263ffffffff9091166024820152604401610ac1565b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548163ffffffff021916908363ffffffff1602179055506101a082015181600201600a6101000a81548160ff0219169083151502179055509050507fe375c8cb6ea9807cd0371503b632b93da5ee0f1f64205db8b5b28b95d6b588b06040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152508260405161126a929190615df7565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261386b82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261384f9190615e14565b85608001516fffffffffffffffffffffffffffffffff166142e5565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261110e90849061430d565b8051604081111561394c576040517fb5a10cfa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff16156139a057600e5463ffffffff6c010000000000000000000000008204166bffffffffffffffffffffffff909116106139a0576139a06124b3565b60006139ac6008613b75565b90505b80156139ee5760006139cd6139c5600184615e14565b600890613b80565b5090506139db6008826143f2565b5050806139e790615e27565b90506139af565b506000805b82811015613af6576000848281518110613a0f57613a0f6157e0565b60200260200101516000015190506000858381518110613a3157613a316157e0565b60200260200101516020015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480613a8657506001600160a01b038216155b15613ac8576040517f4de938d10000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610ac1565b613ad860088361ffff8416614407565b50613ae761ffff821685615d1f565b935050508060010190506139f3565b50600e80547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd2490613b689083908690615e5c565b60405180910390a1505050565b6000610e9a8261441d565b6000808080613b8f8686614428565b909450925050505b9250929050565b8154600090613bba90600160801b900463ffffffff1642615e14565b90508015613c425760018301548354613bf5916fffffffffffffffffffffffffffffffff808216928116918591600160801b909104166142e5565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617600160801b4263ffffffff16021783555b60208201518354613c68916fffffffffffffffffffffffffffffffff9081169116614453565b835483511515600160a01b027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff9283161717845560208301516040808501518316600160801b0291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990613b689084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613d97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dbb9190615e7b565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613e245783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610ac1565b60208401516124ab907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316906142a8565b610f9d6003826000614469565b60008151602014613e9e57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610ac19190614c44565b600082806020019051810190613eb4919061576b565b90506001600160a01b03811180613ecc575061040081105b15610e9a57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610ac19190614c44565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001613f9b9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001613fd49190615eae565b604051602081830303815290604052805190602001208761016001516040516020016140009190615ec1565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b6000610f85836001600160a01b038416614773565b60005b81518110156141b7576000828281518110614095576140956157e0565b60209081029190910181015160408051608080820183528385015163ffffffff90811683528385015167ffffffffffffffff908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9688166c0100000000000000000000000002969096167fffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090951691161792909217919091169290921717905550600101614078565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e8160405161126a9190615ed4565b336001600160a01b0382160361423f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610ac1565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a76400006142db837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166156e1565b610f85919061570b565b6000614304856142f584866156e1565b6142ff90876156f8565b614453565b95945050505050565b6000614362826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661477f9092919063ffffffff16565b80519091501561110e57808060200190518101906143809190615816565b61110e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ac1565b6000610f85836001600160a01b03841661478e565b60006124ab846001600160a01b038516846147ab565b6000610e9a826147c8565b6000808061443685856147d2565b600081815260029690960160205260409095205494959350505050565b60008183106144625781610f85565b5090919050565b8254600160a01b900460ff16158061447f575081155b1561448957505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906144c290600160801b900463ffffffff1642615e14565b905080156145685781831115614504576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461453190839085908490600160801b90046fffffffffffffffffffffffffffffffff166142e5565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff16600160801b4263ffffffff160217875592505b84821015614605576001600160a01b0384166145ba576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610ac1565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610ac1565b848310156146f157600186810154600160801b90046fffffffffffffffffffffffffffffffff1690600090829061463c9082615e14565b614646878a615e14565b61465091906156f8565b61465a919061570b565b90506001600160a01b0386166146a6576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610ac1565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610ac1565b6146fb8584615e14565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f8583836147de565b60606124ab84846000856147f6565b60008181526002830160205260408120819055610f8583836148dd565b600082815260028401602052604081208290556124ab84846148e9565b6000610e9a825490565b6000610f8583836148f5565b60008181526001830160205260408120541515610f85565b60608247101561486e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ac1565b600080866001600160a01b0316858760405161488a9190615f55565b60006040518083038185875af1925050503d80600081146148c7576040519150601f19603f3d011682016040523d82523d6000602084013e6148cc565b606091505b5091509150612f2b8783838761491f565b6000610f858383614998565b6000610f858383614a92565b600082600001828154811061490c5761490c6157e0565b9060005260206000200154905092915050565b6060831561498e578251600003614987576001600160a01b0385163b6149875760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ac1565b50816124ab565b6124ab8383614ae1565b60008181526001830160205260408120548015614a815760006149bc600183615e14565b85549091506000906149d090600190615e14565b9050818114614a355760008660000182815481106149f0576149f06157e0565b9060005260206000200154905080876000018481548110614a1357614a136157e0565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614a4657614a46615f71565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610e9a565b6000915050610e9a565b5092915050565b6000818152600183016020526040812054614ad957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e9a565b506000610e9a565b815115614af15781518083602001fd5b8060405162461bcd60e51b8152600401610ac19190614c44565b6001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401525060c0810151614b8860c08401826001600160a01b03169052565b5060e081015161110e60e08401826001600160a01b03169052565b6101008101610e9a8284614b0b565b6001600160a01b0381168114610f9d57600080fd5b8035614bd281614bb2565b919050565b600060208284031215614be957600080fd5b8135610f8581614bb2565b60005b83811015614c0f578181015183820152602001614bf7565b50506000910152565b60008151808452614c30816020860160208601614bf4565b601f01601f19169290920160200192915050565b602081526000610f856020830184614c18565b67ffffffffffffffff81168114610f9d57600080fd5b600060a08284031215614c7f57600080fd5b50919050565b60008060408385031215614c9857600080fd5b8235614ca381614c57565b9150602083013567ffffffffffffffff811115614cbf57600080fd5b614ccb85828601614c6d565b9150509250929050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614d0e57614d0e614cd5565b60405290565b6040516101c0810167ffffffffffffffff81118282101715614d0e57614d0e614cd5565b60405160a0810167ffffffffffffffff81118282101715614d0e57614d0e614cd5565b6040805190810167ffffffffffffffff81118282101715614d0e57614d0e614cd5565b604051601f8201601f1916810167ffffffffffffffff81118282101715614da757614da7614cd5565b604052919050565b600067ffffffffffffffff821115614dc957614dc9614cd5565b5060051b60200190565b63ffffffff81168114610f9d57600080fd5b8035614bd281614dd3565b803561ffff81168114614bd257600080fd5b8015158114610f9d57600080fd5b8035614bd281614e02565b600082601f830112614e2c57600080fd5b81356020614e41614e3c83614daf565b614d7e565b8083825260208201915060208460051b870101935086841115614e6357600080fd5b602086015b84811015614e88578035614e7b81614bb2565b8352918301918301614e68565b509695505050505050565b6000806040808486031215614ea757600080fd5b833567ffffffffffffffff80821115614ebf57600080fd5b818601915086601f830112614ed357600080fd5b81356020614ee3614e3c83614daf565b82815260e0928302850182019282820191908b851115614f0257600080fd5b958301955b84871015614fab5780878d031215614f1f5760008081fd5b614f27614ceb565b8735614f3281614bb2565b815287850135614f4181614dd3565b8186015287890135614f5281614dd3565b818a01526060614f63898201614df0565b90820152608088810135614f7681614dd3565b9082015260a0614f87898201614de5565b9082015260c0614f98898201614e10565b9082015283529586019591830191614f07565b5097505087013593505080831115614fc257600080fd5b5050614ccb85828601614e1b565b60008060408385031215614fe357600080fd5b8235614fee81614c57565b91506020830135614ffe81614bb2565b809150509250929050565b60006101c0828403121561501c57600080fd5b615024614d14565b61502d83614bc7565b815261503b60208401614df0565b602082015261504c60408401614de5565b604082015261505d60608401614df0565b606082015261506e60808401614de5565b608082015261507f60a08401614df0565b60a082015261509060c08401614df0565b60c08201526150a160e08401614bc7565b60e08201526101006150b4818501614de5565b908201526101206150c6848201614de5565b908201526101406150d8848201614df0565b908201526101606150ea848201614de5565b908201526101806150fc848201614de5565b908201526101a061510e848201614e10565b908201529392505050565b6000806040838503121561512c57600080fd5b8235614fee81614bb2565b80516001600160a01b031682526020810151615159602084018261ffff169052565b506040810151615171604084018263ffffffff169052565b506060810151615187606084018261ffff169052565b50608081015161519f608084018263ffffffff169052565b5060a08101516151b560a084018261ffff169052565b5060c08101516151cb60c084018261ffff169052565b5060e08101516151e660e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015182169084015261018080830151909116908301526101a0908101511515910152565b6101c08101610e9a8284615137565b6000806020838503121561526457600080fd5b823567ffffffffffffffff8082111561527c57600080fd5b818501915085601f83011261529057600080fd5b81358181111561529f57600080fd5b8660208260061b85010111156152b457600080fd5b60209290920196919550909350505050565b60008151808452602080850194506020840160005b8381101561530f57815180516001600160a01b0316885283015161ffff1683880152604090960195908201906001016152db565b509495945050505050565b60408152600061532d60408301856152c6565b90508260208301529392505050565b80356fffffffffffffffffffffffffffffffff81168114614bd257600080fd5b60006060828403121561536e57600080fd5b6040516060810181811067ffffffffffffffff8211171561539157615391614cd5565b604052823561539f81614e02565b81526153ad6020840161533c565b60208201526153be6040840161533c565b60408201529392505050565b600080600080608085870312156153e057600080fd5b84356153eb81614c57565b9350602085013567ffffffffffffffff81111561540757600080fd5b61541387828801614c6d565b93505060408501359150606085013561542b81614bb2565b939692955090935050565b6000602080838503121561544957600080fd5b823567ffffffffffffffff81111561546057600080fd5b8301601f8101851361547157600080fd5b803561547f614e3c82614daf565b81815260a0918202830184019184820191908884111561549e57600080fd5b938501935b838510156155295780858a0312156154bb5760008081fd5b6154c3614d38565b85356154ce81614bb2565b8152858701356154dd81614dd3565b818801526040868101356154f081614c57565b9082015260608681013561550381614c57565b9082015260808681013561551681614e02565b90820152835293840193918501916154a3565b50979650505050505050565b60006020828403121561554757600080fd5b8135610f8581614c57565b6020808252825182820181905260009190848201906040850190845b818110156155935783516001600160a01b03168352928401929184019160010161556e565b50909695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155d457600080fd5b83018035915067ffffffffffffffff8211156155ef57600080fd5b602001915036819003821315613b9757600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261563957600080fd5b83018035915067ffffffffffffffff82111561565457600080fd5b6020019150600681901b3603821315613b9757600080fd5b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114614bd257600080fd5b600080604083850312156156ab57600080fd5b6156b48361566c565b91506156c26020840161566c565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e9a57610e9a6156cb565b80820180821115610e9a57610e9a6156cb565b60008261572857634e487b7160e01b600052601260045260246000fd5b500490565b67ffffffffffffffff818116838216019080821115614a8b57614a8b6156cb565b60006020828403121561576057600080fd5b8151610f8581614bb2565b60006020828403121561577d57600080fd5b5051919050565b60006040828403121561579657600080fd5b61579e614d5b565b82356157a981614bb2565b81526157b760208401614df0565b60208201529392505050565b6000602082840312156157d557600080fd5b8151610f8581614c57565b634e487b7160e01b600052603260045260246000fd5b8181036000831280158383131683831282161715614a8b57614a8b6156cb565b60006020828403121561582857600080fd5b8151610f8581614e02565b60006040828403121561584557600080fd5b61584d614d5b565b823561585881614bb2565b81526020928301359281019290925250919050565b6bffffffffffffffffffffffff818116838216019080821115614a8b57614a8b6156cb565b600067ffffffffffffffff8083168181036158af576158af6156cb565b6001019392505050565b602081526000825160a060208401526158d560c0840182614c18565b905067ffffffffffffffff602085015116604084015260408401516001600160a01b038082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600082601f83011261593357600080fd5b815167ffffffffffffffff81111561594d5761594d614cd5565b6159606020601f19601f84011601614d7e565b81815284602083860101111561597557600080fd5b6124ab826020830160208701614bf4565b60006020828403121561599857600080fd5b815167ffffffffffffffff808211156159b057600080fd5b90830190604082860312156159c457600080fd5b6159cc614d5b565b8251828111156159db57600080fd5b6159e787828601615922565b8252506020830151828111156159fc57600080fd5b615a0887828601615922565b60208301525095945050505050565b602081526000825160606020840152615a336080840182614c18565b90506020840151601f1980858403016040860152615a518383614c18565b92506040860151915080858403016060860152506143048282614c18565b60008151808452602080850194506020840160005b8381101561530f57815180516001600160a01b031688528301518388015260409096019590820190600101615a84565b60008282518085526020808601955060208260051b8401016020860160005b84811015615b0157601f19868403018952615aef838351614c18565b98840198925090830190600101615ad3565b5090979650505050505050565b60208152615b2960208201835167ffffffffffffffff169052565b60006020830151615b4560408401826001600160a01b03169052565b5060408301516001600160a01b038116606084015250606083015167ffffffffffffffff8116608084015250608083015160a083015260a0830151615b8e60c084018215159052565b5060c083015167ffffffffffffffff811660e08401525060e0830151610100615bc1818501836001600160a01b03169052565b840151610120848101919091528401516101a061014080860182905291925090615bef6101c0860184614c18565b9250808601519050601f19610160818786030181880152615c108584615a6f565b945080880151925050610180818786030181880152615c2f8584615ab4565b970151959092019490945250929392505050565b6bffffffffffffffffffffffff828116828216039080821115614a8b57614a8b6156cb565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015615ca85780818660040360031b1b83161692505b505092915050565b60008085851115615cc057600080fd5b83861115615ccd57600080fd5b5050820193919092039150565b600060408284031215615cec57600080fd5b615cf4614d5b565b8235815260208301356157b781614e02565b600060208284031215615d1857600080fd5b5035919050565b63ffffffff818116838216019080821115614a8b57614a8b6156cb565b600060208284031215615d4e57600080fd5b610f858261566c565b602080825282518282018190526000919060409081850190868401855b82811015615dea57815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e09093019290850190600101615d74565b5091979650505050505050565b6102c08101615e068285614b0b565b610f85610100830184615137565b81810381811115610e9a57610e9a6156cb565b600081615e3657615e366156cb565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b63ffffffff831681526040602082015260006124ab60408301846152c6565b600060408284031215615e8d57600080fd5b615e95614d5b565b615e9e8361566c565b815260208301516157b781614dd3565b602081526000610f856020830184615a6f565b602081526000610f856020830184615ab4565b602080825282518282018190526000919060409081850190868401855b82811015615dea57815180516001600160a01b031685528681015163ffffffff16878601528581015167ffffffffffffffff908116878701526060808301519091169086015260809081015115159085015260a09093019290850190600101615ef1565b60008251615f67818460208701614bf4565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfea164736f6c6343000818000a", +} + +var EVM2EVMOnRampABI = EVM2EVMOnRampMetaData.ABI + +var EVM2EVMOnRampBin = EVM2EVMOnRampMetaData.Bin + +func DeployEVM2EVMOnRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMOnRampStaticConfig, dynamicConfig EVM2EVMOnRampDynamicConfig, rateLimiterConfig RateLimiterConfig, feeTokenConfigs []EVM2EVMOnRampFeeTokenConfigArgs, tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs, nopsAndWeights []EVM2EVMOnRampNopAndWeight) (common.Address, *types.Transaction, *EVM2EVMOnRamp, error) { + parsed, err := EVM2EVMOnRampMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMOnRampBin), backend, staticConfig, dynamicConfig, rateLimiterConfig, feeTokenConfigs, tokenTransferFeeConfigArgs, nopsAndWeights) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EVM2EVMOnRamp{address: address, abi: *parsed, EVM2EVMOnRampCaller: EVM2EVMOnRampCaller{contract: contract}, EVM2EVMOnRampTransactor: EVM2EVMOnRampTransactor{contract: contract}, EVM2EVMOnRampFilterer: EVM2EVMOnRampFilterer{contract: contract}}, nil +} + +type EVM2EVMOnRamp struct { + address common.Address + abi abi.ABI + EVM2EVMOnRampCaller + EVM2EVMOnRampTransactor + EVM2EVMOnRampFilterer +} + +type EVM2EVMOnRampCaller struct { + contract *bind.BoundContract +} + +type EVM2EVMOnRampTransactor struct { + contract *bind.BoundContract +} + +type EVM2EVMOnRampFilterer struct { + contract *bind.BoundContract +} + +type EVM2EVMOnRampSession struct { + Contract *EVM2EVMOnRamp + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type EVM2EVMOnRampCallerSession struct { + Contract *EVM2EVMOnRampCaller + CallOpts bind.CallOpts +} + +type EVM2EVMOnRampTransactorSession struct { + Contract *EVM2EVMOnRampTransactor + TransactOpts bind.TransactOpts +} + +type EVM2EVMOnRampRaw struct { + Contract *EVM2EVMOnRamp +} + +type EVM2EVMOnRampCallerRaw struct { + Contract *EVM2EVMOnRampCaller +} + +type EVM2EVMOnRampTransactorRaw struct { + Contract *EVM2EVMOnRampTransactor +} + +func NewEVM2EVMOnRamp(address common.Address, backend bind.ContractBackend) (*EVM2EVMOnRamp, error) { + abi, err := abi.JSON(strings.NewReader(EVM2EVMOnRampABI)) + if err != nil { + return nil, err + } + contract, err := bindEVM2EVMOnRamp(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &EVM2EVMOnRamp{address: address, abi: abi, EVM2EVMOnRampCaller: EVM2EVMOnRampCaller{contract: contract}, EVM2EVMOnRampTransactor: EVM2EVMOnRampTransactor{contract: contract}, EVM2EVMOnRampFilterer: EVM2EVMOnRampFilterer{contract: contract}}, nil +} + +func NewEVM2EVMOnRampCaller(address common.Address, caller bind.ContractCaller) (*EVM2EVMOnRampCaller, error) { + contract, err := bindEVM2EVMOnRamp(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampCaller{contract: contract}, nil +} + +func NewEVM2EVMOnRampTransactor(address common.Address, transactor bind.ContractTransactor) (*EVM2EVMOnRampTransactor, error) { + contract, err := bindEVM2EVMOnRamp(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampTransactor{contract: contract}, nil +} + +func NewEVM2EVMOnRampFilterer(address common.Address, filterer bind.ContractFilterer) (*EVM2EVMOnRampFilterer, error) { + contract, err := bindEVM2EVMOnRamp(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampFilterer{contract: contract}, nil +} + +func bindEVM2EVMOnRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EVM2EVMOnRampMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOnRamp.Contract.EVM2EVMOnRampCaller.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.EVM2EVMOnRampTransactor.contract.Transfer(opts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.EVM2EVMOnRampTransactor.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOnRamp.Contract.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.contract.Transfer(opts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "currentRateLimiterState") + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOnRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOnRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOnRampDynamicConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(EVM2EVMOnRampDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampDynamicConfig)).(*EVM2EVMOnRampDynamicConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetDynamicConfig() (EVM2EVMOnRampDynamicConfig, error) { + return _EVM2EVMOnRamp.Contract.GetDynamicConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetDynamicConfig() (EVM2EVMOnRampDynamicConfig, error) { + return _EVM2EVMOnRamp.Contract.GetDynamicConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getExpectedNextSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetExpectedNextSequenceNumber(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetExpectedNextSequenceNumber(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getFee", destChainSelector, message) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetFee(&_EVM2EVMOnRamp.CallOpts, destChainSelector, message) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetFee(&_EVM2EVMOnRamp.CallOpts, destChainSelector, message) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetFeeTokenConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getFeeTokenConfig", token) + + if err != nil { + return *new(EVM2EVMOnRampFeeTokenConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampFeeTokenConfig)).(*EVM2EVMOnRampFeeTokenConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetFeeTokenConfig(token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) { + return _EVM2EVMOnRamp.Contract.GetFeeTokenConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetFeeTokenConfig(token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) { + return _EVM2EVMOnRamp.Contract.GetFeeTokenConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetNopFeesJuels(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getNopFeesJuels") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetNopFeesJuels() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetNopFeesJuels(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetNopFeesJuels() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetNopFeesJuels(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetNops(opts *bind.CallOpts) (GetNops, + + error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getNops") + + outstruct := new(GetNops) + if err != nil { + return *outstruct, err + } + + outstruct.NopsAndWeights = *abi.ConvertType(out[0], new([]EVM2EVMOnRampNopAndWeight)).(*[]EVM2EVMOnRampNopAndWeight) + outstruct.WeightsTotal = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetNops() (GetNops, + + error) { + return _EVM2EVMOnRamp.Contract.GetNops(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetNops() (GetNops, + + error) { + return _EVM2EVMOnRamp.Contract.GetNops(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetPoolBySourceToken(opts *bind.CallOpts, arg0 uint64, sourceToken common.Address) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getPoolBySourceToken", arg0, sourceToken) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetPoolBySourceToken(arg0 uint64, sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMOnRamp.CallOpts, arg0, sourceToken) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetPoolBySourceToken(arg0 uint64, sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMOnRamp.CallOpts, arg0, sourceToken) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getSenderNonce", sender) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetSenderNonce(&_EVM2EVMOnRamp.CallOpts, sender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetSenderNonce(&_EVM2EVMOnRamp.CallOpts, sender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOnRampStaticConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(EVM2EVMOnRampStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampStaticConfig)).(*EVM2EVMOnRampStaticConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetStaticConfig() (EVM2EVMOnRampStaticConfig, error) { + return _EVM2EVMOnRamp.Contract.GetStaticConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetStaticConfig() (EVM2EVMOnRampStaticConfig, error) { + return _EVM2EVMOnRamp.Contract.GetStaticConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetSupportedTokens(opts *bind.CallOpts, arg0 uint64) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getSupportedTokens", arg0) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetSupportedTokens(arg0 uint64) ([]common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetSupportedTokens(&_EVM2EVMOnRamp.CallOpts, arg0) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetSupportedTokens(arg0 uint64) ([]common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetSupportedTokens(&_EVM2EVMOnRamp.CallOpts, arg0) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getTokenLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetTokenTransferFeeConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getTokenTransferFeeConfig", token) + + if err != nil { + return *new(EVM2EVMOnRampTokenTransferFeeConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampTokenTransferFeeConfig)).(*EVM2EVMOnRampTokenTransferFeeConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetTokenTransferFeeConfig(token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) { + return _EVM2EVMOnRamp.Contract.GetTokenTransferFeeConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetTokenTransferFeeConfig(token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) { + return _EVM2EVMOnRamp.Contract.GetTokenTransferFeeConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "linkAvailableForPayment") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) LinkAvailableForPayment() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.LinkAvailableForPayment(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) LinkAvailableForPayment() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.LinkAvailableForPayment(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) Owner() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.Owner(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) Owner() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.Owner(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) TypeAndVersion() (string, error) { + return _EVM2EVMOnRamp.Contract.TypeAndVersion(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) TypeAndVersion() (string, error) { + return _EVM2EVMOnRamp.Contract.TypeAndVersion(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "acceptOwnership") +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.AcceptOwnership(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.AcceptOwnership(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "forwardFromRouter", destChainSelector, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) ForwardFromRouter(destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ForwardFromRouter(&_EVM2EVMOnRamp.TransactOpts, destChainSelector, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) ForwardFromRouter(destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ForwardFromRouter(&_EVM2EVMOnRamp.TransactOpts, destChainSelector, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) PayNops(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "payNops") +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) PayNops() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.PayNops(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) PayNops() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.PayNops(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setAdmin", newAdmin) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetAdmin(&_EVM2EVMOnRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetAdmin(&_EVM2EVMOnRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setDynamicConfig", dynamicConfig) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetDynamicConfig(dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetDynamicConfig(&_EVM2EVMOnRamp.TransactOpts, dynamicConfig) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetDynamicConfig(dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetDynamicConfig(&_EVM2EVMOnRamp.TransactOpts, dynamicConfig) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetFeeTokenConfig(opts *bind.TransactOpts, feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setFeeTokenConfig", feeTokenConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetFeeTokenConfig(feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetFeeTokenConfig(&_EVM2EVMOnRamp.TransactOpts, feeTokenConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetFeeTokenConfig(feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetFeeTokenConfig(&_EVM2EVMOnRamp.TransactOpts, feeTokenConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetNops(opts *bind.TransactOpts, nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setNops", nopsAndWeights) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetNops(nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetNops(&_EVM2EVMOnRamp.TransactOpts, nopsAndWeights) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetNops(nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetNops(&_EVM2EVMOnRamp.TransactOpts, nopsAndWeights) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setRateLimiterConfig", config) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOnRamp.TransactOpts, config) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOnRamp.TransactOpts, config) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetTokenTransferFeeConfig(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setTokenTransferFeeConfig", tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetTokenTransferFeeConfig(tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetTokenTransferFeeConfig(&_EVM2EVMOnRamp.TransactOpts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetTokenTransferFeeConfig(tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetTokenTransferFeeConfig(&_EVM2EVMOnRamp.TransactOpts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "transferOwnership", to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.TransferOwnership(&_EVM2EVMOnRamp.TransactOpts, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.TransferOwnership(&_EVM2EVMOnRamp.TransactOpts, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) WithdrawNonLinkFees(opts *bind.TransactOpts, feeToken common.Address, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "withdrawNonLinkFees", feeToken, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) WithdrawNonLinkFees(feeToken common.Address, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.WithdrawNonLinkFees(&_EVM2EVMOnRamp.TransactOpts, feeToken, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) WithdrawNonLinkFees(feeToken common.Address, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.WithdrawNonLinkFees(&_EVM2EVMOnRamp.TransactOpts, feeToken, to) +} + +type EVM2EVMOnRampAdminSetIterator struct { + Event *EVM2EVMOnRampAdminSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampAdminSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampAdminSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampAdminSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampAdminSet struct { + NewAdmin common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOnRampAdminSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampAdminSetIterator{contract: _EVM2EVMOnRamp.contract, event: "AdminSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAdminSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampAdminSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseAdminSet(log types.Log) (*EVM2EVMOnRampAdminSet, error) { + event := new(EVM2EVMOnRampAdminSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampCCIPSendRequestedIterator struct { + Event *EVM2EVMOnRampCCIPSendRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampCCIPSendRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampCCIPSendRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampCCIPSendRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampCCIPSendRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampCCIPSendRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampCCIPSendRequested struct { + Message InternalEVM2EVMMessage + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterCCIPSendRequested(opts *bind.FilterOpts) (*EVM2EVMOnRampCCIPSendRequestedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "CCIPSendRequested") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampCCIPSendRequestedIterator{contract: _EVM2EVMOnRamp.contract, event: "CCIPSendRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampCCIPSendRequested) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "CCIPSendRequested") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampCCIPSendRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseCCIPSendRequested(log types.Log) (*EVM2EVMOnRampCCIPSendRequested, error) { + event := new(EVM2EVMOnRampCCIPSendRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampConfigChangedIterator struct { + Event *EVM2EVMOnRampConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampConfigChangedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampConfigChanged struct { + Config RateLimiterConfig + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*EVM2EVMOnRampConfigChangedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampConfigChangedIterator{contract: _EVM2EVMOnRamp.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampConfigChanged) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampConfigChanged) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseConfigChanged(log types.Log) (*EVM2EVMOnRampConfigChanged, error) { + event := new(EVM2EVMOnRampConfigChanged) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampConfigSetIterator struct { + Event *EVM2EVMOnRampConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampConfigSet struct { + StaticConfig EVM2EVMOnRampStaticConfig + DynamicConfig EVM2EVMOnRampDynamicConfig + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampConfigSetIterator{contract: _EVM2EVMOnRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseConfigSet(log types.Log) (*EVM2EVMOnRampConfigSet, error) { + event := new(EVM2EVMOnRampConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampFeeConfigSetIterator struct { + Event *EVM2EVMOnRampFeeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampFeeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampFeeConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampFeeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampFeeConfigSet struct { + FeeConfig []EVM2EVMOnRampFeeTokenConfigArgs + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampFeeConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "FeeConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampFeeConfigSetIterator{contract: _EVM2EVMOnRamp.contract, event: "FeeConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampFeeConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "FeeConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "FeeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseFeeConfigSet(log types.Log) (*EVM2EVMOnRampFeeConfigSet, error) { + event := new(EVM2EVMOnRampFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "FeeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampNopPaidIterator struct { + Event *EVM2EVMOnRampNopPaid + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampNopPaidIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopPaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopPaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampNopPaidIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampNopPaidIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampNopPaid struct { + Nop common.Address + Amount *big.Int + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterNopPaid(opts *bind.FilterOpts, nop []common.Address) (*EVM2EVMOnRampNopPaidIterator, error) { + + var nopRule []interface{} + for _, nopItem := range nop { + nopRule = append(nopRule, nopItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "NopPaid", nopRule) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampNopPaidIterator{contract: _EVM2EVMOnRamp.contract, event: "NopPaid", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchNopPaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopPaid, nop []common.Address) (event.Subscription, error) { + + var nopRule []interface{} + for _, nopItem := range nop { + nopRule = append(nopRule, nopItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "NopPaid", nopRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampNopPaid) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopPaid", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseNopPaid(log types.Log) (*EVM2EVMOnRampNopPaid, error) { + event := new(EVM2EVMOnRampNopPaid) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopPaid", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampNopsSetIterator struct { + Event *EVM2EVMOnRampNopsSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampNopsSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopsSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopsSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampNopsSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampNopsSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampNopsSet struct { + NopWeightsTotal *big.Int + NopsAndWeights []EVM2EVMOnRampNopAndWeight + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterNopsSet(opts *bind.FilterOpts) (*EVM2EVMOnRampNopsSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "NopsSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampNopsSetIterator{contract: _EVM2EVMOnRamp.contract, event: "NopsSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchNopsSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopsSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "NopsSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampNopsSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopsSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseNopsSet(log types.Log) (*EVM2EVMOnRampNopsSet, error) { + event := new(EVM2EVMOnRampNopsSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopsSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampOwnershipTransferRequestedIterator struct { + Event *EVM2EVMOnRampOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampOwnershipTransferRequestedIterator{contract: _EVM2EVMOnRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampOwnershipTransferRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOnRampOwnershipTransferRequested, error) { + event := new(EVM2EVMOnRampOwnershipTransferRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampOwnershipTransferredIterator struct { + Event *EVM2EVMOnRampOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampOwnershipTransferredIterator{contract: _EVM2EVMOnRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampOwnershipTransferred) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseOwnershipTransferred(log types.Log) (*EVM2EVMOnRampOwnershipTransferred, error) { + event := new(EVM2EVMOnRampOwnershipTransferred) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator struct { + Event *EVM2EVMOnRampTokenTransferFeeConfigDeleted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampTokenTransferFeeConfigDeleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampTokenTransferFeeConfigDeleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampTokenTransferFeeConfigDeleted struct { + Tokens []common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts) (*EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "TokenTransferFeeConfigDeleted") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator{contract: _EVM2EVMOnRamp.contract, event: "TokenTransferFeeConfigDeleted", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampTokenTransferFeeConfigDeleted) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "TokenTransferFeeConfigDeleted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampTokenTransferFeeConfigDeleted) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "TokenTransferFeeConfigDeleted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseTokenTransferFeeConfigDeleted(log types.Log) (*EVM2EVMOnRampTokenTransferFeeConfigDeleted, error) { + event := new(EVM2EVMOnRampTokenTransferFeeConfigDeleted) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "TokenTransferFeeConfigDeleted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampTokenTransferFeeConfigSetIterator struct { + Event *EVM2EVMOnRampTokenTransferFeeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampTokenTransferFeeConfigSet struct { + TransferFeeConfig []EVM2EVMOnRampTokenTransferFeeConfigArgs + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterTokenTransferFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampTokenTransferFeeConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "TokenTransferFeeConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampTokenTransferFeeConfigSetIterator{contract: _EVM2EVMOnRamp.contract, event: "TokenTransferFeeConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchTokenTransferFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampTokenTransferFeeConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "TokenTransferFeeConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "TokenTransferFeeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseTokenTransferFeeConfigSet(log types.Log) (*EVM2EVMOnRampTokenTransferFeeConfigSet, error) { + event := new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "TokenTransferFeeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampTokensConsumedIterator struct { + Event *EVM2EVMOnRampTokensConsumed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampTokensConsumedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampTokensConsumedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampTokensConsumedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampTokensConsumed struct { + Tokens *big.Int + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterTokensConsumed(opts *bind.FilterOpts) (*EVM2EVMOnRampTokensConsumedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampTokensConsumedIterator{contract: _EVM2EVMOnRamp.contract, event: "TokensConsumed", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampTokensConsumed) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampTokensConsumed) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseTokensConsumed(log types.Log) (*EVM2EVMOnRampTokensConsumed, error) { + event := new(EVM2EVMOnRampTokensConsumed) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetNops struct { + NopsAndWeights []EVM2EVMOnRampNopAndWeight + WeightsTotal *big.Int +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _EVM2EVMOnRamp.abi.Events["AdminSet"].ID: + return _EVM2EVMOnRamp.ParseAdminSet(log) + case _EVM2EVMOnRamp.abi.Events["CCIPSendRequested"].ID: + return _EVM2EVMOnRamp.ParseCCIPSendRequested(log) + case _EVM2EVMOnRamp.abi.Events["ConfigChanged"].ID: + return _EVM2EVMOnRamp.ParseConfigChanged(log) + case _EVM2EVMOnRamp.abi.Events["ConfigSet"].ID: + return _EVM2EVMOnRamp.ParseConfigSet(log) + case _EVM2EVMOnRamp.abi.Events["FeeConfigSet"].ID: + return _EVM2EVMOnRamp.ParseFeeConfigSet(log) + case _EVM2EVMOnRamp.abi.Events["NopPaid"].ID: + return _EVM2EVMOnRamp.ParseNopPaid(log) + case _EVM2EVMOnRamp.abi.Events["NopsSet"].ID: + return _EVM2EVMOnRamp.ParseNopsSet(log) + case _EVM2EVMOnRamp.abi.Events["OwnershipTransferRequested"].ID: + return _EVM2EVMOnRamp.ParseOwnershipTransferRequested(log) + case _EVM2EVMOnRamp.abi.Events["OwnershipTransferred"].ID: + return _EVM2EVMOnRamp.ParseOwnershipTransferred(log) + case _EVM2EVMOnRamp.abi.Events["TokenTransferFeeConfigDeleted"].ID: + return _EVM2EVMOnRamp.ParseTokenTransferFeeConfigDeleted(log) + case _EVM2EVMOnRamp.abi.Events["TokenTransferFeeConfigSet"].ID: + return _EVM2EVMOnRamp.ParseTokenTransferFeeConfigSet(log) + case _EVM2EVMOnRamp.abi.Events["TokensConsumed"].ID: + return _EVM2EVMOnRamp.ParseTokensConsumed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (EVM2EVMOnRampAdminSet) Topic() common.Hash { + return common.HexToHash("0x8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c") +} + +func (EVM2EVMOnRampCCIPSendRequested) Topic() common.Hash { + return common.HexToHash("0xd0c3c799bf9e2639de44391e7f524d229b2b55f5b1ea94b2bf7da42f7243dddd") +} + +func (EVM2EVMOnRampConfigChanged) Topic() common.Hash { + return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") +} + +func (EVM2EVMOnRampConfigSet) Topic() common.Hash { + return common.HexToHash("0xe375c8cb6ea9807cd0371503b632b93da5ee0f1f64205db8b5b28b95d6b588b0") +} + +func (EVM2EVMOnRampFeeConfigSet) Topic() common.Hash { + return common.HexToHash("0x067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e") +} + +func (EVM2EVMOnRampNopPaid) Topic() common.Hash { + return common.HexToHash("0x55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f") +} + +func (EVM2EVMOnRampNopsSet) Topic() common.Hash { + return common.HexToHash("0x8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd24") +} + +func (EVM2EVMOnRampOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (EVM2EVMOnRampOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (EVM2EVMOnRampTokenTransferFeeConfigDeleted) Topic() common.Hash { + return common.HexToHash("0xfb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b") +} + +func (EVM2EVMOnRampTokenTransferFeeConfigSet) Topic() common.Hash { + return common.HexToHash("0xf5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d0") +} + +func (EVM2EVMOnRampTokensConsumed) Topic() common.Hash { + return common.HexToHash("0x1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a") +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRamp) Address() common.Address { + return _EVM2EVMOnRamp.address +} + +type EVM2EVMOnRampInterface interface { + CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) + + GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOnRampDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) + + GetFeeTokenConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) + + GetNopFeesJuels(opts *bind.CallOpts) (*big.Int, error) + + GetNops(opts *bind.CallOpts) (GetNops, + + error) + + GetPoolBySourceToken(opts *bind.CallOpts, arg0 uint64, sourceToken common.Address) (common.Address, error) + + GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) + + GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOnRampStaticConfig, error) + + GetSupportedTokens(opts *bind.CallOpts, arg0 uint64) ([]common.Address, error) + + GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) + + GetTokenTransferFeeConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) + + LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) + + PayNops(opts *bind.TransactOpts) (*types.Transaction, error) + + SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) + + SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) + + SetFeeTokenConfig(opts *bind.TransactOpts, feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) + + SetNops(opts *bind.TransactOpts, nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) + + SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) + + SetTokenTransferFeeConfig(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + WithdrawNonLinkFees(opts *bind.TransactOpts, feeToken common.Address, to common.Address) (*types.Transaction, error) + + FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOnRampAdminSetIterator, error) + + WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAdminSet) (event.Subscription, error) + + ParseAdminSet(log types.Log) (*EVM2EVMOnRampAdminSet, error) + + FilterCCIPSendRequested(opts *bind.FilterOpts) (*EVM2EVMOnRampCCIPSendRequestedIterator, error) + + WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampCCIPSendRequested) (event.Subscription, error) + + ParseCCIPSendRequested(log types.Log) (*EVM2EVMOnRampCCIPSendRequested, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*EVM2EVMOnRampConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*EVM2EVMOnRampConfigChanged, error) + + FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*EVM2EVMOnRampConfigSet, error) + + FilterFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampFeeConfigSetIterator, error) + + WatchFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampFeeConfigSet) (event.Subscription, error) + + ParseFeeConfigSet(log types.Log) (*EVM2EVMOnRampFeeConfigSet, error) + + FilterNopPaid(opts *bind.FilterOpts, nop []common.Address) (*EVM2EVMOnRampNopPaidIterator, error) + + WatchNopPaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopPaid, nop []common.Address) (event.Subscription, error) + + ParseNopPaid(log types.Log) (*EVM2EVMOnRampNopPaid, error) + + FilterNopsSet(opts *bind.FilterOpts) (*EVM2EVMOnRampNopsSetIterator, error) + + WatchNopsSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopsSet) (event.Subscription, error) + + ParseNopsSet(log types.Log) (*EVM2EVMOnRampNopsSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOnRampOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*EVM2EVMOnRampOwnershipTransferred, error) + + FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts) (*EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator, error) + + WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampTokenTransferFeeConfigDeleted) (event.Subscription, error) + + ParseTokenTransferFeeConfigDeleted(log types.Log) (*EVM2EVMOnRampTokenTransferFeeConfigDeleted, error) + + FilterTokenTransferFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampTokenTransferFeeConfigSetIterator, error) + + WatchTokenTransferFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampTokenTransferFeeConfigSet) (event.Subscription, error) + + ParseTokenTransferFeeConfigSet(log types.Log) (*EVM2EVMOnRampTokenTransferFeeConfigSet, error) + + FilterTokensConsumed(opts *bind.FilterOpts) (*EVM2EVMOnRampTokensConsumedIterator, error) + + WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampTokensConsumed) (event.Subscription, error) + + ParseTokensConsumed(log types.Log) (*EVM2EVMOnRampTokensConsumed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0/evm_2_evm_onramp_1_0_0.go b/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0/evm_2_evm_onramp_1_0_0.go new file mode 100644 index 0000000000..6fd05d693a --- /dev/null +++ b/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0/evm_2_evm_onramp_1_0_0.go @@ -0,0 +1,2792 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package evm_2_evm_onramp_1_0_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientEVM2AnyMessage struct { + Receiver []byte + Data []byte + TokenAmounts []ClientEVMTokenAmount + FeeToken common.Address + ExtraArgs []byte +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type EVM2EVMOnRampDynamicConfig struct { + Router common.Address + MaxTokensLength uint16 + PriceRegistry common.Address + MaxDataSize uint32 + MaxGasLimit uint64 +} + +type EVM2EVMOnRampFeeTokenConfig struct { + NetworkFeeAmountUSD *big.Int + GasMultiplier uint64 + DestGasOverhead uint32 + DestGasPerPayloadByte uint16 + Enabled bool +} + +type EVM2EVMOnRampFeeTokenConfigArgs struct { + Token common.Address + GasMultiplier uint64 + NetworkFeeAmountUSD *big.Int + DestGasOverhead uint32 + DestGasPerPayloadByte uint16 + Enabled bool +} + +type EVM2EVMOnRampNopAndWeight struct { + Nop common.Address + Weight uint16 +} + +type EVM2EVMOnRampStaticConfig struct { + LinkToken common.Address + ChainSelector uint64 + DestChainSelector uint64 + DefaultTxGasLimit uint64 + MaxNopFeesJuels *big.Int + PrevOnRamp common.Address + ArmProxy common.Address +} + +type EVM2EVMOnRampTokenTransferFeeConfig struct { + MinFee uint32 + MaxFee uint32 + Ratio uint16 +} + +type EVM2EVMOnRampTokenTransferFeeConfigArgs struct { + Token common.Address + MinFee uint32 + MaxFee uint32 + Ratio uint16 +} + +type InternalEVM2EVMMessage struct { + SourceChainSelector uint64 + SequenceNumber uint64 + FeeTokenAmount *big.Int + Sender common.Address + Nonce uint64 + GasLimit *big.Int + Strict bool + Receiver common.Address + Data []byte + TokenAmounts []ClientEVMTokenAmount + FeeToken common.Address + MessageId [32]byte +} + +type InternalPoolUpdate struct { + Token common.Address + Pool common.Address +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +var EVM2EVMOnRampMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"maxGasLimit\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"tokensAndPools\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"networkFeeAmountUSD\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFee\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"}],\"name\":\"InvalidNopAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWithdrawParams\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkBalanceNotSettled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeeBalanceReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoFeesToPay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoNopsToPay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdminOrNop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyNops\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"AllowListEnabledSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"maxGasLimit\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"networkFeeAmountUSD\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeConfig\",\"type\":\"tuple[]\"}],\"name\":\"FeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NopPaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nopWeightsTotal\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"NopsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFee\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"transferFeeConfig\",\"type\":\"tuple[]\"}],\"name\":\"TokenTransferFeeConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"maxGasLimit\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getFeeTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"networkFeeAmountUSD\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfig\",\"name\":\"feeTokenConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNopFeesJuels\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNops\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"weightsTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFee\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"setAllowListEnabled\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"maxGasLimit\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"networkFeeAmountUSD\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setFeeTokenConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFee\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setTokenTransferFeeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawNonLinkFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101806040526012805460ff60c01b191690553480156200001f57600080fd5b50604051620081c9380380620081c9833981016040819052620000429162001eb3565b8333806000816200009a5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cd57620000cd8162000369565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555087516001600160a01b0316158062000176575060208801516001600160401b0316155b806200018d575060408801516001600160401b0316155b80620001a4575060608801516001600160401b0316155b80620001bb575060c08801516001600160a01b0316155b15620001da576040516306b7c75960e31b815260040160405180910390fd5b6020808901516040808b015181517fbdd59ac4dd1d82276c9a9c5d2656546346b9dcdb1f9b4204aed4ec15c23d7d3a948101949094526001600160401b039283169184019190915216606082015230608082015260a00160408051601f19818403018152918152815160209283012060809081528a516001600160a01b0390811660e052928b01516001600160401b0390811661010052918b015182166101205260608b015190911660a0908152908a01516001600160601b031660c0908152908a01518216610140528901511661016052620002b78762000414565b620002c28362000566565b620002cd82620006d8565b620002d881620007e5565b6040805160008082526020820190925262000323916200031b565b6040805180820190915260008082526020820152815260200190600190039081620002f35790505b508762000a0f565b8451156200035b576012805460ff60c81b1916600160c81b179055604080516000808252602082019092526200035b91508662000d12565b505050505050505062002405565b336001600160a01b03821603620003c35760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000091565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60408101516001600160a01b031662000440576040516306b7c75960e31b815260040160405180910390fd5b8051600580546020808501516001600160a01b039485166001600160b01b031990931692909217600160a01b61ffff909316830217909255604080850151600680546060808901516080808b0151958a166001600160c01b03199094169390931763ffffffff909116909602959095176001600160c01b0316600160c01b6001600160401b039485160217909155825160e080820185525187168152610100518316958101959095526101205182168584015260a080519092169385019390935260c080516001600160601b03169385019390935261014051851690840152610160519093169082015290517fdd226617d8d287f40a64c54741bbcdc492b3e096ef16bc5273a18cb6ab85f124916200055b91849062001fd6565b60405180910390a150565b60005b8151811015620006a65760008282815181106200058a576200058a62002086565b6020908102919091018101516040805160a08082018352828401516001600160601b039081168352848601516001600160401b0390811684880190815260608088015163ffffffff9081168789019081526080808b015161ffff908116948a01948552978b0151151590890190815299516001600160a01b03166000908152600f909b52979099209551865492519751915198511515600160d01b0260ff60d01b1999909616600160c01b0261ffff60c01b1992909a16600160a01b029190911665ffffffffffff60a01b19979093166c01000000000000000000000000026001600160a01b03199092169316929092179190911793909316929092179390931791909116179055506200069e81620020b2565b905062000569565b507ffba339fca97870ffdfaedbae3745db5e6de1a6909dfd0e0dbb56917469ffe236816040516200055b9190620020ce565b60005b8151811015620007b3576000828281518110620006fc57620006fc62002086565b60209081029190910181015160408051606080820183528385015163ffffffff90811683528385015181168387019081529185015161ffff90811684860190815295516001600160a01b031660009081526010909752939095209151825491519451909316680100000000000000000261ffff60401b19948616640100000000026001600160401b03199092169390951692909217919091179190911691909117905550620007ab81620020b2565b9050620006db565b507fcb0c5f472d325cf0c56953fc81870ddd80d0d3c9a3fbfe777002d75f380dfb81816040516200055b91906200216f565b805160408111156200080a57604051635ad0867d60e11b815260040160405180910390fd5b6012546c01000000000000000000000000900463ffffffff161580159062000854575060125463ffffffff6c010000000000000000000000008204166001600160601b0390911610155b1562000864576200086462000e5d565b60006200087260076200105d565b90505b8015620008be576000620008986200088f600184620021de565b60079062001070565b509050620008a86007826200108e565b505080620008b690620021f4565b905062000875565b506000805b82811015620009a6576000848281518110620008e357620008e362002086565b6020026020010151600001519050600085838151811062000908576200090862002086565b602002602001015160200151905060e0516001600160a01b0316826001600160a01b031614806200094057506001600160a01b038216155b156200096b57604051634de938d160e01b81526001600160a01b038316600482015260240162000091565b6200097d60078361ffff8416620010ac565b506200098e61ffff8216856200220e565b93505050806200099e90620020b2565b9050620008c3565b506012805463ffffffff60601b19166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249062000a0290839086906200222e565b60405180910390a1505050565b60005b825181101562000b4b57600083828151811062000a335762000a3362002086565b6020026020010151600001519050600084838151811062000a585762000a5862002086565b6020908102919091018101510151905062000a75600a83620010cc565b62000a9f576040516373913ebd60e01b81526001600160a01b038316600482015260240162000091565b6001600160a01b03811662000ab6600a84620010e3565b6001600160a01b03161462000ade57604051630d98f73360e31b815260040160405180910390fd5b62000aeb600a83620010fa565b1562000b3557604080516001600160a01b038085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a15b50508062000b4390620020b2565b905062000a12565b5060005b815181101562000d0d57600082828151811062000b705762000b7062002086565b6020026020010151600001519050600083838151811062000b955762000b9562002086565b602002602001015160200151905060006001600160a01b0316826001600160a01b0316148062000bcc57506001600160a01b038116155b1562000bea5760405162d8548360e71b815260040160405180910390fd5b806001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000c29573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c4f91906200229b565b6001600160a01b0316826001600160a01b03161462000c8157604051630d98f73360e31b815260040160405180910390fd5b62000c8f600a838362001111565b1562000cde57604080516001600160a01b038085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a162000cf7565b604051633caf458560e01b815260040160405180910390fd5b50508062000d0590620020b2565b905062000b4f565b505050565b60005b825181101562000da757600083828151811062000d365762000d3662002086565b6020908102919091010151905062000d50600d8262001129565b1562000d93576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5062000d9f81620020b2565b905062000d15565b5060005b815181101562000d0d57600082828151811062000dcc5762000dcc62002086565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000df8575062000e4a565b62000e05600d8262001140565b1562000e48576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b62000e5581620020b2565b905062000dab565b6000546001600160a01b0316331480159062000e8457506002546001600160a01b03163314155b801562000e9b575062000e9960073362001157565b155b1562000eba5760405163032bb72b60e31b815260040160405180910390fd5b6012546c01000000000000000000000000900463ffffffff16600081900362000ef65760405163990e30bf60e01b815260040160405180910390fd5b6012546001600160601b03168181101562000f24576040516311a1ee3b60e31b815260040160405180910390fd5b600062000f306200116e565b121562000f5057604051631e9acf1760e31b815260040160405180910390fd5b80600062000f5f60076200105d565b905060005b81811015620010375760008062000f7d60078462001070565b909250905060008762000f9a836001600160601b038a16620022bb565b62000fa69190620022d5565b905062000fb48187620022f8565b60e05190965062000fd9906001600160a01b0316846001600160601b038416620011fc565b6040516001600160601b03821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a2505050806200102f90620020b2565b905062000f64565b5050601280546001600160601b0319166001600160601b03929092169190911790555050565b60006200106a8262001254565b92915050565b600080808062001081868662001261565b9097909650945050505050565b6000620010a5836001600160a01b0384166200128e565b9392505050565b6000620010c4846001600160a01b03851684620012ad565b949350505050565b6000620010a5836001600160a01b038416620012cc565b6000620010a5836001600160a01b038416620012da565b6000620010a5836001600160a01b038416620012e8565b6000620010c4846001600160a01b03851684620012f6565b6000620010a5836001600160a01b0384166200130e565b6000620010a5836001600160a01b03841662001419565b6000620010a5836001600160a01b0384166200146b565b60125460e0516040516370a0823160e01b81523060048201526000926001600160601b0316916001600160a01b0316906370a0823190602401602060405180830381865afa158015620011c5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011eb91906200231b565b620011f7919062002335565b905090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915262000d0d9185916200147916565b60006200106a826200154a565b6000808062001271858562001555565b600081815260029690960160205260409095205494959350505050565b60008181526002830160205260408120819055620010a5838362001563565b60008281526002840160205260408120829055620010c4848462001571565b6000620010a583836200146b565b6000620010a583836200157f565b6000620010a583836200128e565b6000620010c484846001600160a01b038516620012ad565b600081815260018301602052604081205480156200140757600062001335600183620021de565b85549091506000906200134b90600190620021de565b9050818114620013b75760008660000182815481106200136f576200136f62002086565b906000526020600020015490508087600001848154811062001395576200139562002086565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620013cb57620013cb62002358565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200106a565b60009150506200106a565b5092915050565b600081815260018301602052604081205462001462575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200106a565b5060006200106a565b6000620010a58383620015f4565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620014c8906001600160a01b0385169084906200160d565b80519091501562000d0d5780806020019051810190620014e991906200236e565b62000d0d5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000091565b60006200106a825490565b6000620010a583836200161e565b6000620010a583836200130e565b6000620010a5838362001419565b600081815260028301602052604081205480151580620015a65750620015a684846200146b565b620010a55760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000604482015260640162000091565b60008181526001830160205260408120541515620010a5565b6060620010c484846000856200164b565b600082600001828154811062001638576200163862002086565b9060005260206000200154905092915050565b606082471015620016ae5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000091565b600080866001600160a01b03168587604051620016cc9190620023b2565b60006040518083038185875af1925050503d80600081146200170b576040519150601f19603f3d011682016040523d82523d6000602084013e62001710565b606091505b50909250905062001724878383876200172f565b979650505050505050565b60608315620017a35782516000036200179b576001600160a01b0385163b6200179b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000091565b5081620010c4565b620010c48383815115620017ba5781518083602001fd5b8060405162461bcd60e51b8152600401620000919190620023d0565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620018115762001811620017d6565b60405290565b60405160c081016001600160401b0381118282101715620018115762001811620017d6565b604051608081016001600160401b0381118282101715620018115762001811620017d6565b604051601f8201601f191681016001600160401b03811182821017156200188c576200188c620017d6565b604052919050565b6001600160a01b0381168114620018aa57600080fd5b50565b80516001600160401b0381168114620018c557600080fd5b919050565b80516001600160601b0381168114620018c557600080fd5b600060e08284031215620018f557600080fd5b60405160e081016001600160401b03811182821017156200191a576200191a620017d6565b806040525080915082516200192f8162001894565b81526200193f60208401620018ad565b60208201526200195260408401620018ad565b60408201526200196560608401620018ad565b60608201526200197860808401620018ca565b608082015260a08301516200198d8162001894565b60a082015260c0830151620019a28162001894565b60c0919091015292915050565b805161ffff81168114620018c557600080fd5b805163ffffffff81168114620018c557600080fd5b600060a08284031215620019ea57600080fd5b60405160a081016001600160401b038111828210171562001a0f5762001a0f620017d6565b8060405250809150825162001a248162001894565b815262001a3460208401620019af565b6020820152604083015162001a498162001894565b604082015262001a5c60608401620019c2565b606082015262001a6f60808401620018ad565b60808201525092915050565b60006001600160401b0382111562001a975762001a97620017d6565b5060051b60200190565b600082601f83011262001ab357600080fd5b8151602062001acc62001ac68362001a7b565b62001861565b82815260069290921b8401810191818101908684111562001aec57600080fd5b8286015b8481101562001b46576040818903121562001b0b5760008081fd5b62001b15620017ec565b815162001b228162001894565b81528185015162001b338162001894565b8186015283529183019160400162001af0565b509695505050505050565b600082601f83011262001b6357600080fd5b8151602062001b7662001ac68362001a7b565b82815260059290921b8401810191818101908684111562001b9657600080fd5b8286015b8481101562001b4657805162001bb08162001894565b835291830191830162001b9a565b80518015158114620018c557600080fd5b80516001600160801b0381168114620018c557600080fd5b60006060828403121562001bfa57600080fd5b604051606081016001600160401b038111828210171562001c1f5762001c1f620017d6565b60405290508062001c308362001bbe565b815262001c406020840162001bcf565b602082015262001c536040840162001bcf565b60408201525092915050565b600082601f83011262001c7157600080fd5b8151602062001c8462001ac68362001a7b565b82815260c0928302850182019282820191908785111562001ca457600080fd5b8387015b8581101562001d465781818a03121562001cc25760008081fd5b62001ccc62001817565b815162001cd98162001894565b815262001ce8828701620018ad565b86820152604062001cfb818401620018ca565b90820152606062001d0e838201620019c2565b90820152608062001d21838201620019af565b9082015260a062001d3483820162001bbe565b90820152845292840192810162001ca8565b5090979650505050505050565b600082601f83011262001d6557600080fd5b8151602062001d7862001ac68362001a7b565b82815260079290921b8401810191818101908684111562001d9857600080fd5b8286015b8481101562001b46576080818903121562001db75760008081fd5b62001dc16200183c565b815162001dce8162001894565b815262001ddd828601620019c2565b85820152604062001df0818401620019c2565b90820152606062001e03838201620019af565b9082015283529183019160800162001d9c565b600082601f83011262001e2857600080fd5b8151602062001e3b62001ac68362001a7b565b82815260069290921b8401810191818101908684111562001e5b57600080fd5b8286015b8481101562001b46576040818903121562001e7a5760008081fd5b62001e84620017ec565b815162001e918162001894565b815262001ea0828601620019af565b8186015283529183019160400162001e5f565b600080600080600080600080610280898b03121562001ed157600080fd5b62001edd8a8a620018e2565b975062001eee8a60e08b01620019d7565b6101808a01519097506001600160401b038082111562001f0d57600080fd5b62001f1b8c838d0162001aa1565b97506101a08b015191508082111562001f3357600080fd5b62001f418c838d0162001b51565b965062001f538c6101c08d0162001be7565b95506102208b015191508082111562001f6b57600080fd5b62001f798c838d0162001c5f565b94506102408b015191508082111562001f9157600080fd5b62001f9f8c838d0162001d53565b93506102608b015191508082111562001fb757600080fd5b5062001fc68b828c0162001e16565b9150509295985092959890939650565b82516001600160a01b0390811682526020808501516001600160401b03908116828501526040808701518216818601526060808801518316818701526080808901516001600160601b03168188015260a0808a015187169088015260c0808a01518716908801528751861660e08801529387015161ffff16610100870152908601519093166101208501529184015163ffffffff16610140840152830151166101608201526101808101620010a5565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620020c757620020c76200209c565b5060010190565b602080825282518282018190526000919060409081850190868401855b828110156200216257815180516001600160a01b03168552868101516001600160401b031687860152858101516001600160601b03168686015260608082015163ffffffff169086015260808082015161ffff169086015260a09081015115159085015260c09093019290850190600101620020eb565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b828110156200216257815180516001600160a01b031685528681015163ffffffff9081168887015286820151168686015260609081015161ffff1690850152608090930192908501906001016200218c565b818103818111156200106a576200106a6200209c565b6000816200220657620022066200209c565b506000190190565b63ffffffff8181168382160190808211156200141257620014126200209c565b6000604080830163ffffffff8616845260208281860152818651808452606087019150828801935060005b818110156200228d57845180516001600160a01b0316845284015161ffff1684840152938301939185019160010162002259565b509098975050505050505050565b600060208284031215620022ae57600080fd5b8151620010a58162001894565b80820281158282048414176200106a576200106a6200209c565b600082620022f357634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b038281168282160390808211156200141257620014126200209c565b6000602082840312156200232e57600080fd5b5051919050565b81810360008312801583831316838312821617156200141257620014126200209c565b634e487b7160e01b600052603160045260246000fd5b6000602082840312156200238157600080fd5b620010a58262001bbe565b60005b83811015620023a95781810151838201526020016200238f565b50506000910152565b60008251620023c68184602087016200238c565b9190910192915050565b6020815260008251806020840152620023f18160408501602087016200238c565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516101405161016051615cbd6200250c600039600081816103600152818161140a0152612c2001526000818161033101528181611320015281816113880152818161185a015281816118c20152612bf801526000818161029d01528181610af901528181611c520152612b7001526000818161026d0152818161198d0152612b4601526000818161023e01528181610dfa0152818161160d01528181611706015281816121a501528181612b2101528181612d6b015261323c0152600081816102fd015281816117d20152612bc20152600081816102cd015281816122bd0152612b9701526000611b6c0152615cbd6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806376f6ae761161010f578063b06d41bc116100a2578063e0351e1311610071578063e0351e13146108ee578063efeadb6d14610921578063eff7cc4814610934578063f2fde38b1461093c57600080fd5b8063b06d41bc146108b5578063c92b2832146108cb578063d09dc339146108de578063d3c7c2c7146108e657600080fd5b80638da5cb5b116100de5780638da5cb5b146107105780639a113c3614610721578063a7cd63b71461088d578063a7d3e02f146108a257600080fd5b806376f6ae76146106cf578063799c3a67146106e257806379ba5097146106f5578063856c8247146106fd57600080fd5b8063549e946f116101875780635d86f141116101565780635d86f141146105d45780635ebbd9f8146105e7578063704b6c02146105fa5780637437ff9f1461060d57600080fd5b8063549e946f1461056957806354b714681461057c57806354c8a4f31461059c578063599f6431146105af57600080fd5b80633a87ac53116101c35780633a87ac53146104bc5780633a9bf949146104d15780634120fccd146104e4578063546719cd1461050557600080fd5b806306285c69146101f55780631772047e146103a6578063181f5a771461045257806338724a951461049b575b600080fd5b6103906040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60405161039d9190614822565b60405180910390f35b6104216103b43660046148b3565b6040805160608082018352600080835260208084018290529284018190526001600160a01b039490941684526010825292829020825193840183525463ffffffff80821685526401000000008204169184019190915268010000000000000000900461ffff169082015290565b60408051825163ffffffff9081168252602080850151909116908201529181015161ffff169082015260600161039d565b61048e6040518060400160405280601381526020017f45564d3245564d4f6e52616d7020312e302e300000000000000000000000000081525081565b60405161039d919061493e565b6104ae6104a9366004614963565b61094f565b60405190815260200161039d565b6104cf6104ca366004614b4a565b610c8d565b005b6104cf6104df366004614bef565b610ca3565b6104ec610cb7565b60405167ffffffffffffffff909116815260200161039d565b61050d610ceb565b60405161039d919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6104cf610577366004614c83565b610d9b565b6012546040516bffffffffffffffffffffffff909116815260200161039d565b6104cf6105aa366004614d20565b610f50565b6002546001600160a01b03165b6040516001600160a01b03909116815260200161039d565b6105bc6105e23660046148b3565b610f62565b6104cf6105f5366004614d7a565b610fc1565b6104cf6106083660046148b3565b611027565b6106c26040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526005546001600160a01b038082168352740100000000000000000000000000000000000000009182900461ffff16602084015260065490811693830193909352820463ffffffff166060820152780100000000000000000000000000000000000000000000000090910467ffffffffffffffff16608082015290565b60405161039d9190614e58565b6104cf6106dd366004614eb2565b6110f1565b6104cf6106f0366004614f40565b6111a9565b6104cf61120f565b6104ec61070b3660046148b3565b6112f2565b6000546001600160a01b03166105bc565b61082761072f3660046148b3565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506001600160a01b03166000908152600f6020908152604091829020825160a08101845290546bffffffffffffffffffffffff811682526c01000000000000000000000000810467ffffffffffffffff169282019290925274010000000000000000000000000000000000000000820463ffffffff16928101929092527801000000000000000000000000000000000000000000000000810461ffff1660608301527a010000000000000000000000000000000000000000000000000000900460ff161515608082015290565b60405161039d9190600060a0820190506bffffffffffffffffffffffff835116825267ffffffffffffffff602084015116602083015263ffffffff604084015116604083015261ffff606084015116606083015260808301511515608083015292915050565b6108956113fa565b60405161039d919061505e565b6104ae6108b03660046150ab565b611406565b6108bd611d39565b60405161039d929190615159565b6104cf6108d936600461519b565b611e3d565b6104ae611ea5565b610895611eaf565b601254790100000000000000000000000000000000000000000000000000900460ff16604051901515815260200161039d565b6104cf61092f366004615209565b611f60565b6104cf611fe6565b6104cf61094a3660046148b3565b61227d565b600080600f8161096560808601606087016148b3565b6001600160a01b031681526020808201929092526040908101600020815160a08101835290546bffffffffffffffffffffffff811682526c01000000000000000000000000810467ffffffffffffffff169382019390935274010000000000000000000000000000000000000000830463ffffffff16918101919091527801000000000000000000000000000000000000000000000000820461ffff1660608201527a01000000000000000000000000000000000000000000000000000090910460ff16151560808201819052909150610a8c57610a4960808401606085016148b3565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024015b60405180910390fd5b60065460009081906001600160a01b031663ffdb4b37610ab260808801606089016148b3565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044016040805180830381865afa158015610b3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b61919061524e565b91509150600083600001516bffffffffffffffffffffffff16670de0b6b3a7640000856020015167ffffffffffffffff16866060015161ffff16898060200190610bab9190615281565b610bb6929150615315565b604088015163ffffffff16610bd6610bd160808d018d615281565b61228e565b51610be1919061532c565b610beb919061532c565b610bf59190615315565b610c199077ffffffffffffffffffffffffffffffffffffffffffffffff8616615315565b610c23919061533f565b610c2d919061532c565b9050610c55610c4260808801606089016148b3565b84610c5060408a018a61537a565b612382565b610c7977ffffffffffffffffffffffffffffffffffffffffffffffff8516836125ce565b610c83919061532c565b9695505050505050565b610c95612607565b610c9f828261267d565b5050565b610cab612607565b610cb4816129dd565b50565b601254600090610ce690700100000000000000000000000000000000900467ffffffffffffffff1660016153e2565b905090565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610ce690612c76565b6000546001600160a01b03163314801590610dc157506002546001600160a01b03163314155b15610df8576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480610e3f57506001600160a01b038116155b15610e76576040517f232cb97f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610e80612d28565b1215610eb8576040517f02075e0000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610c9f9082906001600160a01b038516906370a0823190602401602060405180830381865afa158015610f1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3f9190615403565b6001600160a01b0385169190612de8565b610f58612607565b610c9f8282612e68565b6000610f6f600a83612fa3565b610fb0576040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610a83565b610fbb600a83612fb8565b92915050565b6000546001600160a01b03163314801590610fe757506002546001600160a01b03163314155b1561101e576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cb481612fcd565b6000546001600160a01b0316331480159061104d57506002546001600160a01b03163314155b15611084576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b6000546001600160a01b0316331480159061111757506002546001600160a01b03163314155b1561114e576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c9f8282808060200260200160405190810160405280939291908181526020016000905b8282101561119f576111906040830286013681900381019061541c565b81526020019060010190611173565b5050505050613103565b6000546001600160a01b031633148015906111cf57506002546001600160a01b03163314155b15611206576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cb481613376565b6001546001600160a01b03163314611283576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610a83565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b03811660009081526011602052604081205467ffffffffffffffff168015801561134b57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15610fbb576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa1580156113cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f3919061545b565b9392505050565b6060610ce6600d613585565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611466573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148a9190615478565b156114c1576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114cb8480615281565b9050602014611512576114de8480615281565b6040517f370d875f000000000000000000000000000000000000000000000000000000008152600401610a839291906154de565b600061151e8580615281565b81019061152b91906154f2565b90506001600160a01b038111806115425750600a81105b15611551576114de8580615281565b6000611563610bd16080880188615281565b905061158f6115756020880188615281565b835190915061158760408a018a61537a565b905087613592565b61160361159f604088018861537a565b808060200260200160405190810160405280939291908181526020016000905b828210156115eb576115dc6040830286013681900381019061550b565b815260200190600101906115bf565b50506006546001600160a01b031692506137b5915050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001661163d60808801606089016148b3565b6001600160a01b0316036116a1576012805486919060009061166e9084906bffffffffffffffffffffffff16615545565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506117c0565b6006546001600160a01b03166241e5be6116c16080890160608a016148b3565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018990527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa15801561174d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117719190615403565b601280546000906117919084906bffffffffffffffffffffffff16615545565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b6012546bffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081169116111561182d576040517fe5c7a49100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03841660009081526011602052604090205467ffffffffffffffff1615801561188557507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b1561197d576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611909573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192d919061545b565b6001600160a01b038516600090815260116020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790555b60006040518061018001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020016012601081819054906101000a900467ffffffffffffffff166119dd9061556a565b825467ffffffffffffffff9182166101009390930a8381029083021990911617909255825260208083018a90526001600160a01b03891660408085018290526000918252601190925290812080546060909401939092611a3d911661556a565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200183600001518152602001600015158152602001846001600160a01b03168152602001888060200190611aa39190615281565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001611aea60408a018a61537a565b808060200260200160405190810160405280939291908181526020016000905b82821015611b3657611b276040830286013681900381019061550b565b81526020019060010190611b0a565b5050509183525050602001611b5160808a0160608b016148b3565b6001600160a01b0316815260006020909101529050611b90817f000000000000000000000000000000000000000000000000000000000000000061396e565b61016082015260005b611ba6604089018961537a565b9050811015611cf2576000611bbe60408a018a61537a565b83818110611bce57611bce615591565b905060400201803603810190611be4919061550b565b9050611bf38160000151610f62565b6001600160a01b0316639687544588611c0c8c80615281565b60208087015160408051928301815260008352517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b168152611c7a959493927f0000000000000000000000000000000000000000000000000000000000000000916004016155c0565b6000604051808303816000875af1158015611c99573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611cdf9190810190615618565b505080611ceb906156ca565b9050611b99565b507faffc45517195d6499808c643bd4a7b0ffeedf95bea5852840d7bfcf63f59e82181604051611d229190615746565b60405180910390a161016001519695505050505050565b6060600080611d486007613a78565b90508067ffffffffffffffff811115611d6357611d63614998565b604051908082528060200260200182016040528015611da857816020015b6040805180820190915260008082526020820152815260200190600190039081611d815790505b50925060005b81811015611e1a57600080611dc4600784613a83565b915091506040518060400160405280836001600160a01b031681526020018261ffff16815250868481518110611dfc57611dfc615591565b6020026020010181905250505080611e13906156ca565b9050611dae565b505060125491926c0100000000000000000000000090920463ffffffff16919050565b6000546001600160a01b03163314801590611e6357506002546001600160a01b03163314155b15611e9a576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cb4600382613aa1565b6000610ce6612d28565b60606000611ebd600a613c79565b67ffffffffffffffff811115611ed557611ed5614998565b604051908082528060200260200182016040528015611efe578160200160208202803683370190505b50905060005b8151811015611f5a57611f18600a82613c84565b50828281518110611f2b57611f2b615591565b60200260200101816001600160a01b03166001600160a01b03168152505080611f53906156ca565b9050611f04565b50919050565b611f68612607565b60128054821515790100000000000000000000000000000000000000000000000000027fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff9091161790556040517fccf4daf6ab6430389f26b970595dab82a5881ad454770907e415ede27c8df032906110e690831515815260200190565b6000546001600160a01b0316331480159061200c57506002546001600160a01b03163314155b8015612020575061201e600733613c93565b155b15612057576040517f195db95800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6012546c01000000000000000000000000900463ffffffff1660008190036120ab576040517f990e30bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6012546bffffffffffffffffffffffff16818110156120f6576040517f8d0f71d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612100612d28565b1215612138576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060006121456007613a78565b905060005b8181101561223a57600080612160600784613a83565b9092509050600087612180836bffffffffffffffffffffffff8a16615315565b61218a919061533f565b90506121968187615883565b95506121da6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846bffffffffffffffffffffffff8416612de8565b6040516bffffffffffffffffffffffff821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a250505080612233906156ca565b905061214a565b5050601280547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff929092169190911790555050565b612285612607565b610cb481613ca8565b60408051602081019091526000815260008290036122e45750604080516020810190915267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152610fbb565b7f97a657c90000000000000000000000000000000000000000000000000000000061230f83856158a8565b7fffffffff000000000000000000000000000000000000000000000000000000001614612368576040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61237582600481866158f0565b8101906113f3919061591a565b6000818082036123965760009150506125c6565b60005b818110156125c35760008585838181106123b5576123b5615591565b9050604002018036038101906123cb919061550b565b80516001600160a01b031660009081526010602090815260408083208151606081018352905463ffffffff8082168352640100000000820416938201939093526801000000000000000090920461ffff16908201819052929350911561252257825189906001600160a01b038c81169116146124cc5760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152911690634ab35b0b90602401602060405180830381865afa1580156124a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c9919061595c565b90505b620186a0836040015161ffff1661250a86602001518477ffffffffffffffffffffffffffffffffffffffffffffffff16613d8390919063ffffffff16565b6125149190615315565b61251e919061533f565b9150505b815160009061253e9063ffffffff16662386f26fc10000615315565b90506000836020015163ffffffff16662386f26fc1000061255f9190615315565b9050818310156125715781925061257d565b8083111561257d578092505b6125a177ffffffffffffffffffffffffffffffffffffffffffffffff8c16846125ce565b6125ab908961532c565b97505050505050806125bc906156ca565b9050612399565b50505b949350505050565b600077ffffffffffffffffffffffffffffffffffffffffffffffff83166125fd83670de0b6b3a7640000615315565b6113f3919061533f565b6000546001600160a01b0316331461267b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610a83565b565b60005b82518110156127de57600083828151811061269d5761269d615591565b602002602001015160000151905060008483815181106126bf576126bf615591565b60200260200101516020015190506126e182600a612fa390919063ffffffff16565b612722576040517f73913ebd0000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610a83565b6001600160a01b038116612737600a84612fb8565b6001600160a01b031614612777576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612782600a83613db2565b156127cb57604080516001600160a01b038085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a15b5050806127d7906156ca565b9050612680565b5060005b81518110156129d85760008282815181106127ff576127ff615591565b6020026020010151600001519050600083838151811061282157612821615591565b602002602001015160200151905060006001600160a01b0316826001600160a01b0316148061285757506001600160a01b038116155b1561288e576040517f6c2a418000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f09190615977565b6001600160a01b0316826001600160a01b03161461293a576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612946600a8383613dc7565b1561299357604080516001600160a01b038085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a16129c5565b6040517f3caf458500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050806129d1906156ca565b90506127e2565b505050565b60408101516001600160a01b0316612a21576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600580546020808501516001600160a01b039485167fffffffffffffffffffff00000000000000000000000000000000000000000000909316929092177401000000000000000000000000000000000000000061ffff909316830217909255604080850151600680546060808901516080808b0151958a167fffffffffffffffff0000000000000000000000000000000000000000000000009094169390931763ffffffff9091169096029590951777ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff9485160217909155825160e0810184527f0000000000000000000000000000000000000000000000000000000000000000871681527f00000000000000000000000000000000000000000000000000000000000000008316958101959095527f00000000000000000000000000000000000000000000000000000000000000008216858401527f0000000000000000000000000000000000000000000000000000000000000000909116928401929092527f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16918301919091527f0000000000000000000000000000000000000000000000000000000000000000831660a08301527f000000000000000000000000000000000000000000000000000000000000000090921660c082015290517fdd226617d8d287f40a64c54741bbcdc492b3e096ef16bc5273a18cb6ab85f124916110e6918490615994565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152612d0482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642612ce89190615a69565b85608001516fffffffffffffffffffffffffffffffff16613ddd565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6012546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916bffffffffffffffffffffffff16907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612dba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dde9190615403565b610ce69190615a7c565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526129d8908490613e05565b60005b8251811015612ef9576000838281518110612e8857612e88615591565b60200260200101519050612ea681600d613f0490919063ffffffff16565b15612ee8576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50612ef2816156ca565b9050612e6b565b5060005b81518110156129d8576000828281518110612f1a57612f1a615591565b6020026020010151905060006001600160a01b0316816001600160a01b031603612f445750612f93565b612f4f600d82613f19565b15612f91576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b612f9c816156ca565b9050612efd565b60006113f3836001600160a01b038416613f2e565b60006113f3836001600160a01b038416613f3a565b60005b81518110156130d3576000828281518110612fed57612fed615591565b60209081029190910181015160408051606080820183528385015163ffffffff90811683528385015181168387019081529185015161ffff90811684860190815295516001600160a01b03166000908152601090975293909520915182549151945190931668010000000000000000027fffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffff948616640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090921693909516929092179190911791909116919091179055506130cc816156ca565b9050612fd0565b507fcb0c5f472d325cf0c56953fc81870ddd80d0d3c9a3fbfe777002d75f380dfb81816040516110e69190615a9c565b80516040811115613140576040517fb5a10cfa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6012546c01000000000000000000000000900463ffffffff161580159061318e575060125463ffffffff6c010000000000000000000000008204166bffffffffffffffffffffffff90911610155b1561319b5761319b611fe6565b60006131a76007613a78565b90505b80156131e95760006131c86131c0600184615a69565b600790613a83565b5090506131d6600782613f46565b5050806131e290615b16565b90506131aa565b506000805b828110156132f757600084828151811061320a5761320a615591565b6020026020010151600001519050600085838151811061322c5761322c615591565b60200260200101516020015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316148061328157506001600160a01b038216155b156132c3576040517f4de938d10000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610a83565b6132d360078361ffff8416613f5b565b506132e261ffff821685615b4b565b93505050806132f0906156ca565b90506131ee565b50601280547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd24906133699083908690615b68565b60405180910390a1505050565b60005b815181101561355557600082828151811061339657613396615591565b6020908102919091018101516040805160a08082018352828401516bffffffffffffffffffffffff90811683528486015167ffffffffffffffff90811684880190815260608088015163ffffffff9081168789019081526080808b015161ffff908116948a01948552978b0151151590890190815299516001600160a01b03166000908152600f909b529790992095518654925197519151985115157a010000000000000000000000000000000000000000000000000000027fffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff999096167801000000000000000000000000000000000000000000000000027fffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffff92909a167401000000000000000000000000000000000000000002919091167fffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff979093166c01000000000000000000000000027fffffffffffffffffffffffff000000000000000000000000000000000000000090921693169290921791909117939093169290921793909317919091161790555061354e816156ca565b9050613379565b507ffba339fca97870ffdfaedbae3745db5e6de1a6909dfd0e0dbb56917469ffe236816040516110e69190615b87565b606060006113f383613f71565b6001600160a01b0381166135d2576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b03163314613616576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065474010000000000000000000000000000000000000000900463ffffffff168085111561367b576040517f869337890000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610a83565b6006547801000000000000000000000000000000000000000000000000900467ffffffffffffffff168411156136dd576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055474010000000000000000000000000000000000000000900461ffff16831115613735576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254790100000000000000000000000000000000000000000000000000900460ff16801561376c575061376a600d83613fcd565b155b156137ae576040517fd0d259760000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610a83565b5050505050565b81516000805b8281101561395a576000846001600160a01b031663d02641a08784815181106137e6576137e6615591565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b0390911660048201526024016040805180830381865afa15801561384d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138719190615c1f565b51905077ffffffffffffffffffffffffffffffffffffffffffffffff81166000036138f2578582815181106138a8576138a8615591565b6020908102919091010151516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a83565b61393c86838151811061390757613907615591565b6020026020010151602001518277ffffffffffffffffffffffffffffffffffffffffffffffff16613d8390919063ffffffff16565b613946908461532c565b92505080613953906156ca565b90506137bb565b506139686003826000613fef565b50505050565b60008060001b828460200151856080015186606001518760e00151886101000151805190602001208961012001516040516020016139ac9190615c52565b604051602081830303815290604052805190602001208a60a001518b60c001518c61014001518d60400151604051602001613a5a9c9b9a999897969594939291909b8c5260208c019a909a5267ffffffffffffffff98891660408c01529690971660608a01526001600160a01b0394851660808a015292841660a089015260c088019190915260e0870152610100860152911515610120850152166101408301526101608201526101800190565b60405160208183030381529060405280519060200120905092915050565b6000610fbb8261433e565b6000808080613a928686614349565b909450925050505b9250929050565b8154600090613aca90700100000000000000000000000000000000900463ffffffff1642615a69565b90508015613b6c5760018301548354613b12916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416613ddd565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354613b92916fffffffffffffffffffffffffffffffff9081169116614374565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906133699084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b6000610fbb82613a78565b6000808080613a928686613a83565b60006113f3836001600160a01b03841661438a565b336001600160a01b03821603613d1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610a83565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a76400006125fd8377ffffffffffffffffffffffffffffffffffffffffffffffff8616615315565b60006113f3836001600160a01b038416614396565b60006125c6846001600160a01b038516846143a2565b6000613dfc85613ded8486615315565b613df7908761532c565b614374565b95945050505050565b6000613e5a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166143b89092919063ffffffff16565b8051909150156129d85780806020019051810190613e789190615478565b6129d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a83565b60006113f3836001600160a01b0384166143c7565b60006113f3836001600160a01b0384166144c1565b60006113f3838361438a565b60006113f38383614510565b60006113f3836001600160a01b03841661459a565b60006125c6846001600160a01b038516846145b7565b606081600001805480602002602001604051908101604052809291908181526020018280548015613fc157602002820191906000526020600020905b815481526020019060010190808311613fad575b50505050509050919050565b6001600160a01b038116600090815260018301602052604081205415156113f3565b825474010000000000000000000000000000000000000000900460ff161580614016575081155b1561402057505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061406690700100000000000000000000000000000000900463ffffffff1642615a69565b9050801561412657818311156140a8576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546140e29083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16613ddd565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156141c3576001600160a01b038416614178576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610a83565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610a83565b848310156142bc5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906142079082615a69565b614211878a615a69565b61421b919061532c565b614225919061533f565b90506001600160a01b038616614271576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610a83565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610a83565b6142c68584615a69565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610fbb826145d4565b6000808061435785856145de565b600081815260029690960160205260409095205494959350505050565b600081831061438357816113f3565b5090919050565b60006113f383836145ea565b60006113f3838361459a565b60006125c684846001600160a01b0385166145b7565b60606125c68484600085614602565b600081815260018301602052604081205480156144b05760006143eb600183615a69565b85549091506000906143ff90600190615a69565b905081811461446457600086600001828154811061441f5761441f615591565b906000526020600020015490508087600001848154811061444257614442615591565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061447557614475615c65565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610fbb565b6000915050610fbb565b5092915050565b600081815260018301602052604081205461450857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610fbb565b506000610fbb565b6000818152600283016020526040812054801515806145345750614534848461438a565b6113f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b657900006044820152606401610a83565b600081815260028301602052604081208190556113f3838361470e565b600082815260028401602052604081208290556125c6848461471a565b6000610fbb825490565b60006113f38383614726565b600081815260018301602052604081205415156113f3565b606082471015614694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a83565b600080866001600160a01b031685876040516146b09190615c94565b60006040518083038185875af1925050503d80600081146146ed576040519150601f19603f3d011682016040523d82523d6000602084013e6146f2565b606091505b509150915061470387838387614750565b979650505050505050565b60006113f383836143c7565b60006113f383836144c1565b600082600001828154811061473d5761473d615591565b9060005260206000200154905092915050565b606083156147d95782516000036147d2576001600160a01b0385163b6147d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a83565b50816125c6565b6125c683838151156147ee5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a83919061493e565b60e08101610fbb82846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b6001600160a01b0381168114610cb457600080fd5b6000602082840312156148c557600080fd5b81356113f38161489e565b60005b838110156148eb5781810151838201526020016148d3565b50506000910152565b6000815180845261490c8160208601602086016148d0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006113f360208301846148f4565b600060a08284031215611f5a57600080fd5b60006020828403121561497557600080fd5b813567ffffffffffffffff81111561498c57600080fd5b6125c684828501614951565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156149ea576149ea614998565b60405290565b6040516080810167ffffffffffffffff811182821017156149ea576149ea614998565b60405160c0810167ffffffffffffffff811182821017156149ea576149ea614998565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614a7d57614a7d614998565b604052919050565b600067ffffffffffffffff821115614a9f57614a9f614998565b5060051b60200190565b600082601f830112614aba57600080fd5b81356020614acf614aca83614a85565b614a36565b82815260069290921b84018101918181019086841115614aee57600080fd5b8286015b84811015614b3f5760408189031215614b0b5760008081fd5b614b136149c7565b8135614b1e8161489e565b815281850135614b2d8161489e565b81860152835291830191604001614af2565b509695505050505050565b60008060408385031215614b5d57600080fd5b823567ffffffffffffffff80821115614b7557600080fd5b614b8186838701614aa9565b93506020850135915080821115614b9757600080fd5b50614ba485828601614aa9565b9150509250929050565b803561ffff81168114614bc057600080fd5b919050565b803563ffffffff81168114614bc057600080fd5b67ffffffffffffffff81168114610cb457600080fd5b600060a08284031215614c0157600080fd5b60405160a0810181811067ffffffffffffffff82111715614c2457614c24614998565b6040528235614c328161489e565b8152614c4060208401614bae565b60208201526040830135614c538161489e565b6040820152614c6460608401614bc5565b60608201526080830135614c7781614bd9565b60808201529392505050565b60008060408385031215614c9657600080fd5b8235614ca18161489e565b91506020830135614cb18161489e565b809150509250929050565b600082601f830112614ccd57600080fd5b81356020614cdd614aca83614a85565b82815260059290921b84018101918181019086841115614cfc57600080fd5b8286015b84811015614b3f578035614d138161489e565b8352918301918301614d00565b60008060408385031215614d3357600080fd5b823567ffffffffffffffff80821115614d4b57600080fd5b614d5786838701614cbc565b93506020850135915080821115614d6d57600080fd5b50614ba485828601614cbc565b60006020808385031215614d8d57600080fd5b823567ffffffffffffffff811115614da457600080fd5b8301601f81018513614db557600080fd5b8035614dc3614aca82614a85565b81815260079190911b82018301908381019087831115614de257600080fd5b928401925b828410156147035760808489031215614e005760008081fd5b614e086149f0565b8435614e138161489e565b8152614e20858701614bc5565b868201526040614e31818701614bc5565b908201526060614e42868201614bae565b9082015282526080939093019290840190614de7565b60a08101610fbb82846001600160a01b0380825116835261ffff60208301511660208401528060408301511660408401525063ffffffff606082015116606083015267ffffffffffffffff60808201511660808301525050565b60008060208385031215614ec557600080fd5b823567ffffffffffffffff80821115614edd57600080fd5b818501915085601f830112614ef157600080fd5b813581811115614f0057600080fd5b8660208260061b8501011115614f1557600080fd5b60209290920196919550909350505050565b8015158114610cb457600080fd5b8035614bc081614f27565b60006020808385031215614f5357600080fd5b823567ffffffffffffffff811115614f6a57600080fd5b8301601f81018513614f7b57600080fd5b8035614f89614aca82614a85565b81815260c09182028301840191848201919088841115614fa857600080fd5b938501935b838510156150525780858a031215614fc55760008081fd5b614fcd614a13565b8535614fd88161489e565b815285870135614fe781614bd9565b818801526040868101356bffffffffffffffffffffffff8116811461500c5760008081fd5b90820152606061501d878201614bc5565b90820152608061502e878201614bae565b9082015260a061503f878201614f35565b9082015283529384019391850191614fad565b50979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561509f5783516001600160a01b03168352928401929184019160010161507a565b50909695505050505050565b6000806000606084860312156150c057600080fd5b833567ffffffffffffffff8111156150d757600080fd5b6150e386828701614951565b9350506020840135915060408401356150fb8161489e565b809150509250925092565b600081518084526020808501945080840160005b8381101561514e57815180516001600160a01b0316885283015161ffff16838801526040909601959082019060010161511a565b509495945050505050565b60408152600061516c6040830185615106565b90508260208301529392505050565b80356fffffffffffffffffffffffffffffffff81168114614bc057600080fd5b6000606082840312156151ad57600080fd5b6040516060810181811067ffffffffffffffff821117156151d0576151d0614998565b60405282356151de81614f27565b81526151ec6020840161517b565b60208201526151fd6040840161517b565b60408201529392505050565b60006020828403121561521b57600080fd5b81356113f381614f27565b805177ffffffffffffffffffffffffffffffffffffffffffffffff81168114614bc057600080fd5b6000806040838503121561526157600080fd5b61526a83615226565b915061527860208401615226565b90509250929050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126152b657600080fd5b83018035915067ffffffffffffffff8211156152d157600080fd5b602001915036819003821315613a9a57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610fbb57610fbb6152e6565b80820180821115610fbb57610fbb6152e6565b600082615375577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126153af57600080fd5b83018035915067ffffffffffffffff8211156153ca57600080fd5b6020019150600681901b3603821315613a9a57600080fd5b67ffffffffffffffff8181168382160190808211156144ba576144ba6152e6565b60006020828403121561541557600080fd5b5051919050565b60006040828403121561542e57600080fd5b6154366149c7565b82356154418161489e565b815261544f60208401614bae565b60208201529392505050565b60006020828403121561546d57600080fd5b81516113f381614bd9565b60006020828403121561548a57600080fd5b81516113f381614f27565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006125c6602083018486615495565b60006020828403121561550457600080fd5b5035919050565b60006040828403121561551d57600080fd5b6155256149c7565b82356155308161489e565b81526020928301359281019290925250919050565b6bffffffffffffffffffffffff8181168382160190808211156144ba576144ba6152e6565b600067ffffffffffffffff808316818103615587576155876152e6565b6001019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6001600160a01b038716815260a0602082015260006155e360a083018789615495565b85604084015267ffffffffffffffff85166060840152828103608084015261560b81856148f4565b9998505050505050505050565b60006020828403121561562a57600080fd5b815167ffffffffffffffff8082111561564257600080fd5b818401915084601f83011261565657600080fd5b81518181111561566857615668614998565b61569960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a36565b91508082528560208285010111156156b057600080fd5b6156c18160208401602086016148d0565b50949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036156fb576156fb6152e6565b5060010190565b600081518084526020808501945080840160005b8381101561514e57815180516001600160a01b031688528301518388015260409096019590820190600101615716565b6020815261576160208201835167ffffffffffffffff169052565b6000602083015161577e604084018267ffffffffffffffff169052565b506040830151606083015260608301516157a360808401826001600160a01b03169052565b50608083015167ffffffffffffffff811660a08401525060a083015160c083015260c08301516157d760e084018215159052565b5060e08301516101006157f4818501836001600160a01b03169052565b8085015191505061018061012081818601526158146101a08601846148f4565b92508086015190506101407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086850301818701526158528483615702565b935080870151915050610160615872818701836001600160a01b03169052565b959095015193019290925250919050565b6bffffffffffffffffffffffff8281168282160390808211156144ba576144ba6152e6565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156158e85780818660040360031b1b83161692505b505092915050565b6000808585111561590057600080fd5b8386111561590d57600080fd5b5050820193919092039150565b60006020828403121561592c57600080fd5b6040516020810181811067ffffffffffffffff8211171561594f5761594f614998565b6040529135825250919050565b60006020828403121561596e57600080fd5b6113f382615226565b60006020828403121561598957600080fd5b81516113f38161489e565b6101808101615a1182856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b82516001600160a01b0390811660e0840152602084015161ffff16610100840152604084015116610120830152606083015163ffffffff16610140830152608083015167ffffffffffffffff166101608301526113f3565b81810381811115610fbb57610fbb6152e6565b81810360008312801583831316838312821617156144ba576144ba6152e6565b602080825282518282018190526000919060409081850190868401855b82811015615b0957815180516001600160a01b031685528681015163ffffffff9081168887015286820151168686015260609081015161ffff169085015260809093019290850190600101615ab9565b5091979650505050505050565b600081615b2557615b256152e6565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b63ffffffff8181168382160190808211156144ba576144ba6152e6565b63ffffffff831681526040602082015260006125c66040830184615106565b602080825282518282018190526000919060409081850190868401855b82811015615b0957815180516001600160a01b031685528681015167ffffffffffffffff1687860152858101516bffffffffffffffffffffffff168686015260608082015163ffffffff169086015260808082015161ffff169086015260a09081015115159085015260c09093019290850190600101615ba4565b600060408284031215615c3157600080fd5b615c396149c7565b615c4283615226565b8152602083015161544f81614bd9565b6020815260006113f36020830184615702565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251615ca68184602087016148d0565b919091019291505056fea164736f6c6343000813000a", +} + +var EVM2EVMOnRampABI = EVM2EVMOnRampMetaData.ABI + +var EVM2EVMOnRampBin = EVM2EVMOnRampMetaData.Bin + +func DeployEVM2EVMOnRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMOnRampStaticConfig, dynamicConfig EVM2EVMOnRampDynamicConfig, tokensAndPools []InternalPoolUpdate, allowlist []common.Address, rateLimiterConfig RateLimiterConfig, feeTokenConfigs []EVM2EVMOnRampFeeTokenConfigArgs, tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs, nopsAndWeights []EVM2EVMOnRampNopAndWeight) (common.Address, *types.Transaction, *EVM2EVMOnRamp, error) { + parsed, err := EVM2EVMOnRampMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMOnRampBin), backend, staticConfig, dynamicConfig, tokensAndPools, allowlist, rateLimiterConfig, feeTokenConfigs, tokenTransferFeeConfigArgs, nopsAndWeights) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EVM2EVMOnRamp{EVM2EVMOnRampCaller: EVM2EVMOnRampCaller{contract: contract}, EVM2EVMOnRampTransactor: EVM2EVMOnRampTransactor{contract: contract}, EVM2EVMOnRampFilterer: EVM2EVMOnRampFilterer{contract: contract}}, nil +} + +type EVM2EVMOnRamp struct { + address common.Address + abi abi.ABI + EVM2EVMOnRampCaller + EVM2EVMOnRampTransactor + EVM2EVMOnRampFilterer +} + +type EVM2EVMOnRampCaller struct { + contract *bind.BoundContract +} + +type EVM2EVMOnRampTransactor struct { + contract *bind.BoundContract +} + +type EVM2EVMOnRampFilterer struct { + contract *bind.BoundContract +} + +type EVM2EVMOnRampSession struct { + Contract *EVM2EVMOnRamp + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type EVM2EVMOnRampCallerSession struct { + Contract *EVM2EVMOnRampCaller + CallOpts bind.CallOpts +} + +type EVM2EVMOnRampTransactorSession struct { + Contract *EVM2EVMOnRampTransactor + TransactOpts bind.TransactOpts +} + +type EVM2EVMOnRampRaw struct { + Contract *EVM2EVMOnRamp +} + +type EVM2EVMOnRampCallerRaw struct { + Contract *EVM2EVMOnRampCaller +} + +type EVM2EVMOnRampTransactorRaw struct { + Contract *EVM2EVMOnRampTransactor +} + +func NewEVM2EVMOnRamp(address common.Address, backend bind.ContractBackend) (*EVM2EVMOnRamp, error) { + abi, err := abi.JSON(strings.NewReader(EVM2EVMOnRampABI)) + if err != nil { + return nil, err + } + contract, err := bindEVM2EVMOnRamp(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &EVM2EVMOnRamp{address: address, abi: abi, EVM2EVMOnRampCaller: EVM2EVMOnRampCaller{contract: contract}, EVM2EVMOnRampTransactor: EVM2EVMOnRampTransactor{contract: contract}, EVM2EVMOnRampFilterer: EVM2EVMOnRampFilterer{contract: contract}}, nil +} + +func NewEVM2EVMOnRampCaller(address common.Address, caller bind.ContractCaller) (*EVM2EVMOnRampCaller, error) { + contract, err := bindEVM2EVMOnRamp(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampCaller{contract: contract}, nil +} + +func NewEVM2EVMOnRampTransactor(address common.Address, transactor bind.ContractTransactor) (*EVM2EVMOnRampTransactor, error) { + contract, err := bindEVM2EVMOnRamp(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampTransactor{contract: contract}, nil +} + +func NewEVM2EVMOnRampFilterer(address common.Address, filterer bind.ContractFilterer) (*EVM2EVMOnRampFilterer, error) { + contract, err := bindEVM2EVMOnRamp(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampFilterer{contract: contract}, nil +} + +func bindEVM2EVMOnRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EVM2EVMOnRampMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOnRamp.Contract.EVM2EVMOnRampCaller.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.EVM2EVMOnRampTransactor.contract.Transfer(opts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.EVM2EVMOnRampTransactor.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOnRamp.Contract.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.contract.Transfer(opts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "currentRateLimiterState") + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOnRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOnRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetAllowList() ([]common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetAllowList(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetAllowList() ([]common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetAllowList(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetAllowListEnabled() (bool, error) { + return _EVM2EVMOnRamp.Contract.GetAllowListEnabled(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetAllowListEnabled() (bool, error) { + return _EVM2EVMOnRamp.Contract.GetAllowListEnabled(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOnRampDynamicConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(EVM2EVMOnRampDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampDynamicConfig)).(*EVM2EVMOnRampDynamicConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetDynamicConfig() (EVM2EVMOnRampDynamicConfig, error) { + return _EVM2EVMOnRamp.Contract.GetDynamicConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetDynamicConfig() (EVM2EVMOnRampDynamicConfig, error) { + return _EVM2EVMOnRamp.Contract.GetDynamicConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getExpectedNextSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetExpectedNextSequenceNumber(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetExpectedNextSequenceNumber(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetFee(opts *bind.CallOpts, message ClientEVM2AnyMessage) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getFee", message) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetFee(message ClientEVM2AnyMessage) (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetFee(&_EVM2EVMOnRamp.CallOpts, message) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetFee(message ClientEVM2AnyMessage) (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetFee(&_EVM2EVMOnRamp.CallOpts, message) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetFeeTokenConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getFeeTokenConfig", token) + + if err != nil { + return *new(EVM2EVMOnRampFeeTokenConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampFeeTokenConfig)).(*EVM2EVMOnRampFeeTokenConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetFeeTokenConfig(token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) { + return _EVM2EVMOnRamp.Contract.GetFeeTokenConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetFeeTokenConfig(token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) { + return _EVM2EVMOnRamp.Contract.GetFeeTokenConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetNopFeesJuels(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getNopFeesJuels") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetNopFeesJuels() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetNopFeesJuels(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetNopFeesJuels() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetNopFeesJuels(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetNops(opts *bind.CallOpts) (GetNops, + + error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getNops") + + outstruct := new(GetNops) + if err != nil { + return *outstruct, err + } + + outstruct.NopsAndWeights = *abi.ConvertType(out[0], new([]EVM2EVMOnRampNopAndWeight)).(*[]EVM2EVMOnRampNopAndWeight) + outstruct.WeightsTotal = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetNops() (GetNops, + + error) { + return _EVM2EVMOnRamp.Contract.GetNops(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetNops() (GetNops, + + error) { + return _EVM2EVMOnRamp.Contract.GetNops(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetPoolBySourceToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getPoolBySourceToken", sourceToken) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetPoolBySourceToken(sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMOnRamp.CallOpts, sourceToken) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetPoolBySourceToken(sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMOnRamp.CallOpts, sourceToken) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getSenderNonce", sender) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetSenderNonce(&_EVM2EVMOnRamp.CallOpts, sender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetSenderNonce(&_EVM2EVMOnRamp.CallOpts, sender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOnRampStaticConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(EVM2EVMOnRampStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampStaticConfig)).(*EVM2EVMOnRampStaticConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetStaticConfig() (EVM2EVMOnRampStaticConfig, error) { + return _EVM2EVMOnRamp.Contract.GetStaticConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetStaticConfig() (EVM2EVMOnRampStaticConfig, error) { + return _EVM2EVMOnRamp.Contract.GetStaticConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetSupportedTokens(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getSupportedTokens") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetSupportedTokens() ([]common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetSupportedTokens(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetSupportedTokens() ([]common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetSupportedTokens(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getTokenLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetTokenTransferFeeConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getTokenTransferFeeConfig", token) + + if err != nil { + return *new(EVM2EVMOnRampTokenTransferFeeConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampTokenTransferFeeConfig)).(*EVM2EVMOnRampTokenTransferFeeConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetTokenTransferFeeConfig(token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) { + return _EVM2EVMOnRamp.Contract.GetTokenTransferFeeConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetTokenTransferFeeConfig(token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) { + return _EVM2EVMOnRamp.Contract.GetTokenTransferFeeConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "linkAvailableForPayment") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) LinkAvailableForPayment() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.LinkAvailableForPayment(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) LinkAvailableForPayment() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.LinkAvailableForPayment(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) Owner() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.Owner(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) Owner() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.Owner(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) TypeAndVersion() (string, error) { + return _EVM2EVMOnRamp.Contract.TypeAndVersion(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) TypeAndVersion() (string, error) { + return _EVM2EVMOnRamp.Contract.TypeAndVersion(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "acceptOwnership") +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.AcceptOwnership(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.AcceptOwnership(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ApplyAllowListUpdates(&_EVM2EVMOnRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ApplyAllowListUpdates(&_EVM2EVMOnRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) ApplyPoolUpdates(opts *bind.TransactOpts, removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "applyPoolUpdates", removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) ApplyPoolUpdates(removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ApplyPoolUpdates(&_EVM2EVMOnRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) ApplyPoolUpdates(removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ApplyPoolUpdates(&_EVM2EVMOnRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) ForwardFromRouter(opts *bind.TransactOpts, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "forwardFromRouter", message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) ForwardFromRouter(message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ForwardFromRouter(&_EVM2EVMOnRamp.TransactOpts, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) ForwardFromRouter(message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ForwardFromRouter(&_EVM2EVMOnRamp.TransactOpts, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) PayNops(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "payNops") +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) PayNops() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.PayNops(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) PayNops() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.PayNops(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setAdmin", newAdmin) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetAdmin(&_EVM2EVMOnRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetAdmin(&_EVM2EVMOnRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetAllowListEnabled(opts *bind.TransactOpts, enabled bool) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setAllowListEnabled", enabled) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetAllowListEnabled(enabled bool) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetAllowListEnabled(&_EVM2EVMOnRamp.TransactOpts, enabled) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetAllowListEnabled(enabled bool) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetAllowListEnabled(&_EVM2EVMOnRamp.TransactOpts, enabled) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setDynamicConfig", dynamicConfig) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetDynamicConfig(dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetDynamicConfig(&_EVM2EVMOnRamp.TransactOpts, dynamicConfig) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetDynamicConfig(dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetDynamicConfig(&_EVM2EVMOnRamp.TransactOpts, dynamicConfig) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetFeeTokenConfig(opts *bind.TransactOpts, feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setFeeTokenConfig", feeTokenConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetFeeTokenConfig(feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetFeeTokenConfig(&_EVM2EVMOnRamp.TransactOpts, feeTokenConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetFeeTokenConfig(feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetFeeTokenConfig(&_EVM2EVMOnRamp.TransactOpts, feeTokenConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetNops(opts *bind.TransactOpts, nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setNops", nopsAndWeights) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetNops(nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetNops(&_EVM2EVMOnRamp.TransactOpts, nopsAndWeights) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetNops(nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetNops(&_EVM2EVMOnRamp.TransactOpts, nopsAndWeights) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setRateLimiterConfig", config) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOnRamp.TransactOpts, config) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOnRamp.TransactOpts, config) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetTokenTransferFeeConfig(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setTokenTransferFeeConfig", tokenTransferFeeConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetTokenTransferFeeConfig(tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetTokenTransferFeeConfig(&_EVM2EVMOnRamp.TransactOpts, tokenTransferFeeConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetTokenTransferFeeConfig(tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetTokenTransferFeeConfig(&_EVM2EVMOnRamp.TransactOpts, tokenTransferFeeConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "transferOwnership", to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.TransferOwnership(&_EVM2EVMOnRamp.TransactOpts, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.TransferOwnership(&_EVM2EVMOnRamp.TransactOpts, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) WithdrawNonLinkFees(opts *bind.TransactOpts, feeToken common.Address, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "withdrawNonLinkFees", feeToken, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) WithdrawNonLinkFees(feeToken common.Address, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.WithdrawNonLinkFees(&_EVM2EVMOnRamp.TransactOpts, feeToken, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) WithdrawNonLinkFees(feeToken common.Address, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.WithdrawNonLinkFees(&_EVM2EVMOnRamp.TransactOpts, feeToken, to) +} + +type EVM2EVMOnRampAdminSetIterator struct { + Event *EVM2EVMOnRampAdminSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampAdminSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampAdminSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampAdminSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampAdminSet struct { + NewAdmin common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOnRampAdminSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampAdminSetIterator{contract: _EVM2EVMOnRamp.contract, event: "AdminSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAdminSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampAdminSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseAdminSet(log types.Log) (*EVM2EVMOnRampAdminSet, error) { + event := new(EVM2EVMOnRampAdminSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampAllowListAddIterator struct { + Event *EVM2EVMOnRampAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampAllowListAddIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*EVM2EVMOnRampAllowListAddIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampAllowListAddIterator{contract: _EVM2EVMOnRamp.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampAllowListAdd) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseAllowListAdd(log types.Log) (*EVM2EVMOnRampAllowListAdd, error) { + event := new(EVM2EVMOnRampAllowListAdd) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampAllowListEnabledSetIterator struct { + Event *EVM2EVMOnRampAllowListEnabledSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampAllowListEnabledSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAllowListEnabledSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAllowListEnabledSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampAllowListEnabledSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampAllowListEnabledSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampAllowListEnabledSet struct { + Enabled bool + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterAllowListEnabledSet(opts *bind.FilterOpts) (*EVM2EVMOnRampAllowListEnabledSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "AllowListEnabledSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampAllowListEnabledSetIterator{contract: _EVM2EVMOnRamp.contract, event: "AllowListEnabledSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchAllowListEnabledSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAllowListEnabledSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "AllowListEnabledSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampAllowListEnabledSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AllowListEnabledSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseAllowListEnabledSet(log types.Log) (*EVM2EVMOnRampAllowListEnabledSet, error) { + event := new(EVM2EVMOnRampAllowListEnabledSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AllowListEnabledSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampAllowListRemoveIterator struct { + Event *EVM2EVMOnRampAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*EVM2EVMOnRampAllowListRemoveIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampAllowListRemoveIterator{contract: _EVM2EVMOnRamp.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampAllowListRemove) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseAllowListRemove(log types.Log) (*EVM2EVMOnRampAllowListRemove, error) { + event := new(EVM2EVMOnRampAllowListRemove) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampCCIPSendRequestedIterator struct { + Event *EVM2EVMOnRampCCIPSendRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampCCIPSendRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampCCIPSendRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampCCIPSendRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampCCIPSendRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampCCIPSendRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampCCIPSendRequested struct { + Message InternalEVM2EVMMessage + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterCCIPSendRequested(opts *bind.FilterOpts) (*EVM2EVMOnRampCCIPSendRequestedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "CCIPSendRequested") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampCCIPSendRequestedIterator{contract: _EVM2EVMOnRamp.contract, event: "CCIPSendRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampCCIPSendRequested) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "CCIPSendRequested") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampCCIPSendRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseCCIPSendRequested(log types.Log) (*EVM2EVMOnRampCCIPSendRequested, error) { + event := new(EVM2EVMOnRampCCIPSendRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampConfigSetIterator struct { + Event *EVM2EVMOnRampConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampConfigSet struct { + StaticConfig EVM2EVMOnRampStaticConfig + DynamicConfig EVM2EVMOnRampDynamicConfig + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampConfigSetIterator{contract: _EVM2EVMOnRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseConfigSet(log types.Log) (*EVM2EVMOnRampConfigSet, error) { + event := new(EVM2EVMOnRampConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampFeeConfigSetIterator struct { + Event *EVM2EVMOnRampFeeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampFeeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampFeeConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampFeeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampFeeConfigSet struct { + FeeConfig []EVM2EVMOnRampFeeTokenConfigArgs + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampFeeConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "FeeConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampFeeConfigSetIterator{contract: _EVM2EVMOnRamp.contract, event: "FeeConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampFeeConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "FeeConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "FeeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseFeeConfigSet(log types.Log) (*EVM2EVMOnRampFeeConfigSet, error) { + event := new(EVM2EVMOnRampFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "FeeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampNopPaidIterator struct { + Event *EVM2EVMOnRampNopPaid + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampNopPaidIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopPaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopPaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampNopPaidIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampNopPaidIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampNopPaid struct { + Nop common.Address + Amount *big.Int + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterNopPaid(opts *bind.FilterOpts, nop []common.Address) (*EVM2EVMOnRampNopPaidIterator, error) { + + var nopRule []interface{} + for _, nopItem := range nop { + nopRule = append(nopRule, nopItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "NopPaid", nopRule) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampNopPaidIterator{contract: _EVM2EVMOnRamp.contract, event: "NopPaid", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchNopPaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopPaid, nop []common.Address) (event.Subscription, error) { + + var nopRule []interface{} + for _, nopItem := range nop { + nopRule = append(nopRule, nopItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "NopPaid", nopRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampNopPaid) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopPaid", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseNopPaid(log types.Log) (*EVM2EVMOnRampNopPaid, error) { + event := new(EVM2EVMOnRampNopPaid) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopPaid", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampNopsSetIterator struct { + Event *EVM2EVMOnRampNopsSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampNopsSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopsSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopsSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampNopsSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampNopsSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampNopsSet struct { + NopWeightsTotal *big.Int + NopsAndWeights []EVM2EVMOnRampNopAndWeight + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterNopsSet(opts *bind.FilterOpts) (*EVM2EVMOnRampNopsSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "NopsSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampNopsSetIterator{contract: _EVM2EVMOnRamp.contract, event: "NopsSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchNopsSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopsSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "NopsSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampNopsSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopsSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseNopsSet(log types.Log) (*EVM2EVMOnRampNopsSet, error) { + event := new(EVM2EVMOnRampNopsSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopsSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampOwnershipTransferRequestedIterator struct { + Event *EVM2EVMOnRampOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampOwnershipTransferRequestedIterator{contract: _EVM2EVMOnRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampOwnershipTransferRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOnRampOwnershipTransferRequested, error) { + event := new(EVM2EVMOnRampOwnershipTransferRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampOwnershipTransferredIterator struct { + Event *EVM2EVMOnRampOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampOwnershipTransferredIterator{contract: _EVM2EVMOnRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampOwnershipTransferred) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseOwnershipTransferred(log types.Log) (*EVM2EVMOnRampOwnershipTransferred, error) { + event := new(EVM2EVMOnRampOwnershipTransferred) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampPoolAddedIterator struct { + Event *EVM2EVMOnRampPoolAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampPoolAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampPoolAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampPoolAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampPoolAddedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampPoolAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampPoolAdded struct { + Token common.Address + Pool common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterPoolAdded(opts *bind.FilterOpts) (*EVM2EVMOnRampPoolAddedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "PoolAdded") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampPoolAddedIterator{contract: _EVM2EVMOnRamp.contract, event: "PoolAdded", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchPoolAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampPoolAdded) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "PoolAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampPoolAdded) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "PoolAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParsePoolAdded(log types.Log) (*EVM2EVMOnRampPoolAdded, error) { + event := new(EVM2EVMOnRampPoolAdded) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "PoolAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampPoolRemovedIterator struct { + Event *EVM2EVMOnRampPoolRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampPoolRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampPoolRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampPoolRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampPoolRemovedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampPoolRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampPoolRemoved struct { + Token common.Address + Pool common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterPoolRemoved(opts *bind.FilterOpts) (*EVM2EVMOnRampPoolRemovedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "PoolRemoved") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampPoolRemovedIterator{contract: _EVM2EVMOnRamp.contract, event: "PoolRemoved", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchPoolRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampPoolRemoved) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "PoolRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampPoolRemoved) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "PoolRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParsePoolRemoved(log types.Log) (*EVM2EVMOnRampPoolRemoved, error) { + event := new(EVM2EVMOnRampPoolRemoved) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "PoolRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampTokenTransferFeeConfigSetIterator struct { + Event *EVM2EVMOnRampTokenTransferFeeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampTokenTransferFeeConfigSet struct { + TransferFeeConfig []EVM2EVMOnRampTokenTransferFeeConfigArgs + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterTokenTransferFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampTokenTransferFeeConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "TokenTransferFeeConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampTokenTransferFeeConfigSetIterator{contract: _EVM2EVMOnRamp.contract, event: "TokenTransferFeeConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchTokenTransferFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampTokenTransferFeeConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "TokenTransferFeeConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "TokenTransferFeeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseTokenTransferFeeConfigSet(log types.Log) (*EVM2EVMOnRampTokenTransferFeeConfigSet, error) { + event := new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "TokenTransferFeeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetNops struct { + NopsAndWeights []EVM2EVMOnRampNopAndWeight + WeightsTotal *big.Int +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _EVM2EVMOnRamp.abi.Events["AdminSet"].ID: + return _EVM2EVMOnRamp.ParseAdminSet(log) + case _EVM2EVMOnRamp.abi.Events["AllowListAdd"].ID: + return _EVM2EVMOnRamp.ParseAllowListAdd(log) + case _EVM2EVMOnRamp.abi.Events["AllowListEnabledSet"].ID: + return _EVM2EVMOnRamp.ParseAllowListEnabledSet(log) + case _EVM2EVMOnRamp.abi.Events["AllowListRemove"].ID: + return _EVM2EVMOnRamp.ParseAllowListRemove(log) + case _EVM2EVMOnRamp.abi.Events["CCIPSendRequested"].ID: + return _EVM2EVMOnRamp.ParseCCIPSendRequested(log) + case _EVM2EVMOnRamp.abi.Events["ConfigSet"].ID: + return _EVM2EVMOnRamp.ParseConfigSet(log) + case _EVM2EVMOnRamp.abi.Events["FeeConfigSet"].ID: + return _EVM2EVMOnRamp.ParseFeeConfigSet(log) + case _EVM2EVMOnRamp.abi.Events["NopPaid"].ID: + return _EVM2EVMOnRamp.ParseNopPaid(log) + case _EVM2EVMOnRamp.abi.Events["NopsSet"].ID: + return _EVM2EVMOnRamp.ParseNopsSet(log) + case _EVM2EVMOnRamp.abi.Events["OwnershipTransferRequested"].ID: + return _EVM2EVMOnRamp.ParseOwnershipTransferRequested(log) + case _EVM2EVMOnRamp.abi.Events["OwnershipTransferred"].ID: + return _EVM2EVMOnRamp.ParseOwnershipTransferred(log) + case _EVM2EVMOnRamp.abi.Events["PoolAdded"].ID: + return _EVM2EVMOnRamp.ParsePoolAdded(log) + case _EVM2EVMOnRamp.abi.Events["PoolRemoved"].ID: + return _EVM2EVMOnRamp.ParsePoolRemoved(log) + case _EVM2EVMOnRamp.abi.Events["TokenTransferFeeConfigSet"].ID: + return _EVM2EVMOnRamp.ParseTokenTransferFeeConfigSet(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (EVM2EVMOnRampAdminSet) Topic() common.Hash { + return common.HexToHash("0x8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c") +} + +func (EVM2EVMOnRampAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (EVM2EVMOnRampAllowListEnabledSet) Topic() common.Hash { + return common.HexToHash("0xccf4daf6ab6430389f26b970595dab82a5881ad454770907e415ede27c8df032") +} + +func (EVM2EVMOnRampAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (EVM2EVMOnRampCCIPSendRequested) Topic() common.Hash { + return common.HexToHash("0xaffc45517195d6499808c643bd4a7b0ffeedf95bea5852840d7bfcf63f59e821") +} + +func (EVM2EVMOnRampConfigSet) Topic() common.Hash { + return common.HexToHash("0xdd226617d8d287f40a64c54741bbcdc492b3e096ef16bc5273a18cb6ab85f124") +} + +func (EVM2EVMOnRampFeeConfigSet) Topic() common.Hash { + return common.HexToHash("0xfba339fca97870ffdfaedbae3745db5e6de1a6909dfd0e0dbb56917469ffe236") +} + +func (EVM2EVMOnRampNopPaid) Topic() common.Hash { + return common.HexToHash("0x55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f") +} + +func (EVM2EVMOnRampNopsSet) Topic() common.Hash { + return common.HexToHash("0x8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd24") +} + +func (EVM2EVMOnRampOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (EVM2EVMOnRampOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (EVM2EVMOnRampPoolAdded) Topic() common.Hash { + return common.HexToHash("0x95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c") +} + +func (EVM2EVMOnRampPoolRemoved) Topic() common.Hash { + return common.HexToHash("0x987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c") +} + +func (EVM2EVMOnRampTokenTransferFeeConfigSet) Topic() common.Hash { + return common.HexToHash("0xcb0c5f472d325cf0c56953fc81870ddd80d0d3c9a3fbfe777002d75f380dfb81") +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRamp) Address() common.Address { + return _EVM2EVMOnRamp.address +} + +type EVM2EVMOnRampInterface interface { + CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) + + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOnRampDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetFee(opts *bind.CallOpts, message ClientEVM2AnyMessage) (*big.Int, error) + + GetFeeTokenConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) + + GetNopFeesJuels(opts *bind.CallOpts) (*big.Int, error) + + GetNops(opts *bind.CallOpts) (GetNops, + + error) + + GetPoolBySourceToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) + + GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) + + GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOnRampStaticConfig, error) + + GetSupportedTokens(opts *bind.CallOpts) ([]common.Address, error) + + GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) + + GetTokenTransferFeeConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) + + LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyPoolUpdates(opts *bind.TransactOpts, removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) + + ForwardFromRouter(opts *bind.TransactOpts, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) + + PayNops(opts *bind.TransactOpts) (*types.Transaction, error) + + SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) + + SetAllowListEnabled(opts *bind.TransactOpts, enabled bool) (*types.Transaction, error) + + SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) + + SetFeeTokenConfig(opts *bind.TransactOpts, feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) + + SetNops(opts *bind.TransactOpts, nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) + + SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) + + SetTokenTransferFeeConfig(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + WithdrawNonLinkFees(opts *bind.TransactOpts, feeToken common.Address, to common.Address) (*types.Transaction, error) + + FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOnRampAdminSetIterator, error) + + WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAdminSet) (event.Subscription, error) + + ParseAdminSet(log types.Log) (*EVM2EVMOnRampAdminSet, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*EVM2EVMOnRampAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*EVM2EVMOnRampAllowListAdd, error) + + FilterAllowListEnabledSet(opts *bind.FilterOpts) (*EVM2EVMOnRampAllowListEnabledSetIterator, error) + + WatchAllowListEnabledSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAllowListEnabledSet) (event.Subscription, error) + + ParseAllowListEnabledSet(log types.Log) (*EVM2EVMOnRampAllowListEnabledSet, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*EVM2EVMOnRampAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*EVM2EVMOnRampAllowListRemove, error) + + FilterCCIPSendRequested(opts *bind.FilterOpts) (*EVM2EVMOnRampCCIPSendRequestedIterator, error) + + WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampCCIPSendRequested) (event.Subscription, error) + + ParseCCIPSendRequested(log types.Log) (*EVM2EVMOnRampCCIPSendRequested, error) + + FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*EVM2EVMOnRampConfigSet, error) + + FilterFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampFeeConfigSetIterator, error) + + WatchFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampFeeConfigSet) (event.Subscription, error) + + ParseFeeConfigSet(log types.Log) (*EVM2EVMOnRampFeeConfigSet, error) + + FilterNopPaid(opts *bind.FilterOpts, nop []common.Address) (*EVM2EVMOnRampNopPaidIterator, error) + + WatchNopPaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopPaid, nop []common.Address) (event.Subscription, error) + + ParseNopPaid(log types.Log) (*EVM2EVMOnRampNopPaid, error) + + FilterNopsSet(opts *bind.FilterOpts) (*EVM2EVMOnRampNopsSetIterator, error) + + WatchNopsSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopsSet) (event.Subscription, error) + + ParseNopsSet(log types.Log) (*EVM2EVMOnRampNopsSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOnRampOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*EVM2EVMOnRampOwnershipTransferred, error) + + FilterPoolAdded(opts *bind.FilterOpts) (*EVM2EVMOnRampPoolAddedIterator, error) + + WatchPoolAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampPoolAdded) (event.Subscription, error) + + ParsePoolAdded(log types.Log) (*EVM2EVMOnRampPoolAdded, error) + + FilterPoolRemoved(opts *bind.FilterOpts) (*EVM2EVMOnRampPoolRemovedIterator, error) + + WatchPoolRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampPoolRemoved) (event.Subscription, error) + + ParsePoolRemoved(log types.Log) (*EVM2EVMOnRampPoolRemoved, error) + + FilterTokenTransferFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampTokenTransferFeeConfigSetIterator, error) + + WatchTokenTransferFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampTokenTransferFeeConfigSet) (event.Subscription, error) + + ParseTokenTransferFeeConfigSet(log types.Log) (*EVM2EVMOnRampTokenTransferFeeConfigSet, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_1_0/evm_2_evm_onramp_1_1_0.go b/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_1_0/evm_2_evm_onramp_1_1_0.go new file mode 100644 index 0000000000..fb5aa512ac --- /dev/null +++ b/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_1_0/evm_2_evm_onramp_1_1_0.go @@ -0,0 +1,2794 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package evm_2_evm_onramp_1_1_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientEVM2AnyMessage struct { + Receiver []byte + Data []byte + TokenAmounts []ClientEVMTokenAmount + FeeToken common.Address + ExtraArgs []byte +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type EVM2EVMOnRampDynamicConfig struct { + Router common.Address + MaxTokensLength uint16 + DestGasOverhead uint32 + DestGasPerPayloadByte uint16 + PriceRegistry common.Address + MaxDataSize uint32 + MaxGasLimit uint64 +} + +type EVM2EVMOnRampFeeTokenConfig struct { + NetworkFeeUSD uint32 + MinTokenTransferFeeUSD uint32 + MaxTokenTransferFeeUSD uint32 + GasMultiplier uint64 + PremiumMultiplier uint64 + Enabled bool +} + +type EVM2EVMOnRampFeeTokenConfigArgs struct { + Token common.Address + NetworkFeeUSD uint32 + MinTokenTransferFeeUSD uint32 + MaxTokenTransferFeeUSD uint32 + GasMultiplier uint64 + PremiumMultiplier uint64 + Enabled bool +} + +type EVM2EVMOnRampNopAndWeight struct { + Nop common.Address + Weight uint16 +} + +type EVM2EVMOnRampStaticConfig struct { + LinkToken common.Address + ChainSelector uint64 + DestChainSelector uint64 + DefaultTxGasLimit uint64 + MaxNopFeesJuels *big.Int + PrevOnRamp common.Address + ArmProxy common.Address +} + +type EVM2EVMOnRampTokenTransferFeeConfig struct { + Ratio uint16 + DestGasOverhead uint32 +} + +type EVM2EVMOnRampTokenTransferFeeConfigArgs struct { + Token common.Address + Ratio uint16 + DestGasOverhead uint32 +} + +type InternalEVM2EVMMessage struct { + SourceChainSelector uint64 + SequenceNumber uint64 + FeeTokenAmount *big.Int + Sender common.Address + Nonce uint64 + GasLimit *big.Int + Strict bool + Receiver common.Address + Data []byte + TokenAmounts []ClientEVMTokenAmount + FeeToken common.Address + MessageId [32]byte +} + +type InternalPoolUpdate struct { + Token common.Address + Pool common.Address +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +var EVM2EVMOnRampMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"maxGasLimit\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"tokensAndPools\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"minTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"}],\"name\":\"InvalidNopAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWithdrawParams\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkBalanceNotSettled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeeBalanceReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoFeesToPay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoNopsToPay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdminOrNop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyNops\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"AllowListEnabledSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"maxGasLimit\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"minTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeConfig\",\"type\":\"tuple[]\"}],\"name\":\"FeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NopPaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nopWeightsTotal\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"NopsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"transferFeeConfig\",\"type\":\"tuple[]\"}],\"name\":\"TokenTransferFeeConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"maxGasLimit\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getFeeTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"networkFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"minTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfig\",\"name\":\"feeTokenConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNopFeesJuels\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNops\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"weightsTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"setAllowListEnabled\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"maxGasLimit\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"minTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setFeeTokenConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setTokenTransferFeeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawNonLinkFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101806040526012805460ff60c01b191690553480156200001f57600080fd5b506040516200834538038062008345833981016040819052620000429162001e90565b8333806000816200009a5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cd57620000cd8162000369565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555087516001600160a01b0316158062000176575060208801516001600160401b0316155b806200018d575060408801516001600160401b0316155b80620001a4575060608801516001600160401b0316155b80620001bb575060c08801516001600160a01b0316155b15620001da576040516306b7c75960e31b815260040160405180910390fd5b6020808901516040808b015181517fbdd59ac4dd1d82276c9a9c5d2656546346b9dcdb1f9b4204aed4ec15c23d7d3a948101949094526001600160401b039283169184019190915216606082015230608082015260a00160408051601f19818403018152918152815160209283012060809081528a516001600160a01b0390811660e052928b01516001600160401b0390811661010052918b015182166101205260608b015190911660a0908152908a01516001600160601b031660c0908152908a01518216610140528901511661016052620002b78762000414565b620002c2836200059e565b620002cd8262000739565b620002d88162000810565b6040805160008082526020820190925262000323916200031b565b6040805180820190915260008082526020820152815260200190600190039081620002f35790505b508762000a3a565b8451156200035b576012805460ff60c81b1916600160c81b179055604080516000808252602082019092526200035b91508662000d3d565b505050505050505062002407565b336001600160a01b03821603620003c35760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000091565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60808101516001600160a01b031662000440576040516306b7c75960e31b815260040160405180910390fd5b8051600580546020808501516040808701516060808901516001600160a01b039889166001600160b01b031990971696909617600160a01b61ffff95861681029190911765ffffffffffff60b01b1916600160b01b63ffffffff9485160261ffff60d01b191617600160d01b9590971694909402959095179095556080808801516006805460a0808c015160c0808e0151958d166001600160c01b0319909416939093179a16909602989098176001600160c01b0316600160c01b6001600160401b0393841602179055825160e08082018552518916815261010051821695810195909552610120518116858401528351169484019490945284516001600160601b031693830193909352610140518516908201526101605190931691830191909152517f72c6aaba4dde02f77d291123a76185c418ba63f8c217a2d56b08aec84e9bbfb8916200059391849062001fb3565b60405180910390a150565b60005b815181101562000707576000828281518110620005c257620005c26200207f565b6020908102919091018101516040805160c080820183528385015163ffffffff908116835283850151811683870190815260608087015183168587019081526080808901516001600160401b0390811693880193845260a0808b01518216928901928352968a0151151596880196875298516001600160a01b03166000908152600f909a529690982094518554925198519151965194511515600160e01b0260ff60e01b19958916600160a01b0295909516600160a01b600160e81b0319979098166c0100000000000000000000000002600160601b600160a01b0319928516680100000000000000000292909216600160401b600160a01b0319998516640100000000026001600160401b0319909416919094161791909117969096161794909417919091169190911791909117905550620006ff81620020ab565b9050620005a1565b507f2386f61ab5cafc3fed44f9f614f721ab53479ef64067fd16c1a2491b63ddf1a881604051620005939190620020c7565b60005b8151811015620007de5760008282815181106200075d576200075d6200207f565b6020908102919091018101516040805180820182528284015161ffff90811682528284015163ffffffff90811683870190815294516001600160a01b03166000908152601090965292909420905181549351909216620100000265ffffffffffff19909316919093161717905550620007d681620020ab565b90506200073c565b507f4230c60a9725eb5fb992cf6a215398b4e81b4606d4a1e6be8dfe0b60dc172ec1816040516200059391906200217f565b805160408111156200083557604051635ad0867d60e11b815260040160405180910390fd5b6012546c01000000000000000000000000900463ffffffff16158015906200087f575060125463ffffffff6c010000000000000000000000008204166001600160601b0390911610155b156200088f576200088f62000e88565b60006200089d600762001088565b90505b8015620008e9576000620008c3620008ba600184620021e0565b6007906200109b565b509050620008d3600782620010b9565b505080620008e190620021f6565b9050620008a0565b506000805b82811015620009d15760008482815181106200090e576200090e6200207f565b602002602001015160000151905060008583815181106200093357620009336200207f565b602002602001015160200151905060e0516001600160a01b0316826001600160a01b031614806200096b57506001600160a01b038216155b156200099657604051634de938d160e01b81526001600160a01b038316600482015260240162000091565b620009a860078361ffff8416620010d7565b50620009b961ffff82168562002210565b9350505080620009c990620020ab565b9050620008ee565b506012805463ffffffff60601b19166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249062000a2d908390869062002230565b60405180910390a1505050565b60005b825181101562000b7657600083828151811062000a5e5762000a5e6200207f565b6020026020010151600001519050600084838151811062000a835762000a836200207f565b6020908102919091018101510151905062000aa0600a83620010f7565b62000aca576040516373913ebd60e01b81526001600160a01b038316600482015260240162000091565b6001600160a01b03811662000ae1600a846200110e565b6001600160a01b03161462000b0957604051630d98f73360e31b815260040160405180910390fd5b62000b16600a8362001125565b1562000b6057604080516001600160a01b038085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a15b50508062000b6e90620020ab565b905062000a3d565b5060005b815181101562000d3857600082828151811062000b9b5762000b9b6200207f565b6020026020010151600001519050600083838151811062000bc05762000bc06200207f565b602002602001015160200151905060006001600160a01b0316826001600160a01b0316148062000bf757506001600160a01b038116155b1562000c155760405162d8548360e71b815260040160405180910390fd5b806001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000c54573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c7a91906200229d565b6001600160a01b0316826001600160a01b03161462000cac57604051630d98f73360e31b815260040160405180910390fd5b62000cba600a83836200113c565b1562000d0957604080516001600160a01b038085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a162000d22565b604051633caf458560e01b815260040160405180910390fd5b50508062000d3090620020ab565b905062000b7a565b505050565b60005b825181101562000dd257600083828151811062000d615762000d616200207f565b6020908102919091010151905062000d7b600d8262001154565b1562000dbe576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5062000dca81620020ab565b905062000d40565b5060005b815181101562000d3857600082828151811062000df75762000df76200207f565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000e23575062000e75565b62000e30600d826200116b565b1562000e73576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b62000e8081620020ab565b905062000dd6565b6000546001600160a01b0316331480159062000eaf57506002546001600160a01b03163314155b801562000ec6575062000ec460073362001182565b155b1562000ee55760405163032bb72b60e31b815260040160405180910390fd5b6012546c01000000000000000000000000900463ffffffff16600081900362000f215760405163990e30bf60e01b815260040160405180910390fd5b6012546001600160601b03168181101562000f4f576040516311a1ee3b60e31b815260040160405180910390fd5b600062000f5b62001199565b121562000f7b57604051631e9acf1760e31b815260040160405180910390fd5b80600062000f8a600762001088565b905060005b81811015620010625760008062000fa86007846200109b565b909250905060008762000fc5836001600160601b038a16620022bd565b62000fd19190620022d7565b905062000fdf8187620022fa565b60e05190965062001004906001600160a01b0316846001600160601b03841662001227565b6040516001600160601b03821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a2505050806200105a90620020ab565b905062000f8f565b5050601280546001600160601b0319166001600160601b03929092169190911790555050565b600062001095826200127f565b92915050565b6000808080620010ac86866200128c565b9097909650945050505050565b6000620010d0836001600160a01b038416620012b9565b9392505050565b6000620010ef846001600160a01b03851684620012d8565b949350505050565b6000620010d0836001600160a01b038416620012f7565b6000620010d0836001600160a01b03841662001305565b6000620010d0836001600160a01b03841662001313565b6000620010ef846001600160a01b0385168462001321565b6000620010d0836001600160a01b03841662001339565b6000620010d0836001600160a01b03841662001444565b6000620010d0836001600160a01b03841662001496565b60125460e0516040516370a0823160e01b81523060048201526000926001600160601b0316916001600160a01b0316906370a0823190602401602060405180830381865afa158015620011f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200121691906200231d565b62001222919062002337565b905090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915262000d38918591620014a416565b6000620010958262001575565b600080806200129c858562001580565b600081815260029690960160205260409095205494959350505050565b60008181526002830160205260408120819055620010d083836200158e565b60008281526002840160205260408120829055620010ef84846200159c565b6000620010d0838362001496565b6000620010d08383620015aa565b6000620010d08383620012b9565b6000620010ef84846001600160a01b038516620012d8565b600081815260018301602052604081205480156200143257600062001360600183620021e0565b85549091506000906200137690600190620021e0565b9050818114620013e25760008660000182815481106200139a576200139a6200207f565b9060005260206000200154905080876000018481548110620013c057620013c06200207f565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620013f657620013f66200235a565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062001095565b600091505062001095565b5092915050565b60008181526001830160205260408120546200148d5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562001095565b50600062001095565b6000620010d083836200161f565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620014f3906001600160a01b03851690849062001638565b80519091501562000d38578080602001905181019062001514919062002370565b62000d385760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000091565b600062001095825490565b6000620010d0838362001649565b6000620010d0838362001339565b6000620010d0838362001444565b600081815260028301602052604081205480151580620015d15750620015d1848462001496565b620010d05760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000604482015260640162000091565b60008181526001830160205260408120541515620010d0565b6060620010ef848460008562001676565b60008260000182815481106200166357620016636200207f565b9060005260206000200154905092915050565b606082471015620016d95760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000091565b600080866001600160a01b03168587604051620016f79190620023b4565b60006040518083038185875af1925050503d806000811462001736576040519150601f19603f3d011682016040523d82523d6000602084013e6200173b565b606091505b5090925090506200174f878383876200175a565b979650505050505050565b60608315620017ce578251600003620017c6576001600160a01b0385163b620017c65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000091565b5081620010ef565b620010ef8383815115620017e55781518083602001fd5b8060405162461bcd60e51b8152600401620000919190620023d2565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b03811182821017156200183c576200183c62001801565b60405290565b604080519081016001600160401b03811182821017156200183c576200183c62001801565b604051606081016001600160401b03811182821017156200183c576200183c62001801565b604051601f8201601f191681016001600160401b0381118282101715620018b757620018b762001801565b604052919050565b6001600160a01b0381168114620018d557600080fd5b50565b8051620018e581620018bf565b919050565b80516001600160401b0381168114620018e557600080fd5b600060e082840312156200191557600080fd5b6200191f62001817565b905081516200192e81620018bf565b81526200193e60208301620018ea565b60208201526200195160408301620018ea565b60408201526200196460608301620018ea565b606082015260808201516001600160601b03811681146200198457600080fd5b60808201526200199760a08301620018d8565b60a0820152620019aa60c08301620018d8565b60c082015292915050565b805161ffff81168114620018e557600080fd5b805163ffffffff81168114620018e557600080fd5b600060e08284031215620019f057600080fd5b620019fa62001817565b9050815162001a0981620018bf565b815262001a1960208301620019b5565b602082015262001a2c60408301620019c8565b604082015262001a3f60608301620019b5565b6060820152608082015162001a5481620018bf565b608082015262001a6760a08301620019c8565b60a0820152620019aa60c08301620018ea565b60006001600160401b0382111562001a965762001a9662001801565b5060051b60200190565b600082601f83011262001ab257600080fd5b8151602062001acb62001ac58362001a7a565b6200188c565b82815260069290921b8401810191818101908684111562001aeb57600080fd5b8286015b8481101562001b45576040818903121562001b0a5760008081fd5b62001b1462001842565b815162001b2181620018bf565b81528185015162001b3281620018bf565b8186015283529183019160400162001aef565b509695505050505050565b600082601f83011262001b6257600080fd5b8151602062001b7562001ac58362001a7a565b82815260059290921b8401810191818101908684111562001b9557600080fd5b8286015b8481101562001b4557805162001baf81620018bf565b835291830191830162001b99565b80518015158114620018e557600080fd5b80516001600160801b0381168114620018e557600080fd5b60006060828403121562001bf957600080fd5b62001c0362001867565b905062001c108262001bbd565b815262001c206020830162001bce565b602082015262001c336040830162001bce565b604082015292915050565b600082601f83011262001c5057600080fd5b8151602062001c6362001ac58362001a7a565b82815260e0928302850182019282820191908785111562001c8357600080fd5b8387015b8581101562001d385781818a03121562001ca15760008081fd5b62001cab62001817565b815162001cb881620018bf565b815262001cc7828701620019c8565b86820152604062001cda818401620019c8565b90820152606062001ced838201620019c8565b90820152608062001d00838201620018ea565b9082015260a062001d13838201620018ea565b9082015260c062001d2683820162001bbd565b90820152845292840192810162001c87565b5090979650505050505050565b600082601f83011262001d5757600080fd5b8151602062001d6a62001ac58362001a7a565b8281526060928302850182019282820191908785111562001d8a57600080fd5b8387015b8581101562001d385781818a03121562001da85760008081fd5b62001db262001867565b815162001dbf81620018bf565b815262001dce828701620019b5565b86820152604062001de1818401620019c8565b90820152845292840192810162001d8e565b600082601f83011262001e0557600080fd5b8151602062001e1862001ac58362001a7a565b82815260069290921b8401810191818101908684111562001e3857600080fd5b8286015b8481101562001b45576040818903121562001e575760008081fd5b62001e6162001842565b815162001e6e81620018bf565b815262001e7d828601620019b5565b8186015283529183019160400162001e3c565b6000806000806000806000806102c0898b03121562001eae57600080fd5b62001eba8a8a62001902565b975062001ecb8a60e08b01620019dd565b6101c08a01519097506001600160401b038082111562001eea57600080fd5b62001ef88c838d0162001aa0565b97506101e08b015191508082111562001f1057600080fd5b62001f1e8c838d0162001b50565b965062001f308c6102008d0162001be6565b95506102608b015191508082111562001f4857600080fd5b62001f568c838d0162001c3e565b94506102808b015191508082111562001f6e57600080fd5b62001f7c8c838d0162001d45565b93506102a08b015191508082111562001f9457600080fd5b5062001fa38b828c0162001df3565b9150509295985092959890939650565b82516001600160a01b0390811682526020808501516001600160401b03908116828501526040808701518216818601526060808801518316818701526080808901516001600160601b03168188015260a0808a015187168189015260c0808b01518816818a01528951881660e08a01529589015161ffff9081166101008a01529389015163ffffffff9081166101208a015292890151909316610140880152870151909416610160860152850151909216610180840152830151166101a08201526101c08101620010d0565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620020c057620020c062002095565b5060010190565b602080825282518282018190526000919060409081850190868401855b828110156200217257815180516001600160a01b031685528681015163ffffffff9081168887015286820151811687870152606080830151909116908601526080808201516001600160401b03169086015260a08082015162002151878301826001600160401b03169052565b505060c09081015115159085015260e09093019290850190600101620020e4565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b828110156200217257815180516001600160a01b031685528681015161ffff168786015285015163ffffffff1685850152606090930192908501906001016200219c565b8181038181111562001095576200109562002095565b60008162002208576200220862002095565b506000190190565b63ffffffff8181168382160190808211156200143d576200143d62002095565b6000604080830163ffffffff8616845260208281860152818651808452606087019150828801935060005b818110156200228f57845180516001600160a01b0316845284015161ffff168484015293830193918501916001016200225b565b509098975050505050505050565b600060208284031215620022b057600080fd5b8151620010d081620018bf565b808202811582820484141762001095576200109562002095565b600082620022f557634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b038281168282160390808211156200143d576200143d62002095565b6000602082840312156200233057600080fd5b5051919050565b81810360008312801583831316838312821617156200143d576200143d62002095565b634e487b7160e01b600052603160045260246000fd5b6000602082840312156200238357600080fd5b620010d08262001bbd565b60005b83811015620023ab57818101518382015260200162002391565b50506000910152565b60008251620023c88184602087016200238e565b9190910192915050565b6020815260008251806020840152620023f38160408501602087016200238e565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516101405161016051615e376200250e600039600081816103600152818161148701526135700152600081816103310152818161139d01528181611405015281816119cc01528181611a34015261354901526000818161029d01528181610bcf01528181611dc401526134c301526000818161026d01528181611aff015261349901526000818161023e01528181610f320152818161177f015281816118780152818161237d015281816130380152818161347401526137000152600081816102fd0152818161194401526135130152600081816102cd015281816126c401526134ea01526000611cde0152615e376000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806376f6ae761161010f578063c92b2832116100a2578063e76c0b0611610071578063e76c0b0614610943578063efeadb6d14610956578063eff7cc4814610969578063f2fde38b1461097157600080fd5b8063c92b2832146108ed578063d09dc33914610900578063d3c7c2c714610908578063e0351e131461091057600080fd5b80639a113c36116100de5780639a113c3614610742578063a7cd63b7146108af578063a7d3e02f146108c4578063b06d41bc146108d757600080fd5b806376f6ae761461070357806379ba509714610716578063856c82471461071e5780638da5cb5b1461073157600080fd5b8063549e946f116101875780635d86f141116101565780635d86f141146105ae578063704b6c02146105c15780637132721a146105d45780637437ff9f146105e757600080fd5b8063549e946f1461054357806354b714681461055657806354c8a4f314610576578063599f64311461058957600080fd5b806338724a95116101c357806338724a951461048a5780633a87ac53146104ab5780634120fccd146104be578063546719cd146104df57600080fd5b806306285c69146101f55780631772047e146103a6578063181f5a771461042c578063352e4bc814610475575b600080fd5b6103906040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60405161039d919061499d565b60405180910390f35b6104076103b4366004614a2e565b6040805180820190915260008082526020820152506001600160a01b031660009081526010602090815260409182902082518084019093525461ffff8116835262010000900463ffffffff169082015290565b60408051825161ffff16815260209283015163ffffffff16928101929092520161039d565b6104686040518060400160405280601381526020017f45564d3245564d4f6e52616d7020312e312e300000000000000000000000000081525081565b60405161039d9190614ab9565b610488610483366004614c1a565b610984565b005b61049d610498366004614d50565b6109ed565b60405190815260200161039d565b6104886104b9366004614e21565b610dd9565b6104c6610def565b60405167ffffffffffffffff909116815260200161039d565b6104e7610e23565b60405161039d919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b610488610551366004614e85565b610ed3565b6012546040516bffffffffffffffffffffffff909116815260200161039d565b610488610584366004614f22565b611088565b6002546001600160a01b03165b6040516001600160a01b03909116815260200161039d565b6105966105bc366004614a2e565b61109a565b6104886105cf366004614a2e565b6110f9565b6104886105e2366004614f8e565b6111c3565b6106f66040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152506040805160e0810182526005546001600160a01b03808216835261ffff740100000000000000000000000000000000000000008084048216602086015263ffffffff76010000000000000000000000000000000000000000000085048116968601969096527a010000000000000000000000000000000000000000000000000000909304166060840152600654908116608084015290810490921660a082015267ffffffffffffffff78010000000000000000000000000000000000000000000000009092049190911660c082015290565b60405161039d9190615026565b6104886107113660046150a1565b6111d4565b61048861128c565b6104c661072c366004614a2e565b61136f565b6000546001600160a01b0316610596565b610845610750366004614a2e565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506001600160a01b03166000908152600f6020908152604091829020825160c081018452905463ffffffff808216835264010000000082048116938301939093526801000000000000000081049092169281019290925267ffffffffffffffff6c0100000000000000000000000082048116606084015274010000000000000000000000000000000000000000820416608083015260ff7c010000000000000000000000000000000000000000000000000000000090910416151560a082015290565b60405161039d9190600060c08201905063ffffffff80845116835280602085015116602084015280604085015116604084015250606083015167ffffffffffffffff8082166060850152806080860151166080850152505060a0830151151560a083015292915050565b6108b7611477565b60405161039d9190615116565b61049d6108d2366004615163565b611483565b6108df611eab565b60405161039d929190615211565b6104886108fb366004615253565b611faf565b61049d612017565b6108b7612021565b601254790100000000000000000000000000000000000000000000000000900460ff16604051901515815260200161039d565b6104886109513660046152a3565b6120d2565b61048861096436600461536c565b612138565b6104886121be565b61048861097f366004614a2e565b612455565b6000546001600160a01b031633148015906109aa57506002546001600160a01b03163314155b156109e1576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109ea81612466565b50565b600080610a05610a006080850185615389565b612695565b9050610a30610a176020850185615389565b8351909150610a2960408701876153ee565b9050612789565b6000600f81610a456080870160608801614a2e565b6001600160a01b031681526020808201929092526040908101600020815160c081018352905463ffffffff80821683526401000000008204811694830194909452680100000000000000008104909316918101919091526c01000000000000000000000000820467ffffffffffffffff90811660608301527401000000000000000000000000000000000000000083041660808201527c010000000000000000000000000000000000000000000000000000000090910460ff16151560a08201819052909150610b6257610b1f6080850160608601614a2e565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024015b60405180910390fd5b60065460009081906001600160a01b031663ffdb4b37610b886080890160608a01614a2e565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044016040805180830381865afa158015610c13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c37919061547e565b909250905060008080610c4d60408a018a6153ee565b90501115610c8657610c7c610c6860808a0160608b01614a2e565b85610c7660408c018c6153ee565b896128ae565b9092509050610ca2565b8451610c9f9063ffffffff16662386f26fc100006154e0565b91505b6080850151610cbb9067ffffffffffffffff16836154e0565b606086015160055491935060009167ffffffffffffffff9091169063ffffffff8416907a010000000000000000000000000000000000000000000000000000900461ffff16610d0d60208d018d615389565b610d189291506154e0565b6005548a51610d4791760100000000000000000000000000000000000000000000900463ffffffff16906154f7565b610d5191906154f7565b610d5b91906154f7565b610d6591906154e0565b610d899077ffffffffffffffffffffffffffffffffffffffffffffffff86166154e0565b9050610dcc670de0b6b3a7640000610da183866154f7565b610dab919061550a565b77ffffffffffffffffffffffffffffffffffffffffffffffff871690612b34565b9998505050505050505050565b610de1612b6d565b610deb8282612be3565b5050565b601254600090610e1e90700100000000000000000000000000000000900467ffffffffffffffff166001615545565b905090565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610e1e90612f43565b6000546001600160a01b03163314801590610ef957506002546001600160a01b03163314155b15610f30576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480610f7757506001600160a01b038116155b15610fae576040517f232cb97f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610fb8612ff5565b1215610ff0576040517f02075e0000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610deb9082906001600160a01b038516906370a0823190602401602060405180830381865afa158015611053573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110779190615566565b6001600160a01b03851691906130b5565b611090612b6d565b610deb8282613135565b60006110a7600a83613270565b6110e8576040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610b59565b6110f3600a83613285565b92915050565b6000546001600160a01b0316331480159061111f57506002546001600160a01b03163314155b15611156576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b6111cb612b6d565b6109ea8161329a565b6000546001600160a01b031633148015906111fa57506002546001600160a01b03163314155b15611231576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610deb8282808060200260200160405190810160405280939291908181526020016000905b82821015611282576112736040830286013681900381019061557f565b81526020019060010190611256565b50505050506135c7565b6001546001600160a01b03163314611300576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610b59565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b03811660009081526011602052604081205467ffffffffffffffff16801580156113c857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b156110f3576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa15801561144c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147091906155be565b9392505050565b6060610e1e600d61383a565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061150791906155db565b1561153e576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03821661157e576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254790100000000000000000000000000000000000000000000000000900460ff1680156115b557506115b3600d83613847565b155b156115f7576040517fd0d259760000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610b59565b6005546001600160a01b0316331461163b576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116458480615389565b905060201461168c576116588480615389565b6040517f370d875f000000000000000000000000000000000000000000000000000000008152600401610b59929190615641565b60006116988580615389565b8101906116a59190615655565b90506001600160a01b038111806116bc5750600a81105b156116cb576116588580615389565b60006116dd610a006080880188615389565b90506117016116ef6020880188615389565b8351909150610a2960408a018a6153ee565b61177561171160408801886153ee565b808060200260200160405190810160405280939291908181526020016000905b8282101561175d5761174e6040830286013681900381019061566e565b81526020019060010190611731565b50506006546001600160a01b03169250613869915050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166117af6080880160608901614a2e565b6001600160a01b03160361181357601280548691906000906117e09084906bffffffffffffffffffffffff166156a8565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550611932565b6006546001600160a01b03166241e5be6118336080890160608a01614a2e565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018990527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa1580156118bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e39190615566565b601280546000906119039084906bffffffffffffffffffffffff166156a8565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b6012546bffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081169116111561199f576040517fe5c7a49100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03841660009081526011602052604090205467ffffffffffffffff161580156119f757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15611aef576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9f91906155be565b6001600160a01b038516600090815260116020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790555b60006040518061018001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020016012601081819054906101000a900467ffffffffffffffff16611b4f906156cd565b825467ffffffffffffffff9182166101009390930a8381029083021990911617909255825260208083018a90526001600160a01b03891660408085018290526000918252601190925290812080546060909401939092611baf91166156cd565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200183600001518152602001600015158152602001846001600160a01b03168152602001888060200190611c159190615389565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001611c5c60408a018a6153ee565b808060200260200160405190810160405280939291908181526020016000905b82821015611ca857611c996040830286013681900381019061566e565b81526020019060010190611c7c565b5050509183525050602001611cc360808a0160608b01614a2e565b6001600160a01b0316815260006020909101529050611d02817f0000000000000000000000000000000000000000000000000000000000000000613a1c565b61016082015260005b611d1860408901896153ee565b9050811015611e64576000611d3060408a018a6153ee565b83818110611d4057611d406156f4565b905060400201803603810190611d56919061566e565b9050611d65816000015161109a565b6001600160a01b0316639687544588611d7e8c80615389565b60208087015160408051928301815260008352517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b168152611dec959493927f000000000000000000000000000000000000000000000000000000000000000091600401615723565b6000604051808303816000875af1158015611e0b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e51919081019061576e565b505080611e5d90615820565b9050611d0b565b507faffc45517195d6499808c643bd4a7b0ffeedf95bea5852840d7bfcf63f59e82181604051611e94919061589c565b60405180910390a161016001519695505050505050565b6060600080611eba6007613b26565b90508067ffffffffffffffff811115611ed557611ed5614acc565b604051908082528060200260200182016040528015611f1a57816020015b6040805180820190915260008082526020820152815260200190600190039081611ef35790505b50925060005b81811015611f8c57600080611f36600784613b31565b915091506040518060400160405280836001600160a01b031681526020018261ffff16815250868481518110611f6e57611f6e6156f4565b6020026020010181905250505080611f8590615820565b9050611f20565b505060125491926c0100000000000000000000000090920463ffffffff16919050565b6000546001600160a01b03163314801590611fd557506002546001600160a01b03163314155b1561200c576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109ea600382613b4f565b6000610e1e612ff5565b6060600061202f600a613d27565b67ffffffffffffffff81111561204757612047614acc565b604051908082528060200260200182016040528015612070578160200160208202803683370190505b50905060005b81518110156120cc5761208a600a82613d32565b5082828151811061209d5761209d6156f4565b60200260200101816001600160a01b03166001600160a01b031681525050806120c590615820565b9050612076565b50919050565b6000546001600160a01b031633148015906120f857506002546001600160a01b03163314155b1561212f576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109ea81613d41565b612140612b6d565b60128054821515790100000000000000000000000000000000000000000000000000027fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff9091161790556040517fccf4daf6ab6430389f26b970595dab82a5881ad454770907e415ede27c8df032906111b890831515815260200190565b6000546001600160a01b031633148015906121e457506002546001600160a01b03163314155b80156121f857506121f6600733613e28565b155b1561222f576040517f195db95800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6012546c01000000000000000000000000900463ffffffff166000819003612283576040517f990e30bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6012546bffffffffffffffffffffffff16818110156122ce576040517f8d0f71d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122d8612ff5565b1215612310576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600061231d6007613b26565b905060005b8181101561241257600080612338600784613b31565b9092509050600087612358836bffffffffffffffffffffffff8a166154e0565b612362919061550a565b905061236e81876159d9565b95506123b26001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846bffffffffffffffffffffffff84166130b5565b6040516bffffffffffffffffffffffff821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a25050508061240b90615820565b9050612322565b5050601280547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff929092169190911790555050565b61245d612b6d565b6109ea81613e3d565b60005b8151811015612665576000828281518110612486576124866156f4565b6020908102919091018101516040805160c080820183528385015163ffffffff9081168352838501518116838701908152606080870151831685870190815260808089015167ffffffffffffffff90811693880193845260a0808b01518216928901928352968a0151151596880196875298516001600160a01b03166000908152600f909a5296909820945185549251985191519651945115157c0100000000000000000000000000000000000000000000000000000000027fffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9589167401000000000000000000000000000000000000000002959095167fffffff000000000000000000ffffffffffffffffffffffffffffffffffffffff979098166c01000000000000000000000000027fffffffffffffffffffffffff0000000000000000ffffffffffffffffffffffff9285166801000000000000000002929092167fffffffffffffffffffffffff000000000000000000000000ffffffffffffffff998516640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090941691909416179190911796909616179490941791909116919091179190911790555061265e81615820565b9050612469565b507f2386f61ab5cafc3fed44f9f614f721ab53479ef64067fd16c1a2491b63ddf1a8816040516111b891906159fe565b60408051602081019091526000815260008290036126eb5750604080516020810190915267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526110f3565b7f97a657c9000000000000000000000000000000000000000000000000000000006127168385615ab5565b7fffffffff00000000000000000000000000000000000000000000000000000000161461276f576040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61277c8260048186615afd565b8101906114709190615b27565b60065474010000000000000000000000000000000000000000900463ffffffff16808411156127ee576040517f869337890000000000000000000000000000000000000000000000000000000081526004810182905260248101859052604401610b59565b6006547801000000000000000000000000000000000000000000000000900467ffffffffffffffff16831115612850576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055474010000000000000000000000000000000000000000900461ffff168211156128a8576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b60008083815b81811015612ac05760008787838181106128d0576128d06156f4565b9050604002018036038101906128e6919061566e565b80516001600160a01b031660009081526010602090815260409182902082518084019093525461ffff8116835263ffffffff620100009091048116918301919091528251929350909161293d91600a919061327016565b6129815781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610b59565b805160009061ffff1615612a8e5760008c6001600160a01b031684600001516001600160a01b031614612a3d5760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152911690634ab35b0b90602401602060405180830381865afa158015612a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a369190615b69565b9050612a40565b508a5b82516020850151620186a09161ffff1690612a769077ffffffffffffffffffffffffffffffffffffffffffffffff851690613f18565b612a8091906154e0565b612a8a919061550a565b9150505b612a9881886154f7565b9650816020015186612aaa9190615b84565b955050505080612ab990615820565b90506128b4565b506000846020015163ffffffff16662386f26fc10000612ae091906154e0565b905080841015612af3579250612b2a9050565b6000856040015163ffffffff16662386f26fc10000612b1291906154e0565b905080851115612b26579350612b2a915050565b5050505b9550959350505050565b600077ffffffffffffffffffffffffffffffffffffffffffffffff8316612b6383670de0b6b3a76400006154e0565b611470919061550a565b6000546001600160a01b03163314612be1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610b59565b565b60005b8251811015612d44576000838281518110612c0357612c036156f4565b60200260200101516000015190506000848381518110612c2557612c256156f4565b6020026020010151602001519050612c4782600a61327090919063ffffffff16565b612c88576040517f73913ebd0000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610b59565b6001600160a01b038116612c9d600a84613285565b6001600160a01b031614612cdd576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612ce8600a83613f47565b15612d3157604080516001600160a01b038085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a15b505080612d3d90615820565b9050612be6565b5060005b8151811015612f3e576000828281518110612d6557612d656156f4565b60200260200101516000015190506000838381518110612d8757612d876156f4565b602002602001015160200151905060006001600160a01b0316826001600160a01b03161480612dbd57506001600160a01b038116155b15612df4576040517f6c2a418000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e569190615ba1565b6001600160a01b0316826001600160a01b031614612ea0576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612eac600a8383613f5c565b15612ef957604080516001600160a01b038085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a1612f2b565b6040517f3caf458500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505080612f3790615820565b9050612d48565b505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152612fd182606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642612fb59190615bbe565b85608001516fffffffffffffffffffffffffffffffff16613f7a565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6012546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916bffffffffffffffffffffffff16907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015613087573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ab9190615566565b610e1e9190615bd1565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052612f3e908490613fa2565b60005b82518110156131c6576000838281518110613155576131556156f4565b6020026020010151905061317381600d6140a190919063ffffffff16565b156131b5576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506131bf81615820565b9050613138565b5060005b8151811015612f3e5760008282815181106131e7576131e76156f4565b6020026020010151905060006001600160a01b0316816001600160a01b0316036132115750613260565b61321c600d826140b6565b1561325e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b61326981615820565b90506131ca565b6000611470836001600160a01b0384166140cb565b6000611470836001600160a01b0384166140d7565b60808101516001600160a01b03166132de576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600580546020808501516040808701516060808901516001600160a01b039889167fffffffffffffffffffff00000000000000000000000000000000000000000000909716969096177401000000000000000000000000000000000000000061ffff9586168102919091177fffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffff1676010000000000000000000000000000000000000000000063ffffffff948516027fffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffff16177a0100000000000000000000000000000000000000000000000000009590971694909402959095179095556080808801516006805460a0808c015160c0808e0151958d167fffffffffffffffff000000000000000000000000000000000000000000000000909416939093179a169096029890981777ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff93841602179055825160e0810184527f0000000000000000000000000000000000000000000000000000000000000000891681527f00000000000000000000000000000000000000000000000000000000000000008216958101959095527f00000000000000000000000000000000000000000000000000000000000000008116858401527f000000000000000000000000000000000000000000000000000000000000000016948401949094527f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16938301939093527f00000000000000000000000000000000000000000000000000000000000000008516908201527f000000000000000000000000000000000000000000000000000000000000000090931691830191909152517f72c6aaba4dde02f77d291123a76185c418ba63f8c217a2d56b08aec84e9bbfb8916111b8918490615bf1565b80516040811115613604576040517fb5a10cfa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6012546c01000000000000000000000000900463ffffffff1615801590613652575060125463ffffffff6c010000000000000000000000008204166bffffffffffffffffffffffff90911610155b1561365f5761365f6121be565b600061366b6007613b26565b90505b80156136ad57600061368c613684600184615bbe565b600790613b31565b50905061369a6007826140e3565b5050806136a690615ce6565b905061366e565b506000805b828110156137bb5760008482815181106136ce576136ce6156f4565b602002602001015160000151905060008583815181106136f0576136f06156f4565b60200260200101516020015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316148061374557506001600160a01b038216155b15613787576040517f4de938d10000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610b59565b61379760078361ffff84166140f8565b506137a661ffff821685615b84565b93505050806137b490615820565b90506136b2565b50601280547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249061382d9083908690615d1b565b60405180910390a1505050565b606060006114708361410e565b6001600160a01b03811660009081526001830160205260408120541515611470565b81516000805b82811015613a0e576000846001600160a01b031663d02641a087848151811061389a5761389a6156f4565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b0390911660048201526024016040805180830381865afa158015613901573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139259190615d3a565b51905077ffffffffffffffffffffffffffffffffffffffffffffffff81166000036139a65785828151811061395c5761395c6156f4565b6020908102919091010151516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610b59565b6139f08683815181106139bb576139bb6156f4565b6020026020010151602001518277ffffffffffffffffffffffffffffffffffffffffffffffff16613f1890919063ffffffff16565b6139fa90846154f7565b92505080613a0790615820565b905061386f565b506128a8600382600061416a565b60008060001b828460200151856080015186606001518760e0015188610100015180519060200120896101200151604051602001613a5a9190615d6d565b604051602081830303815290604052805190602001208a60a001518b60c001518c61014001518d60400151604051602001613b089c9b9a999897969594939291909b8c5260208c019a909a5267ffffffffffffffff98891660408c01529690971660608a01526001600160a01b0394851660808a015292841660a089015260c088019190915260e0870152610100860152911515610120850152166101408301526101608201526101800190565b60405160208183030381529060405280519060200120905092915050565b60006110f3826144b9565b6000808080613b4086866144c4565b909450925050505b9250929050565b8154600090613b7890700100000000000000000000000000000000900463ffffffff1642615bbe565b90508015613c1a5760018301548354613bc0916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416613f7a565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354613c40916fffffffffffffffffffffffffffffffff90811691166144ef565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061382d9084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60006110f382613b26565b6000808080613b408686613b31565b60005b8151811015613df8576000828281518110613d6157613d616156f4565b6020908102919091018101516040805180820182528284015161ffff90811682528284015163ffffffff90811683870190815294516001600160a01b0316600090815260109096529290942090518154935190921662010000027fffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000909316919093161717905550613df181615820565b9050613d44565b507f4230c60a9725eb5fb992cf6a215398b4e81b4606d4a1e6be8dfe0b60dc172ec1816040516111b89190615d80565b6000611470836001600160a01b038416614505565b336001600160a01b03821603613eaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610b59565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a7640000612b638377ffffffffffffffffffffffffffffffffffffffffffffffff86166154e0565b6000611470836001600160a01b038416614511565b6000613f72846001600160a01b0385168461451d565b949350505050565b6000613f9985613f8a84866154e0565b613f9490876154f7565b6144ef565b95945050505050565b6000613ff7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166145339092919063ffffffff16565b805190915015612f3e578080602001905181019061401591906155db565b612f3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b59565b6000611470836001600160a01b038416614542565b6000611470836001600160a01b03841661463c565b60006114708383614505565b6000611470838361468b565b6000611470836001600160a01b038416614715565b6000613f72846001600160a01b03851684614732565b60608160000180548060200260200160405190810160405280929190818152602001828054801561415e57602002820191906000526020600020905b81548152602001906001019080831161414a575b50505050509050919050565b825474010000000000000000000000000000000000000000900460ff161580614191575081155b1561419b57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906141e190700100000000000000000000000000000000900463ffffffff1642615bbe565b905080156142a15781831115614223576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461425d9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16613f7a565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561433e576001600160a01b0384166142f3576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610b59565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610b59565b848310156144375760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906143829082615bbe565b61438c878a615bbe565b61439691906154f7565b6143a0919061550a565b90506001600160a01b0386166143ec576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610b59565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610b59565b6144418584615bbe565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60006110f38261474f565b600080806144d28585614759565b600081815260029690960160205260409095205494959350505050565b60008183106144fe5781611470565b5090919050565b60006114708383614765565b60006114708383614715565b6000613f7284846001600160a01b038516614732565b6060613f72848460008561477d565b6000818152600183016020526040812054801561462b576000614566600183615bbe565b855490915060009061457a90600190615bbe565b90508181146145df57600086600001828154811061459a5761459a6156f4565b90600052602060002001549050808760000184815481106145bd576145bd6156f4565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806145f0576145f0615ddf565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506110f3565b60009150506110f3565b5092915050565b6000818152600183016020526040812054614683575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556110f3565b5060006110f3565b6000818152600283016020526040812054801515806146af57506146af8484614505565b611470576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b657900006044820152606401610b59565b600081815260028301602052604081208190556114708383614889565b60008281526002840160205260408120829055613f728484614895565b60006110f3825490565b600061147083836148a1565b60008181526001830160205260408120541515611470565b60608247101561480f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b59565b600080866001600160a01b0316858760405161482b9190615e0e565b60006040518083038185875af1925050503d8060008114614868576040519150601f19603f3d011682016040523d82523d6000602084013e61486d565b606091505b509150915061487e878383876148cb565b979650505050505050565b60006114708383614542565b6000611470838361463c565b60008260000182815481106148b8576148b86156f4565b9060005260206000200154905092915050565b6060831561495457825160000361494d576001600160a01b0385163b61494d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b59565b5081613f72565b613f7283838151156149695781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b599190614ab9565b60e081016110f382846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b6001600160a01b03811681146109ea57600080fd5b600060208284031215614a4057600080fd5b813561147081614a19565b60005b83811015614a66578181015183820152602001614a4e565b50506000910152565b60008151808452614a87816020860160208601614a4b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006114706020830184614a6f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614b1e57614b1e614acc565b60405290565b6040805190810167ffffffffffffffff81118282101715614b1e57614b1e614acc565b6040516060810167ffffffffffffffff81118282101715614b1e57614b1e614acc565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614bb157614bb1614acc565b604052919050565b600067ffffffffffffffff821115614bd357614bd3614acc565b5060051b60200190565b803563ffffffff81168114614bf157600080fd5b919050565b67ffffffffffffffff811681146109ea57600080fd5b80151581146109ea57600080fd5b60006020808385031215614c2d57600080fd5b823567ffffffffffffffff811115614c4457600080fd5b8301601f81018513614c5557600080fd5b8035614c68614c6382614bb9565b614b6a565b81815260e09182028301840191848201919088841115614c8757600080fd5b938501935b83851015614d325780858a031215614ca45760008081fd5b614cac614afb565b8535614cb781614a19565b8152614cc4868801614bdd565b878201526040614cd5818801614bdd565b908201526060614ce6878201614bdd565b90820152608086810135614cf981614bf6565b9082015260a086810135614d0c81614bf6565b9082015260c086810135614d1f81614c0c565b9082015283529384019391850191614c8c565b50979650505050505050565b600060a082840312156120cc57600080fd5b600060208284031215614d6257600080fd5b813567ffffffffffffffff811115614d7957600080fd5b613f7284828501614d3e565b600082601f830112614d9657600080fd5b81356020614da6614c6383614bb9565b82815260069290921b84018101918181019086841115614dc557600080fd5b8286015b84811015614e165760408189031215614de25760008081fd5b614dea614b24565b8135614df581614a19565b815281850135614e0481614a19565b81860152835291830191604001614dc9565b509695505050505050565b60008060408385031215614e3457600080fd5b823567ffffffffffffffff80821115614e4c57600080fd5b614e5886838701614d85565b93506020850135915080821115614e6e57600080fd5b50614e7b85828601614d85565b9150509250929050565b60008060408385031215614e9857600080fd5b8235614ea381614a19565b91506020830135614eb381614a19565b809150509250929050565b600082601f830112614ecf57600080fd5b81356020614edf614c6383614bb9565b82815260059290921b84018101918181019086841115614efe57600080fd5b8286015b84811015614e16578035614f1581614a19565b8352918301918301614f02565b60008060408385031215614f3557600080fd5b823567ffffffffffffffff80821115614f4d57600080fd5b614f5986838701614ebe565b93506020850135915080821115614f6f57600080fd5b50614e7b85828601614ebe565b803561ffff81168114614bf157600080fd5b600060e08284031215614fa057600080fd5b614fa8614afb565b8235614fb381614a19565b8152614fc160208401614f7c565b6020820152614fd260408401614bdd565b6040820152614fe360608401614f7c565b60608201526080830135614ff681614a19565b608082015261500760a08401614bdd565b60a082015260c083013561501a81614bf6565b60c08201529392505050565b60e081016110f382846001600160a01b03808251168352602082015161ffff80821660208601526040840151915063ffffffff80831660408701528160608601511660608701528360808601511660808701528060a08601511660a08701525050505067ffffffffffffffff60c08201511660c08301525050565b600080602083850312156150b457600080fd5b823567ffffffffffffffff808211156150cc57600080fd5b818501915085601f8301126150e057600080fd5b8135818111156150ef57600080fd5b8660208260061b850101111561510457600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b818110156151575783516001600160a01b031683529284019291840191600101615132565b50909695505050505050565b60008060006060848603121561517857600080fd5b833567ffffffffffffffff81111561518f57600080fd5b61519b86828701614d3e565b9350506020840135915060408401356151b381614a19565b809150509250925092565b600081518084526020808501945080840160005b8381101561520657815180516001600160a01b0316885283015161ffff1683880152604090960195908201906001016151d2565b509495945050505050565b60408152600061522460408301856151be565b90508260208301529392505050565b80356fffffffffffffffffffffffffffffffff81168114614bf157600080fd5b60006060828403121561526557600080fd5b61526d614b47565b823561527881614c0c565b815261528660208401615233565b602082015261529760408401615233565b60408201529392505050565b600060208083850312156152b657600080fd5b823567ffffffffffffffff8111156152cd57600080fd5b8301601f810185136152de57600080fd5b80356152ec614c6382614bb9565b8181526060918202830184019184820191908884111561530b57600080fd5b938501935b83851015614d325780858a0312156153285760008081fd5b615330614b47565b853561533b81614a19565b8152615348868801614f7c565b878201526040615359818801614bdd565b9082015283529384019391850191615310565b60006020828403121561537e57600080fd5b813561147081614c0c565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126153be57600080fd5b83018035915067ffffffffffffffff8211156153d957600080fd5b602001915036819003821315613b4857600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261542357600080fd5b83018035915067ffffffffffffffff82111561543e57600080fd5b6020019150600681901b3603821315613b4857600080fd5b805177ffffffffffffffffffffffffffffffffffffffffffffffff81168114614bf157600080fd5b6000806040838503121561549157600080fd5b61549a83615456565b91506154a860208401615456565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176110f3576110f36154b1565b808201808211156110f3576110f36154b1565b600082615540577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b67ffffffffffffffff818116838216019080821115614635576146356154b1565b60006020828403121561557857600080fd5b5051919050565b60006040828403121561559157600080fd5b615599614b24565b82356155a481614a19565b81526155b260208401614f7c565b60208201529392505050565b6000602082840312156155d057600080fd5b815161147081614bf6565b6000602082840312156155ed57600080fd5b815161147081614c0c565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000613f726020830184866155f8565b60006020828403121561566757600080fd5b5035919050565b60006040828403121561568057600080fd5b615688614b24565b823561569381614a19565b81526020928301359281019290925250919050565b6bffffffffffffffffffffffff818116838216019080821115614635576146356154b1565b600067ffffffffffffffff8083168181036156ea576156ea6154b1565b6001019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6001600160a01b038716815260a06020820152600061574660a0830187896155f8565b85604084015267ffffffffffffffff851660608401528281036080840152610dcc8185614a6f565b60006020828403121561578057600080fd5b815167ffffffffffffffff8082111561579857600080fd5b818401915084601f8301126157ac57600080fd5b8151818111156157be576157be614acc565b6157ef60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614b6a565b915080825285602082850101111561580657600080fd5b615817816020840160208601614a4b565b50949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615851576158516154b1565b5060010190565b600081518084526020808501945080840160005b8381101561520657815180516001600160a01b03168852830151838801526040909601959082019060010161586c565b602081526158b760208201835167ffffffffffffffff169052565b600060208301516158d4604084018267ffffffffffffffff169052565b506040830151606083015260608301516158f960808401826001600160a01b03169052565b50608083015167ffffffffffffffff811660a08401525060a083015160c083015260c083015161592d60e084018215159052565b5060e083015161010061594a818501836001600160a01b03169052565b80850151915050610180610120818186015261596a6101a0860184614a6f565b92508086015190506101407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086850301818701526159a88483615858565b9350808701519150506101606159c8818701836001600160a01b03169052565b959095015193019290925250919050565b6bffffffffffffffffffffffff828116828216039080821115614635576146356154b1565b602080825282518282018190526000919060409081850190868401855b82811015615aa857815180516001600160a01b031685528681015163ffffffff90811688870152868201518116878701526060808301519091169086015260808082015167ffffffffffffffff169086015260a080820151615a888288018267ffffffffffffffff169052565b505060c09081015115159085015260e09093019290850190600101615a1b565b5091979650505050505050565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015615af55780818660040360031b1b83161692505b505092915050565b60008085851115615b0d57600080fd5b83861115615b1a57600080fd5b5050820193919092039150565b600060208284031215615b3957600080fd5b6040516020810181811067ffffffffffffffff82111715615b5c57615b5c614acc565b6040529135825250919050565b600060208284031215615b7b57600080fd5b61147082615456565b63ffffffff818116838216019080821115614635576146356154b1565b600060208284031215615bb357600080fd5b815161147081614a19565b818103818111156110f3576110f36154b1565b8181036000831280158383131683831282161715614635576146356154b1565b6101c08101615c6e82856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b82516001600160a01b0390811660e0840152602084015161ffff908116610100850152604085015163ffffffff9081166101208601526060860151909116610140850152608085015190911661016084015260a08401511661018083015260c083015167ffffffffffffffff166101a0830152611470565b600081615cf557615cf56154b1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b63ffffffff83168152604060208201526000613f7260408301846151be565b600060408284031215615d4c57600080fd5b615d54614b24565b615d5d83615456565b815260208301516155b281614bf6565b6020815260006114706020830184615858565b602080825282518282018190526000919060409081850190868401855b82811015615aa857815180516001600160a01b031685528681015161ffff168786015285015163ffffffff168585015260609093019290850190600101615d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251615e20818460208701614a4b565b919091019291505056fea164736f6c6343000813000a", +} + +var EVM2EVMOnRampABI = EVM2EVMOnRampMetaData.ABI + +var EVM2EVMOnRampBin = EVM2EVMOnRampMetaData.Bin + +func DeployEVM2EVMOnRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMOnRampStaticConfig, dynamicConfig EVM2EVMOnRampDynamicConfig, tokensAndPools []InternalPoolUpdate, allowlist []common.Address, rateLimiterConfig RateLimiterConfig, feeTokenConfigs []EVM2EVMOnRampFeeTokenConfigArgs, tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs, nopsAndWeights []EVM2EVMOnRampNopAndWeight) (common.Address, *types.Transaction, *EVM2EVMOnRamp, error) { + parsed, err := EVM2EVMOnRampMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMOnRampBin), backend, staticConfig, dynamicConfig, tokensAndPools, allowlist, rateLimiterConfig, feeTokenConfigs, tokenTransferFeeConfigArgs, nopsAndWeights) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EVM2EVMOnRamp{EVM2EVMOnRampCaller: EVM2EVMOnRampCaller{contract: contract}, EVM2EVMOnRampTransactor: EVM2EVMOnRampTransactor{contract: contract}, EVM2EVMOnRampFilterer: EVM2EVMOnRampFilterer{contract: contract}}, nil +} + +type EVM2EVMOnRamp struct { + address common.Address + abi abi.ABI + EVM2EVMOnRampCaller + EVM2EVMOnRampTransactor + EVM2EVMOnRampFilterer +} + +type EVM2EVMOnRampCaller struct { + contract *bind.BoundContract +} + +type EVM2EVMOnRampTransactor struct { + contract *bind.BoundContract +} + +type EVM2EVMOnRampFilterer struct { + contract *bind.BoundContract +} + +type EVM2EVMOnRampSession struct { + Contract *EVM2EVMOnRamp + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type EVM2EVMOnRampCallerSession struct { + Contract *EVM2EVMOnRampCaller + CallOpts bind.CallOpts +} + +type EVM2EVMOnRampTransactorSession struct { + Contract *EVM2EVMOnRampTransactor + TransactOpts bind.TransactOpts +} + +type EVM2EVMOnRampRaw struct { + Contract *EVM2EVMOnRamp +} + +type EVM2EVMOnRampCallerRaw struct { + Contract *EVM2EVMOnRampCaller +} + +type EVM2EVMOnRampTransactorRaw struct { + Contract *EVM2EVMOnRampTransactor +} + +func NewEVM2EVMOnRamp(address common.Address, backend bind.ContractBackend) (*EVM2EVMOnRamp, error) { + abi, err := abi.JSON(strings.NewReader(EVM2EVMOnRampABI)) + if err != nil { + return nil, err + } + contract, err := bindEVM2EVMOnRamp(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &EVM2EVMOnRamp{address: address, abi: abi, EVM2EVMOnRampCaller: EVM2EVMOnRampCaller{contract: contract}, EVM2EVMOnRampTransactor: EVM2EVMOnRampTransactor{contract: contract}, EVM2EVMOnRampFilterer: EVM2EVMOnRampFilterer{contract: contract}}, nil +} + +func NewEVM2EVMOnRampCaller(address common.Address, caller bind.ContractCaller) (*EVM2EVMOnRampCaller, error) { + contract, err := bindEVM2EVMOnRamp(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampCaller{contract: contract}, nil +} + +func NewEVM2EVMOnRampTransactor(address common.Address, transactor bind.ContractTransactor) (*EVM2EVMOnRampTransactor, error) { + contract, err := bindEVM2EVMOnRamp(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampTransactor{contract: contract}, nil +} + +func NewEVM2EVMOnRampFilterer(address common.Address, filterer bind.ContractFilterer) (*EVM2EVMOnRampFilterer, error) { + contract, err := bindEVM2EVMOnRamp(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampFilterer{contract: contract}, nil +} + +func bindEVM2EVMOnRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EVM2EVMOnRampMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOnRamp.Contract.EVM2EVMOnRampCaller.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.EVM2EVMOnRampTransactor.contract.Transfer(opts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.EVM2EVMOnRampTransactor.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOnRamp.Contract.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.contract.Transfer(opts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "currentRateLimiterState") + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOnRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOnRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetAllowList() ([]common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetAllowList(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetAllowList() ([]common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetAllowList(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetAllowListEnabled() (bool, error) { + return _EVM2EVMOnRamp.Contract.GetAllowListEnabled(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetAllowListEnabled() (bool, error) { + return _EVM2EVMOnRamp.Contract.GetAllowListEnabled(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOnRampDynamicConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(EVM2EVMOnRampDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampDynamicConfig)).(*EVM2EVMOnRampDynamicConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetDynamicConfig() (EVM2EVMOnRampDynamicConfig, error) { + return _EVM2EVMOnRamp.Contract.GetDynamicConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetDynamicConfig() (EVM2EVMOnRampDynamicConfig, error) { + return _EVM2EVMOnRamp.Contract.GetDynamicConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getExpectedNextSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetExpectedNextSequenceNumber(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetExpectedNextSequenceNumber(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetFee(opts *bind.CallOpts, message ClientEVM2AnyMessage) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getFee", message) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetFee(message ClientEVM2AnyMessage) (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetFee(&_EVM2EVMOnRamp.CallOpts, message) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetFee(message ClientEVM2AnyMessage) (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetFee(&_EVM2EVMOnRamp.CallOpts, message) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetFeeTokenConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getFeeTokenConfig", token) + + if err != nil { + return *new(EVM2EVMOnRampFeeTokenConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampFeeTokenConfig)).(*EVM2EVMOnRampFeeTokenConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetFeeTokenConfig(token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) { + return _EVM2EVMOnRamp.Contract.GetFeeTokenConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetFeeTokenConfig(token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) { + return _EVM2EVMOnRamp.Contract.GetFeeTokenConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetNopFeesJuels(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getNopFeesJuels") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetNopFeesJuels() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetNopFeesJuels(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetNopFeesJuels() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetNopFeesJuels(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetNops(opts *bind.CallOpts) (GetNops, + + error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getNops") + + outstruct := new(GetNops) + if err != nil { + return *outstruct, err + } + + outstruct.NopsAndWeights = *abi.ConvertType(out[0], new([]EVM2EVMOnRampNopAndWeight)).(*[]EVM2EVMOnRampNopAndWeight) + outstruct.WeightsTotal = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetNops() (GetNops, + + error) { + return _EVM2EVMOnRamp.Contract.GetNops(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetNops() (GetNops, + + error) { + return _EVM2EVMOnRamp.Contract.GetNops(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetPoolBySourceToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getPoolBySourceToken", sourceToken) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetPoolBySourceToken(sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMOnRamp.CallOpts, sourceToken) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetPoolBySourceToken(sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMOnRamp.CallOpts, sourceToken) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getSenderNonce", sender) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetSenderNonce(&_EVM2EVMOnRamp.CallOpts, sender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetSenderNonce(&_EVM2EVMOnRamp.CallOpts, sender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOnRampStaticConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(EVM2EVMOnRampStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampStaticConfig)).(*EVM2EVMOnRampStaticConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetStaticConfig() (EVM2EVMOnRampStaticConfig, error) { + return _EVM2EVMOnRamp.Contract.GetStaticConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetStaticConfig() (EVM2EVMOnRampStaticConfig, error) { + return _EVM2EVMOnRamp.Contract.GetStaticConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetSupportedTokens(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getSupportedTokens") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetSupportedTokens() ([]common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetSupportedTokens(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetSupportedTokens() ([]common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetSupportedTokens(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getTokenLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetTokenTransferFeeConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getTokenTransferFeeConfig", token) + + if err != nil { + return *new(EVM2EVMOnRampTokenTransferFeeConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampTokenTransferFeeConfig)).(*EVM2EVMOnRampTokenTransferFeeConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetTokenTransferFeeConfig(token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) { + return _EVM2EVMOnRamp.Contract.GetTokenTransferFeeConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetTokenTransferFeeConfig(token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) { + return _EVM2EVMOnRamp.Contract.GetTokenTransferFeeConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "linkAvailableForPayment") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) LinkAvailableForPayment() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.LinkAvailableForPayment(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) LinkAvailableForPayment() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.LinkAvailableForPayment(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) Owner() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.Owner(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) Owner() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.Owner(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) TypeAndVersion() (string, error) { + return _EVM2EVMOnRamp.Contract.TypeAndVersion(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) TypeAndVersion() (string, error) { + return _EVM2EVMOnRamp.Contract.TypeAndVersion(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "acceptOwnership") +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.AcceptOwnership(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.AcceptOwnership(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ApplyAllowListUpdates(&_EVM2EVMOnRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ApplyAllowListUpdates(&_EVM2EVMOnRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) ApplyPoolUpdates(opts *bind.TransactOpts, removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "applyPoolUpdates", removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) ApplyPoolUpdates(removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ApplyPoolUpdates(&_EVM2EVMOnRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) ApplyPoolUpdates(removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ApplyPoolUpdates(&_EVM2EVMOnRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) ForwardFromRouter(opts *bind.TransactOpts, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "forwardFromRouter", message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) ForwardFromRouter(message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ForwardFromRouter(&_EVM2EVMOnRamp.TransactOpts, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) ForwardFromRouter(message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ForwardFromRouter(&_EVM2EVMOnRamp.TransactOpts, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) PayNops(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "payNops") +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) PayNops() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.PayNops(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) PayNops() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.PayNops(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setAdmin", newAdmin) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetAdmin(&_EVM2EVMOnRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetAdmin(&_EVM2EVMOnRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetAllowListEnabled(opts *bind.TransactOpts, enabled bool) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setAllowListEnabled", enabled) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetAllowListEnabled(enabled bool) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetAllowListEnabled(&_EVM2EVMOnRamp.TransactOpts, enabled) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetAllowListEnabled(enabled bool) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetAllowListEnabled(&_EVM2EVMOnRamp.TransactOpts, enabled) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setDynamicConfig", dynamicConfig) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetDynamicConfig(dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetDynamicConfig(&_EVM2EVMOnRamp.TransactOpts, dynamicConfig) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetDynamicConfig(dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetDynamicConfig(&_EVM2EVMOnRamp.TransactOpts, dynamicConfig) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetFeeTokenConfig(opts *bind.TransactOpts, feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setFeeTokenConfig", feeTokenConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetFeeTokenConfig(feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetFeeTokenConfig(&_EVM2EVMOnRamp.TransactOpts, feeTokenConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetFeeTokenConfig(feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetFeeTokenConfig(&_EVM2EVMOnRamp.TransactOpts, feeTokenConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetNops(opts *bind.TransactOpts, nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setNops", nopsAndWeights) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetNops(nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetNops(&_EVM2EVMOnRamp.TransactOpts, nopsAndWeights) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetNops(nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetNops(&_EVM2EVMOnRamp.TransactOpts, nopsAndWeights) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setRateLimiterConfig", config) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOnRamp.TransactOpts, config) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOnRamp.TransactOpts, config) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetTokenTransferFeeConfig(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setTokenTransferFeeConfig", tokenTransferFeeConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetTokenTransferFeeConfig(tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetTokenTransferFeeConfig(&_EVM2EVMOnRamp.TransactOpts, tokenTransferFeeConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetTokenTransferFeeConfig(tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetTokenTransferFeeConfig(&_EVM2EVMOnRamp.TransactOpts, tokenTransferFeeConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "transferOwnership", to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.TransferOwnership(&_EVM2EVMOnRamp.TransactOpts, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.TransferOwnership(&_EVM2EVMOnRamp.TransactOpts, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) WithdrawNonLinkFees(opts *bind.TransactOpts, feeToken common.Address, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "withdrawNonLinkFees", feeToken, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) WithdrawNonLinkFees(feeToken common.Address, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.WithdrawNonLinkFees(&_EVM2EVMOnRamp.TransactOpts, feeToken, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) WithdrawNonLinkFees(feeToken common.Address, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.WithdrawNonLinkFees(&_EVM2EVMOnRamp.TransactOpts, feeToken, to) +} + +type EVM2EVMOnRampAdminSetIterator struct { + Event *EVM2EVMOnRampAdminSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampAdminSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampAdminSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampAdminSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampAdminSet struct { + NewAdmin common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOnRampAdminSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampAdminSetIterator{contract: _EVM2EVMOnRamp.contract, event: "AdminSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAdminSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampAdminSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseAdminSet(log types.Log) (*EVM2EVMOnRampAdminSet, error) { + event := new(EVM2EVMOnRampAdminSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampAllowListAddIterator struct { + Event *EVM2EVMOnRampAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampAllowListAddIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*EVM2EVMOnRampAllowListAddIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampAllowListAddIterator{contract: _EVM2EVMOnRamp.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampAllowListAdd) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseAllowListAdd(log types.Log) (*EVM2EVMOnRampAllowListAdd, error) { + event := new(EVM2EVMOnRampAllowListAdd) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampAllowListEnabledSetIterator struct { + Event *EVM2EVMOnRampAllowListEnabledSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampAllowListEnabledSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAllowListEnabledSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAllowListEnabledSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampAllowListEnabledSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampAllowListEnabledSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampAllowListEnabledSet struct { + Enabled bool + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterAllowListEnabledSet(opts *bind.FilterOpts) (*EVM2EVMOnRampAllowListEnabledSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "AllowListEnabledSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampAllowListEnabledSetIterator{contract: _EVM2EVMOnRamp.contract, event: "AllowListEnabledSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchAllowListEnabledSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAllowListEnabledSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "AllowListEnabledSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampAllowListEnabledSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AllowListEnabledSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseAllowListEnabledSet(log types.Log) (*EVM2EVMOnRampAllowListEnabledSet, error) { + event := new(EVM2EVMOnRampAllowListEnabledSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AllowListEnabledSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampAllowListRemoveIterator struct { + Event *EVM2EVMOnRampAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*EVM2EVMOnRampAllowListRemoveIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampAllowListRemoveIterator{contract: _EVM2EVMOnRamp.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampAllowListRemove) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseAllowListRemove(log types.Log) (*EVM2EVMOnRampAllowListRemove, error) { + event := new(EVM2EVMOnRampAllowListRemove) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampCCIPSendRequestedIterator struct { + Event *EVM2EVMOnRampCCIPSendRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampCCIPSendRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampCCIPSendRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampCCIPSendRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampCCIPSendRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampCCIPSendRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampCCIPSendRequested struct { + Message InternalEVM2EVMMessage + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterCCIPSendRequested(opts *bind.FilterOpts) (*EVM2EVMOnRampCCIPSendRequestedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "CCIPSendRequested") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampCCIPSendRequestedIterator{contract: _EVM2EVMOnRamp.contract, event: "CCIPSendRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampCCIPSendRequested) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "CCIPSendRequested") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampCCIPSendRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseCCIPSendRequested(log types.Log) (*EVM2EVMOnRampCCIPSendRequested, error) { + event := new(EVM2EVMOnRampCCIPSendRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampConfigSetIterator struct { + Event *EVM2EVMOnRampConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampConfigSet struct { + StaticConfig EVM2EVMOnRampStaticConfig + DynamicConfig EVM2EVMOnRampDynamicConfig + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampConfigSetIterator{contract: _EVM2EVMOnRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseConfigSet(log types.Log) (*EVM2EVMOnRampConfigSet, error) { + event := new(EVM2EVMOnRampConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampFeeConfigSetIterator struct { + Event *EVM2EVMOnRampFeeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampFeeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampFeeConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampFeeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampFeeConfigSet struct { + FeeConfig []EVM2EVMOnRampFeeTokenConfigArgs + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampFeeConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "FeeConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampFeeConfigSetIterator{contract: _EVM2EVMOnRamp.contract, event: "FeeConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampFeeConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "FeeConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "FeeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseFeeConfigSet(log types.Log) (*EVM2EVMOnRampFeeConfigSet, error) { + event := new(EVM2EVMOnRampFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "FeeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampNopPaidIterator struct { + Event *EVM2EVMOnRampNopPaid + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampNopPaidIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopPaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopPaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampNopPaidIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampNopPaidIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampNopPaid struct { + Nop common.Address + Amount *big.Int + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterNopPaid(opts *bind.FilterOpts, nop []common.Address) (*EVM2EVMOnRampNopPaidIterator, error) { + + var nopRule []interface{} + for _, nopItem := range nop { + nopRule = append(nopRule, nopItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "NopPaid", nopRule) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampNopPaidIterator{contract: _EVM2EVMOnRamp.contract, event: "NopPaid", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchNopPaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopPaid, nop []common.Address) (event.Subscription, error) { + + var nopRule []interface{} + for _, nopItem := range nop { + nopRule = append(nopRule, nopItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "NopPaid", nopRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampNopPaid) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopPaid", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseNopPaid(log types.Log) (*EVM2EVMOnRampNopPaid, error) { + event := new(EVM2EVMOnRampNopPaid) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopPaid", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampNopsSetIterator struct { + Event *EVM2EVMOnRampNopsSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampNopsSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopsSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopsSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampNopsSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampNopsSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampNopsSet struct { + NopWeightsTotal *big.Int + NopsAndWeights []EVM2EVMOnRampNopAndWeight + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterNopsSet(opts *bind.FilterOpts) (*EVM2EVMOnRampNopsSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "NopsSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampNopsSetIterator{contract: _EVM2EVMOnRamp.contract, event: "NopsSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchNopsSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopsSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "NopsSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampNopsSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopsSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseNopsSet(log types.Log) (*EVM2EVMOnRampNopsSet, error) { + event := new(EVM2EVMOnRampNopsSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopsSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampOwnershipTransferRequestedIterator struct { + Event *EVM2EVMOnRampOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampOwnershipTransferRequestedIterator{contract: _EVM2EVMOnRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampOwnershipTransferRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOnRampOwnershipTransferRequested, error) { + event := new(EVM2EVMOnRampOwnershipTransferRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampOwnershipTransferredIterator struct { + Event *EVM2EVMOnRampOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampOwnershipTransferredIterator{contract: _EVM2EVMOnRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampOwnershipTransferred) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseOwnershipTransferred(log types.Log) (*EVM2EVMOnRampOwnershipTransferred, error) { + event := new(EVM2EVMOnRampOwnershipTransferred) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampPoolAddedIterator struct { + Event *EVM2EVMOnRampPoolAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampPoolAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampPoolAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampPoolAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampPoolAddedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampPoolAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampPoolAdded struct { + Token common.Address + Pool common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterPoolAdded(opts *bind.FilterOpts) (*EVM2EVMOnRampPoolAddedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "PoolAdded") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampPoolAddedIterator{contract: _EVM2EVMOnRamp.contract, event: "PoolAdded", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchPoolAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampPoolAdded) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "PoolAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampPoolAdded) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "PoolAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParsePoolAdded(log types.Log) (*EVM2EVMOnRampPoolAdded, error) { + event := new(EVM2EVMOnRampPoolAdded) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "PoolAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampPoolRemovedIterator struct { + Event *EVM2EVMOnRampPoolRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampPoolRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampPoolRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampPoolRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampPoolRemovedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampPoolRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampPoolRemoved struct { + Token common.Address + Pool common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterPoolRemoved(opts *bind.FilterOpts) (*EVM2EVMOnRampPoolRemovedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "PoolRemoved") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampPoolRemovedIterator{contract: _EVM2EVMOnRamp.contract, event: "PoolRemoved", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchPoolRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampPoolRemoved) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "PoolRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampPoolRemoved) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "PoolRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParsePoolRemoved(log types.Log) (*EVM2EVMOnRampPoolRemoved, error) { + event := new(EVM2EVMOnRampPoolRemoved) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "PoolRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampTokenTransferFeeConfigSetIterator struct { + Event *EVM2EVMOnRampTokenTransferFeeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampTokenTransferFeeConfigSet struct { + TransferFeeConfig []EVM2EVMOnRampTokenTransferFeeConfigArgs + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterTokenTransferFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampTokenTransferFeeConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "TokenTransferFeeConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampTokenTransferFeeConfigSetIterator{contract: _EVM2EVMOnRamp.contract, event: "TokenTransferFeeConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchTokenTransferFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampTokenTransferFeeConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "TokenTransferFeeConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "TokenTransferFeeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseTokenTransferFeeConfigSet(log types.Log) (*EVM2EVMOnRampTokenTransferFeeConfigSet, error) { + event := new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "TokenTransferFeeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetNops struct { + NopsAndWeights []EVM2EVMOnRampNopAndWeight + WeightsTotal *big.Int +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _EVM2EVMOnRamp.abi.Events["AdminSet"].ID: + return _EVM2EVMOnRamp.ParseAdminSet(log) + case _EVM2EVMOnRamp.abi.Events["AllowListAdd"].ID: + return _EVM2EVMOnRamp.ParseAllowListAdd(log) + case _EVM2EVMOnRamp.abi.Events["AllowListEnabledSet"].ID: + return _EVM2EVMOnRamp.ParseAllowListEnabledSet(log) + case _EVM2EVMOnRamp.abi.Events["AllowListRemove"].ID: + return _EVM2EVMOnRamp.ParseAllowListRemove(log) + case _EVM2EVMOnRamp.abi.Events["CCIPSendRequested"].ID: + return _EVM2EVMOnRamp.ParseCCIPSendRequested(log) + case _EVM2EVMOnRamp.abi.Events["ConfigSet"].ID: + return _EVM2EVMOnRamp.ParseConfigSet(log) + case _EVM2EVMOnRamp.abi.Events["FeeConfigSet"].ID: + return _EVM2EVMOnRamp.ParseFeeConfigSet(log) + case _EVM2EVMOnRamp.abi.Events["NopPaid"].ID: + return _EVM2EVMOnRamp.ParseNopPaid(log) + case _EVM2EVMOnRamp.abi.Events["NopsSet"].ID: + return _EVM2EVMOnRamp.ParseNopsSet(log) + case _EVM2EVMOnRamp.abi.Events["OwnershipTransferRequested"].ID: + return _EVM2EVMOnRamp.ParseOwnershipTransferRequested(log) + case _EVM2EVMOnRamp.abi.Events["OwnershipTransferred"].ID: + return _EVM2EVMOnRamp.ParseOwnershipTransferred(log) + case _EVM2EVMOnRamp.abi.Events["PoolAdded"].ID: + return _EVM2EVMOnRamp.ParsePoolAdded(log) + case _EVM2EVMOnRamp.abi.Events["PoolRemoved"].ID: + return _EVM2EVMOnRamp.ParsePoolRemoved(log) + case _EVM2EVMOnRamp.abi.Events["TokenTransferFeeConfigSet"].ID: + return _EVM2EVMOnRamp.ParseTokenTransferFeeConfigSet(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (EVM2EVMOnRampAdminSet) Topic() common.Hash { + return common.HexToHash("0x8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c") +} + +func (EVM2EVMOnRampAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (EVM2EVMOnRampAllowListEnabledSet) Topic() common.Hash { + return common.HexToHash("0xccf4daf6ab6430389f26b970595dab82a5881ad454770907e415ede27c8df032") +} + +func (EVM2EVMOnRampAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (EVM2EVMOnRampCCIPSendRequested) Topic() common.Hash { + return common.HexToHash("0xaffc45517195d6499808c643bd4a7b0ffeedf95bea5852840d7bfcf63f59e821") +} + +func (EVM2EVMOnRampConfigSet) Topic() common.Hash { + return common.HexToHash("0x72c6aaba4dde02f77d291123a76185c418ba63f8c217a2d56b08aec84e9bbfb8") +} + +func (EVM2EVMOnRampFeeConfigSet) Topic() common.Hash { + return common.HexToHash("0x2386f61ab5cafc3fed44f9f614f721ab53479ef64067fd16c1a2491b63ddf1a8") +} + +func (EVM2EVMOnRampNopPaid) Topic() common.Hash { + return common.HexToHash("0x55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f") +} + +func (EVM2EVMOnRampNopsSet) Topic() common.Hash { + return common.HexToHash("0x8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd24") +} + +func (EVM2EVMOnRampOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (EVM2EVMOnRampOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (EVM2EVMOnRampPoolAdded) Topic() common.Hash { + return common.HexToHash("0x95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c") +} + +func (EVM2EVMOnRampPoolRemoved) Topic() common.Hash { + return common.HexToHash("0x987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c") +} + +func (EVM2EVMOnRampTokenTransferFeeConfigSet) Topic() common.Hash { + return common.HexToHash("0x4230c60a9725eb5fb992cf6a215398b4e81b4606d4a1e6be8dfe0b60dc172ec1") +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRamp) Address() common.Address { + return _EVM2EVMOnRamp.address +} + +type EVM2EVMOnRampInterface interface { + CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) + + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOnRampDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetFee(opts *bind.CallOpts, message ClientEVM2AnyMessage) (*big.Int, error) + + GetFeeTokenConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) + + GetNopFeesJuels(opts *bind.CallOpts) (*big.Int, error) + + GetNops(opts *bind.CallOpts) (GetNops, + + error) + + GetPoolBySourceToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) + + GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) + + GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOnRampStaticConfig, error) + + GetSupportedTokens(opts *bind.CallOpts) ([]common.Address, error) + + GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) + + GetTokenTransferFeeConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) + + LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyPoolUpdates(opts *bind.TransactOpts, removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) + + ForwardFromRouter(opts *bind.TransactOpts, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) + + PayNops(opts *bind.TransactOpts) (*types.Transaction, error) + + SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) + + SetAllowListEnabled(opts *bind.TransactOpts, enabled bool) (*types.Transaction, error) + + SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) + + SetFeeTokenConfig(opts *bind.TransactOpts, feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) + + SetNops(opts *bind.TransactOpts, nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) + + SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) + + SetTokenTransferFeeConfig(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + WithdrawNonLinkFees(opts *bind.TransactOpts, feeToken common.Address, to common.Address) (*types.Transaction, error) + + FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOnRampAdminSetIterator, error) + + WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAdminSet) (event.Subscription, error) + + ParseAdminSet(log types.Log) (*EVM2EVMOnRampAdminSet, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*EVM2EVMOnRampAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*EVM2EVMOnRampAllowListAdd, error) + + FilterAllowListEnabledSet(opts *bind.FilterOpts) (*EVM2EVMOnRampAllowListEnabledSetIterator, error) + + WatchAllowListEnabledSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAllowListEnabledSet) (event.Subscription, error) + + ParseAllowListEnabledSet(log types.Log) (*EVM2EVMOnRampAllowListEnabledSet, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*EVM2EVMOnRampAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*EVM2EVMOnRampAllowListRemove, error) + + FilterCCIPSendRequested(opts *bind.FilterOpts) (*EVM2EVMOnRampCCIPSendRequestedIterator, error) + + WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampCCIPSendRequested) (event.Subscription, error) + + ParseCCIPSendRequested(log types.Log) (*EVM2EVMOnRampCCIPSendRequested, error) + + FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*EVM2EVMOnRampConfigSet, error) + + FilterFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampFeeConfigSetIterator, error) + + WatchFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampFeeConfigSet) (event.Subscription, error) + + ParseFeeConfigSet(log types.Log) (*EVM2EVMOnRampFeeConfigSet, error) + + FilterNopPaid(opts *bind.FilterOpts, nop []common.Address) (*EVM2EVMOnRampNopPaidIterator, error) + + WatchNopPaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopPaid, nop []common.Address) (event.Subscription, error) + + ParseNopPaid(log types.Log) (*EVM2EVMOnRampNopPaid, error) + + FilterNopsSet(opts *bind.FilterOpts) (*EVM2EVMOnRampNopsSetIterator, error) + + WatchNopsSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopsSet) (event.Subscription, error) + + ParseNopsSet(log types.Log) (*EVM2EVMOnRampNopsSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOnRampOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*EVM2EVMOnRampOwnershipTransferred, error) + + FilterPoolAdded(opts *bind.FilterOpts) (*EVM2EVMOnRampPoolAddedIterator, error) + + WatchPoolAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampPoolAdded) (event.Subscription, error) + + ParsePoolAdded(log types.Log) (*EVM2EVMOnRampPoolAdded, error) + + FilterPoolRemoved(opts *bind.FilterOpts) (*EVM2EVMOnRampPoolRemovedIterator, error) + + WatchPoolRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampPoolRemoved) (event.Subscription, error) + + ParsePoolRemoved(log types.Log) (*EVM2EVMOnRampPoolRemoved, error) + + FilterTokenTransferFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampTokenTransferFeeConfigSetIterator, error) + + WatchTokenTransferFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampTokenTransferFeeConfigSet) (event.Subscription, error) + + ParseTokenTransferFeeConfigSet(log types.Log) (*EVM2EVMOnRampTokenTransferFeeConfigSet, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0/evm_2_evm_onramp_1_2_0.go b/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0/evm_2_evm_onramp_1_2_0.go new file mode 100644 index 0000000000..8c652e140d --- /dev/null +++ b/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0/evm_2_evm_onramp_1_2_0.go @@ -0,0 +1,2337 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package evm_2_evm_onramp_1_2_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientEVM2AnyMessage struct { + Receiver []byte + Data []byte + TokenAmounts []ClientEVMTokenAmount + FeeToken common.Address + ExtraArgs []byte +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type EVM2EVMOnRampDynamicConfig struct { + Router common.Address + MaxNumberOfTokensPerMsg uint16 + DestGasOverhead uint32 + DestGasPerPayloadByte uint16 + DestDataAvailabilityOverheadGas uint32 + DestGasPerDataAvailabilityByte uint16 + DestDataAvailabilityMultiplierBps uint16 + PriceRegistry common.Address + MaxDataBytes uint32 + MaxPerMsgGasLimit uint32 +} + +type EVM2EVMOnRampFeeTokenConfig struct { + NetworkFeeUSDCents uint32 + GasMultiplierWeiPerEth uint64 + PremiumMultiplierWeiPerEth uint64 + Enabled bool +} + +type EVM2EVMOnRampFeeTokenConfigArgs struct { + Token common.Address + NetworkFeeUSDCents uint32 + GasMultiplierWeiPerEth uint64 + PremiumMultiplierWeiPerEth uint64 + Enabled bool +} + +type EVM2EVMOnRampNopAndWeight struct { + Nop common.Address + Weight uint16 +} + +type EVM2EVMOnRampStaticConfig struct { + LinkToken common.Address + ChainSelector uint64 + DestChainSelector uint64 + DefaultTxGasLimit uint64 + MaxNopFeesJuels *big.Int + PrevOnRamp common.Address + ArmProxy common.Address +} + +type EVM2EVMOnRampTokenTransferFeeConfig struct { + MinFeeUSDCents uint32 + MaxFeeUSDCents uint32 + DeciBps uint16 + DestGasOverhead uint32 + DestBytesOverhead uint32 +} + +type EVM2EVMOnRampTokenTransferFeeConfigArgs struct { + Token common.Address + MinFeeUSDCents uint32 + MaxFeeUSDCents uint32 + DeciBps uint16 + DestGasOverhead uint32 + DestBytesOverhead uint32 +} + +type InternalEVM2EVMMessage struct { + SourceChainSelector uint64 + Sender common.Address + Receiver common.Address + SequenceNumber uint64 + GasLimit *big.Int + Strict bool + Nonce uint64 + FeeToken common.Address + FeeTokenAmount *big.Int + Data []byte + TokenAmounts []ClientEVMTokenAmount + SourceTokenData [][]byte + MessageId [32]byte +} + +type InternalPoolUpdate struct { + Token common.Address + Pool common.Address +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +var EVM2EVMOnRampMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"tokensAndPools\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidChainSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"}],\"name\":\"InvalidNopAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWithdrawParams\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkBalanceNotSettled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeeBalanceReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoFeesToPay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoNopsToPay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdminOrNop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyNops\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeConfig\",\"type\":\"tuple[]\"}],\"name\":\"FeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NopPaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nopWeightsTotal\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"NopsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"transferFeeConfig\",\"type\":\"tuple[]\"}],\"name\":\"TokenTransferFeeConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getFeeTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfig\",\"name\":\"feeTokenConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNopFeesJuels\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNops\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"weightsTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setFeeTokenConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setTokenTransferFeeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawNonLinkFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101806040523480156200001257600080fd5b506040516200849a3803806200849a833981016040819052620000359162001e40565b8333806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c08162000323565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555086516001600160a01b0316158062000169575060208701516001600160401b0316155b8062000180575060408701516001600160401b0316155b8062000197575060608701516001600160401b0316155b80620001ae575060c08701516001600160a01b0316155b15620001cd576040516306b7c75960e31b815260040160405180910390fd5b6020808801516040808a015181517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3948101949094526001600160401b039283169184019190915216606082015230608082015260a00160408051601f198184030181529181528151602092830120608090815289516001600160a01b0390811660e052928a01516001600160401b0390811661010052918a015182166101205260608a015190911660a0908152908901516001600160601b031660c0908152908901518216610140528801511661016052620002aa86620003ce565b620002b58362000645565b620002c0826200077f565b620002cb81620008e5565b6040805160008082526020820190925262000316916200030e565b6040805180820190915260008082526020820152815260200190600190039081620002e65790505b508662000b0f565b505050505050506200241a565b336001600160a01b038216036200037d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e08101516001600160a01b0316620003fa576040516306b7c75960e31b815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055509050507f2a57f7c2027cf032c78b77d4d8d2fbd20ad22e5d5e5b5fb23ac7d7820d44adc66040518060e0016040528060e0516001600160a01b03168152602001610100516001600160401b03168152602001610120516001600160401b0316815260200160a0516001600160401b0316815260200160c0516001600160601b03168152602001610140516001600160a01b03168152602001610160516001600160a01b0316815250826040516200063a92919062002015565b60405180910390a150565b60005b81518110156200074d57600082828151811062000669576200066962002095565b60209081029190910181015160408051608080820183528385015163ffffffff9081168352838501516001600160401b03908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600d90985294909620925183549451925195511515600160a01b0260ff60a01b199688166c010000000000000000000000000296909616600160601b600160a81b031993909716640100000000026001600160601b0319909516911617929092179190911692909217179055506200074581620020c1565b905062000648565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e816040516200063a9190620020dd565b60005b8151811015620008b3576000828281518110620007a357620007a362002095565b6020908102919091018101516040805160a080820183528385015163ffffffff908116835283850151811683870190815260608087015161ffff9081168688019081526080808a0151861693880193845295890151851695870195865297516001600160a01b03166000908152600e909952959097209351845491519651975193518316600160701b0263ffffffff60701b199484166a01000000000000000000000263ffffffff60501b199990971668010000000000000000029890981665ffffffffffff60401b19978416640100000000026001600160401b03199093169190931617179490941693909317919091179190911691909117905550620008ab81620020c1565b905062000782565b507f555c74101f7a15746d31c6731170310e667bcc607996b2fc0b981a7b26a416e9816040516200063a91906200216c565b805160408111156200090a57604051635ad0867d60e11b815260040160405180910390fd5b6010546c01000000000000000000000000900463ffffffff161580159062000954575060105463ffffffff6c010000000000000000000000008204166001600160601b0390911610155b1562000964576200096462000e12565b600062000972600762001012565b90505b8015620009be576000620009986200098f600184620021f3565b60079062001025565b509050620009a860078262001043565b505080620009b69062002209565b905062000975565b506000805b8281101562000aa6576000848281518110620009e357620009e362002095565b6020026020010151600001519050600085838151811062000a085762000a0862002095565b602002602001015160200151905060e0516001600160a01b0316826001600160a01b0316148062000a4057506001600160a01b038216155b1562000a6b57604051634de938d160e01b81526001600160a01b038316600482015260240162000084565b62000a7d60078361ffff841662001061565b5062000a8e61ffff82168562002223565b935050508062000a9e90620020c1565b9050620009c3565b506010805463ffffffff60601b19166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249062000b02908390869062002243565b60405180910390a1505050565b60005b825181101562000c4b57600083828151811062000b335762000b3362002095565b6020026020010151600001519050600084838151811062000b585762000b5862002095565b6020908102919091018101510151905062000b75600a8362001081565b62000b9f576040516373913ebd60e01b81526001600160a01b038316600482015260240162000084565b6001600160a01b03811662000bb6600a8462001098565b6001600160a01b03161462000bde57604051630d98f73360e31b815260040160405180910390fd5b62000beb600a83620010af565b1562000c3557604080516001600160a01b038085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a15b50508062000c4390620020c1565b905062000b12565b5060005b815181101562000e0d57600082828151811062000c705762000c7062002095565b6020026020010151600001519050600083838151811062000c955762000c9562002095565b602002602001015160200151905060006001600160a01b0316826001600160a01b0316148062000ccc57506001600160a01b038116155b1562000cea5760405162d8548360e71b815260040160405180910390fd5b806001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000d29573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d4f9190620022b0565b6001600160a01b0316826001600160a01b03161462000d8157604051630d98f73360e31b815260040160405180910390fd5b62000d8f600a8383620010c6565b1562000dde57604080516001600160a01b038085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a162000df7565b604051633caf458560e01b815260040160405180910390fd5b50508062000e0590620020c1565b905062000c4f565b505050565b6000546001600160a01b0316331480159062000e3957506002546001600160a01b03163314155b801562000e50575062000e4e600733620010de565b155b1562000e6f5760405163032bb72b60e31b815260040160405180910390fd5b6010546c01000000000000000000000000900463ffffffff16600081900362000eab5760405163990e30bf60e01b815260040160405180910390fd5b6010546001600160601b03168181101562000ed9576040516311a1ee3b60e31b815260040160405180910390fd5b600062000ee5620010f5565b121562000f0557604051631e9acf1760e31b815260040160405180910390fd5b80600062000f14600762001012565b905060005b8181101562000fec5760008062000f3260078462001025565b909250905060008762000f4f836001600160601b038a16620022d0565b62000f5b9190620022ea565b905062000f6981876200230d565b60e05190965062000f8e906001600160a01b0316846001600160601b03841662001183565b6040516001600160601b03821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a25050508062000fe490620020c1565b905062000f19565b5050601080546001600160601b0319166001600160601b03929092169190911790555050565b60006200101f82620011db565b92915050565b6000808080620010368686620011e8565b9097909650945050505050565b60006200105a836001600160a01b03841662001215565b9392505050565b600062001079846001600160a01b0385168462001234565b949350505050565b60006200105a836001600160a01b03841662001253565b60006200105a836001600160a01b03841662001261565b60006200105a836001600160a01b0384166200126f565b600062001079846001600160a01b038516846200127d565b60006200105a836001600160a01b03841662001295565b60105460e0516040516370a0823160e01b81523060048201526000926001600160601b0316916001600160a01b0316906370a0823190602401602060405180830381865afa1580156200114c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001172919062002330565b6200117e91906200234a565b905090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915262000e0d918591620012a316565b60006200101f8262001374565b60008080620011f885856200137f565b600081815260029690960160205260409095205494959350505050565b600081815260028301602052604081208190556200105a83836200138d565b600082815260028401602052604081208290556200107984846200139b565b60006200105a838362001295565b60006200105a8383620013a9565b60006200105a838362001215565b60006200107984846001600160a01b03851662001234565b60006200105a83836200141e565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620012f2906001600160a01b03851690849062001437565b80519091501562000e0d57808060200190518101906200131391906200236d565b62000e0d5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000084565b60006200101f825490565b60006200105a838362001448565b60006200105a838362001475565b60006200105a838362001580565b600081815260028301602052604081205480151580620013d05750620013d0848462001295565b6200105a5760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000604482015260640162000084565b600081815260018301602052604081205415156200105a565b6060620010798484600085620015d2565b600082600001828154811062001462576200146262002095565b9060005260206000200154905092915050565b600081815260018301602052604081205480156200156e5760006200149c600183620021f3565b8554909150600090620014b290600190620021f3565b90508181146200151e576000866000018281548110620014d657620014d662002095565b9060005260206000200154905080876000018481548110620014fc57620014fc62002095565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200153257620015326200238b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200101f565b60009150506200101f565b5092915050565b6000818152600183016020526040812054620015c9575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200101f565b5060006200101f565b606082471015620016355760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000084565b600080866001600160a01b03168587604051620016539190620023c7565b60006040518083038185875af1925050503d806000811462001692576040519150601f19603f3d011682016040523d82523d6000602084013e62001697565b606091505b509092509050620016ab87838387620016b6565b979650505050505050565b606083156200172a57825160000362001722576001600160a01b0385163b620017225760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000084565b508162001079565b620010798383815115620017415781518083602001fd5b8060405162461bcd60e51b8152600401620000849190620023e5565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b03811182821017156200179857620017986200175d565b60405290565b60405161014081016001600160401b03811182821017156200179857620017986200175d565b604080519081016001600160401b03811182821017156200179857620017986200175d565b60405160a081016001600160401b03811182821017156200179857620017986200175d565b60405160c081016001600160401b03811182821017156200179857620017986200175d565b604051601f8201601f191681016001600160401b03811182821017156200185e576200185e6200175d565b604052919050565b6001600160a01b03811681146200187c57600080fd5b50565b80516200188c8162001866565b919050565b80516001600160401b03811681146200188c57600080fd5b600060e08284031215620018bc57600080fd5b620018c662001773565b90508151620018d58162001866565b8152620018e56020830162001891565b6020820152620018f86040830162001891565b60408201526200190b6060830162001891565b606082015260808201516001600160601b03811681146200192b57600080fd5b60808201526200193e60a083016200187f565b60a08201526200195160c083016200187f565b60c082015292915050565b805161ffff811681146200188c57600080fd5b805163ffffffff811681146200188c57600080fd5b600061014082840312156200199857600080fd5b620019a26200179e565b9050620019af826200187f565b8152620019bf602083016200195c565b6020820152620019d2604083016200196f565b6040820152620019e5606083016200195c565b6060820152620019f8608083016200196f565b608082015262001a0b60a083016200195c565b60a082015262001a1e60c083016200195c565b60c082015262001a3160e083016200187f565b60e082015261010062001a468184016200196f565b9082015261012062001a5a8382016200196f565b9082015292915050565b60006001600160401b0382111562001a805762001a806200175d565b5060051b60200190565b600082601f83011262001a9c57600080fd5b8151602062001ab562001aaf8362001a64565b62001833565b82815260069290921b8401810191818101908684111562001ad557600080fd5b8286015b8481101562001b2f576040818903121562001af45760008081fd5b62001afe620017c4565b815162001b0b8162001866565b81528185015162001b1c8162001866565b8186015283529183019160400162001ad9565b509695505050505050565b805180151581146200188c57600080fd5b80516001600160801b03811681146200188c57600080fd5b60006060828403121562001b7657600080fd5b604051606081016001600160401b038111828210171562001b9b5762001b9b6200175d565b60405290508062001bac8362001b3a565b815262001bbc6020840162001b4b565b602082015262001bcf6040840162001b4b565b60408201525092915050565b600082601f83011262001bed57600080fd5b8151602062001c0062001aaf8362001a64565b82815260a0928302850182019282820191908785111562001c2057600080fd5b8387015b8581101562001caf5781818a03121562001c3e5760008081fd5b62001c48620017e9565b815162001c558162001866565b815262001c648287016200196f565b86820152604062001c7781840162001891565b90820152606062001c8a83820162001891565b90820152608062001c9d83820162001b3a565b90820152845292840192810162001c24565b5090979650505050505050565b600082601f83011262001cce57600080fd5b8151602062001ce162001aaf8362001a64565b82815260c0928302850182019282820191908785111562001d0157600080fd5b8387015b8581101562001caf5781818a03121562001d1f5760008081fd5b62001d296200180e565b815162001d368162001866565b815262001d458287016200196f565b86820152604062001d588184016200196f565b90820152606062001d6b8382016200195c565b90820152608062001d7e8382016200196f565b9082015260a062001d918382016200196f565b90820152845292840192810162001d05565b600082601f83011262001db557600080fd5b8151602062001dc862001aaf8362001a64565b82815260069290921b8401810191818101908684111562001de857600080fd5b8286015b8481101562001b2f576040818903121562001e075760008081fd5b62001e11620017c4565b815162001e1e8162001866565b815262001e2d8286016200195c565b8186015283529183019160400162001dec565b6000806000806000806000610300888a03121562001e5d57600080fd5b62001e698989620018a9565b965062001e7a8960e08a0162001984565b6102208901519096506001600160401b038082111562001e9957600080fd5b62001ea78b838c0162001a8a565b965062001eb98b6102408c0162001b63565b95506102a08a015191508082111562001ed157600080fd5b62001edf8b838c0162001bdb565b94506102c08a015191508082111562001ef757600080fd5b62001f058b838c0162001cbc565b93506102e08a015191508082111562001f1d57600080fd5b5062001f2c8a828b0162001da3565b91505092959891949750929550565b80516001600160a01b03168252602081015162001f5e602084018261ffff169052565b50604081015162001f77604084018263ffffffff169052565b50606081015162001f8e606084018261ffff169052565b50608081015162001fa7608084018263ffffffff169052565b5060a081015162001fbe60a084018261ffff169052565b5060c081015162001fd560c084018261ffff169052565b5060e081015162001ff160e08401826001600160a01b03169052565b506101008181015163ffffffff908116918401919091526101209182015116910152565b82516001600160a01b0390811682526020808501516001600160401b0390811691840191909152604080860151821690840152606080860151909116908301526080808501516001600160601b03169083015260a08085015182169083015260c0808501519091169082015261022081016200105a60e083018462001f3b565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620020d657620020d6620020ab565b5060010190565b602080825282518282018190526000919060409081850190868401855b828110156200215f57815180516001600160a01b031685528681015163ffffffff1687860152858101516001600160401b03908116878701526060808301519091169086015260809081015115159085015260a09093019290850190600101620020fa565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b828110156200215f57815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a091820151169085015260c0909301929085019060010162002189565b818103818111156200101f576200101f620020ab565b6000816200221b576200221b620020ab565b506000190190565b63ffffffff818116838216019080821115620015795762001579620020ab565b6000604080830163ffffffff8616845260208281860152818651808452606087019150828801935060005b81811015620022a257845180516001600160a01b0316845284015161ffff168484015293830193918501916001016200226e565b509098975050505050505050565b600060208284031215620022c357600080fd5b81516200105a8162001866565b80820281158282048414176200101f576200101f620020ab565b6000826200230857634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b03828116828216039080821115620015795762001579620020ab565b6000602082840312156200234357600080fd5b5051919050565b8181036000831280158383131683831282161715620015795762001579620020ab565b6000602082840312156200238057600080fd5b6200105a8262001b3a565b634e487b7160e01b600052603160045260246000fd5b60005b83811015620023be578181015183820152602001620023a4565b50506000910152565b60008251620023db818460208701620023a1565b9190910192915050565b602081526000825180602084015262002406816040850160208701620023a1565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516101405161016051615f726200252860003960008181610334015281816116530152613dfb015260008181610305015281816114060152818161146e01528181611c3501528181611c9d0152613dcc0152600081816102710152818161097f01528181611790015281816120350152613d3801526000818161024101528181611d680152613d0801526000818161021201528181610fb4015281816119e001528181611ae1015281816123a301528181613090015281816132c60152613cd90152600081816102d101528181611bad0152613d980152600081816102a1015281816125d30152613d680152600061215e0152615f726000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806379ba5097116100f9578063d09dc33911610097578063eff7cc4811610071578063eff7cc481461092d578063f25561fd14610935578063f2fde38b14610948578063fbca3b741461095b57600080fd5b8063d09dc339146108ff578063df0aa9e914610907578063e687b40a1461091a57600080fd5b80638da5cb5b116100d35780638da5cb5b146107c05780639a113c36146107d1578063b06d41bc146108d6578063c92b2832146108ec57600080fd5b806379ba5097146107925780637ec757511461079a578063856c8247146107ad57600080fd5b8063546719cd11610166578063599f643111610140578063599f6431146105ec578063704b6c02146105fd5780637437ff9f1461061057806376f6ae761461077f57600080fd5b8063546719cd14610555578063549e946f146105b957806354b71468146105cc57600080fd5b806320487ded116101a257806320487ded146104d35780633a87ac53146104f45780634120fccd1461050957806348a98aa41461052a57600080fd5b806306285c69146101c95780631772047e1461037a578063181f5a771461048a575b600080fd5b6103646040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516103719190614ac2565b60405180910390f35b61043c610388366004614b63565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506001600160a01b03166000908152600e6020908152604091829020825160a081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000090920416608082015290565b6040516103719190815163ffffffff908116825260208084015182169083015260408084015161ffff1690830152606080840151821690830152608092830151169181019190915260a00190565b6104c66040518060400160405280601381526020017f45564d3245564d4f6e52616d7020312e322e300000000000000000000000000081525081565b6040516103719190614bd0565b6104e66104e1366004614c11565b61097b565b604051908152602001610371565b610507610502366004614e19565b610dfb565b005b610511610e11565b60405167ffffffffffffffff9091168152602001610371565b61053d610538366004614e73565b610e45565b6040516001600160a01b039091168152602001610371565b61055d610ea5565b604051610371919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6105076105c7366004614eac565b610f55565b6010546040516bffffffffffffffffffffffff9091168152602001610371565b6002546001600160a01b031661053d565b61050761060b366004614b63565b61110a565b6107726040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101919091525060408051610140810182526005546001600160a01b03808216835261ffff7401000000000000000000000000000000000000000083048116602085015263ffffffff76010000000000000000000000000000000000000000000084048116958501959095527a0100000000000000000000000000000000000000000000000000008304811660608501527c0100000000000000000000000000000000000000000000000000000000928390048516608085015260065480821660a086015262010000810490911660c0850152640100000000810490911660e08401527801000000000000000000000000000000000000000000000000810484166101008401520490911661012082015290565b6040516103719190614fa5565b61050761078d366004614fb4565b6111d4565b61050761128c565b6105076107a8366004615058565b61136f565b6105116107bb366004614b63565b6113d8565b6000546001600160a01b031661053d565b61088c6107df366004614b63565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b03166000908152600d60209081526040918290208251608081018452905463ffffffff8116825267ffffffffffffffff64010000000082048116938301939093526c0100000000000000000000000081049092169281019290925260ff74010000000000000000000000000000000000000000909104161515606082015290565b60408051825163ffffffff16815260208084015167ffffffffffffffff90811691830191909152838301511691810191909152606091820151151591810191909152608001610371565b6108de6114d9565b6040516103719291906151bb565b6105076108fa36600461520b565b6115dd565b6104e6611645565b6104e6610915366004615279565b61164f565b6105076109283660046152e5565b6121d3565b6105076121e4565b6105076109433660046153ad565b61247b565b610507610956366004614b63565b6124e1565b61096e6109693660046154a0565b6124f2565b60405161037191906154bd565b60007f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168367ffffffffffffffff16146109fb576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6000610a12610a0d608085018561550a565b6125a4565b519050610a3c610a25602085018561550a565b905082610a35604087018761556f565b9050612698565b6000600d81610a516080870160608801614b63565b6001600160a01b0316815260208082019290925260409081016000208151608081018352905463ffffffff81168252640100000000810467ffffffffffffffff908116948301949094526c010000000000000000000000008104909316918101919091527401000000000000000000000000000000000000000090910460ff16151560608201819052909150610b2f57610af16080850160608601614b63565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016109f2565b600654600090819064010000000090046001600160a01b031663ffdb4b37610b5d6080890160608a01614b63565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff8a1660248201526044016040805180830381865afa158015610bc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bec9190615603565b9092509050806000808080610c0460408c018c61556f565b90501115610c3e57610c32610c1f60808c0160608d01614b63565b87610c2d60408e018e61556f565b6127c1565b91945092509050610c5a565b8651610c579063ffffffff16662386f26fc10000615665565b92505b6040870151610c739067ffffffffffffffff1684615665565b60208881015160055492955060009267ffffffffffffffff9091169163ffffffff8616917a010000000000000000000000000000000000000000000000000000900461ffff1690610cc6908f018f61550a565b610cd1929150615665565b600554610cfe90760100000000000000000000000000000000000000000000900463ffffffff168d61567c565b610d08919061567c565b610d12919061567c565b610d1c9190615665565b610d36906dffffffffffffffffffffffffffff8716615665565b60065490915060009062010000900461ffff1615610daa576000607060ff16887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16901c9050610da6818e8060200190610d8c919061550a565b90508f8060400190610d9e919061556f565b905087612acb565b9150505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff881681610dd4848861567c565b610dde919061567c565b610de8919061568f565b9a50505050505050505050505b92915050565b610e03612b9b565b610e0d8282612c11565b5050565b601054600090610e4090700100000000000000000000000000000000900467ffffffffffffffff1660016156ca565b905090565b6000610e52600a83612f71565b610e93576040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024016109f2565b610e9e600a83612f86565b9392505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610e4090612f9b565b6000546001600160a01b03163314801590610f7b57506002546001600160a01b03163314155b15610fb2576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480610ff957506001600160a01b038116155b15611030576040517f232cb97f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061103a61304d565b1215611072576040517f02075e0000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610e0d9082906001600160a01b038516906370a0823190602401602060405180830381865afa1580156110d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f991906156eb565b6001600160a01b038516919061310d565b6000546001600160a01b0316331480159061113057506002546001600160a01b03163314155b15611167576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b6000546001600160a01b031633148015906111fa57506002546001600160a01b03163314155b15611231576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e0d8282808060200260200160405190810160405280939291908181526020016000905b828210156112825761127360408302860136819003810190615704565b81526020019060010190611256565b505050505061318d565b6001546001600160a01b03163314611300576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016109f2565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000546001600160a01b0316331480159061139557506002546001600160a01b03163314155b156113cc576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113d581613400565b50565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168015801561143157507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15610df5576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa1580156114b5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9e9190615743565b60606000806114e860076135c6565b90508067ffffffffffffffff81111561150357611503614c61565b60405190808252806020026020018201604052801561154857816020015b60408051808201909152600080825260208201528152602001906001900390816115215790505b50925060005b818110156115ba576000806115646007846135d1565b915091506040518060400160405280836001600160a01b031681526020018261ffff1681525086848151811061159c5761159c615760565b60200260200101819052505050806115b39061578f565b905061154e565b505060105491926c0100000000000000000000000090920463ffffffff16919050565b6000546001600160a01b0316331480159061160357506002546001600160a01b03163314155b1561163a576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113d56003826135ef565b6000610e4061304d565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d391906157c7565b1561170a576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03821661174a576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b0316331461178e576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168567ffffffffffffffff1614611807576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016109f2565b611811848061550a565b905060201461185857611824848061550a565b6040517f370d875f0000000000000000000000000000000000000000000000000000000081526004016109f292919061580f565b6000611864858061550a565b8101906118719190615823565b90506001600160a01b038111806118885750600a81105b1561189757611824858061550a565b60006118a9610a0d608088018861550a565b51905060006118bb604088018861556f565b91506118d890506118cf602089018961550a565b90508383612698565b80156119d65760005b81811015611959576118f6604089018961556f565b8281811061190657611906615760565b90506040020160200135600003611949576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119528161578f565b90506118e1565b506119d661196a604089018961556f565b808060200260200160405190810160405280939291908181526020016000905b828210156119b6576119a76040830286013681900381019061583c565b8152602001906001019061198a565b505060065464010000000090046001600160a01b031692506137c7915050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016611a106080890160608a01614b63565b6001600160a01b031603611a745760108054879190600090611a419084906bffffffffffffffffffffffff16615876565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550611b9b565b60065464010000000090046001600160a01b03166241e5be611a9c60808a0160608b01614b63565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018a90527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa158015611b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4c91906156eb565b60108054600090611b6c9084906bffffffffffffffffffffffff16615876565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b6010546bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811691161115611c08576040517fe5c7a49100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0385166000908152600f602052604090205467ffffffffffffffff16158015611c6057507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15611d58576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d089190615743565b6001600160a01b0386166000908152600f6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790555b6000604051806101a001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168152602001876001600160a01b03168152602001856001600160a01b0316815260200160108081819054906101000a900467ffffffffffffffff16611dd59061589b565b825467ffffffffffffffff9182166101009390930a838102908302199091161790925582526020808301879052600060408085018290526001600160a01b038c168252600f90925290812080546060909401939092611e34911661589b565b825467ffffffffffffffff9182166101009390930a83810292021916179091558152602001611e6960808b0160608c01614b63565b6001600160a01b03168152602001888152602001898060200190611e8d919061550a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001611ed460408b018b61556f565b808060200260200160405190810160405280939291908181526020016000905b82821015611f2057611f116040830286013681900381019061583c565b81526020019060010190611ef4565b505050505081526020018367ffffffffffffffff811115611f4357611f43614c61565b604051908082528060200260200182016040528015611f7657816020015b6060815260200190600190039081611f615790505b508152600060209091018190529091505b82811015612157576000611f9e60408b018b61556f565b83818110611fae57611fae615760565b905060400201803603810190611fc4919061583c565b90506000611fd68c8360000151610e45565b6001600160a01b031663968754458a611fef8e8061550a565b60208088015160408051928301815260008352517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b16815261205d959493927f0000000000000000000000000000000000000000000000000000000000000000916004016158c2565b6000604051808303816000875af115801561207c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120a4919081019061591a565b82516001600160a01b03166000908152600e602052604090205481519192506e010000000000000000000000000000900463ffffffff1610156121215781516040517f36f536ca0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016109f2565b80846101600151848151811061213957612139615760565b60200260200101819052505050806121509061578f565b9050611f87565b50612182817f0000000000000000000000000000000000000000000000000000000000000000613982565b6101808201526040517fd0c3c799bf9e2639de44391e7f524d229b2b55f5b1ea94b2bf7da42f7243dddd906121b8908390615a47565b60405180910390a1610180015193505050505b949350505050565b6121db612b9b565b6113d581613add565b6000546001600160a01b0316331480159061220a57506002546001600160a01b03163314155b801561221e575061221c600733613e35565b155b15612255576040517f195db95800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546c01000000000000000000000000900463ffffffff1660008190036122a9576040517f990e30bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546bffffffffffffffffffffffff16818110156122f4576040517f8d0f71d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122fe61304d565b1215612336576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600061234360076135c6565b905060005b818110156124385760008061235e6007846135d1565b909250905060008761237e836bffffffffffffffffffffffff8a16615665565b612388919061568f565b90506123948187615b7c565b95506123d86001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846bffffffffffffffffffffffff841661310d565b6040516bffffffffffffffffffffffff821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a2505050806124319061578f565b9050612348565b5050601080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff929092169190911790555050565b6000546001600160a01b031633148015906124a157506002546001600160a01b03163314155b156124d8576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113d581613e4a565b6124e9612b9b565b6113d581613fd5565b60606000612500600a6140b0565b67ffffffffffffffff81111561251857612518614c61565b604051908082528060200260200182016040528015612541578160200160208202803683370190505b50905060005b815181101561259d5761255b600a826140bb565b5082828151811061256e5761256e615760565b60200260200101816001600160a01b03166001600160a01b031681525050806125969061578f565b9050612547565b5092915050565b60408051602081019091526000815260008290036125fa5750604080516020810190915267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152610df5565b7f97a657c9000000000000000000000000000000000000000000000000000000006126258385615ba1565b7fffffffff00000000000000000000000000000000000000000000000000000000161461267e576040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61268b8260048186615be9565b810190610e9e9190615c13565b6006547801000000000000000000000000000000000000000000000000900463ffffffff1680841115612701576040517f8693378900000000000000000000000000000000000000000000000000000000815260048101829052602481018590526044016109f2565b6006547c0100000000000000000000000000000000000000000000000000000000900463ffffffff16831115612763576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055474010000000000000000000000000000000000000000900461ffff168211156127bb576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6000808083815b81811015612abf5760008787838181106127e4576127e4615760565b9050604002018036038101906127fa919061583c565b80516001600160a01b03166000908152600e6020908152604091829020825160a081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e010000000000000000000000000000909204811660808301528251929350909161289791600a9190612f7116565b6128db5781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016109f2565b604081015160009061ffff16156129ff5760008c6001600160a01b031684600001516001600160a01b0316146129a25760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526401000000009092041690634ab35b0b90602401602060405180830381865afa158015612977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299b9190615c55565b90506129a5565b508a5b620186a0836040015161ffff166129e78660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166140ca90919063ffffffff16565b6129f19190615665565b6129fb919061568f565b9150505b6060820151612a0e9088615c70565b9650816080015186612a209190615c70565b8251909650600090612a3f9063ffffffff16662386f26fc10000615665565b905080821015612a5e57612a53818a61567c565b985050505050612aaf565b6000836020015163ffffffff16662386f26fc10000612a7d9190615665565b905080831115612a9d57612a91818b61567c565b99505050505050612aaf565b612aa7838b61567c565b995050505050505b612ab88161578f565b90506127c8565b50509450945094915050565b60008063ffffffff8316612ae0608086615665565b612aec8761022061567c565b612af6919061567c565b612b00919061567c565b6005546006549192506000917c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690612b429061ffff1684615665565b612b4c919061567c565b60065490915062010000900461ffff16612b766dffffffffffffffffffffffffffff891683615665565b612b809190615665565b612b9090655af3107a4000615665565b979650505050505050565b6000546001600160a01b03163314612c0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016109f2565b565b60005b8251811015612d72576000838281518110612c3157612c31615760565b60200260200101516000015190506000848381518110612c5357612c53615760565b6020026020010151602001519050612c7582600a612f7190919063ffffffff16565b612cb6576040517f73913ebd0000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024016109f2565b6001600160a01b038116612ccb600a84612f86565b6001600160a01b031614612d0b576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612d16600a83614107565b15612d5f57604080516001600160a01b038085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a15b505080612d6b9061578f565b9050612c14565b5060005b8151811015612f6c576000828281518110612d9357612d93615760565b60200260200101516000015190506000838381518110612db557612db5615760565b602002602001015160200151905060006001600160a01b0316826001600160a01b03161480612deb57506001600160a01b038116155b15612e22576040517f6c2a418000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e849190615c8d565b6001600160a01b0316826001600160a01b031614612ece576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612eda600a838361411c565b15612f2757604080516001600160a01b038085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a1612f59565b6040517f3caf458500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505080612f659061578f565b9050612d76565b505050565b6000610e9e836001600160a01b038416614132565b6000610e9e836001600160a01b03841661413e565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261302982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261300d9190615caa565b85608001516fffffffffffffffffffffffffffffffff1661414a565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6010546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916bffffffffffffffffffffffff16907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156130df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310391906156eb565b610e409190615cbd565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052612f6c908490614172565b805160408111156131ca576040517fb5a10cfa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546c01000000000000000000000000900463ffffffff1615801590613218575060105463ffffffff6c010000000000000000000000008204166bffffffffffffffffffffffff90911610155b15613225576132256121e4565b600061323160076135c6565b90505b801561327357600061325261324a600184615caa565b6007906135d1565b509050613260600782614271565b50508061326c90615cdd565b9050613234565b506000805b8281101561338157600084828151811061329457613294615760565b602002602001015160000151905060008583815181106132b6576132b6615760565b60200260200101516020015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316148061330b57506001600160a01b038216155b1561334d576040517f4de938d10000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024016109f2565b61335d60078361ffff8416614286565b5061336c61ffff821685615c70565b935050508061337a9061578f565b9050613278565b50601080547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd24906133f39083908690615d12565b60405180910390a1505050565b60005b815181101561359657600082828151811061342057613420615760565b6020908102919091018101516040805160a080820183528385015163ffffffff908116835283850151811683870190815260608087015161ffff9081168688019081526080808a0151861693880193845295890151851695870195865297516001600160a01b03166000908152600e9099529590972093518454915196519751935183166e010000000000000000000000000000027fffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff9484166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff999097166801000000000000000002989098167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff978416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909316919093161717949094169390931791909117919091169190911790555061358f8161578f565b9050613403565b507f555c74101f7a15746d31c6731170310e667bcc607996b2fc0b981a7b26a416e9816040516111c99190615d31565b6000610df58261429c565b60008080806135e086866142a7565b909450925050505b9250929050565b815460009061361890700100000000000000000000000000000000900463ffffffff1642615caa565b905080156136ba5760018301548354613660916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661414a565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546136e0916fffffffffffffffffffffffffffffffff90811691166142d2565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906133f39084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b81516000805b82811015613974576000846001600160a01b031663d02641a08784815181106137f8576137f8615760565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b0390911660048201526024016040805180830381865afa15801561385f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138839190615db6565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613908578582815181106138be576138be615760565b6020908102919091010151516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016109f2565b61395686838151811061391d5761391d615760565b602002602001015160200151827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166140ca90919063ffffffff16565b613960908461567c565b9250508061396d9061578f565b90506137cd565b506127bb60038260006142e8565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001613a189897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001613a519190615de9565b60405160208183030381529060405280519060200120876101600151604051602001613a7d9190615dfc565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b60e08101516001600160a01b0316613b21576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055509050507f2a57f7c2027cf032c78b77d4d8d2fbd20ad22e5d5e5b5fb23ac7d7820d44adc66040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250826040516111c9929190615e0f565b6000610e9e836001600160a01b038416614637565b60005b8151811015613fa5576000828281518110613e6a57613e6a615760565b60209081029190910181015160408051608080820183528385015163ffffffff90811683528385015167ffffffffffffffff908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600d9098529490962092518354945192519551151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9688166c0100000000000000000000000002969096167fffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090951691161792909217919091169290921717905550613f9e8161578f565b9050613e4d565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e816040516111c99190615e99565b336001600160a01b03821603614047576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016109f2565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000610df5826135c6565b60008080806135e086866135d1565b6000670de0b6b3a76400006140fd837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616615665565b610e9e919061568f565b6000610e9e836001600160a01b038416614643565b60006121cb846001600160a01b0385168461464f565b6000610e9e8383614637565b6000610e9e8383614665565b60006141698561415a8486615665565b614164908761567c565b6142d2565b95945050505050565b60006141c7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166146ef9092919063ffffffff16565b805190915015612f6c57808060200190518101906141e591906157c7565b612f6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016109f2565b6000610e9e836001600160a01b0384166146fe565b60006121cb846001600160a01b0385168461471b565b6000610df582614738565b600080806142b58585614742565b600081815260029690960160205260409095205494959350505050565b60008183106142e15781610e9e565b5090919050565b825474010000000000000000000000000000000000000000900460ff16158061430f575081155b1561431957505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061435f90700100000000000000000000000000000000900463ffffffff1642615caa565b9050801561441f57818311156143a1576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546143db9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661414a565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156144bc576001600160a01b038416614471576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016109f2565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b03851660448201526064016109f2565b848310156145b55760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906145009082615caa565b61450a878a615caa565b614514919061567c565b61451e919061568f565b90506001600160a01b03861661456a576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016109f2565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b03871660448201526064016109f2565b6145bf8584615caa565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610e9e838361474e565b6000610e9e83836146fe565b60006121cb84846001600160a01b03851661471b565b60008181526002830160205260408120548015158061468957506146898484614637565b610e9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b6579000060448201526064016109f2565b60606121cb8484600085614766565b60008181526002830160205260408120819055610e9e8383614867565b600082815260028401602052604081208290556121cb8484614873565b6000610df5825490565b6000610e9e838361487f565b60008181526001830160205260408120541515610e9e565b6060824710156147f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016109f2565b600080866001600160a01b031685876040516148149190615f1a565b60006040518083038185875af1925050503d8060008114614851576040519150601f19603f3d011682016040523d82523d6000602084013e614856565b606091505b5091509150612b90878383876148a9565b6000610e9e838361493c565b6000610e9e8383614a2f565b600082600001828154811061489657614896615760565b9060005260206000200154905092915050565b6060831561493257825160000361492b576001600160a01b0385163b61492b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109f2565b50816121cb565b6121cb8383614a7e565b60008181526001830160205260408120548015614a25576000614960600183615caa565b855490915060009061497490600190615caa565b90508181146149d957600086600001828154811061499457614994615760565b90600052602060002001549050808760000184815481106149b7576149b7615760565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806149ea576149ea615f36565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610df5565b6000915050610df5565b6000818152600183016020526040812054614a7657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610df5565b506000610df5565b815115614a8e5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f29190614bd0565b60e08101610df582846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b6001600160a01b03811681146113d557600080fd5b8035614b5e81614b3e565b919050565b600060208284031215614b7557600080fd5b8135610e9e81614b3e565b60005b83811015614b9b578181015183820152602001614b83565b50506000910152565b60008151808452614bbc816020860160208601614b80565b601f01601f19169290920160200192915050565b602081526000610e9e6020830184614ba4565b67ffffffffffffffff811681146113d557600080fd5b600060a08284031215614c0b57600080fd5b50919050565b60008060408385031215614c2457600080fd5b8235614c2f81614be3565b9150602083013567ffffffffffffffff811115614c4b57600080fd5b614c5785828601614bf9565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715614cb357614cb3614c61565b60405290565b60405160c0810167ffffffffffffffff81118282101715614cb357614cb3614c61565b604051610140810167ffffffffffffffff81118282101715614cb357614cb3614c61565b60405160a0810167ffffffffffffffff81118282101715614cb357614cb3614c61565b604051601f8201601f1916810167ffffffffffffffff81118282101715614d4c57614d4c614c61565b604052919050565b600067ffffffffffffffff821115614d6e57614d6e614c61565b5060051b60200190565b600082601f830112614d8957600080fd5b81356020614d9e614d9983614d54565b614d23565b82815260069290921b84018101918181019086841115614dbd57600080fd5b8286015b84811015614e0e5760408189031215614dda5760008081fd5b614de2614c90565b8135614ded81614b3e565b815281850135614dfc81614b3e565b81860152835291830191604001614dc1565b509695505050505050565b60008060408385031215614e2c57600080fd5b823567ffffffffffffffff80821115614e4457600080fd5b614e5086838701614d78565b93506020850135915080821115614e6657600080fd5b50614c5785828601614d78565b60008060408385031215614e8657600080fd5b8235614e9181614be3565b91506020830135614ea181614b3e565b809150509250929050565b60008060408385031215614ebf57600080fd5b8235614e9181614b3e565b80516001600160a01b031682526020810151614eec602084018261ffff169052565b506040810151614f04604084018263ffffffff169052565b506060810151614f1a606084018261ffff169052565b506080810151614f32608084018263ffffffff169052565b5060a0810151614f4860a084018261ffff169052565b5060c0810151614f5e60c084018261ffff169052565b5060e0810151614f7960e08401826001600160a01b03169052565b506101008181015163ffffffff81168483015250506101208181015163ffffffff8116848301526127bb565b6101408101610df58284614eca565b60008060208385031215614fc757600080fd5b823567ffffffffffffffff80821115614fdf57600080fd5b818501915085601f830112614ff357600080fd5b81358181111561500257600080fd5b8660208260061b850101111561501757600080fd5b60209290920196919550909350505050565b63ffffffff811681146113d557600080fd5b8035614b5e81615029565b803561ffff81168114614b5e57600080fd5b6000602080838503121561506b57600080fd5b823567ffffffffffffffff81111561508257600080fd5b8301601f8101851361509357600080fd5b80356150a1614d9982614d54565b81815260c091820283018401918482019190888411156150c057600080fd5b938501935b8385101561515c5780858a0312156150dd5760008081fd5b6150e5614cb9565b85356150f081614b3e565b8152858701356150ff81615029565b8188015260408681013561511281615029565b908201526060615123878201615046565b9082015260808681013561513681615029565b9082015260a08681013561514981615029565b90820152835293840193918501916150c5565b50979650505050505050565b600081518084526020808501945080840160005b838110156151b057815180516001600160a01b0316885283015161ffff16838801526040909601959082019060010161517c565b509495945050505050565b6040815260006151ce6040830185615168565b90508260208301529392505050565b80151581146113d557600080fd5b80356fffffffffffffffffffffffffffffffff81168114614b5e57600080fd5b60006060828403121561521d57600080fd5b6040516060810181811067ffffffffffffffff8211171561524057615240614c61565b604052823561524e816151dd565b815261525c602084016151eb565b602082015261526d604084016151eb565b60408201529392505050565b6000806000806080858703121561528f57600080fd5b843561529a81614be3565b9350602085013567ffffffffffffffff8111156152b657600080fd5b6152c287828801614bf9565b9350506040850135915060608501356152da81614b3e565b939692955090935050565b600061014082840312156152f857600080fd5b615300614cdc565b61530983614b53565b815261531760208401615046565b60208201526153286040840161503b565b604082015261533960608401615046565b606082015261534a6080840161503b565b608082015261535b60a08401615046565b60a082015261536c60c08401615046565b60c082015261537d60e08401614b53565b60e082015261010061539081850161503b565b908201526101206153a284820161503b565b908201529392505050565b600060208083850312156153c057600080fd5b823567ffffffffffffffff8111156153d757600080fd5b8301601f810185136153e857600080fd5b80356153f6614d9982614d54565b81815260a0918202830184019184820191908884111561541557600080fd5b938501935b8385101561515c5780858a0312156154325760008081fd5b61543a614d00565b853561544581614b3e565b81528587013561545481615029565b8188015260408681013561546781614be3565b9082015260608681013561547a81614be3565b9082015260808681013561548d816151dd565b908201528352938401939185019161541a565b6000602082840312156154b257600080fd5b8135610e9e81614be3565b6020808252825182820181905260009190848201906040850190845b818110156154fe5783516001600160a01b0316835292840192918401916001016154d9565b50909695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261553f57600080fd5b83018035915067ffffffffffffffff82111561555a57600080fd5b6020019150368190038213156135e857600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155a457600080fd5b83018035915067ffffffffffffffff8211156155bf57600080fd5b6020019150600681901b36038213156135e857600080fd5b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114614b5e57600080fd5b6000806040838503121561561657600080fd5b61561f836155d7565b915061562d602084016155d7565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610df557610df5615636565b80820180821115610df557610df5615636565b6000826156c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b67ffffffffffffffff81811683821601908082111561259d5761259d615636565b6000602082840312156156fd57600080fd5b5051919050565b60006040828403121561571657600080fd5b61571e614c90565b823561572981614b3e565b815261573760208401615046565b60208201529392505050565b60006020828403121561575557600080fd5b8151610e9e81614be3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036157c0576157c0615636565b5060010190565b6000602082840312156157d957600080fd5b8151610e9e816151dd565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6020815260006121cb6020830184866157e4565b60006020828403121561583557600080fd5b5035919050565b60006040828403121561584e57600080fd5b615856614c90565b823561586181614b3e565b81526020928301359281019290925250919050565b6bffffffffffffffffffffffff81811683821601908082111561259d5761259d615636565b600067ffffffffffffffff8083168181036158b8576158b8615636565b6001019392505050565b6001600160a01b038716815260a0602082015260006158e560a0830187896157e4565b85604084015267ffffffffffffffff85166060840152828103608084015261590d8185614ba4565b9998505050505050505050565b60006020828403121561592c57600080fd5b815167ffffffffffffffff8082111561594457600080fd5b818401915084601f83011261595857600080fd5b81518181111561596a5761596a614c61565b61597d6020601f19601f84011601614d23565b915080825285602082850101111561599457600080fd5b6159a5816020840160208601614b80565b50949350505050565b600081518084526020808501945080840160005b838110156151b057815180516001600160a01b0316885283015183880152604090960195908201906001016159c2565b600081518084526020808501808196508360051b8101915082860160005b85811015615a3a578284038952615a28848351614ba4565b98850198935090840190600101615a10565b5091979650505050505050565b60208152615a6260208201835167ffffffffffffffff169052565b60006020830151615a7e60408401826001600160a01b03169052565b5060408301516001600160a01b038116606084015250606083015167ffffffffffffffff8116608084015250608083015160a083015260a0830151615ac760c084018215159052565b5060c083015167ffffffffffffffff811660e08401525060e0830151610100615afa818501836001600160a01b03169052565b840151610120848101919091528401516101a061014080860182905291925090615b286101c0860184614ba4565b9250808601519050601f19610160818786030181880152615b4985846159ae565b945080880151925050610180818786030181880152615b6885846159f2565b970151959092019490945250929392505050565b6bffffffffffffffffffffffff82811682821603908082111561259d5761259d615636565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015615be15780818660040360031b1b83161692505b505092915050565b60008085851115615bf957600080fd5b83861115615c0657600080fd5b5050820193919092039150565b600060208284031215615c2557600080fd5b6040516020810181811067ffffffffffffffff82111715615c4857615c48614c61565b6040529135825250919050565b600060208284031215615c6757600080fd5b610e9e826155d7565b63ffffffff81811683821601908082111561259d5761259d615636565b600060208284031215615c9f57600080fd5b8151610e9e81614b3e565b81810381811115610df557610df5615636565b818103600083128015838313168383128216171561259d5761259d615636565b600081615cec57615cec615636565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b63ffffffff831681526040602082015260006121cb6040830184615168565b602080825282518282018190526000919060409081850190868401855b82811015615a3a57815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a091820151169085015260c09093019290850190600101615d4e565b600060408284031215615dc857600080fd5b615dd0614c90565b615dd9836155d7565b8152602083015161573781615029565b602081526000610e9e60208301846159ae565b602081526000610e9e60208301846159f2565b6102208101615e8c82856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b610e9e60e0830184614eca565b602080825282518282018190526000919060409081850190868401855b82811015615a3a57815180516001600160a01b031685528681015163ffffffff16878601528581015167ffffffffffffffff908116878701526060808301519091169086015260809081015115159085015260a09093019290850190600101615eb6565b60008251615f2c818460208701614b80565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", +} + +var EVM2EVMOnRampABI = EVM2EVMOnRampMetaData.ABI + +var EVM2EVMOnRampBin = EVM2EVMOnRampMetaData.Bin + +func DeployEVM2EVMOnRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMOnRampStaticConfig, dynamicConfig EVM2EVMOnRampDynamicConfig, tokensAndPools []InternalPoolUpdate, rateLimiterConfig RateLimiterConfig, feeTokenConfigs []EVM2EVMOnRampFeeTokenConfigArgs, tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs, nopsAndWeights []EVM2EVMOnRampNopAndWeight) (common.Address, *types.Transaction, *EVM2EVMOnRamp, error) { + parsed, err := EVM2EVMOnRampMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMOnRampBin), backend, staticConfig, dynamicConfig, tokensAndPools, rateLimiterConfig, feeTokenConfigs, tokenTransferFeeConfigArgs, nopsAndWeights) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EVM2EVMOnRamp{EVM2EVMOnRampCaller: EVM2EVMOnRampCaller{contract: contract}, EVM2EVMOnRampTransactor: EVM2EVMOnRampTransactor{contract: contract}, EVM2EVMOnRampFilterer: EVM2EVMOnRampFilterer{contract: contract}}, nil +} + +type EVM2EVMOnRamp struct { + address common.Address + abi abi.ABI + EVM2EVMOnRampCaller + EVM2EVMOnRampTransactor + EVM2EVMOnRampFilterer +} + +type EVM2EVMOnRampCaller struct { + contract *bind.BoundContract +} + +type EVM2EVMOnRampTransactor struct { + contract *bind.BoundContract +} + +type EVM2EVMOnRampFilterer struct { + contract *bind.BoundContract +} + +type EVM2EVMOnRampSession struct { + Contract *EVM2EVMOnRamp + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type EVM2EVMOnRampCallerSession struct { + Contract *EVM2EVMOnRampCaller + CallOpts bind.CallOpts +} + +type EVM2EVMOnRampTransactorSession struct { + Contract *EVM2EVMOnRampTransactor + TransactOpts bind.TransactOpts +} + +type EVM2EVMOnRampRaw struct { + Contract *EVM2EVMOnRamp +} + +type EVM2EVMOnRampCallerRaw struct { + Contract *EVM2EVMOnRampCaller +} + +type EVM2EVMOnRampTransactorRaw struct { + Contract *EVM2EVMOnRampTransactor +} + +func NewEVM2EVMOnRamp(address common.Address, backend bind.ContractBackend) (*EVM2EVMOnRamp, error) { + abi, err := abi.JSON(strings.NewReader(EVM2EVMOnRampABI)) + if err != nil { + return nil, err + } + contract, err := bindEVM2EVMOnRamp(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &EVM2EVMOnRamp{address: address, abi: abi, EVM2EVMOnRampCaller: EVM2EVMOnRampCaller{contract: contract}, EVM2EVMOnRampTransactor: EVM2EVMOnRampTransactor{contract: contract}, EVM2EVMOnRampFilterer: EVM2EVMOnRampFilterer{contract: contract}}, nil +} + +func NewEVM2EVMOnRampCaller(address common.Address, caller bind.ContractCaller) (*EVM2EVMOnRampCaller, error) { + contract, err := bindEVM2EVMOnRamp(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampCaller{contract: contract}, nil +} + +func NewEVM2EVMOnRampTransactor(address common.Address, transactor bind.ContractTransactor) (*EVM2EVMOnRampTransactor, error) { + contract, err := bindEVM2EVMOnRamp(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampTransactor{contract: contract}, nil +} + +func NewEVM2EVMOnRampFilterer(address common.Address, filterer bind.ContractFilterer) (*EVM2EVMOnRampFilterer, error) { + contract, err := bindEVM2EVMOnRamp(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampFilterer{contract: contract}, nil +} + +func bindEVM2EVMOnRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EVM2EVMOnRampMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOnRamp.Contract.EVM2EVMOnRampCaller.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.EVM2EVMOnRampTransactor.contract.Transfer(opts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.EVM2EVMOnRampTransactor.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EVM2EVMOnRamp.Contract.contract.Call(opts, result, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.contract.Transfer(opts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.contract.Transact(opts, method, params...) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "currentRateLimiterState") + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOnRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) CurrentRateLimiterState() (RateLimiterTokenBucket, error) { + return _EVM2EVMOnRamp.Contract.CurrentRateLimiterState(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOnRampDynamicConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(EVM2EVMOnRampDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampDynamicConfig)).(*EVM2EVMOnRampDynamicConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetDynamicConfig() (EVM2EVMOnRampDynamicConfig, error) { + return _EVM2EVMOnRamp.Contract.GetDynamicConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetDynamicConfig() (EVM2EVMOnRampDynamicConfig, error) { + return _EVM2EVMOnRamp.Contract.GetDynamicConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getExpectedNextSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetExpectedNextSequenceNumber(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetExpectedNextSequenceNumber(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getFee", destChainSelector, message) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetFee(&_EVM2EVMOnRamp.CallOpts, destChainSelector, message) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetFee(&_EVM2EVMOnRamp.CallOpts, destChainSelector, message) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetFeeTokenConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getFeeTokenConfig", token) + + if err != nil { + return *new(EVM2EVMOnRampFeeTokenConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampFeeTokenConfig)).(*EVM2EVMOnRampFeeTokenConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetFeeTokenConfig(token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) { + return _EVM2EVMOnRamp.Contract.GetFeeTokenConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetFeeTokenConfig(token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) { + return _EVM2EVMOnRamp.Contract.GetFeeTokenConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetNopFeesJuels(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getNopFeesJuels") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetNopFeesJuels() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetNopFeesJuels(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetNopFeesJuels() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.GetNopFeesJuels(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetNops(opts *bind.CallOpts) (GetNops, + + error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getNops") + + outstruct := new(GetNops) + if err != nil { + return *outstruct, err + } + + outstruct.NopsAndWeights = *abi.ConvertType(out[0], new([]EVM2EVMOnRampNopAndWeight)).(*[]EVM2EVMOnRampNopAndWeight) + outstruct.WeightsTotal = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetNops() (GetNops, + + error) { + return _EVM2EVMOnRamp.Contract.GetNops(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetNops() (GetNops, + + error) { + return _EVM2EVMOnRamp.Contract.GetNops(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetPoolBySourceToken(opts *bind.CallOpts, arg0 uint64, sourceToken common.Address) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getPoolBySourceToken", arg0, sourceToken) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetPoolBySourceToken(arg0 uint64, sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMOnRamp.CallOpts, arg0, sourceToken) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetPoolBySourceToken(arg0 uint64, sourceToken common.Address) (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMOnRamp.CallOpts, arg0, sourceToken) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getSenderNonce", sender) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetSenderNonce(&_EVM2EVMOnRamp.CallOpts, sender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetSenderNonce(sender common.Address) (uint64, error) { + return _EVM2EVMOnRamp.Contract.GetSenderNonce(&_EVM2EVMOnRamp.CallOpts, sender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOnRampStaticConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(EVM2EVMOnRampStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampStaticConfig)).(*EVM2EVMOnRampStaticConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetStaticConfig() (EVM2EVMOnRampStaticConfig, error) { + return _EVM2EVMOnRamp.Contract.GetStaticConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetStaticConfig() (EVM2EVMOnRampStaticConfig, error) { + return _EVM2EVMOnRamp.Contract.GetStaticConfig(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetSupportedTokens(opts *bind.CallOpts, arg0 uint64) ([]common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getSupportedTokens", arg0) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetSupportedTokens(arg0 uint64) ([]common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetSupportedTokens(&_EVM2EVMOnRamp.CallOpts, arg0) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetSupportedTokens(arg0 uint64) ([]common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetSupportedTokens(&_EVM2EVMOnRamp.CallOpts, arg0) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getTokenLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetTokenLimitAdmin() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.GetTokenLimitAdmin(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) GetTokenTransferFeeConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "getTokenTransferFeeConfig", token) + + if err != nil { + return *new(EVM2EVMOnRampTokenTransferFeeConfig), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMOnRampTokenTransferFeeConfig)).(*EVM2EVMOnRampTokenTransferFeeConfig) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) GetTokenTransferFeeConfig(token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) { + return _EVM2EVMOnRamp.Contract.GetTokenTransferFeeConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) GetTokenTransferFeeConfig(token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) { + return _EVM2EVMOnRamp.Contract.GetTokenTransferFeeConfig(&_EVM2EVMOnRamp.CallOpts, token) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "linkAvailableForPayment") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) LinkAvailableForPayment() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.LinkAvailableForPayment(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) LinkAvailableForPayment() (*big.Int, error) { + return _EVM2EVMOnRamp.Contract.LinkAvailableForPayment(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) Owner() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.Owner(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) Owner() (common.Address, error) { + return _EVM2EVMOnRamp.Contract.Owner(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _EVM2EVMOnRamp.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) TypeAndVersion() (string, error) { + return _EVM2EVMOnRamp.Contract.TypeAndVersion(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampCallerSession) TypeAndVersion() (string, error) { + return _EVM2EVMOnRamp.Contract.TypeAndVersion(&_EVM2EVMOnRamp.CallOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "acceptOwnership") +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.AcceptOwnership(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.AcceptOwnership(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) ApplyPoolUpdates(opts *bind.TransactOpts, removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "applyPoolUpdates", removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) ApplyPoolUpdates(removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ApplyPoolUpdates(&_EVM2EVMOnRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) ApplyPoolUpdates(removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ApplyPoolUpdates(&_EVM2EVMOnRamp.TransactOpts, removes, adds) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "forwardFromRouter", destChainSelector, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) ForwardFromRouter(destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ForwardFromRouter(&_EVM2EVMOnRamp.TransactOpts, destChainSelector, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) ForwardFromRouter(destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.ForwardFromRouter(&_EVM2EVMOnRamp.TransactOpts, destChainSelector, message, feeTokenAmount, originalSender) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) PayNops(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "payNops") +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) PayNops() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.PayNops(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) PayNops() (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.PayNops(&_EVM2EVMOnRamp.TransactOpts) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setAdmin", newAdmin) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetAdmin(&_EVM2EVMOnRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetAdmin(newAdmin common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetAdmin(&_EVM2EVMOnRamp.TransactOpts, newAdmin) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setDynamicConfig", dynamicConfig) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetDynamicConfig(dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetDynamicConfig(&_EVM2EVMOnRamp.TransactOpts, dynamicConfig) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetDynamicConfig(dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetDynamicConfig(&_EVM2EVMOnRamp.TransactOpts, dynamicConfig) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetFeeTokenConfig(opts *bind.TransactOpts, feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setFeeTokenConfig", feeTokenConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetFeeTokenConfig(feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetFeeTokenConfig(&_EVM2EVMOnRamp.TransactOpts, feeTokenConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetFeeTokenConfig(feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetFeeTokenConfig(&_EVM2EVMOnRamp.TransactOpts, feeTokenConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetNops(opts *bind.TransactOpts, nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setNops", nopsAndWeights) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetNops(nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetNops(&_EVM2EVMOnRamp.TransactOpts, nopsAndWeights) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetNops(nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetNops(&_EVM2EVMOnRamp.TransactOpts, nopsAndWeights) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setRateLimiterConfig", config) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOnRamp.TransactOpts, config) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetRateLimiterConfig(config RateLimiterConfig) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetRateLimiterConfig(&_EVM2EVMOnRamp.TransactOpts, config) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) SetTokenTransferFeeConfig(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "setTokenTransferFeeConfig", tokenTransferFeeConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) SetTokenTransferFeeConfig(tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetTokenTransferFeeConfig(&_EVM2EVMOnRamp.TransactOpts, tokenTransferFeeConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) SetTokenTransferFeeConfig(tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.SetTokenTransferFeeConfig(&_EVM2EVMOnRamp.TransactOpts, tokenTransferFeeConfigArgs) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "transferOwnership", to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.TransferOwnership(&_EVM2EVMOnRamp.TransactOpts, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.TransferOwnership(&_EVM2EVMOnRamp.TransactOpts, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactor) WithdrawNonLinkFees(opts *bind.TransactOpts, feeToken common.Address, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.contract.Transact(opts, "withdrawNonLinkFees", feeToken, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampSession) WithdrawNonLinkFees(feeToken common.Address, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.WithdrawNonLinkFees(&_EVM2EVMOnRamp.TransactOpts, feeToken, to) +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampTransactorSession) WithdrawNonLinkFees(feeToken common.Address, to common.Address) (*types.Transaction, error) { + return _EVM2EVMOnRamp.Contract.WithdrawNonLinkFees(&_EVM2EVMOnRamp.TransactOpts, feeToken, to) +} + +type EVM2EVMOnRampAdminSetIterator struct { + Event *EVM2EVMOnRampAdminSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampAdminSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampAdminSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampAdminSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampAdminSet struct { + NewAdmin common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOnRampAdminSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampAdminSetIterator{contract: _EVM2EVMOnRamp.contract, event: "AdminSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAdminSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "AdminSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampAdminSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseAdminSet(log types.Log) (*EVM2EVMOnRampAdminSet, error) { + event := new(EVM2EVMOnRampAdminSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampCCIPSendRequestedIterator struct { + Event *EVM2EVMOnRampCCIPSendRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampCCIPSendRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampCCIPSendRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampCCIPSendRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampCCIPSendRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampCCIPSendRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampCCIPSendRequested struct { + Message InternalEVM2EVMMessage + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterCCIPSendRequested(opts *bind.FilterOpts) (*EVM2EVMOnRampCCIPSendRequestedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "CCIPSendRequested") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampCCIPSendRequestedIterator{contract: _EVM2EVMOnRamp.contract, event: "CCIPSendRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampCCIPSendRequested) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "CCIPSendRequested") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampCCIPSendRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseCCIPSendRequested(log types.Log) (*EVM2EVMOnRampCCIPSendRequested, error) { + event := new(EVM2EVMOnRampCCIPSendRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampConfigSetIterator struct { + Event *EVM2EVMOnRampConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampConfigSet struct { + StaticConfig EVM2EVMOnRampStaticConfig + DynamicConfig EVM2EVMOnRampDynamicConfig + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampConfigSetIterator{contract: _EVM2EVMOnRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseConfigSet(log types.Log) (*EVM2EVMOnRampConfigSet, error) { + event := new(EVM2EVMOnRampConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampFeeConfigSetIterator struct { + Event *EVM2EVMOnRampFeeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampFeeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampFeeConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampFeeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampFeeConfigSet struct { + FeeConfig []EVM2EVMOnRampFeeTokenConfigArgs + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampFeeConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "FeeConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampFeeConfigSetIterator{contract: _EVM2EVMOnRamp.contract, event: "FeeConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampFeeConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "FeeConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "FeeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseFeeConfigSet(log types.Log) (*EVM2EVMOnRampFeeConfigSet, error) { + event := new(EVM2EVMOnRampFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "FeeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampNopPaidIterator struct { + Event *EVM2EVMOnRampNopPaid + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampNopPaidIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopPaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopPaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampNopPaidIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampNopPaidIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampNopPaid struct { + Nop common.Address + Amount *big.Int + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterNopPaid(opts *bind.FilterOpts, nop []common.Address) (*EVM2EVMOnRampNopPaidIterator, error) { + + var nopRule []interface{} + for _, nopItem := range nop { + nopRule = append(nopRule, nopItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "NopPaid", nopRule) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampNopPaidIterator{contract: _EVM2EVMOnRamp.contract, event: "NopPaid", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchNopPaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopPaid, nop []common.Address) (event.Subscription, error) { + + var nopRule []interface{} + for _, nopItem := range nop { + nopRule = append(nopRule, nopItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "NopPaid", nopRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampNopPaid) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopPaid", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseNopPaid(log types.Log) (*EVM2EVMOnRampNopPaid, error) { + event := new(EVM2EVMOnRampNopPaid) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopPaid", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampNopsSetIterator struct { + Event *EVM2EVMOnRampNopsSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampNopsSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopsSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampNopsSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampNopsSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampNopsSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampNopsSet struct { + NopWeightsTotal *big.Int + NopsAndWeights []EVM2EVMOnRampNopAndWeight + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterNopsSet(opts *bind.FilterOpts) (*EVM2EVMOnRampNopsSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "NopsSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampNopsSetIterator{contract: _EVM2EVMOnRamp.contract, event: "NopsSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchNopsSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopsSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "NopsSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampNopsSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopsSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseNopsSet(log types.Log) (*EVM2EVMOnRampNopsSet, error) { + event := new(EVM2EVMOnRampNopsSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "NopsSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampOwnershipTransferRequestedIterator struct { + Event *EVM2EVMOnRampOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampOwnershipTransferRequestedIterator{contract: _EVM2EVMOnRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampOwnershipTransferRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOnRampOwnershipTransferRequested, error) { + event := new(EVM2EVMOnRampOwnershipTransferRequested) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampOwnershipTransferredIterator struct { + Event *EVM2EVMOnRampOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &EVM2EVMOnRampOwnershipTransferredIterator{contract: _EVM2EVMOnRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampOwnershipTransferred) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseOwnershipTransferred(log types.Log) (*EVM2EVMOnRampOwnershipTransferred, error) { + event := new(EVM2EVMOnRampOwnershipTransferred) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampPoolAddedIterator struct { + Event *EVM2EVMOnRampPoolAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampPoolAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampPoolAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampPoolAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampPoolAddedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampPoolAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampPoolAdded struct { + Token common.Address + Pool common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterPoolAdded(opts *bind.FilterOpts) (*EVM2EVMOnRampPoolAddedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "PoolAdded") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampPoolAddedIterator{contract: _EVM2EVMOnRamp.contract, event: "PoolAdded", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchPoolAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampPoolAdded) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "PoolAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampPoolAdded) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "PoolAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParsePoolAdded(log types.Log) (*EVM2EVMOnRampPoolAdded, error) { + event := new(EVM2EVMOnRampPoolAdded) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "PoolAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampPoolRemovedIterator struct { + Event *EVM2EVMOnRampPoolRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampPoolRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampPoolRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampPoolRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampPoolRemovedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampPoolRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampPoolRemoved struct { + Token common.Address + Pool common.Address + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterPoolRemoved(opts *bind.FilterOpts) (*EVM2EVMOnRampPoolRemovedIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "PoolRemoved") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampPoolRemovedIterator{contract: _EVM2EVMOnRamp.contract, event: "PoolRemoved", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchPoolRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampPoolRemoved) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "PoolRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampPoolRemoved) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "PoolRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParsePoolRemoved(log types.Log) (*EVM2EVMOnRampPoolRemoved, error) { + event := new(EVM2EVMOnRampPoolRemoved) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "PoolRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type EVM2EVMOnRampTokenTransferFeeConfigSetIterator struct { + Event *EVM2EVMOnRampTokenTransferFeeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOnRampTokenTransferFeeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOnRampTokenTransferFeeConfigSet struct { + TransferFeeConfig []EVM2EVMOnRampTokenTransferFeeConfigArgs + Raw types.Log +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) FilterTokenTransferFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampTokenTransferFeeConfigSetIterator, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.FilterLogs(opts, "TokenTransferFeeConfigSet") + if err != nil { + return nil, err + } + return &EVM2EVMOnRampTokenTransferFeeConfigSetIterator{contract: _EVM2EVMOnRamp.contract, event: "TokenTransferFeeConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) WatchTokenTransferFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampTokenTransferFeeConfigSet) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOnRamp.contract.WatchLogs(opts, "TokenTransferFeeConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "TokenTransferFeeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRampFilterer) ParseTokenTransferFeeConfigSet(log types.Log) (*EVM2EVMOnRampTokenTransferFeeConfigSet, error) { + event := new(EVM2EVMOnRampTokenTransferFeeConfigSet) + if err := _EVM2EVMOnRamp.contract.UnpackLog(event, "TokenTransferFeeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetNops struct { + NopsAndWeights []EVM2EVMOnRampNopAndWeight + WeightsTotal *big.Int +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _EVM2EVMOnRamp.abi.Events["AdminSet"].ID: + return _EVM2EVMOnRamp.ParseAdminSet(log) + case _EVM2EVMOnRamp.abi.Events["CCIPSendRequested"].ID: + return _EVM2EVMOnRamp.ParseCCIPSendRequested(log) + case _EVM2EVMOnRamp.abi.Events["ConfigSet"].ID: + return _EVM2EVMOnRamp.ParseConfigSet(log) + case _EVM2EVMOnRamp.abi.Events["FeeConfigSet"].ID: + return _EVM2EVMOnRamp.ParseFeeConfigSet(log) + case _EVM2EVMOnRamp.abi.Events["NopPaid"].ID: + return _EVM2EVMOnRamp.ParseNopPaid(log) + case _EVM2EVMOnRamp.abi.Events["NopsSet"].ID: + return _EVM2EVMOnRamp.ParseNopsSet(log) + case _EVM2EVMOnRamp.abi.Events["OwnershipTransferRequested"].ID: + return _EVM2EVMOnRamp.ParseOwnershipTransferRequested(log) + case _EVM2EVMOnRamp.abi.Events["OwnershipTransferred"].ID: + return _EVM2EVMOnRamp.ParseOwnershipTransferred(log) + case _EVM2EVMOnRamp.abi.Events["PoolAdded"].ID: + return _EVM2EVMOnRamp.ParsePoolAdded(log) + case _EVM2EVMOnRamp.abi.Events["PoolRemoved"].ID: + return _EVM2EVMOnRamp.ParsePoolRemoved(log) + case _EVM2EVMOnRamp.abi.Events["TokenTransferFeeConfigSet"].ID: + return _EVM2EVMOnRamp.ParseTokenTransferFeeConfigSet(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (EVM2EVMOnRampAdminSet) Topic() common.Hash { + return common.HexToHash("0x8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c") +} + +func (EVM2EVMOnRampCCIPSendRequested) Topic() common.Hash { + return common.HexToHash("0xd0c3c799bf9e2639de44391e7f524d229b2b55f5b1ea94b2bf7da42f7243dddd") +} + +func (EVM2EVMOnRampConfigSet) Topic() common.Hash { + return common.HexToHash("0x2a57f7c2027cf032c78b77d4d8d2fbd20ad22e5d5e5b5fb23ac7d7820d44adc6") +} + +func (EVM2EVMOnRampFeeConfigSet) Topic() common.Hash { + return common.HexToHash("0x067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e") +} + +func (EVM2EVMOnRampNopPaid) Topic() common.Hash { + return common.HexToHash("0x55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f") +} + +func (EVM2EVMOnRampNopsSet) Topic() common.Hash { + return common.HexToHash("0x8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd24") +} + +func (EVM2EVMOnRampOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (EVM2EVMOnRampOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (EVM2EVMOnRampPoolAdded) Topic() common.Hash { + return common.HexToHash("0x95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c") +} + +func (EVM2EVMOnRampPoolRemoved) Topic() common.Hash { + return common.HexToHash("0x987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c") +} + +func (EVM2EVMOnRampTokenTransferFeeConfigSet) Topic() common.Hash { + return common.HexToHash("0x555c74101f7a15746d31c6731170310e667bcc607996b2fc0b981a7b26a416e9") +} + +func (_EVM2EVMOnRamp *EVM2EVMOnRamp) Address() common.Address { + return _EVM2EVMOnRamp.address +} + +type EVM2EVMOnRampInterface interface { + CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterTokenBucket, error) + + GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMOnRampDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) + + GetFeeTokenConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampFeeTokenConfig, error) + + GetNopFeesJuels(opts *bind.CallOpts) (*big.Int, error) + + GetNops(opts *bind.CallOpts) (GetNops, + + error) + + GetPoolBySourceToken(opts *bind.CallOpts, arg0 uint64, sourceToken common.Address) (common.Address, error) + + GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) + + GetStaticConfig(opts *bind.CallOpts) (EVM2EVMOnRampStaticConfig, error) + + GetSupportedTokens(opts *bind.CallOpts, arg0 uint64) ([]common.Address, error) + + GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) + + GetTokenTransferFeeConfig(opts *bind.CallOpts, token common.Address) (EVM2EVMOnRampTokenTransferFeeConfig, error) + + LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyPoolUpdates(opts *bind.TransactOpts, removes []InternalPoolUpdate, adds []InternalPoolUpdate) (*types.Transaction, error) + + ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) + + PayNops(opts *bind.TransactOpts) (*types.Transaction, error) + + SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) + + SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) + + SetFeeTokenConfig(opts *bind.TransactOpts, feeTokenConfigArgs []EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) + + SetNops(opts *bind.TransactOpts, nopsAndWeights []EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) + + SetRateLimiterConfig(opts *bind.TransactOpts, config RateLimiterConfig) (*types.Transaction, error) + + SetTokenTransferFeeConfig(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []EVM2EVMOnRampTokenTransferFeeConfigArgs) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + WithdrawNonLinkFees(opts *bind.TransactOpts, feeToken common.Address, to common.Address) (*types.Transaction, error) + + FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMOnRampAdminSetIterator, error) + + WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampAdminSet) (event.Subscription, error) + + ParseAdminSet(log types.Log) (*EVM2EVMOnRampAdminSet, error) + + FilterCCIPSendRequested(opts *bind.FilterOpts) (*EVM2EVMOnRampCCIPSendRequestedIterator, error) + + WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampCCIPSendRequested) (event.Subscription, error) + + ParseCCIPSendRequested(log types.Log) (*EVM2EVMOnRampCCIPSendRequested, error) + + FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*EVM2EVMOnRampConfigSet, error) + + FilterFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampFeeConfigSetIterator, error) + + WatchFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampFeeConfigSet) (event.Subscription, error) + + ParseFeeConfigSet(log types.Log) (*EVM2EVMOnRampFeeConfigSet, error) + + FilterNopPaid(opts *bind.FilterOpts, nop []common.Address) (*EVM2EVMOnRampNopPaidIterator, error) + + WatchNopPaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopPaid, nop []common.Address) (event.Subscription, error) + + ParseNopPaid(log types.Log) (*EVM2EVMOnRampNopPaid, error) + + FilterNopsSet(opts *bind.FilterOpts) (*EVM2EVMOnRampNopsSetIterator, error) + + WatchNopsSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampNopsSet) (event.Subscription, error) + + ParseNopsSet(log types.Log) (*EVM2EVMOnRampNopsSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMOnRampOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMOnRampOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*EVM2EVMOnRampOwnershipTransferred, error) + + FilterPoolAdded(opts *bind.FilterOpts) (*EVM2EVMOnRampPoolAddedIterator, error) + + WatchPoolAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampPoolAdded) (event.Subscription, error) + + ParsePoolAdded(log types.Log) (*EVM2EVMOnRampPoolAdded, error) + + FilterPoolRemoved(opts *bind.FilterOpts) (*EVM2EVMOnRampPoolRemovedIterator, error) + + WatchPoolRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampPoolRemoved) (event.Subscription, error) + + ParsePoolRemoved(log types.Log) (*EVM2EVMOnRampPoolRemoved, error) + + FilterTokenTransferFeeConfigSet(opts *bind.FilterOpts) (*EVM2EVMOnRampTokenTransferFeeConfigSetIterator, error) + + WatchTokenTransferFeeConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMOnRampTokenTransferFeeConfigSet) (event.Subscription, error) + + ParseTokenTransferFeeConfigSet(log types.Log) (*EVM2EVMOnRampTokenTransferFeeConfigSet, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go new file mode 100644 index 0000000000..fe2ac3f87e --- /dev/null +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go @@ -0,0 +1,3204 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package lock_release_token_pool + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type PoolLockOrBurnInV1 struct { + Receiver []byte + RemoteChainSelector uint64 + OriginalSender common.Address + Amount *big.Int + LocalToken common.Address +} + +type PoolLockOrBurnOutV1 struct { + DestTokenAddress []byte + DestPoolData []byte +} + +type PoolReleaseOrMintInV1 struct { + OriginalSender []byte + RemoteChainSelector uint64 + Receiver common.Address + Amount *big.Int + LocalToken common.Address + SourcePoolAddress []byte + SourcePoolData []byte + OffchainTokenData []byte +} + +type PoolReleaseOrMintOutV1 struct { + DestinationAmount *big.Int +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + RemotePoolAddress []byte + RemoteTokenAddress []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +var LockReleaseTokenPoolMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b506040516200487838038062004878833981016040819052620000359162000565565b848484833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200017e565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001695760408051600081526020810190915262000169908462000229565b5050505090151560e05250620006d692505050565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000688565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000688565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200069e565b8554909150600090620003fa906001906200069e565b9050818114620004665760008660000182815481106200041e576200041e62000688565b906000526020600020015490508087600001848154811062000444576200044462000688565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a620006c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b805180151581146200054f57600080fd5b600080600080600060a086880312156200057e57600080fd5b85516200058b8162000513565b602087810151919650906001600160401b0380821115620005ab57600080fd5b818901915089601f830112620005c057600080fd5b815181811115620005d557620005d56200052c565b8060051b604051601f19603f83011681018181108582111715620005fd57620005fd6200052c565b60405291825284820192508381018501918c8311156200061c57600080fd5b938501935b828510156200064557620006358562000542565b8452938501939285019262000621565b8099505050505050506200065c6040870162000542565b92506200066c6060870162000554565b91506200067c6080870162000542565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161410662000772600039600081816104d1015261163801526000818161057e01528181611bd4015261267901526000818161055801528181611a050152611e8a015260008181610285015281816102da0152818161075c0152818161082e015281816108bf015281816116fa0152818161192501528181611daa0152818161260f015261286401526141066000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80638da5cb5b1161010f578063c4bffe2b116100a2578063dc0bd97111610071578063dc0bd97114610556578063e0351e131461057c578063eb521a4c146105a2578063f2fde38b146105b557600080fd5b8063c4bffe2b14610508578063c75eea9c1461051d578063cf7401f314610530578063db6327dc1461054357600080fd5b8063b0f479a1116100de578063b0f479a11461049e578063b7946580146104bc578063bb98546b146104cf578063c0d78655146104f557600080fd5b80638da5cb5b146103dc5780639a4575b9146103fa578063a7cd63b71461041a578063af58d59f1461042f57600080fd5b8063432a6ba31161018757806378a010b21161015657806378a010b21461039b57806379ba5097146103ae5780637d54534e146103b65780638926f54f146103c957600080fd5b8063432a6ba31461033957806354c8a4f3146103575780636cfd15531461036a5780636d3d1a581461037d57600080fd5b8063181f5a77116101c3578063181f5a771461024757806321df0da714610283578063240028e8146102ca578063390775371461031757600080fd5b806301ffc9a7146101ea5780630a2fd493146102125780630a861f2a14610232575b600080fd5b6101fd6101f836600461320e565b6105c8565b60405190151581526020015b60405180910390f35b61022561022036600461326d565b610624565b60405161020991906132f6565b610245610240366004613309565b6106d4565b005b6102256040518060400160405280601e81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e302d646576000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610209565b6101fd6102d836600461334f565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61032a61032536600461336c565b610885565b60405190518152602001610209565b60085473ffffffffffffffffffffffffffffffffffffffff166102a5565b6102456103653660046133f4565b61097b565b61024561037836600461334f565b6109f6565b60095473ffffffffffffffffffffffffffffffffffffffff166102a5565b6102456103a9366004613460565b610a45565b610245610bb4565b6102456103c436600461334f565b610cb1565b6101fd6103d736600461326d565b610d00565b60005473ffffffffffffffffffffffffffffffffffffffff166102a5565b61040d6104083660046134e3565b610d17565b604051610209919061351e565b610422610db1565b604051610209919061357e565b61044261043d36600461326d565b610dc2565b604051610209919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102a5565b6102256104ca36600461326d565b610e97565b7f00000000000000000000000000000000000000000000000000000000000000006101fd565b61024561050336600461334f565b610ec2565b610510610f9d565b60405161020991906135d8565b61044261052b36600461326d565b611055565b61024561053e366004613740565b611127565b610245610551366004613785565b6111b0565b7f00000000000000000000000000000000000000000000000000000000000000006102a5565b7f00000000000000000000000000000000000000000000000000000000000000006101fd565b6102456105b0366004613309565b611636565b6102456105c336600461334f565b611752565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061061e575061061e82611766565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061064f906137c7565b80601f016020809104026020016040519081016040528092919081815260200182805461067b906137c7565b80156106c85780601f1061069d576101008083540402835291602001916106c8565b820191906000526020600020905b8154815290600101906020018083116106ab57829003601f168201915b50505050509050919050565b60085473ffffffffffffffffffffffffffffffffffffffff16331461072c576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107dc919061381a565b1015610814576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61085573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016338361184a565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108a56108a0836138de565b61191e565b6108ea73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633606085013561184a565b6108fa606083016040840161334f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52846060013560405161095c91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610983611b4f565b6109f084848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611bd292505050565b50505050565b6109fe611b4f565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610a4d611b4f565b610a5683610d00565b610a98576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610723565b67ffffffffffffffff831660009081526007602052604081206004018054610abf906137c7565b80601f0160208091040260200160405190810160405280929190818152602001828054610aeb906137c7565b8015610b385780601f10610b0d57610100808354040283529160200191610b38565b820191906000526020600020905b815481529060010190602001808311610b1b57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610b67838583613a23565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610ba693929190613b3e565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610723565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610cb9611b4f565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061061e600567ffffffffffffffff8416611d88565b6040805180820190915260608082526020820152610d3c610d3783613ba2565b611da3565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610d968460200160208101906104ca919061326d565b81526040805160208181019092526000815291015292915050565b6060610dbd6002611f6d565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261061e90611f7a565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061064f906137c7565b610eca611b4f565b73ffffffffffffffffffffffffffffffffffffffff8116610f17576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610fab6005611f6d565b90506000815167ffffffffffffffff811115610fc957610fc961361a565b604051908082528060200260200182016040528015610ff2578160200160208202803683370190505b50905060005b825181101561104e5782818151811061101357611013613c44565b602002602001015182828151811061102d5761102d613c44565b67ffffffffffffffff90921660209283029190910190910152600101610ff8565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261061e90611f7a565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590611167575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156111a0576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610723565b6111ab83838361202c565b505050565b6111b8611b4f565b60005b818110156111ab5760008383838181106111d7576111d7613c44565b90506020028101906111e99190613c73565b6111f290613cb1565b90506112078160800151826020015115612116565b61121a8160a00151826020015115612116565b80602001511561151657805161123c9060059067ffffffffffffffff1661224f565b6112815780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610723565b60408101515115806112965750606081015151155b156112cd576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906114ae9082613d65565b50606082015160058201906114c39082613d65565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506115099493929190613e7f565b60405180910390a161162d565b805161152e9060059067ffffffffffffffff1661225b565b6115735780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610723565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906115dc60048301826131c0565b6115ea6005830160006131c0565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016111bb565b7f000000000000000000000000000000000000000000000000000000000000000061168d576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085473ffffffffffffffffffffffffffffffffffffffff1633146116e0576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610723565b61172273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612267565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b61175a611b4f565b611763816122c5565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806117f957507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061061e57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526111ab9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526123ba565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119b35760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610723565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a859190613f18565b15611abc576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ac981602001516124c6565b6000611ad88260200151610624565b9050805160001480611afc575080805190602001208260a001518051906020012014155b15611b39578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161072391906132f6565b611b4b826020015183606001516125ec565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611bd0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610723565b565b7f0000000000000000000000000000000000000000000000000000000000000000611c29576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611cbf576000838281518110611c4957611c49613c44565b60200260200101519050611c6781600261263390919063ffffffff16565b15611cb65760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611c2c565b5060005b81518110156111ab576000828281518110611ce057611ce0613c44565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d245750611d80565b611d2f600282612655565b15611d7e5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611cc3565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611e385760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610723565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611ee6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f0a9190613f18565b15611f41576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f4e8160400151612677565b611f5b81602001516126f6565b61176381602001518260600151612844565b60606000611d9c83612888565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261200882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611fec9190613f64565b85608001516fffffffffffffffffffffffffffffffff166128e3565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61203583610d00565b612077576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610723565b612082826000612116565b67ffffffffffffffff831660009081526007602052604090206120a5908361290d565b6120b0816000612116565b67ffffffffffffffff831660009081526007602052604090206120d6906002018261290d565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161210993929190613f77565b60405180910390a1505050565b8151156121dd5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061216c575060408201516fffffffffffffffffffffffffffffffff16155b156121a557816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107239190613ffa565b8015611b4b576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612216575060208201516fffffffffffffffffffffffffffffffff1615155b15611b4b57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107239190613ffa565b6000611d9c8383612aaf565b6000611d9c8383612afe565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109f09085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161189c565b3373ffffffffffffffffffffffffffffffffffffffff821603612344576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610723565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061241c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612bf19092919063ffffffff16565b8051909150156111ab578080602001905181019061243a9190613f18565b6111ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610723565b6124cf81610d00565b612511576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610723565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612590573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b49190613f18565b611763576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610723565b67ffffffffffffffff82166000908152600760205260409020611b4b90600201827f0000000000000000000000000000000000000000000000000000000000000000612c00565b6000611d9c8373ffffffffffffffffffffffffffffffffffffffff8416612afe565b6000611d9c8373ffffffffffffffffffffffffffffffffffffffff8416612aaf565b7f000000000000000000000000000000000000000000000000000000000000000015611763576126a8600282612f83565b611763576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610723565b6126ff81610d00565b612741576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610723565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156127ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127de9190614036565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611763576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610723565b67ffffffffffffffff82166000908152600760205260409020611b4b90827f0000000000000000000000000000000000000000000000000000000000000000612c00565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106c857602002820191906000526020600020905b8154815260200190600101908083116128c45750505050509050919050565b6000612902856128f38486614053565b6128fd908761406a565b612fb2565b90505b949350505050565b815460009061293690700100000000000000000000000000000000900463ffffffff1642613f64565b905080156129d8576001830154835461297e916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166128e3565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546129fe916fffffffffffffffffffffffffffffffff9081169116612fb2565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612109908490613ffa565b6000818152600183016020526040812054612af65750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561061e565b50600061061e565b60008181526001830160205260408120548015612be7576000612b22600183613f64565b8554909150600090612b3690600190613f64565b9050818114612b9b576000866000018281548110612b5657612b56613c44565b9060005260206000200154905080876000018481548110612b7957612b79613c44565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612bac57612bac61407d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061061e565b600091505061061e565b60606129058484600085612fc8565b825474010000000000000000000000000000000000000000900460ff161580612c27575081155b15612c3157505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612c7790700100000000000000000000000000000000900463ffffffff1642613f64565b90508015612d375781831115612cb9576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612cf39083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166128e3565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612dee5773ffffffffffffffffffffffffffffffffffffffff8416612d96576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610723565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610723565b84831015612f015760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612e329082613f64565b612e3c878a613f64565b612e46919061406a565b612e5091906140ac565b905073ffffffffffffffffffffffffffffffffffffffff8616612ea9576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610723565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610723565b612f0b8584613f64565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611d9c565b6000818310612fc15781611d9c565b5090919050565b60608247101561305a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610723565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161308391906140e7565b60006040518083038185875af1925050503d80600081146130c0576040519150601f19603f3d011682016040523d82523d6000602084013e6130c5565b606091505b50915091506130d6878383876130e1565b979650505050505050565b606083156131775782516000036131705773ffffffffffffffffffffffffffffffffffffffff85163b613170576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610723565b5081612905565b612905838381511561318c5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072391906132f6565b5080546131cc906137c7565b6000825580601f106131dc575050565b601f01602090049060005260206000209081019061176391905b8082111561320a57600081556001016131f6565b5090565b60006020828403121561322057600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611d9c57600080fd5b803567ffffffffffffffff8116811461326857600080fd5b919050565b60006020828403121561327f57600080fd5b611d9c82613250565b60005b838110156132a357818101518382015260200161328b565b50506000910152565b600081518084526132c4816020860160208601613288565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d9c60208301846132ac565b60006020828403121561331b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461176357600080fd5b803561326881613322565b60006020828403121561336157600080fd5b8135611d9c81613322565b60006020828403121561337e57600080fd5b813567ffffffffffffffff81111561339557600080fd5b82016101008185031215611d9c57600080fd5b60008083601f8401126133ba57600080fd5b50813567ffffffffffffffff8111156133d257600080fd5b6020830191508360208260051b85010111156133ed57600080fd5b9250929050565b6000806000806040858703121561340a57600080fd5b843567ffffffffffffffff8082111561342257600080fd5b61342e888389016133a8565b9096509450602087013591508082111561344757600080fd5b50613454878288016133a8565b95989497509550505050565b60008060006040848603121561347557600080fd5b61347e84613250565b9250602084013567ffffffffffffffff8082111561349b57600080fd5b818601915086601f8301126134af57600080fd5b8135818111156134be57600080fd5b8760208285010111156134d057600080fd5b6020830194508093505050509250925092565b6000602082840312156134f557600080fd5b813567ffffffffffffffff81111561350c57600080fd5b820160a08185031215611d9c57600080fd5b60208152600082516040602084015261353a60608401826132ac565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261357582826132ac565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156135cc57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161359a565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156135cc57835167ffffffffffffffff16835292840192918401916001016135f4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561366d5761366d61361a565b60405290565b60405160c0810167ffffffffffffffff8111828210171561366d5761366d61361a565b801515811461176357600080fd5b803561326881613696565b80356fffffffffffffffffffffffffffffffff8116811461326857600080fd5b6000606082840312156136e157600080fd5b6040516060810181811067ffffffffffffffff821117156137045761370461361a565b604052905080823561371581613696565b8152613723602084016136af565b6020820152613734604084016136af565b60408201525092915050565b600080600060e0848603121561375557600080fd5b61375e84613250565b925061376d85602086016136cf565b915061377c85608086016136cf565b90509250925092565b6000806020838503121561379857600080fd5b823567ffffffffffffffff8111156137af57600080fd5b6137bb858286016133a8565b90969095509350505050565b600181811c908216806137db57607f821691505b602082108103613814577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561382c57600080fd5b5051919050565b600082601f83011261384457600080fd5b813567ffffffffffffffff8082111561385f5761385f61361a565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156138a5576138a561361a565b816040528381528660208588010111156138be57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600061010082360312156138f157600080fd5b6138f9613649565b823567ffffffffffffffff8082111561391157600080fd5b61391d36838701613833565b835261392b60208601613250565b602084015261393c60408601613344565b60408401526060850135606084015261395760808601613344565b608084015260a085013591508082111561397057600080fd5b61397c36838701613833565b60a084015260c085013591508082111561399557600080fd5b6139a136838701613833565b60c084015260e08501359150808211156139ba57600080fd5b506139c736828601613833565b60e08301525092915050565b601f8211156111ab576000816000526020600020601f850160051c810160208610156139fc5750805b601f850160051c820191505b81811015613a1b57828155600101613a08565b505050505050565b67ffffffffffffffff831115613a3b57613a3b61361a565b613a4f83613a4983546137c7565b836139d3565b6000601f841160018114613aa15760008515613a6b5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613b37565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613af05786850135825560209485019460019092019101613ad0565b5086821015613b2b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613b5160408301866132ac565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613bb457600080fd5b60405160a0810167ffffffffffffffff8282108183111715613bd857613bd861361a565b816040528435915080821115613bed57600080fd5b50613bfa36828601613833565b825250613c0960208401613250565b60208201526040830135613c1c81613322565b6040820152606083810135908201526080830135613c3981613322565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ca757600080fd5b9190910192915050565b60006101408236031215613cc457600080fd5b613ccc613673565b613cd583613250565b8152613ce3602084016136a4565b6020820152604083013567ffffffffffffffff80821115613d0357600080fd5b613d0f36838701613833565b60408401526060850135915080821115613d2857600080fd5b50613d3536828601613833565b606083015250613d4836608085016136cf565b6080820152613d5a3660e085016136cf565b60a082015292915050565b815167ffffffffffffffff811115613d7f57613d7f61361a565b613d9381613d8d84546137c7565b846139d3565b602080601f831160018114613de65760008415613db05750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613a1b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e3357888601518255948401946001909101908401613e14565b5085821015613e6f57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613ea3818401876132ac565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613ee19050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613575565b600060208284031215613f2a57600080fd5b8151611d9c81613696565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561061e5761061e613f35565b67ffffffffffffffff8416815260e08101613fc360208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612905565b6060810161061e82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561404857600080fd5b8151611d9c81613322565b808202811582820484141761061e5761061e613f35565b8082018082111561061e5761061e613f35565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826140e2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613ca781846020870161328856fea164736f6c6343000818000a", +} + +var LockReleaseTokenPoolABI = LockReleaseTokenPoolMetaData.ABI + +var LockReleaseTokenPoolBin = LockReleaseTokenPoolMetaData.Bin + +func DeployLockReleaseTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, rmnProxy common.Address, acceptLiquidity bool, router common.Address) (common.Address, *types.Transaction, *LockReleaseTokenPool, error) { + parsed, err := LockReleaseTokenPoolMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LockReleaseTokenPoolBin), backend, token, allowlist, rmnProxy, acceptLiquidity, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &LockReleaseTokenPool{address: address, abi: *parsed, LockReleaseTokenPoolCaller: LockReleaseTokenPoolCaller{contract: contract}, LockReleaseTokenPoolTransactor: LockReleaseTokenPoolTransactor{contract: contract}, LockReleaseTokenPoolFilterer: LockReleaseTokenPoolFilterer{contract: contract}}, nil +} + +type LockReleaseTokenPool struct { + address common.Address + abi abi.ABI + LockReleaseTokenPoolCaller + LockReleaseTokenPoolTransactor + LockReleaseTokenPoolFilterer +} + +type LockReleaseTokenPoolCaller struct { + contract *bind.BoundContract +} + +type LockReleaseTokenPoolTransactor struct { + contract *bind.BoundContract +} + +type LockReleaseTokenPoolFilterer struct { + contract *bind.BoundContract +} + +type LockReleaseTokenPoolSession struct { + Contract *LockReleaseTokenPool + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type LockReleaseTokenPoolCallerSession struct { + Contract *LockReleaseTokenPoolCaller + CallOpts bind.CallOpts +} + +type LockReleaseTokenPoolTransactorSession struct { + Contract *LockReleaseTokenPoolTransactor + TransactOpts bind.TransactOpts +} + +type LockReleaseTokenPoolRaw struct { + Contract *LockReleaseTokenPool +} + +type LockReleaseTokenPoolCallerRaw struct { + Contract *LockReleaseTokenPoolCaller +} + +type LockReleaseTokenPoolTransactorRaw struct { + Contract *LockReleaseTokenPoolTransactor +} + +func NewLockReleaseTokenPool(address common.Address, backend bind.ContractBackend) (*LockReleaseTokenPool, error) { + abi, err := abi.JSON(strings.NewReader(LockReleaseTokenPoolABI)) + if err != nil { + return nil, err + } + contract, err := bindLockReleaseTokenPool(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LockReleaseTokenPool{address: address, abi: abi, LockReleaseTokenPoolCaller: LockReleaseTokenPoolCaller{contract: contract}, LockReleaseTokenPoolTransactor: LockReleaseTokenPoolTransactor{contract: contract}, LockReleaseTokenPoolFilterer: LockReleaseTokenPoolFilterer{contract: contract}}, nil +} + +func NewLockReleaseTokenPoolCaller(address common.Address, caller bind.ContractCaller) (*LockReleaseTokenPoolCaller, error) { + contract, err := bindLockReleaseTokenPool(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolCaller{contract: contract}, nil +} + +func NewLockReleaseTokenPoolTransactor(address common.Address, transactor bind.ContractTransactor) (*LockReleaseTokenPoolTransactor, error) { + contract, err := bindLockReleaseTokenPool(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolTransactor{contract: contract}, nil +} + +func NewLockReleaseTokenPoolFilterer(address common.Address, filterer bind.ContractFilterer) (*LockReleaseTokenPoolFilterer, error) { + contract, err := bindLockReleaseTokenPool(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolFilterer{contract: contract}, nil +} + +func bindLockReleaseTokenPool(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LockReleaseTokenPoolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LockReleaseTokenPool.Contract.LockReleaseTokenPoolCaller.contract.Call(opts, result, method, params...) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.LockReleaseTokenPoolTransactor.contract.Transfer(opts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.LockReleaseTokenPoolTransactor.contract.Transact(opts, method, params...) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LockReleaseTokenPool.Contract.contract.Call(opts, result, method, params...) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.contract.Transfer(opts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.contract.Transact(opts, method, params...) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) CanAcceptLiquidity(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "canAcceptLiquidity") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) CanAcceptLiquidity() (bool, error) { + return _LockReleaseTokenPool.Contract.CanAcceptLiquidity(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) CanAcceptLiquidity() (bool, error) { + return _LockReleaseTokenPool.Contract.CanAcceptLiquidity(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetAllowList() ([]common.Address, error) { + return _LockReleaseTokenPool.Contract.GetAllowList(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetAllowList() ([]common.Address, error) { + return _LockReleaseTokenPool.Contract.GetAllowList(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetAllowListEnabled() (bool, error) { + return _LockReleaseTokenPool.Contract.GetAllowListEnabled(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetAllowListEnabled() (bool, error) { + return _LockReleaseTokenPool.Contract.GetAllowListEnabled(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPool.Contract.GetCurrentInboundRateLimiterState(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPool.Contract.GetCurrentInboundRateLimiterState(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getRateLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetRateLimitAdmin() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRateLimitAdmin(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetRateLimitAdmin() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRateLimitAdmin(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetRebalancer(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getRebalancer") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetRebalancer() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRebalancer(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetRebalancer() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRebalancer(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _LockReleaseTokenPool.Contract.GetRemotePool(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _LockReleaseTokenPool.Contract.GetRemotePool(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getRemoteToken", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _LockReleaseTokenPool.Contract.GetRemoteToken(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _LockReleaseTokenPool.Contract.GetRemoteToken(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetRmnProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getRmnProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetRmnProxy() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRmnProxy(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetRmnProxy() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRmnProxy(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetRouter() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRouter(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetRouter() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRouter(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetSupportedChains() ([]uint64, error) { + return _LockReleaseTokenPool.Contract.GetSupportedChains(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetSupportedChains() ([]uint64, error) { + return _LockReleaseTokenPool.Contract.GetSupportedChains(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetToken() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetToken(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetToken() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetToken(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _LockReleaseTokenPool.Contract.IsSupportedChain(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _LockReleaseTokenPool.Contract.IsSupportedChain(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "isSupportedToken", token) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) IsSupportedToken(token common.Address) (bool, error) { + return _LockReleaseTokenPool.Contract.IsSupportedToken(&_LockReleaseTokenPool.CallOpts, token) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) IsSupportedToken(token common.Address) (bool, error) { + return _LockReleaseTokenPool.Contract.IsSupportedToken(&_LockReleaseTokenPool.CallOpts, token) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) Owner() (common.Address, error) { + return _LockReleaseTokenPool.Contract.Owner(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) Owner() (common.Address, error) { + return _LockReleaseTokenPool.Contract.Owner(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _LockReleaseTokenPool.Contract.SupportsInterface(&_LockReleaseTokenPool.CallOpts, interfaceId) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _LockReleaseTokenPool.Contract.SupportsInterface(&_LockReleaseTokenPool.CallOpts, interfaceId) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) TypeAndVersion() (string, error) { + return _LockReleaseTokenPool.Contract.TypeAndVersion(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) TypeAndVersion() (string, error) { + return _LockReleaseTokenPool.Contract.TypeAndVersion(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "acceptOwnership") +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) AcceptOwnership() (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.AcceptOwnership(&_LockReleaseTokenPool.TransactOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.AcceptOwnership(&_LockReleaseTokenPool.TransactOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyAllowListUpdates(&_LockReleaseTokenPool.TransactOpts, removes, adds) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyAllowListUpdates(&_LockReleaseTokenPool.TransactOpts, removes, adds) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyChainUpdates(&_LockReleaseTokenPool.TransactOpts, chains) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyChainUpdates(&_LockReleaseTokenPool.TransactOpts, chains) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "lockOrBurn", lockOrBurnIn) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.LockOrBurn(&_LockReleaseTokenPool.TransactOpts, lockOrBurnIn) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.LockOrBurn(&_LockReleaseTokenPool.TransactOpts, lockOrBurnIn) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ProvideLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "provideLiquidity", amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ProvideLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ProvideLiquidity(&_LockReleaseTokenPool.TransactOpts, amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ProvideLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ProvideLiquidity(&_LockReleaseTokenPool.TransactOpts, amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "releaseOrMint", releaseOrMintIn) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ReleaseOrMint(&_LockReleaseTokenPool.TransactOpts, releaseOrMintIn) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ReleaseOrMint(&_LockReleaseTokenPool.TransactOpts, releaseOrMintIn) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetChainRateLimiterConfig(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetChainRateLimiterConfig(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRateLimitAdmin(&_LockReleaseTokenPool.TransactOpts, rateLimitAdmin) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRateLimitAdmin(&_LockReleaseTokenPool.TransactOpts, rateLimitAdmin) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetRebalancer(opts *bind.TransactOpts, rebalancer common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setRebalancer", rebalancer) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetRebalancer(rebalancer common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRebalancer(&_LockReleaseTokenPool.TransactOpts, rebalancer) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetRebalancer(rebalancer common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRebalancer(&_LockReleaseTokenPool.TransactOpts, rebalancer) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRemotePool(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRemotePool(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setRouter", newRouter) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRouter(&_LockReleaseTokenPool.TransactOpts, newRouter) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRouter(&_LockReleaseTokenPool.TransactOpts, newRouter) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "transferOwnership", to) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.TransferOwnership(&_LockReleaseTokenPool.TransactOpts, to) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.TransferOwnership(&_LockReleaseTokenPool.TransactOpts, to) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) WithdrawLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "withdrawLiquidity", amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) WithdrawLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.WithdrawLiquidity(&_LockReleaseTokenPool.TransactOpts, amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) WithdrawLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.WithdrawLiquidity(&_LockReleaseTokenPool.TransactOpts, amount) +} + +type LockReleaseTokenPoolAllowListAddIterator struct { + Event *LockReleaseTokenPoolAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAllowListAddIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*LockReleaseTokenPoolAllowListAddIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAllowListAddIterator{contract: _LockReleaseTokenPool.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAllowListAdd) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseAllowListAdd(log types.Log) (*LockReleaseTokenPoolAllowListAdd, error) { + event := new(LockReleaseTokenPoolAllowListAdd) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAllowListRemoveIterator struct { + Event *LockReleaseTokenPoolAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*LockReleaseTokenPoolAllowListRemoveIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAllowListRemoveIterator{contract: _LockReleaseTokenPool.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAllowListRemove) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseAllowListRemove(log types.Log) (*LockReleaseTokenPoolAllowListRemove, error) { + event := new(LockReleaseTokenPoolAllowListRemove) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolBurnedIterator struct { + Event *LockReleaseTokenPoolBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolBurnedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolBurnedIterator{contract: _LockReleaseTokenPool.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolBurned) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseBurned(log types.Log) (*LockReleaseTokenPoolBurned, error) { + event := new(LockReleaseTokenPoolBurned) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolChainAddedIterator struct { + Event *LockReleaseTokenPoolChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolChainAddedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolChainAdded struct { + RemoteChainSelector uint64 + RemoteToken []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterChainAdded(opts *bind.FilterOpts) (*LockReleaseTokenPoolChainAddedIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolChainAddedIterator{contract: _LockReleaseTokenPool.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolChainAdded) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolChainAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseChainAdded(log types.Log) (*LockReleaseTokenPoolChainAdded, error) { + event := new(LockReleaseTokenPoolChainAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolChainConfiguredIterator struct { + Event *LockReleaseTokenPoolChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*LockReleaseTokenPoolChainConfiguredIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolChainConfiguredIterator{contract: _LockReleaseTokenPool.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolChainConfigured) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolChainConfigured) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseChainConfigured(log types.Log) (*LockReleaseTokenPoolChainConfigured, error) { + event := new(LockReleaseTokenPoolChainConfigured) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolChainRemovedIterator struct { + Event *LockReleaseTokenPoolChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolChainRemovedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*LockReleaseTokenPoolChainRemovedIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolChainRemovedIterator{contract: _LockReleaseTokenPool.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolChainRemoved) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolChainRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseChainRemoved(log types.Log) (*LockReleaseTokenPoolChainRemoved, error) { + event := new(LockReleaseTokenPoolChainRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolConfigChangedIterator struct { + Event *LockReleaseTokenPoolConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolConfigChangedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolConfigChanged struct { + Config RateLimiterConfig + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*LockReleaseTokenPoolConfigChangedIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolConfigChangedIterator{contract: _LockReleaseTokenPool.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolConfigChanged) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolConfigChanged) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseConfigChanged(log types.Log) (*LockReleaseTokenPoolConfigChanged, error) { + event := new(LockReleaseTokenPoolConfigChanged) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolLiquidityAddedIterator struct { + Event *LockReleaseTokenPoolLiquidityAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolLiquidityAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolLiquidityAddedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolLiquidityAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolLiquidityAdded struct { + Provider common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterLiquidityAdded(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolLiquidityAddedIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "LiquidityAdded", providerRule, amountRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolLiquidityAddedIterator{contract: _LockReleaseTokenPool.contract, event: "LiquidityAdded", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchLiquidityAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityAdded, provider []common.Address, amount []*big.Int) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "LiquidityAdded", providerRule, amountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolLiquidityAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseLiquidityAdded(log types.Log) (*LockReleaseTokenPoolLiquidityAdded, error) { + event := new(LockReleaseTokenPoolLiquidityAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolLiquidityRemovedIterator struct { + Event *LockReleaseTokenPoolLiquidityRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolLiquidityRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolLiquidityRemovedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolLiquidityRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolLiquidityRemoved struct { + Provider common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterLiquidityRemoved(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolLiquidityRemovedIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "LiquidityRemoved", providerRule, amountRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolLiquidityRemovedIterator{contract: _LockReleaseTokenPool.contract, event: "LiquidityRemoved", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchLiquidityRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityRemoved, provider []common.Address, amount []*big.Int) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "LiquidityRemoved", providerRule, amountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolLiquidityRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseLiquidityRemoved(log types.Log) (*LockReleaseTokenPoolLiquidityRemoved, error) { + event := new(LockReleaseTokenPoolLiquidityRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolLockedIterator struct { + Event *LockReleaseTokenPoolLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolLockedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolLockedIterator{contract: _LockReleaseTokenPool.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolLocked) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseLocked(log types.Log) (*LockReleaseTokenPoolLocked, error) { + event := new(LockReleaseTokenPoolLocked) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolMintedIterator struct { + Event *LockReleaseTokenPoolMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolMintedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolMintedIterator{contract: _LockReleaseTokenPool.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolMinted) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseMinted(log types.Log) (*LockReleaseTokenPoolMinted, error) { + event := new(LockReleaseTokenPoolMinted) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolOwnershipTransferRequestedIterator struct { + Event *LockReleaseTokenPoolOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolOwnershipTransferRequestedIterator{contract: _LockReleaseTokenPool.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolOwnershipTransferRequested) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseOwnershipTransferRequested(log types.Log) (*LockReleaseTokenPoolOwnershipTransferRequested, error) { + event := new(LockReleaseTokenPoolOwnershipTransferRequested) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolOwnershipTransferredIterator struct { + Event *LockReleaseTokenPoolOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolOwnershipTransferredIterator{contract: _LockReleaseTokenPool.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolOwnershipTransferred) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseOwnershipTransferred(log types.Log) (*LockReleaseTokenPoolOwnershipTransferred, error) { + event := new(LockReleaseTokenPoolOwnershipTransferred) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolReleasedIterator struct { + Event *LockReleaseTokenPoolReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolReleasedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolReleasedIterator{contract: _LockReleaseTokenPool.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolReleased) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseReleased(log types.Log) (*LockReleaseTokenPoolReleased, error) { + event := new(LockReleaseTokenPoolReleased) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolRemotePoolSetIterator struct { + Event *LockReleaseTokenPoolRemotePoolSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolRemotePoolSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolRemotePoolSetIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolRemotePoolSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolRemotePoolSet struct { + RemoteChainSelector uint64 + PreviousPoolAddress []byte + RemotePoolAddress []byte + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*LockReleaseTokenPoolRemotePoolSetIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolRemotePoolSetIterator{contract: _LockReleaseTokenPool.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolRemotePoolSet) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseRemotePoolSet(log types.Log) (*LockReleaseTokenPoolRemotePoolSet, error) { + event := new(LockReleaseTokenPoolRemotePoolSet) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolRouterUpdatedIterator struct { + Event *LockReleaseTokenPoolRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*LockReleaseTokenPoolRouterUpdatedIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolRouterUpdatedIterator{contract: _LockReleaseTokenPool.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolRouterUpdated) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseRouterUpdated(log types.Log) (*LockReleaseTokenPoolRouterUpdated, error) { + event := new(LockReleaseTokenPoolRouterUpdated) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolTokensConsumedIterator struct { + Event *LockReleaseTokenPoolTokensConsumed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolTokensConsumedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolTokensConsumedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolTokensConsumedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolTokensConsumed struct { + Tokens *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterTokensConsumed(opts *bind.FilterOpts) (*LockReleaseTokenPoolTokensConsumedIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolTokensConsumedIterator{contract: _LockReleaseTokenPool.contract, event: "TokensConsumed", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolTokensConsumed) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolTokensConsumed) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseTokensConsumed(log types.Log) (*LockReleaseTokenPoolTokensConsumed, error) { + event := new(LockReleaseTokenPoolTokensConsumed) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPool) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _LockReleaseTokenPool.abi.Events["AllowListAdd"].ID: + return _LockReleaseTokenPool.ParseAllowListAdd(log) + case _LockReleaseTokenPool.abi.Events["AllowListRemove"].ID: + return _LockReleaseTokenPool.ParseAllowListRemove(log) + case _LockReleaseTokenPool.abi.Events["Burned"].ID: + return _LockReleaseTokenPool.ParseBurned(log) + case _LockReleaseTokenPool.abi.Events["ChainAdded"].ID: + return _LockReleaseTokenPool.ParseChainAdded(log) + case _LockReleaseTokenPool.abi.Events["ChainConfigured"].ID: + return _LockReleaseTokenPool.ParseChainConfigured(log) + case _LockReleaseTokenPool.abi.Events["ChainRemoved"].ID: + return _LockReleaseTokenPool.ParseChainRemoved(log) + case _LockReleaseTokenPool.abi.Events["ConfigChanged"].ID: + return _LockReleaseTokenPool.ParseConfigChanged(log) + case _LockReleaseTokenPool.abi.Events["LiquidityAdded"].ID: + return _LockReleaseTokenPool.ParseLiquidityAdded(log) + case _LockReleaseTokenPool.abi.Events["LiquidityRemoved"].ID: + return _LockReleaseTokenPool.ParseLiquidityRemoved(log) + case _LockReleaseTokenPool.abi.Events["Locked"].ID: + return _LockReleaseTokenPool.ParseLocked(log) + case _LockReleaseTokenPool.abi.Events["Minted"].ID: + return _LockReleaseTokenPool.ParseMinted(log) + case _LockReleaseTokenPool.abi.Events["OwnershipTransferRequested"].ID: + return _LockReleaseTokenPool.ParseOwnershipTransferRequested(log) + case _LockReleaseTokenPool.abi.Events["OwnershipTransferred"].ID: + return _LockReleaseTokenPool.ParseOwnershipTransferred(log) + case _LockReleaseTokenPool.abi.Events["Released"].ID: + return _LockReleaseTokenPool.ParseReleased(log) + case _LockReleaseTokenPool.abi.Events["RemotePoolSet"].ID: + return _LockReleaseTokenPool.ParseRemotePoolSet(log) + case _LockReleaseTokenPool.abi.Events["RouterUpdated"].ID: + return _LockReleaseTokenPool.ParseRouterUpdated(log) + case _LockReleaseTokenPool.abi.Events["TokensConsumed"].ID: + return _LockReleaseTokenPool.ParseTokensConsumed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (LockReleaseTokenPoolAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (LockReleaseTokenPoolAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (LockReleaseTokenPoolBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (LockReleaseTokenPoolChainAdded) Topic() common.Hash { + return common.HexToHash("0x8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2") +} + +func (LockReleaseTokenPoolChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (LockReleaseTokenPoolChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (LockReleaseTokenPoolConfigChanged) Topic() common.Hash { + return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") +} + +func (LockReleaseTokenPoolLiquidityAdded) Topic() common.Hash { + return common.HexToHash("0xc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb312088") +} + +func (LockReleaseTokenPoolLiquidityRemoved) Topic() common.Hash { + return common.HexToHash("0xc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf9840171719") +} + +func (LockReleaseTokenPoolLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (LockReleaseTokenPoolMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (LockReleaseTokenPoolOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (LockReleaseTokenPoolOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (LockReleaseTokenPoolReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (LockReleaseTokenPoolRemotePoolSet) Topic() common.Hash { + return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +} + +func (LockReleaseTokenPoolRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (LockReleaseTokenPoolTokensConsumed) Topic() common.Hash { + return common.HexToHash("0x1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a") +} + +func (_LockReleaseTokenPool *LockReleaseTokenPool) Address() common.Address { + return _LockReleaseTokenPool.address +} + +type LockReleaseTokenPoolInterface interface { + CanAcceptLiquidity(opts *bind.CallOpts) (bool, error) + + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) + + GetRebalancer(opts *bind.CallOpts) (common.Address, error) + + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRmnProxy(opts *bind.CallOpts) (common.Address, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) + + ProvideLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) + + SetRebalancer(opts *bind.TransactOpts, rebalancer common.Address) (*types.Transaction, error) + + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + WithdrawLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*LockReleaseTokenPoolAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*LockReleaseTokenPoolAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*LockReleaseTokenPoolAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*LockReleaseTokenPoolAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*LockReleaseTokenPoolBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*LockReleaseTokenPoolChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*LockReleaseTokenPoolChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*LockReleaseTokenPoolChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*LockReleaseTokenPoolChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*LockReleaseTokenPoolChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*LockReleaseTokenPoolChainRemoved, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*LockReleaseTokenPoolConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*LockReleaseTokenPoolConfigChanged, error) + + FilterLiquidityAdded(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolLiquidityAddedIterator, error) + + WatchLiquidityAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityAdded, provider []common.Address, amount []*big.Int) (event.Subscription, error) + + ParseLiquidityAdded(log types.Log) (*LockReleaseTokenPoolLiquidityAdded, error) + + FilterLiquidityRemoved(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolLiquidityRemovedIterator, error) + + WatchLiquidityRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityRemoved, provider []common.Address, amount []*big.Int) (event.Subscription, error) + + ParseLiquidityRemoved(log types.Log) (*LockReleaseTokenPoolLiquidityRemoved, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*LockReleaseTokenPoolLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*LockReleaseTokenPoolMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*LockReleaseTokenPoolOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*LockReleaseTokenPoolOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*LockReleaseTokenPoolReleased, error) + + FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*LockReleaseTokenPoolRemotePoolSetIterator, error) + + WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolSet(log types.Log) (*LockReleaseTokenPoolRemotePoolSet, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*LockReleaseTokenPoolRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*LockReleaseTokenPoolRouterUpdated, error) + + FilterTokensConsumed(opts *bind.FilterOpts) (*LockReleaseTokenPoolTokensConsumedIterator, error) + + WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolTokensConsumed) (event.Subscription, error) + + ParseTokensConsumed(log types.Log) (*LockReleaseTokenPoolTokensConsumed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool_1_0_0/lock_release_token_pool.go b/core/gethwrappers/ccip/generated/lock_release_token_pool_1_0_0/lock_release_token_pool.go new file mode 100644 index 0000000000..30ea97eb99 --- /dev/null +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool_1_0_0/lock_release_token_pool.go @@ -0,0 +1,2892 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package lock_release_token_pool_1_0_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolRampUpdate struct { + Ramp common.Address + Allowed bool + RateLimiterConfig RateLimiterConfig +} + +var LockReleaseTokenPoolMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"NonExistentRamp\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermissionsError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"RampAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WithdrawalTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"OnRampRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"addLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"onRamps\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"offRamps\",\"type\":\"tuple[]\"}],\"name\":\"applyRampUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"currentOffRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"currentOnRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLockReleaseInterfaceId\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOffRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOnRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"}],\"name\":\"getProvidedLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"isOnRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"releaseOrMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"removeLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOffRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOnRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b50604051620036093803806200360983398101604081905262000034916200051d565b82828233806000816200008e5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c157620000c18162000133565b5050506001600160a01b038316620000ec576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808416608052811660a052815115801560c0526200012757604080516000815260208101909152620001279083620001de565b5050505050506200068e565b336001600160a01b038216036200018d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000085565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620001ff576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002945760008382815181106200022357620002236200061a565b602090810291909101015190506200023d6002826200034f565b1562000280576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506200028c8162000646565b905062000202565b5060005b81518110156200034a576000828281518110620002b957620002b96200061a565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002e5575062000337565b620002f26002826200036f565b1562000335576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b620003428162000646565b905062000298565b505050565b600062000366836001600160a01b03841662000386565b90505b92915050565b600062000366836001600160a01b0384166200048a565b600081815260018301602052604081205480156200047f576000620003ad60018362000662565b8554909150600090620003c39060019062000662565b90508181146200042f576000866000018281548110620003e757620003e76200061a565b90600052602060002001549050808760000184815481106200040d576200040d6200061a565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000443576200044362000678565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000369565b600091505062000369565b6000818152600183016020526040812054620004d35750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000369565b50600062000369565b6001600160a01b0381168114620004f257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200051881620004dc565b919050565b6000806000606084860312156200053357600080fd5b83516200054081620004dc565b602085810151919450906001600160401b03808211156200056057600080fd5b818701915087601f8301126200057557600080fd5b8151818111156200058a576200058a620004f5565b8060051b604051601f19603f83011681018181108582111715620005b257620005b2620004f5565b60405291825284820192508381018501918a831115620005d157600080fd5b938501935b82851015620005fa57620005ea856200050b565b84529385019392850192620005d6565b80975050505050505062000611604085016200050b565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200065b576200065b62000630565b5060010190565b8181038181111562000369576200036962000630565b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051612f05620007046000396000818161044001528181610aa10152611212015260008181610236015281816108ea0152610b250152600081816101da015281816104fa015281816109d101528181610cbc01528181610db30152818161165201526116ef0152612f056000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806387381314116100e3578063a7cd63b71161008c578063d612b94511610066578063d612b9451461042b578063e0351e131461043e578063f2fde38b1461046457600080fd5b8063a7cd63b7146103fd578063b3a3fb4114610405578063c49907b51461041857600080fd5b806396875445116100bd57806396875445146103c25780639c8f9f23146103e2578063a40e69c7146103f557600080fd5b806387381314146103615780638bfca18c146103765780638da5cb5b146103a457600080fd5b806356dd1e81116101455780637787e7ab1161011f5780637787e7ab146102d757806379ba5097146103465780638627fad61461034e57600080fd5b806356dd1e811461026d5780636f32b872146102b15780637448b3c7146102c457600080fd5b806351c6590a1161017657806351c6590a1461021f5780635246492f1461023457806354c8a4f31461025a57600080fd5b806301ffc9a71461019d5780631d7a74a0146101c557806321df0da7146101d8575b600080fd5b6101b06101ab366004612670565b610477565b60405190151581526020015b60405180910390f35b6101b06101d33660046126db565b6104d3565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b61023261022d3660046126f6565b6104e0565b005b7f00000000000000000000000000000000000000000000000000000000000000006101fa565b61023261026836600461275b565b610576565b6102a361027b3660046126db565b73ffffffffffffffffffffffffffffffffffffffff166000908152600a602052604090205490565b6040519081526020016101bc565b6101b06102bf3660046126db565b6105f1565b6102326102d236600461289e565b6105fe565b6102ea6102e53660046126db565b6106ce565b6040516101bc919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6102326107ac565b61023261035c366004612995565b6108a9565b610369610a4c565b6040516101bc9190612a24565b6040517f98a471770000000000000000000000000000000000000000000000000000000081526020016101bc565b60005473ffffffffffffffffffffffffffffffffffffffff166101fa565b6103d56103d0366004612ac0565b610a5d565b6040516101bc9190612bcc565b6102326103f03660046126f6565b610c43565b610369610e0a565b610369610e16565b6102ea6104133660046126db565b610e22565b610232610426366004612c24565b610f00565b61023261043936600461289e565b610f14565b7f00000000000000000000000000000000000000000000000000000000000000006101b0565b6102326104723660046126db565b610fd3565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f98a471770000000000000000000000000000000000000000000000000000000014806104cd57506104cd82610fe7565b92915050565b60006104cd60078361107f565b61052273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846110b1565b336000908152600a602052604081208054839290610541908490612cb3565b9091555050604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b61057e61118d565b6105eb8484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061121092505050565b50505050565b60006104cd60048361107f565b61060661118d565b61060f826105f1565b610662576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260066020526040902061069190826113db565b7f578db78e348076074dbff64a94073a83e9a65aa6766b8c75fdc89282b0e30ed682826040516106c2929190612cc6565b60405180910390a15050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260066020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526104cd9061158a565b60015473ffffffffffffffffffffffffffffffffffffffff16331461082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610659565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6108b2336104d3565b6108e8576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610953573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109779190612d1e565b156109ae576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109b78361163c565b6109f873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168585611676565b60405183815273ffffffffffffffffffffffffffffffffffffffff85169033907f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f529060200160405180910390a35050505050565b6060610a5860046116cc565b905090565b6060610a68336105f1565b610a9e576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b877f00000000000000000000000000000000000000000000000000000000000000008015610ad45750610ad260028261107f565b155b15610b23576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610659565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb29190612d1e565b15610be9576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bf2866116d9565b60405186815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a25050604080516020810190915260008152979650505050505050565b336000908152600a6020526040902054811115610c8c576040517f6982012000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3c9190612d3b565b1015610d74576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a602052604081208054839290610d93908490612d54565b90915550610dda905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611676565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6060610a5860076116cc565b6060610a5860026116cc565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260096020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526104cd9061158a565b610f0861118d565b6105eb84848484611713565b610f1c61118d565b610f25826104d3565b610f73576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610659565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600960205260409020610fa290826113db565b7fb3ba339cfbb8ef80d7a29ce5493051cb90e64fcfa85d7124efc1adfa4c68399f82826040516106c2929190612cc6565b610fdb61118d565b610fe481611cc3565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f317fa3340000000000000000000000000000000000000000000000000000000014806104cd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105eb9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611db8565b60005473ffffffffffffffffffffffffffffffffffffffff16331461120e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610659565b565b7f0000000000000000000000000000000000000000000000000000000000000000611267576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561130557600083828151811061128757611287612d67565b602002602001015190506112a5816002611ec490919063ffffffff16565b156112f45760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506112fe81612d96565b905061126a565b5060005b81518110156113d657600082828151811061132657611326612d67565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361136a57506113c6565b611375600282611ee6565b156113c45760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6113cf81612d96565b9050611309565b505050565b815460009061140490700100000000000000000000000000000000900463ffffffff1642612d54565b905080156114a6576001830154835461144c916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416611f08565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546114cc916fffffffffffffffffffffffffffffffff9081169116611f32565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061157d908490612dce565b60405180910390a1505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261161882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426115fc9190612d54565b85608001516fffffffffffffffffffffffffffffffff16611f08565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b336000908152600960205260409020610fe490827f0000000000000000000000000000000000000000000000000000000000000000611f48565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526113d69084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161110b565b606060006110aa836122cb565b336000908152600660205260409020610fe490827f0000000000000000000000000000000000000000000000000000000000000000611f48565b61171b61118d565b60005b83811015611a3857600085858381811061173a5761173a612d67565b905060a002018036038101906117509190612e0a565b905080602001511561192857805161176a90600490611ee6565b156118db576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526006909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f0b594bb0555ff7b252e0c789ccc9d8903fec294172064308727d570505cee1ac926118ce9291612cc6565b60405180910390a1611a27565b80516040517fd3eb6bc500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610659565b805161193690600490611ec4565b156119da57805173ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517f7fd064821314ad863a0714a3f1229375ace6b6427ed5544b7b2ba1c47b1b5294916118ce9173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b80516040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610659565b50611a3181612d96565b905061171e565b5060005b81811015611cbc576000838383818110611a5857611a58612d67565b905060a00201803603810190611a6e9190612e0a565b9050806020015115611bf9578051611a8890600790611ee6565b156118db576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526009909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f395b7374909d2b54e5796f53c898ebf41d767c86c78ea86519acf2b805852d8892611bec9291612cc6565b60405180910390a1611cab565b8051611c0790600790611ec4565b156119da57805173ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517fcf91daec21e3510e2f2aea4b09d08c235d5c6844980be709f282ef591dbf420c91611bec9173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b50611cb581612d96565b9050611a3c565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611d42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610659565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611e1a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166123279092919063ffffffff16565b8051909150156113d65780806020019051810190611e389190612d1e565b6113d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610659565b60006110aa8373ffffffffffffffffffffffffffffffffffffffff8416612336565b60006110aa8373ffffffffffffffffffffffffffffffffffffffff8416612429565b6000611f2785611f188486612e5b565b611f229087612cb3565b611f32565b90505b949350505050565b6000818310611f4157816110aa565b5090919050565b825474010000000000000000000000000000000000000000900460ff161580611f6f575081155b15611f7957505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090611fbf90700100000000000000000000000000000000900463ffffffff1642612d54565b9050801561207f5781831115612001576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461203b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16611f08565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156121365773ffffffffffffffffffffffffffffffffffffffff84166120de576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610659565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610659565b848310156122495760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061217a9082612d54565b612184878a612d54565b61218e9190612cb3565b6121989190612e72565b905073ffffffffffffffffffffffffffffffffffffffff86166121f1576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610659565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610659565b6122538584612d54565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561231b57602002820191906000526020600020905b815481526020019060010190808311612307575b50505050509050919050565b6060611f2a8484600085612478565b6000818152600183016020526040812054801561241f57600061235a600183612d54565b855490915060009061236e90600190612d54565b90508181146123d357600086600001828154811061238e5761238e612d67565b90600052602060002001549050808760000184815481106123b1576123b1612d67565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806123e4576123e4612ead565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104cd565b60009150506104cd565b6000818152600183016020526040812054612470575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104cd565b5060006104cd565b60608247101561250a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610659565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125339190612edc565b60006040518083038185875af1925050503d8060008114612570576040519150601f19603f3d011682016040523d82523d6000602084013e612575565b606091505b509150915061258687838387612591565b979650505050505050565b606083156126275782516000036126205773ffffffffffffffffffffffffffffffffffffffff85163b612620576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610659565b5081611f2a565b611f2a838381511561263c5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106599190612bcc565b60006020828403121561268257600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146110aa57600080fd5b803573ffffffffffffffffffffffffffffffffffffffff811681146126d657600080fd5b919050565b6000602082840312156126ed57600080fd5b6110aa826126b2565b60006020828403121561270857600080fd5b5035919050565b60008083601f84011261272157600080fd5b50813567ffffffffffffffff81111561273957600080fd5b6020830191508360208260051b850101111561275457600080fd5b9250929050565b6000806000806040858703121561277157600080fd5b843567ffffffffffffffff8082111561278957600080fd5b6127958883890161270f565b909650945060208701359150808211156127ae57600080fd5b506127bb8782880161270f565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612819576128196127c7565b60405290565b8015158114610fe457600080fd5b80356fffffffffffffffffffffffffffffffff811681146126d657600080fd5b60006060828403121561285f57600080fd5b6128676127f6565b905081356128748161281f565b81526128826020830161282d565b60208201526128936040830161282d565b604082015292915050565b600080608083850312156128b157600080fd5b6128ba836126b2565b91506128c9846020850161284d565b90509250929050565b600082601f8301126128e357600080fd5b813567ffffffffffffffff808211156128fe576128fe6127c7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612944576129446127c7565b8160405283815286602085880101111561295d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803567ffffffffffffffff811681146126d657600080fd5b600080600080600060a086880312156129ad57600080fd5b853567ffffffffffffffff808211156129c557600080fd5b6129d189838a016128d2565b96506129df602089016126b2565b9550604088013594506129f46060890161297d565b93506080880135915080821115612a0a57600080fd5b50612a17888289016128d2565b9150509295509295909350565b6020808252825182820181905260009190848201906040850190845b81811015612a7257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612a40565b50909695505050505050565b60008083601f840112612a9057600080fd5b50813567ffffffffffffffff811115612aa857600080fd5b60208301915083602082850101111561275457600080fd5b600080600080600080600060a0888a031215612adb57600080fd5b612ae4886126b2565b9650602088013567ffffffffffffffff80821115612b0157600080fd5b612b0d8b838c01612a7e565b909850965060408a01359550869150612b2860608b0161297d565b945060808a0135915080821115612b3e57600080fd5b50612b4b8a828b01612a7e565b989b979a50959850939692959293505050565b60005b83811015612b79578181015183820152602001612b61565b50506000910152565b60008151808452612b9a816020860160208601612b5e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006110aa6020830184612b82565b60008083601f840112612bf157600080fd5b50813567ffffffffffffffff811115612c0957600080fd5b60208301915083602060a08302850101111561275457600080fd5b60008060008060408587031215612c3a57600080fd5b843567ffffffffffffffff80821115612c5257600080fd5b612c5e88838901612bdf565b90965094506020870135915080821115612c7757600080fd5b506127bb87828801612bdf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104cd576104cd612c84565b73ffffffffffffffffffffffffffffffffffffffff83168152608081016110aa60208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215612d3057600080fd5b81516110aa8161281f565b600060208284031215612d4d57600080fd5b5051919050565b818103818111156104cd576104cd612c84565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612dc757612dc7612c84565b5060010190565b606081016104cd82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060a08284031215612e1c57600080fd5b612e246127f6565b612e2d836126b2565b81526020830135612e3d8161281f565b6020820152612e4f846040850161284d565b60408201529392505050565b80820281158282048414176104cd576104cd612c84565b600082612ea8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251612eee818460208701612b5e565b919091019291505056fea164736f6c6343000813000a", +} + +var LockReleaseTokenPoolABI = LockReleaseTokenPoolMetaData.ABI + +var LockReleaseTokenPoolBin = LockReleaseTokenPoolMetaData.Bin + +func DeployLockReleaseTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, armProxy common.Address) (common.Address, *types.Transaction, *LockReleaseTokenPool, error) { + parsed, err := LockReleaseTokenPoolMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LockReleaseTokenPoolBin), backend, token, allowlist, armProxy) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &LockReleaseTokenPool{LockReleaseTokenPoolCaller: LockReleaseTokenPoolCaller{contract: contract}, LockReleaseTokenPoolTransactor: LockReleaseTokenPoolTransactor{contract: contract}, LockReleaseTokenPoolFilterer: LockReleaseTokenPoolFilterer{contract: contract}}, nil +} + +type LockReleaseTokenPool struct { + address common.Address + abi abi.ABI + LockReleaseTokenPoolCaller + LockReleaseTokenPoolTransactor + LockReleaseTokenPoolFilterer +} + +type LockReleaseTokenPoolCaller struct { + contract *bind.BoundContract +} + +type LockReleaseTokenPoolTransactor struct { + contract *bind.BoundContract +} + +type LockReleaseTokenPoolFilterer struct { + contract *bind.BoundContract +} + +type LockReleaseTokenPoolSession struct { + Contract *LockReleaseTokenPool + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type LockReleaseTokenPoolCallerSession struct { + Contract *LockReleaseTokenPoolCaller + CallOpts bind.CallOpts +} + +type LockReleaseTokenPoolTransactorSession struct { + Contract *LockReleaseTokenPoolTransactor + TransactOpts bind.TransactOpts +} + +type LockReleaseTokenPoolRaw struct { + Contract *LockReleaseTokenPool +} + +type LockReleaseTokenPoolCallerRaw struct { + Contract *LockReleaseTokenPoolCaller +} + +type LockReleaseTokenPoolTransactorRaw struct { + Contract *LockReleaseTokenPoolTransactor +} + +func NewLockReleaseTokenPool(address common.Address, backend bind.ContractBackend) (*LockReleaseTokenPool, error) { + abi, err := abi.JSON(strings.NewReader(LockReleaseTokenPoolABI)) + if err != nil { + return nil, err + } + contract, err := bindLockReleaseTokenPool(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LockReleaseTokenPool{address: address, abi: abi, LockReleaseTokenPoolCaller: LockReleaseTokenPoolCaller{contract: contract}, LockReleaseTokenPoolTransactor: LockReleaseTokenPoolTransactor{contract: contract}, LockReleaseTokenPoolFilterer: LockReleaseTokenPoolFilterer{contract: contract}}, nil +} + +func NewLockReleaseTokenPoolCaller(address common.Address, caller bind.ContractCaller) (*LockReleaseTokenPoolCaller, error) { + contract, err := bindLockReleaseTokenPool(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolCaller{contract: contract}, nil +} + +func NewLockReleaseTokenPoolTransactor(address common.Address, transactor bind.ContractTransactor) (*LockReleaseTokenPoolTransactor, error) { + contract, err := bindLockReleaseTokenPool(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolTransactor{contract: contract}, nil +} + +func NewLockReleaseTokenPoolFilterer(address common.Address, filterer bind.ContractFilterer) (*LockReleaseTokenPoolFilterer, error) { + contract, err := bindLockReleaseTokenPool(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolFilterer{contract: contract}, nil +} + +func bindLockReleaseTokenPool(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LockReleaseTokenPoolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LockReleaseTokenPool.Contract.LockReleaseTokenPoolCaller.contract.Call(opts, result, method, params...) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.LockReleaseTokenPoolTransactor.contract.Transfer(opts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.LockReleaseTokenPoolTransactor.contract.Transact(opts, method, params...) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LockReleaseTokenPool.Contract.contract.Call(opts, result, method, params...) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.contract.Transfer(opts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.contract.Transact(opts, method, params...) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) CurrentOffRampRateLimiterState(opts *bind.CallOpts, offRamp common.Address) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "currentOffRampRateLimiterState", offRamp) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) CurrentOffRampRateLimiterState(offRamp common.Address) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPool.Contract.CurrentOffRampRateLimiterState(&_LockReleaseTokenPool.CallOpts, offRamp) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) CurrentOffRampRateLimiterState(offRamp common.Address) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPool.Contract.CurrentOffRampRateLimiterState(&_LockReleaseTokenPool.CallOpts, offRamp) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) CurrentOnRampRateLimiterState(opts *bind.CallOpts, onRamp common.Address) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "currentOnRampRateLimiterState", onRamp) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) CurrentOnRampRateLimiterState(onRamp common.Address) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPool.Contract.CurrentOnRampRateLimiterState(&_LockReleaseTokenPool.CallOpts, onRamp) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) CurrentOnRampRateLimiterState(onRamp common.Address) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPool.Contract.CurrentOnRampRateLimiterState(&_LockReleaseTokenPool.CallOpts, onRamp) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetAllowList() ([]common.Address, error) { + return _LockReleaseTokenPool.Contract.GetAllowList(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetAllowList() ([]common.Address, error) { + return _LockReleaseTokenPool.Contract.GetAllowList(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetAllowListEnabled() (bool, error) { + return _LockReleaseTokenPool.Contract.GetAllowListEnabled(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetAllowListEnabled() (bool, error) { + return _LockReleaseTokenPool.Contract.GetAllowListEnabled(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetArmProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getArmProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetArmProxy() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetArmProxy(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetArmProxy() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetArmProxy(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetLockReleaseInterfaceId(opts *bind.CallOpts) ([4]byte, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getLockReleaseInterfaceId") + + if err != nil { + return *new([4]byte), err + } + + out0 := *abi.ConvertType(out[0], new([4]byte)).(*[4]byte) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetLockReleaseInterfaceId() ([4]byte, error) { + return _LockReleaseTokenPool.Contract.GetLockReleaseInterfaceId(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetLockReleaseInterfaceId() ([4]byte, error) { + return _LockReleaseTokenPool.Contract.GetLockReleaseInterfaceId(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetOffRamps(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getOffRamps") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetOffRamps() ([]common.Address, error) { + return _LockReleaseTokenPool.Contract.GetOffRamps(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetOffRamps() ([]common.Address, error) { + return _LockReleaseTokenPool.Contract.GetOffRamps(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetOnRamps(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getOnRamps") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetOnRamps() ([]common.Address, error) { + return _LockReleaseTokenPool.Contract.GetOnRamps(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetOnRamps() ([]common.Address, error) { + return _LockReleaseTokenPool.Contract.GetOnRamps(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetProvidedLiquidity(opts *bind.CallOpts, provider common.Address) (*big.Int, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getProvidedLiquidity", provider) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetProvidedLiquidity(provider common.Address) (*big.Int, error) { + return _LockReleaseTokenPool.Contract.GetProvidedLiquidity(&_LockReleaseTokenPool.CallOpts, provider) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetProvidedLiquidity(provider common.Address) (*big.Int, error) { + return _LockReleaseTokenPool.Contract.GetProvidedLiquidity(&_LockReleaseTokenPool.CallOpts, provider) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetToken() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetToken(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetToken() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetToken(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) IsOffRamp(opts *bind.CallOpts, offRamp common.Address) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "isOffRamp", offRamp) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) IsOffRamp(offRamp common.Address) (bool, error) { + return _LockReleaseTokenPool.Contract.IsOffRamp(&_LockReleaseTokenPool.CallOpts, offRamp) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) IsOffRamp(offRamp common.Address) (bool, error) { + return _LockReleaseTokenPool.Contract.IsOffRamp(&_LockReleaseTokenPool.CallOpts, offRamp) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) IsOnRamp(opts *bind.CallOpts, onRamp common.Address) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "isOnRamp", onRamp) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) IsOnRamp(onRamp common.Address) (bool, error) { + return _LockReleaseTokenPool.Contract.IsOnRamp(&_LockReleaseTokenPool.CallOpts, onRamp) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) IsOnRamp(onRamp common.Address) (bool, error) { + return _LockReleaseTokenPool.Contract.IsOnRamp(&_LockReleaseTokenPool.CallOpts, onRamp) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) Owner() (common.Address, error) { + return _LockReleaseTokenPool.Contract.Owner(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) Owner() (common.Address, error) { + return _LockReleaseTokenPool.Contract.Owner(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _LockReleaseTokenPool.Contract.SupportsInterface(&_LockReleaseTokenPool.CallOpts, interfaceId) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _LockReleaseTokenPool.Contract.SupportsInterface(&_LockReleaseTokenPool.CallOpts, interfaceId) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "acceptOwnership") +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) AcceptOwnership() (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.AcceptOwnership(&_LockReleaseTokenPool.TransactOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.AcceptOwnership(&_LockReleaseTokenPool.TransactOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) AddLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "addLiquidity", amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) AddLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.AddLiquidity(&_LockReleaseTokenPool.TransactOpts, amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) AddLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.AddLiquidity(&_LockReleaseTokenPool.TransactOpts, amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyAllowListUpdates(&_LockReleaseTokenPool.TransactOpts, removes, adds) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyAllowListUpdates(&_LockReleaseTokenPool.TransactOpts, removes, adds) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ApplyRampUpdates(opts *bind.TransactOpts, onRamps []TokenPoolRampUpdate, offRamps []TokenPoolRampUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "applyRampUpdates", onRamps, offRamps) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ApplyRampUpdates(onRamps []TokenPoolRampUpdate, offRamps []TokenPoolRampUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyRampUpdates(&_LockReleaseTokenPool.TransactOpts, onRamps, offRamps) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ApplyRampUpdates(onRamps []TokenPoolRampUpdate, offRamps []TokenPoolRampUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyRampUpdates(&_LockReleaseTokenPool.TransactOpts, onRamps, offRamps) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, originalSender common.Address, arg1 []byte, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "lockOrBurn", originalSender, arg1, amount, arg3, arg4) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) LockOrBurn(originalSender common.Address, arg1 []byte, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.LockOrBurn(&_LockReleaseTokenPool.TransactOpts, originalSender, arg1, amount, arg3, arg4) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) LockOrBurn(originalSender common.Address, arg1 []byte, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.LockOrBurn(&_LockReleaseTokenPool.TransactOpts, originalSender, arg1, amount, arg3, arg4) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ReleaseOrMint(opts *bind.TransactOpts, arg0 []byte, receiver common.Address, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "releaseOrMint", arg0, receiver, amount, arg3, arg4) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ReleaseOrMint(arg0 []byte, receiver common.Address, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ReleaseOrMint(&_LockReleaseTokenPool.TransactOpts, arg0, receiver, amount, arg3, arg4) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ReleaseOrMint(arg0 []byte, receiver common.Address, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ReleaseOrMint(&_LockReleaseTokenPool.TransactOpts, arg0, receiver, amount, arg3, arg4) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) RemoveLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "removeLiquidity", amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) RemoveLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.RemoveLiquidity(&_LockReleaseTokenPool.TransactOpts, amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) RemoveLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.RemoveLiquidity(&_LockReleaseTokenPool.TransactOpts, amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetOffRampRateLimiterConfig(opts *bind.TransactOpts, offRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setOffRampRateLimiterConfig", offRamp, config) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetOffRampRateLimiterConfig(offRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetOffRampRateLimiterConfig(&_LockReleaseTokenPool.TransactOpts, offRamp, config) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetOffRampRateLimiterConfig(offRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetOffRampRateLimiterConfig(&_LockReleaseTokenPool.TransactOpts, offRamp, config) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetOnRampRateLimiterConfig(opts *bind.TransactOpts, onRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setOnRampRateLimiterConfig", onRamp, config) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetOnRampRateLimiterConfig(onRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetOnRampRateLimiterConfig(&_LockReleaseTokenPool.TransactOpts, onRamp, config) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetOnRampRateLimiterConfig(onRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetOnRampRateLimiterConfig(&_LockReleaseTokenPool.TransactOpts, onRamp, config) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "transferOwnership", to) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.TransferOwnership(&_LockReleaseTokenPool.TransactOpts, to) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.TransferOwnership(&_LockReleaseTokenPool.TransactOpts, to) +} + +type LockReleaseTokenPoolAllowListAddIterator struct { + Event *LockReleaseTokenPoolAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAllowListAddIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*LockReleaseTokenPoolAllowListAddIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAllowListAddIterator{contract: _LockReleaseTokenPool.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAllowListAdd) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseAllowListAdd(log types.Log) (*LockReleaseTokenPoolAllowListAdd, error) { + event := new(LockReleaseTokenPoolAllowListAdd) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAllowListRemoveIterator struct { + Event *LockReleaseTokenPoolAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*LockReleaseTokenPoolAllowListRemoveIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAllowListRemoveIterator{contract: _LockReleaseTokenPool.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAllowListRemove) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseAllowListRemove(log types.Log) (*LockReleaseTokenPoolAllowListRemove, error) { + event := new(LockReleaseTokenPoolAllowListRemove) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolBurnedIterator struct { + Event *LockReleaseTokenPoolBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolBurnedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolBurnedIterator{contract: _LockReleaseTokenPool.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolBurned) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseBurned(log types.Log) (*LockReleaseTokenPoolBurned, error) { + event := new(LockReleaseTokenPoolBurned) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolLiquidityAddedIterator struct { + Event *LockReleaseTokenPoolLiquidityAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolLiquidityAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolLiquidityAddedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolLiquidityAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolLiquidityAdded struct { + Provider common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterLiquidityAdded(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolLiquidityAddedIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "LiquidityAdded", providerRule, amountRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolLiquidityAddedIterator{contract: _LockReleaseTokenPool.contract, event: "LiquidityAdded", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchLiquidityAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityAdded, provider []common.Address, amount []*big.Int) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "LiquidityAdded", providerRule, amountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolLiquidityAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseLiquidityAdded(log types.Log) (*LockReleaseTokenPoolLiquidityAdded, error) { + event := new(LockReleaseTokenPoolLiquidityAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolLiquidityRemovedIterator struct { + Event *LockReleaseTokenPoolLiquidityRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolLiquidityRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolLiquidityRemovedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolLiquidityRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolLiquidityRemoved struct { + Provider common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterLiquidityRemoved(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolLiquidityRemovedIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "LiquidityRemoved", providerRule, amountRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolLiquidityRemovedIterator{contract: _LockReleaseTokenPool.contract, event: "LiquidityRemoved", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchLiquidityRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityRemoved, provider []common.Address, amount []*big.Int) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "LiquidityRemoved", providerRule, amountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolLiquidityRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseLiquidityRemoved(log types.Log) (*LockReleaseTokenPoolLiquidityRemoved, error) { + event := new(LockReleaseTokenPoolLiquidityRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolLockedIterator struct { + Event *LockReleaseTokenPoolLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolLockedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolLockedIterator{contract: _LockReleaseTokenPool.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolLocked) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseLocked(log types.Log) (*LockReleaseTokenPoolLocked, error) { + event := new(LockReleaseTokenPoolLocked) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolMintedIterator struct { + Event *LockReleaseTokenPoolMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolMintedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolMintedIterator{contract: _LockReleaseTokenPool.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolMinted) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseMinted(log types.Log) (*LockReleaseTokenPoolMinted, error) { + event := new(LockReleaseTokenPoolMinted) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolOffRampAddedIterator struct { + Event *LockReleaseTokenPoolOffRampAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolOffRampAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOffRampAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOffRampAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolOffRampAddedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolOffRampAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolOffRampAdded struct { + OffRamp common.Address + RateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterOffRampAdded(opts *bind.FilterOpts) (*LockReleaseTokenPoolOffRampAddedIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "OffRampAdded") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolOffRampAddedIterator{contract: _LockReleaseTokenPool.contract, event: "OffRampAdded", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchOffRampAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOffRampAdded) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "OffRampAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolOffRampAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OffRampAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseOffRampAdded(log types.Log) (*LockReleaseTokenPoolOffRampAdded, error) { + event := new(LockReleaseTokenPoolOffRampAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OffRampAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolOffRampConfiguredIterator struct { + Event *LockReleaseTokenPoolOffRampConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolOffRampConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOffRampConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOffRampConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolOffRampConfiguredIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolOffRampConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolOffRampConfigured struct { + OffRamp common.Address + RateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterOffRampConfigured(opts *bind.FilterOpts) (*LockReleaseTokenPoolOffRampConfiguredIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "OffRampConfigured") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolOffRampConfiguredIterator{contract: _LockReleaseTokenPool.contract, event: "OffRampConfigured", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchOffRampConfigured(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOffRampConfigured) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "OffRampConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolOffRampConfigured) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OffRampConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseOffRampConfigured(log types.Log) (*LockReleaseTokenPoolOffRampConfigured, error) { + event := new(LockReleaseTokenPoolOffRampConfigured) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OffRampConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolOffRampRemovedIterator struct { + Event *LockReleaseTokenPoolOffRampRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolOffRampRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOffRampRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOffRampRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolOffRampRemovedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolOffRampRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolOffRampRemoved struct { + OffRamp common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterOffRampRemoved(opts *bind.FilterOpts) (*LockReleaseTokenPoolOffRampRemovedIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "OffRampRemoved") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolOffRampRemovedIterator{contract: _LockReleaseTokenPool.contract, event: "OffRampRemoved", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchOffRampRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOffRampRemoved) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "OffRampRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolOffRampRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OffRampRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseOffRampRemoved(log types.Log) (*LockReleaseTokenPoolOffRampRemoved, error) { + event := new(LockReleaseTokenPoolOffRampRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OffRampRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolOnRampAddedIterator struct { + Event *LockReleaseTokenPoolOnRampAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolOnRampAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOnRampAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOnRampAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolOnRampAddedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolOnRampAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolOnRampAdded struct { + OnRamp common.Address + RateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterOnRampAdded(opts *bind.FilterOpts) (*LockReleaseTokenPoolOnRampAddedIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "OnRampAdded") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolOnRampAddedIterator{contract: _LockReleaseTokenPool.contract, event: "OnRampAdded", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchOnRampAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOnRampAdded) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "OnRampAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolOnRampAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OnRampAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseOnRampAdded(log types.Log) (*LockReleaseTokenPoolOnRampAdded, error) { + event := new(LockReleaseTokenPoolOnRampAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OnRampAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolOnRampConfiguredIterator struct { + Event *LockReleaseTokenPoolOnRampConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolOnRampConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOnRampConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOnRampConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolOnRampConfiguredIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolOnRampConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolOnRampConfigured struct { + OnRamp common.Address + RateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterOnRampConfigured(opts *bind.FilterOpts) (*LockReleaseTokenPoolOnRampConfiguredIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "OnRampConfigured") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolOnRampConfiguredIterator{contract: _LockReleaseTokenPool.contract, event: "OnRampConfigured", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchOnRampConfigured(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOnRampConfigured) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "OnRampConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolOnRampConfigured) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OnRampConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseOnRampConfigured(log types.Log) (*LockReleaseTokenPoolOnRampConfigured, error) { + event := new(LockReleaseTokenPoolOnRampConfigured) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OnRampConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolOnRampRemovedIterator struct { + Event *LockReleaseTokenPoolOnRampRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolOnRampRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOnRampRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOnRampRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolOnRampRemovedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolOnRampRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolOnRampRemoved struct { + OnRamp common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterOnRampRemoved(opts *bind.FilterOpts) (*LockReleaseTokenPoolOnRampRemovedIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "OnRampRemoved") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolOnRampRemovedIterator{contract: _LockReleaseTokenPool.contract, event: "OnRampRemoved", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchOnRampRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOnRampRemoved) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "OnRampRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolOnRampRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OnRampRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseOnRampRemoved(log types.Log) (*LockReleaseTokenPoolOnRampRemoved, error) { + event := new(LockReleaseTokenPoolOnRampRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OnRampRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolOwnershipTransferRequestedIterator struct { + Event *LockReleaseTokenPoolOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolOwnershipTransferRequestedIterator{contract: _LockReleaseTokenPool.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolOwnershipTransferRequested) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseOwnershipTransferRequested(log types.Log) (*LockReleaseTokenPoolOwnershipTransferRequested, error) { + event := new(LockReleaseTokenPoolOwnershipTransferRequested) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolOwnershipTransferredIterator struct { + Event *LockReleaseTokenPoolOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolOwnershipTransferredIterator{contract: _LockReleaseTokenPool.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolOwnershipTransferred) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseOwnershipTransferred(log types.Log) (*LockReleaseTokenPoolOwnershipTransferred, error) { + event := new(LockReleaseTokenPoolOwnershipTransferred) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolReleasedIterator struct { + Event *LockReleaseTokenPoolReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolReleasedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolReleasedIterator{contract: _LockReleaseTokenPool.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolReleased) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseReleased(log types.Log) (*LockReleaseTokenPoolReleased, error) { + event := new(LockReleaseTokenPoolReleased) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPool) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _LockReleaseTokenPool.abi.Events["AllowListAdd"].ID: + return _LockReleaseTokenPool.ParseAllowListAdd(log) + case _LockReleaseTokenPool.abi.Events["AllowListRemove"].ID: + return _LockReleaseTokenPool.ParseAllowListRemove(log) + case _LockReleaseTokenPool.abi.Events["Burned"].ID: + return _LockReleaseTokenPool.ParseBurned(log) + case _LockReleaseTokenPool.abi.Events["LiquidityAdded"].ID: + return _LockReleaseTokenPool.ParseLiquidityAdded(log) + case _LockReleaseTokenPool.abi.Events["LiquidityRemoved"].ID: + return _LockReleaseTokenPool.ParseLiquidityRemoved(log) + case _LockReleaseTokenPool.abi.Events["Locked"].ID: + return _LockReleaseTokenPool.ParseLocked(log) + case _LockReleaseTokenPool.abi.Events["Minted"].ID: + return _LockReleaseTokenPool.ParseMinted(log) + case _LockReleaseTokenPool.abi.Events["OffRampAdded"].ID: + return _LockReleaseTokenPool.ParseOffRampAdded(log) + case _LockReleaseTokenPool.abi.Events["OffRampConfigured"].ID: + return _LockReleaseTokenPool.ParseOffRampConfigured(log) + case _LockReleaseTokenPool.abi.Events["OffRampRemoved"].ID: + return _LockReleaseTokenPool.ParseOffRampRemoved(log) + case _LockReleaseTokenPool.abi.Events["OnRampAdded"].ID: + return _LockReleaseTokenPool.ParseOnRampAdded(log) + case _LockReleaseTokenPool.abi.Events["OnRampConfigured"].ID: + return _LockReleaseTokenPool.ParseOnRampConfigured(log) + case _LockReleaseTokenPool.abi.Events["OnRampRemoved"].ID: + return _LockReleaseTokenPool.ParseOnRampRemoved(log) + case _LockReleaseTokenPool.abi.Events["OwnershipTransferRequested"].ID: + return _LockReleaseTokenPool.ParseOwnershipTransferRequested(log) + case _LockReleaseTokenPool.abi.Events["OwnershipTransferred"].ID: + return _LockReleaseTokenPool.ParseOwnershipTransferred(log) + case _LockReleaseTokenPool.abi.Events["Released"].ID: + return _LockReleaseTokenPool.ParseReleased(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (LockReleaseTokenPoolAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (LockReleaseTokenPoolAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (LockReleaseTokenPoolBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (LockReleaseTokenPoolLiquidityAdded) Topic() common.Hash { + return common.HexToHash("0xc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb312088") +} + +func (LockReleaseTokenPoolLiquidityRemoved) Topic() common.Hash { + return common.HexToHash("0xc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf9840171719") +} + +func (LockReleaseTokenPoolLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (LockReleaseTokenPoolMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (LockReleaseTokenPoolOffRampAdded) Topic() common.Hash { + return common.HexToHash("0x395b7374909d2b54e5796f53c898ebf41d767c86c78ea86519acf2b805852d88") +} + +func (LockReleaseTokenPoolOffRampConfigured) Topic() common.Hash { + return common.HexToHash("0xb3ba339cfbb8ef80d7a29ce5493051cb90e64fcfa85d7124efc1adfa4c68399f") +} + +func (LockReleaseTokenPoolOffRampRemoved) Topic() common.Hash { + return common.HexToHash("0xcf91daec21e3510e2f2aea4b09d08c235d5c6844980be709f282ef591dbf420c") +} + +func (LockReleaseTokenPoolOnRampAdded) Topic() common.Hash { + return common.HexToHash("0x0b594bb0555ff7b252e0c789ccc9d8903fec294172064308727d570505cee1ac") +} + +func (LockReleaseTokenPoolOnRampConfigured) Topic() common.Hash { + return common.HexToHash("0x578db78e348076074dbff64a94073a83e9a65aa6766b8c75fdc89282b0e30ed6") +} + +func (LockReleaseTokenPoolOnRampRemoved) Topic() common.Hash { + return common.HexToHash("0x7fd064821314ad863a0714a3f1229375ace6b6427ed5544b7b2ba1c47b1b5294") +} + +func (LockReleaseTokenPoolOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (LockReleaseTokenPoolOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (LockReleaseTokenPoolReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (_LockReleaseTokenPool *LockReleaseTokenPool) Address() common.Address { + return _LockReleaseTokenPool.address +} + +type LockReleaseTokenPoolInterface interface { + CurrentOffRampRateLimiterState(opts *bind.CallOpts, offRamp common.Address) (RateLimiterTokenBucket, error) + + CurrentOnRampRateLimiterState(opts *bind.CallOpts, onRamp common.Address) (RateLimiterTokenBucket, error) + + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetArmProxy(opts *bind.CallOpts) (common.Address, error) + + GetLockReleaseInterfaceId(opts *bind.CallOpts) ([4]byte, error) + + GetOffRamps(opts *bind.CallOpts) ([]common.Address, error) + + GetOnRamps(opts *bind.CallOpts) ([]common.Address, error) + + GetProvidedLiquidity(opts *bind.CallOpts, provider common.Address) (*big.Int, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsOffRamp(opts *bind.CallOpts, offRamp common.Address) (bool, error) + + IsOnRamp(opts *bind.CallOpts, onRamp common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AddLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyRampUpdates(opts *bind.TransactOpts, onRamps []TokenPoolRampUpdate, offRamps []TokenPoolRampUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, originalSender common.Address, arg1 []byte, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, arg0 []byte, receiver common.Address, amount *big.Int, arg3 uint64, arg4 []byte) (*types.Transaction, error) + + RemoveLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + SetOffRampRateLimiterConfig(opts *bind.TransactOpts, offRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) + + SetOnRampRateLimiterConfig(opts *bind.TransactOpts, onRamp common.Address, config RateLimiterConfig) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*LockReleaseTokenPoolAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*LockReleaseTokenPoolAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*LockReleaseTokenPoolAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*LockReleaseTokenPoolAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*LockReleaseTokenPoolBurned, error) + + FilterLiquidityAdded(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolLiquidityAddedIterator, error) + + WatchLiquidityAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityAdded, provider []common.Address, amount []*big.Int) (event.Subscription, error) + + ParseLiquidityAdded(log types.Log) (*LockReleaseTokenPoolLiquidityAdded, error) + + FilterLiquidityRemoved(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolLiquidityRemovedIterator, error) + + WatchLiquidityRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityRemoved, provider []common.Address, amount []*big.Int) (event.Subscription, error) + + ParseLiquidityRemoved(log types.Log) (*LockReleaseTokenPoolLiquidityRemoved, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*LockReleaseTokenPoolLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*LockReleaseTokenPoolMinted, error) + + FilterOffRampAdded(opts *bind.FilterOpts) (*LockReleaseTokenPoolOffRampAddedIterator, error) + + WatchOffRampAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOffRampAdded) (event.Subscription, error) + + ParseOffRampAdded(log types.Log) (*LockReleaseTokenPoolOffRampAdded, error) + + FilterOffRampConfigured(opts *bind.FilterOpts) (*LockReleaseTokenPoolOffRampConfiguredIterator, error) + + WatchOffRampConfigured(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOffRampConfigured) (event.Subscription, error) + + ParseOffRampConfigured(log types.Log) (*LockReleaseTokenPoolOffRampConfigured, error) + + FilterOffRampRemoved(opts *bind.FilterOpts) (*LockReleaseTokenPoolOffRampRemovedIterator, error) + + WatchOffRampRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOffRampRemoved) (event.Subscription, error) + + ParseOffRampRemoved(log types.Log) (*LockReleaseTokenPoolOffRampRemoved, error) + + FilterOnRampAdded(opts *bind.FilterOpts) (*LockReleaseTokenPoolOnRampAddedIterator, error) + + WatchOnRampAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOnRampAdded) (event.Subscription, error) + + ParseOnRampAdded(log types.Log) (*LockReleaseTokenPoolOnRampAdded, error) + + FilterOnRampConfigured(opts *bind.FilterOpts) (*LockReleaseTokenPoolOnRampConfiguredIterator, error) + + WatchOnRampConfigured(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOnRampConfigured) (event.Subscription, error) + + ParseOnRampConfigured(log types.Log) (*LockReleaseTokenPoolOnRampConfigured, error) + + FilterOnRampRemoved(opts *bind.FilterOpts) (*LockReleaseTokenPoolOnRampRemovedIterator, error) + + WatchOnRampRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOnRampRemoved) (event.Subscription, error) + + ParseOnRampRemoved(log types.Log) (*LockReleaseTokenPoolOnRampRemoved, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*LockReleaseTokenPoolOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*LockReleaseTokenPoolOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*LockReleaseTokenPoolReleased, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0/lock_release_token_pool_1_4_0.go b/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0/lock_release_token_pool_1_4_0.go new file mode 100644 index 0000000000..8d3377f25b --- /dev/null +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0/lock_release_token_pool_1_4_0.go @@ -0,0 +1,2712 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package lock_release_token_pool_1_4_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +var LockReleaseTokenPoolMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRatelimitRate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLockReleaseInterfaceId\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"releaseOrMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b5060405162003dd738038062003dd7833981016040819052620000359162000566565b848484833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200016b565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b1562000103576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001565760408051600081526020810190915262000156908462000216565b5050505090151560e05250620006fd92505050565b336001600160a01b03821603620001c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000237576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002cc5760008382815181106200025b576200025b62000689565b602090810291909101015190506200027560028262000387565b15620002b8576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50620002c481620006b5565b90506200023a565b5060005b815181101562000382576000828281518110620002f157620002f162000689565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200031d57506200036f565b6200032a600282620003a7565b156200036d576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6200037a81620006b5565b9050620002d0565b505050565b60006200039e836001600160a01b038416620003be565b90505b92915050565b60006200039e836001600160a01b038416620004c2565b60008181526001830160205260408120548015620004b7576000620003e5600183620006d1565b8554909150600090620003fb90600190620006d1565b9050818114620004675760008660000182815481106200041f576200041f62000689565b906000526020600020015490508087600001848154811062000445576200044562000689565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047b576200047b620006e7565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a1565b6000915050620003a1565b60008181526001830160205260408120546200050b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a1565b506000620003a1565b6001600160a01b03811681146200052a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620005508162000514565b919050565b805180151581146200055057600080fd5b600080600080600060a086880312156200057f57600080fd5b85516200058c8162000514565b602087810151919650906001600160401b0380821115620005ac57600080fd5b818901915089601f830112620005c157600080fd5b815181811115620005d657620005d66200052d565b8060051b604051601f19603f83011681018181108582111715620005fe57620005fe6200052d565b60405291825284820192508381018501918c8311156200061d57600080fd5b938501935b828510156200064657620006368562000543565b8452938501939285019262000622565b8099505050505050506200065d6040870162000543565b92506200066d6060870162000555565b91506200067d6080870162000543565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620006ca57620006ca6200069f565b5060010190565b81810381811115620003a157620003a16200069f565b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e051613653620007846000396000818161047501526118ac0152600081816104e9015281816113320152611bcb0152600081816102b60152818161106301526113b601526000818161025101528181610663015281816107350152818161114b0152818161196e01528181611f0b0152611f9601526136536000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80638bfca18c116100f9578063c0d7865511610097578063cf7401f311610071578063cf7401f3146104d4578063e0351e13146104e7578063eb521a4c1461050d578063f2fde38b1461052057600080fd5b8063c0d7865514610499578063c4bffe2b146104ac578063c75eea9c146104c157600080fd5b8063a7cd63b7116100d3578063a7cd63b7146103d1578063af58d59f146103e6578063b0f479a114610455578063bb98546b1461047357600080fd5b80638bfca18c146103725780638da5cb5b146103a057806396875445146103be57600080fd5b80635995f0631161016657806379ba50971161014057806379ba5097146103315780637d54534e146103395780638627fad61461034c5780638926f54f1461035f57600080fd5b80635995f063146102ed5780636cfd1553146103005780636d3d1a581461031357600080fd5b806321df0da7116101a257806321df0da71461024f578063432a6ba3146102965780635246492f146102b457806354c8a4f3146102da57600080fd5b806301ffc9a7146101c95780630a861f2a146101f1578063181f5a7714610206575b600080fd5b6101dc6101d7366004612d09565b610533565b60405190151581526020015b60405180910390f35b6102046101ff366004612d4b565b6105db565b005b6102426040518060400160405280601a81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e342e3000000000000081525081565b6040516101e89190612dd2565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101e8565b60095473ffffffffffffffffffffffffffffffffffffffff16610271565b7f0000000000000000000000000000000000000000000000000000000000000000610271565b6102046102e8366004612e31565b61078c565b6102046102fb366004612e9d565b610807565b61020461030e366004612f34565b610d9f565b600a5473ffffffffffffffffffffffffffffffffffffffff16610271565b610204610dee565b610204610347366004612f34565b610eeb565b61020461035a366004613048565b610f3a565b6101dc61036d3660046130dc565b6111c7565b6040517f98a471770000000000000000000000000000000000000000000000000000000081526020016101e8565b60005473ffffffffffffffffffffffffffffffffffffffff16610271565b6102426103cc366004613139565b6111de565b6103d96114d6565b6040516101e891906131d9565b6103f96103f43660046130dc565b6114e7565b6040516101e8919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610271565b7f00000000000000000000000000000000000000000000000000000000000000006101dc565b6102046104a7366004612f34565b6115b9565b6104b4611694565b6040516101e89190613233565b6103f96104cf3660046130dc565b611754565b6102046104e2366004613314565b611826565b7f00000000000000000000000000000000000000000000000000000000000000006101dc565b61020461051b366004612d4b565b6118aa565b61020461052e366004612f34565b6119c6565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f98a471770000000000000000000000000000000000000000000000000000000014806105c657507fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000145b806105d557506105d5826119da565b92915050565b60095473ffffffffffffffffffffffffffffffffffffffff163314610633576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156106bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e39190613359565b101561071b576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61075c73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611a72565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b610794611b46565b61080184848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611bc992505050565b50505050565b61080f611b46565b60005b81811015610d9a57600083838381811061082e5761082e613372565b9050610100020180360381019061084591906133a1565b905061085a8160400151826020015115611d8f565b61086d8160600151826020015115611d8f565b806020015115610c8e57805161088f9060059067ffffffffffffffff16611ecc565b6108d45780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161062a565b6040518060a001604052808260400151602001516fffffffffffffffffffffffffffffffff1681526020014263ffffffff168152602001826040015160000151151581526020018260400151602001516fffffffffffffffffffffffffffffffff1681526020018260400151604001516fffffffffffffffffffffffffffffffff1681525060076000836000015167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160146101000a81548160ff02191690831515021790555060608201518160010160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060808201518160010160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055509050506040518060a001604052808260600151602001516fffffffffffffffffffffffffffffffff1681526020014263ffffffff168152602001826060015160000151151581526020018260600151602001516fffffffffffffffffffffffffffffffff1681526020018260600151604001516fffffffffffffffffffffffffffffffff1681525060086000836000015167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160146101000a81548160ff02191690831515021790555060608201518160010160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060808201518160010160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055509050507f0f135cbb9afa12a8bf3bbd071c117bcca4ddeca6160ef7f33d012a81b9c0c471816000015182604001518360600151604051610c8193929190613423565b60405180910390a1610d89565b8051610ca69060059067ffffffffffffffff16611edf565b610ceb5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161062a565b805167ffffffffffffffff908116600090815260086020908152604080832080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600191820185905586518616855260078452828520805490911681550192909255835191519190921681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916910160405180910390a15b50610d93816134d5565b9050610812565b505050565b610da7611b46565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161062a565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ef3611b46565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b81610f44816111c7565b610f86576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161062a565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015611005573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611029919061350d565b611061576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161062a565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f0919061350d565b15611127576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111318385611eeb565b61117273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168686611a72565b60405184815273ffffffffffffffffffffffffffffffffffffffff86169033907f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f529060200160405180910390a3505050505050565b60006105d5600567ffffffffffffffff8416611f2f565b6060836111ea816111c7565b61122c576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161062a565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156112a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c9919061352a565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132f576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161062a565b887f000000000000000000000000000000000000000000000000000000000000000080156113655750611363600282611f47565b155b156113b4576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161062a565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561141f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611443919061350d565b1561147a576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114848688611f76565b60405187815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a2505060408051602081019091526000815298975050505050505050565b60606114e26002611fba565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260086020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105d590611fc7565b6115c1611b46565b73ffffffffffffffffffffffffffffffffffffffff811661160e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006116a26005611fba565b90506000815167ffffffffffffffff8111156116c0576116c0612f51565b6040519080825280602002602001820160405280156116e9578160200160208202803683370190505b50905060005b825181101561174d5782818151811061170a5761170a613372565b602002602001015182828151811061172457611724613372565b67ffffffffffffffff90921660209283029190910190910152611746816134d5565b90506116ef565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105d590611fc7565b600a5473ffffffffffffffffffffffffffffffffffffffff163314801590611866575060005473ffffffffffffffffffffffffffffffffffffffff163314155b1561189f576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161062a565b610d9a838383612079565b7f0000000000000000000000000000000000000000000000000000000000000000611901576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff163314611954576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161062a565b61199673ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612160565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b6119ce611b46565b6119d7816121be565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f317fa3340000000000000000000000000000000000000000000000000000000014806105d557507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610d9a9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526122b3565b60005473ffffffffffffffffffffffffffffffffffffffff163314611bc7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161062a565b565b7f0000000000000000000000000000000000000000000000000000000000000000611c20576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611cbe576000838281518110611c4057611c40613372565b60200260200101519050611c5e8160026123bf90919063ffffffff16565b15611cad5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50611cb7816134d5565b9050611c23565b5060005b8151811015610d9a576000828281518110611cdf57611cdf613372565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d235750611d7f565b611d2e6002826123e1565b15611d7d5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b611d88816134d5565b9050611cc2565b815115611e5a5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611de5575060408201516fffffffffffffffffffffffffffffffff16155b15611e1e57816040517f70505e5600000000000000000000000000000000000000000000000000000000815260040161062a9190613547565b8015611e56576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580611e93575060208201516fffffffffffffffffffffffffffffffff1615155b15611e5657816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161062a9190613547565b6000611ed883836123ff565b9392505050565b6000611ed8838361244e565b67ffffffffffffffff82166000908152600860205260409020611e5690827f0000000000000000000000000000000000000000000000000000000000000000612541565b60008181526001830160205260408120541515611ed8565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611ed8565b67ffffffffffffffff82166000908152600760205260409020611e5690827f0000000000000000000000000000000000000000000000000000000000000000612541565b60606000611ed8836128c4565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261205582606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426120399190613583565b85608001516fffffffffffffffffffffffffffffffff16612920565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b612082836111c7565b6120c4576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161062a565b6120cf826000611d8f565b67ffffffffffffffff831660009081526007602052604090206120f2908361294a565b6120fd816000611d8f565b67ffffffffffffffff83166000908152600860205260409020612120908261294a565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161215393929190613423565b60405180910390a1505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526108019085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611ac4565b3373ffffffffffffffffffffffffffffffffffffffff82160361223d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161062a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612315826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612aec9092919063ffffffff16565b805190915015610d9a5780806020019051810190612333919061350d565b610d9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161062a565b6000611ed88373ffffffffffffffffffffffffffffffffffffffff841661244e565b6000611ed88373ffffffffffffffffffffffffffffffffffffffff84165b6000818152600183016020526040812054612446575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105d5565b5060006105d5565b60008181526001830160205260408120548015612537576000612472600183613583565b855490915060009061248690600190613583565b90508181146124eb5760008660000182815481106124a6576124a6613372565b90600052602060002001549050808760000184815481106124c9576124c9613372565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806124fc576124fc613596565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105d5565b60009150506105d5565b825474010000000000000000000000000000000000000000900460ff161580612568575081155b1561257257505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906125b890700100000000000000000000000000000000900463ffffffff1642613583565b9050801561267857818311156125fa576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546126349083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612920565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561272f5773ffffffffffffffffffffffffffffffffffffffff84166126d7576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161062a565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161062a565b848310156128425760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906127739082613583565b61277d878a613583565b61278791906135c5565b61279191906135d8565b905073ffffffffffffffffffffffffffffffffffffffff86166127ea576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161062a565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161062a565b61284c8584613583565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561291457602002820191906000526020600020905b815481526020019060010190808311612900575b50505050509050919050565b600061293f856129308486613613565b61293a90876135c5565b612afb565b90505b949350505050565b815460009061297390700100000000000000000000000000000000900463ffffffff1642613583565b90508015612a1557600183015483546129bb916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612920565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612a3b916fffffffffffffffffffffffffffffffff9081169116612afb565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612153908490613547565b60606129428484600085612b11565b6000818310612b0a5781611ed8565b5090919050565b606082471015612ba3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161062a565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612bcc919061362a565b60006040518083038185875af1925050503d8060008114612c09576040519150601f19603f3d011682016040523d82523d6000602084013e612c0e565b606091505b5091509150612c1f87838387612c2a565b979650505050505050565b60608315612cc0578251600003612cb95773ffffffffffffffffffffffffffffffffffffffff85163b612cb9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161062a565b5081612942565b6129428383815115612cd55781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062a9190612dd2565b600060208284031215612d1b57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611ed857600080fd5b600060208284031215612d5d57600080fd5b5035919050565b60005b83811015612d7f578181015183820152602001612d67565b50506000910152565b60008151808452612da0816020860160208601612d64565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611ed86020830184612d88565b60008083601f840112612df757600080fd5b50813567ffffffffffffffff811115612e0f57600080fd5b6020830191508360208260051b8501011115612e2a57600080fd5b9250929050565b60008060008060408587031215612e4757600080fd5b843567ffffffffffffffff80821115612e5f57600080fd5b612e6b88838901612de5565b90965094506020870135915080821115612e8457600080fd5b50612e9187828801612de5565b95989497509550505050565b60008060208385031215612eb057600080fd5b823567ffffffffffffffff80821115612ec857600080fd5b818501915085601f830112612edc57600080fd5b813581811115612eeb57600080fd5b8660208260081b8501011115612f0057600080fd5b60209290920196919550909350505050565b73ffffffffffffffffffffffffffffffffffffffff811681146119d757600080fd5b600060208284031215612f4657600080fd5b8135611ed881612f12565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612f9157600080fd5b813567ffffffffffffffff80821115612fac57612fac612f51565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ff257612ff2612f51565b8160405283815286602085880101111561300b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803567ffffffffffffffff8116811461304357600080fd5b919050565b600080600080600060a0868803121561306057600080fd5b853567ffffffffffffffff8082111561307857600080fd5b61308489838a01612f80565b96506020880135915061309682612f12565b819550604088013594506130ac6060890161302b565b935060808801359150808211156130c257600080fd5b506130cf88828901612f80565b9150509295509295909350565b6000602082840312156130ee57600080fd5b611ed88261302b565b60008083601f84011261310957600080fd5b50813567ffffffffffffffff81111561312157600080fd5b602083019150836020828501011115612e2a57600080fd5b600080600080600080600060a0888a03121561315457600080fd5b873561315f81612f12565b9650602088013567ffffffffffffffff8082111561317c57600080fd5b6131888b838c016130f7565b909850965060408a013595508691506131a360608b0161302b565b945060808a01359150808211156131b957600080fd5b506131c68a828b016130f7565b989b979a50959850939692959293505050565b6020808252825182820181905260009190848201906040850190845b8181101561322757835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016131f5565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561322757835167ffffffffffffffff168352928401929184019160010161324f565b80151581146119d757600080fd5b80356fffffffffffffffffffffffffffffffff8116811461304357600080fd5b6000606082840312156132b557600080fd5b6040516060810181811067ffffffffffffffff821117156132d8576132d8612f51565b60405290508082356132e981613275565b81526132f760208401613283565b602082015261330860408401613283565b60408201525092915050565b600080600060e0848603121561332957600080fd5b6133328461302b565b925061334185602086016132a3565b915061335085608086016132a3565b90509250925092565b60006020828403121561336b57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061010082840312156133b457600080fd5b6040516080810181811067ffffffffffffffff821117156133d7576133d7612f51565b6040526133e38361302b565b815260208301356133f381613275565b602082015261340584604085016132a3565b60408201526134178460a085016132a3565b60608201529392505050565b67ffffffffffffffff8416815260e0810161346f60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612942565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613506576135066134a6565b5060010190565b60006020828403121561351f57600080fd5b8151611ed881613275565b60006020828403121561353c57600080fd5b8151611ed881612f12565b606081016105d582848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b818103818111156105d5576105d56134a6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b808201808211156105d5576105d56134a6565b60008261360e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176105d5576105d56134a6565b6000825161363c818460208701612d64565b919091019291505056fea164736f6c6343000813000a", +} + +var LockReleaseTokenPoolABI = LockReleaseTokenPoolMetaData.ABI + +var LockReleaseTokenPoolBin = LockReleaseTokenPoolMetaData.Bin + +func DeployLockReleaseTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, armProxy common.Address, acceptLiquidity bool, router common.Address) (common.Address, *types.Transaction, *LockReleaseTokenPool, error) { + parsed, err := LockReleaseTokenPoolMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LockReleaseTokenPoolBin), backend, token, allowlist, armProxy, acceptLiquidity, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &LockReleaseTokenPool{address: address, abi: *parsed, LockReleaseTokenPoolCaller: LockReleaseTokenPoolCaller{contract: contract}, LockReleaseTokenPoolTransactor: LockReleaseTokenPoolTransactor{contract: contract}, LockReleaseTokenPoolFilterer: LockReleaseTokenPoolFilterer{contract: contract}}, nil +} + +type LockReleaseTokenPool struct { + address common.Address + abi abi.ABI + LockReleaseTokenPoolCaller + LockReleaseTokenPoolTransactor + LockReleaseTokenPoolFilterer +} + +type LockReleaseTokenPoolCaller struct { + contract *bind.BoundContract +} + +type LockReleaseTokenPoolTransactor struct { + contract *bind.BoundContract +} + +type LockReleaseTokenPoolFilterer struct { + contract *bind.BoundContract +} + +type LockReleaseTokenPoolSession struct { + Contract *LockReleaseTokenPool + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type LockReleaseTokenPoolCallerSession struct { + Contract *LockReleaseTokenPoolCaller + CallOpts bind.CallOpts +} + +type LockReleaseTokenPoolTransactorSession struct { + Contract *LockReleaseTokenPoolTransactor + TransactOpts bind.TransactOpts +} + +type LockReleaseTokenPoolRaw struct { + Contract *LockReleaseTokenPool +} + +type LockReleaseTokenPoolCallerRaw struct { + Contract *LockReleaseTokenPoolCaller +} + +type LockReleaseTokenPoolTransactorRaw struct { + Contract *LockReleaseTokenPoolTransactor +} + +func NewLockReleaseTokenPool(address common.Address, backend bind.ContractBackend) (*LockReleaseTokenPool, error) { + abi, err := abi.JSON(strings.NewReader(LockReleaseTokenPoolABI)) + if err != nil { + return nil, err + } + contract, err := bindLockReleaseTokenPool(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LockReleaseTokenPool{address: address, abi: abi, LockReleaseTokenPoolCaller: LockReleaseTokenPoolCaller{contract: contract}, LockReleaseTokenPoolTransactor: LockReleaseTokenPoolTransactor{contract: contract}, LockReleaseTokenPoolFilterer: LockReleaseTokenPoolFilterer{contract: contract}}, nil +} + +func NewLockReleaseTokenPoolCaller(address common.Address, caller bind.ContractCaller) (*LockReleaseTokenPoolCaller, error) { + contract, err := bindLockReleaseTokenPool(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolCaller{contract: contract}, nil +} + +func NewLockReleaseTokenPoolTransactor(address common.Address, transactor bind.ContractTransactor) (*LockReleaseTokenPoolTransactor, error) { + contract, err := bindLockReleaseTokenPool(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolTransactor{contract: contract}, nil +} + +func NewLockReleaseTokenPoolFilterer(address common.Address, filterer bind.ContractFilterer) (*LockReleaseTokenPoolFilterer, error) { + contract, err := bindLockReleaseTokenPool(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolFilterer{contract: contract}, nil +} + +func bindLockReleaseTokenPool(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LockReleaseTokenPoolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LockReleaseTokenPool.Contract.LockReleaseTokenPoolCaller.contract.Call(opts, result, method, params...) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.LockReleaseTokenPoolTransactor.contract.Transfer(opts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.LockReleaseTokenPoolTransactor.contract.Transact(opts, method, params...) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LockReleaseTokenPool.Contract.contract.Call(opts, result, method, params...) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.contract.Transfer(opts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.contract.Transact(opts, method, params...) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) CanAcceptLiquidity(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "canAcceptLiquidity") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) CanAcceptLiquidity() (bool, error) { + return _LockReleaseTokenPool.Contract.CanAcceptLiquidity(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) CanAcceptLiquidity() (bool, error) { + return _LockReleaseTokenPool.Contract.CanAcceptLiquidity(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetAllowList() ([]common.Address, error) { + return _LockReleaseTokenPool.Contract.GetAllowList(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetAllowList() ([]common.Address, error) { + return _LockReleaseTokenPool.Contract.GetAllowList(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetAllowListEnabled() (bool, error) { + return _LockReleaseTokenPool.Contract.GetAllowListEnabled(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetAllowListEnabled() (bool, error) { + return _LockReleaseTokenPool.Contract.GetAllowListEnabled(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetArmProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getArmProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetArmProxy() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetArmProxy(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetArmProxy() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetArmProxy(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPool.Contract.GetCurrentInboundRateLimiterState(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPool.Contract.GetCurrentInboundRateLimiterState(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetLockReleaseInterfaceId(opts *bind.CallOpts) ([4]byte, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getLockReleaseInterfaceId") + + if err != nil { + return *new([4]byte), err + } + + out0 := *abi.ConvertType(out[0], new([4]byte)).(*[4]byte) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetLockReleaseInterfaceId() ([4]byte, error) { + return _LockReleaseTokenPool.Contract.GetLockReleaseInterfaceId(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetLockReleaseInterfaceId() ([4]byte, error) { + return _LockReleaseTokenPool.Contract.GetLockReleaseInterfaceId(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getRateLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetRateLimitAdmin() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRateLimitAdmin(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetRateLimitAdmin() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRateLimitAdmin(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetRebalancer(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getRebalancer") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetRebalancer() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRebalancer(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetRebalancer() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRebalancer(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetRouter() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRouter(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetRouter() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetRouter(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetSupportedChains() ([]uint64, error) { + return _LockReleaseTokenPool.Contract.GetSupportedChains(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetSupportedChains() ([]uint64, error) { + return _LockReleaseTokenPool.Contract.GetSupportedChains(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetToken() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetToken(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetToken() (common.Address, error) { + return _LockReleaseTokenPool.Contract.GetToken(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _LockReleaseTokenPool.Contract.IsSupportedChain(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _LockReleaseTokenPool.Contract.IsSupportedChain(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) Owner() (common.Address, error) { + return _LockReleaseTokenPool.Contract.Owner(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) Owner() (common.Address, error) { + return _LockReleaseTokenPool.Contract.Owner(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _LockReleaseTokenPool.Contract.SupportsInterface(&_LockReleaseTokenPool.CallOpts, interfaceId) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _LockReleaseTokenPool.Contract.SupportsInterface(&_LockReleaseTokenPool.CallOpts, interfaceId) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) TypeAndVersion() (string, error) { + return _LockReleaseTokenPool.Contract.TypeAndVersion(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) TypeAndVersion() (string, error) { + return _LockReleaseTokenPool.Contract.TypeAndVersion(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "acceptOwnership") +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) AcceptOwnership() (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.AcceptOwnership(&_LockReleaseTokenPool.TransactOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.AcceptOwnership(&_LockReleaseTokenPool.TransactOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyAllowListUpdates(&_LockReleaseTokenPool.TransactOpts, removes, adds) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyAllowListUpdates(&_LockReleaseTokenPool.TransactOpts, removes, adds) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyChainUpdates(&_LockReleaseTokenPool.TransactOpts, chains) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyChainUpdates(&_LockReleaseTokenPool.TransactOpts, chains) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, originalSender common.Address, arg1 []byte, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "lockOrBurn", originalSender, arg1, amount, remoteChainSelector, arg4) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) LockOrBurn(originalSender common.Address, arg1 []byte, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.LockOrBurn(&_LockReleaseTokenPool.TransactOpts, originalSender, arg1, amount, remoteChainSelector, arg4) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) LockOrBurn(originalSender common.Address, arg1 []byte, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.LockOrBurn(&_LockReleaseTokenPool.TransactOpts, originalSender, arg1, amount, remoteChainSelector, arg4) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ProvideLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "provideLiquidity", amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ProvideLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ProvideLiquidity(&_LockReleaseTokenPool.TransactOpts, amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ProvideLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ProvideLiquidity(&_LockReleaseTokenPool.TransactOpts, amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ReleaseOrMint(opts *bind.TransactOpts, arg0 []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "releaseOrMint", arg0, receiver, amount, remoteChainSelector, arg4) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ReleaseOrMint(arg0 []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ReleaseOrMint(&_LockReleaseTokenPool.TransactOpts, arg0, receiver, amount, remoteChainSelector, arg4) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ReleaseOrMint(arg0 []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ReleaseOrMint(&_LockReleaseTokenPool.TransactOpts, arg0, receiver, amount, remoteChainSelector, arg4) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetChainRateLimiterConfig(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetChainRateLimiterConfig(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRateLimitAdmin(&_LockReleaseTokenPool.TransactOpts, rateLimitAdmin) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRateLimitAdmin(&_LockReleaseTokenPool.TransactOpts, rateLimitAdmin) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetRebalancer(opts *bind.TransactOpts, rebalancer common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setRebalancer", rebalancer) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetRebalancer(rebalancer common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRebalancer(&_LockReleaseTokenPool.TransactOpts, rebalancer) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetRebalancer(rebalancer common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRebalancer(&_LockReleaseTokenPool.TransactOpts, rebalancer) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setRouter", newRouter) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRouter(&_LockReleaseTokenPool.TransactOpts, newRouter) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetRouter(&_LockReleaseTokenPool.TransactOpts, newRouter) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "transferOwnership", to) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.TransferOwnership(&_LockReleaseTokenPool.TransactOpts, to) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.TransferOwnership(&_LockReleaseTokenPool.TransactOpts, to) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) WithdrawLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "withdrawLiquidity", amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) WithdrawLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.WithdrawLiquidity(&_LockReleaseTokenPool.TransactOpts, amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) WithdrawLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.WithdrawLiquidity(&_LockReleaseTokenPool.TransactOpts, amount) +} + +type LockReleaseTokenPoolAllowListAddIterator struct { + Event *LockReleaseTokenPoolAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAllowListAddIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*LockReleaseTokenPoolAllowListAddIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAllowListAddIterator{contract: _LockReleaseTokenPool.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAllowListAdd) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseAllowListAdd(log types.Log) (*LockReleaseTokenPoolAllowListAdd, error) { + event := new(LockReleaseTokenPoolAllowListAdd) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAllowListRemoveIterator struct { + Event *LockReleaseTokenPoolAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*LockReleaseTokenPoolAllowListRemoveIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAllowListRemoveIterator{contract: _LockReleaseTokenPool.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAllowListRemove) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseAllowListRemove(log types.Log) (*LockReleaseTokenPoolAllowListRemove, error) { + event := new(LockReleaseTokenPoolAllowListRemove) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolBurnedIterator struct { + Event *LockReleaseTokenPoolBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolBurnedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolBurnedIterator{contract: _LockReleaseTokenPool.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolBurned) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseBurned(log types.Log) (*LockReleaseTokenPoolBurned, error) { + event := new(LockReleaseTokenPoolBurned) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolChainAddedIterator struct { + Event *LockReleaseTokenPoolChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolChainAddedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolChainAdded struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterChainAdded(opts *bind.FilterOpts) (*LockReleaseTokenPoolChainAddedIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolChainAddedIterator{contract: _LockReleaseTokenPool.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolChainAdded) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolChainAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseChainAdded(log types.Log) (*LockReleaseTokenPoolChainAdded, error) { + event := new(LockReleaseTokenPoolChainAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolChainConfiguredIterator struct { + Event *LockReleaseTokenPoolChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*LockReleaseTokenPoolChainConfiguredIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolChainConfiguredIterator{contract: _LockReleaseTokenPool.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolChainConfigured) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolChainConfigured) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseChainConfigured(log types.Log) (*LockReleaseTokenPoolChainConfigured, error) { + event := new(LockReleaseTokenPoolChainConfigured) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolChainRemovedIterator struct { + Event *LockReleaseTokenPoolChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolChainRemovedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*LockReleaseTokenPoolChainRemovedIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolChainRemovedIterator{contract: _LockReleaseTokenPool.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolChainRemoved) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolChainRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseChainRemoved(log types.Log) (*LockReleaseTokenPoolChainRemoved, error) { + event := new(LockReleaseTokenPoolChainRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolLiquidityAddedIterator struct { + Event *LockReleaseTokenPoolLiquidityAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolLiquidityAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolLiquidityAddedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolLiquidityAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolLiquidityAdded struct { + Provider common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterLiquidityAdded(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolLiquidityAddedIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "LiquidityAdded", providerRule, amountRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolLiquidityAddedIterator{contract: _LockReleaseTokenPool.contract, event: "LiquidityAdded", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchLiquidityAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityAdded, provider []common.Address, amount []*big.Int) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "LiquidityAdded", providerRule, amountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolLiquidityAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseLiquidityAdded(log types.Log) (*LockReleaseTokenPoolLiquidityAdded, error) { + event := new(LockReleaseTokenPoolLiquidityAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolLiquidityRemovedIterator struct { + Event *LockReleaseTokenPoolLiquidityRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolLiquidityRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolLiquidityRemovedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolLiquidityRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolLiquidityRemoved struct { + Provider common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterLiquidityRemoved(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolLiquidityRemovedIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "LiquidityRemoved", providerRule, amountRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolLiquidityRemovedIterator{contract: _LockReleaseTokenPool.contract, event: "LiquidityRemoved", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchLiquidityRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityRemoved, provider []common.Address, amount []*big.Int) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "LiquidityRemoved", providerRule, amountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolLiquidityRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseLiquidityRemoved(log types.Log) (*LockReleaseTokenPoolLiquidityRemoved, error) { + event := new(LockReleaseTokenPoolLiquidityRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolLockedIterator struct { + Event *LockReleaseTokenPoolLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolLockedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolLockedIterator{contract: _LockReleaseTokenPool.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolLocked) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseLocked(log types.Log) (*LockReleaseTokenPoolLocked, error) { + event := new(LockReleaseTokenPoolLocked) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolMintedIterator struct { + Event *LockReleaseTokenPoolMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolMintedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolMintedIterator{contract: _LockReleaseTokenPool.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolMinted) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseMinted(log types.Log) (*LockReleaseTokenPoolMinted, error) { + event := new(LockReleaseTokenPoolMinted) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolOwnershipTransferRequestedIterator struct { + Event *LockReleaseTokenPoolOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolOwnershipTransferRequestedIterator{contract: _LockReleaseTokenPool.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolOwnershipTransferRequested) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseOwnershipTransferRequested(log types.Log) (*LockReleaseTokenPoolOwnershipTransferRequested, error) { + event := new(LockReleaseTokenPoolOwnershipTransferRequested) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolOwnershipTransferredIterator struct { + Event *LockReleaseTokenPoolOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolOwnershipTransferredIterator{contract: _LockReleaseTokenPool.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolOwnershipTransferred) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseOwnershipTransferred(log types.Log) (*LockReleaseTokenPoolOwnershipTransferred, error) { + event := new(LockReleaseTokenPoolOwnershipTransferred) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolReleasedIterator struct { + Event *LockReleaseTokenPoolReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolReleasedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolReleasedIterator{contract: _LockReleaseTokenPool.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolReleased) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseReleased(log types.Log) (*LockReleaseTokenPoolReleased, error) { + event := new(LockReleaseTokenPoolReleased) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolRouterUpdatedIterator struct { + Event *LockReleaseTokenPoolRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*LockReleaseTokenPoolRouterUpdatedIterator, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolRouterUpdatedIterator{contract: _LockReleaseTokenPool.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolRouterUpdated) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseRouterUpdated(log types.Log) (*LockReleaseTokenPoolRouterUpdated, error) { + event := new(LockReleaseTokenPoolRouterUpdated) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPool) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _LockReleaseTokenPool.abi.Events["AllowListAdd"].ID: + return _LockReleaseTokenPool.ParseAllowListAdd(log) + case _LockReleaseTokenPool.abi.Events["AllowListRemove"].ID: + return _LockReleaseTokenPool.ParseAllowListRemove(log) + case _LockReleaseTokenPool.abi.Events["Burned"].ID: + return _LockReleaseTokenPool.ParseBurned(log) + case _LockReleaseTokenPool.abi.Events["ChainAdded"].ID: + return _LockReleaseTokenPool.ParseChainAdded(log) + case _LockReleaseTokenPool.abi.Events["ChainConfigured"].ID: + return _LockReleaseTokenPool.ParseChainConfigured(log) + case _LockReleaseTokenPool.abi.Events["ChainRemoved"].ID: + return _LockReleaseTokenPool.ParseChainRemoved(log) + case _LockReleaseTokenPool.abi.Events["LiquidityAdded"].ID: + return _LockReleaseTokenPool.ParseLiquidityAdded(log) + case _LockReleaseTokenPool.abi.Events["LiquidityRemoved"].ID: + return _LockReleaseTokenPool.ParseLiquidityRemoved(log) + case _LockReleaseTokenPool.abi.Events["Locked"].ID: + return _LockReleaseTokenPool.ParseLocked(log) + case _LockReleaseTokenPool.abi.Events["Minted"].ID: + return _LockReleaseTokenPool.ParseMinted(log) + case _LockReleaseTokenPool.abi.Events["OwnershipTransferRequested"].ID: + return _LockReleaseTokenPool.ParseOwnershipTransferRequested(log) + case _LockReleaseTokenPool.abi.Events["OwnershipTransferred"].ID: + return _LockReleaseTokenPool.ParseOwnershipTransferred(log) + case _LockReleaseTokenPool.abi.Events["Released"].ID: + return _LockReleaseTokenPool.ParseReleased(log) + case _LockReleaseTokenPool.abi.Events["RouterUpdated"].ID: + return _LockReleaseTokenPool.ParseRouterUpdated(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (LockReleaseTokenPoolAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (LockReleaseTokenPoolAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (LockReleaseTokenPoolBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (LockReleaseTokenPoolChainAdded) Topic() common.Hash { + return common.HexToHash("0x0f135cbb9afa12a8bf3bbd071c117bcca4ddeca6160ef7f33d012a81b9c0c471") +} + +func (LockReleaseTokenPoolChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (LockReleaseTokenPoolChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (LockReleaseTokenPoolLiquidityAdded) Topic() common.Hash { + return common.HexToHash("0xc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb312088") +} + +func (LockReleaseTokenPoolLiquidityRemoved) Topic() common.Hash { + return common.HexToHash("0xc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf9840171719") +} + +func (LockReleaseTokenPoolLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (LockReleaseTokenPoolMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (LockReleaseTokenPoolOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (LockReleaseTokenPoolOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (LockReleaseTokenPoolReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (LockReleaseTokenPoolRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (_LockReleaseTokenPool *LockReleaseTokenPool) Address() common.Address { + return _LockReleaseTokenPool.address +} + +type LockReleaseTokenPoolInterface interface { + CanAcceptLiquidity(opts *bind.CallOpts) (bool, error) + + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetArmProxy(opts *bind.CallOpts) (common.Address, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetLockReleaseInterfaceId(opts *bind.CallOpts) ([4]byte, error) + + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) + + GetRebalancer(opts *bind.CallOpts) (common.Address, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, originalSender common.Address, arg1 []byte, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) + + ProvideLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, arg0 []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) + + SetRebalancer(opts *bind.TransactOpts, rebalancer common.Address) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + WithdrawLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*LockReleaseTokenPoolAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*LockReleaseTokenPoolAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*LockReleaseTokenPoolAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*LockReleaseTokenPoolAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*LockReleaseTokenPoolBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*LockReleaseTokenPoolChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*LockReleaseTokenPoolChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*LockReleaseTokenPoolChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*LockReleaseTokenPoolChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*LockReleaseTokenPoolChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*LockReleaseTokenPoolChainRemoved, error) + + FilterLiquidityAdded(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolLiquidityAddedIterator, error) + + WatchLiquidityAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityAdded, provider []common.Address, amount []*big.Int) (event.Subscription, error) + + ParseLiquidityAdded(log types.Log) (*LockReleaseTokenPoolLiquidityAdded, error) + + FilterLiquidityRemoved(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolLiquidityRemovedIterator, error) + + WatchLiquidityRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityRemoved, provider []common.Address, amount []*big.Int) (event.Subscription, error) + + ParseLiquidityRemoved(log types.Log) (*LockReleaseTokenPoolLiquidityRemoved, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*LockReleaseTokenPoolLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*LockReleaseTokenPoolMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*LockReleaseTokenPoolOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*LockReleaseTokenPoolOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*LockReleaseTokenPoolReleased, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*LockReleaseTokenPoolRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*LockReleaseTokenPoolRouterUpdated, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go new file mode 100644 index 0000000000..15dd411741 --- /dev/null +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go @@ -0,0 +1,3396 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package lock_release_token_pool_and_proxy + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type PoolLockOrBurnInV1 struct { + Receiver []byte + RemoteChainSelector uint64 + OriginalSender common.Address + Amount *big.Int + LocalToken common.Address +} + +type PoolLockOrBurnOutV1 struct { + DestTokenAddress []byte + DestPoolData []byte +} + +type PoolReleaseOrMintInV1 struct { + OriginalSender []byte + RemoteChainSelector uint64 + Receiver common.Address + Amount *big.Int + LocalToken common.Address + SourcePoolAddress []byte + SourcePoolData []byte + OffchainTokenData []byte +} + +type PoolReleaseOrMintOutV1 struct { + DestinationAmount *big.Int +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + RemotePoolAddress []byte + RemoteTokenAddress []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +var LockReleaseTokenPoolAndProxyMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004e1b38038062004e1b83398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508181146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161469a620007816000396000818161051701526118510152600081816105c401528181611e860152612a4201526000818161059e01528181611c1e0152612139015260008181610292015281816102e7015281816107a2015281816108740152818161093e0152818161191301528181611b3e015281816120590152818161223f015281816129d80152612c2d015261469a6000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c80639766b9321161012a578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e13146105c2578063eb521a4c146105e8578063f2fde38b146105fb57600080fd5b8063db6327dc14610589578063dc0bd9711461059c57600080fd5b8063c0d786551461053b578063c4bffe2b1461054e578063c75eea9c14610563578063cf7401f31461057657600080fd5b8063af58d59f116100f9578063af58d59f14610475578063b0f479a1146104e4578063b794658014610502578063bb98546b1461051557600080fd5b80639766b9321461041a5780639a4575b91461042d578063a7cd63b71461044d578063a8d87a3b1461046257600080fd5b806354c8a4f3116101bd57806379ba50971161018c57806383826b2b1161017157806383826b2b146103d65780638926f54f146103e95780638da5cb5b146103fc57600080fd5b806379ba5097146103bb5780637d54534e146103c357600080fd5b806354c8a4f3146103645780636cfd1553146103775780636d3d1a581461038a57806378a010b2146103a857600080fd5b806321df0da7116101f957806321df0da714610290578063240028e8146102d75780633907753714610324578063432a6ba31461034657600080fd5b806301ffc9a71461022b5780630a2fd493146102535780630a861f2a14610273578063181f5a7714610288575b600080fd5b61023e6102393660046135d7565b61060e565b60405190151581526020015b60405180910390f35b610266610261366004613636565b61066a565b60405161024a91906136bf565b6102866102813660046136d2565b61071a565b005b6102666108cb565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161024a565b61023e6102e5366004613718565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b610337610332366004613735565b6108e7565b6040519051815260200161024a565b60095473ffffffffffffffffffffffffffffffffffffffff166102b2565b6102866103723660046137bd565b610a10565b610286610385366004613718565b610a8b565b600a5473ffffffffffffffffffffffffffffffffffffffff166102b2565b6102866103b6366004613829565b610ada565b610286610c49565b6102866103d1366004613718565b610d46565b61023e6103e43660046138ac565b610d95565b61023e6103f7366004613636565b610e62565b60005473ffffffffffffffffffffffffffffffffffffffff166102b2565b610286610428366004613718565b610e79565b61044061043b3660046138e3565b610f08565b60405161024a919061391e565b610455610fd1565b60405161024a919061397e565b6102b2610470366004613636565b503090565b610488610483366004613636565b610fe2565b60405161024a919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102b2565b610266610510366004613636565b6110b7565b7f000000000000000000000000000000000000000000000000000000000000000061023e565b610286610549366004613718565b6110e2565b6105566111b6565b60405161024a91906139d8565b610488610571366004613636565b61126e565b610286610584366004613b8f565b611340565b610286610597366004613bd4565b6113c9565b7f00000000000000000000000000000000000000000000000000000000000000006102b2565b7f000000000000000000000000000000000000000000000000000000000000000061023e565b6102866105f63660046136d2565b61184f565b610286610609366004613718565b61196b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061066457506106648261197f565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061069590613c16565b80601f01602080910402602001604051908101604052809291908181526020018280546106c190613c16565b801561070e5780601f106106e35761010080835404028352916020019161070e565b820191906000526020600020905b8154815290600101906020018083116106f157829003601f168201915b50505050509050919050565b60095473ffffffffffffffffffffffffffffffffffffffff163314610772576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108229190613c69565b101561085a576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61089b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611a63565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040518060600160405280602681526020016146686026913981565b60408051602081019091526000815261090761090283613d1e565b611b37565b60085473ffffffffffffffffffffffffffffffffffffffff1661096e5761096973ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016336060850135611a63565b61097f565b61097f61097a83613d1e565b611d68565b61098f6060830160408401613718565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f5284606001356040516109f191815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a18611e01565b610a8584848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611e8492505050565b50505050565b610a93611e01565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610ae2611e01565b610aeb83610e62565b610b2d576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610769565b67ffffffffffffffff831660009081526007602052604081206004018054610b5490613c16565b80601f0160208091040260200160405190810160405280929190818152602001828054610b8090613c16565b8015610bcd5780601f10610ba257610100808354040283529160200191610bcd565b820191906000526020600020905b815481529060010190602001808311610bb057829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610bfc838583613e63565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610c3b93929190613f7d565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610cca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610769565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610d4e611e01565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610e5b5750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610e37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5b9190613fe1565b9392505050565b6000610664600567ffffffffffffffff841661203a565b610e81611e01565b6008805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610f2d610f2883613ffe565b612052565b60085473ffffffffffffffffffffffffffffffffffffffff1615610f5c57610f5c610f5783613ffe565b61221c565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610fb68460200160208101906105109190613636565b81526040805160208181019092526000815291015292915050565b6060610fdd6002612336565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261066490612343565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061069590613c16565b6110ea611e01565b73ffffffffffffffffffffffffffffffffffffffff8116611137576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610efc565b606060006111c46005612336565b90506000815167ffffffffffffffff8111156111e2576111e2613a1a565b60405190808252806020026020018201604052801561120b578160200160208202803683370190505b50905060005b82518110156112675782818151811061122c5761122c6140a0565b6020026020010151828281518110611246576112466140a0565b67ffffffffffffffff90921660209283029190910190910152600101611211565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261066490612343565b600a5473ffffffffffffffffffffffffffffffffffffffff163314801590611380575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156113b9576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610769565b6113c48383836123f5565b505050565b6113d1611e01565b60005b818110156113c45760008383838181106113f0576113f06140a0565b905060200281019061140291906140cf565b61140b9061410d565b905061142081608001518260200151156124df565b6114338160a001518260200151156124df565b80602001511561172f5780516114559060059067ffffffffffffffff16612618565b61149a5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610769565b60408101515115806114af5750606081015151155b156114e6576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906116c790826141c1565b50606082015160058201906116dc90826141c1565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061172294939291906142db565b60405180910390a1611846565b80516117479060059067ffffffffffffffff16612624565b61178c5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610769565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906117f56004830182613589565b611803600583016000613589565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016113d4565b7f00000000000000000000000000000000000000000000000000000000000000006118a6576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff1633146118f9576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610769565b61193b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612630565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611973611e01565b61197c8161268e565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611a1257507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061066457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526113c49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612783565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611bcc5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610769565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611c7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9e9190613fe1565b15611cd5576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ce2816020015161288f565b6000611cf1826020015161066a565b9050805160001480611d15575080805190602001208260a001518051906020012014155b15611d52578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161076991906136bf565b611d64826020015183606001516129b5565b5050565b6008548151606083015160208401516040517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90941693638627fad693611dcc9390923392600401614374565b600060405180830381600087803b158015611de657600080fd5b505af1158015611dfa573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610769565b565b7f0000000000000000000000000000000000000000000000000000000000000000611edb576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611f71576000838281518110611efb57611efb6140a0565b60200260200101519050611f198160026129fc90919063ffffffff16565b15611f685760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611ede565b5060005b81518110156113c4576000828281518110611f9257611f926140a0565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611fd65750612032565b611fe1600282612a1e565b156120305760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611f75565b60008181526001830160205260408120541515610e5b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146120e75760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610769565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612195573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121b99190613fe1565b156121f0576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121fd8160400151612a40565b61220a8160200151612abf565b61197c81602001518260600151612c0d565b60085460608201516122699173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611a63565b60085460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909516946396875445946122d1949392916004016143d5565b6000604051808303816000875af11580156122f0573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611d649190810190614435565b60606000610e5b83612c51565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526123d182606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426123b591906144d2565b85608001516fffffffffffffffffffffffffffffffff16612cac565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6123fe83610e62565b612440576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610769565b61244b8260006124df565b67ffffffffffffffff8316600090815260076020526040902061246e9083612cd6565b6124798160006124df565b67ffffffffffffffff8316600090815260076020526040902061249f9060020182612cd6565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516124d2939291906144e5565b60405180910390a1505050565b8151156125a65781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612535575060408201516fffffffffffffffffffffffffffffffff16155b1561256e57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107699190614568565b8015611d64576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806125df575060208201516fffffffffffffffffffffffffffffffff1615155b15611d6457816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107699190614568565b6000610e5b8383612e78565b6000610e5b8383612ec7565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a859085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611ab5565b3373ffffffffffffffffffffffffffffffffffffffff82160361270d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610769565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006127e5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612fba9092919063ffffffff16565b8051909150156113c457808060200190518101906128039190613fe1565b6113c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610769565b61289881610e62565b6128da576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610769565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061297d9190613fe1565b61197c576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610769565b67ffffffffffffffff82166000908152600760205260409020611d6490600201827f0000000000000000000000000000000000000000000000000000000000000000612fc9565b6000610e5b8373ffffffffffffffffffffffffffffffffffffffff8416612ec7565b6000610e5b8373ffffffffffffffffffffffffffffffffffffffff8416612e78565b7f00000000000000000000000000000000000000000000000000000000000000001561197c57612a7160028261334c565b61197c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610769565b612ac881610e62565b612b0a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610769565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612b83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba791906145a4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461197c576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610769565b67ffffffffffffffff82166000908152600760205260409020611d6490827f0000000000000000000000000000000000000000000000000000000000000000612fc9565b60608160000180548060200260200160405190810160405280929190818152602001828054801561070e57602002820191906000526020600020905b815481526020019060010190808311612c8d5750505050509050919050565b6000612ccb85612cbc84866145c1565b612cc690876145d8565b61337b565b90505b949350505050565b8154600090612cff90700100000000000000000000000000000000900463ffffffff16426144d2565b90508015612da15760018301548354612d47916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612cac565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612dc7916fffffffffffffffffffffffffffffffff908116911661337b565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906124d2908490614568565b6000818152600183016020526040812054612ebf57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610664565b506000610664565b60008181526001830160205260408120548015612fb0576000612eeb6001836144d2565b8554909150600090612eff906001906144d2565b9050818114612f64576000866000018281548110612f1f57612f1f6140a0565b9060005260206000200154905080876000018481548110612f4257612f426140a0565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612f7557612f756145eb565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610664565b6000915050610664565b6060612cce8484600085613391565b825474010000000000000000000000000000000000000000900460ff161580612ff0575081155b15612ffa57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061304090700100000000000000000000000000000000900463ffffffff16426144d2565b905080156131005781831115613082576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546130bc9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612cac565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156131b75773ffffffffffffffffffffffffffffffffffffffff841661315f576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610769565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610769565b848310156132ca5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906131fb90826144d2565b613205878a6144d2565b61320f91906145d8565b613219919061461a565b905073ffffffffffffffffffffffffffffffffffffffff8616613272576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610769565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610769565b6132d485846144d2565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610e5b565b600081831061338a5781610e5b565b5090919050565b606082471015613423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610769565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161344c9190614655565b60006040518083038185875af1925050503d8060008114613489576040519150601f19603f3d011682016040523d82523d6000602084013e61348e565b606091505b509150915061349f878383876134aa565b979650505050505050565b606083156135405782516000036135395773ffffffffffffffffffffffffffffffffffffffff85163b613539576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610769565b5081612cce565b612cce83838151156135555781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076991906136bf565b50805461359590613c16565b6000825580601f106135a5575050565b601f01602090049060005260206000209081019061197c91905b808211156135d357600081556001016135bf565b5090565b6000602082840312156135e957600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e5b57600080fd5b803567ffffffffffffffff8116811461363157600080fd5b919050565b60006020828403121561364857600080fd5b610e5b82613619565b60005b8381101561366c578181015183820152602001613654565b50506000910152565b6000815180845261368d816020860160208601613651565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610e5b6020830184613675565b6000602082840312156136e457600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461197c57600080fd5b8035613631816136eb565b60006020828403121561372a57600080fd5b8135610e5b816136eb565b60006020828403121561374757600080fd5b813567ffffffffffffffff81111561375e57600080fd5b82016101008185031215610e5b57600080fd5b60008083601f84011261378357600080fd5b50813567ffffffffffffffff81111561379b57600080fd5b6020830191508360208260051b85010111156137b657600080fd5b9250929050565b600080600080604085870312156137d357600080fd5b843567ffffffffffffffff808211156137eb57600080fd5b6137f788838901613771565b9096509450602087013591508082111561381057600080fd5b5061381d87828801613771565b95989497509550505050565b60008060006040848603121561383e57600080fd5b61384784613619565b9250602084013567ffffffffffffffff8082111561386457600080fd5b818601915086601f83011261387857600080fd5b81358181111561388757600080fd5b87602082850101111561389957600080fd5b6020830194508093505050509250925092565b600080604083850312156138bf57600080fd5b6138c883613619565b915060208301356138d8816136eb565b809150509250929050565b6000602082840312156138f557600080fd5b813567ffffffffffffffff81111561390c57600080fd5b820160a08185031215610e5b57600080fd5b60208152600082516040602084015261393a6060840182613675565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526139758282613675565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156139cc57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161399a565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156139cc57835167ffffffffffffffff16835292840192918401916001016139f4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613a6d57613a6d613a1a565b60405290565b60405160c0810167ffffffffffffffff81118282101715613a6d57613a6d613a1a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613add57613add613a1a565b604052919050565b801515811461197c57600080fd5b803561363181613ae5565b80356fffffffffffffffffffffffffffffffff8116811461363157600080fd5b600060608284031215613b3057600080fd5b6040516060810181811067ffffffffffffffff82111715613b5357613b53613a1a565b6040529050808235613b6481613ae5565b8152613b7260208401613afe565b6020820152613b8360408401613afe565b60408201525092915050565b600080600060e08486031215613ba457600080fd5b613bad84613619565b9250613bbc8560208601613b1e565b9150613bcb8560808601613b1e565b90509250925092565b60008060208385031215613be757600080fd5b823567ffffffffffffffff811115613bfe57600080fd5b613c0a85828601613771565b90969095509350505050565b600181811c90821680613c2a57607f821691505b602082108103613c63577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613c7b57600080fd5b5051919050565b600067ffffffffffffffff821115613c9c57613c9c613a1a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613cd957600080fd5b8135613cec613ce782613c82565b613a96565b818152846020838601011115613d0157600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613d3157600080fd5b613d39613a49565b823567ffffffffffffffff80821115613d5157600080fd5b613d5d36838701613cc8565b8352613d6b60208601613619565b6020840152613d7c6040860161370d565b604084015260608501356060840152613d976080860161370d565b608084015260a0850135915080821115613db057600080fd5b613dbc36838701613cc8565b60a084015260c0850135915080821115613dd557600080fd5b613de136838701613cc8565b60c084015260e0850135915080821115613dfa57600080fd5b50613e0736828601613cc8565b60e08301525092915050565b601f8211156113c4576000816000526020600020601f850160051c81016020861015613e3c5750805b601f850160051c820191505b81811015613e5b57828155600101613e48565b505050505050565b67ffffffffffffffff831115613e7b57613e7b613a1a565b613e8f83613e898354613c16565b83613e13565b6000601f841160018114613ee15760008515613eab5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611dfa565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613f305786850135825560209485019460019092019101613f10565b5086821015613f6b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613f906040830186613675565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613ff357600080fd5b8151610e5b81613ae5565b600060a0823603121561401057600080fd5b60405160a0810167ffffffffffffffff828210818311171561403457614034613a1a565b81604052843591508082111561404957600080fd5b5061405636828601613cc8565b82525061406560208401613619565b60208201526040830135614078816136eb565b6040820152606083810135908201526080830135614095816136eb565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261410357600080fd5b9190910192915050565b6000610140823603121561412057600080fd5b614128613a73565b61413183613619565b815261413f60208401613af3565b6020820152604083013567ffffffffffffffff8082111561415f57600080fd5b61416b36838701613cc8565b6040840152606085013591508082111561418457600080fd5b5061419136828601613cc8565b6060830152506141a43660808501613b1e565b60808201526141b63660e08501613b1e565b60a082015292915050565b815167ffffffffffffffff8111156141db576141db613a1a565b6141ef816141e98454613c16565b84613e13565b602080601f831160018114614242576000841561420c5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613e5b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561428f57888601518255948401946001909101908401614270565b50858210156142cb57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526142ff81840187613675565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061433d9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613975565b60a08152600061438760a0830187613675565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a06020820152600061440460a0830186613675565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561444757600080fd5b815167ffffffffffffffff81111561445e57600080fd5b8201601f8101841361446f57600080fd5b805161447d613ce782613c82565b81815285602083850101111561449257600080fd5b613975826020830160208601613651565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610664576106646144a3565b67ffffffffffffffff8416815260e0810161453160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612cce565b6060810161066482848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156145b657600080fd5b8151610e5b816136eb565b8082028115828204841417610664576106646144a3565b80820180821115610664576106646144a3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614650577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000825161410381846020870161365156fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", +} + +var LockReleaseTokenPoolAndProxyABI = LockReleaseTokenPoolAndProxyMetaData.ABI + +var LockReleaseTokenPoolAndProxyBin = LockReleaseTokenPoolAndProxyMetaData.Bin + +func DeployLockReleaseTokenPoolAndProxy(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, rmnProxy common.Address, acceptLiquidity bool, router common.Address) (common.Address, *types.Transaction, *LockReleaseTokenPoolAndProxy, error) { + parsed, err := LockReleaseTokenPoolAndProxyMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LockReleaseTokenPoolAndProxyBin), backend, token, allowlist, rmnProxy, acceptLiquidity, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &LockReleaseTokenPoolAndProxy{address: address, abi: *parsed, LockReleaseTokenPoolAndProxyCaller: LockReleaseTokenPoolAndProxyCaller{contract: contract}, LockReleaseTokenPoolAndProxyTransactor: LockReleaseTokenPoolAndProxyTransactor{contract: contract}, LockReleaseTokenPoolAndProxyFilterer: LockReleaseTokenPoolAndProxyFilterer{contract: contract}}, nil +} + +type LockReleaseTokenPoolAndProxy struct { + address common.Address + abi abi.ABI + LockReleaseTokenPoolAndProxyCaller + LockReleaseTokenPoolAndProxyTransactor + LockReleaseTokenPoolAndProxyFilterer +} + +type LockReleaseTokenPoolAndProxyCaller struct { + contract *bind.BoundContract +} + +type LockReleaseTokenPoolAndProxyTransactor struct { + contract *bind.BoundContract +} + +type LockReleaseTokenPoolAndProxyFilterer struct { + contract *bind.BoundContract +} + +type LockReleaseTokenPoolAndProxySession struct { + Contract *LockReleaseTokenPoolAndProxy + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type LockReleaseTokenPoolAndProxyCallerSession struct { + Contract *LockReleaseTokenPoolAndProxyCaller + CallOpts bind.CallOpts +} + +type LockReleaseTokenPoolAndProxyTransactorSession struct { + Contract *LockReleaseTokenPoolAndProxyTransactor + TransactOpts bind.TransactOpts +} + +type LockReleaseTokenPoolAndProxyRaw struct { + Contract *LockReleaseTokenPoolAndProxy +} + +type LockReleaseTokenPoolAndProxyCallerRaw struct { + Contract *LockReleaseTokenPoolAndProxyCaller +} + +type LockReleaseTokenPoolAndProxyTransactorRaw struct { + Contract *LockReleaseTokenPoolAndProxyTransactor +} + +func NewLockReleaseTokenPoolAndProxy(address common.Address, backend bind.ContractBackend) (*LockReleaseTokenPoolAndProxy, error) { + abi, err := abi.JSON(strings.NewReader(LockReleaseTokenPoolAndProxyABI)) + if err != nil { + return nil, err + } + contract, err := bindLockReleaseTokenPoolAndProxy(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxy{address: address, abi: abi, LockReleaseTokenPoolAndProxyCaller: LockReleaseTokenPoolAndProxyCaller{contract: contract}, LockReleaseTokenPoolAndProxyTransactor: LockReleaseTokenPoolAndProxyTransactor{contract: contract}, LockReleaseTokenPoolAndProxyFilterer: LockReleaseTokenPoolAndProxyFilterer{contract: contract}}, nil +} + +func NewLockReleaseTokenPoolAndProxyCaller(address common.Address, caller bind.ContractCaller) (*LockReleaseTokenPoolAndProxyCaller, error) { + contract, err := bindLockReleaseTokenPoolAndProxy(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyCaller{contract: contract}, nil +} + +func NewLockReleaseTokenPoolAndProxyTransactor(address common.Address, transactor bind.ContractTransactor) (*LockReleaseTokenPoolAndProxyTransactor, error) { + contract, err := bindLockReleaseTokenPoolAndProxy(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyTransactor{contract: contract}, nil +} + +func NewLockReleaseTokenPoolAndProxyFilterer(address common.Address, filterer bind.ContractFilterer) (*LockReleaseTokenPoolAndProxyFilterer, error) { + contract, err := bindLockReleaseTokenPoolAndProxy(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyFilterer{contract: contract}, nil +} + +func bindLockReleaseTokenPoolAndProxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LockReleaseTokenPoolAndProxyMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LockReleaseTokenPoolAndProxy.Contract.LockReleaseTokenPoolAndProxyCaller.contract.Call(opts, result, method, params...) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.LockReleaseTokenPoolAndProxyTransactor.contract.Transfer(opts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.LockReleaseTokenPoolAndProxyTransactor.contract.Transact(opts, method, params...) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LockReleaseTokenPoolAndProxy.Contract.contract.Call(opts, result, method, params...) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.contract.Transfer(opts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.contract.Transact(opts, method, params...) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) CanAcceptLiquidity(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "canAcceptLiquidity") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) CanAcceptLiquidity() (bool, error) { + return _LockReleaseTokenPoolAndProxy.Contract.CanAcceptLiquidity(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) CanAcceptLiquidity() (bool, error) { + return _LockReleaseTokenPoolAndProxy.Contract.CanAcceptLiquidity(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetAllowList() ([]common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetAllowList(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetAllowList() ([]common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetAllowList(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetAllowListEnabled() (bool, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetAllowListEnabled(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetAllowListEnabled() (bool, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetAllowListEnabled(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetCurrentInboundRateLimiterState(&_LockReleaseTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetCurrentInboundRateLimiterState(&_LockReleaseTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetCurrentOutboundRateLimiterState(&_LockReleaseTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetCurrentOutboundRateLimiterState(&_LockReleaseTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetOnRamp(opts *bind.CallOpts, arg0 uint64) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getOnRamp", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetOnRamp(arg0 uint64) (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetOnRamp(&_LockReleaseTokenPoolAndProxy.CallOpts, arg0) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetOnRamp(arg0 uint64) (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetOnRamp(&_LockReleaseTokenPoolAndProxy.CallOpts, arg0) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getRateLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetRateLimitAdmin() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetRateLimitAdmin(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetRateLimitAdmin() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetRateLimitAdmin(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetRebalancer(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getRebalancer") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetRebalancer() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetRebalancer(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetRebalancer() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetRebalancer(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetRemotePool(&_LockReleaseTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetRemotePool(&_LockReleaseTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getRemoteToken", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetRemoteToken(&_LockReleaseTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetRemoteToken(&_LockReleaseTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetRmnProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getRmnProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetRmnProxy() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetRmnProxy(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetRmnProxy() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetRmnProxy(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetRouter() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetRouter(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetRouter() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetRouter(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetSupportedChains() ([]uint64, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetSupportedChains(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetSupportedChains() ([]uint64, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetSupportedChains(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetToken() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetToken(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetToken() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetToken(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) IsOffRamp(opts *bind.CallOpts, sourceChainSelector uint64, offRamp common.Address) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "isOffRamp", sourceChainSelector, offRamp) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) IsOffRamp(sourceChainSelector uint64, offRamp common.Address) (bool, error) { + return _LockReleaseTokenPoolAndProxy.Contract.IsOffRamp(&_LockReleaseTokenPoolAndProxy.CallOpts, sourceChainSelector, offRamp) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) IsOffRamp(sourceChainSelector uint64, offRamp common.Address) (bool, error) { + return _LockReleaseTokenPoolAndProxy.Contract.IsOffRamp(&_LockReleaseTokenPoolAndProxy.CallOpts, sourceChainSelector, offRamp) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _LockReleaseTokenPoolAndProxy.Contract.IsSupportedChain(&_LockReleaseTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _LockReleaseTokenPoolAndProxy.Contract.IsSupportedChain(&_LockReleaseTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "isSupportedToken", token) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) IsSupportedToken(token common.Address) (bool, error) { + return _LockReleaseTokenPoolAndProxy.Contract.IsSupportedToken(&_LockReleaseTokenPoolAndProxy.CallOpts, token) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) IsSupportedToken(token common.Address) (bool, error) { + return _LockReleaseTokenPoolAndProxy.Contract.IsSupportedToken(&_LockReleaseTokenPoolAndProxy.CallOpts, token) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) Owner() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.Owner(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) Owner() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.Owner(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SupportsInterface(&_LockReleaseTokenPoolAndProxy.CallOpts, interfaceId) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SupportsInterface(&_LockReleaseTokenPoolAndProxy.CallOpts, interfaceId) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) TypeAndVersion() (string, error) { + return _LockReleaseTokenPoolAndProxy.Contract.TypeAndVersion(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) TypeAndVersion() (string, error) { + return _LockReleaseTokenPoolAndProxy.Contract.TypeAndVersion(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "acceptOwnership") +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) AcceptOwnership() (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.AcceptOwnership(&_LockReleaseTokenPoolAndProxy.TransactOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.AcceptOwnership(&_LockReleaseTokenPoolAndProxy.TransactOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.ApplyAllowListUpdates(&_LockReleaseTokenPoolAndProxy.TransactOpts, removes, adds) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.ApplyAllowListUpdates(&_LockReleaseTokenPoolAndProxy.TransactOpts, removes, adds) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.ApplyChainUpdates(&_LockReleaseTokenPoolAndProxy.TransactOpts, chains) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.ApplyChainUpdates(&_LockReleaseTokenPoolAndProxy.TransactOpts, chains) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "lockOrBurn", lockOrBurnIn) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.LockOrBurn(&_LockReleaseTokenPoolAndProxy.TransactOpts, lockOrBurnIn) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.LockOrBurn(&_LockReleaseTokenPoolAndProxy.TransactOpts, lockOrBurnIn) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) ProvideLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "provideLiquidity", amount) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) ProvideLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.ProvideLiquidity(&_LockReleaseTokenPoolAndProxy.TransactOpts, amount) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) ProvideLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.ProvideLiquidity(&_LockReleaseTokenPoolAndProxy.TransactOpts, amount) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "releaseOrMint", releaseOrMintIn) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.ReleaseOrMint(&_LockReleaseTokenPoolAndProxy.TransactOpts, releaseOrMintIn) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.ReleaseOrMint(&_LockReleaseTokenPoolAndProxy.TransactOpts, releaseOrMintIn) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SetChainRateLimiterConfig(&_LockReleaseTokenPoolAndProxy.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SetChainRateLimiterConfig(&_LockReleaseTokenPoolAndProxy.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) SetPreviousPool(opts *bind.TransactOpts, prevPool common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "setPreviousPool", prevPool) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) SetPreviousPool(prevPool common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SetPreviousPool(&_LockReleaseTokenPoolAndProxy.TransactOpts, prevPool) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) SetPreviousPool(prevPool common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SetPreviousPool(&_LockReleaseTokenPoolAndProxy.TransactOpts, prevPool) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SetRateLimitAdmin(&_LockReleaseTokenPoolAndProxy.TransactOpts, rateLimitAdmin) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SetRateLimitAdmin(&_LockReleaseTokenPoolAndProxy.TransactOpts, rateLimitAdmin) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) SetRebalancer(opts *bind.TransactOpts, rebalancer common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "setRebalancer", rebalancer) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) SetRebalancer(rebalancer common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SetRebalancer(&_LockReleaseTokenPoolAndProxy.TransactOpts, rebalancer) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) SetRebalancer(rebalancer common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SetRebalancer(&_LockReleaseTokenPoolAndProxy.TransactOpts, rebalancer) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SetRemotePool(&_LockReleaseTokenPoolAndProxy.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SetRemotePool(&_LockReleaseTokenPoolAndProxy.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "setRouter", newRouter) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SetRouter(&_LockReleaseTokenPoolAndProxy.TransactOpts, newRouter) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.SetRouter(&_LockReleaseTokenPoolAndProxy.TransactOpts, newRouter) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "transferOwnership", to) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.TransferOwnership(&_LockReleaseTokenPoolAndProxy.TransactOpts, to) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.TransferOwnership(&_LockReleaseTokenPoolAndProxy.TransactOpts, to) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) WithdrawLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "withdrawLiquidity", amount) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) WithdrawLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.WithdrawLiquidity(&_LockReleaseTokenPoolAndProxy.TransactOpts, amount) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) WithdrawLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.WithdrawLiquidity(&_LockReleaseTokenPoolAndProxy.TransactOpts, amount) +} + +type LockReleaseTokenPoolAndProxyAllowListAddIterator struct { + Event *LockReleaseTokenPoolAndProxyAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyAllowListAddIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyAllowListAddIterator, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyAllowListAddIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyAllowListAdd) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseAllowListAdd(log types.Log) (*LockReleaseTokenPoolAndProxyAllowListAdd, error) { + event := new(LockReleaseTokenPoolAndProxyAllowListAdd) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyAllowListRemoveIterator struct { + Event *LockReleaseTokenPoolAndProxyAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyAllowListRemoveIterator, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyAllowListRemoveIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyAllowListRemove) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseAllowListRemove(log types.Log) (*LockReleaseTokenPoolAndProxyAllowListRemove, error) { + event := new(LockReleaseTokenPoolAndProxyAllowListRemove) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyBurnedIterator struct { + Event *LockReleaseTokenPoolAndProxyBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyBurnedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolAndProxyBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyBurnedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyBurned) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseBurned(log types.Log) (*LockReleaseTokenPoolAndProxyBurned, error) { + event := new(LockReleaseTokenPoolAndProxyBurned) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyChainAddedIterator struct { + Event *LockReleaseTokenPoolAndProxyChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyChainAddedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyChainAdded struct { + RemoteChainSelector uint64 + RemoteToken []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterChainAdded(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyChainAddedIterator, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyChainAddedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyChainAdded) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyChainAdded) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseChainAdded(log types.Log) (*LockReleaseTokenPoolAndProxyChainAdded, error) { + event := new(LockReleaseTokenPoolAndProxyChainAdded) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyChainConfiguredIterator struct { + Event *LockReleaseTokenPoolAndProxyChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyChainConfiguredIterator, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyChainConfiguredIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyChainConfigured) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyChainConfigured) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseChainConfigured(log types.Log) (*LockReleaseTokenPoolAndProxyChainConfigured, error) { + event := new(LockReleaseTokenPoolAndProxyChainConfigured) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyChainRemovedIterator struct { + Event *LockReleaseTokenPoolAndProxyChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyChainRemovedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyChainRemovedIterator, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyChainRemovedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyChainRemoved) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyChainRemoved) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseChainRemoved(log types.Log) (*LockReleaseTokenPoolAndProxyChainRemoved, error) { + event := new(LockReleaseTokenPoolAndProxyChainRemoved) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyConfigChangedIterator struct { + Event *LockReleaseTokenPoolAndProxyConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyConfigChangedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyConfigChanged struct { + Config RateLimiterConfig + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyConfigChangedIterator, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyConfigChangedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyConfigChanged) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyConfigChanged) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseConfigChanged(log types.Log) (*LockReleaseTokenPoolAndProxyConfigChanged, error) { + event := new(LockReleaseTokenPoolAndProxyConfigChanged) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyLegacyPoolChangedIterator struct { + Event *LockReleaseTokenPoolAndProxyLegacyPoolChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyLegacyPoolChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyLegacyPoolChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyLegacyPoolChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyLegacyPoolChangedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyLegacyPoolChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyLegacyPoolChanged struct { + OldPool common.Address + NewPool common.Address + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterLegacyPoolChanged(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyLegacyPoolChangedIterator, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "LegacyPoolChanged") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyLegacyPoolChangedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "LegacyPoolChanged", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchLegacyPoolChanged(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyLegacyPoolChanged) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "LegacyPoolChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyLegacyPoolChanged) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "LegacyPoolChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseLegacyPoolChanged(log types.Log) (*LockReleaseTokenPoolAndProxyLegacyPoolChanged, error) { + event := new(LockReleaseTokenPoolAndProxyLegacyPoolChanged) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "LegacyPoolChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyLiquidityAddedIterator struct { + Event *LockReleaseTokenPoolAndProxyLiquidityAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyLiquidityAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyLiquidityAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyLiquidityAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyLiquidityAddedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyLiquidityAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyLiquidityAdded struct { + Provider common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterLiquidityAdded(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolAndProxyLiquidityAddedIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "LiquidityAdded", providerRule, amountRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyLiquidityAddedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "LiquidityAdded", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchLiquidityAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyLiquidityAdded, provider []common.Address, amount []*big.Int) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "LiquidityAdded", providerRule, amountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyLiquidityAdded) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "LiquidityAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseLiquidityAdded(log types.Log) (*LockReleaseTokenPoolAndProxyLiquidityAdded, error) { + event := new(LockReleaseTokenPoolAndProxyLiquidityAdded) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "LiquidityAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyLiquidityRemovedIterator struct { + Event *LockReleaseTokenPoolAndProxyLiquidityRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyLiquidityRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyLiquidityRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyLiquidityRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyLiquidityRemovedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyLiquidityRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyLiquidityRemoved struct { + Provider common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterLiquidityRemoved(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolAndProxyLiquidityRemovedIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "LiquidityRemoved", providerRule, amountRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyLiquidityRemovedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "LiquidityRemoved", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchLiquidityRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyLiquidityRemoved, provider []common.Address, amount []*big.Int) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "LiquidityRemoved", providerRule, amountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyLiquidityRemoved) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "LiquidityRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseLiquidityRemoved(log types.Log) (*LockReleaseTokenPoolAndProxyLiquidityRemoved, error) { + event := new(LockReleaseTokenPoolAndProxyLiquidityRemoved) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "LiquidityRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyLockedIterator struct { + Event *LockReleaseTokenPoolAndProxyLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyLockedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolAndProxyLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyLockedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyLocked) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseLocked(log types.Log) (*LockReleaseTokenPoolAndProxyLocked, error) { + event := new(LockReleaseTokenPoolAndProxyLocked) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyMintedIterator struct { + Event *LockReleaseTokenPoolAndProxyMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyMintedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolAndProxyMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyMintedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyMinted) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseMinted(log types.Log) (*LockReleaseTokenPoolAndProxyMinted, error) { + event := new(LockReleaseTokenPoolAndProxyMinted) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyOwnershipTransferRequestedIterator struct { + Event *LockReleaseTokenPoolAndProxyOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolAndProxyOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyOwnershipTransferRequestedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyOwnershipTransferRequested) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseOwnershipTransferRequested(log types.Log) (*LockReleaseTokenPoolAndProxyOwnershipTransferRequested, error) { + event := new(LockReleaseTokenPoolAndProxyOwnershipTransferRequested) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyOwnershipTransferredIterator struct { + Event *LockReleaseTokenPoolAndProxyOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolAndProxyOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyOwnershipTransferredIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyOwnershipTransferred) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseOwnershipTransferred(log types.Log) (*LockReleaseTokenPoolAndProxyOwnershipTransferred, error) { + event := new(LockReleaseTokenPoolAndProxyOwnershipTransferred) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyReleasedIterator struct { + Event *LockReleaseTokenPoolAndProxyReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyReleasedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolAndProxyReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyReleasedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyReleased) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseReleased(log types.Log) (*LockReleaseTokenPoolAndProxyReleased, error) { + event := new(LockReleaseTokenPoolAndProxyReleased) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyRemotePoolSetIterator struct { + Event *LockReleaseTokenPoolAndProxyRemotePoolSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyRemotePoolSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyRemotePoolSetIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyRemotePoolSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyRemotePoolSet struct { + RemoteChainSelector uint64 + PreviousPoolAddress []byte + RemotePoolAddress []byte + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*LockReleaseTokenPoolAndProxyRemotePoolSetIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyRemotePoolSetIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyRemotePoolSet) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseRemotePoolSet(log types.Log) (*LockReleaseTokenPoolAndProxyRemotePoolSet, error) { + event := new(LockReleaseTokenPoolAndProxyRemotePoolSet) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyRouterUpdatedIterator struct { + Event *LockReleaseTokenPoolAndProxyRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyRouterUpdatedIterator, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyRouterUpdatedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyRouterUpdated) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseRouterUpdated(log types.Log) (*LockReleaseTokenPoolAndProxyRouterUpdated, error) { + event := new(LockReleaseTokenPoolAndProxyRouterUpdated) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolAndProxyTokensConsumedIterator struct { + Event *LockReleaseTokenPoolAndProxyTokensConsumed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolAndProxyTokensConsumedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolAndProxyTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolAndProxyTokensConsumedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolAndProxyTokensConsumedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolAndProxyTokensConsumed struct { + Tokens *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) FilterTokensConsumed(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyTokensConsumedIterator, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.FilterLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolAndProxyTokensConsumedIterator{contract: _LockReleaseTokenPoolAndProxy.contract, event: "TokensConsumed", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyTokensConsumed) (event.Subscription, error) { + + logs, sub, err := _LockReleaseTokenPoolAndProxy.contract.WatchLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolAndProxyTokensConsumed) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyFilterer) ParseTokensConsumed(log types.Log) (*LockReleaseTokenPoolAndProxyTokensConsumed, error) { + event := new(LockReleaseTokenPoolAndProxyTokensConsumed) + if err := _LockReleaseTokenPoolAndProxy.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxy) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _LockReleaseTokenPoolAndProxy.abi.Events["AllowListAdd"].ID: + return _LockReleaseTokenPoolAndProxy.ParseAllowListAdd(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["AllowListRemove"].ID: + return _LockReleaseTokenPoolAndProxy.ParseAllowListRemove(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["Burned"].ID: + return _LockReleaseTokenPoolAndProxy.ParseBurned(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["ChainAdded"].ID: + return _LockReleaseTokenPoolAndProxy.ParseChainAdded(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["ChainConfigured"].ID: + return _LockReleaseTokenPoolAndProxy.ParseChainConfigured(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["ChainRemoved"].ID: + return _LockReleaseTokenPoolAndProxy.ParseChainRemoved(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["ConfigChanged"].ID: + return _LockReleaseTokenPoolAndProxy.ParseConfigChanged(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["LegacyPoolChanged"].ID: + return _LockReleaseTokenPoolAndProxy.ParseLegacyPoolChanged(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["LiquidityAdded"].ID: + return _LockReleaseTokenPoolAndProxy.ParseLiquidityAdded(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["LiquidityRemoved"].ID: + return _LockReleaseTokenPoolAndProxy.ParseLiquidityRemoved(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["Locked"].ID: + return _LockReleaseTokenPoolAndProxy.ParseLocked(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["Minted"].ID: + return _LockReleaseTokenPoolAndProxy.ParseMinted(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["OwnershipTransferRequested"].ID: + return _LockReleaseTokenPoolAndProxy.ParseOwnershipTransferRequested(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["OwnershipTransferred"].ID: + return _LockReleaseTokenPoolAndProxy.ParseOwnershipTransferred(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["Released"].ID: + return _LockReleaseTokenPoolAndProxy.ParseReleased(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["RemotePoolSet"].ID: + return _LockReleaseTokenPoolAndProxy.ParseRemotePoolSet(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["RouterUpdated"].ID: + return _LockReleaseTokenPoolAndProxy.ParseRouterUpdated(log) + case _LockReleaseTokenPoolAndProxy.abi.Events["TokensConsumed"].ID: + return _LockReleaseTokenPoolAndProxy.ParseTokensConsumed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (LockReleaseTokenPoolAndProxyAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (LockReleaseTokenPoolAndProxyAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (LockReleaseTokenPoolAndProxyBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (LockReleaseTokenPoolAndProxyChainAdded) Topic() common.Hash { + return common.HexToHash("0x8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2") +} + +func (LockReleaseTokenPoolAndProxyChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (LockReleaseTokenPoolAndProxyChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (LockReleaseTokenPoolAndProxyConfigChanged) Topic() common.Hash { + return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") +} + +func (LockReleaseTokenPoolAndProxyLegacyPoolChanged) Topic() common.Hash { + return common.HexToHash("0x81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f228") +} + +func (LockReleaseTokenPoolAndProxyLiquidityAdded) Topic() common.Hash { + return common.HexToHash("0xc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb312088") +} + +func (LockReleaseTokenPoolAndProxyLiquidityRemoved) Topic() common.Hash { + return common.HexToHash("0xc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf9840171719") +} + +func (LockReleaseTokenPoolAndProxyLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (LockReleaseTokenPoolAndProxyMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (LockReleaseTokenPoolAndProxyOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (LockReleaseTokenPoolAndProxyOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (LockReleaseTokenPoolAndProxyReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (LockReleaseTokenPoolAndProxyRemotePoolSet) Topic() common.Hash { + return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +} + +func (LockReleaseTokenPoolAndProxyRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (LockReleaseTokenPoolAndProxyTokensConsumed) Topic() common.Hash { + return common.HexToHash("0x1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a") +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxy) Address() common.Address { + return _LockReleaseTokenPoolAndProxy.address +} + +type LockReleaseTokenPoolAndProxyInterface interface { + CanAcceptLiquidity(opts *bind.CallOpts) (bool, error) + + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetOnRamp(opts *bind.CallOpts, arg0 uint64) (common.Address, error) + + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) + + GetRebalancer(opts *bind.CallOpts) (common.Address, error) + + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRmnProxy(opts *bind.CallOpts) (common.Address, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsOffRamp(opts *bind.CallOpts, sourceChainSelector uint64, offRamp common.Address) (bool, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) + + ProvideLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetPreviousPool(opts *bind.TransactOpts, prevPool common.Address) (*types.Transaction, error) + + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) + + SetRebalancer(opts *bind.TransactOpts, rebalancer common.Address) (*types.Transaction, error) + + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + WithdrawLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*LockReleaseTokenPoolAndProxyAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*LockReleaseTokenPoolAndProxyAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolAndProxyBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*LockReleaseTokenPoolAndProxyBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*LockReleaseTokenPoolAndProxyChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*LockReleaseTokenPoolAndProxyChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*LockReleaseTokenPoolAndProxyChainRemoved, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*LockReleaseTokenPoolAndProxyConfigChanged, error) + + FilterLegacyPoolChanged(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyLegacyPoolChangedIterator, error) + + WatchLegacyPoolChanged(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyLegacyPoolChanged) (event.Subscription, error) + + ParseLegacyPoolChanged(log types.Log) (*LockReleaseTokenPoolAndProxyLegacyPoolChanged, error) + + FilterLiquidityAdded(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolAndProxyLiquidityAddedIterator, error) + + WatchLiquidityAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyLiquidityAdded, provider []common.Address, amount []*big.Int) (event.Subscription, error) + + ParseLiquidityAdded(log types.Log) (*LockReleaseTokenPoolAndProxyLiquidityAdded, error) + + FilterLiquidityRemoved(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LockReleaseTokenPoolAndProxyLiquidityRemovedIterator, error) + + WatchLiquidityRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyLiquidityRemoved, provider []common.Address, amount []*big.Int) (event.Subscription, error) + + ParseLiquidityRemoved(log types.Log) (*LockReleaseTokenPoolAndProxyLiquidityRemoved, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolAndProxyLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*LockReleaseTokenPoolAndProxyLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolAndProxyMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*LockReleaseTokenPoolAndProxyMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolAndProxyOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*LockReleaseTokenPoolAndProxyOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LockReleaseTokenPoolAndProxyOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*LockReleaseTokenPoolAndProxyOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*LockReleaseTokenPoolAndProxyReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*LockReleaseTokenPoolAndProxyReleased, error) + + FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*LockReleaseTokenPoolAndProxyRemotePoolSetIterator, error) + + WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolSet(log types.Log) (*LockReleaseTokenPoolAndProxyRemotePoolSet, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*LockReleaseTokenPoolAndProxyRouterUpdated, error) + + FilterTokensConsumed(opts *bind.FilterOpts) (*LockReleaseTokenPoolAndProxyTokensConsumedIterator, error) + + WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolAndProxyTokensConsumed) (event.Subscription, error) + + ParseTokensConsumed(log types.Log) (*LockReleaseTokenPoolAndProxyTokensConsumed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/maybe_revert_message_receiver/maybe_revert_message_receiver.go b/core/gethwrappers/ccip/generated/maybe_revert_message_receiver/maybe_revert_message_receiver.go new file mode 100644 index 0000000000..3b52e8c871 --- /dev/null +++ b/core/gethwrappers/ccip/generated/maybe_revert_message_receiver/maybe_revert_message_receiver.go @@ -0,0 +1,564 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package maybe_revert_message_receiver + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientAny2EVMMessage struct { + MessageId [32]byte + SourceChainSelector uint64 + Sender []byte + Data []byte + DestTokenAmounts []ClientEVMTokenAmount +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +var MaybeRevertMessageReceiverMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"toRevert\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"CustomError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReceiveRevert\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"MessageReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ValueReceived\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_toRevert\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"setErr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"toRevert\",\"type\":\"bool\"}],\"name\":\"setRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x608060405234801561001057600080fd5b506040516107e73803806107e783398101604081905261002f9161005d565b600080546001600160a81b0319163360ff60a01b191617600160a01b92151592909202919091179055610086565b60006020828403121561006f57600080fd5b8151801515811461007f57600080fd5b9392505050565b610752806100956000396000f3fe60806040526004361061005e5760003560e01c806377f5b0e61161004357806377f5b0e61461015857806385572ffb1461017a5780638fb5f1711461019a57600080fd5b806301ffc9a7146100f25780635100fc211461012657600080fd5b366100ed5760005474010000000000000000000000000000000000000000900460ff16156100b8576040517f3085b8db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040513481527fe12e3b7047ff60a2dd763cf536a43597e5ce7fe7aa7476345bd4cd079912bcef9060200160405180910390a1005b600080fd5b3480156100fe57600080fd5b5061011261010d366004610335565b6101ff565b604051901515815260200160405180910390f35b34801561013257600080fd5b506000546101129074010000000000000000000000000000000000000000900460ff1681565b34801561016457600080fd5b506101786101733660046103ad565b610298565b005b34801561018657600080fd5b5061017861019536600461047c565b6102a8565b3480156101a657600080fd5b506101786101b53660046104b7565b6000805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f85572ffb00000000000000000000000000000000000000000000000000000000148061029257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60016102a4828261057d565b5050565b60005474010000000000000000000000000000000000000000900460ff16156103095760016040517f5a4ff6710000000000000000000000000000000000000000000000000000000081526004016103009190610697565b60405180910390fd5b6040517fd82ce31e3523f6eeb2d24317b2b4133001e8472729657f663b68624c45f8f3e890600090a150565b60006020828403121561034757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461037757600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156103bf57600080fd5b813567ffffffffffffffff808211156103d757600080fd5b818401915084601f8301126103eb57600080fd5b8135818111156103fd576103fd61037e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156104435761044361037e565b8160405282815287602084870101111561045c57600080fd5b826020860160208301376000928101602001929092525095945050505050565b60006020828403121561048e57600080fd5b813567ffffffffffffffff8111156104a557600080fd5b820160a0818503121561037757600080fd5b6000602082840312156104c957600080fd5b8135801515811461037757600080fd5b600181811c908216806104ed57607f821691505b602082108103610526577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115610578576000816000526020600020601f850160051c810160208610156105555750805b601f850160051c820191505b8181101561057457828155600101610561565b5050505b505050565b815167ffffffffffffffff8111156105975761059761037e565b6105ab816105a584546104d9565b8461052c565b602080601f8311600181146105fe57600084156105c85750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610574565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561064b5788860151825594840194600190910190840161062c565b508582101561068757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60006020808352600084546106ab816104d9565b80602087015260406001808416600081146106cd576001811461070757610737565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550610737565b89600052602060002060005b8581101561072e5781548b8201860152908301908801610713565b8a016040019650505b50939897505050505050505056fea164736f6c6343000818000a", +} + +var MaybeRevertMessageReceiverABI = MaybeRevertMessageReceiverMetaData.ABI + +var MaybeRevertMessageReceiverBin = MaybeRevertMessageReceiverMetaData.Bin + +func DeployMaybeRevertMessageReceiver(auth *bind.TransactOpts, backend bind.ContractBackend, toRevert bool) (common.Address, *types.Transaction, *MaybeRevertMessageReceiver, error) { + parsed, err := MaybeRevertMessageReceiverMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MaybeRevertMessageReceiverBin), backend, toRevert) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MaybeRevertMessageReceiver{address: address, abi: *parsed, MaybeRevertMessageReceiverCaller: MaybeRevertMessageReceiverCaller{contract: contract}, MaybeRevertMessageReceiverTransactor: MaybeRevertMessageReceiverTransactor{contract: contract}, MaybeRevertMessageReceiverFilterer: MaybeRevertMessageReceiverFilterer{contract: contract}}, nil +} + +type MaybeRevertMessageReceiver struct { + address common.Address + abi abi.ABI + MaybeRevertMessageReceiverCaller + MaybeRevertMessageReceiverTransactor + MaybeRevertMessageReceiverFilterer +} + +type MaybeRevertMessageReceiverCaller struct { + contract *bind.BoundContract +} + +type MaybeRevertMessageReceiverTransactor struct { + contract *bind.BoundContract +} + +type MaybeRevertMessageReceiverFilterer struct { + contract *bind.BoundContract +} + +type MaybeRevertMessageReceiverSession struct { + Contract *MaybeRevertMessageReceiver + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type MaybeRevertMessageReceiverCallerSession struct { + Contract *MaybeRevertMessageReceiverCaller + CallOpts bind.CallOpts +} + +type MaybeRevertMessageReceiverTransactorSession struct { + Contract *MaybeRevertMessageReceiverTransactor + TransactOpts bind.TransactOpts +} + +type MaybeRevertMessageReceiverRaw struct { + Contract *MaybeRevertMessageReceiver +} + +type MaybeRevertMessageReceiverCallerRaw struct { + Contract *MaybeRevertMessageReceiverCaller +} + +type MaybeRevertMessageReceiverTransactorRaw struct { + Contract *MaybeRevertMessageReceiverTransactor +} + +func NewMaybeRevertMessageReceiver(address common.Address, backend bind.ContractBackend) (*MaybeRevertMessageReceiver, error) { + abi, err := abi.JSON(strings.NewReader(MaybeRevertMessageReceiverABI)) + if err != nil { + return nil, err + } + contract, err := bindMaybeRevertMessageReceiver(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MaybeRevertMessageReceiver{address: address, abi: abi, MaybeRevertMessageReceiverCaller: MaybeRevertMessageReceiverCaller{contract: contract}, MaybeRevertMessageReceiverTransactor: MaybeRevertMessageReceiverTransactor{contract: contract}, MaybeRevertMessageReceiverFilterer: MaybeRevertMessageReceiverFilterer{contract: contract}}, nil +} + +func NewMaybeRevertMessageReceiverCaller(address common.Address, caller bind.ContractCaller) (*MaybeRevertMessageReceiverCaller, error) { + contract, err := bindMaybeRevertMessageReceiver(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MaybeRevertMessageReceiverCaller{contract: contract}, nil +} + +func NewMaybeRevertMessageReceiverTransactor(address common.Address, transactor bind.ContractTransactor) (*MaybeRevertMessageReceiverTransactor, error) { + contract, err := bindMaybeRevertMessageReceiver(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MaybeRevertMessageReceiverTransactor{contract: contract}, nil +} + +func NewMaybeRevertMessageReceiverFilterer(address common.Address, filterer bind.ContractFilterer) (*MaybeRevertMessageReceiverFilterer, error) { + contract, err := bindMaybeRevertMessageReceiver(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MaybeRevertMessageReceiverFilterer{contract: contract}, nil +} + +func bindMaybeRevertMessageReceiver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MaybeRevertMessageReceiverMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MaybeRevertMessageReceiver.Contract.MaybeRevertMessageReceiverCaller.contract.Call(opts, result, method, params...) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.Contract.MaybeRevertMessageReceiverTransactor.contract.Transfer(opts) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.Contract.MaybeRevertMessageReceiverTransactor.contract.Transact(opts, method, params...) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MaybeRevertMessageReceiver.Contract.contract.Call(opts, result, method, params...) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.Contract.contract.Transfer(opts) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.Contract.contract.Transact(opts, method, params...) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverCaller) SToRevert(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _MaybeRevertMessageReceiver.contract.Call(opts, &out, "s_toRevert") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverSession) SToRevert() (bool, error) { + return _MaybeRevertMessageReceiver.Contract.SToRevert(&_MaybeRevertMessageReceiver.CallOpts) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverCallerSession) SToRevert() (bool, error) { + return _MaybeRevertMessageReceiver.Contract.SToRevert(&_MaybeRevertMessageReceiver.CallOpts) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _MaybeRevertMessageReceiver.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _MaybeRevertMessageReceiver.Contract.SupportsInterface(&_MaybeRevertMessageReceiver.CallOpts, interfaceId) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _MaybeRevertMessageReceiver.Contract.SupportsInterface(&_MaybeRevertMessageReceiver.CallOpts, interfaceId) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverTransactor) CcipReceive(opts *bind.TransactOpts, arg0 ClientAny2EVMMessage) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.contract.Transact(opts, "ccipReceive", arg0) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverSession) CcipReceive(arg0 ClientAny2EVMMessage) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.Contract.CcipReceive(&_MaybeRevertMessageReceiver.TransactOpts, arg0) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverTransactorSession) CcipReceive(arg0 ClientAny2EVMMessage) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.Contract.CcipReceive(&_MaybeRevertMessageReceiver.TransactOpts, arg0) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverTransactor) SetErr(opts *bind.TransactOpts, err []byte) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.contract.Transact(opts, "setErr", err) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverSession) SetErr(err []byte) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.Contract.SetErr(&_MaybeRevertMessageReceiver.TransactOpts, err) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverTransactorSession) SetErr(err []byte) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.Contract.SetErr(&_MaybeRevertMessageReceiver.TransactOpts, err) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverTransactor) SetRevert(opts *bind.TransactOpts, toRevert bool) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.contract.Transact(opts, "setRevert", toRevert) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverSession) SetRevert(toRevert bool) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.Contract.SetRevert(&_MaybeRevertMessageReceiver.TransactOpts, toRevert) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverTransactorSession) SetRevert(toRevert bool) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.Contract.SetRevert(&_MaybeRevertMessageReceiver.TransactOpts, toRevert) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.contract.RawTransact(opts, nil) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverSession) Receive() (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.Contract.Receive(&_MaybeRevertMessageReceiver.TransactOpts) +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverTransactorSession) Receive() (*types.Transaction, error) { + return _MaybeRevertMessageReceiver.Contract.Receive(&_MaybeRevertMessageReceiver.TransactOpts) +} + +type MaybeRevertMessageReceiverMessageReceivedIterator struct { + Event *MaybeRevertMessageReceiverMessageReceived + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MaybeRevertMessageReceiverMessageReceivedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MaybeRevertMessageReceiverMessageReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MaybeRevertMessageReceiverMessageReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MaybeRevertMessageReceiverMessageReceivedIterator) Error() error { + return it.fail +} + +func (it *MaybeRevertMessageReceiverMessageReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MaybeRevertMessageReceiverMessageReceived struct { + Raw types.Log +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverFilterer) FilterMessageReceived(opts *bind.FilterOpts) (*MaybeRevertMessageReceiverMessageReceivedIterator, error) { + + logs, sub, err := _MaybeRevertMessageReceiver.contract.FilterLogs(opts, "MessageReceived") + if err != nil { + return nil, err + } + return &MaybeRevertMessageReceiverMessageReceivedIterator{contract: _MaybeRevertMessageReceiver.contract, event: "MessageReceived", logs: logs, sub: sub}, nil +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverFilterer) WatchMessageReceived(opts *bind.WatchOpts, sink chan<- *MaybeRevertMessageReceiverMessageReceived) (event.Subscription, error) { + + logs, sub, err := _MaybeRevertMessageReceiver.contract.WatchLogs(opts, "MessageReceived") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MaybeRevertMessageReceiverMessageReceived) + if err := _MaybeRevertMessageReceiver.contract.UnpackLog(event, "MessageReceived", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverFilterer) ParseMessageReceived(log types.Log) (*MaybeRevertMessageReceiverMessageReceived, error) { + event := new(MaybeRevertMessageReceiverMessageReceived) + if err := _MaybeRevertMessageReceiver.contract.UnpackLog(event, "MessageReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MaybeRevertMessageReceiverValueReceivedIterator struct { + Event *MaybeRevertMessageReceiverValueReceived + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MaybeRevertMessageReceiverValueReceivedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MaybeRevertMessageReceiverValueReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MaybeRevertMessageReceiverValueReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MaybeRevertMessageReceiverValueReceivedIterator) Error() error { + return it.fail +} + +func (it *MaybeRevertMessageReceiverValueReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MaybeRevertMessageReceiverValueReceived struct { + Amount *big.Int + Raw types.Log +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverFilterer) FilterValueReceived(opts *bind.FilterOpts) (*MaybeRevertMessageReceiverValueReceivedIterator, error) { + + logs, sub, err := _MaybeRevertMessageReceiver.contract.FilterLogs(opts, "ValueReceived") + if err != nil { + return nil, err + } + return &MaybeRevertMessageReceiverValueReceivedIterator{contract: _MaybeRevertMessageReceiver.contract, event: "ValueReceived", logs: logs, sub: sub}, nil +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverFilterer) WatchValueReceived(opts *bind.WatchOpts, sink chan<- *MaybeRevertMessageReceiverValueReceived) (event.Subscription, error) { + + logs, sub, err := _MaybeRevertMessageReceiver.contract.WatchLogs(opts, "ValueReceived") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MaybeRevertMessageReceiverValueReceived) + if err := _MaybeRevertMessageReceiver.contract.UnpackLog(event, "ValueReceived", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiverFilterer) ParseValueReceived(log types.Log) (*MaybeRevertMessageReceiverValueReceived, error) { + event := new(MaybeRevertMessageReceiverValueReceived) + if err := _MaybeRevertMessageReceiver.contract.UnpackLog(event, "ValueReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiver) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _MaybeRevertMessageReceiver.abi.Events["MessageReceived"].ID: + return _MaybeRevertMessageReceiver.ParseMessageReceived(log) + case _MaybeRevertMessageReceiver.abi.Events["ValueReceived"].ID: + return _MaybeRevertMessageReceiver.ParseValueReceived(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (MaybeRevertMessageReceiverMessageReceived) Topic() common.Hash { + return common.HexToHash("0xd82ce31e3523f6eeb2d24317b2b4133001e8472729657f663b68624c45f8f3e8") +} + +func (MaybeRevertMessageReceiverValueReceived) Topic() common.Hash { + return common.HexToHash("0xe12e3b7047ff60a2dd763cf536a43597e5ce7fe7aa7476345bd4cd079912bcef") +} + +func (_MaybeRevertMessageReceiver *MaybeRevertMessageReceiver) Address() common.Address { + return _MaybeRevertMessageReceiver.address +} + +type MaybeRevertMessageReceiverInterface interface { + SToRevert(opts *bind.CallOpts) (bool, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + CcipReceive(opts *bind.TransactOpts, arg0 ClientAny2EVMMessage) (*types.Transaction, error) + + SetErr(opts *bind.TransactOpts, err []byte) (*types.Transaction, error) + + SetRevert(opts *bind.TransactOpts, toRevert bool) (*types.Transaction, error) + + Receive(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterMessageReceived(opts *bind.FilterOpts) (*MaybeRevertMessageReceiverMessageReceivedIterator, error) + + WatchMessageReceived(opts *bind.WatchOpts, sink chan<- *MaybeRevertMessageReceiverMessageReceived) (event.Subscription, error) + + ParseMessageReceived(log types.Log) (*MaybeRevertMessageReceiverMessageReceived, error) + + FilterValueReceived(opts *bind.FilterOpts) (*MaybeRevertMessageReceiverValueReceivedIterator, error) + + WatchValueReceived(opts *bind.WatchOpts, sink chan<- *MaybeRevertMessageReceiverValueReceived) (event.Subscription, error) + + ParseValueReceived(log types.Log) (*MaybeRevertMessageReceiverValueReceived, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/message_hasher/message_hasher.go b/core/gethwrappers/ccip/generated/message_hasher/message_hasher.go new file mode 100644 index 0000000000..52434b5049 --- /dev/null +++ b/core/gethwrappers/ccip/generated/message_hasher/message_hasher.go @@ -0,0 +1,427 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package message_hasher + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientEVMExtraArgsV1 struct { + GasLimit *big.Int +} + +type ClientEVMExtraArgsV2 struct { + GasLimit *big.Int + AllowOutOfOrderExecution bool +} + +type InternalAny2EVMRampMessage struct { + Header InternalRampMessageHeader + Sender []byte + Data []byte + Receiver common.Address + GasLimit *big.Int + TokenAmounts []InternalRampTokenAmount +} + +type InternalRampMessageHeader struct { + MessageId [32]byte + SourceChainSelector uint64 + DestChainSelector uint64 + SequenceNumber uint64 + Nonce uint64 +} + +type InternalRampTokenAmount struct { + SourcePoolAddress []byte + DestTokenAddress []byte + ExtraData []byte + Amount *big.Int +} + +var MessageHasherMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"decodeEVMExtraArgsV1\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMExtraArgsV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"allowOutOfOrderExecution\",\"type\":\"bool\"}],\"name\":\"decodeEVMExtraArgsV2\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"allowOutOfOrderExecution\",\"type\":\"bool\"}],\"internalType\":\"structClient.EVMExtraArgsV2\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMExtraArgsV1\",\"name\":\"extraArgs\",\"type\":\"tuple\"}],\"name\":\"encodeEVMExtraArgsV1\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"allowOutOfOrderExecution\",\"type\":\"bool\"}],\"internalType\":\"structClient.EVMExtraArgsV2\",\"name\":\"extraArgs\",\"type\":\"tuple\"}],\"name\":\"encodeEVMExtraArgsV2\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"leafDomainSeparator\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"implicitMetadataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"fixedSizeFieldsHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"dataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"tokenAmountsHash\",\"type\":\"bytes32\"}],\"name\":\"encodeFinalHashPreimage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"name\":\"encodeFixedSizeFieldsHashPreimage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"any2EVMMessageHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"name\":\"encodeMetadataHashPreimage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"encodeTokenAmountsHashPreimage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610de7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063a91d3aeb11610076578063c63641bd1161005b578063c63641bd1461019e578063c7ca9a18146101f5578063e733d2091461020857600080fd5b8063a91d3aeb14610150578063b17df7141461016357600080fd5b8063902e94a0146100a85780639511afaa146100d157806399df8d05146100f2578063a1e747df1461013d575b600080fd5b6100bb6100b63660046107d9565b61021b565b6040516100c8919061087a565b60405180910390f35b6100e46100df366004610958565b610244565b6040519081526020016100c8565b6100bb610100366004610a62565b604080516020810196909652858101949094526060850192909252608084015260a0808401919091528151808403909101815260c0909201905290565b6100bb61014b366004610a9d565b610257565b6100bb61015e366004610b05565b610289565b61018f610171366004610b86565b60408051602080820183526000909152815190810190915290815290565b604051905181526020016100c8565b6101d86101ac366004610baf565b604080518082019091526000808252602082015250604080518082019091529182521515602082015290565b6040805182518152602092830151151592810192909252016100c8565b6100bb610203366004610bdb565b6102c1565b6100bb610216366004610c2f565b6102d2565b60608160405160200161022e9190610c71565b6040516020818303038152906040529050919050565b600061025083836102dd565b9392505050565b6060848484846040516020016102709493929190610d3d565b6040516020818303038152906040529050949350505050565b60608686868686866040516020016102a696959493929190610d7a565b60405160208183030381529060405290509695505050505050565b60606102cc8261043a565b92915050565b60606102cc826104fc565b815160208082015160409283015192516000938493610323937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101610d3d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052805160209182012086518051888401516060808b0151908401516080808d0151950151959761038a9794969395929491939101610d7a565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016103c19190610c71565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c00160405160208183030381529060405280519060200120905092915050565b604051815160248201526020820151151560448201526060907f181dcf1000000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b604051815160248201526060907f97a657c90000000000000000000000000000000000000000000000000000000090604401610479565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561058557610585610533565b60405290565b60405160c0810167ffffffffffffffff8111828210171561058557610585610533565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156105f5576105f5610533565b604052919050565b600082601f83011261060e57600080fd5b813567ffffffffffffffff81111561062857610628610533565b61065960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016105ae565b81815284602083860101111561066e57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261069c57600080fd5b8135602067ffffffffffffffff808311156106b9576106b9610533565b8260051b6106c88382016105ae565b93845285810183019383810190888611156106e257600080fd5b84880192505b858310156107cd578235848111156107005760008081fd5b88016080818b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018113156107365760008081fd5b61073e610562565b87830135878111156107505760008081fd5b61075e8d8a838701016105fd565b825250604080840135888111156107755760008081fd5b6107838e8b838801016105fd565b8a840152506060808501358981111561079c5760008081fd5b6107aa8f8c838901016105fd565b9284019290925293909201359281019290925250825291840191908401906106e8565b98975050505050505050565b6000602082840312156107eb57600080fd5b813567ffffffffffffffff81111561080257600080fd5b61080e8482850161068b565b949350505050565b6000815180845260005b8181101561083c57602081850181015186830182015201610820565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006102506020830184610816565b803567ffffffffffffffff811681146108a557600080fd5b919050565b600060a082840312156108bc57600080fd5b60405160a0810181811067ffffffffffffffff821117156108df576108df610533565b604052823581529050806108f56020840161088d565b60208201526109066040840161088d565b60408201526109176060840161088d565b60608201526109286080840161088d565b60808201525092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146108a557600080fd5b6000806040838503121561096b57600080fd5b823567ffffffffffffffff8082111561098357600080fd5b90840190610140828703121561099857600080fd5b6109a061058b565b6109aa87846108aa565b815260a0830135828111156109be57600080fd5b6109ca888286016105fd565b60208301525060c0830135828111156109e257600080fd5b6109ee888286016105fd565b604083015250610a0060e08401610934565b6060820152610100830135608082015261012083013582811115610a2357600080fd5b610a2f8882860161068b565b60a08301525093506020850135915080821115610a4b57600080fd5b50610a58858286016105fd565b9150509250929050565b600080600080600060a08688031215610a7a57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060008060808587031215610ab357600080fd5b84359350610ac36020860161088d565b9250610ad16040860161088d565b9150606085013567ffffffffffffffff811115610aed57600080fd5b610af9878288016105fd565b91505092959194509250565b60008060008060008060c08789031215610b1e57600080fd5b86359550602087013567ffffffffffffffff811115610b3c57600080fd5b610b4889828a016105fd565b955050610b5760408801610934565b9350610b656060880161088d565b925060808701359150610b7a60a0880161088d565b90509295509295509295565b600060208284031215610b9857600080fd5b5035919050565b803580151581146108a557600080fd5b60008060408385031215610bc257600080fd5b82359150610bd260208401610b9f565b90509250929050565b600060408284031215610bed57600080fd5b6040516040810181811067ffffffffffffffff82111715610c1057610c10610533565b60405282358152610c2360208401610b9f565b60208201529392505050565b600060208284031215610c4157600080fd5b6040516020810181811067ffffffffffffffff82111715610c6457610c64610533565b6040529135825250919050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015610d2f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0898403018552815160808151818652610cde82870182610816565b915050888201518582038a870152610cf68282610816565b9150508782015185820389870152610d0e8282610816565b60609384015196909301959095525094870194925090860190600101610c9a565b509098975050505050505050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152610d706080830184610816565b9695505050505050565b86815260c060208201526000610d9360c0830188610816565b73ffffffffffffffffffffffffffffffffffffffff9690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a0909101529291505056fea164736f6c6343000818000a", +} + +var MessageHasherABI = MessageHasherMetaData.ABI + +var MessageHasherBin = MessageHasherMetaData.Bin + +func DeployMessageHasher(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MessageHasher, error) { + parsed, err := MessageHasherMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MessageHasherBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MessageHasher{address: address, abi: *parsed, MessageHasherCaller: MessageHasherCaller{contract: contract}, MessageHasherTransactor: MessageHasherTransactor{contract: contract}, MessageHasherFilterer: MessageHasherFilterer{contract: contract}}, nil +} + +type MessageHasher struct { + address common.Address + abi abi.ABI + MessageHasherCaller + MessageHasherTransactor + MessageHasherFilterer +} + +type MessageHasherCaller struct { + contract *bind.BoundContract +} + +type MessageHasherTransactor struct { + contract *bind.BoundContract +} + +type MessageHasherFilterer struct { + contract *bind.BoundContract +} + +type MessageHasherSession struct { + Contract *MessageHasher + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type MessageHasherCallerSession struct { + Contract *MessageHasherCaller + CallOpts bind.CallOpts +} + +type MessageHasherTransactorSession struct { + Contract *MessageHasherTransactor + TransactOpts bind.TransactOpts +} + +type MessageHasherRaw struct { + Contract *MessageHasher +} + +type MessageHasherCallerRaw struct { + Contract *MessageHasherCaller +} + +type MessageHasherTransactorRaw struct { + Contract *MessageHasherTransactor +} + +func NewMessageHasher(address common.Address, backend bind.ContractBackend) (*MessageHasher, error) { + abi, err := abi.JSON(strings.NewReader(MessageHasherABI)) + if err != nil { + return nil, err + } + contract, err := bindMessageHasher(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MessageHasher{address: address, abi: abi, MessageHasherCaller: MessageHasherCaller{contract: contract}, MessageHasherTransactor: MessageHasherTransactor{contract: contract}, MessageHasherFilterer: MessageHasherFilterer{contract: contract}}, nil +} + +func NewMessageHasherCaller(address common.Address, caller bind.ContractCaller) (*MessageHasherCaller, error) { + contract, err := bindMessageHasher(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MessageHasherCaller{contract: contract}, nil +} + +func NewMessageHasherTransactor(address common.Address, transactor bind.ContractTransactor) (*MessageHasherTransactor, error) { + contract, err := bindMessageHasher(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MessageHasherTransactor{contract: contract}, nil +} + +func NewMessageHasherFilterer(address common.Address, filterer bind.ContractFilterer) (*MessageHasherFilterer, error) { + contract, err := bindMessageHasher(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MessageHasherFilterer{contract: contract}, nil +} + +func bindMessageHasher(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MessageHasherMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_MessageHasher *MessageHasherRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MessageHasher.Contract.MessageHasherCaller.contract.Call(opts, result, method, params...) +} + +func (_MessageHasher *MessageHasherRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MessageHasher.Contract.MessageHasherTransactor.contract.Transfer(opts) +} + +func (_MessageHasher *MessageHasherRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MessageHasher.Contract.MessageHasherTransactor.contract.Transact(opts, method, params...) +} + +func (_MessageHasher *MessageHasherCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MessageHasher.Contract.contract.Call(opts, result, method, params...) +} + +func (_MessageHasher *MessageHasherTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MessageHasher.Contract.contract.Transfer(opts) +} + +func (_MessageHasher *MessageHasherTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MessageHasher.Contract.contract.Transact(opts, method, params...) +} + +func (_MessageHasher *MessageHasherCaller) DecodeEVMExtraArgsV1(opts *bind.CallOpts, gasLimit *big.Int) (ClientEVMExtraArgsV1, error) { + var out []interface{} + err := _MessageHasher.contract.Call(opts, &out, "decodeEVMExtraArgsV1", gasLimit) + + if err != nil { + return *new(ClientEVMExtraArgsV1), err + } + + out0 := *abi.ConvertType(out[0], new(ClientEVMExtraArgsV1)).(*ClientEVMExtraArgsV1) + + return out0, err + +} + +func (_MessageHasher *MessageHasherSession) DecodeEVMExtraArgsV1(gasLimit *big.Int) (ClientEVMExtraArgsV1, error) { + return _MessageHasher.Contract.DecodeEVMExtraArgsV1(&_MessageHasher.CallOpts, gasLimit) +} + +func (_MessageHasher *MessageHasherCallerSession) DecodeEVMExtraArgsV1(gasLimit *big.Int) (ClientEVMExtraArgsV1, error) { + return _MessageHasher.Contract.DecodeEVMExtraArgsV1(&_MessageHasher.CallOpts, gasLimit) +} + +func (_MessageHasher *MessageHasherCaller) DecodeEVMExtraArgsV2(opts *bind.CallOpts, gasLimit *big.Int, allowOutOfOrderExecution bool) (ClientEVMExtraArgsV2, error) { + var out []interface{} + err := _MessageHasher.contract.Call(opts, &out, "decodeEVMExtraArgsV2", gasLimit, allowOutOfOrderExecution) + + if err != nil { + return *new(ClientEVMExtraArgsV2), err + } + + out0 := *abi.ConvertType(out[0], new(ClientEVMExtraArgsV2)).(*ClientEVMExtraArgsV2) + + return out0, err + +} + +func (_MessageHasher *MessageHasherSession) DecodeEVMExtraArgsV2(gasLimit *big.Int, allowOutOfOrderExecution bool) (ClientEVMExtraArgsV2, error) { + return _MessageHasher.Contract.DecodeEVMExtraArgsV2(&_MessageHasher.CallOpts, gasLimit, allowOutOfOrderExecution) +} + +func (_MessageHasher *MessageHasherCallerSession) DecodeEVMExtraArgsV2(gasLimit *big.Int, allowOutOfOrderExecution bool) (ClientEVMExtraArgsV2, error) { + return _MessageHasher.Contract.DecodeEVMExtraArgsV2(&_MessageHasher.CallOpts, gasLimit, allowOutOfOrderExecution) +} + +func (_MessageHasher *MessageHasherCaller) EncodeEVMExtraArgsV1(opts *bind.CallOpts, extraArgs ClientEVMExtraArgsV1) ([]byte, error) { + var out []interface{} + err := _MessageHasher.contract.Call(opts, &out, "encodeEVMExtraArgsV1", extraArgs) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_MessageHasher *MessageHasherSession) EncodeEVMExtraArgsV1(extraArgs ClientEVMExtraArgsV1) ([]byte, error) { + return _MessageHasher.Contract.EncodeEVMExtraArgsV1(&_MessageHasher.CallOpts, extraArgs) +} + +func (_MessageHasher *MessageHasherCallerSession) EncodeEVMExtraArgsV1(extraArgs ClientEVMExtraArgsV1) ([]byte, error) { + return _MessageHasher.Contract.EncodeEVMExtraArgsV1(&_MessageHasher.CallOpts, extraArgs) +} + +func (_MessageHasher *MessageHasherCaller) EncodeEVMExtraArgsV2(opts *bind.CallOpts, extraArgs ClientEVMExtraArgsV2) ([]byte, error) { + var out []interface{} + err := _MessageHasher.contract.Call(opts, &out, "encodeEVMExtraArgsV2", extraArgs) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_MessageHasher *MessageHasherSession) EncodeEVMExtraArgsV2(extraArgs ClientEVMExtraArgsV2) ([]byte, error) { + return _MessageHasher.Contract.EncodeEVMExtraArgsV2(&_MessageHasher.CallOpts, extraArgs) +} + +func (_MessageHasher *MessageHasherCallerSession) EncodeEVMExtraArgsV2(extraArgs ClientEVMExtraArgsV2) ([]byte, error) { + return _MessageHasher.Contract.EncodeEVMExtraArgsV2(&_MessageHasher.CallOpts, extraArgs) +} + +func (_MessageHasher *MessageHasherCaller) EncodeFinalHashPreimage(opts *bind.CallOpts, leafDomainSeparator [32]byte, implicitMetadataHash [32]byte, fixedSizeFieldsHash [32]byte, dataHash [32]byte, tokenAmountsHash [32]byte) ([]byte, error) { + var out []interface{} + err := _MessageHasher.contract.Call(opts, &out, "encodeFinalHashPreimage", leafDomainSeparator, implicitMetadataHash, fixedSizeFieldsHash, dataHash, tokenAmountsHash) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_MessageHasher *MessageHasherSession) EncodeFinalHashPreimage(leafDomainSeparator [32]byte, implicitMetadataHash [32]byte, fixedSizeFieldsHash [32]byte, dataHash [32]byte, tokenAmountsHash [32]byte) ([]byte, error) { + return _MessageHasher.Contract.EncodeFinalHashPreimage(&_MessageHasher.CallOpts, leafDomainSeparator, implicitMetadataHash, fixedSizeFieldsHash, dataHash, tokenAmountsHash) +} + +func (_MessageHasher *MessageHasherCallerSession) EncodeFinalHashPreimage(leafDomainSeparator [32]byte, implicitMetadataHash [32]byte, fixedSizeFieldsHash [32]byte, dataHash [32]byte, tokenAmountsHash [32]byte) ([]byte, error) { + return _MessageHasher.Contract.EncodeFinalHashPreimage(&_MessageHasher.CallOpts, leafDomainSeparator, implicitMetadataHash, fixedSizeFieldsHash, dataHash, tokenAmountsHash) +} + +func (_MessageHasher *MessageHasherCaller) EncodeFixedSizeFieldsHashPreimage(opts *bind.CallOpts, messageId [32]byte, sender []byte, receiver common.Address, sequenceNumber uint64, gasLimit *big.Int, nonce uint64) ([]byte, error) { + var out []interface{} + err := _MessageHasher.contract.Call(opts, &out, "encodeFixedSizeFieldsHashPreimage", messageId, sender, receiver, sequenceNumber, gasLimit, nonce) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_MessageHasher *MessageHasherSession) EncodeFixedSizeFieldsHashPreimage(messageId [32]byte, sender []byte, receiver common.Address, sequenceNumber uint64, gasLimit *big.Int, nonce uint64) ([]byte, error) { + return _MessageHasher.Contract.EncodeFixedSizeFieldsHashPreimage(&_MessageHasher.CallOpts, messageId, sender, receiver, sequenceNumber, gasLimit, nonce) +} + +func (_MessageHasher *MessageHasherCallerSession) EncodeFixedSizeFieldsHashPreimage(messageId [32]byte, sender []byte, receiver common.Address, sequenceNumber uint64, gasLimit *big.Int, nonce uint64) ([]byte, error) { + return _MessageHasher.Contract.EncodeFixedSizeFieldsHashPreimage(&_MessageHasher.CallOpts, messageId, sender, receiver, sequenceNumber, gasLimit, nonce) +} + +func (_MessageHasher *MessageHasherCaller) EncodeMetadataHashPreimage(opts *bind.CallOpts, any2EVMMessageHash [32]byte, sourceChainSelector uint64, destChainSelector uint64, onRamp []byte) ([]byte, error) { + var out []interface{} + err := _MessageHasher.contract.Call(opts, &out, "encodeMetadataHashPreimage", any2EVMMessageHash, sourceChainSelector, destChainSelector, onRamp) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_MessageHasher *MessageHasherSession) EncodeMetadataHashPreimage(any2EVMMessageHash [32]byte, sourceChainSelector uint64, destChainSelector uint64, onRamp []byte) ([]byte, error) { + return _MessageHasher.Contract.EncodeMetadataHashPreimage(&_MessageHasher.CallOpts, any2EVMMessageHash, sourceChainSelector, destChainSelector, onRamp) +} + +func (_MessageHasher *MessageHasherCallerSession) EncodeMetadataHashPreimage(any2EVMMessageHash [32]byte, sourceChainSelector uint64, destChainSelector uint64, onRamp []byte) ([]byte, error) { + return _MessageHasher.Contract.EncodeMetadataHashPreimage(&_MessageHasher.CallOpts, any2EVMMessageHash, sourceChainSelector, destChainSelector, onRamp) +} + +func (_MessageHasher *MessageHasherCaller) EncodeTokenAmountsHashPreimage(opts *bind.CallOpts, rampTokenAmounts []InternalRampTokenAmount) ([]byte, error) { + var out []interface{} + err := _MessageHasher.contract.Call(opts, &out, "encodeTokenAmountsHashPreimage", rampTokenAmounts) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_MessageHasher *MessageHasherSession) EncodeTokenAmountsHashPreimage(rampTokenAmounts []InternalRampTokenAmount) ([]byte, error) { + return _MessageHasher.Contract.EncodeTokenAmountsHashPreimage(&_MessageHasher.CallOpts, rampTokenAmounts) +} + +func (_MessageHasher *MessageHasherCallerSession) EncodeTokenAmountsHashPreimage(rampTokenAmounts []InternalRampTokenAmount) ([]byte, error) { + return _MessageHasher.Contract.EncodeTokenAmountsHashPreimage(&_MessageHasher.CallOpts, rampTokenAmounts) +} + +func (_MessageHasher *MessageHasherCaller) Hash(opts *bind.CallOpts, message InternalAny2EVMRampMessage, onRamp []byte) ([32]byte, error) { + var out []interface{} + err := _MessageHasher.contract.Call(opts, &out, "hash", message, onRamp) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_MessageHasher *MessageHasherSession) Hash(message InternalAny2EVMRampMessage, onRamp []byte) ([32]byte, error) { + return _MessageHasher.Contract.Hash(&_MessageHasher.CallOpts, message, onRamp) +} + +func (_MessageHasher *MessageHasherCallerSession) Hash(message InternalAny2EVMRampMessage, onRamp []byte) ([32]byte, error) { + return _MessageHasher.Contract.Hash(&_MessageHasher.CallOpts, message, onRamp) +} + +func (_MessageHasher *MessageHasher) Address() common.Address { + return _MessageHasher.address +} + +type MessageHasherInterface interface { + DecodeEVMExtraArgsV1(opts *bind.CallOpts, gasLimit *big.Int) (ClientEVMExtraArgsV1, error) + + DecodeEVMExtraArgsV2(opts *bind.CallOpts, gasLimit *big.Int, allowOutOfOrderExecution bool) (ClientEVMExtraArgsV2, error) + + EncodeEVMExtraArgsV1(opts *bind.CallOpts, extraArgs ClientEVMExtraArgsV1) ([]byte, error) + + EncodeEVMExtraArgsV2(opts *bind.CallOpts, extraArgs ClientEVMExtraArgsV2) ([]byte, error) + + EncodeFinalHashPreimage(opts *bind.CallOpts, leafDomainSeparator [32]byte, implicitMetadataHash [32]byte, fixedSizeFieldsHash [32]byte, dataHash [32]byte, tokenAmountsHash [32]byte) ([]byte, error) + + EncodeFixedSizeFieldsHashPreimage(opts *bind.CallOpts, messageId [32]byte, sender []byte, receiver common.Address, sequenceNumber uint64, gasLimit *big.Int, nonce uint64) ([]byte, error) + + EncodeMetadataHashPreimage(opts *bind.CallOpts, any2EVMMessageHash [32]byte, sourceChainSelector uint64, destChainSelector uint64, onRamp []byte) ([]byte, error) + + EncodeTokenAmountsHashPreimage(opts *bind.CallOpts, rampTokenAmounts []InternalRampTokenAmount) ([]byte, error) + + Hash(opts *bind.CallOpts, message InternalAny2EVMRampMessage, onRamp []byte) ([32]byte, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/mock_arm_contract/mock_arm_contract.go b/core/gethwrappers/ccip/generated/mock_arm_contract/mock_arm_contract.go new file mode 100644 index 0000000000..fff63bef80 --- /dev/null +++ b/core/gethwrappers/ccip/generated/mock_arm_contract/mock_arm_contract.go @@ -0,0 +1,746 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package mock_arm_contract + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type IRMNTaggedRoot struct { + CommitStore common.Address + Root [32]byte +} + +type RMNConfig struct { + Voters []RMNVoter + BlessWeightThreshold uint16 + CurseWeightThreshold uint16 +} + +type RMNUnvoteToCurseRecord struct { + CurseVoteAddr common.Address + CursesHash [32]byte + ForceUnvote bool +} + +type RMNVoter struct { + BlessVoteAddr common.Address + CurseVoteAddr common.Address + CurseUnvoteAddr common.Address + BlessWeight uint8 + CurseWeight uint8 +} + +var MockARMContractMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"CustomError\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseUnvoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"cursesHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"forceUnvote\",\"type\":\"bool\"}],\"internalType\":\"structRMN.UnvoteToCurseRecord[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"ownerUnvoteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"cursesHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"forceUnvote\",\"type\":\"bool\"}],\"internalType\":\"structRMN.UnvoteToCurseRecord[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"ownerUnvoteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"setRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"voteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"voteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610ed7806101576000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063618af128116100815780637a7c27491161005b5780637a7c2749146102b55780638da5cb5b146102c8578063f2fde38b146102f057600080fd5b8063618af1281461020a578063794860871461024357806379ba5097146102ad57600080fd5b8063397796f7116100b2578063397796f7146101ba5780633f42ab73146101c25780634d616771146101d957600080fd5b8063119a3527146100d9578063257174dc1461012b5780632cbc26bb14610192575b600080fd5b6101296100e73660046107fe565b50600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055565b005b6101296101393660046109db565b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550565b6101a56101a0366004610a29565b610303565b60405190151581526020015b60405180910390f35b6101a56103b7565b6101ca610424565b6040516101b193929190610a4b565b6101a56101e7366004610b1e565b5060015474010000000000000000000000000000000000000000900460ff161590565b610129610218366004610b36565b50600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff169055565b610129610251366004610b73565b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905550565b610129610565565b6101296102c3366004610b96565b610662565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101b1565b6101296102fe366004610c49565b610672565b60006002805461031290610c64565b1590506103575760026040517f5a4ff67100000000000000000000000000000000000000000000000000000000815260040161034e9190610cb1565b60405180910390fd5b60015474010000000000000000000000000000000000000000900460ff16806103b157507fffffffffffffffffffffffffffffffff00000000000000000000000000000000821660009081526006602052604090205460ff165b92915050565b6000600280546103c690610c64565b1590506104025760026040517f5a4ff67100000000000000000000000000000000000000000000000000000000815260040161034e9190610cb1565b5060015474010000000000000000000000000000000000000000900460ff1690565b6040805160608082018352815260006020820181905291810182905281906005546040805160038054608060208202840181019094526060830181815263ffffffff8087169664010000000090041694929392849284929184919060009085015b828210156105315760008481526020908190206040805160a08101825260038602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001808301548216858701526002909201549081169284019290925260ff74010000000000000000000000000000000000000000830481166060850152750100000000000000000000000000000000000000000090920490911660808301529083529092019101610485565b505050908252506001919091015461ffff808216602084015262010000909104166040909101529296919550919350915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161034e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600261066e8282610db0565b5050565b61067a610686565b61068381610709565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610707576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161034e565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161034e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561081057600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561086957610869610817565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156108b6576108b6610817565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146108e257600080fd5b919050565b600082601f8301126108f857600080fd5b8135602067ffffffffffffffff82111561091457610914610817565b610922818360051b0161086f565b8281526060928302850182019282820191908785111561094157600080fd5b8387015b8581101561099e5781818a03121561095d5760008081fd5b610965610846565b61096e826108be565b81528582013586820152604080830135801515811461098d5760008081fd5b908201528452928401928101610945565b5090979650505050505050565b80357fffffffffffffffffffffffffffffffff00000000000000000000000000000000811681146108e257600080fd5b600080604083850312156109ee57600080fd5b823567ffffffffffffffff811115610a0557600080fd5b610a11858286016108e7565b925050610a20602084016109ab565b90509250929050565b600060208284031215610a3b57600080fd5b610a44826109ab565b9392505050565b63ffffffff84811682528316602080830191909152606060408084018290528451848301839052805160c0860181905260009491820190859060e08801905b80831015610af1578351805173ffffffffffffffffffffffffffffffffffffffff9081168452868201518116878501528782015116878401528781015160ff908116898501526080918201511690830152928401926001929092019160a090910190610a8a565b509288015161ffff908116608089015260409098015190971660a090960195909552979650505050505050565b600060408284031215610b3057600080fd5b50919050565b600060208284031215610b4857600080fd5b813567ffffffffffffffff811115610b5f57600080fd5b610b6b848285016108e7565b949350505050565b60008060408385031215610b8657600080fd5b82359150610a20602084016109ab565b60006020808385031215610ba957600080fd5b823567ffffffffffffffff80821115610bc157600080fd5b818501915085601f830112610bd557600080fd5b813581811115610be757610be7610817565b610c17847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161086f565b91508082528684828501011115610c2d57600080fd5b8084840185840137600090820190930192909252509392505050565b600060208284031215610c5b57600080fd5b610a44826108be565b600181811c90821680610c7857607f821691505b602082108103610b30577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454610cc581610c64565b8060208701526040600180841660008114610ce75760018114610d2157610d51565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550610d51565b89600052602060002060005b85811015610d485781548b8201860152908301908801610d2d565b8a016040019650505b509398975050505050505050565b601f821115610dab576000816000526020600020601f850160051c81016020861015610d885750805b601f850160051c820191505b81811015610da757828155600101610d94565b5050505b505050565b815167ffffffffffffffff811115610dca57610dca610817565b610dde81610dd88454610c64565b84610d5f565b602080601f831160018114610e315760008415610dfb5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610da7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015610e7e57888601518255948401946001909101908401610e5f565b5085821015610eba57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", +} + +var MockARMContractABI = MockARMContractMetaData.ABI + +var MockARMContractBin = MockARMContractMetaData.Bin + +func DeployMockARMContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MockARMContract, error) { + parsed, err := MockARMContractMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MockARMContractBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MockARMContract{address: address, abi: *parsed, MockARMContractCaller: MockARMContractCaller{contract: contract}, MockARMContractTransactor: MockARMContractTransactor{contract: contract}, MockARMContractFilterer: MockARMContractFilterer{contract: contract}}, nil +} + +type MockARMContract struct { + address common.Address + abi abi.ABI + MockARMContractCaller + MockARMContractTransactor + MockARMContractFilterer +} + +type MockARMContractCaller struct { + contract *bind.BoundContract +} + +type MockARMContractTransactor struct { + contract *bind.BoundContract +} + +type MockARMContractFilterer struct { + contract *bind.BoundContract +} + +type MockARMContractSession struct { + Contract *MockARMContract + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type MockARMContractCallerSession struct { + Contract *MockARMContractCaller + CallOpts bind.CallOpts +} + +type MockARMContractTransactorSession struct { + Contract *MockARMContractTransactor + TransactOpts bind.TransactOpts +} + +type MockARMContractRaw struct { + Contract *MockARMContract +} + +type MockARMContractCallerRaw struct { + Contract *MockARMContractCaller +} + +type MockARMContractTransactorRaw struct { + Contract *MockARMContractTransactor +} + +func NewMockARMContract(address common.Address, backend bind.ContractBackend) (*MockARMContract, error) { + abi, err := abi.JSON(strings.NewReader(MockARMContractABI)) + if err != nil { + return nil, err + } + contract, err := bindMockARMContract(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MockARMContract{address: address, abi: abi, MockARMContractCaller: MockARMContractCaller{contract: contract}, MockARMContractTransactor: MockARMContractTransactor{contract: contract}, MockARMContractFilterer: MockARMContractFilterer{contract: contract}}, nil +} + +func NewMockARMContractCaller(address common.Address, caller bind.ContractCaller) (*MockARMContractCaller, error) { + contract, err := bindMockARMContract(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MockARMContractCaller{contract: contract}, nil +} + +func NewMockARMContractTransactor(address common.Address, transactor bind.ContractTransactor) (*MockARMContractTransactor, error) { + contract, err := bindMockARMContract(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MockARMContractTransactor{contract: contract}, nil +} + +func NewMockARMContractFilterer(address common.Address, filterer bind.ContractFilterer) (*MockARMContractFilterer, error) { + contract, err := bindMockARMContract(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MockARMContractFilterer{contract: contract}, nil +} + +func bindMockARMContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MockARMContractMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_MockARMContract *MockARMContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockARMContract.Contract.MockARMContractCaller.contract.Call(opts, result, method, params...) +} + +func (_MockARMContract *MockARMContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockARMContract.Contract.MockARMContractTransactor.contract.Transfer(opts) +} + +func (_MockARMContract *MockARMContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockARMContract.Contract.MockARMContractTransactor.contract.Transact(opts, method, params...) +} + +func (_MockARMContract *MockARMContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockARMContract.Contract.contract.Call(opts, result, method, params...) +} + +func (_MockARMContract *MockARMContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockARMContract.Contract.contract.Transfer(opts) +} + +func (_MockARMContract *MockARMContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockARMContract.Contract.contract.Transact(opts, method, params...) +} + +func (_MockARMContract *MockARMContractCaller) GetConfigDetails(opts *bind.CallOpts) (GetConfigDetails, + + error) { + var out []interface{} + err := _MockARMContract.contract.Call(opts, &out, "getConfigDetails") + + outstruct := new(GetConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.Version = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.Config = *abi.ConvertType(out[2], new(RMNConfig)).(*RMNConfig) + + return *outstruct, err + +} + +func (_MockARMContract *MockARMContractSession) GetConfigDetails() (GetConfigDetails, + + error) { + return _MockARMContract.Contract.GetConfigDetails(&_MockARMContract.CallOpts) +} + +func (_MockARMContract *MockARMContractCallerSession) GetConfigDetails() (GetConfigDetails, + + error) { + return _MockARMContract.Contract.GetConfigDetails(&_MockARMContract.CallOpts) +} + +func (_MockARMContract *MockARMContractCaller) IsBlessed(opts *bind.CallOpts, arg0 IRMNTaggedRoot) (bool, error) { + var out []interface{} + err := _MockARMContract.contract.Call(opts, &out, "isBlessed", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_MockARMContract *MockARMContractSession) IsBlessed(arg0 IRMNTaggedRoot) (bool, error) { + return _MockARMContract.Contract.IsBlessed(&_MockARMContract.CallOpts, arg0) +} + +func (_MockARMContract *MockARMContractCallerSession) IsBlessed(arg0 IRMNTaggedRoot) (bool, error) { + return _MockARMContract.Contract.IsBlessed(&_MockARMContract.CallOpts, arg0) +} + +func (_MockARMContract *MockARMContractCaller) IsCursed(opts *bind.CallOpts, subject [16]byte) (bool, error) { + var out []interface{} + err := _MockARMContract.contract.Call(opts, &out, "isCursed", subject) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_MockARMContract *MockARMContractSession) IsCursed(subject [16]byte) (bool, error) { + return _MockARMContract.Contract.IsCursed(&_MockARMContract.CallOpts, subject) +} + +func (_MockARMContract *MockARMContractCallerSession) IsCursed(subject [16]byte) (bool, error) { + return _MockARMContract.Contract.IsCursed(&_MockARMContract.CallOpts, subject) +} + +func (_MockARMContract *MockARMContractCaller) IsCursed0(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _MockARMContract.contract.Call(opts, &out, "isCursed0") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_MockARMContract *MockARMContractSession) IsCursed0() (bool, error) { + return _MockARMContract.Contract.IsCursed0(&_MockARMContract.CallOpts) +} + +func (_MockARMContract *MockARMContractCallerSession) IsCursed0() (bool, error) { + return _MockARMContract.Contract.IsCursed0(&_MockARMContract.CallOpts) +} + +func (_MockARMContract *MockARMContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _MockARMContract.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_MockARMContract *MockARMContractSession) Owner() (common.Address, error) { + return _MockARMContract.Contract.Owner(&_MockARMContract.CallOpts) +} + +func (_MockARMContract *MockARMContractCallerSession) Owner() (common.Address, error) { + return _MockARMContract.Contract.Owner(&_MockARMContract.CallOpts) +} + +func (_MockARMContract *MockARMContractTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockARMContract.contract.Transact(opts, "acceptOwnership") +} + +func (_MockARMContract *MockARMContractSession) AcceptOwnership() (*types.Transaction, error) { + return _MockARMContract.Contract.AcceptOwnership(&_MockARMContract.TransactOpts) +} + +func (_MockARMContract *MockARMContractTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _MockARMContract.Contract.AcceptOwnership(&_MockARMContract.TransactOpts) +} + +func (_MockARMContract *MockARMContractTransactor) OwnerUnvoteToCurse(opts *bind.TransactOpts, arg0 []RMNUnvoteToCurseRecord, subject [16]byte) (*types.Transaction, error) { + return _MockARMContract.contract.Transact(opts, "ownerUnvoteToCurse", arg0, subject) +} + +func (_MockARMContract *MockARMContractSession) OwnerUnvoteToCurse(arg0 []RMNUnvoteToCurseRecord, subject [16]byte) (*types.Transaction, error) { + return _MockARMContract.Contract.OwnerUnvoteToCurse(&_MockARMContract.TransactOpts, arg0, subject) +} + +func (_MockARMContract *MockARMContractTransactorSession) OwnerUnvoteToCurse(arg0 []RMNUnvoteToCurseRecord, subject [16]byte) (*types.Transaction, error) { + return _MockARMContract.Contract.OwnerUnvoteToCurse(&_MockARMContract.TransactOpts, arg0, subject) +} + +func (_MockARMContract *MockARMContractTransactor) OwnerUnvoteToCurse0(opts *bind.TransactOpts, arg0 []RMNUnvoteToCurseRecord) (*types.Transaction, error) { + return _MockARMContract.contract.Transact(opts, "ownerUnvoteToCurse0", arg0) +} + +func (_MockARMContract *MockARMContractSession) OwnerUnvoteToCurse0(arg0 []RMNUnvoteToCurseRecord) (*types.Transaction, error) { + return _MockARMContract.Contract.OwnerUnvoteToCurse0(&_MockARMContract.TransactOpts, arg0) +} + +func (_MockARMContract *MockARMContractTransactorSession) OwnerUnvoteToCurse0(arg0 []RMNUnvoteToCurseRecord) (*types.Transaction, error) { + return _MockARMContract.Contract.OwnerUnvoteToCurse0(&_MockARMContract.TransactOpts, arg0) +} + +func (_MockARMContract *MockARMContractTransactor) SetRevert(opts *bind.TransactOpts, err []byte) (*types.Transaction, error) { + return _MockARMContract.contract.Transact(opts, "setRevert", err) +} + +func (_MockARMContract *MockARMContractSession) SetRevert(err []byte) (*types.Transaction, error) { + return _MockARMContract.Contract.SetRevert(&_MockARMContract.TransactOpts, err) +} + +func (_MockARMContract *MockARMContractTransactorSession) SetRevert(err []byte) (*types.Transaction, error) { + return _MockARMContract.Contract.SetRevert(&_MockARMContract.TransactOpts, err) +} + +func (_MockARMContract *MockARMContractTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _MockARMContract.contract.Transact(opts, "transferOwnership", to) +} + +func (_MockARMContract *MockARMContractSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _MockARMContract.Contract.TransferOwnership(&_MockARMContract.TransactOpts, to) +} + +func (_MockARMContract *MockARMContractTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _MockARMContract.Contract.TransferOwnership(&_MockARMContract.TransactOpts, to) +} + +func (_MockARMContract *MockARMContractTransactor) VoteToCurse(opts *bind.TransactOpts, arg0 [32]byte) (*types.Transaction, error) { + return _MockARMContract.contract.Transact(opts, "voteToCurse", arg0) +} + +func (_MockARMContract *MockARMContractSession) VoteToCurse(arg0 [32]byte) (*types.Transaction, error) { + return _MockARMContract.Contract.VoteToCurse(&_MockARMContract.TransactOpts, arg0) +} + +func (_MockARMContract *MockARMContractTransactorSession) VoteToCurse(arg0 [32]byte) (*types.Transaction, error) { + return _MockARMContract.Contract.VoteToCurse(&_MockARMContract.TransactOpts, arg0) +} + +func (_MockARMContract *MockARMContractTransactor) VoteToCurse0(opts *bind.TransactOpts, arg0 [32]byte, subject [16]byte) (*types.Transaction, error) { + return _MockARMContract.contract.Transact(opts, "voteToCurse0", arg0, subject) +} + +func (_MockARMContract *MockARMContractSession) VoteToCurse0(arg0 [32]byte, subject [16]byte) (*types.Transaction, error) { + return _MockARMContract.Contract.VoteToCurse0(&_MockARMContract.TransactOpts, arg0, subject) +} + +func (_MockARMContract *MockARMContractTransactorSession) VoteToCurse0(arg0 [32]byte, subject [16]byte) (*types.Transaction, error) { + return _MockARMContract.Contract.VoteToCurse0(&_MockARMContract.TransactOpts, arg0, subject) +} + +type MockARMContractOwnershipTransferRequestedIterator struct { + Event *MockARMContractOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MockARMContractOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MockARMContractOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MockARMContractOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MockARMContractOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *MockARMContractOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MockARMContractOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_MockARMContract *MockARMContractFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MockARMContractOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _MockARMContract.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &MockARMContractOwnershipTransferRequestedIterator{contract: _MockARMContract.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_MockARMContract *MockARMContractFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MockARMContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _MockARMContract.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MockARMContractOwnershipTransferRequested) + if err := _MockARMContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MockARMContract *MockARMContractFilterer) ParseOwnershipTransferRequested(log types.Log) (*MockARMContractOwnershipTransferRequested, error) { + event := new(MockARMContractOwnershipTransferRequested) + if err := _MockARMContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MockARMContractOwnershipTransferredIterator struct { + Event *MockARMContractOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MockARMContractOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MockARMContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MockARMContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MockARMContractOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *MockARMContractOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MockARMContractOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_MockARMContract *MockARMContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MockARMContractOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _MockARMContract.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &MockARMContractOwnershipTransferredIterator{contract: _MockARMContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_MockARMContract *MockARMContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MockARMContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _MockARMContract.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MockARMContractOwnershipTransferred) + if err := _MockARMContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MockARMContract *MockARMContractFilterer) ParseOwnershipTransferred(log types.Log) (*MockARMContractOwnershipTransferred, error) { + event := new(MockARMContractOwnershipTransferred) + if err := _MockARMContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetConfigDetails struct { + Version uint32 + BlockNumber uint32 + Config RMNConfig +} + +func (_MockARMContract *MockARMContract) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _MockARMContract.abi.Events["OwnershipTransferRequested"].ID: + return _MockARMContract.ParseOwnershipTransferRequested(log) + case _MockARMContract.abi.Events["OwnershipTransferred"].ID: + return _MockARMContract.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (MockARMContractOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (MockARMContractOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_MockARMContract *MockARMContract) Address() common.Address { + return _MockARMContract.address +} + +type MockARMContractInterface interface { + GetConfigDetails(opts *bind.CallOpts) (GetConfigDetails, + + error) + + IsBlessed(opts *bind.CallOpts, arg0 IRMNTaggedRoot) (bool, error) + + IsCursed(opts *bind.CallOpts, subject [16]byte) (bool, error) + + IsCursed0(opts *bind.CallOpts) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + OwnerUnvoteToCurse(opts *bind.TransactOpts, arg0 []RMNUnvoteToCurseRecord, subject [16]byte) (*types.Transaction, error) + + OwnerUnvoteToCurse0(opts *bind.TransactOpts, arg0 []RMNUnvoteToCurseRecord) (*types.Transaction, error) + + SetRevert(opts *bind.TransactOpts, err []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + VoteToCurse(opts *bind.TransactOpts, arg0 [32]byte) (*types.Transaction, error) + + VoteToCurse0(opts *bind.TransactOpts, arg0 [32]byte, subject [16]byte) (*types.Transaction, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MockARMContractOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MockARMContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*MockARMContractOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MockARMContractOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MockARMContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*MockARMContractOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/mock_usdc_token_messenger/mock_usdc_token_messenger.go b/core/gethwrappers/ccip/generated/mock_usdc_token_messenger/mock_usdc_token_messenger.go new file mode 100644 index 0000000000..cdd66b76cb --- /dev/null +++ b/core/gethwrappers/ccip/generated/mock_usdc_token_messenger/mock_usdc_token_messenger.go @@ -0,0 +1,488 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package mock_usdc_token_messenger + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var MockE2EUSDCTokenMessengerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burnToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"mintRecipient\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"destinationDomain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"destinationTokenMessenger\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"destinationCaller\",\"type\":\"bytes32\"}],\"name\":\"DepositForBurn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DESTINATION_TOKEN_MESSENGER\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"mintRecipient\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"burnToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationCaller\",\"type\":\"bytes32\"}],\"name\":\"depositForBurnWithCaller\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localMessageTransmitter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localMessageTransmitterWithRelay\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitterWithRelay\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageBodyVersion\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_nonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e060405234801561001057600080fd5b5060405161083c38038061083c83398101604081905261002f91610063565b63ffffffff909116608052600080546001600160401b03191660011790556001600160a01b031660a081905260c0526100b2565b6000806040838503121561007657600080fd5b825163ffffffff8116811461008a57600080fd5b60208401519092506001600160a01b03811681146100a757600080fd5b809150509250929050565b60805160a05160c0516107486100f460003960008181610129015281816104aa015261056a01526000607901526000818160fa01526102d801526107486000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063a250c66a11610050578063a250c66a14610124578063f856ddb61461014b578063fb8406a91461015e57600080fd5b80632c121921146100775780637eccf63e146100c35780639cdbb181146100f0575b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6000546100d79067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100ba565b60405163ffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100ba565b6100997f000000000000000000000000000000000000000000000000000000000000000081565b6100d76101593660046105ad565b610193565b6101857f17c71eed51b181d8ae1908b4743526c6dbf099c201f158a1acd5f6718e82e8f681565b6040519081526020016100ba565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810186905260009073ffffffffffffffffffffffffffffffffffffffff8416906323b872dd906064016020604051808303816000875af115801561020f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102339190610621565b506040517f42966c680000000000000000000000000000000000000000000000000000000081526004810187905273ffffffffffffffffffffffffffffffffffffffff8416906342966c6890602401600060405180830381600087803b15801561029c57600080fd5b505af11580156102b0573d6000803e3d6000fd5b50506040517fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e01b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b16602482015260388101879052605881018990523360788201526000925060980190506040516020818303038152906040529050610386867f17c71eed51b181d8ae1908b4743526c6dbf099c201f158a1acd5f6718e82e8f68584610466565b600080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169182179055604080518981526020810188905263ffffffff8916918101919091527f17c71eed51b181d8ae1908b4743526c6dbf099c201f158a1acd5f6718e82e8f6606082015260808101859052339173ffffffffffffffffffffffffffffffffffffffff8716917f2fa9ca894982930190727e75500a97d8dc500233a5065e0f3126c48fbe0343c09060a00160405180910390a4505060005467ffffffffffffffff1695945050505050565b60008261052d576040517f0ba469bc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690630ba469bc906104e3908890889087906004016106ae565b6020604051808303816000875af1158015610502573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052691906106dc565b90506105a5565b6040517ff7259a7500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f7259a75906104e3908890889088908890600401610706565b949350505050565b600080600080600060a086880312156105c557600080fd5b85359450602086013563ffffffff811681146105e057600080fd5b935060408601359250606086013573ffffffffffffffffffffffffffffffffffffffff8116811461061057600080fd5b949793965091946080013592915050565b60006020828403121561063357600080fd5b8151801515811461064357600080fd5b9392505050565b6000815180845260005b8181101561067057602081850181015186830182015201610654565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b63ffffffff841681528260208201526060604082015260006106d3606083018461064a565b95945050505050565b6000602082840312156106ee57600080fd5b815167ffffffffffffffff8116811461064357600080fd5b63ffffffff85168152836020820152826040820152608060608201526000610731608083018461064a565b969550505050505056fea164736f6c6343000818000a", +} + +var MockE2EUSDCTokenMessengerABI = MockE2EUSDCTokenMessengerMetaData.ABI + +var MockE2EUSDCTokenMessengerBin = MockE2EUSDCTokenMessengerMetaData.Bin + +func DeployMockE2EUSDCTokenMessenger(auth *bind.TransactOpts, backend bind.ContractBackend, version uint32, transmitter common.Address) (common.Address, *types.Transaction, *MockE2EUSDCTokenMessenger, error) { + parsed, err := MockE2EUSDCTokenMessengerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MockE2EUSDCTokenMessengerBin), backend, version, transmitter) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MockE2EUSDCTokenMessenger{address: address, abi: *parsed, MockE2EUSDCTokenMessengerCaller: MockE2EUSDCTokenMessengerCaller{contract: contract}, MockE2EUSDCTokenMessengerTransactor: MockE2EUSDCTokenMessengerTransactor{contract: contract}, MockE2EUSDCTokenMessengerFilterer: MockE2EUSDCTokenMessengerFilterer{contract: contract}}, nil +} + +type MockE2EUSDCTokenMessenger struct { + address common.Address + abi abi.ABI + MockE2EUSDCTokenMessengerCaller + MockE2EUSDCTokenMessengerTransactor + MockE2EUSDCTokenMessengerFilterer +} + +type MockE2EUSDCTokenMessengerCaller struct { + contract *bind.BoundContract +} + +type MockE2EUSDCTokenMessengerTransactor struct { + contract *bind.BoundContract +} + +type MockE2EUSDCTokenMessengerFilterer struct { + contract *bind.BoundContract +} + +type MockE2EUSDCTokenMessengerSession struct { + Contract *MockE2EUSDCTokenMessenger + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type MockE2EUSDCTokenMessengerCallerSession struct { + Contract *MockE2EUSDCTokenMessengerCaller + CallOpts bind.CallOpts +} + +type MockE2EUSDCTokenMessengerTransactorSession struct { + Contract *MockE2EUSDCTokenMessengerTransactor + TransactOpts bind.TransactOpts +} + +type MockE2EUSDCTokenMessengerRaw struct { + Contract *MockE2EUSDCTokenMessenger +} + +type MockE2EUSDCTokenMessengerCallerRaw struct { + Contract *MockE2EUSDCTokenMessengerCaller +} + +type MockE2EUSDCTokenMessengerTransactorRaw struct { + Contract *MockE2EUSDCTokenMessengerTransactor +} + +func NewMockE2EUSDCTokenMessenger(address common.Address, backend bind.ContractBackend) (*MockE2EUSDCTokenMessenger, error) { + abi, err := abi.JSON(strings.NewReader(MockE2EUSDCTokenMessengerABI)) + if err != nil { + return nil, err + } + contract, err := bindMockE2EUSDCTokenMessenger(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MockE2EUSDCTokenMessenger{address: address, abi: abi, MockE2EUSDCTokenMessengerCaller: MockE2EUSDCTokenMessengerCaller{contract: contract}, MockE2EUSDCTokenMessengerTransactor: MockE2EUSDCTokenMessengerTransactor{contract: contract}, MockE2EUSDCTokenMessengerFilterer: MockE2EUSDCTokenMessengerFilterer{contract: contract}}, nil +} + +func NewMockE2EUSDCTokenMessengerCaller(address common.Address, caller bind.ContractCaller) (*MockE2EUSDCTokenMessengerCaller, error) { + contract, err := bindMockE2EUSDCTokenMessenger(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MockE2EUSDCTokenMessengerCaller{contract: contract}, nil +} + +func NewMockE2EUSDCTokenMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*MockE2EUSDCTokenMessengerTransactor, error) { + contract, err := bindMockE2EUSDCTokenMessenger(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MockE2EUSDCTokenMessengerTransactor{contract: contract}, nil +} + +func NewMockE2EUSDCTokenMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*MockE2EUSDCTokenMessengerFilterer, error) { + contract, err := bindMockE2EUSDCTokenMessenger(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MockE2EUSDCTokenMessengerFilterer{contract: contract}, nil +} + +func bindMockE2EUSDCTokenMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MockE2EUSDCTokenMessengerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockE2EUSDCTokenMessenger.Contract.MockE2EUSDCTokenMessengerCaller.contract.Call(opts, result, method, params...) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockE2EUSDCTokenMessenger.Contract.MockE2EUSDCTokenMessengerTransactor.contract.Transfer(opts) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockE2EUSDCTokenMessenger.Contract.MockE2EUSDCTokenMessengerTransactor.contract.Transact(opts, method, params...) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockE2EUSDCTokenMessenger.Contract.contract.Call(opts, result, method, params...) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockE2EUSDCTokenMessenger.Contract.contract.Transfer(opts) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockE2EUSDCTokenMessenger.Contract.contract.Transact(opts, method, params...) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerCaller) DESTINATIONTOKENMESSENGER(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _MockE2EUSDCTokenMessenger.contract.Call(opts, &out, "DESTINATION_TOKEN_MESSENGER") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerSession) DESTINATIONTOKENMESSENGER() ([32]byte, error) { + return _MockE2EUSDCTokenMessenger.Contract.DESTINATIONTOKENMESSENGER(&_MockE2EUSDCTokenMessenger.CallOpts) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerCallerSession) DESTINATIONTOKENMESSENGER() ([32]byte, error) { + return _MockE2EUSDCTokenMessenger.Contract.DESTINATIONTOKENMESSENGER(&_MockE2EUSDCTokenMessenger.CallOpts) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerCaller) LocalMessageTransmitter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _MockE2EUSDCTokenMessenger.contract.Call(opts, &out, "localMessageTransmitter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerSession) LocalMessageTransmitter() (common.Address, error) { + return _MockE2EUSDCTokenMessenger.Contract.LocalMessageTransmitter(&_MockE2EUSDCTokenMessenger.CallOpts) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerCallerSession) LocalMessageTransmitter() (common.Address, error) { + return _MockE2EUSDCTokenMessenger.Contract.LocalMessageTransmitter(&_MockE2EUSDCTokenMessenger.CallOpts) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerCaller) LocalMessageTransmitterWithRelay(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _MockE2EUSDCTokenMessenger.contract.Call(opts, &out, "localMessageTransmitterWithRelay") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerSession) LocalMessageTransmitterWithRelay() (common.Address, error) { + return _MockE2EUSDCTokenMessenger.Contract.LocalMessageTransmitterWithRelay(&_MockE2EUSDCTokenMessenger.CallOpts) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerCallerSession) LocalMessageTransmitterWithRelay() (common.Address, error) { + return _MockE2EUSDCTokenMessenger.Contract.LocalMessageTransmitterWithRelay(&_MockE2EUSDCTokenMessenger.CallOpts) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerCaller) MessageBodyVersion(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _MockE2EUSDCTokenMessenger.contract.Call(opts, &out, "messageBodyVersion") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerSession) MessageBodyVersion() (uint32, error) { + return _MockE2EUSDCTokenMessenger.Contract.MessageBodyVersion(&_MockE2EUSDCTokenMessenger.CallOpts) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerCallerSession) MessageBodyVersion() (uint32, error) { + return _MockE2EUSDCTokenMessenger.Contract.MessageBodyVersion(&_MockE2EUSDCTokenMessenger.CallOpts) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerCaller) SNonce(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _MockE2EUSDCTokenMessenger.contract.Call(opts, &out, "s_nonce") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerSession) SNonce() (uint64, error) { + return _MockE2EUSDCTokenMessenger.Contract.SNonce(&_MockE2EUSDCTokenMessenger.CallOpts) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerCallerSession) SNonce() (uint64, error) { + return _MockE2EUSDCTokenMessenger.Contract.SNonce(&_MockE2EUSDCTokenMessenger.CallOpts) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerTransactor) DepositForBurnWithCaller(opts *bind.TransactOpts, amount *big.Int, destinationDomain uint32, mintRecipient [32]byte, burnToken common.Address, destinationCaller [32]byte) (*types.Transaction, error) { + return _MockE2EUSDCTokenMessenger.contract.Transact(opts, "depositForBurnWithCaller", amount, destinationDomain, mintRecipient, burnToken, destinationCaller) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerSession) DepositForBurnWithCaller(amount *big.Int, destinationDomain uint32, mintRecipient [32]byte, burnToken common.Address, destinationCaller [32]byte) (*types.Transaction, error) { + return _MockE2EUSDCTokenMessenger.Contract.DepositForBurnWithCaller(&_MockE2EUSDCTokenMessenger.TransactOpts, amount, destinationDomain, mintRecipient, burnToken, destinationCaller) +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerTransactorSession) DepositForBurnWithCaller(amount *big.Int, destinationDomain uint32, mintRecipient [32]byte, burnToken common.Address, destinationCaller [32]byte) (*types.Transaction, error) { + return _MockE2EUSDCTokenMessenger.Contract.DepositForBurnWithCaller(&_MockE2EUSDCTokenMessenger.TransactOpts, amount, destinationDomain, mintRecipient, burnToken, destinationCaller) +} + +type MockE2EUSDCTokenMessengerDepositForBurnIterator struct { + Event *MockE2EUSDCTokenMessengerDepositForBurn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MockE2EUSDCTokenMessengerDepositForBurnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MockE2EUSDCTokenMessengerDepositForBurn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MockE2EUSDCTokenMessengerDepositForBurn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MockE2EUSDCTokenMessengerDepositForBurnIterator) Error() error { + return it.fail +} + +func (it *MockE2EUSDCTokenMessengerDepositForBurnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MockE2EUSDCTokenMessengerDepositForBurn struct { + Nonce uint64 + BurnToken common.Address + Amount *big.Int + Depositor common.Address + MintRecipient [32]byte + DestinationDomain uint32 + DestinationTokenMessenger [32]byte + DestinationCaller [32]byte + Raw types.Log +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerFilterer) FilterDepositForBurn(opts *bind.FilterOpts, nonce []uint64, burnToken []common.Address, depositor []common.Address) (*MockE2EUSDCTokenMessengerDepositForBurnIterator, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var burnTokenRule []interface{} + for _, burnTokenItem := range burnToken { + burnTokenRule = append(burnTokenRule, burnTokenItem) + } + + var depositorRule []interface{} + for _, depositorItem := range depositor { + depositorRule = append(depositorRule, depositorItem) + } + + logs, sub, err := _MockE2EUSDCTokenMessenger.contract.FilterLogs(opts, "DepositForBurn", nonceRule, burnTokenRule, depositorRule) + if err != nil { + return nil, err + } + return &MockE2EUSDCTokenMessengerDepositForBurnIterator{contract: _MockE2EUSDCTokenMessenger.contract, event: "DepositForBurn", logs: logs, sub: sub}, nil +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerFilterer) WatchDepositForBurn(opts *bind.WatchOpts, sink chan<- *MockE2EUSDCTokenMessengerDepositForBurn, nonce []uint64, burnToken []common.Address, depositor []common.Address) (event.Subscription, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var burnTokenRule []interface{} + for _, burnTokenItem := range burnToken { + burnTokenRule = append(burnTokenRule, burnTokenItem) + } + + var depositorRule []interface{} + for _, depositorItem := range depositor { + depositorRule = append(depositorRule, depositorItem) + } + + logs, sub, err := _MockE2EUSDCTokenMessenger.contract.WatchLogs(opts, "DepositForBurn", nonceRule, burnTokenRule, depositorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MockE2EUSDCTokenMessengerDepositForBurn) + if err := _MockE2EUSDCTokenMessenger.contract.UnpackLog(event, "DepositForBurn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessengerFilterer) ParseDepositForBurn(log types.Log) (*MockE2EUSDCTokenMessengerDepositForBurn, error) { + event := new(MockE2EUSDCTokenMessengerDepositForBurn) + if err := _MockE2EUSDCTokenMessenger.contract.UnpackLog(event, "DepositForBurn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessenger) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _MockE2EUSDCTokenMessenger.abi.Events["DepositForBurn"].ID: + return _MockE2EUSDCTokenMessenger.ParseDepositForBurn(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (MockE2EUSDCTokenMessengerDepositForBurn) Topic() common.Hash { + return common.HexToHash("0x2fa9ca894982930190727e75500a97d8dc500233a5065e0f3126c48fbe0343c0") +} + +func (_MockE2EUSDCTokenMessenger *MockE2EUSDCTokenMessenger) Address() common.Address { + return _MockE2EUSDCTokenMessenger.address +} + +type MockE2EUSDCTokenMessengerInterface interface { + DESTINATIONTOKENMESSENGER(opts *bind.CallOpts) ([32]byte, error) + + LocalMessageTransmitter(opts *bind.CallOpts) (common.Address, error) + + LocalMessageTransmitterWithRelay(opts *bind.CallOpts) (common.Address, error) + + MessageBodyVersion(opts *bind.CallOpts) (uint32, error) + + SNonce(opts *bind.CallOpts) (uint64, error) + + DepositForBurnWithCaller(opts *bind.TransactOpts, amount *big.Int, destinationDomain uint32, mintRecipient [32]byte, burnToken common.Address, destinationCaller [32]byte) (*types.Transaction, error) + + FilterDepositForBurn(opts *bind.FilterOpts, nonce []uint64, burnToken []common.Address, depositor []common.Address) (*MockE2EUSDCTokenMessengerDepositForBurnIterator, error) + + WatchDepositForBurn(opts *bind.WatchOpts, sink chan<- *MockE2EUSDCTokenMessengerDepositForBurn, nonce []uint64, burnToken []common.Address, depositor []common.Address) (event.Subscription, error) + + ParseDepositForBurn(log types.Log) (*MockE2EUSDCTokenMessengerDepositForBurn, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter/mock_usdc_token_transmitter.go b/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter/mock_usdc_token_transmitter.go new file mode 100644 index 0000000000..b31a834407 --- /dev/null +++ b/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter/mock_usdc_token_transmitter.go @@ -0,0 +1,471 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package mock_usdc_token_transmitter + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var MockE2EUSDCTransmitterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_version\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"MessageSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextAvailableNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"receiveMessage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_shouldSucceed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"recipient\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"messageBody\",\"type\":\"bytes\"}],\"name\":\"sendMessage\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"recipient\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"destinationCaller\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"messageBody\",\"type\":\"bytes\"}],\"name\":\"sendMessageWithCaller\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"shouldSucceed\",\"type\":\"bool\"}],\"name\":\"setShouldSucceed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e060405234801561001057600080fd5b5060405161097b38038061097b83398101604081905261002f91610076565b63ffffffff928316608052911660a0526000805460ff191660011790556001600160a01b031660c0526100ca565b805163ffffffff8116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005d565b92506100a26020850161005d565b60408501519092506001600160a01b03811681146100bf57600080fd5b809150509250925092565b60805160a05160c0516108756101066000396000610256015260008181610140015261046001526000818160c0015261043f01526108756000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638371744e1161005b5780638371744e146101255780638d3638f41461013e5780639e31ddb614610164578063f7259a75146101a557600080fd5b80630ba469bc1461008d57806354fd4d50146100be57806357ecfd28146100f55780637a64293514610118575b600080fd5b6100a061009b366004610552565b6101b8565b60405167ffffffffffffffff90911681526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405163ffffffff90911681526020016100b5565b6101086101033660046105ac565b6101e1565b60405190151581526020016100b5565b6000546101089060ff1681565b6000546100a090610100900467ffffffffffffffff1681565b7f00000000000000000000000000000000000000000000000000000000000000006100e0565b6101a361017236600461060c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b005b6100a06101b3366004610635565b6102c2565b600080806101c4610372565b9050336101d688888584868b8b6103d4565b509695505050505050565b6000806101f260546040878961069d565b6101fb916106c7565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815260609190911c60048201819052683635c9adc5dea000006024830152915073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561029a57600080fd5b505af11580156102ae573d6000803e3d6000fd5b505060005460ff1698975050505050505050565b600083610356576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f44657374696e6174696f6e2063616c6c6572206d757374206265206e6f6e7a6560448201527f726f00000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610360610372565b9050336101d688888884868a8a6103d4565b60008054610100900467ffffffffffffffff1661039081600161070f565b6000805467ffffffffffffffff92909216610100027fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff909216919091179055919050565b8561043b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f526563697069656e74206d757374206265206e6f6e7a65726f00000000000000604482015260640161034d565b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008986888b8b898960405160200161049e9998979695949392919061075e565b60405160208183030381529060405290507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036816040516104de91906107fb565b60405180910390a15050505050505050565b803563ffffffff8116811461050457600080fd5b919050565b60008083601f84011261051b57600080fd5b50813567ffffffffffffffff81111561053357600080fd5b60208301915083602082850101111561054b57600080fd5b9250929050565b6000806000806060858703121561056857600080fd5b610571856104f0565b935060208501359250604085013567ffffffffffffffff81111561059457600080fd5b6105a087828801610509565b95989497509550505050565b600080600080604085870312156105c257600080fd5b843567ffffffffffffffff808211156105da57600080fd5b6105e688838901610509565b909650945060208701359150808211156105ff57600080fd5b506105a087828801610509565b60006020828403121561061e57600080fd5b8135801515811461062e57600080fd5b9392505050565b60008060008060006080868803121561064d57600080fd5b610656866104f0565b94506020860135935060408601359250606086013567ffffffffffffffff81111561068057600080fd5b61068c88828901610509565b969995985093965092949392505050565b600080858511156106ad57600080fd5b838611156106ba57600080fd5b5050820193919092039150565b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000081358181169160148510156107075780818660140360031b1b83161692505b505092915050565b67ffffffffffffffff818116838216019080821115610757577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5092915050565b60007fffffffff00000000000000000000000000000000000000000000000000000000808c60e01b168352808b60e01b166004840152808a60e01b166008840152507fffffffffffffffff0000000000000000000000000000000000000000000000008860c01b16600c83015286601483015285603483015284605483015282846074840137506000910160740190815298975050505050505050565b60006020808352835180602085015260005b818110156108295785810183015185820160400152820161080d565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050509291505056fea164736f6c6343000818000a", +} + +var MockE2EUSDCTransmitterABI = MockE2EUSDCTransmitterMetaData.ABI + +var MockE2EUSDCTransmitterBin = MockE2EUSDCTransmitterMetaData.Bin + +func DeployMockE2EUSDCTransmitter(auth *bind.TransactOpts, backend bind.ContractBackend, _version uint32, _localDomain uint32, token common.Address) (common.Address, *types.Transaction, *MockE2EUSDCTransmitter, error) { + parsed, err := MockE2EUSDCTransmitterMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MockE2EUSDCTransmitterBin), backend, _version, _localDomain, token) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MockE2EUSDCTransmitter{address: address, abi: *parsed, MockE2EUSDCTransmitterCaller: MockE2EUSDCTransmitterCaller{contract: contract}, MockE2EUSDCTransmitterTransactor: MockE2EUSDCTransmitterTransactor{contract: contract}, MockE2EUSDCTransmitterFilterer: MockE2EUSDCTransmitterFilterer{contract: contract}}, nil +} + +type MockE2EUSDCTransmitter struct { + address common.Address + abi abi.ABI + MockE2EUSDCTransmitterCaller + MockE2EUSDCTransmitterTransactor + MockE2EUSDCTransmitterFilterer +} + +type MockE2EUSDCTransmitterCaller struct { + contract *bind.BoundContract +} + +type MockE2EUSDCTransmitterTransactor struct { + contract *bind.BoundContract +} + +type MockE2EUSDCTransmitterFilterer struct { + contract *bind.BoundContract +} + +type MockE2EUSDCTransmitterSession struct { + Contract *MockE2EUSDCTransmitter + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type MockE2EUSDCTransmitterCallerSession struct { + Contract *MockE2EUSDCTransmitterCaller + CallOpts bind.CallOpts +} + +type MockE2EUSDCTransmitterTransactorSession struct { + Contract *MockE2EUSDCTransmitterTransactor + TransactOpts bind.TransactOpts +} + +type MockE2EUSDCTransmitterRaw struct { + Contract *MockE2EUSDCTransmitter +} + +type MockE2EUSDCTransmitterCallerRaw struct { + Contract *MockE2EUSDCTransmitterCaller +} + +type MockE2EUSDCTransmitterTransactorRaw struct { + Contract *MockE2EUSDCTransmitterTransactor +} + +func NewMockE2EUSDCTransmitter(address common.Address, backend bind.ContractBackend) (*MockE2EUSDCTransmitter, error) { + abi, err := abi.JSON(strings.NewReader(MockE2EUSDCTransmitterABI)) + if err != nil { + return nil, err + } + contract, err := bindMockE2EUSDCTransmitter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MockE2EUSDCTransmitter{address: address, abi: abi, MockE2EUSDCTransmitterCaller: MockE2EUSDCTransmitterCaller{contract: contract}, MockE2EUSDCTransmitterTransactor: MockE2EUSDCTransmitterTransactor{contract: contract}, MockE2EUSDCTransmitterFilterer: MockE2EUSDCTransmitterFilterer{contract: contract}}, nil +} + +func NewMockE2EUSDCTransmitterCaller(address common.Address, caller bind.ContractCaller) (*MockE2EUSDCTransmitterCaller, error) { + contract, err := bindMockE2EUSDCTransmitter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MockE2EUSDCTransmitterCaller{contract: contract}, nil +} + +func NewMockE2EUSDCTransmitterTransactor(address common.Address, transactor bind.ContractTransactor) (*MockE2EUSDCTransmitterTransactor, error) { + contract, err := bindMockE2EUSDCTransmitter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MockE2EUSDCTransmitterTransactor{contract: contract}, nil +} + +func NewMockE2EUSDCTransmitterFilterer(address common.Address, filterer bind.ContractFilterer) (*MockE2EUSDCTransmitterFilterer, error) { + contract, err := bindMockE2EUSDCTransmitter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MockE2EUSDCTransmitterFilterer{contract: contract}, nil +} + +func bindMockE2EUSDCTransmitter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MockE2EUSDCTransmitterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockE2EUSDCTransmitter.Contract.MockE2EUSDCTransmitterCaller.contract.Call(opts, result, method, params...) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.Contract.MockE2EUSDCTransmitterTransactor.contract.Transfer(opts) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.Contract.MockE2EUSDCTransmitterTransactor.contract.Transact(opts, method, params...) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockE2EUSDCTransmitter.Contract.contract.Call(opts, result, method, params...) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.Contract.contract.Transfer(opts) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.Contract.contract.Transact(opts, method, params...) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _MockE2EUSDCTransmitter.contract.Call(opts, &out, "localDomain") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterSession) LocalDomain() (uint32, error) { + return _MockE2EUSDCTransmitter.Contract.LocalDomain(&_MockE2EUSDCTransmitter.CallOpts) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterCallerSession) LocalDomain() (uint32, error) { + return _MockE2EUSDCTransmitter.Contract.LocalDomain(&_MockE2EUSDCTransmitter.CallOpts) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterCaller) NextAvailableNonce(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _MockE2EUSDCTransmitter.contract.Call(opts, &out, "nextAvailableNonce") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterSession) NextAvailableNonce() (uint64, error) { + return _MockE2EUSDCTransmitter.Contract.NextAvailableNonce(&_MockE2EUSDCTransmitter.CallOpts) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterCallerSession) NextAvailableNonce() (uint64, error) { + return _MockE2EUSDCTransmitter.Contract.NextAvailableNonce(&_MockE2EUSDCTransmitter.CallOpts) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterCaller) SShouldSucceed(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _MockE2EUSDCTransmitter.contract.Call(opts, &out, "s_shouldSucceed") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterSession) SShouldSucceed() (bool, error) { + return _MockE2EUSDCTransmitter.Contract.SShouldSucceed(&_MockE2EUSDCTransmitter.CallOpts) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterCallerSession) SShouldSucceed() (bool, error) { + return _MockE2EUSDCTransmitter.Contract.SShouldSucceed(&_MockE2EUSDCTransmitter.CallOpts) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterCaller) Version(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _MockE2EUSDCTransmitter.contract.Call(opts, &out, "version") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterSession) Version() (uint32, error) { + return _MockE2EUSDCTransmitter.Contract.Version(&_MockE2EUSDCTransmitter.CallOpts) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterCallerSession) Version() (uint32, error) { + return _MockE2EUSDCTransmitter.Contract.Version(&_MockE2EUSDCTransmitter.CallOpts) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterTransactor) ReceiveMessage(opts *bind.TransactOpts, message []byte, arg1 []byte) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.contract.Transact(opts, "receiveMessage", message, arg1) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterSession) ReceiveMessage(message []byte, arg1 []byte) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.Contract.ReceiveMessage(&_MockE2EUSDCTransmitter.TransactOpts, message, arg1) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterTransactorSession) ReceiveMessage(message []byte, arg1 []byte) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.Contract.ReceiveMessage(&_MockE2EUSDCTransmitter.TransactOpts, message, arg1) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterTransactor) SendMessage(opts *bind.TransactOpts, destinationDomain uint32, recipient [32]byte, messageBody []byte) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.contract.Transact(opts, "sendMessage", destinationDomain, recipient, messageBody) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterSession) SendMessage(destinationDomain uint32, recipient [32]byte, messageBody []byte) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.Contract.SendMessage(&_MockE2EUSDCTransmitter.TransactOpts, destinationDomain, recipient, messageBody) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterTransactorSession) SendMessage(destinationDomain uint32, recipient [32]byte, messageBody []byte) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.Contract.SendMessage(&_MockE2EUSDCTransmitter.TransactOpts, destinationDomain, recipient, messageBody) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterTransactor) SendMessageWithCaller(opts *bind.TransactOpts, destinationDomain uint32, recipient [32]byte, destinationCaller [32]byte, messageBody []byte) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.contract.Transact(opts, "sendMessageWithCaller", destinationDomain, recipient, destinationCaller, messageBody) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterSession) SendMessageWithCaller(destinationDomain uint32, recipient [32]byte, destinationCaller [32]byte, messageBody []byte) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.Contract.SendMessageWithCaller(&_MockE2EUSDCTransmitter.TransactOpts, destinationDomain, recipient, destinationCaller, messageBody) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterTransactorSession) SendMessageWithCaller(destinationDomain uint32, recipient [32]byte, destinationCaller [32]byte, messageBody []byte) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.Contract.SendMessageWithCaller(&_MockE2EUSDCTransmitter.TransactOpts, destinationDomain, recipient, destinationCaller, messageBody) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterTransactor) SetShouldSucceed(opts *bind.TransactOpts, shouldSucceed bool) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.contract.Transact(opts, "setShouldSucceed", shouldSucceed) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterSession) SetShouldSucceed(shouldSucceed bool) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.Contract.SetShouldSucceed(&_MockE2EUSDCTransmitter.TransactOpts, shouldSucceed) +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterTransactorSession) SetShouldSucceed(shouldSucceed bool) (*types.Transaction, error) { + return _MockE2EUSDCTransmitter.Contract.SetShouldSucceed(&_MockE2EUSDCTransmitter.TransactOpts, shouldSucceed) +} + +type MockE2EUSDCTransmitterMessageSentIterator struct { + Event *MockE2EUSDCTransmitterMessageSent + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MockE2EUSDCTransmitterMessageSentIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MockE2EUSDCTransmitterMessageSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MockE2EUSDCTransmitterMessageSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MockE2EUSDCTransmitterMessageSentIterator) Error() error { + return it.fail +} + +func (it *MockE2EUSDCTransmitterMessageSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MockE2EUSDCTransmitterMessageSent struct { + Message []byte + Raw types.Log +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterFilterer) FilterMessageSent(opts *bind.FilterOpts) (*MockE2EUSDCTransmitterMessageSentIterator, error) { + + logs, sub, err := _MockE2EUSDCTransmitter.contract.FilterLogs(opts, "MessageSent") + if err != nil { + return nil, err + } + return &MockE2EUSDCTransmitterMessageSentIterator{contract: _MockE2EUSDCTransmitter.contract, event: "MessageSent", logs: logs, sub: sub}, nil +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterFilterer) WatchMessageSent(opts *bind.WatchOpts, sink chan<- *MockE2EUSDCTransmitterMessageSent) (event.Subscription, error) { + + logs, sub, err := _MockE2EUSDCTransmitter.contract.WatchLogs(opts, "MessageSent") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MockE2EUSDCTransmitterMessageSent) + if err := _MockE2EUSDCTransmitter.contract.UnpackLog(event, "MessageSent", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitterFilterer) ParseMessageSent(log types.Log) (*MockE2EUSDCTransmitterMessageSent, error) { + event := new(MockE2EUSDCTransmitterMessageSent) + if err := _MockE2EUSDCTransmitter.contract.UnpackLog(event, "MessageSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitter) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _MockE2EUSDCTransmitter.abi.Events["MessageSent"].ID: + return _MockE2EUSDCTransmitter.ParseMessageSent(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (MockE2EUSDCTransmitterMessageSent) Topic() common.Hash { + return common.HexToHash("0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036") +} + +func (_MockE2EUSDCTransmitter *MockE2EUSDCTransmitter) Address() common.Address { + return _MockE2EUSDCTransmitter.address +} + +type MockE2EUSDCTransmitterInterface interface { + LocalDomain(opts *bind.CallOpts) (uint32, error) + + NextAvailableNonce(opts *bind.CallOpts) (uint64, error) + + SShouldSucceed(opts *bind.CallOpts) (bool, error) + + Version(opts *bind.CallOpts) (uint32, error) + + ReceiveMessage(opts *bind.TransactOpts, message []byte, arg1 []byte) (*types.Transaction, error) + + SendMessage(opts *bind.TransactOpts, destinationDomain uint32, recipient [32]byte, messageBody []byte) (*types.Transaction, error) + + SendMessageWithCaller(opts *bind.TransactOpts, destinationDomain uint32, recipient [32]byte, destinationCaller [32]byte, messageBody []byte) (*types.Transaction, error) + + SetShouldSucceed(opts *bind.TransactOpts, shouldSucceed bool) (*types.Transaction, error) + + FilterMessageSent(opts *bind.FilterOpts) (*MockE2EUSDCTransmitterMessageSentIterator, error) + + WatchMessageSent(opts *bind.WatchOpts, sink chan<- *MockE2EUSDCTransmitterMessageSent) (event.Subscription, error) + + ParseMessageSent(log types.Log) (*MockE2EUSDCTransmitterMessageSent, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/mock_v3_aggregator_contract/mock_v3_aggregator_contract.go b/core/gethwrappers/ccip/generated/mock_v3_aggregator_contract/mock_v3_aggregator_contract.go new file mode 100644 index 0000000000..c3521d3515 --- /dev/null +++ b/core/gethwrappers/ccip/generated/mock_v3_aggregator_contract/mock_v3_aggregator_contract.go @@ -0,0 +1,797 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package mock_v3_aggregator_contract + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var MockV3AggregatorMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"_decimals\",\"type\":\"uint8\"},{\"internalType\":\"int256\",\"name\":\"_initialAnswer\",\"type\":\"int256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int256\",\"name\":\"current\",\"type\":\"int256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"}],\"name\":\"AnswerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"startedBy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"}],\"name\":\"NewRound\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"description\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint80\",\"name\":\"_roundId\",\"type\":\"uint80\"}],\"name\":\"getRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRound\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"_answer\",\"type\":\"int256\"}],\"name\":\"updateAnswer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint80\",\"name\":\"_roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"_answer\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startedAt\",\"type\":\"uint256\"}],\"name\":\"updateRoundData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5060405161059638038061059683398101604081905261002f916100a4565b6000805460ff191660ff84161790556100478161004e565b50506100ff565b60018190554260025560038054906000610067836100d8565b9091555050600380546000908152600460209081526040808320949094558254825260058152838220429081905592548252600690529190912055565b600080604083850312156100b757600080fd5b825160ff811681146100c857600080fd5b6020939093015192949293505050565b6000600182016100f857634e487b7160e01b600052601160045260246000fd5b5060010190565b6104888061010e6000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80638205bf6a11610081578063b5ab58dc1161005b578063b5ab58dc1461025b578063b633620c1461027b578063feaf968c1461029b57600080fd5b80638205bf6a146101c15780639a6fc8f5146101ca578063a87a20ce1461024857600080fd5b806354fd4d50116100b257806354fd4d5014610171578063668a0f02146101795780637284e4161461018257600080fd5b8063313ce567146100d95780634aa2011f146100fd57806350d25bcd1461015a575b600080fd5b6000546100e69060ff1681565b60405160ff90911681526020015b60405180910390f35b61015861010b36600461033b565b69ffffffffffffffffffff90931660038181556001849055600283905560009182526004602090815260408084209590955581548352600581528483209390935554815260069091522055565b005b61016360015481565b6040519081526020016100f4565b610163600081565b61016360035481565b604080518082018252601f81527f76302e382f74657374732f4d6f636b563341676772656761746f722e736f6c00602082015290516100f49190610374565b61016360025481565b6102116101d83660046103e1565b69ffffffffffffffffffff8116600090815260046020908152604080832054600683528184205460059093529220549293919290918490565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a0016100f4565b610158610256366004610403565b6102c6565b610163610269366004610403565b60046020526000908152604090205481565b610163610289366004610403565b60056020526000908152604090205481565b6003546000818152600460209081526040808320546006835281842054600590935292205483610211565b600181905542600255600380549060006102df8361041c565b9091555050600380546000908152600460209081526040808320949094558254825260058152838220429081905592548252600690529190912055565b803569ffffffffffffffffffff8116811461033657600080fd5b919050565b6000806000806080858703121561035157600080fd5b61035a8561031c565b966020860135965060408601359560600135945092505050565b60006020808352835180602085015260005b818110156103a257858101830151858201604001528201610386565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000602082840312156103f357600080fd5b6103fc8261031c565b9392505050565b60006020828403121561041557600080fd5b5035919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610474577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c6343000818000a", +} + +var MockV3AggregatorABI = MockV3AggregatorMetaData.ABI + +var MockV3AggregatorBin = MockV3AggregatorMetaData.Bin + +func DeployMockV3Aggregator(auth *bind.TransactOpts, backend bind.ContractBackend, _decimals uint8, _initialAnswer *big.Int) (common.Address, *types.Transaction, *MockV3Aggregator, error) { + parsed, err := MockV3AggregatorMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MockV3AggregatorBin), backend, _decimals, _initialAnswer) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MockV3Aggregator{address: address, abi: *parsed, MockV3AggregatorCaller: MockV3AggregatorCaller{contract: contract}, MockV3AggregatorTransactor: MockV3AggregatorTransactor{contract: contract}, MockV3AggregatorFilterer: MockV3AggregatorFilterer{contract: contract}}, nil +} + +type MockV3Aggregator struct { + address common.Address + abi abi.ABI + MockV3AggregatorCaller + MockV3AggregatorTransactor + MockV3AggregatorFilterer +} + +type MockV3AggregatorCaller struct { + contract *bind.BoundContract +} + +type MockV3AggregatorTransactor struct { + contract *bind.BoundContract +} + +type MockV3AggregatorFilterer struct { + contract *bind.BoundContract +} + +type MockV3AggregatorSession struct { + Contract *MockV3Aggregator + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type MockV3AggregatorCallerSession struct { + Contract *MockV3AggregatorCaller + CallOpts bind.CallOpts +} + +type MockV3AggregatorTransactorSession struct { + Contract *MockV3AggregatorTransactor + TransactOpts bind.TransactOpts +} + +type MockV3AggregatorRaw struct { + Contract *MockV3Aggregator +} + +type MockV3AggregatorCallerRaw struct { + Contract *MockV3AggregatorCaller +} + +type MockV3AggregatorTransactorRaw struct { + Contract *MockV3AggregatorTransactor +} + +func NewMockV3Aggregator(address common.Address, backend bind.ContractBackend) (*MockV3Aggregator, error) { + abi, err := abi.JSON(strings.NewReader(MockV3AggregatorABI)) + if err != nil { + return nil, err + } + contract, err := bindMockV3Aggregator(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MockV3Aggregator{address: address, abi: abi, MockV3AggregatorCaller: MockV3AggregatorCaller{contract: contract}, MockV3AggregatorTransactor: MockV3AggregatorTransactor{contract: contract}, MockV3AggregatorFilterer: MockV3AggregatorFilterer{contract: contract}}, nil +} + +func NewMockV3AggregatorCaller(address common.Address, caller bind.ContractCaller) (*MockV3AggregatorCaller, error) { + contract, err := bindMockV3Aggregator(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MockV3AggregatorCaller{contract: contract}, nil +} + +func NewMockV3AggregatorTransactor(address common.Address, transactor bind.ContractTransactor) (*MockV3AggregatorTransactor, error) { + contract, err := bindMockV3Aggregator(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MockV3AggregatorTransactor{contract: contract}, nil +} + +func NewMockV3AggregatorFilterer(address common.Address, filterer bind.ContractFilterer) (*MockV3AggregatorFilterer, error) { + contract, err := bindMockV3Aggregator(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MockV3AggregatorFilterer{contract: contract}, nil +} + +func bindMockV3Aggregator(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MockV3AggregatorMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_MockV3Aggregator *MockV3AggregatorRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockV3Aggregator.Contract.MockV3AggregatorCaller.contract.Call(opts, result, method, params...) +} + +func (_MockV3Aggregator *MockV3AggregatorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockV3Aggregator.Contract.MockV3AggregatorTransactor.contract.Transfer(opts) +} + +func (_MockV3Aggregator *MockV3AggregatorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockV3Aggregator.Contract.MockV3AggregatorTransactor.contract.Transact(opts, method, params...) +} + +func (_MockV3Aggregator *MockV3AggregatorCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockV3Aggregator.Contract.contract.Call(opts, result, method, params...) +} + +func (_MockV3Aggregator *MockV3AggregatorTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockV3Aggregator.Contract.contract.Transfer(opts) +} + +func (_MockV3Aggregator *MockV3AggregatorTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockV3Aggregator.Contract.contract.Transact(opts, method, params...) +} + +func (_MockV3Aggregator *MockV3AggregatorCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _MockV3Aggregator.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_MockV3Aggregator *MockV3AggregatorSession) Decimals() (uint8, error) { + return _MockV3Aggregator.Contract.Decimals(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCallerSession) Decimals() (uint8, error) { + return _MockV3Aggregator.Contract.Decimals(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCaller) Description(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _MockV3Aggregator.contract.Call(opts, &out, "description") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_MockV3Aggregator *MockV3AggregatorSession) Description() (string, error) { + return _MockV3Aggregator.Contract.Description(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCallerSession) Description() (string, error) { + return _MockV3Aggregator.Contract.Description(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCaller) GetAnswer(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _MockV3Aggregator.contract.Call(opts, &out, "getAnswer", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_MockV3Aggregator *MockV3AggregatorSession) GetAnswer(arg0 *big.Int) (*big.Int, error) { + return _MockV3Aggregator.Contract.GetAnswer(&_MockV3Aggregator.CallOpts, arg0) +} + +func (_MockV3Aggregator *MockV3AggregatorCallerSession) GetAnswer(arg0 *big.Int) (*big.Int, error) { + return _MockV3Aggregator.Contract.GetAnswer(&_MockV3Aggregator.CallOpts, arg0) +} + +func (_MockV3Aggregator *MockV3AggregatorCaller) GetRoundData(opts *bind.CallOpts, _roundId *big.Int) (GetRoundData, + + error) { + var out []interface{} + err := _MockV3Aggregator.contract.Call(opts, &out, "getRoundData", _roundId) + + outstruct := new(GetRoundData) + if err != nil { + return *outstruct, err + } + + outstruct.RoundId = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Answer = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.StartedAt = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.UpdatedAt = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.AnsweredInRound = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_MockV3Aggregator *MockV3AggregatorSession) GetRoundData(_roundId *big.Int) (GetRoundData, + + error) { + return _MockV3Aggregator.Contract.GetRoundData(&_MockV3Aggregator.CallOpts, _roundId) +} + +func (_MockV3Aggregator *MockV3AggregatorCallerSession) GetRoundData(_roundId *big.Int) (GetRoundData, + + error) { + return _MockV3Aggregator.Contract.GetRoundData(&_MockV3Aggregator.CallOpts, _roundId) +} + +func (_MockV3Aggregator *MockV3AggregatorCaller) GetTimestamp(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _MockV3Aggregator.contract.Call(opts, &out, "getTimestamp", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_MockV3Aggregator *MockV3AggregatorSession) GetTimestamp(arg0 *big.Int) (*big.Int, error) { + return _MockV3Aggregator.Contract.GetTimestamp(&_MockV3Aggregator.CallOpts, arg0) +} + +func (_MockV3Aggregator *MockV3AggregatorCallerSession) GetTimestamp(arg0 *big.Int) (*big.Int, error) { + return _MockV3Aggregator.Contract.GetTimestamp(&_MockV3Aggregator.CallOpts, arg0) +} + +func (_MockV3Aggregator *MockV3AggregatorCaller) LatestAnswer(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MockV3Aggregator.contract.Call(opts, &out, "latestAnswer") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_MockV3Aggregator *MockV3AggregatorSession) LatestAnswer() (*big.Int, error) { + return _MockV3Aggregator.Contract.LatestAnswer(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCallerSession) LatestAnswer() (*big.Int, error) { + return _MockV3Aggregator.Contract.LatestAnswer(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCaller) LatestRound(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MockV3Aggregator.contract.Call(opts, &out, "latestRound") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_MockV3Aggregator *MockV3AggregatorSession) LatestRound() (*big.Int, error) { + return _MockV3Aggregator.Contract.LatestRound(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCallerSession) LatestRound() (*big.Int, error) { + return _MockV3Aggregator.Contract.LatestRound(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCaller) LatestRoundData(opts *bind.CallOpts) (LatestRoundData, + + error) { + var out []interface{} + err := _MockV3Aggregator.contract.Call(opts, &out, "latestRoundData") + + outstruct := new(LatestRoundData) + if err != nil { + return *outstruct, err + } + + outstruct.RoundId = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Answer = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.StartedAt = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.UpdatedAt = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.AnsweredInRound = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_MockV3Aggregator *MockV3AggregatorSession) LatestRoundData() (LatestRoundData, + + error) { + return _MockV3Aggregator.Contract.LatestRoundData(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCallerSession) LatestRoundData() (LatestRoundData, + + error) { + return _MockV3Aggregator.Contract.LatestRoundData(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCaller) LatestTimestamp(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MockV3Aggregator.contract.Call(opts, &out, "latestTimestamp") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_MockV3Aggregator *MockV3AggregatorSession) LatestTimestamp() (*big.Int, error) { + return _MockV3Aggregator.Contract.LatestTimestamp(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCallerSession) LatestTimestamp() (*big.Int, error) { + return _MockV3Aggregator.Contract.LatestTimestamp(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCaller) Version(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MockV3Aggregator.contract.Call(opts, &out, "version") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_MockV3Aggregator *MockV3AggregatorSession) Version() (*big.Int, error) { + return _MockV3Aggregator.Contract.Version(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorCallerSession) Version() (*big.Int, error) { + return _MockV3Aggregator.Contract.Version(&_MockV3Aggregator.CallOpts) +} + +func (_MockV3Aggregator *MockV3AggregatorTransactor) UpdateAnswer(opts *bind.TransactOpts, _answer *big.Int) (*types.Transaction, error) { + return _MockV3Aggregator.contract.Transact(opts, "updateAnswer", _answer) +} + +func (_MockV3Aggregator *MockV3AggregatorSession) UpdateAnswer(_answer *big.Int) (*types.Transaction, error) { + return _MockV3Aggregator.Contract.UpdateAnswer(&_MockV3Aggregator.TransactOpts, _answer) +} + +func (_MockV3Aggregator *MockV3AggregatorTransactorSession) UpdateAnswer(_answer *big.Int) (*types.Transaction, error) { + return _MockV3Aggregator.Contract.UpdateAnswer(&_MockV3Aggregator.TransactOpts, _answer) +} + +func (_MockV3Aggregator *MockV3AggregatorTransactor) UpdateRoundData(opts *bind.TransactOpts, _roundId *big.Int, _answer *big.Int, _timestamp *big.Int, _startedAt *big.Int) (*types.Transaction, error) { + return _MockV3Aggregator.contract.Transact(opts, "updateRoundData", _roundId, _answer, _timestamp, _startedAt) +} + +func (_MockV3Aggregator *MockV3AggregatorSession) UpdateRoundData(_roundId *big.Int, _answer *big.Int, _timestamp *big.Int, _startedAt *big.Int) (*types.Transaction, error) { + return _MockV3Aggregator.Contract.UpdateRoundData(&_MockV3Aggregator.TransactOpts, _roundId, _answer, _timestamp, _startedAt) +} + +func (_MockV3Aggregator *MockV3AggregatorTransactorSession) UpdateRoundData(_roundId *big.Int, _answer *big.Int, _timestamp *big.Int, _startedAt *big.Int) (*types.Transaction, error) { + return _MockV3Aggregator.Contract.UpdateRoundData(&_MockV3Aggregator.TransactOpts, _roundId, _answer, _timestamp, _startedAt) +} + +type MockV3AggregatorAnswerUpdatedIterator struct { + Event *MockV3AggregatorAnswerUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MockV3AggregatorAnswerUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MockV3AggregatorAnswerUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MockV3AggregatorAnswerUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MockV3AggregatorAnswerUpdatedIterator) Error() error { + return it.fail +} + +func (it *MockV3AggregatorAnswerUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MockV3AggregatorAnswerUpdated struct { + Current *big.Int + RoundId *big.Int + UpdatedAt *big.Int + Raw types.Log +} + +func (_MockV3Aggregator *MockV3AggregatorFilterer) FilterAnswerUpdated(opts *bind.FilterOpts, current []*big.Int, roundId []*big.Int) (*MockV3AggregatorAnswerUpdatedIterator, error) { + + var currentRule []interface{} + for _, currentItem := range current { + currentRule = append(currentRule, currentItem) + } + var roundIdRule []interface{} + for _, roundIdItem := range roundId { + roundIdRule = append(roundIdRule, roundIdItem) + } + + logs, sub, err := _MockV3Aggregator.contract.FilterLogs(opts, "AnswerUpdated", currentRule, roundIdRule) + if err != nil { + return nil, err + } + return &MockV3AggregatorAnswerUpdatedIterator{contract: _MockV3Aggregator.contract, event: "AnswerUpdated", logs: logs, sub: sub}, nil +} + +func (_MockV3Aggregator *MockV3AggregatorFilterer) WatchAnswerUpdated(opts *bind.WatchOpts, sink chan<- *MockV3AggregatorAnswerUpdated, current []*big.Int, roundId []*big.Int) (event.Subscription, error) { + + var currentRule []interface{} + for _, currentItem := range current { + currentRule = append(currentRule, currentItem) + } + var roundIdRule []interface{} + for _, roundIdItem := range roundId { + roundIdRule = append(roundIdRule, roundIdItem) + } + + logs, sub, err := _MockV3Aggregator.contract.WatchLogs(opts, "AnswerUpdated", currentRule, roundIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MockV3AggregatorAnswerUpdated) + if err := _MockV3Aggregator.contract.UnpackLog(event, "AnswerUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MockV3Aggregator *MockV3AggregatorFilterer) ParseAnswerUpdated(log types.Log) (*MockV3AggregatorAnswerUpdated, error) { + event := new(MockV3AggregatorAnswerUpdated) + if err := _MockV3Aggregator.contract.UnpackLog(event, "AnswerUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MockV3AggregatorNewRoundIterator struct { + Event *MockV3AggregatorNewRound + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MockV3AggregatorNewRoundIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MockV3AggregatorNewRound) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MockV3AggregatorNewRound) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MockV3AggregatorNewRoundIterator) Error() error { + return it.fail +} + +func (it *MockV3AggregatorNewRoundIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MockV3AggregatorNewRound struct { + RoundId *big.Int + StartedBy common.Address + StartedAt *big.Int + Raw types.Log +} + +func (_MockV3Aggregator *MockV3AggregatorFilterer) FilterNewRound(opts *bind.FilterOpts, roundId []*big.Int, startedBy []common.Address) (*MockV3AggregatorNewRoundIterator, error) { + + var roundIdRule []interface{} + for _, roundIdItem := range roundId { + roundIdRule = append(roundIdRule, roundIdItem) + } + var startedByRule []interface{} + for _, startedByItem := range startedBy { + startedByRule = append(startedByRule, startedByItem) + } + + logs, sub, err := _MockV3Aggregator.contract.FilterLogs(opts, "NewRound", roundIdRule, startedByRule) + if err != nil { + return nil, err + } + return &MockV3AggregatorNewRoundIterator{contract: _MockV3Aggregator.contract, event: "NewRound", logs: logs, sub: sub}, nil +} + +func (_MockV3Aggregator *MockV3AggregatorFilterer) WatchNewRound(opts *bind.WatchOpts, sink chan<- *MockV3AggregatorNewRound, roundId []*big.Int, startedBy []common.Address) (event.Subscription, error) { + + var roundIdRule []interface{} + for _, roundIdItem := range roundId { + roundIdRule = append(roundIdRule, roundIdItem) + } + var startedByRule []interface{} + for _, startedByItem := range startedBy { + startedByRule = append(startedByRule, startedByItem) + } + + logs, sub, err := _MockV3Aggregator.contract.WatchLogs(opts, "NewRound", roundIdRule, startedByRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MockV3AggregatorNewRound) + if err := _MockV3Aggregator.contract.UnpackLog(event, "NewRound", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MockV3Aggregator *MockV3AggregatorFilterer) ParseNewRound(log types.Log) (*MockV3AggregatorNewRound, error) { + event := new(MockV3AggregatorNewRound) + if err := _MockV3Aggregator.contract.UnpackLog(event, "NewRound", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetRoundData struct { + RoundId *big.Int + Answer *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int +} +type LatestRoundData struct { + RoundId *big.Int + Answer *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int +} + +func (_MockV3Aggregator *MockV3Aggregator) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _MockV3Aggregator.abi.Events["AnswerUpdated"].ID: + return _MockV3Aggregator.ParseAnswerUpdated(log) + case _MockV3Aggregator.abi.Events["NewRound"].ID: + return _MockV3Aggregator.ParseNewRound(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (MockV3AggregatorAnswerUpdated) Topic() common.Hash { + return common.HexToHash("0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f") +} + +func (MockV3AggregatorNewRound) Topic() common.Hash { + return common.HexToHash("0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271") +} + +func (_MockV3Aggregator *MockV3Aggregator) Address() common.Address { + return _MockV3Aggregator.address +} + +type MockV3AggregatorInterface interface { + Decimals(opts *bind.CallOpts) (uint8, error) + + Description(opts *bind.CallOpts) (string, error) + + GetAnswer(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + GetRoundData(opts *bind.CallOpts, _roundId *big.Int) (GetRoundData, + + error) + + GetTimestamp(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + LatestAnswer(opts *bind.CallOpts) (*big.Int, error) + + LatestRound(opts *bind.CallOpts) (*big.Int, error) + + LatestRoundData(opts *bind.CallOpts) (LatestRoundData, + + error) + + LatestTimestamp(opts *bind.CallOpts) (*big.Int, error) + + Version(opts *bind.CallOpts) (*big.Int, error) + + UpdateAnswer(opts *bind.TransactOpts, _answer *big.Int) (*types.Transaction, error) + + UpdateRoundData(opts *bind.TransactOpts, _roundId *big.Int, _answer *big.Int, _timestamp *big.Int, _startedAt *big.Int) (*types.Transaction, error) + + FilterAnswerUpdated(opts *bind.FilterOpts, current []*big.Int, roundId []*big.Int) (*MockV3AggregatorAnswerUpdatedIterator, error) + + WatchAnswerUpdated(opts *bind.WatchOpts, sink chan<- *MockV3AggregatorAnswerUpdated, current []*big.Int, roundId []*big.Int) (event.Subscription, error) + + ParseAnswerUpdated(log types.Log) (*MockV3AggregatorAnswerUpdated, error) + + FilterNewRound(opts *bind.FilterOpts, roundId []*big.Int, startedBy []common.Address) (*MockV3AggregatorNewRoundIterator, error) + + WatchNewRound(opts *bind.WatchOpts, sink chan<- *MockV3AggregatorNewRound, roundId []*big.Int, startedBy []common.Address) (event.Subscription, error) + + ParseNewRound(log types.Log) (*MockV3AggregatorNewRound, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go b/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go new file mode 100644 index 0000000000..9fca2d1d36 --- /dev/null +++ b/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go @@ -0,0 +1,1836 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package multi_aggregate_rate_limiter + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type AuthorizedCallersAuthorizedCallerArgs struct { + AddedCallers []common.Address + RemovedCallers []common.Address +} + +type ClientAny2EVMMessage struct { + MessageId [32]byte + SourceChainSelector uint64 + Sender []byte + Data []byte + DestTokenAmounts []ClientEVMTokenAmount +} + +type ClientEVM2AnyMessage struct { + Receiver []byte + Data []byte + TokenAmounts []ClientEVMTokenAmount + FeeToken common.Address + ExtraArgs []byte +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type MultiAggregateRateLimiterLocalRateLimitToken struct { + RemoteChainSelector uint64 + LocalToken common.Address +} + +type MultiAggregateRateLimiterRateLimitTokenArgs struct { + LocalTokenArgs MultiAggregateRateLimiterLocalRateLimitToken + RemoteToken [32]byte +} + +type MultiAggregateRateLimiterRateLimiterConfigArgs struct { + RemoteChainSelector uint64 + IsOutboundLane bool + RateLimiterConfig RateLimiterConfig +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +var MultiAggregateRateLimiterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"PriceRegistrySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"RateLimiterConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"remoteToken\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimiterConfigArgs[]\",\"name\":\"rateLimiterUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applyRateLimiterConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"}],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"localTokens\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"remoteTokens\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onInboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onOutboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"setPriceRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken\",\"name\":\"localTokenArgs\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"remoteToken\",\"type\":\"bytes32\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimitTokenArgs[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b5060405162002e2f38038062002e2f833981016040819052620000349162000538565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000102565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001ad565b50620000fa82620002fc565b50506200066f565b336001600160a01b038216036200015c5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b81518110156200023d576000828281518110620001d657620001d662000621565b60209081029190910101519050620001f060028262000378565b1562000233576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001b5565b50815160005b8151811015620002f657600082828151811062000264576200026462000621565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002a2576040516342bcdf7f60e11b815260040160405180910390fd5b620002af60028262000398565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000243565b50505050565b6001600160a01b03811662000324576040516342bcdf7f60e11b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b60006200038f836001600160a01b038416620003af565b90505b92915050565b60006200038f836001600160a01b038416620004b3565b60008181526001830160205260408120548015620004a8576000620003d660018362000637565b8554909150600090620003ec9060019062000637565b90508181146200045857600086600001828154811062000410576200041062000621565b906000526020600020015490508087600001848154811062000436576200043662000621565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200046c576200046c62000659565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000392565b600091505062000392565b6000818152600183016020526040812054620004fc5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000392565b50600062000392565b80516001600160a01b03811681146200051d57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200054c57600080fd5b620005578362000505565b602084810151919350906001600160401b03808211156200057757600080fd5b818601915086601f8301126200058c57600080fd5b815181811115620005a157620005a162000522565b8060051b604051601f19603f83011681018181108582111715620005c957620005c962000522565b604052918252848201925083810185019189831115620005e857600080fd5b938501935b828510156200061157620006018562000505565b84529385019392850192620005ed565b8096505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039257634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b6127b0806200067f6000396000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806379ba50971161008c57806391a2749a1161006657806391a2749a14610232578063e0a0e50614610245578063f2fde38b14610258578063fe843cd01461026b57600080fd5b806379ba5097146101f95780637c8b5e9a146102015780638da5cb5b1461021457600080fd5b80632451a627116100bd5780632451a627146101b0578063508ee9de146101c5578063537e304e146101d857600080fd5b806308d450a1146100e45780630a35bcc4146100f95780630d6c107e14610171575b600080fd5b6100f76100f2366004611ef5565b61027e565b005b61010c610107366004611fd5565b61029d565b604051610168919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60405180910390f35b60055473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610168565b6101b8610362565b604051610168919061205a565b6100f76101d336600461206d565b610373565b6101eb6101e6366004612088565b610384565b6040516101689291906120a3565b6100f76104e7565b6100f761020f3660046121c4565b6105e9565b60005473ffffffffffffffffffffffffffffffffffffffff1661018b565b6100f76102403660046122f5565b610838565b6100f7610253366004612386565b610849565b6100f761026636600461206d565b6108be565b6100f76102793660046123fb565b6108cf565b610286610c0e565b61029a816020015182608001516000610c53565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526103596102d58484610d2a565b6040805160a08101825282546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff16151593830193909352600190930154808316606083015292909204166080820152610d5a565b90505b92915050565b606061036e6002610e0c565b905090565b61037b610e20565b61029a81610ea1565b67ffffffffffffffff8116600090815260046020526040812060609182916103ab90610f67565b90508067ffffffffffffffff8111156103c6576103c6611c66565b6040519080825280602002602001820160405280156103ef578160200160208202803683370190505b5092508067ffffffffffffffff81111561040b5761040b611c66565b604051908082528060200260200182016040528015610434578160200160208202803683370190505b50915060005b818110156104e05767ffffffffffffffff8516600090815260046020526040812081906104679084610f72565b915091508186848151811061047e5761047e61252f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808584815181106104cb576104cb61252f565b6020908102919091010152505060010161043a565b5050915091565b60015473ffffffffffffffffffffffffffffffffffffffff16331461056d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6105f1610e20565b60005b82518110156106cf5760008382815181106106115761061161252f565b602002602001015160200151905060008483815181106106335761063361252f565b6020908102919091018101515167ffffffffffffffff81166000908152600490925260409091209091506106679083610f90565b156106c5576040805167ffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff841660208201527f530cabd30786b7235e124a6c0db77e0b685ef22813b1fe87554247f404eb8ed6910160405180910390a15b50506001016105f4565b5060005b81518110156108335760008282815181106106f0576106f061252f565b602002602001015160000151905060008383815181106107125761071261252f565b6020026020010151602001519050600082602001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610762575081155b15610799576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825167ffffffffffffffff811660009081526004602052604090206107bf908385610fb2565b15610824576040805167ffffffffffffffff831681526020810185905273ffffffffffffffffffffffffffffffffffffffff84168183015290517ffd96f5ca8894a9584abba5645131a95480f9340bd5e0046ceff789111ff16c6d9181900360600190a15b505050508060010190506106d3565b505050565b610840610e20565b61029a81610fdd565b610851610c0e565b6108ba82610862604084018461255e565b808060200260200160405190810160405280939291908181526020016000905b828210156108ae5761089f604083028601368190038101906125c6565b81526020019060010190610882565b50505050506001610c53565b5050565b6108c6610e20565b61029a81611169565b6108d7610e20565b60005b81518110156108ba5760008282815181106108f7576108f761252f565b6020908102919091010151604081015181519192509067ffffffffffffffff8116600003610951576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015160006109628383610d2a565b8054909150700100000000000000000000000000000000900463ffffffff16600003610bb0576040805160a081018252602080870180516fffffffffffffffffffffffffffffffff908116845263ffffffff421692840192909252875115158385015251811660608301529186015190911660808201528215610ac95767ffffffffffffffff8416600090815260066020908152604091829020835160028201805493860151948601516fffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009095169490941770010000000000000000000000000000000063ffffffff9096168602177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000941515949094029390931790925560608401516080850151908316921690920217600390910155610baa565b67ffffffffffffffff84166000908152600660209081526040918290208351815492850151938501516fffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff00000000000000000000000000000000000000009094169390931770010000000000000000000000000000000063ffffffff9095168502177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000093151593909302929092178155606084015160808501519083169216909202176001909101555b50610bba565b610bba818561125e565b8267ffffffffffffffff167ff14a5415ce6988a9e870a85fff0b9d7b7dd79bbc228cb63cad610daf6f7b6b978386604051610bf69291906125e2565b60405180910390a250505050508060010190506108da565b610c1960023361140d565b610c51576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610564565b565b6000610c5f8483610d2a565b805490915074010000000000000000000000000000000000000000900460ff1615610d24576000805b8451811015610d0f57610cd3858281518110610ca657610ca661252f565b6020908102919091018101515167ffffffffffffffff89166000908152600490925260409091209061143c565b15610d0757610cfa858281518110610ced57610ced61252f565b602002602001015161145e565b610d049083612655565b91505b600101610c88565b508015610d2257610d228282600061159a565b505b50505050565b67ffffffffffffffff821660009081526006602052604081208215610d5357600201905061035c565b905061035c565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152610de882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642610dcc9190612668565b85608001516fffffffffffffffffffffffffffffffff1661191d565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60606000610e1983611945565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610564565b73ffffffffffffffffffffffffffffffffffffffff8116610eee576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b600061035c826119a1565b6000808080610f8186866119ac565b909450925050505b9250929050565b60006103598373ffffffffffffffffffffffffffffffffffffffff84166119d7565b6000610fd58473ffffffffffffffffffffffffffffffffffffffff8516846119f4565b949350505050565b602081015160005b81518110156110785760008282815181106110025761100261252f565b60200260200101519050611020816002611a1190919063ffffffff16565b1561106f5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101610fe5565b50815160005b8151811015610d2457600082828151811061109b5761109b61252f565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361110b576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611116600282611a33565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010161107e565b3373ffffffffffffffffffffffffffffffffffffffff8216036111e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610564565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b815460009061128790700100000000000000000000000000000000900463ffffffff1642612668565b9050801561132957600183015483546112cf916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661191d565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461134f916fffffffffffffffffffffffffffffffff9081169116611a55565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061140090849061267b565b60405180910390a1505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610359565b60006103598373ffffffffffffffffffffffffffffffffffffffff8416611a6b565b60055481516040517fd02641a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526000928392169063d02641a0906024016040805180830381865afa1580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f691906126b7565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660000361156c5782516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610564565b6020830151610e19907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690611a77565b825474010000000000000000000000000000000000000000900460ff1615806115c1575081155b156115cb57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061161190700100000000000000000000000000000000900463ffffffff1642612668565b905080156116d15781831115611653576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461168d9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661191d565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156117885773ffffffffffffffffffffffffffffffffffffffff8416611730576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610564565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610564565b8483101561189b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906117cc9082612668565b6117d6878a612668565b6117e09190612655565b6117ea9190612722565b905073ffffffffffffffffffffffffffffffffffffffff8616611843576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610564565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610564565b6118a58584612668565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600061193c8561192d848661275d565b6119379087612655565b611a55565b95945050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561199557602002820191906000526020600020905b815481526020019060010190808311611981575b50505050509050919050565b600061035c82611ab4565b600080806119ba8585611abe565b600081815260029690960160205260409095205494959350505050565b600081815260028301602052604081208190556103598383611aca565b60008281526002840160205260408120829055610fd58484611ad6565b60006103598373ffffffffffffffffffffffffffffffffffffffff8416611ae2565b60006103598373ffffffffffffffffffffffffffffffffffffffff8416611bd5565b6000818310611a645781610359565b5090919050565b60006103598383611c24565b6000670de0b6b3a7640000611aaa837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff861661275d565b6103599190612722565b600061035c825490565b60006103598383611c3c565b60006103598383611ae2565b60006103598383611bd5565b60008181526001830160205260408120548015611bcb576000611b06600183612668565b8554909150600090611b1a90600190612668565b9050818114611b7f576000866000018281548110611b3a57611b3a61252f565b9060005260206000200154905080876000018481548110611b5d57611b5d61252f565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611b9057611b90612774565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061035c565b600091505061035c565b6000818152600183016020526040812054611c1c5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561035c565b50600061035c565b60008181526001830160205260408120541515610359565b6000826000018281548110611c5357611c5361252f565b9060005260206000200154905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611cb857611cb8611c66565b60405290565b60405160a0810167ffffffffffffffff81118282101715611cb857611cb8611c66565b6040516060810167ffffffffffffffff81118282101715611cb857611cb8611c66565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d4b57611d4b611c66565b604052919050565b803567ffffffffffffffff81168114611d6b57600080fd5b919050565b600082601f830112611d8157600080fd5b813567ffffffffffffffff811115611d9b57611d9b611c66565b611dcc60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611d04565b818152846020838601011115611de157600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115611e1857611e18611c66565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d6b57600080fd5b600060408284031215611e5857600080fd5b611e60611c95565b9050611e6b82611e22565b81526020820135602082015292915050565b600082601f830112611e8e57600080fd5b81356020611ea3611e9e83611dfe565b611d04565b8083825260208201915060208460061b870101935086841115611ec557600080fd5b602086015b84811015611eea57611edc8882611e46565b835291830191604001611eca565b509695505050505050565b600060208284031215611f0757600080fd5b813567ffffffffffffffff80821115611f1f57600080fd5b9083019060a08286031215611f3357600080fd5b611f3b611cbe565b82358152611f4b60208401611d53565b6020820152604083013582811115611f6257600080fd5b611f6e87828601611d70565b604083015250606083013582811115611f8657600080fd5b611f9287828601611d70565b606083015250608083013582811115611faa57600080fd5b611fb687828601611e7d565b60808301525095945050505050565b80358015158114611d6b57600080fd5b60008060408385031215611fe857600080fd5b611ff183611d53565b9150611fff60208401611fc5565b90509250929050565b60008151808452602080850194506020840160005b8381101561204f57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161201d565b509495945050505050565b6020815260006103596020830184612008565b60006020828403121561207f57600080fd5b61035982611e22565b60006020828403121561209a57600080fd5b61035982611d53565b6040815260006120b66040830185612008565b82810360208481019190915284518083528582019282019060005b818110156120ed578451835293830193918301916001016120d1565b5090979650505050505050565b60006040828403121561210c57600080fd5b612114611c95565b905061211f82611d53565b815261212d60208301611e22565b602082015292915050565b600082601f83011261214957600080fd5b81356020612159611e9e83611dfe565b80838252602082019150606060206060860288010194508785111561217d57600080fd5b602087015b858110156120ed5781818a03121561219a5760008081fd5b6121a2611c95565b6121ac8a836120fa565b81526040820135868201528452928401928101612182565b60008060408084860312156121d857600080fd5b833567ffffffffffffffff808211156121f057600080fd5b818601915086601f83011261220457600080fd5b81356020612214611e9e83611dfe565b8083825260208201915060208460061b87010193508a84111561223657600080fd5b6020860195505b8386101561225e5761224f8b876120fa565b8252948601949082019061223d565b9750505050602086013592508083111561227757600080fd5b505061228585828601612138565b9150509250929050565b600082601f8301126122a057600080fd5b813560206122b0611e9e83611dfe565b8083825260208201915060208460051b8701019350868411156122d257600080fd5b602086015b84811015611eea576122e881611e22565b83529183019183016122d7565b60006020828403121561230757600080fd5b813567ffffffffffffffff8082111561231f57600080fd5b908301906040828603121561233357600080fd5b61233b611c95565b82358281111561234a57600080fd5b6123568782860161228f565b82525060208301358281111561236b57600080fd5b6123778782860161228f565b60208301525095945050505050565b6000806040838503121561239957600080fd5b6123a283611d53565b9150602083013567ffffffffffffffff8111156123be57600080fd5b830160a081860312156123d057600080fd5b809150509250929050565b80356fffffffffffffffffffffffffffffffff81168114611d6b57600080fd5b6000602080838503121561240e57600080fd5b823567ffffffffffffffff81111561242557600080fd5b8301601f8101851361243657600080fd5b8035612444611e9e82611dfe565b81815260a0918202830184019184820191908884111561246357600080fd5b938501935b8385101561252357848903818112156124815760008081fd5b612489611ce1565b61249287611d53565b815261249f888801611fc5565b8882015260406060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0850112156124d75760008081fd5b6124df611ce1565b93506124ec828a01611fc5565b84526124f9818a016123db565b8a8501525061250a608089016123db565b8382015281019190915283529384019391850191612468565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261259357600080fd5b83018035915067ffffffffffffffff8211156125ae57600080fd5b6020019150600681901b3603821315610f8957600080fd5b6000604082840312156125d857600080fd5b6103598383611e46565b821515815260808101610e1960208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561035c5761035c612626565b8181038181111561035c5761035c612626565b6060810161035c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000604082840312156126c957600080fd5b6126d1611c95565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146126fd57600080fd5b8152602083015163ffffffff8116811461271657600080fd5b60208201529392505050565b600082612758577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761035c5761035c612626565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", +} + +var MultiAggregateRateLimiterABI = MultiAggregateRateLimiterMetaData.ABI + +var MultiAggregateRateLimiterBin = MultiAggregateRateLimiterMetaData.Bin + +func DeployMultiAggregateRateLimiter(auth *bind.TransactOpts, backend bind.ContractBackend, priceRegistry common.Address, authorizedCallers []common.Address) (common.Address, *types.Transaction, *MultiAggregateRateLimiter, error) { + parsed, err := MultiAggregateRateLimiterMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MultiAggregateRateLimiterBin), backend, priceRegistry, authorizedCallers) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MultiAggregateRateLimiter{address: address, abi: *parsed, MultiAggregateRateLimiterCaller: MultiAggregateRateLimiterCaller{contract: contract}, MultiAggregateRateLimiterTransactor: MultiAggregateRateLimiterTransactor{contract: contract}, MultiAggregateRateLimiterFilterer: MultiAggregateRateLimiterFilterer{contract: contract}}, nil +} + +type MultiAggregateRateLimiter struct { + address common.Address + abi abi.ABI + MultiAggregateRateLimiterCaller + MultiAggregateRateLimiterTransactor + MultiAggregateRateLimiterFilterer +} + +type MultiAggregateRateLimiterCaller struct { + contract *bind.BoundContract +} + +type MultiAggregateRateLimiterTransactor struct { + contract *bind.BoundContract +} + +type MultiAggregateRateLimiterFilterer struct { + contract *bind.BoundContract +} + +type MultiAggregateRateLimiterSession struct { + Contract *MultiAggregateRateLimiter + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type MultiAggregateRateLimiterCallerSession struct { + Contract *MultiAggregateRateLimiterCaller + CallOpts bind.CallOpts +} + +type MultiAggregateRateLimiterTransactorSession struct { + Contract *MultiAggregateRateLimiterTransactor + TransactOpts bind.TransactOpts +} + +type MultiAggregateRateLimiterRaw struct { + Contract *MultiAggregateRateLimiter +} + +type MultiAggregateRateLimiterCallerRaw struct { + Contract *MultiAggregateRateLimiterCaller +} + +type MultiAggregateRateLimiterTransactorRaw struct { + Contract *MultiAggregateRateLimiterTransactor +} + +func NewMultiAggregateRateLimiter(address common.Address, backend bind.ContractBackend) (*MultiAggregateRateLimiter, error) { + abi, err := abi.JSON(strings.NewReader(MultiAggregateRateLimiterABI)) + if err != nil { + return nil, err + } + contract, err := bindMultiAggregateRateLimiter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiter{address: address, abi: abi, MultiAggregateRateLimiterCaller: MultiAggregateRateLimiterCaller{contract: contract}, MultiAggregateRateLimiterTransactor: MultiAggregateRateLimiterTransactor{contract: contract}, MultiAggregateRateLimiterFilterer: MultiAggregateRateLimiterFilterer{contract: contract}}, nil +} + +func NewMultiAggregateRateLimiterCaller(address common.Address, caller bind.ContractCaller) (*MultiAggregateRateLimiterCaller, error) { + contract, err := bindMultiAggregateRateLimiter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterCaller{contract: contract}, nil +} + +func NewMultiAggregateRateLimiterTransactor(address common.Address, transactor bind.ContractTransactor) (*MultiAggregateRateLimiterTransactor, error) { + contract, err := bindMultiAggregateRateLimiter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterTransactor{contract: contract}, nil +} + +func NewMultiAggregateRateLimiterFilterer(address common.Address, filterer bind.ContractFilterer) (*MultiAggregateRateLimiterFilterer, error) { + contract, err := bindMultiAggregateRateLimiter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterFilterer{contract: contract}, nil +} + +func bindMultiAggregateRateLimiter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MultiAggregateRateLimiterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MultiAggregateRateLimiter.Contract.MultiAggregateRateLimiterCaller.contract.Call(opts, result, method, params...) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.MultiAggregateRateLimiterTransactor.contract.Transfer(opts) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.MultiAggregateRateLimiterTransactor.contract.Transact(opts, method, params...) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MultiAggregateRateLimiter.Contract.contract.Call(opts, result, method, params...) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.contract.Transfer(opts) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.contract.Transact(opts, method, params...) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) CurrentRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64, isOutboundLane bool) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _MultiAggregateRateLimiter.contract.Call(opts, &out, "currentRateLimiterState", remoteChainSelector, isOutboundLane) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) CurrentRateLimiterState(remoteChainSelector uint64, isOutboundLane bool) (RateLimiterTokenBucket, error) { + return _MultiAggregateRateLimiter.Contract.CurrentRateLimiterState(&_MultiAggregateRateLimiter.CallOpts, remoteChainSelector, isOutboundLane) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerSession) CurrentRateLimiterState(remoteChainSelector uint64, isOutboundLane bool) (RateLimiterTokenBucket, error) { + return _MultiAggregateRateLimiter.Contract.CurrentRateLimiterState(&_MultiAggregateRateLimiter.CallOpts, remoteChainSelector, isOutboundLane) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _MultiAggregateRateLimiter.contract.Call(opts, &out, "getAllAuthorizedCallers") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) GetAllAuthorizedCallers() ([]common.Address, error) { + return _MultiAggregateRateLimiter.Contract.GetAllAuthorizedCallers(&_MultiAggregateRateLimiter.CallOpts) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerSession) GetAllAuthorizedCallers() ([]common.Address, error) { + return _MultiAggregateRateLimiter.Contract.GetAllAuthorizedCallers(&_MultiAggregateRateLimiter.CallOpts) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) GetAllRateLimitTokens(opts *bind.CallOpts, remoteChainSelector uint64) (GetAllRateLimitTokens, + + error) { + var out []interface{} + err := _MultiAggregateRateLimiter.contract.Call(opts, &out, "getAllRateLimitTokens", remoteChainSelector) + + outstruct := new(GetAllRateLimitTokens) + if err != nil { + return *outstruct, err + } + + outstruct.LocalTokens = *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + outstruct.RemoteTokens = *abi.ConvertType(out[1], new([][32]byte)).(*[][32]byte) + + return *outstruct, err + +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) GetAllRateLimitTokens(remoteChainSelector uint64) (GetAllRateLimitTokens, + + error) { + return _MultiAggregateRateLimiter.Contract.GetAllRateLimitTokens(&_MultiAggregateRateLimiter.CallOpts, remoteChainSelector) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerSession) GetAllRateLimitTokens(remoteChainSelector uint64) (GetAllRateLimitTokens, + + error) { + return _MultiAggregateRateLimiter.Contract.GetAllRateLimitTokens(&_MultiAggregateRateLimiter.CallOpts, remoteChainSelector) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) GetPriceRegistry(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _MultiAggregateRateLimiter.contract.Call(opts, &out, "getPriceRegistry") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) GetPriceRegistry() (common.Address, error) { + return _MultiAggregateRateLimiter.Contract.GetPriceRegistry(&_MultiAggregateRateLimiter.CallOpts) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerSession) GetPriceRegistry() (common.Address, error) { + return _MultiAggregateRateLimiter.Contract.GetPriceRegistry(&_MultiAggregateRateLimiter.CallOpts) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _MultiAggregateRateLimiter.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) Owner() (common.Address, error) { + return _MultiAggregateRateLimiter.Contract.Owner(&_MultiAggregateRateLimiter.CallOpts) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerSession) Owner() (common.Address, error) { + return _MultiAggregateRateLimiter.Contract.Owner(&_MultiAggregateRateLimiter.CallOpts) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.contract.Transact(opts, "acceptOwnership") +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) AcceptOwnership() (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.AcceptOwnership(&_MultiAggregateRateLimiter.TransactOpts) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.AcceptOwnership(&_MultiAggregateRateLimiter.TransactOpts) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.contract.Transact(opts, "applyAuthorizedCallerUpdates", authorizedCallerArgs) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.ApplyAuthorizedCallerUpdates(&_MultiAggregateRateLimiter.TransactOpts, authorizedCallerArgs) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.ApplyAuthorizedCallerUpdates(&_MultiAggregateRateLimiter.TransactOpts, authorizedCallerArgs) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) ApplyRateLimiterConfigUpdates(opts *bind.TransactOpts, rateLimiterUpdates []MultiAggregateRateLimiterRateLimiterConfigArgs) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.contract.Transact(opts, "applyRateLimiterConfigUpdates", rateLimiterUpdates) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) ApplyRateLimiterConfigUpdates(rateLimiterUpdates []MultiAggregateRateLimiterRateLimiterConfigArgs) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.ApplyRateLimiterConfigUpdates(&_MultiAggregateRateLimiter.TransactOpts, rateLimiterUpdates) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) ApplyRateLimiterConfigUpdates(rateLimiterUpdates []MultiAggregateRateLimiterRateLimiterConfigArgs) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.ApplyRateLimiterConfigUpdates(&_MultiAggregateRateLimiter.TransactOpts, rateLimiterUpdates) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) OnInboundMessage(opts *bind.TransactOpts, message ClientAny2EVMMessage) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.contract.Transact(opts, "onInboundMessage", message) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) OnInboundMessage(message ClientAny2EVMMessage) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.OnInboundMessage(&_MultiAggregateRateLimiter.TransactOpts, message) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) OnInboundMessage(message ClientAny2EVMMessage) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.OnInboundMessage(&_MultiAggregateRateLimiter.TransactOpts, message) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) OnOutboundMessage(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.contract.Transact(opts, "onOutboundMessage", destChainSelector, message) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) OnOutboundMessage(destChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.OnOutboundMessage(&_MultiAggregateRateLimiter.TransactOpts, destChainSelector, message) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) OnOutboundMessage(destChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.OnOutboundMessage(&_MultiAggregateRateLimiter.TransactOpts, destChainSelector, message) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) SetPriceRegistry(opts *bind.TransactOpts, newPriceRegistry common.Address) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.contract.Transact(opts, "setPriceRegistry", newPriceRegistry) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) SetPriceRegistry(newPriceRegistry common.Address) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.SetPriceRegistry(&_MultiAggregateRateLimiter.TransactOpts, newPriceRegistry) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) SetPriceRegistry(newPriceRegistry common.Address) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.SetPriceRegistry(&_MultiAggregateRateLimiter.TransactOpts, newPriceRegistry) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.contract.Transact(opts, "transferOwnership", to) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.TransferOwnership(&_MultiAggregateRateLimiter.TransactOpts, to) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.TransferOwnership(&_MultiAggregateRateLimiter.TransactOpts, to) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) UpdateRateLimitTokens(opts *bind.TransactOpts, removes []MultiAggregateRateLimiterLocalRateLimitToken, adds []MultiAggregateRateLimiterRateLimitTokenArgs) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.contract.Transact(opts, "updateRateLimitTokens", removes, adds) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) UpdateRateLimitTokens(removes []MultiAggregateRateLimiterLocalRateLimitToken, adds []MultiAggregateRateLimiterRateLimitTokenArgs) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.UpdateRateLimitTokens(&_MultiAggregateRateLimiter.TransactOpts, removes, adds) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) UpdateRateLimitTokens(removes []MultiAggregateRateLimiterLocalRateLimitToken, adds []MultiAggregateRateLimiterRateLimitTokenArgs) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.UpdateRateLimitTokens(&_MultiAggregateRateLimiter.TransactOpts, removes, adds) +} + +type MultiAggregateRateLimiterAuthorizedCallerAddedIterator struct { + Event *MultiAggregateRateLimiterAuthorizedCallerAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiAggregateRateLimiterAuthorizedCallerAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterAuthorizedCallerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterAuthorizedCallerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiAggregateRateLimiterAuthorizedCallerAddedIterator) Error() error { + return it.fail +} + +func (it *MultiAggregateRateLimiterAuthorizedCallerAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiAggregateRateLimiterAuthorizedCallerAdded struct { + Caller common.Address + Raw types.Log +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*MultiAggregateRateLimiterAuthorizedCallerAddedIterator, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "AuthorizedCallerAdded") + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterAuthorizedCallerAddedIterator{contract: _MultiAggregateRateLimiter.contract, event: "AuthorizedCallerAdded", logs: logs, sub: sub}, nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterAuthorizedCallerAdded) (event.Subscription, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "AuthorizedCallerAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiAggregateRateLimiterAuthorizedCallerAdded) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "AuthorizedCallerAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseAuthorizedCallerAdded(log types.Log) (*MultiAggregateRateLimiterAuthorizedCallerAdded, error) { + event := new(MultiAggregateRateLimiterAuthorizedCallerAdded) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "AuthorizedCallerAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiAggregateRateLimiterAuthorizedCallerRemovedIterator struct { + Event *MultiAggregateRateLimiterAuthorizedCallerRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiAggregateRateLimiterAuthorizedCallerRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterAuthorizedCallerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterAuthorizedCallerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiAggregateRateLimiterAuthorizedCallerRemovedIterator) Error() error { + return it.fail +} + +func (it *MultiAggregateRateLimiterAuthorizedCallerRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiAggregateRateLimiterAuthorizedCallerRemoved struct { + Caller common.Address + Raw types.Log +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*MultiAggregateRateLimiterAuthorizedCallerRemovedIterator, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "AuthorizedCallerRemoved") + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterAuthorizedCallerRemovedIterator{contract: _MultiAggregateRateLimiter.contract, event: "AuthorizedCallerRemoved", logs: logs, sub: sub}, nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterAuthorizedCallerRemoved) (event.Subscription, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "AuthorizedCallerRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiAggregateRateLimiterAuthorizedCallerRemoved) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "AuthorizedCallerRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseAuthorizedCallerRemoved(log types.Log) (*MultiAggregateRateLimiterAuthorizedCallerRemoved, error) { + event := new(MultiAggregateRateLimiterAuthorizedCallerRemoved) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "AuthorizedCallerRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiAggregateRateLimiterConfigChangedIterator struct { + Event *MultiAggregateRateLimiterConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiAggregateRateLimiterConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiAggregateRateLimiterConfigChangedIterator) Error() error { + return it.fail +} + +func (it *MultiAggregateRateLimiterConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiAggregateRateLimiterConfigChanged struct { + Config RateLimiterConfig + Raw types.Log +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*MultiAggregateRateLimiterConfigChangedIterator, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterConfigChangedIterator{contract: _MultiAggregateRateLimiter.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterConfigChanged) (event.Subscription, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiAggregateRateLimiterConfigChanged) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseConfigChanged(log types.Log) (*MultiAggregateRateLimiterConfigChanged, error) { + event := new(MultiAggregateRateLimiterConfigChanged) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiAggregateRateLimiterOwnershipTransferRequestedIterator struct { + Event *MultiAggregateRateLimiterOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiAggregateRateLimiterOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiAggregateRateLimiterOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *MultiAggregateRateLimiterOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiAggregateRateLimiterOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiAggregateRateLimiterOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterOwnershipTransferRequestedIterator{contract: _MultiAggregateRateLimiter.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiAggregateRateLimiterOwnershipTransferRequested) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseOwnershipTransferRequested(log types.Log) (*MultiAggregateRateLimiterOwnershipTransferRequested, error) { + event := new(MultiAggregateRateLimiterOwnershipTransferRequested) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiAggregateRateLimiterOwnershipTransferredIterator struct { + Event *MultiAggregateRateLimiterOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiAggregateRateLimiterOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiAggregateRateLimiterOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *MultiAggregateRateLimiterOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiAggregateRateLimiterOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiAggregateRateLimiterOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterOwnershipTransferredIterator{contract: _MultiAggregateRateLimiter.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiAggregateRateLimiterOwnershipTransferred) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseOwnershipTransferred(log types.Log) (*MultiAggregateRateLimiterOwnershipTransferred, error) { + event := new(MultiAggregateRateLimiterOwnershipTransferred) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiAggregateRateLimiterPriceRegistrySetIterator struct { + Event *MultiAggregateRateLimiterPriceRegistrySet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiAggregateRateLimiterPriceRegistrySetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterPriceRegistrySet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterPriceRegistrySet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiAggregateRateLimiterPriceRegistrySetIterator) Error() error { + return it.fail +} + +func (it *MultiAggregateRateLimiterPriceRegistrySetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiAggregateRateLimiterPriceRegistrySet struct { + NewPriceRegistry common.Address + Raw types.Log +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterPriceRegistrySet(opts *bind.FilterOpts) (*MultiAggregateRateLimiterPriceRegistrySetIterator, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "PriceRegistrySet") + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterPriceRegistrySetIterator{contract: _MultiAggregateRateLimiter.contract, event: "PriceRegistrySet", logs: logs, sub: sub}, nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchPriceRegistrySet(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterPriceRegistrySet) (event.Subscription, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "PriceRegistrySet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiAggregateRateLimiterPriceRegistrySet) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "PriceRegistrySet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParsePriceRegistrySet(log types.Log) (*MultiAggregateRateLimiterPriceRegistrySet, error) { + event := new(MultiAggregateRateLimiterPriceRegistrySet) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "PriceRegistrySet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiAggregateRateLimiterRateLimiterConfigUpdatedIterator struct { + Event *MultiAggregateRateLimiterRateLimiterConfigUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiAggregateRateLimiterRateLimiterConfigUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterRateLimiterConfigUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterRateLimiterConfigUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiAggregateRateLimiterRateLimiterConfigUpdatedIterator) Error() error { + return it.fail +} + +func (it *MultiAggregateRateLimiterRateLimiterConfigUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiAggregateRateLimiterRateLimiterConfigUpdated struct { + RemoteChainSelector uint64 + IsOutboundLane bool + Config RateLimiterConfig + Raw types.Log +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterRateLimiterConfigUpdated(opts *bind.FilterOpts, remoteChainSelector []uint64) (*MultiAggregateRateLimiterRateLimiterConfigUpdatedIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "RateLimiterConfigUpdated", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterRateLimiterConfigUpdatedIterator{contract: _MultiAggregateRateLimiter.contract, event: "RateLimiterConfigUpdated", logs: logs, sub: sub}, nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchRateLimiterConfigUpdated(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterRateLimiterConfigUpdated, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "RateLimiterConfigUpdated", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiAggregateRateLimiterRateLimiterConfigUpdated) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "RateLimiterConfigUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseRateLimiterConfigUpdated(log types.Log) (*MultiAggregateRateLimiterRateLimiterConfigUpdated, error) { + event := new(MultiAggregateRateLimiterRateLimiterConfigUpdated) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "RateLimiterConfigUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiAggregateRateLimiterTokenAggregateRateLimitAddedIterator struct { + Event *MultiAggregateRateLimiterTokenAggregateRateLimitAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiAggregateRateLimiterTokenAggregateRateLimitAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterTokenAggregateRateLimitAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterTokenAggregateRateLimitAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiAggregateRateLimiterTokenAggregateRateLimitAddedIterator) Error() error { + return it.fail +} + +func (it *MultiAggregateRateLimiterTokenAggregateRateLimitAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiAggregateRateLimiterTokenAggregateRateLimitAdded struct { + RemoteChainSelector uint64 + RemoteToken [32]byte + LocalToken common.Address + Raw types.Log +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterTokenAggregateRateLimitAdded(opts *bind.FilterOpts) (*MultiAggregateRateLimiterTokenAggregateRateLimitAddedIterator, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "TokenAggregateRateLimitAdded") + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterTokenAggregateRateLimitAddedIterator{contract: _MultiAggregateRateLimiter.contract, event: "TokenAggregateRateLimitAdded", logs: logs, sub: sub}, nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchTokenAggregateRateLimitAdded(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterTokenAggregateRateLimitAdded) (event.Subscription, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "TokenAggregateRateLimitAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiAggregateRateLimiterTokenAggregateRateLimitAdded) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "TokenAggregateRateLimitAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseTokenAggregateRateLimitAdded(log types.Log) (*MultiAggregateRateLimiterTokenAggregateRateLimitAdded, error) { + event := new(MultiAggregateRateLimiterTokenAggregateRateLimitAdded) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "TokenAggregateRateLimitAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiAggregateRateLimiterTokenAggregateRateLimitRemovedIterator struct { + Event *MultiAggregateRateLimiterTokenAggregateRateLimitRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiAggregateRateLimiterTokenAggregateRateLimitRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterTokenAggregateRateLimitRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterTokenAggregateRateLimitRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiAggregateRateLimiterTokenAggregateRateLimitRemovedIterator) Error() error { + return it.fail +} + +func (it *MultiAggregateRateLimiterTokenAggregateRateLimitRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiAggregateRateLimiterTokenAggregateRateLimitRemoved struct { + RemoteChainSelector uint64 + LocalToken common.Address + Raw types.Log +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterTokenAggregateRateLimitRemoved(opts *bind.FilterOpts) (*MultiAggregateRateLimiterTokenAggregateRateLimitRemovedIterator, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "TokenAggregateRateLimitRemoved") + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterTokenAggregateRateLimitRemovedIterator{contract: _MultiAggregateRateLimiter.contract, event: "TokenAggregateRateLimitRemoved", logs: logs, sub: sub}, nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchTokenAggregateRateLimitRemoved(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterTokenAggregateRateLimitRemoved) (event.Subscription, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "TokenAggregateRateLimitRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiAggregateRateLimiterTokenAggregateRateLimitRemoved) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "TokenAggregateRateLimitRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseTokenAggregateRateLimitRemoved(log types.Log) (*MultiAggregateRateLimiterTokenAggregateRateLimitRemoved, error) { + event := new(MultiAggregateRateLimiterTokenAggregateRateLimitRemoved) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "TokenAggregateRateLimitRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiAggregateRateLimiterTokensConsumedIterator struct { + Event *MultiAggregateRateLimiterTokensConsumed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiAggregateRateLimiterTokensConsumedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiAggregateRateLimiterTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiAggregateRateLimiterTokensConsumedIterator) Error() error { + return it.fail +} + +func (it *MultiAggregateRateLimiterTokensConsumedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiAggregateRateLimiterTokensConsumed struct { + Tokens *big.Int + Raw types.Log +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterTokensConsumed(opts *bind.FilterOpts) (*MultiAggregateRateLimiterTokensConsumedIterator, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return &MultiAggregateRateLimiterTokensConsumedIterator{contract: _MultiAggregateRateLimiter.contract, event: "TokensConsumed", logs: logs, sub: sub}, nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterTokensConsumed) (event.Subscription, error) { + + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiAggregateRateLimiterTokensConsumed) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseTokensConsumed(log types.Log) (*MultiAggregateRateLimiterTokensConsumed, error) { + event := new(MultiAggregateRateLimiterTokensConsumed) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetAllRateLimitTokens struct { + LocalTokens []common.Address + RemoteTokens [][32]byte +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiter) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _MultiAggregateRateLimiter.abi.Events["AuthorizedCallerAdded"].ID: + return _MultiAggregateRateLimiter.ParseAuthorizedCallerAdded(log) + case _MultiAggregateRateLimiter.abi.Events["AuthorizedCallerRemoved"].ID: + return _MultiAggregateRateLimiter.ParseAuthorizedCallerRemoved(log) + case _MultiAggregateRateLimiter.abi.Events["ConfigChanged"].ID: + return _MultiAggregateRateLimiter.ParseConfigChanged(log) + case _MultiAggregateRateLimiter.abi.Events["OwnershipTransferRequested"].ID: + return _MultiAggregateRateLimiter.ParseOwnershipTransferRequested(log) + case _MultiAggregateRateLimiter.abi.Events["OwnershipTransferred"].ID: + return _MultiAggregateRateLimiter.ParseOwnershipTransferred(log) + case _MultiAggregateRateLimiter.abi.Events["PriceRegistrySet"].ID: + return _MultiAggregateRateLimiter.ParsePriceRegistrySet(log) + case _MultiAggregateRateLimiter.abi.Events["RateLimiterConfigUpdated"].ID: + return _MultiAggregateRateLimiter.ParseRateLimiterConfigUpdated(log) + case _MultiAggregateRateLimiter.abi.Events["TokenAggregateRateLimitAdded"].ID: + return _MultiAggregateRateLimiter.ParseTokenAggregateRateLimitAdded(log) + case _MultiAggregateRateLimiter.abi.Events["TokenAggregateRateLimitRemoved"].ID: + return _MultiAggregateRateLimiter.ParseTokenAggregateRateLimitRemoved(log) + case _MultiAggregateRateLimiter.abi.Events["TokensConsumed"].ID: + return _MultiAggregateRateLimiter.ParseTokensConsumed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (MultiAggregateRateLimiterAuthorizedCallerAdded) Topic() common.Hash { + return common.HexToHash("0xeb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef") +} + +func (MultiAggregateRateLimiterAuthorizedCallerRemoved) Topic() common.Hash { + return common.HexToHash("0xc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda77580") +} + +func (MultiAggregateRateLimiterConfigChanged) Topic() common.Hash { + return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") +} + +func (MultiAggregateRateLimiterOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (MultiAggregateRateLimiterOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (MultiAggregateRateLimiterPriceRegistrySet) Topic() common.Hash { + return common.HexToHash("0xdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df9") +} + +func (MultiAggregateRateLimiterRateLimiterConfigUpdated) Topic() common.Hash { + return common.HexToHash("0xf14a5415ce6988a9e870a85fff0b9d7b7dd79bbc228cb63cad610daf6f7b6b97") +} + +func (MultiAggregateRateLimiterTokenAggregateRateLimitAdded) Topic() common.Hash { + return common.HexToHash("0xfd96f5ca8894a9584abba5645131a95480f9340bd5e0046ceff789111ff16c6d") +} + +func (MultiAggregateRateLimiterTokenAggregateRateLimitRemoved) Topic() common.Hash { + return common.HexToHash("0x530cabd30786b7235e124a6c0db77e0b685ef22813b1fe87554247f404eb8ed6") +} + +func (MultiAggregateRateLimiterTokensConsumed) Topic() common.Hash { + return common.HexToHash("0x1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a") +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiter) Address() common.Address { + return _MultiAggregateRateLimiter.address +} + +type MultiAggregateRateLimiterInterface interface { + CurrentRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64, isOutboundLane bool) (RateLimiterTokenBucket, error) + + GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) + + GetAllRateLimitTokens(opts *bind.CallOpts, remoteChainSelector uint64) (GetAllRateLimitTokens, + + error) + + GetPriceRegistry(opts *bind.CallOpts) (common.Address, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) + + ApplyRateLimiterConfigUpdates(opts *bind.TransactOpts, rateLimiterUpdates []MultiAggregateRateLimiterRateLimiterConfigArgs) (*types.Transaction, error) + + OnInboundMessage(opts *bind.TransactOpts, message ClientAny2EVMMessage) (*types.Transaction, error) + + OnOutboundMessage(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) + + SetPriceRegistry(opts *bind.TransactOpts, newPriceRegistry common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdateRateLimitTokens(opts *bind.TransactOpts, removes []MultiAggregateRateLimiterLocalRateLimitToken, adds []MultiAggregateRateLimiterRateLimitTokenArgs) (*types.Transaction, error) + + FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*MultiAggregateRateLimiterAuthorizedCallerAddedIterator, error) + + WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterAuthorizedCallerAdded) (event.Subscription, error) + + ParseAuthorizedCallerAdded(log types.Log) (*MultiAggregateRateLimiterAuthorizedCallerAdded, error) + + FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*MultiAggregateRateLimiterAuthorizedCallerRemovedIterator, error) + + WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterAuthorizedCallerRemoved) (event.Subscription, error) + + ParseAuthorizedCallerRemoved(log types.Log) (*MultiAggregateRateLimiterAuthorizedCallerRemoved, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*MultiAggregateRateLimiterConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*MultiAggregateRateLimiterConfigChanged, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiAggregateRateLimiterOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*MultiAggregateRateLimiterOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiAggregateRateLimiterOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*MultiAggregateRateLimiterOwnershipTransferred, error) + + FilterPriceRegistrySet(opts *bind.FilterOpts) (*MultiAggregateRateLimiterPriceRegistrySetIterator, error) + + WatchPriceRegistrySet(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterPriceRegistrySet) (event.Subscription, error) + + ParsePriceRegistrySet(log types.Log) (*MultiAggregateRateLimiterPriceRegistrySet, error) + + FilterRateLimiterConfigUpdated(opts *bind.FilterOpts, remoteChainSelector []uint64) (*MultiAggregateRateLimiterRateLimiterConfigUpdatedIterator, error) + + WatchRateLimiterConfigUpdated(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterRateLimiterConfigUpdated, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRateLimiterConfigUpdated(log types.Log) (*MultiAggregateRateLimiterRateLimiterConfigUpdated, error) + + FilterTokenAggregateRateLimitAdded(opts *bind.FilterOpts) (*MultiAggregateRateLimiterTokenAggregateRateLimitAddedIterator, error) + + WatchTokenAggregateRateLimitAdded(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterTokenAggregateRateLimitAdded) (event.Subscription, error) + + ParseTokenAggregateRateLimitAdded(log types.Log) (*MultiAggregateRateLimiterTokenAggregateRateLimitAdded, error) + + FilterTokenAggregateRateLimitRemoved(opts *bind.FilterOpts) (*MultiAggregateRateLimiterTokenAggregateRateLimitRemovedIterator, error) + + WatchTokenAggregateRateLimitRemoved(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterTokenAggregateRateLimitRemoved) (event.Subscription, error) + + ParseTokenAggregateRateLimitRemoved(log types.Log) (*MultiAggregateRateLimiterTokenAggregateRateLimitRemoved, error) + + FilterTokensConsumed(opts *bind.FilterOpts) (*MultiAggregateRateLimiterTokensConsumedIterator, error) + + WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterTokensConsumed) (event.Subscription, error) + + ParseTokensConsumed(log types.Log) (*MultiAggregateRateLimiterTokensConsumed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/multi_ocr3_helper/multi_ocr3_helper.go b/core/gethwrappers/ccip/generated/multi_ocr3_helper/multi_ocr3_helper.go new file mode 100644 index 0000000000..d51e398b43 --- /dev/null +++ b/core/gethwrappers/ccip/generated/multi_ocr3_helper/multi_ocr3_helper.go @@ -0,0 +1,1096 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package multi_ocr3_helper + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type MultiOCR3BaseConfigInfo struct { + ConfigDigest [32]byte + F uint8 + N uint8 + IsSignatureVerificationEnabled bool +} + +type MultiOCR3BaseOCRConfig struct { + ConfigInfo MultiOCR3BaseConfigInfo + Signers []common.Address + Transmitters []common.Address +} + +type MultiOCR3BaseOCRConfigArgs struct { + ConfigDigest [32]byte + OcrPluginType uint8 + F uint8 + IsSignatureVerificationEnabled bool + Signers []common.Address + Transmitters []common.Address +} + +type MultiOCR3BaseOracle struct { + Index uint8 + Role uint8 +} + +var MultiOCR3HelperMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"AfterConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"oracleAddress\",\"type\":\"address\"}],\"name\":\"getOracle\",\"outputs\":[{\"components\":[{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"enumMultiOCR3Base.Role\",\"name\":\"role\",\"type\":\"uint8\"}],\"internalType\":\"structMultiOCR3Base.Oracle\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"setTransmitOcrPluginType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmitWithSignatures\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"transmitWithoutSignatures\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000a9565b5050466080525062000154565b336001600160a01b03821603620001035760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b608051611db66200017760003960008181610efc0152610f480152611db66000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80637ac0aa1a11610076578063c673e5841161005b578063c673e584146101c5578063f2fde38b146101e5578063f716f99f146101f857600080fd5b80637ac0aa1a1461015b5780638da5cb5b1461019d57600080fd5b806334a9c92e116100a757806334a9c92e1461012057806344e65e551461014057806379ba50971461015357600080fd5b8063181f5a77146100c357806326bf9d261461010b575b600080fd5b604080518082018252601981527f4d756c74694f4352334261736548656c70657220312e302e300000000000000060208201529051610102919061153c565b60405180910390f35b61011e610119366004611603565b61020b565b005b61013361012e366004611691565b61023a565b60405161010291906116f3565b61011e61014e366004611766565b6102ca565b61011e61034d565b61011e610169366004611819565b600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610102565b6101d86101d3366004611819565b61044f565b604051610102919061188d565b61011e6101f3366004611920565b6105c7565b61011e610206366004611a8c565b6105db565b604080516000808252602082019092526004549091506102349060ff168585858580600061061d565b50505050565b6040805180820182526000808252602080830182905260ff86811683526003825284832073ffffffffffffffffffffffffffffffffffffffff871684528252918490208451808601909552805480841686529394939092918401916101009091041660028111156102ad576102ad6116c4565b60028111156102be576102be6116c4565b90525090505b92915050565b60045460408051602080880282810182019093528782526103439360ff16928c928c928c928c918c91829185019084908082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b9182918501908490808284376000920191909152508a925061061d915050565b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104926040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c08201529485529182018054845181840281018401909552808552929385830193909283018282801561054857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161051d575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156105b757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161058c575b5050505050815250509050919050565b6105cf6109a1565b6105d881610a24565b50565b6105e36109a1565b60005b81518110156106195761061182828151811061060457610604611bf5565b6020026020010151610b19565b6001016105e6565b5050565b60ff8781166000908152600260209081526040808320815160808101835281548152600190910154808616938201939093526101008304851691810191909152620100009091049092161515606083015287359061067c8760a4611c53565b90508260600151156106c4578451610695906020611c66565b86516106a2906020611c66565b6106ad9060a0611c53565b6106b79190611c53565b6106c19082611c53565b90505b368114610706576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016103ca565b508151811461074e5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016103ca565b610756610ef9565b60ff808a16600090815260036020908152604080832033845282528083208151808301909252805480861683529394919390928401916101009091041660028111156107a4576107a46116c4565b60028111156107b5576107b56116c4565b90525090506002816020015160028111156107d2576107d26116c4565b1480156108335750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff168154811061080e5761080e611bf5565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b610869576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5081606001511561094b576020820151610884906001611c7d565b60ff168551146108c0576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83518551146108fb576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000878760405161090d929190611c96565b604051908190038120610924918b90602001611ca6565b6040516020818303038152906040528051906020012090506109498a82888888610f7a565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103ca565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103ca565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff16600003610b5d5760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611cba565b60208082015160ff80821660009081526002909352604083206001810154929390928392169003610bca57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055610c1f565b6060840151600182015460ff6201000090910416151590151514610c1f576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016103ca565b60a08401518051601f60ff82161115610c675760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611cba565b610cda8585600301805480602002602001604051908101604052809291908181526020018280548015610cd057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ca5575b50505050506111b2565b856060015115610e4857610d558585600201805480602002602001604051908101604052809291908181526020018280548015610cd05760200282019190600052602060002090815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ca55750505050506111b2565b60808601518051610d6f906002870190602084019061147e565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f1015610de85760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611cba565b6040880151610df8906003611cd4565b60ff168160ff1611610e395760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611cba565b610e458783600161124a565b50505b610e548583600261124a565b8151610e69906003860190602085019061147e565b506040868101516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f54793610ee0938a939260028b01929190611cf7565b60405180910390a1610ef185611445565b505050505050565b467f000000000000000000000000000000000000000000000000000000000000000014610a22576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016103ca565b610f82611508565b835160005b81811015610343576000600188868460208110610fa657610fa6611bf5565b610fb391901a601b611c7d565b898581518110610fc557610fc5611bf5565b6020026020010151898681518110610fdf57610fdf611bf5565b60200260200101516040516000815260200160405260405161101d949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561103f573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015160ff808e1660009081526003602090815285822073ffffffffffffffffffffffffffffffffffffffff8516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156110cb576110cb6116c4565b60028111156110dc576110dc6116c4565b90525090506001816020015160028111156110f9576110f96116c4565b14611130576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061114757611147611bf5565b602002015115611183576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061119e5761119e611bf5565b911515602090920201525050600101610f87565b60005b81518110156112455760ff8316600090815260036020526040812083519091908490849081106111e7576111e7611bf5565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556001016111b5565b505050565b60005b82518160ff161015610234576000838260ff168151811061127057611270611bf5565b602002602001015190506000600281111561128d5761128d6116c4565b60ff808716600090815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915290205461010090041660028111156112d9576112d96116c4565b146113135760046040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611cba565b73ffffffffffffffffffffffffffffffffffffffff8116611360576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff168152602001846002811115611386576113866116c4565b905260ff808716600090815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282529091208351815493167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00841681178255918401519092909183917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561142b5761142b6116c4565b0217905550905050508061143e90611d8a565b905061124d565b60405160ff821681527f897ac1b2c12867721b284f3eb147bd4ab046d4eef1cf31c1d8988bfcfb962b539060200160405180910390a150565b8280548282559060005260206000209081019282156114f8579160200282015b828111156114f857825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061149e565b50611504929150611527565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b808211156115045760008155600101611528565b60006020808352835180602085015260005b8181101561156a5785810183015185820160400152820161154e565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b80606081018310156102c457600080fd5b60008083601f8401126115cc57600080fd5b50813567ffffffffffffffff8111156115e457600080fd5b6020830191508360208285010111156115fc57600080fd5b9250929050565b60008060006080848603121561161857600080fd5b61162285856115a9565b9250606084013567ffffffffffffffff81111561163e57600080fd5b61164a868287016115ba565b9497909650939450505050565b803560ff8116811461166857600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461166857600080fd5b600080604083850312156116a457600080fd5b6116ad83611657565b91506116bb6020840161166d565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b815160ff1681526020820151604082019060038110611714576117146116c4565b8060208401525092915050565b60008083601f84011261173357600080fd5b50813567ffffffffffffffff81111561174b57600080fd5b6020830191508360208260051b85010111156115fc57600080fd5b60008060008060008060008060e0898b03121561178257600080fd5b61178c8a8a6115a9565b9750606089013567ffffffffffffffff808211156117a957600080fd5b6117b58c838d016115ba565b909950975060808b01359150808211156117ce57600080fd5b6117da8c838d01611721565b909750955060a08b01359150808211156117f357600080fd5b506118008b828c01611721565b999c989b50969995989497949560c00135949350505050565b60006020828403121561182b57600080fd5b61183482611657565b9392505050565b60008151808452602080850194506020840160005b8381101561188257815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101611850565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a08401526118dc60e084018261183b565b905060408401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160c0850152611917828261183b565b95945050505050565b60006020828403121561193257600080fd5b6118348261166d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff8111828210171561198d5761198d61193b565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156119da576119da61193b565b604052919050565b600067ffffffffffffffff8211156119fc576119fc61193b565b5060051b60200190565b8035801515811461166857600080fd5b600082601f830112611a2757600080fd5b81356020611a3c611a37836119e2565b611993565b8083825260208201915060208460051b870101935086841115611a5e57600080fd5b602086015b84811015611a8157611a748161166d565b8352918301918301611a63565b509695505050505050565b60006020808385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b8135611ad9611a37826119e2565b81815260059190911b83018401908481019088831115611af857600080fd5b8585015b83811015611be857803585811115611b1357600080fd5b860160c0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215611b485760008081fd5b611b5061196a565b8882013581526040611b63818401611657565b8a8301526060611b74818501611657565b8284015260809150611b87828501611a06565b9083015260a08381013589811115611b9f5760008081fd5b611bad8f8d83880101611a16565b838501525060c0840135915088821115611bc75760008081fd5b611bd58e8c84870101611a16565b9083015250845250918601918601611afc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156102c4576102c4611c24565b80820281158282048414176102c4576102c4611c24565b60ff81811683821601908111156102c4576102c4611c24565b8183823760009101908152919050565b828152606082602083013760800192915050565b6020810160058310611cce57611cce6116c4565b91905290565b60ff8181168382160290811690818114611cf057611cf0611c24565b5092915050565b600060a0820160ff88168352602087602085015260a0604085015281875480845260c086019150886000526020600020935060005b81811015611d5e57845473ffffffffffffffffffffffffffffffffffffffff1683526001948501949284019201611d2c565b50508481036060860152611d72818861183b565b935050505060ff831660808301529695505050505050565b600060ff821660ff8103611da057611da0611c24565b6001019291505056fea164736f6c6343000818000a", +} + +var MultiOCR3HelperABI = MultiOCR3HelperMetaData.ABI + +var MultiOCR3HelperBin = MultiOCR3HelperMetaData.Bin + +func DeployMultiOCR3Helper(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MultiOCR3Helper, error) { + parsed, err := MultiOCR3HelperMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MultiOCR3HelperBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MultiOCR3Helper{address: address, abi: *parsed, MultiOCR3HelperCaller: MultiOCR3HelperCaller{contract: contract}, MultiOCR3HelperTransactor: MultiOCR3HelperTransactor{contract: contract}, MultiOCR3HelperFilterer: MultiOCR3HelperFilterer{contract: contract}}, nil +} + +type MultiOCR3Helper struct { + address common.Address + abi abi.ABI + MultiOCR3HelperCaller + MultiOCR3HelperTransactor + MultiOCR3HelperFilterer +} + +type MultiOCR3HelperCaller struct { + contract *bind.BoundContract +} + +type MultiOCR3HelperTransactor struct { + contract *bind.BoundContract +} + +type MultiOCR3HelperFilterer struct { + contract *bind.BoundContract +} + +type MultiOCR3HelperSession struct { + Contract *MultiOCR3Helper + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type MultiOCR3HelperCallerSession struct { + Contract *MultiOCR3HelperCaller + CallOpts bind.CallOpts +} + +type MultiOCR3HelperTransactorSession struct { + Contract *MultiOCR3HelperTransactor + TransactOpts bind.TransactOpts +} + +type MultiOCR3HelperRaw struct { + Contract *MultiOCR3Helper +} + +type MultiOCR3HelperCallerRaw struct { + Contract *MultiOCR3HelperCaller +} + +type MultiOCR3HelperTransactorRaw struct { + Contract *MultiOCR3HelperTransactor +} + +func NewMultiOCR3Helper(address common.Address, backend bind.ContractBackend) (*MultiOCR3Helper, error) { + abi, err := abi.JSON(strings.NewReader(MultiOCR3HelperABI)) + if err != nil { + return nil, err + } + contract, err := bindMultiOCR3Helper(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MultiOCR3Helper{address: address, abi: abi, MultiOCR3HelperCaller: MultiOCR3HelperCaller{contract: contract}, MultiOCR3HelperTransactor: MultiOCR3HelperTransactor{contract: contract}, MultiOCR3HelperFilterer: MultiOCR3HelperFilterer{contract: contract}}, nil +} + +func NewMultiOCR3HelperCaller(address common.Address, caller bind.ContractCaller) (*MultiOCR3HelperCaller, error) { + contract, err := bindMultiOCR3Helper(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MultiOCR3HelperCaller{contract: contract}, nil +} + +func NewMultiOCR3HelperTransactor(address common.Address, transactor bind.ContractTransactor) (*MultiOCR3HelperTransactor, error) { + contract, err := bindMultiOCR3Helper(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MultiOCR3HelperTransactor{contract: contract}, nil +} + +func NewMultiOCR3HelperFilterer(address common.Address, filterer bind.ContractFilterer) (*MultiOCR3HelperFilterer, error) { + contract, err := bindMultiOCR3Helper(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MultiOCR3HelperFilterer{contract: contract}, nil +} + +func bindMultiOCR3Helper(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MultiOCR3HelperMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_MultiOCR3Helper *MultiOCR3HelperRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MultiOCR3Helper.Contract.MultiOCR3HelperCaller.contract.Call(opts, result, method, params...) +} + +func (_MultiOCR3Helper *MultiOCR3HelperRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.MultiOCR3HelperTransactor.contract.Transfer(opts) +} + +func (_MultiOCR3Helper *MultiOCR3HelperRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.MultiOCR3HelperTransactor.contract.Transact(opts, method, params...) +} + +func (_MultiOCR3Helper *MultiOCR3HelperCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MultiOCR3Helper.Contract.contract.Call(opts, result, method, params...) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.contract.Transfer(opts) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.contract.Transact(opts, method, params...) +} + +func (_MultiOCR3Helper *MultiOCR3HelperCaller) GetOracle(opts *bind.CallOpts, ocrPluginType uint8, oracleAddress common.Address) (MultiOCR3BaseOracle, error) { + var out []interface{} + err := _MultiOCR3Helper.contract.Call(opts, &out, "getOracle", ocrPluginType, oracleAddress) + + if err != nil { + return *new(MultiOCR3BaseOracle), err + } + + out0 := *abi.ConvertType(out[0], new(MultiOCR3BaseOracle)).(*MultiOCR3BaseOracle) + + return out0, err + +} + +func (_MultiOCR3Helper *MultiOCR3HelperSession) GetOracle(ocrPluginType uint8, oracleAddress common.Address) (MultiOCR3BaseOracle, error) { + return _MultiOCR3Helper.Contract.GetOracle(&_MultiOCR3Helper.CallOpts, ocrPluginType, oracleAddress) +} + +func (_MultiOCR3Helper *MultiOCR3HelperCallerSession) GetOracle(ocrPluginType uint8, oracleAddress common.Address) (MultiOCR3BaseOracle, error) { + return _MultiOCR3Helper.Contract.GetOracle(&_MultiOCR3Helper.CallOpts, ocrPluginType, oracleAddress) +} + +func (_MultiOCR3Helper *MultiOCR3HelperCaller) LatestConfigDetails(opts *bind.CallOpts, ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { + var out []interface{} + err := _MultiOCR3Helper.contract.Call(opts, &out, "latestConfigDetails", ocrPluginType) + + if err != nil { + return *new(MultiOCR3BaseOCRConfig), err + } + + out0 := *abi.ConvertType(out[0], new(MultiOCR3BaseOCRConfig)).(*MultiOCR3BaseOCRConfig) + + return out0, err + +} + +func (_MultiOCR3Helper *MultiOCR3HelperSession) LatestConfigDetails(ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { + return _MultiOCR3Helper.Contract.LatestConfigDetails(&_MultiOCR3Helper.CallOpts, ocrPluginType) +} + +func (_MultiOCR3Helper *MultiOCR3HelperCallerSession) LatestConfigDetails(ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { + return _MultiOCR3Helper.Contract.LatestConfigDetails(&_MultiOCR3Helper.CallOpts, ocrPluginType) +} + +func (_MultiOCR3Helper *MultiOCR3HelperCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _MultiOCR3Helper.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_MultiOCR3Helper *MultiOCR3HelperSession) Owner() (common.Address, error) { + return _MultiOCR3Helper.Contract.Owner(&_MultiOCR3Helper.CallOpts) +} + +func (_MultiOCR3Helper *MultiOCR3HelperCallerSession) Owner() (common.Address, error) { + return _MultiOCR3Helper.Contract.Owner(&_MultiOCR3Helper.CallOpts) +} + +func (_MultiOCR3Helper *MultiOCR3HelperCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _MultiOCR3Helper.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_MultiOCR3Helper *MultiOCR3HelperSession) TypeAndVersion() (string, error) { + return _MultiOCR3Helper.Contract.TypeAndVersion(&_MultiOCR3Helper.CallOpts) +} + +func (_MultiOCR3Helper *MultiOCR3HelperCallerSession) TypeAndVersion() (string, error) { + return _MultiOCR3Helper.Contract.TypeAndVersion(&_MultiOCR3Helper.CallOpts) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MultiOCR3Helper.contract.Transact(opts, "acceptOwnership") +} + +func (_MultiOCR3Helper *MultiOCR3HelperSession) AcceptOwnership() (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.AcceptOwnership(&_MultiOCR3Helper.TransactOpts) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.AcceptOwnership(&_MultiOCR3Helper.TransactOpts) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactor) SetOCR3Configs(opts *bind.TransactOpts, ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { + return _MultiOCR3Helper.contract.Transact(opts, "setOCR3Configs", ocrConfigArgs) +} + +func (_MultiOCR3Helper *MultiOCR3HelperSession) SetOCR3Configs(ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.SetOCR3Configs(&_MultiOCR3Helper.TransactOpts, ocrConfigArgs) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactorSession) SetOCR3Configs(ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.SetOCR3Configs(&_MultiOCR3Helper.TransactOpts, ocrConfigArgs) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactor) SetTransmitOcrPluginType(opts *bind.TransactOpts, ocrPluginType uint8) (*types.Transaction, error) { + return _MultiOCR3Helper.contract.Transact(opts, "setTransmitOcrPluginType", ocrPluginType) +} + +func (_MultiOCR3Helper *MultiOCR3HelperSession) SetTransmitOcrPluginType(ocrPluginType uint8) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.SetTransmitOcrPluginType(&_MultiOCR3Helper.TransactOpts, ocrPluginType) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactorSession) SetTransmitOcrPluginType(ocrPluginType uint8) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.SetTransmitOcrPluginType(&_MultiOCR3Helper.TransactOpts, ocrPluginType) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _MultiOCR3Helper.contract.Transact(opts, "transferOwnership", to) +} + +func (_MultiOCR3Helper *MultiOCR3HelperSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.TransferOwnership(&_MultiOCR3Helper.TransactOpts, to) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.TransferOwnership(&_MultiOCR3Helper.TransactOpts, to) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactor) TransmitWithSignatures(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _MultiOCR3Helper.contract.Transact(opts, "transmitWithSignatures", reportContext, report, rs, ss, rawVs) +} + +func (_MultiOCR3Helper *MultiOCR3HelperSession) TransmitWithSignatures(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.TransmitWithSignatures(&_MultiOCR3Helper.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactorSession) TransmitWithSignatures(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.TransmitWithSignatures(&_MultiOCR3Helper.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactor) TransmitWithoutSignatures(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte) (*types.Transaction, error) { + return _MultiOCR3Helper.contract.Transact(opts, "transmitWithoutSignatures", reportContext, report) +} + +func (_MultiOCR3Helper *MultiOCR3HelperSession) TransmitWithoutSignatures(reportContext [3][32]byte, report []byte) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.TransmitWithoutSignatures(&_MultiOCR3Helper.TransactOpts, reportContext, report) +} + +func (_MultiOCR3Helper *MultiOCR3HelperTransactorSession) TransmitWithoutSignatures(reportContext [3][32]byte, report []byte) (*types.Transaction, error) { + return _MultiOCR3Helper.Contract.TransmitWithoutSignatures(&_MultiOCR3Helper.TransactOpts, reportContext, report) +} + +type MultiOCR3HelperAfterConfigSetIterator struct { + Event *MultiOCR3HelperAfterConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiOCR3HelperAfterConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiOCR3HelperAfterConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiOCR3HelperAfterConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiOCR3HelperAfterConfigSetIterator) Error() error { + return it.fail +} + +func (it *MultiOCR3HelperAfterConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiOCR3HelperAfterConfigSet struct { + OcrPluginType uint8 + Raw types.Log +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) FilterAfterConfigSet(opts *bind.FilterOpts) (*MultiOCR3HelperAfterConfigSetIterator, error) { + + logs, sub, err := _MultiOCR3Helper.contract.FilterLogs(opts, "AfterConfigSet") + if err != nil { + return nil, err + } + return &MultiOCR3HelperAfterConfigSetIterator{contract: _MultiOCR3Helper.contract, event: "AfterConfigSet", logs: logs, sub: sub}, nil +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) WatchAfterConfigSet(opts *bind.WatchOpts, sink chan<- *MultiOCR3HelperAfterConfigSet) (event.Subscription, error) { + + logs, sub, err := _MultiOCR3Helper.contract.WatchLogs(opts, "AfterConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiOCR3HelperAfterConfigSet) + if err := _MultiOCR3Helper.contract.UnpackLog(event, "AfterConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) ParseAfterConfigSet(log types.Log) (*MultiOCR3HelperAfterConfigSet, error) { + event := new(MultiOCR3HelperAfterConfigSet) + if err := _MultiOCR3Helper.contract.UnpackLog(event, "AfterConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiOCR3HelperConfigSetIterator struct { + Event *MultiOCR3HelperConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiOCR3HelperConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiOCR3HelperConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiOCR3HelperConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiOCR3HelperConfigSetIterator) Error() error { + return it.fail +} + +func (it *MultiOCR3HelperConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiOCR3HelperConfigSet struct { + OcrPluginType uint8 + ConfigDigest [32]byte + Signers []common.Address + Transmitters []common.Address + F uint8 + Raw types.Log +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) FilterConfigSet(opts *bind.FilterOpts) (*MultiOCR3HelperConfigSetIterator, error) { + + logs, sub, err := _MultiOCR3Helper.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &MultiOCR3HelperConfigSetIterator{contract: _MultiOCR3Helper.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *MultiOCR3HelperConfigSet) (event.Subscription, error) { + + logs, sub, err := _MultiOCR3Helper.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiOCR3HelperConfigSet) + if err := _MultiOCR3Helper.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) ParseConfigSet(log types.Log) (*MultiOCR3HelperConfigSet, error) { + event := new(MultiOCR3HelperConfigSet) + if err := _MultiOCR3Helper.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiOCR3HelperOwnershipTransferRequestedIterator struct { + Event *MultiOCR3HelperOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiOCR3HelperOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiOCR3HelperOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiOCR3HelperOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiOCR3HelperOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *MultiOCR3HelperOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiOCR3HelperOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiOCR3HelperOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _MultiOCR3Helper.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &MultiOCR3HelperOwnershipTransferRequestedIterator{contract: _MultiOCR3Helper.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MultiOCR3HelperOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _MultiOCR3Helper.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiOCR3HelperOwnershipTransferRequested) + if err := _MultiOCR3Helper.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) ParseOwnershipTransferRequested(log types.Log) (*MultiOCR3HelperOwnershipTransferRequested, error) { + event := new(MultiOCR3HelperOwnershipTransferRequested) + if err := _MultiOCR3Helper.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiOCR3HelperOwnershipTransferredIterator struct { + Event *MultiOCR3HelperOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiOCR3HelperOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiOCR3HelperOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiOCR3HelperOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiOCR3HelperOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *MultiOCR3HelperOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiOCR3HelperOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiOCR3HelperOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _MultiOCR3Helper.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &MultiOCR3HelperOwnershipTransferredIterator{contract: _MultiOCR3Helper.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MultiOCR3HelperOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _MultiOCR3Helper.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiOCR3HelperOwnershipTransferred) + if err := _MultiOCR3Helper.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) ParseOwnershipTransferred(log types.Log) (*MultiOCR3HelperOwnershipTransferred, error) { + event := new(MultiOCR3HelperOwnershipTransferred) + if err := _MultiOCR3Helper.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MultiOCR3HelperTransmittedIterator struct { + Event *MultiOCR3HelperTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MultiOCR3HelperTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MultiOCR3HelperTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MultiOCR3HelperTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MultiOCR3HelperTransmittedIterator) Error() error { + return it.fail +} + +func (it *MultiOCR3HelperTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MultiOCR3HelperTransmitted struct { + OcrPluginType uint8 + ConfigDigest [32]byte + SequenceNumber uint64 + Raw types.Log +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) FilterTransmitted(opts *bind.FilterOpts, ocrPluginType []uint8) (*MultiOCR3HelperTransmittedIterator, error) { + + var ocrPluginTypeRule []interface{} + for _, ocrPluginTypeItem := range ocrPluginType { + ocrPluginTypeRule = append(ocrPluginTypeRule, ocrPluginTypeItem) + } + + logs, sub, err := _MultiOCR3Helper.contract.FilterLogs(opts, "Transmitted", ocrPluginTypeRule) + if err != nil { + return nil, err + } + return &MultiOCR3HelperTransmittedIterator{contract: _MultiOCR3Helper.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *MultiOCR3HelperTransmitted, ocrPluginType []uint8) (event.Subscription, error) { + + var ocrPluginTypeRule []interface{} + for _, ocrPluginTypeItem := range ocrPluginType { + ocrPluginTypeRule = append(ocrPluginTypeRule, ocrPluginTypeItem) + } + + logs, sub, err := _MultiOCR3Helper.contract.WatchLogs(opts, "Transmitted", ocrPluginTypeRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MultiOCR3HelperTransmitted) + if err := _MultiOCR3Helper.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MultiOCR3Helper *MultiOCR3HelperFilterer) ParseTransmitted(log types.Log) (*MultiOCR3HelperTransmitted, error) { + event := new(MultiOCR3HelperTransmitted) + if err := _MultiOCR3Helper.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_MultiOCR3Helper *MultiOCR3Helper) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _MultiOCR3Helper.abi.Events["AfterConfigSet"].ID: + return _MultiOCR3Helper.ParseAfterConfigSet(log) + case _MultiOCR3Helper.abi.Events["ConfigSet"].ID: + return _MultiOCR3Helper.ParseConfigSet(log) + case _MultiOCR3Helper.abi.Events["OwnershipTransferRequested"].ID: + return _MultiOCR3Helper.ParseOwnershipTransferRequested(log) + case _MultiOCR3Helper.abi.Events["OwnershipTransferred"].ID: + return _MultiOCR3Helper.ParseOwnershipTransferred(log) + case _MultiOCR3Helper.abi.Events["Transmitted"].ID: + return _MultiOCR3Helper.ParseTransmitted(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (MultiOCR3HelperAfterConfigSet) Topic() common.Hash { + return common.HexToHash("0x897ac1b2c12867721b284f3eb147bd4ab046d4eef1cf31c1d8988bfcfb962b53") +} + +func (MultiOCR3HelperConfigSet) Topic() common.Hash { + return common.HexToHash("0xab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547") +} + +func (MultiOCR3HelperOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (MultiOCR3HelperOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (MultiOCR3HelperTransmitted) Topic() common.Hash { + return common.HexToHash("0x198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0") +} + +func (_MultiOCR3Helper *MultiOCR3Helper) Address() common.Address { + return _MultiOCR3Helper.address +} + +type MultiOCR3HelperInterface interface { + GetOracle(opts *bind.CallOpts, ocrPluginType uint8, oracleAddress common.Address) (MultiOCR3BaseOracle, error) + + LatestConfigDetails(opts *bind.CallOpts, ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + SetOCR3Configs(opts *bind.TransactOpts, ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) + + SetTransmitOcrPluginType(opts *bind.TransactOpts, ocrPluginType uint8) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + TransmitWithSignatures(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + TransmitWithoutSignatures(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte) (*types.Transaction, error) + + FilterAfterConfigSet(opts *bind.FilterOpts) (*MultiOCR3HelperAfterConfigSetIterator, error) + + WatchAfterConfigSet(opts *bind.WatchOpts, sink chan<- *MultiOCR3HelperAfterConfigSet) (event.Subscription, error) + + ParseAfterConfigSet(log types.Log) (*MultiOCR3HelperAfterConfigSet, error) + + FilterConfigSet(opts *bind.FilterOpts) (*MultiOCR3HelperConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *MultiOCR3HelperConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*MultiOCR3HelperConfigSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiOCR3HelperOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MultiOCR3HelperOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*MultiOCR3HelperOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiOCR3HelperOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MultiOCR3HelperOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*MultiOCR3HelperOwnershipTransferred, error) + + FilterTransmitted(opts *bind.FilterOpts, ocrPluginType []uint8) (*MultiOCR3HelperTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *MultiOCR3HelperTransmitted, ocrPluginType []uint8) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*MultiOCR3HelperTransmitted, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go b/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go new file mode 100644 index 0000000000..14979b4fe3 --- /dev/null +++ b/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go @@ -0,0 +1,1234 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package nonce_manager + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type AuthorizedCallersAuthorizedCallerArgs struct { + AddedCallers []common.Address + RemovedCallers []common.Address +} + +type NonceManagerPreviousRamps struct { + PrevOnRamp common.Address + PrevOffRamp common.Address +} + +type NonceManagerPreviousRampsArgs struct { + RemoteChainSelector uint64 + PrevRamps NonceManagerPreviousRamps +} + +var NonceManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"PreviousRampAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"prevRamp\",\"type\":\"tuple\"}],\"name\":\"PreviousRampsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"}],\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"prevRamps\",\"type\":\"tuple\"}],\"internalType\":\"structNonceManager.PreviousRampsArgs[]\",\"name\":\"previousRampsArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPreviousRampsUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"getInboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getIncrementedOutboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getOutboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getPreviousRamps\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"}],\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expectedNonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"incrementInboundNonce\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b5060405162001ad538038062001ad58339810160408190526200003491620004b0565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620000f6565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001a1565b5050620005d0565b336001600160a01b03821603620001505760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000231576000828281518110620001ca57620001ca62000582565b60209081029190910101519050620001e4600282620002f0565b1562000227576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001a9565b50815160005b8151811015620002ea57600082828151811062000258576200025862000582565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000296576040516342bcdf7f60e11b815260040160405180910390fd5b620002a360028262000310565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000237565b50505050565b600062000307836001600160a01b03841662000327565b90505b92915050565b600062000307836001600160a01b0384166200042b565b60008181526001830160205260408120548015620004205760006200034e60018362000598565b8554909150600090620003649060019062000598565b9050818114620003d057600086600001828154811062000388576200038862000582565b9060005260206000200154905080876000018481548110620003ae57620003ae62000582565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620003e457620003e4620005ba565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200030a565b60009150506200030a565b600081815260018301602052604081205462000474575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200030a565b5060006200030a565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b0381168114620004ab57600080fd5b919050565b60006020808385031215620004c457600080fd5b82516001600160401b0380821115620004dc57600080fd5b818501915085601f830112620004f157600080fd5b8151818111156200050657620005066200047d565b8060051b604051601f19603f830116810181811085821117156200052e576200052e6200047d565b6040529182528482019250838101850191888311156200054d57600080fd5b938501935b828510156200057657620005668562000493565b8452938501939285019262000552565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200030a57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b6114f580620005e06000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c806391a2749a11610081578063e0e03cae1161005b578063e0e03cae14610228578063ea458c0c1461024b578063f2fde38b1461025e57600080fd5b806391a2749a146101d6578063bf18402a146101e9578063c92236251461021557600080fd5b806379ba5097116100b257806379ba50971461019157806384d8acf71461019b5780638da5cb5b146101ae57600080fd5b80632451a627146100ce578063294b5630146100ec575b600080fd5b6100d6610271565b6040516100e39190610f2e565b60405180910390f35b61015d6100fa366004610f9e565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600460209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff9081168452600190910154169082015290565b60408051825173ffffffffffffffffffffffffffffffffffffffff90811682526020938401511692810192909252016100e3565b610199610282565b005b6101996101a9366004610fbb565b610384565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e3565b6101996101e4366004611146565b610560565b6101fc6101f73660046111ed565b610574565b60405167ffffffffffffffff90911681526020016100e3565b6101fc61022336600461126f565b610589565b61023b6102363660046112c4565b6105a0565b60405190151581526020016100e3565b6101fc6102593660046111ed565b6106a9565b61019961026c366004611329565b61073d565b606061027d600261074e565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314610308576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61038c61075b565b60005b8181101561055b57368383838181106103aa576103aa611346565b606002919091019150600090506004816103c76020850185610f9e565b67ffffffffffffffff1681526020810191909152604001600020805490915073ffffffffffffffffffffffffffffffffffffffff161515806104225750600181015473ffffffffffffffffffffffffffffffffffffffff1615155b15610459576040517fc6117ae200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104696040830160208401611329565b81547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff919091161781556104b96060830160408401611329565b6001820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561050d6020830183610f9e565b67ffffffffffffffff167fa2e43edcbc4fd175ae4bebbe3fd6139871ed1f1783cd4a1ace59b90d302c3319836020016040516105499190611375565b60405180910390a2505060010161038f565b505050565b61056861075b565b610571816107de565b50565b60006105808383610970565b90505b92915050565b6000610596848484610a8d565b90505b9392505050565b60006105aa610bde565b60006105b7868585610a8d565b6105c29060016113ec565b90508467ffffffffffffffff168167ffffffffffffffff1614610626577f606ff8179e5e3c059b82df931acc496b7b6053e8879042f8267f930e0595f69f86868686604051610614949392919061140d565b60405180910390a160009150506106a1565b67ffffffffffffffff86166000908152600660205260409081902090518291906106539087908790611479565b908152604051908190036020019020805467ffffffffffffffff929092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090921691909117905550600190505b949350505050565b60006106b3610bde565b60006106bf8484610970565b6106ca9060016113ec565b67ffffffffffffffff808616600090815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff89168452909152902080549183167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090921691909117905591505092915050565b61074561075b565b61057181610c21565b6060600061059983610d16565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102ff565b565b602081015160005b815181101561087957600082828151811061080357610803611346565b60200260200101519050610821816002610d7290919063ffffffff16565b156108705760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b506001016107e6565b50815160005b815181101561096a57600082828151811061089c5761089c611346565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361090c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610917600282610d94565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010161087f565b50505050565b67ffffffffffffffff808316600090815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120549091168082036105805767ffffffffffffffff841660009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff168015610a85576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015282169063856c824790602401602060405180830381865afa158015610a58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7c9190611489565b92505050610583565b509392505050565b67ffffffffffffffff83166000908152600660205260408082209051829190610ab99086908690611479565b9081526040519081900360200190205467ffffffffffffffff16905060008190036105965767ffffffffffffffff851660009081526004602052604090206001015473ffffffffffffffffffffffffffffffffffffffff168015610bd55773ffffffffffffffffffffffffffffffffffffffff811663856c8247610b3f86880188611329565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401602060405180830381865afa158015610ba8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bcc9190611489565b92505050610599565b50949350505050565b610be9600233610db6565b6107dc576040517fd86ad9cf0000000000000000000000000000000000000000000000000000000081523360048201526024016102ff565b3373ffffffffffffffffffffffffffffffffffffffff821603610ca0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102ff565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b606081600001805480602002602001604051908101604052809291908181526020018280548015610d6657602002820191906000526020600020905b815481526020019060010190808311610d52575b50505050509050919050565b60006105808373ffffffffffffffffffffffffffffffffffffffff8416610de5565b60006105808373ffffffffffffffffffffffffffffffffffffffff8416610edf565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610580565b60008181526001830160205260408120548015610ece576000610e096001836114a6565b8554909150600090610e1d906001906114a6565b9050818114610e82576000866000018281548110610e3d57610e3d611346565b9060005260206000200154905080876000018481548110610e6057610e60611346565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610e9357610e936114b9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610583565b6000915050610583565b5092915050565b6000818152600183016020526040812054610f2657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610583565b506000610583565b6020808252825182820181905260009190848201906040850190845b81811015610f7c57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610f4a565b50909695505050505050565b67ffffffffffffffff8116811461057157600080fd5b600060208284031215610fb057600080fd5b813561058081610f88565b60008060208385031215610fce57600080fd5b823567ffffffffffffffff80821115610fe657600080fd5b818501915085601f830112610ffa57600080fd5b81358181111561100957600080fd5b86602060608302850101111561101e57600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461057157600080fd5b600082601f83011261109257600080fd5b8135602067ffffffffffffffff808311156110af576110af611030565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811084821117156110f2576110f2611030565b604052938452602081870181019490810192508785111561111257600080fd5b6020870191505b8482101561113b57813561112c8161105f565b83529183019190830190611119565b979650505050505050565b60006020828403121561115857600080fd5b813567ffffffffffffffff8082111561117057600080fd5b908301906040828603121561118457600080fd5b60405160408101818110838211171561119f5761119f611030565b6040528235828111156111b157600080fd5b6111bd87828601611081565b8252506020830135828111156111d257600080fd5b6111de87828601611081565b60208301525095945050505050565b6000806040838503121561120057600080fd5b823561120b81610f88565b9150602083013561121b8161105f565b809150509250929050565b60008083601f84011261123857600080fd5b50813567ffffffffffffffff81111561125057600080fd5b60208301915083602082850101111561126857600080fd5b9250929050565b60008060006040848603121561128457600080fd5b833561128f81610f88565b9250602084013567ffffffffffffffff8111156112ab57600080fd5b6112b786828701611226565b9497909650939450505050565b600080600080606085870312156112da57600080fd5b84356112e581610f88565b935060208501356112f581610f88565b9250604085013567ffffffffffffffff81111561131157600080fd5b61131d87828801611226565b95989497509550505050565b60006020828403121561133b57600080fd5b81356105808161105f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040810182356113848161105f565b73ffffffffffffffffffffffffffffffffffffffff90811683526020840135906113ad8261105f565b8082166020850152505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff818116838216019080821115610ed857610ed86113bd565b600067ffffffffffffffff8087168352808616602084015250606060408301528260608301528284608084013760006080848401015260807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905095945050505050565b8183823760009101908152919050565b60006020828403121561149b57600080fd5b815161058081610f88565b81810381811115610583576105836113bd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", +} + +var NonceManagerABI = NonceManagerMetaData.ABI + +var NonceManagerBin = NonceManagerMetaData.Bin + +func DeployNonceManager(auth *bind.TransactOpts, backend bind.ContractBackend, authorizedCallers []common.Address) (common.Address, *types.Transaction, *NonceManager, error) { + parsed, err := NonceManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(NonceManagerBin), backend, authorizedCallers) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NonceManager{address: address, abi: *parsed, NonceManagerCaller: NonceManagerCaller{contract: contract}, NonceManagerTransactor: NonceManagerTransactor{contract: contract}, NonceManagerFilterer: NonceManagerFilterer{contract: contract}}, nil +} + +type NonceManager struct { + address common.Address + abi abi.ABI + NonceManagerCaller + NonceManagerTransactor + NonceManagerFilterer +} + +type NonceManagerCaller struct { + contract *bind.BoundContract +} + +type NonceManagerTransactor struct { + contract *bind.BoundContract +} + +type NonceManagerFilterer struct { + contract *bind.BoundContract +} + +type NonceManagerSession struct { + Contract *NonceManager + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type NonceManagerCallerSession struct { + Contract *NonceManagerCaller + CallOpts bind.CallOpts +} + +type NonceManagerTransactorSession struct { + Contract *NonceManagerTransactor + TransactOpts bind.TransactOpts +} + +type NonceManagerRaw struct { + Contract *NonceManager +} + +type NonceManagerCallerRaw struct { + Contract *NonceManagerCaller +} + +type NonceManagerTransactorRaw struct { + Contract *NonceManagerTransactor +} + +func NewNonceManager(address common.Address, backend bind.ContractBackend) (*NonceManager, error) { + abi, err := abi.JSON(strings.NewReader(NonceManagerABI)) + if err != nil { + return nil, err + } + contract, err := bindNonceManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NonceManager{address: address, abi: abi, NonceManagerCaller: NonceManagerCaller{contract: contract}, NonceManagerTransactor: NonceManagerTransactor{contract: contract}, NonceManagerFilterer: NonceManagerFilterer{contract: contract}}, nil +} + +func NewNonceManagerCaller(address common.Address, caller bind.ContractCaller) (*NonceManagerCaller, error) { + contract, err := bindNonceManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NonceManagerCaller{contract: contract}, nil +} + +func NewNonceManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*NonceManagerTransactor, error) { + contract, err := bindNonceManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NonceManagerTransactor{contract: contract}, nil +} + +func NewNonceManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*NonceManagerFilterer, error) { + contract, err := bindNonceManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NonceManagerFilterer{contract: contract}, nil +} + +func bindNonceManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NonceManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_NonceManager *NonceManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NonceManager.Contract.NonceManagerCaller.contract.Call(opts, result, method, params...) +} + +func (_NonceManager *NonceManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NonceManager.Contract.NonceManagerTransactor.contract.Transfer(opts) +} + +func (_NonceManager *NonceManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NonceManager.Contract.NonceManagerTransactor.contract.Transact(opts, method, params...) +} + +func (_NonceManager *NonceManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NonceManager.Contract.contract.Call(opts, result, method, params...) +} + +func (_NonceManager *NonceManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NonceManager.Contract.contract.Transfer(opts) +} + +func (_NonceManager *NonceManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NonceManager.Contract.contract.Transact(opts, method, params...) +} + +func (_NonceManager *NonceManagerCaller) GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _NonceManager.contract.Call(opts, &out, "getAllAuthorizedCallers") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_NonceManager *NonceManagerSession) GetAllAuthorizedCallers() ([]common.Address, error) { + return _NonceManager.Contract.GetAllAuthorizedCallers(&_NonceManager.CallOpts) +} + +func (_NonceManager *NonceManagerCallerSession) GetAllAuthorizedCallers() ([]common.Address, error) { + return _NonceManager.Contract.GetAllAuthorizedCallers(&_NonceManager.CallOpts) +} + +func (_NonceManager *NonceManagerCaller) GetInboundNonce(opts *bind.CallOpts, sourceChainSelector uint64, sender []byte) (uint64, error) { + var out []interface{} + err := _NonceManager.contract.Call(opts, &out, "getInboundNonce", sourceChainSelector, sender) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_NonceManager *NonceManagerSession) GetInboundNonce(sourceChainSelector uint64, sender []byte) (uint64, error) { + return _NonceManager.Contract.GetInboundNonce(&_NonceManager.CallOpts, sourceChainSelector, sender) +} + +func (_NonceManager *NonceManagerCallerSession) GetInboundNonce(sourceChainSelector uint64, sender []byte) (uint64, error) { + return _NonceManager.Contract.GetInboundNonce(&_NonceManager.CallOpts, sourceChainSelector, sender) +} + +func (_NonceManager *NonceManagerCaller) GetOutboundNonce(opts *bind.CallOpts, destChainSelector uint64, sender common.Address) (uint64, error) { + var out []interface{} + err := _NonceManager.contract.Call(opts, &out, "getOutboundNonce", destChainSelector, sender) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_NonceManager *NonceManagerSession) GetOutboundNonce(destChainSelector uint64, sender common.Address) (uint64, error) { + return _NonceManager.Contract.GetOutboundNonce(&_NonceManager.CallOpts, destChainSelector, sender) +} + +func (_NonceManager *NonceManagerCallerSession) GetOutboundNonce(destChainSelector uint64, sender common.Address) (uint64, error) { + return _NonceManager.Contract.GetOutboundNonce(&_NonceManager.CallOpts, destChainSelector, sender) +} + +func (_NonceManager *NonceManagerCaller) GetPreviousRamps(opts *bind.CallOpts, chainSelector uint64) (NonceManagerPreviousRamps, error) { + var out []interface{} + err := _NonceManager.contract.Call(opts, &out, "getPreviousRamps", chainSelector) + + if err != nil { + return *new(NonceManagerPreviousRamps), err + } + + out0 := *abi.ConvertType(out[0], new(NonceManagerPreviousRamps)).(*NonceManagerPreviousRamps) + + return out0, err + +} + +func (_NonceManager *NonceManagerSession) GetPreviousRamps(chainSelector uint64) (NonceManagerPreviousRamps, error) { + return _NonceManager.Contract.GetPreviousRamps(&_NonceManager.CallOpts, chainSelector) +} + +func (_NonceManager *NonceManagerCallerSession) GetPreviousRamps(chainSelector uint64) (NonceManagerPreviousRamps, error) { + return _NonceManager.Contract.GetPreviousRamps(&_NonceManager.CallOpts, chainSelector) +} + +func (_NonceManager *NonceManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NonceManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_NonceManager *NonceManagerSession) Owner() (common.Address, error) { + return _NonceManager.Contract.Owner(&_NonceManager.CallOpts) +} + +func (_NonceManager *NonceManagerCallerSession) Owner() (common.Address, error) { + return _NonceManager.Contract.Owner(&_NonceManager.CallOpts) +} + +func (_NonceManager *NonceManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NonceManager.contract.Transact(opts, "acceptOwnership") +} + +func (_NonceManager *NonceManagerSession) AcceptOwnership() (*types.Transaction, error) { + return _NonceManager.Contract.AcceptOwnership(&_NonceManager.TransactOpts) +} + +func (_NonceManager *NonceManagerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _NonceManager.Contract.AcceptOwnership(&_NonceManager.TransactOpts) +} + +func (_NonceManager *NonceManagerTransactor) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _NonceManager.contract.Transact(opts, "applyAuthorizedCallerUpdates", authorizedCallerArgs) +} + +func (_NonceManager *NonceManagerSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _NonceManager.Contract.ApplyAuthorizedCallerUpdates(&_NonceManager.TransactOpts, authorizedCallerArgs) +} + +func (_NonceManager *NonceManagerTransactorSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _NonceManager.Contract.ApplyAuthorizedCallerUpdates(&_NonceManager.TransactOpts, authorizedCallerArgs) +} + +func (_NonceManager *NonceManagerTransactor) ApplyPreviousRampsUpdates(opts *bind.TransactOpts, previousRampsArgs []NonceManagerPreviousRampsArgs) (*types.Transaction, error) { + return _NonceManager.contract.Transact(opts, "applyPreviousRampsUpdates", previousRampsArgs) +} + +func (_NonceManager *NonceManagerSession) ApplyPreviousRampsUpdates(previousRampsArgs []NonceManagerPreviousRampsArgs) (*types.Transaction, error) { + return _NonceManager.Contract.ApplyPreviousRampsUpdates(&_NonceManager.TransactOpts, previousRampsArgs) +} + +func (_NonceManager *NonceManagerTransactorSession) ApplyPreviousRampsUpdates(previousRampsArgs []NonceManagerPreviousRampsArgs) (*types.Transaction, error) { + return _NonceManager.Contract.ApplyPreviousRampsUpdates(&_NonceManager.TransactOpts, previousRampsArgs) +} + +func (_NonceManager *NonceManagerTransactor) GetIncrementedOutboundNonce(opts *bind.TransactOpts, destChainSelector uint64, sender common.Address) (*types.Transaction, error) { + return _NonceManager.contract.Transact(opts, "getIncrementedOutboundNonce", destChainSelector, sender) +} + +func (_NonceManager *NonceManagerSession) GetIncrementedOutboundNonce(destChainSelector uint64, sender common.Address) (*types.Transaction, error) { + return _NonceManager.Contract.GetIncrementedOutboundNonce(&_NonceManager.TransactOpts, destChainSelector, sender) +} + +func (_NonceManager *NonceManagerTransactorSession) GetIncrementedOutboundNonce(destChainSelector uint64, sender common.Address) (*types.Transaction, error) { + return _NonceManager.Contract.GetIncrementedOutboundNonce(&_NonceManager.TransactOpts, destChainSelector, sender) +} + +func (_NonceManager *NonceManagerTransactor) IncrementInboundNonce(opts *bind.TransactOpts, sourceChainSelector uint64, expectedNonce uint64, sender []byte) (*types.Transaction, error) { + return _NonceManager.contract.Transact(opts, "incrementInboundNonce", sourceChainSelector, expectedNonce, sender) +} + +func (_NonceManager *NonceManagerSession) IncrementInboundNonce(sourceChainSelector uint64, expectedNonce uint64, sender []byte) (*types.Transaction, error) { + return _NonceManager.Contract.IncrementInboundNonce(&_NonceManager.TransactOpts, sourceChainSelector, expectedNonce, sender) +} + +func (_NonceManager *NonceManagerTransactorSession) IncrementInboundNonce(sourceChainSelector uint64, expectedNonce uint64, sender []byte) (*types.Transaction, error) { + return _NonceManager.Contract.IncrementInboundNonce(&_NonceManager.TransactOpts, sourceChainSelector, expectedNonce, sender) +} + +func (_NonceManager *NonceManagerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _NonceManager.contract.Transact(opts, "transferOwnership", to) +} + +func (_NonceManager *NonceManagerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _NonceManager.Contract.TransferOwnership(&_NonceManager.TransactOpts, to) +} + +func (_NonceManager *NonceManagerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _NonceManager.Contract.TransferOwnership(&_NonceManager.TransactOpts, to) +} + +type NonceManagerAuthorizedCallerAddedIterator struct { + Event *NonceManagerAuthorizedCallerAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NonceManagerAuthorizedCallerAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NonceManagerAuthorizedCallerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NonceManagerAuthorizedCallerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NonceManagerAuthorizedCallerAddedIterator) Error() error { + return it.fail +} + +func (it *NonceManagerAuthorizedCallerAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NonceManagerAuthorizedCallerAdded struct { + Caller common.Address + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*NonceManagerAuthorizedCallerAddedIterator, error) { + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "AuthorizedCallerAdded") + if err != nil { + return nil, err + } + return &NonceManagerAuthorizedCallerAddedIterator{contract: _NonceManager.contract, event: "AuthorizedCallerAdded", logs: logs, sub: sub}, nil +} + +func (_NonceManager *NonceManagerFilterer) WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *NonceManagerAuthorizedCallerAdded) (event.Subscription, error) { + + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "AuthorizedCallerAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NonceManagerAuthorizedCallerAdded) + if err := _NonceManager.contract.UnpackLog(event, "AuthorizedCallerAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NonceManager *NonceManagerFilterer) ParseAuthorizedCallerAdded(log types.Log) (*NonceManagerAuthorizedCallerAdded, error) { + event := new(NonceManagerAuthorizedCallerAdded) + if err := _NonceManager.contract.UnpackLog(event, "AuthorizedCallerAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NonceManagerAuthorizedCallerRemovedIterator struct { + Event *NonceManagerAuthorizedCallerRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NonceManagerAuthorizedCallerRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NonceManagerAuthorizedCallerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NonceManagerAuthorizedCallerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NonceManagerAuthorizedCallerRemovedIterator) Error() error { + return it.fail +} + +func (it *NonceManagerAuthorizedCallerRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NonceManagerAuthorizedCallerRemoved struct { + Caller common.Address + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*NonceManagerAuthorizedCallerRemovedIterator, error) { + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "AuthorizedCallerRemoved") + if err != nil { + return nil, err + } + return &NonceManagerAuthorizedCallerRemovedIterator{contract: _NonceManager.contract, event: "AuthorizedCallerRemoved", logs: logs, sub: sub}, nil +} + +func (_NonceManager *NonceManagerFilterer) WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *NonceManagerAuthorizedCallerRemoved) (event.Subscription, error) { + + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "AuthorizedCallerRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NonceManagerAuthorizedCallerRemoved) + if err := _NonceManager.contract.UnpackLog(event, "AuthorizedCallerRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NonceManager *NonceManagerFilterer) ParseAuthorizedCallerRemoved(log types.Log) (*NonceManagerAuthorizedCallerRemoved, error) { + event := new(NonceManagerAuthorizedCallerRemoved) + if err := _NonceManager.contract.UnpackLog(event, "AuthorizedCallerRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NonceManagerOwnershipTransferRequestedIterator struct { + Event *NonceManagerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NonceManagerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NonceManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NonceManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NonceManagerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *NonceManagerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NonceManagerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NonceManagerOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &NonceManagerOwnershipTransferRequestedIterator{contract: _NonceManager.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_NonceManager *NonceManagerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *NonceManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NonceManagerOwnershipTransferRequested) + if err := _NonceManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NonceManager *NonceManagerFilterer) ParseOwnershipTransferRequested(log types.Log) (*NonceManagerOwnershipTransferRequested, error) { + event := new(NonceManagerOwnershipTransferRequested) + if err := _NonceManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NonceManagerOwnershipTransferredIterator struct { + Event *NonceManagerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NonceManagerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NonceManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NonceManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NonceManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *NonceManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NonceManagerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NonceManagerOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &NonceManagerOwnershipTransferredIterator{contract: _NonceManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_NonceManager *NonceManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *NonceManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NonceManagerOwnershipTransferred) + if err := _NonceManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NonceManager *NonceManagerFilterer) ParseOwnershipTransferred(log types.Log) (*NonceManagerOwnershipTransferred, error) { + event := new(NonceManagerOwnershipTransferred) + if err := _NonceManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NonceManagerPreviousRampsUpdatedIterator struct { + Event *NonceManagerPreviousRampsUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NonceManagerPreviousRampsUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NonceManagerPreviousRampsUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NonceManagerPreviousRampsUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NonceManagerPreviousRampsUpdatedIterator) Error() error { + return it.fail +} + +func (it *NonceManagerPreviousRampsUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NonceManagerPreviousRampsUpdated struct { + RemoteChainSelector uint64 + PrevRamp NonceManagerPreviousRamps + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterPreviousRampsUpdated(opts *bind.FilterOpts, remoteChainSelector []uint64) (*NonceManagerPreviousRampsUpdatedIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "PreviousRampsUpdated", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &NonceManagerPreviousRampsUpdatedIterator{contract: _NonceManager.contract, event: "PreviousRampsUpdated", logs: logs, sub: sub}, nil +} + +func (_NonceManager *NonceManagerFilterer) WatchPreviousRampsUpdated(opts *bind.WatchOpts, sink chan<- *NonceManagerPreviousRampsUpdated, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "PreviousRampsUpdated", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NonceManagerPreviousRampsUpdated) + if err := _NonceManager.contract.UnpackLog(event, "PreviousRampsUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NonceManager *NonceManagerFilterer) ParsePreviousRampsUpdated(log types.Log) (*NonceManagerPreviousRampsUpdated, error) { + event := new(NonceManagerPreviousRampsUpdated) + if err := _NonceManager.contract.UnpackLog(event, "PreviousRampsUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NonceManagerSkippedIncorrectNonceIterator struct { + Event *NonceManagerSkippedIncorrectNonce + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NonceManagerSkippedIncorrectNonceIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NonceManagerSkippedIncorrectNonce) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NonceManagerSkippedIncorrectNonce) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NonceManagerSkippedIncorrectNonceIterator) Error() error { + return it.fail +} + +func (it *NonceManagerSkippedIncorrectNonceIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NonceManagerSkippedIncorrectNonce struct { + SourceChainSelector uint64 + Nonce uint64 + Sender []byte + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterSkippedIncorrectNonce(opts *bind.FilterOpts) (*NonceManagerSkippedIncorrectNonceIterator, error) { + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "SkippedIncorrectNonce") + if err != nil { + return nil, err + } + return &NonceManagerSkippedIncorrectNonceIterator{contract: _NonceManager.contract, event: "SkippedIncorrectNonce", logs: logs, sub: sub}, nil +} + +func (_NonceManager *NonceManagerFilterer) WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *NonceManagerSkippedIncorrectNonce) (event.Subscription, error) { + + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "SkippedIncorrectNonce") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NonceManagerSkippedIncorrectNonce) + if err := _NonceManager.contract.UnpackLog(event, "SkippedIncorrectNonce", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NonceManager *NonceManagerFilterer) ParseSkippedIncorrectNonce(log types.Log) (*NonceManagerSkippedIncorrectNonce, error) { + event := new(NonceManagerSkippedIncorrectNonce) + if err := _NonceManager.contract.UnpackLog(event, "SkippedIncorrectNonce", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_NonceManager *NonceManager) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _NonceManager.abi.Events["AuthorizedCallerAdded"].ID: + return _NonceManager.ParseAuthorizedCallerAdded(log) + case _NonceManager.abi.Events["AuthorizedCallerRemoved"].ID: + return _NonceManager.ParseAuthorizedCallerRemoved(log) + case _NonceManager.abi.Events["OwnershipTransferRequested"].ID: + return _NonceManager.ParseOwnershipTransferRequested(log) + case _NonceManager.abi.Events["OwnershipTransferred"].ID: + return _NonceManager.ParseOwnershipTransferred(log) + case _NonceManager.abi.Events["PreviousRampsUpdated"].ID: + return _NonceManager.ParsePreviousRampsUpdated(log) + case _NonceManager.abi.Events["SkippedIncorrectNonce"].ID: + return _NonceManager.ParseSkippedIncorrectNonce(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (NonceManagerAuthorizedCallerAdded) Topic() common.Hash { + return common.HexToHash("0xeb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef") +} + +func (NonceManagerAuthorizedCallerRemoved) Topic() common.Hash { + return common.HexToHash("0xc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda77580") +} + +func (NonceManagerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (NonceManagerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (NonceManagerPreviousRampsUpdated) Topic() common.Hash { + return common.HexToHash("0xa2e43edcbc4fd175ae4bebbe3fd6139871ed1f1783cd4a1ace59b90d302c3319") +} + +func (NonceManagerSkippedIncorrectNonce) Topic() common.Hash { + return common.HexToHash("0x606ff8179e5e3c059b82df931acc496b7b6053e8879042f8267f930e0595f69f") +} + +func (_NonceManager *NonceManager) Address() common.Address { + return _NonceManager.address +} + +type NonceManagerInterface interface { + GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) + + GetInboundNonce(opts *bind.CallOpts, sourceChainSelector uint64, sender []byte) (uint64, error) + + GetOutboundNonce(opts *bind.CallOpts, destChainSelector uint64, sender common.Address) (uint64, error) + + GetPreviousRamps(opts *bind.CallOpts, chainSelector uint64) (NonceManagerPreviousRamps, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) + + ApplyPreviousRampsUpdates(opts *bind.TransactOpts, previousRampsArgs []NonceManagerPreviousRampsArgs) (*types.Transaction, error) + + GetIncrementedOutboundNonce(opts *bind.TransactOpts, destChainSelector uint64, sender common.Address) (*types.Transaction, error) + + IncrementInboundNonce(opts *bind.TransactOpts, sourceChainSelector uint64, expectedNonce uint64, sender []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*NonceManagerAuthorizedCallerAddedIterator, error) + + WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *NonceManagerAuthorizedCallerAdded) (event.Subscription, error) + + ParseAuthorizedCallerAdded(log types.Log) (*NonceManagerAuthorizedCallerAdded, error) + + FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*NonceManagerAuthorizedCallerRemovedIterator, error) + + WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *NonceManagerAuthorizedCallerRemoved) (event.Subscription, error) + + ParseAuthorizedCallerRemoved(log types.Log) (*NonceManagerAuthorizedCallerRemoved, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NonceManagerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *NonceManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*NonceManagerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NonceManagerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *NonceManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*NonceManagerOwnershipTransferred, error) + + FilterPreviousRampsUpdated(opts *bind.FilterOpts, remoteChainSelector []uint64) (*NonceManagerPreviousRampsUpdatedIterator, error) + + WatchPreviousRampsUpdated(opts *bind.WatchOpts, sink chan<- *NonceManagerPreviousRampsUpdated, remoteChainSelector []uint64) (event.Subscription, error) + + ParsePreviousRampsUpdated(log types.Log) (*NonceManagerPreviousRampsUpdated, error) + + FilterSkippedIncorrectNonce(opts *bind.FilterOpts) (*NonceManagerSkippedIncorrectNonceIterator, error) + + WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *NonceManagerSkippedIncorrectNonce) (event.Subscription, error) + + ParseSkippedIncorrectNonce(log types.Log) (*NonceManagerSkippedIncorrectNonce, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/ocr3_config_encoder/ocr3_config_encoder.go b/core/gethwrappers/ccip/generated/ocr3_config_encoder/ocr3_config_encoder.go new file mode 100644 index 0000000000..399ae5dbd6 --- /dev/null +++ b/core/gethwrappers/ccip/generated/ocr3_config_encoder/ocr3_config_encoder.go @@ -0,0 +1,196 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package ocr3_config_encoder + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CCIPConfigTypesOCR3Config struct { + PluginType uint8 + ChainSelector uint64 + F uint8 + OffchainConfigVersion uint64 + OfframpAddress []byte + BootstrapP2PIds [][32]byte + P2pIds [][32]byte + Signers [][]byte + Transmitters [][]byte + OffchainConfig []byte +} + +var IOCR3ConfigEncoderMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"bootstrapP2PIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.OCR3Config[]\",\"name\":\"config\",\"type\":\"tuple[]\"}],\"name\":\"exposeOCR3Config\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +var IOCR3ConfigEncoderABI = IOCR3ConfigEncoderMetaData.ABI + +type IOCR3ConfigEncoder struct { + address common.Address + abi abi.ABI + IOCR3ConfigEncoderCaller + IOCR3ConfigEncoderTransactor + IOCR3ConfigEncoderFilterer +} + +type IOCR3ConfigEncoderCaller struct { + contract *bind.BoundContract +} + +type IOCR3ConfigEncoderTransactor struct { + contract *bind.BoundContract +} + +type IOCR3ConfigEncoderFilterer struct { + contract *bind.BoundContract +} + +type IOCR3ConfigEncoderSession struct { + Contract *IOCR3ConfigEncoder + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type IOCR3ConfigEncoderCallerSession struct { + Contract *IOCR3ConfigEncoderCaller + CallOpts bind.CallOpts +} + +type IOCR3ConfigEncoderTransactorSession struct { + Contract *IOCR3ConfigEncoderTransactor + TransactOpts bind.TransactOpts +} + +type IOCR3ConfigEncoderRaw struct { + Contract *IOCR3ConfigEncoder +} + +type IOCR3ConfigEncoderCallerRaw struct { + Contract *IOCR3ConfigEncoderCaller +} + +type IOCR3ConfigEncoderTransactorRaw struct { + Contract *IOCR3ConfigEncoderTransactor +} + +func NewIOCR3ConfigEncoder(address common.Address, backend bind.ContractBackend) (*IOCR3ConfigEncoder, error) { + abi, err := abi.JSON(strings.NewReader(IOCR3ConfigEncoderABI)) + if err != nil { + return nil, err + } + contract, err := bindIOCR3ConfigEncoder(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &IOCR3ConfigEncoder{address: address, abi: abi, IOCR3ConfigEncoderCaller: IOCR3ConfigEncoderCaller{contract: contract}, IOCR3ConfigEncoderTransactor: IOCR3ConfigEncoderTransactor{contract: contract}, IOCR3ConfigEncoderFilterer: IOCR3ConfigEncoderFilterer{contract: contract}}, nil +} + +func NewIOCR3ConfigEncoderCaller(address common.Address, caller bind.ContractCaller) (*IOCR3ConfigEncoderCaller, error) { + contract, err := bindIOCR3ConfigEncoder(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &IOCR3ConfigEncoderCaller{contract: contract}, nil +} + +func NewIOCR3ConfigEncoderTransactor(address common.Address, transactor bind.ContractTransactor) (*IOCR3ConfigEncoderTransactor, error) { + contract, err := bindIOCR3ConfigEncoder(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IOCR3ConfigEncoderTransactor{contract: contract}, nil +} + +func NewIOCR3ConfigEncoderFilterer(address common.Address, filterer bind.ContractFilterer) (*IOCR3ConfigEncoderFilterer, error) { + contract, err := bindIOCR3ConfigEncoder(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IOCR3ConfigEncoderFilterer{contract: contract}, nil +} + +func bindIOCR3ConfigEncoder(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := IOCR3ConfigEncoderMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_IOCR3ConfigEncoder *IOCR3ConfigEncoderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IOCR3ConfigEncoder.Contract.IOCR3ConfigEncoderCaller.contract.Call(opts, result, method, params...) +} + +func (_IOCR3ConfigEncoder *IOCR3ConfigEncoderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IOCR3ConfigEncoder.Contract.IOCR3ConfigEncoderTransactor.contract.Transfer(opts) +} + +func (_IOCR3ConfigEncoder *IOCR3ConfigEncoderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IOCR3ConfigEncoder.Contract.IOCR3ConfigEncoderTransactor.contract.Transact(opts, method, params...) +} + +func (_IOCR3ConfigEncoder *IOCR3ConfigEncoderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IOCR3ConfigEncoder.Contract.contract.Call(opts, result, method, params...) +} + +func (_IOCR3ConfigEncoder *IOCR3ConfigEncoderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IOCR3ConfigEncoder.Contract.contract.Transfer(opts) +} + +func (_IOCR3ConfigEncoder *IOCR3ConfigEncoderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IOCR3ConfigEncoder.Contract.contract.Transact(opts, method, params...) +} + +func (_IOCR3ConfigEncoder *IOCR3ConfigEncoderCaller) ExposeOCR3Config(opts *bind.CallOpts, config []CCIPConfigTypesOCR3Config) ([]byte, error) { + var out []interface{} + err := _IOCR3ConfigEncoder.contract.Call(opts, &out, "exposeOCR3Config", config) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_IOCR3ConfigEncoder *IOCR3ConfigEncoderSession) ExposeOCR3Config(config []CCIPConfigTypesOCR3Config) ([]byte, error) { + return _IOCR3ConfigEncoder.Contract.ExposeOCR3Config(&_IOCR3ConfigEncoder.CallOpts, config) +} + +func (_IOCR3ConfigEncoder *IOCR3ConfigEncoderCallerSession) ExposeOCR3Config(config []CCIPConfigTypesOCR3Config) ([]byte, error) { + return _IOCR3ConfigEncoder.Contract.ExposeOCR3Config(&_IOCR3ConfigEncoder.CallOpts, config) +} + +func (_IOCR3ConfigEncoder *IOCR3ConfigEncoder) Address() common.Address { + return _IOCR3ConfigEncoder.address +} + +type IOCR3ConfigEncoderInterface interface { + ExposeOCR3Config(opts *bind.CallOpts, config []CCIPConfigTypesOCR3Config) ([]byte, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/ping_pong_demo/ping_pong_demo.go b/core/gethwrappers/ccip/generated/ping_pong_demo/ping_pong_demo.go new file mode 100644 index 0000000000..4387dd3080 --- /dev/null +++ b/core/gethwrappers/ccip/generated/ping_pong_demo/ping_pong_demo.go @@ -0,0 +1,1061 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package ping_pong_demo + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientAny2EVMMessage struct { + MessageId [32]byte + SourceChainSelector uint64 + Sender []byte + Data []byte + DestTokenAmounts []ClientEVMTokenAmount +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +var PingPongDemoMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"feeToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"InvalidRouter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Ping\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Pong\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartChainSelector\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"counterpartChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"counterpartAddress\",\"type\":\"address\"}],\"name\":\"setCounterpart\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setCounterpartAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"setCounterpartChainSelector\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pause\",\"type\":\"bool\"}],\"name\":\"setPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startPingPong\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b50604051620013d8380380620013d8833981016040819052620000349162000263565b33806000846001600160a01b03811662000069576040516335fdcccd60e21b8152600060048201526024015b60405180910390fd5b6001600160a01b039081166080528216620000c75760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604482015260640162000060565b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000fa57620000fa816200019f565b50506002805460ff60a01b1916905550600380546001600160a01b0319166001600160a01b0383811691821790925560405163095ea7b360e01b8152918416600483015260001960248301529063095ea7b3906044016020604051808303816000875af115801562000170573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001969190620002a2565b505050620002cd565b336001600160a01b03821603620001f95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200026057600080fd5b50565b600080604083850312156200027757600080fd5b825162000284816200024a565b602084015190925062000297816200024a565b809150509250929050565b600060208284031215620002b557600080fd5b81518015158114620002c657600080fd5b9392505050565b6080516110e1620002f7600039600081816102290152818161058e01526108f201526110e16000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80638da5cb5b11610097578063b5a1101111610066578063b5a1101114610270578063bee518a414610283578063ca709a25146102c1578063f2fde38b146102df57600080fd5b80638da5cb5b146101f65780639d2aede514610214578063b0f479a114610227578063b187bd261461024d57600080fd5b80632874d8bf116100d35780632874d8bf146101945780632b6e5d631461019c57806379ba5097146101db57806385572ffb146101e357600080fd5b806301ffc9a71461010557806316c38b3c1461012d578063181f5a77146101425780631892b90614610181575b600080fd5b610118610113366004610af5565b6102f2565b60405190151581526020015b60405180910390f35b61014061013b366004610b3e565b61038b565b005b604080518082018252601281527f50696e67506f6e6744656d6f20312e322e300000000000000000000000000000602082015290516101249190610bc4565b61014061018f366004610bf4565b6103dd565b610140610438565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b610140610474565b6101406101f1366004610c0f565b610576565b60005473ffffffffffffffffffffffffffffffffffffffff166101b6565b610140610222366004610c6e565b6105fb565b7f00000000000000000000000000000000000000000000000000000000000000006101b6565b60025474010000000000000000000000000000000000000000900460ff16610118565b61014061027e366004610c89565b61064a565b60015474010000000000000000000000000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff9091168152602001610124565b60035473ffffffffffffffffffffffffffffffffffffffff166101b6565b6101406102ed366004610c6e565b6106ec565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f85572ffb00000000000000000000000000000000000000000000000000000000148061038557507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6103936106fd565b6002805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6103e56106fd565b6001805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104406106fd565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff169055610472600161077e565b565b60015473ffffffffffffffffffffffffffffffffffffffff1633146104fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146105e7576040517fd7f733340000000000000000000000000000000000000000000000000000000081523360048201526024016104f1565b6105f86105f382610ebf565b6109aa565b50565b6106036106fd565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6106526106fd565b6001805467ffffffffffffffff90931674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909316929092179091556002805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055565b6106f46106fd565b6105f881610a00565b60005473ffffffffffffffffffffffffffffffffffffffff163314610472576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104f1565b806001166001036107c1576040518181527f48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f9060200160405180910390a16107f5565b6040518181527f58b69f57828e6962d216502094c54f6562f3bf082ba758966c3454f9e37b15259060200160405180910390a15b60008160405160200161080a91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a08301825260025473ffffffffffffffffffffffffffffffffffffffff1660c0808501919091528251808503909101815260e084018352835260208084018290528251600080825291810184529194509291820190836108b8565b60408051808201909152600080825260208201528152602001906001900390816108915790505b50815260035473ffffffffffffffffffffffffffffffffffffffff16602080830191909152604080519182018152600082529091015290507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166396f4e9f9600160149054906101000a900467ffffffffffffffff16836040518363ffffffff1660e01b8152600401610961929190610f6c565b6020604051808303816000875af1158015610980573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a49190611081565b50505050565b600081606001518060200190518101906109c49190611081565b60025490915074010000000000000000000000000000000000000000900460ff166109fc576109fc6109f782600161109a565b61077e565b5050565b3373ffffffffffffffffffffffffffffffffffffffff821603610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104f1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610b0757600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610b3757600080fd5b9392505050565b600060208284031215610b5057600080fd5b81358015158114610b3757600080fd5b6000815180845260005b81811015610b8657602081850181015186830182015201610b6a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b376020830184610b60565b803567ffffffffffffffff81168114610bef57600080fd5b919050565b600060208284031215610c0657600080fd5b610b3782610bd7565b600060208284031215610c2157600080fd5b813567ffffffffffffffff811115610c3857600080fd5b820160a08185031215610b3757600080fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610bef57600080fd5b600060208284031215610c8057600080fd5b610b3782610c4a565b60008060408385031215610c9c57600080fd5b610ca583610bd7565b9150610cb360208401610c4a565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610d0e57610d0e610cbc565b60405290565b60405160a0810167ffffffffffffffff81118282101715610d0e57610d0e610cbc565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d7e57610d7e610cbc565b604052919050565b600082601f830112610d9757600080fd5b813567ffffffffffffffff811115610db157610db1610cbc565b610de260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610d37565b818152846020838601011115610df757600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f830112610e2557600080fd5b8135602067ffffffffffffffff821115610e4157610e41610cbc565b610e4f818360051b01610d37565b82815260069290921b84018101918181019086841115610e6e57600080fd5b8286015b84811015610eb45760408189031215610e8b5760008081fd5b610e93610ceb565b610e9c82610c4a565b81528185013585820152835291830191604001610e72565b509695505050505050565b600060a08236031215610ed157600080fd5b610ed9610d14565b82358152610ee960208401610bd7565b6020820152604083013567ffffffffffffffff80821115610f0957600080fd5b610f1536838701610d86565b60408401526060850135915080821115610f2e57600080fd5b610f3a36838701610d86565b60608401526080850135915080821115610f5357600080fd5b50610f6036828601610e14565b60808301525092915050565b6000604067ffffffffffffffff851683526020604081850152845160a06040860152610f9b60e0860182610b60565b9050818601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080878403016060880152610fd68383610b60565b6040890151888203830160808a01528051808352908601945060009350908501905b80841015611037578451805173ffffffffffffffffffffffffffffffffffffffff16835286015186830152938501936001939093019290860190610ff8565b50606089015173ffffffffffffffffffffffffffffffffffffffff1660a08901526080890151888203830160c08a015295506110738187610b60565b9a9950505050505050505050565b60006020828403121561109357600080fd5b5051919050565b80820180821115610385577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000818000a", +} + +var PingPongDemoABI = PingPongDemoMetaData.ABI + +var PingPongDemoBin = PingPongDemoMetaData.Bin + +func DeployPingPongDemo(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address, feeToken common.Address) (common.Address, *types.Transaction, *PingPongDemo, error) { + parsed, err := PingPongDemoMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PingPongDemoBin), backend, router, feeToken) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PingPongDemo{address: address, abi: *parsed, PingPongDemoCaller: PingPongDemoCaller{contract: contract}, PingPongDemoTransactor: PingPongDemoTransactor{contract: contract}, PingPongDemoFilterer: PingPongDemoFilterer{contract: contract}}, nil +} + +type PingPongDemo struct { + address common.Address + abi abi.ABI + PingPongDemoCaller + PingPongDemoTransactor + PingPongDemoFilterer +} + +type PingPongDemoCaller struct { + contract *bind.BoundContract +} + +type PingPongDemoTransactor struct { + contract *bind.BoundContract +} + +type PingPongDemoFilterer struct { + contract *bind.BoundContract +} + +type PingPongDemoSession struct { + Contract *PingPongDemo + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type PingPongDemoCallerSession struct { + Contract *PingPongDemoCaller + CallOpts bind.CallOpts +} + +type PingPongDemoTransactorSession struct { + Contract *PingPongDemoTransactor + TransactOpts bind.TransactOpts +} + +type PingPongDemoRaw struct { + Contract *PingPongDemo +} + +type PingPongDemoCallerRaw struct { + Contract *PingPongDemoCaller +} + +type PingPongDemoTransactorRaw struct { + Contract *PingPongDemoTransactor +} + +func NewPingPongDemo(address common.Address, backend bind.ContractBackend) (*PingPongDemo, error) { + abi, err := abi.JSON(strings.NewReader(PingPongDemoABI)) + if err != nil { + return nil, err + } + contract, err := bindPingPongDemo(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &PingPongDemo{address: address, abi: abi, PingPongDemoCaller: PingPongDemoCaller{contract: contract}, PingPongDemoTransactor: PingPongDemoTransactor{contract: contract}, PingPongDemoFilterer: PingPongDemoFilterer{contract: contract}}, nil +} + +func NewPingPongDemoCaller(address common.Address, caller bind.ContractCaller) (*PingPongDemoCaller, error) { + contract, err := bindPingPongDemo(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &PingPongDemoCaller{contract: contract}, nil +} + +func NewPingPongDemoTransactor(address common.Address, transactor bind.ContractTransactor) (*PingPongDemoTransactor, error) { + contract, err := bindPingPongDemo(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &PingPongDemoTransactor{contract: contract}, nil +} + +func NewPingPongDemoFilterer(address common.Address, filterer bind.ContractFilterer) (*PingPongDemoFilterer, error) { + contract, err := bindPingPongDemo(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PingPongDemoFilterer{contract: contract}, nil +} + +func bindPingPongDemo(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := PingPongDemoMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_PingPongDemo *PingPongDemoRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PingPongDemo.Contract.PingPongDemoCaller.contract.Call(opts, result, method, params...) +} + +func (_PingPongDemo *PingPongDemoRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PingPongDemo.Contract.PingPongDemoTransactor.contract.Transfer(opts) +} + +func (_PingPongDemo *PingPongDemoRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PingPongDemo.Contract.PingPongDemoTransactor.contract.Transact(opts, method, params...) +} + +func (_PingPongDemo *PingPongDemoCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PingPongDemo.Contract.contract.Call(opts, result, method, params...) +} + +func (_PingPongDemo *PingPongDemoTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PingPongDemo.Contract.contract.Transfer(opts) +} + +func (_PingPongDemo *PingPongDemoTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PingPongDemo.Contract.contract.Transact(opts, method, params...) +} + +func (_PingPongDemo *PingPongDemoCaller) GetCounterpartAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PingPongDemo.contract.Call(opts, &out, "getCounterpartAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_PingPongDemo *PingPongDemoSession) GetCounterpartAddress() (common.Address, error) { + return _PingPongDemo.Contract.GetCounterpartAddress(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCallerSession) GetCounterpartAddress() (common.Address, error) { + return _PingPongDemo.Contract.GetCounterpartAddress(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCaller) GetCounterpartChainSelector(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _PingPongDemo.contract.Call(opts, &out, "getCounterpartChainSelector") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_PingPongDemo *PingPongDemoSession) GetCounterpartChainSelector() (uint64, error) { + return _PingPongDemo.Contract.GetCounterpartChainSelector(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCallerSession) GetCounterpartChainSelector() (uint64, error) { + return _PingPongDemo.Contract.GetCounterpartChainSelector(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCaller) GetFeeToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PingPongDemo.contract.Call(opts, &out, "getFeeToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_PingPongDemo *PingPongDemoSession) GetFeeToken() (common.Address, error) { + return _PingPongDemo.Contract.GetFeeToken(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCallerSession) GetFeeToken() (common.Address, error) { + return _PingPongDemo.Contract.GetFeeToken(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PingPongDemo.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_PingPongDemo *PingPongDemoSession) GetRouter() (common.Address, error) { + return _PingPongDemo.Contract.GetRouter(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCallerSession) GetRouter() (common.Address, error) { + return _PingPongDemo.Contract.GetRouter(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCaller) IsPaused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _PingPongDemo.contract.Call(opts, &out, "isPaused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_PingPongDemo *PingPongDemoSession) IsPaused() (bool, error) { + return _PingPongDemo.Contract.IsPaused(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCallerSession) IsPaused() (bool, error) { + return _PingPongDemo.Contract.IsPaused(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PingPongDemo.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_PingPongDemo *PingPongDemoSession) Owner() (common.Address, error) { + return _PingPongDemo.Contract.Owner(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCallerSession) Owner() (common.Address, error) { + return _PingPongDemo.Contract.Owner(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _PingPongDemo.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_PingPongDemo *PingPongDemoSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _PingPongDemo.Contract.SupportsInterface(&_PingPongDemo.CallOpts, interfaceId) +} + +func (_PingPongDemo *PingPongDemoCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _PingPongDemo.Contract.SupportsInterface(&_PingPongDemo.CallOpts, interfaceId) +} + +func (_PingPongDemo *PingPongDemoCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _PingPongDemo.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_PingPongDemo *PingPongDemoSession) TypeAndVersion() (string, error) { + return _PingPongDemo.Contract.TypeAndVersion(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCallerSession) TypeAndVersion() (string, error) { + return _PingPongDemo.Contract.TypeAndVersion(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PingPongDemo.contract.Transact(opts, "acceptOwnership") +} + +func (_PingPongDemo *PingPongDemoSession) AcceptOwnership() (*types.Transaction, error) { + return _PingPongDemo.Contract.AcceptOwnership(&_PingPongDemo.TransactOpts) +} + +func (_PingPongDemo *PingPongDemoTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _PingPongDemo.Contract.AcceptOwnership(&_PingPongDemo.TransactOpts) +} + +func (_PingPongDemo *PingPongDemoTransactor) CcipReceive(opts *bind.TransactOpts, message ClientAny2EVMMessage) (*types.Transaction, error) { + return _PingPongDemo.contract.Transact(opts, "ccipReceive", message) +} + +func (_PingPongDemo *PingPongDemoSession) CcipReceive(message ClientAny2EVMMessage) (*types.Transaction, error) { + return _PingPongDemo.Contract.CcipReceive(&_PingPongDemo.TransactOpts, message) +} + +func (_PingPongDemo *PingPongDemoTransactorSession) CcipReceive(message ClientAny2EVMMessage) (*types.Transaction, error) { + return _PingPongDemo.Contract.CcipReceive(&_PingPongDemo.TransactOpts, message) +} + +func (_PingPongDemo *PingPongDemoTransactor) SetCounterpart(opts *bind.TransactOpts, counterpartChainSelector uint64, counterpartAddress common.Address) (*types.Transaction, error) { + return _PingPongDemo.contract.Transact(opts, "setCounterpart", counterpartChainSelector, counterpartAddress) +} + +func (_PingPongDemo *PingPongDemoSession) SetCounterpart(counterpartChainSelector uint64, counterpartAddress common.Address) (*types.Transaction, error) { + return _PingPongDemo.Contract.SetCounterpart(&_PingPongDemo.TransactOpts, counterpartChainSelector, counterpartAddress) +} + +func (_PingPongDemo *PingPongDemoTransactorSession) SetCounterpart(counterpartChainSelector uint64, counterpartAddress common.Address) (*types.Transaction, error) { + return _PingPongDemo.Contract.SetCounterpart(&_PingPongDemo.TransactOpts, counterpartChainSelector, counterpartAddress) +} + +func (_PingPongDemo *PingPongDemoTransactor) SetCounterpartAddress(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _PingPongDemo.contract.Transact(opts, "setCounterpartAddress", addr) +} + +func (_PingPongDemo *PingPongDemoSession) SetCounterpartAddress(addr common.Address) (*types.Transaction, error) { + return _PingPongDemo.Contract.SetCounterpartAddress(&_PingPongDemo.TransactOpts, addr) +} + +func (_PingPongDemo *PingPongDemoTransactorSession) SetCounterpartAddress(addr common.Address) (*types.Transaction, error) { + return _PingPongDemo.Contract.SetCounterpartAddress(&_PingPongDemo.TransactOpts, addr) +} + +func (_PingPongDemo *PingPongDemoTransactor) SetCounterpartChainSelector(opts *bind.TransactOpts, chainSelector uint64) (*types.Transaction, error) { + return _PingPongDemo.contract.Transact(opts, "setCounterpartChainSelector", chainSelector) +} + +func (_PingPongDemo *PingPongDemoSession) SetCounterpartChainSelector(chainSelector uint64) (*types.Transaction, error) { + return _PingPongDemo.Contract.SetCounterpartChainSelector(&_PingPongDemo.TransactOpts, chainSelector) +} + +func (_PingPongDemo *PingPongDemoTransactorSession) SetCounterpartChainSelector(chainSelector uint64) (*types.Transaction, error) { + return _PingPongDemo.Contract.SetCounterpartChainSelector(&_PingPongDemo.TransactOpts, chainSelector) +} + +func (_PingPongDemo *PingPongDemoTransactor) SetPaused(opts *bind.TransactOpts, pause bool) (*types.Transaction, error) { + return _PingPongDemo.contract.Transact(opts, "setPaused", pause) +} + +func (_PingPongDemo *PingPongDemoSession) SetPaused(pause bool) (*types.Transaction, error) { + return _PingPongDemo.Contract.SetPaused(&_PingPongDemo.TransactOpts, pause) +} + +func (_PingPongDemo *PingPongDemoTransactorSession) SetPaused(pause bool) (*types.Transaction, error) { + return _PingPongDemo.Contract.SetPaused(&_PingPongDemo.TransactOpts, pause) +} + +func (_PingPongDemo *PingPongDemoTransactor) StartPingPong(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PingPongDemo.contract.Transact(opts, "startPingPong") +} + +func (_PingPongDemo *PingPongDemoSession) StartPingPong() (*types.Transaction, error) { + return _PingPongDemo.Contract.StartPingPong(&_PingPongDemo.TransactOpts) +} + +func (_PingPongDemo *PingPongDemoTransactorSession) StartPingPong() (*types.Transaction, error) { + return _PingPongDemo.Contract.StartPingPong(&_PingPongDemo.TransactOpts) +} + +func (_PingPongDemo *PingPongDemoTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _PingPongDemo.contract.Transact(opts, "transferOwnership", to) +} + +func (_PingPongDemo *PingPongDemoSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _PingPongDemo.Contract.TransferOwnership(&_PingPongDemo.TransactOpts, to) +} + +func (_PingPongDemo *PingPongDemoTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _PingPongDemo.Contract.TransferOwnership(&_PingPongDemo.TransactOpts, to) +} + +type PingPongDemoOwnershipTransferRequestedIterator struct { + Event *PingPongDemoOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PingPongDemoOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PingPongDemoOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PingPongDemoOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PingPongDemoOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *PingPongDemoOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PingPongDemoOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_PingPongDemo *PingPongDemoFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PingPongDemoOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PingPongDemo.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &PingPongDemoOwnershipTransferRequestedIterator{contract: _PingPongDemo.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_PingPongDemo *PingPongDemoFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PingPongDemoOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PingPongDemo.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PingPongDemoOwnershipTransferRequested) + if err := _PingPongDemo.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PingPongDemo *PingPongDemoFilterer) ParseOwnershipTransferRequested(log types.Log) (*PingPongDemoOwnershipTransferRequested, error) { + event := new(PingPongDemoOwnershipTransferRequested) + if err := _PingPongDemo.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PingPongDemoOwnershipTransferredIterator struct { + Event *PingPongDemoOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PingPongDemoOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PingPongDemoOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PingPongDemoOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PingPongDemoOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *PingPongDemoOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PingPongDemoOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_PingPongDemo *PingPongDemoFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PingPongDemoOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PingPongDemo.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &PingPongDemoOwnershipTransferredIterator{contract: _PingPongDemo.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_PingPongDemo *PingPongDemoFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PingPongDemoOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PingPongDemo.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PingPongDemoOwnershipTransferred) + if err := _PingPongDemo.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PingPongDemo *PingPongDemoFilterer) ParseOwnershipTransferred(log types.Log) (*PingPongDemoOwnershipTransferred, error) { + event := new(PingPongDemoOwnershipTransferred) + if err := _PingPongDemo.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PingPongDemoPingIterator struct { + Event *PingPongDemoPing + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PingPongDemoPingIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PingPongDemoPing) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PingPongDemoPing) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PingPongDemoPingIterator) Error() error { + return it.fail +} + +func (it *PingPongDemoPingIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PingPongDemoPing struct { + PingPongCount *big.Int + Raw types.Log +} + +func (_PingPongDemo *PingPongDemoFilterer) FilterPing(opts *bind.FilterOpts) (*PingPongDemoPingIterator, error) { + + logs, sub, err := _PingPongDemo.contract.FilterLogs(opts, "Ping") + if err != nil { + return nil, err + } + return &PingPongDemoPingIterator{contract: _PingPongDemo.contract, event: "Ping", logs: logs, sub: sub}, nil +} + +func (_PingPongDemo *PingPongDemoFilterer) WatchPing(opts *bind.WatchOpts, sink chan<- *PingPongDemoPing) (event.Subscription, error) { + + logs, sub, err := _PingPongDemo.contract.WatchLogs(opts, "Ping") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PingPongDemoPing) + if err := _PingPongDemo.contract.UnpackLog(event, "Ping", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PingPongDemo *PingPongDemoFilterer) ParsePing(log types.Log) (*PingPongDemoPing, error) { + event := new(PingPongDemoPing) + if err := _PingPongDemo.contract.UnpackLog(event, "Ping", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PingPongDemoPongIterator struct { + Event *PingPongDemoPong + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PingPongDemoPongIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PingPongDemoPong) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PingPongDemoPong) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PingPongDemoPongIterator) Error() error { + return it.fail +} + +func (it *PingPongDemoPongIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PingPongDemoPong struct { + PingPongCount *big.Int + Raw types.Log +} + +func (_PingPongDemo *PingPongDemoFilterer) FilterPong(opts *bind.FilterOpts) (*PingPongDemoPongIterator, error) { + + logs, sub, err := _PingPongDemo.contract.FilterLogs(opts, "Pong") + if err != nil { + return nil, err + } + return &PingPongDemoPongIterator{contract: _PingPongDemo.contract, event: "Pong", logs: logs, sub: sub}, nil +} + +func (_PingPongDemo *PingPongDemoFilterer) WatchPong(opts *bind.WatchOpts, sink chan<- *PingPongDemoPong) (event.Subscription, error) { + + logs, sub, err := _PingPongDemo.contract.WatchLogs(opts, "Pong") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PingPongDemoPong) + if err := _PingPongDemo.contract.UnpackLog(event, "Pong", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PingPongDemo *PingPongDemoFilterer) ParsePong(log types.Log) (*PingPongDemoPong, error) { + event := new(PingPongDemoPong) + if err := _PingPongDemo.contract.UnpackLog(event, "Pong", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_PingPongDemo *PingPongDemo) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _PingPongDemo.abi.Events["OwnershipTransferRequested"].ID: + return _PingPongDemo.ParseOwnershipTransferRequested(log) + case _PingPongDemo.abi.Events["OwnershipTransferred"].ID: + return _PingPongDemo.ParseOwnershipTransferred(log) + case _PingPongDemo.abi.Events["Ping"].ID: + return _PingPongDemo.ParsePing(log) + case _PingPongDemo.abi.Events["Pong"].ID: + return _PingPongDemo.ParsePong(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (PingPongDemoOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (PingPongDemoOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (PingPongDemoPing) Topic() common.Hash { + return common.HexToHash("0x48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f") +} + +func (PingPongDemoPong) Topic() common.Hash { + return common.HexToHash("0x58b69f57828e6962d216502094c54f6562f3bf082ba758966c3454f9e37b1525") +} + +func (_PingPongDemo *PingPongDemo) Address() common.Address { + return _PingPongDemo.address +} + +type PingPongDemoInterface interface { + GetCounterpartAddress(opts *bind.CallOpts) (common.Address, error) + + GetCounterpartChainSelector(opts *bind.CallOpts) (uint64, error) + + GetFeeToken(opts *bind.CallOpts) (common.Address, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + IsPaused(opts *bind.CallOpts) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + CcipReceive(opts *bind.TransactOpts, message ClientAny2EVMMessage) (*types.Transaction, error) + + SetCounterpart(opts *bind.TransactOpts, counterpartChainSelector uint64, counterpartAddress common.Address) (*types.Transaction, error) + + SetCounterpartAddress(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) + + SetCounterpartChainSelector(opts *bind.TransactOpts, chainSelector uint64) (*types.Transaction, error) + + SetPaused(opts *bind.TransactOpts, pause bool) (*types.Transaction, error) + + StartPingPong(opts *bind.TransactOpts) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PingPongDemoOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PingPongDemoOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*PingPongDemoOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PingPongDemoOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PingPongDemoOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*PingPongDemoOwnershipTransferred, error) + + FilterPing(opts *bind.FilterOpts) (*PingPongDemoPingIterator, error) + + WatchPing(opts *bind.WatchOpts, sink chan<- *PingPongDemoPing) (event.Subscription, error) + + ParsePing(log types.Log) (*PingPongDemoPing, error) + + FilterPong(opts *bind.FilterOpts) (*PingPongDemoPongIterator, error) + + WatchPong(opts *bind.WatchOpts, sink chan<- *PingPongDemoPong) (event.Subscription, error) + + ParsePong(log types.Log) (*PingPongDemoPong, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/price_registry/price_registry.go b/core/gethwrappers/ccip/generated/price_registry/price_registry.go new file mode 100644 index 0000000000..19f1bd4a19 --- /dev/null +++ b/core/gethwrappers/ccip/generated/price_registry/price_registry.go @@ -0,0 +1,3141 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package price_registry + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type AuthorizedCallersAuthorizedCallerArgs struct { + AddedCallers []common.Address + RemovedCallers []common.Address +} + +type ClientEVM2AnyMessage struct { + Receiver []byte + Data []byte + TokenAmounts []ClientEVMTokenAmount + FeeToken common.Address + ExtraArgs []byte +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type IPriceRegistryTokenPriceFeedConfig struct { + DataFeedAddress common.Address + TokenDecimals uint8 +} + +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + +type InternalRampTokenAmount struct { + SourcePoolAddress []byte + DestTokenAddress []byte + ExtraData []byte + Amount *big.Int +} + +type InternalTimestampedPackedUint224 struct { + Value *big.Int + Timestamp uint32 +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +type PriceRegistryDestChainConfig struct { + IsEnabled bool + MaxNumberOfTokensPerMsg uint16 + MaxDataBytes uint32 + MaxPerMsgGasLimit uint32 + DestGasOverhead uint32 + DestGasPerPayloadByte uint16 + DestDataAvailabilityOverheadGas uint32 + DestGasPerDataAvailabilityByte uint16 + DestDataAvailabilityMultiplierBps uint16 + DefaultTokenFeeUSDCents uint16 + DefaultTokenDestGasOverhead uint32 + DefaultTokenDestBytesOverhead uint32 + DefaultTxGasLimit uint32 + GasMultiplierWeiPerEth uint64 + NetworkFeeUSDCents uint32 + EnforceOutOfOrder bool + ChainFamilySelector [4]byte +} + +type PriceRegistryDestChainConfigArgs struct { + DestChainSelector uint64 + DestChainConfig PriceRegistryDestChainConfig +} + +type PriceRegistryPremiumMultiplierWeiPerEthArgs struct { + Token common.Address + PremiumMultiplierWeiPerEth uint64 +} + +type PriceRegistryStaticConfig struct { + MaxFeeJuelsPerMsg *big.Int + LinkToken common.Address + StalenessThreshold uint32 +} + +type PriceRegistryTokenPriceFeedUpdate struct { + SourceToken common.Address + FeedConfig IPriceRegistryTokenPriceFeedConfig +} + +type PriceRegistryTokenTransferFeeConfig struct { + MinFeeUSDCents uint32 + MaxFeeUSDCents uint32 + DeciBps uint16 + DestGasOverhead uint32 + DestBytesOverhead uint32 + IsEnabled bool +} + +type PriceRegistryTokenTransferFeeConfigArgs struct { + DestChainSelector uint64 + TokenTransferFeeConfigs []PriceRegistryTokenTransferFeeConfigSingleTokenArgs +} + +type PriceRegistryTokenTransferFeeConfigRemoveArgs struct { + DestChainSelector uint64 + Token common.Address +} + +type PriceRegistryTokenTransferFeeConfigSingleTokenArgs struct { + Token common.Address + TokenTransferFeeConfig PriceRegistryTokenTransferFeeConfig +} + +var PriceRegistryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"validatePoolReturnData\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b50604051620069373803806200693783398101604081905262000034916200180a565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a99565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b65565b5050505050505062001ac8565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001929565b60209081029190910101519050620002f560028262000e98565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001929565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000eb8565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001929565b6020026020010151600c62000eb860201b90919060201c565b1562000499578281815181106200045b576200045b62001929565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001929565b6020026020010151600c62000e9860201b90919060201c565b156200053b57818181518110620004fd57620004fd62001929565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001929565b6020908102919091018101518051818301516001600160a01b0380831660008181526006875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001929565b6020026020010151905060008383815181106200065f576200065f62001929565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061018081015163ffffffff16155b80620006ba57506102008101516001600160e01b031916630a04b54b60e21b14155b80620006d15750602081610160015163ffffffff16105b80620006f15750806060015163ffffffff1681610180015163ffffffff16115b156200071c5760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260086020526040812060010154600160a81b900460e01b6001600160e01b03191690036200079c57816001600160401b03167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516200078e91906200193f565b60405180910390a2620007e0565b816001600160401b03167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad9382604051620007d791906200193f565b60405180910390a25b8060086000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a8154816001600160401b0302191690836001600160401b031602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000abd5762000abd62001929565b6020026020010151600001519050600083838151811062000ae25762000ae262001929565b6020908102919091018101518101516001600160a01b03841660008181526007845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a9c565b60005b825181101562000dd257600083828151811062000b895762000b8962001929565b6020026020010151905060008160000151905060005b82602001515181101562000dc35760008360200151828151811062000bc85762000bc862001929565b602002602001015160200151905060008460200151838151811062000bf15762000bf162001929565b60200260200101516000015190506020826080015163ffffffff16101562000c4a5760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b03841660008181526009602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000db0908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000b9f565b50505080600101905062000b68565b5060005b81518110156200054457600082828151811062000df75762000df762001929565b6020026020010151600001519050600083838151811062000e1c5762000e1c62001929565b6020908102919091018101518101516001600160401b03841660008181526009845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000dd6565b600062000eaf836001600160a01b03841662000ecf565b90505b92915050565b600062000eaf836001600160a01b03841662000fd3565b6000818152600183016020526040812054801562000fc857600062000ef660018362001a90565b855490915060009062000f0c9060019062001a90565b905081811462000f7857600086600001828154811062000f305762000f3062001929565b906000526020600020015490508087600001848154811062000f565762000f5662001929565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f8c5762000f8c62001ab2565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000eb2565b600091505062000eb2565b60008181526001830160205260408120546200101c5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000eb2565b50600062000eb2565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171562001060576200106062001025565b60405290565b60405160c081016001600160401b038111828210171562001060576200106062001025565b60405161022081016001600160401b038111828210171562001060576200106062001025565b604051601f8201601f191681016001600160401b0381118282101715620010dc57620010dc62001025565b604052919050565b80516001600160a01b0381168114620010fc57600080fd5b919050565b805163ffffffff81168114620010fc57600080fd5b6000606082840312156200112957600080fd5b604051606081016001600160401b03811182821017156200114e576200114e62001025565b604052825190915081906001600160601b03811681146200116e57600080fd5b81526200117e60208401620010e4565b6020820152620011916040840162001101565b60408201525092915050565b60006001600160401b03821115620011b957620011b962001025565b5060051b60200190565b600082601f830112620011d557600080fd5b81516020620011ee620011e8836200119d565b620010b1565b8083825260208201915060208460051b8701019350868411156200121157600080fd5b602086015b8481101562001238576200122a81620010e4565b835291830191830162001216565b509695505050505050565b600082601f8301126200125557600080fd5b8151602062001268620011e8836200119d565b828152606092830285018201928282019190878511156200128857600080fd5b8387015b858110156200131b5780890382811215620012a75760008081fd5b620012b16200103b565b620012bc83620010e4565b8152604080601f1984011215620012d35760008081fd5b620012dd6200103b565b9250620012ec888501620010e4565b835283015160ff81168114620013025760008081fd5b828801528087019190915284529284019281016200128c565b5090979650505050505050565b80516001600160401b0381168114620010fc57600080fd5b805161ffff81168114620010fc57600080fd5b80518015158114620010fc57600080fd5b600082601f8301126200137657600080fd5b8151602062001389620011e8836200119d565b82815260059290921b84018101918181019086841115620013a957600080fd5b8286015b84811015620012385780516001600160401b0380821115620013ce57600080fd5b908801906040601f19838c038101821315620013e957600080fd5b620013f36200103b565b6200140089860162001328565b815282850151848111156200141457600080fd5b8086019550508c603f8601126200142a57600080fd5b8885015193506200143f620011e8856200119d565b84815260e09094028501830193898101908e8611156200145e57600080fd5b958401955b858710156200153757868f0360e08112156200147e57600080fd5b620014886200103b565b6200149389620010e4565b815260c08683011215620014a657600080fd5b620014b062001066565b9150620014bf8d8a0162001101565b8252620014ce878a0162001101565b8d830152620014e060608a0162001340565b87830152620014f260808a0162001101565b60608301526200150560a08a0162001101565b60808301526200151860c08a0162001353565b60a0830152808d0191909152825260e09690960195908a019062001463565b828b015250875250505092840192508301620013ad565b600082601f8301126200156057600080fd5b8151602062001573620011e8836200119d565b82815260069290921b840181019181810190868411156200159357600080fd5b8286015b84811015620012385760408189031215620015b25760008081fd5b620015bc6200103b565b620015c782620010e4565b8152620015d685830162001328565b8186015283529183019160400162001597565b80516001600160e01b031981168114620010fc57600080fd5b600082601f8301126200161457600080fd5b8151602062001627620011e8836200119d565b82815261024092830285018201928282019190878511156200164857600080fd5b8387015b858110156200131b5780890382811215620016675760008081fd5b620016716200103b565b6200167c8362001328565b815261022080601f1984011215620016945760008081fd5b6200169e6200108b565b9250620016ad88850162001353565b83526040620016be81860162001340565b898501526060620016d181870162001101565b8286015260809150620016e682870162001101565b9085015260a0620016f986820162001101565b8286015260c091506200170e82870162001340565b9085015260e06200172186820162001101565b8286015261010091506200173782870162001340565b908501526101206200174b86820162001340565b8286015261014091506200176182870162001340565b908501526101606200177586820162001101565b8286015261018091506200178b82870162001101565b908501526101a06200179f86820162001101565b828601526101c09150620017b582870162001328565b908501526101e0620017c986820162001101565b828601526102009150620017df82870162001353565b90850152620017f0858301620015e9565b90840152508087019190915284529284019281016200164c565b6000806000806000806000610120888a0312156200182757600080fd5b62001833898962001116565b60608901519097506001600160401b03808211156200185157600080fd5b6200185f8b838c01620011c3565b975060808a01519150808211156200187657600080fd5b620018848b838c01620011c3565b965060a08a01519150808211156200189b57600080fd5b620018a98b838c0162001243565b955060c08a0151915080821115620018c057600080fd5b620018ce8b838c0162001364565b945060e08a0151915080821115620018e557600080fd5b620018f38b838c016200154e565b93506101008a01519150808211156200190b57600080fd5b506200191a8a828b0162001602565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b8151151581526102208101602083015162001960602084018261ffff169052565b50604083015162001979604084018263ffffffff169052565b50606083015162001992606084018263ffffffff169052565b506080830151620019ab608084018263ffffffff169052565b5060a0830151620019c260a084018261ffff169052565b5060c0830151620019db60c084018263ffffffff169052565b5060e0830151620019f260e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a0808501516001600160401b0316908401526101c080850151909116908301526101e080840151151590830152610200928301516001600160e01b031916929091019190915290565b8181038181111562000eb257634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051614e1562001b22600039600081816102d901528181611ad30152611b3c01526000818161029d0152818161104e01526110ae015260008181610269015281816110d701526111470152614e156000f3fe608060405234801561001057600080fd5b50600436106101b85760003560e01c80637afac322116100f9578063cc88924c11610097578063d8694ccd11610071578063d8694ccd14610a5c578063f2fde38b14610a6f578063f700042a14610a82578063ffdb4b3714610a9557600080fd5b8063cc88924c14610a2e578063cdc73d5114610a41578063d02641a014610a4957600080fd5b806391a2749a116100d357806391a2749a14610939578063a69c64c01461094c578063bf78e03f1461095f578063c4276bfc14610a0c57600080fd5b80637afac3221461078e57806382b49eb0146107a15780638da5cb5b1461091157600080fd5b8063407e108611610166578063514e8cff11610140578063514e8cff146104385780636def4ce7146104db578063770e2dc41461077357806379ba50971461078657600080fd5b8063407e1086146103c557806345ac924d146103d85780634ab35b0b146103f857600080fd5b8063181f5a7711610197578063181f5a77146103525780632451a6271461039b5780633937306f146103b057600080fd5b806241e5be146101bd578063061877e3146101e357806306285c691461023c575b600080fd5b6101d06101cb366004613802565b610add565b6040519081526020015b60405180910390f35b6102236101f136600461383e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101da565b610306604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101da565b61038e6040518060400160405280601781526020017f5072696365526567697374727920312e362e302d64657600000000000000000081525081565b6040516101da91906138bd565b6103a3610b4b565b6040516101da91906138d0565b6103c36103be36600461392a565b610b5c565b005b6103c36103d3366004613a86565b610e11565b6103eb6103e6366004613be4565b610e25565b6040516101da9190613c26565b61040b61040636600461383e565b610ef0565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6104ce610446366004613cb9565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600460209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101da9190613cd4565b6107666104e9366004613cb9565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081018290526102008101919091525067ffffffffffffffff908116600090815260086020908152604091829020825161022081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a0850152710100000000000000000000000000000000008304871660c08501527501000000000000000000000000000000000000000000808404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b010000000000000000000000000000000000000000000000000000009092048616610140840152600190930154808616610160840152640100000000810486166101808401526801000000000000000081049096166101a083015270010000000000000000000000000000000086049094166101c082015274010000000000000000000000000000000000000000850490911615156101e08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b1661020082015290565b6040516101da9190613d0f565b6103c3610781366004613f4c565b610efb565b6103c3610f11565b6103c361079c366004614266565b611013565b6108b16107af3660046142ca565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff91909116600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101da9190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6103c36109473660046142f4565b611025565b6103c361095a366004614385565b611036565b6109d861096d36600461383e565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526006825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101da565b610a1f610a1a36600461444a565b611047565b6040516101da939291906144e5565b6103c3610a3c36600461450f565b611245565b6103a361141b565b6104ce610a5736600461383e565b611427565b6101d0610a6a3660046145aa565b611523565b6103c3610a7d36600461383e565b6119dd565b6103c3610a9036600461462f565b6119ee565b610aa8610aa336600461484f565b6119ff565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101da565b6000610ae882611b8a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b0f85611b8a565b610b37907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16856148a8565b610b4191906148bf565b90505b9392505050565b6060610b576002611c24565b905090565b610b64611c31565b6000610b7082806148fa565b9050905060005b81811015610cba576000610b8b84806148fa565b83818110610b9b57610b9b614962565b905060400201803603810190610bb191906149bd565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a92610ca99290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610b77565b506000610cca60208401846148fa565b9050905060005b81811015610e0b576000610ce860208601866148fa565b83818110610cf857610cf8614962565b905060400201803603810190610d0e91906149fa565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600490975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e92610dfa9290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610cd1565b50505050565b610e19611c76565b610e2281611cf7565b50565b60608160008167ffffffffffffffff811115610e4357610e43613965565b604051908082528060200260200182016040528015610e8857816020015b6040805180820190915260008082526020820152815260200190600190039081610e615790505b50905060005b82811015610ee557610ec0868683818110610eab57610eab614962565b9050602002016020810190610a57919061383e565b828281518110610ed257610ed2614962565b6020908102919091010152600101610e8e565b509150505b92915050565b6000610eea82611b8a565b610f03611c76565b610f0d8282611df5565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61101b611c76565b610f0d8282612201565b61102d611c76565b610e2281612348565b61103e611c76565b610e22816124d4565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036110a7578592506110d5565b6110d287877f0000000000000000000000000000000000000000000000000000000000000000610add565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611174576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610f8e565b67ffffffffffffffff8816600090815260086020526040812060010154640100000000900463ffffffff16906111ab8787846125be565b9050806020015193508484611232836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b67ffffffffffffffff85166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b905b8481101561141257600084848381811061129c5761129c614962565b6112b2926020604090920201908101915061383e565b905060008787848181106112c8576112c8614962565b90506020028101906112da9190614a1d565b6112e8906040810190614a5b565b91505060208111156113985767ffffffffffffffff8916600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115611398576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610f8e565b611408848989868181106113ae576113ae614962565b90506020028101906113c09190614a1d565b6113ce906020810190614a5b565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061276792505050565b5050600101611280565b50505050505050565b6060610b57600c611c24565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600660209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff16908201529061151a57505073ffffffffffffffffffffffffffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b44816127b9565b67ffffffffffffffff8083166000908152600860209081526040808320815161022081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a0860152710100000000000000000000000000000000008404871660c08601527501000000000000000000000000000000000000000000808504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b010000000000000000000000000000000000000000000000000000009093048616610140850152600190940154808616610160850152640100000000810486166101808501526801000000000000000081049098166101a084015270010000000000000000000000000000000088049094166101c083015274010000000000000000000000000000000000000000870490931615156101e08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b16610200840152909190611759576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b600061176860408501856148fa565b91506117c490508261177d6020870187614a5b565b90508361178a8880614a5b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129fc92505050565b60006007816117d9608088016060890161383e565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff169150806118286118226080890160608a0161383e565b896119ff565b909250905060008080861561186e57611862888c61184c60808e0160608f0161383e565b888e806040019061185d91906148fa565b612aa6565b9194509250905061188e565b6101c088015161188b9063ffffffff16662386f26fc100006148a8565b92505b61010088015160009061ffff16156118d2576118cf896dffffffffffffffffffffffffffff607088901c166118c660208f018f614a5b565b90508b86612d84565b90505b6101a089015160009067ffffffffffffffff166118fb6118f560808f018f614a5b565b8d612e33565b600001518563ffffffff168c60a0015161ffff168f806020019061191f9190614a5b565b61192a9291506148a8565b8d6080015163ffffffff1661193f9190614ac0565b6119499190614ac0565b6119539190614ac0565b61196d906dffffffffffffffffffffffffffff89166148a8565b61197791906148a8565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff871682826119ae67ffffffffffffffff8c16896148a8565b6119b89190614ac0565b6119c29190614ac0565b6119cc91906148bf565b9d9c50505050505050505050505050565b6119e5611c76565b610e2281612ef4565b6119f6611c76565b610e2281612fe9565b67ffffffffffffffff811660009081526004602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203611ab7576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b6000816020015163ffffffff1642611acf9190614ad3565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115611b70576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610f8e565b611b7986611b8a565b9151919350909150505b9250929050565b600080611b9683611427565b9050806020015163ffffffff1660001480611bce575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15611c1d576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610f8e565b5192915050565b60606000610b44836134d1565b611c3c60023361352d565b611c74576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610f8e565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314611c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610f8e565b60005b8151811015610f0d576000828281518110611d1757611d17614962565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526006875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a2505050806001019050611cfa565b60005b8251811015612118576000838281518110611e1557611e15614962565b6020026020010151905060008160000151905060005b82602001515181101561210a57600083602001518281518110611e5057611e50614962565b6020026020010151602001519050600084602001518381518110611e7657611e76614962565b60200260200101516000015190506020826080015163ffffffff161015611ef35760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610f8e565b67ffffffffffffffff8416600081815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906120f8908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101611e2b565b505050806001019050611df8565b5060005b81518110156121fc57600082828151811061213957612139614962565b6020026020010151600001519050600083838151811061215b5761215b614962565b60209081029190910181015181015167ffffffffffffffff8416600081815260098452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010161211c565b505050565b60005b82518110156122a45761223a83828151811061222257612222614962565b6020026020010151600c61355c90919063ffffffff16565b1561229c5782818151811061225157612251614962565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b600101612204565b5060005b81518110156121fc576122de8282815181106122c6576122c6614962565b6020026020010151600c61357e90919063ffffffff16565b15612340578181815181106122f5576122f5614962565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6001016122a8565b602081015160005b81518110156123e357600082828151811061236d5761236d614962565b6020026020010151905061238b81600261357e90919063ffffffff16565b156123da5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612350565b50815160005b8151811015610e0b57600082828151811061240657612406614962565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612476576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61248160028261355c565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016123e9565b60005b8151811015610f0d5760008282815181106124f4576124f4614962565b6020026020010151600001519050600083838151811061251657612516614962565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526007845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a250506001016124d7565b604080518082019091526000808252602082015260008390036125ff57506040805180820190915267ffffffffffffffff8216815260006020820152610b44565b600061260b8486614ae6565b9050600061261c8560048189614b2c565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f000000000000000000000000000000000000000000000000000000000016126b957808060200190518101906126b09190614b56565b92505050610b44565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601612735576040518060400160405280828060200190518101906127219190614b82565b815260006020909101529250610b44915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610f0d576121fc816135a0565b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612823573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128479190614bb5565b5050509150506000811215612888576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000819050600085602001518473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129039190614c05565b61290d9190614c22565b905060248160ff16111561294257612926602482614c3b565b61293190600a614d74565b61293b90836148bf565b9150612965565b61294d816024614c3b565b61295890600a614d74565b61296290836148a8565b91505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8211156129bb576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff42166020820152949350505050565b836040015163ffffffff16831115612a555760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610f8e565b836020015161ffff16821115612a97576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e0b84610200015182612767565b6000808083815b81811015612d76576000878783818110612ac957612ac9614962565b905060400201803603810190612adf9190614d83565b67ffffffffffffffff8c166000908152600960209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090612c05576101208d0151612bcc9061ffff16662386f26fc100006148a8565b612bd69088614ac0565b96508c610140015186612be99190614dbc565b95508c610160015185612bfc9190614dbc565b94505050612d6e565b604081015160009061ffff1615612cbe5760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614612c61578351612c5a90611b8a565b9050612c64565b508a5b620186a0836040015161ffff16612ca68660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661365390919063ffffffff16565b612cb091906148a8565b612cba91906148bf565b9150505b6060820151612ccd9088614dbc565b9650816080015186612cdf9190614dbc565b8251909650600090612cfe9063ffffffff16662386f26fc100006148a8565b905080821015612d1d57612d12818a614ac0565b985050505050612d6e565b6000836020015163ffffffff16662386f26fc10000612d3c91906148a8565b905080831115612d5c57612d50818b614ac0565b99505050505050612d6e565b612d66838b614ac0565b995050505050505b600101612aad565b505096509650969350505050565b60008063ffffffff8316612d9960e0866148a8565b612da5876101c0614ac0565b612daf9190614ac0565b612db99190614ac0565b905060008760c0015163ffffffff168860e0015161ffff1683612ddc91906148a8565b612de69190614ac0565b61010089015190915061ffff16612e0d6dffffffffffffffffffffffffffff8916836148a8565b612e1791906148a8565b612e2790655af3107a40006148a8565b98975050505050505050565b60408051808201909152600080825260208201526000612e5f858585610180015163ffffffff166125be565b9050826060015163ffffffff1681600001511115612ea9576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101e001518015612ebd57508060200151155b15610b41576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612f73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610f8e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b8151811015610f0d57600082828151811061300957613009614962565b60200260200101519050600083838151811061302757613027614962565b60200260200101516000015190506000826020015190508167ffffffffffffffff1660001480613060575061018081015163ffffffff16155b806130b257506102008101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130c85750602081610160015163ffffffff16105b806130e75750806060015163ffffffff1681610180015163ffffffff16115b1561312a576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610f8e565b67ffffffffffffffff82166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131d2578167ffffffffffffffff167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516131c59190613d0f565b60405180910390a2613215565b8167ffffffffffffffff167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad938260405161320c9190613d0f565b60405180910390a25b80600860008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612fec565b60608160000180548060200260200160405190810160405280929190818152602001828054801561352157602002820191906000526020600020905b81548152602001906001019080831161350d575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b44565b6000610b448373ffffffffffffffffffffffffffffffffffffffff8416613690565b6000610b448373ffffffffffffffffffffffffffffffffffffffff84166136df565b600081516020146135df57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e91906138bd565b6000828060200190518101906135f59190614b82565b905073ffffffffffffffffffffffffffffffffffffffff81118061361a575061040081105b15610eea57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e91906138bd565b6000670de0b6b3a7640000613686837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166148a8565b610b4491906148bf565b60008181526001830160205260408120546136d757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610eea565b506000610eea565b600081815260018301602052604081205480156137c8576000613703600183614ad3565b855490915060009061371790600190614ad3565b905081811461377c57600086600001828154811061373757613737614962565b906000526020600020015490508087600001848154811061375a5761375a614962565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061378d5761378d614dd9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610eea565b6000915050610eea565b5092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146137fd57600080fd5b919050565b60008060006060848603121561381757600080fd5b613820846137d9565b925060208401359150613835604085016137d9565b90509250925092565b60006020828403121561385057600080fd5b610b44826137d9565b6000815180845260005b8181101561387f57602081850181015186830182015201613863565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b446020830184613859565b6020808252825182820181905260009190848201906040850190845b8181101561391e57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016138ec565b50909695505050505050565b60006020828403121561393c57600080fd5b813567ffffffffffffffff81111561395357600080fd5b820160408185031215610b4457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156139b7576139b7613965565b60405290565b60405160c0810167ffffffffffffffff811182821017156139b7576139b7613965565b604051610220810167ffffffffffffffff811182821017156139b7576139b7613965565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613a4b57613a4b613965565b604052919050565b600067ffffffffffffffff821115613a6d57613a6d613965565b5060051b60200190565b60ff81168114610e2257600080fd5b60006020808385031215613a9957600080fd5b823567ffffffffffffffff811115613ab057600080fd5b8301601f81018513613ac157600080fd5b8035613ad4613acf82613a53565b613a04565b81815260609182028301840191848201919088841115613af357600080fd5b938501935b83851015613b935784890381811215613b115760008081fd5b613b19613994565b613b22876137d9565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084011215613b565760008081fd5b613b5e613994565b9250613b6b8989016137d9565b8352870135613b7981613a77565b828901528088019190915283529384019391850191613af8565b50979650505050505050565b60008083601f840112613bb157600080fd5b50813567ffffffffffffffff811115613bc957600080fd5b6020830191508360208260051b8501011115611b8357600080fd5b60008060208385031215613bf757600080fd5b823567ffffffffffffffff811115613c0e57600080fd5b613c1a85828601613b9f565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b82811015613c9457613c8484835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101613c43565b5091979650505050505050565b803567ffffffffffffffff811681146137fd57600080fd5b600060208284031215613ccb57600080fd5b610b4482613ca1565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff169082015260408101610eea565b81511515815261022081016020830151613d2f602084018261ffff169052565b506040830151613d47604084018263ffffffff169052565b506060830151613d5f606084018263ffffffff169052565b506080830151613d77608084018263ffffffff169052565b5060a0830151613d8d60a084018261ffff169052565b5060c0830151613da560c084018263ffffffff169052565b5060e0830151613dbb60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a08085015167ffffffffffffffff16908401526101c080850151909116908301526101e080840151151590830152610200808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff811681146137fd57600080fd5b803561ffff811681146137fd57600080fd5b8015158114610e2257600080fd5b80356137fd81613e9b565b600082601f830112613ec557600080fd5b81356020613ed5613acf83613a53565b82815260069290921b84018101918181019086841115613ef457600080fd5b8286015b84811015613f415760408189031215613f115760008081fd5b613f19613994565b613f2282613ca1565b8152613f2f8583016137d9565b81860152835291830191604001613ef8565b509695505050505050565b60008060408385031215613f5f57600080fd5b67ffffffffffffffff83351115613f7557600080fd5b83601f843585010112613f8757600080fd5b613f97613acf8435850135613a53565b8335840180358083526020808401939260059290921b90910101861015613fbd57600080fd5b602085358601015b85358601803560051b016020018110156141ca5767ffffffffffffffff81351115613fef57600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a0301121561402857600080fd5b614030613994565b61403c60208301613ca1565b815267ffffffffffffffff6040830135111561405757600080fd5b88603f60408401358401011261406c57600080fd5b614082613acf6020604085013585010135613a53565b6020604084810135850182810135808552928401939260e00201018b10156140a957600080fd5b6040808501358501015b6040858101358601602081013560e00201018110156141ab5760e0818d0312156140dc57600080fd5b6140e4613994565b6140ed826137d9565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f0301121561412157600080fd5b6141296139bd565b61413560208401613e75565b815261414360408401613e75565b602082015261415460608401613e89565b604082015261416560808401613e75565b606082015261417660a08401613e75565b608082015261418860c0840135613e9b565b60c083013560a0820152602082810191909152908452929092019160e0016140b3565b5080602084015250508085525050602083019250602081019050613fc5565b5092505067ffffffffffffffff602084013511156141e757600080fd5b6141f78460208501358501613eb4565b90509250929050565b600082601f83011261421157600080fd5b81356020614221613acf83613a53565b8083825260208201915060208460051b87010193508684111561424357600080fd5b602086015b84811015613f4157614259816137d9565b8352918301918301614248565b6000806040838503121561427957600080fd5b823567ffffffffffffffff8082111561429157600080fd5b61429d86838701614200565b935060208501359150808211156142b357600080fd5b506142c085828601614200565b9150509250929050565b600080604083850312156142dd57600080fd5b6142e683613ca1565b91506141f7602084016137d9565b60006020828403121561430657600080fd5b813567ffffffffffffffff8082111561431e57600080fd5b908301906040828603121561433257600080fd5b61433a613994565b82358281111561434957600080fd5b61435587828601614200565b82525060208301358281111561436a57600080fd5b61437687828601614200565b60208301525095945050505050565b6000602080838503121561439857600080fd5b823567ffffffffffffffff8111156143af57600080fd5b8301601f810185136143c057600080fd5b80356143ce613acf82613a53565b81815260069190911b820183019083810190878311156143ed57600080fd5b928401925b8284101561443f576040848903121561440b5760008081fd5b614413613994565b61441c856137d9565b8152614429868601613ca1565b81870152825260409390930192908401906143f2565b979650505050505050565b60008060008060006080868803121561446257600080fd5b61446b86613ca1565b9450614479602087016137d9565b935060408601359250606086013567ffffffffffffffff8082111561449d57600080fd5b818801915088601f8301126144b157600080fd5b8135818111156144c057600080fd5b8960208285010111156144d257600080fd5b9699959850939650602001949392505050565b83815282151560208201526060604082015260006145066060830184613859565b95945050505050565b60008060008060006060868803121561452757600080fd5b61453086613ca1565b9450602086013567ffffffffffffffff8082111561454d57600080fd5b61455989838a01613b9f565b9096509450604088013591508082111561457257600080fd5b818801915088601f83011261458657600080fd5b81358181111561459557600080fd5b8960208260061b85010111156144d257600080fd5b600080604083850312156145bd57600080fd5b6145c683613ca1565b9150602083013567ffffffffffffffff8111156145e257600080fd5b830160a081860312156145f457600080fd5b809150509250929050565b80357fffffffff00000000000000000000000000000000000000000000000000000000811681146137fd57600080fd5b6000602080838503121561464257600080fd5b823567ffffffffffffffff81111561465957600080fd5b8301601f8101851361466a57600080fd5b8035614678613acf82613a53565b818152610240918202830184019184820191908884111561469857600080fd5b938501935b83851015613b9357848903818112156146b65760008081fd5b6146be613994565b6146c787613ca1565b8152610220807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156146fc5760008081fd5b6147046139e0565b9250614711898901613ea9565b83526040614720818a01613e89565b8a8501526060614731818b01613e75565b8286015260809150614744828b01613e75565b9085015260a06147558a8201613e75565b8286015260c09150614768828b01613e89565b9085015260e06147798a8201613e75565b82860152610100915061478d828b01613e89565b9085015261012061479f8a8201613e89565b8286015261014091506147b3828b01613e89565b908501526101606147c58a8201613e75565b8286015261018091506147d9828b01613e75565b908501526101a06147eb8a8201613e75565b828601526101c091506147ff828b01613ca1565b908501526101e06148118a8201613e75565b828601526102009150614825828b01613ea9565b908501526148348983016145ff565b9084015250808801919091528352938401939185019161469d565b6000806040838503121561486257600080fd5b61486b836137d9565b91506141f760208401613ca1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610eea57610eea614879565b6000826148f5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261492f57600080fd5b83018035915067ffffffffffffffff82111561494a57600080fd5b6020019150600681901b3603821315611b8357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146137fd57600080fd5b6000604082840312156149cf57600080fd5b6149d7613994565b6149e0836137d9565b81526149ee60208401614991565b60208201529392505050565b600060408284031215614a0c57600080fd5b614a14613994565b6149e083613ca1565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112614a5157600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614a9057600080fd5b83018035915067ffffffffffffffff821115614aab57600080fd5b602001915036819003821315611b8357600080fd5b80820180821115610eea57610eea614879565b81810381811115610eea57610eea614879565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015613e6d5760049490940360031b84901b1690921692915050565b60008085851115614b3c57600080fd5b83861115614b4957600080fd5b5050820193919092039150565b600060408284031215614b6857600080fd5b614b70613994565b8251815260208301516149ee81613e9b565b600060208284031215614b9457600080fd5b5051919050565b805169ffffffffffffffffffff811681146137fd57600080fd5b600080600080600060a08688031215614bcd57600080fd5b614bd686614b9b565b9450602086015193506040860151925060608601519150614bf960808701614b9b565b90509295509295909350565b600060208284031215614c1757600080fd5b8151610b4481613a77565b60ff8181168382160190811115610eea57610eea614879565b60ff8281168282160390811115610eea57610eea614879565b600181815b80851115614cad57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614c9357614c93614879565b80851615614ca057918102915b93841c9390800290614c59565b509250929050565b600082614cc457506001610eea565b81614cd157506000610eea565b8160018114614ce75760028114614cf157614d0d565b6001915050610eea565b60ff841115614d0257614d02614879565b50506001821b610eea565b5060208310610133831016604e8410600b8410161715614d30575081810a610eea565b614d3a8383614c54565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614d6c57614d6c614879565b029392505050565b6000610b4460ff841683614cb5565b600060408284031215614d9557600080fd5b614d9d613994565b614da6836137d9565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156137d2576137d2614879565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", +} + +var PriceRegistryABI = PriceRegistryMetaData.ABI + +var PriceRegistryBin = PriceRegistryMetaData.Bin + +func DeployPriceRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig PriceRegistryStaticConfig, priceUpdaters []common.Address, feeTokens []common.Address, tokenPriceFeeds []PriceRegistryTokenPriceFeedUpdate, tokenTransferFeeConfigArgs []PriceRegistryTokenTransferFeeConfigArgs, premiumMultiplierWeiPerEthArgs []PriceRegistryPremiumMultiplierWeiPerEthArgs, destChainConfigArgs []PriceRegistryDestChainConfigArgs) (common.Address, *types.Transaction, *PriceRegistry, error) { + parsed, err := PriceRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PriceRegistryBin), backend, staticConfig, priceUpdaters, feeTokens, tokenPriceFeeds, tokenTransferFeeConfigArgs, premiumMultiplierWeiPerEthArgs, destChainConfigArgs) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PriceRegistry{address: address, abi: *parsed, PriceRegistryCaller: PriceRegistryCaller{contract: contract}, PriceRegistryTransactor: PriceRegistryTransactor{contract: contract}, PriceRegistryFilterer: PriceRegistryFilterer{contract: contract}}, nil +} + +type PriceRegistry struct { + address common.Address + abi abi.ABI + PriceRegistryCaller + PriceRegistryTransactor + PriceRegistryFilterer +} + +type PriceRegistryCaller struct { + contract *bind.BoundContract +} + +type PriceRegistryTransactor struct { + contract *bind.BoundContract +} + +type PriceRegistryFilterer struct { + contract *bind.BoundContract +} + +type PriceRegistrySession struct { + Contract *PriceRegistry + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type PriceRegistryCallerSession struct { + Contract *PriceRegistryCaller + CallOpts bind.CallOpts +} + +type PriceRegistryTransactorSession struct { + Contract *PriceRegistryTransactor + TransactOpts bind.TransactOpts +} + +type PriceRegistryRaw struct { + Contract *PriceRegistry +} + +type PriceRegistryCallerRaw struct { + Contract *PriceRegistryCaller +} + +type PriceRegistryTransactorRaw struct { + Contract *PriceRegistryTransactor +} + +func NewPriceRegistry(address common.Address, backend bind.ContractBackend) (*PriceRegistry, error) { + abi, err := abi.JSON(strings.NewReader(PriceRegistryABI)) + if err != nil { + return nil, err + } + contract, err := bindPriceRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &PriceRegistry{address: address, abi: abi, PriceRegistryCaller: PriceRegistryCaller{contract: contract}, PriceRegistryTransactor: PriceRegistryTransactor{contract: contract}, PriceRegistryFilterer: PriceRegistryFilterer{contract: contract}}, nil +} + +func NewPriceRegistryCaller(address common.Address, caller bind.ContractCaller) (*PriceRegistryCaller, error) { + contract, err := bindPriceRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &PriceRegistryCaller{contract: contract}, nil +} + +func NewPriceRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*PriceRegistryTransactor, error) { + contract, err := bindPriceRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &PriceRegistryTransactor{contract: contract}, nil +} + +func NewPriceRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*PriceRegistryFilterer, error) { + contract, err := bindPriceRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PriceRegistryFilterer{contract: contract}, nil +} + +func bindPriceRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := PriceRegistryMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_PriceRegistry *PriceRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PriceRegistry.Contract.PriceRegistryCaller.contract.Call(opts, result, method, params...) +} + +func (_PriceRegistry *PriceRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PriceRegistry.Contract.PriceRegistryTransactor.contract.Transfer(opts) +} + +func (_PriceRegistry *PriceRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PriceRegistry.Contract.PriceRegistryTransactor.contract.Transact(opts, method, params...) +} + +func (_PriceRegistry *PriceRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PriceRegistry.Contract.contract.Call(opts, result, method, params...) +} + +func (_PriceRegistry *PriceRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PriceRegistry.Contract.contract.Transfer(opts) +} + +func (_PriceRegistry *PriceRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PriceRegistry.Contract.contract.Transact(opts, method, params...) +} + +func (_PriceRegistry *PriceRegistryCaller) ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "convertTokenAmount", fromToken, fromTokenAmount, toToken) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) ConvertTokenAmount(fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.ConvertTokenAmount(&_PriceRegistry.CallOpts, fromToken, fromTokenAmount, toToken) +} + +func (_PriceRegistry *PriceRegistryCallerSession) ConvertTokenAmount(fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.ConvertTokenAmount(&_PriceRegistry.CallOpts, fromToken, fromTokenAmount, toToken) +} + +func (_PriceRegistry *PriceRegistryCaller) GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getAllAuthorizedCallers") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetAllAuthorizedCallers() ([]common.Address, error) { + return _PriceRegistry.Contract.GetAllAuthorizedCallers(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetAllAuthorizedCallers() ([]common.Address, error) { + return _PriceRegistry.Contract.GetAllAuthorizedCallers(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (PriceRegistryDestChainConfig, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getDestChainConfig", destChainSelector) + + if err != nil { + return *new(PriceRegistryDestChainConfig), err + } + + out0 := *abi.ConvertType(out[0], new(PriceRegistryDestChainConfig)).(*PriceRegistryDestChainConfig) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetDestChainConfig(destChainSelector uint64) (PriceRegistryDestChainConfig, error) { + return _PriceRegistry.Contract.GetDestChainConfig(&_PriceRegistry.CallOpts, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetDestChainConfig(destChainSelector uint64) (PriceRegistryDestChainConfig, error) { + return _PriceRegistry.Contract.GetDestChainConfig(&_PriceRegistry.CallOpts, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCaller) GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (InternalTimestampedPackedUint224, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getDestinationChainGasPrice", destChainSelector) + + if err != nil { + return *new(InternalTimestampedPackedUint224), err + } + + out0 := *abi.ConvertType(out[0], new(InternalTimestampedPackedUint224)).(*InternalTimestampedPackedUint224) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetDestinationChainGasPrice(destChainSelector uint64) (InternalTimestampedPackedUint224, error) { + return _PriceRegistry.Contract.GetDestinationChainGasPrice(&_PriceRegistry.CallOpts, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetDestinationChainGasPrice(destChainSelector uint64) (InternalTimestampedPackedUint224, error) { + return _PriceRegistry.Contract.GetDestinationChainGasPrice(&_PriceRegistry.CallOpts, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCaller) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getFeeTokens") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetFeeTokens() ([]common.Address, error) { + return _PriceRegistry.Contract.GetFeeTokens(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetFeeTokens() ([]common.Address, error) { + return _PriceRegistry.Contract.GetFeeTokens(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) GetPremiumMultiplierWeiPerEth(opts *bind.CallOpts, token common.Address) (uint64, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getPremiumMultiplierWeiPerEth", token) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetPremiumMultiplierWeiPerEth(token common.Address) (uint64, error) { + return _PriceRegistry.Contract.GetPremiumMultiplierWeiPerEth(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetPremiumMultiplierWeiPerEth(token common.Address) (uint64, error) { + return _PriceRegistry.Contract.GetPremiumMultiplierWeiPerEth(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCaller) GetStaticConfig(opts *bind.CallOpts) (PriceRegistryStaticConfig, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(PriceRegistryStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(PriceRegistryStaticConfig)).(*PriceRegistryStaticConfig) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetStaticConfig() (PriceRegistryStaticConfig, error) { + return _PriceRegistry.Contract.GetStaticConfig(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetStaticConfig() (PriceRegistryStaticConfig, error) { + return _PriceRegistry.Contract.GetStaticConfig(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenAndGasPrices", token, destChainSelector) + + outstruct := new(GetTokenAndGasPrices) + if err != nil { + return *outstruct, err + } + + outstruct.TokenPrice = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.GasPriceValue = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenAndGasPrices(token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) { + return _PriceRegistry.Contract.GetTokenAndGasPrices(&_PriceRegistry.CallOpts, token, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenAndGasPrices(token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) { + return _PriceRegistry.Contract.GetTokenAndGasPrices(&_PriceRegistry.CallOpts, token, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenPrice(opts *bind.CallOpts, token common.Address) (InternalTimestampedPackedUint224, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenPrice", token) + + if err != nil { + return *new(InternalTimestampedPackedUint224), err + } + + out0 := *abi.ConvertType(out[0], new(InternalTimestampedPackedUint224)).(*InternalTimestampedPackedUint224) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenPrice(token common.Address) (InternalTimestampedPackedUint224, error) { + return _PriceRegistry.Contract.GetTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenPrice(token common.Address) (InternalTimestampedPackedUint224, error) { + return _PriceRegistry.Contract.GetTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenPriceFeedConfig(opts *bind.CallOpts, token common.Address) (IPriceRegistryTokenPriceFeedConfig, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenPriceFeedConfig", token) + + if err != nil { + return *new(IPriceRegistryTokenPriceFeedConfig), err + } + + out0 := *abi.ConvertType(out[0], new(IPriceRegistryTokenPriceFeedConfig)).(*IPriceRegistryTokenPriceFeedConfig) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenPriceFeedConfig(token common.Address) (IPriceRegistryTokenPriceFeedConfig, error) { + return _PriceRegistry.Contract.GetTokenPriceFeedConfig(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenPriceFeedConfig(token common.Address) (IPriceRegistryTokenPriceFeedConfig, error) { + return _PriceRegistry.Contract.GetTokenPriceFeedConfig(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]InternalTimestampedPackedUint224, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenPrices", tokens) + + if err != nil { + return *new([]InternalTimestampedPackedUint224), err + } + + out0 := *abi.ConvertType(out[0], new([]InternalTimestampedPackedUint224)).(*[]InternalTimestampedPackedUint224) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenPrices(tokens []common.Address) ([]InternalTimestampedPackedUint224, error) { + return _PriceRegistry.Contract.GetTokenPrices(&_PriceRegistry.CallOpts, tokens) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenPrices(tokens []common.Address) ([]InternalTimestampedPackedUint224, error) { + return _PriceRegistry.Contract.GetTokenPrices(&_PriceRegistry.CallOpts, tokens) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenTransferFeeConfig(opts *bind.CallOpts, destChainSelector uint64, token common.Address) (PriceRegistryTokenTransferFeeConfig, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenTransferFeeConfig", destChainSelector, token) + + if err != nil { + return *new(PriceRegistryTokenTransferFeeConfig), err + } + + out0 := *abi.ConvertType(out[0], new(PriceRegistryTokenTransferFeeConfig)).(*PriceRegistryTokenTransferFeeConfig) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenTransferFeeConfig(destChainSelector uint64, token common.Address) (PriceRegistryTokenTransferFeeConfig, error) { + return _PriceRegistry.Contract.GetTokenTransferFeeConfig(&_PriceRegistry.CallOpts, destChainSelector, token) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenTransferFeeConfig(destChainSelector uint64, token common.Address) (PriceRegistryTokenTransferFeeConfig, error) { + return _PriceRegistry.Contract.GetTokenTransferFeeConfig(&_PriceRegistry.CallOpts, destChainSelector, token) +} + +func (_PriceRegistry *PriceRegistryCaller) GetValidatedFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getValidatedFee", destChainSelector, message) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetValidatedFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _PriceRegistry.Contract.GetValidatedFee(&_PriceRegistry.CallOpts, destChainSelector, message) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetValidatedFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _PriceRegistry.Contract.GetValidatedFee(&_PriceRegistry.CallOpts, destChainSelector, message) +} + +func (_PriceRegistry *PriceRegistryCaller) GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getValidatedTokenPrice", token) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetValidatedTokenPrice(token common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.GetValidatedTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetValidatedTokenPrice(token common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.GetValidatedTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) Owner() (common.Address, error) { + return _PriceRegistry.Contract.Owner(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) Owner() (common.Address, error) { + return _PriceRegistry.Contract.Owner(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) ProcessMessageArgs(opts *bind.CallOpts, destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (ProcessMessageArgs, + + error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "processMessageArgs", destChainSelector, feeToken, feeTokenAmount, extraArgs) + + outstruct := new(ProcessMessageArgs) + if err != nil { + return *outstruct, err + } + + outstruct.MsgFeeJuels = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.IsOutOfOrderExecution = *abi.ConvertType(out[1], new(bool)).(*bool) + outstruct.ConvertedExtraArgs = *abi.ConvertType(out[2], new([]byte)).(*[]byte) + + return *outstruct, err + +} + +func (_PriceRegistry *PriceRegistrySession) ProcessMessageArgs(destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (ProcessMessageArgs, + + error) { + return _PriceRegistry.Contract.ProcessMessageArgs(&_PriceRegistry.CallOpts, destChainSelector, feeToken, feeTokenAmount, extraArgs) +} + +func (_PriceRegistry *PriceRegistryCallerSession) ProcessMessageArgs(destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (ProcessMessageArgs, + + error) { + return _PriceRegistry.Contract.ProcessMessageArgs(&_PriceRegistry.CallOpts, destChainSelector, feeToken, feeTokenAmount, extraArgs) +} + +func (_PriceRegistry *PriceRegistryCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) TypeAndVersion() (string, error) { + return _PriceRegistry.Contract.TypeAndVersion(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) TypeAndVersion() (string, error) { + return _PriceRegistry.Contract.TypeAndVersion(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) ValidatePoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) error { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "validatePoolReturnData", destChainSelector, rampTokenAmounts, sourceTokenAmounts) + + if err != nil { + return err + } + + return err + +} + +func (_PriceRegistry *PriceRegistrySession) ValidatePoolReturnData(destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) error { + return _PriceRegistry.Contract.ValidatePoolReturnData(&_PriceRegistry.CallOpts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) ValidatePoolReturnData(destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) error { + return _PriceRegistry.Contract.ValidatePoolReturnData(&_PriceRegistry.CallOpts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) +} + +func (_PriceRegistry *PriceRegistryTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "acceptOwnership") +} + +func (_PriceRegistry *PriceRegistrySession) AcceptOwnership() (*types.Transaction, error) { + return _PriceRegistry.Contract.AcceptOwnership(&_PriceRegistry.TransactOpts) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _PriceRegistry.Contract.AcceptOwnership(&_PriceRegistry.TransactOpts) +} + +func (_PriceRegistry *PriceRegistryTransactor) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "applyAuthorizedCallerUpdates", authorizedCallerArgs) +} + +func (_PriceRegistry *PriceRegistrySession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyAuthorizedCallerUpdates(&_PriceRegistry.TransactOpts, authorizedCallerArgs) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyAuthorizedCallerUpdates(&_PriceRegistry.TransactOpts, authorizedCallerArgs) +} + +func (_PriceRegistry *PriceRegistryTransactor) ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []PriceRegistryDestChainConfigArgs) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "applyDestChainConfigUpdates", destChainConfigArgs) +} + +func (_PriceRegistry *PriceRegistrySession) ApplyDestChainConfigUpdates(destChainConfigArgs []PriceRegistryDestChainConfigArgs) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyDestChainConfigUpdates(&_PriceRegistry.TransactOpts, destChainConfigArgs) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) ApplyDestChainConfigUpdates(destChainConfigArgs []PriceRegistryDestChainConfigArgs) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyDestChainConfigUpdates(&_PriceRegistry.TransactOpts, destChainConfigArgs) +} + +func (_PriceRegistry *PriceRegistryTransactor) ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "applyFeeTokensUpdates", feeTokensToAdd, feeTokensToRemove) +} + +func (_PriceRegistry *PriceRegistrySession) ApplyFeeTokensUpdates(feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyFeeTokensUpdates(&_PriceRegistry.TransactOpts, feeTokensToAdd, feeTokensToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) ApplyFeeTokensUpdates(feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyFeeTokensUpdates(&_PriceRegistry.TransactOpts, feeTokensToAdd, feeTokensToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactor) ApplyPremiumMultiplierWeiPerEthUpdates(opts *bind.TransactOpts, premiumMultiplierWeiPerEthArgs []PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "applyPremiumMultiplierWeiPerEthUpdates", premiumMultiplierWeiPerEthArgs) +} + +func (_PriceRegistry *PriceRegistrySession) ApplyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs []PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyPremiumMultiplierWeiPerEthUpdates(&_PriceRegistry.TransactOpts, premiumMultiplierWeiPerEthArgs) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) ApplyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs []PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyPremiumMultiplierWeiPerEthUpdates(&_PriceRegistry.TransactOpts, premiumMultiplierWeiPerEthArgs) +} + +func (_PriceRegistry *PriceRegistryTransactor) ApplyTokenTransferFeeConfigUpdates(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "applyTokenTransferFeeConfigUpdates", tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) +} + +func (_PriceRegistry *PriceRegistrySession) ApplyTokenTransferFeeConfigUpdates(tokenTransferFeeConfigArgs []PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyTokenTransferFeeConfigUpdates(&_PriceRegistry.TransactOpts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) ApplyTokenTransferFeeConfigUpdates(tokenTransferFeeConfigArgs []PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyTokenTransferFeeConfigUpdates(&_PriceRegistry.TransactOpts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) +} + +func (_PriceRegistry *PriceRegistryTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "transferOwnership", to) +} + +func (_PriceRegistry *PriceRegistrySession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.TransferOwnership(&_PriceRegistry.TransactOpts, to) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.TransferOwnership(&_PriceRegistry.TransactOpts, to) +} + +func (_PriceRegistry *PriceRegistryTransactor) UpdatePrices(opts *bind.TransactOpts, priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "updatePrices", priceUpdates) +} + +func (_PriceRegistry *PriceRegistrySession) UpdatePrices(priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _PriceRegistry.Contract.UpdatePrices(&_PriceRegistry.TransactOpts, priceUpdates) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) UpdatePrices(priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _PriceRegistry.Contract.UpdatePrices(&_PriceRegistry.TransactOpts, priceUpdates) +} + +func (_PriceRegistry *PriceRegistryTransactor) UpdateTokenPriceFeeds(opts *bind.TransactOpts, tokenPriceFeedUpdates []PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "updateTokenPriceFeeds", tokenPriceFeedUpdates) +} + +func (_PriceRegistry *PriceRegistrySession) UpdateTokenPriceFeeds(tokenPriceFeedUpdates []PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error) { + return _PriceRegistry.Contract.UpdateTokenPriceFeeds(&_PriceRegistry.TransactOpts, tokenPriceFeedUpdates) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) UpdateTokenPriceFeeds(tokenPriceFeedUpdates []PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error) { + return _PriceRegistry.Contract.UpdateTokenPriceFeeds(&_PriceRegistry.TransactOpts, tokenPriceFeedUpdates) +} + +type PriceRegistryAuthorizedCallerAddedIterator struct { + Event *PriceRegistryAuthorizedCallerAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryAuthorizedCallerAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryAuthorizedCallerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryAuthorizedCallerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryAuthorizedCallerAddedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryAuthorizedCallerAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryAuthorizedCallerAdded struct { + Caller common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*PriceRegistryAuthorizedCallerAddedIterator, error) { + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "AuthorizedCallerAdded") + if err != nil { + return nil, err + } + return &PriceRegistryAuthorizedCallerAddedIterator{contract: _PriceRegistry.contract, event: "AuthorizedCallerAdded", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryAuthorizedCallerAdded) (event.Subscription, error) { + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "AuthorizedCallerAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryAuthorizedCallerAdded) + if err := _PriceRegistry.contract.UnpackLog(event, "AuthorizedCallerAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseAuthorizedCallerAdded(log types.Log) (*PriceRegistryAuthorizedCallerAdded, error) { + event := new(PriceRegistryAuthorizedCallerAdded) + if err := _PriceRegistry.contract.UnpackLog(event, "AuthorizedCallerAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryAuthorizedCallerRemovedIterator struct { + Event *PriceRegistryAuthorizedCallerRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryAuthorizedCallerRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryAuthorizedCallerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryAuthorizedCallerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryAuthorizedCallerRemovedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryAuthorizedCallerRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryAuthorizedCallerRemoved struct { + Caller common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*PriceRegistryAuthorizedCallerRemovedIterator, error) { + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "AuthorizedCallerRemoved") + if err != nil { + return nil, err + } + return &PriceRegistryAuthorizedCallerRemovedIterator{contract: _PriceRegistry.contract, event: "AuthorizedCallerRemoved", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryAuthorizedCallerRemoved) (event.Subscription, error) { + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "AuthorizedCallerRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryAuthorizedCallerRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "AuthorizedCallerRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseAuthorizedCallerRemoved(log types.Log) (*PriceRegistryAuthorizedCallerRemoved, error) { + event := new(PriceRegistryAuthorizedCallerRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "AuthorizedCallerRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryDestChainAddedIterator struct { + Event *PriceRegistryDestChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryDestChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryDestChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryDestChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryDestChainAddedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryDestChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryDestChainAdded struct { + DestChainSelector uint64 + DestChainConfig PriceRegistryDestChainConfig + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterDestChainAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*PriceRegistryDestChainAddedIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "DestChainAdded", destChainSelectorRule) + if err != nil { + return nil, err + } + return &PriceRegistryDestChainAddedIterator{contract: _PriceRegistry.contract, event: "DestChainAdded", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchDestChainAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryDestChainAdded, destChainSelector []uint64) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "DestChainAdded", destChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryDestChainAdded) + if err := _PriceRegistry.contract.UnpackLog(event, "DestChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseDestChainAdded(log types.Log) (*PriceRegistryDestChainAdded, error) { + event := new(PriceRegistryDestChainAdded) + if err := _PriceRegistry.contract.UnpackLog(event, "DestChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryDestChainConfigUpdatedIterator struct { + Event *PriceRegistryDestChainConfigUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryDestChainConfigUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryDestChainConfigUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryDestChainConfigUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryDestChainConfigUpdatedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryDestChainConfigUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryDestChainConfigUpdated struct { + DestChainSelector uint64 + DestChainConfig PriceRegistryDestChainConfig + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterDestChainConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*PriceRegistryDestChainConfigUpdatedIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "DestChainConfigUpdated", destChainSelectorRule) + if err != nil { + return nil, err + } + return &PriceRegistryDestChainConfigUpdatedIterator{contract: _PriceRegistry.contract, event: "DestChainConfigUpdated", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchDestChainConfigUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryDestChainConfigUpdated, destChainSelector []uint64) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "DestChainConfigUpdated", destChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryDestChainConfigUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "DestChainConfigUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseDestChainConfigUpdated(log types.Log) (*PriceRegistryDestChainConfigUpdated, error) { + event := new(PriceRegistryDestChainConfigUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "DestChainConfigUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryFeeTokenAddedIterator struct { + Event *PriceRegistryFeeTokenAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryFeeTokenAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryFeeTokenAddedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryFeeTokenAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryFeeTokenAdded struct { + FeeToken common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenAddedIterator, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "FeeTokenAdded", feeTokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryFeeTokenAddedIterator{contract: _PriceRegistry.contract, event: "FeeTokenAdded", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "FeeTokenAdded", feeTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryFeeTokenAdded) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseFeeTokenAdded(log types.Log) (*PriceRegistryFeeTokenAdded, error) { + event := new(PriceRegistryFeeTokenAdded) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryFeeTokenRemovedIterator struct { + Event *PriceRegistryFeeTokenRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryFeeTokenRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryFeeTokenRemovedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryFeeTokenRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryFeeTokenRemoved struct { + FeeToken common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenRemovedIterator, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "FeeTokenRemoved", feeTokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryFeeTokenRemovedIterator{contract: _PriceRegistry.contract, event: "FeeTokenRemoved", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "FeeTokenRemoved", feeTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryFeeTokenRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseFeeTokenRemoved(log types.Log) (*PriceRegistryFeeTokenRemoved, error) { + event := new(PriceRegistryFeeTokenRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryOwnershipTransferRequestedIterator struct { + Event *PriceRegistryOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &PriceRegistryOwnershipTransferRequestedIterator{contract: _PriceRegistry.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryOwnershipTransferRequested) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseOwnershipTransferRequested(log types.Log) (*PriceRegistryOwnershipTransferRequested, error) { + event := new(PriceRegistryOwnershipTransferRequested) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryOwnershipTransferredIterator struct { + Event *PriceRegistryOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &PriceRegistryOwnershipTransferredIterator{contract: _PriceRegistry.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryOwnershipTransferred) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseOwnershipTransferred(log types.Log) (*PriceRegistryOwnershipTransferred, error) { + event := new(PriceRegistryOwnershipTransferred) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator struct { + Event *PriceRegistryPremiumMultiplierWeiPerEthUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPremiumMultiplierWeiPerEthUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPremiumMultiplierWeiPerEthUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryPremiumMultiplierWeiPerEthUpdated struct { + Token common.Address + PremiumMultiplierWeiPerEth uint64 + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterPremiumMultiplierWeiPerEthUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PremiumMultiplierWeiPerEthUpdated", tokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator{contract: _PriceRegistry.contract, event: "PremiumMultiplierWeiPerEthUpdated", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchPremiumMultiplierWeiPerEthUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryPremiumMultiplierWeiPerEthUpdated, token []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PremiumMultiplierWeiPerEthUpdated", tokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryPremiumMultiplierWeiPerEthUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "PremiumMultiplierWeiPerEthUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParsePremiumMultiplierWeiPerEthUpdated(log types.Log) (*PriceRegistryPremiumMultiplierWeiPerEthUpdated, error) { + event := new(PriceRegistryPremiumMultiplierWeiPerEthUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "PremiumMultiplierWeiPerEthUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryPriceFeedPerTokenUpdatedIterator struct { + Event *PriceRegistryPriceFeedPerTokenUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryPriceFeedPerTokenUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceFeedPerTokenUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceFeedPerTokenUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryPriceFeedPerTokenUpdatedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryPriceFeedPerTokenUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryPriceFeedPerTokenUpdated struct { + Token common.Address + PriceFeedConfig IPriceRegistryTokenPriceFeedConfig + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterPriceFeedPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryPriceFeedPerTokenUpdatedIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PriceFeedPerTokenUpdated", tokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryPriceFeedPerTokenUpdatedIterator{contract: _PriceRegistry.contract, event: "PriceFeedPerTokenUpdated", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchPriceFeedPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceFeedPerTokenUpdated, token []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PriceFeedPerTokenUpdated", tokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryPriceFeedPerTokenUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceFeedPerTokenUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParsePriceFeedPerTokenUpdated(log types.Log) (*PriceRegistryPriceFeedPerTokenUpdated, error) { + event := new(PriceRegistryPriceFeedPerTokenUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceFeedPerTokenUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryPriceUpdaterRemovedIterator struct { + Event *PriceRegistryPriceUpdaterRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryPriceUpdaterRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryPriceUpdaterRemovedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryPriceUpdaterRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryPriceUpdaterRemoved struct { + PriceUpdater common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterPriceUpdaterRemoved(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterRemovedIterator, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PriceUpdaterRemoved", priceUpdaterRule) + if err != nil { + return nil, err + } + return &PriceRegistryPriceUpdaterRemovedIterator{contract: _PriceRegistry.contract, event: "PriceUpdaterRemoved", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchPriceUpdaterRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address) (event.Subscription, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PriceUpdaterRemoved", priceUpdaterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryPriceUpdaterRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParsePriceUpdaterRemoved(log types.Log) (*PriceRegistryPriceUpdaterRemoved, error) { + event := new(PriceRegistryPriceUpdaterRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryPriceUpdaterSetIterator struct { + Event *PriceRegistryPriceUpdaterSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryPriceUpdaterSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryPriceUpdaterSetIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryPriceUpdaterSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryPriceUpdaterSet struct { + PriceUpdater common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterPriceUpdaterSet(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterSetIterator, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PriceUpdaterSet", priceUpdaterRule) + if err != nil { + return nil, err + } + return &PriceRegistryPriceUpdaterSetIterator{contract: _PriceRegistry.contract, event: "PriceUpdaterSet", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchPriceUpdaterSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterSet, priceUpdater []common.Address) (event.Subscription, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PriceUpdaterSet", priceUpdaterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryPriceUpdaterSet) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParsePriceUpdaterSet(log types.Log) (*PriceRegistryPriceUpdaterSet, error) { + event := new(PriceRegistryPriceUpdaterSet) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryTokenTransferFeeConfigDeletedIterator struct { + Event *PriceRegistryTokenTransferFeeConfigDeleted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryTokenTransferFeeConfigDeletedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryTokenTransferFeeConfigDeleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryTokenTransferFeeConfigDeleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryTokenTransferFeeConfigDeletedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryTokenTransferFeeConfigDeletedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryTokenTransferFeeConfigDeleted struct { + DestChainSelector uint64 + Token common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*PriceRegistryTokenTransferFeeConfigDeletedIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "TokenTransferFeeConfigDeleted", destChainSelectorRule, tokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryTokenTransferFeeConfigDeletedIterator{contract: _PriceRegistry.contract, event: "TokenTransferFeeConfigDeleted", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *PriceRegistryTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "TokenTransferFeeConfigDeleted", destChainSelectorRule, tokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryTokenTransferFeeConfigDeleted) + if err := _PriceRegistry.contract.UnpackLog(event, "TokenTransferFeeConfigDeleted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseTokenTransferFeeConfigDeleted(log types.Log) (*PriceRegistryTokenTransferFeeConfigDeleted, error) { + event := new(PriceRegistryTokenTransferFeeConfigDeleted) + if err := _PriceRegistry.contract.UnpackLog(event, "TokenTransferFeeConfigDeleted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryTokenTransferFeeConfigUpdatedIterator struct { + Event *PriceRegistryTokenTransferFeeConfigUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryTokenTransferFeeConfigUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryTokenTransferFeeConfigUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryTokenTransferFeeConfigUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryTokenTransferFeeConfigUpdatedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryTokenTransferFeeConfigUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryTokenTransferFeeConfigUpdated struct { + DestChainSelector uint64 + Token common.Address + TokenTransferFeeConfig PriceRegistryTokenTransferFeeConfig + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterTokenTransferFeeConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*PriceRegistryTokenTransferFeeConfigUpdatedIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "TokenTransferFeeConfigUpdated", destChainSelectorRule, tokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryTokenTransferFeeConfigUpdatedIterator{contract: _PriceRegistry.contract, event: "TokenTransferFeeConfigUpdated", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchTokenTransferFeeConfigUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryTokenTransferFeeConfigUpdated, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "TokenTransferFeeConfigUpdated", destChainSelectorRule, tokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryTokenTransferFeeConfigUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "TokenTransferFeeConfigUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseTokenTransferFeeConfigUpdated(log types.Log) (*PriceRegistryTokenTransferFeeConfigUpdated, error) { + event := new(PriceRegistryTokenTransferFeeConfigUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "TokenTransferFeeConfigUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryUsdPerTokenUpdatedIterator struct { + Event *PriceRegistryUsdPerTokenUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryUsdPerTokenUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerTokenUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerTokenUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryUsdPerTokenUpdatedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryUsdPerTokenUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryUsdPerTokenUpdated struct { + Token common.Address + Value *big.Int + Timestamp *big.Int + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryUsdPerTokenUpdatedIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "UsdPerTokenUpdated", tokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryUsdPerTokenUpdatedIterator{contract: _PriceRegistry.contract, event: "UsdPerTokenUpdated", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "UsdPerTokenUpdated", tokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryUsdPerTokenUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerTokenUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseUsdPerTokenUpdated(log types.Log) (*PriceRegistryUsdPerTokenUpdated, error) { + event := new(PriceRegistryUsdPerTokenUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerTokenUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryUsdPerUnitGasUpdatedIterator struct { + Event *PriceRegistryUsdPerUnitGasUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerUnitGasUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerUnitGasUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryUsdPerUnitGasUpdated struct { + DestChain uint64 + Value *big.Int + Timestamp *big.Int + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*PriceRegistryUsdPerUnitGasUpdatedIterator, error) { + + var destChainRule []interface{} + for _, destChainItem := range destChain { + destChainRule = append(destChainRule, destChainItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "UsdPerUnitGasUpdated", destChainRule) + if err != nil { + return nil, err + } + return &PriceRegistryUsdPerUnitGasUpdatedIterator{contract: _PriceRegistry.contract, event: "UsdPerUnitGasUpdated", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) { + + var destChainRule []interface{} + for _, destChainItem := range destChain { + destChainRule = append(destChainRule, destChainItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "UsdPerUnitGasUpdated", destChainRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryUsdPerUnitGasUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerUnitGasUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseUsdPerUnitGasUpdated(log types.Log) (*PriceRegistryUsdPerUnitGasUpdated, error) { + event := new(PriceRegistryUsdPerUnitGasUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerUnitGasUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetTokenAndGasPrices struct { + TokenPrice *big.Int + GasPriceValue *big.Int +} +type ProcessMessageArgs struct { + MsgFeeJuels *big.Int + IsOutOfOrderExecution bool + ConvertedExtraArgs []byte +} + +func (_PriceRegistry *PriceRegistry) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _PriceRegistry.abi.Events["AuthorizedCallerAdded"].ID: + return _PriceRegistry.ParseAuthorizedCallerAdded(log) + case _PriceRegistry.abi.Events["AuthorizedCallerRemoved"].ID: + return _PriceRegistry.ParseAuthorizedCallerRemoved(log) + case _PriceRegistry.abi.Events["DestChainAdded"].ID: + return _PriceRegistry.ParseDestChainAdded(log) + case _PriceRegistry.abi.Events["DestChainConfigUpdated"].ID: + return _PriceRegistry.ParseDestChainConfigUpdated(log) + case _PriceRegistry.abi.Events["FeeTokenAdded"].ID: + return _PriceRegistry.ParseFeeTokenAdded(log) + case _PriceRegistry.abi.Events["FeeTokenRemoved"].ID: + return _PriceRegistry.ParseFeeTokenRemoved(log) + case _PriceRegistry.abi.Events["OwnershipTransferRequested"].ID: + return _PriceRegistry.ParseOwnershipTransferRequested(log) + case _PriceRegistry.abi.Events["OwnershipTransferred"].ID: + return _PriceRegistry.ParseOwnershipTransferred(log) + case _PriceRegistry.abi.Events["PremiumMultiplierWeiPerEthUpdated"].ID: + return _PriceRegistry.ParsePremiumMultiplierWeiPerEthUpdated(log) + case _PriceRegistry.abi.Events["PriceFeedPerTokenUpdated"].ID: + return _PriceRegistry.ParsePriceFeedPerTokenUpdated(log) + case _PriceRegistry.abi.Events["PriceUpdaterRemoved"].ID: + return _PriceRegistry.ParsePriceUpdaterRemoved(log) + case _PriceRegistry.abi.Events["PriceUpdaterSet"].ID: + return _PriceRegistry.ParsePriceUpdaterSet(log) + case _PriceRegistry.abi.Events["TokenTransferFeeConfigDeleted"].ID: + return _PriceRegistry.ParseTokenTransferFeeConfigDeleted(log) + case _PriceRegistry.abi.Events["TokenTransferFeeConfigUpdated"].ID: + return _PriceRegistry.ParseTokenTransferFeeConfigUpdated(log) + case _PriceRegistry.abi.Events["UsdPerTokenUpdated"].ID: + return _PriceRegistry.ParseUsdPerTokenUpdated(log) + case _PriceRegistry.abi.Events["UsdPerUnitGasUpdated"].ID: + return _PriceRegistry.ParseUsdPerUnitGasUpdated(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (PriceRegistryAuthorizedCallerAdded) Topic() common.Hash { + return common.HexToHash("0xeb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef") +} + +func (PriceRegistryAuthorizedCallerRemoved) Topic() common.Hash { + return common.HexToHash("0xc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda77580") +} + +func (PriceRegistryDestChainAdded) Topic() common.Hash { + return common.HexToHash("0xa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577") +} + +func (PriceRegistryDestChainConfigUpdated) Topic() common.Hash { + return common.HexToHash("0xa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad93") +} + +func (PriceRegistryFeeTokenAdded) Topic() common.Hash { + return common.HexToHash("0xdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba23") +} + +func (PriceRegistryFeeTokenRemoved) Topic() common.Hash { + return common.HexToHash("0x1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f91") +} + +func (PriceRegistryOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (PriceRegistryOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (PriceRegistryPremiumMultiplierWeiPerEthUpdated) Topic() common.Hash { + return common.HexToHash("0xbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d") +} + +func (PriceRegistryPriceFeedPerTokenUpdated) Topic() common.Hash { + return common.HexToHash("0x08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464") +} + +func (PriceRegistryPriceUpdaterRemoved) Topic() common.Hash { + return common.HexToHash("0xff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c") +} + +func (PriceRegistryPriceUpdaterSet) Topic() common.Hash { + return common.HexToHash("0x34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b8") +} + +func (PriceRegistryTokenTransferFeeConfigDeleted) Topic() common.Hash { + return common.HexToHash("0x4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b") +} + +func (PriceRegistryTokenTransferFeeConfigUpdated) Topic() common.Hash { + return common.HexToHash("0x94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5") +} + +func (PriceRegistryUsdPerTokenUpdated) Topic() common.Hash { + return common.HexToHash("0x52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a") +} + +func (PriceRegistryUsdPerUnitGasUpdated) Topic() common.Hash { + return common.HexToHash("0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e") +} + +func (_PriceRegistry *PriceRegistry) Address() common.Address { + return _PriceRegistry.address +} + +type PriceRegistryInterface interface { + ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) + + GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) + + GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (PriceRegistryDestChainConfig, error) + + GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (InternalTimestampedPackedUint224, error) + + GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) + + GetPremiumMultiplierWeiPerEth(opts *bind.CallOpts, token common.Address) (uint64, error) + + GetStaticConfig(opts *bind.CallOpts) (PriceRegistryStaticConfig, error) + + GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) + + GetTokenPrice(opts *bind.CallOpts, token common.Address) (InternalTimestampedPackedUint224, error) + + GetTokenPriceFeedConfig(opts *bind.CallOpts, token common.Address) (IPriceRegistryTokenPriceFeedConfig, error) + + GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]InternalTimestampedPackedUint224, error) + + GetTokenTransferFeeConfig(opts *bind.CallOpts, destChainSelector uint64, token common.Address) (PriceRegistryTokenTransferFeeConfig, error) + + GetValidatedFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) + + GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + ProcessMessageArgs(opts *bind.CallOpts, destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (ProcessMessageArgs, + + error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + ValidatePoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) error + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) + + ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []PriceRegistryDestChainConfigArgs) (*types.Transaction, error) + + ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) + + ApplyPremiumMultiplierWeiPerEthUpdates(opts *bind.TransactOpts, premiumMultiplierWeiPerEthArgs []PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) + + ApplyTokenTransferFeeConfigUpdates(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdatePrices(opts *bind.TransactOpts, priceUpdates InternalPriceUpdates) (*types.Transaction, error) + + UpdateTokenPriceFeeds(opts *bind.TransactOpts, tokenPriceFeedUpdates []PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error) + + FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*PriceRegistryAuthorizedCallerAddedIterator, error) + + WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryAuthorizedCallerAdded) (event.Subscription, error) + + ParseAuthorizedCallerAdded(log types.Log) (*PriceRegistryAuthorizedCallerAdded, error) + + FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*PriceRegistryAuthorizedCallerRemovedIterator, error) + + WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryAuthorizedCallerRemoved) (event.Subscription, error) + + ParseAuthorizedCallerRemoved(log types.Log) (*PriceRegistryAuthorizedCallerRemoved, error) + + FilterDestChainAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*PriceRegistryDestChainAddedIterator, error) + + WatchDestChainAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryDestChainAdded, destChainSelector []uint64) (event.Subscription, error) + + ParseDestChainAdded(log types.Log) (*PriceRegistryDestChainAdded, error) + + FilterDestChainConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*PriceRegistryDestChainConfigUpdatedIterator, error) + + WatchDestChainConfigUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryDestChainConfigUpdated, destChainSelector []uint64) (event.Subscription, error) + + ParseDestChainConfigUpdated(log types.Log) (*PriceRegistryDestChainConfigUpdated, error) + + FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenAddedIterator, error) + + WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) + + ParseFeeTokenAdded(log types.Log) (*PriceRegistryFeeTokenAdded, error) + + FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenRemovedIterator, error) + + WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) + + ParseFeeTokenRemoved(log types.Log) (*PriceRegistryFeeTokenRemoved, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*PriceRegistryOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*PriceRegistryOwnershipTransferred, error) + + FilterPremiumMultiplierWeiPerEthUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator, error) + + WatchPremiumMultiplierWeiPerEthUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryPremiumMultiplierWeiPerEthUpdated, token []common.Address) (event.Subscription, error) + + ParsePremiumMultiplierWeiPerEthUpdated(log types.Log) (*PriceRegistryPremiumMultiplierWeiPerEthUpdated, error) + + FilterPriceFeedPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryPriceFeedPerTokenUpdatedIterator, error) + + WatchPriceFeedPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceFeedPerTokenUpdated, token []common.Address) (event.Subscription, error) + + ParsePriceFeedPerTokenUpdated(log types.Log) (*PriceRegistryPriceFeedPerTokenUpdated, error) + + FilterPriceUpdaterRemoved(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterRemovedIterator, error) + + WatchPriceUpdaterRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address) (event.Subscription, error) + + ParsePriceUpdaterRemoved(log types.Log) (*PriceRegistryPriceUpdaterRemoved, error) + + FilterPriceUpdaterSet(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterSetIterator, error) + + WatchPriceUpdaterSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterSet, priceUpdater []common.Address) (event.Subscription, error) + + ParsePriceUpdaterSet(log types.Log) (*PriceRegistryPriceUpdaterSet, error) + + FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*PriceRegistryTokenTransferFeeConfigDeletedIterator, error) + + WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *PriceRegistryTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) + + ParseTokenTransferFeeConfigDeleted(log types.Log) (*PriceRegistryTokenTransferFeeConfigDeleted, error) + + FilterTokenTransferFeeConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*PriceRegistryTokenTransferFeeConfigUpdatedIterator, error) + + WatchTokenTransferFeeConfigUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryTokenTransferFeeConfigUpdated, destChainSelector []uint64, token []common.Address) (event.Subscription, error) + + ParseTokenTransferFeeConfigUpdated(log types.Log) (*PriceRegistryTokenTransferFeeConfigUpdated, error) + + FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryUsdPerTokenUpdatedIterator, error) + + WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) + + ParseUsdPerTokenUpdated(log types.Log) (*PriceRegistryUsdPerTokenUpdated, error) + + FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*PriceRegistryUsdPerUnitGasUpdatedIterator, error) + + WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) + + ParseUsdPerUnitGasUpdated(log types.Log) (*PriceRegistryUsdPerUnitGasUpdated, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/price_registry_1_0_0/price_registry.go b/core/gethwrappers/ccip/generated/price_registry_1_0_0/price_registry.go new file mode 100644 index 0000000000..212d01aee4 --- /dev/null +++ b/core/gethwrappers/ccip/generated/price_registry_1_0_0/price_registry.go @@ -0,0 +1,1665 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package price_registry_1_0_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalTimestampedUint192Value struct { + Value *big.Int + Timestamp uint64 +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var PriceRegistryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStalenessThreshold\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpdaterOrOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleTokenPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToRemove\",\"type\":\"address[]\"}],\"name\":\"applyPriceUpdatersUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint192\",\"name\":\"value\",\"type\":\"uint192\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.TimestampedUint192Value\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceUpdaters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStalenessThreshold\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint192\",\"name\":\"tokenPrice\",\"type\":\"uint192\"},{\"internalType\":\"uint192\",\"name\":\"gasPriceValue\",\"type\":\"uint192\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint192\",\"name\":\"value\",\"type\":\"uint192\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.TimestampedUint192Value\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint192\",\"name\":\"value\",\"type\":\"uint192\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.TimestampedUint192Value[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint192\",\"name\":\"\",\"type\":\"uint192\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"usdPerToken\",\"type\":\"uint192\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint192\",\"name\":\"usdPerUnitGas\",\"type\":\"uint192\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200217d3803806200217d8339810160408190526200003491620006fe565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000133565b5050604080516000815260208101909152620000dd91508490620001de565b604080516000815260208101909152620000f99083906200033a565b8063ffffffff166000036200012157604051631151410960e11b815260040160405180910390fd5b63ffffffff1660805250620007fa9050565b336001600160a01b038216036200018d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b825181101562000289576200021d83828151811062000204576200020462000786565b602002602001015160046200049160201b90919060201c565b15620002765782818151811062000238576200023862000786565b60200260200101516001600160a01b03167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b6200028181620007b2565b9050620001e1565b5060005b81518110156200033557620002c9828281518110620002b057620002b062000786565b60200260200101516004620004b160201b90919060201c565b156200032257818181518110620002e457620002e462000786565b60200260200101516001600160a01b03167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b6200032d81620007b2565b90506200028d565b505050565b60005b8251811015620003e5576200037983828151811062000360576200036062000786565b602002602001015160066200049160201b90919060201c565b15620003d25782818151811062000394576200039462000786565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b620003dd81620007b2565b90506200033d565b5060005b81518110156200033557620004258282815181106200040c576200040c62000786565b60200260200101516006620004b160201b90919060201c565b156200047e5781818151811062000440576200044062000786565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6200048981620007b2565b9050620003e9565b6000620004a8836001600160a01b038416620004c8565b90505b92915050565b6000620004a8836001600160a01b0384166200051a565b60008181526001830160205260408120546200051157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004ab565b506000620004ab565b600081815260018301602052604081205480156200061357600062000541600183620007ce565b85549091506000906200055790600190620007ce565b9050818114620005c35760008660000182815481106200057b576200057b62000786565b9060005260206000200154905080876000018481548110620005a157620005a162000786565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620005d757620005d7620007e4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004ab565b6000915050620004ab565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200064c57600080fd5b919050565b600082601f8301126200066357600080fd5b815160206001600160401b03808311156200068257620006826200061e565b8260051b604051601f19603f83011681018181108482111715620006aa57620006aa6200061e565b604052938452858101830193838101925087851115620006c957600080fd5b83870191505b84821015620006f357620006e38262000634565b83529183019190830190620006cf565b979650505050505050565b6000806000606084860312156200071457600080fd5b83516001600160401b03808211156200072c57600080fd5b6200073a8783880162000651565b945060208601519150808211156200075157600080fd5b50620007608682870162000651565b925050604084015163ffffffff811681146200077b57600080fd5b809150509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620007c757620007c76200079c565b5060010190565b81810381811115620004ab57620004ab6200079c565b634e487b7160e01b600052603160045260246000fd5b60805161194b620008326000396000818161028501528181610a5201528181610abb01528181610c180152610c8d015261194b6000f3fe608060405234801561001057600080fd5b50600436106100f45760003560e01c8063866548c911610097578063cdc73d5111610066578063cdc73d51146102c4578063d02641a0146102cc578063f2fde38b1461036a578063ffdb4b371461037d57600080fd5b8063866548c9146102405780638da5cb5b14610253578063a6c94a731461027b578063bfcd4566146102af57600080fd5b8063514e8cff116100d3578063514e8cff1461017b57806352877af01461021057806379ba5097146102255780637afac3221461022d57600080fd5b806241e5be146100f957806345ac924d1461011f5780634ab35b0b1461013f575b600080fd5b61010c61010736600461133e565b6103c1565b6040519081526020015b60405180910390f35b61013261012d36600461137a565b610425565b60405161011691906113ef565b61015261014d36600461146a565b6104f9565b60405177ffffffffffffffffffffffffffffffffffffffffffffffff9091168152602001610116565b61020361018936600461149d565b6040805180820182526000808252602091820181905267ffffffffffffffff93841681526002825282902082518084019093525477ffffffffffffffffffffffffffffffffffffffffffffffff81168352780100000000000000000000000000000000000000000000000090049092169181019190915290565b60405161011691906114b8565b61022361021e3660046115e2565b610504565b005b61022361051a565b61022361023b3660046115e2565b61061c565b61022361024e366004611646565b61062e565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610116565b60405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610116565b6102b7610951565b6040516101169190611681565b6102b7610962565b6102036102da36600461146a565b60408051808201909152600080825260208201525073ffffffffffffffffffffffffffffffffffffffff1660009081526003602090815260409182902082518084019093525477ffffffffffffffffffffffffffffffffffffffffffffffff811683527801000000000000000000000000000000000000000000000000900467ffffffffffffffff169082015290565b61022361037836600461146a565b61096e565b61039061038b3660046116db565b610982565b6040805177ffffffffffffffffffffffffffffffffffffffffffffffff938416815292909116602083015201610116565b60006103cc82610b09565b77ffffffffffffffffffffffffffffffffffffffffffffffff166103ef85610b09565b6104139077ffffffffffffffffffffffffffffffffffffffffffffffff168561173d565b61041d9190611754565b949350505050565b60608160008167ffffffffffffffff811115610443576104436114f3565b60405190808252806020026020018201604052801561048857816020015b60408051808201909152600080825260208201528152602001906001900390816104615790505b50905060005b828110156104ee576104c08686838181106104ab576104ab61178f565b90506020020160208101906102da919061146a565b8282815181106104d2576104d261178f565b6020026020010181905250806104e7906117be565b905061048e565b509150505b92915050565b60006104f382610b09565b61050c610cc9565b6105168282610d4c565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610624610cc9565b6105168282610ea8565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061065e575061065c600433610fff565b155b15610695576040517f46f0815400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106a182806117f6565b9050905060005b818110156107eb5760006106bc84806117f6565b838181106106cc576106cc61178f565b9050604002018036038101906106e29190611886565b6040805180820182526020808401805177ffffffffffffffffffffffffffffffffffffffffffffffff908116845267ffffffffffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff908116600090815260039097529588902096519051909216780100000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926107d292909177ffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a2506107e4816117be565b90506106a8565b506107fc604083016020840161149d565b67ffffffffffffffff161561051657604051806040016040528083604001602081019061082991906118e1565b77ffffffffffffffffffffffffffffffffffffffffffffffff1681526020014267ffffffffffffffff168152506002600084602001602081019061086d919061149d565b67ffffffffffffffff9081168252602080830193909352604091820160002084519484015190911678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff909416939093179092556108e191840190840161149d565b67ffffffffffffffff167fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e61091c60608501604086016118e1565b6040805177ffffffffffffffffffffffffffffffffffffffffffffffff90921682524260208301520160405180910390a25050565b606061095d6004611031565b905090565b606061095d6006611031565b610976610cc9565b61097f8161103e565b50565b67ffffffffffffffff808216600090815260026020908152604080832081518083019092525477ffffffffffffffffffffffffffffffffffffffffffffffff8116825278010000000000000000000000000000000000000000000000009004909316908301819052909182918203610a32576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610597565b6000816020015167ffffffffffffffff1642610a4e91906118fc565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610aef576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610597565b610af886610b09565b9151919350909150505b9250929050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020908152604080832081518083019092525477ffffffffffffffffffffffffffffffffffffffffffffffff811682527801000000000000000000000000000000000000000000000000900467ffffffffffffffff16918101829052901580610ba95750805177ffffffffffffffffffffffffffffffffffffffffffffffff16155b15610bf8576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610597565b6000816020015167ffffffffffffffff1642610c1491906118fc565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610cc1576040517fc65fdfca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610597565b505192915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610597565b565b60005b8251811015610df757610d85838281518110610d6d57610d6d61178f565b6020026020010151600461113390919063ffffffff16565b15610de757828181518110610d9c57610d9c61178f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b610df0816117be565b9050610d4f565b5060005b8151811015610ea357610e31828281518110610e1957610e1961178f565b6020026020010151600461115590919063ffffffff16565b15610e9357818181518110610e4857610e4861178f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b610e9c816117be565b9050610dfb565b505050565b60005b8251811015610f5357610ee1838281518110610ec957610ec961178f565b6020026020010151600661113390919063ffffffff16565b15610f4357828181518110610ef857610ef861178f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b610f4c816117be565b9050610eab565b5060005b8151811015610ea357610f8d828281518110610f7557610f7561178f565b6020026020010151600661115590919063ffffffff16565b15610fef57818181518110610fa457610fa461178f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b610ff8816117be565b9050610f57565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b6060600061102a83611177565b3373ffffffffffffffffffffffffffffffffffffffff8216036110bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610597565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061102a8373ffffffffffffffffffffffffffffffffffffffff84166111d3565b600061102a8373ffffffffffffffffffffffffffffffffffffffff8416611222565b6060816000018054806020026020016040519081016040528092919081815260200182805480156111c757602002820191906000526020600020905b8154815260200190600101908083116111b3575b50505050509050919050565b600081815260018301602052604081205461121a575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104f3565b5060006104f3565b6000818152600183016020526040812054801561130b5760006112466001836118fc565b855490915060009061125a906001906118fc565b90508181146112bf57600086600001828154811061127a5761127a61178f565b906000526020600020015490508087600001848154811061129d5761129d61178f565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112d0576112d061190f565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104f3565b60009150506104f3565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133957600080fd5b919050565b60008060006060848603121561135357600080fd5b61135c84611315565b92506020840135915061137160408501611315565b90509250925092565b6000806020838503121561138d57600080fd5b823567ffffffffffffffff808211156113a557600080fd5b818501915085601f8301126113b957600080fd5b8135818111156113c857600080fd5b8660208260051b85010111156113dd57600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b8281101561145d5761144d848351805177ffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015167ffffffffffffffff16910152565b928401929085019060010161140c565b5091979650505050505050565b60006020828403121561147c57600080fd5b61102a82611315565b803567ffffffffffffffff8116811461133957600080fd5b6000602082840312156114af57600080fd5b61102a82611485565b815177ffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015167ffffffffffffffff1690820152604081016104f3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261153357600080fd5b8135602067ffffffffffffffff80831115611550576115506114f3565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611593576115936114f3565b6040529384528581018301938381019250878511156115b157600080fd5b83870191505b848210156115d7576115c882611315565b835291830191908301906115b7565b979650505050505050565b600080604083850312156115f557600080fd5b823567ffffffffffffffff8082111561160d57600080fd5b61161986838701611522565b9350602085013591508082111561162f57600080fd5b5061163c85828601611522565b9150509250929050565b60006020828403121561165857600080fd5b813567ffffffffffffffff81111561166f57600080fd5b82016060818503121561102a57600080fd5b6020808252825182820181905260009190848201906040850190845b818110156116cf57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161169d565b50909695505050505050565b600080604083850312156116ee57600080fd5b6116f783611315565b915061170560208401611485565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176104f3576104f361170e565b60008261178a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036117ef576117ef61170e565b5060010190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261182b57600080fd5b83018035915067ffffffffffffffff82111561184657600080fd5b6020019150600681901b3603821315610b0257600080fd5b803577ffffffffffffffffffffffffffffffffffffffffffffffff8116811461133957600080fd5b60006040828403121561189857600080fd5b6040516040810181811067ffffffffffffffff821117156118bb576118bb6114f3565b6040526118c783611315565b81526118d56020840161185e565b60208201529392505050565b6000602082840312156118f357600080fd5b61102a8261185e565b818103818111156104f3576104f361170e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", +} + +var PriceRegistryABI = PriceRegistryMetaData.ABI + +var PriceRegistryBin = PriceRegistryMetaData.Bin + +func DeployPriceRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, priceUpdaters []common.Address, feeTokens []common.Address, stalenessThreshold uint32) (common.Address, *types.Transaction, *PriceRegistry, error) { + parsed, err := PriceRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PriceRegistryBin), backend, priceUpdaters, feeTokens, stalenessThreshold) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PriceRegistry{PriceRegistryCaller: PriceRegistryCaller{contract: contract}, PriceRegistryTransactor: PriceRegistryTransactor{contract: contract}, PriceRegistryFilterer: PriceRegistryFilterer{contract: contract}}, nil +} + +type PriceRegistry struct { + address common.Address + abi abi.ABI + PriceRegistryCaller + PriceRegistryTransactor + PriceRegistryFilterer +} + +type PriceRegistryCaller struct { + contract *bind.BoundContract +} + +type PriceRegistryTransactor struct { + contract *bind.BoundContract +} + +type PriceRegistryFilterer struct { + contract *bind.BoundContract +} + +type PriceRegistrySession struct { + Contract *PriceRegistry + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type PriceRegistryCallerSession struct { + Contract *PriceRegistryCaller + CallOpts bind.CallOpts +} + +type PriceRegistryTransactorSession struct { + Contract *PriceRegistryTransactor + TransactOpts bind.TransactOpts +} + +type PriceRegistryRaw struct { + Contract *PriceRegistry +} + +type PriceRegistryCallerRaw struct { + Contract *PriceRegistryCaller +} + +type PriceRegistryTransactorRaw struct { + Contract *PriceRegistryTransactor +} + +func NewPriceRegistry(address common.Address, backend bind.ContractBackend) (*PriceRegistry, error) { + abi, err := abi.JSON(strings.NewReader(PriceRegistryABI)) + if err != nil { + return nil, err + } + contract, err := bindPriceRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &PriceRegistry{address: address, abi: abi, PriceRegistryCaller: PriceRegistryCaller{contract: contract}, PriceRegistryTransactor: PriceRegistryTransactor{contract: contract}, PriceRegistryFilterer: PriceRegistryFilterer{contract: contract}}, nil +} + +func NewPriceRegistryCaller(address common.Address, caller bind.ContractCaller) (*PriceRegistryCaller, error) { + contract, err := bindPriceRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &PriceRegistryCaller{contract: contract}, nil +} + +func NewPriceRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*PriceRegistryTransactor, error) { + contract, err := bindPriceRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &PriceRegistryTransactor{contract: contract}, nil +} + +func NewPriceRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*PriceRegistryFilterer, error) { + contract, err := bindPriceRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PriceRegistryFilterer{contract: contract}, nil +} + +func bindPriceRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := PriceRegistryMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_PriceRegistry *PriceRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PriceRegistry.Contract.PriceRegistryCaller.contract.Call(opts, result, method, params...) +} + +func (_PriceRegistry *PriceRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PriceRegistry.Contract.PriceRegistryTransactor.contract.Transfer(opts) +} + +func (_PriceRegistry *PriceRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PriceRegistry.Contract.PriceRegistryTransactor.contract.Transact(opts, method, params...) +} + +func (_PriceRegistry *PriceRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PriceRegistry.Contract.contract.Call(opts, result, method, params...) +} + +func (_PriceRegistry *PriceRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PriceRegistry.Contract.contract.Transfer(opts) +} + +func (_PriceRegistry *PriceRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PriceRegistry.Contract.contract.Transact(opts, method, params...) +} + +func (_PriceRegistry *PriceRegistryCaller) ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "convertTokenAmount", fromToken, fromTokenAmount, toToken) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) ConvertTokenAmount(fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.ConvertTokenAmount(&_PriceRegistry.CallOpts, fromToken, fromTokenAmount, toToken) +} + +func (_PriceRegistry *PriceRegistryCallerSession) ConvertTokenAmount(fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.ConvertTokenAmount(&_PriceRegistry.CallOpts, fromToken, fromTokenAmount, toToken) +} + +func (_PriceRegistry *PriceRegistryCaller) GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (InternalTimestampedUint192Value, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getDestinationChainGasPrice", destChainSelector) + + if err != nil { + return *new(InternalTimestampedUint192Value), err + } + + out0 := *abi.ConvertType(out[0], new(InternalTimestampedUint192Value)).(*InternalTimestampedUint192Value) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetDestinationChainGasPrice(destChainSelector uint64) (InternalTimestampedUint192Value, error) { + return _PriceRegistry.Contract.GetDestinationChainGasPrice(&_PriceRegistry.CallOpts, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetDestinationChainGasPrice(destChainSelector uint64) (InternalTimestampedUint192Value, error) { + return _PriceRegistry.Contract.GetDestinationChainGasPrice(&_PriceRegistry.CallOpts, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCaller) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getFeeTokens") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetFeeTokens() ([]common.Address, error) { + return _PriceRegistry.Contract.GetFeeTokens(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetFeeTokens() ([]common.Address, error) { + return _PriceRegistry.Contract.GetFeeTokens(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) GetPriceUpdaters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getPriceUpdaters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetPriceUpdaters() ([]common.Address, error) { + return _PriceRegistry.Contract.GetPriceUpdaters(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetPriceUpdaters() ([]common.Address, error) { + return _PriceRegistry.Contract.GetPriceUpdaters(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) GetStalenessThreshold(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getStalenessThreshold") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetStalenessThreshold() (*big.Int, error) { + return _PriceRegistry.Contract.GetStalenessThreshold(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetStalenessThreshold() (*big.Int, error) { + return _PriceRegistry.Contract.GetStalenessThreshold(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenAndGasPrices", token, destChainSelector) + + outstruct := new(GetTokenAndGasPrices) + if err != nil { + return *outstruct, err + } + + outstruct.TokenPrice = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.GasPriceValue = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenAndGasPrices(token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) { + return _PriceRegistry.Contract.GetTokenAndGasPrices(&_PriceRegistry.CallOpts, token, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenAndGasPrices(token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) { + return _PriceRegistry.Contract.GetTokenAndGasPrices(&_PriceRegistry.CallOpts, token, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenPrice(opts *bind.CallOpts, token common.Address) (InternalTimestampedUint192Value, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenPrice", token) + + if err != nil { + return *new(InternalTimestampedUint192Value), err + } + + out0 := *abi.ConvertType(out[0], new(InternalTimestampedUint192Value)).(*InternalTimestampedUint192Value) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenPrice(token common.Address) (InternalTimestampedUint192Value, error) { + return _PriceRegistry.Contract.GetTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenPrice(token common.Address) (InternalTimestampedUint192Value, error) { + return _PriceRegistry.Contract.GetTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]InternalTimestampedUint192Value, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenPrices", tokens) + + if err != nil { + return *new([]InternalTimestampedUint192Value), err + } + + out0 := *abi.ConvertType(out[0], new([]InternalTimestampedUint192Value)).(*[]InternalTimestampedUint192Value) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenPrices(tokens []common.Address) ([]InternalTimestampedUint192Value, error) { + return _PriceRegistry.Contract.GetTokenPrices(&_PriceRegistry.CallOpts, tokens) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenPrices(tokens []common.Address) ([]InternalTimestampedUint192Value, error) { + return _PriceRegistry.Contract.GetTokenPrices(&_PriceRegistry.CallOpts, tokens) +} + +func (_PriceRegistry *PriceRegistryCaller) GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getValidatedTokenPrice", token) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetValidatedTokenPrice(token common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.GetValidatedTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetValidatedTokenPrice(token common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.GetValidatedTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) Owner() (common.Address, error) { + return _PriceRegistry.Contract.Owner(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) Owner() (common.Address, error) { + return _PriceRegistry.Contract.Owner(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "acceptOwnership") +} + +func (_PriceRegistry *PriceRegistrySession) AcceptOwnership() (*types.Transaction, error) { + return _PriceRegistry.Contract.AcceptOwnership(&_PriceRegistry.TransactOpts) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _PriceRegistry.Contract.AcceptOwnership(&_PriceRegistry.TransactOpts) +} + +func (_PriceRegistry *PriceRegistryTransactor) ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "applyFeeTokensUpdates", feeTokensToAdd, feeTokensToRemove) +} + +func (_PriceRegistry *PriceRegistrySession) ApplyFeeTokensUpdates(feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyFeeTokensUpdates(&_PriceRegistry.TransactOpts, feeTokensToAdd, feeTokensToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) ApplyFeeTokensUpdates(feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyFeeTokensUpdates(&_PriceRegistry.TransactOpts, feeTokensToAdd, feeTokensToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactor) ApplyPriceUpdatersUpdates(opts *bind.TransactOpts, priceUpdatersToAdd []common.Address, priceUpdatersToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "applyPriceUpdatersUpdates", priceUpdatersToAdd, priceUpdatersToRemove) +} + +func (_PriceRegistry *PriceRegistrySession) ApplyPriceUpdatersUpdates(priceUpdatersToAdd []common.Address, priceUpdatersToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyPriceUpdatersUpdates(&_PriceRegistry.TransactOpts, priceUpdatersToAdd, priceUpdatersToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) ApplyPriceUpdatersUpdates(priceUpdatersToAdd []common.Address, priceUpdatersToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyPriceUpdatersUpdates(&_PriceRegistry.TransactOpts, priceUpdatersToAdd, priceUpdatersToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "transferOwnership", to) +} + +func (_PriceRegistry *PriceRegistrySession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.TransferOwnership(&_PriceRegistry.TransactOpts, to) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.TransferOwnership(&_PriceRegistry.TransactOpts, to) +} + +func (_PriceRegistry *PriceRegistryTransactor) UpdatePrices(opts *bind.TransactOpts, priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "updatePrices", priceUpdates) +} + +func (_PriceRegistry *PriceRegistrySession) UpdatePrices(priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _PriceRegistry.Contract.UpdatePrices(&_PriceRegistry.TransactOpts, priceUpdates) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) UpdatePrices(priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _PriceRegistry.Contract.UpdatePrices(&_PriceRegistry.TransactOpts, priceUpdates) +} + +type PriceRegistryFeeTokenAddedIterator struct { + Event *PriceRegistryFeeTokenAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryFeeTokenAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryFeeTokenAddedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryFeeTokenAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryFeeTokenAdded struct { + FeeToken common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenAddedIterator, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "FeeTokenAdded", feeTokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryFeeTokenAddedIterator{contract: _PriceRegistry.contract, event: "FeeTokenAdded", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "FeeTokenAdded", feeTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryFeeTokenAdded) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseFeeTokenAdded(log types.Log) (*PriceRegistryFeeTokenAdded, error) { + event := new(PriceRegistryFeeTokenAdded) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryFeeTokenRemovedIterator struct { + Event *PriceRegistryFeeTokenRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryFeeTokenRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryFeeTokenRemovedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryFeeTokenRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryFeeTokenRemoved struct { + FeeToken common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenRemovedIterator, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "FeeTokenRemoved", feeTokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryFeeTokenRemovedIterator{contract: _PriceRegistry.contract, event: "FeeTokenRemoved", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "FeeTokenRemoved", feeTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryFeeTokenRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseFeeTokenRemoved(log types.Log) (*PriceRegistryFeeTokenRemoved, error) { + event := new(PriceRegistryFeeTokenRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryOwnershipTransferRequestedIterator struct { + Event *PriceRegistryOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &PriceRegistryOwnershipTransferRequestedIterator{contract: _PriceRegistry.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryOwnershipTransferRequested) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseOwnershipTransferRequested(log types.Log) (*PriceRegistryOwnershipTransferRequested, error) { + event := new(PriceRegistryOwnershipTransferRequested) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryOwnershipTransferredIterator struct { + Event *PriceRegistryOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &PriceRegistryOwnershipTransferredIterator{contract: _PriceRegistry.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryOwnershipTransferred) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseOwnershipTransferred(log types.Log) (*PriceRegistryOwnershipTransferred, error) { + event := new(PriceRegistryOwnershipTransferred) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryPriceUpdaterRemovedIterator struct { + Event *PriceRegistryPriceUpdaterRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryPriceUpdaterRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryPriceUpdaterRemovedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryPriceUpdaterRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryPriceUpdaterRemoved struct { + PriceUpdater common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterPriceUpdaterRemoved(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterRemovedIterator, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PriceUpdaterRemoved", priceUpdaterRule) + if err != nil { + return nil, err + } + return &PriceRegistryPriceUpdaterRemovedIterator{contract: _PriceRegistry.contract, event: "PriceUpdaterRemoved", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchPriceUpdaterRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address) (event.Subscription, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PriceUpdaterRemoved", priceUpdaterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryPriceUpdaterRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParsePriceUpdaterRemoved(log types.Log) (*PriceRegistryPriceUpdaterRemoved, error) { + event := new(PriceRegistryPriceUpdaterRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryPriceUpdaterSetIterator struct { + Event *PriceRegistryPriceUpdaterSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryPriceUpdaterSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryPriceUpdaterSetIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryPriceUpdaterSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryPriceUpdaterSet struct { + PriceUpdater common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterPriceUpdaterSet(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterSetIterator, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PriceUpdaterSet", priceUpdaterRule) + if err != nil { + return nil, err + } + return &PriceRegistryPriceUpdaterSetIterator{contract: _PriceRegistry.contract, event: "PriceUpdaterSet", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchPriceUpdaterSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterSet, priceUpdater []common.Address) (event.Subscription, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PriceUpdaterSet", priceUpdaterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryPriceUpdaterSet) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParsePriceUpdaterSet(log types.Log) (*PriceRegistryPriceUpdaterSet, error) { + event := new(PriceRegistryPriceUpdaterSet) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryUsdPerTokenUpdatedIterator struct { + Event *PriceRegistryUsdPerTokenUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryUsdPerTokenUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerTokenUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerTokenUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryUsdPerTokenUpdatedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryUsdPerTokenUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryUsdPerTokenUpdated struct { + Token common.Address + Value *big.Int + Timestamp *big.Int + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryUsdPerTokenUpdatedIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "UsdPerTokenUpdated", tokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryUsdPerTokenUpdatedIterator{contract: _PriceRegistry.contract, event: "UsdPerTokenUpdated", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "UsdPerTokenUpdated", tokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryUsdPerTokenUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerTokenUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseUsdPerTokenUpdated(log types.Log) (*PriceRegistryUsdPerTokenUpdated, error) { + event := new(PriceRegistryUsdPerTokenUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerTokenUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryUsdPerUnitGasUpdatedIterator struct { + Event *PriceRegistryUsdPerUnitGasUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerUnitGasUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerUnitGasUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryUsdPerUnitGasUpdated struct { + DestChain uint64 + Value *big.Int + Timestamp *big.Int + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*PriceRegistryUsdPerUnitGasUpdatedIterator, error) { + + var destChainRule []interface{} + for _, destChainItem := range destChain { + destChainRule = append(destChainRule, destChainItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "UsdPerUnitGasUpdated", destChainRule) + if err != nil { + return nil, err + } + return &PriceRegistryUsdPerUnitGasUpdatedIterator{contract: _PriceRegistry.contract, event: "UsdPerUnitGasUpdated", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) { + + var destChainRule []interface{} + for _, destChainItem := range destChain { + destChainRule = append(destChainRule, destChainItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "UsdPerUnitGasUpdated", destChainRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryUsdPerUnitGasUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerUnitGasUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseUsdPerUnitGasUpdated(log types.Log) (*PriceRegistryUsdPerUnitGasUpdated, error) { + event := new(PriceRegistryUsdPerUnitGasUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerUnitGasUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetTokenAndGasPrices struct { + TokenPrice *big.Int + GasPriceValue *big.Int +} + +func (_PriceRegistry *PriceRegistry) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _PriceRegistry.abi.Events["FeeTokenAdded"].ID: + return _PriceRegistry.ParseFeeTokenAdded(log) + case _PriceRegistry.abi.Events["FeeTokenRemoved"].ID: + return _PriceRegistry.ParseFeeTokenRemoved(log) + case _PriceRegistry.abi.Events["OwnershipTransferRequested"].ID: + return _PriceRegistry.ParseOwnershipTransferRequested(log) + case _PriceRegistry.abi.Events["OwnershipTransferred"].ID: + return _PriceRegistry.ParseOwnershipTransferred(log) + case _PriceRegistry.abi.Events["PriceUpdaterRemoved"].ID: + return _PriceRegistry.ParsePriceUpdaterRemoved(log) + case _PriceRegistry.abi.Events["PriceUpdaterSet"].ID: + return _PriceRegistry.ParsePriceUpdaterSet(log) + case _PriceRegistry.abi.Events["UsdPerTokenUpdated"].ID: + return _PriceRegistry.ParseUsdPerTokenUpdated(log) + case _PriceRegistry.abi.Events["UsdPerUnitGasUpdated"].ID: + return _PriceRegistry.ParseUsdPerUnitGasUpdated(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (PriceRegistryFeeTokenAdded) Topic() common.Hash { + return common.HexToHash("0xdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba23") +} + +func (PriceRegistryFeeTokenRemoved) Topic() common.Hash { + return common.HexToHash("0x1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f91") +} + +func (PriceRegistryOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (PriceRegistryOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (PriceRegistryPriceUpdaterRemoved) Topic() common.Hash { + return common.HexToHash("0xff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c") +} + +func (PriceRegistryPriceUpdaterSet) Topic() common.Hash { + return common.HexToHash("0x34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b8") +} + +func (PriceRegistryUsdPerTokenUpdated) Topic() common.Hash { + return common.HexToHash("0x52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a") +} + +func (PriceRegistryUsdPerUnitGasUpdated) Topic() common.Hash { + return common.HexToHash("0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e") +} + +func (_PriceRegistry *PriceRegistry) Address() common.Address { + return _PriceRegistry.address +} + +type PriceRegistryInterface interface { + ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) + + GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (InternalTimestampedUint192Value, error) + + GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) + + GetPriceUpdaters(opts *bind.CallOpts) ([]common.Address, error) + + GetStalenessThreshold(opts *bind.CallOpts) (*big.Int, error) + + GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) + + GetTokenPrice(opts *bind.CallOpts, token common.Address) (InternalTimestampedUint192Value, error) + + GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]InternalTimestampedUint192Value, error) + + GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) + + ApplyPriceUpdatersUpdates(opts *bind.TransactOpts, priceUpdatersToAdd []common.Address, priceUpdatersToRemove []common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdatePrices(opts *bind.TransactOpts, priceUpdates InternalPriceUpdates) (*types.Transaction, error) + + FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenAddedIterator, error) + + WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) + + ParseFeeTokenAdded(log types.Log) (*PriceRegistryFeeTokenAdded, error) + + FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenRemovedIterator, error) + + WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) + + ParseFeeTokenRemoved(log types.Log) (*PriceRegistryFeeTokenRemoved, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*PriceRegistryOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*PriceRegistryOwnershipTransferred, error) + + FilterPriceUpdaterRemoved(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterRemovedIterator, error) + + WatchPriceUpdaterRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address) (event.Subscription, error) + + ParsePriceUpdaterRemoved(log types.Log) (*PriceRegistryPriceUpdaterRemoved, error) + + FilterPriceUpdaterSet(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterSetIterator, error) + + WatchPriceUpdaterSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterSet, priceUpdater []common.Address) (event.Subscription, error) + + ParsePriceUpdaterSet(log types.Log) (*PriceRegistryPriceUpdaterSet, error) + + FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryUsdPerTokenUpdatedIterator, error) + + WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) + + ParseUsdPerTokenUpdated(log types.Log) (*PriceRegistryUsdPerTokenUpdated, error) + + FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*PriceRegistryUsdPerUnitGasUpdatedIterator, error) + + WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) + + ParseUsdPerUnitGasUpdated(log types.Log) (*PriceRegistryUsdPerUnitGasUpdated, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/price_registry_1_2_0/price_registry.go b/core/gethwrappers/ccip/generated/price_registry_1_2_0/price_registry.go new file mode 100644 index 0000000000..64e16bd1dc --- /dev/null +++ b/core/gethwrappers/ccip/generated/price_registry_1_2_0/price_registry.go @@ -0,0 +1,1693 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package price_registry_1_2_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + +type InternalTimestampedPackedUint224 struct { + Value *big.Int + Timestamp uint32 +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var PriceRegistryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStalenessThreshold\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpdaterOrOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleTokenPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToRemove\",\"type\":\"address[]\"}],\"name\":\"applyPriceUpdatersUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceUpdaters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStalenessThreshold\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200227f3803806200227f8339810160408190526200003491620006fe565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000133565b5050604080516000815260208101909152620000dd91508490620001de565b604080516000815260208101909152620000f99083906200033a565b8063ffffffff166000036200012157604051631151410960e11b815260040160405180910390fd5b63ffffffff1660805250620007fa9050565b336001600160a01b038216036200018d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b825181101562000289576200021d83828151811062000204576200020462000786565b602002602001015160046200049160201b90919060201c565b15620002765782818151811062000238576200023862000786565b60200260200101516001600160a01b03167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b6200028181620007b2565b9050620001e1565b5060005b81518110156200033557620002c9828281518110620002b057620002b062000786565b60200260200101516004620004b160201b90919060201c565b156200032257818181518110620002e457620002e462000786565b60200260200101516001600160a01b03167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b6200032d81620007b2565b90506200028d565b505050565b60005b8251811015620003e5576200037983828151811062000360576200036062000786565b602002602001015160066200049160201b90919060201c565b15620003d25782818151811062000394576200039462000786565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b620003dd81620007b2565b90506200033d565b5060005b81518110156200033557620004258282815181106200040c576200040c62000786565b60200260200101516006620004b160201b90919060201c565b156200047e5781818151811062000440576200044062000786565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6200048981620007b2565b9050620003e9565b6000620004a8836001600160a01b038416620004c8565b90505b92915050565b6000620004a8836001600160a01b0384166200051a565b60008181526001830160205260408120546200051157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004ab565b506000620004ab565b600081815260018301602052604081205480156200061357600062000541600183620007ce565b85549091506000906200055790600190620007ce565b9050818114620005c35760008660000182815481106200057b576200057b62000786565b9060005260206000200154905080876000018481548110620005a157620005a162000786565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620005d757620005d7620007e4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004ab565b6000915050620004ab565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200064c57600080fd5b919050565b600082601f8301126200066357600080fd5b815160206001600160401b03808311156200068257620006826200061e565b8260051b604051601f19603f83011681018181108482111715620006aa57620006aa6200061e565b604052938452858101830193838101925087851115620006c957600080fd5b83870191505b84821015620006f357620006e38262000634565b83529183019190830190620006cf565b979650505050505050565b6000806000606084860312156200071457600080fd5b83516001600160401b03808211156200072c57600080fd5b6200073a8783880162000651565b945060208601519150808211156200075157600080fd5b50620007608682870162000651565b925050604084015163ffffffff811681146200077b57600080fd5b809150509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620007c757620007c76200079c565b5060010190565b81810381811115620004ab57620004ab6200079c565b634e487b7160e01b600052603160045260246000fd5b608051611a4d62000832600039600081816102eb01528181610acd01528181610b3601528181610c970152610d0c0152611a4d6000f3fe608060405234801561001057600080fd5b50600436106100ff5760003560e01c80637afac32211610097578063cdc73d5111610066578063cdc73d511461032a578063d02641a014610332578063f2fde38b146103d4578063ffdb4b37146103e757600080fd5b80637afac322146102a65780638da5cb5b146102b9578063a6c94a73146102e1578063bfcd45661461031557600080fd5b80634ab35b0b116100d35780634ab35b0b146101a8578063514e8cff146101e857806352877af01461028b57806379ba50971461029e57600080fd5b806241e5be14610104578063181f5a771461012a5780633937306f1461017357806345ac924d14610188575b600080fd5b6101176101123660046113bd565b61042f565b6040519081526020015b60405180910390f35b6101666040518060400160405280601381526020017f5072696365526567697374727920312e322e300000000000000000000000000081525081565b60405161012191906113f9565b610186610181366004611465565b61049b565b005b61019b6101963660046114a0565b6107bf565b6040516101219190611515565b6101bb6101b6366004611590565b610893565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b61027e6101f63660046115c3565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600260209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b60405161012191906115de565b610186610299366004611731565b61089e565b6101866108b4565b6101866102b4366004611731565b6109b6565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b60405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610121565b61031d6109c8565b6040516101219190611795565b61031d6109d9565b61027e610340366004611590565b60408051808201909152600080825260208201525073ffffffffffffffffffffffffffffffffffffffff166000908152600360209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6101866103e2366004611590565b6109e5565b6103fa6103f53660046117ef565b6109f9565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff938416815292909116602083015201610121565b600061043a82610b84565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661046185610b84565b610489907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685611851565b6104939190611868565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906104cb57506104c9600433610d48565b155b15610502576040517f46f0815400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061050e82806118a3565b9050905060005b8181101561066057600061052984806118a3565b838181106105395761053961190b565b90506040020180360381019061054f9190611966565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600390975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926106479290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250610659816119a3565b9050610515565b50600061067060208401846118a3565b9050905060005b818110156107b957600061068e60208601866118a3565b8381811061069e5761069e61190b565b9050604002018036038101906106b491906119db565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600290975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e926107a09290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a2506107b2816119a3565b9050610677565b50505050565b60608160008167ffffffffffffffff8111156107dd576107dd611619565b60405190808252806020026020018201604052801561082257816020015b60408051808201909152600080825260208201528152602001906001900390816107fb5790505b50905060005b828110156108885761085a8686838181106108455761084561190b565b90506020020160208101906103409190611590565b82828151811061086c5761086c61190b565b602002602001018190525080610881906119a3565b9050610828565b509150505b92915050565b600061088d82610b84565b6108a6610d7a565b6108b08282610dfd565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461093a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6109be610d7a565b6108b08282610f59565b60606109d460046110b0565b905090565b60606109d460066110b0565b6109ed610d7a565b6109f6816110bd565b50565b67ffffffffffffffff811660009081526002602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203610ab1576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610931565b6000816020015163ffffffff1642610ac991906119fe565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610b6a576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610931565b610b7386610b84565b9151919350909150505b9250929050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff16918101829052901580610c2c575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15610c7b576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610931565b6000816020015163ffffffff1642610c9391906119fe565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610d40576040517fc65fdfca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610931565b505192915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610dfb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610931565b565b60005b8251811015610ea857610e36838281518110610e1e57610e1e61190b565b602002602001015160046111b290919063ffffffff16565b15610e9857828181518110610e4d57610e4d61190b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b610ea1816119a3565b9050610e00565b5060005b8151811015610f5457610ee2828281518110610eca57610eca61190b565b602002602001015160046111d490919063ffffffff16565b15610f4457818181518110610ef957610ef961190b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b610f4d816119a3565b9050610eac565b505050565b60005b825181101561100457610f92838281518110610f7a57610f7a61190b565b602002602001015160066111b290919063ffffffff16565b15610ff457828181518110610fa957610fa961190b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b610ffd816119a3565b9050610f5c565b5060005b8151811015610f545761103e8282815181106110265761102661190b565b602002602001015160066111d490919063ffffffff16565b156110a0578181815181106110555761105561190b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6110a9816119a3565b9050611008565b60606000610d73836111f6565b3373ffffffffffffffffffffffffffffffffffffffff82160361113c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610931565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000610d738373ffffffffffffffffffffffffffffffffffffffff8416611252565b6000610d738373ffffffffffffffffffffffffffffffffffffffff84166112a1565b60608160000180548060200260200160405190810160405280929190818152602001828054801561124657602002820191906000526020600020905b815481526020019060010190808311611232575b50505050509050919050565b60008181526001830160205260408120546112995750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561088d565b50600061088d565b6000818152600183016020526040812054801561138a5760006112c56001836119fe565b85549091506000906112d9906001906119fe565b905081811461133e5760008660000182815481106112f9576112f961190b565b906000526020600020015490508087600001848154811061131c5761131c61190b565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061134f5761134f611a11565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061088d565b600091505061088d565b803573ffffffffffffffffffffffffffffffffffffffff811681146113b857600080fd5b919050565b6000806000606084860312156113d257600080fd5b6113db84611394565b9250602084013591506113f060408501611394565b90509250925092565b600060208083528351808285015260005b818110156114265785810183015185820160400152820161140a565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561147757600080fd5b813567ffffffffffffffff81111561148e57600080fd5b820160408185031215610d7357600080fd5b600080602083850312156114b357600080fd5b823567ffffffffffffffff808211156114cb57600080fd5b818501915085601f8301126114df57600080fd5b8135818111156114ee57600080fd5b8660208260051b850101111561150357600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b828110156115835761157384835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101611532565b5091979650505050505050565b6000602082840312156115a257600080fd5b610d7382611394565b803567ffffffffffffffff811681146113b857600080fd5b6000602082840312156115d557600080fd5b610d73826115ab565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff16908201526040810161088d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561166b5761166b611619565b60405290565b600082601f83011261168257600080fd5b8135602067ffffffffffffffff8083111561169f5761169f611619565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811084821117156116e2576116e2611619565b60405293845285810183019383810192508785111561170057600080fd5b83870191505b848210156117265761171782611394565b83529183019190830190611706565b979650505050505050565b6000806040838503121561174457600080fd5b823567ffffffffffffffff8082111561175c57600080fd5b61176886838701611671565b9350602085013591508082111561177e57600080fd5b5061178b85828601611671565b9150509250929050565b6020808252825182820181905260009190848201906040850190845b818110156117e357835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016117b1565b50909695505050505050565b6000806040838503121561180257600080fd5b61180b83611394565b9150611819602084016115ab565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761088d5761088d611822565b60008261189e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126118d857600080fd5b83018035915067ffffffffffffffff8211156118f357600080fd5b6020019150600681901b3603821315610b7d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146113b857600080fd5b60006040828403121561197857600080fd5b611980611648565b61198983611394565b81526119976020840161193a565b60208201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036119d4576119d4611822565b5060010190565b6000604082840312156119ed57600080fd5b6119f5611648565b611989836115ab565b8181038181111561088d5761088d611822565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", +} + +var PriceRegistryABI = PriceRegistryMetaData.ABI + +var PriceRegistryBin = PriceRegistryMetaData.Bin + +func DeployPriceRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, priceUpdaters []common.Address, feeTokens []common.Address, stalenessThreshold uint32) (common.Address, *types.Transaction, *PriceRegistry, error) { + parsed, err := PriceRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PriceRegistryBin), backend, priceUpdaters, feeTokens, stalenessThreshold) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PriceRegistry{address: address, abi: *parsed, PriceRegistryCaller: PriceRegistryCaller{contract: contract}, PriceRegistryTransactor: PriceRegistryTransactor{contract: contract}, PriceRegistryFilterer: PriceRegistryFilterer{contract: contract}}, nil +} + +type PriceRegistry struct { + address common.Address + abi abi.ABI + PriceRegistryCaller + PriceRegistryTransactor + PriceRegistryFilterer +} + +type PriceRegistryCaller struct { + contract *bind.BoundContract +} + +type PriceRegistryTransactor struct { + contract *bind.BoundContract +} + +type PriceRegistryFilterer struct { + contract *bind.BoundContract +} + +type PriceRegistrySession struct { + Contract *PriceRegistry + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type PriceRegistryCallerSession struct { + Contract *PriceRegistryCaller + CallOpts bind.CallOpts +} + +type PriceRegistryTransactorSession struct { + Contract *PriceRegistryTransactor + TransactOpts bind.TransactOpts +} + +type PriceRegistryRaw struct { + Contract *PriceRegistry +} + +type PriceRegistryCallerRaw struct { + Contract *PriceRegistryCaller +} + +type PriceRegistryTransactorRaw struct { + Contract *PriceRegistryTransactor +} + +func NewPriceRegistry(address common.Address, backend bind.ContractBackend) (*PriceRegistry, error) { + abi, err := abi.JSON(strings.NewReader(PriceRegistryABI)) + if err != nil { + return nil, err + } + contract, err := bindPriceRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &PriceRegistry{address: address, abi: abi, PriceRegistryCaller: PriceRegistryCaller{contract: contract}, PriceRegistryTransactor: PriceRegistryTransactor{contract: contract}, PriceRegistryFilterer: PriceRegistryFilterer{contract: contract}}, nil +} + +func NewPriceRegistryCaller(address common.Address, caller bind.ContractCaller) (*PriceRegistryCaller, error) { + contract, err := bindPriceRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &PriceRegistryCaller{contract: contract}, nil +} + +func NewPriceRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*PriceRegistryTransactor, error) { + contract, err := bindPriceRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &PriceRegistryTransactor{contract: contract}, nil +} + +func NewPriceRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*PriceRegistryFilterer, error) { + contract, err := bindPriceRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PriceRegistryFilterer{contract: contract}, nil +} + +func bindPriceRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := PriceRegistryMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_PriceRegistry *PriceRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PriceRegistry.Contract.PriceRegistryCaller.contract.Call(opts, result, method, params...) +} + +func (_PriceRegistry *PriceRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PriceRegistry.Contract.PriceRegistryTransactor.contract.Transfer(opts) +} + +func (_PriceRegistry *PriceRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PriceRegistry.Contract.PriceRegistryTransactor.contract.Transact(opts, method, params...) +} + +func (_PriceRegistry *PriceRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PriceRegistry.Contract.contract.Call(opts, result, method, params...) +} + +func (_PriceRegistry *PriceRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PriceRegistry.Contract.contract.Transfer(opts) +} + +func (_PriceRegistry *PriceRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PriceRegistry.Contract.contract.Transact(opts, method, params...) +} + +func (_PriceRegistry *PriceRegistryCaller) ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "convertTokenAmount", fromToken, fromTokenAmount, toToken) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) ConvertTokenAmount(fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.ConvertTokenAmount(&_PriceRegistry.CallOpts, fromToken, fromTokenAmount, toToken) +} + +func (_PriceRegistry *PriceRegistryCallerSession) ConvertTokenAmount(fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.ConvertTokenAmount(&_PriceRegistry.CallOpts, fromToken, fromTokenAmount, toToken) +} + +func (_PriceRegistry *PriceRegistryCaller) GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (InternalTimestampedPackedUint224, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getDestinationChainGasPrice", destChainSelector) + + if err != nil { + return *new(InternalTimestampedPackedUint224), err + } + + out0 := *abi.ConvertType(out[0], new(InternalTimestampedPackedUint224)).(*InternalTimestampedPackedUint224) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetDestinationChainGasPrice(destChainSelector uint64) (InternalTimestampedPackedUint224, error) { + return _PriceRegistry.Contract.GetDestinationChainGasPrice(&_PriceRegistry.CallOpts, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetDestinationChainGasPrice(destChainSelector uint64) (InternalTimestampedPackedUint224, error) { + return _PriceRegistry.Contract.GetDestinationChainGasPrice(&_PriceRegistry.CallOpts, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCaller) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getFeeTokens") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetFeeTokens() ([]common.Address, error) { + return _PriceRegistry.Contract.GetFeeTokens(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetFeeTokens() ([]common.Address, error) { + return _PriceRegistry.Contract.GetFeeTokens(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) GetPriceUpdaters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getPriceUpdaters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetPriceUpdaters() ([]common.Address, error) { + return _PriceRegistry.Contract.GetPriceUpdaters(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetPriceUpdaters() ([]common.Address, error) { + return _PriceRegistry.Contract.GetPriceUpdaters(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) GetStalenessThreshold(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getStalenessThreshold") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetStalenessThreshold() (*big.Int, error) { + return _PriceRegistry.Contract.GetStalenessThreshold(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetStalenessThreshold() (*big.Int, error) { + return _PriceRegistry.Contract.GetStalenessThreshold(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenAndGasPrices", token, destChainSelector) + + outstruct := new(GetTokenAndGasPrices) + if err != nil { + return *outstruct, err + } + + outstruct.TokenPrice = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.GasPriceValue = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenAndGasPrices(token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) { + return _PriceRegistry.Contract.GetTokenAndGasPrices(&_PriceRegistry.CallOpts, token, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenAndGasPrices(token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) { + return _PriceRegistry.Contract.GetTokenAndGasPrices(&_PriceRegistry.CallOpts, token, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenPrice(opts *bind.CallOpts, token common.Address) (InternalTimestampedPackedUint224, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenPrice", token) + + if err != nil { + return *new(InternalTimestampedPackedUint224), err + } + + out0 := *abi.ConvertType(out[0], new(InternalTimestampedPackedUint224)).(*InternalTimestampedPackedUint224) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenPrice(token common.Address) (InternalTimestampedPackedUint224, error) { + return _PriceRegistry.Contract.GetTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenPrice(token common.Address) (InternalTimestampedPackedUint224, error) { + return _PriceRegistry.Contract.GetTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]InternalTimestampedPackedUint224, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenPrices", tokens) + + if err != nil { + return *new([]InternalTimestampedPackedUint224), err + } + + out0 := *abi.ConvertType(out[0], new([]InternalTimestampedPackedUint224)).(*[]InternalTimestampedPackedUint224) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenPrices(tokens []common.Address) ([]InternalTimestampedPackedUint224, error) { + return _PriceRegistry.Contract.GetTokenPrices(&_PriceRegistry.CallOpts, tokens) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenPrices(tokens []common.Address) ([]InternalTimestampedPackedUint224, error) { + return _PriceRegistry.Contract.GetTokenPrices(&_PriceRegistry.CallOpts, tokens) +} + +func (_PriceRegistry *PriceRegistryCaller) GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getValidatedTokenPrice", token) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetValidatedTokenPrice(token common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.GetValidatedTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetValidatedTokenPrice(token common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.GetValidatedTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) Owner() (common.Address, error) { + return _PriceRegistry.Contract.Owner(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) Owner() (common.Address, error) { + return _PriceRegistry.Contract.Owner(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) TypeAndVersion() (string, error) { + return _PriceRegistry.Contract.TypeAndVersion(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) TypeAndVersion() (string, error) { + return _PriceRegistry.Contract.TypeAndVersion(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "acceptOwnership") +} + +func (_PriceRegistry *PriceRegistrySession) AcceptOwnership() (*types.Transaction, error) { + return _PriceRegistry.Contract.AcceptOwnership(&_PriceRegistry.TransactOpts) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _PriceRegistry.Contract.AcceptOwnership(&_PriceRegistry.TransactOpts) +} + +func (_PriceRegistry *PriceRegistryTransactor) ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "applyFeeTokensUpdates", feeTokensToAdd, feeTokensToRemove) +} + +func (_PriceRegistry *PriceRegistrySession) ApplyFeeTokensUpdates(feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyFeeTokensUpdates(&_PriceRegistry.TransactOpts, feeTokensToAdd, feeTokensToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) ApplyFeeTokensUpdates(feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyFeeTokensUpdates(&_PriceRegistry.TransactOpts, feeTokensToAdd, feeTokensToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactor) ApplyPriceUpdatersUpdates(opts *bind.TransactOpts, priceUpdatersToAdd []common.Address, priceUpdatersToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "applyPriceUpdatersUpdates", priceUpdatersToAdd, priceUpdatersToRemove) +} + +func (_PriceRegistry *PriceRegistrySession) ApplyPriceUpdatersUpdates(priceUpdatersToAdd []common.Address, priceUpdatersToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyPriceUpdatersUpdates(&_PriceRegistry.TransactOpts, priceUpdatersToAdd, priceUpdatersToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) ApplyPriceUpdatersUpdates(priceUpdatersToAdd []common.Address, priceUpdatersToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyPriceUpdatersUpdates(&_PriceRegistry.TransactOpts, priceUpdatersToAdd, priceUpdatersToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "transferOwnership", to) +} + +func (_PriceRegistry *PriceRegistrySession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.TransferOwnership(&_PriceRegistry.TransactOpts, to) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.TransferOwnership(&_PriceRegistry.TransactOpts, to) +} + +func (_PriceRegistry *PriceRegistryTransactor) UpdatePrices(opts *bind.TransactOpts, priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "updatePrices", priceUpdates) +} + +func (_PriceRegistry *PriceRegistrySession) UpdatePrices(priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _PriceRegistry.Contract.UpdatePrices(&_PriceRegistry.TransactOpts, priceUpdates) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) UpdatePrices(priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _PriceRegistry.Contract.UpdatePrices(&_PriceRegistry.TransactOpts, priceUpdates) +} + +type PriceRegistryFeeTokenAddedIterator struct { + Event *PriceRegistryFeeTokenAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryFeeTokenAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryFeeTokenAddedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryFeeTokenAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryFeeTokenAdded struct { + FeeToken common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenAddedIterator, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "FeeTokenAdded", feeTokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryFeeTokenAddedIterator{contract: _PriceRegistry.contract, event: "FeeTokenAdded", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "FeeTokenAdded", feeTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryFeeTokenAdded) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseFeeTokenAdded(log types.Log) (*PriceRegistryFeeTokenAdded, error) { + event := new(PriceRegistryFeeTokenAdded) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryFeeTokenRemovedIterator struct { + Event *PriceRegistryFeeTokenRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryFeeTokenRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryFeeTokenRemovedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryFeeTokenRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryFeeTokenRemoved struct { + FeeToken common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenRemovedIterator, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "FeeTokenRemoved", feeTokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryFeeTokenRemovedIterator{contract: _PriceRegistry.contract, event: "FeeTokenRemoved", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "FeeTokenRemoved", feeTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryFeeTokenRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseFeeTokenRemoved(log types.Log) (*PriceRegistryFeeTokenRemoved, error) { + event := new(PriceRegistryFeeTokenRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryOwnershipTransferRequestedIterator struct { + Event *PriceRegistryOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &PriceRegistryOwnershipTransferRequestedIterator{contract: _PriceRegistry.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryOwnershipTransferRequested) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseOwnershipTransferRequested(log types.Log) (*PriceRegistryOwnershipTransferRequested, error) { + event := new(PriceRegistryOwnershipTransferRequested) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryOwnershipTransferredIterator struct { + Event *PriceRegistryOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &PriceRegistryOwnershipTransferredIterator{contract: _PriceRegistry.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryOwnershipTransferred) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseOwnershipTransferred(log types.Log) (*PriceRegistryOwnershipTransferred, error) { + event := new(PriceRegistryOwnershipTransferred) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryPriceUpdaterRemovedIterator struct { + Event *PriceRegistryPriceUpdaterRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryPriceUpdaterRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryPriceUpdaterRemovedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryPriceUpdaterRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryPriceUpdaterRemoved struct { + PriceUpdater common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterPriceUpdaterRemoved(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterRemovedIterator, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PriceUpdaterRemoved", priceUpdaterRule) + if err != nil { + return nil, err + } + return &PriceRegistryPriceUpdaterRemovedIterator{contract: _PriceRegistry.contract, event: "PriceUpdaterRemoved", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchPriceUpdaterRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address) (event.Subscription, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PriceUpdaterRemoved", priceUpdaterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryPriceUpdaterRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParsePriceUpdaterRemoved(log types.Log) (*PriceRegistryPriceUpdaterRemoved, error) { + event := new(PriceRegistryPriceUpdaterRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryPriceUpdaterSetIterator struct { + Event *PriceRegistryPriceUpdaterSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryPriceUpdaterSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryPriceUpdaterSetIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryPriceUpdaterSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryPriceUpdaterSet struct { + PriceUpdater common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterPriceUpdaterSet(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterSetIterator, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PriceUpdaterSet", priceUpdaterRule) + if err != nil { + return nil, err + } + return &PriceRegistryPriceUpdaterSetIterator{contract: _PriceRegistry.contract, event: "PriceUpdaterSet", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchPriceUpdaterSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterSet, priceUpdater []common.Address) (event.Subscription, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PriceUpdaterSet", priceUpdaterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryPriceUpdaterSet) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParsePriceUpdaterSet(log types.Log) (*PriceRegistryPriceUpdaterSet, error) { + event := new(PriceRegistryPriceUpdaterSet) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryUsdPerTokenUpdatedIterator struct { + Event *PriceRegistryUsdPerTokenUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryUsdPerTokenUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerTokenUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerTokenUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryUsdPerTokenUpdatedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryUsdPerTokenUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryUsdPerTokenUpdated struct { + Token common.Address + Value *big.Int + Timestamp *big.Int + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryUsdPerTokenUpdatedIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "UsdPerTokenUpdated", tokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryUsdPerTokenUpdatedIterator{contract: _PriceRegistry.contract, event: "UsdPerTokenUpdated", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "UsdPerTokenUpdated", tokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryUsdPerTokenUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerTokenUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseUsdPerTokenUpdated(log types.Log) (*PriceRegistryUsdPerTokenUpdated, error) { + event := new(PriceRegistryUsdPerTokenUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerTokenUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryUsdPerUnitGasUpdatedIterator struct { + Event *PriceRegistryUsdPerUnitGasUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerUnitGasUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerUnitGasUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryUsdPerUnitGasUpdated struct { + DestChain uint64 + Value *big.Int + Timestamp *big.Int + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*PriceRegistryUsdPerUnitGasUpdatedIterator, error) { + + var destChainRule []interface{} + for _, destChainItem := range destChain { + destChainRule = append(destChainRule, destChainItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "UsdPerUnitGasUpdated", destChainRule) + if err != nil { + return nil, err + } + return &PriceRegistryUsdPerUnitGasUpdatedIterator{contract: _PriceRegistry.contract, event: "UsdPerUnitGasUpdated", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) { + + var destChainRule []interface{} + for _, destChainItem := range destChain { + destChainRule = append(destChainRule, destChainItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "UsdPerUnitGasUpdated", destChainRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryUsdPerUnitGasUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerUnitGasUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseUsdPerUnitGasUpdated(log types.Log) (*PriceRegistryUsdPerUnitGasUpdated, error) { + event := new(PriceRegistryUsdPerUnitGasUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerUnitGasUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetTokenAndGasPrices struct { + TokenPrice *big.Int + GasPriceValue *big.Int +} + +func (_PriceRegistry *PriceRegistry) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _PriceRegistry.abi.Events["FeeTokenAdded"].ID: + return _PriceRegistry.ParseFeeTokenAdded(log) + case _PriceRegistry.abi.Events["FeeTokenRemoved"].ID: + return _PriceRegistry.ParseFeeTokenRemoved(log) + case _PriceRegistry.abi.Events["OwnershipTransferRequested"].ID: + return _PriceRegistry.ParseOwnershipTransferRequested(log) + case _PriceRegistry.abi.Events["OwnershipTransferred"].ID: + return _PriceRegistry.ParseOwnershipTransferred(log) + case _PriceRegistry.abi.Events["PriceUpdaterRemoved"].ID: + return _PriceRegistry.ParsePriceUpdaterRemoved(log) + case _PriceRegistry.abi.Events["PriceUpdaterSet"].ID: + return _PriceRegistry.ParsePriceUpdaterSet(log) + case _PriceRegistry.abi.Events["UsdPerTokenUpdated"].ID: + return _PriceRegistry.ParseUsdPerTokenUpdated(log) + case _PriceRegistry.abi.Events["UsdPerUnitGasUpdated"].ID: + return _PriceRegistry.ParseUsdPerUnitGasUpdated(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (PriceRegistryFeeTokenAdded) Topic() common.Hash { + return common.HexToHash("0xdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba23") +} + +func (PriceRegistryFeeTokenRemoved) Topic() common.Hash { + return common.HexToHash("0x1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f91") +} + +func (PriceRegistryOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (PriceRegistryOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (PriceRegistryPriceUpdaterRemoved) Topic() common.Hash { + return common.HexToHash("0xff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c") +} + +func (PriceRegistryPriceUpdaterSet) Topic() common.Hash { + return common.HexToHash("0x34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b8") +} + +func (PriceRegistryUsdPerTokenUpdated) Topic() common.Hash { + return common.HexToHash("0x52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a") +} + +func (PriceRegistryUsdPerUnitGasUpdated) Topic() common.Hash { + return common.HexToHash("0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e") +} + +func (_PriceRegistry *PriceRegistry) Address() common.Address { + return _PriceRegistry.address +} + +type PriceRegistryInterface interface { + ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) + + GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (InternalTimestampedPackedUint224, error) + + GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) + + GetPriceUpdaters(opts *bind.CallOpts) ([]common.Address, error) + + GetStalenessThreshold(opts *bind.CallOpts) (*big.Int, error) + + GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) + + GetTokenPrice(opts *bind.CallOpts, token common.Address) (InternalTimestampedPackedUint224, error) + + GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]InternalTimestampedPackedUint224, error) + + GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) + + ApplyPriceUpdatersUpdates(opts *bind.TransactOpts, priceUpdatersToAdd []common.Address, priceUpdatersToRemove []common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdatePrices(opts *bind.TransactOpts, priceUpdates InternalPriceUpdates) (*types.Transaction, error) + + FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenAddedIterator, error) + + WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) + + ParseFeeTokenAdded(log types.Log) (*PriceRegistryFeeTokenAdded, error) + + FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenRemovedIterator, error) + + WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) + + ParseFeeTokenRemoved(log types.Log) (*PriceRegistryFeeTokenRemoved, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*PriceRegistryOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*PriceRegistryOwnershipTransferred, error) + + FilterPriceUpdaterRemoved(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterRemovedIterator, error) + + WatchPriceUpdaterRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address) (event.Subscription, error) + + ParsePriceUpdaterRemoved(log types.Log) (*PriceRegistryPriceUpdaterRemoved, error) + + FilterPriceUpdaterSet(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterSetIterator, error) + + WatchPriceUpdaterSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterSet, priceUpdater []common.Address) (event.Subscription, error) + + ParsePriceUpdaterSet(log types.Log) (*PriceRegistryPriceUpdaterSet, error) + + FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryUsdPerTokenUpdatedIterator, error) + + WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) + + ParseUsdPerTokenUpdated(log types.Log) (*PriceRegistryUsdPerTokenUpdated, error) + + FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*PriceRegistryUsdPerUnitGasUpdatedIterator, error) + + WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) + + ParseUsdPerUnitGasUpdated(log types.Log) (*PriceRegistryUsdPerUnitGasUpdated, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} \ No newline at end of file diff --git a/core/gethwrappers/ccip/generated/registry_module_owner_custom/registry_module_owner_custom.go b/core/gethwrappers/ccip/generated/registry_module_owner_custom/registry_module_owner_custom.go new file mode 100644 index 0000000000..bab8100d6f --- /dev/null +++ b/core/gethwrappers/ccip/generated/registry_module_owner_custom/registry_module_owner_custom.go @@ -0,0 +1,390 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package registry_module_owner_custom + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var RegistryModuleOwnerCustomMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AddressZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"CanOnlySelfRegister\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"}],\"name\":\"AdministratorRegistered\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"registerAdminViaGetCCIPAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"registerAdminViaOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a060405234801561001057600080fd5b5060405161048938038061048983398101604081905261002f91610067565b6001600160a01b03811661005657604051639fabe1c160e01b815260040160405180910390fd5b6001600160a01b0316608052610097565b60006020828403121561007957600080fd5b81516001600160a01b038116811461009057600080fd5b9392505050565b6080516103d76100b2600039600061023201526103d76000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063181f5a771461004657806396ea2f7a14610064578063ff12c35414610079575b600080fd5b61004e61008c565b60405161005b91906102d7565b60405180910390f35b610077610072366004610366565b6100a8565b005b610077610087366004610366565b610123565b6040518060600160405280602381526020016103a86023913981565b610120818273ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061011b919061038a565b610172565b50565b610120818273ffffffffffffffffffffffffffffffffffffffff16638fd6a6ac6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100f7573d6000803e3d6000fd5b73ffffffffffffffffffffffffffffffffffffffff811633146101e5576040517fc454d18200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80831660048301528316602482015260440160405180910390fd5b6040517fe677ae3700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015282811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063e677ae3790604401600060405180830381600087803b15801561027657600080fd5b505af115801561028a573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff8085169350851691507f09590fb70af4b833346363965e043a9339e8c7d378b8a2b903c75c277faec4f990600090a35050565b60006020808352835180602085015260005b81811015610305578581018301518582016040015282016102e9565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461012057600080fd5b60006020828403121561037857600080fd5b813561038381610344565b9392505050565b60006020828403121561039c57600080fd5b81516103838161034456fe52656769737472794d6f64756c654f776e6572437573746f6d20312e352e302d646576a164736f6c6343000818000a", +} + +var RegistryModuleOwnerCustomABI = RegistryModuleOwnerCustomMetaData.ABI + +var RegistryModuleOwnerCustomBin = RegistryModuleOwnerCustomMetaData.Bin + +func DeployRegistryModuleOwnerCustom(auth *bind.TransactOpts, backend bind.ContractBackend, tokenAdminRegistry common.Address) (common.Address, *types.Transaction, *RegistryModuleOwnerCustom, error) { + parsed, err := RegistryModuleOwnerCustomMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(RegistryModuleOwnerCustomBin), backend, tokenAdminRegistry) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &RegistryModuleOwnerCustom{address: address, abi: *parsed, RegistryModuleOwnerCustomCaller: RegistryModuleOwnerCustomCaller{contract: contract}, RegistryModuleOwnerCustomTransactor: RegistryModuleOwnerCustomTransactor{contract: contract}, RegistryModuleOwnerCustomFilterer: RegistryModuleOwnerCustomFilterer{contract: contract}}, nil +} + +type RegistryModuleOwnerCustom struct { + address common.Address + abi abi.ABI + RegistryModuleOwnerCustomCaller + RegistryModuleOwnerCustomTransactor + RegistryModuleOwnerCustomFilterer +} + +type RegistryModuleOwnerCustomCaller struct { + contract *bind.BoundContract +} + +type RegistryModuleOwnerCustomTransactor struct { + contract *bind.BoundContract +} + +type RegistryModuleOwnerCustomFilterer struct { + contract *bind.BoundContract +} + +type RegistryModuleOwnerCustomSession struct { + Contract *RegistryModuleOwnerCustom + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type RegistryModuleOwnerCustomCallerSession struct { + Contract *RegistryModuleOwnerCustomCaller + CallOpts bind.CallOpts +} + +type RegistryModuleOwnerCustomTransactorSession struct { + Contract *RegistryModuleOwnerCustomTransactor + TransactOpts bind.TransactOpts +} + +type RegistryModuleOwnerCustomRaw struct { + Contract *RegistryModuleOwnerCustom +} + +type RegistryModuleOwnerCustomCallerRaw struct { + Contract *RegistryModuleOwnerCustomCaller +} + +type RegistryModuleOwnerCustomTransactorRaw struct { + Contract *RegistryModuleOwnerCustomTransactor +} + +func NewRegistryModuleOwnerCustom(address common.Address, backend bind.ContractBackend) (*RegistryModuleOwnerCustom, error) { + abi, err := abi.JSON(strings.NewReader(RegistryModuleOwnerCustomABI)) + if err != nil { + return nil, err + } + contract, err := bindRegistryModuleOwnerCustom(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &RegistryModuleOwnerCustom{address: address, abi: abi, RegistryModuleOwnerCustomCaller: RegistryModuleOwnerCustomCaller{contract: contract}, RegistryModuleOwnerCustomTransactor: RegistryModuleOwnerCustomTransactor{contract: contract}, RegistryModuleOwnerCustomFilterer: RegistryModuleOwnerCustomFilterer{contract: contract}}, nil +} + +func NewRegistryModuleOwnerCustomCaller(address common.Address, caller bind.ContractCaller) (*RegistryModuleOwnerCustomCaller, error) { + contract, err := bindRegistryModuleOwnerCustom(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &RegistryModuleOwnerCustomCaller{contract: contract}, nil +} + +func NewRegistryModuleOwnerCustomTransactor(address common.Address, transactor bind.ContractTransactor) (*RegistryModuleOwnerCustomTransactor, error) { + contract, err := bindRegistryModuleOwnerCustom(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &RegistryModuleOwnerCustomTransactor{contract: contract}, nil +} + +func NewRegistryModuleOwnerCustomFilterer(address common.Address, filterer bind.ContractFilterer) (*RegistryModuleOwnerCustomFilterer, error) { + contract, err := bindRegistryModuleOwnerCustom(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &RegistryModuleOwnerCustomFilterer{contract: contract}, nil +} + +func bindRegistryModuleOwnerCustom(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := RegistryModuleOwnerCustomMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RegistryModuleOwnerCustom.Contract.RegistryModuleOwnerCustomCaller.contract.Call(opts, result, method, params...) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RegistryModuleOwnerCustom.Contract.RegistryModuleOwnerCustomTransactor.contract.Transfer(opts) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RegistryModuleOwnerCustom.Contract.RegistryModuleOwnerCustomTransactor.contract.Transact(opts, method, params...) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RegistryModuleOwnerCustom.Contract.contract.Call(opts, result, method, params...) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RegistryModuleOwnerCustom.Contract.contract.Transfer(opts) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RegistryModuleOwnerCustom.Contract.contract.Transact(opts, method, params...) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _RegistryModuleOwnerCustom.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomSession) TypeAndVersion() (string, error) { + return _RegistryModuleOwnerCustom.Contract.TypeAndVersion(&_RegistryModuleOwnerCustom.CallOpts) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomCallerSession) TypeAndVersion() (string, error) { + return _RegistryModuleOwnerCustom.Contract.TypeAndVersion(&_RegistryModuleOwnerCustom.CallOpts) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomTransactor) RegisterAdminViaGetCCIPAdmin(opts *bind.TransactOpts, token common.Address) (*types.Transaction, error) { + return _RegistryModuleOwnerCustom.contract.Transact(opts, "registerAdminViaGetCCIPAdmin", token) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomSession) RegisterAdminViaGetCCIPAdmin(token common.Address) (*types.Transaction, error) { + return _RegistryModuleOwnerCustom.Contract.RegisterAdminViaGetCCIPAdmin(&_RegistryModuleOwnerCustom.TransactOpts, token) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomTransactorSession) RegisterAdminViaGetCCIPAdmin(token common.Address) (*types.Transaction, error) { + return _RegistryModuleOwnerCustom.Contract.RegisterAdminViaGetCCIPAdmin(&_RegistryModuleOwnerCustom.TransactOpts, token) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomTransactor) RegisterAdminViaOwner(opts *bind.TransactOpts, token common.Address) (*types.Transaction, error) { + return _RegistryModuleOwnerCustom.contract.Transact(opts, "registerAdminViaOwner", token) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomSession) RegisterAdminViaOwner(token common.Address) (*types.Transaction, error) { + return _RegistryModuleOwnerCustom.Contract.RegisterAdminViaOwner(&_RegistryModuleOwnerCustom.TransactOpts, token) +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomTransactorSession) RegisterAdminViaOwner(token common.Address) (*types.Transaction, error) { + return _RegistryModuleOwnerCustom.Contract.RegisterAdminViaOwner(&_RegistryModuleOwnerCustom.TransactOpts, token) +} + +type RegistryModuleOwnerCustomAdministratorRegisteredIterator struct { + Event *RegistryModuleOwnerCustomAdministratorRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RegistryModuleOwnerCustomAdministratorRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RegistryModuleOwnerCustomAdministratorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RegistryModuleOwnerCustomAdministratorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RegistryModuleOwnerCustomAdministratorRegisteredIterator) Error() error { + return it.fail +} + +func (it *RegistryModuleOwnerCustomAdministratorRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RegistryModuleOwnerCustomAdministratorRegistered struct { + Token common.Address + Administrator common.Address + Raw types.Log +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomFilterer) FilterAdministratorRegistered(opts *bind.FilterOpts, token []common.Address, administrator []common.Address) (*RegistryModuleOwnerCustomAdministratorRegisteredIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var administratorRule []interface{} + for _, administratorItem := range administrator { + administratorRule = append(administratorRule, administratorItem) + } + + logs, sub, err := _RegistryModuleOwnerCustom.contract.FilterLogs(opts, "AdministratorRegistered", tokenRule, administratorRule) + if err != nil { + return nil, err + } + return &RegistryModuleOwnerCustomAdministratorRegisteredIterator{contract: _RegistryModuleOwnerCustom.contract, event: "AdministratorRegistered", logs: logs, sub: sub}, nil +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomFilterer) WatchAdministratorRegistered(opts *bind.WatchOpts, sink chan<- *RegistryModuleOwnerCustomAdministratorRegistered, token []common.Address, administrator []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var administratorRule []interface{} + for _, administratorItem := range administrator { + administratorRule = append(administratorRule, administratorItem) + } + + logs, sub, err := _RegistryModuleOwnerCustom.contract.WatchLogs(opts, "AdministratorRegistered", tokenRule, administratorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RegistryModuleOwnerCustomAdministratorRegistered) + if err := _RegistryModuleOwnerCustom.contract.UnpackLog(event, "AdministratorRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustomFilterer) ParseAdministratorRegistered(log types.Log) (*RegistryModuleOwnerCustomAdministratorRegistered, error) { + event := new(RegistryModuleOwnerCustomAdministratorRegistered) + if err := _RegistryModuleOwnerCustom.contract.UnpackLog(event, "AdministratorRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustom) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _RegistryModuleOwnerCustom.abi.Events["AdministratorRegistered"].ID: + return _RegistryModuleOwnerCustom.ParseAdministratorRegistered(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (RegistryModuleOwnerCustomAdministratorRegistered) Topic() common.Hash { + return common.HexToHash("0x09590fb70af4b833346363965e043a9339e8c7d378b8a2b903c75c277faec4f9") +} + +func (_RegistryModuleOwnerCustom *RegistryModuleOwnerCustom) Address() common.Address { + return _RegistryModuleOwnerCustom.address +} + +type RegistryModuleOwnerCustomInterface interface { + TypeAndVersion(opts *bind.CallOpts) (string, error) + + RegisterAdminViaGetCCIPAdmin(opts *bind.TransactOpts, token common.Address) (*types.Transaction, error) + + RegisterAdminViaOwner(opts *bind.TransactOpts, token common.Address) (*types.Transaction, error) + + FilterAdministratorRegistered(opts *bind.FilterOpts, token []common.Address, administrator []common.Address) (*RegistryModuleOwnerCustomAdministratorRegisteredIterator, error) + + WatchAdministratorRegistered(opts *bind.WatchOpts, sink chan<- *RegistryModuleOwnerCustomAdministratorRegistered, token []common.Address, administrator []common.Address) (event.Subscription, error) + + ParseAdministratorRegistered(log types.Log) (*RegistryModuleOwnerCustomAdministratorRegistered, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/report_codec/report_codec.go b/core/gethwrappers/ccip/generated/report_codec/report_codec.go new file mode 100644 index 0000000000..1648ea9ba5 --- /dev/null +++ b/core/gethwrappers/ccip/generated/report_codec/report_codec.go @@ -0,0 +1,559 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package report_codec + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type EVM2EVMMultiOffRampCommitReport struct { + PriceUpdates InternalPriceUpdates + MerkleRoots []EVM2EVMMultiOffRampMerkleRoot +} + +type EVM2EVMMultiOffRampInterval struct { + Min uint64 + Max uint64 +} + +type EVM2EVMMultiOffRampMerkleRoot struct { + SourceChainSelector uint64 + Interval EVM2EVMMultiOffRampInterval + MerkleRoot [32]byte +} + +type InternalAny2EVMRampMessage struct { + Header InternalRampMessageHeader + Sender []byte + Data []byte + Receiver common.Address + GasLimit *big.Int + TokenAmounts []InternalRampTokenAmount +} + +type InternalExecutionReportSingleChain struct { + SourceChainSelector uint64 + Messages []InternalAny2EVMRampMessage + OffchainTokenData [][][]byte + Proofs [][32]byte + ProofFlagBits *big.Int +} + +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + +type InternalRampMessageHeader struct { + MessageId [32]byte + SourceChainSelector uint64 + DestChainSelector uint64 + SequenceNumber uint64 + Nonce uint64 +} + +type InternalRampTokenAmount struct { + SourcePoolAddress []byte + DestTokenAddress []byte + ExtraData []byte + Amount *big.Int +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var ReportCodecMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportDecoded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"report\",\"type\":\"tuple[]\"}],\"name\":\"ExecuteReportDecoded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeCommitReport\",\"outputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeExecuteReport\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061124f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636fb349561461003b578063f816ec6014610064575b600080fd5b61004e61004936600461024f565b610084565b60405161005b91906104f5565b60405180910390f35b61007761007236600461024f565b6100a0565b60405161005b91906107ae565b60608180602001905181019061009a9190610dc3565b92915050565b604080516080810182526060918101828152828201839052815260208101919091528180602001905181019061009a91906110d9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715610128576101286100d6565b60405290565b6040516080810167ffffffffffffffff81118282101715610128576101286100d6565b60405160c0810167ffffffffffffffff81118282101715610128576101286100d6565b6040805190810167ffffffffffffffff81118282101715610128576101286100d6565b6040516060810167ffffffffffffffff81118282101715610128576101286100d6565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610201576102016100d6565b604052919050565b600067ffffffffffffffff821115610223576102236100d6565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006020828403121561026157600080fd5b813567ffffffffffffffff81111561027857600080fd5b8201601f8101841361028957600080fd5b803561029c61029782610209565b6101ba565b8181528560208385010111156102b157600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b838110156102ea5781810151838201526020016102d2565b50506000910152565b6000815180845261030b8160208601602086016102cf565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b848110156103f2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086840301895281516080815181865261039e828701826102f3565b91505085820151858203878701526103b682826102f3565b915050604080830151868303828801526103d083826102f3565b606094850151979094019690965250509884019892509083019060010161035a565b5090979650505050505050565b6000828251808552602080860195506005818360051b8501018287016000805b868110156104aa577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe088850381018c5283518051808752908801908887019080891b88018a01865b8281101561049357858a83030184526104818286516102f3565b948c0194938c01939150600101610467565b509e8a019e9750505093870193505060010161041f565b50919998505050505050505050565b60008151808452602080850194506020840160005b838110156104ea578151875295820195908201906001016104ce565b509495945050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156106dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452815160a0860167ffffffffffffffff8083511688528883015160a08a8a015282815180855260c08b01915060c08160051b8c010194508b8301925060005b81811015610686577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408c87030183528351805180518852868f820151168f890152866040820151166040890152866060820151166060890152866080820151166080890152508d81015161014060a08901526106096101408901826102f3565b9050604082015188820360c08a015261062282826102f3565b915050606082015161064c60e08a018273ffffffffffffffffffffffffffffffffffffffff169052565b50608082015161010089015260a08201519150878103610120890152610672818361033d565b97505050928c0192918c0191600101610589565b5050505050604082015187820360408901526106a282826103ff565b915050606082015187820360608901526106bc82826104b9565b6080938401519890930197909752509450928501929085019060010161051c565b5092979650505050505050565b60008151808452602080850194506020840160005b838110156104ea578151805167ffffffffffffffff1688528301517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683880152604090960195908201906001016106ff565b600081518084526020808501945080840160005b838110156104ea578151805167ffffffffffffffff90811689528482015180518216868b0152850151166040808a01919091520151606088015260809096019590820190600101610762565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b8083101561083e578351805173ffffffffffffffffffffffffffffffffffffffff1683528701517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16878301529286019260019290920191908401906107e1565b50938501518785037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa00160808901529361087881866106ea565b9450505050508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08482030160408501526108b8818361074e565b95945050505050565b600067ffffffffffffffff8211156108db576108db6100d6565b5060051b60200190565b805167ffffffffffffffff811681146108fd57600080fd5b919050565b600060a0828403121561091457600080fd5b61091c610105565b90508151815261092e602083016108e5565b602082015261093f604083016108e5565b6040820152610950606083016108e5565b6060820152610961608083016108e5565b608082015292915050565b600082601f83011261097d57600080fd5b815161098b61029782610209565b8181528460208386010111156109a057600080fd5b6109b18260208301602087016102cf565b949350505050565b805173ffffffffffffffffffffffffffffffffffffffff811681146108fd57600080fd5b600082601f8301126109ee57600080fd5b815160206109fe610297836108c1565b82815260059290921b84018101918181019086841115610a1d57600080fd5b8286015b84811015610b1157805167ffffffffffffffff80821115610a425760008081fd5b81890191506080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610a7b5760008081fd5b610a8361012e565b8784015183811115610a955760008081fd5b610aa38d8a8388010161096c565b82525060408085015184811115610aba5760008081fd5b610ac88e8b8389010161096c565b8a8401525060608086015185811115610ae15760008081fd5b610aef8f8c838a010161096c565b9284019290925294909201519381019390935250508352918301918301610a21565b509695505050505050565b600082601f830112610b2d57600080fd5b81516020610b3d610297836108c1565b82815260059290921b84018101918181019086841115610b5c57600080fd5b8286015b84811015610b1157805167ffffffffffffffff80821115610b815760008081fd5b8189019150610140807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610bbb5760008081fd5b610bc3610151565b610bcf8c898601610902565b815260c084015183811115610be45760008081fd5b610bf28d8a8388010161096c565b898301525060e084015183811115610c0a5760008081fd5b610c188d8a8388010161096c565b604083015250610c2b61010085016109b9565b60608201526101208401516080820152908301519082821115610c4e5760008081fd5b610c5c8c89848701016109dd565b60a08201528652505050918301918301610b60565b600082601f830112610c8257600080fd5b81516020610c92610297836108c1565b82815260059290921b84018101918181019086841115610cb157600080fd5b8286015b84811015610b1157805167ffffffffffffffff80821115610cd557600080fd5b818901915089603f830112610ce957600080fd5b85820151610cf9610297826108c1565b81815260059190911b830160400190878101908c831115610d1957600080fd5b604085015b83811015610d5257805185811115610d3557600080fd5b610d448f6040838a010161096c565b845250918901918901610d1e565b50875250505092840192508301610cb5565b600082601f830112610d7557600080fd5b81516020610d85610297836108c1565b8083825260208201915060208460051b870101935086841115610da757600080fd5b602086015b84811015610b115780518352918301918301610dac565b60006020808385031215610dd657600080fd5b825167ffffffffffffffff80821115610dee57600080fd5b818501915085601f830112610e0257600080fd5b8151610e10610297826108c1565b81815260059190911b83018401908481019088831115610e2f57600080fd5b8585015b83811015610f2957805185811115610e4a57600080fd5b860160a0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215610e7f5760008081fd5b610e87610105565b610e928983016108e5565b815260408083015188811115610ea85760008081fd5b610eb68e8c83870101610b1c565b8b8401525060608084015189811115610ecf5760008081fd5b610edd8f8d83880101610c71565b8385015250608091508184015189811115610ef85760008081fd5b610f068f8d83880101610d64565b918401919091525060a09290920151918101919091528352918601918601610e33565b5098975050505050505050565b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146108fd57600080fd5b600082601f830112610f7357600080fd5b81516020610f83610297836108c1565b82815260069290921b84018101918181019086841115610fa257600080fd5b8286015b84811015610b115760408189031215610fbf5760008081fd5b610fc7610174565b610fd0826108e5565b8152610fdd858301610f36565b81860152835291830191604001610fa6565b600082601f83011261100057600080fd5b81516020611010610297836108c1565b82815260079290921b8401810191818101908684111561102f57600080fd5b8286015b84811015610b1157808803608081121561104d5760008081fd5b611055610197565b61105e836108e5565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156110925760008081fd5b61109a610174565b92506110a78785016108e5565b83526110b48185016108e5565b8388015281870192909252606083015191810191909152835291830191608001611033565b600060208083850312156110ec57600080fd5b825167ffffffffffffffff8082111561110457600080fd5b8185019150604080838803121561111a57600080fd5b611122610174565b83518381111561113157600080fd5b84016040818a03121561114357600080fd5b61114b610174565b81518581111561115a57600080fd5b8201601f81018b1361116b57600080fd5b8051611179610297826108c1565b81815260069190911b8201890190898101908d83111561119857600080fd5b928a01925b828410156111e65787848f0312156111b55760008081fd5b6111bd610174565b6111c6856109b9565b81526111d38c8601610f36565b818d0152825292870192908a019061119d565b8452505050818701519350848411156111fe57600080fd5b61120a8a858401610f62565b818801528252508385015191508282111561122457600080fd5b61123088838601610fef565b8582015280955050505050509291505056fea164736f6c6343000818000a", +} + +var ReportCodecABI = ReportCodecMetaData.ABI + +var ReportCodecBin = ReportCodecMetaData.Bin + +func DeployReportCodec(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ReportCodec, error) { + parsed, err := ReportCodecMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ReportCodecBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ReportCodec{address: address, abi: *parsed, ReportCodecCaller: ReportCodecCaller{contract: contract}, ReportCodecTransactor: ReportCodecTransactor{contract: contract}, ReportCodecFilterer: ReportCodecFilterer{contract: contract}}, nil +} + +type ReportCodec struct { + address common.Address + abi abi.ABI + ReportCodecCaller + ReportCodecTransactor + ReportCodecFilterer +} + +type ReportCodecCaller struct { + contract *bind.BoundContract +} + +type ReportCodecTransactor struct { + contract *bind.BoundContract +} + +type ReportCodecFilterer struct { + contract *bind.BoundContract +} + +type ReportCodecSession struct { + Contract *ReportCodec + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ReportCodecCallerSession struct { + Contract *ReportCodecCaller + CallOpts bind.CallOpts +} + +type ReportCodecTransactorSession struct { + Contract *ReportCodecTransactor + TransactOpts bind.TransactOpts +} + +type ReportCodecRaw struct { + Contract *ReportCodec +} + +type ReportCodecCallerRaw struct { + Contract *ReportCodecCaller +} + +type ReportCodecTransactorRaw struct { + Contract *ReportCodecTransactor +} + +func NewReportCodec(address common.Address, backend bind.ContractBackend) (*ReportCodec, error) { + abi, err := abi.JSON(strings.NewReader(ReportCodecABI)) + if err != nil { + return nil, err + } + contract, err := bindReportCodec(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ReportCodec{address: address, abi: abi, ReportCodecCaller: ReportCodecCaller{contract: contract}, ReportCodecTransactor: ReportCodecTransactor{contract: contract}, ReportCodecFilterer: ReportCodecFilterer{contract: contract}}, nil +} + +func NewReportCodecCaller(address common.Address, caller bind.ContractCaller) (*ReportCodecCaller, error) { + contract, err := bindReportCodec(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ReportCodecCaller{contract: contract}, nil +} + +func NewReportCodecTransactor(address common.Address, transactor bind.ContractTransactor) (*ReportCodecTransactor, error) { + contract, err := bindReportCodec(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ReportCodecTransactor{contract: contract}, nil +} + +func NewReportCodecFilterer(address common.Address, filterer bind.ContractFilterer) (*ReportCodecFilterer, error) { + contract, err := bindReportCodec(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ReportCodecFilterer{contract: contract}, nil +} + +func bindReportCodec(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ReportCodecMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ReportCodec *ReportCodecRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReportCodec.Contract.ReportCodecCaller.contract.Call(opts, result, method, params...) +} + +func (_ReportCodec *ReportCodecRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReportCodec.Contract.ReportCodecTransactor.contract.Transfer(opts) +} + +func (_ReportCodec *ReportCodecRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReportCodec.Contract.ReportCodecTransactor.contract.Transact(opts, method, params...) +} + +func (_ReportCodec *ReportCodecCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReportCodec.Contract.contract.Call(opts, result, method, params...) +} + +func (_ReportCodec *ReportCodecTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReportCodec.Contract.contract.Transfer(opts) +} + +func (_ReportCodec *ReportCodecTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReportCodec.Contract.contract.Transact(opts, method, params...) +} + +func (_ReportCodec *ReportCodecCaller) DecodeCommitReport(opts *bind.CallOpts, report []byte) (EVM2EVMMultiOffRampCommitReport, error) { + var out []interface{} + err := _ReportCodec.contract.Call(opts, &out, "decodeCommitReport", report) + + if err != nil { + return *new(EVM2EVMMultiOffRampCommitReport), err + } + + out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOffRampCommitReport)).(*EVM2EVMMultiOffRampCommitReport) + + return out0, err + +} + +func (_ReportCodec *ReportCodecSession) DecodeCommitReport(report []byte) (EVM2EVMMultiOffRampCommitReport, error) { + return _ReportCodec.Contract.DecodeCommitReport(&_ReportCodec.CallOpts, report) +} + +func (_ReportCodec *ReportCodecCallerSession) DecodeCommitReport(report []byte) (EVM2EVMMultiOffRampCommitReport, error) { + return _ReportCodec.Contract.DecodeCommitReport(&_ReportCodec.CallOpts, report) +} + +func (_ReportCodec *ReportCodecCaller) DecodeExecuteReport(opts *bind.CallOpts, report []byte) ([]InternalExecutionReportSingleChain, error) { + var out []interface{} + err := _ReportCodec.contract.Call(opts, &out, "decodeExecuteReport", report) + + if err != nil { + return *new([]InternalExecutionReportSingleChain), err + } + + out0 := *abi.ConvertType(out[0], new([]InternalExecutionReportSingleChain)).(*[]InternalExecutionReportSingleChain) + + return out0, err + +} + +func (_ReportCodec *ReportCodecSession) DecodeExecuteReport(report []byte) ([]InternalExecutionReportSingleChain, error) { + return _ReportCodec.Contract.DecodeExecuteReport(&_ReportCodec.CallOpts, report) +} + +func (_ReportCodec *ReportCodecCallerSession) DecodeExecuteReport(report []byte) ([]InternalExecutionReportSingleChain, error) { + return _ReportCodec.Contract.DecodeExecuteReport(&_ReportCodec.CallOpts, report) +} + +type ReportCodecCommitReportDecodedIterator struct { + Event *ReportCodecCommitReportDecoded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ReportCodecCommitReportDecodedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReportCodecCommitReportDecoded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ReportCodecCommitReportDecoded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ReportCodecCommitReportDecodedIterator) Error() error { + return it.fail +} + +func (it *ReportCodecCommitReportDecodedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ReportCodecCommitReportDecoded struct { + Report EVM2EVMMultiOffRampCommitReport + Raw types.Log +} + +func (_ReportCodec *ReportCodecFilterer) FilterCommitReportDecoded(opts *bind.FilterOpts) (*ReportCodecCommitReportDecodedIterator, error) { + + logs, sub, err := _ReportCodec.contract.FilterLogs(opts, "CommitReportDecoded") + if err != nil { + return nil, err + } + return &ReportCodecCommitReportDecodedIterator{contract: _ReportCodec.contract, event: "CommitReportDecoded", logs: logs, sub: sub}, nil +} + +func (_ReportCodec *ReportCodecFilterer) WatchCommitReportDecoded(opts *bind.WatchOpts, sink chan<- *ReportCodecCommitReportDecoded) (event.Subscription, error) { + + logs, sub, err := _ReportCodec.contract.WatchLogs(opts, "CommitReportDecoded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ReportCodecCommitReportDecoded) + if err := _ReportCodec.contract.UnpackLog(event, "CommitReportDecoded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ReportCodec *ReportCodecFilterer) ParseCommitReportDecoded(log types.Log) (*ReportCodecCommitReportDecoded, error) { + event := new(ReportCodecCommitReportDecoded) + if err := _ReportCodec.contract.UnpackLog(event, "CommitReportDecoded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ReportCodecExecuteReportDecodedIterator struct { + Event *ReportCodecExecuteReportDecoded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ReportCodecExecuteReportDecodedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReportCodecExecuteReportDecoded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ReportCodecExecuteReportDecoded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ReportCodecExecuteReportDecodedIterator) Error() error { + return it.fail +} + +func (it *ReportCodecExecuteReportDecodedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ReportCodecExecuteReportDecoded struct { + Report []InternalExecutionReportSingleChain + Raw types.Log +} + +func (_ReportCodec *ReportCodecFilterer) FilterExecuteReportDecoded(opts *bind.FilterOpts) (*ReportCodecExecuteReportDecodedIterator, error) { + + logs, sub, err := _ReportCodec.contract.FilterLogs(opts, "ExecuteReportDecoded") + if err != nil { + return nil, err + } + return &ReportCodecExecuteReportDecodedIterator{contract: _ReportCodec.contract, event: "ExecuteReportDecoded", logs: logs, sub: sub}, nil +} + +func (_ReportCodec *ReportCodecFilterer) WatchExecuteReportDecoded(opts *bind.WatchOpts, sink chan<- *ReportCodecExecuteReportDecoded) (event.Subscription, error) { + + logs, sub, err := _ReportCodec.contract.WatchLogs(opts, "ExecuteReportDecoded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ReportCodecExecuteReportDecoded) + if err := _ReportCodec.contract.UnpackLog(event, "ExecuteReportDecoded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ReportCodec *ReportCodecFilterer) ParseExecuteReportDecoded(log types.Log) (*ReportCodecExecuteReportDecoded, error) { + event := new(ReportCodecExecuteReportDecoded) + if err := _ReportCodec.contract.UnpackLog(event, "ExecuteReportDecoded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_ReportCodec *ReportCodec) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _ReportCodec.abi.Events["CommitReportDecoded"].ID: + return _ReportCodec.ParseCommitReportDecoded(log) + case _ReportCodec.abi.Events["ExecuteReportDecoded"].ID: + return _ReportCodec.ParseExecuteReportDecoded(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (ReportCodecCommitReportDecoded) Topic() common.Hash { + return common.HexToHash("0x1b2cb5e9d31bdaabb2ae07532436ae669406f84003ca27179b4dfb72f127f7dc") +} + +func (ReportCodecExecuteReportDecoded) Topic() common.Hash { + return common.HexToHash("0x7f4f1032eaaa1f5c3fc02d56071d69a09a2595d9a5fa4704f0eb298792908abb") +} + +func (_ReportCodec *ReportCodec) Address() common.Address { + return _ReportCodec.address +} + +type ReportCodecInterface interface { + DecodeCommitReport(opts *bind.CallOpts, report []byte) (EVM2EVMMultiOffRampCommitReport, error) + + DecodeExecuteReport(opts *bind.CallOpts, report []byte) ([]InternalExecutionReportSingleChain, error) + + FilterCommitReportDecoded(opts *bind.FilterOpts) (*ReportCodecCommitReportDecodedIterator, error) + + WatchCommitReportDecoded(opts *bind.WatchOpts, sink chan<- *ReportCodecCommitReportDecoded) (event.Subscription, error) + + ParseCommitReportDecoded(log types.Log) (*ReportCodecCommitReportDecoded, error) + + FilterExecuteReportDecoded(opts *bind.FilterOpts) (*ReportCodecExecuteReportDecodedIterator, error) + + WatchExecuteReportDecoded(opts *bind.WatchOpts, sink chan<- *ReportCodecExecuteReportDecoded) (event.Subscription, error) + + ParseExecuteReportDecoded(log types.Log) (*ReportCodecExecuteReportDecoded, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/router/router.go b/core/gethwrappers/ccip/generated/router/router.go new file mode 100644 index 0000000000..c53d4824b1 --- /dev/null +++ b/core/gethwrappers/ccip/generated/router/router.go @@ -0,0 +1,1431 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package router + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientAny2EVMMessage struct { + MessageId [32]byte + SourceChainSelector uint64 + Sender []byte + Data []byte + DestTokenAmounts []ClientEVMTokenAmount +} + +type ClientEVM2AnyMessage struct { + Receiver []byte + Data []byte + TokenAmounts []ClientEVMTokenAmount + FeeToken common.Address + ExtraArgs []byte +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type RouterOffRamp struct { + SourceChainSelector uint64 + OffRamp common.Address +} + +type RouterOnRamp struct { + DestChainSelector uint64 + OnRamp common.Address +} + +var RouterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"wrappedNative\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFeeTokenAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMsgValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"InvalidRecipientAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyOffRamp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"UnsupportedDestinationChain\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"calldataHash\",\"type\":\"bytes32\"}],\"name\":\"MessageExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"OnRampSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_RET_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"internalType\":\"structRouter.OnRamp[]\",\"name\":\"onRampUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"internalType\":\"structRouter.OffRamp[]\",\"name\":\"offRampRemoves\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"internalType\":\"structRouter.OffRamp[]\",\"name\":\"offRampAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyRampUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destinationChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ccipSend\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destinationChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOffRamps\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"internalType\":\"structRouter.OffRamp[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWrappedNative\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"isChainSupported\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"recoverTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"routeMessage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"retData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"wrappedNative\",\"type\":\"address\"}],\"name\":\"setWrappedNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162002d2838038062002d288339810160408190526200003491620001af565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e7565b5050600280546001600160a01b0319166001600160a01b039485161790555016608052620001e7565b336001600160a01b03821603620001415760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001aa57600080fd5b919050565b60008060408385031215620001c357600080fd5b620001ce8362000192565b9150620001de6020840162000192565b90509250929050565b608051612b1762000211600039600081816101f9015281816105e10152610af20152612b176000f3fe6080604052600436106101295760003560e01c80638da5cb5b116100a5578063a8d87a3b11610074578063e861e90711610059578063e861e90714610409578063f2fde38b14610434578063fbca3b741461045457600080fd5b8063a8d87a3b1461039c578063da5fcac8146103e957600080fd5b80638da5cb5b146102ed57806396f4e9f914610318578063a40e69c71461032b578063a48a90581461034d57600080fd5b806352cb60ca116100fc578063787350e3116100e1578063787350e31461028057806379ba5097146102a857806383826b2b146102bd57600080fd5b806352cb60ca1461023e5780635f3e849f1461026057600080fd5b8063181f5a771461012e57806320487ded1461018d5780633cf97983146101bb5780635246492f146101ea575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280600c81526020017f526f7574657220312e322e30000000000000000000000000000000000000000081525081565b6040516101849190611f3c565b60405180910390f35b34801561019957600080fd5b506101ad6101a83660046121ad565b610481565b604051908152602001610184565b3480156101c757600080fd5b506101db6101d63660046122aa565b6105d9565b60405161018493929190612322565b3480156101f657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561024a57600080fd5b5061025e61025936600461234d565b610836565b005b34801561026c57600080fd5b5061025e61027b36600461236a565b610885565b34801561028c57600080fd5b50610295608481565b60405161ffff9091168152602001610184565b3480156102b457600080fd5b5061025e6109d3565b3480156102c957600080fd5b506102dd6102d83660046123ab565b610ad0565b6040519015158152602001610184565b3480156102f957600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610219565b6101ad6103263660046121ad565b610aee565b34801561033757600080fd5b50610340611087565b60405161018491906123e2565b34801561035957600080fd5b506102dd610368366004612451565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b3480156103a857600080fd5b506102196103b7366004612451565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b3480156103f557600080fd5b5061025e6104043660046124b8565b61118b565b34801561041557600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff16610219565b34801561044057600080fd5b5061025e61044f36600461234d565b611490565b34801561046057600080fd5b5061047461046f366004612451565b6114a4565b6040516101849190612552565b606081015160009073ffffffffffffffffffffffffffffffffffffffff166104c25760025473ffffffffffffffffffffffffffffffffffffffff1660608301525b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff168061053a576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024015b60405180910390fd5b6040517f20487ded00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216906320487ded9061058e9087908790600401612689565b602060405180830381865afa1580156105ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105cf91906126ac565b9150505b92915050565b6000606060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e91906126c5565b156106a5576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106be6106b86040890160208a01612451565b33610ad0565b6106f4576040517fd2316ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006385572ffb60e01b8860405160240161070f91906127f4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905061079c8186888a60846115c4565b919550935091507f9b877de93ea9895756e337442c657f95a34fc68e7eb988bdfa693d5be83016b688356107d660408b0160208c01612451565b83516020850120604051610823939291339193845267ffffffffffffffff92909216602084015273ffffffffffffffffffffffffffffffffffffffff166040830152606082015260800190565b60405180910390a1509450945094915050565b61083e6116ea565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61088d6116ea565b73ffffffffffffffffffffffffffffffffffffffff82166108f2576040517f26a78f8f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610531565b73ffffffffffffffffffffffffffffffffffffffff83166109ad5760008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610967576040519150601f19603f3d011682016040523d82523d6000602084013e61096c565b606091505b50509050806109a7576040517fe417b80b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6109ce73ffffffffffffffffffffffffffffffffffffffff8416838361176d565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610531565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000610ae7610adf8484611841565b600490611885565b9392505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7f91906126c5565b15610bb6576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610c29576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610531565b606083015160009073ffffffffffffffffffffffffffffffffffffffff16610dbb5760025473ffffffffffffffffffffffffffffffffffffffff90811660608601526040517f20487ded000000000000000000000000000000000000000000000000000000008152908316906320487ded90610cab9088908890600401612689565b602060405180830381865afa158015610cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cec91906126ac565b905080341015610d28576040517f07da6ee600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b349050836060015173ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610d7757600080fd5b505af1158015610d8b573d6000803e3d6000fd5b505050506060850151610db6915073ffffffffffffffffffffffffffffffffffffffff16838361176d565b610eb2565b3415610df3576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f20487ded00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906320487ded90610e479088908890600401612689565b602060405180830381865afa158015610e64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8891906126ac565b6060850151909150610eb29073ffffffffffffffffffffffffffffffffffffffff1633848461189d565b60005b846040015151811015610fe257600085604001518281518110610eda57610eda612900565b6020908102919091010151516040517f48a98aa400000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8916600482015273ffffffffffffffffffffffffffffffffffffffff8083166024830152919250610fd9913391908716906348a98aa490604401602060405180830381865afa158015610f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f90919061292f565b88604001518581518110610fa657610fa6612900565b6020026020010151602001518473ffffffffffffffffffffffffffffffffffffffff1661189d909392919063ffffffff16565b50600101610eb5565b506040517fdf0aa9e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169063df0aa9e99061103b90889088908690339060040161294c565b6020604051808303816000875af115801561105a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107e91906126ac565b95945050505050565b6060600061109560046118fb565b90506000815167ffffffffffffffff8111156110b3576110b3611f6c565b6040519080825280602002602001820160405280156110f857816020015b60408051808201909152600080825260208201528152602001906001900390816110d15790505b50905060005b825181101561118457600083828151811061111b5761111b612900565b60200260200101519050604051806040016040528060a083901c67ffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681525083838151811061117057611170612900565b6020908102919091010152506001016110fe565b5092915050565b6111936116ea565b60005b8581101561126f5760008787838181106111b2576111b2612900565b9050604002018036038101906111c8919061299c565b60208181018051835167ffffffffffffffff90811660009081526003855260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055855193519051921682529394509216917f1f7d0ec248b80e5c0dde0ee531c4fc8fdb6ce9a2b3d90f560c74acd6a7202f23910160405180910390a250600101611196565b5060005b838110156113a757600085858381811061128f5761128f612900565b6112a59260206040909202019081019150612451565b905060008686848181106112bb576112bb612900565b90506040020160200160208101906112d3919061234d565b90506112ea6112e28383611841565b600490611908565b611348576040517f4964779000000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8316600482015273ffffffffffffffffffffffffffffffffffffffff82166024820152604401610531565b60405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa823809efda3ba66c873364eec120fa0923d9fabda73bc97dd5663341e2d9bcb9060200160405180910390a25050600101611273565b5060005b818110156114875760008383838181106113c7576113c7612900565b6113dd9260206040909202019081019150612451565b905060008484848181106113f3576113f3612900565b905060400201602001602081019061140b919061234d565b905061142261141a8383611841565b600490611914565b1561147d5760405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa4bdf64ebdf3316320601a081916a75aa144bcef6c4beeb0e9fb1982cacc6b949060200160405180910390a25b50506001016113ab565b50505050505050565b6114986116ea565b6114a181611920565b50565b60606114de8267ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b6114f8576040805160008082526020820190925290611184565b67ffffffffffffffff8216600081815260036020526040908190205490517ffbca3b74000000000000000000000000000000000000000000000000000000008152600481019290925273ffffffffffffffffffffffffffffffffffffffff169063fbca3b7490602401600060405180830381865afa15801561157e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d391908101906129db565b6000606060008361ffff1667ffffffffffffffff8111156115e7576115e7611f6c565b6040519080825280601f01601f191660200182016040528015611611576020820181803683370190505b509150863b611644577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015611677577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b85900360408104810387106116b0577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156116d35750835b808352806000602085013e50955095509592505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461176b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610531565b565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109ce9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611a15565b6000610ae773ffffffffffffffffffffffffffffffffffffffff83167bffffffffffffffff000000000000000000000000000000000000000060a086901b16612a99565b60008181526001830160205260408120541515610ae7565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109a79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016117bf565b60606000610ae783611b21565b6000610ae78383611b7d565b6000610ae78383611c70565b3373ffffffffffffffffffffffffffffffffffffffff82160361199f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610531565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611a77826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611cbf9092919063ffffffff16565b8051909150156109ce5780806020019051810190611a9591906126c5565b6109ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610531565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b7157602002820191906000526020600020905b815481526020019060010190808311611b5d575b50505050509050919050565b60008181526001830160205260408120548015611c66576000611ba1600183612aac565b8554909150600090611bb590600190612aac565b9050818114611c1a576000866000018281548110611bd557611bd5612900565b9060005260206000200154905080876000018481548110611bf857611bf8612900565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611c2b57611c2b612abf565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105d3565b60009150506105d3565b6000818152600183016020526040812054611cb7575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105d3565b5060006105d3565b6060611cce8484600085611cd6565b949350505050565b606082471015611d68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610531565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611d919190612aee565b60006040518083038185875af1925050503d8060008114611dce576040519150601f19603f3d011682016040523d82523d6000602084013e611dd3565b606091505b5091509150611de487838387611def565b979650505050505050565b60608315611e85578251600003611e7e5773ffffffffffffffffffffffffffffffffffffffff85163b611e7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610531565b5081611cce565b611cce8383815115611e9a5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105319190611f3c565b60005b83811015611ee9578181015183820152602001611ed1565b50506000910152565b60008151808452611f0a816020860160208601611ece565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ae76020830184611ef2565b803567ffffffffffffffff81168114611f6757600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611fbe57611fbe611f6c565b60405290565b60405160a0810167ffffffffffffffff81118282101715611fbe57611fbe611f6c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561202e5761202e611f6c565b604052919050565b600082601f83011261204757600080fd5b813567ffffffffffffffff81111561206157612061611f6c565b61209260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611fe7565b8181528460208386010111156120a757600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff8211156120de576120de611f6c565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146114a157600080fd5b8035611f67816120e8565b600082601f83011261212657600080fd5b8135602061213b612136836120c4565b611fe7565b82815260069290921b8401810191818101908684111561215a57600080fd5b8286015b848110156121a257604081890312156121775760008081fd5b61217f611f9b565b813561218a816120e8565b8152818501358582015283529183019160400161215e565b509695505050505050565b600080604083850312156121c057600080fd5b6121c983611f4f565b9150602083013567ffffffffffffffff808211156121e657600080fd5b9084019060a082870312156121fa57600080fd5b612202611fc4565b82358281111561221157600080fd5b61221d88828601612036565b82525060208301358281111561223257600080fd5b61223e88828601612036565b60208301525060408301358281111561225657600080fd5b61226288828601612115565b6040830152506122746060840161210a565b606082015260808301358281111561228b57600080fd5b61229788828601612036565b6080830152508093505050509250929050565b600080600080608085870312156122c057600080fd5b843567ffffffffffffffff8111156122d757600080fd5b850160a081880312156122e957600080fd5b9350602085013561ffff8116811461230057600080fd5b9250604085013591506060850135612317816120e8565b939692955090935050565b831515815260606020820152600061233d6060830185611ef2565b9050826040830152949350505050565b60006020828403121561235f57600080fd5b8135610ae7816120e8565b60008060006060848603121561237f57600080fd5b833561238a816120e8565b9250602084013561239a816120e8565b929592945050506040919091013590565b600080604083850312156123be57600080fd5b6123c783611f4f565b915060208301356123d7816120e8565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b82811015612444578151805167ffffffffffffffff16855286015173ffffffffffffffffffffffffffffffffffffffff168685015292840192908501906001016123ff565b5091979650505050505050565b60006020828403121561246357600080fd5b610ae782611f4f565b60008083601f84011261247e57600080fd5b50813567ffffffffffffffff81111561249657600080fd5b6020830191508360208260061b85010111156124b157600080fd5b9250929050565b600080600080600080606087890312156124d157600080fd5b863567ffffffffffffffff808211156124e957600080fd5b6124f58a838b0161246c565b9098509650602089013591508082111561250e57600080fd5b61251a8a838b0161246c565b9096509450604089013591508082111561253357600080fd5b5061254089828a0161246c565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b818110156125a057835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161256e565b50909695505050505050565b6000815160a084526125c160a0850182611ef2565b9050602080840151858303828701526125da8382611ef2565b60408681015188830389830152805180845290850195509092506000918401905b8083101561263a578551805173ffffffffffffffffffffffffffffffffffffffff168352850151858301529484019460019290920191908301906125fb565b5060608701519450612664606089018673ffffffffffffffffffffffffffffffffffffffff169052565b60808701519450878103608089015261267d8186611ef2565b98975050505050505050565b67ffffffffffffffff83168152604060208201526000611cce60408301846125ac565b6000602082840312156126be57600080fd5b5051919050565b6000602082840312156126d757600080fd5b81518015158114610ae757600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261271c57600080fd5b830160208101925035905067ffffffffffffffff81111561273c57600080fd5b8036038213156124b157600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156127e95781356127b7816120e8565b73ffffffffffffffffffffffffffffffffffffffff1687528183013583880152604096870196909101906001016127a4565b509495945050505050565b6020815281356020820152600061280d60208401611f4f565b67ffffffffffffffff808216604085015261282b60408601866126e7565b925060a0606086015261284260c08601848361274b565b92505061285260608601866126e7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08087860301608088015261288885838561274b565b9450608088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030183126128c157600080fd5b602092880192830192359150838211156128da57600080fd5b8160061b36038313156128ec57600080fd5b8685030160a0870152611de4848284612794565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561294157600080fd5b8151610ae7816120e8565b67ffffffffffffffff8516815260806020820152600061296f60808301866125ac565b905083604083015273ffffffffffffffffffffffffffffffffffffffff8316606083015295945050505050565b6000604082840312156129ae57600080fd5b6129b6611f9b565b6129bf83611f4f565b815260208301356129cf816120e8565b60208201529392505050565b600060208083850312156129ee57600080fd5b825167ffffffffffffffff811115612a0557600080fd5b8301601f81018513612a1657600080fd5b8051612a24612136826120c4565b81815260059190911b82018301908381019087831115612a4357600080fd5b928401925b82841015611de4578351612a5b816120e8565b82529284019290840190612a48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156105d3576105d3612a6a565b818103818111156105d3576105d3612a6a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251612b00818460208701611ece565b919091019291505056fea164736f6c6343000818000a", +} + +var RouterABI = RouterMetaData.ABI + +var RouterBin = RouterMetaData.Bin + +func DeployRouter(auth *bind.TransactOpts, backend bind.ContractBackend, wrappedNative common.Address, armProxy common.Address) (common.Address, *types.Transaction, *Router, error) { + parsed, err := RouterMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(RouterBin), backend, wrappedNative, armProxy) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Router{address: address, abi: *parsed, RouterCaller: RouterCaller{contract: contract}, RouterTransactor: RouterTransactor{contract: contract}, RouterFilterer: RouterFilterer{contract: contract}}, nil +} + +type Router struct { + address common.Address + abi abi.ABI + RouterCaller + RouterTransactor + RouterFilterer +} + +type RouterCaller struct { + contract *bind.BoundContract +} + +type RouterTransactor struct { + contract *bind.BoundContract +} + +type RouterFilterer struct { + contract *bind.BoundContract +} + +type RouterSession struct { + Contract *Router + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type RouterCallerSession struct { + Contract *RouterCaller + CallOpts bind.CallOpts +} + +type RouterTransactorSession struct { + Contract *RouterTransactor + TransactOpts bind.TransactOpts +} + +type RouterRaw struct { + Contract *Router +} + +type RouterCallerRaw struct { + Contract *RouterCaller +} + +type RouterTransactorRaw struct { + Contract *RouterTransactor +} + +func NewRouter(address common.Address, backend bind.ContractBackend) (*Router, error) { + abi, err := abi.JSON(strings.NewReader(RouterABI)) + if err != nil { + return nil, err + } + contract, err := bindRouter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Router{address: address, abi: abi, RouterCaller: RouterCaller{contract: contract}, RouterTransactor: RouterTransactor{contract: contract}, RouterFilterer: RouterFilterer{contract: contract}}, nil +} + +func NewRouterCaller(address common.Address, caller bind.ContractCaller) (*RouterCaller, error) { + contract, err := bindRouter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &RouterCaller{contract: contract}, nil +} + +func NewRouterTransactor(address common.Address, transactor bind.ContractTransactor) (*RouterTransactor, error) { + contract, err := bindRouter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &RouterTransactor{contract: contract}, nil +} + +func NewRouterFilterer(address common.Address, filterer bind.ContractFilterer) (*RouterFilterer, error) { + contract, err := bindRouter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &RouterFilterer{contract: contract}, nil +} + +func bindRouter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := RouterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_Router *RouterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Router.Contract.RouterCaller.contract.Call(opts, result, method, params...) +} + +func (_Router *RouterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Router.Contract.RouterTransactor.contract.Transfer(opts) +} + +func (_Router *RouterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Router.Contract.RouterTransactor.contract.Transact(opts, method, params...) +} + +func (_Router *RouterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Router.Contract.contract.Call(opts, result, method, params...) +} + +func (_Router *RouterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Router.Contract.contract.Transfer(opts) +} + +func (_Router *RouterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Router.Contract.contract.Transact(opts, method, params...) +} + +func (_Router *RouterCaller) MAXRETBYTES(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "MAX_RET_BYTES") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +func (_Router *RouterSession) MAXRETBYTES() (uint16, error) { + return _Router.Contract.MAXRETBYTES(&_Router.CallOpts) +} + +func (_Router *RouterCallerSession) MAXRETBYTES() (uint16, error) { + return _Router.Contract.MAXRETBYTES(&_Router.CallOpts) +} + +func (_Router *RouterCaller) GetArmProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "getArmProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_Router *RouterSession) GetArmProxy() (common.Address, error) { + return _Router.Contract.GetArmProxy(&_Router.CallOpts) +} + +func (_Router *RouterCallerSession) GetArmProxy() (common.Address, error) { + return _Router.Contract.GetArmProxy(&_Router.CallOpts) +} + +func (_Router *RouterCaller) GetFee(opts *bind.CallOpts, destinationChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "getFee", destinationChainSelector, message) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_Router *RouterSession) GetFee(destinationChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _Router.Contract.GetFee(&_Router.CallOpts, destinationChainSelector, message) +} + +func (_Router *RouterCallerSession) GetFee(destinationChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _Router.Contract.GetFee(&_Router.CallOpts, destinationChainSelector, message) +} + +func (_Router *RouterCaller) GetOffRamps(opts *bind.CallOpts) ([]RouterOffRamp, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "getOffRamps") + + if err != nil { + return *new([]RouterOffRamp), err + } + + out0 := *abi.ConvertType(out[0], new([]RouterOffRamp)).(*[]RouterOffRamp) + + return out0, err + +} + +func (_Router *RouterSession) GetOffRamps() ([]RouterOffRamp, error) { + return _Router.Contract.GetOffRamps(&_Router.CallOpts) +} + +func (_Router *RouterCallerSession) GetOffRamps() ([]RouterOffRamp, error) { + return _Router.Contract.GetOffRamps(&_Router.CallOpts) +} + +func (_Router *RouterCaller) GetOnRamp(opts *bind.CallOpts, destChainSelector uint64) (common.Address, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "getOnRamp", destChainSelector) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_Router *RouterSession) GetOnRamp(destChainSelector uint64) (common.Address, error) { + return _Router.Contract.GetOnRamp(&_Router.CallOpts, destChainSelector) +} + +func (_Router *RouterCallerSession) GetOnRamp(destChainSelector uint64) (common.Address, error) { + return _Router.Contract.GetOnRamp(&_Router.CallOpts, destChainSelector) +} + +func (_Router *RouterCaller) GetSupportedTokens(opts *bind.CallOpts, chainSelector uint64) ([]common.Address, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "getSupportedTokens", chainSelector) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_Router *RouterSession) GetSupportedTokens(chainSelector uint64) ([]common.Address, error) { + return _Router.Contract.GetSupportedTokens(&_Router.CallOpts, chainSelector) +} + +func (_Router *RouterCallerSession) GetSupportedTokens(chainSelector uint64) ([]common.Address, error) { + return _Router.Contract.GetSupportedTokens(&_Router.CallOpts, chainSelector) +} + +func (_Router *RouterCaller) GetWrappedNative(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "getWrappedNative") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_Router *RouterSession) GetWrappedNative() (common.Address, error) { + return _Router.Contract.GetWrappedNative(&_Router.CallOpts) +} + +func (_Router *RouterCallerSession) GetWrappedNative() (common.Address, error) { + return _Router.Contract.GetWrappedNative(&_Router.CallOpts) +} + +func (_Router *RouterCaller) IsChainSupported(opts *bind.CallOpts, chainSelector uint64) (bool, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "isChainSupported", chainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_Router *RouterSession) IsChainSupported(chainSelector uint64) (bool, error) { + return _Router.Contract.IsChainSupported(&_Router.CallOpts, chainSelector) +} + +func (_Router *RouterCallerSession) IsChainSupported(chainSelector uint64) (bool, error) { + return _Router.Contract.IsChainSupported(&_Router.CallOpts, chainSelector) +} + +func (_Router *RouterCaller) IsOffRamp(opts *bind.CallOpts, sourceChainSelector uint64, offRamp common.Address) (bool, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "isOffRamp", sourceChainSelector, offRamp) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_Router *RouterSession) IsOffRamp(sourceChainSelector uint64, offRamp common.Address) (bool, error) { + return _Router.Contract.IsOffRamp(&_Router.CallOpts, sourceChainSelector, offRamp) +} + +func (_Router *RouterCallerSession) IsOffRamp(sourceChainSelector uint64, offRamp common.Address) (bool, error) { + return _Router.Contract.IsOffRamp(&_Router.CallOpts, sourceChainSelector, offRamp) +} + +func (_Router *RouterCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_Router *RouterSession) Owner() (common.Address, error) { + return _Router.Contract.Owner(&_Router.CallOpts) +} + +func (_Router *RouterCallerSession) Owner() (common.Address, error) { + return _Router.Contract.Owner(&_Router.CallOpts) +} + +func (_Router *RouterCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_Router *RouterSession) TypeAndVersion() (string, error) { + return _Router.Contract.TypeAndVersion(&_Router.CallOpts) +} + +func (_Router *RouterCallerSession) TypeAndVersion() (string, error) { + return _Router.Contract.TypeAndVersion(&_Router.CallOpts) +} + +func (_Router *RouterTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "acceptOwnership") +} + +func (_Router *RouterSession) AcceptOwnership() (*types.Transaction, error) { + return _Router.Contract.AcceptOwnership(&_Router.TransactOpts) +} + +func (_Router *RouterTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _Router.Contract.AcceptOwnership(&_Router.TransactOpts) +} + +func (_Router *RouterTransactor) ApplyRampUpdates(opts *bind.TransactOpts, onRampUpdates []RouterOnRamp, offRampRemoves []RouterOffRamp, offRampAdds []RouterOffRamp) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "applyRampUpdates", onRampUpdates, offRampRemoves, offRampAdds) +} + +func (_Router *RouterSession) ApplyRampUpdates(onRampUpdates []RouterOnRamp, offRampRemoves []RouterOffRamp, offRampAdds []RouterOffRamp) (*types.Transaction, error) { + return _Router.Contract.ApplyRampUpdates(&_Router.TransactOpts, onRampUpdates, offRampRemoves, offRampAdds) +} + +func (_Router *RouterTransactorSession) ApplyRampUpdates(onRampUpdates []RouterOnRamp, offRampRemoves []RouterOffRamp, offRampAdds []RouterOffRamp) (*types.Transaction, error) { + return _Router.Contract.ApplyRampUpdates(&_Router.TransactOpts, onRampUpdates, offRampRemoves, offRampAdds) +} + +func (_Router *RouterTransactor) CcipSend(opts *bind.TransactOpts, destinationChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "ccipSend", destinationChainSelector, message) +} + +func (_Router *RouterSession) CcipSend(destinationChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) { + return _Router.Contract.CcipSend(&_Router.TransactOpts, destinationChainSelector, message) +} + +func (_Router *RouterTransactorSession) CcipSend(destinationChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) { + return _Router.Contract.CcipSend(&_Router.TransactOpts, destinationChainSelector, message) +} + +func (_Router *RouterTransactor) RecoverTokens(opts *bind.TransactOpts, tokenAddress common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "recoverTokens", tokenAddress, to, amount) +} + +func (_Router *RouterSession) RecoverTokens(tokenAddress common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _Router.Contract.RecoverTokens(&_Router.TransactOpts, tokenAddress, to, amount) +} + +func (_Router *RouterTransactorSession) RecoverTokens(tokenAddress common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _Router.Contract.RecoverTokens(&_Router.TransactOpts, tokenAddress, to, amount) +} + +func (_Router *RouterTransactor) RouteMessage(opts *bind.TransactOpts, message ClientAny2EVMMessage, gasForCallExactCheck uint16, gasLimit *big.Int, receiver common.Address) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "routeMessage", message, gasForCallExactCheck, gasLimit, receiver) +} + +func (_Router *RouterSession) RouteMessage(message ClientAny2EVMMessage, gasForCallExactCheck uint16, gasLimit *big.Int, receiver common.Address) (*types.Transaction, error) { + return _Router.Contract.RouteMessage(&_Router.TransactOpts, message, gasForCallExactCheck, gasLimit, receiver) +} + +func (_Router *RouterTransactorSession) RouteMessage(message ClientAny2EVMMessage, gasForCallExactCheck uint16, gasLimit *big.Int, receiver common.Address) (*types.Transaction, error) { + return _Router.Contract.RouteMessage(&_Router.TransactOpts, message, gasForCallExactCheck, gasLimit, receiver) +} + +func (_Router *RouterTransactor) SetWrappedNative(opts *bind.TransactOpts, wrappedNative common.Address) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "setWrappedNative", wrappedNative) +} + +func (_Router *RouterSession) SetWrappedNative(wrappedNative common.Address) (*types.Transaction, error) { + return _Router.Contract.SetWrappedNative(&_Router.TransactOpts, wrappedNative) +} + +func (_Router *RouterTransactorSession) SetWrappedNative(wrappedNative common.Address) (*types.Transaction, error) { + return _Router.Contract.SetWrappedNative(&_Router.TransactOpts, wrappedNative) +} + +func (_Router *RouterTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "transferOwnership", to) +} + +func (_Router *RouterSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _Router.Contract.TransferOwnership(&_Router.TransactOpts, to) +} + +func (_Router *RouterTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _Router.Contract.TransferOwnership(&_Router.TransactOpts, to) +} + +type RouterMessageExecutedIterator struct { + Event *RouterMessageExecuted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RouterMessageExecutedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RouterMessageExecuted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RouterMessageExecuted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RouterMessageExecutedIterator) Error() error { + return it.fail +} + +func (it *RouterMessageExecutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RouterMessageExecuted struct { + MessageId [32]byte + SourceChainSelector uint64 + OffRamp common.Address + CalldataHash [32]byte + Raw types.Log +} + +func (_Router *RouterFilterer) FilterMessageExecuted(opts *bind.FilterOpts) (*RouterMessageExecutedIterator, error) { + + logs, sub, err := _Router.contract.FilterLogs(opts, "MessageExecuted") + if err != nil { + return nil, err + } + return &RouterMessageExecutedIterator{contract: _Router.contract, event: "MessageExecuted", logs: logs, sub: sub}, nil +} + +func (_Router *RouterFilterer) WatchMessageExecuted(opts *bind.WatchOpts, sink chan<- *RouterMessageExecuted) (event.Subscription, error) { + + logs, sub, err := _Router.contract.WatchLogs(opts, "MessageExecuted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RouterMessageExecuted) + if err := _Router.contract.UnpackLog(event, "MessageExecuted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Router *RouterFilterer) ParseMessageExecuted(log types.Log) (*RouterMessageExecuted, error) { + event := new(RouterMessageExecuted) + if err := _Router.contract.UnpackLog(event, "MessageExecuted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RouterOffRampAddedIterator struct { + Event *RouterOffRampAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RouterOffRampAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RouterOffRampAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RouterOffRampAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RouterOffRampAddedIterator) Error() error { + return it.fail +} + +func (it *RouterOffRampAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RouterOffRampAdded struct { + SourceChainSelector uint64 + OffRamp common.Address + Raw types.Log +} + +func (_Router *RouterFilterer) FilterOffRampAdded(opts *bind.FilterOpts, sourceChainSelector []uint64) (*RouterOffRampAddedIterator, error) { + + var sourceChainSelectorRule []interface{} + for _, sourceChainSelectorItem := range sourceChainSelector { + sourceChainSelectorRule = append(sourceChainSelectorRule, sourceChainSelectorItem) + } + + logs, sub, err := _Router.contract.FilterLogs(opts, "OffRampAdded", sourceChainSelectorRule) + if err != nil { + return nil, err + } + return &RouterOffRampAddedIterator{contract: _Router.contract, event: "OffRampAdded", logs: logs, sub: sub}, nil +} + +func (_Router *RouterFilterer) WatchOffRampAdded(opts *bind.WatchOpts, sink chan<- *RouterOffRampAdded, sourceChainSelector []uint64) (event.Subscription, error) { + + var sourceChainSelectorRule []interface{} + for _, sourceChainSelectorItem := range sourceChainSelector { + sourceChainSelectorRule = append(sourceChainSelectorRule, sourceChainSelectorItem) + } + + logs, sub, err := _Router.contract.WatchLogs(opts, "OffRampAdded", sourceChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RouterOffRampAdded) + if err := _Router.contract.UnpackLog(event, "OffRampAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Router *RouterFilterer) ParseOffRampAdded(log types.Log) (*RouterOffRampAdded, error) { + event := new(RouterOffRampAdded) + if err := _Router.contract.UnpackLog(event, "OffRampAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RouterOffRampRemovedIterator struct { + Event *RouterOffRampRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RouterOffRampRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RouterOffRampRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RouterOffRampRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RouterOffRampRemovedIterator) Error() error { + return it.fail +} + +func (it *RouterOffRampRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RouterOffRampRemoved struct { + SourceChainSelector uint64 + OffRamp common.Address + Raw types.Log +} + +func (_Router *RouterFilterer) FilterOffRampRemoved(opts *bind.FilterOpts, sourceChainSelector []uint64) (*RouterOffRampRemovedIterator, error) { + + var sourceChainSelectorRule []interface{} + for _, sourceChainSelectorItem := range sourceChainSelector { + sourceChainSelectorRule = append(sourceChainSelectorRule, sourceChainSelectorItem) + } + + logs, sub, err := _Router.contract.FilterLogs(opts, "OffRampRemoved", sourceChainSelectorRule) + if err != nil { + return nil, err + } + return &RouterOffRampRemovedIterator{contract: _Router.contract, event: "OffRampRemoved", logs: logs, sub: sub}, nil +} + +func (_Router *RouterFilterer) WatchOffRampRemoved(opts *bind.WatchOpts, sink chan<- *RouterOffRampRemoved, sourceChainSelector []uint64) (event.Subscription, error) { + + var sourceChainSelectorRule []interface{} + for _, sourceChainSelectorItem := range sourceChainSelector { + sourceChainSelectorRule = append(sourceChainSelectorRule, sourceChainSelectorItem) + } + + logs, sub, err := _Router.contract.WatchLogs(opts, "OffRampRemoved", sourceChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RouterOffRampRemoved) + if err := _Router.contract.UnpackLog(event, "OffRampRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Router *RouterFilterer) ParseOffRampRemoved(log types.Log) (*RouterOffRampRemoved, error) { + event := new(RouterOffRampRemoved) + if err := _Router.contract.UnpackLog(event, "OffRampRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RouterOnRampSetIterator struct { + Event *RouterOnRampSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RouterOnRampSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RouterOnRampSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RouterOnRampSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RouterOnRampSetIterator) Error() error { + return it.fail +} + +func (it *RouterOnRampSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RouterOnRampSet struct { + DestChainSelector uint64 + OnRamp common.Address + Raw types.Log +} + +func (_Router *RouterFilterer) FilterOnRampSet(opts *bind.FilterOpts, destChainSelector []uint64) (*RouterOnRampSetIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _Router.contract.FilterLogs(opts, "OnRampSet", destChainSelectorRule) + if err != nil { + return nil, err + } + return &RouterOnRampSetIterator{contract: _Router.contract, event: "OnRampSet", logs: logs, sub: sub}, nil +} + +func (_Router *RouterFilterer) WatchOnRampSet(opts *bind.WatchOpts, sink chan<- *RouterOnRampSet, destChainSelector []uint64) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _Router.contract.WatchLogs(opts, "OnRampSet", destChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RouterOnRampSet) + if err := _Router.contract.UnpackLog(event, "OnRampSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Router *RouterFilterer) ParseOnRampSet(log types.Log) (*RouterOnRampSet, error) { + event := new(RouterOnRampSet) + if err := _Router.contract.UnpackLog(event, "OnRampSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RouterOwnershipTransferRequestedIterator struct { + Event *RouterOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RouterOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RouterOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RouterOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RouterOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *RouterOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RouterOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_Router *RouterFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RouterOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Router.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &RouterOwnershipTransferRequestedIterator{contract: _Router.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_Router *RouterFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *RouterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Router.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RouterOwnershipTransferRequested) + if err := _Router.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Router *RouterFilterer) ParseOwnershipTransferRequested(log types.Log) (*RouterOwnershipTransferRequested, error) { + event := new(RouterOwnershipTransferRequested) + if err := _Router.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RouterOwnershipTransferredIterator struct { + Event *RouterOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RouterOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RouterOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RouterOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RouterOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *RouterOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RouterOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_Router *RouterFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RouterOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Router.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &RouterOwnershipTransferredIterator{contract: _Router.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_Router *RouterFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *RouterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Router.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RouterOwnershipTransferred) + if err := _Router.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Router *RouterFilterer) ParseOwnershipTransferred(log types.Log) (*RouterOwnershipTransferred, error) { + event := new(RouterOwnershipTransferred) + if err := _Router.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_Router *Router) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _Router.abi.Events["MessageExecuted"].ID: + return _Router.ParseMessageExecuted(log) + case _Router.abi.Events["OffRampAdded"].ID: + return _Router.ParseOffRampAdded(log) + case _Router.abi.Events["OffRampRemoved"].ID: + return _Router.ParseOffRampRemoved(log) + case _Router.abi.Events["OnRampSet"].ID: + return _Router.ParseOnRampSet(log) + case _Router.abi.Events["OwnershipTransferRequested"].ID: + return _Router.ParseOwnershipTransferRequested(log) + case _Router.abi.Events["OwnershipTransferred"].ID: + return _Router.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (RouterMessageExecuted) Topic() common.Hash { + return common.HexToHash("0x9b877de93ea9895756e337442c657f95a34fc68e7eb988bdfa693d5be83016b6") +} + +func (RouterOffRampAdded) Topic() common.Hash { + return common.HexToHash("0xa4bdf64ebdf3316320601a081916a75aa144bcef6c4beeb0e9fb1982cacc6b94") +} + +func (RouterOffRampRemoved) Topic() common.Hash { + return common.HexToHash("0xa823809efda3ba66c873364eec120fa0923d9fabda73bc97dd5663341e2d9bcb") +} + +func (RouterOnRampSet) Topic() common.Hash { + return common.HexToHash("0x1f7d0ec248b80e5c0dde0ee531c4fc8fdb6ce9a2b3d90f560c74acd6a7202f23") +} + +func (RouterOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (RouterOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_Router *Router) Address() common.Address { + return _Router.address +} + +type RouterInterface interface { + MAXRETBYTES(opts *bind.CallOpts) (uint16, error) + + GetArmProxy(opts *bind.CallOpts) (common.Address, error) + + GetFee(opts *bind.CallOpts, destinationChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) + + GetOffRamps(opts *bind.CallOpts) ([]RouterOffRamp, error) + + GetOnRamp(opts *bind.CallOpts, destChainSelector uint64) (common.Address, error) + + GetSupportedTokens(opts *bind.CallOpts, chainSelector uint64) ([]common.Address, error) + + GetWrappedNative(opts *bind.CallOpts) (common.Address, error) + + IsChainSupported(opts *bind.CallOpts, chainSelector uint64) (bool, error) + + IsOffRamp(opts *bind.CallOpts, sourceChainSelector uint64, offRamp common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyRampUpdates(opts *bind.TransactOpts, onRampUpdates []RouterOnRamp, offRampRemoves []RouterOffRamp, offRampAdds []RouterOffRamp) (*types.Transaction, error) + + CcipSend(opts *bind.TransactOpts, destinationChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) + + RecoverTokens(opts *bind.TransactOpts, tokenAddress common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) + + RouteMessage(opts *bind.TransactOpts, message ClientAny2EVMMessage, gasForCallExactCheck uint16, gasLimit *big.Int, receiver common.Address) (*types.Transaction, error) + + SetWrappedNative(opts *bind.TransactOpts, wrappedNative common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterMessageExecuted(opts *bind.FilterOpts) (*RouterMessageExecutedIterator, error) + + WatchMessageExecuted(opts *bind.WatchOpts, sink chan<- *RouterMessageExecuted) (event.Subscription, error) + + ParseMessageExecuted(log types.Log) (*RouterMessageExecuted, error) + + FilterOffRampAdded(opts *bind.FilterOpts, sourceChainSelector []uint64) (*RouterOffRampAddedIterator, error) + + WatchOffRampAdded(opts *bind.WatchOpts, sink chan<- *RouterOffRampAdded, sourceChainSelector []uint64) (event.Subscription, error) + + ParseOffRampAdded(log types.Log) (*RouterOffRampAdded, error) + + FilterOffRampRemoved(opts *bind.FilterOpts, sourceChainSelector []uint64) (*RouterOffRampRemovedIterator, error) + + WatchOffRampRemoved(opts *bind.WatchOpts, sink chan<- *RouterOffRampRemoved, sourceChainSelector []uint64) (event.Subscription, error) + + ParseOffRampRemoved(log types.Log) (*RouterOffRampRemoved, error) + + FilterOnRampSet(opts *bind.FilterOpts, destChainSelector []uint64) (*RouterOnRampSetIterator, error) + + WatchOnRampSet(opts *bind.WatchOpts, sink chan<- *RouterOnRampSet, destChainSelector []uint64) (event.Subscription, error) + + ParseOnRampSet(log types.Log) (*RouterOnRampSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RouterOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *RouterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*RouterOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RouterOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *RouterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*RouterOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/self_funded_ping_pong/self_funded_ping_pong.go b/core/gethwrappers/ccip/generated/self_funded_ping_pong/self_funded_ping_pong.go new file mode 100644 index 0000000000..d6e2db6bf3 --- /dev/null +++ b/core/gethwrappers/ccip/generated/self_funded_ping_pong/self_funded_ping_pong.go @@ -0,0 +1,1370 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package self_funded_ping_pong + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ClientAny2EVMMessage struct { + MessageId [32]byte + SourceChainSelector uint64 + Sender []byte + Data []byte + DestTokenAmounts []ClientEVMTokenAmount +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +var SelfFundedPingPongMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"roundTripsBeforeFunding\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"InvalidRouter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"countIncrBeforeFunding\",\"type\":\"uint8\"}],\"name\":\"CountIncrBeforeFundingSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Funded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Ping\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Pong\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"fundPingPong\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCountIncrBeforeFunding\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartChainSelector\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"countIncrBeforeFunding\",\"type\":\"uint8\"}],\"name\":\"setCountIncrBeforeFunding\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"counterpartChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"counterpartAddress\",\"type\":\"address\"}],\"name\":\"setCounterpart\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setCounterpartAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"setCounterpartChainSelector\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pause\",\"type\":\"bool\"}],\"name\":\"setPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startPingPong\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200182238038062001822833981016040819052620000349162000291565b828233806000846001600160a01b0381166200006b576040516335fdcccd60e21b8152600060048201526024015b60405180910390fd5b6001600160a01b039081166080528216620000c95760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604482015260640162000062565b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000fc57620000fc81620001cd565b50506002805460ff60a01b1916905550600380546001600160a01b0319166001600160a01b0383811691821790925560405163095ea7b360e01b8152918416600483015260001960248301529063095ea7b3906044016020604051808303816000875af115801562000172573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001989190620002ea565b505050806002620001aa919062000315565b600360146101000a81548160ff021916908360ff16021790555050505062000347565b336001600160a01b03821603620002275760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000062565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200028e57600080fd5b50565b600080600060608486031215620002a757600080fd5b8351620002b48162000278565b6020850151909350620002c78162000278565b604085015190925060ff81168114620002df57600080fd5b809150509250925092565b600060208284031215620002fd57600080fd5b815180151581146200030e57600080fd5b9392505050565b60ff81811683821602908116908181146200034057634e487b7160e01b600052601160045260246000fd5b5092915050565b6080516114aa62000378600039600081816102970152818161063f0152818161072c0152610c2201526114aa6000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c80638f491cba116100cd578063bee518a411610081578063e6c725f511610066578063e6c725f51461034d578063ef686d8e1461037d578063f2fde38b1461039057600080fd5b8063bee518a4146102f1578063ca709a251461032f57600080fd5b8063b0f479a1116100b2578063b0f479a114610295578063b187bd26146102bb578063b5a11011146102de57600080fd5b80638f491cba1461026f5780639d2aede51461028257600080fd5b80632874d8bf1161012457806379ba50971161010957806379ba50971461023657806385572ffb1461023e5780638da5cb5b1461025157600080fd5b80632874d8bf146101ef5780632b6e5d63146101f757600080fd5b806301ffc9a71461015657806316c38b3c1461017e578063181f5a77146101935780631892b906146101dc575b600080fd5b610169610164366004610e24565b6103a3565b60405190151581526020015b60405180910390f35b61019161018c366004610e6d565b61043c565b005b6101cf6040518060400160405280601881526020017f53656c6646756e64656450696e67506f6e6720312e322e30000000000000000081525081565b6040516101759190610ef3565b6101916101ea366004610f23565b61048e565b6101916104e9565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610175565b610191610525565b61019161024c366004610f3e565b610627565b60005473ffffffffffffffffffffffffffffffffffffffff16610211565b61019161027d366004610f79565b6106ac565b610191610290366004610fb4565b61088b565b7f0000000000000000000000000000000000000000000000000000000000000000610211565b60025474010000000000000000000000000000000000000000900460ff16610169565b6101916102ec366004610fd1565b6108da565b60015474010000000000000000000000000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff9091168152602001610175565b60035473ffffffffffffffffffffffffffffffffffffffff16610211565b60035474010000000000000000000000000000000000000000900460ff1660405160ff9091168152602001610175565b61019161038b366004611008565b61097c565b61019161039e366004610fb4565b610a04565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f85572ffb00000000000000000000000000000000000000000000000000000000148061043657507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b610444610a15565b6002805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b610496610a15565b6001805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104f1610a15565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556105236001610a96565b565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610698576040517fd7f733340000000000000000000000000000000000000000000000000000000081523360048201526024016105a2565b6106a96106a482611230565b610cd9565b50565b60035474010000000000000000000000000000000000000000900460ff1615806106f2575060035474010000000000000000000000000000000000000000900460ff1681105b156106fa5750565b6003546001906107259074010000000000000000000000000000000000000000900460ff16836112dd565b116106a9577f00000000000000000000000000000000000000000000000000000000000000006001546040517fa8d87a3b0000000000000000000000000000000000000000000000000000000081527401000000000000000000000000000000000000000090910467ffffffffffffffff16600482015273ffffffffffffffffffffffffffffffffffffffff919091169063a8d87a3b90602401602060405180830381865afa1580156107dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108009190611318565b73ffffffffffffffffffffffffffffffffffffffff1663eff7cc486040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561084757600080fd5b505af115801561085b573d6000803e3d6000fd5b50506040517f302777af5d26fab9dd5120c5f1307c65193ebc51daf33244ada4365fab10602c925060009150a150565b610893610a15565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6108e2610a15565b6001805467ffffffffffffffff90931674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909316929092179091556002805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055565b610984610a15565b600380547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000060ff8416908102919091179091556040519081527f4768dbf8645b24c54f2887651545d24f748c0d0d1d4c689eb810fb19f0befcf39060200160405180910390a150565b610a0c610a15565b6106a981610d2f565b60005473ffffffffffffffffffffffffffffffffffffffff163314610523576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105a2565b80600116600103610ad9576040518181527f48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f9060200160405180910390a1610b0d565b6040518181527f58b69f57828e6962d216502094c54f6562f3bf082ba758966c3454f9e37b15259060200160405180910390a15b610b16816106ac565b6040805160a0810190915260025473ffffffffffffffffffffffffffffffffffffffff1660c08201526000908060e08101604051602081830303815290604052815260200183604051602001610b6e91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905281526020016000604051908082528060200260200182016040528015610be857816020015b6040805180820190915260008082526020820152815260200190600190039081610bc15790505b50815260035473ffffffffffffffffffffffffffffffffffffffff16602080830191909152604080519182018152600082529091015290507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166396f4e9f9600160149054906101000a900467ffffffffffffffff16836040518363ffffffff1660e01b8152600401610c91929190611335565b6020604051808303816000875af1158015610cb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd4919061144a565b505050565b60008160600151806020019051810190610cf3919061144a565b60025490915074010000000000000000000000000000000000000000900460ff16610d2b57610d2b610d26826001611463565b610a96565b5050565b3373ffffffffffffffffffffffffffffffffffffffff821603610dae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105a2565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610e3657600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e6657600080fd5b9392505050565b600060208284031215610e7f57600080fd5b81358015158114610e6657600080fd5b6000815180845260005b81811015610eb557602081850181015186830182015201610e99565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610e666020830184610e8f565b803567ffffffffffffffff81168114610f1e57600080fd5b919050565b600060208284031215610f3557600080fd5b610e6682610f06565b600060208284031215610f5057600080fd5b813567ffffffffffffffff811115610f6757600080fd5b820160a08185031215610e6657600080fd5b600060208284031215610f8b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146106a957600080fd5b600060208284031215610fc657600080fd5b8135610e6681610f92565b60008060408385031215610fe457600080fd5b610fed83610f06565b91506020830135610ffd81610f92565b809150509250929050565b60006020828403121561101a57600080fd5b813560ff81168114610e6657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561107d5761107d61102b565b60405290565b60405160a0810167ffffffffffffffff8111828210171561107d5761107d61102b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156110ed576110ed61102b565b604052919050565b600082601f83011261110657600080fd5b813567ffffffffffffffff8111156111205761112061102b565b61115160207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016110a6565b81815284602083860101111561116657600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261119457600080fd5b8135602067ffffffffffffffff8211156111b0576111b061102b565b6111be818360051b016110a6565b82815260069290921b840181019181810190868411156111dd57600080fd5b8286015b8481101561122557604081890312156111fa5760008081fd5b61120261105a565b813561120d81610f92565b815281850135858201528352918301916040016111e1565b509695505050505050565b600060a0823603121561124257600080fd5b61124a611083565b8235815261125a60208401610f06565b6020820152604083013567ffffffffffffffff8082111561127a57600080fd5b611286368387016110f5565b6040840152606085013591508082111561129f57600080fd5b6112ab368387016110f5565b606084015260808501359150808211156112c457600080fd5b506112d136828601611183565b60808301525092915050565b600082611313577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b60006020828403121561132a57600080fd5b8151610e6681610f92565b6000604067ffffffffffffffff851683526020604081850152845160a0604086015261136460e0860182610e8f565b9050818601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087840301606088015261139f8383610e8f565b6040890151888203830160808a01528051808352908601945060009350908501905b80841015611400578451805173ffffffffffffffffffffffffffffffffffffffff168352860151868301529385019360019390930192908601906113c1565b50606089015173ffffffffffffffffffffffffffffffffffffffff1660a08901526080890151888203830160c08a0152955061143c8187610e8f565b9a9950505050505050505050565b60006020828403121561145c57600080fd5b5051919050565b80820180821115610436577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000818000a", +} + +var SelfFundedPingPongABI = SelfFundedPingPongMetaData.ABI + +var SelfFundedPingPongBin = SelfFundedPingPongMetaData.Bin + +func DeploySelfFundedPingPong(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address, feeToken common.Address, roundTripsBeforeFunding uint8) (common.Address, *types.Transaction, *SelfFundedPingPong, error) { + parsed, err := SelfFundedPingPongMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SelfFundedPingPongBin), backend, router, feeToken, roundTripsBeforeFunding) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &SelfFundedPingPong{address: address, abi: *parsed, SelfFundedPingPongCaller: SelfFundedPingPongCaller{contract: contract}, SelfFundedPingPongTransactor: SelfFundedPingPongTransactor{contract: contract}, SelfFundedPingPongFilterer: SelfFundedPingPongFilterer{contract: contract}}, nil +} + +type SelfFundedPingPong struct { + address common.Address + abi abi.ABI + SelfFundedPingPongCaller + SelfFundedPingPongTransactor + SelfFundedPingPongFilterer +} + +type SelfFundedPingPongCaller struct { + contract *bind.BoundContract +} + +type SelfFundedPingPongTransactor struct { + contract *bind.BoundContract +} + +type SelfFundedPingPongFilterer struct { + contract *bind.BoundContract +} + +type SelfFundedPingPongSession struct { + Contract *SelfFundedPingPong + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type SelfFundedPingPongCallerSession struct { + Contract *SelfFundedPingPongCaller + CallOpts bind.CallOpts +} + +type SelfFundedPingPongTransactorSession struct { + Contract *SelfFundedPingPongTransactor + TransactOpts bind.TransactOpts +} + +type SelfFundedPingPongRaw struct { + Contract *SelfFundedPingPong +} + +type SelfFundedPingPongCallerRaw struct { + Contract *SelfFundedPingPongCaller +} + +type SelfFundedPingPongTransactorRaw struct { + Contract *SelfFundedPingPongTransactor +} + +func NewSelfFundedPingPong(address common.Address, backend bind.ContractBackend) (*SelfFundedPingPong, error) { + abi, err := abi.JSON(strings.NewReader(SelfFundedPingPongABI)) + if err != nil { + return nil, err + } + contract, err := bindSelfFundedPingPong(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &SelfFundedPingPong{address: address, abi: abi, SelfFundedPingPongCaller: SelfFundedPingPongCaller{contract: contract}, SelfFundedPingPongTransactor: SelfFundedPingPongTransactor{contract: contract}, SelfFundedPingPongFilterer: SelfFundedPingPongFilterer{contract: contract}}, nil +} + +func NewSelfFundedPingPongCaller(address common.Address, caller bind.ContractCaller) (*SelfFundedPingPongCaller, error) { + contract, err := bindSelfFundedPingPong(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &SelfFundedPingPongCaller{contract: contract}, nil +} + +func NewSelfFundedPingPongTransactor(address common.Address, transactor bind.ContractTransactor) (*SelfFundedPingPongTransactor, error) { + contract, err := bindSelfFundedPingPong(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &SelfFundedPingPongTransactor{contract: contract}, nil +} + +func NewSelfFundedPingPongFilterer(address common.Address, filterer bind.ContractFilterer) (*SelfFundedPingPongFilterer, error) { + contract, err := bindSelfFundedPingPong(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &SelfFundedPingPongFilterer{contract: contract}, nil +} + +func bindSelfFundedPingPong(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := SelfFundedPingPongMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SelfFundedPingPong.Contract.SelfFundedPingPongCaller.contract.Call(opts, result, method, params...) +} + +func (_SelfFundedPingPong *SelfFundedPingPongRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SelfFundedPingPongTransactor.contract.Transfer(opts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SelfFundedPingPongTransactor.contract.Transact(opts, method, params...) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SelfFundedPingPong.Contract.contract.Call(opts, result, method, params...) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.contract.Transfer(opts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.contract.Transact(opts, method, params...) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCaller) GetCountIncrBeforeFunding(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _SelfFundedPingPong.contract.Call(opts, &out, "getCountIncrBeforeFunding") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) GetCountIncrBeforeFunding() (uint8, error) { + return _SelfFundedPingPong.Contract.GetCountIncrBeforeFunding(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCallerSession) GetCountIncrBeforeFunding() (uint8, error) { + return _SelfFundedPingPong.Contract.GetCountIncrBeforeFunding(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCaller) GetCounterpartAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SelfFundedPingPong.contract.Call(opts, &out, "getCounterpartAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) GetCounterpartAddress() (common.Address, error) { + return _SelfFundedPingPong.Contract.GetCounterpartAddress(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCallerSession) GetCounterpartAddress() (common.Address, error) { + return _SelfFundedPingPong.Contract.GetCounterpartAddress(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCaller) GetCounterpartChainSelector(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _SelfFundedPingPong.contract.Call(opts, &out, "getCounterpartChainSelector") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) GetCounterpartChainSelector() (uint64, error) { + return _SelfFundedPingPong.Contract.GetCounterpartChainSelector(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCallerSession) GetCounterpartChainSelector() (uint64, error) { + return _SelfFundedPingPong.Contract.GetCounterpartChainSelector(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCaller) GetFeeToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SelfFundedPingPong.contract.Call(opts, &out, "getFeeToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) GetFeeToken() (common.Address, error) { + return _SelfFundedPingPong.Contract.GetFeeToken(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCallerSession) GetFeeToken() (common.Address, error) { + return _SelfFundedPingPong.Contract.GetFeeToken(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SelfFundedPingPong.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) GetRouter() (common.Address, error) { + return _SelfFundedPingPong.Contract.GetRouter(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCallerSession) GetRouter() (common.Address, error) { + return _SelfFundedPingPong.Contract.GetRouter(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCaller) IsPaused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _SelfFundedPingPong.contract.Call(opts, &out, "isPaused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) IsPaused() (bool, error) { + return _SelfFundedPingPong.Contract.IsPaused(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCallerSession) IsPaused() (bool, error) { + return _SelfFundedPingPong.Contract.IsPaused(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SelfFundedPingPong.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) Owner() (common.Address, error) { + return _SelfFundedPingPong.Contract.Owner(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCallerSession) Owner() (common.Address, error) { + return _SelfFundedPingPong.Contract.Owner(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _SelfFundedPingPong.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _SelfFundedPingPong.Contract.SupportsInterface(&_SelfFundedPingPong.CallOpts, interfaceId) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _SelfFundedPingPong.Contract.SupportsInterface(&_SelfFundedPingPong.CallOpts, interfaceId) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _SelfFundedPingPong.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) TypeAndVersion() (string, error) { + return _SelfFundedPingPong.Contract.TypeAndVersion(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCallerSession) TypeAndVersion() (string, error) { + return _SelfFundedPingPong.Contract.TypeAndVersion(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SelfFundedPingPong.contract.Transact(opts, "acceptOwnership") +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) AcceptOwnership() (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.AcceptOwnership(&_SelfFundedPingPong.TransactOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.AcceptOwnership(&_SelfFundedPingPong.TransactOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactor) CcipReceive(opts *bind.TransactOpts, message ClientAny2EVMMessage) (*types.Transaction, error) { + return _SelfFundedPingPong.contract.Transact(opts, "ccipReceive", message) +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) CcipReceive(message ClientAny2EVMMessage) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.CcipReceive(&_SelfFundedPingPong.TransactOpts, message) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorSession) CcipReceive(message ClientAny2EVMMessage) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.CcipReceive(&_SelfFundedPingPong.TransactOpts, message) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactor) FundPingPong(opts *bind.TransactOpts, pingPongCount *big.Int) (*types.Transaction, error) { + return _SelfFundedPingPong.contract.Transact(opts, "fundPingPong", pingPongCount) +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) FundPingPong(pingPongCount *big.Int) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.FundPingPong(&_SelfFundedPingPong.TransactOpts, pingPongCount) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorSession) FundPingPong(pingPongCount *big.Int) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.FundPingPong(&_SelfFundedPingPong.TransactOpts, pingPongCount) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactor) SetCountIncrBeforeFunding(opts *bind.TransactOpts, countIncrBeforeFunding uint8) (*types.Transaction, error) { + return _SelfFundedPingPong.contract.Transact(opts, "setCountIncrBeforeFunding", countIncrBeforeFunding) +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) SetCountIncrBeforeFunding(countIncrBeforeFunding uint8) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SetCountIncrBeforeFunding(&_SelfFundedPingPong.TransactOpts, countIncrBeforeFunding) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorSession) SetCountIncrBeforeFunding(countIncrBeforeFunding uint8) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SetCountIncrBeforeFunding(&_SelfFundedPingPong.TransactOpts, countIncrBeforeFunding) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactor) SetCounterpart(opts *bind.TransactOpts, counterpartChainSelector uint64, counterpartAddress common.Address) (*types.Transaction, error) { + return _SelfFundedPingPong.contract.Transact(opts, "setCounterpart", counterpartChainSelector, counterpartAddress) +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) SetCounterpart(counterpartChainSelector uint64, counterpartAddress common.Address) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SetCounterpart(&_SelfFundedPingPong.TransactOpts, counterpartChainSelector, counterpartAddress) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorSession) SetCounterpart(counterpartChainSelector uint64, counterpartAddress common.Address) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SetCounterpart(&_SelfFundedPingPong.TransactOpts, counterpartChainSelector, counterpartAddress) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactor) SetCounterpartAddress(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _SelfFundedPingPong.contract.Transact(opts, "setCounterpartAddress", addr) +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) SetCounterpartAddress(addr common.Address) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SetCounterpartAddress(&_SelfFundedPingPong.TransactOpts, addr) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorSession) SetCounterpartAddress(addr common.Address) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SetCounterpartAddress(&_SelfFundedPingPong.TransactOpts, addr) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactor) SetCounterpartChainSelector(opts *bind.TransactOpts, chainSelector uint64) (*types.Transaction, error) { + return _SelfFundedPingPong.contract.Transact(opts, "setCounterpartChainSelector", chainSelector) +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) SetCounterpartChainSelector(chainSelector uint64) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SetCounterpartChainSelector(&_SelfFundedPingPong.TransactOpts, chainSelector) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorSession) SetCounterpartChainSelector(chainSelector uint64) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SetCounterpartChainSelector(&_SelfFundedPingPong.TransactOpts, chainSelector) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactor) SetPaused(opts *bind.TransactOpts, pause bool) (*types.Transaction, error) { + return _SelfFundedPingPong.contract.Transact(opts, "setPaused", pause) +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) SetPaused(pause bool) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SetPaused(&_SelfFundedPingPong.TransactOpts, pause) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorSession) SetPaused(pause bool) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SetPaused(&_SelfFundedPingPong.TransactOpts, pause) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactor) StartPingPong(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SelfFundedPingPong.contract.Transact(opts, "startPingPong") +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) StartPingPong() (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.StartPingPong(&_SelfFundedPingPong.TransactOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorSession) StartPingPong() (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.StartPingPong(&_SelfFundedPingPong.TransactOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _SelfFundedPingPong.contract.Transact(opts, "transferOwnership", to) +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.TransferOwnership(&_SelfFundedPingPong.TransactOpts, to) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.TransferOwnership(&_SelfFundedPingPong.TransactOpts, to) +} + +type SelfFundedPingPongCountIncrBeforeFundingSetIterator struct { + Event *SelfFundedPingPongCountIncrBeforeFundingSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *SelfFundedPingPongCountIncrBeforeFundingSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongCountIncrBeforeFundingSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongCountIncrBeforeFundingSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *SelfFundedPingPongCountIncrBeforeFundingSetIterator) Error() error { + return it.fail +} + +func (it *SelfFundedPingPongCountIncrBeforeFundingSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type SelfFundedPingPongCountIncrBeforeFundingSet struct { + CountIncrBeforeFunding uint8 + Raw types.Log +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) FilterCountIncrBeforeFundingSet(opts *bind.FilterOpts) (*SelfFundedPingPongCountIncrBeforeFundingSetIterator, error) { + + logs, sub, err := _SelfFundedPingPong.contract.FilterLogs(opts, "CountIncrBeforeFundingSet") + if err != nil { + return nil, err + } + return &SelfFundedPingPongCountIncrBeforeFundingSetIterator{contract: _SelfFundedPingPong.contract, event: "CountIncrBeforeFundingSet", logs: logs, sub: sub}, nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) WatchCountIncrBeforeFundingSet(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongCountIncrBeforeFundingSet) (event.Subscription, error) { + + logs, sub, err := _SelfFundedPingPong.contract.WatchLogs(opts, "CountIncrBeforeFundingSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(SelfFundedPingPongCountIncrBeforeFundingSet) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "CountIncrBeforeFundingSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) ParseCountIncrBeforeFundingSet(log types.Log) (*SelfFundedPingPongCountIncrBeforeFundingSet, error) { + event := new(SelfFundedPingPongCountIncrBeforeFundingSet) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "CountIncrBeforeFundingSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type SelfFundedPingPongFundedIterator struct { + Event *SelfFundedPingPongFunded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *SelfFundedPingPongFundedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongFunded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongFunded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *SelfFundedPingPongFundedIterator) Error() error { + return it.fail +} + +func (it *SelfFundedPingPongFundedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type SelfFundedPingPongFunded struct { + Raw types.Log +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) FilterFunded(opts *bind.FilterOpts) (*SelfFundedPingPongFundedIterator, error) { + + logs, sub, err := _SelfFundedPingPong.contract.FilterLogs(opts, "Funded") + if err != nil { + return nil, err + } + return &SelfFundedPingPongFundedIterator{contract: _SelfFundedPingPong.contract, event: "Funded", logs: logs, sub: sub}, nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) WatchFunded(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongFunded) (event.Subscription, error) { + + logs, sub, err := _SelfFundedPingPong.contract.WatchLogs(opts, "Funded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(SelfFundedPingPongFunded) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "Funded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) ParseFunded(log types.Log) (*SelfFundedPingPongFunded, error) { + event := new(SelfFundedPingPongFunded) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "Funded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type SelfFundedPingPongOwnershipTransferRequestedIterator struct { + Event *SelfFundedPingPongOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *SelfFundedPingPongOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *SelfFundedPingPongOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *SelfFundedPingPongOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type SelfFundedPingPongOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*SelfFundedPingPongOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _SelfFundedPingPong.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &SelfFundedPingPongOwnershipTransferRequestedIterator{contract: _SelfFundedPingPong.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _SelfFundedPingPong.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(SelfFundedPingPongOwnershipTransferRequested) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) ParseOwnershipTransferRequested(log types.Log) (*SelfFundedPingPongOwnershipTransferRequested, error) { + event := new(SelfFundedPingPongOwnershipTransferRequested) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type SelfFundedPingPongOwnershipTransferredIterator struct { + Event *SelfFundedPingPongOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *SelfFundedPingPongOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *SelfFundedPingPongOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *SelfFundedPingPongOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type SelfFundedPingPongOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*SelfFundedPingPongOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _SelfFundedPingPong.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &SelfFundedPingPongOwnershipTransferredIterator{contract: _SelfFundedPingPong.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _SelfFundedPingPong.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(SelfFundedPingPongOwnershipTransferred) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) ParseOwnershipTransferred(log types.Log) (*SelfFundedPingPongOwnershipTransferred, error) { + event := new(SelfFundedPingPongOwnershipTransferred) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type SelfFundedPingPongPingIterator struct { + Event *SelfFundedPingPongPing + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *SelfFundedPingPongPingIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongPing) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongPing) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *SelfFundedPingPongPingIterator) Error() error { + return it.fail +} + +func (it *SelfFundedPingPongPingIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type SelfFundedPingPongPing struct { + PingPongCount *big.Int + Raw types.Log +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) FilterPing(opts *bind.FilterOpts) (*SelfFundedPingPongPingIterator, error) { + + logs, sub, err := _SelfFundedPingPong.contract.FilterLogs(opts, "Ping") + if err != nil { + return nil, err + } + return &SelfFundedPingPongPingIterator{contract: _SelfFundedPingPong.contract, event: "Ping", logs: logs, sub: sub}, nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) WatchPing(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongPing) (event.Subscription, error) { + + logs, sub, err := _SelfFundedPingPong.contract.WatchLogs(opts, "Ping") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(SelfFundedPingPongPing) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "Ping", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) ParsePing(log types.Log) (*SelfFundedPingPongPing, error) { + event := new(SelfFundedPingPongPing) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "Ping", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type SelfFundedPingPongPongIterator struct { + Event *SelfFundedPingPongPong + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *SelfFundedPingPongPongIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongPong) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongPong) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *SelfFundedPingPongPongIterator) Error() error { + return it.fail +} + +func (it *SelfFundedPingPongPongIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type SelfFundedPingPongPong struct { + PingPongCount *big.Int + Raw types.Log +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) FilterPong(opts *bind.FilterOpts) (*SelfFundedPingPongPongIterator, error) { + + logs, sub, err := _SelfFundedPingPong.contract.FilterLogs(opts, "Pong") + if err != nil { + return nil, err + } + return &SelfFundedPingPongPongIterator{contract: _SelfFundedPingPong.contract, event: "Pong", logs: logs, sub: sub}, nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) WatchPong(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongPong) (event.Subscription, error) { + + logs, sub, err := _SelfFundedPingPong.contract.WatchLogs(opts, "Pong") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(SelfFundedPingPongPong) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "Pong", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) ParsePong(log types.Log) (*SelfFundedPingPongPong, error) { + event := new(SelfFundedPingPongPong) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "Pong", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_SelfFundedPingPong *SelfFundedPingPong) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _SelfFundedPingPong.abi.Events["CountIncrBeforeFundingSet"].ID: + return _SelfFundedPingPong.ParseCountIncrBeforeFundingSet(log) + case _SelfFundedPingPong.abi.Events["Funded"].ID: + return _SelfFundedPingPong.ParseFunded(log) + case _SelfFundedPingPong.abi.Events["OwnershipTransferRequested"].ID: + return _SelfFundedPingPong.ParseOwnershipTransferRequested(log) + case _SelfFundedPingPong.abi.Events["OwnershipTransferred"].ID: + return _SelfFundedPingPong.ParseOwnershipTransferred(log) + case _SelfFundedPingPong.abi.Events["Ping"].ID: + return _SelfFundedPingPong.ParsePing(log) + case _SelfFundedPingPong.abi.Events["Pong"].ID: + return _SelfFundedPingPong.ParsePong(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (SelfFundedPingPongCountIncrBeforeFundingSet) Topic() common.Hash { + return common.HexToHash("0x4768dbf8645b24c54f2887651545d24f748c0d0d1d4c689eb810fb19f0befcf3") +} + +func (SelfFundedPingPongFunded) Topic() common.Hash { + return common.HexToHash("0x302777af5d26fab9dd5120c5f1307c65193ebc51daf33244ada4365fab10602c") +} + +func (SelfFundedPingPongOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (SelfFundedPingPongOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (SelfFundedPingPongPing) Topic() common.Hash { + return common.HexToHash("0x48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f") +} + +func (SelfFundedPingPongPong) Topic() common.Hash { + return common.HexToHash("0x58b69f57828e6962d216502094c54f6562f3bf082ba758966c3454f9e37b1525") +} + +func (_SelfFundedPingPong *SelfFundedPingPong) Address() common.Address { + return _SelfFundedPingPong.address +} + +type SelfFundedPingPongInterface interface { + GetCountIncrBeforeFunding(opts *bind.CallOpts) (uint8, error) + + GetCounterpartAddress(opts *bind.CallOpts) (common.Address, error) + + GetCounterpartChainSelector(opts *bind.CallOpts) (uint64, error) + + GetFeeToken(opts *bind.CallOpts) (common.Address, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + IsPaused(opts *bind.CallOpts) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + CcipReceive(opts *bind.TransactOpts, message ClientAny2EVMMessage) (*types.Transaction, error) + + FundPingPong(opts *bind.TransactOpts, pingPongCount *big.Int) (*types.Transaction, error) + + SetCountIncrBeforeFunding(opts *bind.TransactOpts, countIncrBeforeFunding uint8) (*types.Transaction, error) + + SetCounterpart(opts *bind.TransactOpts, counterpartChainSelector uint64, counterpartAddress common.Address) (*types.Transaction, error) + + SetCounterpartAddress(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) + + SetCounterpartChainSelector(opts *bind.TransactOpts, chainSelector uint64) (*types.Transaction, error) + + SetPaused(opts *bind.TransactOpts, pause bool) (*types.Transaction, error) + + StartPingPong(opts *bind.TransactOpts) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterCountIncrBeforeFundingSet(opts *bind.FilterOpts) (*SelfFundedPingPongCountIncrBeforeFundingSetIterator, error) + + WatchCountIncrBeforeFundingSet(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongCountIncrBeforeFundingSet) (event.Subscription, error) + + ParseCountIncrBeforeFundingSet(log types.Log) (*SelfFundedPingPongCountIncrBeforeFundingSet, error) + + FilterFunded(opts *bind.FilterOpts) (*SelfFundedPingPongFundedIterator, error) + + WatchFunded(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongFunded) (event.Subscription, error) + + ParseFunded(log types.Log) (*SelfFundedPingPongFunded, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*SelfFundedPingPongOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*SelfFundedPingPongOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*SelfFundedPingPongOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*SelfFundedPingPongOwnershipTransferred, error) + + FilterPing(opts *bind.FilterOpts) (*SelfFundedPingPongPingIterator, error) + + WatchPing(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongPing) (event.Subscription, error) + + ParsePing(log types.Log) (*SelfFundedPingPongPing, error) + + FilterPong(opts *bind.FilterOpts) (*SelfFundedPingPongPongIterator, error) + + WatchPong(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongPong) (event.Subscription, error) + + ParsePong(log types.Log) (*SelfFundedPingPongPong, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/token_admin_registry/token_admin_registry.go b/core/gethwrappers/ccip/generated/token_admin_registry/token_admin_registry.go new file mode 100644 index 0000000000..189b4b600b --- /dev/null +++ b/core/gethwrappers/ccip/generated/token_admin_registry/token_admin_registry.go @@ -0,0 +1,1795 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package token_admin_registry + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type TokenAdminRegistryTokenConfig struct { + Administrator common.Address + PendingAdministrator common.Address + TokenPool common.Address +} + +var TokenAdminRegistryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"AlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidTokenPoolToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"OnlyAdministrator\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"OnlyPendingAdministrator\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"OnlyRegistryModuleOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"currentAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdministratorTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdministratorTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"disabled\",\"type\":\"bool\"}],\"name\":\"DisableReRegistrationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousPool\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"PoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"RegistryModuleAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"RegistryModuleRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"RemovedAdministrator\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"acceptAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"addRegistryModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"startIndex\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxCount\",\"type\":\"uint64\"}],\"name\":\"getAllConfiguredTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getPools\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pendingAdministrator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenPool\",\"type\":\"address\"}],\"internalType\":\"structTokenAdminRegistry.TokenConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"}],\"name\":\"isAdministrator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"isRegistryModule\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"}],\"name\":\"proposeAdministrator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"removeRegistryModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"setPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611449806101576000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80637d3f255211610097578063cb67e3b111610066578063cb67e3b1146102bc578063ddadfa8e14610374578063e677ae3714610387578063f2fde38b1461039a57600080fd5b80637d3f2552146101e05780638da5cb5b14610203578063bbe4f6db14610242578063c1af6e031461027f57600080fd5b80634e847fc7116100d35780634e847fc7146101925780635e63547a146101a557806372d64a81146101c557806379ba5097146101d857600080fd5b806310cbcf1814610105578063156194da1461011a578063181f5a771461012d5780633dc457721461017f575b600080fd5b61011861011336600461116c565b6103ad565b005b61011861012836600461116c565b61040a565b6101696040518060400160405280601c81526020017f546f6b656e41646d696e526567697374727920312e352e302d6465760000000081525081565b6040516101769190611187565b60405180910390f35b61011861018d36600461116c565b61050f565b6101186101a03660046111f4565b610573565b6101b86101b3366004611227565b6107d3565b604051610176919061129c565b6101b86101d336600461130e565b6108cc565b6101186109e2565b6101f36101ee36600461116c565b610adf565b6040519015158152602001610176565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610176565b61021d61025036600461116c565b73ffffffffffffffffffffffffffffffffffffffff908116600090815260026020819052604090912001541690565b6101f361028d3660046111f4565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260026020526040902054821691161490565b6103356102ca36600461116c565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff948516815260028084529084902084519283018552805486168352600181015486169383019390935291909101549092169082015290565b60408051825173ffffffffffffffffffffffffffffffffffffffff90811682526020808501518216908301529282015190921690820152606001610176565b6101186103823660046111f4565b610aec565b6101186103953660046111f4565b610bf6565b6101186103a836600461116c565b610dbe565b6103b5610dcf565b6103c0600582610e52565b156104075760405173ffffffffffffffffffffffffffffffffffffffff8216907f93eaa26dcb9275e56bacb1d33fdbf402262da6f0f4baf2a6e2cd154b73f387f890600090a25b50565b73ffffffffffffffffffffffffffffffffffffffff808216600090815260026020526040902060018101549091163314610493576040517f3edffe7500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff831660248201526044015b60405180910390fd5b8054337fffffffffffffffffffffffff00000000000000000000000000000000000000009182168117835560018301805490921690915560405173ffffffffffffffffffffffffffffffffffffffff8416907f399b55200f7f639a63d76efe3dcfa9156ce367058d6b673041b84a628885f5a790600090a35050565b610517610dcf565b610522600582610e7b565b156104075760405173ffffffffffffffffffffffffffffffffffffffff821681527f3cabf004338366bfeaeb610ad827cb58d16b588017c509501f2c97c83caae7b29060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff80831660009081526002602052604090205483911633146105f3576040517fed5d85b500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161048a565b73ffffffffffffffffffffffffffffffffffffffff8216158015906106a557506040517f240028e800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283169063240028e890602401602060405180830381865afa15801561067f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a39190611338565b155b156106f4576040517f962b60e600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240161048a565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020819052604090912090810180548584167fffffffffffffffffffffffff0000000000000000000000000000000000000000821681179092559192919091169081146107cc578373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f754449ec3aff3bd528bfce43ae9319c4a381b67fcd1d20097b3b24dacaecc35d60405160405180910390a45b5050505050565b606060008267ffffffffffffffff8111156107f0576107f061135a565b604051908082528060200260200182016040528015610819578160200160208202803683370190505b50905060005b838110156108c2576002600086868481811061083d5761083d611389565b9050602002016020810190610852919061116c565b73ffffffffffffffffffffffffffffffffffffffff9081168252602082019290925260400160002060020154835191169083908390811061089557610895611389565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015260010161081f565b5090505b92915050565b606060006108da6003610e9d565b9050808467ffffffffffffffff16106108f357506108c6565b67ffffffffffffffff80841690829061090e908716836113e7565b111561092b5761092867ffffffffffffffff8616836113fa565b90505b8067ffffffffffffffff8111156109445761094461135a565b60405190808252806020026020018201604052801561096d578160200160208202803683370190505b50925060005b818110156109d95761099a6109928267ffffffffffffffff89166113e7565b600390610ea7565b8482815181106109ac576109ac611389565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101610973565b50505092915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161048a565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006108c6600583610eb3565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020548391163314610b6c576040517fed5d85b500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161048a565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152600260205260408082206001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001695881695861790559051909392339290917fc54c3051ff16e63bb9203214432372aca006c589e3653619b577a3265675b7169190a450505050565b610bff33610adf565b158015610c24575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610c5d576040517f51ca1ec300000000000000000000000000000000000000000000000000000000815233600482015260240161048a565b73ffffffffffffffffffffffffffffffffffffffff8116610caa576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020805490911615610d24576040517f45ed80e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240161048a565b6001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055610d71600384610e7b565b5060405173ffffffffffffffffffffffffffffffffffffffff808416916000918616907fc54c3051ff16e63bb9203214432372aca006c589e3653619b577a3265675b716908390a4505050565b610dc6610dcf565b61040781610ee2565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161048a565b565b6000610e748373ffffffffffffffffffffffffffffffffffffffff8416610fd7565b9392505050565b6000610e748373ffffffffffffffffffffffffffffffffffffffff84166110ca565b60006108c6825490565b6000610e748383611119565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610e74565b3373ffffffffffffffffffffffffffffffffffffffff821603610f61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161048a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081815260018301602052604081205480156110c0576000610ffb6001836113fa565b855490915060009061100f906001906113fa565b905081811461107457600086600001828154811061102f5761102f611389565b906000526020600020015490508087600001848154811061105257611052611389565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806110855761108561140d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108c6565b60009150506108c6565b6000818152600183016020526040812054611111575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108c6565b5060006108c6565b600082600001828154811061113057611130611389565b9060005260206000200154905092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116757600080fd5b919050565b60006020828403121561117e57600080fd5b610e7482611143565b60006020808352835180602085015260005b818110156111b557858101830151858201604001528201611199565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000806040838503121561120757600080fd5b61121083611143565b915061121e60208401611143565b90509250929050565b6000806020838503121561123a57600080fd5b823567ffffffffffffffff8082111561125257600080fd5b818501915085601f83011261126657600080fd5b81358181111561127557600080fd5b8660208260051b850101111561128a57600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b818110156112ea57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016112b8565b50909695505050505050565b803567ffffffffffffffff8116811461116757600080fd5b6000806040838503121561132157600080fd5b61132a836112f6565b915061121e602084016112f6565b60006020828403121561134a57600080fd5b81518015158114610e7457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156108c6576108c66113b8565b818103818111156108c6576108c66113b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", +} + +var TokenAdminRegistryABI = TokenAdminRegistryMetaData.ABI + +var TokenAdminRegistryBin = TokenAdminRegistryMetaData.Bin + +func DeployTokenAdminRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TokenAdminRegistry, error) { + parsed, err := TokenAdminRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TokenAdminRegistryBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TokenAdminRegistry{address: address, abi: *parsed, TokenAdminRegistryCaller: TokenAdminRegistryCaller{contract: contract}, TokenAdminRegistryTransactor: TokenAdminRegistryTransactor{contract: contract}, TokenAdminRegistryFilterer: TokenAdminRegistryFilterer{contract: contract}}, nil +} + +type TokenAdminRegistry struct { + address common.Address + abi abi.ABI + TokenAdminRegistryCaller + TokenAdminRegistryTransactor + TokenAdminRegistryFilterer +} + +type TokenAdminRegistryCaller struct { + contract *bind.BoundContract +} + +type TokenAdminRegistryTransactor struct { + contract *bind.BoundContract +} + +type TokenAdminRegistryFilterer struct { + contract *bind.BoundContract +} + +type TokenAdminRegistrySession struct { + Contract *TokenAdminRegistry + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type TokenAdminRegistryCallerSession struct { + Contract *TokenAdminRegistryCaller + CallOpts bind.CallOpts +} + +type TokenAdminRegistryTransactorSession struct { + Contract *TokenAdminRegistryTransactor + TransactOpts bind.TransactOpts +} + +type TokenAdminRegistryRaw struct { + Contract *TokenAdminRegistry +} + +type TokenAdminRegistryCallerRaw struct { + Contract *TokenAdminRegistryCaller +} + +type TokenAdminRegistryTransactorRaw struct { + Contract *TokenAdminRegistryTransactor +} + +func NewTokenAdminRegistry(address common.Address, backend bind.ContractBackend) (*TokenAdminRegistry, error) { + abi, err := abi.JSON(strings.NewReader(TokenAdminRegistryABI)) + if err != nil { + return nil, err + } + contract, err := bindTokenAdminRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TokenAdminRegistry{address: address, abi: abi, TokenAdminRegistryCaller: TokenAdminRegistryCaller{contract: contract}, TokenAdminRegistryTransactor: TokenAdminRegistryTransactor{contract: contract}, TokenAdminRegistryFilterer: TokenAdminRegistryFilterer{contract: contract}}, nil +} + +func NewTokenAdminRegistryCaller(address common.Address, caller bind.ContractCaller) (*TokenAdminRegistryCaller, error) { + contract, err := bindTokenAdminRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TokenAdminRegistryCaller{contract: contract}, nil +} + +func NewTokenAdminRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*TokenAdminRegistryTransactor, error) { + contract, err := bindTokenAdminRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TokenAdminRegistryTransactor{contract: contract}, nil +} + +func NewTokenAdminRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*TokenAdminRegistryFilterer, error) { + contract, err := bindTokenAdminRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TokenAdminRegistryFilterer{contract: contract}, nil +} + +func bindTokenAdminRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TokenAdminRegistryMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TokenAdminRegistry.Contract.TokenAdminRegistryCaller.contract.Call(opts, result, method, params...) +} + +func (_TokenAdminRegistry *TokenAdminRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.TokenAdminRegistryTransactor.contract.Transfer(opts) +} + +func (_TokenAdminRegistry *TokenAdminRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.TokenAdminRegistryTransactor.contract.Transact(opts, method, params...) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TokenAdminRegistry.Contract.contract.Call(opts, result, method, params...) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.contract.Transfer(opts) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.contract.Transact(opts, method, params...) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCaller) GetAllConfiguredTokens(opts *bind.CallOpts, startIndex uint64, maxCount uint64) ([]common.Address, error) { + var out []interface{} + err := _TokenAdminRegistry.contract.Call(opts, &out, "getAllConfiguredTokens", startIndex, maxCount) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) GetAllConfiguredTokens(startIndex uint64, maxCount uint64) ([]common.Address, error) { + return _TokenAdminRegistry.Contract.GetAllConfiguredTokens(&_TokenAdminRegistry.CallOpts, startIndex, maxCount) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCallerSession) GetAllConfiguredTokens(startIndex uint64, maxCount uint64) ([]common.Address, error) { + return _TokenAdminRegistry.Contract.GetAllConfiguredTokens(&_TokenAdminRegistry.CallOpts, startIndex, maxCount) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCaller) GetPool(opts *bind.CallOpts, token common.Address) (common.Address, error) { + var out []interface{} + err := _TokenAdminRegistry.contract.Call(opts, &out, "getPool", token) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) GetPool(token common.Address) (common.Address, error) { + return _TokenAdminRegistry.Contract.GetPool(&_TokenAdminRegistry.CallOpts, token) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCallerSession) GetPool(token common.Address) (common.Address, error) { + return _TokenAdminRegistry.Contract.GetPool(&_TokenAdminRegistry.CallOpts, token) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCaller) GetPools(opts *bind.CallOpts, tokens []common.Address) ([]common.Address, error) { + var out []interface{} + err := _TokenAdminRegistry.contract.Call(opts, &out, "getPools", tokens) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) GetPools(tokens []common.Address) ([]common.Address, error) { + return _TokenAdminRegistry.Contract.GetPools(&_TokenAdminRegistry.CallOpts, tokens) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCallerSession) GetPools(tokens []common.Address) ([]common.Address, error) { + return _TokenAdminRegistry.Contract.GetPools(&_TokenAdminRegistry.CallOpts, tokens) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCaller) GetTokenConfig(opts *bind.CallOpts, token common.Address) (TokenAdminRegistryTokenConfig, error) { + var out []interface{} + err := _TokenAdminRegistry.contract.Call(opts, &out, "getTokenConfig", token) + + if err != nil { + return *new(TokenAdminRegistryTokenConfig), err + } + + out0 := *abi.ConvertType(out[0], new(TokenAdminRegistryTokenConfig)).(*TokenAdminRegistryTokenConfig) + + return out0, err + +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) GetTokenConfig(token common.Address) (TokenAdminRegistryTokenConfig, error) { + return _TokenAdminRegistry.Contract.GetTokenConfig(&_TokenAdminRegistry.CallOpts, token) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCallerSession) GetTokenConfig(token common.Address) (TokenAdminRegistryTokenConfig, error) { + return _TokenAdminRegistry.Contract.GetTokenConfig(&_TokenAdminRegistry.CallOpts, token) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCaller) IsAdministrator(opts *bind.CallOpts, localToken common.Address, administrator common.Address) (bool, error) { + var out []interface{} + err := _TokenAdminRegistry.contract.Call(opts, &out, "isAdministrator", localToken, administrator) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) IsAdministrator(localToken common.Address, administrator common.Address) (bool, error) { + return _TokenAdminRegistry.Contract.IsAdministrator(&_TokenAdminRegistry.CallOpts, localToken, administrator) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCallerSession) IsAdministrator(localToken common.Address, administrator common.Address) (bool, error) { + return _TokenAdminRegistry.Contract.IsAdministrator(&_TokenAdminRegistry.CallOpts, localToken, administrator) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCaller) IsRegistryModule(opts *bind.CallOpts, module common.Address) (bool, error) { + var out []interface{} + err := _TokenAdminRegistry.contract.Call(opts, &out, "isRegistryModule", module) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) IsRegistryModule(module common.Address) (bool, error) { + return _TokenAdminRegistry.Contract.IsRegistryModule(&_TokenAdminRegistry.CallOpts, module) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCallerSession) IsRegistryModule(module common.Address) (bool, error) { + return _TokenAdminRegistry.Contract.IsRegistryModule(&_TokenAdminRegistry.CallOpts, module) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenAdminRegistry.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) Owner() (common.Address, error) { + return _TokenAdminRegistry.Contract.Owner(&_TokenAdminRegistry.CallOpts) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCallerSession) Owner() (common.Address, error) { + return _TokenAdminRegistry.Contract.Owner(&_TokenAdminRegistry.CallOpts) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _TokenAdminRegistry.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) TypeAndVersion() (string, error) { + return _TokenAdminRegistry.Contract.TypeAndVersion(&_TokenAdminRegistry.CallOpts) +} + +func (_TokenAdminRegistry *TokenAdminRegistryCallerSession) TypeAndVersion() (string, error) { + return _TokenAdminRegistry.Contract.TypeAndVersion(&_TokenAdminRegistry.CallOpts) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactor) AcceptAdminRole(opts *bind.TransactOpts, localToken common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.contract.Transact(opts, "acceptAdminRole", localToken) +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) AcceptAdminRole(localToken common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.AcceptAdminRole(&_TokenAdminRegistry.TransactOpts, localToken) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactorSession) AcceptAdminRole(localToken common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.AcceptAdminRole(&_TokenAdminRegistry.TransactOpts, localToken) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenAdminRegistry.contract.Transact(opts, "acceptOwnership") +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) AcceptOwnership() (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.AcceptOwnership(&_TokenAdminRegistry.TransactOpts) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.AcceptOwnership(&_TokenAdminRegistry.TransactOpts) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactor) AddRegistryModule(opts *bind.TransactOpts, module common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.contract.Transact(opts, "addRegistryModule", module) +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) AddRegistryModule(module common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.AddRegistryModule(&_TokenAdminRegistry.TransactOpts, module) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactorSession) AddRegistryModule(module common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.AddRegistryModule(&_TokenAdminRegistry.TransactOpts, module) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactor) ProposeAdministrator(opts *bind.TransactOpts, localToken common.Address, administrator common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.contract.Transact(opts, "proposeAdministrator", localToken, administrator) +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) ProposeAdministrator(localToken common.Address, administrator common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.ProposeAdministrator(&_TokenAdminRegistry.TransactOpts, localToken, administrator) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactorSession) ProposeAdministrator(localToken common.Address, administrator common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.ProposeAdministrator(&_TokenAdminRegistry.TransactOpts, localToken, administrator) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactor) RemoveRegistryModule(opts *bind.TransactOpts, module common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.contract.Transact(opts, "removeRegistryModule", module) +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) RemoveRegistryModule(module common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.RemoveRegistryModule(&_TokenAdminRegistry.TransactOpts, module) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactorSession) RemoveRegistryModule(module common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.RemoveRegistryModule(&_TokenAdminRegistry.TransactOpts, module) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactor) SetPool(opts *bind.TransactOpts, localToken common.Address, pool common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.contract.Transact(opts, "setPool", localToken, pool) +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) SetPool(localToken common.Address, pool common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.SetPool(&_TokenAdminRegistry.TransactOpts, localToken, pool) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactorSession) SetPool(localToken common.Address, pool common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.SetPool(&_TokenAdminRegistry.TransactOpts, localToken, pool) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactor) TransferAdminRole(opts *bind.TransactOpts, localToken common.Address, newAdmin common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.contract.Transact(opts, "transferAdminRole", localToken, newAdmin) +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) TransferAdminRole(localToken common.Address, newAdmin common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.TransferAdminRole(&_TokenAdminRegistry.TransactOpts, localToken, newAdmin) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactorSession) TransferAdminRole(localToken common.Address, newAdmin common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.TransferAdminRole(&_TokenAdminRegistry.TransactOpts, localToken, newAdmin) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.contract.Transact(opts, "transferOwnership", to) +} + +func (_TokenAdminRegistry *TokenAdminRegistrySession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.TransferOwnership(&_TokenAdminRegistry.TransactOpts, to) +} + +func (_TokenAdminRegistry *TokenAdminRegistryTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _TokenAdminRegistry.Contract.TransferOwnership(&_TokenAdminRegistry.TransactOpts, to) +} + +type TokenAdminRegistryAdministratorTransferRequestedIterator struct { + Event *TokenAdminRegistryAdministratorTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenAdminRegistryAdministratorTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryAdministratorTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryAdministratorTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenAdminRegistryAdministratorTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *TokenAdminRegistryAdministratorTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenAdminRegistryAdministratorTransferRequested struct { + Token common.Address + CurrentAdmin common.Address + NewAdmin common.Address + Raw types.Log +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) FilterAdministratorTransferRequested(opts *bind.FilterOpts, token []common.Address, currentAdmin []common.Address, newAdmin []common.Address) (*TokenAdminRegistryAdministratorTransferRequestedIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var currentAdminRule []interface{} + for _, currentAdminItem := range currentAdmin { + currentAdminRule = append(currentAdminRule, currentAdminItem) + } + var newAdminRule []interface{} + for _, newAdminItem := range newAdmin { + newAdminRule = append(newAdminRule, newAdminItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.FilterLogs(opts, "AdministratorTransferRequested", tokenRule, currentAdminRule, newAdminRule) + if err != nil { + return nil, err + } + return &TokenAdminRegistryAdministratorTransferRequestedIterator{contract: _TokenAdminRegistry.contract, event: "AdministratorTransferRequested", logs: logs, sub: sub}, nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) WatchAdministratorTransferRequested(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryAdministratorTransferRequested, token []common.Address, currentAdmin []common.Address, newAdmin []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var currentAdminRule []interface{} + for _, currentAdminItem := range currentAdmin { + currentAdminRule = append(currentAdminRule, currentAdminItem) + } + var newAdminRule []interface{} + for _, newAdminItem := range newAdmin { + newAdminRule = append(newAdminRule, newAdminItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.WatchLogs(opts, "AdministratorTransferRequested", tokenRule, currentAdminRule, newAdminRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenAdminRegistryAdministratorTransferRequested) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "AdministratorTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParseAdministratorTransferRequested(log types.Log) (*TokenAdminRegistryAdministratorTransferRequested, error) { + event := new(TokenAdminRegistryAdministratorTransferRequested) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "AdministratorTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenAdminRegistryAdministratorTransferredIterator struct { + Event *TokenAdminRegistryAdministratorTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenAdminRegistryAdministratorTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryAdministratorTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryAdministratorTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenAdminRegistryAdministratorTransferredIterator) Error() error { + return it.fail +} + +func (it *TokenAdminRegistryAdministratorTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenAdminRegistryAdministratorTransferred struct { + Token common.Address + NewAdmin common.Address + Raw types.Log +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) FilterAdministratorTransferred(opts *bind.FilterOpts, token []common.Address, newAdmin []common.Address) (*TokenAdminRegistryAdministratorTransferredIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var newAdminRule []interface{} + for _, newAdminItem := range newAdmin { + newAdminRule = append(newAdminRule, newAdminItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.FilterLogs(opts, "AdministratorTransferred", tokenRule, newAdminRule) + if err != nil { + return nil, err + } + return &TokenAdminRegistryAdministratorTransferredIterator{contract: _TokenAdminRegistry.contract, event: "AdministratorTransferred", logs: logs, sub: sub}, nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) WatchAdministratorTransferred(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryAdministratorTransferred, token []common.Address, newAdmin []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var newAdminRule []interface{} + for _, newAdminItem := range newAdmin { + newAdminRule = append(newAdminRule, newAdminItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.WatchLogs(opts, "AdministratorTransferred", tokenRule, newAdminRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenAdminRegistryAdministratorTransferred) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "AdministratorTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParseAdministratorTransferred(log types.Log) (*TokenAdminRegistryAdministratorTransferred, error) { + event := new(TokenAdminRegistryAdministratorTransferred) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "AdministratorTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenAdminRegistryDisableReRegistrationSetIterator struct { + Event *TokenAdminRegistryDisableReRegistrationSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenAdminRegistryDisableReRegistrationSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryDisableReRegistrationSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryDisableReRegistrationSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenAdminRegistryDisableReRegistrationSetIterator) Error() error { + return it.fail +} + +func (it *TokenAdminRegistryDisableReRegistrationSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenAdminRegistryDisableReRegistrationSet struct { + Token common.Address + Disabled bool + Raw types.Log +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) FilterDisableReRegistrationSet(opts *bind.FilterOpts, token []common.Address) (*TokenAdminRegistryDisableReRegistrationSetIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.FilterLogs(opts, "DisableReRegistrationSet", tokenRule) + if err != nil { + return nil, err + } + return &TokenAdminRegistryDisableReRegistrationSetIterator{contract: _TokenAdminRegistry.contract, event: "DisableReRegistrationSet", logs: logs, sub: sub}, nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) WatchDisableReRegistrationSet(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryDisableReRegistrationSet, token []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.WatchLogs(opts, "DisableReRegistrationSet", tokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenAdminRegistryDisableReRegistrationSet) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "DisableReRegistrationSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParseDisableReRegistrationSet(log types.Log) (*TokenAdminRegistryDisableReRegistrationSet, error) { + event := new(TokenAdminRegistryDisableReRegistrationSet) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "DisableReRegistrationSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenAdminRegistryOwnershipTransferRequestedIterator struct { + Event *TokenAdminRegistryOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenAdminRegistryOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenAdminRegistryOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *TokenAdminRegistryOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenAdminRegistryOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenAdminRegistryOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &TokenAdminRegistryOwnershipTransferRequestedIterator{contract: _TokenAdminRegistry.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenAdminRegistryOwnershipTransferRequested) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParseOwnershipTransferRequested(log types.Log) (*TokenAdminRegistryOwnershipTransferRequested, error) { + event := new(TokenAdminRegistryOwnershipTransferRequested) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenAdminRegistryOwnershipTransferredIterator struct { + Event *TokenAdminRegistryOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenAdminRegistryOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenAdminRegistryOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *TokenAdminRegistryOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenAdminRegistryOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenAdminRegistryOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &TokenAdminRegistryOwnershipTransferredIterator{contract: _TokenAdminRegistry.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenAdminRegistryOwnershipTransferred) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParseOwnershipTransferred(log types.Log) (*TokenAdminRegistryOwnershipTransferred, error) { + event := new(TokenAdminRegistryOwnershipTransferred) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenAdminRegistryPoolSetIterator struct { + Event *TokenAdminRegistryPoolSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenAdminRegistryPoolSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryPoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryPoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenAdminRegistryPoolSetIterator) Error() error { + return it.fail +} + +func (it *TokenAdminRegistryPoolSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenAdminRegistryPoolSet struct { + Token common.Address + PreviousPool common.Address + NewPool common.Address + Raw types.Log +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) FilterPoolSet(opts *bind.FilterOpts, token []common.Address, previousPool []common.Address, newPool []common.Address) (*TokenAdminRegistryPoolSetIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var previousPoolRule []interface{} + for _, previousPoolItem := range previousPool { + previousPoolRule = append(previousPoolRule, previousPoolItem) + } + var newPoolRule []interface{} + for _, newPoolItem := range newPool { + newPoolRule = append(newPoolRule, newPoolItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.FilterLogs(opts, "PoolSet", tokenRule, previousPoolRule, newPoolRule) + if err != nil { + return nil, err + } + return &TokenAdminRegistryPoolSetIterator{contract: _TokenAdminRegistry.contract, event: "PoolSet", logs: logs, sub: sub}, nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) WatchPoolSet(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryPoolSet, token []common.Address, previousPool []common.Address, newPool []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var previousPoolRule []interface{} + for _, previousPoolItem := range previousPool { + previousPoolRule = append(previousPoolRule, previousPoolItem) + } + var newPoolRule []interface{} + for _, newPoolItem := range newPool { + newPoolRule = append(newPoolRule, newPoolItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.WatchLogs(opts, "PoolSet", tokenRule, previousPoolRule, newPoolRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenAdminRegistryPoolSet) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "PoolSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParsePoolSet(log types.Log) (*TokenAdminRegistryPoolSet, error) { + event := new(TokenAdminRegistryPoolSet) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "PoolSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenAdminRegistryRegistryModuleAddedIterator struct { + Event *TokenAdminRegistryRegistryModuleAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenAdminRegistryRegistryModuleAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryRegistryModuleAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryRegistryModuleAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenAdminRegistryRegistryModuleAddedIterator) Error() error { + return it.fail +} + +func (it *TokenAdminRegistryRegistryModuleAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenAdminRegistryRegistryModuleAdded struct { + Module common.Address + Raw types.Log +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) FilterRegistryModuleAdded(opts *bind.FilterOpts) (*TokenAdminRegistryRegistryModuleAddedIterator, error) { + + logs, sub, err := _TokenAdminRegistry.contract.FilterLogs(opts, "RegistryModuleAdded") + if err != nil { + return nil, err + } + return &TokenAdminRegistryRegistryModuleAddedIterator{contract: _TokenAdminRegistry.contract, event: "RegistryModuleAdded", logs: logs, sub: sub}, nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) WatchRegistryModuleAdded(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryRegistryModuleAdded) (event.Subscription, error) { + + logs, sub, err := _TokenAdminRegistry.contract.WatchLogs(opts, "RegistryModuleAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenAdminRegistryRegistryModuleAdded) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "RegistryModuleAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParseRegistryModuleAdded(log types.Log) (*TokenAdminRegistryRegistryModuleAdded, error) { + event := new(TokenAdminRegistryRegistryModuleAdded) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "RegistryModuleAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenAdminRegistryRegistryModuleRemovedIterator struct { + Event *TokenAdminRegistryRegistryModuleRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenAdminRegistryRegistryModuleRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryRegistryModuleRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryRegistryModuleRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenAdminRegistryRegistryModuleRemovedIterator) Error() error { + return it.fail +} + +func (it *TokenAdminRegistryRegistryModuleRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenAdminRegistryRegistryModuleRemoved struct { + Module common.Address + Raw types.Log +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) FilterRegistryModuleRemoved(opts *bind.FilterOpts, module []common.Address) (*TokenAdminRegistryRegistryModuleRemovedIterator, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.FilterLogs(opts, "RegistryModuleRemoved", moduleRule) + if err != nil { + return nil, err + } + return &TokenAdminRegistryRegistryModuleRemovedIterator{contract: _TokenAdminRegistry.contract, event: "RegistryModuleRemoved", logs: logs, sub: sub}, nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) WatchRegistryModuleRemoved(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryRegistryModuleRemoved, module []common.Address) (event.Subscription, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _TokenAdminRegistry.contract.WatchLogs(opts, "RegistryModuleRemoved", moduleRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenAdminRegistryRegistryModuleRemoved) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "RegistryModuleRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParseRegistryModuleRemoved(log types.Log) (*TokenAdminRegistryRegistryModuleRemoved, error) { + event := new(TokenAdminRegistryRegistryModuleRemoved) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "RegistryModuleRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenAdminRegistryRemovedAdministratorIterator struct { + Event *TokenAdminRegistryRemovedAdministrator + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenAdminRegistryRemovedAdministratorIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryRemovedAdministrator) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenAdminRegistryRemovedAdministrator) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenAdminRegistryRemovedAdministratorIterator) Error() error { + return it.fail +} + +func (it *TokenAdminRegistryRemovedAdministratorIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenAdminRegistryRemovedAdministrator struct { + Token common.Address + Raw types.Log +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) FilterRemovedAdministrator(opts *bind.FilterOpts) (*TokenAdminRegistryRemovedAdministratorIterator, error) { + + logs, sub, err := _TokenAdminRegistry.contract.FilterLogs(opts, "RemovedAdministrator") + if err != nil { + return nil, err + } + return &TokenAdminRegistryRemovedAdministratorIterator{contract: _TokenAdminRegistry.contract, event: "RemovedAdministrator", logs: logs, sub: sub}, nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) WatchRemovedAdministrator(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryRemovedAdministrator) (event.Subscription, error) { + + logs, sub, err := _TokenAdminRegistry.contract.WatchLogs(opts, "RemovedAdministrator") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenAdminRegistryRemovedAdministrator) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "RemovedAdministrator", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParseRemovedAdministrator(log types.Log) (*TokenAdminRegistryRemovedAdministrator, error) { + event := new(TokenAdminRegistryRemovedAdministrator) + if err := _TokenAdminRegistry.contract.UnpackLog(event, "RemovedAdministrator", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_TokenAdminRegistry *TokenAdminRegistry) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _TokenAdminRegistry.abi.Events["AdministratorTransferRequested"].ID: + return _TokenAdminRegistry.ParseAdministratorTransferRequested(log) + case _TokenAdminRegistry.abi.Events["AdministratorTransferred"].ID: + return _TokenAdminRegistry.ParseAdministratorTransferred(log) + case _TokenAdminRegistry.abi.Events["DisableReRegistrationSet"].ID: + return _TokenAdminRegistry.ParseDisableReRegistrationSet(log) + case _TokenAdminRegistry.abi.Events["OwnershipTransferRequested"].ID: + return _TokenAdminRegistry.ParseOwnershipTransferRequested(log) + case _TokenAdminRegistry.abi.Events["OwnershipTransferred"].ID: + return _TokenAdminRegistry.ParseOwnershipTransferred(log) + case _TokenAdminRegistry.abi.Events["PoolSet"].ID: + return _TokenAdminRegistry.ParsePoolSet(log) + case _TokenAdminRegistry.abi.Events["RegistryModuleAdded"].ID: + return _TokenAdminRegistry.ParseRegistryModuleAdded(log) + case _TokenAdminRegistry.abi.Events["RegistryModuleRemoved"].ID: + return _TokenAdminRegistry.ParseRegistryModuleRemoved(log) + case _TokenAdminRegistry.abi.Events["RemovedAdministrator"].ID: + return _TokenAdminRegistry.ParseRemovedAdministrator(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (TokenAdminRegistryAdministratorTransferRequested) Topic() common.Hash { + return common.HexToHash("0xc54c3051ff16e63bb9203214432372aca006c589e3653619b577a3265675b716") +} + +func (TokenAdminRegistryAdministratorTransferred) Topic() common.Hash { + return common.HexToHash("0x399b55200f7f639a63d76efe3dcfa9156ce367058d6b673041b84a628885f5a7") +} + +func (TokenAdminRegistryDisableReRegistrationSet) Topic() common.Hash { + return common.HexToHash("0x4f1ce406d38233729d1052ad9f0c2b56bd742cd4fb59781573b51fa1f268a92e") +} + +func (TokenAdminRegistryOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (TokenAdminRegistryOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (TokenAdminRegistryPoolSet) Topic() common.Hash { + return common.HexToHash("0x754449ec3aff3bd528bfce43ae9319c4a381b67fcd1d20097b3b24dacaecc35d") +} + +func (TokenAdminRegistryRegistryModuleAdded) Topic() common.Hash { + return common.HexToHash("0x3cabf004338366bfeaeb610ad827cb58d16b588017c509501f2c97c83caae7b2") +} + +func (TokenAdminRegistryRegistryModuleRemoved) Topic() common.Hash { + return common.HexToHash("0x93eaa26dcb9275e56bacb1d33fdbf402262da6f0f4baf2a6e2cd154b73f387f8") +} + +func (TokenAdminRegistryRemovedAdministrator) Topic() common.Hash { + return common.HexToHash("0x7b309bf0232684e703b0a791653cc857835761a0365ccade0e2aa66ef02ca530") +} + +func (_TokenAdminRegistry *TokenAdminRegistry) Address() common.Address { + return _TokenAdminRegistry.address +} + +type TokenAdminRegistryInterface interface { + GetAllConfiguredTokens(opts *bind.CallOpts, startIndex uint64, maxCount uint64) ([]common.Address, error) + + GetPool(opts *bind.CallOpts, token common.Address) (common.Address, error) + + GetPools(opts *bind.CallOpts, tokens []common.Address) ([]common.Address, error) + + GetTokenConfig(opts *bind.CallOpts, token common.Address) (TokenAdminRegistryTokenConfig, error) + + IsAdministrator(opts *bind.CallOpts, localToken common.Address, administrator common.Address) (bool, error) + + IsRegistryModule(opts *bind.CallOpts, module common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptAdminRole(opts *bind.TransactOpts, localToken common.Address) (*types.Transaction, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AddRegistryModule(opts *bind.TransactOpts, module common.Address) (*types.Transaction, error) + + ProposeAdministrator(opts *bind.TransactOpts, localToken common.Address, administrator common.Address) (*types.Transaction, error) + + RemoveRegistryModule(opts *bind.TransactOpts, module common.Address) (*types.Transaction, error) + + SetPool(opts *bind.TransactOpts, localToken common.Address, pool common.Address) (*types.Transaction, error) + + TransferAdminRole(opts *bind.TransactOpts, localToken common.Address, newAdmin common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAdministratorTransferRequested(opts *bind.FilterOpts, token []common.Address, currentAdmin []common.Address, newAdmin []common.Address) (*TokenAdminRegistryAdministratorTransferRequestedIterator, error) + + WatchAdministratorTransferRequested(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryAdministratorTransferRequested, token []common.Address, currentAdmin []common.Address, newAdmin []common.Address) (event.Subscription, error) + + ParseAdministratorTransferRequested(log types.Log) (*TokenAdminRegistryAdministratorTransferRequested, error) + + FilterAdministratorTransferred(opts *bind.FilterOpts, token []common.Address, newAdmin []common.Address) (*TokenAdminRegistryAdministratorTransferredIterator, error) + + WatchAdministratorTransferred(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryAdministratorTransferred, token []common.Address, newAdmin []common.Address) (event.Subscription, error) + + ParseAdministratorTransferred(log types.Log) (*TokenAdminRegistryAdministratorTransferred, error) + + FilterDisableReRegistrationSet(opts *bind.FilterOpts, token []common.Address) (*TokenAdminRegistryDisableReRegistrationSetIterator, error) + + WatchDisableReRegistrationSet(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryDisableReRegistrationSet, token []common.Address) (event.Subscription, error) + + ParseDisableReRegistrationSet(log types.Log) (*TokenAdminRegistryDisableReRegistrationSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenAdminRegistryOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*TokenAdminRegistryOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenAdminRegistryOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*TokenAdminRegistryOwnershipTransferred, error) + + FilterPoolSet(opts *bind.FilterOpts, token []common.Address, previousPool []common.Address, newPool []common.Address) (*TokenAdminRegistryPoolSetIterator, error) + + WatchPoolSet(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryPoolSet, token []common.Address, previousPool []common.Address, newPool []common.Address) (event.Subscription, error) + + ParsePoolSet(log types.Log) (*TokenAdminRegistryPoolSet, error) + + FilterRegistryModuleAdded(opts *bind.FilterOpts) (*TokenAdminRegistryRegistryModuleAddedIterator, error) + + WatchRegistryModuleAdded(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryRegistryModuleAdded) (event.Subscription, error) + + ParseRegistryModuleAdded(log types.Log) (*TokenAdminRegistryRegistryModuleAdded, error) + + FilterRegistryModuleRemoved(opts *bind.FilterOpts, module []common.Address) (*TokenAdminRegistryRegistryModuleRemovedIterator, error) + + WatchRegistryModuleRemoved(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryRegistryModuleRemoved, module []common.Address) (event.Subscription, error) + + ParseRegistryModuleRemoved(log types.Log) (*TokenAdminRegistryRegistryModuleRemoved, error) + + FilterRemovedAdministrator(opts *bind.FilterOpts) (*TokenAdminRegistryRemovedAdministratorIterator, error) + + WatchRemovedAdministrator(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryRemovedAdministrator) (event.Subscription, error) + + ParseRemovedAdministrator(log types.Log) (*TokenAdminRegistryRemovedAdministrator, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/token_pool/token_pool.go b/core/gethwrappers/ccip/generated/token_pool/token_pool.go new file mode 100644 index 0000000000..0fb4c4e087 --- /dev/null +++ b/core/gethwrappers/ccip/generated/token_pool/token_pool.go @@ -0,0 +1,2608 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package token_pool + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type PoolLockOrBurnInV1 struct { + Receiver []byte + RemoteChainSelector uint64 + OriginalSender common.Address + Amount *big.Int + LocalToken common.Address +} + +type PoolLockOrBurnOutV1 struct { + DestTokenAddress []byte + DestPoolData []byte +} + +type PoolReleaseOrMintInV1 struct { + OriginalSender []byte + RemoteChainSelector uint64 + Receiver common.Address + Amount *big.Int + LocalToken common.Address + SourcePoolAddress []byte + SourcePoolData []byte + OffchainTokenData []byte +} + +type PoolReleaseOrMintOutV1 struct { + DestinationAmount *big.Int +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + RemotePoolAddress []byte + RemoteTokenAddress []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +var TokenPoolMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"lockOrBurnOut\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +var TokenPoolABI = TokenPoolMetaData.ABI + +type TokenPool struct { + address common.Address + abi abi.ABI + TokenPoolCaller + TokenPoolTransactor + TokenPoolFilterer +} + +type TokenPoolCaller struct { + contract *bind.BoundContract +} + +type TokenPoolTransactor struct { + contract *bind.BoundContract +} + +type TokenPoolFilterer struct { + contract *bind.BoundContract +} + +type TokenPoolSession struct { + Contract *TokenPool + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type TokenPoolCallerSession struct { + Contract *TokenPoolCaller + CallOpts bind.CallOpts +} + +type TokenPoolTransactorSession struct { + Contract *TokenPoolTransactor + TransactOpts bind.TransactOpts +} + +type TokenPoolRaw struct { + Contract *TokenPool +} + +type TokenPoolCallerRaw struct { + Contract *TokenPoolCaller +} + +type TokenPoolTransactorRaw struct { + Contract *TokenPoolTransactor +} + +func NewTokenPool(address common.Address, backend bind.ContractBackend) (*TokenPool, error) { + abi, err := abi.JSON(strings.NewReader(TokenPoolABI)) + if err != nil { + return nil, err + } + contract, err := bindTokenPool(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TokenPool{address: address, abi: abi, TokenPoolCaller: TokenPoolCaller{contract: contract}, TokenPoolTransactor: TokenPoolTransactor{contract: contract}, TokenPoolFilterer: TokenPoolFilterer{contract: contract}}, nil +} + +func NewTokenPoolCaller(address common.Address, caller bind.ContractCaller) (*TokenPoolCaller, error) { + contract, err := bindTokenPool(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TokenPoolCaller{contract: contract}, nil +} + +func NewTokenPoolTransactor(address common.Address, transactor bind.ContractTransactor) (*TokenPoolTransactor, error) { + contract, err := bindTokenPool(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TokenPoolTransactor{contract: contract}, nil +} + +func NewTokenPoolFilterer(address common.Address, filterer bind.ContractFilterer) (*TokenPoolFilterer, error) { + contract, err := bindTokenPool(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TokenPoolFilterer{contract: contract}, nil +} + +func bindTokenPool(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TokenPoolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_TokenPool *TokenPoolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TokenPool.Contract.TokenPoolCaller.contract.Call(opts, result, method, params...) +} + +func (_TokenPool *TokenPoolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenPool.Contract.TokenPoolTransactor.contract.Transfer(opts) +} + +func (_TokenPool *TokenPoolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TokenPool.Contract.TokenPoolTransactor.contract.Transact(opts, method, params...) +} + +func (_TokenPool *TokenPoolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TokenPool.Contract.contract.Call(opts, result, method, params...) +} + +func (_TokenPool *TokenPoolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenPool.Contract.contract.Transfer(opts) +} + +func (_TokenPool *TokenPoolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TokenPool.Contract.contract.Transact(opts, method, params...) +} + +func (_TokenPool *TokenPoolCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetAllowList() ([]common.Address, error) { + return _TokenPool.Contract.GetAllowList(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetAllowList() ([]common.Address, error) { + return _TokenPool.Contract.GetAllowList(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetAllowListEnabled() (bool, error) { + return _TokenPool.Contract.GetAllowListEnabled(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetAllowListEnabled() (bool, error) { + return _TokenPool.Contract.GetAllowListEnabled(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _TokenPool.Contract.GetCurrentInboundRateLimiterState(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _TokenPool.Contract.GetCurrentInboundRateLimiterState(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _TokenPool.Contract.GetCurrentOutboundRateLimiterState(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _TokenPool.Contract.GetCurrentOutboundRateLimiterState(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _TokenPool.Contract.GetRemotePool(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _TokenPool.Contract.GetRemotePool(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getRemoteToken", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _TokenPool.Contract.GetRemoteToken(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCallerSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _TokenPool.Contract.GetRemoteToken(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCaller) GetRmnProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getRmnProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetRmnProxy() (common.Address, error) { + return _TokenPool.Contract.GetRmnProxy(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetRmnProxy() (common.Address, error) { + return _TokenPool.Contract.GetRmnProxy(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetRouter() (common.Address, error) { + return _TokenPool.Contract.GetRouter(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetRouter() (common.Address, error) { + return _TokenPool.Contract.GetRouter(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetSupportedChains() ([]uint64, error) { + return _TokenPool.Contract.GetSupportedChains(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetSupportedChains() ([]uint64, error) { + return _TokenPool.Contract.GetSupportedChains(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetToken() (common.Address, error) { + return _TokenPool.Contract.GetToken(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetToken() (common.Address, error) { + return _TokenPool.Contract.GetToken(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _TokenPool.Contract.IsSupportedChain(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _TokenPool.Contract.IsSupportedChain(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCaller) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "isSupportedToken", token) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) IsSupportedToken(token common.Address) (bool, error) { + return _TokenPool.Contract.IsSupportedToken(&_TokenPool.CallOpts, token) +} + +func (_TokenPool *TokenPoolCallerSession) IsSupportedToken(token common.Address) (bool, error) { + return _TokenPool.Contract.IsSupportedToken(&_TokenPool.CallOpts, token) +} + +func (_TokenPool *TokenPoolCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) Owner() (common.Address, error) { + return _TokenPool.Contract.Owner(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) Owner() (common.Address, error) { + return _TokenPool.Contract.Owner(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _TokenPool.Contract.SupportsInterface(&_TokenPool.CallOpts, interfaceId) +} + +func (_TokenPool *TokenPoolCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _TokenPool.Contract.SupportsInterface(&_TokenPool.CallOpts, interfaceId) +} + +func (_TokenPool *TokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "acceptOwnership") +} + +func (_TokenPool *TokenPoolSession) AcceptOwnership() (*types.Transaction, error) { + return _TokenPool.Contract.AcceptOwnership(&_TokenPool.TransactOpts) +} + +func (_TokenPool *TokenPoolTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _TokenPool.Contract.AcceptOwnership(&_TokenPool.TransactOpts) +} + +func (_TokenPool *TokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_TokenPool *TokenPoolSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.ApplyAllowListUpdates(&_TokenPool.TransactOpts, removes, adds) +} + +func (_TokenPool *TokenPoolTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.ApplyAllowListUpdates(&_TokenPool.TransactOpts, removes, adds) +} + +func (_TokenPool *TokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_TokenPool *TokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _TokenPool.Contract.ApplyChainUpdates(&_TokenPool.TransactOpts, chains) +} + +func (_TokenPool *TokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _TokenPool.Contract.ApplyChainUpdates(&_TokenPool.TransactOpts, chains) +} + +func (_TokenPool *TokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "lockOrBurn", lockOrBurnIn) +} + +func (_TokenPool *TokenPoolSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _TokenPool.Contract.LockOrBurn(&_TokenPool.TransactOpts, lockOrBurnIn) +} + +func (_TokenPool *TokenPoolTransactorSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _TokenPool.Contract.LockOrBurn(&_TokenPool.TransactOpts, lockOrBurnIn) +} + +func (_TokenPool *TokenPoolTransactor) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "releaseOrMint", releaseOrMintIn) +} + +func (_TokenPool *TokenPoolSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _TokenPool.Contract.ReleaseOrMint(&_TokenPool.TransactOpts, releaseOrMintIn) +} + +func (_TokenPool *TokenPoolTransactorSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _TokenPool.Contract.ReleaseOrMint(&_TokenPool.TransactOpts, releaseOrMintIn) +} + +func (_TokenPool *TokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_TokenPool *TokenPoolSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _TokenPool.Contract.SetChainRateLimiterConfig(&_TokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_TokenPool *TokenPoolTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _TokenPool.Contract.SetChainRateLimiterConfig(&_TokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_TokenPool *TokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_TokenPool *TokenPoolSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _TokenPool.Contract.SetRemotePool(&_TokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_TokenPool *TokenPoolTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _TokenPool.Contract.SetRemotePool(&_TokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_TokenPool *TokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "setRouter", newRouter) +} + +func (_TokenPool *TokenPoolSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.SetRouter(&_TokenPool.TransactOpts, newRouter) +} + +func (_TokenPool *TokenPoolTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.SetRouter(&_TokenPool.TransactOpts, newRouter) +} + +func (_TokenPool *TokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "transferOwnership", to) +} + +func (_TokenPool *TokenPoolSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.TransferOwnership(&_TokenPool.TransactOpts, to) +} + +func (_TokenPool *TokenPoolTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.TransferOwnership(&_TokenPool.TransactOpts, to) +} + +type TokenPoolAllowListAddIterator struct { + Event *TokenPoolAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolAllowListAddIterator) Error() error { + return it.fail +} + +func (it *TokenPoolAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*TokenPoolAllowListAddIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &TokenPoolAllowListAddIterator{contract: _TokenPool.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *TokenPoolAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolAllowListAdd) + if err := _TokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseAllowListAdd(log types.Log) (*TokenPoolAllowListAdd, error) { + event := new(TokenPoolAllowListAdd) + if err := _TokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolAllowListRemoveIterator struct { + Event *TokenPoolAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *TokenPoolAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*TokenPoolAllowListRemoveIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &TokenPoolAllowListRemoveIterator{contract: _TokenPool.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *TokenPoolAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolAllowListRemove) + if err := _TokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseAllowListRemove(log types.Log) (*TokenPoolAllowListRemove, error) { + event := new(TokenPoolAllowListRemove) + if err := _TokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolBurnedIterator struct { + Event *TokenPoolBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolBurnedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*TokenPoolBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &TokenPoolBurnedIterator{contract: _TokenPool.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *TokenPoolBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolBurned) + if err := _TokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseBurned(log types.Log) (*TokenPoolBurned, error) { + event := new(TokenPoolBurned) + if err := _TokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolChainAddedIterator struct { + Event *TokenPoolChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolChainAddedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolChainAdded struct { + RemoteChainSelector uint64 + RemoteToken []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterChainAdded(opts *bind.FilterOpts) (*TokenPoolChainAddedIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &TokenPoolChainAddedIterator{contract: _TokenPool.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *TokenPoolChainAdded) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolChainAdded) + if err := _TokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseChainAdded(log types.Log) (*TokenPoolChainAdded, error) { + event := new(TokenPoolChainAdded) + if err := _TokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolChainConfiguredIterator struct { + Event *TokenPoolChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *TokenPoolChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*TokenPoolChainConfiguredIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &TokenPoolChainConfiguredIterator{contract: _TokenPool.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *TokenPoolChainConfigured) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolChainConfigured) + if err := _TokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseChainConfigured(log types.Log) (*TokenPoolChainConfigured, error) { + event := new(TokenPoolChainConfigured) + if err := _TokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolChainRemovedIterator struct { + Event *TokenPoolChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolChainRemovedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*TokenPoolChainRemovedIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &TokenPoolChainRemovedIterator{contract: _TokenPool.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *TokenPoolChainRemoved) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolChainRemoved) + if err := _TokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseChainRemoved(log types.Log) (*TokenPoolChainRemoved, error) { + event := new(TokenPoolChainRemoved) + if err := _TokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolConfigChangedIterator struct { + Event *TokenPoolConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolConfigChangedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolConfigChanged struct { + Config RateLimiterConfig + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*TokenPoolConfigChangedIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &TokenPoolConfigChangedIterator{contract: _TokenPool.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *TokenPoolConfigChanged) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolConfigChanged) + if err := _TokenPool.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseConfigChanged(log types.Log) (*TokenPoolConfigChanged, error) { + event := new(TokenPoolConfigChanged) + if err := _TokenPool.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolLockedIterator struct { + Event *TokenPoolLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolLockedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*TokenPoolLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &TokenPoolLockedIterator{contract: _TokenPool.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *TokenPoolLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolLocked) + if err := _TokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseLocked(log types.Log) (*TokenPoolLocked, error) { + event := new(TokenPoolLocked) + if err := _TokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolMintedIterator struct { + Event *TokenPoolMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolMintedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*TokenPoolMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &TokenPoolMintedIterator{contract: _TokenPool.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *TokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolMinted) + if err := _TokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseMinted(log types.Log) (*TokenPoolMinted, error) { + event := new(TokenPoolMinted) + if err := _TokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolOwnershipTransferRequestedIterator struct { + Event *TokenPoolOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenPoolOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &TokenPoolOwnershipTransferRequestedIterator{contract: _TokenPool.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *TokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolOwnershipTransferRequested) + if err := _TokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseOwnershipTransferRequested(log types.Log) (*TokenPoolOwnershipTransferRequested, error) { + event := new(TokenPoolOwnershipTransferRequested) + if err := _TokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolOwnershipTransferredIterator struct { + Event *TokenPoolOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *TokenPoolOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenPoolOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &TokenPoolOwnershipTransferredIterator{contract: _TokenPool.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolOwnershipTransferred) + if err := _TokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseOwnershipTransferred(log types.Log) (*TokenPoolOwnershipTransferred, error) { + event := new(TokenPoolOwnershipTransferred) + if err := _TokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolReleasedIterator struct { + Event *TokenPoolReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolReleasedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*TokenPoolReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &TokenPoolReleasedIterator{contract: _TokenPool.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *TokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolReleased) + if err := _TokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseReleased(log types.Log) (*TokenPoolReleased, error) { + event := new(TokenPoolReleased) + if err := _TokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolRemotePoolSetIterator struct { + Event *TokenPoolRemotePoolSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolRemotePoolSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolRemotePoolSetIterator) Error() error { + return it.fail +} + +func (it *TokenPoolRemotePoolSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolRemotePoolSet struct { + RemoteChainSelector uint64 + PreviousPoolAddress []byte + RemotePoolAddress []byte + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*TokenPoolRemotePoolSetIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &TokenPoolRemotePoolSetIterator{contract: _TokenPool.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *TokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolRemotePoolSet) + if err := _TokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseRemotePoolSet(log types.Log) (*TokenPoolRemotePoolSet, error) { + event := new(TokenPoolRemotePoolSet) + if err := _TokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolRouterUpdatedIterator struct { + Event *TokenPoolRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*TokenPoolRouterUpdatedIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &TokenPoolRouterUpdatedIterator{contract: _TokenPool.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *TokenPoolRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolRouterUpdated) + if err := _TokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseRouterUpdated(log types.Log) (*TokenPoolRouterUpdated, error) { + event := new(TokenPoolRouterUpdated) + if err := _TokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_TokenPool *TokenPool) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _TokenPool.abi.Events["AllowListAdd"].ID: + return _TokenPool.ParseAllowListAdd(log) + case _TokenPool.abi.Events["AllowListRemove"].ID: + return _TokenPool.ParseAllowListRemove(log) + case _TokenPool.abi.Events["Burned"].ID: + return _TokenPool.ParseBurned(log) + case _TokenPool.abi.Events["ChainAdded"].ID: + return _TokenPool.ParseChainAdded(log) + case _TokenPool.abi.Events["ChainConfigured"].ID: + return _TokenPool.ParseChainConfigured(log) + case _TokenPool.abi.Events["ChainRemoved"].ID: + return _TokenPool.ParseChainRemoved(log) + case _TokenPool.abi.Events["ConfigChanged"].ID: + return _TokenPool.ParseConfigChanged(log) + case _TokenPool.abi.Events["Locked"].ID: + return _TokenPool.ParseLocked(log) + case _TokenPool.abi.Events["Minted"].ID: + return _TokenPool.ParseMinted(log) + case _TokenPool.abi.Events["OwnershipTransferRequested"].ID: + return _TokenPool.ParseOwnershipTransferRequested(log) + case _TokenPool.abi.Events["OwnershipTransferred"].ID: + return _TokenPool.ParseOwnershipTransferred(log) + case _TokenPool.abi.Events["Released"].ID: + return _TokenPool.ParseReleased(log) + case _TokenPool.abi.Events["RemotePoolSet"].ID: + return _TokenPool.ParseRemotePoolSet(log) + case _TokenPool.abi.Events["RouterUpdated"].ID: + return _TokenPool.ParseRouterUpdated(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (TokenPoolAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (TokenPoolAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (TokenPoolBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (TokenPoolChainAdded) Topic() common.Hash { + return common.HexToHash("0x8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2") +} + +func (TokenPoolChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (TokenPoolChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (TokenPoolConfigChanged) Topic() common.Hash { + return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") +} + +func (TokenPoolLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (TokenPoolMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (TokenPoolOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (TokenPoolOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (TokenPoolReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (TokenPoolRemotePoolSet) Topic() common.Hash { + return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +} + +func (TokenPoolRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (_TokenPool *TokenPool) Address() common.Address { + return _TokenPool.address +} + +type TokenPoolInterface interface { + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRmnProxy(opts *bind.CallOpts) (common.Address, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*TokenPoolAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *TokenPoolAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*TokenPoolAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*TokenPoolAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *TokenPoolAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*TokenPoolAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*TokenPoolBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *TokenPoolBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*TokenPoolBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*TokenPoolChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *TokenPoolChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*TokenPoolChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*TokenPoolChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *TokenPoolChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*TokenPoolChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*TokenPoolChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *TokenPoolChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*TokenPoolChainRemoved, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*TokenPoolConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *TokenPoolConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*TokenPoolConfigChanged, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*TokenPoolLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *TokenPoolLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*TokenPoolLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*TokenPoolMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *TokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*TokenPoolMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenPoolOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *TokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*TokenPoolOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenPoolOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*TokenPoolOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*TokenPoolReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *TokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*TokenPoolReleased, error) + + FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*TokenPoolRemotePoolSetIterator, error) + + WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *TokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolSet(log types.Log) (*TokenPoolRemotePoolSet, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*TokenPoolRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *TokenPoolRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*TokenPoolRouterUpdated, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/token_pool_1_4_0/token_pool_1_4_0.go b/core/gethwrappers/ccip/generated/token_pool_1_4_0/token_pool_1_4_0.go new file mode 100644 index 0000000000..477a32d0fd --- /dev/null +++ b/core/gethwrappers/ccip/generated/token_pool_1_4_0/token_pool_1_4_0.go @@ -0,0 +1,2221 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package token_pool_1_4_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +var TokenPoolMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRatelimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"releaseOrMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +var TokenPoolABI = TokenPoolMetaData.ABI + +type TokenPool struct { + address common.Address + abi abi.ABI + TokenPoolCaller + TokenPoolTransactor + TokenPoolFilterer +} + +type TokenPoolCaller struct { + contract *bind.BoundContract +} + +type TokenPoolTransactor struct { + contract *bind.BoundContract +} + +type TokenPoolFilterer struct { + contract *bind.BoundContract +} + +type TokenPoolSession struct { + Contract *TokenPool + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type TokenPoolCallerSession struct { + Contract *TokenPoolCaller + CallOpts bind.CallOpts +} + +type TokenPoolTransactorSession struct { + Contract *TokenPoolTransactor + TransactOpts bind.TransactOpts +} + +type TokenPoolRaw struct { + Contract *TokenPool +} + +type TokenPoolCallerRaw struct { + Contract *TokenPoolCaller +} + +type TokenPoolTransactorRaw struct { + Contract *TokenPoolTransactor +} + +func NewTokenPool(address common.Address, backend bind.ContractBackend) (*TokenPool, error) { + abi, err := abi.JSON(strings.NewReader(TokenPoolABI)) + if err != nil { + return nil, err + } + contract, err := bindTokenPool(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TokenPool{address: address, abi: abi, TokenPoolCaller: TokenPoolCaller{contract: contract}, TokenPoolTransactor: TokenPoolTransactor{contract: contract}, TokenPoolFilterer: TokenPoolFilterer{contract: contract}}, nil +} + +func NewTokenPoolCaller(address common.Address, caller bind.ContractCaller) (*TokenPoolCaller, error) { + contract, err := bindTokenPool(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TokenPoolCaller{contract: contract}, nil +} + +func NewTokenPoolTransactor(address common.Address, transactor bind.ContractTransactor) (*TokenPoolTransactor, error) { + contract, err := bindTokenPool(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TokenPoolTransactor{contract: contract}, nil +} + +func NewTokenPoolFilterer(address common.Address, filterer bind.ContractFilterer) (*TokenPoolFilterer, error) { + contract, err := bindTokenPool(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TokenPoolFilterer{contract: contract}, nil +} + +func bindTokenPool(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TokenPoolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_TokenPool *TokenPoolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TokenPool.Contract.TokenPoolCaller.contract.Call(opts, result, method, params...) +} + +func (_TokenPool *TokenPoolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenPool.Contract.TokenPoolTransactor.contract.Transfer(opts) +} + +func (_TokenPool *TokenPoolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TokenPool.Contract.TokenPoolTransactor.contract.Transact(opts, method, params...) +} + +func (_TokenPool *TokenPoolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TokenPool.Contract.contract.Call(opts, result, method, params...) +} + +func (_TokenPool *TokenPoolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenPool.Contract.contract.Transfer(opts) +} + +func (_TokenPool *TokenPoolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TokenPool.Contract.contract.Transact(opts, method, params...) +} + +func (_TokenPool *TokenPoolCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetAllowList() ([]common.Address, error) { + return _TokenPool.Contract.GetAllowList(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetAllowList() ([]common.Address, error) { + return _TokenPool.Contract.GetAllowList(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetAllowListEnabled() (bool, error) { + return _TokenPool.Contract.GetAllowListEnabled(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetAllowListEnabled() (bool, error) { + return _TokenPool.Contract.GetAllowListEnabled(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) GetArmProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getArmProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetArmProxy() (common.Address, error) { + return _TokenPool.Contract.GetArmProxy(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetArmProxy() (common.Address, error) { + return _TokenPool.Contract.GetArmProxy(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _TokenPool.Contract.GetCurrentInboundRateLimiterState(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _TokenPool.Contract.GetCurrentInboundRateLimiterState(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _TokenPool.Contract.GetCurrentOutboundRateLimiterState(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _TokenPool.Contract.GetCurrentOutboundRateLimiterState(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetRouter() (common.Address, error) { + return _TokenPool.Contract.GetRouter(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetRouter() (common.Address, error) { + return _TokenPool.Contract.GetRouter(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetSupportedChains() ([]uint64, error) { + return _TokenPool.Contract.GetSupportedChains(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetSupportedChains() ([]uint64, error) { + return _TokenPool.Contract.GetSupportedChains(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetToken() (common.Address, error) { + return _TokenPool.Contract.GetToken(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetToken() (common.Address, error) { + return _TokenPool.Contract.GetToken(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _TokenPool.Contract.IsSupportedChain(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _TokenPool.Contract.IsSupportedChain(&_TokenPool.CallOpts, remoteChainSelector) +} + +func (_TokenPool *TokenPoolCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) Owner() (common.Address, error) { + return _TokenPool.Contract.Owner(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) Owner() (common.Address, error) { + return _TokenPool.Contract.Owner(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _TokenPool.Contract.SupportsInterface(&_TokenPool.CallOpts, interfaceId) +} + +func (_TokenPool *TokenPoolCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _TokenPool.Contract.SupportsInterface(&_TokenPool.CallOpts, interfaceId) +} + +func (_TokenPool *TokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "acceptOwnership") +} + +func (_TokenPool *TokenPoolSession) AcceptOwnership() (*types.Transaction, error) { + return _TokenPool.Contract.AcceptOwnership(&_TokenPool.TransactOpts) +} + +func (_TokenPool *TokenPoolTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _TokenPool.Contract.AcceptOwnership(&_TokenPool.TransactOpts) +} + +func (_TokenPool *TokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_TokenPool *TokenPoolSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.ApplyAllowListUpdates(&_TokenPool.TransactOpts, removes, adds) +} + +func (_TokenPool *TokenPoolTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.ApplyAllowListUpdates(&_TokenPool.TransactOpts, removes, adds) +} + +func (_TokenPool *TokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_TokenPool *TokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _TokenPool.Contract.ApplyChainUpdates(&_TokenPool.TransactOpts, chains) +} + +func (_TokenPool *TokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _TokenPool.Contract.ApplyChainUpdates(&_TokenPool.TransactOpts, chains) +} + +func (_TokenPool *TokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, originalSender common.Address, receiver []byte, amount *big.Int, remoteChainSelector uint64, extraArgs []byte) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "lockOrBurn", originalSender, receiver, amount, remoteChainSelector, extraArgs) +} + +func (_TokenPool *TokenPoolSession) LockOrBurn(originalSender common.Address, receiver []byte, amount *big.Int, remoteChainSelector uint64, extraArgs []byte) (*types.Transaction, error) { + return _TokenPool.Contract.LockOrBurn(&_TokenPool.TransactOpts, originalSender, receiver, amount, remoteChainSelector, extraArgs) +} + +func (_TokenPool *TokenPoolTransactorSession) LockOrBurn(originalSender common.Address, receiver []byte, amount *big.Int, remoteChainSelector uint64, extraArgs []byte) (*types.Transaction, error) { + return _TokenPool.Contract.LockOrBurn(&_TokenPool.TransactOpts, originalSender, receiver, amount, remoteChainSelector, extraArgs) +} + +func (_TokenPool *TokenPoolTransactor) ReleaseOrMint(opts *bind.TransactOpts, originalSender []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, extraData []byte) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "releaseOrMint", originalSender, receiver, amount, remoteChainSelector, extraData) +} + +func (_TokenPool *TokenPoolSession) ReleaseOrMint(originalSender []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, extraData []byte) (*types.Transaction, error) { + return _TokenPool.Contract.ReleaseOrMint(&_TokenPool.TransactOpts, originalSender, receiver, amount, remoteChainSelector, extraData) +} + +func (_TokenPool *TokenPoolTransactorSession) ReleaseOrMint(originalSender []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, extraData []byte) (*types.Transaction, error) { + return _TokenPool.Contract.ReleaseOrMint(&_TokenPool.TransactOpts, originalSender, receiver, amount, remoteChainSelector, extraData) +} + +func (_TokenPool *TokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_TokenPool *TokenPoolSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _TokenPool.Contract.SetChainRateLimiterConfig(&_TokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_TokenPool *TokenPoolTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _TokenPool.Contract.SetChainRateLimiterConfig(&_TokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_TokenPool *TokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "setRouter", newRouter) +} + +func (_TokenPool *TokenPoolSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.SetRouter(&_TokenPool.TransactOpts, newRouter) +} + +func (_TokenPool *TokenPoolTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.SetRouter(&_TokenPool.TransactOpts, newRouter) +} + +func (_TokenPool *TokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "transferOwnership", to) +} + +func (_TokenPool *TokenPoolSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.TransferOwnership(&_TokenPool.TransactOpts, to) +} + +func (_TokenPool *TokenPoolTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.TransferOwnership(&_TokenPool.TransactOpts, to) +} + +type TokenPoolAllowListAddIterator struct { + Event *TokenPoolAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolAllowListAddIterator) Error() error { + return it.fail +} + +func (it *TokenPoolAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*TokenPoolAllowListAddIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &TokenPoolAllowListAddIterator{contract: _TokenPool.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *TokenPoolAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolAllowListAdd) + if err := _TokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseAllowListAdd(log types.Log) (*TokenPoolAllowListAdd, error) { + event := new(TokenPoolAllowListAdd) + if err := _TokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolAllowListRemoveIterator struct { + Event *TokenPoolAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *TokenPoolAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*TokenPoolAllowListRemoveIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &TokenPoolAllowListRemoveIterator{contract: _TokenPool.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *TokenPoolAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolAllowListRemove) + if err := _TokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseAllowListRemove(log types.Log) (*TokenPoolAllowListRemove, error) { + event := new(TokenPoolAllowListRemove) + if err := _TokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolBurnedIterator struct { + Event *TokenPoolBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolBurnedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*TokenPoolBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &TokenPoolBurnedIterator{contract: _TokenPool.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *TokenPoolBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolBurned) + if err := _TokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseBurned(log types.Log) (*TokenPoolBurned, error) { + event := new(TokenPoolBurned) + if err := _TokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolChainAddedIterator struct { + Event *TokenPoolChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolChainAddedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolChainAdded struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterChainAdded(opts *bind.FilterOpts) (*TokenPoolChainAddedIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &TokenPoolChainAddedIterator{contract: _TokenPool.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *TokenPoolChainAdded) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolChainAdded) + if err := _TokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseChainAdded(log types.Log) (*TokenPoolChainAdded, error) { + event := new(TokenPoolChainAdded) + if err := _TokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolChainConfiguredIterator struct { + Event *TokenPoolChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *TokenPoolChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*TokenPoolChainConfiguredIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &TokenPoolChainConfiguredIterator{contract: _TokenPool.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *TokenPoolChainConfigured) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolChainConfigured) + if err := _TokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseChainConfigured(log types.Log) (*TokenPoolChainConfigured, error) { + event := new(TokenPoolChainConfigured) + if err := _TokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolChainRemovedIterator struct { + Event *TokenPoolChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolChainRemovedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*TokenPoolChainRemovedIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &TokenPoolChainRemovedIterator{contract: _TokenPool.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *TokenPoolChainRemoved) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolChainRemoved) + if err := _TokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseChainRemoved(log types.Log) (*TokenPoolChainRemoved, error) { + event := new(TokenPoolChainRemoved) + if err := _TokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolLockedIterator struct { + Event *TokenPoolLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolLockedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*TokenPoolLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &TokenPoolLockedIterator{contract: _TokenPool.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *TokenPoolLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolLocked) + if err := _TokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseLocked(log types.Log) (*TokenPoolLocked, error) { + event := new(TokenPoolLocked) + if err := _TokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolMintedIterator struct { + Event *TokenPoolMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolMintedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*TokenPoolMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &TokenPoolMintedIterator{contract: _TokenPool.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *TokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolMinted) + if err := _TokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseMinted(log types.Log) (*TokenPoolMinted, error) { + event := new(TokenPoolMinted) + if err := _TokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolOwnershipTransferRequestedIterator struct { + Event *TokenPoolOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenPoolOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &TokenPoolOwnershipTransferRequestedIterator{contract: _TokenPool.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *TokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolOwnershipTransferRequested) + if err := _TokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseOwnershipTransferRequested(log types.Log) (*TokenPoolOwnershipTransferRequested, error) { + event := new(TokenPoolOwnershipTransferRequested) + if err := _TokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolOwnershipTransferredIterator struct { + Event *TokenPoolOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *TokenPoolOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenPoolOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &TokenPoolOwnershipTransferredIterator{contract: _TokenPool.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolOwnershipTransferred) + if err := _TokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseOwnershipTransferred(log types.Log) (*TokenPoolOwnershipTransferred, error) { + event := new(TokenPoolOwnershipTransferred) + if err := _TokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolReleasedIterator struct { + Event *TokenPoolReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolReleasedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*TokenPoolReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &TokenPoolReleasedIterator{contract: _TokenPool.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *TokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolReleased) + if err := _TokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseReleased(log types.Log) (*TokenPoolReleased, error) { + event := new(TokenPoolReleased) + if err := _TokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolRouterUpdatedIterator struct { + Event *TokenPoolRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *TokenPoolRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*TokenPoolRouterUpdatedIterator, error) { + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &TokenPoolRouterUpdatedIterator{contract: _TokenPool.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *TokenPoolRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolRouterUpdated) + if err := _TokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_TokenPool *TokenPoolFilterer) ParseRouterUpdated(log types.Log) (*TokenPoolRouterUpdated, error) { + event := new(TokenPoolRouterUpdated) + if err := _TokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_TokenPool *TokenPool) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _TokenPool.abi.Events["AllowListAdd"].ID: + return _TokenPool.ParseAllowListAdd(log) + case _TokenPool.abi.Events["AllowListRemove"].ID: + return _TokenPool.ParseAllowListRemove(log) + case _TokenPool.abi.Events["Burned"].ID: + return _TokenPool.ParseBurned(log) + case _TokenPool.abi.Events["ChainAdded"].ID: + return _TokenPool.ParseChainAdded(log) + case _TokenPool.abi.Events["ChainConfigured"].ID: + return _TokenPool.ParseChainConfigured(log) + case _TokenPool.abi.Events["ChainRemoved"].ID: + return _TokenPool.ParseChainRemoved(log) + case _TokenPool.abi.Events["Locked"].ID: + return _TokenPool.ParseLocked(log) + case _TokenPool.abi.Events["Minted"].ID: + return _TokenPool.ParseMinted(log) + case _TokenPool.abi.Events["OwnershipTransferRequested"].ID: + return _TokenPool.ParseOwnershipTransferRequested(log) + case _TokenPool.abi.Events["OwnershipTransferred"].ID: + return _TokenPool.ParseOwnershipTransferred(log) + case _TokenPool.abi.Events["Released"].ID: + return _TokenPool.ParseReleased(log) + case _TokenPool.abi.Events["RouterUpdated"].ID: + return _TokenPool.ParseRouterUpdated(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (TokenPoolAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (TokenPoolAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (TokenPoolBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (TokenPoolChainAdded) Topic() common.Hash { + return common.HexToHash("0x0f135cbb9afa12a8bf3bbd071c117bcca4ddeca6160ef7f33d012a81b9c0c471") +} + +func (TokenPoolChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (TokenPoolChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (TokenPoolLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (TokenPoolMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (TokenPoolOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (TokenPoolOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (TokenPoolReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (TokenPoolRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (_TokenPool *TokenPool) Address() common.Address { + return _TokenPool.address +} + +type TokenPoolInterface interface { + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetArmProxy(opts *bind.CallOpts) (common.Address, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, originalSender common.Address, receiver []byte, amount *big.Int, remoteChainSelector uint64, extraArgs []byte) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, originalSender []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, extraData []byte) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*TokenPoolAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *TokenPoolAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*TokenPoolAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*TokenPoolAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *TokenPoolAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*TokenPoolAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*TokenPoolBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *TokenPoolBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*TokenPoolBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*TokenPoolChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *TokenPoolChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*TokenPoolChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*TokenPoolChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *TokenPoolChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*TokenPoolChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*TokenPoolChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *TokenPoolChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*TokenPoolChainRemoved, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*TokenPoolLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *TokenPoolLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*TokenPoolLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*TokenPoolMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *TokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*TokenPoolMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenPoolOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *TokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*TokenPoolOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenPoolOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*TokenPoolOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*TokenPoolReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *TokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*TokenPoolReleased, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*TokenPoolRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *TokenPoolRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*TokenPoolRouterUpdated, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go new file mode 100644 index 0000000000..1e15b6b6cd --- /dev/null +++ b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go @@ -0,0 +1,3185 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package usdc_token_pool + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type PoolLockOrBurnInV1 struct { + Receiver []byte + RemoteChainSelector uint64 + OriginalSender common.Address + Amount *big.Int + LocalToken common.Address +} + +type PoolLockOrBurnOutV1 struct { + DestTokenAddress []byte + DestPoolData []byte +} + +type PoolReleaseOrMintInV1 struct { + OriginalSender []byte + RemoteChainSelector uint64 + Receiver common.Address + Amount *big.Int + LocalToken common.Address + SourcePoolAddress []byte + SourcePoolData []byte + OffchainTokenData []byte +} + +type PoolReleaseOrMintOutV1 struct { + DestinationAmount *big.Int +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + RemotePoolAddress []byte + RemoteTokenAddress []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +type USDCTokenPoolDomain struct { + AllowedCaller [32]byte + DomainIdentifier uint32 + Enabled bool +} + +type USDCTokenPoolDomainUpdate struct { + AllowedCaller [32]byte + DomainIdentifier uint32 + DestChainSelector uint64 + Enabled bool +} + +var USDCTokenPoolMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101406040523480156200001257600080fd5b506040516200559338038062005593833981016040819052620000359162000b4c565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200041b565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016957604080516000815260208101909152620001699084620004c6565b5050506001600160a01b038616905062000196576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fd919062000c72565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000240573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000266919062000c99565b905063ffffffff81161562000297576040516334697c6b60e11b815263ffffffff8216600482015260240162000087565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fe919062000c99565b905063ffffffff8116156200032f576040516316ba39c560e31b815263ffffffff8216600482015260240162000087565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa15801562000381573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a7919062000c99565b63ffffffff166101205260e051608051620003d1916001600160a01b039091169060001962000623565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000de6565b336001600160a01b03821603620004755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620004e7576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005725760008382815181106200050b576200050b62000cc1565b602090810291909101015190506200052560028262000709565b1562000568576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620004ea565b5060005b81518110156200061e57600082828151811062000597576200059762000cc1565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005c3575062000615565b620005d060028262000729565b1562000613576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000576565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200069b919062000cd7565b620006a7919062000d07565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000703918691906200074016565b50505050565b600062000720836001600160a01b03841662000811565b90505b92915050565b600062000720836001600160a01b03841662000915565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200078f906001600160a01b03851690849062000967565b8051909150156200061e5780806020019051810190620007b0919062000d1d565b6200061e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000087565b600081815260018301602052604081205480156200090a5760006200083860018362000d41565b85549091506000906200084e9060019062000d41565b9050818114620008ba57600086600001828154811062000872576200087262000cc1565b906000526020600020015490508087600001848154811062000898576200089862000cc1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620008ce57620008ce62000d57565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000723565b600091505062000723565b60008181526001830160205260408120546200095e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000723565b50600062000723565b606062000978848460008562000980565b949350505050565b606082471015620009e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000087565b600080866001600160a01b0316858760405162000a01919062000d93565b60006040518083038185875af1925050503d806000811462000a40576040519150601f19603f3d011682016040523d82523d6000602084013e62000a45565b606091505b50909250905062000a598783838762000a64565b979650505050505050565b6060831562000ad857825160000362000ad0576001600160a01b0385163b62000ad05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000087565b508162000978565b62000978838381511562000aef5781518083602001fd5b8060405162461bcd60e51b815260040162000087919062000db1565b6001600160a01b038116811462000b2157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b478162000b0b565b919050565b600080600080600060a0868803121562000b6557600080fd5b855162000b728162000b0b565b8095505060208087015162000b878162000b0b565b60408801519095506001600160401b038082111562000ba557600080fd5b818901915089601f83011262000bba57600080fd5b81518181111562000bcf5762000bcf62000b24565b8060051b604051601f19603f8301168101818110858211171562000bf75762000bf762000b24565b60405291825284820192508381018501918c83111562000c1657600080fd5b938501935b8285101562000c3f5762000c2f8562000b3a565b8452938501939285019262000c1b565b80985050505050505062000c566060870162000b3a565b915062000c666080870162000b3a565b90509295509295909350565b60006020828403121562000c8557600080fd5b815162000c928162000b0b565b9392505050565b60006020828403121562000cac57600080fd5b815163ffffffff8116811462000c9257600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000cea57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000723576200072362000cf1565b60006020828403121562000d3057600080fd5b8151801515811462000c9257600080fd5b8181038181111562000723576200072362000cf1565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d8a57818101518382015260200162000d70565b50506000910152565b6000825162000da781846020870162000d6d565b9190910192915050565b602081526000825180602084015262000dd281604085016020870162000d6d565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516146ed62000ea66000396000818161036c0152818161116601528181611d6d0152611dcb01526000818161062f0152610a31015260008181610345015261107a0152600081816105f301528181611ef5015261293c01526000818161052f01528181611b6b01526121ab015260008181610279015281816102ce01528181610af70152818161104701528181611a8b015281816120cb015281816127c60152612b2701526146ed6000f3fe608060405234801561001057600080fd5b50600436106101d95760003560e01c80639fdf13ff11610104578063c75eea9c116100a2578063dfadfa3511610071578063dfadfa3514610553578063e0351e13146105f1578063f2fde38b14610617578063fbf84dd71461062a57600080fd5b8063c75eea9c146104f4578063cf7401f314610507578063db6327dc1461051a578063dc0bd9711461052d57600080fd5b8063b0f479a1116100de578063b0f479a11461049b578063b7946580146104b9578063c0d78655146104cc578063c4bffe2b146104df57600080fd5b80639fdf13ff1461040f578063a7cd63b714610417578063af58d59f1461042c57600080fd5b806354c8a4f31161017c57806379ba50971161014b57806379ba5097146103b65780638926f54f146103be5780638da5cb5b146103d15780639a4575b9146103ef57600080fd5b806354c8a4f31461032d5780636155cda0146103405780636b716b0d1461036757806378a010b2146103a357600080fd5b8063181f5a77116101b8578063181f5a771461023b57806321df0da714610277578063240028e8146102be578063390775371461030b57600080fd5b806241d3c1146101de57806301ffc9a7146101f35780630a2fd4931461021b575b600080fd5b6101f16101ec3660046134d1565b610651565b005b610206610201366004613546565b6107ee565b60405190151581526020015b60405180910390f35b61022e6102293660046135ae565b6108d3565b6040516102129190613639565b61022e6040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e342e300000000000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610212565b6102066102cc366004613679565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61031e610319366004613696565b610983565b60405190518152602001610212565b6101f161033b36600461371e565b610bb5565b6102997f000000000000000000000000000000000000000000000000000000000000000081565b61038e7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610212565b6101f16103b136600461378a565b610c30565b6101f1610d9f565b6102066103cc3660046135ae565b610e9c565b60005473ffffffffffffffffffffffffffffffffffffffff16610299565b6104026103fd36600461380f565b610eb3565b604051610212919061384a565b61038e600081565b61041f6111e0565b60405161021291906138aa565b61043f61043a3660046135ae565b6111f1565b604051610212919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610299565b61022e6104c73660046135ae565b6112c6565b6101f16104da366004613679565b6112f1565b6104e76113c5565b6040516102129190613904565b61043f6105023660046135ae565b61147d565b6101f1610515366004613a8f565b61154f565b6101f1610528366004613ad6565b611567565b7f0000000000000000000000000000000000000000000000000000000000000000610299565b6105c76105613660046135ae565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600882529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610212565b7f0000000000000000000000000000000000000000000000000000000000000000610206565b6101f1610625366004613679565b6119ed565b6102997f000000000000000000000000000000000000000000000000000000000000000081565b610659611a01565b60005b818110156107b057600083838381811061067857610678613b18565b90506080020180360381019061068e9190613b5b565b805190915015806106ab5750604081015167ffffffffffffffff16155b1561071a57604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600890925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090951691909316179290921790550161065c565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee5682826040516107e2929190613bd5565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061088157507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806108cd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906108fe90613c5c565b80601f016020809104026020016040519081016040528092919081815260200182805461092a90613c5c565b80156109775780601f1061094c57610100808354040283529160200191610977565b820191906000526020600020905b81548152906001019060200180831161095a57829003601f168201915b50505050509050919050565b6040805160208101909152600081526109a361099e83613d5a565b611a84565b60006109b260c0840184613e4f565b8101906109bf9190613eb4565b905060006109d060e0850185613e4f565b8101906109dd9190613ef3565b90506109ed816000015183611cb5565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610a6492600401613f84565b6020604051808303816000875af1158015610a83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa79190613fa9565b610add576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b2273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016336060870135611e66565b610b326060850160408601613679565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610b9491815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b610bbd611a01565b610c2a84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ef392505050565b50505050565b610c38611a01565b610c4183610e9c565b610c83576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610711565b67ffffffffffffffff831660009081526007602052604081206004018054610caa90613c5c565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd690613c5c565b8015610d235780601f10610cf857610100808354040283529160200191610d23565b820191906000526020600020905b815481529060010190602001808311610d0657829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610d5283858361400e565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d9193929190614172565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610711565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006108cd600567ffffffffffffffff84166120a9565b6040805180820190915260608082526020820152610ed8610ed3836141a2565b6120c4565b6000600881610eed60408601602087016135ae565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff161515908201819052909150610f9457610f5560408401602085016135ae565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610711565b610f9e8380613e4f565b9050602014610fe557610fb18380613e4f565b6040517fa3c8cf09000000000000000000000000000000000000000000000000000000008152600401610711929190614246565b602081015181516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060860135600482015263ffffffff90921660248301526044820181905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091526000917f00000000000000000000000000000000000000000000000000000000000000009091169063f856ddb69060a4016020604051808303816000875af11580156110c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e9919061425a565b6040516060860135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260405180604001604052806111468660200160208101906104c791906135ae565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529052949350505050565b60606111ec600261228e565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526108cd9061229b565b67ffffffffffffffff811660009081526007602052604090206005018054606091906108fe90613c5c565b6112f9611a01565b73ffffffffffffffffffffffffffffffffffffffff8116611346576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f168491016107e2565b606060006113d3600561228e565b90506000815167ffffffffffffffff8111156113f1576113f1613946565b60405190808252806020026020018201604052801561141a578160200160208202803683370190505b50905060005b82518110156114765782818151811061143b5761143b613b18565b602002602001015182828151811061145557611455613b18565b67ffffffffffffffff90921660209283029190910190910152600101611420565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526108cd9061229b565b611557611a01565b61156283838361234d565b505050565b61156f611a01565b60005b8181101561156257600083838381811061158e5761158e613b18565b90506020028101906115a09190614277565b6115a9906142b5565b90506115be8160800151826020015115612437565b6115d18160a00151826020015115612437565b8060200151156118cd5780516115f39060059067ffffffffffffffff16612570565b6116385780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610711565b604081015151158061164d5750606081015151155b15611684576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906118659082614369565b506060820151600582019061187a9082614369565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506118c09493929190614483565b60405180910390a16119e4565b80516118e59060059067ffffffffffffffff1661257c565b61192a5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610711565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906119936004830182613483565b6119a1600583016000613483565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611572565b6119f5611a01565b6119fe81612588565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610711565b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611b195760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610711565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611bc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611beb9190613fa9565b15611c22576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c2f816020015161267d565b6000611c3e82602001516108d3565b9050805160001480611c62575080805190602001208260a001518051906020012014155b15611c9f578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107119190613639565b611cb1826020015183606001516127a3565b5050565b600482015163ffffffff811615611d00576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610711565b6008830151600c8401516014850151602085015163ffffffff808516911614611d6b5760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff91821660048201529084166024820152604401610711565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611e00576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015283166024820152604401610711565b845167ffffffffffffffff828116911614611e5e5784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821660048201529082166024820152604401610711565b505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526115629084906127ea565b7f0000000000000000000000000000000000000000000000000000000000000000611f4a576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611fe0576000838281518110611f6a57611f6a613b18565b60200260200101519050611f888160026128f690919063ffffffff16565b15611fd75760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f4d565b5060005b815181101561156257600082828151811061200157612001613b18565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361204557506120a1565b612050600282612918565b1561209f5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611fe4565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121595760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610711565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612207573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222b9190613fa9565b15612262576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61226f816040015161293a565b61227c81602001516129b9565b6119fe81602001518260600151612b07565b606060006120bd83612b4b565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261232982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261230d919061454b565b85608001516fffffffffffffffffffffffffffffffff16612ba6565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61235683610e9c565b612398576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610711565b6123a3826000612437565b67ffffffffffffffff831660009081526007602052604090206123c69083612bd0565b6123d1816000612437565b67ffffffffffffffff831660009081526007602052604090206123f79060020182612bd0565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161242a9392919061455e565b60405180910390a1505050565b8151156124fe5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061248d575060408201516fffffffffffffffffffffffffffffffff16155b156124c657816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161071191906145e1565b8015611cb1576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612537575060208201516fffffffffffffffffffffffffffffffff1615155b15611cb157816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161071191906145e1565b60006120bd8383612d72565b60006120bd8383612dc1565b3373ffffffffffffffffffffffffffffffffffffffff821603612607576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610711565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61268681610e9c565b6126c8576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610711565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612747573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276b9190613fa9565b6119fe576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610711565b67ffffffffffffffff82166000908152600760205260409020611cb190600201827f0000000000000000000000000000000000000000000000000000000000000000612eb4565b600061284c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166132379092919063ffffffff16565b805190915015611562578080602001905181019061286a9190613fa9565b611562576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610711565b60006120bd8373ffffffffffffffffffffffffffffffffffffffff8416612dc1565b60006120bd8373ffffffffffffffffffffffffffffffffffffffff8416612d72565b7f0000000000000000000000000000000000000000000000000000000000000000156119fe5761296b600282613246565b6119fe576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610711565b6129c281610e9c565b612a04576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610711565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612a7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aa1919061461d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146119fe576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610711565b67ffffffffffffffff82166000908152600760205260409020611cb190827f0000000000000000000000000000000000000000000000000000000000000000612eb4565b60608160000180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020905b815481526020019060010190808311612b875750505050509050919050565b6000612bc585612bb6848661463a565b612bc09087614651565b613275565b90505b949350505050565b8154600090612bf990700100000000000000000000000000000000900463ffffffff164261454b565b90508015612c9b5760018301548354612c41916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612ba6565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612cc1916fffffffffffffffffffffffffffffffff9081169116613275565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061242a9084906145e1565b6000818152600183016020526040812054612db9575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108cd565b5060006108cd565b60008181526001830160205260408120548015612eaa576000612de560018361454b565b8554909150600090612df99060019061454b565b9050818114612e5e576000866000018281548110612e1957612e19613b18565b9060005260206000200154905080876000018481548110612e3c57612e3c613b18565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612e6f57612e6f614664565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108cd565b60009150506108cd565b825474010000000000000000000000000000000000000000900460ff161580612edb575081155b15612ee557505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612f2b90700100000000000000000000000000000000900463ffffffff164261454b565b90508015612feb5781831115612f6d576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612fa79083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612ba6565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156130a25773ffffffffffffffffffffffffffffffffffffffff841661304a576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610711565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610711565b848310156131b55760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906130e6908261454b565b6130f0878a61454b565b6130fa9190614651565b6131049190614693565b905073ffffffffffffffffffffffffffffffffffffffff861661315d576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610711565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610711565b6131bf858461454b565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6060612bc8848460008561328b565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156120bd565b600081831061328457816120bd565b5090919050565b60608247101561331d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610711565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161334691906146ce565b60006040518083038185875af1925050503d8060008114613383576040519150601f19603f3d011682016040523d82523d6000602084013e613388565b606091505b5091509150613399878383876133a4565b979650505050505050565b6060831561343a5782516000036134335773ffffffffffffffffffffffffffffffffffffffff85163b613433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610711565b5081612bc8565b612bc8838381511561344f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107119190613639565b50805461348f90613c5c565b6000825580601f1061349f575050565b601f0160209004906000526020600020908101906119fe91905b808211156134cd57600081556001016134b9565b5090565b600080602083850312156134e457600080fd5b823567ffffffffffffffff808211156134fc57600080fd5b818501915085601f83011261351057600080fd5b81358181111561351f57600080fd5b8660208260071b850101111561353457600080fd5b60209290920196919550909350505050565b60006020828403121561355857600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146120bd57600080fd5b67ffffffffffffffff811681146119fe57600080fd5b80356135a981613588565b919050565b6000602082840312156135c057600080fd5b81356120bd81613588565b60005b838110156135e65781810151838201526020016135ce565b50506000910152565b600081518084526136078160208601602086016135cb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006120bd60208301846135ef565b73ffffffffffffffffffffffffffffffffffffffff811681146119fe57600080fd5b80356135a98161364c565b60006020828403121561368b57600080fd5b81356120bd8161364c565b6000602082840312156136a857600080fd5b813567ffffffffffffffff8111156136bf57600080fd5b820161010081850312156120bd57600080fd5b60008083601f8401126136e457600080fd5b50813567ffffffffffffffff8111156136fc57600080fd5b6020830191508360208260051b850101111561371757600080fd5b9250929050565b6000806000806040858703121561373457600080fd5b843567ffffffffffffffff8082111561374c57600080fd5b613758888389016136d2565b9096509450602087013591508082111561377157600080fd5b5061377e878288016136d2565b95989497509550505050565b60008060006040848603121561379f57600080fd5b83356137aa81613588565b9250602084013567ffffffffffffffff808211156137c757600080fd5b818601915086601f8301126137db57600080fd5b8135818111156137ea57600080fd5b8760208285010111156137fc57600080fd5b6020830194508093505050509250925092565b60006020828403121561382157600080fd5b813567ffffffffffffffff81111561383857600080fd5b820160a081850312156120bd57600080fd5b60208152600082516040602084015261386660608401826135ef565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526138a182826135ef565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156138f857835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016138c6565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156138f857835167ffffffffffffffff1683529284019291840191600101613920565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561399957613999613946565b60405290565b6040805190810167ffffffffffffffff8111828210171561399957613999613946565b60405160c0810167ffffffffffffffff8111828210171561399957613999613946565b80151581146119fe57600080fd5b80356135a9816139e5565b80356fffffffffffffffffffffffffffffffff811681146135a957600080fd5b600060608284031215613a3057600080fd5b6040516060810181811067ffffffffffffffff82111715613a5357613a53613946565b6040529050808235613a64816139e5565b8152613a72602084016139fe565b6020820152613a83604084016139fe565b60408201525092915050565b600080600060e08486031215613aa457600080fd5b8335613aaf81613588565b9250613abe8560208601613a1e565b9150613acd8560808601613a1e565b90509250925092565b60008060208385031215613ae957600080fd5b823567ffffffffffffffff811115613b0057600080fd5b613b0c858286016136d2565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff811681146135a957600080fd5b600060808284031215613b6d57600080fd5b6040516080810181811067ffffffffffffffff82111715613b9057613b90613946565b60405282358152613ba360208401613b47565b60208201526040830135613bb681613588565b60408201526060830135613bc9816139e5565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613c4f578135835263ffffffff613c07868401613b47565b168584015283820135613c1981613588565b67ffffffffffffffff1683850152606082810135613c36816139e5565b1515908401526080928301929190910190600101613beb565b5090979650505050505050565b600181811c90821680613c7057607f821691505b602082108103613ca9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f830112613cc057600080fd5b813567ffffffffffffffff80821115613cdb57613cdb613946565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613d2157613d21613946565b81604052838152866020858801011115613d3a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613d6d57600080fd5b613d75613975565b823567ffffffffffffffff80821115613d8d57600080fd5b613d9936838701613caf565b8352613da76020860161359e565b6020840152613db86040860161366e565b604084015260608501356060840152613dd36080860161366e565b608084015260a0850135915080821115613dec57600080fd5b613df836838701613caf565b60a084015260c0850135915080821115613e1157600080fd5b613e1d36838701613caf565b60c084015260e0850135915080821115613e3657600080fd5b50613e4336828601613caf565b60e08301525092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613e8457600080fd5b83018035915067ffffffffffffffff821115613e9f57600080fd5b60200191503681900382131561371757600080fd5b600060408284031215613ec657600080fd5b613ece61399f565b8235613ed981613588565b8152613ee760208401613b47565b60208201529392505050565b600060208284031215613f0557600080fd5b813567ffffffffffffffff80821115613f1d57600080fd5b9083019060408286031215613f3157600080fd5b613f3961399f565b823582811115613f4857600080fd5b613f5487828601613caf565b825250602083013582811115613f6957600080fd5b613f7587828601613caf565b60208301525095945050505050565b604081526000613f9760408301856135ef565b82810360208401526138a181856135ef565b600060208284031215613fbb57600080fd5b81516120bd816139e5565b601f821115611562576000816000526020600020601f850160051c81016020861015613fef5750805b601f850160051c820191505b81811015611e5e57828155600101613ffb565b67ffffffffffffffff83111561402657614026613946565b61403a836140348354613c5c565b83613fc6565b6000601f84116001811461408c57600085156140565750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614122565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140db57868501358255602094850194600190920191016140bb565b5086821015614116577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60408152600061418560408301866135ef565b8281036020840152614198818587614129565b9695505050505050565b600060a082360312156141b457600080fd5b60405160a0810167ffffffffffffffff82821081831117156141d8576141d8613946565b8160405284359150808211156141ed57600080fd5b506141fa36828601613caf565b825250602083013561420b81613588565b6020820152604083013561421e8161364c565b604082015260608381013590820152608083013561423b8161364c565b608082015292915050565b602081526000612bc8602083018486614129565b60006020828403121561426c57600080fd5b81516120bd81613588565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126142ab57600080fd5b9190910192915050565b600061014082360312156142c857600080fd5b6142d06139c2565b6142d98361359e565b81526142e7602084016139f3565b6020820152604083013567ffffffffffffffff8082111561430757600080fd5b61431336838701613caf565b6040840152606085013591508082111561432c57600080fd5b5061433936828601613caf565b60608301525061434c3660808501613a1e565b608082015261435e3660e08501613a1e565b60a082015292915050565b815167ffffffffffffffff81111561438357614383613946565b614397816143918454613c5c565b84613fc6565b602080601f8311600181146143ea57600084156143b45750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611e5e565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561443757888601518255948401946001909101908401614418565b508582101561447357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526144a7818401876135ef565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506144e59050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526138a1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156108cd576108cd61451c565b67ffffffffffffffff8416815260e081016145aa60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612bc8565b606081016108cd82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561462f57600080fd5b81516120bd8161364c565b80820281158282048414176108cd576108cd61451c565b808201808211156108cd576108cd61451c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826146c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082516142ab8184602087016135cb56fea164736f6c6343000818000a", +} + +var USDCTokenPoolABI = USDCTokenPoolMetaData.ABI + +var USDCTokenPoolBin = USDCTokenPoolMetaData.Bin + +func DeployUSDCTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, tokenMessenger common.Address, token common.Address, allowlist []common.Address, rmnProxy common.Address, router common.Address) (common.Address, *types.Transaction, *USDCTokenPool, error) { + parsed, err := USDCTokenPoolMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(USDCTokenPoolBin), backend, tokenMessenger, token, allowlist, rmnProxy, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &USDCTokenPool{address: address, abi: *parsed, USDCTokenPoolCaller: USDCTokenPoolCaller{contract: contract}, USDCTokenPoolTransactor: USDCTokenPoolTransactor{contract: contract}, USDCTokenPoolFilterer: USDCTokenPoolFilterer{contract: contract}}, nil +} + +type USDCTokenPool struct { + address common.Address + abi abi.ABI + USDCTokenPoolCaller + USDCTokenPoolTransactor + USDCTokenPoolFilterer +} + +type USDCTokenPoolCaller struct { + contract *bind.BoundContract +} + +type USDCTokenPoolTransactor struct { + contract *bind.BoundContract +} + +type USDCTokenPoolFilterer struct { + contract *bind.BoundContract +} + +type USDCTokenPoolSession struct { + Contract *USDCTokenPool + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type USDCTokenPoolCallerSession struct { + Contract *USDCTokenPoolCaller + CallOpts bind.CallOpts +} + +type USDCTokenPoolTransactorSession struct { + Contract *USDCTokenPoolTransactor + TransactOpts bind.TransactOpts +} + +type USDCTokenPoolRaw struct { + Contract *USDCTokenPool +} + +type USDCTokenPoolCallerRaw struct { + Contract *USDCTokenPoolCaller +} + +type USDCTokenPoolTransactorRaw struct { + Contract *USDCTokenPoolTransactor +} + +func NewUSDCTokenPool(address common.Address, backend bind.ContractBackend) (*USDCTokenPool, error) { + abi, err := abi.JSON(strings.NewReader(USDCTokenPoolABI)) + if err != nil { + return nil, err + } + contract, err := bindUSDCTokenPool(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &USDCTokenPool{address: address, abi: abi, USDCTokenPoolCaller: USDCTokenPoolCaller{contract: contract}, USDCTokenPoolTransactor: USDCTokenPoolTransactor{contract: contract}, USDCTokenPoolFilterer: USDCTokenPoolFilterer{contract: contract}}, nil +} + +func NewUSDCTokenPoolCaller(address common.Address, caller bind.ContractCaller) (*USDCTokenPoolCaller, error) { + contract, err := bindUSDCTokenPool(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &USDCTokenPoolCaller{contract: contract}, nil +} + +func NewUSDCTokenPoolTransactor(address common.Address, transactor bind.ContractTransactor) (*USDCTokenPoolTransactor, error) { + contract, err := bindUSDCTokenPool(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &USDCTokenPoolTransactor{contract: contract}, nil +} + +func NewUSDCTokenPoolFilterer(address common.Address, filterer bind.ContractFilterer) (*USDCTokenPoolFilterer, error) { + contract, err := bindUSDCTokenPool(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &USDCTokenPoolFilterer{contract: contract}, nil +} + +func bindUSDCTokenPool(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := USDCTokenPoolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_USDCTokenPool *USDCTokenPoolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _USDCTokenPool.Contract.USDCTokenPoolCaller.contract.Call(opts, result, method, params...) +} + +func (_USDCTokenPool *USDCTokenPoolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _USDCTokenPool.Contract.USDCTokenPoolTransactor.contract.Transfer(opts) +} + +func (_USDCTokenPool *USDCTokenPoolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _USDCTokenPool.Contract.USDCTokenPoolTransactor.contract.Transact(opts, method, params...) +} + +func (_USDCTokenPool *USDCTokenPoolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _USDCTokenPool.Contract.contract.Call(opts, result, method, params...) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _USDCTokenPool.Contract.contract.Transfer(opts) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _USDCTokenPool.Contract.contract.Transact(opts, method, params...) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) SUPPORTEDUSDCVERSION(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "SUPPORTED_USDC_VERSION") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) SUPPORTEDUSDCVERSION() (uint32, error) { + return _USDCTokenPool.Contract.SUPPORTEDUSDCVERSION(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) SUPPORTEDUSDCVERSION() (uint32, error) { + return _USDCTokenPool.Contract.SUPPORTEDUSDCVERSION(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetAllowList() ([]common.Address, error) { + return _USDCTokenPool.Contract.GetAllowList(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetAllowList() ([]common.Address, error) { + return _USDCTokenPool.Contract.GetAllowList(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetAllowListEnabled() (bool, error) { + return _USDCTokenPool.Contract.GetAllowListEnabled(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetAllowListEnabled() (bool, error) { + return _USDCTokenPool.Contract.GetAllowListEnabled(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _USDCTokenPool.Contract.GetCurrentInboundRateLimiterState(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _USDCTokenPool.Contract.GetCurrentInboundRateLimiterState(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _USDCTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _USDCTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetDomain(opts *bind.CallOpts, chainSelector uint64) (USDCTokenPoolDomain, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getDomain", chainSelector) + + if err != nil { + return *new(USDCTokenPoolDomain), err + } + + out0 := *abi.ConvertType(out[0], new(USDCTokenPoolDomain)).(*USDCTokenPoolDomain) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetDomain(chainSelector uint64) (USDCTokenPoolDomain, error) { + return _USDCTokenPool.Contract.GetDomain(&_USDCTokenPool.CallOpts, chainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetDomain(chainSelector uint64) (USDCTokenPoolDomain, error) { + return _USDCTokenPool.Contract.GetDomain(&_USDCTokenPool.CallOpts, chainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _USDCTokenPool.Contract.GetRemotePool(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _USDCTokenPool.Contract.GetRemotePool(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getRemoteToken", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _USDCTokenPool.Contract.GetRemoteToken(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _USDCTokenPool.Contract.GetRemoteToken(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetRmnProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getRmnProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetRmnProxy() (common.Address, error) { + return _USDCTokenPool.Contract.GetRmnProxy(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetRmnProxy() (common.Address, error) { + return _USDCTokenPool.Contract.GetRmnProxy(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetRouter() (common.Address, error) { + return _USDCTokenPool.Contract.GetRouter(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetRouter() (common.Address, error) { + return _USDCTokenPool.Contract.GetRouter(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetSupportedChains() ([]uint64, error) { + return _USDCTokenPool.Contract.GetSupportedChains(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetSupportedChains() ([]uint64, error) { + return _USDCTokenPool.Contract.GetSupportedChains(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetToken() (common.Address, error) { + return _USDCTokenPool.Contract.GetToken(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetToken() (common.Address, error) { + return _USDCTokenPool.Contract.GetToken(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) ILocalDomainIdentifier(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "i_localDomainIdentifier") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) ILocalDomainIdentifier() (uint32, error) { + return _USDCTokenPool.Contract.ILocalDomainIdentifier(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) ILocalDomainIdentifier() (uint32, error) { + return _USDCTokenPool.Contract.ILocalDomainIdentifier(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) IMessageTransmitter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "i_messageTransmitter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) IMessageTransmitter() (common.Address, error) { + return _USDCTokenPool.Contract.IMessageTransmitter(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) IMessageTransmitter() (common.Address, error) { + return _USDCTokenPool.Contract.IMessageTransmitter(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) ITokenMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "i_tokenMessenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) ITokenMessenger() (common.Address, error) { + return _USDCTokenPool.Contract.ITokenMessenger(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) ITokenMessenger() (common.Address, error) { + return _USDCTokenPool.Contract.ITokenMessenger(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _USDCTokenPool.Contract.IsSupportedChain(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _USDCTokenPool.Contract.IsSupportedChain(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "isSupportedToken", token) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) IsSupportedToken(token common.Address) (bool, error) { + return _USDCTokenPool.Contract.IsSupportedToken(&_USDCTokenPool.CallOpts, token) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) IsSupportedToken(token common.Address) (bool, error) { + return _USDCTokenPool.Contract.IsSupportedToken(&_USDCTokenPool.CallOpts, token) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) Owner() (common.Address, error) { + return _USDCTokenPool.Contract.Owner(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) Owner() (common.Address, error) { + return _USDCTokenPool.Contract.Owner(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _USDCTokenPool.Contract.SupportsInterface(&_USDCTokenPool.CallOpts, interfaceId) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _USDCTokenPool.Contract.SupportsInterface(&_USDCTokenPool.CallOpts, interfaceId) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) TypeAndVersion() (string, error) { + return _USDCTokenPool.Contract.TypeAndVersion(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) TypeAndVersion() (string, error) { + return _USDCTokenPool.Contract.TypeAndVersion(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "acceptOwnership") +} + +func (_USDCTokenPool *USDCTokenPoolSession) AcceptOwnership() (*types.Transaction, error) { + return _USDCTokenPool.Contract.AcceptOwnership(&_USDCTokenPool.TransactOpts) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _USDCTokenPool.Contract.AcceptOwnership(&_USDCTokenPool.TransactOpts) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_USDCTokenPool *USDCTokenPoolSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ApplyAllowListUpdates(&_USDCTokenPool.TransactOpts, removes, adds) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ApplyAllowListUpdates(&_USDCTokenPool.TransactOpts, removes, adds) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_USDCTokenPool *USDCTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ApplyChainUpdates(&_USDCTokenPool.TransactOpts, chains) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ApplyChainUpdates(&_USDCTokenPool.TransactOpts, chains) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "lockOrBurn", lockOrBurnIn) +} + +func (_USDCTokenPool *USDCTokenPoolSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _USDCTokenPool.Contract.LockOrBurn(&_USDCTokenPool.TransactOpts, lockOrBurnIn) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _USDCTokenPool.Contract.LockOrBurn(&_USDCTokenPool.TransactOpts, lockOrBurnIn) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "releaseOrMint", releaseOrMintIn) +} + +func (_USDCTokenPool *USDCTokenPoolSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ReleaseOrMint(&_USDCTokenPool.TransactOpts, releaseOrMintIn) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ReleaseOrMint(&_USDCTokenPool.TransactOpts, releaseOrMintIn) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_USDCTokenPool *USDCTokenPoolSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetChainRateLimiterConfig(&_USDCTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetChainRateLimiterConfig(&_USDCTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) SetDomains(opts *bind.TransactOpts, domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "setDomains", domains) +} + +func (_USDCTokenPool *USDCTokenPoolSession) SetDomains(domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetDomains(&_USDCTokenPool.TransactOpts, domains) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetDomains(domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetDomains(&_USDCTokenPool.TransactOpts, domains) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_USDCTokenPool *USDCTokenPoolSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetRemotePool(&_USDCTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetRemotePool(&_USDCTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "setRouter", newRouter) +} + +func (_USDCTokenPool *USDCTokenPoolSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetRouter(&_USDCTokenPool.TransactOpts, newRouter) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetRouter(&_USDCTokenPool.TransactOpts, newRouter) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "transferOwnership", to) +} + +func (_USDCTokenPool *USDCTokenPoolSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.TransferOwnership(&_USDCTokenPool.TransactOpts, to) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.TransferOwnership(&_USDCTokenPool.TransactOpts, to) +} + +type USDCTokenPoolAllowListAddIterator struct { + Event *USDCTokenPoolAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolAllowListAddIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*USDCTokenPoolAllowListAddIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &USDCTokenPoolAllowListAddIterator{contract: _USDCTokenPool.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolAllowListAdd) + if err := _USDCTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseAllowListAdd(log types.Log) (*USDCTokenPoolAllowListAdd, error) { + event := new(USDCTokenPoolAllowListAdd) + if err := _USDCTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolAllowListRemoveIterator struct { + Event *USDCTokenPoolAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*USDCTokenPoolAllowListRemoveIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &USDCTokenPoolAllowListRemoveIterator{contract: _USDCTokenPool.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolAllowListRemove) + if err := _USDCTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseAllowListRemove(log types.Log) (*USDCTokenPoolAllowListRemove, error) { + event := new(USDCTokenPoolAllowListRemove) + if err := _USDCTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolBurnedIterator struct { + Event *USDCTokenPoolBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolBurnedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*USDCTokenPoolBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolBurnedIterator{contract: _USDCTokenPool.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolBurned) + if err := _USDCTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseBurned(log types.Log) (*USDCTokenPoolBurned, error) { + event := new(USDCTokenPoolBurned) + if err := _USDCTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolChainAddedIterator struct { + Event *USDCTokenPoolChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolChainAddedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolChainAdded struct { + RemoteChainSelector uint64 + RemoteToken []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterChainAdded(opts *bind.FilterOpts) (*USDCTokenPoolChainAddedIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &USDCTokenPoolChainAddedIterator{contract: _USDCTokenPool.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolChainAdded) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolChainAdded) + if err := _USDCTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseChainAdded(log types.Log) (*USDCTokenPoolChainAdded, error) { + event := new(USDCTokenPoolChainAdded) + if err := _USDCTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolChainConfiguredIterator struct { + Event *USDCTokenPoolChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*USDCTokenPoolChainConfiguredIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &USDCTokenPoolChainConfiguredIterator{contract: _USDCTokenPool.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolChainConfigured) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolChainConfigured) + if err := _USDCTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseChainConfigured(log types.Log) (*USDCTokenPoolChainConfigured, error) { + event := new(USDCTokenPoolChainConfigured) + if err := _USDCTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolChainRemovedIterator struct { + Event *USDCTokenPoolChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolChainRemovedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*USDCTokenPoolChainRemovedIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &USDCTokenPoolChainRemovedIterator{contract: _USDCTokenPool.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolChainRemoved) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolChainRemoved) + if err := _USDCTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseChainRemoved(log types.Log) (*USDCTokenPoolChainRemoved, error) { + event := new(USDCTokenPoolChainRemoved) + if err := _USDCTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolConfigChangedIterator struct { + Event *USDCTokenPoolConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolConfigChangedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolConfigChanged struct { + Config RateLimiterConfig + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*USDCTokenPoolConfigChangedIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &USDCTokenPoolConfigChangedIterator{contract: _USDCTokenPool.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolConfigChanged) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolConfigChanged) + if err := _USDCTokenPool.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseConfigChanged(log types.Log) (*USDCTokenPoolConfigChanged, error) { + event := new(USDCTokenPoolConfigChanged) + if err := _USDCTokenPool.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolConfigSetIterator struct { + Event *USDCTokenPoolConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolConfigSetIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolConfigSet struct { + TokenMessenger common.Address + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterConfigSet(opts *bind.FilterOpts) (*USDCTokenPoolConfigSetIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &USDCTokenPoolConfigSetIterator{contract: _USDCTokenPool.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolConfigSet) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolConfigSet) + if err := _USDCTokenPool.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseConfigSet(log types.Log) (*USDCTokenPoolConfigSet, error) { + event := new(USDCTokenPoolConfigSet) + if err := _USDCTokenPool.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolDomainsSetIterator struct { + Event *USDCTokenPoolDomainsSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolDomainsSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolDomainsSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolDomainsSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolDomainsSetIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolDomainsSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolDomainsSet struct { + Arg0 []USDCTokenPoolDomainUpdate + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterDomainsSet(opts *bind.FilterOpts) (*USDCTokenPoolDomainsSetIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "DomainsSet") + if err != nil { + return nil, err + } + return &USDCTokenPoolDomainsSetIterator{contract: _USDCTokenPool.contract, event: "DomainsSet", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchDomainsSet(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolDomainsSet) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "DomainsSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolDomainsSet) + if err := _USDCTokenPool.contract.UnpackLog(event, "DomainsSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseDomainsSet(log types.Log) (*USDCTokenPoolDomainsSet, error) { + event := new(USDCTokenPoolDomainsSet) + if err := _USDCTokenPool.contract.UnpackLog(event, "DomainsSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolLockedIterator struct { + Event *USDCTokenPoolLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolLockedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*USDCTokenPoolLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolLockedIterator{contract: _USDCTokenPool.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolLocked) + if err := _USDCTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseLocked(log types.Log) (*USDCTokenPoolLocked, error) { + event := new(USDCTokenPoolLocked) + if err := _USDCTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolMintedIterator struct { + Event *USDCTokenPoolMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolMintedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*USDCTokenPoolMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolMintedIterator{contract: _USDCTokenPool.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolMinted) + if err := _USDCTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseMinted(log types.Log) (*USDCTokenPoolMinted, error) { + event := new(USDCTokenPoolMinted) + if err := _USDCTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolOwnershipTransferRequestedIterator struct { + Event *USDCTokenPoolOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*USDCTokenPoolOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolOwnershipTransferRequestedIterator{contract: _USDCTokenPool.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolOwnershipTransferRequested) + if err := _USDCTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseOwnershipTransferRequested(log types.Log) (*USDCTokenPoolOwnershipTransferRequested, error) { + event := new(USDCTokenPoolOwnershipTransferRequested) + if err := _USDCTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolOwnershipTransferredIterator struct { + Event *USDCTokenPoolOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*USDCTokenPoolOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolOwnershipTransferredIterator{contract: _USDCTokenPool.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolOwnershipTransferred) + if err := _USDCTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseOwnershipTransferred(log types.Log) (*USDCTokenPoolOwnershipTransferred, error) { + event := new(USDCTokenPoolOwnershipTransferred) + if err := _USDCTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolReleasedIterator struct { + Event *USDCTokenPoolReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolReleasedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*USDCTokenPoolReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolReleasedIterator{contract: _USDCTokenPool.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolReleased) + if err := _USDCTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseReleased(log types.Log) (*USDCTokenPoolReleased, error) { + event := new(USDCTokenPoolReleased) + if err := _USDCTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolRemotePoolSetIterator struct { + Event *USDCTokenPoolRemotePoolSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolRemotePoolSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolRemotePoolSetIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolRemotePoolSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolRemotePoolSet struct { + RemoteChainSelector uint64 + PreviousPoolAddress []byte + RemotePoolAddress []byte + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*USDCTokenPoolRemotePoolSetIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolRemotePoolSetIterator{contract: _USDCTokenPool.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolRemotePoolSet) + if err := _USDCTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseRemotePoolSet(log types.Log) (*USDCTokenPoolRemotePoolSet, error) { + event := new(USDCTokenPoolRemotePoolSet) + if err := _USDCTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolRouterUpdatedIterator struct { + Event *USDCTokenPoolRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*USDCTokenPoolRouterUpdatedIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &USDCTokenPoolRouterUpdatedIterator{contract: _USDCTokenPool.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolRouterUpdated) + if err := _USDCTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseRouterUpdated(log types.Log) (*USDCTokenPoolRouterUpdated, error) { + event := new(USDCTokenPoolRouterUpdated) + if err := _USDCTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolTokensConsumedIterator struct { + Event *USDCTokenPoolTokensConsumed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolTokensConsumedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolTokensConsumedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolTokensConsumedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolTokensConsumed struct { + Tokens *big.Int + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterTokensConsumed(opts *bind.FilterOpts) (*USDCTokenPoolTokensConsumedIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return &USDCTokenPoolTokensConsumedIterator{contract: _USDCTokenPool.contract, event: "TokensConsumed", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolTokensConsumed) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolTokensConsumed) + if err := _USDCTokenPool.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseTokensConsumed(log types.Log) (*USDCTokenPoolTokensConsumed, error) { + event := new(USDCTokenPoolTokensConsumed) + if err := _USDCTokenPool.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_USDCTokenPool *USDCTokenPool) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _USDCTokenPool.abi.Events["AllowListAdd"].ID: + return _USDCTokenPool.ParseAllowListAdd(log) + case _USDCTokenPool.abi.Events["AllowListRemove"].ID: + return _USDCTokenPool.ParseAllowListRemove(log) + case _USDCTokenPool.abi.Events["Burned"].ID: + return _USDCTokenPool.ParseBurned(log) + case _USDCTokenPool.abi.Events["ChainAdded"].ID: + return _USDCTokenPool.ParseChainAdded(log) + case _USDCTokenPool.abi.Events["ChainConfigured"].ID: + return _USDCTokenPool.ParseChainConfigured(log) + case _USDCTokenPool.abi.Events["ChainRemoved"].ID: + return _USDCTokenPool.ParseChainRemoved(log) + case _USDCTokenPool.abi.Events["ConfigChanged"].ID: + return _USDCTokenPool.ParseConfigChanged(log) + case _USDCTokenPool.abi.Events["ConfigSet"].ID: + return _USDCTokenPool.ParseConfigSet(log) + case _USDCTokenPool.abi.Events["DomainsSet"].ID: + return _USDCTokenPool.ParseDomainsSet(log) + case _USDCTokenPool.abi.Events["Locked"].ID: + return _USDCTokenPool.ParseLocked(log) + case _USDCTokenPool.abi.Events["Minted"].ID: + return _USDCTokenPool.ParseMinted(log) + case _USDCTokenPool.abi.Events["OwnershipTransferRequested"].ID: + return _USDCTokenPool.ParseOwnershipTransferRequested(log) + case _USDCTokenPool.abi.Events["OwnershipTransferred"].ID: + return _USDCTokenPool.ParseOwnershipTransferred(log) + case _USDCTokenPool.abi.Events["Released"].ID: + return _USDCTokenPool.ParseReleased(log) + case _USDCTokenPool.abi.Events["RemotePoolSet"].ID: + return _USDCTokenPool.ParseRemotePoolSet(log) + case _USDCTokenPool.abi.Events["RouterUpdated"].ID: + return _USDCTokenPool.ParseRouterUpdated(log) + case _USDCTokenPool.abi.Events["TokensConsumed"].ID: + return _USDCTokenPool.ParseTokensConsumed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (USDCTokenPoolAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (USDCTokenPoolAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (USDCTokenPoolBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (USDCTokenPoolChainAdded) Topic() common.Hash { + return common.HexToHash("0x8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2") +} + +func (USDCTokenPoolChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (USDCTokenPoolChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (USDCTokenPoolConfigChanged) Topic() common.Hash { + return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") +} + +func (USDCTokenPoolConfigSet) Topic() common.Hash { + return common.HexToHash("0x2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea9544") +} + +func (USDCTokenPoolDomainsSet) Topic() common.Hash { + return common.HexToHash("0x1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee56") +} + +func (USDCTokenPoolLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (USDCTokenPoolMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (USDCTokenPoolOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (USDCTokenPoolOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (USDCTokenPoolReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (USDCTokenPoolRemotePoolSet) Topic() common.Hash { + return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +} + +func (USDCTokenPoolRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (USDCTokenPoolTokensConsumed) Topic() common.Hash { + return common.HexToHash("0x1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a") +} + +func (_USDCTokenPool *USDCTokenPool) Address() common.Address { + return _USDCTokenPool.address +} + +type USDCTokenPoolInterface interface { + SUPPORTEDUSDCVERSION(opts *bind.CallOpts) (uint32, error) + + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetDomain(opts *bind.CallOpts, chainSelector uint64) (USDCTokenPoolDomain, error) + + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRmnProxy(opts *bind.CallOpts) (common.Address, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + ILocalDomainIdentifier(opts *bind.CallOpts) (uint32, error) + + IMessageTransmitter(opts *bind.CallOpts) (common.Address, error) + + ITokenMessenger(opts *bind.CallOpts) (common.Address, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetDomains(opts *bind.TransactOpts, domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) + + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*USDCTokenPoolAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*USDCTokenPoolAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*USDCTokenPoolAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*USDCTokenPoolAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*USDCTokenPoolBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*USDCTokenPoolBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*USDCTokenPoolChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*USDCTokenPoolChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*USDCTokenPoolChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*USDCTokenPoolChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*USDCTokenPoolChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*USDCTokenPoolChainRemoved, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*USDCTokenPoolConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*USDCTokenPoolConfigChanged, error) + + FilterConfigSet(opts *bind.FilterOpts) (*USDCTokenPoolConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*USDCTokenPoolConfigSet, error) + + FilterDomainsSet(opts *bind.FilterOpts) (*USDCTokenPoolDomainsSetIterator, error) + + WatchDomainsSet(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolDomainsSet) (event.Subscription, error) + + ParseDomainsSet(log types.Log) (*USDCTokenPoolDomainsSet, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*USDCTokenPoolLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*USDCTokenPoolLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*USDCTokenPoolMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*USDCTokenPoolMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*USDCTokenPoolOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*USDCTokenPoolOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*USDCTokenPoolOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*USDCTokenPoolOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*USDCTokenPoolReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*USDCTokenPoolReleased, error) + + FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*USDCTokenPoolRemotePoolSetIterator, error) + + WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolSet(log types.Log) (*USDCTokenPoolRemotePoolSet, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*USDCTokenPoolRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*USDCTokenPoolRouterUpdated, error) + + FilterTokensConsumed(opts *bind.FilterOpts) (*USDCTokenPoolTokensConsumedIterator, error) + + WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolTokensConsumed) (event.Subscription, error) + + ParseTokensConsumed(log types.Log) (*USDCTokenPoolTokensConsumed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/usdc_token_pool_1_4_0/usdc_token_pool_1_4_0.go b/core/gethwrappers/ccip/generated/usdc_token_pool_1_4_0/usdc_token_pool_1_4_0.go new file mode 100644 index 0000000000..67250b86e6 --- /dev/null +++ b/core/gethwrappers/ccip/generated/usdc_token_pool_1_4_0/usdc_token_pool_1_4_0.go @@ -0,0 +1,2693 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package usdc_token_pool_1_4_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +type USDCTokenPoolDomain struct { + AllowedCaller [32]byte + DomainIdentifier uint32 + Enabled bool +} + +type USDCTokenPoolDomainUpdate struct { + AllowedCaller [32]byte + DomainIdentifier uint32 + DestChainSelector uint64 + Enabled bool +} + +var USDCTokenPoolMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRatelimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getUSDCInterfaceId\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"destinationReceiver\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"releaseOrMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101406040523480156200001257600080fd5b506040516200458a3803806200458a833981016040819052620000359162000b4d565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c38162000408565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b1562000103576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200015657604080516000815260208101909152620001569084620004b3565b5050506001600160a01b038616905062000183576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001c4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ea919062000c73565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200022d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000253919062000c9a565b905063ffffffff81161562000284576040516334697c6b60e11b815263ffffffff8216600482015260240162000087565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002c5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002eb919062000c9a565b905063ffffffff8116156200031c576040516316ba39c560e31b815263ffffffff8216600482015260240162000087565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa1580156200036e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000394919062000c9a565b63ffffffff166101205260e051608051620003be916001600160a01b039091169060001962000624565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000e03565b336001600160a01b03821603620004625760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620004d4576040516335f4a7b360e01b815260040160405180910390fd5b60005b825181101562000569576000838281518110620004f857620004f862000cc2565b60209081029190910101519050620005126002826200070a565b1562000555576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50620005618162000cee565b9050620004d7565b5060005b81518110156200061f5760008282815181106200058e576200058e62000cc2565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005ba57506200060c565b620005c76002826200072a565b156200060a576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b620006178162000cee565b90506200056d565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000676573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200069c919062000d0a565b620006a8919062000d24565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000704918691906200074116565b50505050565b600062000721836001600160a01b03841662000812565b90505b92915050565b600062000721836001600160a01b03841662000916565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000790906001600160a01b03851690849062000968565b8051909150156200061f5780806020019051810190620007b1919062000d3a565b6200061f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000087565b600081815260018301602052604081205480156200090b5760006200083960018362000d5e565b85549091506000906200084f9060019062000d5e565b9050818114620008bb57600086600001828154811062000873576200087362000cc2565b906000526020600020015490508087600001848154811062000899576200089962000cc2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620008cf57620008cf62000d74565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000724565b600091505062000724565b60008181526001830160205260408120546200095f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000724565b50600062000724565b606062000979848460008562000981565b949350505050565b606082471015620009e45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000087565b600080866001600160a01b0316858760405162000a02919062000db0565b60006040518083038185875af1925050503d806000811462000a41576040519150601f19603f3d011682016040523d82523d6000602084013e62000a46565b606091505b50909250905062000a5a8783838762000a65565b979650505050505050565b6060831562000ad957825160000362000ad1576001600160a01b0385163b62000ad15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000087565b508162000979565b62000979838381511562000af05781518083602001fd5b8060405162461bcd60e51b815260040162000087919062000dce565b6001600160a01b038116811462000b2257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b488162000b0c565b919050565b600080600080600060a0868803121562000b6657600080fd5b855162000b738162000b0c565b8095505060208087015162000b888162000b0c565b60408801519095506001600160401b038082111562000ba657600080fd5b818901915089601f83011262000bbb57600080fd5b81518181111562000bd05762000bd062000b25565b8060051b604051601f19603f8301168101818110858211171562000bf85762000bf862000b25565b60405291825284820192508381018501918c83111562000c1757600080fd5b938501935b8285101562000c405762000c308562000b3b565b8452938501939285019262000c1c565b80985050505050505062000c576060870162000b3b565b915062000c676080870162000b3b565b90509295509295909350565b60006020828403121562000c8657600080fd5b815162000c938162000b0c565b9392505050565b60006020828403121562000cad57600080fd5b815163ffffffff8116811462000c9357600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820162000d035762000d0362000cd8565b5060010190565b60006020828403121562000d1d57600080fd5b5051919050565b8082018082111562000724576200072462000cd8565b60006020828403121562000d4d57600080fd5b8151801515811462000c9357600080fd5b8181038181111562000724576200072462000cd8565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000da757818101518382015260200162000d8d565b50506000910152565b6000825162000dc481846020870162000d8a565b9190910192915050565b602081526000825180602084015262000def81604085016020870162000d8a565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516136f162000e99600039600081816103020152818161159f01528181611ea10152611eff01526000818161059a015261109d0152600081816102db01526114da01526000818161055e0152818161130d0152611a850152600061028c015260008181610245015281816114a401528181611dc5015261200101526136f16000f3fe608060405234801561001057600080fd5b50600436106101b85760003560e01c80638da5cb5b116100f9578063c4bffe2b11610097578063dfadfa3511610071578063dfadfa35146104be578063e0351e131461055c578063f2fde38b14610582578063fbf84dd71461059557600080fd5b8063c4bffe2b14610483578063c75eea9c14610498578063cf7401f3146104ab57600080fd5b8063a7cd63b7116100d3578063a7cd63b7146103ce578063af58d59f146103e3578063b0f479a114610452578063c0d786551461047057600080fd5b80638da5cb5b1461039557806396875445146103b35780639fdf13ff146103c657600080fd5b80635995f063116101665780636d108139116101405780636d1081391461033957806379ba5097146103675780638627fad61461036f5780638926f54f1461038257600080fd5b80635995f063146102c35780636155cda0146102d65780636b716b0d146102fd57600080fd5b806321df0da71161019757806321df0da7146102435780635246492f1461028a57806354c8a4f3146102b057600080fd5b806241d3c1146101bd57806301ffc9a7146101d2578063181f5a77146101fa575b600080fd5b6101d06101cb366004612a03565b6105bc565b005b6101e56101e0366004612a78565b610763565b60405190151581526020015b60405180910390f35b6102366040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e342e300000000000000000000000000081525081565b6040516101f19190612b28565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f1565b7f0000000000000000000000000000000000000000000000000000000000000000610265565b6101d06102be366004612b87565b6107bf565b6101d06102d1366004612bf3565b61083a565b6102657f000000000000000000000000000000000000000000000000000000000000000081565b6103247f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101f1565b6040517fd6aca1be0000000000000000000000000000000000000000000000000000000081526020016101f1565b6101d0610dd2565b6101d061037d366004612df4565b610ecf565b6101e5610390366004612e8b565b6111a2565b60005473ffffffffffffffffffffffffffffffffffffffff16610265565b6102366103c1366004612eea565b6111b9565b610324600081565b6103d66115f8565b6040516101f19190612f8b565b6103f66103f1366004612e8b565b611609565b6040516101f1919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610265565b6101d061047e366004612fe5565b6116db565b61048b6117af565b6040516101f19190613002565b6103f66104a6366004612e8b565b61186f565b6101d06104b93660046130e8565b611941565b6105326104cc366004612e8b565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600982529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff1690820152918101511515908201526060016101f1565b7f00000000000000000000000000000000000000000000000000000000000000006101e5565b6101d0610590366004612fe5565b611954565b6102657f000000000000000000000000000000000000000000000000000000000000000081565b6105c4611968565b60005b818110156107255760008383838181106105e3576105e361312f565b9050608002018036038101906105f99190613170565b805190915015806106165750604081015167ffffffffffffffff16155b1561068557604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600990925293902091518255516001909101805493511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909416919092161791909117905561071e816131fd565b90506105c7565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee568282604051610757929190613235565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fd6aca1be0000000000000000000000000000000000000000000000000000000014806107b957506107b9826119eb565b92915050565b6107c7611968565b61083484848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611a8392505050565b50505050565b610842611968565b60005b81811015610dcd5760008383838181106108615761086161312f565b9050610100020180360381019061087891906132be565b905061088d8160400151826020015115611c49565b6108a08160600151826020015115611c49565b806020015115610cc15780516108c29060059067ffffffffffffffff16611d86565b6109075780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161067c565b6040518060a001604052808260400151602001516fffffffffffffffffffffffffffffffff1681526020014263ffffffff168152602001826040015160000151151581526020018260400151602001516fffffffffffffffffffffffffffffffff1681526020018260400151604001516fffffffffffffffffffffffffffffffff1681525060076000836000015167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160146101000a81548160ff02191690831515021790555060608201518160010160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060808201518160010160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055509050506040518060a001604052808260600151602001516fffffffffffffffffffffffffffffffff1681526020014263ffffffff168152602001826060015160000151151581526020018260600151602001516fffffffffffffffffffffffffffffffff1681526020018260600151604001516fffffffffffffffffffffffffffffffff1681525060086000836000015167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160146101000a81548160ff02191690831515021790555060608201518160010160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060808201518160010160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055509050507f0f135cbb9afa12a8bf3bbd071c117bcca4ddeca6160ef7f33d012a81b9c0c471816000015182604001518360600151604051610cb493929190613318565b60405180910390a1610dbc565b8051610cd99060059067ffffffffffffffff16611d99565b610d1e5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161067c565b805167ffffffffffffffff908116600090815260086020908152604080832080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600191820185905586518616855260078452828520805490911681550192909255835191519190921681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916910160405180910390a15b50610dc6816131fd565b9050610845565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161067c565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b81610ed9816111a2565b610f1b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161067c565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015610f9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fbe919061339b565b610ff6576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161067c565b6110008385611da5565b6000808380602001905181019061101791906133fd565b915091506000828060200190518101906110319190613461565b905060008280602001905181019061104991906134a2565b9050611059816000015183611de9565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd28926110d092600401613533565b6020604051808303816000875af11580156110ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611113919061339b565b611149576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405188815273ffffffffffffffffffffffffffffffffffffffff8a169033907f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f09060200160405180910390a350505050505050505050565b60006107b9600567ffffffffffffffff8416611f9a565b6060836111c5816111a2565b611207576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161067c565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015611280573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a49190613561565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461130a576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161067c565b887f00000000000000000000000000000000000000000000000000000000000000008015611340575061133e600282611fb2565b155b1561138f576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161067c565b67ffffffffffffffff861660009081526009602090815260409182902082516060810184528154815260019091015463ffffffff81169282019290925264010000000090910460ff16151591810182905290611423576040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015260240161067c565b61142d8789611fe1565b600061143c6020828c8e61357e565b611445916135a8565b602083015183516040517ff856ddb6000000000000000000000000000000000000000000000000000000008152600481018d905263ffffffff90921660248301526044820183905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063f856ddb69060a4016020604051808303816000875af1158015611523573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154791906135e4565b6040518b815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260408051808201825267ffffffffffffffff9290921680835263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602094850190815283519485019290925290511682820152805180830382018152606090920190529c9b505050505050505050505050565b60606116046002612025565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260086020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526107b990612032565b6116e3611968565b73ffffffffffffffffffffffffffffffffffffffff8116611730576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610757565b606060006117bd6005612025565b90506000815167ffffffffffffffff8111156117db576117db612c56565b604051908082528060200260200182016040528015611804578160200160208202803683370190505b50905060005b8251811015611868578281815181106118255761182561312f565b602002602001015182828151811061183f5761183f61312f565b67ffffffffffffffff90921660209283029190910190910152611861816131fd565b905061180a565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526107b990612032565b611949611968565b610dcd8383836120e4565b61195c611968565b611965816121cb565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146119e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161067c565b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f317fa3340000000000000000000000000000000000000000000000000000000014806107b957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b7f0000000000000000000000000000000000000000000000000000000000000000611ada576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611b78576000838281518110611afa57611afa61312f565b60200260200101519050611b188160026122c090919063ffffffff16565b15611b675760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50611b71816131fd565b9050611add565b5060005b8151811015610dcd576000828281518110611b9957611b9961312f565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bdd5750611c39565b611be86002826122e2565b15611c375760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b611c42816131fd565b9050611b7c565b815115611d145781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611c9f575060408201516fffffffffffffffffffffffffffffffff16155b15611cd857816040517f70505e5600000000000000000000000000000000000000000000000000000000815260040161067c9190613601565b8015611d10576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580611d4d575060208201516fffffffffffffffffffffffffffffffff1615155b15611d1057816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161067c9190613601565b6000611d928383612300565b9392505050565b6000611d92838361234f565b67ffffffffffffffff82166000908152600860205260409020611d1090827f0000000000000000000000000000000000000000000000000000000000000000612442565b600482015163ffffffff811615611e34576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff8216600482015260240161067c565b6008830151600c8401516014850151602085015163ffffffff808516911614611e9f5760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff9182166004820152908416602482015260440161067c565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611f34576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161067c565b845167ffffffffffffffff828116911614611f925784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9182166004820152908216602482015260440161067c565b505050505050565b60008181526001830160205260408120541515611d92565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611d92565b67ffffffffffffffff82166000908152600760205260409020611d1090827f0000000000000000000000000000000000000000000000000000000000000000612442565b60606000611d92836127c5565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526120c082606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426120a4919061363d565b85608001516fffffffffffffffffffffffffffffffff16612821565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6120ed836111a2565b61212f576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161067c565b61213a826000611c49565b67ffffffffffffffff8316600090815260076020526040902061215d908361284b565b612168816000611c49565b67ffffffffffffffff8316600090815260086020526040902061218b908261284b565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516121be93929190613318565b60405180910390a1505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361224a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161067c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611d928373ffffffffffffffffffffffffffffffffffffffff841661234f565b6000611d928373ffffffffffffffffffffffffffffffffffffffff84165b6000818152600183016020526040812054612347575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556107b9565b5060006107b9565b6000818152600183016020526040812054801561243857600061237360018361363d565b85549091506000906123879060019061363d565b90508181146123ec5760008660000182815481106123a7576123a761312f565b90600052602060002001549050808760000184815481106123ca576123ca61312f565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806123fd576123fd613650565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506107b9565b60009150506107b9565b825474010000000000000000000000000000000000000000900460ff161580612469575081155b1561247357505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906124b990700100000000000000000000000000000000900463ffffffff164261363d565b9050801561257957818311156124fb576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546125359083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612821565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156126305773ffffffffffffffffffffffffffffffffffffffff84166125d8576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161067c565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161067c565b848310156127435760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612674908261363d565b61267e878a61363d565b612688919061367f565b6126929190613692565b905073ffffffffffffffffffffffffffffffffffffffff86166126eb576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161067c565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161067c565b61274d858461363d565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561281557602002820191906000526020600020905b815481526020019060010190808311612801575b50505050509050919050565b60006128408561283184866136cd565b61283b908761367f565b6129ed565b90505b949350505050565b815460009061287490700100000000000000000000000000000000900463ffffffff164261363d565b9050801561291657600183015483546128bc916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612821565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461293c916fffffffffffffffffffffffffffffffff90811691166129ed565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906121be908490613601565b60008183106129fc5781611d92565b5090919050565b60008060208385031215612a1657600080fd5b823567ffffffffffffffff80821115612a2e57600080fd5b818501915085601f830112612a4257600080fd5b813581811115612a5157600080fd5b8660208260071b8501011115612a6657600080fd5b60209290920196919550909350505050565b600060208284031215612a8a57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611d9257600080fd5b60005b83811015612ad5578181015183820152602001612abd565b50506000910152565b60008151808452612af6816020860160208601612aba565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d926020830184612ade565b60008083601f840112612b4d57600080fd5b50813567ffffffffffffffff811115612b6557600080fd5b6020830191508360208260051b8501011115612b8057600080fd5b9250929050565b60008060008060408587031215612b9d57600080fd5b843567ffffffffffffffff80821115612bb557600080fd5b612bc188838901612b3b565b90965094506020870135915080821115612bda57600080fd5b50612be787828801612b3b565b95989497509550505050565b60008060208385031215612c0657600080fd5b823567ffffffffffffffff80821115612c1e57600080fd5b818501915085601f830112612c3257600080fd5b813581811115612c4157600080fd5b8660208260081b8501011115612a6657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715612ca857612ca8612c56565b60405290565b6040805190810167ffffffffffffffff81118282101715612ca857612ca8612c56565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612d1857612d18612c56565b604052919050565b600067ffffffffffffffff821115612d3a57612d3a612c56565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112612d7757600080fd5b8135612d8a612d8582612d20565b612cd1565b818152846020838601011115612d9f57600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461196557600080fd5b67ffffffffffffffff8116811461196557600080fd5b600080600080600060a08688031215612e0c57600080fd5b853567ffffffffffffffff80821115612e2457600080fd5b612e3089838a01612d66565b965060208801359150612e4282612dbc565b90945060408701359350606087013590612e5b82612dde565b90925060808701359080821115612e7157600080fd5b50612e7e88828901612d66565b9150509295509295909350565b600060208284031215612e9d57600080fd5b8135611d9281612dde565b60008083601f840112612eba57600080fd5b50813567ffffffffffffffff811115612ed257600080fd5b602083019150836020828501011115612b8057600080fd5b600080600080600080600060a0888a031215612f0557600080fd5b8735612f1081612dbc565b9650602088013567ffffffffffffffff80821115612f2d57600080fd5b612f398b838c01612ea8565b909850965060408a0135955060608a01359150612f5582612dde565b90935060808901359080821115612f6b57600080fd5b50612f788a828b01612ea8565b989b979a50959850939692959293505050565b6020808252825182820181905260009190848201906040850190845b81811015612fd957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612fa7565b50909695505050505050565b600060208284031215612ff757600080fd5b8135611d9281612dbc565b6020808252825182820181905260009190848201906040850190845b81811015612fd957835167ffffffffffffffff168352928401929184019160010161301e565b801515811461196557600080fd5b80356fffffffffffffffffffffffffffffffff8116811461307257600080fd5b919050565b60006060828403121561308957600080fd5b6040516060810181811067ffffffffffffffff821117156130ac576130ac612c56565b60405290508082356130bd81613044565b81526130cb60208401613052565b60208201526130dc60408401613052565b60408201525092915050565b600080600060e084860312156130fd57600080fd5b833561310881612dde565b92506131178560208601613077565b91506131268560808601613077565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b63ffffffff8116811461196557600080fd5b60006080828403121561318257600080fd5b61318a612c85565b82358152602083013561319c8161315e565b602082015260408301356131af81612dde565b604082015260608301356131c281613044565b60608201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361322e5761322e6131ce565b5060010190565b6020808252818101839052600090604080840186845b878110156132b15781358352848201356132648161315e565b63ffffffff16838601528184013561327b81612dde565b67ffffffffffffffff168385015260608281013561329881613044565b151590840152608092830192919091019060010161324b565b5090979650505050505050565b600061010082840312156132d157600080fd5b6132d9612c85565b82356132e481612dde565b815260208301356132f481613044565b60208201526133068460408501613077565b60408201526131c28460a08501613077565b67ffffffffffffffff8416815260e0810161336460208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612843565b6000602082840312156133ad57600080fd5b8151611d9281613044565b600082601f8301126133c957600080fd5b81516133d7612d8582612d20565b8181528460208386010111156133ec57600080fd5b612843826020830160208701612aba565b6000806040838503121561341057600080fd5b825167ffffffffffffffff8082111561342857600080fd5b613434868387016133b8565b9350602085015191508082111561344a57600080fd5b50613457858286016133b8565b9150509250929050565b60006040828403121561347357600080fd5b61347b612cae565b825161348681612dde565b815260208301516134968161315e565b60208201529392505050565b6000602082840312156134b457600080fd5b815167ffffffffffffffff808211156134cc57600080fd5b90830190604082860312156134e057600080fd5b6134e8612cae565b8251828111156134f757600080fd5b613503878286016133b8565b82525060208301518281111561351857600080fd5b613524878286016133b8565b60208301525095945050505050565b6040815260006135466040830185612ade565b82810360208401526135588185612ade565b95945050505050565b60006020828403121561357357600080fd5b8151611d9281612dbc565b6000808585111561358e57600080fd5b8386111561359b57600080fd5b5050820193919092039150565b803560208310156107b9577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b6000602082840312156135f657600080fd5b8151611d9281612dde565b606081016107b982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b818103818111156107b9576107b96131ce565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b808201808211156107b9576107b96131ce565b6000826136c8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176107b9576107b96131ce56fea164736f6c6343000813000a", +} + +var USDCTokenPoolABI = USDCTokenPoolMetaData.ABI + +var USDCTokenPoolBin = USDCTokenPoolMetaData.Bin + +func DeployUSDCTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, tokenMessenger common.Address, token common.Address, allowlist []common.Address, armProxy common.Address, router common.Address) (common.Address, *types.Transaction, *USDCTokenPool, error) { + parsed, err := USDCTokenPoolMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(USDCTokenPoolBin), backend, tokenMessenger, token, allowlist, armProxy, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &USDCTokenPool{address: address, abi: *parsed, USDCTokenPoolCaller: USDCTokenPoolCaller{contract: contract}, USDCTokenPoolTransactor: USDCTokenPoolTransactor{contract: contract}, USDCTokenPoolFilterer: USDCTokenPoolFilterer{contract: contract}}, nil +} + +type USDCTokenPool struct { + address common.Address + abi abi.ABI + USDCTokenPoolCaller + USDCTokenPoolTransactor + USDCTokenPoolFilterer +} + +type USDCTokenPoolCaller struct { + contract *bind.BoundContract +} + +type USDCTokenPoolTransactor struct { + contract *bind.BoundContract +} + +type USDCTokenPoolFilterer struct { + contract *bind.BoundContract +} + +type USDCTokenPoolSession struct { + Contract *USDCTokenPool + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type USDCTokenPoolCallerSession struct { + Contract *USDCTokenPoolCaller + CallOpts bind.CallOpts +} + +type USDCTokenPoolTransactorSession struct { + Contract *USDCTokenPoolTransactor + TransactOpts bind.TransactOpts +} + +type USDCTokenPoolRaw struct { + Contract *USDCTokenPool +} + +type USDCTokenPoolCallerRaw struct { + Contract *USDCTokenPoolCaller +} + +type USDCTokenPoolTransactorRaw struct { + Contract *USDCTokenPoolTransactor +} + +func NewUSDCTokenPool(address common.Address, backend bind.ContractBackend) (*USDCTokenPool, error) { + abi, err := abi.JSON(strings.NewReader(USDCTokenPoolABI)) + if err != nil { + return nil, err + } + contract, err := bindUSDCTokenPool(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &USDCTokenPool{address: address, abi: abi, USDCTokenPoolCaller: USDCTokenPoolCaller{contract: contract}, USDCTokenPoolTransactor: USDCTokenPoolTransactor{contract: contract}, USDCTokenPoolFilterer: USDCTokenPoolFilterer{contract: contract}}, nil +} + +func NewUSDCTokenPoolCaller(address common.Address, caller bind.ContractCaller) (*USDCTokenPoolCaller, error) { + contract, err := bindUSDCTokenPool(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &USDCTokenPoolCaller{contract: contract}, nil +} + +func NewUSDCTokenPoolTransactor(address common.Address, transactor bind.ContractTransactor) (*USDCTokenPoolTransactor, error) { + contract, err := bindUSDCTokenPool(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &USDCTokenPoolTransactor{contract: contract}, nil +} + +func NewUSDCTokenPoolFilterer(address common.Address, filterer bind.ContractFilterer) (*USDCTokenPoolFilterer, error) { + contract, err := bindUSDCTokenPool(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &USDCTokenPoolFilterer{contract: contract}, nil +} + +func bindUSDCTokenPool(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := USDCTokenPoolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_USDCTokenPool *USDCTokenPoolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _USDCTokenPool.Contract.USDCTokenPoolCaller.contract.Call(opts, result, method, params...) +} + +func (_USDCTokenPool *USDCTokenPoolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _USDCTokenPool.Contract.USDCTokenPoolTransactor.contract.Transfer(opts) +} + +func (_USDCTokenPool *USDCTokenPoolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _USDCTokenPool.Contract.USDCTokenPoolTransactor.contract.Transact(opts, method, params...) +} + +func (_USDCTokenPool *USDCTokenPoolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _USDCTokenPool.Contract.contract.Call(opts, result, method, params...) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _USDCTokenPool.Contract.contract.Transfer(opts) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _USDCTokenPool.Contract.contract.Transact(opts, method, params...) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) SUPPORTEDUSDCVERSION(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "SUPPORTED_USDC_VERSION") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) SUPPORTEDUSDCVERSION() (uint32, error) { + return _USDCTokenPool.Contract.SUPPORTEDUSDCVERSION(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) SUPPORTEDUSDCVERSION() (uint32, error) { + return _USDCTokenPool.Contract.SUPPORTEDUSDCVERSION(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetAllowList() ([]common.Address, error) { + return _USDCTokenPool.Contract.GetAllowList(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetAllowList() ([]common.Address, error) { + return _USDCTokenPool.Contract.GetAllowList(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetAllowListEnabled() (bool, error) { + return _USDCTokenPool.Contract.GetAllowListEnabled(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetAllowListEnabled() (bool, error) { + return _USDCTokenPool.Contract.GetAllowListEnabled(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetArmProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getArmProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetArmProxy() (common.Address, error) { + return _USDCTokenPool.Contract.GetArmProxy(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetArmProxy() (common.Address, error) { + return _USDCTokenPool.Contract.GetArmProxy(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _USDCTokenPool.Contract.GetCurrentInboundRateLimiterState(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _USDCTokenPool.Contract.GetCurrentInboundRateLimiterState(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _USDCTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _USDCTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetDomain(opts *bind.CallOpts, chainSelector uint64) (USDCTokenPoolDomain, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getDomain", chainSelector) + + if err != nil { + return *new(USDCTokenPoolDomain), err + } + + out0 := *abi.ConvertType(out[0], new(USDCTokenPoolDomain)).(*USDCTokenPoolDomain) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetDomain(chainSelector uint64) (USDCTokenPoolDomain, error) { + return _USDCTokenPool.Contract.GetDomain(&_USDCTokenPool.CallOpts, chainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetDomain(chainSelector uint64) (USDCTokenPoolDomain, error) { + return _USDCTokenPool.Contract.GetDomain(&_USDCTokenPool.CallOpts, chainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetRouter() (common.Address, error) { + return _USDCTokenPool.Contract.GetRouter(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetRouter() (common.Address, error) { + return _USDCTokenPool.Contract.GetRouter(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetSupportedChains() ([]uint64, error) { + return _USDCTokenPool.Contract.GetSupportedChains(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetSupportedChains() ([]uint64, error) { + return _USDCTokenPool.Contract.GetSupportedChains(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetToken() (common.Address, error) { + return _USDCTokenPool.Contract.GetToken(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetToken() (common.Address, error) { + return _USDCTokenPool.Contract.GetToken(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) GetUSDCInterfaceId(opts *bind.CallOpts) ([4]byte, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getUSDCInterfaceId") + + if err != nil { + return *new([4]byte), err + } + + out0 := *abi.ConvertType(out[0], new([4]byte)).(*[4]byte) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetUSDCInterfaceId() ([4]byte, error) { + return _USDCTokenPool.Contract.GetUSDCInterfaceId(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetUSDCInterfaceId() ([4]byte, error) { + return _USDCTokenPool.Contract.GetUSDCInterfaceId(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) ILocalDomainIdentifier(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "i_localDomainIdentifier") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) ILocalDomainIdentifier() (uint32, error) { + return _USDCTokenPool.Contract.ILocalDomainIdentifier(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) ILocalDomainIdentifier() (uint32, error) { + return _USDCTokenPool.Contract.ILocalDomainIdentifier(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) IMessageTransmitter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "i_messageTransmitter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) IMessageTransmitter() (common.Address, error) { + return _USDCTokenPool.Contract.IMessageTransmitter(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) IMessageTransmitter() (common.Address, error) { + return _USDCTokenPool.Contract.IMessageTransmitter(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) ITokenMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "i_tokenMessenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) ITokenMessenger() (common.Address, error) { + return _USDCTokenPool.Contract.ITokenMessenger(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) ITokenMessenger() (common.Address, error) { + return _USDCTokenPool.Contract.ITokenMessenger(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _USDCTokenPool.Contract.IsSupportedChain(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _USDCTokenPool.Contract.IsSupportedChain(&_USDCTokenPool.CallOpts, remoteChainSelector) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) Owner() (common.Address, error) { + return _USDCTokenPool.Contract.Owner(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) Owner() (common.Address, error) { + return _USDCTokenPool.Contract.Owner(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _USDCTokenPool.Contract.SupportsInterface(&_USDCTokenPool.CallOpts, interfaceId) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _USDCTokenPool.Contract.SupportsInterface(&_USDCTokenPool.CallOpts, interfaceId) +} + +func (_USDCTokenPool *USDCTokenPoolCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) TypeAndVersion() (string, error) { + return _USDCTokenPool.Contract.TypeAndVersion(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) TypeAndVersion() (string, error) { + return _USDCTokenPool.Contract.TypeAndVersion(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "acceptOwnership") +} + +func (_USDCTokenPool *USDCTokenPoolSession) AcceptOwnership() (*types.Transaction, error) { + return _USDCTokenPool.Contract.AcceptOwnership(&_USDCTokenPool.TransactOpts) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _USDCTokenPool.Contract.AcceptOwnership(&_USDCTokenPool.TransactOpts) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_USDCTokenPool *USDCTokenPoolSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ApplyAllowListUpdates(&_USDCTokenPool.TransactOpts, removes, adds) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ApplyAllowListUpdates(&_USDCTokenPool.TransactOpts, removes, adds) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_USDCTokenPool *USDCTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ApplyChainUpdates(&_USDCTokenPool.TransactOpts, chains) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ApplyChainUpdates(&_USDCTokenPool.TransactOpts, chains) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, originalSender common.Address, destinationReceiver []byte, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "lockOrBurn", originalSender, destinationReceiver, amount, remoteChainSelector, arg4) +} + +func (_USDCTokenPool *USDCTokenPoolSession) LockOrBurn(originalSender common.Address, destinationReceiver []byte, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _USDCTokenPool.Contract.LockOrBurn(&_USDCTokenPool.TransactOpts, originalSender, destinationReceiver, amount, remoteChainSelector, arg4) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) LockOrBurn(originalSender common.Address, destinationReceiver []byte, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) { + return _USDCTokenPool.Contract.LockOrBurn(&_USDCTokenPool.TransactOpts, originalSender, destinationReceiver, amount, remoteChainSelector, arg4) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) ReleaseOrMint(opts *bind.TransactOpts, arg0 []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, extraData []byte) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "releaseOrMint", arg0, receiver, amount, remoteChainSelector, extraData) +} + +func (_USDCTokenPool *USDCTokenPoolSession) ReleaseOrMint(arg0 []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, extraData []byte) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ReleaseOrMint(&_USDCTokenPool.TransactOpts, arg0, receiver, amount, remoteChainSelector, extraData) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) ReleaseOrMint(arg0 []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, extraData []byte) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ReleaseOrMint(&_USDCTokenPool.TransactOpts, arg0, receiver, amount, remoteChainSelector, extraData) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_USDCTokenPool *USDCTokenPoolSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetChainRateLimiterConfig(&_USDCTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetChainRateLimiterConfig(&_USDCTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) SetDomains(opts *bind.TransactOpts, domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "setDomains", domains) +} + +func (_USDCTokenPool *USDCTokenPoolSession) SetDomains(domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetDomains(&_USDCTokenPool.TransactOpts, domains) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetDomains(domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetDomains(&_USDCTokenPool.TransactOpts, domains) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "setRouter", newRouter) +} + +func (_USDCTokenPool *USDCTokenPoolSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetRouter(&_USDCTokenPool.TransactOpts, newRouter) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetRouter(&_USDCTokenPool.TransactOpts, newRouter) +} + +func (_USDCTokenPool *USDCTokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "transferOwnership", to) +} + +func (_USDCTokenPool *USDCTokenPoolSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.TransferOwnership(&_USDCTokenPool.TransactOpts, to) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.TransferOwnership(&_USDCTokenPool.TransactOpts, to) +} + +type USDCTokenPoolAllowListAddIterator struct { + Event *USDCTokenPoolAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolAllowListAddIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*USDCTokenPoolAllowListAddIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &USDCTokenPoolAllowListAddIterator{contract: _USDCTokenPool.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolAllowListAdd) + if err := _USDCTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseAllowListAdd(log types.Log) (*USDCTokenPoolAllowListAdd, error) { + event := new(USDCTokenPoolAllowListAdd) + if err := _USDCTokenPool.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolAllowListRemoveIterator struct { + Event *USDCTokenPoolAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*USDCTokenPoolAllowListRemoveIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &USDCTokenPoolAllowListRemoveIterator{contract: _USDCTokenPool.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolAllowListRemove) + if err := _USDCTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseAllowListRemove(log types.Log) (*USDCTokenPoolAllowListRemove, error) { + event := new(USDCTokenPoolAllowListRemove) + if err := _USDCTokenPool.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolBurnedIterator struct { + Event *USDCTokenPoolBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolBurnedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*USDCTokenPoolBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolBurnedIterator{contract: _USDCTokenPool.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolBurned) + if err := _USDCTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseBurned(log types.Log) (*USDCTokenPoolBurned, error) { + event := new(USDCTokenPoolBurned) + if err := _USDCTokenPool.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolChainAddedIterator struct { + Event *USDCTokenPoolChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolChainAddedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolChainAdded struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterChainAdded(opts *bind.FilterOpts) (*USDCTokenPoolChainAddedIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &USDCTokenPoolChainAddedIterator{contract: _USDCTokenPool.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolChainAdded) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolChainAdded) + if err := _USDCTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseChainAdded(log types.Log) (*USDCTokenPoolChainAdded, error) { + event := new(USDCTokenPoolChainAdded) + if err := _USDCTokenPool.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolChainConfiguredIterator struct { + Event *USDCTokenPoolChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*USDCTokenPoolChainConfiguredIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &USDCTokenPoolChainConfiguredIterator{contract: _USDCTokenPool.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolChainConfigured) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolChainConfigured) + if err := _USDCTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseChainConfigured(log types.Log) (*USDCTokenPoolChainConfigured, error) { + event := new(USDCTokenPoolChainConfigured) + if err := _USDCTokenPool.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolChainRemovedIterator struct { + Event *USDCTokenPoolChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolChainRemovedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*USDCTokenPoolChainRemovedIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &USDCTokenPoolChainRemovedIterator{contract: _USDCTokenPool.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolChainRemoved) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolChainRemoved) + if err := _USDCTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseChainRemoved(log types.Log) (*USDCTokenPoolChainRemoved, error) { + event := new(USDCTokenPoolChainRemoved) + if err := _USDCTokenPool.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolConfigSetIterator struct { + Event *USDCTokenPoolConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolConfigSetIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolConfigSet struct { + TokenMessenger common.Address + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterConfigSet(opts *bind.FilterOpts) (*USDCTokenPoolConfigSetIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &USDCTokenPoolConfigSetIterator{contract: _USDCTokenPool.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolConfigSet) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolConfigSet) + if err := _USDCTokenPool.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseConfigSet(log types.Log) (*USDCTokenPoolConfigSet, error) { + event := new(USDCTokenPoolConfigSet) + if err := _USDCTokenPool.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolDomainsSetIterator struct { + Event *USDCTokenPoolDomainsSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolDomainsSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolDomainsSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolDomainsSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolDomainsSetIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolDomainsSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolDomainsSet struct { + Arg0 []USDCTokenPoolDomainUpdate + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterDomainsSet(opts *bind.FilterOpts) (*USDCTokenPoolDomainsSetIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "DomainsSet") + if err != nil { + return nil, err + } + return &USDCTokenPoolDomainsSetIterator{contract: _USDCTokenPool.contract, event: "DomainsSet", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchDomainsSet(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolDomainsSet) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "DomainsSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolDomainsSet) + if err := _USDCTokenPool.contract.UnpackLog(event, "DomainsSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseDomainsSet(log types.Log) (*USDCTokenPoolDomainsSet, error) { + event := new(USDCTokenPoolDomainsSet) + if err := _USDCTokenPool.contract.UnpackLog(event, "DomainsSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolLockedIterator struct { + Event *USDCTokenPoolLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolLockedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*USDCTokenPoolLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolLockedIterator{contract: _USDCTokenPool.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolLocked) + if err := _USDCTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseLocked(log types.Log) (*USDCTokenPoolLocked, error) { + event := new(USDCTokenPoolLocked) + if err := _USDCTokenPool.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolMintedIterator struct { + Event *USDCTokenPoolMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolMintedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*USDCTokenPoolMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolMintedIterator{contract: _USDCTokenPool.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolMinted) + if err := _USDCTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseMinted(log types.Log) (*USDCTokenPoolMinted, error) { + event := new(USDCTokenPoolMinted) + if err := _USDCTokenPool.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolOwnershipTransferRequestedIterator struct { + Event *USDCTokenPoolOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*USDCTokenPoolOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolOwnershipTransferRequestedIterator{contract: _USDCTokenPool.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolOwnershipTransferRequested) + if err := _USDCTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseOwnershipTransferRequested(log types.Log) (*USDCTokenPoolOwnershipTransferRequested, error) { + event := new(USDCTokenPoolOwnershipTransferRequested) + if err := _USDCTokenPool.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolOwnershipTransferredIterator struct { + Event *USDCTokenPoolOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*USDCTokenPoolOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolOwnershipTransferredIterator{contract: _USDCTokenPool.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolOwnershipTransferred) + if err := _USDCTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseOwnershipTransferred(log types.Log) (*USDCTokenPoolOwnershipTransferred, error) { + event := new(USDCTokenPoolOwnershipTransferred) + if err := _USDCTokenPool.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolReleasedIterator struct { + Event *USDCTokenPoolReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolReleasedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*USDCTokenPoolReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolReleasedIterator{contract: _USDCTokenPool.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolReleased) + if err := _USDCTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseReleased(log types.Log) (*USDCTokenPoolReleased, error) { + event := new(USDCTokenPoolReleased) + if err := _USDCTokenPool.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolRouterUpdatedIterator struct { + Event *USDCTokenPoolRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCTokenPoolRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*USDCTokenPoolRouterUpdatedIterator, error) { + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &USDCTokenPoolRouterUpdatedIterator{contract: _USDCTokenPool.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolRouterUpdated) + if err := _USDCTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseRouterUpdated(log types.Log) (*USDCTokenPoolRouterUpdated, error) { + event := new(USDCTokenPoolRouterUpdated) + if err := _USDCTokenPool.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_USDCTokenPool *USDCTokenPool) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _USDCTokenPool.abi.Events["AllowListAdd"].ID: + return _USDCTokenPool.ParseAllowListAdd(log) + case _USDCTokenPool.abi.Events["AllowListRemove"].ID: + return _USDCTokenPool.ParseAllowListRemove(log) + case _USDCTokenPool.abi.Events["Burned"].ID: + return _USDCTokenPool.ParseBurned(log) + case _USDCTokenPool.abi.Events["ChainAdded"].ID: + return _USDCTokenPool.ParseChainAdded(log) + case _USDCTokenPool.abi.Events["ChainConfigured"].ID: + return _USDCTokenPool.ParseChainConfigured(log) + case _USDCTokenPool.abi.Events["ChainRemoved"].ID: + return _USDCTokenPool.ParseChainRemoved(log) + case _USDCTokenPool.abi.Events["ConfigSet"].ID: + return _USDCTokenPool.ParseConfigSet(log) + case _USDCTokenPool.abi.Events["DomainsSet"].ID: + return _USDCTokenPool.ParseDomainsSet(log) + case _USDCTokenPool.abi.Events["Locked"].ID: + return _USDCTokenPool.ParseLocked(log) + case _USDCTokenPool.abi.Events["Minted"].ID: + return _USDCTokenPool.ParseMinted(log) + case _USDCTokenPool.abi.Events["OwnershipTransferRequested"].ID: + return _USDCTokenPool.ParseOwnershipTransferRequested(log) + case _USDCTokenPool.abi.Events["OwnershipTransferred"].ID: + return _USDCTokenPool.ParseOwnershipTransferred(log) + case _USDCTokenPool.abi.Events["Released"].ID: + return _USDCTokenPool.ParseReleased(log) + case _USDCTokenPool.abi.Events["RouterUpdated"].ID: + return _USDCTokenPool.ParseRouterUpdated(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (USDCTokenPoolAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (USDCTokenPoolAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (USDCTokenPoolBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (USDCTokenPoolChainAdded) Topic() common.Hash { + return common.HexToHash("0x0f135cbb9afa12a8bf3bbd071c117bcca4ddeca6160ef7f33d012a81b9c0c471") +} + +func (USDCTokenPoolChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (USDCTokenPoolChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (USDCTokenPoolConfigSet) Topic() common.Hash { + return common.HexToHash("0x2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea9544") +} + +func (USDCTokenPoolDomainsSet) Topic() common.Hash { + return common.HexToHash("0x1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee56") +} + +func (USDCTokenPoolLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (USDCTokenPoolMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (USDCTokenPoolOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (USDCTokenPoolOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (USDCTokenPoolReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (USDCTokenPoolRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (_USDCTokenPool *USDCTokenPool) Address() common.Address { + return _USDCTokenPool.address +} + +type USDCTokenPoolInterface interface { + SUPPORTEDUSDCVERSION(opts *bind.CallOpts) (uint32, error) + + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetArmProxy(opts *bind.CallOpts) (common.Address, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetDomain(opts *bind.CallOpts, chainSelector uint64) (USDCTokenPoolDomain, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + GetUSDCInterfaceId(opts *bind.CallOpts) ([4]byte, error) + + ILocalDomainIdentifier(opts *bind.CallOpts) (uint32, error) + + IMessageTransmitter(opts *bind.CallOpts) (common.Address, error) + + ITokenMessenger(opts *bind.CallOpts) (common.Address, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, originalSender common.Address, destinationReceiver []byte, amount *big.Int, remoteChainSelector uint64, arg4 []byte) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, arg0 []byte, receiver common.Address, amount *big.Int, remoteChainSelector uint64, extraData []byte) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetDomains(opts *bind.TransactOpts, domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*USDCTokenPoolAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*USDCTokenPoolAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*USDCTokenPoolAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*USDCTokenPoolAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*USDCTokenPoolBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*USDCTokenPoolBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*USDCTokenPoolChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*USDCTokenPoolChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*USDCTokenPoolChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*USDCTokenPoolChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*USDCTokenPoolChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*USDCTokenPoolChainRemoved, error) + + FilterConfigSet(opts *bind.FilterOpts) (*USDCTokenPoolConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*USDCTokenPoolConfigSet, error) + + FilterDomainsSet(opts *bind.FilterOpts) (*USDCTokenPoolDomainsSetIterator, error) + + WatchDomainsSet(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolDomainsSet) (event.Subscription, error) + + ParseDomainsSet(log types.Log) (*USDCTokenPoolDomainsSet, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*USDCTokenPoolLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*USDCTokenPoolLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*USDCTokenPoolMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*USDCTokenPoolMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*USDCTokenPoolOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*USDCTokenPoolOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*USDCTokenPoolOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*USDCTokenPoolOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*USDCTokenPoolReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*USDCTokenPoolReleased, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*USDCTokenPoolRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*USDCTokenPoolRouterUpdated, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generated/weth9/weth9.go b/core/gethwrappers/ccip/generated/weth9/weth9.go new file mode 100644 index 0000000000..50d0aa23f7 --- /dev/null +++ b/core/gethwrappers/ccip/generated/weth9/weth9.go @@ -0,0 +1,996 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package weth9 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var WETH9MetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60c0604052600d60809081526c2bb930b83832b21022ba3432b960991b60a05260009061002c9082610116565b506040805180820190915260048152630ae8aa8960e31b60208201526001906100559082610116565b506002805460ff1916601217905534801561006f57600080fd5b506101d5565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061009f57607f821691505b6020821081036100bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610111576000816000526020600020601f850160051c810160208610156100ee5750805b601f850160051c820191505b8181101561010d578281556001016100fa565b5050505b505050565b81516001600160401b0381111561012f5761012f610075565b6101438161013d845461008b565b846100c5565b602080601f83116001811461017857600084156101605750858301515b600019600386901b1c1916600185901b17855561010d565b600085815260208120601f198616915b828110156101a757888601518255948401946001909101908401610188565b50858210156101c55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6108ad806101e46000396000f3fe6080604052600436106100c05760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146101fa578063d0e30db01461021a578063dd62ed3e1461022257600080fd5b8063313ce5671461018c57806370a08231146101b857806395d89b41146101e557600080fd5b806318160ddd116100a557806318160ddd1461012f57806323b872dd1461014c5780632e1a7d4d1461016c57600080fd5b806306fdde03146100d4578063095ea7b3146100ff57600080fd5b366100cf576100cd61025a565b005b600080fd5b3480156100e057600080fd5b506100e96102b5565b6040516100f69190610695565b60405180910390f35b34801561010b57600080fd5b5061011f61011a36600461072b565b610343565b60405190151581526020016100f6565b34801561013b57600080fd5b50475b6040519081526020016100f6565b34801561015857600080fd5b5061011f610167366004610755565b6103bd565b34801561017857600080fd5b506100cd610187366004610791565b6105c4565b34801561019857600080fd5b506002546101a69060ff1681565b60405160ff90911681526020016100f6565b3480156101c457600080fd5b5061013e6101d33660046107aa565b60036020526000908152604090205481565b3480156101f157600080fd5b506100e961066a565b34801561020657600080fd5b5061011f61021536600461072b565b610677565b6100cd61068b565b34801561022e57600080fd5b5061013e61023d3660046107c5565b600460209081526000928352604080842090915290825290205481565b3360009081526003602052604081208054349290610279908490610827565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b600080546102c29061083a565b80601f01602080910402602001604051908101604052809291908181526020018280546102ee9061083a565b801561033b5780601f106103105761010080835404028352916020019161033b565b820191906000526020600020905b81548152906001019060200180831161031e57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103ab9086815260200190565b60405180910390a35060015b92915050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156103ef57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610455575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020546fffffffffffffffffffffffffffffffff14155b156104dd5773ffffffffffffffffffffffffffffffffffffffff8416600090815260046020908152604080832033845290915290205482111561049757600080fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152600460209081526040808320338452909152812080548492906104d790849061088d565b90915550505b73ffffffffffffffffffffffffffffffffffffffff84166000908152600360205260408120805484929061051290849061088d565b909155505073ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120805484929061054c908490610827565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516105b291815260200190565b60405180910390a35060019392505050565b336000908152600360205260409020548111156105e057600080fd5b33600090815260036020526040812080548392906105ff90849061088d565b9091555050604051339082156108fc029083906000818181858888f19350505050158015610631573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b600180546102c29061083a565b60006106843384846103bd565b9392505050565b61069361025a565b565b60006020808352835180602085015260005b818110156106c3578581018301518582016040015282016106a7565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461072657600080fd5b919050565b6000806040838503121561073e57600080fd5b61074783610702565b946020939093013593505050565b60008060006060848603121561076a57600080fd5b61077384610702565b925061078160208501610702565b9150604084013590509250925092565b6000602082840312156107a357600080fd5b5035919050565b6000602082840312156107bc57600080fd5b61068482610702565b600080604083850312156107d857600080fd5b6107e183610702565b91506107ef60208401610702565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156103b7576103b76107f8565b600181811c9082168061084e57607f821691505b602082108103610887577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b818103818111156103b7576103b76107f856fea164736f6c6343000818000a", +} + +var WETH9ABI = WETH9MetaData.ABI + +var WETH9Bin = WETH9MetaData.Bin + +func DeployWETH9(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *WETH9, error) { + parsed, err := WETH9MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(WETH9Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &WETH9{address: address, abi: *parsed, WETH9Caller: WETH9Caller{contract: contract}, WETH9Transactor: WETH9Transactor{contract: contract}, WETH9Filterer: WETH9Filterer{contract: contract}}, nil +} + +type WETH9 struct { + address common.Address + abi abi.ABI + WETH9Caller + WETH9Transactor + WETH9Filterer +} + +type WETH9Caller struct { + contract *bind.BoundContract +} + +type WETH9Transactor struct { + contract *bind.BoundContract +} + +type WETH9Filterer struct { + contract *bind.BoundContract +} + +type WETH9Session struct { + Contract *WETH9 + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type WETH9CallerSession struct { + Contract *WETH9Caller + CallOpts bind.CallOpts +} + +type WETH9TransactorSession struct { + Contract *WETH9Transactor + TransactOpts bind.TransactOpts +} + +type WETH9Raw struct { + Contract *WETH9 +} + +type WETH9CallerRaw struct { + Contract *WETH9Caller +} + +type WETH9TransactorRaw struct { + Contract *WETH9Transactor +} + +func NewWETH9(address common.Address, backend bind.ContractBackend) (*WETH9, error) { + abi, err := abi.JSON(strings.NewReader(WETH9ABI)) + if err != nil { + return nil, err + } + contract, err := bindWETH9(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &WETH9{address: address, abi: abi, WETH9Caller: WETH9Caller{contract: contract}, WETH9Transactor: WETH9Transactor{contract: contract}, WETH9Filterer: WETH9Filterer{contract: contract}}, nil +} + +func NewWETH9Caller(address common.Address, caller bind.ContractCaller) (*WETH9Caller, error) { + contract, err := bindWETH9(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &WETH9Caller{contract: contract}, nil +} + +func NewWETH9Transactor(address common.Address, transactor bind.ContractTransactor) (*WETH9Transactor, error) { + contract, err := bindWETH9(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &WETH9Transactor{contract: contract}, nil +} + +func NewWETH9Filterer(address common.Address, filterer bind.ContractFilterer) (*WETH9Filterer, error) { + contract, err := bindWETH9(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &WETH9Filterer{contract: contract}, nil +} + +func bindWETH9(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := WETH9MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_WETH9 *WETH9Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _WETH9.Contract.WETH9Caller.contract.Call(opts, result, method, params...) +} + +func (_WETH9 *WETH9Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WETH9.Contract.WETH9Transactor.contract.Transfer(opts) +} + +func (_WETH9 *WETH9Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _WETH9.Contract.WETH9Transactor.contract.Transact(opts, method, params...) +} + +func (_WETH9 *WETH9CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _WETH9.Contract.contract.Call(opts, result, method, params...) +} + +func (_WETH9 *WETH9TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WETH9.Contract.contract.Transfer(opts) +} + +func (_WETH9 *WETH9TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _WETH9.Contract.contract.Transact(opts, method, params...) +} + +func (_WETH9 *WETH9Caller) Allowance(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (*big.Int, error) { + var out []interface{} + err := _WETH9.contract.Call(opts, &out, "allowance", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_WETH9 *WETH9Session) Allowance(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _WETH9.Contract.Allowance(&_WETH9.CallOpts, arg0, arg1) +} + +func (_WETH9 *WETH9CallerSession) Allowance(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _WETH9.Contract.Allowance(&_WETH9.CallOpts, arg0, arg1) +} + +func (_WETH9 *WETH9Caller) BalanceOf(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { + var out []interface{} + err := _WETH9.contract.Call(opts, &out, "balanceOf", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_WETH9 *WETH9Session) BalanceOf(arg0 common.Address) (*big.Int, error) { + return _WETH9.Contract.BalanceOf(&_WETH9.CallOpts, arg0) +} + +func (_WETH9 *WETH9CallerSession) BalanceOf(arg0 common.Address) (*big.Int, error) { + return _WETH9.Contract.BalanceOf(&_WETH9.CallOpts, arg0) +} + +func (_WETH9 *WETH9Caller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _WETH9.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_WETH9 *WETH9Session) Decimals() (uint8, error) { + return _WETH9.Contract.Decimals(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9CallerSession) Decimals() (uint8, error) { + return _WETH9.Contract.Decimals(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9Caller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _WETH9.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_WETH9 *WETH9Session) Name() (string, error) { + return _WETH9.Contract.Name(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9CallerSession) Name() (string, error) { + return _WETH9.Contract.Name(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9Caller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _WETH9.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_WETH9 *WETH9Session) Symbol() (string, error) { + return _WETH9.Contract.Symbol(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9CallerSession) Symbol() (string, error) { + return _WETH9.Contract.Symbol(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _WETH9.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_WETH9 *WETH9Session) TotalSupply() (*big.Int, error) { + return _WETH9.Contract.TotalSupply(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9CallerSession) TotalSupply() (*big.Int, error) { + return _WETH9.Contract.TotalSupply(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9Transactor) Approve(opts *bind.TransactOpts, guy common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.contract.Transact(opts, "approve", guy, wad) +} + +func (_WETH9 *WETH9Session) Approve(guy common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Approve(&_WETH9.TransactOpts, guy, wad) +} + +func (_WETH9 *WETH9TransactorSession) Approve(guy common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Approve(&_WETH9.TransactOpts, guy, wad) +} + +func (_WETH9 *WETH9Transactor) Deposit(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WETH9.contract.Transact(opts, "deposit") +} + +func (_WETH9 *WETH9Session) Deposit() (*types.Transaction, error) { + return _WETH9.Contract.Deposit(&_WETH9.TransactOpts) +} + +func (_WETH9 *WETH9TransactorSession) Deposit() (*types.Transaction, error) { + return _WETH9.Contract.Deposit(&_WETH9.TransactOpts) +} + +func (_WETH9 *WETH9Transactor) Transfer(opts *bind.TransactOpts, dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.contract.Transact(opts, "transfer", dst, wad) +} + +func (_WETH9 *WETH9Session) Transfer(dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Transfer(&_WETH9.TransactOpts, dst, wad) +} + +func (_WETH9 *WETH9TransactorSession) Transfer(dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Transfer(&_WETH9.TransactOpts, dst, wad) +} + +func (_WETH9 *WETH9Transactor) TransferFrom(opts *bind.TransactOpts, src common.Address, dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.contract.Transact(opts, "transferFrom", src, dst, wad) +} + +func (_WETH9 *WETH9Session) TransferFrom(src common.Address, dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.TransferFrom(&_WETH9.TransactOpts, src, dst, wad) +} + +func (_WETH9 *WETH9TransactorSession) TransferFrom(src common.Address, dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.TransferFrom(&_WETH9.TransactOpts, src, dst, wad) +} + +func (_WETH9 *WETH9Transactor) Withdraw(opts *bind.TransactOpts, wad *big.Int) (*types.Transaction, error) { + return _WETH9.contract.Transact(opts, "withdraw", wad) +} + +func (_WETH9 *WETH9Session) Withdraw(wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Withdraw(&_WETH9.TransactOpts, wad) +} + +func (_WETH9 *WETH9TransactorSession) Withdraw(wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Withdraw(&_WETH9.TransactOpts, wad) +} + +func (_WETH9 *WETH9Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WETH9.contract.RawTransact(opts, nil) +} + +func (_WETH9 *WETH9Session) Receive() (*types.Transaction, error) { + return _WETH9.Contract.Receive(&_WETH9.TransactOpts) +} + +func (_WETH9 *WETH9TransactorSession) Receive() (*types.Transaction, error) { + return _WETH9.Contract.Receive(&_WETH9.TransactOpts) +} + +type WETH9ApprovalIterator struct { + Event *WETH9Approval + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *WETH9ApprovalIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(WETH9Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(WETH9Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *WETH9ApprovalIterator) Error() error { + return it.fail +} + +func (it *WETH9ApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type WETH9Approval struct { + Src common.Address + Guy common.Address + Wad *big.Int + Raw types.Log +} + +func (_WETH9 *WETH9Filterer) FilterApproval(opts *bind.FilterOpts, src []common.Address, guy []common.Address) (*WETH9ApprovalIterator, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + var guyRule []interface{} + for _, guyItem := range guy { + guyRule = append(guyRule, guyItem) + } + + logs, sub, err := _WETH9.contract.FilterLogs(opts, "Approval", srcRule, guyRule) + if err != nil { + return nil, err + } + return &WETH9ApprovalIterator{contract: _WETH9.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +func (_WETH9 *WETH9Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *WETH9Approval, src []common.Address, guy []common.Address) (event.Subscription, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + var guyRule []interface{} + for _, guyItem := range guy { + guyRule = append(guyRule, guyItem) + } + + logs, sub, err := _WETH9.contract.WatchLogs(opts, "Approval", srcRule, guyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(WETH9Approval) + if err := _WETH9.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_WETH9 *WETH9Filterer) ParseApproval(log types.Log) (*WETH9Approval, error) { + event := new(WETH9Approval) + if err := _WETH9.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type WETH9DepositIterator struct { + Event *WETH9Deposit + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *WETH9DepositIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(WETH9Deposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(WETH9Deposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *WETH9DepositIterator) Error() error { + return it.fail +} + +func (it *WETH9DepositIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type WETH9Deposit struct { + Dst common.Address + Wad *big.Int + Raw types.Log +} + +func (_WETH9 *WETH9Filterer) FilterDeposit(opts *bind.FilterOpts, dst []common.Address) (*WETH9DepositIterator, error) { + + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _WETH9.contract.FilterLogs(opts, "Deposit", dstRule) + if err != nil { + return nil, err + } + return &WETH9DepositIterator{contract: _WETH9.contract, event: "Deposit", logs: logs, sub: sub}, nil +} + +func (_WETH9 *WETH9Filterer) WatchDeposit(opts *bind.WatchOpts, sink chan<- *WETH9Deposit, dst []common.Address) (event.Subscription, error) { + + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _WETH9.contract.WatchLogs(opts, "Deposit", dstRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(WETH9Deposit) + if err := _WETH9.contract.UnpackLog(event, "Deposit", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_WETH9 *WETH9Filterer) ParseDeposit(log types.Log) (*WETH9Deposit, error) { + event := new(WETH9Deposit) + if err := _WETH9.contract.UnpackLog(event, "Deposit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type WETH9TransferIterator struct { + Event *WETH9Transfer + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *WETH9TransferIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(WETH9Transfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(WETH9Transfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *WETH9TransferIterator) Error() error { + return it.fail +} + +func (it *WETH9TransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type WETH9Transfer struct { + Src common.Address + Dst common.Address + Wad *big.Int + Raw types.Log +} + +func (_WETH9 *WETH9Filterer) FilterTransfer(opts *bind.FilterOpts, src []common.Address, dst []common.Address) (*WETH9TransferIterator, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _WETH9.contract.FilterLogs(opts, "Transfer", srcRule, dstRule) + if err != nil { + return nil, err + } + return &WETH9TransferIterator{contract: _WETH9.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +func (_WETH9 *WETH9Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *WETH9Transfer, src []common.Address, dst []common.Address) (event.Subscription, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _WETH9.contract.WatchLogs(opts, "Transfer", srcRule, dstRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(WETH9Transfer) + if err := _WETH9.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_WETH9 *WETH9Filterer) ParseTransfer(log types.Log) (*WETH9Transfer, error) { + event := new(WETH9Transfer) + if err := _WETH9.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type WETH9WithdrawalIterator struct { + Event *WETH9Withdrawal + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *WETH9WithdrawalIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(WETH9Withdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(WETH9Withdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *WETH9WithdrawalIterator) Error() error { + return it.fail +} + +func (it *WETH9WithdrawalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type WETH9Withdrawal struct { + Src common.Address + Wad *big.Int + Raw types.Log +} + +func (_WETH9 *WETH9Filterer) FilterWithdrawal(opts *bind.FilterOpts, src []common.Address) (*WETH9WithdrawalIterator, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + + logs, sub, err := _WETH9.contract.FilterLogs(opts, "Withdrawal", srcRule) + if err != nil { + return nil, err + } + return &WETH9WithdrawalIterator{contract: _WETH9.contract, event: "Withdrawal", logs: logs, sub: sub}, nil +} + +func (_WETH9 *WETH9Filterer) WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *WETH9Withdrawal, src []common.Address) (event.Subscription, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + + logs, sub, err := _WETH9.contract.WatchLogs(opts, "Withdrawal", srcRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(WETH9Withdrawal) + if err := _WETH9.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_WETH9 *WETH9Filterer) ParseWithdrawal(log types.Log) (*WETH9Withdrawal, error) { + event := new(WETH9Withdrawal) + if err := _WETH9.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_WETH9 *WETH9) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _WETH9.abi.Events["Approval"].ID: + return _WETH9.ParseApproval(log) + case _WETH9.abi.Events["Deposit"].ID: + return _WETH9.ParseDeposit(log) + case _WETH9.abi.Events["Transfer"].ID: + return _WETH9.ParseTransfer(log) + case _WETH9.abi.Events["Withdrawal"].ID: + return _WETH9.ParseWithdrawal(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (WETH9Approval) Topic() common.Hash { + return common.HexToHash("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925") +} + +func (WETH9Deposit) Topic() common.Hash { + return common.HexToHash("0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c") +} + +func (WETH9Transfer) Topic() common.Hash { + return common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") +} + +func (WETH9Withdrawal) Topic() common.Hash { + return common.HexToHash("0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65") +} + +func (_WETH9 *WETH9) Address() common.Address { + return _WETH9.address +} + +type WETH9Interface interface { + Allowance(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (*big.Int, error) + + BalanceOf(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) + + Decimals(opts *bind.CallOpts) (uint8, error) + + Name(opts *bind.CallOpts) (string, error) + + Symbol(opts *bind.CallOpts) (string, error) + + TotalSupply(opts *bind.CallOpts) (*big.Int, error) + + Approve(opts *bind.TransactOpts, guy common.Address, wad *big.Int) (*types.Transaction, error) + + Deposit(opts *bind.TransactOpts) (*types.Transaction, error) + + Transfer(opts *bind.TransactOpts, dst common.Address, wad *big.Int) (*types.Transaction, error) + + TransferFrom(opts *bind.TransactOpts, src common.Address, dst common.Address, wad *big.Int) (*types.Transaction, error) + + Withdraw(opts *bind.TransactOpts, wad *big.Int) (*types.Transaction, error) + + Receive(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterApproval(opts *bind.FilterOpts, src []common.Address, guy []common.Address) (*WETH9ApprovalIterator, error) + + WatchApproval(opts *bind.WatchOpts, sink chan<- *WETH9Approval, src []common.Address, guy []common.Address) (event.Subscription, error) + + ParseApproval(log types.Log) (*WETH9Approval, error) + + FilterDeposit(opts *bind.FilterOpts, dst []common.Address) (*WETH9DepositIterator, error) + + WatchDeposit(opts *bind.WatchOpts, sink chan<- *WETH9Deposit, dst []common.Address) (event.Subscription, error) + + ParseDeposit(log types.Log) (*WETH9Deposit, error) + + FilterTransfer(opts *bind.FilterOpts, src []common.Address, dst []common.Address) (*WETH9TransferIterator, error) + + WatchTransfer(opts *bind.WatchOpts, sink chan<- *WETH9Transfer, src []common.Address, dst []common.Address) (event.Subscription, error) + + ParseTransfer(log types.Log) (*WETH9Transfer, error) + + FilterWithdrawal(opts *bind.FilterOpts, src []common.Address) (*WETH9WithdrawalIterator, error) + + WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *WETH9Withdrawal, src []common.Address) (event.Subscription, error) + + ParseWithdrawal(log types.Log) (*WETH9Withdrawal, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt new file mode 100644 index 0000000000..663eacb5dd --- /dev/null +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -0,0 +1,37 @@ +GETH_VERSION: 1.13.8 +arm_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 1a0abacf84def916519013f713b667f106434a091af8b9f441e12cc90aa2cdf8 +arm_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 +burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin d0708a0ae657eb7df01a5177ff4d5850c5823c821f5f6bbd0a468b3982330b13 +burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin fcb85edfc871504a5146db2e3951193c2de089fe491dd7a2fbc755fd92725cac +burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 17bcd03828f43f50028bc4d66fdfb0cf576aaf28895d8f86c6ff598159a0cd64 +burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6f40135e1488097eafa843839a719fe9a3c21354565b64eb377a24a0a55782ef +ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin c06c1cf1d004a803585a2c9d7a71ee5997b5fca86c2e111335cb8b930d9e3b5a +commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin ddc26c10c2a52b59624faae9005827b09b98db4566887a736005e8cc37cf8a51 +commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin ebd8aac686fa28a71d4212bcd25a28f8f640d50dce5e50498b2f6b8534890b69 +ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de +evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 25a7bf3aa46252844c7afabc15db1051e7b6a717e296fc4c6e2f2f93d16033c5 +evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 9478aedc9f0072fbdafb54a6f82248de1efbcd7bdff18a90d8556b9aaff67455 +evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin a8c23c9280a713544eae0a0b8841a9caf97e616338d31ebc62501d8b4ab0eed6 +evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 116d5cb8447a1af61664a8d1db2d76086c042a3228337bc5cd49b9abd3e815f7 +lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin 95a93517b01f51c35d82711a0015995f4804820ed67f6b46b785c4c94815df93 +lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin 05e308151b5adc9ba8d33385b8f82d55aad638652fe50e3ea8b09b1d0bbfd367 +maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 +message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin 1d5146d43e1b99cd2d6f9f06475be19087e4349f7cee0fdbbf134ba65e967c93 +mock_arm_contract: ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.abi ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.bin e7a3a6c3eda5fb882e16bcc2b4340f78523acb67907bcdcaf3c8ffc51488688e +mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin e0cf17a38b438239fc6294ddca88f86b6c39e4542aefd9815b2d92987191b8bd +mock_usdc_token_transmitter: ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin 33bdad70822e889de7c720ed20085cf9cd3f8eba8b68f26bd6535197749595fe +mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin 518e19efa2ff52b0fefd8e597b05765317ee7638189bfe34ca43de2f6599faf4 +multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin abb0ecb1ed8621f26e43b39f5fa25f3d0b6d6c184fa37c404c4389605ecb74e7 +multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin aa299e0c2659d53aad4eace4d66be0e734b1366008593669cf30361ff529da6a +nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 78b58f4f192db7496e2b6de805d6a2c918b98d4fa62f3c7ed145ef3b5657a40d +ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 +ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 1588313bb5e781d181a825247d30828f59007700f36b4b9b00391592b06ff4b4 +price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 09cdd37920d6f605c8a264f805bdba183813517169b2b5df4547e995d9ce73f7 +registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 7b2a47349d3fdb8d8b4e206d68577219deca7fabd1e893686fa8f118ad980d2d +report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin c07af8433bf8dbc7981725b18922a9c4e2dea068dd204bc62adc0e926cb499c3 +router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 42576577e81beea9a069bd9229caaa9a71227fbaef3871a1a2e69fd218216290 +self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 86e169636e5633854ed0b709c804066b615040bceba25aa5137450fbe6f76fa3 +token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin fb06d2cf5f7476e512c6fb7aab8eab43545efd7f0f6ca133c64ff4e3963902c4 +token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 47a83e91b28ad1381a2a5882e2adfe168809a63a8f533ab1631f174550c64bed +usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin a54136ed9bffc74fff830c5066dbfcee6db1f31d636795317267d6baf1e0427a +weth9: ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin 2970d79a0ca6dd6279cde130de45e56c8790ed695eae477fb5ba4c1bb75b720d diff --git a/core/gethwrappers/ccip/go_generate.go b/core/gethwrappers/ccip/go_generate.go new file mode 100644 index 0000000000..870ac2dd57 --- /dev/null +++ b/core/gethwrappers/ccip/go_generate.go @@ -0,0 +1,80 @@ +// Package gethwrappers_ccip provides tools for wrapping solidity contracts with +// golang packages, using abigen. +package ccip + +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin CommitStore commit_store +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin CommitStoreHelper commit_store_helper +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin BurnMintTokenPool burn_mint_token_pool +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin BurnFromMintTokenPool burn_from_mint_token_pool +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin BurnWithFromMintTokenPool burn_with_from_mint_token_pool +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin LockReleaseTokenPool lock_release_token_pool +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin BurnMintTokenPoolAndProxy burn_mint_token_pool_and_proxy +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin LockReleaseTokenPoolAndProxy lock_release_token_pool_and_proxy +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin TokenPool token_pool +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin ARMContract arm_contract +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin ARMProxyContract arm_proxy_contract +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.abi ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.bin MockARMContract mock_arm_contract +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin TokenAdminRegistry token_admin_registry +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin RegistryModuleOwnerCustom registry_module_owner_custom +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin MockE2EUSDCTokenMessenger mock_usdc_token_messenger +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin MockE2EUSDCTransmitter mock_usdc_token_transmitter + +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin MockV3Aggregator mock_v3_aggregator_contract + +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin EVM2EVMOnRamp evm_2_evm_onramp +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin EVM2EVMMultiOnRamp evm_2_evm_multi_onramp +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin EVM2EVMOffRamp evm_2_evm_offramp +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin EVM2EVMMultiOffRamp evm_2_evm_multi_offramp +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin MultiAggregateRateLimiter multi_aggregate_rate_limiter +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin Router router +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin PriceRegistry price_registry +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin CCIPConfig ccip_config +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin IOCR3ConfigEncoder ocr3_config_encoder +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin NonceManager nonce_manager + +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin MaybeRevertMessageReceiver maybe_revert_message_receiver +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin PingPongDemo ping_pong_demo +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin SelfFundedPingPong self_funded_ping_pong +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin MessageHasher message_hasher +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin MultiOCR3Helper multi_ocr3_helper +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin ReportCodec report_codec +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin EtherSenderReceiver ether_sender_receiver +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin WETH9 weth9 + +// Customer contracts +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin USDCTokenPool usdc_token_pool + +// To run these commands, you must either install docker, or the correct version +// of abigen. The latter can be installed with these commands, at least on linux: +// +// git clone https://github.com/ethereum/go-ethereum +// cd go-ethereum/cmd/abigen +// git checkout v +// go install +// +// Here, is the version of go-ethereum specified in chainlink's +// go.mod. This will install abigen in "$GOPATH/bin", which you should add to +// your $PATH. +// +// To reduce explicit dependencies, and in case the system does not have the +// correct version of abigen installed , the above commands spin up docker +// containers. In my hands, total running time including compilation is about +// 13s. If you're modifying solidity code and testing against go code a lot, it +// might be worthwhile to generate the the wrappers using a static container +// with abigen and solc, which will complete much faster. E.g. +// +// abigen -sol ../../contracts/src/v0.6/VRFAll.sol -pkg vrf -out solidity_interfaces.go +// +// where VRFAll.sol simply contains `import "contract_path";` instructions for +// all the contracts you wish to target. This runs in about 0.25 seconds in my +// hands. +// +// If you're on linux, you can copy the correct version of solc out of the +// appropriate docker container. At least, the following works on ubuntu: +// +// $ docker run --name solc ethereum/solc:0.6.2 +// $ sudo docker cp solc:/usr/bin/solc /usr/bin +// $ docker rm solc +// +// If you need to point abigen at your solc executable, you can specify the path +// with the abigen --solc option. diff --git a/core/gethwrappers/ccip/mocks/commit_store_interface.go b/core/gethwrappers/ccip/mocks/commit_store_interface.go new file mode 100644 index 0000000000..124c2acaa4 --- /dev/null +++ b/core/gethwrappers/ccip/mocks/commit_store_interface.go @@ -0,0 +1,3418 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_contracts + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + commit_store "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + + event "github.com/ethereum/go-ethereum/event" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// CommitStoreInterface is an autogenerated mock type for the CommitStoreInterface type +type CommitStoreInterface struct { + mock.Mock +} + +type CommitStoreInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *CommitStoreInterface) EXPECT() *CommitStoreInterface_Expecter { + return &CommitStoreInterface_Expecter{mock: &_m.Mock} +} + +// AcceptOwnership provides a mock function with given fields: opts +func (_m *CommitStoreInterface) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for AcceptOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_AcceptOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AcceptOwnership' +type CommitStoreInterface_AcceptOwnership_Call struct { + *mock.Call +} + +// AcceptOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *CommitStoreInterface_Expecter) AcceptOwnership(opts interface{}) *CommitStoreInterface_AcceptOwnership_Call { + return &CommitStoreInterface_AcceptOwnership_Call{Call: _e.mock.On("AcceptOwnership", opts)} +} + +func (_c *CommitStoreInterface_AcceptOwnership_Call) Run(run func(opts *bind.TransactOpts)) *CommitStoreInterface_AcceptOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_AcceptOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *CommitStoreInterface_AcceptOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_AcceptOwnership_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *CommitStoreInterface_AcceptOwnership_Call { + _c.Call.Return(run) + return _c +} + +// Address provides a mock function with given fields: +func (_m *CommitStoreInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// CommitStoreInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type CommitStoreInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *CommitStoreInterface_Expecter) Address() *CommitStoreInterface_Address_Call { + return &CommitStoreInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *CommitStoreInterface_Address_Call) Run(run func()) *CommitStoreInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *CommitStoreInterface_Address_Call) Return(_a0 common.Address) *CommitStoreInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *CommitStoreInterface_Address_Call) RunAndReturn(run func() common.Address) *CommitStoreInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfigSet provides a mock function with given fields: opts +func (_m *CommitStoreInterface) FilterConfigSet(opts *bind.FilterOpts) (*commit_store.CommitStoreConfigSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterConfigSet") + } + + var r0 *commit_store.CommitStoreConfigSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*commit_store.CommitStoreConfigSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *commit_store.CommitStoreConfigSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreConfigSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_FilterConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfigSet' +type CommitStoreInterface_FilterConfigSet_Call struct { + *mock.Call +} + +// FilterConfigSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *CommitStoreInterface_Expecter) FilterConfigSet(opts interface{}) *CommitStoreInterface_FilterConfigSet_Call { + return &CommitStoreInterface_FilterConfigSet_Call{Call: _e.mock.On("FilterConfigSet", opts)} +} + +func (_c *CommitStoreInterface_FilterConfigSet_Call) Run(run func(opts *bind.FilterOpts)) *CommitStoreInterface_FilterConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_FilterConfigSet_Call) Return(_a0 *commit_store.CommitStoreConfigSetIterator, _a1 error) *CommitStoreInterface_FilterConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_FilterConfigSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*commit_store.CommitStoreConfigSetIterator, error)) *CommitStoreInterface_FilterConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfigSet0 provides a mock function with given fields: opts +func (_m *CommitStoreInterface) FilterConfigSet0(opts *bind.FilterOpts) (*commit_store.CommitStoreConfigSet0Iterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterConfigSet0") + } + + var r0 *commit_store.CommitStoreConfigSet0Iterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*commit_store.CommitStoreConfigSet0Iterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *commit_store.CommitStoreConfigSet0Iterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreConfigSet0Iterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_FilterConfigSet0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfigSet0' +type CommitStoreInterface_FilterConfigSet0_Call struct { + *mock.Call +} + +// FilterConfigSet0 is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *CommitStoreInterface_Expecter) FilterConfigSet0(opts interface{}) *CommitStoreInterface_FilterConfigSet0_Call { + return &CommitStoreInterface_FilterConfigSet0_Call{Call: _e.mock.On("FilterConfigSet0", opts)} +} + +func (_c *CommitStoreInterface_FilterConfigSet0_Call) Run(run func(opts *bind.FilterOpts)) *CommitStoreInterface_FilterConfigSet0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_FilterConfigSet0_Call) Return(_a0 *commit_store.CommitStoreConfigSet0Iterator, _a1 error) *CommitStoreInterface_FilterConfigSet0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_FilterConfigSet0_Call) RunAndReturn(run func(*bind.FilterOpts) (*commit_store.CommitStoreConfigSet0Iterator, error)) *CommitStoreInterface_FilterConfigSet0_Call { + _c.Call.Return(run) + return _c +} + +// FilterLatestPriceEpochAndRoundSet provides a mock function with given fields: opts +func (_m *CommitStoreInterface) FilterLatestPriceEpochAndRoundSet(opts *bind.FilterOpts) (*commit_store.CommitStoreLatestPriceEpochAndRoundSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterLatestPriceEpochAndRoundSet") + } + + var r0 *commit_store.CommitStoreLatestPriceEpochAndRoundSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*commit_store.CommitStoreLatestPriceEpochAndRoundSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *commit_store.CommitStoreLatestPriceEpochAndRoundSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreLatestPriceEpochAndRoundSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_FilterLatestPriceEpochAndRoundSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterLatestPriceEpochAndRoundSet' +type CommitStoreInterface_FilterLatestPriceEpochAndRoundSet_Call struct { + *mock.Call +} + +// FilterLatestPriceEpochAndRoundSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *CommitStoreInterface_Expecter) FilterLatestPriceEpochAndRoundSet(opts interface{}) *CommitStoreInterface_FilterLatestPriceEpochAndRoundSet_Call { + return &CommitStoreInterface_FilterLatestPriceEpochAndRoundSet_Call{Call: _e.mock.On("FilterLatestPriceEpochAndRoundSet", opts)} +} + +func (_c *CommitStoreInterface_FilterLatestPriceEpochAndRoundSet_Call) Run(run func(opts *bind.FilterOpts)) *CommitStoreInterface_FilterLatestPriceEpochAndRoundSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_FilterLatestPriceEpochAndRoundSet_Call) Return(_a0 *commit_store.CommitStoreLatestPriceEpochAndRoundSetIterator, _a1 error) *CommitStoreInterface_FilterLatestPriceEpochAndRoundSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_FilterLatestPriceEpochAndRoundSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*commit_store.CommitStoreLatestPriceEpochAndRoundSetIterator, error)) *CommitStoreInterface_FilterLatestPriceEpochAndRoundSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferRequested provides a mock function with given fields: opts, from, to +func (_m *CommitStoreInterface) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*commit_store.CommitStoreOwnershipTransferRequestedIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferRequested") + } + + var r0 *commit_store.CommitStoreOwnershipTransferRequestedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*commit_store.CommitStoreOwnershipTransferRequestedIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *commit_store.CommitStoreOwnershipTransferRequestedIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreOwnershipTransferRequestedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_FilterOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferRequested' +type CommitStoreInterface_FilterOwnershipTransferRequested_Call struct { + *mock.Call +} + +// FilterOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *CommitStoreInterface_Expecter) FilterOwnershipTransferRequested(opts interface{}, from interface{}, to interface{}) *CommitStoreInterface_FilterOwnershipTransferRequested_Call { + return &CommitStoreInterface_FilterOwnershipTransferRequested_Call{Call: _e.mock.On("FilterOwnershipTransferRequested", opts, from, to)} +} + +func (_c *CommitStoreInterface_FilterOwnershipTransferRequested_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *CommitStoreInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *CommitStoreInterface_FilterOwnershipTransferRequested_Call) Return(_a0 *commit_store.CommitStoreOwnershipTransferRequestedIterator, _a1 error) *CommitStoreInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_FilterOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*commit_store.CommitStoreOwnershipTransferRequestedIterator, error)) *CommitStoreInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferred provides a mock function with given fields: opts, from, to +func (_m *CommitStoreInterface) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*commit_store.CommitStoreOwnershipTransferredIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferred") + } + + var r0 *commit_store.CommitStoreOwnershipTransferredIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*commit_store.CommitStoreOwnershipTransferredIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *commit_store.CommitStoreOwnershipTransferredIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreOwnershipTransferredIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_FilterOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferred' +type CommitStoreInterface_FilterOwnershipTransferred_Call struct { + *mock.Call +} + +// FilterOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *CommitStoreInterface_Expecter) FilterOwnershipTransferred(opts interface{}, from interface{}, to interface{}) *CommitStoreInterface_FilterOwnershipTransferred_Call { + return &CommitStoreInterface_FilterOwnershipTransferred_Call{Call: _e.mock.On("FilterOwnershipTransferred", opts, from, to)} +} + +func (_c *CommitStoreInterface_FilterOwnershipTransferred_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *CommitStoreInterface_FilterOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *CommitStoreInterface_FilterOwnershipTransferred_Call) Return(_a0 *commit_store.CommitStoreOwnershipTransferredIterator, _a1 error) *CommitStoreInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_FilterOwnershipTransferred_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*commit_store.CommitStoreOwnershipTransferredIterator, error)) *CommitStoreInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// FilterPaused provides a mock function with given fields: opts +func (_m *CommitStoreInterface) FilterPaused(opts *bind.FilterOpts) (*commit_store.CommitStorePausedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterPaused") + } + + var r0 *commit_store.CommitStorePausedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*commit_store.CommitStorePausedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *commit_store.CommitStorePausedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStorePausedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_FilterPaused_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPaused' +type CommitStoreInterface_FilterPaused_Call struct { + *mock.Call +} + +// FilterPaused is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *CommitStoreInterface_Expecter) FilterPaused(opts interface{}) *CommitStoreInterface_FilterPaused_Call { + return &CommitStoreInterface_FilterPaused_Call{Call: _e.mock.On("FilterPaused", opts)} +} + +func (_c *CommitStoreInterface_FilterPaused_Call) Run(run func(opts *bind.FilterOpts)) *CommitStoreInterface_FilterPaused_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_FilterPaused_Call) Return(_a0 *commit_store.CommitStorePausedIterator, _a1 error) *CommitStoreInterface_FilterPaused_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_FilterPaused_Call) RunAndReturn(run func(*bind.FilterOpts) (*commit_store.CommitStorePausedIterator, error)) *CommitStoreInterface_FilterPaused_Call { + _c.Call.Return(run) + return _c +} + +// FilterReportAccepted provides a mock function with given fields: opts +func (_m *CommitStoreInterface) FilterReportAccepted(opts *bind.FilterOpts) (*commit_store.CommitStoreReportAcceptedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterReportAccepted") + } + + var r0 *commit_store.CommitStoreReportAcceptedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*commit_store.CommitStoreReportAcceptedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *commit_store.CommitStoreReportAcceptedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreReportAcceptedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_FilterReportAccepted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterReportAccepted' +type CommitStoreInterface_FilterReportAccepted_Call struct { + *mock.Call +} + +// FilterReportAccepted is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *CommitStoreInterface_Expecter) FilterReportAccepted(opts interface{}) *CommitStoreInterface_FilterReportAccepted_Call { + return &CommitStoreInterface_FilterReportAccepted_Call{Call: _e.mock.On("FilterReportAccepted", opts)} +} + +func (_c *CommitStoreInterface_FilterReportAccepted_Call) Run(run func(opts *bind.FilterOpts)) *CommitStoreInterface_FilterReportAccepted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_FilterReportAccepted_Call) Return(_a0 *commit_store.CommitStoreReportAcceptedIterator, _a1 error) *CommitStoreInterface_FilterReportAccepted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_FilterReportAccepted_Call) RunAndReturn(run func(*bind.FilterOpts) (*commit_store.CommitStoreReportAcceptedIterator, error)) *CommitStoreInterface_FilterReportAccepted_Call { + _c.Call.Return(run) + return _c +} + +// FilterRootRemoved provides a mock function with given fields: opts +func (_m *CommitStoreInterface) FilterRootRemoved(opts *bind.FilterOpts) (*commit_store.CommitStoreRootRemovedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterRootRemoved") + } + + var r0 *commit_store.CommitStoreRootRemovedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*commit_store.CommitStoreRootRemovedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *commit_store.CommitStoreRootRemovedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreRootRemovedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_FilterRootRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterRootRemoved' +type CommitStoreInterface_FilterRootRemoved_Call struct { + *mock.Call +} + +// FilterRootRemoved is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *CommitStoreInterface_Expecter) FilterRootRemoved(opts interface{}) *CommitStoreInterface_FilterRootRemoved_Call { + return &CommitStoreInterface_FilterRootRemoved_Call{Call: _e.mock.On("FilterRootRemoved", opts)} +} + +func (_c *CommitStoreInterface_FilterRootRemoved_Call) Run(run func(opts *bind.FilterOpts)) *CommitStoreInterface_FilterRootRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_FilterRootRemoved_Call) Return(_a0 *commit_store.CommitStoreRootRemovedIterator, _a1 error) *CommitStoreInterface_FilterRootRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_FilterRootRemoved_Call) RunAndReturn(run func(*bind.FilterOpts) (*commit_store.CommitStoreRootRemovedIterator, error)) *CommitStoreInterface_FilterRootRemoved_Call { + _c.Call.Return(run) + return _c +} + +// FilterSequenceNumberSet provides a mock function with given fields: opts +func (_m *CommitStoreInterface) FilterSequenceNumberSet(opts *bind.FilterOpts) (*commit_store.CommitStoreSequenceNumberSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterSequenceNumberSet") + } + + var r0 *commit_store.CommitStoreSequenceNumberSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*commit_store.CommitStoreSequenceNumberSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *commit_store.CommitStoreSequenceNumberSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreSequenceNumberSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_FilterSequenceNumberSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterSequenceNumberSet' +type CommitStoreInterface_FilterSequenceNumberSet_Call struct { + *mock.Call +} + +// FilterSequenceNumberSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *CommitStoreInterface_Expecter) FilterSequenceNumberSet(opts interface{}) *CommitStoreInterface_FilterSequenceNumberSet_Call { + return &CommitStoreInterface_FilterSequenceNumberSet_Call{Call: _e.mock.On("FilterSequenceNumberSet", opts)} +} + +func (_c *CommitStoreInterface_FilterSequenceNumberSet_Call) Run(run func(opts *bind.FilterOpts)) *CommitStoreInterface_FilterSequenceNumberSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_FilterSequenceNumberSet_Call) Return(_a0 *commit_store.CommitStoreSequenceNumberSetIterator, _a1 error) *CommitStoreInterface_FilterSequenceNumberSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_FilterSequenceNumberSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*commit_store.CommitStoreSequenceNumberSetIterator, error)) *CommitStoreInterface_FilterSequenceNumberSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterTransmitted provides a mock function with given fields: opts +func (_m *CommitStoreInterface) FilterTransmitted(opts *bind.FilterOpts) (*commit_store.CommitStoreTransmittedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterTransmitted") + } + + var r0 *commit_store.CommitStoreTransmittedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*commit_store.CommitStoreTransmittedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *commit_store.CommitStoreTransmittedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreTransmittedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_FilterTransmitted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTransmitted' +type CommitStoreInterface_FilterTransmitted_Call struct { + *mock.Call +} + +// FilterTransmitted is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *CommitStoreInterface_Expecter) FilterTransmitted(opts interface{}) *CommitStoreInterface_FilterTransmitted_Call { + return &CommitStoreInterface_FilterTransmitted_Call{Call: _e.mock.On("FilterTransmitted", opts)} +} + +func (_c *CommitStoreInterface_FilterTransmitted_Call) Run(run func(opts *bind.FilterOpts)) *CommitStoreInterface_FilterTransmitted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_FilterTransmitted_Call) Return(_a0 *commit_store.CommitStoreTransmittedIterator, _a1 error) *CommitStoreInterface_FilterTransmitted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_FilterTransmitted_Call) RunAndReturn(run func(*bind.FilterOpts) (*commit_store.CommitStoreTransmittedIterator, error)) *CommitStoreInterface_FilterTransmitted_Call { + _c.Call.Return(run) + return _c +} + +// FilterUnpaused provides a mock function with given fields: opts +func (_m *CommitStoreInterface) FilterUnpaused(opts *bind.FilterOpts) (*commit_store.CommitStoreUnpausedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterUnpaused") + } + + var r0 *commit_store.CommitStoreUnpausedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*commit_store.CommitStoreUnpausedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *commit_store.CommitStoreUnpausedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreUnpausedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_FilterUnpaused_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterUnpaused' +type CommitStoreInterface_FilterUnpaused_Call struct { + *mock.Call +} + +// FilterUnpaused is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *CommitStoreInterface_Expecter) FilterUnpaused(opts interface{}) *CommitStoreInterface_FilterUnpaused_Call { + return &CommitStoreInterface_FilterUnpaused_Call{Call: _e.mock.On("FilterUnpaused", opts)} +} + +func (_c *CommitStoreInterface_FilterUnpaused_Call) Run(run func(opts *bind.FilterOpts)) *CommitStoreInterface_FilterUnpaused_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_FilterUnpaused_Call) Return(_a0 *commit_store.CommitStoreUnpausedIterator, _a1 error) *CommitStoreInterface_FilterUnpaused_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_FilterUnpaused_Call) RunAndReturn(run func(*bind.FilterOpts) (*commit_store.CommitStoreUnpausedIterator, error)) *CommitStoreInterface_FilterUnpaused_Call { + _c.Call.Return(run) + return _c +} + +// GetDynamicConfig provides a mock function with given fields: opts +func (_m *CommitStoreInterface) GetDynamicConfig(opts *bind.CallOpts) (commit_store.CommitStoreDynamicConfig, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetDynamicConfig") + } + + var r0 commit_store.CommitStoreDynamicConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (commit_store.CommitStoreDynamicConfig, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) commit_store.CommitStoreDynamicConfig); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(commit_store.CommitStoreDynamicConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_GetDynamicConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDynamicConfig' +type CommitStoreInterface_GetDynamicConfig_Call struct { + *mock.Call +} + +// GetDynamicConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *CommitStoreInterface_Expecter) GetDynamicConfig(opts interface{}) *CommitStoreInterface_GetDynamicConfig_Call { + return &CommitStoreInterface_GetDynamicConfig_Call{Call: _e.mock.On("GetDynamicConfig", opts)} +} + +func (_c *CommitStoreInterface_GetDynamicConfig_Call) Run(run func(opts *bind.CallOpts)) *CommitStoreInterface_GetDynamicConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_GetDynamicConfig_Call) Return(_a0 commit_store.CommitStoreDynamicConfig, _a1 error) *CommitStoreInterface_GetDynamicConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_GetDynamicConfig_Call) RunAndReturn(run func(*bind.CallOpts) (commit_store.CommitStoreDynamicConfig, error)) *CommitStoreInterface_GetDynamicConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetExpectedNextSequenceNumber provides a mock function with given fields: opts +func (_m *CommitStoreInterface) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetExpectedNextSequenceNumber") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (uint64, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) uint64); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_GetExpectedNextSequenceNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExpectedNextSequenceNumber' +type CommitStoreInterface_GetExpectedNextSequenceNumber_Call struct { + *mock.Call +} + +// GetExpectedNextSequenceNumber is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *CommitStoreInterface_Expecter) GetExpectedNextSequenceNumber(opts interface{}) *CommitStoreInterface_GetExpectedNextSequenceNumber_Call { + return &CommitStoreInterface_GetExpectedNextSequenceNumber_Call{Call: _e.mock.On("GetExpectedNextSequenceNumber", opts)} +} + +func (_c *CommitStoreInterface_GetExpectedNextSequenceNumber_Call) Run(run func(opts *bind.CallOpts)) *CommitStoreInterface_GetExpectedNextSequenceNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_GetExpectedNextSequenceNumber_Call) Return(_a0 uint64, _a1 error) *CommitStoreInterface_GetExpectedNextSequenceNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_GetExpectedNextSequenceNumber_Call) RunAndReturn(run func(*bind.CallOpts) (uint64, error)) *CommitStoreInterface_GetExpectedNextSequenceNumber_Call { + _c.Call.Return(run) + return _c +} + +// GetLatestPriceEpochAndRound provides a mock function with given fields: opts +func (_m *CommitStoreInterface) GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetLatestPriceEpochAndRound") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (uint64, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) uint64); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_GetLatestPriceEpochAndRound_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLatestPriceEpochAndRound' +type CommitStoreInterface_GetLatestPriceEpochAndRound_Call struct { + *mock.Call +} + +// GetLatestPriceEpochAndRound is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *CommitStoreInterface_Expecter) GetLatestPriceEpochAndRound(opts interface{}) *CommitStoreInterface_GetLatestPriceEpochAndRound_Call { + return &CommitStoreInterface_GetLatestPriceEpochAndRound_Call{Call: _e.mock.On("GetLatestPriceEpochAndRound", opts)} +} + +func (_c *CommitStoreInterface_GetLatestPriceEpochAndRound_Call) Run(run func(opts *bind.CallOpts)) *CommitStoreInterface_GetLatestPriceEpochAndRound_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_GetLatestPriceEpochAndRound_Call) Return(_a0 uint64, _a1 error) *CommitStoreInterface_GetLatestPriceEpochAndRound_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_GetLatestPriceEpochAndRound_Call) RunAndReturn(run func(*bind.CallOpts) (uint64, error)) *CommitStoreInterface_GetLatestPriceEpochAndRound_Call { + _c.Call.Return(run) + return _c +} + +// GetMerkleRoot provides a mock function with given fields: opts, root +func (_m *CommitStoreInterface) GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) { + ret := _m.Called(opts, root) + + if len(ret) == 0 { + panic("no return value specified for GetMerkleRoot") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, [32]byte) (*big.Int, error)); ok { + return rf(opts, root) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, [32]byte) *big.Int); ok { + r0 = rf(opts, root) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, [32]byte) error); ok { + r1 = rf(opts, root) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_GetMerkleRoot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetMerkleRoot' +type CommitStoreInterface_GetMerkleRoot_Call struct { + *mock.Call +} + +// GetMerkleRoot is a helper method to define mock.On call +// - opts *bind.CallOpts +// - root [32]byte +func (_e *CommitStoreInterface_Expecter) GetMerkleRoot(opts interface{}, root interface{}) *CommitStoreInterface_GetMerkleRoot_Call { + return &CommitStoreInterface_GetMerkleRoot_Call{Call: _e.mock.On("GetMerkleRoot", opts, root)} +} + +func (_c *CommitStoreInterface_GetMerkleRoot_Call) Run(run func(opts *bind.CallOpts, root [32]byte)) *CommitStoreInterface_GetMerkleRoot_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].([32]byte)) + }) + return _c +} + +func (_c *CommitStoreInterface_GetMerkleRoot_Call) Return(_a0 *big.Int, _a1 error) *CommitStoreInterface_GetMerkleRoot_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_GetMerkleRoot_Call) RunAndReturn(run func(*bind.CallOpts, [32]byte) (*big.Int, error)) *CommitStoreInterface_GetMerkleRoot_Call { + _c.Call.Return(run) + return _c +} + +// GetStaticConfig provides a mock function with given fields: opts +func (_m *CommitStoreInterface) GetStaticConfig(opts *bind.CallOpts) (commit_store.CommitStoreStaticConfig, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetStaticConfig") + } + + var r0 commit_store.CommitStoreStaticConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (commit_store.CommitStoreStaticConfig, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) commit_store.CommitStoreStaticConfig); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(commit_store.CommitStoreStaticConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_GetStaticConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStaticConfig' +type CommitStoreInterface_GetStaticConfig_Call struct { + *mock.Call +} + +// GetStaticConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *CommitStoreInterface_Expecter) GetStaticConfig(opts interface{}) *CommitStoreInterface_GetStaticConfig_Call { + return &CommitStoreInterface_GetStaticConfig_Call{Call: _e.mock.On("GetStaticConfig", opts)} +} + +func (_c *CommitStoreInterface_GetStaticConfig_Call) Run(run func(opts *bind.CallOpts)) *CommitStoreInterface_GetStaticConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_GetStaticConfig_Call) Return(_a0 commit_store.CommitStoreStaticConfig, _a1 error) *CommitStoreInterface_GetStaticConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_GetStaticConfig_Call) RunAndReturn(run func(*bind.CallOpts) (commit_store.CommitStoreStaticConfig, error)) *CommitStoreInterface_GetStaticConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetTransmitters provides a mock function with given fields: opts +func (_m *CommitStoreInterface) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetTransmitters") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_GetTransmitters_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTransmitters' +type CommitStoreInterface_GetTransmitters_Call struct { + *mock.Call +} + +// GetTransmitters is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *CommitStoreInterface_Expecter) GetTransmitters(opts interface{}) *CommitStoreInterface_GetTransmitters_Call { + return &CommitStoreInterface_GetTransmitters_Call{Call: _e.mock.On("GetTransmitters", opts)} +} + +func (_c *CommitStoreInterface_GetTransmitters_Call) Run(run func(opts *bind.CallOpts)) *CommitStoreInterface_GetTransmitters_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_GetTransmitters_Call) Return(_a0 []common.Address, _a1 error) *CommitStoreInterface_GetTransmitters_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_GetTransmitters_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *CommitStoreInterface_GetTransmitters_Call { + _c.Call.Return(run) + return _c +} + +// IsBlessed provides a mock function with given fields: opts, root +func (_m *CommitStoreInterface) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { + ret := _m.Called(opts, root) + + if len(ret) == 0 { + panic("no return value specified for IsBlessed") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, [32]byte) (bool, error)); ok { + return rf(opts, root) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, [32]byte) bool); ok { + r0 = rf(opts, root) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, [32]byte) error); ok { + r1 = rf(opts, root) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_IsBlessed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsBlessed' +type CommitStoreInterface_IsBlessed_Call struct { + *mock.Call +} + +// IsBlessed is a helper method to define mock.On call +// - opts *bind.CallOpts +// - root [32]byte +func (_e *CommitStoreInterface_Expecter) IsBlessed(opts interface{}, root interface{}) *CommitStoreInterface_IsBlessed_Call { + return &CommitStoreInterface_IsBlessed_Call{Call: _e.mock.On("IsBlessed", opts, root)} +} + +func (_c *CommitStoreInterface_IsBlessed_Call) Run(run func(opts *bind.CallOpts, root [32]byte)) *CommitStoreInterface_IsBlessed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].([32]byte)) + }) + return _c +} + +func (_c *CommitStoreInterface_IsBlessed_Call) Return(_a0 bool, _a1 error) *CommitStoreInterface_IsBlessed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_IsBlessed_Call) RunAndReturn(run func(*bind.CallOpts, [32]byte) (bool, error)) *CommitStoreInterface_IsBlessed_Call { + _c.Call.Return(run) + return _c +} + +// IsUnpausedAndNotCursed provides a mock function with given fields: opts +func (_m *CommitStoreInterface) IsUnpausedAndNotCursed(opts *bind.CallOpts) (bool, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for IsUnpausedAndNotCursed") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (bool, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) bool); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_IsUnpausedAndNotCursed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsUnpausedAndNotCursed' +type CommitStoreInterface_IsUnpausedAndNotCursed_Call struct { + *mock.Call +} + +// IsUnpausedAndNotCursed is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *CommitStoreInterface_Expecter) IsUnpausedAndNotCursed(opts interface{}) *CommitStoreInterface_IsUnpausedAndNotCursed_Call { + return &CommitStoreInterface_IsUnpausedAndNotCursed_Call{Call: _e.mock.On("IsUnpausedAndNotCursed", opts)} +} + +func (_c *CommitStoreInterface_IsUnpausedAndNotCursed_Call) Run(run func(opts *bind.CallOpts)) *CommitStoreInterface_IsUnpausedAndNotCursed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_IsUnpausedAndNotCursed_Call) Return(_a0 bool, _a1 error) *CommitStoreInterface_IsUnpausedAndNotCursed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_IsUnpausedAndNotCursed_Call) RunAndReturn(run func(*bind.CallOpts) (bool, error)) *CommitStoreInterface_IsUnpausedAndNotCursed_Call { + _c.Call.Return(run) + return _c +} + +// LatestConfigDetails provides a mock function with given fields: opts +func (_m *CommitStoreInterface) LatestConfigDetails(opts *bind.CallOpts) (commit_store.LatestConfigDetails, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LatestConfigDetails") + } + + var r0 commit_store.LatestConfigDetails + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (commit_store.LatestConfigDetails, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) commit_store.LatestConfigDetails); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(commit_store.LatestConfigDetails) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_LatestConfigDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestConfigDetails' +type CommitStoreInterface_LatestConfigDetails_Call struct { + *mock.Call +} + +// LatestConfigDetails is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *CommitStoreInterface_Expecter) LatestConfigDetails(opts interface{}) *CommitStoreInterface_LatestConfigDetails_Call { + return &CommitStoreInterface_LatestConfigDetails_Call{Call: _e.mock.On("LatestConfigDetails", opts)} +} + +func (_c *CommitStoreInterface_LatestConfigDetails_Call) Run(run func(opts *bind.CallOpts)) *CommitStoreInterface_LatestConfigDetails_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_LatestConfigDetails_Call) Return(_a0 commit_store.LatestConfigDetails, _a1 error) *CommitStoreInterface_LatestConfigDetails_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_LatestConfigDetails_Call) RunAndReturn(run func(*bind.CallOpts) (commit_store.LatestConfigDetails, error)) *CommitStoreInterface_LatestConfigDetails_Call { + _c.Call.Return(run) + return _c +} + +// LatestConfigDigestAndEpoch provides a mock function with given fields: opts +func (_m *CommitStoreInterface) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (commit_store.LatestConfigDigestAndEpoch, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LatestConfigDigestAndEpoch") + } + + var r0 commit_store.LatestConfigDigestAndEpoch + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (commit_store.LatestConfigDigestAndEpoch, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) commit_store.LatestConfigDigestAndEpoch); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(commit_store.LatestConfigDigestAndEpoch) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_LatestConfigDigestAndEpoch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestConfigDigestAndEpoch' +type CommitStoreInterface_LatestConfigDigestAndEpoch_Call struct { + *mock.Call +} + +// LatestConfigDigestAndEpoch is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *CommitStoreInterface_Expecter) LatestConfigDigestAndEpoch(opts interface{}) *CommitStoreInterface_LatestConfigDigestAndEpoch_Call { + return &CommitStoreInterface_LatestConfigDigestAndEpoch_Call{Call: _e.mock.On("LatestConfigDigestAndEpoch", opts)} +} + +func (_c *CommitStoreInterface_LatestConfigDigestAndEpoch_Call) Run(run func(opts *bind.CallOpts)) *CommitStoreInterface_LatestConfigDigestAndEpoch_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_LatestConfigDigestAndEpoch_Call) Return(_a0 commit_store.LatestConfigDigestAndEpoch, _a1 error) *CommitStoreInterface_LatestConfigDigestAndEpoch_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_LatestConfigDigestAndEpoch_Call) RunAndReturn(run func(*bind.CallOpts) (commit_store.LatestConfigDigestAndEpoch, error)) *CommitStoreInterface_LatestConfigDigestAndEpoch_Call { + _c.Call.Return(run) + return _c +} + +// Owner provides a mock function with given fields: opts +func (_m *CommitStoreInterface) Owner(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Owner") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_Owner_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Owner' +type CommitStoreInterface_Owner_Call struct { + *mock.Call +} + +// Owner is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *CommitStoreInterface_Expecter) Owner(opts interface{}) *CommitStoreInterface_Owner_Call { + return &CommitStoreInterface_Owner_Call{Call: _e.mock.On("Owner", opts)} +} + +func (_c *CommitStoreInterface_Owner_Call) Run(run func(opts *bind.CallOpts)) *CommitStoreInterface_Owner_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_Owner_Call) Return(_a0 common.Address, _a1 error) *CommitStoreInterface_Owner_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_Owner_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *CommitStoreInterface_Owner_Call { + _c.Call.Return(run) + return _c +} + +// ParseConfigSet provides a mock function with given fields: log +func (_m *CommitStoreInterface) ParseConfigSet(log types.Log) (*commit_store.CommitStoreConfigSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseConfigSet") + } + + var r0 *commit_store.CommitStoreConfigSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*commit_store.CommitStoreConfigSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *commit_store.CommitStoreConfigSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreConfigSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ParseConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseConfigSet' +type CommitStoreInterface_ParseConfigSet_Call struct { + *mock.Call +} + +// ParseConfigSet is a helper method to define mock.On call +// - log types.Log +func (_e *CommitStoreInterface_Expecter) ParseConfigSet(log interface{}) *CommitStoreInterface_ParseConfigSet_Call { + return &CommitStoreInterface_ParseConfigSet_Call{Call: _e.mock.On("ParseConfigSet", log)} +} + +func (_c *CommitStoreInterface_ParseConfigSet_Call) Run(run func(log types.Log)) *CommitStoreInterface_ParseConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *CommitStoreInterface_ParseConfigSet_Call) Return(_a0 *commit_store.CommitStoreConfigSet, _a1 error) *CommitStoreInterface_ParseConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ParseConfigSet_Call) RunAndReturn(run func(types.Log) (*commit_store.CommitStoreConfigSet, error)) *CommitStoreInterface_ParseConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseConfigSet0 provides a mock function with given fields: log +func (_m *CommitStoreInterface) ParseConfigSet0(log types.Log) (*commit_store.CommitStoreConfigSet0, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseConfigSet0") + } + + var r0 *commit_store.CommitStoreConfigSet0 + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*commit_store.CommitStoreConfigSet0, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *commit_store.CommitStoreConfigSet0); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreConfigSet0) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ParseConfigSet0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseConfigSet0' +type CommitStoreInterface_ParseConfigSet0_Call struct { + *mock.Call +} + +// ParseConfigSet0 is a helper method to define mock.On call +// - log types.Log +func (_e *CommitStoreInterface_Expecter) ParseConfigSet0(log interface{}) *CommitStoreInterface_ParseConfigSet0_Call { + return &CommitStoreInterface_ParseConfigSet0_Call{Call: _e.mock.On("ParseConfigSet0", log)} +} + +func (_c *CommitStoreInterface_ParseConfigSet0_Call) Run(run func(log types.Log)) *CommitStoreInterface_ParseConfigSet0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *CommitStoreInterface_ParseConfigSet0_Call) Return(_a0 *commit_store.CommitStoreConfigSet0, _a1 error) *CommitStoreInterface_ParseConfigSet0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ParseConfigSet0_Call) RunAndReturn(run func(types.Log) (*commit_store.CommitStoreConfigSet0, error)) *CommitStoreInterface_ParseConfigSet0_Call { + _c.Call.Return(run) + return _c +} + +// ParseLatestPriceEpochAndRoundSet provides a mock function with given fields: log +func (_m *CommitStoreInterface) ParseLatestPriceEpochAndRoundSet(log types.Log) (*commit_store.CommitStoreLatestPriceEpochAndRoundSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLatestPriceEpochAndRoundSet") + } + + var r0 *commit_store.CommitStoreLatestPriceEpochAndRoundSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*commit_store.CommitStoreLatestPriceEpochAndRoundSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *commit_store.CommitStoreLatestPriceEpochAndRoundSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreLatestPriceEpochAndRoundSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ParseLatestPriceEpochAndRoundSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLatestPriceEpochAndRoundSet' +type CommitStoreInterface_ParseLatestPriceEpochAndRoundSet_Call struct { + *mock.Call +} + +// ParseLatestPriceEpochAndRoundSet is a helper method to define mock.On call +// - log types.Log +func (_e *CommitStoreInterface_Expecter) ParseLatestPriceEpochAndRoundSet(log interface{}) *CommitStoreInterface_ParseLatestPriceEpochAndRoundSet_Call { + return &CommitStoreInterface_ParseLatestPriceEpochAndRoundSet_Call{Call: _e.mock.On("ParseLatestPriceEpochAndRoundSet", log)} +} + +func (_c *CommitStoreInterface_ParseLatestPriceEpochAndRoundSet_Call) Run(run func(log types.Log)) *CommitStoreInterface_ParseLatestPriceEpochAndRoundSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *CommitStoreInterface_ParseLatestPriceEpochAndRoundSet_Call) Return(_a0 *commit_store.CommitStoreLatestPriceEpochAndRoundSet, _a1 error) *CommitStoreInterface_ParseLatestPriceEpochAndRoundSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ParseLatestPriceEpochAndRoundSet_Call) RunAndReturn(run func(types.Log) (*commit_store.CommitStoreLatestPriceEpochAndRoundSet, error)) *CommitStoreInterface_ParseLatestPriceEpochAndRoundSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *CommitStoreInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type CommitStoreInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *CommitStoreInterface_Expecter) ParseLog(log interface{}) *CommitStoreInterface_ParseLog_Call { + return &CommitStoreInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *CommitStoreInterface_ParseLog_Call) Run(run func(log types.Log)) *CommitStoreInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *CommitStoreInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *CommitStoreInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *CommitStoreInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferRequested provides a mock function with given fields: log +func (_m *CommitStoreInterface) ParseOwnershipTransferRequested(log types.Log) (*commit_store.CommitStoreOwnershipTransferRequested, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferRequested") + } + + var r0 *commit_store.CommitStoreOwnershipTransferRequested + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*commit_store.CommitStoreOwnershipTransferRequested, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *commit_store.CommitStoreOwnershipTransferRequested); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreOwnershipTransferRequested) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ParseOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferRequested' +type CommitStoreInterface_ParseOwnershipTransferRequested_Call struct { + *mock.Call +} + +// ParseOwnershipTransferRequested is a helper method to define mock.On call +// - log types.Log +func (_e *CommitStoreInterface_Expecter) ParseOwnershipTransferRequested(log interface{}) *CommitStoreInterface_ParseOwnershipTransferRequested_Call { + return &CommitStoreInterface_ParseOwnershipTransferRequested_Call{Call: _e.mock.On("ParseOwnershipTransferRequested", log)} +} + +func (_c *CommitStoreInterface_ParseOwnershipTransferRequested_Call) Run(run func(log types.Log)) *CommitStoreInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *CommitStoreInterface_ParseOwnershipTransferRequested_Call) Return(_a0 *commit_store.CommitStoreOwnershipTransferRequested, _a1 error) *CommitStoreInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ParseOwnershipTransferRequested_Call) RunAndReturn(run func(types.Log) (*commit_store.CommitStoreOwnershipTransferRequested, error)) *CommitStoreInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferred provides a mock function with given fields: log +func (_m *CommitStoreInterface) ParseOwnershipTransferred(log types.Log) (*commit_store.CommitStoreOwnershipTransferred, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferred") + } + + var r0 *commit_store.CommitStoreOwnershipTransferred + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*commit_store.CommitStoreOwnershipTransferred, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *commit_store.CommitStoreOwnershipTransferred); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreOwnershipTransferred) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ParseOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferred' +type CommitStoreInterface_ParseOwnershipTransferred_Call struct { + *mock.Call +} + +// ParseOwnershipTransferred is a helper method to define mock.On call +// - log types.Log +func (_e *CommitStoreInterface_Expecter) ParseOwnershipTransferred(log interface{}) *CommitStoreInterface_ParseOwnershipTransferred_Call { + return &CommitStoreInterface_ParseOwnershipTransferred_Call{Call: _e.mock.On("ParseOwnershipTransferred", log)} +} + +func (_c *CommitStoreInterface_ParseOwnershipTransferred_Call) Run(run func(log types.Log)) *CommitStoreInterface_ParseOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *CommitStoreInterface_ParseOwnershipTransferred_Call) Return(_a0 *commit_store.CommitStoreOwnershipTransferred, _a1 error) *CommitStoreInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ParseOwnershipTransferred_Call) RunAndReturn(run func(types.Log) (*commit_store.CommitStoreOwnershipTransferred, error)) *CommitStoreInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// ParsePaused provides a mock function with given fields: log +func (_m *CommitStoreInterface) ParsePaused(log types.Log) (*commit_store.CommitStorePaused, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParsePaused") + } + + var r0 *commit_store.CommitStorePaused + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*commit_store.CommitStorePaused, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *commit_store.CommitStorePaused); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStorePaused) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ParsePaused_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePaused' +type CommitStoreInterface_ParsePaused_Call struct { + *mock.Call +} + +// ParsePaused is a helper method to define mock.On call +// - log types.Log +func (_e *CommitStoreInterface_Expecter) ParsePaused(log interface{}) *CommitStoreInterface_ParsePaused_Call { + return &CommitStoreInterface_ParsePaused_Call{Call: _e.mock.On("ParsePaused", log)} +} + +func (_c *CommitStoreInterface_ParsePaused_Call) Run(run func(log types.Log)) *CommitStoreInterface_ParsePaused_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *CommitStoreInterface_ParsePaused_Call) Return(_a0 *commit_store.CommitStorePaused, _a1 error) *CommitStoreInterface_ParsePaused_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ParsePaused_Call) RunAndReturn(run func(types.Log) (*commit_store.CommitStorePaused, error)) *CommitStoreInterface_ParsePaused_Call { + _c.Call.Return(run) + return _c +} + +// ParseReportAccepted provides a mock function with given fields: log +func (_m *CommitStoreInterface) ParseReportAccepted(log types.Log) (*commit_store.CommitStoreReportAccepted, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseReportAccepted") + } + + var r0 *commit_store.CommitStoreReportAccepted + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*commit_store.CommitStoreReportAccepted, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *commit_store.CommitStoreReportAccepted); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreReportAccepted) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ParseReportAccepted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseReportAccepted' +type CommitStoreInterface_ParseReportAccepted_Call struct { + *mock.Call +} + +// ParseReportAccepted is a helper method to define mock.On call +// - log types.Log +func (_e *CommitStoreInterface_Expecter) ParseReportAccepted(log interface{}) *CommitStoreInterface_ParseReportAccepted_Call { + return &CommitStoreInterface_ParseReportAccepted_Call{Call: _e.mock.On("ParseReportAccepted", log)} +} + +func (_c *CommitStoreInterface_ParseReportAccepted_Call) Run(run func(log types.Log)) *CommitStoreInterface_ParseReportAccepted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *CommitStoreInterface_ParseReportAccepted_Call) Return(_a0 *commit_store.CommitStoreReportAccepted, _a1 error) *CommitStoreInterface_ParseReportAccepted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ParseReportAccepted_Call) RunAndReturn(run func(types.Log) (*commit_store.CommitStoreReportAccepted, error)) *CommitStoreInterface_ParseReportAccepted_Call { + _c.Call.Return(run) + return _c +} + +// ParseRootRemoved provides a mock function with given fields: log +func (_m *CommitStoreInterface) ParseRootRemoved(log types.Log) (*commit_store.CommitStoreRootRemoved, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseRootRemoved") + } + + var r0 *commit_store.CommitStoreRootRemoved + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*commit_store.CommitStoreRootRemoved, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *commit_store.CommitStoreRootRemoved); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreRootRemoved) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ParseRootRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseRootRemoved' +type CommitStoreInterface_ParseRootRemoved_Call struct { + *mock.Call +} + +// ParseRootRemoved is a helper method to define mock.On call +// - log types.Log +func (_e *CommitStoreInterface_Expecter) ParseRootRemoved(log interface{}) *CommitStoreInterface_ParseRootRemoved_Call { + return &CommitStoreInterface_ParseRootRemoved_Call{Call: _e.mock.On("ParseRootRemoved", log)} +} + +func (_c *CommitStoreInterface_ParseRootRemoved_Call) Run(run func(log types.Log)) *CommitStoreInterface_ParseRootRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *CommitStoreInterface_ParseRootRemoved_Call) Return(_a0 *commit_store.CommitStoreRootRemoved, _a1 error) *CommitStoreInterface_ParseRootRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ParseRootRemoved_Call) RunAndReturn(run func(types.Log) (*commit_store.CommitStoreRootRemoved, error)) *CommitStoreInterface_ParseRootRemoved_Call { + _c.Call.Return(run) + return _c +} + +// ParseSequenceNumberSet provides a mock function with given fields: log +func (_m *CommitStoreInterface) ParseSequenceNumberSet(log types.Log) (*commit_store.CommitStoreSequenceNumberSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseSequenceNumberSet") + } + + var r0 *commit_store.CommitStoreSequenceNumberSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*commit_store.CommitStoreSequenceNumberSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *commit_store.CommitStoreSequenceNumberSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreSequenceNumberSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ParseSequenceNumberSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseSequenceNumberSet' +type CommitStoreInterface_ParseSequenceNumberSet_Call struct { + *mock.Call +} + +// ParseSequenceNumberSet is a helper method to define mock.On call +// - log types.Log +func (_e *CommitStoreInterface_Expecter) ParseSequenceNumberSet(log interface{}) *CommitStoreInterface_ParseSequenceNumberSet_Call { + return &CommitStoreInterface_ParseSequenceNumberSet_Call{Call: _e.mock.On("ParseSequenceNumberSet", log)} +} + +func (_c *CommitStoreInterface_ParseSequenceNumberSet_Call) Run(run func(log types.Log)) *CommitStoreInterface_ParseSequenceNumberSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *CommitStoreInterface_ParseSequenceNumberSet_Call) Return(_a0 *commit_store.CommitStoreSequenceNumberSet, _a1 error) *CommitStoreInterface_ParseSequenceNumberSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ParseSequenceNumberSet_Call) RunAndReturn(run func(types.Log) (*commit_store.CommitStoreSequenceNumberSet, error)) *CommitStoreInterface_ParseSequenceNumberSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseTransmitted provides a mock function with given fields: log +func (_m *CommitStoreInterface) ParseTransmitted(log types.Log) (*commit_store.CommitStoreTransmitted, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTransmitted") + } + + var r0 *commit_store.CommitStoreTransmitted + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*commit_store.CommitStoreTransmitted, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *commit_store.CommitStoreTransmitted); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreTransmitted) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ParseTransmitted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTransmitted' +type CommitStoreInterface_ParseTransmitted_Call struct { + *mock.Call +} + +// ParseTransmitted is a helper method to define mock.On call +// - log types.Log +func (_e *CommitStoreInterface_Expecter) ParseTransmitted(log interface{}) *CommitStoreInterface_ParseTransmitted_Call { + return &CommitStoreInterface_ParseTransmitted_Call{Call: _e.mock.On("ParseTransmitted", log)} +} + +func (_c *CommitStoreInterface_ParseTransmitted_Call) Run(run func(log types.Log)) *CommitStoreInterface_ParseTransmitted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *CommitStoreInterface_ParseTransmitted_Call) Return(_a0 *commit_store.CommitStoreTransmitted, _a1 error) *CommitStoreInterface_ParseTransmitted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ParseTransmitted_Call) RunAndReturn(run func(types.Log) (*commit_store.CommitStoreTransmitted, error)) *CommitStoreInterface_ParseTransmitted_Call { + _c.Call.Return(run) + return _c +} + +// ParseUnpaused provides a mock function with given fields: log +func (_m *CommitStoreInterface) ParseUnpaused(log types.Log) (*commit_store.CommitStoreUnpaused, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseUnpaused") + } + + var r0 *commit_store.CommitStoreUnpaused + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*commit_store.CommitStoreUnpaused, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *commit_store.CommitStoreUnpaused); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commit_store.CommitStoreUnpaused) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ParseUnpaused_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseUnpaused' +type CommitStoreInterface_ParseUnpaused_Call struct { + *mock.Call +} + +// ParseUnpaused is a helper method to define mock.On call +// - log types.Log +func (_e *CommitStoreInterface_Expecter) ParseUnpaused(log interface{}) *CommitStoreInterface_ParseUnpaused_Call { + return &CommitStoreInterface_ParseUnpaused_Call{Call: _e.mock.On("ParseUnpaused", log)} +} + +func (_c *CommitStoreInterface_ParseUnpaused_Call) Run(run func(log types.Log)) *CommitStoreInterface_ParseUnpaused_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *CommitStoreInterface_ParseUnpaused_Call) Return(_a0 *commit_store.CommitStoreUnpaused, _a1 error) *CommitStoreInterface_ParseUnpaused_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ParseUnpaused_Call) RunAndReturn(run func(types.Log) (*commit_store.CommitStoreUnpaused, error)) *CommitStoreInterface_ParseUnpaused_Call { + _c.Call.Return(run) + return _c +} + +// Pause provides a mock function with given fields: opts +func (_m *CommitStoreInterface) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Pause") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_Pause_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Pause' +type CommitStoreInterface_Pause_Call struct { + *mock.Call +} + +// Pause is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *CommitStoreInterface_Expecter) Pause(opts interface{}) *CommitStoreInterface_Pause_Call { + return &CommitStoreInterface_Pause_Call{Call: _e.mock.On("Pause", opts)} +} + +func (_c *CommitStoreInterface_Pause_Call) Run(run func(opts *bind.TransactOpts)) *CommitStoreInterface_Pause_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_Pause_Call) Return(_a0 *types.Transaction, _a1 error) *CommitStoreInterface_Pause_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_Pause_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *CommitStoreInterface_Pause_Call { + _c.Call.Return(run) + return _c +} + +// Paused provides a mock function with given fields: opts +func (_m *CommitStoreInterface) Paused(opts *bind.CallOpts) (bool, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Paused") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (bool, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) bool); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_Paused_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Paused' +type CommitStoreInterface_Paused_Call struct { + *mock.Call +} + +// Paused is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *CommitStoreInterface_Expecter) Paused(opts interface{}) *CommitStoreInterface_Paused_Call { + return &CommitStoreInterface_Paused_Call{Call: _e.mock.On("Paused", opts)} +} + +func (_c *CommitStoreInterface_Paused_Call) Run(run func(opts *bind.CallOpts)) *CommitStoreInterface_Paused_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_Paused_Call) Return(_a0 bool, _a1 error) *CommitStoreInterface_Paused_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_Paused_Call) RunAndReturn(run func(*bind.CallOpts) (bool, error)) *CommitStoreInterface_Paused_Call { + _c.Call.Return(run) + return _c +} + +// ResetUnblessedRoots provides a mock function with given fields: opts, rootToReset +func (_m *CommitStoreInterface) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) { + ret := _m.Called(opts, rootToReset) + + if len(ret) == 0 { + panic("no return value specified for ResetUnblessedRoots") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, [][32]byte) (*types.Transaction, error)); ok { + return rf(opts, rootToReset) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, [][32]byte) *types.Transaction); ok { + r0 = rf(opts, rootToReset) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, [][32]byte) error); ok { + r1 = rf(opts, rootToReset) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_ResetUnblessedRoots_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ResetUnblessedRoots' +type CommitStoreInterface_ResetUnblessedRoots_Call struct { + *mock.Call +} + +// ResetUnblessedRoots is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - rootToReset [][32]byte +func (_e *CommitStoreInterface_Expecter) ResetUnblessedRoots(opts interface{}, rootToReset interface{}) *CommitStoreInterface_ResetUnblessedRoots_Call { + return &CommitStoreInterface_ResetUnblessedRoots_Call{Call: _e.mock.On("ResetUnblessedRoots", opts, rootToReset)} +} + +func (_c *CommitStoreInterface_ResetUnblessedRoots_Call) Run(run func(opts *bind.TransactOpts, rootToReset [][32]byte)) *CommitStoreInterface_ResetUnblessedRoots_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([][32]byte)) + }) + return _c +} + +func (_c *CommitStoreInterface_ResetUnblessedRoots_Call) Return(_a0 *types.Transaction, _a1 error) *CommitStoreInterface_ResetUnblessedRoots_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_ResetUnblessedRoots_Call) RunAndReturn(run func(*bind.TransactOpts, [][32]byte) (*types.Transaction, error)) *CommitStoreInterface_ResetUnblessedRoots_Call { + _c.Call.Return(run) + return _c +} + +// SetLatestPriceEpochAndRound provides a mock function with given fields: opts, latestPriceEpochAndRound +func (_m *CommitStoreInterface) SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + ret := _m.Called(opts, latestPriceEpochAndRound) + + if len(ret) == 0 { + panic("no return value specified for SetLatestPriceEpochAndRound") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, *big.Int) (*types.Transaction, error)); ok { + return rf(opts, latestPriceEpochAndRound) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, *big.Int) *types.Transaction); ok { + r0 = rf(opts, latestPriceEpochAndRound) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, *big.Int) error); ok { + r1 = rf(opts, latestPriceEpochAndRound) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_SetLatestPriceEpochAndRound_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetLatestPriceEpochAndRound' +type CommitStoreInterface_SetLatestPriceEpochAndRound_Call struct { + *mock.Call +} + +// SetLatestPriceEpochAndRound is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - latestPriceEpochAndRound *big.Int +func (_e *CommitStoreInterface_Expecter) SetLatestPriceEpochAndRound(opts interface{}, latestPriceEpochAndRound interface{}) *CommitStoreInterface_SetLatestPriceEpochAndRound_Call { + return &CommitStoreInterface_SetLatestPriceEpochAndRound_Call{Call: _e.mock.On("SetLatestPriceEpochAndRound", opts, latestPriceEpochAndRound)} +} + +func (_c *CommitStoreInterface_SetLatestPriceEpochAndRound_Call) Run(run func(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int)) *CommitStoreInterface_SetLatestPriceEpochAndRound_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(*big.Int)) + }) + return _c +} + +func (_c *CommitStoreInterface_SetLatestPriceEpochAndRound_Call) Return(_a0 *types.Transaction, _a1 error) *CommitStoreInterface_SetLatestPriceEpochAndRound_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_SetLatestPriceEpochAndRound_Call) RunAndReturn(run func(*bind.TransactOpts, *big.Int) (*types.Transaction, error)) *CommitStoreInterface_SetLatestPriceEpochAndRound_Call { + _c.Call.Return(run) + return _c +} + +// SetMinSeqNr provides a mock function with given fields: opts, minSeqNr +func (_m *CommitStoreInterface) SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) { + ret := _m.Called(opts, minSeqNr) + + if len(ret) == 0 { + panic("no return value specified for SetMinSeqNr") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, uint64) (*types.Transaction, error)); ok { + return rf(opts, minSeqNr) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, uint64) *types.Transaction); ok { + r0 = rf(opts, minSeqNr) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, uint64) error); ok { + r1 = rf(opts, minSeqNr) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_SetMinSeqNr_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMinSeqNr' +type CommitStoreInterface_SetMinSeqNr_Call struct { + *mock.Call +} + +// SetMinSeqNr is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - minSeqNr uint64 +func (_e *CommitStoreInterface_Expecter) SetMinSeqNr(opts interface{}, minSeqNr interface{}) *CommitStoreInterface_SetMinSeqNr_Call { + return &CommitStoreInterface_SetMinSeqNr_Call{Call: _e.mock.On("SetMinSeqNr", opts, minSeqNr)} +} + +func (_c *CommitStoreInterface_SetMinSeqNr_Call) Run(run func(opts *bind.TransactOpts, minSeqNr uint64)) *CommitStoreInterface_SetMinSeqNr_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *CommitStoreInterface_SetMinSeqNr_Call) Return(_a0 *types.Transaction, _a1 error) *CommitStoreInterface_SetMinSeqNr_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_SetMinSeqNr_Call) RunAndReturn(run func(*bind.TransactOpts, uint64) (*types.Transaction, error)) *CommitStoreInterface_SetMinSeqNr_Call { + _c.Call.Return(run) + return _c +} + +// SetOCR2Config provides a mock function with given fields: opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig +func (_m *CommitStoreInterface) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + ret := _m.Called(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + + if len(ret) == 0 { + panic("no return value specified for SetOCR2Config") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) (*types.Transaction, error)); ok { + return rf(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) *types.Transaction); ok { + r0 = rf(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) error); ok { + r1 = rf(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_SetOCR2Config_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetOCR2Config' +type CommitStoreInterface_SetOCR2Config_Call struct { + *mock.Call +} + +// SetOCR2Config is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - signers []common.Address +// - transmitters []common.Address +// - f uint8 +// - onchainConfig []byte +// - offchainConfigVersion uint64 +// - offchainConfig []byte +func (_e *CommitStoreInterface_Expecter) SetOCR2Config(opts interface{}, signers interface{}, transmitters interface{}, f interface{}, onchainConfig interface{}, offchainConfigVersion interface{}, offchainConfig interface{}) *CommitStoreInterface_SetOCR2Config_Call { + return &CommitStoreInterface_SetOCR2Config_Call{Call: _e.mock.On("SetOCR2Config", opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig)} +} + +func (_c *CommitStoreInterface_SetOCR2Config_Call) Run(run func(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte)) *CommitStoreInterface_SetOCR2Config_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]common.Address), args[2].([]common.Address), args[3].(uint8), args[4].([]byte), args[5].(uint64), args[6].([]byte)) + }) + return _c +} + +func (_c *CommitStoreInterface_SetOCR2Config_Call) Return(_a0 *types.Transaction, _a1 error) *CommitStoreInterface_SetOCR2Config_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_SetOCR2Config_Call) RunAndReturn(run func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) (*types.Transaction, error)) *CommitStoreInterface_SetOCR2Config_Call { + _c.Call.Return(run) + return _c +} + +// TransferOwnership provides a mock function with given fields: opts, to +func (_m *CommitStoreInterface) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, to) + + if len(ret) == 0 { + panic("no return value specified for TransferOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, to) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_TransferOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TransferOwnership' +type CommitStoreInterface_TransferOwnership_Call struct { + *mock.Call +} + +// TransferOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - to common.Address +func (_e *CommitStoreInterface_Expecter) TransferOwnership(opts interface{}, to interface{}) *CommitStoreInterface_TransferOwnership_Call { + return &CommitStoreInterface_TransferOwnership_Call{Call: _e.mock.On("TransferOwnership", opts, to)} +} + +func (_c *CommitStoreInterface_TransferOwnership_Call) Run(run func(opts *bind.TransactOpts, to common.Address)) *CommitStoreInterface_TransferOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *CommitStoreInterface_TransferOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *CommitStoreInterface_TransferOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_TransferOwnership_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *CommitStoreInterface_TransferOwnership_Call { + _c.Call.Return(run) + return _c +} + +// Transmit provides a mock function with given fields: opts, reportContext, report, rs, ss, rawVs +func (_m *CommitStoreInterface) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + ret := _m.Called(opts, reportContext, report, rs, ss, rawVs) + + if len(ret) == 0 { + panic("no return value specified for Transmit") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) (*types.Transaction, error)); ok { + return rf(opts, reportContext, report, rs, ss, rawVs) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) *types.Transaction); ok { + r0 = rf(opts, reportContext, report, rs, ss, rawVs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) error); ok { + r1 = rf(opts, reportContext, report, rs, ss, rawVs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_Transmit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Transmit' +type CommitStoreInterface_Transmit_Call struct { + *mock.Call +} + +// Transmit is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - reportContext [3][32]byte +// - report []byte +// - rs [][32]byte +// - ss [][32]byte +// - rawVs [32]byte +func (_e *CommitStoreInterface_Expecter) Transmit(opts interface{}, reportContext interface{}, report interface{}, rs interface{}, ss interface{}, rawVs interface{}) *CommitStoreInterface_Transmit_Call { + return &CommitStoreInterface_Transmit_Call{Call: _e.mock.On("Transmit", opts, reportContext, report, rs, ss, rawVs)} +} + +func (_c *CommitStoreInterface_Transmit_Call) Run(run func(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte)) *CommitStoreInterface_Transmit_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([3][32]byte), args[2].([]byte), args[3].([][32]byte), args[4].([][32]byte), args[5].([32]byte)) + }) + return _c +} + +func (_c *CommitStoreInterface_Transmit_Call) Return(_a0 *types.Transaction, _a1 error) *CommitStoreInterface_Transmit_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_Transmit_Call) RunAndReturn(run func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) (*types.Transaction, error)) *CommitStoreInterface_Transmit_Call { + _c.Call.Return(run) + return _c +} + +// TypeAndVersion provides a mock function with given fields: opts +func (_m *CommitStoreInterface) TypeAndVersion(opts *bind.CallOpts) (string, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for TypeAndVersion") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (string, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) string); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_TypeAndVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TypeAndVersion' +type CommitStoreInterface_TypeAndVersion_Call struct { + *mock.Call +} + +// TypeAndVersion is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *CommitStoreInterface_Expecter) TypeAndVersion(opts interface{}) *CommitStoreInterface_TypeAndVersion_Call { + return &CommitStoreInterface_TypeAndVersion_Call{Call: _e.mock.On("TypeAndVersion", opts)} +} + +func (_c *CommitStoreInterface_TypeAndVersion_Call) Run(run func(opts *bind.CallOpts)) *CommitStoreInterface_TypeAndVersion_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_TypeAndVersion_Call) Return(_a0 string, _a1 error) *CommitStoreInterface_TypeAndVersion_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_TypeAndVersion_Call) RunAndReturn(run func(*bind.CallOpts) (string, error)) *CommitStoreInterface_TypeAndVersion_Call { + _c.Call.Return(run) + return _c +} + +// Unpause provides a mock function with given fields: opts +func (_m *CommitStoreInterface) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Unpause") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_Unpause_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Unpause' +type CommitStoreInterface_Unpause_Call struct { + *mock.Call +} + +// Unpause is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *CommitStoreInterface_Expecter) Unpause(opts interface{}) *CommitStoreInterface_Unpause_Call { + return &CommitStoreInterface_Unpause_Call{Call: _e.mock.On("Unpause", opts)} +} + +func (_c *CommitStoreInterface_Unpause_Call) Run(run func(opts *bind.TransactOpts)) *CommitStoreInterface_Unpause_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *CommitStoreInterface_Unpause_Call) Return(_a0 *types.Transaction, _a1 error) *CommitStoreInterface_Unpause_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_Unpause_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *CommitStoreInterface_Unpause_Call { + _c.Call.Return(run) + return _c +} + +// Verify provides a mock function with given fields: opts, hashedLeaves, proofs, proofFlagBits +func (_m *CommitStoreInterface) Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + ret := _m.Called(opts, hashedLeaves, proofs, proofFlagBits) + + if len(ret) == 0 { + panic("no return value specified for Verify") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, [][32]byte, [][32]byte, *big.Int) (*big.Int, error)); ok { + return rf(opts, hashedLeaves, proofs, proofFlagBits) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, [][32]byte, [][32]byte, *big.Int) *big.Int); ok { + r0 = rf(opts, hashedLeaves, proofs, proofFlagBits) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, [][32]byte, [][32]byte, *big.Int) error); ok { + r1 = rf(opts, hashedLeaves, proofs, proofFlagBits) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_Verify_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Verify' +type CommitStoreInterface_Verify_Call struct { + *mock.Call +} + +// Verify is a helper method to define mock.On call +// - opts *bind.CallOpts +// - hashedLeaves [][32]byte +// - proofs [][32]byte +// - proofFlagBits *big.Int +func (_e *CommitStoreInterface_Expecter) Verify(opts interface{}, hashedLeaves interface{}, proofs interface{}, proofFlagBits interface{}) *CommitStoreInterface_Verify_Call { + return &CommitStoreInterface_Verify_Call{Call: _e.mock.On("Verify", opts, hashedLeaves, proofs, proofFlagBits)} +} + +func (_c *CommitStoreInterface_Verify_Call) Run(run func(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int)) *CommitStoreInterface_Verify_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].([][32]byte), args[2].([][32]byte), args[3].(*big.Int)) + }) + return _c +} + +func (_c *CommitStoreInterface_Verify_Call) Return(_a0 *big.Int, _a1 error) *CommitStoreInterface_Verify_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_Verify_Call) RunAndReturn(run func(*bind.CallOpts, [][32]byte, [][32]byte, *big.Int) (*big.Int, error)) *CommitStoreInterface_Verify_Call { + _c.Call.Return(run) + return _c +} + +// WatchConfigSet provides a mock function with given fields: opts, sink +func (_m *CommitStoreInterface) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreConfigSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchConfigSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreConfigSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreConfigSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreConfigSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_WatchConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchConfigSet' +type CommitStoreInterface_WatchConfigSet_Call struct { + *mock.Call +} + +// WatchConfigSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *commit_store.CommitStoreConfigSet +func (_e *CommitStoreInterface_Expecter) WatchConfigSet(opts interface{}, sink interface{}) *CommitStoreInterface_WatchConfigSet_Call { + return &CommitStoreInterface_WatchConfigSet_Call{Call: _e.mock.On("WatchConfigSet", opts, sink)} +} + +func (_c *CommitStoreInterface_WatchConfigSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreConfigSet)) *CommitStoreInterface_WatchConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *commit_store.CommitStoreConfigSet)) + }) + return _c +} + +func (_c *CommitStoreInterface_WatchConfigSet_Call) Return(_a0 event.Subscription, _a1 error) *CommitStoreInterface_WatchConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_WatchConfigSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *commit_store.CommitStoreConfigSet) (event.Subscription, error)) *CommitStoreInterface_WatchConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchConfigSet0 provides a mock function with given fields: opts, sink +func (_m *CommitStoreInterface) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreConfigSet0) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchConfigSet0") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreConfigSet0) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreConfigSet0) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreConfigSet0) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_WatchConfigSet0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchConfigSet0' +type CommitStoreInterface_WatchConfigSet0_Call struct { + *mock.Call +} + +// WatchConfigSet0 is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *commit_store.CommitStoreConfigSet0 +func (_e *CommitStoreInterface_Expecter) WatchConfigSet0(opts interface{}, sink interface{}) *CommitStoreInterface_WatchConfigSet0_Call { + return &CommitStoreInterface_WatchConfigSet0_Call{Call: _e.mock.On("WatchConfigSet0", opts, sink)} +} + +func (_c *CommitStoreInterface_WatchConfigSet0_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreConfigSet0)) *CommitStoreInterface_WatchConfigSet0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *commit_store.CommitStoreConfigSet0)) + }) + return _c +} + +func (_c *CommitStoreInterface_WatchConfigSet0_Call) Return(_a0 event.Subscription, _a1 error) *CommitStoreInterface_WatchConfigSet0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_WatchConfigSet0_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *commit_store.CommitStoreConfigSet0) (event.Subscription, error)) *CommitStoreInterface_WatchConfigSet0_Call { + _c.Call.Return(run) + return _c +} + +// WatchLatestPriceEpochAndRoundSet provides a mock function with given fields: opts, sink +func (_m *CommitStoreInterface) WatchLatestPriceEpochAndRoundSet(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreLatestPriceEpochAndRoundSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchLatestPriceEpochAndRoundSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreLatestPriceEpochAndRoundSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreLatestPriceEpochAndRoundSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreLatestPriceEpochAndRoundSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_WatchLatestPriceEpochAndRoundSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchLatestPriceEpochAndRoundSet' +type CommitStoreInterface_WatchLatestPriceEpochAndRoundSet_Call struct { + *mock.Call +} + +// WatchLatestPriceEpochAndRoundSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *commit_store.CommitStoreLatestPriceEpochAndRoundSet +func (_e *CommitStoreInterface_Expecter) WatchLatestPriceEpochAndRoundSet(opts interface{}, sink interface{}) *CommitStoreInterface_WatchLatestPriceEpochAndRoundSet_Call { + return &CommitStoreInterface_WatchLatestPriceEpochAndRoundSet_Call{Call: _e.mock.On("WatchLatestPriceEpochAndRoundSet", opts, sink)} +} + +func (_c *CommitStoreInterface_WatchLatestPriceEpochAndRoundSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreLatestPriceEpochAndRoundSet)) *CommitStoreInterface_WatchLatestPriceEpochAndRoundSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *commit_store.CommitStoreLatestPriceEpochAndRoundSet)) + }) + return _c +} + +func (_c *CommitStoreInterface_WatchLatestPriceEpochAndRoundSet_Call) Return(_a0 event.Subscription, _a1 error) *CommitStoreInterface_WatchLatestPriceEpochAndRoundSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_WatchLatestPriceEpochAndRoundSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *commit_store.CommitStoreLatestPriceEpochAndRoundSet) (event.Subscription, error)) *CommitStoreInterface_WatchLatestPriceEpochAndRoundSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferRequested provides a mock function with given fields: opts, sink, from, to +func (_m *CommitStoreInterface) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferRequested") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreOwnershipTransferRequested, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreOwnershipTransferRequested, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_WatchOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferRequested' +type CommitStoreInterface_WatchOwnershipTransferRequested_Call struct { + *mock.Call +} + +// WatchOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *commit_store.CommitStoreOwnershipTransferRequested +// - from []common.Address +// - to []common.Address +func (_e *CommitStoreInterface_Expecter) WatchOwnershipTransferRequested(opts interface{}, sink interface{}, from interface{}, to interface{}) *CommitStoreInterface_WatchOwnershipTransferRequested_Call { + return &CommitStoreInterface_WatchOwnershipTransferRequested_Call{Call: _e.mock.On("WatchOwnershipTransferRequested", opts, sink, from, to)} +} + +func (_c *CommitStoreInterface_WatchOwnershipTransferRequested_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreOwnershipTransferRequested, from []common.Address, to []common.Address)) *CommitStoreInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *commit_store.CommitStoreOwnershipTransferRequested), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *CommitStoreInterface_WatchOwnershipTransferRequested_Call) Return(_a0 event.Subscription, _a1 error) *CommitStoreInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_WatchOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *commit_store.CommitStoreOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)) *CommitStoreInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferred provides a mock function with given fields: opts, sink, from, to +func (_m *CommitStoreInterface) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferred") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreOwnershipTransferred, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreOwnershipTransferred, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_WatchOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferred' +type CommitStoreInterface_WatchOwnershipTransferred_Call struct { + *mock.Call +} + +// WatchOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *commit_store.CommitStoreOwnershipTransferred +// - from []common.Address +// - to []common.Address +func (_e *CommitStoreInterface_Expecter) WatchOwnershipTransferred(opts interface{}, sink interface{}, from interface{}, to interface{}) *CommitStoreInterface_WatchOwnershipTransferred_Call { + return &CommitStoreInterface_WatchOwnershipTransferred_Call{Call: _e.mock.On("WatchOwnershipTransferred", opts, sink, from, to)} +} + +func (_c *CommitStoreInterface_WatchOwnershipTransferred_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreOwnershipTransferred, from []common.Address, to []common.Address)) *CommitStoreInterface_WatchOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *commit_store.CommitStoreOwnershipTransferred), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *CommitStoreInterface_WatchOwnershipTransferred_Call) Return(_a0 event.Subscription, _a1 error) *CommitStoreInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_WatchOwnershipTransferred_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *commit_store.CommitStoreOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)) *CommitStoreInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// WatchPaused provides a mock function with given fields: opts, sink +func (_m *CommitStoreInterface) WatchPaused(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStorePaused) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchPaused") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStorePaused) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStorePaused) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *commit_store.CommitStorePaused) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_WatchPaused_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPaused' +type CommitStoreInterface_WatchPaused_Call struct { + *mock.Call +} + +// WatchPaused is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *commit_store.CommitStorePaused +func (_e *CommitStoreInterface_Expecter) WatchPaused(opts interface{}, sink interface{}) *CommitStoreInterface_WatchPaused_Call { + return &CommitStoreInterface_WatchPaused_Call{Call: _e.mock.On("WatchPaused", opts, sink)} +} + +func (_c *CommitStoreInterface_WatchPaused_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStorePaused)) *CommitStoreInterface_WatchPaused_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *commit_store.CommitStorePaused)) + }) + return _c +} + +func (_c *CommitStoreInterface_WatchPaused_Call) Return(_a0 event.Subscription, _a1 error) *CommitStoreInterface_WatchPaused_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_WatchPaused_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *commit_store.CommitStorePaused) (event.Subscription, error)) *CommitStoreInterface_WatchPaused_Call { + _c.Call.Return(run) + return _c +} + +// WatchReportAccepted provides a mock function with given fields: opts, sink +func (_m *CommitStoreInterface) WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreReportAccepted) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchReportAccepted") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreReportAccepted) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreReportAccepted) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreReportAccepted) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_WatchReportAccepted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchReportAccepted' +type CommitStoreInterface_WatchReportAccepted_Call struct { + *mock.Call +} + +// WatchReportAccepted is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *commit_store.CommitStoreReportAccepted +func (_e *CommitStoreInterface_Expecter) WatchReportAccepted(opts interface{}, sink interface{}) *CommitStoreInterface_WatchReportAccepted_Call { + return &CommitStoreInterface_WatchReportAccepted_Call{Call: _e.mock.On("WatchReportAccepted", opts, sink)} +} + +func (_c *CommitStoreInterface_WatchReportAccepted_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreReportAccepted)) *CommitStoreInterface_WatchReportAccepted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *commit_store.CommitStoreReportAccepted)) + }) + return _c +} + +func (_c *CommitStoreInterface_WatchReportAccepted_Call) Return(_a0 event.Subscription, _a1 error) *CommitStoreInterface_WatchReportAccepted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_WatchReportAccepted_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *commit_store.CommitStoreReportAccepted) (event.Subscription, error)) *CommitStoreInterface_WatchReportAccepted_Call { + _c.Call.Return(run) + return _c +} + +// WatchRootRemoved provides a mock function with given fields: opts, sink +func (_m *CommitStoreInterface) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreRootRemoved) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchRootRemoved") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreRootRemoved) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreRootRemoved) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreRootRemoved) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_WatchRootRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchRootRemoved' +type CommitStoreInterface_WatchRootRemoved_Call struct { + *mock.Call +} + +// WatchRootRemoved is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *commit_store.CommitStoreRootRemoved +func (_e *CommitStoreInterface_Expecter) WatchRootRemoved(opts interface{}, sink interface{}) *CommitStoreInterface_WatchRootRemoved_Call { + return &CommitStoreInterface_WatchRootRemoved_Call{Call: _e.mock.On("WatchRootRemoved", opts, sink)} +} + +func (_c *CommitStoreInterface_WatchRootRemoved_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreRootRemoved)) *CommitStoreInterface_WatchRootRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *commit_store.CommitStoreRootRemoved)) + }) + return _c +} + +func (_c *CommitStoreInterface_WatchRootRemoved_Call) Return(_a0 event.Subscription, _a1 error) *CommitStoreInterface_WatchRootRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_WatchRootRemoved_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *commit_store.CommitStoreRootRemoved) (event.Subscription, error)) *CommitStoreInterface_WatchRootRemoved_Call { + _c.Call.Return(run) + return _c +} + +// WatchSequenceNumberSet provides a mock function with given fields: opts, sink +func (_m *CommitStoreInterface) WatchSequenceNumberSet(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreSequenceNumberSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchSequenceNumberSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreSequenceNumberSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreSequenceNumberSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreSequenceNumberSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_WatchSequenceNumberSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchSequenceNumberSet' +type CommitStoreInterface_WatchSequenceNumberSet_Call struct { + *mock.Call +} + +// WatchSequenceNumberSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *commit_store.CommitStoreSequenceNumberSet +func (_e *CommitStoreInterface_Expecter) WatchSequenceNumberSet(opts interface{}, sink interface{}) *CommitStoreInterface_WatchSequenceNumberSet_Call { + return &CommitStoreInterface_WatchSequenceNumberSet_Call{Call: _e.mock.On("WatchSequenceNumberSet", opts, sink)} +} + +func (_c *CommitStoreInterface_WatchSequenceNumberSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreSequenceNumberSet)) *CommitStoreInterface_WatchSequenceNumberSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *commit_store.CommitStoreSequenceNumberSet)) + }) + return _c +} + +func (_c *CommitStoreInterface_WatchSequenceNumberSet_Call) Return(_a0 event.Subscription, _a1 error) *CommitStoreInterface_WatchSequenceNumberSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_WatchSequenceNumberSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *commit_store.CommitStoreSequenceNumberSet) (event.Subscription, error)) *CommitStoreInterface_WatchSequenceNumberSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchTransmitted provides a mock function with given fields: opts, sink +func (_m *CommitStoreInterface) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreTransmitted) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchTransmitted") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreTransmitted) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreTransmitted) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreTransmitted) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_WatchTransmitted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTransmitted' +type CommitStoreInterface_WatchTransmitted_Call struct { + *mock.Call +} + +// WatchTransmitted is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *commit_store.CommitStoreTransmitted +func (_e *CommitStoreInterface_Expecter) WatchTransmitted(opts interface{}, sink interface{}) *CommitStoreInterface_WatchTransmitted_Call { + return &CommitStoreInterface_WatchTransmitted_Call{Call: _e.mock.On("WatchTransmitted", opts, sink)} +} + +func (_c *CommitStoreInterface_WatchTransmitted_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreTransmitted)) *CommitStoreInterface_WatchTransmitted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *commit_store.CommitStoreTransmitted)) + }) + return _c +} + +func (_c *CommitStoreInterface_WatchTransmitted_Call) Return(_a0 event.Subscription, _a1 error) *CommitStoreInterface_WatchTransmitted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_WatchTransmitted_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *commit_store.CommitStoreTransmitted) (event.Subscription, error)) *CommitStoreInterface_WatchTransmitted_Call { + _c.Call.Return(run) + return _c +} + +// WatchUnpaused provides a mock function with given fields: opts, sink +func (_m *CommitStoreInterface) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreUnpaused) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchUnpaused") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreUnpaused) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreUnpaused) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *commit_store.CommitStoreUnpaused) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreInterface_WatchUnpaused_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchUnpaused' +type CommitStoreInterface_WatchUnpaused_Call struct { + *mock.Call +} + +// WatchUnpaused is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *commit_store.CommitStoreUnpaused +func (_e *CommitStoreInterface_Expecter) WatchUnpaused(opts interface{}, sink interface{}) *CommitStoreInterface_WatchUnpaused_Call { + return &CommitStoreInterface_WatchUnpaused_Call{Call: _e.mock.On("WatchUnpaused", opts, sink)} +} + +func (_c *CommitStoreInterface_WatchUnpaused_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *commit_store.CommitStoreUnpaused)) *CommitStoreInterface_WatchUnpaused_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *commit_store.CommitStoreUnpaused)) + }) + return _c +} + +func (_c *CommitStoreInterface_WatchUnpaused_Call) Return(_a0 event.Subscription, _a1 error) *CommitStoreInterface_WatchUnpaused_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreInterface_WatchUnpaused_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *commit_store.CommitStoreUnpaused) (event.Subscription, error)) *CommitStoreInterface_WatchUnpaused_Call { + _c.Call.Return(run) + return _c +} + +// NewCommitStoreInterface creates a new instance of CommitStoreInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewCommitStoreInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *CommitStoreInterface { + mock := &CommitStoreInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/ccip/mocks/evm2_evm_off_ramp_interface.go b/core/gethwrappers/ccip/mocks/evm2_evm_off_ramp_interface.go new file mode 100644 index 0000000000..6da66583e6 --- /dev/null +++ b/core/gethwrappers/ccip/mocks/evm2_evm_off_ramp_interface.go @@ -0,0 +1,3893 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_contracts + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + evm_2_evm_offramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// EVM2EVMOffRampInterface is an autogenerated mock type for the EVM2EVMOffRampInterface type +type EVM2EVMOffRampInterface struct { + mock.Mock +} + +type EVM2EVMOffRampInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *EVM2EVMOffRampInterface) EXPECT() *EVM2EVMOffRampInterface_Expecter { + return &EVM2EVMOffRampInterface_Expecter{mock: &_m.Mock} +} + +// AcceptOwnership provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for AcceptOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_AcceptOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AcceptOwnership' +type EVM2EVMOffRampInterface_AcceptOwnership_Call struct { + *mock.Call +} + +// AcceptOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *EVM2EVMOffRampInterface_Expecter) AcceptOwnership(opts interface{}) *EVM2EVMOffRampInterface_AcceptOwnership_Call { + return &EVM2EVMOffRampInterface_AcceptOwnership_Call{Call: _e.mock.On("AcceptOwnership", opts)} +} + +func (_c *EVM2EVMOffRampInterface_AcceptOwnership_Call) Run(run func(opts *bind.TransactOpts)) *EVM2EVMOffRampInterface_AcceptOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_AcceptOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_AcceptOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_AcceptOwnership_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *EVM2EVMOffRampInterface_AcceptOwnership_Call { + _c.Call.Return(run) + return _c +} + +// Address provides a mock function with given fields: +func (_m *EVM2EVMOffRampInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// EVM2EVMOffRampInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type EVM2EVMOffRampInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *EVM2EVMOffRampInterface_Expecter) Address() *EVM2EVMOffRampInterface_Address_Call { + return &EVM2EVMOffRampInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *EVM2EVMOffRampInterface_Address_Call) Run(run func()) *EVM2EVMOffRampInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Address_Call) Return(_a0 common.Address) *EVM2EVMOffRampInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Address_Call) RunAndReturn(run func() common.Address) *EVM2EVMOffRampInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// CcipReceive provides a mock function with given fields: opts, arg0 +func (_m *EVM2EVMOffRampInterface) CcipReceive(opts *bind.CallOpts, arg0 evm_2_evm_offramp.ClientAny2EVMMessage) error { + ret := _m.Called(opts, arg0) + + if len(ret) == 0 { + panic("no return value specified for CcipReceive") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, evm_2_evm_offramp.ClientAny2EVMMessage) error); ok { + r0 = rf(opts, arg0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// EVM2EVMOffRampInterface_CcipReceive_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CcipReceive' +type EVM2EVMOffRampInterface_CcipReceive_Call struct { + *mock.Call +} + +// CcipReceive is a helper method to define mock.On call +// - opts *bind.CallOpts +// - arg0 evm_2_evm_offramp.ClientAny2EVMMessage +func (_e *EVM2EVMOffRampInterface_Expecter) CcipReceive(opts interface{}, arg0 interface{}) *EVM2EVMOffRampInterface_CcipReceive_Call { + return &EVM2EVMOffRampInterface_CcipReceive_Call{Call: _e.mock.On("CcipReceive", opts, arg0)} +} + +func (_c *EVM2EVMOffRampInterface_CcipReceive_Call) Run(run func(opts *bind.CallOpts, arg0 evm_2_evm_offramp.ClientAny2EVMMessage)) *EVM2EVMOffRampInterface_CcipReceive_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(evm_2_evm_offramp.ClientAny2EVMMessage)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_CcipReceive_Call) Return(_a0 error) *EVM2EVMOffRampInterface_CcipReceive_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *EVM2EVMOffRampInterface_CcipReceive_Call) RunAndReturn(run func(*bind.CallOpts, evm_2_evm_offramp.ClientAny2EVMMessage) error) *EVM2EVMOffRampInterface_CcipReceive_Call { + _c.Call.Return(run) + return _c +} + +// CurrentRateLimiterState provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) CurrentRateLimiterState(opts *bind.CallOpts) (evm_2_evm_offramp.RateLimiterTokenBucket, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for CurrentRateLimiterState") + } + + var r0 evm_2_evm_offramp.RateLimiterTokenBucket + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp.RateLimiterTokenBucket, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp.RateLimiterTokenBucket); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp.RateLimiterTokenBucket) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_CurrentRateLimiterState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CurrentRateLimiterState' +type EVM2EVMOffRampInterface_CurrentRateLimiterState_Call struct { + *mock.Call +} + +// CurrentRateLimiterState is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) CurrentRateLimiterState(opts interface{}) *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call { + return &EVM2EVMOffRampInterface_CurrentRateLimiterState_Call{Call: _e.mock.On("CurrentRateLimiterState", opts)} +} + +func (_c *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call) Return(_a0 evm_2_evm_offramp.RateLimiterTokenBucket, _a1 error) *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp.RateLimiterTokenBucket, error)) *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call { + _c.Call.Return(run) + return _c +} + +// ExecuteSingleMessage provides a mock function with given fields: opts, message, offchainTokenData +func (_m *EVM2EVMOffRampInterface) ExecuteSingleMessage(opts *bind.TransactOpts, message evm_2_evm_offramp.InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + ret := _m.Called(opts, message, offchainTokenData) + + if len(ret) == 0 { + panic("no return value specified for ExecuteSingleMessage") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalEVM2EVMMessage, [][]byte) (*types.Transaction, error)); ok { + return rf(opts, message, offchainTokenData) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalEVM2EVMMessage, [][]byte) *types.Transaction); ok { + r0 = rf(opts, message, offchainTokenData) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalEVM2EVMMessage, [][]byte) error); ok { + r1 = rf(opts, message, offchainTokenData) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ExecuteSingleMessage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExecuteSingleMessage' +type EVM2EVMOffRampInterface_ExecuteSingleMessage_Call struct { + *mock.Call +} + +// ExecuteSingleMessage is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - message evm_2_evm_offramp.InternalEVM2EVMMessage +// - offchainTokenData [][]byte +func (_e *EVM2EVMOffRampInterface_Expecter) ExecuteSingleMessage(opts interface{}, message interface{}, offchainTokenData interface{}) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + return &EVM2EVMOffRampInterface_ExecuteSingleMessage_Call{Call: _e.mock.On("ExecuteSingleMessage", opts, message, offchainTokenData)} +} + +func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) Run(run func(opts *bind.TransactOpts, message evm_2_evm_offramp.InternalEVM2EVMMessage, offchainTokenData [][]byte)) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp.InternalEVM2EVMMessage), args[2].([][]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp.InternalEVM2EVMMessage, [][]byte) (*types.Transaction, error)) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + _c.Call.Return(run) + return _c +} + +// FilterAdminSet provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterAdminSet(opts *bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampAdminSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterAdminSet") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampAdminSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampAdminSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp.EVM2EVMOffRampAdminSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampAdminSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterAdminSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterAdminSet' +type EVM2EVMOffRampInterface_FilterAdminSet_Call struct { + *mock.Call +} + +// FilterAdminSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterAdminSet(opts interface{}) *EVM2EVMOffRampInterface_FilterAdminSet_Call { + return &EVM2EVMOffRampInterface_FilterAdminSet_Call{Call: _e.mock.On("FilterAdminSet", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterAdminSet_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterAdminSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterAdminSet_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampAdminSetIterator, _a1 error) *EVM2EVMOffRampInterface_FilterAdminSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterAdminSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampAdminSetIterator, error)) *EVM2EVMOffRampInterface_FilterAdminSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfigChanged provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterConfigChanged(opts *bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampConfigChangedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterConfigChanged") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampConfigChangedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampConfigChangedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp.EVM2EVMOffRampConfigChangedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampConfigChangedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterConfigChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfigChanged' +type EVM2EVMOffRampInterface_FilterConfigChanged_Call struct { + *mock.Call +} + +// FilterConfigChanged is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterConfigChanged(opts interface{}) *EVM2EVMOffRampInterface_FilterConfigChanged_Call { + return &EVM2EVMOffRampInterface_FilterConfigChanged_Call{Call: _e.mock.On("FilterConfigChanged", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigChanged_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterConfigChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigChanged_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampConfigChangedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterConfigChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigChanged_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampConfigChangedIterator, error)) *EVM2EVMOffRampInterface_FilterConfigChanged_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfigSet provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterConfigSet(opts *bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampConfigSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterConfigSet") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampConfigSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampConfigSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp.EVM2EVMOffRampConfigSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampConfigSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfigSet' +type EVM2EVMOffRampInterface_FilterConfigSet_Call struct { + *mock.Call +} + +// FilterConfigSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterConfigSet(opts interface{}) *EVM2EVMOffRampInterface_FilterConfigSet_Call { + return &EVM2EVMOffRampInterface_FilterConfigSet_Call{Call: _e.mock.On("FilterConfigSet", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampConfigSetIterator, _a1 error) *EVM2EVMOffRampInterface_FilterConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampConfigSetIterator, error)) *EVM2EVMOffRampInterface_FilterConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfigSet0 provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterConfigSet0(opts *bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampConfigSet0Iterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterConfigSet0") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0Iterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampConfigSet0Iterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0Iterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampConfigSet0Iterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterConfigSet0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfigSet0' +type EVM2EVMOffRampInterface_FilterConfigSet0_Call struct { + *mock.Call +} + +// FilterConfigSet0 is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterConfigSet0(opts interface{}) *EVM2EVMOffRampInterface_FilterConfigSet0_Call { + return &EVM2EVMOffRampInterface_FilterConfigSet0_Call{Call: _e.mock.On("FilterConfigSet0", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet0_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterConfigSet0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet0_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0Iterator, _a1 error) *EVM2EVMOffRampInterface_FilterConfigSet0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet0_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampConfigSet0Iterator, error)) *EVM2EVMOffRampInterface_FilterConfigSet0_Call { + _c.Call.Return(run) + return _c +} + +// FilterExecutionStateChanged provides a mock function with given fields: opts, sequenceNumber, messageId +func (_m *EVM2EVMOffRampInterface) FilterExecutionStateChanged(opts *bind.FilterOpts, sequenceNumber []uint64, messageId [][32]byte) (*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChangedIterator, error) { + ret := _m.Called(opts, sequenceNumber, messageId) + + if len(ret) == 0 { + panic("no return value specified for FilterExecutionStateChanged") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChangedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, [][32]byte) (*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChangedIterator, error)); ok { + return rf(opts, sequenceNumber, messageId) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, [][32]byte) *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChangedIterator); ok { + r0 = rf(opts, sequenceNumber, messageId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChangedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, [][32]byte) error); ok { + r1 = rf(opts, sequenceNumber, messageId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterExecutionStateChanged' +type EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call struct { + *mock.Call +} + +// FilterExecutionStateChanged is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - sequenceNumber []uint64 +// - messageId [][32]byte +func (_e *EVM2EVMOffRampInterface_Expecter) FilterExecutionStateChanged(opts interface{}, sequenceNumber interface{}, messageId interface{}) *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call { + return &EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call{Call: _e.mock.On("FilterExecutionStateChanged", opts, sequenceNumber, messageId)} +} + +func (_c *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call) Run(run func(opts *bind.FilterOpts, sequenceNumber []uint64, messageId [][32]byte)) *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([][32]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChangedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, [][32]byte) (*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChangedIterator, error)) *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferRequested provides a mock function with given fields: opts, from, to +func (_m *EVM2EVMOffRampInterface) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequestedIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferRequested") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequestedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequestedIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequestedIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequestedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferRequested' +type EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call struct { + *mock.Call +} + +// FilterOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) FilterOwnershipTransferRequested(opts interface{}, from interface{}, to interface{}) *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call { + return &EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call{Call: _e.mock.On("FilterOwnershipTransferRequested", opts, from, to)} +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequestedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequestedIterator, error)) *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferred provides a mock function with given fields: opts, from, to +func (_m *EVM2EVMOffRampInterface) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferredIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferred") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferredIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferredIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferredIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferredIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferred' +type EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call struct { + *mock.Call +} + +// FilterOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) FilterOwnershipTransferred(opts interface{}, from interface{}, to interface{}) *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call { + return &EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call{Call: _e.mock.On("FilterOwnershipTransferred", opts, from, to)} +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferredIterator, _a1 error) *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferredIterator, error)) *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// FilterSkippedAlreadyExecutedMessage provides a mock function with given fields: opts, sequenceNumber +func (_m *EVM2EVMOffRampInterface) FilterSkippedAlreadyExecutedMessage(opts *bind.FilterOpts, sequenceNumber []uint64) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator, error) { + ret := _m.Called(opts, sequenceNumber) + + if len(ret) == 0 { + panic("no return value specified for FilterSkippedAlreadyExecutedMessage") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator, error)); ok { + return rf(opts, sequenceNumber) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator); ok { + r0 = rf(opts, sequenceNumber) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { + r1 = rf(opts, sequenceNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterSkippedAlreadyExecutedMessage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterSkippedAlreadyExecutedMessage' +type EVM2EVMOffRampInterface_FilterSkippedAlreadyExecutedMessage_Call struct { + *mock.Call +} + +// FilterSkippedAlreadyExecutedMessage is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - sequenceNumber []uint64 +func (_e *EVM2EVMOffRampInterface_Expecter) FilterSkippedAlreadyExecutedMessage(opts interface{}, sequenceNumber interface{}) *EVM2EVMOffRampInterface_FilterSkippedAlreadyExecutedMessage_Call { + return &EVM2EVMOffRampInterface_FilterSkippedAlreadyExecutedMessage_Call{Call: _e.mock.On("FilterSkippedAlreadyExecutedMessage", opts, sequenceNumber)} +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedAlreadyExecutedMessage_Call) Run(run func(opts *bind.FilterOpts, sequenceNumber []uint64)) *EVM2EVMOffRampInterface_FilterSkippedAlreadyExecutedMessage_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedAlreadyExecutedMessage_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator, _a1 error) *EVM2EVMOffRampInterface_FilterSkippedAlreadyExecutedMessage_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedAlreadyExecutedMessage_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessageIterator, error)) *EVM2EVMOffRampInterface_FilterSkippedAlreadyExecutedMessage_Call { + _c.Call.Return(run) + return _c +} + +// FilterSkippedIncorrectNonce provides a mock function with given fields: opts, nonce, sender +func (_m *EVM2EVMOffRampInterface) FilterSkippedIncorrectNonce(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonceIterator, error) { + ret := _m.Called(opts, nonce, sender) + + if len(ret) == 0 { + panic("no return value specified for FilterSkippedIncorrectNonce") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonceIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonceIterator, error)); ok { + return rf(opts, nonce, sender) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonceIterator); ok { + r0 = rf(opts, nonce, sender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonceIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, []common.Address) error); ok { + r1 = rf(opts, nonce, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterSkippedIncorrectNonce' +type EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call struct { + *mock.Call +} + +// FilterSkippedIncorrectNonce is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - nonce []uint64 +// - sender []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) FilterSkippedIncorrectNonce(opts interface{}, nonce interface{}, sender interface{}) *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call { + return &EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call{Call: _e.mock.On("FilterSkippedIncorrectNonce", opts, nonce, sender)} +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call) Run(run func(opts *bind.FilterOpts, nonce []uint64, sender []common.Address)) *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonceIterator, _a1 error) *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, []common.Address) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonceIterator, error)) *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call { + _c.Call.Return(run) + return _c +} + +// FilterSkippedSenderWithPreviousRampMessageInflight provides a mock function with given fields: opts, nonce, sender +func (_m *EVM2EVMOffRampInterface) FilterSkippedSenderWithPreviousRampMessageInflight(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error) { + ret := _m.Called(opts, nonce, sender) + + if len(ret) == 0 { + panic("no return value specified for FilterSkippedSenderWithPreviousRampMessageInflight") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error)); ok { + return rf(opts, nonce, sender) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator); ok { + r0 = rf(opts, nonce, sender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, []common.Address) error); ok { + r1 = rf(opts, nonce, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterSkippedSenderWithPreviousRampMessageInflight' +type EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call struct { + *mock.Call +} + +// FilterSkippedSenderWithPreviousRampMessageInflight is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - nonce []uint64 +// - sender []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) FilterSkippedSenderWithPreviousRampMessageInflight(opts interface{}, nonce interface{}, sender interface{}) *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call { + return &EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call{Call: _e.mock.On("FilterSkippedSenderWithPreviousRampMessageInflight", opts, nonce, sender)} +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call) Run(run func(opts *bind.FilterOpts, nonce []uint64, sender []common.Address)) *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, _a1 error) *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, []common.Address) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error)) *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(run) + return _c +} + +// FilterTokenAggregateRateLimitAdded provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterTokenAggregateRateLimitAdded(opts *bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAddedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterTokenAggregateRateLimitAdded") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAddedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAddedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAddedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAddedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTokenAggregateRateLimitAdded' +type EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitAdded_Call struct { + *mock.Call +} + +// FilterTokenAggregateRateLimitAdded is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterTokenAggregateRateLimitAdded(opts interface{}) *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitAdded_Call { + return &EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitAdded_Call{Call: _e.mock.On("FilterTokenAggregateRateLimitAdded", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitAdded_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitAdded_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAddedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitAdded_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAddedIterator, error)) *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitAdded_Call { + _c.Call.Return(run) + return _c +} + +// FilterTokenAggregateRateLimitRemoved provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterTokenAggregateRateLimitRemoved(opts *bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterTokenAggregateRateLimitRemoved") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTokenAggregateRateLimitRemoved' +type EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitRemoved_Call struct { + *mock.Call +} + +// FilterTokenAggregateRateLimitRemoved is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterTokenAggregateRateLimitRemoved(opts interface{}) *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitRemoved_Call { + return &EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitRemoved_Call{Call: _e.mock.On("FilterTokenAggregateRateLimitRemoved", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitRemoved_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitRemoved_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitRemoved_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemovedIterator, error)) *EVM2EVMOffRampInterface_FilterTokenAggregateRateLimitRemoved_Call { + _c.Call.Return(run) + return _c +} + +// FilterTokensConsumed provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterTokensConsumed(opts *bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampTokensConsumedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterTokensConsumed") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampTokensConsumedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampTokensConsumedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterTokensConsumed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTokensConsumed' +type EVM2EVMOffRampInterface_FilterTokensConsumed_Call struct { + *mock.Call +} + +// FilterTokensConsumed is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterTokensConsumed(opts interface{}) *EVM2EVMOffRampInterface_FilterTokensConsumed_Call { + return &EVM2EVMOffRampInterface_FilterTokensConsumed_Call{Call: _e.mock.On("FilterTokensConsumed", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterTokensConsumed_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterTokensConsumed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterTokensConsumed_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterTokensConsumed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterTokensConsumed_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampTokensConsumedIterator, error)) *EVM2EVMOffRampInterface_FilterTokensConsumed_Call { + _c.Call.Return(run) + return _c +} + +// FilterTransmitted provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterTransmitted(opts *bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampTransmittedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterTransmitted") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampTransmittedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampTransmittedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp.EVM2EVMOffRampTransmittedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampTransmittedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterTransmitted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTransmitted' +type EVM2EVMOffRampInterface_FilterTransmitted_Call struct { + *mock.Call +} + +// FilterTransmitted is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterTransmitted(opts interface{}) *EVM2EVMOffRampInterface_FilterTransmitted_Call { + return &EVM2EVMOffRampInterface_FilterTransmitted_Call{Call: _e.mock.On("FilterTransmitted", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterTransmitted_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterTransmitted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterTransmitted_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampTransmittedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterTransmitted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterTransmitted_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampTransmittedIterator, error)) *EVM2EVMOffRampInterface_FilterTransmitted_Call { + _c.Call.Return(run) + return _c +} + +// GetAllRateLimitTokens provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetAllRateLimitTokens(opts *bind.CallOpts) (evm_2_evm_offramp.GetAllRateLimitTokens, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetAllRateLimitTokens") + } + + var r0 evm_2_evm_offramp.GetAllRateLimitTokens + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp.GetAllRateLimitTokens, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp.GetAllRateLimitTokens); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp.GetAllRateLimitTokens) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetAllRateLimitTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAllRateLimitTokens' +type EVM2EVMOffRampInterface_GetAllRateLimitTokens_Call struct { + *mock.Call +} + +// GetAllRateLimitTokens is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetAllRateLimitTokens(opts interface{}) *EVM2EVMOffRampInterface_GetAllRateLimitTokens_Call { + return &EVM2EVMOffRampInterface_GetAllRateLimitTokens_Call{Call: _e.mock.On("GetAllRateLimitTokens", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetAllRateLimitTokens_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetAllRateLimitTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetAllRateLimitTokens_Call) Return(_a0 evm_2_evm_offramp.GetAllRateLimitTokens, _a1 error) *EVM2EVMOffRampInterface_GetAllRateLimitTokens_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetAllRateLimitTokens_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp.GetAllRateLimitTokens, error)) *EVM2EVMOffRampInterface_GetAllRateLimitTokens_Call { + _c.Call.Return(run) + return _c +} + +// GetDynamicConfig provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetDynamicConfig(opts *bind.CallOpts) (evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetDynamicConfig") + } + + var r0 evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetDynamicConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDynamicConfig' +type EVM2EVMOffRampInterface_GetDynamicConfig_Call struct { + *mock.Call +} + +// GetDynamicConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetDynamicConfig(opts interface{}) *EVM2EVMOffRampInterface_GetDynamicConfig_Call { + return &EVM2EVMOffRampInterface_GetDynamicConfig_Call{Call: _e.mock.On("GetDynamicConfig", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetDynamicConfig_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetDynamicConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDynamicConfig_Call) Return(_a0 evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig, _a1 error) *EVM2EVMOffRampInterface_GetDynamicConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDynamicConfig_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig, error)) *EVM2EVMOffRampInterface_GetDynamicConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetExecutionState provides a mock function with given fields: opts, sequenceNumber +func (_m *EVM2EVMOffRampInterface) GetExecutionState(opts *bind.CallOpts, sequenceNumber uint64) (uint8, error) { + ret := _m.Called(opts, sequenceNumber) + + if len(ret) == 0 { + panic("no return value specified for GetExecutionState") + } + + var r0 uint8 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (uint8, error)); ok { + return rf(opts, sequenceNumber) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) uint8); ok { + r0 = rf(opts, sequenceNumber) + } else { + r0 = ret.Get(0).(uint8) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, sequenceNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetExecutionState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExecutionState' +type EVM2EVMOffRampInterface_GetExecutionState_Call struct { + *mock.Call +} + +// GetExecutionState is a helper method to define mock.On call +// - opts *bind.CallOpts +// - sequenceNumber uint64 +func (_e *EVM2EVMOffRampInterface_Expecter) GetExecutionState(opts interface{}, sequenceNumber interface{}) *EVM2EVMOffRampInterface_GetExecutionState_Call { + return &EVM2EVMOffRampInterface_GetExecutionState_Call{Call: _e.mock.On("GetExecutionState", opts, sequenceNumber)} +} + +func (_c *EVM2EVMOffRampInterface_GetExecutionState_Call) Run(run func(opts *bind.CallOpts, sequenceNumber uint64)) *EVM2EVMOffRampInterface_GetExecutionState_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetExecutionState_Call) Return(_a0 uint8, _a1 error) *EVM2EVMOffRampInterface_GetExecutionState_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetExecutionState_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (uint8, error)) *EVM2EVMOffRampInterface_GetExecutionState_Call { + _c.Call.Return(run) + return _c +} + +// GetSenderNonce provides a mock function with given fields: opts, sender +func (_m *EVM2EVMOffRampInterface) GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) { + ret := _m.Called(opts, sender) + + if len(ret) == 0 { + panic("no return value specified for GetSenderNonce") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (uint64, error)); ok { + return rf(opts, sender) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) uint64); ok { + r0 = rf(opts, sender) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetSenderNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSenderNonce' +type EVM2EVMOffRampInterface_GetSenderNonce_Call struct { + *mock.Call +} + +// GetSenderNonce is a helper method to define mock.On call +// - opts *bind.CallOpts +// - sender common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) GetSenderNonce(opts interface{}, sender interface{}) *EVM2EVMOffRampInterface_GetSenderNonce_Call { + return &EVM2EVMOffRampInterface_GetSenderNonce_Call{Call: _e.mock.On("GetSenderNonce", opts, sender)} +} + +func (_c *EVM2EVMOffRampInterface_GetSenderNonce_Call) Run(run func(opts *bind.CallOpts, sender common.Address)) *EVM2EVMOffRampInterface_GetSenderNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetSenderNonce_Call) Return(_a0 uint64, _a1 error) *EVM2EVMOffRampInterface_GetSenderNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetSenderNonce_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (uint64, error)) *EVM2EVMOffRampInterface_GetSenderNonce_Call { + _c.Call.Return(run) + return _c +} + +// GetStaticConfig provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetStaticConfig(opts *bind.CallOpts) (evm_2_evm_offramp.EVM2EVMOffRampStaticConfig, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetStaticConfig") + } + + var r0 evm_2_evm_offramp.EVM2EVMOffRampStaticConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp.EVM2EVMOffRampStaticConfig, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp.EVM2EVMOffRampStaticConfig); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp.EVM2EVMOffRampStaticConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetStaticConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStaticConfig' +type EVM2EVMOffRampInterface_GetStaticConfig_Call struct { + *mock.Call +} + +// GetStaticConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetStaticConfig(opts interface{}) *EVM2EVMOffRampInterface_GetStaticConfig_Call { + return &EVM2EVMOffRampInterface_GetStaticConfig_Call{Call: _e.mock.On("GetStaticConfig", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetStaticConfig_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetStaticConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetStaticConfig_Call) Return(_a0 evm_2_evm_offramp.EVM2EVMOffRampStaticConfig, _a1 error) *EVM2EVMOffRampInterface_GetStaticConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetStaticConfig_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp.EVM2EVMOffRampStaticConfig, error)) *EVM2EVMOffRampInterface_GetStaticConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenLimitAdmin provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetTokenLimitAdmin") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenLimitAdmin' +type EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call struct { + *mock.Call +} + +// GetTokenLimitAdmin is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetTokenLimitAdmin(opts interface{}) *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call { + return &EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call{Call: _e.mock.On("GetTokenLimitAdmin", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call { + _c.Call.Return(run) + return _c +} + +// GetTransmitters provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetTransmitters") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetTransmitters_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTransmitters' +type EVM2EVMOffRampInterface_GetTransmitters_Call struct { + *mock.Call +} + +// GetTransmitters is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetTransmitters(opts interface{}) *EVM2EVMOffRampInterface_GetTransmitters_Call { + return &EVM2EVMOffRampInterface_GetTransmitters_Call{Call: _e.mock.On("GetTransmitters", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetTransmitters_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetTransmitters_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetTransmitters_Call) Return(_a0 []common.Address, _a1 error) *EVM2EVMOffRampInterface_GetTransmitters_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetTransmitters_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *EVM2EVMOffRampInterface_GetTransmitters_Call { + _c.Call.Return(run) + return _c +} + +// LatestConfigDetails provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) LatestConfigDetails(opts *bind.CallOpts) (evm_2_evm_offramp.LatestConfigDetails, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LatestConfigDetails") + } + + var r0 evm_2_evm_offramp.LatestConfigDetails + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp.LatestConfigDetails, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp.LatestConfigDetails); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp.LatestConfigDetails) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_LatestConfigDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestConfigDetails' +type EVM2EVMOffRampInterface_LatestConfigDetails_Call struct { + *mock.Call +} + +// LatestConfigDetails is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) LatestConfigDetails(opts interface{}) *EVM2EVMOffRampInterface_LatestConfigDetails_Call { + return &EVM2EVMOffRampInterface_LatestConfigDetails_Call{Call: _e.mock.On("LatestConfigDetails", opts)} +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDetails_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_LatestConfigDetails_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDetails_Call) Return(_a0 evm_2_evm_offramp.LatestConfigDetails, _a1 error) *EVM2EVMOffRampInterface_LatestConfigDetails_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDetails_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp.LatestConfigDetails, error)) *EVM2EVMOffRampInterface_LatestConfigDetails_Call { + _c.Call.Return(run) + return _c +} + +// LatestConfigDigestAndEpoch provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (evm_2_evm_offramp.LatestConfigDigestAndEpoch, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LatestConfigDigestAndEpoch") + } + + var r0 evm_2_evm_offramp.LatestConfigDigestAndEpoch + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp.LatestConfigDigestAndEpoch, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp.LatestConfigDigestAndEpoch); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp.LatestConfigDigestAndEpoch) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestConfigDigestAndEpoch' +type EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call struct { + *mock.Call +} + +// LatestConfigDigestAndEpoch is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) LatestConfigDigestAndEpoch(opts interface{}) *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call { + return &EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call{Call: _e.mock.On("LatestConfigDigestAndEpoch", opts)} +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call) Return(_a0 evm_2_evm_offramp.LatestConfigDigestAndEpoch, _a1 error) *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp.LatestConfigDigestAndEpoch, error)) *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call { + _c.Call.Return(run) + return _c +} + +// ManuallyExecute provides a mock function with given fields: opts, report, gasLimitOverrides +func (_m *EVM2EVMOffRampInterface) ManuallyExecute(opts *bind.TransactOpts, report evm_2_evm_offramp.InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { + ret := _m.Called(opts, report, gasLimitOverrides) + + if len(ret) == 0 { + panic("no return value specified for ManuallyExecute") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalExecutionReport, []*big.Int) (*types.Transaction, error)); ok { + return rf(opts, report, gasLimitOverrides) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalExecutionReport, []*big.Int) *types.Transaction); ok { + r0 = rf(opts, report, gasLimitOverrides) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalExecutionReport, []*big.Int) error); ok { + r1 = rf(opts, report, gasLimitOverrides) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ManuallyExecute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ManuallyExecute' +type EVM2EVMOffRampInterface_ManuallyExecute_Call struct { + *mock.Call +} + +// ManuallyExecute is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - report evm_2_evm_offramp.InternalExecutionReport +// - gasLimitOverrides []*big.Int +func (_e *EVM2EVMOffRampInterface_Expecter) ManuallyExecute(opts interface{}, report interface{}, gasLimitOverrides interface{}) *EVM2EVMOffRampInterface_ManuallyExecute_Call { + return &EVM2EVMOffRampInterface_ManuallyExecute_Call{Call: _e.mock.On("ManuallyExecute", opts, report, gasLimitOverrides)} +} + +func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) Run(run func(opts *bind.TransactOpts, report evm_2_evm_offramp.InternalExecutionReport, gasLimitOverrides []*big.Int)) *EVM2EVMOffRampInterface_ManuallyExecute_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp.InternalExecutionReport), args[2].([]*big.Int)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_ManuallyExecute_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp.InternalExecutionReport, []*big.Int) (*types.Transaction, error)) *EVM2EVMOffRampInterface_ManuallyExecute_Call { + _c.Call.Return(run) + return _c +} + +// Owner provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) Owner(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Owner") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_Owner_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Owner' +type EVM2EVMOffRampInterface_Owner_Call struct { + *mock.Call +} + +// Owner is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) Owner(opts interface{}) *EVM2EVMOffRampInterface_Owner_Call { + return &EVM2EVMOffRampInterface_Owner_Call{Call: _e.mock.On("Owner", opts)} +} + +func (_c *EVM2EVMOffRampInterface_Owner_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_Owner_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Owner_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOffRampInterface_Owner_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Owner_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *EVM2EVMOffRampInterface_Owner_Call { + _c.Call.Return(run) + return _c +} + +// ParseAdminSet provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseAdminSet(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampAdminSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseAdminSet") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampAdminSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampAdminSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampAdminSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampAdminSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseAdminSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseAdminSet' +type EVM2EVMOffRampInterface_ParseAdminSet_Call struct { + *mock.Call +} + +// ParseAdminSet is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseAdminSet(log interface{}) *EVM2EVMOffRampInterface_ParseAdminSet_Call { + return &EVM2EVMOffRampInterface_ParseAdminSet_Call{Call: _e.mock.On("ParseAdminSet", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseAdminSet_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseAdminSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseAdminSet_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampAdminSet, _a1 error) *EVM2EVMOffRampInterface_ParseAdminSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseAdminSet_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampAdminSet, error)) *EVM2EVMOffRampInterface_ParseAdminSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseConfigChanged provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseConfigChanged(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampConfigChanged, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseConfigChanged") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampConfigChanged + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampConfigChanged, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampConfigChanged); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampConfigChanged) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseConfigChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseConfigChanged' +type EVM2EVMOffRampInterface_ParseConfigChanged_Call struct { + *mock.Call +} + +// ParseConfigChanged is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseConfigChanged(log interface{}) *EVM2EVMOffRampInterface_ParseConfigChanged_Call { + return &EVM2EVMOffRampInterface_ParseConfigChanged_Call{Call: _e.mock.On("ParseConfigChanged", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigChanged_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseConfigChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigChanged_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampConfigChanged, _a1 error) *EVM2EVMOffRampInterface_ParseConfigChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigChanged_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampConfigChanged, error)) *EVM2EVMOffRampInterface_ParseConfigChanged_Call { + _c.Call.Return(run) + return _c +} + +// ParseConfigSet provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseConfigSet(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampConfigSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseConfigSet") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampConfigSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampConfigSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampConfigSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampConfigSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseConfigSet' +type EVM2EVMOffRampInterface_ParseConfigSet_Call struct { + *mock.Call +} + +// ParseConfigSet is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseConfigSet(log interface{}) *EVM2EVMOffRampInterface_ParseConfigSet_Call { + return &EVM2EVMOffRampInterface_ParseConfigSet_Call{Call: _e.mock.On("ParseConfigSet", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampConfigSet, _a1 error) *EVM2EVMOffRampInterface_ParseConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampConfigSet, error)) *EVM2EVMOffRampInterface_ParseConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseConfigSet0 provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseConfigSet0(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampConfigSet0, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseConfigSet0") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0 + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampConfigSet0, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampConfigSet0) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseConfigSet0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseConfigSet0' +type EVM2EVMOffRampInterface_ParseConfigSet0_Call struct { + *mock.Call +} + +// ParseConfigSet0 is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseConfigSet0(log interface{}) *EVM2EVMOffRampInterface_ParseConfigSet0_Call { + return &EVM2EVMOffRampInterface_ParseConfigSet0_Call{Call: _e.mock.On("ParseConfigSet0", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet0_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseConfigSet0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet0_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0, _a1 error) *EVM2EVMOffRampInterface_ParseConfigSet0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet0_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampConfigSet0, error)) *EVM2EVMOffRampInterface_ParseConfigSet0_Call { + _c.Call.Return(run) + return _c +} + +// ParseExecutionStateChanged provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseExecutionStateChanged(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseExecutionStateChanged") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseExecutionStateChanged' +type EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call struct { + *mock.Call +} + +// ParseExecutionStateChanged is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseExecutionStateChanged(log interface{}) *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call { + return &EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call{Call: _e.mock.On("ParseExecutionStateChanged", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged, _a1 error) *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged, error)) *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type EVM2EVMOffRampInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseLog(log interface{}) *EVM2EVMOffRampInterface_ParseLog_Call { + return &EVM2EVMOffRampInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseLog_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *EVM2EVMOffRampInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *EVM2EVMOffRampInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferRequested provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseOwnershipTransferRequested(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferRequested") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferRequested' +type EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call struct { + *mock.Call +} + +// ParseOwnershipTransferRequested is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseOwnershipTransferRequested(log interface{}) *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call { + return &EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call{Call: _e.mock.On("ParseOwnershipTransferRequested", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested, _a1 error) *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested, error)) *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferred provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseOwnershipTransferred(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferred") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferred' +type EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call struct { + *mock.Call +} + +// ParseOwnershipTransferred is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseOwnershipTransferred(log interface{}) *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call { + return &EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call{Call: _e.mock.On("ParseOwnershipTransferred", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred, _a1 error) *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred, error)) *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// ParseSkippedAlreadyExecutedMessage provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseSkippedAlreadyExecutedMessage(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseSkippedAlreadyExecutedMessage") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseSkippedAlreadyExecutedMessage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseSkippedAlreadyExecutedMessage' +type EVM2EVMOffRampInterface_ParseSkippedAlreadyExecutedMessage_Call struct { + *mock.Call +} + +// ParseSkippedAlreadyExecutedMessage is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseSkippedAlreadyExecutedMessage(log interface{}) *EVM2EVMOffRampInterface_ParseSkippedAlreadyExecutedMessage_Call { + return &EVM2EVMOffRampInterface_ParseSkippedAlreadyExecutedMessage_Call{Call: _e.mock.On("ParseSkippedAlreadyExecutedMessage", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedAlreadyExecutedMessage_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseSkippedAlreadyExecutedMessage_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedAlreadyExecutedMessage_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage, _a1 error) *EVM2EVMOffRampInterface_ParseSkippedAlreadyExecutedMessage_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedAlreadyExecutedMessage_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage, error)) *EVM2EVMOffRampInterface_ParseSkippedAlreadyExecutedMessage_Call { + _c.Call.Return(run) + return _c +} + +// ParseSkippedIncorrectNonce provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseSkippedIncorrectNonce(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseSkippedIncorrectNonce") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseSkippedIncorrectNonce' +type EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call struct { + *mock.Call +} + +// ParseSkippedIncorrectNonce is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseSkippedIncorrectNonce(log interface{}) *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call { + return &EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call{Call: _e.mock.On("ParseSkippedIncorrectNonce", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce, _a1 error) *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce, error)) *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call { + _c.Call.Return(run) + return _c +} + +// ParseSkippedSenderWithPreviousRampMessageInflight provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseSkippedSenderWithPreviousRampMessageInflight(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseSkippedSenderWithPreviousRampMessageInflight") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseSkippedSenderWithPreviousRampMessageInflight' +type EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call struct { + *mock.Call +} + +// ParseSkippedSenderWithPreviousRampMessageInflight is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseSkippedSenderWithPreviousRampMessageInflight(log interface{}) *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call { + return &EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call{Call: _e.mock.On("ParseSkippedSenderWithPreviousRampMessageInflight", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, _a1 error) *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error)) *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(run) + return _c +} + +// ParseTokenAggregateRateLimitAdded provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseTokenAggregateRateLimitAdded(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTokenAggregateRateLimitAdded") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTokenAggregateRateLimitAdded' +type EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitAdded_Call struct { + *mock.Call +} + +// ParseTokenAggregateRateLimitAdded is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseTokenAggregateRateLimitAdded(log interface{}) *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitAdded_Call { + return &EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitAdded_Call{Call: _e.mock.On("ParseTokenAggregateRateLimitAdded", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitAdded_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitAdded_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded, _a1 error) *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitAdded_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded, error)) *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitAdded_Call { + _c.Call.Return(run) + return _c +} + +// ParseTokenAggregateRateLimitRemoved provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseTokenAggregateRateLimitRemoved(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTokenAggregateRateLimitRemoved") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTokenAggregateRateLimitRemoved' +type EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitRemoved_Call struct { + *mock.Call +} + +// ParseTokenAggregateRateLimitRemoved is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseTokenAggregateRateLimitRemoved(log interface{}) *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitRemoved_Call { + return &EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitRemoved_Call{Call: _e.mock.On("ParseTokenAggregateRateLimitRemoved", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitRemoved_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitRemoved_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved, _a1 error) *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitRemoved_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved, error)) *EVM2EVMOffRampInterface_ParseTokenAggregateRateLimitRemoved_Call { + _c.Call.Return(run) + return _c +} + +// ParseTokensConsumed provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseTokensConsumed(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTokensConsumed") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseTokensConsumed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTokensConsumed' +type EVM2EVMOffRampInterface_ParseTokensConsumed_Call struct { + *mock.Call +} + +// ParseTokensConsumed is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseTokensConsumed(log interface{}) *EVM2EVMOffRampInterface_ParseTokensConsumed_Call { + return &EVM2EVMOffRampInterface_ParseTokensConsumed_Call{Call: _e.mock.On("ParseTokensConsumed", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseTokensConsumed_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseTokensConsumed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseTokensConsumed_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed, _a1 error) *EVM2EVMOffRampInterface_ParseTokensConsumed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseTokensConsumed_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed, error)) *EVM2EVMOffRampInterface_ParseTokensConsumed_Call { + _c.Call.Return(run) + return _c +} + +// ParseTransmitted provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseTransmitted(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampTransmitted, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTransmitted") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampTransmitted + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampTransmitted, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampTransmitted); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampTransmitted) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseTransmitted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTransmitted' +type EVM2EVMOffRampInterface_ParseTransmitted_Call struct { + *mock.Call +} + +// ParseTransmitted is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseTransmitted(log interface{}) *EVM2EVMOffRampInterface_ParseTransmitted_Call { + return &EVM2EVMOffRampInterface_ParseTransmitted_Call{Call: _e.mock.On("ParseTransmitted", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseTransmitted_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseTransmitted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseTransmitted_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampTransmitted, _a1 error) *EVM2EVMOffRampInterface_ParseTransmitted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseTransmitted_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampTransmitted, error)) *EVM2EVMOffRampInterface_ParseTransmitted_Call { + _c.Call.Return(run) + return _c +} + +// SetAdmin provides a mock function with given fields: opts, newAdmin +func (_m *EVM2EVMOffRampInterface) SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, newAdmin) + + if len(ret) == 0 { + panic("no return value specified for SetAdmin") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, newAdmin) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, newAdmin) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, newAdmin) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_SetAdmin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetAdmin' +type EVM2EVMOffRampInterface_SetAdmin_Call struct { + *mock.Call +} + +// SetAdmin is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - newAdmin common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) SetAdmin(opts interface{}, newAdmin interface{}) *EVM2EVMOffRampInterface_SetAdmin_Call { + return &EVM2EVMOffRampInterface_SetAdmin_Call{Call: _e.mock.On("SetAdmin", opts, newAdmin)} +} + +func (_c *EVM2EVMOffRampInterface_SetAdmin_Call) Run(run func(opts *bind.TransactOpts, newAdmin common.Address)) *EVM2EVMOffRampInterface_SetAdmin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetAdmin_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_SetAdmin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetAdmin_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *EVM2EVMOffRampInterface_SetAdmin_Call { + _c.Call.Return(run) + return _c +} + +// SetOCR2Config provides a mock function with given fields: opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig +func (_m *EVM2EVMOffRampInterface) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + ret := _m.Called(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + + if len(ret) == 0 { + panic("no return value specified for SetOCR2Config") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) (*types.Transaction, error)); ok { + return rf(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) *types.Transaction); ok { + r0 = rf(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) error); ok { + r1 = rf(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_SetOCR2Config_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetOCR2Config' +type EVM2EVMOffRampInterface_SetOCR2Config_Call struct { + *mock.Call +} + +// SetOCR2Config is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - signers []common.Address +// - transmitters []common.Address +// - f uint8 +// - onchainConfig []byte +// - offchainConfigVersion uint64 +// - offchainConfig []byte +func (_e *EVM2EVMOffRampInterface_Expecter) SetOCR2Config(opts interface{}, signers interface{}, transmitters interface{}, f interface{}, onchainConfig interface{}, offchainConfigVersion interface{}, offchainConfig interface{}) *EVM2EVMOffRampInterface_SetOCR2Config_Call { + return &EVM2EVMOffRampInterface_SetOCR2Config_Call{Call: _e.mock.On("SetOCR2Config", opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig)} +} + +func (_c *EVM2EVMOffRampInterface_SetOCR2Config_Call) Run(run func(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte)) *EVM2EVMOffRampInterface_SetOCR2Config_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]common.Address), args[2].([]common.Address), args[3].(uint8), args[4].([]byte), args[5].(uint64), args[6].([]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetOCR2Config_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_SetOCR2Config_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetOCR2Config_Call) RunAndReturn(run func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) (*types.Transaction, error)) *EVM2EVMOffRampInterface_SetOCR2Config_Call { + _c.Call.Return(run) + return _c +} + +// SetRateLimiterConfig provides a mock function with given fields: opts, config +func (_m *EVM2EVMOffRampInterface) SetRateLimiterConfig(opts *bind.TransactOpts, config evm_2_evm_offramp.RateLimiterConfig) (*types.Transaction, error) { + ret := _m.Called(opts, config) + + if len(ret) == 0 { + panic("no return value specified for SetRateLimiterConfig") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.RateLimiterConfig) (*types.Transaction, error)); ok { + return rf(opts, config) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.RateLimiterConfig) *types.Transaction); ok { + r0 = rf(opts, config) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp.RateLimiterConfig) error); ok { + r1 = rf(opts, config) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_SetRateLimiterConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetRateLimiterConfig' +type EVM2EVMOffRampInterface_SetRateLimiterConfig_Call struct { + *mock.Call +} + +// SetRateLimiterConfig is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - config evm_2_evm_offramp.RateLimiterConfig +func (_e *EVM2EVMOffRampInterface_Expecter) SetRateLimiterConfig(opts interface{}, config interface{}) *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call { + return &EVM2EVMOffRampInterface_SetRateLimiterConfig_Call{Call: _e.mock.On("SetRateLimiterConfig", opts, config)} +} + +func (_c *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call) Run(run func(opts *bind.TransactOpts, config evm_2_evm_offramp.RateLimiterConfig)) *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp.RateLimiterConfig)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp.RateLimiterConfig) (*types.Transaction, error)) *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call { + _c.Call.Return(run) + return _c +} + +// TransferOwnership provides a mock function with given fields: opts, to +func (_m *EVM2EVMOffRampInterface) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, to) + + if len(ret) == 0 { + panic("no return value specified for TransferOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, to) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_TransferOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TransferOwnership' +type EVM2EVMOffRampInterface_TransferOwnership_Call struct { + *mock.Call +} + +// TransferOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - to common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) TransferOwnership(opts interface{}, to interface{}) *EVM2EVMOffRampInterface_TransferOwnership_Call { + return &EVM2EVMOffRampInterface_TransferOwnership_Call{Call: _e.mock.On("TransferOwnership", opts, to)} +} + +func (_c *EVM2EVMOffRampInterface_TransferOwnership_Call) Run(run func(opts *bind.TransactOpts, to common.Address)) *EVM2EVMOffRampInterface_TransferOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_TransferOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_TransferOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_TransferOwnership_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *EVM2EVMOffRampInterface_TransferOwnership_Call { + _c.Call.Return(run) + return _c +} + +// Transmit provides a mock function with given fields: opts, reportContext, report, rs, ss, arg4 +func (_m *EVM2EVMOffRampInterface) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) { + ret := _m.Called(opts, reportContext, report, rs, ss, arg4) + + if len(ret) == 0 { + panic("no return value specified for Transmit") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) (*types.Transaction, error)); ok { + return rf(opts, reportContext, report, rs, ss, arg4) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) *types.Transaction); ok { + r0 = rf(opts, reportContext, report, rs, ss, arg4) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) error); ok { + r1 = rf(opts, reportContext, report, rs, ss, arg4) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_Transmit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Transmit' +type EVM2EVMOffRampInterface_Transmit_Call struct { + *mock.Call +} + +// Transmit is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - reportContext [3][32]byte +// - report []byte +// - rs [][32]byte +// - ss [][32]byte +// - arg4 [32]byte +func (_e *EVM2EVMOffRampInterface_Expecter) Transmit(opts interface{}, reportContext interface{}, report interface{}, rs interface{}, ss interface{}, arg4 interface{}) *EVM2EVMOffRampInterface_Transmit_Call { + return &EVM2EVMOffRampInterface_Transmit_Call{Call: _e.mock.On("Transmit", opts, reportContext, report, rs, ss, arg4)} +} + +func (_c *EVM2EVMOffRampInterface_Transmit_Call) Run(run func(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte)) *EVM2EVMOffRampInterface_Transmit_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([3][32]byte), args[2].([]byte), args[3].([][32]byte), args[4].([][32]byte), args[5].([32]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Transmit_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_Transmit_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Transmit_Call) RunAndReturn(run func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) (*types.Transaction, error)) *EVM2EVMOffRampInterface_Transmit_Call { + _c.Call.Return(run) + return _c +} + +// TypeAndVersion provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) TypeAndVersion(opts *bind.CallOpts) (string, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for TypeAndVersion") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (string, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) string); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_TypeAndVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TypeAndVersion' +type EVM2EVMOffRampInterface_TypeAndVersion_Call struct { + *mock.Call +} + +// TypeAndVersion is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) TypeAndVersion(opts interface{}) *EVM2EVMOffRampInterface_TypeAndVersion_Call { + return &EVM2EVMOffRampInterface_TypeAndVersion_Call{Call: _e.mock.On("TypeAndVersion", opts)} +} + +func (_c *EVM2EVMOffRampInterface_TypeAndVersion_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_TypeAndVersion_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_TypeAndVersion_Call) Return(_a0 string, _a1 error) *EVM2EVMOffRampInterface_TypeAndVersion_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_TypeAndVersion_Call) RunAndReturn(run func(*bind.CallOpts) (string, error)) *EVM2EVMOffRampInterface_TypeAndVersion_Call { + _c.Call.Return(run) + return _c +} + +// UpdateRateLimitTokens provides a mock function with given fields: opts, removes, adds +func (_m *EVM2EVMOffRampInterface) UpdateRateLimitTokens(opts *bind.TransactOpts, removes []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken, adds []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken) (*types.Transaction, error) { + ret := _m.Called(opts, removes, adds) + + if len(ret) == 0 { + panic("no return value specified for UpdateRateLimitTokens") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken, []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken) (*types.Transaction, error)); ok { + return rf(opts, removes, adds) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken, []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken) *types.Transaction); ok { + r0 = rf(opts, removes, adds) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken, []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken) error); ok { + r1 = rf(opts, removes, adds) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_UpdateRateLimitTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateRateLimitTokens' +type EVM2EVMOffRampInterface_UpdateRateLimitTokens_Call struct { + *mock.Call +} + +// UpdateRateLimitTokens is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - removes []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken +// - adds []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken +func (_e *EVM2EVMOffRampInterface_Expecter) UpdateRateLimitTokens(opts interface{}, removes interface{}, adds interface{}) *EVM2EVMOffRampInterface_UpdateRateLimitTokens_Call { + return &EVM2EVMOffRampInterface_UpdateRateLimitTokens_Call{Call: _e.mock.On("UpdateRateLimitTokens", opts, removes, adds)} +} + +func (_c *EVM2EVMOffRampInterface_UpdateRateLimitTokens_Call) Run(run func(opts *bind.TransactOpts, removes []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken, adds []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken)) *EVM2EVMOffRampInterface_UpdateRateLimitTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken), args[2].([]evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_UpdateRateLimitTokens_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_UpdateRateLimitTokens_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_UpdateRateLimitTokens_Call) RunAndReturn(run func(*bind.TransactOpts, []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken, []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken) (*types.Transaction, error)) *EVM2EVMOffRampInterface_UpdateRateLimitTokens_Call { + _c.Call.Return(run) + return _c +} + +// WatchAdminSet provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampAdminSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchAdminSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampAdminSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampAdminSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampAdminSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchAdminSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchAdminSet' +type EVM2EVMOffRampInterface_WatchAdminSet_Call struct { + *mock.Call +} + +// WatchAdminSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampAdminSet +func (_e *EVM2EVMOffRampInterface_Expecter) WatchAdminSet(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchAdminSet_Call { + return &EVM2EVMOffRampInterface_WatchAdminSet_Call{Call: _e.mock.On("WatchAdminSet", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchAdminSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampAdminSet)) *EVM2EVMOffRampInterface_WatchAdminSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampAdminSet)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchAdminSet_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchAdminSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchAdminSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampAdminSet) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchAdminSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchConfigChanged provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigChanged) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchConfigChanged") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigChanged) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigChanged) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigChanged) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchConfigChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchConfigChanged' +type EVM2EVMOffRampInterface_WatchConfigChanged_Call struct { + *mock.Call +} + +// WatchConfigChanged is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigChanged +func (_e *EVM2EVMOffRampInterface_Expecter) WatchConfigChanged(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchConfigChanged_Call { + return &EVM2EVMOffRampInterface_WatchConfigChanged_Call{Call: _e.mock.On("WatchConfigChanged", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigChanged_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigChanged)) *EVM2EVMOffRampInterface_WatchConfigChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigChanged)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigChanged_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchConfigChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigChanged_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigChanged) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchConfigChanged_Call { + _c.Call.Return(run) + return _c +} + +// WatchConfigSet provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchConfigSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchConfigSet' +type EVM2EVMOffRampInterface_WatchConfigSet_Call struct { + *mock.Call +} + +// WatchConfigSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet +func (_e *EVM2EVMOffRampInterface_Expecter) WatchConfigSet(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchConfigSet_Call { + return &EVM2EVMOffRampInterface_WatchConfigSet_Call{Call: _e.mock.On("WatchConfigSet", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet)) *EVM2EVMOffRampInterface_WatchConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchConfigSet0 provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchConfigSet0") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchConfigSet0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchConfigSet0' +type EVM2EVMOffRampInterface_WatchConfigSet0_Call struct { + *mock.Call +} + +// WatchConfigSet0 is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0 +func (_e *EVM2EVMOffRampInterface_Expecter) WatchConfigSet0(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchConfigSet0_Call { + return &EVM2EVMOffRampInterface_WatchConfigSet0_Call{Call: _e.mock.On("WatchConfigSet0", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet0_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0)) *EVM2EVMOffRampInterface_WatchConfigSet0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet0_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchConfigSet0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet0_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigSet0) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchConfigSet0_Call { + _c.Call.Return(run) + return _c +} + +// WatchExecutionStateChanged provides a mock function with given fields: opts, sink, sequenceNumber, messageId +func (_m *EVM2EVMOffRampInterface) WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) { + ret := _m.Called(opts, sink, sequenceNumber, messageId) + + if len(ret) == 0 { + panic("no return value specified for WatchExecutionStateChanged") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged, []uint64, [][32]byte) (event.Subscription, error)); ok { + return rf(opts, sink, sequenceNumber, messageId) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged, []uint64, [][32]byte) event.Subscription); ok { + r0 = rf(opts, sink, sequenceNumber, messageId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged, []uint64, [][32]byte) error); ok { + r1 = rf(opts, sink, sequenceNumber, messageId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchExecutionStateChanged' +type EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call struct { + *mock.Call +} + +// WatchExecutionStateChanged is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged +// - sequenceNumber []uint64 +// - messageId [][32]byte +func (_e *EVM2EVMOffRampInterface_Expecter) WatchExecutionStateChanged(opts interface{}, sink interface{}, sequenceNumber interface{}, messageId interface{}) *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call { + return &EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call{Call: _e.mock.On("WatchExecutionStateChanged", opts, sink, sequenceNumber, messageId)} +} + +func (_c *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged, sequenceNumber []uint64, messageId [][32]byte)) *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged), args[2].([]uint64), args[3].([][32]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged, []uint64, [][32]byte) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferRequested provides a mock function with given fields: opts, sink, from, to +func (_m *EVM2EVMOffRampInterface) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferRequested") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferRequested' +type EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call struct { + *mock.Call +} + +// WatchOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) WatchOwnershipTransferRequested(opts interface{}, sink interface{}, from interface{}, to interface{}) *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call { + return &EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call{Call: _e.mock.On("WatchOwnershipTransferRequested", opts, sink, from, to)} +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested, from []common.Address, to []common.Address)) *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferred provides a mock function with given fields: opts, sink, from, to +func (_m *EVM2EVMOffRampInterface) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferred") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferred' +type EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call struct { + *mock.Call +} + +// WatchOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) WatchOwnershipTransferred(opts interface{}, sink interface{}, from interface{}, to interface{}) *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call { + return &EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call{Call: _e.mock.On("WatchOwnershipTransferred", opts, sink, from, to)} +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred, from []common.Address, to []common.Address)) *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// WatchSkippedAlreadyExecutedMessage provides a mock function with given fields: opts, sink, sequenceNumber +func (_m *EVM2EVMOffRampInterface) WatchSkippedAlreadyExecutedMessage(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage, sequenceNumber []uint64) (event.Subscription, error) { + ret := _m.Called(opts, sink, sequenceNumber) + + if len(ret) == 0 { + panic("no return value specified for WatchSkippedAlreadyExecutedMessage") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage, []uint64) (event.Subscription, error)); ok { + return rf(opts, sink, sequenceNumber) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage, []uint64) event.Subscription); ok { + r0 = rf(opts, sink, sequenceNumber) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage, []uint64) error); ok { + r1 = rf(opts, sink, sequenceNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchSkippedAlreadyExecutedMessage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchSkippedAlreadyExecutedMessage' +type EVM2EVMOffRampInterface_WatchSkippedAlreadyExecutedMessage_Call struct { + *mock.Call +} + +// WatchSkippedAlreadyExecutedMessage is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage +// - sequenceNumber []uint64 +func (_e *EVM2EVMOffRampInterface_Expecter) WatchSkippedAlreadyExecutedMessage(opts interface{}, sink interface{}, sequenceNumber interface{}) *EVM2EVMOffRampInterface_WatchSkippedAlreadyExecutedMessage_Call { + return &EVM2EVMOffRampInterface_WatchSkippedAlreadyExecutedMessage_Call{Call: _e.mock.On("WatchSkippedAlreadyExecutedMessage", opts, sink, sequenceNumber)} +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedAlreadyExecutedMessage_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage, sequenceNumber []uint64)) *EVM2EVMOffRampInterface_WatchSkippedAlreadyExecutedMessage_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage), args[2].([]uint64)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedAlreadyExecutedMessage_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchSkippedAlreadyExecutedMessage_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedAlreadyExecutedMessage_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedAlreadyExecutedMessage, []uint64) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchSkippedAlreadyExecutedMessage_Call { + _c.Call.Return(run) + return _c +} + +// WatchSkippedIncorrectNonce provides a mock function with given fields: opts, sink, nonce, sender +func (_m *EVM2EVMOffRampInterface) WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce, nonce []uint64, sender []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, nonce, sender) + + if len(ret) == 0 { + panic("no return value specified for WatchSkippedIncorrectNonce") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce, []uint64, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, nonce, sender) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce, []uint64, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, nonce, sender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce, []uint64, []common.Address) error); ok { + r1 = rf(opts, sink, nonce, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchSkippedIncorrectNonce' +type EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call struct { + *mock.Call +} + +// WatchSkippedIncorrectNonce is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce +// - nonce []uint64 +// - sender []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) WatchSkippedIncorrectNonce(opts interface{}, sink interface{}, nonce interface{}, sender interface{}) *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call { + return &EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call{Call: _e.mock.On("WatchSkippedIncorrectNonce", opts, sink, nonce, sender)} +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce, nonce []uint64, sender []common.Address)) *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce), args[2].([]uint64), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedIncorrectNonce, []uint64, []common.Address) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call { + _c.Call.Return(run) + return _c +} + +// WatchSkippedSenderWithPreviousRampMessageInflight provides a mock function with given fields: opts, sink, nonce, sender +func (_m *EVM2EVMOffRampInterface) WatchSkippedSenderWithPreviousRampMessageInflight(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, nonce []uint64, sender []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, nonce, sender) + + if len(ret) == 0 { + panic("no return value specified for WatchSkippedSenderWithPreviousRampMessageInflight") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, []uint64, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, nonce, sender) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, []uint64, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, nonce, sender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, []uint64, []common.Address) error); ok { + r1 = rf(opts, sink, nonce, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchSkippedSenderWithPreviousRampMessageInflight' +type EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call struct { + *mock.Call +} + +// WatchSkippedSenderWithPreviousRampMessageInflight is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight +// - nonce []uint64 +// - sender []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) WatchSkippedSenderWithPreviousRampMessageInflight(opts interface{}, sink interface{}, nonce interface{}, sender interface{}) *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call { + return &EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call{Call: _e.mock.On("WatchSkippedSenderWithPreviousRampMessageInflight", opts, sink, nonce, sender)} +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, nonce []uint64, sender []common.Address)) *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight), args[2].([]uint64), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, []uint64, []common.Address) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(run) + return _c +} + +// WatchTokenAggregateRateLimitAdded provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchTokenAggregateRateLimitAdded(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchTokenAggregateRateLimitAdded") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTokenAggregateRateLimitAdded' +type EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitAdded_Call struct { + *mock.Call +} + +// WatchTokenAggregateRateLimitAdded is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded +func (_e *EVM2EVMOffRampInterface_Expecter) WatchTokenAggregateRateLimitAdded(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitAdded_Call { + return &EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitAdded_Call{Call: _e.mock.On("WatchTokenAggregateRateLimitAdded", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitAdded_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded)) *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitAdded_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitAdded_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitAdded) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitAdded_Call { + _c.Call.Return(run) + return _c +} + +// WatchTokenAggregateRateLimitRemoved provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchTokenAggregateRateLimitRemoved(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchTokenAggregateRateLimitRemoved") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTokenAggregateRateLimitRemoved' +type EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitRemoved_Call struct { + *mock.Call +} + +// WatchTokenAggregateRateLimitRemoved is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved +func (_e *EVM2EVMOffRampInterface_Expecter) WatchTokenAggregateRateLimitRemoved(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitRemoved_Call { + return &EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitRemoved_Call{Call: _e.mock.On("WatchTokenAggregateRateLimitRemoved", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitRemoved_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved)) *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitRemoved_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitRemoved_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokenAggregateRateLimitRemoved) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchTokenAggregateRateLimitRemoved_Call { + _c.Call.Return(run) + return _c +} + +// WatchTokensConsumed provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchTokensConsumed") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchTokensConsumed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTokensConsumed' +type EVM2EVMOffRampInterface_WatchTokensConsumed_Call struct { + *mock.Call +} + +// WatchTokensConsumed is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed +func (_e *EVM2EVMOffRampInterface_Expecter) WatchTokensConsumed(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchTokensConsumed_Call { + return &EVM2EVMOffRampInterface_WatchTokensConsumed_Call{Call: _e.mock.On("WatchTokensConsumed", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchTokensConsumed_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed)) *EVM2EVMOffRampInterface_WatchTokensConsumed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchTokensConsumed_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchTokensConsumed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchTokensConsumed_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTokensConsumed) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchTokensConsumed_Call { + _c.Call.Return(run) + return _c +} + +// WatchTransmitted provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampTransmitted) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchTransmitted") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTransmitted) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTransmitted) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTransmitted) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchTransmitted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTransmitted' +type EVM2EVMOffRampInterface_WatchTransmitted_Call struct { + *mock.Call +} + +// WatchTransmitted is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampTransmitted +func (_e *EVM2EVMOffRampInterface_Expecter) WatchTransmitted(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchTransmitted_Call { + return &EVM2EVMOffRampInterface_WatchTransmitted_Call{Call: _e.mock.On("WatchTransmitted", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchTransmitted_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampTransmitted)) *EVM2EVMOffRampInterface_WatchTransmitted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampTransmitted)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchTransmitted_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchTransmitted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchTransmitted_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampTransmitted) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchTransmitted_Call { + _c.Call.Return(run) + return _c +} + +// NewEVM2EVMOffRampInterface creates a new instance of EVM2EVMOffRampInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewEVM2EVMOffRampInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *EVM2EVMOffRampInterface { + mock := &EVM2EVMOffRampInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/ccip/mocks/evm2_evm_on_ramp_interface.go b/core/gethwrappers/ccip/mocks/evm2_evm_on_ramp_interface.go new file mode 100644 index 0000000000..5758077749 --- /dev/null +++ b/core/gethwrappers/ccip/mocks/evm2_evm_on_ramp_interface.go @@ -0,0 +1,3832 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_contracts + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + evm_2_evm_onramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// EVM2EVMOnRampInterface is an autogenerated mock type for the EVM2EVMOnRampInterface type +type EVM2EVMOnRampInterface struct { + mock.Mock +} + +type EVM2EVMOnRampInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *EVM2EVMOnRampInterface) EXPECT() *EVM2EVMOnRampInterface_Expecter { + return &EVM2EVMOnRampInterface_Expecter{mock: &_m.Mock} +} + +// AcceptOwnership provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for AcceptOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_AcceptOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AcceptOwnership' +type EVM2EVMOnRampInterface_AcceptOwnership_Call struct { + *mock.Call +} + +// AcceptOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *EVM2EVMOnRampInterface_Expecter) AcceptOwnership(opts interface{}) *EVM2EVMOnRampInterface_AcceptOwnership_Call { + return &EVM2EVMOnRampInterface_AcceptOwnership_Call{Call: _e.mock.On("AcceptOwnership", opts)} +} + +func (_c *EVM2EVMOnRampInterface_AcceptOwnership_Call) Run(run func(opts *bind.TransactOpts)) *EVM2EVMOnRampInterface_AcceptOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_AcceptOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOnRampInterface_AcceptOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_AcceptOwnership_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *EVM2EVMOnRampInterface_AcceptOwnership_Call { + _c.Call.Return(run) + return _c +} + +// Address provides a mock function with given fields: +func (_m *EVM2EVMOnRampInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// EVM2EVMOnRampInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type EVM2EVMOnRampInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *EVM2EVMOnRampInterface_Expecter) Address() *EVM2EVMOnRampInterface_Address_Call { + return &EVM2EVMOnRampInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *EVM2EVMOnRampInterface_Address_Call) Run(run func()) *EVM2EVMOnRampInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_Address_Call) Return(_a0 common.Address) *EVM2EVMOnRampInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *EVM2EVMOnRampInterface_Address_Call) RunAndReturn(run func() common.Address) *EVM2EVMOnRampInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// CurrentRateLimiterState provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) CurrentRateLimiterState(opts *bind.CallOpts) (evm_2_evm_onramp.RateLimiterTokenBucket, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for CurrentRateLimiterState") + } + + var r0 evm_2_evm_onramp.RateLimiterTokenBucket + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_onramp.RateLimiterTokenBucket, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_onramp.RateLimiterTokenBucket); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_onramp.RateLimiterTokenBucket) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_CurrentRateLimiterState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CurrentRateLimiterState' +type EVM2EVMOnRampInterface_CurrentRateLimiterState_Call struct { + *mock.Call +} + +// CurrentRateLimiterState is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOnRampInterface_Expecter) CurrentRateLimiterState(opts interface{}) *EVM2EVMOnRampInterface_CurrentRateLimiterState_Call { + return &EVM2EVMOnRampInterface_CurrentRateLimiterState_Call{Call: _e.mock.On("CurrentRateLimiterState", opts)} +} + +func (_c *EVM2EVMOnRampInterface_CurrentRateLimiterState_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOnRampInterface_CurrentRateLimiterState_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_CurrentRateLimiterState_Call) Return(_a0 evm_2_evm_onramp.RateLimiterTokenBucket, _a1 error) *EVM2EVMOnRampInterface_CurrentRateLimiterState_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_CurrentRateLimiterState_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_onramp.RateLimiterTokenBucket, error)) *EVM2EVMOnRampInterface_CurrentRateLimiterState_Call { + _c.Call.Return(run) + return _c +} + +// FilterAdminSet provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) FilterAdminSet(opts *bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampAdminSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterAdminSet") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampAdminSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampAdminSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_onramp.EVM2EVMOnRampAdminSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampAdminSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_FilterAdminSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterAdminSet' +type EVM2EVMOnRampInterface_FilterAdminSet_Call struct { + *mock.Call +} + +// FilterAdminSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOnRampInterface_Expecter) FilterAdminSet(opts interface{}) *EVM2EVMOnRampInterface_FilterAdminSet_Call { + return &EVM2EVMOnRampInterface_FilterAdminSet_Call{Call: _e.mock.On("FilterAdminSet", opts)} +} + +func (_c *EVM2EVMOnRampInterface_FilterAdminSet_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOnRampInterface_FilterAdminSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterAdminSet_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampAdminSetIterator, _a1 error) *EVM2EVMOnRampInterface_FilterAdminSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterAdminSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampAdminSetIterator, error)) *EVM2EVMOnRampInterface_FilterAdminSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterCCIPSendRequested provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) FilterCCIPSendRequested(opts *bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequestedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterCCIPSendRequested") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequestedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequestedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequestedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequestedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_FilterCCIPSendRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterCCIPSendRequested' +type EVM2EVMOnRampInterface_FilterCCIPSendRequested_Call struct { + *mock.Call +} + +// FilterCCIPSendRequested is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOnRampInterface_Expecter) FilterCCIPSendRequested(opts interface{}) *EVM2EVMOnRampInterface_FilterCCIPSendRequested_Call { + return &EVM2EVMOnRampInterface_FilterCCIPSendRequested_Call{Call: _e.mock.On("FilterCCIPSendRequested", opts)} +} + +func (_c *EVM2EVMOnRampInterface_FilterCCIPSendRequested_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOnRampInterface_FilterCCIPSendRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterCCIPSendRequested_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequestedIterator, _a1 error) *EVM2EVMOnRampInterface_FilterCCIPSendRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterCCIPSendRequested_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequestedIterator, error)) *EVM2EVMOnRampInterface_FilterCCIPSendRequested_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfigChanged provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) FilterConfigChanged(opts *bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampConfigChangedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterConfigChanged") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampConfigChangedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampConfigChangedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_onramp.EVM2EVMOnRampConfigChangedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampConfigChangedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_FilterConfigChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfigChanged' +type EVM2EVMOnRampInterface_FilterConfigChanged_Call struct { + *mock.Call +} + +// FilterConfigChanged is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOnRampInterface_Expecter) FilterConfigChanged(opts interface{}) *EVM2EVMOnRampInterface_FilterConfigChanged_Call { + return &EVM2EVMOnRampInterface_FilterConfigChanged_Call{Call: _e.mock.On("FilterConfigChanged", opts)} +} + +func (_c *EVM2EVMOnRampInterface_FilterConfigChanged_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOnRampInterface_FilterConfigChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterConfigChanged_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampConfigChangedIterator, _a1 error) *EVM2EVMOnRampInterface_FilterConfigChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterConfigChanged_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampConfigChangedIterator, error)) *EVM2EVMOnRampInterface_FilterConfigChanged_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfigSet provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) FilterConfigSet(opts *bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampConfigSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterConfigSet") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampConfigSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampConfigSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_onramp.EVM2EVMOnRampConfigSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampConfigSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_FilterConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfigSet' +type EVM2EVMOnRampInterface_FilterConfigSet_Call struct { + *mock.Call +} + +// FilterConfigSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOnRampInterface_Expecter) FilterConfigSet(opts interface{}) *EVM2EVMOnRampInterface_FilterConfigSet_Call { + return &EVM2EVMOnRampInterface_FilterConfigSet_Call{Call: _e.mock.On("FilterConfigSet", opts)} +} + +func (_c *EVM2EVMOnRampInterface_FilterConfigSet_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOnRampInterface_FilterConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterConfigSet_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampConfigSetIterator, _a1 error) *EVM2EVMOnRampInterface_FilterConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterConfigSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampConfigSetIterator, error)) *EVM2EVMOnRampInterface_FilterConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterFeeConfigSet provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) FilterFeeConfigSet(opts *bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterFeeConfigSet") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_FilterFeeConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterFeeConfigSet' +type EVM2EVMOnRampInterface_FilterFeeConfigSet_Call struct { + *mock.Call +} + +// FilterFeeConfigSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOnRampInterface_Expecter) FilterFeeConfigSet(opts interface{}) *EVM2EVMOnRampInterface_FilterFeeConfigSet_Call { + return &EVM2EVMOnRampInterface_FilterFeeConfigSet_Call{Call: _e.mock.On("FilterFeeConfigSet", opts)} +} + +func (_c *EVM2EVMOnRampInterface_FilterFeeConfigSet_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOnRampInterface_FilterFeeConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterFeeConfigSet_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSetIterator, _a1 error) *EVM2EVMOnRampInterface_FilterFeeConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterFeeConfigSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSetIterator, error)) *EVM2EVMOnRampInterface_FilterFeeConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterNopPaid provides a mock function with given fields: opts, nop +func (_m *EVM2EVMOnRampInterface) FilterNopPaid(opts *bind.FilterOpts, nop []common.Address) (*evm_2_evm_onramp.EVM2EVMOnRampNopPaidIterator, error) { + ret := _m.Called(opts, nop) + + if len(ret) == 0 { + panic("no return value specified for FilterNopPaid") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampNopPaidIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*evm_2_evm_onramp.EVM2EVMOnRampNopPaidIterator, error)); ok { + return rf(opts, nop) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *evm_2_evm_onramp.EVM2EVMOnRampNopPaidIterator); ok { + r0 = rf(opts, nop) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampNopPaidIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, nop) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_FilterNopPaid_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterNopPaid' +type EVM2EVMOnRampInterface_FilterNopPaid_Call struct { + *mock.Call +} + +// FilterNopPaid is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - nop []common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) FilterNopPaid(opts interface{}, nop interface{}) *EVM2EVMOnRampInterface_FilterNopPaid_Call { + return &EVM2EVMOnRampInterface_FilterNopPaid_Call{Call: _e.mock.On("FilterNopPaid", opts, nop)} +} + +func (_c *EVM2EVMOnRampInterface_FilterNopPaid_Call) Run(run func(opts *bind.FilterOpts, nop []common.Address)) *EVM2EVMOnRampInterface_FilterNopPaid_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterNopPaid_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampNopPaidIterator, _a1 error) *EVM2EVMOnRampInterface_FilterNopPaid_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterNopPaid_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*evm_2_evm_onramp.EVM2EVMOnRampNopPaidIterator, error)) *EVM2EVMOnRampInterface_FilterNopPaid_Call { + _c.Call.Return(run) + return _c +} + +// FilterNopsSet provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) FilterNopsSet(opts *bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampNopsSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterNopsSet") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampNopsSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampNopsSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_onramp.EVM2EVMOnRampNopsSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampNopsSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_FilterNopsSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterNopsSet' +type EVM2EVMOnRampInterface_FilterNopsSet_Call struct { + *mock.Call +} + +// FilterNopsSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOnRampInterface_Expecter) FilterNopsSet(opts interface{}) *EVM2EVMOnRampInterface_FilterNopsSet_Call { + return &EVM2EVMOnRampInterface_FilterNopsSet_Call{Call: _e.mock.On("FilterNopsSet", opts)} +} + +func (_c *EVM2EVMOnRampInterface_FilterNopsSet_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOnRampInterface_FilterNopsSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterNopsSet_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampNopsSetIterator, _a1 error) *EVM2EVMOnRampInterface_FilterNopsSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterNopsSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampNopsSetIterator, error)) *EVM2EVMOnRampInterface_FilterNopsSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferRequested provides a mock function with given fields: opts, from, to +func (_m *EVM2EVMOnRampInterface) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequestedIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferRequested") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequestedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequestedIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequestedIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequestedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_FilterOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferRequested' +type EVM2EVMOnRampInterface_FilterOwnershipTransferRequested_Call struct { + *mock.Call +} + +// FilterOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) FilterOwnershipTransferRequested(opts interface{}, from interface{}, to interface{}) *EVM2EVMOnRampInterface_FilterOwnershipTransferRequested_Call { + return &EVM2EVMOnRampInterface_FilterOwnershipTransferRequested_Call{Call: _e.mock.On("FilterOwnershipTransferRequested", opts, from, to)} +} + +func (_c *EVM2EVMOnRampInterface_FilterOwnershipTransferRequested_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *EVM2EVMOnRampInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterOwnershipTransferRequested_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequestedIterator, _a1 error) *EVM2EVMOnRampInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequestedIterator, error)) *EVM2EVMOnRampInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferred provides a mock function with given fields: opts, from, to +func (_m *EVM2EVMOnRampInterface) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferredIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferred") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferredIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferredIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferredIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferredIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_FilterOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferred' +type EVM2EVMOnRampInterface_FilterOwnershipTransferred_Call struct { + *mock.Call +} + +// FilterOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) FilterOwnershipTransferred(opts interface{}, from interface{}, to interface{}) *EVM2EVMOnRampInterface_FilterOwnershipTransferred_Call { + return &EVM2EVMOnRampInterface_FilterOwnershipTransferred_Call{Call: _e.mock.On("FilterOwnershipTransferred", opts, from, to)} +} + +func (_c *EVM2EVMOnRampInterface_FilterOwnershipTransferred_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *EVM2EVMOnRampInterface_FilterOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterOwnershipTransferred_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferredIterator, _a1 error) *EVM2EVMOnRampInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterOwnershipTransferred_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferredIterator, error)) *EVM2EVMOnRampInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// FilterTokenTransferFeeConfigDeleted provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterTokenTransferFeeConfigDeleted") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTokenTransferFeeConfigDeleted' +type EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigDeleted_Call struct { + *mock.Call +} + +// FilterTokenTransferFeeConfigDeleted is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOnRampInterface_Expecter) FilterTokenTransferFeeConfigDeleted(opts interface{}) *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigDeleted_Call { + return &EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigDeleted_Call{Call: _e.mock.On("FilterTokenTransferFeeConfigDeleted", opts)} +} + +func (_c *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigDeleted_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigDeleted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigDeleted_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator, _a1 error) *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigDeleted_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeletedIterator, error)) *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(run) + return _c +} + +// FilterTokenTransferFeeConfigSet provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) FilterTokenTransferFeeConfigSet(opts *bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterTokenTransferFeeConfigSet") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTokenTransferFeeConfigSet' +type EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigSet_Call struct { + *mock.Call +} + +// FilterTokenTransferFeeConfigSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOnRampInterface_Expecter) FilterTokenTransferFeeConfigSet(opts interface{}) *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigSet_Call { + return &EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigSet_Call{Call: _e.mock.On("FilterTokenTransferFeeConfigSet", opts)} +} + +func (_c *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigSet_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigSet_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSetIterator, _a1 error) *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSetIterator, error)) *EVM2EVMOnRampInterface_FilterTokenTransferFeeConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterTokensConsumed provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) FilterTokensConsumed(opts *bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampTokensConsumedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterTokensConsumed") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampTokensConsumedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampTokensConsumedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_FilterTokensConsumed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTokensConsumed' +type EVM2EVMOnRampInterface_FilterTokensConsumed_Call struct { + *mock.Call +} + +// FilterTokensConsumed is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOnRampInterface_Expecter) FilterTokensConsumed(opts interface{}) *EVM2EVMOnRampInterface_FilterTokensConsumed_Call { + return &EVM2EVMOnRampInterface_FilterTokensConsumed_Call{Call: _e.mock.On("FilterTokensConsumed", opts)} +} + +func (_c *EVM2EVMOnRampInterface_FilterTokensConsumed_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOnRampInterface_FilterTokensConsumed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterTokensConsumed_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumedIterator, _a1 error) *EVM2EVMOnRampInterface_FilterTokensConsumed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_FilterTokensConsumed_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_onramp.EVM2EVMOnRampTokensConsumedIterator, error)) *EVM2EVMOnRampInterface_FilterTokensConsumed_Call { + _c.Call.Return(run) + return _c +} + +// ForwardFromRouter provides a mock function with given fields: opts, destChainSelector, message, feeTokenAmount, originalSender +func (_m *EVM2EVMOnRampInterface) ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message evm_2_evm_onramp.ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, destChainSelector, message, feeTokenAmount, originalSender) + + if len(ret) == 0 { + panic("no return value specified for ForwardFromRouter") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, uint64, evm_2_evm_onramp.ClientEVM2AnyMessage, *big.Int, common.Address) (*types.Transaction, error)); ok { + return rf(opts, destChainSelector, message, feeTokenAmount, originalSender) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, uint64, evm_2_evm_onramp.ClientEVM2AnyMessage, *big.Int, common.Address) *types.Transaction); ok { + r0 = rf(opts, destChainSelector, message, feeTokenAmount, originalSender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, uint64, evm_2_evm_onramp.ClientEVM2AnyMessage, *big.Int, common.Address) error); ok { + r1 = rf(opts, destChainSelector, message, feeTokenAmount, originalSender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ForwardFromRouter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ForwardFromRouter' +type EVM2EVMOnRampInterface_ForwardFromRouter_Call struct { + *mock.Call +} + +// ForwardFromRouter is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - destChainSelector uint64 +// - message evm_2_evm_onramp.ClientEVM2AnyMessage +// - feeTokenAmount *big.Int +// - originalSender common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) ForwardFromRouter(opts interface{}, destChainSelector interface{}, message interface{}, feeTokenAmount interface{}, originalSender interface{}) *EVM2EVMOnRampInterface_ForwardFromRouter_Call { + return &EVM2EVMOnRampInterface_ForwardFromRouter_Call{Call: _e.mock.On("ForwardFromRouter", opts, destChainSelector, message, feeTokenAmount, originalSender)} +} + +func (_c *EVM2EVMOnRampInterface_ForwardFromRouter_Call) Run(run func(opts *bind.TransactOpts, destChainSelector uint64, message evm_2_evm_onramp.ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address)) *EVM2EVMOnRampInterface_ForwardFromRouter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(uint64), args[2].(evm_2_evm_onramp.ClientEVM2AnyMessage), args[3].(*big.Int), args[4].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ForwardFromRouter_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOnRampInterface_ForwardFromRouter_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ForwardFromRouter_Call) RunAndReturn(run func(*bind.TransactOpts, uint64, evm_2_evm_onramp.ClientEVM2AnyMessage, *big.Int, common.Address) (*types.Transaction, error)) *EVM2EVMOnRampInterface_ForwardFromRouter_Call { + _c.Call.Return(run) + return _c +} + +// GetDynamicConfig provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) GetDynamicConfig(opts *bind.CallOpts) (evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetDynamicConfig") + } + + var r0 evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_GetDynamicConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDynamicConfig' +type EVM2EVMOnRampInterface_GetDynamicConfig_Call struct { + *mock.Call +} + +// GetDynamicConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOnRampInterface_Expecter) GetDynamicConfig(opts interface{}) *EVM2EVMOnRampInterface_GetDynamicConfig_Call { + return &EVM2EVMOnRampInterface_GetDynamicConfig_Call{Call: _e.mock.On("GetDynamicConfig", opts)} +} + +func (_c *EVM2EVMOnRampInterface_GetDynamicConfig_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOnRampInterface_GetDynamicConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetDynamicConfig_Call) Return(_a0 evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig, _a1 error) *EVM2EVMOnRampInterface_GetDynamicConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetDynamicConfig_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig, error)) *EVM2EVMOnRampInterface_GetDynamicConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetExpectedNextSequenceNumber provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetExpectedNextSequenceNumber") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (uint64, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) uint64); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_GetExpectedNextSequenceNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExpectedNextSequenceNumber' +type EVM2EVMOnRampInterface_GetExpectedNextSequenceNumber_Call struct { + *mock.Call +} + +// GetExpectedNextSequenceNumber is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOnRampInterface_Expecter) GetExpectedNextSequenceNumber(opts interface{}) *EVM2EVMOnRampInterface_GetExpectedNextSequenceNumber_Call { + return &EVM2EVMOnRampInterface_GetExpectedNextSequenceNumber_Call{Call: _e.mock.On("GetExpectedNextSequenceNumber", opts)} +} + +func (_c *EVM2EVMOnRampInterface_GetExpectedNextSequenceNumber_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOnRampInterface_GetExpectedNextSequenceNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetExpectedNextSequenceNumber_Call) Return(_a0 uint64, _a1 error) *EVM2EVMOnRampInterface_GetExpectedNextSequenceNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetExpectedNextSequenceNumber_Call) RunAndReturn(run func(*bind.CallOpts) (uint64, error)) *EVM2EVMOnRampInterface_GetExpectedNextSequenceNumber_Call { + _c.Call.Return(run) + return _c +} + +// GetFee provides a mock function with given fields: opts, destChainSelector, message +func (_m *EVM2EVMOnRampInterface) GetFee(opts *bind.CallOpts, destChainSelector uint64, message evm_2_evm_onramp.ClientEVM2AnyMessage) (*big.Int, error) { + ret := _m.Called(opts, destChainSelector, message) + + if len(ret) == 0 { + panic("no return value specified for GetFee") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, evm_2_evm_onramp.ClientEVM2AnyMessage) (*big.Int, error)); ok { + return rf(opts, destChainSelector, message) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, evm_2_evm_onramp.ClientEVM2AnyMessage) *big.Int); ok { + r0 = rf(opts, destChainSelector, message) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, evm_2_evm_onramp.ClientEVM2AnyMessage) error); ok { + r1 = rf(opts, destChainSelector, message) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_GetFee_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFee' +type EVM2EVMOnRampInterface_GetFee_Call struct { + *mock.Call +} + +// GetFee is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +// - message evm_2_evm_onramp.ClientEVM2AnyMessage +func (_e *EVM2EVMOnRampInterface_Expecter) GetFee(opts interface{}, destChainSelector interface{}, message interface{}) *EVM2EVMOnRampInterface_GetFee_Call { + return &EVM2EVMOnRampInterface_GetFee_Call{Call: _e.mock.On("GetFee", opts, destChainSelector, message)} +} + +func (_c *EVM2EVMOnRampInterface_GetFee_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, message evm_2_evm_onramp.ClientEVM2AnyMessage)) *EVM2EVMOnRampInterface_GetFee_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(evm_2_evm_onramp.ClientEVM2AnyMessage)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetFee_Call) Return(_a0 *big.Int, _a1 error) *EVM2EVMOnRampInterface_GetFee_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetFee_Call) RunAndReturn(run func(*bind.CallOpts, uint64, evm_2_evm_onramp.ClientEVM2AnyMessage) (*big.Int, error)) *EVM2EVMOnRampInterface_GetFee_Call { + _c.Call.Return(run) + return _c +} + +// GetFeeTokenConfig provides a mock function with given fields: opts, token +func (_m *EVM2EVMOnRampInterface) GetFeeTokenConfig(opts *bind.CallOpts, token common.Address) (evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfig, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for GetFeeTokenConfig") + } + + var r0 evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfig, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfig); ok { + r0 = rf(opts, token) + } else { + r0 = ret.Get(0).(evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_GetFeeTokenConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFeeTokenConfig' +type EVM2EVMOnRampInterface_GetFeeTokenConfig_Call struct { + *mock.Call +} + +// GetFeeTokenConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +// - token common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) GetFeeTokenConfig(opts interface{}, token interface{}) *EVM2EVMOnRampInterface_GetFeeTokenConfig_Call { + return &EVM2EVMOnRampInterface_GetFeeTokenConfig_Call{Call: _e.mock.On("GetFeeTokenConfig", opts, token)} +} + +func (_c *EVM2EVMOnRampInterface_GetFeeTokenConfig_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *EVM2EVMOnRampInterface_GetFeeTokenConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetFeeTokenConfig_Call) Return(_a0 evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfig, _a1 error) *EVM2EVMOnRampInterface_GetFeeTokenConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetFeeTokenConfig_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfig, error)) *EVM2EVMOnRampInterface_GetFeeTokenConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetNopFeesJuels provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) GetNopFeesJuels(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetNopFeesJuels") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_GetNopFeesJuels_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetNopFeesJuels' +type EVM2EVMOnRampInterface_GetNopFeesJuels_Call struct { + *mock.Call +} + +// GetNopFeesJuels is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOnRampInterface_Expecter) GetNopFeesJuels(opts interface{}) *EVM2EVMOnRampInterface_GetNopFeesJuels_Call { + return &EVM2EVMOnRampInterface_GetNopFeesJuels_Call{Call: _e.mock.On("GetNopFeesJuels", opts)} +} + +func (_c *EVM2EVMOnRampInterface_GetNopFeesJuels_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOnRampInterface_GetNopFeesJuels_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetNopFeesJuels_Call) Return(_a0 *big.Int, _a1 error) *EVM2EVMOnRampInterface_GetNopFeesJuels_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetNopFeesJuels_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *EVM2EVMOnRampInterface_GetNopFeesJuels_Call { + _c.Call.Return(run) + return _c +} + +// GetNops provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) GetNops(opts *bind.CallOpts) (evm_2_evm_onramp.GetNops, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetNops") + } + + var r0 evm_2_evm_onramp.GetNops + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_onramp.GetNops, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_onramp.GetNops); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_onramp.GetNops) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_GetNops_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetNops' +type EVM2EVMOnRampInterface_GetNops_Call struct { + *mock.Call +} + +// GetNops is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOnRampInterface_Expecter) GetNops(opts interface{}) *EVM2EVMOnRampInterface_GetNops_Call { + return &EVM2EVMOnRampInterface_GetNops_Call{Call: _e.mock.On("GetNops", opts)} +} + +func (_c *EVM2EVMOnRampInterface_GetNops_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOnRampInterface_GetNops_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetNops_Call) Return(_a0 evm_2_evm_onramp.GetNops, _a1 error) *EVM2EVMOnRampInterface_GetNops_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetNops_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_onramp.GetNops, error)) *EVM2EVMOnRampInterface_GetNops_Call { + _c.Call.Return(run) + return _c +} + +// GetPoolBySourceToken provides a mock function with given fields: opts, arg0, sourceToken +func (_m *EVM2EVMOnRampInterface) GetPoolBySourceToken(opts *bind.CallOpts, arg0 uint64, sourceToken common.Address) (common.Address, error) { + ret := _m.Called(opts, arg0, sourceToken) + + if len(ret) == 0 { + panic("no return value specified for GetPoolBySourceToken") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address) (common.Address, error)); ok { + return rf(opts, arg0, sourceToken) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address) common.Address); ok { + r0 = rf(opts, arg0, sourceToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, common.Address) error); ok { + r1 = rf(opts, arg0, sourceToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_GetPoolBySourceToken_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPoolBySourceToken' +type EVM2EVMOnRampInterface_GetPoolBySourceToken_Call struct { + *mock.Call +} + +// GetPoolBySourceToken is a helper method to define mock.On call +// - opts *bind.CallOpts +// - arg0 uint64 +// - sourceToken common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) GetPoolBySourceToken(opts interface{}, arg0 interface{}, sourceToken interface{}) *EVM2EVMOnRampInterface_GetPoolBySourceToken_Call { + return &EVM2EVMOnRampInterface_GetPoolBySourceToken_Call{Call: _e.mock.On("GetPoolBySourceToken", opts, arg0, sourceToken)} +} + +func (_c *EVM2EVMOnRampInterface_GetPoolBySourceToken_Call) Run(run func(opts *bind.CallOpts, arg0 uint64, sourceToken common.Address)) *EVM2EVMOnRampInterface_GetPoolBySourceToken_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetPoolBySourceToken_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOnRampInterface_GetPoolBySourceToken_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetPoolBySourceToken_Call) RunAndReturn(run func(*bind.CallOpts, uint64, common.Address) (common.Address, error)) *EVM2EVMOnRampInterface_GetPoolBySourceToken_Call { + _c.Call.Return(run) + return _c +} + +// GetSenderNonce provides a mock function with given fields: opts, sender +func (_m *EVM2EVMOnRampInterface) GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) { + ret := _m.Called(opts, sender) + + if len(ret) == 0 { + panic("no return value specified for GetSenderNonce") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (uint64, error)); ok { + return rf(opts, sender) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) uint64); ok { + r0 = rf(opts, sender) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_GetSenderNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSenderNonce' +type EVM2EVMOnRampInterface_GetSenderNonce_Call struct { + *mock.Call +} + +// GetSenderNonce is a helper method to define mock.On call +// - opts *bind.CallOpts +// - sender common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) GetSenderNonce(opts interface{}, sender interface{}) *EVM2EVMOnRampInterface_GetSenderNonce_Call { + return &EVM2EVMOnRampInterface_GetSenderNonce_Call{Call: _e.mock.On("GetSenderNonce", opts, sender)} +} + +func (_c *EVM2EVMOnRampInterface_GetSenderNonce_Call) Run(run func(opts *bind.CallOpts, sender common.Address)) *EVM2EVMOnRampInterface_GetSenderNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetSenderNonce_Call) Return(_a0 uint64, _a1 error) *EVM2EVMOnRampInterface_GetSenderNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetSenderNonce_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (uint64, error)) *EVM2EVMOnRampInterface_GetSenderNonce_Call { + _c.Call.Return(run) + return _c +} + +// GetStaticConfig provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) GetStaticConfig(opts *bind.CallOpts) (evm_2_evm_onramp.EVM2EVMOnRampStaticConfig, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetStaticConfig") + } + + var r0 evm_2_evm_onramp.EVM2EVMOnRampStaticConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_onramp.EVM2EVMOnRampStaticConfig, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_onramp.EVM2EVMOnRampStaticConfig); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_onramp.EVM2EVMOnRampStaticConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_GetStaticConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStaticConfig' +type EVM2EVMOnRampInterface_GetStaticConfig_Call struct { + *mock.Call +} + +// GetStaticConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOnRampInterface_Expecter) GetStaticConfig(opts interface{}) *EVM2EVMOnRampInterface_GetStaticConfig_Call { + return &EVM2EVMOnRampInterface_GetStaticConfig_Call{Call: _e.mock.On("GetStaticConfig", opts)} +} + +func (_c *EVM2EVMOnRampInterface_GetStaticConfig_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOnRampInterface_GetStaticConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetStaticConfig_Call) Return(_a0 evm_2_evm_onramp.EVM2EVMOnRampStaticConfig, _a1 error) *EVM2EVMOnRampInterface_GetStaticConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetStaticConfig_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_onramp.EVM2EVMOnRampStaticConfig, error)) *EVM2EVMOnRampInterface_GetStaticConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetSupportedTokens provides a mock function with given fields: opts, arg0 +func (_m *EVM2EVMOnRampInterface) GetSupportedTokens(opts *bind.CallOpts, arg0 uint64) ([]common.Address, error) { + ret := _m.Called(opts, arg0) + + if len(ret) == 0 { + panic("no return value specified for GetSupportedTokens") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) ([]common.Address, error)); ok { + return rf(opts, arg0) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) []common.Address); ok { + r0 = rf(opts, arg0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, arg0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_GetSupportedTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSupportedTokens' +type EVM2EVMOnRampInterface_GetSupportedTokens_Call struct { + *mock.Call +} + +// GetSupportedTokens is a helper method to define mock.On call +// - opts *bind.CallOpts +// - arg0 uint64 +func (_e *EVM2EVMOnRampInterface_Expecter) GetSupportedTokens(opts interface{}, arg0 interface{}) *EVM2EVMOnRampInterface_GetSupportedTokens_Call { + return &EVM2EVMOnRampInterface_GetSupportedTokens_Call{Call: _e.mock.On("GetSupportedTokens", opts, arg0)} +} + +func (_c *EVM2EVMOnRampInterface_GetSupportedTokens_Call) Run(run func(opts *bind.CallOpts, arg0 uint64)) *EVM2EVMOnRampInterface_GetSupportedTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetSupportedTokens_Call) Return(_a0 []common.Address, _a1 error) *EVM2EVMOnRampInterface_GetSupportedTokens_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetSupportedTokens_Call) RunAndReturn(run func(*bind.CallOpts, uint64) ([]common.Address, error)) *EVM2EVMOnRampInterface_GetSupportedTokens_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenLimitAdmin provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetTokenLimitAdmin") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_GetTokenLimitAdmin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenLimitAdmin' +type EVM2EVMOnRampInterface_GetTokenLimitAdmin_Call struct { + *mock.Call +} + +// GetTokenLimitAdmin is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOnRampInterface_Expecter) GetTokenLimitAdmin(opts interface{}) *EVM2EVMOnRampInterface_GetTokenLimitAdmin_Call { + return &EVM2EVMOnRampInterface_GetTokenLimitAdmin_Call{Call: _e.mock.On("GetTokenLimitAdmin", opts)} +} + +func (_c *EVM2EVMOnRampInterface_GetTokenLimitAdmin_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOnRampInterface_GetTokenLimitAdmin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetTokenLimitAdmin_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOnRampInterface_GetTokenLimitAdmin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetTokenLimitAdmin_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *EVM2EVMOnRampInterface_GetTokenLimitAdmin_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenTransferFeeConfig provides a mock function with given fields: opts, token +func (_m *EVM2EVMOnRampInterface) GetTokenTransferFeeConfig(opts *bind.CallOpts, token common.Address) (evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfig, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for GetTokenTransferFeeConfig") + } + + var r0 evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfig, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfig); ok { + r0 = rf(opts, token) + } else { + r0 = ret.Get(0).(evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_GetTokenTransferFeeConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenTransferFeeConfig' +type EVM2EVMOnRampInterface_GetTokenTransferFeeConfig_Call struct { + *mock.Call +} + +// GetTokenTransferFeeConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +// - token common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) GetTokenTransferFeeConfig(opts interface{}, token interface{}) *EVM2EVMOnRampInterface_GetTokenTransferFeeConfig_Call { + return &EVM2EVMOnRampInterface_GetTokenTransferFeeConfig_Call{Call: _e.mock.On("GetTokenTransferFeeConfig", opts, token)} +} + +func (_c *EVM2EVMOnRampInterface_GetTokenTransferFeeConfig_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *EVM2EVMOnRampInterface_GetTokenTransferFeeConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetTokenTransferFeeConfig_Call) Return(_a0 evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfig, _a1 error) *EVM2EVMOnRampInterface_GetTokenTransferFeeConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_GetTokenTransferFeeConfig_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfig, error)) *EVM2EVMOnRampInterface_GetTokenTransferFeeConfig_Call { + _c.Call.Return(run) + return _c +} + +// LinkAvailableForPayment provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LinkAvailableForPayment") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_LinkAvailableForPayment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LinkAvailableForPayment' +type EVM2EVMOnRampInterface_LinkAvailableForPayment_Call struct { + *mock.Call +} + +// LinkAvailableForPayment is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOnRampInterface_Expecter) LinkAvailableForPayment(opts interface{}) *EVM2EVMOnRampInterface_LinkAvailableForPayment_Call { + return &EVM2EVMOnRampInterface_LinkAvailableForPayment_Call{Call: _e.mock.On("LinkAvailableForPayment", opts)} +} + +func (_c *EVM2EVMOnRampInterface_LinkAvailableForPayment_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOnRampInterface_LinkAvailableForPayment_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_LinkAvailableForPayment_Call) Return(_a0 *big.Int, _a1 error) *EVM2EVMOnRampInterface_LinkAvailableForPayment_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_LinkAvailableForPayment_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *EVM2EVMOnRampInterface_LinkAvailableForPayment_Call { + _c.Call.Return(run) + return _c +} + +// Owner provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) Owner(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Owner") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_Owner_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Owner' +type EVM2EVMOnRampInterface_Owner_Call struct { + *mock.Call +} + +// Owner is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOnRampInterface_Expecter) Owner(opts interface{}) *EVM2EVMOnRampInterface_Owner_Call { + return &EVM2EVMOnRampInterface_Owner_Call{Call: _e.mock.On("Owner", opts)} +} + +func (_c *EVM2EVMOnRampInterface_Owner_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOnRampInterface_Owner_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_Owner_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOnRampInterface_Owner_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_Owner_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *EVM2EVMOnRampInterface_Owner_Call { + _c.Call.Return(run) + return _c +} + +// ParseAdminSet provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseAdminSet(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampAdminSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseAdminSet") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampAdminSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampAdminSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_onramp.EVM2EVMOnRampAdminSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampAdminSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseAdminSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseAdminSet' +type EVM2EVMOnRampInterface_ParseAdminSet_Call struct { + *mock.Call +} + +// ParseAdminSet is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseAdminSet(log interface{}) *EVM2EVMOnRampInterface_ParseAdminSet_Call { + return &EVM2EVMOnRampInterface_ParseAdminSet_Call{Call: _e.mock.On("ParseAdminSet", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseAdminSet_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseAdminSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseAdminSet_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampAdminSet, _a1 error) *EVM2EVMOnRampInterface_ParseAdminSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseAdminSet_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampAdminSet, error)) *EVM2EVMOnRampInterface_ParseAdminSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseCCIPSendRequested provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseCCIPSendRequested(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseCCIPSendRequested") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseCCIPSendRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseCCIPSendRequested' +type EVM2EVMOnRampInterface_ParseCCIPSendRequested_Call struct { + *mock.Call +} + +// ParseCCIPSendRequested is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseCCIPSendRequested(log interface{}) *EVM2EVMOnRampInterface_ParseCCIPSendRequested_Call { + return &EVM2EVMOnRampInterface_ParseCCIPSendRequested_Call{Call: _e.mock.On("ParseCCIPSendRequested", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseCCIPSendRequested_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseCCIPSendRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseCCIPSendRequested_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested, _a1 error) *EVM2EVMOnRampInterface_ParseCCIPSendRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseCCIPSendRequested_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested, error)) *EVM2EVMOnRampInterface_ParseCCIPSendRequested_Call { + _c.Call.Return(run) + return _c +} + +// ParseConfigChanged provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseConfigChanged(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampConfigChanged, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseConfigChanged") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampConfigChanged + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampConfigChanged, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_onramp.EVM2EVMOnRampConfigChanged); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampConfigChanged) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseConfigChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseConfigChanged' +type EVM2EVMOnRampInterface_ParseConfigChanged_Call struct { + *mock.Call +} + +// ParseConfigChanged is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseConfigChanged(log interface{}) *EVM2EVMOnRampInterface_ParseConfigChanged_Call { + return &EVM2EVMOnRampInterface_ParseConfigChanged_Call{Call: _e.mock.On("ParseConfigChanged", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseConfigChanged_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseConfigChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseConfigChanged_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampConfigChanged, _a1 error) *EVM2EVMOnRampInterface_ParseConfigChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseConfigChanged_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampConfigChanged, error)) *EVM2EVMOnRampInterface_ParseConfigChanged_Call { + _c.Call.Return(run) + return _c +} + +// ParseConfigSet provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseConfigSet(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampConfigSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseConfigSet") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampConfigSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampConfigSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_onramp.EVM2EVMOnRampConfigSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampConfigSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseConfigSet' +type EVM2EVMOnRampInterface_ParseConfigSet_Call struct { + *mock.Call +} + +// ParseConfigSet is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseConfigSet(log interface{}) *EVM2EVMOnRampInterface_ParseConfigSet_Call { + return &EVM2EVMOnRampInterface_ParseConfigSet_Call{Call: _e.mock.On("ParseConfigSet", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseConfigSet_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseConfigSet_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampConfigSet, _a1 error) *EVM2EVMOnRampInterface_ParseConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseConfigSet_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampConfigSet, error)) *EVM2EVMOnRampInterface_ParseConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseFeeConfigSet provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseFeeConfigSet(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseFeeConfigSet") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseFeeConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseFeeConfigSet' +type EVM2EVMOnRampInterface_ParseFeeConfigSet_Call struct { + *mock.Call +} + +// ParseFeeConfigSet is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseFeeConfigSet(log interface{}) *EVM2EVMOnRampInterface_ParseFeeConfigSet_Call { + return &EVM2EVMOnRampInterface_ParseFeeConfigSet_Call{Call: _e.mock.On("ParseFeeConfigSet", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseFeeConfigSet_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseFeeConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseFeeConfigSet_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet, _a1 error) *EVM2EVMOnRampInterface_ParseFeeConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseFeeConfigSet_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet, error)) *EVM2EVMOnRampInterface_ParseFeeConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type EVM2EVMOnRampInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseLog(log interface{}) *EVM2EVMOnRampInterface_ParseLog_Call { + return &EVM2EVMOnRampInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseLog_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *EVM2EVMOnRampInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *EVM2EVMOnRampInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseNopPaid provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseNopPaid(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampNopPaid, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseNopPaid") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampNopPaid + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampNopPaid, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_onramp.EVM2EVMOnRampNopPaid); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampNopPaid) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseNopPaid_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseNopPaid' +type EVM2EVMOnRampInterface_ParseNopPaid_Call struct { + *mock.Call +} + +// ParseNopPaid is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseNopPaid(log interface{}) *EVM2EVMOnRampInterface_ParseNopPaid_Call { + return &EVM2EVMOnRampInterface_ParseNopPaid_Call{Call: _e.mock.On("ParseNopPaid", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseNopPaid_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseNopPaid_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseNopPaid_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampNopPaid, _a1 error) *EVM2EVMOnRampInterface_ParseNopPaid_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseNopPaid_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampNopPaid, error)) *EVM2EVMOnRampInterface_ParseNopPaid_Call { + _c.Call.Return(run) + return _c +} + +// ParseNopsSet provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseNopsSet(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampNopsSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseNopsSet") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampNopsSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampNopsSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_onramp.EVM2EVMOnRampNopsSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampNopsSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseNopsSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseNopsSet' +type EVM2EVMOnRampInterface_ParseNopsSet_Call struct { + *mock.Call +} + +// ParseNopsSet is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseNopsSet(log interface{}) *EVM2EVMOnRampInterface_ParseNopsSet_Call { + return &EVM2EVMOnRampInterface_ParseNopsSet_Call{Call: _e.mock.On("ParseNopsSet", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseNopsSet_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseNopsSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseNopsSet_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampNopsSet, _a1 error) *EVM2EVMOnRampInterface_ParseNopsSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseNopsSet_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampNopsSet, error)) *EVM2EVMOnRampInterface_ParseNopsSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferRequested provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseOwnershipTransferRequested(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferRequested") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferRequested' +type EVM2EVMOnRampInterface_ParseOwnershipTransferRequested_Call struct { + *mock.Call +} + +// ParseOwnershipTransferRequested is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseOwnershipTransferRequested(log interface{}) *EVM2EVMOnRampInterface_ParseOwnershipTransferRequested_Call { + return &EVM2EVMOnRampInterface_ParseOwnershipTransferRequested_Call{Call: _e.mock.On("ParseOwnershipTransferRequested", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseOwnershipTransferRequested_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseOwnershipTransferRequested_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested, _a1 error) *EVM2EVMOnRampInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseOwnershipTransferRequested_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested, error)) *EVM2EVMOnRampInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferred provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseOwnershipTransferred(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferred") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferred' +type EVM2EVMOnRampInterface_ParseOwnershipTransferred_Call struct { + *mock.Call +} + +// ParseOwnershipTransferred is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseOwnershipTransferred(log interface{}) *EVM2EVMOnRampInterface_ParseOwnershipTransferred_Call { + return &EVM2EVMOnRampInterface_ParseOwnershipTransferred_Call{Call: _e.mock.On("ParseOwnershipTransferred", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseOwnershipTransferred_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseOwnershipTransferred_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred, _a1 error) *EVM2EVMOnRampInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseOwnershipTransferred_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred, error)) *EVM2EVMOnRampInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// ParseTokenTransferFeeConfigDeleted provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseTokenTransferFeeConfigDeleted(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTokenTransferFeeConfigDeleted") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTokenTransferFeeConfigDeleted' +type EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigDeleted_Call struct { + *mock.Call +} + +// ParseTokenTransferFeeConfigDeleted is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseTokenTransferFeeConfigDeleted(log interface{}) *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigDeleted_Call { + return &EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigDeleted_Call{Call: _e.mock.On("ParseTokenTransferFeeConfigDeleted", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigDeleted_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigDeleted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigDeleted_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted, _a1 error) *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigDeleted_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted, error)) *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(run) + return _c +} + +// ParseTokenTransferFeeConfigSet provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseTokenTransferFeeConfigSet(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTokenTransferFeeConfigSet") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTokenTransferFeeConfigSet' +type EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigSet_Call struct { + *mock.Call +} + +// ParseTokenTransferFeeConfigSet is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseTokenTransferFeeConfigSet(log interface{}) *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigSet_Call { + return &EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigSet_Call{Call: _e.mock.On("ParseTokenTransferFeeConfigSet", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigSet_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigSet_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet, _a1 error) *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigSet_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet, error)) *EVM2EVMOnRampInterface_ParseTokenTransferFeeConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseTokensConsumed provides a mock function with given fields: log +func (_m *EVM2EVMOnRampInterface) ParseTokensConsumed(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTokensConsumed") + } + + var r0 *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_ParseTokensConsumed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTokensConsumed' +type EVM2EVMOnRampInterface_ParseTokensConsumed_Call struct { + *mock.Call +} + +// ParseTokensConsumed is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOnRampInterface_Expecter) ParseTokensConsumed(log interface{}) *EVM2EVMOnRampInterface_ParseTokensConsumed_Call { + return &EVM2EVMOnRampInterface_ParseTokensConsumed_Call{Call: _e.mock.On("ParseTokensConsumed", log)} +} + +func (_c *EVM2EVMOnRampInterface_ParseTokensConsumed_Call) Run(run func(log types.Log)) *EVM2EVMOnRampInterface_ParseTokensConsumed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseTokensConsumed_Call) Return(_a0 *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed, _a1 error) *EVM2EVMOnRampInterface_ParseTokensConsumed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_ParseTokensConsumed_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed, error)) *EVM2EVMOnRampInterface_ParseTokensConsumed_Call { + _c.Call.Return(run) + return _c +} + +// PayNops provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) PayNops(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for PayNops") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_PayNops_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PayNops' +type EVM2EVMOnRampInterface_PayNops_Call struct { + *mock.Call +} + +// PayNops is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *EVM2EVMOnRampInterface_Expecter) PayNops(opts interface{}) *EVM2EVMOnRampInterface_PayNops_Call { + return &EVM2EVMOnRampInterface_PayNops_Call{Call: _e.mock.On("PayNops", opts)} +} + +func (_c *EVM2EVMOnRampInterface_PayNops_Call) Run(run func(opts *bind.TransactOpts)) *EVM2EVMOnRampInterface_PayNops_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_PayNops_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOnRampInterface_PayNops_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_PayNops_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *EVM2EVMOnRampInterface_PayNops_Call { + _c.Call.Return(run) + return _c +} + +// SetAdmin provides a mock function with given fields: opts, newAdmin +func (_m *EVM2EVMOnRampInterface) SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, newAdmin) + + if len(ret) == 0 { + panic("no return value specified for SetAdmin") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, newAdmin) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, newAdmin) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, newAdmin) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_SetAdmin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetAdmin' +type EVM2EVMOnRampInterface_SetAdmin_Call struct { + *mock.Call +} + +// SetAdmin is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - newAdmin common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) SetAdmin(opts interface{}, newAdmin interface{}) *EVM2EVMOnRampInterface_SetAdmin_Call { + return &EVM2EVMOnRampInterface_SetAdmin_Call{Call: _e.mock.On("SetAdmin", opts, newAdmin)} +} + +func (_c *EVM2EVMOnRampInterface_SetAdmin_Call) Run(run func(opts *bind.TransactOpts, newAdmin common.Address)) *EVM2EVMOnRampInterface_SetAdmin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_SetAdmin_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOnRampInterface_SetAdmin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_SetAdmin_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *EVM2EVMOnRampInterface_SetAdmin_Call { + _c.Call.Return(run) + return _c +} + +// SetDynamicConfig provides a mock function with given fields: opts, dynamicConfig +func (_m *EVM2EVMOnRampInterface) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + ret := _m.Called(opts, dynamicConfig) + + if len(ret) == 0 { + panic("no return value specified for SetDynamicConfig") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig) (*types.Transaction, error)); ok { + return rf(opts, dynamicConfig) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig) *types.Transaction); ok { + r0 = rf(opts, dynamicConfig) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig) error); ok { + r1 = rf(opts, dynamicConfig) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_SetDynamicConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetDynamicConfig' +type EVM2EVMOnRampInterface_SetDynamicConfig_Call struct { + *mock.Call +} + +// SetDynamicConfig is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - dynamicConfig evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig +func (_e *EVM2EVMOnRampInterface_Expecter) SetDynamicConfig(opts interface{}, dynamicConfig interface{}) *EVM2EVMOnRampInterface_SetDynamicConfig_Call { + return &EVM2EVMOnRampInterface_SetDynamicConfig_Call{Call: _e.mock.On("SetDynamicConfig", opts, dynamicConfig)} +} + +func (_c *EVM2EVMOnRampInterface_SetDynamicConfig_Call) Run(run func(opts *bind.TransactOpts, dynamicConfig evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig)) *EVM2EVMOnRampInterface_SetDynamicConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_SetDynamicConfig_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOnRampInterface_SetDynamicConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_SetDynamicConfig_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig) (*types.Transaction, error)) *EVM2EVMOnRampInterface_SetDynamicConfig_Call { + _c.Call.Return(run) + return _c +} + +// SetFeeTokenConfig provides a mock function with given fields: opts, feeTokenConfigArgs +func (_m *EVM2EVMOnRampInterface) SetFeeTokenConfig(opts *bind.TransactOpts, feeTokenConfigArgs []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error) { + ret := _m.Called(opts, feeTokenConfigArgs) + + if len(ret) == 0 { + panic("no return value specified for SetFeeTokenConfig") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error)); ok { + return rf(opts, feeTokenConfigArgs) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs) *types.Transaction); ok { + r0 = rf(opts, feeTokenConfigArgs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs) error); ok { + r1 = rf(opts, feeTokenConfigArgs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_SetFeeTokenConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetFeeTokenConfig' +type EVM2EVMOnRampInterface_SetFeeTokenConfig_Call struct { + *mock.Call +} + +// SetFeeTokenConfig is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - feeTokenConfigArgs []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs +func (_e *EVM2EVMOnRampInterface_Expecter) SetFeeTokenConfig(opts interface{}, feeTokenConfigArgs interface{}) *EVM2EVMOnRampInterface_SetFeeTokenConfig_Call { + return &EVM2EVMOnRampInterface_SetFeeTokenConfig_Call{Call: _e.mock.On("SetFeeTokenConfig", opts, feeTokenConfigArgs)} +} + +func (_c *EVM2EVMOnRampInterface_SetFeeTokenConfig_Call) Run(run func(opts *bind.TransactOpts, feeTokenConfigArgs []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs)) *EVM2EVMOnRampInterface_SetFeeTokenConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_SetFeeTokenConfig_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOnRampInterface_SetFeeTokenConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_SetFeeTokenConfig_Call) RunAndReturn(run func(*bind.TransactOpts, []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs) (*types.Transaction, error)) *EVM2EVMOnRampInterface_SetFeeTokenConfig_Call { + _c.Call.Return(run) + return _c +} + +// SetNops provides a mock function with given fields: opts, nopsAndWeights +func (_m *EVM2EVMOnRampInterface) SetNops(opts *bind.TransactOpts, nopsAndWeights []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight) (*types.Transaction, error) { + ret := _m.Called(opts, nopsAndWeights) + + if len(ret) == 0 { + panic("no return value specified for SetNops") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight) (*types.Transaction, error)); ok { + return rf(opts, nopsAndWeights) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight) *types.Transaction); ok { + r0 = rf(opts, nopsAndWeights) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight) error); ok { + r1 = rf(opts, nopsAndWeights) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_SetNops_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetNops' +type EVM2EVMOnRampInterface_SetNops_Call struct { + *mock.Call +} + +// SetNops is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - nopsAndWeights []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight +func (_e *EVM2EVMOnRampInterface_Expecter) SetNops(opts interface{}, nopsAndWeights interface{}) *EVM2EVMOnRampInterface_SetNops_Call { + return &EVM2EVMOnRampInterface_SetNops_Call{Call: _e.mock.On("SetNops", opts, nopsAndWeights)} +} + +func (_c *EVM2EVMOnRampInterface_SetNops_Call) Run(run func(opts *bind.TransactOpts, nopsAndWeights []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight)) *EVM2EVMOnRampInterface_SetNops_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_SetNops_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOnRampInterface_SetNops_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_SetNops_Call) RunAndReturn(run func(*bind.TransactOpts, []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight) (*types.Transaction, error)) *EVM2EVMOnRampInterface_SetNops_Call { + _c.Call.Return(run) + return _c +} + +// SetRateLimiterConfig provides a mock function with given fields: opts, config +func (_m *EVM2EVMOnRampInterface) SetRateLimiterConfig(opts *bind.TransactOpts, config evm_2_evm_onramp.RateLimiterConfig) (*types.Transaction, error) { + ret := _m.Called(opts, config) + + if len(ret) == 0 { + panic("no return value specified for SetRateLimiterConfig") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_onramp.RateLimiterConfig) (*types.Transaction, error)); ok { + return rf(opts, config) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_onramp.RateLimiterConfig) *types.Transaction); ok { + r0 = rf(opts, config) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_onramp.RateLimiterConfig) error); ok { + r1 = rf(opts, config) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_SetRateLimiterConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetRateLimiterConfig' +type EVM2EVMOnRampInterface_SetRateLimiterConfig_Call struct { + *mock.Call +} + +// SetRateLimiterConfig is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - config evm_2_evm_onramp.RateLimiterConfig +func (_e *EVM2EVMOnRampInterface_Expecter) SetRateLimiterConfig(opts interface{}, config interface{}) *EVM2EVMOnRampInterface_SetRateLimiterConfig_Call { + return &EVM2EVMOnRampInterface_SetRateLimiterConfig_Call{Call: _e.mock.On("SetRateLimiterConfig", opts, config)} +} + +func (_c *EVM2EVMOnRampInterface_SetRateLimiterConfig_Call) Run(run func(opts *bind.TransactOpts, config evm_2_evm_onramp.RateLimiterConfig)) *EVM2EVMOnRampInterface_SetRateLimiterConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_onramp.RateLimiterConfig)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_SetRateLimiterConfig_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOnRampInterface_SetRateLimiterConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_SetRateLimiterConfig_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_onramp.RateLimiterConfig) (*types.Transaction, error)) *EVM2EVMOnRampInterface_SetRateLimiterConfig_Call { + _c.Call.Return(run) + return _c +} + +// SetTokenTransferFeeConfig provides a mock function with given fields: opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs +func (_m *EVM2EVMOnRampInterface) SetTokenTransferFeeConfig(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) + + if len(ret) == 0 { + panic("no return value specified for SetTokenTransferFeeConfig") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs, []common.Address) (*types.Transaction, error)); ok { + return rf(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs, []common.Address) *types.Transaction); ok { + r0 = rf(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs, []common.Address) error); ok { + r1 = rf(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_SetTokenTransferFeeConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetTokenTransferFeeConfig' +type EVM2EVMOnRampInterface_SetTokenTransferFeeConfig_Call struct { + *mock.Call +} + +// SetTokenTransferFeeConfig is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - tokenTransferFeeConfigArgs []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs +// - tokensToUseDefaultFeeConfigs []common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) SetTokenTransferFeeConfig(opts interface{}, tokenTransferFeeConfigArgs interface{}, tokensToUseDefaultFeeConfigs interface{}) *EVM2EVMOnRampInterface_SetTokenTransferFeeConfig_Call { + return &EVM2EVMOnRampInterface_SetTokenTransferFeeConfig_Call{Call: _e.mock.On("SetTokenTransferFeeConfig", opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs)} +} + +func (_c *EVM2EVMOnRampInterface_SetTokenTransferFeeConfig_Call) Run(run func(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []common.Address)) *EVM2EVMOnRampInterface_SetTokenTransferFeeConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_SetTokenTransferFeeConfig_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOnRampInterface_SetTokenTransferFeeConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_SetTokenTransferFeeConfig_Call) RunAndReturn(run func(*bind.TransactOpts, []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs, []common.Address) (*types.Transaction, error)) *EVM2EVMOnRampInterface_SetTokenTransferFeeConfig_Call { + _c.Call.Return(run) + return _c +} + +// TransferOwnership provides a mock function with given fields: opts, to +func (_m *EVM2EVMOnRampInterface) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, to) + + if len(ret) == 0 { + panic("no return value specified for TransferOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, to) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_TransferOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TransferOwnership' +type EVM2EVMOnRampInterface_TransferOwnership_Call struct { + *mock.Call +} + +// TransferOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - to common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) TransferOwnership(opts interface{}, to interface{}) *EVM2EVMOnRampInterface_TransferOwnership_Call { + return &EVM2EVMOnRampInterface_TransferOwnership_Call{Call: _e.mock.On("TransferOwnership", opts, to)} +} + +func (_c *EVM2EVMOnRampInterface_TransferOwnership_Call) Run(run func(opts *bind.TransactOpts, to common.Address)) *EVM2EVMOnRampInterface_TransferOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_TransferOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOnRampInterface_TransferOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_TransferOwnership_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *EVM2EVMOnRampInterface_TransferOwnership_Call { + _c.Call.Return(run) + return _c +} + +// TypeAndVersion provides a mock function with given fields: opts +func (_m *EVM2EVMOnRampInterface) TypeAndVersion(opts *bind.CallOpts) (string, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for TypeAndVersion") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (string, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) string); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_TypeAndVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TypeAndVersion' +type EVM2EVMOnRampInterface_TypeAndVersion_Call struct { + *mock.Call +} + +// TypeAndVersion is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOnRampInterface_Expecter) TypeAndVersion(opts interface{}) *EVM2EVMOnRampInterface_TypeAndVersion_Call { + return &EVM2EVMOnRampInterface_TypeAndVersion_Call{Call: _e.mock.On("TypeAndVersion", opts)} +} + +func (_c *EVM2EVMOnRampInterface_TypeAndVersion_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOnRampInterface_TypeAndVersion_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_TypeAndVersion_Call) Return(_a0 string, _a1 error) *EVM2EVMOnRampInterface_TypeAndVersion_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_TypeAndVersion_Call) RunAndReturn(run func(*bind.CallOpts) (string, error)) *EVM2EVMOnRampInterface_TypeAndVersion_Call { + _c.Call.Return(run) + return _c +} + +// WatchAdminSet provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOnRampInterface) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampAdminSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchAdminSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampAdminSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampAdminSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampAdminSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WatchAdminSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchAdminSet' +type EVM2EVMOnRampInterface_WatchAdminSet_Call struct { + *mock.Call +} + +// WatchAdminSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampAdminSet +func (_e *EVM2EVMOnRampInterface_Expecter) WatchAdminSet(opts interface{}, sink interface{}) *EVM2EVMOnRampInterface_WatchAdminSet_Call { + return &EVM2EVMOnRampInterface_WatchAdminSet_Call{Call: _e.mock.On("WatchAdminSet", opts, sink)} +} + +func (_c *EVM2EVMOnRampInterface_WatchAdminSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampAdminSet)) *EVM2EVMOnRampInterface_WatchAdminSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_onramp.EVM2EVMOnRampAdminSet)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchAdminSet_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOnRampInterface_WatchAdminSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchAdminSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampAdminSet) (event.Subscription, error)) *EVM2EVMOnRampInterface_WatchAdminSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchCCIPSendRequested provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOnRampInterface) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchCCIPSendRequested") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WatchCCIPSendRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchCCIPSendRequested' +type EVM2EVMOnRampInterface_WatchCCIPSendRequested_Call struct { + *mock.Call +} + +// WatchCCIPSendRequested is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested +func (_e *EVM2EVMOnRampInterface_Expecter) WatchCCIPSendRequested(opts interface{}, sink interface{}) *EVM2EVMOnRampInterface_WatchCCIPSendRequested_Call { + return &EVM2EVMOnRampInterface_WatchCCIPSendRequested_Call{Call: _e.mock.On("WatchCCIPSendRequested", opts, sink)} +} + +func (_c *EVM2EVMOnRampInterface_WatchCCIPSendRequested_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested)) *EVM2EVMOnRampInterface_WatchCCIPSendRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchCCIPSendRequested_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOnRampInterface_WatchCCIPSendRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchCCIPSendRequested_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested) (event.Subscription, error)) *EVM2EVMOnRampInterface_WatchCCIPSendRequested_Call { + _c.Call.Return(run) + return _c +} + +// WatchConfigChanged provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOnRampInterface) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigChanged) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchConfigChanged") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigChanged) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigChanged) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigChanged) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WatchConfigChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchConfigChanged' +type EVM2EVMOnRampInterface_WatchConfigChanged_Call struct { + *mock.Call +} + +// WatchConfigChanged is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigChanged +func (_e *EVM2EVMOnRampInterface_Expecter) WatchConfigChanged(opts interface{}, sink interface{}) *EVM2EVMOnRampInterface_WatchConfigChanged_Call { + return &EVM2EVMOnRampInterface_WatchConfigChanged_Call{Call: _e.mock.On("WatchConfigChanged", opts, sink)} +} + +func (_c *EVM2EVMOnRampInterface_WatchConfigChanged_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigChanged)) *EVM2EVMOnRampInterface_WatchConfigChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigChanged)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchConfigChanged_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOnRampInterface_WatchConfigChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchConfigChanged_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigChanged) (event.Subscription, error)) *EVM2EVMOnRampInterface_WatchConfigChanged_Call { + _c.Call.Return(run) + return _c +} + +// WatchConfigSet provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOnRampInterface) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchConfigSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WatchConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchConfigSet' +type EVM2EVMOnRampInterface_WatchConfigSet_Call struct { + *mock.Call +} + +// WatchConfigSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigSet +func (_e *EVM2EVMOnRampInterface_Expecter) WatchConfigSet(opts interface{}, sink interface{}) *EVM2EVMOnRampInterface_WatchConfigSet_Call { + return &EVM2EVMOnRampInterface_WatchConfigSet_Call{Call: _e.mock.On("WatchConfigSet", opts, sink)} +} + +func (_c *EVM2EVMOnRampInterface_WatchConfigSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigSet)) *EVM2EVMOnRampInterface_WatchConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigSet)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchConfigSet_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOnRampInterface_WatchConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchConfigSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampConfigSet) (event.Subscription, error)) *EVM2EVMOnRampInterface_WatchConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchFeeConfigSet provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOnRampInterface) WatchFeeConfigSet(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchFeeConfigSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WatchFeeConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchFeeConfigSet' +type EVM2EVMOnRampInterface_WatchFeeConfigSet_Call struct { + *mock.Call +} + +// WatchFeeConfigSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet +func (_e *EVM2EVMOnRampInterface_Expecter) WatchFeeConfigSet(opts interface{}, sink interface{}) *EVM2EVMOnRampInterface_WatchFeeConfigSet_Call { + return &EVM2EVMOnRampInterface_WatchFeeConfigSet_Call{Call: _e.mock.On("WatchFeeConfigSet", opts, sink)} +} + +func (_c *EVM2EVMOnRampInterface_WatchFeeConfigSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet)) *EVM2EVMOnRampInterface_WatchFeeConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchFeeConfigSet_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOnRampInterface_WatchFeeConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchFeeConfigSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampFeeConfigSet) (event.Subscription, error)) *EVM2EVMOnRampInterface_WatchFeeConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchNopPaid provides a mock function with given fields: opts, sink, nop +func (_m *EVM2EVMOnRampInterface) WatchNopPaid(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopPaid, nop []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, nop) + + if len(ret) == 0 { + panic("no return value specified for WatchNopPaid") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopPaid, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, nop) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopPaid, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, nop) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopPaid, []common.Address) error); ok { + r1 = rf(opts, sink, nop) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WatchNopPaid_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchNopPaid' +type EVM2EVMOnRampInterface_WatchNopPaid_Call struct { + *mock.Call +} + +// WatchNopPaid is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopPaid +// - nop []common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) WatchNopPaid(opts interface{}, sink interface{}, nop interface{}) *EVM2EVMOnRampInterface_WatchNopPaid_Call { + return &EVM2EVMOnRampInterface_WatchNopPaid_Call{Call: _e.mock.On("WatchNopPaid", opts, sink, nop)} +} + +func (_c *EVM2EVMOnRampInterface_WatchNopPaid_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopPaid, nop []common.Address)) *EVM2EVMOnRampInterface_WatchNopPaid_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopPaid), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchNopPaid_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOnRampInterface_WatchNopPaid_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchNopPaid_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopPaid, []common.Address) (event.Subscription, error)) *EVM2EVMOnRampInterface_WatchNopPaid_Call { + _c.Call.Return(run) + return _c +} + +// WatchNopsSet provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOnRampInterface) WatchNopsSet(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopsSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchNopsSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopsSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopsSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopsSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WatchNopsSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchNopsSet' +type EVM2EVMOnRampInterface_WatchNopsSet_Call struct { + *mock.Call +} + +// WatchNopsSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopsSet +func (_e *EVM2EVMOnRampInterface_Expecter) WatchNopsSet(opts interface{}, sink interface{}) *EVM2EVMOnRampInterface_WatchNopsSet_Call { + return &EVM2EVMOnRampInterface_WatchNopsSet_Call{Call: _e.mock.On("WatchNopsSet", opts, sink)} +} + +func (_c *EVM2EVMOnRampInterface_WatchNopsSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopsSet)) *EVM2EVMOnRampInterface_WatchNopsSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopsSet)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchNopsSet_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOnRampInterface_WatchNopsSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchNopsSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampNopsSet) (event.Subscription, error)) *EVM2EVMOnRampInterface_WatchNopsSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferRequested provides a mock function with given fields: opts, sink, from, to +func (_m *EVM2EVMOnRampInterface) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferRequested") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WatchOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferRequested' +type EVM2EVMOnRampInterface_WatchOwnershipTransferRequested_Call struct { + *mock.Call +} + +// WatchOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) WatchOwnershipTransferRequested(opts interface{}, sink interface{}, from interface{}, to interface{}) *EVM2EVMOnRampInterface_WatchOwnershipTransferRequested_Call { + return &EVM2EVMOnRampInterface_WatchOwnershipTransferRequested_Call{Call: _e.mock.On("WatchOwnershipTransferRequested", opts, sink, from, to)} +} + +func (_c *EVM2EVMOnRampInterface_WatchOwnershipTransferRequested_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested, from []common.Address, to []common.Address)) *EVM2EVMOnRampInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchOwnershipTransferRequested_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOnRampInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)) *EVM2EVMOnRampInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferred provides a mock function with given fields: opts, sink, from, to +func (_m *EVM2EVMOnRampInterface) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferred") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WatchOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferred' +type EVM2EVMOnRampInterface_WatchOwnershipTransferred_Call struct { + *mock.Call +} + +// WatchOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) WatchOwnershipTransferred(opts interface{}, sink interface{}, from interface{}, to interface{}) *EVM2EVMOnRampInterface_WatchOwnershipTransferred_Call { + return &EVM2EVMOnRampInterface_WatchOwnershipTransferred_Call{Call: _e.mock.On("WatchOwnershipTransferred", opts, sink, from, to)} +} + +func (_c *EVM2EVMOnRampInterface_WatchOwnershipTransferred_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred, from []common.Address, to []common.Address)) *EVM2EVMOnRampInterface_WatchOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchOwnershipTransferred_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOnRampInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchOwnershipTransferred_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)) *EVM2EVMOnRampInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// WatchTokenTransferFeeConfigDeleted provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOnRampInterface) WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchTokenTransferFeeConfigDeleted") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTokenTransferFeeConfigDeleted' +type EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigDeleted_Call struct { + *mock.Call +} + +// WatchTokenTransferFeeConfigDeleted is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted +func (_e *EVM2EVMOnRampInterface_Expecter) WatchTokenTransferFeeConfigDeleted(opts interface{}, sink interface{}) *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigDeleted_Call { + return &EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigDeleted_Call{Call: _e.mock.On("WatchTokenTransferFeeConfigDeleted", opts, sink)} +} + +func (_c *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigDeleted_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted)) *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigDeleted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigDeleted_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigDeleted_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigDeleted) (event.Subscription, error)) *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(run) + return _c +} + +// WatchTokenTransferFeeConfigSet provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOnRampInterface) WatchTokenTransferFeeConfigSet(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchTokenTransferFeeConfigSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTokenTransferFeeConfigSet' +type EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigSet_Call struct { + *mock.Call +} + +// WatchTokenTransferFeeConfigSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet +func (_e *EVM2EVMOnRampInterface_Expecter) WatchTokenTransferFeeConfigSet(opts interface{}, sink interface{}) *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigSet_Call { + return &EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigSet_Call{Call: _e.mock.On("WatchTokenTransferFeeConfigSet", opts, sink)} +} + +func (_c *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet)) *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigSet_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigSet) (event.Subscription, error)) *EVM2EVMOnRampInterface_WatchTokenTransferFeeConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchTokensConsumed provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOnRampInterface) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchTokensConsumed") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WatchTokensConsumed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTokensConsumed' +type EVM2EVMOnRampInterface_WatchTokensConsumed_Call struct { + *mock.Call +} + +// WatchTokensConsumed is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed +func (_e *EVM2EVMOnRampInterface_Expecter) WatchTokensConsumed(opts interface{}, sink interface{}) *EVM2EVMOnRampInterface_WatchTokensConsumed_Call { + return &EVM2EVMOnRampInterface_WatchTokensConsumed_Call{Call: _e.mock.On("WatchTokensConsumed", opts, sink)} +} + +func (_c *EVM2EVMOnRampInterface_WatchTokensConsumed_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed)) *EVM2EVMOnRampInterface_WatchTokensConsumed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchTokensConsumed_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOnRampInterface_WatchTokensConsumed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WatchTokensConsumed_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_onramp.EVM2EVMOnRampTokensConsumed) (event.Subscription, error)) *EVM2EVMOnRampInterface_WatchTokensConsumed_Call { + _c.Call.Return(run) + return _c +} + +// WithdrawNonLinkFees provides a mock function with given fields: opts, feeToken, to +func (_m *EVM2EVMOnRampInterface) WithdrawNonLinkFees(opts *bind.TransactOpts, feeToken common.Address, to common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, feeToken, to) + + if len(ret) == 0 { + panic("no return value specified for WithdrawNonLinkFees") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address) (*types.Transaction, error)); ok { + return rf(opts, feeToken, to) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address) *types.Transaction); ok { + r0 = rf(opts, feeToken, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, common.Address) error); ok { + r1 = rf(opts, feeToken, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOnRampInterface_WithdrawNonLinkFees_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WithdrawNonLinkFees' +type EVM2EVMOnRampInterface_WithdrawNonLinkFees_Call struct { + *mock.Call +} + +// WithdrawNonLinkFees is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - feeToken common.Address +// - to common.Address +func (_e *EVM2EVMOnRampInterface_Expecter) WithdrawNonLinkFees(opts interface{}, feeToken interface{}, to interface{}) *EVM2EVMOnRampInterface_WithdrawNonLinkFees_Call { + return &EVM2EVMOnRampInterface_WithdrawNonLinkFees_Call{Call: _e.mock.On("WithdrawNonLinkFees", opts, feeToken, to)} +} + +func (_c *EVM2EVMOnRampInterface_WithdrawNonLinkFees_Call) Run(run func(opts *bind.TransactOpts, feeToken common.Address, to common.Address)) *EVM2EVMOnRampInterface_WithdrawNonLinkFees_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WithdrawNonLinkFees_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOnRampInterface_WithdrawNonLinkFees_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOnRampInterface_WithdrawNonLinkFees_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, common.Address) (*types.Transaction, error)) *EVM2EVMOnRampInterface_WithdrawNonLinkFees_Call { + _c.Call.Return(run) + return _c +} + +// NewEVM2EVMOnRampInterface creates a new instance of EVM2EVMOnRampInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewEVM2EVMOnRampInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *EVM2EVMOnRampInterface { + mock := &EVM2EVMOnRampInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/ccip/mocks/link_token_interface.go b/core/gethwrappers/ccip/mocks/link_token_interface.go new file mode 100644 index 0000000000..efb4507f58 --- /dev/null +++ b/core/gethwrappers/ccip/mocks/link_token_interface.go @@ -0,0 +1,1217 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_contracts + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + link_token_interface "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// LinkTokenInterface is an autogenerated mock type for the LinkTokenInterface type +type LinkTokenInterface struct { + mock.Mock +} + +type LinkTokenInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *LinkTokenInterface) EXPECT() *LinkTokenInterface_Expecter { + return &LinkTokenInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *LinkTokenInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// LinkTokenInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type LinkTokenInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *LinkTokenInterface_Expecter) Address() *LinkTokenInterface_Address_Call { + return &LinkTokenInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *LinkTokenInterface_Address_Call) Run(run func()) *LinkTokenInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *LinkTokenInterface_Address_Call) Return(_a0 common.Address) *LinkTokenInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *LinkTokenInterface_Address_Call) RunAndReturn(run func() common.Address) *LinkTokenInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// Allowance provides a mock function with given fields: opts, _owner, _spender +func (_m *LinkTokenInterface) Allowance(opts *bind.CallOpts, _owner common.Address, _spender common.Address) (*big.Int, error) { + ret := _m.Called(opts, _owner, _spender) + + if len(ret) == 0 { + panic("no return value specified for Allowance") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, common.Address) (*big.Int, error)); ok { + return rf(opts, _owner, _spender) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, common.Address) *big.Int); ok { + r0 = rf(opts, _owner, _spender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address, common.Address) error); ok { + r1 = rf(opts, _owner, _spender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_Allowance_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Allowance' +type LinkTokenInterface_Allowance_Call struct { + *mock.Call +} + +// Allowance is a helper method to define mock.On call +// - opts *bind.CallOpts +// - _owner common.Address +// - _spender common.Address +func (_e *LinkTokenInterface_Expecter) Allowance(opts interface{}, _owner interface{}, _spender interface{}) *LinkTokenInterface_Allowance_Call { + return &LinkTokenInterface_Allowance_Call{Call: _e.mock.On("Allowance", opts, _owner, _spender)} +} + +func (_c *LinkTokenInterface_Allowance_Call) Run(run func(opts *bind.CallOpts, _owner common.Address, _spender common.Address)) *LinkTokenInterface_Allowance_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address), args[2].(common.Address)) + }) + return _c +} + +func (_c *LinkTokenInterface_Allowance_Call) Return(_a0 *big.Int, _a1 error) *LinkTokenInterface_Allowance_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_Allowance_Call) RunAndReturn(run func(*bind.CallOpts, common.Address, common.Address) (*big.Int, error)) *LinkTokenInterface_Allowance_Call { + _c.Call.Return(run) + return _c +} + +// Approve provides a mock function with given fields: opts, _spender, _value +func (_m *LinkTokenInterface) Approve(opts *bind.TransactOpts, _spender common.Address, _value *big.Int) (*types.Transaction, error) { + ret := _m.Called(opts, _spender, _value) + + if len(ret) == 0 { + panic("no return value specified for Approve") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, *big.Int) (*types.Transaction, error)); ok { + return rf(opts, _spender, _value) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, *big.Int) *types.Transaction); ok { + r0 = rf(opts, _spender, _value) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, *big.Int) error); ok { + r1 = rf(opts, _spender, _value) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_Approve_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Approve' +type LinkTokenInterface_Approve_Call struct { + *mock.Call +} + +// Approve is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _spender common.Address +// - _value *big.Int +func (_e *LinkTokenInterface_Expecter) Approve(opts interface{}, _spender interface{}, _value interface{}) *LinkTokenInterface_Approve_Call { + return &LinkTokenInterface_Approve_Call{Call: _e.mock.On("Approve", opts, _spender, _value)} +} + +func (_c *LinkTokenInterface_Approve_Call) Run(run func(opts *bind.TransactOpts, _spender common.Address, _value *big.Int)) *LinkTokenInterface_Approve_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(*big.Int)) + }) + return _c +} + +func (_c *LinkTokenInterface_Approve_Call) Return(_a0 *types.Transaction, _a1 error) *LinkTokenInterface_Approve_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_Approve_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, *big.Int) (*types.Transaction, error)) *LinkTokenInterface_Approve_Call { + _c.Call.Return(run) + return _c +} + +// BalanceOf provides a mock function with given fields: opts, _owner +func (_m *LinkTokenInterface) BalanceOf(opts *bind.CallOpts, _owner common.Address) (*big.Int, error) { + ret := _m.Called(opts, _owner) + + if len(ret) == 0 { + panic("no return value specified for BalanceOf") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (*big.Int, error)); ok { + return rf(opts, _owner) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) *big.Int); ok { + r0 = rf(opts, _owner) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, _owner) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_BalanceOf_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BalanceOf' +type LinkTokenInterface_BalanceOf_Call struct { + *mock.Call +} + +// BalanceOf is a helper method to define mock.On call +// - opts *bind.CallOpts +// - _owner common.Address +func (_e *LinkTokenInterface_Expecter) BalanceOf(opts interface{}, _owner interface{}) *LinkTokenInterface_BalanceOf_Call { + return &LinkTokenInterface_BalanceOf_Call{Call: _e.mock.On("BalanceOf", opts, _owner)} +} + +func (_c *LinkTokenInterface_BalanceOf_Call) Run(run func(opts *bind.CallOpts, _owner common.Address)) *LinkTokenInterface_BalanceOf_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *LinkTokenInterface_BalanceOf_Call) Return(_a0 *big.Int, _a1 error) *LinkTokenInterface_BalanceOf_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_BalanceOf_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (*big.Int, error)) *LinkTokenInterface_BalanceOf_Call { + _c.Call.Return(run) + return _c +} + +// Decimals provides a mock function with given fields: opts +func (_m *LinkTokenInterface) Decimals(opts *bind.CallOpts) (uint8, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Decimals") + } + + var r0 uint8 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (uint8, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) uint8); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(uint8) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_Decimals_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Decimals' +type LinkTokenInterface_Decimals_Call struct { + *mock.Call +} + +// Decimals is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *LinkTokenInterface_Expecter) Decimals(opts interface{}) *LinkTokenInterface_Decimals_Call { + return &LinkTokenInterface_Decimals_Call{Call: _e.mock.On("Decimals", opts)} +} + +func (_c *LinkTokenInterface_Decimals_Call) Run(run func(opts *bind.CallOpts)) *LinkTokenInterface_Decimals_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *LinkTokenInterface_Decimals_Call) Return(_a0 uint8, _a1 error) *LinkTokenInterface_Decimals_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_Decimals_Call) RunAndReturn(run func(*bind.CallOpts) (uint8, error)) *LinkTokenInterface_Decimals_Call { + _c.Call.Return(run) + return _c +} + +// DecreaseApproval provides a mock function with given fields: opts, _spender, _subtractedValue +func (_m *LinkTokenInterface) DecreaseApproval(opts *bind.TransactOpts, _spender common.Address, _subtractedValue *big.Int) (*types.Transaction, error) { + ret := _m.Called(opts, _spender, _subtractedValue) + + if len(ret) == 0 { + panic("no return value specified for DecreaseApproval") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, *big.Int) (*types.Transaction, error)); ok { + return rf(opts, _spender, _subtractedValue) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, *big.Int) *types.Transaction); ok { + r0 = rf(opts, _spender, _subtractedValue) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, *big.Int) error); ok { + r1 = rf(opts, _spender, _subtractedValue) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_DecreaseApproval_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DecreaseApproval' +type LinkTokenInterface_DecreaseApproval_Call struct { + *mock.Call +} + +// DecreaseApproval is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _spender common.Address +// - _subtractedValue *big.Int +func (_e *LinkTokenInterface_Expecter) DecreaseApproval(opts interface{}, _spender interface{}, _subtractedValue interface{}) *LinkTokenInterface_DecreaseApproval_Call { + return &LinkTokenInterface_DecreaseApproval_Call{Call: _e.mock.On("DecreaseApproval", opts, _spender, _subtractedValue)} +} + +func (_c *LinkTokenInterface_DecreaseApproval_Call) Run(run func(opts *bind.TransactOpts, _spender common.Address, _subtractedValue *big.Int)) *LinkTokenInterface_DecreaseApproval_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(*big.Int)) + }) + return _c +} + +func (_c *LinkTokenInterface_DecreaseApproval_Call) Return(_a0 *types.Transaction, _a1 error) *LinkTokenInterface_DecreaseApproval_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_DecreaseApproval_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, *big.Int) (*types.Transaction, error)) *LinkTokenInterface_DecreaseApproval_Call { + _c.Call.Return(run) + return _c +} + +// FilterApproval provides a mock function with given fields: opts, owner, spender +func (_m *LinkTokenInterface) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*link_token_interface.LinkTokenApprovalIterator, error) { + ret := _m.Called(opts, owner, spender) + + if len(ret) == 0 { + panic("no return value specified for FilterApproval") + } + + var r0 *link_token_interface.LinkTokenApprovalIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*link_token_interface.LinkTokenApprovalIterator, error)); ok { + return rf(opts, owner, spender) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *link_token_interface.LinkTokenApprovalIterator); ok { + r0 = rf(opts, owner, spender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*link_token_interface.LinkTokenApprovalIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, owner, spender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_FilterApproval_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterApproval' +type LinkTokenInterface_FilterApproval_Call struct { + *mock.Call +} + +// FilterApproval is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - owner []common.Address +// - spender []common.Address +func (_e *LinkTokenInterface_Expecter) FilterApproval(opts interface{}, owner interface{}, spender interface{}) *LinkTokenInterface_FilterApproval_Call { + return &LinkTokenInterface_FilterApproval_Call{Call: _e.mock.On("FilterApproval", opts, owner, spender)} +} + +func (_c *LinkTokenInterface_FilterApproval_Call) Run(run func(opts *bind.FilterOpts, owner []common.Address, spender []common.Address)) *LinkTokenInterface_FilterApproval_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *LinkTokenInterface_FilterApproval_Call) Return(_a0 *link_token_interface.LinkTokenApprovalIterator, _a1 error) *LinkTokenInterface_FilterApproval_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_FilterApproval_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*link_token_interface.LinkTokenApprovalIterator, error)) *LinkTokenInterface_FilterApproval_Call { + _c.Call.Return(run) + return _c +} + +// FilterTransfer provides a mock function with given fields: opts, from, to +func (_m *LinkTokenInterface) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*link_token_interface.LinkTokenTransferIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterTransfer") + } + + var r0 *link_token_interface.LinkTokenTransferIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*link_token_interface.LinkTokenTransferIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *link_token_interface.LinkTokenTransferIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*link_token_interface.LinkTokenTransferIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_FilterTransfer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTransfer' +type LinkTokenInterface_FilterTransfer_Call struct { + *mock.Call +} + +// FilterTransfer is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *LinkTokenInterface_Expecter) FilterTransfer(opts interface{}, from interface{}, to interface{}) *LinkTokenInterface_FilterTransfer_Call { + return &LinkTokenInterface_FilterTransfer_Call{Call: _e.mock.On("FilterTransfer", opts, from, to)} +} + +func (_c *LinkTokenInterface_FilterTransfer_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *LinkTokenInterface_FilterTransfer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *LinkTokenInterface_FilterTransfer_Call) Return(_a0 *link_token_interface.LinkTokenTransferIterator, _a1 error) *LinkTokenInterface_FilterTransfer_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_FilterTransfer_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*link_token_interface.LinkTokenTransferIterator, error)) *LinkTokenInterface_FilterTransfer_Call { + _c.Call.Return(run) + return _c +} + +// IncreaseApproval provides a mock function with given fields: opts, _spender, _addedValue +func (_m *LinkTokenInterface) IncreaseApproval(opts *bind.TransactOpts, _spender common.Address, _addedValue *big.Int) (*types.Transaction, error) { + ret := _m.Called(opts, _spender, _addedValue) + + if len(ret) == 0 { + panic("no return value specified for IncreaseApproval") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, *big.Int) (*types.Transaction, error)); ok { + return rf(opts, _spender, _addedValue) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, *big.Int) *types.Transaction); ok { + r0 = rf(opts, _spender, _addedValue) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, *big.Int) error); ok { + r1 = rf(opts, _spender, _addedValue) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_IncreaseApproval_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IncreaseApproval' +type LinkTokenInterface_IncreaseApproval_Call struct { + *mock.Call +} + +// IncreaseApproval is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _spender common.Address +// - _addedValue *big.Int +func (_e *LinkTokenInterface_Expecter) IncreaseApproval(opts interface{}, _spender interface{}, _addedValue interface{}) *LinkTokenInterface_IncreaseApproval_Call { + return &LinkTokenInterface_IncreaseApproval_Call{Call: _e.mock.On("IncreaseApproval", opts, _spender, _addedValue)} +} + +func (_c *LinkTokenInterface_IncreaseApproval_Call) Run(run func(opts *bind.TransactOpts, _spender common.Address, _addedValue *big.Int)) *LinkTokenInterface_IncreaseApproval_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(*big.Int)) + }) + return _c +} + +func (_c *LinkTokenInterface_IncreaseApproval_Call) Return(_a0 *types.Transaction, _a1 error) *LinkTokenInterface_IncreaseApproval_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_IncreaseApproval_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, *big.Int) (*types.Transaction, error)) *LinkTokenInterface_IncreaseApproval_Call { + _c.Call.Return(run) + return _c +} + +// Name provides a mock function with given fields: opts +func (_m *LinkTokenInterface) Name(opts *bind.CallOpts) (string, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Name") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (string, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) string); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' +type LinkTokenInterface_Name_Call struct { + *mock.Call +} + +// Name is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *LinkTokenInterface_Expecter) Name(opts interface{}) *LinkTokenInterface_Name_Call { + return &LinkTokenInterface_Name_Call{Call: _e.mock.On("Name", opts)} +} + +func (_c *LinkTokenInterface_Name_Call) Run(run func(opts *bind.CallOpts)) *LinkTokenInterface_Name_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *LinkTokenInterface_Name_Call) Return(_a0 string, _a1 error) *LinkTokenInterface_Name_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_Name_Call) RunAndReturn(run func(*bind.CallOpts) (string, error)) *LinkTokenInterface_Name_Call { + _c.Call.Return(run) + return _c +} + +// ParseApproval provides a mock function with given fields: log +func (_m *LinkTokenInterface) ParseApproval(log types.Log) (*link_token_interface.LinkTokenApproval, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseApproval") + } + + var r0 *link_token_interface.LinkTokenApproval + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*link_token_interface.LinkTokenApproval, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *link_token_interface.LinkTokenApproval); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*link_token_interface.LinkTokenApproval) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_ParseApproval_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseApproval' +type LinkTokenInterface_ParseApproval_Call struct { + *mock.Call +} + +// ParseApproval is a helper method to define mock.On call +// - log types.Log +func (_e *LinkTokenInterface_Expecter) ParseApproval(log interface{}) *LinkTokenInterface_ParseApproval_Call { + return &LinkTokenInterface_ParseApproval_Call{Call: _e.mock.On("ParseApproval", log)} +} + +func (_c *LinkTokenInterface_ParseApproval_Call) Run(run func(log types.Log)) *LinkTokenInterface_ParseApproval_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *LinkTokenInterface_ParseApproval_Call) Return(_a0 *link_token_interface.LinkTokenApproval, _a1 error) *LinkTokenInterface_ParseApproval_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_ParseApproval_Call) RunAndReturn(run func(types.Log) (*link_token_interface.LinkTokenApproval, error)) *LinkTokenInterface_ParseApproval_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *LinkTokenInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type LinkTokenInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *LinkTokenInterface_Expecter) ParseLog(log interface{}) *LinkTokenInterface_ParseLog_Call { + return &LinkTokenInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *LinkTokenInterface_ParseLog_Call) Run(run func(log types.Log)) *LinkTokenInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *LinkTokenInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *LinkTokenInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *LinkTokenInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseTransfer provides a mock function with given fields: log +func (_m *LinkTokenInterface) ParseTransfer(log types.Log) (*link_token_interface.LinkTokenTransfer, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTransfer") + } + + var r0 *link_token_interface.LinkTokenTransfer + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*link_token_interface.LinkTokenTransfer, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *link_token_interface.LinkTokenTransfer); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*link_token_interface.LinkTokenTransfer) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_ParseTransfer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTransfer' +type LinkTokenInterface_ParseTransfer_Call struct { + *mock.Call +} + +// ParseTransfer is a helper method to define mock.On call +// - log types.Log +func (_e *LinkTokenInterface_Expecter) ParseTransfer(log interface{}) *LinkTokenInterface_ParseTransfer_Call { + return &LinkTokenInterface_ParseTransfer_Call{Call: _e.mock.On("ParseTransfer", log)} +} + +func (_c *LinkTokenInterface_ParseTransfer_Call) Run(run func(log types.Log)) *LinkTokenInterface_ParseTransfer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *LinkTokenInterface_ParseTransfer_Call) Return(_a0 *link_token_interface.LinkTokenTransfer, _a1 error) *LinkTokenInterface_ParseTransfer_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_ParseTransfer_Call) RunAndReturn(run func(types.Log) (*link_token_interface.LinkTokenTransfer, error)) *LinkTokenInterface_ParseTransfer_Call { + _c.Call.Return(run) + return _c +} + +// Symbol provides a mock function with given fields: opts +func (_m *LinkTokenInterface) Symbol(opts *bind.CallOpts) (string, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Symbol") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (string, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) string); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_Symbol_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Symbol' +type LinkTokenInterface_Symbol_Call struct { + *mock.Call +} + +// Symbol is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *LinkTokenInterface_Expecter) Symbol(opts interface{}) *LinkTokenInterface_Symbol_Call { + return &LinkTokenInterface_Symbol_Call{Call: _e.mock.On("Symbol", opts)} +} + +func (_c *LinkTokenInterface_Symbol_Call) Run(run func(opts *bind.CallOpts)) *LinkTokenInterface_Symbol_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *LinkTokenInterface_Symbol_Call) Return(_a0 string, _a1 error) *LinkTokenInterface_Symbol_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_Symbol_Call) RunAndReturn(run func(*bind.CallOpts) (string, error)) *LinkTokenInterface_Symbol_Call { + _c.Call.Return(run) + return _c +} + +// TotalSupply provides a mock function with given fields: opts +func (_m *LinkTokenInterface) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for TotalSupply") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_TotalSupply_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TotalSupply' +type LinkTokenInterface_TotalSupply_Call struct { + *mock.Call +} + +// TotalSupply is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *LinkTokenInterface_Expecter) TotalSupply(opts interface{}) *LinkTokenInterface_TotalSupply_Call { + return &LinkTokenInterface_TotalSupply_Call{Call: _e.mock.On("TotalSupply", opts)} +} + +func (_c *LinkTokenInterface_TotalSupply_Call) Run(run func(opts *bind.CallOpts)) *LinkTokenInterface_TotalSupply_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *LinkTokenInterface_TotalSupply_Call) Return(_a0 *big.Int, _a1 error) *LinkTokenInterface_TotalSupply_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_TotalSupply_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *LinkTokenInterface_TotalSupply_Call { + _c.Call.Return(run) + return _c +} + +// Transfer provides a mock function with given fields: opts, _to, _value +func (_m *LinkTokenInterface) Transfer(opts *bind.TransactOpts, _to common.Address, _value *big.Int) (*types.Transaction, error) { + ret := _m.Called(opts, _to, _value) + + if len(ret) == 0 { + panic("no return value specified for Transfer") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, *big.Int) (*types.Transaction, error)); ok { + return rf(opts, _to, _value) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, *big.Int) *types.Transaction); ok { + r0 = rf(opts, _to, _value) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, *big.Int) error); ok { + r1 = rf(opts, _to, _value) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_Transfer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Transfer' +type LinkTokenInterface_Transfer_Call struct { + *mock.Call +} + +// Transfer is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _to common.Address +// - _value *big.Int +func (_e *LinkTokenInterface_Expecter) Transfer(opts interface{}, _to interface{}, _value interface{}) *LinkTokenInterface_Transfer_Call { + return &LinkTokenInterface_Transfer_Call{Call: _e.mock.On("Transfer", opts, _to, _value)} +} + +func (_c *LinkTokenInterface_Transfer_Call) Run(run func(opts *bind.TransactOpts, _to common.Address, _value *big.Int)) *LinkTokenInterface_Transfer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(*big.Int)) + }) + return _c +} + +func (_c *LinkTokenInterface_Transfer_Call) Return(_a0 *types.Transaction, _a1 error) *LinkTokenInterface_Transfer_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_Transfer_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, *big.Int) (*types.Transaction, error)) *LinkTokenInterface_Transfer_Call { + _c.Call.Return(run) + return _c +} + +// TransferAndCall provides a mock function with given fields: opts, _to, _value, _data +func (_m *LinkTokenInterface) TransferAndCall(opts *bind.TransactOpts, _to common.Address, _value *big.Int, _data []byte) (*types.Transaction, error) { + ret := _m.Called(opts, _to, _value, _data) + + if len(ret) == 0 { + panic("no return value specified for TransferAndCall") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, *big.Int, []byte) (*types.Transaction, error)); ok { + return rf(opts, _to, _value, _data) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, *big.Int, []byte) *types.Transaction); ok { + r0 = rf(opts, _to, _value, _data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, *big.Int, []byte) error); ok { + r1 = rf(opts, _to, _value, _data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_TransferAndCall_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TransferAndCall' +type LinkTokenInterface_TransferAndCall_Call struct { + *mock.Call +} + +// TransferAndCall is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _to common.Address +// - _value *big.Int +// - _data []byte +func (_e *LinkTokenInterface_Expecter) TransferAndCall(opts interface{}, _to interface{}, _value interface{}, _data interface{}) *LinkTokenInterface_TransferAndCall_Call { + return &LinkTokenInterface_TransferAndCall_Call{Call: _e.mock.On("TransferAndCall", opts, _to, _value, _data)} +} + +func (_c *LinkTokenInterface_TransferAndCall_Call) Run(run func(opts *bind.TransactOpts, _to common.Address, _value *big.Int, _data []byte)) *LinkTokenInterface_TransferAndCall_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(*big.Int), args[3].([]byte)) + }) + return _c +} + +func (_c *LinkTokenInterface_TransferAndCall_Call) Return(_a0 *types.Transaction, _a1 error) *LinkTokenInterface_TransferAndCall_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_TransferAndCall_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, *big.Int, []byte) (*types.Transaction, error)) *LinkTokenInterface_TransferAndCall_Call { + _c.Call.Return(run) + return _c +} + +// TransferFrom provides a mock function with given fields: opts, _from, _to, _value +func (_m *LinkTokenInterface) TransferFrom(opts *bind.TransactOpts, _from common.Address, _to common.Address, _value *big.Int) (*types.Transaction, error) { + ret := _m.Called(opts, _from, _to, _value) + + if len(ret) == 0 { + panic("no return value specified for TransferFrom") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, *big.Int) (*types.Transaction, error)); ok { + return rf(opts, _from, _to, _value) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, *big.Int) *types.Transaction); ok { + r0 = rf(opts, _from, _to, _value) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, common.Address, *big.Int) error); ok { + r1 = rf(opts, _from, _to, _value) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_TransferFrom_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TransferFrom' +type LinkTokenInterface_TransferFrom_Call struct { + *mock.Call +} + +// TransferFrom is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _from common.Address +// - _to common.Address +// - _value *big.Int +func (_e *LinkTokenInterface_Expecter) TransferFrom(opts interface{}, _from interface{}, _to interface{}, _value interface{}) *LinkTokenInterface_TransferFrom_Call { + return &LinkTokenInterface_TransferFrom_Call{Call: _e.mock.On("TransferFrom", opts, _from, _to, _value)} +} + +func (_c *LinkTokenInterface_TransferFrom_Call) Run(run func(opts *bind.TransactOpts, _from common.Address, _to common.Address, _value *big.Int)) *LinkTokenInterface_TransferFrom_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(common.Address), args[3].(*big.Int)) + }) + return _c +} + +func (_c *LinkTokenInterface_TransferFrom_Call) Return(_a0 *types.Transaction, _a1 error) *LinkTokenInterface_TransferFrom_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_TransferFrom_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, common.Address, *big.Int) (*types.Transaction, error)) *LinkTokenInterface_TransferFrom_Call { + _c.Call.Return(run) + return _c +} + +// WatchApproval provides a mock function with given fields: opts, sink, owner, spender +func (_m *LinkTokenInterface) WatchApproval(opts *bind.WatchOpts, sink chan<- *link_token_interface.LinkTokenApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, owner, spender) + + if len(ret) == 0 { + panic("no return value specified for WatchApproval") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *link_token_interface.LinkTokenApproval, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, owner, spender) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *link_token_interface.LinkTokenApproval, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, owner, spender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *link_token_interface.LinkTokenApproval, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, owner, spender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_WatchApproval_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchApproval' +type LinkTokenInterface_WatchApproval_Call struct { + *mock.Call +} + +// WatchApproval is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *link_token_interface.LinkTokenApproval +// - owner []common.Address +// - spender []common.Address +func (_e *LinkTokenInterface_Expecter) WatchApproval(opts interface{}, sink interface{}, owner interface{}, spender interface{}) *LinkTokenInterface_WatchApproval_Call { + return &LinkTokenInterface_WatchApproval_Call{Call: _e.mock.On("WatchApproval", opts, sink, owner, spender)} +} + +func (_c *LinkTokenInterface_WatchApproval_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *link_token_interface.LinkTokenApproval, owner []common.Address, spender []common.Address)) *LinkTokenInterface_WatchApproval_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *link_token_interface.LinkTokenApproval), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *LinkTokenInterface_WatchApproval_Call) Return(_a0 event.Subscription, _a1 error) *LinkTokenInterface_WatchApproval_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_WatchApproval_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *link_token_interface.LinkTokenApproval, []common.Address, []common.Address) (event.Subscription, error)) *LinkTokenInterface_WatchApproval_Call { + _c.Call.Return(run) + return _c +} + +// WatchTransfer provides a mock function with given fields: opts, sink, from, to +func (_m *LinkTokenInterface) WatchTransfer(opts *bind.WatchOpts, sink chan<- *link_token_interface.LinkTokenTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchTransfer") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *link_token_interface.LinkTokenTransfer, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *link_token_interface.LinkTokenTransfer, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *link_token_interface.LinkTokenTransfer, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LinkTokenInterface_WatchTransfer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTransfer' +type LinkTokenInterface_WatchTransfer_Call struct { + *mock.Call +} + +// WatchTransfer is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *link_token_interface.LinkTokenTransfer +// - from []common.Address +// - to []common.Address +func (_e *LinkTokenInterface_Expecter) WatchTransfer(opts interface{}, sink interface{}, from interface{}, to interface{}) *LinkTokenInterface_WatchTransfer_Call { + return &LinkTokenInterface_WatchTransfer_Call{Call: _e.mock.On("WatchTransfer", opts, sink, from, to)} +} + +func (_c *LinkTokenInterface_WatchTransfer_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *link_token_interface.LinkTokenTransfer, from []common.Address, to []common.Address)) *LinkTokenInterface_WatchTransfer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *link_token_interface.LinkTokenTransfer), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *LinkTokenInterface_WatchTransfer_Call) Return(_a0 event.Subscription, _a1 error) *LinkTokenInterface_WatchTransfer_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LinkTokenInterface_WatchTransfer_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *link_token_interface.LinkTokenTransfer, []common.Address, []common.Address) (event.Subscription, error)) *LinkTokenInterface_WatchTransfer_Call { + _c.Call.Return(run) + return _c +} + +// NewLinkTokenInterface creates a new instance of LinkTokenInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewLinkTokenInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *LinkTokenInterface { + mock := &LinkTokenInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/ccip/mocks/price_registry_interface.go b/core/gethwrappers/ccip/mocks/price_registry_interface.go new file mode 100644 index 0000000000..8c2834acce --- /dev/null +++ b/core/gethwrappers/ccip/mocks/price_registry_interface.go @@ -0,0 +1,4555 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_contracts + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + mock "github.com/stretchr/testify/mock" + + price_registry "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// PriceRegistryInterface is an autogenerated mock type for the PriceRegistryInterface type +type PriceRegistryInterface struct { + mock.Mock +} + +type PriceRegistryInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *PriceRegistryInterface) EXPECT() *PriceRegistryInterface_Expecter { + return &PriceRegistryInterface_Expecter{mock: &_m.Mock} +} + +// AcceptOwnership provides a mock function with given fields: opts +func (_m *PriceRegistryInterface) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for AcceptOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_AcceptOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AcceptOwnership' +type PriceRegistryInterface_AcceptOwnership_Call struct { + *mock.Call +} + +// AcceptOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *PriceRegistryInterface_Expecter) AcceptOwnership(opts interface{}) *PriceRegistryInterface_AcceptOwnership_Call { + return &PriceRegistryInterface_AcceptOwnership_Call{Call: _e.mock.On("AcceptOwnership", opts)} +} + +func (_c *PriceRegistryInterface_AcceptOwnership_Call) Run(run func(opts *bind.TransactOpts)) *PriceRegistryInterface_AcceptOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *PriceRegistryInterface_AcceptOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_AcceptOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_AcceptOwnership_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *PriceRegistryInterface_AcceptOwnership_Call { + _c.Call.Return(run) + return _c +} + +// Address provides a mock function with given fields: +func (_m *PriceRegistryInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// PriceRegistryInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type PriceRegistryInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *PriceRegistryInterface_Expecter) Address() *PriceRegistryInterface_Address_Call { + return &PriceRegistryInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *PriceRegistryInterface_Address_Call) Run(run func()) *PriceRegistryInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *PriceRegistryInterface_Address_Call) Return(_a0 common.Address) *PriceRegistryInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *PriceRegistryInterface_Address_Call) RunAndReturn(run func() common.Address) *PriceRegistryInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// ApplyAuthorizedCallerUpdates provides a mock function with given fields: opts, authorizedCallerArgs +func (_m *PriceRegistryInterface) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs price_registry.AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + ret := _m.Called(opts, authorizedCallerArgs) + + if len(ret) == 0 { + panic("no return value specified for ApplyAuthorizedCallerUpdates") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, price_registry.AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error)); ok { + return rf(opts, authorizedCallerArgs) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, price_registry.AuthorizedCallersAuthorizedCallerArgs) *types.Transaction); ok { + r0 = rf(opts, authorizedCallerArgs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, price_registry.AuthorizedCallersAuthorizedCallerArgs) error); ok { + r1 = rf(opts, authorizedCallerArgs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyAuthorizedCallerUpdates' +type PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call struct { + *mock.Call +} + +// ApplyAuthorizedCallerUpdates is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - authorizedCallerArgs price_registry.AuthorizedCallersAuthorizedCallerArgs +func (_e *PriceRegistryInterface_Expecter) ApplyAuthorizedCallerUpdates(opts interface{}, authorizedCallerArgs interface{}) *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call { + return &PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call{Call: _e.mock.On("ApplyAuthorizedCallerUpdates", opts, authorizedCallerArgs)} +} + +func (_c *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call) Run(run func(opts *bind.TransactOpts, authorizedCallerArgs price_registry.AuthorizedCallersAuthorizedCallerArgs)) *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(price_registry.AuthorizedCallersAuthorizedCallerArgs)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, price_registry.AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error)) *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call { + _c.Call.Return(run) + return _c +} + +// ApplyDestChainConfigUpdates provides a mock function with given fields: opts, destChainConfigArgs +func (_m *PriceRegistryInterface) ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []price_registry.PriceRegistryDestChainConfigArgs) (*types.Transaction, error) { + ret := _m.Called(opts, destChainConfigArgs) + + if len(ret) == 0 { + panic("no return value specified for ApplyDestChainConfigUpdates") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryDestChainConfigArgs) (*types.Transaction, error)); ok { + return rf(opts, destChainConfigArgs) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryDestChainConfigArgs) *types.Transaction); ok { + r0 = rf(opts, destChainConfigArgs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []price_registry.PriceRegistryDestChainConfigArgs) error); ok { + r1 = rf(opts, destChainConfigArgs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ApplyDestChainConfigUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyDestChainConfigUpdates' +type PriceRegistryInterface_ApplyDestChainConfigUpdates_Call struct { + *mock.Call +} + +// ApplyDestChainConfigUpdates is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - destChainConfigArgs []price_registry.PriceRegistryDestChainConfigArgs +func (_e *PriceRegistryInterface_Expecter) ApplyDestChainConfigUpdates(opts interface{}, destChainConfigArgs interface{}) *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call { + return &PriceRegistryInterface_ApplyDestChainConfigUpdates_Call{Call: _e.mock.On("ApplyDestChainConfigUpdates", opts, destChainConfigArgs)} +} + +func (_c *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call) Run(run func(opts *bind.TransactOpts, destChainConfigArgs []price_registry.PriceRegistryDestChainConfigArgs)) *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]price_registry.PriceRegistryDestChainConfigArgs)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []price_registry.PriceRegistryDestChainConfigArgs) (*types.Transaction, error)) *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call { + _c.Call.Return(run) + return _c +} + +// ApplyFeeTokensUpdates provides a mock function with given fields: opts, feeTokensToAdd, feeTokensToRemove +func (_m *PriceRegistryInterface) ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, feeTokensToAdd, feeTokensToRemove) + + if len(ret) == 0 { + panic("no return value specified for ApplyFeeTokensUpdates") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address) (*types.Transaction, error)); ok { + return rf(opts, feeTokensToAdd, feeTokensToRemove) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address) *types.Transaction); ok { + r0 = rf(opts, feeTokensToAdd, feeTokensToRemove) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, feeTokensToAdd, feeTokensToRemove) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ApplyFeeTokensUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyFeeTokensUpdates' +type PriceRegistryInterface_ApplyFeeTokensUpdates_Call struct { + *mock.Call +} + +// ApplyFeeTokensUpdates is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - feeTokensToAdd []common.Address +// - feeTokensToRemove []common.Address +func (_e *PriceRegistryInterface_Expecter) ApplyFeeTokensUpdates(opts interface{}, feeTokensToAdd interface{}, feeTokensToRemove interface{}) *PriceRegistryInterface_ApplyFeeTokensUpdates_Call { + return &PriceRegistryInterface_ApplyFeeTokensUpdates_Call{Call: _e.mock.On("ApplyFeeTokensUpdates", opts, feeTokensToAdd, feeTokensToRemove)} +} + +func (_c *PriceRegistryInterface_ApplyFeeTokensUpdates_Call) Run(run func(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address)) *PriceRegistryInterface_ApplyFeeTokensUpdates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ApplyFeeTokensUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_ApplyFeeTokensUpdates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ApplyFeeTokensUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []common.Address, []common.Address) (*types.Transaction, error)) *PriceRegistryInterface_ApplyFeeTokensUpdates_Call { + _c.Call.Return(run) + return _c +} + +// ApplyPremiumMultiplierWeiPerEthUpdates provides a mock function with given fields: opts, premiumMultiplierWeiPerEthArgs +func (_m *PriceRegistryInterface) ApplyPremiumMultiplierWeiPerEthUpdates(opts *bind.TransactOpts, premiumMultiplierWeiPerEthArgs []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) { + ret := _m.Called(opts, premiumMultiplierWeiPerEthArgs) + + if len(ret) == 0 { + panic("no return value specified for ApplyPremiumMultiplierWeiPerEthUpdates") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error)); ok { + return rf(opts, premiumMultiplierWeiPerEthArgs) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs) *types.Transaction); ok { + r0 = rf(opts, premiumMultiplierWeiPerEthArgs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs) error); ok { + r1 = rf(opts, premiumMultiplierWeiPerEthArgs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyPremiumMultiplierWeiPerEthUpdates' +type PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call struct { + *mock.Call +} + +// ApplyPremiumMultiplierWeiPerEthUpdates is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - premiumMultiplierWeiPerEthArgs []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs +func (_e *PriceRegistryInterface_Expecter) ApplyPremiumMultiplierWeiPerEthUpdates(opts interface{}, premiumMultiplierWeiPerEthArgs interface{}) *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call { + return &PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call{Call: _e.mock.On("ApplyPremiumMultiplierWeiPerEthUpdates", opts, premiumMultiplierWeiPerEthArgs)} +} + +func (_c *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call) Run(run func(opts *bind.TransactOpts, premiumMultiplierWeiPerEthArgs []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs)) *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error)) *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call { + _c.Call.Return(run) + return _c +} + +// ApplyTokenTransferFeeConfigUpdates provides a mock function with given fields: opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs +func (_m *PriceRegistryInterface) ApplyTokenTransferFeeConfigUpdates(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []price_registry.PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) { + ret := _m.Called(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) + + if len(ret) == 0 { + panic("no return value specified for ApplyTokenTransferFeeConfigUpdates") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryTokenTransferFeeConfigArgs, []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error)); ok { + return rf(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryTokenTransferFeeConfigArgs, []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs) *types.Transaction); ok { + r0 = rf(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []price_registry.PriceRegistryTokenTransferFeeConfigArgs, []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs) error); ok { + r1 = rf(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyTokenTransferFeeConfigUpdates' +type PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call struct { + *mock.Call +} + +// ApplyTokenTransferFeeConfigUpdates is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - tokenTransferFeeConfigArgs []price_registry.PriceRegistryTokenTransferFeeConfigArgs +// - tokensToUseDefaultFeeConfigs []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs +func (_e *PriceRegistryInterface_Expecter) ApplyTokenTransferFeeConfigUpdates(opts interface{}, tokenTransferFeeConfigArgs interface{}, tokensToUseDefaultFeeConfigs interface{}) *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call { + return &PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call{Call: _e.mock.On("ApplyTokenTransferFeeConfigUpdates", opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs)} +} + +func (_c *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call) Run(run func(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []price_registry.PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs)) *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]price_registry.PriceRegistryTokenTransferFeeConfigArgs), args[2].([]price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []price_registry.PriceRegistryTokenTransferFeeConfigArgs, []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error)) *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call { + _c.Call.Return(run) + return _c +} + +// ConvertTokenAmount provides a mock function with given fields: opts, fromToken, fromTokenAmount, toToken +func (_m *PriceRegistryInterface) ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + ret := _m.Called(opts, fromToken, fromTokenAmount, toToken) + + if len(ret) == 0 { + panic("no return value specified for ConvertTokenAmount") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, *big.Int, common.Address) (*big.Int, error)); ok { + return rf(opts, fromToken, fromTokenAmount, toToken) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, *big.Int, common.Address) *big.Int); ok { + r0 = rf(opts, fromToken, fromTokenAmount, toToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address, *big.Int, common.Address) error); ok { + r1 = rf(opts, fromToken, fromTokenAmount, toToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ConvertTokenAmount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ConvertTokenAmount' +type PriceRegistryInterface_ConvertTokenAmount_Call struct { + *mock.Call +} + +// ConvertTokenAmount is a helper method to define mock.On call +// - opts *bind.CallOpts +// - fromToken common.Address +// - fromTokenAmount *big.Int +// - toToken common.Address +func (_e *PriceRegistryInterface_Expecter) ConvertTokenAmount(opts interface{}, fromToken interface{}, fromTokenAmount interface{}, toToken interface{}) *PriceRegistryInterface_ConvertTokenAmount_Call { + return &PriceRegistryInterface_ConvertTokenAmount_Call{Call: _e.mock.On("ConvertTokenAmount", opts, fromToken, fromTokenAmount, toToken)} +} + +func (_c *PriceRegistryInterface_ConvertTokenAmount_Call) Run(run func(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address)) *PriceRegistryInterface_ConvertTokenAmount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address), args[2].(*big.Int), args[3].(common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ConvertTokenAmount_Call) Return(_a0 *big.Int, _a1 error) *PriceRegistryInterface_ConvertTokenAmount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ConvertTokenAmount_Call) RunAndReturn(run func(*bind.CallOpts, common.Address, *big.Int, common.Address) (*big.Int, error)) *PriceRegistryInterface_ConvertTokenAmount_Call { + _c.Call.Return(run) + return _c +} + +// FilterAuthorizedCallerAdded provides a mock function with given fields: opts +func (_m *PriceRegistryInterface) FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*price_registry.PriceRegistryAuthorizedCallerAddedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterAuthorizedCallerAdded") + } + + var r0 *price_registry.PriceRegistryAuthorizedCallerAddedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*price_registry.PriceRegistryAuthorizedCallerAddedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *price_registry.PriceRegistryAuthorizedCallerAddedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryAuthorizedCallerAddedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterAuthorizedCallerAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterAuthorizedCallerAdded' +type PriceRegistryInterface_FilterAuthorizedCallerAdded_Call struct { + *mock.Call +} + +// FilterAuthorizedCallerAdded is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *PriceRegistryInterface_Expecter) FilterAuthorizedCallerAdded(opts interface{}) *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call { + return &PriceRegistryInterface_FilterAuthorizedCallerAdded_Call{Call: _e.mock.On("FilterAuthorizedCallerAdded", opts)} +} + +func (_c *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call) Run(run func(opts *bind.FilterOpts)) *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call) Return(_a0 *price_registry.PriceRegistryAuthorizedCallerAddedIterator, _a1 error) *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call) RunAndReturn(run func(*bind.FilterOpts) (*price_registry.PriceRegistryAuthorizedCallerAddedIterator, error)) *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call { + _c.Call.Return(run) + return _c +} + +// FilterAuthorizedCallerRemoved provides a mock function with given fields: opts +func (_m *PriceRegistryInterface) FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*price_registry.PriceRegistryAuthorizedCallerRemovedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterAuthorizedCallerRemoved") + } + + var r0 *price_registry.PriceRegistryAuthorizedCallerRemovedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*price_registry.PriceRegistryAuthorizedCallerRemovedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *price_registry.PriceRegistryAuthorizedCallerRemovedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryAuthorizedCallerRemovedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterAuthorizedCallerRemoved' +type PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call struct { + *mock.Call +} + +// FilterAuthorizedCallerRemoved is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *PriceRegistryInterface_Expecter) FilterAuthorizedCallerRemoved(opts interface{}) *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call { + return &PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call{Call: _e.mock.On("FilterAuthorizedCallerRemoved", opts)} +} + +func (_c *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call) Run(run func(opts *bind.FilterOpts)) *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call) Return(_a0 *price_registry.PriceRegistryAuthorizedCallerRemovedIterator, _a1 error) *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call) RunAndReturn(run func(*bind.FilterOpts) (*price_registry.PriceRegistryAuthorizedCallerRemovedIterator, error)) *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call { + _c.Call.Return(run) + return _c +} + +// FilterDestChainAdded provides a mock function with given fields: opts, destChainSelector +func (_m *PriceRegistryInterface) FilterDestChainAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*price_registry.PriceRegistryDestChainAddedIterator, error) { + ret := _m.Called(opts, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for FilterDestChainAdded") + } + + var r0 *price_registry.PriceRegistryDestChainAddedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*price_registry.PriceRegistryDestChainAddedIterator, error)); ok { + return rf(opts, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *price_registry.PriceRegistryDestChainAddedIterator); ok { + r0 = rf(opts, destChainSelector) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryDestChainAddedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { + r1 = rf(opts, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterDestChainAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterDestChainAdded' +type PriceRegistryInterface_FilterDestChainAdded_Call struct { + *mock.Call +} + +// FilterDestChainAdded is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - destChainSelector []uint64 +func (_e *PriceRegistryInterface_Expecter) FilterDestChainAdded(opts interface{}, destChainSelector interface{}) *PriceRegistryInterface_FilterDestChainAdded_Call { + return &PriceRegistryInterface_FilterDestChainAdded_Call{Call: _e.mock.On("FilterDestChainAdded", opts, destChainSelector)} +} + +func (_c *PriceRegistryInterface_FilterDestChainAdded_Call) Run(run func(opts *bind.FilterOpts, destChainSelector []uint64)) *PriceRegistryInterface_FilterDestChainAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterDestChainAdded_Call) Return(_a0 *price_registry.PriceRegistryDestChainAddedIterator, _a1 error) *PriceRegistryInterface_FilterDestChainAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterDestChainAdded_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*price_registry.PriceRegistryDestChainAddedIterator, error)) *PriceRegistryInterface_FilterDestChainAdded_Call { + _c.Call.Return(run) + return _c +} + +// FilterDestChainConfigUpdated provides a mock function with given fields: opts, destChainSelector +func (_m *PriceRegistryInterface) FilterDestChainConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*price_registry.PriceRegistryDestChainConfigUpdatedIterator, error) { + ret := _m.Called(opts, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for FilterDestChainConfigUpdated") + } + + var r0 *price_registry.PriceRegistryDestChainConfigUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*price_registry.PriceRegistryDestChainConfigUpdatedIterator, error)); ok { + return rf(opts, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *price_registry.PriceRegistryDestChainConfigUpdatedIterator); ok { + r0 = rf(opts, destChainSelector) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryDestChainConfigUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { + r1 = rf(opts, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterDestChainConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterDestChainConfigUpdated' +type PriceRegistryInterface_FilterDestChainConfigUpdated_Call struct { + *mock.Call +} + +// FilterDestChainConfigUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - destChainSelector []uint64 +func (_e *PriceRegistryInterface_Expecter) FilterDestChainConfigUpdated(opts interface{}, destChainSelector interface{}) *PriceRegistryInterface_FilterDestChainConfigUpdated_Call { + return &PriceRegistryInterface_FilterDestChainConfigUpdated_Call{Call: _e.mock.On("FilterDestChainConfigUpdated", opts, destChainSelector)} +} + +func (_c *PriceRegistryInterface_FilterDestChainConfigUpdated_Call) Run(run func(opts *bind.FilterOpts, destChainSelector []uint64)) *PriceRegistryInterface_FilterDestChainConfigUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterDestChainConfigUpdated_Call) Return(_a0 *price_registry.PriceRegistryDestChainConfigUpdatedIterator, _a1 error) *PriceRegistryInterface_FilterDestChainConfigUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterDestChainConfigUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*price_registry.PriceRegistryDestChainConfigUpdatedIterator, error)) *PriceRegistryInterface_FilterDestChainConfigUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FilterFeeTokenAdded provides a mock function with given fields: opts, feeToken +func (_m *PriceRegistryInterface) FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*price_registry.PriceRegistryFeeTokenAddedIterator, error) { + ret := _m.Called(opts, feeToken) + + if len(ret) == 0 { + panic("no return value specified for FilterFeeTokenAdded") + } + + var r0 *price_registry.PriceRegistryFeeTokenAddedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryFeeTokenAddedIterator, error)); ok { + return rf(opts, feeToken) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryFeeTokenAddedIterator); ok { + r0 = rf(opts, feeToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryFeeTokenAddedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, feeToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterFeeTokenAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterFeeTokenAdded' +type PriceRegistryInterface_FilterFeeTokenAdded_Call struct { + *mock.Call +} + +// FilterFeeTokenAdded is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - feeToken []common.Address +func (_e *PriceRegistryInterface_Expecter) FilterFeeTokenAdded(opts interface{}, feeToken interface{}) *PriceRegistryInterface_FilterFeeTokenAdded_Call { + return &PriceRegistryInterface_FilterFeeTokenAdded_Call{Call: _e.mock.On("FilterFeeTokenAdded", opts, feeToken)} +} + +func (_c *PriceRegistryInterface_FilterFeeTokenAdded_Call) Run(run func(opts *bind.FilterOpts, feeToken []common.Address)) *PriceRegistryInterface_FilterFeeTokenAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterFeeTokenAdded_Call) Return(_a0 *price_registry.PriceRegistryFeeTokenAddedIterator, _a1 error) *PriceRegistryInterface_FilterFeeTokenAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterFeeTokenAdded_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryFeeTokenAddedIterator, error)) *PriceRegistryInterface_FilterFeeTokenAdded_Call { + _c.Call.Return(run) + return _c +} + +// FilterFeeTokenRemoved provides a mock function with given fields: opts, feeToken +func (_m *PriceRegistryInterface) FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*price_registry.PriceRegistryFeeTokenRemovedIterator, error) { + ret := _m.Called(opts, feeToken) + + if len(ret) == 0 { + panic("no return value specified for FilterFeeTokenRemoved") + } + + var r0 *price_registry.PriceRegistryFeeTokenRemovedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryFeeTokenRemovedIterator, error)); ok { + return rf(opts, feeToken) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryFeeTokenRemovedIterator); ok { + r0 = rf(opts, feeToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryFeeTokenRemovedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, feeToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterFeeTokenRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterFeeTokenRemoved' +type PriceRegistryInterface_FilterFeeTokenRemoved_Call struct { + *mock.Call +} + +// FilterFeeTokenRemoved is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - feeToken []common.Address +func (_e *PriceRegistryInterface_Expecter) FilterFeeTokenRemoved(opts interface{}, feeToken interface{}) *PriceRegistryInterface_FilterFeeTokenRemoved_Call { + return &PriceRegistryInterface_FilterFeeTokenRemoved_Call{Call: _e.mock.On("FilterFeeTokenRemoved", opts, feeToken)} +} + +func (_c *PriceRegistryInterface_FilterFeeTokenRemoved_Call) Run(run func(opts *bind.FilterOpts, feeToken []common.Address)) *PriceRegistryInterface_FilterFeeTokenRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterFeeTokenRemoved_Call) Return(_a0 *price_registry.PriceRegistryFeeTokenRemovedIterator, _a1 error) *PriceRegistryInterface_FilterFeeTokenRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterFeeTokenRemoved_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryFeeTokenRemovedIterator, error)) *PriceRegistryInterface_FilterFeeTokenRemoved_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferRequested provides a mock function with given fields: opts, from, to +func (_m *PriceRegistryInterface) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*price_registry.PriceRegistryOwnershipTransferRequestedIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferRequested") + } + + var r0 *price_registry.PriceRegistryOwnershipTransferRequestedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*price_registry.PriceRegistryOwnershipTransferRequestedIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *price_registry.PriceRegistryOwnershipTransferRequestedIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryOwnershipTransferRequestedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferRequested' +type PriceRegistryInterface_FilterOwnershipTransferRequested_Call struct { + *mock.Call +} + +// FilterOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *PriceRegistryInterface_Expecter) FilterOwnershipTransferRequested(opts interface{}, from interface{}, to interface{}) *PriceRegistryInterface_FilterOwnershipTransferRequested_Call { + return &PriceRegistryInterface_FilterOwnershipTransferRequested_Call{Call: _e.mock.On("FilterOwnershipTransferRequested", opts, from, to)} +} + +func (_c *PriceRegistryInterface_FilterOwnershipTransferRequested_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *PriceRegistryInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterOwnershipTransferRequested_Call) Return(_a0 *price_registry.PriceRegistryOwnershipTransferRequestedIterator, _a1 error) *PriceRegistryInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*price_registry.PriceRegistryOwnershipTransferRequestedIterator, error)) *PriceRegistryInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferred provides a mock function with given fields: opts, from, to +func (_m *PriceRegistryInterface) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*price_registry.PriceRegistryOwnershipTransferredIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferred") + } + + var r0 *price_registry.PriceRegistryOwnershipTransferredIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*price_registry.PriceRegistryOwnershipTransferredIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *price_registry.PriceRegistryOwnershipTransferredIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryOwnershipTransferredIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferred' +type PriceRegistryInterface_FilterOwnershipTransferred_Call struct { + *mock.Call +} + +// FilterOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *PriceRegistryInterface_Expecter) FilterOwnershipTransferred(opts interface{}, from interface{}, to interface{}) *PriceRegistryInterface_FilterOwnershipTransferred_Call { + return &PriceRegistryInterface_FilterOwnershipTransferred_Call{Call: _e.mock.On("FilterOwnershipTransferred", opts, from, to)} +} + +func (_c *PriceRegistryInterface_FilterOwnershipTransferred_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *PriceRegistryInterface_FilterOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterOwnershipTransferred_Call) Return(_a0 *price_registry.PriceRegistryOwnershipTransferredIterator, _a1 error) *PriceRegistryInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterOwnershipTransferred_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*price_registry.PriceRegistryOwnershipTransferredIterator, error)) *PriceRegistryInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// FilterPremiumMultiplierWeiPerEthUpdated provides a mock function with given fields: opts, token +func (_m *PriceRegistryInterface) FilterPremiumMultiplierWeiPerEthUpdated(opts *bind.FilterOpts, token []common.Address) (*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for FilterPremiumMultiplierWeiPerEthUpdated") + } + + var r0 *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator); ok { + r0 = rf(opts, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPremiumMultiplierWeiPerEthUpdated' +type PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call struct { + *mock.Call +} + +// FilterPremiumMultiplierWeiPerEthUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - token []common.Address +func (_e *PriceRegistryInterface_Expecter) FilterPremiumMultiplierWeiPerEthUpdated(opts interface{}, token interface{}) *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call { + return &PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call{Call: _e.mock.On("FilterPremiumMultiplierWeiPerEthUpdated", opts, token)} +} + +func (_c *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call) Run(run func(opts *bind.FilterOpts, token []common.Address)) *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call) Return(_a0 *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator, _a1 error) *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator, error)) *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FilterPriceFeedPerTokenUpdated provides a mock function with given fields: opts, token +func (_m *PriceRegistryInterface) FilterPriceFeedPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for FilterPriceFeedPerTokenUpdated") + } + + var r0 *price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator); ok { + r0 = rf(opts, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPriceFeedPerTokenUpdated' +type PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call struct { + *mock.Call +} + +// FilterPriceFeedPerTokenUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - token []common.Address +func (_e *PriceRegistryInterface_Expecter) FilterPriceFeedPerTokenUpdated(opts interface{}, token interface{}) *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call { + return &PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call{Call: _e.mock.On("FilterPriceFeedPerTokenUpdated", opts, token)} +} + +func (_c *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call) Run(run func(opts *bind.FilterOpts, token []common.Address)) *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call) Return(_a0 *price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator, _a1 error) *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator, error)) *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FilterPriceUpdaterRemoved provides a mock function with given fields: opts, priceUpdater +func (_m *PriceRegistryInterface) FilterPriceUpdaterRemoved(opts *bind.FilterOpts, priceUpdater []common.Address) (*price_registry.PriceRegistryPriceUpdaterRemovedIterator, error) { + ret := _m.Called(opts, priceUpdater) + + if len(ret) == 0 { + panic("no return value specified for FilterPriceUpdaterRemoved") + } + + var r0 *price_registry.PriceRegistryPriceUpdaterRemovedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPriceUpdaterRemovedIterator, error)); ok { + return rf(opts, priceUpdater) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryPriceUpdaterRemovedIterator); ok { + r0 = rf(opts, priceUpdater) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryPriceUpdaterRemovedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, priceUpdater) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterPriceUpdaterRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPriceUpdaterRemoved' +type PriceRegistryInterface_FilterPriceUpdaterRemoved_Call struct { + *mock.Call +} + +// FilterPriceUpdaterRemoved is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - priceUpdater []common.Address +func (_e *PriceRegistryInterface_Expecter) FilterPriceUpdaterRemoved(opts interface{}, priceUpdater interface{}) *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call { + return &PriceRegistryInterface_FilterPriceUpdaterRemoved_Call{Call: _e.mock.On("FilterPriceUpdaterRemoved", opts, priceUpdater)} +} + +func (_c *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call) Run(run func(opts *bind.FilterOpts, priceUpdater []common.Address)) *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call) Return(_a0 *price_registry.PriceRegistryPriceUpdaterRemovedIterator, _a1 error) *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPriceUpdaterRemovedIterator, error)) *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call { + _c.Call.Return(run) + return _c +} + +// FilterPriceUpdaterSet provides a mock function with given fields: opts, priceUpdater +func (_m *PriceRegistryInterface) FilterPriceUpdaterSet(opts *bind.FilterOpts, priceUpdater []common.Address) (*price_registry.PriceRegistryPriceUpdaterSetIterator, error) { + ret := _m.Called(opts, priceUpdater) + + if len(ret) == 0 { + panic("no return value specified for FilterPriceUpdaterSet") + } + + var r0 *price_registry.PriceRegistryPriceUpdaterSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPriceUpdaterSetIterator, error)); ok { + return rf(opts, priceUpdater) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryPriceUpdaterSetIterator); ok { + r0 = rf(opts, priceUpdater) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryPriceUpdaterSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, priceUpdater) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterPriceUpdaterSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPriceUpdaterSet' +type PriceRegistryInterface_FilterPriceUpdaterSet_Call struct { + *mock.Call +} + +// FilterPriceUpdaterSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - priceUpdater []common.Address +func (_e *PriceRegistryInterface_Expecter) FilterPriceUpdaterSet(opts interface{}, priceUpdater interface{}) *PriceRegistryInterface_FilterPriceUpdaterSet_Call { + return &PriceRegistryInterface_FilterPriceUpdaterSet_Call{Call: _e.mock.On("FilterPriceUpdaterSet", opts, priceUpdater)} +} + +func (_c *PriceRegistryInterface_FilterPriceUpdaterSet_Call) Run(run func(opts *bind.FilterOpts, priceUpdater []common.Address)) *PriceRegistryInterface_FilterPriceUpdaterSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterPriceUpdaterSet_Call) Return(_a0 *price_registry.PriceRegistryPriceUpdaterSetIterator, _a1 error) *PriceRegistryInterface_FilterPriceUpdaterSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterPriceUpdaterSet_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPriceUpdaterSetIterator, error)) *PriceRegistryInterface_FilterPriceUpdaterSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterTokenTransferFeeConfigDeleted provides a mock function with given fields: opts, destChainSelector, token +func (_m *PriceRegistryInterface) FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator, error) { + ret := _m.Called(opts, destChainSelector, token) + + if len(ret) == 0 { + panic("no return value specified for FilterTokenTransferFeeConfigDeleted") + } + + var r0 *price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator, error)); ok { + return rf(opts, destChainSelector, token) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) *price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator); ok { + r0 = rf(opts, destChainSelector, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, []common.Address) error); ok { + r1 = rf(opts, destChainSelector, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTokenTransferFeeConfigDeleted' +type PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call struct { + *mock.Call +} + +// FilterTokenTransferFeeConfigDeleted is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - destChainSelector []uint64 +// - token []common.Address +func (_e *PriceRegistryInterface_Expecter) FilterTokenTransferFeeConfigDeleted(opts interface{}, destChainSelector interface{}, token interface{}) *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call { + return &PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call{Call: _e.mock.On("FilterTokenTransferFeeConfigDeleted", opts, destChainSelector, token)} +} + +func (_c *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call) Run(run func(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address)) *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call) Return(_a0 *price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator, _a1 error) *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator, error)) *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(run) + return _c +} + +// FilterTokenTransferFeeConfigUpdated provides a mock function with given fields: opts, destChainSelector, token +func (_m *PriceRegistryInterface) FilterTokenTransferFeeConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator, error) { + ret := _m.Called(opts, destChainSelector, token) + + if len(ret) == 0 { + panic("no return value specified for FilterTokenTransferFeeConfigUpdated") + } + + var r0 *price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator, error)); ok { + return rf(opts, destChainSelector, token) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) *price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator); ok { + r0 = rf(opts, destChainSelector, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, []common.Address) error); ok { + r1 = rf(opts, destChainSelector, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTokenTransferFeeConfigUpdated' +type PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call struct { + *mock.Call +} + +// FilterTokenTransferFeeConfigUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - destChainSelector []uint64 +// - token []common.Address +func (_e *PriceRegistryInterface_Expecter) FilterTokenTransferFeeConfigUpdated(opts interface{}, destChainSelector interface{}, token interface{}) *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call { + return &PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call{Call: _e.mock.On("FilterTokenTransferFeeConfigUpdated", opts, destChainSelector, token)} +} + +func (_c *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call) Run(run func(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address)) *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call) Return(_a0 *price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator, _a1 error) *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator, error)) *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FilterUsdPerTokenUpdated provides a mock function with given fields: opts, token +func (_m *PriceRegistryInterface) FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*price_registry.PriceRegistryUsdPerTokenUpdatedIterator, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for FilterUsdPerTokenUpdated") + } + + var r0 *price_registry.PriceRegistryUsdPerTokenUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryUsdPerTokenUpdatedIterator, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryUsdPerTokenUpdatedIterator); ok { + r0 = rf(opts, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryUsdPerTokenUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterUsdPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterUsdPerTokenUpdated' +type PriceRegistryInterface_FilterUsdPerTokenUpdated_Call struct { + *mock.Call +} + +// FilterUsdPerTokenUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - token []common.Address +func (_e *PriceRegistryInterface_Expecter) FilterUsdPerTokenUpdated(opts interface{}, token interface{}) *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call { + return &PriceRegistryInterface_FilterUsdPerTokenUpdated_Call{Call: _e.mock.On("FilterUsdPerTokenUpdated", opts, token)} +} + +func (_c *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call) Run(run func(opts *bind.FilterOpts, token []common.Address)) *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call) Return(_a0 *price_registry.PriceRegistryUsdPerTokenUpdatedIterator, _a1 error) *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryUsdPerTokenUpdatedIterator, error)) *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FilterUsdPerUnitGasUpdated provides a mock function with given fields: opts, destChain +func (_m *PriceRegistryInterface) FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator, error) { + ret := _m.Called(opts, destChain) + + if len(ret) == 0 { + panic("no return value specified for FilterUsdPerUnitGasUpdated") + } + + var r0 *price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator, error)); ok { + return rf(opts, destChain) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator); ok { + r0 = rf(opts, destChain) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { + r1 = rf(opts, destChain) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterUsdPerUnitGasUpdated' +type PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call struct { + *mock.Call +} + +// FilterUsdPerUnitGasUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - destChain []uint64 +func (_e *PriceRegistryInterface_Expecter) FilterUsdPerUnitGasUpdated(opts interface{}, destChain interface{}) *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call { + return &PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call{Call: _e.mock.On("FilterUsdPerUnitGasUpdated", opts, destChain)} +} + +func (_c *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call) Run(run func(opts *bind.FilterOpts, destChain []uint64)) *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call) Return(_a0 *price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator, _a1 error) *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator, error)) *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call { + _c.Call.Return(run) + return _c +} + +// GetAllAuthorizedCallers provides a mock function with given fields: opts +func (_m *PriceRegistryInterface) GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetAllAuthorizedCallers") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetAllAuthorizedCallers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAllAuthorizedCallers' +type PriceRegistryInterface_GetAllAuthorizedCallers_Call struct { + *mock.Call +} + +// GetAllAuthorizedCallers is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *PriceRegistryInterface_Expecter) GetAllAuthorizedCallers(opts interface{}) *PriceRegistryInterface_GetAllAuthorizedCallers_Call { + return &PriceRegistryInterface_GetAllAuthorizedCallers_Call{Call: _e.mock.On("GetAllAuthorizedCallers", opts)} +} + +func (_c *PriceRegistryInterface_GetAllAuthorizedCallers_Call) Run(run func(opts *bind.CallOpts)) *PriceRegistryInterface_GetAllAuthorizedCallers_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetAllAuthorizedCallers_Call) Return(_a0 []common.Address, _a1 error) *PriceRegistryInterface_GetAllAuthorizedCallers_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetAllAuthorizedCallers_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *PriceRegistryInterface_GetAllAuthorizedCallers_Call { + _c.Call.Return(run) + return _c +} + +// GetDestChainConfig provides a mock function with given fields: opts, destChainSelector +func (_m *PriceRegistryInterface) GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (price_registry.PriceRegistryDestChainConfig, error) { + ret := _m.Called(opts, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for GetDestChainConfig") + } + + var r0 price_registry.PriceRegistryDestChainConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (price_registry.PriceRegistryDestChainConfig, error)); ok { + return rf(opts, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) price_registry.PriceRegistryDestChainConfig); ok { + r0 = rf(opts, destChainSelector) + } else { + r0 = ret.Get(0).(price_registry.PriceRegistryDestChainConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetDestChainConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDestChainConfig' +type PriceRegistryInterface_GetDestChainConfig_Call struct { + *mock.Call +} + +// GetDestChainConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +func (_e *PriceRegistryInterface_Expecter) GetDestChainConfig(opts interface{}, destChainSelector interface{}) *PriceRegistryInterface_GetDestChainConfig_Call { + return &PriceRegistryInterface_GetDestChainConfig_Call{Call: _e.mock.On("GetDestChainConfig", opts, destChainSelector)} +} + +func (_c *PriceRegistryInterface_GetDestChainConfig_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64)) *PriceRegistryInterface_GetDestChainConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetDestChainConfig_Call) Return(_a0 price_registry.PriceRegistryDestChainConfig, _a1 error) *PriceRegistryInterface_GetDestChainConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetDestChainConfig_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (price_registry.PriceRegistryDestChainConfig, error)) *PriceRegistryInterface_GetDestChainConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetDestinationChainGasPrice provides a mock function with given fields: opts, destChainSelector +func (_m *PriceRegistryInterface) GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (price_registry.InternalTimestampedPackedUint224, error) { + ret := _m.Called(opts, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for GetDestinationChainGasPrice") + } + + var r0 price_registry.InternalTimestampedPackedUint224 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (price_registry.InternalTimestampedPackedUint224, error)); ok { + return rf(opts, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) price_registry.InternalTimestampedPackedUint224); ok { + r0 = rf(opts, destChainSelector) + } else { + r0 = ret.Get(0).(price_registry.InternalTimestampedPackedUint224) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetDestinationChainGasPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDestinationChainGasPrice' +type PriceRegistryInterface_GetDestinationChainGasPrice_Call struct { + *mock.Call +} + +// GetDestinationChainGasPrice is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +func (_e *PriceRegistryInterface_Expecter) GetDestinationChainGasPrice(opts interface{}, destChainSelector interface{}) *PriceRegistryInterface_GetDestinationChainGasPrice_Call { + return &PriceRegistryInterface_GetDestinationChainGasPrice_Call{Call: _e.mock.On("GetDestinationChainGasPrice", opts, destChainSelector)} +} + +func (_c *PriceRegistryInterface_GetDestinationChainGasPrice_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64)) *PriceRegistryInterface_GetDestinationChainGasPrice_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetDestinationChainGasPrice_Call) Return(_a0 price_registry.InternalTimestampedPackedUint224, _a1 error) *PriceRegistryInterface_GetDestinationChainGasPrice_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetDestinationChainGasPrice_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (price_registry.InternalTimestampedPackedUint224, error)) *PriceRegistryInterface_GetDestinationChainGasPrice_Call { + _c.Call.Return(run) + return _c +} + +// GetFeeTokens provides a mock function with given fields: opts +func (_m *PriceRegistryInterface) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetFeeTokens") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetFeeTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFeeTokens' +type PriceRegistryInterface_GetFeeTokens_Call struct { + *mock.Call +} + +// GetFeeTokens is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *PriceRegistryInterface_Expecter) GetFeeTokens(opts interface{}) *PriceRegistryInterface_GetFeeTokens_Call { + return &PriceRegistryInterface_GetFeeTokens_Call{Call: _e.mock.On("GetFeeTokens", opts)} +} + +func (_c *PriceRegistryInterface_GetFeeTokens_Call) Run(run func(opts *bind.CallOpts)) *PriceRegistryInterface_GetFeeTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetFeeTokens_Call) Return(_a0 []common.Address, _a1 error) *PriceRegistryInterface_GetFeeTokens_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetFeeTokens_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *PriceRegistryInterface_GetFeeTokens_Call { + _c.Call.Return(run) + return _c +} + +// GetPremiumMultiplierWeiPerEth provides a mock function with given fields: opts, token +func (_m *PriceRegistryInterface) GetPremiumMultiplierWeiPerEth(opts *bind.CallOpts, token common.Address) (uint64, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for GetPremiumMultiplierWeiPerEth") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (uint64, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) uint64); ok { + r0 = rf(opts, token) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPremiumMultiplierWeiPerEth' +type PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call struct { + *mock.Call +} + +// GetPremiumMultiplierWeiPerEth is a helper method to define mock.On call +// - opts *bind.CallOpts +// - token common.Address +func (_e *PriceRegistryInterface_Expecter) GetPremiumMultiplierWeiPerEth(opts interface{}, token interface{}) *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call { + return &PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call{Call: _e.mock.On("GetPremiumMultiplierWeiPerEth", opts, token)} +} + +func (_c *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call) Return(_a0 uint64, _a1 error) *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (uint64, error)) *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call { + _c.Call.Return(run) + return _c +} + +// GetStaticConfig provides a mock function with given fields: opts +func (_m *PriceRegistryInterface) GetStaticConfig(opts *bind.CallOpts) (price_registry.PriceRegistryStaticConfig, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetStaticConfig") + } + + var r0 price_registry.PriceRegistryStaticConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (price_registry.PriceRegistryStaticConfig, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) price_registry.PriceRegistryStaticConfig); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(price_registry.PriceRegistryStaticConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetStaticConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStaticConfig' +type PriceRegistryInterface_GetStaticConfig_Call struct { + *mock.Call +} + +// GetStaticConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *PriceRegistryInterface_Expecter) GetStaticConfig(opts interface{}) *PriceRegistryInterface_GetStaticConfig_Call { + return &PriceRegistryInterface_GetStaticConfig_Call{Call: _e.mock.On("GetStaticConfig", opts)} +} + +func (_c *PriceRegistryInterface_GetStaticConfig_Call) Run(run func(opts *bind.CallOpts)) *PriceRegistryInterface_GetStaticConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetStaticConfig_Call) Return(_a0 price_registry.PriceRegistryStaticConfig, _a1 error) *PriceRegistryInterface_GetStaticConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetStaticConfig_Call) RunAndReturn(run func(*bind.CallOpts) (price_registry.PriceRegistryStaticConfig, error)) *PriceRegistryInterface_GetStaticConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenAndGasPrices provides a mock function with given fields: opts, token, destChainSelector +func (_m *PriceRegistryInterface) GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (price_registry.GetTokenAndGasPrices, error) { + ret := _m.Called(opts, token, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for GetTokenAndGasPrices") + } + + var r0 price_registry.GetTokenAndGasPrices + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, uint64) (price_registry.GetTokenAndGasPrices, error)); ok { + return rf(opts, token, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, uint64) price_registry.GetTokenAndGasPrices); ok { + r0 = rf(opts, token, destChainSelector) + } else { + r0 = ret.Get(0).(price_registry.GetTokenAndGasPrices) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address, uint64) error); ok { + r1 = rf(opts, token, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetTokenAndGasPrices_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenAndGasPrices' +type PriceRegistryInterface_GetTokenAndGasPrices_Call struct { + *mock.Call +} + +// GetTokenAndGasPrices is a helper method to define mock.On call +// - opts *bind.CallOpts +// - token common.Address +// - destChainSelector uint64 +func (_e *PriceRegistryInterface_Expecter) GetTokenAndGasPrices(opts interface{}, token interface{}, destChainSelector interface{}) *PriceRegistryInterface_GetTokenAndGasPrices_Call { + return &PriceRegistryInterface_GetTokenAndGasPrices_Call{Call: _e.mock.On("GetTokenAndGasPrices", opts, token, destChainSelector)} +} + +func (_c *PriceRegistryInterface_GetTokenAndGasPrices_Call) Run(run func(opts *bind.CallOpts, token common.Address, destChainSelector uint64)) *PriceRegistryInterface_GetTokenAndGasPrices_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address), args[2].(uint64)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetTokenAndGasPrices_Call) Return(_a0 price_registry.GetTokenAndGasPrices, _a1 error) *PriceRegistryInterface_GetTokenAndGasPrices_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetTokenAndGasPrices_Call) RunAndReturn(run func(*bind.CallOpts, common.Address, uint64) (price_registry.GetTokenAndGasPrices, error)) *PriceRegistryInterface_GetTokenAndGasPrices_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenPrice provides a mock function with given fields: opts, token +func (_m *PriceRegistryInterface) GetTokenPrice(opts *bind.CallOpts, token common.Address) (price_registry.InternalTimestampedPackedUint224, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for GetTokenPrice") + } + + var r0 price_registry.InternalTimestampedPackedUint224 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (price_registry.InternalTimestampedPackedUint224, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) price_registry.InternalTimestampedPackedUint224); ok { + r0 = rf(opts, token) + } else { + r0 = ret.Get(0).(price_registry.InternalTimestampedPackedUint224) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetTokenPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenPrice' +type PriceRegistryInterface_GetTokenPrice_Call struct { + *mock.Call +} + +// GetTokenPrice is a helper method to define mock.On call +// - opts *bind.CallOpts +// - token common.Address +func (_e *PriceRegistryInterface_Expecter) GetTokenPrice(opts interface{}, token interface{}) *PriceRegistryInterface_GetTokenPrice_Call { + return &PriceRegistryInterface_GetTokenPrice_Call{Call: _e.mock.On("GetTokenPrice", opts, token)} +} + +func (_c *PriceRegistryInterface_GetTokenPrice_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *PriceRegistryInterface_GetTokenPrice_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetTokenPrice_Call) Return(_a0 price_registry.InternalTimestampedPackedUint224, _a1 error) *PriceRegistryInterface_GetTokenPrice_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetTokenPrice_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (price_registry.InternalTimestampedPackedUint224, error)) *PriceRegistryInterface_GetTokenPrice_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenPriceFeedConfig provides a mock function with given fields: opts, token +func (_m *PriceRegistryInterface) GetTokenPriceFeedConfig(opts *bind.CallOpts, token common.Address) (price_registry.IPriceRegistryTokenPriceFeedConfig, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for GetTokenPriceFeedConfig") + } + + var r0 price_registry.IPriceRegistryTokenPriceFeedConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (price_registry.IPriceRegistryTokenPriceFeedConfig, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) price_registry.IPriceRegistryTokenPriceFeedConfig); ok { + r0 = rf(opts, token) + } else { + r0 = ret.Get(0).(price_registry.IPriceRegistryTokenPriceFeedConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetTokenPriceFeedConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenPriceFeedConfig' +type PriceRegistryInterface_GetTokenPriceFeedConfig_Call struct { + *mock.Call +} + +// GetTokenPriceFeedConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +// - token common.Address +func (_e *PriceRegistryInterface_Expecter) GetTokenPriceFeedConfig(opts interface{}, token interface{}) *PriceRegistryInterface_GetTokenPriceFeedConfig_Call { + return &PriceRegistryInterface_GetTokenPriceFeedConfig_Call{Call: _e.mock.On("GetTokenPriceFeedConfig", opts, token)} +} + +func (_c *PriceRegistryInterface_GetTokenPriceFeedConfig_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *PriceRegistryInterface_GetTokenPriceFeedConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetTokenPriceFeedConfig_Call) Return(_a0 price_registry.IPriceRegistryTokenPriceFeedConfig, _a1 error) *PriceRegistryInterface_GetTokenPriceFeedConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetTokenPriceFeedConfig_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (price_registry.IPriceRegistryTokenPriceFeedConfig, error)) *PriceRegistryInterface_GetTokenPriceFeedConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenPrices provides a mock function with given fields: opts, tokens +func (_m *PriceRegistryInterface) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]price_registry.InternalTimestampedPackedUint224, error) { + ret := _m.Called(opts, tokens) + + if len(ret) == 0 { + panic("no return value specified for GetTokenPrices") + } + + var r0 []price_registry.InternalTimestampedPackedUint224 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, []common.Address) ([]price_registry.InternalTimestampedPackedUint224, error)); ok { + return rf(opts, tokens) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, []common.Address) []price_registry.InternalTimestampedPackedUint224); ok { + r0 = rf(opts, tokens) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]price_registry.InternalTimestampedPackedUint224) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, []common.Address) error); ok { + r1 = rf(opts, tokens) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetTokenPrices_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenPrices' +type PriceRegistryInterface_GetTokenPrices_Call struct { + *mock.Call +} + +// GetTokenPrices is a helper method to define mock.On call +// - opts *bind.CallOpts +// - tokens []common.Address +func (_e *PriceRegistryInterface_Expecter) GetTokenPrices(opts interface{}, tokens interface{}) *PriceRegistryInterface_GetTokenPrices_Call { + return &PriceRegistryInterface_GetTokenPrices_Call{Call: _e.mock.On("GetTokenPrices", opts, tokens)} +} + +func (_c *PriceRegistryInterface_GetTokenPrices_Call) Run(run func(opts *bind.CallOpts, tokens []common.Address)) *PriceRegistryInterface_GetTokenPrices_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetTokenPrices_Call) Return(_a0 []price_registry.InternalTimestampedPackedUint224, _a1 error) *PriceRegistryInterface_GetTokenPrices_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetTokenPrices_Call) RunAndReturn(run func(*bind.CallOpts, []common.Address) ([]price_registry.InternalTimestampedPackedUint224, error)) *PriceRegistryInterface_GetTokenPrices_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenTransferFeeConfig provides a mock function with given fields: opts, destChainSelector, token +func (_m *PriceRegistryInterface) GetTokenTransferFeeConfig(opts *bind.CallOpts, destChainSelector uint64, token common.Address) (price_registry.PriceRegistryTokenTransferFeeConfig, error) { + ret := _m.Called(opts, destChainSelector, token) + + if len(ret) == 0 { + panic("no return value specified for GetTokenTransferFeeConfig") + } + + var r0 price_registry.PriceRegistryTokenTransferFeeConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address) (price_registry.PriceRegistryTokenTransferFeeConfig, error)); ok { + return rf(opts, destChainSelector, token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address) price_registry.PriceRegistryTokenTransferFeeConfig); ok { + r0 = rf(opts, destChainSelector, token) + } else { + r0 = ret.Get(0).(price_registry.PriceRegistryTokenTransferFeeConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, common.Address) error); ok { + r1 = rf(opts, destChainSelector, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetTokenTransferFeeConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenTransferFeeConfig' +type PriceRegistryInterface_GetTokenTransferFeeConfig_Call struct { + *mock.Call +} + +// GetTokenTransferFeeConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +// - token common.Address +func (_e *PriceRegistryInterface_Expecter) GetTokenTransferFeeConfig(opts interface{}, destChainSelector interface{}, token interface{}) *PriceRegistryInterface_GetTokenTransferFeeConfig_Call { + return &PriceRegistryInterface_GetTokenTransferFeeConfig_Call{Call: _e.mock.On("GetTokenTransferFeeConfig", opts, destChainSelector, token)} +} + +func (_c *PriceRegistryInterface_GetTokenTransferFeeConfig_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, token common.Address)) *PriceRegistryInterface_GetTokenTransferFeeConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetTokenTransferFeeConfig_Call) Return(_a0 price_registry.PriceRegistryTokenTransferFeeConfig, _a1 error) *PriceRegistryInterface_GetTokenTransferFeeConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetTokenTransferFeeConfig_Call) RunAndReturn(run func(*bind.CallOpts, uint64, common.Address) (price_registry.PriceRegistryTokenTransferFeeConfig, error)) *PriceRegistryInterface_GetTokenTransferFeeConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetValidatedFee provides a mock function with given fields: opts, destChainSelector, message +func (_m *PriceRegistryInterface) GetValidatedFee(opts *bind.CallOpts, destChainSelector uint64, message price_registry.ClientEVM2AnyMessage) (*big.Int, error) { + ret := _m.Called(opts, destChainSelector, message) + + if len(ret) == 0 { + panic("no return value specified for GetValidatedFee") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, price_registry.ClientEVM2AnyMessage) (*big.Int, error)); ok { + return rf(opts, destChainSelector, message) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, price_registry.ClientEVM2AnyMessage) *big.Int); ok { + r0 = rf(opts, destChainSelector, message) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, price_registry.ClientEVM2AnyMessage) error); ok { + r1 = rf(opts, destChainSelector, message) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetValidatedFee_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetValidatedFee' +type PriceRegistryInterface_GetValidatedFee_Call struct { + *mock.Call +} + +// GetValidatedFee is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +// - message price_registry.ClientEVM2AnyMessage +func (_e *PriceRegistryInterface_Expecter) GetValidatedFee(opts interface{}, destChainSelector interface{}, message interface{}) *PriceRegistryInterface_GetValidatedFee_Call { + return &PriceRegistryInterface_GetValidatedFee_Call{Call: _e.mock.On("GetValidatedFee", opts, destChainSelector, message)} +} + +func (_c *PriceRegistryInterface_GetValidatedFee_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, message price_registry.ClientEVM2AnyMessage)) *PriceRegistryInterface_GetValidatedFee_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(price_registry.ClientEVM2AnyMessage)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetValidatedFee_Call) Return(_a0 *big.Int, _a1 error) *PriceRegistryInterface_GetValidatedFee_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetValidatedFee_Call) RunAndReturn(run func(*bind.CallOpts, uint64, price_registry.ClientEVM2AnyMessage) (*big.Int, error)) *PriceRegistryInterface_GetValidatedFee_Call { + _c.Call.Return(run) + return _c +} + +// GetValidatedTokenPrice provides a mock function with given fields: opts, token +func (_m *PriceRegistryInterface) GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for GetValidatedTokenPrice") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (*big.Int, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) *big.Int); ok { + r0 = rf(opts, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_GetValidatedTokenPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetValidatedTokenPrice' +type PriceRegistryInterface_GetValidatedTokenPrice_Call struct { + *mock.Call +} + +// GetValidatedTokenPrice is a helper method to define mock.On call +// - opts *bind.CallOpts +// - token common.Address +func (_e *PriceRegistryInterface_Expecter) GetValidatedTokenPrice(opts interface{}, token interface{}) *PriceRegistryInterface_GetValidatedTokenPrice_Call { + return &PriceRegistryInterface_GetValidatedTokenPrice_Call{Call: _e.mock.On("GetValidatedTokenPrice", opts, token)} +} + +func (_c *PriceRegistryInterface_GetValidatedTokenPrice_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *PriceRegistryInterface_GetValidatedTokenPrice_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_GetValidatedTokenPrice_Call) Return(_a0 *big.Int, _a1 error) *PriceRegistryInterface_GetValidatedTokenPrice_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_GetValidatedTokenPrice_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (*big.Int, error)) *PriceRegistryInterface_GetValidatedTokenPrice_Call { + _c.Call.Return(run) + return _c +} + +// Owner provides a mock function with given fields: opts +func (_m *PriceRegistryInterface) Owner(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Owner") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_Owner_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Owner' +type PriceRegistryInterface_Owner_Call struct { + *mock.Call +} + +// Owner is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *PriceRegistryInterface_Expecter) Owner(opts interface{}) *PriceRegistryInterface_Owner_Call { + return &PriceRegistryInterface_Owner_Call{Call: _e.mock.On("Owner", opts)} +} + +func (_c *PriceRegistryInterface_Owner_Call) Run(run func(opts *bind.CallOpts)) *PriceRegistryInterface_Owner_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *PriceRegistryInterface_Owner_Call) Return(_a0 common.Address, _a1 error) *PriceRegistryInterface_Owner_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_Owner_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *PriceRegistryInterface_Owner_Call { + _c.Call.Return(run) + return _c +} + +// ParseAuthorizedCallerAdded provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseAuthorizedCallerAdded(log types.Log) (*price_registry.PriceRegistryAuthorizedCallerAdded, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseAuthorizedCallerAdded") + } + + var r0 *price_registry.PriceRegistryAuthorizedCallerAdded + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryAuthorizedCallerAdded, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryAuthorizedCallerAdded); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryAuthorizedCallerAdded) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseAuthorizedCallerAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseAuthorizedCallerAdded' +type PriceRegistryInterface_ParseAuthorizedCallerAdded_Call struct { + *mock.Call +} + +// ParseAuthorizedCallerAdded is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseAuthorizedCallerAdded(log interface{}) *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call { + return &PriceRegistryInterface_ParseAuthorizedCallerAdded_Call{Call: _e.mock.On("ParseAuthorizedCallerAdded", log)} +} + +func (_c *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call) Return(_a0 *price_registry.PriceRegistryAuthorizedCallerAdded, _a1 error) *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryAuthorizedCallerAdded, error)) *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call { + _c.Call.Return(run) + return _c +} + +// ParseAuthorizedCallerRemoved provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseAuthorizedCallerRemoved(log types.Log) (*price_registry.PriceRegistryAuthorizedCallerRemoved, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseAuthorizedCallerRemoved") + } + + var r0 *price_registry.PriceRegistryAuthorizedCallerRemoved + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryAuthorizedCallerRemoved, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryAuthorizedCallerRemoved); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryAuthorizedCallerRemoved) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseAuthorizedCallerRemoved' +type PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call struct { + *mock.Call +} + +// ParseAuthorizedCallerRemoved is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseAuthorizedCallerRemoved(log interface{}) *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call { + return &PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call{Call: _e.mock.On("ParseAuthorizedCallerRemoved", log)} +} + +func (_c *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call) Return(_a0 *price_registry.PriceRegistryAuthorizedCallerRemoved, _a1 error) *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryAuthorizedCallerRemoved, error)) *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call { + _c.Call.Return(run) + return _c +} + +// ParseDestChainAdded provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseDestChainAdded(log types.Log) (*price_registry.PriceRegistryDestChainAdded, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseDestChainAdded") + } + + var r0 *price_registry.PriceRegistryDestChainAdded + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryDestChainAdded, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryDestChainAdded); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryDestChainAdded) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseDestChainAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseDestChainAdded' +type PriceRegistryInterface_ParseDestChainAdded_Call struct { + *mock.Call +} + +// ParseDestChainAdded is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseDestChainAdded(log interface{}) *PriceRegistryInterface_ParseDestChainAdded_Call { + return &PriceRegistryInterface_ParseDestChainAdded_Call{Call: _e.mock.On("ParseDestChainAdded", log)} +} + +func (_c *PriceRegistryInterface_ParseDestChainAdded_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseDestChainAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseDestChainAdded_Call) Return(_a0 *price_registry.PriceRegistryDestChainAdded, _a1 error) *PriceRegistryInterface_ParseDestChainAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseDestChainAdded_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryDestChainAdded, error)) *PriceRegistryInterface_ParseDestChainAdded_Call { + _c.Call.Return(run) + return _c +} + +// ParseDestChainConfigUpdated provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseDestChainConfigUpdated(log types.Log) (*price_registry.PriceRegistryDestChainConfigUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseDestChainConfigUpdated") + } + + var r0 *price_registry.PriceRegistryDestChainConfigUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryDestChainConfigUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryDestChainConfigUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryDestChainConfigUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseDestChainConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseDestChainConfigUpdated' +type PriceRegistryInterface_ParseDestChainConfigUpdated_Call struct { + *mock.Call +} + +// ParseDestChainConfigUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseDestChainConfigUpdated(log interface{}) *PriceRegistryInterface_ParseDestChainConfigUpdated_Call { + return &PriceRegistryInterface_ParseDestChainConfigUpdated_Call{Call: _e.mock.On("ParseDestChainConfigUpdated", log)} +} + +func (_c *PriceRegistryInterface_ParseDestChainConfigUpdated_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseDestChainConfigUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseDestChainConfigUpdated_Call) Return(_a0 *price_registry.PriceRegistryDestChainConfigUpdated, _a1 error) *PriceRegistryInterface_ParseDestChainConfigUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseDestChainConfigUpdated_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryDestChainConfigUpdated, error)) *PriceRegistryInterface_ParseDestChainConfigUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ParseFeeTokenAdded provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseFeeTokenAdded(log types.Log) (*price_registry.PriceRegistryFeeTokenAdded, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseFeeTokenAdded") + } + + var r0 *price_registry.PriceRegistryFeeTokenAdded + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryFeeTokenAdded, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryFeeTokenAdded); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryFeeTokenAdded) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseFeeTokenAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseFeeTokenAdded' +type PriceRegistryInterface_ParseFeeTokenAdded_Call struct { + *mock.Call +} + +// ParseFeeTokenAdded is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseFeeTokenAdded(log interface{}) *PriceRegistryInterface_ParseFeeTokenAdded_Call { + return &PriceRegistryInterface_ParseFeeTokenAdded_Call{Call: _e.mock.On("ParseFeeTokenAdded", log)} +} + +func (_c *PriceRegistryInterface_ParseFeeTokenAdded_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseFeeTokenAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseFeeTokenAdded_Call) Return(_a0 *price_registry.PriceRegistryFeeTokenAdded, _a1 error) *PriceRegistryInterface_ParseFeeTokenAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseFeeTokenAdded_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryFeeTokenAdded, error)) *PriceRegistryInterface_ParseFeeTokenAdded_Call { + _c.Call.Return(run) + return _c +} + +// ParseFeeTokenRemoved provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseFeeTokenRemoved(log types.Log) (*price_registry.PriceRegistryFeeTokenRemoved, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseFeeTokenRemoved") + } + + var r0 *price_registry.PriceRegistryFeeTokenRemoved + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryFeeTokenRemoved, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryFeeTokenRemoved); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryFeeTokenRemoved) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseFeeTokenRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseFeeTokenRemoved' +type PriceRegistryInterface_ParseFeeTokenRemoved_Call struct { + *mock.Call +} + +// ParseFeeTokenRemoved is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseFeeTokenRemoved(log interface{}) *PriceRegistryInterface_ParseFeeTokenRemoved_Call { + return &PriceRegistryInterface_ParseFeeTokenRemoved_Call{Call: _e.mock.On("ParseFeeTokenRemoved", log)} +} + +func (_c *PriceRegistryInterface_ParseFeeTokenRemoved_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseFeeTokenRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseFeeTokenRemoved_Call) Return(_a0 *price_registry.PriceRegistryFeeTokenRemoved, _a1 error) *PriceRegistryInterface_ParseFeeTokenRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseFeeTokenRemoved_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryFeeTokenRemoved, error)) *PriceRegistryInterface_ParseFeeTokenRemoved_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type PriceRegistryInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseLog(log interface{}) *PriceRegistryInterface_ParseLog_Call { + return &PriceRegistryInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *PriceRegistryInterface_ParseLog_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *PriceRegistryInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *PriceRegistryInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferRequested provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseOwnershipTransferRequested(log types.Log) (*price_registry.PriceRegistryOwnershipTransferRequested, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferRequested") + } + + var r0 *price_registry.PriceRegistryOwnershipTransferRequested + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryOwnershipTransferRequested, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryOwnershipTransferRequested); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryOwnershipTransferRequested) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferRequested' +type PriceRegistryInterface_ParseOwnershipTransferRequested_Call struct { + *mock.Call +} + +// ParseOwnershipTransferRequested is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseOwnershipTransferRequested(log interface{}) *PriceRegistryInterface_ParseOwnershipTransferRequested_Call { + return &PriceRegistryInterface_ParseOwnershipTransferRequested_Call{Call: _e.mock.On("ParseOwnershipTransferRequested", log)} +} + +func (_c *PriceRegistryInterface_ParseOwnershipTransferRequested_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseOwnershipTransferRequested_Call) Return(_a0 *price_registry.PriceRegistryOwnershipTransferRequested, _a1 error) *PriceRegistryInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseOwnershipTransferRequested_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryOwnershipTransferRequested, error)) *PriceRegistryInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferred provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseOwnershipTransferred(log types.Log) (*price_registry.PriceRegistryOwnershipTransferred, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferred") + } + + var r0 *price_registry.PriceRegistryOwnershipTransferred + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryOwnershipTransferred, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryOwnershipTransferred); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryOwnershipTransferred) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferred' +type PriceRegistryInterface_ParseOwnershipTransferred_Call struct { + *mock.Call +} + +// ParseOwnershipTransferred is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseOwnershipTransferred(log interface{}) *PriceRegistryInterface_ParseOwnershipTransferred_Call { + return &PriceRegistryInterface_ParseOwnershipTransferred_Call{Call: _e.mock.On("ParseOwnershipTransferred", log)} +} + +func (_c *PriceRegistryInterface_ParseOwnershipTransferred_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseOwnershipTransferred_Call) Return(_a0 *price_registry.PriceRegistryOwnershipTransferred, _a1 error) *PriceRegistryInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseOwnershipTransferred_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryOwnershipTransferred, error)) *PriceRegistryInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// ParsePremiumMultiplierWeiPerEthUpdated provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParsePremiumMultiplierWeiPerEthUpdated(log types.Log) (*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParsePremiumMultiplierWeiPerEthUpdated") + } + + var r0 *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePremiumMultiplierWeiPerEthUpdated' +type PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call struct { + *mock.Call +} + +// ParsePremiumMultiplierWeiPerEthUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParsePremiumMultiplierWeiPerEthUpdated(log interface{}) *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call { + return &PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call{Call: _e.mock.On("ParsePremiumMultiplierWeiPerEthUpdated", log)} +} + +func (_c *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call) Return(_a0 *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, _a1 error) *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, error)) *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ParsePriceFeedPerTokenUpdated provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParsePriceFeedPerTokenUpdated(log types.Log) (*price_registry.PriceRegistryPriceFeedPerTokenUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParsePriceFeedPerTokenUpdated") + } + + var r0 *price_registry.PriceRegistryPriceFeedPerTokenUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryPriceFeedPerTokenUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryPriceFeedPerTokenUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryPriceFeedPerTokenUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePriceFeedPerTokenUpdated' +type PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call struct { + *mock.Call +} + +// ParsePriceFeedPerTokenUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParsePriceFeedPerTokenUpdated(log interface{}) *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call { + return &PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call{Call: _e.mock.On("ParsePriceFeedPerTokenUpdated", log)} +} + +func (_c *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call) Return(_a0 *price_registry.PriceRegistryPriceFeedPerTokenUpdated, _a1 error) *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryPriceFeedPerTokenUpdated, error)) *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ParsePriceUpdaterRemoved provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParsePriceUpdaterRemoved(log types.Log) (*price_registry.PriceRegistryPriceUpdaterRemoved, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParsePriceUpdaterRemoved") + } + + var r0 *price_registry.PriceRegistryPriceUpdaterRemoved + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryPriceUpdaterRemoved, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryPriceUpdaterRemoved); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryPriceUpdaterRemoved) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParsePriceUpdaterRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePriceUpdaterRemoved' +type PriceRegistryInterface_ParsePriceUpdaterRemoved_Call struct { + *mock.Call +} + +// ParsePriceUpdaterRemoved is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParsePriceUpdaterRemoved(log interface{}) *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call { + return &PriceRegistryInterface_ParsePriceUpdaterRemoved_Call{Call: _e.mock.On("ParsePriceUpdaterRemoved", log)} +} + +func (_c *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call) Return(_a0 *price_registry.PriceRegistryPriceUpdaterRemoved, _a1 error) *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryPriceUpdaterRemoved, error)) *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call { + _c.Call.Return(run) + return _c +} + +// ParsePriceUpdaterSet provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParsePriceUpdaterSet(log types.Log) (*price_registry.PriceRegistryPriceUpdaterSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParsePriceUpdaterSet") + } + + var r0 *price_registry.PriceRegistryPriceUpdaterSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryPriceUpdaterSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryPriceUpdaterSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryPriceUpdaterSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParsePriceUpdaterSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePriceUpdaterSet' +type PriceRegistryInterface_ParsePriceUpdaterSet_Call struct { + *mock.Call +} + +// ParsePriceUpdaterSet is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParsePriceUpdaterSet(log interface{}) *PriceRegistryInterface_ParsePriceUpdaterSet_Call { + return &PriceRegistryInterface_ParsePriceUpdaterSet_Call{Call: _e.mock.On("ParsePriceUpdaterSet", log)} +} + +func (_c *PriceRegistryInterface_ParsePriceUpdaterSet_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParsePriceUpdaterSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParsePriceUpdaterSet_Call) Return(_a0 *price_registry.PriceRegistryPriceUpdaterSet, _a1 error) *PriceRegistryInterface_ParsePriceUpdaterSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParsePriceUpdaterSet_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryPriceUpdaterSet, error)) *PriceRegistryInterface_ParsePriceUpdaterSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseTokenTransferFeeConfigDeleted provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseTokenTransferFeeConfigDeleted(log types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigDeleted, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTokenTransferFeeConfigDeleted") + } + + var r0 *price_registry.PriceRegistryTokenTransferFeeConfigDeleted + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigDeleted, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryTokenTransferFeeConfigDeleted); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryTokenTransferFeeConfigDeleted) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTokenTransferFeeConfigDeleted' +type PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call struct { + *mock.Call +} + +// ParseTokenTransferFeeConfigDeleted is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseTokenTransferFeeConfigDeleted(log interface{}) *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call { + return &PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call{Call: _e.mock.On("ParseTokenTransferFeeConfigDeleted", log)} +} + +func (_c *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call) Return(_a0 *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, _a1 error) *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigDeleted, error)) *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(run) + return _c +} + +// ParseTokenTransferFeeConfigUpdated provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseTokenTransferFeeConfigUpdated(log types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTokenTransferFeeConfigUpdated") + } + + var r0 *price_registry.PriceRegistryTokenTransferFeeConfigUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryTokenTransferFeeConfigUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryTokenTransferFeeConfigUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTokenTransferFeeConfigUpdated' +type PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call struct { + *mock.Call +} + +// ParseTokenTransferFeeConfigUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseTokenTransferFeeConfigUpdated(log interface{}) *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call { + return &PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call{Call: _e.mock.On("ParseTokenTransferFeeConfigUpdated", log)} +} + +func (_c *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call) Return(_a0 *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, _a1 error) *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigUpdated, error)) *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ParseUsdPerTokenUpdated provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseUsdPerTokenUpdated(log types.Log) (*price_registry.PriceRegistryUsdPerTokenUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseUsdPerTokenUpdated") + } + + var r0 *price_registry.PriceRegistryUsdPerTokenUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryUsdPerTokenUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryUsdPerTokenUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryUsdPerTokenUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseUsdPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseUsdPerTokenUpdated' +type PriceRegistryInterface_ParseUsdPerTokenUpdated_Call struct { + *mock.Call +} + +// ParseUsdPerTokenUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseUsdPerTokenUpdated(log interface{}) *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call { + return &PriceRegistryInterface_ParseUsdPerTokenUpdated_Call{Call: _e.mock.On("ParseUsdPerTokenUpdated", log)} +} + +func (_c *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call) Return(_a0 *price_registry.PriceRegistryUsdPerTokenUpdated, _a1 error) *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryUsdPerTokenUpdated, error)) *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ParseUsdPerUnitGasUpdated provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseUsdPerUnitGasUpdated(log types.Log) (*price_registry.PriceRegistryUsdPerUnitGasUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseUsdPerUnitGasUpdated") + } + + var r0 *price_registry.PriceRegistryUsdPerUnitGasUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryUsdPerUnitGasUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryUsdPerUnitGasUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryUsdPerUnitGasUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseUsdPerUnitGasUpdated' +type PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call struct { + *mock.Call +} + +// ParseUsdPerUnitGasUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseUsdPerUnitGasUpdated(log interface{}) *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call { + return &PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call{Call: _e.mock.On("ParseUsdPerUnitGasUpdated", log)} +} + +func (_c *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call) Return(_a0 *price_registry.PriceRegistryUsdPerUnitGasUpdated, _a1 error) *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryUsdPerUnitGasUpdated, error)) *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ProcessMessageArgs provides a mock function with given fields: opts, destChainSelector, feeToken, feeTokenAmount, extraArgs +func (_m *PriceRegistryInterface) ProcessMessageArgs(opts *bind.CallOpts, destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (price_registry.ProcessMessageArgs, error) { + ret := _m.Called(opts, destChainSelector, feeToken, feeTokenAmount, extraArgs) + + if len(ret) == 0 { + panic("no return value specified for ProcessMessageArgs") + } + + var r0 price_registry.ProcessMessageArgs + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address, *big.Int, []byte) (price_registry.ProcessMessageArgs, error)); ok { + return rf(opts, destChainSelector, feeToken, feeTokenAmount, extraArgs) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address, *big.Int, []byte) price_registry.ProcessMessageArgs); ok { + r0 = rf(opts, destChainSelector, feeToken, feeTokenAmount, extraArgs) + } else { + r0 = ret.Get(0).(price_registry.ProcessMessageArgs) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, common.Address, *big.Int, []byte) error); ok { + r1 = rf(opts, destChainSelector, feeToken, feeTokenAmount, extraArgs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ProcessMessageArgs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ProcessMessageArgs' +type PriceRegistryInterface_ProcessMessageArgs_Call struct { + *mock.Call +} + +// ProcessMessageArgs is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +// - feeToken common.Address +// - feeTokenAmount *big.Int +// - extraArgs []byte +func (_e *PriceRegistryInterface_Expecter) ProcessMessageArgs(opts interface{}, destChainSelector interface{}, feeToken interface{}, feeTokenAmount interface{}, extraArgs interface{}) *PriceRegistryInterface_ProcessMessageArgs_Call { + return &PriceRegistryInterface_ProcessMessageArgs_Call{Call: _e.mock.On("ProcessMessageArgs", opts, destChainSelector, feeToken, feeTokenAmount, extraArgs)} +} + +func (_c *PriceRegistryInterface_ProcessMessageArgs_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte)) *PriceRegistryInterface_ProcessMessageArgs_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(common.Address), args[3].(*big.Int), args[4].([]byte)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ProcessMessageArgs_Call) Return(_a0 price_registry.ProcessMessageArgs, _a1 error) *PriceRegistryInterface_ProcessMessageArgs_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ProcessMessageArgs_Call) RunAndReturn(run func(*bind.CallOpts, uint64, common.Address, *big.Int, []byte) (price_registry.ProcessMessageArgs, error)) *PriceRegistryInterface_ProcessMessageArgs_Call { + _c.Call.Return(run) + return _c +} + +// TransferOwnership provides a mock function with given fields: opts, to +func (_m *PriceRegistryInterface) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, to) + + if len(ret) == 0 { + panic("no return value specified for TransferOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, to) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_TransferOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TransferOwnership' +type PriceRegistryInterface_TransferOwnership_Call struct { + *mock.Call +} + +// TransferOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - to common.Address +func (_e *PriceRegistryInterface_Expecter) TransferOwnership(opts interface{}, to interface{}) *PriceRegistryInterface_TransferOwnership_Call { + return &PriceRegistryInterface_TransferOwnership_Call{Call: _e.mock.On("TransferOwnership", opts, to)} +} + +func (_c *PriceRegistryInterface_TransferOwnership_Call) Run(run func(opts *bind.TransactOpts, to common.Address)) *PriceRegistryInterface_TransferOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_TransferOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_TransferOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_TransferOwnership_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *PriceRegistryInterface_TransferOwnership_Call { + _c.Call.Return(run) + return _c +} + +// TypeAndVersion provides a mock function with given fields: opts +func (_m *PriceRegistryInterface) TypeAndVersion(opts *bind.CallOpts) (string, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for TypeAndVersion") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (string, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) string); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_TypeAndVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TypeAndVersion' +type PriceRegistryInterface_TypeAndVersion_Call struct { + *mock.Call +} + +// TypeAndVersion is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *PriceRegistryInterface_Expecter) TypeAndVersion(opts interface{}) *PriceRegistryInterface_TypeAndVersion_Call { + return &PriceRegistryInterface_TypeAndVersion_Call{Call: _e.mock.On("TypeAndVersion", opts)} +} + +func (_c *PriceRegistryInterface_TypeAndVersion_Call) Run(run func(opts *bind.CallOpts)) *PriceRegistryInterface_TypeAndVersion_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *PriceRegistryInterface_TypeAndVersion_Call) Return(_a0 string, _a1 error) *PriceRegistryInterface_TypeAndVersion_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_TypeAndVersion_Call) RunAndReturn(run func(*bind.CallOpts) (string, error)) *PriceRegistryInterface_TypeAndVersion_Call { + _c.Call.Return(run) + return _c +} + +// UpdatePrices provides a mock function with given fields: opts, priceUpdates +func (_m *PriceRegistryInterface) UpdatePrices(opts *bind.TransactOpts, priceUpdates price_registry.InternalPriceUpdates) (*types.Transaction, error) { + ret := _m.Called(opts, priceUpdates) + + if len(ret) == 0 { + panic("no return value specified for UpdatePrices") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, price_registry.InternalPriceUpdates) (*types.Transaction, error)); ok { + return rf(opts, priceUpdates) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, price_registry.InternalPriceUpdates) *types.Transaction); ok { + r0 = rf(opts, priceUpdates) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, price_registry.InternalPriceUpdates) error); ok { + r1 = rf(opts, priceUpdates) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_UpdatePrices_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdatePrices' +type PriceRegistryInterface_UpdatePrices_Call struct { + *mock.Call +} + +// UpdatePrices is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - priceUpdates price_registry.InternalPriceUpdates +func (_e *PriceRegistryInterface_Expecter) UpdatePrices(opts interface{}, priceUpdates interface{}) *PriceRegistryInterface_UpdatePrices_Call { + return &PriceRegistryInterface_UpdatePrices_Call{Call: _e.mock.On("UpdatePrices", opts, priceUpdates)} +} + +func (_c *PriceRegistryInterface_UpdatePrices_Call) Run(run func(opts *bind.TransactOpts, priceUpdates price_registry.InternalPriceUpdates)) *PriceRegistryInterface_UpdatePrices_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(price_registry.InternalPriceUpdates)) + }) + return _c +} + +func (_c *PriceRegistryInterface_UpdatePrices_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_UpdatePrices_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_UpdatePrices_Call) RunAndReturn(run func(*bind.TransactOpts, price_registry.InternalPriceUpdates) (*types.Transaction, error)) *PriceRegistryInterface_UpdatePrices_Call { + _c.Call.Return(run) + return _c +} + +// UpdateTokenPriceFeeds provides a mock function with given fields: opts, tokenPriceFeedUpdates +func (_m *PriceRegistryInterface) UpdateTokenPriceFeeds(opts *bind.TransactOpts, tokenPriceFeedUpdates []price_registry.PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error) { + ret := _m.Called(opts, tokenPriceFeedUpdates) + + if len(ret) == 0 { + panic("no return value specified for UpdateTokenPriceFeeds") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error)); ok { + return rf(opts, tokenPriceFeedUpdates) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryTokenPriceFeedUpdate) *types.Transaction); ok { + r0 = rf(opts, tokenPriceFeedUpdates) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []price_registry.PriceRegistryTokenPriceFeedUpdate) error); ok { + r1 = rf(opts, tokenPriceFeedUpdates) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_UpdateTokenPriceFeeds_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateTokenPriceFeeds' +type PriceRegistryInterface_UpdateTokenPriceFeeds_Call struct { + *mock.Call +} + +// UpdateTokenPriceFeeds is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - tokenPriceFeedUpdates []price_registry.PriceRegistryTokenPriceFeedUpdate +func (_e *PriceRegistryInterface_Expecter) UpdateTokenPriceFeeds(opts interface{}, tokenPriceFeedUpdates interface{}) *PriceRegistryInterface_UpdateTokenPriceFeeds_Call { + return &PriceRegistryInterface_UpdateTokenPriceFeeds_Call{Call: _e.mock.On("UpdateTokenPriceFeeds", opts, tokenPriceFeedUpdates)} +} + +func (_c *PriceRegistryInterface_UpdateTokenPriceFeeds_Call) Run(run func(opts *bind.TransactOpts, tokenPriceFeedUpdates []price_registry.PriceRegistryTokenPriceFeedUpdate)) *PriceRegistryInterface_UpdateTokenPriceFeeds_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]price_registry.PriceRegistryTokenPriceFeedUpdate)) + }) + return _c +} + +func (_c *PriceRegistryInterface_UpdateTokenPriceFeeds_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_UpdateTokenPriceFeeds_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_UpdateTokenPriceFeeds_Call) RunAndReturn(run func(*bind.TransactOpts, []price_registry.PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error)) *PriceRegistryInterface_UpdateTokenPriceFeeds_Call { + _c.Call.Return(run) + return _c +} + +// ValidatePoolReturnData provides a mock function with given fields: opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts +func (_m *PriceRegistryInterface) ValidatePoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []price_registry.InternalRampTokenAmount, sourceTokenAmounts []price_registry.ClientEVMTokenAmount) error { + ret := _m.Called(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) + + if len(ret) == 0 { + panic("no return value specified for ValidatePoolReturnData") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, []price_registry.InternalRampTokenAmount, []price_registry.ClientEVMTokenAmount) error); ok { + r0 = rf(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// PriceRegistryInterface_ValidatePoolReturnData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ValidatePoolReturnData' +type PriceRegistryInterface_ValidatePoolReturnData_Call struct { + *mock.Call +} + +// ValidatePoolReturnData is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +// - rampTokenAmounts []price_registry.InternalRampTokenAmount +// - sourceTokenAmounts []price_registry.ClientEVMTokenAmount +func (_e *PriceRegistryInterface_Expecter) ValidatePoolReturnData(opts interface{}, destChainSelector interface{}, rampTokenAmounts interface{}, sourceTokenAmounts interface{}) *PriceRegistryInterface_ValidatePoolReturnData_Call { + return &PriceRegistryInterface_ValidatePoolReturnData_Call{Call: _e.mock.On("ValidatePoolReturnData", opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts)} +} + +func (_c *PriceRegistryInterface_ValidatePoolReturnData_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []price_registry.InternalRampTokenAmount, sourceTokenAmounts []price_registry.ClientEVMTokenAmount)) *PriceRegistryInterface_ValidatePoolReturnData_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].([]price_registry.InternalRampTokenAmount), args[3].([]price_registry.ClientEVMTokenAmount)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ValidatePoolReturnData_Call) Return(_a0 error) *PriceRegistryInterface_ValidatePoolReturnData_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *PriceRegistryInterface_ValidatePoolReturnData_Call) RunAndReturn(run func(*bind.CallOpts, uint64, []price_registry.InternalRampTokenAmount, []price_registry.ClientEVMTokenAmount) error) *PriceRegistryInterface_ValidatePoolReturnData_Call { + _c.Call.Return(run) + return _c +} + +// WatchAuthorizedCallerAdded provides a mock function with given fields: opts, sink +func (_m *PriceRegistryInterface) WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryAuthorizedCallerAdded) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchAuthorizedCallerAdded") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerAdded) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerAdded) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerAdded) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchAuthorizedCallerAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchAuthorizedCallerAdded' +type PriceRegistryInterface_WatchAuthorizedCallerAdded_Call struct { + *mock.Call +} + +// WatchAuthorizedCallerAdded is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryAuthorizedCallerAdded +func (_e *PriceRegistryInterface_Expecter) WatchAuthorizedCallerAdded(opts interface{}, sink interface{}) *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call { + return &PriceRegistryInterface_WatchAuthorizedCallerAdded_Call{Call: _e.mock.On("WatchAuthorizedCallerAdded", opts, sink)} +} + +func (_c *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryAuthorizedCallerAdded)) *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryAuthorizedCallerAdded)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerAdded) (event.Subscription, error)) *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call { + _c.Call.Return(run) + return _c +} + +// WatchAuthorizedCallerRemoved provides a mock function with given fields: opts, sink +func (_m *PriceRegistryInterface) WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchAuthorizedCallerRemoved") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchAuthorizedCallerRemoved' +type PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call struct { + *mock.Call +} + +// WatchAuthorizedCallerRemoved is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved +func (_e *PriceRegistryInterface_Expecter) WatchAuthorizedCallerRemoved(opts interface{}, sink interface{}) *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call { + return &PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call{Call: _e.mock.On("WatchAuthorizedCallerRemoved", opts, sink)} +} + +func (_c *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved)) *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved) (event.Subscription, error)) *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call { + _c.Call.Return(run) + return _c +} + +// WatchDestChainAdded provides a mock function with given fields: opts, sink, destChainSelector +func (_m *PriceRegistryInterface) WatchDestChainAdded(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryDestChainAdded, destChainSelector []uint64) (event.Subscription, error) { + ret := _m.Called(opts, sink, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for WatchDestChainAdded") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainAdded, []uint64) (event.Subscription, error)); ok { + return rf(opts, sink, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainAdded, []uint64) event.Subscription); ok { + r0 = rf(opts, sink, destChainSelector) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainAdded, []uint64) error); ok { + r1 = rf(opts, sink, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchDestChainAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchDestChainAdded' +type PriceRegistryInterface_WatchDestChainAdded_Call struct { + *mock.Call +} + +// WatchDestChainAdded is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryDestChainAdded +// - destChainSelector []uint64 +func (_e *PriceRegistryInterface_Expecter) WatchDestChainAdded(opts interface{}, sink interface{}, destChainSelector interface{}) *PriceRegistryInterface_WatchDestChainAdded_Call { + return &PriceRegistryInterface_WatchDestChainAdded_Call{Call: _e.mock.On("WatchDestChainAdded", opts, sink, destChainSelector)} +} + +func (_c *PriceRegistryInterface_WatchDestChainAdded_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryDestChainAdded, destChainSelector []uint64)) *PriceRegistryInterface_WatchDestChainAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryDestChainAdded), args[2].([]uint64)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchDestChainAdded_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchDestChainAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchDestChainAdded_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainAdded, []uint64) (event.Subscription, error)) *PriceRegistryInterface_WatchDestChainAdded_Call { + _c.Call.Return(run) + return _c +} + +// WatchDestChainConfigUpdated provides a mock function with given fields: opts, sink, destChainSelector +func (_m *PriceRegistryInterface) WatchDestChainConfigUpdated(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryDestChainConfigUpdated, destChainSelector []uint64) (event.Subscription, error) { + ret := _m.Called(opts, sink, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for WatchDestChainConfigUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainConfigUpdated, []uint64) (event.Subscription, error)); ok { + return rf(opts, sink, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainConfigUpdated, []uint64) event.Subscription); ok { + r0 = rf(opts, sink, destChainSelector) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainConfigUpdated, []uint64) error); ok { + r1 = rf(opts, sink, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchDestChainConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchDestChainConfigUpdated' +type PriceRegistryInterface_WatchDestChainConfigUpdated_Call struct { + *mock.Call +} + +// WatchDestChainConfigUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryDestChainConfigUpdated +// - destChainSelector []uint64 +func (_e *PriceRegistryInterface_Expecter) WatchDestChainConfigUpdated(opts interface{}, sink interface{}, destChainSelector interface{}) *PriceRegistryInterface_WatchDestChainConfigUpdated_Call { + return &PriceRegistryInterface_WatchDestChainConfigUpdated_Call{Call: _e.mock.On("WatchDestChainConfigUpdated", opts, sink, destChainSelector)} +} + +func (_c *PriceRegistryInterface_WatchDestChainConfigUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryDestChainConfigUpdated, destChainSelector []uint64)) *PriceRegistryInterface_WatchDestChainConfigUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryDestChainConfigUpdated), args[2].([]uint64)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchDestChainConfigUpdated_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchDestChainConfigUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchDestChainConfigUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainConfigUpdated, []uint64) (event.Subscription, error)) *PriceRegistryInterface_WatchDestChainConfigUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WatchFeeTokenAdded provides a mock function with given fields: opts, sink, feeToken +func (_m *PriceRegistryInterface) WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, feeToken) + + if len(ret) == 0 { + panic("no return value specified for WatchFeeTokenAdded") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenAdded, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, feeToken) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenAdded, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, feeToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenAdded, []common.Address) error); ok { + r1 = rf(opts, sink, feeToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchFeeTokenAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchFeeTokenAdded' +type PriceRegistryInterface_WatchFeeTokenAdded_Call struct { + *mock.Call +} + +// WatchFeeTokenAdded is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryFeeTokenAdded +// - feeToken []common.Address +func (_e *PriceRegistryInterface_Expecter) WatchFeeTokenAdded(opts interface{}, sink interface{}, feeToken interface{}) *PriceRegistryInterface_WatchFeeTokenAdded_Call { + return &PriceRegistryInterface_WatchFeeTokenAdded_Call{Call: _e.mock.On("WatchFeeTokenAdded", opts, sink, feeToken)} +} + +func (_c *PriceRegistryInterface_WatchFeeTokenAdded_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryFeeTokenAdded, feeToken []common.Address)) *PriceRegistryInterface_WatchFeeTokenAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryFeeTokenAdded), args[2].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchFeeTokenAdded_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchFeeTokenAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchFeeTokenAdded_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenAdded, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchFeeTokenAdded_Call { + _c.Call.Return(run) + return _c +} + +// WatchFeeTokenRemoved provides a mock function with given fields: opts, sink, feeToken +func (_m *PriceRegistryInterface) WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, feeToken) + + if len(ret) == 0 { + panic("no return value specified for WatchFeeTokenRemoved") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenRemoved, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, feeToken) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenRemoved, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, feeToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenRemoved, []common.Address) error); ok { + r1 = rf(opts, sink, feeToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchFeeTokenRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchFeeTokenRemoved' +type PriceRegistryInterface_WatchFeeTokenRemoved_Call struct { + *mock.Call +} + +// WatchFeeTokenRemoved is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryFeeTokenRemoved +// - feeToken []common.Address +func (_e *PriceRegistryInterface_Expecter) WatchFeeTokenRemoved(opts interface{}, sink interface{}, feeToken interface{}) *PriceRegistryInterface_WatchFeeTokenRemoved_Call { + return &PriceRegistryInterface_WatchFeeTokenRemoved_Call{Call: _e.mock.On("WatchFeeTokenRemoved", opts, sink, feeToken)} +} + +func (_c *PriceRegistryInterface_WatchFeeTokenRemoved_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryFeeTokenRemoved, feeToken []common.Address)) *PriceRegistryInterface_WatchFeeTokenRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryFeeTokenRemoved), args[2].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchFeeTokenRemoved_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchFeeTokenRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchFeeTokenRemoved_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenRemoved, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchFeeTokenRemoved_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferRequested provides a mock function with given fields: opts, sink, from, to +func (_m *PriceRegistryInterface) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferRequested") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferRequested, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferRequested, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferRequested' +type PriceRegistryInterface_WatchOwnershipTransferRequested_Call struct { + *mock.Call +} + +// WatchOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryOwnershipTransferRequested +// - from []common.Address +// - to []common.Address +func (_e *PriceRegistryInterface_Expecter) WatchOwnershipTransferRequested(opts interface{}, sink interface{}, from interface{}, to interface{}) *PriceRegistryInterface_WatchOwnershipTransferRequested_Call { + return &PriceRegistryInterface_WatchOwnershipTransferRequested_Call{Call: _e.mock.On("WatchOwnershipTransferRequested", opts, sink, from, to)} +} + +func (_c *PriceRegistryInterface_WatchOwnershipTransferRequested_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address)) *PriceRegistryInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryOwnershipTransferRequested), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchOwnershipTransferRequested_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferred provides a mock function with given fields: opts, sink, from, to +func (_m *PriceRegistryInterface) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferred") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferred, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferred, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferred' +type PriceRegistryInterface_WatchOwnershipTransferred_Call struct { + *mock.Call +} + +// WatchOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryOwnershipTransferred +// - from []common.Address +// - to []common.Address +func (_e *PriceRegistryInterface_Expecter) WatchOwnershipTransferred(opts interface{}, sink interface{}, from interface{}, to interface{}) *PriceRegistryInterface_WatchOwnershipTransferred_Call { + return &PriceRegistryInterface_WatchOwnershipTransferred_Call{Call: _e.mock.On("WatchOwnershipTransferred", opts, sink, from, to)} +} + +func (_c *PriceRegistryInterface_WatchOwnershipTransferred_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address)) *PriceRegistryInterface_WatchOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryOwnershipTransferred), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchOwnershipTransferred_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchOwnershipTransferred_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// WatchPremiumMultiplierWeiPerEthUpdated provides a mock function with given fields: opts, sink, token +func (_m *PriceRegistryInterface) WatchPremiumMultiplierWeiPerEthUpdated(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, token []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, token) + + if len(ret) == 0 { + panic("no return value specified for WatchPremiumMultiplierWeiPerEthUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, token) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, []common.Address) error); ok { + r1 = rf(opts, sink, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPremiumMultiplierWeiPerEthUpdated' +type PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call struct { + *mock.Call +} + +// WatchPremiumMultiplierWeiPerEthUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated +// - token []common.Address +func (_e *PriceRegistryInterface_Expecter) WatchPremiumMultiplierWeiPerEthUpdated(opts interface{}, sink interface{}, token interface{}) *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call { + return &PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call{Call: _e.mock.On("WatchPremiumMultiplierWeiPerEthUpdated", opts, sink, token)} +} + +func (_c *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, token []common.Address)) *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated), args[2].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WatchPriceFeedPerTokenUpdated provides a mock function with given fields: opts, sink, token +func (_m *PriceRegistryInterface) WatchPriceFeedPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated, token []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, token) + + if len(ret) == 0 { + panic("no return value specified for WatchPriceFeedPerTokenUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, token) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated, []common.Address) error); ok { + r1 = rf(opts, sink, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPriceFeedPerTokenUpdated' +type PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call struct { + *mock.Call +} + +// WatchPriceFeedPerTokenUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated +// - token []common.Address +func (_e *PriceRegistryInterface_Expecter) WatchPriceFeedPerTokenUpdated(opts interface{}, sink interface{}, token interface{}) *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call { + return &PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call{Call: _e.mock.On("WatchPriceFeedPerTokenUpdated", opts, sink, token)} +} + +func (_c *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated, token []common.Address)) *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated), args[2].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WatchPriceUpdaterRemoved provides a mock function with given fields: opts, sink, priceUpdater +func (_m *PriceRegistryInterface) WatchPriceUpdaterRemoved(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, priceUpdater) + + if len(ret) == 0 { + panic("no return value specified for WatchPriceUpdaterRemoved") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterRemoved, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, priceUpdater) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterRemoved, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, priceUpdater) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterRemoved, []common.Address) error); ok { + r1 = rf(opts, sink, priceUpdater) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchPriceUpdaterRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPriceUpdaterRemoved' +type PriceRegistryInterface_WatchPriceUpdaterRemoved_Call struct { + *mock.Call +} + +// WatchPriceUpdaterRemoved is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryPriceUpdaterRemoved +// - priceUpdater []common.Address +func (_e *PriceRegistryInterface_Expecter) WatchPriceUpdaterRemoved(opts interface{}, sink interface{}, priceUpdater interface{}) *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call { + return &PriceRegistryInterface_WatchPriceUpdaterRemoved_Call{Call: _e.mock.On("WatchPriceUpdaterRemoved", opts, sink, priceUpdater)} +} + +func (_c *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address)) *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryPriceUpdaterRemoved), args[2].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterRemoved, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call { + _c.Call.Return(run) + return _c +} + +// WatchPriceUpdaterSet provides a mock function with given fields: opts, sink, priceUpdater +func (_m *PriceRegistryInterface) WatchPriceUpdaterSet(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPriceUpdaterSet, priceUpdater []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, priceUpdater) + + if len(ret) == 0 { + panic("no return value specified for WatchPriceUpdaterSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterSet, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, priceUpdater) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterSet, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, priceUpdater) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterSet, []common.Address) error); ok { + r1 = rf(opts, sink, priceUpdater) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchPriceUpdaterSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPriceUpdaterSet' +type PriceRegistryInterface_WatchPriceUpdaterSet_Call struct { + *mock.Call +} + +// WatchPriceUpdaterSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryPriceUpdaterSet +// - priceUpdater []common.Address +func (_e *PriceRegistryInterface_Expecter) WatchPriceUpdaterSet(opts interface{}, sink interface{}, priceUpdater interface{}) *PriceRegistryInterface_WatchPriceUpdaterSet_Call { + return &PriceRegistryInterface_WatchPriceUpdaterSet_Call{Call: _e.mock.On("WatchPriceUpdaterSet", opts, sink, priceUpdater)} +} + +func (_c *PriceRegistryInterface_WatchPriceUpdaterSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPriceUpdaterSet, priceUpdater []common.Address)) *PriceRegistryInterface_WatchPriceUpdaterSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryPriceUpdaterSet), args[2].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchPriceUpdaterSet_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchPriceUpdaterSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchPriceUpdaterSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterSet, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchPriceUpdaterSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchTokenTransferFeeConfigDeleted provides a mock function with given fields: opts, sink, destChainSelector, token +func (_m *PriceRegistryInterface) WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, destChainSelector, token) + + if len(ret) == 0 { + panic("no return value specified for WatchTokenTransferFeeConfigDeleted") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, []uint64, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, destChainSelector, token) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, []uint64, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, destChainSelector, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, []uint64, []common.Address) error); ok { + r1 = rf(opts, sink, destChainSelector, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTokenTransferFeeConfigDeleted' +type PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call struct { + *mock.Call +} + +// WatchTokenTransferFeeConfigDeleted is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted +// - destChainSelector []uint64 +// - token []common.Address +func (_e *PriceRegistryInterface_Expecter) WatchTokenTransferFeeConfigDeleted(opts interface{}, sink interface{}, destChainSelector interface{}, token interface{}) *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call { + return &PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call{Call: _e.mock.On("WatchTokenTransferFeeConfigDeleted", opts, sink, destChainSelector, token)} +} + +func (_c *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address)) *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted), args[2].([]uint64), args[3].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, []uint64, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(run) + return _c +} + +// WatchTokenTransferFeeConfigUpdated provides a mock function with given fields: opts, sink, destChainSelector, token +func (_m *PriceRegistryInterface) WatchTokenTransferFeeConfigUpdated(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, destChainSelector, token) + + if len(ret) == 0 { + panic("no return value specified for WatchTokenTransferFeeConfigUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, []uint64, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, destChainSelector, token) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, []uint64, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, destChainSelector, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, []uint64, []common.Address) error); ok { + r1 = rf(opts, sink, destChainSelector, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTokenTransferFeeConfigUpdated' +type PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call struct { + *mock.Call +} + +// WatchTokenTransferFeeConfigUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated +// - destChainSelector []uint64 +// - token []common.Address +func (_e *PriceRegistryInterface_Expecter) WatchTokenTransferFeeConfigUpdated(opts interface{}, sink interface{}, destChainSelector interface{}, token interface{}) *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call { + return &PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call{Call: _e.mock.On("WatchTokenTransferFeeConfigUpdated", opts, sink, destChainSelector, token)} +} + +func (_c *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, destChainSelector []uint64, token []common.Address)) *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated), args[2].([]uint64), args[3].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, []uint64, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WatchUsdPerTokenUpdated provides a mock function with given fields: opts, sink, token +func (_m *PriceRegistryInterface) WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, token) + + if len(ret) == 0 { + panic("no return value specified for WatchUsdPerTokenUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerTokenUpdated, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, token) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerTokenUpdated, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerTokenUpdated, []common.Address) error); ok { + r1 = rf(opts, sink, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchUsdPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchUsdPerTokenUpdated' +type PriceRegistryInterface_WatchUsdPerTokenUpdated_Call struct { + *mock.Call +} + +// WatchUsdPerTokenUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryUsdPerTokenUpdated +// - token []common.Address +func (_e *PriceRegistryInterface_Expecter) WatchUsdPerTokenUpdated(opts interface{}, sink interface{}, token interface{}) *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call { + return &PriceRegistryInterface_WatchUsdPerTokenUpdated_Call{Call: _e.mock.On("WatchUsdPerTokenUpdated", opts, sink, token)} +} + +func (_c *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryUsdPerTokenUpdated, token []common.Address)) *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryUsdPerTokenUpdated), args[2].([]common.Address)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerTokenUpdated, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WatchUsdPerUnitGasUpdated provides a mock function with given fields: opts, sink, destChain +func (_m *PriceRegistryInterface) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) { + ret := _m.Called(opts, sink, destChain) + + if len(ret) == 0 { + panic("no return value specified for WatchUsdPerUnitGasUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated, []uint64) (event.Subscription, error)); ok { + return rf(opts, sink, destChain) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated, []uint64) event.Subscription); ok { + r0 = rf(opts, sink, destChain) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated, []uint64) error); ok { + r1 = rf(opts, sink, destChain) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchUsdPerUnitGasUpdated' +type PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call struct { + *mock.Call +} + +// WatchUsdPerUnitGasUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated +// - destChain []uint64 +func (_e *PriceRegistryInterface_Expecter) WatchUsdPerUnitGasUpdated(opts interface{}, sink interface{}, destChain interface{}) *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call { + return &PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call{Call: _e.mock.On("WatchUsdPerUnitGasUpdated", opts, sink, destChain)} +} + +func (_c *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated, destChain []uint64)) *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated), args[2].([]uint64)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated, []uint64) (event.Subscription, error)) *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call { + _c.Call.Return(run) + return _c +} + +// NewPriceRegistryInterface creates a new instance of PriceRegistryInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewPriceRegistryInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *PriceRegistryInterface { + mock := &PriceRegistryInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/ccip/mocks/v1_0_0/evm2_evm_off_ramp_interface.go b/core/gethwrappers/ccip/mocks/v1_0_0/evm2_evm_off_ramp_interface.go new file mode 100644 index 0000000000..cefb2c2684 --- /dev/null +++ b/core/gethwrappers/ccip/mocks/v1_0_0/evm2_evm_off_ramp_interface.go @@ -0,0 +1,3603 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_contracts + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + evm_2_evm_offramp_1_0_0 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// EVM2EVMOffRampInterface is an autogenerated mock type for the EVM2EVMOffRampInterface type +type EVM2EVMOffRampInterface struct { + mock.Mock +} + +type EVM2EVMOffRampInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *EVM2EVMOffRampInterface) EXPECT() *EVM2EVMOffRampInterface_Expecter { + return &EVM2EVMOffRampInterface_Expecter{mock: &_m.Mock} +} + +// AcceptOwnership provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for AcceptOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_AcceptOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AcceptOwnership' +type EVM2EVMOffRampInterface_AcceptOwnership_Call struct { + *mock.Call +} + +// AcceptOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *EVM2EVMOffRampInterface_Expecter) AcceptOwnership(opts interface{}) *EVM2EVMOffRampInterface_AcceptOwnership_Call { + return &EVM2EVMOffRampInterface_AcceptOwnership_Call{Call: _e.mock.On("AcceptOwnership", opts)} +} + +func (_c *EVM2EVMOffRampInterface_AcceptOwnership_Call) Run(run func(opts *bind.TransactOpts)) *EVM2EVMOffRampInterface_AcceptOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_AcceptOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_AcceptOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_AcceptOwnership_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *EVM2EVMOffRampInterface_AcceptOwnership_Call { + _c.Call.Return(run) + return _c +} + +// Address provides a mock function with given fields: +func (_m *EVM2EVMOffRampInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// EVM2EVMOffRampInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type EVM2EVMOffRampInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *EVM2EVMOffRampInterface_Expecter) Address() *EVM2EVMOffRampInterface_Address_Call { + return &EVM2EVMOffRampInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *EVM2EVMOffRampInterface_Address_Call) Run(run func()) *EVM2EVMOffRampInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Address_Call) Return(_a0 common.Address) *EVM2EVMOffRampInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Address_Call) RunAndReturn(run func() common.Address) *EVM2EVMOffRampInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// ApplyPoolUpdates provides a mock function with given fields: opts, removes, adds +func (_m *EVM2EVMOffRampInterface) ApplyPoolUpdates(opts *bind.TransactOpts, removes []evm_2_evm_offramp_1_0_0.InternalPoolUpdate, adds []evm_2_evm_offramp_1_0_0.InternalPoolUpdate) (*types.Transaction, error) { + ret := _m.Called(opts, removes, adds) + + if len(ret) == 0 { + panic("no return value specified for ApplyPoolUpdates") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []evm_2_evm_offramp_1_0_0.InternalPoolUpdate, []evm_2_evm_offramp_1_0_0.InternalPoolUpdate) (*types.Transaction, error)); ok { + return rf(opts, removes, adds) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []evm_2_evm_offramp_1_0_0.InternalPoolUpdate, []evm_2_evm_offramp_1_0_0.InternalPoolUpdate) *types.Transaction); ok { + r0 = rf(opts, removes, adds) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []evm_2_evm_offramp_1_0_0.InternalPoolUpdate, []evm_2_evm_offramp_1_0_0.InternalPoolUpdate) error); ok { + r1 = rf(opts, removes, adds) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ApplyPoolUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyPoolUpdates' +type EVM2EVMOffRampInterface_ApplyPoolUpdates_Call struct { + *mock.Call +} + +// ApplyPoolUpdates is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - removes []evm_2_evm_offramp_1_0_0.InternalPoolUpdate +// - adds []evm_2_evm_offramp_1_0_0.InternalPoolUpdate +func (_e *EVM2EVMOffRampInterface_Expecter) ApplyPoolUpdates(opts interface{}, removes interface{}, adds interface{}) *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call { + return &EVM2EVMOffRampInterface_ApplyPoolUpdates_Call{Call: _e.mock.On("ApplyPoolUpdates", opts, removes, adds)} +} + +func (_c *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call) Run(run func(opts *bind.TransactOpts, removes []evm_2_evm_offramp_1_0_0.InternalPoolUpdate, adds []evm_2_evm_offramp_1_0_0.InternalPoolUpdate)) *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]evm_2_evm_offramp_1_0_0.InternalPoolUpdate), args[2].([]evm_2_evm_offramp_1_0_0.InternalPoolUpdate)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []evm_2_evm_offramp_1_0_0.InternalPoolUpdate, []evm_2_evm_offramp_1_0_0.InternalPoolUpdate) (*types.Transaction, error)) *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call { + _c.Call.Return(run) + return _c +} + +// CcipReceive provides a mock function with given fields: opts, arg0 +func (_m *EVM2EVMOffRampInterface) CcipReceive(opts *bind.CallOpts, arg0 evm_2_evm_offramp_1_0_0.ClientAny2EVMMessage) error { + ret := _m.Called(opts, arg0) + + if len(ret) == 0 { + panic("no return value specified for CcipReceive") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, evm_2_evm_offramp_1_0_0.ClientAny2EVMMessage) error); ok { + r0 = rf(opts, arg0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// EVM2EVMOffRampInterface_CcipReceive_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CcipReceive' +type EVM2EVMOffRampInterface_CcipReceive_Call struct { + *mock.Call +} + +// CcipReceive is a helper method to define mock.On call +// - opts *bind.CallOpts +// - arg0 evm_2_evm_offramp_1_0_0.ClientAny2EVMMessage +func (_e *EVM2EVMOffRampInterface_Expecter) CcipReceive(opts interface{}, arg0 interface{}) *EVM2EVMOffRampInterface_CcipReceive_Call { + return &EVM2EVMOffRampInterface_CcipReceive_Call{Call: _e.mock.On("CcipReceive", opts, arg0)} +} + +func (_c *EVM2EVMOffRampInterface_CcipReceive_Call) Run(run func(opts *bind.CallOpts, arg0 evm_2_evm_offramp_1_0_0.ClientAny2EVMMessage)) *EVM2EVMOffRampInterface_CcipReceive_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(evm_2_evm_offramp_1_0_0.ClientAny2EVMMessage)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_CcipReceive_Call) Return(_a0 error) *EVM2EVMOffRampInterface_CcipReceive_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *EVM2EVMOffRampInterface_CcipReceive_Call) RunAndReturn(run func(*bind.CallOpts, evm_2_evm_offramp_1_0_0.ClientAny2EVMMessage) error) *EVM2EVMOffRampInterface_CcipReceive_Call { + _c.Call.Return(run) + return _c +} + +// CurrentRateLimiterState provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) CurrentRateLimiterState(opts *bind.CallOpts) (evm_2_evm_offramp_1_0_0.RateLimiterTokenBucket, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for CurrentRateLimiterState") + } + + var r0 evm_2_evm_offramp_1_0_0.RateLimiterTokenBucket + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp_1_0_0.RateLimiterTokenBucket, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp_1_0_0.RateLimiterTokenBucket); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp_1_0_0.RateLimiterTokenBucket) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_CurrentRateLimiterState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CurrentRateLimiterState' +type EVM2EVMOffRampInterface_CurrentRateLimiterState_Call struct { + *mock.Call +} + +// CurrentRateLimiterState is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) CurrentRateLimiterState(opts interface{}) *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call { + return &EVM2EVMOffRampInterface_CurrentRateLimiterState_Call{Call: _e.mock.On("CurrentRateLimiterState", opts)} +} + +func (_c *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call) Return(_a0 evm_2_evm_offramp_1_0_0.RateLimiterTokenBucket, _a1 error) *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp_1_0_0.RateLimiterTokenBucket, error)) *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call { + _c.Call.Return(run) + return _c +} + +// ExecuteSingleMessage provides a mock function with given fields: opts, message, offchainTokenData +func (_m *EVM2EVMOffRampInterface) ExecuteSingleMessage(opts *bind.TransactOpts, message evm_2_evm_offramp_1_0_0.InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + ret := _m.Called(opts, message, offchainTokenData) + + if len(ret) == 0 { + panic("no return value specified for ExecuteSingleMessage") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp_1_0_0.InternalEVM2EVMMessage, [][]byte) (*types.Transaction, error)); ok { + return rf(opts, message, offchainTokenData) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp_1_0_0.InternalEVM2EVMMessage, [][]byte) *types.Transaction); ok { + r0 = rf(opts, message, offchainTokenData) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp_1_0_0.InternalEVM2EVMMessage, [][]byte) error); ok { + r1 = rf(opts, message, offchainTokenData) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ExecuteSingleMessage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExecuteSingleMessage' +type EVM2EVMOffRampInterface_ExecuteSingleMessage_Call struct { + *mock.Call +} + +// ExecuteSingleMessage is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - message evm_2_evm_offramp_1_0_0.InternalEVM2EVMMessage +// - offchainTokenData [][]byte +func (_e *EVM2EVMOffRampInterface_Expecter) ExecuteSingleMessage(opts interface{}, message interface{}, offchainTokenData interface{}) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + return &EVM2EVMOffRampInterface_ExecuteSingleMessage_Call{Call: _e.mock.On("ExecuteSingleMessage", opts, message, offchainTokenData)} +} + +func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) Run(run func(opts *bind.TransactOpts, message evm_2_evm_offramp_1_0_0.InternalEVM2EVMMessage, offchainTokenData [][]byte)) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp_1_0_0.InternalEVM2EVMMessage), args[2].([][]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp_1_0_0.InternalEVM2EVMMessage, [][]byte) (*types.Transaction, error)) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + _c.Call.Return(run) + return _c +} + +// FilterAdminSet provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterAdminSet(opts *bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterAdminSet") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterAdminSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterAdminSet' +type EVM2EVMOffRampInterface_FilterAdminSet_Call struct { + *mock.Call +} + +// FilterAdminSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterAdminSet(opts interface{}) *EVM2EVMOffRampInterface_FilterAdminSet_Call { + return &EVM2EVMOffRampInterface_FilterAdminSet_Call{Call: _e.mock.On("FilterAdminSet", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterAdminSet_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterAdminSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterAdminSet_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSetIterator, _a1 error) *EVM2EVMOffRampInterface_FilterAdminSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterAdminSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSetIterator, error)) *EVM2EVMOffRampInterface_FilterAdminSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfigSet provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterConfigSet(opts *bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterConfigSet") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfigSet' +type EVM2EVMOffRampInterface_FilterConfigSet_Call struct { + *mock.Call +} + +// FilterConfigSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterConfigSet(opts interface{}) *EVM2EVMOffRampInterface_FilterConfigSet_Call { + return &EVM2EVMOffRampInterface_FilterConfigSet_Call{Call: _e.mock.On("FilterConfigSet", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSetIterator, _a1 error) *EVM2EVMOffRampInterface_FilterConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSetIterator, error)) *EVM2EVMOffRampInterface_FilterConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfigSet0 provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterConfigSet0(opts *bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0Iterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterConfigSet0") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0Iterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0Iterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0Iterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0Iterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterConfigSet0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfigSet0' +type EVM2EVMOffRampInterface_FilterConfigSet0_Call struct { + *mock.Call +} + +// FilterConfigSet0 is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterConfigSet0(opts interface{}) *EVM2EVMOffRampInterface_FilterConfigSet0_Call { + return &EVM2EVMOffRampInterface_FilterConfigSet0_Call{Call: _e.mock.On("FilterConfigSet0", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet0_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterConfigSet0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet0_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0Iterator, _a1 error) *EVM2EVMOffRampInterface_FilterConfigSet0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet0_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0Iterator, error)) *EVM2EVMOffRampInterface_FilterConfigSet0_Call { + _c.Call.Return(run) + return _c +} + +// FilterExecutionStateChanged provides a mock function with given fields: opts, sequenceNumber, messageId +func (_m *EVM2EVMOffRampInterface) FilterExecutionStateChanged(opts *bind.FilterOpts, sequenceNumber []uint64, messageId [][32]byte) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChangedIterator, error) { + ret := _m.Called(opts, sequenceNumber, messageId) + + if len(ret) == 0 { + panic("no return value specified for FilterExecutionStateChanged") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChangedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, [][32]byte) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChangedIterator, error)); ok { + return rf(opts, sequenceNumber, messageId) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, [][32]byte) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChangedIterator); ok { + r0 = rf(opts, sequenceNumber, messageId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChangedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, [][32]byte) error); ok { + r1 = rf(opts, sequenceNumber, messageId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterExecutionStateChanged' +type EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call struct { + *mock.Call +} + +// FilterExecutionStateChanged is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - sequenceNumber []uint64 +// - messageId [][32]byte +func (_e *EVM2EVMOffRampInterface_Expecter) FilterExecutionStateChanged(opts interface{}, sequenceNumber interface{}, messageId interface{}) *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call { + return &EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call{Call: _e.mock.On("FilterExecutionStateChanged", opts, sequenceNumber, messageId)} +} + +func (_c *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call) Run(run func(opts *bind.FilterOpts, sequenceNumber []uint64, messageId [][32]byte)) *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([][32]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChangedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, [][32]byte) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChangedIterator, error)) *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferRequested provides a mock function with given fields: opts, from, to +func (_m *EVM2EVMOffRampInterface) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequestedIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferRequested") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequestedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequestedIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequestedIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequestedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferRequested' +type EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call struct { + *mock.Call +} + +// FilterOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) FilterOwnershipTransferRequested(opts interface{}, from interface{}, to interface{}) *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call { + return &EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call{Call: _e.mock.On("FilterOwnershipTransferRequested", opts, from, to)} +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequestedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequestedIterator, error)) *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferred provides a mock function with given fields: opts, from, to +func (_m *EVM2EVMOffRampInterface) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferredIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferred") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferredIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferredIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferredIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferredIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferred' +type EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call struct { + *mock.Call +} + +// FilterOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) FilterOwnershipTransferred(opts interface{}, from interface{}, to interface{}) *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call { + return &EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call{Call: _e.mock.On("FilterOwnershipTransferred", opts, from, to)} +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferredIterator, _a1 error) *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferredIterator, error)) *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// FilterPoolAdded provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterPoolAdded(opts *bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAddedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterPoolAdded") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAddedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAddedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAddedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAddedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterPoolAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPoolAdded' +type EVM2EVMOffRampInterface_FilterPoolAdded_Call struct { + *mock.Call +} + +// FilterPoolAdded is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterPoolAdded(opts interface{}) *EVM2EVMOffRampInterface_FilterPoolAdded_Call { + return &EVM2EVMOffRampInterface_FilterPoolAdded_Call{Call: _e.mock.On("FilterPoolAdded", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterPoolAdded_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterPoolAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterPoolAdded_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAddedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterPoolAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterPoolAdded_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAddedIterator, error)) *EVM2EVMOffRampInterface_FilterPoolAdded_Call { + _c.Call.Return(run) + return _c +} + +// FilterPoolRemoved provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterPoolRemoved(opts *bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemovedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterPoolRemoved") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemovedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemovedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemovedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemovedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterPoolRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPoolRemoved' +type EVM2EVMOffRampInterface_FilterPoolRemoved_Call struct { + *mock.Call +} + +// FilterPoolRemoved is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterPoolRemoved(opts interface{}) *EVM2EVMOffRampInterface_FilterPoolRemoved_Call { + return &EVM2EVMOffRampInterface_FilterPoolRemoved_Call{Call: _e.mock.On("FilterPoolRemoved", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterPoolRemoved_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterPoolRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterPoolRemoved_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemovedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterPoolRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterPoolRemoved_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemovedIterator, error)) *EVM2EVMOffRampInterface_FilterPoolRemoved_Call { + _c.Call.Return(run) + return _c +} + +// FilterSkippedIncorrectNonce provides a mock function with given fields: opts, nonce, sender +func (_m *EVM2EVMOffRampInterface) FilterSkippedIncorrectNonce(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonceIterator, error) { + ret := _m.Called(opts, nonce, sender) + + if len(ret) == 0 { + panic("no return value specified for FilterSkippedIncorrectNonce") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonceIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonceIterator, error)); ok { + return rf(opts, nonce, sender) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonceIterator); ok { + r0 = rf(opts, nonce, sender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonceIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, []common.Address) error); ok { + r1 = rf(opts, nonce, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterSkippedIncorrectNonce' +type EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call struct { + *mock.Call +} + +// FilterSkippedIncorrectNonce is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - nonce []uint64 +// - sender []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) FilterSkippedIncorrectNonce(opts interface{}, nonce interface{}, sender interface{}) *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call { + return &EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call{Call: _e.mock.On("FilterSkippedIncorrectNonce", opts, nonce, sender)} +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call) Run(run func(opts *bind.FilterOpts, nonce []uint64, sender []common.Address)) *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonceIterator, _a1 error) *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, []common.Address) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonceIterator, error)) *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call { + _c.Call.Return(run) + return _c +} + +// FilterSkippedSenderWithPreviousRampMessageInflight provides a mock function with given fields: opts, nonce, sender +func (_m *EVM2EVMOffRampInterface) FilterSkippedSenderWithPreviousRampMessageInflight(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error) { + ret := _m.Called(opts, nonce, sender) + + if len(ret) == 0 { + panic("no return value specified for FilterSkippedSenderWithPreviousRampMessageInflight") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error)); ok { + return rf(opts, nonce, sender) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator); ok { + r0 = rf(opts, nonce, sender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, []common.Address) error); ok { + r1 = rf(opts, nonce, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterSkippedSenderWithPreviousRampMessageInflight' +type EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call struct { + *mock.Call +} + +// FilterSkippedSenderWithPreviousRampMessageInflight is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - nonce []uint64 +// - sender []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) FilterSkippedSenderWithPreviousRampMessageInflight(opts interface{}, nonce interface{}, sender interface{}) *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call { + return &EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call{Call: _e.mock.On("FilterSkippedSenderWithPreviousRampMessageInflight", opts, nonce, sender)} +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call) Run(run func(opts *bind.FilterOpts, nonce []uint64, sender []common.Address)) *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, _a1 error) *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, []common.Address) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error)) *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(run) + return _c +} + +// FilterTransmitted provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterTransmitted(opts *bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmittedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterTransmitted") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmittedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmittedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmittedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmittedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterTransmitted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTransmitted' +type EVM2EVMOffRampInterface_FilterTransmitted_Call struct { + *mock.Call +} + +// FilterTransmitted is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterTransmitted(opts interface{}) *EVM2EVMOffRampInterface_FilterTransmitted_Call { + return &EVM2EVMOffRampInterface_FilterTransmitted_Call{Call: _e.mock.On("FilterTransmitted", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterTransmitted_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterTransmitted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterTransmitted_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmittedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterTransmitted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterTransmitted_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmittedIterator, error)) *EVM2EVMOffRampInterface_FilterTransmitted_Call { + _c.Call.Return(run) + return _c +} + +// GetDestinationToken provides a mock function with given fields: opts, sourceToken +func (_m *EVM2EVMOffRampInterface) GetDestinationToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) { + ret := _m.Called(opts, sourceToken) + + if len(ret) == 0 { + panic("no return value specified for GetDestinationToken") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (common.Address, error)); ok { + return rf(opts, sourceToken) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) common.Address); ok { + r0 = rf(opts, sourceToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, sourceToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetDestinationToken_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDestinationToken' +type EVM2EVMOffRampInterface_GetDestinationToken_Call struct { + *mock.Call +} + +// GetDestinationToken is a helper method to define mock.On call +// - opts *bind.CallOpts +// - sourceToken common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) GetDestinationToken(opts interface{}, sourceToken interface{}) *EVM2EVMOffRampInterface_GetDestinationToken_Call { + return &EVM2EVMOffRampInterface_GetDestinationToken_Call{Call: _e.mock.On("GetDestinationToken", opts, sourceToken)} +} + +func (_c *EVM2EVMOffRampInterface_GetDestinationToken_Call) Run(run func(opts *bind.CallOpts, sourceToken common.Address)) *EVM2EVMOffRampInterface_GetDestinationToken_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDestinationToken_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOffRampInterface_GetDestinationToken_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDestinationToken_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (common.Address, error)) *EVM2EVMOffRampInterface_GetDestinationToken_Call { + _c.Call.Return(run) + return _c +} + +// GetDestinationTokens provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetDestinationTokens(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetDestinationTokens") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetDestinationTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDestinationTokens' +type EVM2EVMOffRampInterface_GetDestinationTokens_Call struct { + *mock.Call +} + +// GetDestinationTokens is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetDestinationTokens(opts interface{}) *EVM2EVMOffRampInterface_GetDestinationTokens_Call { + return &EVM2EVMOffRampInterface_GetDestinationTokens_Call{Call: _e.mock.On("GetDestinationTokens", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetDestinationTokens_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetDestinationTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDestinationTokens_Call) Return(_a0 []common.Address, _a1 error) *EVM2EVMOffRampInterface_GetDestinationTokens_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDestinationTokens_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *EVM2EVMOffRampInterface_GetDestinationTokens_Call { + _c.Call.Return(run) + return _c +} + +// GetDynamicConfig provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetDynamicConfig(opts *bind.CallOpts) (evm_2_evm_offramp_1_0_0.EVM2EVMOffRampDynamicConfig, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetDynamicConfig") + } + + var r0 evm_2_evm_offramp_1_0_0.EVM2EVMOffRampDynamicConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp_1_0_0.EVM2EVMOffRampDynamicConfig, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp_1_0_0.EVM2EVMOffRampDynamicConfig); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp_1_0_0.EVM2EVMOffRampDynamicConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetDynamicConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDynamicConfig' +type EVM2EVMOffRampInterface_GetDynamicConfig_Call struct { + *mock.Call +} + +// GetDynamicConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetDynamicConfig(opts interface{}) *EVM2EVMOffRampInterface_GetDynamicConfig_Call { + return &EVM2EVMOffRampInterface_GetDynamicConfig_Call{Call: _e.mock.On("GetDynamicConfig", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetDynamicConfig_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetDynamicConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDynamicConfig_Call) Return(_a0 evm_2_evm_offramp_1_0_0.EVM2EVMOffRampDynamicConfig, _a1 error) *EVM2EVMOffRampInterface_GetDynamicConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDynamicConfig_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp_1_0_0.EVM2EVMOffRampDynamicConfig, error)) *EVM2EVMOffRampInterface_GetDynamicConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetExecutionState provides a mock function with given fields: opts, sequenceNumber +func (_m *EVM2EVMOffRampInterface) GetExecutionState(opts *bind.CallOpts, sequenceNumber uint64) (uint8, error) { + ret := _m.Called(opts, sequenceNumber) + + if len(ret) == 0 { + panic("no return value specified for GetExecutionState") + } + + var r0 uint8 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (uint8, error)); ok { + return rf(opts, sequenceNumber) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) uint8); ok { + r0 = rf(opts, sequenceNumber) + } else { + r0 = ret.Get(0).(uint8) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, sequenceNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetExecutionState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExecutionState' +type EVM2EVMOffRampInterface_GetExecutionState_Call struct { + *mock.Call +} + +// GetExecutionState is a helper method to define mock.On call +// - opts *bind.CallOpts +// - sequenceNumber uint64 +func (_e *EVM2EVMOffRampInterface_Expecter) GetExecutionState(opts interface{}, sequenceNumber interface{}) *EVM2EVMOffRampInterface_GetExecutionState_Call { + return &EVM2EVMOffRampInterface_GetExecutionState_Call{Call: _e.mock.On("GetExecutionState", opts, sequenceNumber)} +} + +func (_c *EVM2EVMOffRampInterface_GetExecutionState_Call) Run(run func(opts *bind.CallOpts, sequenceNumber uint64)) *EVM2EVMOffRampInterface_GetExecutionState_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetExecutionState_Call) Return(_a0 uint8, _a1 error) *EVM2EVMOffRampInterface_GetExecutionState_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetExecutionState_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (uint8, error)) *EVM2EVMOffRampInterface_GetExecutionState_Call { + _c.Call.Return(run) + return _c +} + +// GetPoolByDestToken provides a mock function with given fields: opts, destToken +func (_m *EVM2EVMOffRampInterface) GetPoolByDestToken(opts *bind.CallOpts, destToken common.Address) (common.Address, error) { + ret := _m.Called(opts, destToken) + + if len(ret) == 0 { + panic("no return value specified for GetPoolByDestToken") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (common.Address, error)); ok { + return rf(opts, destToken) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) common.Address); ok { + r0 = rf(opts, destToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, destToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetPoolByDestToken_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPoolByDestToken' +type EVM2EVMOffRampInterface_GetPoolByDestToken_Call struct { + *mock.Call +} + +// GetPoolByDestToken is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destToken common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) GetPoolByDestToken(opts interface{}, destToken interface{}) *EVM2EVMOffRampInterface_GetPoolByDestToken_Call { + return &EVM2EVMOffRampInterface_GetPoolByDestToken_Call{Call: _e.mock.On("GetPoolByDestToken", opts, destToken)} +} + +func (_c *EVM2EVMOffRampInterface_GetPoolByDestToken_Call) Run(run func(opts *bind.CallOpts, destToken common.Address)) *EVM2EVMOffRampInterface_GetPoolByDestToken_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetPoolByDestToken_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOffRampInterface_GetPoolByDestToken_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetPoolByDestToken_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (common.Address, error)) *EVM2EVMOffRampInterface_GetPoolByDestToken_Call { + _c.Call.Return(run) + return _c +} + +// GetPoolBySourceToken provides a mock function with given fields: opts, sourceToken +func (_m *EVM2EVMOffRampInterface) GetPoolBySourceToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) { + ret := _m.Called(opts, sourceToken) + + if len(ret) == 0 { + panic("no return value specified for GetPoolBySourceToken") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (common.Address, error)); ok { + return rf(opts, sourceToken) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) common.Address); ok { + r0 = rf(opts, sourceToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, sourceToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetPoolBySourceToken_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPoolBySourceToken' +type EVM2EVMOffRampInterface_GetPoolBySourceToken_Call struct { + *mock.Call +} + +// GetPoolBySourceToken is a helper method to define mock.On call +// - opts *bind.CallOpts +// - sourceToken common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) GetPoolBySourceToken(opts interface{}, sourceToken interface{}) *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call { + return &EVM2EVMOffRampInterface_GetPoolBySourceToken_Call{Call: _e.mock.On("GetPoolBySourceToken", opts, sourceToken)} +} + +func (_c *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call) Run(run func(opts *bind.CallOpts, sourceToken common.Address)) *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (common.Address, error)) *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call { + _c.Call.Return(run) + return _c +} + +// GetSenderNonce provides a mock function with given fields: opts, sender +func (_m *EVM2EVMOffRampInterface) GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) { + ret := _m.Called(opts, sender) + + if len(ret) == 0 { + panic("no return value specified for GetSenderNonce") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (uint64, error)); ok { + return rf(opts, sender) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) uint64); ok { + r0 = rf(opts, sender) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetSenderNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSenderNonce' +type EVM2EVMOffRampInterface_GetSenderNonce_Call struct { + *mock.Call +} + +// GetSenderNonce is a helper method to define mock.On call +// - opts *bind.CallOpts +// - sender common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) GetSenderNonce(opts interface{}, sender interface{}) *EVM2EVMOffRampInterface_GetSenderNonce_Call { + return &EVM2EVMOffRampInterface_GetSenderNonce_Call{Call: _e.mock.On("GetSenderNonce", opts, sender)} +} + +func (_c *EVM2EVMOffRampInterface_GetSenderNonce_Call) Run(run func(opts *bind.CallOpts, sender common.Address)) *EVM2EVMOffRampInterface_GetSenderNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetSenderNonce_Call) Return(_a0 uint64, _a1 error) *EVM2EVMOffRampInterface_GetSenderNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetSenderNonce_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (uint64, error)) *EVM2EVMOffRampInterface_GetSenderNonce_Call { + _c.Call.Return(run) + return _c +} + +// GetStaticConfig provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetStaticConfig(opts *bind.CallOpts) (evm_2_evm_offramp_1_0_0.EVM2EVMOffRampStaticConfig, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetStaticConfig") + } + + var r0 evm_2_evm_offramp_1_0_0.EVM2EVMOffRampStaticConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp_1_0_0.EVM2EVMOffRampStaticConfig, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp_1_0_0.EVM2EVMOffRampStaticConfig); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp_1_0_0.EVM2EVMOffRampStaticConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetStaticConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStaticConfig' +type EVM2EVMOffRampInterface_GetStaticConfig_Call struct { + *mock.Call +} + +// GetStaticConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetStaticConfig(opts interface{}) *EVM2EVMOffRampInterface_GetStaticConfig_Call { + return &EVM2EVMOffRampInterface_GetStaticConfig_Call{Call: _e.mock.On("GetStaticConfig", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetStaticConfig_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetStaticConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetStaticConfig_Call) Return(_a0 evm_2_evm_offramp_1_0_0.EVM2EVMOffRampStaticConfig, _a1 error) *EVM2EVMOffRampInterface_GetStaticConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetStaticConfig_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp_1_0_0.EVM2EVMOffRampStaticConfig, error)) *EVM2EVMOffRampInterface_GetStaticConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetSupportedTokens provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetSupportedTokens(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetSupportedTokens") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetSupportedTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSupportedTokens' +type EVM2EVMOffRampInterface_GetSupportedTokens_Call struct { + *mock.Call +} + +// GetSupportedTokens is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetSupportedTokens(opts interface{}) *EVM2EVMOffRampInterface_GetSupportedTokens_Call { + return &EVM2EVMOffRampInterface_GetSupportedTokens_Call{Call: _e.mock.On("GetSupportedTokens", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetSupportedTokens_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetSupportedTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetSupportedTokens_Call) Return(_a0 []common.Address, _a1 error) *EVM2EVMOffRampInterface_GetSupportedTokens_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetSupportedTokens_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *EVM2EVMOffRampInterface_GetSupportedTokens_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenLimitAdmin provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetTokenLimitAdmin") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenLimitAdmin' +type EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call struct { + *mock.Call +} + +// GetTokenLimitAdmin is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetTokenLimitAdmin(opts interface{}) *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call { + return &EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call{Call: _e.mock.On("GetTokenLimitAdmin", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call { + _c.Call.Return(run) + return _c +} + +// GetTransmitters provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetTransmitters") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetTransmitters_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTransmitters' +type EVM2EVMOffRampInterface_GetTransmitters_Call struct { + *mock.Call +} + +// GetTransmitters is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetTransmitters(opts interface{}) *EVM2EVMOffRampInterface_GetTransmitters_Call { + return &EVM2EVMOffRampInterface_GetTransmitters_Call{Call: _e.mock.On("GetTransmitters", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetTransmitters_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetTransmitters_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetTransmitters_Call) Return(_a0 []common.Address, _a1 error) *EVM2EVMOffRampInterface_GetTransmitters_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetTransmitters_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *EVM2EVMOffRampInterface_GetTransmitters_Call { + _c.Call.Return(run) + return _c +} + +// LatestConfigDetails provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) LatestConfigDetails(opts *bind.CallOpts) (evm_2_evm_offramp_1_0_0.LatestConfigDetails, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LatestConfigDetails") + } + + var r0 evm_2_evm_offramp_1_0_0.LatestConfigDetails + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp_1_0_0.LatestConfigDetails, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp_1_0_0.LatestConfigDetails); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp_1_0_0.LatestConfigDetails) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_LatestConfigDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestConfigDetails' +type EVM2EVMOffRampInterface_LatestConfigDetails_Call struct { + *mock.Call +} + +// LatestConfigDetails is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) LatestConfigDetails(opts interface{}) *EVM2EVMOffRampInterface_LatestConfigDetails_Call { + return &EVM2EVMOffRampInterface_LatestConfigDetails_Call{Call: _e.mock.On("LatestConfigDetails", opts)} +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDetails_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_LatestConfigDetails_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDetails_Call) Return(_a0 evm_2_evm_offramp_1_0_0.LatestConfigDetails, _a1 error) *EVM2EVMOffRampInterface_LatestConfigDetails_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDetails_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp_1_0_0.LatestConfigDetails, error)) *EVM2EVMOffRampInterface_LatestConfigDetails_Call { + _c.Call.Return(run) + return _c +} + +// LatestConfigDigestAndEpoch provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (evm_2_evm_offramp_1_0_0.LatestConfigDigestAndEpoch, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LatestConfigDigestAndEpoch") + } + + var r0 evm_2_evm_offramp_1_0_0.LatestConfigDigestAndEpoch + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp_1_0_0.LatestConfigDigestAndEpoch, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp_1_0_0.LatestConfigDigestAndEpoch); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp_1_0_0.LatestConfigDigestAndEpoch) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestConfigDigestAndEpoch' +type EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call struct { + *mock.Call +} + +// LatestConfigDigestAndEpoch is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) LatestConfigDigestAndEpoch(opts interface{}) *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call { + return &EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call{Call: _e.mock.On("LatestConfigDigestAndEpoch", opts)} +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call) Return(_a0 evm_2_evm_offramp_1_0_0.LatestConfigDigestAndEpoch, _a1 error) *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp_1_0_0.LatestConfigDigestAndEpoch, error)) *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call { + _c.Call.Return(run) + return _c +} + +// ManuallyExecute provides a mock function with given fields: opts, report, gasLimitOverrides +func (_m *EVM2EVMOffRampInterface) ManuallyExecute(opts *bind.TransactOpts, report evm_2_evm_offramp_1_0_0.InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { + ret := _m.Called(opts, report, gasLimitOverrides) + + if len(ret) == 0 { + panic("no return value specified for ManuallyExecute") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp_1_0_0.InternalExecutionReport, []*big.Int) (*types.Transaction, error)); ok { + return rf(opts, report, gasLimitOverrides) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp_1_0_0.InternalExecutionReport, []*big.Int) *types.Transaction); ok { + r0 = rf(opts, report, gasLimitOverrides) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp_1_0_0.InternalExecutionReport, []*big.Int) error); ok { + r1 = rf(opts, report, gasLimitOverrides) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ManuallyExecute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ManuallyExecute' +type EVM2EVMOffRampInterface_ManuallyExecute_Call struct { + *mock.Call +} + +// ManuallyExecute is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - report evm_2_evm_offramp_1_0_0.InternalExecutionReport +// - gasLimitOverrides []*big.Int +func (_e *EVM2EVMOffRampInterface_Expecter) ManuallyExecute(opts interface{}, report interface{}, gasLimitOverrides interface{}) *EVM2EVMOffRampInterface_ManuallyExecute_Call { + return &EVM2EVMOffRampInterface_ManuallyExecute_Call{Call: _e.mock.On("ManuallyExecute", opts, report, gasLimitOverrides)} +} + +func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) Run(run func(opts *bind.TransactOpts, report evm_2_evm_offramp_1_0_0.InternalExecutionReport, gasLimitOverrides []*big.Int)) *EVM2EVMOffRampInterface_ManuallyExecute_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp_1_0_0.InternalExecutionReport), args[2].([]*big.Int)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_ManuallyExecute_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp_1_0_0.InternalExecutionReport, []*big.Int) (*types.Transaction, error)) *EVM2EVMOffRampInterface_ManuallyExecute_Call { + _c.Call.Return(run) + return _c +} + +// Owner provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) Owner(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Owner") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_Owner_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Owner' +type EVM2EVMOffRampInterface_Owner_Call struct { + *mock.Call +} + +// Owner is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) Owner(opts interface{}) *EVM2EVMOffRampInterface_Owner_Call { + return &EVM2EVMOffRampInterface_Owner_Call{Call: _e.mock.On("Owner", opts)} +} + +func (_c *EVM2EVMOffRampInterface_Owner_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_Owner_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Owner_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOffRampInterface_Owner_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Owner_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *EVM2EVMOffRampInterface_Owner_Call { + _c.Call.Return(run) + return _c +} + +// ParseAdminSet provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseAdminSet(log types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseAdminSet") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseAdminSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseAdminSet' +type EVM2EVMOffRampInterface_ParseAdminSet_Call struct { + *mock.Call +} + +// ParseAdminSet is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseAdminSet(log interface{}) *EVM2EVMOffRampInterface_ParseAdminSet_Call { + return &EVM2EVMOffRampInterface_ParseAdminSet_Call{Call: _e.mock.On("ParseAdminSet", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseAdminSet_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseAdminSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseAdminSet_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet, _a1 error) *EVM2EVMOffRampInterface_ParseAdminSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseAdminSet_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet, error)) *EVM2EVMOffRampInterface_ParseAdminSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseConfigSet provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseConfigSet(log types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseConfigSet") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseConfigSet' +type EVM2EVMOffRampInterface_ParseConfigSet_Call struct { + *mock.Call +} + +// ParseConfigSet is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseConfigSet(log interface{}) *EVM2EVMOffRampInterface_ParseConfigSet_Call { + return &EVM2EVMOffRampInterface_ParseConfigSet_Call{Call: _e.mock.On("ParseConfigSet", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet, _a1 error) *EVM2EVMOffRampInterface_ParseConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet, error)) *EVM2EVMOffRampInterface_ParseConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseConfigSet0 provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseConfigSet0(log types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseConfigSet0") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0 + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseConfigSet0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseConfigSet0' +type EVM2EVMOffRampInterface_ParseConfigSet0_Call struct { + *mock.Call +} + +// ParseConfigSet0 is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseConfigSet0(log interface{}) *EVM2EVMOffRampInterface_ParseConfigSet0_Call { + return &EVM2EVMOffRampInterface_ParseConfigSet0_Call{Call: _e.mock.On("ParseConfigSet0", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet0_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseConfigSet0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet0_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0, _a1 error) *EVM2EVMOffRampInterface_ParseConfigSet0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet0_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0, error)) *EVM2EVMOffRampInterface_ParseConfigSet0_Call { + _c.Call.Return(run) + return _c +} + +// ParseExecutionStateChanged provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseExecutionStateChanged(log types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseExecutionStateChanged") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseExecutionStateChanged' +type EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call struct { + *mock.Call +} + +// ParseExecutionStateChanged is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseExecutionStateChanged(log interface{}) *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call { + return &EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call{Call: _e.mock.On("ParseExecutionStateChanged", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged, _a1 error) *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged, error)) *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type EVM2EVMOffRampInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseLog(log interface{}) *EVM2EVMOffRampInterface_ParseLog_Call { + return &EVM2EVMOffRampInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseLog_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *EVM2EVMOffRampInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *EVM2EVMOffRampInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferRequested provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseOwnershipTransferRequested(log types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferRequested") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferRequested' +type EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call struct { + *mock.Call +} + +// ParseOwnershipTransferRequested is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseOwnershipTransferRequested(log interface{}) *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call { + return &EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call{Call: _e.mock.On("ParseOwnershipTransferRequested", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested, _a1 error) *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested, error)) *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferred provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseOwnershipTransferred(log types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferred") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferred' +type EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call struct { + *mock.Call +} + +// ParseOwnershipTransferred is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseOwnershipTransferred(log interface{}) *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call { + return &EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call{Call: _e.mock.On("ParseOwnershipTransferred", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred, _a1 error) *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred, error)) *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// ParsePoolAdded provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParsePoolAdded(log types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParsePoolAdded") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParsePoolAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePoolAdded' +type EVM2EVMOffRampInterface_ParsePoolAdded_Call struct { + *mock.Call +} + +// ParsePoolAdded is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParsePoolAdded(log interface{}) *EVM2EVMOffRampInterface_ParsePoolAdded_Call { + return &EVM2EVMOffRampInterface_ParsePoolAdded_Call{Call: _e.mock.On("ParsePoolAdded", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParsePoolAdded_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParsePoolAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParsePoolAdded_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded, _a1 error) *EVM2EVMOffRampInterface_ParsePoolAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParsePoolAdded_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded, error)) *EVM2EVMOffRampInterface_ParsePoolAdded_Call { + _c.Call.Return(run) + return _c +} + +// ParsePoolRemoved provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParsePoolRemoved(log types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParsePoolRemoved") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParsePoolRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePoolRemoved' +type EVM2EVMOffRampInterface_ParsePoolRemoved_Call struct { + *mock.Call +} + +// ParsePoolRemoved is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParsePoolRemoved(log interface{}) *EVM2EVMOffRampInterface_ParsePoolRemoved_Call { + return &EVM2EVMOffRampInterface_ParsePoolRemoved_Call{Call: _e.mock.On("ParsePoolRemoved", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParsePoolRemoved_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParsePoolRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParsePoolRemoved_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved, _a1 error) *EVM2EVMOffRampInterface_ParsePoolRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParsePoolRemoved_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved, error)) *EVM2EVMOffRampInterface_ParsePoolRemoved_Call { + _c.Call.Return(run) + return _c +} + +// ParseSkippedIncorrectNonce provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseSkippedIncorrectNonce(log types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseSkippedIncorrectNonce") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseSkippedIncorrectNonce' +type EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call struct { + *mock.Call +} + +// ParseSkippedIncorrectNonce is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseSkippedIncorrectNonce(log interface{}) *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call { + return &EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call{Call: _e.mock.On("ParseSkippedIncorrectNonce", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce, _a1 error) *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce, error)) *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call { + _c.Call.Return(run) + return _c +} + +// ParseSkippedSenderWithPreviousRampMessageInflight provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseSkippedSenderWithPreviousRampMessageInflight(log types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseSkippedSenderWithPreviousRampMessageInflight") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseSkippedSenderWithPreviousRampMessageInflight' +type EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call struct { + *mock.Call +} + +// ParseSkippedSenderWithPreviousRampMessageInflight is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseSkippedSenderWithPreviousRampMessageInflight(log interface{}) *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call { + return &EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call{Call: _e.mock.On("ParseSkippedSenderWithPreviousRampMessageInflight", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, _a1 error) *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error)) *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(run) + return _c +} + +// ParseTransmitted provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseTransmitted(log types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTransmitted") + } + + var r0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseTransmitted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTransmitted' +type EVM2EVMOffRampInterface_ParseTransmitted_Call struct { + *mock.Call +} + +// ParseTransmitted is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseTransmitted(log interface{}) *EVM2EVMOffRampInterface_ParseTransmitted_Call { + return &EVM2EVMOffRampInterface_ParseTransmitted_Call{Call: _e.mock.On("ParseTransmitted", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseTransmitted_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseTransmitted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseTransmitted_Call) Return(_a0 *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted, _a1 error) *EVM2EVMOffRampInterface_ParseTransmitted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseTransmitted_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted, error)) *EVM2EVMOffRampInterface_ParseTransmitted_Call { + _c.Call.Return(run) + return _c +} + +// SetAdmin provides a mock function with given fields: opts, newAdmin +func (_m *EVM2EVMOffRampInterface) SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, newAdmin) + + if len(ret) == 0 { + panic("no return value specified for SetAdmin") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, newAdmin) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, newAdmin) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, newAdmin) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_SetAdmin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetAdmin' +type EVM2EVMOffRampInterface_SetAdmin_Call struct { + *mock.Call +} + +// SetAdmin is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - newAdmin common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) SetAdmin(opts interface{}, newAdmin interface{}) *EVM2EVMOffRampInterface_SetAdmin_Call { + return &EVM2EVMOffRampInterface_SetAdmin_Call{Call: _e.mock.On("SetAdmin", opts, newAdmin)} +} + +func (_c *EVM2EVMOffRampInterface_SetAdmin_Call) Run(run func(opts *bind.TransactOpts, newAdmin common.Address)) *EVM2EVMOffRampInterface_SetAdmin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetAdmin_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_SetAdmin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetAdmin_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *EVM2EVMOffRampInterface_SetAdmin_Call { + _c.Call.Return(run) + return _c +} + +// SetOCR2Config provides a mock function with given fields: opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig +func (_m *EVM2EVMOffRampInterface) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + ret := _m.Called(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + + if len(ret) == 0 { + panic("no return value specified for SetOCR2Config") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) (*types.Transaction, error)); ok { + return rf(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) *types.Transaction); ok { + r0 = rf(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) error); ok { + r1 = rf(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_SetOCR2Config_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetOCR2Config' +type EVM2EVMOffRampInterface_SetOCR2Config_Call struct { + *mock.Call +} + +// SetOCR2Config is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - signers []common.Address +// - transmitters []common.Address +// - f uint8 +// - onchainConfig []byte +// - offchainConfigVersion uint64 +// - offchainConfig []byte +func (_e *EVM2EVMOffRampInterface_Expecter) SetOCR2Config(opts interface{}, signers interface{}, transmitters interface{}, f interface{}, onchainConfig interface{}, offchainConfigVersion interface{}, offchainConfig interface{}) *EVM2EVMOffRampInterface_SetOCR2Config_Call { + return &EVM2EVMOffRampInterface_SetOCR2Config_Call{Call: _e.mock.On("SetOCR2Config", opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig)} +} + +func (_c *EVM2EVMOffRampInterface_SetOCR2Config_Call) Run(run func(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte)) *EVM2EVMOffRampInterface_SetOCR2Config_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]common.Address), args[2].([]common.Address), args[3].(uint8), args[4].([]byte), args[5].(uint64), args[6].([]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetOCR2Config_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_SetOCR2Config_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetOCR2Config_Call) RunAndReturn(run func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) (*types.Transaction, error)) *EVM2EVMOffRampInterface_SetOCR2Config_Call { + _c.Call.Return(run) + return _c +} + +// SetRateLimiterConfig provides a mock function with given fields: opts, config +func (_m *EVM2EVMOffRampInterface) SetRateLimiterConfig(opts *bind.TransactOpts, config evm_2_evm_offramp_1_0_0.RateLimiterConfig) (*types.Transaction, error) { + ret := _m.Called(opts, config) + + if len(ret) == 0 { + panic("no return value specified for SetRateLimiterConfig") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp_1_0_0.RateLimiterConfig) (*types.Transaction, error)); ok { + return rf(opts, config) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp_1_0_0.RateLimiterConfig) *types.Transaction); ok { + r0 = rf(opts, config) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp_1_0_0.RateLimiterConfig) error); ok { + r1 = rf(opts, config) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_SetRateLimiterConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetRateLimiterConfig' +type EVM2EVMOffRampInterface_SetRateLimiterConfig_Call struct { + *mock.Call +} + +// SetRateLimiterConfig is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - config evm_2_evm_offramp_1_0_0.RateLimiterConfig +func (_e *EVM2EVMOffRampInterface_Expecter) SetRateLimiterConfig(opts interface{}, config interface{}) *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call { + return &EVM2EVMOffRampInterface_SetRateLimiterConfig_Call{Call: _e.mock.On("SetRateLimiterConfig", opts, config)} +} + +func (_c *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call) Run(run func(opts *bind.TransactOpts, config evm_2_evm_offramp_1_0_0.RateLimiterConfig)) *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp_1_0_0.RateLimiterConfig)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp_1_0_0.RateLimiterConfig) (*types.Transaction, error)) *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call { + _c.Call.Return(run) + return _c +} + +// TransferOwnership provides a mock function with given fields: opts, to +func (_m *EVM2EVMOffRampInterface) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, to) + + if len(ret) == 0 { + panic("no return value specified for TransferOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, to) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_TransferOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TransferOwnership' +type EVM2EVMOffRampInterface_TransferOwnership_Call struct { + *mock.Call +} + +// TransferOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - to common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) TransferOwnership(opts interface{}, to interface{}) *EVM2EVMOffRampInterface_TransferOwnership_Call { + return &EVM2EVMOffRampInterface_TransferOwnership_Call{Call: _e.mock.On("TransferOwnership", opts, to)} +} + +func (_c *EVM2EVMOffRampInterface_TransferOwnership_Call) Run(run func(opts *bind.TransactOpts, to common.Address)) *EVM2EVMOffRampInterface_TransferOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_TransferOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_TransferOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_TransferOwnership_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *EVM2EVMOffRampInterface_TransferOwnership_Call { + _c.Call.Return(run) + return _c +} + +// Transmit provides a mock function with given fields: opts, reportContext, report, rs, ss, arg4 +func (_m *EVM2EVMOffRampInterface) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) { + ret := _m.Called(opts, reportContext, report, rs, ss, arg4) + + if len(ret) == 0 { + panic("no return value specified for Transmit") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) (*types.Transaction, error)); ok { + return rf(opts, reportContext, report, rs, ss, arg4) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) *types.Transaction); ok { + r0 = rf(opts, reportContext, report, rs, ss, arg4) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) error); ok { + r1 = rf(opts, reportContext, report, rs, ss, arg4) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_Transmit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Transmit' +type EVM2EVMOffRampInterface_Transmit_Call struct { + *mock.Call +} + +// Transmit is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - reportContext [3][32]byte +// - report []byte +// - rs [][32]byte +// - ss [][32]byte +// - arg4 [32]byte +func (_e *EVM2EVMOffRampInterface_Expecter) Transmit(opts interface{}, reportContext interface{}, report interface{}, rs interface{}, ss interface{}, arg4 interface{}) *EVM2EVMOffRampInterface_Transmit_Call { + return &EVM2EVMOffRampInterface_Transmit_Call{Call: _e.mock.On("Transmit", opts, reportContext, report, rs, ss, arg4)} +} + +func (_c *EVM2EVMOffRampInterface_Transmit_Call) Run(run func(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte)) *EVM2EVMOffRampInterface_Transmit_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([3][32]byte), args[2].([]byte), args[3].([][32]byte), args[4].([][32]byte), args[5].([32]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Transmit_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_Transmit_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Transmit_Call) RunAndReturn(run func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) (*types.Transaction, error)) *EVM2EVMOffRampInterface_Transmit_Call { + _c.Call.Return(run) + return _c +} + +// TypeAndVersion provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) TypeAndVersion(opts *bind.CallOpts) (string, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for TypeAndVersion") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (string, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) string); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_TypeAndVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TypeAndVersion' +type EVM2EVMOffRampInterface_TypeAndVersion_Call struct { + *mock.Call +} + +// TypeAndVersion is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) TypeAndVersion(opts interface{}) *EVM2EVMOffRampInterface_TypeAndVersion_Call { + return &EVM2EVMOffRampInterface_TypeAndVersion_Call{Call: _e.mock.On("TypeAndVersion", opts)} +} + +func (_c *EVM2EVMOffRampInterface_TypeAndVersion_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_TypeAndVersion_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_TypeAndVersion_Call) Return(_a0 string, _a1 error) *EVM2EVMOffRampInterface_TypeAndVersion_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_TypeAndVersion_Call) RunAndReturn(run func(*bind.CallOpts) (string, error)) *EVM2EVMOffRampInterface_TypeAndVersion_Call { + _c.Call.Return(run) + return _c +} + +// WatchAdminSet provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchAdminSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchAdminSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchAdminSet' +type EVM2EVMOffRampInterface_WatchAdminSet_Call struct { + *mock.Call +} + +// WatchAdminSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet +func (_e *EVM2EVMOffRampInterface_Expecter) WatchAdminSet(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchAdminSet_Call { + return &EVM2EVMOffRampInterface_WatchAdminSet_Call{Call: _e.mock.On("WatchAdminSet", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchAdminSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet)) *EVM2EVMOffRampInterface_WatchAdminSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchAdminSet_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchAdminSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchAdminSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampAdminSet) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchAdminSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchConfigSet provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchConfigSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchConfigSet' +type EVM2EVMOffRampInterface_WatchConfigSet_Call struct { + *mock.Call +} + +// WatchConfigSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet +func (_e *EVM2EVMOffRampInterface_Expecter) WatchConfigSet(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchConfigSet_Call { + return &EVM2EVMOffRampInterface_WatchConfigSet_Call{Call: _e.mock.On("WatchConfigSet", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet)) *EVM2EVMOffRampInterface_WatchConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchConfigSet0 provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchConfigSet0") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchConfigSet0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchConfigSet0' +type EVM2EVMOffRampInterface_WatchConfigSet0_Call struct { + *mock.Call +} + +// WatchConfigSet0 is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0 +func (_e *EVM2EVMOffRampInterface_Expecter) WatchConfigSet0(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchConfigSet0_Call { + return &EVM2EVMOffRampInterface_WatchConfigSet0_Call{Call: _e.mock.On("WatchConfigSet0", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet0_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0)) *EVM2EVMOffRampInterface_WatchConfigSet0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet0_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchConfigSet0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet0_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampConfigSet0) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchConfigSet0_Call { + _c.Call.Return(run) + return _c +} + +// WatchExecutionStateChanged provides a mock function with given fields: opts, sink, sequenceNumber, messageId +func (_m *EVM2EVMOffRampInterface) WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) { + ret := _m.Called(opts, sink, sequenceNumber, messageId) + + if len(ret) == 0 { + panic("no return value specified for WatchExecutionStateChanged") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged, []uint64, [][32]byte) (event.Subscription, error)); ok { + return rf(opts, sink, sequenceNumber, messageId) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged, []uint64, [][32]byte) event.Subscription); ok { + r0 = rf(opts, sink, sequenceNumber, messageId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged, []uint64, [][32]byte) error); ok { + r1 = rf(opts, sink, sequenceNumber, messageId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchExecutionStateChanged' +type EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call struct { + *mock.Call +} + +// WatchExecutionStateChanged is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged +// - sequenceNumber []uint64 +// - messageId [][32]byte +func (_e *EVM2EVMOffRampInterface_Expecter) WatchExecutionStateChanged(opts interface{}, sink interface{}, sequenceNumber interface{}, messageId interface{}) *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call { + return &EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call{Call: _e.mock.On("WatchExecutionStateChanged", opts, sink, sequenceNumber, messageId)} +} + +func (_c *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged, sequenceNumber []uint64, messageId [][32]byte)) *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged), args[2].([]uint64), args[3].([][32]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampExecutionStateChanged, []uint64, [][32]byte) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferRequested provides a mock function with given fields: opts, sink, from, to +func (_m *EVM2EVMOffRampInterface) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferRequested") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferRequested' +type EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call struct { + *mock.Call +} + +// WatchOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) WatchOwnershipTransferRequested(opts interface{}, sink interface{}, from interface{}, to interface{}) *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call { + return &EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call{Call: _e.mock.On("WatchOwnershipTransferRequested", opts, sink, from, to)} +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested, from []common.Address, to []common.Address)) *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferred provides a mock function with given fields: opts, sink, from, to +func (_m *EVM2EVMOffRampInterface) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferred") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferred' +type EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call struct { + *mock.Call +} + +// WatchOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) WatchOwnershipTransferred(opts interface{}, sink interface{}, from interface{}, to interface{}) *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call { + return &EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call{Call: _e.mock.On("WatchOwnershipTransferred", opts, sink, from, to)} +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred, from []common.Address, to []common.Address)) *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// WatchPoolAdded provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchPoolAdded(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchPoolAdded") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchPoolAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPoolAdded' +type EVM2EVMOffRampInterface_WatchPoolAdded_Call struct { + *mock.Call +} + +// WatchPoolAdded is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded +func (_e *EVM2EVMOffRampInterface_Expecter) WatchPoolAdded(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchPoolAdded_Call { + return &EVM2EVMOffRampInterface_WatchPoolAdded_Call{Call: _e.mock.On("WatchPoolAdded", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchPoolAdded_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded)) *EVM2EVMOffRampInterface_WatchPoolAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchPoolAdded_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchPoolAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchPoolAdded_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolAdded) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchPoolAdded_Call { + _c.Call.Return(run) + return _c +} + +// WatchPoolRemoved provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchPoolRemoved(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchPoolRemoved") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchPoolRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPoolRemoved' +type EVM2EVMOffRampInterface_WatchPoolRemoved_Call struct { + *mock.Call +} + +// WatchPoolRemoved is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved +func (_e *EVM2EVMOffRampInterface_Expecter) WatchPoolRemoved(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchPoolRemoved_Call { + return &EVM2EVMOffRampInterface_WatchPoolRemoved_Call{Call: _e.mock.On("WatchPoolRemoved", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchPoolRemoved_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved)) *EVM2EVMOffRampInterface_WatchPoolRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchPoolRemoved_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchPoolRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchPoolRemoved_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampPoolRemoved) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchPoolRemoved_Call { + _c.Call.Return(run) + return _c +} + +// WatchSkippedIncorrectNonce provides a mock function with given fields: opts, sink, nonce, sender +func (_m *EVM2EVMOffRampInterface) WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce, nonce []uint64, sender []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, nonce, sender) + + if len(ret) == 0 { + panic("no return value specified for WatchSkippedIncorrectNonce") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce, []uint64, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, nonce, sender) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce, []uint64, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, nonce, sender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce, []uint64, []common.Address) error); ok { + r1 = rf(opts, sink, nonce, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchSkippedIncorrectNonce' +type EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call struct { + *mock.Call +} + +// WatchSkippedIncorrectNonce is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce +// - nonce []uint64 +// - sender []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) WatchSkippedIncorrectNonce(opts interface{}, sink interface{}, nonce interface{}, sender interface{}) *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call { + return &EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call{Call: _e.mock.On("WatchSkippedIncorrectNonce", opts, sink, nonce, sender)} +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce, nonce []uint64, sender []common.Address)) *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce), args[2].([]uint64), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedIncorrectNonce, []uint64, []common.Address) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call { + _c.Call.Return(run) + return _c +} + +// WatchSkippedSenderWithPreviousRampMessageInflight provides a mock function with given fields: opts, sink, nonce, sender +func (_m *EVM2EVMOffRampInterface) WatchSkippedSenderWithPreviousRampMessageInflight(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, nonce []uint64, sender []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, nonce, sender) + + if len(ret) == 0 { + panic("no return value specified for WatchSkippedSenderWithPreviousRampMessageInflight") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, []uint64, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, nonce, sender) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, []uint64, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, nonce, sender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, []uint64, []common.Address) error); ok { + r1 = rf(opts, sink, nonce, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchSkippedSenderWithPreviousRampMessageInflight' +type EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call struct { + *mock.Call +} + +// WatchSkippedSenderWithPreviousRampMessageInflight is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight +// - nonce []uint64 +// - sender []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) WatchSkippedSenderWithPreviousRampMessageInflight(opts interface{}, sink interface{}, nonce interface{}, sender interface{}) *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call { + return &EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call{Call: _e.mock.On("WatchSkippedSenderWithPreviousRampMessageInflight", opts, sink, nonce, sender)} +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, nonce []uint64, sender []common.Address)) *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight), args[2].([]uint64), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, []uint64, []common.Address) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(run) + return _c +} + +// WatchTransmitted provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchTransmitted") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchTransmitted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTransmitted' +type EVM2EVMOffRampInterface_WatchTransmitted_Call struct { + *mock.Call +} + +// WatchTransmitted is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted +func (_e *EVM2EVMOffRampInterface_Expecter) WatchTransmitted(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchTransmitted_Call { + return &EVM2EVMOffRampInterface_WatchTransmitted_Call{Call: _e.mock.On("WatchTransmitted", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchTransmitted_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted)) *EVM2EVMOffRampInterface_WatchTransmitted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchTransmitted_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchTransmitted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchTransmitted_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_0_0.EVM2EVMOffRampTransmitted) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchTransmitted_Call { + _c.Call.Return(run) + return _c +} + +// NewEVM2EVMOffRampInterface creates a new instance of EVM2EVMOffRampInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewEVM2EVMOffRampInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *EVM2EVMOffRampInterface { + mock := &EVM2EVMOffRampInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/ccip/mocks/v1_2_0/evm2_evm_off_ramp_interface.go b/core/gethwrappers/ccip/mocks/v1_2_0/evm2_evm_off_ramp_interface.go new file mode 100644 index 0000000000..840c6e6c5e --- /dev/null +++ b/core/gethwrappers/ccip/mocks/v1_2_0/evm2_evm_off_ramp_interface.go @@ -0,0 +1,3603 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_contracts + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + evm_2_evm_offramp_1_2_0 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// EVM2EVMOffRampInterface is an autogenerated mock type for the EVM2EVMOffRampInterface type +type EVM2EVMOffRampInterface struct { + mock.Mock +} + +type EVM2EVMOffRampInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *EVM2EVMOffRampInterface) EXPECT() *EVM2EVMOffRampInterface_Expecter { + return &EVM2EVMOffRampInterface_Expecter{mock: &_m.Mock} +} + +// AcceptOwnership provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for AcceptOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_AcceptOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AcceptOwnership' +type EVM2EVMOffRampInterface_AcceptOwnership_Call struct { + *mock.Call +} + +// AcceptOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *EVM2EVMOffRampInterface_Expecter) AcceptOwnership(opts interface{}) *EVM2EVMOffRampInterface_AcceptOwnership_Call { + return &EVM2EVMOffRampInterface_AcceptOwnership_Call{Call: _e.mock.On("AcceptOwnership", opts)} +} + +func (_c *EVM2EVMOffRampInterface_AcceptOwnership_Call) Run(run func(opts *bind.TransactOpts)) *EVM2EVMOffRampInterface_AcceptOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_AcceptOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_AcceptOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_AcceptOwnership_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *EVM2EVMOffRampInterface_AcceptOwnership_Call { + _c.Call.Return(run) + return _c +} + +// Address provides a mock function with given fields: +func (_m *EVM2EVMOffRampInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// EVM2EVMOffRampInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type EVM2EVMOffRampInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *EVM2EVMOffRampInterface_Expecter) Address() *EVM2EVMOffRampInterface_Address_Call { + return &EVM2EVMOffRampInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *EVM2EVMOffRampInterface_Address_Call) Run(run func()) *EVM2EVMOffRampInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Address_Call) Return(_a0 common.Address) *EVM2EVMOffRampInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Address_Call) RunAndReturn(run func() common.Address) *EVM2EVMOffRampInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// ApplyPoolUpdates provides a mock function with given fields: opts, removes, adds +func (_m *EVM2EVMOffRampInterface) ApplyPoolUpdates(opts *bind.TransactOpts, removes []evm_2_evm_offramp_1_2_0.InternalPoolUpdate, adds []evm_2_evm_offramp_1_2_0.InternalPoolUpdate) (*types.Transaction, error) { + ret := _m.Called(opts, removes, adds) + + if len(ret) == 0 { + panic("no return value specified for ApplyPoolUpdates") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []evm_2_evm_offramp_1_2_0.InternalPoolUpdate, []evm_2_evm_offramp_1_2_0.InternalPoolUpdate) (*types.Transaction, error)); ok { + return rf(opts, removes, adds) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []evm_2_evm_offramp_1_2_0.InternalPoolUpdate, []evm_2_evm_offramp_1_2_0.InternalPoolUpdate) *types.Transaction); ok { + r0 = rf(opts, removes, adds) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []evm_2_evm_offramp_1_2_0.InternalPoolUpdate, []evm_2_evm_offramp_1_2_0.InternalPoolUpdate) error); ok { + r1 = rf(opts, removes, adds) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ApplyPoolUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyPoolUpdates' +type EVM2EVMOffRampInterface_ApplyPoolUpdates_Call struct { + *mock.Call +} + +// ApplyPoolUpdates is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - removes []evm_2_evm_offramp_1_2_0.InternalPoolUpdate +// - adds []evm_2_evm_offramp_1_2_0.InternalPoolUpdate +func (_e *EVM2EVMOffRampInterface_Expecter) ApplyPoolUpdates(opts interface{}, removes interface{}, adds interface{}) *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call { + return &EVM2EVMOffRampInterface_ApplyPoolUpdates_Call{Call: _e.mock.On("ApplyPoolUpdates", opts, removes, adds)} +} + +func (_c *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call) Run(run func(opts *bind.TransactOpts, removes []evm_2_evm_offramp_1_2_0.InternalPoolUpdate, adds []evm_2_evm_offramp_1_2_0.InternalPoolUpdate)) *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]evm_2_evm_offramp_1_2_0.InternalPoolUpdate), args[2].([]evm_2_evm_offramp_1_2_0.InternalPoolUpdate)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []evm_2_evm_offramp_1_2_0.InternalPoolUpdate, []evm_2_evm_offramp_1_2_0.InternalPoolUpdate) (*types.Transaction, error)) *EVM2EVMOffRampInterface_ApplyPoolUpdates_Call { + _c.Call.Return(run) + return _c +} + +// CcipReceive provides a mock function with given fields: opts, arg0 +func (_m *EVM2EVMOffRampInterface) CcipReceive(opts *bind.CallOpts, arg0 evm_2_evm_offramp_1_2_0.ClientAny2EVMMessage) error { + ret := _m.Called(opts, arg0) + + if len(ret) == 0 { + panic("no return value specified for CcipReceive") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, evm_2_evm_offramp_1_2_0.ClientAny2EVMMessage) error); ok { + r0 = rf(opts, arg0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// EVM2EVMOffRampInterface_CcipReceive_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CcipReceive' +type EVM2EVMOffRampInterface_CcipReceive_Call struct { + *mock.Call +} + +// CcipReceive is a helper method to define mock.On call +// - opts *bind.CallOpts +// - arg0 evm_2_evm_offramp_1_2_0.ClientAny2EVMMessage +func (_e *EVM2EVMOffRampInterface_Expecter) CcipReceive(opts interface{}, arg0 interface{}) *EVM2EVMOffRampInterface_CcipReceive_Call { + return &EVM2EVMOffRampInterface_CcipReceive_Call{Call: _e.mock.On("CcipReceive", opts, arg0)} +} + +func (_c *EVM2EVMOffRampInterface_CcipReceive_Call) Run(run func(opts *bind.CallOpts, arg0 evm_2_evm_offramp_1_2_0.ClientAny2EVMMessage)) *EVM2EVMOffRampInterface_CcipReceive_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(evm_2_evm_offramp_1_2_0.ClientAny2EVMMessage)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_CcipReceive_Call) Return(_a0 error) *EVM2EVMOffRampInterface_CcipReceive_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *EVM2EVMOffRampInterface_CcipReceive_Call) RunAndReturn(run func(*bind.CallOpts, evm_2_evm_offramp_1_2_0.ClientAny2EVMMessage) error) *EVM2EVMOffRampInterface_CcipReceive_Call { + _c.Call.Return(run) + return _c +} + +// CurrentRateLimiterState provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) CurrentRateLimiterState(opts *bind.CallOpts) (evm_2_evm_offramp_1_2_0.RateLimiterTokenBucket, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for CurrentRateLimiterState") + } + + var r0 evm_2_evm_offramp_1_2_0.RateLimiterTokenBucket + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp_1_2_0.RateLimiterTokenBucket, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp_1_2_0.RateLimiterTokenBucket); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp_1_2_0.RateLimiterTokenBucket) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_CurrentRateLimiterState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CurrentRateLimiterState' +type EVM2EVMOffRampInterface_CurrentRateLimiterState_Call struct { + *mock.Call +} + +// CurrentRateLimiterState is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) CurrentRateLimiterState(opts interface{}) *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call { + return &EVM2EVMOffRampInterface_CurrentRateLimiterState_Call{Call: _e.mock.On("CurrentRateLimiterState", opts)} +} + +func (_c *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call) Return(_a0 evm_2_evm_offramp_1_2_0.RateLimiterTokenBucket, _a1 error) *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp_1_2_0.RateLimiterTokenBucket, error)) *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call { + _c.Call.Return(run) + return _c +} + +// ExecuteSingleMessage provides a mock function with given fields: opts, message, offchainTokenData +func (_m *EVM2EVMOffRampInterface) ExecuteSingleMessage(opts *bind.TransactOpts, message evm_2_evm_offramp_1_2_0.InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + ret := _m.Called(opts, message, offchainTokenData) + + if len(ret) == 0 { + panic("no return value specified for ExecuteSingleMessage") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp_1_2_0.InternalEVM2EVMMessage, [][]byte) (*types.Transaction, error)); ok { + return rf(opts, message, offchainTokenData) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp_1_2_0.InternalEVM2EVMMessage, [][]byte) *types.Transaction); ok { + r0 = rf(opts, message, offchainTokenData) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp_1_2_0.InternalEVM2EVMMessage, [][]byte) error); ok { + r1 = rf(opts, message, offchainTokenData) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ExecuteSingleMessage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExecuteSingleMessage' +type EVM2EVMOffRampInterface_ExecuteSingleMessage_Call struct { + *mock.Call +} + +// ExecuteSingleMessage is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - message evm_2_evm_offramp_1_2_0.InternalEVM2EVMMessage +// - offchainTokenData [][]byte +func (_e *EVM2EVMOffRampInterface_Expecter) ExecuteSingleMessage(opts interface{}, message interface{}, offchainTokenData interface{}) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + return &EVM2EVMOffRampInterface_ExecuteSingleMessage_Call{Call: _e.mock.On("ExecuteSingleMessage", opts, message, offchainTokenData)} +} + +func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) Run(run func(opts *bind.TransactOpts, message evm_2_evm_offramp_1_2_0.InternalEVM2EVMMessage, offchainTokenData [][]byte)) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp_1_2_0.InternalEVM2EVMMessage), args[2].([][]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp_1_2_0.InternalEVM2EVMMessage, [][]byte) (*types.Transaction, error)) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + _c.Call.Return(run) + return _c +} + +// FilterAdminSet provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterAdminSet(opts *bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterAdminSet") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterAdminSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterAdminSet' +type EVM2EVMOffRampInterface_FilterAdminSet_Call struct { + *mock.Call +} + +// FilterAdminSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterAdminSet(opts interface{}) *EVM2EVMOffRampInterface_FilterAdminSet_Call { + return &EVM2EVMOffRampInterface_FilterAdminSet_Call{Call: _e.mock.On("FilterAdminSet", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterAdminSet_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterAdminSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterAdminSet_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSetIterator, _a1 error) *EVM2EVMOffRampInterface_FilterAdminSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterAdminSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSetIterator, error)) *EVM2EVMOffRampInterface_FilterAdminSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfigSet provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterConfigSet(opts *bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSetIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterConfigSet") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSetIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSetIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfigSet' +type EVM2EVMOffRampInterface_FilterConfigSet_Call struct { + *mock.Call +} + +// FilterConfigSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterConfigSet(opts interface{}) *EVM2EVMOffRampInterface_FilterConfigSet_Call { + return &EVM2EVMOffRampInterface_FilterConfigSet_Call{Call: _e.mock.On("FilterConfigSet", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSetIterator, _a1 error) *EVM2EVMOffRampInterface_FilterConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSetIterator, error)) *EVM2EVMOffRampInterface_FilterConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfigSet0 provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterConfigSet0(opts *bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0Iterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterConfigSet0") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0Iterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0Iterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0Iterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0Iterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterConfigSet0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfigSet0' +type EVM2EVMOffRampInterface_FilterConfigSet0_Call struct { + *mock.Call +} + +// FilterConfigSet0 is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterConfigSet0(opts interface{}) *EVM2EVMOffRampInterface_FilterConfigSet0_Call { + return &EVM2EVMOffRampInterface_FilterConfigSet0_Call{Call: _e.mock.On("FilterConfigSet0", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet0_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterConfigSet0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet0_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0Iterator, _a1 error) *EVM2EVMOffRampInterface_FilterConfigSet0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterConfigSet0_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0Iterator, error)) *EVM2EVMOffRampInterface_FilterConfigSet0_Call { + _c.Call.Return(run) + return _c +} + +// FilterExecutionStateChanged provides a mock function with given fields: opts, sequenceNumber, messageId +func (_m *EVM2EVMOffRampInterface) FilterExecutionStateChanged(opts *bind.FilterOpts, sequenceNumber []uint64, messageId [][32]byte) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChangedIterator, error) { + ret := _m.Called(opts, sequenceNumber, messageId) + + if len(ret) == 0 { + panic("no return value specified for FilterExecutionStateChanged") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChangedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, [][32]byte) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChangedIterator, error)); ok { + return rf(opts, sequenceNumber, messageId) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, [][32]byte) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChangedIterator); ok { + r0 = rf(opts, sequenceNumber, messageId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChangedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, [][32]byte) error); ok { + r1 = rf(opts, sequenceNumber, messageId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterExecutionStateChanged' +type EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call struct { + *mock.Call +} + +// FilterExecutionStateChanged is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - sequenceNumber []uint64 +// - messageId [][32]byte +func (_e *EVM2EVMOffRampInterface_Expecter) FilterExecutionStateChanged(opts interface{}, sequenceNumber interface{}, messageId interface{}) *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call { + return &EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call{Call: _e.mock.On("FilterExecutionStateChanged", opts, sequenceNumber, messageId)} +} + +func (_c *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call) Run(run func(opts *bind.FilterOpts, sequenceNumber []uint64, messageId [][32]byte)) *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([][32]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChangedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, [][32]byte) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChangedIterator, error)) *EVM2EVMOffRampInterface_FilterExecutionStateChanged_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferRequested provides a mock function with given fields: opts, from, to +func (_m *EVM2EVMOffRampInterface) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequestedIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferRequested") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequestedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequestedIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequestedIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequestedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferRequested' +type EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call struct { + *mock.Call +} + +// FilterOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) FilterOwnershipTransferRequested(opts interface{}, from interface{}, to interface{}) *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call { + return &EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call{Call: _e.mock.On("FilterOwnershipTransferRequested", opts, from, to)} +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequestedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequestedIterator, error)) *EVM2EVMOffRampInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferred provides a mock function with given fields: opts, from, to +func (_m *EVM2EVMOffRampInterface) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferredIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferred") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferredIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferredIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferredIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferredIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferred' +type EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call struct { + *mock.Call +} + +// FilterOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) FilterOwnershipTransferred(opts interface{}, from interface{}, to interface{}) *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call { + return &EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call{Call: _e.mock.On("FilterOwnershipTransferred", opts, from, to)} +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferredIterator, _a1 error) *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferredIterator, error)) *EVM2EVMOffRampInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// FilterPoolAdded provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterPoolAdded(opts *bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAddedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterPoolAdded") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAddedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAddedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAddedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAddedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterPoolAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPoolAdded' +type EVM2EVMOffRampInterface_FilterPoolAdded_Call struct { + *mock.Call +} + +// FilterPoolAdded is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterPoolAdded(opts interface{}) *EVM2EVMOffRampInterface_FilterPoolAdded_Call { + return &EVM2EVMOffRampInterface_FilterPoolAdded_Call{Call: _e.mock.On("FilterPoolAdded", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterPoolAdded_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterPoolAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterPoolAdded_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAddedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterPoolAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterPoolAdded_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAddedIterator, error)) *EVM2EVMOffRampInterface_FilterPoolAdded_Call { + _c.Call.Return(run) + return _c +} + +// FilterPoolRemoved provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterPoolRemoved(opts *bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemovedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterPoolRemoved") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemovedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemovedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemovedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemovedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterPoolRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPoolRemoved' +type EVM2EVMOffRampInterface_FilterPoolRemoved_Call struct { + *mock.Call +} + +// FilterPoolRemoved is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterPoolRemoved(opts interface{}) *EVM2EVMOffRampInterface_FilterPoolRemoved_Call { + return &EVM2EVMOffRampInterface_FilterPoolRemoved_Call{Call: _e.mock.On("FilterPoolRemoved", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterPoolRemoved_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterPoolRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterPoolRemoved_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemovedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterPoolRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterPoolRemoved_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemovedIterator, error)) *EVM2EVMOffRampInterface_FilterPoolRemoved_Call { + _c.Call.Return(run) + return _c +} + +// FilterSkippedIncorrectNonce provides a mock function with given fields: opts, nonce, sender +func (_m *EVM2EVMOffRampInterface) FilterSkippedIncorrectNonce(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonceIterator, error) { + ret := _m.Called(opts, nonce, sender) + + if len(ret) == 0 { + panic("no return value specified for FilterSkippedIncorrectNonce") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonceIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonceIterator, error)); ok { + return rf(opts, nonce, sender) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonceIterator); ok { + r0 = rf(opts, nonce, sender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonceIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, []common.Address) error); ok { + r1 = rf(opts, nonce, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterSkippedIncorrectNonce' +type EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call struct { + *mock.Call +} + +// FilterSkippedIncorrectNonce is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - nonce []uint64 +// - sender []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) FilterSkippedIncorrectNonce(opts interface{}, nonce interface{}, sender interface{}) *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call { + return &EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call{Call: _e.mock.On("FilterSkippedIncorrectNonce", opts, nonce, sender)} +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call) Run(run func(opts *bind.FilterOpts, nonce []uint64, sender []common.Address)) *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonceIterator, _a1 error) *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, []common.Address) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonceIterator, error)) *EVM2EVMOffRampInterface_FilterSkippedIncorrectNonce_Call { + _c.Call.Return(run) + return _c +} + +// FilterSkippedSenderWithPreviousRampMessageInflight provides a mock function with given fields: opts, nonce, sender +func (_m *EVM2EVMOffRampInterface) FilterSkippedSenderWithPreviousRampMessageInflight(opts *bind.FilterOpts, nonce []uint64, sender []common.Address) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error) { + ret := _m.Called(opts, nonce, sender) + + if len(ret) == 0 { + panic("no return value specified for FilterSkippedSenderWithPreviousRampMessageInflight") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error)); ok { + return rf(opts, nonce, sender) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator); ok { + r0 = rf(opts, nonce, sender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, []common.Address) error); ok { + r1 = rf(opts, nonce, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterSkippedSenderWithPreviousRampMessageInflight' +type EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call struct { + *mock.Call +} + +// FilterSkippedSenderWithPreviousRampMessageInflight is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - nonce []uint64 +// - sender []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) FilterSkippedSenderWithPreviousRampMessageInflight(opts interface{}, nonce interface{}, sender interface{}) *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call { + return &EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call{Call: _e.mock.On("FilterSkippedSenderWithPreviousRampMessageInflight", opts, nonce, sender)} +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call) Run(run func(opts *bind.FilterOpts, nonce []uint64, sender []common.Address)) *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, _a1 error) *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, []common.Address) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflightIterator, error)) *EVM2EVMOffRampInterface_FilterSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(run) + return _c +} + +// FilterTransmitted provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterTransmitted(opts *bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmittedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterTransmitted") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmittedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmittedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmittedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmittedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterTransmitted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTransmitted' +type EVM2EVMOffRampInterface_FilterTransmitted_Call struct { + *mock.Call +} + +// FilterTransmitted is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterTransmitted(opts interface{}) *EVM2EVMOffRampInterface_FilterTransmitted_Call { + return &EVM2EVMOffRampInterface_FilterTransmitted_Call{Call: _e.mock.On("FilterTransmitted", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterTransmitted_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterTransmitted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterTransmitted_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmittedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterTransmitted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterTransmitted_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmittedIterator, error)) *EVM2EVMOffRampInterface_FilterTransmitted_Call { + _c.Call.Return(run) + return _c +} + +// GetDestinationToken provides a mock function with given fields: opts, sourceToken +func (_m *EVM2EVMOffRampInterface) GetDestinationToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) { + ret := _m.Called(opts, sourceToken) + + if len(ret) == 0 { + panic("no return value specified for GetDestinationToken") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (common.Address, error)); ok { + return rf(opts, sourceToken) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) common.Address); ok { + r0 = rf(opts, sourceToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, sourceToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetDestinationToken_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDestinationToken' +type EVM2EVMOffRampInterface_GetDestinationToken_Call struct { + *mock.Call +} + +// GetDestinationToken is a helper method to define mock.On call +// - opts *bind.CallOpts +// - sourceToken common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) GetDestinationToken(opts interface{}, sourceToken interface{}) *EVM2EVMOffRampInterface_GetDestinationToken_Call { + return &EVM2EVMOffRampInterface_GetDestinationToken_Call{Call: _e.mock.On("GetDestinationToken", opts, sourceToken)} +} + +func (_c *EVM2EVMOffRampInterface_GetDestinationToken_Call) Run(run func(opts *bind.CallOpts, sourceToken common.Address)) *EVM2EVMOffRampInterface_GetDestinationToken_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDestinationToken_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOffRampInterface_GetDestinationToken_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDestinationToken_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (common.Address, error)) *EVM2EVMOffRampInterface_GetDestinationToken_Call { + _c.Call.Return(run) + return _c +} + +// GetDestinationTokens provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetDestinationTokens(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetDestinationTokens") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetDestinationTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDestinationTokens' +type EVM2EVMOffRampInterface_GetDestinationTokens_Call struct { + *mock.Call +} + +// GetDestinationTokens is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetDestinationTokens(opts interface{}) *EVM2EVMOffRampInterface_GetDestinationTokens_Call { + return &EVM2EVMOffRampInterface_GetDestinationTokens_Call{Call: _e.mock.On("GetDestinationTokens", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetDestinationTokens_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetDestinationTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDestinationTokens_Call) Return(_a0 []common.Address, _a1 error) *EVM2EVMOffRampInterface_GetDestinationTokens_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDestinationTokens_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *EVM2EVMOffRampInterface_GetDestinationTokens_Call { + _c.Call.Return(run) + return _c +} + +// GetDynamicConfig provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetDynamicConfig(opts *bind.CallOpts) (evm_2_evm_offramp_1_2_0.EVM2EVMOffRampDynamicConfig, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetDynamicConfig") + } + + var r0 evm_2_evm_offramp_1_2_0.EVM2EVMOffRampDynamicConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp_1_2_0.EVM2EVMOffRampDynamicConfig, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp_1_2_0.EVM2EVMOffRampDynamicConfig); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp_1_2_0.EVM2EVMOffRampDynamicConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetDynamicConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDynamicConfig' +type EVM2EVMOffRampInterface_GetDynamicConfig_Call struct { + *mock.Call +} + +// GetDynamicConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetDynamicConfig(opts interface{}) *EVM2EVMOffRampInterface_GetDynamicConfig_Call { + return &EVM2EVMOffRampInterface_GetDynamicConfig_Call{Call: _e.mock.On("GetDynamicConfig", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetDynamicConfig_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetDynamicConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDynamicConfig_Call) Return(_a0 evm_2_evm_offramp_1_2_0.EVM2EVMOffRampDynamicConfig, _a1 error) *EVM2EVMOffRampInterface_GetDynamicConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetDynamicConfig_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp_1_2_0.EVM2EVMOffRampDynamicConfig, error)) *EVM2EVMOffRampInterface_GetDynamicConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetExecutionState provides a mock function with given fields: opts, sequenceNumber +func (_m *EVM2EVMOffRampInterface) GetExecutionState(opts *bind.CallOpts, sequenceNumber uint64) (uint8, error) { + ret := _m.Called(opts, sequenceNumber) + + if len(ret) == 0 { + panic("no return value specified for GetExecutionState") + } + + var r0 uint8 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (uint8, error)); ok { + return rf(opts, sequenceNumber) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) uint8); ok { + r0 = rf(opts, sequenceNumber) + } else { + r0 = ret.Get(0).(uint8) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, sequenceNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetExecutionState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExecutionState' +type EVM2EVMOffRampInterface_GetExecutionState_Call struct { + *mock.Call +} + +// GetExecutionState is a helper method to define mock.On call +// - opts *bind.CallOpts +// - sequenceNumber uint64 +func (_e *EVM2EVMOffRampInterface_Expecter) GetExecutionState(opts interface{}, sequenceNumber interface{}) *EVM2EVMOffRampInterface_GetExecutionState_Call { + return &EVM2EVMOffRampInterface_GetExecutionState_Call{Call: _e.mock.On("GetExecutionState", opts, sequenceNumber)} +} + +func (_c *EVM2EVMOffRampInterface_GetExecutionState_Call) Run(run func(opts *bind.CallOpts, sequenceNumber uint64)) *EVM2EVMOffRampInterface_GetExecutionState_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetExecutionState_Call) Return(_a0 uint8, _a1 error) *EVM2EVMOffRampInterface_GetExecutionState_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetExecutionState_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (uint8, error)) *EVM2EVMOffRampInterface_GetExecutionState_Call { + _c.Call.Return(run) + return _c +} + +// GetPoolByDestToken provides a mock function with given fields: opts, destToken +func (_m *EVM2EVMOffRampInterface) GetPoolByDestToken(opts *bind.CallOpts, destToken common.Address) (common.Address, error) { + ret := _m.Called(opts, destToken) + + if len(ret) == 0 { + panic("no return value specified for GetPoolByDestToken") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (common.Address, error)); ok { + return rf(opts, destToken) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) common.Address); ok { + r0 = rf(opts, destToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, destToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetPoolByDestToken_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPoolByDestToken' +type EVM2EVMOffRampInterface_GetPoolByDestToken_Call struct { + *mock.Call +} + +// GetPoolByDestToken is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destToken common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) GetPoolByDestToken(opts interface{}, destToken interface{}) *EVM2EVMOffRampInterface_GetPoolByDestToken_Call { + return &EVM2EVMOffRampInterface_GetPoolByDestToken_Call{Call: _e.mock.On("GetPoolByDestToken", opts, destToken)} +} + +func (_c *EVM2EVMOffRampInterface_GetPoolByDestToken_Call) Run(run func(opts *bind.CallOpts, destToken common.Address)) *EVM2EVMOffRampInterface_GetPoolByDestToken_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetPoolByDestToken_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOffRampInterface_GetPoolByDestToken_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetPoolByDestToken_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (common.Address, error)) *EVM2EVMOffRampInterface_GetPoolByDestToken_Call { + _c.Call.Return(run) + return _c +} + +// GetPoolBySourceToken provides a mock function with given fields: opts, sourceToken +func (_m *EVM2EVMOffRampInterface) GetPoolBySourceToken(opts *bind.CallOpts, sourceToken common.Address) (common.Address, error) { + ret := _m.Called(opts, sourceToken) + + if len(ret) == 0 { + panic("no return value specified for GetPoolBySourceToken") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (common.Address, error)); ok { + return rf(opts, sourceToken) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) common.Address); ok { + r0 = rf(opts, sourceToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, sourceToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetPoolBySourceToken_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPoolBySourceToken' +type EVM2EVMOffRampInterface_GetPoolBySourceToken_Call struct { + *mock.Call +} + +// GetPoolBySourceToken is a helper method to define mock.On call +// - opts *bind.CallOpts +// - sourceToken common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) GetPoolBySourceToken(opts interface{}, sourceToken interface{}) *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call { + return &EVM2EVMOffRampInterface_GetPoolBySourceToken_Call{Call: _e.mock.On("GetPoolBySourceToken", opts, sourceToken)} +} + +func (_c *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call) Run(run func(opts *bind.CallOpts, sourceToken common.Address)) *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (common.Address, error)) *EVM2EVMOffRampInterface_GetPoolBySourceToken_Call { + _c.Call.Return(run) + return _c +} + +// GetSenderNonce provides a mock function with given fields: opts, sender +func (_m *EVM2EVMOffRampInterface) GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) { + ret := _m.Called(opts, sender) + + if len(ret) == 0 { + panic("no return value specified for GetSenderNonce") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (uint64, error)); ok { + return rf(opts, sender) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) uint64); ok { + r0 = rf(opts, sender) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetSenderNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSenderNonce' +type EVM2EVMOffRampInterface_GetSenderNonce_Call struct { + *mock.Call +} + +// GetSenderNonce is a helper method to define mock.On call +// - opts *bind.CallOpts +// - sender common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) GetSenderNonce(opts interface{}, sender interface{}) *EVM2EVMOffRampInterface_GetSenderNonce_Call { + return &EVM2EVMOffRampInterface_GetSenderNonce_Call{Call: _e.mock.On("GetSenderNonce", opts, sender)} +} + +func (_c *EVM2EVMOffRampInterface_GetSenderNonce_Call) Run(run func(opts *bind.CallOpts, sender common.Address)) *EVM2EVMOffRampInterface_GetSenderNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetSenderNonce_Call) Return(_a0 uint64, _a1 error) *EVM2EVMOffRampInterface_GetSenderNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetSenderNonce_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (uint64, error)) *EVM2EVMOffRampInterface_GetSenderNonce_Call { + _c.Call.Return(run) + return _c +} + +// GetStaticConfig provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetStaticConfig(opts *bind.CallOpts) (evm_2_evm_offramp_1_2_0.EVM2EVMOffRampStaticConfig, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetStaticConfig") + } + + var r0 evm_2_evm_offramp_1_2_0.EVM2EVMOffRampStaticConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp_1_2_0.EVM2EVMOffRampStaticConfig, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp_1_2_0.EVM2EVMOffRampStaticConfig); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp_1_2_0.EVM2EVMOffRampStaticConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetStaticConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStaticConfig' +type EVM2EVMOffRampInterface_GetStaticConfig_Call struct { + *mock.Call +} + +// GetStaticConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetStaticConfig(opts interface{}) *EVM2EVMOffRampInterface_GetStaticConfig_Call { + return &EVM2EVMOffRampInterface_GetStaticConfig_Call{Call: _e.mock.On("GetStaticConfig", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetStaticConfig_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetStaticConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetStaticConfig_Call) Return(_a0 evm_2_evm_offramp_1_2_0.EVM2EVMOffRampStaticConfig, _a1 error) *EVM2EVMOffRampInterface_GetStaticConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetStaticConfig_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp_1_2_0.EVM2EVMOffRampStaticConfig, error)) *EVM2EVMOffRampInterface_GetStaticConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetSupportedTokens provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetSupportedTokens(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetSupportedTokens") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetSupportedTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSupportedTokens' +type EVM2EVMOffRampInterface_GetSupportedTokens_Call struct { + *mock.Call +} + +// GetSupportedTokens is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetSupportedTokens(opts interface{}) *EVM2EVMOffRampInterface_GetSupportedTokens_Call { + return &EVM2EVMOffRampInterface_GetSupportedTokens_Call{Call: _e.mock.On("GetSupportedTokens", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetSupportedTokens_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetSupportedTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetSupportedTokens_Call) Return(_a0 []common.Address, _a1 error) *EVM2EVMOffRampInterface_GetSupportedTokens_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetSupportedTokens_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *EVM2EVMOffRampInterface_GetSupportedTokens_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenLimitAdmin provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetTokenLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetTokenLimitAdmin") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenLimitAdmin' +type EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call struct { + *mock.Call +} + +// GetTokenLimitAdmin is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetTokenLimitAdmin(opts interface{}) *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call { + return &EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call{Call: _e.mock.On("GetTokenLimitAdmin", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *EVM2EVMOffRampInterface_GetTokenLimitAdmin_Call { + _c.Call.Return(run) + return _c +} + +// GetTransmitters provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetTransmitters") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_GetTransmitters_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTransmitters' +type EVM2EVMOffRampInterface_GetTransmitters_Call struct { + *mock.Call +} + +// GetTransmitters is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) GetTransmitters(opts interface{}) *EVM2EVMOffRampInterface_GetTransmitters_Call { + return &EVM2EVMOffRampInterface_GetTransmitters_Call{Call: _e.mock.On("GetTransmitters", opts)} +} + +func (_c *EVM2EVMOffRampInterface_GetTransmitters_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_GetTransmitters_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetTransmitters_Call) Return(_a0 []common.Address, _a1 error) *EVM2EVMOffRampInterface_GetTransmitters_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_GetTransmitters_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *EVM2EVMOffRampInterface_GetTransmitters_Call { + _c.Call.Return(run) + return _c +} + +// LatestConfigDetails provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) LatestConfigDetails(opts *bind.CallOpts) (evm_2_evm_offramp_1_2_0.LatestConfigDetails, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LatestConfigDetails") + } + + var r0 evm_2_evm_offramp_1_2_0.LatestConfigDetails + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp_1_2_0.LatestConfigDetails, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp_1_2_0.LatestConfigDetails); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp_1_2_0.LatestConfigDetails) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_LatestConfigDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestConfigDetails' +type EVM2EVMOffRampInterface_LatestConfigDetails_Call struct { + *mock.Call +} + +// LatestConfigDetails is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) LatestConfigDetails(opts interface{}) *EVM2EVMOffRampInterface_LatestConfigDetails_Call { + return &EVM2EVMOffRampInterface_LatestConfigDetails_Call{Call: _e.mock.On("LatestConfigDetails", opts)} +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDetails_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_LatestConfigDetails_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDetails_Call) Return(_a0 evm_2_evm_offramp_1_2_0.LatestConfigDetails, _a1 error) *EVM2EVMOffRampInterface_LatestConfigDetails_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDetails_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp_1_2_0.LatestConfigDetails, error)) *EVM2EVMOffRampInterface_LatestConfigDetails_Call { + _c.Call.Return(run) + return _c +} + +// LatestConfigDigestAndEpoch provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (evm_2_evm_offramp_1_2_0.LatestConfigDigestAndEpoch, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LatestConfigDigestAndEpoch") + } + + var r0 evm_2_evm_offramp_1_2_0.LatestConfigDigestAndEpoch + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (evm_2_evm_offramp_1_2_0.LatestConfigDigestAndEpoch, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) evm_2_evm_offramp_1_2_0.LatestConfigDigestAndEpoch); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(evm_2_evm_offramp_1_2_0.LatestConfigDigestAndEpoch) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestConfigDigestAndEpoch' +type EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call struct { + *mock.Call +} + +// LatestConfigDigestAndEpoch is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) LatestConfigDigestAndEpoch(opts interface{}) *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call { + return &EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call{Call: _e.mock.On("LatestConfigDigestAndEpoch", opts)} +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call) Return(_a0 evm_2_evm_offramp_1_2_0.LatestConfigDigestAndEpoch, _a1 error) *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call) RunAndReturn(run func(*bind.CallOpts) (evm_2_evm_offramp_1_2_0.LatestConfigDigestAndEpoch, error)) *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call { + _c.Call.Return(run) + return _c +} + +// ManuallyExecute provides a mock function with given fields: opts, report, gasLimitOverrides +func (_m *EVM2EVMOffRampInterface) ManuallyExecute(opts *bind.TransactOpts, report evm_2_evm_offramp_1_2_0.InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { + ret := _m.Called(opts, report, gasLimitOverrides) + + if len(ret) == 0 { + panic("no return value specified for ManuallyExecute") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp_1_2_0.InternalExecutionReport, []*big.Int) (*types.Transaction, error)); ok { + return rf(opts, report, gasLimitOverrides) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp_1_2_0.InternalExecutionReport, []*big.Int) *types.Transaction); ok { + r0 = rf(opts, report, gasLimitOverrides) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp_1_2_0.InternalExecutionReport, []*big.Int) error); ok { + r1 = rf(opts, report, gasLimitOverrides) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ManuallyExecute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ManuallyExecute' +type EVM2EVMOffRampInterface_ManuallyExecute_Call struct { + *mock.Call +} + +// ManuallyExecute is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - report evm_2_evm_offramp_1_2_0.InternalExecutionReport +// - gasLimitOverrides []*big.Int +func (_e *EVM2EVMOffRampInterface_Expecter) ManuallyExecute(opts interface{}, report interface{}, gasLimitOverrides interface{}) *EVM2EVMOffRampInterface_ManuallyExecute_Call { + return &EVM2EVMOffRampInterface_ManuallyExecute_Call{Call: _e.mock.On("ManuallyExecute", opts, report, gasLimitOverrides)} +} + +func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) Run(run func(opts *bind.TransactOpts, report evm_2_evm_offramp_1_2_0.InternalExecutionReport, gasLimitOverrides []*big.Int)) *EVM2EVMOffRampInterface_ManuallyExecute_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp_1_2_0.InternalExecutionReport), args[2].([]*big.Int)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_ManuallyExecute_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp_1_2_0.InternalExecutionReport, []*big.Int) (*types.Transaction, error)) *EVM2EVMOffRampInterface_ManuallyExecute_Call { + _c.Call.Return(run) + return _c +} + +// Owner provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) Owner(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Owner") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_Owner_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Owner' +type EVM2EVMOffRampInterface_Owner_Call struct { + *mock.Call +} + +// Owner is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) Owner(opts interface{}) *EVM2EVMOffRampInterface_Owner_Call { + return &EVM2EVMOffRampInterface_Owner_Call{Call: _e.mock.On("Owner", opts)} +} + +func (_c *EVM2EVMOffRampInterface_Owner_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_Owner_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Owner_Call) Return(_a0 common.Address, _a1 error) *EVM2EVMOffRampInterface_Owner_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Owner_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *EVM2EVMOffRampInterface_Owner_Call { + _c.Call.Return(run) + return _c +} + +// ParseAdminSet provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseAdminSet(log types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseAdminSet") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseAdminSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseAdminSet' +type EVM2EVMOffRampInterface_ParseAdminSet_Call struct { + *mock.Call +} + +// ParseAdminSet is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseAdminSet(log interface{}) *EVM2EVMOffRampInterface_ParseAdminSet_Call { + return &EVM2EVMOffRampInterface_ParseAdminSet_Call{Call: _e.mock.On("ParseAdminSet", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseAdminSet_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseAdminSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseAdminSet_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet, _a1 error) *EVM2EVMOffRampInterface_ParseAdminSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseAdminSet_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet, error)) *EVM2EVMOffRampInterface_ParseAdminSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseConfigSet provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseConfigSet(log types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseConfigSet") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseConfigSet' +type EVM2EVMOffRampInterface_ParseConfigSet_Call struct { + *mock.Call +} + +// ParseConfigSet is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseConfigSet(log interface{}) *EVM2EVMOffRampInterface_ParseConfigSet_Call { + return &EVM2EVMOffRampInterface_ParseConfigSet_Call{Call: _e.mock.On("ParseConfigSet", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet, _a1 error) *EVM2EVMOffRampInterface_ParseConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet, error)) *EVM2EVMOffRampInterface_ParseConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseConfigSet0 provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseConfigSet0(log types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseConfigSet0") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0 + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseConfigSet0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseConfigSet0' +type EVM2EVMOffRampInterface_ParseConfigSet0_Call struct { + *mock.Call +} + +// ParseConfigSet0 is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseConfigSet0(log interface{}) *EVM2EVMOffRampInterface_ParseConfigSet0_Call { + return &EVM2EVMOffRampInterface_ParseConfigSet0_Call{Call: _e.mock.On("ParseConfigSet0", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet0_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseConfigSet0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet0_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0, _a1 error) *EVM2EVMOffRampInterface_ParseConfigSet0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseConfigSet0_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0, error)) *EVM2EVMOffRampInterface_ParseConfigSet0_Call { + _c.Call.Return(run) + return _c +} + +// ParseExecutionStateChanged provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseExecutionStateChanged(log types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseExecutionStateChanged") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseExecutionStateChanged' +type EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call struct { + *mock.Call +} + +// ParseExecutionStateChanged is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseExecutionStateChanged(log interface{}) *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call { + return &EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call{Call: _e.mock.On("ParseExecutionStateChanged", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged, _a1 error) *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged, error)) *EVM2EVMOffRampInterface_ParseExecutionStateChanged_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type EVM2EVMOffRampInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseLog(log interface{}) *EVM2EVMOffRampInterface_ParseLog_Call { + return &EVM2EVMOffRampInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseLog_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *EVM2EVMOffRampInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *EVM2EVMOffRampInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferRequested provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseOwnershipTransferRequested(log types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferRequested") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferRequested' +type EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call struct { + *mock.Call +} + +// ParseOwnershipTransferRequested is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseOwnershipTransferRequested(log interface{}) *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call { + return &EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call{Call: _e.mock.On("ParseOwnershipTransferRequested", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested, _a1 error) *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested, error)) *EVM2EVMOffRampInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferred provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseOwnershipTransferred(log types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferred") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferred' +type EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call struct { + *mock.Call +} + +// ParseOwnershipTransferred is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseOwnershipTransferred(log interface{}) *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call { + return &EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call{Call: _e.mock.On("ParseOwnershipTransferred", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred, _a1 error) *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred, error)) *EVM2EVMOffRampInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// ParsePoolAdded provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParsePoolAdded(log types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParsePoolAdded") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParsePoolAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePoolAdded' +type EVM2EVMOffRampInterface_ParsePoolAdded_Call struct { + *mock.Call +} + +// ParsePoolAdded is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParsePoolAdded(log interface{}) *EVM2EVMOffRampInterface_ParsePoolAdded_Call { + return &EVM2EVMOffRampInterface_ParsePoolAdded_Call{Call: _e.mock.On("ParsePoolAdded", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParsePoolAdded_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParsePoolAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParsePoolAdded_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded, _a1 error) *EVM2EVMOffRampInterface_ParsePoolAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParsePoolAdded_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded, error)) *EVM2EVMOffRampInterface_ParsePoolAdded_Call { + _c.Call.Return(run) + return _c +} + +// ParsePoolRemoved provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParsePoolRemoved(log types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParsePoolRemoved") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParsePoolRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePoolRemoved' +type EVM2EVMOffRampInterface_ParsePoolRemoved_Call struct { + *mock.Call +} + +// ParsePoolRemoved is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParsePoolRemoved(log interface{}) *EVM2EVMOffRampInterface_ParsePoolRemoved_Call { + return &EVM2EVMOffRampInterface_ParsePoolRemoved_Call{Call: _e.mock.On("ParsePoolRemoved", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParsePoolRemoved_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParsePoolRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParsePoolRemoved_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved, _a1 error) *EVM2EVMOffRampInterface_ParsePoolRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParsePoolRemoved_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved, error)) *EVM2EVMOffRampInterface_ParsePoolRemoved_Call { + _c.Call.Return(run) + return _c +} + +// ParseSkippedIncorrectNonce provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseSkippedIncorrectNonce(log types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseSkippedIncorrectNonce") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseSkippedIncorrectNonce' +type EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call struct { + *mock.Call +} + +// ParseSkippedIncorrectNonce is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseSkippedIncorrectNonce(log interface{}) *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call { + return &EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call{Call: _e.mock.On("ParseSkippedIncorrectNonce", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce, _a1 error) *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce, error)) *EVM2EVMOffRampInterface_ParseSkippedIncorrectNonce_Call { + _c.Call.Return(run) + return _c +} + +// ParseSkippedSenderWithPreviousRampMessageInflight provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseSkippedSenderWithPreviousRampMessageInflight(log types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseSkippedSenderWithPreviousRampMessageInflight") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseSkippedSenderWithPreviousRampMessageInflight' +type EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call struct { + *mock.Call +} + +// ParseSkippedSenderWithPreviousRampMessageInflight is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseSkippedSenderWithPreviousRampMessageInflight(log interface{}) *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call { + return &EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call{Call: _e.mock.On("ParseSkippedSenderWithPreviousRampMessageInflight", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, _a1 error) *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, error)) *EVM2EVMOffRampInterface_ParseSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(run) + return _c +} + +// ParseTransmitted provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseTransmitted(log types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTransmitted") + } + + var r0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseTransmitted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTransmitted' +type EVM2EVMOffRampInterface_ParseTransmitted_Call struct { + *mock.Call +} + +// ParseTransmitted is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseTransmitted(log interface{}) *EVM2EVMOffRampInterface_ParseTransmitted_Call { + return &EVM2EVMOffRampInterface_ParseTransmitted_Call{Call: _e.mock.On("ParseTransmitted", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseTransmitted_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseTransmitted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseTransmitted_Call) Return(_a0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted, _a1 error) *EVM2EVMOffRampInterface_ParseTransmitted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseTransmitted_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted, error)) *EVM2EVMOffRampInterface_ParseTransmitted_Call { + _c.Call.Return(run) + return _c +} + +// SetAdmin provides a mock function with given fields: opts, newAdmin +func (_m *EVM2EVMOffRampInterface) SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, newAdmin) + + if len(ret) == 0 { + panic("no return value specified for SetAdmin") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, newAdmin) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, newAdmin) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, newAdmin) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_SetAdmin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetAdmin' +type EVM2EVMOffRampInterface_SetAdmin_Call struct { + *mock.Call +} + +// SetAdmin is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - newAdmin common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) SetAdmin(opts interface{}, newAdmin interface{}) *EVM2EVMOffRampInterface_SetAdmin_Call { + return &EVM2EVMOffRampInterface_SetAdmin_Call{Call: _e.mock.On("SetAdmin", opts, newAdmin)} +} + +func (_c *EVM2EVMOffRampInterface_SetAdmin_Call) Run(run func(opts *bind.TransactOpts, newAdmin common.Address)) *EVM2EVMOffRampInterface_SetAdmin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetAdmin_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_SetAdmin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetAdmin_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *EVM2EVMOffRampInterface_SetAdmin_Call { + _c.Call.Return(run) + return _c +} + +// SetOCR2Config provides a mock function with given fields: opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig +func (_m *EVM2EVMOffRampInterface) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + ret := _m.Called(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + + if len(ret) == 0 { + panic("no return value specified for SetOCR2Config") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) (*types.Transaction, error)); ok { + return rf(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) *types.Transaction); ok { + r0 = rf(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) error); ok { + r1 = rf(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_SetOCR2Config_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetOCR2Config' +type EVM2EVMOffRampInterface_SetOCR2Config_Call struct { + *mock.Call +} + +// SetOCR2Config is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - signers []common.Address +// - transmitters []common.Address +// - f uint8 +// - onchainConfig []byte +// - offchainConfigVersion uint64 +// - offchainConfig []byte +func (_e *EVM2EVMOffRampInterface_Expecter) SetOCR2Config(opts interface{}, signers interface{}, transmitters interface{}, f interface{}, onchainConfig interface{}, offchainConfigVersion interface{}, offchainConfig interface{}) *EVM2EVMOffRampInterface_SetOCR2Config_Call { + return &EVM2EVMOffRampInterface_SetOCR2Config_Call{Call: _e.mock.On("SetOCR2Config", opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig)} +} + +func (_c *EVM2EVMOffRampInterface_SetOCR2Config_Call) Run(run func(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte)) *EVM2EVMOffRampInterface_SetOCR2Config_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]common.Address), args[2].([]common.Address), args[3].(uint8), args[4].([]byte), args[5].(uint64), args[6].([]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetOCR2Config_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_SetOCR2Config_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetOCR2Config_Call) RunAndReturn(run func(*bind.TransactOpts, []common.Address, []common.Address, uint8, []byte, uint64, []byte) (*types.Transaction, error)) *EVM2EVMOffRampInterface_SetOCR2Config_Call { + _c.Call.Return(run) + return _c +} + +// SetRateLimiterConfig provides a mock function with given fields: opts, config +func (_m *EVM2EVMOffRampInterface) SetRateLimiterConfig(opts *bind.TransactOpts, config evm_2_evm_offramp_1_2_0.RateLimiterConfig) (*types.Transaction, error) { + ret := _m.Called(opts, config) + + if len(ret) == 0 { + panic("no return value specified for SetRateLimiterConfig") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp_1_2_0.RateLimiterConfig) (*types.Transaction, error)); ok { + return rf(opts, config) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp_1_2_0.RateLimiterConfig) *types.Transaction); ok { + r0 = rf(opts, config) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp_1_2_0.RateLimiterConfig) error); ok { + r1 = rf(opts, config) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_SetRateLimiterConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetRateLimiterConfig' +type EVM2EVMOffRampInterface_SetRateLimiterConfig_Call struct { + *mock.Call +} + +// SetRateLimiterConfig is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - config evm_2_evm_offramp_1_2_0.RateLimiterConfig +func (_e *EVM2EVMOffRampInterface_Expecter) SetRateLimiterConfig(opts interface{}, config interface{}) *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call { + return &EVM2EVMOffRampInterface_SetRateLimiterConfig_Call{Call: _e.mock.On("SetRateLimiterConfig", opts, config)} +} + +func (_c *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call) Run(run func(opts *bind.TransactOpts, config evm_2_evm_offramp_1_2_0.RateLimiterConfig)) *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp_1_2_0.RateLimiterConfig)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp_1_2_0.RateLimiterConfig) (*types.Transaction, error)) *EVM2EVMOffRampInterface_SetRateLimiterConfig_Call { + _c.Call.Return(run) + return _c +} + +// TransferOwnership provides a mock function with given fields: opts, to +func (_m *EVM2EVMOffRampInterface) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, to) + + if len(ret) == 0 { + panic("no return value specified for TransferOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, to) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_TransferOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TransferOwnership' +type EVM2EVMOffRampInterface_TransferOwnership_Call struct { + *mock.Call +} + +// TransferOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - to common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) TransferOwnership(opts interface{}, to interface{}) *EVM2EVMOffRampInterface_TransferOwnership_Call { + return &EVM2EVMOffRampInterface_TransferOwnership_Call{Call: _e.mock.On("TransferOwnership", opts, to)} +} + +func (_c *EVM2EVMOffRampInterface_TransferOwnership_Call) Run(run func(opts *bind.TransactOpts, to common.Address)) *EVM2EVMOffRampInterface_TransferOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_TransferOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_TransferOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_TransferOwnership_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *EVM2EVMOffRampInterface_TransferOwnership_Call { + _c.Call.Return(run) + return _c +} + +// Transmit provides a mock function with given fields: opts, reportContext, report, rs, ss, arg4 +func (_m *EVM2EVMOffRampInterface) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte) (*types.Transaction, error) { + ret := _m.Called(opts, reportContext, report, rs, ss, arg4) + + if len(ret) == 0 { + panic("no return value specified for Transmit") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) (*types.Transaction, error)); ok { + return rf(opts, reportContext, report, rs, ss, arg4) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) *types.Transaction); ok { + r0 = rf(opts, reportContext, report, rs, ss, arg4) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) error); ok { + r1 = rf(opts, reportContext, report, rs, ss, arg4) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_Transmit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Transmit' +type EVM2EVMOffRampInterface_Transmit_Call struct { + *mock.Call +} + +// Transmit is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - reportContext [3][32]byte +// - report []byte +// - rs [][32]byte +// - ss [][32]byte +// - arg4 [32]byte +func (_e *EVM2EVMOffRampInterface_Expecter) Transmit(opts interface{}, reportContext interface{}, report interface{}, rs interface{}, ss interface{}, arg4 interface{}) *EVM2EVMOffRampInterface_Transmit_Call { + return &EVM2EVMOffRampInterface_Transmit_Call{Call: _e.mock.On("Transmit", opts, reportContext, report, rs, ss, arg4)} +} + +func (_c *EVM2EVMOffRampInterface_Transmit_Call) Run(run func(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, arg4 [32]byte)) *EVM2EVMOffRampInterface_Transmit_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([3][32]byte), args[2].([]byte), args[3].([][32]byte), args[4].([][32]byte), args[5].([32]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Transmit_Call) Return(_a0 *types.Transaction, _a1 error) *EVM2EVMOffRampInterface_Transmit_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_Transmit_Call) RunAndReturn(run func(*bind.TransactOpts, [3][32]byte, []byte, [][32]byte, [][32]byte, [32]byte) (*types.Transaction, error)) *EVM2EVMOffRampInterface_Transmit_Call { + _c.Call.Return(run) + return _c +} + +// TypeAndVersion provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) TypeAndVersion(opts *bind.CallOpts) (string, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for TypeAndVersion") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (string, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) string); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_TypeAndVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TypeAndVersion' +type EVM2EVMOffRampInterface_TypeAndVersion_Call struct { + *mock.Call +} + +// TypeAndVersion is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *EVM2EVMOffRampInterface_Expecter) TypeAndVersion(opts interface{}) *EVM2EVMOffRampInterface_TypeAndVersion_Call { + return &EVM2EVMOffRampInterface_TypeAndVersion_Call{Call: _e.mock.On("TypeAndVersion", opts)} +} + +func (_c *EVM2EVMOffRampInterface_TypeAndVersion_Call) Run(run func(opts *bind.CallOpts)) *EVM2EVMOffRampInterface_TypeAndVersion_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_TypeAndVersion_Call) Return(_a0 string, _a1 error) *EVM2EVMOffRampInterface_TypeAndVersion_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_TypeAndVersion_Call) RunAndReturn(run func(*bind.CallOpts) (string, error)) *EVM2EVMOffRampInterface_TypeAndVersion_Call { + _c.Call.Return(run) + return _c +} + +// WatchAdminSet provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchAdminSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchAdminSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchAdminSet' +type EVM2EVMOffRampInterface_WatchAdminSet_Call struct { + *mock.Call +} + +// WatchAdminSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet +func (_e *EVM2EVMOffRampInterface_Expecter) WatchAdminSet(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchAdminSet_Call { + return &EVM2EVMOffRampInterface_WatchAdminSet_Call{Call: _e.mock.On("WatchAdminSet", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchAdminSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet)) *EVM2EVMOffRampInterface_WatchAdminSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchAdminSet_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchAdminSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchAdminSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampAdminSet) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchAdminSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchConfigSet provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchConfigSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchConfigSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchConfigSet' +type EVM2EVMOffRampInterface_WatchConfigSet_Call struct { + *mock.Call +} + +// WatchConfigSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet +func (_e *EVM2EVMOffRampInterface_Expecter) WatchConfigSet(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchConfigSet_Call { + return &EVM2EVMOffRampInterface_WatchConfigSet_Call{Call: _e.mock.On("WatchConfigSet", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet)) *EVM2EVMOffRampInterface_WatchConfigSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchConfigSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchConfigSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchConfigSet0 provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchConfigSet0") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchConfigSet0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchConfigSet0' +type EVM2EVMOffRampInterface_WatchConfigSet0_Call struct { + *mock.Call +} + +// WatchConfigSet0 is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0 +func (_e *EVM2EVMOffRampInterface_Expecter) WatchConfigSet0(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchConfigSet0_Call { + return &EVM2EVMOffRampInterface_WatchConfigSet0_Call{Call: _e.mock.On("WatchConfigSet0", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet0_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0)) *EVM2EVMOffRampInterface_WatchConfigSet0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet0_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchConfigSet0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchConfigSet0_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampConfigSet0) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchConfigSet0_Call { + _c.Call.Return(run) + return _c +} + +// WatchExecutionStateChanged provides a mock function with given fields: opts, sink, sequenceNumber, messageId +func (_m *EVM2EVMOffRampInterface) WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) { + ret := _m.Called(opts, sink, sequenceNumber, messageId) + + if len(ret) == 0 { + panic("no return value specified for WatchExecutionStateChanged") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged, []uint64, [][32]byte) (event.Subscription, error)); ok { + return rf(opts, sink, sequenceNumber, messageId) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged, []uint64, [][32]byte) event.Subscription); ok { + r0 = rf(opts, sink, sequenceNumber, messageId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged, []uint64, [][32]byte) error); ok { + r1 = rf(opts, sink, sequenceNumber, messageId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchExecutionStateChanged' +type EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call struct { + *mock.Call +} + +// WatchExecutionStateChanged is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged +// - sequenceNumber []uint64 +// - messageId [][32]byte +func (_e *EVM2EVMOffRampInterface_Expecter) WatchExecutionStateChanged(opts interface{}, sink interface{}, sequenceNumber interface{}, messageId interface{}) *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call { + return &EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call{Call: _e.mock.On("WatchExecutionStateChanged", opts, sink, sequenceNumber, messageId)} +} + +func (_c *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged, sequenceNumber []uint64, messageId [][32]byte)) *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged), args[2].([]uint64), args[3].([][32]byte)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampExecutionStateChanged, []uint64, [][32]byte) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchExecutionStateChanged_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferRequested provides a mock function with given fields: opts, sink, from, to +func (_m *EVM2EVMOffRampInterface) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferRequested") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferRequested' +type EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call struct { + *mock.Call +} + +// WatchOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) WatchOwnershipTransferRequested(opts interface{}, sink interface{}, from interface{}, to interface{}) *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call { + return &EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call{Call: _e.mock.On("WatchOwnershipTransferRequested", opts, sink, from, to)} +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested, from []common.Address, to []common.Address)) *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferred provides a mock function with given fields: opts, sink, from, to +func (_m *EVM2EVMOffRampInterface) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferred") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferred' +type EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call struct { + *mock.Call +} + +// WatchOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred +// - from []common.Address +// - to []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) WatchOwnershipTransferred(opts interface{}, sink interface{}, from interface{}, to interface{}) *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call { + return &EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call{Call: _e.mock.On("WatchOwnershipTransferred", opts, sink, from, to)} +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred, from []common.Address, to []common.Address)) *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// WatchPoolAdded provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchPoolAdded(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchPoolAdded") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchPoolAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPoolAdded' +type EVM2EVMOffRampInterface_WatchPoolAdded_Call struct { + *mock.Call +} + +// WatchPoolAdded is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded +func (_e *EVM2EVMOffRampInterface_Expecter) WatchPoolAdded(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchPoolAdded_Call { + return &EVM2EVMOffRampInterface_WatchPoolAdded_Call{Call: _e.mock.On("WatchPoolAdded", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchPoolAdded_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded)) *EVM2EVMOffRampInterface_WatchPoolAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchPoolAdded_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchPoolAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchPoolAdded_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolAdded) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchPoolAdded_Call { + _c.Call.Return(run) + return _c +} + +// WatchPoolRemoved provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchPoolRemoved(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchPoolRemoved") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchPoolRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPoolRemoved' +type EVM2EVMOffRampInterface_WatchPoolRemoved_Call struct { + *mock.Call +} + +// WatchPoolRemoved is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved +func (_e *EVM2EVMOffRampInterface_Expecter) WatchPoolRemoved(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchPoolRemoved_Call { + return &EVM2EVMOffRampInterface_WatchPoolRemoved_Call{Call: _e.mock.On("WatchPoolRemoved", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchPoolRemoved_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved)) *EVM2EVMOffRampInterface_WatchPoolRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchPoolRemoved_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchPoolRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchPoolRemoved_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampPoolRemoved) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchPoolRemoved_Call { + _c.Call.Return(run) + return _c +} + +// WatchSkippedIncorrectNonce provides a mock function with given fields: opts, sink, nonce, sender +func (_m *EVM2EVMOffRampInterface) WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce, nonce []uint64, sender []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, nonce, sender) + + if len(ret) == 0 { + panic("no return value specified for WatchSkippedIncorrectNonce") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce, []uint64, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, nonce, sender) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce, []uint64, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, nonce, sender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce, []uint64, []common.Address) error); ok { + r1 = rf(opts, sink, nonce, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchSkippedIncorrectNonce' +type EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call struct { + *mock.Call +} + +// WatchSkippedIncorrectNonce is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce +// - nonce []uint64 +// - sender []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) WatchSkippedIncorrectNonce(opts interface{}, sink interface{}, nonce interface{}, sender interface{}) *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call { + return &EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call{Call: _e.mock.On("WatchSkippedIncorrectNonce", opts, sink, nonce, sender)} +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce, nonce []uint64, sender []common.Address)) *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce), args[2].([]uint64), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedIncorrectNonce, []uint64, []common.Address) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchSkippedIncorrectNonce_Call { + _c.Call.Return(run) + return _c +} + +// WatchSkippedSenderWithPreviousRampMessageInflight provides a mock function with given fields: opts, sink, nonce, sender +func (_m *EVM2EVMOffRampInterface) WatchSkippedSenderWithPreviousRampMessageInflight(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, nonce []uint64, sender []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, nonce, sender) + + if len(ret) == 0 { + panic("no return value specified for WatchSkippedSenderWithPreviousRampMessageInflight") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, []uint64, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, nonce, sender) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, []uint64, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, nonce, sender) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, []uint64, []common.Address) error); ok { + r1 = rf(opts, sink, nonce, sender) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchSkippedSenderWithPreviousRampMessageInflight' +type EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call struct { + *mock.Call +} + +// WatchSkippedSenderWithPreviousRampMessageInflight is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight +// - nonce []uint64 +// - sender []common.Address +func (_e *EVM2EVMOffRampInterface_Expecter) WatchSkippedSenderWithPreviousRampMessageInflight(opts interface{}, sink interface{}, nonce interface{}, sender interface{}) *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call { + return &EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call{Call: _e.mock.On("WatchSkippedSenderWithPreviousRampMessageInflight", opts, sink, nonce, sender)} +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, nonce []uint64, sender []common.Address)) *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight), args[2].([]uint64), args[3].([]common.Address)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampSkippedSenderWithPreviousRampMessageInflight, []uint64, []common.Address) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchSkippedSenderWithPreviousRampMessageInflight_Call { + _c.Call.Return(run) + return _c +} + +// WatchTransmitted provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchTransmitted") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchTransmitted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTransmitted' +type EVM2EVMOffRampInterface_WatchTransmitted_Call struct { + *mock.Call +} + +// WatchTransmitted is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted +func (_e *EVM2EVMOffRampInterface_Expecter) WatchTransmitted(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchTransmitted_Call { + return &EVM2EVMOffRampInterface_WatchTransmitted_Call{Call: _e.mock.On("WatchTransmitted", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchTransmitted_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted)) *EVM2EVMOffRampInterface_WatchTransmitted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchTransmitted_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchTransmitted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchTransmitted_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp_1_2_0.EVM2EVMOffRampTransmitted) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchTransmitted_Call { + _c.Call.Return(run) + return _c +} + +// NewEVM2EVMOffRampInterface creates a new instance of EVM2EVMOffRampInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewEVM2EVMOffRampInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *EVM2EVMOffRampInterface { + mock := &EVM2EVMOffRampInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index c916380cb4..95485faf4b 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -154,20 +154,14 @@ package gethwrappers // ChainReader test contract //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.abi ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.bin ChainReaderTester chain_reader_tester -// Chainlink Functions //go:generate go generate ./functions - -// Chainlink Keystone //go:generate go generate ./keystone - -// Mercury //go:generate go generate ./llo-feeds - -// Operator Forwarder //go:generate go generate ./operatorforwarder - -// Shared //go:generate go generate ./shared +//go:generate go generate ./transmission +//go:generate go generate ./ccip +//go:generate go generate ./liquiditymanager // Mocks that contain only events and functions to emit them // These contracts are used in testing Atlas flows. The contracts contain no logic, only events, structures, and functions to emit them. @@ -177,6 +171,3 @@ package gethwrappers // 3. Compile events mock contracts. ./generation/compile_event_mock_contract.sh calls contracts/scripts/native_solc_compile_all_events_mock to compile events mock contracts. // 4. Generate wrappers for events mock contracts. //go:generate ./generation/compile_event_mock_contract.sh - -// Transmission -//go:generate go generate ./transmission diff --git a/core/gethwrappers/liquiditymanager/generated/abstract_arbitrum_token_gateway/abstract_arbitrum_token_gateway.go b/core/gethwrappers/liquiditymanager/generated/abstract_arbitrum_token_gateway/abstract_arbitrum_token_gateway.go new file mode 100644 index 0000000000..d9dd3f435d --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/abstract_arbitrum_token_gateway/abstract_arbitrum_token_gateway.go @@ -0,0 +1,283 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package abstract_arbitrum_token_gateway + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var AbstractArbitrumTokenGatewayMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"l1ERC20\",\"type\":\"address\"}],\"name\":\"calculateL2TokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counterpartGateway\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"finalizeInboundTransfer\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"getOutboundCalldata\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_gasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"outboundTransfer\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"router\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +var AbstractArbitrumTokenGatewayABI = AbstractArbitrumTokenGatewayMetaData.ABI + +type AbstractArbitrumTokenGateway struct { + address common.Address + abi abi.ABI + AbstractArbitrumTokenGatewayCaller + AbstractArbitrumTokenGatewayTransactor + AbstractArbitrumTokenGatewayFilterer +} + +type AbstractArbitrumTokenGatewayCaller struct { + contract *bind.BoundContract +} + +type AbstractArbitrumTokenGatewayTransactor struct { + contract *bind.BoundContract +} + +type AbstractArbitrumTokenGatewayFilterer struct { + contract *bind.BoundContract +} + +type AbstractArbitrumTokenGatewaySession struct { + Contract *AbstractArbitrumTokenGateway + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type AbstractArbitrumTokenGatewayCallerSession struct { + Contract *AbstractArbitrumTokenGatewayCaller + CallOpts bind.CallOpts +} + +type AbstractArbitrumTokenGatewayTransactorSession struct { + Contract *AbstractArbitrumTokenGatewayTransactor + TransactOpts bind.TransactOpts +} + +type AbstractArbitrumTokenGatewayRaw struct { + Contract *AbstractArbitrumTokenGateway +} + +type AbstractArbitrumTokenGatewayCallerRaw struct { + Contract *AbstractArbitrumTokenGatewayCaller +} + +type AbstractArbitrumTokenGatewayTransactorRaw struct { + Contract *AbstractArbitrumTokenGatewayTransactor +} + +func NewAbstractArbitrumTokenGateway(address common.Address, backend bind.ContractBackend) (*AbstractArbitrumTokenGateway, error) { + abi, err := abi.JSON(strings.NewReader(AbstractArbitrumTokenGatewayABI)) + if err != nil { + return nil, err + } + contract, err := bindAbstractArbitrumTokenGateway(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AbstractArbitrumTokenGateway{address: address, abi: abi, AbstractArbitrumTokenGatewayCaller: AbstractArbitrumTokenGatewayCaller{contract: contract}, AbstractArbitrumTokenGatewayTransactor: AbstractArbitrumTokenGatewayTransactor{contract: contract}, AbstractArbitrumTokenGatewayFilterer: AbstractArbitrumTokenGatewayFilterer{contract: contract}}, nil +} + +func NewAbstractArbitrumTokenGatewayCaller(address common.Address, caller bind.ContractCaller) (*AbstractArbitrumTokenGatewayCaller, error) { + contract, err := bindAbstractArbitrumTokenGateway(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AbstractArbitrumTokenGatewayCaller{contract: contract}, nil +} + +func NewAbstractArbitrumTokenGatewayTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractArbitrumTokenGatewayTransactor, error) { + contract, err := bindAbstractArbitrumTokenGateway(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AbstractArbitrumTokenGatewayTransactor{contract: contract}, nil +} + +func NewAbstractArbitrumTokenGatewayFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractArbitrumTokenGatewayFilterer, error) { + contract, err := bindAbstractArbitrumTokenGateway(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AbstractArbitrumTokenGatewayFilterer{contract: contract}, nil +} + +func bindAbstractArbitrumTokenGateway(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := AbstractArbitrumTokenGatewayMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractArbitrumTokenGateway.Contract.AbstractArbitrumTokenGatewayCaller.contract.Call(opts, result, method, params...) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractArbitrumTokenGateway.Contract.AbstractArbitrumTokenGatewayTransactor.contract.Transfer(opts) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractArbitrumTokenGateway.Contract.AbstractArbitrumTokenGatewayTransactor.contract.Transact(opts, method, params...) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractArbitrumTokenGateway.Contract.contract.Call(opts, result, method, params...) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractArbitrumTokenGateway.Contract.contract.Transfer(opts) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractArbitrumTokenGateway.Contract.contract.Transact(opts, method, params...) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayCaller) CalculateL2TokenAddress(opts *bind.CallOpts, l1ERC20 common.Address) (common.Address, error) { + var out []interface{} + err := _AbstractArbitrumTokenGateway.contract.Call(opts, &out, "calculateL2TokenAddress", l1ERC20) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewaySession) CalculateL2TokenAddress(l1ERC20 common.Address) (common.Address, error) { + return _AbstractArbitrumTokenGateway.Contract.CalculateL2TokenAddress(&_AbstractArbitrumTokenGateway.CallOpts, l1ERC20) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayCallerSession) CalculateL2TokenAddress(l1ERC20 common.Address) (common.Address, error) { + return _AbstractArbitrumTokenGateway.Contract.CalculateL2TokenAddress(&_AbstractArbitrumTokenGateway.CallOpts, l1ERC20) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayCaller) CounterpartGateway(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AbstractArbitrumTokenGateway.contract.Call(opts, &out, "counterpartGateway") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewaySession) CounterpartGateway() (common.Address, error) { + return _AbstractArbitrumTokenGateway.Contract.CounterpartGateway(&_AbstractArbitrumTokenGateway.CallOpts) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayCallerSession) CounterpartGateway() (common.Address, error) { + return _AbstractArbitrumTokenGateway.Contract.CounterpartGateway(&_AbstractArbitrumTokenGateway.CallOpts) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayCaller) GetOutboundCalldata(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + var out []interface{} + err := _AbstractArbitrumTokenGateway.contract.Call(opts, &out, "getOutboundCalldata", _token, _from, _to, _amount, _data) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewaySession) GetOutboundCalldata(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + return _AbstractArbitrumTokenGateway.Contract.GetOutboundCalldata(&_AbstractArbitrumTokenGateway.CallOpts, _token, _from, _to, _amount, _data) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayCallerSession) GetOutboundCalldata(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + return _AbstractArbitrumTokenGateway.Contract.GetOutboundCalldata(&_AbstractArbitrumTokenGateway.CallOpts, _token, _from, _to, _amount, _data) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayCaller) Router(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AbstractArbitrumTokenGateway.contract.Call(opts, &out, "router") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewaySession) Router() (common.Address, error) { + return _AbstractArbitrumTokenGateway.Contract.Router(&_AbstractArbitrumTokenGateway.CallOpts) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayCallerSession) Router() (common.Address, error) { + return _AbstractArbitrumTokenGateway.Contract.Router(&_AbstractArbitrumTokenGateway.CallOpts) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayTransactor) FinalizeInboundTransfer(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _AbstractArbitrumTokenGateway.contract.Transact(opts, "finalizeInboundTransfer", _token, _from, _to, _amount, _data) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewaySession) FinalizeInboundTransfer(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _AbstractArbitrumTokenGateway.Contract.FinalizeInboundTransfer(&_AbstractArbitrumTokenGateway.TransactOpts, _token, _from, _to, _amount, _data) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayTransactorSession) FinalizeInboundTransfer(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _AbstractArbitrumTokenGateway.Contract.FinalizeInboundTransfer(&_AbstractArbitrumTokenGateway.TransactOpts, _token, _from, _to, _amount, _data) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayTransactor) OutboundTransfer(opts *bind.TransactOpts, _token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _AbstractArbitrumTokenGateway.contract.Transact(opts, "outboundTransfer", _token, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewaySession) OutboundTransfer(_token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _AbstractArbitrumTokenGateway.Contract.OutboundTransfer(&_AbstractArbitrumTokenGateway.TransactOpts, _token, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGatewayTransactorSession) OutboundTransfer(_token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _AbstractArbitrumTokenGateway.Contract.OutboundTransfer(&_AbstractArbitrumTokenGateway.TransactOpts, _token, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_AbstractArbitrumTokenGateway *AbstractArbitrumTokenGateway) Address() common.Address { + return _AbstractArbitrumTokenGateway.address +} + +type AbstractArbitrumTokenGatewayInterface interface { + CalculateL2TokenAddress(opts *bind.CallOpts, l1ERC20 common.Address) (common.Address, error) + + CounterpartGateway(opts *bind.CallOpts) (common.Address, error) + + GetOutboundCalldata(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) + + Router(opts *bind.CallOpts) (common.Address, error) + + FinalizeInboundTransfer(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) + + OutboundTransfer(opts *bind.TransactOpts, _token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/arb_node_interface/arb_node_interface.go b/core/gethwrappers/liquiditymanager/generated/arb_node_interface/arb_node_interface.go new file mode 100644 index 0000000000..966c9f7316 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/arb_node_interface/arb_node_interface.go @@ -0,0 +1,428 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package arb_node_interface + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var NodeInterfaceMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"l2BlockNum\",\"type\":\"uint64\"}],\"name\":\"blockL1Num\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"l1BlockNum\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"size\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"leaf\",\"type\":\"uint64\"}],\"name\":\"constructOutboxProof\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"send\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"l2CallValue\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"excessFeeRefundAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"callValueRefundAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"estimateRetryableTicket\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"}],\"name\":\"findBatchContainingBlock\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"batch\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"contractCreation\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"gasEstimateComponents\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"gasEstimate\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"gasEstimateForL1\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"baseFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1BaseFeeEstimate\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"contractCreation\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"gasEstimateL1Component\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"gasEstimateForL1\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"baseFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1BaseFeeEstimate\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"name\":\"getL1Confirmations\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"confirmations\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"}],\"name\":\"l2BlockRangeForL1\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"firstBlock\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastBlock\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"batchNum\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"index\",\"type\":\"uint64\"}],\"name\":\"legacyLookupMessageBatchProof\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"path\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"l2Sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1Dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"l2Block\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1Block\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"calldataForL1\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nitroGenesisBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", +} + +var NodeInterfaceABI = NodeInterfaceMetaData.ABI + +type NodeInterface struct { + address common.Address + abi abi.ABI + NodeInterfaceCaller + NodeInterfaceTransactor + NodeInterfaceFilterer +} + +type NodeInterfaceCaller struct { + contract *bind.BoundContract +} + +type NodeInterfaceTransactor struct { + contract *bind.BoundContract +} + +type NodeInterfaceFilterer struct { + contract *bind.BoundContract +} + +type NodeInterfaceSession struct { + Contract *NodeInterface + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type NodeInterfaceCallerSession struct { + Contract *NodeInterfaceCaller + CallOpts bind.CallOpts +} + +type NodeInterfaceTransactorSession struct { + Contract *NodeInterfaceTransactor + TransactOpts bind.TransactOpts +} + +type NodeInterfaceRaw struct { + Contract *NodeInterface +} + +type NodeInterfaceCallerRaw struct { + Contract *NodeInterfaceCaller +} + +type NodeInterfaceTransactorRaw struct { + Contract *NodeInterfaceTransactor +} + +func NewNodeInterface(address common.Address, backend bind.ContractBackend) (*NodeInterface, error) { + abi, err := abi.JSON(strings.NewReader(NodeInterfaceABI)) + if err != nil { + return nil, err + } + contract, err := bindNodeInterface(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NodeInterface{address: address, abi: abi, NodeInterfaceCaller: NodeInterfaceCaller{contract: contract}, NodeInterfaceTransactor: NodeInterfaceTransactor{contract: contract}, NodeInterfaceFilterer: NodeInterfaceFilterer{contract: contract}}, nil +} + +func NewNodeInterfaceCaller(address common.Address, caller bind.ContractCaller) (*NodeInterfaceCaller, error) { + contract, err := bindNodeInterface(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NodeInterfaceCaller{contract: contract}, nil +} + +func NewNodeInterfaceTransactor(address common.Address, transactor bind.ContractTransactor) (*NodeInterfaceTransactor, error) { + contract, err := bindNodeInterface(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NodeInterfaceTransactor{contract: contract}, nil +} + +func NewNodeInterfaceFilterer(address common.Address, filterer bind.ContractFilterer) (*NodeInterfaceFilterer, error) { + contract, err := bindNodeInterface(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NodeInterfaceFilterer{contract: contract}, nil +} + +func bindNodeInterface(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NodeInterfaceMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_NodeInterface *NodeInterfaceRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NodeInterface.Contract.NodeInterfaceCaller.contract.Call(opts, result, method, params...) +} + +func (_NodeInterface *NodeInterfaceRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NodeInterface.Contract.NodeInterfaceTransactor.contract.Transfer(opts) +} + +func (_NodeInterface *NodeInterfaceRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NodeInterface.Contract.NodeInterfaceTransactor.contract.Transact(opts, method, params...) +} + +func (_NodeInterface *NodeInterfaceCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NodeInterface.Contract.contract.Call(opts, result, method, params...) +} + +func (_NodeInterface *NodeInterfaceTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NodeInterface.Contract.contract.Transfer(opts) +} + +func (_NodeInterface *NodeInterfaceTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NodeInterface.Contract.contract.Transact(opts, method, params...) +} + +func (_NodeInterface *NodeInterfaceCaller) BlockL1Num(opts *bind.CallOpts, l2BlockNum uint64) (uint64, error) { + var out []interface{} + err := _NodeInterface.contract.Call(opts, &out, "blockL1Num", l2BlockNum) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_NodeInterface *NodeInterfaceSession) BlockL1Num(l2BlockNum uint64) (uint64, error) { + return _NodeInterface.Contract.BlockL1Num(&_NodeInterface.CallOpts, l2BlockNum) +} + +func (_NodeInterface *NodeInterfaceCallerSession) BlockL1Num(l2BlockNum uint64) (uint64, error) { + return _NodeInterface.Contract.BlockL1Num(&_NodeInterface.CallOpts, l2BlockNum) +} + +func (_NodeInterface *NodeInterfaceCaller) ConstructOutboxProof(opts *bind.CallOpts, size uint64, leaf uint64) (ConstructOutboxProof, + + error) { + var out []interface{} + err := _NodeInterface.contract.Call(opts, &out, "constructOutboxProof", size, leaf) + + outstruct := new(ConstructOutboxProof) + if err != nil { + return *outstruct, err + } + + outstruct.Send = *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + outstruct.Root = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Proof = *abi.ConvertType(out[2], new([][32]byte)).(*[][32]byte) + + return *outstruct, err + +} + +func (_NodeInterface *NodeInterfaceSession) ConstructOutboxProof(size uint64, leaf uint64) (ConstructOutboxProof, + + error) { + return _NodeInterface.Contract.ConstructOutboxProof(&_NodeInterface.CallOpts, size, leaf) +} + +func (_NodeInterface *NodeInterfaceCallerSession) ConstructOutboxProof(size uint64, leaf uint64) (ConstructOutboxProof, + + error) { + return _NodeInterface.Contract.ConstructOutboxProof(&_NodeInterface.CallOpts, size, leaf) +} + +func (_NodeInterface *NodeInterfaceCaller) FindBatchContainingBlock(opts *bind.CallOpts, blockNum uint64) (uint64, error) { + var out []interface{} + err := _NodeInterface.contract.Call(opts, &out, "findBatchContainingBlock", blockNum) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_NodeInterface *NodeInterfaceSession) FindBatchContainingBlock(blockNum uint64) (uint64, error) { + return _NodeInterface.Contract.FindBatchContainingBlock(&_NodeInterface.CallOpts, blockNum) +} + +func (_NodeInterface *NodeInterfaceCallerSession) FindBatchContainingBlock(blockNum uint64) (uint64, error) { + return _NodeInterface.Contract.FindBatchContainingBlock(&_NodeInterface.CallOpts, blockNum) +} + +func (_NodeInterface *NodeInterfaceCaller) GetL1Confirmations(opts *bind.CallOpts, blockHash [32]byte) (uint64, error) { + var out []interface{} + err := _NodeInterface.contract.Call(opts, &out, "getL1Confirmations", blockHash) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_NodeInterface *NodeInterfaceSession) GetL1Confirmations(blockHash [32]byte) (uint64, error) { + return _NodeInterface.Contract.GetL1Confirmations(&_NodeInterface.CallOpts, blockHash) +} + +func (_NodeInterface *NodeInterfaceCallerSession) GetL1Confirmations(blockHash [32]byte) (uint64, error) { + return _NodeInterface.Contract.GetL1Confirmations(&_NodeInterface.CallOpts, blockHash) +} + +func (_NodeInterface *NodeInterfaceCaller) L2BlockRangeForL1(opts *bind.CallOpts, blockNum uint64) (L2BlockRangeForL1, + + error) { + var out []interface{} + err := _NodeInterface.contract.Call(opts, &out, "l2BlockRangeForL1", blockNum) + + outstruct := new(L2BlockRangeForL1) + if err != nil { + return *outstruct, err + } + + outstruct.FirstBlock = *abi.ConvertType(out[0], new(uint64)).(*uint64) + outstruct.LastBlock = *abi.ConvertType(out[1], new(uint64)).(*uint64) + + return *outstruct, err + +} + +func (_NodeInterface *NodeInterfaceSession) L2BlockRangeForL1(blockNum uint64) (L2BlockRangeForL1, + + error) { + return _NodeInterface.Contract.L2BlockRangeForL1(&_NodeInterface.CallOpts, blockNum) +} + +func (_NodeInterface *NodeInterfaceCallerSession) L2BlockRangeForL1(blockNum uint64) (L2BlockRangeForL1, + + error) { + return _NodeInterface.Contract.L2BlockRangeForL1(&_NodeInterface.CallOpts, blockNum) +} + +func (_NodeInterface *NodeInterfaceCaller) LegacyLookupMessageBatchProof(opts *bind.CallOpts, batchNum *big.Int, index uint64) (LegacyLookupMessageBatchProof, + + error) { + var out []interface{} + err := _NodeInterface.contract.Call(opts, &out, "legacyLookupMessageBatchProof", batchNum, index) + + outstruct := new(LegacyLookupMessageBatchProof) + if err != nil { + return *outstruct, err + } + + outstruct.Proof = *abi.ConvertType(out[0], new([][32]byte)).(*[][32]byte) + outstruct.Path = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.L2Sender = *abi.ConvertType(out[2], new(common.Address)).(*common.Address) + outstruct.L1Dest = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) + outstruct.L2Block = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + outstruct.L1Block = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) + outstruct.Timestamp = *abi.ConvertType(out[6], new(*big.Int)).(**big.Int) + outstruct.Amount = *abi.ConvertType(out[7], new(*big.Int)).(**big.Int) + outstruct.CalldataForL1 = *abi.ConvertType(out[8], new([]byte)).(*[]byte) + + return *outstruct, err + +} + +func (_NodeInterface *NodeInterfaceSession) LegacyLookupMessageBatchProof(batchNum *big.Int, index uint64) (LegacyLookupMessageBatchProof, + + error) { + return _NodeInterface.Contract.LegacyLookupMessageBatchProof(&_NodeInterface.CallOpts, batchNum, index) +} + +func (_NodeInterface *NodeInterfaceCallerSession) LegacyLookupMessageBatchProof(batchNum *big.Int, index uint64) (LegacyLookupMessageBatchProof, + + error) { + return _NodeInterface.Contract.LegacyLookupMessageBatchProof(&_NodeInterface.CallOpts, batchNum, index) +} + +func (_NodeInterface *NodeInterfaceCaller) NitroGenesisBlock(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NodeInterface.contract.Call(opts, &out, "nitroGenesisBlock") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_NodeInterface *NodeInterfaceSession) NitroGenesisBlock() (*big.Int, error) { + return _NodeInterface.Contract.NitroGenesisBlock(&_NodeInterface.CallOpts) +} + +func (_NodeInterface *NodeInterfaceCallerSession) NitroGenesisBlock() (*big.Int, error) { + return _NodeInterface.Contract.NitroGenesisBlock(&_NodeInterface.CallOpts) +} + +func (_NodeInterface *NodeInterfaceTransactor) EstimateRetryableTicket(opts *bind.TransactOpts, sender common.Address, deposit *big.Int, to common.Address, l2CallValue *big.Int, excessFeeRefundAddress common.Address, callValueRefundAddress common.Address, data []byte) (*types.Transaction, error) { + return _NodeInterface.contract.Transact(opts, "estimateRetryableTicket", sender, deposit, to, l2CallValue, excessFeeRefundAddress, callValueRefundAddress, data) +} + +func (_NodeInterface *NodeInterfaceSession) EstimateRetryableTicket(sender common.Address, deposit *big.Int, to common.Address, l2CallValue *big.Int, excessFeeRefundAddress common.Address, callValueRefundAddress common.Address, data []byte) (*types.Transaction, error) { + return _NodeInterface.Contract.EstimateRetryableTicket(&_NodeInterface.TransactOpts, sender, deposit, to, l2CallValue, excessFeeRefundAddress, callValueRefundAddress, data) +} + +func (_NodeInterface *NodeInterfaceTransactorSession) EstimateRetryableTicket(sender common.Address, deposit *big.Int, to common.Address, l2CallValue *big.Int, excessFeeRefundAddress common.Address, callValueRefundAddress common.Address, data []byte) (*types.Transaction, error) { + return _NodeInterface.Contract.EstimateRetryableTicket(&_NodeInterface.TransactOpts, sender, deposit, to, l2CallValue, excessFeeRefundAddress, callValueRefundAddress, data) +} + +func (_NodeInterface *NodeInterfaceTransactor) GasEstimateComponents(opts *bind.TransactOpts, to common.Address, contractCreation bool, data []byte) (*types.Transaction, error) { + return _NodeInterface.contract.Transact(opts, "gasEstimateComponents", to, contractCreation, data) +} + +func (_NodeInterface *NodeInterfaceSession) GasEstimateComponents(to common.Address, contractCreation bool, data []byte) (*types.Transaction, error) { + return _NodeInterface.Contract.GasEstimateComponents(&_NodeInterface.TransactOpts, to, contractCreation, data) +} + +func (_NodeInterface *NodeInterfaceTransactorSession) GasEstimateComponents(to common.Address, contractCreation bool, data []byte) (*types.Transaction, error) { + return _NodeInterface.Contract.GasEstimateComponents(&_NodeInterface.TransactOpts, to, contractCreation, data) +} + +func (_NodeInterface *NodeInterfaceTransactor) GasEstimateL1Component(opts *bind.TransactOpts, to common.Address, contractCreation bool, data []byte) (*types.Transaction, error) { + return _NodeInterface.contract.Transact(opts, "gasEstimateL1Component", to, contractCreation, data) +} + +func (_NodeInterface *NodeInterfaceSession) GasEstimateL1Component(to common.Address, contractCreation bool, data []byte) (*types.Transaction, error) { + return _NodeInterface.Contract.GasEstimateL1Component(&_NodeInterface.TransactOpts, to, contractCreation, data) +} + +func (_NodeInterface *NodeInterfaceTransactorSession) GasEstimateL1Component(to common.Address, contractCreation bool, data []byte) (*types.Transaction, error) { + return _NodeInterface.Contract.GasEstimateL1Component(&_NodeInterface.TransactOpts, to, contractCreation, data) +} + +type ConstructOutboxProof struct { + Send [32]byte + Root [32]byte + Proof [][32]byte +} +type L2BlockRangeForL1 struct { + FirstBlock uint64 + LastBlock uint64 +} +type LegacyLookupMessageBatchProof struct { + Proof [][32]byte + Path *big.Int + L2Sender common.Address + L1Dest common.Address + L2Block *big.Int + L1Block *big.Int + Timestamp *big.Int + Amount *big.Int + CalldataForL1 []byte +} + +func (_NodeInterface *NodeInterface) Address() common.Address { + return _NodeInterface.address +} + +type NodeInterfaceInterface interface { + BlockL1Num(opts *bind.CallOpts, l2BlockNum uint64) (uint64, error) + + ConstructOutboxProof(opts *bind.CallOpts, size uint64, leaf uint64) (ConstructOutboxProof, + + error) + + FindBatchContainingBlock(opts *bind.CallOpts, blockNum uint64) (uint64, error) + + GetL1Confirmations(opts *bind.CallOpts, blockHash [32]byte) (uint64, error) + + L2BlockRangeForL1(opts *bind.CallOpts, blockNum uint64) (L2BlockRangeForL1, + + error) + + LegacyLookupMessageBatchProof(opts *bind.CallOpts, batchNum *big.Int, index uint64) (LegacyLookupMessageBatchProof, + + error) + + NitroGenesisBlock(opts *bind.CallOpts) (*big.Int, error) + + EstimateRetryableTicket(opts *bind.TransactOpts, sender common.Address, deposit *big.Int, to common.Address, l2CallValue *big.Int, excessFeeRefundAddress common.Address, callValueRefundAddress common.Address, data []byte) (*types.Transaction, error) + + GasEstimateComponents(opts *bind.TransactOpts, to common.Address, contractCreation bool, data []byte) (*types.Transaction, error) + + GasEstimateL1Component(opts *bind.TransactOpts, to common.Address, contractCreation bool, data []byte) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/arbitrum_gateway_router/arbitrum_gateway_router.go b/core/gethwrappers/liquiditymanager/generated/arbitrum_gateway_router/arbitrum_gateway_router.go new file mode 100644 index 0000000000..2e16cbb7b4 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/arbitrum_gateway_router/arbitrum_gateway_router.go @@ -0,0 +1,730 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package arbitrum_gateway_router + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var ArbitrumGatewayRouterMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newDefaultGateway\",\"type\":\"address\"}],\"name\":\"DefaultGatewayUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"gateway\",\"type\":\"address\"}],\"name\":\"GatewaySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_userFrom\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_userTo\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"gateway\",\"type\":\"address\"}],\"name\":\"TransferRouted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"l1ERC20\",\"type\":\"address\"}],\"name\":\"calculateL2TokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultGateway\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"gateway\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"finalizeInboundTransfer\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"getGateway\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"gateway\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"getOutboundCalldata\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_gasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"outboundTransfer\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", +} + +var ArbitrumGatewayRouterABI = ArbitrumGatewayRouterMetaData.ABI + +type ArbitrumGatewayRouter struct { + address common.Address + abi abi.ABI + ArbitrumGatewayRouterCaller + ArbitrumGatewayRouterTransactor + ArbitrumGatewayRouterFilterer +} + +type ArbitrumGatewayRouterCaller struct { + contract *bind.BoundContract +} + +type ArbitrumGatewayRouterTransactor struct { + contract *bind.BoundContract +} + +type ArbitrumGatewayRouterFilterer struct { + contract *bind.BoundContract +} + +type ArbitrumGatewayRouterSession struct { + Contract *ArbitrumGatewayRouter + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ArbitrumGatewayRouterCallerSession struct { + Contract *ArbitrumGatewayRouterCaller + CallOpts bind.CallOpts +} + +type ArbitrumGatewayRouterTransactorSession struct { + Contract *ArbitrumGatewayRouterTransactor + TransactOpts bind.TransactOpts +} + +type ArbitrumGatewayRouterRaw struct { + Contract *ArbitrumGatewayRouter +} + +type ArbitrumGatewayRouterCallerRaw struct { + Contract *ArbitrumGatewayRouterCaller +} + +type ArbitrumGatewayRouterTransactorRaw struct { + Contract *ArbitrumGatewayRouterTransactor +} + +func NewArbitrumGatewayRouter(address common.Address, backend bind.ContractBackend) (*ArbitrumGatewayRouter, error) { + abi, err := abi.JSON(strings.NewReader(ArbitrumGatewayRouterABI)) + if err != nil { + return nil, err + } + contract, err := bindArbitrumGatewayRouter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ArbitrumGatewayRouter{address: address, abi: abi, ArbitrumGatewayRouterCaller: ArbitrumGatewayRouterCaller{contract: contract}, ArbitrumGatewayRouterTransactor: ArbitrumGatewayRouterTransactor{contract: contract}, ArbitrumGatewayRouterFilterer: ArbitrumGatewayRouterFilterer{contract: contract}}, nil +} + +func NewArbitrumGatewayRouterCaller(address common.Address, caller bind.ContractCaller) (*ArbitrumGatewayRouterCaller, error) { + contract, err := bindArbitrumGatewayRouter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ArbitrumGatewayRouterCaller{contract: contract}, nil +} + +func NewArbitrumGatewayRouterTransactor(address common.Address, transactor bind.ContractTransactor) (*ArbitrumGatewayRouterTransactor, error) { + contract, err := bindArbitrumGatewayRouter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ArbitrumGatewayRouterTransactor{contract: contract}, nil +} + +func NewArbitrumGatewayRouterFilterer(address common.Address, filterer bind.ContractFilterer) (*ArbitrumGatewayRouterFilterer, error) { + contract, err := bindArbitrumGatewayRouter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ArbitrumGatewayRouterFilterer{contract: contract}, nil +} + +func bindArbitrumGatewayRouter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ArbitrumGatewayRouterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumGatewayRouter.Contract.ArbitrumGatewayRouterCaller.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumGatewayRouter.Contract.ArbitrumGatewayRouterTransactor.contract.Transfer(opts) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumGatewayRouter.Contract.ArbitrumGatewayRouterTransactor.contract.Transact(opts, method, params...) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumGatewayRouter.Contract.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumGatewayRouter.Contract.contract.Transfer(opts) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumGatewayRouter.Contract.contract.Transact(opts, method, params...) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterCaller) CalculateL2TokenAddress(opts *bind.CallOpts, l1ERC20 common.Address) (common.Address, error) { + var out []interface{} + err := _ArbitrumGatewayRouter.contract.Call(opts, &out, "calculateL2TokenAddress", l1ERC20) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterSession) CalculateL2TokenAddress(l1ERC20 common.Address) (common.Address, error) { + return _ArbitrumGatewayRouter.Contract.CalculateL2TokenAddress(&_ArbitrumGatewayRouter.CallOpts, l1ERC20) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterCallerSession) CalculateL2TokenAddress(l1ERC20 common.Address) (common.Address, error) { + return _ArbitrumGatewayRouter.Contract.CalculateL2TokenAddress(&_ArbitrumGatewayRouter.CallOpts, l1ERC20) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterCaller) DefaultGateway(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbitrumGatewayRouter.contract.Call(opts, &out, "defaultGateway") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterSession) DefaultGateway() (common.Address, error) { + return _ArbitrumGatewayRouter.Contract.DefaultGateway(&_ArbitrumGatewayRouter.CallOpts) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterCallerSession) DefaultGateway() (common.Address, error) { + return _ArbitrumGatewayRouter.Contract.DefaultGateway(&_ArbitrumGatewayRouter.CallOpts) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterCaller) GetGateway(opts *bind.CallOpts, _token common.Address) (common.Address, error) { + var out []interface{} + err := _ArbitrumGatewayRouter.contract.Call(opts, &out, "getGateway", _token) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterSession) GetGateway(_token common.Address) (common.Address, error) { + return _ArbitrumGatewayRouter.Contract.GetGateway(&_ArbitrumGatewayRouter.CallOpts, _token) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterCallerSession) GetGateway(_token common.Address) (common.Address, error) { + return _ArbitrumGatewayRouter.Contract.GetGateway(&_ArbitrumGatewayRouter.CallOpts, _token) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterCaller) GetOutboundCalldata(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + var out []interface{} + err := _ArbitrumGatewayRouter.contract.Call(opts, &out, "getOutboundCalldata", _token, _from, _to, _amount, _data) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterSession) GetOutboundCalldata(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + return _ArbitrumGatewayRouter.Contract.GetOutboundCalldata(&_ArbitrumGatewayRouter.CallOpts, _token, _from, _to, _amount, _data) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterCallerSession) GetOutboundCalldata(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + return _ArbitrumGatewayRouter.Contract.GetOutboundCalldata(&_ArbitrumGatewayRouter.CallOpts, _token, _from, _to, _amount, _data) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterTransactor) FinalizeInboundTransfer(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumGatewayRouter.contract.Transact(opts, "finalizeInboundTransfer", _token, _from, _to, _amount, _data) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterSession) FinalizeInboundTransfer(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumGatewayRouter.Contract.FinalizeInboundTransfer(&_ArbitrumGatewayRouter.TransactOpts, _token, _from, _to, _amount, _data) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterTransactorSession) FinalizeInboundTransfer(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumGatewayRouter.Contract.FinalizeInboundTransfer(&_ArbitrumGatewayRouter.TransactOpts, _token, _from, _to, _amount, _data) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterTransactor) OutboundTransfer(opts *bind.TransactOpts, _token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumGatewayRouter.contract.Transact(opts, "outboundTransfer", _token, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterSession) OutboundTransfer(_token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumGatewayRouter.Contract.OutboundTransfer(&_ArbitrumGatewayRouter.TransactOpts, _token, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterTransactorSession) OutboundTransfer(_token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumGatewayRouter.Contract.OutboundTransfer(&_ArbitrumGatewayRouter.TransactOpts, _token, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +type ArbitrumGatewayRouterDefaultGatewayUpdatedIterator struct { + Event *ArbitrumGatewayRouterDefaultGatewayUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbitrumGatewayRouterDefaultGatewayUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbitrumGatewayRouterDefaultGatewayUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbitrumGatewayRouterDefaultGatewayUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbitrumGatewayRouterDefaultGatewayUpdatedIterator) Error() error { + return it.fail +} + +func (it *ArbitrumGatewayRouterDefaultGatewayUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbitrumGatewayRouterDefaultGatewayUpdated struct { + NewDefaultGateway common.Address + Raw types.Log +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterFilterer) FilterDefaultGatewayUpdated(opts *bind.FilterOpts) (*ArbitrumGatewayRouterDefaultGatewayUpdatedIterator, error) { + + logs, sub, err := _ArbitrumGatewayRouter.contract.FilterLogs(opts, "DefaultGatewayUpdated") + if err != nil { + return nil, err + } + return &ArbitrumGatewayRouterDefaultGatewayUpdatedIterator{contract: _ArbitrumGatewayRouter.contract, event: "DefaultGatewayUpdated", logs: logs, sub: sub}, nil +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterFilterer) WatchDefaultGatewayUpdated(opts *bind.WatchOpts, sink chan<- *ArbitrumGatewayRouterDefaultGatewayUpdated) (event.Subscription, error) { + + logs, sub, err := _ArbitrumGatewayRouter.contract.WatchLogs(opts, "DefaultGatewayUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbitrumGatewayRouterDefaultGatewayUpdated) + if err := _ArbitrumGatewayRouter.contract.UnpackLog(event, "DefaultGatewayUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterFilterer) ParseDefaultGatewayUpdated(log types.Log) (*ArbitrumGatewayRouterDefaultGatewayUpdated, error) { + event := new(ArbitrumGatewayRouterDefaultGatewayUpdated) + if err := _ArbitrumGatewayRouter.contract.UnpackLog(event, "DefaultGatewayUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ArbitrumGatewayRouterGatewaySetIterator struct { + Event *ArbitrumGatewayRouterGatewaySet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbitrumGatewayRouterGatewaySetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbitrumGatewayRouterGatewaySet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbitrumGatewayRouterGatewaySet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbitrumGatewayRouterGatewaySetIterator) Error() error { + return it.fail +} + +func (it *ArbitrumGatewayRouterGatewaySetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbitrumGatewayRouterGatewaySet struct { + L1Token common.Address + Gateway common.Address + Raw types.Log +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterFilterer) FilterGatewaySet(opts *bind.FilterOpts, l1Token []common.Address, gateway []common.Address) (*ArbitrumGatewayRouterGatewaySetIterator, error) { + + var l1TokenRule []interface{} + for _, l1TokenItem := range l1Token { + l1TokenRule = append(l1TokenRule, l1TokenItem) + } + var gatewayRule []interface{} + for _, gatewayItem := range gateway { + gatewayRule = append(gatewayRule, gatewayItem) + } + + logs, sub, err := _ArbitrumGatewayRouter.contract.FilterLogs(opts, "GatewaySet", l1TokenRule, gatewayRule) + if err != nil { + return nil, err + } + return &ArbitrumGatewayRouterGatewaySetIterator{contract: _ArbitrumGatewayRouter.contract, event: "GatewaySet", logs: logs, sub: sub}, nil +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterFilterer) WatchGatewaySet(opts *bind.WatchOpts, sink chan<- *ArbitrumGatewayRouterGatewaySet, l1Token []common.Address, gateway []common.Address) (event.Subscription, error) { + + var l1TokenRule []interface{} + for _, l1TokenItem := range l1Token { + l1TokenRule = append(l1TokenRule, l1TokenItem) + } + var gatewayRule []interface{} + for _, gatewayItem := range gateway { + gatewayRule = append(gatewayRule, gatewayItem) + } + + logs, sub, err := _ArbitrumGatewayRouter.contract.WatchLogs(opts, "GatewaySet", l1TokenRule, gatewayRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbitrumGatewayRouterGatewaySet) + if err := _ArbitrumGatewayRouter.contract.UnpackLog(event, "GatewaySet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterFilterer) ParseGatewaySet(log types.Log) (*ArbitrumGatewayRouterGatewaySet, error) { + event := new(ArbitrumGatewayRouterGatewaySet) + if err := _ArbitrumGatewayRouter.contract.UnpackLog(event, "GatewaySet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ArbitrumGatewayRouterTransferRoutedIterator struct { + Event *ArbitrumGatewayRouterTransferRouted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbitrumGatewayRouterTransferRoutedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbitrumGatewayRouterTransferRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbitrumGatewayRouterTransferRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbitrumGatewayRouterTransferRoutedIterator) Error() error { + return it.fail +} + +func (it *ArbitrumGatewayRouterTransferRoutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbitrumGatewayRouterTransferRouted struct { + Token common.Address + UserFrom common.Address + UserTo common.Address + Gateway common.Address + Raw types.Log +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterFilterer) FilterTransferRouted(opts *bind.FilterOpts, token []common.Address, _userFrom []common.Address, _userTo []common.Address) (*ArbitrumGatewayRouterTransferRoutedIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var _userFromRule []interface{} + for _, _userFromItem := range _userFrom { + _userFromRule = append(_userFromRule, _userFromItem) + } + var _userToRule []interface{} + for _, _userToItem := range _userTo { + _userToRule = append(_userToRule, _userToItem) + } + + logs, sub, err := _ArbitrumGatewayRouter.contract.FilterLogs(opts, "TransferRouted", tokenRule, _userFromRule, _userToRule) + if err != nil { + return nil, err + } + return &ArbitrumGatewayRouterTransferRoutedIterator{contract: _ArbitrumGatewayRouter.contract, event: "TransferRouted", logs: logs, sub: sub}, nil +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterFilterer) WatchTransferRouted(opts *bind.WatchOpts, sink chan<- *ArbitrumGatewayRouterTransferRouted, token []common.Address, _userFrom []common.Address, _userTo []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var _userFromRule []interface{} + for _, _userFromItem := range _userFrom { + _userFromRule = append(_userFromRule, _userFromItem) + } + var _userToRule []interface{} + for _, _userToItem := range _userTo { + _userToRule = append(_userToRule, _userToItem) + } + + logs, sub, err := _ArbitrumGatewayRouter.contract.WatchLogs(opts, "TransferRouted", tokenRule, _userFromRule, _userToRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbitrumGatewayRouterTransferRouted) + if err := _ArbitrumGatewayRouter.contract.UnpackLog(event, "TransferRouted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouterFilterer) ParseTransferRouted(log types.Log) (*ArbitrumGatewayRouterTransferRouted, error) { + event := new(ArbitrumGatewayRouterTransferRouted) + if err := _ArbitrumGatewayRouter.contract.UnpackLog(event, "TransferRouted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouter) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _ArbitrumGatewayRouter.abi.Events["DefaultGatewayUpdated"].ID: + return _ArbitrumGatewayRouter.ParseDefaultGatewayUpdated(log) + case _ArbitrumGatewayRouter.abi.Events["GatewaySet"].ID: + return _ArbitrumGatewayRouter.ParseGatewaySet(log) + case _ArbitrumGatewayRouter.abi.Events["TransferRouted"].ID: + return _ArbitrumGatewayRouter.ParseTransferRouted(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (ArbitrumGatewayRouterDefaultGatewayUpdated) Topic() common.Hash { + return common.HexToHash("0x3a8f8eb961383a94d41d193e16a3af73eaddfd5764a4c640257323a1603ac331") +} + +func (ArbitrumGatewayRouterGatewaySet) Topic() common.Hash { + return common.HexToHash("0x812ca95fe4492a9e2d1f2723c2c40c03a60a27b059581ae20ac4e4d73bfba354") +} + +func (ArbitrumGatewayRouterTransferRouted) Topic() common.Hash { + return common.HexToHash("0x85291dff2161a93c2f12c819d31889c96c63042116f5bc5a205aa701c2c429f5") +} + +func (_ArbitrumGatewayRouter *ArbitrumGatewayRouter) Address() common.Address { + return _ArbitrumGatewayRouter.address +} + +type ArbitrumGatewayRouterInterface interface { + CalculateL2TokenAddress(opts *bind.CallOpts, l1ERC20 common.Address) (common.Address, error) + + DefaultGateway(opts *bind.CallOpts) (common.Address, error) + + GetGateway(opts *bind.CallOpts, _token common.Address) (common.Address, error) + + GetOutboundCalldata(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) + + FinalizeInboundTransfer(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) + + OutboundTransfer(opts *bind.TransactOpts, _token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) + + FilterDefaultGatewayUpdated(opts *bind.FilterOpts) (*ArbitrumGatewayRouterDefaultGatewayUpdatedIterator, error) + + WatchDefaultGatewayUpdated(opts *bind.WatchOpts, sink chan<- *ArbitrumGatewayRouterDefaultGatewayUpdated) (event.Subscription, error) + + ParseDefaultGatewayUpdated(log types.Log) (*ArbitrumGatewayRouterDefaultGatewayUpdated, error) + + FilterGatewaySet(opts *bind.FilterOpts, l1Token []common.Address, gateway []common.Address) (*ArbitrumGatewayRouterGatewaySetIterator, error) + + WatchGatewaySet(opts *bind.WatchOpts, sink chan<- *ArbitrumGatewayRouterGatewaySet, l1Token []common.Address, gateway []common.Address) (event.Subscription, error) + + ParseGatewaySet(log types.Log) (*ArbitrumGatewayRouterGatewaySet, error) + + FilterTransferRouted(opts *bind.FilterOpts, token []common.Address, _userFrom []common.Address, _userTo []common.Address) (*ArbitrumGatewayRouterTransferRoutedIterator, error) + + WatchTransferRouted(opts *bind.WatchOpts, sink chan<- *ArbitrumGatewayRouterTransferRouted, token []common.Address, _userFrom []common.Address, _userTo []common.Address) (event.Subscription, error) + + ParseTransferRouted(log types.Log) (*ArbitrumGatewayRouterTransferRouted, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/arbitrum_inbox/arbitrum_inbox.go b/core/gethwrappers/liquiditymanager/generated/arbitrum_inbox/arbitrum_inbox.go new file mode 100644 index 0000000000..4632ae6ba7 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/arbitrum_inbox/arbitrum_inbox.go @@ -0,0 +1,744 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package arbitrum_inbox + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var ArbitrumInboxMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"messageNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"InboxMessageDelivered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"messageNum\",\"type\":\"uint256\"}],\"name\":\"InboxMessageDeliveredFromOrigin\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contractIBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseFee\",\"type\":\"uint256\"}],\"name\":\"calculateRetryableSubmissionFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIBridge\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"contractISequencerInbox\",\"name\":\"_sequencerInbox\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"isAllowed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxDataSize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"sendContractTransaction\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"messageData\",\"type\":\"bytes\"}],\"name\":\"sendL2Message\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"messageData\",\"type\":\"bytes\"}],\"name\":\"sendL2MessageFromOrigin\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"sendUnsignedTransaction\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sequencerInbox\",\"outputs\":[{\"internalType\":\"contractISequencerInbox\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"user\",\"type\":\"address[]\"},{\"internalType\":\"bool[]\",\"name\":\"val\",\"type\":\"bool[]\"}],\"name\":\"setAllowList\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_allowListEnabled\",\"type\":\"bool\"}],\"name\":\"setAllowListEnabled\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +var ArbitrumInboxABI = ArbitrumInboxMetaData.ABI + +type ArbitrumInbox struct { + address common.Address + abi abi.ABI + ArbitrumInboxCaller + ArbitrumInboxTransactor + ArbitrumInboxFilterer +} + +type ArbitrumInboxCaller struct { + contract *bind.BoundContract +} + +type ArbitrumInboxTransactor struct { + contract *bind.BoundContract +} + +type ArbitrumInboxFilterer struct { + contract *bind.BoundContract +} + +type ArbitrumInboxSession struct { + Contract *ArbitrumInbox + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ArbitrumInboxCallerSession struct { + Contract *ArbitrumInboxCaller + CallOpts bind.CallOpts +} + +type ArbitrumInboxTransactorSession struct { + Contract *ArbitrumInboxTransactor + TransactOpts bind.TransactOpts +} + +type ArbitrumInboxRaw struct { + Contract *ArbitrumInbox +} + +type ArbitrumInboxCallerRaw struct { + Contract *ArbitrumInboxCaller +} + +type ArbitrumInboxTransactorRaw struct { + Contract *ArbitrumInboxTransactor +} + +func NewArbitrumInbox(address common.Address, backend bind.ContractBackend) (*ArbitrumInbox, error) { + abi, err := abi.JSON(strings.NewReader(ArbitrumInboxABI)) + if err != nil { + return nil, err + } + contract, err := bindArbitrumInbox(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ArbitrumInbox{address: address, abi: abi, ArbitrumInboxCaller: ArbitrumInboxCaller{contract: contract}, ArbitrumInboxTransactor: ArbitrumInboxTransactor{contract: contract}, ArbitrumInboxFilterer: ArbitrumInboxFilterer{contract: contract}}, nil +} + +func NewArbitrumInboxCaller(address common.Address, caller bind.ContractCaller) (*ArbitrumInboxCaller, error) { + contract, err := bindArbitrumInbox(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ArbitrumInboxCaller{contract: contract}, nil +} + +func NewArbitrumInboxTransactor(address common.Address, transactor bind.ContractTransactor) (*ArbitrumInboxTransactor, error) { + contract, err := bindArbitrumInbox(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ArbitrumInboxTransactor{contract: contract}, nil +} + +func NewArbitrumInboxFilterer(address common.Address, filterer bind.ContractFilterer) (*ArbitrumInboxFilterer, error) { + contract, err := bindArbitrumInbox(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ArbitrumInboxFilterer{contract: contract}, nil +} + +func bindArbitrumInbox(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ArbitrumInboxMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ArbitrumInbox *ArbitrumInboxRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumInbox.Contract.ArbitrumInboxCaller.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumInbox *ArbitrumInboxRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.ArbitrumInboxTransactor.contract.Transfer(opts) +} + +func (_ArbitrumInbox *ArbitrumInboxRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.ArbitrumInboxTransactor.contract.Transact(opts, method, params...) +} + +func (_ArbitrumInbox *ArbitrumInboxCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumInbox.Contract.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.contract.Transfer(opts) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.contract.Transact(opts, method, params...) +} + +func (_ArbitrumInbox *ArbitrumInboxCaller) AllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _ArbitrumInbox.contract.Call(opts, &out, "allowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ArbitrumInbox *ArbitrumInboxSession) AllowListEnabled() (bool, error) { + return _ArbitrumInbox.Contract.AllowListEnabled(&_ArbitrumInbox.CallOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxCallerSession) AllowListEnabled() (bool, error) { + return _ArbitrumInbox.Contract.AllowListEnabled(&_ArbitrumInbox.CallOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxCaller) Bridge(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbitrumInbox.contract.Call(opts, &out, "bridge") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbitrumInbox *ArbitrumInboxSession) Bridge() (common.Address, error) { + return _ArbitrumInbox.Contract.Bridge(&_ArbitrumInbox.CallOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxCallerSession) Bridge() (common.Address, error) { + return _ArbitrumInbox.Contract.Bridge(&_ArbitrumInbox.CallOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxCaller) CalculateRetryableSubmissionFee(opts *bind.CallOpts, dataLength *big.Int, baseFee *big.Int) (*big.Int, error) { + var out []interface{} + err := _ArbitrumInbox.contract.Call(opts, &out, "calculateRetryableSubmissionFee", dataLength, baseFee) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbitrumInbox *ArbitrumInboxSession) CalculateRetryableSubmissionFee(dataLength *big.Int, baseFee *big.Int) (*big.Int, error) { + return _ArbitrumInbox.Contract.CalculateRetryableSubmissionFee(&_ArbitrumInbox.CallOpts, dataLength, baseFee) +} + +func (_ArbitrumInbox *ArbitrumInboxCallerSession) CalculateRetryableSubmissionFee(dataLength *big.Int, baseFee *big.Int) (*big.Int, error) { + return _ArbitrumInbox.Contract.CalculateRetryableSubmissionFee(&_ArbitrumInbox.CallOpts, dataLength, baseFee) +} + +func (_ArbitrumInbox *ArbitrumInboxCaller) GetProxyAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbitrumInbox.contract.Call(opts, &out, "getProxyAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbitrumInbox *ArbitrumInboxSession) GetProxyAdmin() (common.Address, error) { + return _ArbitrumInbox.Contract.GetProxyAdmin(&_ArbitrumInbox.CallOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxCallerSession) GetProxyAdmin() (common.Address, error) { + return _ArbitrumInbox.Contract.GetProxyAdmin(&_ArbitrumInbox.CallOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxCaller) IsAllowed(opts *bind.CallOpts, user common.Address) (bool, error) { + var out []interface{} + err := _ArbitrumInbox.contract.Call(opts, &out, "isAllowed", user) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ArbitrumInbox *ArbitrumInboxSession) IsAllowed(user common.Address) (bool, error) { + return _ArbitrumInbox.Contract.IsAllowed(&_ArbitrumInbox.CallOpts, user) +} + +func (_ArbitrumInbox *ArbitrumInboxCallerSession) IsAllowed(user common.Address) (bool, error) { + return _ArbitrumInbox.Contract.IsAllowed(&_ArbitrumInbox.CallOpts, user) +} + +func (_ArbitrumInbox *ArbitrumInboxCaller) MaxDataSize(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbitrumInbox.contract.Call(opts, &out, "maxDataSize") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbitrumInbox *ArbitrumInboxSession) MaxDataSize() (*big.Int, error) { + return _ArbitrumInbox.Contract.MaxDataSize(&_ArbitrumInbox.CallOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxCallerSession) MaxDataSize() (*big.Int, error) { + return _ArbitrumInbox.Contract.MaxDataSize(&_ArbitrumInbox.CallOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxCaller) SequencerInbox(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbitrumInbox.contract.Call(opts, &out, "sequencerInbox") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbitrumInbox *ArbitrumInboxSession) SequencerInbox() (common.Address, error) { + return _ArbitrumInbox.Contract.SequencerInbox(&_ArbitrumInbox.CallOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxCallerSession) SequencerInbox() (common.Address, error) { + return _ArbitrumInbox.Contract.SequencerInbox(&_ArbitrumInbox.CallOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactor) Initialize(opts *bind.TransactOpts, _bridge common.Address, _sequencerInbox common.Address) (*types.Transaction, error) { + return _ArbitrumInbox.contract.Transact(opts, "initialize", _bridge, _sequencerInbox) +} + +func (_ArbitrumInbox *ArbitrumInboxSession) Initialize(_bridge common.Address, _sequencerInbox common.Address) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.Initialize(&_ArbitrumInbox.TransactOpts, _bridge, _sequencerInbox) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactorSession) Initialize(_bridge common.Address, _sequencerInbox common.Address) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.Initialize(&_ArbitrumInbox.TransactOpts, _bridge, _sequencerInbox) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumInbox.contract.Transact(opts, "pause") +} + +func (_ArbitrumInbox *ArbitrumInboxSession) Pause() (*types.Transaction, error) { + return _ArbitrumInbox.Contract.Pause(&_ArbitrumInbox.TransactOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactorSession) Pause() (*types.Transaction, error) { + return _ArbitrumInbox.Contract.Pause(&_ArbitrumInbox.TransactOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactor) SendContractTransaction(opts *bind.TransactOpts, gasLimit *big.Int, maxFeePerGas *big.Int, to common.Address, value *big.Int, data []byte) (*types.Transaction, error) { + return _ArbitrumInbox.contract.Transact(opts, "sendContractTransaction", gasLimit, maxFeePerGas, to, value, data) +} + +func (_ArbitrumInbox *ArbitrumInboxSession) SendContractTransaction(gasLimit *big.Int, maxFeePerGas *big.Int, to common.Address, value *big.Int, data []byte) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.SendContractTransaction(&_ArbitrumInbox.TransactOpts, gasLimit, maxFeePerGas, to, value, data) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactorSession) SendContractTransaction(gasLimit *big.Int, maxFeePerGas *big.Int, to common.Address, value *big.Int, data []byte) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.SendContractTransaction(&_ArbitrumInbox.TransactOpts, gasLimit, maxFeePerGas, to, value, data) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactor) SendL2Message(opts *bind.TransactOpts, messageData []byte) (*types.Transaction, error) { + return _ArbitrumInbox.contract.Transact(opts, "sendL2Message", messageData) +} + +func (_ArbitrumInbox *ArbitrumInboxSession) SendL2Message(messageData []byte) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.SendL2Message(&_ArbitrumInbox.TransactOpts, messageData) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactorSession) SendL2Message(messageData []byte) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.SendL2Message(&_ArbitrumInbox.TransactOpts, messageData) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactor) SendL2MessageFromOrigin(opts *bind.TransactOpts, messageData []byte) (*types.Transaction, error) { + return _ArbitrumInbox.contract.Transact(opts, "sendL2MessageFromOrigin", messageData) +} + +func (_ArbitrumInbox *ArbitrumInboxSession) SendL2MessageFromOrigin(messageData []byte) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.SendL2MessageFromOrigin(&_ArbitrumInbox.TransactOpts, messageData) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactorSession) SendL2MessageFromOrigin(messageData []byte) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.SendL2MessageFromOrigin(&_ArbitrumInbox.TransactOpts, messageData) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactor) SendUnsignedTransaction(opts *bind.TransactOpts, gasLimit *big.Int, maxFeePerGas *big.Int, nonce *big.Int, to common.Address, value *big.Int, data []byte) (*types.Transaction, error) { + return _ArbitrumInbox.contract.Transact(opts, "sendUnsignedTransaction", gasLimit, maxFeePerGas, nonce, to, value, data) +} + +func (_ArbitrumInbox *ArbitrumInboxSession) SendUnsignedTransaction(gasLimit *big.Int, maxFeePerGas *big.Int, nonce *big.Int, to common.Address, value *big.Int, data []byte) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.SendUnsignedTransaction(&_ArbitrumInbox.TransactOpts, gasLimit, maxFeePerGas, nonce, to, value, data) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactorSession) SendUnsignedTransaction(gasLimit *big.Int, maxFeePerGas *big.Int, nonce *big.Int, to common.Address, value *big.Int, data []byte) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.SendUnsignedTransaction(&_ArbitrumInbox.TransactOpts, gasLimit, maxFeePerGas, nonce, to, value, data) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactor) SetAllowList(opts *bind.TransactOpts, user []common.Address, val []bool) (*types.Transaction, error) { + return _ArbitrumInbox.contract.Transact(opts, "setAllowList", user, val) +} + +func (_ArbitrumInbox *ArbitrumInboxSession) SetAllowList(user []common.Address, val []bool) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.SetAllowList(&_ArbitrumInbox.TransactOpts, user, val) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactorSession) SetAllowList(user []common.Address, val []bool) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.SetAllowList(&_ArbitrumInbox.TransactOpts, user, val) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactor) SetAllowListEnabled(opts *bind.TransactOpts, _allowListEnabled bool) (*types.Transaction, error) { + return _ArbitrumInbox.contract.Transact(opts, "setAllowListEnabled", _allowListEnabled) +} + +func (_ArbitrumInbox *ArbitrumInboxSession) SetAllowListEnabled(_allowListEnabled bool) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.SetAllowListEnabled(&_ArbitrumInbox.TransactOpts, _allowListEnabled) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactorSession) SetAllowListEnabled(_allowListEnabled bool) (*types.Transaction, error) { + return _ArbitrumInbox.Contract.SetAllowListEnabled(&_ArbitrumInbox.TransactOpts, _allowListEnabled) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumInbox.contract.Transact(opts, "unpause") +} + +func (_ArbitrumInbox *ArbitrumInboxSession) Unpause() (*types.Transaction, error) { + return _ArbitrumInbox.Contract.Unpause(&_ArbitrumInbox.TransactOpts) +} + +func (_ArbitrumInbox *ArbitrumInboxTransactorSession) Unpause() (*types.Transaction, error) { + return _ArbitrumInbox.Contract.Unpause(&_ArbitrumInbox.TransactOpts) +} + +type ArbitrumInboxInboxMessageDeliveredIterator struct { + Event *ArbitrumInboxInboxMessageDelivered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbitrumInboxInboxMessageDeliveredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbitrumInboxInboxMessageDelivered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbitrumInboxInboxMessageDelivered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbitrumInboxInboxMessageDeliveredIterator) Error() error { + return it.fail +} + +func (it *ArbitrumInboxInboxMessageDeliveredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbitrumInboxInboxMessageDelivered struct { + MessageNum *big.Int + Data []byte + Raw types.Log +} + +func (_ArbitrumInbox *ArbitrumInboxFilterer) FilterInboxMessageDelivered(opts *bind.FilterOpts, messageNum []*big.Int) (*ArbitrumInboxInboxMessageDeliveredIterator, error) { + + var messageNumRule []interface{} + for _, messageNumItem := range messageNum { + messageNumRule = append(messageNumRule, messageNumItem) + } + + logs, sub, err := _ArbitrumInbox.contract.FilterLogs(opts, "InboxMessageDelivered", messageNumRule) + if err != nil { + return nil, err + } + return &ArbitrumInboxInboxMessageDeliveredIterator{contract: _ArbitrumInbox.contract, event: "InboxMessageDelivered", logs: logs, sub: sub}, nil +} + +func (_ArbitrumInbox *ArbitrumInboxFilterer) WatchInboxMessageDelivered(opts *bind.WatchOpts, sink chan<- *ArbitrumInboxInboxMessageDelivered, messageNum []*big.Int) (event.Subscription, error) { + + var messageNumRule []interface{} + for _, messageNumItem := range messageNum { + messageNumRule = append(messageNumRule, messageNumItem) + } + + logs, sub, err := _ArbitrumInbox.contract.WatchLogs(opts, "InboxMessageDelivered", messageNumRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbitrumInboxInboxMessageDelivered) + if err := _ArbitrumInbox.contract.UnpackLog(event, "InboxMessageDelivered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbitrumInbox *ArbitrumInboxFilterer) ParseInboxMessageDelivered(log types.Log) (*ArbitrumInboxInboxMessageDelivered, error) { + event := new(ArbitrumInboxInboxMessageDelivered) + if err := _ArbitrumInbox.contract.UnpackLog(event, "InboxMessageDelivered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ArbitrumInboxInboxMessageDeliveredFromOriginIterator struct { + Event *ArbitrumInboxInboxMessageDeliveredFromOrigin + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbitrumInboxInboxMessageDeliveredFromOriginIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbitrumInboxInboxMessageDeliveredFromOrigin) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbitrumInboxInboxMessageDeliveredFromOrigin) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbitrumInboxInboxMessageDeliveredFromOriginIterator) Error() error { + return it.fail +} + +func (it *ArbitrumInboxInboxMessageDeliveredFromOriginIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbitrumInboxInboxMessageDeliveredFromOrigin struct { + MessageNum *big.Int + Raw types.Log +} + +func (_ArbitrumInbox *ArbitrumInboxFilterer) FilterInboxMessageDeliveredFromOrigin(opts *bind.FilterOpts, messageNum []*big.Int) (*ArbitrumInboxInboxMessageDeliveredFromOriginIterator, error) { + + var messageNumRule []interface{} + for _, messageNumItem := range messageNum { + messageNumRule = append(messageNumRule, messageNumItem) + } + + logs, sub, err := _ArbitrumInbox.contract.FilterLogs(opts, "InboxMessageDeliveredFromOrigin", messageNumRule) + if err != nil { + return nil, err + } + return &ArbitrumInboxInboxMessageDeliveredFromOriginIterator{contract: _ArbitrumInbox.contract, event: "InboxMessageDeliveredFromOrigin", logs: logs, sub: sub}, nil +} + +func (_ArbitrumInbox *ArbitrumInboxFilterer) WatchInboxMessageDeliveredFromOrigin(opts *bind.WatchOpts, sink chan<- *ArbitrumInboxInboxMessageDeliveredFromOrigin, messageNum []*big.Int) (event.Subscription, error) { + + var messageNumRule []interface{} + for _, messageNumItem := range messageNum { + messageNumRule = append(messageNumRule, messageNumItem) + } + + logs, sub, err := _ArbitrumInbox.contract.WatchLogs(opts, "InboxMessageDeliveredFromOrigin", messageNumRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbitrumInboxInboxMessageDeliveredFromOrigin) + if err := _ArbitrumInbox.contract.UnpackLog(event, "InboxMessageDeliveredFromOrigin", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbitrumInbox *ArbitrumInboxFilterer) ParseInboxMessageDeliveredFromOrigin(log types.Log) (*ArbitrumInboxInboxMessageDeliveredFromOrigin, error) { + event := new(ArbitrumInboxInboxMessageDeliveredFromOrigin) + if err := _ArbitrumInbox.contract.UnpackLog(event, "InboxMessageDeliveredFromOrigin", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_ArbitrumInbox *ArbitrumInbox) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _ArbitrumInbox.abi.Events["InboxMessageDelivered"].ID: + return _ArbitrumInbox.ParseInboxMessageDelivered(log) + case _ArbitrumInbox.abi.Events["InboxMessageDeliveredFromOrigin"].ID: + return _ArbitrumInbox.ParseInboxMessageDeliveredFromOrigin(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (ArbitrumInboxInboxMessageDelivered) Topic() common.Hash { + return common.HexToHash("0xff64905f73a67fb594e0f940a8075a860db489ad991e032f48c81123eb52d60b") +} + +func (ArbitrumInboxInboxMessageDeliveredFromOrigin) Topic() common.Hash { + return common.HexToHash("0xab532385be8f1005a4b6ba8fa20a2245facb346134ac739fe9a5198dc1580b9c") +} + +func (_ArbitrumInbox *ArbitrumInbox) Address() common.Address { + return _ArbitrumInbox.address +} + +type ArbitrumInboxInterface interface { + AllowListEnabled(opts *bind.CallOpts) (bool, error) + + Bridge(opts *bind.CallOpts) (common.Address, error) + + CalculateRetryableSubmissionFee(opts *bind.CallOpts, dataLength *big.Int, baseFee *big.Int) (*big.Int, error) + + GetProxyAdmin(opts *bind.CallOpts) (common.Address, error) + + IsAllowed(opts *bind.CallOpts, user common.Address) (bool, error) + + MaxDataSize(opts *bind.CallOpts) (*big.Int, error) + + SequencerInbox(opts *bind.CallOpts) (common.Address, error) + + Initialize(opts *bind.TransactOpts, _bridge common.Address, _sequencerInbox common.Address) (*types.Transaction, error) + + Pause(opts *bind.TransactOpts) (*types.Transaction, error) + + SendContractTransaction(opts *bind.TransactOpts, gasLimit *big.Int, maxFeePerGas *big.Int, to common.Address, value *big.Int, data []byte) (*types.Transaction, error) + + SendL2Message(opts *bind.TransactOpts, messageData []byte) (*types.Transaction, error) + + SendL2MessageFromOrigin(opts *bind.TransactOpts, messageData []byte) (*types.Transaction, error) + + SendUnsignedTransaction(opts *bind.TransactOpts, gasLimit *big.Int, maxFeePerGas *big.Int, nonce *big.Int, to common.Address, value *big.Int, data []byte) (*types.Transaction, error) + + SetAllowList(opts *bind.TransactOpts, user []common.Address, val []bool) (*types.Transaction, error) + + SetAllowListEnabled(opts *bind.TransactOpts, _allowListEnabled bool) (*types.Transaction, error) + + Unpause(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterInboxMessageDelivered(opts *bind.FilterOpts, messageNum []*big.Int) (*ArbitrumInboxInboxMessageDeliveredIterator, error) + + WatchInboxMessageDelivered(opts *bind.WatchOpts, sink chan<- *ArbitrumInboxInboxMessageDelivered, messageNum []*big.Int) (event.Subscription, error) + + ParseInboxMessageDelivered(log types.Log) (*ArbitrumInboxInboxMessageDelivered, error) + + FilterInboxMessageDeliveredFromOrigin(opts *bind.FilterOpts, messageNum []*big.Int) (*ArbitrumInboxInboxMessageDeliveredFromOriginIterator, error) + + WatchInboxMessageDeliveredFromOrigin(opts *bind.WatchOpts, sink chan<- *ArbitrumInboxInboxMessageDeliveredFromOrigin, messageNum []*big.Int) (event.Subscription, error) + + ParseInboxMessageDeliveredFromOrigin(log types.Log) (*ArbitrumInboxInboxMessageDeliveredFromOrigin, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/arbitrum_l1_bridge_adapter/arbitrum_l1_bridge_adapter.go b/core/gethwrappers/liquiditymanager/generated/arbitrum_l1_bridge_adapter/arbitrum_l1_bridge_adapter.go new file mode 100644 index 0000000000..d0ddb797f1 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/arbitrum_l1_bridge_adapter/arbitrum_l1_bridge_adapter.go @@ -0,0 +1,316 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package arbitrum_l1_bridge_adapter + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ArbitrumL1BridgeAdapterArbitrumFinalizationPayload struct { + Proof [][32]byte + Index *big.Int + L2Sender common.Address + To common.Address + L2Block *big.Int + L1Block *big.Int + L2Timestamp *big.Int + Value *big.Int + Data []byte +} + +type ArbitrumL1BridgeAdapterSendERC20Params struct { + GasLimit *big.Int + MaxSubmissionCost *big.Int + MaxFeePerGas *big.Int +} + +var ArbitrumL1BridgeAdapterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIL1GatewayRouter\",\"name\":\"l1GatewayRouter\",\"type\":\"address\"},{\"internalType\":\"contractIOutbox\",\"name\":\"l1Outbox\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BridgeAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wanted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InsufficientEthValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"MsgShouldNotContainValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"MsgValueDoesNotMatchAmount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NoGatewayForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unimplemented\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"l2Sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"l2Block\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1Block\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l2Timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structArbitrumL1BridgeAdapter.ArbitrumFinalizationPayload\",\"name\":\"payload\",\"type\":\"tuple\"}],\"name\":\"exposeArbitrumFinalizationPayload\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"}],\"internalType\":\"structArbitrumL1BridgeAdapter.SendERC20Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"exposeSendERC20Params\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"arbitrumFinalizationPayload\",\"type\":\"bytes\"}],\"name\":\"finalizeWithdrawERC20\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBridgeFeeInNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"}],\"name\":\"getL2Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"bridgeSpecificPayload\",\"type\":\"bytes\"}],\"name\":\"sendERC20\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x60c060405234801561001057600080fd5b50604051620013c0380380620013c08339810160408190526100319161009b565b6001600160a01b038216158061004e57506001600160a01b038116155b1561006c57604051635e9c404d60e11b815260040160405180910390fd5b6001600160a01b039182166080521660a0526100d5565b6001600160a01b038116811461009857600080fd5b50565b600080604083850312156100ae57600080fd5b82516100b981610083565b60208401519092506100ca81610083565b809150509250929050565b60805160a0516112b76200010960003960006102100152600081816102f90152818161047101526105cd01526112b76000f3fe6080604052600436106100655760003560e01c8063b5399c9e11610043578063b5399c9e146100e2578063c7665dd214610102578063c985069c1461011d57600080fd5b80632e4b1fc91461006a57806338314bb214610092578063a71d98b7146100c2575b600080fd5b34801561007657600080fd5b5061007f610162565b6040519081526020015b60405180910390f35b34801561009e57600080fd5b506100b26100ad366004610ba1565b610196565b6040519015158152602001610089565b6100d56100d0366004610c06565b61028d565b6040516100899190610cf9565b3480156100ee57600080fd5b506101006100fd366004610dbb565b50565b005b34801561010e57600080fd5b506101006100fd366004610f28565b34801561012957600080fd5b5061013d610138366004611012565b610585565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610089565b60006040517f6e12839900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806101a583850185610f28565b805160208201516040808401516060850151608086015160a087015160c088015160e08901516101008a015196517f08635a95000000000000000000000000000000000000000000000000000000008152999a5073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016996308635a959961024d999098909796959493929160040161102f565b600060405180830381600087803b15801561026757600080fd5b505af115801561027b573d6000803e3d6000fd5b5050505060019150505b949350505050565b60606102b173ffffffffffffffffffffffffffffffffffffffff8816333087610640565b6040517fbda009fe00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bda009fe90602401602060405180830381865afa158015610342573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061036691906110ed565b905073ffffffffffffffffffffffffffffffffffffffff81166103d2576040517f6c1460f400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff891660048201526024015b60405180910390fd5b6103f373ffffffffffffffffffffffffffffffffffffffff89168287610722565b600061040184860186610dbb565b9050600081602001518260400151836000015161041e9190611139565b6104289190611150565b90508034101561046d576040517f03da4d23000000000000000000000000000000000000000000000000000000008152346004820152602481018290526044016103c9565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634fb1a07b348d8c8d8d89600001518a604001518b60200151604051806020016040528060008152506040516020016104e0929190611163565b6040516020818303038152906040526040518963ffffffff1660e01b8152600401610511979695949392919061117c565b60006040518083038185885af115801561052f573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261057691908101906111dc565b9b9a5050505050505050505050565b6040517fa7e28d4800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063a7e28d4890602401602060405180830381865afa158015610616573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063a91906110ed565b92915050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261071c9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526108a9565b50505050565b8015806107c257506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561079c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c09190611253565b155b61084e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084016103c9565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526108a49084907f095ea7b3000000000000000000000000000000000000000000000000000000009060640161069a565b505050565b600061090b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166109b59092919063ffffffff16565b8051909150156108a45780806020019051810190610929919061126c565b6108a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016103c9565b60606102858484600085856000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e9919061128e565b60006040518083038185875af1925050503d8060008114610a26576040519150601f19603f3d011682016040523d82523d6000602084013e610a2b565b606091505b5091509150610a3c87838387610a47565b979650505050505050565b60608315610add578251600003610ad65773ffffffffffffffffffffffffffffffffffffffff85163b610ad6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103c9565b5081610285565b6102858383815115610af25781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c99190610cf9565b73ffffffffffffffffffffffffffffffffffffffff811681146100fd57600080fd5b8035610b5381610b26565b919050565b60008083601f840112610b6a57600080fd5b50813567ffffffffffffffff811115610b8257600080fd5b602083019150836020828501011115610b9a57600080fd5b9250929050565b60008060008060608587031215610bb757600080fd5b8435610bc281610b26565b93506020850135610bd281610b26565b9250604085013567ffffffffffffffff811115610bee57600080fd5b610bfa87828801610b58565b95989497509550505050565b60008060008060008060a08789031215610c1f57600080fd5b8635610c2a81610b26565b95506020870135610c3a81610b26565b94506040870135610c4a81610b26565b935060608701359250608087013567ffffffffffffffff811115610c6d57600080fd5b610c7989828a01610b58565b979a9699509497509295939492505050565b60005b83811015610ca6578181015183820152602001610c8e565b50506000910152565b60008151808452610cc7816020860160208601610c8b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610d0c6020830184610caf565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff81118282101715610d6657610d66610d13565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610db357610db3610d13565b604052919050565b600060608284031215610dcd57600080fd5b6040516060810181811067ffffffffffffffff82111715610df057610df0610d13565b80604052508235815260208301356020820152604083013560408201528091505092915050565b600082601f830112610e2857600080fd5b8135602067ffffffffffffffff821115610e4457610e44610d13565b8160051b610e53828201610d6c565b9283528481018201928281019087851115610e6d57600080fd5b83870192505b84831015610a3c57823582529183019190830190610e73565b600067ffffffffffffffff821115610ea657610ea6610d13565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112610ee357600080fd5b8135610ef6610ef182610e8c565b610d6c565b818152846020838601011115610f0b57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215610f3a57600080fd5b813567ffffffffffffffff80821115610f5257600080fd5b908301906101208286031215610f6757600080fd5b610f6f610d42565b823582811115610f7e57600080fd5b610f8a87828601610e17565b82525060208301356020820152610fa360408401610b48565b6040820152610fb460608401610b48565b60608201526080830135608082015260a083013560a082015260c083013560c082015260e083013560e08201526101008084013583811115610ff557600080fd5b61100188828701610ed2565b918301919091525095945050505050565b60006020828403121561102457600080fd5b8135610d0c81610b26565b6101208082528a51908201819052600090610140830190602090818e01845b8281101561106a5781518552938301939083019060010161104e565b505050508a6020840152611096604084018b73ffffffffffffffffffffffffffffffffffffffff169052565b73ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528560c08401528460e08401528281036101008401526110dd8185610caf565b9c9b505050505050505050505050565b6000602082840312156110ff57600080fd5b8151610d0c81610b26565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761063a5761063a61110a565b8082018082111561063a5761063a61110a565b8281526040602082015260006102856040830184610caf565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152508560608301528460808301528360a083015260e060c08301526111cf60e0830184610caf565b9998505050505050505050565b6000602082840312156111ee57600080fd5b815167ffffffffffffffff81111561120557600080fd5b8201601f8101841361121657600080fd5b8051611224610ef182610e8c565b81815285602083850101111561123957600080fd5b61124a826020830160208601610c8b565b95945050505050565b60006020828403121561126557600080fd5b5051919050565b60006020828403121561127e57600080fd5b81518015158114610d0c57600080fd5b600082516112a0818460208701610c8b565b919091019291505056fea164736f6c6343000818000a", +} + +var ArbitrumL1BridgeAdapterABI = ArbitrumL1BridgeAdapterMetaData.ABI + +var ArbitrumL1BridgeAdapterBin = ArbitrumL1BridgeAdapterMetaData.Bin + +func DeployArbitrumL1BridgeAdapter(auth *bind.TransactOpts, backend bind.ContractBackend, l1GatewayRouter common.Address, l1Outbox common.Address) (common.Address, *types.Transaction, *ArbitrumL1BridgeAdapter, error) { + parsed, err := ArbitrumL1BridgeAdapterMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ArbitrumL1BridgeAdapterBin), backend, l1GatewayRouter, l1Outbox) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ArbitrumL1BridgeAdapter{address: address, abi: *parsed, ArbitrumL1BridgeAdapterCaller: ArbitrumL1BridgeAdapterCaller{contract: contract}, ArbitrumL1BridgeAdapterTransactor: ArbitrumL1BridgeAdapterTransactor{contract: contract}, ArbitrumL1BridgeAdapterFilterer: ArbitrumL1BridgeAdapterFilterer{contract: contract}}, nil +} + +type ArbitrumL1BridgeAdapter struct { + address common.Address + abi abi.ABI + ArbitrumL1BridgeAdapterCaller + ArbitrumL1BridgeAdapterTransactor + ArbitrumL1BridgeAdapterFilterer +} + +type ArbitrumL1BridgeAdapterCaller struct { + contract *bind.BoundContract +} + +type ArbitrumL1BridgeAdapterTransactor struct { + contract *bind.BoundContract +} + +type ArbitrumL1BridgeAdapterFilterer struct { + contract *bind.BoundContract +} + +type ArbitrumL1BridgeAdapterSession struct { + Contract *ArbitrumL1BridgeAdapter + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ArbitrumL1BridgeAdapterCallerSession struct { + Contract *ArbitrumL1BridgeAdapterCaller + CallOpts bind.CallOpts +} + +type ArbitrumL1BridgeAdapterTransactorSession struct { + Contract *ArbitrumL1BridgeAdapterTransactor + TransactOpts bind.TransactOpts +} + +type ArbitrumL1BridgeAdapterRaw struct { + Contract *ArbitrumL1BridgeAdapter +} + +type ArbitrumL1BridgeAdapterCallerRaw struct { + Contract *ArbitrumL1BridgeAdapterCaller +} + +type ArbitrumL1BridgeAdapterTransactorRaw struct { + Contract *ArbitrumL1BridgeAdapterTransactor +} + +func NewArbitrumL1BridgeAdapter(address common.Address, backend bind.ContractBackend) (*ArbitrumL1BridgeAdapter, error) { + abi, err := abi.JSON(strings.NewReader(ArbitrumL1BridgeAdapterABI)) + if err != nil { + return nil, err + } + contract, err := bindArbitrumL1BridgeAdapter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ArbitrumL1BridgeAdapter{address: address, abi: abi, ArbitrumL1BridgeAdapterCaller: ArbitrumL1BridgeAdapterCaller{contract: contract}, ArbitrumL1BridgeAdapterTransactor: ArbitrumL1BridgeAdapterTransactor{contract: contract}, ArbitrumL1BridgeAdapterFilterer: ArbitrumL1BridgeAdapterFilterer{contract: contract}}, nil +} + +func NewArbitrumL1BridgeAdapterCaller(address common.Address, caller bind.ContractCaller) (*ArbitrumL1BridgeAdapterCaller, error) { + contract, err := bindArbitrumL1BridgeAdapter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ArbitrumL1BridgeAdapterCaller{contract: contract}, nil +} + +func NewArbitrumL1BridgeAdapterTransactor(address common.Address, transactor bind.ContractTransactor) (*ArbitrumL1BridgeAdapterTransactor, error) { + contract, err := bindArbitrumL1BridgeAdapter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ArbitrumL1BridgeAdapterTransactor{contract: contract}, nil +} + +func NewArbitrumL1BridgeAdapterFilterer(address common.Address, filterer bind.ContractFilterer) (*ArbitrumL1BridgeAdapterFilterer, error) { + contract, err := bindArbitrumL1BridgeAdapter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ArbitrumL1BridgeAdapterFilterer{contract: contract}, nil +} + +func bindArbitrumL1BridgeAdapter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ArbitrumL1BridgeAdapterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumL1BridgeAdapter.Contract.ArbitrumL1BridgeAdapterCaller.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumL1BridgeAdapter.Contract.ArbitrumL1BridgeAdapterTransactor.contract.Transfer(opts) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumL1BridgeAdapter.Contract.ArbitrumL1BridgeAdapterTransactor.contract.Transact(opts, method, params...) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumL1BridgeAdapter.Contract.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumL1BridgeAdapter.Contract.contract.Transfer(opts) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumL1BridgeAdapter.Contract.contract.Transact(opts, method, params...) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterCaller) ExposeArbitrumFinalizationPayload(opts *bind.CallOpts, payload ArbitrumL1BridgeAdapterArbitrumFinalizationPayload) error { + var out []interface{} + err := _ArbitrumL1BridgeAdapter.contract.Call(opts, &out, "exposeArbitrumFinalizationPayload", payload) + + if err != nil { + return err + } + + return err + +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterSession) ExposeArbitrumFinalizationPayload(payload ArbitrumL1BridgeAdapterArbitrumFinalizationPayload) error { + return _ArbitrumL1BridgeAdapter.Contract.ExposeArbitrumFinalizationPayload(&_ArbitrumL1BridgeAdapter.CallOpts, payload) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterCallerSession) ExposeArbitrumFinalizationPayload(payload ArbitrumL1BridgeAdapterArbitrumFinalizationPayload) error { + return _ArbitrumL1BridgeAdapter.Contract.ExposeArbitrumFinalizationPayload(&_ArbitrumL1BridgeAdapter.CallOpts, payload) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterCaller) ExposeSendERC20Params(opts *bind.CallOpts, params ArbitrumL1BridgeAdapterSendERC20Params) error { + var out []interface{} + err := _ArbitrumL1BridgeAdapter.contract.Call(opts, &out, "exposeSendERC20Params", params) + + if err != nil { + return err + } + + return err + +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterSession) ExposeSendERC20Params(params ArbitrumL1BridgeAdapterSendERC20Params) error { + return _ArbitrumL1BridgeAdapter.Contract.ExposeSendERC20Params(&_ArbitrumL1BridgeAdapter.CallOpts, params) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterCallerSession) ExposeSendERC20Params(params ArbitrumL1BridgeAdapterSendERC20Params) error { + return _ArbitrumL1BridgeAdapter.Contract.ExposeSendERC20Params(&_ArbitrumL1BridgeAdapter.CallOpts, params) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterCaller) GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbitrumL1BridgeAdapter.contract.Call(opts, &out, "getBridgeFeeInNative") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterSession) GetBridgeFeeInNative() (*big.Int, error) { + return _ArbitrumL1BridgeAdapter.Contract.GetBridgeFeeInNative(&_ArbitrumL1BridgeAdapter.CallOpts) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterCallerSession) GetBridgeFeeInNative() (*big.Int, error) { + return _ArbitrumL1BridgeAdapter.Contract.GetBridgeFeeInNative(&_ArbitrumL1BridgeAdapter.CallOpts) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterCaller) GetL2Token(opts *bind.CallOpts, l1Token common.Address) (common.Address, error) { + var out []interface{} + err := _ArbitrumL1BridgeAdapter.contract.Call(opts, &out, "getL2Token", l1Token) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterSession) GetL2Token(l1Token common.Address) (common.Address, error) { + return _ArbitrumL1BridgeAdapter.Contract.GetL2Token(&_ArbitrumL1BridgeAdapter.CallOpts, l1Token) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterCallerSession) GetL2Token(l1Token common.Address) (common.Address, error) { + return _ArbitrumL1BridgeAdapter.Contract.GetL2Token(&_ArbitrumL1BridgeAdapter.CallOpts, l1Token) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterTransactor) FinalizeWithdrawERC20(opts *bind.TransactOpts, arg0 common.Address, arg1 common.Address, arbitrumFinalizationPayload []byte) (*types.Transaction, error) { + return _ArbitrumL1BridgeAdapter.contract.Transact(opts, "finalizeWithdrawERC20", arg0, arg1, arbitrumFinalizationPayload) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterSession) FinalizeWithdrawERC20(arg0 common.Address, arg1 common.Address, arbitrumFinalizationPayload []byte) (*types.Transaction, error) { + return _ArbitrumL1BridgeAdapter.Contract.FinalizeWithdrawERC20(&_ArbitrumL1BridgeAdapter.TransactOpts, arg0, arg1, arbitrumFinalizationPayload) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterTransactorSession) FinalizeWithdrawERC20(arg0 common.Address, arg1 common.Address, arbitrumFinalizationPayload []byte) (*types.Transaction, error) { + return _ArbitrumL1BridgeAdapter.Contract.FinalizeWithdrawERC20(&_ArbitrumL1BridgeAdapter.TransactOpts, arg0, arg1, arbitrumFinalizationPayload) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterTransactor) SendERC20(opts *bind.TransactOpts, localToken common.Address, arg1 common.Address, recipient common.Address, amount *big.Int, bridgeSpecificPayload []byte) (*types.Transaction, error) { + return _ArbitrumL1BridgeAdapter.contract.Transact(opts, "sendERC20", localToken, arg1, recipient, amount, bridgeSpecificPayload) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterSession) SendERC20(localToken common.Address, arg1 common.Address, recipient common.Address, amount *big.Int, bridgeSpecificPayload []byte) (*types.Transaction, error) { + return _ArbitrumL1BridgeAdapter.Contract.SendERC20(&_ArbitrumL1BridgeAdapter.TransactOpts, localToken, arg1, recipient, amount, bridgeSpecificPayload) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapterTransactorSession) SendERC20(localToken common.Address, arg1 common.Address, recipient common.Address, amount *big.Int, bridgeSpecificPayload []byte) (*types.Transaction, error) { + return _ArbitrumL1BridgeAdapter.Contract.SendERC20(&_ArbitrumL1BridgeAdapter.TransactOpts, localToken, arg1, recipient, amount, bridgeSpecificPayload) +} + +func (_ArbitrumL1BridgeAdapter *ArbitrumL1BridgeAdapter) Address() common.Address { + return _ArbitrumL1BridgeAdapter.address +} + +type ArbitrumL1BridgeAdapterInterface interface { + ExposeArbitrumFinalizationPayload(opts *bind.CallOpts, payload ArbitrumL1BridgeAdapterArbitrumFinalizationPayload) error + + ExposeSendERC20Params(opts *bind.CallOpts, params ArbitrumL1BridgeAdapterSendERC20Params) error + + GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) + + GetL2Token(opts *bind.CallOpts, l1Token common.Address) (common.Address, error) + + FinalizeWithdrawERC20(opts *bind.TransactOpts, arg0 common.Address, arg1 common.Address, arbitrumFinalizationPayload []byte) (*types.Transaction, error) + + SendERC20(opts *bind.TransactOpts, localToken common.Address, arg1 common.Address, recipient common.Address, amount *big.Int, bridgeSpecificPayload []byte) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/arbitrum_l1_gateway_router/arbitrum_l1_gateway_router.go b/core/gethwrappers/liquiditymanager/generated/arbitrum_l1_gateway_router/arbitrum_l1_gateway_router.go new file mode 100644 index 0000000000..e2e76e5f5b --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/arbitrum_l1_gateway_router/arbitrum_l1_gateway_router.go @@ -0,0 +1,349 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package arbitrum_l1_gateway_router + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var ArbitrumL1GatewayRouterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"l1ERC20\",\"type\":\"address\"}],\"name\":\"calculateL2TokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"finalizeInboundTransfer\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"getOutboundCalldata\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"inbox\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_gasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"outboundTransfer\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_refundTo\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_gasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"outboundTransferCustomRefund\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_gateway\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_maxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_gasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_creditBackAddress\",\"type\":\"address\"}],\"name\":\"setGateway\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_gateway\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_maxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_gasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxSubmissionCost\",\"type\":\"uint256\"}],\"name\":\"setGateway\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +var ArbitrumL1GatewayRouterABI = ArbitrumL1GatewayRouterMetaData.ABI + +type ArbitrumL1GatewayRouter struct { + address common.Address + abi abi.ABI + ArbitrumL1GatewayRouterCaller + ArbitrumL1GatewayRouterTransactor + ArbitrumL1GatewayRouterFilterer +} + +type ArbitrumL1GatewayRouterCaller struct { + contract *bind.BoundContract +} + +type ArbitrumL1GatewayRouterTransactor struct { + contract *bind.BoundContract +} + +type ArbitrumL1GatewayRouterFilterer struct { + contract *bind.BoundContract +} + +type ArbitrumL1GatewayRouterSession struct { + Contract *ArbitrumL1GatewayRouter + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ArbitrumL1GatewayRouterCallerSession struct { + Contract *ArbitrumL1GatewayRouterCaller + CallOpts bind.CallOpts +} + +type ArbitrumL1GatewayRouterTransactorSession struct { + Contract *ArbitrumL1GatewayRouterTransactor + TransactOpts bind.TransactOpts +} + +type ArbitrumL1GatewayRouterRaw struct { + Contract *ArbitrumL1GatewayRouter +} + +type ArbitrumL1GatewayRouterCallerRaw struct { + Contract *ArbitrumL1GatewayRouterCaller +} + +type ArbitrumL1GatewayRouterTransactorRaw struct { + Contract *ArbitrumL1GatewayRouterTransactor +} + +func NewArbitrumL1GatewayRouter(address common.Address, backend bind.ContractBackend) (*ArbitrumL1GatewayRouter, error) { + abi, err := abi.JSON(strings.NewReader(ArbitrumL1GatewayRouterABI)) + if err != nil { + return nil, err + } + contract, err := bindArbitrumL1GatewayRouter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ArbitrumL1GatewayRouter{address: address, abi: abi, ArbitrumL1GatewayRouterCaller: ArbitrumL1GatewayRouterCaller{contract: contract}, ArbitrumL1GatewayRouterTransactor: ArbitrumL1GatewayRouterTransactor{contract: contract}, ArbitrumL1GatewayRouterFilterer: ArbitrumL1GatewayRouterFilterer{contract: contract}}, nil +} + +func NewArbitrumL1GatewayRouterCaller(address common.Address, caller bind.ContractCaller) (*ArbitrumL1GatewayRouterCaller, error) { + contract, err := bindArbitrumL1GatewayRouter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ArbitrumL1GatewayRouterCaller{contract: contract}, nil +} + +func NewArbitrumL1GatewayRouterTransactor(address common.Address, transactor bind.ContractTransactor) (*ArbitrumL1GatewayRouterTransactor, error) { + contract, err := bindArbitrumL1GatewayRouter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ArbitrumL1GatewayRouterTransactor{contract: contract}, nil +} + +func NewArbitrumL1GatewayRouterFilterer(address common.Address, filterer bind.ContractFilterer) (*ArbitrumL1GatewayRouterFilterer, error) { + contract, err := bindArbitrumL1GatewayRouter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ArbitrumL1GatewayRouterFilterer{contract: contract}, nil +} + +func bindArbitrumL1GatewayRouter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ArbitrumL1GatewayRouterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumL1GatewayRouter.Contract.ArbitrumL1GatewayRouterCaller.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.ArbitrumL1GatewayRouterTransactor.contract.Transfer(opts) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.ArbitrumL1GatewayRouterTransactor.contract.Transact(opts, method, params...) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumL1GatewayRouter.Contract.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.contract.Transfer(opts) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.contract.Transact(opts, method, params...) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterCaller) CalculateL2TokenAddress(opts *bind.CallOpts, l1ERC20 common.Address) (common.Address, error) { + var out []interface{} + err := _ArbitrumL1GatewayRouter.contract.Call(opts, &out, "calculateL2TokenAddress", l1ERC20) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterSession) CalculateL2TokenAddress(l1ERC20 common.Address) (common.Address, error) { + return _ArbitrumL1GatewayRouter.Contract.CalculateL2TokenAddress(&_ArbitrumL1GatewayRouter.CallOpts, l1ERC20) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterCallerSession) CalculateL2TokenAddress(l1ERC20 common.Address) (common.Address, error) { + return _ArbitrumL1GatewayRouter.Contract.CalculateL2TokenAddress(&_ArbitrumL1GatewayRouter.CallOpts, l1ERC20) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterCaller) GetOutboundCalldata(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + var out []interface{} + err := _ArbitrumL1GatewayRouter.contract.Call(opts, &out, "getOutboundCalldata", _token, _from, _to, _amount, _data) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterSession) GetOutboundCalldata(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + return _ArbitrumL1GatewayRouter.Contract.GetOutboundCalldata(&_ArbitrumL1GatewayRouter.CallOpts, _token, _from, _to, _amount, _data) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterCallerSession) GetOutboundCalldata(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + return _ArbitrumL1GatewayRouter.Contract.GetOutboundCalldata(&_ArbitrumL1GatewayRouter.CallOpts, _token, _from, _to, _amount, _data) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterCaller) Inbox(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbitrumL1GatewayRouter.contract.Call(opts, &out, "inbox") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterSession) Inbox() (common.Address, error) { + return _ArbitrumL1GatewayRouter.Contract.Inbox(&_ArbitrumL1GatewayRouter.CallOpts) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterCallerSession) Inbox() (common.Address, error) { + return _ArbitrumL1GatewayRouter.Contract.Inbox(&_ArbitrumL1GatewayRouter.CallOpts) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbitrumL1GatewayRouter.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterSession) Owner() (common.Address, error) { + return _ArbitrumL1GatewayRouter.Contract.Owner(&_ArbitrumL1GatewayRouter.CallOpts) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterCallerSession) Owner() (common.Address, error) { + return _ArbitrumL1GatewayRouter.Contract.Owner(&_ArbitrumL1GatewayRouter.CallOpts) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _ArbitrumL1GatewayRouter.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _ArbitrumL1GatewayRouter.Contract.SupportsInterface(&_ArbitrumL1GatewayRouter.CallOpts, interfaceId) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _ArbitrumL1GatewayRouter.Contract.SupportsInterface(&_ArbitrumL1GatewayRouter.CallOpts, interfaceId) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterTransactor) FinalizeInboundTransfer(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.contract.Transact(opts, "finalizeInboundTransfer", _token, _from, _to, _amount, _data) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterSession) FinalizeInboundTransfer(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.FinalizeInboundTransfer(&_ArbitrumL1GatewayRouter.TransactOpts, _token, _from, _to, _amount, _data) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterTransactorSession) FinalizeInboundTransfer(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.FinalizeInboundTransfer(&_ArbitrumL1GatewayRouter.TransactOpts, _token, _from, _to, _amount, _data) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterTransactor) OutboundTransfer(opts *bind.TransactOpts, _token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.contract.Transact(opts, "outboundTransfer", _token, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterSession) OutboundTransfer(_token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.OutboundTransfer(&_ArbitrumL1GatewayRouter.TransactOpts, _token, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterTransactorSession) OutboundTransfer(_token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.OutboundTransfer(&_ArbitrumL1GatewayRouter.TransactOpts, _token, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterTransactor) OutboundTransferCustomRefund(opts *bind.TransactOpts, _token common.Address, _refundTo common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.contract.Transact(opts, "outboundTransferCustomRefund", _token, _refundTo, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterSession) OutboundTransferCustomRefund(_token common.Address, _refundTo common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.OutboundTransferCustomRefund(&_ArbitrumL1GatewayRouter.TransactOpts, _token, _refundTo, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterTransactorSession) OutboundTransferCustomRefund(_token common.Address, _refundTo common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.OutboundTransferCustomRefund(&_ArbitrumL1GatewayRouter.TransactOpts, _token, _refundTo, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterTransactor) SetGateway(opts *bind.TransactOpts, _gateway common.Address, _maxGas *big.Int, _gasPriceBid *big.Int, _maxSubmissionCost *big.Int, _creditBackAddress common.Address) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.contract.Transact(opts, "setGateway", _gateway, _maxGas, _gasPriceBid, _maxSubmissionCost, _creditBackAddress) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterSession) SetGateway(_gateway common.Address, _maxGas *big.Int, _gasPriceBid *big.Int, _maxSubmissionCost *big.Int, _creditBackAddress common.Address) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.SetGateway(&_ArbitrumL1GatewayRouter.TransactOpts, _gateway, _maxGas, _gasPriceBid, _maxSubmissionCost, _creditBackAddress) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterTransactorSession) SetGateway(_gateway common.Address, _maxGas *big.Int, _gasPriceBid *big.Int, _maxSubmissionCost *big.Int, _creditBackAddress common.Address) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.SetGateway(&_ArbitrumL1GatewayRouter.TransactOpts, _gateway, _maxGas, _gasPriceBid, _maxSubmissionCost, _creditBackAddress) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterTransactor) SetGateway0(opts *bind.TransactOpts, _gateway common.Address, _maxGas *big.Int, _gasPriceBid *big.Int, _maxSubmissionCost *big.Int) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.contract.Transact(opts, "setGateway0", _gateway, _maxGas, _gasPriceBid, _maxSubmissionCost) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterSession) SetGateway0(_gateway common.Address, _maxGas *big.Int, _gasPriceBid *big.Int, _maxSubmissionCost *big.Int) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.SetGateway0(&_ArbitrumL1GatewayRouter.TransactOpts, _gateway, _maxGas, _gasPriceBid, _maxSubmissionCost) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouterTransactorSession) SetGateway0(_gateway common.Address, _maxGas *big.Int, _gasPriceBid *big.Int, _maxSubmissionCost *big.Int) (*types.Transaction, error) { + return _ArbitrumL1GatewayRouter.Contract.SetGateway0(&_ArbitrumL1GatewayRouter.TransactOpts, _gateway, _maxGas, _gasPriceBid, _maxSubmissionCost) +} + +func (_ArbitrumL1GatewayRouter *ArbitrumL1GatewayRouter) Address() common.Address { + return _ArbitrumL1GatewayRouter.address +} + +type ArbitrumL1GatewayRouterInterface interface { + CalculateL2TokenAddress(opts *bind.CallOpts, l1ERC20 common.Address) (common.Address, error) + + GetOutboundCalldata(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) + + Inbox(opts *bind.CallOpts) (common.Address, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + FinalizeInboundTransfer(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) + + OutboundTransfer(opts *bind.TransactOpts, _token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) + + OutboundTransferCustomRefund(opts *bind.TransactOpts, _token common.Address, _refundTo common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) + + SetGateway(opts *bind.TransactOpts, _gateway common.Address, _maxGas *big.Int, _gasPriceBid *big.Int, _maxSubmissionCost *big.Int, _creditBackAddress common.Address) (*types.Transaction, error) + + SetGateway0(opts *bind.TransactOpts, _gateway common.Address, _maxGas *big.Int, _gasPriceBid *big.Int, _maxSubmissionCost *big.Int) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/arbitrum_l2_bridge_adapter/arbitrum_l2_bridge_adapter.go b/core/gethwrappers/liquiditymanager/generated/arbitrum_l2_bridge_adapter/arbitrum_l2_bridge_adapter.go new file mode 100644 index 0000000000..245daddaa4 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/arbitrum_l2_bridge_adapter/arbitrum_l2_bridge_adapter.go @@ -0,0 +1,254 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package arbitrum_l2_bridge_adapter + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var ArbitrumL2BridgeAdapterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIL2GatewayRouter\",\"name\":\"l2GatewayRouter\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BridgeAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wanted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InsufficientEthValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"MsgShouldNotContainValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"MsgValueDoesNotMatchAmount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"depositNativeToL1\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"finalizeWithdrawERC20\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBridgeFeeInNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"sendERC20\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x60a060405234801561001057600080fd5b50604051610a24380380610a2483398101604081905261002f91610067565b6001600160a01b03811661005657604051635e9c404d60e11b815260040160405180910390fd5b6001600160a01b0316608052610097565b60006020828403121561007957600080fd5b81516001600160a01b038116811461009057600080fd5b9392505050565b6080516109726100b2600039600061021a01526109726000f3fe60806040526004361061003f5760003560e01c80630ff98e31146100445780632e4b1fc91461005957806338314bb21461007a578063a71d98b7146100aa575b600080fd5b61005761005236600461060a565b6100ca565b005b34801561006557600080fd5b50604051600081526020015b60405180910390f35b34801561008657600080fd5b5061009a610095366004610675565b610161565b6040519015158152602001610071565b6100bd6100b83660046106d6565b61016c565b60405161007191906107c3565b6040517f25e1606300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526064906325e1606390349060240160206040518083038185885af1158015610138573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061015d91906107d6565b5050565b60015b949350505050565b606034156101ad576040517f2543d86e0000000000000000000000000000000000000000000000000000000081523460048201526024015b60405180910390fd5b6101cf73ffffffffffffffffffffffffffffffffffffffff88163330876102c4565b60408051602081018252600080825291517f7b3a3c8b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001691637b3a3c8b91610253918b918b918b916004016107ef565b6000604051808303816000875af1158015610272573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526102b89190810190610867565b98975050505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905261035990859061035f565b50505050565b60006103c1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104709092919063ffffffff16565b80519091501561046b57808060200190518101906103df9190610927565b61046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101a4565b505050565b60606101648484600085856000808673ffffffffffffffffffffffffffffffffffffffff1685876040516104a49190610949565b60006040518083038185875af1925050503d80600081146104e1576040519150601f19603f3d011682016040523d82523d6000602084013e6104e6565b606091505b50915091506104f787838387610502565b979650505050505050565b606083156105985782516000036105915773ffffffffffffffffffffffffffffffffffffffff85163b610591576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101a4565b5081610164565b61016483838151156105ad5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a491906107c3565b803573ffffffffffffffffffffffffffffffffffffffff8116811461060557600080fd5b919050565b60006020828403121561061c57600080fd5b610625826105e1565b9392505050565b60008083601f84011261063e57600080fd5b50813567ffffffffffffffff81111561065657600080fd5b60208301915083602082850101111561066e57600080fd5b9250929050565b6000806000806060858703121561068b57600080fd5b610694856105e1565b93506106a2602086016105e1565b9250604085013567ffffffffffffffff8111156106be57600080fd5b6106ca8782880161062c565b95989497509550505050565b60008060008060008060a087890312156106ef57600080fd5b6106f8876105e1565b9550610706602088016105e1565b9450610714604088016105e1565b935060608701359250608087013567ffffffffffffffff81111561073757600080fd5b61074389828a0161062c565b979a9699509497509295939492505050565b60005b83811015610770578181015183820152602001610758565b50506000910152565b60008151808452610791816020860160208601610755565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106256020830184610779565b6000602082840312156107e857600080fd5b5051919050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261082e6080830184610779565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561087957600080fd5b815167ffffffffffffffff8082111561089157600080fd5b818401915084601f8301126108a557600080fd5b8151818111156108b7576108b7610838565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108fd576108fd610838565b8160405282815287602084870101111561091657600080fd5b6104f7836020830160208801610755565b60006020828403121561093957600080fd5b8151801515811461062557600080fd5b6000825161095b818460208701610755565b919091019291505056fea164736f6c6343000818000a", +} + +var ArbitrumL2BridgeAdapterABI = ArbitrumL2BridgeAdapterMetaData.ABI + +var ArbitrumL2BridgeAdapterBin = ArbitrumL2BridgeAdapterMetaData.Bin + +func DeployArbitrumL2BridgeAdapter(auth *bind.TransactOpts, backend bind.ContractBackend, l2GatewayRouter common.Address) (common.Address, *types.Transaction, *ArbitrumL2BridgeAdapter, error) { + parsed, err := ArbitrumL2BridgeAdapterMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ArbitrumL2BridgeAdapterBin), backend, l2GatewayRouter) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ArbitrumL2BridgeAdapter{address: address, abi: *parsed, ArbitrumL2BridgeAdapterCaller: ArbitrumL2BridgeAdapterCaller{contract: contract}, ArbitrumL2BridgeAdapterTransactor: ArbitrumL2BridgeAdapterTransactor{contract: contract}, ArbitrumL2BridgeAdapterFilterer: ArbitrumL2BridgeAdapterFilterer{contract: contract}}, nil +} + +type ArbitrumL2BridgeAdapter struct { + address common.Address + abi abi.ABI + ArbitrumL2BridgeAdapterCaller + ArbitrumL2BridgeAdapterTransactor + ArbitrumL2BridgeAdapterFilterer +} + +type ArbitrumL2BridgeAdapterCaller struct { + contract *bind.BoundContract +} + +type ArbitrumL2BridgeAdapterTransactor struct { + contract *bind.BoundContract +} + +type ArbitrumL2BridgeAdapterFilterer struct { + contract *bind.BoundContract +} + +type ArbitrumL2BridgeAdapterSession struct { + Contract *ArbitrumL2BridgeAdapter + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ArbitrumL2BridgeAdapterCallerSession struct { + Contract *ArbitrumL2BridgeAdapterCaller + CallOpts bind.CallOpts +} + +type ArbitrumL2BridgeAdapterTransactorSession struct { + Contract *ArbitrumL2BridgeAdapterTransactor + TransactOpts bind.TransactOpts +} + +type ArbitrumL2BridgeAdapterRaw struct { + Contract *ArbitrumL2BridgeAdapter +} + +type ArbitrumL2BridgeAdapterCallerRaw struct { + Contract *ArbitrumL2BridgeAdapterCaller +} + +type ArbitrumL2BridgeAdapterTransactorRaw struct { + Contract *ArbitrumL2BridgeAdapterTransactor +} + +func NewArbitrumL2BridgeAdapter(address common.Address, backend bind.ContractBackend) (*ArbitrumL2BridgeAdapter, error) { + abi, err := abi.JSON(strings.NewReader(ArbitrumL2BridgeAdapterABI)) + if err != nil { + return nil, err + } + contract, err := bindArbitrumL2BridgeAdapter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ArbitrumL2BridgeAdapter{address: address, abi: abi, ArbitrumL2BridgeAdapterCaller: ArbitrumL2BridgeAdapterCaller{contract: contract}, ArbitrumL2BridgeAdapterTransactor: ArbitrumL2BridgeAdapterTransactor{contract: contract}, ArbitrumL2BridgeAdapterFilterer: ArbitrumL2BridgeAdapterFilterer{contract: contract}}, nil +} + +func NewArbitrumL2BridgeAdapterCaller(address common.Address, caller bind.ContractCaller) (*ArbitrumL2BridgeAdapterCaller, error) { + contract, err := bindArbitrumL2BridgeAdapter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ArbitrumL2BridgeAdapterCaller{contract: contract}, nil +} + +func NewArbitrumL2BridgeAdapterTransactor(address common.Address, transactor bind.ContractTransactor) (*ArbitrumL2BridgeAdapterTransactor, error) { + contract, err := bindArbitrumL2BridgeAdapter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ArbitrumL2BridgeAdapterTransactor{contract: contract}, nil +} + +func NewArbitrumL2BridgeAdapterFilterer(address common.Address, filterer bind.ContractFilterer) (*ArbitrumL2BridgeAdapterFilterer, error) { + contract, err := bindArbitrumL2BridgeAdapter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ArbitrumL2BridgeAdapterFilterer{contract: contract}, nil +} + +func bindArbitrumL2BridgeAdapter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ArbitrumL2BridgeAdapterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumL2BridgeAdapter.Contract.ArbitrumL2BridgeAdapterCaller.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumL2BridgeAdapter.Contract.ArbitrumL2BridgeAdapterTransactor.contract.Transfer(opts) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumL2BridgeAdapter.Contract.ArbitrumL2BridgeAdapterTransactor.contract.Transact(opts, method, params...) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumL2BridgeAdapter.Contract.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumL2BridgeAdapter.Contract.contract.Transfer(opts) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumL2BridgeAdapter.Contract.contract.Transact(opts, method, params...) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterCaller) FinalizeWithdrawERC20(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) { + var out []interface{} + err := _ArbitrumL2BridgeAdapter.contract.Call(opts, &out, "finalizeWithdrawERC20", arg0, arg1, arg2) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterSession) FinalizeWithdrawERC20(arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) { + return _ArbitrumL2BridgeAdapter.Contract.FinalizeWithdrawERC20(&_ArbitrumL2BridgeAdapter.CallOpts, arg0, arg1, arg2) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterCallerSession) FinalizeWithdrawERC20(arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) { + return _ArbitrumL2BridgeAdapter.Contract.FinalizeWithdrawERC20(&_ArbitrumL2BridgeAdapter.CallOpts, arg0, arg1, arg2) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterCaller) GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbitrumL2BridgeAdapter.contract.Call(opts, &out, "getBridgeFeeInNative") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterSession) GetBridgeFeeInNative() (*big.Int, error) { + return _ArbitrumL2BridgeAdapter.Contract.GetBridgeFeeInNative(&_ArbitrumL2BridgeAdapter.CallOpts) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterCallerSession) GetBridgeFeeInNative() (*big.Int, error) { + return _ArbitrumL2BridgeAdapter.Contract.GetBridgeFeeInNative(&_ArbitrumL2BridgeAdapter.CallOpts) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterTransactor) DepositNativeToL1(opts *bind.TransactOpts, recipient common.Address) (*types.Transaction, error) { + return _ArbitrumL2BridgeAdapter.contract.Transact(opts, "depositNativeToL1", recipient) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterSession) DepositNativeToL1(recipient common.Address) (*types.Transaction, error) { + return _ArbitrumL2BridgeAdapter.Contract.DepositNativeToL1(&_ArbitrumL2BridgeAdapter.TransactOpts, recipient) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterTransactorSession) DepositNativeToL1(recipient common.Address) (*types.Transaction, error) { + return _ArbitrumL2BridgeAdapter.Contract.DepositNativeToL1(&_ArbitrumL2BridgeAdapter.TransactOpts, recipient) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterTransactor) SendERC20(opts *bind.TransactOpts, localToken common.Address, remoteToken common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _ArbitrumL2BridgeAdapter.contract.Transact(opts, "sendERC20", localToken, remoteToken, recipient, amount, arg4) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterSession) SendERC20(localToken common.Address, remoteToken common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _ArbitrumL2BridgeAdapter.Contract.SendERC20(&_ArbitrumL2BridgeAdapter.TransactOpts, localToken, remoteToken, recipient, amount, arg4) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapterTransactorSession) SendERC20(localToken common.Address, remoteToken common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _ArbitrumL2BridgeAdapter.Contract.SendERC20(&_ArbitrumL2BridgeAdapter.TransactOpts, localToken, remoteToken, recipient, amount, arg4) +} + +func (_ArbitrumL2BridgeAdapter *ArbitrumL2BridgeAdapter) Address() common.Address { + return _ArbitrumL2BridgeAdapter.address +} + +type ArbitrumL2BridgeAdapterInterface interface { + FinalizeWithdrawERC20(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) + + GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) + + DepositNativeToL1(opts *bind.TransactOpts, recipient common.Address) (*types.Transaction, error) + + SendERC20(opts *bind.TransactOpts, localToken common.Address, remoteToken common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/arbitrum_rollup_core/arbitrum_rollup_core.go b/core/gethwrappers/liquiditymanager/generated/arbitrum_rollup_core/arbitrum_rollup_core.go new file mode 100644 index 0000000000..f90cc869d5 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/arbitrum_rollup_core/arbitrum_rollup_core.go @@ -0,0 +1,2022 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package arbitrum_rollup_core + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type Assertion struct { + BeforeState ExecutionState + AfterState ExecutionState + NumBlocks uint64 +} + +type ExecutionState struct { + GlobalState GlobalState + MachineStatus uint8 +} + +type GlobalState struct { + Bytes32Vals [2][32]byte + U64Vals [2]uint64 +} + +type IRollupCoreStaker struct { + AmountStaked *big.Int + Index uint64 + LatestStakedNode uint64 + CurrentChallenge uint64 + IsStaked bool +} + +type Node struct { + StateHash [32]byte + ChallengeHash [32]byte + ConfirmData [32]byte + PrevNum uint64 + DeadlineBlock uint64 + NoChildConfirmedBeforeBlock uint64 + StakerCount uint64 + ChildStakerCount uint64 + FirstChildBlock uint64 + LatestChildNumber uint64 + CreatedAtBlock uint64 + NodeHash [32]byte +} + +var ArbRollupCoreMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nodeNum\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"sendRoot\",\"type\":\"bytes32\"}],\"name\":\"NodeConfirmed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nodeNum\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"parentNodeHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"nodeHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"executionHash\",\"type\":\"bytes32\"},{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32[2]\",\"name\":\"bytes32Vals\",\"type\":\"bytes32[2]\"},{\"internalType\":\"uint64[2]\",\"name\":\"u64Vals\",\"type\":\"uint64[2]\"}],\"internalType\":\"structGlobalState\",\"name\":\"globalState\",\"type\":\"tuple\"},{\"internalType\":\"enumMachineStatus\",\"name\":\"machineStatus\",\"type\":\"uint8\"}],\"internalType\":\"structExecutionState\",\"name\":\"beforeState\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32[2]\",\"name\":\"bytes32Vals\",\"type\":\"bytes32[2]\"},{\"internalType\":\"uint64[2]\",\"name\":\"u64Vals\",\"type\":\"uint64[2]\"}],\"internalType\":\"structGlobalState\",\"name\":\"globalState\",\"type\":\"tuple\"},{\"internalType\":\"enumMachineStatus\",\"name\":\"machineStatus\",\"type\":\"uint8\"}],\"internalType\":\"structExecutionState\",\"name\":\"afterState\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"numBlocks\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structAssertion\",\"name\":\"assertion\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"afterInboxBatchAcc\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"wasmModuleRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"inboxMaxCount\",\"type\":\"uint256\"}],\"name\":\"NodeCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nodeNum\",\"type\":\"uint64\"}],\"name\":\"NodeRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"challengeIndex\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"asserter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"challenger\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"challengedNode\",\"type\":\"uint64\"}],\"name\":\"RollupChallengeStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"machineHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"}],\"name\":\"RollupInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"finalBalance\",\"type\":\"uint256\"}],\"name\":\"UserStakeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"finalBalance\",\"type\":\"uint256\"}],\"name\":\"UserWithdrawableFundsUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"}],\"name\":\"amountStaked\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"baseStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contractIBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"challengeManager\",\"outputs\":[{\"internalType\":\"contractIChallengeManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"confirmPeriodBlocks\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"}],\"name\":\"currentChallenge\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"extraChallengeTimeBlocks\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"firstUnresolvedNode\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"nodeNum\",\"type\":\"uint64\"}],\"name\":\"getNode\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"stateHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"challengeHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"confirmData\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"prevNum\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"deadlineBlock\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"noChildConfirmedBeforeBlock\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"stakerCount\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"childStakerCount\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"firstChildBlock\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"latestChildNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"createdAtBlock\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"nodeHash\",\"type\":\"bytes32\"}],\"internalType\":\"structNode\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"nodeNum\",\"type\":\"uint64\"}],\"name\":\"getNodeCreationBlockForLogLookup\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"}],\"name\":\"getStaker\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountStaked\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"index\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"latestStakedNode\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"currentChallenge\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isStaked\",\"type\":\"bool\"}],\"internalType\":\"structIRollupCore.Staker\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"stakerNum\",\"type\":\"uint64\"}],\"name\":\"getStakerAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"}],\"name\":\"isStaked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isValidator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"}],\"name\":\"isZombie\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastStakeBlock\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfirmed\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestNodeCreated\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"}],\"name\":\"latestStakedNode\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"loserStakeEscrow\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minimumAssertionPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"nodeNum\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"}],\"name\":\"nodeHasStaker\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"outbox\",\"outputs\":[{\"internalType\":\"contractIOutbox\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rollupEventInbox\",\"outputs\":[{\"internalType\":\"contractIRollupEventInbox\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sequencerInbox\",\"outputs\":[{\"internalType\":\"contractISequencerInbox\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakeToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakerCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validatorWhitelistDisabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wasmModuleRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"withdrawableFunds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"zombieNum\",\"type\":\"uint256\"}],\"name\":\"zombieAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"zombieCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"zombieNum\",\"type\":\"uint256\"}],\"name\":\"zombieLatestStakedNode\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +var ArbRollupCoreABI = ArbRollupCoreMetaData.ABI + +type ArbRollupCore struct { + address common.Address + abi abi.ABI + ArbRollupCoreCaller + ArbRollupCoreTransactor + ArbRollupCoreFilterer +} + +type ArbRollupCoreCaller struct { + contract *bind.BoundContract +} + +type ArbRollupCoreTransactor struct { + contract *bind.BoundContract +} + +type ArbRollupCoreFilterer struct { + contract *bind.BoundContract +} + +type ArbRollupCoreSession struct { + Contract *ArbRollupCore + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ArbRollupCoreCallerSession struct { + Contract *ArbRollupCoreCaller + CallOpts bind.CallOpts +} + +type ArbRollupCoreTransactorSession struct { + Contract *ArbRollupCoreTransactor + TransactOpts bind.TransactOpts +} + +type ArbRollupCoreRaw struct { + Contract *ArbRollupCore +} + +type ArbRollupCoreCallerRaw struct { + Contract *ArbRollupCoreCaller +} + +type ArbRollupCoreTransactorRaw struct { + Contract *ArbRollupCoreTransactor +} + +func NewArbRollupCore(address common.Address, backend bind.ContractBackend) (*ArbRollupCore, error) { + abi, err := abi.JSON(strings.NewReader(ArbRollupCoreABI)) + if err != nil { + return nil, err + } + contract, err := bindArbRollupCore(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ArbRollupCore{address: address, abi: abi, ArbRollupCoreCaller: ArbRollupCoreCaller{contract: contract}, ArbRollupCoreTransactor: ArbRollupCoreTransactor{contract: contract}, ArbRollupCoreFilterer: ArbRollupCoreFilterer{contract: contract}}, nil +} + +func NewArbRollupCoreCaller(address common.Address, caller bind.ContractCaller) (*ArbRollupCoreCaller, error) { + contract, err := bindArbRollupCore(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ArbRollupCoreCaller{contract: contract}, nil +} + +func NewArbRollupCoreTransactor(address common.Address, transactor bind.ContractTransactor) (*ArbRollupCoreTransactor, error) { + contract, err := bindArbRollupCore(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ArbRollupCoreTransactor{contract: contract}, nil +} + +func NewArbRollupCoreFilterer(address common.Address, filterer bind.ContractFilterer) (*ArbRollupCoreFilterer, error) { + contract, err := bindArbRollupCore(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ArbRollupCoreFilterer{contract: contract}, nil +} + +func bindArbRollupCore(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ArbRollupCoreMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ArbRollupCore *ArbRollupCoreRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbRollupCore.Contract.ArbRollupCoreCaller.contract.Call(opts, result, method, params...) +} + +func (_ArbRollupCore *ArbRollupCoreRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbRollupCore.Contract.ArbRollupCoreTransactor.contract.Transfer(opts) +} + +func (_ArbRollupCore *ArbRollupCoreRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbRollupCore.Contract.ArbRollupCoreTransactor.contract.Transact(opts, method, params...) +} + +func (_ArbRollupCore *ArbRollupCoreCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbRollupCore.Contract.contract.Call(opts, result, method, params...) +} + +func (_ArbRollupCore *ArbRollupCoreTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbRollupCore.Contract.contract.Transfer(opts) +} + +func (_ArbRollupCore *ArbRollupCoreTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbRollupCore.Contract.contract.Transact(opts, method, params...) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) AmountStaked(opts *bind.CallOpts, staker common.Address) (*big.Int, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "amountStaked", staker) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) AmountStaked(staker common.Address) (*big.Int, error) { + return _ArbRollupCore.Contract.AmountStaked(&_ArbRollupCore.CallOpts, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) AmountStaked(staker common.Address) (*big.Int, error) { + return _ArbRollupCore.Contract.AmountStaked(&_ArbRollupCore.CallOpts, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) BaseStake(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "baseStake") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) BaseStake() (*big.Int, error) { + return _ArbRollupCore.Contract.BaseStake(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) BaseStake() (*big.Int, error) { + return _ArbRollupCore.Contract.BaseStake(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) Bridge(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "bridge") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) Bridge() (common.Address, error) { + return _ArbRollupCore.Contract.Bridge(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) Bridge() (common.Address, error) { + return _ArbRollupCore.Contract.Bridge(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) ChainId(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "chainId") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) ChainId() (*big.Int, error) { + return _ArbRollupCore.Contract.ChainId(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) ChainId() (*big.Int, error) { + return _ArbRollupCore.Contract.ChainId(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) ChallengeManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "challengeManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) ChallengeManager() (common.Address, error) { + return _ArbRollupCore.Contract.ChallengeManager(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) ChallengeManager() (common.Address, error) { + return _ArbRollupCore.Contract.ChallengeManager(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) ConfirmPeriodBlocks(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "confirmPeriodBlocks") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) ConfirmPeriodBlocks() (uint64, error) { + return _ArbRollupCore.Contract.ConfirmPeriodBlocks(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) ConfirmPeriodBlocks() (uint64, error) { + return _ArbRollupCore.Contract.ConfirmPeriodBlocks(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) CurrentChallenge(opts *bind.CallOpts, staker common.Address) (uint64, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "currentChallenge", staker) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) CurrentChallenge(staker common.Address) (uint64, error) { + return _ArbRollupCore.Contract.CurrentChallenge(&_ArbRollupCore.CallOpts, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) CurrentChallenge(staker common.Address) (uint64, error) { + return _ArbRollupCore.Contract.CurrentChallenge(&_ArbRollupCore.CallOpts, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) ExtraChallengeTimeBlocks(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "extraChallengeTimeBlocks") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) ExtraChallengeTimeBlocks() (uint64, error) { + return _ArbRollupCore.Contract.ExtraChallengeTimeBlocks(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) ExtraChallengeTimeBlocks() (uint64, error) { + return _ArbRollupCore.Contract.ExtraChallengeTimeBlocks(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) FirstUnresolvedNode(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "firstUnresolvedNode") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) FirstUnresolvedNode() (uint64, error) { + return _ArbRollupCore.Contract.FirstUnresolvedNode(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) FirstUnresolvedNode() (uint64, error) { + return _ArbRollupCore.Contract.FirstUnresolvedNode(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) GetNode(opts *bind.CallOpts, nodeNum uint64) (Node, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "getNode", nodeNum) + + if err != nil { + return *new(Node), err + } + + out0 := *abi.ConvertType(out[0], new(Node)).(*Node) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) GetNode(nodeNum uint64) (Node, error) { + return _ArbRollupCore.Contract.GetNode(&_ArbRollupCore.CallOpts, nodeNum) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) GetNode(nodeNum uint64) (Node, error) { + return _ArbRollupCore.Contract.GetNode(&_ArbRollupCore.CallOpts, nodeNum) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) GetNodeCreationBlockForLogLookup(opts *bind.CallOpts, nodeNum uint64) (*big.Int, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "getNodeCreationBlockForLogLookup", nodeNum) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) GetNodeCreationBlockForLogLookup(nodeNum uint64) (*big.Int, error) { + return _ArbRollupCore.Contract.GetNodeCreationBlockForLogLookup(&_ArbRollupCore.CallOpts, nodeNum) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) GetNodeCreationBlockForLogLookup(nodeNum uint64) (*big.Int, error) { + return _ArbRollupCore.Contract.GetNodeCreationBlockForLogLookup(&_ArbRollupCore.CallOpts, nodeNum) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) GetStaker(opts *bind.CallOpts, staker common.Address) (IRollupCoreStaker, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "getStaker", staker) + + if err != nil { + return *new(IRollupCoreStaker), err + } + + out0 := *abi.ConvertType(out[0], new(IRollupCoreStaker)).(*IRollupCoreStaker) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) GetStaker(staker common.Address) (IRollupCoreStaker, error) { + return _ArbRollupCore.Contract.GetStaker(&_ArbRollupCore.CallOpts, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) GetStaker(staker common.Address) (IRollupCoreStaker, error) { + return _ArbRollupCore.Contract.GetStaker(&_ArbRollupCore.CallOpts, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) GetStakerAddress(opts *bind.CallOpts, stakerNum uint64) (common.Address, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "getStakerAddress", stakerNum) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) GetStakerAddress(stakerNum uint64) (common.Address, error) { + return _ArbRollupCore.Contract.GetStakerAddress(&_ArbRollupCore.CallOpts, stakerNum) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) GetStakerAddress(stakerNum uint64) (common.Address, error) { + return _ArbRollupCore.Contract.GetStakerAddress(&_ArbRollupCore.CallOpts, stakerNum) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) IsStaked(opts *bind.CallOpts, staker common.Address) (bool, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "isStaked", staker) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) IsStaked(staker common.Address) (bool, error) { + return _ArbRollupCore.Contract.IsStaked(&_ArbRollupCore.CallOpts, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) IsStaked(staker common.Address) (bool, error) { + return _ArbRollupCore.Contract.IsStaked(&_ArbRollupCore.CallOpts, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) IsValidator(opts *bind.CallOpts, arg0 common.Address) (bool, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "isValidator", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) IsValidator(arg0 common.Address) (bool, error) { + return _ArbRollupCore.Contract.IsValidator(&_ArbRollupCore.CallOpts, arg0) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) IsValidator(arg0 common.Address) (bool, error) { + return _ArbRollupCore.Contract.IsValidator(&_ArbRollupCore.CallOpts, arg0) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) IsZombie(opts *bind.CallOpts, staker common.Address) (bool, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "isZombie", staker) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) IsZombie(staker common.Address) (bool, error) { + return _ArbRollupCore.Contract.IsZombie(&_ArbRollupCore.CallOpts, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) IsZombie(staker common.Address) (bool, error) { + return _ArbRollupCore.Contract.IsZombie(&_ArbRollupCore.CallOpts, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) LastStakeBlock(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "lastStakeBlock") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) LastStakeBlock() (uint64, error) { + return _ArbRollupCore.Contract.LastStakeBlock(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) LastStakeBlock() (uint64, error) { + return _ArbRollupCore.Contract.LastStakeBlock(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) LatestConfirmed(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "latestConfirmed") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) LatestConfirmed() (uint64, error) { + return _ArbRollupCore.Contract.LatestConfirmed(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) LatestConfirmed() (uint64, error) { + return _ArbRollupCore.Contract.LatestConfirmed(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) LatestNodeCreated(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "latestNodeCreated") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) LatestNodeCreated() (uint64, error) { + return _ArbRollupCore.Contract.LatestNodeCreated(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) LatestNodeCreated() (uint64, error) { + return _ArbRollupCore.Contract.LatestNodeCreated(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) LatestStakedNode(opts *bind.CallOpts, staker common.Address) (uint64, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "latestStakedNode", staker) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) LatestStakedNode(staker common.Address) (uint64, error) { + return _ArbRollupCore.Contract.LatestStakedNode(&_ArbRollupCore.CallOpts, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) LatestStakedNode(staker common.Address) (uint64, error) { + return _ArbRollupCore.Contract.LatestStakedNode(&_ArbRollupCore.CallOpts, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) LoserStakeEscrow(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "loserStakeEscrow") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) LoserStakeEscrow() (common.Address, error) { + return _ArbRollupCore.Contract.LoserStakeEscrow(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) LoserStakeEscrow() (common.Address, error) { + return _ArbRollupCore.Contract.LoserStakeEscrow(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) MinimumAssertionPeriod(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "minimumAssertionPeriod") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) MinimumAssertionPeriod() (*big.Int, error) { + return _ArbRollupCore.Contract.MinimumAssertionPeriod(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) MinimumAssertionPeriod() (*big.Int, error) { + return _ArbRollupCore.Contract.MinimumAssertionPeriod(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) NodeHasStaker(opts *bind.CallOpts, nodeNum uint64, staker common.Address) (bool, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "nodeHasStaker", nodeNum, staker) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) NodeHasStaker(nodeNum uint64, staker common.Address) (bool, error) { + return _ArbRollupCore.Contract.NodeHasStaker(&_ArbRollupCore.CallOpts, nodeNum, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) NodeHasStaker(nodeNum uint64, staker common.Address) (bool, error) { + return _ArbRollupCore.Contract.NodeHasStaker(&_ArbRollupCore.CallOpts, nodeNum, staker) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) Outbox(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "outbox") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) Outbox() (common.Address, error) { + return _ArbRollupCore.Contract.Outbox(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) Outbox() (common.Address, error) { + return _ArbRollupCore.Contract.Outbox(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) RollupEventInbox(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "rollupEventInbox") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) RollupEventInbox() (common.Address, error) { + return _ArbRollupCore.Contract.RollupEventInbox(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) RollupEventInbox() (common.Address, error) { + return _ArbRollupCore.Contract.RollupEventInbox(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) SequencerInbox(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "sequencerInbox") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) SequencerInbox() (common.Address, error) { + return _ArbRollupCore.Contract.SequencerInbox(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) SequencerInbox() (common.Address, error) { + return _ArbRollupCore.Contract.SequencerInbox(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) StakeToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "stakeToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) StakeToken() (common.Address, error) { + return _ArbRollupCore.Contract.StakeToken(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) StakeToken() (common.Address, error) { + return _ArbRollupCore.Contract.StakeToken(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) StakerCount(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "stakerCount") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) StakerCount() (uint64, error) { + return _ArbRollupCore.Contract.StakerCount(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) StakerCount() (uint64, error) { + return _ArbRollupCore.Contract.StakerCount(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) ValidatorWhitelistDisabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "validatorWhitelistDisabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) ValidatorWhitelistDisabled() (bool, error) { + return _ArbRollupCore.Contract.ValidatorWhitelistDisabled(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) ValidatorWhitelistDisabled() (bool, error) { + return _ArbRollupCore.Contract.ValidatorWhitelistDisabled(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) WasmModuleRoot(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "wasmModuleRoot") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) WasmModuleRoot() ([32]byte, error) { + return _ArbRollupCore.Contract.WasmModuleRoot(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) WasmModuleRoot() ([32]byte, error) { + return _ArbRollupCore.Contract.WasmModuleRoot(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) WithdrawableFunds(opts *bind.CallOpts, owner common.Address) (*big.Int, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "withdrawableFunds", owner) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) WithdrawableFunds(owner common.Address) (*big.Int, error) { + return _ArbRollupCore.Contract.WithdrawableFunds(&_ArbRollupCore.CallOpts, owner) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) WithdrawableFunds(owner common.Address) (*big.Int, error) { + return _ArbRollupCore.Contract.WithdrawableFunds(&_ArbRollupCore.CallOpts, owner) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) ZombieAddress(opts *bind.CallOpts, zombieNum *big.Int) (common.Address, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "zombieAddress", zombieNum) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) ZombieAddress(zombieNum *big.Int) (common.Address, error) { + return _ArbRollupCore.Contract.ZombieAddress(&_ArbRollupCore.CallOpts, zombieNum) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) ZombieAddress(zombieNum *big.Int) (common.Address, error) { + return _ArbRollupCore.Contract.ZombieAddress(&_ArbRollupCore.CallOpts, zombieNum) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) ZombieCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "zombieCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) ZombieCount() (*big.Int, error) { + return _ArbRollupCore.Contract.ZombieCount(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) ZombieCount() (*big.Int, error) { + return _ArbRollupCore.Contract.ZombieCount(&_ArbRollupCore.CallOpts) +} + +func (_ArbRollupCore *ArbRollupCoreCaller) ZombieLatestStakedNode(opts *bind.CallOpts, zombieNum *big.Int) (uint64, error) { + var out []interface{} + err := _ArbRollupCore.contract.Call(opts, &out, "zombieLatestStakedNode", zombieNum) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_ArbRollupCore *ArbRollupCoreSession) ZombieLatestStakedNode(zombieNum *big.Int) (uint64, error) { + return _ArbRollupCore.Contract.ZombieLatestStakedNode(&_ArbRollupCore.CallOpts, zombieNum) +} + +func (_ArbRollupCore *ArbRollupCoreCallerSession) ZombieLatestStakedNode(zombieNum *big.Int) (uint64, error) { + return _ArbRollupCore.Contract.ZombieLatestStakedNode(&_ArbRollupCore.CallOpts, zombieNum) +} + +type ArbRollupCoreNodeConfirmedIterator struct { + Event *ArbRollupCoreNodeConfirmed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbRollupCoreNodeConfirmedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreNodeConfirmed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreNodeConfirmed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbRollupCoreNodeConfirmedIterator) Error() error { + return it.fail +} + +func (it *ArbRollupCoreNodeConfirmedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbRollupCoreNodeConfirmed struct { + NodeNum uint64 + BlockHash [32]byte + SendRoot [32]byte + Raw types.Log +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) FilterNodeConfirmed(opts *bind.FilterOpts, nodeNum []uint64) (*ArbRollupCoreNodeConfirmedIterator, error) { + + var nodeNumRule []interface{} + for _, nodeNumItem := range nodeNum { + nodeNumRule = append(nodeNumRule, nodeNumItem) + } + + logs, sub, err := _ArbRollupCore.contract.FilterLogs(opts, "NodeConfirmed", nodeNumRule) + if err != nil { + return nil, err + } + return &ArbRollupCoreNodeConfirmedIterator{contract: _ArbRollupCore.contract, event: "NodeConfirmed", logs: logs, sub: sub}, nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) WatchNodeConfirmed(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreNodeConfirmed, nodeNum []uint64) (event.Subscription, error) { + + var nodeNumRule []interface{} + for _, nodeNumItem := range nodeNum { + nodeNumRule = append(nodeNumRule, nodeNumItem) + } + + logs, sub, err := _ArbRollupCore.contract.WatchLogs(opts, "NodeConfirmed", nodeNumRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbRollupCoreNodeConfirmed) + if err := _ArbRollupCore.contract.UnpackLog(event, "NodeConfirmed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) ParseNodeConfirmed(log types.Log) (*ArbRollupCoreNodeConfirmed, error) { + event := new(ArbRollupCoreNodeConfirmed) + if err := _ArbRollupCore.contract.UnpackLog(event, "NodeConfirmed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ArbRollupCoreNodeCreatedIterator struct { + Event *ArbRollupCoreNodeCreated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbRollupCoreNodeCreatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreNodeCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreNodeCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbRollupCoreNodeCreatedIterator) Error() error { + return it.fail +} + +func (it *ArbRollupCoreNodeCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbRollupCoreNodeCreated struct { + NodeNum uint64 + ParentNodeHash [32]byte + NodeHash [32]byte + ExecutionHash [32]byte + Assertion Assertion + AfterInboxBatchAcc [32]byte + WasmModuleRoot [32]byte + InboxMaxCount *big.Int + Raw types.Log +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) FilterNodeCreated(opts *bind.FilterOpts, nodeNum []uint64, parentNodeHash [][32]byte, nodeHash [][32]byte) (*ArbRollupCoreNodeCreatedIterator, error) { + + var nodeNumRule []interface{} + for _, nodeNumItem := range nodeNum { + nodeNumRule = append(nodeNumRule, nodeNumItem) + } + var parentNodeHashRule []interface{} + for _, parentNodeHashItem := range parentNodeHash { + parentNodeHashRule = append(parentNodeHashRule, parentNodeHashItem) + } + var nodeHashRule []interface{} + for _, nodeHashItem := range nodeHash { + nodeHashRule = append(nodeHashRule, nodeHashItem) + } + + logs, sub, err := _ArbRollupCore.contract.FilterLogs(opts, "NodeCreated", nodeNumRule, parentNodeHashRule, nodeHashRule) + if err != nil { + return nil, err + } + return &ArbRollupCoreNodeCreatedIterator{contract: _ArbRollupCore.contract, event: "NodeCreated", logs: logs, sub: sub}, nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) WatchNodeCreated(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreNodeCreated, nodeNum []uint64, parentNodeHash [][32]byte, nodeHash [][32]byte) (event.Subscription, error) { + + var nodeNumRule []interface{} + for _, nodeNumItem := range nodeNum { + nodeNumRule = append(nodeNumRule, nodeNumItem) + } + var parentNodeHashRule []interface{} + for _, parentNodeHashItem := range parentNodeHash { + parentNodeHashRule = append(parentNodeHashRule, parentNodeHashItem) + } + var nodeHashRule []interface{} + for _, nodeHashItem := range nodeHash { + nodeHashRule = append(nodeHashRule, nodeHashItem) + } + + logs, sub, err := _ArbRollupCore.contract.WatchLogs(opts, "NodeCreated", nodeNumRule, parentNodeHashRule, nodeHashRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbRollupCoreNodeCreated) + if err := _ArbRollupCore.contract.UnpackLog(event, "NodeCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) ParseNodeCreated(log types.Log) (*ArbRollupCoreNodeCreated, error) { + event := new(ArbRollupCoreNodeCreated) + if err := _ArbRollupCore.contract.UnpackLog(event, "NodeCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ArbRollupCoreNodeRejectedIterator struct { + Event *ArbRollupCoreNodeRejected + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbRollupCoreNodeRejectedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreNodeRejected) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreNodeRejected) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbRollupCoreNodeRejectedIterator) Error() error { + return it.fail +} + +func (it *ArbRollupCoreNodeRejectedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbRollupCoreNodeRejected struct { + NodeNum uint64 + Raw types.Log +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) FilterNodeRejected(opts *bind.FilterOpts, nodeNum []uint64) (*ArbRollupCoreNodeRejectedIterator, error) { + + var nodeNumRule []interface{} + for _, nodeNumItem := range nodeNum { + nodeNumRule = append(nodeNumRule, nodeNumItem) + } + + logs, sub, err := _ArbRollupCore.contract.FilterLogs(opts, "NodeRejected", nodeNumRule) + if err != nil { + return nil, err + } + return &ArbRollupCoreNodeRejectedIterator{contract: _ArbRollupCore.contract, event: "NodeRejected", logs: logs, sub: sub}, nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) WatchNodeRejected(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreNodeRejected, nodeNum []uint64) (event.Subscription, error) { + + var nodeNumRule []interface{} + for _, nodeNumItem := range nodeNum { + nodeNumRule = append(nodeNumRule, nodeNumItem) + } + + logs, sub, err := _ArbRollupCore.contract.WatchLogs(opts, "NodeRejected", nodeNumRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbRollupCoreNodeRejected) + if err := _ArbRollupCore.contract.UnpackLog(event, "NodeRejected", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) ParseNodeRejected(log types.Log) (*ArbRollupCoreNodeRejected, error) { + event := new(ArbRollupCoreNodeRejected) + if err := _ArbRollupCore.contract.UnpackLog(event, "NodeRejected", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ArbRollupCoreRollupChallengeStartedIterator struct { + Event *ArbRollupCoreRollupChallengeStarted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbRollupCoreRollupChallengeStartedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreRollupChallengeStarted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreRollupChallengeStarted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbRollupCoreRollupChallengeStartedIterator) Error() error { + return it.fail +} + +func (it *ArbRollupCoreRollupChallengeStartedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbRollupCoreRollupChallengeStarted struct { + ChallengeIndex uint64 + Asserter common.Address + Challenger common.Address + ChallengedNode uint64 + Raw types.Log +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) FilterRollupChallengeStarted(opts *bind.FilterOpts, challengeIndex []uint64) (*ArbRollupCoreRollupChallengeStartedIterator, error) { + + var challengeIndexRule []interface{} + for _, challengeIndexItem := range challengeIndex { + challengeIndexRule = append(challengeIndexRule, challengeIndexItem) + } + + logs, sub, err := _ArbRollupCore.contract.FilterLogs(opts, "RollupChallengeStarted", challengeIndexRule) + if err != nil { + return nil, err + } + return &ArbRollupCoreRollupChallengeStartedIterator{contract: _ArbRollupCore.contract, event: "RollupChallengeStarted", logs: logs, sub: sub}, nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) WatchRollupChallengeStarted(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreRollupChallengeStarted, challengeIndex []uint64) (event.Subscription, error) { + + var challengeIndexRule []interface{} + for _, challengeIndexItem := range challengeIndex { + challengeIndexRule = append(challengeIndexRule, challengeIndexItem) + } + + logs, sub, err := _ArbRollupCore.contract.WatchLogs(opts, "RollupChallengeStarted", challengeIndexRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbRollupCoreRollupChallengeStarted) + if err := _ArbRollupCore.contract.UnpackLog(event, "RollupChallengeStarted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) ParseRollupChallengeStarted(log types.Log) (*ArbRollupCoreRollupChallengeStarted, error) { + event := new(ArbRollupCoreRollupChallengeStarted) + if err := _ArbRollupCore.contract.UnpackLog(event, "RollupChallengeStarted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ArbRollupCoreRollupInitializedIterator struct { + Event *ArbRollupCoreRollupInitialized + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbRollupCoreRollupInitializedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreRollupInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreRollupInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbRollupCoreRollupInitializedIterator) Error() error { + return it.fail +} + +func (it *ArbRollupCoreRollupInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbRollupCoreRollupInitialized struct { + MachineHash [32]byte + ChainId *big.Int + Raw types.Log +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) FilterRollupInitialized(opts *bind.FilterOpts) (*ArbRollupCoreRollupInitializedIterator, error) { + + logs, sub, err := _ArbRollupCore.contract.FilterLogs(opts, "RollupInitialized") + if err != nil { + return nil, err + } + return &ArbRollupCoreRollupInitializedIterator{contract: _ArbRollupCore.contract, event: "RollupInitialized", logs: logs, sub: sub}, nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) WatchRollupInitialized(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreRollupInitialized) (event.Subscription, error) { + + logs, sub, err := _ArbRollupCore.contract.WatchLogs(opts, "RollupInitialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbRollupCoreRollupInitialized) + if err := _ArbRollupCore.contract.UnpackLog(event, "RollupInitialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) ParseRollupInitialized(log types.Log) (*ArbRollupCoreRollupInitialized, error) { + event := new(ArbRollupCoreRollupInitialized) + if err := _ArbRollupCore.contract.UnpackLog(event, "RollupInitialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ArbRollupCoreUserStakeUpdatedIterator struct { + Event *ArbRollupCoreUserStakeUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbRollupCoreUserStakeUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreUserStakeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreUserStakeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbRollupCoreUserStakeUpdatedIterator) Error() error { + return it.fail +} + +func (it *ArbRollupCoreUserStakeUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbRollupCoreUserStakeUpdated struct { + User common.Address + InitialBalance *big.Int + FinalBalance *big.Int + Raw types.Log +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) FilterUserStakeUpdated(opts *bind.FilterOpts, user []common.Address) (*ArbRollupCoreUserStakeUpdatedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _ArbRollupCore.contract.FilterLogs(opts, "UserStakeUpdated", userRule) + if err != nil { + return nil, err + } + return &ArbRollupCoreUserStakeUpdatedIterator{contract: _ArbRollupCore.contract, event: "UserStakeUpdated", logs: logs, sub: sub}, nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) WatchUserStakeUpdated(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreUserStakeUpdated, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _ArbRollupCore.contract.WatchLogs(opts, "UserStakeUpdated", userRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbRollupCoreUserStakeUpdated) + if err := _ArbRollupCore.contract.UnpackLog(event, "UserStakeUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) ParseUserStakeUpdated(log types.Log) (*ArbRollupCoreUserStakeUpdated, error) { + event := new(ArbRollupCoreUserStakeUpdated) + if err := _ArbRollupCore.contract.UnpackLog(event, "UserStakeUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ArbRollupCoreUserWithdrawableFundsUpdatedIterator struct { + Event *ArbRollupCoreUserWithdrawableFundsUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbRollupCoreUserWithdrawableFundsUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreUserWithdrawableFundsUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbRollupCoreUserWithdrawableFundsUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbRollupCoreUserWithdrawableFundsUpdatedIterator) Error() error { + return it.fail +} + +func (it *ArbRollupCoreUserWithdrawableFundsUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbRollupCoreUserWithdrawableFundsUpdated struct { + User common.Address + InitialBalance *big.Int + FinalBalance *big.Int + Raw types.Log +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) FilterUserWithdrawableFundsUpdated(opts *bind.FilterOpts, user []common.Address) (*ArbRollupCoreUserWithdrawableFundsUpdatedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _ArbRollupCore.contract.FilterLogs(opts, "UserWithdrawableFundsUpdated", userRule) + if err != nil { + return nil, err + } + return &ArbRollupCoreUserWithdrawableFundsUpdatedIterator{contract: _ArbRollupCore.contract, event: "UserWithdrawableFundsUpdated", logs: logs, sub: sub}, nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) WatchUserWithdrawableFundsUpdated(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreUserWithdrawableFundsUpdated, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _ArbRollupCore.contract.WatchLogs(opts, "UserWithdrawableFundsUpdated", userRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbRollupCoreUserWithdrawableFundsUpdated) + if err := _ArbRollupCore.contract.UnpackLog(event, "UserWithdrawableFundsUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbRollupCore *ArbRollupCoreFilterer) ParseUserWithdrawableFundsUpdated(log types.Log) (*ArbRollupCoreUserWithdrawableFundsUpdated, error) { + event := new(ArbRollupCoreUserWithdrawableFundsUpdated) + if err := _ArbRollupCore.contract.UnpackLog(event, "UserWithdrawableFundsUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_ArbRollupCore *ArbRollupCore) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _ArbRollupCore.abi.Events["NodeConfirmed"].ID: + return _ArbRollupCore.ParseNodeConfirmed(log) + case _ArbRollupCore.abi.Events["NodeCreated"].ID: + return _ArbRollupCore.ParseNodeCreated(log) + case _ArbRollupCore.abi.Events["NodeRejected"].ID: + return _ArbRollupCore.ParseNodeRejected(log) + case _ArbRollupCore.abi.Events["RollupChallengeStarted"].ID: + return _ArbRollupCore.ParseRollupChallengeStarted(log) + case _ArbRollupCore.abi.Events["RollupInitialized"].ID: + return _ArbRollupCore.ParseRollupInitialized(log) + case _ArbRollupCore.abi.Events["UserStakeUpdated"].ID: + return _ArbRollupCore.ParseUserStakeUpdated(log) + case _ArbRollupCore.abi.Events["UserWithdrawableFundsUpdated"].ID: + return _ArbRollupCore.ParseUserWithdrawableFundsUpdated(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (ArbRollupCoreNodeConfirmed) Topic() common.Hash { + return common.HexToHash("0x22ef0479a7ff660660d1c2fe35f1b632cf31675c2d9378db8cec95b00d8ffa3c") +} + +func (ArbRollupCoreNodeCreated) Topic() common.Hash { + return common.HexToHash("0x4f4caa9e67fb994e349dd35d1ad0ce23053d4323f83ce11dc817b5435031d096") +} + +func (ArbRollupCoreNodeRejected) Topic() common.Hash { + return common.HexToHash("0xeaffa3d968707ec919a2fc9f31d5ab2b86c905881ff561725d5a82fc95ad4640") +} + +func (ArbRollupCoreRollupChallengeStarted) Topic() common.Hash { + return common.HexToHash("0x6db7dc2f507647d135035469b27aa79cea90582779d084a7821d6cd092cbd873") +} + +func (ArbRollupCoreRollupInitialized) Topic() common.Hash { + return common.HexToHash("0xfc1b83c11d99d08a938e0b82a0bd45f822f71ff5abf23f999c93c4533d752464") +} + +func (ArbRollupCoreUserStakeUpdated) Topic() common.Hash { + return common.HexToHash("0xebd093d389ab57f3566918d2c379a2b4d9539e8eb95efad9d5e465457833fde6") +} + +func (ArbRollupCoreUserWithdrawableFundsUpdated) Topic() common.Hash { + return common.HexToHash("0xa740af14c56e4e04a617b1de1eb20de73270decbaaead14f142aabf3038e5ae2") +} + +func (_ArbRollupCore *ArbRollupCore) Address() common.Address { + return _ArbRollupCore.address +} + +type ArbRollupCoreInterface interface { + AmountStaked(opts *bind.CallOpts, staker common.Address) (*big.Int, error) + + BaseStake(opts *bind.CallOpts) (*big.Int, error) + + Bridge(opts *bind.CallOpts) (common.Address, error) + + ChainId(opts *bind.CallOpts) (*big.Int, error) + + ChallengeManager(opts *bind.CallOpts) (common.Address, error) + + ConfirmPeriodBlocks(opts *bind.CallOpts) (uint64, error) + + CurrentChallenge(opts *bind.CallOpts, staker common.Address) (uint64, error) + + ExtraChallengeTimeBlocks(opts *bind.CallOpts) (uint64, error) + + FirstUnresolvedNode(opts *bind.CallOpts) (uint64, error) + + GetNode(opts *bind.CallOpts, nodeNum uint64) (Node, error) + + GetNodeCreationBlockForLogLookup(opts *bind.CallOpts, nodeNum uint64) (*big.Int, error) + + GetStaker(opts *bind.CallOpts, staker common.Address) (IRollupCoreStaker, error) + + GetStakerAddress(opts *bind.CallOpts, stakerNum uint64) (common.Address, error) + + IsStaked(opts *bind.CallOpts, staker common.Address) (bool, error) + + IsValidator(opts *bind.CallOpts, arg0 common.Address) (bool, error) + + IsZombie(opts *bind.CallOpts, staker common.Address) (bool, error) + + LastStakeBlock(opts *bind.CallOpts) (uint64, error) + + LatestConfirmed(opts *bind.CallOpts) (uint64, error) + + LatestNodeCreated(opts *bind.CallOpts) (uint64, error) + + LatestStakedNode(opts *bind.CallOpts, staker common.Address) (uint64, error) + + LoserStakeEscrow(opts *bind.CallOpts) (common.Address, error) + + MinimumAssertionPeriod(opts *bind.CallOpts) (*big.Int, error) + + NodeHasStaker(opts *bind.CallOpts, nodeNum uint64, staker common.Address) (bool, error) + + Outbox(opts *bind.CallOpts) (common.Address, error) + + RollupEventInbox(opts *bind.CallOpts) (common.Address, error) + + SequencerInbox(opts *bind.CallOpts) (common.Address, error) + + StakeToken(opts *bind.CallOpts) (common.Address, error) + + StakerCount(opts *bind.CallOpts) (uint64, error) + + ValidatorWhitelistDisabled(opts *bind.CallOpts) (bool, error) + + WasmModuleRoot(opts *bind.CallOpts) ([32]byte, error) + + WithdrawableFunds(opts *bind.CallOpts, owner common.Address) (*big.Int, error) + + ZombieAddress(opts *bind.CallOpts, zombieNum *big.Int) (common.Address, error) + + ZombieCount(opts *bind.CallOpts) (*big.Int, error) + + ZombieLatestStakedNode(opts *bind.CallOpts, zombieNum *big.Int) (uint64, error) + + FilterNodeConfirmed(opts *bind.FilterOpts, nodeNum []uint64) (*ArbRollupCoreNodeConfirmedIterator, error) + + WatchNodeConfirmed(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreNodeConfirmed, nodeNum []uint64) (event.Subscription, error) + + ParseNodeConfirmed(log types.Log) (*ArbRollupCoreNodeConfirmed, error) + + FilterNodeCreated(opts *bind.FilterOpts, nodeNum []uint64, parentNodeHash [][32]byte, nodeHash [][32]byte) (*ArbRollupCoreNodeCreatedIterator, error) + + WatchNodeCreated(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreNodeCreated, nodeNum []uint64, parentNodeHash [][32]byte, nodeHash [][32]byte) (event.Subscription, error) + + ParseNodeCreated(log types.Log) (*ArbRollupCoreNodeCreated, error) + + FilterNodeRejected(opts *bind.FilterOpts, nodeNum []uint64) (*ArbRollupCoreNodeRejectedIterator, error) + + WatchNodeRejected(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreNodeRejected, nodeNum []uint64) (event.Subscription, error) + + ParseNodeRejected(log types.Log) (*ArbRollupCoreNodeRejected, error) + + FilterRollupChallengeStarted(opts *bind.FilterOpts, challengeIndex []uint64) (*ArbRollupCoreRollupChallengeStartedIterator, error) + + WatchRollupChallengeStarted(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreRollupChallengeStarted, challengeIndex []uint64) (event.Subscription, error) + + ParseRollupChallengeStarted(log types.Log) (*ArbRollupCoreRollupChallengeStarted, error) + + FilterRollupInitialized(opts *bind.FilterOpts) (*ArbRollupCoreRollupInitializedIterator, error) + + WatchRollupInitialized(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreRollupInitialized) (event.Subscription, error) + + ParseRollupInitialized(log types.Log) (*ArbRollupCoreRollupInitialized, error) + + FilterUserStakeUpdated(opts *bind.FilterOpts, user []common.Address) (*ArbRollupCoreUserStakeUpdatedIterator, error) + + WatchUserStakeUpdated(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreUserStakeUpdated, user []common.Address) (event.Subscription, error) + + ParseUserStakeUpdated(log types.Log) (*ArbRollupCoreUserStakeUpdated, error) + + FilterUserWithdrawableFundsUpdated(opts *bind.FilterOpts, user []common.Address) (*ArbRollupCoreUserWithdrawableFundsUpdatedIterator, error) + + WatchUserWithdrawableFundsUpdated(opts *bind.WatchOpts, sink chan<- *ArbRollupCoreUserWithdrawableFundsUpdated, user []common.Address) (event.Subscription, error) + + ParseUserWithdrawableFundsUpdated(log types.Log) (*ArbRollupCoreUserWithdrawableFundsUpdated, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/arbitrum_token_gateway/arbitrum_token_gateway.go b/core/gethwrappers/liquiditymanager/generated/arbitrum_token_gateway/arbitrum_token_gateway.go new file mode 100644 index 0000000000..db303b881f --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/arbitrum_token_gateway/arbitrum_token_gateway.go @@ -0,0 +1,235 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package arbitrum_token_gateway + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var ArbitrumTokenGatewayMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"l1ERC20\",\"type\":\"address\"}],\"name\":\"calculateL2TokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"finalizeInboundTransfer\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"getOutboundCalldata\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_gasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"outboundTransfer\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", +} + +var ArbitrumTokenGatewayABI = ArbitrumTokenGatewayMetaData.ABI + +type ArbitrumTokenGateway struct { + address common.Address + abi abi.ABI + ArbitrumTokenGatewayCaller + ArbitrumTokenGatewayTransactor + ArbitrumTokenGatewayFilterer +} + +type ArbitrumTokenGatewayCaller struct { + contract *bind.BoundContract +} + +type ArbitrumTokenGatewayTransactor struct { + contract *bind.BoundContract +} + +type ArbitrumTokenGatewayFilterer struct { + contract *bind.BoundContract +} + +type ArbitrumTokenGatewaySession struct { + Contract *ArbitrumTokenGateway + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ArbitrumTokenGatewayCallerSession struct { + Contract *ArbitrumTokenGatewayCaller + CallOpts bind.CallOpts +} + +type ArbitrumTokenGatewayTransactorSession struct { + Contract *ArbitrumTokenGatewayTransactor + TransactOpts bind.TransactOpts +} + +type ArbitrumTokenGatewayRaw struct { + Contract *ArbitrumTokenGateway +} + +type ArbitrumTokenGatewayCallerRaw struct { + Contract *ArbitrumTokenGatewayCaller +} + +type ArbitrumTokenGatewayTransactorRaw struct { + Contract *ArbitrumTokenGatewayTransactor +} + +func NewArbitrumTokenGateway(address common.Address, backend bind.ContractBackend) (*ArbitrumTokenGateway, error) { + abi, err := abi.JSON(strings.NewReader(ArbitrumTokenGatewayABI)) + if err != nil { + return nil, err + } + contract, err := bindArbitrumTokenGateway(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ArbitrumTokenGateway{address: address, abi: abi, ArbitrumTokenGatewayCaller: ArbitrumTokenGatewayCaller{contract: contract}, ArbitrumTokenGatewayTransactor: ArbitrumTokenGatewayTransactor{contract: contract}, ArbitrumTokenGatewayFilterer: ArbitrumTokenGatewayFilterer{contract: contract}}, nil +} + +func NewArbitrumTokenGatewayCaller(address common.Address, caller bind.ContractCaller) (*ArbitrumTokenGatewayCaller, error) { + contract, err := bindArbitrumTokenGateway(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ArbitrumTokenGatewayCaller{contract: contract}, nil +} + +func NewArbitrumTokenGatewayTransactor(address common.Address, transactor bind.ContractTransactor) (*ArbitrumTokenGatewayTransactor, error) { + contract, err := bindArbitrumTokenGateway(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ArbitrumTokenGatewayTransactor{contract: contract}, nil +} + +func NewArbitrumTokenGatewayFilterer(address common.Address, filterer bind.ContractFilterer) (*ArbitrumTokenGatewayFilterer, error) { + contract, err := bindArbitrumTokenGateway(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ArbitrumTokenGatewayFilterer{contract: contract}, nil +} + +func bindArbitrumTokenGateway(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ArbitrumTokenGatewayMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumTokenGateway.Contract.ArbitrumTokenGatewayCaller.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumTokenGateway.Contract.ArbitrumTokenGatewayTransactor.contract.Transfer(opts) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumTokenGateway.Contract.ArbitrumTokenGatewayTransactor.contract.Transact(opts, method, params...) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbitrumTokenGateway.Contract.contract.Call(opts, result, method, params...) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbitrumTokenGateway.Contract.contract.Transfer(opts) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbitrumTokenGateway.Contract.contract.Transact(opts, method, params...) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayCaller) CalculateL2TokenAddress(opts *bind.CallOpts, l1ERC20 common.Address) (common.Address, error) { + var out []interface{} + err := _ArbitrumTokenGateway.contract.Call(opts, &out, "calculateL2TokenAddress", l1ERC20) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewaySession) CalculateL2TokenAddress(l1ERC20 common.Address) (common.Address, error) { + return _ArbitrumTokenGateway.Contract.CalculateL2TokenAddress(&_ArbitrumTokenGateway.CallOpts, l1ERC20) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayCallerSession) CalculateL2TokenAddress(l1ERC20 common.Address) (common.Address, error) { + return _ArbitrumTokenGateway.Contract.CalculateL2TokenAddress(&_ArbitrumTokenGateway.CallOpts, l1ERC20) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayCaller) GetOutboundCalldata(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + var out []interface{} + err := _ArbitrumTokenGateway.contract.Call(opts, &out, "getOutboundCalldata", _token, _from, _to, _amount, _data) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewaySession) GetOutboundCalldata(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + return _ArbitrumTokenGateway.Contract.GetOutboundCalldata(&_ArbitrumTokenGateway.CallOpts, _token, _from, _to, _amount, _data) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayCallerSession) GetOutboundCalldata(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + return _ArbitrumTokenGateway.Contract.GetOutboundCalldata(&_ArbitrumTokenGateway.CallOpts, _token, _from, _to, _amount, _data) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayTransactor) FinalizeInboundTransfer(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumTokenGateway.contract.Transact(opts, "finalizeInboundTransfer", _token, _from, _to, _amount, _data) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewaySession) FinalizeInboundTransfer(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumTokenGateway.Contract.FinalizeInboundTransfer(&_ArbitrumTokenGateway.TransactOpts, _token, _from, _to, _amount, _data) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayTransactorSession) FinalizeInboundTransfer(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumTokenGateway.Contract.FinalizeInboundTransfer(&_ArbitrumTokenGateway.TransactOpts, _token, _from, _to, _amount, _data) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayTransactor) OutboundTransfer(opts *bind.TransactOpts, _token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumTokenGateway.contract.Transact(opts, "outboundTransfer", _token, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewaySession) OutboundTransfer(_token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumTokenGateway.Contract.OutboundTransfer(&_ArbitrumTokenGateway.TransactOpts, _token, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGatewayTransactorSession) OutboundTransfer(_token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + return _ArbitrumTokenGateway.Contract.OutboundTransfer(&_ArbitrumTokenGateway.TransactOpts, _token, _to, _amount, _maxGas, _gasPriceBid, _data) +} + +func (_ArbitrumTokenGateway *ArbitrumTokenGateway) Address() common.Address { + return _ArbitrumTokenGateway.address +} + +type ArbitrumTokenGatewayInterface interface { + CalculateL2TokenAddress(opts *bind.CallOpts, l1ERC20 common.Address) (common.Address, error) + + GetOutboundCalldata(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) + + FinalizeInboundTransfer(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) + + OutboundTransfer(opts *bind.TransactOpts, _token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/arbsys/arbsys.go b/core/gethwrappers/liquiditymanager/generated/arbsys/arbsys.go new file mode 100644 index 0000000000..fe9eb5e75b --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/arbsys/arbsys.go @@ -0,0 +1,940 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package arbsys + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var ArbSysMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"uniqueId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"batchNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"indexInBatch\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"arbBlockNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"ethBlockNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"callvalue\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"L2ToL1Transaction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"hash\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"position\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"arbBlockNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"ethBlockNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"callvalue\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"L2ToL1Tx\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"reserved\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"position\",\"type\":\"uint256\"}],\"name\":\"SendMerkleUpdate\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"arbBlockNum\",\"type\":\"uint256\"}],\"name\":\"arbBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"arbBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"arbChainID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"arbOSVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStorageGasAvailable\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isTopLevelCall\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"unused\",\"type\":\"address\"}],\"name\":\"mapL1SenderContractAddressToL2Alias\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"myCallersAddressWithoutAliasing\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sendMerkleTreeState\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"size\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"partials\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"sendTxToL1\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wasMyCallersAddressAliased\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"withdrawEth\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", +} + +var ArbSysABI = ArbSysMetaData.ABI + +type ArbSys struct { + address common.Address + abi abi.ABI + ArbSysCaller + ArbSysTransactor + ArbSysFilterer +} + +type ArbSysCaller struct { + contract *bind.BoundContract +} + +type ArbSysTransactor struct { + contract *bind.BoundContract +} + +type ArbSysFilterer struct { + contract *bind.BoundContract +} + +type ArbSysSession struct { + Contract *ArbSys + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ArbSysCallerSession struct { + Contract *ArbSysCaller + CallOpts bind.CallOpts +} + +type ArbSysTransactorSession struct { + Contract *ArbSysTransactor + TransactOpts bind.TransactOpts +} + +type ArbSysRaw struct { + Contract *ArbSys +} + +type ArbSysCallerRaw struct { + Contract *ArbSysCaller +} + +type ArbSysTransactorRaw struct { + Contract *ArbSysTransactor +} + +func NewArbSys(address common.Address, backend bind.ContractBackend) (*ArbSys, error) { + abi, err := abi.JSON(strings.NewReader(ArbSysABI)) + if err != nil { + return nil, err + } + contract, err := bindArbSys(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ArbSys{address: address, abi: abi, ArbSysCaller: ArbSysCaller{contract: contract}, ArbSysTransactor: ArbSysTransactor{contract: contract}, ArbSysFilterer: ArbSysFilterer{contract: contract}}, nil +} + +func NewArbSysCaller(address common.Address, caller bind.ContractCaller) (*ArbSysCaller, error) { + contract, err := bindArbSys(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ArbSysCaller{contract: contract}, nil +} + +func NewArbSysTransactor(address common.Address, transactor bind.ContractTransactor) (*ArbSysTransactor, error) { + contract, err := bindArbSys(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ArbSysTransactor{contract: contract}, nil +} + +func NewArbSysFilterer(address common.Address, filterer bind.ContractFilterer) (*ArbSysFilterer, error) { + contract, err := bindArbSys(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ArbSysFilterer{contract: contract}, nil +} + +func bindArbSys(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ArbSysMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ArbSys *ArbSysRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbSys.Contract.ArbSysCaller.contract.Call(opts, result, method, params...) +} + +func (_ArbSys *ArbSysRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbSys.Contract.ArbSysTransactor.contract.Transfer(opts) +} + +func (_ArbSys *ArbSysRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbSys.Contract.ArbSysTransactor.contract.Transact(opts, method, params...) +} + +func (_ArbSys *ArbSysCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ArbSys.Contract.contract.Call(opts, result, method, params...) +} + +func (_ArbSys *ArbSysTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ArbSys.Contract.contract.Transfer(opts) +} + +func (_ArbSys *ArbSysTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ArbSys.Contract.contract.Transact(opts, method, params...) +} + +func (_ArbSys *ArbSysCaller) ArbBlockHash(opts *bind.CallOpts, arbBlockNum *big.Int) ([32]byte, error) { + var out []interface{} + err := _ArbSys.contract.Call(opts, &out, "arbBlockHash", arbBlockNum) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_ArbSys *ArbSysSession) ArbBlockHash(arbBlockNum *big.Int) ([32]byte, error) { + return _ArbSys.Contract.ArbBlockHash(&_ArbSys.CallOpts, arbBlockNum) +} + +func (_ArbSys *ArbSysCallerSession) ArbBlockHash(arbBlockNum *big.Int) ([32]byte, error) { + return _ArbSys.Contract.ArbBlockHash(&_ArbSys.CallOpts, arbBlockNum) +} + +func (_ArbSys *ArbSysCaller) ArbBlockNumber(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbSys.contract.Call(opts, &out, "arbBlockNumber") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbSys *ArbSysSession) ArbBlockNumber() (*big.Int, error) { + return _ArbSys.Contract.ArbBlockNumber(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCallerSession) ArbBlockNumber() (*big.Int, error) { + return _ArbSys.Contract.ArbBlockNumber(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCaller) ArbChainID(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbSys.contract.Call(opts, &out, "arbChainID") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbSys *ArbSysSession) ArbChainID() (*big.Int, error) { + return _ArbSys.Contract.ArbChainID(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCallerSession) ArbChainID() (*big.Int, error) { + return _ArbSys.Contract.ArbChainID(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCaller) ArbOSVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbSys.contract.Call(opts, &out, "arbOSVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbSys *ArbSysSession) ArbOSVersion() (*big.Int, error) { + return _ArbSys.Contract.ArbOSVersion(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCallerSession) ArbOSVersion() (*big.Int, error) { + return _ArbSys.Contract.ArbOSVersion(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCaller) GetStorageGasAvailable(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ArbSys.contract.Call(opts, &out, "getStorageGasAvailable") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ArbSys *ArbSysSession) GetStorageGasAvailable() (*big.Int, error) { + return _ArbSys.Contract.GetStorageGasAvailable(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCallerSession) GetStorageGasAvailable() (*big.Int, error) { + return _ArbSys.Contract.GetStorageGasAvailable(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCaller) IsTopLevelCall(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _ArbSys.contract.Call(opts, &out, "isTopLevelCall") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ArbSys *ArbSysSession) IsTopLevelCall() (bool, error) { + return _ArbSys.Contract.IsTopLevelCall(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCallerSession) IsTopLevelCall() (bool, error) { + return _ArbSys.Contract.IsTopLevelCall(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCaller) MapL1SenderContractAddressToL2Alias(opts *bind.CallOpts, sender common.Address, unused common.Address) (common.Address, error) { + var out []interface{} + err := _ArbSys.contract.Call(opts, &out, "mapL1SenderContractAddressToL2Alias", sender, unused) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbSys *ArbSysSession) MapL1SenderContractAddressToL2Alias(sender common.Address, unused common.Address) (common.Address, error) { + return _ArbSys.Contract.MapL1SenderContractAddressToL2Alias(&_ArbSys.CallOpts, sender, unused) +} + +func (_ArbSys *ArbSysCallerSession) MapL1SenderContractAddressToL2Alias(sender common.Address, unused common.Address) (common.Address, error) { + return _ArbSys.Contract.MapL1SenderContractAddressToL2Alias(&_ArbSys.CallOpts, sender, unused) +} + +func (_ArbSys *ArbSysCaller) MyCallersAddressWithoutAliasing(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ArbSys.contract.Call(opts, &out, "myCallersAddressWithoutAliasing") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ArbSys *ArbSysSession) MyCallersAddressWithoutAliasing() (common.Address, error) { + return _ArbSys.Contract.MyCallersAddressWithoutAliasing(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCallerSession) MyCallersAddressWithoutAliasing() (common.Address, error) { + return _ArbSys.Contract.MyCallersAddressWithoutAliasing(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCaller) SendMerkleTreeState(opts *bind.CallOpts) (SendMerkleTreeState, + + error) { + var out []interface{} + err := _ArbSys.contract.Call(opts, &out, "sendMerkleTreeState") + + outstruct := new(SendMerkleTreeState) + if err != nil { + return *outstruct, err + } + + outstruct.Size = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Root = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Partials = *abi.ConvertType(out[2], new([][32]byte)).(*[][32]byte) + + return *outstruct, err + +} + +func (_ArbSys *ArbSysSession) SendMerkleTreeState() (SendMerkleTreeState, + + error) { + return _ArbSys.Contract.SendMerkleTreeState(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCallerSession) SendMerkleTreeState() (SendMerkleTreeState, + + error) { + return _ArbSys.Contract.SendMerkleTreeState(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCaller) WasMyCallersAddressAliased(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _ArbSys.contract.Call(opts, &out, "wasMyCallersAddressAliased") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ArbSys *ArbSysSession) WasMyCallersAddressAliased() (bool, error) { + return _ArbSys.Contract.WasMyCallersAddressAliased(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysCallerSession) WasMyCallersAddressAliased() (bool, error) { + return _ArbSys.Contract.WasMyCallersAddressAliased(&_ArbSys.CallOpts) +} + +func (_ArbSys *ArbSysTransactor) SendTxToL1(opts *bind.TransactOpts, destination common.Address, data []byte) (*types.Transaction, error) { + return _ArbSys.contract.Transact(opts, "sendTxToL1", destination, data) +} + +func (_ArbSys *ArbSysSession) SendTxToL1(destination common.Address, data []byte) (*types.Transaction, error) { + return _ArbSys.Contract.SendTxToL1(&_ArbSys.TransactOpts, destination, data) +} + +func (_ArbSys *ArbSysTransactorSession) SendTxToL1(destination common.Address, data []byte) (*types.Transaction, error) { + return _ArbSys.Contract.SendTxToL1(&_ArbSys.TransactOpts, destination, data) +} + +func (_ArbSys *ArbSysTransactor) WithdrawEth(opts *bind.TransactOpts, destination common.Address) (*types.Transaction, error) { + return _ArbSys.contract.Transact(opts, "withdrawEth", destination) +} + +func (_ArbSys *ArbSysSession) WithdrawEth(destination common.Address) (*types.Transaction, error) { + return _ArbSys.Contract.WithdrawEth(&_ArbSys.TransactOpts, destination) +} + +func (_ArbSys *ArbSysTransactorSession) WithdrawEth(destination common.Address) (*types.Transaction, error) { + return _ArbSys.Contract.WithdrawEth(&_ArbSys.TransactOpts, destination) +} + +type ArbSysL2ToL1TransactionIterator struct { + Event *ArbSysL2ToL1Transaction + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbSysL2ToL1TransactionIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbSysL2ToL1Transaction) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbSysL2ToL1Transaction) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbSysL2ToL1TransactionIterator) Error() error { + return it.fail +} + +func (it *ArbSysL2ToL1TransactionIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbSysL2ToL1Transaction struct { + Caller common.Address + Destination common.Address + UniqueId *big.Int + BatchNumber *big.Int + IndexInBatch *big.Int + ArbBlockNum *big.Int + EthBlockNum *big.Int + Timestamp *big.Int + Callvalue *big.Int + Data []byte + Raw types.Log +} + +func (_ArbSys *ArbSysFilterer) FilterL2ToL1Transaction(opts *bind.FilterOpts, destination []common.Address, uniqueId []*big.Int, batchNumber []*big.Int) (*ArbSysL2ToL1TransactionIterator, error) { + + var destinationRule []interface{} + for _, destinationItem := range destination { + destinationRule = append(destinationRule, destinationItem) + } + var uniqueIdRule []interface{} + for _, uniqueIdItem := range uniqueId { + uniqueIdRule = append(uniqueIdRule, uniqueIdItem) + } + var batchNumberRule []interface{} + for _, batchNumberItem := range batchNumber { + batchNumberRule = append(batchNumberRule, batchNumberItem) + } + + logs, sub, err := _ArbSys.contract.FilterLogs(opts, "L2ToL1Transaction", destinationRule, uniqueIdRule, batchNumberRule) + if err != nil { + return nil, err + } + return &ArbSysL2ToL1TransactionIterator{contract: _ArbSys.contract, event: "L2ToL1Transaction", logs: logs, sub: sub}, nil +} + +func (_ArbSys *ArbSysFilterer) WatchL2ToL1Transaction(opts *bind.WatchOpts, sink chan<- *ArbSysL2ToL1Transaction, destination []common.Address, uniqueId []*big.Int, batchNumber []*big.Int) (event.Subscription, error) { + + var destinationRule []interface{} + for _, destinationItem := range destination { + destinationRule = append(destinationRule, destinationItem) + } + var uniqueIdRule []interface{} + for _, uniqueIdItem := range uniqueId { + uniqueIdRule = append(uniqueIdRule, uniqueIdItem) + } + var batchNumberRule []interface{} + for _, batchNumberItem := range batchNumber { + batchNumberRule = append(batchNumberRule, batchNumberItem) + } + + logs, sub, err := _ArbSys.contract.WatchLogs(opts, "L2ToL1Transaction", destinationRule, uniqueIdRule, batchNumberRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbSysL2ToL1Transaction) + if err := _ArbSys.contract.UnpackLog(event, "L2ToL1Transaction", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbSys *ArbSysFilterer) ParseL2ToL1Transaction(log types.Log) (*ArbSysL2ToL1Transaction, error) { + event := new(ArbSysL2ToL1Transaction) + if err := _ArbSys.contract.UnpackLog(event, "L2ToL1Transaction", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ArbSysL2ToL1TxIterator struct { + Event *ArbSysL2ToL1Tx + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbSysL2ToL1TxIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbSysL2ToL1Tx) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbSysL2ToL1Tx) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbSysL2ToL1TxIterator) Error() error { + return it.fail +} + +func (it *ArbSysL2ToL1TxIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbSysL2ToL1Tx struct { + Caller common.Address + Destination common.Address + Hash *big.Int + Position *big.Int + ArbBlockNum *big.Int + EthBlockNum *big.Int + Timestamp *big.Int + Callvalue *big.Int + Data []byte + Raw types.Log +} + +func (_ArbSys *ArbSysFilterer) FilterL2ToL1Tx(opts *bind.FilterOpts, destination []common.Address, hash []*big.Int, position []*big.Int) (*ArbSysL2ToL1TxIterator, error) { + + var destinationRule []interface{} + for _, destinationItem := range destination { + destinationRule = append(destinationRule, destinationItem) + } + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + var positionRule []interface{} + for _, positionItem := range position { + positionRule = append(positionRule, positionItem) + } + + logs, sub, err := _ArbSys.contract.FilterLogs(opts, "L2ToL1Tx", destinationRule, hashRule, positionRule) + if err != nil { + return nil, err + } + return &ArbSysL2ToL1TxIterator{contract: _ArbSys.contract, event: "L2ToL1Tx", logs: logs, sub: sub}, nil +} + +func (_ArbSys *ArbSysFilterer) WatchL2ToL1Tx(opts *bind.WatchOpts, sink chan<- *ArbSysL2ToL1Tx, destination []common.Address, hash []*big.Int, position []*big.Int) (event.Subscription, error) { + + var destinationRule []interface{} + for _, destinationItem := range destination { + destinationRule = append(destinationRule, destinationItem) + } + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + var positionRule []interface{} + for _, positionItem := range position { + positionRule = append(positionRule, positionItem) + } + + logs, sub, err := _ArbSys.contract.WatchLogs(opts, "L2ToL1Tx", destinationRule, hashRule, positionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbSysL2ToL1Tx) + if err := _ArbSys.contract.UnpackLog(event, "L2ToL1Tx", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbSys *ArbSysFilterer) ParseL2ToL1Tx(log types.Log) (*ArbSysL2ToL1Tx, error) { + event := new(ArbSysL2ToL1Tx) + if err := _ArbSys.contract.UnpackLog(event, "L2ToL1Tx", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ArbSysSendMerkleUpdateIterator struct { + Event *ArbSysSendMerkleUpdate + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ArbSysSendMerkleUpdateIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ArbSysSendMerkleUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ArbSysSendMerkleUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ArbSysSendMerkleUpdateIterator) Error() error { + return it.fail +} + +func (it *ArbSysSendMerkleUpdateIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ArbSysSendMerkleUpdate struct { + Reserved *big.Int + Hash [32]byte + Position *big.Int + Raw types.Log +} + +func (_ArbSys *ArbSysFilterer) FilterSendMerkleUpdate(opts *bind.FilterOpts, reserved []*big.Int, hash [][32]byte, position []*big.Int) (*ArbSysSendMerkleUpdateIterator, error) { + + var reservedRule []interface{} + for _, reservedItem := range reserved { + reservedRule = append(reservedRule, reservedItem) + } + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + var positionRule []interface{} + for _, positionItem := range position { + positionRule = append(positionRule, positionItem) + } + + logs, sub, err := _ArbSys.contract.FilterLogs(opts, "SendMerkleUpdate", reservedRule, hashRule, positionRule) + if err != nil { + return nil, err + } + return &ArbSysSendMerkleUpdateIterator{contract: _ArbSys.contract, event: "SendMerkleUpdate", logs: logs, sub: sub}, nil +} + +func (_ArbSys *ArbSysFilterer) WatchSendMerkleUpdate(opts *bind.WatchOpts, sink chan<- *ArbSysSendMerkleUpdate, reserved []*big.Int, hash [][32]byte, position []*big.Int) (event.Subscription, error) { + + var reservedRule []interface{} + for _, reservedItem := range reserved { + reservedRule = append(reservedRule, reservedItem) + } + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + var positionRule []interface{} + for _, positionItem := range position { + positionRule = append(positionRule, positionItem) + } + + logs, sub, err := _ArbSys.contract.WatchLogs(opts, "SendMerkleUpdate", reservedRule, hashRule, positionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ArbSysSendMerkleUpdate) + if err := _ArbSys.contract.UnpackLog(event, "SendMerkleUpdate", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ArbSys *ArbSysFilterer) ParseSendMerkleUpdate(log types.Log) (*ArbSysSendMerkleUpdate, error) { + event := new(ArbSysSendMerkleUpdate) + if err := _ArbSys.contract.UnpackLog(event, "SendMerkleUpdate", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type SendMerkleTreeState struct { + Size *big.Int + Root [32]byte + Partials [][32]byte +} + +func (_ArbSys *ArbSys) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _ArbSys.abi.Events["L2ToL1Transaction"].ID: + return _ArbSys.ParseL2ToL1Transaction(log) + case _ArbSys.abi.Events["L2ToL1Tx"].ID: + return _ArbSys.ParseL2ToL1Tx(log) + case _ArbSys.abi.Events["SendMerkleUpdate"].ID: + return _ArbSys.ParseSendMerkleUpdate(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (ArbSysL2ToL1Transaction) Topic() common.Hash { + return common.HexToHash("0x5baaa87db386365b5c161be377bc3d8e317e8d98d71a3ca7ed7d555340c8f767") +} + +func (ArbSysL2ToL1Tx) Topic() common.Hash { + return common.HexToHash("0x3e7aafa77dbf186b7fd488006beff893744caa3c4f6f299e8a709fa2087374fc") +} + +func (ArbSysSendMerkleUpdate) Topic() common.Hash { + return common.HexToHash("0xe9e13da364699fb5b0496ff5a0fc70760ad5836e93ba96568a4e42b9914a8b95") +} + +func (_ArbSys *ArbSys) Address() common.Address { + return _ArbSys.address +} + +type ArbSysInterface interface { + ArbBlockHash(opts *bind.CallOpts, arbBlockNum *big.Int) ([32]byte, error) + + ArbBlockNumber(opts *bind.CallOpts) (*big.Int, error) + + ArbChainID(opts *bind.CallOpts) (*big.Int, error) + + ArbOSVersion(opts *bind.CallOpts) (*big.Int, error) + + GetStorageGasAvailable(opts *bind.CallOpts) (*big.Int, error) + + IsTopLevelCall(opts *bind.CallOpts) (bool, error) + + MapL1SenderContractAddressToL2Alias(opts *bind.CallOpts, sender common.Address, unused common.Address) (common.Address, error) + + MyCallersAddressWithoutAliasing(opts *bind.CallOpts) (common.Address, error) + + SendMerkleTreeState(opts *bind.CallOpts) (SendMerkleTreeState, + + error) + + WasMyCallersAddressAliased(opts *bind.CallOpts) (bool, error) + + SendTxToL1(opts *bind.TransactOpts, destination common.Address, data []byte) (*types.Transaction, error) + + WithdrawEth(opts *bind.TransactOpts, destination common.Address) (*types.Transaction, error) + + FilterL2ToL1Transaction(opts *bind.FilterOpts, destination []common.Address, uniqueId []*big.Int, batchNumber []*big.Int) (*ArbSysL2ToL1TransactionIterator, error) + + WatchL2ToL1Transaction(opts *bind.WatchOpts, sink chan<- *ArbSysL2ToL1Transaction, destination []common.Address, uniqueId []*big.Int, batchNumber []*big.Int) (event.Subscription, error) + + ParseL2ToL1Transaction(log types.Log) (*ArbSysL2ToL1Transaction, error) + + FilterL2ToL1Tx(opts *bind.FilterOpts, destination []common.Address, hash []*big.Int, position []*big.Int) (*ArbSysL2ToL1TxIterator, error) + + WatchL2ToL1Tx(opts *bind.WatchOpts, sink chan<- *ArbSysL2ToL1Tx, destination []common.Address, hash []*big.Int, position []*big.Int) (event.Subscription, error) + + ParseL2ToL1Tx(log types.Log) (*ArbSysL2ToL1Tx, error) + + FilterSendMerkleUpdate(opts *bind.FilterOpts, reserved []*big.Int, hash [][32]byte, position []*big.Int) (*ArbSysSendMerkleUpdateIterator, error) + + WatchSendMerkleUpdate(opts *bind.WatchOpts, sink chan<- *ArbSysSendMerkleUpdate, reserved []*big.Int, hash [][32]byte, position []*big.Int) (event.Subscription, error) + + ParseSendMerkleUpdate(log types.Log) (*ArbSysSendMerkleUpdate, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/l2_arbitrum_gateway/l2_arbitrum_gateway.go b/core/gethwrappers/liquiditymanager/generated/l2_arbitrum_gateway/l2_arbitrum_gateway.go new file mode 100644 index 0000000000..4e5ab36f5d --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/l2_arbitrum_gateway/l2_arbitrum_gateway.go @@ -0,0 +1,823 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package l2_arbitrum_gateway + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var L2ArbitrumGatewayMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"DepositFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"TxToL1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l2ToL1Id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_exitNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawalInitiated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"l1ERC20\",\"type\":\"address\"}],\"name\":\"calculateL2TokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counterpartGateway\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"exitNum\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"finalizeInboundTransfer\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"getOutboundCalldata\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"outboundCalldata\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"outboundTransfer\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"outboundTransfer\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"res\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"postUpgradeInit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"router\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +var L2ArbitrumGatewayABI = L2ArbitrumGatewayMetaData.ABI + +type L2ArbitrumGateway struct { + address common.Address + abi abi.ABI + L2ArbitrumGatewayCaller + L2ArbitrumGatewayTransactor + L2ArbitrumGatewayFilterer +} + +type L2ArbitrumGatewayCaller struct { + contract *bind.BoundContract +} + +type L2ArbitrumGatewayTransactor struct { + contract *bind.BoundContract +} + +type L2ArbitrumGatewayFilterer struct { + contract *bind.BoundContract +} + +type L2ArbitrumGatewaySession struct { + Contract *L2ArbitrumGateway + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type L2ArbitrumGatewayCallerSession struct { + Contract *L2ArbitrumGatewayCaller + CallOpts bind.CallOpts +} + +type L2ArbitrumGatewayTransactorSession struct { + Contract *L2ArbitrumGatewayTransactor + TransactOpts bind.TransactOpts +} + +type L2ArbitrumGatewayRaw struct { + Contract *L2ArbitrumGateway +} + +type L2ArbitrumGatewayCallerRaw struct { + Contract *L2ArbitrumGatewayCaller +} + +type L2ArbitrumGatewayTransactorRaw struct { + Contract *L2ArbitrumGatewayTransactor +} + +func NewL2ArbitrumGateway(address common.Address, backend bind.ContractBackend) (*L2ArbitrumGateway, error) { + abi, err := abi.JSON(strings.NewReader(L2ArbitrumGatewayABI)) + if err != nil { + return nil, err + } + contract, err := bindL2ArbitrumGateway(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &L2ArbitrumGateway{address: address, abi: abi, L2ArbitrumGatewayCaller: L2ArbitrumGatewayCaller{contract: contract}, L2ArbitrumGatewayTransactor: L2ArbitrumGatewayTransactor{contract: contract}, L2ArbitrumGatewayFilterer: L2ArbitrumGatewayFilterer{contract: contract}}, nil +} + +func NewL2ArbitrumGatewayCaller(address common.Address, caller bind.ContractCaller) (*L2ArbitrumGatewayCaller, error) { + contract, err := bindL2ArbitrumGateway(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &L2ArbitrumGatewayCaller{contract: contract}, nil +} + +func NewL2ArbitrumGatewayTransactor(address common.Address, transactor bind.ContractTransactor) (*L2ArbitrumGatewayTransactor, error) { + contract, err := bindL2ArbitrumGateway(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &L2ArbitrumGatewayTransactor{contract: contract}, nil +} + +func NewL2ArbitrumGatewayFilterer(address common.Address, filterer bind.ContractFilterer) (*L2ArbitrumGatewayFilterer, error) { + contract, err := bindL2ArbitrumGateway(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &L2ArbitrumGatewayFilterer{contract: contract}, nil +} + +func bindL2ArbitrumGateway(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := L2ArbitrumGatewayMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _L2ArbitrumGateway.Contract.L2ArbitrumGatewayCaller.contract.Call(opts, result, method, params...) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L2ArbitrumGateway.Contract.L2ArbitrumGatewayTransactor.contract.Transfer(opts) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _L2ArbitrumGateway.Contract.L2ArbitrumGatewayTransactor.contract.Transact(opts, method, params...) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _L2ArbitrumGateway.Contract.contract.Call(opts, result, method, params...) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L2ArbitrumGateway.Contract.contract.Transfer(opts) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _L2ArbitrumGateway.Contract.contract.Transact(opts, method, params...) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayCaller) CalculateL2TokenAddress(opts *bind.CallOpts, l1ERC20 common.Address) (common.Address, error) { + var out []interface{} + err := _L2ArbitrumGateway.contract.Call(opts, &out, "calculateL2TokenAddress", l1ERC20) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewaySession) CalculateL2TokenAddress(l1ERC20 common.Address) (common.Address, error) { + return _L2ArbitrumGateway.Contract.CalculateL2TokenAddress(&_L2ArbitrumGateway.CallOpts, l1ERC20) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayCallerSession) CalculateL2TokenAddress(l1ERC20 common.Address) (common.Address, error) { + return _L2ArbitrumGateway.Contract.CalculateL2TokenAddress(&_L2ArbitrumGateway.CallOpts, l1ERC20) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayCaller) CounterpartGateway(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L2ArbitrumGateway.contract.Call(opts, &out, "counterpartGateway") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewaySession) CounterpartGateway() (common.Address, error) { + return _L2ArbitrumGateway.Contract.CounterpartGateway(&_L2ArbitrumGateway.CallOpts) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayCallerSession) CounterpartGateway() (common.Address, error) { + return _L2ArbitrumGateway.Contract.CounterpartGateway(&_L2ArbitrumGateway.CallOpts) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayCaller) ExitNum(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _L2ArbitrumGateway.contract.Call(opts, &out, "exitNum") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewaySession) ExitNum() (*big.Int, error) { + return _L2ArbitrumGateway.Contract.ExitNum(&_L2ArbitrumGateway.CallOpts) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayCallerSession) ExitNum() (*big.Int, error) { + return _L2ArbitrumGateway.Contract.ExitNum(&_L2ArbitrumGateway.CallOpts) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayCaller) GetOutboundCalldata(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + var out []interface{} + err := _L2ArbitrumGateway.contract.Call(opts, &out, "getOutboundCalldata", _token, _from, _to, _amount, _data) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewaySession) GetOutboundCalldata(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + return _L2ArbitrumGateway.Contract.GetOutboundCalldata(&_L2ArbitrumGateway.CallOpts, _token, _from, _to, _amount, _data) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayCallerSession) GetOutboundCalldata(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + return _L2ArbitrumGateway.Contract.GetOutboundCalldata(&_L2ArbitrumGateway.CallOpts, _token, _from, _to, _amount, _data) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayCaller) Router(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L2ArbitrumGateway.contract.Call(opts, &out, "router") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewaySession) Router() (common.Address, error) { + return _L2ArbitrumGateway.Contract.Router(&_L2ArbitrumGateway.CallOpts) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayCallerSession) Router() (common.Address, error) { + return _L2ArbitrumGateway.Contract.Router(&_L2ArbitrumGateway.CallOpts) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayTransactor) FinalizeInboundTransfer(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _L2ArbitrumGateway.contract.Transact(opts, "finalizeInboundTransfer", _token, _from, _to, _amount, _data) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewaySession) FinalizeInboundTransfer(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _L2ArbitrumGateway.Contract.FinalizeInboundTransfer(&_L2ArbitrumGateway.TransactOpts, _token, _from, _to, _amount, _data) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayTransactorSession) FinalizeInboundTransfer(_token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _L2ArbitrumGateway.Contract.FinalizeInboundTransfer(&_L2ArbitrumGateway.TransactOpts, _token, _from, _to, _amount, _data) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayTransactor) OutboundTransfer(opts *bind.TransactOpts, _l1Token common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _L2ArbitrumGateway.contract.Transact(opts, "outboundTransfer", _l1Token, _to, _amount, _data) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewaySession) OutboundTransfer(_l1Token common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _L2ArbitrumGateway.Contract.OutboundTransfer(&_L2ArbitrumGateway.TransactOpts, _l1Token, _to, _amount, _data) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayTransactorSession) OutboundTransfer(_l1Token common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + return _L2ArbitrumGateway.Contract.OutboundTransfer(&_L2ArbitrumGateway.TransactOpts, _l1Token, _to, _amount, _data) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayTransactor) OutboundTransfer0(opts *bind.TransactOpts, _l1Token common.Address, _to common.Address, _amount *big.Int, arg3 *big.Int, arg4 *big.Int, _data []byte) (*types.Transaction, error) { + return _L2ArbitrumGateway.contract.Transact(opts, "outboundTransfer0", _l1Token, _to, _amount, arg3, arg4, _data) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewaySession) OutboundTransfer0(_l1Token common.Address, _to common.Address, _amount *big.Int, arg3 *big.Int, arg4 *big.Int, _data []byte) (*types.Transaction, error) { + return _L2ArbitrumGateway.Contract.OutboundTransfer0(&_L2ArbitrumGateway.TransactOpts, _l1Token, _to, _amount, arg3, arg4, _data) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayTransactorSession) OutboundTransfer0(_l1Token common.Address, _to common.Address, _amount *big.Int, arg3 *big.Int, arg4 *big.Int, _data []byte) (*types.Transaction, error) { + return _L2ArbitrumGateway.Contract.OutboundTransfer0(&_L2ArbitrumGateway.TransactOpts, _l1Token, _to, _amount, arg3, arg4, _data) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayTransactor) PostUpgradeInit(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L2ArbitrumGateway.contract.Transact(opts, "postUpgradeInit") +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewaySession) PostUpgradeInit() (*types.Transaction, error) { + return _L2ArbitrumGateway.Contract.PostUpgradeInit(&_L2ArbitrumGateway.TransactOpts) +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayTransactorSession) PostUpgradeInit() (*types.Transaction, error) { + return _L2ArbitrumGateway.Contract.PostUpgradeInit(&_L2ArbitrumGateway.TransactOpts) +} + +type L2ArbitrumGatewayDepositFinalizedIterator struct { + Event *L2ArbitrumGatewayDepositFinalized + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *L2ArbitrumGatewayDepositFinalizedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(L2ArbitrumGatewayDepositFinalized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(L2ArbitrumGatewayDepositFinalized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *L2ArbitrumGatewayDepositFinalizedIterator) Error() error { + return it.fail +} + +func (it *L2ArbitrumGatewayDepositFinalizedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type L2ArbitrumGatewayDepositFinalized struct { + L1Token common.Address + From common.Address + To common.Address + Amount *big.Int + Raw types.Log +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayFilterer) FilterDepositFinalized(opts *bind.FilterOpts, l1Token []common.Address, _from []common.Address, _to []common.Address) (*L2ArbitrumGatewayDepositFinalizedIterator, error) { + + var l1TokenRule []interface{} + for _, l1TokenItem := range l1Token { + l1TokenRule = append(l1TokenRule, l1TokenItem) + } + var _fromRule []interface{} + for _, _fromItem := range _from { + _fromRule = append(_fromRule, _fromItem) + } + var _toRule []interface{} + for _, _toItem := range _to { + _toRule = append(_toRule, _toItem) + } + + logs, sub, err := _L2ArbitrumGateway.contract.FilterLogs(opts, "DepositFinalized", l1TokenRule, _fromRule, _toRule) + if err != nil { + return nil, err + } + return &L2ArbitrumGatewayDepositFinalizedIterator{contract: _L2ArbitrumGateway.contract, event: "DepositFinalized", logs: logs, sub: sub}, nil +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayFilterer) WatchDepositFinalized(opts *bind.WatchOpts, sink chan<- *L2ArbitrumGatewayDepositFinalized, l1Token []common.Address, _from []common.Address, _to []common.Address) (event.Subscription, error) { + + var l1TokenRule []interface{} + for _, l1TokenItem := range l1Token { + l1TokenRule = append(l1TokenRule, l1TokenItem) + } + var _fromRule []interface{} + for _, _fromItem := range _from { + _fromRule = append(_fromRule, _fromItem) + } + var _toRule []interface{} + for _, _toItem := range _to { + _toRule = append(_toRule, _toItem) + } + + logs, sub, err := _L2ArbitrumGateway.contract.WatchLogs(opts, "DepositFinalized", l1TokenRule, _fromRule, _toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(L2ArbitrumGatewayDepositFinalized) + if err := _L2ArbitrumGateway.contract.UnpackLog(event, "DepositFinalized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayFilterer) ParseDepositFinalized(log types.Log) (*L2ArbitrumGatewayDepositFinalized, error) { + event := new(L2ArbitrumGatewayDepositFinalized) + if err := _L2ArbitrumGateway.contract.UnpackLog(event, "DepositFinalized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type L2ArbitrumGatewayTxToL1Iterator struct { + Event *L2ArbitrumGatewayTxToL1 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *L2ArbitrumGatewayTxToL1Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(L2ArbitrumGatewayTxToL1) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(L2ArbitrumGatewayTxToL1) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *L2ArbitrumGatewayTxToL1Iterator) Error() error { + return it.fail +} + +func (it *L2ArbitrumGatewayTxToL1Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type L2ArbitrumGatewayTxToL1 struct { + From common.Address + To common.Address + Id *big.Int + Data []byte + Raw types.Log +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayFilterer) FilterTxToL1(opts *bind.FilterOpts, _from []common.Address, _to []common.Address, _id []*big.Int) (*L2ArbitrumGatewayTxToL1Iterator, error) { + + var _fromRule []interface{} + for _, _fromItem := range _from { + _fromRule = append(_fromRule, _fromItem) + } + var _toRule []interface{} + for _, _toItem := range _to { + _toRule = append(_toRule, _toItem) + } + var _idRule []interface{} + for _, _idItem := range _id { + _idRule = append(_idRule, _idItem) + } + + logs, sub, err := _L2ArbitrumGateway.contract.FilterLogs(opts, "TxToL1", _fromRule, _toRule, _idRule) + if err != nil { + return nil, err + } + return &L2ArbitrumGatewayTxToL1Iterator{contract: _L2ArbitrumGateway.contract, event: "TxToL1", logs: logs, sub: sub}, nil +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayFilterer) WatchTxToL1(opts *bind.WatchOpts, sink chan<- *L2ArbitrumGatewayTxToL1, _from []common.Address, _to []common.Address, _id []*big.Int) (event.Subscription, error) { + + var _fromRule []interface{} + for _, _fromItem := range _from { + _fromRule = append(_fromRule, _fromItem) + } + var _toRule []interface{} + for _, _toItem := range _to { + _toRule = append(_toRule, _toItem) + } + var _idRule []interface{} + for _, _idItem := range _id { + _idRule = append(_idRule, _idItem) + } + + logs, sub, err := _L2ArbitrumGateway.contract.WatchLogs(opts, "TxToL1", _fromRule, _toRule, _idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(L2ArbitrumGatewayTxToL1) + if err := _L2ArbitrumGateway.contract.UnpackLog(event, "TxToL1", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayFilterer) ParseTxToL1(log types.Log) (*L2ArbitrumGatewayTxToL1, error) { + event := new(L2ArbitrumGatewayTxToL1) + if err := _L2ArbitrumGateway.contract.UnpackLog(event, "TxToL1", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type L2ArbitrumGatewayWithdrawalInitiatedIterator struct { + Event *L2ArbitrumGatewayWithdrawalInitiated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *L2ArbitrumGatewayWithdrawalInitiatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(L2ArbitrumGatewayWithdrawalInitiated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(L2ArbitrumGatewayWithdrawalInitiated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *L2ArbitrumGatewayWithdrawalInitiatedIterator) Error() error { + return it.fail +} + +func (it *L2ArbitrumGatewayWithdrawalInitiatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type L2ArbitrumGatewayWithdrawalInitiated struct { + L1Token common.Address + From common.Address + To common.Address + L2ToL1Id *big.Int + ExitNum *big.Int + Amount *big.Int + Raw types.Log +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayFilterer) FilterWithdrawalInitiated(opts *bind.FilterOpts, _from []common.Address, _to []common.Address, _l2ToL1Id []*big.Int) (*L2ArbitrumGatewayWithdrawalInitiatedIterator, error) { + + var _fromRule []interface{} + for _, _fromItem := range _from { + _fromRule = append(_fromRule, _fromItem) + } + var _toRule []interface{} + for _, _toItem := range _to { + _toRule = append(_toRule, _toItem) + } + var _l2ToL1IdRule []interface{} + for _, _l2ToL1IdItem := range _l2ToL1Id { + _l2ToL1IdRule = append(_l2ToL1IdRule, _l2ToL1IdItem) + } + + logs, sub, err := _L2ArbitrumGateway.contract.FilterLogs(opts, "WithdrawalInitiated", _fromRule, _toRule, _l2ToL1IdRule) + if err != nil { + return nil, err + } + return &L2ArbitrumGatewayWithdrawalInitiatedIterator{contract: _L2ArbitrumGateway.contract, event: "WithdrawalInitiated", logs: logs, sub: sub}, nil +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayFilterer) WatchWithdrawalInitiated(opts *bind.WatchOpts, sink chan<- *L2ArbitrumGatewayWithdrawalInitiated, _from []common.Address, _to []common.Address, _l2ToL1Id []*big.Int) (event.Subscription, error) { + + var _fromRule []interface{} + for _, _fromItem := range _from { + _fromRule = append(_fromRule, _fromItem) + } + var _toRule []interface{} + for _, _toItem := range _to { + _toRule = append(_toRule, _toItem) + } + var _l2ToL1IdRule []interface{} + for _, _l2ToL1IdItem := range _l2ToL1Id { + _l2ToL1IdRule = append(_l2ToL1IdRule, _l2ToL1IdItem) + } + + logs, sub, err := _L2ArbitrumGateway.contract.WatchLogs(opts, "WithdrawalInitiated", _fromRule, _toRule, _l2ToL1IdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(L2ArbitrumGatewayWithdrawalInitiated) + if err := _L2ArbitrumGateway.contract.UnpackLog(event, "WithdrawalInitiated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_L2ArbitrumGateway *L2ArbitrumGatewayFilterer) ParseWithdrawalInitiated(log types.Log) (*L2ArbitrumGatewayWithdrawalInitiated, error) { + event := new(L2ArbitrumGatewayWithdrawalInitiated) + if err := _L2ArbitrumGateway.contract.UnpackLog(event, "WithdrawalInitiated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_L2ArbitrumGateway *L2ArbitrumGateway) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _L2ArbitrumGateway.abi.Events["DepositFinalized"].ID: + return _L2ArbitrumGateway.ParseDepositFinalized(log) + case _L2ArbitrumGateway.abi.Events["TxToL1"].ID: + return _L2ArbitrumGateway.ParseTxToL1(log) + case _L2ArbitrumGateway.abi.Events["WithdrawalInitiated"].ID: + return _L2ArbitrumGateway.ParseWithdrawalInitiated(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (L2ArbitrumGatewayDepositFinalized) Topic() common.Hash { + return common.HexToHash("0xc7f2e9c55c40a50fbc217dfc70cd39a222940dfa62145aa0ca49eb9535d4fcb2") +} + +func (L2ArbitrumGatewayTxToL1) Topic() common.Hash { + return common.HexToHash("0x2b986d32a0536b7e19baa48ab949fec7b903b7fad7730820b20632d100cc3a68") +} + +func (L2ArbitrumGatewayWithdrawalInitiated) Topic() common.Hash { + return common.HexToHash("0x3073a74ecb728d10be779fe19a74a1428e20468f5b4d167bf9c73d9067847d73") +} + +func (_L2ArbitrumGateway *L2ArbitrumGateway) Address() common.Address { + return _L2ArbitrumGateway.address +} + +type L2ArbitrumGatewayInterface interface { + CalculateL2TokenAddress(opts *bind.CallOpts, l1ERC20 common.Address) (common.Address, error) + + CounterpartGateway(opts *bind.CallOpts) (common.Address, error) + + ExitNum(opts *bind.CallOpts) (*big.Int, error) + + GetOutboundCalldata(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) + + Router(opts *bind.CallOpts) (common.Address, error) + + FinalizeInboundTransfer(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) + + OutboundTransfer(opts *bind.TransactOpts, _l1Token common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) + + OutboundTransfer0(opts *bind.TransactOpts, _l1Token common.Address, _to common.Address, _amount *big.Int, arg3 *big.Int, arg4 *big.Int, _data []byte) (*types.Transaction, error) + + PostUpgradeInit(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterDepositFinalized(opts *bind.FilterOpts, l1Token []common.Address, _from []common.Address, _to []common.Address) (*L2ArbitrumGatewayDepositFinalizedIterator, error) + + WatchDepositFinalized(opts *bind.WatchOpts, sink chan<- *L2ArbitrumGatewayDepositFinalized, l1Token []common.Address, _from []common.Address, _to []common.Address) (event.Subscription, error) + + ParseDepositFinalized(log types.Log) (*L2ArbitrumGatewayDepositFinalized, error) + + FilterTxToL1(opts *bind.FilterOpts, _from []common.Address, _to []common.Address, _id []*big.Int) (*L2ArbitrumGatewayTxToL1Iterator, error) + + WatchTxToL1(opts *bind.WatchOpts, sink chan<- *L2ArbitrumGatewayTxToL1, _from []common.Address, _to []common.Address, _id []*big.Int) (event.Subscription, error) + + ParseTxToL1(log types.Log) (*L2ArbitrumGatewayTxToL1, error) + + FilterWithdrawalInitiated(opts *bind.FilterOpts, _from []common.Address, _to []common.Address, _l2ToL1Id []*big.Int) (*L2ArbitrumGatewayWithdrawalInitiatedIterator, error) + + WatchWithdrawalInitiated(opts *bind.WatchOpts, sink chan<- *L2ArbitrumGatewayWithdrawalInitiated, _from []common.Address, _to []common.Address, _l2ToL1Id []*big.Int) (event.Subscription, error) + + ParseWithdrawalInitiated(log types.Log) (*L2ArbitrumGatewayWithdrawalInitiated, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/l2_arbitrum_messenger/l2_arbitrum_messenger.go b/core/gethwrappers/liquiditymanager/generated/l2_arbitrum_messenger/l2_arbitrum_messenger.go new file mode 100644 index 0000000000..4aa2952efc --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/l2_arbitrum_messenger/l2_arbitrum_messenger.go @@ -0,0 +1,329 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package l2_arbitrum_messenger + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var L2ArbitrumMessengerMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"TxToL1\",\"type\":\"event\"}]", +} + +var L2ArbitrumMessengerABI = L2ArbitrumMessengerMetaData.ABI + +type L2ArbitrumMessenger struct { + address common.Address + abi abi.ABI + L2ArbitrumMessengerCaller + L2ArbitrumMessengerTransactor + L2ArbitrumMessengerFilterer +} + +type L2ArbitrumMessengerCaller struct { + contract *bind.BoundContract +} + +type L2ArbitrumMessengerTransactor struct { + contract *bind.BoundContract +} + +type L2ArbitrumMessengerFilterer struct { + contract *bind.BoundContract +} + +type L2ArbitrumMessengerSession struct { + Contract *L2ArbitrumMessenger + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type L2ArbitrumMessengerCallerSession struct { + Contract *L2ArbitrumMessengerCaller + CallOpts bind.CallOpts +} + +type L2ArbitrumMessengerTransactorSession struct { + Contract *L2ArbitrumMessengerTransactor + TransactOpts bind.TransactOpts +} + +type L2ArbitrumMessengerRaw struct { + Contract *L2ArbitrumMessenger +} + +type L2ArbitrumMessengerCallerRaw struct { + Contract *L2ArbitrumMessengerCaller +} + +type L2ArbitrumMessengerTransactorRaw struct { + Contract *L2ArbitrumMessengerTransactor +} + +func NewL2ArbitrumMessenger(address common.Address, backend bind.ContractBackend) (*L2ArbitrumMessenger, error) { + abi, err := abi.JSON(strings.NewReader(L2ArbitrumMessengerABI)) + if err != nil { + return nil, err + } + contract, err := bindL2ArbitrumMessenger(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &L2ArbitrumMessenger{address: address, abi: abi, L2ArbitrumMessengerCaller: L2ArbitrumMessengerCaller{contract: contract}, L2ArbitrumMessengerTransactor: L2ArbitrumMessengerTransactor{contract: contract}, L2ArbitrumMessengerFilterer: L2ArbitrumMessengerFilterer{contract: contract}}, nil +} + +func NewL2ArbitrumMessengerCaller(address common.Address, caller bind.ContractCaller) (*L2ArbitrumMessengerCaller, error) { + contract, err := bindL2ArbitrumMessenger(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &L2ArbitrumMessengerCaller{contract: contract}, nil +} + +func NewL2ArbitrumMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*L2ArbitrumMessengerTransactor, error) { + contract, err := bindL2ArbitrumMessenger(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &L2ArbitrumMessengerTransactor{contract: contract}, nil +} + +func NewL2ArbitrumMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*L2ArbitrumMessengerFilterer, error) { + contract, err := bindL2ArbitrumMessenger(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &L2ArbitrumMessengerFilterer{contract: contract}, nil +} + +func bindL2ArbitrumMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := L2ArbitrumMessengerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_L2ArbitrumMessenger *L2ArbitrumMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _L2ArbitrumMessenger.Contract.L2ArbitrumMessengerCaller.contract.Call(opts, result, method, params...) +} + +func (_L2ArbitrumMessenger *L2ArbitrumMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L2ArbitrumMessenger.Contract.L2ArbitrumMessengerTransactor.contract.Transfer(opts) +} + +func (_L2ArbitrumMessenger *L2ArbitrumMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _L2ArbitrumMessenger.Contract.L2ArbitrumMessengerTransactor.contract.Transact(opts, method, params...) +} + +func (_L2ArbitrumMessenger *L2ArbitrumMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _L2ArbitrumMessenger.Contract.contract.Call(opts, result, method, params...) +} + +func (_L2ArbitrumMessenger *L2ArbitrumMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L2ArbitrumMessenger.Contract.contract.Transfer(opts) +} + +func (_L2ArbitrumMessenger *L2ArbitrumMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _L2ArbitrumMessenger.Contract.contract.Transact(opts, method, params...) +} + +type L2ArbitrumMessengerTxToL1Iterator struct { + Event *L2ArbitrumMessengerTxToL1 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *L2ArbitrumMessengerTxToL1Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(L2ArbitrumMessengerTxToL1) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(L2ArbitrumMessengerTxToL1) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *L2ArbitrumMessengerTxToL1Iterator) Error() error { + return it.fail +} + +func (it *L2ArbitrumMessengerTxToL1Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type L2ArbitrumMessengerTxToL1 struct { + From common.Address + To common.Address + Id *big.Int + Data []byte + Raw types.Log +} + +func (_L2ArbitrumMessenger *L2ArbitrumMessengerFilterer) FilterTxToL1(opts *bind.FilterOpts, _from []common.Address, _to []common.Address, _id []*big.Int) (*L2ArbitrumMessengerTxToL1Iterator, error) { + + var _fromRule []interface{} + for _, _fromItem := range _from { + _fromRule = append(_fromRule, _fromItem) + } + var _toRule []interface{} + for _, _toItem := range _to { + _toRule = append(_toRule, _toItem) + } + var _idRule []interface{} + for _, _idItem := range _id { + _idRule = append(_idRule, _idItem) + } + + logs, sub, err := _L2ArbitrumMessenger.contract.FilterLogs(opts, "TxToL1", _fromRule, _toRule, _idRule) + if err != nil { + return nil, err + } + return &L2ArbitrumMessengerTxToL1Iterator{contract: _L2ArbitrumMessenger.contract, event: "TxToL1", logs: logs, sub: sub}, nil +} + +func (_L2ArbitrumMessenger *L2ArbitrumMessengerFilterer) WatchTxToL1(opts *bind.WatchOpts, sink chan<- *L2ArbitrumMessengerTxToL1, _from []common.Address, _to []common.Address, _id []*big.Int) (event.Subscription, error) { + + var _fromRule []interface{} + for _, _fromItem := range _from { + _fromRule = append(_fromRule, _fromItem) + } + var _toRule []interface{} + for _, _toItem := range _to { + _toRule = append(_toRule, _toItem) + } + var _idRule []interface{} + for _, _idItem := range _id { + _idRule = append(_idRule, _idItem) + } + + logs, sub, err := _L2ArbitrumMessenger.contract.WatchLogs(opts, "TxToL1", _fromRule, _toRule, _idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(L2ArbitrumMessengerTxToL1) + if err := _L2ArbitrumMessenger.contract.UnpackLog(event, "TxToL1", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_L2ArbitrumMessenger *L2ArbitrumMessengerFilterer) ParseTxToL1(log types.Log) (*L2ArbitrumMessengerTxToL1, error) { + event := new(L2ArbitrumMessengerTxToL1) + if err := _L2ArbitrumMessenger.contract.UnpackLog(event, "TxToL1", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_L2ArbitrumMessenger *L2ArbitrumMessenger) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _L2ArbitrumMessenger.abi.Events["TxToL1"].ID: + return _L2ArbitrumMessenger.ParseTxToL1(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (L2ArbitrumMessengerTxToL1) Topic() common.Hash { + return common.HexToHash("0x2b986d32a0536b7e19baa48ab949fec7b903b7fad7730820b20632d100cc3a68") +} + +func (_L2ArbitrumMessenger *L2ArbitrumMessenger) Address() common.Address { + return _L2ArbitrumMessenger.address +} + +type L2ArbitrumMessengerInterface interface { + FilterTxToL1(opts *bind.FilterOpts, _from []common.Address, _to []common.Address, _id []*big.Int) (*L2ArbitrumMessengerTxToL1Iterator, error) + + WatchTxToL1(opts *bind.WatchOpts, sink chan<- *L2ArbitrumMessengerTxToL1, _from []common.Address, _to []common.Address, _id []*big.Int) (event.Subscription, error) + + ParseTxToL1(log types.Log) (*L2ArbitrumMessengerTxToL1, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/liquiditymanager/liquiditymanager.go b/core/gethwrappers/liquiditymanager/generated/liquiditymanager/liquiditymanager.go new file mode 100644 index 0000000000..6c0cfd3f6f --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/liquiditymanager/liquiditymanager.go @@ -0,0 +1,2878 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package liquiditymanager + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ILiquidityManagerCrossChainRebalancerArgs struct { + RemoteRebalancer common.Address + LocalBridge common.Address + RemoteToken common.Address + RemoteChainSelector uint64 + Enabled bool +} + +type LiquidityManagerCrossChainRebalancer struct { + RemoteRebalancer common.Address + LocalBridge common.Address + RemoteToken common.Address + Enabled bool +} + +var LiquidityManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"localChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractILiquidityContainer\",\"name\":\"localLiquidityContainer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minimumLiquidity\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"finance\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reserve\",\"type\":\"uint256\"}],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidRemoteChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"latestSequenceNumber\",\"type\":\"uint64\"}],\"name\":\"NonIncreasingSequenceNumber\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceRole\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelector\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"contractIBridgeAdapter\",\"name\":\"localBridge\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"remoteRebalancer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"CrossChainRebalancerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"ocrSeqNum\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"bridgeSpecificData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"FinalizationFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"ocrSeqNum\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"bridgeSpecificData\",\"type\":\"bytes\"}],\"name\":\"FinalizationStepCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"financeRole\",\"type\":\"address\"}],\"name\":\"FinanceRoleSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAddedToContainer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newLiquidityContainer\",\"type\":\"address\"}],\"name\":\"LiquidityContainerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remover\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemovedFromContainer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"ocrSeqNum\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"fromChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"toChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"bridgeSpecificData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"bridgeReturnData\",\"type\":\"bytes\"}],\"name\":\"LiquidityTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"MinimumLiquiditySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"}],\"name\":\"NativeDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"NativeWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"addLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllCrossChainRebalancers\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"remoteRebalancer\",\"type\":\"address\"},{\"internalType\":\"contractIBridgeAdapter\",\"name\":\"localBridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structILiquidityManager.CrossChainRebalancerArgs[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getCrossChainRebalancer\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"remoteRebalancer\",\"type\":\"address\"},{\"internalType\":\"contractIBridgeAdapter\",\"name\":\"localBridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structLiquidityManager.CrossChainRebalancer\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFinanceRole\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"currentLiquidity\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLocalLiquidityContainer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinimumLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedDestChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nativeBridgeFee\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"bridgeSpecificPayload\",\"type\":\"bytes\"}],\"name\":\"rebalanceLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"shouldWrapNative\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"bridgeSpecificPayload\",\"type\":\"bytes\"}],\"name\":\"receiveLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"removeLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"remoteRebalancer\",\"type\":\"address\"},{\"internalType\":\"contractIBridgeAdapter\",\"name\":\"localBridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structILiquidityManager.CrossChainRebalancerArgs\",\"name\":\"crossChainLiqManager\",\"type\":\"tuple\"}],\"name\":\"setCrossChainRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"remoteRebalancer\",\"type\":\"address\"},{\"internalType\":\"contractIBridgeAdapter\",\"name\":\"localBridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structILiquidityManager.CrossChainRebalancerArgs[]\",\"name\":\"crossChainRebalancers\",\"type\":\"tuple[]\"}],\"name\":\"setCrossChainRebalancers\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"finance\",\"type\":\"address\"}],\"name\":\"setFinanceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractILiquidityContainer\",\"name\":\"localLiquidityContainer\",\"type\":\"address\"}],\"name\":\"setLocalLiquidityContainer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minimumLiquidity\",\"type\":\"uint256\"}],\"name\":\"setMinimumLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR3Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"addresspayable\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60e06040523480156200001157600080fd5b5060405162004b8538038062004b85833981016040819052620000349162000239565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000175565b505046608052506001600160401b038416600003620000f05760405163f89d762960e01b815260040160405180910390fd5b6001600160a01b03851615806200010e57506001600160a01b038316155b156200012d5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0394851660a0526001600160401b0390931660c052600b80549285166001600160a01b0319938416179055600855600c8054929093169116179055620002b8565b336001600160a01b03821603620001cf5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200023657600080fd5b50565b600080600080600060a086880312156200025257600080fd5b85516200025f8162000220565b60208701519095506001600160401b03811681146200027d57600080fd5b6040870151909450620002908162000220565b606087015160808801519194509250620002aa8162000220565b809150509295509295909350565b60805160a05160c0516148576200032e6000396000818161321a01526133ef0152600081816104850152818161078201528181610a1f01528181610a6501528181611762015281816130f801528181613179015281816132a201526133400152600081816118ff015261194b01526148576000f3fe6080604052600436106101bb5760003560e01c8063791781f5116100ec578063b7e7fa051161008a578063f1c0461611610064578063f1c0461614610696578063f2fde38b146106d5578063f8c2d8fa146106f5578063fe65d5af1461071557600080fd5b8063b7e7fa051461062b578063b8ca8dd81461064b578063da9c0f961461066b57600080fd5b806383d34afe116100c657806383d34afe146105ab5780638da5cb5b146105c05780639c8f9f23146105eb578063b1dc65a41461060b57600080fd5b8063791781f51461052e57806379ba50971461055957806381ff70481461056e57600080fd5b806351c6590a116101595780636511d919116101335780636511d91914610473578063666cab8d146104cc5780636a11ee90146104ee578063706bf6451461050e57600080fd5b806351c6590a14610321578063568446e7146103415780635fc3ea0b1461045357600080fd5b80633275636e116101955780633275636e1461029f578063348759c1146102bf5780634f814d04146102e157806350a197d71461030157600080fd5b80630910a510146101ff578063181f5a7714610227578063282567b41461027d57600080fd5b366101fa57604080513481523360208201527f3c597f6ac9fe7f0ed6da50b07618f5850a642e459ad587f7fab491a71f8b0ab8910160405180910390a1005b600080fd5b34801561020b57600080fd5b50610214610737565b6040519081526020015b60405180910390f35b34801561023357600080fd5b506102706040518060400160405280601a81526020017f4c69717569646974794d616e6167657220312e302e302d64657600000000000081525081565b60405161021e91906139c6565b34801561028957600080fd5b5061029d6102983660046139e0565b6107f2565b005b3480156102ab57600080fd5b5061029d6102ba3660046139f9565b61083f565b3480156102cb57600080fd5b506102d4610853565b60405161021e9190613a11565b3480156102ed57600080fd5b5061029d6102fc366004613a81565b6108df565b34801561030d57600080fd5b5061029d61031c366004613b12565b610960565b34801561032d57600080fd5b5061029d61033c3660046139e0565b610a05565b34801561034d57600080fd5b5061040461035c366004613b83565b6040805160808101825260008082526020820181905291810182905260608101919091525067ffffffffffffffff166000908152600960209081526040918290208251608081018452815473ffffffffffffffffffffffffffffffffffffffff908116825260018301548116938201939093526002909101549182169281019290925274010000000000000000000000000000000000000000900460ff161515606082015290565b60408051825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015182169083015283830151169181019190915260609182015115159181019190915260800161021e565b34801561045f57600080fd5b5061029d61046e366004613b9e565b610b42565b34801561047f57600080fd5b506104a77f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021e565b3480156104d857600080fd5b506104e1610bb9565b60405161021e9190613c32565b3480156104fa57600080fd5b5061029d610509366004613e53565b610c27565b34801561051a57600080fd5b5061029d610529366004613a81565b61145b565b34801561053a57600080fd5b50600b5473ffffffffffffffffffffffffffffffffffffffff166104a7565b34801561056557600080fd5b5061029d61151f565b34801561057a57600080fd5b506004546002546040805163ffffffff8085168252640100000000909404909316602084015282015260600161021e565b3480156105b757600080fd5b50600854610214565b3480156105cc57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166104a7565b3480156105f757600080fd5b5061029d6106063660046139e0565b61161c565b34801561061757600080fd5b5061029d610626366004613f65565b6117bc565b34801561063757600080fd5b5061029d61064636600461401c565b611e2d565b34801561065757600080fd5b5061029d610666366004614091565b611e68565b34801561067757600080fd5b50600c5473ffffffffffffffffffffffffffffffffffffffff166104a7565b3480156106a257600080fd5b5060045468010000000000000000900467ffffffffffffffff1660405167ffffffffffffffff909116815260200161021e565b3480156106e157600080fd5b5061029d6106f0366004613a81565b611fa6565b34801561070157600080fd5b5061029d6107103660046140c1565b611fb7565b34801561072157600080fd5b5061072a612053565b60405161021e919061410c565b600b546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526000917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156107c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ed91906141a1565b905090565b6107fa612214565b600880549082905560408051828152602081018490527ff97e758c8b3d81df7b0e1b7327a6a7fcf09a41536b2d274b9103015d715f11eb910160405180910390a15050565b610847612214565b61085081612297565b50565b6060600a8054806020026020016040519081016040528092919081815260200182805480156108d557602002820191906000526020600020906000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff16815260200190600801906020826007010492830192600103820291508084116108905790505b5050505050905090565b6108e7612214565b600c80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f58024d20c07d3ebb87b192861d337d3a60995665acc5b8ce29596458b1f251709060200160405180910390a150565b600c5473ffffffffffffffffffffffffffffffffffffffff1633146109b1576040517fb2a59b2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109fe858584848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525089925067ffffffffffffffff91506126939050565b5050505050565b610a4773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612918565b600b54610a8e9073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081169116836129fa565b600b546040517feb521a4c0000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff9091169063eb521a4c90602401600060405180830381600087803b158015610afa57600080fd5b505af1158015610b0e573d6000803e3d6000fd5b50506040518392503391507f5414b81d05ac3542606f164e16a9a107d05d21e906539cc5ceb61d7b6b707eb590600090a350565b600c5473ffffffffffffffffffffffffffffffffffffffff163314610b93576040517fb2a59b2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bb473ffffffffffffffffffffffffffffffffffffffff84168284612b7c565b505050565b606060078054806020026020016040519081016040528092919081815260200182805480156108d557602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610bf3575050505050905090565b855185518560ff16601f831115610c9f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b80600003610d09576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610c96565b818314610d97576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610c96565b610da28160036141e9565b8311610e0a576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610c96565b610e12612214565b60065460005b81811015610f06576005600060068381548110610e3757610e37614206565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560078054600592919084908110610ea757610ea7614206565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600101610e18565b50895160005b818110156112d95760008c8281518110610f2857610f28614206565b6020026020010151905060006002811115610f4557610f45614235565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610f8457610f84614235565b14610feb576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610c96565b73ffffffffffffffffffffffffffffffffffffffff8116611038576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156110e8576110e8614235565b021790555090505060008c838151811061110457611104614206565b602002602001015190506000600281111561112157611121614235565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561116057611160614235565b146111c7576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610c96565b73ffffffffffffffffffffffffffffffffffffffff8116611214576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156112c4576112c4614235565b02179055509050505050806001019050610f0c565b508a516112ed9060069060208e019061389a565b5089516113019060079060208d019061389a565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c1617179055600480546113879146913091906000906113599063ffffffff16614264565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e612bd2565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055506000600460086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f60405161144599989796959493929190614287565b60405180910390a1505050505050505050505050565b611463612214565b73ffffffffffffffffffffffffffffffffffffffff81166114b0576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f07dc474694ac40123aadcd2445f1b38d2eb353edd9319dcea043548ab34990ec90600090a250565b60015473ffffffffffffffffffffffffffffffffffffffff1633146115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610c96565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600c5473ffffffffffffffffffffffffffffffffffffffff16331461166d576040517fb2a59b2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611677610737565b9050818110156116c4576040517fd54d0fc4000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260006044820152606401610c96565b600b546040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff90911690630a861f2a90602401600060405180830381600087803b15801561173057600080fd5b505af1158015611744573d6000803e3d6000fd5b5061178b92505073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690503384612b7c565b604051829033907f2bda316674f8d73d289689d7a3acdf8e353b7a142fb5a68ac2aa475104039c1890600090a35050565b60045460208901359067ffffffffffffffff6801000000000000000090910481169082161161183f57600480546040517f6e376b6600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff80851693820193909352680100000000000000009091049091166024820152604401610c96565b61184a888883612c7d565b600480547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff8416021790556040805160608101825260025480825260035460ff808216602085015261010090910416928201929092528a359182146118fc5780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610c96565b467f00000000000000000000000000000000000000000000000000000000000000001461197d576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610c96565b6040805183815267ffffffffffffffff851660208201527fe893c2681d327421d89e1cb54fbe64645b4dcea668d6826130b62cf4c6eefea2910160405180910390a160208101516119cf90600161431d565b60ff168714611a0a576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514611a43576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff80821684529293919291840191610100909104166002811115611a8657611a86614235565b6002811115611a9757611a97614235565b9052509050600281602001516002811115611ab457611ab4614235565b148015611afb57506007816000015160ff1681548110611ad657611ad6614206565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611b31576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611b3f8660206141e9565b611b4a8960206141e9565b611b568c610144614336565b611b609190614336565b611b6a9190614336565b9050368114611bae576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610c96565b5060008a8a604051611bc1929190614349565b604051908190038120611bd8918e90602001614359565b604051602081830303815290604052805190602001209050611bf8613924565b8860005b81811015611e1c5760006001858a8460208110611c1b57611c1b614206565b611c2891901a601b61431d565b8f8f86818110611c3a57611c3a614206565b905060200201358e8e87818110611c5357611c53614206565b9050602002013560405160008152602001604052604051611c90949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611cb2573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff8082168652939750919550929392840191610100909104166002811115611d3557611d35614235565b6002811115611d4657611d46614235565b9052509050600181602001516002811115611d6357611d63614235565b14611d9a576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f8110611db157611db1614206565b602002015115611ded576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f8110611e0857611e08614206565b911515602090920201525050600101611bfc565b505050505050505050505050505050565b611e35612214565b60005b81811015610bb457611e60838383818110611e5557611e55614206565b905060a00201612297565b600101611e38565b600c5473ffffffffffffffffffffffffffffffffffffffff163314611eb9576040517fb2a59b2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff168360405160006040518083038185875af1925050503d8060008114611f13576040519150601f19603f3d011682016040523d82523d6000602084013e611f18565b606091505b5050905080611f53576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805184815273ffffffffffffffffffffffffffffffffffffffff841660208201527f6b84d241b711af111ecfa0e518239e6ca212da442a76548fe8a1f4e77518256a910160405180910390a1505050565b611fae612214565b61085081612e2c565b600c5473ffffffffffffffffffffffffffffffffffffffff163314612008576040517fb2a59b2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109fe85858567ffffffffffffffff86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f2192505050565b600a5460609060008167ffffffffffffffff81111561207457612074613c45565b6040519080825280602002602001820160405280156120eb57816020015b6040805160a0810182526000808252602080830182905292820181905260608201819052608082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816120925790505b50905060005b8281101561220d576000600a828154811061210e5761210e614206565b6000918252602080832060048304015460039092166008026101000a90910467ffffffffffffffff1680835260098252604092839020835160808082018652825473ffffffffffffffffffffffffffffffffffffffff9081168352600184015481168387019081526002909401548082168489019081527401000000000000000000000000000000000000000090910460ff1615156060808601918252895160a081018b528651851681529651841698870198909852905190911696840196909652938201839052935115159281019290925285519093508590859081106121f8576121f8614206565b602090810291909101015250506001016120f1565b5092915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612295576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c96565b565b6122a76080820160608301613b83565b67ffffffffffffffff166000036122ea576040517ff89d762900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122f96020830183613a81565b73ffffffffffffffffffffffffffffffffffffffff161480612340575060006123286040830160208401613a81565b73ffffffffffffffffffffffffffffffffffffffff16145b80612370575060006123586060830160408401613a81565b73ffffffffffffffffffffffffffffffffffffffff16145b156123a7576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006009816123bc6080850160608601613b83565b67ffffffffffffffff16815260208101919091526040016000206002015473ffffffffffffffffffffffffffffffffffffffff160361244857600a6124076080830160608401613b83565b8154600181018355600092835260209092206004830401805460039093166008026101000a67ffffffffffffffff8181021990941692909316929092021790555b6040805160808101909152806124616020840184613a81565b73ffffffffffffffffffffffffffffffffffffffff16815260200182602001602081019061248f9190613a81565b73ffffffffffffffffffffffffffffffffffffffff1681526020016124ba6060840160408501613a81565b73ffffffffffffffffffffffffffffffffffffffff1681526020016124e560a084016080850161436d565b15159052600960006124fd6080850160608601613b83565b67ffffffffffffffff16815260208082019290925260409081016000208351815473ffffffffffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161783559385015160018301805491831691909516179093559083015160029091018054606094850151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00000000000000000000000000000000000000000090911692909316919091179190911790556125de9060808301908301613b83565b67ffffffffffffffff167fab9bd0e4888101232b8f09dae2952ff59a6eea4a19fbddf2a8ca7b23f0e4cb406126196040840160208501613a81565b6126296060850160408601613a81565b6126366020860186613a81565b61264660a087016080880161436d565b604051612688949392919073ffffffffffffffffffffffffffffffffffffffff9485168152928416602084015292166040820152901515606082015260800190565b60405180910390a250565b67ffffffffffffffff85166000908152600960209081526040918290208251608081018452815473ffffffffffffffffffffffffffffffffffffffff908116825260018301548116938201939093526002909101549182169281019290925274010000000000000000000000000000000000000000900460ff16151560608201819052612758576040517fc9ff038f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff87166004820152602401610c96565b602081015181516040517f38314bb200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916338314bb2916127b4913090899060040161438a565b6020604051808303816000875af192505050801561280d575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261280a918101906143cc565b60015b612896573d80801561283b576040519150601f19603f3d011682016040523d82523d6000602084013e612840565b606091505b508667ffffffffffffffff168367ffffffffffffffff167fa481d91c3f9574c23ee84fef85246354b760a0527a535d6382354e4684703ce387846040516128889291906143e9565b60405180910390a350612903565b80156128ae576128a9868489888861329a565b6128fc565b8667ffffffffffffffff168367ffffffffffffffff167f8d3121fe961b40270f336aa75feb1213f1c979a33993311c60da4dd0f24526cf876040516128f391906139c6565b60405180910390a35b50506109fe565b612910858388878761329a565b505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526129f49085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613481565b50505050565b801580612a9a57506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015612a74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a9891906141a1565b155b612b26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610c96565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610bb49084907f095ea7b30000000000000000000000000000000000000000000000000000000090606401612972565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610bb49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612972565b6000808a8a8a8a8a8a8a8a8a604051602001612bf69998979695949392919061440e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6000612c8b838501856145ab565b8051516020820151519192509081158015612ca4575080155b15612cda576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015612d7e57612d7684600001518281518110612cfe57612cfe614206565b60200260200101516040015185600001518381518110612d2057612d20614206565b60200260200101516000015186600001518481518110612d4257612d42614206565b6020026020010151602001518888600001518681518110612d6557612d65614206565b602002602001015160600151612f21565b600101612cdd565b5060005b81811015612e2357612e1b84602001518281518110612da357612da3614206565b60200260200101516020015185602001518381518110612dc557612dc5614206565b60200260200101516000015186602001518481518110612de757612de7614206565b60200260200101516060015187602001518581518110612e0957612e09614206565b60200260200101516040015189612693565b600101612d82565b50505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603612eab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c96565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612f2b610737565b60085490915080821080612f47575085612f45828461471f565b105b15612f8f576040517fd54d0fc4000000000000000000000000000000000000000000000000000000008152600481018790526024810183905260448101829052606401610c96565b67ffffffffffffffff87166000908152600960209081526040918290208251608081018452815473ffffffffffffffffffffffffffffffffffffffff908116825260018301548116938201939093526002909101549182169281019290925274010000000000000000000000000000000000000000900460ff16151560608201819052613054576040517fc9ff038f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff89166004820152602401610c96565b600b546040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690630a861f2a90602401600060405180830381600087803b1580156130c057600080fd5b505af11580156130d4573d6000803e3d6000fd5b505050602082015161311f915073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690896129fa565b6020810151604080830151835191517fa71d98b700000000000000000000000000000000000000000000000000000000815260009373ffffffffffffffffffffffffffffffffffffffff169263a71d98b7928b926131a6927f000000000000000000000000000000000000000000000000000000000000000092918f908d90600401614732565b60006040518083038185885af11580156131c4573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261320b9190810190614779565b90508867ffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168767ffffffffffffffff167f2a0b69eaf1b415ca57005b4f87582ddefc6d960325ff30dc62a9b3e1e1e5b8a885600001518c8a8760405161328794939291906147e7565b60405180910390a4505050505050505050565b8015613322577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0866040518263ffffffff1660e01b81526004016000604051808303818588803b15801561330857600080fd5b505af115801561331c573d6000803e3d6000fd5b50505050505b600b546133699073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811691168761358d565b600b546040517feb521a4c0000000000000000000000000000000000000000000000000000000081526004810187905273ffffffffffffffffffffffffffffffffffffffff9091169063eb521a4c90602401600060405180830381600087803b1580156133d557600080fd5b505af11580156133e9573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168367ffffffffffffffff168567ffffffffffffffff167f2a0b69eaf1b415ca57005b4f87582ddefc6d960325ff30dc62a9b3e1e1e5b8a83089876040518060200160405280600081525060405161347294939291906147e7565b60405180910390a45050505050565b60006134e3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661368b9092919063ffffffff16565b805190915015610bb4578080602001905181019061350191906143cc565b610bb4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610c96565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015613604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061362891906141a1565b6136329190614336565b60405173ffffffffffffffffffffffffffffffffffffffff85166024820152604481018290529091506129f49085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401612972565b606061369a84846000856136a2565b949350505050565b606082471015613734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c96565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161375d919061482e565b60006040518083038185875af1925050503d806000811461379a576040519150601f19603f3d011682016040523d82523d6000602084013e61379f565b606091505b50915091506137b0878383876137bb565b979650505050505050565b6060831561385157825160000361384a5773ffffffffffffffffffffffffffffffffffffffff85163b61384a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c96565b508161369a565b61369a83838151156138665781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9691906139c6565b828054828255906000526020600020908101928215613914579160200282015b8281111561391457825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906138ba565b50613920929150613943565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b808211156139205760008155600101613944565b60005b8381101561397357818101518382015260200161395b565b50506000910152565b60008151808452613994816020860160208601613958565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006139d9602083018461397c565b9392505050565b6000602082840312156139f257600080fd5b5035919050565b600060a08284031215613a0b57600080fd5b50919050565b6020808252825182820181905260009190848201906040850190845b81811015613a5357835167ffffffffffffffff1683529284019291840191600101613a2d565b50909695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461085057600080fd5b600060208284031215613a9357600080fd5b81356139d981613a5f565b803567ffffffffffffffff81168114613ab657600080fd5b919050565b801515811461085057600080fd5b60008083601f840112613adb57600080fd5b50813567ffffffffffffffff811115613af357600080fd5b602083019150836020828501011115613b0b57600080fd5b9250929050565b600080600080600060808688031215613b2a57600080fd5b613b3386613a9e565b9450602086013593506040860135613b4a81613abb565b9250606086013567ffffffffffffffff811115613b6657600080fd5b613b7288828901613ac9565b969995985093965092949392505050565b600060208284031215613b9557600080fd5b6139d982613a9e565b600080600060608486031215613bb357600080fd5b8335613bbe81613a5f565b9250602084013591506040840135613bd581613a5f565b809150509250925092565b60008151808452602080850194506020840160005b83811015613c2757815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613bf5565b509495945050505050565b6020815260006139d96020830184613be0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613c9757613c97613c45565b60405290565b6040805190810167ffffffffffffffff81118282101715613c9757613c97613c45565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613d0757613d07613c45565b604052919050565b600067ffffffffffffffff821115613d2957613d29613c45565b5060051b60200190565b600082601f830112613d4457600080fd5b81356020613d59613d5483613d0f565b613cc0565b8083825260208201915060208460051b870101935086841115613d7b57600080fd5b602086015b84811015613da0578035613d9381613a5f565b8352918301918301613d80565b509695505050505050565b803560ff81168114613ab657600080fd5b600067ffffffffffffffff821115613dd657613dd6613c45565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613e1357600080fd5b8135613e21613d5482613dbc565b818152846020838601011115613e3657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215613e6c57600080fd5b863567ffffffffffffffff80821115613e8457600080fd5b613e908a838b01613d33565b97506020890135915080821115613ea657600080fd5b613eb28a838b01613d33565b9650613ec060408a01613dab565b95506060890135915080821115613ed657600080fd5b613ee28a838b01613e02565b9450613ef060808a01613a9e565b935060a0890135915080821115613f0657600080fd5b50613f1389828a01613e02565b9150509295509295509295565b60008083601f840112613f3257600080fd5b50813567ffffffffffffffff811115613f4a57600080fd5b6020830191508360208260051b8501011115613b0b57600080fd5b60008060008060008060008060e0898b031215613f8157600080fd5b606089018a811115613f9257600080fd5b8998503567ffffffffffffffff80821115613fac57600080fd5b613fb88c838d01613ac9565b909950975060808b0135915080821115613fd157600080fd5b613fdd8c838d01613f20565b909750955060a08b0135915080821115613ff657600080fd5b506140038b828c01613f20565b999c989b50969995989497949560c00135949350505050565b6000806020838503121561402f57600080fd5b823567ffffffffffffffff8082111561404757600080fd5b818501915085601f83011261405b57600080fd5b81358181111561406a57600080fd5b86602060a08302850101111561407f57600080fd5b60209290920196919550909350505050565b600080604083850312156140a457600080fd5b8235915060208301356140b681613a5f565b809150509250929050565b6000806000806000608086880312156140d957600080fd5b6140e286613a9e565b94506020860135935060408601359250606086013567ffffffffffffffff811115613b6657600080fd5b602080825282518282018190526000919060409081850190868401855b82811015614194578151805173ffffffffffffffffffffffffffffffffffffffff90811686528782015181168887015286820151168686015260608082015167ffffffffffffffff169086015260809081015115159085015260a09093019290850190600101614129565b5091979650505050505050565b6000602082840312156141b357600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417614200576142006141ba565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff80831681810361427d5761427d6141ba565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526142b78184018a613be0565b905082810360808401526142cb8189613be0565b905060ff871660a084015282810360c08401526142e8818761397c565b905067ffffffffffffffff851660e084015282810361010084015261430d818561397c565b9c9b505050505050505050505050565b60ff8181168382160190811115614200576142006141ba565b80820180821115614200576142006141ba565b8183823760009101908152919050565b828152606082602083013760800192915050565b60006020828403121561437f57600080fd5b81356139d981613abb565b600073ffffffffffffffffffffffffffffffffffffffff8086168352808516602084015250606060408301526143c3606083018461397c565b95945050505050565b6000602082840312156143de57600080fd5b81516139d981613abb565b6040815260006143fc604083018561397c565b82810360208401526143c3818561397c565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526144558285018b613be0565b91508382036080850152614469828a613be0565b915060ff881660a085015283820360c0850152614486828861397c565b90861660e0850152838103610100850152905061430d818561397c565b600082601f8301126144b457600080fd5b813560206144c4613d5483613d0f565b82815260059290921b840181019181810190868411156144e357600080fd5b8286015b84811015613da057803567ffffffffffffffff808211156145085760008081fd5b81890191506080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d030112156145415760008081fd5b614549613c74565b878401358152604061455c818601613a9e565b8983015260608086013561456f81613abb565b8383015292850135928484111561458857600091508182fd5b6145968e8b86890101613e02565b908301525086525050509183019183016144e7565b600060208083850312156145be57600080fd5b823567ffffffffffffffff808211156145d657600080fd5b90840190604082870312156145ea57600080fd5b6145f2613c9d565b82358281111561460157600080fd5b8301601f8101881361461257600080fd5b8035614620613d5482613d0f565b81815260059190911b8201860190868101908a83111561463f57600080fd5b8784015b838110156146eb5780358781111561465a57600080fd5b85016080818e037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001121561468e57600080fd5b614696613c74565b8a820135815260408201358b8201526146b160608301613a9e565b60408201526080820135898111156146c95760008081fd5b6146d78f8d83860101613e02565b606083015250845250918801918801614643565b508452505050828401358281111561470257600080fd5b61470e888286016144a3565b948201949094529695505050505050565b81810381811115614200576142006141ba565b600073ffffffffffffffffffffffffffffffffffffffff8088168352808716602084015280861660408401525083606083015260a060808301526137b060a083018461397c565b60006020828403121561478b57600080fd5b815167ffffffffffffffff8111156147a257600080fd5b8201601f810184136147b357600080fd5b80516147c1613d5482613dbc565b8181528560208385010111156147d657600080fd5b6143c3826020830160208601613958565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015260806040820152600061481c608083018561397c565b82810360608401526137b0818561397c565b60008251614840818460208701613958565b919091019291505056fea164736f6c6343000818000a", +} + +var LiquidityManagerABI = LiquidityManagerMetaData.ABI + +var LiquidityManagerBin = LiquidityManagerMetaData.Bin + +func DeployLiquidityManager(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, localChainSelector uint64, localLiquidityContainer common.Address, minimumLiquidity *big.Int, finance common.Address) (common.Address, *types.Transaction, *LiquidityManager, error) { + parsed, err := LiquidityManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LiquidityManagerBin), backend, token, localChainSelector, localLiquidityContainer, minimumLiquidity, finance) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &LiquidityManager{address: address, abi: *parsed, LiquidityManagerCaller: LiquidityManagerCaller{contract: contract}, LiquidityManagerTransactor: LiquidityManagerTransactor{contract: contract}, LiquidityManagerFilterer: LiquidityManagerFilterer{contract: contract}}, nil +} + +type LiquidityManager struct { + address common.Address + abi abi.ABI + LiquidityManagerCaller + LiquidityManagerTransactor + LiquidityManagerFilterer +} + +type LiquidityManagerCaller struct { + contract *bind.BoundContract +} + +type LiquidityManagerTransactor struct { + contract *bind.BoundContract +} + +type LiquidityManagerFilterer struct { + contract *bind.BoundContract +} + +type LiquidityManagerSession struct { + Contract *LiquidityManager + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type LiquidityManagerCallerSession struct { + Contract *LiquidityManagerCaller + CallOpts bind.CallOpts +} + +type LiquidityManagerTransactorSession struct { + Contract *LiquidityManagerTransactor + TransactOpts bind.TransactOpts +} + +type LiquidityManagerRaw struct { + Contract *LiquidityManager +} + +type LiquidityManagerCallerRaw struct { + Contract *LiquidityManagerCaller +} + +type LiquidityManagerTransactorRaw struct { + Contract *LiquidityManagerTransactor +} + +func NewLiquidityManager(address common.Address, backend bind.ContractBackend) (*LiquidityManager, error) { + abi, err := abi.JSON(strings.NewReader(LiquidityManagerABI)) + if err != nil { + return nil, err + } + contract, err := bindLiquidityManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LiquidityManager{address: address, abi: abi, LiquidityManagerCaller: LiquidityManagerCaller{contract: contract}, LiquidityManagerTransactor: LiquidityManagerTransactor{contract: contract}, LiquidityManagerFilterer: LiquidityManagerFilterer{contract: contract}}, nil +} + +func NewLiquidityManagerCaller(address common.Address, caller bind.ContractCaller) (*LiquidityManagerCaller, error) { + contract, err := bindLiquidityManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LiquidityManagerCaller{contract: contract}, nil +} + +func NewLiquidityManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*LiquidityManagerTransactor, error) { + contract, err := bindLiquidityManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LiquidityManagerTransactor{contract: contract}, nil +} + +func NewLiquidityManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*LiquidityManagerFilterer, error) { + contract, err := bindLiquidityManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LiquidityManagerFilterer{contract: contract}, nil +} + +func bindLiquidityManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LiquidityManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_LiquidityManager *LiquidityManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LiquidityManager.Contract.LiquidityManagerCaller.contract.Call(opts, result, method, params...) +} + +func (_LiquidityManager *LiquidityManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LiquidityManager.Contract.LiquidityManagerTransactor.contract.Transfer(opts) +} + +func (_LiquidityManager *LiquidityManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LiquidityManager.Contract.LiquidityManagerTransactor.contract.Transact(opts, method, params...) +} + +func (_LiquidityManager *LiquidityManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LiquidityManager.Contract.contract.Call(opts, result, method, params...) +} + +func (_LiquidityManager *LiquidityManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LiquidityManager.Contract.contract.Transfer(opts) +} + +func (_LiquidityManager *LiquidityManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LiquidityManager.Contract.contract.Transact(opts, method, params...) +} + +func (_LiquidityManager *LiquidityManagerCaller) GetAllCrossChainRebalancers(opts *bind.CallOpts) ([]ILiquidityManagerCrossChainRebalancerArgs, error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "getAllCrossChainRebalancers") + + if err != nil { + return *new([]ILiquidityManagerCrossChainRebalancerArgs), err + } + + out0 := *abi.ConvertType(out[0], new([]ILiquidityManagerCrossChainRebalancerArgs)).(*[]ILiquidityManagerCrossChainRebalancerArgs) + + return out0, err + +} + +func (_LiquidityManager *LiquidityManagerSession) GetAllCrossChainRebalancers() ([]ILiquidityManagerCrossChainRebalancerArgs, error) { + return _LiquidityManager.Contract.GetAllCrossChainRebalancers(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) GetAllCrossChainRebalancers() ([]ILiquidityManagerCrossChainRebalancerArgs, error) { + return _LiquidityManager.Contract.GetAllCrossChainRebalancers(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCaller) GetCrossChainRebalancer(opts *bind.CallOpts, chainSelector uint64) (LiquidityManagerCrossChainRebalancer, error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "getCrossChainRebalancer", chainSelector) + + if err != nil { + return *new(LiquidityManagerCrossChainRebalancer), err + } + + out0 := *abi.ConvertType(out[0], new(LiquidityManagerCrossChainRebalancer)).(*LiquidityManagerCrossChainRebalancer) + + return out0, err + +} + +func (_LiquidityManager *LiquidityManagerSession) GetCrossChainRebalancer(chainSelector uint64) (LiquidityManagerCrossChainRebalancer, error) { + return _LiquidityManager.Contract.GetCrossChainRebalancer(&_LiquidityManager.CallOpts, chainSelector) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) GetCrossChainRebalancer(chainSelector uint64) (LiquidityManagerCrossChainRebalancer, error) { + return _LiquidityManager.Contract.GetCrossChainRebalancer(&_LiquidityManager.CallOpts, chainSelector) +} + +func (_LiquidityManager *LiquidityManagerCaller) GetFinanceRole(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "getFinanceRole") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LiquidityManager *LiquidityManagerSession) GetFinanceRole() (common.Address, error) { + return _LiquidityManager.Contract.GetFinanceRole(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) GetFinanceRole() (common.Address, error) { + return _LiquidityManager.Contract.GetFinanceRole(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCaller) GetLiquidity(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "getLiquidity") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LiquidityManager *LiquidityManagerSession) GetLiquidity() (*big.Int, error) { + return _LiquidityManager.Contract.GetLiquidity(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) GetLiquidity() (*big.Int, error) { + return _LiquidityManager.Contract.GetLiquidity(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCaller) GetLocalLiquidityContainer(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "getLocalLiquidityContainer") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LiquidityManager *LiquidityManagerSession) GetLocalLiquidityContainer() (common.Address, error) { + return _LiquidityManager.Contract.GetLocalLiquidityContainer(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) GetLocalLiquidityContainer() (common.Address, error) { + return _LiquidityManager.Contract.GetLocalLiquidityContainer(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCaller) GetMinimumLiquidity(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "getMinimumLiquidity") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LiquidityManager *LiquidityManagerSession) GetMinimumLiquidity() (*big.Int, error) { + return _LiquidityManager.Contract.GetMinimumLiquidity(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) GetMinimumLiquidity() (*big.Int, error) { + return _LiquidityManager.Contract.GetMinimumLiquidity(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCaller) GetSupportedDestChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "getSupportedDestChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_LiquidityManager *LiquidityManagerSession) GetSupportedDestChains() ([]uint64, error) { + return _LiquidityManager.Contract.GetSupportedDestChains(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) GetSupportedDestChains() ([]uint64, error) { + return _LiquidityManager.Contract.GetSupportedDestChains(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCaller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_LiquidityManager *LiquidityManagerSession) GetTransmitters() ([]common.Address, error) { + return _LiquidityManager.Contract.GetTransmitters(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) GetTransmitters() ([]common.Address, error) { + return _LiquidityManager.Contract.GetTransmitters(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCaller) ILocalToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "i_localToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LiquidityManager *LiquidityManagerSession) ILocalToken() (common.Address, error) { + return _LiquidityManager.Contract.ILocalToken(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) ILocalToken() (common.Address, error) { + return _LiquidityManager.Contract.ILocalToken(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_LiquidityManager *LiquidityManagerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _LiquidityManager.Contract.LatestConfigDetails(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _LiquidityManager.Contract.LatestConfigDetails(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCaller) LatestSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "latestSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_LiquidityManager *LiquidityManagerSession) LatestSequenceNumber() (uint64, error) { + return _LiquidityManager.Contract.LatestSequenceNumber(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) LatestSequenceNumber() (uint64, error) { + return _LiquidityManager.Contract.LatestSequenceNumber(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LiquidityManager *LiquidityManagerSession) Owner() (common.Address, error) { + return _LiquidityManager.Contract.Owner(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) Owner() (common.Address, error) { + return _LiquidityManager.Contract.Owner(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _LiquidityManager.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_LiquidityManager *LiquidityManagerSession) TypeAndVersion() (string, error) { + return _LiquidityManager.Contract.TypeAndVersion(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerCallerSession) TypeAndVersion() (string, error) { + return _LiquidityManager.Contract.TypeAndVersion(&_LiquidityManager.CallOpts) +} + +func (_LiquidityManager *LiquidityManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "acceptOwnership") +} + +func (_LiquidityManager *LiquidityManagerSession) AcceptOwnership() (*types.Transaction, error) { + return _LiquidityManager.Contract.AcceptOwnership(&_LiquidityManager.TransactOpts) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _LiquidityManager.Contract.AcceptOwnership(&_LiquidityManager.TransactOpts) +} + +func (_LiquidityManager *LiquidityManagerTransactor) AddLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "addLiquidity", amount) +} + +func (_LiquidityManager *LiquidityManagerSession) AddLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LiquidityManager.Contract.AddLiquidity(&_LiquidityManager.TransactOpts, amount) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) AddLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LiquidityManager.Contract.AddLiquidity(&_LiquidityManager.TransactOpts, amount) +} + +func (_LiquidityManager *LiquidityManagerTransactor) RebalanceLiquidity(opts *bind.TransactOpts, chainSelector uint64, amount *big.Int, nativeBridgeFee *big.Int, bridgeSpecificPayload []byte) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "rebalanceLiquidity", chainSelector, amount, nativeBridgeFee, bridgeSpecificPayload) +} + +func (_LiquidityManager *LiquidityManagerSession) RebalanceLiquidity(chainSelector uint64, amount *big.Int, nativeBridgeFee *big.Int, bridgeSpecificPayload []byte) (*types.Transaction, error) { + return _LiquidityManager.Contract.RebalanceLiquidity(&_LiquidityManager.TransactOpts, chainSelector, amount, nativeBridgeFee, bridgeSpecificPayload) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) RebalanceLiquidity(chainSelector uint64, amount *big.Int, nativeBridgeFee *big.Int, bridgeSpecificPayload []byte) (*types.Transaction, error) { + return _LiquidityManager.Contract.RebalanceLiquidity(&_LiquidityManager.TransactOpts, chainSelector, amount, nativeBridgeFee, bridgeSpecificPayload) +} + +func (_LiquidityManager *LiquidityManagerTransactor) ReceiveLiquidity(opts *bind.TransactOpts, remoteChainSelector uint64, amount *big.Int, shouldWrapNative bool, bridgeSpecificPayload []byte) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "receiveLiquidity", remoteChainSelector, amount, shouldWrapNative, bridgeSpecificPayload) +} + +func (_LiquidityManager *LiquidityManagerSession) ReceiveLiquidity(remoteChainSelector uint64, amount *big.Int, shouldWrapNative bool, bridgeSpecificPayload []byte) (*types.Transaction, error) { + return _LiquidityManager.Contract.ReceiveLiquidity(&_LiquidityManager.TransactOpts, remoteChainSelector, amount, shouldWrapNative, bridgeSpecificPayload) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) ReceiveLiquidity(remoteChainSelector uint64, amount *big.Int, shouldWrapNative bool, bridgeSpecificPayload []byte) (*types.Transaction, error) { + return _LiquidityManager.Contract.ReceiveLiquidity(&_LiquidityManager.TransactOpts, remoteChainSelector, amount, shouldWrapNative, bridgeSpecificPayload) +} + +func (_LiquidityManager *LiquidityManagerTransactor) RemoveLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "removeLiquidity", amount) +} + +func (_LiquidityManager *LiquidityManagerSession) RemoveLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LiquidityManager.Contract.RemoveLiquidity(&_LiquidityManager.TransactOpts, amount) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) RemoveLiquidity(amount *big.Int) (*types.Transaction, error) { + return _LiquidityManager.Contract.RemoveLiquidity(&_LiquidityManager.TransactOpts, amount) +} + +func (_LiquidityManager *LiquidityManagerTransactor) SetCrossChainRebalancer(opts *bind.TransactOpts, crossChainLiqManager ILiquidityManagerCrossChainRebalancerArgs) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "setCrossChainRebalancer", crossChainLiqManager) +} + +func (_LiquidityManager *LiquidityManagerSession) SetCrossChainRebalancer(crossChainLiqManager ILiquidityManagerCrossChainRebalancerArgs) (*types.Transaction, error) { + return _LiquidityManager.Contract.SetCrossChainRebalancer(&_LiquidityManager.TransactOpts, crossChainLiqManager) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) SetCrossChainRebalancer(crossChainLiqManager ILiquidityManagerCrossChainRebalancerArgs) (*types.Transaction, error) { + return _LiquidityManager.Contract.SetCrossChainRebalancer(&_LiquidityManager.TransactOpts, crossChainLiqManager) +} + +func (_LiquidityManager *LiquidityManagerTransactor) SetCrossChainRebalancers(opts *bind.TransactOpts, crossChainRebalancers []ILiquidityManagerCrossChainRebalancerArgs) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "setCrossChainRebalancers", crossChainRebalancers) +} + +func (_LiquidityManager *LiquidityManagerSession) SetCrossChainRebalancers(crossChainRebalancers []ILiquidityManagerCrossChainRebalancerArgs) (*types.Transaction, error) { + return _LiquidityManager.Contract.SetCrossChainRebalancers(&_LiquidityManager.TransactOpts, crossChainRebalancers) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) SetCrossChainRebalancers(crossChainRebalancers []ILiquidityManagerCrossChainRebalancerArgs) (*types.Transaction, error) { + return _LiquidityManager.Contract.SetCrossChainRebalancers(&_LiquidityManager.TransactOpts, crossChainRebalancers) +} + +func (_LiquidityManager *LiquidityManagerTransactor) SetFinanceRole(opts *bind.TransactOpts, finance common.Address) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "setFinanceRole", finance) +} + +func (_LiquidityManager *LiquidityManagerSession) SetFinanceRole(finance common.Address) (*types.Transaction, error) { + return _LiquidityManager.Contract.SetFinanceRole(&_LiquidityManager.TransactOpts, finance) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) SetFinanceRole(finance common.Address) (*types.Transaction, error) { + return _LiquidityManager.Contract.SetFinanceRole(&_LiquidityManager.TransactOpts, finance) +} + +func (_LiquidityManager *LiquidityManagerTransactor) SetLocalLiquidityContainer(opts *bind.TransactOpts, localLiquidityContainer common.Address) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "setLocalLiquidityContainer", localLiquidityContainer) +} + +func (_LiquidityManager *LiquidityManagerSession) SetLocalLiquidityContainer(localLiquidityContainer common.Address) (*types.Transaction, error) { + return _LiquidityManager.Contract.SetLocalLiquidityContainer(&_LiquidityManager.TransactOpts, localLiquidityContainer) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) SetLocalLiquidityContainer(localLiquidityContainer common.Address) (*types.Transaction, error) { + return _LiquidityManager.Contract.SetLocalLiquidityContainer(&_LiquidityManager.TransactOpts, localLiquidityContainer) +} + +func (_LiquidityManager *LiquidityManagerTransactor) SetMinimumLiquidity(opts *bind.TransactOpts, minimumLiquidity *big.Int) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "setMinimumLiquidity", minimumLiquidity) +} + +func (_LiquidityManager *LiquidityManagerSession) SetMinimumLiquidity(minimumLiquidity *big.Int) (*types.Transaction, error) { + return _LiquidityManager.Contract.SetMinimumLiquidity(&_LiquidityManager.TransactOpts, minimumLiquidity) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) SetMinimumLiquidity(minimumLiquidity *big.Int) (*types.Transaction, error) { + return _LiquidityManager.Contract.SetMinimumLiquidity(&_LiquidityManager.TransactOpts, minimumLiquidity) +} + +func (_LiquidityManager *LiquidityManagerTransactor) SetOCR3Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "setOCR3Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_LiquidityManager *LiquidityManagerSession) SetOCR3Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _LiquidityManager.Contract.SetOCR3Config(&_LiquidityManager.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) SetOCR3Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _LiquidityManager.Contract.SetOCR3Config(&_LiquidityManager.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_LiquidityManager *LiquidityManagerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "transferOwnership", to) +} + +func (_LiquidityManager *LiquidityManagerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LiquidityManager.Contract.TransferOwnership(&_LiquidityManager.TransactOpts, to) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LiquidityManager.Contract.TransferOwnership(&_LiquidityManager.TransactOpts, to) +} + +func (_LiquidityManager *LiquidityManagerTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) +} + +func (_LiquidityManager *LiquidityManagerSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _LiquidityManager.Contract.Transmit(&_LiquidityManager.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _LiquidityManager.Contract.Transmit(&_LiquidityManager.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_LiquidityManager *LiquidityManagerTransactor) WithdrawERC20(opts *bind.TransactOpts, token common.Address, amount *big.Int, destination common.Address) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "withdrawERC20", token, amount, destination) +} + +func (_LiquidityManager *LiquidityManagerSession) WithdrawERC20(token common.Address, amount *big.Int, destination common.Address) (*types.Transaction, error) { + return _LiquidityManager.Contract.WithdrawERC20(&_LiquidityManager.TransactOpts, token, amount, destination) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) WithdrawERC20(token common.Address, amount *big.Int, destination common.Address) (*types.Transaction, error) { + return _LiquidityManager.Contract.WithdrawERC20(&_LiquidityManager.TransactOpts, token, amount, destination) +} + +func (_LiquidityManager *LiquidityManagerTransactor) WithdrawNative(opts *bind.TransactOpts, amount *big.Int, destination common.Address) (*types.Transaction, error) { + return _LiquidityManager.contract.Transact(opts, "withdrawNative", amount, destination) +} + +func (_LiquidityManager *LiquidityManagerSession) WithdrawNative(amount *big.Int, destination common.Address) (*types.Transaction, error) { + return _LiquidityManager.Contract.WithdrawNative(&_LiquidityManager.TransactOpts, amount, destination) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) WithdrawNative(amount *big.Int, destination common.Address) (*types.Transaction, error) { + return _LiquidityManager.Contract.WithdrawNative(&_LiquidityManager.TransactOpts, amount, destination) +} + +func (_LiquidityManager *LiquidityManagerTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LiquidityManager.contract.RawTransact(opts, nil) +} + +func (_LiquidityManager *LiquidityManagerSession) Receive() (*types.Transaction, error) { + return _LiquidityManager.Contract.Receive(&_LiquidityManager.TransactOpts) +} + +func (_LiquidityManager *LiquidityManagerTransactorSession) Receive() (*types.Transaction, error) { + return _LiquidityManager.Contract.Receive(&_LiquidityManager.TransactOpts) +} + +type LiquidityManagerConfigSetIterator struct { + Event *LiquidityManagerConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerConfigSetIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerConfigSet struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterConfigSet(opts *bind.FilterOpts) (*LiquidityManagerConfigSetIterator, error) { + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &LiquidityManagerConfigSetIterator{contract: _LiquidityManager.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *LiquidityManagerConfigSet) (event.Subscription, error) { + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerConfigSet) + if err := _LiquidityManager.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseConfigSet(log types.Log) (*LiquidityManagerConfigSet, error) { + event := new(LiquidityManagerConfigSet) + if err := _LiquidityManager.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerCrossChainRebalancerSetIterator struct { + Event *LiquidityManagerCrossChainRebalancerSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerCrossChainRebalancerSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerCrossChainRebalancerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerCrossChainRebalancerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerCrossChainRebalancerSetIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerCrossChainRebalancerSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerCrossChainRebalancerSet struct { + RemoteChainSelector uint64 + LocalBridge common.Address + RemoteToken common.Address + RemoteRebalancer common.Address + Enabled bool + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterCrossChainRebalancerSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*LiquidityManagerCrossChainRebalancerSetIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "CrossChainRebalancerSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &LiquidityManagerCrossChainRebalancerSetIterator{contract: _LiquidityManager.contract, event: "CrossChainRebalancerSet", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchCrossChainRebalancerSet(opts *bind.WatchOpts, sink chan<- *LiquidityManagerCrossChainRebalancerSet, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "CrossChainRebalancerSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerCrossChainRebalancerSet) + if err := _LiquidityManager.contract.UnpackLog(event, "CrossChainRebalancerSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseCrossChainRebalancerSet(log types.Log) (*LiquidityManagerCrossChainRebalancerSet, error) { + event := new(LiquidityManagerCrossChainRebalancerSet) + if err := _LiquidityManager.contract.UnpackLog(event, "CrossChainRebalancerSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerFinalizationFailedIterator struct { + Event *LiquidityManagerFinalizationFailed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerFinalizationFailedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerFinalizationFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerFinalizationFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerFinalizationFailedIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerFinalizationFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerFinalizationFailed struct { + OcrSeqNum uint64 + RemoteChainSelector uint64 + BridgeSpecificData []byte + Reason []byte + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterFinalizationFailed(opts *bind.FilterOpts, ocrSeqNum []uint64, remoteChainSelector []uint64) (*LiquidityManagerFinalizationFailedIterator, error) { + + var ocrSeqNumRule []interface{} + for _, ocrSeqNumItem := range ocrSeqNum { + ocrSeqNumRule = append(ocrSeqNumRule, ocrSeqNumItem) + } + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "FinalizationFailed", ocrSeqNumRule, remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &LiquidityManagerFinalizationFailedIterator{contract: _LiquidityManager.contract, event: "FinalizationFailed", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchFinalizationFailed(opts *bind.WatchOpts, sink chan<- *LiquidityManagerFinalizationFailed, ocrSeqNum []uint64, remoteChainSelector []uint64) (event.Subscription, error) { + + var ocrSeqNumRule []interface{} + for _, ocrSeqNumItem := range ocrSeqNum { + ocrSeqNumRule = append(ocrSeqNumRule, ocrSeqNumItem) + } + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "FinalizationFailed", ocrSeqNumRule, remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerFinalizationFailed) + if err := _LiquidityManager.contract.UnpackLog(event, "FinalizationFailed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseFinalizationFailed(log types.Log) (*LiquidityManagerFinalizationFailed, error) { + event := new(LiquidityManagerFinalizationFailed) + if err := _LiquidityManager.contract.UnpackLog(event, "FinalizationFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerFinalizationStepCompletedIterator struct { + Event *LiquidityManagerFinalizationStepCompleted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerFinalizationStepCompletedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerFinalizationStepCompleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerFinalizationStepCompleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerFinalizationStepCompletedIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerFinalizationStepCompletedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerFinalizationStepCompleted struct { + OcrSeqNum uint64 + RemoteChainSelector uint64 + BridgeSpecificData []byte + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterFinalizationStepCompleted(opts *bind.FilterOpts, ocrSeqNum []uint64, remoteChainSelector []uint64) (*LiquidityManagerFinalizationStepCompletedIterator, error) { + + var ocrSeqNumRule []interface{} + for _, ocrSeqNumItem := range ocrSeqNum { + ocrSeqNumRule = append(ocrSeqNumRule, ocrSeqNumItem) + } + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "FinalizationStepCompleted", ocrSeqNumRule, remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &LiquidityManagerFinalizationStepCompletedIterator{contract: _LiquidityManager.contract, event: "FinalizationStepCompleted", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchFinalizationStepCompleted(opts *bind.WatchOpts, sink chan<- *LiquidityManagerFinalizationStepCompleted, ocrSeqNum []uint64, remoteChainSelector []uint64) (event.Subscription, error) { + + var ocrSeqNumRule []interface{} + for _, ocrSeqNumItem := range ocrSeqNum { + ocrSeqNumRule = append(ocrSeqNumRule, ocrSeqNumItem) + } + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "FinalizationStepCompleted", ocrSeqNumRule, remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerFinalizationStepCompleted) + if err := _LiquidityManager.contract.UnpackLog(event, "FinalizationStepCompleted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseFinalizationStepCompleted(log types.Log) (*LiquidityManagerFinalizationStepCompleted, error) { + event := new(LiquidityManagerFinalizationStepCompleted) + if err := _LiquidityManager.contract.UnpackLog(event, "FinalizationStepCompleted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerFinanceRoleSetIterator struct { + Event *LiquidityManagerFinanceRoleSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerFinanceRoleSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerFinanceRoleSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerFinanceRoleSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerFinanceRoleSetIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerFinanceRoleSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerFinanceRoleSet struct { + FinanceRole common.Address + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterFinanceRoleSet(opts *bind.FilterOpts) (*LiquidityManagerFinanceRoleSetIterator, error) { + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "FinanceRoleSet") + if err != nil { + return nil, err + } + return &LiquidityManagerFinanceRoleSetIterator{contract: _LiquidityManager.contract, event: "FinanceRoleSet", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchFinanceRoleSet(opts *bind.WatchOpts, sink chan<- *LiquidityManagerFinanceRoleSet) (event.Subscription, error) { + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "FinanceRoleSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerFinanceRoleSet) + if err := _LiquidityManager.contract.UnpackLog(event, "FinanceRoleSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseFinanceRoleSet(log types.Log) (*LiquidityManagerFinanceRoleSet, error) { + event := new(LiquidityManagerFinanceRoleSet) + if err := _LiquidityManager.contract.UnpackLog(event, "FinanceRoleSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerLiquidityAddedToContainerIterator struct { + Event *LiquidityManagerLiquidityAddedToContainer + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerLiquidityAddedToContainerIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerLiquidityAddedToContainer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerLiquidityAddedToContainer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerLiquidityAddedToContainerIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerLiquidityAddedToContainerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerLiquidityAddedToContainer struct { + Provider common.Address + Amount *big.Int + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterLiquidityAddedToContainer(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LiquidityManagerLiquidityAddedToContainerIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "LiquidityAddedToContainer", providerRule, amountRule) + if err != nil { + return nil, err + } + return &LiquidityManagerLiquidityAddedToContainerIterator{contract: _LiquidityManager.contract, event: "LiquidityAddedToContainer", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchLiquidityAddedToContainer(opts *bind.WatchOpts, sink chan<- *LiquidityManagerLiquidityAddedToContainer, provider []common.Address, amount []*big.Int) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "LiquidityAddedToContainer", providerRule, amountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerLiquidityAddedToContainer) + if err := _LiquidityManager.contract.UnpackLog(event, "LiquidityAddedToContainer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseLiquidityAddedToContainer(log types.Log) (*LiquidityManagerLiquidityAddedToContainer, error) { + event := new(LiquidityManagerLiquidityAddedToContainer) + if err := _LiquidityManager.contract.UnpackLog(event, "LiquidityAddedToContainer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerLiquidityContainerSetIterator struct { + Event *LiquidityManagerLiquidityContainerSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerLiquidityContainerSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerLiquidityContainerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerLiquidityContainerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerLiquidityContainerSetIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerLiquidityContainerSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerLiquidityContainerSet struct { + NewLiquidityContainer common.Address + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterLiquidityContainerSet(opts *bind.FilterOpts, newLiquidityContainer []common.Address) (*LiquidityManagerLiquidityContainerSetIterator, error) { + + var newLiquidityContainerRule []interface{} + for _, newLiquidityContainerItem := range newLiquidityContainer { + newLiquidityContainerRule = append(newLiquidityContainerRule, newLiquidityContainerItem) + } + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "LiquidityContainerSet", newLiquidityContainerRule) + if err != nil { + return nil, err + } + return &LiquidityManagerLiquidityContainerSetIterator{contract: _LiquidityManager.contract, event: "LiquidityContainerSet", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchLiquidityContainerSet(opts *bind.WatchOpts, sink chan<- *LiquidityManagerLiquidityContainerSet, newLiquidityContainer []common.Address) (event.Subscription, error) { + + var newLiquidityContainerRule []interface{} + for _, newLiquidityContainerItem := range newLiquidityContainer { + newLiquidityContainerRule = append(newLiquidityContainerRule, newLiquidityContainerItem) + } + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "LiquidityContainerSet", newLiquidityContainerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerLiquidityContainerSet) + if err := _LiquidityManager.contract.UnpackLog(event, "LiquidityContainerSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseLiquidityContainerSet(log types.Log) (*LiquidityManagerLiquidityContainerSet, error) { + event := new(LiquidityManagerLiquidityContainerSet) + if err := _LiquidityManager.contract.UnpackLog(event, "LiquidityContainerSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerLiquidityRemovedFromContainerIterator struct { + Event *LiquidityManagerLiquidityRemovedFromContainer + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerLiquidityRemovedFromContainerIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerLiquidityRemovedFromContainer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerLiquidityRemovedFromContainer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerLiquidityRemovedFromContainerIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerLiquidityRemovedFromContainerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerLiquidityRemovedFromContainer struct { + Remover common.Address + Amount *big.Int + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterLiquidityRemovedFromContainer(opts *bind.FilterOpts, remover []common.Address, amount []*big.Int) (*LiquidityManagerLiquidityRemovedFromContainerIterator, error) { + + var removerRule []interface{} + for _, removerItem := range remover { + removerRule = append(removerRule, removerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "LiquidityRemovedFromContainer", removerRule, amountRule) + if err != nil { + return nil, err + } + return &LiquidityManagerLiquidityRemovedFromContainerIterator{contract: _LiquidityManager.contract, event: "LiquidityRemovedFromContainer", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchLiquidityRemovedFromContainer(opts *bind.WatchOpts, sink chan<- *LiquidityManagerLiquidityRemovedFromContainer, remover []common.Address, amount []*big.Int) (event.Subscription, error) { + + var removerRule []interface{} + for _, removerItem := range remover { + removerRule = append(removerRule, removerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "LiquidityRemovedFromContainer", removerRule, amountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerLiquidityRemovedFromContainer) + if err := _LiquidityManager.contract.UnpackLog(event, "LiquidityRemovedFromContainer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseLiquidityRemovedFromContainer(log types.Log) (*LiquidityManagerLiquidityRemovedFromContainer, error) { + event := new(LiquidityManagerLiquidityRemovedFromContainer) + if err := _LiquidityManager.contract.UnpackLog(event, "LiquidityRemovedFromContainer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerLiquidityTransferredIterator struct { + Event *LiquidityManagerLiquidityTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerLiquidityTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerLiquidityTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerLiquidityTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerLiquidityTransferredIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerLiquidityTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerLiquidityTransferred struct { + OcrSeqNum uint64 + FromChainSelector uint64 + ToChainSelector uint64 + To common.Address + Amount *big.Int + BridgeSpecificData []byte + BridgeReturnData []byte + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterLiquidityTransferred(opts *bind.FilterOpts, ocrSeqNum []uint64, fromChainSelector []uint64, toChainSelector []uint64) (*LiquidityManagerLiquidityTransferredIterator, error) { + + var ocrSeqNumRule []interface{} + for _, ocrSeqNumItem := range ocrSeqNum { + ocrSeqNumRule = append(ocrSeqNumRule, ocrSeqNumItem) + } + var fromChainSelectorRule []interface{} + for _, fromChainSelectorItem := range fromChainSelector { + fromChainSelectorRule = append(fromChainSelectorRule, fromChainSelectorItem) + } + var toChainSelectorRule []interface{} + for _, toChainSelectorItem := range toChainSelector { + toChainSelectorRule = append(toChainSelectorRule, toChainSelectorItem) + } + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "LiquidityTransferred", ocrSeqNumRule, fromChainSelectorRule, toChainSelectorRule) + if err != nil { + return nil, err + } + return &LiquidityManagerLiquidityTransferredIterator{contract: _LiquidityManager.contract, event: "LiquidityTransferred", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchLiquidityTransferred(opts *bind.WatchOpts, sink chan<- *LiquidityManagerLiquidityTransferred, ocrSeqNum []uint64, fromChainSelector []uint64, toChainSelector []uint64) (event.Subscription, error) { + + var ocrSeqNumRule []interface{} + for _, ocrSeqNumItem := range ocrSeqNum { + ocrSeqNumRule = append(ocrSeqNumRule, ocrSeqNumItem) + } + var fromChainSelectorRule []interface{} + for _, fromChainSelectorItem := range fromChainSelector { + fromChainSelectorRule = append(fromChainSelectorRule, fromChainSelectorItem) + } + var toChainSelectorRule []interface{} + for _, toChainSelectorItem := range toChainSelector { + toChainSelectorRule = append(toChainSelectorRule, toChainSelectorItem) + } + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "LiquidityTransferred", ocrSeqNumRule, fromChainSelectorRule, toChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerLiquidityTransferred) + if err := _LiquidityManager.contract.UnpackLog(event, "LiquidityTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseLiquidityTransferred(log types.Log) (*LiquidityManagerLiquidityTransferred, error) { + event := new(LiquidityManagerLiquidityTransferred) + if err := _LiquidityManager.contract.UnpackLog(event, "LiquidityTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerMinimumLiquiditySetIterator struct { + Event *LiquidityManagerMinimumLiquiditySet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerMinimumLiquiditySetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerMinimumLiquiditySet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerMinimumLiquiditySet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerMinimumLiquiditySetIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerMinimumLiquiditySetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerMinimumLiquiditySet struct { + OldBalance *big.Int + NewBalance *big.Int + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterMinimumLiquiditySet(opts *bind.FilterOpts) (*LiquidityManagerMinimumLiquiditySetIterator, error) { + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "MinimumLiquiditySet") + if err != nil { + return nil, err + } + return &LiquidityManagerMinimumLiquiditySetIterator{contract: _LiquidityManager.contract, event: "MinimumLiquiditySet", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchMinimumLiquiditySet(opts *bind.WatchOpts, sink chan<- *LiquidityManagerMinimumLiquiditySet) (event.Subscription, error) { + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "MinimumLiquiditySet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerMinimumLiquiditySet) + if err := _LiquidityManager.contract.UnpackLog(event, "MinimumLiquiditySet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseMinimumLiquiditySet(log types.Log) (*LiquidityManagerMinimumLiquiditySet, error) { + event := new(LiquidityManagerMinimumLiquiditySet) + if err := _LiquidityManager.contract.UnpackLog(event, "MinimumLiquiditySet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerNativeDepositedIterator struct { + Event *LiquidityManagerNativeDeposited + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerNativeDepositedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerNativeDeposited) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerNativeDeposited) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerNativeDepositedIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerNativeDepositedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerNativeDeposited struct { + Amount *big.Int + Depositor common.Address + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterNativeDeposited(opts *bind.FilterOpts) (*LiquidityManagerNativeDepositedIterator, error) { + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "NativeDeposited") + if err != nil { + return nil, err + } + return &LiquidityManagerNativeDepositedIterator{contract: _LiquidityManager.contract, event: "NativeDeposited", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchNativeDeposited(opts *bind.WatchOpts, sink chan<- *LiquidityManagerNativeDeposited) (event.Subscription, error) { + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "NativeDeposited") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerNativeDeposited) + if err := _LiquidityManager.contract.UnpackLog(event, "NativeDeposited", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseNativeDeposited(log types.Log) (*LiquidityManagerNativeDeposited, error) { + event := new(LiquidityManagerNativeDeposited) + if err := _LiquidityManager.contract.UnpackLog(event, "NativeDeposited", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerNativeWithdrawnIterator struct { + Event *LiquidityManagerNativeWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerNativeWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerNativeWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerNativeWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerNativeWithdrawnIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerNativeWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerNativeWithdrawn struct { + Amount *big.Int + Destination common.Address + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterNativeWithdrawn(opts *bind.FilterOpts) (*LiquidityManagerNativeWithdrawnIterator, error) { + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "NativeWithdrawn") + if err != nil { + return nil, err + } + return &LiquidityManagerNativeWithdrawnIterator{contract: _LiquidityManager.contract, event: "NativeWithdrawn", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchNativeWithdrawn(opts *bind.WatchOpts, sink chan<- *LiquidityManagerNativeWithdrawn) (event.Subscription, error) { + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "NativeWithdrawn") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerNativeWithdrawn) + if err := _LiquidityManager.contract.UnpackLog(event, "NativeWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseNativeWithdrawn(log types.Log) (*LiquidityManagerNativeWithdrawn, error) { + event := new(LiquidityManagerNativeWithdrawn) + if err := _LiquidityManager.contract.UnpackLog(event, "NativeWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerOwnershipTransferRequestedIterator struct { + Event *LiquidityManagerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LiquidityManagerOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &LiquidityManagerOwnershipTransferRequestedIterator{contract: _LiquidityManager.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LiquidityManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerOwnershipTransferRequested) + if err := _LiquidityManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseOwnershipTransferRequested(log types.Log) (*LiquidityManagerOwnershipTransferRequested, error) { + event := new(LiquidityManagerOwnershipTransferRequested) + if err := _LiquidityManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerOwnershipTransferredIterator struct { + Event *LiquidityManagerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LiquidityManagerOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &LiquidityManagerOwnershipTransferredIterator{contract: _LiquidityManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LiquidityManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerOwnershipTransferred) + if err := _LiquidityManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseOwnershipTransferred(log types.Log) (*LiquidityManagerOwnershipTransferred, error) { + event := new(LiquidityManagerOwnershipTransferred) + if err := _LiquidityManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LiquidityManagerTransmittedIterator struct { + Event *LiquidityManagerTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LiquidityManagerTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LiquidityManagerTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LiquidityManagerTransmittedIterator) Error() error { + return it.fail +} + +func (it *LiquidityManagerTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LiquidityManagerTransmitted struct { + ConfigDigest [32]byte + SequenceNumber uint64 + Raw types.Log +} + +func (_LiquidityManager *LiquidityManagerFilterer) FilterTransmitted(opts *bind.FilterOpts) (*LiquidityManagerTransmittedIterator, error) { + + logs, sub, err := _LiquidityManager.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &LiquidityManagerTransmittedIterator{contract: _LiquidityManager.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *LiquidityManagerTransmitted) (event.Subscription, error) { + + logs, sub, err := _LiquidityManager.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LiquidityManagerTransmitted) + if err := _LiquidityManager.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LiquidityManager *LiquidityManagerFilterer) ParseTransmitted(log types.Log) (*LiquidityManagerTransmitted, error) { + event := new(LiquidityManagerTransmitted) + if err := _LiquidityManager.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} + +func (_LiquidityManager *LiquidityManager) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _LiquidityManager.abi.Events["ConfigSet"].ID: + return _LiquidityManager.ParseConfigSet(log) + case _LiquidityManager.abi.Events["CrossChainRebalancerSet"].ID: + return _LiquidityManager.ParseCrossChainRebalancerSet(log) + case _LiquidityManager.abi.Events["FinalizationFailed"].ID: + return _LiquidityManager.ParseFinalizationFailed(log) + case _LiquidityManager.abi.Events["FinalizationStepCompleted"].ID: + return _LiquidityManager.ParseFinalizationStepCompleted(log) + case _LiquidityManager.abi.Events["FinanceRoleSet"].ID: + return _LiquidityManager.ParseFinanceRoleSet(log) + case _LiquidityManager.abi.Events["LiquidityAddedToContainer"].ID: + return _LiquidityManager.ParseLiquidityAddedToContainer(log) + case _LiquidityManager.abi.Events["LiquidityContainerSet"].ID: + return _LiquidityManager.ParseLiquidityContainerSet(log) + case _LiquidityManager.abi.Events["LiquidityRemovedFromContainer"].ID: + return _LiquidityManager.ParseLiquidityRemovedFromContainer(log) + case _LiquidityManager.abi.Events["LiquidityTransferred"].ID: + return _LiquidityManager.ParseLiquidityTransferred(log) + case _LiquidityManager.abi.Events["MinimumLiquiditySet"].ID: + return _LiquidityManager.ParseMinimumLiquiditySet(log) + case _LiquidityManager.abi.Events["NativeDeposited"].ID: + return _LiquidityManager.ParseNativeDeposited(log) + case _LiquidityManager.abi.Events["NativeWithdrawn"].ID: + return _LiquidityManager.ParseNativeWithdrawn(log) + case _LiquidityManager.abi.Events["OwnershipTransferRequested"].ID: + return _LiquidityManager.ParseOwnershipTransferRequested(log) + case _LiquidityManager.abi.Events["OwnershipTransferred"].ID: + return _LiquidityManager.ParseOwnershipTransferred(log) + case _LiquidityManager.abi.Events["Transmitted"].ID: + return _LiquidityManager.ParseTransmitted(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (LiquidityManagerConfigSet) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (LiquidityManagerCrossChainRebalancerSet) Topic() common.Hash { + return common.HexToHash("0xab9bd0e4888101232b8f09dae2952ff59a6eea4a19fbddf2a8ca7b23f0e4cb40") +} + +func (LiquidityManagerFinalizationFailed) Topic() common.Hash { + return common.HexToHash("0xa481d91c3f9574c23ee84fef85246354b760a0527a535d6382354e4684703ce3") +} + +func (LiquidityManagerFinalizationStepCompleted) Topic() common.Hash { + return common.HexToHash("0x8d3121fe961b40270f336aa75feb1213f1c979a33993311c60da4dd0f24526cf") +} + +func (LiquidityManagerFinanceRoleSet) Topic() common.Hash { + return common.HexToHash("0x58024d20c07d3ebb87b192861d337d3a60995665acc5b8ce29596458b1f25170") +} + +func (LiquidityManagerLiquidityAddedToContainer) Topic() common.Hash { + return common.HexToHash("0x5414b81d05ac3542606f164e16a9a107d05d21e906539cc5ceb61d7b6b707eb5") +} + +func (LiquidityManagerLiquidityContainerSet) Topic() common.Hash { + return common.HexToHash("0x07dc474694ac40123aadcd2445f1b38d2eb353edd9319dcea043548ab34990ec") +} + +func (LiquidityManagerLiquidityRemovedFromContainer) Topic() common.Hash { + return common.HexToHash("0x2bda316674f8d73d289689d7a3acdf8e353b7a142fb5a68ac2aa475104039c18") +} + +func (LiquidityManagerLiquidityTransferred) Topic() common.Hash { + return common.HexToHash("0x2a0b69eaf1b415ca57005b4f87582ddefc6d960325ff30dc62a9b3e1e1e5b8a8") +} + +func (LiquidityManagerMinimumLiquiditySet) Topic() common.Hash { + return common.HexToHash("0xf97e758c8b3d81df7b0e1b7327a6a7fcf09a41536b2d274b9103015d715f11eb") +} + +func (LiquidityManagerNativeDeposited) Topic() common.Hash { + return common.HexToHash("0x3c597f6ac9fe7f0ed6da50b07618f5850a642e459ad587f7fab491a71f8b0ab8") +} + +func (LiquidityManagerNativeWithdrawn) Topic() common.Hash { + return common.HexToHash("0x6b84d241b711af111ecfa0e518239e6ca212da442a76548fe8a1f4e77518256a") +} + +func (LiquidityManagerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (LiquidityManagerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (LiquidityManagerTransmitted) Topic() common.Hash { + return common.HexToHash("0xe893c2681d327421d89e1cb54fbe64645b4dcea668d6826130b62cf4c6eefea2") +} + +func (_LiquidityManager *LiquidityManager) Address() common.Address { + return _LiquidityManager.address +} + +type LiquidityManagerInterface interface { + GetAllCrossChainRebalancers(opts *bind.CallOpts) ([]ILiquidityManagerCrossChainRebalancerArgs, error) + + GetCrossChainRebalancer(opts *bind.CallOpts, chainSelector uint64) (LiquidityManagerCrossChainRebalancer, error) + + GetFinanceRole(opts *bind.CallOpts) (common.Address, error) + + GetLiquidity(opts *bind.CallOpts) (*big.Int, error) + + GetLocalLiquidityContainer(opts *bind.CallOpts) (common.Address, error) + + GetMinimumLiquidity(opts *bind.CallOpts) (*big.Int, error) + + GetSupportedDestChains(opts *bind.CallOpts) ([]uint64, error) + + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + ILocalToken(opts *bind.CallOpts) (common.Address, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestSequenceNumber(opts *bind.CallOpts) (uint64, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AddLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + RebalanceLiquidity(opts *bind.TransactOpts, chainSelector uint64, amount *big.Int, nativeBridgeFee *big.Int, bridgeSpecificPayload []byte) (*types.Transaction, error) + + ReceiveLiquidity(opts *bind.TransactOpts, remoteChainSelector uint64, amount *big.Int, shouldWrapNative bool, bridgeSpecificPayload []byte) (*types.Transaction, error) + + RemoveLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + SetCrossChainRebalancer(opts *bind.TransactOpts, crossChainLiqManager ILiquidityManagerCrossChainRebalancerArgs) (*types.Transaction, error) + + SetCrossChainRebalancers(opts *bind.TransactOpts, crossChainRebalancers []ILiquidityManagerCrossChainRebalancerArgs) (*types.Transaction, error) + + SetFinanceRole(opts *bind.TransactOpts, finance common.Address) (*types.Transaction, error) + + SetLocalLiquidityContainer(opts *bind.TransactOpts, localLiquidityContainer common.Address) (*types.Transaction, error) + + SetMinimumLiquidity(opts *bind.TransactOpts, minimumLiquidity *big.Int) (*types.Transaction, error) + + SetOCR3Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + WithdrawERC20(opts *bind.TransactOpts, token common.Address, amount *big.Int, destination common.Address) (*types.Transaction, error) + + WithdrawNative(opts *bind.TransactOpts, amount *big.Int, destination common.Address) (*types.Transaction, error) + + Receive(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*LiquidityManagerConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *LiquidityManagerConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*LiquidityManagerConfigSet, error) + + FilterCrossChainRebalancerSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*LiquidityManagerCrossChainRebalancerSetIterator, error) + + WatchCrossChainRebalancerSet(opts *bind.WatchOpts, sink chan<- *LiquidityManagerCrossChainRebalancerSet, remoteChainSelector []uint64) (event.Subscription, error) + + ParseCrossChainRebalancerSet(log types.Log) (*LiquidityManagerCrossChainRebalancerSet, error) + + FilterFinalizationFailed(opts *bind.FilterOpts, ocrSeqNum []uint64, remoteChainSelector []uint64) (*LiquidityManagerFinalizationFailedIterator, error) + + WatchFinalizationFailed(opts *bind.WatchOpts, sink chan<- *LiquidityManagerFinalizationFailed, ocrSeqNum []uint64, remoteChainSelector []uint64) (event.Subscription, error) + + ParseFinalizationFailed(log types.Log) (*LiquidityManagerFinalizationFailed, error) + + FilterFinalizationStepCompleted(opts *bind.FilterOpts, ocrSeqNum []uint64, remoteChainSelector []uint64) (*LiquidityManagerFinalizationStepCompletedIterator, error) + + WatchFinalizationStepCompleted(opts *bind.WatchOpts, sink chan<- *LiquidityManagerFinalizationStepCompleted, ocrSeqNum []uint64, remoteChainSelector []uint64) (event.Subscription, error) + + ParseFinalizationStepCompleted(log types.Log) (*LiquidityManagerFinalizationStepCompleted, error) + + FilterFinanceRoleSet(opts *bind.FilterOpts) (*LiquidityManagerFinanceRoleSetIterator, error) + + WatchFinanceRoleSet(opts *bind.WatchOpts, sink chan<- *LiquidityManagerFinanceRoleSet) (event.Subscription, error) + + ParseFinanceRoleSet(log types.Log) (*LiquidityManagerFinanceRoleSet, error) + + FilterLiquidityAddedToContainer(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*LiquidityManagerLiquidityAddedToContainerIterator, error) + + WatchLiquidityAddedToContainer(opts *bind.WatchOpts, sink chan<- *LiquidityManagerLiquidityAddedToContainer, provider []common.Address, amount []*big.Int) (event.Subscription, error) + + ParseLiquidityAddedToContainer(log types.Log) (*LiquidityManagerLiquidityAddedToContainer, error) + + FilterLiquidityContainerSet(opts *bind.FilterOpts, newLiquidityContainer []common.Address) (*LiquidityManagerLiquidityContainerSetIterator, error) + + WatchLiquidityContainerSet(opts *bind.WatchOpts, sink chan<- *LiquidityManagerLiquidityContainerSet, newLiquidityContainer []common.Address) (event.Subscription, error) + + ParseLiquidityContainerSet(log types.Log) (*LiquidityManagerLiquidityContainerSet, error) + + FilterLiquidityRemovedFromContainer(opts *bind.FilterOpts, remover []common.Address, amount []*big.Int) (*LiquidityManagerLiquidityRemovedFromContainerIterator, error) + + WatchLiquidityRemovedFromContainer(opts *bind.WatchOpts, sink chan<- *LiquidityManagerLiquidityRemovedFromContainer, remover []common.Address, amount []*big.Int) (event.Subscription, error) + + ParseLiquidityRemovedFromContainer(log types.Log) (*LiquidityManagerLiquidityRemovedFromContainer, error) + + FilterLiquidityTransferred(opts *bind.FilterOpts, ocrSeqNum []uint64, fromChainSelector []uint64, toChainSelector []uint64) (*LiquidityManagerLiquidityTransferredIterator, error) + + WatchLiquidityTransferred(opts *bind.WatchOpts, sink chan<- *LiquidityManagerLiquidityTransferred, ocrSeqNum []uint64, fromChainSelector []uint64, toChainSelector []uint64) (event.Subscription, error) + + ParseLiquidityTransferred(log types.Log) (*LiquidityManagerLiquidityTransferred, error) + + FilterMinimumLiquiditySet(opts *bind.FilterOpts) (*LiquidityManagerMinimumLiquiditySetIterator, error) + + WatchMinimumLiquiditySet(opts *bind.WatchOpts, sink chan<- *LiquidityManagerMinimumLiquiditySet) (event.Subscription, error) + + ParseMinimumLiquiditySet(log types.Log) (*LiquidityManagerMinimumLiquiditySet, error) + + FilterNativeDeposited(opts *bind.FilterOpts) (*LiquidityManagerNativeDepositedIterator, error) + + WatchNativeDeposited(opts *bind.WatchOpts, sink chan<- *LiquidityManagerNativeDeposited) (event.Subscription, error) + + ParseNativeDeposited(log types.Log) (*LiquidityManagerNativeDeposited, error) + + FilterNativeWithdrawn(opts *bind.FilterOpts) (*LiquidityManagerNativeWithdrawnIterator, error) + + WatchNativeWithdrawn(opts *bind.WatchOpts, sink chan<- *LiquidityManagerNativeWithdrawn) (event.Subscription, error) + + ParseNativeWithdrawn(log types.Log) (*LiquidityManagerNativeWithdrawn, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LiquidityManagerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LiquidityManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*LiquidityManagerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LiquidityManagerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LiquidityManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*LiquidityManagerOwnershipTransferred, error) + + FilterTransmitted(opts *bind.FilterOpts) (*LiquidityManagerTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *LiquidityManagerTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*LiquidityManagerTransmitted, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/mock_l1_bridge_adapter/mock_l1_bridge_adapter.go b/core/gethwrappers/liquiditymanager/generated/mock_l1_bridge_adapter/mock_l1_bridge_adapter.go new file mode 100644 index 0000000000..bbfbb1079d --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/mock_l1_bridge_adapter/mock_l1_bridge_adapter.go @@ -0,0 +1,660 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package mock_l1_bridge_adapter + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type MockL1BridgeAdapterFinalizePayload struct { + Nonce *big.Int + Amount *big.Int +} + +type MockL1BridgeAdapterPayload struct { + Action uint8 + Data []byte +} + +type MockL1BridgeAdapterProvePayload struct { + Nonce *big.Int +} + +var MockL1BridgeAdapterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"holdNative\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BridgeAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wanted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InsufficientEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFinalizationAction\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"MsgShouldNotContainValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"MsgValueDoesNotMatchAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativeSendFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"NonceAlreadyUsed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"NonceNotProven\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structMockL1BridgeAdapter.FinalizePayload\",\"name\":\"payload\",\"type\":\"tuple\"}],\"name\":\"encodeFinalizePayload\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enumMockL1BridgeAdapter.FinalizationAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structMockL1BridgeAdapter.Payload\",\"name\":\"payload\",\"type\":\"tuple\"}],\"name\":\"encodePayload\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structMockL1BridgeAdapter.ProvePayload\",\"name\":\"payload\",\"type\":\"tuple\"}],\"name\":\"encodeProvePayload\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"localReceiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bridgeSpecificPayload\",\"type\":\"bytes\"}],\"name\":\"finalizeWithdrawERC20\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBridgeFeeInNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"sendERC20\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60c0604052600160005534801561001557600080fd5b5060405161126f38038061126f8339810160408190526100349161004c565b6001600160a01b03909116608052151560a052610097565b6000806040838503121561005f57600080fd5b82516001600160a01b038116811461007657600080fd5b6020840151909250801515811461008c57600080fd5b809150509250929050565b60805160a0516111906100df6000396000818161042801526109cf0152600081816101c2015281816102940152818161047b015281816105660152610aa701526111906000f3fe60806040526004361061007f5760003560e01c8063a71d98b71161004e578063a71d98b71461011c578063aee0c3881461013c578063eb521a4c14610157578063f19e1eb61461017757600080fd5b80630a861f2a1461008b5780632e4b1fc9146100ad578063331e5ff0146100ce57806338314bb2146100ec57600080fd5b3661008657005b600080fd5b34801561009757600080fd5b506100ab6100a6366004610c43565b610192565b005b3480156100b957600080fd5b50604051600081526020015b60405180910390f35b3480156100da57600080fd5b506100ab6100e9366004610d26565b50565b3480156100f857600080fd5b5061010c610107366004610e8a565b6102eb565b60405190151581526020016100c5565b61012f61012a366004610eeb565b610385565b6040516100c59190610fd8565b34801561014857600080fd5b506100ab6100e9366004610ff2565b34801561016357600080fd5b506100ab610172366004610c43565b61054c565b34801561018357600080fd5b506100ab6100e9366004611024565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561021e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102429190611048565b101561027a576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102bb73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633836105be565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6000806102fa83850185610d26565b905060008151600181111561031157610311611061565b036103275761031f81610697565b91505061037d565b60018151600181111561033c5761033c611061565b0361034b5761031f818661074b565b6040517fee2ef09800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b949350505050565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810184905260609073ffffffffffffffffffffffffffffffffffffffff8816906323b872dd906064016020604051808303816000875af1158015610401573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104259190611090565b507f0000000000000000000000000000000000000000000000000000000000000000156104ed576040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018590527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156104d457600080fd5b505af11580156104e8573d6000803e3d6000fd5b505050505b6000805481806104fc836110b2565b9190505560405160200161051291815260200190565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905298975050505050505050565b61058e73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633308461085d565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526106929084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526108c1565b505050565b60008082602001518060200190518101906106b29190611111565b805160009081526001602052604090205490915060ff161561070b5780516040517f91cab50400000000000000000000000000000000000000000000000000000000815260048101919091526024015b60405180910390fd5b516000908152600160208190526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905592915050565b60008083602001518060200190518101906107669190611135565b805160009081526001602052604090205490915060ff166107b95780516040517f974f61110000000000000000000000000000000000000000000000000000000081526004810191909152602401610702565b805160009081526002602052604090205460ff161561080a5780516040517f91cab5040000000000000000000000000000000000000000000000000000000081526004810191909152602401610702565b8051600090815260026020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905581015161085390846109cd565b5060019392505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526108bb9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610610565b50505050565b6000610923826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ad29092919063ffffffff16565b80519091501561069257808060200190518101906109419190611090565b610692576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610702565b7f000000000000000000000000000000000000000000000000000000000000000015610a8d5760008173ffffffffffffffffffffffffffffffffffffffff168360405160006040518083038185875af1925050503d8060008114610a4d576040519150601f19603f3d011682016040523d82523d6000602084013e610a52565b606091505b5050905080610692576040517fa0c968e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ace73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001682846105be565b5050565b606061037d8484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051610b069190611167565b60006040518083038185875af1925050503d8060008114610b43576040519150601f19603f3d011682016040523d82523d6000602084013e610b48565b606091505b5091509150610b5987838387610b64565b979650505050505050565b60608315610bfa578251600003610bf35773ffffffffffffffffffffffffffffffffffffffff85163b610bf3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610702565b508161037d565b61037d8383815115610c0f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107029190610fd8565b600060208284031215610c5557600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610cae57610cae610c5c565b60405290565b6040516020810167ffffffffffffffff81118282101715610cae57610cae610c5c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d1e57610d1e610c5c565b604052919050565b60006020808385031215610d3957600080fd5b823567ffffffffffffffff80821115610d5157600080fd5b9084019060408287031215610d6557600080fd5b610d6d610c8b565b823560028110610d7c57600080fd5b81528284013582811115610d8f57600080fd5b80840193505086601f840112610da457600080fd5b823582811115610db657610db6610c5c565b610de6857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610cd7565b92508083528785828601011115610dfc57600080fd5b8085850186850137600090830185015292830152509392505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610e3c57600080fd5b919050565b60008083601f840112610e5357600080fd5b50813567ffffffffffffffff811115610e6b57600080fd5b602083019150836020828501011115610e8357600080fd5b9250929050565b60008060008060608587031215610ea057600080fd5b610ea985610e18565b9350610eb760208601610e18565b9250604085013567ffffffffffffffff811115610ed357600080fd5b610edf87828801610e41565b95989497509550505050565b60008060008060008060a08789031215610f0457600080fd5b610f0d87610e18565b9550610f1b60208801610e18565b9450610f2960408801610e18565b935060608701359250608087013567ffffffffffffffff811115610f4c57600080fd5b610f5889828a01610e41565b979a9699509497509295939492505050565b60005b83811015610f85578181015183820152602001610f6d565b50506000910152565b60008151808452610fa6816020860160208601610f6a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610feb6020830184610f8e565b9392505050565b60006040828403121561100457600080fd5b61100c610c8b565b82358152602083013560208201528091505092915050565b60006020828403121561103657600080fd5b61103e610cb4565b9135825250919050565b60006020828403121561105a57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000602082840312156110a257600080fd5b81518015158114610feb57600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361110a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60006020828403121561112357600080fd5b61112b610cb4565b9151825250919050565b60006040828403121561114757600080fd5b61114f610c8b565b82518152602083015160208201528091505092915050565b60008251611179818460208701610f6a565b919091019291505056fea164736f6c6343000818000a", +} + +var MockL1BridgeAdapterABI = MockL1BridgeAdapterMetaData.ABI + +var MockL1BridgeAdapterBin = MockL1BridgeAdapterMetaData.Bin + +func DeployMockL1BridgeAdapter(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, holdNative bool) (common.Address, *types.Transaction, *MockL1BridgeAdapter, error) { + parsed, err := MockL1BridgeAdapterMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MockL1BridgeAdapterBin), backend, token, holdNative) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MockL1BridgeAdapter{address: address, abi: *parsed, MockL1BridgeAdapterCaller: MockL1BridgeAdapterCaller{contract: contract}, MockL1BridgeAdapterTransactor: MockL1BridgeAdapterTransactor{contract: contract}, MockL1BridgeAdapterFilterer: MockL1BridgeAdapterFilterer{contract: contract}}, nil +} + +type MockL1BridgeAdapter struct { + address common.Address + abi abi.ABI + MockL1BridgeAdapterCaller + MockL1BridgeAdapterTransactor + MockL1BridgeAdapterFilterer +} + +type MockL1BridgeAdapterCaller struct { + contract *bind.BoundContract +} + +type MockL1BridgeAdapterTransactor struct { + contract *bind.BoundContract +} + +type MockL1BridgeAdapterFilterer struct { + contract *bind.BoundContract +} + +type MockL1BridgeAdapterSession struct { + Contract *MockL1BridgeAdapter + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type MockL1BridgeAdapterCallerSession struct { + Contract *MockL1BridgeAdapterCaller + CallOpts bind.CallOpts +} + +type MockL1BridgeAdapterTransactorSession struct { + Contract *MockL1BridgeAdapterTransactor + TransactOpts bind.TransactOpts +} + +type MockL1BridgeAdapterRaw struct { + Contract *MockL1BridgeAdapter +} + +type MockL1BridgeAdapterCallerRaw struct { + Contract *MockL1BridgeAdapterCaller +} + +type MockL1BridgeAdapterTransactorRaw struct { + Contract *MockL1BridgeAdapterTransactor +} + +func NewMockL1BridgeAdapter(address common.Address, backend bind.ContractBackend) (*MockL1BridgeAdapter, error) { + abi, err := abi.JSON(strings.NewReader(MockL1BridgeAdapterABI)) + if err != nil { + return nil, err + } + contract, err := bindMockL1BridgeAdapter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MockL1BridgeAdapter{address: address, abi: abi, MockL1BridgeAdapterCaller: MockL1BridgeAdapterCaller{contract: contract}, MockL1BridgeAdapterTransactor: MockL1BridgeAdapterTransactor{contract: contract}, MockL1BridgeAdapterFilterer: MockL1BridgeAdapterFilterer{contract: contract}}, nil +} + +func NewMockL1BridgeAdapterCaller(address common.Address, caller bind.ContractCaller) (*MockL1BridgeAdapterCaller, error) { + contract, err := bindMockL1BridgeAdapter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MockL1BridgeAdapterCaller{contract: contract}, nil +} + +func NewMockL1BridgeAdapterTransactor(address common.Address, transactor bind.ContractTransactor) (*MockL1BridgeAdapterTransactor, error) { + contract, err := bindMockL1BridgeAdapter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MockL1BridgeAdapterTransactor{contract: contract}, nil +} + +func NewMockL1BridgeAdapterFilterer(address common.Address, filterer bind.ContractFilterer) (*MockL1BridgeAdapterFilterer, error) { + contract, err := bindMockL1BridgeAdapter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MockL1BridgeAdapterFilterer{contract: contract}, nil +} + +func bindMockL1BridgeAdapter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MockL1BridgeAdapterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockL1BridgeAdapter.Contract.MockL1BridgeAdapterCaller.contract.Call(opts, result, method, params...) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.MockL1BridgeAdapterTransactor.contract.Transfer(opts) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.MockL1BridgeAdapterTransactor.contract.Transact(opts, method, params...) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockL1BridgeAdapter.Contract.contract.Call(opts, result, method, params...) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.contract.Transfer(opts) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.contract.Transact(opts, method, params...) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterCaller) EncodeFinalizePayload(opts *bind.CallOpts, payload MockL1BridgeAdapterFinalizePayload) error { + var out []interface{} + err := _MockL1BridgeAdapter.contract.Call(opts, &out, "encodeFinalizePayload", payload) + + if err != nil { + return err + } + + return err + +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterSession) EncodeFinalizePayload(payload MockL1BridgeAdapterFinalizePayload) error { + return _MockL1BridgeAdapter.Contract.EncodeFinalizePayload(&_MockL1BridgeAdapter.CallOpts, payload) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterCallerSession) EncodeFinalizePayload(payload MockL1BridgeAdapterFinalizePayload) error { + return _MockL1BridgeAdapter.Contract.EncodeFinalizePayload(&_MockL1BridgeAdapter.CallOpts, payload) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterCaller) EncodePayload(opts *bind.CallOpts, payload MockL1BridgeAdapterPayload) error { + var out []interface{} + err := _MockL1BridgeAdapter.contract.Call(opts, &out, "encodePayload", payload) + + if err != nil { + return err + } + + return err + +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterSession) EncodePayload(payload MockL1BridgeAdapterPayload) error { + return _MockL1BridgeAdapter.Contract.EncodePayload(&_MockL1BridgeAdapter.CallOpts, payload) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterCallerSession) EncodePayload(payload MockL1BridgeAdapterPayload) error { + return _MockL1BridgeAdapter.Contract.EncodePayload(&_MockL1BridgeAdapter.CallOpts, payload) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterCaller) EncodeProvePayload(opts *bind.CallOpts, payload MockL1BridgeAdapterProvePayload) error { + var out []interface{} + err := _MockL1BridgeAdapter.contract.Call(opts, &out, "encodeProvePayload", payload) + + if err != nil { + return err + } + + return err + +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterSession) EncodeProvePayload(payload MockL1BridgeAdapterProvePayload) error { + return _MockL1BridgeAdapter.Contract.EncodeProvePayload(&_MockL1BridgeAdapter.CallOpts, payload) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterCallerSession) EncodeProvePayload(payload MockL1BridgeAdapterProvePayload) error { + return _MockL1BridgeAdapter.Contract.EncodeProvePayload(&_MockL1BridgeAdapter.CallOpts, payload) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterCaller) GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MockL1BridgeAdapter.contract.Call(opts, &out, "getBridgeFeeInNative") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterSession) GetBridgeFeeInNative() (*big.Int, error) { + return _MockL1BridgeAdapter.Contract.GetBridgeFeeInNative(&_MockL1BridgeAdapter.CallOpts) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterCallerSession) GetBridgeFeeInNative() (*big.Int, error) { + return _MockL1BridgeAdapter.Contract.GetBridgeFeeInNative(&_MockL1BridgeAdapter.CallOpts) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterTransactor) FinalizeWithdrawERC20(opts *bind.TransactOpts, arg0 common.Address, localReceiver common.Address, bridgeSpecificPayload []byte) (*types.Transaction, error) { + return _MockL1BridgeAdapter.contract.Transact(opts, "finalizeWithdrawERC20", arg0, localReceiver, bridgeSpecificPayload) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterSession) FinalizeWithdrawERC20(arg0 common.Address, localReceiver common.Address, bridgeSpecificPayload []byte) (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.FinalizeWithdrawERC20(&_MockL1BridgeAdapter.TransactOpts, arg0, localReceiver, bridgeSpecificPayload) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterTransactorSession) FinalizeWithdrawERC20(arg0 common.Address, localReceiver common.Address, bridgeSpecificPayload []byte) (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.FinalizeWithdrawERC20(&_MockL1BridgeAdapter.TransactOpts, arg0, localReceiver, bridgeSpecificPayload) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterTransactor) ProvideLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _MockL1BridgeAdapter.contract.Transact(opts, "provideLiquidity", amount) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterSession) ProvideLiquidity(amount *big.Int) (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.ProvideLiquidity(&_MockL1BridgeAdapter.TransactOpts, amount) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterTransactorSession) ProvideLiquidity(amount *big.Int) (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.ProvideLiquidity(&_MockL1BridgeAdapter.TransactOpts, amount) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterTransactor) SendERC20(opts *bind.TransactOpts, localToken common.Address, arg1 common.Address, arg2 common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _MockL1BridgeAdapter.contract.Transact(opts, "sendERC20", localToken, arg1, arg2, amount, arg4) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterSession) SendERC20(localToken common.Address, arg1 common.Address, arg2 common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.SendERC20(&_MockL1BridgeAdapter.TransactOpts, localToken, arg1, arg2, amount, arg4) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterTransactorSession) SendERC20(localToken common.Address, arg1 common.Address, arg2 common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.SendERC20(&_MockL1BridgeAdapter.TransactOpts, localToken, arg1, arg2, amount, arg4) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterTransactor) WithdrawLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _MockL1BridgeAdapter.contract.Transact(opts, "withdrawLiquidity", amount) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterSession) WithdrawLiquidity(amount *big.Int) (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.WithdrawLiquidity(&_MockL1BridgeAdapter.TransactOpts, amount) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterTransactorSession) WithdrawLiquidity(amount *big.Int) (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.WithdrawLiquidity(&_MockL1BridgeAdapter.TransactOpts, amount) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockL1BridgeAdapter.contract.RawTransact(opts, nil) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterSession) Receive() (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.Receive(&_MockL1BridgeAdapter.TransactOpts) +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterTransactorSession) Receive() (*types.Transaction, error) { + return _MockL1BridgeAdapter.Contract.Receive(&_MockL1BridgeAdapter.TransactOpts) +} + +type MockL1BridgeAdapterLiquidityAddedIterator struct { + Event *MockL1BridgeAdapterLiquidityAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MockL1BridgeAdapterLiquidityAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MockL1BridgeAdapterLiquidityAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MockL1BridgeAdapterLiquidityAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MockL1BridgeAdapterLiquidityAddedIterator) Error() error { + return it.fail +} + +func (it *MockL1BridgeAdapterLiquidityAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MockL1BridgeAdapterLiquidityAdded struct { + Provider common.Address + Amount *big.Int + Raw types.Log +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterFilterer) FilterLiquidityAdded(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*MockL1BridgeAdapterLiquidityAddedIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _MockL1BridgeAdapter.contract.FilterLogs(opts, "LiquidityAdded", providerRule, amountRule) + if err != nil { + return nil, err + } + return &MockL1BridgeAdapterLiquidityAddedIterator{contract: _MockL1BridgeAdapter.contract, event: "LiquidityAdded", logs: logs, sub: sub}, nil +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterFilterer) WatchLiquidityAdded(opts *bind.WatchOpts, sink chan<- *MockL1BridgeAdapterLiquidityAdded, provider []common.Address, amount []*big.Int) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _MockL1BridgeAdapter.contract.WatchLogs(opts, "LiquidityAdded", providerRule, amountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MockL1BridgeAdapterLiquidityAdded) + if err := _MockL1BridgeAdapter.contract.UnpackLog(event, "LiquidityAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterFilterer) ParseLiquidityAdded(log types.Log) (*MockL1BridgeAdapterLiquidityAdded, error) { + event := new(MockL1BridgeAdapterLiquidityAdded) + if err := _MockL1BridgeAdapter.contract.UnpackLog(event, "LiquidityAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type MockL1BridgeAdapterLiquidityRemovedIterator struct { + Event *MockL1BridgeAdapterLiquidityRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *MockL1BridgeAdapterLiquidityRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(MockL1BridgeAdapterLiquidityRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(MockL1BridgeAdapterLiquidityRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *MockL1BridgeAdapterLiquidityRemovedIterator) Error() error { + return it.fail +} + +func (it *MockL1BridgeAdapterLiquidityRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type MockL1BridgeAdapterLiquidityRemoved struct { + Provider common.Address + Amount *big.Int + Raw types.Log +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterFilterer) FilterLiquidityRemoved(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*MockL1BridgeAdapterLiquidityRemovedIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _MockL1BridgeAdapter.contract.FilterLogs(opts, "LiquidityRemoved", providerRule, amountRule) + if err != nil { + return nil, err + } + return &MockL1BridgeAdapterLiquidityRemovedIterator{contract: _MockL1BridgeAdapter.contract, event: "LiquidityRemoved", logs: logs, sub: sub}, nil +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterFilterer) WatchLiquidityRemoved(opts *bind.WatchOpts, sink chan<- *MockL1BridgeAdapterLiquidityRemoved, provider []common.Address, amount []*big.Int) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + + logs, sub, err := _MockL1BridgeAdapter.contract.WatchLogs(opts, "LiquidityRemoved", providerRule, amountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(MockL1BridgeAdapterLiquidityRemoved) + if err := _MockL1BridgeAdapter.contract.UnpackLog(event, "LiquidityRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapterFilterer) ParseLiquidityRemoved(log types.Log) (*MockL1BridgeAdapterLiquidityRemoved, error) { + event := new(MockL1BridgeAdapterLiquidityRemoved) + if err := _MockL1BridgeAdapter.contract.UnpackLog(event, "LiquidityRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapter) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _MockL1BridgeAdapter.abi.Events["LiquidityAdded"].ID: + return _MockL1BridgeAdapter.ParseLiquidityAdded(log) + case _MockL1BridgeAdapter.abi.Events["LiquidityRemoved"].ID: + return _MockL1BridgeAdapter.ParseLiquidityRemoved(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (MockL1BridgeAdapterLiquidityAdded) Topic() common.Hash { + return common.HexToHash("0xc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb312088") +} + +func (MockL1BridgeAdapterLiquidityRemoved) Topic() common.Hash { + return common.HexToHash("0xc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf9840171719") +} + +func (_MockL1BridgeAdapter *MockL1BridgeAdapter) Address() common.Address { + return _MockL1BridgeAdapter.address +} + +type MockL1BridgeAdapterInterface interface { + EncodeFinalizePayload(opts *bind.CallOpts, payload MockL1BridgeAdapterFinalizePayload) error + + EncodePayload(opts *bind.CallOpts, payload MockL1BridgeAdapterPayload) error + + EncodeProvePayload(opts *bind.CallOpts, payload MockL1BridgeAdapterProvePayload) error + + GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) + + FinalizeWithdrawERC20(opts *bind.TransactOpts, arg0 common.Address, localReceiver common.Address, bridgeSpecificPayload []byte) (*types.Transaction, error) + + ProvideLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + SendERC20(opts *bind.TransactOpts, localToken common.Address, arg1 common.Address, arg2 common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) + + WithdrawLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + Receive(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterLiquidityAdded(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*MockL1BridgeAdapterLiquidityAddedIterator, error) + + WatchLiquidityAdded(opts *bind.WatchOpts, sink chan<- *MockL1BridgeAdapterLiquidityAdded, provider []common.Address, amount []*big.Int) (event.Subscription, error) + + ParseLiquidityAdded(log types.Log) (*MockL1BridgeAdapterLiquidityAdded, error) + + FilterLiquidityRemoved(opts *bind.FilterOpts, provider []common.Address, amount []*big.Int) (*MockL1BridgeAdapterLiquidityRemovedIterator, error) + + WatchLiquidityRemoved(opts *bind.WatchOpts, sink chan<- *MockL1BridgeAdapterLiquidityRemoved, provider []common.Address, amount []*big.Int) (event.Subscription, error) + + ParseLiquidityRemoved(log types.Log) (*MockL1BridgeAdapterLiquidityRemoved, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/mock_l2_bridge_adapter/mock_l2_bridge_adapter.go b/core/gethwrappers/liquiditymanager/generated/mock_l2_bridge_adapter/mock_l2_bridge_adapter.go new file mode 100644 index 0000000000..463214247f --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/mock_l2_bridge_adapter/mock_l2_bridge_adapter.go @@ -0,0 +1,240 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package mock_l2_bridge_adapter + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var MockL2BridgeAdapterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"BridgeAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wanted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InsufficientEthValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"MsgShouldNotContainValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"MsgValueDoesNotMatchAmount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"finalizeWithdrawERC20\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBridgeFeeInNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"sendERC20\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061035f806100206000396000f3fe6080604052600436106100345760003560e01c80632e4b1fc91461003957806338314bb21461005a578063a71d98b71461008f575b600080fd5b34801561004557600080fd5b50604051600081526020015b60405180910390f35b34801561006657600080fd5b5061007f6100753660046101dc565b6001949350505050565b6040519015158152602001610051565b6100a261009d36600461023d565b6100af565b60405161005191906102bc565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810184905260609073ffffffffffffffffffffffffffffffffffffffff8816906323b872dd906064016020604051808303816000875af115801561012b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014f9190610329565b50506040805160208101909152600081529695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461018e57600080fd5b919050565b60008083601f8401126101a557600080fd5b50813567ffffffffffffffff8111156101bd57600080fd5b6020830191508360208285010111156101d557600080fd5b9250929050565b600080600080606085870312156101f257600080fd5b6101fb8561016a565b93506102096020860161016a565b9250604085013567ffffffffffffffff81111561022557600080fd5b61023187828801610193565b95989497509550505050565b60008060008060008060a0878903121561025657600080fd5b61025f8761016a565b955061026d6020880161016a565b945061027b6040880161016a565b935060608701359250608087013567ffffffffffffffff81111561029e57600080fd5b6102aa89828a01610193565b979a9699509497509295939492505050565b60006020808352835180602085015260005b818110156102ea578581018301518582016040015282016102ce565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561033b57600080fd5b8151801515811461034b57600080fd5b939250505056fea164736f6c6343000818000a", +} + +var MockL2BridgeAdapterABI = MockL2BridgeAdapterMetaData.ABI + +var MockL2BridgeAdapterBin = MockL2BridgeAdapterMetaData.Bin + +func DeployMockL2BridgeAdapter(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MockL2BridgeAdapter, error) { + parsed, err := MockL2BridgeAdapterMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MockL2BridgeAdapterBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MockL2BridgeAdapter{address: address, abi: *parsed, MockL2BridgeAdapterCaller: MockL2BridgeAdapterCaller{contract: contract}, MockL2BridgeAdapterTransactor: MockL2BridgeAdapterTransactor{contract: contract}, MockL2BridgeAdapterFilterer: MockL2BridgeAdapterFilterer{contract: contract}}, nil +} + +type MockL2BridgeAdapter struct { + address common.Address + abi abi.ABI + MockL2BridgeAdapterCaller + MockL2BridgeAdapterTransactor + MockL2BridgeAdapterFilterer +} + +type MockL2BridgeAdapterCaller struct { + contract *bind.BoundContract +} + +type MockL2BridgeAdapterTransactor struct { + contract *bind.BoundContract +} + +type MockL2BridgeAdapterFilterer struct { + contract *bind.BoundContract +} + +type MockL2BridgeAdapterSession struct { + Contract *MockL2BridgeAdapter + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type MockL2BridgeAdapterCallerSession struct { + Contract *MockL2BridgeAdapterCaller + CallOpts bind.CallOpts +} + +type MockL2BridgeAdapterTransactorSession struct { + Contract *MockL2BridgeAdapterTransactor + TransactOpts bind.TransactOpts +} + +type MockL2BridgeAdapterRaw struct { + Contract *MockL2BridgeAdapter +} + +type MockL2BridgeAdapterCallerRaw struct { + Contract *MockL2BridgeAdapterCaller +} + +type MockL2BridgeAdapterTransactorRaw struct { + Contract *MockL2BridgeAdapterTransactor +} + +func NewMockL2BridgeAdapter(address common.Address, backend bind.ContractBackend) (*MockL2BridgeAdapter, error) { + abi, err := abi.JSON(strings.NewReader(MockL2BridgeAdapterABI)) + if err != nil { + return nil, err + } + contract, err := bindMockL2BridgeAdapter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MockL2BridgeAdapter{address: address, abi: abi, MockL2BridgeAdapterCaller: MockL2BridgeAdapterCaller{contract: contract}, MockL2BridgeAdapterTransactor: MockL2BridgeAdapterTransactor{contract: contract}, MockL2BridgeAdapterFilterer: MockL2BridgeAdapterFilterer{contract: contract}}, nil +} + +func NewMockL2BridgeAdapterCaller(address common.Address, caller bind.ContractCaller) (*MockL2BridgeAdapterCaller, error) { + contract, err := bindMockL2BridgeAdapter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MockL2BridgeAdapterCaller{contract: contract}, nil +} + +func NewMockL2BridgeAdapterTransactor(address common.Address, transactor bind.ContractTransactor) (*MockL2BridgeAdapterTransactor, error) { + contract, err := bindMockL2BridgeAdapter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MockL2BridgeAdapterTransactor{contract: contract}, nil +} + +func NewMockL2BridgeAdapterFilterer(address common.Address, filterer bind.ContractFilterer) (*MockL2BridgeAdapterFilterer, error) { + contract, err := bindMockL2BridgeAdapter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MockL2BridgeAdapterFilterer{contract: contract}, nil +} + +func bindMockL2BridgeAdapter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MockL2BridgeAdapterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockL2BridgeAdapter.Contract.MockL2BridgeAdapterCaller.contract.Call(opts, result, method, params...) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockL2BridgeAdapter.Contract.MockL2BridgeAdapterTransactor.contract.Transfer(opts) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockL2BridgeAdapter.Contract.MockL2BridgeAdapterTransactor.contract.Transact(opts, method, params...) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockL2BridgeAdapter.Contract.contract.Call(opts, result, method, params...) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockL2BridgeAdapter.Contract.contract.Transfer(opts) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockL2BridgeAdapter.Contract.contract.Transact(opts, method, params...) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterCaller) FinalizeWithdrawERC20(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) { + var out []interface{} + err := _MockL2BridgeAdapter.contract.Call(opts, &out, "finalizeWithdrawERC20", arg0, arg1, arg2) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterSession) FinalizeWithdrawERC20(arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) { + return _MockL2BridgeAdapter.Contract.FinalizeWithdrawERC20(&_MockL2BridgeAdapter.CallOpts, arg0, arg1, arg2) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterCallerSession) FinalizeWithdrawERC20(arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) { + return _MockL2BridgeAdapter.Contract.FinalizeWithdrawERC20(&_MockL2BridgeAdapter.CallOpts, arg0, arg1, arg2) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterCaller) GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MockL2BridgeAdapter.contract.Call(opts, &out, "getBridgeFeeInNative") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterSession) GetBridgeFeeInNative() (*big.Int, error) { + return _MockL2BridgeAdapter.Contract.GetBridgeFeeInNative(&_MockL2BridgeAdapter.CallOpts) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterCallerSession) GetBridgeFeeInNative() (*big.Int, error) { + return _MockL2BridgeAdapter.Contract.GetBridgeFeeInNative(&_MockL2BridgeAdapter.CallOpts) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterTransactor) SendERC20(opts *bind.TransactOpts, localToken common.Address, arg1 common.Address, arg2 common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _MockL2BridgeAdapter.contract.Transact(opts, "sendERC20", localToken, arg1, arg2, amount, arg4) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterSession) SendERC20(localToken common.Address, arg1 common.Address, arg2 common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _MockL2BridgeAdapter.Contract.SendERC20(&_MockL2BridgeAdapter.TransactOpts, localToken, arg1, arg2, amount, arg4) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapterTransactorSession) SendERC20(localToken common.Address, arg1 common.Address, arg2 common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _MockL2BridgeAdapter.Contract.SendERC20(&_MockL2BridgeAdapter.TransactOpts, localToken, arg1, arg2, amount, arg4) +} + +func (_MockL2BridgeAdapter *MockL2BridgeAdapter) Address() common.Address { + return _MockL2BridgeAdapter.address +} + +type MockL2BridgeAdapterInterface interface { + FinalizeWithdrawERC20(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) + + GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) + + SendERC20(opts *bind.TransactOpts, localToken common.Address, arg1 common.Address, arg2 common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/no_op_ocr3/no_op_ocr3.go b/core/gethwrappers/liquiditymanager/generated/no_op_ocr3/no_op_ocr3.go new file mode 100644 index 0000000000..c9dca8b5f4 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/no_op_ocr3/no_op_ocr3.go @@ -0,0 +1,946 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package no_op_ocr3 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var NoOpOCR3MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"latestSequenceNumber\",\"type\":\"uint64\"}],\"name\":\"NonIncreasingSequenceNumber\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR3Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b038481169190911790915581161561009757610097816100a3565b5050466080525061014c565b336001600160a01b038216036100fb5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b608051611c0d6200016f60003960008181610cb40152610d000152611c0d6000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c806381ff704811610076578063b1dc65a41161005b578063b1dc65a414610184578063f1c0461614610197578063f2fde38b146101c957600080fd5b806381ff70481461012c5780638da5cb5b1461015c57600080fd5b8063181f5a77146100a8578063666cab8d146100fa5780636a11ee901461010f57806379ba509714610124575b600080fd5b6100e46040518060400160405280600e81526020017f4e6f4f704f43523320312e302e3000000000000000000000000000000000000081525081565b6040516100f1919061153b565b60405180910390f35b6101026101dc565b6040516100f191906115a7565b61012261011d36600461179f565b61024b565b005b610122610a7f565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016100f1565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f1565b6101226101923660046118b8565b610b7c565b60045468010000000000000000900467ffffffffffffffff1660405167ffffffffffffffff90911681526020016100f1565b6101226101d736600461199d565b6111e2565b6060600780548060200260200160405190810160405280929190818152602001828054801561024157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610216575b5050505050905090565b855185518560ff16601f8311156102c3576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b8060000361032d576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f736974697665000000000000000000000000000060448201526064016102ba565b8183146103bb576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e0000000000000000000000000000000000000000000000000000000060648201526084016102ba565b6103c68160036119e7565b831161042e576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f2068696768000000000000000060448201526064016102ba565b6104366111f6565b60065460005b8181101561052a57600560006006838154811061045b5761045b611a04565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600780546005929190849081106104cb576104cb611a04565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161043c565b50895160005b818110156108fd5760008c828151811061054c5761054c611a04565b602002602001015190506000600281111561056957610569611a33565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff1660028111156105a8576105a8611a33565b1461060f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e6572206164647265737300000000000000000060448201526064016102ba565b73ffffffffffffffffffffffffffffffffffffffff811661065c576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561070c5761070c611a33565b021790555090505060008c838151811061072857610728611a04565b602002602001015190506000600281111561074557610745611a33565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561078457610784611a33565b146107eb576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d697474657220616464726573730000000060448201526064016102ba565b73ffffffffffffffffffffffffffffffffffffffff8116610838576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156108e8576108e8611a33565b02179055509050505050806001019050610530565b508a516109119060069060208e0190611419565b5089516109259060079060208d0190611419565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c1617179055600480546109ab91469130919060009061097d9063ffffffff16611a62565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611279565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055506000600460086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610a6999989796959493929190611a85565b60405180910390a1505050505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016102ba565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60045460208901359067ffffffffffffffff68010000000000000000909104811690821611610bff57600480546040517f6e376b6600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808516938201939093526801000000000000000090910490911660248201526044016102ba565b600480547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff8416021790556040805160608101825260025480825260035460ff808216602085015261010090910416928201929092528a35918214610cb15780516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018390526044016102ba565b467f000000000000000000000000000000000000000000000000000000000000000014610d32576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016102ba565b6040805183815267ffffffffffffffff851660208201527fe893c2681d327421d89e1cb54fbe64645b4dcea668d6826130b62cf4c6eefea2910160405180910390a16020810151610d84906001611b1b565b60ff168714610dbf576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514610df8576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff80821684529293919291840191610100909104166002811115610e3b57610e3b611a33565b6002811115610e4c57610e4c611a33565b9052509050600281602001516002811115610e6957610e69611a33565b148015610eb057506007816000015160ff1681548110610e8b57610e8b611a04565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b610ee6576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000610ef48660206119e7565b610eff8960206119e7565b610f0b8c610144611b34565b610f159190611b34565b610f1f9190611b34565b9050368114610f63576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016102ba565b5060008a8a604051610f76929190611b47565b604051908190038120610f8d918e90602001611b57565b604051602081830303815290604052805190602001209050610fad6114a3565b8860005b818110156111d15760006001858a8460208110610fd057610fd0611a04565b610fdd91901a601b611b1b565b8f8f86818110610fef57610fef611a04565b905060200201358e8e8781811061100857611008611a04565b9050602002013560405160008152602001604052604051611045949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611067573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff80821686529397509195509293928401916101009091041660028111156110ea576110ea611a33565b60028111156110fb576110fb611a33565b905250905060018160200151600281111561111857611118611a33565b1461114f576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061116657611166611a04565b6020020151156111a2576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106111bd576111bd611a04565b911515602090920201525050600101610fb1565b505050505050505050505050505050565b6111ea6111f6565b6111f381611324565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611277576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102ba565b565b6000808a8a8a8a8a8a8a8a8a60405160200161129d99989796959493929190611b6b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036113a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102ba565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215611493579160200282015b8281111561149357825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190611439565b5061149f9291506114c2565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561149f57600081556001016114c3565b6000815180845260005b818110156114fd576020818501810151868301820152016114e1565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061154e60208301846114d7565b9392505050565b60008151808452602080850194506020840160005b8381101561159c57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161156a565b509495945050505050565b60208152600061154e6020830184611555565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611630576116306115ba565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461165c57600080fd5b919050565b600082601f83011261167257600080fd5b8135602067ffffffffffffffff82111561168e5761168e6115ba565b8160051b61169d8282016115e9565b92835284810182019282810190878511156116b757600080fd5b83870192505b848310156116dd576116ce83611638565b825291830191908301906116bd565b979650505050505050565b803560ff8116811461165c57600080fd5b600082601f83011261170a57600080fd5b813567ffffffffffffffff811115611724576117246115ba565b61175560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016115e9565b81815284602083860101111561176a57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff8116811461165c57600080fd5b60008060008060008060c087890312156117b857600080fd5b863567ffffffffffffffff808211156117d057600080fd5b6117dc8a838b01611661565b975060208901359150808211156117f257600080fd5b6117fe8a838b01611661565b965061180c60408a016116e8565b9550606089013591508082111561182257600080fd5b61182e8a838b016116f9565b945061183c60808a01611787565b935060a089013591508082111561185257600080fd5b5061185f89828a016116f9565b9150509295509295509295565b60008083601f84011261187e57600080fd5b50813567ffffffffffffffff81111561189657600080fd5b6020830191508360208260051b85010111156118b157600080fd5b9250929050565b60008060008060008060008060e0898b0312156118d457600080fd5b606089018a8111156118e557600080fd5b8998503567ffffffffffffffff808211156118ff57600080fd5b818b0191508b601f83011261191357600080fd5b81358181111561192257600080fd5b8c602082850101111561193457600080fd5b6020830199508098505060808b013591508082111561195257600080fd5b61195e8c838d0161186c565b909750955060a08b013591508082111561197757600080fd5b506119848b828c0161186c565b999c989b50969995989497949560c00135949350505050565b6000602082840312156119af57600080fd5b61154e82611638565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176119fe576119fe6119b8565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103611a7b57611a7b6119b8565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152611ab58184018a611555565b90508281036080840152611ac98189611555565b905060ff871660a084015282810360c0840152611ae681876114d7565b905067ffffffffffffffff851660e0840152828103610100840152611b0b81856114d7565b9c9b505050505050505050505050565b60ff81811683821601908111156119fe576119fe6119b8565b808201808211156119fe576119fe6119b8565b8183823760009101908152919050565b828152606082602083013760800192915050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152611bb28285018b611555565b91508382036080850152611bc6828a611555565b915060ff881660a085015283820360c0850152611be382886114d7565b90861660e08501528381036101008501529050611b0b81856114d756fea164736f6c6343000818000a", +} + +var NoOpOCR3ABI = NoOpOCR3MetaData.ABI + +var NoOpOCR3Bin = NoOpOCR3MetaData.Bin + +func DeployNoOpOCR3(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *NoOpOCR3, error) { + parsed, err := NoOpOCR3MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(NoOpOCR3Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NoOpOCR3{address: address, abi: *parsed, NoOpOCR3Caller: NoOpOCR3Caller{contract: contract}, NoOpOCR3Transactor: NoOpOCR3Transactor{contract: contract}, NoOpOCR3Filterer: NoOpOCR3Filterer{contract: contract}}, nil +} + +type NoOpOCR3 struct { + address common.Address + abi abi.ABI + NoOpOCR3Caller + NoOpOCR3Transactor + NoOpOCR3Filterer +} + +type NoOpOCR3Caller struct { + contract *bind.BoundContract +} + +type NoOpOCR3Transactor struct { + contract *bind.BoundContract +} + +type NoOpOCR3Filterer struct { + contract *bind.BoundContract +} + +type NoOpOCR3Session struct { + Contract *NoOpOCR3 + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type NoOpOCR3CallerSession struct { + Contract *NoOpOCR3Caller + CallOpts bind.CallOpts +} + +type NoOpOCR3TransactorSession struct { + Contract *NoOpOCR3Transactor + TransactOpts bind.TransactOpts +} + +type NoOpOCR3Raw struct { + Contract *NoOpOCR3 +} + +type NoOpOCR3CallerRaw struct { + Contract *NoOpOCR3Caller +} + +type NoOpOCR3TransactorRaw struct { + Contract *NoOpOCR3Transactor +} + +func NewNoOpOCR3(address common.Address, backend bind.ContractBackend) (*NoOpOCR3, error) { + abi, err := abi.JSON(strings.NewReader(NoOpOCR3ABI)) + if err != nil { + return nil, err + } + contract, err := bindNoOpOCR3(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NoOpOCR3{address: address, abi: abi, NoOpOCR3Caller: NoOpOCR3Caller{contract: contract}, NoOpOCR3Transactor: NoOpOCR3Transactor{contract: contract}, NoOpOCR3Filterer: NoOpOCR3Filterer{contract: contract}}, nil +} + +func NewNoOpOCR3Caller(address common.Address, caller bind.ContractCaller) (*NoOpOCR3Caller, error) { + contract, err := bindNoOpOCR3(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NoOpOCR3Caller{contract: contract}, nil +} + +func NewNoOpOCR3Transactor(address common.Address, transactor bind.ContractTransactor) (*NoOpOCR3Transactor, error) { + contract, err := bindNoOpOCR3(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NoOpOCR3Transactor{contract: contract}, nil +} + +func NewNoOpOCR3Filterer(address common.Address, filterer bind.ContractFilterer) (*NoOpOCR3Filterer, error) { + contract, err := bindNoOpOCR3(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NoOpOCR3Filterer{contract: contract}, nil +} + +func bindNoOpOCR3(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NoOpOCR3MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_NoOpOCR3 *NoOpOCR3Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NoOpOCR3.Contract.NoOpOCR3Caller.contract.Call(opts, result, method, params...) +} + +func (_NoOpOCR3 *NoOpOCR3Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NoOpOCR3.Contract.NoOpOCR3Transactor.contract.Transfer(opts) +} + +func (_NoOpOCR3 *NoOpOCR3Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NoOpOCR3.Contract.NoOpOCR3Transactor.contract.Transact(opts, method, params...) +} + +func (_NoOpOCR3 *NoOpOCR3CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NoOpOCR3.Contract.contract.Call(opts, result, method, params...) +} + +func (_NoOpOCR3 *NoOpOCR3TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NoOpOCR3.Contract.contract.Transfer(opts) +} + +func (_NoOpOCR3 *NoOpOCR3TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NoOpOCR3.Contract.contract.Transact(opts, method, params...) +} + +func (_NoOpOCR3 *NoOpOCR3Caller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _NoOpOCR3.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_NoOpOCR3 *NoOpOCR3Session) GetTransmitters() ([]common.Address, error) { + return _NoOpOCR3.Contract.GetTransmitters(&_NoOpOCR3.CallOpts) +} + +func (_NoOpOCR3 *NoOpOCR3CallerSession) GetTransmitters() ([]common.Address, error) { + return _NoOpOCR3.Contract.GetTransmitters(&_NoOpOCR3.CallOpts) +} + +func (_NoOpOCR3 *NoOpOCR3Caller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _NoOpOCR3.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_NoOpOCR3 *NoOpOCR3Session) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _NoOpOCR3.Contract.LatestConfigDetails(&_NoOpOCR3.CallOpts) +} + +func (_NoOpOCR3 *NoOpOCR3CallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _NoOpOCR3.Contract.LatestConfigDetails(&_NoOpOCR3.CallOpts) +} + +func (_NoOpOCR3 *NoOpOCR3Caller) LatestSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _NoOpOCR3.contract.Call(opts, &out, "latestSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_NoOpOCR3 *NoOpOCR3Session) LatestSequenceNumber() (uint64, error) { + return _NoOpOCR3.Contract.LatestSequenceNumber(&_NoOpOCR3.CallOpts) +} + +func (_NoOpOCR3 *NoOpOCR3CallerSession) LatestSequenceNumber() (uint64, error) { + return _NoOpOCR3.Contract.LatestSequenceNumber(&_NoOpOCR3.CallOpts) +} + +func (_NoOpOCR3 *NoOpOCR3Caller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NoOpOCR3.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_NoOpOCR3 *NoOpOCR3Session) Owner() (common.Address, error) { + return _NoOpOCR3.Contract.Owner(&_NoOpOCR3.CallOpts) +} + +func (_NoOpOCR3 *NoOpOCR3CallerSession) Owner() (common.Address, error) { + return _NoOpOCR3.Contract.Owner(&_NoOpOCR3.CallOpts) +} + +func (_NoOpOCR3 *NoOpOCR3Caller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _NoOpOCR3.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_NoOpOCR3 *NoOpOCR3Session) TypeAndVersion() (string, error) { + return _NoOpOCR3.Contract.TypeAndVersion(&_NoOpOCR3.CallOpts) +} + +func (_NoOpOCR3 *NoOpOCR3CallerSession) TypeAndVersion() (string, error) { + return _NoOpOCR3.Contract.TypeAndVersion(&_NoOpOCR3.CallOpts) +} + +func (_NoOpOCR3 *NoOpOCR3Transactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NoOpOCR3.contract.Transact(opts, "acceptOwnership") +} + +func (_NoOpOCR3 *NoOpOCR3Session) AcceptOwnership() (*types.Transaction, error) { + return _NoOpOCR3.Contract.AcceptOwnership(&_NoOpOCR3.TransactOpts) +} + +func (_NoOpOCR3 *NoOpOCR3TransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _NoOpOCR3.Contract.AcceptOwnership(&_NoOpOCR3.TransactOpts) +} + +func (_NoOpOCR3 *NoOpOCR3Transactor) SetOCR3Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _NoOpOCR3.contract.Transact(opts, "setOCR3Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_NoOpOCR3 *NoOpOCR3Session) SetOCR3Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _NoOpOCR3.Contract.SetOCR3Config(&_NoOpOCR3.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_NoOpOCR3 *NoOpOCR3TransactorSession) SetOCR3Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _NoOpOCR3.Contract.SetOCR3Config(&_NoOpOCR3.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_NoOpOCR3 *NoOpOCR3Transactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _NoOpOCR3.contract.Transact(opts, "transferOwnership", to) +} + +func (_NoOpOCR3 *NoOpOCR3Session) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _NoOpOCR3.Contract.TransferOwnership(&_NoOpOCR3.TransactOpts, to) +} + +func (_NoOpOCR3 *NoOpOCR3TransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _NoOpOCR3.Contract.TransferOwnership(&_NoOpOCR3.TransactOpts, to) +} + +func (_NoOpOCR3 *NoOpOCR3Transactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _NoOpOCR3.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) +} + +func (_NoOpOCR3 *NoOpOCR3Session) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _NoOpOCR3.Contract.Transmit(&_NoOpOCR3.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_NoOpOCR3 *NoOpOCR3TransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _NoOpOCR3.Contract.Transmit(&_NoOpOCR3.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +type NoOpOCR3ConfigSetIterator struct { + Event *NoOpOCR3ConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NoOpOCR3ConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NoOpOCR3ConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NoOpOCR3ConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NoOpOCR3ConfigSetIterator) Error() error { + return it.fail +} + +func (it *NoOpOCR3ConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NoOpOCR3ConfigSet struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_NoOpOCR3 *NoOpOCR3Filterer) FilterConfigSet(opts *bind.FilterOpts) (*NoOpOCR3ConfigSetIterator, error) { + + logs, sub, err := _NoOpOCR3.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &NoOpOCR3ConfigSetIterator{contract: _NoOpOCR3.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_NoOpOCR3 *NoOpOCR3Filterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *NoOpOCR3ConfigSet) (event.Subscription, error) { + + logs, sub, err := _NoOpOCR3.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NoOpOCR3ConfigSet) + if err := _NoOpOCR3.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NoOpOCR3 *NoOpOCR3Filterer) ParseConfigSet(log types.Log) (*NoOpOCR3ConfigSet, error) { + event := new(NoOpOCR3ConfigSet) + if err := _NoOpOCR3.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NoOpOCR3OwnershipTransferRequestedIterator struct { + Event *NoOpOCR3OwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NoOpOCR3OwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NoOpOCR3OwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NoOpOCR3OwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NoOpOCR3OwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *NoOpOCR3OwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NoOpOCR3OwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_NoOpOCR3 *NoOpOCR3Filterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NoOpOCR3OwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NoOpOCR3.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &NoOpOCR3OwnershipTransferRequestedIterator{contract: _NoOpOCR3.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_NoOpOCR3 *NoOpOCR3Filterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *NoOpOCR3OwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NoOpOCR3.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NoOpOCR3OwnershipTransferRequested) + if err := _NoOpOCR3.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NoOpOCR3 *NoOpOCR3Filterer) ParseOwnershipTransferRequested(log types.Log) (*NoOpOCR3OwnershipTransferRequested, error) { + event := new(NoOpOCR3OwnershipTransferRequested) + if err := _NoOpOCR3.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NoOpOCR3OwnershipTransferredIterator struct { + Event *NoOpOCR3OwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NoOpOCR3OwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NoOpOCR3OwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NoOpOCR3OwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NoOpOCR3OwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *NoOpOCR3OwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NoOpOCR3OwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_NoOpOCR3 *NoOpOCR3Filterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NoOpOCR3OwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NoOpOCR3.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &NoOpOCR3OwnershipTransferredIterator{contract: _NoOpOCR3.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_NoOpOCR3 *NoOpOCR3Filterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *NoOpOCR3OwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NoOpOCR3.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NoOpOCR3OwnershipTransferred) + if err := _NoOpOCR3.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NoOpOCR3 *NoOpOCR3Filterer) ParseOwnershipTransferred(log types.Log) (*NoOpOCR3OwnershipTransferred, error) { + event := new(NoOpOCR3OwnershipTransferred) + if err := _NoOpOCR3.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NoOpOCR3TransmittedIterator struct { + Event *NoOpOCR3Transmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NoOpOCR3TransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NoOpOCR3Transmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NoOpOCR3Transmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *NoOpOCR3TransmittedIterator) Error() error { + return it.fail +} + +func (it *NoOpOCR3TransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NoOpOCR3Transmitted struct { + ConfigDigest [32]byte + SequenceNumber uint64 + Raw types.Log +} + +func (_NoOpOCR3 *NoOpOCR3Filterer) FilterTransmitted(opts *bind.FilterOpts) (*NoOpOCR3TransmittedIterator, error) { + + logs, sub, err := _NoOpOCR3.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &NoOpOCR3TransmittedIterator{contract: _NoOpOCR3.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_NoOpOCR3 *NoOpOCR3Filterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *NoOpOCR3Transmitted) (event.Subscription, error) { + + logs, sub, err := _NoOpOCR3.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NoOpOCR3Transmitted) + if err := _NoOpOCR3.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NoOpOCR3 *NoOpOCR3Filterer) ParseTransmitted(log types.Log) (*NoOpOCR3Transmitted, error) { + event := new(NoOpOCR3Transmitted) + if err := _NoOpOCR3.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} + +func (_NoOpOCR3 *NoOpOCR3) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _NoOpOCR3.abi.Events["ConfigSet"].ID: + return _NoOpOCR3.ParseConfigSet(log) + case _NoOpOCR3.abi.Events["OwnershipTransferRequested"].ID: + return _NoOpOCR3.ParseOwnershipTransferRequested(log) + case _NoOpOCR3.abi.Events["OwnershipTransferred"].ID: + return _NoOpOCR3.ParseOwnershipTransferred(log) + case _NoOpOCR3.abi.Events["Transmitted"].ID: + return _NoOpOCR3.ParseTransmitted(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (NoOpOCR3ConfigSet) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (NoOpOCR3OwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (NoOpOCR3OwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (NoOpOCR3Transmitted) Topic() common.Hash { + return common.HexToHash("0xe893c2681d327421d89e1cb54fbe64645b4dcea668d6826130b62cf4c6eefea2") +} + +func (_NoOpOCR3 *NoOpOCR3) Address() common.Address { + return _NoOpOCR3.address +} + +type NoOpOCR3Interface interface { + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestSequenceNumber(opts *bind.CallOpts) (uint64, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + SetOCR3Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*NoOpOCR3ConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *NoOpOCR3ConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*NoOpOCR3ConfigSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NoOpOCR3OwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *NoOpOCR3OwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*NoOpOCR3OwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NoOpOCR3OwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *NoOpOCR3OwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*NoOpOCR3OwnershipTransferred, error) + + FilterTransmitted(opts *bind.FilterOpts) (*NoOpOCR3TransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *NoOpOCR3Transmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*NoOpOCR3Transmitted, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/optimism_cross_domain_messenger/optimism_cross_domain_messenger.go b/core/gethwrappers/liquiditymanager/generated/optimism_cross_domain_messenger/optimism_cross_domain_messenger.go new file mode 100644 index 0000000000..599d2e3739 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/optimism_cross_domain_messenger/optimism_cross_domain_messenger.go @@ -0,0 +1,328 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_cross_domain_messenger + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var OptimismCrossDomainMessengerMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"SentMessage\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"relayMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]", +} + +var OptimismCrossDomainMessengerABI = OptimismCrossDomainMessengerMetaData.ABI + +type OptimismCrossDomainMessenger struct { + address common.Address + abi abi.ABI + OptimismCrossDomainMessengerCaller + OptimismCrossDomainMessengerTransactor + OptimismCrossDomainMessengerFilterer +} + +type OptimismCrossDomainMessengerCaller struct { + contract *bind.BoundContract +} + +type OptimismCrossDomainMessengerTransactor struct { + contract *bind.BoundContract +} + +type OptimismCrossDomainMessengerFilterer struct { + contract *bind.BoundContract +} + +type OptimismCrossDomainMessengerSession struct { + Contract *OptimismCrossDomainMessenger + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismCrossDomainMessengerCallerSession struct { + Contract *OptimismCrossDomainMessengerCaller + CallOpts bind.CallOpts +} + +type OptimismCrossDomainMessengerTransactorSession struct { + Contract *OptimismCrossDomainMessengerTransactor + TransactOpts bind.TransactOpts +} + +type OptimismCrossDomainMessengerRaw struct { + Contract *OptimismCrossDomainMessenger +} + +type OptimismCrossDomainMessengerCallerRaw struct { + Contract *OptimismCrossDomainMessengerCaller +} + +type OptimismCrossDomainMessengerTransactorRaw struct { + Contract *OptimismCrossDomainMessengerTransactor +} + +func NewOptimismCrossDomainMessenger(address common.Address, backend bind.ContractBackend) (*OptimismCrossDomainMessenger, error) { + abi, err := abi.JSON(strings.NewReader(OptimismCrossDomainMessengerABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismCrossDomainMessenger(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismCrossDomainMessenger{address: address, abi: abi, OptimismCrossDomainMessengerCaller: OptimismCrossDomainMessengerCaller{contract: contract}, OptimismCrossDomainMessengerTransactor: OptimismCrossDomainMessengerTransactor{contract: contract}, OptimismCrossDomainMessengerFilterer: OptimismCrossDomainMessengerFilterer{contract: contract}}, nil +} + +func NewOptimismCrossDomainMessengerCaller(address common.Address, caller bind.ContractCaller) (*OptimismCrossDomainMessengerCaller, error) { + contract, err := bindOptimismCrossDomainMessenger(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismCrossDomainMessengerCaller{contract: contract}, nil +} + +func NewOptimismCrossDomainMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*OptimismCrossDomainMessengerTransactor, error) { + contract, err := bindOptimismCrossDomainMessenger(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismCrossDomainMessengerTransactor{contract: contract}, nil +} + +func NewOptimismCrossDomainMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*OptimismCrossDomainMessengerFilterer, error) { + contract, err := bindOptimismCrossDomainMessenger(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismCrossDomainMessengerFilterer{contract: contract}, nil +} + +func bindOptimismCrossDomainMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismCrossDomainMessengerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismCrossDomainMessenger.Contract.OptimismCrossDomainMessengerCaller.contract.Call(opts, result, method, params...) +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismCrossDomainMessenger.Contract.OptimismCrossDomainMessengerTransactor.contract.Transfer(opts) +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismCrossDomainMessenger.Contract.OptimismCrossDomainMessengerTransactor.contract.Transact(opts, method, params...) +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismCrossDomainMessenger.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismCrossDomainMessenger.Contract.contract.Transfer(opts) +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismCrossDomainMessenger.Contract.contract.Transact(opts, method, params...) +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessengerTransactor) RelayMessage(opts *bind.TransactOpts, _nonce *big.Int, _sender common.Address, _target common.Address, _value *big.Int, _minGasLimit *big.Int, _message []byte) (*types.Transaction, error) { + return _OptimismCrossDomainMessenger.contract.Transact(opts, "relayMessage", _nonce, _sender, _target, _value, _minGasLimit, _message) +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessengerSession) RelayMessage(_nonce *big.Int, _sender common.Address, _target common.Address, _value *big.Int, _minGasLimit *big.Int, _message []byte) (*types.Transaction, error) { + return _OptimismCrossDomainMessenger.Contract.RelayMessage(&_OptimismCrossDomainMessenger.TransactOpts, _nonce, _sender, _target, _value, _minGasLimit, _message) +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessengerTransactorSession) RelayMessage(_nonce *big.Int, _sender common.Address, _target common.Address, _value *big.Int, _minGasLimit *big.Int, _message []byte) (*types.Transaction, error) { + return _OptimismCrossDomainMessenger.Contract.RelayMessage(&_OptimismCrossDomainMessenger.TransactOpts, _nonce, _sender, _target, _value, _minGasLimit, _message) +} + +type OptimismCrossDomainMessengerSentMessageIterator struct { + Event *OptimismCrossDomainMessengerSentMessage + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OptimismCrossDomainMessengerSentMessageIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OptimismCrossDomainMessengerSentMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(OptimismCrossDomainMessengerSentMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *OptimismCrossDomainMessengerSentMessageIterator) Error() error { + return it.fail +} + +func (it *OptimismCrossDomainMessengerSentMessageIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OptimismCrossDomainMessengerSentMessage struct { + Target common.Address + Sender common.Address + Message []byte + MessageNonce *big.Int + GasLimit *big.Int + Raw types.Log +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessengerFilterer) FilterSentMessage(opts *bind.FilterOpts, target []common.Address) (*OptimismCrossDomainMessengerSentMessageIterator, error) { + + var targetRule []interface{} + for _, targetItem := range target { + targetRule = append(targetRule, targetItem) + } + + logs, sub, err := _OptimismCrossDomainMessenger.contract.FilterLogs(opts, "SentMessage", targetRule) + if err != nil { + return nil, err + } + return &OptimismCrossDomainMessengerSentMessageIterator{contract: _OptimismCrossDomainMessenger.contract, event: "SentMessage", logs: logs, sub: sub}, nil +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessengerFilterer) WatchSentMessage(opts *bind.WatchOpts, sink chan<- *OptimismCrossDomainMessengerSentMessage, target []common.Address) (event.Subscription, error) { + + var targetRule []interface{} + for _, targetItem := range target { + targetRule = append(targetRule, targetItem) + } + + logs, sub, err := _OptimismCrossDomainMessenger.contract.WatchLogs(opts, "SentMessage", targetRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OptimismCrossDomainMessengerSentMessage) + if err := _OptimismCrossDomainMessenger.contract.UnpackLog(event, "SentMessage", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessengerFilterer) ParseSentMessage(log types.Log) (*OptimismCrossDomainMessengerSentMessage, error) { + event := new(OptimismCrossDomainMessengerSentMessage) + if err := _OptimismCrossDomainMessenger.contract.UnpackLog(event, "SentMessage", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessenger) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _OptimismCrossDomainMessenger.abi.Events["SentMessage"].ID: + return _OptimismCrossDomainMessenger.ParseSentMessage(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (OptimismCrossDomainMessengerSentMessage) Topic() common.Hash { + return common.HexToHash("0xcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a") +} + +func (_OptimismCrossDomainMessenger *OptimismCrossDomainMessenger) Address() common.Address { + return _OptimismCrossDomainMessenger.address +} + +type OptimismCrossDomainMessengerInterface interface { + RelayMessage(opts *bind.TransactOpts, _nonce *big.Int, _sender common.Address, _target common.Address, _value *big.Int, _minGasLimit *big.Int, _message []byte) (*types.Transaction, error) + + FilterSentMessage(opts *bind.FilterOpts, target []common.Address) (*OptimismCrossDomainMessengerSentMessageIterator, error) + + WatchSentMessage(opts *bind.WatchOpts, sink chan<- *OptimismCrossDomainMessengerSentMessage, target []common.Address) (event.Subscription, error) + + ParseSentMessage(log types.Log) (*OptimismCrossDomainMessengerSentMessage, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/optimism_dispute_game_factory/optimism_dispute_game_factory.go b/core/gethwrappers/liquiditymanager/generated/optimism_dispute_game_factory/optimism_dispute_game_factory.go new file mode 100644 index 0000000000..909324ad1f --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/optimism_dispute_game_factory/optimism_dispute_game_factory.go @@ -0,0 +1,215 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_dispute_game_factory + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type IOptimismDisputeGameFactoryGameSearchResult struct { + Index *big.Int + Metadata [32]byte + Timestamp uint64 + RootClaim [32]byte + ExtraData []byte +} + +var OptimismDisputeGameFactoryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"GameType\",\"name\":\"_gameType\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_n\",\"type\":\"uint256\"}],\"name\":\"findLatestGames\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"GameId\",\"name\":\"metadata\",\"type\":\"bytes32\"},{\"internalType\":\"Timestamp\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"Claim\",\"name\":\"rootClaim\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"internalType\":\"structIOptimismDisputeGameFactory.GameSearchResult[]\",\"name\":\"games_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gameCount_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +var OptimismDisputeGameFactoryABI = OptimismDisputeGameFactoryMetaData.ABI + +type OptimismDisputeGameFactory struct { + address common.Address + abi abi.ABI + OptimismDisputeGameFactoryCaller + OptimismDisputeGameFactoryTransactor + OptimismDisputeGameFactoryFilterer +} + +type OptimismDisputeGameFactoryCaller struct { + contract *bind.BoundContract +} + +type OptimismDisputeGameFactoryTransactor struct { + contract *bind.BoundContract +} + +type OptimismDisputeGameFactoryFilterer struct { + contract *bind.BoundContract +} + +type OptimismDisputeGameFactorySession struct { + Contract *OptimismDisputeGameFactory + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismDisputeGameFactoryCallerSession struct { + Contract *OptimismDisputeGameFactoryCaller + CallOpts bind.CallOpts +} + +type OptimismDisputeGameFactoryTransactorSession struct { + Contract *OptimismDisputeGameFactoryTransactor + TransactOpts bind.TransactOpts +} + +type OptimismDisputeGameFactoryRaw struct { + Contract *OptimismDisputeGameFactory +} + +type OptimismDisputeGameFactoryCallerRaw struct { + Contract *OptimismDisputeGameFactoryCaller +} + +type OptimismDisputeGameFactoryTransactorRaw struct { + Contract *OptimismDisputeGameFactoryTransactor +} + +func NewOptimismDisputeGameFactory(address common.Address, backend bind.ContractBackend) (*OptimismDisputeGameFactory, error) { + abi, err := abi.JSON(strings.NewReader(OptimismDisputeGameFactoryABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismDisputeGameFactory(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismDisputeGameFactory{address: address, abi: abi, OptimismDisputeGameFactoryCaller: OptimismDisputeGameFactoryCaller{contract: contract}, OptimismDisputeGameFactoryTransactor: OptimismDisputeGameFactoryTransactor{contract: contract}, OptimismDisputeGameFactoryFilterer: OptimismDisputeGameFactoryFilterer{contract: contract}}, nil +} + +func NewOptimismDisputeGameFactoryCaller(address common.Address, caller bind.ContractCaller) (*OptimismDisputeGameFactoryCaller, error) { + contract, err := bindOptimismDisputeGameFactory(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismDisputeGameFactoryCaller{contract: contract}, nil +} + +func NewOptimismDisputeGameFactoryTransactor(address common.Address, transactor bind.ContractTransactor) (*OptimismDisputeGameFactoryTransactor, error) { + contract, err := bindOptimismDisputeGameFactory(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismDisputeGameFactoryTransactor{contract: contract}, nil +} + +func NewOptimismDisputeGameFactoryFilterer(address common.Address, filterer bind.ContractFilterer) (*OptimismDisputeGameFactoryFilterer, error) { + contract, err := bindOptimismDisputeGameFactory(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismDisputeGameFactoryFilterer{contract: contract}, nil +} + +func bindOptimismDisputeGameFactory(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismDisputeGameFactoryMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactoryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismDisputeGameFactory.Contract.OptimismDisputeGameFactoryCaller.contract.Call(opts, result, method, params...) +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactoryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismDisputeGameFactory.Contract.OptimismDisputeGameFactoryTransactor.contract.Transfer(opts) +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactoryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismDisputeGameFactory.Contract.OptimismDisputeGameFactoryTransactor.contract.Transact(opts, method, params...) +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactoryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismDisputeGameFactory.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactoryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismDisputeGameFactory.Contract.contract.Transfer(opts) +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactoryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismDisputeGameFactory.Contract.contract.Transact(opts, method, params...) +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactoryCaller) FindLatestGames(opts *bind.CallOpts, _gameType uint32, _start *big.Int, _n *big.Int) ([]IOptimismDisputeGameFactoryGameSearchResult, error) { + var out []interface{} + err := _OptimismDisputeGameFactory.contract.Call(opts, &out, "findLatestGames", _gameType, _start, _n) + + if err != nil { + return *new([]IOptimismDisputeGameFactoryGameSearchResult), err + } + + out0 := *abi.ConvertType(out[0], new([]IOptimismDisputeGameFactoryGameSearchResult)).(*[]IOptimismDisputeGameFactoryGameSearchResult) + + return out0, err + +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactorySession) FindLatestGames(_gameType uint32, _start *big.Int, _n *big.Int) ([]IOptimismDisputeGameFactoryGameSearchResult, error) { + return _OptimismDisputeGameFactory.Contract.FindLatestGames(&_OptimismDisputeGameFactory.CallOpts, _gameType, _start, _n) +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactoryCallerSession) FindLatestGames(_gameType uint32, _start *big.Int, _n *big.Int) ([]IOptimismDisputeGameFactoryGameSearchResult, error) { + return _OptimismDisputeGameFactory.Contract.FindLatestGames(&_OptimismDisputeGameFactory.CallOpts, _gameType, _start, _n) +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactoryCaller) GameCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _OptimismDisputeGameFactory.contract.Call(opts, &out, "gameCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactorySession) GameCount() (*big.Int, error) { + return _OptimismDisputeGameFactory.Contract.GameCount(&_OptimismDisputeGameFactory.CallOpts) +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactoryCallerSession) GameCount() (*big.Int, error) { + return _OptimismDisputeGameFactory.Contract.GameCount(&_OptimismDisputeGameFactory.CallOpts) +} + +func (_OptimismDisputeGameFactory *OptimismDisputeGameFactory) Address() common.Address { + return _OptimismDisputeGameFactory.address +} + +type OptimismDisputeGameFactoryInterface interface { + FindLatestGames(opts *bind.CallOpts, _gameType uint32, _start *big.Int, _n *big.Int) ([]IOptimismDisputeGameFactoryGameSearchResult, error) + + GameCount(opts *bind.CallOpts) (*big.Int, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/optimism_l1_bridge_adapter/optimism_l1_bridge_adapter.go b/core/gethwrappers/liquiditymanager/generated/optimism_l1_bridge_adapter/optimism_l1_bridge_adapter.go new file mode 100644 index 0000000000..189d13dd43 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/optimism_l1_bridge_adapter/optimism_l1_bridge_adapter.go @@ -0,0 +1,316 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_l1_bridge_adapter + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var OptimismL1BridgeAdapterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIL1StandardBridge\",\"name\":\"l1Bridge\",\"type\":\"address\"},{\"internalType\":\"contractIWrappedNative\",\"name\":\"wrappedNative\",\"type\":\"address\"},{\"internalType\":\"contractIOptimismPortal\",\"name\":\"optimismPortal\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BridgeAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wanted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InsufficientEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFinalizationAction\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"MsgShouldNotContainValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"MsgValueDoesNotMatchAmount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"finalizeWithdrawERC20\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBridgeFeeInNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getL1Bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOptimismPortal\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWrappedNative\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"sendERC20\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60e0604052600080546001600160401b03191690553480156200002157600080fd5b50604051620016e7380380620016e78339810160408190526200004491620000cb565b6001600160a01b03831615806200006257506001600160a01b038216155b806200007557506001600160a01b038116155b156200009457604051635e9c404d60e11b815260040160405180910390fd5b6001600160a01b0392831660805290821660a0521660c0526200011f565b6001600160a01b0381168114620000c857600080fd5b50565b600080600060608486031215620000e157600080fd5b8351620000ee81620000b2565b60208501519093506200010181620000b2565b60408501519092506200011481620000b2565b809150509250925092565b60805160a05160c0516115686200017f6000396000818160d5015281816105f901526106da01526000818161017c0152818161035401526103d40152600081816101490152818161048001528181610515015261057701526115686000f3fe6080604052600436106100695760003560e01c8063a71d98b711610043578063a71d98b71461011a578063c86d5bdd1461013a578063e861e9071461016d57600080fd5b80632e4b1fc91461007557806338314bb21461009657806354fd969f146100c657600080fd5b3661007057005b600080fd5b34801561008157600080fd5b50604051600081526020015b60405180910390f35b3480156100a257600080fd5b506100b66100b1366004610c62565b6101a0565b604051901515815260200161008d565b3480156100d257600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161008d565b61012d610128366004610cc7565b61027f565b60405161008d9190610dba565b34801561014657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006100f5565b34801561017957600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006100f5565b6000806101af83850185610ee4565b90506000815160018111156101c6576101c6610faa565b036101fb57600081602001518060200190518101906101e5919061116c565b90506101f0816105f7565b600092505050610277565b60018151600181111561021057610210610faa565b03610245576000816020015180602001905181019061022f919061126a565b905061023a8161069b565b600192505050610277565b6040517fee2ef09800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b949350505050565b60606102a373ffffffffffffffffffffffffffffffffffffffff881633308761070e565b34156102e2576040517f2543d86e0000000000000000000000000000000000000000000000000000000081523460048201526024015b60405180910390fd5b6000805467ffffffffffffffff1681806102fb836112ed565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550604051602001610341919067ffffffffffffffff91909116815260200190565b60405160208183030381529060405290507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16036104f9576040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018690527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561042d57600080fd5b505af1158015610441573d6000803e3d6000fd5b50506040517f9a2ac6d500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169250639a2ac6d5915087906104be908a90600090879060040161133b565b6000604051808303818588803b1580156104d757600080fd5b505af11580156104eb573d6000803e3d6000fd5b5050505050809150506105ed565b61053a73ffffffffffffffffffffffffffffffffffffffff89167f0000000000000000000000000000000000000000000000000000000000000000876107f0565b6040517f838b252000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063838b2520906105b7908b908b908b908b90600090899060040161137f565b600060405180830381600087803b1580156105d157600080fd5b505af11580156105e5573d6000803e3d6000fd5b509293505050505b9695505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634870496f82600001518360200151846040015185606001516040518563ffffffff1660e01b81526004016106669493929190611435565b600060405180830381600087803b15801561068057600080fd5b505af1158015610694573d6000803e3d6000fd5b5050505050565b80516040517f8c3152e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001691638c3152e99161066691906004016114f1565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526107ea9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610977565b50505050565b80158061089057506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561086a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088e9190611504565b155b61091c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084016102d9565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109729084907f095ea7b30000000000000000000000000000000000000000000000000000000090606401610768565b505050565b60006109d9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610a839092919063ffffffff16565b80519091501561097257808060200190518101906109f7919061151d565b610972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016102d9565b60606102778484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051610ab7919061153f565b60006040518083038185875af1925050503d8060008114610af4576040519150601f19603f3d011682016040523d82523d6000602084013e610af9565b606091505b5091509150610b0a87838387610b15565b979650505050505050565b60608315610bab578251600003610ba45773ffffffffffffffffffffffffffffffffffffffff85163b610ba4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102d9565b5081610277565b6102778383815115610bc05781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d99190610dba565b73ffffffffffffffffffffffffffffffffffffffff81168114610c1657600080fd5b50565b60008083601f840112610c2b57600080fd5b50813567ffffffffffffffff811115610c4357600080fd5b602083019150836020828501011115610c5b57600080fd5b9250929050565b60008060008060608587031215610c7857600080fd5b8435610c8381610bf4565b93506020850135610c9381610bf4565b9250604085013567ffffffffffffffff811115610caf57600080fd5b610cbb87828801610c19565b95989497509550505050565b60008060008060008060a08789031215610ce057600080fd5b8635610ceb81610bf4565b95506020870135610cfb81610bf4565b94506040870135610d0b81610bf4565b935060608701359250608087013567ffffffffffffffff811115610d2e57600080fd5b610d3a89828a01610c19565b979a9699509497509295939492505050565b60005b83811015610d67578181015183820152602001610d4f565b50506000910152565b60008151808452610d88816020860160208601610d4c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610dcd6020830184610d70565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610e2657610e26610dd4565b60405290565b6040516080810167ffffffffffffffff81118282101715610e2657610e26610dd4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610e9657610e96610dd4565b604052919050565b600067ffffffffffffffff821115610eb857610eb8610dd4565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006020808385031215610ef757600080fd5b823567ffffffffffffffff80821115610f0f57600080fd5b9084019060408287031215610f2357600080fd5b610f2b610e03565b823560028110610f3a57600080fd5b81528284013582811115610f4d57600080fd5b80840193505086601f840112610f6257600080fd5b82359150610f77610f7283610e9e565b610e4f565b8281528785848601011115610f8b57600080fd5b8285850186830137600092810185019290925292830152509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600082601f830112610fea57600080fd5b8151610ff8610f7282610e9e565b81815284602083860101111561100d57600080fd5b610277826020830160208701610d4c565b600060c0828403121561103057600080fd5b60405160c0810167ffffffffffffffff828210818311171561105457611054610dd4565b81604052829350845183526020850151915061106f82610bf4565b8160208401526040850151915061108582610bf4565b816040840152606085015160608401526080850151608084015260a08501519150808211156110b357600080fd5b506110c085828601610fd9565b60a0830152505092915050565b600082601f8301126110de57600080fd5b8151602067ffffffffffffffff808311156110fb576110fb610dd4565b8260051b61110a838201610e4f565b938452858101830193838101908886111561112457600080fd5b84880192505b85831015611160578251848111156111425760008081fd5b6111508a87838c0101610fd9565b835250918401919084019061112a565b98975050505050505050565b60006020828403121561117e57600080fd5b815167ffffffffffffffff8082111561119657600080fd5b9083019081850360e08112156111ab57600080fd5b6111b3610e2c565b8351838111156111c257600080fd5b6111ce8882870161101e565b8252506020840151602082015260807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08301121561120b57600080fd5b611213610e2c565b6040858101518252606080870151602084015260808701518284015260a08701519083015282015260c084015191508282111561124f57600080fd5b61125b878386016110cd565b60608201529695505050505050565b60006020828403121561127c57600080fd5b815167ffffffffffffffff8082111561129457600080fd5b90830190602082860312156112a857600080fd5b6040516020810181811083821117156112c3576112c3610dd4565b6040528251828111156112d557600080fd5b6112e18782860161101e565b82525095945050505050565b600067ffffffffffffffff808316818103611331577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6001019392505050565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff831660208201526060604082015260006113766060830184610d70565b95945050505050565b600073ffffffffffffffffffffffffffffffffffffffff8089168352808816602084015280871660408401525084606083015263ffffffff8416608083015260c060a083015261116060c0830184610d70565b805182526000602082015173ffffffffffffffffffffffffffffffffffffffff80821660208601528060408501511660408601525050606082015160608401526080820151608084015260a082015160c060a085015261027760c0850182610d70565b60e08152600061144860e08301876113d2565b602086818501528551604085015280860151606085015260408601516080850152606086015160a085015283820360c08501528185518084528284019150828160051b85010183880160005b838110156114e0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08784030185526114ce838351610d70565b94860194925090850190600101611494565b50909b9a5050505050505050505050565b602081526000610dcd60208301846113d2565b60006020828403121561151657600080fd5b5051919050565b60006020828403121561152f57600080fd5b81518015158114610dcd57600080fd5b60008251611551818460208701610d4c565b919091019291505056fea164736f6c6343000818000a", +} + +var OptimismL1BridgeAdapterABI = OptimismL1BridgeAdapterMetaData.ABI + +var OptimismL1BridgeAdapterBin = OptimismL1BridgeAdapterMetaData.Bin + +func DeployOptimismL1BridgeAdapter(auth *bind.TransactOpts, backend bind.ContractBackend, l1Bridge common.Address, wrappedNative common.Address, optimismPortal common.Address) (common.Address, *types.Transaction, *OptimismL1BridgeAdapter, error) { + parsed, err := OptimismL1BridgeAdapterMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(OptimismL1BridgeAdapterBin), backend, l1Bridge, wrappedNative, optimismPortal) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &OptimismL1BridgeAdapter{address: address, abi: *parsed, OptimismL1BridgeAdapterCaller: OptimismL1BridgeAdapterCaller{contract: contract}, OptimismL1BridgeAdapterTransactor: OptimismL1BridgeAdapterTransactor{contract: contract}, OptimismL1BridgeAdapterFilterer: OptimismL1BridgeAdapterFilterer{contract: contract}}, nil +} + +type OptimismL1BridgeAdapter struct { + address common.Address + abi abi.ABI + OptimismL1BridgeAdapterCaller + OptimismL1BridgeAdapterTransactor + OptimismL1BridgeAdapterFilterer +} + +type OptimismL1BridgeAdapterCaller struct { + contract *bind.BoundContract +} + +type OptimismL1BridgeAdapterTransactor struct { + contract *bind.BoundContract +} + +type OptimismL1BridgeAdapterFilterer struct { + contract *bind.BoundContract +} + +type OptimismL1BridgeAdapterSession struct { + Contract *OptimismL1BridgeAdapter + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismL1BridgeAdapterCallerSession struct { + Contract *OptimismL1BridgeAdapterCaller + CallOpts bind.CallOpts +} + +type OptimismL1BridgeAdapterTransactorSession struct { + Contract *OptimismL1BridgeAdapterTransactor + TransactOpts bind.TransactOpts +} + +type OptimismL1BridgeAdapterRaw struct { + Contract *OptimismL1BridgeAdapter +} + +type OptimismL1BridgeAdapterCallerRaw struct { + Contract *OptimismL1BridgeAdapterCaller +} + +type OptimismL1BridgeAdapterTransactorRaw struct { + Contract *OptimismL1BridgeAdapterTransactor +} + +func NewOptimismL1BridgeAdapter(address common.Address, backend bind.ContractBackend) (*OptimismL1BridgeAdapter, error) { + abi, err := abi.JSON(strings.NewReader(OptimismL1BridgeAdapterABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismL1BridgeAdapter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismL1BridgeAdapter{address: address, abi: abi, OptimismL1BridgeAdapterCaller: OptimismL1BridgeAdapterCaller{contract: contract}, OptimismL1BridgeAdapterTransactor: OptimismL1BridgeAdapterTransactor{contract: contract}, OptimismL1BridgeAdapterFilterer: OptimismL1BridgeAdapterFilterer{contract: contract}}, nil +} + +func NewOptimismL1BridgeAdapterCaller(address common.Address, caller bind.ContractCaller) (*OptimismL1BridgeAdapterCaller, error) { + contract, err := bindOptimismL1BridgeAdapter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismL1BridgeAdapterCaller{contract: contract}, nil +} + +func NewOptimismL1BridgeAdapterTransactor(address common.Address, transactor bind.ContractTransactor) (*OptimismL1BridgeAdapterTransactor, error) { + contract, err := bindOptimismL1BridgeAdapter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismL1BridgeAdapterTransactor{contract: contract}, nil +} + +func NewOptimismL1BridgeAdapterFilterer(address common.Address, filterer bind.ContractFilterer) (*OptimismL1BridgeAdapterFilterer, error) { + contract, err := bindOptimismL1BridgeAdapter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismL1BridgeAdapterFilterer{contract: contract}, nil +} + +func bindOptimismL1BridgeAdapter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismL1BridgeAdapterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismL1BridgeAdapter.Contract.OptimismL1BridgeAdapterCaller.contract.Call(opts, result, method, params...) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.Contract.OptimismL1BridgeAdapterTransactor.contract.Transfer(opts) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.Contract.OptimismL1BridgeAdapterTransactor.contract.Transact(opts, method, params...) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismL1BridgeAdapter.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.Contract.contract.Transfer(opts) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.Contract.contract.Transact(opts, method, params...) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterCaller) GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _OptimismL1BridgeAdapter.contract.Call(opts, &out, "getBridgeFeeInNative") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterSession) GetBridgeFeeInNative() (*big.Int, error) { + return _OptimismL1BridgeAdapter.Contract.GetBridgeFeeInNative(&_OptimismL1BridgeAdapter.CallOpts) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterCallerSession) GetBridgeFeeInNative() (*big.Int, error) { + return _OptimismL1BridgeAdapter.Contract.GetBridgeFeeInNative(&_OptimismL1BridgeAdapter.CallOpts) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterCaller) GetL1Bridge(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismL1BridgeAdapter.contract.Call(opts, &out, "getL1Bridge") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterSession) GetL1Bridge() (common.Address, error) { + return _OptimismL1BridgeAdapter.Contract.GetL1Bridge(&_OptimismL1BridgeAdapter.CallOpts) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterCallerSession) GetL1Bridge() (common.Address, error) { + return _OptimismL1BridgeAdapter.Contract.GetL1Bridge(&_OptimismL1BridgeAdapter.CallOpts) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterCaller) GetOptimismPortal(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismL1BridgeAdapter.contract.Call(opts, &out, "getOptimismPortal") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterSession) GetOptimismPortal() (common.Address, error) { + return _OptimismL1BridgeAdapter.Contract.GetOptimismPortal(&_OptimismL1BridgeAdapter.CallOpts) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterCallerSession) GetOptimismPortal() (common.Address, error) { + return _OptimismL1BridgeAdapter.Contract.GetOptimismPortal(&_OptimismL1BridgeAdapter.CallOpts) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterCaller) GetWrappedNative(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismL1BridgeAdapter.contract.Call(opts, &out, "getWrappedNative") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterSession) GetWrappedNative() (common.Address, error) { + return _OptimismL1BridgeAdapter.Contract.GetWrappedNative(&_OptimismL1BridgeAdapter.CallOpts) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterCallerSession) GetWrappedNative() (common.Address, error) { + return _OptimismL1BridgeAdapter.Contract.GetWrappedNative(&_OptimismL1BridgeAdapter.CallOpts) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterTransactor) FinalizeWithdrawERC20(opts *bind.TransactOpts, arg0 common.Address, arg1 common.Address, data []byte) (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.contract.Transact(opts, "finalizeWithdrawERC20", arg0, arg1, data) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterSession) FinalizeWithdrawERC20(arg0 common.Address, arg1 common.Address, data []byte) (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.Contract.FinalizeWithdrawERC20(&_OptimismL1BridgeAdapter.TransactOpts, arg0, arg1, data) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterTransactorSession) FinalizeWithdrawERC20(arg0 common.Address, arg1 common.Address, data []byte) (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.Contract.FinalizeWithdrawERC20(&_OptimismL1BridgeAdapter.TransactOpts, arg0, arg1, data) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterTransactor) SendERC20(opts *bind.TransactOpts, localToken common.Address, remoteToken common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.contract.Transact(opts, "sendERC20", localToken, remoteToken, recipient, amount, arg4) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterSession) SendERC20(localToken common.Address, remoteToken common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.Contract.SendERC20(&_OptimismL1BridgeAdapter.TransactOpts, localToken, remoteToken, recipient, amount, arg4) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterTransactorSession) SendERC20(localToken common.Address, remoteToken common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.Contract.SendERC20(&_OptimismL1BridgeAdapter.TransactOpts, localToken, remoteToken, recipient, amount, arg4) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.contract.RawTransact(opts, nil) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterSession) Receive() (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.Contract.Receive(&_OptimismL1BridgeAdapter.TransactOpts) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapterTransactorSession) Receive() (*types.Transaction, error) { + return _OptimismL1BridgeAdapter.Contract.Receive(&_OptimismL1BridgeAdapter.TransactOpts) +} + +func (_OptimismL1BridgeAdapter *OptimismL1BridgeAdapter) Address() common.Address { + return _OptimismL1BridgeAdapter.address +} + +type OptimismL1BridgeAdapterInterface interface { + GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) + + GetL1Bridge(opts *bind.CallOpts) (common.Address, error) + + GetOptimismPortal(opts *bind.CallOpts) (common.Address, error) + + GetWrappedNative(opts *bind.CallOpts) (common.Address, error) + + FinalizeWithdrawERC20(opts *bind.TransactOpts, arg0 common.Address, arg1 common.Address, data []byte) (*types.Transaction, error) + + SendERC20(opts *bind.TransactOpts, localToken common.Address, remoteToken common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) + + Receive(opts *bind.TransactOpts) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/optimism_l1_bridge_adapter_encoder/optimism_l1_bridge_adapter_encoder.go b/core/gethwrappers/liquiditymanager/generated/optimism_l1_bridge_adapter_encoder/optimism_l1_bridge_adapter_encoder.go new file mode 100644 index 0000000000..14aa651399 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/optimism_l1_bridge_adapter_encoder/optimism_l1_bridge_adapter_encoder.go @@ -0,0 +1,257 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_l1_bridge_adapter_encoder + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type OptimismL1BridgeAdapterFinalizeWithdrawERC20Payload struct { + Action uint8 + Data []byte +} + +type OptimismL1BridgeAdapterOptimismFinalizationPayload struct { + WithdrawalTransaction TypesWithdrawalTransaction +} + +type OptimismL1BridgeAdapterOptimismProveWithdrawalPayload struct { + WithdrawalTransaction TypesWithdrawalTransaction + L2OutputIndex *big.Int + OutputRootProof TypesOutputRootProof + WithdrawalProof [][]byte +} + +type TypesOutputRootProof struct { + Version [32]byte + StateRoot [32]byte + MessagePasserStorageRoot [32]byte + LatestBlockhash [32]byte +} + +type TypesWithdrawalTransaction struct { + Nonce *big.Int + Sender common.Address + Target common.Address + Value *big.Int + GasLimit *big.Int + Data []byte +} + +var OptimismL1BridgeAdapterEncoderMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"enumOptimismL1BridgeAdapter.FinalizationAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structOptimismL1BridgeAdapter.FinalizeWithdrawERC20Payload\",\"name\":\"payload\",\"type\":\"tuple\"}],\"name\":\"encodeFinalizeWithdrawalERC20Payload\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"withdrawalTransaction\",\"type\":\"tuple\"}],\"internalType\":\"structOptimismL1BridgeAdapter.OptimismFinalizationPayload\",\"name\":\"payload\",\"type\":\"tuple\"}],\"name\":\"encodeOptimismFinalizationPayload\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"withdrawalTransaction\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"l2OutputIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}],\"internalType\":\"structTypes.OutputRootProof\",\"name\":\"outputRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"withdrawalProof\",\"type\":\"bytes[]\"}],\"internalType\":\"structOptimismL1BridgeAdapter.OptimismProveWithdrawalPayload\",\"name\":\"payload\",\"type\":\"tuple\"}],\"name\":\"encodeOptimismProveWithdrawalPayload\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}]", +} + +var OptimismL1BridgeAdapterEncoderABI = OptimismL1BridgeAdapterEncoderMetaData.ABI + +type OptimismL1BridgeAdapterEncoder struct { + address common.Address + abi abi.ABI + OptimismL1BridgeAdapterEncoderCaller + OptimismL1BridgeAdapterEncoderTransactor + OptimismL1BridgeAdapterEncoderFilterer +} + +type OptimismL1BridgeAdapterEncoderCaller struct { + contract *bind.BoundContract +} + +type OptimismL1BridgeAdapterEncoderTransactor struct { + contract *bind.BoundContract +} + +type OptimismL1BridgeAdapterEncoderFilterer struct { + contract *bind.BoundContract +} + +type OptimismL1BridgeAdapterEncoderSession struct { + Contract *OptimismL1BridgeAdapterEncoder + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismL1BridgeAdapterEncoderCallerSession struct { + Contract *OptimismL1BridgeAdapterEncoderCaller + CallOpts bind.CallOpts +} + +type OptimismL1BridgeAdapterEncoderTransactorSession struct { + Contract *OptimismL1BridgeAdapterEncoderTransactor + TransactOpts bind.TransactOpts +} + +type OptimismL1BridgeAdapterEncoderRaw struct { + Contract *OptimismL1BridgeAdapterEncoder +} + +type OptimismL1BridgeAdapterEncoderCallerRaw struct { + Contract *OptimismL1BridgeAdapterEncoderCaller +} + +type OptimismL1BridgeAdapterEncoderTransactorRaw struct { + Contract *OptimismL1BridgeAdapterEncoderTransactor +} + +func NewOptimismL1BridgeAdapterEncoder(address common.Address, backend bind.ContractBackend) (*OptimismL1BridgeAdapterEncoder, error) { + abi, err := abi.JSON(strings.NewReader(OptimismL1BridgeAdapterEncoderABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismL1BridgeAdapterEncoder(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismL1BridgeAdapterEncoder{address: address, abi: abi, OptimismL1BridgeAdapterEncoderCaller: OptimismL1BridgeAdapterEncoderCaller{contract: contract}, OptimismL1BridgeAdapterEncoderTransactor: OptimismL1BridgeAdapterEncoderTransactor{contract: contract}, OptimismL1BridgeAdapterEncoderFilterer: OptimismL1BridgeAdapterEncoderFilterer{contract: contract}}, nil +} + +func NewOptimismL1BridgeAdapterEncoderCaller(address common.Address, caller bind.ContractCaller) (*OptimismL1BridgeAdapterEncoderCaller, error) { + contract, err := bindOptimismL1BridgeAdapterEncoder(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismL1BridgeAdapterEncoderCaller{contract: contract}, nil +} + +func NewOptimismL1BridgeAdapterEncoderTransactor(address common.Address, transactor bind.ContractTransactor) (*OptimismL1BridgeAdapterEncoderTransactor, error) { + contract, err := bindOptimismL1BridgeAdapterEncoder(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismL1BridgeAdapterEncoderTransactor{contract: contract}, nil +} + +func NewOptimismL1BridgeAdapterEncoderFilterer(address common.Address, filterer bind.ContractFilterer) (*OptimismL1BridgeAdapterEncoderFilterer, error) { + contract, err := bindOptimismL1BridgeAdapterEncoder(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismL1BridgeAdapterEncoderFilterer{contract: contract}, nil +} + +func bindOptimismL1BridgeAdapterEncoder(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismL1BridgeAdapterEncoderMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismL1BridgeAdapterEncoder.Contract.OptimismL1BridgeAdapterEncoderCaller.contract.Call(opts, result, method, params...) +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL1BridgeAdapterEncoder.Contract.OptimismL1BridgeAdapterEncoderTransactor.contract.Transfer(opts) +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismL1BridgeAdapterEncoder.Contract.OptimismL1BridgeAdapterEncoderTransactor.contract.Transact(opts, method, params...) +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismL1BridgeAdapterEncoder.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL1BridgeAdapterEncoder.Contract.contract.Transfer(opts) +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismL1BridgeAdapterEncoder.Contract.contract.Transact(opts, method, params...) +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderCaller) EncodeFinalizeWithdrawalERC20Payload(opts *bind.CallOpts, payload OptimismL1BridgeAdapterFinalizeWithdrawERC20Payload) error { + var out []interface{} + err := _OptimismL1BridgeAdapterEncoder.contract.Call(opts, &out, "encodeFinalizeWithdrawalERC20Payload", payload) + + if err != nil { + return err + } + + return err + +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderSession) EncodeFinalizeWithdrawalERC20Payload(payload OptimismL1BridgeAdapterFinalizeWithdrawERC20Payload) error { + return _OptimismL1BridgeAdapterEncoder.Contract.EncodeFinalizeWithdrawalERC20Payload(&_OptimismL1BridgeAdapterEncoder.CallOpts, payload) +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderCallerSession) EncodeFinalizeWithdrawalERC20Payload(payload OptimismL1BridgeAdapterFinalizeWithdrawERC20Payload) error { + return _OptimismL1BridgeAdapterEncoder.Contract.EncodeFinalizeWithdrawalERC20Payload(&_OptimismL1BridgeAdapterEncoder.CallOpts, payload) +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderCaller) EncodeOptimismFinalizationPayload(opts *bind.CallOpts, payload OptimismL1BridgeAdapterOptimismFinalizationPayload) error { + var out []interface{} + err := _OptimismL1BridgeAdapterEncoder.contract.Call(opts, &out, "encodeOptimismFinalizationPayload", payload) + + if err != nil { + return err + } + + return err + +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderSession) EncodeOptimismFinalizationPayload(payload OptimismL1BridgeAdapterOptimismFinalizationPayload) error { + return _OptimismL1BridgeAdapterEncoder.Contract.EncodeOptimismFinalizationPayload(&_OptimismL1BridgeAdapterEncoder.CallOpts, payload) +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderCallerSession) EncodeOptimismFinalizationPayload(payload OptimismL1BridgeAdapterOptimismFinalizationPayload) error { + return _OptimismL1BridgeAdapterEncoder.Contract.EncodeOptimismFinalizationPayload(&_OptimismL1BridgeAdapterEncoder.CallOpts, payload) +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderCaller) EncodeOptimismProveWithdrawalPayload(opts *bind.CallOpts, payload OptimismL1BridgeAdapterOptimismProveWithdrawalPayload) error { + var out []interface{} + err := _OptimismL1BridgeAdapterEncoder.contract.Call(opts, &out, "encodeOptimismProveWithdrawalPayload", payload) + + if err != nil { + return err + } + + return err + +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderSession) EncodeOptimismProveWithdrawalPayload(payload OptimismL1BridgeAdapterOptimismProveWithdrawalPayload) error { + return _OptimismL1BridgeAdapterEncoder.Contract.EncodeOptimismProveWithdrawalPayload(&_OptimismL1BridgeAdapterEncoder.CallOpts, payload) +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoderCallerSession) EncodeOptimismProveWithdrawalPayload(payload OptimismL1BridgeAdapterOptimismProveWithdrawalPayload) error { + return _OptimismL1BridgeAdapterEncoder.Contract.EncodeOptimismProveWithdrawalPayload(&_OptimismL1BridgeAdapterEncoder.CallOpts, payload) +} + +func (_OptimismL1BridgeAdapterEncoder *OptimismL1BridgeAdapterEncoder) Address() common.Address { + return _OptimismL1BridgeAdapterEncoder.address +} + +type OptimismL1BridgeAdapterEncoderInterface interface { + EncodeFinalizeWithdrawalERC20Payload(opts *bind.CallOpts, payload OptimismL1BridgeAdapterFinalizeWithdrawERC20Payload) error + + EncodeOptimismFinalizationPayload(opts *bind.CallOpts, payload OptimismL1BridgeAdapterOptimismFinalizationPayload) error + + EncodeOptimismProveWithdrawalPayload(opts *bind.CallOpts, payload OptimismL1BridgeAdapterOptimismProveWithdrawalPayload) error + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/optimism_l1_standard_bridge/optimism_l1_standard_bridge.go b/core/gethwrappers/liquiditymanager/generated/optimism_l1_standard_bridge/optimism_l1_standard_bridge.go new file mode 100644 index 0000000000..b376a33435 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/optimism_l1_standard_bridge/optimism_l1_standard_bridge.go @@ -0,0 +1,173 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_l1_standard_bridge + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var OptimismL1StandardBridgeMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]", +} + +var OptimismL1StandardBridgeABI = OptimismL1StandardBridgeMetaData.ABI + +type OptimismL1StandardBridge struct { + address common.Address + abi abi.ABI + OptimismL1StandardBridgeCaller + OptimismL1StandardBridgeTransactor + OptimismL1StandardBridgeFilterer +} + +type OptimismL1StandardBridgeCaller struct { + contract *bind.BoundContract +} + +type OptimismL1StandardBridgeTransactor struct { + contract *bind.BoundContract +} + +type OptimismL1StandardBridgeFilterer struct { + contract *bind.BoundContract +} + +type OptimismL1StandardBridgeSession struct { + Contract *OptimismL1StandardBridge + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismL1StandardBridgeCallerSession struct { + Contract *OptimismL1StandardBridgeCaller + CallOpts bind.CallOpts +} + +type OptimismL1StandardBridgeTransactorSession struct { + Contract *OptimismL1StandardBridgeTransactor + TransactOpts bind.TransactOpts +} + +type OptimismL1StandardBridgeRaw struct { + Contract *OptimismL1StandardBridge +} + +type OptimismL1StandardBridgeCallerRaw struct { + Contract *OptimismL1StandardBridgeCaller +} + +type OptimismL1StandardBridgeTransactorRaw struct { + Contract *OptimismL1StandardBridgeTransactor +} + +func NewOptimismL1StandardBridge(address common.Address, backend bind.ContractBackend) (*OptimismL1StandardBridge, error) { + abi, err := abi.JSON(strings.NewReader(OptimismL1StandardBridgeABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismL1StandardBridge(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismL1StandardBridge{address: address, abi: abi, OptimismL1StandardBridgeCaller: OptimismL1StandardBridgeCaller{contract: contract}, OptimismL1StandardBridgeTransactor: OptimismL1StandardBridgeTransactor{contract: contract}, OptimismL1StandardBridgeFilterer: OptimismL1StandardBridgeFilterer{contract: contract}}, nil +} + +func NewOptimismL1StandardBridgeCaller(address common.Address, caller bind.ContractCaller) (*OptimismL1StandardBridgeCaller, error) { + contract, err := bindOptimismL1StandardBridge(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismL1StandardBridgeCaller{contract: contract}, nil +} + +func NewOptimismL1StandardBridgeTransactor(address common.Address, transactor bind.ContractTransactor) (*OptimismL1StandardBridgeTransactor, error) { + contract, err := bindOptimismL1StandardBridge(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismL1StandardBridgeTransactor{contract: contract}, nil +} + +func NewOptimismL1StandardBridgeFilterer(address common.Address, filterer bind.ContractFilterer) (*OptimismL1StandardBridgeFilterer, error) { + contract, err := bindOptimismL1StandardBridge(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismL1StandardBridgeFilterer{contract: contract}, nil +} + +func bindOptimismL1StandardBridge(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismL1StandardBridgeMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismL1StandardBridge *OptimismL1StandardBridgeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismL1StandardBridge.Contract.OptimismL1StandardBridgeCaller.contract.Call(opts, result, method, params...) +} + +func (_OptimismL1StandardBridge *OptimismL1StandardBridgeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL1StandardBridge.Contract.OptimismL1StandardBridgeTransactor.contract.Transfer(opts) +} + +func (_OptimismL1StandardBridge *OptimismL1StandardBridgeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismL1StandardBridge.Contract.OptimismL1StandardBridgeTransactor.contract.Transact(opts, method, params...) +} + +func (_OptimismL1StandardBridge *OptimismL1StandardBridgeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismL1StandardBridge.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismL1StandardBridge *OptimismL1StandardBridgeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL1StandardBridge.Contract.contract.Transfer(opts) +} + +func (_OptimismL1StandardBridge *OptimismL1StandardBridgeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismL1StandardBridge.Contract.contract.Transact(opts, method, params...) +} + +func (_OptimismL1StandardBridge *OptimismL1StandardBridgeTransactor) DepositETHTo(opts *bind.TransactOpts, _to common.Address, _minGasLimit uint32, _extraData []byte) (*types.Transaction, error) { + return _OptimismL1StandardBridge.contract.Transact(opts, "depositETHTo", _to, _minGasLimit, _extraData) +} + +func (_OptimismL1StandardBridge *OptimismL1StandardBridgeSession) DepositETHTo(_to common.Address, _minGasLimit uint32, _extraData []byte) (*types.Transaction, error) { + return _OptimismL1StandardBridge.Contract.DepositETHTo(&_OptimismL1StandardBridge.TransactOpts, _to, _minGasLimit, _extraData) +} + +func (_OptimismL1StandardBridge *OptimismL1StandardBridgeTransactorSession) DepositETHTo(_to common.Address, _minGasLimit uint32, _extraData []byte) (*types.Transaction, error) { + return _OptimismL1StandardBridge.Contract.DepositETHTo(&_OptimismL1StandardBridge.TransactOpts, _to, _minGasLimit, _extraData) +} + +func (_OptimismL1StandardBridge *OptimismL1StandardBridge) Address() common.Address { + return _OptimismL1StandardBridge.address +} + +type OptimismL1StandardBridgeInterface interface { + DepositETHTo(opts *bind.TransactOpts, _to common.Address, _minGasLimit uint32, _extraData []byte) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/optimism_l2_bridge_adapter/optimism_l2_bridge_adapter.go b/core/gethwrappers/liquiditymanager/generated/optimism_l2_bridge_adapter/optimism_l2_bridge_adapter.go new file mode 100644 index 0000000000..589db5ceb4 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/optimism_l2_bridge_adapter/optimism_l2_bridge_adapter.go @@ -0,0 +1,302 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_l2_bridge_adapter + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var OptimismL2BridgeAdapterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIWrappedNative\",\"name\":\"wrappedNative\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BridgeAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wanted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InsufficientEthValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"MsgShouldNotContainValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"MsgValueDoesNotMatchAmount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"finalizeWithdrawERC20\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBridgeFeeInNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getL2Bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWrappedNative\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"sendERC20\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60c0604052734200000000000000000000000000000000000010608052600080546001600160401b031916905534801561003857600080fd5b50604051610c2e380380610c2e83398101604081905261005791610068565b6001600160a01b031660a052610098565b60006020828403121561007a57600080fd5b81516001600160a01b038116811461009157600080fd5b9392505050565b60805160a051610b4f6100df6000396000818161013e0152818161024201526102c2015260008181609a0152818161036e0152818161043c01526104f60152610b4f6000f3fe60806040526004361061005e5760003560e01c806338314bb21161004357806338314bb2146100df578063a71d98b71461010f578063e861e9071461012f57600080fd5b80632e4b1fc91461006a5780633429072c1461008b57600080fd5b3661006557005b600080fd5b34801561007657600080fd5b50604051600081526020015b60405180910390f35b34801561009757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610082565b3480156100eb57600080fd5b506100ff6100fa366004610903565b610162565b6040519015158152602001610082565b61012261011d366004610964565b61016d565b6040516100829190610a51565b34801561013b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006100ba565b60015b949350505050565b606034156101ae576040517f2543d86e0000000000000000000000000000000000000000000000000000000081523460048201526024015b60405180910390fd5b6101d073ffffffffffffffffffffffffffffffffffffffff8816333087610574565b6000805467ffffffffffffffff1681806101e983610a6b565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060405160200161022f919067ffffffffffffffff91909116815260200190565b60405160208183030381529060405290507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16036103ff576040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018690527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561031b57600080fd5b505af115801561032f573d6000803e3d6000fd5b50506040517fa3a7954800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016925063a3a79548915087906103c49073deaddeaddeaddeaddeaddeaddeaddeaddead0000908b9084906000908990600401610ab9565b6000604051808303818588803b1580156103dd57600080fd5b505af11580156103f1573d6000803e3d6000fd5b50505050508091505061056a565b6040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820187905289169063095ea7b3906044016020604051808303816000875af1158015610494573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b89190610b04565b506040517fa3a7954800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a3a7954890610534908b908a908a906000908890600401610ab9565b600060405180830381600087803b15801561054e57600080fd5b505af1158015610562573d6000803e3d6000fd5b509293505050505b9695505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905261060990859061060f565b50505050565b6000610671826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166107209092919063ffffffff16565b80519091501561071b578080602001905181019061068f9190610b04565b61071b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101a5565b505050565b60606101658484600085856000808673ffffffffffffffffffffffffffffffffffffffff1685876040516107549190610b26565b60006040518083038185875af1925050503d8060008114610791576040519150601f19603f3d011682016040523d82523d6000602084013e610796565b606091505b50915091506107a7878383876107b2565b979650505050505050565b606083156108485782516000036108415773ffffffffffffffffffffffffffffffffffffffff85163b610841576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101a5565b5081610165565b610165838381511561085d5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a59190610a51565b803573ffffffffffffffffffffffffffffffffffffffff811681146108b557600080fd5b919050565b60008083601f8401126108cc57600080fd5b50813567ffffffffffffffff8111156108e457600080fd5b6020830191508360208285010111156108fc57600080fd5b9250929050565b6000806000806060858703121561091957600080fd5b61092285610891565b935061093060208601610891565b9250604085013567ffffffffffffffff81111561094c57600080fd5b610958878288016108ba565b95989497509550505050565b60008060008060008060a0878903121561097d57600080fd5b61098687610891565b955061099460208801610891565b94506109a260408801610891565b935060608701359250608087013567ffffffffffffffff8111156109c557600080fd5b6109d189828a016108ba565b979a9699509497509295939492505050565b60005b838110156109fe5781810151838201526020016109e6565b50506000910152565b60008151808452610a1f8160208601602086016109e3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610a646020830184610a07565b9392505050565b600067ffffffffffffffff808316818103610aaf577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6001019392505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015263ffffffff8416606083015260a060808301526107a760a0830184610a07565b600060208284031215610b1657600080fd5b81518015158114610a6457600080fd5b60008251610b388184602087016109e3565b919091019291505056fea164736f6c6343000818000a", +} + +var OptimismL2BridgeAdapterABI = OptimismL2BridgeAdapterMetaData.ABI + +var OptimismL2BridgeAdapterBin = OptimismL2BridgeAdapterMetaData.Bin + +func DeployOptimismL2BridgeAdapter(auth *bind.TransactOpts, backend bind.ContractBackend, wrappedNative common.Address) (common.Address, *types.Transaction, *OptimismL2BridgeAdapter, error) { + parsed, err := OptimismL2BridgeAdapterMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(OptimismL2BridgeAdapterBin), backend, wrappedNative) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &OptimismL2BridgeAdapter{address: address, abi: *parsed, OptimismL2BridgeAdapterCaller: OptimismL2BridgeAdapterCaller{contract: contract}, OptimismL2BridgeAdapterTransactor: OptimismL2BridgeAdapterTransactor{contract: contract}, OptimismL2BridgeAdapterFilterer: OptimismL2BridgeAdapterFilterer{contract: contract}}, nil +} + +type OptimismL2BridgeAdapter struct { + address common.Address + abi abi.ABI + OptimismL2BridgeAdapterCaller + OptimismL2BridgeAdapterTransactor + OptimismL2BridgeAdapterFilterer +} + +type OptimismL2BridgeAdapterCaller struct { + contract *bind.BoundContract +} + +type OptimismL2BridgeAdapterTransactor struct { + contract *bind.BoundContract +} + +type OptimismL2BridgeAdapterFilterer struct { + contract *bind.BoundContract +} + +type OptimismL2BridgeAdapterSession struct { + Contract *OptimismL2BridgeAdapter + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismL2BridgeAdapterCallerSession struct { + Contract *OptimismL2BridgeAdapterCaller + CallOpts bind.CallOpts +} + +type OptimismL2BridgeAdapterTransactorSession struct { + Contract *OptimismL2BridgeAdapterTransactor + TransactOpts bind.TransactOpts +} + +type OptimismL2BridgeAdapterRaw struct { + Contract *OptimismL2BridgeAdapter +} + +type OptimismL2BridgeAdapterCallerRaw struct { + Contract *OptimismL2BridgeAdapterCaller +} + +type OptimismL2BridgeAdapterTransactorRaw struct { + Contract *OptimismL2BridgeAdapterTransactor +} + +func NewOptimismL2BridgeAdapter(address common.Address, backend bind.ContractBackend) (*OptimismL2BridgeAdapter, error) { + abi, err := abi.JSON(strings.NewReader(OptimismL2BridgeAdapterABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismL2BridgeAdapter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismL2BridgeAdapter{address: address, abi: abi, OptimismL2BridgeAdapterCaller: OptimismL2BridgeAdapterCaller{contract: contract}, OptimismL2BridgeAdapterTransactor: OptimismL2BridgeAdapterTransactor{contract: contract}, OptimismL2BridgeAdapterFilterer: OptimismL2BridgeAdapterFilterer{contract: contract}}, nil +} + +func NewOptimismL2BridgeAdapterCaller(address common.Address, caller bind.ContractCaller) (*OptimismL2BridgeAdapterCaller, error) { + contract, err := bindOptimismL2BridgeAdapter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismL2BridgeAdapterCaller{contract: contract}, nil +} + +func NewOptimismL2BridgeAdapterTransactor(address common.Address, transactor bind.ContractTransactor) (*OptimismL2BridgeAdapterTransactor, error) { + contract, err := bindOptimismL2BridgeAdapter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismL2BridgeAdapterTransactor{contract: contract}, nil +} + +func NewOptimismL2BridgeAdapterFilterer(address common.Address, filterer bind.ContractFilterer) (*OptimismL2BridgeAdapterFilterer, error) { + contract, err := bindOptimismL2BridgeAdapter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismL2BridgeAdapterFilterer{contract: contract}, nil +} + +func bindOptimismL2BridgeAdapter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismL2BridgeAdapterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismL2BridgeAdapter.Contract.OptimismL2BridgeAdapterCaller.contract.Call(opts, result, method, params...) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL2BridgeAdapter.Contract.OptimismL2BridgeAdapterTransactor.contract.Transfer(opts) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismL2BridgeAdapter.Contract.OptimismL2BridgeAdapterTransactor.contract.Transact(opts, method, params...) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismL2BridgeAdapter.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL2BridgeAdapter.Contract.contract.Transfer(opts) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismL2BridgeAdapter.Contract.contract.Transact(opts, method, params...) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterCaller) FinalizeWithdrawERC20(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) { + var out []interface{} + err := _OptimismL2BridgeAdapter.contract.Call(opts, &out, "finalizeWithdrawERC20", arg0, arg1, arg2) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterSession) FinalizeWithdrawERC20(arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) { + return _OptimismL2BridgeAdapter.Contract.FinalizeWithdrawERC20(&_OptimismL2BridgeAdapter.CallOpts, arg0, arg1, arg2) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterCallerSession) FinalizeWithdrawERC20(arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) { + return _OptimismL2BridgeAdapter.Contract.FinalizeWithdrawERC20(&_OptimismL2BridgeAdapter.CallOpts, arg0, arg1, arg2) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterCaller) GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _OptimismL2BridgeAdapter.contract.Call(opts, &out, "getBridgeFeeInNative") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterSession) GetBridgeFeeInNative() (*big.Int, error) { + return _OptimismL2BridgeAdapter.Contract.GetBridgeFeeInNative(&_OptimismL2BridgeAdapter.CallOpts) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterCallerSession) GetBridgeFeeInNative() (*big.Int, error) { + return _OptimismL2BridgeAdapter.Contract.GetBridgeFeeInNative(&_OptimismL2BridgeAdapter.CallOpts) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterCaller) GetL2Bridge(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismL2BridgeAdapter.contract.Call(opts, &out, "getL2Bridge") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterSession) GetL2Bridge() (common.Address, error) { + return _OptimismL2BridgeAdapter.Contract.GetL2Bridge(&_OptimismL2BridgeAdapter.CallOpts) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterCallerSession) GetL2Bridge() (common.Address, error) { + return _OptimismL2BridgeAdapter.Contract.GetL2Bridge(&_OptimismL2BridgeAdapter.CallOpts) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterCaller) GetWrappedNative(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismL2BridgeAdapter.contract.Call(opts, &out, "getWrappedNative") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterSession) GetWrappedNative() (common.Address, error) { + return _OptimismL2BridgeAdapter.Contract.GetWrappedNative(&_OptimismL2BridgeAdapter.CallOpts) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterCallerSession) GetWrappedNative() (common.Address, error) { + return _OptimismL2BridgeAdapter.Contract.GetWrappedNative(&_OptimismL2BridgeAdapter.CallOpts) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterTransactor) SendERC20(opts *bind.TransactOpts, localToken common.Address, arg1 common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _OptimismL2BridgeAdapter.contract.Transact(opts, "sendERC20", localToken, arg1, recipient, amount, arg4) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterSession) SendERC20(localToken common.Address, arg1 common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _OptimismL2BridgeAdapter.Contract.SendERC20(&_OptimismL2BridgeAdapter.TransactOpts, localToken, arg1, recipient, amount, arg4) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterTransactorSession) SendERC20(localToken common.Address, arg1 common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + return _OptimismL2BridgeAdapter.Contract.SendERC20(&_OptimismL2BridgeAdapter.TransactOpts, localToken, arg1, recipient, amount, arg4) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL2BridgeAdapter.contract.RawTransact(opts, nil) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterSession) Receive() (*types.Transaction, error) { + return _OptimismL2BridgeAdapter.Contract.Receive(&_OptimismL2BridgeAdapter.TransactOpts) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapterTransactorSession) Receive() (*types.Transaction, error) { + return _OptimismL2BridgeAdapter.Contract.Receive(&_OptimismL2BridgeAdapter.TransactOpts) +} + +func (_OptimismL2BridgeAdapter *OptimismL2BridgeAdapter) Address() common.Address { + return _OptimismL2BridgeAdapter.address +} + +type OptimismL2BridgeAdapterInterface interface { + FinalizeWithdrawERC20(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) + + GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) + + GetL2Bridge(opts *bind.CallOpts) (common.Address, error) + + GetWrappedNative(opts *bind.CallOpts) (common.Address, error) + + SendERC20(opts *bind.TransactOpts, localToken common.Address, arg1 common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) + + Receive(opts *bind.TransactOpts) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/optimism_l2_output_oracle/optimism_l2_output_oracle.go b/core/gethwrappers/liquiditymanager/generated/optimism_l2_output_oracle/optimism_l2_output_oracle.go new file mode 100644 index 0000000000..ddcd6e47ca --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/optimism_l2_output_oracle/optimism_l2_output_oracle.go @@ -0,0 +1,213 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_l2_output_oracle + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type TypesOutputProposal struct { + OutputRoot [32]byte + Timestamp *big.Int + L2BlockNumber *big.Int +} + +var OptimismL2OutputOracleMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"getL2Output\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}],\"internalType\":\"structTypes.OutputProposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"getL2OutputIndexAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +var OptimismL2OutputOracleABI = OptimismL2OutputOracleMetaData.ABI + +type OptimismL2OutputOracle struct { + address common.Address + abi abi.ABI + OptimismL2OutputOracleCaller + OptimismL2OutputOracleTransactor + OptimismL2OutputOracleFilterer +} + +type OptimismL2OutputOracleCaller struct { + contract *bind.BoundContract +} + +type OptimismL2OutputOracleTransactor struct { + contract *bind.BoundContract +} + +type OptimismL2OutputOracleFilterer struct { + contract *bind.BoundContract +} + +type OptimismL2OutputOracleSession struct { + Contract *OptimismL2OutputOracle + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismL2OutputOracleCallerSession struct { + Contract *OptimismL2OutputOracleCaller + CallOpts bind.CallOpts +} + +type OptimismL2OutputOracleTransactorSession struct { + Contract *OptimismL2OutputOracleTransactor + TransactOpts bind.TransactOpts +} + +type OptimismL2OutputOracleRaw struct { + Contract *OptimismL2OutputOracle +} + +type OptimismL2OutputOracleCallerRaw struct { + Contract *OptimismL2OutputOracleCaller +} + +type OptimismL2OutputOracleTransactorRaw struct { + Contract *OptimismL2OutputOracleTransactor +} + +func NewOptimismL2OutputOracle(address common.Address, backend bind.ContractBackend) (*OptimismL2OutputOracle, error) { + abi, err := abi.JSON(strings.NewReader(OptimismL2OutputOracleABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismL2OutputOracle(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismL2OutputOracle{address: address, abi: abi, OptimismL2OutputOracleCaller: OptimismL2OutputOracleCaller{contract: contract}, OptimismL2OutputOracleTransactor: OptimismL2OutputOracleTransactor{contract: contract}, OptimismL2OutputOracleFilterer: OptimismL2OutputOracleFilterer{contract: contract}}, nil +} + +func NewOptimismL2OutputOracleCaller(address common.Address, caller bind.ContractCaller) (*OptimismL2OutputOracleCaller, error) { + contract, err := bindOptimismL2OutputOracle(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismL2OutputOracleCaller{contract: contract}, nil +} + +func NewOptimismL2OutputOracleTransactor(address common.Address, transactor bind.ContractTransactor) (*OptimismL2OutputOracleTransactor, error) { + contract, err := bindOptimismL2OutputOracle(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismL2OutputOracleTransactor{contract: contract}, nil +} + +func NewOptimismL2OutputOracleFilterer(address common.Address, filterer bind.ContractFilterer) (*OptimismL2OutputOracleFilterer, error) { + contract, err := bindOptimismL2OutputOracle(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismL2OutputOracleFilterer{contract: contract}, nil +} + +func bindOptimismL2OutputOracle(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismL2OutputOracleMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracleRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismL2OutputOracle.Contract.OptimismL2OutputOracleCaller.contract.Call(opts, result, method, params...) +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracleRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL2OutputOracle.Contract.OptimismL2OutputOracleTransactor.contract.Transfer(opts) +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracleRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismL2OutputOracle.Contract.OptimismL2OutputOracleTransactor.contract.Transact(opts, method, params...) +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracleCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismL2OutputOracle.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracleTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL2OutputOracle.Contract.contract.Transfer(opts) +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracleTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismL2OutputOracle.Contract.contract.Transact(opts, method, params...) +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracleCaller) GetL2Output(opts *bind.CallOpts, _l2OutputIndex *big.Int) (TypesOutputProposal, error) { + var out []interface{} + err := _OptimismL2OutputOracle.contract.Call(opts, &out, "getL2Output", _l2OutputIndex) + + if err != nil { + return *new(TypesOutputProposal), err + } + + out0 := *abi.ConvertType(out[0], new(TypesOutputProposal)).(*TypesOutputProposal) + + return out0, err + +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracleSession) GetL2Output(_l2OutputIndex *big.Int) (TypesOutputProposal, error) { + return _OptimismL2OutputOracle.Contract.GetL2Output(&_OptimismL2OutputOracle.CallOpts, _l2OutputIndex) +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracleCallerSession) GetL2Output(_l2OutputIndex *big.Int) (TypesOutputProposal, error) { + return _OptimismL2OutputOracle.Contract.GetL2Output(&_OptimismL2OutputOracle.CallOpts, _l2OutputIndex) +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracleCaller) GetL2OutputIndexAfter(opts *bind.CallOpts, _l2BlockNumber *big.Int) (*big.Int, error) { + var out []interface{} + err := _OptimismL2OutputOracle.contract.Call(opts, &out, "getL2OutputIndexAfter", _l2BlockNumber) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracleSession) GetL2OutputIndexAfter(_l2BlockNumber *big.Int) (*big.Int, error) { + return _OptimismL2OutputOracle.Contract.GetL2OutputIndexAfter(&_OptimismL2OutputOracle.CallOpts, _l2BlockNumber) +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracleCallerSession) GetL2OutputIndexAfter(_l2BlockNumber *big.Int) (*big.Int, error) { + return _OptimismL2OutputOracle.Contract.GetL2OutputIndexAfter(&_OptimismL2OutputOracle.CallOpts, _l2BlockNumber) +} + +func (_OptimismL2OutputOracle *OptimismL2OutputOracle) Address() common.Address { + return _OptimismL2OutputOracle.address +} + +type OptimismL2OutputOracleInterface interface { + GetL2Output(opts *bind.CallOpts, _l2OutputIndex *big.Int) (TypesOutputProposal, error) + + GetL2OutputIndexAfter(opts *bind.CallOpts, _l2BlockNumber *big.Int) (*big.Int, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/optimism_l2_to_l1_message_passer/optimism_l2_to_l1_message_passer.go b/core/gethwrappers/liquiditymanager/generated/optimism_l2_to_l1_message_passer/optimism_l2_to_l1_message_passer.go new file mode 100644 index 0000000000..69ee5a2ba2 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/optimism_l2_to_l1_message_passer/optimism_l2_to_l1_message_passer.go @@ -0,0 +1,332 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_l2_to_l1_message_passer + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var OptimismL2ToL1MessagePasserMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"}],\"name\":\"MessagePassed\",\"type\":\"event\"}]", +} + +var OptimismL2ToL1MessagePasserABI = OptimismL2ToL1MessagePasserMetaData.ABI + +type OptimismL2ToL1MessagePasser struct { + address common.Address + abi abi.ABI + OptimismL2ToL1MessagePasserCaller + OptimismL2ToL1MessagePasserTransactor + OptimismL2ToL1MessagePasserFilterer +} + +type OptimismL2ToL1MessagePasserCaller struct { + contract *bind.BoundContract +} + +type OptimismL2ToL1MessagePasserTransactor struct { + contract *bind.BoundContract +} + +type OptimismL2ToL1MessagePasserFilterer struct { + contract *bind.BoundContract +} + +type OptimismL2ToL1MessagePasserSession struct { + Contract *OptimismL2ToL1MessagePasser + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismL2ToL1MessagePasserCallerSession struct { + Contract *OptimismL2ToL1MessagePasserCaller + CallOpts bind.CallOpts +} + +type OptimismL2ToL1MessagePasserTransactorSession struct { + Contract *OptimismL2ToL1MessagePasserTransactor + TransactOpts bind.TransactOpts +} + +type OptimismL2ToL1MessagePasserRaw struct { + Contract *OptimismL2ToL1MessagePasser +} + +type OptimismL2ToL1MessagePasserCallerRaw struct { + Contract *OptimismL2ToL1MessagePasserCaller +} + +type OptimismL2ToL1MessagePasserTransactorRaw struct { + Contract *OptimismL2ToL1MessagePasserTransactor +} + +func NewOptimismL2ToL1MessagePasser(address common.Address, backend bind.ContractBackend) (*OptimismL2ToL1MessagePasser, error) { + abi, err := abi.JSON(strings.NewReader(OptimismL2ToL1MessagePasserABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismL2ToL1MessagePasser(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismL2ToL1MessagePasser{address: address, abi: abi, OptimismL2ToL1MessagePasserCaller: OptimismL2ToL1MessagePasserCaller{contract: contract}, OptimismL2ToL1MessagePasserTransactor: OptimismL2ToL1MessagePasserTransactor{contract: contract}, OptimismL2ToL1MessagePasserFilterer: OptimismL2ToL1MessagePasserFilterer{contract: contract}}, nil +} + +func NewOptimismL2ToL1MessagePasserCaller(address common.Address, caller bind.ContractCaller) (*OptimismL2ToL1MessagePasserCaller, error) { + contract, err := bindOptimismL2ToL1MessagePasser(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismL2ToL1MessagePasserCaller{contract: contract}, nil +} + +func NewOptimismL2ToL1MessagePasserTransactor(address common.Address, transactor bind.ContractTransactor) (*OptimismL2ToL1MessagePasserTransactor, error) { + contract, err := bindOptimismL2ToL1MessagePasser(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismL2ToL1MessagePasserTransactor{contract: contract}, nil +} + +func NewOptimismL2ToL1MessagePasserFilterer(address common.Address, filterer bind.ContractFilterer) (*OptimismL2ToL1MessagePasserFilterer, error) { + contract, err := bindOptimismL2ToL1MessagePasser(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismL2ToL1MessagePasserFilterer{contract: contract}, nil +} + +func bindOptimismL2ToL1MessagePasser(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismL2ToL1MessagePasserMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismL2ToL1MessagePasser *OptimismL2ToL1MessagePasserRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismL2ToL1MessagePasser.Contract.OptimismL2ToL1MessagePasserCaller.contract.Call(opts, result, method, params...) +} + +func (_OptimismL2ToL1MessagePasser *OptimismL2ToL1MessagePasserRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL2ToL1MessagePasser.Contract.OptimismL2ToL1MessagePasserTransactor.contract.Transfer(opts) +} + +func (_OptimismL2ToL1MessagePasser *OptimismL2ToL1MessagePasserRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismL2ToL1MessagePasser.Contract.OptimismL2ToL1MessagePasserTransactor.contract.Transact(opts, method, params...) +} + +func (_OptimismL2ToL1MessagePasser *OptimismL2ToL1MessagePasserCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismL2ToL1MessagePasser.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismL2ToL1MessagePasser *OptimismL2ToL1MessagePasserTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismL2ToL1MessagePasser.Contract.contract.Transfer(opts) +} + +func (_OptimismL2ToL1MessagePasser *OptimismL2ToL1MessagePasserTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismL2ToL1MessagePasser.Contract.contract.Transact(opts, method, params...) +} + +type OptimismL2ToL1MessagePasserMessagePassedIterator struct { + Event *OptimismL2ToL1MessagePasserMessagePassed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OptimismL2ToL1MessagePasserMessagePassedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OptimismL2ToL1MessagePasserMessagePassed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(OptimismL2ToL1MessagePasserMessagePassed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *OptimismL2ToL1MessagePasserMessagePassedIterator) Error() error { + return it.fail +} + +func (it *OptimismL2ToL1MessagePasserMessagePassedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OptimismL2ToL1MessagePasserMessagePassed struct { + Nonce *big.Int + Sender common.Address + Target common.Address + Value *big.Int + GasLimit *big.Int + Data []byte + WithdrawalHash [32]byte + Raw types.Log +} + +func (_OptimismL2ToL1MessagePasser *OptimismL2ToL1MessagePasserFilterer) FilterMessagePassed(opts *bind.FilterOpts, nonce []*big.Int, sender []common.Address, target []common.Address) (*OptimismL2ToL1MessagePasserMessagePassedIterator, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var targetRule []interface{} + for _, targetItem := range target { + targetRule = append(targetRule, targetItem) + } + + logs, sub, err := _OptimismL2ToL1MessagePasser.contract.FilterLogs(opts, "MessagePassed", nonceRule, senderRule, targetRule) + if err != nil { + return nil, err + } + return &OptimismL2ToL1MessagePasserMessagePassedIterator{contract: _OptimismL2ToL1MessagePasser.contract, event: "MessagePassed", logs: logs, sub: sub}, nil +} + +func (_OptimismL2ToL1MessagePasser *OptimismL2ToL1MessagePasserFilterer) WatchMessagePassed(opts *bind.WatchOpts, sink chan<- *OptimismL2ToL1MessagePasserMessagePassed, nonce []*big.Int, sender []common.Address, target []common.Address) (event.Subscription, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var targetRule []interface{} + for _, targetItem := range target { + targetRule = append(targetRule, targetItem) + } + + logs, sub, err := _OptimismL2ToL1MessagePasser.contract.WatchLogs(opts, "MessagePassed", nonceRule, senderRule, targetRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OptimismL2ToL1MessagePasserMessagePassed) + if err := _OptimismL2ToL1MessagePasser.contract.UnpackLog(event, "MessagePassed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_OptimismL2ToL1MessagePasser *OptimismL2ToL1MessagePasserFilterer) ParseMessagePassed(log types.Log) (*OptimismL2ToL1MessagePasserMessagePassed, error) { + event := new(OptimismL2ToL1MessagePasserMessagePassed) + if err := _OptimismL2ToL1MessagePasser.contract.UnpackLog(event, "MessagePassed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_OptimismL2ToL1MessagePasser *OptimismL2ToL1MessagePasser) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _OptimismL2ToL1MessagePasser.abi.Events["MessagePassed"].ID: + return _OptimismL2ToL1MessagePasser.ParseMessagePassed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (OptimismL2ToL1MessagePasserMessagePassed) Topic() common.Hash { + return common.HexToHash("0x02a52367d10742d8032712c1bb8e0144ff1ec5ffda1ed7d70bb05a2744955054") +} + +func (_OptimismL2ToL1MessagePasser *OptimismL2ToL1MessagePasser) Address() common.Address { + return _OptimismL2ToL1MessagePasser.address +} + +type OptimismL2ToL1MessagePasserInterface interface { + FilterMessagePassed(opts *bind.FilterOpts, nonce []*big.Int, sender []common.Address, target []common.Address) (*OptimismL2ToL1MessagePasserMessagePassedIterator, error) + + WatchMessagePassed(opts *bind.WatchOpts, sink chan<- *OptimismL2ToL1MessagePasserMessagePassed, nonce []*big.Int, sender []common.Address, target []common.Address) (event.Subscription, error) + + ParseMessagePassed(log types.Log) (*OptimismL2ToL1MessagePasserMessagePassed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/optimism_portal/optimism_portal.go b/core/gethwrappers/liquiditymanager/generated/optimism_portal/optimism_portal.go new file mode 100644 index 0000000000..e142d700fc --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/optimism_portal/optimism_portal.go @@ -0,0 +1,227 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_portal + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type TypesOutputRootProof struct { + Version [32]byte + StateRoot [32]byte + MessagePasserStorageRoot [32]byte + LatestBlockhash [32]byte +} + +type TypesWithdrawalTransaction struct { + Nonce *big.Int + Sender common.Address + Target common.Address + Value *big.Int + GasLimit *big.Int + Data []byte +} + +var OptimismPortalMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"}],\"name\":\"finalizeWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}],\"internalType\":\"structTypes.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"_withdrawalProof\",\"type\":\"bytes[]\"}],\"name\":\"proveWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +var OptimismPortalABI = OptimismPortalMetaData.ABI + +type OptimismPortal struct { + address common.Address + abi abi.ABI + OptimismPortalCaller + OptimismPortalTransactor + OptimismPortalFilterer +} + +type OptimismPortalCaller struct { + contract *bind.BoundContract +} + +type OptimismPortalTransactor struct { + contract *bind.BoundContract +} + +type OptimismPortalFilterer struct { + contract *bind.BoundContract +} + +type OptimismPortalSession struct { + Contract *OptimismPortal + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismPortalCallerSession struct { + Contract *OptimismPortalCaller + CallOpts bind.CallOpts +} + +type OptimismPortalTransactorSession struct { + Contract *OptimismPortalTransactor + TransactOpts bind.TransactOpts +} + +type OptimismPortalRaw struct { + Contract *OptimismPortal +} + +type OptimismPortalCallerRaw struct { + Contract *OptimismPortalCaller +} + +type OptimismPortalTransactorRaw struct { + Contract *OptimismPortalTransactor +} + +func NewOptimismPortal(address common.Address, backend bind.ContractBackend) (*OptimismPortal, error) { + abi, err := abi.JSON(strings.NewReader(OptimismPortalABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismPortal(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismPortal{address: address, abi: abi, OptimismPortalCaller: OptimismPortalCaller{contract: contract}, OptimismPortalTransactor: OptimismPortalTransactor{contract: contract}, OptimismPortalFilterer: OptimismPortalFilterer{contract: contract}}, nil +} + +func NewOptimismPortalCaller(address common.Address, caller bind.ContractCaller) (*OptimismPortalCaller, error) { + contract, err := bindOptimismPortal(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismPortalCaller{contract: contract}, nil +} + +func NewOptimismPortalTransactor(address common.Address, transactor bind.ContractTransactor) (*OptimismPortalTransactor, error) { + contract, err := bindOptimismPortal(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismPortalTransactor{contract: contract}, nil +} + +func NewOptimismPortalFilterer(address common.Address, filterer bind.ContractFilterer) (*OptimismPortalFilterer, error) { + contract, err := bindOptimismPortal(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismPortalFilterer{contract: contract}, nil +} + +func bindOptimismPortal(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismPortalMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismPortal *OptimismPortalRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismPortal.Contract.OptimismPortalCaller.contract.Call(opts, result, method, params...) +} + +func (_OptimismPortal *OptimismPortalRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismPortal.Contract.OptimismPortalTransactor.contract.Transfer(opts) +} + +func (_OptimismPortal *OptimismPortalRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismPortal.Contract.OptimismPortalTransactor.contract.Transact(opts, method, params...) +} + +func (_OptimismPortal *OptimismPortalCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismPortal.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismPortal *OptimismPortalTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismPortal.Contract.contract.Transfer(opts) +} + +func (_OptimismPortal *OptimismPortalTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismPortal.Contract.contract.Transact(opts, method, params...) +} + +func (_OptimismPortal *OptimismPortalCaller) Version(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _OptimismPortal.contract.Call(opts, &out, "version") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_OptimismPortal *OptimismPortalSession) Version() (string, error) { + return _OptimismPortal.Contract.Version(&_OptimismPortal.CallOpts) +} + +func (_OptimismPortal *OptimismPortalCallerSession) Version() (string, error) { + return _OptimismPortal.Contract.Version(&_OptimismPortal.CallOpts) +} + +func (_OptimismPortal *OptimismPortalTransactor) FinalizeWithdrawalTransaction(opts *bind.TransactOpts, _tx TypesWithdrawalTransaction) (*types.Transaction, error) { + return _OptimismPortal.contract.Transact(opts, "finalizeWithdrawalTransaction", _tx) +} + +func (_OptimismPortal *OptimismPortalSession) FinalizeWithdrawalTransaction(_tx TypesWithdrawalTransaction) (*types.Transaction, error) { + return _OptimismPortal.Contract.FinalizeWithdrawalTransaction(&_OptimismPortal.TransactOpts, _tx) +} + +func (_OptimismPortal *OptimismPortalTransactorSession) FinalizeWithdrawalTransaction(_tx TypesWithdrawalTransaction) (*types.Transaction, error) { + return _OptimismPortal.Contract.FinalizeWithdrawalTransaction(&_OptimismPortal.TransactOpts, _tx) +} + +func (_OptimismPortal *OptimismPortalTransactor) ProveWithdrawalTransaction(opts *bind.TransactOpts, _tx TypesWithdrawalTransaction, _l2OutputIndex *big.Int, _outputRootProof TypesOutputRootProof, _withdrawalProof [][]byte) (*types.Transaction, error) { + return _OptimismPortal.contract.Transact(opts, "proveWithdrawalTransaction", _tx, _l2OutputIndex, _outputRootProof, _withdrawalProof) +} + +func (_OptimismPortal *OptimismPortalSession) ProveWithdrawalTransaction(_tx TypesWithdrawalTransaction, _l2OutputIndex *big.Int, _outputRootProof TypesOutputRootProof, _withdrawalProof [][]byte) (*types.Transaction, error) { + return _OptimismPortal.Contract.ProveWithdrawalTransaction(&_OptimismPortal.TransactOpts, _tx, _l2OutputIndex, _outputRootProof, _withdrawalProof) +} + +func (_OptimismPortal *OptimismPortalTransactorSession) ProveWithdrawalTransaction(_tx TypesWithdrawalTransaction, _l2OutputIndex *big.Int, _outputRootProof TypesOutputRootProof, _withdrawalProof [][]byte) (*types.Transaction, error) { + return _OptimismPortal.Contract.ProveWithdrawalTransaction(&_OptimismPortal.TransactOpts, _tx, _l2OutputIndex, _outputRootProof, _withdrawalProof) +} + +func (_OptimismPortal *OptimismPortal) Address() common.Address { + return _OptimismPortal.address +} + +type OptimismPortalInterface interface { + Version(opts *bind.CallOpts) (string, error) + + FinalizeWithdrawalTransaction(opts *bind.TransactOpts, _tx TypesWithdrawalTransaction) (*types.Transaction, error) + + ProveWithdrawalTransaction(opts *bind.TransactOpts, _tx TypesWithdrawalTransaction, _l2OutputIndex *big.Int, _outputRootProof TypesOutputRootProof, _withdrawalProof [][]byte) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/optimism_portal_2/optimism_portal_2.go b/core/gethwrappers/liquiditymanager/generated/optimism_portal_2/optimism_portal_2.go new file mode 100644 index 0000000000..1759ca1251 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/optimism_portal_2/optimism_portal_2.go @@ -0,0 +1,207 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_portal_2 + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var OptimismPortal2MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"disputeGameFactory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"respectedGameType\",\"outputs\":[{\"internalType\":\"GameType\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +var OptimismPortal2ABI = OptimismPortal2MetaData.ABI + +type OptimismPortal2 struct { + address common.Address + abi abi.ABI + OptimismPortal2Caller + OptimismPortal2Transactor + OptimismPortal2Filterer +} + +type OptimismPortal2Caller struct { + contract *bind.BoundContract +} + +type OptimismPortal2Transactor struct { + contract *bind.BoundContract +} + +type OptimismPortal2Filterer struct { + contract *bind.BoundContract +} + +type OptimismPortal2Session struct { + Contract *OptimismPortal2 + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismPortal2CallerSession struct { + Contract *OptimismPortal2Caller + CallOpts bind.CallOpts +} + +type OptimismPortal2TransactorSession struct { + Contract *OptimismPortal2Transactor + TransactOpts bind.TransactOpts +} + +type OptimismPortal2Raw struct { + Contract *OptimismPortal2 +} + +type OptimismPortal2CallerRaw struct { + Contract *OptimismPortal2Caller +} + +type OptimismPortal2TransactorRaw struct { + Contract *OptimismPortal2Transactor +} + +func NewOptimismPortal2(address common.Address, backend bind.ContractBackend) (*OptimismPortal2, error) { + abi, err := abi.JSON(strings.NewReader(OptimismPortal2ABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismPortal2(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismPortal2{address: address, abi: abi, OptimismPortal2Caller: OptimismPortal2Caller{contract: contract}, OptimismPortal2Transactor: OptimismPortal2Transactor{contract: contract}, OptimismPortal2Filterer: OptimismPortal2Filterer{contract: contract}}, nil +} + +func NewOptimismPortal2Caller(address common.Address, caller bind.ContractCaller) (*OptimismPortal2Caller, error) { + contract, err := bindOptimismPortal2(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismPortal2Caller{contract: contract}, nil +} + +func NewOptimismPortal2Transactor(address common.Address, transactor bind.ContractTransactor) (*OptimismPortal2Transactor, error) { + contract, err := bindOptimismPortal2(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismPortal2Transactor{contract: contract}, nil +} + +func NewOptimismPortal2Filterer(address common.Address, filterer bind.ContractFilterer) (*OptimismPortal2Filterer, error) { + contract, err := bindOptimismPortal2(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismPortal2Filterer{contract: contract}, nil +} + +func bindOptimismPortal2(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismPortal2MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismPortal2 *OptimismPortal2Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismPortal2.Contract.OptimismPortal2Caller.contract.Call(opts, result, method, params...) +} + +func (_OptimismPortal2 *OptimismPortal2Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismPortal2.Contract.OptimismPortal2Transactor.contract.Transfer(opts) +} + +func (_OptimismPortal2 *OptimismPortal2Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismPortal2.Contract.OptimismPortal2Transactor.contract.Transact(opts, method, params...) +} + +func (_OptimismPortal2 *OptimismPortal2CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismPortal2.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismPortal2 *OptimismPortal2TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismPortal2.Contract.contract.Transfer(opts) +} + +func (_OptimismPortal2 *OptimismPortal2TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismPortal2.Contract.contract.Transact(opts, method, params...) +} + +func (_OptimismPortal2 *OptimismPortal2Caller) DisputeGameFactory(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "disputeGameFactory") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_OptimismPortal2 *OptimismPortal2Session) DisputeGameFactory() (common.Address, error) { + return _OptimismPortal2.Contract.DisputeGameFactory(&_OptimismPortal2.CallOpts) +} + +func (_OptimismPortal2 *OptimismPortal2CallerSession) DisputeGameFactory() (common.Address, error) { + return _OptimismPortal2.Contract.DisputeGameFactory(&_OptimismPortal2.CallOpts) +} + +func (_OptimismPortal2 *OptimismPortal2Caller) RespectedGameType(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "respectedGameType") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_OptimismPortal2 *OptimismPortal2Session) RespectedGameType() (uint32, error) { + return _OptimismPortal2.Contract.RespectedGameType(&_OptimismPortal2.CallOpts) +} + +func (_OptimismPortal2 *OptimismPortal2CallerSession) RespectedGameType() (uint32, error) { + return _OptimismPortal2.Contract.RespectedGameType(&_OptimismPortal2.CallOpts) +} + +func (_OptimismPortal2 *OptimismPortal2) Address() common.Address { + return _OptimismPortal2.address +} + +type OptimismPortal2Interface interface { + DisputeGameFactory(opts *bind.CallOpts) (common.Address, error) + + RespectedGameType(opts *bind.CallOpts) (uint32, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/optimism_standard_bridge/optimism_standard_bridge.go b/core/gethwrappers/liquiditymanager/generated/optimism_standard_bridge/optimism_standard_bridge.go new file mode 100644 index 0000000000..b6a7d45143 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/optimism_standard_bridge/optimism_standard_bridge.go @@ -0,0 +1,345 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_standard_bridge + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var OptimismStandardBridgeMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeFinalized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +var OptimismStandardBridgeABI = OptimismStandardBridgeMetaData.ABI + +type OptimismStandardBridge struct { + address common.Address + abi abi.ABI + OptimismStandardBridgeCaller + OptimismStandardBridgeTransactor + OptimismStandardBridgeFilterer +} + +type OptimismStandardBridgeCaller struct { + contract *bind.BoundContract +} + +type OptimismStandardBridgeTransactor struct { + contract *bind.BoundContract +} + +type OptimismStandardBridgeFilterer struct { + contract *bind.BoundContract +} + +type OptimismStandardBridgeSession struct { + Contract *OptimismStandardBridge + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismStandardBridgeCallerSession struct { + Contract *OptimismStandardBridgeCaller + CallOpts bind.CallOpts +} + +type OptimismStandardBridgeTransactorSession struct { + Contract *OptimismStandardBridgeTransactor + TransactOpts bind.TransactOpts +} + +type OptimismStandardBridgeRaw struct { + Contract *OptimismStandardBridge +} + +type OptimismStandardBridgeCallerRaw struct { + Contract *OptimismStandardBridgeCaller +} + +type OptimismStandardBridgeTransactorRaw struct { + Contract *OptimismStandardBridgeTransactor +} + +func NewOptimismStandardBridge(address common.Address, backend bind.ContractBackend) (*OptimismStandardBridge, error) { + abi, err := abi.JSON(strings.NewReader(OptimismStandardBridgeABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismStandardBridge(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismStandardBridge{address: address, abi: abi, OptimismStandardBridgeCaller: OptimismStandardBridgeCaller{contract: contract}, OptimismStandardBridgeTransactor: OptimismStandardBridgeTransactor{contract: contract}, OptimismStandardBridgeFilterer: OptimismStandardBridgeFilterer{contract: contract}}, nil +} + +func NewOptimismStandardBridgeCaller(address common.Address, caller bind.ContractCaller) (*OptimismStandardBridgeCaller, error) { + contract, err := bindOptimismStandardBridge(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismStandardBridgeCaller{contract: contract}, nil +} + +func NewOptimismStandardBridgeTransactor(address common.Address, transactor bind.ContractTransactor) (*OptimismStandardBridgeTransactor, error) { + contract, err := bindOptimismStandardBridge(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismStandardBridgeTransactor{contract: contract}, nil +} + +func NewOptimismStandardBridgeFilterer(address common.Address, filterer bind.ContractFilterer) (*OptimismStandardBridgeFilterer, error) { + contract, err := bindOptimismStandardBridge(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismStandardBridgeFilterer{contract: contract}, nil +} + +func bindOptimismStandardBridge(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismStandardBridgeMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismStandardBridge *OptimismStandardBridgeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismStandardBridge.Contract.OptimismStandardBridgeCaller.contract.Call(opts, result, method, params...) +} + +func (_OptimismStandardBridge *OptimismStandardBridgeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismStandardBridge.Contract.OptimismStandardBridgeTransactor.contract.Transfer(opts) +} + +func (_OptimismStandardBridge *OptimismStandardBridgeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismStandardBridge.Contract.OptimismStandardBridgeTransactor.contract.Transact(opts, method, params...) +} + +func (_OptimismStandardBridge *OptimismStandardBridgeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismStandardBridge.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismStandardBridge *OptimismStandardBridgeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismStandardBridge.Contract.contract.Transfer(opts) +} + +func (_OptimismStandardBridge *OptimismStandardBridgeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismStandardBridge.Contract.contract.Transact(opts, method, params...) +} + +func (_OptimismStandardBridge *OptimismStandardBridgeTransactor) FinalizeBridgeERC20(opts *bind.TransactOpts, _localToken common.Address, _remoteToken common.Address, _from common.Address, _to common.Address, _amount *big.Int, _extraData []byte) (*types.Transaction, error) { + return _OptimismStandardBridge.contract.Transact(opts, "finalizeBridgeERC20", _localToken, _remoteToken, _from, _to, _amount, _extraData) +} + +func (_OptimismStandardBridge *OptimismStandardBridgeSession) FinalizeBridgeERC20(_localToken common.Address, _remoteToken common.Address, _from common.Address, _to common.Address, _amount *big.Int, _extraData []byte) (*types.Transaction, error) { + return _OptimismStandardBridge.Contract.FinalizeBridgeERC20(&_OptimismStandardBridge.TransactOpts, _localToken, _remoteToken, _from, _to, _amount, _extraData) +} + +func (_OptimismStandardBridge *OptimismStandardBridgeTransactorSession) FinalizeBridgeERC20(_localToken common.Address, _remoteToken common.Address, _from common.Address, _to common.Address, _amount *big.Int, _extraData []byte) (*types.Transaction, error) { + return _OptimismStandardBridge.Contract.FinalizeBridgeERC20(&_OptimismStandardBridge.TransactOpts, _localToken, _remoteToken, _from, _to, _amount, _extraData) +} + +type OptimismStandardBridgeERC20BridgeFinalizedIterator struct { + Event *OptimismStandardBridgeERC20BridgeFinalized + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OptimismStandardBridgeERC20BridgeFinalizedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OptimismStandardBridgeERC20BridgeFinalized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(OptimismStandardBridgeERC20BridgeFinalized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *OptimismStandardBridgeERC20BridgeFinalizedIterator) Error() error { + return it.fail +} + +func (it *OptimismStandardBridgeERC20BridgeFinalizedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OptimismStandardBridgeERC20BridgeFinalized struct { + LocalToken common.Address + RemoteToken common.Address + From common.Address + To common.Address + Amount *big.Int + ExtraData []byte + Raw types.Log +} + +func (_OptimismStandardBridge *OptimismStandardBridgeFilterer) FilterERC20BridgeFinalized(opts *bind.FilterOpts, localToken []common.Address, remoteToken []common.Address, from []common.Address) (*OptimismStandardBridgeERC20BridgeFinalizedIterator, error) { + + var localTokenRule []interface{} + for _, localTokenItem := range localToken { + localTokenRule = append(localTokenRule, localTokenItem) + } + var remoteTokenRule []interface{} + for _, remoteTokenItem := range remoteToken { + remoteTokenRule = append(remoteTokenRule, remoteTokenItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _OptimismStandardBridge.contract.FilterLogs(opts, "ERC20BridgeFinalized", localTokenRule, remoteTokenRule, fromRule) + if err != nil { + return nil, err + } + return &OptimismStandardBridgeERC20BridgeFinalizedIterator{contract: _OptimismStandardBridge.contract, event: "ERC20BridgeFinalized", logs: logs, sub: sub}, nil +} + +func (_OptimismStandardBridge *OptimismStandardBridgeFilterer) WatchERC20BridgeFinalized(opts *bind.WatchOpts, sink chan<- *OptimismStandardBridgeERC20BridgeFinalized, localToken []common.Address, remoteToken []common.Address, from []common.Address) (event.Subscription, error) { + + var localTokenRule []interface{} + for _, localTokenItem := range localToken { + localTokenRule = append(localTokenRule, localTokenItem) + } + var remoteTokenRule []interface{} + for _, remoteTokenItem := range remoteToken { + remoteTokenRule = append(remoteTokenRule, remoteTokenItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _OptimismStandardBridge.contract.WatchLogs(opts, "ERC20BridgeFinalized", localTokenRule, remoteTokenRule, fromRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OptimismStandardBridgeERC20BridgeFinalized) + if err := _OptimismStandardBridge.contract.UnpackLog(event, "ERC20BridgeFinalized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_OptimismStandardBridge *OptimismStandardBridgeFilterer) ParseERC20BridgeFinalized(log types.Log) (*OptimismStandardBridgeERC20BridgeFinalized, error) { + event := new(OptimismStandardBridgeERC20BridgeFinalized) + if err := _OptimismStandardBridge.contract.UnpackLog(event, "ERC20BridgeFinalized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_OptimismStandardBridge *OptimismStandardBridge) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _OptimismStandardBridge.abi.Events["ERC20BridgeFinalized"].ID: + return _OptimismStandardBridge.ParseERC20BridgeFinalized(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (OptimismStandardBridgeERC20BridgeFinalized) Topic() common.Hash { + return common.HexToHash("0xd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd") +} + +func (_OptimismStandardBridge *OptimismStandardBridge) Address() common.Address { + return _OptimismStandardBridge.address +} + +type OptimismStandardBridgeInterface interface { + FinalizeBridgeERC20(opts *bind.TransactOpts, _localToken common.Address, _remoteToken common.Address, _from common.Address, _to common.Address, _amount *big.Int, _extraData []byte) (*types.Transaction, error) + + FilterERC20BridgeFinalized(opts *bind.FilterOpts, localToken []common.Address, remoteToken []common.Address, from []common.Address) (*OptimismStandardBridgeERC20BridgeFinalizedIterator, error) + + WatchERC20BridgeFinalized(opts *bind.WatchOpts, sink chan<- *OptimismStandardBridgeERC20BridgeFinalized, localToken []common.Address, remoteToken []common.Address, from []common.Address) (event.Subscription, error) + + ParseERC20BridgeFinalized(log types.Log) (*OptimismStandardBridgeERC20BridgeFinalized, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generated/report_encoder/report_encoder.go b/core/gethwrappers/liquiditymanager/generated/report_encoder/report_encoder.go new file mode 100644 index 0000000000..1e14ea185e --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generated/report_encoder/report_encoder.go @@ -0,0 +1,256 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package report_encoder + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ILiquidityManagerCrossChainRebalancerArgs struct { + RemoteRebalancer common.Address + LocalBridge common.Address + RemoteToken common.Address + RemoteChainSelector uint64 + Enabled bool +} + +type ILiquidityManagerLiquidityInstructions struct { + SendLiquidityParams []ILiquidityManagerSendLiquidityParams + ReceiveLiquidityParams []ILiquidityManagerReceiveLiquidityParams +} + +type ILiquidityManagerReceiveLiquidityParams struct { + Amount *big.Int + RemoteChainSelector uint64 + ShouldWrapNative bool + BridgeData []byte +} + +type ILiquidityManagerSendLiquidityParams struct { + Amount *big.Int + NativeBridgeFee *big.Int + RemoteChainSelector uint64 + BridgeData []byte +} + +var ReportEncoderMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nativeBridgeFee\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"bridgeData\",\"type\":\"bytes\"}],\"internalType\":\"structILiquidityManager.SendLiquidityParams[]\",\"name\":\"sendLiquidityParams\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"shouldWrapNative\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"bridgeData\",\"type\":\"bytes\"}],\"internalType\":\"structILiquidityManager.ReceiveLiquidityParams[]\",\"name\":\"receiveLiquidityParams\",\"type\":\"tuple[]\"}],\"internalType\":\"structILiquidityManager.LiquidityInstructions\",\"name\":\"instructions\",\"type\":\"tuple\"}],\"name\":\"exposeForEncoding\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllCrossChainRebalancers\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"remoteRebalancer\",\"type\":\"address\"},{\"internalType\":\"contractIBridgeAdapter\",\"name\":\"localBridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structILiquidityManager.CrossChainRebalancerArgs[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"currentLiquidity\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +var ReportEncoderABI = ReportEncoderMetaData.ABI + +type ReportEncoder struct { + address common.Address + abi abi.ABI + ReportEncoderCaller + ReportEncoderTransactor + ReportEncoderFilterer +} + +type ReportEncoderCaller struct { + contract *bind.BoundContract +} + +type ReportEncoderTransactor struct { + contract *bind.BoundContract +} + +type ReportEncoderFilterer struct { + contract *bind.BoundContract +} + +type ReportEncoderSession struct { + Contract *ReportEncoder + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ReportEncoderCallerSession struct { + Contract *ReportEncoderCaller + CallOpts bind.CallOpts +} + +type ReportEncoderTransactorSession struct { + Contract *ReportEncoderTransactor + TransactOpts bind.TransactOpts +} + +type ReportEncoderRaw struct { + Contract *ReportEncoder +} + +type ReportEncoderCallerRaw struct { + Contract *ReportEncoderCaller +} + +type ReportEncoderTransactorRaw struct { + Contract *ReportEncoderTransactor +} + +func NewReportEncoder(address common.Address, backend bind.ContractBackend) (*ReportEncoder, error) { + abi, err := abi.JSON(strings.NewReader(ReportEncoderABI)) + if err != nil { + return nil, err + } + contract, err := bindReportEncoder(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ReportEncoder{address: address, abi: abi, ReportEncoderCaller: ReportEncoderCaller{contract: contract}, ReportEncoderTransactor: ReportEncoderTransactor{contract: contract}, ReportEncoderFilterer: ReportEncoderFilterer{contract: contract}}, nil +} + +func NewReportEncoderCaller(address common.Address, caller bind.ContractCaller) (*ReportEncoderCaller, error) { + contract, err := bindReportEncoder(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ReportEncoderCaller{contract: contract}, nil +} + +func NewReportEncoderTransactor(address common.Address, transactor bind.ContractTransactor) (*ReportEncoderTransactor, error) { + contract, err := bindReportEncoder(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ReportEncoderTransactor{contract: contract}, nil +} + +func NewReportEncoderFilterer(address common.Address, filterer bind.ContractFilterer) (*ReportEncoderFilterer, error) { + contract, err := bindReportEncoder(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ReportEncoderFilterer{contract: contract}, nil +} + +func bindReportEncoder(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ReportEncoderMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ReportEncoder *ReportEncoderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReportEncoder.Contract.ReportEncoderCaller.contract.Call(opts, result, method, params...) +} + +func (_ReportEncoder *ReportEncoderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReportEncoder.Contract.ReportEncoderTransactor.contract.Transfer(opts) +} + +func (_ReportEncoder *ReportEncoderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReportEncoder.Contract.ReportEncoderTransactor.contract.Transact(opts, method, params...) +} + +func (_ReportEncoder *ReportEncoderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReportEncoder.Contract.contract.Call(opts, result, method, params...) +} + +func (_ReportEncoder *ReportEncoderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReportEncoder.Contract.contract.Transfer(opts) +} + +func (_ReportEncoder *ReportEncoderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReportEncoder.Contract.contract.Transact(opts, method, params...) +} + +func (_ReportEncoder *ReportEncoderCaller) ExposeForEncoding(opts *bind.CallOpts, instructions ILiquidityManagerLiquidityInstructions) error { + var out []interface{} + err := _ReportEncoder.contract.Call(opts, &out, "exposeForEncoding", instructions) + + if err != nil { + return err + } + + return err + +} + +func (_ReportEncoder *ReportEncoderSession) ExposeForEncoding(instructions ILiquidityManagerLiquidityInstructions) error { + return _ReportEncoder.Contract.ExposeForEncoding(&_ReportEncoder.CallOpts, instructions) +} + +func (_ReportEncoder *ReportEncoderCallerSession) ExposeForEncoding(instructions ILiquidityManagerLiquidityInstructions) error { + return _ReportEncoder.Contract.ExposeForEncoding(&_ReportEncoder.CallOpts, instructions) +} + +func (_ReportEncoder *ReportEncoderCaller) GetAllCrossChainRebalancers(opts *bind.CallOpts) ([]ILiquidityManagerCrossChainRebalancerArgs, error) { + var out []interface{} + err := _ReportEncoder.contract.Call(opts, &out, "getAllCrossChainRebalancers") + + if err != nil { + return *new([]ILiquidityManagerCrossChainRebalancerArgs), err + } + + out0 := *abi.ConvertType(out[0], new([]ILiquidityManagerCrossChainRebalancerArgs)).(*[]ILiquidityManagerCrossChainRebalancerArgs) + + return out0, err + +} + +func (_ReportEncoder *ReportEncoderSession) GetAllCrossChainRebalancers() ([]ILiquidityManagerCrossChainRebalancerArgs, error) { + return _ReportEncoder.Contract.GetAllCrossChainRebalancers(&_ReportEncoder.CallOpts) +} + +func (_ReportEncoder *ReportEncoderCallerSession) GetAllCrossChainRebalancers() ([]ILiquidityManagerCrossChainRebalancerArgs, error) { + return _ReportEncoder.Contract.GetAllCrossChainRebalancers(&_ReportEncoder.CallOpts) +} + +func (_ReportEncoder *ReportEncoderCaller) GetLiquidity(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ReportEncoder.contract.Call(opts, &out, "getLiquidity") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ReportEncoder *ReportEncoderSession) GetLiquidity() (*big.Int, error) { + return _ReportEncoder.Contract.GetLiquidity(&_ReportEncoder.CallOpts) +} + +func (_ReportEncoder *ReportEncoderCallerSession) GetLiquidity() (*big.Int, error) { + return _ReportEncoder.Contract.GetLiquidity(&_ReportEncoder.CallOpts) +} + +func (_ReportEncoder *ReportEncoder) Address() common.Address { + return _ReportEncoder.address +} + +type ReportEncoderInterface interface { + ExposeForEncoding(opts *bind.CallOpts, instructions ILiquidityManagerLiquidityInstructions) error + + GetAllCrossChainRebalancers(opts *bind.CallOpts) ([]ILiquidityManagerCrossChainRebalancerArgs, error) + + GetLiquidity(opts *bind.CallOpts) (*big.Int, error) + + Address() common.Address +} diff --git a/core/gethwrappers/liquiditymanager/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/liquiditymanager/generation/generated-wrapper-dependency-versions-do-not-edit.txt new file mode 100644 index 0000000000..a4fe8720ab --- /dev/null +++ b/core/gethwrappers/liquiditymanager/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -0,0 +1,29 @@ +GETH_VERSION: 1.13.8 +abstract_arbitrum_token_gateway: ../../../contracts/solc/v0.8.24/IAbstractArbitrumTokenGateway/IAbstractArbitrumTokenGateway.abi ../../../contracts/solc/v0.8.24/IAbstractArbitrumTokenGateway/IAbstractArbitrumTokenGateway.bin 779e05d8fb797d4fcfa565174c071ad9f0161d103d6a322f6d0e1e42be568fa0 +arb_node_interface: ../../../contracts/solc/v0.8.24/INodeInterface/INodeInterface.abi ../../../contracts/solc/v0.8.24/INodeInterface/INodeInterface.bin c72f9e9d1e9b9c371c42817590a490a327e743775f423d9417982914d6136ff7 +arbitrum_gateway_router: ../../../contracts/solc/v0.8.24/IArbitrumGatewayRouter/IArbitrumGatewayRouter.abi ../../../contracts/solc/v0.8.24/IArbitrumGatewayRouter/IArbitrumGatewayRouter.bin d02c8ed0b4bfe50630e0fce452f9aef23d394bd28110314356954185a6544cb8 +arbitrum_inbox: ../../../contracts/solc/v0.8.24/IArbitrumInbox/IArbitrumInbox.abi ../../../contracts/solc/v0.8.24/IArbitrumInbox/IArbitrumInbox.bin 815c2ba12fadd3a6961330d746645dd1920a06253ce9555b46b4c8526065dbaf +arbitrum_l1_bridge_adapter: ../../../contracts/solc/v0.8.24/ArbitrumL1BridgeAdapter/ArbitrumL1BridgeAdapter.abi ../../../contracts/solc/v0.8.24/ArbitrumL1BridgeAdapter/ArbitrumL1BridgeAdapter.bin 1a3719911f8af8652fbf7653ca514a21e7e1acbac4c8bed56f353b8ce69c98d6 +arbitrum_l1_gateway_router: ../../../contracts/solc/v0.8.24/IArbitrumL1GatewayRouter/IArbitrumL1GatewayRouter.abi ../../../contracts/solc/v0.8.24/IArbitrumL1GatewayRouter/IArbitrumL1GatewayRouter.bin 48b098f0667521be7c4a31f2c361a2898536c5ab5406c18c2cedf8c8238909ad +arbitrum_l2_bridge_adapter: ../../../contracts/solc/v0.8.24/ArbitrumL2BridgeAdapter/ArbitrumL2BridgeAdapter.abi ../../../contracts/solc/v0.8.24/ArbitrumL2BridgeAdapter/ArbitrumL2BridgeAdapter.bin c22f2cf6a940dbedf96329a2041d8e396094c172665ace33727bcc0b4aaf9535 +arbitrum_rollup_core: ../../../contracts/solc/v0.8.24/IArbRollupCore/IArbRollupCore.abi ../../../contracts/solc/v0.8.24/IArbRollupCore/IArbRollupCore.bin 18ebdef208265cde0cde8671214840afdffaf57b5d82627d18604727b6210fa6 +arbitrum_token_gateway: ../../../contracts/solc/v0.8.24/IArbitrumTokenGateway/IArbitrumTokenGateway.abi ../../../contracts/solc/v0.8.24/IArbitrumTokenGateway/IArbitrumTokenGateway.bin c3d42c4f174317fe06f96435952ebe7ca8b042c787a61bf3f69060c00c396eae +arbsys: ../../../contracts/solc/v0.8.24/IArbSys/IArbSys.abi ../../../contracts/solc/v0.8.24/IArbSys/IArbSys.bin 70adb49f157d8e077485d1a5c87ddf64b214822aef736bb68e122a77bab78a16 +l2_arbitrum_gateway: ../../../contracts/solc/v0.8.24/IL2ArbitrumGateway/IL2ArbitrumGateway.abi ../../../contracts/solc/v0.8.24/IL2ArbitrumGateway/IL2ArbitrumGateway.bin 4d1af2bdb0aeb0b15e3cbc4ed2158f9bcba4925f68ed3669e0ecfde14115c893 +l2_arbitrum_messenger: ../../../contracts/solc/v0.8.24/IL2ArbitrumMessenger/IL2ArbitrumMessenger.abi ../../../contracts/solc/v0.8.24/IL2ArbitrumMessenger/IL2ArbitrumMessenger.bin 84d4bfedf16e92e3fb15880832fa54a3a21808dffea8a7c0946cde3b5e17a0c3 +liquiditymanager: ../../../contracts/solc/v0.8.24/LiquidityManager/LiquidityManager.abi ../../../contracts/solc/v0.8.24/LiquidityManager/LiquidityManager.bin 6e9aecb13ccf2e92e799e4a2a75c98d58949e34a04e30878f29765f3653993e4 +mock_l1_bridge_adapter: ../../../contracts/solc/v0.8.24/MockBridgeAdapter/MockL1BridgeAdapter.abi ../../../contracts/solc/v0.8.24/MockBridgeAdapter/MockL1BridgeAdapter.bin 538d2e3855031bcb4ef28ab8f0c54c8249e90936a588cde81b965d1dd2d08ad4 +mock_l2_bridge_adapter: ../../../contracts/solc/v0.8.24/MockBridgeAdapter/MockL2BridgeAdapter.abi ../../../contracts/solc/v0.8.24/MockBridgeAdapter/MockL2BridgeAdapter.bin 8ff182e2ac6aac98e1fe85c37d6d92a0b0570de695ed1292127ae25babe96bda +no_op_ocr3: ../../../contracts/solc/v0.8.24/NoOpOCR3/NoOpOCR3.abi ../../../contracts/solc/v0.8.24/NoOpOCR3/NoOpOCR3.bin 8797017885f77efaa7784d3adab29924c95231562baac947949269592c88a441 +optimism_cross_domain_messenger: ../../../contracts/solc/v0.8.24/IOptimismCrossDomainMessenger/IOptimismCrossDomainMessenger.abi ../../../contracts/solc/v0.8.24/IOptimismCrossDomainMessenger/IOptimismCrossDomainMessenger.bin e6d54a344ca1cf29e3b2d320bad4ab4b5aa6c197705d7a65586d4d215d751fca +optimism_dispute_game_factory: ../../../contracts/solc/v0.8.24/IOptimismDisputeGameFactory/IOptimismDisputeGameFactory.abi ../../../contracts/solc/v0.8.24/IOptimismDisputeGameFactory/IOptimismDisputeGameFactory.bin d4bcd96a87fdc6316b3788bd33eb8d96140002f7716b123a03ba4196a5aeeb72 +optimism_l1_bridge_adapter: ../../../contracts/solc/v0.8.24/OptimismL1BridgeAdapter/OptimismL1BridgeAdapter.abi ../../../contracts/solc/v0.8.24/OptimismL1BridgeAdapter/OptimismL1BridgeAdapter.bin f05678747b99fa7bc4255e7c11a44e5e49f51f749a97f5b41ac9badae0592ac1 +optimism_l1_bridge_adapter_encoder: ../../../contracts/solc/v0.8.24/OptimismL1BridgeAdapterEncoder/OptimismL1BridgeAdapterEncoder.abi ../../../contracts/solc/v0.8.24/OptimismL1BridgeAdapterEncoder/OptimismL1BridgeAdapterEncoder.bin 449f12408130b7d0a17aa1da14b5bbae7f22d90307422992ebf26c7fe93b85f2 +optimism_l1_standard_bridge: ../../../contracts/solc/v0.8.24/IOptimismL1StandardBridge/IOptimismL1StandardBridge.abi ../../../contracts/solc/v0.8.24/IOptimismL1StandardBridge/IOptimismL1StandardBridge.bin ba8676c979f072983617d55b51ea3bc482abe06356830da57816c28f5397eb2e +optimism_l2_bridge_adapter: ../../../contracts/solc/v0.8.24/OptimismL2BridgeAdapter/OptimismL2BridgeAdapter.abi ../../../contracts/solc/v0.8.24/OptimismL2BridgeAdapter/OptimismL2BridgeAdapter.bin ac707b967a62f8a70c8d1b1d02d28d1d8474f0511c279f709b68bbb3e08067bd +optimism_l2_output_oracle: ../../../contracts/solc/v0.8.24/IOptimismL2OutputOracle/IOptimismL2OutputOracle.abi ../../../contracts/solc/v0.8.24/IOptimismL2OutputOracle/IOptimismL2OutputOracle.bin c89386866c41c4b31fed4b8b945ba27aa8258ad472968da98a81448a8a95e43c +optimism_l2_to_l1_message_passer: ../../../contracts/solc/v0.8.24/IOptimismL2ToL1MessagePasser/IOptimismL2ToL1MessagePasser.abi ../../../contracts/solc/v0.8.24/IOptimismL2ToL1MessagePasser/IOptimismL2ToL1MessagePasser.bin 51f4568aa734c564a9aa82169f06e974e30650aeccbd07b20b0c8c60d48459fd +optimism_portal: ../../../contracts/solc/v0.8.24/IOptimismPortal/IOptimismPortal.abi ../../../contracts/solc/v0.8.24/IOptimismPortal/IOptimismPortal.bin a644f108c9267f16bcea1648c8935e0e3741484b9b9ba7e87e0c2cb02bd0839f +optimism_portal_2: ../../../contracts/solc/v0.8.24/IOptimismPortal2/IOptimismPortal2.abi ../../../contracts/solc/v0.8.24/IOptimismPortal2/IOptimismPortal2.bin a205fe314abb9056a23ee1ed609e182d012e3809d886c68c96c7b13da9513ab4 +optimism_standard_bridge: ../../../contracts/solc/v0.8.24/IOptimismStandardBridge/IOptimismStandardBridge.abi ../../../contracts/solc/v0.8.24/IOptimismStandardBridge/IOptimismStandardBridge.bin aaa354f8d9a45484aacb896eb148d315ac58587fad0e607adcd468723e653a94 +report_encoder: ../../../contracts/solc/v0.8.24/ReportEncoder/ReportEncoder.abi ../../../contracts/solc/v0.8.24/ReportEncoder/ReportEncoder.bin 43c10d4541b687ce08e754e07ccaa8ac6e5a4f2973d359ece4a56a02b68149d1 diff --git a/core/gethwrappers/liquiditymanager/go_generate.go b/core/gethwrappers/liquiditymanager/go_generate.go new file mode 100644 index 0000000000..93507793bb --- /dev/null +++ b/core/gethwrappers/liquiditymanager/go_generate.go @@ -0,0 +1,37 @@ +// Package gethwrappers_ccip provides tools for wrapping solidity contracts with +// golang packages, using abigen. +package liquiditymanager + +// LiquidityManager contracts +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/LiquidityManager/LiquidityManager.abi ../../../contracts/solc/v0.8.24/LiquidityManager/LiquidityManager.bin LiquidityManager liquiditymanager +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ArbitrumL1BridgeAdapter/ArbitrumL1BridgeAdapter.abi ../../../contracts/solc/v0.8.24/ArbitrumL1BridgeAdapter/ArbitrumL1BridgeAdapter.bin ArbitrumL1BridgeAdapter arbitrum_l1_bridge_adapter +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ArbitrumL2BridgeAdapter/ArbitrumL2BridgeAdapter.abi ../../../contracts/solc/v0.8.24/ArbitrumL2BridgeAdapter/ArbitrumL2BridgeAdapter.bin ArbitrumL2BridgeAdapter arbitrum_l2_bridge_adapter +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/OptimismL1BridgeAdapter/OptimismL1BridgeAdapter.abi ../../../contracts/solc/v0.8.24/OptimismL1BridgeAdapter/OptimismL1BridgeAdapter.bin OptimismL1BridgeAdapter optimism_l1_bridge_adapter +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/OptimismL2BridgeAdapter/OptimismL2BridgeAdapter.abi ../../../contracts/solc/v0.8.24/OptimismL2BridgeAdapter/OptimismL2BridgeAdapter.bin OptimismL2BridgeAdapter optimism_l2_bridge_adapter +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/NoOpOCR3/NoOpOCR3.abi ../../../contracts/solc/v0.8.24/NoOpOCR3/NoOpOCR3.bin NoOpOCR3 no_op_ocr3 +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockBridgeAdapter/MockL2BridgeAdapter.abi ../../../contracts/solc/v0.8.24/MockBridgeAdapter/MockL2BridgeAdapter.bin MockL2BridgeAdapter mock_l2_bridge_adapter +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockBridgeAdapter/MockL1BridgeAdapter.abi ../../../contracts/solc/v0.8.24/MockBridgeAdapter/MockL1BridgeAdapter.bin MockL1BridgeAdapter mock_l1_bridge_adapter +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ReportEncoder/ReportEncoder.abi ../../../contracts/solc/v0.8.24/ReportEncoder/ReportEncoder.bin ReportEncoder report_encoder +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/OptimismL1BridgeAdapterEncoder/OptimismL1BridgeAdapterEncoder.abi ../../../contracts/solc/v0.8.24/OptimismL1BridgeAdapterEncoder/OptimismL1BridgeAdapterEncoder.bin OptimismL1BridgeAdapterEncoder optimism_l1_bridge_adapter_encoder + +// Arbitrum helpers +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IArbSys/IArbSys.abi ../../../contracts/solc/v0.8.24/IArbSys/IArbSys.bin ArbSys arbsys +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/INodeInterface/INodeInterface.abi ../../../contracts/solc/v0.8.24/INodeInterface/INodeInterface.bin NodeInterface arb_node_interface +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IL2ArbitrumGateway/IL2ArbitrumGateway.abi ../../../contracts/solc/v0.8.24/IL2ArbitrumGateway/IL2ArbitrumGateway.bin L2ArbitrumGateway l2_arbitrum_gateway +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IL2ArbitrumMessenger/IL2ArbitrumMessenger.abi ../../../contracts/solc/v0.8.24/IL2ArbitrumMessenger/IL2ArbitrumMessenger.bin L2ArbitrumMessenger l2_arbitrum_messenger +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IArbRollupCore/IArbRollupCore.abi ../../../contracts/solc/v0.8.24/IArbRollupCore/IArbRollupCore.bin ArbRollupCore arbitrum_rollup_core +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IArbitrumL1GatewayRouter/IArbitrumL1GatewayRouter.abi ../../../contracts/solc/v0.8.24/IArbitrumL1GatewayRouter/IArbitrumL1GatewayRouter.bin ArbitrumL1GatewayRouter arbitrum_l1_gateway_router +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IArbitrumInbox/IArbitrumInbox.abi ../../../contracts/solc/v0.8.24/IArbitrumInbox/IArbitrumInbox.bin ArbitrumInbox arbitrum_inbox +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IArbitrumGatewayRouter/IArbitrumGatewayRouter.abi ../../../contracts/solc/v0.8.24/IArbitrumGatewayRouter/IArbitrumGatewayRouter.bin ArbitrumGatewayRouter arbitrum_gateway_router +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IArbitrumTokenGateway/IArbitrumTokenGateway.abi ../../../contracts/solc/v0.8.24/IArbitrumTokenGateway/IArbitrumTokenGateway.bin ArbitrumTokenGateway arbitrum_token_gateway +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IAbstractArbitrumTokenGateway/IAbstractArbitrumTokenGateway.abi ../../../contracts/solc/v0.8.24/IAbstractArbitrumTokenGateway/IAbstractArbitrumTokenGateway.bin AbstractArbitrumTokenGateway abstract_arbitrum_token_gateway + +// Optimism helpers +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IOptimismPortal/IOptimismPortal.abi ../../../contracts/solc/v0.8.24/IOptimismPortal/IOptimismPortal.bin OptimismPortal optimism_portal +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IOptimismL2OutputOracle/IOptimismL2OutputOracle.abi ../../../contracts/solc/v0.8.24/IOptimismL2OutputOracle/IOptimismL2OutputOracle.bin OptimismL2OutputOracle optimism_l2_output_oracle +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IOptimismL2ToL1MessagePasser/IOptimismL2ToL1MessagePasser.abi ../../../contracts/solc/v0.8.24/IOptimismL2ToL1MessagePasser/IOptimismL2ToL1MessagePasser.bin OptimismL2ToL1MessagePasser optimism_l2_to_l1_message_passer +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IOptimismCrossDomainMessenger/IOptimismCrossDomainMessenger.abi ../../../contracts/solc/v0.8.24/IOptimismCrossDomainMessenger/IOptimismCrossDomainMessenger.bin OptimismCrossDomainMessenger optimism_cross_domain_messenger +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IOptimismPortal2/IOptimismPortal2.abi ../../../contracts/solc/v0.8.24/IOptimismPortal2/IOptimismPortal2.bin OptimismPortal2 optimism_portal_2 +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IOptimismDisputeGameFactory/IOptimismDisputeGameFactory.abi ../../../contracts/solc/v0.8.24/IOptimismDisputeGameFactory/IOptimismDisputeGameFactory.bin OptimismDisputeGameFactory optimism_dispute_game_factory +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IOptimismStandardBridge/IOptimismStandardBridge.abi ../../../contracts/solc/v0.8.24/IOptimismStandardBridge/IOptimismStandardBridge.bin OptimismStandardBridge optimism_standard_bridge +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IOptimismL1StandardBridge/IOptimismL1StandardBridge.abi ../../../contracts/solc/v0.8.24/IOptimismL1StandardBridge/IOptimismL1StandardBridge.bin OptimismL1StandardBridge optimism_l1_standard_bridge diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_gateway_router/arbitrum_gateway_router_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_gateway_router/arbitrum_gateway_router_interface.go new file mode 100644 index 0000000000..7503e5357e --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_gateway_router/arbitrum_gateway_router_interface.go @@ -0,0 +1,1054 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_arbitrum_gateway_router + +import ( + big "math/big" + + arbitrum_gateway_router "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_gateway_router" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// ArbitrumGatewayRouterInterface is an autogenerated mock type for the ArbitrumGatewayRouterInterface type +type ArbitrumGatewayRouterInterface struct { + mock.Mock +} + +type ArbitrumGatewayRouterInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *ArbitrumGatewayRouterInterface) EXPECT() *ArbitrumGatewayRouterInterface_Expecter { + return &ArbitrumGatewayRouterInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *ArbitrumGatewayRouterInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// ArbitrumGatewayRouterInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type ArbitrumGatewayRouterInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *ArbitrumGatewayRouterInterface_Expecter) Address() *ArbitrumGatewayRouterInterface_Address_Call { + return &ArbitrumGatewayRouterInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *ArbitrumGatewayRouterInterface_Address_Call) Run(run func()) *ArbitrumGatewayRouterInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_Address_Call) Return(_a0 common.Address) *ArbitrumGatewayRouterInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_Address_Call) RunAndReturn(run func() common.Address) *ArbitrumGatewayRouterInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// CalculateL2TokenAddress provides a mock function with given fields: opts, l1ERC20 +func (_m *ArbitrumGatewayRouterInterface) CalculateL2TokenAddress(opts *bind.CallOpts, l1ERC20 common.Address) (common.Address, error) { + ret := _m.Called(opts, l1ERC20) + + if len(ret) == 0 { + panic("no return value specified for CalculateL2TokenAddress") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (common.Address, error)); ok { + return rf(opts, l1ERC20) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) common.Address); ok { + r0 = rf(opts, l1ERC20) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, l1ERC20) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_CalculateL2TokenAddress_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CalculateL2TokenAddress' +type ArbitrumGatewayRouterInterface_CalculateL2TokenAddress_Call struct { + *mock.Call +} + +// CalculateL2TokenAddress is a helper method to define mock.On call +// - opts *bind.CallOpts +// - l1ERC20 common.Address +func (_e *ArbitrumGatewayRouterInterface_Expecter) CalculateL2TokenAddress(opts interface{}, l1ERC20 interface{}) *ArbitrumGatewayRouterInterface_CalculateL2TokenAddress_Call { + return &ArbitrumGatewayRouterInterface_CalculateL2TokenAddress_Call{Call: _e.mock.On("CalculateL2TokenAddress", opts, l1ERC20)} +} + +func (_c *ArbitrumGatewayRouterInterface_CalculateL2TokenAddress_Call) Run(run func(opts *bind.CallOpts, l1ERC20 common.Address)) *ArbitrumGatewayRouterInterface_CalculateL2TokenAddress_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_CalculateL2TokenAddress_Call) Return(_a0 common.Address, _a1 error) *ArbitrumGatewayRouterInterface_CalculateL2TokenAddress_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_CalculateL2TokenAddress_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (common.Address, error)) *ArbitrumGatewayRouterInterface_CalculateL2TokenAddress_Call { + _c.Call.Return(run) + return _c +} + +// DefaultGateway provides a mock function with given fields: opts +func (_m *ArbitrumGatewayRouterInterface) DefaultGateway(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for DefaultGateway") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_DefaultGateway_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DefaultGateway' +type ArbitrumGatewayRouterInterface_DefaultGateway_Call struct { + *mock.Call +} + +// DefaultGateway is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbitrumGatewayRouterInterface_Expecter) DefaultGateway(opts interface{}) *ArbitrumGatewayRouterInterface_DefaultGateway_Call { + return &ArbitrumGatewayRouterInterface_DefaultGateway_Call{Call: _e.mock.On("DefaultGateway", opts)} +} + +func (_c *ArbitrumGatewayRouterInterface_DefaultGateway_Call) Run(run func(opts *bind.CallOpts)) *ArbitrumGatewayRouterInterface_DefaultGateway_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_DefaultGateway_Call) Return(_a0 common.Address, _a1 error) *ArbitrumGatewayRouterInterface_DefaultGateway_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_DefaultGateway_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *ArbitrumGatewayRouterInterface_DefaultGateway_Call { + _c.Call.Return(run) + return _c +} + +// FilterDefaultGatewayUpdated provides a mock function with given fields: opts +func (_m *ArbitrumGatewayRouterInterface) FilterDefaultGatewayUpdated(opts *bind.FilterOpts) (*arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdatedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterDefaultGatewayUpdated") + } + + var r0 *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdatedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdatedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_FilterDefaultGatewayUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterDefaultGatewayUpdated' +type ArbitrumGatewayRouterInterface_FilterDefaultGatewayUpdated_Call struct { + *mock.Call +} + +// FilterDefaultGatewayUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *ArbitrumGatewayRouterInterface_Expecter) FilterDefaultGatewayUpdated(opts interface{}) *ArbitrumGatewayRouterInterface_FilterDefaultGatewayUpdated_Call { + return &ArbitrumGatewayRouterInterface_FilterDefaultGatewayUpdated_Call{Call: _e.mock.On("FilterDefaultGatewayUpdated", opts)} +} + +func (_c *ArbitrumGatewayRouterInterface_FilterDefaultGatewayUpdated_Call) Run(run func(opts *bind.FilterOpts)) *ArbitrumGatewayRouterInterface_FilterDefaultGatewayUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_FilterDefaultGatewayUpdated_Call) Return(_a0 *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdatedIterator, _a1 error) *ArbitrumGatewayRouterInterface_FilterDefaultGatewayUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_FilterDefaultGatewayUpdated_Call) RunAndReturn(run func(*bind.FilterOpts) (*arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdatedIterator, error)) *ArbitrumGatewayRouterInterface_FilterDefaultGatewayUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FilterGatewaySet provides a mock function with given fields: opts, l1Token, gateway +func (_m *ArbitrumGatewayRouterInterface) FilterGatewaySet(opts *bind.FilterOpts, l1Token []common.Address, gateway []common.Address) (*arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySetIterator, error) { + ret := _m.Called(opts, l1Token, gateway) + + if len(ret) == 0 { + panic("no return value specified for FilterGatewaySet") + } + + var r0 *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySetIterator, error)); ok { + return rf(opts, l1Token, gateway) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySetIterator); ok { + r0 = rf(opts, l1Token, gateway) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, l1Token, gateway) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_FilterGatewaySet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterGatewaySet' +type ArbitrumGatewayRouterInterface_FilterGatewaySet_Call struct { + *mock.Call +} + +// FilterGatewaySet is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - l1Token []common.Address +// - gateway []common.Address +func (_e *ArbitrumGatewayRouterInterface_Expecter) FilterGatewaySet(opts interface{}, l1Token interface{}, gateway interface{}) *ArbitrumGatewayRouterInterface_FilterGatewaySet_Call { + return &ArbitrumGatewayRouterInterface_FilterGatewaySet_Call{Call: _e.mock.On("FilterGatewaySet", opts, l1Token, gateway)} +} + +func (_c *ArbitrumGatewayRouterInterface_FilterGatewaySet_Call) Run(run func(opts *bind.FilterOpts, l1Token []common.Address, gateway []common.Address)) *ArbitrumGatewayRouterInterface_FilterGatewaySet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_FilterGatewaySet_Call) Return(_a0 *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySetIterator, _a1 error) *ArbitrumGatewayRouterInterface_FilterGatewaySet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_FilterGatewaySet_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySetIterator, error)) *ArbitrumGatewayRouterInterface_FilterGatewaySet_Call { + _c.Call.Return(run) + return _c +} + +// FilterTransferRouted provides a mock function with given fields: opts, token, _userFrom, _userTo +func (_m *ArbitrumGatewayRouterInterface) FilterTransferRouted(opts *bind.FilterOpts, token []common.Address, _userFrom []common.Address, _userTo []common.Address) (*arbitrum_gateway_router.ArbitrumGatewayRouterTransferRoutedIterator, error) { + ret := _m.Called(opts, token, _userFrom, _userTo) + + if len(ret) == 0 { + panic("no return value specified for FilterTransferRouted") + } + + var r0 *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRoutedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address, []common.Address) (*arbitrum_gateway_router.ArbitrumGatewayRouterTransferRoutedIterator, error)); ok { + return rf(opts, token, _userFrom, _userTo) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address, []common.Address) *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRoutedIterator); ok { + r0 = rf(opts, token, _userFrom, _userTo) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_gateway_router.ArbitrumGatewayRouterTransferRoutedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address, []common.Address) error); ok { + r1 = rf(opts, token, _userFrom, _userTo) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_FilterTransferRouted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTransferRouted' +type ArbitrumGatewayRouterInterface_FilterTransferRouted_Call struct { + *mock.Call +} + +// FilterTransferRouted is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - token []common.Address +// - _userFrom []common.Address +// - _userTo []common.Address +func (_e *ArbitrumGatewayRouterInterface_Expecter) FilterTransferRouted(opts interface{}, token interface{}, _userFrom interface{}, _userTo interface{}) *ArbitrumGatewayRouterInterface_FilterTransferRouted_Call { + return &ArbitrumGatewayRouterInterface_FilterTransferRouted_Call{Call: _e.mock.On("FilterTransferRouted", opts, token, _userFrom, _userTo)} +} + +func (_c *ArbitrumGatewayRouterInterface_FilterTransferRouted_Call) Run(run func(opts *bind.FilterOpts, token []common.Address, _userFrom []common.Address, _userTo []common.Address)) *ArbitrumGatewayRouterInterface_FilterTransferRouted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_FilterTransferRouted_Call) Return(_a0 *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRoutedIterator, _a1 error) *ArbitrumGatewayRouterInterface_FilterTransferRouted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_FilterTransferRouted_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address, []common.Address) (*arbitrum_gateway_router.ArbitrumGatewayRouterTransferRoutedIterator, error)) *ArbitrumGatewayRouterInterface_FilterTransferRouted_Call { + _c.Call.Return(run) + return _c +} + +// FinalizeInboundTransfer provides a mock function with given fields: opts, _token, _from, _to, _amount, _data +func (_m *ArbitrumGatewayRouterInterface) FinalizeInboundTransfer(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + ret := _m.Called(opts, _token, _from, _to, _amount, _data) + + if len(ret) == 0 { + panic("no return value specified for FinalizeInboundTransfer") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) (*types.Transaction, error)); ok { + return rf(opts, _token, _from, _to, _amount, _data) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) *types.Transaction); ok { + r0 = rf(opts, _token, _from, _to, _amount, _data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) error); ok { + r1 = rf(opts, _token, _from, _to, _amount, _data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_FinalizeInboundTransfer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FinalizeInboundTransfer' +type ArbitrumGatewayRouterInterface_FinalizeInboundTransfer_Call struct { + *mock.Call +} + +// FinalizeInboundTransfer is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _token common.Address +// - _from common.Address +// - _to common.Address +// - _amount *big.Int +// - _data []byte +func (_e *ArbitrumGatewayRouterInterface_Expecter) FinalizeInboundTransfer(opts interface{}, _token interface{}, _from interface{}, _to interface{}, _amount interface{}, _data interface{}) *ArbitrumGatewayRouterInterface_FinalizeInboundTransfer_Call { + return &ArbitrumGatewayRouterInterface_FinalizeInboundTransfer_Call{Call: _e.mock.On("FinalizeInboundTransfer", opts, _token, _from, _to, _amount, _data)} +} + +func (_c *ArbitrumGatewayRouterInterface_FinalizeInboundTransfer_Call) Run(run func(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte)) *ArbitrumGatewayRouterInterface_FinalizeInboundTransfer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(common.Address), args[3].(common.Address), args[4].(*big.Int), args[5].([]byte)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_FinalizeInboundTransfer_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumGatewayRouterInterface_FinalizeInboundTransfer_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_FinalizeInboundTransfer_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) (*types.Transaction, error)) *ArbitrumGatewayRouterInterface_FinalizeInboundTransfer_Call { + _c.Call.Return(run) + return _c +} + +// GetGateway provides a mock function with given fields: opts, _token +func (_m *ArbitrumGatewayRouterInterface) GetGateway(opts *bind.CallOpts, _token common.Address) (common.Address, error) { + ret := _m.Called(opts, _token) + + if len(ret) == 0 { + panic("no return value specified for GetGateway") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (common.Address, error)); ok { + return rf(opts, _token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) common.Address); ok { + r0 = rf(opts, _token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, _token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_GetGateway_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGateway' +type ArbitrumGatewayRouterInterface_GetGateway_Call struct { + *mock.Call +} + +// GetGateway is a helper method to define mock.On call +// - opts *bind.CallOpts +// - _token common.Address +func (_e *ArbitrumGatewayRouterInterface_Expecter) GetGateway(opts interface{}, _token interface{}) *ArbitrumGatewayRouterInterface_GetGateway_Call { + return &ArbitrumGatewayRouterInterface_GetGateway_Call{Call: _e.mock.On("GetGateway", opts, _token)} +} + +func (_c *ArbitrumGatewayRouterInterface_GetGateway_Call) Run(run func(opts *bind.CallOpts, _token common.Address)) *ArbitrumGatewayRouterInterface_GetGateway_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_GetGateway_Call) Return(_a0 common.Address, _a1 error) *ArbitrumGatewayRouterInterface_GetGateway_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_GetGateway_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (common.Address, error)) *ArbitrumGatewayRouterInterface_GetGateway_Call { + _c.Call.Return(run) + return _c +} + +// GetOutboundCalldata provides a mock function with given fields: opts, _token, _from, _to, _amount, _data +func (_m *ArbitrumGatewayRouterInterface) GetOutboundCalldata(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + ret := _m.Called(opts, _token, _from, _to, _amount, _data) + + if len(ret) == 0 { + panic("no return value specified for GetOutboundCalldata") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, common.Address, common.Address, *big.Int, []byte) ([]byte, error)); ok { + return rf(opts, _token, _from, _to, _amount, _data) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, common.Address, common.Address, *big.Int, []byte) []byte); ok { + r0 = rf(opts, _token, _from, _to, _amount, _data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address, common.Address, common.Address, *big.Int, []byte) error); ok { + r1 = rf(opts, _token, _from, _to, _amount, _data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_GetOutboundCalldata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetOutboundCalldata' +type ArbitrumGatewayRouterInterface_GetOutboundCalldata_Call struct { + *mock.Call +} + +// GetOutboundCalldata is a helper method to define mock.On call +// - opts *bind.CallOpts +// - _token common.Address +// - _from common.Address +// - _to common.Address +// - _amount *big.Int +// - _data []byte +func (_e *ArbitrumGatewayRouterInterface_Expecter) GetOutboundCalldata(opts interface{}, _token interface{}, _from interface{}, _to interface{}, _amount interface{}, _data interface{}) *ArbitrumGatewayRouterInterface_GetOutboundCalldata_Call { + return &ArbitrumGatewayRouterInterface_GetOutboundCalldata_Call{Call: _e.mock.On("GetOutboundCalldata", opts, _token, _from, _to, _amount, _data)} +} + +func (_c *ArbitrumGatewayRouterInterface_GetOutboundCalldata_Call) Run(run func(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte)) *ArbitrumGatewayRouterInterface_GetOutboundCalldata_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address), args[2].(common.Address), args[3].(common.Address), args[4].(*big.Int), args[5].([]byte)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_GetOutboundCalldata_Call) Return(_a0 []byte, _a1 error) *ArbitrumGatewayRouterInterface_GetOutboundCalldata_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_GetOutboundCalldata_Call) RunAndReturn(run func(*bind.CallOpts, common.Address, common.Address, common.Address, *big.Int, []byte) ([]byte, error)) *ArbitrumGatewayRouterInterface_GetOutboundCalldata_Call { + _c.Call.Return(run) + return _c +} + +// OutboundTransfer provides a mock function with given fields: opts, _token, _to, _amount, _maxGas, _gasPriceBid, _data +func (_m *ArbitrumGatewayRouterInterface) OutboundTransfer(opts *bind.TransactOpts, _token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte) (*types.Transaction, error) { + ret := _m.Called(opts, _token, _to, _amount, _maxGas, _gasPriceBid, _data) + + if len(ret) == 0 { + panic("no return value specified for OutboundTransfer") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, *big.Int, *big.Int, *big.Int, []byte) (*types.Transaction, error)); ok { + return rf(opts, _token, _to, _amount, _maxGas, _gasPriceBid, _data) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, *big.Int, *big.Int, *big.Int, []byte) *types.Transaction); ok { + r0 = rf(opts, _token, _to, _amount, _maxGas, _gasPriceBid, _data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, common.Address, *big.Int, *big.Int, *big.Int, []byte) error); ok { + r1 = rf(opts, _token, _to, _amount, _maxGas, _gasPriceBid, _data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_OutboundTransfer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OutboundTransfer' +type ArbitrumGatewayRouterInterface_OutboundTransfer_Call struct { + *mock.Call +} + +// OutboundTransfer is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _token common.Address +// - _to common.Address +// - _amount *big.Int +// - _maxGas *big.Int +// - _gasPriceBid *big.Int +// - _data []byte +func (_e *ArbitrumGatewayRouterInterface_Expecter) OutboundTransfer(opts interface{}, _token interface{}, _to interface{}, _amount interface{}, _maxGas interface{}, _gasPriceBid interface{}, _data interface{}) *ArbitrumGatewayRouterInterface_OutboundTransfer_Call { + return &ArbitrumGatewayRouterInterface_OutboundTransfer_Call{Call: _e.mock.On("OutboundTransfer", opts, _token, _to, _amount, _maxGas, _gasPriceBid, _data)} +} + +func (_c *ArbitrumGatewayRouterInterface_OutboundTransfer_Call) Run(run func(opts *bind.TransactOpts, _token common.Address, _to common.Address, _amount *big.Int, _maxGas *big.Int, _gasPriceBid *big.Int, _data []byte)) *ArbitrumGatewayRouterInterface_OutboundTransfer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(common.Address), args[3].(*big.Int), args[4].(*big.Int), args[5].(*big.Int), args[6].([]byte)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_OutboundTransfer_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumGatewayRouterInterface_OutboundTransfer_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_OutboundTransfer_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, common.Address, *big.Int, *big.Int, *big.Int, []byte) (*types.Transaction, error)) *ArbitrumGatewayRouterInterface_OutboundTransfer_Call { + _c.Call.Return(run) + return _c +} + +// ParseDefaultGatewayUpdated provides a mock function with given fields: log +func (_m *ArbitrumGatewayRouterInterface) ParseDefaultGatewayUpdated(log types.Log) (*arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseDefaultGatewayUpdated") + } + + var r0 *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_ParseDefaultGatewayUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseDefaultGatewayUpdated' +type ArbitrumGatewayRouterInterface_ParseDefaultGatewayUpdated_Call struct { + *mock.Call +} + +// ParseDefaultGatewayUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *ArbitrumGatewayRouterInterface_Expecter) ParseDefaultGatewayUpdated(log interface{}) *ArbitrumGatewayRouterInterface_ParseDefaultGatewayUpdated_Call { + return &ArbitrumGatewayRouterInterface_ParseDefaultGatewayUpdated_Call{Call: _e.mock.On("ParseDefaultGatewayUpdated", log)} +} + +func (_c *ArbitrumGatewayRouterInterface_ParseDefaultGatewayUpdated_Call) Run(run func(log types.Log)) *ArbitrumGatewayRouterInterface_ParseDefaultGatewayUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_ParseDefaultGatewayUpdated_Call) Return(_a0 *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated, _a1 error) *ArbitrumGatewayRouterInterface_ParseDefaultGatewayUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_ParseDefaultGatewayUpdated_Call) RunAndReturn(run func(types.Log) (*arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated, error)) *ArbitrumGatewayRouterInterface_ParseDefaultGatewayUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ParseGatewaySet provides a mock function with given fields: log +func (_m *ArbitrumGatewayRouterInterface) ParseGatewaySet(log types.Log) (*arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseGatewaySet") + } + + var r0 *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_ParseGatewaySet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseGatewaySet' +type ArbitrumGatewayRouterInterface_ParseGatewaySet_Call struct { + *mock.Call +} + +// ParseGatewaySet is a helper method to define mock.On call +// - log types.Log +func (_e *ArbitrumGatewayRouterInterface_Expecter) ParseGatewaySet(log interface{}) *ArbitrumGatewayRouterInterface_ParseGatewaySet_Call { + return &ArbitrumGatewayRouterInterface_ParseGatewaySet_Call{Call: _e.mock.On("ParseGatewaySet", log)} +} + +func (_c *ArbitrumGatewayRouterInterface_ParseGatewaySet_Call) Run(run func(log types.Log)) *ArbitrumGatewayRouterInterface_ParseGatewaySet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_ParseGatewaySet_Call) Return(_a0 *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet, _a1 error) *ArbitrumGatewayRouterInterface_ParseGatewaySet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_ParseGatewaySet_Call) RunAndReturn(run func(types.Log) (*arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet, error)) *ArbitrumGatewayRouterInterface_ParseGatewaySet_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *ArbitrumGatewayRouterInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type ArbitrumGatewayRouterInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *ArbitrumGatewayRouterInterface_Expecter) ParseLog(log interface{}) *ArbitrumGatewayRouterInterface_ParseLog_Call { + return &ArbitrumGatewayRouterInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *ArbitrumGatewayRouterInterface_ParseLog_Call) Run(run func(log types.Log)) *ArbitrumGatewayRouterInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *ArbitrumGatewayRouterInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *ArbitrumGatewayRouterInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseTransferRouted provides a mock function with given fields: log +func (_m *ArbitrumGatewayRouterInterface) ParseTransferRouted(log types.Log) (*arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTransferRouted") + } + + var r0 *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_ParseTransferRouted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTransferRouted' +type ArbitrumGatewayRouterInterface_ParseTransferRouted_Call struct { + *mock.Call +} + +// ParseTransferRouted is a helper method to define mock.On call +// - log types.Log +func (_e *ArbitrumGatewayRouterInterface_Expecter) ParseTransferRouted(log interface{}) *ArbitrumGatewayRouterInterface_ParseTransferRouted_Call { + return &ArbitrumGatewayRouterInterface_ParseTransferRouted_Call{Call: _e.mock.On("ParseTransferRouted", log)} +} + +func (_c *ArbitrumGatewayRouterInterface_ParseTransferRouted_Call) Run(run func(log types.Log)) *ArbitrumGatewayRouterInterface_ParseTransferRouted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_ParseTransferRouted_Call) Return(_a0 *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted, _a1 error) *ArbitrumGatewayRouterInterface_ParseTransferRouted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_ParseTransferRouted_Call) RunAndReturn(run func(types.Log) (*arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted, error)) *ArbitrumGatewayRouterInterface_ParseTransferRouted_Call { + _c.Call.Return(run) + return _c +} + +// WatchDefaultGatewayUpdated provides a mock function with given fields: opts, sink +func (_m *ArbitrumGatewayRouterInterface) WatchDefaultGatewayUpdated(opts *bind.WatchOpts, sink chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchDefaultGatewayUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_WatchDefaultGatewayUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchDefaultGatewayUpdated' +type ArbitrumGatewayRouterInterface_WatchDefaultGatewayUpdated_Call struct { + *mock.Call +} + +// WatchDefaultGatewayUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated +func (_e *ArbitrumGatewayRouterInterface_Expecter) WatchDefaultGatewayUpdated(opts interface{}, sink interface{}) *ArbitrumGatewayRouterInterface_WatchDefaultGatewayUpdated_Call { + return &ArbitrumGatewayRouterInterface_WatchDefaultGatewayUpdated_Call{Call: _e.mock.On("WatchDefaultGatewayUpdated", opts, sink)} +} + +func (_c *ArbitrumGatewayRouterInterface_WatchDefaultGatewayUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated)) *ArbitrumGatewayRouterInterface_WatchDefaultGatewayUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_WatchDefaultGatewayUpdated_Call) Return(_a0 event.Subscription, _a1 error) *ArbitrumGatewayRouterInterface_WatchDefaultGatewayUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_WatchDefaultGatewayUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterDefaultGatewayUpdated) (event.Subscription, error)) *ArbitrumGatewayRouterInterface_WatchDefaultGatewayUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WatchGatewaySet provides a mock function with given fields: opts, sink, l1Token, gateway +func (_m *ArbitrumGatewayRouterInterface) WatchGatewaySet(opts *bind.WatchOpts, sink chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet, l1Token []common.Address, gateway []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, l1Token, gateway) + + if len(ret) == 0 { + panic("no return value specified for WatchGatewaySet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, l1Token, gateway) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, l1Token, gateway) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, l1Token, gateway) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_WatchGatewaySet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchGatewaySet' +type ArbitrumGatewayRouterInterface_WatchGatewaySet_Call struct { + *mock.Call +} + +// WatchGatewaySet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet +// - l1Token []common.Address +// - gateway []common.Address +func (_e *ArbitrumGatewayRouterInterface_Expecter) WatchGatewaySet(opts interface{}, sink interface{}, l1Token interface{}, gateway interface{}) *ArbitrumGatewayRouterInterface_WatchGatewaySet_Call { + return &ArbitrumGatewayRouterInterface_WatchGatewaySet_Call{Call: _e.mock.On("WatchGatewaySet", opts, sink, l1Token, gateway)} +} + +func (_c *ArbitrumGatewayRouterInterface_WatchGatewaySet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet, l1Token []common.Address, gateway []common.Address)) *ArbitrumGatewayRouterInterface_WatchGatewaySet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_WatchGatewaySet_Call) Return(_a0 event.Subscription, _a1 error) *ArbitrumGatewayRouterInterface_WatchGatewaySet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_WatchGatewaySet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterGatewaySet, []common.Address, []common.Address) (event.Subscription, error)) *ArbitrumGatewayRouterInterface_WatchGatewaySet_Call { + _c.Call.Return(run) + return _c +} + +// WatchTransferRouted provides a mock function with given fields: opts, sink, token, _userFrom, _userTo +func (_m *ArbitrumGatewayRouterInterface) WatchTransferRouted(opts *bind.WatchOpts, sink chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted, token []common.Address, _userFrom []common.Address, _userTo []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, token, _userFrom, _userTo) + + if len(ret) == 0 { + panic("no return value specified for WatchTransferRouted") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted, []common.Address, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, token, _userFrom, _userTo) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted, []common.Address, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, token, _userFrom, _userTo) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted, []common.Address, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, token, _userFrom, _userTo) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumGatewayRouterInterface_WatchTransferRouted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTransferRouted' +type ArbitrumGatewayRouterInterface_WatchTransferRouted_Call struct { + *mock.Call +} + +// WatchTransferRouted is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted +// - token []common.Address +// - _userFrom []common.Address +// - _userTo []common.Address +func (_e *ArbitrumGatewayRouterInterface_Expecter) WatchTransferRouted(opts interface{}, sink interface{}, token interface{}, _userFrom interface{}, _userTo interface{}) *ArbitrumGatewayRouterInterface_WatchTransferRouted_Call { + return &ArbitrumGatewayRouterInterface_WatchTransferRouted_Call{Call: _e.mock.On("WatchTransferRouted", opts, sink, token, _userFrom, _userTo)} +} + +func (_c *ArbitrumGatewayRouterInterface_WatchTransferRouted_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted, token []common.Address, _userFrom []common.Address, _userTo []common.Address)) *ArbitrumGatewayRouterInterface_WatchTransferRouted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted), args[2].([]common.Address), args[3].([]common.Address), args[4].([]common.Address)) + }) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_WatchTransferRouted_Call) Return(_a0 event.Subscription, _a1 error) *ArbitrumGatewayRouterInterface_WatchTransferRouted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumGatewayRouterInterface_WatchTransferRouted_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbitrum_gateway_router.ArbitrumGatewayRouterTransferRouted, []common.Address, []common.Address, []common.Address) (event.Subscription, error)) *ArbitrumGatewayRouterInterface_WatchTransferRouted_Call { + _c.Call.Return(run) + return _c +} + +// NewArbitrumGatewayRouterInterface creates a new instance of ArbitrumGatewayRouterInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewArbitrumGatewayRouterInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *ArbitrumGatewayRouterInterface { + mock := &ArbitrumGatewayRouterInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_inbox/arbitrum_inbox_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_inbox/arbitrum_inbox_interface.go new file mode 100644 index 0000000000..ca259c0621 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_inbox/arbitrum_inbox_interface.go @@ -0,0 +1,1452 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_arbitrum_inbox + +import ( + big "math/big" + + arbitrum_inbox "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_inbox" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// ArbitrumInboxInterface is an autogenerated mock type for the ArbitrumInboxInterface type +type ArbitrumInboxInterface struct { + mock.Mock +} + +type ArbitrumInboxInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *ArbitrumInboxInterface) EXPECT() *ArbitrumInboxInterface_Expecter { + return &ArbitrumInboxInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *ArbitrumInboxInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// ArbitrumInboxInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type ArbitrumInboxInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *ArbitrumInboxInterface_Expecter) Address() *ArbitrumInboxInterface_Address_Call { + return &ArbitrumInboxInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *ArbitrumInboxInterface_Address_Call) Run(run func()) *ArbitrumInboxInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ArbitrumInboxInterface_Address_Call) Return(_a0 common.Address) *ArbitrumInboxInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ArbitrumInboxInterface_Address_Call) RunAndReturn(run func() common.Address) *ArbitrumInboxInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// AllowListEnabled provides a mock function with given fields: opts +func (_m *ArbitrumInboxInterface) AllowListEnabled(opts *bind.CallOpts) (bool, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for AllowListEnabled") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (bool, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) bool); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_AllowListEnabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AllowListEnabled' +type ArbitrumInboxInterface_AllowListEnabled_Call struct { + *mock.Call +} + +// AllowListEnabled is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbitrumInboxInterface_Expecter) AllowListEnabled(opts interface{}) *ArbitrumInboxInterface_AllowListEnabled_Call { + return &ArbitrumInboxInterface_AllowListEnabled_Call{Call: _e.mock.On("AllowListEnabled", opts)} +} + +func (_c *ArbitrumInboxInterface_AllowListEnabled_Call) Run(run func(opts *bind.CallOpts)) *ArbitrumInboxInterface_AllowListEnabled_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_AllowListEnabled_Call) Return(_a0 bool, _a1 error) *ArbitrumInboxInterface_AllowListEnabled_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_AllowListEnabled_Call) RunAndReturn(run func(*bind.CallOpts) (bool, error)) *ArbitrumInboxInterface_AllowListEnabled_Call { + _c.Call.Return(run) + return _c +} + +// Bridge provides a mock function with given fields: opts +func (_m *ArbitrumInboxInterface) Bridge(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Bridge") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_Bridge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bridge' +type ArbitrumInboxInterface_Bridge_Call struct { + *mock.Call +} + +// Bridge is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbitrumInboxInterface_Expecter) Bridge(opts interface{}) *ArbitrumInboxInterface_Bridge_Call { + return &ArbitrumInboxInterface_Bridge_Call{Call: _e.mock.On("Bridge", opts)} +} + +func (_c *ArbitrumInboxInterface_Bridge_Call) Run(run func(opts *bind.CallOpts)) *ArbitrumInboxInterface_Bridge_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_Bridge_Call) Return(_a0 common.Address, _a1 error) *ArbitrumInboxInterface_Bridge_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_Bridge_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *ArbitrumInboxInterface_Bridge_Call { + _c.Call.Return(run) + return _c +} + +// CalculateRetryableSubmissionFee provides a mock function with given fields: opts, dataLength, baseFee +func (_m *ArbitrumInboxInterface) CalculateRetryableSubmissionFee(opts *bind.CallOpts, dataLength *big.Int, baseFee *big.Int) (*big.Int, error) { + ret := _m.Called(opts, dataLength, baseFee) + + if len(ret) == 0 { + panic("no return value specified for CalculateRetryableSubmissionFee") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int, *big.Int) (*big.Int, error)); ok { + return rf(opts, dataLength, baseFee) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int, *big.Int) *big.Int); ok { + r0 = rf(opts, dataLength, baseFee) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, *big.Int, *big.Int) error); ok { + r1 = rf(opts, dataLength, baseFee) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_CalculateRetryableSubmissionFee_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CalculateRetryableSubmissionFee' +type ArbitrumInboxInterface_CalculateRetryableSubmissionFee_Call struct { + *mock.Call +} + +// CalculateRetryableSubmissionFee is a helper method to define mock.On call +// - opts *bind.CallOpts +// - dataLength *big.Int +// - baseFee *big.Int +func (_e *ArbitrumInboxInterface_Expecter) CalculateRetryableSubmissionFee(opts interface{}, dataLength interface{}, baseFee interface{}) *ArbitrumInboxInterface_CalculateRetryableSubmissionFee_Call { + return &ArbitrumInboxInterface_CalculateRetryableSubmissionFee_Call{Call: _e.mock.On("CalculateRetryableSubmissionFee", opts, dataLength, baseFee)} +} + +func (_c *ArbitrumInboxInterface_CalculateRetryableSubmissionFee_Call) Run(run func(opts *bind.CallOpts, dataLength *big.Int, baseFee *big.Int)) *ArbitrumInboxInterface_CalculateRetryableSubmissionFee_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(*big.Int), args[2].(*big.Int)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_CalculateRetryableSubmissionFee_Call) Return(_a0 *big.Int, _a1 error) *ArbitrumInboxInterface_CalculateRetryableSubmissionFee_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_CalculateRetryableSubmissionFee_Call) RunAndReturn(run func(*bind.CallOpts, *big.Int, *big.Int) (*big.Int, error)) *ArbitrumInboxInterface_CalculateRetryableSubmissionFee_Call { + _c.Call.Return(run) + return _c +} + +// FilterInboxMessageDelivered provides a mock function with given fields: opts, messageNum +func (_m *ArbitrumInboxInterface) FilterInboxMessageDelivered(opts *bind.FilterOpts, messageNum []*big.Int) (*arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredIterator, error) { + ret := _m.Called(opts, messageNum) + + if len(ret) == 0 { + panic("no return value specified for FilterInboxMessageDelivered") + } + + var r0 *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []*big.Int) (*arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredIterator, error)); ok { + return rf(opts, messageNum) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []*big.Int) *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredIterator); ok { + r0 = rf(opts, messageNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []*big.Int) error); ok { + r1 = rf(opts, messageNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_FilterInboxMessageDelivered_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterInboxMessageDelivered' +type ArbitrumInboxInterface_FilterInboxMessageDelivered_Call struct { + *mock.Call +} + +// FilterInboxMessageDelivered is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - messageNum []*big.Int +func (_e *ArbitrumInboxInterface_Expecter) FilterInboxMessageDelivered(opts interface{}, messageNum interface{}) *ArbitrumInboxInterface_FilterInboxMessageDelivered_Call { + return &ArbitrumInboxInterface_FilterInboxMessageDelivered_Call{Call: _e.mock.On("FilterInboxMessageDelivered", opts, messageNum)} +} + +func (_c *ArbitrumInboxInterface_FilterInboxMessageDelivered_Call) Run(run func(opts *bind.FilterOpts, messageNum []*big.Int)) *ArbitrumInboxInterface_FilterInboxMessageDelivered_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]*big.Int)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_FilterInboxMessageDelivered_Call) Return(_a0 *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredIterator, _a1 error) *ArbitrumInboxInterface_FilterInboxMessageDelivered_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_FilterInboxMessageDelivered_Call) RunAndReturn(run func(*bind.FilterOpts, []*big.Int) (*arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredIterator, error)) *ArbitrumInboxInterface_FilterInboxMessageDelivered_Call { + _c.Call.Return(run) + return _c +} + +// FilterInboxMessageDeliveredFromOrigin provides a mock function with given fields: opts, messageNum +func (_m *ArbitrumInboxInterface) FilterInboxMessageDeliveredFromOrigin(opts *bind.FilterOpts, messageNum []*big.Int) (*arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOriginIterator, error) { + ret := _m.Called(opts, messageNum) + + if len(ret) == 0 { + panic("no return value specified for FilterInboxMessageDeliveredFromOrigin") + } + + var r0 *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOriginIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []*big.Int) (*arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOriginIterator, error)); ok { + return rf(opts, messageNum) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []*big.Int) *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOriginIterator); ok { + r0 = rf(opts, messageNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOriginIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []*big.Int) error); ok { + r1 = rf(opts, messageNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_FilterInboxMessageDeliveredFromOrigin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterInboxMessageDeliveredFromOrigin' +type ArbitrumInboxInterface_FilterInboxMessageDeliveredFromOrigin_Call struct { + *mock.Call +} + +// FilterInboxMessageDeliveredFromOrigin is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - messageNum []*big.Int +func (_e *ArbitrumInboxInterface_Expecter) FilterInboxMessageDeliveredFromOrigin(opts interface{}, messageNum interface{}) *ArbitrumInboxInterface_FilterInboxMessageDeliveredFromOrigin_Call { + return &ArbitrumInboxInterface_FilterInboxMessageDeliveredFromOrigin_Call{Call: _e.mock.On("FilterInboxMessageDeliveredFromOrigin", opts, messageNum)} +} + +func (_c *ArbitrumInboxInterface_FilterInboxMessageDeliveredFromOrigin_Call) Run(run func(opts *bind.FilterOpts, messageNum []*big.Int)) *ArbitrumInboxInterface_FilterInboxMessageDeliveredFromOrigin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]*big.Int)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_FilterInboxMessageDeliveredFromOrigin_Call) Return(_a0 *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOriginIterator, _a1 error) *ArbitrumInboxInterface_FilterInboxMessageDeliveredFromOrigin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_FilterInboxMessageDeliveredFromOrigin_Call) RunAndReturn(run func(*bind.FilterOpts, []*big.Int) (*arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOriginIterator, error)) *ArbitrumInboxInterface_FilterInboxMessageDeliveredFromOrigin_Call { + _c.Call.Return(run) + return _c +} + +// GetProxyAdmin provides a mock function with given fields: opts +func (_m *ArbitrumInboxInterface) GetProxyAdmin(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetProxyAdmin") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_GetProxyAdmin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetProxyAdmin' +type ArbitrumInboxInterface_GetProxyAdmin_Call struct { + *mock.Call +} + +// GetProxyAdmin is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbitrumInboxInterface_Expecter) GetProxyAdmin(opts interface{}) *ArbitrumInboxInterface_GetProxyAdmin_Call { + return &ArbitrumInboxInterface_GetProxyAdmin_Call{Call: _e.mock.On("GetProxyAdmin", opts)} +} + +func (_c *ArbitrumInboxInterface_GetProxyAdmin_Call) Run(run func(opts *bind.CallOpts)) *ArbitrumInboxInterface_GetProxyAdmin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_GetProxyAdmin_Call) Return(_a0 common.Address, _a1 error) *ArbitrumInboxInterface_GetProxyAdmin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_GetProxyAdmin_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *ArbitrumInboxInterface_GetProxyAdmin_Call { + _c.Call.Return(run) + return _c +} + +// Initialize provides a mock function with given fields: opts, _bridge, _sequencerInbox +func (_m *ArbitrumInboxInterface) Initialize(opts *bind.TransactOpts, _bridge common.Address, _sequencerInbox common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, _bridge, _sequencerInbox) + + if len(ret) == 0 { + panic("no return value specified for Initialize") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address) (*types.Transaction, error)); ok { + return rf(opts, _bridge, _sequencerInbox) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address) *types.Transaction); ok { + r0 = rf(opts, _bridge, _sequencerInbox) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, common.Address) error); ok { + r1 = rf(opts, _bridge, _sequencerInbox) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_Initialize_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Initialize' +type ArbitrumInboxInterface_Initialize_Call struct { + *mock.Call +} + +// Initialize is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _bridge common.Address +// - _sequencerInbox common.Address +func (_e *ArbitrumInboxInterface_Expecter) Initialize(opts interface{}, _bridge interface{}, _sequencerInbox interface{}) *ArbitrumInboxInterface_Initialize_Call { + return &ArbitrumInboxInterface_Initialize_Call{Call: _e.mock.On("Initialize", opts, _bridge, _sequencerInbox)} +} + +func (_c *ArbitrumInboxInterface_Initialize_Call) Run(run func(opts *bind.TransactOpts, _bridge common.Address, _sequencerInbox common.Address)) *ArbitrumInboxInterface_Initialize_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(common.Address)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_Initialize_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumInboxInterface_Initialize_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_Initialize_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, common.Address) (*types.Transaction, error)) *ArbitrumInboxInterface_Initialize_Call { + _c.Call.Return(run) + return _c +} + +// IsAllowed provides a mock function with given fields: opts, user +func (_m *ArbitrumInboxInterface) IsAllowed(opts *bind.CallOpts, user common.Address) (bool, error) { + ret := _m.Called(opts, user) + + if len(ret) == 0 { + panic("no return value specified for IsAllowed") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (bool, error)); ok { + return rf(opts, user) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) bool); ok { + r0 = rf(opts, user) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, user) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_IsAllowed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsAllowed' +type ArbitrumInboxInterface_IsAllowed_Call struct { + *mock.Call +} + +// IsAllowed is a helper method to define mock.On call +// - opts *bind.CallOpts +// - user common.Address +func (_e *ArbitrumInboxInterface_Expecter) IsAllowed(opts interface{}, user interface{}) *ArbitrumInboxInterface_IsAllowed_Call { + return &ArbitrumInboxInterface_IsAllowed_Call{Call: _e.mock.On("IsAllowed", opts, user)} +} + +func (_c *ArbitrumInboxInterface_IsAllowed_Call) Run(run func(opts *bind.CallOpts, user common.Address)) *ArbitrumInboxInterface_IsAllowed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_IsAllowed_Call) Return(_a0 bool, _a1 error) *ArbitrumInboxInterface_IsAllowed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_IsAllowed_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (bool, error)) *ArbitrumInboxInterface_IsAllowed_Call { + _c.Call.Return(run) + return _c +} + +// MaxDataSize provides a mock function with given fields: opts +func (_m *ArbitrumInboxInterface) MaxDataSize(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for MaxDataSize") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_MaxDataSize_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MaxDataSize' +type ArbitrumInboxInterface_MaxDataSize_Call struct { + *mock.Call +} + +// MaxDataSize is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbitrumInboxInterface_Expecter) MaxDataSize(opts interface{}) *ArbitrumInboxInterface_MaxDataSize_Call { + return &ArbitrumInboxInterface_MaxDataSize_Call{Call: _e.mock.On("MaxDataSize", opts)} +} + +func (_c *ArbitrumInboxInterface_MaxDataSize_Call) Run(run func(opts *bind.CallOpts)) *ArbitrumInboxInterface_MaxDataSize_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_MaxDataSize_Call) Return(_a0 *big.Int, _a1 error) *ArbitrumInboxInterface_MaxDataSize_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_MaxDataSize_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *ArbitrumInboxInterface_MaxDataSize_Call { + _c.Call.Return(run) + return _c +} + +// ParseInboxMessageDelivered provides a mock function with given fields: log +func (_m *ArbitrumInboxInterface) ParseInboxMessageDelivered(log types.Log) (*arbitrum_inbox.ArbitrumInboxInboxMessageDelivered, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseInboxMessageDelivered") + } + + var r0 *arbitrum_inbox.ArbitrumInboxInboxMessageDelivered + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbitrum_inbox.ArbitrumInboxInboxMessageDelivered, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbitrum_inbox.ArbitrumInboxInboxMessageDelivered); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_inbox.ArbitrumInboxInboxMessageDelivered) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_ParseInboxMessageDelivered_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseInboxMessageDelivered' +type ArbitrumInboxInterface_ParseInboxMessageDelivered_Call struct { + *mock.Call +} + +// ParseInboxMessageDelivered is a helper method to define mock.On call +// - log types.Log +func (_e *ArbitrumInboxInterface_Expecter) ParseInboxMessageDelivered(log interface{}) *ArbitrumInboxInterface_ParseInboxMessageDelivered_Call { + return &ArbitrumInboxInterface_ParseInboxMessageDelivered_Call{Call: _e.mock.On("ParseInboxMessageDelivered", log)} +} + +func (_c *ArbitrumInboxInterface_ParseInboxMessageDelivered_Call) Run(run func(log types.Log)) *ArbitrumInboxInterface_ParseInboxMessageDelivered_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_ParseInboxMessageDelivered_Call) Return(_a0 *arbitrum_inbox.ArbitrumInboxInboxMessageDelivered, _a1 error) *ArbitrumInboxInterface_ParseInboxMessageDelivered_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_ParseInboxMessageDelivered_Call) RunAndReturn(run func(types.Log) (*arbitrum_inbox.ArbitrumInboxInboxMessageDelivered, error)) *ArbitrumInboxInterface_ParseInboxMessageDelivered_Call { + _c.Call.Return(run) + return _c +} + +// ParseInboxMessageDeliveredFromOrigin provides a mock function with given fields: log +func (_m *ArbitrumInboxInterface) ParseInboxMessageDeliveredFromOrigin(log types.Log) (*arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseInboxMessageDeliveredFromOrigin") + } + + var r0 *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_ParseInboxMessageDeliveredFromOrigin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseInboxMessageDeliveredFromOrigin' +type ArbitrumInboxInterface_ParseInboxMessageDeliveredFromOrigin_Call struct { + *mock.Call +} + +// ParseInboxMessageDeliveredFromOrigin is a helper method to define mock.On call +// - log types.Log +func (_e *ArbitrumInboxInterface_Expecter) ParseInboxMessageDeliveredFromOrigin(log interface{}) *ArbitrumInboxInterface_ParseInboxMessageDeliveredFromOrigin_Call { + return &ArbitrumInboxInterface_ParseInboxMessageDeliveredFromOrigin_Call{Call: _e.mock.On("ParseInboxMessageDeliveredFromOrigin", log)} +} + +func (_c *ArbitrumInboxInterface_ParseInboxMessageDeliveredFromOrigin_Call) Run(run func(log types.Log)) *ArbitrumInboxInterface_ParseInboxMessageDeliveredFromOrigin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_ParseInboxMessageDeliveredFromOrigin_Call) Return(_a0 *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin, _a1 error) *ArbitrumInboxInterface_ParseInboxMessageDeliveredFromOrigin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_ParseInboxMessageDeliveredFromOrigin_Call) RunAndReturn(run func(types.Log) (*arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin, error)) *ArbitrumInboxInterface_ParseInboxMessageDeliveredFromOrigin_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *ArbitrumInboxInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type ArbitrumInboxInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *ArbitrumInboxInterface_Expecter) ParseLog(log interface{}) *ArbitrumInboxInterface_ParseLog_Call { + return &ArbitrumInboxInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *ArbitrumInboxInterface_ParseLog_Call) Run(run func(log types.Log)) *ArbitrumInboxInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *ArbitrumInboxInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *ArbitrumInboxInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// Pause provides a mock function with given fields: opts +func (_m *ArbitrumInboxInterface) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Pause") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_Pause_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Pause' +type ArbitrumInboxInterface_Pause_Call struct { + *mock.Call +} + +// Pause is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *ArbitrumInboxInterface_Expecter) Pause(opts interface{}) *ArbitrumInboxInterface_Pause_Call { + return &ArbitrumInboxInterface_Pause_Call{Call: _e.mock.On("Pause", opts)} +} + +func (_c *ArbitrumInboxInterface_Pause_Call) Run(run func(opts *bind.TransactOpts)) *ArbitrumInboxInterface_Pause_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_Pause_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumInboxInterface_Pause_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_Pause_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *ArbitrumInboxInterface_Pause_Call { + _c.Call.Return(run) + return _c +} + +// SendContractTransaction provides a mock function with given fields: opts, gasLimit, maxFeePerGas, to, value, data +func (_m *ArbitrumInboxInterface) SendContractTransaction(opts *bind.TransactOpts, gasLimit *big.Int, maxFeePerGas *big.Int, to common.Address, value *big.Int, data []byte) (*types.Transaction, error) { + ret := _m.Called(opts, gasLimit, maxFeePerGas, to, value, data) + + if len(ret) == 0 { + panic("no return value specified for SendContractTransaction") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, *big.Int, *big.Int, common.Address, *big.Int, []byte) (*types.Transaction, error)); ok { + return rf(opts, gasLimit, maxFeePerGas, to, value, data) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, *big.Int, *big.Int, common.Address, *big.Int, []byte) *types.Transaction); ok { + r0 = rf(opts, gasLimit, maxFeePerGas, to, value, data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, *big.Int, *big.Int, common.Address, *big.Int, []byte) error); ok { + r1 = rf(opts, gasLimit, maxFeePerGas, to, value, data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_SendContractTransaction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendContractTransaction' +type ArbitrumInboxInterface_SendContractTransaction_Call struct { + *mock.Call +} + +// SendContractTransaction is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - gasLimit *big.Int +// - maxFeePerGas *big.Int +// - to common.Address +// - value *big.Int +// - data []byte +func (_e *ArbitrumInboxInterface_Expecter) SendContractTransaction(opts interface{}, gasLimit interface{}, maxFeePerGas interface{}, to interface{}, value interface{}, data interface{}) *ArbitrumInboxInterface_SendContractTransaction_Call { + return &ArbitrumInboxInterface_SendContractTransaction_Call{Call: _e.mock.On("SendContractTransaction", opts, gasLimit, maxFeePerGas, to, value, data)} +} + +func (_c *ArbitrumInboxInterface_SendContractTransaction_Call) Run(run func(opts *bind.TransactOpts, gasLimit *big.Int, maxFeePerGas *big.Int, to common.Address, value *big.Int, data []byte)) *ArbitrumInboxInterface_SendContractTransaction_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(*big.Int), args[2].(*big.Int), args[3].(common.Address), args[4].(*big.Int), args[5].([]byte)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_SendContractTransaction_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumInboxInterface_SendContractTransaction_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_SendContractTransaction_Call) RunAndReturn(run func(*bind.TransactOpts, *big.Int, *big.Int, common.Address, *big.Int, []byte) (*types.Transaction, error)) *ArbitrumInboxInterface_SendContractTransaction_Call { + _c.Call.Return(run) + return _c +} + +// SendL2Message provides a mock function with given fields: opts, messageData +func (_m *ArbitrumInboxInterface) SendL2Message(opts *bind.TransactOpts, messageData []byte) (*types.Transaction, error) { + ret := _m.Called(opts, messageData) + + if len(ret) == 0 { + panic("no return value specified for SendL2Message") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []byte) (*types.Transaction, error)); ok { + return rf(opts, messageData) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []byte) *types.Transaction); ok { + r0 = rf(opts, messageData) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []byte) error); ok { + r1 = rf(opts, messageData) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_SendL2Message_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendL2Message' +type ArbitrumInboxInterface_SendL2Message_Call struct { + *mock.Call +} + +// SendL2Message is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - messageData []byte +func (_e *ArbitrumInboxInterface_Expecter) SendL2Message(opts interface{}, messageData interface{}) *ArbitrumInboxInterface_SendL2Message_Call { + return &ArbitrumInboxInterface_SendL2Message_Call{Call: _e.mock.On("SendL2Message", opts, messageData)} +} + +func (_c *ArbitrumInboxInterface_SendL2Message_Call) Run(run func(opts *bind.TransactOpts, messageData []byte)) *ArbitrumInboxInterface_SendL2Message_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]byte)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_SendL2Message_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumInboxInterface_SendL2Message_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_SendL2Message_Call) RunAndReturn(run func(*bind.TransactOpts, []byte) (*types.Transaction, error)) *ArbitrumInboxInterface_SendL2Message_Call { + _c.Call.Return(run) + return _c +} + +// SendL2MessageFromOrigin provides a mock function with given fields: opts, messageData +func (_m *ArbitrumInboxInterface) SendL2MessageFromOrigin(opts *bind.TransactOpts, messageData []byte) (*types.Transaction, error) { + ret := _m.Called(opts, messageData) + + if len(ret) == 0 { + panic("no return value specified for SendL2MessageFromOrigin") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []byte) (*types.Transaction, error)); ok { + return rf(opts, messageData) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []byte) *types.Transaction); ok { + r0 = rf(opts, messageData) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []byte) error); ok { + r1 = rf(opts, messageData) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_SendL2MessageFromOrigin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendL2MessageFromOrigin' +type ArbitrumInboxInterface_SendL2MessageFromOrigin_Call struct { + *mock.Call +} + +// SendL2MessageFromOrigin is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - messageData []byte +func (_e *ArbitrumInboxInterface_Expecter) SendL2MessageFromOrigin(opts interface{}, messageData interface{}) *ArbitrumInboxInterface_SendL2MessageFromOrigin_Call { + return &ArbitrumInboxInterface_SendL2MessageFromOrigin_Call{Call: _e.mock.On("SendL2MessageFromOrigin", opts, messageData)} +} + +func (_c *ArbitrumInboxInterface_SendL2MessageFromOrigin_Call) Run(run func(opts *bind.TransactOpts, messageData []byte)) *ArbitrumInboxInterface_SendL2MessageFromOrigin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]byte)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_SendL2MessageFromOrigin_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumInboxInterface_SendL2MessageFromOrigin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_SendL2MessageFromOrigin_Call) RunAndReturn(run func(*bind.TransactOpts, []byte) (*types.Transaction, error)) *ArbitrumInboxInterface_SendL2MessageFromOrigin_Call { + _c.Call.Return(run) + return _c +} + +// SendUnsignedTransaction provides a mock function with given fields: opts, gasLimit, maxFeePerGas, nonce, to, value, data +func (_m *ArbitrumInboxInterface) SendUnsignedTransaction(opts *bind.TransactOpts, gasLimit *big.Int, maxFeePerGas *big.Int, nonce *big.Int, to common.Address, value *big.Int, data []byte) (*types.Transaction, error) { + ret := _m.Called(opts, gasLimit, maxFeePerGas, nonce, to, value, data) + + if len(ret) == 0 { + panic("no return value specified for SendUnsignedTransaction") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, *big.Int, *big.Int, *big.Int, common.Address, *big.Int, []byte) (*types.Transaction, error)); ok { + return rf(opts, gasLimit, maxFeePerGas, nonce, to, value, data) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, *big.Int, *big.Int, *big.Int, common.Address, *big.Int, []byte) *types.Transaction); ok { + r0 = rf(opts, gasLimit, maxFeePerGas, nonce, to, value, data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, *big.Int, *big.Int, *big.Int, common.Address, *big.Int, []byte) error); ok { + r1 = rf(opts, gasLimit, maxFeePerGas, nonce, to, value, data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_SendUnsignedTransaction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendUnsignedTransaction' +type ArbitrumInboxInterface_SendUnsignedTransaction_Call struct { + *mock.Call +} + +// SendUnsignedTransaction is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - gasLimit *big.Int +// - maxFeePerGas *big.Int +// - nonce *big.Int +// - to common.Address +// - value *big.Int +// - data []byte +func (_e *ArbitrumInboxInterface_Expecter) SendUnsignedTransaction(opts interface{}, gasLimit interface{}, maxFeePerGas interface{}, nonce interface{}, to interface{}, value interface{}, data interface{}) *ArbitrumInboxInterface_SendUnsignedTransaction_Call { + return &ArbitrumInboxInterface_SendUnsignedTransaction_Call{Call: _e.mock.On("SendUnsignedTransaction", opts, gasLimit, maxFeePerGas, nonce, to, value, data)} +} + +func (_c *ArbitrumInboxInterface_SendUnsignedTransaction_Call) Run(run func(opts *bind.TransactOpts, gasLimit *big.Int, maxFeePerGas *big.Int, nonce *big.Int, to common.Address, value *big.Int, data []byte)) *ArbitrumInboxInterface_SendUnsignedTransaction_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(*big.Int), args[2].(*big.Int), args[3].(*big.Int), args[4].(common.Address), args[5].(*big.Int), args[6].([]byte)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_SendUnsignedTransaction_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumInboxInterface_SendUnsignedTransaction_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_SendUnsignedTransaction_Call) RunAndReturn(run func(*bind.TransactOpts, *big.Int, *big.Int, *big.Int, common.Address, *big.Int, []byte) (*types.Transaction, error)) *ArbitrumInboxInterface_SendUnsignedTransaction_Call { + _c.Call.Return(run) + return _c +} + +// SequencerInbox provides a mock function with given fields: opts +func (_m *ArbitrumInboxInterface) SequencerInbox(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for SequencerInbox") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_SequencerInbox_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SequencerInbox' +type ArbitrumInboxInterface_SequencerInbox_Call struct { + *mock.Call +} + +// SequencerInbox is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbitrumInboxInterface_Expecter) SequencerInbox(opts interface{}) *ArbitrumInboxInterface_SequencerInbox_Call { + return &ArbitrumInboxInterface_SequencerInbox_Call{Call: _e.mock.On("SequencerInbox", opts)} +} + +func (_c *ArbitrumInboxInterface_SequencerInbox_Call) Run(run func(opts *bind.CallOpts)) *ArbitrumInboxInterface_SequencerInbox_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_SequencerInbox_Call) Return(_a0 common.Address, _a1 error) *ArbitrumInboxInterface_SequencerInbox_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_SequencerInbox_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *ArbitrumInboxInterface_SequencerInbox_Call { + _c.Call.Return(run) + return _c +} + +// SetAllowList provides a mock function with given fields: opts, user, val +func (_m *ArbitrumInboxInterface) SetAllowList(opts *bind.TransactOpts, user []common.Address, val []bool) (*types.Transaction, error) { + ret := _m.Called(opts, user, val) + + if len(ret) == 0 { + panic("no return value specified for SetAllowList") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []bool) (*types.Transaction, error)); ok { + return rf(opts, user, val) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []bool) *types.Transaction); ok { + r0 = rf(opts, user, val) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []common.Address, []bool) error); ok { + r1 = rf(opts, user, val) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_SetAllowList_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetAllowList' +type ArbitrumInboxInterface_SetAllowList_Call struct { + *mock.Call +} + +// SetAllowList is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - user []common.Address +// - val []bool +func (_e *ArbitrumInboxInterface_Expecter) SetAllowList(opts interface{}, user interface{}, val interface{}) *ArbitrumInboxInterface_SetAllowList_Call { + return &ArbitrumInboxInterface_SetAllowList_Call{Call: _e.mock.On("SetAllowList", opts, user, val)} +} + +func (_c *ArbitrumInboxInterface_SetAllowList_Call) Run(run func(opts *bind.TransactOpts, user []common.Address, val []bool)) *ArbitrumInboxInterface_SetAllowList_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]common.Address), args[2].([]bool)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_SetAllowList_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumInboxInterface_SetAllowList_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_SetAllowList_Call) RunAndReturn(run func(*bind.TransactOpts, []common.Address, []bool) (*types.Transaction, error)) *ArbitrumInboxInterface_SetAllowList_Call { + _c.Call.Return(run) + return _c +} + +// SetAllowListEnabled provides a mock function with given fields: opts, _allowListEnabled +func (_m *ArbitrumInboxInterface) SetAllowListEnabled(opts *bind.TransactOpts, _allowListEnabled bool) (*types.Transaction, error) { + ret := _m.Called(opts, _allowListEnabled) + + if len(ret) == 0 { + panic("no return value specified for SetAllowListEnabled") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, bool) (*types.Transaction, error)); ok { + return rf(opts, _allowListEnabled) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, bool) *types.Transaction); ok { + r0 = rf(opts, _allowListEnabled) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, bool) error); ok { + r1 = rf(opts, _allowListEnabled) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_SetAllowListEnabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetAllowListEnabled' +type ArbitrumInboxInterface_SetAllowListEnabled_Call struct { + *mock.Call +} + +// SetAllowListEnabled is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _allowListEnabled bool +func (_e *ArbitrumInboxInterface_Expecter) SetAllowListEnabled(opts interface{}, _allowListEnabled interface{}) *ArbitrumInboxInterface_SetAllowListEnabled_Call { + return &ArbitrumInboxInterface_SetAllowListEnabled_Call{Call: _e.mock.On("SetAllowListEnabled", opts, _allowListEnabled)} +} + +func (_c *ArbitrumInboxInterface_SetAllowListEnabled_Call) Run(run func(opts *bind.TransactOpts, _allowListEnabled bool)) *ArbitrumInboxInterface_SetAllowListEnabled_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(bool)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_SetAllowListEnabled_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumInboxInterface_SetAllowListEnabled_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_SetAllowListEnabled_Call) RunAndReturn(run func(*bind.TransactOpts, bool) (*types.Transaction, error)) *ArbitrumInboxInterface_SetAllowListEnabled_Call { + _c.Call.Return(run) + return _c +} + +// Unpause provides a mock function with given fields: opts +func (_m *ArbitrumInboxInterface) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Unpause") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_Unpause_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Unpause' +type ArbitrumInboxInterface_Unpause_Call struct { + *mock.Call +} + +// Unpause is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *ArbitrumInboxInterface_Expecter) Unpause(opts interface{}) *ArbitrumInboxInterface_Unpause_Call { + return &ArbitrumInboxInterface_Unpause_Call{Call: _e.mock.On("Unpause", opts)} +} + +func (_c *ArbitrumInboxInterface_Unpause_Call) Run(run func(opts *bind.TransactOpts)) *ArbitrumInboxInterface_Unpause_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_Unpause_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumInboxInterface_Unpause_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_Unpause_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *ArbitrumInboxInterface_Unpause_Call { + _c.Call.Return(run) + return _c +} + +// WatchInboxMessageDelivered provides a mock function with given fields: opts, sink, messageNum +func (_m *ArbitrumInboxInterface) WatchInboxMessageDelivered(opts *bind.WatchOpts, sink chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDelivered, messageNum []*big.Int) (event.Subscription, error) { + ret := _m.Called(opts, sink, messageNum) + + if len(ret) == 0 { + panic("no return value specified for WatchInboxMessageDelivered") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDelivered, []*big.Int) (event.Subscription, error)); ok { + return rf(opts, sink, messageNum) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDelivered, []*big.Int) event.Subscription); ok { + r0 = rf(opts, sink, messageNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDelivered, []*big.Int) error); ok { + r1 = rf(opts, sink, messageNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_WatchInboxMessageDelivered_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchInboxMessageDelivered' +type ArbitrumInboxInterface_WatchInboxMessageDelivered_Call struct { + *mock.Call +} + +// WatchInboxMessageDelivered is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDelivered +// - messageNum []*big.Int +func (_e *ArbitrumInboxInterface_Expecter) WatchInboxMessageDelivered(opts interface{}, sink interface{}, messageNum interface{}) *ArbitrumInboxInterface_WatchInboxMessageDelivered_Call { + return &ArbitrumInboxInterface_WatchInboxMessageDelivered_Call{Call: _e.mock.On("WatchInboxMessageDelivered", opts, sink, messageNum)} +} + +func (_c *ArbitrumInboxInterface_WatchInboxMessageDelivered_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDelivered, messageNum []*big.Int)) *ArbitrumInboxInterface_WatchInboxMessageDelivered_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDelivered), args[2].([]*big.Int)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_WatchInboxMessageDelivered_Call) Return(_a0 event.Subscription, _a1 error) *ArbitrumInboxInterface_WatchInboxMessageDelivered_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_WatchInboxMessageDelivered_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDelivered, []*big.Int) (event.Subscription, error)) *ArbitrumInboxInterface_WatchInboxMessageDelivered_Call { + _c.Call.Return(run) + return _c +} + +// WatchInboxMessageDeliveredFromOrigin provides a mock function with given fields: opts, sink, messageNum +func (_m *ArbitrumInboxInterface) WatchInboxMessageDeliveredFromOrigin(opts *bind.WatchOpts, sink chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin, messageNum []*big.Int) (event.Subscription, error) { + ret := _m.Called(opts, sink, messageNum) + + if len(ret) == 0 { + panic("no return value specified for WatchInboxMessageDeliveredFromOrigin") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin, []*big.Int) (event.Subscription, error)); ok { + return rf(opts, sink, messageNum) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin, []*big.Int) event.Subscription); ok { + r0 = rf(opts, sink, messageNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin, []*big.Int) error); ok { + r1 = rf(opts, sink, messageNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumInboxInterface_WatchInboxMessageDeliveredFromOrigin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchInboxMessageDeliveredFromOrigin' +type ArbitrumInboxInterface_WatchInboxMessageDeliveredFromOrigin_Call struct { + *mock.Call +} + +// WatchInboxMessageDeliveredFromOrigin is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin +// - messageNum []*big.Int +func (_e *ArbitrumInboxInterface_Expecter) WatchInboxMessageDeliveredFromOrigin(opts interface{}, sink interface{}, messageNum interface{}) *ArbitrumInboxInterface_WatchInboxMessageDeliveredFromOrigin_Call { + return &ArbitrumInboxInterface_WatchInboxMessageDeliveredFromOrigin_Call{Call: _e.mock.On("WatchInboxMessageDeliveredFromOrigin", opts, sink, messageNum)} +} + +func (_c *ArbitrumInboxInterface_WatchInboxMessageDeliveredFromOrigin_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin, messageNum []*big.Int)) *ArbitrumInboxInterface_WatchInboxMessageDeliveredFromOrigin_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin), args[2].([]*big.Int)) + }) + return _c +} + +func (_c *ArbitrumInboxInterface_WatchInboxMessageDeliveredFromOrigin_Call) Return(_a0 event.Subscription, _a1 error) *ArbitrumInboxInterface_WatchInboxMessageDeliveredFromOrigin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumInboxInterface_WatchInboxMessageDeliveredFromOrigin_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbitrum_inbox.ArbitrumInboxInboxMessageDeliveredFromOrigin, []*big.Int) (event.Subscription, error)) *ArbitrumInboxInterface_WatchInboxMessageDeliveredFromOrigin_Call { + _c.Call.Return(run) + return _c +} + +// NewArbitrumInboxInterface creates a new instance of ArbitrumInboxInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewArbitrumInboxInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *ArbitrumInboxInterface { + mock := &ArbitrumInboxInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_l1_bridge_adapter/arbitrum_l1_bridge_adapter_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_l1_bridge_adapter/arbitrum_l1_bridge_adapter_interface.go new file mode 100644 index 0000000000..94c24efa20 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_l1_bridge_adapter/arbitrum_l1_bridge_adapter_interface.go @@ -0,0 +1,426 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_arbitrum_l1_bridge_adapter + +import ( + big "math/big" + + arbitrum_l1_bridge_adapter "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_l1_bridge_adapter" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// ArbitrumL1BridgeAdapterInterface is an autogenerated mock type for the ArbitrumL1BridgeAdapterInterface type +type ArbitrumL1BridgeAdapterInterface struct { + mock.Mock +} + +type ArbitrumL1BridgeAdapterInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *ArbitrumL1BridgeAdapterInterface) EXPECT() *ArbitrumL1BridgeAdapterInterface_Expecter { + return &ArbitrumL1BridgeAdapterInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *ArbitrumL1BridgeAdapterInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// ArbitrumL1BridgeAdapterInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type ArbitrumL1BridgeAdapterInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *ArbitrumL1BridgeAdapterInterface_Expecter) Address() *ArbitrumL1BridgeAdapterInterface_Address_Call { + return &ArbitrumL1BridgeAdapterInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *ArbitrumL1BridgeAdapterInterface_Address_Call) Run(run func()) *ArbitrumL1BridgeAdapterInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_Address_Call) Return(_a0 common.Address) *ArbitrumL1BridgeAdapterInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_Address_Call) RunAndReturn(run func() common.Address) *ArbitrumL1BridgeAdapterInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// ExposeArbitrumFinalizationPayload provides a mock function with given fields: opts, payload +func (_m *ArbitrumL1BridgeAdapterInterface) ExposeArbitrumFinalizationPayload(opts *bind.CallOpts, payload arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapterArbitrumFinalizationPayload) error { + ret := _m.Called(opts, payload) + + if len(ret) == 0 { + panic("no return value specified for ExposeArbitrumFinalizationPayload") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapterArbitrumFinalizationPayload) error); ok { + r0 = rf(opts, payload) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ArbitrumL1BridgeAdapterInterface_ExposeArbitrumFinalizationPayload_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExposeArbitrumFinalizationPayload' +type ArbitrumL1BridgeAdapterInterface_ExposeArbitrumFinalizationPayload_Call struct { + *mock.Call +} + +// ExposeArbitrumFinalizationPayload is a helper method to define mock.On call +// - opts *bind.CallOpts +// - payload arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapterArbitrumFinalizationPayload +func (_e *ArbitrumL1BridgeAdapterInterface_Expecter) ExposeArbitrumFinalizationPayload(opts interface{}, payload interface{}) *ArbitrumL1BridgeAdapterInterface_ExposeArbitrumFinalizationPayload_Call { + return &ArbitrumL1BridgeAdapterInterface_ExposeArbitrumFinalizationPayload_Call{Call: _e.mock.On("ExposeArbitrumFinalizationPayload", opts, payload)} +} + +func (_c *ArbitrumL1BridgeAdapterInterface_ExposeArbitrumFinalizationPayload_Call) Run(run func(opts *bind.CallOpts, payload arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapterArbitrumFinalizationPayload)) *ArbitrumL1BridgeAdapterInterface_ExposeArbitrumFinalizationPayload_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapterArbitrumFinalizationPayload)) + }) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_ExposeArbitrumFinalizationPayload_Call) Return(_a0 error) *ArbitrumL1BridgeAdapterInterface_ExposeArbitrumFinalizationPayload_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_ExposeArbitrumFinalizationPayload_Call) RunAndReturn(run func(*bind.CallOpts, arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapterArbitrumFinalizationPayload) error) *ArbitrumL1BridgeAdapterInterface_ExposeArbitrumFinalizationPayload_Call { + _c.Call.Return(run) + return _c +} + +// ExposeSendERC20Params provides a mock function with given fields: opts, params +func (_m *ArbitrumL1BridgeAdapterInterface) ExposeSendERC20Params(opts *bind.CallOpts, params arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapterSendERC20Params) error { + ret := _m.Called(opts, params) + + if len(ret) == 0 { + panic("no return value specified for ExposeSendERC20Params") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapterSendERC20Params) error); ok { + r0 = rf(opts, params) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ArbitrumL1BridgeAdapterInterface_ExposeSendERC20Params_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExposeSendERC20Params' +type ArbitrumL1BridgeAdapterInterface_ExposeSendERC20Params_Call struct { + *mock.Call +} + +// ExposeSendERC20Params is a helper method to define mock.On call +// - opts *bind.CallOpts +// - params arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapterSendERC20Params +func (_e *ArbitrumL1BridgeAdapterInterface_Expecter) ExposeSendERC20Params(opts interface{}, params interface{}) *ArbitrumL1BridgeAdapterInterface_ExposeSendERC20Params_Call { + return &ArbitrumL1BridgeAdapterInterface_ExposeSendERC20Params_Call{Call: _e.mock.On("ExposeSendERC20Params", opts, params)} +} + +func (_c *ArbitrumL1BridgeAdapterInterface_ExposeSendERC20Params_Call) Run(run func(opts *bind.CallOpts, params arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapterSendERC20Params)) *ArbitrumL1BridgeAdapterInterface_ExposeSendERC20Params_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapterSendERC20Params)) + }) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_ExposeSendERC20Params_Call) Return(_a0 error) *ArbitrumL1BridgeAdapterInterface_ExposeSendERC20Params_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_ExposeSendERC20Params_Call) RunAndReturn(run func(*bind.CallOpts, arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapterSendERC20Params) error) *ArbitrumL1BridgeAdapterInterface_ExposeSendERC20Params_Call { + _c.Call.Return(run) + return _c +} + +// FinalizeWithdrawERC20 provides a mock function with given fields: opts, arg0, arg1, arbitrumFinalizationPayload +func (_m *ArbitrumL1BridgeAdapterInterface) FinalizeWithdrawERC20(opts *bind.TransactOpts, arg0 common.Address, arg1 common.Address, arbitrumFinalizationPayload []byte) (*types.Transaction, error) { + ret := _m.Called(opts, arg0, arg1, arbitrumFinalizationPayload) + + if len(ret) == 0 { + panic("no return value specified for FinalizeWithdrawERC20") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, []byte) (*types.Transaction, error)); ok { + return rf(opts, arg0, arg1, arbitrumFinalizationPayload) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, []byte) *types.Transaction); ok { + r0 = rf(opts, arg0, arg1, arbitrumFinalizationPayload) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, common.Address, []byte) error); ok { + r1 = rf(opts, arg0, arg1, arbitrumFinalizationPayload) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumL1BridgeAdapterInterface_FinalizeWithdrawERC20_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FinalizeWithdrawERC20' +type ArbitrumL1BridgeAdapterInterface_FinalizeWithdrawERC20_Call struct { + *mock.Call +} + +// FinalizeWithdrawERC20 is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - arg0 common.Address +// - arg1 common.Address +// - arbitrumFinalizationPayload []byte +func (_e *ArbitrumL1BridgeAdapterInterface_Expecter) FinalizeWithdrawERC20(opts interface{}, arg0 interface{}, arg1 interface{}, arbitrumFinalizationPayload interface{}) *ArbitrumL1BridgeAdapterInterface_FinalizeWithdrawERC20_Call { + return &ArbitrumL1BridgeAdapterInterface_FinalizeWithdrawERC20_Call{Call: _e.mock.On("FinalizeWithdrawERC20", opts, arg0, arg1, arbitrumFinalizationPayload)} +} + +func (_c *ArbitrumL1BridgeAdapterInterface_FinalizeWithdrawERC20_Call) Run(run func(opts *bind.TransactOpts, arg0 common.Address, arg1 common.Address, arbitrumFinalizationPayload []byte)) *ArbitrumL1BridgeAdapterInterface_FinalizeWithdrawERC20_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(common.Address), args[3].([]byte)) + }) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_FinalizeWithdrawERC20_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumL1BridgeAdapterInterface_FinalizeWithdrawERC20_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_FinalizeWithdrawERC20_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, common.Address, []byte) (*types.Transaction, error)) *ArbitrumL1BridgeAdapterInterface_FinalizeWithdrawERC20_Call { + _c.Call.Return(run) + return _c +} + +// GetBridgeFeeInNative provides a mock function with given fields: opts +func (_m *ArbitrumL1BridgeAdapterInterface) GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetBridgeFeeInNative") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumL1BridgeAdapterInterface_GetBridgeFeeInNative_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBridgeFeeInNative' +type ArbitrumL1BridgeAdapterInterface_GetBridgeFeeInNative_Call struct { + *mock.Call +} + +// GetBridgeFeeInNative is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbitrumL1BridgeAdapterInterface_Expecter) GetBridgeFeeInNative(opts interface{}) *ArbitrumL1BridgeAdapterInterface_GetBridgeFeeInNative_Call { + return &ArbitrumL1BridgeAdapterInterface_GetBridgeFeeInNative_Call{Call: _e.mock.On("GetBridgeFeeInNative", opts)} +} + +func (_c *ArbitrumL1BridgeAdapterInterface_GetBridgeFeeInNative_Call) Run(run func(opts *bind.CallOpts)) *ArbitrumL1BridgeAdapterInterface_GetBridgeFeeInNative_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_GetBridgeFeeInNative_Call) Return(_a0 *big.Int, _a1 error) *ArbitrumL1BridgeAdapterInterface_GetBridgeFeeInNative_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_GetBridgeFeeInNative_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *ArbitrumL1BridgeAdapterInterface_GetBridgeFeeInNative_Call { + _c.Call.Return(run) + return _c +} + +// GetL2Token provides a mock function with given fields: opts, l1Token +func (_m *ArbitrumL1BridgeAdapterInterface) GetL2Token(opts *bind.CallOpts, l1Token common.Address) (common.Address, error) { + ret := _m.Called(opts, l1Token) + + if len(ret) == 0 { + panic("no return value specified for GetL2Token") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (common.Address, error)); ok { + return rf(opts, l1Token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) common.Address); ok { + r0 = rf(opts, l1Token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, l1Token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumL1BridgeAdapterInterface_GetL2Token_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetL2Token' +type ArbitrumL1BridgeAdapterInterface_GetL2Token_Call struct { + *mock.Call +} + +// GetL2Token is a helper method to define mock.On call +// - opts *bind.CallOpts +// - l1Token common.Address +func (_e *ArbitrumL1BridgeAdapterInterface_Expecter) GetL2Token(opts interface{}, l1Token interface{}) *ArbitrumL1BridgeAdapterInterface_GetL2Token_Call { + return &ArbitrumL1BridgeAdapterInterface_GetL2Token_Call{Call: _e.mock.On("GetL2Token", opts, l1Token)} +} + +func (_c *ArbitrumL1BridgeAdapterInterface_GetL2Token_Call) Run(run func(opts *bind.CallOpts, l1Token common.Address)) *ArbitrumL1BridgeAdapterInterface_GetL2Token_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_GetL2Token_Call) Return(_a0 common.Address, _a1 error) *ArbitrumL1BridgeAdapterInterface_GetL2Token_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_GetL2Token_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (common.Address, error)) *ArbitrumL1BridgeAdapterInterface_GetL2Token_Call { + _c.Call.Return(run) + return _c +} + +// SendERC20 provides a mock function with given fields: opts, localToken, arg1, recipient, amount, bridgeSpecificPayload +func (_m *ArbitrumL1BridgeAdapterInterface) SendERC20(opts *bind.TransactOpts, localToken common.Address, arg1 common.Address, recipient common.Address, amount *big.Int, bridgeSpecificPayload []byte) (*types.Transaction, error) { + ret := _m.Called(opts, localToken, arg1, recipient, amount, bridgeSpecificPayload) + + if len(ret) == 0 { + panic("no return value specified for SendERC20") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) (*types.Transaction, error)); ok { + return rf(opts, localToken, arg1, recipient, amount, bridgeSpecificPayload) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) *types.Transaction); ok { + r0 = rf(opts, localToken, arg1, recipient, amount, bridgeSpecificPayload) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) error); ok { + r1 = rf(opts, localToken, arg1, recipient, amount, bridgeSpecificPayload) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumL1BridgeAdapterInterface_SendERC20_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendERC20' +type ArbitrumL1BridgeAdapterInterface_SendERC20_Call struct { + *mock.Call +} + +// SendERC20 is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - localToken common.Address +// - arg1 common.Address +// - recipient common.Address +// - amount *big.Int +// - bridgeSpecificPayload []byte +func (_e *ArbitrumL1BridgeAdapterInterface_Expecter) SendERC20(opts interface{}, localToken interface{}, arg1 interface{}, recipient interface{}, amount interface{}, bridgeSpecificPayload interface{}) *ArbitrumL1BridgeAdapterInterface_SendERC20_Call { + return &ArbitrumL1BridgeAdapterInterface_SendERC20_Call{Call: _e.mock.On("SendERC20", opts, localToken, arg1, recipient, amount, bridgeSpecificPayload)} +} + +func (_c *ArbitrumL1BridgeAdapterInterface_SendERC20_Call) Run(run func(opts *bind.TransactOpts, localToken common.Address, arg1 common.Address, recipient common.Address, amount *big.Int, bridgeSpecificPayload []byte)) *ArbitrumL1BridgeAdapterInterface_SendERC20_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(common.Address), args[3].(common.Address), args[4].(*big.Int), args[5].([]byte)) + }) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_SendERC20_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumL1BridgeAdapterInterface_SendERC20_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumL1BridgeAdapterInterface_SendERC20_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) (*types.Transaction, error)) *ArbitrumL1BridgeAdapterInterface_SendERC20_Call { + _c.Call.Return(run) + return _c +} + +// NewArbitrumL1BridgeAdapterInterface creates a new instance of ArbitrumL1BridgeAdapterInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewArbitrumL1BridgeAdapterInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *ArbitrumL1BridgeAdapterInterface { + mock := &ArbitrumL1BridgeAdapterInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_l2_bridge_adapter/arbitrum_l2_bridge_adapter_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_l2_bridge_adapter/arbitrum_l2_bridge_adapter_interface.go new file mode 100644 index 0000000000..01d025790a --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_l2_bridge_adapter/arbitrum_l2_bridge_adapter_interface.go @@ -0,0 +1,327 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_arbitrum_l2_bridge_adapter + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// ArbitrumL2BridgeAdapterInterface is an autogenerated mock type for the ArbitrumL2BridgeAdapterInterface type +type ArbitrumL2BridgeAdapterInterface struct { + mock.Mock +} + +type ArbitrumL2BridgeAdapterInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *ArbitrumL2BridgeAdapterInterface) EXPECT() *ArbitrumL2BridgeAdapterInterface_Expecter { + return &ArbitrumL2BridgeAdapterInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *ArbitrumL2BridgeAdapterInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// ArbitrumL2BridgeAdapterInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type ArbitrumL2BridgeAdapterInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *ArbitrumL2BridgeAdapterInterface_Expecter) Address() *ArbitrumL2BridgeAdapterInterface_Address_Call { + return &ArbitrumL2BridgeAdapterInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *ArbitrumL2BridgeAdapterInterface_Address_Call) Run(run func()) *ArbitrumL2BridgeAdapterInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ArbitrumL2BridgeAdapterInterface_Address_Call) Return(_a0 common.Address) *ArbitrumL2BridgeAdapterInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ArbitrumL2BridgeAdapterInterface_Address_Call) RunAndReturn(run func() common.Address) *ArbitrumL2BridgeAdapterInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// DepositNativeToL1 provides a mock function with given fields: opts, recipient +func (_m *ArbitrumL2BridgeAdapterInterface) DepositNativeToL1(opts *bind.TransactOpts, recipient common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, recipient) + + if len(ret) == 0 { + panic("no return value specified for DepositNativeToL1") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, recipient) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, recipient) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, recipient) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumL2BridgeAdapterInterface_DepositNativeToL1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DepositNativeToL1' +type ArbitrumL2BridgeAdapterInterface_DepositNativeToL1_Call struct { + *mock.Call +} + +// DepositNativeToL1 is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - recipient common.Address +func (_e *ArbitrumL2BridgeAdapterInterface_Expecter) DepositNativeToL1(opts interface{}, recipient interface{}) *ArbitrumL2BridgeAdapterInterface_DepositNativeToL1_Call { + return &ArbitrumL2BridgeAdapterInterface_DepositNativeToL1_Call{Call: _e.mock.On("DepositNativeToL1", opts, recipient)} +} + +func (_c *ArbitrumL2BridgeAdapterInterface_DepositNativeToL1_Call) Run(run func(opts *bind.TransactOpts, recipient common.Address)) *ArbitrumL2BridgeAdapterInterface_DepositNativeToL1_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbitrumL2BridgeAdapterInterface_DepositNativeToL1_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumL2BridgeAdapterInterface_DepositNativeToL1_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumL2BridgeAdapterInterface_DepositNativeToL1_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *ArbitrumL2BridgeAdapterInterface_DepositNativeToL1_Call { + _c.Call.Return(run) + return _c +} + +// FinalizeWithdrawERC20 provides a mock function with given fields: opts, arg0, arg1, arg2 +func (_m *ArbitrumL2BridgeAdapterInterface) FinalizeWithdrawERC20(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 []byte) (bool, error) { + ret := _m.Called(opts, arg0, arg1, arg2) + + if len(ret) == 0 { + panic("no return value specified for FinalizeWithdrawERC20") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, common.Address, []byte) (bool, error)); ok { + return rf(opts, arg0, arg1, arg2) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, common.Address, []byte) bool); ok { + r0 = rf(opts, arg0, arg1, arg2) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address, common.Address, []byte) error); ok { + r1 = rf(opts, arg0, arg1, arg2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumL2BridgeAdapterInterface_FinalizeWithdrawERC20_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FinalizeWithdrawERC20' +type ArbitrumL2BridgeAdapterInterface_FinalizeWithdrawERC20_Call struct { + *mock.Call +} + +// FinalizeWithdrawERC20 is a helper method to define mock.On call +// - opts *bind.CallOpts +// - arg0 common.Address +// - arg1 common.Address +// - arg2 []byte +func (_e *ArbitrumL2BridgeAdapterInterface_Expecter) FinalizeWithdrawERC20(opts interface{}, arg0 interface{}, arg1 interface{}, arg2 interface{}) *ArbitrumL2BridgeAdapterInterface_FinalizeWithdrawERC20_Call { + return &ArbitrumL2BridgeAdapterInterface_FinalizeWithdrawERC20_Call{Call: _e.mock.On("FinalizeWithdrawERC20", opts, arg0, arg1, arg2)} +} + +func (_c *ArbitrumL2BridgeAdapterInterface_FinalizeWithdrawERC20_Call) Run(run func(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 []byte)) *ArbitrumL2BridgeAdapterInterface_FinalizeWithdrawERC20_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address), args[2].(common.Address), args[3].([]byte)) + }) + return _c +} + +func (_c *ArbitrumL2BridgeAdapterInterface_FinalizeWithdrawERC20_Call) Return(_a0 bool, _a1 error) *ArbitrumL2BridgeAdapterInterface_FinalizeWithdrawERC20_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumL2BridgeAdapterInterface_FinalizeWithdrawERC20_Call) RunAndReturn(run func(*bind.CallOpts, common.Address, common.Address, []byte) (bool, error)) *ArbitrumL2BridgeAdapterInterface_FinalizeWithdrawERC20_Call { + _c.Call.Return(run) + return _c +} + +// GetBridgeFeeInNative provides a mock function with given fields: opts +func (_m *ArbitrumL2BridgeAdapterInterface) GetBridgeFeeInNative(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetBridgeFeeInNative") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumL2BridgeAdapterInterface_GetBridgeFeeInNative_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBridgeFeeInNative' +type ArbitrumL2BridgeAdapterInterface_GetBridgeFeeInNative_Call struct { + *mock.Call +} + +// GetBridgeFeeInNative is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbitrumL2BridgeAdapterInterface_Expecter) GetBridgeFeeInNative(opts interface{}) *ArbitrumL2BridgeAdapterInterface_GetBridgeFeeInNative_Call { + return &ArbitrumL2BridgeAdapterInterface_GetBridgeFeeInNative_Call{Call: _e.mock.On("GetBridgeFeeInNative", opts)} +} + +func (_c *ArbitrumL2BridgeAdapterInterface_GetBridgeFeeInNative_Call) Run(run func(opts *bind.CallOpts)) *ArbitrumL2BridgeAdapterInterface_GetBridgeFeeInNative_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbitrumL2BridgeAdapterInterface_GetBridgeFeeInNative_Call) Return(_a0 *big.Int, _a1 error) *ArbitrumL2BridgeAdapterInterface_GetBridgeFeeInNative_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumL2BridgeAdapterInterface_GetBridgeFeeInNative_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *ArbitrumL2BridgeAdapterInterface_GetBridgeFeeInNative_Call { + _c.Call.Return(run) + return _c +} + +// SendERC20 provides a mock function with given fields: opts, localToken, remoteToken, recipient, amount, arg4 +func (_m *ArbitrumL2BridgeAdapterInterface) SendERC20(opts *bind.TransactOpts, localToken common.Address, remoteToken common.Address, recipient common.Address, amount *big.Int, arg4 []byte) (*types.Transaction, error) { + ret := _m.Called(opts, localToken, remoteToken, recipient, amount, arg4) + + if len(ret) == 0 { + panic("no return value specified for SendERC20") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) (*types.Transaction, error)); ok { + return rf(opts, localToken, remoteToken, recipient, amount, arg4) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) *types.Transaction); ok { + r0 = rf(opts, localToken, remoteToken, recipient, amount, arg4) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) error); ok { + r1 = rf(opts, localToken, remoteToken, recipient, amount, arg4) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbitrumL2BridgeAdapterInterface_SendERC20_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendERC20' +type ArbitrumL2BridgeAdapterInterface_SendERC20_Call struct { + *mock.Call +} + +// SendERC20 is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - localToken common.Address +// - remoteToken common.Address +// - recipient common.Address +// - amount *big.Int +// - arg4 []byte +func (_e *ArbitrumL2BridgeAdapterInterface_Expecter) SendERC20(opts interface{}, localToken interface{}, remoteToken interface{}, recipient interface{}, amount interface{}, arg4 interface{}) *ArbitrumL2BridgeAdapterInterface_SendERC20_Call { + return &ArbitrumL2BridgeAdapterInterface_SendERC20_Call{Call: _e.mock.On("SendERC20", opts, localToken, remoteToken, recipient, amount, arg4)} +} + +func (_c *ArbitrumL2BridgeAdapterInterface_SendERC20_Call) Run(run func(opts *bind.TransactOpts, localToken common.Address, remoteToken common.Address, recipient common.Address, amount *big.Int, arg4 []byte)) *ArbitrumL2BridgeAdapterInterface_SendERC20_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(common.Address), args[3].(common.Address), args[4].(*big.Int), args[5].([]byte)) + }) + return _c +} + +func (_c *ArbitrumL2BridgeAdapterInterface_SendERC20_Call) Return(_a0 *types.Transaction, _a1 error) *ArbitrumL2BridgeAdapterInterface_SendERC20_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbitrumL2BridgeAdapterInterface_SendERC20_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) (*types.Transaction, error)) *ArbitrumL2BridgeAdapterInterface_SendERC20_Call { + _c.Call.Return(run) + return _c +} + +// NewArbitrumL2BridgeAdapterInterface creates a new instance of ArbitrumL2BridgeAdapterInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewArbitrumL2BridgeAdapterInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *ArbitrumL2BridgeAdapterInterface { + mock := &ArbitrumL2BridgeAdapterInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_rollup_core/arb_rollup_core_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_rollup_core/arb_rollup_core_interface.go new file mode 100644 index 0000000000..bc18ea95f1 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_arbitrum_rollup_core/arb_rollup_core_interface.go @@ -0,0 +1,3347 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_arbitrum_rollup_core + +import ( + big "math/big" + + arbitrum_rollup_core "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_rollup_core" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// ArbRollupCoreInterface is an autogenerated mock type for the ArbRollupCoreInterface type +type ArbRollupCoreInterface struct { + mock.Mock +} + +type ArbRollupCoreInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *ArbRollupCoreInterface) EXPECT() *ArbRollupCoreInterface_Expecter { + return &ArbRollupCoreInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *ArbRollupCoreInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// ArbRollupCoreInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type ArbRollupCoreInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *ArbRollupCoreInterface_Expecter) Address() *ArbRollupCoreInterface_Address_Call { + return &ArbRollupCoreInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *ArbRollupCoreInterface_Address_Call) Run(run func()) *ArbRollupCoreInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ArbRollupCoreInterface_Address_Call) Return(_a0 common.Address) *ArbRollupCoreInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ArbRollupCoreInterface_Address_Call) RunAndReturn(run func() common.Address) *ArbRollupCoreInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// AmountStaked provides a mock function with given fields: opts, staker +func (_m *ArbRollupCoreInterface) AmountStaked(opts *bind.CallOpts, staker common.Address) (*big.Int, error) { + ret := _m.Called(opts, staker) + + if len(ret) == 0 { + panic("no return value specified for AmountStaked") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (*big.Int, error)); ok { + return rf(opts, staker) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) *big.Int); ok { + r0 = rf(opts, staker) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, staker) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_AmountStaked_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AmountStaked' +type ArbRollupCoreInterface_AmountStaked_Call struct { + *mock.Call +} + +// AmountStaked is a helper method to define mock.On call +// - opts *bind.CallOpts +// - staker common.Address +func (_e *ArbRollupCoreInterface_Expecter) AmountStaked(opts interface{}, staker interface{}) *ArbRollupCoreInterface_AmountStaked_Call { + return &ArbRollupCoreInterface_AmountStaked_Call{Call: _e.mock.On("AmountStaked", opts, staker)} +} + +func (_c *ArbRollupCoreInterface_AmountStaked_Call) Run(run func(opts *bind.CallOpts, staker common.Address)) *ArbRollupCoreInterface_AmountStaked_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_AmountStaked_Call) Return(_a0 *big.Int, _a1 error) *ArbRollupCoreInterface_AmountStaked_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_AmountStaked_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (*big.Int, error)) *ArbRollupCoreInterface_AmountStaked_Call { + _c.Call.Return(run) + return _c +} + +// BaseStake provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) BaseStake(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for BaseStake") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_BaseStake_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BaseStake' +type ArbRollupCoreInterface_BaseStake_Call struct { + *mock.Call +} + +// BaseStake is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) BaseStake(opts interface{}) *ArbRollupCoreInterface_BaseStake_Call { + return &ArbRollupCoreInterface_BaseStake_Call{Call: _e.mock.On("BaseStake", opts)} +} + +func (_c *ArbRollupCoreInterface_BaseStake_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_BaseStake_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_BaseStake_Call) Return(_a0 *big.Int, _a1 error) *ArbRollupCoreInterface_BaseStake_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_BaseStake_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *ArbRollupCoreInterface_BaseStake_Call { + _c.Call.Return(run) + return _c +} + +// Bridge provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) Bridge(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Bridge") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_Bridge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bridge' +type ArbRollupCoreInterface_Bridge_Call struct { + *mock.Call +} + +// Bridge is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) Bridge(opts interface{}) *ArbRollupCoreInterface_Bridge_Call { + return &ArbRollupCoreInterface_Bridge_Call{Call: _e.mock.On("Bridge", opts)} +} + +func (_c *ArbRollupCoreInterface_Bridge_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_Bridge_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_Bridge_Call) Return(_a0 common.Address, _a1 error) *ArbRollupCoreInterface_Bridge_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_Bridge_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *ArbRollupCoreInterface_Bridge_Call { + _c.Call.Return(run) + return _c +} + +// ChainId provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) ChainId(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for ChainId") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ChainId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ChainId' +type ArbRollupCoreInterface_ChainId_Call struct { + *mock.Call +} + +// ChainId is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) ChainId(opts interface{}) *ArbRollupCoreInterface_ChainId_Call { + return &ArbRollupCoreInterface_ChainId_Call{Call: _e.mock.On("ChainId", opts)} +} + +func (_c *ArbRollupCoreInterface_ChainId_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_ChainId_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ChainId_Call) Return(_a0 *big.Int, _a1 error) *ArbRollupCoreInterface_ChainId_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ChainId_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *ArbRollupCoreInterface_ChainId_Call { + _c.Call.Return(run) + return _c +} + +// ChallengeManager provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) ChallengeManager(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for ChallengeManager") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ChallengeManager_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ChallengeManager' +type ArbRollupCoreInterface_ChallengeManager_Call struct { + *mock.Call +} + +// ChallengeManager is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) ChallengeManager(opts interface{}) *ArbRollupCoreInterface_ChallengeManager_Call { + return &ArbRollupCoreInterface_ChallengeManager_Call{Call: _e.mock.On("ChallengeManager", opts)} +} + +func (_c *ArbRollupCoreInterface_ChallengeManager_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_ChallengeManager_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ChallengeManager_Call) Return(_a0 common.Address, _a1 error) *ArbRollupCoreInterface_ChallengeManager_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ChallengeManager_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *ArbRollupCoreInterface_ChallengeManager_Call { + _c.Call.Return(run) + return _c +} + +// ConfirmPeriodBlocks provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) ConfirmPeriodBlocks(opts *bind.CallOpts) (uint64, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for ConfirmPeriodBlocks") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (uint64, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) uint64); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ConfirmPeriodBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ConfirmPeriodBlocks' +type ArbRollupCoreInterface_ConfirmPeriodBlocks_Call struct { + *mock.Call +} + +// ConfirmPeriodBlocks is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) ConfirmPeriodBlocks(opts interface{}) *ArbRollupCoreInterface_ConfirmPeriodBlocks_Call { + return &ArbRollupCoreInterface_ConfirmPeriodBlocks_Call{Call: _e.mock.On("ConfirmPeriodBlocks", opts)} +} + +func (_c *ArbRollupCoreInterface_ConfirmPeriodBlocks_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_ConfirmPeriodBlocks_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ConfirmPeriodBlocks_Call) Return(_a0 uint64, _a1 error) *ArbRollupCoreInterface_ConfirmPeriodBlocks_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ConfirmPeriodBlocks_Call) RunAndReturn(run func(*bind.CallOpts) (uint64, error)) *ArbRollupCoreInterface_ConfirmPeriodBlocks_Call { + _c.Call.Return(run) + return _c +} + +// CurrentChallenge provides a mock function with given fields: opts, staker +func (_m *ArbRollupCoreInterface) CurrentChallenge(opts *bind.CallOpts, staker common.Address) (uint64, error) { + ret := _m.Called(opts, staker) + + if len(ret) == 0 { + panic("no return value specified for CurrentChallenge") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (uint64, error)); ok { + return rf(opts, staker) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) uint64); ok { + r0 = rf(opts, staker) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, staker) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_CurrentChallenge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CurrentChallenge' +type ArbRollupCoreInterface_CurrentChallenge_Call struct { + *mock.Call +} + +// CurrentChallenge is a helper method to define mock.On call +// - opts *bind.CallOpts +// - staker common.Address +func (_e *ArbRollupCoreInterface_Expecter) CurrentChallenge(opts interface{}, staker interface{}) *ArbRollupCoreInterface_CurrentChallenge_Call { + return &ArbRollupCoreInterface_CurrentChallenge_Call{Call: _e.mock.On("CurrentChallenge", opts, staker)} +} + +func (_c *ArbRollupCoreInterface_CurrentChallenge_Call) Run(run func(opts *bind.CallOpts, staker common.Address)) *ArbRollupCoreInterface_CurrentChallenge_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_CurrentChallenge_Call) Return(_a0 uint64, _a1 error) *ArbRollupCoreInterface_CurrentChallenge_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_CurrentChallenge_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (uint64, error)) *ArbRollupCoreInterface_CurrentChallenge_Call { + _c.Call.Return(run) + return _c +} + +// ExtraChallengeTimeBlocks provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) ExtraChallengeTimeBlocks(opts *bind.CallOpts) (uint64, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for ExtraChallengeTimeBlocks") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (uint64, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) uint64); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ExtraChallengeTimeBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExtraChallengeTimeBlocks' +type ArbRollupCoreInterface_ExtraChallengeTimeBlocks_Call struct { + *mock.Call +} + +// ExtraChallengeTimeBlocks is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) ExtraChallengeTimeBlocks(opts interface{}) *ArbRollupCoreInterface_ExtraChallengeTimeBlocks_Call { + return &ArbRollupCoreInterface_ExtraChallengeTimeBlocks_Call{Call: _e.mock.On("ExtraChallengeTimeBlocks", opts)} +} + +func (_c *ArbRollupCoreInterface_ExtraChallengeTimeBlocks_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_ExtraChallengeTimeBlocks_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ExtraChallengeTimeBlocks_Call) Return(_a0 uint64, _a1 error) *ArbRollupCoreInterface_ExtraChallengeTimeBlocks_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ExtraChallengeTimeBlocks_Call) RunAndReturn(run func(*bind.CallOpts) (uint64, error)) *ArbRollupCoreInterface_ExtraChallengeTimeBlocks_Call { + _c.Call.Return(run) + return _c +} + +// FilterNodeConfirmed provides a mock function with given fields: opts, nodeNum +func (_m *ArbRollupCoreInterface) FilterNodeConfirmed(opts *bind.FilterOpts, nodeNum []uint64) (*arbitrum_rollup_core.ArbRollupCoreNodeConfirmedIterator, error) { + ret := _m.Called(opts, nodeNum) + + if len(ret) == 0 { + panic("no return value specified for FilterNodeConfirmed") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreNodeConfirmedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*arbitrum_rollup_core.ArbRollupCoreNodeConfirmedIterator, error)); ok { + return rf(opts, nodeNum) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *arbitrum_rollup_core.ArbRollupCoreNodeConfirmedIterator); ok { + r0 = rf(opts, nodeNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreNodeConfirmedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { + r1 = rf(opts, nodeNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_FilterNodeConfirmed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterNodeConfirmed' +type ArbRollupCoreInterface_FilterNodeConfirmed_Call struct { + *mock.Call +} + +// FilterNodeConfirmed is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - nodeNum []uint64 +func (_e *ArbRollupCoreInterface_Expecter) FilterNodeConfirmed(opts interface{}, nodeNum interface{}) *ArbRollupCoreInterface_FilterNodeConfirmed_Call { + return &ArbRollupCoreInterface_FilterNodeConfirmed_Call{Call: _e.mock.On("FilterNodeConfirmed", opts, nodeNum)} +} + +func (_c *ArbRollupCoreInterface_FilterNodeConfirmed_Call) Run(run func(opts *bind.FilterOpts, nodeNum []uint64)) *ArbRollupCoreInterface_FilterNodeConfirmed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterNodeConfirmed_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreNodeConfirmedIterator, _a1 error) *ArbRollupCoreInterface_FilterNodeConfirmed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterNodeConfirmed_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*arbitrum_rollup_core.ArbRollupCoreNodeConfirmedIterator, error)) *ArbRollupCoreInterface_FilterNodeConfirmed_Call { + _c.Call.Return(run) + return _c +} + +// FilterNodeCreated provides a mock function with given fields: opts, nodeNum, parentNodeHash, nodeHash +func (_m *ArbRollupCoreInterface) FilterNodeCreated(opts *bind.FilterOpts, nodeNum []uint64, parentNodeHash [][32]byte, nodeHash [][32]byte) (*arbitrum_rollup_core.ArbRollupCoreNodeCreatedIterator, error) { + ret := _m.Called(opts, nodeNum, parentNodeHash, nodeHash) + + if len(ret) == 0 { + panic("no return value specified for FilterNodeCreated") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreNodeCreatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, [][32]byte, [][32]byte) (*arbitrum_rollup_core.ArbRollupCoreNodeCreatedIterator, error)); ok { + return rf(opts, nodeNum, parentNodeHash, nodeHash) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, [][32]byte, [][32]byte) *arbitrum_rollup_core.ArbRollupCoreNodeCreatedIterator); ok { + r0 = rf(opts, nodeNum, parentNodeHash, nodeHash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreNodeCreatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, [][32]byte, [][32]byte) error); ok { + r1 = rf(opts, nodeNum, parentNodeHash, nodeHash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_FilterNodeCreated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterNodeCreated' +type ArbRollupCoreInterface_FilterNodeCreated_Call struct { + *mock.Call +} + +// FilterNodeCreated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - nodeNum []uint64 +// - parentNodeHash [][32]byte +// - nodeHash [][32]byte +func (_e *ArbRollupCoreInterface_Expecter) FilterNodeCreated(opts interface{}, nodeNum interface{}, parentNodeHash interface{}, nodeHash interface{}) *ArbRollupCoreInterface_FilterNodeCreated_Call { + return &ArbRollupCoreInterface_FilterNodeCreated_Call{Call: _e.mock.On("FilterNodeCreated", opts, nodeNum, parentNodeHash, nodeHash)} +} + +func (_c *ArbRollupCoreInterface_FilterNodeCreated_Call) Run(run func(opts *bind.FilterOpts, nodeNum []uint64, parentNodeHash [][32]byte, nodeHash [][32]byte)) *ArbRollupCoreInterface_FilterNodeCreated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([][32]byte), args[3].([][32]byte)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterNodeCreated_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreNodeCreatedIterator, _a1 error) *ArbRollupCoreInterface_FilterNodeCreated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterNodeCreated_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, [][32]byte, [][32]byte) (*arbitrum_rollup_core.ArbRollupCoreNodeCreatedIterator, error)) *ArbRollupCoreInterface_FilterNodeCreated_Call { + _c.Call.Return(run) + return _c +} + +// FilterNodeRejected provides a mock function with given fields: opts, nodeNum +func (_m *ArbRollupCoreInterface) FilterNodeRejected(opts *bind.FilterOpts, nodeNum []uint64) (*arbitrum_rollup_core.ArbRollupCoreNodeRejectedIterator, error) { + ret := _m.Called(opts, nodeNum) + + if len(ret) == 0 { + panic("no return value specified for FilterNodeRejected") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreNodeRejectedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*arbitrum_rollup_core.ArbRollupCoreNodeRejectedIterator, error)); ok { + return rf(opts, nodeNum) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *arbitrum_rollup_core.ArbRollupCoreNodeRejectedIterator); ok { + r0 = rf(opts, nodeNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreNodeRejectedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { + r1 = rf(opts, nodeNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_FilterNodeRejected_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterNodeRejected' +type ArbRollupCoreInterface_FilterNodeRejected_Call struct { + *mock.Call +} + +// FilterNodeRejected is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - nodeNum []uint64 +func (_e *ArbRollupCoreInterface_Expecter) FilterNodeRejected(opts interface{}, nodeNum interface{}) *ArbRollupCoreInterface_FilterNodeRejected_Call { + return &ArbRollupCoreInterface_FilterNodeRejected_Call{Call: _e.mock.On("FilterNodeRejected", opts, nodeNum)} +} + +func (_c *ArbRollupCoreInterface_FilterNodeRejected_Call) Run(run func(opts *bind.FilterOpts, nodeNum []uint64)) *ArbRollupCoreInterface_FilterNodeRejected_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterNodeRejected_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreNodeRejectedIterator, _a1 error) *ArbRollupCoreInterface_FilterNodeRejected_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterNodeRejected_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*arbitrum_rollup_core.ArbRollupCoreNodeRejectedIterator, error)) *ArbRollupCoreInterface_FilterNodeRejected_Call { + _c.Call.Return(run) + return _c +} + +// FilterRollupChallengeStarted provides a mock function with given fields: opts, challengeIndex +func (_m *ArbRollupCoreInterface) FilterRollupChallengeStarted(opts *bind.FilterOpts, challengeIndex []uint64) (*arbitrum_rollup_core.ArbRollupCoreRollupChallengeStartedIterator, error) { + ret := _m.Called(opts, challengeIndex) + + if len(ret) == 0 { + panic("no return value specified for FilterRollupChallengeStarted") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStartedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*arbitrum_rollup_core.ArbRollupCoreRollupChallengeStartedIterator, error)); ok { + return rf(opts, challengeIndex) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStartedIterator); ok { + r0 = rf(opts, challengeIndex) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreRollupChallengeStartedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { + r1 = rf(opts, challengeIndex) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_FilterRollupChallengeStarted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterRollupChallengeStarted' +type ArbRollupCoreInterface_FilterRollupChallengeStarted_Call struct { + *mock.Call +} + +// FilterRollupChallengeStarted is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - challengeIndex []uint64 +func (_e *ArbRollupCoreInterface_Expecter) FilterRollupChallengeStarted(opts interface{}, challengeIndex interface{}) *ArbRollupCoreInterface_FilterRollupChallengeStarted_Call { + return &ArbRollupCoreInterface_FilterRollupChallengeStarted_Call{Call: _e.mock.On("FilterRollupChallengeStarted", opts, challengeIndex)} +} + +func (_c *ArbRollupCoreInterface_FilterRollupChallengeStarted_Call) Run(run func(opts *bind.FilterOpts, challengeIndex []uint64)) *ArbRollupCoreInterface_FilterRollupChallengeStarted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterRollupChallengeStarted_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStartedIterator, _a1 error) *ArbRollupCoreInterface_FilterRollupChallengeStarted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterRollupChallengeStarted_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*arbitrum_rollup_core.ArbRollupCoreRollupChallengeStartedIterator, error)) *ArbRollupCoreInterface_FilterRollupChallengeStarted_Call { + _c.Call.Return(run) + return _c +} + +// FilterRollupInitialized provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) FilterRollupInitialized(opts *bind.FilterOpts) (*arbitrum_rollup_core.ArbRollupCoreRollupInitializedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterRollupInitialized") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreRollupInitializedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*arbitrum_rollup_core.ArbRollupCoreRollupInitializedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *arbitrum_rollup_core.ArbRollupCoreRollupInitializedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreRollupInitializedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_FilterRollupInitialized_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterRollupInitialized' +type ArbRollupCoreInterface_FilterRollupInitialized_Call struct { + *mock.Call +} + +// FilterRollupInitialized is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *ArbRollupCoreInterface_Expecter) FilterRollupInitialized(opts interface{}) *ArbRollupCoreInterface_FilterRollupInitialized_Call { + return &ArbRollupCoreInterface_FilterRollupInitialized_Call{Call: _e.mock.On("FilterRollupInitialized", opts)} +} + +func (_c *ArbRollupCoreInterface_FilterRollupInitialized_Call) Run(run func(opts *bind.FilterOpts)) *ArbRollupCoreInterface_FilterRollupInitialized_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterRollupInitialized_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreRollupInitializedIterator, _a1 error) *ArbRollupCoreInterface_FilterRollupInitialized_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterRollupInitialized_Call) RunAndReturn(run func(*bind.FilterOpts) (*arbitrum_rollup_core.ArbRollupCoreRollupInitializedIterator, error)) *ArbRollupCoreInterface_FilterRollupInitialized_Call { + _c.Call.Return(run) + return _c +} + +// FilterUserStakeUpdated provides a mock function with given fields: opts, user +func (_m *ArbRollupCoreInterface) FilterUserStakeUpdated(opts *bind.FilterOpts, user []common.Address) (*arbitrum_rollup_core.ArbRollupCoreUserStakeUpdatedIterator, error) { + ret := _m.Called(opts, user) + + if len(ret) == 0 { + panic("no return value specified for FilterUserStakeUpdated") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*arbitrum_rollup_core.ArbRollupCoreUserStakeUpdatedIterator, error)); ok { + return rf(opts, user) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdatedIterator); ok { + r0 = rf(opts, user) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreUserStakeUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, user) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_FilterUserStakeUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterUserStakeUpdated' +type ArbRollupCoreInterface_FilterUserStakeUpdated_Call struct { + *mock.Call +} + +// FilterUserStakeUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - user []common.Address +func (_e *ArbRollupCoreInterface_Expecter) FilterUserStakeUpdated(opts interface{}, user interface{}) *ArbRollupCoreInterface_FilterUserStakeUpdated_Call { + return &ArbRollupCoreInterface_FilterUserStakeUpdated_Call{Call: _e.mock.On("FilterUserStakeUpdated", opts, user)} +} + +func (_c *ArbRollupCoreInterface_FilterUserStakeUpdated_Call) Run(run func(opts *bind.FilterOpts, user []common.Address)) *ArbRollupCoreInterface_FilterUserStakeUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterUserStakeUpdated_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdatedIterator, _a1 error) *ArbRollupCoreInterface_FilterUserStakeUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterUserStakeUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*arbitrum_rollup_core.ArbRollupCoreUserStakeUpdatedIterator, error)) *ArbRollupCoreInterface_FilterUserStakeUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FilterUserWithdrawableFundsUpdated provides a mock function with given fields: opts, user +func (_m *ArbRollupCoreInterface) FilterUserWithdrawableFundsUpdated(opts *bind.FilterOpts, user []common.Address) (*arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdatedIterator, error) { + ret := _m.Called(opts, user) + + if len(ret) == 0 { + panic("no return value specified for FilterUserWithdrawableFundsUpdated") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdatedIterator, error)); ok { + return rf(opts, user) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdatedIterator); ok { + r0 = rf(opts, user) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, user) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_FilterUserWithdrawableFundsUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterUserWithdrawableFundsUpdated' +type ArbRollupCoreInterface_FilterUserWithdrawableFundsUpdated_Call struct { + *mock.Call +} + +// FilterUserWithdrawableFundsUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - user []common.Address +func (_e *ArbRollupCoreInterface_Expecter) FilterUserWithdrawableFundsUpdated(opts interface{}, user interface{}) *ArbRollupCoreInterface_FilterUserWithdrawableFundsUpdated_Call { + return &ArbRollupCoreInterface_FilterUserWithdrawableFundsUpdated_Call{Call: _e.mock.On("FilterUserWithdrawableFundsUpdated", opts, user)} +} + +func (_c *ArbRollupCoreInterface_FilterUserWithdrawableFundsUpdated_Call) Run(run func(opts *bind.FilterOpts, user []common.Address)) *ArbRollupCoreInterface_FilterUserWithdrawableFundsUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterUserWithdrawableFundsUpdated_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdatedIterator, _a1 error) *ArbRollupCoreInterface_FilterUserWithdrawableFundsUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_FilterUserWithdrawableFundsUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdatedIterator, error)) *ArbRollupCoreInterface_FilterUserWithdrawableFundsUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FirstUnresolvedNode provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) FirstUnresolvedNode(opts *bind.CallOpts) (uint64, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FirstUnresolvedNode") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (uint64, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) uint64); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_FirstUnresolvedNode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FirstUnresolvedNode' +type ArbRollupCoreInterface_FirstUnresolvedNode_Call struct { + *mock.Call +} + +// FirstUnresolvedNode is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) FirstUnresolvedNode(opts interface{}) *ArbRollupCoreInterface_FirstUnresolvedNode_Call { + return &ArbRollupCoreInterface_FirstUnresolvedNode_Call{Call: _e.mock.On("FirstUnresolvedNode", opts)} +} + +func (_c *ArbRollupCoreInterface_FirstUnresolvedNode_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_FirstUnresolvedNode_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_FirstUnresolvedNode_Call) Return(_a0 uint64, _a1 error) *ArbRollupCoreInterface_FirstUnresolvedNode_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_FirstUnresolvedNode_Call) RunAndReturn(run func(*bind.CallOpts) (uint64, error)) *ArbRollupCoreInterface_FirstUnresolvedNode_Call { + _c.Call.Return(run) + return _c +} + +// GetNode provides a mock function with given fields: opts, nodeNum +func (_m *ArbRollupCoreInterface) GetNode(opts *bind.CallOpts, nodeNum uint64) (arbitrum_rollup_core.Node, error) { + ret := _m.Called(opts, nodeNum) + + if len(ret) == 0 { + panic("no return value specified for GetNode") + } + + var r0 arbitrum_rollup_core.Node + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (arbitrum_rollup_core.Node, error)); ok { + return rf(opts, nodeNum) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) arbitrum_rollup_core.Node); ok { + r0 = rf(opts, nodeNum) + } else { + r0 = ret.Get(0).(arbitrum_rollup_core.Node) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, nodeNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_GetNode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetNode' +type ArbRollupCoreInterface_GetNode_Call struct { + *mock.Call +} + +// GetNode is a helper method to define mock.On call +// - opts *bind.CallOpts +// - nodeNum uint64 +func (_e *ArbRollupCoreInterface_Expecter) GetNode(opts interface{}, nodeNum interface{}) *ArbRollupCoreInterface_GetNode_Call { + return &ArbRollupCoreInterface_GetNode_Call{Call: _e.mock.On("GetNode", opts, nodeNum)} +} + +func (_c *ArbRollupCoreInterface_GetNode_Call) Run(run func(opts *bind.CallOpts, nodeNum uint64)) *ArbRollupCoreInterface_GetNode_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_GetNode_Call) Return(_a0 arbitrum_rollup_core.Node, _a1 error) *ArbRollupCoreInterface_GetNode_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_GetNode_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (arbitrum_rollup_core.Node, error)) *ArbRollupCoreInterface_GetNode_Call { + _c.Call.Return(run) + return _c +} + +// GetNodeCreationBlockForLogLookup provides a mock function with given fields: opts, nodeNum +func (_m *ArbRollupCoreInterface) GetNodeCreationBlockForLogLookup(opts *bind.CallOpts, nodeNum uint64) (*big.Int, error) { + ret := _m.Called(opts, nodeNum) + + if len(ret) == 0 { + panic("no return value specified for GetNodeCreationBlockForLogLookup") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (*big.Int, error)); ok { + return rf(opts, nodeNum) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) *big.Int); ok { + r0 = rf(opts, nodeNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, nodeNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_GetNodeCreationBlockForLogLookup_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetNodeCreationBlockForLogLookup' +type ArbRollupCoreInterface_GetNodeCreationBlockForLogLookup_Call struct { + *mock.Call +} + +// GetNodeCreationBlockForLogLookup is a helper method to define mock.On call +// - opts *bind.CallOpts +// - nodeNum uint64 +func (_e *ArbRollupCoreInterface_Expecter) GetNodeCreationBlockForLogLookup(opts interface{}, nodeNum interface{}) *ArbRollupCoreInterface_GetNodeCreationBlockForLogLookup_Call { + return &ArbRollupCoreInterface_GetNodeCreationBlockForLogLookup_Call{Call: _e.mock.On("GetNodeCreationBlockForLogLookup", opts, nodeNum)} +} + +func (_c *ArbRollupCoreInterface_GetNodeCreationBlockForLogLookup_Call) Run(run func(opts *bind.CallOpts, nodeNum uint64)) *ArbRollupCoreInterface_GetNodeCreationBlockForLogLookup_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_GetNodeCreationBlockForLogLookup_Call) Return(_a0 *big.Int, _a1 error) *ArbRollupCoreInterface_GetNodeCreationBlockForLogLookup_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_GetNodeCreationBlockForLogLookup_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (*big.Int, error)) *ArbRollupCoreInterface_GetNodeCreationBlockForLogLookup_Call { + _c.Call.Return(run) + return _c +} + +// GetStaker provides a mock function with given fields: opts, staker +func (_m *ArbRollupCoreInterface) GetStaker(opts *bind.CallOpts, staker common.Address) (arbitrum_rollup_core.IRollupCoreStaker, error) { + ret := _m.Called(opts, staker) + + if len(ret) == 0 { + panic("no return value specified for GetStaker") + } + + var r0 arbitrum_rollup_core.IRollupCoreStaker + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (arbitrum_rollup_core.IRollupCoreStaker, error)); ok { + return rf(opts, staker) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) arbitrum_rollup_core.IRollupCoreStaker); ok { + r0 = rf(opts, staker) + } else { + r0 = ret.Get(0).(arbitrum_rollup_core.IRollupCoreStaker) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, staker) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_GetStaker_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStaker' +type ArbRollupCoreInterface_GetStaker_Call struct { + *mock.Call +} + +// GetStaker is a helper method to define mock.On call +// - opts *bind.CallOpts +// - staker common.Address +func (_e *ArbRollupCoreInterface_Expecter) GetStaker(opts interface{}, staker interface{}) *ArbRollupCoreInterface_GetStaker_Call { + return &ArbRollupCoreInterface_GetStaker_Call{Call: _e.mock.On("GetStaker", opts, staker)} +} + +func (_c *ArbRollupCoreInterface_GetStaker_Call) Run(run func(opts *bind.CallOpts, staker common.Address)) *ArbRollupCoreInterface_GetStaker_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_GetStaker_Call) Return(_a0 arbitrum_rollup_core.IRollupCoreStaker, _a1 error) *ArbRollupCoreInterface_GetStaker_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_GetStaker_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (arbitrum_rollup_core.IRollupCoreStaker, error)) *ArbRollupCoreInterface_GetStaker_Call { + _c.Call.Return(run) + return _c +} + +// GetStakerAddress provides a mock function with given fields: opts, stakerNum +func (_m *ArbRollupCoreInterface) GetStakerAddress(opts *bind.CallOpts, stakerNum uint64) (common.Address, error) { + ret := _m.Called(opts, stakerNum) + + if len(ret) == 0 { + panic("no return value specified for GetStakerAddress") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (common.Address, error)); ok { + return rf(opts, stakerNum) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) common.Address); ok { + r0 = rf(opts, stakerNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, stakerNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_GetStakerAddress_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStakerAddress' +type ArbRollupCoreInterface_GetStakerAddress_Call struct { + *mock.Call +} + +// GetStakerAddress is a helper method to define mock.On call +// - opts *bind.CallOpts +// - stakerNum uint64 +func (_e *ArbRollupCoreInterface_Expecter) GetStakerAddress(opts interface{}, stakerNum interface{}) *ArbRollupCoreInterface_GetStakerAddress_Call { + return &ArbRollupCoreInterface_GetStakerAddress_Call{Call: _e.mock.On("GetStakerAddress", opts, stakerNum)} +} + +func (_c *ArbRollupCoreInterface_GetStakerAddress_Call) Run(run func(opts *bind.CallOpts, stakerNum uint64)) *ArbRollupCoreInterface_GetStakerAddress_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_GetStakerAddress_Call) Return(_a0 common.Address, _a1 error) *ArbRollupCoreInterface_GetStakerAddress_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_GetStakerAddress_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (common.Address, error)) *ArbRollupCoreInterface_GetStakerAddress_Call { + _c.Call.Return(run) + return _c +} + +// IsStaked provides a mock function with given fields: opts, staker +func (_m *ArbRollupCoreInterface) IsStaked(opts *bind.CallOpts, staker common.Address) (bool, error) { + ret := _m.Called(opts, staker) + + if len(ret) == 0 { + panic("no return value specified for IsStaked") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (bool, error)); ok { + return rf(opts, staker) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) bool); ok { + r0 = rf(opts, staker) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, staker) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_IsStaked_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsStaked' +type ArbRollupCoreInterface_IsStaked_Call struct { + *mock.Call +} + +// IsStaked is a helper method to define mock.On call +// - opts *bind.CallOpts +// - staker common.Address +func (_e *ArbRollupCoreInterface_Expecter) IsStaked(opts interface{}, staker interface{}) *ArbRollupCoreInterface_IsStaked_Call { + return &ArbRollupCoreInterface_IsStaked_Call{Call: _e.mock.On("IsStaked", opts, staker)} +} + +func (_c *ArbRollupCoreInterface_IsStaked_Call) Run(run func(opts *bind.CallOpts, staker common.Address)) *ArbRollupCoreInterface_IsStaked_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_IsStaked_Call) Return(_a0 bool, _a1 error) *ArbRollupCoreInterface_IsStaked_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_IsStaked_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (bool, error)) *ArbRollupCoreInterface_IsStaked_Call { + _c.Call.Return(run) + return _c +} + +// IsValidator provides a mock function with given fields: opts, arg0 +func (_m *ArbRollupCoreInterface) IsValidator(opts *bind.CallOpts, arg0 common.Address) (bool, error) { + ret := _m.Called(opts, arg0) + + if len(ret) == 0 { + panic("no return value specified for IsValidator") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (bool, error)); ok { + return rf(opts, arg0) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) bool); ok { + r0 = rf(opts, arg0) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, arg0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_IsValidator_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsValidator' +type ArbRollupCoreInterface_IsValidator_Call struct { + *mock.Call +} + +// IsValidator is a helper method to define mock.On call +// - opts *bind.CallOpts +// - arg0 common.Address +func (_e *ArbRollupCoreInterface_Expecter) IsValidator(opts interface{}, arg0 interface{}) *ArbRollupCoreInterface_IsValidator_Call { + return &ArbRollupCoreInterface_IsValidator_Call{Call: _e.mock.On("IsValidator", opts, arg0)} +} + +func (_c *ArbRollupCoreInterface_IsValidator_Call) Run(run func(opts *bind.CallOpts, arg0 common.Address)) *ArbRollupCoreInterface_IsValidator_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_IsValidator_Call) Return(_a0 bool, _a1 error) *ArbRollupCoreInterface_IsValidator_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_IsValidator_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (bool, error)) *ArbRollupCoreInterface_IsValidator_Call { + _c.Call.Return(run) + return _c +} + +// IsZombie provides a mock function with given fields: opts, staker +func (_m *ArbRollupCoreInterface) IsZombie(opts *bind.CallOpts, staker common.Address) (bool, error) { + ret := _m.Called(opts, staker) + + if len(ret) == 0 { + panic("no return value specified for IsZombie") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (bool, error)); ok { + return rf(opts, staker) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) bool); ok { + r0 = rf(opts, staker) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, staker) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_IsZombie_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsZombie' +type ArbRollupCoreInterface_IsZombie_Call struct { + *mock.Call +} + +// IsZombie is a helper method to define mock.On call +// - opts *bind.CallOpts +// - staker common.Address +func (_e *ArbRollupCoreInterface_Expecter) IsZombie(opts interface{}, staker interface{}) *ArbRollupCoreInterface_IsZombie_Call { + return &ArbRollupCoreInterface_IsZombie_Call{Call: _e.mock.On("IsZombie", opts, staker)} +} + +func (_c *ArbRollupCoreInterface_IsZombie_Call) Run(run func(opts *bind.CallOpts, staker common.Address)) *ArbRollupCoreInterface_IsZombie_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_IsZombie_Call) Return(_a0 bool, _a1 error) *ArbRollupCoreInterface_IsZombie_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_IsZombie_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (bool, error)) *ArbRollupCoreInterface_IsZombie_Call { + _c.Call.Return(run) + return _c +} + +// LastStakeBlock provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) LastStakeBlock(opts *bind.CallOpts) (uint64, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LastStakeBlock") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (uint64, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) uint64); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_LastStakeBlock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LastStakeBlock' +type ArbRollupCoreInterface_LastStakeBlock_Call struct { + *mock.Call +} + +// LastStakeBlock is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) LastStakeBlock(opts interface{}) *ArbRollupCoreInterface_LastStakeBlock_Call { + return &ArbRollupCoreInterface_LastStakeBlock_Call{Call: _e.mock.On("LastStakeBlock", opts)} +} + +func (_c *ArbRollupCoreInterface_LastStakeBlock_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_LastStakeBlock_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_LastStakeBlock_Call) Return(_a0 uint64, _a1 error) *ArbRollupCoreInterface_LastStakeBlock_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_LastStakeBlock_Call) RunAndReturn(run func(*bind.CallOpts) (uint64, error)) *ArbRollupCoreInterface_LastStakeBlock_Call { + _c.Call.Return(run) + return _c +} + +// LatestConfirmed provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) LatestConfirmed(opts *bind.CallOpts) (uint64, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LatestConfirmed") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (uint64, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) uint64); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_LatestConfirmed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestConfirmed' +type ArbRollupCoreInterface_LatestConfirmed_Call struct { + *mock.Call +} + +// LatestConfirmed is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) LatestConfirmed(opts interface{}) *ArbRollupCoreInterface_LatestConfirmed_Call { + return &ArbRollupCoreInterface_LatestConfirmed_Call{Call: _e.mock.On("LatestConfirmed", opts)} +} + +func (_c *ArbRollupCoreInterface_LatestConfirmed_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_LatestConfirmed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_LatestConfirmed_Call) Return(_a0 uint64, _a1 error) *ArbRollupCoreInterface_LatestConfirmed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_LatestConfirmed_Call) RunAndReturn(run func(*bind.CallOpts) (uint64, error)) *ArbRollupCoreInterface_LatestConfirmed_Call { + _c.Call.Return(run) + return _c +} + +// LatestNodeCreated provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) LatestNodeCreated(opts *bind.CallOpts) (uint64, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LatestNodeCreated") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (uint64, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) uint64); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_LatestNodeCreated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestNodeCreated' +type ArbRollupCoreInterface_LatestNodeCreated_Call struct { + *mock.Call +} + +// LatestNodeCreated is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) LatestNodeCreated(opts interface{}) *ArbRollupCoreInterface_LatestNodeCreated_Call { + return &ArbRollupCoreInterface_LatestNodeCreated_Call{Call: _e.mock.On("LatestNodeCreated", opts)} +} + +func (_c *ArbRollupCoreInterface_LatestNodeCreated_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_LatestNodeCreated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_LatestNodeCreated_Call) Return(_a0 uint64, _a1 error) *ArbRollupCoreInterface_LatestNodeCreated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_LatestNodeCreated_Call) RunAndReturn(run func(*bind.CallOpts) (uint64, error)) *ArbRollupCoreInterface_LatestNodeCreated_Call { + _c.Call.Return(run) + return _c +} + +// LatestStakedNode provides a mock function with given fields: opts, staker +func (_m *ArbRollupCoreInterface) LatestStakedNode(opts *bind.CallOpts, staker common.Address) (uint64, error) { + ret := _m.Called(opts, staker) + + if len(ret) == 0 { + panic("no return value specified for LatestStakedNode") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (uint64, error)); ok { + return rf(opts, staker) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) uint64); ok { + r0 = rf(opts, staker) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, staker) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_LatestStakedNode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestStakedNode' +type ArbRollupCoreInterface_LatestStakedNode_Call struct { + *mock.Call +} + +// LatestStakedNode is a helper method to define mock.On call +// - opts *bind.CallOpts +// - staker common.Address +func (_e *ArbRollupCoreInterface_Expecter) LatestStakedNode(opts interface{}, staker interface{}) *ArbRollupCoreInterface_LatestStakedNode_Call { + return &ArbRollupCoreInterface_LatestStakedNode_Call{Call: _e.mock.On("LatestStakedNode", opts, staker)} +} + +func (_c *ArbRollupCoreInterface_LatestStakedNode_Call) Run(run func(opts *bind.CallOpts, staker common.Address)) *ArbRollupCoreInterface_LatestStakedNode_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_LatestStakedNode_Call) Return(_a0 uint64, _a1 error) *ArbRollupCoreInterface_LatestStakedNode_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_LatestStakedNode_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (uint64, error)) *ArbRollupCoreInterface_LatestStakedNode_Call { + _c.Call.Return(run) + return _c +} + +// LoserStakeEscrow provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) LoserStakeEscrow(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for LoserStakeEscrow") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_LoserStakeEscrow_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoserStakeEscrow' +type ArbRollupCoreInterface_LoserStakeEscrow_Call struct { + *mock.Call +} + +// LoserStakeEscrow is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) LoserStakeEscrow(opts interface{}) *ArbRollupCoreInterface_LoserStakeEscrow_Call { + return &ArbRollupCoreInterface_LoserStakeEscrow_Call{Call: _e.mock.On("LoserStakeEscrow", opts)} +} + +func (_c *ArbRollupCoreInterface_LoserStakeEscrow_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_LoserStakeEscrow_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_LoserStakeEscrow_Call) Return(_a0 common.Address, _a1 error) *ArbRollupCoreInterface_LoserStakeEscrow_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_LoserStakeEscrow_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *ArbRollupCoreInterface_LoserStakeEscrow_Call { + _c.Call.Return(run) + return _c +} + +// MinimumAssertionPeriod provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) MinimumAssertionPeriod(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for MinimumAssertionPeriod") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_MinimumAssertionPeriod_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MinimumAssertionPeriod' +type ArbRollupCoreInterface_MinimumAssertionPeriod_Call struct { + *mock.Call +} + +// MinimumAssertionPeriod is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) MinimumAssertionPeriod(opts interface{}) *ArbRollupCoreInterface_MinimumAssertionPeriod_Call { + return &ArbRollupCoreInterface_MinimumAssertionPeriod_Call{Call: _e.mock.On("MinimumAssertionPeriod", opts)} +} + +func (_c *ArbRollupCoreInterface_MinimumAssertionPeriod_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_MinimumAssertionPeriod_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_MinimumAssertionPeriod_Call) Return(_a0 *big.Int, _a1 error) *ArbRollupCoreInterface_MinimumAssertionPeriod_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_MinimumAssertionPeriod_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *ArbRollupCoreInterface_MinimumAssertionPeriod_Call { + _c.Call.Return(run) + return _c +} + +// NodeHasStaker provides a mock function with given fields: opts, nodeNum, staker +func (_m *ArbRollupCoreInterface) NodeHasStaker(opts *bind.CallOpts, nodeNum uint64, staker common.Address) (bool, error) { + ret := _m.Called(opts, nodeNum, staker) + + if len(ret) == 0 { + panic("no return value specified for NodeHasStaker") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address) (bool, error)); ok { + return rf(opts, nodeNum, staker) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address) bool); ok { + r0 = rf(opts, nodeNum, staker) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, common.Address) error); ok { + r1 = rf(opts, nodeNum, staker) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_NodeHasStaker_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NodeHasStaker' +type ArbRollupCoreInterface_NodeHasStaker_Call struct { + *mock.Call +} + +// NodeHasStaker is a helper method to define mock.On call +// - opts *bind.CallOpts +// - nodeNum uint64 +// - staker common.Address +func (_e *ArbRollupCoreInterface_Expecter) NodeHasStaker(opts interface{}, nodeNum interface{}, staker interface{}) *ArbRollupCoreInterface_NodeHasStaker_Call { + return &ArbRollupCoreInterface_NodeHasStaker_Call{Call: _e.mock.On("NodeHasStaker", opts, nodeNum, staker)} +} + +func (_c *ArbRollupCoreInterface_NodeHasStaker_Call) Run(run func(opts *bind.CallOpts, nodeNum uint64, staker common.Address)) *ArbRollupCoreInterface_NodeHasStaker_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_NodeHasStaker_Call) Return(_a0 bool, _a1 error) *ArbRollupCoreInterface_NodeHasStaker_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_NodeHasStaker_Call) RunAndReturn(run func(*bind.CallOpts, uint64, common.Address) (bool, error)) *ArbRollupCoreInterface_NodeHasStaker_Call { + _c.Call.Return(run) + return _c +} + +// Outbox provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) Outbox(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Outbox") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_Outbox_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Outbox' +type ArbRollupCoreInterface_Outbox_Call struct { + *mock.Call +} + +// Outbox is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) Outbox(opts interface{}) *ArbRollupCoreInterface_Outbox_Call { + return &ArbRollupCoreInterface_Outbox_Call{Call: _e.mock.On("Outbox", opts)} +} + +func (_c *ArbRollupCoreInterface_Outbox_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_Outbox_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_Outbox_Call) Return(_a0 common.Address, _a1 error) *ArbRollupCoreInterface_Outbox_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_Outbox_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *ArbRollupCoreInterface_Outbox_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *ArbRollupCoreInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type ArbRollupCoreInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *ArbRollupCoreInterface_Expecter) ParseLog(log interface{}) *ArbRollupCoreInterface_ParseLog_Call { + return &ArbRollupCoreInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *ArbRollupCoreInterface_ParseLog_Call) Run(run func(log types.Log)) *ArbRollupCoreInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *ArbRollupCoreInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *ArbRollupCoreInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseNodeConfirmed provides a mock function with given fields: log +func (_m *ArbRollupCoreInterface) ParseNodeConfirmed(log types.Log) (*arbitrum_rollup_core.ArbRollupCoreNodeConfirmed, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseNodeConfirmed") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreNodeConfirmed + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreNodeConfirmed, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbitrum_rollup_core.ArbRollupCoreNodeConfirmed); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreNodeConfirmed) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ParseNodeConfirmed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseNodeConfirmed' +type ArbRollupCoreInterface_ParseNodeConfirmed_Call struct { + *mock.Call +} + +// ParseNodeConfirmed is a helper method to define mock.On call +// - log types.Log +func (_e *ArbRollupCoreInterface_Expecter) ParseNodeConfirmed(log interface{}) *ArbRollupCoreInterface_ParseNodeConfirmed_Call { + return &ArbRollupCoreInterface_ParseNodeConfirmed_Call{Call: _e.mock.On("ParseNodeConfirmed", log)} +} + +func (_c *ArbRollupCoreInterface_ParseNodeConfirmed_Call) Run(run func(log types.Log)) *ArbRollupCoreInterface_ParseNodeConfirmed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseNodeConfirmed_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreNodeConfirmed, _a1 error) *ArbRollupCoreInterface_ParseNodeConfirmed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseNodeConfirmed_Call) RunAndReturn(run func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreNodeConfirmed, error)) *ArbRollupCoreInterface_ParseNodeConfirmed_Call { + _c.Call.Return(run) + return _c +} + +// ParseNodeCreated provides a mock function with given fields: log +func (_m *ArbRollupCoreInterface) ParseNodeCreated(log types.Log) (*arbitrum_rollup_core.ArbRollupCoreNodeCreated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseNodeCreated") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreNodeCreated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreNodeCreated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbitrum_rollup_core.ArbRollupCoreNodeCreated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreNodeCreated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ParseNodeCreated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseNodeCreated' +type ArbRollupCoreInterface_ParseNodeCreated_Call struct { + *mock.Call +} + +// ParseNodeCreated is a helper method to define mock.On call +// - log types.Log +func (_e *ArbRollupCoreInterface_Expecter) ParseNodeCreated(log interface{}) *ArbRollupCoreInterface_ParseNodeCreated_Call { + return &ArbRollupCoreInterface_ParseNodeCreated_Call{Call: _e.mock.On("ParseNodeCreated", log)} +} + +func (_c *ArbRollupCoreInterface_ParseNodeCreated_Call) Run(run func(log types.Log)) *ArbRollupCoreInterface_ParseNodeCreated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseNodeCreated_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreNodeCreated, _a1 error) *ArbRollupCoreInterface_ParseNodeCreated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseNodeCreated_Call) RunAndReturn(run func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreNodeCreated, error)) *ArbRollupCoreInterface_ParseNodeCreated_Call { + _c.Call.Return(run) + return _c +} + +// ParseNodeRejected provides a mock function with given fields: log +func (_m *ArbRollupCoreInterface) ParseNodeRejected(log types.Log) (*arbitrum_rollup_core.ArbRollupCoreNodeRejected, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseNodeRejected") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreNodeRejected + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreNodeRejected, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbitrum_rollup_core.ArbRollupCoreNodeRejected); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreNodeRejected) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ParseNodeRejected_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseNodeRejected' +type ArbRollupCoreInterface_ParseNodeRejected_Call struct { + *mock.Call +} + +// ParseNodeRejected is a helper method to define mock.On call +// - log types.Log +func (_e *ArbRollupCoreInterface_Expecter) ParseNodeRejected(log interface{}) *ArbRollupCoreInterface_ParseNodeRejected_Call { + return &ArbRollupCoreInterface_ParseNodeRejected_Call{Call: _e.mock.On("ParseNodeRejected", log)} +} + +func (_c *ArbRollupCoreInterface_ParseNodeRejected_Call) Run(run func(log types.Log)) *ArbRollupCoreInterface_ParseNodeRejected_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseNodeRejected_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreNodeRejected, _a1 error) *ArbRollupCoreInterface_ParseNodeRejected_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseNodeRejected_Call) RunAndReturn(run func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreNodeRejected, error)) *ArbRollupCoreInterface_ParseNodeRejected_Call { + _c.Call.Return(run) + return _c +} + +// ParseRollupChallengeStarted provides a mock function with given fields: log +func (_m *ArbRollupCoreInterface) ParseRollupChallengeStarted(log types.Log) (*arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseRollupChallengeStarted") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ParseRollupChallengeStarted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseRollupChallengeStarted' +type ArbRollupCoreInterface_ParseRollupChallengeStarted_Call struct { + *mock.Call +} + +// ParseRollupChallengeStarted is a helper method to define mock.On call +// - log types.Log +func (_e *ArbRollupCoreInterface_Expecter) ParseRollupChallengeStarted(log interface{}) *ArbRollupCoreInterface_ParseRollupChallengeStarted_Call { + return &ArbRollupCoreInterface_ParseRollupChallengeStarted_Call{Call: _e.mock.On("ParseRollupChallengeStarted", log)} +} + +func (_c *ArbRollupCoreInterface_ParseRollupChallengeStarted_Call) Run(run func(log types.Log)) *ArbRollupCoreInterface_ParseRollupChallengeStarted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseRollupChallengeStarted_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted, _a1 error) *ArbRollupCoreInterface_ParseRollupChallengeStarted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseRollupChallengeStarted_Call) RunAndReturn(run func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted, error)) *ArbRollupCoreInterface_ParseRollupChallengeStarted_Call { + _c.Call.Return(run) + return _c +} + +// ParseRollupInitialized provides a mock function with given fields: log +func (_m *ArbRollupCoreInterface) ParseRollupInitialized(log types.Log) (*arbitrum_rollup_core.ArbRollupCoreRollupInitialized, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseRollupInitialized") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreRollupInitialized + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreRollupInitialized, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbitrum_rollup_core.ArbRollupCoreRollupInitialized); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreRollupInitialized) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ParseRollupInitialized_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseRollupInitialized' +type ArbRollupCoreInterface_ParseRollupInitialized_Call struct { + *mock.Call +} + +// ParseRollupInitialized is a helper method to define mock.On call +// - log types.Log +func (_e *ArbRollupCoreInterface_Expecter) ParseRollupInitialized(log interface{}) *ArbRollupCoreInterface_ParseRollupInitialized_Call { + return &ArbRollupCoreInterface_ParseRollupInitialized_Call{Call: _e.mock.On("ParseRollupInitialized", log)} +} + +func (_c *ArbRollupCoreInterface_ParseRollupInitialized_Call) Run(run func(log types.Log)) *ArbRollupCoreInterface_ParseRollupInitialized_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseRollupInitialized_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreRollupInitialized, _a1 error) *ArbRollupCoreInterface_ParseRollupInitialized_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseRollupInitialized_Call) RunAndReturn(run func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreRollupInitialized, error)) *ArbRollupCoreInterface_ParseRollupInitialized_Call { + _c.Call.Return(run) + return _c +} + +// ParseUserStakeUpdated provides a mock function with given fields: log +func (_m *ArbRollupCoreInterface) ParseUserStakeUpdated(log types.Log) (*arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseUserStakeUpdated") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ParseUserStakeUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseUserStakeUpdated' +type ArbRollupCoreInterface_ParseUserStakeUpdated_Call struct { + *mock.Call +} + +// ParseUserStakeUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *ArbRollupCoreInterface_Expecter) ParseUserStakeUpdated(log interface{}) *ArbRollupCoreInterface_ParseUserStakeUpdated_Call { + return &ArbRollupCoreInterface_ParseUserStakeUpdated_Call{Call: _e.mock.On("ParseUserStakeUpdated", log)} +} + +func (_c *ArbRollupCoreInterface_ParseUserStakeUpdated_Call) Run(run func(log types.Log)) *ArbRollupCoreInterface_ParseUserStakeUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseUserStakeUpdated_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated, _a1 error) *ArbRollupCoreInterface_ParseUserStakeUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseUserStakeUpdated_Call) RunAndReturn(run func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated, error)) *ArbRollupCoreInterface_ParseUserStakeUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ParseUserWithdrawableFundsUpdated provides a mock function with given fields: log +func (_m *ArbRollupCoreInterface) ParseUserWithdrawableFundsUpdated(log types.Log) (*arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseUserWithdrawableFundsUpdated") + } + + var r0 *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ParseUserWithdrawableFundsUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseUserWithdrawableFundsUpdated' +type ArbRollupCoreInterface_ParseUserWithdrawableFundsUpdated_Call struct { + *mock.Call +} + +// ParseUserWithdrawableFundsUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *ArbRollupCoreInterface_Expecter) ParseUserWithdrawableFundsUpdated(log interface{}) *ArbRollupCoreInterface_ParseUserWithdrawableFundsUpdated_Call { + return &ArbRollupCoreInterface_ParseUserWithdrawableFundsUpdated_Call{Call: _e.mock.On("ParseUserWithdrawableFundsUpdated", log)} +} + +func (_c *ArbRollupCoreInterface_ParseUserWithdrawableFundsUpdated_Call) Run(run func(log types.Log)) *ArbRollupCoreInterface_ParseUserWithdrawableFundsUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseUserWithdrawableFundsUpdated_Call) Return(_a0 *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated, _a1 error) *ArbRollupCoreInterface_ParseUserWithdrawableFundsUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ParseUserWithdrawableFundsUpdated_Call) RunAndReturn(run func(types.Log) (*arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated, error)) *ArbRollupCoreInterface_ParseUserWithdrawableFundsUpdated_Call { + _c.Call.Return(run) + return _c +} + +// RollupEventInbox provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) RollupEventInbox(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for RollupEventInbox") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_RollupEventInbox_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RollupEventInbox' +type ArbRollupCoreInterface_RollupEventInbox_Call struct { + *mock.Call +} + +// RollupEventInbox is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) RollupEventInbox(opts interface{}) *ArbRollupCoreInterface_RollupEventInbox_Call { + return &ArbRollupCoreInterface_RollupEventInbox_Call{Call: _e.mock.On("RollupEventInbox", opts)} +} + +func (_c *ArbRollupCoreInterface_RollupEventInbox_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_RollupEventInbox_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_RollupEventInbox_Call) Return(_a0 common.Address, _a1 error) *ArbRollupCoreInterface_RollupEventInbox_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_RollupEventInbox_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *ArbRollupCoreInterface_RollupEventInbox_Call { + _c.Call.Return(run) + return _c +} + +// SequencerInbox provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) SequencerInbox(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for SequencerInbox") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_SequencerInbox_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SequencerInbox' +type ArbRollupCoreInterface_SequencerInbox_Call struct { + *mock.Call +} + +// SequencerInbox is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) SequencerInbox(opts interface{}) *ArbRollupCoreInterface_SequencerInbox_Call { + return &ArbRollupCoreInterface_SequencerInbox_Call{Call: _e.mock.On("SequencerInbox", opts)} +} + +func (_c *ArbRollupCoreInterface_SequencerInbox_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_SequencerInbox_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_SequencerInbox_Call) Return(_a0 common.Address, _a1 error) *ArbRollupCoreInterface_SequencerInbox_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_SequencerInbox_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *ArbRollupCoreInterface_SequencerInbox_Call { + _c.Call.Return(run) + return _c +} + +// StakeToken provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) StakeToken(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for StakeToken") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_StakeToken_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StakeToken' +type ArbRollupCoreInterface_StakeToken_Call struct { + *mock.Call +} + +// StakeToken is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) StakeToken(opts interface{}) *ArbRollupCoreInterface_StakeToken_Call { + return &ArbRollupCoreInterface_StakeToken_Call{Call: _e.mock.On("StakeToken", opts)} +} + +func (_c *ArbRollupCoreInterface_StakeToken_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_StakeToken_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_StakeToken_Call) Return(_a0 common.Address, _a1 error) *ArbRollupCoreInterface_StakeToken_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_StakeToken_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *ArbRollupCoreInterface_StakeToken_Call { + _c.Call.Return(run) + return _c +} + +// StakerCount provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) StakerCount(opts *bind.CallOpts) (uint64, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for StakerCount") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (uint64, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) uint64); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_StakerCount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StakerCount' +type ArbRollupCoreInterface_StakerCount_Call struct { + *mock.Call +} + +// StakerCount is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) StakerCount(opts interface{}) *ArbRollupCoreInterface_StakerCount_Call { + return &ArbRollupCoreInterface_StakerCount_Call{Call: _e.mock.On("StakerCount", opts)} +} + +func (_c *ArbRollupCoreInterface_StakerCount_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_StakerCount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_StakerCount_Call) Return(_a0 uint64, _a1 error) *ArbRollupCoreInterface_StakerCount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_StakerCount_Call) RunAndReturn(run func(*bind.CallOpts) (uint64, error)) *ArbRollupCoreInterface_StakerCount_Call { + _c.Call.Return(run) + return _c +} + +// ValidatorWhitelistDisabled provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) ValidatorWhitelistDisabled(opts *bind.CallOpts) (bool, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for ValidatorWhitelistDisabled") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (bool, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) bool); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ValidatorWhitelistDisabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ValidatorWhitelistDisabled' +type ArbRollupCoreInterface_ValidatorWhitelistDisabled_Call struct { + *mock.Call +} + +// ValidatorWhitelistDisabled is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) ValidatorWhitelistDisabled(opts interface{}) *ArbRollupCoreInterface_ValidatorWhitelistDisabled_Call { + return &ArbRollupCoreInterface_ValidatorWhitelistDisabled_Call{Call: _e.mock.On("ValidatorWhitelistDisabled", opts)} +} + +func (_c *ArbRollupCoreInterface_ValidatorWhitelistDisabled_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_ValidatorWhitelistDisabled_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ValidatorWhitelistDisabled_Call) Return(_a0 bool, _a1 error) *ArbRollupCoreInterface_ValidatorWhitelistDisabled_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ValidatorWhitelistDisabled_Call) RunAndReturn(run func(*bind.CallOpts) (bool, error)) *ArbRollupCoreInterface_ValidatorWhitelistDisabled_Call { + _c.Call.Return(run) + return _c +} + +// WasmModuleRoot provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) WasmModuleRoot(opts *bind.CallOpts) ([32]byte, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for WasmModuleRoot") + } + + var r0 [32]byte + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([32]byte, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) [32]byte); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([32]byte) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_WasmModuleRoot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WasmModuleRoot' +type ArbRollupCoreInterface_WasmModuleRoot_Call struct { + *mock.Call +} + +// WasmModuleRoot is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) WasmModuleRoot(opts interface{}) *ArbRollupCoreInterface_WasmModuleRoot_Call { + return &ArbRollupCoreInterface_WasmModuleRoot_Call{Call: _e.mock.On("WasmModuleRoot", opts)} +} + +func (_c *ArbRollupCoreInterface_WasmModuleRoot_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_WasmModuleRoot_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_WasmModuleRoot_Call) Return(_a0 [32]byte, _a1 error) *ArbRollupCoreInterface_WasmModuleRoot_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_WasmModuleRoot_Call) RunAndReturn(run func(*bind.CallOpts) ([32]byte, error)) *ArbRollupCoreInterface_WasmModuleRoot_Call { + _c.Call.Return(run) + return _c +} + +// WatchNodeConfirmed provides a mock function with given fields: opts, sink, nodeNum +func (_m *ArbRollupCoreInterface) WatchNodeConfirmed(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreNodeConfirmed, nodeNum []uint64) (event.Subscription, error) { + ret := _m.Called(opts, sink, nodeNum) + + if len(ret) == 0 { + panic("no return value specified for WatchNodeConfirmed") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreNodeConfirmed, []uint64) (event.Subscription, error)); ok { + return rf(opts, sink, nodeNum) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreNodeConfirmed, []uint64) event.Subscription); ok { + r0 = rf(opts, sink, nodeNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreNodeConfirmed, []uint64) error); ok { + r1 = rf(opts, sink, nodeNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_WatchNodeConfirmed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchNodeConfirmed' +type ArbRollupCoreInterface_WatchNodeConfirmed_Call struct { + *mock.Call +} + +// WatchNodeConfirmed is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbitrum_rollup_core.ArbRollupCoreNodeConfirmed +// - nodeNum []uint64 +func (_e *ArbRollupCoreInterface_Expecter) WatchNodeConfirmed(opts interface{}, sink interface{}, nodeNum interface{}) *ArbRollupCoreInterface_WatchNodeConfirmed_Call { + return &ArbRollupCoreInterface_WatchNodeConfirmed_Call{Call: _e.mock.On("WatchNodeConfirmed", opts, sink, nodeNum)} +} + +func (_c *ArbRollupCoreInterface_WatchNodeConfirmed_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreNodeConfirmed, nodeNum []uint64)) *ArbRollupCoreInterface_WatchNodeConfirmed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbitrum_rollup_core.ArbRollupCoreNodeConfirmed), args[2].([]uint64)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchNodeConfirmed_Call) Return(_a0 event.Subscription, _a1 error) *ArbRollupCoreInterface_WatchNodeConfirmed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchNodeConfirmed_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreNodeConfirmed, []uint64) (event.Subscription, error)) *ArbRollupCoreInterface_WatchNodeConfirmed_Call { + _c.Call.Return(run) + return _c +} + +// WatchNodeCreated provides a mock function with given fields: opts, sink, nodeNum, parentNodeHash, nodeHash +func (_m *ArbRollupCoreInterface) WatchNodeCreated(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreNodeCreated, nodeNum []uint64, parentNodeHash [][32]byte, nodeHash [][32]byte) (event.Subscription, error) { + ret := _m.Called(opts, sink, nodeNum, parentNodeHash, nodeHash) + + if len(ret) == 0 { + panic("no return value specified for WatchNodeCreated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreNodeCreated, []uint64, [][32]byte, [][32]byte) (event.Subscription, error)); ok { + return rf(opts, sink, nodeNum, parentNodeHash, nodeHash) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreNodeCreated, []uint64, [][32]byte, [][32]byte) event.Subscription); ok { + r0 = rf(opts, sink, nodeNum, parentNodeHash, nodeHash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreNodeCreated, []uint64, [][32]byte, [][32]byte) error); ok { + r1 = rf(opts, sink, nodeNum, parentNodeHash, nodeHash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_WatchNodeCreated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchNodeCreated' +type ArbRollupCoreInterface_WatchNodeCreated_Call struct { + *mock.Call +} + +// WatchNodeCreated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbitrum_rollup_core.ArbRollupCoreNodeCreated +// - nodeNum []uint64 +// - parentNodeHash [][32]byte +// - nodeHash [][32]byte +func (_e *ArbRollupCoreInterface_Expecter) WatchNodeCreated(opts interface{}, sink interface{}, nodeNum interface{}, parentNodeHash interface{}, nodeHash interface{}) *ArbRollupCoreInterface_WatchNodeCreated_Call { + return &ArbRollupCoreInterface_WatchNodeCreated_Call{Call: _e.mock.On("WatchNodeCreated", opts, sink, nodeNum, parentNodeHash, nodeHash)} +} + +func (_c *ArbRollupCoreInterface_WatchNodeCreated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreNodeCreated, nodeNum []uint64, parentNodeHash [][32]byte, nodeHash [][32]byte)) *ArbRollupCoreInterface_WatchNodeCreated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbitrum_rollup_core.ArbRollupCoreNodeCreated), args[2].([]uint64), args[3].([][32]byte), args[4].([][32]byte)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchNodeCreated_Call) Return(_a0 event.Subscription, _a1 error) *ArbRollupCoreInterface_WatchNodeCreated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchNodeCreated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreNodeCreated, []uint64, [][32]byte, [][32]byte) (event.Subscription, error)) *ArbRollupCoreInterface_WatchNodeCreated_Call { + _c.Call.Return(run) + return _c +} + +// WatchNodeRejected provides a mock function with given fields: opts, sink, nodeNum +func (_m *ArbRollupCoreInterface) WatchNodeRejected(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreNodeRejected, nodeNum []uint64) (event.Subscription, error) { + ret := _m.Called(opts, sink, nodeNum) + + if len(ret) == 0 { + panic("no return value specified for WatchNodeRejected") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreNodeRejected, []uint64) (event.Subscription, error)); ok { + return rf(opts, sink, nodeNum) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreNodeRejected, []uint64) event.Subscription); ok { + r0 = rf(opts, sink, nodeNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreNodeRejected, []uint64) error); ok { + r1 = rf(opts, sink, nodeNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_WatchNodeRejected_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchNodeRejected' +type ArbRollupCoreInterface_WatchNodeRejected_Call struct { + *mock.Call +} + +// WatchNodeRejected is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbitrum_rollup_core.ArbRollupCoreNodeRejected +// - nodeNum []uint64 +func (_e *ArbRollupCoreInterface_Expecter) WatchNodeRejected(opts interface{}, sink interface{}, nodeNum interface{}) *ArbRollupCoreInterface_WatchNodeRejected_Call { + return &ArbRollupCoreInterface_WatchNodeRejected_Call{Call: _e.mock.On("WatchNodeRejected", opts, sink, nodeNum)} +} + +func (_c *ArbRollupCoreInterface_WatchNodeRejected_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreNodeRejected, nodeNum []uint64)) *ArbRollupCoreInterface_WatchNodeRejected_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbitrum_rollup_core.ArbRollupCoreNodeRejected), args[2].([]uint64)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchNodeRejected_Call) Return(_a0 event.Subscription, _a1 error) *ArbRollupCoreInterface_WatchNodeRejected_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchNodeRejected_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreNodeRejected, []uint64) (event.Subscription, error)) *ArbRollupCoreInterface_WatchNodeRejected_Call { + _c.Call.Return(run) + return _c +} + +// WatchRollupChallengeStarted provides a mock function with given fields: opts, sink, challengeIndex +func (_m *ArbRollupCoreInterface) WatchRollupChallengeStarted(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted, challengeIndex []uint64) (event.Subscription, error) { + ret := _m.Called(opts, sink, challengeIndex) + + if len(ret) == 0 { + panic("no return value specified for WatchRollupChallengeStarted") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted, []uint64) (event.Subscription, error)); ok { + return rf(opts, sink, challengeIndex) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted, []uint64) event.Subscription); ok { + r0 = rf(opts, sink, challengeIndex) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted, []uint64) error); ok { + r1 = rf(opts, sink, challengeIndex) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_WatchRollupChallengeStarted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchRollupChallengeStarted' +type ArbRollupCoreInterface_WatchRollupChallengeStarted_Call struct { + *mock.Call +} + +// WatchRollupChallengeStarted is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted +// - challengeIndex []uint64 +func (_e *ArbRollupCoreInterface_Expecter) WatchRollupChallengeStarted(opts interface{}, sink interface{}, challengeIndex interface{}) *ArbRollupCoreInterface_WatchRollupChallengeStarted_Call { + return &ArbRollupCoreInterface_WatchRollupChallengeStarted_Call{Call: _e.mock.On("WatchRollupChallengeStarted", opts, sink, challengeIndex)} +} + +func (_c *ArbRollupCoreInterface_WatchRollupChallengeStarted_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted, challengeIndex []uint64)) *ArbRollupCoreInterface_WatchRollupChallengeStarted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted), args[2].([]uint64)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchRollupChallengeStarted_Call) Return(_a0 event.Subscription, _a1 error) *ArbRollupCoreInterface_WatchRollupChallengeStarted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchRollupChallengeStarted_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreRollupChallengeStarted, []uint64) (event.Subscription, error)) *ArbRollupCoreInterface_WatchRollupChallengeStarted_Call { + _c.Call.Return(run) + return _c +} + +// WatchRollupInitialized provides a mock function with given fields: opts, sink +func (_m *ArbRollupCoreInterface) WatchRollupInitialized(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreRollupInitialized) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchRollupInitialized") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreRollupInitialized) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreRollupInitialized) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreRollupInitialized) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_WatchRollupInitialized_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchRollupInitialized' +type ArbRollupCoreInterface_WatchRollupInitialized_Call struct { + *mock.Call +} + +// WatchRollupInitialized is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbitrum_rollup_core.ArbRollupCoreRollupInitialized +func (_e *ArbRollupCoreInterface_Expecter) WatchRollupInitialized(opts interface{}, sink interface{}) *ArbRollupCoreInterface_WatchRollupInitialized_Call { + return &ArbRollupCoreInterface_WatchRollupInitialized_Call{Call: _e.mock.On("WatchRollupInitialized", opts, sink)} +} + +func (_c *ArbRollupCoreInterface_WatchRollupInitialized_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreRollupInitialized)) *ArbRollupCoreInterface_WatchRollupInitialized_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbitrum_rollup_core.ArbRollupCoreRollupInitialized)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchRollupInitialized_Call) Return(_a0 event.Subscription, _a1 error) *ArbRollupCoreInterface_WatchRollupInitialized_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchRollupInitialized_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreRollupInitialized) (event.Subscription, error)) *ArbRollupCoreInterface_WatchRollupInitialized_Call { + _c.Call.Return(run) + return _c +} + +// WatchUserStakeUpdated provides a mock function with given fields: opts, sink, user +func (_m *ArbRollupCoreInterface) WatchUserStakeUpdated(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated, user []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, user) + + if len(ret) == 0 { + panic("no return value specified for WatchUserStakeUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, user) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, user) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated, []common.Address) error); ok { + r1 = rf(opts, sink, user) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_WatchUserStakeUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchUserStakeUpdated' +type ArbRollupCoreInterface_WatchUserStakeUpdated_Call struct { + *mock.Call +} + +// WatchUserStakeUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated +// - user []common.Address +func (_e *ArbRollupCoreInterface_Expecter) WatchUserStakeUpdated(opts interface{}, sink interface{}, user interface{}) *ArbRollupCoreInterface_WatchUserStakeUpdated_Call { + return &ArbRollupCoreInterface_WatchUserStakeUpdated_Call{Call: _e.mock.On("WatchUserStakeUpdated", opts, sink, user)} +} + +func (_c *ArbRollupCoreInterface_WatchUserStakeUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated, user []common.Address)) *ArbRollupCoreInterface_WatchUserStakeUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated), args[2].([]common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchUserStakeUpdated_Call) Return(_a0 event.Subscription, _a1 error) *ArbRollupCoreInterface_WatchUserStakeUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchUserStakeUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreUserStakeUpdated, []common.Address) (event.Subscription, error)) *ArbRollupCoreInterface_WatchUserStakeUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WatchUserWithdrawableFundsUpdated provides a mock function with given fields: opts, sink, user +func (_m *ArbRollupCoreInterface) WatchUserWithdrawableFundsUpdated(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated, user []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, user) + + if len(ret) == 0 { + panic("no return value specified for WatchUserWithdrawableFundsUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, user) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, user) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated, []common.Address) error); ok { + r1 = rf(opts, sink, user) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_WatchUserWithdrawableFundsUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchUserWithdrawableFundsUpdated' +type ArbRollupCoreInterface_WatchUserWithdrawableFundsUpdated_Call struct { + *mock.Call +} + +// WatchUserWithdrawableFundsUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated +// - user []common.Address +func (_e *ArbRollupCoreInterface_Expecter) WatchUserWithdrawableFundsUpdated(opts interface{}, sink interface{}, user interface{}) *ArbRollupCoreInterface_WatchUserWithdrawableFundsUpdated_Call { + return &ArbRollupCoreInterface_WatchUserWithdrawableFundsUpdated_Call{Call: _e.mock.On("WatchUserWithdrawableFundsUpdated", opts, sink, user)} +} + +func (_c *ArbRollupCoreInterface_WatchUserWithdrawableFundsUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated, user []common.Address)) *ArbRollupCoreInterface_WatchUserWithdrawableFundsUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated), args[2].([]common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchUserWithdrawableFundsUpdated_Call) Return(_a0 event.Subscription, _a1 error) *ArbRollupCoreInterface_WatchUserWithdrawableFundsUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_WatchUserWithdrawableFundsUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbitrum_rollup_core.ArbRollupCoreUserWithdrawableFundsUpdated, []common.Address) (event.Subscription, error)) *ArbRollupCoreInterface_WatchUserWithdrawableFundsUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WithdrawableFunds provides a mock function with given fields: opts, owner +func (_m *ArbRollupCoreInterface) WithdrawableFunds(opts *bind.CallOpts, owner common.Address) (*big.Int, error) { + ret := _m.Called(opts, owner) + + if len(ret) == 0 { + panic("no return value specified for WithdrawableFunds") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (*big.Int, error)); ok { + return rf(opts, owner) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) *big.Int); ok { + r0 = rf(opts, owner) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, owner) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_WithdrawableFunds_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WithdrawableFunds' +type ArbRollupCoreInterface_WithdrawableFunds_Call struct { + *mock.Call +} + +// WithdrawableFunds is a helper method to define mock.On call +// - opts *bind.CallOpts +// - owner common.Address +func (_e *ArbRollupCoreInterface_Expecter) WithdrawableFunds(opts interface{}, owner interface{}) *ArbRollupCoreInterface_WithdrawableFunds_Call { + return &ArbRollupCoreInterface_WithdrawableFunds_Call{Call: _e.mock.On("WithdrawableFunds", opts, owner)} +} + +func (_c *ArbRollupCoreInterface_WithdrawableFunds_Call) Run(run func(opts *bind.CallOpts, owner common.Address)) *ArbRollupCoreInterface_WithdrawableFunds_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_WithdrawableFunds_Call) Return(_a0 *big.Int, _a1 error) *ArbRollupCoreInterface_WithdrawableFunds_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_WithdrawableFunds_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (*big.Int, error)) *ArbRollupCoreInterface_WithdrawableFunds_Call { + _c.Call.Return(run) + return _c +} + +// ZombieAddress provides a mock function with given fields: opts, zombieNum +func (_m *ArbRollupCoreInterface) ZombieAddress(opts *bind.CallOpts, zombieNum *big.Int) (common.Address, error) { + ret := _m.Called(opts, zombieNum) + + if len(ret) == 0 { + panic("no return value specified for ZombieAddress") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) (common.Address, error)); ok { + return rf(opts, zombieNum) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) common.Address); ok { + r0 = rf(opts, zombieNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, *big.Int) error); ok { + r1 = rf(opts, zombieNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ZombieAddress_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ZombieAddress' +type ArbRollupCoreInterface_ZombieAddress_Call struct { + *mock.Call +} + +// ZombieAddress is a helper method to define mock.On call +// - opts *bind.CallOpts +// - zombieNum *big.Int +func (_e *ArbRollupCoreInterface_Expecter) ZombieAddress(opts interface{}, zombieNum interface{}) *ArbRollupCoreInterface_ZombieAddress_Call { + return &ArbRollupCoreInterface_ZombieAddress_Call{Call: _e.mock.On("ZombieAddress", opts, zombieNum)} +} + +func (_c *ArbRollupCoreInterface_ZombieAddress_Call) Run(run func(opts *bind.CallOpts, zombieNum *big.Int)) *ArbRollupCoreInterface_ZombieAddress_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(*big.Int)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ZombieAddress_Call) Return(_a0 common.Address, _a1 error) *ArbRollupCoreInterface_ZombieAddress_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ZombieAddress_Call) RunAndReturn(run func(*bind.CallOpts, *big.Int) (common.Address, error)) *ArbRollupCoreInterface_ZombieAddress_Call { + _c.Call.Return(run) + return _c +} + +// ZombieCount provides a mock function with given fields: opts +func (_m *ArbRollupCoreInterface) ZombieCount(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for ZombieCount") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ZombieCount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ZombieCount' +type ArbRollupCoreInterface_ZombieCount_Call struct { + *mock.Call +} + +// ZombieCount is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbRollupCoreInterface_Expecter) ZombieCount(opts interface{}) *ArbRollupCoreInterface_ZombieCount_Call { + return &ArbRollupCoreInterface_ZombieCount_Call{Call: _e.mock.On("ZombieCount", opts)} +} + +func (_c *ArbRollupCoreInterface_ZombieCount_Call) Run(run func(opts *bind.CallOpts)) *ArbRollupCoreInterface_ZombieCount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ZombieCount_Call) Return(_a0 *big.Int, _a1 error) *ArbRollupCoreInterface_ZombieCount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ZombieCount_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *ArbRollupCoreInterface_ZombieCount_Call { + _c.Call.Return(run) + return _c +} + +// ZombieLatestStakedNode provides a mock function with given fields: opts, zombieNum +func (_m *ArbRollupCoreInterface) ZombieLatestStakedNode(opts *bind.CallOpts, zombieNum *big.Int) (uint64, error) { + ret := _m.Called(opts, zombieNum) + + if len(ret) == 0 { + panic("no return value specified for ZombieLatestStakedNode") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) (uint64, error)); ok { + return rf(opts, zombieNum) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) uint64); ok { + r0 = rf(opts, zombieNum) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, *big.Int) error); ok { + r1 = rf(opts, zombieNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbRollupCoreInterface_ZombieLatestStakedNode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ZombieLatestStakedNode' +type ArbRollupCoreInterface_ZombieLatestStakedNode_Call struct { + *mock.Call +} + +// ZombieLatestStakedNode is a helper method to define mock.On call +// - opts *bind.CallOpts +// - zombieNum *big.Int +func (_e *ArbRollupCoreInterface_Expecter) ZombieLatestStakedNode(opts interface{}, zombieNum interface{}) *ArbRollupCoreInterface_ZombieLatestStakedNode_Call { + return &ArbRollupCoreInterface_ZombieLatestStakedNode_Call{Call: _e.mock.On("ZombieLatestStakedNode", opts, zombieNum)} +} + +func (_c *ArbRollupCoreInterface_ZombieLatestStakedNode_Call) Run(run func(opts *bind.CallOpts, zombieNum *big.Int)) *ArbRollupCoreInterface_ZombieLatestStakedNode_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(*big.Int)) + }) + return _c +} + +func (_c *ArbRollupCoreInterface_ZombieLatestStakedNode_Call) Return(_a0 uint64, _a1 error) *ArbRollupCoreInterface_ZombieLatestStakedNode_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbRollupCoreInterface_ZombieLatestStakedNode_Call) RunAndReturn(run func(*bind.CallOpts, *big.Int) (uint64, error)) *ArbRollupCoreInterface_ZombieLatestStakedNode_Call { + _c.Call.Return(run) + return _c +} + +// NewArbRollupCoreInterface creates a new instance of ArbRollupCoreInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewArbRollupCoreInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *ArbRollupCoreInterface { + mock := &ArbRollupCoreInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_arbsys/arb_sys_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_arbsys/arb_sys_interface.go new file mode 100644 index 0000000000..609cff0ced --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_arbsys/arb_sys_interface.go @@ -0,0 +1,1392 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_arbsys + +import ( + big "math/big" + + arbsys "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbsys" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// ArbSysInterface is an autogenerated mock type for the ArbSysInterface type +type ArbSysInterface struct { + mock.Mock +} + +type ArbSysInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *ArbSysInterface) EXPECT() *ArbSysInterface_Expecter { + return &ArbSysInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *ArbSysInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// ArbSysInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type ArbSysInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *ArbSysInterface_Expecter) Address() *ArbSysInterface_Address_Call { + return &ArbSysInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *ArbSysInterface_Address_Call) Run(run func()) *ArbSysInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ArbSysInterface_Address_Call) Return(_a0 common.Address) *ArbSysInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ArbSysInterface_Address_Call) RunAndReturn(run func() common.Address) *ArbSysInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// ArbBlockHash provides a mock function with given fields: opts, arbBlockNum +func (_m *ArbSysInterface) ArbBlockHash(opts *bind.CallOpts, arbBlockNum *big.Int) ([32]byte, error) { + ret := _m.Called(opts, arbBlockNum) + + if len(ret) == 0 { + panic("no return value specified for ArbBlockHash") + } + + var r0 [32]byte + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) ([32]byte, error)); ok { + return rf(opts, arbBlockNum) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) [32]byte); ok { + r0 = rf(opts, arbBlockNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([32]byte) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, *big.Int) error); ok { + r1 = rf(opts, arbBlockNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_ArbBlockHash_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ArbBlockHash' +type ArbSysInterface_ArbBlockHash_Call struct { + *mock.Call +} + +// ArbBlockHash is a helper method to define mock.On call +// - opts *bind.CallOpts +// - arbBlockNum *big.Int +func (_e *ArbSysInterface_Expecter) ArbBlockHash(opts interface{}, arbBlockNum interface{}) *ArbSysInterface_ArbBlockHash_Call { + return &ArbSysInterface_ArbBlockHash_Call{Call: _e.mock.On("ArbBlockHash", opts, arbBlockNum)} +} + +func (_c *ArbSysInterface_ArbBlockHash_Call) Run(run func(opts *bind.CallOpts, arbBlockNum *big.Int)) *ArbSysInterface_ArbBlockHash_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(*big.Int)) + }) + return _c +} + +func (_c *ArbSysInterface_ArbBlockHash_Call) Return(_a0 [32]byte, _a1 error) *ArbSysInterface_ArbBlockHash_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_ArbBlockHash_Call) RunAndReturn(run func(*bind.CallOpts, *big.Int) ([32]byte, error)) *ArbSysInterface_ArbBlockHash_Call { + _c.Call.Return(run) + return _c +} + +// ArbBlockNumber provides a mock function with given fields: opts +func (_m *ArbSysInterface) ArbBlockNumber(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for ArbBlockNumber") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_ArbBlockNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ArbBlockNumber' +type ArbSysInterface_ArbBlockNumber_Call struct { + *mock.Call +} + +// ArbBlockNumber is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbSysInterface_Expecter) ArbBlockNumber(opts interface{}) *ArbSysInterface_ArbBlockNumber_Call { + return &ArbSysInterface_ArbBlockNumber_Call{Call: _e.mock.On("ArbBlockNumber", opts)} +} + +func (_c *ArbSysInterface_ArbBlockNumber_Call) Run(run func(opts *bind.CallOpts)) *ArbSysInterface_ArbBlockNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbSysInterface_ArbBlockNumber_Call) Return(_a0 *big.Int, _a1 error) *ArbSysInterface_ArbBlockNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_ArbBlockNumber_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *ArbSysInterface_ArbBlockNumber_Call { + _c.Call.Return(run) + return _c +} + +// ArbChainID provides a mock function with given fields: opts +func (_m *ArbSysInterface) ArbChainID(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for ArbChainID") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_ArbChainID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ArbChainID' +type ArbSysInterface_ArbChainID_Call struct { + *mock.Call +} + +// ArbChainID is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbSysInterface_Expecter) ArbChainID(opts interface{}) *ArbSysInterface_ArbChainID_Call { + return &ArbSysInterface_ArbChainID_Call{Call: _e.mock.On("ArbChainID", opts)} +} + +func (_c *ArbSysInterface_ArbChainID_Call) Run(run func(opts *bind.CallOpts)) *ArbSysInterface_ArbChainID_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbSysInterface_ArbChainID_Call) Return(_a0 *big.Int, _a1 error) *ArbSysInterface_ArbChainID_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_ArbChainID_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *ArbSysInterface_ArbChainID_Call { + _c.Call.Return(run) + return _c +} + +// ArbOSVersion provides a mock function with given fields: opts +func (_m *ArbSysInterface) ArbOSVersion(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for ArbOSVersion") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_ArbOSVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ArbOSVersion' +type ArbSysInterface_ArbOSVersion_Call struct { + *mock.Call +} + +// ArbOSVersion is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbSysInterface_Expecter) ArbOSVersion(opts interface{}) *ArbSysInterface_ArbOSVersion_Call { + return &ArbSysInterface_ArbOSVersion_Call{Call: _e.mock.On("ArbOSVersion", opts)} +} + +func (_c *ArbSysInterface_ArbOSVersion_Call) Run(run func(opts *bind.CallOpts)) *ArbSysInterface_ArbOSVersion_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbSysInterface_ArbOSVersion_Call) Return(_a0 *big.Int, _a1 error) *ArbSysInterface_ArbOSVersion_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_ArbOSVersion_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *ArbSysInterface_ArbOSVersion_Call { + _c.Call.Return(run) + return _c +} + +// FilterL2ToL1Transaction provides a mock function with given fields: opts, destination, uniqueId, batchNumber +func (_m *ArbSysInterface) FilterL2ToL1Transaction(opts *bind.FilterOpts, destination []common.Address, uniqueId []*big.Int, batchNumber []*big.Int) (*arbsys.ArbSysL2ToL1TransactionIterator, error) { + ret := _m.Called(opts, destination, uniqueId, batchNumber) + + if len(ret) == 0 { + panic("no return value specified for FilterL2ToL1Transaction") + } + + var r0 *arbsys.ArbSysL2ToL1TransactionIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []*big.Int, []*big.Int) (*arbsys.ArbSysL2ToL1TransactionIterator, error)); ok { + return rf(opts, destination, uniqueId, batchNumber) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []*big.Int, []*big.Int) *arbsys.ArbSysL2ToL1TransactionIterator); ok { + r0 = rf(opts, destination, uniqueId, batchNumber) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbsys.ArbSysL2ToL1TransactionIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []*big.Int, []*big.Int) error); ok { + r1 = rf(opts, destination, uniqueId, batchNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_FilterL2ToL1Transaction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterL2ToL1Transaction' +type ArbSysInterface_FilterL2ToL1Transaction_Call struct { + *mock.Call +} + +// FilterL2ToL1Transaction is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - destination []common.Address +// - uniqueId []*big.Int +// - batchNumber []*big.Int +func (_e *ArbSysInterface_Expecter) FilterL2ToL1Transaction(opts interface{}, destination interface{}, uniqueId interface{}, batchNumber interface{}) *ArbSysInterface_FilterL2ToL1Transaction_Call { + return &ArbSysInterface_FilterL2ToL1Transaction_Call{Call: _e.mock.On("FilterL2ToL1Transaction", opts, destination, uniqueId, batchNumber)} +} + +func (_c *ArbSysInterface_FilterL2ToL1Transaction_Call) Run(run func(opts *bind.FilterOpts, destination []common.Address, uniqueId []*big.Int, batchNumber []*big.Int)) *ArbSysInterface_FilterL2ToL1Transaction_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]*big.Int), args[3].([]*big.Int)) + }) + return _c +} + +func (_c *ArbSysInterface_FilterL2ToL1Transaction_Call) Return(_a0 *arbsys.ArbSysL2ToL1TransactionIterator, _a1 error) *ArbSysInterface_FilterL2ToL1Transaction_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_FilterL2ToL1Transaction_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []*big.Int, []*big.Int) (*arbsys.ArbSysL2ToL1TransactionIterator, error)) *ArbSysInterface_FilterL2ToL1Transaction_Call { + _c.Call.Return(run) + return _c +} + +// FilterL2ToL1Tx provides a mock function with given fields: opts, destination, hash, position +func (_m *ArbSysInterface) FilterL2ToL1Tx(opts *bind.FilterOpts, destination []common.Address, hash []*big.Int, position []*big.Int) (*arbsys.ArbSysL2ToL1TxIterator, error) { + ret := _m.Called(opts, destination, hash, position) + + if len(ret) == 0 { + panic("no return value specified for FilterL2ToL1Tx") + } + + var r0 *arbsys.ArbSysL2ToL1TxIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []*big.Int, []*big.Int) (*arbsys.ArbSysL2ToL1TxIterator, error)); ok { + return rf(opts, destination, hash, position) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []*big.Int, []*big.Int) *arbsys.ArbSysL2ToL1TxIterator); ok { + r0 = rf(opts, destination, hash, position) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbsys.ArbSysL2ToL1TxIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []*big.Int, []*big.Int) error); ok { + r1 = rf(opts, destination, hash, position) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_FilterL2ToL1Tx_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterL2ToL1Tx' +type ArbSysInterface_FilterL2ToL1Tx_Call struct { + *mock.Call +} + +// FilterL2ToL1Tx is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - destination []common.Address +// - hash []*big.Int +// - position []*big.Int +func (_e *ArbSysInterface_Expecter) FilterL2ToL1Tx(opts interface{}, destination interface{}, hash interface{}, position interface{}) *ArbSysInterface_FilterL2ToL1Tx_Call { + return &ArbSysInterface_FilterL2ToL1Tx_Call{Call: _e.mock.On("FilterL2ToL1Tx", opts, destination, hash, position)} +} + +func (_c *ArbSysInterface_FilterL2ToL1Tx_Call) Run(run func(opts *bind.FilterOpts, destination []common.Address, hash []*big.Int, position []*big.Int)) *ArbSysInterface_FilterL2ToL1Tx_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]*big.Int), args[3].([]*big.Int)) + }) + return _c +} + +func (_c *ArbSysInterface_FilterL2ToL1Tx_Call) Return(_a0 *arbsys.ArbSysL2ToL1TxIterator, _a1 error) *ArbSysInterface_FilterL2ToL1Tx_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_FilterL2ToL1Tx_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []*big.Int, []*big.Int) (*arbsys.ArbSysL2ToL1TxIterator, error)) *ArbSysInterface_FilterL2ToL1Tx_Call { + _c.Call.Return(run) + return _c +} + +// FilterSendMerkleUpdate provides a mock function with given fields: opts, reserved, hash, position +func (_m *ArbSysInterface) FilterSendMerkleUpdate(opts *bind.FilterOpts, reserved []*big.Int, hash [][32]byte, position []*big.Int) (*arbsys.ArbSysSendMerkleUpdateIterator, error) { + ret := _m.Called(opts, reserved, hash, position) + + if len(ret) == 0 { + panic("no return value specified for FilterSendMerkleUpdate") + } + + var r0 *arbsys.ArbSysSendMerkleUpdateIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []*big.Int, [][32]byte, []*big.Int) (*arbsys.ArbSysSendMerkleUpdateIterator, error)); ok { + return rf(opts, reserved, hash, position) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []*big.Int, [][32]byte, []*big.Int) *arbsys.ArbSysSendMerkleUpdateIterator); ok { + r0 = rf(opts, reserved, hash, position) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbsys.ArbSysSendMerkleUpdateIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []*big.Int, [][32]byte, []*big.Int) error); ok { + r1 = rf(opts, reserved, hash, position) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_FilterSendMerkleUpdate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterSendMerkleUpdate' +type ArbSysInterface_FilterSendMerkleUpdate_Call struct { + *mock.Call +} + +// FilterSendMerkleUpdate is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - reserved []*big.Int +// - hash [][32]byte +// - position []*big.Int +func (_e *ArbSysInterface_Expecter) FilterSendMerkleUpdate(opts interface{}, reserved interface{}, hash interface{}, position interface{}) *ArbSysInterface_FilterSendMerkleUpdate_Call { + return &ArbSysInterface_FilterSendMerkleUpdate_Call{Call: _e.mock.On("FilterSendMerkleUpdate", opts, reserved, hash, position)} +} + +func (_c *ArbSysInterface_FilterSendMerkleUpdate_Call) Run(run func(opts *bind.FilterOpts, reserved []*big.Int, hash [][32]byte, position []*big.Int)) *ArbSysInterface_FilterSendMerkleUpdate_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]*big.Int), args[2].([][32]byte), args[3].([]*big.Int)) + }) + return _c +} + +func (_c *ArbSysInterface_FilterSendMerkleUpdate_Call) Return(_a0 *arbsys.ArbSysSendMerkleUpdateIterator, _a1 error) *ArbSysInterface_FilterSendMerkleUpdate_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_FilterSendMerkleUpdate_Call) RunAndReturn(run func(*bind.FilterOpts, []*big.Int, [][32]byte, []*big.Int) (*arbsys.ArbSysSendMerkleUpdateIterator, error)) *ArbSysInterface_FilterSendMerkleUpdate_Call { + _c.Call.Return(run) + return _c +} + +// GetStorageGasAvailable provides a mock function with given fields: opts +func (_m *ArbSysInterface) GetStorageGasAvailable(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetStorageGasAvailable") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_GetStorageGasAvailable_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStorageGasAvailable' +type ArbSysInterface_GetStorageGasAvailable_Call struct { + *mock.Call +} + +// GetStorageGasAvailable is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbSysInterface_Expecter) GetStorageGasAvailable(opts interface{}) *ArbSysInterface_GetStorageGasAvailable_Call { + return &ArbSysInterface_GetStorageGasAvailable_Call{Call: _e.mock.On("GetStorageGasAvailable", opts)} +} + +func (_c *ArbSysInterface_GetStorageGasAvailable_Call) Run(run func(opts *bind.CallOpts)) *ArbSysInterface_GetStorageGasAvailable_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbSysInterface_GetStorageGasAvailable_Call) Return(_a0 *big.Int, _a1 error) *ArbSysInterface_GetStorageGasAvailable_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_GetStorageGasAvailable_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *ArbSysInterface_GetStorageGasAvailable_Call { + _c.Call.Return(run) + return _c +} + +// IsTopLevelCall provides a mock function with given fields: opts +func (_m *ArbSysInterface) IsTopLevelCall(opts *bind.CallOpts) (bool, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for IsTopLevelCall") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (bool, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) bool); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_IsTopLevelCall_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsTopLevelCall' +type ArbSysInterface_IsTopLevelCall_Call struct { + *mock.Call +} + +// IsTopLevelCall is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbSysInterface_Expecter) IsTopLevelCall(opts interface{}) *ArbSysInterface_IsTopLevelCall_Call { + return &ArbSysInterface_IsTopLevelCall_Call{Call: _e.mock.On("IsTopLevelCall", opts)} +} + +func (_c *ArbSysInterface_IsTopLevelCall_Call) Run(run func(opts *bind.CallOpts)) *ArbSysInterface_IsTopLevelCall_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbSysInterface_IsTopLevelCall_Call) Return(_a0 bool, _a1 error) *ArbSysInterface_IsTopLevelCall_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_IsTopLevelCall_Call) RunAndReturn(run func(*bind.CallOpts) (bool, error)) *ArbSysInterface_IsTopLevelCall_Call { + _c.Call.Return(run) + return _c +} + +// MapL1SenderContractAddressToL2Alias provides a mock function with given fields: opts, sender, unused +func (_m *ArbSysInterface) MapL1SenderContractAddressToL2Alias(opts *bind.CallOpts, sender common.Address, unused common.Address) (common.Address, error) { + ret := _m.Called(opts, sender, unused) + + if len(ret) == 0 { + panic("no return value specified for MapL1SenderContractAddressToL2Alias") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, common.Address) (common.Address, error)); ok { + return rf(opts, sender, unused) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, common.Address) common.Address); ok { + r0 = rf(opts, sender, unused) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address, common.Address) error); ok { + r1 = rf(opts, sender, unused) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_MapL1SenderContractAddressToL2Alias_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MapL1SenderContractAddressToL2Alias' +type ArbSysInterface_MapL1SenderContractAddressToL2Alias_Call struct { + *mock.Call +} + +// MapL1SenderContractAddressToL2Alias is a helper method to define mock.On call +// - opts *bind.CallOpts +// - sender common.Address +// - unused common.Address +func (_e *ArbSysInterface_Expecter) MapL1SenderContractAddressToL2Alias(opts interface{}, sender interface{}, unused interface{}) *ArbSysInterface_MapL1SenderContractAddressToL2Alias_Call { + return &ArbSysInterface_MapL1SenderContractAddressToL2Alias_Call{Call: _e.mock.On("MapL1SenderContractAddressToL2Alias", opts, sender, unused)} +} + +func (_c *ArbSysInterface_MapL1SenderContractAddressToL2Alias_Call) Run(run func(opts *bind.CallOpts, sender common.Address, unused common.Address)) *ArbSysInterface_MapL1SenderContractAddressToL2Alias_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address), args[2].(common.Address)) + }) + return _c +} + +func (_c *ArbSysInterface_MapL1SenderContractAddressToL2Alias_Call) Return(_a0 common.Address, _a1 error) *ArbSysInterface_MapL1SenderContractAddressToL2Alias_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_MapL1SenderContractAddressToL2Alias_Call) RunAndReturn(run func(*bind.CallOpts, common.Address, common.Address) (common.Address, error)) *ArbSysInterface_MapL1SenderContractAddressToL2Alias_Call { + _c.Call.Return(run) + return _c +} + +// MyCallersAddressWithoutAliasing provides a mock function with given fields: opts +func (_m *ArbSysInterface) MyCallersAddressWithoutAliasing(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for MyCallersAddressWithoutAliasing") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_MyCallersAddressWithoutAliasing_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MyCallersAddressWithoutAliasing' +type ArbSysInterface_MyCallersAddressWithoutAliasing_Call struct { + *mock.Call +} + +// MyCallersAddressWithoutAliasing is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbSysInterface_Expecter) MyCallersAddressWithoutAliasing(opts interface{}) *ArbSysInterface_MyCallersAddressWithoutAliasing_Call { + return &ArbSysInterface_MyCallersAddressWithoutAliasing_Call{Call: _e.mock.On("MyCallersAddressWithoutAliasing", opts)} +} + +func (_c *ArbSysInterface_MyCallersAddressWithoutAliasing_Call) Run(run func(opts *bind.CallOpts)) *ArbSysInterface_MyCallersAddressWithoutAliasing_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbSysInterface_MyCallersAddressWithoutAliasing_Call) Return(_a0 common.Address, _a1 error) *ArbSysInterface_MyCallersAddressWithoutAliasing_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_MyCallersAddressWithoutAliasing_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *ArbSysInterface_MyCallersAddressWithoutAliasing_Call { + _c.Call.Return(run) + return _c +} + +// ParseL2ToL1Transaction provides a mock function with given fields: log +func (_m *ArbSysInterface) ParseL2ToL1Transaction(log types.Log) (*arbsys.ArbSysL2ToL1Transaction, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseL2ToL1Transaction") + } + + var r0 *arbsys.ArbSysL2ToL1Transaction + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbsys.ArbSysL2ToL1Transaction, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbsys.ArbSysL2ToL1Transaction); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbsys.ArbSysL2ToL1Transaction) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_ParseL2ToL1Transaction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseL2ToL1Transaction' +type ArbSysInterface_ParseL2ToL1Transaction_Call struct { + *mock.Call +} + +// ParseL2ToL1Transaction is a helper method to define mock.On call +// - log types.Log +func (_e *ArbSysInterface_Expecter) ParseL2ToL1Transaction(log interface{}) *ArbSysInterface_ParseL2ToL1Transaction_Call { + return &ArbSysInterface_ParseL2ToL1Transaction_Call{Call: _e.mock.On("ParseL2ToL1Transaction", log)} +} + +func (_c *ArbSysInterface_ParseL2ToL1Transaction_Call) Run(run func(log types.Log)) *ArbSysInterface_ParseL2ToL1Transaction_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbSysInterface_ParseL2ToL1Transaction_Call) Return(_a0 *arbsys.ArbSysL2ToL1Transaction, _a1 error) *ArbSysInterface_ParseL2ToL1Transaction_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_ParseL2ToL1Transaction_Call) RunAndReturn(run func(types.Log) (*arbsys.ArbSysL2ToL1Transaction, error)) *ArbSysInterface_ParseL2ToL1Transaction_Call { + _c.Call.Return(run) + return _c +} + +// ParseL2ToL1Tx provides a mock function with given fields: log +func (_m *ArbSysInterface) ParseL2ToL1Tx(log types.Log) (*arbsys.ArbSysL2ToL1Tx, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseL2ToL1Tx") + } + + var r0 *arbsys.ArbSysL2ToL1Tx + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbsys.ArbSysL2ToL1Tx, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbsys.ArbSysL2ToL1Tx); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbsys.ArbSysL2ToL1Tx) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_ParseL2ToL1Tx_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseL2ToL1Tx' +type ArbSysInterface_ParseL2ToL1Tx_Call struct { + *mock.Call +} + +// ParseL2ToL1Tx is a helper method to define mock.On call +// - log types.Log +func (_e *ArbSysInterface_Expecter) ParseL2ToL1Tx(log interface{}) *ArbSysInterface_ParseL2ToL1Tx_Call { + return &ArbSysInterface_ParseL2ToL1Tx_Call{Call: _e.mock.On("ParseL2ToL1Tx", log)} +} + +func (_c *ArbSysInterface_ParseL2ToL1Tx_Call) Run(run func(log types.Log)) *ArbSysInterface_ParseL2ToL1Tx_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbSysInterface_ParseL2ToL1Tx_Call) Return(_a0 *arbsys.ArbSysL2ToL1Tx, _a1 error) *ArbSysInterface_ParseL2ToL1Tx_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_ParseL2ToL1Tx_Call) RunAndReturn(run func(types.Log) (*arbsys.ArbSysL2ToL1Tx, error)) *ArbSysInterface_ParseL2ToL1Tx_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *ArbSysInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type ArbSysInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *ArbSysInterface_Expecter) ParseLog(log interface{}) *ArbSysInterface_ParseLog_Call { + return &ArbSysInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *ArbSysInterface_ParseLog_Call) Run(run func(log types.Log)) *ArbSysInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbSysInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *ArbSysInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *ArbSysInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseSendMerkleUpdate provides a mock function with given fields: log +func (_m *ArbSysInterface) ParseSendMerkleUpdate(log types.Log) (*arbsys.ArbSysSendMerkleUpdate, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseSendMerkleUpdate") + } + + var r0 *arbsys.ArbSysSendMerkleUpdate + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*arbsys.ArbSysSendMerkleUpdate, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *arbsys.ArbSysSendMerkleUpdate); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*arbsys.ArbSysSendMerkleUpdate) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_ParseSendMerkleUpdate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseSendMerkleUpdate' +type ArbSysInterface_ParseSendMerkleUpdate_Call struct { + *mock.Call +} + +// ParseSendMerkleUpdate is a helper method to define mock.On call +// - log types.Log +func (_e *ArbSysInterface_Expecter) ParseSendMerkleUpdate(log interface{}) *ArbSysInterface_ParseSendMerkleUpdate_Call { + return &ArbSysInterface_ParseSendMerkleUpdate_Call{Call: _e.mock.On("ParseSendMerkleUpdate", log)} +} + +func (_c *ArbSysInterface_ParseSendMerkleUpdate_Call) Run(run func(log types.Log)) *ArbSysInterface_ParseSendMerkleUpdate_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *ArbSysInterface_ParseSendMerkleUpdate_Call) Return(_a0 *arbsys.ArbSysSendMerkleUpdate, _a1 error) *ArbSysInterface_ParseSendMerkleUpdate_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_ParseSendMerkleUpdate_Call) RunAndReturn(run func(types.Log) (*arbsys.ArbSysSendMerkleUpdate, error)) *ArbSysInterface_ParseSendMerkleUpdate_Call { + _c.Call.Return(run) + return _c +} + +// SendMerkleTreeState provides a mock function with given fields: opts +func (_m *ArbSysInterface) SendMerkleTreeState(opts *bind.CallOpts) (arbsys.SendMerkleTreeState, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for SendMerkleTreeState") + } + + var r0 arbsys.SendMerkleTreeState + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (arbsys.SendMerkleTreeState, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) arbsys.SendMerkleTreeState); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(arbsys.SendMerkleTreeState) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_SendMerkleTreeState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendMerkleTreeState' +type ArbSysInterface_SendMerkleTreeState_Call struct { + *mock.Call +} + +// SendMerkleTreeState is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbSysInterface_Expecter) SendMerkleTreeState(opts interface{}) *ArbSysInterface_SendMerkleTreeState_Call { + return &ArbSysInterface_SendMerkleTreeState_Call{Call: _e.mock.On("SendMerkleTreeState", opts)} +} + +func (_c *ArbSysInterface_SendMerkleTreeState_Call) Run(run func(opts *bind.CallOpts)) *ArbSysInterface_SendMerkleTreeState_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbSysInterface_SendMerkleTreeState_Call) Return(_a0 arbsys.SendMerkleTreeState, _a1 error) *ArbSysInterface_SendMerkleTreeState_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_SendMerkleTreeState_Call) RunAndReturn(run func(*bind.CallOpts) (arbsys.SendMerkleTreeState, error)) *ArbSysInterface_SendMerkleTreeState_Call { + _c.Call.Return(run) + return _c +} + +// SendTxToL1 provides a mock function with given fields: opts, destination, data +func (_m *ArbSysInterface) SendTxToL1(opts *bind.TransactOpts, destination common.Address, data []byte) (*types.Transaction, error) { + ret := _m.Called(opts, destination, data) + + if len(ret) == 0 { + panic("no return value specified for SendTxToL1") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, []byte) (*types.Transaction, error)); ok { + return rf(opts, destination, data) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, []byte) *types.Transaction); ok { + r0 = rf(opts, destination, data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, []byte) error); ok { + r1 = rf(opts, destination, data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_SendTxToL1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendTxToL1' +type ArbSysInterface_SendTxToL1_Call struct { + *mock.Call +} + +// SendTxToL1 is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - destination common.Address +// - data []byte +func (_e *ArbSysInterface_Expecter) SendTxToL1(opts interface{}, destination interface{}, data interface{}) *ArbSysInterface_SendTxToL1_Call { + return &ArbSysInterface_SendTxToL1_Call{Call: _e.mock.On("SendTxToL1", opts, destination, data)} +} + +func (_c *ArbSysInterface_SendTxToL1_Call) Run(run func(opts *bind.TransactOpts, destination common.Address, data []byte)) *ArbSysInterface_SendTxToL1_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].([]byte)) + }) + return _c +} + +func (_c *ArbSysInterface_SendTxToL1_Call) Return(_a0 *types.Transaction, _a1 error) *ArbSysInterface_SendTxToL1_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_SendTxToL1_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, []byte) (*types.Transaction, error)) *ArbSysInterface_SendTxToL1_Call { + _c.Call.Return(run) + return _c +} + +// WasMyCallersAddressAliased provides a mock function with given fields: opts +func (_m *ArbSysInterface) WasMyCallersAddressAliased(opts *bind.CallOpts) (bool, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for WasMyCallersAddressAliased") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (bool, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) bool); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_WasMyCallersAddressAliased_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WasMyCallersAddressAliased' +type ArbSysInterface_WasMyCallersAddressAliased_Call struct { + *mock.Call +} + +// WasMyCallersAddressAliased is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *ArbSysInterface_Expecter) WasMyCallersAddressAliased(opts interface{}) *ArbSysInterface_WasMyCallersAddressAliased_Call { + return &ArbSysInterface_WasMyCallersAddressAliased_Call{Call: _e.mock.On("WasMyCallersAddressAliased", opts)} +} + +func (_c *ArbSysInterface_WasMyCallersAddressAliased_Call) Run(run func(opts *bind.CallOpts)) *ArbSysInterface_WasMyCallersAddressAliased_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *ArbSysInterface_WasMyCallersAddressAliased_Call) Return(_a0 bool, _a1 error) *ArbSysInterface_WasMyCallersAddressAliased_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_WasMyCallersAddressAliased_Call) RunAndReturn(run func(*bind.CallOpts) (bool, error)) *ArbSysInterface_WasMyCallersAddressAliased_Call { + _c.Call.Return(run) + return _c +} + +// WatchL2ToL1Transaction provides a mock function with given fields: opts, sink, destination, uniqueId, batchNumber +func (_m *ArbSysInterface) WatchL2ToL1Transaction(opts *bind.WatchOpts, sink chan<- *arbsys.ArbSysL2ToL1Transaction, destination []common.Address, uniqueId []*big.Int, batchNumber []*big.Int) (event.Subscription, error) { + ret := _m.Called(opts, sink, destination, uniqueId, batchNumber) + + if len(ret) == 0 { + panic("no return value specified for WatchL2ToL1Transaction") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbsys.ArbSysL2ToL1Transaction, []common.Address, []*big.Int, []*big.Int) (event.Subscription, error)); ok { + return rf(opts, sink, destination, uniqueId, batchNumber) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbsys.ArbSysL2ToL1Transaction, []common.Address, []*big.Int, []*big.Int) event.Subscription); ok { + r0 = rf(opts, sink, destination, uniqueId, batchNumber) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbsys.ArbSysL2ToL1Transaction, []common.Address, []*big.Int, []*big.Int) error); ok { + r1 = rf(opts, sink, destination, uniqueId, batchNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_WatchL2ToL1Transaction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchL2ToL1Transaction' +type ArbSysInterface_WatchL2ToL1Transaction_Call struct { + *mock.Call +} + +// WatchL2ToL1Transaction is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbsys.ArbSysL2ToL1Transaction +// - destination []common.Address +// - uniqueId []*big.Int +// - batchNumber []*big.Int +func (_e *ArbSysInterface_Expecter) WatchL2ToL1Transaction(opts interface{}, sink interface{}, destination interface{}, uniqueId interface{}, batchNumber interface{}) *ArbSysInterface_WatchL2ToL1Transaction_Call { + return &ArbSysInterface_WatchL2ToL1Transaction_Call{Call: _e.mock.On("WatchL2ToL1Transaction", opts, sink, destination, uniqueId, batchNumber)} +} + +func (_c *ArbSysInterface_WatchL2ToL1Transaction_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbsys.ArbSysL2ToL1Transaction, destination []common.Address, uniqueId []*big.Int, batchNumber []*big.Int)) *ArbSysInterface_WatchL2ToL1Transaction_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbsys.ArbSysL2ToL1Transaction), args[2].([]common.Address), args[3].([]*big.Int), args[4].([]*big.Int)) + }) + return _c +} + +func (_c *ArbSysInterface_WatchL2ToL1Transaction_Call) Return(_a0 event.Subscription, _a1 error) *ArbSysInterface_WatchL2ToL1Transaction_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_WatchL2ToL1Transaction_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbsys.ArbSysL2ToL1Transaction, []common.Address, []*big.Int, []*big.Int) (event.Subscription, error)) *ArbSysInterface_WatchL2ToL1Transaction_Call { + _c.Call.Return(run) + return _c +} + +// WatchL2ToL1Tx provides a mock function with given fields: opts, sink, destination, hash, position +func (_m *ArbSysInterface) WatchL2ToL1Tx(opts *bind.WatchOpts, sink chan<- *arbsys.ArbSysL2ToL1Tx, destination []common.Address, hash []*big.Int, position []*big.Int) (event.Subscription, error) { + ret := _m.Called(opts, sink, destination, hash, position) + + if len(ret) == 0 { + panic("no return value specified for WatchL2ToL1Tx") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbsys.ArbSysL2ToL1Tx, []common.Address, []*big.Int, []*big.Int) (event.Subscription, error)); ok { + return rf(opts, sink, destination, hash, position) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbsys.ArbSysL2ToL1Tx, []common.Address, []*big.Int, []*big.Int) event.Subscription); ok { + r0 = rf(opts, sink, destination, hash, position) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbsys.ArbSysL2ToL1Tx, []common.Address, []*big.Int, []*big.Int) error); ok { + r1 = rf(opts, sink, destination, hash, position) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_WatchL2ToL1Tx_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchL2ToL1Tx' +type ArbSysInterface_WatchL2ToL1Tx_Call struct { + *mock.Call +} + +// WatchL2ToL1Tx is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbsys.ArbSysL2ToL1Tx +// - destination []common.Address +// - hash []*big.Int +// - position []*big.Int +func (_e *ArbSysInterface_Expecter) WatchL2ToL1Tx(opts interface{}, sink interface{}, destination interface{}, hash interface{}, position interface{}) *ArbSysInterface_WatchL2ToL1Tx_Call { + return &ArbSysInterface_WatchL2ToL1Tx_Call{Call: _e.mock.On("WatchL2ToL1Tx", opts, sink, destination, hash, position)} +} + +func (_c *ArbSysInterface_WatchL2ToL1Tx_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbsys.ArbSysL2ToL1Tx, destination []common.Address, hash []*big.Int, position []*big.Int)) *ArbSysInterface_WatchL2ToL1Tx_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbsys.ArbSysL2ToL1Tx), args[2].([]common.Address), args[3].([]*big.Int), args[4].([]*big.Int)) + }) + return _c +} + +func (_c *ArbSysInterface_WatchL2ToL1Tx_Call) Return(_a0 event.Subscription, _a1 error) *ArbSysInterface_WatchL2ToL1Tx_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_WatchL2ToL1Tx_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbsys.ArbSysL2ToL1Tx, []common.Address, []*big.Int, []*big.Int) (event.Subscription, error)) *ArbSysInterface_WatchL2ToL1Tx_Call { + _c.Call.Return(run) + return _c +} + +// WatchSendMerkleUpdate provides a mock function with given fields: opts, sink, reserved, hash, position +func (_m *ArbSysInterface) WatchSendMerkleUpdate(opts *bind.WatchOpts, sink chan<- *arbsys.ArbSysSendMerkleUpdate, reserved []*big.Int, hash [][32]byte, position []*big.Int) (event.Subscription, error) { + ret := _m.Called(opts, sink, reserved, hash, position) + + if len(ret) == 0 { + panic("no return value specified for WatchSendMerkleUpdate") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbsys.ArbSysSendMerkleUpdate, []*big.Int, [][32]byte, []*big.Int) (event.Subscription, error)); ok { + return rf(opts, sink, reserved, hash, position) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *arbsys.ArbSysSendMerkleUpdate, []*big.Int, [][32]byte, []*big.Int) event.Subscription); ok { + r0 = rf(opts, sink, reserved, hash, position) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *arbsys.ArbSysSendMerkleUpdate, []*big.Int, [][32]byte, []*big.Int) error); ok { + r1 = rf(opts, sink, reserved, hash, position) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_WatchSendMerkleUpdate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchSendMerkleUpdate' +type ArbSysInterface_WatchSendMerkleUpdate_Call struct { + *mock.Call +} + +// WatchSendMerkleUpdate is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *arbsys.ArbSysSendMerkleUpdate +// - reserved []*big.Int +// - hash [][32]byte +// - position []*big.Int +func (_e *ArbSysInterface_Expecter) WatchSendMerkleUpdate(opts interface{}, sink interface{}, reserved interface{}, hash interface{}, position interface{}) *ArbSysInterface_WatchSendMerkleUpdate_Call { + return &ArbSysInterface_WatchSendMerkleUpdate_Call{Call: _e.mock.On("WatchSendMerkleUpdate", opts, sink, reserved, hash, position)} +} + +func (_c *ArbSysInterface_WatchSendMerkleUpdate_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *arbsys.ArbSysSendMerkleUpdate, reserved []*big.Int, hash [][32]byte, position []*big.Int)) *ArbSysInterface_WatchSendMerkleUpdate_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *arbsys.ArbSysSendMerkleUpdate), args[2].([]*big.Int), args[3].([][32]byte), args[4].([]*big.Int)) + }) + return _c +} + +func (_c *ArbSysInterface_WatchSendMerkleUpdate_Call) Return(_a0 event.Subscription, _a1 error) *ArbSysInterface_WatchSendMerkleUpdate_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_WatchSendMerkleUpdate_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *arbsys.ArbSysSendMerkleUpdate, []*big.Int, [][32]byte, []*big.Int) (event.Subscription, error)) *ArbSysInterface_WatchSendMerkleUpdate_Call { + _c.Call.Return(run) + return _c +} + +// WithdrawEth provides a mock function with given fields: opts, destination +func (_m *ArbSysInterface) WithdrawEth(opts *bind.TransactOpts, destination common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, destination) + + if len(ret) == 0 { + panic("no return value specified for WithdrawEth") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, destination) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, destination) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, destination) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ArbSysInterface_WithdrawEth_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WithdrawEth' +type ArbSysInterface_WithdrawEth_Call struct { + *mock.Call +} + +// WithdrawEth is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - destination common.Address +func (_e *ArbSysInterface_Expecter) WithdrawEth(opts interface{}, destination interface{}) *ArbSysInterface_WithdrawEth_Call { + return &ArbSysInterface_WithdrawEth_Call{Call: _e.mock.On("WithdrawEth", opts, destination)} +} + +func (_c *ArbSysInterface_WithdrawEth_Call) Run(run func(opts *bind.TransactOpts, destination common.Address)) *ArbSysInterface_WithdrawEth_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *ArbSysInterface_WithdrawEth_Call) Return(_a0 *types.Transaction, _a1 error) *ArbSysInterface_WithdrawEth_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ArbSysInterface_WithdrawEth_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *ArbSysInterface_WithdrawEth_Call { + _c.Call.Return(run) + return _c +} + +// NewArbSysInterface creates a new instance of ArbSysInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewArbSysInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *ArbSysInterface { + mock := &ArbSysInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_l2_arbitrum_gateway/l2_arbitrum_gateway_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_l2_arbitrum_gateway/l2_arbitrum_gateway_interface.go new file mode 100644 index 0000000000..6ed290e912 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_l2_arbitrum_gateway/l2_arbitrum_gateway_interface.go @@ -0,0 +1,1238 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_l2_arbitrum_gateway + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + l2_arbitrum_gateway "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/l2_arbitrum_gateway" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// L2ArbitrumGatewayInterface is an autogenerated mock type for the L2ArbitrumGatewayInterface type +type L2ArbitrumGatewayInterface struct { + mock.Mock +} + +type L2ArbitrumGatewayInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *L2ArbitrumGatewayInterface) EXPECT() *L2ArbitrumGatewayInterface_Expecter { + return &L2ArbitrumGatewayInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *L2ArbitrumGatewayInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// L2ArbitrumGatewayInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type L2ArbitrumGatewayInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *L2ArbitrumGatewayInterface_Expecter) Address() *L2ArbitrumGatewayInterface_Address_Call { + return &L2ArbitrumGatewayInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *L2ArbitrumGatewayInterface_Address_Call) Run(run func()) *L2ArbitrumGatewayInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_Address_Call) Return(_a0 common.Address) *L2ArbitrumGatewayInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_Address_Call) RunAndReturn(run func() common.Address) *L2ArbitrumGatewayInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// CalculateL2TokenAddress provides a mock function with given fields: opts, l1ERC20 +func (_m *L2ArbitrumGatewayInterface) CalculateL2TokenAddress(opts *bind.CallOpts, l1ERC20 common.Address) (common.Address, error) { + ret := _m.Called(opts, l1ERC20) + + if len(ret) == 0 { + panic("no return value specified for CalculateL2TokenAddress") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (common.Address, error)); ok { + return rf(opts, l1ERC20) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) common.Address); ok { + r0 = rf(opts, l1ERC20) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, l1ERC20) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_CalculateL2TokenAddress_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CalculateL2TokenAddress' +type L2ArbitrumGatewayInterface_CalculateL2TokenAddress_Call struct { + *mock.Call +} + +// CalculateL2TokenAddress is a helper method to define mock.On call +// - opts *bind.CallOpts +// - l1ERC20 common.Address +func (_e *L2ArbitrumGatewayInterface_Expecter) CalculateL2TokenAddress(opts interface{}, l1ERC20 interface{}) *L2ArbitrumGatewayInterface_CalculateL2TokenAddress_Call { + return &L2ArbitrumGatewayInterface_CalculateL2TokenAddress_Call{Call: _e.mock.On("CalculateL2TokenAddress", opts, l1ERC20)} +} + +func (_c *L2ArbitrumGatewayInterface_CalculateL2TokenAddress_Call) Run(run func(opts *bind.CallOpts, l1ERC20 common.Address)) *L2ArbitrumGatewayInterface_CalculateL2TokenAddress_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_CalculateL2TokenAddress_Call) Return(_a0 common.Address, _a1 error) *L2ArbitrumGatewayInterface_CalculateL2TokenAddress_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_CalculateL2TokenAddress_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (common.Address, error)) *L2ArbitrumGatewayInterface_CalculateL2TokenAddress_Call { + _c.Call.Return(run) + return _c +} + +// CounterpartGateway provides a mock function with given fields: opts +func (_m *L2ArbitrumGatewayInterface) CounterpartGateway(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for CounterpartGateway") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_CounterpartGateway_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CounterpartGateway' +type L2ArbitrumGatewayInterface_CounterpartGateway_Call struct { + *mock.Call +} + +// CounterpartGateway is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *L2ArbitrumGatewayInterface_Expecter) CounterpartGateway(opts interface{}) *L2ArbitrumGatewayInterface_CounterpartGateway_Call { + return &L2ArbitrumGatewayInterface_CounterpartGateway_Call{Call: _e.mock.On("CounterpartGateway", opts)} +} + +func (_c *L2ArbitrumGatewayInterface_CounterpartGateway_Call) Run(run func(opts *bind.CallOpts)) *L2ArbitrumGatewayInterface_CounterpartGateway_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_CounterpartGateway_Call) Return(_a0 common.Address, _a1 error) *L2ArbitrumGatewayInterface_CounterpartGateway_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_CounterpartGateway_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *L2ArbitrumGatewayInterface_CounterpartGateway_Call { + _c.Call.Return(run) + return _c +} + +// ExitNum provides a mock function with given fields: opts +func (_m *L2ArbitrumGatewayInterface) ExitNum(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for ExitNum") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_ExitNum_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExitNum' +type L2ArbitrumGatewayInterface_ExitNum_Call struct { + *mock.Call +} + +// ExitNum is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *L2ArbitrumGatewayInterface_Expecter) ExitNum(opts interface{}) *L2ArbitrumGatewayInterface_ExitNum_Call { + return &L2ArbitrumGatewayInterface_ExitNum_Call{Call: _e.mock.On("ExitNum", opts)} +} + +func (_c *L2ArbitrumGatewayInterface_ExitNum_Call) Run(run func(opts *bind.CallOpts)) *L2ArbitrumGatewayInterface_ExitNum_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_ExitNum_Call) Return(_a0 *big.Int, _a1 error) *L2ArbitrumGatewayInterface_ExitNum_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_ExitNum_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *L2ArbitrumGatewayInterface_ExitNum_Call { + _c.Call.Return(run) + return _c +} + +// FilterDepositFinalized provides a mock function with given fields: opts, l1Token, _from, _to +func (_m *L2ArbitrumGatewayInterface) FilterDepositFinalized(opts *bind.FilterOpts, l1Token []common.Address, _from []common.Address, _to []common.Address) (*l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalizedIterator, error) { + ret := _m.Called(opts, l1Token, _from, _to) + + if len(ret) == 0 { + panic("no return value specified for FilterDepositFinalized") + } + + var r0 *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalizedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address, []common.Address) (*l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalizedIterator, error)); ok { + return rf(opts, l1Token, _from, _to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address, []common.Address) *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalizedIterator); ok { + r0 = rf(opts, l1Token, _from, _to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalizedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address, []common.Address) error); ok { + r1 = rf(opts, l1Token, _from, _to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_FilterDepositFinalized_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterDepositFinalized' +type L2ArbitrumGatewayInterface_FilterDepositFinalized_Call struct { + *mock.Call +} + +// FilterDepositFinalized is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - l1Token []common.Address +// - _from []common.Address +// - _to []common.Address +func (_e *L2ArbitrumGatewayInterface_Expecter) FilterDepositFinalized(opts interface{}, l1Token interface{}, _from interface{}, _to interface{}) *L2ArbitrumGatewayInterface_FilterDepositFinalized_Call { + return &L2ArbitrumGatewayInterface_FilterDepositFinalized_Call{Call: _e.mock.On("FilterDepositFinalized", opts, l1Token, _from, _to)} +} + +func (_c *L2ArbitrumGatewayInterface_FilterDepositFinalized_Call) Run(run func(opts *bind.FilterOpts, l1Token []common.Address, _from []common.Address, _to []common.Address)) *L2ArbitrumGatewayInterface_FilterDepositFinalized_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_FilterDepositFinalized_Call) Return(_a0 *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalizedIterator, _a1 error) *L2ArbitrumGatewayInterface_FilterDepositFinalized_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_FilterDepositFinalized_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address, []common.Address) (*l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalizedIterator, error)) *L2ArbitrumGatewayInterface_FilterDepositFinalized_Call { + _c.Call.Return(run) + return _c +} + +// FilterTxToL1 provides a mock function with given fields: opts, _from, _to, _id +func (_m *L2ArbitrumGatewayInterface) FilterTxToL1(opts *bind.FilterOpts, _from []common.Address, _to []common.Address, _id []*big.Int) (*l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1Iterator, error) { + ret := _m.Called(opts, _from, _to, _id) + + if len(ret) == 0 { + panic("no return value specified for FilterTxToL1") + } + + var r0 *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1Iterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address, []*big.Int) (*l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1Iterator, error)); ok { + return rf(opts, _from, _to, _id) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address, []*big.Int) *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1Iterator); ok { + r0 = rf(opts, _from, _to, _id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1Iterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address, []*big.Int) error); ok { + r1 = rf(opts, _from, _to, _id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_FilterTxToL1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTxToL1' +type L2ArbitrumGatewayInterface_FilterTxToL1_Call struct { + *mock.Call +} + +// FilterTxToL1 is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - _from []common.Address +// - _to []common.Address +// - _id []*big.Int +func (_e *L2ArbitrumGatewayInterface_Expecter) FilterTxToL1(opts interface{}, _from interface{}, _to interface{}, _id interface{}) *L2ArbitrumGatewayInterface_FilterTxToL1_Call { + return &L2ArbitrumGatewayInterface_FilterTxToL1_Call{Call: _e.mock.On("FilterTxToL1", opts, _from, _to, _id)} +} + +func (_c *L2ArbitrumGatewayInterface_FilterTxToL1_Call) Run(run func(opts *bind.FilterOpts, _from []common.Address, _to []common.Address, _id []*big.Int)) *L2ArbitrumGatewayInterface_FilterTxToL1_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address), args[3].([]*big.Int)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_FilterTxToL1_Call) Return(_a0 *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1Iterator, _a1 error) *L2ArbitrumGatewayInterface_FilterTxToL1_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_FilterTxToL1_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address, []*big.Int) (*l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1Iterator, error)) *L2ArbitrumGatewayInterface_FilterTxToL1_Call { + _c.Call.Return(run) + return _c +} + +// FilterWithdrawalInitiated provides a mock function with given fields: opts, _from, _to, _l2ToL1Id +func (_m *L2ArbitrumGatewayInterface) FilterWithdrawalInitiated(opts *bind.FilterOpts, _from []common.Address, _to []common.Address, _l2ToL1Id []*big.Int) (*l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiatedIterator, error) { + ret := _m.Called(opts, _from, _to, _l2ToL1Id) + + if len(ret) == 0 { + panic("no return value specified for FilterWithdrawalInitiated") + } + + var r0 *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address, []*big.Int) (*l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiatedIterator, error)); ok { + return rf(opts, _from, _to, _l2ToL1Id) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address, []*big.Int) *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiatedIterator); ok { + r0 = rf(opts, _from, _to, _l2ToL1Id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address, []*big.Int) error); ok { + r1 = rf(opts, _from, _to, _l2ToL1Id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_FilterWithdrawalInitiated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterWithdrawalInitiated' +type L2ArbitrumGatewayInterface_FilterWithdrawalInitiated_Call struct { + *mock.Call +} + +// FilterWithdrawalInitiated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - _from []common.Address +// - _to []common.Address +// - _l2ToL1Id []*big.Int +func (_e *L2ArbitrumGatewayInterface_Expecter) FilterWithdrawalInitiated(opts interface{}, _from interface{}, _to interface{}, _l2ToL1Id interface{}) *L2ArbitrumGatewayInterface_FilterWithdrawalInitiated_Call { + return &L2ArbitrumGatewayInterface_FilterWithdrawalInitiated_Call{Call: _e.mock.On("FilterWithdrawalInitiated", opts, _from, _to, _l2ToL1Id)} +} + +func (_c *L2ArbitrumGatewayInterface_FilterWithdrawalInitiated_Call) Run(run func(opts *bind.FilterOpts, _from []common.Address, _to []common.Address, _l2ToL1Id []*big.Int)) *L2ArbitrumGatewayInterface_FilterWithdrawalInitiated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address), args[3].([]*big.Int)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_FilterWithdrawalInitiated_Call) Return(_a0 *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiatedIterator, _a1 error) *L2ArbitrumGatewayInterface_FilterWithdrawalInitiated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_FilterWithdrawalInitiated_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address, []*big.Int) (*l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiatedIterator, error)) *L2ArbitrumGatewayInterface_FilterWithdrawalInitiated_Call { + _c.Call.Return(run) + return _c +} + +// FinalizeInboundTransfer provides a mock function with given fields: opts, _token, _from, _to, _amount, _data +func (_m *L2ArbitrumGatewayInterface) FinalizeInboundTransfer(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + ret := _m.Called(opts, _token, _from, _to, _amount, _data) + + if len(ret) == 0 { + panic("no return value specified for FinalizeInboundTransfer") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) (*types.Transaction, error)); ok { + return rf(opts, _token, _from, _to, _amount, _data) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) *types.Transaction); ok { + r0 = rf(opts, _token, _from, _to, _amount, _data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) error); ok { + r1 = rf(opts, _token, _from, _to, _amount, _data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_FinalizeInboundTransfer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FinalizeInboundTransfer' +type L2ArbitrumGatewayInterface_FinalizeInboundTransfer_Call struct { + *mock.Call +} + +// FinalizeInboundTransfer is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _token common.Address +// - _from common.Address +// - _to common.Address +// - _amount *big.Int +// - _data []byte +func (_e *L2ArbitrumGatewayInterface_Expecter) FinalizeInboundTransfer(opts interface{}, _token interface{}, _from interface{}, _to interface{}, _amount interface{}, _data interface{}) *L2ArbitrumGatewayInterface_FinalizeInboundTransfer_Call { + return &L2ArbitrumGatewayInterface_FinalizeInboundTransfer_Call{Call: _e.mock.On("FinalizeInboundTransfer", opts, _token, _from, _to, _amount, _data)} +} + +func (_c *L2ArbitrumGatewayInterface_FinalizeInboundTransfer_Call) Run(run func(opts *bind.TransactOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte)) *L2ArbitrumGatewayInterface_FinalizeInboundTransfer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(common.Address), args[3].(common.Address), args[4].(*big.Int), args[5].([]byte)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_FinalizeInboundTransfer_Call) Return(_a0 *types.Transaction, _a1 error) *L2ArbitrumGatewayInterface_FinalizeInboundTransfer_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_FinalizeInboundTransfer_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, common.Address, common.Address, *big.Int, []byte) (*types.Transaction, error)) *L2ArbitrumGatewayInterface_FinalizeInboundTransfer_Call { + _c.Call.Return(run) + return _c +} + +// GetOutboundCalldata provides a mock function with given fields: opts, _token, _from, _to, _amount, _data +func (_m *L2ArbitrumGatewayInterface) GetOutboundCalldata(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte) ([]byte, error) { + ret := _m.Called(opts, _token, _from, _to, _amount, _data) + + if len(ret) == 0 { + panic("no return value specified for GetOutboundCalldata") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, common.Address, common.Address, *big.Int, []byte) ([]byte, error)); ok { + return rf(opts, _token, _from, _to, _amount, _data) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, common.Address, common.Address, *big.Int, []byte) []byte); ok { + r0 = rf(opts, _token, _from, _to, _amount, _data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address, common.Address, common.Address, *big.Int, []byte) error); ok { + r1 = rf(opts, _token, _from, _to, _amount, _data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_GetOutboundCalldata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetOutboundCalldata' +type L2ArbitrumGatewayInterface_GetOutboundCalldata_Call struct { + *mock.Call +} + +// GetOutboundCalldata is a helper method to define mock.On call +// - opts *bind.CallOpts +// - _token common.Address +// - _from common.Address +// - _to common.Address +// - _amount *big.Int +// - _data []byte +func (_e *L2ArbitrumGatewayInterface_Expecter) GetOutboundCalldata(opts interface{}, _token interface{}, _from interface{}, _to interface{}, _amount interface{}, _data interface{}) *L2ArbitrumGatewayInterface_GetOutboundCalldata_Call { + return &L2ArbitrumGatewayInterface_GetOutboundCalldata_Call{Call: _e.mock.On("GetOutboundCalldata", opts, _token, _from, _to, _amount, _data)} +} + +func (_c *L2ArbitrumGatewayInterface_GetOutboundCalldata_Call) Run(run func(opts *bind.CallOpts, _token common.Address, _from common.Address, _to common.Address, _amount *big.Int, _data []byte)) *L2ArbitrumGatewayInterface_GetOutboundCalldata_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address), args[2].(common.Address), args[3].(common.Address), args[4].(*big.Int), args[5].([]byte)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_GetOutboundCalldata_Call) Return(_a0 []byte, _a1 error) *L2ArbitrumGatewayInterface_GetOutboundCalldata_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_GetOutboundCalldata_Call) RunAndReturn(run func(*bind.CallOpts, common.Address, common.Address, common.Address, *big.Int, []byte) ([]byte, error)) *L2ArbitrumGatewayInterface_GetOutboundCalldata_Call { + _c.Call.Return(run) + return _c +} + +// OutboundTransfer provides a mock function with given fields: opts, _l1Token, _to, _amount, _data +func (_m *L2ArbitrumGatewayInterface) OutboundTransfer(opts *bind.TransactOpts, _l1Token common.Address, _to common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { + ret := _m.Called(opts, _l1Token, _to, _amount, _data) + + if len(ret) == 0 { + panic("no return value specified for OutboundTransfer") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, *big.Int, []byte) (*types.Transaction, error)); ok { + return rf(opts, _l1Token, _to, _amount, _data) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, *big.Int, []byte) *types.Transaction); ok { + r0 = rf(opts, _l1Token, _to, _amount, _data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, common.Address, *big.Int, []byte) error); ok { + r1 = rf(opts, _l1Token, _to, _amount, _data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_OutboundTransfer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OutboundTransfer' +type L2ArbitrumGatewayInterface_OutboundTransfer_Call struct { + *mock.Call +} + +// OutboundTransfer is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _l1Token common.Address +// - _to common.Address +// - _amount *big.Int +// - _data []byte +func (_e *L2ArbitrumGatewayInterface_Expecter) OutboundTransfer(opts interface{}, _l1Token interface{}, _to interface{}, _amount interface{}, _data interface{}) *L2ArbitrumGatewayInterface_OutboundTransfer_Call { + return &L2ArbitrumGatewayInterface_OutboundTransfer_Call{Call: _e.mock.On("OutboundTransfer", opts, _l1Token, _to, _amount, _data)} +} + +func (_c *L2ArbitrumGatewayInterface_OutboundTransfer_Call) Run(run func(opts *bind.TransactOpts, _l1Token common.Address, _to common.Address, _amount *big.Int, _data []byte)) *L2ArbitrumGatewayInterface_OutboundTransfer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(common.Address), args[3].(*big.Int), args[4].([]byte)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_OutboundTransfer_Call) Return(_a0 *types.Transaction, _a1 error) *L2ArbitrumGatewayInterface_OutboundTransfer_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_OutboundTransfer_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, common.Address, *big.Int, []byte) (*types.Transaction, error)) *L2ArbitrumGatewayInterface_OutboundTransfer_Call { + _c.Call.Return(run) + return _c +} + +// OutboundTransfer0 provides a mock function with given fields: opts, _l1Token, _to, _amount, arg3, arg4, _data +func (_m *L2ArbitrumGatewayInterface) OutboundTransfer0(opts *bind.TransactOpts, _l1Token common.Address, _to common.Address, _amount *big.Int, arg3 *big.Int, arg4 *big.Int, _data []byte) (*types.Transaction, error) { + ret := _m.Called(opts, _l1Token, _to, _amount, arg3, arg4, _data) + + if len(ret) == 0 { + panic("no return value specified for OutboundTransfer0") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, *big.Int, *big.Int, *big.Int, []byte) (*types.Transaction, error)); ok { + return rf(opts, _l1Token, _to, _amount, arg3, arg4, _data) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, common.Address, *big.Int, *big.Int, *big.Int, []byte) *types.Transaction); ok { + r0 = rf(opts, _l1Token, _to, _amount, arg3, arg4, _data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, common.Address, *big.Int, *big.Int, *big.Int, []byte) error); ok { + r1 = rf(opts, _l1Token, _to, _amount, arg3, arg4, _data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_OutboundTransfer0_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OutboundTransfer0' +type L2ArbitrumGatewayInterface_OutboundTransfer0_Call struct { + *mock.Call +} + +// OutboundTransfer0 is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _l1Token common.Address +// - _to common.Address +// - _amount *big.Int +// - arg3 *big.Int +// - arg4 *big.Int +// - _data []byte +func (_e *L2ArbitrumGatewayInterface_Expecter) OutboundTransfer0(opts interface{}, _l1Token interface{}, _to interface{}, _amount interface{}, arg3 interface{}, arg4 interface{}, _data interface{}) *L2ArbitrumGatewayInterface_OutboundTransfer0_Call { + return &L2ArbitrumGatewayInterface_OutboundTransfer0_Call{Call: _e.mock.On("OutboundTransfer0", opts, _l1Token, _to, _amount, arg3, arg4, _data)} +} + +func (_c *L2ArbitrumGatewayInterface_OutboundTransfer0_Call) Run(run func(opts *bind.TransactOpts, _l1Token common.Address, _to common.Address, _amount *big.Int, arg3 *big.Int, arg4 *big.Int, _data []byte)) *L2ArbitrumGatewayInterface_OutboundTransfer0_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(common.Address), args[3].(*big.Int), args[4].(*big.Int), args[5].(*big.Int), args[6].([]byte)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_OutboundTransfer0_Call) Return(_a0 *types.Transaction, _a1 error) *L2ArbitrumGatewayInterface_OutboundTransfer0_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_OutboundTransfer0_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, common.Address, *big.Int, *big.Int, *big.Int, []byte) (*types.Transaction, error)) *L2ArbitrumGatewayInterface_OutboundTransfer0_Call { + _c.Call.Return(run) + return _c +} + +// ParseDepositFinalized provides a mock function with given fields: log +func (_m *L2ArbitrumGatewayInterface) ParseDepositFinalized(log types.Log) (*l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseDepositFinalized") + } + + var r0 *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_ParseDepositFinalized_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseDepositFinalized' +type L2ArbitrumGatewayInterface_ParseDepositFinalized_Call struct { + *mock.Call +} + +// ParseDepositFinalized is a helper method to define mock.On call +// - log types.Log +func (_e *L2ArbitrumGatewayInterface_Expecter) ParseDepositFinalized(log interface{}) *L2ArbitrumGatewayInterface_ParseDepositFinalized_Call { + return &L2ArbitrumGatewayInterface_ParseDepositFinalized_Call{Call: _e.mock.On("ParseDepositFinalized", log)} +} + +func (_c *L2ArbitrumGatewayInterface_ParseDepositFinalized_Call) Run(run func(log types.Log)) *L2ArbitrumGatewayInterface_ParseDepositFinalized_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_ParseDepositFinalized_Call) Return(_a0 *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized, _a1 error) *L2ArbitrumGatewayInterface_ParseDepositFinalized_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_ParseDepositFinalized_Call) RunAndReturn(run func(types.Log) (*l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized, error)) *L2ArbitrumGatewayInterface_ParseDepositFinalized_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *L2ArbitrumGatewayInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type L2ArbitrumGatewayInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *L2ArbitrumGatewayInterface_Expecter) ParseLog(log interface{}) *L2ArbitrumGatewayInterface_ParseLog_Call { + return &L2ArbitrumGatewayInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *L2ArbitrumGatewayInterface_ParseLog_Call) Run(run func(log types.Log)) *L2ArbitrumGatewayInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *L2ArbitrumGatewayInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *L2ArbitrumGatewayInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseTxToL1 provides a mock function with given fields: log +func (_m *L2ArbitrumGatewayInterface) ParseTxToL1(log types.Log) (*l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTxToL1") + } + + var r0 *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1 + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_ParseTxToL1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTxToL1' +type L2ArbitrumGatewayInterface_ParseTxToL1_Call struct { + *mock.Call +} + +// ParseTxToL1 is a helper method to define mock.On call +// - log types.Log +func (_e *L2ArbitrumGatewayInterface_Expecter) ParseTxToL1(log interface{}) *L2ArbitrumGatewayInterface_ParseTxToL1_Call { + return &L2ArbitrumGatewayInterface_ParseTxToL1_Call{Call: _e.mock.On("ParseTxToL1", log)} +} + +func (_c *L2ArbitrumGatewayInterface_ParseTxToL1_Call) Run(run func(log types.Log)) *L2ArbitrumGatewayInterface_ParseTxToL1_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_ParseTxToL1_Call) Return(_a0 *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1, _a1 error) *L2ArbitrumGatewayInterface_ParseTxToL1_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_ParseTxToL1_Call) RunAndReturn(run func(types.Log) (*l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1, error)) *L2ArbitrumGatewayInterface_ParseTxToL1_Call { + _c.Call.Return(run) + return _c +} + +// ParseWithdrawalInitiated provides a mock function with given fields: log +func (_m *L2ArbitrumGatewayInterface) ParseWithdrawalInitiated(log types.Log) (*l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseWithdrawalInitiated") + } + + var r0 *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_ParseWithdrawalInitiated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseWithdrawalInitiated' +type L2ArbitrumGatewayInterface_ParseWithdrawalInitiated_Call struct { + *mock.Call +} + +// ParseWithdrawalInitiated is a helper method to define mock.On call +// - log types.Log +func (_e *L2ArbitrumGatewayInterface_Expecter) ParseWithdrawalInitiated(log interface{}) *L2ArbitrumGatewayInterface_ParseWithdrawalInitiated_Call { + return &L2ArbitrumGatewayInterface_ParseWithdrawalInitiated_Call{Call: _e.mock.On("ParseWithdrawalInitiated", log)} +} + +func (_c *L2ArbitrumGatewayInterface_ParseWithdrawalInitiated_Call) Run(run func(log types.Log)) *L2ArbitrumGatewayInterface_ParseWithdrawalInitiated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_ParseWithdrawalInitiated_Call) Return(_a0 *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated, _a1 error) *L2ArbitrumGatewayInterface_ParseWithdrawalInitiated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_ParseWithdrawalInitiated_Call) RunAndReturn(run func(types.Log) (*l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated, error)) *L2ArbitrumGatewayInterface_ParseWithdrawalInitiated_Call { + _c.Call.Return(run) + return _c +} + +// PostUpgradeInit provides a mock function with given fields: opts +func (_m *L2ArbitrumGatewayInterface) PostUpgradeInit(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for PostUpgradeInit") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_PostUpgradeInit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PostUpgradeInit' +type L2ArbitrumGatewayInterface_PostUpgradeInit_Call struct { + *mock.Call +} + +// PostUpgradeInit is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *L2ArbitrumGatewayInterface_Expecter) PostUpgradeInit(opts interface{}) *L2ArbitrumGatewayInterface_PostUpgradeInit_Call { + return &L2ArbitrumGatewayInterface_PostUpgradeInit_Call{Call: _e.mock.On("PostUpgradeInit", opts)} +} + +func (_c *L2ArbitrumGatewayInterface_PostUpgradeInit_Call) Run(run func(opts *bind.TransactOpts)) *L2ArbitrumGatewayInterface_PostUpgradeInit_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_PostUpgradeInit_Call) Return(_a0 *types.Transaction, _a1 error) *L2ArbitrumGatewayInterface_PostUpgradeInit_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_PostUpgradeInit_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *L2ArbitrumGatewayInterface_PostUpgradeInit_Call { + _c.Call.Return(run) + return _c +} + +// Router provides a mock function with given fields: opts +func (_m *L2ArbitrumGatewayInterface) Router(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Router") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_Router_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Router' +type L2ArbitrumGatewayInterface_Router_Call struct { + *mock.Call +} + +// Router is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *L2ArbitrumGatewayInterface_Expecter) Router(opts interface{}) *L2ArbitrumGatewayInterface_Router_Call { + return &L2ArbitrumGatewayInterface_Router_Call{Call: _e.mock.On("Router", opts)} +} + +func (_c *L2ArbitrumGatewayInterface_Router_Call) Run(run func(opts *bind.CallOpts)) *L2ArbitrumGatewayInterface_Router_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_Router_Call) Return(_a0 common.Address, _a1 error) *L2ArbitrumGatewayInterface_Router_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_Router_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *L2ArbitrumGatewayInterface_Router_Call { + _c.Call.Return(run) + return _c +} + +// WatchDepositFinalized provides a mock function with given fields: opts, sink, l1Token, _from, _to +func (_m *L2ArbitrumGatewayInterface) WatchDepositFinalized(opts *bind.WatchOpts, sink chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized, l1Token []common.Address, _from []common.Address, _to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, l1Token, _from, _to) + + if len(ret) == 0 { + panic("no return value specified for WatchDepositFinalized") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized, []common.Address, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, l1Token, _from, _to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized, []common.Address, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, l1Token, _from, _to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized, []common.Address, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, l1Token, _from, _to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_WatchDepositFinalized_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchDepositFinalized' +type L2ArbitrumGatewayInterface_WatchDepositFinalized_Call struct { + *mock.Call +} + +// WatchDepositFinalized is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized +// - l1Token []common.Address +// - _from []common.Address +// - _to []common.Address +func (_e *L2ArbitrumGatewayInterface_Expecter) WatchDepositFinalized(opts interface{}, sink interface{}, l1Token interface{}, _from interface{}, _to interface{}) *L2ArbitrumGatewayInterface_WatchDepositFinalized_Call { + return &L2ArbitrumGatewayInterface_WatchDepositFinalized_Call{Call: _e.mock.On("WatchDepositFinalized", opts, sink, l1Token, _from, _to)} +} + +func (_c *L2ArbitrumGatewayInterface_WatchDepositFinalized_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized, l1Token []common.Address, _from []common.Address, _to []common.Address)) *L2ArbitrumGatewayInterface_WatchDepositFinalized_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized), args[2].([]common.Address), args[3].([]common.Address), args[4].([]common.Address)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_WatchDepositFinalized_Call) Return(_a0 event.Subscription, _a1 error) *L2ArbitrumGatewayInterface_WatchDepositFinalized_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_WatchDepositFinalized_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayDepositFinalized, []common.Address, []common.Address, []common.Address) (event.Subscription, error)) *L2ArbitrumGatewayInterface_WatchDepositFinalized_Call { + _c.Call.Return(run) + return _c +} + +// WatchTxToL1 provides a mock function with given fields: opts, sink, _from, _to, _id +func (_m *L2ArbitrumGatewayInterface) WatchTxToL1(opts *bind.WatchOpts, sink chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1, _from []common.Address, _to []common.Address, _id []*big.Int) (event.Subscription, error) { + ret := _m.Called(opts, sink, _from, _to, _id) + + if len(ret) == 0 { + panic("no return value specified for WatchTxToL1") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1, []common.Address, []common.Address, []*big.Int) (event.Subscription, error)); ok { + return rf(opts, sink, _from, _to, _id) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1, []common.Address, []common.Address, []*big.Int) event.Subscription); ok { + r0 = rf(opts, sink, _from, _to, _id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1, []common.Address, []common.Address, []*big.Int) error); ok { + r1 = rf(opts, sink, _from, _to, _id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_WatchTxToL1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTxToL1' +type L2ArbitrumGatewayInterface_WatchTxToL1_Call struct { + *mock.Call +} + +// WatchTxToL1 is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1 +// - _from []common.Address +// - _to []common.Address +// - _id []*big.Int +func (_e *L2ArbitrumGatewayInterface_Expecter) WatchTxToL1(opts interface{}, sink interface{}, _from interface{}, _to interface{}, _id interface{}) *L2ArbitrumGatewayInterface_WatchTxToL1_Call { + return &L2ArbitrumGatewayInterface_WatchTxToL1_Call{Call: _e.mock.On("WatchTxToL1", opts, sink, _from, _to, _id)} +} + +func (_c *L2ArbitrumGatewayInterface_WatchTxToL1_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1, _from []common.Address, _to []common.Address, _id []*big.Int)) *L2ArbitrumGatewayInterface_WatchTxToL1_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1), args[2].([]common.Address), args[3].([]common.Address), args[4].([]*big.Int)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_WatchTxToL1_Call) Return(_a0 event.Subscription, _a1 error) *L2ArbitrumGatewayInterface_WatchTxToL1_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_WatchTxToL1_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayTxToL1, []common.Address, []common.Address, []*big.Int) (event.Subscription, error)) *L2ArbitrumGatewayInterface_WatchTxToL1_Call { + _c.Call.Return(run) + return _c +} + +// WatchWithdrawalInitiated provides a mock function with given fields: opts, sink, _from, _to, _l2ToL1Id +func (_m *L2ArbitrumGatewayInterface) WatchWithdrawalInitiated(opts *bind.WatchOpts, sink chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated, _from []common.Address, _to []common.Address, _l2ToL1Id []*big.Int) (event.Subscription, error) { + ret := _m.Called(opts, sink, _from, _to, _l2ToL1Id) + + if len(ret) == 0 { + panic("no return value specified for WatchWithdrawalInitiated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated, []common.Address, []common.Address, []*big.Int) (event.Subscription, error)); ok { + return rf(opts, sink, _from, _to, _l2ToL1Id) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated, []common.Address, []common.Address, []*big.Int) event.Subscription); ok { + r0 = rf(opts, sink, _from, _to, _l2ToL1Id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated, []common.Address, []common.Address, []*big.Int) error); ok { + r1 = rf(opts, sink, _from, _to, _l2ToL1Id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumGatewayInterface_WatchWithdrawalInitiated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchWithdrawalInitiated' +type L2ArbitrumGatewayInterface_WatchWithdrawalInitiated_Call struct { + *mock.Call +} + +// WatchWithdrawalInitiated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated +// - _from []common.Address +// - _to []common.Address +// - _l2ToL1Id []*big.Int +func (_e *L2ArbitrumGatewayInterface_Expecter) WatchWithdrawalInitiated(opts interface{}, sink interface{}, _from interface{}, _to interface{}, _l2ToL1Id interface{}) *L2ArbitrumGatewayInterface_WatchWithdrawalInitiated_Call { + return &L2ArbitrumGatewayInterface_WatchWithdrawalInitiated_Call{Call: _e.mock.On("WatchWithdrawalInitiated", opts, sink, _from, _to, _l2ToL1Id)} +} + +func (_c *L2ArbitrumGatewayInterface_WatchWithdrawalInitiated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated, _from []common.Address, _to []common.Address, _l2ToL1Id []*big.Int)) *L2ArbitrumGatewayInterface_WatchWithdrawalInitiated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated), args[2].([]common.Address), args[3].([]common.Address), args[4].([]*big.Int)) + }) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_WatchWithdrawalInitiated_Call) Return(_a0 event.Subscription, _a1 error) *L2ArbitrumGatewayInterface_WatchWithdrawalInitiated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumGatewayInterface_WatchWithdrawalInitiated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *l2_arbitrum_gateway.L2ArbitrumGatewayWithdrawalInitiated, []common.Address, []common.Address, []*big.Int) (event.Subscription, error)) *L2ArbitrumGatewayInterface_WatchWithdrawalInitiated_Call { + _c.Call.Return(run) + return _c +} + +// NewL2ArbitrumGatewayInterface creates a new instance of L2ArbitrumGatewayInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewL2ArbitrumGatewayInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *L2ArbitrumGatewayInterface { + mock := &L2ArbitrumGatewayInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_l2_arbitrum_messenger/l2_arbitrum_messenger_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_l2_arbitrum_messenger/l2_arbitrum_messenger_interface.go new file mode 100644 index 0000000000..126f870685 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_l2_arbitrum_messenger/l2_arbitrum_messenger_interface.go @@ -0,0 +1,333 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_l2_arbitrum_messenger + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + l2_arbitrum_messenger "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/l2_arbitrum_messenger" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// L2ArbitrumMessengerInterface is an autogenerated mock type for the L2ArbitrumMessengerInterface type +type L2ArbitrumMessengerInterface struct { + mock.Mock +} + +type L2ArbitrumMessengerInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *L2ArbitrumMessengerInterface) EXPECT() *L2ArbitrumMessengerInterface_Expecter { + return &L2ArbitrumMessengerInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *L2ArbitrumMessengerInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// L2ArbitrumMessengerInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type L2ArbitrumMessengerInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *L2ArbitrumMessengerInterface_Expecter) Address() *L2ArbitrumMessengerInterface_Address_Call { + return &L2ArbitrumMessengerInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *L2ArbitrumMessengerInterface_Address_Call) Run(run func()) *L2ArbitrumMessengerInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *L2ArbitrumMessengerInterface_Address_Call) Return(_a0 common.Address) *L2ArbitrumMessengerInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *L2ArbitrumMessengerInterface_Address_Call) RunAndReturn(run func() common.Address) *L2ArbitrumMessengerInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// FilterTxToL1 provides a mock function with given fields: opts, _from, _to, _id +func (_m *L2ArbitrumMessengerInterface) FilterTxToL1(opts *bind.FilterOpts, _from []common.Address, _to []common.Address, _id []*big.Int) (*l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1Iterator, error) { + ret := _m.Called(opts, _from, _to, _id) + + if len(ret) == 0 { + panic("no return value specified for FilterTxToL1") + } + + var r0 *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1Iterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address, []*big.Int) (*l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1Iterator, error)); ok { + return rf(opts, _from, _to, _id) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address, []*big.Int) *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1Iterator); ok { + r0 = rf(opts, _from, _to, _id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1Iterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address, []*big.Int) error); ok { + r1 = rf(opts, _from, _to, _id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumMessengerInterface_FilterTxToL1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTxToL1' +type L2ArbitrumMessengerInterface_FilterTxToL1_Call struct { + *mock.Call +} + +// FilterTxToL1 is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - _from []common.Address +// - _to []common.Address +// - _id []*big.Int +func (_e *L2ArbitrumMessengerInterface_Expecter) FilterTxToL1(opts interface{}, _from interface{}, _to interface{}, _id interface{}) *L2ArbitrumMessengerInterface_FilterTxToL1_Call { + return &L2ArbitrumMessengerInterface_FilterTxToL1_Call{Call: _e.mock.On("FilterTxToL1", opts, _from, _to, _id)} +} + +func (_c *L2ArbitrumMessengerInterface_FilterTxToL1_Call) Run(run func(opts *bind.FilterOpts, _from []common.Address, _to []common.Address, _id []*big.Int)) *L2ArbitrumMessengerInterface_FilterTxToL1_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address), args[3].([]*big.Int)) + }) + return _c +} + +func (_c *L2ArbitrumMessengerInterface_FilterTxToL1_Call) Return(_a0 *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1Iterator, _a1 error) *L2ArbitrumMessengerInterface_FilterTxToL1_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumMessengerInterface_FilterTxToL1_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address, []*big.Int) (*l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1Iterator, error)) *L2ArbitrumMessengerInterface_FilterTxToL1_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *L2ArbitrumMessengerInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumMessengerInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type L2ArbitrumMessengerInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *L2ArbitrumMessengerInterface_Expecter) ParseLog(log interface{}) *L2ArbitrumMessengerInterface_ParseLog_Call { + return &L2ArbitrumMessengerInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *L2ArbitrumMessengerInterface_ParseLog_Call) Run(run func(log types.Log)) *L2ArbitrumMessengerInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *L2ArbitrumMessengerInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *L2ArbitrumMessengerInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumMessengerInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *L2ArbitrumMessengerInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseTxToL1 provides a mock function with given fields: log +func (_m *L2ArbitrumMessengerInterface) ParseTxToL1(log types.Log) (*l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTxToL1") + } + + var r0 *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1 + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumMessengerInterface_ParseTxToL1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTxToL1' +type L2ArbitrumMessengerInterface_ParseTxToL1_Call struct { + *mock.Call +} + +// ParseTxToL1 is a helper method to define mock.On call +// - log types.Log +func (_e *L2ArbitrumMessengerInterface_Expecter) ParseTxToL1(log interface{}) *L2ArbitrumMessengerInterface_ParseTxToL1_Call { + return &L2ArbitrumMessengerInterface_ParseTxToL1_Call{Call: _e.mock.On("ParseTxToL1", log)} +} + +func (_c *L2ArbitrumMessengerInterface_ParseTxToL1_Call) Run(run func(log types.Log)) *L2ArbitrumMessengerInterface_ParseTxToL1_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *L2ArbitrumMessengerInterface_ParseTxToL1_Call) Return(_a0 *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1, _a1 error) *L2ArbitrumMessengerInterface_ParseTxToL1_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumMessengerInterface_ParseTxToL1_Call) RunAndReturn(run func(types.Log) (*l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1, error)) *L2ArbitrumMessengerInterface_ParseTxToL1_Call { + _c.Call.Return(run) + return _c +} + +// WatchTxToL1 provides a mock function with given fields: opts, sink, _from, _to, _id +func (_m *L2ArbitrumMessengerInterface) WatchTxToL1(opts *bind.WatchOpts, sink chan<- *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1, _from []common.Address, _to []common.Address, _id []*big.Int) (event.Subscription, error) { + ret := _m.Called(opts, sink, _from, _to, _id) + + if len(ret) == 0 { + panic("no return value specified for WatchTxToL1") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1, []common.Address, []common.Address, []*big.Int) (event.Subscription, error)); ok { + return rf(opts, sink, _from, _to, _id) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1, []common.Address, []common.Address, []*big.Int) event.Subscription); ok { + r0 = rf(opts, sink, _from, _to, _id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1, []common.Address, []common.Address, []*big.Int) error); ok { + r1 = rf(opts, sink, _from, _to, _id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2ArbitrumMessengerInterface_WatchTxToL1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTxToL1' +type L2ArbitrumMessengerInterface_WatchTxToL1_Call struct { + *mock.Call +} + +// WatchTxToL1 is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1 +// - _from []common.Address +// - _to []common.Address +// - _id []*big.Int +func (_e *L2ArbitrumMessengerInterface_Expecter) WatchTxToL1(opts interface{}, sink interface{}, _from interface{}, _to interface{}, _id interface{}) *L2ArbitrumMessengerInterface_WatchTxToL1_Call { + return &L2ArbitrumMessengerInterface_WatchTxToL1_Call{Call: _e.mock.On("WatchTxToL1", opts, sink, _from, _to, _id)} +} + +func (_c *L2ArbitrumMessengerInterface_WatchTxToL1_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1, _from []common.Address, _to []common.Address, _id []*big.Int)) *L2ArbitrumMessengerInterface_WatchTxToL1_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1), args[2].([]common.Address), args[3].([]common.Address), args[4].([]*big.Int)) + }) + return _c +} + +func (_c *L2ArbitrumMessengerInterface_WatchTxToL1_Call) Return(_a0 event.Subscription, _a1 error) *L2ArbitrumMessengerInterface_WatchTxToL1_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2ArbitrumMessengerInterface_WatchTxToL1_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *l2_arbitrum_messenger.L2ArbitrumMessengerTxToL1, []common.Address, []common.Address, []*big.Int) (event.Subscription, error)) *L2ArbitrumMessengerInterface_WatchTxToL1_Call { + _c.Call.Return(run) + return _c +} + +// NewL2ArbitrumMessengerInterface creates a new instance of L2ArbitrumMessengerInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewL2ArbitrumMessengerInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *L2ArbitrumMessengerInterface { + mock := &L2ArbitrumMessengerInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_node_interface/node_interface_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_node_interface/node_interface_interface.go new file mode 100644 index 0000000000..8210f1050e --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_node_interface/node_interface_interface.go @@ -0,0 +1,680 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_node_interface + +import ( + big "math/big" + + arb_node_interface "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arb_node_interface" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// NodeInterfaceInterface is an autogenerated mock type for the NodeInterfaceInterface type +type NodeInterfaceInterface struct { + mock.Mock +} + +type NodeInterfaceInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *NodeInterfaceInterface) EXPECT() *NodeInterfaceInterface_Expecter { + return &NodeInterfaceInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *NodeInterfaceInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// NodeInterfaceInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type NodeInterfaceInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *NodeInterfaceInterface_Expecter) Address() *NodeInterfaceInterface_Address_Call { + return &NodeInterfaceInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *NodeInterfaceInterface_Address_Call) Run(run func()) *NodeInterfaceInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *NodeInterfaceInterface_Address_Call) Return(_a0 common.Address) *NodeInterfaceInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *NodeInterfaceInterface_Address_Call) RunAndReturn(run func() common.Address) *NodeInterfaceInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// BlockL1Num provides a mock function with given fields: opts, l2BlockNum +func (_m *NodeInterfaceInterface) BlockL1Num(opts *bind.CallOpts, l2BlockNum uint64) (uint64, error) { + ret := _m.Called(opts, l2BlockNum) + + if len(ret) == 0 { + panic("no return value specified for BlockL1Num") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (uint64, error)); ok { + return rf(opts, l2BlockNum) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) uint64); ok { + r0 = rf(opts, l2BlockNum) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, l2BlockNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NodeInterfaceInterface_BlockL1Num_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BlockL1Num' +type NodeInterfaceInterface_BlockL1Num_Call struct { + *mock.Call +} + +// BlockL1Num is a helper method to define mock.On call +// - opts *bind.CallOpts +// - l2BlockNum uint64 +func (_e *NodeInterfaceInterface_Expecter) BlockL1Num(opts interface{}, l2BlockNum interface{}) *NodeInterfaceInterface_BlockL1Num_Call { + return &NodeInterfaceInterface_BlockL1Num_Call{Call: _e.mock.On("BlockL1Num", opts, l2BlockNum)} +} + +func (_c *NodeInterfaceInterface_BlockL1Num_Call) Run(run func(opts *bind.CallOpts, l2BlockNum uint64)) *NodeInterfaceInterface_BlockL1Num_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *NodeInterfaceInterface_BlockL1Num_Call) Return(_a0 uint64, _a1 error) *NodeInterfaceInterface_BlockL1Num_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *NodeInterfaceInterface_BlockL1Num_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (uint64, error)) *NodeInterfaceInterface_BlockL1Num_Call { + _c.Call.Return(run) + return _c +} + +// ConstructOutboxProof provides a mock function with given fields: opts, size, leaf +func (_m *NodeInterfaceInterface) ConstructOutboxProof(opts *bind.CallOpts, size uint64, leaf uint64) (arb_node_interface.ConstructOutboxProof, error) { + ret := _m.Called(opts, size, leaf) + + if len(ret) == 0 { + panic("no return value specified for ConstructOutboxProof") + } + + var r0 arb_node_interface.ConstructOutboxProof + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, uint64) (arb_node_interface.ConstructOutboxProof, error)); ok { + return rf(opts, size, leaf) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, uint64) arb_node_interface.ConstructOutboxProof); ok { + r0 = rf(opts, size, leaf) + } else { + r0 = ret.Get(0).(arb_node_interface.ConstructOutboxProof) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, uint64) error); ok { + r1 = rf(opts, size, leaf) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NodeInterfaceInterface_ConstructOutboxProof_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ConstructOutboxProof' +type NodeInterfaceInterface_ConstructOutboxProof_Call struct { + *mock.Call +} + +// ConstructOutboxProof is a helper method to define mock.On call +// - opts *bind.CallOpts +// - size uint64 +// - leaf uint64 +func (_e *NodeInterfaceInterface_Expecter) ConstructOutboxProof(opts interface{}, size interface{}, leaf interface{}) *NodeInterfaceInterface_ConstructOutboxProof_Call { + return &NodeInterfaceInterface_ConstructOutboxProof_Call{Call: _e.mock.On("ConstructOutboxProof", opts, size, leaf)} +} + +func (_c *NodeInterfaceInterface_ConstructOutboxProof_Call) Run(run func(opts *bind.CallOpts, size uint64, leaf uint64)) *NodeInterfaceInterface_ConstructOutboxProof_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(uint64)) + }) + return _c +} + +func (_c *NodeInterfaceInterface_ConstructOutboxProof_Call) Return(_a0 arb_node_interface.ConstructOutboxProof, _a1 error) *NodeInterfaceInterface_ConstructOutboxProof_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *NodeInterfaceInterface_ConstructOutboxProof_Call) RunAndReturn(run func(*bind.CallOpts, uint64, uint64) (arb_node_interface.ConstructOutboxProof, error)) *NodeInterfaceInterface_ConstructOutboxProof_Call { + _c.Call.Return(run) + return _c +} + +// EstimateRetryableTicket provides a mock function with given fields: opts, sender, deposit, to, l2CallValue, excessFeeRefundAddress, callValueRefundAddress, data +func (_m *NodeInterfaceInterface) EstimateRetryableTicket(opts *bind.TransactOpts, sender common.Address, deposit *big.Int, to common.Address, l2CallValue *big.Int, excessFeeRefundAddress common.Address, callValueRefundAddress common.Address, data []byte) (*types.Transaction, error) { + ret := _m.Called(opts, sender, deposit, to, l2CallValue, excessFeeRefundAddress, callValueRefundAddress, data) + + if len(ret) == 0 { + panic("no return value specified for EstimateRetryableTicket") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, *big.Int, common.Address, *big.Int, common.Address, common.Address, []byte) (*types.Transaction, error)); ok { + return rf(opts, sender, deposit, to, l2CallValue, excessFeeRefundAddress, callValueRefundAddress, data) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, *big.Int, common.Address, *big.Int, common.Address, common.Address, []byte) *types.Transaction); ok { + r0 = rf(opts, sender, deposit, to, l2CallValue, excessFeeRefundAddress, callValueRefundAddress, data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, *big.Int, common.Address, *big.Int, common.Address, common.Address, []byte) error); ok { + r1 = rf(opts, sender, deposit, to, l2CallValue, excessFeeRefundAddress, callValueRefundAddress, data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NodeInterfaceInterface_EstimateRetryableTicket_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EstimateRetryableTicket' +type NodeInterfaceInterface_EstimateRetryableTicket_Call struct { + *mock.Call +} + +// EstimateRetryableTicket is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - sender common.Address +// - deposit *big.Int +// - to common.Address +// - l2CallValue *big.Int +// - excessFeeRefundAddress common.Address +// - callValueRefundAddress common.Address +// - data []byte +func (_e *NodeInterfaceInterface_Expecter) EstimateRetryableTicket(opts interface{}, sender interface{}, deposit interface{}, to interface{}, l2CallValue interface{}, excessFeeRefundAddress interface{}, callValueRefundAddress interface{}, data interface{}) *NodeInterfaceInterface_EstimateRetryableTicket_Call { + return &NodeInterfaceInterface_EstimateRetryableTicket_Call{Call: _e.mock.On("EstimateRetryableTicket", opts, sender, deposit, to, l2CallValue, excessFeeRefundAddress, callValueRefundAddress, data)} +} + +func (_c *NodeInterfaceInterface_EstimateRetryableTicket_Call) Run(run func(opts *bind.TransactOpts, sender common.Address, deposit *big.Int, to common.Address, l2CallValue *big.Int, excessFeeRefundAddress common.Address, callValueRefundAddress common.Address, data []byte)) *NodeInterfaceInterface_EstimateRetryableTicket_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(*big.Int), args[3].(common.Address), args[4].(*big.Int), args[5].(common.Address), args[6].(common.Address), args[7].([]byte)) + }) + return _c +} + +func (_c *NodeInterfaceInterface_EstimateRetryableTicket_Call) Return(_a0 *types.Transaction, _a1 error) *NodeInterfaceInterface_EstimateRetryableTicket_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *NodeInterfaceInterface_EstimateRetryableTicket_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, *big.Int, common.Address, *big.Int, common.Address, common.Address, []byte) (*types.Transaction, error)) *NodeInterfaceInterface_EstimateRetryableTicket_Call { + _c.Call.Return(run) + return _c +} + +// FindBatchContainingBlock provides a mock function with given fields: opts, blockNum +func (_m *NodeInterfaceInterface) FindBatchContainingBlock(opts *bind.CallOpts, blockNum uint64) (uint64, error) { + ret := _m.Called(opts, blockNum) + + if len(ret) == 0 { + panic("no return value specified for FindBatchContainingBlock") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (uint64, error)); ok { + return rf(opts, blockNum) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) uint64); ok { + r0 = rf(opts, blockNum) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, blockNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NodeInterfaceInterface_FindBatchContainingBlock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindBatchContainingBlock' +type NodeInterfaceInterface_FindBatchContainingBlock_Call struct { + *mock.Call +} + +// FindBatchContainingBlock is a helper method to define mock.On call +// - opts *bind.CallOpts +// - blockNum uint64 +func (_e *NodeInterfaceInterface_Expecter) FindBatchContainingBlock(opts interface{}, blockNum interface{}) *NodeInterfaceInterface_FindBatchContainingBlock_Call { + return &NodeInterfaceInterface_FindBatchContainingBlock_Call{Call: _e.mock.On("FindBatchContainingBlock", opts, blockNum)} +} + +func (_c *NodeInterfaceInterface_FindBatchContainingBlock_Call) Run(run func(opts *bind.CallOpts, blockNum uint64)) *NodeInterfaceInterface_FindBatchContainingBlock_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *NodeInterfaceInterface_FindBatchContainingBlock_Call) Return(_a0 uint64, _a1 error) *NodeInterfaceInterface_FindBatchContainingBlock_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *NodeInterfaceInterface_FindBatchContainingBlock_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (uint64, error)) *NodeInterfaceInterface_FindBatchContainingBlock_Call { + _c.Call.Return(run) + return _c +} + +// GasEstimateComponents provides a mock function with given fields: opts, to, contractCreation, data +func (_m *NodeInterfaceInterface) GasEstimateComponents(opts *bind.TransactOpts, to common.Address, contractCreation bool, data []byte) (*types.Transaction, error) { + ret := _m.Called(opts, to, contractCreation, data) + + if len(ret) == 0 { + panic("no return value specified for GasEstimateComponents") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, bool, []byte) (*types.Transaction, error)); ok { + return rf(opts, to, contractCreation, data) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, bool, []byte) *types.Transaction); ok { + r0 = rf(opts, to, contractCreation, data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, bool, []byte) error); ok { + r1 = rf(opts, to, contractCreation, data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NodeInterfaceInterface_GasEstimateComponents_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GasEstimateComponents' +type NodeInterfaceInterface_GasEstimateComponents_Call struct { + *mock.Call +} + +// GasEstimateComponents is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - to common.Address +// - contractCreation bool +// - data []byte +func (_e *NodeInterfaceInterface_Expecter) GasEstimateComponents(opts interface{}, to interface{}, contractCreation interface{}, data interface{}) *NodeInterfaceInterface_GasEstimateComponents_Call { + return &NodeInterfaceInterface_GasEstimateComponents_Call{Call: _e.mock.On("GasEstimateComponents", opts, to, contractCreation, data)} +} + +func (_c *NodeInterfaceInterface_GasEstimateComponents_Call) Run(run func(opts *bind.TransactOpts, to common.Address, contractCreation bool, data []byte)) *NodeInterfaceInterface_GasEstimateComponents_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(bool), args[3].([]byte)) + }) + return _c +} + +func (_c *NodeInterfaceInterface_GasEstimateComponents_Call) Return(_a0 *types.Transaction, _a1 error) *NodeInterfaceInterface_GasEstimateComponents_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *NodeInterfaceInterface_GasEstimateComponents_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, bool, []byte) (*types.Transaction, error)) *NodeInterfaceInterface_GasEstimateComponents_Call { + _c.Call.Return(run) + return _c +} + +// GasEstimateL1Component provides a mock function with given fields: opts, to, contractCreation, data +func (_m *NodeInterfaceInterface) GasEstimateL1Component(opts *bind.TransactOpts, to common.Address, contractCreation bool, data []byte) (*types.Transaction, error) { + ret := _m.Called(opts, to, contractCreation, data) + + if len(ret) == 0 { + panic("no return value specified for GasEstimateL1Component") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, bool, []byte) (*types.Transaction, error)); ok { + return rf(opts, to, contractCreation, data) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address, bool, []byte) *types.Transaction); ok { + r0 = rf(opts, to, contractCreation, data) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address, bool, []byte) error); ok { + r1 = rf(opts, to, contractCreation, data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NodeInterfaceInterface_GasEstimateL1Component_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GasEstimateL1Component' +type NodeInterfaceInterface_GasEstimateL1Component_Call struct { + *mock.Call +} + +// GasEstimateL1Component is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - to common.Address +// - contractCreation bool +// - data []byte +func (_e *NodeInterfaceInterface_Expecter) GasEstimateL1Component(opts interface{}, to interface{}, contractCreation interface{}, data interface{}) *NodeInterfaceInterface_GasEstimateL1Component_Call { + return &NodeInterfaceInterface_GasEstimateL1Component_Call{Call: _e.mock.On("GasEstimateL1Component", opts, to, contractCreation, data)} +} + +func (_c *NodeInterfaceInterface_GasEstimateL1Component_Call) Run(run func(opts *bind.TransactOpts, to common.Address, contractCreation bool, data []byte)) *NodeInterfaceInterface_GasEstimateL1Component_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address), args[2].(bool), args[3].([]byte)) + }) + return _c +} + +func (_c *NodeInterfaceInterface_GasEstimateL1Component_Call) Return(_a0 *types.Transaction, _a1 error) *NodeInterfaceInterface_GasEstimateL1Component_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *NodeInterfaceInterface_GasEstimateL1Component_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address, bool, []byte) (*types.Transaction, error)) *NodeInterfaceInterface_GasEstimateL1Component_Call { + _c.Call.Return(run) + return _c +} + +// GetL1Confirmations provides a mock function with given fields: opts, blockHash +func (_m *NodeInterfaceInterface) GetL1Confirmations(opts *bind.CallOpts, blockHash [32]byte) (uint64, error) { + ret := _m.Called(opts, blockHash) + + if len(ret) == 0 { + panic("no return value specified for GetL1Confirmations") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, [32]byte) (uint64, error)); ok { + return rf(opts, blockHash) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, [32]byte) uint64); ok { + r0 = rf(opts, blockHash) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, [32]byte) error); ok { + r1 = rf(opts, blockHash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NodeInterfaceInterface_GetL1Confirmations_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetL1Confirmations' +type NodeInterfaceInterface_GetL1Confirmations_Call struct { + *mock.Call +} + +// GetL1Confirmations is a helper method to define mock.On call +// - opts *bind.CallOpts +// - blockHash [32]byte +func (_e *NodeInterfaceInterface_Expecter) GetL1Confirmations(opts interface{}, blockHash interface{}) *NodeInterfaceInterface_GetL1Confirmations_Call { + return &NodeInterfaceInterface_GetL1Confirmations_Call{Call: _e.mock.On("GetL1Confirmations", opts, blockHash)} +} + +func (_c *NodeInterfaceInterface_GetL1Confirmations_Call) Run(run func(opts *bind.CallOpts, blockHash [32]byte)) *NodeInterfaceInterface_GetL1Confirmations_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].([32]byte)) + }) + return _c +} + +func (_c *NodeInterfaceInterface_GetL1Confirmations_Call) Return(_a0 uint64, _a1 error) *NodeInterfaceInterface_GetL1Confirmations_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *NodeInterfaceInterface_GetL1Confirmations_Call) RunAndReturn(run func(*bind.CallOpts, [32]byte) (uint64, error)) *NodeInterfaceInterface_GetL1Confirmations_Call { + _c.Call.Return(run) + return _c +} + +// L2BlockRangeForL1 provides a mock function with given fields: opts, blockNum +func (_m *NodeInterfaceInterface) L2BlockRangeForL1(opts *bind.CallOpts, blockNum uint64) (arb_node_interface.L2BlockRangeForL1, error) { + ret := _m.Called(opts, blockNum) + + if len(ret) == 0 { + panic("no return value specified for L2BlockRangeForL1") + } + + var r0 arb_node_interface.L2BlockRangeForL1 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (arb_node_interface.L2BlockRangeForL1, error)); ok { + return rf(opts, blockNum) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) arb_node_interface.L2BlockRangeForL1); ok { + r0 = rf(opts, blockNum) + } else { + r0 = ret.Get(0).(arb_node_interface.L2BlockRangeForL1) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, blockNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NodeInterfaceInterface_L2BlockRangeForL1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'L2BlockRangeForL1' +type NodeInterfaceInterface_L2BlockRangeForL1_Call struct { + *mock.Call +} + +// L2BlockRangeForL1 is a helper method to define mock.On call +// - opts *bind.CallOpts +// - blockNum uint64 +func (_e *NodeInterfaceInterface_Expecter) L2BlockRangeForL1(opts interface{}, blockNum interface{}) *NodeInterfaceInterface_L2BlockRangeForL1_Call { + return &NodeInterfaceInterface_L2BlockRangeForL1_Call{Call: _e.mock.On("L2BlockRangeForL1", opts, blockNum)} +} + +func (_c *NodeInterfaceInterface_L2BlockRangeForL1_Call) Run(run func(opts *bind.CallOpts, blockNum uint64)) *NodeInterfaceInterface_L2BlockRangeForL1_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *NodeInterfaceInterface_L2BlockRangeForL1_Call) Return(_a0 arb_node_interface.L2BlockRangeForL1, _a1 error) *NodeInterfaceInterface_L2BlockRangeForL1_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *NodeInterfaceInterface_L2BlockRangeForL1_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (arb_node_interface.L2BlockRangeForL1, error)) *NodeInterfaceInterface_L2BlockRangeForL1_Call { + _c.Call.Return(run) + return _c +} + +// LegacyLookupMessageBatchProof provides a mock function with given fields: opts, batchNum, index +func (_m *NodeInterfaceInterface) LegacyLookupMessageBatchProof(opts *bind.CallOpts, batchNum *big.Int, index uint64) (arb_node_interface.LegacyLookupMessageBatchProof, error) { + ret := _m.Called(opts, batchNum, index) + + if len(ret) == 0 { + panic("no return value specified for LegacyLookupMessageBatchProof") + } + + var r0 arb_node_interface.LegacyLookupMessageBatchProof + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int, uint64) (arb_node_interface.LegacyLookupMessageBatchProof, error)); ok { + return rf(opts, batchNum, index) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int, uint64) arb_node_interface.LegacyLookupMessageBatchProof); ok { + r0 = rf(opts, batchNum, index) + } else { + r0 = ret.Get(0).(arb_node_interface.LegacyLookupMessageBatchProof) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, *big.Int, uint64) error); ok { + r1 = rf(opts, batchNum, index) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NodeInterfaceInterface_LegacyLookupMessageBatchProof_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LegacyLookupMessageBatchProof' +type NodeInterfaceInterface_LegacyLookupMessageBatchProof_Call struct { + *mock.Call +} + +// LegacyLookupMessageBatchProof is a helper method to define mock.On call +// - opts *bind.CallOpts +// - batchNum *big.Int +// - index uint64 +func (_e *NodeInterfaceInterface_Expecter) LegacyLookupMessageBatchProof(opts interface{}, batchNum interface{}, index interface{}) *NodeInterfaceInterface_LegacyLookupMessageBatchProof_Call { + return &NodeInterfaceInterface_LegacyLookupMessageBatchProof_Call{Call: _e.mock.On("LegacyLookupMessageBatchProof", opts, batchNum, index)} +} + +func (_c *NodeInterfaceInterface_LegacyLookupMessageBatchProof_Call) Run(run func(opts *bind.CallOpts, batchNum *big.Int, index uint64)) *NodeInterfaceInterface_LegacyLookupMessageBatchProof_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(*big.Int), args[2].(uint64)) + }) + return _c +} + +func (_c *NodeInterfaceInterface_LegacyLookupMessageBatchProof_Call) Return(_a0 arb_node_interface.LegacyLookupMessageBatchProof, _a1 error) *NodeInterfaceInterface_LegacyLookupMessageBatchProof_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *NodeInterfaceInterface_LegacyLookupMessageBatchProof_Call) RunAndReturn(run func(*bind.CallOpts, *big.Int, uint64) (arb_node_interface.LegacyLookupMessageBatchProof, error)) *NodeInterfaceInterface_LegacyLookupMessageBatchProof_Call { + _c.Call.Return(run) + return _c +} + +// NitroGenesisBlock provides a mock function with given fields: opts +func (_m *NodeInterfaceInterface) NitroGenesisBlock(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for NitroGenesisBlock") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NodeInterfaceInterface_NitroGenesisBlock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NitroGenesisBlock' +type NodeInterfaceInterface_NitroGenesisBlock_Call struct { + *mock.Call +} + +// NitroGenesisBlock is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *NodeInterfaceInterface_Expecter) NitroGenesisBlock(opts interface{}) *NodeInterfaceInterface_NitroGenesisBlock_Call { + return &NodeInterfaceInterface_NitroGenesisBlock_Call{Call: _e.mock.On("NitroGenesisBlock", opts)} +} + +func (_c *NodeInterfaceInterface_NitroGenesisBlock_Call) Run(run func(opts *bind.CallOpts)) *NodeInterfaceInterface_NitroGenesisBlock_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *NodeInterfaceInterface_NitroGenesisBlock_Call) Return(_a0 *big.Int, _a1 error) *NodeInterfaceInterface_NitroGenesisBlock_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *NodeInterfaceInterface_NitroGenesisBlock_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *NodeInterfaceInterface_NitroGenesisBlock_Call { + _c.Call.Return(run) + return _c +} + +// NewNodeInterfaceInterface creates a new instance of NodeInterfaceInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewNodeInterfaceInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *NodeInterfaceInterface { + mock := &NodeInterfaceInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_optimism_dispute_game_factory/optimism_dispute_game_factory_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_optimism_dispute_game_factory/optimism_dispute_game_factory_interface.go new file mode 100644 index 0000000000..3f0b69f1a0 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_optimism_dispute_game_factory/optimism_dispute_game_factory_interface.go @@ -0,0 +1,207 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_optimism_dispute_game_factory + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" + + optimism_dispute_game_factory "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_dispute_game_factory" +) + +// OptimismDisputeGameFactoryInterface is an autogenerated mock type for the OptimismDisputeGameFactoryInterface type +type OptimismDisputeGameFactoryInterface struct { + mock.Mock +} + +type OptimismDisputeGameFactoryInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *OptimismDisputeGameFactoryInterface) EXPECT() *OptimismDisputeGameFactoryInterface_Expecter { + return &OptimismDisputeGameFactoryInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *OptimismDisputeGameFactoryInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// OptimismDisputeGameFactoryInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type OptimismDisputeGameFactoryInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *OptimismDisputeGameFactoryInterface_Expecter) Address() *OptimismDisputeGameFactoryInterface_Address_Call { + return &OptimismDisputeGameFactoryInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *OptimismDisputeGameFactoryInterface_Address_Call) Run(run func()) *OptimismDisputeGameFactoryInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *OptimismDisputeGameFactoryInterface_Address_Call) Return(_a0 common.Address) *OptimismDisputeGameFactoryInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *OptimismDisputeGameFactoryInterface_Address_Call) RunAndReturn(run func() common.Address) *OptimismDisputeGameFactoryInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// FindLatestGames provides a mock function with given fields: opts, _gameType, _start, _n +func (_m *OptimismDisputeGameFactoryInterface) FindLatestGames(opts *bind.CallOpts, _gameType uint32, _start *big.Int, _n *big.Int) ([]optimism_dispute_game_factory.IOptimismDisputeGameFactoryGameSearchResult, error) { + ret := _m.Called(opts, _gameType, _start, _n) + + if len(ret) == 0 { + panic("no return value specified for FindLatestGames") + } + + var r0 []optimism_dispute_game_factory.IOptimismDisputeGameFactoryGameSearchResult + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint32, *big.Int, *big.Int) ([]optimism_dispute_game_factory.IOptimismDisputeGameFactoryGameSearchResult, error)); ok { + return rf(opts, _gameType, _start, _n) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint32, *big.Int, *big.Int) []optimism_dispute_game_factory.IOptimismDisputeGameFactoryGameSearchResult); ok { + r0 = rf(opts, _gameType, _start, _n) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]optimism_dispute_game_factory.IOptimismDisputeGameFactoryGameSearchResult) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint32, *big.Int, *big.Int) error); ok { + r1 = rf(opts, _gameType, _start, _n) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OptimismDisputeGameFactoryInterface_FindLatestGames_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindLatestGames' +type OptimismDisputeGameFactoryInterface_FindLatestGames_Call struct { + *mock.Call +} + +// FindLatestGames is a helper method to define mock.On call +// - opts *bind.CallOpts +// - _gameType uint32 +// - _start *big.Int +// - _n *big.Int +func (_e *OptimismDisputeGameFactoryInterface_Expecter) FindLatestGames(opts interface{}, _gameType interface{}, _start interface{}, _n interface{}) *OptimismDisputeGameFactoryInterface_FindLatestGames_Call { + return &OptimismDisputeGameFactoryInterface_FindLatestGames_Call{Call: _e.mock.On("FindLatestGames", opts, _gameType, _start, _n)} +} + +func (_c *OptimismDisputeGameFactoryInterface_FindLatestGames_Call) Run(run func(opts *bind.CallOpts, _gameType uint32, _start *big.Int, _n *big.Int)) *OptimismDisputeGameFactoryInterface_FindLatestGames_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint32), args[2].(*big.Int), args[3].(*big.Int)) + }) + return _c +} + +func (_c *OptimismDisputeGameFactoryInterface_FindLatestGames_Call) Return(_a0 []optimism_dispute_game_factory.IOptimismDisputeGameFactoryGameSearchResult, _a1 error) *OptimismDisputeGameFactoryInterface_FindLatestGames_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OptimismDisputeGameFactoryInterface_FindLatestGames_Call) RunAndReturn(run func(*bind.CallOpts, uint32, *big.Int, *big.Int) ([]optimism_dispute_game_factory.IOptimismDisputeGameFactoryGameSearchResult, error)) *OptimismDisputeGameFactoryInterface_FindLatestGames_Call { + _c.Call.Return(run) + return _c +} + +// GameCount provides a mock function with given fields: opts +func (_m *OptimismDisputeGameFactoryInterface) GameCount(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GameCount") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (*big.Int, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OptimismDisputeGameFactoryInterface_GameCount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GameCount' +type OptimismDisputeGameFactoryInterface_GameCount_Call struct { + *mock.Call +} + +// GameCount is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *OptimismDisputeGameFactoryInterface_Expecter) GameCount(opts interface{}) *OptimismDisputeGameFactoryInterface_GameCount_Call { + return &OptimismDisputeGameFactoryInterface_GameCount_Call{Call: _e.mock.On("GameCount", opts)} +} + +func (_c *OptimismDisputeGameFactoryInterface_GameCount_Call) Run(run func(opts *bind.CallOpts)) *OptimismDisputeGameFactoryInterface_GameCount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *OptimismDisputeGameFactoryInterface_GameCount_Call) Return(_a0 *big.Int, _a1 error) *OptimismDisputeGameFactoryInterface_GameCount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OptimismDisputeGameFactoryInterface_GameCount_Call) RunAndReturn(run func(*bind.CallOpts) (*big.Int, error)) *OptimismDisputeGameFactoryInterface_GameCount_Call { + _c.Call.Return(run) + return _c +} + +// NewOptimismDisputeGameFactoryInterface creates a new instance of OptimismDisputeGameFactoryInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewOptimismDisputeGameFactoryInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *OptimismDisputeGameFactoryInterface { + mock := &OptimismDisputeGameFactoryInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_optimism_l2_output_oracle/optimism_l2_output_oracle_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_optimism_l2_output_oracle/optimism_l2_output_oracle_interface.go new file mode 100644 index 0000000000..f93bee3bf5 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_optimism_l2_output_oracle/optimism_l2_output_oracle_interface.go @@ -0,0 +1,204 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_optimism_l2_output_oracle + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" + + optimism_l2_output_oracle "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_l2_output_oracle" +) + +// OptimismL2OutputOracleInterface is an autogenerated mock type for the OptimismL2OutputOracleInterface type +type OptimismL2OutputOracleInterface struct { + mock.Mock +} + +type OptimismL2OutputOracleInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *OptimismL2OutputOracleInterface) EXPECT() *OptimismL2OutputOracleInterface_Expecter { + return &OptimismL2OutputOracleInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *OptimismL2OutputOracleInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// OptimismL2OutputOracleInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type OptimismL2OutputOracleInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *OptimismL2OutputOracleInterface_Expecter) Address() *OptimismL2OutputOracleInterface_Address_Call { + return &OptimismL2OutputOracleInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *OptimismL2OutputOracleInterface_Address_Call) Run(run func()) *OptimismL2OutputOracleInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *OptimismL2OutputOracleInterface_Address_Call) Return(_a0 common.Address) *OptimismL2OutputOracleInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *OptimismL2OutputOracleInterface_Address_Call) RunAndReturn(run func() common.Address) *OptimismL2OutputOracleInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// GetL2Output provides a mock function with given fields: opts, _l2OutputIndex +func (_m *OptimismL2OutputOracleInterface) GetL2Output(opts *bind.CallOpts, _l2OutputIndex *big.Int) (optimism_l2_output_oracle.TypesOutputProposal, error) { + ret := _m.Called(opts, _l2OutputIndex) + + if len(ret) == 0 { + panic("no return value specified for GetL2Output") + } + + var r0 optimism_l2_output_oracle.TypesOutputProposal + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) (optimism_l2_output_oracle.TypesOutputProposal, error)); ok { + return rf(opts, _l2OutputIndex) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) optimism_l2_output_oracle.TypesOutputProposal); ok { + r0 = rf(opts, _l2OutputIndex) + } else { + r0 = ret.Get(0).(optimism_l2_output_oracle.TypesOutputProposal) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, *big.Int) error); ok { + r1 = rf(opts, _l2OutputIndex) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OptimismL2OutputOracleInterface_GetL2Output_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetL2Output' +type OptimismL2OutputOracleInterface_GetL2Output_Call struct { + *mock.Call +} + +// GetL2Output is a helper method to define mock.On call +// - opts *bind.CallOpts +// - _l2OutputIndex *big.Int +func (_e *OptimismL2OutputOracleInterface_Expecter) GetL2Output(opts interface{}, _l2OutputIndex interface{}) *OptimismL2OutputOracleInterface_GetL2Output_Call { + return &OptimismL2OutputOracleInterface_GetL2Output_Call{Call: _e.mock.On("GetL2Output", opts, _l2OutputIndex)} +} + +func (_c *OptimismL2OutputOracleInterface_GetL2Output_Call) Run(run func(opts *bind.CallOpts, _l2OutputIndex *big.Int)) *OptimismL2OutputOracleInterface_GetL2Output_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(*big.Int)) + }) + return _c +} + +func (_c *OptimismL2OutputOracleInterface_GetL2Output_Call) Return(_a0 optimism_l2_output_oracle.TypesOutputProposal, _a1 error) *OptimismL2OutputOracleInterface_GetL2Output_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OptimismL2OutputOracleInterface_GetL2Output_Call) RunAndReturn(run func(*bind.CallOpts, *big.Int) (optimism_l2_output_oracle.TypesOutputProposal, error)) *OptimismL2OutputOracleInterface_GetL2Output_Call { + _c.Call.Return(run) + return _c +} + +// GetL2OutputIndexAfter provides a mock function with given fields: opts, _l2BlockNumber +func (_m *OptimismL2OutputOracleInterface) GetL2OutputIndexAfter(opts *bind.CallOpts, _l2BlockNumber *big.Int) (*big.Int, error) { + ret := _m.Called(opts, _l2BlockNumber) + + if len(ret) == 0 { + panic("no return value specified for GetL2OutputIndexAfter") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) (*big.Int, error)); ok { + return rf(opts, _l2BlockNumber) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) *big.Int); ok { + r0 = rf(opts, _l2BlockNumber) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, *big.Int) error); ok { + r1 = rf(opts, _l2BlockNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OptimismL2OutputOracleInterface_GetL2OutputIndexAfter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetL2OutputIndexAfter' +type OptimismL2OutputOracleInterface_GetL2OutputIndexAfter_Call struct { + *mock.Call +} + +// GetL2OutputIndexAfter is a helper method to define mock.On call +// - opts *bind.CallOpts +// - _l2BlockNumber *big.Int +func (_e *OptimismL2OutputOracleInterface_Expecter) GetL2OutputIndexAfter(opts interface{}, _l2BlockNumber interface{}) *OptimismL2OutputOracleInterface_GetL2OutputIndexAfter_Call { + return &OptimismL2OutputOracleInterface_GetL2OutputIndexAfter_Call{Call: _e.mock.On("GetL2OutputIndexAfter", opts, _l2BlockNumber)} +} + +func (_c *OptimismL2OutputOracleInterface_GetL2OutputIndexAfter_Call) Run(run func(opts *bind.CallOpts, _l2BlockNumber *big.Int)) *OptimismL2OutputOracleInterface_GetL2OutputIndexAfter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(*big.Int)) + }) + return _c +} + +func (_c *OptimismL2OutputOracleInterface_GetL2OutputIndexAfter_Call) Return(_a0 *big.Int, _a1 error) *OptimismL2OutputOracleInterface_GetL2OutputIndexAfter_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OptimismL2OutputOracleInterface_GetL2OutputIndexAfter_Call) RunAndReturn(run func(*bind.CallOpts, *big.Int) (*big.Int, error)) *OptimismL2OutputOracleInterface_GetL2OutputIndexAfter_Call { + _c.Call.Return(run) + return _c +} + +// NewOptimismL2OutputOracleInterface creates a new instance of OptimismL2OutputOracleInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewOptimismL2OutputOracleInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *OptimismL2OutputOracleInterface { + mock := &OptimismL2OutputOracleInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_optimism_portal/optimism_portal_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_optimism_portal/optimism_portal_interface.go new file mode 100644 index 0000000000..eede00e7d9 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_optimism_portal/optimism_portal_interface.go @@ -0,0 +1,267 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_optimism_portal + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" + + optimism_portal "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_portal" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// OptimismPortalInterface is an autogenerated mock type for the OptimismPortalInterface type +type OptimismPortalInterface struct { + mock.Mock +} + +type OptimismPortalInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *OptimismPortalInterface) EXPECT() *OptimismPortalInterface_Expecter { + return &OptimismPortalInterface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *OptimismPortalInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// OptimismPortalInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type OptimismPortalInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *OptimismPortalInterface_Expecter) Address() *OptimismPortalInterface_Address_Call { + return &OptimismPortalInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *OptimismPortalInterface_Address_Call) Run(run func()) *OptimismPortalInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *OptimismPortalInterface_Address_Call) Return(_a0 common.Address) *OptimismPortalInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *OptimismPortalInterface_Address_Call) RunAndReturn(run func() common.Address) *OptimismPortalInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// FinalizeWithdrawalTransaction provides a mock function with given fields: opts, _tx +func (_m *OptimismPortalInterface) FinalizeWithdrawalTransaction(opts *bind.TransactOpts, _tx optimism_portal.TypesWithdrawalTransaction) (*types.Transaction, error) { + ret := _m.Called(opts, _tx) + + if len(ret) == 0 { + panic("no return value specified for FinalizeWithdrawalTransaction") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, optimism_portal.TypesWithdrawalTransaction) (*types.Transaction, error)); ok { + return rf(opts, _tx) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, optimism_portal.TypesWithdrawalTransaction) *types.Transaction); ok { + r0 = rf(opts, _tx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, optimism_portal.TypesWithdrawalTransaction) error); ok { + r1 = rf(opts, _tx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OptimismPortalInterface_FinalizeWithdrawalTransaction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FinalizeWithdrawalTransaction' +type OptimismPortalInterface_FinalizeWithdrawalTransaction_Call struct { + *mock.Call +} + +// FinalizeWithdrawalTransaction is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _tx optimism_portal.TypesWithdrawalTransaction +func (_e *OptimismPortalInterface_Expecter) FinalizeWithdrawalTransaction(opts interface{}, _tx interface{}) *OptimismPortalInterface_FinalizeWithdrawalTransaction_Call { + return &OptimismPortalInterface_FinalizeWithdrawalTransaction_Call{Call: _e.mock.On("FinalizeWithdrawalTransaction", opts, _tx)} +} + +func (_c *OptimismPortalInterface_FinalizeWithdrawalTransaction_Call) Run(run func(opts *bind.TransactOpts, _tx optimism_portal.TypesWithdrawalTransaction)) *OptimismPortalInterface_FinalizeWithdrawalTransaction_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(optimism_portal.TypesWithdrawalTransaction)) + }) + return _c +} + +func (_c *OptimismPortalInterface_FinalizeWithdrawalTransaction_Call) Return(_a0 *types.Transaction, _a1 error) *OptimismPortalInterface_FinalizeWithdrawalTransaction_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OptimismPortalInterface_FinalizeWithdrawalTransaction_Call) RunAndReturn(run func(*bind.TransactOpts, optimism_portal.TypesWithdrawalTransaction) (*types.Transaction, error)) *OptimismPortalInterface_FinalizeWithdrawalTransaction_Call { + _c.Call.Return(run) + return _c +} + +// ProveWithdrawalTransaction provides a mock function with given fields: opts, _tx, _l2OutputIndex, _outputRootProof, _withdrawalProof +func (_m *OptimismPortalInterface) ProveWithdrawalTransaction(opts *bind.TransactOpts, _tx optimism_portal.TypesWithdrawalTransaction, _l2OutputIndex *big.Int, _outputRootProof optimism_portal.TypesOutputRootProof, _withdrawalProof [][]byte) (*types.Transaction, error) { + ret := _m.Called(opts, _tx, _l2OutputIndex, _outputRootProof, _withdrawalProof) + + if len(ret) == 0 { + panic("no return value specified for ProveWithdrawalTransaction") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, optimism_portal.TypesWithdrawalTransaction, *big.Int, optimism_portal.TypesOutputRootProof, [][]byte) (*types.Transaction, error)); ok { + return rf(opts, _tx, _l2OutputIndex, _outputRootProof, _withdrawalProof) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, optimism_portal.TypesWithdrawalTransaction, *big.Int, optimism_portal.TypesOutputRootProof, [][]byte) *types.Transaction); ok { + r0 = rf(opts, _tx, _l2OutputIndex, _outputRootProof, _withdrawalProof) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, optimism_portal.TypesWithdrawalTransaction, *big.Int, optimism_portal.TypesOutputRootProof, [][]byte) error); ok { + r1 = rf(opts, _tx, _l2OutputIndex, _outputRootProof, _withdrawalProof) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OptimismPortalInterface_ProveWithdrawalTransaction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ProveWithdrawalTransaction' +type OptimismPortalInterface_ProveWithdrawalTransaction_Call struct { + *mock.Call +} + +// ProveWithdrawalTransaction is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - _tx optimism_portal.TypesWithdrawalTransaction +// - _l2OutputIndex *big.Int +// - _outputRootProof optimism_portal.TypesOutputRootProof +// - _withdrawalProof [][]byte +func (_e *OptimismPortalInterface_Expecter) ProveWithdrawalTransaction(opts interface{}, _tx interface{}, _l2OutputIndex interface{}, _outputRootProof interface{}, _withdrawalProof interface{}) *OptimismPortalInterface_ProveWithdrawalTransaction_Call { + return &OptimismPortalInterface_ProveWithdrawalTransaction_Call{Call: _e.mock.On("ProveWithdrawalTransaction", opts, _tx, _l2OutputIndex, _outputRootProof, _withdrawalProof)} +} + +func (_c *OptimismPortalInterface_ProveWithdrawalTransaction_Call) Run(run func(opts *bind.TransactOpts, _tx optimism_portal.TypesWithdrawalTransaction, _l2OutputIndex *big.Int, _outputRootProof optimism_portal.TypesOutputRootProof, _withdrawalProof [][]byte)) *OptimismPortalInterface_ProveWithdrawalTransaction_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(optimism_portal.TypesWithdrawalTransaction), args[2].(*big.Int), args[3].(optimism_portal.TypesOutputRootProof), args[4].([][]byte)) + }) + return _c +} + +func (_c *OptimismPortalInterface_ProveWithdrawalTransaction_Call) Return(_a0 *types.Transaction, _a1 error) *OptimismPortalInterface_ProveWithdrawalTransaction_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OptimismPortalInterface_ProveWithdrawalTransaction_Call) RunAndReturn(run func(*bind.TransactOpts, optimism_portal.TypesWithdrawalTransaction, *big.Int, optimism_portal.TypesOutputRootProof, [][]byte) (*types.Transaction, error)) *OptimismPortalInterface_ProveWithdrawalTransaction_Call { + _c.Call.Return(run) + return _c +} + +// Version provides a mock function with given fields: opts +func (_m *OptimismPortalInterface) Version(opts *bind.CallOpts) (string, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Version") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (string, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) string); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OptimismPortalInterface_Version_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Version' +type OptimismPortalInterface_Version_Call struct { + *mock.Call +} + +// Version is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *OptimismPortalInterface_Expecter) Version(opts interface{}) *OptimismPortalInterface_Version_Call { + return &OptimismPortalInterface_Version_Call{Call: _e.mock.On("Version", opts)} +} + +func (_c *OptimismPortalInterface_Version_Call) Run(run func(opts *bind.CallOpts)) *OptimismPortalInterface_Version_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *OptimismPortalInterface_Version_Call) Return(_a0 string, _a1 error) *OptimismPortalInterface_Version_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OptimismPortalInterface_Version_Call) RunAndReturn(run func(*bind.CallOpts) (string, error)) *OptimismPortalInterface_Version_Call { + _c.Call.Return(run) + return _c +} + +// NewOptimismPortalInterface creates a new instance of OptimismPortalInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewOptimismPortalInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *OptimismPortalInterface { + mock := &OptimismPortalInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/liquiditymanager/mocks/mock_optimism_portal_2/optimism_portal2_interface.go b/core/gethwrappers/liquiditymanager/mocks/mock_optimism_portal_2/optimism_portal2_interface.go new file mode 100644 index 0000000000..e3d1312120 --- /dev/null +++ b/core/gethwrappers/liquiditymanager/mocks/mock_optimism_portal_2/optimism_portal2_interface.go @@ -0,0 +1,198 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_optimism_portal_2 + +import ( + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" +) + +// OptimismPortal2Interface is an autogenerated mock type for the OptimismPortal2Interface type +type OptimismPortal2Interface struct { + mock.Mock +} + +type OptimismPortal2Interface_Expecter struct { + mock *mock.Mock +} + +func (_m *OptimismPortal2Interface) EXPECT() *OptimismPortal2Interface_Expecter { + return &OptimismPortal2Interface_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *OptimismPortal2Interface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// OptimismPortal2Interface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type OptimismPortal2Interface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *OptimismPortal2Interface_Expecter) Address() *OptimismPortal2Interface_Address_Call { + return &OptimismPortal2Interface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *OptimismPortal2Interface_Address_Call) Run(run func()) *OptimismPortal2Interface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *OptimismPortal2Interface_Address_Call) Return(_a0 common.Address) *OptimismPortal2Interface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *OptimismPortal2Interface_Address_Call) RunAndReturn(run func() common.Address) *OptimismPortal2Interface_Address_Call { + _c.Call.Return(run) + return _c +} + +// DisputeGameFactory provides a mock function with given fields: opts +func (_m *OptimismPortal2Interface) DisputeGameFactory(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for DisputeGameFactory") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OptimismPortal2Interface_DisputeGameFactory_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DisputeGameFactory' +type OptimismPortal2Interface_DisputeGameFactory_Call struct { + *mock.Call +} + +// DisputeGameFactory is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *OptimismPortal2Interface_Expecter) DisputeGameFactory(opts interface{}) *OptimismPortal2Interface_DisputeGameFactory_Call { + return &OptimismPortal2Interface_DisputeGameFactory_Call{Call: _e.mock.On("DisputeGameFactory", opts)} +} + +func (_c *OptimismPortal2Interface_DisputeGameFactory_Call) Run(run func(opts *bind.CallOpts)) *OptimismPortal2Interface_DisputeGameFactory_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *OptimismPortal2Interface_DisputeGameFactory_Call) Return(_a0 common.Address, _a1 error) *OptimismPortal2Interface_DisputeGameFactory_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OptimismPortal2Interface_DisputeGameFactory_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *OptimismPortal2Interface_DisputeGameFactory_Call { + _c.Call.Return(run) + return _c +} + +// RespectedGameType provides a mock function with given fields: opts +func (_m *OptimismPortal2Interface) RespectedGameType(opts *bind.CallOpts) (uint32, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for RespectedGameType") + } + + var r0 uint32 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (uint32, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) uint32); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(uint32) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OptimismPortal2Interface_RespectedGameType_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RespectedGameType' +type OptimismPortal2Interface_RespectedGameType_Call struct { + *mock.Call +} + +// RespectedGameType is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *OptimismPortal2Interface_Expecter) RespectedGameType(opts interface{}) *OptimismPortal2Interface_RespectedGameType_Call { + return &OptimismPortal2Interface_RespectedGameType_Call{Call: _e.mock.On("RespectedGameType", opts)} +} + +func (_c *OptimismPortal2Interface_RespectedGameType_Call) Run(run func(opts *bind.CallOpts)) *OptimismPortal2Interface_RespectedGameType_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *OptimismPortal2Interface_RespectedGameType_Call) Return(_a0 uint32, _a1 error) *OptimismPortal2Interface_RespectedGameType_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OptimismPortal2Interface_RespectedGameType_Call) RunAndReturn(run func(*bind.CallOpts) (uint32, error)) *OptimismPortal2Interface_RespectedGameType_Call { + _c.Call.Return(run) + return _c +} + +// NewOptimismPortal2Interface creates a new instance of OptimismPortal2Interface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewOptimismPortal2Interface(t interface { + mock.TestingT + Cleanup(func()) +}) *OptimismPortal2Interface { + mock := &OptimismPortal2Interface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} From 24c4826267cd45b70cec71f29e9801cee70df7f4 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Wed, 31 Jul 2024 09:30:45 -0400 Subject: [PATCH 013/432] [TT-1422] Fix Slack Tag (#13971) --- .github/workflows/client-compatibility-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 7d03348898..a2cd1af97e 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -676,7 +676,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "${{ contains(join(needs.*.result, ','), 'failure') && format('Some tests failed, notifying ', secrets.COMPAT_SLACK_NOTIFICATION_HANDLE) || 'All Good!' }}" + "text": "${{ contains(join(needs.*.result, ','), 'failure') && format('Some tests failed, notifying ', secrets.COMPAT_SLACK_NOTIFICATION_HANDLE) || 'All Good!' }}" } }, { From 3de00b734f7eeff4f10547cd3626adc68f0be639 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Wed, 31 Jul 2024 09:57:26 -0400 Subject: [PATCH 014/432] Build Image for Tags (#13965) --- .github/workflows/client-compatibility-tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index a2cd1af97e..8f0755c855 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -284,7 +284,6 @@ jobs: if: | always() && needs.should-run.outputs.should_run == 'true' && - github.ref_type != 'tag' && ( needs.select-versions.outputs.evm_implementations != '' || github.event.inputs.base64TestList != '' From 15dc74cabd3a83041ca97df54ea0fbb7e76e2a0a Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Date: Wed, 31 Jul 2024 20:02:38 +0200 Subject: [PATCH 015/432] BCI-3842 custom timeouts for Hedera (#13876) * allow to configure RPCTimeouts * Custom (30s) timeout for Hedera RPC requests with large payloads (SendTransaction, CallContext, etc.) * fix linter --- .changeset/mean-brooms-agree.md | 5 ++ core/chains/evm/client/chain_client.go | 3 +- core/chains/evm/client/evm_client.go | 14 ++- core/chains/evm/client/helpers_test.go | 4 +- core/chains/evm/client/rpc_client.go | 81 +++++++++-------- core/chains/evm/client/rpc_client_test.go | 88 +++++++++++++++++-- core/chains/evm/config/chaintype/chaintype.go | 6 +- core/services/chainlink/config_test.go | 4 +- core/services/ocr/contract_tracker.go | 2 +- 9 files changed, 152 insertions(+), 55 deletions(-) create mode 100644 .changeset/mean-brooms-agree.md diff --git a/.changeset/mean-brooms-agree.md b/.changeset/mean-brooms-agree.md new file mode 100644 index 0000000000..0dd2ba7bd3 --- /dev/null +++ b/.changeset/mean-brooms-agree.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Custom (30s) timeout for Hedera RPC requests with large payloads (SendTransaction, CallContext, etc.) #internal diff --git a/core/chains/evm/client/chain_client.go b/core/chains/evm/client/chain_client.go index 7597346914..c39214471c 100644 --- a/core/chains/evm/client/chain_client.go +++ b/core/chains/evm/client/chain_client.go @@ -20,7 +20,6 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) -const queryTimeout = 10 * time.Second const BALANCE_OF_ADDRESS_FUNCTION_SELECTOR = "0x70a08231" var _ Client = (*chainClient)(nil) @@ -99,7 +98,7 @@ type Client interface { } func ContextWithDefaultTimeout() (ctx context.Context, cancel context.CancelFunc) { - return context.WithTimeout(context.Background(), queryTimeout) + return context.WithTimeout(context.Background(), commonclient.QueryTimeout) } type chainClient struct { diff --git a/core/chains/evm/client/evm_client.go b/core/chains/evm/client/evm_client.go index c2373ee775..3676808683 100644 --- a/core/chains/evm/client/evm_client.go +++ b/core/chains/evm/client/evm_client.go @@ -3,6 +3,7 @@ package client import ( "math/big" "net/url" + "time" "github.com/smartcontractkit/chainlink-common/pkg/logger" @@ -17,16 +18,17 @@ func NewEvmClient(cfg evmconfig.NodePool, chainCfg commonclient.ChainConfig, cli var empty url.URL var primaries []commonclient.Node[*big.Int, *evmtypes.Head, RPCClient] var sendonlys []commonclient.SendOnlyNode[*big.Int, RPCClient] + largePayloadRPCTimeout, defaultRPCTimeout := getRPCTimeouts(chainType) for i, node := range nodes { if node.SendOnly != nil && *node.SendOnly { rpc := NewRPCClient(lggr, empty, (*url.URL)(node.HTTPURL), *node.Name, int32(i), chainID, - commonclient.Secondary, cfg.FinalizedBlockPollInterval()) + commonclient.Secondary, cfg.FinalizedBlockPollInterval(), largePayloadRPCTimeout, defaultRPCTimeout) sendonly := commonclient.NewSendOnlyNode(lggr, (url.URL)(*node.HTTPURL), *node.Name, chainID, rpc) sendonlys = append(sendonlys, sendonly) } else { rpc := NewRPCClient(lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), *node.Name, int32(i), - chainID, commonclient.Primary, cfg.FinalizedBlockPollInterval()) + chainID, commonclient.Primary, cfg.FinalizedBlockPollInterval(), largePayloadRPCTimeout, defaultRPCTimeout) primaryNode := commonclient.NewNode(cfg, chainCfg, lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), *node.Name, int32(i), chainID, *node.Order, rpc, "EVM") @@ -37,3 +39,11 @@ func NewEvmClient(cfg evmconfig.NodePool, chainCfg commonclient.ChainConfig, cli return NewChainClient(lggr, cfg.SelectionMode(), cfg.LeaseDuration(), chainCfg.NodeNoNewHeadsThreshold(), primaries, sendonlys, chainID, chainType, clientErrors, cfg.DeathDeclarationDelay()) } + +func getRPCTimeouts(chainType chaintype.ChainType) (largePayload, defaultTimeout time.Duration) { + if chaintype.ChainHedera == chainType { + return 30 * time.Second, commonclient.QueryTimeout + } + + return commonclient.QueryTimeout, commonclient.QueryTimeout +} diff --git a/core/chains/evm/client/helpers_test.go b/core/chains/evm/client/helpers_test.go index a2a55e1791..8caacb4190 100644 --- a/core/chains/evm/client/helpers_test.go +++ b/core/chains/evm/client/helpers_test.go @@ -140,7 +140,7 @@ func NewChainClientWithTestNode( } lggr := logger.Test(t) - rpc := NewRPCClient(lggr, *parsed, rpcHTTPURL, "eth-primary-rpc-0", id, chainID, commonclient.Primary, 0) + rpc := NewRPCClient(lggr, *parsed, rpcHTTPURL, "eth-primary-rpc-0", id, chainID, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) n := commonclient.NewNode[*big.Int, *evmtypes.Head, RPCClient]( nodeCfg, clientMocks.ChainConfig{NoNewHeadsThresholdVal: noNewHeadsThreshold}, lggr, *parsed, rpcHTTPURL, "eth-primary-node-0", id, chainID, 1, rpc, "EVM") @@ -152,7 +152,7 @@ func NewChainClientWithTestNode( return nil, pkgerrors.Errorf("sendonly ethereum rpc url scheme must be http(s): %s", u.String()) } var empty url.URL - rpc := NewRPCClient(lggr, empty, &sendonlyRPCURLs[i], fmt.Sprintf("eth-sendonly-rpc-%d", i), id, chainID, commonclient.Secondary, 0) + rpc := NewRPCClient(lggr, empty, &sendonlyRPCURLs[i], fmt.Sprintf("eth-sendonly-rpc-%d", i), id, chainID, commonclient.Secondary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) s := commonclient.NewSendOnlyNode[*big.Int, RPCClient]( lggr, u, fmt.Sprintf("eth-sendonly-%d", i), chainID, rpc) sendonlys = append(sendonlys, s) diff --git a/core/chains/evm/client/rpc_client.go b/core/chains/evm/client/rpc_client.go index 1a0023227a..200703dd42 100644 --- a/core/chains/evm/client/rpc_client.go +++ b/core/chains/evm/client/rpc_client.go @@ -117,6 +117,8 @@ type rpcClient struct { id int32 chainID *big.Int tier commonclient.NodeTier + largePayloadRpcTimeout time.Duration + rpcTimeout time.Duration finalizedBlockPollInterval time.Duration ws rawclient @@ -152,8 +154,13 @@ func NewRPCClient( chainID *big.Int, tier commonclient.NodeTier, finalizedBlockPollInterval time.Duration, + largePayloadRpcTimeout time.Duration, + rpcTimeout time.Duration, ) RPCClient { - r := new(rpcClient) + r := &rpcClient{ + largePayloadRpcTimeout: largePayloadRpcTimeout, + rpcTimeout: rpcTimeout, + } r.name = name r.id = id r.chainID = chainID @@ -178,7 +185,7 @@ func NewRPCClient( // Not thread-safe, pure dial. func (r *rpcClient) Dial(callerCtx context.Context) error { - ctx, cancel := r.makeQueryCtx(callerCtx) + ctx, cancel := r.makeQueryCtx(callerCtx, r.rpcTimeout) defer cancel() promEVMPoolRPCNodeDials.WithLabelValues(r.chainID.String(), r.name).Inc() @@ -367,7 +374,7 @@ func (r *rpcClient) UnsubscribeAllExceptAliveLoop() { // CallContext implementation func (r *rpcClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.largePayloadRpcTimeout) defer cancel() lggr := r.newRqLggr().With( "method", method, @@ -390,7 +397,7 @@ func (r *rpcClient) CallContext(ctx context.Context, result interface{}, method } func (r *rpcClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.largePayloadRpcTimeout) defer cancel() lggr := r.newRqLggr().With("nBatchElems", len(b), "batchElems", b) @@ -411,7 +418,7 @@ func (r *rpcClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) err // TODO: Full transition from SubscribeNewHead to SubscribeToHeads is done in BCI-2875 func (r *rpcClient) SubscribeNewHead(ctx context.Context, channel chan<- *evmtypes.Head) (_ commontypes.Subscription, err error) { - ctx, cancel, chStopInFlight, ws, _ := r.acquireQueryCtx(ctx) + ctx, cancel, chStopInFlight, ws, _ := r.acquireQueryCtx(ctx, r.rpcTimeout) defer cancel() args := []interface{}{"newHeads"} lggr := r.newRqLggr().With("args", args) @@ -442,7 +449,7 @@ func (r *rpcClient) SubscribeNewHead(ctx context.Context, channel chan<- *evmtyp } func (r *rpcClient) SubscribeToHeads(ctx context.Context) (ch <-chan *evmtypes.Head, sub commontypes.Subscription, err error) { - ctx, cancel, chStopInFlight, ws, _ := r.acquireQueryCtx(ctx) + ctx, cancel, chStopInFlight, ws, _ := r.acquireQueryCtx(ctx, r.rpcTimeout) defer cancel() args := []interface{}{rpcSubscriptionMethodNewHeads} @@ -504,7 +511,7 @@ func (r *rpcClient) TransactionReceipt(ctx context.Context, txHash common.Hash) } func (r *rpcClient) TransactionReceiptGeth(ctx context.Context, txHash common.Hash) (receipt *types.Receipt, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("txHash", txHash) @@ -527,7 +534,7 @@ func (r *rpcClient) TransactionReceiptGeth(ctx context.Context, txHash common.Ha return } func (r *rpcClient) TransactionByHash(ctx context.Context, txHash common.Hash) (tx *types.Transaction, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("txHash", txHash) @@ -551,7 +558,7 @@ func (r *rpcClient) TransactionByHash(ctx context.Context, txHash common.Hash) ( } func (r *rpcClient) HeaderByNumber(ctx context.Context, number *big.Int) (header *types.Header, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("number", number) @@ -572,7 +579,7 @@ func (r *rpcClient) HeaderByNumber(ctx context.Context, number *big.Int) (header } func (r *rpcClient) HeaderByHash(ctx context.Context, hash common.Hash) (header *types.Header, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("hash", hash) @@ -604,7 +611,7 @@ func (r *rpcClient) BlockByNumber(ctx context.Context, number *big.Int) (head *e } func (r *rpcClient) blockByNumber(ctx context.Context, number string) (head *evmtypes.Head, err error) { - ctx, cancel, chStopInFlight, ws, http := r.acquireQueryCtx(ctx) + ctx, cancel, chStopInFlight, ws, http := r.acquireQueryCtx(ctx, r.rpcTimeout) defer cancel() const method = "eth_getBlockByNumber" args := []interface{}{number, false} @@ -656,7 +663,7 @@ func (r *rpcClient) BlockByHash(ctx context.Context, hash common.Hash) (head *ev } func (r *rpcClient) BlockByHashGeth(ctx context.Context, hash common.Hash) (block *types.Block, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("hash", hash) @@ -679,7 +686,7 @@ func (r *rpcClient) BlockByHashGeth(ctx context.Context, hash common.Hash) (bloc } func (r *rpcClient) BlockByNumberGeth(ctx context.Context, number *big.Int) (block *types.Block, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("number", number) @@ -702,7 +709,7 @@ func (r *rpcClient) BlockByNumberGeth(ctx context.Context, number *big.Int) (blo } func (r *rpcClient) SendTransaction(ctx context.Context, tx *types.Transaction) error { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.largePayloadRpcTimeout) defer cancel() lggr := r.newRqLggr().With("tx", tx) @@ -740,7 +747,7 @@ func (r *rpcClient) SendEmptyTransaction( // PendingSequenceAt returns one higher than the highest nonce from both mempool and mined transactions func (r *rpcClient) PendingSequenceAt(ctx context.Context, account common.Address) (nonce evmtypes.Nonce, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("account", account) @@ -769,7 +776,7 @@ func (r *rpcClient) PendingSequenceAt(ctx context.Context, account common.Addres // mined nonce at the given block number, but it actually returns the total // transaction count which is the highest mined nonce + 1 func (r *rpcClient) SequenceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (nonce evmtypes.Nonce, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("account", account, "blockNumber", blockNumber) @@ -795,7 +802,7 @@ func (r *rpcClient) SequenceAt(ctx context.Context, account common.Address, bloc } func (r *rpcClient) PendingCodeAt(ctx context.Context, account common.Address) (code []byte, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("account", account) @@ -818,7 +825,7 @@ func (r *rpcClient) PendingCodeAt(ctx context.Context, account common.Address) ( } func (r *rpcClient) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) (code []byte, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("account", account, "blockNumber", blockNumber) @@ -841,7 +848,7 @@ func (r *rpcClient) CodeAt(ctx context.Context, account common.Address, blockNum } func (r *rpcClient) EstimateGas(ctx context.Context, c interface{}) (gas uint64, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.largePayloadRpcTimeout) defer cancel() call := c.(ethereum.CallMsg) lggr := r.newRqLggr().With("call", call) @@ -865,7 +872,7 @@ func (r *rpcClient) EstimateGas(ctx context.Context, c interface{}) (gas uint64, } func (r *rpcClient) SuggestGasPrice(ctx context.Context) (price *big.Int, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr() @@ -888,7 +895,7 @@ func (r *rpcClient) SuggestGasPrice(ctx context.Context) (price *big.Int, err er } func (r *rpcClient) CallContract(ctx context.Context, msg interface{}, blockNumber *big.Int) (val []byte, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.largePayloadRpcTimeout) defer cancel() lggr := r.newRqLggr().With("callMsg", msg, "blockNumber", blockNumber) message := msg.(ethereum.CallMsg) @@ -916,7 +923,7 @@ func (r *rpcClient) CallContract(ctx context.Context, msg interface{}, blockNumb } func (r *rpcClient) PendingCallContract(ctx context.Context, msg interface{}) (val []byte, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.largePayloadRpcTimeout) defer cancel() lggr := r.newRqLggr().With("callMsg", msg) message := msg.(ethereum.CallMsg) @@ -950,7 +957,7 @@ func (r *rpcClient) LatestBlockHeight(ctx context.Context) (*big.Int, error) { } func (r *rpcClient) BlockNumber(ctx context.Context) (height uint64, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr() @@ -973,7 +980,7 @@ func (r *rpcClient) BlockNumber(ctx context.Context) (height uint64, err error) } func (r *rpcClient) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (balance *big.Int, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("account", account.Hex(), "blockNumber", blockNumber) @@ -1038,7 +1045,7 @@ func (r *rpcClient) FilterEvents(ctx context.Context, q ethereum.FilterQuery) ([ } func (r *rpcClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) (l []types.Log, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("q", q) @@ -1066,7 +1073,7 @@ func (r *rpcClient) ClientVersion(ctx context.Context) (version string, err erro } func (r *rpcClient) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (_ ethereum.Subscription, err error) { - ctx, cancel, chStopInFlight, ws, _ := r.acquireQueryCtx(ctx) + ctx, cancel, chStopInFlight, ws, _ := r.acquireQueryCtx(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr().With("q", q) @@ -1092,7 +1099,7 @@ func (r *rpcClient) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQu } func (r *rpcClient) SuggestGasTipCap(ctx context.Context) (tipCap *big.Int, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr() @@ -1117,7 +1124,7 @@ func (r *rpcClient) SuggestGasTipCap(ctx context.Context) (tipCap *big.Int, err // Returns the ChainID according to the geth client. This is useful for functions like verify() // the common node. func (r *rpcClient) ChainID(ctx context.Context) (chainID *big.Int, err error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() @@ -1172,12 +1179,12 @@ func (r *rpcClient) wrapHTTP(err error) error { } // makeLiveQueryCtxAndSafeGetClients wraps makeQueryCtx -func (r *rpcClient) makeLiveQueryCtxAndSafeGetClients(parentCtx context.Context) (ctx context.Context, cancel context.CancelFunc, ws rawclient, http *rawclient) { - ctx, cancel, _, ws, http = r.acquireQueryCtx(parentCtx) +func (r *rpcClient) makeLiveQueryCtxAndSafeGetClients(parentCtx context.Context, timeout time.Duration) (ctx context.Context, cancel context.CancelFunc, ws rawclient, http *rawclient) { + ctx, cancel, _, ws, http = r.acquireQueryCtx(parentCtx, timeout) return } -func (r *rpcClient) acquireQueryCtx(parentCtx context.Context) (ctx context.Context, cancel context.CancelFunc, +func (r *rpcClient) acquireQueryCtx(parentCtx context.Context, timeout time.Duration) (ctx context.Context, cancel context.CancelFunc, chStopInFlight chan struct{}, ws rawclient, http *rawclient) { // Need to wrap in mutex because state transition can cancel and replace the // context @@ -1189,7 +1196,7 @@ func (r *rpcClient) acquireQueryCtx(parentCtx context.Context) (ctx context.Cont http = &cp } r.stateMu.RUnlock() - ctx, cancel = makeQueryCtx(parentCtx, chStopInFlight) + ctx, cancel = makeQueryCtx(parentCtx, chStopInFlight, timeout) return } @@ -1197,10 +1204,10 @@ func (r *rpcClient) acquireQueryCtx(parentCtx context.Context) (ctx context.Cont // 1. Passed in ctx cancels // 2. Passed in channel is closed // 3. Default timeout is reached (queryTimeout) -func makeQueryCtx(ctx context.Context, ch services.StopChan) (context.Context, context.CancelFunc) { +func makeQueryCtx(ctx context.Context, ch services.StopChan, timeout time.Duration) (context.Context, context.CancelFunc) { var chCancel, timeoutCancel context.CancelFunc ctx, chCancel = ch.Ctx(ctx) - ctx, timeoutCancel = context.WithTimeout(ctx, queryTimeout) + ctx, timeoutCancel = context.WithTimeout(ctx, timeout) cancel := func() { chCancel() timeoutCancel() @@ -1208,12 +1215,12 @@ func makeQueryCtx(ctx context.Context, ch services.StopChan) (context.Context, c return ctx, cancel } -func (r *rpcClient) makeQueryCtx(ctx context.Context) (context.Context, context.CancelFunc) { - return makeQueryCtx(ctx, r.getChStopInflight()) +func (r *rpcClient) makeQueryCtx(ctx context.Context, timeout time.Duration) (context.Context, context.CancelFunc) { + return makeQueryCtx(ctx, r.getChStopInflight(), timeout) } func (r *rpcClient) IsSyncing(ctx context.Context) (bool, error) { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() lggr := r.newRqLggr() diff --git a/core/chains/evm/client/rpc_client_test.go b/core/chains/evm/client/rpc_client_test.go index 9b21aedbea..d6a11e0d01 100644 --- a/core/chains/evm/client/rpc_client_test.go +++ b/core/chains/evm/client/rpc_client_test.go @@ -3,10 +3,12 @@ package client_test import ( "context" "encoding/json" + "errors" "fmt" "math/big" "net/url" "testing" + "time" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/core/types" @@ -56,7 +58,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) // set to default values @@ -106,7 +108,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) ch := make(chan *evmtypes.Head) @@ -129,7 +131,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { t.Run("Block's chain ID matched configured", func(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) ch := make(chan *evmtypes.Head) @@ -146,7 +148,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { }) wsURL := server.WSURL() observedLggr, observed := logger.TestObserved(t, zap.DebugLevel) - rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) + rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) require.NoError(t, rpc.Dial(ctx)) server.Close() _, err := rpc.SubscribeNewHead(ctx, make(chan *evmtypes.Head)) @@ -156,7 +158,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { t.Run("Subscription error is properly wrapper", func(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) sub, err := rpc.SubscribeNewHead(ctx, make(chan *evmtypes.Head)) @@ -184,7 +186,7 @@ func TestRPCClient_SubscribeFilterLogs(t *testing.T) { }) wsURL := server.WSURL() observedLggr, observed := logger.TestObserved(t, zap.DebugLevel) - rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) + rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) require.NoError(t, rpc.Dial(ctx)) server.Close() _, err := rpc.SubscribeFilterLogs(ctx, ethereum.FilterQuery{}, make(chan types.Log)) @@ -201,7 +203,7 @@ func TestRPCClient_SubscribeFilterLogs(t *testing.T) { return resp }) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) sub, err := rpc.SubscribeFilterLogs(ctx, ethereum.FilterQuery{}, make(chan types.Log)) @@ -250,7 +252,7 @@ func TestRPCClient_LatestFinalizedBlock(t *testing.T) { } server := createRPCServer() - rpc := client.NewRPCClient(lggr, *server.URL, nil, "rpc", 1, chainId, commonclient.Primary, 0) + rpc := client.NewRPCClient(lggr, *server.URL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) require.NoError(t, rpc.Dial(ctx)) defer rpc.Close() server.Head = &evmtypes.Head{Number: 128} @@ -298,3 +300,73 @@ func TestRPCClient_LatestFinalizedBlock(t *testing.T) { assert.Equal(t, int64(0), latest.BlockNumber) assert.Equal(t, int64(0), latest.FinalizedBlockNumber) } + +func TestRpcClientLargePayloadTimeout(t *testing.T) { + t.Parallel() + + testCases := []struct { + Name string + Fn func(ctx context.Context, rpc client.RPCClient) error + }{ + { + Name: "SendTransaction", + Fn: func(ctx context.Context, rpc client.RPCClient) error { + return rpc.SendTransaction(ctx, types.NewTx(&types.LegacyTx{})) + }, + }, + { + Name: "EstimateGas", + Fn: func(ctx context.Context, rpc client.RPCClient) error { + _, err := rpc.EstimateGas(ctx, ethereum.CallMsg{}) + return err + }, + }, + { + Name: "CallContract", + Fn: func(ctx context.Context, rpc client.RPCClient) error { + _, err := rpc.CallContract(ctx, ethereum.CallMsg{}, nil) + return err + }, + }, + { + Name: "CallContext", + Fn: func(ctx context.Context, rpc client.RPCClient) error { + err := rpc.CallContext(ctx, nil, "rpc_call", nil) + return err + }, + }, + { + Name: "BatchCallContext", + Fn: func(ctx context.Context, rpc client.RPCClient) error { + err := rpc.BatchCallContext(ctx, nil) + return err + }, + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.Name, func(t *testing.T) { + t.Parallel() + // use background context to ensure that the DeadlineExceeded is caused by timeout we've set on request + // level, instead of one that was set on test level. + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + chainId := big.NewInt(123456) + rpcURL := testutils.NewWSServer(t, chainId, func(method string, params gjson.Result) (resp testutils.JSONRPCResponse) { + // block until test is done + <-ctx.Done() + return + }).WSURL() + + // use something unreasonably large for RPC timeout to ensure that we use largePayloadRPCTimeout + const rpcTimeout = time.Hour + const largePayloadRPCTimeout = tests.TestInterval + rpc := client.NewRPCClient(logger.Test(t), *rpcURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, largePayloadRPCTimeout, rpcTimeout) + require.NoError(t, rpc.Dial(ctx)) + defer rpc.Close() + err := testCase.Fn(ctx, rpc) + assert.True(t, errors.Is(err, context.DeadlineExceeded), fmt.Sprintf("Expected DedlineExceeded error, but got: %v", err)) + }) + } +} diff --git a/core/chains/evm/config/chaintype/chaintype.go b/core/chains/evm/config/chaintype/chaintype.go index 9b845969e4..e8abfc5abb 100644 --- a/core/chains/evm/config/chaintype/chaintype.go +++ b/core/chains/evm/config/chaintype/chaintype.go @@ -19,6 +19,7 @@ const ( ChainXLayer ChainType = "xlayer" ChainZkEvm ChainType = "zkevm" ChainZkSync ChainType = "zksync" + ChainHedera ChainType = "hedera" ) // IsL2 returns true if this chain is a Layer 2 chain. Notably: @@ -35,7 +36,7 @@ func (c ChainType) IsL2() bool { func (c ChainType) IsValid() bool { switch c { - case "", ChainArbitrum, ChainCelo, ChainGnosis, ChainKroma, ChainMetis, ChainOptimismBedrock, ChainScroll, ChainWeMix, ChainXLayer, ChainZkEvm, ChainZkSync: + case "", ChainArbitrum, ChainCelo, ChainGnosis, ChainKroma, ChainMetis, ChainOptimismBedrock, ChainScroll, ChainWeMix, ChainXLayer, ChainZkEvm, ChainZkSync, ChainHedera: return true } return false @@ -65,6 +66,8 @@ func ChainTypeFromSlug(slug string) ChainType { return ChainZkEvm case "zksync": return ChainZkSync + case "hedera": + return ChainHedera default: return ChainType(slug) } @@ -128,4 +131,5 @@ var ErrInvalidChainType = fmt.Errorf("must be one of %s or omitted", strings.Joi string(ChainXLayer), string(ChainZkEvm), string(ChainZkSync), + string(ChainHedera), }, ", ")) diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index ba182b8f60..256ef9e940 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -1302,7 +1302,7 @@ func TestConfig_Validate(t *testing.T) { - 1: 10 errors: - ChainType: invalid value (Foo): must not be set with this chain id - Nodes: missing: must have at least one node - - ChainType: invalid value (Foo): must be one of arbitrum, celo, gnosis, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync or omitted + - ChainType: invalid value (Foo): must be one of arbitrum, celo, gnosis, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync, hedera or omitted - HeadTracker.HistoryDepth: invalid value (30): must be greater than or equal to FinalizedBlockOffset - GasEstimator.BumpThreshold: invalid value (0): cannot be 0 if auto-purge feature is enabled for Foo - Transactions.AutoPurge.Threshold: missing: needs to be set if auto-purge feature is enabled for Foo @@ -1315,7 +1315,7 @@ func TestConfig_Validate(t *testing.T) { - 2: 5 errors: - ChainType: invalid value (Arbitrum): only "optimismBedrock" can be used with this chain id - Nodes: missing: must have at least one node - - ChainType: invalid value (Arbitrum): must be one of arbitrum, celo, gnosis, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync or omitted + - ChainType: invalid value (Arbitrum): must be one of arbitrum, celo, gnosis, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync, hedera or omitted - FinalityDepth: invalid value (0): must be greater than or equal to 1 - MinIncomingConfirmations: invalid value (0): must be greater than or equal to 1 - 3.Nodes: 5 errors: diff --git a/core/services/ocr/contract_tracker.go b/core/services/ocr/contract_tracker.go index 11dfacd1d1..9546c522a2 100644 --- a/core/services/ocr/contract_tracker.go +++ b/core/services/ocr/contract_tracker.go @@ -399,7 +399,7 @@ func (t *OCRContractTracker) LatestBlockHeight(ctx context.Context) (blockheight // care about the block height; we have no way of getting the L1 block // height anyway return 0, nil - case "", chaintype.ChainArbitrum, chaintype.ChainCelo, chaintype.ChainGnosis, chaintype.ChainKroma, chaintype.ChainOptimismBedrock, chaintype.ChainScroll, chaintype.ChainWeMix, chaintype.ChainXLayer, chaintype.ChainZkEvm, chaintype.ChainZkSync: + case "", chaintype.ChainArbitrum, chaintype.ChainCelo, chaintype.ChainGnosis, chaintype.ChainKroma, chaintype.ChainOptimismBedrock, chaintype.ChainScroll, chaintype.ChainWeMix, chaintype.ChainXLayer, chaintype.ChainZkEvm, chaintype.ChainZkSync, chaintype.ChainHedera: // continue } latestBlockHeight := t.getLatestBlockHeight() From 94aa60db8f3842fef41f9afc2eb1bf94049b564b Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Wed, 31 Jul 2024 17:44:42 -0400 Subject: [PATCH 016/432] Updates CTF and removes some replaces (#13980) --- integration-tests/go.mod | 40 +++-------------------------------- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 4 ++-- integration-tests/load/go.sum | 4 ++-- 4 files changed, 9 insertions(+), 43 deletions(-) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index d76fb920d1..f485b290db 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -29,7 +29,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 - github.com/smartcontractkit/chainlink-testing-framework v1.32.7 + github.com/smartcontractkit/chainlink-testing-framework v1.33.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 @@ -466,13 +466,13 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect k8s.io/api v0.28.2 // indirect - k8s.io/apiextensions-apiserver v0.28.1 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect k8s.io/cli-runtime v0.28.2 // indirect k8s.io/client-go v0.28.2 // indirect k8s.io/component-base v0.28.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect - k8s.io/kubectl v0.28.1 // indirect + k8s.io/kubectl v0.28.2 // indirect k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect nhooyr.io/websocket v1.8.7 // indirect pgregory.net/rapid v0.5.5 // indirect @@ -507,37 +507,3 @@ replace ( github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.14.0 github.com/prometheus/common => github.com/prometheus/common v0.42.0 ) - -replace ( - k8s.io/api => k8s.io/api v0.28.2 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.28.2 - k8s.io/apimachinery => k8s.io/apimachinery v0.28.2 - k8s.io/apiserver => k8s.io/apiserver v0.28.2 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.28.2 - k8s.io/client-go => k8s.io/client-go v0.28.2 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.28.2 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.28.2 - k8s.io/code-generator => k8s.io/code-generator v0.28.2 - k8s.io/component-base => k8s.io/component-base v0.28.2 - k8s.io/component-helpers => k8s.io/component-helpers v0.28.2 - k8s.io/controller-manager => k8s.io/controller-manager v0.28.2 - k8s.io/cri-api => k8s.io/cri-api v0.28.2 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.28.2 - k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.28.2 - k8s.io/endpointslice => k8s.io/endpointslice v0.28.2 - k8s.io/kms => k8s.io/kms v0.28.2 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.28.2 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.28.2 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.28.2 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.28.2 - k8s.io/kubectl => k8s.io/kubectl v0.28.2 - k8s.io/kubelet => k8s.io/kubelet v0.28.2 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.28.2 - k8s.io/metrics => k8s.io/metrics v0.28.2 - k8s.io/mount-utils => k8s.io/mount-utils v0.28.2 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.28.2 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.28.2 - k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.28.2 - k8s.io/sample-controller => k8s.io/sample-controller v0.28.2 - sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.16.2 -) diff --git a/integration-tests/go.sum b/integration-tests/go.sum index dd002a75d5..57b55a8b01 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1498,8 +1498,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.32.7 h1:/I6Upq9KdnleWnUF1W3c3mAgMowAgi0yAcn8Vh5Px50= -github.com/smartcontractkit/chainlink-testing-framework v1.32.7/go.mod h1:Y1D6k7KLPZ52kwp3WJxShp4Wzw22jKldIzMT2yosipI= +github.com/smartcontractkit/chainlink-testing-framework v1.33.0 h1:vHQODEdsq5AIbRiyZZ30de6uwJUNFXLYvCr+Odr8TIs= +github.com/smartcontractkit/chainlink-testing-framework v1.33.0/go.mod h1:GrhHthZ5AmceF82+Ypw6Fov1EvB05JJbb1T0EKyO1x0= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 95726e6371..0a774c01dd 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,7 +17,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 - github.com/smartcontractkit/chainlink-testing-framework v1.32.7 + github.com/smartcontractkit/chainlink-testing-framework v1.33.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 @@ -474,7 +474,7 @@ require ( k8s.io/component-base v0.30.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect - k8s.io/kubectl v0.28.1 // indirect + k8s.io/kubectl v0.28.2 // indirect k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect nhooyr.io/websocket v1.8.7 // indirect pgregory.net/rapid v0.5.5 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 0fbe5f832c..0db884f178 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1480,8 +1480,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.32.7 h1:/I6Upq9KdnleWnUF1W3c3mAgMowAgi0yAcn8Vh5Px50= -github.com/smartcontractkit/chainlink-testing-framework v1.32.7/go.mod h1:Y1D6k7KLPZ52kwp3WJxShp4Wzw22jKldIzMT2yosipI= +github.com/smartcontractkit/chainlink-testing-framework v1.33.0 h1:vHQODEdsq5AIbRiyZZ30de6uwJUNFXLYvCr+Odr8TIs= +github.com/smartcontractkit/chainlink-testing-framework v1.33.0/go.mod h1:GrhHthZ5AmceF82+Ypw6Fov1EvB05JJbb1T0EKyO1x0= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= From 610a516390bdc93714db4d587498205e4a60603c Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Thu, 1 Aug 2024 06:14:48 -0700 Subject: [PATCH 017/432] [Keystone] Fix init order for Peer Wrapper and Dispatcher (#13976) --- core/services/chainlink/application.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index cabaacbb27..138ca25ed3 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -213,17 +213,15 @@ func NewApplication(opts ApplicationOpts) (Application, error) { externalPeer := externalp2p.NewExternalPeerWrapper(keyStore.P2P(), cfg.Capabilities().Peering(), opts.DS, globalLogger) signer := externalPeer externalPeerWrapper = externalPeer - remoteDispatcher := remote.NewDispatcher(externalPeerWrapper, signer, opts.CapabilitiesRegistry, globalLogger) - srvcs = append(srvcs, remoteDispatcher) - - dispatcher = remoteDispatcher - } else { + dispatcher = remote.NewDispatcher(externalPeerWrapper, signer, opts.CapabilitiesRegistry, globalLogger) + srvcs = append(srvcs, externalPeerWrapper) // peer wrapper must be started before dispatcher + srvcs = append(srvcs, dispatcher) + } else { // tests only dispatcher = opts.CapabilitiesDispatcher externalPeerWrapper = opts.CapabilitiesPeerWrapper + srvcs = append(srvcs, externalPeerWrapper) } - srvcs = append(srvcs, externalPeerWrapper) - rid := cfg.Capabilities().ExternalRegistry().RelayID() registryAddress := cfg.Capabilities().ExternalRegistry().Address() relayer, err := relayerChainInterops.Get(rid) From 20dbba8e76604a2488b0717d53d706ee11b11a9c Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Thu, 1 Aug 2024 08:45:14 -0500 Subject: [PATCH 018/432] Add nonce validation after broadcast for Hedera (#13957) * Added post-broadcast nonce validation for Hedera * Added changeset * Updated chaintype docs for Hedera * Fixed lint errors * Added condition to handle on-chain seq less than tx seq and updated comment --- .changeset/friendly-impalas-sniff.md | 5 + common/txmgr/broadcaster.go | 92 +++++++++++++---- common/txmgr/confirmer.go | 12 ++- common/txmgr/types/tx_store.go | 1 + core/chains/evm/config/chaintype/chaintype.go | 10 +- core/chains/evm/txmgr/broadcaster_test.go | 98 ++++++++++++++++++- core/chains/evm/txmgr/builder.go | 6 +- core/chains/evm/types/types.go | 16 +++ core/config/docs/chains-evm.toml | 2 +- core/services/chainlink/config_test.go | 4 +- core/services/ocr/contract_tracker.go | 2 +- docs/CONFIG.md | 2 +- 12 files changed, 213 insertions(+), 37 deletions(-) create mode 100644 .changeset/friendly-impalas-sniff.md diff --git a/.changeset/friendly-impalas-sniff.md b/.changeset/friendly-impalas-sniff.md new file mode 100644 index 0000000000..8a041a338b --- /dev/null +++ b/.changeset/friendly-impalas-sniff.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Added nonce validation immediately after broadcast for Hedera #internal diff --git a/common/txmgr/broadcaster.go b/common/txmgr/broadcaster.go index 2a9c1231d7..b2fb1dabff 100644 --- a/common/txmgr/broadcaster.go +++ b/common/txmgr/broadcaster.go @@ -34,6 +34,13 @@ const ( // TransmitCheckTimeout controls the maximum amount of time that will be // spent on the transmit check. TransmitCheckTimeout = 2 * time.Second + + // maxBroadcastRetries is the number of times a transaction broadcast is retried when the sequence fails to increment on Hedera + maxHederaBroadcastRetries = 3 + + // hederaChainType is the string representation of the Hedera chain type + // Temporary solution until the Broadcaster is moved to the EVM code base + hederaChainType = "hedera" ) var ( @@ -114,6 +121,7 @@ type Broadcaster[ sequenceTracker txmgrtypes.SequenceTracker[ADDR, SEQ] resumeCallback ResumeCallback chainID CHAIN_ID + chainType string config txmgrtypes.BroadcasterChainConfig feeConfig txmgrtypes.BroadcasterFeeConfig txConfig txmgrtypes.BroadcasterTransactionsConfig @@ -163,6 +171,7 @@ func NewBroadcaster[ lggr logger.Logger, checkerFactory TransmitCheckerFactory[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], autoSyncSequence bool, + chainType string, ) *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] { lggr = logger.Named(lggr, "Broadcaster") b := &Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]{ @@ -171,6 +180,7 @@ func NewBroadcaster[ client: client, TxAttemptBuilder: txAttemptBuilder, chainID: client.ConfiguredChainID(), + chainType: chainType, config: config, feeConfig: feeConfig, txConfig: txConfig, @@ -411,7 +421,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand return fmt.Errorf("handleAnyInProgressTx failed: %w", err), true } if etx != nil { - if err, retryable := eb.handleInProgressTx(ctx, *etx, etx.TxAttempts[0], etx.CreatedAt); err != nil { + if err, retryable := eb.handleInProgressTx(ctx, *etx, etx.TxAttempts[0], etx.CreatedAt, 0); err != nil { return fmt.Errorf("handleAnyInProgressTx failed: %w", err), retryable } } @@ -464,12 +474,12 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand return fmt.Errorf("processUnstartedTxs failed on UpdateTxUnstartedToInProgress: %w", err), true } - return eb.handleInProgressTx(ctx, *etx, attempt, time.Now()) + return eb.handleInProgressTx(ctx, *etx, attempt, time.Now(), 0) } // There can be at most one in_progress transaction per address. // Here we complete the job that we didn't finish last time. -func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) handleInProgressTx(ctx context.Context, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time) (error, bool) { +func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) handleInProgressTx(ctx context.Context, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time, retryCount int) (error, bool) { if etx.State != TxInProgress { return fmt.Errorf("invariant violation: expected transaction %v to be in_progress, it was %s", etx.ID, etx.State), false } @@ -478,6 +488,11 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand lgr.Infow("Sending transaction", "txAttemptID", attempt.ID, "txHash", attempt.Hash, "meta", etx.Meta, "feeLimit", attempt.ChainSpecificFeeLimit, "callerProvidedFeeLimit", etx.FeeLimit, "attempt", attempt, "etx", etx) errType, err := eb.client.SendTransactionReturnCode(ctx, etx, attempt, lgr) + // The validation below is only applicable to Hedera because it has instant finality and a unique sequence behavior + if eb.chainType == hederaChainType { + errType, err = eb.validateOnChainSequence(ctx, lgr, errType, err, etx, retryCount) + } + if errType != client.Fatal { etx.InitialBroadcastAt = &initialBroadcastAt etx.BroadcastAt = &initialBroadcastAt @@ -538,7 +553,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand eb.sequenceTracker.GenerateNextSequence(etx.FromAddress, *etx.Sequence) return err, true case client.Underpriced: - return eb.tryAgainBumpingGas(ctx, lgr, err, etx, attempt, initialBroadcastAt) + return eb.tryAgainBumpingGas(ctx, lgr, err, etx, attempt, initialBroadcastAt, retryCount+1) case client.InsufficientFunds: // NOTE: This bails out of the entire cycle and essentially "blocks" on // any transaction that gets insufficient_funds. This is OK if a @@ -600,6 +615,44 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand } } +func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) validateOnChainSequence(ctx context.Context, lgr logger.SugaredLogger, errType client.SendTxReturnCode, err error, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], retryCount int) (client.SendTxReturnCode, error) { + // Only check if sequence was incremented if broadcast was successful, otherwise return the existing err type + if errType != client.Successful { + return errType, err + } + // Transaction sequence cannot be nil here since a sequence is required to broadcast + txSeq := *etx.Sequence + // Retrieve the latest mined sequence from on-chain + nextSeqOnChain, err := eb.client.SequenceAt(ctx, etx.FromAddress, nil) + if err != nil { + return errType, err + } + + // Check that the transaction count has incremented on-chain to include the broadcasted transaction + // Insufficient transaction fee is a common scenario in which the sequence is not incremented by the chain even though we got a successful response + // If the sequence failed to increment and hasn't reached the max retries, return the Underpriced error to try again with a bumped attempt + if nextSeqOnChain.Int64() == txSeq.Int64() && retryCount < maxHederaBroadcastRetries { + return client.Underpriced, nil + } + + // If the transaction reaches the retry limit and fails to get included, mark it as fatally errored + // Some unknown error other than insufficient tx fee could be the cause + if nextSeqOnChain.Int64() == txSeq.Int64() && retryCount >= maxHederaBroadcastRetries { + err := fmt.Errorf("failed to broadcast transaction on %s after %d retries", hederaChainType, retryCount) + lgr.Error(err.Error()) + return client.Fatal, err + } + + // Belts and braces approach to detect and handle sqeuence gaps if the broadcast is considered successful + if nextSeqOnChain.Int64() < txSeq.Int64() { + err := fmt.Errorf("next expected sequence on-chain (%s) is less than the broadcasted transaction's sequence (%s)", nextSeqOnChain.String(), txSeq.String()) + lgr.Criticalw("Sequence gap has been detected and needs to be filled", "error", err) + return client.Fatal, err + } + + return client.Successful, nil +} + // Finds next transaction in the queue, assigns a sequence, and moves it to "in_progress" state ready for broadcast. // Returns nil if no transactions are in queue func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) nextUnstartedTransactionWithSequence(fromAddress ADDR) (*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) { @@ -622,23 +675,26 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) next return etx, nil } -func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryAgainBumpingGas(ctx context.Context, lgr logger.Logger, txError error, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time) (err error, retryable bool) { - logger.With(lgr, - "sendError", txError, - "attemptFee", attempt.TxFee, - "maxGasPriceConfig", eb.feeConfig.MaxFeePrice(), - ).Errorf("attempt fee %v was rejected by the node for being too low. "+ - "Node returned: '%s'. "+ - "Will bump and retry. ACTION REQUIRED: This is a configuration error. "+ - "Consider increasing FeeEstimator.PriceDefault (current value: %s)", - attempt.TxFee, txError.Error(), eb.feeConfig.FeePriceDefault()) +func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryAgainBumpingGas(ctx context.Context, lgr logger.Logger, txError error, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time, retry int) (err error, retryable bool) { + // This log error is not applicable to Hedera since the action required would not be needed for its gas estimator + if eb.chainType != hederaChainType { + logger.With(lgr, + "sendError", txError, + "attemptFee", attempt.TxFee, + "maxGasPriceConfig", eb.feeConfig.MaxFeePrice(), + ).Errorf("attempt fee %v was rejected by the node for being too low. "+ + "Node returned: '%s'. "+ + "Will bump and retry. ACTION REQUIRED: This is a configuration error. "+ + "Consider increasing FeeEstimator.PriceDefault (current value: %s)", + attempt.TxFee, txError.Error(), eb.feeConfig.FeePriceDefault()) + } replacementAttempt, bumpedFee, bumpedFeeLimit, retryable, err := eb.NewBumpTxAttempt(ctx, etx, attempt, nil, lgr) if err != nil { return fmt.Errorf("tryAgainBumpFee failed: %w", err), retryable } - return eb.saveTryAgainAttempt(ctx, lgr, etx, attempt, replacementAttempt, initialBroadcastAt, bumpedFee, bumpedFeeLimit) + return eb.saveTryAgainAttempt(ctx, lgr, etx, attempt, replacementAttempt, initialBroadcastAt, bumpedFee, bumpedFeeLimit, retry) } func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryAgainWithNewEstimation(ctx context.Context, lgr logger.Logger, txError error, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time) (err error, retryable bool) { @@ -655,15 +711,15 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryA lgr.Warnw("L2 rejected transaction due to incorrect fee, re-estimated and will try again", "etxID", etx.ID, "err", err, "newGasPrice", fee, "newGasLimit", feeLimit) - return eb.saveTryAgainAttempt(ctx, lgr, etx, attempt, replacementAttempt, initialBroadcastAt, fee, feeLimit) + return eb.saveTryAgainAttempt(ctx, lgr, etx, attempt, replacementAttempt, initialBroadcastAt, fee, feeLimit, 0) } -func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) saveTryAgainAttempt(ctx context.Context, lgr logger.Logger, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], replacementAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time, newFee FEE, newFeeLimit uint64) (err error, retyrable bool) { +func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) saveTryAgainAttempt(ctx context.Context, lgr logger.Logger, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], replacementAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time, newFee FEE, newFeeLimit uint64, retry int) (err error, retyrable bool) { if err = eb.txStore.SaveReplacementInProgressAttempt(ctx, attempt, &replacementAttempt); err != nil { return fmt.Errorf("tryAgainWithNewFee failed: %w", err), true } lgr.Debugw("Bumped fee on initial send", "oldFee", attempt.TxFee.String(), "newFee", newFee.String(), "newFeeLimit", newFeeLimit) - return eb.handleInProgressTx(ctx, etx, replacementAttempt, initialBroadcastAt) + return eb.handleInProgressTx(ctx, etx, replacementAttempt, initialBroadcastAt, retry) } func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) saveFatallyErroredTransaction(lgr logger.Logger, etx *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) error { diff --git a/common/txmgr/confirmer.go b/common/txmgr/confirmer.go index a9e30ffff1..1e3922fdbf 100644 --- a/common/txmgr/confirmer.go +++ b/common/txmgr/confirmer.go @@ -664,11 +664,15 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) bat } if receipt.GetStatus() == 0 { - rpcError, errExtract := ec.client.CallContract(ctx, attempt, receipt.GetBlockNumber()) - if errExtract == nil { - l.Warnw("transaction reverted on-chain", "hash", receipt.GetTxHash(), "rpcError", rpcError.String()) + if receipt.GetRevertReason() != nil { + l.Warnw("transaction reverted on-chain", "hash", receipt.GetTxHash(), "revertReason", *receipt.GetRevertReason()) } else { - l.Warnw("transaction reverted on-chain unable to extract revert reason", "hash", receipt.GetTxHash(), "err", err) + rpcError, errExtract := ec.client.CallContract(ctx, attempt, receipt.GetBlockNumber()) + if errExtract == nil { + l.Warnw("transaction reverted on-chain", "hash", receipt.GetTxHash(), "rpcError", rpcError.String()) + } else { + l.Warnw("transaction reverted on-chain unable to extract revert reason", "hash", receipt.GetTxHash(), "err", err) + } } // This might increment more than once e.g. in case of re-orgs going back and forth we might re-fetch the same receipt promRevertedTxCount.WithLabelValues(ec.chainID.String()).Add(1) diff --git a/common/txmgr/types/tx_store.go b/common/txmgr/types/tx_store.go index 25040ea3bd..875339cfba 100644 --- a/common/txmgr/types/tx_store.go +++ b/common/txmgr/types/tx_store.go @@ -132,4 +132,5 @@ type ChainReceipt[TX_HASH, BLOCK_HASH types.Hashable] interface { GetFeeUsed() uint64 GetTransactionIndex() uint GetBlockHash() BLOCK_HASH + GetRevertReason() *string } diff --git a/core/chains/evm/config/chaintype/chaintype.go b/core/chains/evm/config/chaintype/chaintype.go index e8abfc5abb..623a80f54f 100644 --- a/core/chains/evm/config/chaintype/chaintype.go +++ b/core/chains/evm/config/chaintype/chaintype.go @@ -11,6 +11,7 @@ const ( ChainArbitrum ChainType = "arbitrum" ChainCelo ChainType = "celo" ChainGnosis ChainType = "gnosis" + ChainHedera ChainType = "hedera" ChainKroma ChainType = "kroma" ChainMetis ChainType = "metis" ChainOptimismBedrock ChainType = "optimismBedrock" @@ -19,7 +20,6 @@ const ( ChainXLayer ChainType = "xlayer" ChainZkEvm ChainType = "zkevm" ChainZkSync ChainType = "zksync" - ChainHedera ChainType = "hedera" ) // IsL2 returns true if this chain is a Layer 2 chain. Notably: @@ -36,7 +36,7 @@ func (c ChainType) IsL2() bool { func (c ChainType) IsValid() bool { switch c { - case "", ChainArbitrum, ChainCelo, ChainGnosis, ChainKroma, ChainMetis, ChainOptimismBedrock, ChainScroll, ChainWeMix, ChainXLayer, ChainZkEvm, ChainZkSync, ChainHedera: + case "", ChainArbitrum, ChainCelo, ChainGnosis, ChainHedera, ChainKroma, ChainMetis, ChainOptimismBedrock, ChainScroll, ChainWeMix, ChainXLayer, ChainZkEvm, ChainZkSync: return true } return false @@ -50,6 +50,8 @@ func ChainTypeFromSlug(slug string) ChainType { return ChainCelo case "gnosis": return ChainGnosis + case "hedera": + return ChainHedera case "kroma": return ChainKroma case "metis": @@ -66,8 +68,6 @@ func ChainTypeFromSlug(slug string) ChainType { return ChainZkEvm case "zksync": return ChainZkSync - case "hedera": - return ChainHedera default: return ChainType(slug) } @@ -123,6 +123,7 @@ var ErrInvalidChainType = fmt.Errorf("must be one of %s or omitted", strings.Joi string(ChainArbitrum), string(ChainCelo), string(ChainGnosis), + string(ChainHedera), string(ChainKroma), string(ChainMetis), string(ChainOptimismBedrock), @@ -131,5 +132,4 @@ var ErrInvalidChainType = fmt.Errorf("must be one of %s or omitted", strings.Joi string(ChainXLayer), string(ChainZkEvm), string(ChainZkSync), - string(ChainHedera), }, ", ")) diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 3559c329de..537875a647 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -34,6 +34,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" gasmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/keystore" @@ -70,7 +71,7 @@ func NewTestEthBroadcaster( return gas.NewFixedPriceEstimator(config.EVM().GasEstimator(), nil, ge.BlockHistory(), lggr, nil) }, ge.EIP1559DynamicFees(), ge) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, keyStore, estimator) - ethBroadcaster := txmgrcommon.NewBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), gconfig.Database().Listener(), keyStore, txBuilder, nonceTracker, lggr, checkerFactory, nonceAutoSync) + ethBroadcaster := txmgrcommon.NewBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), gconfig.Database().Listener(), keyStore, txBuilder, nonceTracker, lggr, checkerFactory, nonceAutoSync, "") // Mark instance as test ethBroadcaster.XXXTestDisableUnstartedTxAutoProcessing() @@ -101,6 +102,7 @@ func TestEthBroadcaster_Lifecycle(t *testing.T) { logger.Test(t), &testCheckerFactory{}, false, + "", ) // Can't close an unstarted instance @@ -159,6 +161,7 @@ func TestEthBroadcaster_LoadNextSequenceMapFailure_StartupSuccess(t *testing.T) logger.Test(t), &testCheckerFactory{}, false, + "", ) // Instance starts without error even if loading next sequence map fails @@ -638,6 +641,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_OptimisticLockingOnEthTx(t *testi logger.Test(t), &testCheckerFactory{}, false, + "", ) eb.XXXTestDisableUnstartedTxAutoProcessing() @@ -1157,7 +1161,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { }, evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), evmcfg.EVM().GasEstimator()) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), evmcfg.EVM().GasEstimator(), ethKeyStore, estimator) localNextNonce = getLocalNextNonce(t, nonceTracker, fromAddress) - eb2 := txmgr.NewEvmBroadcaster(txStore, txmClient, txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(evmcfg.EVM().GasEstimator()), evmcfg.EVM().Transactions(), cfg.Database().Listener(), ethKeyStore, txBuilder, lggr, &testCheckerFactory{}, false) + eb2 := txmgr.NewEvmBroadcaster(txStore, txmClient, txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(evmcfg.EVM().GasEstimator()), evmcfg.EVM().Transactions(), cfg.Database().Listener(), ethKeyStore, txBuilder, lggr, &testCheckerFactory{}, false, "") retryable, err := eb2.ProcessUnstartedTxs(ctx, fromAddress) assert.NoError(t, err) assert.False(t, retryable) @@ -1753,7 +1757,7 @@ func TestEthBroadcaster_SyncNonce(t *testing.T) { kst.On("EnabledAddressesForChain", mock.Anything, testutils.FixtureChainID).Return(addresses, nil).Once() ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() txmClient := txmgr.NewEvmTxmClient(ethClient, nil) - eb := txmgr.NewEvmBroadcaster(txStore, txmClient, evmTxmCfg, txmgr.NewEvmTxmFeeConfig(ge), evmcfg.EVM().Transactions(), cfg.Database().Listener(), kst, txBuilder, lggr, checkerFactory, false) + eb := txmgr.NewEvmBroadcaster(txStore, txmClient, evmTxmCfg, txmgr.NewEvmTxmFeeConfig(ge), evmcfg.EVM().Transactions(), cfg.Database().Listener(), kst, txBuilder, lggr, checkerFactory, false, "") err := eb.Start(ctx) assert.NoError(t, err) @@ -1802,6 +1806,94 @@ func TestEthBroadcaster_NonceTracker_InProgressTx(t *testing.T) { }) } +func TestEthBroadcaster_HederaBroadcastValidation(t *testing.T) { + t.Parallel() + + db := pgtest.NewSqlxDB(t) + cfg := configtest.NewTestGeneralConfig(t) + txStore := cltest.NewTestTxStore(t, db) + ethKeyStore := cltest.NewKeyStore(t, db).Eth() + evmcfg := evmtest.NewChainScopedConfig(t, cfg) + ethClient := testutils.NewEthClientMockWithDefaultChain(t) + lggr, observed := logger.TestObserved(t, zapcore.DebugLevel) + ge := evmcfg.EVM().GasEstimator() + estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator { + return gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), nil, ge.BlockHistory(), lggr, nil) + }, ge.EIP1559DynamicFees(), ge) + txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ethKeyStore, estimator) + checkerFactory := &txmgr.CheckerFactory{Client: ethClient} + ctx := tests.Context(t) + + t.Run("transaction successfully broadcasted and increments on-chain nonce", func(t *testing.T) { + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + localNonce := uint64(0) + ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { + return tx.Nonce() == localNonce + }), fromAddress).Return(commonclient.Successful, nil).Once() + ethClient.On("SequenceAt", mock.Anything, fromAddress, mock.Anything).Return(evmtypes.Nonce(1), nil).Once() + + mustInsertInProgressEthTxWithAttempt(t, txStore, evmtypes.Nonce(localNonce), fromAddress) + nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) + eb := txmgrcommon.NewBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(evmcfg.EVM().GasEstimator()), evmcfg.EVM().Transactions(), cfg.Database().Listener(), ethKeyStore, txBuilder, nonceTracker, lggr, checkerFactory, false, string(chaintype.ChainHedera)) + // Mark instance as test + eb.XXXTestDisableUnstartedTxAutoProcessing() + servicetest.Run(t, eb) + + retryable, err := eb.ProcessUnstartedTxs(ctx, fromAddress) + require.NoError(t, err) + require.False(t, retryable) + }) + + t.Run("transaction successfully broadcasted, failed to increment on-chain nonce, succeeded on bumped retry attempt", func(t *testing.T) { + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + localNonce := uint64(0) + ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { + return tx.Nonce() == localNonce + }), fromAddress).Return(commonclient.Successful, nil).Twice() + ethClient.On("SequenceAt", mock.Anything, fromAddress, mock.Anything).Return(evmtypes.Nonce(0), nil).Once() + ethClient.On("SequenceAt", mock.Anything, fromAddress, mock.Anything).Return(evmtypes.Nonce(1), nil).Once() + + mustInsertInProgressEthTxWithAttempt(t, txStore, evmtypes.Nonce(localNonce), fromAddress) + nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) + eb := txmgrcommon.NewBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(evmcfg.EVM().GasEstimator()), evmcfg.EVM().Transactions(), cfg.Database().Listener(), ethKeyStore, txBuilder, nonceTracker, lggr, checkerFactory, false, string(chaintype.ChainHedera)) + // Mark instance as test + eb.XXXTestDisableUnstartedTxAutoProcessing() + servicetest.Run(t, eb) + + retryable, err := eb.ProcessUnstartedTxs(ctx, fromAddress) + tests.AssertLogEventually(t, observed, "Bumped fee on initial send") + require.NoError(t, err) + require.False(t, retryable) + }) + + t.Run("transaction successfully broadcasted, failed to increment on-chain nonce on every retry", func(t *testing.T) { + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + localNonce := uint64(0) + ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { + return tx.Nonce() == localNonce + }), fromAddress).Return(commonclient.Successful, nil).Times(4) + ethClient.On("SequenceAt", mock.Anything, fromAddress, mock.Anything).Return(evmtypes.Nonce(0), nil).Times(4) + + etx := mustInsertInProgressEthTxWithAttempt(t, txStore, evmtypes.Nonce(localNonce), fromAddress) + nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) + eb := txmgrcommon.NewBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(evmcfg.EVM().GasEstimator()), evmcfg.EVM().Transactions(), cfg.Database().Listener(), ethKeyStore, txBuilder, nonceTracker, lggr, checkerFactory, false, string(chaintype.ChainHedera)) + // Mark instance as test + eb.XXXTestDisableUnstartedTxAutoProcessing() + servicetest.Run(t, eb) + + retryable, err := eb.ProcessUnstartedTxs(ctx, fromAddress) + tests.AssertLogEventually(t, observed, "Bumped fee on initial send") + require.NoError(t, err) + require.False(t, retryable) + tests.AssertLogEventually(t, observed, "failed to broadcast transaction on hedera after 3 retries") + + etx, err = txStore.FindTxWithAttempts(ctx, etx.ID) + require.NoError(t, err) + require.Equal(t, txmgrcommon.TxFatalError, etx.State) + require.Error(t, etx.GetError(), "failed to broadcast transaction on hedera after 3 retries") + }) +} + type testCheckerFactory struct { err error } diff --git a/core/chains/evm/txmgr/builder.go b/core/chains/evm/txmgr/builder.go index dcf15a4fa2..8234d55b96 100644 --- a/core/chains/evm/txmgr/builder.go +++ b/core/chains/evm/txmgr/builder.go @@ -10,6 +10,7 @@ import ( txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/forwarders" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/keystore" @@ -49,7 +50,7 @@ func NewTxm( feeCfg := NewEvmTxmFeeConfig(fCfg) // wrap Evm specific config txmClient := NewEvmTxmClient(client, clientErrors) // wrap Evm specific client chainID := txmClient.ConfiguredChainID() - evmBroadcaster := NewEvmBroadcaster(txStore, txmClient, txmCfg, feeCfg, txConfig, listenerConfig, keyStore, txAttemptBuilder, lggr, checker, chainConfig.NonceAutoSync()) + evmBroadcaster := NewEvmBroadcaster(txStore, txmClient, txmCfg, feeCfg, txConfig, listenerConfig, keyStore, txAttemptBuilder, lggr, checker, chainConfig.NonceAutoSync(), chainConfig.ChainType()) evmTracker := NewEvmTracker(txStore, keyStore, chainID, lggr) stuckTxDetector := NewStuckTxDetector(lggr, client.ConfiguredChainID(), chainConfig.ChainType(), fCfg.PriceMax(), txConfig.AutoPurge(), estimator, txStore, client) evmConfirmer := NewEvmConfirmer(txStore, txmClient, txmCfg, feeCfg, txConfig, dbConfig, keyStore, txAttemptBuilder, lggr, stuckTxDetector) @@ -138,7 +139,8 @@ func NewEvmBroadcaster( logger logger.Logger, checkerFactory TransmitCheckerFactory, autoSyncNonce bool, + chainType chaintype.ChainType, ) *Broadcaster { nonceTracker := NewNonceTracker(logger, txStore, client) - return txmgr.NewBroadcaster(txStore, client, chainConfig, feeConfig, txConfig, listenerConfig, keystore, txAttemptBuilder, nonceTracker, logger, checkerFactory, autoSyncNonce) + return txmgr.NewBroadcaster(txStore, client, chainConfig, feeConfig, txConfig, listenerConfig, keystore, txAttemptBuilder, nonceTracker, logger, checkerFactory, autoSyncNonce, string(chainType)) } diff --git a/core/chains/evm/types/types.go b/core/chains/evm/types/types.go index 57a53bce67..c834ffeb86 100644 --- a/core/chains/evm/types/types.go +++ b/core/chains/evm/types/types.go @@ -63,6 +63,7 @@ type Receipt struct { BlockHash common.Hash `json:"blockHash,omitempty"` BlockNumber *big.Int `json:"blockNumber,omitempty"` TransactionIndex uint `json:"transactionIndex"` + RevertReason []byte `json:"revertReason,omitempty"` // Only provided by Hedera } // FromGethReceipt converts a gethTypes.Receipt to a Receipt @@ -86,6 +87,7 @@ func FromGethReceipt(gr *gethTypes.Receipt) *Receipt { gr.BlockHash, gr.BlockNumber, gr.TransactionIndex, + nil, } } @@ -119,6 +121,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { BlockHash common.Hash `json:"blockHash,omitempty"` BlockNumber *hexutil.Big `json:"blockNumber,omitempty"` TransactionIndex hexutil.Uint `json:"transactionIndex"` + RevertReason hexutil.Bytes `json:"revertReason,omitempty"` // Only provided by Hedera } var enc Receipt enc.PostState = r.PostState @@ -132,6 +135,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { enc.BlockHash = r.BlockHash enc.BlockNumber = (*hexutil.Big)(r.BlockNumber) enc.TransactionIndex = hexutil.Uint(r.TransactionIndex) + enc.RevertReason = r.RevertReason return json.Marshal(&enc) } @@ -149,6 +153,7 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { BlockHash *common.Hash `json:"blockHash,omitempty"` BlockNumber *hexutil.Big `json:"blockNumber,omitempty"` TransactionIndex *hexutil.Uint `json:"transactionIndex"` + RevertReason *hexutil.Bytes `json:"revertReason,omitempty"` // Only provided by Hedera } var dec Receipt if err := json.Unmarshal(input, &dec); err != nil { @@ -185,6 +190,9 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { if dec.TransactionIndex != nil { r.TransactionIndex = uint(*dec.TransactionIndex) } + if dec.RevertReason != nil { + r.RevertReason = *dec.RevertReason + } return nil } @@ -225,6 +233,14 @@ func (r *Receipt) GetBlockHash() common.Hash { return r.BlockHash } +func (r *Receipt) GetRevertReason() *string { + if len(r.RevertReason) == 0 { + return nil + } + revertReason := string(r.RevertReason) + return &revertReason +} + type Confirmations int const ( diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index 460f6f6500..444804b382 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -14,7 +14,7 @@ BlockBackfillDepth = 10 # Default # BlockBackfillSkip enables skipping of very long backfills. BlockBackfillSkip = false # Default # ChainType is automatically detected from chain ID. Set this to force a certain chain type regardless of chain ID. -# Available types: `arbitrum`, `celo`, `gnosis`, `kroma`, `metis`, `optimismBedrock`, `scroll`, `wemix`, `xlayer`, `zksync` +# Available types: `arbitrum`, `celo`, `gnosis`, `hedera`, `kroma`, `metis`, `optimismBedrock`, `scroll`, `wemix`, `xlayer`, `zksync` ChainType = 'arbitrum' # Example # FinalityDepth is the number of blocks after which an ethereum transaction is considered "final". Note that the default is automatically set based on chain ID, so it should not be necessary to change this under normal operation. # BlocksConsideredFinal determines how deeply we look back to ensure that transactions are confirmed onto the longest chain diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 256ef9e940..9b40e4dfce 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -1302,7 +1302,7 @@ func TestConfig_Validate(t *testing.T) { - 1: 10 errors: - ChainType: invalid value (Foo): must not be set with this chain id - Nodes: missing: must have at least one node - - ChainType: invalid value (Foo): must be one of arbitrum, celo, gnosis, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync, hedera or omitted + - ChainType: invalid value (Foo): must be one of arbitrum, celo, gnosis, hedera, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync or omitted - HeadTracker.HistoryDepth: invalid value (30): must be greater than or equal to FinalizedBlockOffset - GasEstimator.BumpThreshold: invalid value (0): cannot be 0 if auto-purge feature is enabled for Foo - Transactions.AutoPurge.Threshold: missing: needs to be set if auto-purge feature is enabled for Foo @@ -1315,7 +1315,7 @@ func TestConfig_Validate(t *testing.T) { - 2: 5 errors: - ChainType: invalid value (Arbitrum): only "optimismBedrock" can be used with this chain id - Nodes: missing: must have at least one node - - ChainType: invalid value (Arbitrum): must be one of arbitrum, celo, gnosis, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync, hedera or omitted + - ChainType: invalid value (Arbitrum): must be one of arbitrum, celo, gnosis, hedera, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync or omitted - FinalityDepth: invalid value (0): must be greater than or equal to 1 - MinIncomingConfirmations: invalid value (0): must be greater than or equal to 1 - 3.Nodes: 5 errors: diff --git a/core/services/ocr/contract_tracker.go b/core/services/ocr/contract_tracker.go index 9546c522a2..6651e4b65d 100644 --- a/core/services/ocr/contract_tracker.go +++ b/core/services/ocr/contract_tracker.go @@ -399,7 +399,7 @@ func (t *OCRContractTracker) LatestBlockHeight(ctx context.Context) (blockheight // care about the block height; we have no way of getting the L1 block // height anyway return 0, nil - case "", chaintype.ChainArbitrum, chaintype.ChainCelo, chaintype.ChainGnosis, chaintype.ChainKroma, chaintype.ChainOptimismBedrock, chaintype.ChainScroll, chaintype.ChainWeMix, chaintype.ChainXLayer, chaintype.ChainZkEvm, chaintype.ChainZkSync, chaintype.ChainHedera: + case "", chaintype.ChainArbitrum, chaintype.ChainCelo, chaintype.ChainGnosis, chaintype.ChainHedera, chaintype.ChainKroma, chaintype.ChainOptimismBedrock, chaintype.ChainScroll, chaintype.ChainWeMix, chaintype.ChainXLayer, chaintype.ChainZkEvm, chaintype.ChainZkSync: // continue } latestBlockHeight := t.getLatestBlockHeight() diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 0d670b3515..240ccf1bd4 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -7346,7 +7346,7 @@ BlockBackfillSkip enables skipping of very long backfills. ChainType = 'arbitrum' # Example ``` ChainType is automatically detected from chain ID. Set this to force a certain chain type regardless of chain ID. -Available types: `arbitrum`, `celo`, `gnosis`, `kroma`, `metis`, `optimismBedrock`, `scroll`, `wemix`, `xlayer`, `zksync` +Available types: `arbitrum`, `celo`, `gnosis`, `hedera`, `kroma`, `metis`, `optimismBedrock`, `scroll`, `wemix`, `xlayer`, `zksync` ### FinalityDepth ```toml From f9747546fdc64f10187fda170e398a6fc9f40803 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Thu, 1 Aug 2024 16:36:02 +0200 Subject: [PATCH 019/432] [TT-1394] add Reth to compatibility pipeline (#13804) * add support to compat pipeline for reth * npe protection, step condition streamlining * update compat pipeline * do not fetch latest images if base64 input is passed * use tagged CTF * check if Reth docker images are up to date * update compat pipeline with latest update images version * update pipeline reference --- .../workflows/client-compatibility-tests.yml | 45 ++++++++++++++++--- .../docker/test_env/test_env_builder.go | 1 + 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 8f0755c855..91ada8b7ab 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -14,10 +14,10 @@ on: required: false type: string evmImplementations: - description: comma separated list of EVM implementations to test (ignored if base64TestList is used) + description: comma separated list of EVM implementations to test (ignored if base64TestList is used); supports geth,besu,nethermind,erigon,reth required: true type: string - default: "geth,besu,nethermind,erigon" + default: "geth,besu,nethermind,erigon,reth" latestVersionsNumber: description: how many of latest images of EVM implementations to test with (ignored if base64TestList is used) required: true @@ -162,6 +162,12 @@ jobs: echo "New nethermind release found: $new_nethermind" implementations_arr+=("nethermind") fi + new_reth=$(ghlatestreleasechecker "paradigmxyz/reth" $RELEASED_DAYS_AGO) + if [ "new_reth" != "none" ]; then + echo "New reth release found: $new_reth" + implementations_arr+=("reth") + fi + IFS=',' eth_implementations="${implementations_arr[*]}" if [ -n "$eth_implementations" ]; then @@ -179,7 +185,7 @@ jobs: fi else echo "Will test all EVM implementations" - echo "evm_implementations=geth,besu,nethermind,erigon" >> $GITHUB_OUTPUT + echo "evm_implementations=geth,besu,nethermind,erigon,reth" >> $GITHUB_OUTPUT fi - name: Select Chainlink version id: select-chainlink-version @@ -269,9 +275,11 @@ jobs: expression: '^[0-9]+\.[0-9]+\.[0-9]+$' - name: tofelb/ethereum-genesis-generator expression: '^[0-9]+\.[0-9]+\.[0-9]+(\-slots\-per\-epoch)?' + - name: ghcr.io/paradigmxyz/reth + expression: '^v[0-9]+\.[0-9]+\.[0-9]+$' steps: - name: Update internal ECR if the latest Ethereum client image does not exist - uses: smartcontractkit/chainlink-testing-framework/.github/actions/update-internal-mirrors@5eea86ee4f7742b4e944561a570a6b268e712d9e # v1.30.3 + uses: smartcontractkit/chainlink-testing-framework/.github/actions/update-internal-mirrors@352cf299b529a33208146d9f7f0e0b5534fba6e7 # v1.33.0 with: aws_region: ${{ secrets.QA_AWS_REGION }} role_to_assume: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} @@ -279,6 +287,7 @@ jobs: image_name: ${{matrix.mirror.name}} expression: ${{matrix.mirror.expression}} page_size: ${{matrix.mirror.page_size}} + github_token: ${{ secrets.RETH_GH_TOKEN }} # needed only for checking GHRC.io repositories build-chainlink: if: | @@ -322,7 +331,7 @@ jobs: get-latest-available-images: name: Get Latest EVM Implementation's Images - if: always() && needs.should-run.outputs.should_run == 'true' && (needs.select-versions.outputs.evm_implementations != '' || github.event.inputs.base64TestList != '') + if: always() && needs.should-run.outputs.should_run == 'true' && needs.select-versions.outputs.evm_implementations != '' && github.event.inputs.base64TestList == '' environment: integration runs-on: ubuntu-latest needs: [check-ecr-images-exist, should-run, select-versions] @@ -336,6 +345,7 @@ jobs: nethermind_images: ${{ env.NETHERMIND_IMAGES }} besu_images: ${{ env.BESU_IMAGES }} erigon_images: ${{ env.ERIGON_IMAGES }} + reth_images: ${{ env.RETH_IMAGES }} steps: # Setup AWS creds - name: Configure AWS Credentials @@ -390,6 +400,12 @@ jobs: echo "ERIGON_IMAGES=$erigon_images" >> $GITHUB_ENV echo "Erigon latest images: $erigon_images" fi + + if [[ "$ETH_IMPLEMENTATIONS" == *"reth"* ]]; then + reth_images=$(ecrimagefetcher 'ghcr.io/paradigmxyz/reth' '^v[0-9]+\.[0-9]+\.[0-9]+$' ${{ env.LATEST_IMAGE_COUNT }}) + echo "RETH_IMAGES=$reth_images" >> $GITHUB_ENV + echo "Reth latest images: $reth_images" + fi # End Build Test Dependencies @@ -518,7 +534,24 @@ jobs: else echo "Will not test compatibility with nethermind" fi - + + if [[ "$ETH_IMPLEMENTATIONS" == *"reth"* ]]; then + echo "Will test compatibility with reth" + testlistgenerator -o compatibility_test_list.json -p cron -r TestCronBasic -f './smoke/cron_test.go' -e reth -d "${{ needs.get-latest-available-images.outputs.reth_images }}" -t "evm-implementation-compatibility-test" -n "ubuntu-latest" + testlistgenerator -o compatibility_test_list.json -p flux -r TestFluxBasic -f './smoke/flux_test.go' -e reth -d "${{ needs.get-latest-available-images.outputs.reth_images }}" -t "evm-implementation-compatibility-test" -n "ubuntu-latest" + testlistgenerator -o compatibility_test_list.json -p runlog -r TestRunLogBasic -f './smoke/runlog_test.go' -e reth -d "${{ needs.get-latest-available-images.outputs.reth_images }}" -t "evm-implementation-compatibility-test" -n "ubuntu-latest" + testlistgenerator -o compatibility_test_list.json -p log_poller -r TestLogPollerFewFiltersFixedDepth -f './smoke/log_poller_test.go' -e reth -d "${{ needs.get-latest-available-images.outputs.reth_images }}" -t "evm-implementation-compatibility-test" -n "ubuntu-latest" + testlistgenerator -o compatibility_test_list.json -p ocr -r TestOCRBasic -f './smoke/ocr_test.go' -e reth -d "${{ needs.get-latest-available-images.outputs.reth_images }}" -t "evm-implementation-compatibility-test" -n "ubuntu-latest" + testlistgenerator -o compatibility_test_list.json -p ocr2 -r '^TestOCRv2Basic/plugins$' -f './smoke/ocr2_test.go' -e reth -d "${{ needs.get-latest-available-images.outputs.reth_images }}" -t "evm-implementation-compatibility-test" -n "ubuntu-latest" + testlistgenerator -o compatibility_test_list.json -p automation -r 'TestAutomationBasic/registry_2_1_logtrigger' -f './smoke/automation_test.go' -e reth -d "${{ needs.get-latest-available-images.outputs.reth_images }}" -t "evm-implementation-compatibility-test" -n "ubuntu-latest" + testlistgenerator -o compatibility_test_list.json -p keeper -r 'TestKeeperBasicSmoke/registry_1_3' -f './smoke/keeper_test.go' -e reth -d "${{ needs.get-latest-available-images.outputs.reth_images }}" -t "evm-implementation-compatibility-test" -n "ubuntu-latest" + testlistgenerator -o compatibility_test_list.json -p vrf -r '^TestVRFBasic/Request_Randomness$' -f './smoke/vrf_test.go' -e reth -d "${{ needs.get-latest-available-images.outputs.reth_images }}" -t "evm-implementation-compatibility-test" -n "ubuntu-latest" + testlistgenerator -o compatibility_test_list.json -p vrfv2 -r '^TestVRFv2Basic/Request_Randomness$' -f './smoke/vrfv2_test.go' -e reth -d "${{ needs.get-latest-available-images.outputs.reth_images }}" -t "evm-implementation-compatibility-test" -n "ubuntu-latest" + testlistgenerator -o compatibility_test_list.json -p vrfv2plus -r '^TestVRFv2Plus$/^Link_Billing$' -f './smoke/vrfv2plus_test.go' -e reth -d "${{ needs.get-latest-available-images.outputs.reth_images }}" -t "evm-implementation-compatibility-test" -n "ubuntu-latest" + else + echo "Will not test compatibility with reth" + fi + jq . compatibility_test_list.json JOB_MATRIX_JSON=$(jq -c . compatibility_test_list.json) echo "JOB_MATRIX_JSON=${JOB_MATRIX_JSON}" >> $GITHUB_ENV diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go index 0b7c9de5ff..df399cbb46 100644 --- a/integration-tests/docker/test_env/test_env_builder.go +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -280,6 +280,7 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { // new logs can be added to the log stream, so parallel processing would get stuck on waiting for it to be unlocked LogScanningLoop: for i := 0; i < b.clNodesCount; i++ { + // if something went wrong during environment setup we might not have all nodes, and we don't want an NPE if b == nil || b.te == nil || b.te.ClCluster == nil || b.te.ClCluster.Nodes == nil || b.te.ClCluster.Nodes[i] == nil || len(b.te.ClCluster.Nodes)-1 < i { continue } From 1d12fbf5e9356615d0659e43f2046565211d27fb Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Thu, 1 Aug 2024 17:10:15 +0200 Subject: [PATCH 020/432] core: add -failing filter to health command (#13989) --- core/cmd/app.go | 4 ++ core/cmd/shell_remote.go | 6 ++- core/web/health_controller.go | 4 ++ core/web/health_controller_test.go | 12 ++++++ core/web/testdata/body/health-failing.html | 47 ++++++++++++++++++++++ core/web/testdata/body/health-failing.json | 1 + core/web/testdata/body/health-failing.txt | 2 + testdata/scripts/health/help.txtar | 3 +- testdata/scripts/health/multi-chain.txtar | 26 ++++++++++++ 9 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 core/web/testdata/body/health-failing.html create mode 100644 core/web/testdata/body/health-failing.json create mode 100644 core/web/testdata/body/health-failing.txt diff --git a/core/cmd/app.go b/core/cmd/app.go index 1ccb3da9a0..53c96980de 100644 --- a/core/cmd/app.go +++ b/core/cmd/app.go @@ -168,6 +168,10 @@ func NewApp(s *Shell) *cli.App { Usage: "Prints a health report", Action: s.Health, Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "failing, f", + Usage: "filter for failing services", + }, cli.BoolFlag{ Name: "json, j", Usage: "json output", diff --git a/core/cmd/shell_remote.go b/core/cmd/shell_remote.go index aab4a94da6..0aa3f3837d 100644 --- a/core/cmd/shell_remote.go +++ b/core/cmd/shell_remote.go @@ -517,7 +517,11 @@ func (s *Shell) Health(c *cli.Context) error { if c.Bool("json") { mime = gin.MIMEJSON } - resp, err := s.HTTP.Get(s.ctx(), "/health", map[string]string{"Accept": mime}) + u := "/health" + if c.Bool("failing") { + u += "?failing" + } + resp, err := s.HTTP.Get(s.ctx(), u, map[string]string{"Accept": mime}) if err != nil { return s.errorOut(err) } diff --git a/core/web/health_controller.go b/core/web/health_controller.go index bd775671d7..ee08c39fcf 100644 --- a/core/web/health_controller.go +++ b/core/web/health_controller.go @@ -69,6 +69,8 @@ func (hc *HealthController) Readyz(c *gin.Context) { } func (hc *HealthController) Health(c *gin.Context) { + _, failing := c.GetQuery("failing") + status := http.StatusOK checker := hc.App.GetHealthChecker() @@ -89,6 +91,8 @@ func (hc *HealthController) Health(c *gin.Context) { if err != nil { status = HealthStatusFailing output = err.Error() + } else if failing { + continue // omit from returned data } checks = append(checks, presenters.Check{ diff --git a/core/web/health_controller_test.go b/core/web/health_controller_test.go index 21da1fb2e4..14367b1e4b 100644 --- a/core/web/health_controller_test.go +++ b/core/web/health_controller_test.go @@ -97,6 +97,12 @@ var ( bodyHTML string //go:embed testdata/body/health.txt bodyTXT string + //go:embed testdata/body/health-failing.json + bodyJSONFailing string + //go:embed testdata/body/health-failing.html + bodyHTMLFailing string + //go:embed testdata/body/health-failing.txt + bodyTXTFailing string ) func TestHealthController_Health_body(t *testing.T) { @@ -111,6 +117,12 @@ func TestHealthController_Health_body(t *testing.T) { {"html", "/health", map[string]string{"Accept": gin.MIMEHTML}, bodyHTML}, {"text", "/health", map[string]string{"Accept": gin.MIMEPlain}, bodyTXT}, {".txt", "/health.txt", nil, bodyTXT}, + + {"default-failing", "/health?failing", nil, bodyJSONFailing}, + {"json-failing", "/health?failing", map[string]string{"Accept": gin.MIMEJSON}, bodyJSONFailing}, + {"html-failing", "/health?failing", map[string]string{"Accept": gin.MIMEHTML}, bodyHTMLFailing}, + {"text-failing", "/health?failing", map[string]string{"Accept": gin.MIMEPlain}, bodyTXTFailing}, + {".txt-failing", "/health.txt?failing", nil, bodyTXTFailing}, } { t.Run(tc.name, func(t *testing.T) { app := cltest.NewApplicationWithKey(t) diff --git a/core/web/testdata/body/health-failing.html b/core/web/testdata/body/health-failing.html new file mode 100644 index 0000000000..6b667a3ba6 --- /dev/null +++ b/core/web/testdata/body/health-failing.html @@ -0,0 +1,47 @@ + +

    + EVM +
    + 0 +
    + HeadTracker +
    + HeadListener +
    Listener is not connected
    +
    +
    +
    +
    diff --git a/core/web/testdata/body/health-failing.json b/core/web/testdata/body/health-failing.json new file mode 100644 index 0000000000..185b98b8da --- /dev/null +++ b/core/web/testdata/body/health-failing.json @@ -0,0 +1 @@ +{"data":[{"type":"checks","id":"EVM.0.HeadTracker.HeadListener","attributes":{"name":"EVM.0.HeadTracker.HeadListener","status":"failing","output":"Listener is not connected"}}]} diff --git a/core/web/testdata/body/health-failing.txt b/core/web/testdata/body/health-failing.txt new file mode 100644 index 0000000000..c6b948c3f9 --- /dev/null +++ b/core/web/testdata/body/health-failing.txt @@ -0,0 +1,2 @@ +! EVM.0.HeadTracker.HeadListener + Listener is not connected diff --git a/testdata/scripts/health/help.txtar b/testdata/scripts/health/help.txtar index 07eb0509e7..68176f05a4 100644 --- a/testdata/scripts/health/help.txtar +++ b/testdata/scripts/health/help.txtar @@ -9,5 +9,6 @@ USAGE: chainlink health [command options] [arguments...] OPTIONS: - --json, -j json output + --failing, -f filter for failing services + --json, -j json output diff --git a/testdata/scripts/health/multi-chain.txtar b/testdata/scripts/health/multi-chain.txtar index 8178f8e821..7e01493b30 100644 --- a/testdata/scripts/health/multi-chain.txtar +++ b/testdata/scripts/health/multi-chain.txtar @@ -15,6 +15,14 @@ cp stdout compact.json exec jq . compact.json cmp stdout out.json +exec chainlink --remote-node-url $NODEURL health -failing +cmp stdout out-unhealthy.txt + +exec chainlink --remote-node-url $NODEURL health -f -json +cp stdout compact.json +exec jq . compact.json +cmp stdout out-unhealthy.json + -- testdb.txt -- CL_DATABASE_URL -- testport.txt -- @@ -87,6 +95,10 @@ ok Solana.Bar ok StarkNet.Baz ok TelemetryManager +-- out-unhealthy.txt -- +! EVM.1.HeadTracker.HeadListener + Listener is not connected + -- out.json -- { "data": [ @@ -317,3 +329,17 @@ ok TelemetryManager } ] } +-- out-unhealthy.json -- +{ + "data": [ + { + "type": "checks", + "id": "EVM.1.HeadTracker.HeadListener", + "attributes": { + "name": "EVM.1.HeadTracker.HeadListener", + "status": "failing", + "output": "Listener is not connected" + } + } + ] +} From 3b4c2b58c3ebb04a2261108e758a3419de436a71 Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Thu, 1 Aug 2024 12:13:35 -0400 Subject: [PATCH 021/432] Bump version and update CHANGELOG fore core v2.15.0 (#13948) * Bump version and update CHANGELOG fore core v2.15.0 Signed-off-by: chainchad <96362174+chainchad@users.noreply.github.com> * Fix changelog version * Back out local only change * Remove dupe CL entry * Create init changeset for next release * Use changeset github changelog generator (cherry picked from commit 69cccdf2af8b322a45f66374aabcf03649ddc9d8) --------- Signed-off-by: chainchad <96362174+chainchad@users.noreply.github.com> --- .changeset/angry-wolves-fix.md | 5 -- .changeset/big-kiwis-cross.md | 5 ++ .changeset/bright-crabs-live.md | 7 --- .changeset/bright-readers-dress.md | 5 -- .changeset/cuddly-toys-warn.md | 14 ----- .changeset/curly-zebras-agree.md | 5 -- .changeset/dull-seals-jog.md | 5 -- .changeset/eighty-points-bathe.md | 5 -- .changeset/fluffy-ghosts-sneeze.md | 5 -- .changeset/fresh-badgers-pull.md | 5 -- .changeset/gold-candles-flow.md | 5 -- .changeset/good-paws-switch.md | 5 -- .changeset/healthy-lamps-argue.md | 5 -- .changeset/hungry-pandas-suffer.md | 5 -- .changeset/kind-garlics-smash.md | 5 -- .changeset/lucky-cameras-punch.md | 5 -- .changeset/mighty-nails-argue.md | 5 -- .changeset/neat-peas-reflect.md | 5 -- .changeset/neat-rockets-love.md | 5 -- .changeset/pink-papayas-swim.md | 5 -- .changeset/proud-zoos-sort.md | 5 -- .changeset/red-meals-mix.md | 5 -- .changeset/serious-apples-dance.md | 5 -- .changeset/shiny-ligers-compete.md | 5 -- .changeset/silent-cups-flow.md | 5 -- .changeset/silver-peas-happen.md | 5 -- .changeset/slow-trees-pay.md | 5 -- .changeset/soft-maps-ring.md | 5 -- .changeset/sour-guests-exercise.md | 5 -- .changeset/tall-emus-fail.md | 5 -- .changeset/tricky-seas-invite.md | 5 -- .changeset/twenty-rings-kneel.md | 5 -- .changeset/unlucky-lemons-learn.md | 5 -- .changeset/wet-wasps-hide.md | 5 -- CHANGELOG.md | 83 ++++++++++++++++++++++++++++++ package.json | 2 +- 36 files changed, 89 insertions(+), 177 deletions(-) delete mode 100644 .changeset/angry-wolves-fix.md create mode 100644 .changeset/big-kiwis-cross.md delete mode 100644 .changeset/bright-crabs-live.md delete mode 100644 .changeset/bright-readers-dress.md delete mode 100644 .changeset/cuddly-toys-warn.md delete mode 100644 .changeset/curly-zebras-agree.md delete mode 100644 .changeset/dull-seals-jog.md delete mode 100644 .changeset/eighty-points-bathe.md delete mode 100644 .changeset/fluffy-ghosts-sneeze.md delete mode 100644 .changeset/fresh-badgers-pull.md delete mode 100644 .changeset/gold-candles-flow.md delete mode 100644 .changeset/good-paws-switch.md delete mode 100644 .changeset/healthy-lamps-argue.md delete mode 100644 .changeset/hungry-pandas-suffer.md delete mode 100644 .changeset/kind-garlics-smash.md delete mode 100644 .changeset/lucky-cameras-punch.md delete mode 100644 .changeset/mighty-nails-argue.md delete mode 100644 .changeset/neat-peas-reflect.md delete mode 100644 .changeset/neat-rockets-love.md delete mode 100644 .changeset/pink-papayas-swim.md delete mode 100644 .changeset/proud-zoos-sort.md delete mode 100644 .changeset/red-meals-mix.md delete mode 100644 .changeset/serious-apples-dance.md delete mode 100644 .changeset/shiny-ligers-compete.md delete mode 100644 .changeset/silent-cups-flow.md delete mode 100644 .changeset/silver-peas-happen.md delete mode 100644 .changeset/slow-trees-pay.md delete mode 100644 .changeset/soft-maps-ring.md delete mode 100644 .changeset/sour-guests-exercise.md delete mode 100644 .changeset/tall-emus-fail.md delete mode 100644 .changeset/tricky-seas-invite.md delete mode 100644 .changeset/twenty-rings-kneel.md delete mode 100644 .changeset/unlucky-lemons-learn.md delete mode 100644 .changeset/wet-wasps-hide.md diff --git a/.changeset/angry-wolves-fix.md b/.changeset/angry-wolves-fix.md deleted file mode 100644 index 51fe7d7be8..0000000000 --- a/.changeset/angry-wolves-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -add chaos and reorg tests #added diff --git a/.changeset/big-kiwis-cross.md b/.changeset/big-kiwis-cross.md new file mode 100644 index 0000000000..3bc450c20e --- /dev/null +++ b/.changeset/big-kiwis-cross.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Initialize start of v2.16.0 release diff --git a/.changeset/bright-crabs-live.md b/.changeset/bright-crabs-live.md deleted file mode 100644 index 7e21431ee2..0000000000 --- a/.changeset/bright-crabs-live.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"chainlink": minor ---- - -Remove ocr2vrf - -#removed all ocr2vrf and dkg OCR2 plugin materials. \ No newline at end of file diff --git a/.changeset/bright-readers-dress.md b/.changeset/bright-readers-dress.md deleted file mode 100644 index ac26fbeb4e..0000000000 --- a/.changeset/bright-readers-dress.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal address security vulnerabilities around updating nodes and node operators on capabilities registry diff --git a/.changeset/cuddly-toys-warn.md b/.changeset/cuddly-toys-warn.md deleted file mode 100644 index 8e15ba6501..0000000000 --- a/.changeset/cuddly-toys-warn.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -"chainlink": patch ---- - -Add "VerboseLogging" option to mercury - -Off by default, can be enabled like so: - -```toml -[Mercury] -VerboseLogging = true -``` - -#updated diff --git a/.changeset/curly-zebras-agree.md b/.changeset/curly-zebras-agree.md deleted file mode 100644 index a57b379d2a..0000000000 --- a/.changeset/curly-zebras-agree.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#added support for EIP-1559 transactions for Scroll diff --git a/.changeset/dull-seals-jog.md b/.changeset/dull-seals-jog.md deleted file mode 100644 index 12dbb06d86..0000000000 --- a/.changeset/dull-seals-jog.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -remove tautological err check within evm txm. #internal diff --git a/.changeset/eighty-points-bathe.md b/.changeset/eighty-points-bathe.md deleted file mode 100644 index 914975c961..0000000000 --- a/.changeset/eighty-points-bathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#db_update add an empty BAL spec in migrations diff --git a/.changeset/fluffy-ghosts-sneeze.md b/.changeset/fluffy-ghosts-sneeze.md deleted file mode 100644 index 48503995c2..0000000000 --- a/.changeset/fluffy-ghosts-sneeze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Dequeue minimum guaranteed upkeeps as a priority #changed diff --git a/.changeset/fresh-badgers-pull.md b/.changeset/fresh-badgers-pull.md deleted file mode 100644 index 17255e767d..0000000000 --- a/.changeset/fresh-badgers-pull.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal change chain reader to use nil blocknumber when reading latest value diff --git a/.changeset/gold-candles-flow.md b/.changeset/gold-candles-flow.md deleted file mode 100644 index 277a96469e..0000000000 --- a/.changeset/gold-candles-flow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal Bumped dependencies for `chainlink-common`, `chainlink-solana`, and `chainlink-starknet`. diff --git a/.changeset/good-paws-switch.md b/.changeset/good-paws-switch.md deleted file mode 100644 index 76758a2c86..0000000000 --- a/.changeset/good-paws-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal add `NewChainWriter` method onto the dummy relayer. diff --git a/.changeset/healthy-lamps-argue.md b/.changeset/healthy-lamps-argue.md deleted file mode 100644 index 33357ddd6c..0000000000 --- a/.changeset/healthy-lamps-argue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Initialize registry syncer' contract reader lazily #keystone #internal diff --git a/.changeset/hungry-pandas-suffer.md b/.changeset/hungry-pandas-suffer.md deleted file mode 100644 index f8f151a7ce..0000000000 --- a/.changeset/hungry-pandas-suffer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Make send signatures configurable when Transmit in Contract Transmitter #internal diff --git a/.changeset/kind-garlics-smash.md b/.changeset/kind-garlics-smash.md deleted file mode 100644 index 3d9ededa23..0000000000 --- a/.changeset/kind-garlics-smash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Updated Functions ToS contract wrappers #internal diff --git a/.changeset/lucky-cameras-punch.md b/.changeset/lucky-cameras-punch.md deleted file mode 100644 index 73dbc1e7c7..0000000000 --- a/.changeset/lucky-cameras-punch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal end to end test for streams capabilities diff --git a/.changeset/mighty-nails-argue.md b/.changeset/mighty-nails-argue.md deleted file mode 100644 index 9456f44956..0000000000 --- a/.changeset/mighty-nails-argue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Change CR GetLatestValue to accept confidenceLevels that map to finality for contract read and event querying. Also remove Pending from BoundContract which used to map to finality for log events. diff --git a/.changeset/neat-peas-reflect.md b/.changeset/neat-peas-reflect.md deleted file mode 100644 index 2728e74668..0000000000 --- a/.changeset/neat-peas-reflect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal Updated wrappers for improved L1 -> L2 fee calculation for Functions diff --git a/.changeset/neat-rockets-love.md b/.changeset/neat-rockets-love.md deleted file mode 100644 index 29fdcebe6e..0000000000 --- a/.changeset/neat-rockets-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Added small check to allow for nil TxMeta in CW SubmitTransaction diff --git a/.changeset/pink-papayas-swim.md b/.changeset/pink-papayas-swim.md deleted file mode 100644 index 1e6a2cacd0..0000000000 --- a/.changeset/pink-papayas-swim.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Add BatchGetLatestValues to ChainReader diff --git a/.changeset/proud-zoos-sort.md b/.changeset/proud-zoos-sort.md deleted file mode 100644 index 571beae821..0000000000 --- a/.changeset/proud-zoos-sort.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -VRFV2Plus coordinator and wrapper split contracts between L1 and L2 chains #updated diff --git a/.changeset/red-meals-mix.md b/.changeset/red-meals-mix.md deleted file mode 100644 index a3667ed20e..0000000000 --- a/.changeset/red-meals-mix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Bump to start the next version diff --git a/.changeset/serious-apples-dance.md b/.changeset/serious-apples-dance.md deleted file mode 100644 index 37f8be7e6e..0000000000 --- a/.changeset/serious-apples-dance.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal Mercury v3: Include telemetry if bid/ask violation is detected diff --git a/.changeset/shiny-ligers-compete.md b/.changeset/shiny-ligers-compete.md deleted file mode 100644 index d621b94183..0000000000 --- a/.changeset/shiny-ligers-compete.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal logging of non determinism in target server diff --git a/.changeset/silent-cups-flow.md b/.changeset/silent-cups-flow.md deleted file mode 100644 index 564e02223f..0000000000 --- a/.changeset/silent-cups-flow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal refactor goose migrations to use provider diff --git a/.changeset/silver-peas-happen.md b/.changeset/silver-peas-happen.md deleted file mode 100644 index 2e7d062e26..0000000000 --- a/.changeset/silver-peas-happen.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal cleanup heavyweight test databases automatically diff --git a/.changeset/slow-trees-pay.md b/.changeset/slow-trees-pay.md deleted file mode 100644 index 73dca08308..0000000000 --- a/.changeset/slow-trees-pay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Protocol-level support for preventing bid/ask variant violations in mercury #added diff --git a/.changeset/soft-maps-ring.md b/.changeset/soft-maps-ring.md deleted file mode 100644 index 1beed3685b..0000000000 --- a/.changeset/soft-maps-ring.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#changed Rename the `InBackupHealthReport` to `StartUpHealthReport` and enable it for DB migrations as well. This will enable health report to be available during long start-up tasks (db backups and migrations). \ No newline at end of file diff --git a/.changeset/sour-guests-exercise.md b/.changeset/sour-guests-exercise.md deleted file mode 100644 index 6138a786d9..0000000000 --- a/.changeset/sour-guests-exercise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal additional logging to remote target capability diff --git a/.changeset/tall-emus-fail.md b/.changeset/tall-emus-fail.md deleted file mode 100644 index 98d5775cb1..0000000000 --- a/.changeset/tall-emus-fail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal Use txid as the idempotency key in the evm chainwriter diff --git a/.changeset/tricky-seas-invite.md b/.changeset/tricky-seas-invite.md deleted file mode 100644 index f109a2d8f9..0000000000 --- a/.changeset/tricky-seas-invite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Fix TestHeadTracker_CallsHeadTrackableCallbacks flaky test #internal diff --git a/.changeset/twenty-rings-kneel.md b/.changeset/twenty-rings-kneel.md deleted file mode 100644 index 160881c7fa..0000000000 --- a/.changeset/twenty-rings-kneel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#bugfix Set LatestFinalizedBlock for finalized blocks saved by logpoller diff --git a/.changeset/unlucky-lemons-learn.md b/.changeset/unlucky-lemons-learn.md deleted file mode 100644 index 3e33963995..0000000000 --- a/.changeset/unlucky-lemons-learn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Use the new log buffer in automation #changed diff --git a/.changeset/wet-wasps-hide.md b/.changeset/wet-wasps-hide.md deleted file mode 100644 index 2d6d6fd764..0000000000 --- a/.changeset/wet-wasps-hide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Fix TestIntegration_KeeperPluginLogUpkeep_ErrHandler flaky test #internal diff --git a/CHANGELOG.md b/CHANGELOG.md index d25c84b322..a521df865b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,88 @@ # Changelog Chainlink Core +## 2.15.0 + +### Minor Changes + +- [#13472](https://github.com/smartcontractkit/chainlink/pull/13472) [`685681e1b3`](https://github.com/smartcontractkit/chainlink/commit/685681e1b3b44ec9dadd4756ec6f0407ffda8afe) Thanks [@vreff](https://github.com/vreff)! - Remove ocr2vrf + + #removed all ocr2vrf and dkg OCR2 plugin materials. + +- [#13787](https://github.com/smartcontractkit/chainlink/pull/13787) [`e065b82d2b`](https://github.com/smartcontractkit/chainlink/commit/e065b82d2b8d565c046c2d96065ad1f593d9b488) Thanks [@cedric-cordenier](https://github.com/cedric-cordenier)! - Initialize registry syncer' contract reader lazily #keystone #internal + +- [#13514](https://github.com/smartcontractkit/chainlink/pull/13514) [`f84a3f2f27`](https://github.com/smartcontractkit/chainlink/commit/f84a3f2f276847d26c94bf67215e2a3600951c9c) Thanks [@ilija42](https://github.com/ilija42)! - #internal Change CR GetLatestValue to accept confidenceLevels that map to finality for contract read and event querying. Also remove Pending from BoundContract which used to map to finality for log events. + +- [#13805](https://github.com/smartcontractkit/chainlink/pull/13805) [`5daee38379`](https://github.com/smartcontractkit/chainlink/commit/5daee38379495cd858d8022339b5e9202e2ef0aa) Thanks [@silaslenihan](https://github.com/silaslenihan)! - #internal Added small check to allow for nil TxMeta in CW SubmitTransaction + +- [#13635](https://github.com/smartcontractkit/chainlink/pull/13635) [`055a9d24f8`](https://github.com/smartcontractkit/chainlink/commit/055a9d24f80a0a6cba8a44cab1a2832eef883761) Thanks [@ilija42](https://github.com/ilija42)! - #internal Add BatchGetLatestValues to ChainReader + +- [#13753](https://github.com/smartcontractkit/chainlink/pull/13753) [`8beda6093f`](https://github.com/smartcontractkit/chainlink/commit/8beda6093fe464a98b34ceb77bac6ba51add26b2) Thanks [@snehaagni](https://github.com/snehaagni)! - Bump to start the next version + +- [#13678](https://github.com/smartcontractkit/chainlink/pull/13678) [`4e3f5e8d4f`](https://github.com/smartcontractkit/chainlink/commit/4e3f5e8d4f022dcabce177ac52477820b85f04b1) Thanks [@krehermann](https://github.com/krehermann)! - #internal refactor goose migrations to use provider + +- [#13843](https://github.com/smartcontractkit/chainlink/pull/13843) [`31557117b2`](https://github.com/smartcontractkit/chainlink/commit/31557117b25f456b0dda38453098fa92dba55200) Thanks [@krehermann](https://github.com/krehermann)! - #internal cleanup heavyweight test databases automatically + +- [#13861](https://github.com/smartcontractkit/chainlink/pull/13861) [`b3c93a7f25`](https://github.com/smartcontractkit/chainlink/commit/b3c93a7f259a279060f555098efb4d683ab7e838) Thanks [@reductionista](https://github.com/reductionista)! - #bugfix Set LatestFinalizedBlock for finalized blocks saved by logpoller + +- [#13821](https://github.com/smartcontractkit/chainlink/pull/13821) [`5b668c186a`](https://github.com/smartcontractkit/chainlink/commit/5b668c186ac8ba294a97b20484352221f258bae2) Thanks [@ferglor](https://github.com/ferglor)! - Use the new log buffer in automation #changed + +### Patch Changes + +- [#13749](https://github.com/smartcontractkit/chainlink/pull/13749) [`e28f8a4386`](https://github.com/smartcontractkit/chainlink/commit/e28f8a4386fcd0baa09cf95e5f59e3312b592506) Thanks [@shileiwill](https://github.com/shileiwill)! - add chaos and reorg tests #added + +- [#13937](https://github.com/smartcontractkit/chainlink/pull/13937) [`27d9c71b19`](https://github.com/smartcontractkit/chainlink/commit/27d9c71b196961666de87bc3128d31f3c22fb3fa) Thanks [@cds95](https://github.com/cds95)! - #internal address security vulnerabilities around updating nodes and node operators on capabilities registry + +- [#13692](https://github.com/smartcontractkit/chainlink/pull/13692) [`5f3d58ba67`](https://github.com/smartcontractkit/chainlink/commit/5f3d58ba67a4e92832d2fa9fc2af487b697ee8ab) Thanks [@samsondav](https://github.com/samsondav)! - Add "VerboseLogging" option to mercury + + Off by default, can be enabled like so: + + ```toml + [Mercury] + VerboseLogging = true + ``` + + #updated + +- [#13687](https://github.com/smartcontractkit/chainlink/pull/13687) [`df0b06ee1c`](https://github.com/smartcontractkit/chainlink/commit/df0b06ee1ce28a8a7977bd3c9bdd8c9c307bef79) Thanks [@KodeyThomas](https://github.com/KodeyThomas)! - #added support for EIP-1559 transactions for Scroll + +- [#13857](https://github.com/smartcontractkit/chainlink/pull/13857) [`6bf25fc01c`](https://github.com/smartcontractkit/chainlink/commit/6bf25fc01c2e0c7de2ef9d79d511688c276368c1) Thanks [@Farber98](https://github.com/Farber98)! - remove tautological err check within evm txm. #internal + +- [#13839](https://github.com/smartcontractkit/chainlink/pull/13839) [`48b11ddff4`](https://github.com/smartcontractkit/chainlink/commit/48b11ddff47675c4c645764b0a25fd8a23b247ed) Thanks [@jinhoonbang](https://github.com/jinhoonbang)! - #db_update add an empty BAL spec in migrations + +- [#13653](https://github.com/smartcontractkit/chainlink/pull/13653) [`b1c9315776`](https://github.com/smartcontractkit/chainlink/commit/b1c9315776c906bd671c5be404b5cd0c5c34fdba) Thanks [@ferglor](https://github.com/ferglor)! - Dequeue minimum guaranteed upkeeps as a priority #changed + +- [#13906](https://github.com/smartcontractkit/chainlink/pull/13906) [`6adb82788a`](https://github.com/smartcontractkit/chainlink/commit/6adb82788a3b53514dd8b2c0742565e5bd175f9b) Thanks [@ettec](https://github.com/ettec)! - #internal change chain reader to use nil blocknumber when reading latest value + +- [#13793](https://github.com/smartcontractkit/chainlink/pull/13793) [`741351107b`](https://github.com/smartcontractkit/chainlink/commit/741351107b11966f0af8246a76ac7b5bd6a20556) Thanks [@nickcorin](https://github.com/nickcorin)! - #internal Bumped dependencies for `chainlink-common`, `chainlink-solana`, and `chainlink-starknet`. + +- [#13789](https://github.com/smartcontractkit/chainlink/pull/13789) [`e140a2bc1c`](https://github.com/smartcontractkit/chainlink/commit/e140a2bc1c90fa2522109c9da021c3085ed9268d) Thanks [@nickcorin](https://github.com/nickcorin)! - #internal add `NewChainWriter` method onto the dummy relayer. + +- [#13761](https://github.com/smartcontractkit/chainlink/pull/13761) [`89196f1fb8`](https://github.com/smartcontractkit/chainlink/commit/89196f1fb8306c90d4e45281130c894bb12328f7) Thanks [@agusaldasoro](https://github.com/agusaldasoro)! - Make send signatures configurable when Transmit in Contract Transmitter #internal + +- [#13795](https://github.com/smartcontractkit/chainlink/pull/13795) [`683a12e85e`](https://github.com/smartcontractkit/chainlink/commit/683a12e85e91628f240fe24f32b982b53ac30bd9) Thanks [@KuphJr](https://github.com/KuphJr)! - Updated Functions ToS contract wrappers #internal + +- [#13838](https://github.com/smartcontractkit/chainlink/pull/13838) [`d6ebada1b6`](https://github.com/smartcontractkit/chainlink/commit/d6ebada1b6572820a98255b8762cf60810db3210) Thanks [@ettec](https://github.com/ettec)! - #internal end to end test for streams capabilities + +- [#13815](https://github.com/smartcontractkit/chainlink/pull/13815) [`fb177f4ee7`](https://github.com/smartcontractkit/chainlink/commit/fb177f4ee77898dd12e20499e421a4d591fb92ef) Thanks [@KuphJr](https://github.com/KuphJr)! - #internal Updated wrappers for improved L1 -> L2 fee calculation for Functions + +- [#13335](https://github.com/smartcontractkit/chainlink/pull/13335) [`697e469e41`](https://github.com/smartcontractkit/chainlink/commit/697e469e41e640c8c71214461426174340527b4b) Thanks [@ibrajer](https://github.com/ibrajer)! - VRFV2Plus coordinator and wrapper split contracts between L1 and L2 chains #updated + +- [#13785](https://github.com/smartcontractkit/chainlink/pull/13785) [`873abacbc6`](https://github.com/smartcontractkit/chainlink/commit/873abacbc6ce1391fec245045c9436b92d3749f4) Thanks [@martin-cll](https://github.com/martin-cll)! - #internal Mercury v3: Include telemetry if bid/ask violation is detected + +- [#13877](https://github.com/smartcontractkit/chainlink/pull/13877) [`81a21bb56c`](https://github.com/smartcontractkit/chainlink/commit/81a21bb56cd597858221f775c796994be0f2e0da) Thanks [@ettec](https://github.com/ettec)! - #internal logging of non determinism in target server + +- [#13868](https://github.com/smartcontractkit/chainlink/pull/13868) [`00ef51a7c1`](https://github.com/smartcontractkit/chainlink/commit/00ef51a7c11fd227b73e3533f59950aa78b82162) Thanks [@samsondav](https://github.com/samsondav)! - Protocol-level support for preventing bid/ask variant violations in mercury #added + +- [#13120](https://github.com/smartcontractkit/chainlink/pull/13120) [`68a6a66919`](https://github.com/smartcontractkit/chainlink/commit/68a6a6691906aec5807f6c8dae12f9da621304ee) Thanks [@george-dorin](https://github.com/george-dorin)! - #changed Rename the `InBackupHealthReport` to `StartUpHealthReport` and enable it for DB migrations as well. This will enable health report to be available during long start-up tasks (db backups and migrations). + +- [#13852](https://github.com/smartcontractkit/chainlink/pull/13852) [`ced300beeb`](https://github.com/smartcontractkit/chainlink/commit/ced300beebbd1971e11e83a558bb9b1efe0290d9) Thanks [@ettec](https://github.com/ettec)! - #internal additional logging to remote target capability + +- [#13829](https://github.com/smartcontractkit/chainlink/pull/13829) [`51225f83f3`](https://github.com/smartcontractkit/chainlink/commit/51225f83f30a87606c3c7af56618cd16393c345e) Thanks [@nickcorin](https://github.com/nickcorin)! - #internal Use txid as the idempotency key in the evm chainwriter + +- [#13712](https://github.com/smartcontractkit/chainlink/pull/13712) [`535d2795c6`](https://github.com/smartcontractkit/chainlink/commit/535d2795c6e9b66315fe066c7dbaf91977d3e913) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - Fix TestHeadTracker_CallsHeadTrackableCallbacks flaky test #internal + +- [#13713](https://github.com/smartcontractkit/chainlink/pull/13713) [`6d2b5faf10`](https://github.com/smartcontractkit/chainlink/commit/6d2b5faf10efb81a235ff3470bc205c929a6d35d) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - Fix TestIntegration_KeeperPluginLogUpkeep_ErrHandler flaky test #internal + ## 2.14.0 - 2024-07-29 ### Minor Changes diff --git a/package.json b/package.json index b60a4573d5..18171178bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chainlink", - "version": "2.14.0", + "version": "2.15.0", "description": "node of the decentralized oracle network, bridging on and off-chain computation", "main": "index.js", "scripts": { From 5eb95f1cbae7ee9f573690edfaf7bc72dbac0a28 Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:43:12 -0400 Subject: [PATCH 022/432] Remove old CRIB remnants (cleanup) (#13912) --- .../scripts/crib/lib/check-route53-records.js | 91 -- .github/scripts/crib/package.json | 20 - .github/scripts/crib/pnpm-lock.yaml | 1206 ----------------- .github/scripts/crib/pr-comment-crib-env.js | 145 -- .github/workflows/build.yml | 1 - .github/workflows/pr-labels.yml | 46 - 6 files changed, 1509 deletions(-) delete mode 100644 .github/scripts/crib/lib/check-route53-records.js delete mode 100644 .github/scripts/crib/package.json delete mode 100644 .github/scripts/crib/pnpm-lock.yaml delete mode 100755 .github/scripts/crib/pr-comment-crib-env.js delete mode 100644 .github/workflows/pr-labels.yml diff --git a/.github/scripts/crib/lib/check-route53-records.js b/.github/scripts/crib/lib/check-route53-records.js deleted file mode 100644 index f35762ec88..0000000000 --- a/.github/scripts/crib/lib/check-route53-records.js +++ /dev/null @@ -1,91 +0,0 @@ -import { setTimeout } from "node:timers/promises"; -import { - Route53Client, - ListResourceRecordSetsCommand, -} from "@aws-sdk/client-route-53"; - -// us-east-1 is the global region used by Route 53. -const route53Client = new Route53Client({ region: "us-east-1" }); - -async function paginateListResourceRecordSets(route53Client, params) { - let isTruncated = true; - let nextRecordName, nextRecordType; - let allRecordSets = []; - - while (isTruncated) { - const response = await route53Client.send( - new ListResourceRecordSetsCommand({ - ...params, - ...(nextRecordName && { StartRecordName: nextRecordName }), - ...(nextRecordType && { StartRecordType: nextRecordType }), - }) - ); - - allRecordSets = allRecordSets.concat(response.ResourceRecordSets); - isTruncated = response.IsTruncated; - if (isTruncated) { - nextRecordName = response.NextRecordName; - nextRecordType = response.NextRecordType; - } - } - - return allRecordSets; -} - -/** - * Check if Route 53 records exist for a given Route 53 zone. - * - * @param {string} hostedZoneId The ID of the hosted zone. - * @param {string[]} recordNames An array of record names to check. - * @param {number} maxRetries The maximum number of retries. - * @param {number} initialBackoffMs The initial backoff time in milliseconds. - * @returns {Promise} True if records exist, false otherwise. - */ -export async function route53RecordsExist( - hostedZoneId, - recordNames, - maxRetries = 8, - initialBackoffMs = 2000 -) { - let attempts = 0; - - // We try to gather all records within a specified time limit. - // We issue retries due to an indeterminate amount of time required - // for record propagation. - console.info("Checking DNS records in Route 53..."); - while (attempts < maxRetries) { - try { - const allRecordSets = await paginateListResourceRecordSets( - route53Client, - { - HostedZoneId: hostedZoneId, - MaxItems: "300", - } - ); - - const recordExists = recordNames.every((name) => - allRecordSets.some((r) => r.Name.includes(name)) - ); - - if (recordExists) { - console.info("All records found in Route 53."); - return true; - } - - // If any record is not found, throw an error to trigger a retry - throw new Error( - "One or more DNS records not found in Route 53, retrying..." - ); - } catch (error) { - console.error(`Attempt ${attempts + 1}:`, error.message); - if (attempts === maxRetries - 1) { - return false; // Return false after the last attempt - } - // Exponential backoff - await setTimeout(initialBackoffMs * 2 ** attempts); - attempts++; - } - } - // Should not reach here if retries are exhausted - return false; -} diff --git a/.github/scripts/crib/package.json b/.github/scripts/crib/package.json deleted file mode 100644 index b009d63f38..0000000000 --- a/.github/scripts/crib/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "crib", - "version": "1.0.0", - "description": "", - "main": "pr-comment-crib-env.js", - "type": "module", - "keywords": [], - "author": "", - "license": "MIT", - "engines": { - "node": ">=18", - "pnpm": ">=9" - }, - "dependencies": { - "@actions/core": "^1.10.1", - "@actions/github": "^6.0.0", - "@aws-sdk/client-route-53": "^3.525.0", - "@octokit/rest": "^20.0.2" - } -} diff --git a/.github/scripts/crib/pnpm-lock.yaml b/.github/scripts/crib/pnpm-lock.yaml deleted file mode 100644 index a65caf8355..0000000000 --- a/.github/scripts/crib/pnpm-lock.yaml +++ /dev/null @@ -1,1206 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@actions/core': - specifier: ^1.10.1 - version: 1.10.1 - '@actions/github': - specifier: ^6.0.0 - version: 6.0.0 - '@aws-sdk/client-route-53': - specifier: ^3.525.0 - version: 3.529.1 - '@octokit/rest': - specifier: ^20.0.2 - version: 20.0.2 - -packages: - - '@actions/core@1.10.1': - resolution: {integrity: sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==} - - '@actions/github@6.0.0': - resolution: {integrity: sha512-alScpSVnYmjNEXboZjarjukQEzgCRmjMv6Xj47fsdnqGS73bjJNDpiiXmp8jr0UZLdUB6d9jW63IcmddUP+l0g==} - - '@actions/http-client@2.2.1': - resolution: {integrity: sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw==} - - '@aws-crypto/crc32@3.0.0': - resolution: {integrity: sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==} - - '@aws-crypto/ie11-detection@3.0.0': - resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} - - '@aws-crypto/sha256-browser@3.0.0': - resolution: {integrity: sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==} - - '@aws-crypto/sha256-js@3.0.0': - resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} - - '@aws-crypto/supports-web-crypto@3.0.0': - resolution: {integrity: sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==} - - '@aws-crypto/util@3.0.0': - resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} - - '@aws-sdk/client-route-53@3.529.1': - resolution: {integrity: sha512-osra30V5ILwEBeE1DUZreY7HYWQGco+WcQ1qg1UDSh/C0Nyxlu+8bVpwB/bjaldmy5Fi9MRv8SQsMdiAJFNp+w==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/client-sso-oidc@3.529.1': - resolution: {integrity: sha512-bimxCWAvRnVcluWEQeadXvHyzWlBWsuGVligsaVZaGF0TLSn0eLpzpN9B1EhHzTf7m0Kh/wGtPSH1JxO6PpB+A==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@aws-sdk/credential-provider-node': ^3.529.1 - - '@aws-sdk/client-sso@3.529.1': - resolution: {integrity: sha512-KT1U/ZNjDhVv2ZgjzaeAn9VM7l667yeSguMrRYC8qk5h91/61MbjZypi6eOuKuVM+0fsQvzKScTQz0Lio0eYag==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/client-sts@3.529.1': - resolution: {integrity: sha512-Rvk2Sr3MACQTOtngUU+omlf4E17k47dRVXR7OFRD6Ow5iGgC9tkN2q/ExDPW/ktPOmM0lSgzWyQ6/PC/Zq3HUg==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@aws-sdk/credential-provider-node': ^3.529.1 - - '@aws-sdk/core@3.529.1': - resolution: {integrity: sha512-Sj42sYPfaL9PHvvciMICxhyrDZjqnnvFbPKDmQL5aFKyXy122qx7RdVqUOQERDmMQfvJh6+0W1zQlLnre89q4Q==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/credential-provider-env@3.523.0': - resolution: {integrity: sha512-Y6DWdH6/OuMDoNKVzZlNeBc6f1Yjk1lYMjANKpIhMbkRCvLJw/PYZKOZa8WpXbTYdgg9XLjKybnLIb3ww3uuzA==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/credential-provider-http@3.525.0': - resolution: {integrity: sha512-RNWQGuSBQZhl3iqklOslUEfQ4br1V3DCPboMpeqFtddUWJV3m2u2extFur9/4Uy+1EHVF120IwZUKtd8dF+ibw==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/credential-provider-ini@3.529.1': - resolution: {integrity: sha512-RjHsuTvHIwXG7a/3ERexemiD3c9riKMCZQzY2/b0Gg0ButEVbBcMfERtUzWmQ0V4ufe/PEZjP68MH1gupcoF9A==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/credential-provider-node@3.529.1': - resolution: {integrity: sha512-mvY7F3dMmk/0dZOCfl5sUI1bG0osureBjxhELGCF0KkJqhWI0hIzh8UnPkYytSg3vdc97CMv7pTcozxrdA3b0g==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/credential-provider-process@3.523.0': - resolution: {integrity: sha512-f0LP9KlFmMvPWdKeUKYlZ6FkQAECUeZMmISsv6NKtvPCI9e4O4cLTeR09telwDK8P0HrgcRuZfXM7E30m8re0Q==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/credential-provider-sso@3.529.1': - resolution: {integrity: sha512-KFMKkaoTGDgSJG+o9Ii7AglWG5JQeF6IFw9cXLMwDdIrp3KUmRcUIqe0cjOoCqeQEDGy0VHsimHmKKJ3894i/A==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/credential-provider-web-identity@3.529.1': - resolution: {integrity: sha512-AGuZDOKN+AttjwTjrF47WLqzeEut2YynyxjkXZhxZF/xn8i5Y51kUAUdXsXw1bgR25pAeXQIdhsrQlRa1Pm5kw==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/middleware-host-header@3.523.0': - resolution: {integrity: sha512-4g3q7Ta9sdD9TMUuohBAkbx/e3I/juTqfKi7TPgP+8jxcYX72MOsgemAMHuP6CX27eyj4dpvjH+w4SIVDiDSmg==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/middleware-logger@3.523.0': - resolution: {integrity: sha512-PeDNJNhfiaZx54LBaLTXzUaJ9LXFwDFFIksipjqjvxMafnoVcQwKbkoPUWLe5ytT4nnL1LogD3s55mERFUsnwg==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/middleware-recursion-detection@3.523.0': - resolution: {integrity: sha512-nZ3Vt7ehfSDYnrcg/aAfjjvpdE+61B3Zk68i6/hSUIegT3IH9H1vSW67NDKVp+50hcEfzWwM2HMPXxlzuyFyrw==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/middleware-sdk-route53@3.523.0': - resolution: {integrity: sha512-d+SKqDBM3XCVkF/crRWwJD1WuS4PBY/CaTGwIyND1Z3o3ZCMhyo4f2ni19U+7ZtEULW50ZGznhB2F4GJHqpDUg==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/middleware-user-agent@3.525.0': - resolution: {integrity: sha512-4al/6uO+t/QIYXK2OgqzDKQzzLAYJza1vWFS+S0lJ3jLNGyLB5BMU5KqWjDzevYZ4eCnz2Nn7z0FveUTNz8YdQ==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/region-config-resolver@3.525.0': - resolution: {integrity: sha512-8kFqXk6UyKgTMi7N7QlhA6qM4pGPWbiUXqEY2RgUWngtxqNFGeM9JTexZeuavQI+qLLe09VPShPNX71fEDcM6w==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/token-providers@3.529.1': - resolution: {integrity: sha512-NpgMjsfpqiugbxrYGXtta914N43Mx/H0niidqv8wKMTgWQEtsJvYtOni+kuLXB+LmpjaMFNlpadooFU/bK4buA==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/types@3.523.0': - resolution: {integrity: sha512-AqGIu4u+SxPiUuNBp2acCVcq80KDUFjxe6e3cMTvKWTzCbrVk1AXv0dAaJnCmdkWIha6zJDWxpIk/aL4EGhZ9A==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/util-endpoints@3.525.0': - resolution: {integrity: sha512-DIW7WWU5tIGkeeKX6NJUyrEIdWMiqjLQG3XBzaUj+ufIENwNjdAHhlD8l2vX7Yr3JZRT6yN/84wBCj7Tw1xd1g==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/util-locate-window@3.495.0': - resolution: {integrity: sha512-MfaPXT0kLX2tQaR90saBT9fWQq2DHqSSJRzW+MZWsmF+y5LGCOhO22ac/2o6TKSQm7h0HRc2GaADqYYYor62yg==} - engines: {node: '>=14.0.0'} - - '@aws-sdk/util-user-agent-browser@3.523.0': - resolution: {integrity: sha512-6ZRNdGHX6+HQFqTbIA5+i8RWzxFyxsZv8D3soRfpdyWIKkzhSz8IyRKXRciwKBJDaC7OX2jzGE90wxRQft27nA==} - - '@aws-sdk/util-user-agent-node@3.525.0': - resolution: {integrity: sha512-88Wjt4efyUSBGcyIuh1dvoMqY1k15jpJc5A/3yi67clBQEFsu9QCodQCQPqmRjV3VRcMtBOk+jeCTiUzTY5dRQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - aws-crt: '>=1.0.0' - peerDependenciesMeta: - aws-crt: - optional: true - - '@aws-sdk/util-utf8-browser@3.259.0': - resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} - - '@aws-sdk/xml-builder@3.523.0': - resolution: {integrity: sha512-wfvyVymj2TUw7SuDor9IuFcAzJZvWRBZotvY/wQJOlYa3UP3Oezzecy64N4FWfBJEsZdrTN+HOZFl+IzTWWnUA==} - engines: {node: '>=14.0.0'} - - '@fastify/busboy@2.1.1': - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} - engines: {node: '>=14'} - - '@octokit/auth-token@4.0.0': - resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==} - engines: {node: '>= 18'} - - '@octokit/core@5.1.0': - resolution: {integrity: sha512-BDa2VAMLSh3otEiaMJ/3Y36GU4qf6GI+VivQ/P41NC6GHcdxpKlqV0ikSZ5gdQsmS3ojXeRx5vasgNTinF0Q4g==} - engines: {node: '>= 18'} - - '@octokit/endpoint@9.0.4': - resolution: {integrity: sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==} - engines: {node: '>= 18'} - - '@octokit/graphql@7.0.2': - resolution: {integrity: sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==} - engines: {node: '>= 18'} - - '@octokit/openapi-types@20.0.0': - resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==} - - '@octokit/plugin-paginate-rest@9.2.1': - resolution: {integrity: sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==} - engines: {node: '>= 18'} - peerDependencies: - '@octokit/core': '5' - - '@octokit/plugin-request-log@4.0.1': - resolution: {integrity: sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==} - engines: {node: '>= 18'} - peerDependencies: - '@octokit/core': '5' - - '@octokit/plugin-rest-endpoint-methods@10.4.1': - resolution: {integrity: sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==} - engines: {node: '>= 18'} - peerDependencies: - '@octokit/core': '5' - - '@octokit/request-error@5.0.1': - resolution: {integrity: sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==} - engines: {node: '>= 18'} - - '@octokit/request@8.2.0': - resolution: {integrity: sha512-exPif6x5uwLqv1N1irkLG1zZNJkOtj8bZxuVHd71U5Ftuxf2wGNvAJyNBcPbPC+EBzwYEbBDdSFb8EPcjpYxPQ==} - engines: {node: '>= 18'} - - '@octokit/rest@20.0.2': - resolution: {integrity: sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==} - engines: {node: '>= 18'} - - '@octokit/types@12.6.0': - resolution: {integrity: sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==} - - '@smithy/abort-controller@2.1.4': - resolution: {integrity: sha512-66HO817oIZ2otLIqy06R5muapqZjkgF1jfU0wyNko8cuqZNu8nbS9ljlhcRYw/M/uWRJzB9ih81DLSHhYbBLlQ==} - engines: {node: '>=14.0.0'} - - '@smithy/config-resolver@2.1.5': - resolution: {integrity: sha512-LcBB5JQC3Tx2ZExIJzfvWaajhFIwHrUNQeqxhred2r5nnqrdly9uoCrvM1sxOOdghYuWWm2Kr8tBCDOmxsgeTA==} - engines: {node: '>=14.0.0'} - - '@smithy/core@1.3.8': - resolution: {integrity: sha512-6cFhQ9ChU7MxvOXJn6nuUSONacpNsGHWhfueROQuM/0vibDdZA9FWEdNbVkuVuc+BFI5BnaX3ltERUlpUirpIA==} - engines: {node: '>=14.0.0'} - - '@smithy/credential-provider-imds@2.2.6': - resolution: {integrity: sha512-+xQe4Pite0kdk9qn0Vyw5BRVh0iSlj+T4TEKRXr4E1wZKtVgIzGlkCrfICSjiPVFkPxk4jMpVboMYdEiiA88/w==} - engines: {node: '>=14.0.0'} - - '@smithy/eventstream-codec@2.1.4': - resolution: {integrity: sha512-UkiieTztP7adg8EuqZvB0Y4LewdleZCJU7Kgt9RDutMsRYqO32fMpWeQHeTHaIMosmzcRZUykMRrhwGJe9mP3A==} - - '@smithy/fetch-http-handler@2.4.5': - resolution: {integrity: sha512-FR1IMGdo0yRFs1tk71zRGSa1MznVLQOVNaPjyNtx6dOcy/u0ovEnXN5NVz6slw5KujFlg3N1w4+UbO8F3WyYUg==} - - '@smithy/hash-node@2.1.4': - resolution: {integrity: sha512-uvCcpDLXaTTL0X/9ezF8T8sS77UglTfZVQaUOBiCvR0QydeSyio3t0Hj3QooVdyFsKTubR8gCk/ubLk3vAyDng==} - engines: {node: '>=14.0.0'} - - '@smithy/invalid-dependency@2.1.4': - resolution: {integrity: sha512-QzlNBl6jt3nb9jNnE51wTegReVvUdozyMMrFEyb/rc6AzPID1O+qMJYjAAoNw098y0CZVfCpEnoK2+mfBOd8XA==} - - '@smithy/is-array-buffer@2.1.1': - resolution: {integrity: sha512-xozSQrcUinPpNPNPds4S7z/FakDTh1MZWtRP/2vQtYB/u3HYrX2UXuZs+VhaKBd6Vc7g2XPr2ZtwGBNDN6fNKQ==} - engines: {node: '>=14.0.0'} - - '@smithy/middleware-content-length@2.1.4': - resolution: {integrity: sha512-C6VRwfcr0w9qRFhDGCpWMVhlEIBFlmlPRP1aX9Cv9xDj9SUwlDrNvoV1oP1vjRYuLxCDgovBBynCwwcluS2wLw==} - engines: {node: '>=14.0.0'} - - '@smithy/middleware-endpoint@2.4.6': - resolution: {integrity: sha512-AsXtUXHPOAS0EGZUSFOsVJvc7p0KL29PGkLxLfycPOcFVLru/oinYB6yvyL73ZZPX2OB8sMYUMrj7eH2kI7V/w==} - engines: {node: '>=14.0.0'} - - '@smithy/middleware-retry@2.1.7': - resolution: {integrity: sha512-8fOP/cJN4oMv+5SRffZC8RkqfWxHqGgn/86JPINY/1DnTRegzf+G5GT9lmIdG1YasuSbU7LISfW9PXil3isPVw==} - engines: {node: '>=14.0.0'} - - '@smithy/middleware-serde@2.2.1': - resolution: {integrity: sha512-VAWRWqnNjgccebndpyK94om4ZTYzXLQxUmNCXYzM/3O9MTfQjTNBgtFtQwyIIez6z7LWcCsXmnKVIOE9mLqAHQ==} - engines: {node: '>=14.0.0'} - - '@smithy/middleware-stack@2.1.4': - resolution: {integrity: sha512-Qqs2ba8Ax1rGKOSGJS2JN23fhhox2WMdRuzx0NYHtXzhxbJOIMmz9uQY6Hf4PY8FPteBPp1+h0j5Fmr+oW12sg==} - engines: {node: '>=14.0.0'} - - '@smithy/node-config-provider@2.2.5': - resolution: {integrity: sha512-CxPf2CXhjO79IypHJLBATB66Dw6suvr1Yc2ccY39hpR6wdse3pZ3E8RF83SODiNH0Wjmkd0ze4OF8exugEixgA==} - engines: {node: '>=14.0.0'} - - '@smithy/node-http-handler@2.4.3': - resolution: {integrity: sha512-bD5zRdEl1u/4vAAMeQnGEUNbH1seISV2Z0Wnn7ltPRl/6B2zND1R9XzTfsOnH1R5jqghpochF/mma8u7uXz0qQ==} - engines: {node: '>=14.0.0'} - - '@smithy/property-provider@2.1.4': - resolution: {integrity: sha512-nWaY/MImj1BiXZ9WY65h45dcxOx8pl06KYoHxwojDxDL+Q9yLU1YnZpgv8zsHhEftlj9KhePENjQTlNowWVyug==} - engines: {node: '>=14.0.0'} - - '@smithy/protocol-http@3.2.2': - resolution: {integrity: sha512-xYBlllOQcOuLoxzhF2u8kRHhIFGQpDeTQj/dBSnw4kfI29WMKL5RnW1m9YjnJAJ49miuIvrkJR+gW5bCQ+Mchw==} - engines: {node: '>=14.0.0'} - - '@smithy/querystring-builder@2.1.4': - resolution: {integrity: sha512-LXSL0J/nRWvGT+jIj+Fip3j0J1ZmHkUyBFRzg/4SmPNCLeDrtVu7ptKOnTboPsFZu5BxmpYok3kJuQzzRdrhbw==} - engines: {node: '>=14.0.0'} - - '@smithy/querystring-parser@2.1.4': - resolution: {integrity: sha512-U2b8olKXgZAs0eRo7Op11jTNmmcC/sqYmsA7vN6A+jkGnDvJlEl7AetUegbBzU8q3D6WzC5rhR/joIy8tXPzIg==} - engines: {node: '>=14.0.0'} - - '@smithy/service-error-classification@2.1.4': - resolution: {integrity: sha512-JW2Hthy21evnvDmYYk1kItOmbp3X5XI5iqorXgFEunb6hQfSDZ7O1g0Clyxg7k/Pcr9pfLk5xDIR2To/IohlsQ==} - engines: {node: '>=14.0.0'} - - '@smithy/shared-ini-file-loader@2.3.5': - resolution: {integrity: sha512-oI99+hOvsM8oAJtxAGmoL/YCcGXtbP0fjPseYGaNmJ4X5xOFTer0KPk7AIH3AL6c5AlYErivEi1X/X78HgTVIw==} - engines: {node: '>=14.0.0'} - - '@smithy/signature-v4@2.1.4': - resolution: {integrity: sha512-gnu9gCn0qQ8IdhNjs6o3QVCXzUs33znSDYwVMWo3nX4dM6j7z9u6FC302ShYyVWfO4MkVMuGCCJ6nl3PcH7V1Q==} - engines: {node: '>=14.0.0'} - - '@smithy/smithy-client@2.4.5': - resolution: {integrity: sha512-igXOM4kPXPo6b5LZXTUqTnrGk20uVd8OXoybC3f89gczzGfziLK4yUNOmiHSdxY9OOMOnnhVe5MpTm01MpFqvA==} - engines: {node: '>=14.0.0'} - - '@smithy/types@2.11.0': - resolution: {integrity: sha512-AR0SXO7FuAskfNhyGfSTThpLRntDI5bOrU0xrpVYU0rZyjl3LBXInZFMTP/NNSd7IS6Ksdtar0QvnrPRIhVrLQ==} - engines: {node: '>=14.0.0'} - - '@smithy/url-parser@2.1.4': - resolution: {integrity: sha512-1hTy6UYRYqOZlHKH2/2NzdNQ4NNmW2Lp0sYYvztKy+dEQuLvZL9w88zCzFQqqFer3DMcscYOshImxkJTGdV+rg==} - - '@smithy/util-base64@2.2.1': - resolution: {integrity: sha512-troGfokrpoqv8TGgsb8p4vvM71vqor314514jyQ0i9Zae3qs0jUVbSMCIBB1tseVynXFRcZJAZ9hPQYlifLD5A==} - engines: {node: '>=14.0.0'} - - '@smithy/util-body-length-browser@2.1.1': - resolution: {integrity: sha512-ekOGBLvs1VS2d1zM2ER4JEeBWAvIOUKeaFch29UjjJsxmZ/f0L3K3x0dEETgh3Q9bkZNHgT+rkdl/J/VUqSRag==} - - '@smithy/util-body-length-node@2.2.2': - resolution: {integrity: sha512-U7DooaT1SfW7XHrOcxthYJnQ+WMaefRrFPxW5Qmypw38Ivv+TKvfVuVHA9V162h8BeW9rzOJwOunjgXd0DdB4w==} - engines: {node: '>=14.0.0'} - - '@smithy/util-buffer-from@2.1.1': - resolution: {integrity: sha512-clhNjbyfqIv9Md2Mg6FffGVrJxw7bgK7s3Iax36xnfVj6cg0fUG7I4RH0XgXJF8bxi+saY5HR21g2UPKSxVCXg==} - engines: {node: '>=14.0.0'} - - '@smithy/util-config-provider@2.2.1': - resolution: {integrity: sha512-50VL/tx9oYYcjJn/qKqNy7sCtpD0+s8XEBamIFo4mFFTclKMNp+rsnymD796uybjiIquB7VCB/DeafduL0y2kw==} - engines: {node: '>=14.0.0'} - - '@smithy/util-defaults-mode-browser@2.1.7': - resolution: {integrity: sha512-vvIpWsysEdY77R0Qzr6+LRW50ye7eii7AyHM0OJnTi0isHYiXo5M/7o4k8gjK/b1upQJdfjzSBoJVa2SWrI+2g==} - engines: {node: '>= 10.0.0'} - - '@smithy/util-defaults-mode-node@2.2.7': - resolution: {integrity: sha512-qzXkSDyU6Th+rNNcNkG4a7Ix7m5HlMOtSCPxTVKlkz7eVsqbSSPggegbFeQJ2MVELBB4wnzNPsVPJIrpIaJpXA==} - engines: {node: '>= 10.0.0'} - - '@smithy/util-endpoints@1.1.5': - resolution: {integrity: sha512-tgDpaUNsUtRvNiBulKU1VnpoXU1GINMfZZXunRhUXOTBEAufG1Wp79uDXLau2gg1RZ4dpAR6lXCkrmddihCGUg==} - engines: {node: '>= 14.0.0'} - - '@smithy/util-hex-encoding@2.1.1': - resolution: {integrity: sha512-3UNdP2pkYUUBGEXzQI9ODTDK+Tcu1BlCyDBaRHwyxhA+8xLP8agEKQq4MGmpjqb4VQAjq9TwlCQX0kP6XDKYLg==} - engines: {node: '>=14.0.0'} - - '@smithy/util-middleware@2.1.4': - resolution: {integrity: sha512-5yYNOgCN0DL0OplME0pthoUR/sCfipnROkbTO7m872o0GHCVNJj5xOFJ143rvHNA54+pIPMLum4z2DhPC2pVGA==} - engines: {node: '>=14.0.0'} - - '@smithy/util-retry@2.1.4': - resolution: {integrity: sha512-JRZwhA3fhkdenSEYIWatC8oLwt4Bdf2LhHbNQApqb7yFoIGMl4twcYI3BcJZ7YIBZrACA9jGveW6tuCd836XzQ==} - engines: {node: '>= 14.0.0'} - - '@smithy/util-stream@2.1.5': - resolution: {integrity: sha512-FqvBFeTgx+QC4+i8USHqU8Ifs9nYRpW/OBfksojtgkxPIQ2H7ypXDEbnQRAV7PwoNHWcSwPomLYi0svmQQG5ow==} - engines: {node: '>=14.0.0'} - - '@smithy/util-uri-escape@2.1.1': - resolution: {integrity: sha512-saVzI1h6iRBUVSqtnlOnc9ssU09ypo7n+shdQ8hBTZno/9rZ3AuRYvoHInV57VF7Qn7B+pFJG7qTzFiHxWlWBw==} - engines: {node: '>=14.0.0'} - - '@smithy/util-utf8@2.2.0': - resolution: {integrity: sha512-hBsKr5BqrDrKS8qy+YcV7/htmMGxriA1PREOf/8AGBhHIZnfilVv1Waf1OyKhSbFW15U/8+gcMUQ9/Kk5qwpHQ==} - engines: {node: '>=14.0.0'} - - '@smithy/util-waiter@2.1.4': - resolution: {integrity: sha512-AK17WaC0hx1wR9juAOsQkJ6DjDxBGEf5TrKhpXtNFEn+cVto9Li3MVsdpAO97AF7bhFXSyC8tJA3F4ThhqwCdg==} - engines: {node: '>=14.0.0'} - - before-after-hook@2.2.3: - resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} - - bowser@2.11.0: - resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} - - deprecation@2.3.1: - resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} - - fast-xml-parser@4.2.5: - resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} - hasBin: true - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - strnum@1.0.5: - resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} - - tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - - tunnel@0.0.6: - resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} - engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} - - undici@5.28.3: - resolution: {integrity: sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==} - engines: {node: '>=14.0'} - - universal-user-agent@6.0.1: - resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} - - uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - -snapshots: - - '@actions/core@1.10.1': - dependencies: - '@actions/http-client': 2.2.1 - uuid: 8.3.2 - - '@actions/github@6.0.0': - dependencies: - '@actions/http-client': 2.2.1 - '@octokit/core': 5.1.0 - '@octokit/plugin-paginate-rest': 9.2.1(@octokit/core@5.1.0) - '@octokit/plugin-rest-endpoint-methods': 10.4.1(@octokit/core@5.1.0) - - '@actions/http-client@2.2.1': - dependencies: - tunnel: 0.0.6 - undici: 5.28.3 - - '@aws-crypto/crc32@3.0.0': - dependencies: - '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.523.0 - tslib: 1.14.1 - - '@aws-crypto/ie11-detection@3.0.0': - dependencies: - tslib: 1.14.1 - - '@aws-crypto/sha256-browser@3.0.0': - dependencies: - '@aws-crypto/ie11-detection': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-crypto/supports-web-crypto': 3.0.0 - '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.523.0 - '@aws-sdk/util-locate-window': 3.495.0 - '@aws-sdk/util-utf8-browser': 3.259.0 - tslib: 1.14.1 - - '@aws-crypto/sha256-js@3.0.0': - dependencies: - '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.523.0 - tslib: 1.14.1 - - '@aws-crypto/supports-web-crypto@3.0.0': - dependencies: - tslib: 1.14.1 - - '@aws-crypto/util@3.0.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@aws-sdk/util-utf8-browser': 3.259.0 - tslib: 1.14.1 - - '@aws-sdk/client-route-53@3.529.1': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.529.1(@aws-sdk/credential-provider-node@3.529.1) - '@aws-sdk/core': 3.529.1 - '@aws-sdk/credential-provider-node': 3.529.1 - '@aws-sdk/middleware-host-header': 3.523.0 - '@aws-sdk/middleware-logger': 3.523.0 - '@aws-sdk/middleware-recursion-detection': 3.523.0 - '@aws-sdk/middleware-sdk-route53': 3.523.0 - '@aws-sdk/middleware-user-agent': 3.525.0 - '@aws-sdk/region-config-resolver': 3.525.0 - '@aws-sdk/types': 3.523.0 - '@aws-sdk/util-endpoints': 3.525.0 - '@aws-sdk/util-user-agent-browser': 3.523.0 - '@aws-sdk/util-user-agent-node': 3.525.0 - '@aws-sdk/xml-builder': 3.523.0 - '@smithy/config-resolver': 2.1.5 - '@smithy/core': 1.3.8 - '@smithy/fetch-http-handler': 2.4.5 - '@smithy/hash-node': 2.1.4 - '@smithy/invalid-dependency': 2.1.4 - '@smithy/middleware-content-length': 2.1.4 - '@smithy/middleware-endpoint': 2.4.6 - '@smithy/middleware-retry': 2.1.7 - '@smithy/middleware-serde': 2.2.1 - '@smithy/middleware-stack': 2.1.4 - '@smithy/node-config-provider': 2.2.5 - '@smithy/node-http-handler': 2.4.3 - '@smithy/protocol-http': 3.2.2 - '@smithy/smithy-client': 2.4.5 - '@smithy/types': 2.11.0 - '@smithy/url-parser': 2.1.4 - '@smithy/util-base64': 2.2.1 - '@smithy/util-body-length-browser': 2.1.1 - '@smithy/util-body-length-node': 2.2.2 - '@smithy/util-defaults-mode-browser': 2.1.7 - '@smithy/util-defaults-mode-node': 2.2.7 - '@smithy/util-endpoints': 1.1.5 - '@smithy/util-middleware': 2.1.4 - '@smithy/util-retry': 2.1.4 - '@smithy/util-utf8': 2.2.0 - '@smithy/util-waiter': 2.1.4 - tslib: 2.6.2 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/client-sso-oidc@3.529.1(@aws-sdk/credential-provider-node@3.529.1)': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.529.1(@aws-sdk/credential-provider-node@3.529.1) - '@aws-sdk/core': 3.529.1 - '@aws-sdk/credential-provider-node': 3.529.1 - '@aws-sdk/middleware-host-header': 3.523.0 - '@aws-sdk/middleware-logger': 3.523.0 - '@aws-sdk/middleware-recursion-detection': 3.523.0 - '@aws-sdk/middleware-user-agent': 3.525.0 - '@aws-sdk/region-config-resolver': 3.525.0 - '@aws-sdk/types': 3.523.0 - '@aws-sdk/util-endpoints': 3.525.0 - '@aws-sdk/util-user-agent-browser': 3.523.0 - '@aws-sdk/util-user-agent-node': 3.525.0 - '@smithy/config-resolver': 2.1.5 - '@smithy/core': 1.3.8 - '@smithy/fetch-http-handler': 2.4.5 - '@smithy/hash-node': 2.1.4 - '@smithy/invalid-dependency': 2.1.4 - '@smithy/middleware-content-length': 2.1.4 - '@smithy/middleware-endpoint': 2.4.6 - '@smithy/middleware-retry': 2.1.7 - '@smithy/middleware-serde': 2.2.1 - '@smithy/middleware-stack': 2.1.4 - '@smithy/node-config-provider': 2.2.5 - '@smithy/node-http-handler': 2.4.3 - '@smithy/protocol-http': 3.2.2 - '@smithy/smithy-client': 2.4.5 - '@smithy/types': 2.11.0 - '@smithy/url-parser': 2.1.4 - '@smithy/util-base64': 2.2.1 - '@smithy/util-body-length-browser': 2.1.1 - '@smithy/util-body-length-node': 2.2.2 - '@smithy/util-defaults-mode-browser': 2.1.7 - '@smithy/util-defaults-mode-node': 2.2.7 - '@smithy/util-endpoints': 1.1.5 - '@smithy/util-middleware': 2.1.4 - '@smithy/util-retry': 2.1.4 - '@smithy/util-utf8': 2.2.0 - tslib: 2.6.2 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/client-sso@3.529.1': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/core': 3.529.1 - '@aws-sdk/middleware-host-header': 3.523.0 - '@aws-sdk/middleware-logger': 3.523.0 - '@aws-sdk/middleware-recursion-detection': 3.523.0 - '@aws-sdk/middleware-user-agent': 3.525.0 - '@aws-sdk/region-config-resolver': 3.525.0 - '@aws-sdk/types': 3.523.0 - '@aws-sdk/util-endpoints': 3.525.0 - '@aws-sdk/util-user-agent-browser': 3.523.0 - '@aws-sdk/util-user-agent-node': 3.525.0 - '@smithy/config-resolver': 2.1.5 - '@smithy/core': 1.3.8 - '@smithy/fetch-http-handler': 2.4.5 - '@smithy/hash-node': 2.1.4 - '@smithy/invalid-dependency': 2.1.4 - '@smithy/middleware-content-length': 2.1.4 - '@smithy/middleware-endpoint': 2.4.6 - '@smithy/middleware-retry': 2.1.7 - '@smithy/middleware-serde': 2.2.1 - '@smithy/middleware-stack': 2.1.4 - '@smithy/node-config-provider': 2.2.5 - '@smithy/node-http-handler': 2.4.3 - '@smithy/protocol-http': 3.2.2 - '@smithy/smithy-client': 2.4.5 - '@smithy/types': 2.11.0 - '@smithy/url-parser': 2.1.4 - '@smithy/util-base64': 2.2.1 - '@smithy/util-body-length-browser': 2.1.1 - '@smithy/util-body-length-node': 2.2.2 - '@smithy/util-defaults-mode-browser': 2.1.7 - '@smithy/util-defaults-mode-node': 2.2.7 - '@smithy/util-endpoints': 1.1.5 - '@smithy/util-middleware': 2.1.4 - '@smithy/util-retry': 2.1.4 - '@smithy/util-utf8': 2.2.0 - tslib: 2.6.2 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/client-sts@3.529.1(@aws-sdk/credential-provider-node@3.529.1)': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/core': 3.529.1 - '@aws-sdk/credential-provider-node': 3.529.1 - '@aws-sdk/middleware-host-header': 3.523.0 - '@aws-sdk/middleware-logger': 3.523.0 - '@aws-sdk/middleware-recursion-detection': 3.523.0 - '@aws-sdk/middleware-user-agent': 3.525.0 - '@aws-sdk/region-config-resolver': 3.525.0 - '@aws-sdk/types': 3.523.0 - '@aws-sdk/util-endpoints': 3.525.0 - '@aws-sdk/util-user-agent-browser': 3.523.0 - '@aws-sdk/util-user-agent-node': 3.525.0 - '@smithy/config-resolver': 2.1.5 - '@smithy/core': 1.3.8 - '@smithy/fetch-http-handler': 2.4.5 - '@smithy/hash-node': 2.1.4 - '@smithy/invalid-dependency': 2.1.4 - '@smithy/middleware-content-length': 2.1.4 - '@smithy/middleware-endpoint': 2.4.6 - '@smithy/middleware-retry': 2.1.7 - '@smithy/middleware-serde': 2.2.1 - '@smithy/middleware-stack': 2.1.4 - '@smithy/node-config-provider': 2.2.5 - '@smithy/node-http-handler': 2.4.3 - '@smithy/protocol-http': 3.2.2 - '@smithy/smithy-client': 2.4.5 - '@smithy/types': 2.11.0 - '@smithy/url-parser': 2.1.4 - '@smithy/util-base64': 2.2.1 - '@smithy/util-body-length-browser': 2.1.1 - '@smithy/util-body-length-node': 2.2.2 - '@smithy/util-defaults-mode-browser': 2.1.7 - '@smithy/util-defaults-mode-node': 2.2.7 - '@smithy/util-endpoints': 1.1.5 - '@smithy/util-middleware': 2.1.4 - '@smithy/util-retry': 2.1.4 - '@smithy/util-utf8': 2.2.0 - tslib: 2.6.2 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/core@3.529.1': - dependencies: - '@smithy/core': 1.3.8 - '@smithy/protocol-http': 3.2.2 - '@smithy/signature-v4': 2.1.4 - '@smithy/smithy-client': 2.4.5 - '@smithy/types': 2.11.0 - fast-xml-parser: 4.2.5 - tslib: 2.6.2 - - '@aws-sdk/credential-provider-env@3.523.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@smithy/property-provider': 2.1.4 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@aws-sdk/credential-provider-http@3.525.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@smithy/fetch-http-handler': 2.4.5 - '@smithy/node-http-handler': 2.4.3 - '@smithy/property-provider': 2.1.4 - '@smithy/protocol-http': 3.2.2 - '@smithy/smithy-client': 2.4.5 - '@smithy/types': 2.11.0 - '@smithy/util-stream': 2.1.5 - tslib: 2.6.2 - - '@aws-sdk/credential-provider-ini@3.529.1(@aws-sdk/credential-provider-node@3.529.1)': - dependencies: - '@aws-sdk/client-sts': 3.529.1(@aws-sdk/credential-provider-node@3.529.1) - '@aws-sdk/credential-provider-env': 3.523.0 - '@aws-sdk/credential-provider-process': 3.523.0 - '@aws-sdk/credential-provider-sso': 3.529.1(@aws-sdk/credential-provider-node@3.529.1) - '@aws-sdk/credential-provider-web-identity': 3.529.1(@aws-sdk/credential-provider-node@3.529.1) - '@aws-sdk/types': 3.523.0 - '@smithy/credential-provider-imds': 2.2.6 - '@smithy/property-provider': 2.1.4 - '@smithy/shared-ini-file-loader': 2.3.5 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - transitivePeerDependencies: - - '@aws-sdk/credential-provider-node' - - aws-crt - - '@aws-sdk/credential-provider-node@3.529.1': - dependencies: - '@aws-sdk/credential-provider-env': 3.523.0 - '@aws-sdk/credential-provider-http': 3.525.0 - '@aws-sdk/credential-provider-ini': 3.529.1(@aws-sdk/credential-provider-node@3.529.1) - '@aws-sdk/credential-provider-process': 3.523.0 - '@aws-sdk/credential-provider-sso': 3.529.1(@aws-sdk/credential-provider-node@3.529.1) - '@aws-sdk/credential-provider-web-identity': 3.529.1(@aws-sdk/credential-provider-node@3.529.1) - '@aws-sdk/types': 3.523.0 - '@smithy/credential-provider-imds': 2.2.6 - '@smithy/property-provider': 2.1.4 - '@smithy/shared-ini-file-loader': 2.3.5 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/credential-provider-process@3.523.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@smithy/property-provider': 2.1.4 - '@smithy/shared-ini-file-loader': 2.3.5 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@aws-sdk/credential-provider-sso@3.529.1(@aws-sdk/credential-provider-node@3.529.1)': - dependencies: - '@aws-sdk/client-sso': 3.529.1 - '@aws-sdk/token-providers': 3.529.1(@aws-sdk/credential-provider-node@3.529.1) - '@aws-sdk/types': 3.523.0 - '@smithy/property-provider': 2.1.4 - '@smithy/shared-ini-file-loader': 2.3.5 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - transitivePeerDependencies: - - '@aws-sdk/credential-provider-node' - - aws-crt - - '@aws-sdk/credential-provider-web-identity@3.529.1(@aws-sdk/credential-provider-node@3.529.1)': - dependencies: - '@aws-sdk/client-sts': 3.529.1(@aws-sdk/credential-provider-node@3.529.1) - '@aws-sdk/types': 3.523.0 - '@smithy/property-provider': 2.1.4 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - transitivePeerDependencies: - - '@aws-sdk/credential-provider-node' - - aws-crt - - '@aws-sdk/middleware-host-header@3.523.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@smithy/protocol-http': 3.2.2 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@aws-sdk/middleware-logger@3.523.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@aws-sdk/middleware-recursion-detection@3.523.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@smithy/protocol-http': 3.2.2 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@aws-sdk/middleware-sdk-route53@3.523.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@aws-sdk/middleware-user-agent@3.525.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@aws-sdk/util-endpoints': 3.525.0 - '@smithy/protocol-http': 3.2.2 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@aws-sdk/region-config-resolver@3.525.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@smithy/node-config-provider': 2.2.5 - '@smithy/types': 2.11.0 - '@smithy/util-config-provider': 2.2.1 - '@smithy/util-middleware': 2.1.4 - tslib: 2.6.2 - - '@aws-sdk/token-providers@3.529.1(@aws-sdk/credential-provider-node@3.529.1)': - dependencies: - '@aws-sdk/client-sso-oidc': 3.529.1(@aws-sdk/credential-provider-node@3.529.1) - '@aws-sdk/types': 3.523.0 - '@smithy/property-provider': 2.1.4 - '@smithy/shared-ini-file-loader': 2.3.5 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - transitivePeerDependencies: - - '@aws-sdk/credential-provider-node' - - aws-crt - - '@aws-sdk/types@3.523.0': - dependencies: - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@aws-sdk/util-endpoints@3.525.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@smithy/types': 2.11.0 - '@smithy/util-endpoints': 1.1.5 - tslib: 2.6.2 - - '@aws-sdk/util-locate-window@3.495.0': - dependencies: - tslib: 2.6.2 - - '@aws-sdk/util-user-agent-browser@3.523.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@smithy/types': 2.11.0 - bowser: 2.11.0 - tslib: 2.6.2 - - '@aws-sdk/util-user-agent-node@3.525.0': - dependencies: - '@aws-sdk/types': 3.523.0 - '@smithy/node-config-provider': 2.2.5 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@aws-sdk/util-utf8-browser@3.259.0': - dependencies: - tslib: 2.6.2 - - '@aws-sdk/xml-builder@3.523.0': - dependencies: - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@fastify/busboy@2.1.1': {} - - '@octokit/auth-token@4.0.0': {} - - '@octokit/core@5.1.0': - dependencies: - '@octokit/auth-token': 4.0.0 - '@octokit/graphql': 7.0.2 - '@octokit/request': 8.2.0 - '@octokit/request-error': 5.0.1 - '@octokit/types': 12.6.0 - before-after-hook: 2.2.3 - universal-user-agent: 6.0.1 - - '@octokit/endpoint@9.0.4': - dependencies: - '@octokit/types': 12.6.0 - universal-user-agent: 6.0.1 - - '@octokit/graphql@7.0.2': - dependencies: - '@octokit/request': 8.2.0 - '@octokit/types': 12.6.0 - universal-user-agent: 6.0.1 - - '@octokit/openapi-types@20.0.0': {} - - '@octokit/plugin-paginate-rest@9.2.1(@octokit/core@5.1.0)': - dependencies: - '@octokit/core': 5.1.0 - '@octokit/types': 12.6.0 - - '@octokit/plugin-request-log@4.0.1(@octokit/core@5.1.0)': - dependencies: - '@octokit/core': 5.1.0 - - '@octokit/plugin-rest-endpoint-methods@10.4.1(@octokit/core@5.1.0)': - dependencies: - '@octokit/core': 5.1.0 - '@octokit/types': 12.6.0 - - '@octokit/request-error@5.0.1': - dependencies: - '@octokit/types': 12.6.0 - deprecation: 2.3.1 - once: 1.4.0 - - '@octokit/request@8.2.0': - dependencies: - '@octokit/endpoint': 9.0.4 - '@octokit/request-error': 5.0.1 - '@octokit/types': 12.6.0 - universal-user-agent: 6.0.1 - - '@octokit/rest@20.0.2': - dependencies: - '@octokit/core': 5.1.0 - '@octokit/plugin-paginate-rest': 9.2.1(@octokit/core@5.1.0) - '@octokit/plugin-request-log': 4.0.1(@octokit/core@5.1.0) - '@octokit/plugin-rest-endpoint-methods': 10.4.1(@octokit/core@5.1.0) - - '@octokit/types@12.6.0': - dependencies: - '@octokit/openapi-types': 20.0.0 - - '@smithy/abort-controller@2.1.4': - dependencies: - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/config-resolver@2.1.5': - dependencies: - '@smithy/node-config-provider': 2.2.5 - '@smithy/types': 2.11.0 - '@smithy/util-config-provider': 2.2.1 - '@smithy/util-middleware': 2.1.4 - tslib: 2.6.2 - - '@smithy/core@1.3.8': - dependencies: - '@smithy/middleware-endpoint': 2.4.6 - '@smithy/middleware-retry': 2.1.7 - '@smithy/middleware-serde': 2.2.1 - '@smithy/protocol-http': 3.2.2 - '@smithy/smithy-client': 2.4.5 - '@smithy/types': 2.11.0 - '@smithy/util-middleware': 2.1.4 - tslib: 2.6.2 - - '@smithy/credential-provider-imds@2.2.6': - dependencies: - '@smithy/node-config-provider': 2.2.5 - '@smithy/property-provider': 2.1.4 - '@smithy/types': 2.11.0 - '@smithy/url-parser': 2.1.4 - tslib: 2.6.2 - - '@smithy/eventstream-codec@2.1.4': - dependencies: - '@aws-crypto/crc32': 3.0.0 - '@smithy/types': 2.11.0 - '@smithy/util-hex-encoding': 2.1.1 - tslib: 2.6.2 - - '@smithy/fetch-http-handler@2.4.5': - dependencies: - '@smithy/protocol-http': 3.2.2 - '@smithy/querystring-builder': 2.1.4 - '@smithy/types': 2.11.0 - '@smithy/util-base64': 2.2.1 - tslib: 2.6.2 - - '@smithy/hash-node@2.1.4': - dependencies: - '@smithy/types': 2.11.0 - '@smithy/util-buffer-from': 2.1.1 - '@smithy/util-utf8': 2.2.0 - tslib: 2.6.2 - - '@smithy/invalid-dependency@2.1.4': - dependencies: - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/is-array-buffer@2.1.1': - dependencies: - tslib: 2.6.2 - - '@smithy/middleware-content-length@2.1.4': - dependencies: - '@smithy/protocol-http': 3.2.2 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/middleware-endpoint@2.4.6': - dependencies: - '@smithy/middleware-serde': 2.2.1 - '@smithy/node-config-provider': 2.2.5 - '@smithy/shared-ini-file-loader': 2.3.5 - '@smithy/types': 2.11.0 - '@smithy/url-parser': 2.1.4 - '@smithy/util-middleware': 2.1.4 - tslib: 2.6.2 - - '@smithy/middleware-retry@2.1.7': - dependencies: - '@smithy/node-config-provider': 2.2.5 - '@smithy/protocol-http': 3.2.2 - '@smithy/service-error-classification': 2.1.4 - '@smithy/smithy-client': 2.4.5 - '@smithy/types': 2.11.0 - '@smithy/util-middleware': 2.1.4 - '@smithy/util-retry': 2.1.4 - tslib: 2.6.2 - uuid: 8.3.2 - - '@smithy/middleware-serde@2.2.1': - dependencies: - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/middleware-stack@2.1.4': - dependencies: - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/node-config-provider@2.2.5': - dependencies: - '@smithy/property-provider': 2.1.4 - '@smithy/shared-ini-file-loader': 2.3.5 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/node-http-handler@2.4.3': - dependencies: - '@smithy/abort-controller': 2.1.4 - '@smithy/protocol-http': 3.2.2 - '@smithy/querystring-builder': 2.1.4 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/property-provider@2.1.4': - dependencies: - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/protocol-http@3.2.2': - dependencies: - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/querystring-builder@2.1.4': - dependencies: - '@smithy/types': 2.11.0 - '@smithy/util-uri-escape': 2.1.1 - tslib: 2.6.2 - - '@smithy/querystring-parser@2.1.4': - dependencies: - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/service-error-classification@2.1.4': - dependencies: - '@smithy/types': 2.11.0 - - '@smithy/shared-ini-file-loader@2.3.5': - dependencies: - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/signature-v4@2.1.4': - dependencies: - '@smithy/eventstream-codec': 2.1.4 - '@smithy/is-array-buffer': 2.1.1 - '@smithy/types': 2.11.0 - '@smithy/util-hex-encoding': 2.1.1 - '@smithy/util-middleware': 2.1.4 - '@smithy/util-uri-escape': 2.1.1 - '@smithy/util-utf8': 2.2.0 - tslib: 2.6.2 - - '@smithy/smithy-client@2.4.5': - dependencies: - '@smithy/middleware-endpoint': 2.4.6 - '@smithy/middleware-stack': 2.1.4 - '@smithy/protocol-http': 3.2.2 - '@smithy/types': 2.11.0 - '@smithy/util-stream': 2.1.5 - tslib: 2.6.2 - - '@smithy/types@2.11.0': - dependencies: - tslib: 2.6.2 - - '@smithy/url-parser@2.1.4': - dependencies: - '@smithy/querystring-parser': 2.1.4 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/util-base64@2.2.1': - dependencies: - '@smithy/util-buffer-from': 2.1.1 - '@smithy/util-utf8': 2.2.0 - tslib: 2.6.2 - - '@smithy/util-body-length-browser@2.1.1': - dependencies: - tslib: 2.6.2 - - '@smithy/util-body-length-node@2.2.2': - dependencies: - tslib: 2.6.2 - - '@smithy/util-buffer-from@2.1.1': - dependencies: - '@smithy/is-array-buffer': 2.1.1 - tslib: 2.6.2 - - '@smithy/util-config-provider@2.2.1': - dependencies: - tslib: 2.6.2 - - '@smithy/util-defaults-mode-browser@2.1.7': - dependencies: - '@smithy/property-provider': 2.1.4 - '@smithy/smithy-client': 2.4.5 - '@smithy/types': 2.11.0 - bowser: 2.11.0 - tslib: 2.6.2 - - '@smithy/util-defaults-mode-node@2.2.7': - dependencies: - '@smithy/config-resolver': 2.1.5 - '@smithy/credential-provider-imds': 2.2.6 - '@smithy/node-config-provider': 2.2.5 - '@smithy/property-provider': 2.1.4 - '@smithy/smithy-client': 2.4.5 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/util-endpoints@1.1.5': - dependencies: - '@smithy/node-config-provider': 2.2.5 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/util-hex-encoding@2.1.1': - dependencies: - tslib: 2.6.2 - - '@smithy/util-middleware@2.1.4': - dependencies: - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/util-retry@2.1.4': - dependencies: - '@smithy/service-error-classification': 2.1.4 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - '@smithy/util-stream@2.1.5': - dependencies: - '@smithy/fetch-http-handler': 2.4.5 - '@smithy/node-http-handler': 2.4.3 - '@smithy/types': 2.11.0 - '@smithy/util-base64': 2.2.1 - '@smithy/util-buffer-from': 2.1.1 - '@smithy/util-hex-encoding': 2.1.1 - '@smithy/util-utf8': 2.2.0 - tslib: 2.6.2 - - '@smithy/util-uri-escape@2.1.1': - dependencies: - tslib: 2.6.2 - - '@smithy/util-utf8@2.2.0': - dependencies: - '@smithy/util-buffer-from': 2.1.1 - tslib: 2.6.2 - - '@smithy/util-waiter@2.1.4': - dependencies: - '@smithy/abort-controller': 2.1.4 - '@smithy/types': 2.11.0 - tslib: 2.6.2 - - before-after-hook@2.2.3: {} - - bowser@2.11.0: {} - - deprecation@2.3.1: {} - - fast-xml-parser@4.2.5: - dependencies: - strnum: 1.0.5 - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - strnum@1.0.5: {} - - tslib@1.14.1: {} - - tslib@2.6.2: {} - - tunnel@0.0.6: {} - - undici@5.28.3: - dependencies: - '@fastify/busboy': 2.1.1 - - universal-user-agent@6.0.1: {} - - uuid@8.3.2: {} - - wrappy@1.0.2: {} diff --git a/.github/scripts/crib/pr-comment-crib-env.js b/.github/scripts/crib/pr-comment-crib-env.js deleted file mode 100755 index cc36a9deb7..0000000000 --- a/.github/scripts/crib/pr-comment-crib-env.js +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env node - -import * as core from "@actions/core"; -import * as github from "@actions/github"; -import { route53RecordsExist } from "./lib/check-route53-records.js"; - -function generateSubdomains(subdomainPrefix, prNumber) { - const subDomainSuffixes = [ - "node1", - "node2", - "node3", - "node4", - "node5", - "geth-1337-http", - "geth-1337-ws", - "geth-2337-http", - "geth-2337-ws", - "mockserver", - ]; - return subDomainSuffixes.map( - (suffix) => `${subdomainPrefix}-${prNumber}-${suffix}` - ); -} - -async function commentExists(octokit, owner, repo, prNumber, uniqueIdentifier) { - // This will automatically paginate through all comments - const comments = await octokit.paginate(octokit.rest.issues.listComments, { - owner, - repo, - issue_number: prNumber, - }); - - // Check each comment for the unique identifier - return comments.some((comment) => comment.body.includes(uniqueIdentifier)); -} - -async function run() { - try { - const token = process.env.GITHUB_TOKEN; - const route53ZoneId = process.env.ROUTE53_ZONE_ID; - const subdomainPrefix = process.env.SUBDOMAIN_PREFIX || "crib-chainlink"; - - // Check for the existence of GITHUB_TOKEN and ROUTE53_ZONE_ID - if (!token || !route53ZoneId) { - core.setFailed( - "Error: Missing required environment variables: GITHUB_TOKEN or ROUTE53_ZONE_ID." - ); - return; - } - - const octokit = github.getOctokit(token); - const context = github.context; - - const labelsToCheck = ["crib"]; - const { owner, repo } = context.repo; - const prNumber = context.issue.number; - - if (!prNumber) { - core.setFailed("Error: Could not get PR number from context"); - return; - } - - // List labels on the PR - const { data: labels } = await octokit.rest.issues.listLabelsOnIssue({ - owner, - repo, - issue_number: prNumber, - }); - - // Check if any label matches the labelsToCheck - const labelMatches = labels.some((label) => - labelsToCheck.includes(label.name) - ); - - if (!labelMatches) { - core.info("No 'crib' PR label found. Proceeding."); - return; - } - - const subdomains = generateSubdomains(subdomainPrefix, prNumber); - core.debug("Subdomains:", subdomains); - - // Comment header and unique identifier - const commentHeader = "## CRIB Environment Details"; - - // Check if the comment already exists - if (await commentExists(octokit, owner, repo, prNumber, commentHeader)) { - core.info("CRIB environment comment already exists. Skipping."); - return; - } - - // Check if DNS records exist in Route 53 before printing out the subdomains. - try { - const maxRetries = 8; - const recordsExist = await route53RecordsExist( - route53ZoneId, - subdomains, - maxRetries - ); - if (recordsExist) { - core.info("Route 53 DNS records exist."); - } else { - core.setFailed( - "Route 53 DNS records do not exist. Please check the Route 53 hosted zone." - ); - return; - } - } catch (error) { - core.setFailed(error.message); - return; - } - - const subdomainsFormatted = subdomains - .map((subdomain) => `- ${subdomain}.`) - .join("\n"); - - // Construct the comment - const comment = `${commentHeader} :information_source: - -CRIB activated via the 'crib' label. To destroy the environment, remove the 'crib' PR label or close the PR. - -Please review the following details: - -### Subdomains - -_Use these subdomains to access the CRIB environment. They are prefixes to the internal base domain which work over the VPN._ - -${subdomainsFormatted} - -**NOTE:** If you have trouble resolving these subdomains, please try to reset your VPN DNS and/or local DNS. -`; - - // Create a comment on the PR - await octokit.rest.issues.createComment({ - owner, - repo, - issue_number: prNumber, - body: comment, - }); - } catch (error) { - core.setFailed(error.message); - } -} - -run(); diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6e3272204e..f52b9a5974 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,6 @@ jobs: - '!common/**' - '!contracts/**' - '!core/**' - - '!crib/**' - '!dashboard-lib/**' - '!fuzz/**' - '!integration-tests/**' diff --git a/.github/workflows/pr-labels.yml b/.github/workflows/pr-labels.yml deleted file mode 100644 index fc4cae227a..0000000000 --- a/.github/workflows/pr-labels.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: PR Labels - -on: - pull_request: - types: [labeled] - -jobs: - crib: - runs-on: ubuntu-latest - permissions: - # For AWS assume role. - id-token: write - contents: read - # To comment on PR's. - issues: write - pull-requests: write - steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - - uses: pnpm/action-setup@a3252b78c470c02df07e9d59298aecedc3ccdd6d # v3.0.0 - with: - version: ^9.0.0 - - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - with: - node-version: 20 - cache: pnpm - cache-dependency-path: ./.github/scripts/crib/pnpm-lock.yaml - - - run: pnpm install - working-directory: ./.github/scripts/crib - - - name: Assume role capable of dispatching action - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 - with: - role-to-assume: ${{ secrets.AWS_OIDC_CRIB_ROLE_ARN_SAND }} - aws-region: ${{ secrets.AWS_REGION }} - role-duration-seconds: 900 - mask-aws-account-id: true - role-session-name: pr-labels.crib - - - name: Comment CRIB details on PR - run: ./.github/scripts/crib/pr-comment-crib-env.js - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ROUTE53_ZONE_ID: ${{ secrets.ROUTE53_ZONE_ID_SAND }} From 1b4cb83bae78c398ad8ae6e47dbbe747ff93133e Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Thu, 1 Aug 2024 21:06:20 +0200 Subject: [PATCH 023/432] align prom (#13995) --- integration-tests/go.mod | 2 +- integration-tests/load/go.mod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index f485b290db..29af8b4c21 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -361,7 +361,7 @@ require ( github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/prometheus/prometheus v1.8.2-0.20200727090838-6f296594a852 // indirect + github.com/prometheus/prometheus v0.48.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 0a774c01dd..093a6ac6c5 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -352,7 +352,7 @@ require ( github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/prometheus/prometheus v1.8.2-0.20200727090838-6f296594a852 // indirect + github.com/prometheus/prometheus v0.48.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect From 0e8f2dedc24ac9dc2daa440f5254515573d3fce9 Mon Sep 17 00:00:00 2001 From: Cedric Date: Thu, 1 Aug 2024 21:43:51 +0100 Subject: [PATCH 024/432] [fix] Check if DefaultConfig is nil before merging (#13988) --- core/services/workflows/engine.go | 4 ++ core/services/workflows/engine_test.go | 53 +++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index a5fb9a25ea..c85d4a03b2 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -713,6 +713,10 @@ func (e *Engine) configForStep(ctx context.Context, executionID string, step *st return step.config, nil } + if capConfig.DefaultConfig == nil { + return step.config, nil + } + // Merge the configs for now; note that this means that a workflow can override // all of the config set by the capability. This is probably not desirable in // the long-term, but we don't know much about those use cases so stick to a simpler diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index b8d5a9591e..3af8728413 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -123,7 +123,7 @@ func (t testConfigProvider) ConfigForCapability(ctx context.Context, capabilityI return t.configForCapability(ctx, capabilityID, donID) } - return capabilities.CapabilityConfiguration{DefaultConfig: values.EmptyMap()}, nil + return capabilities.CapabilityConfiguration{}, nil } // newTestEngine creates a new engine with some test defaults. @@ -1063,3 +1063,54 @@ func TestEngine_MergesWorkflowConfigAndCRConfig(t *testing.T) { assert.Equal(t, m.(map[string]any)["deltaStage"], "1s") assert.Equal(t, m.(map[string]any)["schedule"], "allAtOnce") } + +func TestEngine_HandlesNilConfigOnchain(t *testing.T) { + ctx := testutils.Context(t) + reg := coreCap.NewRegistry(logger.TestLogger(t)) + + trigger, _ := mockTrigger(t) + + require.NoError(t, reg.Add(ctx, trigger)) + require.NoError(t, reg.Add(ctx, mockConsensus())) + writeID := "write_polygon-testnet-mumbai@1.0.0" + + gotConfig := values.EmptyMap() + target := newMockCapability( + // Create a remote capability so we don't use the local transmission protocol. + capabilities.MustNewRemoteCapabilityInfo( + writeID, + capabilities.CapabilityTypeTarget, + "a write capability targeting polygon testnet", + &capabilities.DON{ID: 1}, + ), + func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { + gotConfig = req.Config + + return capabilities.CapabilityResponse{ + Value: req.Inputs, + }, nil + }, + ) + require.NoError(t, reg.Add(ctx, target)) + + eng, testHooks := newTestEngine( + t, + reg, + simpleWorkflow, + ) + reg.SetLocalRegistry(testConfigProvider{}) + + servicetest.Run(t, eng) + + eid := getExecutionId(t, eng, testHooks) + + state, err := eng.executionStates.Get(ctx, eid) + require.NoError(t, err) + + assert.Equal(t, state.Status, store.StatusCompleted) + + m, err := values.Unwrap(gotConfig) + require.NoError(t, err) + // The write target config contains three keys + assert.Len(t, m.(map[string]any), 3) +} From 4a7828692f1649ea2762df76a6167a148e56a3c9 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:10:11 -0500 Subject: [PATCH 025/432] Nuke unused files (#14010) --- .swp | Bin 61440 -> 0 bytes bors.toml | 20 -------------------- heroku.yml | 6 ------ tools/ci/gorace_test | 4 ---- tools/ci/init_gcloud | 12 ------------ 5 files changed, 42 deletions(-) delete mode 100644 .swp delete mode 100644 bors.toml delete mode 100644 heroku.yml delete mode 100755 tools/ci/gorace_test delete mode 100755 tools/ci/init_gcloud diff --git a/.swp b/.swp deleted file mode 100644 index e2293baeb2c82c5dda684b915378632a283c71fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61440 zcmeI537A}0b?2KUHW&ztA#4de3ozYCE-l73mawCCOUUh5Eg{J=j^dF@U9VeZbyqd@ zs?}Mq zRxe+6PpW@+Uva^%rykgG$<(GzS6x_ry!Oi)1=c9=V?lv?UvuG>%{tW|v+lg?+y`Cr zW6`R$Myyd_jRI>FSfjui1=c9AMu9a7tWjW%0{=P`=r7!F}D6j-Cc8U@xUuttG33an9JjRI>FSfjui1=c8VhbYi&jf`v| z=d;96W&hvV-#@zl$jCRq*THMSHQ>7#sm}+Sz((*_7_~11`@!A7doY4$!6U$TFqq#8 zUJ4F^$AQO!`+`qmZ2um(85{=Zf{$UKzZfim0`$Nyfro=1V%-0C@Op4H_yNvZIa2w8qKLa;`8^9yLmvBJ*F?a@;0S^Tq$7%7);6`u}co6t7c6T3a2af`e z01pTE24BMFe*<^{xCA^Jd>XpF1_=Fb6dIn^C*!l&?({F*k}Y+6$7klcOFQ;VO}4g; z$dip5H)h?=+;Vm_pX+vJvwoMac}9w?f2`Thn$y$yLchqawONaX&$hkO?YF1%?7*=+ zo7|CgXULKJgrNxewbO0owu*u}8rit{X}a0b@@xaAyPcW#>_m65(+|yy>**}cAI*DO zS9?CEC|ma9i_GL*>^1xCZYMj|ET}KT%X-|RGJwf1(Q{ivmhWTagS&0cdp@8`XOR7JnHINi^tgdC?v_~Az1uq_u|eCYaY zy1CFi+Ma9o+j*hGR0Kk}F;LRdz_y{dHqZ>8&{oDT3=#y6hIW2&uHRmm%adxPxT3)@ z(wVt-(a&04`o`d9?auVvA}wudBZXCB5@}jSJ#Ml#ZL(El#p1$3w+G>~qsxAj+^}nL zN0<9~ap4yF%vc@ETNAG5%j6H8uB*{x2o*2Ge*>zFtI8I(EX3ozSkOEO)^6pUetTv) zYwBRqZEdme*4{09vrgWZi4$n5lscX-XAo?5k>Tz1b5qjMJX`FvpT3y8GJK~P&VBhT z)a@-dvPnoQ++e0(=pp6tA0xK2wdJCVHeZ@8EFPU}PiIn>&PJXNXtZgarD;~QXFGYX zo`~jI)@%`QRTSAwx0f{+7N|xi&INPLWhNMNtANF`6M3&aV;`9+)Vnp^hDQd7kI0xPvy)jO;}K^k0}XT7|&$kIK_DmmRPSl^M- z-T8LEFR2lH1xv)SeEN97YI4E!v1Ypy#GkG=enFI?Sz)G|2qpw5>sujGzuB5cj4rk3 z=5#4Q!7!yt@>qvxE0rB!k#Kpe24uRf z@>*73qb%69h5XU%_H9vBV6l+a>_o*uHKFDE^S(;w-)#LtzyIvLEWMy3)7w@7M00j0@9*6ZO9HRFXZE$)8IiUqOV$+fJQ43yeZJ;^QXzG?Enme10i%`6JX_l0lg+jK*eQ7vtIh0`rH zm>LD-w92e#BGN@I0fw3qP0{g5u|dBV8??kCXWo)T=A&rBXzNz%;!Bs=7rMG;+F2T$R&vgqTiSv6Dc0 zQ)Ht?ue8J6?!k#2Bn<;9&qqeu^P)OtrzU-=%M)rCSmpl4Y^K+p&(<|IG8YWb6&nX7 zZWP_Qb=!QI$z<{cH8!3g0KMDW$UN^nBVSm^Y0?GcY`5UwjVGSicv9oSjc&|~jf?&E zT(Qy2UwqLWt|{)JDXLUKIw_-i3It`|+9(EGQEW_;mC6_}k)y(* zW(-JdiyUEg8meWRAljBEZW|d9`~Q4w))}!~vH!2K_UkR!`z^2@e8JlNm+&_O_XQuq z-tT~m!DGO;vH9Nw4uOr};7l3&nG|R!tpN!AOjVufDC$^2I znN)7|&bEwYlbvEAXQdU%HQ#NC;o}y0k+>M(&WK)WBS;qe2$>n91h~>Sk7fH|FPXv9 z-fSynZcg{Q*cakSXm^lj9r)1Z$BuN;a30k{qy*&@hz3}8t4-wU8XyFa2&ypnWyg21 z$a^Q;Qc{R^5}Me^$QE^w?i#IQ_ci+uWXPSld>-NFs>YAdjB;l=+IWv{NKXrFIa$m2 zXH?+uPFsh`IK^7)OIOCYg{AUb0~^_uP1`A?YAcsT%J?(_dG_VS0`1CWg0duqFHVig z78sDW=tN7+WtF$h+1Xw`%VOn;=YA0%3fdNxv7R>PM4Q4scFASQ6B#XDgPi4xVauFv zA&jx@?tm7yJ1sFRq2|&tG!R{;=ew+%uIYYR)e=J~+P^TS^40Zlqm)HkM7;?q_@_8Q z%whz)HG`9CKQqDgJ$N@tb%mBnxqTro%WhP@Src30ozyGG%j4H6tWf0HSqUGfg$SKjB}q29V{3Njny~$p9eCs5i|rGrAWp%4yE%vM_w+?H zt(i8e7CuyQ#z=buZ%Mn2o)Hwb<=DbIFurfs&I3x}i9J*McTVlUX8#8LIzDk=a?h0c z_kn$ryLRo|Ctq?5jHoP~O{e%>ns^6iPu#mZJ$Gn|q1m1*_V3(xa9lcZcyh}K@hQg*WC|YQG2t5jM ziA4k=|D+g3hc7ZRy*!aoQe26ki5PZ-m8>1i6vi@Nu*4QeTvH4hk+CggavObKIH2gV zXoc=2ojRJ60{-cBr*j&n>s;3s80p(EpRDUrt;})^pIT~WH;5d<0?U~XtScnNX4ggE zmZ{RpkShpg6@fli)Q^65)`)T`#L~;GLwsqswlM;%Pvoy7meU~2n52pKjzHTymjR;&wnRh z%CK=|tqr>gK{ATZpJ6eAOVavB41)NxurisgVo)2OmQ}4xV`awi7*WB)rY}d?UH$t^ zCN;}(Wr^~$m~Z8XE&&(Cp1@cIOqNU zx4RUHmnSUP9YpWWgS$m5!jMq;!=m3jY#cSR~AWNl0)qYhi;-SUGkJ1|dy*)+%2m(g*?ub5`nI0zmIqW4_t=mPjGQk9HA3NIR6)!<^jtS*Fm=c5li_MF& zlL&TZ#uD~T;CKWzsvibVu_&)w5V=E=4;&TCU`is)VBb?wo{AGg#j^Mbtkl8D_-7g_PZyYS*I2&hDXnmB)0G|D=GR2G2AJURc(3)X=G_f`m@S zk}DL^_c0^VktJBkacUYM(vE^-TuBpbXDqU_1>qO_-3z>OA&h7ZG%55HUr}MD>8bAt zvP#leEtT{`-R)!Qe_@I1E{f76b4{eZ9cVjMLKKOc=T4FELyFQR+L>J%b+$6Gz2nYI z^=LM_KD#-t!&x76f!bqenCLKZAj{xz4y)XSh7kCnY?3P3SNIJq(|b3{CY(b$QXAp| zb>of3NENg7s-9KeK?z|{x?@ElE@&kib%UCW_(X|}v27j`+_jo;tC<;9Wwfg?KOBH* z0x>LInTz?f#9$Z=QyYXMh3TQ2tEd<)HqcNlw79yV4>h}SEmbrrc`Hr^!xhdIZ1{Sk z2^R@%qB-P^J5i>GD}V;0ADi$el_$r#bHoV=O)Gu2c>-r!QMw~v!0JTq)XdKVk;IM) zq}rCxr6h8$S2y+5TR>;k5$tHC?V@uCRtY#Ojp^lWNUlzvi)D^Vo|of0eFx?{r`D*q`2}!I|{fXGYgz zE5~R}anz|>gvaeO@%yVMibcf6${xXsT6K*bA-JS7El%o4=M2kjIaKh+XPp!Ke*=c; zo5eoG{`cqevGYF+-V2sN6FeAv44ePe;6>K{KbOBF;7_sp-wotEz#P~L?hby4?f(Pt zULa=!_JIko9y|>E06)ODz}LZT;O#)p4D0}p1djlJiGSdKfSbSs_$hEt@Iib7uLcXC z3(f=g1z*N5@Iml<-~`wPzKTEKX7EEJ>W<90lp310$v98 zfGKcK@O}IM?*%UeF94TENJ5_f~vS!v=G@--B!Rd8WQQb`b9WDXdRA5%;KgQ88 z+1lV|OVELE6N@gUnx#h2NBR-gjA*do%t6S8-bNTy#j=Zv(HcwnMbYy%Zd6!Wj_AI& zN$UNIS`?~vTjfp*WK!e4Y>MUVy5lVobkkMQIBJnA*2I;0B1_!V4x;v_y8Zno@P5K; zP@~Q!5Yv%(_A^Rv*C#VXz6PbQ#LkB?l4mxx==}0E#CkffPihUg!cUuETDUsoWn^_z zGce>7HIJKshMgw~;wY*FDzl!Hr<5DeFEjjZ=!tnWt{mYy^F;)9Y$UCIewnW5NgUJW z(2+32_1!T`Pe>I_DP{KB_HH*LSH6-WJkj%WI*@p zfrn8)aOUWbobO;sZNfkjUm~=$Z7X@R;gx6PJ&w*0@nW2Qr37@`MZw&Gp%jOMWBSJz zp#yNIowdq|iBR-iu_IC^x7Zm`B8$syB>|I5bT{-+DX#J;Og}9oG%KR3=N{ZwZl2Vi z*eSQS%0Y#dx-M`#u#vbN4NKzfJ(}y5TnnSxO&iY%l8`ad-R0y*&D}B)!P*;_)oEL& zIpf?WID>6ObVL)C1dbTi2~}FF)U~AD#rJ%I_=J|8B%0h|nMWl5`~u!gmCbj6qfqWx zR8%-9F|4c=GSrTv3;Z3Iu>3GhOsKlk6qyCWr8*PrZ+D<+!tAzbMAPaayO`&%)=2){ z?Sh-1r;jPibMh@S0sebB`360#7=Aji)Gf1?Ny`JJusa%H=dDDOLz`Z&$;9u?5=^i0 ze31s=tE$O9)9w)vQJXvcQ5==4l;|3frtYtK+iQ5dzr^9hFjV7s?2F56P5hzcJhHG~t5e%nFaclDb;HJc=Z{QCBH)n{Ta_T`(>m?;uBT&SP z(lnSoah03e-Nu=7Muxz|tI;fE7r@KDWxs=Af}Wtiw>>FY1cZvK8t1+%%Xm1AEKxCH zo$x~jEn)n~?@EW=-jm;2vp)Emah6if)MnV)ZrGq%lZ=%p-ac&ZuHOx_E(vG<%RY5{ z{{Q!}_5U+C2;}U)?EC*ccK-XoNpKl>GWaSszT5-wYVb60Ex0%MF1Gy}KnqL*vGvae ze}X;#>)_Xb+zW6H_zbrEp8>J&kATO6+py!`3f=;)1NQ-U0}=}$=L3EbTnFw4{sOz=n-v+(!&-;mnX;xYZH&&UaaZ!GyF~1R< zD0@T7L&h+O((3v%h@C`X79~8*U8lr~&``V2L=lM1Eha+e10FnF@ z5&A!c7`(>Z1CZ)%o&CU2Nq+$F#~{6jJ0WPAumEl+&82!CjOA@PWjAF|WyUR@tI#aEd;*xu&FcQLT`|?do^BR>ABSVWy6kE&HE`w#C z`brG5`LI2Io`>Hha@!mNMcK2527Q~7X|fuxXQY3r`PEceqd5ar_t^@sSVqKoMy=Y# zo@-S)dO8lV`;ExN(dqYo#drzHtxBY1 z4L)YcsXB3)(*A*x$Ed=hYzu9*x?~}YmNI`;j9bbiHLIUos6)?Pcs@^U?_DD`o=W@~ zsb}4YyUZHVYT1Rt_}OJ&H7$9^lDHcZ$Gx^u3?r6GW>YJ0@RTQ}=VkmZcL71ItH(+A zJ4s%cU2P+GVy|y5(OJMZGX|nn2%o2vaw~eBBTs1To=4tSJG0ZLE9(PZt{Hco zCD)1*spN|p==GCfPdZWAHyA!)q&wEjWlq}3CW*|Qxo-FPqK40i9!Y!A?G`)Uxwn0_ zJy1z21(tkj2%s<|o@JLOix4g}MEaIHb^6lMtU7Q<2sCo?vi8T7I~+FIe38u4NaUt| zzR>5|@vHXewEL{b_|M>YMqR0nYFL=!fwd0Ur$`j&0S!OpK(UH=+)QQ(6{n$aVQR@l zv&|g+IAB;vRhh^fmYnJd5*7=x+Gd~8`RTNfOoLGo?Ggq{J4}?TmB+Qu97mka;5#Kp z?p2YcMM>2*n;wDV;|*4s!)IXG+p(%;&!>{M8UG`cQ!ya=zABw+#)hJF76@O-cx zd=K0HJwRgrUj{A$PXzY@e~5iAcL2T!>;>n5k7D0{1iTi^f*G&_oC_WVzJ|U3D)34m z_W?W^Yy%GhpU3Y1Kj2NE2_6l;i`{=a_(SjBtJ7F?X)88pDK14rH!MoO$x&gIXc?dN>x;v3&~hs2 zi}9oq@w$37~M2B2H82@+2(>({5%hM!i7Ls((oS$#G?OgN5z}ppf*N?YX#w{e3xjP7`!3*({UT?2O1- z!+lc3s`v$2_W||zhAY8qYKVC`%#8a=3gA+SS&4CxLzuc2bO-ipDw&o)i5*OMhwe*P z-NB34;FJRwLJaK0F*H^;xO~;UnAk1vj#*%9N)EZp60-77)oWehP8~PiHcA&->a2{* zm*x$tK%dvNS$=m?L^#hB?|w-pf4MrBXr*eyB$fIHp798@k~XQOUMU$@wx}qQz?vLN zs#TV`U!Am-LU-CDnp$e=$jw(sx251uFI@&iftEE%ON&smiz|(k zY*=c;Dv4gT7CfQul6G5dKW%Iy=1|A@)s_jHdRfg@sCR(HEb4znn0skzC0R7{;$%|0 z@qvfZclc8z-k5Zo2Gxe0wt;2cOwl0v_AFPVFFa#fC;v#pdO|L7%Z1|VdNg6(xRDqA z%=d^jfiv=~$ZW2J#+^==lB4~4=dP9(dNdV@F1O2LC9&&|Olc>kWLt+4xOPLVJ+tj& z)k?cOdxcVkwADQ%0$(ggl@47W*peNq-ZtraXL4%Un$^`B`4qiOWRpP?rg_tLuk0cc zyUXq4q#BTke;T$0dhKHf|0km( zJ#l5!_GDbQknTEOso{;-vi5^-2i=W8$^!%W$2?HOTaG~5D;C9jAyh~U8BYFajwS?j zWvq(wZokR(La1+Ms@VVMVW+-C?A7S}|J$(n3os7O1!DjI4fq`REO<9K4mJYu13V8r z30wjm0ltLoe+zgQ_z&QpvHkxE+zPtjUf^u-FWCKm0Imo7!6U(!vHM>Jo)4Y{o&lD@ z9w0t}&tmtV1oAF`E5R;s9{4skzuW`xbnti}as9V~mw~5&$AgD~2Y_?H=f&m+ZwGGz zzXqNMo(-M_HiPeB|4W>}uYlv=a_|uFVDJ%q0n^}YAol=#2K)cn;3DuuAa@0R0tjti zEc6}r$@F8_Q%o^y5(c>}H@6#`uu)yqSUq6~`8YGRVYMXeQ(Nfhx^-jOGoNVE+BB{bqhNSw*BPn^_u-j!^L5U0V>;;A9!?KJ^> zk$=MS;L84pqUwhr{LS3EU?_Z9OkntwgDiQ^1i*Sl8!092FrEt2nzEmQi*J3X+9^gd z)(j-8R}Iv3qd=R+7}rO+qvp6+-JJXG$bG}Q;pen7ec)7Al+?0<&nji&Ke)0&+leBj z_Zg~mHTJqIE7r0o%G#&K<7T}Z@ldEj?EG@!FBYxxbK;BQ^5J&tP1&2P4lWMt1=p7G(WooTwNu8yH6{qsq~*fItchvL(Sg)4{TII4 z-R>+B=FSBu;#`^5YgN?YQ=6BFR^!oOQ(jfEY_n3*YBh0_)T2~ah}7+810JTh%|-0i zI?<*_-kTLC^F%PitnC38nWUq4bm z%4#aDSxRE^$GXWN37V!~SxE`4tyNd-`eZZ{n&&kXOFc`FtJ8BcrAAmiD4m+FI;$T# zt-acwG86iYG{LV6#wQSuOJT)mSy_rIFfS}{KMYE^f_CMy8!gNFCQ^x)sjtPaB*ybn zqR~(ZYfhaxzenmjF`|(*DXp_AUMoAA&Q+4O#Ov#=e2()X72PIHZMWq7Mp62-Bvvut zs+)MC=G3V;ZkQug$B(x0n@mMgd=;Y|Euirxp4k7FV3)p1>{IOjr&=5J9oYPD2mcYg z6zm2+18&CNzY1Id#=$w@%h>z3g4cjP*aV&c&IgYJe}n!1QSf~5Wbh#HIc)#m0`CAf zf#-s4K<)*U_<(D{K_GVmegM1@EP{hTVgs%QzX1LTyZ__hjo>JF61WfeTkL;{3%CSa z4DJTrh0Wgq^I#hgKfs5v@m~k#zz*430@6^p05OV>$@~qb$i;xj3v4t6D4TKR4%NtqqH&n*AmP)V?5g%ccBZl-o2KD^7*AZS>y>ZyqDsB?E>P%3vG6RNn z+Dh=D4!4M>G=jxB)`Uf5J#ap?Fnf)0)Fz^zEZS=VPB0j>%n|3FI9#KXHH*!(d4YMJNaSgfl zRmvY!jx3ZFHTB2dUl=d%cgmZm1FEi$e{*MEP*cyGKhKmoVzffJIXt|xj9X&yR`~fH z_Bau_Hp6ynsXH}N*b-M>@DUh0NSu16B9ah4~Z|hcQdXL#nwpM7KGZ(klhTODal`wSY_u{0ha`tAbQCn*GuC7%y8(DeBu? zlfwko;dHy4)o8@D!l!q_xn7t_HxnV`YPH44a}}9l8%yt10h50O&ag?XtTgQ=nc)uA zqzu1Qt&AvCu#!4j*loDr9dOf|Ql%5|RU~o`frb-SDvhj>Q*(myL&S?nIf~mE*RQjbRk@U)$_v)V3Zl=Hb zHQmWPxvbXf^Hp(kjPRP=PDiz0it$X%o)c5&b*K;bmr>ikzg3 zrq1eh;)p(V8u6-B=DJp_PDf61(o?bjpNNqvHmlhG`>etGL2Uh9;5O|0F9Nske-r<1 zfZMU_YoDH}ZtOH-f&i?|C`v6`7o(JZE-1&D5 zjDhc9_x~n12(AL($KIFo0CLaY;?A(Z^8aQ4mN>XvH5p_r-1S~ zfX_fr=LfJPUG*O;4<)Mj8s5G)Al6WJpx6&mg~V8dM5mVbC->Rt=4Kp=C+}ZDF^V!F zKx6SCb%At3THG{h}4QCVeDW?3(PIf1bFWP9ng9RqNN>nqs3>H}(N0>u*gq zT*DGwC$Z0V{hfB4LEXZKzELB#EUQ*~z7Yql&$L`!Q00an-=XEvY9ls8*}Z@sGVroi zR!a$iEupeBmZT=nss^2zcxA;? zkmru6%$#F!NS;`{l@gMt=2eH1DbfckS)yklLseQ8m5f7`a5H?NXVIQP!}TdtXY7e;4eFK* z$&@)Nsr1*7NH{%M7nRiMW0y@PgRsHqsS%-kr;l*uiqd?w4z7? zDa9=Mch1NZ`(A@yYwC<*N)j=9d|P&$J(6;cNZ=k9z8R4=%BLbT%Q;ng@?&v`|Aiep zx22c-Xt$lba0)N(k*e%2o93WY^ED_RUQETNwC@``(02RBm+mt}ohuo*=&xZlsb-YE zg(0dw_rk^T+Uj@v;==SGo@xy%Zup%RD|-1{X2~01Nn!nK-L|RhSo&o|#^Q{!=a6;` zVpBVogL0NfRP2BGELi*hp!quTR&4**f#-o)@C5LW*!{l)mcbLi7qR(23qAwn{{K&c zXMxS&8`%9H05^a~1Bv_p5Rkq8p9hzMp9K#C4+U?=*6)I?;0M_Fe*kua2ZINI`-8v4 zzJEE8^Z#GLj{kM=I`CSs7hC{-h&}(?;N{?YAol$Ra2t00XTgWSE#Ng^88pEWup4X# z8F)W-{w?6Qz&k(>Yy#iJ=D!8p1TF;+1fRh6e=qnAAa?>xfKA{b;NIX{(Dj4hc|d3^ zERtMjDvOulnrMYjeL3hDiD9bq+%lb=`bl2&6_S+1ib@cfZ3ESJBS*NgLt9jP#i&__ zllwx=PZM6IPuP=dddj)hgh=mL)8k+GFD0xCvoV zalrb#iA`TzP{ShBi)llgI>ts%?%WoWNemC^;A(nj%qmH~LG!s5D#iJQU<)eFF{*sA zQX#K)wB44J9*5e z=IE(*Yb!DESk^&>-I{GCF5bT6k*D@w95FQSV01zpow@wWhHPeQHsj3#-<8t%8s5!x zNwBP1n%odfuC~zm*d{8cEjI_acNki>*5A;?ImJMSCR^**|76ZnKP&Mm(2>)alICrh zmbpB!6TbQJnS1!ad=qQ#cvdNtx(Of#6AI;@38nE$`qoHyN*))9%sB4@(Fqh>WY)-m zhrAQE>S-!M08rH?OzrV@G2w-^_s@mPI%~2AF`1fAvJO;DC0!k2u^SN!=^J{%9OJdJ zoHYnNu)}-gNBtI$)3)E;izpQMp{vby!Rx_@>D= zur35ewA5JI_&y<%#1CN17H3nGpL*xrgr8|O&gd2Vc~$bfwV zzR)C-yslv@IR9!|rnYR&?}?q~22I?Wz8Mg7@F^yrYB}j!#P@c5DhaPH-^NcpmXY+r zJjAdHGgVx{=r^ zPT~|Q7BE)w1Kig%q?9;W$n2|JULkv$Fce_L(~yd7ijXCiT0`>1$wFpFmaSGIap8p} z?1UR|W%c0>&XCrv1imOZ-31-2gz&*f^@D2PBd=k6{JPkY){3E^r@fW-c+zg%#j)3i8 zGZ+Jp0cV5n<2(3k@E71y;6va8;QgQn_JQ-kt@skI17E;*@DA{HFb?GYfQN!V!B21) zTnH`z8^Cw)5&Q%A2DlZx0z3sg3Va7&!Dqqmf@L7@2>b=`MSKKb0KW{H;OmTojK$Yv zJkIb(=C8P?Fh-2k)R<96gIo#_|F%BcOoW>ngKi~Ynlcgmy>_LWKBLUWJ?2&_>!iTB zhx|m!>CsWNVf%vY-eMD8RJB8XFS#TS#q%fZs#;Q(dTq&n`u?>qU^-=!HaP#Kh4#9hexi+_g!ih@opFTf*~_ z&MQqCLKwl!b|EFU*i6tGp+Jq(r=)&cztY-S$3=!*CjXA-deO$gH}~ z38+56_>^3{6Bk{1p>2qcf9e?Myp%bh@ni1B3o1+OBO$w97Gy5{w1!^jlxbG%RM#2m z9gya^i2fDsyO4@o@K4<}7xBC!-4H9U-2CeF2`OX>c?Yu<^Q=Wuf#bXy&Ki`1EQU?& z400o(Y&avxpplzVL}E174DEs7&j<0?&yfA)D~svpDwl9Z`ZHd6;&Exa@u{v5v81tsH=)J<%PXerjCVahs1NZ zdw~*S+2}P*>db~n>Uk+*4t79vw`Rv$vdJB-)C0p?O-h}4Q9LWfit`u;j;Y375#=;X zcXULm&-{CCqIJ*RL><;8KgGynYyh)Ir41-;Q>|Yg(fVI^%S!D32V-Z>S^IylwK?C3 zo&PLw9r!Y~{oet(`~Q6KBW(INfGdHV_5TVsyx8@ZgNwl?uo2uH$b0^N74*UV!Kbm; z{|k6A*Z}SZ#CDf6{_g?r20id7@N+=+{9gqozzFyeHu+n@L2wN?A3PlV4mSBK!1F)@ zoDUuc{x^2{Dew$%2dX7ExVv^);VADKd`qg}WqW?r3*#tmej28#>*(>$rp(&Tr;RZLPp zU!2wF1f|ug{id937+jgpiO<{TQO_vz07IZVcS6pi#cyOC^g>o@jdtFxythl1sII;R zR^3h0YwvYFnt$=SSE~!A=|VAR98!Atfl4MzdS^7BOxXk8tcgF)Y!H|X)psf?VXe4u z`zk6ek`~A=k_i?L<<#5<6%15Q6R+EQ_1m~7D95PyP{AyT)ur5s6}FT$OwN9bdTvF~ z5MPE0cO#&y*^Mx-&5hqk)+w83W=P8NN|t0SKO9ny+q_TmyB|$Hr#X1Z>jG-6QEeAA z2x>mjyptc?$Z6n8P%!)qlr*8w5t+?IOdm5QBl1fK_VFV=p#wZ>ya`%lSVzpWsB-fI zrm$6YtBsQ|@zPUGYiP1k`Jy;2EEdN`OGWtBsuyEKdlIQ;{^-mUI*yG^+HYd`Lud5h ztsLKTtDPT*v~*Lr{6B0m$hW~w8j;85!*v)sj;h5;W!E=+xK7Q+2Emo(%4 zIVnWuqi66W!*C6FP^KtiQ_q6wkU3fB{-(B)R8(st;pB_F|Lr((RhIB2c~hjQ&c-F= z;s9j5Ls|B`B1xapws&B*T3It|EiTNpr{$&|lU9^zS;aZkC5xt?k@hhb;4I00tb_)3$08iAk=(*ME7gq;C!WC>_X4gWOLB2Q z$X{Lx#k3remYBAjN6IoAYWO|Z7}$GeG@QT-=2+y2kRIOUM6yNqk;Rg281t1ZYPkyr zMi|s!xp$#7kYVH;30GBypEGrC0Iwc-`B~S^;q}CZyFH01L&5~Whhe6@t{fxstNz}} zb9tWvdZkPNcPoxfYi1Z`ro4V=sn_OxLEIK>rkmTsnqwLjuJ92pR_c?zuepMwmR;RQ zGj^)hp$l5DN_~|w6+MAmpqdM*L}A5;6pCk-nsS^hqYq4C-8V72a;A3@lPlWpT(dVz zcmtX-U-*w#U9@Luxo!&){IIAmQ_>(D=)k6($`+~=Bb&E9Np|~!zt9NjwxD;#zV_+2g9Jn9&Ccc3` z1-F0~f!*LC;D6EIKLeixp8(qbvcbOgeT@QZ6j-Cc8U=m=C?KYgGly>UDj#ly0mj(Y zflqXqm8DiRBD0yYRaE@}`fT-_bXl2~FhTOW4Ytbmj`J0v>-*CxX%6>$NXhw>G|5bO zX4ZREOzEZCtokLSkkc}0_TaHXGmstQBm~juP_^XM;_K;CCVd*xp;oG=bx1o&+v0DM z&b2)JJ`tPZk_26CqJF4tPwKS)LFLsN-2;lR3As+Af!tR7!2IE;uAJ+2F?Yr$3L6IY z>V?o`(i#J}TyW$NB8}ZV9H#!(Fn6N*hNz=tBk|71cI6ynn8CH&71S~;<8YF!v1{G&4Nh+BYQJV z-n|}}#CpB0@71M@us@|NAvK~ZdD4Go8s20@ORnO@&E ze&ucfV|lyyRGV20D*I1yLLJSS(|MUF?6SmZxa`Wkc~`8ZqZ~I%4j`m+RnEsmxu?55 zjyFoQzO}N9SwE=9hI6IEQ5h3*B*_`G<>16=J9KvY$h@ytPe~fb&q@PX4c#m40S4-n zV#ULQNxaYDn+y00HAfTj6#a@f`#j%Px8$n#VpMs*w6PYdwB*2l=qj`kFS>;mM}iFu zeTi5c@iys3)$J>k7DUE@s9?9uBqutvGa9DZ7|67SvyJD`Q(~3TpLJ|d8aBK4?1xu7 HJo5hlrWzqI diff --git a/bors.toml b/bors.toml deleted file mode 100644 index 5970c638ce..0000000000 --- a/bors.toml +++ /dev/null @@ -1,20 +0,0 @@ -# https://github.com/bors-ng/bors-ng/issues/730 -status = [ - "sigscanner-check", - "lint", - "Core Tests (go_core_tests)", - "Core Tests (go_core_race_tests)", - "Solana Smoke Tests", - "Prettier Formatting", - "ETH Smoke Tests", - "Solidity" -] -block_labels = [ "do-not-merge", "do-not-merge-yet", "needs changes", "wip" ] -timeout_sec = 3600 # one hour -required_approvals = 1 -up_to_date_approvals = true -delete_merged_branches = true -update_base_for_deletes = true -# todo: enable after organizing codeowners -# use_codeowners = true -use_squash_merge = true diff --git a/heroku.yml b/heroku.yml deleted file mode 100644 index bb95afa121..0000000000 --- a/heroku.yml +++ /dev/null @@ -1,6 +0,0 @@ -build: - docker: - web: Dockerfile.web - config: - REACT_APP_INFURA_KEY: - REACT_APP_GA_ID: diff --git a/tools/ci/gorace_test b/tools/ci/gorace_test deleted file mode 100755 index ebf0b89281..0000000000 --- a/tools/ci/gorace_test +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -set -e -GORACE="halt_on_error=1" go test -v -race -parallel 2 -p 1 chainlink/core/internal chainlink/core/services diff --git a/tools/ci/init_gcloud b/tools/ci/init_gcloud deleted file mode 100755 index f1ebb12b59..0000000000 --- a/tools/ci/init_gcloud +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -if [ -z "$GCLOUD_SERVICE_KEY" ] -then - echo "Skipping gcloud initiation because no service key is set" - exit 0 -else - echo $GCLOUD_SERVICE_KEY > ${HOME}/gcloud-service-key.json - gcloud auth activate-service-account --key-file=${HOME}/gcloud-service-key.json - gcloud --quiet config set project ${GOOGLE_PROJECT_ID} - gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE} -fi From c1bd103e9b134a90e0bd5f77b6e54797c7c881a8 Mon Sep 17 00:00:00 2001 From: Kodey Thomas Date: Fri, 2 Aug 2024 12:50:23 +0100 Subject: [PATCH 026/432] Add L3X Config (#13987) * Add L3X Config * Changeset * comments * comments --- .changeset/cool-mirrors-beg.md | 5 + .../evm/config/toml/defaults/L3X_Mainnet.toml | 18 ++ .../evm/config/toml/defaults/L3X_Sepolia.toml | 18 ++ docs/CONFIG.md | 190 ++++++++++++++++++ 4 files changed, 231 insertions(+) create mode 100644 .changeset/cool-mirrors-beg.md create mode 100644 core/chains/evm/config/toml/defaults/L3X_Mainnet.toml create mode 100644 core/chains/evm/config/toml/defaults/L3X_Sepolia.toml diff --git a/.changeset/cool-mirrors-beg.md b/.changeset/cool-mirrors-beg.md new file mode 100644 index 0000000000..a030ac7e3a --- /dev/null +++ b/.changeset/cool-mirrors-beg.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added L3X Config diff --git a/core/chains/evm/config/toml/defaults/L3X_Mainnet.toml b/core/chains/evm/config/toml/defaults/L3X_Mainnet.toml new file mode 100644 index 0000000000..1fbda42fd2 --- /dev/null +++ b/core/chains/evm/config/toml/defaults/L3X_Mainnet.toml @@ -0,0 +1,18 @@ +ChainID = '12324' +ChainType = 'arbitrum' +FinalityTagEnabled = true +FinalityDepth = 10 +LinkContractAddress = '0x79f531a3D07214304F259DC28c7191513223bcf3' +# Produces blocks on-demand +NoNewHeadsThreshold = '0' +OCR.ContractConfirmations = 1 +LogPollInterval = '10s' + +[GasEstimator] +Mode = 'Arbitrum' +LimitMax = 1_000_000_000 +# Arbitrum-based chains uses the suggested gas price, so we don't want to place any limits on the minimum +PriceMin = '0' +PriceDefault = '0.1 gwei' +FeeCapDefault = '1000 gwei' +BumpThreshold = 5 diff --git a/core/chains/evm/config/toml/defaults/L3X_Sepolia.toml b/core/chains/evm/config/toml/defaults/L3X_Sepolia.toml new file mode 100644 index 0000000000..ee515bb72b --- /dev/null +++ b/core/chains/evm/config/toml/defaults/L3X_Sepolia.toml @@ -0,0 +1,18 @@ +ChainID = '12325' +ChainType = 'arbitrum' +FinalityTagEnabled = true +FinalityDepth = 10 +LinkContractAddress = '0xa71848C99155DA0b245981E5ebD1C94C4be51c43' +# Produces blocks on-demand +NoNewHeadsThreshold = '0' +OCR.ContractConfirmations = 1 +LogPollInterval = '10s' + +[GasEstimator] +Mode = 'Arbitrum' +LimitMax = 1_000_000_000 +# Arbitrum-based chains uses the suggested gas price, so we don't want to place any limits on the minimum +PriceMin = '0' +PriceDefault = '0.1 gwei' +FeeCapDefault = '1000 gwei' +BumpThreshold = 5 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 240ccf1bd4..5caab7614e 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -5242,6 +5242,196 @@ GasLimit = 5400000

    +
    L3X Mainnet (12324)

    + +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +ChainType = 'arbitrum' +FinalityDepth = 10 +FinalityTagEnabled = true +LinkContractAddress = '0x79f531a3D07214304F259DC28c7191513223bcf3' +LogBackfillBatchSize = 1000 +LogPollInterval = '10s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 3 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '0s' +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 +FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '1m0s' + +[Transactions.AutoPurge] +Enabled = false + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'Arbitrum' +PriceDefault = '100 mwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '0' +LimitDefault = 500000 +LimitMax = 1000000000 +LimitMultiplier = '1' +LimitTransfer = 21000 +BumpMin = '5 gwei' +BumpPercent = 20 +BumpThreshold = 5 +EIP1559DynamicFees = false +FeeCapDefault = '1 micro' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 8 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[HeadTracker] +HistoryDepth = 100 +MaxBufferSize = 3 +SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 5 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false +FinalizedBlockPollInterval = '5s' +EnforceRepeatableRead = false +DeathDeclarationDelay = '10s' + +[OCR] +ContractConfirmations = 1 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 5400000 +``` + +

    + +
    L3X Sepolia (12325)

    + +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +ChainType = 'arbitrum' +FinalityDepth = 10 +FinalityTagEnabled = true +LinkContractAddress = '0xa71848C99155DA0b245981E5ebD1C94C4be51c43' +LogBackfillBatchSize = 1000 +LogPollInterval = '10s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 3 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '0s' +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 +FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '1m0s' + +[Transactions.AutoPurge] +Enabled = false + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'Arbitrum' +PriceDefault = '100 mwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '0' +LimitDefault = 500000 +LimitMax = 1000000000 +LimitMultiplier = '1' +LimitTransfer = 21000 +BumpMin = '5 gwei' +BumpPercent = 20 +BumpThreshold = 5 +EIP1559DynamicFees = false +FeeCapDefault = '1 micro' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 8 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[HeadTracker] +HistoryDepth = 100 +MaxBufferSize = 3 +SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 5 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false +FinalizedBlockPollInterval = '5s' +EnforceRepeatableRead = false +DeathDeclarationDelay = '10s' + +[OCR] +ContractConfirmations = 1 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 5400000 +``` + +

    +
    Arbitrum Mainnet (42161)

    ```toml From f5e0bd614a6c42d195c4ad74a10f7070970d01d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Fri, 2 Aug 2024 16:42:00 +0300 Subject: [PATCH 027/432] Disallow zero address signers + pin Solidity version (#13993) * Disallow zero address signer * pragma ^0.8.19 => 0.8.24 * Changesets * Update gethwrappers --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .changeset/slimy-forks-wait.md | 5 +++ contracts/.changeset/silver-pots-cover.md | 5 +++ contracts/gas-snapshots/keystone.gas-snapshot | 40 ++++++++++--------- .../src/v0.8/keystone/KeystoneForwarder.sol | 3 +- .../src/v0.8/keystone/OCR3Capability.sol | 2 +- .../interfaces/ICapabilityConfiguration.sol | 2 +- .../v0.8/keystone/interfaces/IReceiver.sol | 2 +- .../src/v0.8/keystone/interfaces/IRouter.sol | 2 +- .../src/v0.8/keystone/ocr/OCR2Abstract.sol | 2 +- .../src/v0.8/keystone/test/BaseTest.t.sol | 2 +- .../CapabilitiesRegistry_AddDONTest.t.sol | 2 +- ...esRegistry_DeprecateCapabilitiesTest.t.sol | 2 +- ...bilitiesRegistry_GetCapabilitiesTest.t.sol | 2 +- .../CapabilitiesRegistry_GetDONsTest.t.sol | 2 +- ...esRegistry_GetHashedCapabilityIdTest.t.sol | 2 +- ...ilitiesRegistry_GetNodeOperatorsTest.t.sol | 2 +- .../CapabilitiesRegistry_GetNodesTest.t.sol | 2 +- ...tiesRegistry_UpdateNodeOperatorsTest.t.sol | 2 +- .../src/v0.8/keystone/test/Constants.t.sol | 2 +- .../test/KeystoneForwarderBaseTest.t.sol | 2 +- .../test/KeystoneForwarder_ReportTest.t.sol | 2 +- .../KeystoneForwarder_SetConfigTest.t.sol | 10 ++++- ...KeystoneForwarder_TypeAndVersionTest.t.sol | 2 +- .../src/v0.8/keystone/test/mocks/Receiver.sol | 2 +- .../keystone/generated/forwarder/forwarder.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 26 files changed, 63 insertions(+), 42 deletions(-) create mode 100644 .changeset/slimy-forks-wait.md create mode 100644 contracts/.changeset/silver-pots-cover.md diff --git a/.changeset/slimy-forks-wait.md b/.changeset/slimy-forks-wait.md new file mode 100644 index 0000000000..0408383bd0 --- /dev/null +++ b/.changeset/slimy-forks-wait.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal diff --git a/contracts/.changeset/silver-pots-cover.md b/contracts/.changeset/silver-pots-cover.md new file mode 100644 index 0000000000..93fba83b55 --- /dev/null +++ b/contracts/.changeset/silver-pots-cover.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +#internal diff --git a/contracts/gas-snapshots/keystone.gas-snapshot b/contracts/gas-snapshots/keystone.gas-snapshot index 2880e4c0e3..759e287b01 100644 --- a/contracts/gas-snapshots/keystone.gas-snapshot +++ b/contracts/gas-snapshots/keystone.gas-snapshot @@ -63,24 +63,25 @@ CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateCapabilityAdded() (g CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 107643) CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 163357) CapabilitiesRegistry_UpdateDONTest:test_UpdatesDON() (gas: 371909) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_CalledByNonAdminAndNonOwner() (gas: 20631) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_CalledByNonAdminAndNonOwner() (gas: 20728) CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorAdminIsZeroAddress() (gas: 20052) CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorDoesNotExist() (gas: 19790) CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorIdAndParamLengthsMismatch() (gas: 15430) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_UpdatesNodeOperator() (gas: 36937) -CapabilitiesRegistry_UpdateNodesTest:test_CanUpdateParamsIfNodeSignerAddressNoLongerUsed() (gas: 256157) -CapabilitiesRegistry_UpdateNodesTest:test_OwnerCanUpdateNodes() (gas: 162059) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 35766) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25069) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 27308) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeSignerAlreadyAssignedToAnotherNode() (gas: 29219) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 27296) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByCapabilityDON() (gas: 470803) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByWorkflowDON() (gas: 341084) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 26951) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 25480) -CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162113) -KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 1797755) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_UpdatesNodeOperator() (gas: 37034) +CapabilitiesRegistry_UpdateNodesTest:test_CanUpdateParamsIfNodeSignerAddressNoLongerUsed() (gas: 256371) +CapabilitiesRegistry_UpdateNodesTest:test_OwnerCanUpdateNodes() (gas: 162166) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 35873) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByAnotherNodeOperatorAdmin() (gas: 29200) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 29377) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 29199) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeSignerAlreadyAssignedToAnotherNode() (gas: 31326) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 29165) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByCapabilityDON() (gas: 470910) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByWorkflowDON() (gas: 341191) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 29058) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 27587) +CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162220) +KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 1798375) KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() (gas: 125910) KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverNotContract() (gas: 127403) KeystoneForwarder_ReportTest:test_Report_SuccessfulDelivery() (gas: 155928) @@ -96,10 +97,11 @@ KeystoneForwarder_ReportTest:test_RevertWhen_TooManySignatures() (gas: 56050) KeystoneForwarder_SetConfigTest:test_RevertWhen_ExcessSigners() (gas: 20184) KeystoneForwarder_SetConfigTest:test_RevertWhen_FaultToleranceIsZero() (gas: 88057) KeystoneForwarder_SetConfigTest:test_RevertWhen_InsufficientSigners() (gas: 14533) -KeystoneForwarder_SetConfigTest:test_RevertWhen_NotOwner() (gas: 88788) -KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingDuplicateSigners() (gas: 114507) -KeystoneForwarder_SetConfigTest:test_SetConfig_FirstTime() (gas: 1539921) -KeystoneForwarder_SetConfigTest:test_SetConfig_WhenSignersAreRemoved() (gas: 1534476) +KeystoneForwarder_SetConfigTest:test_RevertWhen_NotOwner() (gas: 88766) +KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingDuplicateSigners() (gas: 114570) +KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingZeroAddressSigner() (gas: 114225) +KeystoneForwarder_SetConfigTest:test_SetConfig_FirstTime() (gas: 1540541) +KeystoneForwarder_SetConfigTest:test_SetConfig_WhenSignersAreRemoved() (gas: 1535211) KeystoneForwarder_TypeAndVersionTest:test_TypeAndVersion() (gas: 9641) KeystoneRouter_SetConfigTest:test_AddForwarder_RevertWhen_NotOwner() (gas: 10978) KeystoneRouter_SetConfigTest:test_RemoveForwarder_RevertWhen_NotOwner() (gas: 10923) diff --git a/contracts/src/v0.8/keystone/KeystoneForwarder.sol b/contracts/src/v0.8/keystone/KeystoneForwarder.sol index 4b44feccbf..b18e381cc6 100644 --- a/contracts/src/v0.8/keystone/KeystoneForwarder.sol +++ b/contracts/src/v0.8/keystone/KeystoneForwarder.sol @@ -49,7 +49,7 @@ contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { error InvalidConfig(uint64 configId); /// @notice This error is thrown whenever a signer address is not in the - /// configuration. + /// configuration or when trying to set a zero address as a signer. /// @param signer The signer address that was not in the configuration error InvalidSigner(address signer); @@ -187,6 +187,7 @@ contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { for (uint256 i = 0; i < signers.length; ++i) { // assign indices, detect duplicates address signer = signers[i]; + if (signer == address(0)) revert InvalidSigner(signer); if (s_configs[configId]._positions[signer] != 0) revert DuplicateSigner(signer); s_configs[configId]._positions[signer] = i + 1; } diff --git a/contracts/src/v0.8/keystone/OCR3Capability.sol b/contracts/src/v0.8/keystone/OCR3Capability.sol index 8613a803b2..1ba934b1c4 100644 --- a/contracts/src/v0.8/keystone/OCR3Capability.sol +++ b/contracts/src/v0.8/keystone/OCR3Capability.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {OCR2Base} from "./ocr/OCR2Base.sol"; diff --git a/contracts/src/v0.8/keystone/interfaces/ICapabilityConfiguration.sol b/contracts/src/v0.8/keystone/interfaces/ICapabilityConfiguration.sol index 429c2a1d3a..702d55dba9 100644 --- a/contracts/src/v0.8/keystone/interfaces/ICapabilityConfiguration.sol +++ b/contracts/src/v0.8/keystone/interfaces/ICapabilityConfiguration.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; /// @notice Interface for capability configuration contract. It MUST be /// implemented for a contract to be used as a capability configuration. diff --git a/contracts/src/v0.8/keystone/interfaces/IReceiver.sol b/contracts/src/v0.8/keystone/interfaces/IReceiver.sol index f58c2da7ae..3af340a121 100644 --- a/contracts/src/v0.8/keystone/interfaces/IReceiver.sol +++ b/contracts/src/v0.8/keystone/interfaces/IReceiver.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; /// @title IReceiver - receives keystone reports interface IReceiver { diff --git a/contracts/src/v0.8/keystone/interfaces/IRouter.sol b/contracts/src/v0.8/keystone/interfaces/IRouter.sol index a36c17c14d..95d11b0bb3 100644 --- a/contracts/src/v0.8/keystone/interfaces/IRouter.sol +++ b/contracts/src/v0.8/keystone/interfaces/IRouter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; /// @title IRouter - delivers keystone reports to receiver interface IRouter { diff --git a/contracts/src/v0.8/keystone/ocr/OCR2Abstract.sol b/contracts/src/v0.8/keystone/ocr/OCR2Abstract.sol index 083a404534..3c1e304748 100644 --- a/contracts/src/v0.8/keystone/ocr/OCR2Abstract.sol +++ b/contracts/src/v0.8/keystone/ocr/OCR2Abstract.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; diff --git a/contracts/src/v0.8/keystone/test/BaseTest.t.sol b/contracts/src/v0.8/keystone/test/BaseTest.t.sol index e637406c14..64dc018c3a 100644 --- a/contracts/src/v0.8/keystone/test/BaseTest.t.sol +++ b/contracts/src/v0.8/keystone/test/BaseTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {Test} from "forge-std/Test.sol"; import {Constants} from "./Constants.t.sol"; diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_AddDONTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_AddDONTest.t.sol index fff6623a59..65c85e4f74 100644 --- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_AddDONTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_AddDONTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {BaseTest} from "./BaseTest.t.sol"; import {ICapabilityConfiguration} from "../interfaces/ICapabilityConfiguration.sol"; diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_DeprecateCapabilitiesTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_DeprecateCapabilitiesTest.t.sol index 4d289e7c74..e06fa4a703 100644 --- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_DeprecateCapabilitiesTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_DeprecateCapabilitiesTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {BaseTest} from "./BaseTest.t.sol"; import {CapabilitiesRegistry} from "../CapabilitiesRegistry.sol"; diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetCapabilitiesTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetCapabilitiesTest.t.sol index 9702c62b9c..8f39183ee7 100644 --- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetCapabilitiesTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetCapabilitiesTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {BaseTest} from "./BaseTest.t.sol"; import {CapabilitiesRegistry} from "../CapabilitiesRegistry.sol"; diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetDONsTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetDONsTest.t.sol index a83b1421d3..a79485abad 100644 --- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetDONsTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetDONsTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {BaseTest} from "./BaseTest.t.sol"; diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetHashedCapabilityIdTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetHashedCapabilityIdTest.t.sol index b9a6e6dc97..cdfb0eb643 100644 --- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetHashedCapabilityIdTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetHashedCapabilityIdTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {BaseTest} from "./BaseTest.t.sol"; import {CapabilityConfigurationContract} from "./mocks/CapabilityConfigurationContract.sol"; diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetNodeOperatorsTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetNodeOperatorsTest.t.sol index 36ef201a99..471f4a86ad 100644 --- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetNodeOperatorsTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetNodeOperatorsTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {BaseTest} from "./BaseTest.t.sol"; import {CapabilitiesRegistry} from "../CapabilitiesRegistry.sol"; diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetNodesTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetNodesTest.t.sol index 901e7b9272..a5fe5fa1d1 100644 --- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetNodesTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_GetNodesTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {BaseTest} from "./BaseTest.t.sol"; import {CapabilitiesRegistry} from "../CapabilitiesRegistry.sol"; diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateNodeOperatorsTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateNodeOperatorsTest.t.sol index 721fd35eae..8f6be580f4 100644 --- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateNodeOperatorsTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateNodeOperatorsTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {BaseTest} from "./BaseTest.t.sol"; import {CapabilitiesRegistry} from "../CapabilitiesRegistry.sol"; diff --git a/contracts/src/v0.8/keystone/test/Constants.t.sol b/contracts/src/v0.8/keystone/test/Constants.t.sol index 23c80eea9f..a540a25572 100644 --- a/contracts/src/v0.8/keystone/test/Constants.t.sol +++ b/contracts/src/v0.8/keystone/test/Constants.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; contract Constants { address internal constant ADMIN = address(1); diff --git a/contracts/src/v0.8/keystone/test/KeystoneForwarderBaseTest.t.sol b/contracts/src/v0.8/keystone/test/KeystoneForwarderBaseTest.t.sol index 3b3c406078..c106c2b2b2 100644 --- a/contracts/src/v0.8/keystone/test/KeystoneForwarderBaseTest.t.sol +++ b/contracts/src/v0.8/keystone/test/KeystoneForwarderBaseTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {Test} from "forge-std/Test.sol"; import {Receiver} from "./mocks/Receiver.sol"; diff --git a/contracts/src/v0.8/keystone/test/KeystoneForwarder_ReportTest.t.sol b/contracts/src/v0.8/keystone/test/KeystoneForwarder_ReportTest.t.sol index ccb398fac5..56e421a8c9 100644 --- a/contracts/src/v0.8/keystone/test/KeystoneForwarder_ReportTest.t.sol +++ b/contracts/src/v0.8/keystone/test/KeystoneForwarder_ReportTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {BaseTest} from "./KeystoneForwarderBaseTest.t.sol"; import {IRouter} from "../interfaces/IRouter.sol"; diff --git a/contracts/src/v0.8/keystone/test/KeystoneForwarder_SetConfigTest.t.sol b/contracts/src/v0.8/keystone/test/KeystoneForwarder_SetConfigTest.t.sol index 4b908bb702..5dcf79b38e 100644 --- a/contracts/src/v0.8/keystone/test/KeystoneForwarder_SetConfigTest.t.sol +++ b/contracts/src/v0.8/keystone/test/KeystoneForwarder_SetConfigTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {BaseTest} from "./KeystoneForwarderBaseTest.t.sol"; import {KeystoneForwarder} from "../KeystoneForwarder.sol"; @@ -41,6 +41,14 @@ contract KeystoneForwarder_SetConfigTest is BaseTest { s_forwarder.setConfig(DON_ID, CONFIG_VERSION, F, signers); } + function test_RevertWhen_ProvidingZeroAddressSigner() public { + address[] memory signers = _getSignerAddresses(); + signers[1] = address(0); + + vm.expectRevert(abi.encodeWithSelector(KeystoneForwarder.InvalidSigner.selector, signers[1])); + s_forwarder.setConfig(DON_ID, CONFIG_VERSION, F, signers); + } + function test_SetConfig_FirstTime() public { s_forwarder.setConfig(DON_ID, CONFIG_VERSION, F, _getSignerAddresses()); } diff --git a/contracts/src/v0.8/keystone/test/KeystoneForwarder_TypeAndVersionTest.t.sol b/contracts/src/v0.8/keystone/test/KeystoneForwarder_TypeAndVersionTest.t.sol index 8aad376649..5a5cc70d2b 100644 --- a/contracts/src/v0.8/keystone/test/KeystoneForwarder_TypeAndVersionTest.t.sol +++ b/contracts/src/v0.8/keystone/test/KeystoneForwarder_TypeAndVersionTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {BaseTest} from "./KeystoneForwarderBaseTest.t.sol"; diff --git a/contracts/src/v0.8/keystone/test/mocks/Receiver.sol b/contracts/src/v0.8/keystone/test/mocks/Receiver.sol index 25e8755641..4d6bd2d3ac 100644 --- a/contracts/src/v0.8/keystone/test/mocks/Receiver.sol +++ b/contracts/src/v0.8/keystone/test/mocks/Receiver.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity 0.8.24; import {IReceiver} from "../../interfaces/IReceiver.sol"; diff --git a/core/gethwrappers/keystone/generated/forwarder/forwarder.go b/core/gethwrappers/keystone/generated/forwarder/forwarder.go index 0412241cf7..3b6fba5c7c 100644 --- a/core/gethwrappers/keystone/generated/forwarder/forwarder.go +++ b/core/gethwrappers/keystone/generated/forwarder/forwarder.go @@ -32,7 +32,7 @@ var ( var KeystoneForwarderMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"DuplicateSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"configId\",\"type\":\"uint64\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"received\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedForwarder\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"ForwarderAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"ForwarderRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"result\",\"type\":\"bool\"}],\"name\":\"ReportProcessed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"addForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"}],\"name\":\"clearConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmissionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmissionState\",\"outputs\":[{\"internalType\":\"enumIRouter.TransmissionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmitter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"isForwarder\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"removeForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"reportContext\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"signatures\",\"type\":\"bytes[]\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"validatedReport\",\"type\":\"bytes\"}],\"name\":\"route\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b038481169190911790915581161561009757610097816100b9565b5050306000908152600360205260409020805460ff1916600117905550610162565b336001600160a01b038216036101115760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611b2d80620001726000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379ba50971161008c578063abcef55411610066578063abcef5541461023e578063ee59d26c14610277578063ef6e17a01461028a578063f2fde38b1461029d57600080fd5b806379ba5097146101e05780638864b864146101e85780638da5cb5b1461022057600080fd5b8063354bdd66116100c8578063354bdd661461017957806343c164671461019a5780634d93172d146101ba5780635c41d2fe146101cd57600080fd5b806311289565146100ef578063181f5a7714610104578063233fd52d14610156575b600080fd5b6101026100fd366004611474565b6102b0565b005b6101406040518060400160405280601a81526020017f466f7277617264657220616e6420526f7574657220312e302e3000000000000081525081565b60405161014d919061151f565b60405180910390f35b61016961016436600461158c565b61080d565b604051901515815260200161014d565b61018c610187366004611614565b610a00565b60405190815260200161014d565b6101ad6101a8366004611614565b610a84565b60405161014d9190611679565b6101026101c83660046116ba565b610b09565b6101026101db3660046116ba565b610b85565b610102610c04565b6101fb6101f6366004611614565b610d01565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014d565b60005473ffffffffffffffffffffffffffffffffffffffff166101fb565b61016961024c3660046116ba565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6101026102853660046116e9565b610d41565b610102610298366004611767565b6110ba565b6101026102ab3660046116ba565b61115a565b606d8510156102eb576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600061032f89898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061116e92505050565b67ffffffffffffffff8216600090815260026020526040812080549497509195509193509160ff16908190036103a2576040517fdf3b81ea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b856103ae8260016117c9565b60ff1614610400576103c18160016117c9565b6040517fd6022e8e00000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101879052604401610399565b60008b8b6040516104129291906117e8565b60405190819003812061042b918c908c906020016117f8565b60405160208183030381529060405280519060200120905061044b611301565b60005b888110156106cd573660008b8b8481811061046b5761046b611812565b905060200281019061047d9190611841565b9092509050604181146104c05781816040517f2adfdc300000000000000000000000000000000000000000000000000000000081526004016103999291906118ef565b6000600186848460408181106104d8576104d8611812565b6104ea92013560f81c9050601b6117c9565b6104f860206000878961190b565b61050191611935565b61050f60406020888a61190b565b61051891611935565b6040805160008152602081018083529590955260ff909316928401929092526060830152608082015260a0016020604051602081039080840390855afa158015610566573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8116600090815260028c0160205291822054909350915081900361060c576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610399565b600086826020811061062057610620611812565b602002015173ffffffffffffffffffffffffffffffffffffffff161461068a576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610399565b8186826020811061069d5761069d611812565b73ffffffffffffffffffffffffffffffffffffffff909216602092909202015250506001909201915061044e9050565b50505050505060003073ffffffffffffffffffffffffffffffffffffffff1663233fd52d6106fc8c8686610a00565b338d8d8d602d90606d926107129392919061190b565b8f8f606d9080926107259392919061190b565b6040518863ffffffff1660e01b81526004016107479796959493929190611971565b6020604051808303816000875af1158015610766573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078a91906119d2565b9050817dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916838b73ffffffffffffffffffffffffffffffffffffffff167f3617b009e9785c42daebadb6d3fb553243a4bf586d07ea72d65d80013ce116b5846040516107f9911515815260200190565b60405180910390a450505050505050505050565b3360009081526003602052604081205460ff16610856576040517fd79e123d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008881526004602052604090205473ffffffffffffffffffffffffffffffffffffffff16156108b5576040517fa53dc8ca00000000000000000000000000000000000000000000000000000000815260048101899052602401610399565b600088815260046020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a81169190911790915587163b9003610917575060006109f5565b6040517f805f213200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87169063805f21329061096f9088908890889088906004016119f4565b600060405180830381600087803b15801561098957600080fd5b505af192505050801561099a575060015b6109a6575060006109f5565b50600087815260046020526040902080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905560015b979650505050505050565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018390527fffff000000000000000000000000000000000000000000000000000000000000821660548201526000906056016040516020818303038152906040528051906020012090505b9392505050565b600080610a92858585610a00565b60008181526004602052604090205490915073ffffffffffffffffffffffffffffffffffffffff16610ac8576000915050610a7d565b60008181526004602052604090205474010000000000000000000000000000000000000000900460ff16610afd576002610b00565b60015b95945050505050565b610b11611189565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fb96d15bf9258c7b8df062753a6a262864611fc7b060a5ee2e57e79b85f898d389190a250565b610b8d611189565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f0ea0ce2c048ff45a4a95f2947879de3fb94abec2f152190400cab2d1272a68e79190a250565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610399565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600060046000610d12868686610a00565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff16949350505050565b610d49611189565b8260ff16600003610d86576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f811115610dcb576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101829052601f6024820152604401610399565b610dd6836003611a1b565b60ff168111610e345780610deb846003611a1b565b610df69060016117c9565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260ff166024820152604401610399565b67ffffffff00000000602086901b1663ffffffff85161760005b67ffffffffffffffff8216600090815260026020526040902060010154811015610ee45767ffffffffffffffff8216600090815260026020819052604082206001810180549190920192919084908110610eaa57610eaa611812565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812055600101610e4e565b5060005b82811015610ffc576000848483818110610f0457610f04611812565b9050602002016020810190610f1991906116ba565b67ffffffffffffffff8416600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff86168552909201905290205490915015610fa8576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610399565b610fb3826001611a3e565b67ffffffffffffffff8416600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff90961684529490910190529190912055600101610ee8565b5067ffffffffffffffff81166000908152600260205260409020611024906001018484611320565b5067ffffffffffffffff81166000908152600260205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff87161790555163ffffffff86811691908816907f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a455906110aa90889088908890611a51565b60405180910390a3505050505050565b6110c2611189565b63ffffffff818116602084811b67ffffffff00000000168217600090815260028252604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558051828152928301905291928516917f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a4559160405161114e929190611ab7565b60405180910390a35050565b611162611189565b61116b8161120c565b50565b60218101516045820151608b90920151909260c09290921c91565b60005473ffffffffffffffffffffffffffffffffffffffff16331461120a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610399565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361128b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610399565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6040518061040001604052806020906020820280368337509192915050565b828054828255906000526020600020908101928215611398579160200282015b828111156113985781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff843516178255602090920191600190910190611340565b506113a49291506113a8565b5090565b5b808211156113a457600081556001016113a9565b803573ffffffffffffffffffffffffffffffffffffffff811681146113e157600080fd5b919050565b60008083601f8401126113f857600080fd5b50813567ffffffffffffffff81111561141057600080fd5b60208301915083602082850101111561142857600080fd5b9250929050565b60008083601f84011261144157600080fd5b50813567ffffffffffffffff81111561145957600080fd5b6020830191508360208260051b850101111561142857600080fd5b60008060008060008060006080888a03121561148f57600080fd5b611498886113bd565b9650602088013567ffffffffffffffff808211156114b557600080fd5b6114c18b838c016113e6565b909850965060408a01359150808211156114da57600080fd5b6114e68b838c016113e6565b909650945060608a01359150808211156114ff57600080fd5b5061150c8a828b0161142f565b989b979a50959850939692959293505050565b60006020808352835180602085015260005b8181101561154d57858101830151858201604001528201611531565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600080600080600080600060a0888a0312156115a757600080fd5b873596506115b7602089016113bd565b95506115c5604089016113bd565b9450606088013567ffffffffffffffff808211156115e257600080fd5b6115ee8b838c016113e6565b909650945060808a013591508082111561160757600080fd5b5061150c8a828b016113e6565b60008060006060848603121561162957600080fd5b611632846113bd565b92506020840135915060408401357fffff0000000000000000000000000000000000000000000000000000000000008116811461166e57600080fd5b809150509250925092565b60208101600383106116b4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000602082840312156116cc57600080fd5b610a7d826113bd565b803563ffffffff811681146113e157600080fd5b60008060008060006080868803121561170157600080fd5b61170a866116d5565b9450611718602087016116d5565b9350604086013560ff8116811461172e57600080fd5b9250606086013567ffffffffffffffff81111561174a57600080fd5b6117568882890161142f565b969995985093965092949392505050565b6000806040838503121561177a57600080fd5b611783836116d5565b9150611791602084016116d5565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff81811683821601908111156117e2576117e261179a565b92915050565b8183823760009101908152919050565b838152818360208301376000910160200190815292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261187657600080fd5b83018035915067ffffffffffffffff82111561189157600080fd5b60200191503681900382131561142857600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006119036020830184866118a6565b949350505050565b6000808585111561191b57600080fd5b8386111561192857600080fd5b5050820193919092039150565b803560208310156117e2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525060a060608301526119b160a0830186886118a6565b82810360808401526119c48185876118a6565b9a9950505050505050505050565b6000602082840312156119e457600080fd5b81518015158114610a7d57600080fd5b604081526000611a086040830186886118a6565b82810360208401526109f58185876118a6565b60ff8181168382160290811690818114611a3757611a3761179a565b5092915050565b808201808211156117e2576117e261179a565b60ff8416815260406020808301829052908201839052600090849060608401835b86811015611aab5773ffffffffffffffffffffffffffffffffffffffff611a98856113bd565b1682529282019290820190600101611a72565b50979650505050505050565b60006040820160ff8516835260206040602085015281855180845260608601915060208701935060005b81811015611b1357845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101611ae1565b509097965050505050505056fea164736f6c6343000818000a", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b038481169190911790915581161561009757610097816100b9565b5050306000908152600360205260409020805460ff1916600117905550610162565b336001600160a01b038216036101115760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611b9180620001726000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379ba50971161008c578063abcef55411610066578063abcef5541461023e578063ee59d26c14610277578063ef6e17a01461028a578063f2fde38b1461029d57600080fd5b806379ba5097146101e05780638864b864146101e85780638da5cb5b1461022057600080fd5b8063354bdd66116100c8578063354bdd661461017957806343c164671461019a5780634d93172d146101ba5780635c41d2fe146101cd57600080fd5b806311289565146100ef578063181f5a7714610104578063233fd52d14610156575b600080fd5b6101026100fd3660046114d8565b6102b0565b005b6101406040518060400160405280601a81526020017f466f7277617264657220616e6420526f7574657220312e302e3000000000000081525081565b60405161014d9190611583565b60405180910390f35b6101696101643660046115f0565b61080d565b604051901515815260200161014d565b61018c610187366004611678565b610a00565b60405190815260200161014d565b6101ad6101a8366004611678565b610a84565b60405161014d91906116dd565b6101026101c836600461171e565b610b09565b6101026101db36600461171e565b610b85565b610102610c04565b6101fb6101f6366004611678565b610d01565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014d565b60005473ffffffffffffffffffffffffffffffffffffffff166101fb565b61016961024c36600461171e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b61010261028536600461174d565b610d41565b6101026102983660046117cb565b61111e565b6101026102ab36600461171e565b6111be565b606d8510156102eb576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600061032f89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111d292505050565b67ffffffffffffffff8216600090815260026020526040812080549497509195509193509160ff16908190036103a2576040517fdf3b81ea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b856103ae82600161182d565b60ff1614610400576103c181600161182d565b6040517fd6022e8e00000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101879052604401610399565b60008b8b60405161041292919061184c565b60405190819003812061042b918c908c9060200161185c565b60405160208183030381529060405280519060200120905061044b611365565b60005b888110156106cd573660008b8b8481811061046b5761046b611876565b905060200281019061047d91906118a5565b9092509050604181146104c05781816040517f2adfdc30000000000000000000000000000000000000000000000000000000008152600401610399929190611953565b6000600186848460408181106104d8576104d8611876565b6104ea92013560f81c9050601b61182d565b6104f860206000878961196f565b61050191611999565b61050f60406020888a61196f565b61051891611999565b6040805160008152602081018083529590955260ff909316928401929092526060830152608082015260a0016020604051602081039080840390855afa158015610566573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8116600090815260028c0160205291822054909350915081900361060c576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610399565b600086826020811061062057610620611876565b602002015173ffffffffffffffffffffffffffffffffffffffff161461068a576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610399565b8186826020811061069d5761069d611876565b73ffffffffffffffffffffffffffffffffffffffff909216602092909202015250506001909201915061044e9050565b50505050505060003073ffffffffffffffffffffffffffffffffffffffff1663233fd52d6106fc8c8686610a00565b338d8d8d602d90606d926107129392919061196f565b8f8f606d9080926107259392919061196f565b6040518863ffffffff1660e01b815260040161074797969594939291906119d5565b6020604051808303816000875af1158015610766573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078a9190611a36565b9050817dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916838b73ffffffffffffffffffffffffffffffffffffffff167f3617b009e9785c42daebadb6d3fb553243a4bf586d07ea72d65d80013ce116b5846040516107f9911515815260200190565b60405180910390a450505050505050505050565b3360009081526003602052604081205460ff16610856576040517fd79e123d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008881526004602052604090205473ffffffffffffffffffffffffffffffffffffffff16156108b5576040517fa53dc8ca00000000000000000000000000000000000000000000000000000000815260048101899052602401610399565b600088815260046020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a81169190911790915587163b9003610917575060006109f5565b6040517f805f213200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87169063805f21329061096f908890889088908890600401611a58565b600060405180830381600087803b15801561098957600080fd5b505af192505050801561099a575060015b6109a6575060006109f5565b50600087815260046020526040902080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905560015b979650505050505050565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018390527fffff000000000000000000000000000000000000000000000000000000000000821660548201526000906056016040516020818303038152906040528051906020012090505b9392505050565b600080610a92858585610a00565b60008181526004602052604090205490915073ffffffffffffffffffffffffffffffffffffffff16610ac8576000915050610a7d565b60008181526004602052604090205474010000000000000000000000000000000000000000900460ff16610afd576002610b00565b60015b95945050505050565b610b116111ed565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fb96d15bf9258c7b8df062753a6a262864611fc7b060a5ee2e57e79b85f898d389190a250565b610b8d6111ed565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f0ea0ce2c048ff45a4a95f2947879de3fb94abec2f152190400cab2d1272a68e79190a250565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610399565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600060046000610d12868686610a00565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff16949350505050565b610d496111ed565b8260ff16600003610d86576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f811115610dcb576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101829052601f6024820152604401610399565b610dd6836003611a7f565b60ff168111610e345780610deb846003611a7f565b610df690600161182d565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260ff166024820152604401610399565b67ffffffff00000000602086901b1663ffffffff85161760005b67ffffffffffffffff8216600090815260026020526040902060010154811015610ee45767ffffffffffffffff8216600090815260026020819052604082206001810180549190920192919084908110610eaa57610eaa611876565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812055600101610e4e565b5060005b82811015611060576000848483818110610f0457610f04611876565b9050602002016020810190610f19919061171e565b905073ffffffffffffffffffffffffffffffffffffffff8116610f80576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610399565b67ffffffffffffffff8316600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290920190529020541561100c576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610399565b611017826001611aa2565b67ffffffffffffffff8416600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff90961684529490910190529190912055600101610ee8565b5067ffffffffffffffff81166000908152600260205260409020611088906001018484611384565b5067ffffffffffffffff81166000908152600260205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff87161790555163ffffffff86811691908816907f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a4559061110e90889088908890611ab5565b60405180910390a3505050505050565b6111266111ed565b63ffffffff818116602084811b67ffffffff00000000168217600090815260028252604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558051828152928301905291928516917f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a455916040516111b2929190611b1b565b60405180910390a35050565b6111c66111ed565b6111cf81611270565b50565b60218101516045820151608b90920151909260c09290921c91565b60005473ffffffffffffffffffffffffffffffffffffffff16331461126e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610399565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036112ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610399565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6040518061040001604052806020906020820280368337509192915050565b8280548282559060005260206000209081019282156113fc579160200282015b828111156113fc5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8435161782556020909201916001909101906113a4565b5061140892915061140c565b5090565b5b80821115611408576000815560010161140d565b803573ffffffffffffffffffffffffffffffffffffffff8116811461144557600080fd5b919050565b60008083601f84011261145c57600080fd5b50813567ffffffffffffffff81111561147457600080fd5b60208301915083602082850101111561148c57600080fd5b9250929050565b60008083601f8401126114a557600080fd5b50813567ffffffffffffffff8111156114bd57600080fd5b6020830191508360208260051b850101111561148c57600080fd5b60008060008060008060006080888a0312156114f357600080fd5b6114fc88611421565b9650602088013567ffffffffffffffff8082111561151957600080fd5b6115258b838c0161144a565b909850965060408a013591508082111561153e57600080fd5b61154a8b838c0161144a565b909650945060608a013591508082111561156357600080fd5b506115708a828b01611493565b989b979a50959850939692959293505050565b60006020808352835180602085015260005b818110156115b157858101830151858201604001528201611595565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600080600080600080600060a0888a03121561160b57600080fd5b8735965061161b60208901611421565b955061162960408901611421565b9450606088013567ffffffffffffffff8082111561164657600080fd5b6116528b838c0161144a565b909650945060808a013591508082111561166b57600080fd5b506115708a828b0161144a565b60008060006060848603121561168d57600080fd5b61169684611421565b92506020840135915060408401357fffff000000000000000000000000000000000000000000000000000000000000811681146116d257600080fd5b809150509250925092565b6020810160038310611718577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60006020828403121561173057600080fd5b610a7d82611421565b803563ffffffff8116811461144557600080fd5b60008060008060006080868803121561176557600080fd5b61176e86611739565b945061177c60208701611739565b9350604086013560ff8116811461179257600080fd5b9250606086013567ffffffffffffffff8111156117ae57600080fd5b6117ba88828901611493565b969995985093965092949392505050565b600080604083850312156117de57600080fd5b6117e783611739565b91506117f560208401611739565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff8181168382160190811115611846576118466117fe565b92915050565b8183823760009101908152919050565b838152818360208301376000910160200190815292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126118da57600080fd5b83018035915067ffffffffffffffff8211156118f557600080fd5b60200191503681900382131561148c57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60208152600061196760208301848661190a565b949350505050565b6000808585111561197f57600080fd5b8386111561198c57600080fd5b5050820193919092039150565b80356020831015611846577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525060a06060830152611a1560a08301868861190a565b8281036080840152611a2881858761190a565b9a9950505050505050505050565b600060208284031215611a4857600080fd5b81518015158114610a7d57600080fd5b604081526000611a6c60408301868861190a565b82810360208401526109f581858761190a565b60ff8181168382160290811690818114611a9b57611a9b6117fe565b5092915050565b80820180821115611846576118466117fe565b60ff8416815260406020808301829052908201839052600090849060608401835b86811015611b0f5773ffffffffffffffffffffffffffffffffffffffff611afc85611421565b1682529282019290820190600101611ad6565b50979650505050505050565b60006040820160ff8516835260206040602085015281855180845260608601915060208701935060005b81811015611b7757845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101611b45565b509097965050505050505056fea164736f6c6343000818000a", } var KeystoneForwarderABI = KeystoneForwarderMetaData.ABI diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 7d25f651dd..98d0a4bd02 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,5 +1,5 @@ GETH_VERSION: 1.13.8 capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin 6d2e3aa3a6f3aed2cf24b613743bb9ae4b9558f48a6864dc03b8b0ebb37235e3 feeds_consumer: ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin f098e25df6afc100425fcad7f5107aec0844cc98315117e49da139a179d0eead -forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin dc98a86a3775ead987b79d5b6079ee0e26f31c0626032bdd6508f986e2423227 +forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin 21a203d62a69338a5ca260907a31727421114ca25679330ada5d68f0092725bf ocr3_capability: ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.bin 8bf0f53f222efce7143dea6134552eb26ea1eef845407b4475a0d79b7d7ba9f8 From 2a032e83a5e09ae128e8c751779a7d1eebb729ea Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Fri, 2 Aug 2024 10:35:40 -0500 Subject: [PATCH 028/432] Update AutoPurge config interface and add header for Scroll API (#13999) * Updated AutoPurge heuristic configs to be optional * Added content-type header for Scroll stuck tx API call * Fixed linting * Added changeset --- .changeset/violet-clouds-rhyme.md | 5 ++++ .../evm/config/chain_scoped_transactions.go | 8 +++---- core/chains/evm/config/config.go | 4 ++-- core/chains/evm/txmgr/stuck_tx_detector.go | 23 ++++++++++++++----- .../evm/txmgr/stuck_tx_detector_test.go | 16 ++++++------- 5 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 .changeset/violet-clouds-rhyme.md diff --git a/.changeset/violet-clouds-rhyme.md b/.changeset/violet-clouds-rhyme.md new file mode 100644 index 0000000000..b6db0e85c4 --- /dev/null +++ b/.changeset/violet-clouds-rhyme.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Updated AutoPurge.Threshold and AutoPurge.MinAttempts configs to only be required for heuristic and added content-type header for Scroll API #internal diff --git a/core/chains/evm/config/chain_scoped_transactions.go b/core/chains/evm/config/chain_scoped_transactions.go index 87031a4c66..27edb12648 100644 --- a/core/chains/evm/config/chain_scoped_transactions.go +++ b/core/chains/evm/config/chain_scoped_transactions.go @@ -47,12 +47,12 @@ func (a *autoPurgeConfig) Enabled() bool { return *a.c.Enabled } -func (a *autoPurgeConfig) Threshold() uint32 { - return *a.c.Threshold +func (a *autoPurgeConfig) Threshold() *uint32 { + return a.c.Threshold } -func (a *autoPurgeConfig) MinAttempts() uint32 { - return *a.c.MinAttempts +func (a *autoPurgeConfig) MinAttempts() *uint32 { + return a.c.MinAttempts } func (a *autoPurgeConfig) DetectionApiUrl() *url.URL { diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index b0a5772f73..3ccdfeea8b 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -110,8 +110,8 @@ type Transactions interface { type AutoPurgeConfig interface { Enabled() bool - Threshold() uint32 - MinAttempts() uint32 + Threshold() *uint32 + MinAttempts() *uint32 DetectionApiUrl() *url.URL } diff --git a/core/chains/evm/txmgr/stuck_tx_detector.go b/core/chains/evm/txmgr/stuck_tx_detector.go index 1beb857af8..5901be0b02 100644 --- a/core/chains/evm/txmgr/stuck_tx_detector.go +++ b/core/chains/evm/txmgr/stuck_tx_detector.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "math/big" "net/http" @@ -37,8 +38,8 @@ type stuckTxDetectorTxStore interface { type stuckTxDetectorConfig interface { Enabled() bool - Threshold() uint32 - MinAttempts() uint32 + Threshold() *uint32 + MinAttempts() *uint32 DetectionApiUrl() *url.URL } @@ -78,7 +79,7 @@ func NewStuckTxDetector(lggr logger.Logger, chainID *big.Int, chainType chaintyp func (d *stuckTxDetector) LoadPurgeBlockNumMap(ctx context.Context, addresses []common.Address) error { // Skip loading purge block num map if auto-purge feature disabled or Threshold is set to 0 - if !d.cfg.Enabled() || d.cfg.Threshold() == 0 { + if !d.cfg.Enabled() || d.cfg.Threshold() == nil || *d.cfg.Threshold() == 0 { return nil } d.purgeBlockNumLock.Lock() @@ -172,6 +173,11 @@ func (d *stuckTxDetector) FindUnconfirmedTxWithLowestNonce(ctx context.Context, // 4. If 3 is true, check if the latest attempt's gas price is higher than what our gas estimator's GetFee method returns // 5. If 4 is true, the transaction is likely stuck due to overflow func (d *stuckTxDetector) detectStuckTransactionsHeuristic(ctx context.Context, txs []Tx, blockNum int64) ([]Tx, error) { + if d.cfg.Threshold() == nil || d.cfg.MinAttempts() == nil { + err := errors.New("missing required configs for the stuck transaction heuristic. Transactions.AutoPurge.Threshold and Transactions.AutoPurge.MinAttempts are required") + d.lggr.Error(err.Error()) + return txs, err + } d.purgeBlockNumLock.RLock() defer d.purgeBlockNumLock.RUnlock() // Get gas price from internal gas estimator @@ -187,17 +193,17 @@ func (d *stuckTxDetector) detectStuckTransactionsHeuristic(ctx context.Context, d.purgeBlockNumLock.RLock() lastPurgeBlockNum := d.purgeBlockNumMap[tx.FromAddress] d.purgeBlockNumLock.RUnlock() - if lastPurgeBlockNum > blockNum-int64(d.cfg.Threshold()) { + if lastPurgeBlockNum > blockNum-int64(*d.cfg.Threshold()) { continue } // Tx attempts are loaded from newest to oldest oldestBroadcastAttempt, newestBroadcastAttempt, broadcastedAttemptsCount := findBroadcastedAttempts(tx) // 2. Check if Threshold amount of blocks have passed since the oldest attempt's broadcast block num - if *oldestBroadcastAttempt.BroadcastBeforeBlockNum > blockNum-int64(d.cfg.Threshold()) { + if *oldestBroadcastAttempt.BroadcastBeforeBlockNum > blockNum-int64(*d.cfg.Threshold()) { continue } // 3. Check if the transaction has at least MinAttempts amount of broadcasted attempts - if broadcastedAttemptsCount < d.cfg.MinAttempts() { + if broadcastedAttemptsCount < *d.cfg.MinAttempts() { continue } // 4. Check if the newest broadcasted attempt's gas price is higher than what our gas estimator's GetFee method returns @@ -278,6 +284,10 @@ func (d *stuckTxDetector) detectStuckTransactionsScroll(ctx context.Context, txs if err != nil { return nil, fmt.Errorf("failed to make new request with context: %w", err) } + + // Add Content-Type header + postReq.Header.Add("Content-Type", "application/json") + // Send request resp, err := d.httpClient.Do(postReq) if err != nil { @@ -287,6 +297,7 @@ func (d *stuckTxDetector) detectStuckTransactionsScroll(ctx context.Context, txs if resp.StatusCode != 200 { return nil, fmt.Errorf("request failed with status %d", resp.StatusCode) } + // Decode the response into expected type scrollResp := new(scrollResponse) err = json.NewDecoder(resp.Body).Decode(scrollResp) diff --git a/core/chains/evm/txmgr/stuck_tx_detector_test.go b/core/chains/evm/txmgr/stuck_tx_detector_test.go index e980527c98..5f0d73be18 100644 --- a/core/chains/evm/txmgr/stuck_tx_detector_test.go +++ b/core/chains/evm/txmgr/stuck_tx_detector_test.go @@ -78,8 +78,8 @@ func TestStuckTxDetector_LoadPurgeBlockNumMap(t *testing.T) { autoPurgeMinAttempts := uint32(3) autoPurgeCfg := testAutoPurgeConfig{ enabled: true, // Enable auto-purge feature for testing - threshold: autoPurgeThreshold, - minAttempts: autoPurgeMinAttempts, + threshold: &autoPurgeThreshold, + minAttempts: &autoPurgeMinAttempts, } stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), autoPurgeCfg, feeEstimator, txStore, ethClient) @@ -176,8 +176,8 @@ func TestStuckTxDetector_DetectStuckTransactionsHeuristic(t *testing.T) { autoPurgeMinAttempts := uint32(3) autoPurgeCfg := testAutoPurgeConfig{ enabled: true, // Enable auto-purge feature for testing - threshold: autoPurgeThreshold, - minAttempts: autoPurgeMinAttempts, + threshold: &autoPurgeThreshold, + minAttempts: &autoPurgeMinAttempts, } blockNum := int64(100) stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), autoPurgeCfg, feeEstimator, txStore, ethClient) @@ -423,12 +423,12 @@ func mustInsertUnconfirmedEthTxWithBroadcastPurgeAttempt(t *testing.T, txStore t type testAutoPurgeConfig struct { enabled bool - threshold uint32 - minAttempts uint32 + threshold *uint32 + minAttempts *uint32 detectionApiUrl *url.URL } func (t testAutoPurgeConfig) Enabled() bool { return t.enabled } -func (t testAutoPurgeConfig) Threshold() uint32 { return t.threshold } -func (t testAutoPurgeConfig) MinAttempts() uint32 { return t.minAttempts } +func (t testAutoPurgeConfig) Threshold() *uint32 { return t.threshold } +func (t testAutoPurgeConfig) MinAttempts() *uint32 { return t.minAttempts } func (t testAutoPurgeConfig) DetectionApiUrl() *url.URL { return t.detectionApiUrl } From 82accfff5c445fd1d29a26607234eba73e6b30fd Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Fri, 2 Aug 2024 18:22:49 +0200 Subject: [PATCH 029/432] fix keystone e2e test dispatcher to correctly replicate duplicate registration behaviour (#14018) --- .changeset/happy-adults-wash.md | 5 +++++ .../integration_tests/mock_dispatcher.go | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 .changeset/happy-adults-wash.md diff --git a/.changeset/happy-adults-wash.md b/.changeset/happy-adults-wash.md new file mode 100644 index 0000000000..738f8998b2 --- /dev/null +++ b/.changeset/happy-adults-wash.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal fix to keystone e2e test dispatcher to correctly mock duplicate registration error diff --git a/core/capabilities/integration_tests/mock_dispatcher.go b/core/capabilities/integration_tests/mock_dispatcher.go index f685f0ad2e..1230e59427 100644 --- a/core/capabilities/integration_tests/mock_dispatcher.go +++ b/core/capabilities/integration_tests/mock_dispatcher.go @@ -9,6 +9,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" @@ -58,6 +59,7 @@ func (a *testAsyncMessageBroker) NewDispatcherForNode(nodePeerID p2ptypes.PeerID return &brokerDispatcher{ callerPeerID: nodePeerID, broker: a, + receivers: map[key]remotetypes.Receiver{}, } } @@ -158,6 +160,14 @@ type broker interface { type brokerDispatcher struct { callerPeerID p2ptypes.PeerID broker broker + + receivers map[key]remotetypes.Receiver + mu sync.Mutex +} + +type key struct { + capId string + donId uint32 } func (t *brokerDispatcher) Send(peerID p2ptypes.PeerID, msgBody *remotetypes.MessageBody) error { @@ -171,6 +181,15 @@ func (t *brokerDispatcher) Send(peerID p2ptypes.PeerID, msgBody *remotetypes.Mes } func (t *brokerDispatcher) SetReceiver(capabilityId string, donId uint32, receiver remotetypes.Receiver) error { + t.mu.Lock() + defer t.mu.Unlock() + k := key{capabilityId, donId} + _, ok := t.receivers[k] + if ok { + return fmt.Errorf("%w: receiver already exists for capability %s and don %d", remote.ErrReceiverExists, capabilityId, donId) + } + t.receivers[k] = receiver + t.broker.(*testAsyncMessageBroker).registerReceiverNode(t.callerPeerID, capabilityId, donId, receiver) return nil } From af7dab653b10d8c201a2e6a8b3a587e43abd220c Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Fri, 2 Aug 2024 19:06:45 +0200 Subject: [PATCH 030/432] common/headtracker: improve health error (#13966) --- common/headtracker/head_tracker.go | 8 ++++---- integration-tests/reorg/automation_reorg_test.go | 2 +- integration-tests/smoke/vrfv2_test.go | 2 +- integration-tests/smoke/vrfv2plus_test.go | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/common/headtracker/head_tracker.go b/common/headtracker/head_tracker.go index afa5d931ee..851458591b 100644 --- a/common/headtracker/head_tracker.go +++ b/common/headtracker/head_tracker.go @@ -236,8 +236,7 @@ func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) handleNewHead(ctx context.Context "blockDifficulty", head.BlockDifficulty(), ) - err := ht.headSaver.Save(ctx, head) - if ctx.Err() != nil { + if err := ht.headSaver.Save(ctx, head); ctx.Err() != nil { return nil } else if err != nil { return fmt.Errorf("failed to save head: %#v: %w", head, err) @@ -264,8 +263,9 @@ func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) handleNewHead(ctx context.Context if prevLatestFinalized != nil && head.BlockNumber() <= prevLatestFinalized.BlockNumber() { promOldHead.WithLabelValues(ht.chainID.String()).Inc() - ht.log.Criticalf("Got very old block with number %d (highest seen was %d). This is a problem and either means a very deep re-org occurred, one of the RPC nodes has gotten far out of sync, or the chain went backwards in block numbers. This node may not function correctly without manual intervention.", head.BlockNumber(), prevHead.BlockNumber()) - ht.SvcErrBuffer.Append(errors.New("got very old block")) + err := fmt.Errorf("got very old block with number %d (highest seen was %d)", head.BlockNumber(), prevHead.BlockNumber()) + ht.log.Critical("Got very old block. Either a very deep re-org occurred, one of the RPC nodes has gotten far out of sync, or the chain went backwards in block numbers. This node may not function correctly without manual intervention.", "err", err) + ht.SvcErrBuffer.Append(err) } } return nil diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index 1b9cf5819b..808e394d69 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -43,7 +43,7 @@ var ( ) var logScannerSettings = test_env.GetDefaultChainlinkNodeLogScannerSettingsWithExtraAllowedMessages(testreporters.NewAllowedLogMessage( - "Got very old block with number", + "Got very old block.", "It is expected, because we are causing reorgs", zapcore.DPanicLevel, testreporters.WarnAboutAllowedMsgs_No, diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index 7a53d2c57c..48fbc0071c 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -1063,7 +1063,7 @@ func TestVRFV2NodeReorg(t *testing.T) { chainlinkNodeLogScannerSettings := test_env.GetDefaultChainlinkNodeLogScannerSettingsWithExtraAllowedMessages( testreporters.NewAllowedLogMessage( - "This is a problem and either means a very deep re-org occurred", + "Got very old block.", "Test is expecting a reorg to occur", zapcore.DPanicLevel, testreporters.WarnAboutAllowedMsgs_No), diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index f519aa6cd5..da2989d8fc 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -1959,7 +1959,7 @@ func TestVRFv2PlusNodeReorg(t *testing.T) { } chainlinkNodeLogScannerSettings := test_env.GetDefaultChainlinkNodeLogScannerSettingsWithExtraAllowedMessages( testreporters.NewAllowedLogMessage( - "This is a problem and either means a very deep re-org occurred", + "Got very old block.", "Test is expecting a reorg to occur", zapcore.DPanicLevel, testreporters.WarnAboutAllowedMsgs_No), From 05ef7fdbb115f55a85bcbbc5402350818501e1f5 Mon Sep 17 00:00:00 2001 From: martin-cll <121895364+martin-cll@users.noreply.github.com> Date: Fri, 2 Aug 2024 19:17:10 +0200 Subject: [PATCH 031/432] MERC-6004 Add Mercury v4 schema (#13862) * Add Mercury v4 * Uncomment out test * Add v4 telemetry * MERC-6004 Fix build * Update chainlink-common * Add changeset * Update market status proto enum values * Add changeset hashtag --- .changeset/eight-rocks-notice.md | 5 + core/scripts/go.mod | 4 +- core/scripts/go.sum | 8 +- .../ocr2/plugins/mercury/config/config.go | 4 +- .../ocr2/plugins/mercury/helpers_test.go | 95 +++++ .../ocr2/plugins/mercury/integration_test.go | 323 +++++++++++++++- core/services/ocr2/plugins/mercury/plugin.go | 46 +++ .../ocr2/plugins/mercury/plugin_test.go | 32 ++ core/services/ocrcommon/telemetry.go | 29 ++ core/services/relay/evm/evm.go | 6 +- .../services/relay/evm/mercury/utils/feeds.go | 2 + .../relay/evm/mercury/v4/data_source.go | 290 +++++++++++++++ .../relay/evm/mercury/v4/data_source_test.go | 349 ++++++++++++++++++ .../mercury/v4/reportcodec/report_codec.go | 82 ++++ .../v4/reportcodec/report_codec_test.go | 163 ++++++++ .../relay/evm/mercury/v4/types/types.go | 58 +++ core/services/relay/evm/mercury_provider.go | 10 +- .../synchronization/telem/telem.pb.go | 10 +- .../telem/telem_automation_custom.pb.go | 12 +- .../telem/telem_enhanced_ea.pb.go | 6 +- .../telem/telem_enhanced_ea_mercury.pb.go | 128 +++++-- .../telem/telem_enhanced_ea_mercury.proto | 9 + .../telem/telem_functions_request.pb.go | 6 +- go.mod | 4 +- go.sum | 8 +- integration-tests/go.mod | 4 +- integration-tests/go.sum | 8 +- integration-tests/load/go.mod | 4 +- integration-tests/load/go.sum | 8 +- 29 files changed, 1630 insertions(+), 83 deletions(-) create mode 100644 .changeset/eight-rocks-notice.md create mode 100644 core/services/relay/evm/mercury/v4/data_source.go create mode 100644 core/services/relay/evm/mercury/v4/data_source_test.go create mode 100644 core/services/relay/evm/mercury/v4/reportcodec/report_codec.go create mode 100644 core/services/relay/evm/mercury/v4/reportcodec/report_codec_test.go create mode 100644 core/services/relay/evm/mercury/v4/types/types.go diff --git a/.changeset/eight-rocks-notice.md b/.changeset/eight-rocks-notice.md new file mode 100644 index 0000000000..230abaec48 --- /dev/null +++ b/.changeset/eight-rocks-notice.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +New Mercury v4 report schema #added diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 5cd4aaf63c..4ee443d46f 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 @@ -271,7 +271,7 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index c383b6bf81..3ae26beb63 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1184,12 +1184,12 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 h1:6s4cTIE3NbATxWLrD5JLCq097PC5Y4GKK/Kk4fhURpY= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc h1:nNZqLasN8y5huDKX76JUZtni7WkUI36J61//czbJpDM= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa/go.mod h1:wZvLHX/Sd9hskN51016cTFcT3G62KXVa6xbVDS7tRjc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= diff --git a/core/services/ocr2/plugins/mercury/config/config.go b/core/services/ocr2/plugins/mercury/config/config.go index 5763b883ac..40854bd8c0 100644 --- a/core/services/ocr2/plugins/mercury/config/config.go +++ b/core/services/ocr2/plugins/mercury/config/config.go @@ -108,7 +108,7 @@ func ValidatePluginConfig(config PluginConfig, feedID mercuryutils.FeedID) (merr if config.NativeFeedID != nil { merr = errors.Join(merr, errors.New("nativeFeedID may not be specified for v1 jobs")) } - case 2, 3: + case 2, 3, 4: if config.LinkFeedID == nil { merr = errors.Join(merr, fmt.Errorf("linkFeedID must be specified for v%d jobs", feedID.Version())) } @@ -119,7 +119,7 @@ func ValidatePluginConfig(config PluginConfig, feedID mercuryutils.FeedID) (merr merr = errors.Join(merr, fmt.Errorf("initialBlockNumber may not be specified for v%d jobs", feedID.Version())) } default: - merr = errors.Join(merr, fmt.Errorf("got unsupported schema version %d; supported versions are 1,2,3", feedID.Version())) + merr = errors.Join(merr, fmt.Errorf("got unsupported schema version %d; supported versions are 1,2,3,4", feedID.Version())) } return merr diff --git a/core/services/ocr2/plugins/mercury/helpers_test.go b/core/services/ocr2/plugins/mercury/helpers_test.go index 43d709453b..9691e8d4fa 100644 --- a/core/services/ocr2/plugins/mercury/helpers_test.go +++ b/core/services/ocr2/plugins/mercury/helpers_test.go @@ -121,6 +121,7 @@ type Feed struct { baseBenchmarkPrice *big.Int baseBid *big.Int baseAsk *big.Int + baseMarketStatus uint32 } func randomFeedID(version uint16) [32]byte { @@ -467,3 +468,97 @@ chainID = 1337 nativeFeedID, )) } + +func addV4MercuryJob( + t *testing.T, + node Node, + i int, + verifierAddress common.Address, + bootstrapPeerID string, + bootstrapNodePort int, + bmBridge, + bidBridge, + askBridge, + marketStatusBridge string, + servers map[string]string, + clientPubKey ed25519.PublicKey, + feedName string, + feedID [32]byte, + linkFeedID [32]byte, + nativeFeedID [32]byte, +) { + srvs := make([]string, 0, len(servers)) + for u, k := range servers { + srvs = append(srvs, fmt.Sprintf("%q = %q", u, k)) + } + serversStr := fmt.Sprintf("{ %s }", strings.Join(srvs, ", ")) + + node.AddJob(t, fmt.Sprintf(` +type = "offchainreporting2" +schemaVersion = 1 +name = "mercury-%[1]d-%[11]s" +forwardingAllowed = false +maxTaskDuration = "1s" +contractID = "%[2]s" +feedID = "0x%[10]x" +contractConfigTrackerPollInterval = "1s" +ocrKeyBundleID = "%[3]s" +p2pv2Bootstrappers = [ + "%[4]s" +] +relay = "evm" +pluginType = "mercury" +transmitterID = "%[9]x" +observationSource = """ + // Benchmark Price + price1 [type=bridge name="%[5]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; + price1_parse [type=jsonparse path="result"]; + price1_multiply [type=multiply times=100000000 index=0]; + + price1 -> price1_parse -> price1_multiply; + + // Bid + bid [type=bridge name="%[6]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; + bid_parse [type=jsonparse path="result"]; + bid_multiply [type=multiply times=100000000 index=1]; + + bid -> bid_parse -> bid_multiply; + + // Ask + ask [type=bridge name="%[7]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; + ask_parse [type=jsonparse path="result"]; + ask_multiply [type=multiply times=100000000 index=2]; + + ask -> ask_parse -> ask_multiply; + + // Market Status + marketstatus [type=bridge name="%[14]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; + marketstatus_parse [type=jsonparse path="result" index=3]; + + marketstatus -> marketstatus_parse; +""" + +[pluginConfig] +servers = %[8]s +linkFeedID = "0x%[12]x" +nativeFeedID = "0x%[13]x" + +[relayConfig] +chainID = 1337 + `, + i, + verifierAddress, + node.KeyBundle.ID(), + fmt.Sprintf("%s@127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), + bmBridge, + bidBridge, + askBridge, + serversStr, + clientPubKey, + feedID, + feedName, + linkFeedID, + nativeFeedID, + marketStatusBridge, + )) +} diff --git a/core/services/ocr2/plugins/mercury/integration_test.go b/core/services/ocr2/plugins/mercury/integration_test.go index 832a39237e..9e34e9da8b 100644 --- a/core/services/ocr2/plugins/mercury/integration_test.go +++ b/core/services/ocr2/plugins/mercury/integration_test.go @@ -24,22 +24,21 @@ import ( "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/hashicorp/consul/sdk/freeport" "github.com/shopspring/decimal" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - "go.uber.org/zap/zaptest/observer" - "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/wsrpc/credentials" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" v1 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1" v2 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" v3 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" + v4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" datastreamsmercury "github.com/smartcontractkit/chainlink-data-streams/mercury" - "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" token "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" @@ -56,6 +55,7 @@ import ( reportcodecv1 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1/reportcodec" reportcodecv2 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/reportcodec" reportcodecv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" + reportcodecv4 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v4/reportcodec" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) @@ -146,9 +146,9 @@ func integration_MercuryV1(t *testing.T) { pError := atomic.Int64{} // feeds - btcFeed := Feed{"BTC/USD", randomFeedID(1), big.NewInt(20_000 * multiplier), big.NewInt(19_997 * multiplier), big.NewInt(20_004 * multiplier)} - ethFeed := Feed{"ETH/USD", randomFeedID(1), big.NewInt(1_568 * multiplier), big.NewInt(1_566 * multiplier), big.NewInt(1_569 * multiplier)} - linkFeed := Feed{"LINK/USD", randomFeedID(1), big.NewInt(7150 * multiplier / 1000), big.NewInt(7123 * multiplier / 1000), big.NewInt(7177 * multiplier / 1000)} + btcFeed := Feed{"BTC/USD", randomFeedID(1), big.NewInt(20_000 * multiplier), big.NewInt(19_997 * multiplier), big.NewInt(20_004 * multiplier), 0} + ethFeed := Feed{"ETH/USD", randomFeedID(1), big.NewInt(1_568 * multiplier), big.NewInt(1_566 * multiplier), big.NewInt(1_569 * multiplier), 0} + linkFeed := Feed{"LINK/USD", randomFeedID(1), big.NewInt(7150 * multiplier / 1000), big.NewInt(7123 * multiplier / 1000), big.NewInt(7177 * multiplier / 1000), 0} feeds := []Feed{btcFeed, ethFeed, linkFeed} feedM := make(map[[32]byte]Feed, len(feeds)) for i := range feeds { @@ -1036,3 +1036,308 @@ func integration_MercuryV3(t *testing.T) { } }) } + +func TestIntegration_MercuryV4(t *testing.T) { + t.Parallel() + + integration_MercuryV4(t) +} + +func integration_MercuryV4(t *testing.T) { + ctx := testutils.Context(t) + var logObservers []*observer.ObservedLogs + t.Cleanup(func() { + detectPanicLogs(t, logObservers) + }) + + testStartTimeStamp := uint32(time.Now().Unix()) + + // test vars + // pError is the probability that an EA will return an error instead of a result, as integer percentage + // pError = 0 means it will never return error + pError := atomic.Int64{} + + // feeds + btcFeed := Feed{ + name: "BTC/USD", + id: randomFeedID(4), + baseBenchmarkPrice: big.NewInt(20_000 * multiplier), + baseBid: big.NewInt(19_997 * multiplier), + baseAsk: big.NewInt(20_004 * multiplier), + baseMarketStatus: 1, + } + ethFeed := Feed{ + name: "ETH/USD", + id: randomFeedID(4), + baseBenchmarkPrice: big.NewInt(1_568 * multiplier), + baseBid: big.NewInt(1_566 * multiplier), + baseAsk: big.NewInt(1_569 * multiplier), + baseMarketStatus: 2, + } + linkFeed := Feed{ + name: "LINK/USD", + id: randomFeedID(4), + baseBenchmarkPrice: big.NewInt(7150 * multiplier / 1000), + baseBid: big.NewInt(7123 * multiplier / 1000), + baseAsk: big.NewInt(7177 * multiplier / 1000), + baseMarketStatus: 3, + } + feeds := []Feed{btcFeed, ethFeed, linkFeed} + feedM := make(map[[32]byte]Feed, len(feeds)) + for i := range feeds { + feedM[feeds[i].id] = feeds[i] + } + + clientCSAKeys := make([]csakey.KeyV2, n+1) + clientPubKeys := make([]ed25519.PublicKey, n+1) + for i := 0; i < n+1; i++ { + k := big.NewInt(int64(i)) + key := csakey.MustNewV2XXXTestingOnly(k) + clientCSAKeys[i] = key + clientPubKeys[i] = key.PublicKey + } + + // Test multi-send to three servers + const nSrvs = 3 + reqChs := make([]chan request, nSrvs) + servers := make(map[string]string) + for i := 0; i < nSrvs; i++ { + k := csakey.MustNewV2XXXTestingOnly(big.NewInt(int64(-(i + 1)))) + reqs := make(chan request, 100) + srv := NewMercuryServer(t, ed25519.PrivateKey(k.Raw()), reqs, func() []byte { + report, err := (&reportcodecv4.ReportCodec{}).BuildReport(v4.ReportFields{BenchmarkPrice: big.NewInt(234567), Bid: big.NewInt(1), Ask: big.NewInt(1), LinkFee: big.NewInt(1), NativeFee: big.NewInt(1), MarketStatus: 1}) + if err != nil { + panic(err) + } + return report + }) + serverURL := startMercuryServer(t, srv, clientPubKeys) + reqChs[i] = reqs + servers[serverURL] = fmt.Sprintf("%x", k.PublicKey) + } + chainID := testutils.SimulatedChainID + + steve, backend, verifier, verifierAddress := setupBlockchain(t) + + // Setup bootstrap + oracle nodes + bootstrapNodePort := freeport.GetOne(t) + appBootstrap, bootstrapPeerID, _, bootstrapKb, observedLogs := setupNode(t, bootstrapNodePort, "bootstrap_mercury", backend, clientCSAKeys[n]) + bootstrapNode := Node{App: appBootstrap, KeyBundle: bootstrapKb} + logObservers = append(logObservers, observedLogs) + + // Commit blocks to finality depth to ensure LogPoller has finalized blocks to read from + ch, err := bootstrapNode.App.GetRelayers().LegacyEVMChains().Get(testutils.SimulatedChainID.String()) + require.NoError(t, err) + finalityDepth := ch.Config().EVM().FinalityDepth() + for i := 0; i < int(finalityDepth); i++ { + backend.Commit() + } + + // Set up n oracles + var ( + oracles []confighelper.OracleIdentityExtra + nodes []Node + ) + ports := freeport.GetN(t, n) + for i := 0; i < n; i++ { + app, peerID, transmitter, kb, observedLogs := setupNode(t, ports[i], fmt.Sprintf("oracle_mercury%d", i), backend, clientCSAKeys[i]) + + nodes = append(nodes, Node{ + app, transmitter, kb, + }) + + offchainPublicKey, _ := hex.DecodeString(strings.TrimPrefix(kb.OnChainPublicKey(), "0x")) + oracles = append(oracles, confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: offchainPublicKey, + TransmitAccount: ocr2types.Account(fmt.Sprintf("%x", transmitter[:])), + OffchainPublicKey: kb.OffchainPublicKey(), + PeerID: peerID, + }, + ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), + }) + logObservers = append(logObservers, observedLogs) + } + + for _, feed := range feeds { + addBootstrapJob(t, bootstrapNode, chainID, verifierAddress, feed.name, feed.id) + } + + createBridge := func(name string, i int, p *big.Int, marketStatus uint32, borm bridges.ORM) (bridgeName string) { + bridge := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + b, herr := io.ReadAll(req.Body) + require.NoError(t, herr) + require.Equal(t, `{"data":{"from":"ETH","to":"USD"}}`, string(b)) + + r := rand.Int63n(101) + if r > pError.Load() { + res.WriteHeader(http.StatusOK) + + var val string + if p != nil { + val = decimal.NewFromBigInt(p, 0).Div(decimal.NewFromInt(multiplier)).Add(decimal.NewFromInt(int64(i)).Div(decimal.NewFromInt(100))).String() + } else { + val = fmt.Sprintf("%d", marketStatus) + } + + resp := fmt.Sprintf(`{"result": %s}`, val) + _, herr = res.Write([]byte(resp)) + require.NoError(t, herr) + } else { + res.WriteHeader(http.StatusInternalServerError) + resp := `{"error": "pError test error"}` + _, herr = res.Write([]byte(resp)) + require.NoError(t, herr) + } + })) + t.Cleanup(bridge.Close) + u, _ := url.Parse(bridge.URL) + bridgeName = fmt.Sprintf("bridge-%s-%d", name, i) + require.NoError(t, borm.CreateBridgeType(ctx, &bridges.BridgeType{ + Name: bridges.BridgeName(bridgeName), + URL: models.WebURL(*u), + })) + + return bridgeName + } + + // Add OCR jobs - one per feed on each node + for i, node := range nodes { + for j, feed := range feeds { + bmBridge := createBridge(fmt.Sprintf("benchmarkprice-%d", j), i, feed.baseBenchmarkPrice, 0, node.App.BridgeORM()) + bidBridge := createBridge(fmt.Sprintf("bid-%d", j), i, feed.baseBid, 0, node.App.BridgeORM()) + askBridge := createBridge(fmt.Sprintf("ask-%d", j), i, feed.baseAsk, 0, node.App.BridgeORM()) + marketStatusBridge := createBridge(fmt.Sprintf("marketstatus-%d", j), i, nil, feed.baseMarketStatus, node.App.BridgeORM()) + + addV4MercuryJob( + t, + node, + i, + verifierAddress, + bootstrapPeerID, + bootstrapNodePort, + bmBridge, + bidBridge, + askBridge, + marketStatusBridge, + servers, + clientPubKeys[i], + feed.name, + feed.id, + randomFeedID(2), + randomFeedID(2), + ) + } + } + + // Setup config on contract + onchainConfig, err := (datastreamsmercury.StandardOnchainConfigCodec{}).Encode(rawOnchainConfig) + require.NoError(t, err) + + reportingPluginConfig, err := json.Marshal(rawReportingPluginConfig) + require.NoError(t, err) + + signers, _, _, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTestsMercuryV02( + 2*time.Second, // DeltaProgress + 20*time.Second, // DeltaResend + 400*time.Millisecond, // DeltaInitial + 100*time.Millisecond, // DeltaRound + 0, // DeltaGrace + 300*time.Millisecond, // DeltaCertifiedCommitRequest + 1*time.Minute, // DeltaStage + 100, // rMax + []int{len(nodes)}, // S + oracles, + reportingPluginConfig, // reportingPluginConfig []byte, + 250*time.Millisecond, // Max duration observation + int(f), // f + onchainConfig, + ) + + require.NoError(t, err) + signerAddresses, err := evm.OnchainPublicKeyToAddress(signers) + require.NoError(t, err) + + offchainTransmitters := make([][32]byte, n) + for i := 0; i < n; i++ { + offchainTransmitters[i] = nodes[i].ClientPubKey + } + + for _, feed := range feeds { + _, ferr := verifier.SetConfig( + steve, + feed.id, + signerAddresses, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + nil, + ) + require.NoError(t, ferr) + backend.Commit() + } + + runTestSetup := func(reqs chan request) { + // Expect at least one report per feed from each oracle, per server + seen := make(map[[32]byte]map[credentials.StaticSizedPublicKey]struct{}) + for i := range feeds { + // feedID will be deleted when all n oracles have reported + seen[feeds[i].id] = make(map[credentials.StaticSizedPublicKey]struct{}, n) + } + + for req := range reqs { + v := make(map[string]interface{}) + err := mercury.PayloadTypes.UnpackIntoMap(v, req.req.Payload) + require.NoError(t, err) + report, exists := v["report"] + if !exists { + t.Fatalf("expected payload %#v to contain 'report'", v) + } + reportElems := make(map[string]interface{}) + err = reportcodecv4.ReportTypes.UnpackIntoMap(reportElems, report.([]byte)) + require.NoError(t, err) + + feedID := reportElems["feedId"].([32]uint8) + feed, exists := feedM[feedID] + require.True(t, exists) + + if _, exists := seen[feedID]; !exists { + continue // already saw all oracles for this feed + } + + expectedFee := datastreamsmercury.CalculateFee(big.NewInt(234567), rawReportingPluginConfig.BaseUSDFee) + expectedExpiresAt := reportElems["observationsTimestamp"].(uint32) + rawReportingPluginConfig.ExpirationWindow + + assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp)) + assert.InDelta(t, feed.baseBenchmarkPrice.Int64(), reportElems["benchmarkPrice"].(*big.Int).Int64(), 5000000) + assert.InDelta(t, feed.baseBid.Int64(), reportElems["bid"].(*big.Int).Int64(), 5000000) + assert.InDelta(t, feed.baseAsk.Int64(), reportElems["ask"].(*big.Int).Int64(), 5000000) + assert.NotZero(t, reportElems["validFromTimestamp"].(uint32)) + assert.GreaterOrEqual(t, reportElems["observationsTimestamp"].(uint32), reportElems["validFromTimestamp"].(uint32)) + assert.Equal(t, expectedExpiresAt, reportElems["expiresAt"].(uint32)) + assert.Equal(t, expectedFee, reportElems["linkFee"].(*big.Int)) + assert.Equal(t, expectedFee, reportElems["nativeFee"].(*big.Int)) + assert.Equal(t, feed.baseMarketStatus, reportElems["marketStatus"].(uint32)) + + t.Logf("oracle %x reported for feed %s (0x%x)", req.pk, feed.name, feed.id) + + seen[feedID][req.pk] = struct{}{} + if len(seen[feedID]) == n { + t.Logf("all oracles reported for feed %s (0x%x)", feed.name, feed.id) + delete(seen, feedID) + if len(seen) == 0 { + break // saw all oracles; success! + } + } + } + } + + t.Run("receives at least one report per feed for every server from each oracle when EAs are at 100% reliability", func(t *testing.T) { + for i := 0; i < nSrvs; i++ { + reqs := reqChs[i] + runTestSetup(reqs) + } + }) +} diff --git a/core/services/ocr2/plugins/mercury/plugin.go b/core/services/ocr2/plugins/mercury/plugin.go index c5eba78b0d..0898c1821e 100644 --- a/core/services/ocr2/plugins/mercury/plugin.go +++ b/core/services/ocr2/plugins/mercury/plugin.go @@ -13,6 +13,7 @@ import ( relaymercuryv1 "github.com/smartcontractkit/chainlink-data-streams/mercury/v1" relaymercuryv2 "github.com/smartcontractkit/chainlink-data-streams/mercury/v2" relaymercuryv3 "github.com/smartcontractkit/chainlink-data-streams/mercury/v3" + relaymercuryv4 "github.com/smartcontractkit/chainlink-data-streams/mercury/v4" "github.com/smartcontractkit/chainlink-common/pkg/loop" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" @@ -29,6 +30,7 @@ import ( mercuryv1 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1" mercuryv2 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2" mercuryv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3" + mercuryv4 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v4" "github.com/smartcontractkit/chainlink/v2/plugins" ) @@ -136,6 +138,13 @@ func NewServices( return nil, fmt.Errorf("failed to create mercury v3 factory: %w", err) } srvs = append(srvs, factoryServices...) + case 4: + factory, factoryServices, err = newv4factory(fCfg) + if err != nil { + abort() + return nil, fmt.Errorf("failed to create mercury v4 factory: %w", err) + } + srvs = append(srvs, factoryServices...) default: return nil, errors.Errorf("unknown Mercury report schema version: %d", feedID.Version()) } @@ -162,6 +171,43 @@ type factoryCfg struct { feedID utils.FeedID } +func newv4factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job.ServiceCtx, error) { + var factory ocr3types.MercuryPluginFactory + srvs := make([]job.ServiceCtx, 0) + + ds := mercuryv4.NewDataSource( + factoryCfg.orm, + factoryCfg.pipelineRunner, + factoryCfg.jb, + *factoryCfg.jb.PipelineSpec, + factoryCfg.feedID, + factoryCfg.lggr, + factoryCfg.saver, + factoryCfg.chEnhancedTelem, + factoryCfg.ocr2Provider.MercuryServerFetcher(), + *factoryCfg.reportingPluginConfig.LinkFeedID, + *factoryCfg.reportingPluginConfig.NativeFeedID, + ) + + loopCmd := env.MercuryPlugin.Cmd.Get() + loopEnabled := loopCmd != "" + + if loopEnabled { + cmdFn, opts, mercuryLggr, err := initLoop(loopCmd, factoryCfg.cfg, factoryCfg.feedID, factoryCfg.lggr) + if err != nil { + return nil, nil, fmt.Errorf("failed to init loop for feed %s: %w", factoryCfg.feedID, err) + } + // in loop mode, the factory is grpc server, and we need to handle the server lifecycle + factoryServer := loop.NewMercuryV4Service(mercuryLggr, opts, cmdFn, factoryCfg.ocr2Provider, ds) + srvs = append(srvs, factoryServer) + // adapt the grpc server to the vanilla mercury plugin factory interface used by the oracle + factory = factoryServer + } else { + factory = relaymercuryv4.NewFactory(ds, factoryCfg.lggr, factoryCfg.ocr2Provider.OnchainConfigCodec(), factoryCfg.ocr2Provider.ReportCodecV4()) + } + return factory, srvs, nil +} + func newv3factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job.ServiceCtx, error) { var factory ocr3types.MercuryPluginFactory srvs := make([]job.ServiceCtx, 0) diff --git a/core/services/ocr2/plugins/mercury/plugin_test.go b/core/services/ocr2/plugins/mercury/plugin_test.go index 95aaabec14..f9bef4a3f1 100644 --- a/core/services/ocr2/plugins/mercury/plugin_test.go +++ b/core/services/ocr2/plugins/mercury/plugin_test.go @@ -21,6 +21,7 @@ import ( v1 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1" v2 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" v3 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" + v4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" mercuryocr2 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury" @@ -37,6 +38,7 @@ var ( v1FeedId = [32]uint8{00, 01, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} v2FeedId = [32]uint8{00, 02, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} v3FeedId = [32]uint8{00, 03, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} + v4FeedId = [32]uint8{00, 04, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} testArgsNoPlugin = libocr2.MercuryOracleArgs{ LocalConfig: libocr2types.LocalConfig{ @@ -66,6 +68,13 @@ var ( "nativeFeedID": "0x00036b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472", } + v4jsonCfg = job.JSONConfig{ + "serverURL": "example.com:80", + "serverPubKey": "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", + "linkFeedID": "0x00026b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472", + "nativeFeedID": "0x00036b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472", + } + testJob = job.Job{ ID: 1, ExternalJobID: uuid.Must(uuid.NewRandom()), @@ -135,6 +144,15 @@ func TestNewServices(t *testing.T) { wantServiceCnt: expectedEmbeddedServiceCnt, wantErr: false, }, + { + name: "v4 legacy", + args: args{ + pluginConfig: v4jsonCfg, + feedID: v4FeedId, + }, + wantServiceCnt: expectedEmbeddedServiceCnt, + wantErr: false, + }, { name: "v1 loop", loopMode: true, @@ -168,6 +186,17 @@ func TestNewServices(t *testing.T) { wantErr: false, wantLoopFactory: &loop.MercuryV3Service{}, }, + { + name: "v4 loop", + loopMode: true, + args: args{ + pluginConfig: v4jsonCfg, + feedID: v4FeedId, + }, + wantServiceCnt: expectedLoopServiceCnt, + wantErr: false, + wantLoopFactory: &loop.MercuryV4Service{}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -259,6 +288,9 @@ func (*testProvider) ReportCodecV2() v2.ReportCodec { return nil } // ReportCodecV3 implements types.MercuryProvider. func (*testProvider) ReportCodecV3() v3.ReportCodec { return nil } +// ReportCodecV4 implements types.MercuryProvider. +func (*testProvider) ReportCodecV4() v4.ReportCodec { return nil } + // Start implements types.MercuryProvider. func (*testProvider) Start(context.Context) error { panic("unimplemented") } diff --git a/core/services/ocrcommon/telemetry.go b/core/services/ocrcommon/telemetry.go index 2ef76800a4..2cb4fda910 100644 --- a/core/services/ocrcommon/telemetry.go +++ b/core/services/ocrcommon/telemetry.go @@ -15,6 +15,8 @@ import ( v1types "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1" v2types "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" v3types "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" + v4types "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" @@ -41,6 +43,7 @@ type EnhancedTelemetryMercuryData struct { V1Observation *v1types.Observation V2Observation *v2types.Observation V3Observation *v3types.Observation + V4Observation *v4types.Observation TaskRunResults pipeline.TaskRunResults RepTimestamp ocrtypes.ReportTimestamp FeedVersion mercuryutils.FeedVersion @@ -298,6 +301,8 @@ func (e *EnhancedTelemetryService[T]) collectMercuryEnhancedTelemetry(d Enhanced ask := big.NewInt(0) // v2+v3 fields var mfts, lp, np int64 + // v4 fields + var marketStatus telem.MarketStatus switch { case d.V1Observation != nil: @@ -354,6 +359,29 @@ func (e *EnhancedTelemetryService[T]) collectMercuryEnhancedTelemetry(d Enhanced if obs.Ask.Err == nil && obs.Ask.Val != nil { ask = obs.Ask.Val } + case d.V4Observation != nil: + obs := *d.V4Observation + if obs.MaxFinalizedTimestamp.Err == nil { + mfts = obs.MaxFinalizedTimestamp.Val + } + if obs.LinkPrice.Err == nil && obs.LinkPrice.Val != nil { + lp = obs.LinkPrice.Val.Int64() + } + if obs.NativePrice.Err == nil && obs.NativePrice.Val != nil { + np = obs.NativePrice.Val.Int64() + } + if obs.BenchmarkPrice.Err == nil && obs.BenchmarkPrice.Val != nil { + bp = obs.BenchmarkPrice.Val + } + if obs.Bid.Err == nil && obs.Bid.Val != nil { + bid = obs.Bid.Val + } + if obs.Ask.Err == nil && obs.Ask.Val != nil { + ask = obs.Ask.Val + } + if obs.MarketStatus.Err == nil { + marketStatus = telem.MarketStatus(obs.MarketStatus.Val) + } } for _, trr := range d.TaskRunResults { @@ -401,6 +429,7 @@ func (e *EnhancedTelemetryService[T]) collectMercuryEnhancedTelemetry(d Enhanced ObservationBenchmarkPriceString: stringOrEmpty(bp), ObservationBidString: stringOrEmpty(bid), ObservationAskString: stringOrEmpty(ask), + ObservationMarketStatus: marketStatus, IsLinkFeed: d.IsLinkFeed, LinkPrice: lp, IsNativeFeed: d.IsNativeFeed, diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 3b3393441a..a0782380b5 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -25,6 +25,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core" + reportcodecv4 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v4/reportcodec" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" txm "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" @@ -296,6 +297,7 @@ func (r *Relayer) NewMercuryProvider(rargs commontypes.RelayArgs, pargs commonty reportCodecV1 := reportcodecv1.NewReportCodec(*relayConfig.FeedID, lggr.Named("ReportCodecV1")) reportCodecV2 := reportcodecv2.NewReportCodec(*relayConfig.FeedID, lggr.Named("ReportCodecV2")) reportCodecV3 := reportcodecv3.NewReportCodec(*relayConfig.FeedID, lggr.Named("ReportCodecV3")) + reportCodecV4 := reportcodecv4.NewReportCodec(*relayConfig.FeedID, lggr.Named("ReportCodecV4")) var transmitterCodec mercury.TransmitterReportDecoder switch feedID.Version() { @@ -305,12 +307,14 @@ func (r *Relayer) NewMercuryProvider(rargs commontypes.RelayArgs, pargs commonty transmitterCodec = reportCodecV2 case 3: transmitterCodec = reportCodecV3 + case 4: + transmitterCodec = reportCodecV4 default: return nil, fmt.Errorf("invalid feed version %d", feedID.Version()) } transmitter := mercury.NewTransmitter(lggr, r.transmitterCfg, clients, privKey.PublicKey, rargs.JobID, *relayConfig.FeedID, r.mercuryORM, transmitterCodec, r.triggerCapability) - return NewMercuryProvider(cp, r.chainReader, r.codec, NewMercuryChainReader(r.chain.HeadTracker()), transmitter, reportCodecV1, reportCodecV2, reportCodecV3, lggr), nil + return NewMercuryProvider(cp, r.chainReader, r.codec, NewMercuryChainReader(r.chain.HeadTracker()), transmitter, reportCodecV1, reportCodecV2, reportCodecV3, reportCodecV4, lggr), nil } func (r *Relayer) NewLLOProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.LLOProvider, error) { diff --git a/core/services/relay/evm/mercury/utils/feeds.go b/core/services/relay/evm/mercury/utils/feeds.go index 6f8978bbf0..36d6bc60f5 100644 --- a/core/services/relay/evm/mercury/utils/feeds.go +++ b/core/services/relay/evm/mercury/utils/feeds.go @@ -83,6 +83,7 @@ const ( REPORT_V1 REPORT_V2 REPORT_V3 + REPORT_V4 _ ) @@ -110,3 +111,4 @@ func (f FeedID) Version() FeedVersion { func (f FeedID) IsV1() bool { return f.Version() == REPORT_V1 } func (f FeedID) IsV2() bool { return f.Version() == REPORT_V2 } func (f FeedID) IsV3() bool { return f.Version() == REPORT_V3 } +func (f FeedID) IsV4() bool { return f.Version() == REPORT_V4 } diff --git a/core/services/relay/evm/mercury/v4/data_source.go b/core/services/relay/evm/mercury/v4/data_source.go new file mode 100644 index 0000000000..f9c2c2d5de --- /dev/null +++ b/core/services/relay/evm/mercury/v4/data_source.go @@ -0,0 +1,290 @@ +package v4 + +import ( + "context" + "errors" + "fmt" + "math/big" + "sync" + + pkgerrors "github.com/pkg/errors" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" + v4types "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" + v4 "github.com/smartcontractkit/chainlink-data-streams/mercury/v4" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types" + mercurytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types" + mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v4/reportcodec" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +type Runner interface { + ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars) (run *pipeline.Run, trrs pipeline.TaskRunResults, err error) +} + +type LatestReportFetcher interface { + LatestPrice(ctx context.Context, feedID [32]byte) (*big.Int, error) + LatestTimestamp(context.Context) (int64, error) +} + +type datasource struct { + pipelineRunner Runner + jb job.Job + spec pipeline.Spec + feedID mercuryutils.FeedID + lggr logger.Logger + saver ocrcommon.Saver + orm types.DataSourceORM + codec reportcodec.ReportCodec + + fetcher LatestReportFetcher + linkFeedID mercuryutils.FeedID + nativeFeedID mercuryutils.FeedID + + mu sync.RWMutex + + chEnhancedTelem chan<- ocrcommon.EnhancedTelemetryMercuryData +} + +var _ v4.DataSource = &datasource{} + +func NewDataSource(orm types.DataSourceORM, pr pipeline.Runner, jb job.Job, spec pipeline.Spec, feedID mercuryutils.FeedID, lggr logger.Logger, s ocrcommon.Saver, enhancedTelemChan chan ocrcommon.EnhancedTelemetryMercuryData, fetcher LatestReportFetcher, linkFeedID, nativeFeedID mercuryutils.FeedID) *datasource { + return &datasource{pr, jb, spec, feedID, lggr, s, orm, reportcodec.ReportCodec{}, fetcher, linkFeedID, nativeFeedID, sync.RWMutex{}, enhancedTelemChan} +} + +func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp, fetchMaxFinalizedTimestamp bool) (obs v4types.Observation, pipelineExecutionErr error) { + var wg sync.WaitGroup + ctx, cancel := context.WithCancel(ctx) + + if fetchMaxFinalizedTimestamp { + wg.Add(1) + go func() { + defer wg.Done() + latest, dbErr := ds.orm.LatestReport(ctx, ds.feedID) + if dbErr != nil { + obs.MaxFinalizedTimestamp.Err = dbErr + return + } + if latest != nil { + maxFinalizedBlockNumber, decodeErr := ds.codec.ObservationTimestampFromReport(latest) + obs.MaxFinalizedTimestamp.Val, obs.MaxFinalizedTimestamp.Err = int64(maxFinalizedBlockNumber), decodeErr + return + } + obs.MaxFinalizedTimestamp.Val, obs.MaxFinalizedTimestamp.Err = ds.fetcher.LatestTimestamp(ctx) + }() + } + + var trrs pipeline.TaskRunResults + wg.Add(1) + go func() { + defer wg.Done() + var run *pipeline.Run + run, trrs, pipelineExecutionErr = ds.executeRun(ctx) + if pipelineExecutionErr != nil { + cancel() + pipelineExecutionErr = fmt.Errorf("Observe failed while executing run: %w", pipelineExecutionErr) + return + } + + ds.saver.Save(run) + + var parsed parseOutput + parsed, pipelineExecutionErr = ds.parse(trrs) + if pipelineExecutionErr != nil { + cancel() + // This is not expected under normal circumstances + ds.lggr.Errorw("Observe failed while parsing run results", "err", pipelineExecutionErr) + pipelineExecutionErr = fmt.Errorf("Observe failed while parsing run results: %w", pipelineExecutionErr) + return + } + obs.BenchmarkPrice = parsed.benchmarkPrice + obs.Bid = parsed.bid + obs.Ask = parsed.ask + obs.MarketStatus = parsed.marketStatus + }() + + var isLink, isNative bool + if ds.feedID == ds.linkFeedID { + isLink = true + } else { + wg.Add(1) + go func() { + defer wg.Done() + obs.LinkPrice.Val, obs.LinkPrice.Err = ds.fetcher.LatestPrice(ctx, ds.linkFeedID) + if obs.LinkPrice.Val == nil && obs.LinkPrice.Err == nil { + mercurytypes.PriceFeedMissingCount.WithLabelValues(ds.linkFeedID.String()).Inc() + ds.lggr.Warnw(fmt.Sprintf("Mercury server was missing LINK feed, using sentinel value of %s", v4.MissingPrice), "linkFeedID", ds.linkFeedID) + obs.LinkPrice.Val = v4.MissingPrice + } else if obs.LinkPrice.Err != nil { + mercurytypes.PriceFeedErrorCount.WithLabelValues(ds.linkFeedID.String()).Inc() + ds.lggr.Errorw("Mercury server returned error querying LINK price feed", "err", obs.LinkPrice.Err, "linkFeedID", ds.linkFeedID) + } + }() + } + + if ds.feedID == ds.nativeFeedID { + isNative = true + } else { + wg.Add(1) + go func() { + defer wg.Done() + obs.NativePrice.Val, obs.NativePrice.Err = ds.fetcher.LatestPrice(ctx, ds.nativeFeedID) + if obs.NativePrice.Val == nil && obs.NativePrice.Err == nil { + mercurytypes.PriceFeedMissingCount.WithLabelValues(ds.nativeFeedID.String()).Inc() + ds.lggr.Warnw(fmt.Sprintf("Mercury server was missing native feed, using sentinel value of %s", v4.MissingPrice), "nativeFeedID", ds.nativeFeedID) + obs.NativePrice.Val = v4.MissingPrice + } else if obs.NativePrice.Err != nil { + mercurytypes.PriceFeedErrorCount.WithLabelValues(ds.nativeFeedID.String()).Inc() + ds.lggr.Errorw("Mercury server returned error querying native price feed", "err", obs.NativePrice.Err, "nativeFeedID", ds.nativeFeedID) + } + }() + } + + wg.Wait() + cancel() + + if pipelineExecutionErr != nil { + return + } + + if isLink || isNative { + // run has now completed so it is safe to use benchmark price + if isLink { + // This IS the LINK feed, use our observed price + obs.LinkPrice.Val, obs.LinkPrice.Err = obs.BenchmarkPrice.Val, obs.BenchmarkPrice.Err + } + if isNative { + // This IS the native feed, use our observed price + obs.NativePrice.Val, obs.NativePrice.Err = obs.BenchmarkPrice.Val, obs.BenchmarkPrice.Err + } + } + + ocrcommon.MaybeEnqueueEnhancedTelem(ds.jb, ds.chEnhancedTelem, ocrcommon.EnhancedTelemetryMercuryData{ + V4Observation: &obs, + TaskRunResults: trrs, + RepTimestamp: repts, + FeedVersion: mercuryutils.REPORT_V4, + FetchMaxFinalizedTimestamp: fetchMaxFinalizedTimestamp, + IsLinkFeed: isLink, + IsNativeFeed: isNative, + }) + + return obs, nil +} + +func toBigInt(val interface{}) (*big.Int, error) { + dec, err := utils.ToDecimal(val) + if err != nil { + return nil, err + } + return dec.BigInt(), nil +} + +type parseOutput struct { + benchmarkPrice mercury.ObsResult[*big.Int] + bid mercury.ObsResult[*big.Int] + ask mercury.ObsResult[*big.Int] + marketStatus mercury.ObsResult[uint32] +} + +func (ds *datasource) parse(trrs pipeline.TaskRunResults) (o parseOutput, merr error) { + var finaltrrs []pipeline.TaskRunResult + for _, trr := range trrs { + // only return terminal trrs from executeRun + if trr.IsTerminal() { + finaltrrs = append(finaltrrs, trr) + } + } + + // pipeline.TaskRunResults comes ordered asc by index, this is guaranteed + // by the pipeline executor + if len(finaltrrs) != 4 { + return o, fmt.Errorf("invalid number of results, expected: 4, got: %d", len(finaltrrs)) + } + + merr = errors.Join( + setBenchmarkPrice(&o, finaltrrs[0].Result), + setBid(&o, finaltrrs[1].Result), + setAsk(&o, finaltrrs[2].Result), + setMarketStatus(&o, finaltrrs[3].Result), + ) + + return o, merr +} + +func setBenchmarkPrice(o *parseOutput, res pipeline.Result) error { + if res.Error != nil { + o.benchmarkPrice.Err = res.Error + return res.Error + } + val, err := toBigInt(res.Value) + if err != nil { + return fmt.Errorf("failed to parse BenchmarkPrice: %w", err) + } + o.benchmarkPrice.Val = val + return nil +} + +func setBid(o *parseOutput, res pipeline.Result) error { + if res.Error != nil { + o.bid.Err = res.Error + return res.Error + } + val, err := toBigInt(res.Value) + if err != nil { + return fmt.Errorf("failed to parse Bid: %w", err) + } + o.bid.Val = val + return nil +} + +func setAsk(o *parseOutput, res pipeline.Result) error { + if res.Error != nil { + o.ask.Err = res.Error + return res.Error + } + val, err := toBigInt(res.Value) + if err != nil { + return fmt.Errorf("failed to parse Ask: %w", err) + } + o.ask.Val = val + return nil +} + +func setMarketStatus(o *parseOutput, res pipeline.Result) error { + if res.Error != nil { + o.marketStatus.Err = res.Error + return res.Error + } + val, err := toBigInt(res.Value) + if err != nil { + return fmt.Errorf("failed to parse MarketStatus: %w", err) + } + o.marketStatus.Val = uint32(val.Int64()) + return nil +} + +// The context passed in here has a timeout of (ObservationTimeout + ObservationGracePeriod). +// Upon context cancellation, its expected that we return any usable values within ObservationGracePeriod. +func (ds *datasource) executeRun(ctx context.Context) (*pipeline.Run, pipeline.TaskRunResults, error) { + vars := pipeline.NewVarsFrom(map[string]interface{}{ + "jb": map[string]interface{}{ + "databaseID": ds.jb.ID, + "externalJobID": ds.jb.ExternalJobID, + "name": ds.jb.Name.ValueOrZero(), + }, + }) + + run, trrs, err := ds.pipelineRunner.ExecuteRun(ctx, ds.spec, vars) + if err != nil { + return nil, nil, pkgerrors.Wrapf(err, "error executing run for spec ID %v", ds.spec.ID) + } + + return run, trrs, err +} diff --git a/core/services/relay/evm/mercury/v4/data_source_test.go b/core/services/relay/evm/mercury/v4/data_source_test.go new file mode 100644 index 0000000000..bce9c3c608 --- /dev/null +++ b/core/services/relay/evm/mercury/v4/data_source_test.go @@ -0,0 +1,349 @@ +package v4 + +import ( + "context" + "math/big" + "testing" + + "github.com/pkg/errors" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/assert" + + mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" + relaymercuryv4 "github.com/smartcontractkit/chainlink-data-streams/mercury/v4" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + mercurymocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" + reportcodecv4 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v4/reportcodec" +) + +var _ mercurytypes.ServerFetcher = &mockFetcher{} + +type mockFetcher struct { + ts int64 + tsErr error + linkPrice *big.Int + linkPriceErr error + nativePrice *big.Int + nativePriceErr error +} + +var feedId utils.FeedID = [32]byte{1} +var linkFeedId utils.FeedID = [32]byte{2} +var nativeFeedId utils.FeedID = [32]byte{3} + +func (m *mockFetcher) FetchInitialMaxFinalizedBlockNumber(context.Context) (*int64, error) { + return nil, nil +} + +func (m *mockFetcher) LatestPrice(ctx context.Context, fId [32]byte) (*big.Int, error) { + if fId == linkFeedId { + return m.linkPrice, m.linkPriceErr + } else if fId == nativeFeedId { + return m.nativePrice, m.nativePriceErr + } + return nil, nil +} + +func (m *mockFetcher) LatestTimestamp(context.Context) (int64, error) { + return m.ts, m.tsErr +} + +type mockORM struct { + report []byte + err error +} + +func (m *mockORM) LatestReport(ctx context.Context, feedID [32]byte) (report []byte, err error) { + return m.report, m.err +} + +type mockSaver struct { + r *pipeline.Run +} + +func (ms *mockSaver) Save(r *pipeline.Run) { + ms.r = r +} + +func Test_Datasource(t *testing.T) { + orm := &mockORM{} + ds := &datasource{orm: orm, lggr: logger.TestLogger(t)} + ctx := testutils.Context(t) + repts := ocrtypes.ReportTimestamp{} + + fetcher := &mockFetcher{} + ds.fetcher = fetcher + + saver := &mockSaver{} + ds.saver = saver + + goodTrrs := []pipeline.TaskRunResult{ + { + // bp + Result: pipeline.Result{Value: "122.345"}, + Task: &mercurymocks.MockTask{}, + }, + { + // bid + Result: pipeline.Result{Value: "121.993"}, + Task: &mercurymocks.MockTask{}, + }, + { + // ask + Result: pipeline.Result{Value: "123.111"}, + Task: &mercurymocks.MockTask{}, + }, + { + // marketStatus + Result: pipeline.Result{Value: "1"}, + Task: &mercurymocks.MockTask{}, + }, + } + + ds.pipelineRunner = &mercurymocks.MockRunner{ + Trrs: goodTrrs, + } + + spec := pipeline.Spec{} + ds.spec = spec + + t.Run("when fetchMaxFinalizedTimestamp=true", func(t *testing.T) { + t.Run("with latest report in database", func(t *testing.T) { + orm.report = buildSamplev4Report() + orm.err = nil + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + assert.Equal(t, int64(124), obs.MaxFinalizedTimestamp.Val) + }) + t.Run("if querying latest report fails", func(t *testing.T) { + orm.report = nil + orm.err = errors.New("something exploded") + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.EqualError(t, obs.MaxFinalizedTimestamp.Err, "something exploded") + assert.Zero(t, obs.MaxFinalizedTimestamp.Val) + }) + t.Run("if codec fails to decode", func(t *testing.T) { + orm.report = []byte{1, 2, 3} + orm.err = nil + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.EqualError(t, obs.MaxFinalizedTimestamp.Err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + assert.Zero(t, obs.MaxFinalizedTimestamp.Val) + }) + + orm.report = nil + orm.err = nil + + t.Run("if LatestTimestamp returns error", func(t *testing.T) { + fetcher.tsErr = errors.New("some error") + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.EqualError(t, obs.MaxFinalizedTimestamp.Err, "some error") + assert.Zero(t, obs.MaxFinalizedTimestamp.Val) + }) + + t.Run("if LatestTimestamp succeeds", func(t *testing.T) { + fetcher.tsErr = nil + fetcher.ts = 123 + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.Equal(t, int64(123), obs.MaxFinalizedTimestamp.Val) + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + }) + + t.Run("if LatestTimestamp succeeds but ts=0 (new feed)", func(t *testing.T) { + fetcher.tsErr = nil + fetcher.ts = 0 + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + assert.Zero(t, obs.MaxFinalizedTimestamp.Val) + }) + + t.Run("when run execution succeeded", func(t *testing.T) { + t.Run("when feedId=linkFeedID=nativeFeedId", func(t *testing.T) { + t.Cleanup(func() { + ds.feedID, ds.linkFeedID, ds.nativeFeedID = feedId, linkFeedId, nativeFeedId + }) + + ds.feedID, ds.linkFeedID, ds.nativeFeedID = feedId, feedId, feedId + + fetcher.ts = 123123 + fetcher.tsErr = nil + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.Equal(t, big.NewInt(122), obs.BenchmarkPrice.Val) + assert.NoError(t, obs.BenchmarkPrice.Err) + assert.Equal(t, big.NewInt(121), obs.Bid.Val) + assert.NoError(t, obs.Bid.Err) + assert.Equal(t, big.NewInt(123), obs.Ask.Val) + assert.NoError(t, obs.Ask.Err) + assert.Equal(t, int64(123123), obs.MaxFinalizedTimestamp.Val) + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + assert.Equal(t, big.NewInt(122), obs.LinkPrice.Val) + assert.NoError(t, obs.LinkPrice.Err) + assert.Equal(t, big.NewInt(122), obs.NativePrice.Val) + assert.NoError(t, obs.NativePrice.Err) + assert.Equal(t, uint32(1), obs.MarketStatus.Val) + assert.NoError(t, obs.MarketStatus.Err) + }) + }) + }) + + t.Run("when fetchMaxFinalizedTimestamp=false", func(t *testing.T) { + t.Run("when run execution fails, returns error", func(t *testing.T) { + t.Cleanup(func() { + ds.pipelineRunner = &mercurymocks.MockRunner{ + Trrs: goodTrrs, + Err: nil, + } + }) + + ds.pipelineRunner = &mercurymocks.MockRunner{ + Trrs: goodTrrs, + Err: errors.New("run execution failed"), + } + + _, err := ds.Observe(ctx, repts, false) + assert.EqualError(t, err, "Observe failed while executing run: error executing run for spec ID 0: run execution failed") + }) + + t.Run("when parsing run results fails, return error", func(t *testing.T) { + t.Cleanup(func() { + runner := &mercurymocks.MockRunner{ + Trrs: goodTrrs, + Err: nil, + } + ds.pipelineRunner = runner + }) + + badTrrs := []pipeline.TaskRunResult{ + { + // benchmark price + Result: pipeline.Result{Value: "122.345"}, + Task: &mercurymocks.MockTask{}, + }, + { + // bid + Result: pipeline.Result{Value: "121.993"}, + Task: &mercurymocks.MockTask{}, + }, + { + // ask + Result: pipeline.Result{Error: errors.New("some error with ask")}, + Task: &mercurymocks.MockTask{}, + }, + { + // marketStatus + Result: pipeline.Result{Value: "1"}, + Task: &mercurymocks.MockTask{}, + }, + } + + ds.pipelineRunner = &mercurymocks.MockRunner{ + Trrs: badTrrs, + Err: nil, + } + + _, err := ds.Observe(ctx, repts, false) + assert.EqualError(t, err, "Observe failed while parsing run results: some error with ask") + }) + + t.Run("when run execution succeeded", func(t *testing.T) { + t.Run("when feedId=linkFeedID=nativeFeedId", func(t *testing.T) { + t.Cleanup(func() { + ds.feedID, ds.linkFeedID, ds.nativeFeedID = feedId, linkFeedId, nativeFeedId + }) + + var feedId utils.FeedID = [32]byte{1} + ds.feedID, ds.linkFeedID, ds.nativeFeedID = feedId, feedId, feedId + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Equal(t, big.NewInt(122), obs.BenchmarkPrice.Val) + assert.NoError(t, obs.BenchmarkPrice.Err) + assert.Equal(t, big.NewInt(121), obs.Bid.Val) + assert.NoError(t, obs.Bid.Err) + assert.Equal(t, big.NewInt(123), obs.Ask.Val) + assert.NoError(t, obs.Ask.Err) + assert.Equal(t, int64(0), obs.MaxFinalizedTimestamp.Val) + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + assert.Equal(t, big.NewInt(122), obs.LinkPrice.Val) + assert.NoError(t, obs.LinkPrice.Err) + assert.Equal(t, big.NewInt(122), obs.NativePrice.Val) + assert.NoError(t, obs.NativePrice.Err) + assert.Equal(t, uint32(1), obs.MarketStatus.Val) + assert.NoError(t, obs.MarketStatus.Err) + }) + + t.Run("when fails to fetch linkPrice or nativePrice", func(t *testing.T) { + t.Cleanup(func() { + fetcher.linkPriceErr = nil + fetcher.nativePriceErr = nil + }) + + fetcher.linkPriceErr = errors.New("some error fetching link price") + fetcher.nativePriceErr = errors.New("some error fetching native price") + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Nil(t, obs.LinkPrice.Val) + assert.EqualError(t, obs.LinkPrice.Err, "some error fetching link price") + assert.Nil(t, obs.NativePrice.Val) + assert.EqualError(t, obs.NativePrice.Err, "some error fetching native price") + }) + + t.Run("when succeeds to fetch linkPrice or nativePrice but got nil (new feed)", func(t *testing.T) { + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Equal(t, obs.LinkPrice.Val, relaymercuryv4.MissingPrice) + assert.Nil(t, obs.LinkPrice.Err) + assert.Equal(t, obs.NativePrice.Val, relaymercuryv4.MissingPrice) + assert.Nil(t, obs.NativePrice.Err) + }) + }) + }) +} + +var sampleFeedID = [32]uint8{28, 145, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} + +func buildSamplev4Report() []byte { + feedID := sampleFeedID + timestamp := uint32(124) + bp := big.NewInt(242) + bid := big.NewInt(243) + ask := big.NewInt(244) + validFromTimestamp := uint32(123) + expiresAt := uint32(456) + linkFee := big.NewInt(3334455) + nativeFee := big.NewInt(556677) + marketStatus := uint32(1) + + b, err := reportcodecv4.ReportTypes.Pack(feedID, validFromTimestamp, timestamp, nativeFee, linkFee, expiresAt, bp, bid, ask, marketStatus) + if err != nil { + panic(err) + } + return b +} diff --git a/core/services/relay/evm/mercury/v4/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v4/reportcodec/report_codec.go new file mode 100644 index 0000000000..12f3d88e73 --- /dev/null +++ b/core/services/relay/evm/mercury/v4/reportcodec/report_codec.go @@ -0,0 +1,82 @@ +package reportcodec + +import ( + "errors" + "fmt" + "math/big" + + pkgerrors "github.com/pkg/errors" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + v4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" + reporttypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v4/types" +) + +var ReportTypes = reporttypes.GetSchema() +var maxReportLength = 32 * len(ReportTypes) // each arg is 256 bit EVM word +var zero = big.NewInt(0) + +var _ v4.ReportCodec = &ReportCodec{} + +type ReportCodec struct { + logger logger.Logger + feedID utils.FeedID +} + +func NewReportCodec(feedID [32]byte, lggr logger.Logger) *ReportCodec { + return &ReportCodec{lggr, feedID} +} + +func (r *ReportCodec) BuildReport(rf v4.ReportFields) (ocrtypes.Report, error) { + var merr error + if rf.BenchmarkPrice == nil { + merr = errors.Join(merr, errors.New("benchmarkPrice may not be nil")) + } + if rf.Bid == nil { + merr = errors.Join(merr, errors.New("bid may not be nil")) + } + if rf.Ask == nil { + merr = errors.Join(merr, errors.New("ask may not be nil")) + } + if rf.LinkFee == nil { + merr = errors.Join(merr, errors.New("linkFee may not be nil")) + } else if rf.LinkFee.Cmp(zero) < 0 { + merr = errors.Join(merr, fmt.Errorf("linkFee may not be negative (got: %s)", rf.LinkFee)) + } + if rf.NativeFee == nil { + merr = errors.Join(merr, errors.New("nativeFee may not be nil")) + } else if rf.NativeFee.Cmp(zero) < 0 { + merr = errors.Join(merr, fmt.Errorf("nativeFee may not be negative (got: %s)", rf.NativeFee)) + } + if merr != nil { + return nil, merr + } + reportBytes, err := ReportTypes.Pack(r.feedID, rf.ValidFromTimestamp, rf.Timestamp, rf.NativeFee, rf.LinkFee, rf.ExpiresAt, rf.BenchmarkPrice, rf.Bid, rf.Ask, rf.MarketStatus) + return ocrtypes.Report(reportBytes), pkgerrors.Wrap(err, "failed to pack report blob") +} + +func (r *ReportCodec) MaxReportLength(n int) (int, error) { + return maxReportLength, nil +} + +func (r *ReportCodec) ObservationTimestampFromReport(report ocrtypes.Report) (uint32, error) { + decoded, err := r.Decode(report) + if err != nil { + return 0, err + } + return decoded.ObservationsTimestamp, nil +} + +func (r *ReportCodec) Decode(report ocrtypes.Report) (*reporttypes.Report, error) { + return reporttypes.Decode(report) +} + +func (r *ReportCodec) BenchmarkPriceFromReport(report ocrtypes.Report) (*big.Int, error) { + decoded, err := r.Decode(report) + if err != nil { + return nil, err + } + return decoded.BenchmarkPrice, nil +} diff --git a/core/services/relay/evm/mercury/v4/reportcodec/report_codec_test.go b/core/services/relay/evm/mercury/v4/reportcodec/report_codec_test.go new file mode 100644 index 0000000000..b62f42ef57 --- /dev/null +++ b/core/services/relay/evm/mercury/v4/reportcodec/report_codec_test.go @@ -0,0 +1,163 @@ +package reportcodec + +import ( + "math/big" + "testing" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + v4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" +) + +func newValidReportFields() v4.ReportFields { + return v4.ReportFields{ + Timestamp: 242, + BenchmarkPrice: big.NewInt(243), + Bid: big.NewInt(244), + Ask: big.NewInt(245), + ValidFromTimestamp: 123, + ExpiresAt: 20, + LinkFee: big.NewInt(456), + NativeFee: big.NewInt(457), + MarketStatus: 1, + } +} + +func Test_ReportCodec_BuildReport(t *testing.T) { + r := ReportCodec{} + + t.Run("BuildReport errors on zero values", func(t *testing.T) { + _, err := r.BuildReport(v4.ReportFields{}) + require.Error(t, err) + assert.Contains(t, err.Error(), "benchmarkPrice may not be nil") + assert.Contains(t, err.Error(), "linkFee may not be nil") + assert.Contains(t, err.Error(), "nativeFee may not be nil") + }) + + t.Run("BuildReport constructs a report from observations", func(t *testing.T) { + rf := newValidReportFields() + // only need to test happy path since validations are done in relaymercury + + report, err := r.BuildReport(rf) + require.NoError(t, err) + + reportElems := make(map[string]interface{}) + err = ReportTypes.UnpackIntoMap(reportElems, report) + require.NoError(t, err) + + assert.Equal(t, int(reportElems["observationsTimestamp"].(uint32)), 242) + assert.Equal(t, reportElems["benchmarkPrice"].(*big.Int).Int64(), int64(243)) + assert.Equal(t, reportElems["bid"].(*big.Int).Int64(), int64(244)) + assert.Equal(t, reportElems["ask"].(*big.Int).Int64(), int64(245)) + assert.Equal(t, reportElems["validFromTimestamp"].(uint32), uint32(123)) + assert.Equal(t, reportElems["expiresAt"].(uint32), uint32(20)) + assert.Equal(t, reportElems["linkFee"].(*big.Int).Int64(), int64(456)) + assert.Equal(t, reportElems["nativeFee"].(*big.Int).Int64(), int64(457)) + assert.Equal(t, reportElems["marketStatus"].(uint32), uint32(1)) + + assert.Equal(t, types.Report{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, report) + max, err := r.MaxReportLength(4) + require.NoError(t, err) + assert.LessOrEqual(t, len(report), max) + + t.Run("Decode decodes the report", func(t *testing.T) { + decoded, err := r.Decode(report) + require.NoError(t, err) + + require.NotNil(t, decoded) + + assert.Equal(t, uint32(242), decoded.ObservationsTimestamp) + assert.Equal(t, big.NewInt(243), decoded.BenchmarkPrice) + assert.Equal(t, big.NewInt(244), decoded.Bid) + assert.Equal(t, big.NewInt(245), decoded.Ask) + assert.Equal(t, uint32(123), decoded.ValidFromTimestamp) + assert.Equal(t, uint32(20), decoded.ExpiresAt) + assert.Equal(t, big.NewInt(456), decoded.LinkFee) + assert.Equal(t, big.NewInt(457), decoded.NativeFee) + assert.Equal(t, uint32(1), decoded.MarketStatus) + }) + }) + + t.Run("errors on negative fee", func(t *testing.T) { + rf := newValidReportFields() + rf.LinkFee = big.NewInt(-1) + rf.NativeFee = big.NewInt(-1) + _, err := r.BuildReport(rf) + require.Error(t, err) + + assert.Contains(t, err.Error(), "linkFee may not be negative (got: -1)") + assert.Contains(t, err.Error(), "nativeFee may not be negative (got: -1)") + }) + + t.Run("Decode errors on invalid report", func(t *testing.T) { + _, err := r.Decode([]byte{1, 2, 3}) + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + + longBad := make([]byte, 64) + for i := 0; i < len(longBad); i++ { + longBad[i] = byte(i) + } + _, err = r.Decode(longBad) + assert.EqualError(t, err, "failed to decode report: abi: improperly encoded uint32 value") + }) +} + +func buildSampleReport(ts int64) []byte { + feedID := [32]byte{'f', 'o', 'o'} + timestamp := uint32(ts) + bp := big.NewInt(242) + bid := big.NewInt(243) + ask := big.NewInt(244) + validFromTimestamp := uint32(123) + expiresAt := uint32(456) + linkFee := big.NewInt(3334455) + nativeFee := big.NewInt(556677) + marketStatus := uint32(1) + + b, err := ReportTypes.Pack(feedID, validFromTimestamp, timestamp, nativeFee, linkFee, expiresAt, bp, bid, ask, marketStatus) + if err != nil { + panic(err) + } + return b +} + +func Test_ReportCodec_ObservationTimestampFromReport(t *testing.T) { + r := ReportCodec{} + + t.Run("ObservationTimestampFromReport extracts observation timestamp from a valid report", func(t *testing.T) { + report := buildSampleReport(123) + + ts, err := r.ObservationTimestampFromReport(report) + require.NoError(t, err) + + assert.Equal(t, ts, uint32(123)) + }) + t.Run("ObservationTimestampFromReport returns error when report is invalid", func(t *testing.T) { + report := []byte{1, 2, 3} + + _, err := r.ObservationTimestampFromReport(report) + require.Error(t, err) + + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + }) +} + +func Test_ReportCodec_BenchmarkPriceFromReport(t *testing.T) { + r := ReportCodec{} + + t.Run("BenchmarkPriceFromReport extracts the benchmark price from valid report", func(t *testing.T) { + report := buildSampleReport(123) + + bp, err := r.BenchmarkPriceFromReport(report) + require.NoError(t, err) + + assert.Equal(t, big.NewInt(242), bp) + }) + t.Run("BenchmarkPriceFromReport errors on invalid report", func(t *testing.T) { + _, err := r.BenchmarkPriceFromReport([]byte{1, 2, 3}) + require.Error(t, err) + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + }) +} diff --git a/core/services/relay/evm/mercury/v4/types/types.go b/core/services/relay/evm/mercury/v4/types/types.go new file mode 100644 index 0000000000..3abdd262a6 --- /dev/null +++ b/core/services/relay/evm/mercury/v4/types/types.go @@ -0,0 +1,58 @@ +package reporttypes + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +var schema = GetSchema() + +func GetSchema() abi.Arguments { + mustNewType := func(t string) abi.Type { + result, err := abi.NewType(t, "", []abi.ArgumentMarshaling{}) + if err != nil { + panic(fmt.Sprintf("Unexpected error during abi.NewType: %s", err)) + } + return result + } + return abi.Arguments([]abi.Argument{ + {Name: "feedId", Type: mustNewType("bytes32")}, + {Name: "validFromTimestamp", Type: mustNewType("uint32")}, + {Name: "observationsTimestamp", Type: mustNewType("uint32")}, + {Name: "nativeFee", Type: mustNewType("uint192")}, + {Name: "linkFee", Type: mustNewType("uint192")}, + {Name: "expiresAt", Type: mustNewType("uint32")}, + {Name: "benchmarkPrice", Type: mustNewType("int192")}, + {Name: "bid", Type: mustNewType("int192")}, + {Name: "ask", Type: mustNewType("int192")}, + {Name: "marketStatus", Type: mustNewType("uint32")}, + }) +} + +type Report struct { + FeedId [32]byte + ObservationsTimestamp uint32 + BenchmarkPrice *big.Int + Bid *big.Int + Ask *big.Int + ValidFromTimestamp uint32 + ExpiresAt uint32 + LinkFee *big.Int + NativeFee *big.Int + MarketStatus uint32 +} + +// Decode is made available to external users (i.e. mercury server) +func Decode(report []byte) (*Report, error) { + values, err := schema.Unpack(report) + if err != nil { + return nil, fmt.Errorf("failed to decode report: %w", err) + } + decoded := new(Report) + if err = schema.Copy(decoded, values); err != nil { + return nil, fmt.Errorf("failed to copy report values to struct: %w", err) + } + return decoded, nil +} diff --git a/core/services/relay/evm/mercury_provider.go b/core/services/relay/evm/mercury_provider.go index 48882b701c..9393f66b0d 100644 --- a/core/services/relay/evm/mercury_provider.go +++ b/core/services/relay/evm/mercury_provider.go @@ -8,13 +8,12 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/services" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" - mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" v1 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1" v2 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" v3 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" + v4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" "github.com/smartcontractkit/chainlink-data-streams/mercury" - httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" "github.com/smartcontractkit/chainlink/v2/core/logger" evmmercury "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" @@ -30,6 +29,7 @@ type mercuryProvider struct { reportCodecV1 v1.ReportCodec reportCodecV2 v2.ReportCodec reportCodecV3 v3.ReportCodec + reportCodecV4 v4.ReportCodec mercuryChainReader mercurytypes.ChainReader logger logger.Logger ms services.MultiStart @@ -44,6 +44,7 @@ func NewMercuryProvider( reportCodecV1 v1.ReportCodec, reportCodecV2 v2.ReportCodec, reportCodecV3 v3.ReportCodec, + reportCodecV4 v4.ReportCodec, lggr logger.Logger, ) *mercuryProvider { return &mercuryProvider{ @@ -54,6 +55,7 @@ func NewMercuryProvider( reportCodecV1, reportCodecV2, reportCodecV3, + reportCodecV4, mercuryChainReader, lggr, services.MultiStart{}, @@ -115,6 +117,10 @@ func (p *mercuryProvider) ReportCodecV3() v3.ReportCodec { return p.reportCodecV3 } +func (p *mercuryProvider) ReportCodecV4() v4.ReportCodec { + return p.reportCodecV4 +} + func (p *mercuryProvider) ContractTransmitter() ocrtypes.ContractTransmitter { return p.transmitter } diff --git a/core/services/synchronization/telem/telem.pb.go b/core/services/synchronization/telem/telem.pb.go index e1945bc26d..d51b9628e2 100644 --- a/core/services/synchronization/telem/telem.pb.go +++ b/core/services/synchronization/telem/telem.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.34.2 // protoc v4.25.1 // source: core/services/synchronization/telem/telem.proto @@ -264,7 +264,7 @@ func file_core_services_synchronization_telem_telem_proto_rawDescGZIP() []byte { } var file_core_services_synchronization_telem_telem_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_core_services_synchronization_telem_telem_proto_goTypes = []interface{}{ +var file_core_services_synchronization_telem_telem_proto_goTypes = []any{ (*TelemRequest)(nil), // 0: telem.TelemRequest (*TelemBatchRequest)(nil), // 1: telem.TelemBatchRequest (*TelemResponse)(nil), // 2: telem.TelemResponse @@ -287,7 +287,7 @@ func file_core_services_synchronization_telem_telem_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_core_services_synchronization_telem_telem_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_core_services_synchronization_telem_telem_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*TelemRequest); i { case 0: return &v.state @@ -299,7 +299,7 @@ func file_core_services_synchronization_telem_telem_proto_init() { return nil } } - file_core_services_synchronization_telem_telem_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_core_services_synchronization_telem_telem_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*TelemBatchRequest); i { case 0: return &v.state @@ -311,7 +311,7 @@ func file_core_services_synchronization_telem_telem_proto_init() { return nil } } - file_core_services_synchronization_telem_telem_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_core_services_synchronization_telem_telem_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*TelemResponse); i { case 0: return &v.state diff --git a/core/services/synchronization/telem/telem_automation_custom.pb.go b/core/services/synchronization/telem/telem_automation_custom.pb.go index a53339eda0..30ddce6f79 100644 --- a/core/services/synchronization/telem/telem_automation_custom.pb.go +++ b/core/services/synchronization/telem/telem_automation_custom.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.34.2 // protoc v4.25.1 // source: core/services/synchronization/telem/telem_automation_custom.proto @@ -289,7 +289,7 @@ func file_core_services_synchronization_telem_telem_automation_custom_proto_rawD } var file_core_services_synchronization_telem_telem_automation_custom_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_core_services_synchronization_telem_telem_automation_custom_proto_goTypes = []interface{}{ +var file_core_services_synchronization_telem_telem_automation_custom_proto_goTypes = []any{ (*BlockNumber)(nil), // 0: telem.BlockNumber (*NodeVersion)(nil), // 1: telem.NodeVersion (*AutomationTelemWrapper)(nil), // 2: telem.AutomationTelemWrapper @@ -310,7 +310,7 @@ func file_core_services_synchronization_telem_telem_automation_custom_proto_init return } if !protoimpl.UnsafeEnabled { - file_core_services_synchronization_telem_telem_automation_custom_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_core_services_synchronization_telem_telem_automation_custom_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*BlockNumber); i { case 0: return &v.state @@ -322,7 +322,7 @@ func file_core_services_synchronization_telem_telem_automation_custom_proto_init return nil } } - file_core_services_synchronization_telem_telem_automation_custom_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_core_services_synchronization_telem_telem_automation_custom_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*NodeVersion); i { case 0: return &v.state @@ -334,7 +334,7 @@ func file_core_services_synchronization_telem_telem_automation_custom_proto_init return nil } } - file_core_services_synchronization_telem_telem_automation_custom_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_core_services_synchronization_telem_telem_automation_custom_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*AutomationTelemWrapper); i { case 0: return &v.state @@ -347,7 +347,7 @@ func file_core_services_synchronization_telem_telem_automation_custom_proto_init } } } - file_core_services_synchronization_telem_telem_automation_custom_proto_msgTypes[2].OneofWrappers = []interface{}{ + file_core_services_synchronization_telem_telem_automation_custom_proto_msgTypes[2].OneofWrappers = []any{ (*AutomationTelemWrapper_BlockNumber)(nil), (*AutomationTelemWrapper_NodeVersion)(nil), } diff --git a/core/services/synchronization/telem/telem_enhanced_ea.pb.go b/core/services/synchronization/telem/telem_enhanced_ea.pb.go index a9a81dabfc..c8983a06fe 100644 --- a/core/services/synchronization/telem/telem_enhanced_ea.pb.go +++ b/core/services/synchronization/telem/telem_enhanced_ea.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.34.2 // protoc v4.25.1 // source: core/services/synchronization/telem/telem_enhanced_ea.proto @@ -239,7 +239,7 @@ func file_core_services_synchronization_telem_telem_enhanced_ea_proto_rawDescGZI } var file_core_services_synchronization_telem_telem_enhanced_ea_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_core_services_synchronization_telem_telem_enhanced_ea_proto_goTypes = []interface{}{ +var file_core_services_synchronization_telem_telem_enhanced_ea_proto_goTypes = []any{ (*EnhancedEA)(nil), // 0: telem.EnhancedEA } var file_core_services_synchronization_telem_telem_enhanced_ea_proto_depIdxs = []int32{ @@ -256,7 +256,7 @@ func file_core_services_synchronization_telem_telem_enhanced_ea_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_core_services_synchronization_telem_telem_enhanced_ea_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_core_services_synchronization_telem_telem_enhanced_ea_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*EnhancedEA); i { case 0: return &v.state diff --git a/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go b/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go index e152cb4b15..856619e193 100644 --- a/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go +++ b/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.34.2 // protoc v4.25.1 // source: core/services/synchronization/telem/telem_enhanced_ea_mercury.proto @@ -20,6 +20,56 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type MarketStatus int32 + +const ( + // Same values as those used by OCR. + MarketStatus_UNKNOWN MarketStatus = 0 + MarketStatus_CLOSED MarketStatus = 1 + MarketStatus_OPEN MarketStatus = 2 +) + +// Enum value maps for MarketStatus. +var ( + MarketStatus_name = map[int32]string{ + 0: "UNKNOWN", + 1: "CLOSED", + 2: "OPEN", + } + MarketStatus_value = map[string]int32{ + "UNKNOWN": 0, + "CLOSED": 1, + "OPEN": 2, + } +) + +func (x MarketStatus) Enum() *MarketStatus { + p := new(MarketStatus) + *p = x + return p +} + +func (x MarketStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (MarketStatus) Descriptor() protoreflect.EnumDescriptor { + return file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_enumTypes[0].Descriptor() +} + +func (MarketStatus) Type() protoreflect.EnumType { + return &file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_enumTypes[0] +} + +func (x MarketStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use MarketStatus.Descriptor instead. +func (MarketStatus) EnumDescriptor() ([]byte, []int) { + return file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_rawDescGZIP(), []int{0} +} + type EnhancedEAMercury struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -58,10 +108,12 @@ type EnhancedEAMercury struct { ObservationAsk int64 `protobuf:"varint,17,opt,name=observation_ask,json=observationAsk,proto3" json:"observation_ask,omitempty"` // This value overflows, will be reserved and removed in future versions ObservationBidString string `protobuf:"bytes,23,opt,name=observation_bid_string,json=observationBidString,proto3" json:"observation_bid_string,omitempty"` ObservationAskString string `protobuf:"bytes,24,opt,name=observation_ask_string,json=observationAskString,proto3" json:"observation_ask_string,omitempty"` - ConfigDigest string `protobuf:"bytes,18,opt,name=config_digest,json=configDigest,proto3" json:"config_digest,omitempty"` - Round int64 `protobuf:"varint,19,opt,name=round,proto3" json:"round,omitempty"` - Epoch int64 `protobuf:"varint,20,opt,name=epoch,proto3" json:"epoch,omitempty"` - AssetSymbol string `protobuf:"bytes,21,opt,name=asset_symbol,json=assetSymbol,proto3" json:"asset_symbol,omitempty"` + // v4 + ObservationMarketStatus MarketStatus `protobuf:"varint,34,opt,name=observation_market_status,json=observationMarketStatus,proto3,enum=telem.MarketStatus" json:"observation_market_status,omitempty"` + ConfigDigest string `protobuf:"bytes,18,opt,name=config_digest,json=configDigest,proto3" json:"config_digest,omitempty"` + Round int64 `protobuf:"varint,19,opt,name=round,proto3" json:"round,omitempty"` + Epoch int64 `protobuf:"varint,20,opt,name=epoch,proto3" json:"epoch,omitempty"` + AssetSymbol string `protobuf:"bytes,21,opt,name=asset_symbol,json=assetSymbol,proto3" json:"asset_symbol,omitempty"` } func (x *EnhancedEAMercury) Reset() { @@ -299,6 +351,13 @@ func (x *EnhancedEAMercury) GetObservationAskString() string { return "" } +func (x *EnhancedEAMercury) GetObservationMarketStatus() MarketStatus { + if x != nil { + return x.ObservationMarketStatus + } + return MarketStatus_UNKNOWN +} + func (x *EnhancedEAMercury) GetConfigDigest() string { if x != nil { return x.ConfigDigest @@ -334,7 +393,7 @@ var file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_raw 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x5f, 0x65, 0x6e, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x5f, 0x65, 0x61, 0x5f, 0x6d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x79, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x22, 0xa9, 0x0c, 0x0a, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x22, 0xfa, 0x0c, 0x0a, 0x11, 0x45, 0x6e, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x45, 0x41, 0x4d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, @@ -426,19 +485,28 @@ var file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_raw 0x0a, 0x16, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x73, 0x6b, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x73, 0x6b, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, - 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, - 0x6e, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x12, - 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, - 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, - 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x73, 0x73, - 0x65, 0x74, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x42, 0x4e, 0x5a, 0x4c, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x61, 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x69, 0x6e, - 0x6b, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x69, 0x6e, 0x67, 0x12, 0x4f, 0x0a, 0x19, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2e, + 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x17, 0x6f, 0x62, + 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, + 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x73, + 0x73, 0x65, 0x74, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x2a, 0x31, 0x0a, 0x0c, 0x4d, 0x61, 0x72, + 0x6b, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, + 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, + 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4f, 0x50, 0x45, 0x4e, 0x10, 0x02, 0x42, 0x4e, 0x5a, 0x4c, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -453,16 +521,19 @@ func file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_ra return file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_rawDescData } +var file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_goTypes = []interface{}{ - (*EnhancedEAMercury)(nil), // 0: telem.EnhancedEAMercury +var file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_goTypes = []any{ + (MarketStatus)(0), // 0: telem.MarketStatus + (*EnhancedEAMercury)(nil), // 1: telem.EnhancedEAMercury } var file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 0, // 0: telem.EnhancedEAMercury.observation_market_status:type_name -> telem.MarketStatus + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } func init() { file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_init() } @@ -471,7 +542,7 @@ func file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_in return } if !protoimpl.UnsafeEnabled { - file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*EnhancedEAMercury); i { case 0: return &v.state @@ -489,13 +560,14 @@ func file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_in File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_rawDesc, - NumEnums: 0, + NumEnums: 1, NumMessages: 1, NumExtensions: 0, NumServices: 0, }, GoTypes: file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_goTypes, DependencyIndexes: file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_depIdxs, + EnumInfos: file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_enumTypes, MessageInfos: file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_msgTypes, }.Build() File_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto = out.File diff --git a/core/services/synchronization/telem/telem_enhanced_ea_mercury.proto b/core/services/synchronization/telem/telem_enhanced_ea_mercury.proto index 8488eb1d50..bb41ff86ee 100644 --- a/core/services/synchronization/telem/telem_enhanced_ea_mercury.proto +++ b/core/services/synchronization/telem/telem_enhanced_ea_mercury.proto @@ -4,6 +4,13 @@ option go_package = "github.com/smartcontractkit/chainlink/v2/core/services/sync package telem; +enum MarketStatus { + // Same values as those used by OCR. + UNKNOWN = 0; + CLOSED = 1; + OPEN = 2; +} + message EnhancedEAMercury { uint32 version = 32; @@ -44,6 +51,8 @@ message EnhancedEAMercury { int64 observation_ask=17; // This value overflows, will be reserved and removed in future versions string observation_bid_string = 23; string observation_ask_string = 24; + // v4 + MarketStatus observation_market_status=34; string config_digest = 18; int64 round=19; diff --git a/core/services/synchronization/telem/telem_functions_request.pb.go b/core/services/synchronization/telem/telem_functions_request.pb.go index 0a4a2649b4..89aa9e3fe3 100644 --- a/core/services/synchronization/telem/telem_functions_request.pb.go +++ b/core/services/synchronization/telem/telem_functions_request.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.34.2 // protoc v4.25.1 // source: core/services/synchronization/telem/telem_functions_request.proto @@ -119,7 +119,7 @@ func file_core_services_synchronization_telem_telem_functions_request_proto_rawD } var file_core_services_synchronization_telem_telem_functions_request_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_core_services_synchronization_telem_telem_functions_request_proto_goTypes = []interface{}{ +var file_core_services_synchronization_telem_telem_functions_request_proto_goTypes = []any{ (*FunctionsRequest)(nil), // 0: telem.FunctionsRequest } var file_core_services_synchronization_telem_telem_functions_request_proto_depIdxs = []int32{ @@ -136,7 +136,7 @@ func file_core_services_synchronization_telem_telem_functions_request_proto_init return } if !protoimpl.UnsafeEnabled { - file_core_services_synchronization_telem_telem_functions_request_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_core_services_synchronization_telem_telem_functions_request_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*FunctionsRequest); i { case 0: return &v.state diff --git a/go.mod b/go.mod index 326c06396d..8e2103eb24 100644 --- a/go.mod +++ b/go.mod @@ -72,9 +72,9 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 diff --git a/go.sum b/go.sum index 2ec1753593..73d6d5b227 100644 --- a/go.sum +++ b/go.sum @@ -1136,12 +1136,12 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 h1:6s4cTIE3NbATxWLrD5JLCq097PC5Y4GKK/Kk4fhURpY= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc h1:nNZqLasN8y5huDKX76JUZtni7WkUI36J61//czbJpDM= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa/go.mod h1:wZvLHX/Sd9hskN51016cTFcT3G62KXVa6xbVDS7tRjc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 29af8b4c21..ed693f4fcc 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -28,7 +28,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc github.com/smartcontractkit/chainlink-testing-framework v1.33.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 @@ -377,7 +377,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 57b55a8b01..ca3ce8d903 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1486,12 +1486,12 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 h1:6s4cTIE3NbATxWLrD5JLCq097PC5Y4GKK/Kk4fhURpY= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc h1:nNZqLasN8y5huDKX76JUZtni7WkUI36J61//czbJpDM= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa/go.mod h1:wZvLHX/Sd9hskN51016cTFcT3G62KXVa6xbVDS7tRjc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 093a6ac6c5..3d1ae6c7a9 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.31.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc github.com/smartcontractkit/chainlink-testing-framework v1.33.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 @@ -369,7 +369,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 0db884f178..2a54ec9254 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1468,12 +1468,12 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996 h1:6s4cTIE3NbATxWLrD5JLCq097PC5Y4GKK/Kk4fhURpY= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731121127-5ae22cf04996/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc h1:nNZqLasN8y5huDKX76JUZtni7WkUI36J61//czbJpDM= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa/go.mod h1:wZvLHX/Sd9hskN51016cTFcT3G62KXVa6xbVDS7tRjc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= From 1ac2902c6c514c00341568b8c6dfd799cd262222 Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs <5300706+iljapavlovs@users.noreply.github.com> Date: Mon, 5 Aug 2024 15:00:39 +0300 Subject: [PATCH 032/432] VRF-1138: Make CTF tests to reuse existing VRF Wrapper (#13854) * VRF-1138: Make CTF tests to reuse existing VRF Wrapper * VRF-1138: remove old code * VRF-1138: remove comments * VRF-1138: refactoring * VRF-1138: pr comments * VRF-1138: pr comments * VRF-1138: fixing lint issues * VRF-1138: PR comments --- integration-tests/actions/actions.go | 6 +- .../actions/vrf/common/actions.go | 30 ++ .../actions/vrf/common/models.go | 1 + .../actions/vrf/vrfv2/contract_steps.go | 4 +- .../actions/vrf/vrfv2/setup_steps.go | 40 +-- .../actions/vrf/vrfv2plus/contract_steps.go | 68 ++++- .../actions/vrf/vrfv2plus/models.go | 4 +- .../actions/vrf/vrfv2plus/setup_steps.go | 270 +++++++++++++----- .../contracts/contract_vrf_models.go | 4 + .../contracts/ethereum_contracts.go | 4 +- .../contracts/ethereum_vrf_contracts.go | 20 ++ .../contracts/ethereum_vrfv2_contracts.go | 24 ++ .../contracts/ethereum_vrfv2plus_contracts.go | 24 ++ integration-tests/smoke/vrfv2plus_test.go | 45 ++- .../testconfig/common/vrf/common.go | 36 ++- integration-tests/testconfig/default.toml | 152 ++++++++++ integration-tests/testconfig/vrfv2/config.go | 6 - integration-tests/testconfig/vrfv2/vrfv2.toml | 12 +- .../testconfig/vrfv2plus/vrfv2plus.toml | 23 +- 19 files changed, 599 insertions(+), 174 deletions(-) diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index 65db18ad6f..8487e3a264 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -1216,7 +1216,7 @@ func RandBool() bool { return rand.Intn(2) == 1 } -func ContinuouslyGenerateTXsOnChain(sethClient *seth.Client, stopChannel chan bool, l zerolog.Logger) (bool, error) { +func ContinuouslyGenerateTXsOnChain(sethClient *seth.Client, stopChannel chan bool, wg *sync.WaitGroup, l zerolog.Logger) (bool, error) { counterContract, err := contracts.DeployCounterContract(sethClient) if err != nil { return false, err @@ -1230,6 +1230,10 @@ func ContinuouslyGenerateTXsOnChain(sethClient *seth.Client, stopChannel chan bo select { case <-stopChannel: l.Info().Str("Number of generated transactions on chain", count.String()).Msg("Stopping generating txs on chain. Desired block number reached.") + sleepDuration := time.Second * 10 + l.Info().Str("Waiting for", sleepDuration.String()).Msg("Waiting for transactions to be mined and avoid nonce issues") + time.Sleep(sleepDuration) + wg.Done() return true, nil default: err = counterContract.Increment() diff --git a/integration-tests/actions/vrf/common/actions.go b/integration-tests/actions/vrf/common/actions.go index e599c705ef..1300ac8b72 100644 --- a/integration-tests/actions/vrf/common/actions.go +++ b/integration-tests/actions/vrf/common/actions.go @@ -20,6 +20,7 @@ import ( ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" @@ -384,6 +385,35 @@ func BuildNewCLEnvForVRF(l zerolog.Logger, t *testing.T, envConfig VRFEnvConfig, return env, sethClient, nil } +func LoadExistingCLEnvForVRF( + t *testing.T, + envConfig VRFEnvConfig, + commonExistingEnvConfig *vrf_common_config.ExistingEnvConfig, + l zerolog.Logger, +) (*test_env.CLClusterTestEnv, *seth.Client, error) { + env, err := test_env.NewCLTestEnvBuilder(). + WithTestInstance(t). + WithTestConfig(&envConfig.TestConfig). + WithCustomCleanup(envConfig.CleanupFn). + Build() + if err != nil { + return nil, nil, fmt.Errorf("%s, err: %w", "error creating test env", err) + } + evmNetwork, err := env.GetFirstEvmNetwork() + if err != nil { + return nil, nil, err + } + sethClient, err := seth_utils.GetChainClient(envConfig.TestConfig, *evmNetwork) + if err != nil { + return nil, nil, err + } + err = FundNodesIfNeeded(testcontext.Get(t), commonExistingEnvConfig, sethClient, l) + if err != nil { + return nil, nil, err + } + return env, sethClient, nil +} + func GetRPCUrl(env *test_env.CLClusterTestEnv, chainID int64) (string, error) { provider, err := env.GetRpcProvider(chainID) if err != nil { diff --git a/integration-tests/actions/vrf/common/models.go b/integration-tests/actions/vrf/common/models.go index 9baa5c96e1..f51fd84ba0 100644 --- a/integration-tests/actions/vrf/common/models.go +++ b/integration-tests/actions/vrf/common/models.go @@ -55,6 +55,7 @@ type VRFContracts struct { VRFV2PlusConsumer []contracts.VRFv2PlusLoadTestConsumer LinkToken contracts.LinkToken MockETHLINKFeed contracts.VRFMockETHLINKFeed + LinkNativeFeedAddress string } type VRFOwnerConfig struct { diff --git a/integration-tests/actions/vrf/vrfv2/contract_steps.go b/integration-tests/actions/vrf/vrfv2/contract_steps.go index 324b65b5d6..1b909be9b8 100644 --- a/integration-tests/actions/vrf/vrfv2/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2/contract_steps.go @@ -635,7 +635,7 @@ func SetupNewConsumersAndSubs( ) ([]contracts.VRFv2LoadTestConsumer, []uint64, error) { consumers, err := DeployVRFV2Consumers(sethClient, coordinator.Address(), numberOfConsumerContractsToDeployAndAddToSub) if err != nil { - return nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, err } l.Info(). Str("Coordinator", *testConfig.VRFv2.ExistingEnvConfig.ExistingEnvConfig.CoordinatorAddress). @@ -649,7 +649,7 @@ func SetupNewConsumersAndSubs( numberOfSubToCreate, ) if err != nil { - return nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, err } return consumers, subIDs, nil } diff --git a/integration-tests/actions/vrf/vrfv2/setup_steps.go b/integration-tests/actions/vrf/vrfv2/setup_steps.go index c13aed807a..b5852f8281 100644 --- a/integration-tests/actions/vrf/vrfv2/setup_steps.go +++ b/integration-tests/actions/vrf/vrfv2/setup_steps.go @@ -8,8 +8,6 @@ import ( "github.com/smartcontractkit/seth" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" - "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" "golang.org/x/sync/errgroup" @@ -371,38 +369,30 @@ func SetupVRFV2ForNewEnv( func SetupVRFV2ForExistingEnv(t *testing.T, envConfig vrfcommon.VRFEnvConfig, l zerolog.Logger) (*vrfcommon.VRFContracts, *vrfcommon.VRFKeyData, *test_env.CLClusterTestEnv, *seth.Client, error) { commonExistingEnvConfig := envConfig.TestConfig.VRFv2.ExistingEnvConfig.ExistingEnvConfig - env, err := test_env.NewCLTestEnvBuilder(). - WithTestInstance(t). - WithTestConfig(&envConfig.TestConfig). - WithCustomCleanup(envConfig.CleanupFn). - Build() - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error creating test env", err) - } - evmNetwork, err := env.GetFirstEvmNetwork() - if err != nil { - return nil, nil, nil, nil, err - } - sethClient, err := seth_utils.GetChainClient(envConfig.TestConfig, *evmNetwork) + env, sethClient, err := vrfcommon.LoadExistingCLEnvForVRF( + t, + envConfig, + commonExistingEnvConfig, + l, + ) if err != nil { - return nil, nil, nil, nil, err + return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error loading existing CL env", err) } coordinator, err := contracts.LoadVRFCoordinatorV2(sethClient, *commonExistingEnvConfig.ConsumerAddress) if err != nil { return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error loading VRFCoordinator2", err) } - linkAddr := common.HexToAddress(*commonExistingEnvConfig.LinkAddress) - linkToken, err := contracts.LoadLinkTokenContract(l, sethClient, linkAddr) + linkAddress, err := coordinator.GetLinkAddress(testcontext.Get(t)) if err != nil { - return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error loading LinkToken", err) + return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error getting Link address from Coordinator", err) } - err = vrfcommon.FundNodesIfNeeded(testcontext.Get(t), commonExistingEnvConfig, sethClient, l) + linkToken, err := contracts.LoadLinkTokenContract(l, sethClient, common.HexToAddress(linkAddress.String())) if err != nil { - return nil, nil, nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error loading LinkToken", err) } blockHashStoreAddress, err := coordinator.GetBlockHashStoreAddress(testcontext.Get(t)) if err != nil { - return nil, nil, nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, nil, nil, err } blockHashStore, err := contracts.LoadBlockHashStore(sethClient, blockHashStoreAddress.String()) if err != nil { @@ -449,13 +439,13 @@ func SetupSubsAndConsumersForExistingEnv( l, ) if err != nil { - return nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, err } } else { addr := common.HexToAddress(*commonExistingEnvConfig.ConsumerAddress) consumer, err := contracts.LoadVRFv2LoadTestConsumer(sethClient, addr) if err != nil { - return nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, err } consumers = append(consumers, consumer) subIDs = append(subIDs, *testConfig.VRFv2.ExistingEnvConfig.SubID) @@ -471,7 +461,7 @@ func SetupSubsAndConsumersForExistingEnv( l, ) if err != nil { - return nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, err } } return subIDs, consumers, nil diff --git a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go index 479b00d952..5a4ec9ba11 100644 --- a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go @@ -56,7 +56,7 @@ func DeployVRFV2_5Contracts( } batchCoordinator, err := contracts.DeployBatchVRFCoordinatorV2Plus(chainClient, coordinator.Address()) if err != nil { - return nil, fmt.Errorf("%s, err %w", ErrDeployBatchCoordinatorV2Plus, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployBatchCoordinatorV2Plus, err) } return &vrfcommon.VRFContracts{ CoordinatorV2Plus: coordinator, @@ -407,7 +407,7 @@ func DeployVRFV2PlusDirectFundingContracts( linkTokenAddress string, linkEthFeedAddress string, coordinator contracts.VRFCoordinatorV2_5, - consumerContractsAmount int, + numberOfConsumerContracts int, wrapperSubId *big.Int, configGeneral *vrfv2plusconfig.General, ) (*VRFV2PlusWrapperContracts, error) { @@ -432,7 +432,7 @@ func DeployVRFV2PlusDirectFundingContracts( return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployWrapper, err) } } - consumers, err := DeployVRFV2PlusWrapperConsumers(sethClient, vrfv2PlusWrapper, consumerContractsAmount) + consumers, err := DeployVRFV2PlusWrapperConsumers(sethClient, vrfv2PlusWrapper, numberOfConsumerContracts) if err != nil { return nil, err } @@ -545,9 +545,9 @@ func WaitRandomWordsFulfilledEvent( return randomWordsFulfilledEvent, err } -func DeployVRFV2PlusWrapperConsumers(client *seth.Client, vrfV2PlusWrapper contracts.VRFV2PlusWrapper, consumerContractsAmount int) ([]contracts.VRFv2PlusWrapperLoadTestConsumer, error) { +func DeployVRFV2PlusWrapperConsumers(client *seth.Client, vrfV2PlusWrapper contracts.VRFV2PlusWrapper, numberOfConsumerContracts int) ([]contracts.VRFv2PlusWrapperLoadTestConsumer, error) { var consumers []contracts.VRFv2PlusWrapperLoadTestConsumer - for i := 1; i <= consumerContractsAmount; i++ { + for i := 1; i <= numberOfConsumerContracts; i++ { loadTestConsumer, err := contracts.DeployVRFV2PlusWrapperLoadTestConsumer(client, vrfV2PlusWrapper.Address()) if err != nil { return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrAdvancedConsumer, err) @@ -609,7 +609,7 @@ func SetupNewConsumersAndSubs( ) ([]contracts.VRFv2PlusLoadTestConsumer, []*big.Int, error) { consumers, err := DeployVRFV2PlusConsumers(sethClient, coordinator, consumerContractsAmount) if err != nil { - return nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, err } l.Info(). Str("Coordinator", *testConfig.VRFv2Plus.ExistingEnvConfig.ExistingEnvConfig.CoordinatorAddress). @@ -627,7 +627,7 @@ func SetupNewConsumersAndSubs( *testConfig.VRFv2Plus.General.SubscriptionBillingType, ) if err != nil { - return nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, err } return consumers, subIDs, nil } @@ -652,3 +652,57 @@ func CancelSubsAndReturnFunds(ctx context.Context, vrfContracts *vrfcommon.VRFCo } } } + +func FundWrapperConsumer( + sethClient *seth.Client, + subFundingType string, + linkToken contracts.LinkToken, + wrapperConsumer contracts.VRFv2PlusWrapperLoadTestConsumer, + vrfv2PlusConfig *vrfv2plusconfig.General, + l zerolog.Logger, +) error { + fundConsumerWithLink := func() error { + //fund consumer with Link + linkAmount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(*vrfv2PlusConfig.WrapperConsumerFundingAmountLink)) + l.Info(). + Str("Link Amount", linkAmount.String()). + Str("WrapperConsumerAddress", wrapperConsumer.Address()).Msg("Funding WrapperConsumer with Link") + return linkToken.Transfer( + wrapperConsumer.Address(), + linkAmount, + ) + } + fundConsumerWithNative := func() error { + //fund consumer with Eth (native token) + _, err := actions.SendFunds(l, sethClient, actions.FundsToSendPayload{ + ToAddress: common.HexToAddress(wrapperConsumer.Address()), + Amount: conversions.EtherToWei(big.NewFloat(*vrfv2PlusConfig.WrapperConsumerFundingAmountNativeToken)), + PrivateKey: sethClient.PrivateKeys[0], + }) + return err + } + switch vrfv2plusconfig.BillingType(subFundingType) { + case vrfv2plusconfig.BillingType_Link: + err := fundConsumerWithLink() + if err != nil { + return err + } + case vrfv2plusconfig.BillingType_Native: + err := fundConsumerWithNative() + if err != nil { + return err + } + case vrfv2plusconfig.BillingType_Link_and_Native: + err := fundConsumerWithLink() + if err != nil { + return err + } + err = fundConsumerWithNative() + if err != nil { + return err + } + default: + return fmt.Errorf("invalid billing type: %s", subFundingType) + } + return nil +} diff --git a/integration-tests/actions/vrf/vrfv2plus/models.go b/integration-tests/actions/vrf/vrfv2plus/models.go index a2ca8ec582..5198439c05 100644 --- a/integration-tests/actions/vrf/vrfv2plus/models.go +++ b/integration-tests/actions/vrf/vrfv2plus/models.go @@ -5,6 +5,6 @@ import ( ) type VRFV2PlusWrapperContracts struct { - VRFV2PlusWrapper contracts.VRFV2PlusWrapper - LoadTestConsumers []contracts.VRFv2PlusWrapperLoadTestConsumer + VRFV2PlusWrapper contracts.VRFV2PlusWrapper + WrapperConsumers []contracts.VRFv2PlusWrapperLoadTestConsumer } diff --git a/integration-tests/actions/vrf/vrfv2plus/setup_steps.go b/integration-tests/actions/vrf/vrfv2plus/setup_steps.go index f3c7d53d6e..4833afb9fe 100644 --- a/integration-tests/actions/vrf/vrfv2plus/setup_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/setup_steps.go @@ -8,8 +8,6 @@ import ( "github.com/smartcontractkit/seth" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" - "github.com/shopspring/decimal" "golang.org/x/sync/errgroup" @@ -17,7 +15,6 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" - "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" @@ -28,7 +25,7 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" - vrfv2plus_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2plus" + vrfv2plusconfig "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2plus" "github.com/smartcontractkit/chainlink/integration-tests/types" ) @@ -201,7 +198,7 @@ func SetupVRFV2_5Environment( return vrfContracts, &vrfKeyData, nodeTypeToNodeMap, nil } -func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, config *vrfv2plus_config.General, pubKeyCompressed string, l zerolog.Logger, vrfNode *vrfcommon.VRFNode) error { +func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, config *vrfv2plusconfig.General, pubKeyCompressed string, l zerolog.Logger, vrfNode *vrfcommon.VRFNode) error { vrfJobSpecConfig := vrfcommon.VRFJobSpecConfig{ ForwardingAllowed: *config.VRFJobForwardingAllowed, CoordinatorAddress: contracts.CoordinatorV2Plus.Address(), @@ -235,7 +232,10 @@ func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, config *v nodeConfig := node.NewConfig(vrfNode.CLNode.NodeConfig, node.WithKeySpecificMaxGasPrice(vrfNode.TXKeyAddressStrings, *config.CLNodeMaxGasPriceGWei), ) - l.Info().Msg("Restarting Node with new sending key PriceMax configuration") + l.Info(). + Strs("Sending Keys", vrfNode.TXKeyAddressStrings). + Int64("Price Max Setting", *config.CLNodeMaxGasPriceGWei). + Msg("Restarting Node with new sending key PriceMax configuration") err = vrfNode.CLNode.Restart(nodeConfig) if err != nil { return fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrRestartCLNode, err) @@ -243,29 +243,119 @@ func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, config *v return nil } -func SetupVRFV2PlusWrapperEnvironment( +func SetupVRFV2PlusWrapperForExistingEnv( ctx context.Context, + sethClient *seth.Client, + vrfContracts *vrfcommon.VRFContracts, + keyHash [32]byte, + vrfv2PlusTestConfig types.VRFv2PlusTestConfig, + numberOfConsumerContracts int, l zerolog.Logger, +) (*VRFV2PlusWrapperContracts, *big.Int, error) { + config := *vrfv2PlusTestConfig.GetVRFv2PlusConfig() + var wrapper contracts.VRFV2PlusWrapper + var err error + if *config.ExistingEnvConfig.UseExistingWrapper { + wrapper, err = contracts.LoadVRFV2PlusWrapper(sethClient, *config.ExistingEnvConfig.WrapperAddress) + if err != nil { + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, "error loading VRFV2PlusWrapper", err) + } + } else { + wrapperSubId, err := CreateSubAndFindSubID(ctx, sethClient, vrfContracts.CoordinatorV2Plus) + if err != nil { + return nil, nil, err + } + wrapper, err = contracts.DeployVRFV2PlusWrapper(sethClient, vrfContracts.LinkToken.Address(), vrfContracts.LinkNativeFeedAddress, vrfContracts.CoordinatorV2Plus.Address(), wrapperSubId) + if err != nil { + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployWrapper, err) + } + err = FundSubscriptions( + big.NewFloat(*config.General.SubscriptionFundingAmountNative), + big.NewFloat(*config.General.SubscriptionFundingAmountLink), + vrfContracts.LinkToken, + vrfContracts.CoordinatorV2Plus, + []*big.Int{wrapperSubId}, + *config.General.SubscriptionBillingType, + ) + if err != nil { + return nil, nil, err + } + err = vrfContracts.CoordinatorV2Plus.AddConsumer(wrapperSubId, wrapper.Address()) + if err != nil { + return nil, nil, err + } + err = wrapper.SetConfig( + *config.General.WrapperGasOverhead, + *config.General.CoordinatorGasOverheadNative, + *config.General.CoordinatorGasOverheadLink, + *config.General.CoordinatorGasOverheadPerWord, + *config.General.CoordinatorNativePremiumPercentage, + *config.General.CoordinatorLinkPremiumPercentage, + keyHash, + *config.General.WrapperMaxNumberOfWords, + *config.General.StalenessSeconds, + decimal.RequireFromString(*config.General.FallbackWeiPerUnitLink).BigInt(), + *config.General.FulfillmentFlatFeeNativePPM, + *config.General.FulfillmentFlatFeeLinkDiscountPPM, + ) + if err != nil { + return nil, nil, err + } + } + wrapperSubID, err := wrapper.GetSubID(ctx) + if err != nil { + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, "error getting subID", err) + } + var wrapperConsumers []contracts.VRFv2PlusWrapperLoadTestConsumer + if *config.ExistingEnvConfig.CreateFundAddWrapperConsumers { + wrapperConsumers, err = DeployVRFV2PlusWrapperConsumers(sethClient, wrapper, numberOfConsumerContracts) + if err != nil { + return nil, nil, err + } + } else { + wrapperConsumer, err := contracts.LoadVRFV2WrapperLoadTestConsumer(sethClient, *config.ExistingEnvConfig.WrapperConsumerAddress) + if err != nil { + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, "error loading VRFV2WrapperLoadTestConsumer", err) + } + wrapperConsumers = append(wrapperConsumers, wrapperConsumer) + } + wrapperContracts := &VRFV2PlusWrapperContracts{wrapper, wrapperConsumers} + for _, consumer := range wrapperConsumers { + err = FundWrapperConsumer( + sethClient, + *config.General.SubscriptionBillingType, + vrfContracts.LinkToken, + consumer, + config.General, + l, + ) + if err != nil { + return nil, nil, err + } + } + return wrapperContracts, wrapperSubID, nil +} + +func SetupVRFV2PlusWrapperForNewEnv( + ctx context.Context, sethClient *seth.Client, vrfv2PlusTestConfig types.VRFv2PlusTestConfig, - linkToken contracts.LinkToken, - mockNativeLINKFeed contracts.MockETHLINKFeed, - coordinator contracts.VRFCoordinatorV2_5, + vrfContracts *vrfcommon.VRFContracts, keyHash [32]byte, wrapperConsumerContractsAmount int, + l zerolog.Logger, ) (*VRFV2PlusWrapperContracts, *big.Int, error) { // external EOA has to create a subscription for the wrapper first - wrapperSubId, err := CreateSubAndFindSubID(ctx, sethClient, coordinator) + wrapperSubId, err := CreateSubAndFindSubID(ctx, sethClient, vrfContracts.CoordinatorV2Plus) if err != nil { return nil, nil, err } - vrfv2PlusConfig := vrfv2PlusTestConfig.GetVRFv2PlusConfig().General wrapperContracts, err := DeployVRFV2PlusDirectFundingContracts( sethClient, - linkToken.Address(), - mockNativeLINKFeed.Address(), - coordinator, + vrfContracts.LinkToken.Address(), + vrfContracts.MockETHLINKFeed.Address(), + vrfContracts.CoordinatorV2Plus, wrapperConsumerContractsAmount, wrapperSubId, vrfv2PlusConfig, @@ -273,13 +363,11 @@ func SetupVRFV2PlusWrapperEnvironment( if err != nil { return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } - // once the wrapper is deployed, wrapper address will become consumer of external EOA subscription - err = coordinator.AddConsumer(wrapperSubId, wrapperContracts.VRFV2PlusWrapper.Address()) + err = vrfContracts.CoordinatorV2Plus.AddConsumer(wrapperSubId, wrapperContracts.VRFV2PlusWrapper.Address()) if err != nil { return nil, nil, err } - err = wrapperContracts.VRFV2PlusWrapper.SetConfig( *vrfv2PlusConfig.WrapperGasOverhead, *vrfv2PlusConfig.CoordinatorGasOverheadNative, @@ -297,53 +385,35 @@ func SetupVRFV2PlusWrapperEnvironment( if err != nil { return nil, nil, err } - //fund sub wrapperSubID, err := wrapperContracts.VRFV2PlusWrapper.GetSubID(ctx) if err != nil { return nil, nil, err } - err = FundSubscriptions( big.NewFloat(*vrfv2PlusTestConfig.GetVRFv2PlusConfig().General.SubscriptionFundingAmountNative), big.NewFloat(*vrfv2PlusTestConfig.GetVRFv2PlusConfig().General.SubscriptionFundingAmountLink), - linkToken, - coordinator, + vrfContracts.LinkToken, + vrfContracts.CoordinatorV2Plus, []*big.Int{wrapperSubID}, *vrfv2PlusConfig.SubscriptionBillingType, ) if err != nil { return nil, nil, err } - - //fund consumer with Link - err = linkToken.Transfer( - wrapperContracts.LoadTestConsumers[0].Address(), - big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(*vrfv2PlusConfig.WrapperConsumerFundingAmountLink)), - ) - if err != nil { - return nil, nil, err - } - - //fund consumer with Eth (native token) - _, err = actions.SendFunds(l, sethClient, actions.FundsToSendPayload{ - ToAddress: common.HexToAddress(wrapperContracts.LoadTestConsumers[0].Address()), - Amount: conversions.EtherToWei(big.NewFloat(*vrfv2PlusConfig.WrapperConsumerFundingAmountNativeToken)), - PrivateKey: sethClient.PrivateKeys[0], - }) - if err != nil { - return nil, nil, err - } - - wrapperConsumerBalanceBeforeRequestWei, err := sethClient.Client.BalanceAt(ctx, common.HexToAddress(wrapperContracts.LoadTestConsumers[0].Address()), nil) - if err != nil { - return nil, nil, err + for _, consumer := range wrapperContracts.WrapperConsumers { + err = FundWrapperConsumer( + sethClient, + *vrfv2PlusConfig.SubscriptionBillingType, + vrfContracts.LinkToken, + consumer, + vrfv2PlusConfig, + l, + ) + if err != nil { + return nil, nil, err + } } - l.Info(). - Str("WrapperConsumerBalanceBeforeRequestWei", wrapperConsumerBalanceBeforeRequestWei.String()). - Str("WrapperConsumerAddress", wrapperContracts.LoadTestConsumers[0].Address()). - Msg("WrapperConsumerBalanceBeforeRequestWei") - return wrapperContracts, wrapperSubID, nil } @@ -421,47 +491,45 @@ func SetupVRFV2PlusForNewEnv( func SetupVRFV2PlusForExistingEnv(t *testing.T, envConfig vrfcommon.VRFEnvConfig, l zerolog.Logger) (*vrfcommon.VRFContracts, *vrfcommon.VRFKeyData, *test_env.CLClusterTestEnv, *seth.Client, error) { commonExistingEnvConfig := envConfig.TestConfig.VRFv2Plus.ExistingEnvConfig.ExistingEnvConfig - env, err := test_env.NewCLTestEnvBuilder(). - WithTestInstance(t). - WithTestConfig(&envConfig.TestConfig). - WithCustomCleanup(envConfig.CleanupFn). - Build() - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error creating test env", err) - } - evmNetwork, err := env.GetFirstEvmNetwork() - if err != nil { - return nil, nil, nil, nil, err - } - sethClient, err := seth_utils.GetChainClient(envConfig.TestConfig, *evmNetwork) + env, sethClient, err := vrfcommon.LoadExistingCLEnvForVRF( + t, + envConfig, + commonExistingEnvConfig, + l, + ) if err != nil { - return nil, nil, nil, nil, err + return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error loading existing CL env", err) } coordinator, err := contracts.LoadVRFCoordinatorV2_5(sethClient, *commonExistingEnvConfig.CoordinatorAddress) if err != nil { return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error loading VRFCoordinator2_5", err) } - linkToken, err := contracts.LoadLinkTokenContract(l, sethClient, common.HexToAddress(*commonExistingEnvConfig.LinkAddress)) + linkAddress, err := coordinator.GetLinkAddress(testcontext.Get(t)) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error getting Link address from Coordinator", err) + } + linkToken, err := contracts.LoadLinkTokenContract(l, sethClient, common.HexToAddress(linkAddress.String())) if err != nil { return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error loading LinkToken", err) } - err = vrfcommon.FundNodesIfNeeded(testcontext.Get(t), commonExistingEnvConfig, sethClient, l) + linkNativeFeedAddress, err := coordinator.GetLinkNativeFeed(testcontext.Get(t)) if err != nil { - return nil, nil, nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error getting Link address from Coordinator", err) } blockHashStoreAddress, err := coordinator.GetBlockHashStoreAddress(testcontext.Get(t)) if err != nil { - return nil, nil, nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, nil, nil, err } blockHashStore, err := contracts.LoadBlockHashStore(sethClient, blockHashStoreAddress.String()) if err != nil { return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error loading BlockHashStore", err) } vrfContracts := &vrfcommon.VRFContracts{ - CoordinatorV2Plus: coordinator, - VRFV2PlusConsumer: nil, - LinkToken: linkToken, - BHS: blockHashStore, + CoordinatorV2Plus: coordinator, + VRFV2PlusConsumer: nil, + LinkToken: linkToken, + BHS: blockHashStore, + LinkNativeFeedAddress: linkNativeFeedAddress.String(), } vrfKey := &vrfcommon.VRFKeyData{ VRFKey: nil, @@ -500,12 +568,12 @@ func SetupSubsAndConsumersForExistingEnv( l, ) if err != nil { - return nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, err } } else { consumer, err := contracts.LoadVRFv2PlusLoadTestConsumer(sethClient, *commonExistingEnvConfig.ConsumerAddress) if err != nil { - return nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, err } consumers = append(consumers, consumer) var ok bool @@ -527,21 +595,65 @@ func SetupSubsAndConsumersForExistingEnv( l, ) if err != nil { - return nil, nil, fmt.Errorf("err: %w", err) + return nil, nil, err } } return subIDs, consumers, nil } func SelectBillingTypeWithDistribution(billingType string, distributionFn func() bool) (bool, error) { - switch vrfv2plus_config.BillingType(billingType) { - case vrfv2plus_config.BillingType_Link: + switch vrfv2plusconfig.BillingType(billingType) { + case vrfv2plusconfig.BillingType_Link: return false, nil - case vrfv2plus_config.BillingType_Native: + case vrfv2plusconfig.BillingType_Native: return true, nil - case vrfv2plus_config.BillingType_Link_and_Native: + case vrfv2plusconfig.BillingType_Link_and_Native: return distributionFn(), nil default: return false, fmt.Errorf("invalid billing type: %s", billingType) } } + +func SetupVRFV2PlusWrapperUniverse( + ctx context.Context, + sethClient *seth.Client, + vrfContracts *vrfcommon.VRFContracts, + config *tc.TestConfig, + keyHash [32]byte, + numberOfConsumerContracts int, + l zerolog.Logger, +) (*VRFV2PlusWrapperContracts, *big.Int, error) { + var ( + wrapperContracts *VRFV2PlusWrapperContracts + wrapperSubID *big.Int + err error + ) + if *config.VRFv2Plus.General.UseExistingEnv { + wrapperContracts, wrapperSubID, err = SetupVRFV2PlusWrapperForExistingEnv( + ctx, + sethClient, + vrfContracts, + keyHash, + config, + numberOfConsumerContracts, + l, + ) + if err != nil { + return nil, nil, err + } + } else { + wrapperContracts, wrapperSubID, err = SetupVRFV2PlusWrapperForNewEnv( + ctx, + sethClient, + config, + vrfContracts, + keyHash, + numberOfConsumerContracts, + l, + ) + if err != nil { + return nil, nil, err + } + } + return wrapperContracts, wrapperSubID, nil +} diff --git a/integration-tests/contracts/contract_vrf_models.go b/integration-tests/contracts/contract_vrf_models.go index 45825a18ff..c798c4921c 100644 --- a/integration-tests/contracts/contract_vrf_models.go +++ b/integration-tests/contracts/contract_vrf_models.go @@ -76,6 +76,8 @@ type VRFCoordinatorV2 interface { WaitForConfigSetEvent(timeout time.Duration) (*CoordinatorConfigSet, error) OracleWithdraw(recipient common.Address, amount *big.Int) error GetBlockHashStoreAddress(ctx context.Context) (common.Address, error) + GetLinkAddress(ctx context.Context) (common.Address, error) + GetLinkNativeFeed(ctx context.Context) (common.Address, error) } type VRFCoordinatorV2_5 interface { @@ -121,6 +123,8 @@ type VRFCoordinatorV2_5 interface { ParseRandomWordsFulfilled(log types.Log) (*CoordinatorRandomWordsFulfilled, error) WaitForConfigSetEvent(timeout time.Duration) (*CoordinatorConfigSet, error) GetBlockHashStoreAddress(ctx context.Context) (common.Address, error) + GetLinkAddress(ctx context.Context) (common.Address, error) + GetLinkNativeFeed(ctx context.Context) (common.Address, error) } type VRFCoordinatorV2PlusUpgradedVersion interface { diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index 2db6aeb463..5b08c9a9fb 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -770,12 +770,12 @@ func DeployLinkTokenContract(l zerolog.Logger, client *seth.Client) (*EthereumLi } func LoadLinkTokenContract(l zerolog.Logger, client *seth.Client, address common.Address) (*EthereumLinkToken, error) { - abi, err := link_token_interface.LinkTokenMetaData.GetAbi() + linkABI, err := link_token_interface.LinkTokenMetaData.GetAbi() if err != nil { return &EthereumLinkToken{}, fmt.Errorf("failed to get LinkToken ABI: %w", err) } - client.ContractStore.AddABI("LinkToken", *abi) + client.ContractStore.AddABI("LinkToken", *linkABI) client.ContractStore.AddBIN("LinkToken", common.FromHex(link_token_interface.LinkTokenMetaData.Bin)) linkToken, err := link_token_interface.NewLinkToken(address, wrappers.MustNewWrappedContractBackend(nil, client)) diff --git a/integration-tests/contracts/ethereum_vrf_contracts.go b/integration-tests/contracts/ethereum_vrf_contracts.go index e4dbb87d0b..a09cc809c6 100644 --- a/integration-tests/contracts/ethereum_vrf_contracts.go +++ b/integration-tests/contracts/ethereum_vrf_contracts.go @@ -13,6 +13,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_optimism" "github.com/smartcontractkit/seth" @@ -546,3 +547,22 @@ func LoadVRFV2PlusWrapperOptimism(seth *seth.Client, addr string) (*EthereumVRFV wrapper: contract, }, nil } + +func LoadVRFV2WrapperLoadTestConsumer(seth *seth.Client, addr string) (*EthereumVRFV2PlusWrapperLoadTestConsumer, error) { + address := common.HexToAddress(addr) + abi, err := vrfv2plus_wrapper_load_test_consumer.VRFV2PlusWrapperLoadTestConsumerMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get VRFV2PlusWrapperLoadTestConsumer ABI: %w", err) + } + seth.ContractStore.AddABI("VRFV2PlusWrapperLoadTestConsumer", *abi) + seth.ContractStore.AddBIN("VRFV2PlusWrapperLoadTestConsumer", common.FromHex(vrfv2plus_wrapper_load_test_consumer.VRFV2PlusWrapperLoadTestConsumerMetaData.Bin)) + contract, err := vrfv2plus_wrapper_load_test_consumer.NewVRFV2PlusWrapperLoadTestConsumer(address, wrappers.MustNewWrappedContractBackend(nil, seth)) + if err != nil { + return nil, fmt.Errorf("failed to instantiate VRFV2PlusWrapperLoadTestConsumer instance: %w", err) + } + return &EthereumVRFV2PlusWrapperLoadTestConsumer{ + client: seth, + address: address, + consumer: contract, + }, nil +} diff --git a/integration-tests/contracts/ethereum_vrfv2_contracts.go b/integration-tests/contracts/ethereum_vrfv2_contracts.go index a9d1a93769..df4a6fb9fb 100644 --- a/integration-tests/contracts/ethereum_vrfv2_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2_contracts.go @@ -594,6 +594,30 @@ func (v *EthereumVRFCoordinatorV2) ParseLog(log types.Log) (generated.AbigenLog, return v.coordinator.ParseLog(log) } +func (v *EthereumVRFCoordinatorV2) GetLinkAddress(ctx context.Context) (common.Address, error) { + opts := &bind.CallOpts{ + From: v.client.MustGetRootKeyAddress(), + Context: ctx, + } + address, err := v.coordinator.LINK(opts) + if err != nil { + return common.Address{}, err + } + return address, nil +} + +func (v *EthereumVRFCoordinatorV2) GetLinkNativeFeed(ctx context.Context) (common.Address, error) { + opts := &bind.CallOpts{ + From: v.client.MustGetRootKeyAddress(), + Context: ctx, + } + address, err := v.coordinator.LINKETHFEED(opts) + if err != nil { + return common.Address{}, err + } + return address, nil +} + // CancelSubscription cancels subscription by Sub owner, // return funds to specified address, // checks if pending requests for a sub exist diff --git a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go index 8e099b4f6b..9b286a1d05 100644 --- a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go @@ -340,6 +340,30 @@ func (v *EthereumVRFCoordinatorV2_5) GetBlockHashStoreAddress(ctx context.Contex return blockHashStoreAddress, nil } +func (v *EthereumVRFCoordinatorV2_5) GetLinkAddress(ctx context.Context) (common.Address, error) { + opts := &bind.CallOpts{ + From: v.client.MustGetRootKeyAddress(), + Context: ctx, + } + address, err := v.coordinator.LINK(opts) + if err != nil { + return common.Address{}, err + } + return address, nil +} + +func (v *EthereumVRFCoordinatorV2_5) GetLinkNativeFeed(ctx context.Context) (common.Address, error) { + opts := &bind.CallOpts{ + From: v.client.MustGetRootKeyAddress(), + Context: ctx, + } + address, err := v.coordinator.LINKNATIVEFEED(opts) + if err != nil { + return common.Address{}, err + } + return address, nil +} + // OwnerCancelSubscription cancels subscription by Coordinator owner // return funds to sub owner, // does not check if pending requests for a sub exist diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index da2989d8fc..a1ac5fd554 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -289,16 +289,14 @@ func TestVRFv2Plus(t *testing.T) { t.Run("Direct Funding", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) - wrapperContracts, wrapperSubID, err := vrfv2plus.SetupVRFV2PlusWrapperEnvironment( + wrapperContracts, wrapperSubID, err := vrfv2plus.SetupVRFV2PlusWrapperUniverse( testcontext.Get(t), - l, sethClient, + vrfContracts, &configCopy, - vrfContracts.LinkToken, - vrfContracts.MockETHLINKFeed, - vrfContracts.CoordinatorV2Plus, vrfKey.KeyHash, 1, + l, ) require.NoError(t, err) @@ -307,7 +305,7 @@ func TestVRFv2Plus(t *testing.T) { testConfig := configCopy.VRFv2Plus.General var isNativeBilling = false - wrapperConsumerJuelsBalanceBeforeRequest, err := vrfContracts.LinkToken.BalanceOf(testcontext.Get(t), wrapperContracts.LoadTestConsumers[0].Address()) + wrapperConsumerJuelsBalanceBeforeRequest, err := vrfContracts.LinkToken.BalanceOf(testcontext.Get(t), wrapperContracts.WrapperConsumers[0].Address()) require.NoError(t, err, "error getting wrapper consumer balance") wrapperSubscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), wrapperSubID) @@ -315,7 +313,7 @@ func TestVRFv2Plus(t *testing.T) { subBalanceBeforeRequest := wrapperSubscription.Balance randomWordsFulfilledEvent, err := vrfv2plus.DirectFundingRequestRandomnessAndWaitForFulfillment( - wrapperContracts.LoadTestConsumers[0], + wrapperContracts.WrapperConsumers[0], vrfContracts.CoordinatorV2Plus, vrfKey, wrapperSubID, @@ -331,13 +329,13 @@ func TestVRFv2Plus(t *testing.T) { subBalanceAfterRequest := wrapperSubscription.Balance require.Equal(t, expectedSubBalanceJuels, subBalanceAfterRequest) - consumerStatus, err := wrapperContracts.LoadTestConsumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) + consumerStatus, err := wrapperContracts.WrapperConsumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, consumerStatus.Fulfilled) expectedWrapperConsumerJuelsBalance := new(big.Int).Sub(wrapperConsumerJuelsBalanceBeforeRequest, consumerStatus.Paid) - wrapperConsumerJuelsBalanceAfterRequest, err := vrfContracts.LinkToken.BalanceOf(testcontext.Get(t), wrapperContracts.LoadTestConsumers[0].Address()) + wrapperConsumerJuelsBalanceAfterRequest, err := vrfContracts.LinkToken.BalanceOf(testcontext.Get(t), wrapperContracts.WrapperConsumers[0].Address()) require.NoError(t, err, "error getting wrapper consumer balance") require.Equal(t, expectedWrapperConsumerJuelsBalance, wrapperConsumerJuelsBalanceAfterRequest) @@ -356,7 +354,7 @@ func TestVRFv2Plus(t *testing.T) { testConfig := configCopy.VRFv2Plus.General var isNativeBilling = true - wrapperConsumerBalanceBeforeRequestWei, err := sethClient.Client.BalanceAt(testcontext.Get(t), common.HexToAddress(wrapperContracts.LoadTestConsumers[0].Address()), nil) + wrapperConsumerBalanceBeforeRequestWei, err := sethClient.Client.BalanceAt(testcontext.Get(t), common.HexToAddress(wrapperContracts.WrapperConsumers[0].Address()), nil) require.NoError(t, err, "error getting wrapper consumer balance") wrapperSubscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), wrapperSubID) @@ -364,7 +362,7 @@ func TestVRFv2Plus(t *testing.T) { subBalanceBeforeRequest := wrapperSubscription.NativeBalance randomWordsFulfilledEvent, err := vrfv2plus.DirectFundingRequestRandomnessAndWaitForFulfillment( - wrapperContracts.LoadTestConsumers[0], + wrapperContracts.WrapperConsumers[0], vrfContracts.CoordinatorV2Plus, vrfKey, wrapperSubID, @@ -380,13 +378,13 @@ func TestVRFv2Plus(t *testing.T) { subBalanceAfterRequest := wrapperSubscription.NativeBalance require.Equal(t, expectedSubBalanceWei, subBalanceAfterRequest) - consumerStatus, err := wrapperContracts.LoadTestConsumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) + consumerStatus, err := wrapperContracts.WrapperConsumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, consumerStatus.Fulfilled) expectedWrapperConsumerWeiBalance := new(big.Int).Sub(wrapperConsumerBalanceBeforeRequestWei, consumerStatus.Paid) - wrapperConsumerBalanceAfterRequestWei, err := sethClient.Client.BalanceAt(testcontext.Get(t), common.HexToAddress(wrapperContracts.LoadTestConsumers[0].Address()), nil) + wrapperConsumerBalanceAfterRequestWei, err := sethClient.Client.BalanceAt(testcontext.Get(t), common.HexToAddress(wrapperContracts.WrapperConsumers[0].Address()), nil) require.NoError(t, err, "error getting wrapper consumer balance") require.Equal(t, expectedWrapperConsumerWeiBalance, wrapperConsumerBalanceAfterRequestWei) @@ -1063,16 +1061,14 @@ func TestVRFv2PlusMigration(t *testing.T) { t.Run("Test migration of direct billing using VRFV2PlusWrapper subID", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) - wrapperContracts, wrapperSubID, err := vrfv2plus.SetupVRFV2PlusWrapperEnvironment( + wrapperContracts, wrapperSubID, err := vrfv2plus.SetupVRFV2PlusWrapperUniverse( testcontext.Get(t), - l, sethClient, + vrfContracts, &configCopy, - vrfContracts.LinkToken, - vrfContracts.MockETHLINKFeed, - vrfContracts.CoordinatorV2Plus, vrfKey.KeyHash, 1, + l, ) require.NoError(t, err) subID := wrapperSubID @@ -1203,7 +1199,7 @@ func TestVRFv2PlusMigration(t *testing.T) { // Verify rand requests fulfills with Link Token billing isNativeBilling := false randomWordsFulfilledEvent, err := vrfv2plus.DirectFundingRequestRandomnessAndWaitForFulfillment( - wrapperContracts.LoadTestConsumers[0], + wrapperContracts.WrapperConsumers[0], newCoordinator, vrfKey, subID, @@ -1212,14 +1208,14 @@ func TestVRFv2PlusMigration(t *testing.T) { l, ) require.NoError(t, err, "error requesting randomness and waiting for fulfilment") - consumerStatus, err := wrapperContracts.LoadTestConsumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) + consumerStatus, err := wrapperContracts.WrapperConsumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, consumerStatus.Fulfilled) // Verify rand requests fulfills with Native Token billing isNativeBilling = true randomWordsFulfilledEvent, err = vrfv2plus.DirectFundingRequestRandomnessAndWaitForFulfillment( - wrapperContracts.LoadTestConsumers[0], + wrapperContracts.WrapperConsumers[0], newCoordinator, vrfKey, subID, @@ -1228,7 +1224,7 @@ func TestVRFv2PlusMigration(t *testing.T) { l, ) require.NoError(t, err, "error requesting randomness and waiting for fulfilment") - consumerStatus, err = wrapperContracts.LoadTestConsumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) + consumerStatus, err = wrapperContracts.WrapperConsumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, consumerStatus.Fulfilled) }) @@ -1347,11 +1343,10 @@ func TestVRFV2PlusWithBHS(t *testing.T) { }() if *configCopy.VRFv2Plus.General.GenerateTXsOnChain { + wg.Add(1) go func() { - _, err := actions.ContinuouslyGenerateTXsOnChain(sethClient, desiredBlockNumberReached, l) + _, err := actions.ContinuouslyGenerateTXsOnChain(sethClient, desiredBlockNumberReached, &wg, l) require.NoError(t, err) - // Wait to let the transactions be mined and avoid nonce issues - time.Sleep(time.Second * 5) }() } wg.Wait() diff --git a/integration-tests/testconfig/common/vrf/common.go b/integration-tests/testconfig/common/vrf/common.go index e213191075..326f7c98c7 100644 --- a/integration-tests/testconfig/common/vrf/common.go +++ b/integration-tests/testconfig/common/vrf/common.go @@ -71,10 +71,13 @@ func (c *PerformanceConfig) Validate() error { type ExistingEnvConfig struct { CoordinatorAddress *string `toml:"coordinator_address"` + UseExistingWrapper *bool `toml:"use_existing_wrapper"` + WrapperAddress *string `toml:"wrapper_address"` ConsumerAddress *string `toml:"consumer_address"` - LinkAddress *string `toml:"link_address"` + WrapperConsumerAddress *string `toml:"wrapper_consumer_address"` KeyHash *string `toml:"key_hash"` CreateFundSubsAndAddConsumers *bool `toml:"create_fund_subs_and_add_consumers"` + CreateFundAddWrapperConsumers *bool `toml:"create_fund_add_wrapper_consumers"` NodeSendingKeys []string `toml:"node_sending_keys"` Funding } @@ -83,23 +86,33 @@ func (c *ExistingEnvConfig) Validate() error { if c.CreateFundSubsAndAddConsumers == nil { return errors.New("create_fund_subs_and_add_consumers must be set ") } + if c.CreateFundAddWrapperConsumers == nil { + return errors.New("create_fund_add_wrapper_consumers must be set ") + } if c.CoordinatorAddress == nil { return errors.New("coordinator_address must be set when using existing environment") } if !common.IsHexAddress(*c.CoordinatorAddress) { return errors.New("coordinator_address must be a valid hex address") } + if c.UseExistingWrapper == nil { + return errors.New("use_existing_wrapper must be set ") + } + if *c.UseExistingWrapper { + if c.WrapperAddress == nil { + return errors.New("wrapper_address must be set when using `use_existing_wrapper=true`") + } + if !common.IsHexAddress(*c.WrapperAddress) { + return errors.New("wrapper_address must be a valid hex address") + } + } if c.KeyHash == nil { return errors.New("key_hash must be set when using existing environment") } if *c.KeyHash == "" { return errors.New("key_hash must be a non-empty string") } - if *c.CreateFundSubsAndAddConsumers { - if err := c.Funding.Validate(); err != nil { - return err - } - } else { + if !*c.CreateFundSubsAndAddConsumers { if c.ConsumerAddress == nil || *c.ConsumerAddress == "" { return errors.New("consumer_address must be set when using existing environment") } @@ -107,7 +120,14 @@ func (c *ExistingEnvConfig) Validate() error { return errors.New("consumer_address must be a valid hex address") } } - + if !*c.CreateFundAddWrapperConsumers { + if c.WrapperConsumerAddress == nil || *c.WrapperConsumerAddress == "" { + return errors.New("wrapper_consumer_address must be set when using existing environment") + } + if !common.IsHexAddress(*c.WrapperConsumerAddress) { + return errors.New("wrapper_consumer_address must be a valid hex address") + } + } if c.NodeSendingKeys != nil { for _, key := range c.NodeSendingKeys { if !common.IsHexAddress(key) { @@ -115,7 +135,6 @@ func (c *ExistingEnvConfig) Validate() error { } } } - return nil } @@ -127,7 +146,6 @@ func (c *Funding) Validate() error { if c.NodeSendingKeyFundingMin != nil && *c.NodeSendingKeyFundingMin <= 0 { return errors.New("when set node_sending_key_funding_min must be a positive value") } - return nil } diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index d317d05bc4..e4e216cf4a 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -413,3 +413,155 @@ gas_price_estimation_enabled = true gas_price_estimation_blocks = 100 # priority of the transaction, can be "fast", "standard" or "slow" (the higher the priority, the higher adjustment factor will be used for gas estimation) [default: "standard"] gas_price_estimation_tx_priority = "standard" + + +[[Seth.networks]] +name = "Nexon Mainnet" +transaction_timeout = "3m" +eip_1559_dynamic_fees = true +transfer_gas_fee = 21_000 + +# manual settings, used when gas_price_estimation_enabled is false or when it fails +# legacy transactions +gas_price = 30_000_000_000 + +# EIP-1559 transactions +gas_fee_cap = 30_000_000_000 +gas_tip_cap = 1_800_000_000 + + +[Network.EVMNetworks.NEXON_MAINNET] +evm_name = "NEXON_MAINNET" +#evm_urls = ["rpc ws endpoint"] +#evm_http_urls = ["rpc http endpoint"] +client_implementation = "Ethereum" +#evm_keys = ["private keys you want to use"] +evm_simulated = false +evm_chainlink_transaction_limit = 5000 +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 10000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_chain_id = 60118 + +[[Seth.networks]] +name = "Nexon Stage" +transaction_timeout = "3m" +eip_1559_dynamic_fees = true +transfer_gas_fee = 21_000 + +# manual settings, used when gas_price_estimation_enabled is false or when it fails +# legacy transactions +gas_price = 30_000_000_000 + +# EIP-1559 transactions +gas_fee_cap = 30_000_000_000 +gas_tip_cap = 1_800_000_000 + + +[Network.EVMNetworks.NEXON_STAGE] +evm_name = "NEXON_STAGE" +#evm_urls = ["rpc ws endpoint"] +#evm_http_urls = ["rpc http endpoint"] +client_implementation = "Ethereum" +#evm_keys = ["private keys you want to use"] +evm_simulated = false +evm_chainlink_transaction_limit = 5000 +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 10000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_chain_id = 847799 + + +#### + +[[Seth.networks]] +name = "Nexon QA" +transaction_timeout = "3m" +eip_1559_dynamic_fees = true +transfer_gas_fee = 21_000 + +# manual settings, used when gas_price_estimation_enabled is false or when it fails +# legacy transactions +gas_price = 30_000_000_000 + +# EIP-1559 transactions +gas_fee_cap = 30_000_000_000 +gas_tip_cap = 1_800_000_000 + + +[Network.EVMNetworks.NEXON_QA] +evm_name = "NEXON_QA" +#evm_urls = ["rpc ws endpoint"] +#evm_http_urls = ["rpc http endpoint"] +client_implementation = "Ethereum" +#evm_keys = ["private keys you want to use"] +evm_simulated = false +evm_chainlink_transaction_limit = 5000 +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 10000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_chain_id = 807424 + +##### + +[[Seth.networks]] +name = "Nexon Test" +transaction_timeout = "3m" +eip_1559_dynamic_fees = true +transfer_gas_fee = 21_000 + +# manual settings, used when gas_price_estimation_enabled is false or when it fails +# legacy transactions +gas_price = 30_000_000_000 + +# EIP-1559 transactions +gas_fee_cap = 30_000_000_000 +gas_tip_cap = 1_800_000_000 + + +[Network.EVMNetworks.NEXON_TEST] +evm_name = "NEXON_TEST" +#evm_urls = ["rpc ws endpoint"] +#evm_http_urls = ["rpc http endpoint"] +client_implementation = "Ethereum" +#evm_keys = ["private keys you want to use"] +evm_simulated = false +evm_chainlink_transaction_limit = 5000 +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 10000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_chain_id = 595581 + +##### +[[Seth.networks]] +name = "Nexon Dev" +transaction_timeout = "3m" +eip_1559_dynamic_fees = true +transfer_gas_fee = 21_000 + +# manual settings, used when gas_price_estimation_enabled is false or when it fails +# legacy transactions +gas_price = 30_000_000_000 + +# EIP-1559 transactions +gas_fee_cap = 30_000_000_000 +gas_tip_cap = 1_800_000_000 + + +[Network.EVMNetworks.NEXON_DEV] +evm_name = "NEXON_DEV" +#evm_urls = ["rpc ws endpoint"] +#evm_http_urls = ["rpc http endpoint"] +client_implementation = "Ethereum" +#evm_keys = ["private keys you want to use"] +evm_simulated = false +evm_chainlink_transaction_limit = 5000 +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 10000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_chain_id = 5668 diff --git a/integration-tests/testconfig/vrfv2/config.go b/integration-tests/testconfig/vrfv2/config.go index 76d54a45d5..5e94040396 100644 --- a/integration-tests/testconfig/vrfv2/config.go +++ b/integration-tests/testconfig/vrfv2/config.go @@ -3,8 +3,6 @@ package testconfig import ( "errors" - "github.com/ethereum/go-ethereum/common" - vrf_common_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/common/vrf" ) @@ -52,10 +50,6 @@ func (c *ExistingEnvConfig) Validate() error { if *c.SubID == 0 { return errors.New("sub_id must be positive value") } - - if c.LinkAddress != nil && !common.IsHexAddress(*c.LinkAddress) { - return errors.New("link_address must be a valid hex address") - } } return c.Funding.Validate() diff --git a/integration-tests/testconfig/vrfv2/vrfv2.toml b/integration-tests/testconfig/vrfv2/vrfv2.toml index 011e90c15f..de7200b1e7 100644 --- a/integration-tests/testconfig/vrfv2/vrfv2.toml +++ b/integration-tests/testconfig/vrfv2/vrfv2.toml @@ -113,11 +113,17 @@ bhf_job_run_timeout = "1h" [VRFv2.ExistingEnv] coordinator_address = "" -consumer_address = "" -sub_id = 1 key_hash = "" + +use_existing_wrapper = false +wrapper_address = "" create_fund_subs_and_add_consumers = true -link_address = "" +sub_id = 1 +consumer_address = "" + +create_fund_add_wrapper_consumers = true +wrapper_consumer_address = "" + node_sending_key_funding_min = 10 node_sending_keys = [ "", diff --git a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml index 8f8aa9530e..88ca12975f 100644 --- a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml +++ b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml @@ -57,7 +57,7 @@ BatchSize = 100 """ [Common] -chainlink_node_funding = 0.5 +chainlink_node_funding = 0.7 [VRFv2Plus] [VRFv2Plus.General] @@ -138,11 +138,17 @@ bhf_job_run_timeout = "1h" [VRFv2Plus.ExistingEnv] coordinator_address = "" -consumer_address = "" -sub_id = "" key_hash = "" + +use_existing_wrapper = false +wrapper_address = "" create_fund_subs_and_add_consumers = true -link_address = "" +sub_id = "" +consumer_address = "" + +create_fund_add_wrapper_consumers = true +wrapper_consumer_address = "" + node_sending_key_funding_min = 1 node_sending_keys = [] @@ -272,7 +278,6 @@ key_hash = "0xd360445bacd26df47086ccf255c4f932d297ed8d5c7334b51eed32f61c541601" #key_hash = "0x2328cbee29e32d0b6662d6df82ff0fea7be300bd310561c92f515c9ee19464f1" #key_hash = "0x25f4e2d0509f42ec77db5380f3433a89fe623fa75f65d5b398d5f498327be4dd" create_fund_subs_and_add_consumers = true -link_address = "0x0Fd9e8d3aF1aaee056EB9e802c3A762a667b1904" node_sending_key_funding_min = 10 node_sending_keys = [ "0xD96013C241f1741C35a135321969f92Aae02A12F", @@ -407,7 +412,6 @@ consumer_address = "" sub_id = "" key_hash = "0xe13aa26fe94bfcd2ae055911f4d3bf1aed54ca6cf77af34e17f918802fd69ba1" create_fund_subs_and_add_consumers = true -link_address = "0xb1D4538B4571d411F07960EF2838Ce337FE1E80E" node_sending_key_funding_min = 20 node_sending_keys = [ "0xbE21ae371FcA1aC2d8A152e707D21e68d7d99252", @@ -551,7 +555,6 @@ consumer_address = "" sub_id = "" key_hash = "0x5b03254a80ea3eb72139ff0423cb88be42612780c3dd25f1d95a5ba7708a4be1" create_fund_subs_and_add_consumers = true -link_address = "0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846" node_sending_key_funding_min = 50 node_sending_keys = [ "0x3D7Da5D6A23CA2240CE576C8638C1798a023920a", @@ -676,7 +679,6 @@ consumer_address = "" sub_id = "" key_hash = "0xf5b4a359df0598eef89872ea2170f2afa844dbf74b417e6d44d4bda9420aceb2" create_fund_subs_and_add_consumers = true -link_address = "0x779877A7B0D9E8603169DdbD7836e478b4624789" node_sending_key_funding_min = 50 node_sending_keys = [ "0x0c0DC7f33A1256f0247c5ea75861d385fa5FED31", @@ -799,7 +801,6 @@ consumer_address = "" sub_id = "" key_hash = "0x4d43763d3eff849a89cf578a42787baa32132d7a80032125710e95b3972cd214" create_fund_subs_and_add_consumers = true -link_address = "0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06" node_sending_key_funding_min = 150 node_sending_keys = [ "0x4EE2Cc6D50E8acb6BaEf673B03559525a6c92fB8", @@ -878,7 +879,6 @@ consumer_address = "" sub_id = "" key_hash = "0x7d5692e71807c4c02f5a109627a9ad2b12a361a346790a306983af9a5e3a186f" create_fund_subs_and_add_consumers = true -link_address = "0x92Bd61014c5BDc4A43BBbaAEa63d0694BE43ECDd" node_sending_key_funding_min = 30 node_sending_keys = [ "0xB97c0C52A2B957b45DA213e652c76090DDd0FEc6", @@ -965,7 +965,6 @@ consumer_address = "" sub_id = "" key_hash = "0xdc023892a41e5fe74ec7c4c2e8c0a808b01aea7acaf2b2ae30f4e08df877c48b" create_fund_subs_and_add_consumers = true -link_address = "0xE4DDEDb5A220eC218791dC35b1b4D737ba813EE7" node_sending_key_funding_min = 30 node_sending_keys = [ "0xF3d9879a75BBD85890056D7c6cB37C555F9b41A3", @@ -1051,7 +1050,6 @@ consumer_address = "" sub_id = "" key_hash = "0x0cb2a18e8b762cb4c8f7b17a6cc02ac7b9d2a3346f048cfd2f5d37677f8747d8" create_fund_subs_and_add_consumers = true -link_address = "0xD694472F1CD02E1f3fc3534386bda6802fCFe0f7" node_sending_key_funding_min = 30 node_sending_keys = [ "0xBFD780Af421e98C35918e10B9d6da7389C3e1D10", @@ -1138,7 +1136,6 @@ consumer_address = "" sub_id = "" key_hash = "0xbc9f525e3e1d9e2336f7c77d5f33f5b60aab3765944617fed7f66a6afecac616" create_fund_subs_and_add_consumers = true -link_address = "0x8E3f5E6dFeb4498437149b0d347ef51427dB1DE2" node_sending_key_funding_min = 30 node_sending_keys = [ ] From 7ec99efc64832750825f8bc6711fb9794d6e40df Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Mon, 5 Aug 2024 14:29:14 +0100 Subject: [PATCH 033/432] changes to support deterministic message hash in the remote target (#13935) --- .changeset/polite-crabs-pretend.md | 5 ++ .../keystone_contracts_setup.go | 60 +++++++++++-------- .../integration_tests/mock_libocr.go | 15 +++-- core/capabilities/integration_tests/setup.go | 11 ++-- .../integration_tests/streams_test.go | 6 +- core/capabilities/launcher.go | 2 + core/capabilities/launcher_test.go | 2 +- .../remote/target/endtoend_test.go | 2 +- core/capabilities/remote/target/server.go | 44 ++++++++++++-- .../capabilities/remote/target/server_test.go | 47 +++++++++++++-- core/capabilities/remote/trigger_publisher.go | 8 ++- .../remote/trigger_publisher_test.go | 2 +- .../capabilities/remote/trigger_subscriber.go | 8 ++- .../remote/trigger_subscriber_test.go | 2 +- core/capabilities/streams/trigger_test.go | 2 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- ...deploy_initialize_capabilities_registry.go | 15 +++-- core/services/registrysyncer/syncer.go | 26 +++++--- core/services/registrysyncer/syncer_test.go | 3 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 26 files changed, 202 insertions(+), 82 deletions(-) create mode 100644 .changeset/polite-crabs-pretend.md diff --git a/.changeset/polite-crabs-pretend.md b/.changeset/polite-crabs-pretend.md new file mode 100644 index 0000000000..f8ea63b45c --- /dev/null +++ b/.changeset/polite-crabs-pretend.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal ensure remote target request hash is deterministic diff --git a/core/capabilities/integration_tests/keystone_contracts_setup.go b/core/capabilities/integration_tests/keystone_contracts_setup.go index 42269d1bd4..004a4c32a3 100644 --- a/core/capabilities/integration_tests/keystone_contracts_setup.go +++ b/core/capabilities/integration_tests/keystone_contracts_setup.go @@ -91,8 +91,8 @@ func peerToNode(nopID uint32, p peer) (kcr.CapabilitiesRegistryNodeParams, error }, nil } -func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workflowDonPeers []peer, triggerDonPeers []peer, - targetDonPeerIDs []peer, +func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workflowDon donInfo, triggerDon donInfo, + targetDon donInfo, transactOpts *bind.TransactOpts, backend *ethBackend) common.Address { addr, _, reg, err := kcr.DeployCapabilitiesRegistry(transactOpts, backend) require.NoError(t, err) @@ -157,7 +157,7 @@ func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workfl nopID := recLog.NodeOperatorId nodes := []kcr.CapabilitiesRegistryNodeParams{} - for _, wfPeer := range workflowDonPeers { + for _, wfPeer := range workflowDon.peerIDs { n, innerErr := peerToNode(nopID, wfPeer) require.NoError(t, innerErr) @@ -165,7 +165,7 @@ func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workfl nodes = append(nodes, n) } - for _, triggerPeer := range triggerDonPeers { + for _, triggerPeer := range triggerDon.peerIDs { n, innerErr := peerToNode(nopID, triggerPeer) require.NoError(t, innerErr) @@ -173,7 +173,7 @@ func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workfl nodes = append(nodes, n) } - for _, targetPeer := range targetDonPeerIDs { + for _, targetPeer := range targetDon.peerIDs { n, innerErr := peerToNode(nopID, targetPeer) require.NoError(t, innerErr) @@ -185,7 +185,7 @@ func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workfl require.NoError(t, err) // workflow DON - ps, err := peers(workflowDonPeers) + ps, err := peers(workflowDon.peerIDs) require.NoError(t, err) cc := newCapabilityConfig() @@ -199,22 +199,24 @@ func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workfl }, } - workflowDonF := uint8(2) - _, err = reg.AddDON(transactOpts, ps, cfgs, false, true, workflowDonF) + _, err = reg.AddDON(transactOpts, ps, cfgs, false, true, workflowDon.F) require.NoError(t, err) // trigger DON - ps, err = peers(triggerDonPeers) + ps, err = peers(triggerDon.peerIDs) require.NoError(t, err) - triggerDonF := 1 - config := &pb.RemoteTriggerConfig{ - RegistrationRefresh: durationpb.New(20000 * time.Millisecond), - RegistrationExpiry: durationpb.New(60000 * time.Millisecond), - // F + 1 - MinResponsesToAggregate: uint32(triggerDonF) + 1, + triggerCapabilityConfig := newCapabilityConfig() + triggerCapabilityConfig.RemoteConfig = &pb.CapabilityConfig_RemoteTriggerConfig{ + RemoteTriggerConfig: &pb.RemoteTriggerConfig{ + RegistrationRefresh: durationpb.New(60000 * time.Millisecond), + RegistrationExpiry: durationpb.New(60000 * time.Millisecond), + // F + 1 + MinResponsesToAggregate: uint32(triggerDon.F) + 1, + }, } - configb, err := proto.Marshal(config) + + configb, err := proto.Marshal(triggerCapabilityConfig) require.NoError(t, err) cfgs = []kcr.CapabilitiesRegistryCapabilityConfiguration{ @@ -224,22 +226,31 @@ func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workfl }, } - _, err = reg.AddDON(transactOpts, ps, cfgs, true, false, uint8(triggerDonF)) + _, err = reg.AddDON(transactOpts, ps, cfgs, true, false, triggerDon.F) require.NoError(t, err) // target DON - ps, err = peers(targetDonPeerIDs) + ps, err = peers(targetDon.peerIDs) + require.NoError(t, err) + + targetCapabilityConfig := newCapabilityConfig() + targetCapabilityConfig.RemoteConfig = &pb.CapabilityConfig_RemoteTargetConfig{ + RemoteTargetConfig: &pb.RemoteTargetConfig{ + RequestHashExcludedAttributes: []string{"signed_report.Signatures"}, + }, + } + + remoteTargetConfigBytes, err := proto.Marshal(targetCapabilityConfig) require.NoError(t, err) cfgs = []kcr.CapabilitiesRegistryCapabilityConfiguration{ { CapabilityId: wid, - Config: ccb, + Config: remoteTargetConfigBytes, }, } - targetDonF := uint8(1) - _, err = reg.AddDON(transactOpts, ps, cfgs, true, false, targetDonF) + _, err = reg.AddDON(transactOpts, ps, cfgs, true, false, targetDon.F) require.NoError(t, err) backend.Commit() @@ -253,19 +264,18 @@ func newCapabilityConfig() *pb.CapabilityConfig { } } -func setupForwarderContract(t *testing.T, workflowDonPeers []peer, workflowDonId uint32, - configVersion uint32, f uint8, +func setupForwarderContract(t *testing.T, workflowDon donInfo, transactOpts *bind.TransactOpts, backend *ethBackend) (common.Address, *forwarder.KeystoneForwarder) { addr, _, fwd, err := forwarder.DeployKeystoneForwarder(transactOpts, backend) require.NoError(t, err) backend.Commit() var signers []common.Address - for _, p := range workflowDonPeers { + for _, p := range workflowDon.peerIDs { signers = append(signers, common.HexToAddress(p.Signer)) } - _, err = fwd.SetConfig(transactOpts, workflowDonId, configVersion, f, signers) + _, err = fwd.SetConfig(transactOpts, workflowDon.ID, workflowDon.ConfigVersion, workflowDon.F, signers) require.NoError(t, err) backend.Commit() diff --git a/core/capabilities/integration_tests/mock_libocr.go b/core/capabilities/integration_tests/mock_libocr.go index 39c53d48af..14ccdce600 100644 --- a/core/capabilities/integration_tests/mock_libocr.go +++ b/core/capabilities/integration_tests/mock_libocr.go @@ -157,10 +157,6 @@ func (m *mockLibOCR) simulateProtocolRound(ctx context.Context) error { Signer: commontypes.OracleID(i), Signature: sig, }) - - if uint8(len(signatures)) == m.f+1 { - break - } } for _, node := range m.nodes { @@ -181,7 +177,16 @@ func (m *mockLibOCR) simulateProtocolRound(ctx context.Context) error { continue } - err = node.Transmit(ctx, types.ConfigDigest{}, 0, report, signatures) + // For each node select a random set of f+1 signatures to mimic libocr behaviour + s := rand.NewSource(time.Now().UnixNano()) + r := rand.New(s) + indices := r.Perm(len(signatures)) + selectedSignatures := make([]types.AttributedOnchainSignature, m.f+1) + for i := 0; i < int(m.f+1); i++ { + selectedSignatures[i] = signatures[indices[i]] + } + + err = node.Transmit(ctx, types.ConfigDigest{}, 0, report, selectedSignatures) if err != nil { return fmt.Errorf("failed to transmit report: %w", err) } diff --git a/core/capabilities/integration_tests/setup.go b/core/capabilities/integration_tests/setup.go index 0095d2fd9d..69b8c3eaa0 100644 --- a/core/capabilities/integration_tests/setup.go +++ b/core/capabilities/integration_tests/setup.go @@ -68,8 +68,8 @@ func setupStreamDonsWithTransmissionSchedule(ctx context.Context, t *testing.T, lggr.SetLogLevel(TestLogLevel) ethBlockchain, transactor := setupBlockchain(t, 1000, 1*time.Second) - capabilitiesRegistryAddr := setupCapabilitiesRegistryContract(ctx, t, workflowDonInfo.peerIDs, triggerDonInfo.peerIDs, targetDonInfo.peerIDs, transactor, ethBlockchain) - forwarderAddr, _ := setupForwarderContract(t, workflowDonInfo.peerIDs, workflowDonInfo.ID, 1, workflowDonInfo.F, transactor, ethBlockchain) + capabilitiesRegistryAddr := setupCapabilitiesRegistryContract(ctx, t, workflowDonInfo, triggerDonInfo, targetDonInfo, transactor, ethBlockchain) + forwarderAddr, _ := setupForwarderContract(t, workflowDonInfo, transactor, ethBlockchain) consumerAddr, consumer := setupConsumerContract(t, transactor, ethBlockchain, forwarderAddr, workflowOwnerID, workflowName) var feedIDs []string @@ -259,9 +259,10 @@ func createDonInfo(t *testing.T, don don) donInfo { triggerDonInfo := donInfo{ DON: commoncap.DON{ - ID: don.id, - Members: donPeers, - F: don.f, + ID: don.id, + Members: donPeers, + F: don.f, + ConfigVersion: 1, }, peerIDs: peerIDs, keys: donKeys, diff --git a/core/capabilities/integration_tests/streams_test.go b/core/capabilities/integration_tests/streams_test.go index 6216e36c85..7be392932f 100644 --- a/core/capabilities/integration_tests/streams_test.go +++ b/core/capabilities/integration_tests/streams_test.go @@ -22,9 +22,9 @@ func Test_AllAtOnceTransmissionSchedule(t *testing.T) { // The don IDs set in the below calls are inferred from the order in which the dons are added to the capabilities registry // in the setupCapabilitiesRegistryContract function, should this order change the don IDs will need updating. - workflowDonInfo := createDonInfo(t, don{id: 1, numNodes: 5, f: 1}) - triggerDonInfo := createDonInfo(t, don{id: 2, numNodes: 7, f: 1}) - targetDonInfo := createDonInfo(t, don{id: 3, numNodes: 4, f: 1}) + workflowDonInfo := createDonInfo(t, don{id: 1, numNodes: 7, f: 2}) + triggerDonInfo := createDonInfo(t, don{id: 2, numNodes: 7, f: 2}) + targetDonInfo := createDonInfo(t, don{id: 3, numNodes: 4, f: 2}) consumer, feedIDs, triggerSink := setupStreamDonsWithTransmissionSchedule(ctx, t, workflowDonInfo, triggerDonInfo, targetDonInfo, 3, "2s", "allAtOnce") diff --git a/core/capabilities/launcher.go b/core/capabilities/launcher.go index b4ade04127..b30477e4c8 100644 --- a/core/capabilities/launcher.go +++ b/core/capabilities/launcher.go @@ -216,6 +216,7 @@ func (w *launcher) addRemoteCapabilities(ctx context.Context, myDON registrysync int(remoteDON.F+1), w.lggr, ) + // TODO: We need to implement a custom, Mercury-specific // aggregator here, because there is no guarantee that // all trigger events in the workflow will have the same @@ -358,6 +359,7 @@ func (w *launcher) exposeCapabilities(ctx context.Context, myPeerID p2ptypes.Pee case capabilities.CapabilityTypeTarget: newTargetServer := func(capability capabilities.BaseCapability, info capabilities.CapabilityInfo) (receiverService, error) { return target.NewServer( + c.RemoteTargetConfig, myPeerID, capability.(capabilities.TargetCapability), info, diff --git a/core/capabilities/launcher_test.go b/core/capabilities/launcher_test.go index fb3e6837d0..82b03edcec 100644 --- a/core/capabilities/launcher_test.go +++ b/core/capabilities/launcher_test.go @@ -323,7 +323,7 @@ func TestLauncher_WiresUpClientsForPublicWorkflowDON(t *testing.T) { // The below state describes a Workflow DON (AcceptsWorkflows = true), // which exposes the streams-trigger and write_chain capabilities. // We expect receivers to be wired up and both capabilities to be added to the registry. - var rtc capabilities.RemoteTriggerConfig + rtc := &capabilities.RemoteTriggerConfig{} rtc.ApplyDefaults() state := ®istrysyncer.LocalRegistry{ diff --git a/core/capabilities/remote/target/endtoend_test.go b/core/capabilities/remote/target/endtoend_test.go index 9bbb53d4f6..cfab50f0fe 100644 --- a/core/capabilities/remote/target/endtoend_test.go +++ b/core/capabilities/remote/target/endtoend_test.go @@ -226,7 +226,7 @@ func testRemoteTarget(ctx context.Context, t *testing.T, underlying commoncap.Ta for i := 0; i < numCapabilityPeers; i++ { capabilityPeer := capabilityPeers[i] capabilityDispatcher := broker.NewDispatcherForNode(capabilityPeer) - capabilityNode := target.NewServer(capabilityPeer, underlying, capInfo, capDonInfo, workflowDONs, capabilityDispatcher, + capabilityNode := target.NewServer(&commoncap.RemoteTargetConfig{RequestHashExcludedAttributes: []string{}}, capabilityPeer, underlying, capInfo, capDonInfo, workflowDONs, capabilityDispatcher, capabilityNodeResponseTimeout, lggr) servicetest.Run(t, capabilityNode) broker.RegisterReceiverNode(capabilityPeer, capabilityNode) diff --git a/core/capabilities/remote/target/server.go b/core/capabilities/remote/target/server.go index ea9caf81ef..39023ffb3f 100644 --- a/core/capabilities/remote/target/server.go +++ b/core/capabilities/remote/target/server.go @@ -4,10 +4,12 @@ import ( "context" "crypto/sha256" "encoding/hex" + "fmt" "sync" "time" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/target/request" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" @@ -24,7 +26,9 @@ import ( // server communicates with corresponding client on remote nodes. type server struct { services.StateMachine - lggr logger.Logger + lggr logger.Logger + + config *commoncap.RemoteTargetConfig peerID p2ptypes.PeerID underlying commoncap.TargetCapability capInfo commoncap.CapabilityInfo @@ -51,9 +55,14 @@ type requestAndMsgID struct { messageID string } -func NewServer(peerID p2ptypes.PeerID, underlying commoncap.TargetCapability, capInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, +func NewServer(config *commoncap.RemoteTargetConfig, peerID p2ptypes.PeerID, underlying commoncap.TargetCapability, capInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, workflowDONs map[uint32]commoncap.DON, dispatcher types.Dispatcher, requestTimeout time.Duration, lggr logger.Logger) *server { + if config == nil { + lggr.Info("no config provided, using default values") + config = &commoncap.RemoteTargetConfig{} + } return &server{ + config: config, underlying: underlying, peerID: peerID, capInfo: capInfo, @@ -126,11 +135,16 @@ func (r *server) Receive(ctx context.Context, msg *types.MessageBody) { return } + msgHash, err := r.getMessageHash(msg) + if err != nil { + r.lggr.Errorw("failed to get message hash", "err", err) + return + } + // A request is uniquely identified by the message id and the hash of the payload to prevent a malicious // actor from sending a different payload with the same message id messageId := GetMessageID(msg) - hash := sha256.Sum256(msg.Payload) - requestID := messageId + hex.EncodeToString(hash[:]) + requestID := messageId + hex.EncodeToString(msgHash[:]) if requestIDs, ok := r.messageIDToRequestIDsCount[messageId]; ok { requestIDs[requestID] = requestIDs[requestID] + 1 @@ -161,12 +175,32 @@ func (r *server) Receive(ctx context.Context, msg *types.MessageBody) { reqAndMsgID := r.requestIDToRequest[requestID] - err := reqAndMsgID.request.OnMessage(ctx, msg) + err = reqAndMsgID.request.OnMessage(ctx, msg) if err != nil { r.lggr.Errorw("request failed to OnMessage new message", "request", reqAndMsgID, "err", err) } } +func (r *server) getMessageHash(msg *types.MessageBody) ([32]byte, error) { + req, err := pb.UnmarshalCapabilityRequest(msg.Payload) + if err != nil { + return [32]byte{}, fmt.Errorf("failed to unmarshal capability request: %w", err) + } + + for _, path := range r.config.RequestHashExcludedAttributes { + if !req.Inputs.DeleteAtPath(path) { + return [32]byte{}, fmt.Errorf("failed to delete attribute from map at path: %s", path) + } + } + + reqBytes, err := pb.MarshalCapabilityRequest(req) + if err != nil { + return [32]byte{}, fmt.Errorf("failed to marshal capability request: %w", err) + } + hash := sha256.Sum256(reqBytes) + return hash, nil +} + func GetMessageID(msg *types.MessageBody) string { return string(msg.MessageId) } diff --git a/core/capabilities/remote/target/server_test.go b/core/capabilities/remote/target/server_test.go index a5aa45efd0..2460a2dd0f 100644 --- a/core/capabilities/remote/target/server_test.go +++ b/core/capabilities/remote/target/server_test.go @@ -2,6 +2,7 @@ package target_test import ( "context" + "strconv" "testing" "time" @@ -11,6 +12,7 @@ import ( commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/values" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/target" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" @@ -18,12 +20,48 @@ import ( p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) +func Test_Server_ExcludesNonDeterministicInputAttributes(t *testing.T) { + ctx := testutils.Context(t) + + numCapabilityPeers := 4 + + callers, srvcs := testRemoteTargetServer(ctx, t, &commoncap.RemoteTargetConfig{RequestHashExcludedAttributes: []string{"signed_report.Signatures"}}, + &TestCapability{}, 10, 9, numCapabilityPeers, 3, 10*time.Minute) + + for idx, caller := range callers { + rawInputs := map[string]any{ + "signed_report": map[string]any{"Signatures": "sig" + strconv.Itoa(idx), "Price": 20}, + } + + inputs, err := values.NewMap(rawInputs) + require.NoError(t, err) + + _, err = caller.Execute(context.Background(), + commoncap.CapabilityRequest{ + Metadata: commoncap.RequestMetadata{ + WorkflowID: "workflowID", + WorkflowExecutionID: "workflowExecutionID", + }, + Inputs: inputs, + }) + require.NoError(t, err) + } + + for _, caller := range callers { + for i := 0; i < numCapabilityPeers; i++ { + msg := <-caller.receivedMessages + assert.Equal(t, remotetypes.Error_OK, msg.Error) + } + } + closeServices(t, srvcs) +} + func Test_Server_RespondsAfterSufficientRequests(t *testing.T) { ctx := testutils.Context(t) numCapabilityPeers := 4 - callers, srvcs := testRemoteTargetServer(ctx, t, &TestCapability{}, 10, 9, numCapabilityPeers, 3, 10*time.Minute) + callers, srvcs := testRemoteTargetServer(ctx, t, &commoncap.RemoteTargetConfig{}, &TestCapability{}, 10, 9, numCapabilityPeers, 3, 10*time.Minute) for _, caller := range callers { _, err := caller.Execute(context.Background(), @@ -50,7 +88,7 @@ func Test_Server_InsufficientCallers(t *testing.T) { numCapabilityPeers := 4 - callers, srvcs := testRemoteTargetServer(ctx, t, &TestCapability{}, 10, 10, numCapabilityPeers, 3, 100*time.Millisecond) + callers, srvcs := testRemoteTargetServer(ctx, t, &commoncap.RemoteTargetConfig{}, &TestCapability{}, 10, 10, numCapabilityPeers, 3, 100*time.Millisecond) for _, caller := range callers { _, err := caller.Execute(context.Background(), @@ -77,7 +115,7 @@ func Test_Server_CapabilityError(t *testing.T) { numCapabilityPeers := 4 - callers, srvcs := testRemoteTargetServer(ctx, t, &TestErrorCapability{}, 10, 9, numCapabilityPeers, 3, 100*time.Millisecond) + callers, srvcs := testRemoteTargetServer(ctx, t, &commoncap.RemoteTargetConfig{}, &TestErrorCapability{}, 10, 9, numCapabilityPeers, 3, 100*time.Millisecond) for _, caller := range callers { _, err := caller.Execute(context.Background(), @@ -100,6 +138,7 @@ func Test_Server_CapabilityError(t *testing.T) { } func testRemoteTargetServer(ctx context.Context, t *testing.T, + config *commoncap.RemoteTargetConfig, underlying commoncap.TargetCapability, numWorkflowPeers int, workflowDonF uint8, numCapabilityPeers int, capabilityDonF uint8, capabilityNodeResponseTimeout time.Duration) ([]*serverTestClient, []services.Service) { @@ -150,7 +189,7 @@ func testRemoteTargetServer(ctx context.Context, t *testing.T, for i := 0; i < numCapabilityPeers; i++ { capabilityPeer := capabilityPeers[i] capabilityDispatcher := broker.NewDispatcherForNode(capabilityPeer) - capabilityNode := target.NewServer(capabilityPeer, underlying, capInfo, capDonInfo, workflowDONs, capabilityDispatcher, + capabilityNode := target.NewServer(config, capabilityPeer, underlying, capInfo, capDonInfo, workflowDONs, capabilityDispatcher, capabilityNodeResponseTimeout, lggr) require.NoError(t, capabilityNode.Start(ctx)) broker.RegisterReceiverNode(capabilityPeer, capabilityNode) diff --git a/core/capabilities/remote/trigger_publisher.go b/core/capabilities/remote/trigger_publisher.go index 35ce41118f..c1f2fb32c5 100644 --- a/core/capabilities/remote/trigger_publisher.go +++ b/core/capabilities/remote/trigger_publisher.go @@ -21,7 +21,7 @@ import ( // // TriggerPublisher communicates with corresponding TriggerSubscribers on remote nodes. type triggerPublisher struct { - config capabilities.RemoteTriggerConfig + config *capabilities.RemoteTriggerConfig underlying commoncap.TriggerCapability capInfo commoncap.CapabilityInfo capDonInfo commoncap.DON @@ -48,7 +48,11 @@ type pubRegState struct { var _ types.Receiver = &triggerPublisher{} var _ services.Service = &triggerPublisher{} -func NewTriggerPublisher(config capabilities.RemoteTriggerConfig, underlying commoncap.TriggerCapability, capInfo commoncap.CapabilityInfo, capDonInfo commoncap.DON, workflowDONs map[uint32]commoncap.DON, dispatcher types.Dispatcher, lggr logger.Logger) *triggerPublisher { +func NewTriggerPublisher(config *capabilities.RemoteTriggerConfig, underlying commoncap.TriggerCapability, capInfo commoncap.CapabilityInfo, capDonInfo commoncap.DON, workflowDONs map[uint32]commoncap.DON, dispatcher types.Dispatcher, lggr logger.Logger) *triggerPublisher { + if config == nil { + lggr.Info("no config provided, using default values") + config = &capabilities.RemoteTriggerConfig{} + } config.ApplyDefaults() return &triggerPublisher{ config: config, diff --git a/core/capabilities/remote/trigger_publisher_test.go b/core/capabilities/remote/trigger_publisher_test.go index 1e3000d20c..2c4a851896 100644 --- a/core/capabilities/remote/trigger_publisher_test.go +++ b/core/capabilities/remote/trigger_publisher_test.go @@ -42,7 +42,7 @@ func TestTriggerPublisher_Register(t *testing.T) { } dispatcher := remoteMocks.NewDispatcher(t) - config := capabilities.RemoteTriggerConfig{ + config := &capabilities.RemoteTriggerConfig{ RegistrationRefresh: 100 * time.Millisecond, RegistrationExpiry: 100 * time.Second, MinResponsesToAggregate: 1, diff --git a/core/capabilities/remote/trigger_subscriber.go b/core/capabilities/remote/trigger_subscriber.go index 0ccbf37c61..2d038e45c0 100644 --- a/core/capabilities/remote/trigger_subscriber.go +++ b/core/capabilities/remote/trigger_subscriber.go @@ -23,7 +23,7 @@ import ( // // TriggerSubscriber communicates with corresponding TriggerReceivers on remote nodes. type triggerSubscriber struct { - config capabilities.RemoteTriggerConfig + config *capabilities.RemoteTriggerConfig capInfo commoncap.CapabilityInfo capDonInfo capabilities.DON capDonMembers map[p2ptypes.PeerID]struct{} @@ -55,11 +55,15 @@ var _ services.Service = &triggerSubscriber{} // TODO makes this configurable with a default const defaultSendChannelBufferSize = 1000 -func NewTriggerSubscriber(config capabilities.RemoteTriggerConfig, capInfo commoncap.CapabilityInfo, capDonInfo capabilities.DON, localDonInfo capabilities.DON, dispatcher types.Dispatcher, aggregator types.Aggregator, lggr logger.Logger) *triggerSubscriber { +func NewTriggerSubscriber(config *capabilities.RemoteTriggerConfig, capInfo commoncap.CapabilityInfo, capDonInfo capabilities.DON, localDonInfo capabilities.DON, dispatcher types.Dispatcher, aggregator types.Aggregator, lggr logger.Logger) *triggerSubscriber { if aggregator == nil { lggr.Warnw("no aggregator provided, using default MODE aggregator", "capabilityId", capInfo.ID) aggregator = NewDefaultModeAggregator(uint32(capDonInfo.F + 1)) } + if config == nil { + lggr.Info("no config provided, using default values") + config = &capabilities.RemoteTriggerConfig{} + } config.ApplyDefaults() capDonMembers := make(map[p2ptypes.PeerID]struct{}) for _, member := range capDonInfo.Members { diff --git a/core/capabilities/remote/trigger_subscriber_test.go b/core/capabilities/remote/trigger_subscriber_test.go index 93e962215a..2e34b03ec5 100644 --- a/core/capabilities/remote/trigger_subscriber_test.go +++ b/core/capabilities/remote/trigger_subscriber_test.go @@ -63,7 +63,7 @@ func TestTriggerSubscriber_RegisterAndReceive(t *testing.T) { }) // register trigger - config := capabilities.RemoteTriggerConfig{ + config := &capabilities.RemoteTriggerConfig{ RegistrationRefresh: 100 * time.Millisecond, RegistrationExpiry: 100 * time.Second, MinResponsesToAggregate: 1, diff --git a/core/capabilities/streams/trigger_test.go b/core/capabilities/streams/trigger_test.go index cb4cfaa36b..853f07f2aa 100644 --- a/core/capabilities/streams/trigger_test.go +++ b/core/capabilities/streams/trigger_test.go @@ -87,7 +87,7 @@ func TestStreamsTrigger(t *testing.T) { Members: capMembers, F: uint8(F), } - config := capabilities.RemoteTriggerConfig{ + config := &capabilities.RemoteTriggerConfig{ MinResponsesToAggregate: uint32(F + 1), } subscriber := remote.NewTriggerSubscriber(config, capInfo, capDonInfo, capabilities.DON{}, nil, agg, lggr) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 4ee443d46f..4e25003871 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 3ae26beb63..4c8eee4a1d 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1184,8 +1184,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc h1:nNZqLasN8y5huDKX76JUZtni7WkUI36J61//czbJpDM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 h1:rwo/bzqzbhSPBn1CHFfHiQPcMlpBV/hau4TrpJngTJc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go b/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go index 8762241543..3352267d14 100644 --- a/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go +++ b/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go @@ -11,10 +11,11 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - ragetypes "github.com/smartcontractkit/libocr/ragep2p/types" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/durationpb" + ragetypes "github.com/smartcontractkit/libocr/ragep2p/types" + capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/values" @@ -373,8 +374,14 @@ func (c *deployAndInitializeCapabilitiesRegistryCommand) Run(args []string) { panic(err) } - cc = newCapabilityConfig() - ccb, err = proto.Marshal(cc) + targetCapabilityConfig := newCapabilityConfig() + targetCapabilityConfig.RemoteConfig = &capabilitiespb.CapabilityConfig_RemoteTargetConfig{ + RemoteTargetConfig: &capabilitiespb.RemoteTargetConfig{ + RequestHashExcludedAttributes: []string{"signed_report.Signatures"}, + }, + } + + remoteTargetConfigBytes, err := proto.Marshal(targetCapabilityConfig) if err != nil { panic(err) } @@ -382,7 +389,7 @@ func (c *deployAndInitializeCapabilitiesRegistryCommand) Run(args []string) { cfgs = []kcr.CapabilitiesRegistryCapabilityConfiguration{ { CapabilityId: wid, - Config: ccb, + Config: remoteTargetConfigBytes, }, } _, err = reg.AddDON(env.Owner, ps, cfgs, true, false, 1) diff --git a/core/services/registrysyncer/syncer.go b/core/services/registrysyncer/syncer.go index 4bbfaef504..9675d86dc8 100644 --- a/core/services/registrysyncer/syncer.go +++ b/core/services/registrysyncer/syncer.go @@ -165,12 +165,21 @@ func unmarshalCapabilityConfig(data []byte) (capabilities.CapabilityConfiguratio return capabilities.CapabilityConfiguration{}, err } - var rtc capabilities.RemoteTriggerConfig - if prtc := cconf.GetRemoteTriggerConfig(); prtc != nil { - rtc.RegistrationRefresh = prtc.RegistrationRefresh.AsDuration() - rtc.RegistrationExpiry = prtc.RegistrationExpiry.AsDuration() - rtc.MinResponsesToAggregate = prtc.MinResponsesToAggregate - rtc.MessageExpiry = prtc.MessageExpiry.AsDuration() + var remoteTriggerConfig *capabilities.RemoteTriggerConfig + var remoteTargetConfig *capabilities.RemoteTargetConfig + + switch cconf.GetRemoteConfig().(type) { + case *capabilitiespb.CapabilityConfig_RemoteTriggerConfig: + prtc := cconf.GetRemoteTriggerConfig() + remoteTriggerConfig = &capabilities.RemoteTriggerConfig{} + remoteTriggerConfig.RegistrationRefresh = prtc.RegistrationRefresh.AsDuration() + remoteTriggerConfig.RegistrationExpiry = prtc.RegistrationExpiry.AsDuration() + remoteTriggerConfig.MinResponsesToAggregate = prtc.MinResponsesToAggregate + remoteTriggerConfig.MessageExpiry = prtc.MessageExpiry.AsDuration() + case *capabilitiespb.CapabilityConfig_RemoteTargetConfig: + prtc := cconf.GetRemoteTargetConfig() + remoteTargetConfig = &capabilities.RemoteTargetConfig{} + remoteTargetConfig.RequestHashExcludedAttributes = prtc.RequestHashExcludedAttributes } dc, err := values.FromMapValueProto(cconf.DefaultConfig) @@ -180,7 +189,8 @@ func unmarshalCapabilityConfig(data []byte) (capabilities.CapabilityConfiguratio return capabilities.CapabilityConfiguration{ DefaultConfig: dc, - RemoteTriggerConfig: rtc, + RemoteTriggerConfig: remoteTriggerConfig, + RemoteTargetConfig: remoteTargetConfig, }, nil } @@ -223,8 +233,6 @@ func (s *registrySyncer) localRegistry(ctx context.Context) (*LocalRegistry, err return nil, innerErr } - cconf.RemoteTriggerConfig.ApplyDefaults() - cc[cid] = cconf } diff --git a/core/services/registrysyncer/syncer_test.go b/core/services/registrysyncer/syncer_test.go index b926183394..c13cc90490 100644 --- a/core/services/registrysyncer/syncer_test.go +++ b/core/services/registrysyncer/syncer_test.go @@ -210,6 +210,7 @@ func TestReader_Integration(t *testing.T) { RegistrationExpiry: durationpb.New(60 * time.Second), // F + 1 MinResponsesToAggregate: uint32(1) + 1, + MessageExpiry: durationpb.New(120 * time.Second), }, }, } @@ -256,7 +257,7 @@ func TestReader_Integration(t *testing.T) { }, gotCap) assert.Len(t, s.IDsToDONs, 1) - rtc := capabilities.RemoteTriggerConfig{ + rtc := &capabilities.RemoteTriggerConfig{ RegistrationRefresh: 20 * time.Second, MinResponsesToAggregate: 2, RegistrationExpiry: 60 * time.Second, diff --git a/go.mod b/go.mod index 8e2103eb24..3aa878d1ab 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index 73d6d5b227..0264dcc01c 100644 --- a/go.sum +++ b/go.sum @@ -1136,8 +1136,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc h1:nNZqLasN8y5huDKX76JUZtni7WkUI36J61//czbJpDM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 h1:rwo/bzqzbhSPBn1CHFfHiQPcMlpBV/hau4TrpJngTJc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index ed693f4fcc..d7c1918c92 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -28,7 +28,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 github.com/smartcontractkit/chainlink-testing-framework v1.33.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index ca3ce8d903..2854b2d599 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1486,8 +1486,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc h1:nNZqLasN8y5huDKX76JUZtni7WkUI36J61//czbJpDM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 h1:rwo/bzqzbhSPBn1CHFfHiQPcMlpBV/hau4TrpJngTJc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 3d1ae6c7a9..f0485082ec 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.31.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 github.com/smartcontractkit/chainlink-testing-framework v1.33.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 2a54ec9254..647a02b9b0 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1468,8 +1468,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc h1:nNZqLasN8y5huDKX76JUZtni7WkUI36J61//czbJpDM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240731184516-249ef7ad0cdc/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 h1:rwo/bzqzbhSPBn1CHFfHiQPcMlpBV/hau4TrpJngTJc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= From d90bb66934a46bb1c6d376b000d860e1588d91c7 Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Mon, 5 Aug 2024 17:46:31 +0100 Subject: [PATCH 034/432] common version update to head of develop (#14030) --- .changeset/ninety-cougars-tease.md | 5 +++++ core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 9 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 .changeset/ninety-cougars-tease.md diff --git a/.changeset/ninety-cougars-tease.md b/.changeset/ninety-cougars-tease.md new file mode 100644 index 0000000000..ab12a57191 --- /dev/null +++ b/.changeset/ninety-cougars-tease.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal restore common version to head of develop diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 4e25003871..fe4ee2c974 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 4c8eee4a1d..76eaf61527 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1184,8 +1184,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 h1:rwo/bzqzbhSPBn1CHFfHiQPcMlpBV/hau4TrpJngTJc= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c h1:3apUsez/6Pkp1ckXzSwIhzPRuWjDGjzMjKapEKi0Fcw= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/go.mod b/go.mod index 3aa878d1ab..45e0b62d52 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index 0264dcc01c..4a6b294c12 100644 --- a/go.sum +++ b/go.sum @@ -1136,8 +1136,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 h1:rwo/bzqzbhSPBn1CHFfHiQPcMlpBV/hau4TrpJngTJc= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c h1:3apUsez/6Pkp1ckXzSwIhzPRuWjDGjzMjKapEKi0Fcw= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index d7c1918c92..8f9652099b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -28,7 +28,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c github.com/smartcontractkit/chainlink-testing-framework v1.33.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 2854b2d599..bca92f4a97 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1486,8 +1486,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 h1:rwo/bzqzbhSPBn1CHFfHiQPcMlpBV/hau4TrpJngTJc= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c h1:3apUsez/6Pkp1ckXzSwIhzPRuWjDGjzMjKapEKi0Fcw= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index f0485082ec..f0554f2c72 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.31.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c github.com/smartcontractkit/chainlink-testing-framework v1.33.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 647a02b9b0..f31a11d389 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1468,8 +1468,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409 h1:rwo/bzqzbhSPBn1CHFfHiQPcMlpBV/hau4TrpJngTJc= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240801092904-114abb088409/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c h1:3apUsez/6Pkp1ckXzSwIhzPRuWjDGjzMjKapEKi0Fcw= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= From 8b9f2b6b9098e8ec2368773368239106d066e4e3 Mon Sep 17 00:00:00 2001 From: ilija42 <57732589+ilija42@users.noreply.github.com> Date: Tue, 6 Aug 2024 12:52:10 +0200 Subject: [PATCH 035/432] [BCF - 3339] - Codec and CR hashed topics support (#14016) * Add better handling for CR EVM filtering by hashed indexed topics * Add comments for CR event codec usage * Improve err handling in CR init * Add a TODO for CR QueryKey primitive remapping handling * Update codec test to match most recent changes * Add changeset and run solidity prettier * Add contracts changeset for ChainReaderTester contract changes * simplify getNativeAndCheckedTypesForArg FixedBytesTy case --- .changeset/thin-rings-count.md | 5 + contracts/.changeset/itchy-turtles-agree.md | 5 + .../shared/test/helpers/ChainReaderTester.sol | 8 + .../chain_reader_tester.go | 175 +++++++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- core/services/relay/evm/chain_reader.go | 10 +- core/services/relay/evm/event_binding.go | 67 ++++--- .../chain_reader_interface_tester.go | 16 +- .../relay/evm/evmtesting/run_tests.go | 37 +++- core/services/relay/evm/types/codec_entry.go | 2 +- .../relay/evm/types/codec_entry_test.go | 28 ++- 11 files changed, 314 insertions(+), 41 deletions(-) create mode 100644 .changeset/thin-rings-count.md create mode 100644 contracts/.changeset/itchy-turtles-agree.md diff --git a/.changeset/thin-rings-count.md b/.changeset/thin-rings-count.md new file mode 100644 index 0000000000..20f4b54311 --- /dev/null +++ b/.changeset/thin-rings-count.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#internal Add evm Chain Reader GetLatestValue support for filtering on indexed topic types that get hashed. diff --git a/contracts/.changeset/itchy-turtles-agree.md b/contracts/.changeset/itchy-turtles-agree.md new file mode 100644 index 0000000000..930ab850d9 --- /dev/null +++ b/contracts/.changeset/itchy-turtles-agree.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': minor +--- + +#internal Add an event with indexed topics that get hashed to Chain Reader Tester contract. diff --git a/contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol b/contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol index 58a4b9a25c..709d00cc38 100644 --- a/contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol +++ b/contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol @@ -40,6 +40,9 @@ contract ChainReaderTester { // First topic is event hash event TriggeredWithFourTopics(int32 indexed field1, int32 indexed field2, int32 indexed field3); + // first topic is event hash, second and third topics get hashed before getting stored + event TriggeredWithFourTopicsWithHashed(string indexed field1, uint8[32] indexed field2, bytes32 indexed field3); + TestStruct[] private s_seen; uint64[] private s_arr; uint64 private s_value; @@ -125,4 +128,9 @@ contract ChainReaderTester { function triggerWithFourTopics(int32 field1, int32 field2, int32 field3) public { emit TriggeredWithFourTopics(field1, field2, field3); } + + // first topic is event hash, second and third topics get hashed before getting stored + function triggerWithFourTopicsWithHashed(string memory field1, uint8[32] memory field2, bytes32 field3) public { + emit TriggeredWithFourTopicsWithHashed(field1, field2, field3); + } } diff --git a/core/gethwrappers/generated/chain_reader_tester/chain_reader_tester.go b/core/gethwrappers/generated/chain_reader_tester/chain_reader_tester.go index 751df82269..c59a6f0f0d 100644 --- a/core/gethwrappers/generated/chain_reader_tester/chain_reader_tester.go +++ b/core/gethwrappers/generated/chain_reader_tester/chain_reader_tester.go @@ -52,8 +52,8 @@ type TestStruct struct { } var ChainReaderTesterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"Triggered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"fieldHash\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"TriggeredEventWithDynamicTopic\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field1\",\"type\":\"int32\"},{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field2\",\"type\":\"int32\"},{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field3\",\"type\":\"int32\"}],\"name\":\"TriggeredWithFourTopics\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"addTestStruct\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAlterablePrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDifferentPrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"getElementAtIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"int32\",\"name\":\"Field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"DifferentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"OracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"OracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"BigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"NestedStruct\",\"type\":\"tuple\"}],\"internalType\":\"structTestStruct\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSliceValue\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"returnSeen\",\"outputs\":[{\"components\":[{\"internalType\":\"int32\",\"name\":\"Field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"DifferentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"OracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"OracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"BigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"NestedStruct\",\"type\":\"tuple\"}],\"internalType\":\"structTestStruct\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"value\",\"type\":\"uint64\"}],\"name\":\"setAlterablePrimitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"triggerEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"triggerEventWithDynamicTopic\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field1\",\"type\":\"int32\"},{\"internalType\":\"int32\",\"name\":\"field2\",\"type\":\"int32\"},{\"internalType\":\"int32\",\"name\":\"field3\",\"type\":\"int32\"}],\"name\":\"triggerWithFourTopics\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50600180548082018255600082905260048082047fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6908101805460086003958616810261010090810a8088026001600160401b0391820219909416939093179093558654808801909755848704909301805496909516909202900a91820291021990921691909117905561181e806100a96000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80637f002d6711610081578063ef4e1ced1161005b578063ef4e1ced146101c0578063f6f871c8146101c7578063fbe9fbf6146101da57600080fd5b80637f002d671461017d578063ab5e0b3814610190578063dbfd7332146101ad57600080fd5b806349eac2ac116100b257806349eac2ac1461010c578063679004a41461011f5780636c9a43b61461013457600080fd5b80632c45576f146100ce5780633272b66c146100f7575b600080fd5b6100e16100dc366004610c2b565b6101ec565b6040516100ee9190610d8a565b60405180910390f35b61010a610105366004610ec9565b6104c7565b005b61010a61011a366004610fde565b61051c565b61012761081f565b6040516100ee91906110d0565b61010a61014236600461111e565b600280547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b61010a61018b366004610fde565b6108ab565b6107c65b60405167ffffffffffffffff90911681526020016100ee565b61010a6101bb36600461114f565b610902565b6003610194565b6100e16101d5366004610fde565b61093f565b60025467ffffffffffffffff16610194565b6101f4610a48565b6000610201600184611192565b81548110610211576102116111cc565b6000918252602091829020604080516101008101909152600a90920201805460030b8252600181018054929391929184019161024c906111fb565b80601f0160208091040260200160405190810160405280929190818152602001828054610278906111fb565b80156102c55780601f1061029a576101008083540402835291602001916102c5565b820191906000526020600020905b8154815290600101906020018083116102a857829003601f168201915b5050509183525050600282015460ff166020808301919091526040805161040081018083529190930192916003850191826000855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116102fa57505050928452505050600482015473ffffffffffffffffffffffffffffffffffffffff1660208083019190915260058301805460408051828502810185018252828152940193928301828280156103b357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610388575b5050509183525050600682015460170b6020808301919091526040805180820182526007808601805460f01b7fffff0000000000000000000000000000000000000000000000000000000000001683528351808501855260088801805490930b81526009880180549590970196939591948683019491939284019190610438906111fb565b80601f0160208091040260200160405190810160405280929190818152602001828054610464906111fb565b80156104b15780601f10610486576101008083540402835291602001916104b1565b820191906000526020600020905b81548152906001019060200180831161049457829003601f168201915b5050509190925250505090525090525092915050565b81816040516104d7929190611248565b60405180910390207f3d969732b1bbbb9f1d7eb9f3f14e4cb50a74d950b3ef916a397b85dfbab93c6783836040516105109291906112a1565b60405180910390a25050565b60006040518061010001604052808c60030b81526020018b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060ff8a166020808301919091526040805161040081810183529190930192918b9183908390808284376000920191909152505050815273ffffffffffffffffffffffffffffffffffffffff8816602080830191909152604080518883028181018401835289825291909301929189918991829190850190849080828437600092019190915250505090825250601785900b602082015260400161060e8461139e565b905281546001808201845560009384526020938490208351600a9093020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90931692909217825592820151919290919082019061067490826114f8565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560608201516106c29060038301906020610a97565b5060808201516004820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117905560a08201518051610729916005840191602090910190610b2a565b5060c08201516006820180547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff90921691909117905560e082015180516007830180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660f09290921c91909117815560208083015180516008860180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff90921691909117815591810151909190600986019061080c90826114f8565b5050505050505050505050505050505050565b606060018054806020026020016040519081016040528092919081815260200182805480156108a157602002820191906000526020600020906000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff168152602001906008019060208260070104928301926001038202915080841161085c5790505b5050505050905090565b8960030b7f7188419dcd8b51877b71766f075f3626586c0ff190e7d056aa65ce9acb649a3d8a8a8a8a8a8a8a8a8a6040516108ee99989796959493929190611757565b60405180910390a250505050505050505050565b8060030b8260030b8460030b7f91c80dc390f3d041b3a04b0099b19634499541ea26972250986ee4b24a12fac560405160405180910390a4505050565b610947610a48565b6040518061010001604052808c60030b81526020018b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060ff8a166020808301919091526040805161040081810183529190930192918b9183908390808284376000920191909152505050815273ffffffffffffffffffffffffffffffffffffffff8816602080830191909152604080518883028181018401835289825291909301929189918991829190850190849080828437600092019190915250505090825250601785900b6020820152604001610a378461139e565b90529b9a5050505050505050505050565b6040805161010081018252600080825260606020830181905292820152908101610a70610ba4565b8152600060208201819052606060408301819052820152608001610a92610bc3565b905290565b600183019183908215610b1a5791602002820160005b83821115610aeb57835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302610aad565b8015610b185782816101000a81549060ff0219169055600101602081600001049283019260010302610aeb565b505b50610b26929150610c16565b5090565b828054828255906000526020600020908101928215610b1a579160200282015b82811115610b1a57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610b4a565b6040518061040001604052806020906020820280368337509192915050565b604051806040016040528060007dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001610a926040518060400160405280600060070b8152602001606081525090565b5b80821115610b265760008155600101610c17565b600060208284031215610c3d57600080fd5b5035919050565b6000815180845260005b81811015610c6a57602081850181015186830182015201610c4e565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b8060005b6020808210610cbb5750610cd2565b825160ff1685529384019390910190600101610cac565b50505050565b600081518084526020808501945080840160005b83811015610d1e57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101610cec565b509495945050505050565b7fffff00000000000000000000000000000000000000000000000000000000000081511682526000602082015160406020850152805160070b60408501526020810151905060406060850152610d826080850182610c44565b949350505050565b60208152610d9e60208201835160030b9052565b600060208301516104e0806040850152610dbc610500850183610c44565b91506040850151610dd2606086018260ff169052565b506060850151610de56080860182610ca8565b50608085015173ffffffffffffffffffffffffffffffffffffffff1661048085015260a08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085840381016104a0870152610e428483610cd8565b935060c08701519150610e5b6104c087018360170b9052565b60e0870151915080868503018387015250610e768382610d29565b9695505050505050565b60008083601f840112610e9257600080fd5b50813567ffffffffffffffff811115610eaa57600080fd5b602083019150836020828501011115610ec257600080fd5b9250929050565b60008060208385031215610edc57600080fd5b823567ffffffffffffffff811115610ef357600080fd5b610eff85828601610e80565b90969095509350505050565b8035600381900b8114610f1d57600080fd5b919050565b803560ff81168114610f1d57600080fd5b806104008101831015610f4557600080fd5b92915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610f1d57600080fd5b60008083601f840112610f8157600080fd5b50813567ffffffffffffffff811115610f9957600080fd5b6020830191508360208260051b8501011115610ec257600080fd5b8035601781900b8114610f1d57600080fd5b600060408284031215610fd857600080fd5b50919050565b6000806000806000806000806000806104e08b8d031215610ffe57600080fd5b6110078b610f0b565b995060208b013567ffffffffffffffff8082111561102457600080fd5b6110308e838f01610e80565b909b50995089915061104460408e01610f22565b98506110538e60608f01610f33565b97506110626104608e01610f4b565b96506104808d013591508082111561107957600080fd5b6110858e838f01610f6f565b909650945084915061109a6104a08e01610fb4565b93506104c08d01359150808211156110b157600080fd5b506110be8d828e01610fc6565b9150509295989b9194979a5092959850565b6020808252825182820181905260009190848201906040850190845b8181101561111257835167ffffffffffffffff16835292840192918401916001016110ec565b50909695505050505050565b60006020828403121561113057600080fd5b813567ffffffffffffffff8116811461114857600080fd5b9392505050565b60008060006060848603121561116457600080fd5b61116d84610f0b565b925061117b60208501610f0b565b915061118960408501610f0b565b90509250925092565b81810381811115610f45577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061120f57607f821691505b602082108103610fd8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000610d82602083018486611258565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611307576113076112b5565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611354576113546112b5565b604052919050565b80357fffff00000000000000000000000000000000000000000000000000000000000081168114610f1d57600080fd5b8035600781900b8114610f1d57600080fd5b6000604082360312156113b057600080fd5b6113b86112e4565b6113c18361135c565b815260208084013567ffffffffffffffff808211156113df57600080fd5b8186019150604082360312156113f457600080fd5b6113fc6112e4565b6114058361138c565b8152838301358281111561141857600080fd5b929092019136601f84011261142c57600080fd5b82358281111561143e5761143e6112b5565b61146e857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161130d565b9250808352368582860101111561148457600080fd5b8085850186850137600090830185015280840191909152918301919091525092915050565b601f8211156114f357600081815260208120601f850160051c810160208610156114d05750805b601f850160051c820191505b818110156114ef578281556001016114dc565b5050505b505050565b815167ffffffffffffffff811115611512576115126112b5565b6115268161152084546111fb565b846114a9565b602080601f83116001811461157957600084156115435750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556114ef565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156115c6578886015182559484019460019091019084016115a7565b508582101561160257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8183526000602080850194508260005b85811015610d1e5773ffffffffffffffffffffffffffffffffffffffff61164883610f4b565b1687529582019590820190600101611622565b7fffff0000000000000000000000000000000000000000000000000000000000006116858261135c565b168252600060208201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126116bf57600080fd5b6040602085015282016116d18161138c565b60070b604085015260208101357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe182360301811261170e57600080fd5b0160208101903567ffffffffffffffff81111561172a57600080fd5b80360382131561173957600080fd5b6040606086015261174e608086018284611258565b95945050505050565b60006104c080835261176c8184018c8e611258565b9050602060ff808c1682860152604085018b60005b848110156117a6578361179383610f22565b1683529184019190840190600101611781565b505050505073ffffffffffffffffffffffffffffffffffffffff88166104408401528281036104608401526117dc818789611612565b90506117ee61048084018660170b9052565b8281036104a0840152611801818561165b565b9c9b50505050505050505050505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"Triggered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"fieldHash\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"TriggeredEventWithDynamicTopic\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field1\",\"type\":\"int32\"},{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field2\",\"type\":\"int32\"},{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field3\",\"type\":\"int32\"}],\"name\":\"TriggeredWithFourTopics\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"field1\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint8[32]\",\"name\":\"field2\",\"type\":\"uint8[32]\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"field3\",\"type\":\"bytes32\"}],\"name\":\"TriggeredWithFourTopicsWithHashed\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"addTestStruct\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAlterablePrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDifferentPrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"getElementAtIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"int32\",\"name\":\"Field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"DifferentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"OracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"OracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"BigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"NestedStruct\",\"type\":\"tuple\"}],\"internalType\":\"structTestStruct\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSliceValue\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"returnSeen\",\"outputs\":[{\"components\":[{\"internalType\":\"int32\",\"name\":\"Field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"DifferentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"OracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"OracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"BigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"NestedStruct\",\"type\":\"tuple\"}],\"internalType\":\"structTestStruct\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"value\",\"type\":\"uint64\"}],\"name\":\"setAlterablePrimitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"triggerEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"triggerEventWithDynamicTopic\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field1\",\"type\":\"int32\"},{\"internalType\":\"int32\",\"name\":\"field2\",\"type\":\"int32\"},{\"internalType\":\"int32\",\"name\":\"field3\",\"type\":\"int32\"}],\"name\":\"triggerWithFourTopics\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"field1\",\"type\":\"string\"},{\"internalType\":\"uint8[32]\",\"name\":\"field2\",\"type\":\"uint8[32]\"},{\"internalType\":\"bytes32\",\"name\":\"field3\",\"type\":\"bytes32\"}],\"name\":\"triggerWithFourTopicsWithHashed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50600180548082018255600082905260048082047fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6908101805460086003958616810261010090810a8088026001600160401b0391820219909416939093179093558654808801909755848704909301805496909516909202900a91820291021990921691909117905561199c806100a96000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063a90e199811610081578063ef4e1ced1161005b578063ef4e1ced146101de578063f6f871c8146101e5578063fbe9fbf6146101f857600080fd5b8063a90e19981461019b578063ab5e0b38146101ae578063dbfd7332146101cb57600080fd5b8063679004a4116100b2578063679004a41461012a5780636c9a43b61461013f5780637f002d671461018857600080fd5b80632c45576f146100d95780633272b66c1461010257806349eac2ac14610117575b600080fd5b6100ec6100e7366004610ca3565b61020a565b6040516100f99190610e0c565b60405180910390f35b610115610110366004610f4b565b6104e5565b005b610115610125366004611060565b61053a565b61013261083d565b6040516100f99190611152565b61011561014d3660046111a0565b600280547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b610115610196366004611060565b6108c9565b6101156101a93660046112d4565b610920565b6107c65b60405167ffffffffffffffff90911681526020016100f9565b6101156101d9366004611389565b61097a565b60036101b2565b6100ec6101f3366004611060565b6109b7565b60025467ffffffffffffffff166101b2565b610212610ac0565b600061021f6001846113cc565b8154811061022f5761022f611406565b6000918252602091829020604080516101008101909152600a90920201805460030b8252600181018054929391929184019161026a90611435565b80601f016020809104026020016040519081016040528092919081815260200182805461029690611435565b80156102e35780601f106102b8576101008083540402835291602001916102e3565b820191906000526020600020905b8154815290600101906020018083116102c657829003601f168201915b5050509183525050600282015460ff166020808301919091526040805161040081018083529190930192916003850191826000855b825461010083900a900460ff1681526020600192830181810494850194909303909202910180841161031857505050928452505050600482015473ffffffffffffffffffffffffffffffffffffffff1660208083019190915260058301805460408051828502810185018252828152940193928301828280156103d157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116103a6575b5050509183525050600682015460170b6020808301919091526040805180820182526007808601805460f01b7fffff0000000000000000000000000000000000000000000000000000000000001683528351808501855260088801805490930b8152600988018054959097019693959194868301949193928401919061045690611435565b80601f016020809104026020016040519081016040528092919081815260200182805461048290611435565b80156104cf5780601f106104a4576101008083540402835291602001916104cf565b820191906000526020600020905b8154815290600101906020018083116104b257829003601f168201915b5050509190925250505090525090525092915050565b81816040516104f5929190611482565b60405180910390207f3d969732b1bbbb9f1d7eb9f3f14e4cb50a74d950b3ef916a397b85dfbab93c67838360405161052e9291906114db565b60405180910390a25050565b60006040518061010001604052808c60030b81526020018b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060ff8a166020808301919091526040805161040081810183529190930192918b9183908390808284376000920191909152505050815273ffffffffffffffffffffffffffffffffffffffff8816602080830191909152604080518883028181018401835289825291909301929189918991829190850190849080828437600092019190915250505090825250601785900b602082015260400161062c84611531565b905281546001808201845560009384526020938490208351600a9093020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909316929092178255928201519192909190820190610692908261161e565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560608201516106e09060038301906020610b0f565b5060808201516004820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117905560a08201518051610747916005840191602090910190610ba2565b5060c08201516006820180547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff90921691909117905560e082015180516007830180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660f09290921c91909117815560208083015180516008860180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff90921691909117815591810151909190600986019061082a908261161e565b5050505050505050505050505050505050565b606060018054806020026020016040519081016040528092919081815260200182805480156108bf57602002820191906000526020600020906000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff168152602001906008019060208260070104928301926001038202915080841161087a5790505b5050505050905090565b8960030b7f7188419dcd8b51877b71766f075f3626586c0ff190e7d056aa65ce9acb649a3d8a8a8a8a8a8a8a8a8a60405161090c9998979695949392919061187d565b60405180910390a250505050505050505050565b808260405161092f9190611937565b6040518091039020846040516109459190611973565b604051908190038120907f7220e4dbe4e9d0ed5f71acd022bc89c26748ac6784f2c548bc17bb8e52af34b090600090a4505050565b8060030b8260030b8460030b7f91c80dc390f3d041b3a04b0099b19634499541ea26972250986ee4b24a12fac560405160405180910390a4505050565b6109bf610ac0565b6040518061010001604052808c60030b81526020018b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060ff8a166020808301919091526040805161040081810183529190930192918b9183908390808284376000920191909152505050815273ffffffffffffffffffffffffffffffffffffffff8816602080830191909152604080518883028181018401835289825291909301929189918991829190850190849080828437600092019190915250505090825250601785900b6020820152604001610aaf84611531565b90529b9a5050505050505050505050565b6040805161010081018252600080825260606020830181905292820152908101610ae8610c1c565b8152600060208201819052606060408301819052820152608001610b0a610c3b565b905290565b600183019183908215610b925791602002820160005b83821115610b6357835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302610b25565b8015610b905782816101000a81549060ff0219169055600101602081600001049283019260010302610b63565b505b50610b9e929150610c8e565b5090565b828054828255906000526020600020908101928215610b92579160200282015b82811115610b9257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610bc2565b6040518061040001604052806020906020820280368337509192915050565b604051806040016040528060007dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001610b0a6040518060400160405280600060070b8152602001606081525090565b5b80821115610b9e5760008155600101610c8f565b600060208284031215610cb557600080fd5b5035919050565b60005b83811015610cd7578181015183820152602001610cbf565b50506000910152565b60008151808452610cf8816020860160208601610cbc565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b8060005b6020808210610d3d5750610d54565b825160ff1685529384019390910190600101610d2e565b50505050565b600081518084526020808501945080840160005b83811015610da057815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101610d6e565b509495945050505050565b7fffff00000000000000000000000000000000000000000000000000000000000081511682526000602082015160406020850152805160070b60408501526020810151905060406060850152610e046080850182610ce0565b949350505050565b60208152610e2060208201835160030b9052565b600060208301516104e0806040850152610e3e610500850183610ce0565b91506040850151610e54606086018260ff169052565b506060850151610e676080860182610d2a565b50608085015173ffffffffffffffffffffffffffffffffffffffff1661048085015260a08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085840381016104a0870152610ec48483610d5a565b935060c08701519150610edd6104c087018360170b9052565b60e0870151915080868503018387015250610ef88382610dab565b9695505050505050565b60008083601f840112610f1457600080fd5b50813567ffffffffffffffff811115610f2c57600080fd5b602083019150836020828501011115610f4457600080fd5b9250929050565b60008060208385031215610f5e57600080fd5b823567ffffffffffffffff811115610f7557600080fd5b610f8185828601610f02565b90969095509350505050565b8035600381900b8114610f9f57600080fd5b919050565b803560ff81168114610f9f57600080fd5b806104008101831015610fc757600080fd5b92915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610f9f57600080fd5b60008083601f84011261100357600080fd5b50813567ffffffffffffffff81111561101b57600080fd5b6020830191508360208260051b8501011115610f4457600080fd5b8035601781900b8114610f9f57600080fd5b60006040828403121561105a57600080fd5b50919050565b6000806000806000806000806000806104e08b8d03121561108057600080fd5b6110898b610f8d565b995060208b013567ffffffffffffffff808211156110a657600080fd5b6110b28e838f01610f02565b909b5099508991506110c660408e01610fa4565b98506110d58e60608f01610fb5565b97506110e46104608e01610fcd565b96506104808d01359150808211156110fb57600080fd5b6111078e838f01610ff1565b909650945084915061111c6104a08e01611036565b93506104c08d013591508082111561113357600080fd5b506111408d828e01611048565b9150509295989b9194979a5092959850565b6020808252825182820181905260009190848201906040850190845b8181101561119457835167ffffffffffffffff168352928401929184019160010161116e565b50909695505050505050565b6000602082840312156111b257600080fd5b813567ffffffffffffffff811681146111ca57600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611223576112236111d1565b60405290565b600082601f83011261123a57600080fd5b813567ffffffffffffffff80821115611255576112556111d1565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561129b5761129b6111d1565b816040528381528660208588010111156112b457600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600061044084860312156112ea57600080fd5b833567ffffffffffffffff8082111561130257600080fd5b61130e87838801611229565b94506020915086603f87011261132357600080fd5b6040516104008101818110838211171561133f5761133f6111d1565b60405290508061042087018881111561135757600080fd5b8388015b818110156113795761136c81610fa4565b845292840192840161135b565b5095989097509435955050505050565b60008060006060848603121561139e57600080fd5b6113a784610f8d565b92506113b560208501610f8d565b91506113c360408501610f8d565b90509250925092565b81810381811115610fc7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061144957607f821691505b60208210810361105a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000610e04602083018486611492565b80357fffff00000000000000000000000000000000000000000000000000000000000081168114610f9f57600080fd5b8035600781900b8114610f9f57600080fd5b60006040823603121561154357600080fd5b61154b611200565b611554836114ef565b8152602083013567ffffffffffffffff8082111561157157600080fd5b81850191506040823603121561158657600080fd5b61158e611200565b6115978361151f565b81526020830135828111156115ab57600080fd5b6115b736828601611229565b60208301525080602085015250505080915050919050565b601f82111561161957600081815260208120601f850160051c810160208610156115f65750805b601f850160051c820191505b8181101561161557828155600101611602565b5050505b505050565b815167ffffffffffffffff811115611638576116386111d1565b61164c816116468454611435565b846115cf565b602080601f83116001811461169f57600084156116695750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611615565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156116ec578886015182559484019460019091019084016116cd565b508582101561172857878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8183526000602080850194508260005b85811015610da05773ffffffffffffffffffffffffffffffffffffffff61176e83610fcd565b1687529582019590820190600101611748565b7fffff0000000000000000000000000000000000000000000000000000000000006117ab826114ef565b168252600060208201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126117e557600080fd5b6040602085015282016117f78161151f565b60070b604085015260208101357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe182360301811261183457600080fd5b0160208101903567ffffffffffffffff81111561185057600080fd5b80360382131561185f57600080fd5b60406060860152611874608086018284611492565b95945050505050565b60006104c08083526118928184018c8e611492565b9050602060ff808c1682860152604085018b60005b848110156118cc57836118b983610fa4565b16835291840191908401906001016118a7565b505050505073ffffffffffffffffffffffffffffffffffffffff8816610440840152828103610460840152611902818789611738565b905061191461048084018660170b9052565b8281036104a08401526119278185611781565b9c9b505050505050505050505050565b60008183825b602080821061194c5750611963565b825160ff168452928301929091019060010161193d565b5050506104008201905092915050565b60008251611985818460208701610cbc565b919091019291505056fea164736f6c6343000813000a", } var ChainReaderTesterABI = ChainReaderTesterMetaData.ABI @@ -384,6 +384,18 @@ func (_ChainReaderTester *ChainReaderTesterTransactorSession) TriggerWithFourTop return _ChainReaderTester.Contract.TriggerWithFourTopics(&_ChainReaderTester.TransactOpts, field1, field2, field3) } +func (_ChainReaderTester *ChainReaderTesterTransactor) TriggerWithFourTopicsWithHashed(opts *bind.TransactOpts, field1 string, field2 [32]uint8, field3 [32]byte) (*types.Transaction, error) { + return _ChainReaderTester.contract.Transact(opts, "triggerWithFourTopicsWithHashed", field1, field2, field3) +} + +func (_ChainReaderTester *ChainReaderTesterSession) TriggerWithFourTopicsWithHashed(field1 string, field2 [32]uint8, field3 [32]byte) (*types.Transaction, error) { + return _ChainReaderTester.Contract.TriggerWithFourTopicsWithHashed(&_ChainReaderTester.TransactOpts, field1, field2, field3) +} + +func (_ChainReaderTester *ChainReaderTesterTransactorSession) TriggerWithFourTopicsWithHashed(field1 string, field2 [32]uint8, field3 [32]byte) (*types.Transaction, error) { + return _ChainReaderTester.Contract.TriggerWithFourTopicsWithHashed(&_ChainReaderTester.TransactOpts, field1, field2, field3) +} + type ChainReaderTesterTriggeredIterator struct { Event *ChainReaderTesterTriggered @@ -791,6 +803,151 @@ func (_ChainReaderTester *ChainReaderTesterFilterer) ParseTriggeredWithFourTopic return event, nil } +type ChainReaderTesterTriggeredWithFourTopicsWithHashedIterator struct { + Event *ChainReaderTesterTriggeredWithFourTopicsWithHashed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ChainReaderTesterTriggeredWithFourTopicsWithHashedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChainReaderTesterTriggeredWithFourTopicsWithHashed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ChainReaderTesterTriggeredWithFourTopicsWithHashed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ChainReaderTesterTriggeredWithFourTopicsWithHashedIterator) Error() error { + return it.fail +} + +func (it *ChainReaderTesterTriggeredWithFourTopicsWithHashedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ChainReaderTesterTriggeredWithFourTopicsWithHashed struct { + Field1 common.Hash + Field2 [32]uint8 + Field3 [32]byte + Raw types.Log +} + +func (_ChainReaderTester *ChainReaderTesterFilterer) FilterTriggeredWithFourTopicsWithHashed(opts *bind.FilterOpts, field1 []string, field2 [][32]uint8, field3 [][32]byte) (*ChainReaderTesterTriggeredWithFourTopicsWithHashedIterator, error) { + + var field1Rule []interface{} + for _, field1Item := range field1 { + field1Rule = append(field1Rule, field1Item) + } + var field2Rule []interface{} + for _, field2Item := range field2 { + field2Rule = append(field2Rule, field2Item) + } + var field3Rule []interface{} + for _, field3Item := range field3 { + field3Rule = append(field3Rule, field3Item) + } + + logs, sub, err := _ChainReaderTester.contract.FilterLogs(opts, "TriggeredWithFourTopicsWithHashed", field1Rule, field2Rule, field3Rule) + if err != nil { + return nil, err + } + return &ChainReaderTesterTriggeredWithFourTopicsWithHashedIterator{contract: _ChainReaderTester.contract, event: "TriggeredWithFourTopicsWithHashed", logs: logs, sub: sub}, nil +} + +func (_ChainReaderTester *ChainReaderTesterFilterer) WatchTriggeredWithFourTopicsWithHashed(opts *bind.WatchOpts, sink chan<- *ChainReaderTesterTriggeredWithFourTopicsWithHashed, field1 []string, field2 [][32]uint8, field3 [][32]byte) (event.Subscription, error) { + + var field1Rule []interface{} + for _, field1Item := range field1 { + field1Rule = append(field1Rule, field1Item) + } + var field2Rule []interface{} + for _, field2Item := range field2 { + field2Rule = append(field2Rule, field2Item) + } + var field3Rule []interface{} + for _, field3Item := range field3 { + field3Rule = append(field3Rule, field3Item) + } + + logs, sub, err := _ChainReaderTester.contract.WatchLogs(opts, "TriggeredWithFourTopicsWithHashed", field1Rule, field2Rule, field3Rule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ChainReaderTesterTriggeredWithFourTopicsWithHashed) + if err := _ChainReaderTester.contract.UnpackLog(event, "TriggeredWithFourTopicsWithHashed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ChainReaderTester *ChainReaderTesterFilterer) ParseTriggeredWithFourTopicsWithHashed(log types.Log) (*ChainReaderTesterTriggeredWithFourTopicsWithHashed, error) { + event := new(ChainReaderTesterTriggeredWithFourTopicsWithHashed) + if err := _ChainReaderTester.contract.UnpackLog(event, "TriggeredWithFourTopicsWithHashed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + func (_ChainReaderTester *ChainReaderTester) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { case _ChainReaderTester.abi.Events["Triggered"].ID: @@ -799,6 +956,8 @@ func (_ChainReaderTester *ChainReaderTester) ParseLog(log types.Log) (generated. return _ChainReaderTester.ParseTriggeredEventWithDynamicTopic(log) case _ChainReaderTester.abi.Events["TriggeredWithFourTopics"].ID: return _ChainReaderTester.ParseTriggeredWithFourTopics(log) + case _ChainReaderTester.abi.Events["TriggeredWithFourTopicsWithHashed"].ID: + return _ChainReaderTester.ParseTriggeredWithFourTopicsWithHashed(log) default: return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) @@ -817,6 +976,10 @@ func (ChainReaderTesterTriggeredWithFourTopics) Topic() common.Hash { return common.HexToHash("0x91c80dc390f3d041b3a04b0099b19634499541ea26972250986ee4b24a12fac5") } +func (ChainReaderTesterTriggeredWithFourTopicsWithHashed) Topic() common.Hash { + return common.HexToHash("0x7220e4dbe4e9d0ed5f71acd022bc89c26748ac6784f2c548bc17bb8e52af34b0") +} + func (_ChainReaderTester *ChainReaderTester) Address() common.Address { return _ChainReaderTester.address } @@ -844,6 +1007,8 @@ type ChainReaderTesterInterface interface { TriggerWithFourTopics(opts *bind.TransactOpts, field1 int32, field2 int32, field3 int32) (*types.Transaction, error) + TriggerWithFourTopicsWithHashed(opts *bind.TransactOpts, field1 string, field2 [32]uint8, field3 [32]byte) (*types.Transaction, error) + FilterTriggered(opts *bind.FilterOpts, field []int32) (*ChainReaderTesterTriggeredIterator, error) WatchTriggered(opts *bind.WatchOpts, sink chan<- *ChainReaderTesterTriggered, field []int32) (event.Subscription, error) @@ -862,6 +1027,12 @@ type ChainReaderTesterInterface interface { ParseTriggeredWithFourTopics(log types.Log) (*ChainReaderTesterTriggeredWithFourTopics, error) + FilterTriggeredWithFourTopicsWithHashed(opts *bind.FilterOpts, field1 []string, field2 [][32]uint8, field3 [][32]byte) (*ChainReaderTesterTriggeredWithFourTopicsWithHashedIterator, error) + + WatchTriggeredWithFourTopicsWithHashed(opts *bind.WatchOpts, sink chan<- *ChainReaderTesterTriggeredWithFourTopicsWithHashed, field1 []string, field2 [][32]uint8, field3 [][32]byte) (event.Subscription, error) + + ParseTriggeredWithFourTopicsWithHashed(log types.Log) (*ChainReaderTesterTriggeredWithFourTopicsWithHashed, error) + ParseLog(log types.Log) (generated.AbigenLog, error) Address() common.Address diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 41c270d61c..3299989c58 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -24,7 +24,7 @@ batch_vrf_coordinator_v2: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/Batc batch_vrf_coordinator_v2plus: ../../contracts/solc/v0.8.19/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.19/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.bin f13715b38b5b9084b08bffa571fb1c8ef686001535902e1255052f074b31ad4e blockhash_store: ../../contracts/solc/v0.8.19/BlockhashStore/BlockhashStore.abi ../../contracts/solc/v0.8.19/BlockhashStore/BlockhashStore.bin 31b118f9577240c8834c35f8b5a1440e82a6ca8aea702970de2601824b6ab0e1 chain_module_base: ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.abi ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.bin 39dfce79330e921e5c169051b11c6e5ea15cd4db5a7b09c06aabbe9658148915 -chain_reader_tester: ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.abi ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.bin b3718dad488f54de97d124221d96b867c81e11210084a1fad379cb8385d37ffe +chain_reader_tester: ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.abi ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.bin b207f9e6bf71e445a2664a602677011b87b80bf95c6352fd7869f1a9ddb08a5b chain_specific_util_helper: ../../contracts/solc/v0.8.6/ChainSpecificUtilHelper/ChainSpecificUtilHelper.abi ../../contracts/solc/v0.8.6/ChainSpecificUtilHelper/ChainSpecificUtilHelper.bin 66eb30b0717fefe05672df5ec863c0b9a5a654623c4757307a2726d8f31e26b1 counter: ../../contracts/solc/v0.8.6/Counter/Counter.abi ../../contracts/solc/v0.8.6/Counter/Counter.bin 6ca06e000e8423573ffa0bdfda749d88236ab3da2a4cbb4a868c706da90488c9 cron_upkeep_factory_wrapper: ../../contracts/solc/v0.8.6/CronUpkeepFactory/CronUpkeepFactory.abi - dacb0f8cdf54ae9d2781c5e720fc314b32ed5e58eddccff512c75d6067292cd7 diff --git a/core/services/relay/evm/chain_reader.go b/core/services/relay/evm/chain_reader.go index d84c2f00a9..205fcbbcf0 100644 --- a/core/services/relay/evm/chain_reader.go +++ b/core/services/relay/evm/chain_reader.go @@ -128,6 +128,10 @@ func (cr *chainReader) init(chainContractReaders map[string]types.ChainContractR return err } } + + if cr.bindings.contractBindings[contractName] == nil { + return fmt.Errorf("%w: no read bindings added for contract: %s", commontypes.ErrInvalidConfig, contractName) + } cr.bindings.contractBindings[contractName].pollingFilter = chainContractReader.PollingFilter.ToLPFilter(eventSigsForContractFilter) } return nil @@ -259,7 +263,7 @@ func (cr *chainReader) addEvent(contractName, eventName string, a abi.ABI, chain return err } - // Encoder def's codec won't be used to encode, only for its type as input for GetLatestValue + // Encoder defs codec won't be used for encoding, but for storing caller filtering params which won't be hashed. if err := cr.addEncoderDef(contractName, eventName, filterArgs, nil, chainReaderDefinition.InputModifications); err != nil { return err } @@ -327,9 +331,11 @@ func (cr *chainReader) addQueryingReadBindings(contractName string, genericTopic } } +// getEventInput returns codec entry for expected incoming event params and the modifier to be applied to the params. func (cr *chainReader) getEventInput(def types.ChainReaderDefinition, contractName, eventName string) ( types.CodecEntry, codec.Modifier, error) { inputInfo := cr.parsed.EncoderDefs[WrapItemType(contractName, eventName, true)] + // TODO can this be simplified? Isn't this same as inputInfo.Modifier()? BCI-3909 inMod, err := def.InputModifications.ToModifier(DecoderHooks...) if err != nil { return nil, nil, err @@ -378,6 +384,8 @@ func (cr *chainReader) addDecoderDef(contractName, itemType string, outputs abi. return output.Init() } +// setupEventInput returns abi args where indexed flag is set to false because we expect caller to filter with params that aren't hashed. +// codecEntry has expected onchain types set, for e.g. indexed topics of type string or uint8[32] array are expected as common.Hash onchain. func setupEventInput(event abi.Event, inputFields []string) ([]abi.Argument, types.CodecEntry, map[string]bool) { topicFieldDefs := map[string]bool{} for _, value := range inputFields { diff --git a/core/services/relay/evm/event_binding.go b/core/services/relay/evm/event_binding.go index acfb1aa630..97ddc99a10 100644 --- a/core/services/relay/evm/event_binding.go +++ b/core/services/relay/evm/event_binding.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/google/uuid" "github.com/smartcontractkit/chainlink-common/pkg/codec" @@ -209,11 +210,13 @@ func (e *eventBinding) getLatestValueWithFilters( return err } + // convert caller chain agnostic params types to types representing onchain abi types, for e.g. bytes32. checkedParams, err := e.inputModifier.TransformToOnChain(offChain, "" /* unused */) if err != nil { return err } + // convert onchain params to native types similarly to generated abi wrappers, for e.g. fixed bytes32 abi type to [32]uint8. nativeParams, err := e.inputInfo.ToNative(reflect.ValueOf(checkedParams)) if err != nil { return err @@ -252,6 +255,8 @@ func (e *eventBinding) getLatestValueWithFilters( return e.decodeLog(ctx, logToUse, into) } +// convertToOffChainType creates a struct based on contract abi with applied codec modifiers. +// Created type shouldn't have hashed types for indexed topics since incoming params wouldn't be hashed. func (e *eventBinding) convertToOffChainType(params any) (any, error) { offChain, err := e.codec.CreateType(WrapItemType(e.contractName, e.eventName, true), true) if err != nil { @@ -287,43 +292,35 @@ func matchesRemainingFilters(log *logpoller.Log, filters []common.Hash) bool { return true } -func (e *eventBinding) encodeParams(item reflect.Value) ([]common.Hash, error) { - for item.Kind() == reflect.Pointer { - item = reflect.Indirect(item) +// encodeParams accepts nativeParams and encodes them to match onchain topics. +func (e *eventBinding) encodeParams(nativeParams reflect.Value) ([]common.Hash, error) { + for nativeParams.Kind() == reflect.Pointer { + nativeParams = reflect.Indirect(nativeParams) } - var topics []any - switch item.Kind() { + var params []any + switch nativeParams.Kind() { case reflect.Array, reflect.Slice: - native, err := representArray(item, e.inputInfo) + native, err := representArray(nativeParams, e.inputInfo) if err != nil { return nil, err } - topics = []any{native} + params = []any{native} case reflect.Struct, reflect.Map: var err error - if topics, err = unrollItem(item, e.inputInfo); err != nil { + if params, err = unrollItem(nativeParams, e.inputInfo); err != nil { return nil, err } default: - return nil, fmt.Errorf("%w: cannot encode kind %v", commontypes.ErrInvalidType, item.Kind()) + return nil, fmt.Errorf("%w: cannot encode kind %v", commontypes.ErrInvalidType, nativeParams.Kind()) } - // abi params allow you to Pack a pointers, but MakeTopics doesn't work with pointers. - if err := e.derefTopics(topics); err != nil { + // abi params allow you to Pack a pointers, but makeTopics doesn't work with pointers. + if err := e.derefTopics(params); err != nil { return nil, err } - hashes, err := abi.MakeTopics(topics) - if err != nil { - return nil, wrapInternalErr(err) - } - - if len(hashes) != 1 { - return nil, fmt.Errorf("%w: expected 1 filter set, got %d", commontypes.ErrInternal, len(hashes)) - } - - return hashes[0], nil + return e.makeTopics(params) } func (e *eventBinding) derefTopics(topics []any) error { @@ -340,11 +337,38 @@ func (e *eventBinding) derefTopics(topics []any) error { return nil } +// makeTopics encodes and hashes params filtering values to match onchain indexed topics. +func (e *eventBinding) makeTopics(params []any) ([]common.Hash, error) { + // make topic value for non-fixed bytes array manually because geth MakeTopics doesn't support it + for i, topic := range params { + if abiArg := e.inputInfo.Args()[i]; abiArg.Type.T == abi.ArrayTy && (abiArg.Type.Elem != nil && abiArg.Type.Elem.T == abi.UintTy) { + packed, err := abi.Arguments{abiArg}.Pack(topic) + if err != nil { + return nil, err + } + params[i] = crypto.Keccak256Hash(packed) + } + } + + hashes, err := abi.MakeTopics(params) + if err != nil { + return nil, wrapInternalErr(err) + } + + if len(hashes) != 1 { + return nil, fmt.Errorf("%w: expected 1 filter set, got %d", commontypes.ErrInternal, len(hashes)) + } + + return hashes[0], nil +} + func (e *eventBinding) decodeLog(ctx context.Context, log *logpoller.Log, into any) error { + // decode non indexed topics and apply output modifiers if err := e.codec.Decode(ctx, log.Data, into, WrapItemType(e.contractName, e.eventName, false)); err != nil { return err } + // decode indexed topics which is rarely useful since most indexed topic types get Keccak256 hashed and should be just used for log filtering. topics := make([]common.Hash, len(e.codecTopicInfo.Args())) if len(log.Topics) < len(topics)+1 { return fmt.Errorf("%w: not enough topics to decode", commontypes.ErrInvalidType) @@ -436,6 +460,7 @@ func (e *eventBinding) remapExpression(key string, expression query.Expression) // remap chain agnostic primitives to chain specific func (e *eventBinding) remapPrimitive(key string, expression query.Expression) (query.Expression, error) { switch primitive := expression.Primitive.(type) { + // TODO comparator primitive should undergo codec transformations and do hashed types handling similarly to how GetLatestValue handles it BCI-3910 case *primitives.Comparator: if val, ok := e.eventDataWords[primitive.Name]; ok { return logpoller.NewEventByWordFilter(e.hash, val, primitive.ValueComparators), nil diff --git a/core/services/relay/evm/evmtesting/chain_reader_interface_tester.go b/core/services/relay/evm/evmtesting/chain_reader_interface_tester.go index 4474f054db..7812ab202b 100644 --- a/core/services/relay/evm/evmtesting/chain_reader_interface_tester.go +++ b/core/services/relay/evm/evmtesting/chain_reader_interface_tester.go @@ -32,9 +32,10 @@ import ( ) const ( - triggerWithDynamicTopic = "TriggeredEventWithDynamicTopic" - triggerWithAllTopics = "TriggeredWithFourTopics" - finalityDepth = 4 + triggerWithDynamicTopic = "TriggeredEventWithDynamicTopic" + triggerWithAllTopics = "TriggeredWithFourTopics" + triggerWithAllTopicsWithHashed = "TriggeredWithFourTopicsWithHashed" + finalityDepth = 4 ) type EVMChainReaderInterfaceTesterHelper[T TestingT[T]] interface { @@ -96,7 +97,7 @@ func (it *EVMChainReaderInterfaceTester[T]) Setup(t T) { AnyContractName: { ContractABI: chain_reader_tester.ChainReaderTesterMetaData.ABI, ContractPollingFilter: types.ContractPollingFilter{ - GenericEventNames: []string{EventName, EventWithFilterName}, + GenericEventNames: []string{EventName, EventWithFilterName, triggerWithAllTopicsWithHashed}, }, Configs: map[string]*types.ChainReaderDefinition{ MethodTakingLatestParamsReturningTestStruct: &methodTakingLatestParamsReturningTestStructConfig, @@ -145,6 +146,13 @@ func (it *EVMChainReaderInterfaceTester[T]) Setup(t T) { // These float values can map to different finality concepts across chains. ConfidenceConfirmations: map[string]int{"0.0": int(evmtypes.Unconfirmed), "1.0": int(evmtypes.Finalized)}, }, + triggerWithAllTopicsWithHashed: { + ChainSpecificName: triggerWithAllTopicsWithHashed, + ReadType: types.Event, + EventDefinitions: &types.EventDefinitions{ + InputFields: []string{"Field1", "Field2", "Field3"}, + }, + }, MethodReturningSeenStruct: { ChainSpecificName: "returnSeen", InputModifications: codec.ModifiersConfig{ diff --git a/core/services/relay/evm/evmtesting/run_tests.go b/core/services/relay/evm/evmtesting/run_tests.go index f958c055ca..caa24e8ae2 100644 --- a/core/services/relay/evm/evmtesting/run_tests.go +++ b/core/services/relay/evm/evmtesting/run_tests.go @@ -12,10 +12,9 @@ import ( clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" . "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint common practice to import test mods with . - - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) func RunChainReaderEvmTests[T TestingT[T]](t T, it *EVMChainReaderInterfaceTester[T]) { @@ -74,6 +73,31 @@ func RunChainReaderEvmTests[T TestingT[T]](t T, it *EVMChainReaderInterfaceTeste assert.Equal(t, int32(3), latest.Field3) }) + t.Run("Filtering can be done on indexed topics that get hashed", func(t T) { + it.Setup(t) + it.dirtyContracts = true + triggerFourTopicsWithHashed(t, it, "1", [32]uint8{2}, [32]byte{5}) + triggerFourTopicsWithHashed(t, it, "2", [32]uint8{2}, [32]byte{3}) + triggerFourTopicsWithHashed(t, it, "1", [32]uint8{3}, [32]byte{3}) + + ctx := it.Helper.Context(t) + cr := it.GetChainReader(t) + require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) + var latest struct { + Field3 [32]byte + } + params := struct { + Field1 string + Field2 [32]uint8 + Field3 [32]byte + }{Field1: "1", Field2: [32]uint8{2}, Field3: [32]byte{5}} + + time.Sleep(it.MaxWaitTimeForEvents()) + require.NoError(t, cr.GetLatestValue(ctx, AnyContractName, triggerWithAllTopicsWithHashed, primitives.Unconfirmed, params, &latest)) + // only checking Field3 topic makes sense since it isn't hashed, to check other fields we'd have to replicate solidity encoding and hashing + assert.Equal(t, [32]uint8{5}, latest.Field3) + }) + t.Run("Bind returns error on missing contract at address", func(t T) { it.Setup(t) @@ -95,3 +119,12 @@ func triggerFourTopics[T TestingT[T]](t T, it *EVMChainReaderInterfaceTester[T], it.IncNonce() it.AwaitTx(t, tx) } + +func triggerFourTopicsWithHashed[T TestingT[T]](t T, it *EVMChainReaderInterfaceTester[T], i1 string, i2 [32]uint8, i3 [32]byte) { + tx, err := it.contractTesters[it.address].ChainReaderTesterTransactor.TriggerWithFourTopicsWithHashed(it.GetAuthWithGasSet(t), i1, i2, i3) + require.NoError(t, err) + require.NoError(t, err) + it.Helper.Commit() + it.IncNonce() + it.AwaitTx(t, tx) +} diff --git a/core/services/relay/evm/types/codec_entry.go b/core/services/relay/evm/types/codec_entry.go index 38242c43a2..9a8103cf7f 100644 --- a/core/services/relay/evm/types/codec_entry.go +++ b/core/services/relay/evm/types/codec_entry.go @@ -200,7 +200,7 @@ func getNativeAndCheckedTypesForArg(arg *abi.Argument) (reflect.Type, reflect.Ty return reflect.TypeOf(common.Hash{}), reflect.TypeOf(common.Hash{}), nil } fallthrough - case abi.SliceTy, abi.TupleTy, abi.FixedBytesTy, abi.FixedPointTy, abi.FunctionTy: + case abi.SliceTy, abi.TupleTy, abi.FixedPointTy, abi.FunctionTy: // https://github.com/ethereum/go-ethereum/blob/release/1.12/accounts/abi/topics.go#L78 return nil, nil, fmt.Errorf("%w: unsupported indexed type: %v", commontypes.ErrInvalidConfig, arg.Type) default: diff --git a/core/services/relay/evm/types/codec_entry_test.go b/core/services/relay/evm/types/codec_entry_test.go index 06b08fcecf..64e0998716 100644 --- a/core/services/relay/evm/types/codec_entry_test.go +++ b/core/services/relay/evm/types/codec_entry_test.go @@ -273,17 +273,27 @@ func TestCodecEntry(t *testing.T) { assertHaveSameStructureAndNames(t, iNative.Type(), entry.CheckedType()) }) - t.Run("Indexed non basic types change to hash", func(t *testing.T) { - anyType, err := abi.NewType("string", "", []abi.ArgumentMarshaling{}) + t.Run("Indexed string and bytes array change to hash", func(t *testing.T) { + stringType, err := abi.NewType("string", "", []abi.ArgumentMarshaling{}) require.NoError(t, err) - entry := NewCodecEntry(abi.Arguments{{Name: "Name", Type: anyType, Indexed: true}}, nil, nil) - require.NoError(t, entry.Init()) - nativeField, ok := entry.CheckedType().FieldByName("Name") - require.True(t, ok) - assert.Equal(t, reflect.TypeOf(&common.Hash{}), nativeField.Type) - native, err := entry.ToNative(reflect.New(entry.CheckedType())) + arrayType, err := abi.NewType("uint8[32]", "", []abi.ArgumentMarshaling{}) require.NoError(t, err) - assertHaveSameStructureAndNames(t, native.Type().Elem(), entry.CheckedType()) + + abiArgs := abi.Arguments{ + {Name: "String", Type: stringType, Indexed: true}, + {Name: "Array", Type: arrayType, Indexed: true}, + } + + for i := 0; i < len(abiArgs); i++ { + entry := NewCodecEntry(abi.Arguments{abiArgs[i]}, nil, nil) + require.NoError(t, entry.Init()) + nativeField, ok := entry.CheckedType().FieldByName(abiArgs[i].Name) + require.True(t, ok) + assert.Equal(t, reflect.TypeOf(&common.Hash{}), nativeField.Type) + native, err := entry.ToNative(reflect.New(entry.CheckedType())) + require.NoError(t, err) + assertHaveSameStructureAndNames(t, native.Type().Elem(), entry.CheckedType()) + } }) t.Run("Too many indexed items returns an error", func(t *testing.T) { From 55e7c8b5055c975665a59199d5eda9fa21801a07 Mon Sep 17 00:00:00 2001 From: "Abdelrahman Soliman (Boda)" <2677789+asoliman92@users.noreply.github.com> Date: Tue, 6 Aug 2024 15:15:37 +0400 Subject: [PATCH 036/432] [CCIP-Merge] OCR2 plugins [CCIP-2942] (#14043) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Copy over core/services/ocr2/plugins/ccip from ccip repo (#14024) This is first part in merging offchain code from ccip repo (https://github.com/smartcontractkit/ccip) into chainlink Maintaining history across repos for specific direcotires was complicated so we chose to copy the directory right away. ----------------- Co-authored-by: Abdelrahman Soliman (Boda) <2677789+asoliman92@users.noreply.github.com> Co-authored-by: Agustina Aldasoro Co-authored-by: Amir Y <83904651+amirylm@users.noreply.github.com> Co-authored-by: André Vitor de Lima Matos Co-authored-by: AnieeG Co-authored-by: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Co-authored-by: Chunkai Yang Co-authored-by: Connor Stein Co-authored-by: Evaldas Latoškinas <34982762+elatoskinas@users.noreply.github.com> Co-authored-by: Jean Arnaud Co-authored-by: Justin Kaseman Co-authored-by: Makram Co-authored-by: Makram Kamaleddine Co-authored-by: Mateusz Sekara Co-authored-by: Matt Yang Co-authored-by: Patrick Co-authored-by: Rens Rooimans Co-authored-by: Roman Kashitsyn Co-authored-by: Roman Kashitsyn Co-authored-by: Ryan Stout Co-authored-by: Will Winder Co-authored-by: connorwstein Co-authored-by: dimitris Co-authored-by: dimkouv Co-authored-by: nogo <0xnogo@gmail.com> Co-authored-by: nogo <110664798+0xnogo@users.noreply.github.com> Co-authored-by: valerii-kabisov-cll <172247313+valerii-kabisov-cll@users.noreply.github.com> * [CCIP-2942] OCR2 plugins merge fixes [CCIP-2942] (#14026) * Add status checker original commit: https://github.com/smartcontractkit/ccip/commit/451984ad0469c7d685e305dba0a0d94eb0c9a053 * Add CCIP to types.go * Add Unsafe_SetConnectionsManager to feeds service for testing * Add CCIP feature to core.toml * Rebuilding config * Wiring up relayer and ocr2 delegates - this commit touches shared code ! * Adding mockery configuration for ccip specific code * Setting CCIP feature flag to true - it's no longer used anywhere --------- Co-authored-by: Mateusz Sekara * VRF-1138: Make CTF tests to reuse existing VRF Wrapper (#13854) * VRF-1138: Make CTF tests to reuse existing VRF Wrapper * VRF-1138: remove old code * VRF-1138: remove comments * VRF-1138: refactoring * VRF-1138: pr comments * VRF-1138: pr comments * VRF-1138: fixing lint issues * VRF-1138: PR comments * changes to support deterministic message hash in the remote target (#13935) * common version update to head of develop (#14030) * Add changeset --------- Co-authored-by: Agustina Aldasoro Co-authored-by: Amir Y <83904651+amirylm@users.noreply.github.com> Co-authored-by: André Vitor de Lima Matos Co-authored-by: AnieeG Co-authored-by: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Co-authored-by: Chunkai Yang Co-authored-by: Connor Stein Co-authored-by: Evaldas Latoškinas <34982762+elatoskinas@users.noreply.github.com> Co-authored-by: Jean Arnaud Co-authored-by: Justin Kaseman Co-authored-by: Makram Co-authored-by: Mateusz Sekara Co-authored-by: Matt Yang Co-authored-by: Patrick Co-authored-by: Rens Rooimans Co-authored-by: Roman Kashitsyn Co-authored-by: Roman Kashitsyn Co-authored-by: Ryan Stout Co-authored-by: Will Winder Co-authored-by: dimitris Co-authored-by: nogo <0xnogo@gmail.com> Co-authored-by: nogo <110664798+0xnogo@users.noreply.github.com> Co-authored-by: valerii-kabisov-cll <172247313+valerii-kabisov-cll@users.noreply.github.com> Co-authored-by: Ilja Pavlovs <5300706+iljapavlovs@users.noreply.github.com> Co-authored-by: Matthew Pendrey --- .changeset/young-mice-invent.md | 5 + .mockery.yaml | 93 +- core/config/docs/core.toml | 2 + core/config/toml/types.go | 4 + core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/chainlink/config_test.go | 2 + .../testdata/config-empty-effective.toml | 1 + .../chainlink/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 1 + core/services/feeds/mocks/service.go | 33 + core/services/feeds/service.go | 14 + core/services/ocr2/delegate.go | 401 +++- core/services/ocr2/plugins/ccip/LICENSE.md | 55 + .../plugins/ccip/abihelpers/abi_helpers.go | 187 ++ .../ccip/abihelpers/abi_helpers_test.go | 147 ++ .../ocr2/plugins/ccip/ccipcommit/factory.go | 150 ++ .../plugins/ccip/ccipcommit/factory_test.go | 100 + .../plugins/ccip/ccipcommit/initializers.go | 241 +++ .../ocr2/plugins/ccip/ccipcommit/ocr2.go | 753 +++++++ .../ocr2/plugins/ccip/ccipcommit/ocr2_test.go | 1861 +++++++++++++++++ .../ocr2/plugins/ccip/ccipexec/batching.go | 540 +++++ .../plugins/ccip/ccipexec/batching_test.go | 910 ++++++++ .../ocr2/plugins/ccip/ccipexec/factory.go | 164 ++ .../plugins/ccip/ccipexec/factory_test.go | 67 + .../ocr2/plugins/ccip/ccipexec/gashelpers.go | 83 + .../plugins/ccip/ccipexec/gashelpers_test.go | 179 ++ .../ocr2/plugins/ccip/ccipexec/helpers.go | 53 + .../plugins/ccip/ccipexec/helpers_test.go | 96 + .../ocr2/plugins/ccip/ccipexec/inflight.go | 82 + .../plugins/ccip/ccipexec/inflight_test.go | 42 + .../plugins/ccip/ccipexec/initializers.go | 228 ++ .../ocr2/plugins/ccip/ccipexec/ocr2.go | 845 ++++++++ .../ocr2/plugins/ccip/ccipexec/ocr2_test.go | 1421 +++++++++++++ .../plugins/ccip/clo_ccip_integration_test.go | 137 ++ .../ocr2/plugins/ccip/config/chain_config.go | 48 + .../plugins/ccip/config/chain_config_test.go | 135 ++ .../ocr2/plugins/ccip/config/config.go | 152 ++ .../ocr2/plugins/ccip/config/config_test.go | 234 +++ .../plugins/ccip/config/offchain_config.go | 26 + .../plugins/ccip/config/type_and_version.go | 73 + .../ocr2/plugins/ccip/exportinternal.go | 135 ++ .../plugins/ccip/integration_legacy_test.go | 599 ++++++ .../ocr2/plugins/ccip/integration_test.go | 644 ++++++ .../plugins/ccip/internal/cache/autosync.go | 141 ++ .../ccip/internal/cache/autosync_test.go | 128 ++ .../ccip/internal/cache/chain_health.go | 273 +++ .../ccip/internal/cache/chain_health_test.go | 303 +++ .../ccip/internal/cache/commit_roots.go | 243 +++ .../ccip/internal/cache/commit_roots_test.go | 297 +++ .../internal/cache/commit_roots_unit_test.go | 212 ++ .../ocr2/plugins/ccip/internal/cache/lazy.go | 20 + .../plugins/ccip/internal/cache/lazy_test.go | 71 + .../internal/cache/mocks/chain_health_mock.go | 183 ++ .../internal/cache/observed_chain_health.go | 70 + .../cache/observed_chain_health_test.go | 62 + .../ocr2/plugins/ccip/internal/cache/once.go | 38 + .../plugins/ccip/internal/cache/once_test.go | 83 + .../plugins/ccip/internal/ccipcalc/addr.go | 44 + .../plugins/ccip/internal/ccipcalc/calc.go | 69 + .../ccip/internal/ccipcalc/calc_test.go | 220 ++ .../ccip/internal/ccipcommon/shortcuts.go | 140 ++ .../internal/ccipcommon/shortcuts_test.go | 196 ++ .../mocks/token_pool_batched_reader_mock.go | 142 ++ .../batchreader/token_pool_batch_reader.go | 192 ++ .../token_pool_batch_reader_test.go | 86 + .../mocks/price_registry_mock.go | 97 + .../ccipdata/ccipdataprovider/provider.go | 40 + .../internal/ccipdata/commit_store_reader.go | 81 + .../ccipdata/commit_store_reader_test.go | 423 ++++ .../internal/ccipdata/factory/commit_store.go | 121 ++ .../ccipdata/factory/commit_store_test.go | 37 + .../ccip/internal/ccipdata/factory/offramp.go | 125 ++ .../internal/ccipdata/factory/offramp_test.go | 44 + .../ccip/internal/ccipdata/factory/onramp.go | 88 + .../internal/ccipdata/factory/onramp_test.go | 45 + .../ccipdata/factory/price_registry.go | 82 + .../ccipdata/factory/price_registry_test.go | 46 + .../ccipdata/factory/versionfinder.go | 44 + .../mocks/commit_store_reader_mock.go | 985 +++++++++ .../ccipdata/mocks/offramp_reader_mock.go | 949 +++++++++ .../ccipdata/mocks/onramp_reader_mock.go | 480 +++++ .../mocks/price_registry_reader_mock.go | 498 +++++ .../ccipdata/mocks/token_pool_reader_mock.go | 127 ++ .../ccipdata/mocks/usdc_reader_mock.go | 97 + .../ccip/internal/ccipdata/offramp_reader.go | 13 + .../internal/ccipdata/offramp_reader_test.go | 416 ++++ .../ccip/internal/ccipdata/onramp_reader.go | 21 + .../internal/ccipdata/onramp_reader_test.go | 479 +++++ .../ccipdata/price_registry_reader.go | 14 + .../ccipdata/price_registry_reader_test.go | 296 +++ .../plugins/ccip/internal/ccipdata/reader.go | 78 + .../ccip/internal/ccipdata/reader_test.go | 72 + .../ccip/internal/ccipdata/retry_config.go | 9 + .../ccip/internal/ccipdata/test_utils.go | 36 + .../internal/ccipdata/token_pool_reader.go | 10 + .../ccip/internal/ccipdata/usdc_reader.go | 169 ++ .../ccipdata/usdc_reader_internal_test.go | 178 ++ .../internal/ccipdata/v1_0_0/commit_store.go | 456 ++++ .../ccipdata/v1_0_0/commit_store_test.go | 49 + .../ccip/internal/ccipdata/v1_0_0/hasher.go | 85 + .../internal/ccipdata/v1_0_0/hasher_test.go | 84 + .../ccip/internal/ccipdata/v1_0_0/offramp.go | 689 ++++++ .../ccipdata/v1_0_0/offramp_reader_test.go | 38 + .../v1_0_0/offramp_reader_unit_test.go | 231 ++ .../internal/ccipdata/v1_0_0/offramp_test.go | 232 ++ .../ccip/internal/ccipdata/v1_0_0/onramp.go | 240 +++ .../ccipdata/v1_0_0/price_registry.go | 310 +++ .../internal/ccipdata/v1_0_0/test_helpers.go | 90 + .../ccip/internal/ccipdata/v1_1_0/onramp.go | 70 + .../internal/ccipdata/v1_2_0/commit_store.go | 469 +++++ .../ccipdata/v1_2_0/commit_store_test.go | 224 ++ .../ccip/internal/ccipdata/v1_2_0/hasher.go | 101 + .../internal/ccipdata/v1_2_0/hasher_test.go | 78 + .../ccip/internal/ccipdata/v1_2_0/offramp.go | 340 +++ .../ccipdata/v1_2_0/offramp_reader_test.go | 38 + .../v1_2_0/offramp_reader_unit_test.go | 36 + .../internal/ccipdata/v1_2_0/offramp_test.go | 173 ++ .../ccip/internal/ccipdata/v1_2_0/onramp.go | 255 +++ .../internal/ccipdata/v1_2_0/onramp_test.go | 57 + .../ccipdata/v1_2_0/price_registry.go | 68 + .../internal/ccipdata/v1_2_0/test_helpers.go | 48 + .../internal/ccipdata/v1_2_0/token_pool.go | 48 + .../ccipdata/v1_2_0/token_pool_test.go | 24 + .../internal/ccipdata/v1_4_0/token_pool.go | 48 + .../ccipdata/v1_4_0/token_pool_test.go | 24 + .../internal/ccipdata/v1_5_0/commit_store.go | 59 + .../ccip/internal/ccipdata/v1_5_0/hasher.go | 101 + .../internal/ccipdata/v1_5_0/hasher_test.go | 78 + .../ccip/internal/ccipdata/v1_5_0/offramp.go | 199 ++ .../internal/ccipdata/v1_5_0/offramp_test.go | 1 + .../ccip/internal/ccipdata/v1_5_0/onramp.go | 259 +++ .../internal/ccipdata/v1_5_0/onramp_test.go | 210 ++ .../ccipdb/mocks/price_service_mock.go | 250 +++ .../ccip/internal/ccipdb/price_service.go | 400 ++++ .../internal/ccipdb/price_service_test.go | 755 +++++++ .../ccip/internal/logpollerutil/filters.go | 73 + .../internal/logpollerutil/filters_test.go | 156 ++ .../internal/observability/commit_store.go | 75 + .../ccip/internal/observability/metrics.go | 75 + .../internal/observability/metrics_test.go | 87 + .../ccip/internal/observability/offramp.go | 69 + .../ccip/internal/observability/onramp.go | 63 + .../observability/onramp_observed_test.go | 155 ++ .../internal/observability/price_registry.go | 64 + .../internal/oraclelib/backfilled_oracle.go | 218 ++ .../oraclelib/backfilled_oracle_test.go | 56 + .../plugins/ccip/internal/parseutil/bigint.go | 44 + .../ccip/internal/parseutil/bigint_test.go | 42 + .../plugins/ccip/internal/pricegetter/evm.go | 239 +++ .../ccip/internal/pricegetter/evm_test.go | 546 +++++ .../plugins/ccip/internal/pricegetter/mock.go | 211 ++ .../ccip/internal/pricegetter/pipeline.go | 114 + .../internal/pricegetter/pipeline_test.go | 178 ++ .../ccip/internal/pricegetter/pricegetter.go | 7 + .../ocr2/plugins/ccip/internal/rpclib/evm.go | 337 +++ .../plugins/ccip/internal/rpclib/evm_test.go | 223 ++ .../internal/rpclib/rpclibmocks/evm_mock.go | 97 + core/services/ocr2/plugins/ccip/metrics.go | 99 + .../ocr2/plugins/ccip/metrics_test.go | 47 + .../ocr2/plugins/ccip/observations.go | 149 ++ .../ocr2/plugins/ccip/observations_test.go | 305 +++ .../ocr2/plugins/ccip/pkg/leafer/leafer.go | 61 + .../plugins/ccip/prices/da_price_estimator.go | 176 ++ .../ccip/prices/da_price_estimator_test.go | 440 ++++ .../ccip/prices/exec_price_estimator.go | 65 + .../ccip/prices/exec_price_estimator_test.go | 351 ++++ .../ccip/prices/gas_price_estimator.go | 59 + .../prices/gas_price_estimator_commit_mock.go | 269 +++ .../prices/gas_price_estimator_exec_mock.go | 274 +++ .../ccip/prices/gas_price_estimator_mock.go | 331 +++ .../ocr2/plugins/ccip/proxycommitstore.go | 135 ++ .../ccip/testhelpers/ccip_contracts.go | 1580 ++++++++++++++ .../ocr2/plugins/ccip/testhelpers/config.go | 73 + .../ccip/testhelpers/integration/chainlink.go | 1035 +++++++++ .../ccip/testhelpers/integration/jobspec.go | 334 +++ .../ocr2/plugins/ccip/testhelpers/offramp.go | 119 ++ .../ccip/testhelpers/simulated_backend.go | 75 + .../plugins/ccip/testhelpers/structfields.go | 44 + .../testhelpers_1_4_0/ccip_contracts_1_4_0.go | 1585 ++++++++++++++ .../testhelpers_1_4_0/chainlink.go | 1045 +++++++++ .../testhelpers_1_4_0/config_1_4_0.go | 73 + .../ocr2/plugins/ccip/tokendata/bgworker.go | 213 ++ .../plugins/ccip/tokendata/bgworker_test.go | 188 ++ .../ccip/tokendata/http/http_client.go | 48 + .../tokendata/http/observed_http_client.go | 69 + .../observability/usdc_client_test.go | 151 ++ .../ocr2/plugins/ccip/tokendata/reader.go | 19 + .../plugins/ccip/tokendata/reader_mock.go | 143 ++ .../ocr2/plugins/ccip/tokendata/usdc/usdc.go | 339 +++ .../ccip/tokendata/usdc/usdc_blackbox_test.go | 119 ++ .../plugins/ccip/tokendata/usdc/usdc_test.go | 423 ++++ .../ocr2/plugins/ccip/transactions.rlp | Bin 0 -> 115794 bytes .../plugins/ccip/transmitter/transmitter.go | 143 ++ .../ccip/transmitter/transmitter_test.go | 282 +++ core/services/ocr2/plugins/ccip/vars.go | 14 + core/services/ocr2/validate/validate.go | 59 +- core/services/relay/evm/ccip.go | 205 ++ core/services/relay/evm/ccip_test.go | 18 + core/services/relay/evm/commit_provider.go | 309 +++ core/services/relay/evm/evm.go | 227 +- core/services/relay/evm/exec_provider.go | 391 ++++ .../mocks/ccip_transaction_status_checker.go | 104 + .../evm/statuschecker/txm_status_checker.go | 54 + .../statuschecker/txm_status_checker_test.go | 103 + core/services/synchronization/common.go | 2 + .../testdata/config-empty-effective.toml | 1 + core/web/resolver/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 1 + docs/CONFIG.md | 7 + go.mod | 8 +- go.sum | 9 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- testdata/scripts/node/validate/default.txtar | 1 + .../disk-based-logging-disabled.txtar | 1 + .../validate/disk-based-logging-no-dir.txtar | 1 + .../node/validate/disk-based-logging.txtar | 1 + .../node/validate/invalid-ocr-p2p.txtar | 1 + testdata/scripts/node/validate/invalid.txtar | 1 + testdata/scripts/node/validate/valid.txtar | 1 + testdata/scripts/node/validate/warnings.txtar | 1 + 224 files changed, 42778 insertions(+), 25 deletions(-) create mode 100644 .changeset/young-mice-invent.md create mode 100644 core/services/ocr2/plugins/ccip/LICENSE.md create mode 100644 core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go create mode 100644 core/services/ocr2/plugins/ccip/abihelpers/abi_helpers_test.go create mode 100644 core/services/ocr2/plugins/ccip/ccipcommit/factory.go create mode 100644 core/services/ocr2/plugins/ccip/ccipcommit/factory_test.go create mode 100644 core/services/ocr2/plugins/ccip/ccipcommit/initializers.go create mode 100644 core/services/ocr2/plugins/ccip/ccipcommit/ocr2.go create mode 100644 core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/batching.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/batching_test.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/factory.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/factory_test.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/gashelpers.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/gashelpers_test.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/helpers.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/helpers_test.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/inflight.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/inflight_test.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/initializers.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/ocr2.go create mode 100644 core/services/ocr2/plugins/ccip/ccipexec/ocr2_test.go create mode 100644 core/services/ocr2/plugins/ccip/clo_ccip_integration_test.go create mode 100644 core/services/ocr2/plugins/ccip/config/chain_config.go create mode 100644 core/services/ocr2/plugins/ccip/config/chain_config_test.go create mode 100644 core/services/ocr2/plugins/ccip/config/config.go create mode 100644 core/services/ocr2/plugins/ccip/config/config_test.go create mode 100644 core/services/ocr2/plugins/ccip/config/offchain_config.go create mode 100644 core/services/ocr2/plugins/ccip/config/type_and_version.go create mode 100644 core/services/ocr2/plugins/ccip/exportinternal.go create mode 100644 core/services/ocr2/plugins/ccip/integration_legacy_test.go create mode 100644 core/services/ocr2/plugins/ccip/integration_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/autosync.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/autosync_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/chain_health.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/chain_health_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/commit_roots.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/commit_roots_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/commit_roots_unit_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/lazy.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/lazy_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/mocks/chain_health_mock.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/observed_chain_health.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/observed_chain_health_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/once.go create mode 100644 core/services/ocr2/plugins/ccip/internal/cache/once_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipcalc/addr.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipcalc/calc.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipcalc/calc_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/mocks/token_pool_batched_reader_mock.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/mocks/price_registry_mock.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/provider.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/factory/versionfinder.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/commit_store_reader_mock.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/offramp_reader_mock.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/onramp_reader_mock.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/price_registry_reader_mock.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/token_pool_reader_mock.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/usdc_reader_mock.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/reader_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/retry_config.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/test_utils.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/token_pool_reader.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_internal_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/hasher.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/hasher_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_unit_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/price_registry.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/test_helpers.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_1_0/onramp.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/hasher.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/hasher_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_unit_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/price_registry.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/test_helpers.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/token_pool.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/token_pool_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_4_0/token_pool.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_4_0/token_pool_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/commit_store.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/hasher.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/hasher_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdb/mocks/price_service_mock.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/logpollerutil/filters.go create mode 100644 core/services/ocr2/plugins/ccip/internal/logpollerutil/filters_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/observability/commit_store.go create mode 100644 core/services/ocr2/plugins/ccip/internal/observability/metrics.go create mode 100644 core/services/ocr2/plugins/ccip/internal/observability/metrics_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/observability/offramp.go create mode 100644 core/services/ocr2/plugins/ccip/internal/observability/onramp.go create mode 100644 core/services/ocr2/plugins/ccip/internal/observability/onramp_observed_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/observability/price_registry.go create mode 100644 core/services/ocr2/plugins/ccip/internal/oraclelib/backfilled_oracle.go create mode 100644 core/services/ocr2/plugins/ccip/internal/oraclelib/backfilled_oracle_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/parseutil/bigint.go create mode 100644 core/services/ocr2/plugins/ccip/internal/parseutil/bigint_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/pricegetter/evm.go create mode 100644 core/services/ocr2/plugins/ccip/internal/pricegetter/evm_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/pricegetter/mock.go create mode 100644 core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline.go create mode 100644 core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/pricegetter/pricegetter.go create mode 100644 core/services/ocr2/plugins/ccip/internal/rpclib/evm.go create mode 100644 core/services/ocr2/plugins/ccip/internal/rpclib/evm_test.go create mode 100644 core/services/ocr2/plugins/ccip/internal/rpclib/rpclibmocks/evm_mock.go create mode 100644 core/services/ocr2/plugins/ccip/metrics.go create mode 100644 core/services/ocr2/plugins/ccip/metrics_test.go create mode 100644 core/services/ocr2/plugins/ccip/observations.go create mode 100644 core/services/ocr2/plugins/ccip/observations_test.go create mode 100644 core/services/ocr2/plugins/ccip/pkg/leafer/leafer.go create mode 100644 core/services/ocr2/plugins/ccip/prices/da_price_estimator.go create mode 100644 core/services/ocr2/plugins/ccip/prices/da_price_estimator_test.go create mode 100644 core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go create mode 100644 core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go create mode 100644 core/services/ocr2/plugins/ccip/prices/gas_price_estimator.go create mode 100644 core/services/ocr2/plugins/ccip/prices/gas_price_estimator_commit_mock.go create mode 100644 core/services/ocr2/plugins/ccip/prices/gas_price_estimator_exec_mock.go create mode 100644 core/services/ocr2/plugins/ccip/prices/gas_price_estimator_mock.go create mode 100644 core/services/ocr2/plugins/ccip/proxycommitstore.go create mode 100644 core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go create mode 100644 core/services/ocr2/plugins/ccip/testhelpers/config.go create mode 100644 core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go create mode 100644 core/services/ocr2/plugins/ccip/testhelpers/integration/jobspec.go create mode 100644 core/services/ocr2/plugins/ccip/testhelpers/offramp.go create mode 100644 core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go create mode 100644 core/services/ocr2/plugins/ccip/testhelpers/structfields.go create mode 100644 core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go create mode 100644 core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go create mode 100644 core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go create mode 100644 core/services/ocr2/plugins/ccip/tokendata/bgworker.go create mode 100644 core/services/ocr2/plugins/ccip/tokendata/bgworker_test.go create mode 100644 core/services/ocr2/plugins/ccip/tokendata/http/http_client.go create mode 100644 core/services/ocr2/plugins/ccip/tokendata/http/observed_http_client.go create mode 100644 core/services/ocr2/plugins/ccip/tokendata/observability/usdc_client_test.go create mode 100644 core/services/ocr2/plugins/ccip/tokendata/reader.go create mode 100644 core/services/ocr2/plugins/ccip/tokendata/reader_mock.go create mode 100644 core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go create mode 100644 core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go create mode 100644 core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go create mode 100644 core/services/ocr2/plugins/ccip/transactions.rlp create mode 100644 core/services/ocr2/plugins/ccip/transmitter/transmitter.go create mode 100644 core/services/ocr2/plugins/ccip/transmitter/transmitter_test.go create mode 100644 core/services/ocr2/plugins/ccip/vars.go create mode 100644 core/services/relay/evm/ccip.go create mode 100644 core/services/relay/evm/ccip_test.go create mode 100644 core/services/relay/evm/commit_provider.go create mode 100644 core/services/relay/evm/exec_provider.go create mode 100644 core/services/relay/evm/statuschecker/mocks/ccip_transaction_status_checker.go create mode 100644 core/services/relay/evm/statuschecker/txm_status_checker.go create mode 100644 core/services/relay/evm/statuschecker/txm_status_checker_test.go diff --git a/.changeset/young-mice-invent.md b/.changeset/young-mice-invent.md new file mode 100644 index 0000000000..ba9c67198a --- /dev/null +++ b/.changeset/young-mice-invent.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Added CCIP plugins code from https://github.com/smartcontractkit/ccip/ #added diff --git a/.mockery.yaml b/.mockery.yaml index 77d2145a46..8fab61a5b9 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -457,4 +457,95 @@ packages: filename: optimism_dispute_game_factory_interface.go outpkg: mock_optimism_dispute_game_factory interfaces: - OptimismDisputeGameFactoryInterface: + OptimismDisputeGameFactoryInterface: + github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache: + config: + filename: chain_health_mock.go + interfaces: + ChainHealthcheck: + github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata: + interfaces: + CommitStoreReader: + config: + filename: commit_store_reader_mock.go + OffRampReader: + config: + filename: offramp_reader_mock.go + OnRampReader: + config: + filename: onramp_reader_mock.go + PriceRegistryReader: + config: + filename: price_registry_reader_mock.go + TokenPoolReader: + config: + filename: token_pool_reader_mock.go + USDCReader: + config: + filename: usdc_reader_mock.go + github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader: + config: + filename: token_pool_batched_reader_mock.go + interfaces: + TokenPoolBatchedReader: + github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider: + config: + filename: price_registry_mock.go + interfaces: + PriceRegistry: + github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdb: + config: + filename: price_service_mock.go + interfaces: + PriceService: + github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter: + config: + filename: mock.go + dir: "{{ .InterfaceDir }}/" + outpkg: pricegetter + interfaces: + PriceGetter: + config: + mockname: "Mock{{ .InterfaceName }}" + github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/statuschecker: + interfaces: + CCIPTransactionStatusChecker: + github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib: + config: + outpkg: rpclibmocks + interfaces: + BatchCaller: + config: + filename: batch_caller.go + dir: core/services/relay/evm/rpclibmocks + EvmBatchCaller: + config: + filename: evm_mock.go + dir: "{{ .InterfaceDir }}/rpclibmocks" + + github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices: + config: + dir: "{{ .InterfaceDir }}/" + outpkg: prices + interfaces: + GasPriceEstimatorCommit: + config: + mockname: "Mock{{ .InterfaceName }}" + filename: gas_price_estimator_commit_mock.go + GasPriceEstimatorExec: + config: + mockname: "Mock{{ .InterfaceName }}" + filename: gas_price_estimator_exec_mock.go + GasPriceEstimator: + config: + mockname: "Mock{{ .InterfaceName }}" + filename: gas_price_estimator_mock.go + github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata: + config: + filename: reader_mock.go + dir: "{{ .InterfaceDir }}/" + outpkg: tokendata + interfaces: + Reader: + config: + mockname: "Mock{{ .InterfaceName }}" \ No newline at end of file diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index d1b922cf29..d0960779c6 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -13,6 +13,8 @@ FeedsManager = true # Default LogPoller = false # Default # UICSAKeys enables CSA Keys in the UI. UICSAKeys = false # Default +# CCIP enables the CCIP service. +CCIP = true # Default [Database] # DefaultIdleInTxSessionTimeout is the maximum time allowed for a transaction to be open and idle before timing out. See Postgres `idle_in_transaction_session_timeout` for more details. diff --git a/core/config/toml/types.go b/core/config/toml/types.go index f827f08622..0c91ddd81a 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -303,6 +303,7 @@ type Feature struct { FeedsManager *bool LogPoller *bool UICSAKeys *bool + CCIP *bool } func (f *Feature) setFrom(f2 *Feature) { @@ -315,6 +316,9 @@ func (f *Feature) setFrom(f2 *Feature) { if v := f2.UICSAKeys; v != nil { f.UICSAKeys = v } + if v := f2.CCIP; v != nil { + f.CCIP = v + } } type Database struct { diff --git a/core/scripts/go.mod b/core/scripts/go.mod index fe4ee2c974..0b7f510bcd 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -60,7 +60,7 @@ require ( github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/XSAM/otelsql v0.27.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/avast/retry-go/v4 v4.5.1 // indirect + github.com/avast/retry-go/v4 v4.6.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 76eaf61527..6abc303888 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -147,8 +147,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o= -github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc= +github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= +github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 9b40e4dfce..0038be8a97 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -261,6 +261,7 @@ func TestConfig_Marshal(t *testing.T) { FeedsManager: ptr(true), LogPoller: ptr(true), UICSAKeys: ptr(true), + CCIP: ptr(true), } full.Database = toml.Database{ DefaultIdleInTxSessionTimeout: commoncfg.MustNewDuration(time.Minute), @@ -771,6 +772,7 @@ Headers = ['Authorization: token', 'X-SomeOther-Header: value with spaces | and FeedsManager = true LogPoller = true UICSAKeys = true +CCIP = true `}, {"Database", Config{Core: toml.Core{Database: full.Database}}, `[Database] DefaultIdleInTxSessionTimeout = '1m0s' diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index 1bad3fd91c..f1325d824e 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -6,6 +6,7 @@ ShutdownGracePeriod = '5s' FeedsManager = true LogPoller = false UICSAKeys = false +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 21d68c23ad..d752398f03 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -6,6 +6,7 @@ ShutdownGracePeriod = '10s' FeedsManager = true LogPoller = true UICSAKeys = true +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1m0s' diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index c56e755d36..12427650f4 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -6,6 +6,7 @@ ShutdownGracePeriod = '5s' FeedsManager = true LogPoller = false UICSAKeys = false +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/core/services/feeds/mocks/service.go b/core/services/feeds/mocks/service.go index a660420759..d37c327850 100644 --- a/core/services/feeds/mocks/service.go +++ b/core/services/feeds/mocks/service.go @@ -1403,6 +1403,39 @@ func (_c *Service_SyncNodeInfo_Call) RunAndReturn(run func(context.Context, int6 return _c } +// Unsafe_SetConnectionsManager provides a mock function with given fields: _a0 +func (_m *Service) Unsafe_SetConnectionsManager(_a0 feeds.ConnectionsManager) { + _m.Called(_a0) +} + +// Service_Unsafe_SetConnectionsManager_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Unsafe_SetConnectionsManager' +type Service_Unsafe_SetConnectionsManager_Call struct { + *mock.Call +} + +// Unsafe_SetConnectionsManager is a helper method to define mock.On call +// - _a0 feeds.ConnectionsManager +func (_e *Service_Expecter) Unsafe_SetConnectionsManager(_a0 interface{}) *Service_Unsafe_SetConnectionsManager_Call { + return &Service_Unsafe_SetConnectionsManager_Call{Call: _e.mock.On("Unsafe_SetConnectionsManager", _a0)} +} + +func (_c *Service_Unsafe_SetConnectionsManager_Call) Run(run func(_a0 feeds.ConnectionsManager)) *Service_Unsafe_SetConnectionsManager_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(feeds.ConnectionsManager)) + }) + return _c +} + +func (_c *Service_Unsafe_SetConnectionsManager_Call) Return() *Service_Unsafe_SetConnectionsManager_Call { + _c.Call.Return() + return _c +} + +func (_c *Service_Unsafe_SetConnectionsManager_Call) RunAndReturn(run func(feeds.ConnectionsManager)) *Service_Unsafe_SetConnectionsManager_Call { + _c.Call.Return(run) + return _c +} + // UpdateChainConfig provides a mock function with given fields: ctx, cfg func (_m *Service) UpdateChainConfig(ctx context.Context, cfg feeds.ChainConfig) (int64, error) { ret := _m.Called(ctx, cfg) diff --git a/core/services/feeds/service.go b/core/services/feeds/service.go index b11b2b0167..1733d4a758 100644 --- a/core/services/feeds/service.go +++ b/core/services/feeds/service.go @@ -107,6 +107,9 @@ type Service interface { ListSpecsByJobProposalIDs(ctx context.Context, ids []int64) ([]JobProposalSpec, error) RejectSpec(ctx context.Context, id int64) error UpdateSpecDefinition(ctx context.Context, id int64, spec string) error + + // Unsafe_SetConnectionsManager Only for testing + Unsafe_SetConnectionsManager(ConnectionsManager) } type service struct { @@ -1105,6 +1108,16 @@ func (s *service) observeJobProposalCounts(ctx context.Context) error { return nil } +// Unsafe_SetConnectionsManager sets the ConnectionsManager on the service. +// +// We need to be able to inject a mock for the client to facilitate integration +// tests. +// +// ONLY TO BE USED FOR TESTING. +func (s *service) Unsafe_SetConnectionsManager(connMgr ConnectionsManager) { + s.connMgr = connMgr +} + // findExistingJobForOCR2 looks for existing job for OCR2 func findExistingJobForOCR2(ctx context.Context, j *job.Job, tx job.ORM) (int32, error) { var contractID string @@ -1501,5 +1514,6 @@ func (ns NullService) IsJobManaged(ctx context.Context, jobID int64) (bool, erro func (ns NullService) UpdateSpecDefinition(ctx context.Context, id int64, spec string) error { return ErrFeedsManagerDisabled } +func (ns NullService) Unsafe_SetConnectionsManager(_ ConnectionsManager) {} //revive:enable diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index db0f4e9725..5c44825ca2 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -6,18 +6,25 @@ import ( "encoding/json" "fmt" "log" + "strconv" "time" + "gopkg.in/guregu/null.v4" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" - "google.golang.org/grpc" - "gopkg.in/guregu/null.v4" - + chainselectors "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/libocr/commontypes" libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "google.golang.org/grpc" ocr2keepers20 "github.com/smartcontractkit/chainlink-automation/pkg/v2" ocr2keepers20config "github.com/smartcontractkit/chainlink-automation/pkg/v2/config" @@ -26,13 +33,11 @@ import ( ocr2keepers20runner "github.com/smartcontractkit/chainlink-automation/pkg/v2/runner" ocr2keepers21config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" ocr2keepers21 "github.com/smartcontractkit/chainlink-automation/pkg/v3/plugin" - "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins" "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins/ocr3" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/smartcontractkit/chainlink-common/pkg/types/core" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" datastreamsllo "github.com/smartcontractkit/chainlink-data-streams/llo" @@ -47,12 +52,15 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" "github.com/smartcontractkit/chainlink/v2/core/services/llo" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/ccipcommit" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/ccipexec" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/generic" lloconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/llo/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/median" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/autotelemetry21" ocr2keeper21core "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" @@ -68,6 +76,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" "github.com/smartcontractkit/chainlink/v2/plugins" + + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" ) type ErrJobSpecNoRelayer struct { @@ -284,6 +294,7 @@ func (d *Delegate) cleanupEVM(ctx context.Context, jb job.Job, relayID types.Rel // an inconsistent state. This assumes UnregisterFilter will return nil if the filter wasn't found // at all (no rows deleted). spec := jb.OCR2OracleSpec + transmitterID := spec.TransmitterID.String chain, err := d.legacyChains.Get(relayID.ChainID) if err != nil { d.lggr.Errorw("cleanupEVM: failed to get chain id", "chainId", relayID.ChainID, "err", err) @@ -305,6 +316,51 @@ func (d *Delegate) cleanupEVM(ctx context.Context, jb job.Job, relayID types.Rel d.lggr.Errorw("failed to derive ocr2keeper filter names from spec", "err", err, "spec", spec) } filters = append(filters, filters21...) + case types.CCIPCommit: + // Write PluginConfig bytes to send source/dest relayer provider + info outside of top level rargs/pargs over the wire + var pluginJobSpecConfig ccipconfig.CommitPluginJobSpecConfig + err = json.Unmarshal(spec.PluginConfig.Bytes(), &pluginJobSpecConfig) + if err != nil { + return err + } + + dstProvider, err2 := d.ccipCommitGetDstProvider(ctx, jb, pluginJobSpecConfig, transmitterID) + if err2 != nil { + return err + } + + srcProvider, _, err2 := d.ccipCommitGetSrcProvider(ctx, jb, pluginJobSpecConfig, transmitterID, dstProvider) + if err2 != nil { + return err + } + err2 = ccipcommit.UnregisterCommitPluginLpFilters(srcProvider, dstProvider) + if err2 != nil { + d.lggr.Errorw("failed to unregister ccip commit plugin filters", "err", err2, "spec", spec) + } + return nil + case types.CCIPExecution: + // PROVIDER BASED ARG CONSTRUCTION + // Write PluginConfig bytes to send source/dest relayer provider + info outside of top level rargs/pargs over the wire + var pluginJobSpecConfig ccipconfig.ExecPluginJobSpecConfig + err = json.Unmarshal(spec.PluginConfig.Bytes(), &pluginJobSpecConfig) + if err != nil { + return err + } + + dstProvider, err2 := d.ccipExecGetDstProvider(ctx, jb, pluginJobSpecConfig, transmitterID) + if err2 != nil { + return err + } + + srcProvider, _, err2 := d.ccipExecGetSrcProvider(ctx, jb, pluginJobSpecConfig, transmitterID, dstProvider) + if err2 != nil { + return err + } + err2 = ccipexec.UnregisterExecPluginLpFilters(srcProvider, dstProvider) + if err2 != nil { + d.lggr.Errorw("failed to unregister ccip exec plugin filters", "err", err2, "spec", spec) + } + return nil default: return nil } @@ -448,6 +504,10 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi return d.newServicesGenericPlugin(ctx, lggr, jb, bootstrapPeers, kb, ocrDB, lc, d.capabilitiesRegistry, kvStore) + case types.CCIPCommit: + return d.newServicesCCIPCommit(ctx, lggr, jb, bootstrapPeers, kb, ocrDB, lc, transmitterID) + case types.CCIPExecution: + return d.newServicesCCIPExecution(ctx, lggr, jb, bootstrapPeers, kb, ocrDB, lc, transmitterID) default: return nil, errors.Errorf("plugin type %s not supported", spec.PluginType) } @@ -1498,6 +1558,337 @@ func (d *Delegate) newServicesOCR2Functions( return append([]job.ServiceCtx{functionsProvider, thresholdProvider, s4Provider, ocrLogger}, functionsServices...), nil } +func (d *Delegate) newServicesCCIPCommit(ctx context.Context, lggr logger.SugaredLogger, jb job.Job, bootstrapPeers []commontypes.BootstrapperLocator, kb ocr2key.KeyBundle, ocrDB *db, lc ocrtypes.LocalConfig, transmitterID string) ([]job.ServiceCtx, error) { + spec := jb.OCR2OracleSpec + if spec.Relay != relay.NetworkEVM { + return nil, fmt.Errorf("non evm chains are not supported for CCIP commit") + } + dstRid, err := spec.RelayID() + if err != nil { + return nil, ErrJobSpecNoRelayer{Err: err, PluginName: string(spec.PluginType)} + } + + logError := func(msg string) { + lggr.ErrorIf(d.jobORM.RecordError(context.Background(), jb.ID, msg), "unable to record error") + } + + // Write PluginConfig bytes to send source/dest relayer provider + info outside of top level rargs/pargs over the wire + var pluginJobSpecConfig ccipconfig.CommitPluginJobSpecConfig + err = json.Unmarshal(spec.PluginConfig.Bytes(), &pluginJobSpecConfig) + if err != nil { + return nil, err + } + + dstChainID, err := strconv.ParseInt(dstRid.ChainID, 10, 64) + if err != nil { + return nil, err + } + + dstProvider, err := d.ccipCommitGetDstProvider(ctx, jb, pluginJobSpecConfig, transmitterID) + if err != nil { + return nil, err + } + + srcProvider, srcChainID, err := d.ccipCommitGetSrcProvider(ctx, jb, pluginJobSpecConfig, transmitterID, dstProvider) + if err != nil { + return nil, err + } + + oracleArgsNoPlugin := libocr2.OCR2OracleArgs{ + BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, + V2Bootstrappers: bootstrapPeers, + ContractTransmitter: dstProvider.ContractTransmitter(), + ContractConfigTracker: dstProvider.ContractConfigTracker(), + Database: ocrDB, + LocalConfig: lc, + MonitoringEndpoint: d.monitoringEndpointGen.GenMonitoringEndpoint( + dstRid.Network, + dstRid.ChainID, + spec.ContractID, + synchronization.OCR2CCIPCommit, + ), + OffchainConfigDigester: dstProvider.OffchainConfigDigester(), + OffchainKeyring: kb, + OnchainKeyring: kb, + MetricsRegisterer: prometheus.WrapRegistererWith(map[string]string{"job_name": jb.Name.ValueOrZero()}, prometheus.DefaultRegisterer), + } + + return ccipcommit.NewCommitServices(ctx, d.ds, srcProvider, dstProvider, d.legacyChains, jb, lggr, d.pipelineRunner, oracleArgsNoPlugin, d.isNewlyCreatedJob, int64(srcChainID), dstChainID, logError) +} + +func newCCIPCommitPluginBytes(isSourceProvider bool, sourceStartBlock uint64, destStartBlock uint64) config.CommitPluginConfig { + return config.CommitPluginConfig{ + IsSourceProvider: isSourceProvider, + SourceStartBlock: sourceStartBlock, + DestStartBlock: destStartBlock, + } +} + +func (d *Delegate) ccipCommitGetDstProvider(ctx context.Context, jb job.Job, pluginJobSpecConfig ccipconfig.CommitPluginJobSpecConfig, transmitterID string) (types.CCIPCommitProvider, error) { + spec := jb.OCR2OracleSpec + if spec.Relay != relay.NetworkEVM { + return nil, fmt.Errorf("non evm chains are not supported for CCIP commit") + } + + dstRid, err := spec.RelayID() + if err != nil { + return nil, ErrJobSpecNoRelayer{Err: err, PluginName: string(spec.PluginType)} + } + + // Write PluginConfig bytes to send source/dest relayer provider + info outside of top level rargs/pargs over the wire + dstConfigBytes, err := newCCIPCommitPluginBytes(false, pluginJobSpecConfig.SourceStartBlock, pluginJobSpecConfig.DestStartBlock).Encode() + if err != nil { + return nil, err + } + + // Get provider from dest chain + dstRelayer, err := d.RelayGetter.Get(dstRid) + if err != nil { + return nil, err + } + + provider, err := dstRelayer.NewPluginProvider(ctx, + types.RelayArgs{ + ContractID: spec.ContractID, + RelayConfig: spec.RelayConfig.Bytes(), + ProviderType: string(types.CCIPCommit), + }, + types.PluginArgs{ + TransmitterID: transmitterID, + PluginConfig: dstConfigBytes, + }) + if err != nil { + return nil, fmt.Errorf("unable to create ccip commit provider: %w", err) + } + dstProvider, ok := provider.(types.CCIPCommitProvider) + if !ok { + return nil, fmt.Errorf("could not coerce PluginProvider to CCIPCommitProvider") + } + + return dstProvider, nil +} + +func (d *Delegate) ccipCommitGetSrcProvider(ctx context.Context, jb job.Job, pluginJobSpecConfig ccipconfig.CommitPluginJobSpecConfig, transmitterID string, dstProvider types.CCIPCommitProvider) (srcProvider types.CCIPCommitProvider, srcChainID uint64, err error) { + spec := jb.OCR2OracleSpec + srcConfigBytes, err := newCCIPCommitPluginBytes(true, pluginJobSpecConfig.SourceStartBlock, pluginJobSpecConfig.DestStartBlock).Encode() + if err != nil { + return nil, 0, err + } + // Use OffRampReader to get src chain ID and fetch the src relayer + + var pluginConfig ccipconfig.CommitPluginJobSpecConfig + err = json.Unmarshal(spec.PluginConfig.Bytes(), &pluginConfig) + if err != nil { + return nil, 0, err + } + offRampAddress := pluginConfig.OffRamp + offRampReader, err := dstProvider.NewOffRampReader(ctx, offRampAddress) + if err != nil { + return nil, 0, fmt.Errorf("create offRampReader: %w", err) + } + + offRampConfig, err := offRampReader.GetStaticConfig(ctx) + if err != nil { + return nil, 0, fmt.Errorf("get offRamp static config: %w", err) + } + + srcChainID, err = chainselectors.ChainIdFromSelector(offRampConfig.SourceChainSelector) + if err != nil { + return nil, 0, err + } + srcChainIDstr := strconv.FormatUint(srcChainID, 10) + + // Get provider from source chain + srcRelayer, err := d.RelayGetter.Get(types.RelayID{Network: spec.Relay, ChainID: srcChainIDstr}) + if err != nil { + return nil, 0, err + } + provider, err := srcRelayer.NewPluginProvider(ctx, + types.RelayArgs{ + ContractID: "", // Contract address only valid for dst chain + RelayConfig: spec.RelayConfig.Bytes(), + ProviderType: string(types.CCIPCommit), + }, + types.PluginArgs{ + TransmitterID: transmitterID, + PluginConfig: srcConfigBytes, + }) + if err != nil { + return nil, 0, fmt.Errorf("srcRelayer.NewPluginProvider: %w", err) + } + srcProvider, ok := provider.(types.CCIPCommitProvider) + if !ok { + return nil, 0, fmt.Errorf("could not coerce PluginProvider to CCIPCommitProvider") + } + + return +} + +func (d *Delegate) newServicesCCIPExecution(ctx context.Context, lggr logger.SugaredLogger, jb job.Job, bootstrapPeers []commontypes.BootstrapperLocator, kb ocr2key.KeyBundle, ocrDB *db, lc ocrtypes.LocalConfig, transmitterID string) ([]job.ServiceCtx, error) { + spec := jb.OCR2OracleSpec + if spec.Relay != relay.NetworkEVM { + return nil, fmt.Errorf("non evm chains are not supported for CCIP execution") + } + dstRid, err := spec.RelayID() + + if err != nil { + return nil, ErrJobSpecNoRelayer{Err: err, PluginName: string(spec.PluginType)} + } + + logError := func(msg string) { + lggr.ErrorIf(d.jobORM.RecordError(context.Background(), jb.ID, msg), "unable to record error") + } + + // PROVIDER BASED ARG CONSTRUCTION + // Write PluginConfig bytes to send source/dest relayer provider + info outside of top level rargs/pargs over the wire + var pluginJobSpecConfig ccipconfig.ExecPluginJobSpecConfig + err = json.Unmarshal(spec.PluginConfig.Bytes(), &pluginJobSpecConfig) + if err != nil { + return nil, err + } + + dstChainID, err := strconv.ParseInt(dstRid.ChainID, 10, 64) + if err != nil { + return nil, err + } + + dstProvider, err := d.ccipExecGetDstProvider(ctx, jb, pluginJobSpecConfig, transmitterID) + if err != nil { + return nil, err + } + + srcProvider, srcChainID, err := d.ccipExecGetSrcProvider(ctx, jb, pluginJobSpecConfig, transmitterID, dstProvider) + if err != nil { + return nil, err + } + + oracleArgsNoPlugin2 := libocr2.OCR2OracleArgs{ + BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, + V2Bootstrappers: bootstrapPeers, + ContractTransmitter: dstProvider.ContractTransmitter(), + ContractConfigTracker: dstProvider.ContractConfigTracker(), + Database: ocrDB, + LocalConfig: lc, + MonitoringEndpoint: d.monitoringEndpointGen.GenMonitoringEndpoint( + dstRid.Network, + dstRid.ChainID, + spec.ContractID, + synchronization.OCR2CCIPExec, + ), + OffchainConfigDigester: dstProvider.OffchainConfigDigester(), + OffchainKeyring: kb, + OnchainKeyring: kb, + MetricsRegisterer: prometheus.WrapRegistererWith(map[string]string{"job_name": jb.Name.ValueOrZero()}, prometheus.DefaultRegisterer), + } + + return ccipexec.NewExecServices(ctx, lggr, jb, srcProvider, dstProvider, int64(srcChainID), dstChainID, d.isNewlyCreatedJob, oracleArgsNoPlugin2, logError) +} + +func (d *Delegate) ccipExecGetDstProvider(ctx context.Context, jb job.Job, pluginJobSpecConfig ccipconfig.ExecPluginJobSpecConfig, transmitterID string) (types.CCIPExecProvider, error) { + spec := jb.OCR2OracleSpec + if spec.Relay != relay.NetworkEVM { + return nil, fmt.Errorf("non evm chains are not supported for CCIP execution") + } + dstRid, err := spec.RelayID() + + if err != nil { + return nil, ErrJobSpecNoRelayer{Err: err, PluginName: string(spec.PluginType)} + } + + // PROVIDER BASED ARG CONSTRUCTION + // Write PluginConfig bytes to send source/dest relayer provider + info outside of top level rargs/pargs over the wire + dstConfigBytes, err := newExecPluginConfig(false, pluginJobSpecConfig.SourceStartBlock, pluginJobSpecConfig.DestStartBlock, pluginJobSpecConfig.USDCConfig, string(jb.ID)).Encode() + if err != nil { + return nil, err + } + + // Get provider from dest chain + dstRelayer, err := d.RelayGetter.Get(dstRid) + if err != nil { + return nil, err + } + provider, err := dstRelayer.NewPluginProvider(ctx, + types.RelayArgs{ + ContractID: spec.ContractID, + RelayConfig: spec.RelayConfig.Bytes(), + ProviderType: string(types.CCIPExecution), + }, + types.PluginArgs{ + TransmitterID: transmitterID, + PluginConfig: dstConfigBytes, + }) + if err != nil { + return nil, fmt.Errorf("NewPluginProvider failed on dstRelayer: %w", err) + } + dstProvider, ok := provider.(types.CCIPExecProvider) + if !ok { + return nil, fmt.Errorf("could not coerce PluginProvider to CCIPExecProvider") + } + + return dstProvider, nil +} + +func (d *Delegate) ccipExecGetSrcProvider(ctx context.Context, jb job.Job, pluginJobSpecConfig ccipconfig.ExecPluginJobSpecConfig, transmitterID string, dstProvider types.CCIPExecProvider) (srcProvider types.CCIPExecProvider, srcChainID uint64, err error) { + spec := jb.OCR2OracleSpec + srcConfigBytes, err := newExecPluginConfig(true, pluginJobSpecConfig.SourceStartBlock, pluginJobSpecConfig.DestStartBlock, pluginJobSpecConfig.USDCConfig, string(jb.ID)).Encode() + if err != nil { + return nil, 0, err + } + + // Use OffRampReader to get src chain ID and fetch the src relayer + offRampAddress := cciptypes.Address(common.HexToAddress(spec.ContractID).String()) + offRampReader, err := dstProvider.NewOffRampReader(ctx, offRampAddress) + if err != nil { + return nil, 0, fmt.Errorf("create offRampReader: %w", err) + } + + offRampConfig, err := offRampReader.GetStaticConfig(ctx) + if err != nil { + return nil, 0, fmt.Errorf("get offRamp static config: %w", err) + } + + srcChainID, err = chainselectors.ChainIdFromSelector(offRampConfig.SourceChainSelector) + if err != nil { + return nil, 0, err + } + srcChainIDstr := strconv.FormatUint(srcChainID, 10) + + // Get provider from source chain + srcRelayer, err := d.RelayGetter.Get(types.RelayID{Network: spec.Relay, ChainID: srcChainIDstr}) + if err != nil { + return nil, 0, fmt.Errorf("failed to get relayer: %w", err) + } + provider, err := srcRelayer.NewPluginProvider(ctx, + types.RelayArgs{ + ContractID: "", + RelayConfig: spec.RelayConfig.Bytes(), + ProviderType: string(types.CCIPExecution), + }, + types.PluginArgs{ + TransmitterID: transmitterID, + PluginConfig: srcConfigBytes, + }) + if err != nil { + return nil, 0, err + } + srcProvider, ok := provider.(types.CCIPExecProvider) + if !ok { + return nil, 0, fmt.Errorf("could not coerce PluginProvider to CCIPExecProvider: %w", err) + } + + return +} + +func newExecPluginConfig(isSourceProvider bool, srcStartBlock uint64, dstStartBlock uint64, usdcConfig ccipconfig.USDCConfig, jobID string) config.ExecPluginConfig { + return config.ExecPluginConfig{ + IsSourceProvider: isSourceProvider, + SourceStartBlock: srcStartBlock, + DestStartBlock: dstStartBlock, + USDCConfig: usdcConfig, + JobID: jobID, + } +} + // errorLog implements [loop.ErrorLog] type errorLog struct { jobID int32 diff --git a/core/services/ocr2/plugins/ccip/LICENSE.md b/core/services/ocr2/plugins/ccip/LICENSE.md new file mode 100644 index 0000000000..b127e1a823 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/LICENSE.md @@ -0,0 +1,55 @@ +Business Source License 1.1 + +License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. +"Business Source License" is a trademark of MariaDB Corporation Ab. + +----------------------------------------------------------------------------- + +Parameters + +Licensor: SmartContract Chainlink Limited SEZC + +Licensed Work: Cross-Chain Interoperability Protocol v1.4 +The Licensed Work is (c) 2023 SmartContract Chainlink Limited SEZC + +Additional Use Grant: Any uses listed and defined at [v1.4-CCIP-License-grants](../../../../../contracts/src/v0.8/ccip/v1.4-CCIP-License-grants) + +Change Date: May 23, 2027 + +Change License: MIT + +----------------------------------------------------------------------------- + +Terms + +The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and make non-production use of the Licensed Work. The Licensor may make an Additional Use Grant, above, permitting limited production use. + +Effective on the Change Date, or the fourth anniversary of the first publicly available distribution of a specific version of the Licensed Work under this License, whichever comes first, the Licensor hereby grants you rights under the terms of the Change License, and the rights granted in the paragraph above terminate. + +If your use of the Licensed Work does not comply with the requirements currently in effect as described in this License, you must purchase a commercial license from the Licensor, its affiliated entities, or authorized resellers, or you must refrain from using the Licensed Work. + +All copies of the original and modified Licensed Work, and derivative works of the Licensed Work, are subject to this License. This License applies separately for each version of the Licensed Work and the Change Date may vary for each version of the Licensed Work released by Licensor. + +You must conspicuously display this License on each original or modified copy of the Licensed Work. If you receive the Licensed Work in original or modified form from a third party, the terms and conditions set forth in this License apply to your use of that work. + +Any use of the Licensed Work in violation of this License will automatically terminate your rights under this License for the current and all other versions of the Licensed Work. + +This License does not grant you any right in any trademark or logo of Licensor or its affiliates (provided that you may use a trademark or logo of Licensor as expressly required by this License). + +TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE. + +MariaDB hereby grants you permission to use this License’s text to license your works, and to refer to it using the trademark "Business Source License", as long as you comply with the Covenants of Licensor below. + +----------------------------------------------------------------------------- + +Covenants of Licensor + +In consideration of the right to use this License’s text and the "Business Source License" name and trademark, Licensor covenants to MariaDB, and to all other recipients of the licensed work to be provided by Licensor: + +1. To specify as the Change License the GPL Version 2.0 or any later version, or a license that is compatible with GPL Version 2.0 or a later version, where "compatible" means that software provided under the Change License can be included in a program with software provided under GPL Version 2.0 or a later version. Licensor may specify additional Change Licenses without limitation. + +2. To either: (a) specify an additional grant of rights to use that does not impose any additional restriction on the right granted in this License, as the Additional Use Grant; or (b) insert the text "None". + +3. To specify a Change Date. + +4. Not to modify this License in any other way. \ No newline at end of file diff --git a/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go new file mode 100644 index 0000000000..d0ad5642d9 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go @@ -0,0 +1,187 @@ +package abihelpers + +import ( + "encoding/binary" + "fmt" + "math/big" + "strings" + "sync" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" +) + +func MustGetEventID(name string, abi2 abi.ABI) common.Hash { + event, ok := abi2.Events[name] + if !ok { + panic(fmt.Sprintf("missing event %s", name)) + } + return event.ID +} + +func MustGetEventInputs(name string, abi2 abi.ABI) abi.Arguments { + m, ok := abi2.Events[name] + if !ok { + panic(fmt.Sprintf("missing event %s", name)) + } + return m.Inputs +} + +func MustGetMethodInputs(name string, abi2 abi.ABI) abi.Arguments { + m, ok := abi2.Methods[name] + if !ok { + panic(fmt.Sprintf("missing method %s", name)) + } + return m.Inputs +} + +func MustParseABI(abiStr string) abi.ABI { + abiParsed, err := abi.JSON(strings.NewReader(abiStr)) + if err != nil { + panic(err) + } + return abiParsed +} + +// ProofFlagsToBits transforms a list of boolean proof flags to a *big.Int +// encoded number. +func ProofFlagsToBits(proofFlags []bool) *big.Int { + encodedFlags := big.NewInt(0) + for i := 0; i < len(proofFlags); i++ { + if proofFlags[i] { + encodedFlags.SetBit(encodedFlags, i, 1) + } + } + return encodedFlags +} + +type AbiDefined interface { + AbiString() string +} + +type AbiDefinedValid interface { + AbiDefined + Validate() error +} + +func ABIEncode(abiStr string, values ...interface{}) ([]byte, error) { + inAbi, err := getABI(abiStr, ENCODE) + if err != nil { + return nil, err + } + res, err := inAbi.Pack("method", values...) + if err != nil { + return nil, err + } + return res[4:], nil +} + +func ABIDecode(abiStr string, data []byte) ([]interface{}, error) { + inAbi, err := getABI(abiStr, DECODE) + if err != nil { + return nil, err + } + return inAbi.Unpack("method", data) +} + +func EncodeAbiStruct[T AbiDefined](decoded T) ([]byte, error) { + return ABIEncode(decoded.AbiString(), decoded) +} + +func EncodeAddress(address common.Address) ([]byte, error) { + return ABIEncode(`[{"type":"address"}]`, address) +} + +func DecodeAbiStruct[T AbiDefinedValid](encoded []byte) (T, error) { + var empty T + + decoded, err := ABIDecode(empty.AbiString(), encoded) + if err != nil { + return empty, err + } + + converted := abi.ConvertType(decoded[0], &empty) + if casted, ok := converted.(*T); ok { + return *casted, (*casted).Validate() + } + return empty, fmt.Errorf("can't cast from %T to %T", converted, empty) +} + +func EvmWord(i uint64) common.Hash { + b := make([]byte, 8) + binary.BigEndian.PutUint64(b, i) + return common.BigToHash(big.NewInt(0).SetBytes(b)) +} + +func DecodeOCR2Config(encoded []byte) (*ocr2aggregator.OCR2AggregatorConfigSet, error) { + unpacked := new(ocr2aggregator.OCR2AggregatorConfigSet) + abiPointer, err := ocr2aggregator.OCR2AggregatorMetaData.GetAbi() + if err != nil { + return unpacked, err + } + defaultABI := *abiPointer + err = defaultABI.UnpackIntoInterface(unpacked, "ConfigSet", encoded) + if err != nil { + return unpacked, errors.Wrap(err, "failed to unpack log data") + } + return unpacked, nil +} + +// create const encode and decode +const ( + ENCODE = iota + DECODE +) + +type abiCache struct { + cache map[string]*abi.ABI + mu *sync.RWMutex +} + +func newAbiCache() *abiCache { + return &abiCache{ + cache: make(map[string]*abi.ABI), + mu: &sync.RWMutex{}, + } +} + +// Global cache for ABIs to avoid parsing the same ABI multiple times +// As the module is already a helper module and not a service, we can keep the cache global +// It's private to the package and can't be accessed from outside +var myAbiCache = newAbiCache() + +// This Function is used to get the ABI from the cache or create a new one and cache it for later use +// operationType is used to differentiate between encoding and decoding +// encoding uses a definition with `inputs` and decoding uses a definition with `outputs` (check inDef) +func getABI(abiStr string, operationType uint8) (*abi.ABI, error) { + var operationStr string + switch operationType { + case ENCODE: + operationStr = "inputs" + case DECODE: + operationStr = "outputs" + default: + return nil, fmt.Errorf("invalid operation type") + } + + inDef := fmt.Sprintf(`[{ "name" : "method", "type": "function", "%s": %s}]`, operationStr, abiStr) + + myAbiCache.mu.RLock() + if cachedAbi, found := myAbiCache.cache[inDef]; found { + myAbiCache.mu.RUnlock() // unlocking before returning + return cachedAbi, nil + } + myAbiCache.mu.RUnlock() + + res, err := abi.JSON(strings.NewReader(inDef)) + if err != nil { + return nil, err + } + + myAbiCache.mu.Lock() + defer myAbiCache.mu.Unlock() + myAbiCache.cache[inDef] = &res + return &res, nil +} diff --git a/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers_test.go b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers_test.go new file mode 100644 index 0000000000..4890aeb118 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers_test.go @@ -0,0 +1,147 @@ +package abihelpers + +import ( + "bytes" + "fmt" + "math" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" +) + +func TestProofFlagToBits(t *testing.T) { + genFlags := func(indexesSet []int, size int) []bool { + bools := make([]bool, size) + for _, indexSet := range indexesSet { + bools[indexSet] = true + } + return bools + } + tt := []struct { + flags []bool + expected *big.Int + }{ + { + []bool{true, false, true}, + big.NewInt(5), + }, + { + []bool{true, true, false}, // Note the bits are reversed, slightly easier to implement. + big.NewInt(3), + }, + { + []bool{false, true, true}, + big.NewInt(6), + }, + { + []bool{false, false, false}, + big.NewInt(0), + }, + { + []bool{true, true, true}, + big.NewInt(7), + }, + { + genFlags([]int{266}, 300), + big.NewInt(0).SetBit(big.NewInt(0), 266, 1), + }, + } + for _, tc := range tt { + tc := tc + a := ProofFlagsToBits(tc.flags) + assert.Equal(t, tc.expected.String(), a.String()) + } +} + +func TestEvmWord(t *testing.T) { + testCases := []struct { + inp uint64 + exp common.Hash + }{ + {inp: 1, exp: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001")}, + {inp: math.MaxUint64, exp: common.HexToHash("0x000000000000000000000000000000000000000000000000ffffffffffffffff")}, + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("test %d", tc.inp), func(t *testing.T) { + h := EvmWord(tc.inp) + assert.Equal(t, tc.exp, h) + }) + } +} + +func TestABIEncodeDecode(t *testing.T) { + abiStr := `[{"components": [{"name":"int1","type":"int256"},{"name":"int2","type":"int256"}], "type":"tuple"}]` + values := []interface{}{struct { + Int1 *big.Int `json:"int1"` + Int2 *big.Int `json:"int2"` + }{big.NewInt(10), big.NewInt(12)}} + + // First encoding, should call the underlying utils.ABIEncode + encoded, err := ABIEncode(abiStr, values...) + assert.NoError(t, err) + assert.NotNil(t, encoded) + + // Second encoding, should retrieve from cache + // we're just testing here that it returns same result + encodedAgain, err := ABIEncode(abiStr, values...) + + assert.NoError(t, err) + assert.True(t, bytes.Equal(encoded, encodedAgain)) + + // Should be able to decode it back to the original values + decoded, err := ABIDecode(abiStr, encoded) + assert.NoError(t, err) + assert.Equal(t, decoded, values) +} + +func BenchmarkComparisonEncode(b *testing.B) { + abiStr := `[{"components": [{"name":"int1","type":"int256"},{"name":"int2","type":"int256"}], "type":"tuple"}]` + values := []interface{}{struct { + Int1 *big.Int `json:"int1"` + Int2 *big.Int `json:"int2"` + }{big.NewInt(10), big.NewInt(12)}} + + b.Run("WithoutCache", func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = utils.ABIEncode(abiStr, values...) + } + }) + + // Warm up the cache + _, _ = ABIEncode(abiStr, values...) + + b.Run("WithCache", func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = ABIEncode(abiStr, values...) + } + }) +} + +func BenchmarkComparisonDecode(b *testing.B) { + abiStr := `[{"components": [{"name":"int1","type":"int256"},{"name":"int2","type":"int256"}], "type":"tuple"}]` + values := []interface{}{struct { + Int1 *big.Int `json:"int1"` + Int2 *big.Int `json:"int2"` + }{big.NewInt(10), big.NewInt(12)}} + data, _ := utils.ABIEncode(abiStr, values...) + + b.Run("WithoutCache", func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = utils.ABIDecode(abiStr, data) + } + }) + + // Warm up the cache + _, _ = ABIDecode(abiStr, data) + + b.Run("WithCache", func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = ABIDecode(abiStr, data) + } + }) +} diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/factory.go b/core/services/ocr2/plugins/ccip/ccipcommit/factory.go new file mode 100644 index 0000000000..648f62a23a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipcommit/factory.go @@ -0,0 +1,150 @@ +package ccipcommit + +import ( + "context" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +type CommitReportingPluginFactory struct { + // Configuration derived from the job spec which does not change + // between plugin instances (ie between SetConfigs onchain) + config CommitPluginStaticConfig + + // Dynamic readers + readersMu *sync.Mutex + destPriceRegReader ccipdata.PriceRegistryReader + destPriceRegAddr common.Address +} + +// NewCommitReportingPluginFactory return a new CommitReportingPluginFactory. +func NewCommitReportingPluginFactory(config CommitPluginStaticConfig) *CommitReportingPluginFactory { + return &CommitReportingPluginFactory{ + config: config, + readersMu: &sync.Mutex{}, + + // the fields below are initially empty and populated on demand + destPriceRegReader: nil, + destPriceRegAddr: common.Address{}, + } +} + +func (rf *CommitReportingPluginFactory) UpdateDynamicReaders(ctx context.Context, newPriceRegAddr common.Address) error { + rf.readersMu.Lock() + defer rf.readersMu.Unlock() + // TODO: Investigate use of Close() to cleanup. + // TODO: a true price registry upgrade on an existing lane may want some kind of start block in its config? Right now we + // essentially assume that plugins don't care about historical price reg logs. + if rf.destPriceRegAddr == newPriceRegAddr { + // No-op + return nil + } + // Close old reader if present and open new reader if address changed + if rf.destPriceRegReader != nil { + if err := rf.destPriceRegReader.Close(); err != nil { + return err + } + } + + destPriceRegistryReader, err := rf.config.priceRegistryProvider.NewPriceRegistryReader(context.Background(), cciptypes.Address(newPriceRegAddr.String())) + if err != nil { + return fmt.Errorf("init dynamic price registry: %w", err) + } + rf.destPriceRegReader = destPriceRegistryReader + rf.destPriceRegAddr = newPriceRegAddr + return nil +} + +type reportingPluginAndInfo struct { + plugin types.ReportingPlugin + pluginInfo types.ReportingPluginInfo +} + +// NewReportingPlugin registers a new ReportingPlugin +func (rf *CommitReportingPluginFactory) NewReportingPlugin(config types.ReportingPluginConfig) (types.ReportingPlugin, types.ReportingPluginInfo, error) { + initialRetryDelay := rf.config.newReportingPluginRetryConfig.InitialDelay + maxDelay := rf.config.newReportingPluginRetryConfig.MaxDelay + + pluginAndInfo, err := ccipcommon.RetryUntilSuccess(rf.NewReportingPluginFn(config), initialRetryDelay, maxDelay) + if err != nil { + return nil, types.ReportingPluginInfo{}, err + } + return pluginAndInfo.plugin, pluginAndInfo.pluginInfo, err +} + +// NewReportingPluginFn implements the NewReportingPlugin logic. It is defined as a function so that it can easily be +// retried via RetryUntilSuccess. NewReportingPlugin must return successfully in order for the Commit plugin to +// function, hence why we can only keep retrying it until it succeeds. +func (rf *CommitReportingPluginFactory) NewReportingPluginFn(config types.ReportingPluginConfig) func() (reportingPluginAndInfo, error) { + return func() (reportingPluginAndInfo, error) { + ctx := context.Background() // todo: consider adding some timeout + + destPriceReg, err := rf.config.commitStore.ChangeConfig(ctx, config.OnchainConfig, config.OffchainConfig) + if err != nil { + return reportingPluginAndInfo{}, err + } + + priceRegEvmAddr, err := ccipcalc.GenericAddrToEvm(destPriceReg) + if err != nil { + return reportingPluginAndInfo{}, err + } + if err = rf.UpdateDynamicReaders(ctx, priceRegEvmAddr); err != nil { + return reportingPluginAndInfo{}, err + } + + pluginOffChainConfig, err := rf.config.commitStore.OffchainConfig(ctx) + if err != nil { + return reportingPluginAndInfo{}, err + } + + gasPriceEstimator, err := rf.config.commitStore.GasPriceEstimator(ctx) + if err != nil { + return reportingPluginAndInfo{}, err + } + + err = rf.config.priceService.UpdateDynamicConfig(ctx, gasPriceEstimator, rf.destPriceRegReader) + if err != nil { + return reportingPluginAndInfo{}, err + } + + lggr := rf.config.lggr.Named("CommitReportingPlugin") + plugin := &CommitReportingPlugin{ + sourceChainSelector: rf.config.sourceChainSelector, + sourceNative: rf.config.sourceNative, + onRampReader: rf.config.onRampReader, + destChainSelector: rf.config.destChainSelector, + commitStoreReader: rf.config.commitStore, + F: config.F, + lggr: lggr, + destPriceRegistryReader: rf.destPriceRegReader, + offRampReader: rf.config.offRamp, + gasPriceEstimator: gasPriceEstimator, + offchainConfig: pluginOffChainConfig, + metricsCollector: rf.config.metricsCollector, + chainHealthcheck: rf.config.chainHealthcheck, + priceService: rf.config.priceService, + } + + pluginInfo := types.ReportingPluginInfo{ + Name: "CCIPCommit", + UniqueReports: false, // See comment in CommitStore constructor. + Limits: types.ReportingPluginLimits{ + MaxQueryLength: ccip.MaxQueryLength, + MaxObservationLength: ccip.MaxObservationLength, + MaxReportLength: MaxCommitReportLength, + }, + } + + return reportingPluginAndInfo{plugin, pluginInfo}, nil + } +} diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/factory_test.go b/core/services/ocr2/plugins/ccip/ccipcommit/factory_test.go new file mode 100644 index 0000000000..825026bd17 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipcommit/factory_test.go @@ -0,0 +1,100 @@ +package ccipcommit + +import ( + "errors" + "testing" + "time" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + ccipdataprovidermocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" + dbMocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdb/mocks" +) + +// Assert that NewReportingPlugin keeps retrying until it succeeds. +// +// NewReportingPlugin makes several calls (e.g. CommitStoreReader.ChangeConfig) that can fail. We use mocks to cause the +// first call to each of these functions to fail, then all subsequent calls succeed. We assert that NewReportingPlugin +// retries a sufficient number of times to get through the transient errors and eventually succeed. +func TestNewReportingPluginRetriesUntilSuccess(t *testing.T) { + commitConfig := CommitPluginStaticConfig{} + + // For this unit test, ensure that there is no delay between retries + commitConfig.newReportingPluginRetryConfig = ccipdata.RetryConfig{ + InitialDelay: 0 * time.Nanosecond, + MaxDelay: 0 * time.Nanosecond, + } + + // Set up the OffRampReader mock + mockCommitStore := new(mocks.CommitStoreReader) + + // The first call is set to return an error, the following calls return a nil error + mockCommitStore. + On("ChangeConfig", mock.Anything, mock.Anything, mock.Anything). + Return(ccip.Address(""), errors.New("")). + Once() + mockCommitStore. + On("ChangeConfig", mock.Anything, mock.Anything, mock.Anything). + Return(ccip.Address("0x7c6e4F0BDe29f83BC394B75a7f313B7E5DbD2d77"), nil). + Times(5) + + mockCommitStore. + On("OffchainConfig", mock.Anything). + Return(ccip.CommitOffchainConfig{}, errors.New("")). + Once() + mockCommitStore. + On("OffchainConfig", mock.Anything). + Return(ccip.CommitOffchainConfig{}, nil). + Times(3) + + mockCommitStore. + On("GasPriceEstimator", mock.Anything). + Return(nil, errors.New("")). + Once() + mockCommitStore. + On("GasPriceEstimator", mock.Anything). + Return(nil, nil). + Times(2) + + commitConfig.commitStore = mockCommitStore + + mockPriceService := new(dbMocks.PriceService) + + mockPriceService. + On("UpdateDynamicConfig", mock.Anything, mock.Anything, mock.Anything). + Return(errors.New("")). + Once() + mockPriceService. + On("UpdateDynamicConfig", mock.Anything, mock.Anything, mock.Anything). + Return(nil) + + commitConfig.priceService = mockPriceService + + priceRegistryProvider := new(ccipdataprovidermocks.PriceRegistry) + priceRegistryProvider. + On("NewPriceRegistryReader", mock.Anything, mock.Anything). + Return(nil, errors.New("")). + Once() + priceRegistryProvider. + On("NewPriceRegistryReader", mock.Anything, mock.Anything). + Return(nil, nil). + Once() + commitConfig.priceRegistryProvider = priceRegistryProvider + + commitConfig.lggr, _ = logger.NewLogger() + + factory := NewCommitReportingPluginFactory(commitConfig) + reportingConfig := types.ReportingPluginConfig{} + reportingConfig.OnchainConfig = []byte{1, 2, 3} + reportingConfig.OffchainConfig = []byte{1, 2, 3} + + // Assert that NewReportingPlugin succeeds despite many transient internal failures (mocked out above) + _, _, err := factory.NewReportingPlugin(reportingConfig) + assert.Equal(t, nil, err) +} diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go b/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go new file mode 100644 index 0000000000..e964896ab9 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go @@ -0,0 +1,241 @@ +package ccipcommit + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "strings" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + + "github.com/Masterminds/semver/v3" + "github.com/ethereum/go-ethereum/common" + libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" + "go.uber.org/multierr" + + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + + commonlogger "github.com/smartcontractkit/chainlink-common/pkg/logger" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + + cciporm "github.com/smartcontractkit/chainlink/v2/core/services/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + db "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdb" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/observability" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/oraclelib" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/promwrapper" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" +) + +var defaultNewReportingPluginRetryConfig = ccipdata.RetryConfig{InitialDelay: time.Second, MaxDelay: 5 * time.Minute} + +func NewCommitServices(ctx context.Context, ds sqlutil.DataSource, srcProvider commontypes.CCIPCommitProvider, dstProvider commontypes.CCIPCommitProvider, chainSet legacyevm.LegacyChainContainer, jb job.Job, lggr logger.Logger, pr pipeline.Runner, argsNoPlugin libocr2.OCR2OracleArgs, new bool, sourceChainID int64, destChainID int64, logError func(string)) ([]job.ServiceCtx, error) { + spec := jb.OCR2OracleSpec + + var pluginConfig ccipconfig.CommitPluginJobSpecConfig + err := json.Unmarshal(spec.PluginConfig.Bytes(), &pluginConfig) + if err != nil { + return nil, err + } + + commitStoreAddress := common.HexToAddress(spec.ContractID) + + // commit store contract doesn't exist on the source chain, but we have an implementation of it + // to get access to a gas estimator on the source chain + srcCommitStore, err := srcProvider.NewCommitStoreReader(ctx, ccipcalc.EvmAddrToGeneric(commitStoreAddress)) + if err != nil { + return nil, err + } + + dstCommitStore, err := dstProvider.NewCommitStoreReader(ctx, ccipcalc.EvmAddrToGeneric(commitStoreAddress)) + if err != nil { + return nil, err + } + + var commitStoreReader ccipdata.CommitStoreReader + commitStoreReader = ccip.NewProviderProxyCommitStoreReader(srcCommitStore, dstCommitStore) + commitLggr := lggr.Named("CCIPCommit").With("sourceChain", sourceChainID, "destChain", destChainID) + + var priceGetter pricegetter.PriceGetter + withPipeline := strings.Trim(pluginConfig.TokenPricesUSDPipeline, "\n\t ") != "" + if withPipeline { + priceGetter, err = pricegetter.NewPipelineGetter(pluginConfig.TokenPricesUSDPipeline, pr, jb.ID, jb.ExternalJobID, jb.Name.ValueOrZero(), lggr) + if err != nil { + return nil, fmt.Errorf("creating pipeline price getter: %w", err) + } + } else { + // Use dynamic price getter. + if pluginConfig.PriceGetterConfig == nil { + return nil, fmt.Errorf("priceGetterConfig is nil") + } + + // Build price getter clients for all chains specified in the aggregator configurations. + // Some lanes (e.g. Wemix/Kroma) requires other clients than source and destination, since they use feeds from other chains. + priceGetterClients := map[uint64]pricegetter.DynamicPriceGetterClient{} + for _, aggCfg := range pluginConfig.PriceGetterConfig.AggregatorPrices { + chainID := aggCfg.ChainID + // Retrieve the chain. + chain, _, err2 := ccipconfig.GetChainByChainID(chainSet, chainID) + if err2 != nil { + return nil, fmt.Errorf("retrieving chain for chainID %d: %w", chainID, err2) + } + caller := rpclib.NewDynamicLimitedBatchCaller( + lggr, + chain.Client(), + rpclib.DefaultRpcBatchSizeLimit, + rpclib.DefaultRpcBatchBackOffMultiplier, + rpclib.DefaultMaxParallelRpcCalls, + ) + priceGetterClients[chainID] = pricegetter.NewDynamicPriceGetterClient(caller) + } + + priceGetter, err = pricegetter.NewDynamicPriceGetter(*pluginConfig.PriceGetterConfig, priceGetterClients) + if err != nil { + return nil, fmt.Errorf("creating dynamic price getter: %w", err) + } + } + + offRampReader, err := dstProvider.NewOffRampReader(ctx, pluginConfig.OffRamp) + if err != nil { + return nil, err + } + + staticConfig, err := commitStoreReader.GetCommitStoreStaticConfig(ctx) + if err != nil { + return nil, err + } + onRampAddress := staticConfig.OnRamp + + onRampReader, err := srcProvider.NewOnRampReader(ctx, onRampAddress, staticConfig.SourceChainSelector, staticConfig.ChainSelector) + if err != nil { + return nil, err + } + + onRampRouterAddr, err := onRampReader.RouterAddress(ctx) + if err != nil { + return nil, err + } + sourceNative, err := srcProvider.SourceNativeToken(ctx, onRampRouterAddr) + if err != nil { + return nil, err + } + // Prom wrappers + onRampReader = observability.NewObservedOnRampReader(onRampReader, sourceChainID, ccip.CommitPluginLabel) + commitStoreReader = observability.NewObservedCommitStoreReader(commitStoreReader, destChainID, ccip.CommitPluginLabel) + offRampReader = observability.NewObservedOffRampReader(offRampReader, destChainID, ccip.CommitPluginLabel) + metricsCollector := ccip.NewPluginMetricsCollector(ccip.CommitPluginLabel, sourceChainID, destChainID) + + chainHealthCheck := cache.NewObservedChainHealthCheck( + cache.NewChainHealthcheck( + // Adding more details to Logger to make healthcheck logs more informative + // It's safe because healthcheck logs only in case of unhealthy state + lggr.With( + "onramp", onRampAddress, + "commitStore", commitStoreAddress, + "offramp", pluginConfig.OffRamp, + ), + onRampReader, + commitStoreReader, + ), + ccip.CommitPluginLabel, + sourceChainID, // assuming this is the chain id? + destChainID, + onRampAddress, + ) + + orm, err := cciporm.NewORM(ds) + if err != nil { + return nil, err + } + + priceService := db.NewPriceService( + lggr, + orm, + jb.ID, + staticConfig.ChainSelector, + staticConfig.SourceChainSelector, + sourceNative, + priceGetter, + offRampReader, + ) + + wrappedPluginFactory := NewCommitReportingPluginFactory(CommitPluginStaticConfig{ + lggr: lggr, + newReportingPluginRetryConfig: defaultNewReportingPluginRetryConfig, + onRampReader: onRampReader, + sourceChainSelector: staticConfig.SourceChainSelector, + sourceNative: sourceNative, + offRamp: offRampReader, + commitStore: commitStoreReader, + destChainSelector: staticConfig.ChainSelector, + priceRegistryProvider: ccip.NewChainAgnosticPriceRegistry(dstProvider), + metricsCollector: metricsCollector, + chainHealthcheck: chainHealthCheck, + priceService: priceService, + }) + argsNoPlugin.ReportingPluginFactory = promwrapper.NewPromFactory(wrappedPluginFactory, "CCIPCommit", jb.OCR2OracleSpec.Relay, big.NewInt(0).SetInt64(destChainID)) + argsNoPlugin.Logger = commonlogger.NewOCRWrapper(commitLggr, true, logError) + oracle, err := libocr2.NewOracle(argsNoPlugin) + if err != nil { + return nil, err + } + // If this is a brand-new job, then we make use of the start blocks. If not then we're rebooting and log poller will pick up where we left off. + if new { + return []job.ServiceCtx{ + oraclelib.NewChainAgnosticBackFilledOracle( + lggr, + srcProvider, + dstProvider, + job.NewServiceAdapter(oracle), + ), + chainHealthCheck, + priceService, + }, nil + } + return []job.ServiceCtx{ + job.NewServiceAdapter(oracle), + chainHealthCheck, + priceService, + }, nil +} + +func CommitReportToEthTxMeta(typ ccipconfig.ContractType, ver semver.Version) (func(report []byte) (*txmgr.TxMeta, error), error) { + return factory.CommitReportToEthTxMeta(typ, ver) +} + +// UnregisterCommitPluginLpFilters unregisters all the registered filters for both source and dest chains. +// NOTE: The transaction MUST be used here for CLO's monster tx to function as expected +// https://github.com/smartcontractkit/ccip/blob/68e2197472fb017dd4e5630d21e7878d58bc2a44/core/services/feeds/service.go#L716 +// TODO once that transaction is broken up, we should be able to simply rely on oracle.Close() to cleanup the filters. +// Until then we have to deterministically reload the readers from the spec (and thus their filters) and close them. +func UnregisterCommitPluginLpFilters(srcProvider commontypes.CCIPCommitProvider, dstProvider commontypes.CCIPCommitProvider) error { + unregisterFuncs := []func() error{ + func() error { + return srcProvider.Close() + }, + func() error { + return dstProvider.Close() + }, + } + + var multiErr error + for _, fn := range unregisterFuncs { + if err := fn(); err != nil { + multiErr = multierr.Append(multiErr, err) + } + } + return multiErr +} diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/ocr2.go b/core/services/ocr2/plugins/ccip/ccipcommit/ocr2.go new file mode 100644 index 0000000000..2f0fc4e795 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipcommit/ocr2.go @@ -0,0 +1,753 @@ +package ccipcommit + +import ( + "context" + "encoding/hex" + "fmt" + "math/big" + "sort" + "time" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider" + db "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdb" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +const ( + // only dynamic field in CommitReport is tokens PriceUpdates, and we don't expect to need to update thousands of tokens in a single tx + MaxCommitReportLength = 10_000 + // Maximum inflight seq number range before we consider reports to be failing to get included entirely + // and restart from the chain's minSeqNum. Want to set it high to allow for large throughput, + // but low enough to minimize wasted revert cost. + MaxInflightSeqNumGap = 500 + // OnRampMessagesScanLimit is used to limit number of onramp messages scanned in each Observation. + // Single CommitRoot can contain up to merklemulti.MaxNumberTreeLeaves, so we scan twice that to be safe and still don't hurt DB performance. + OnRampMessagesScanLimit = merklemulti.MaxNumberTreeLeaves * 2 +) + +var ( + _ types.ReportingPluginFactory = &CommitReportingPluginFactory{} + _ types.ReportingPlugin = &CommitReportingPlugin{} +) + +type update struct { + timestamp time.Time + value *big.Int +} + +type CommitPluginStaticConfig struct { + lggr logger.Logger + newReportingPluginRetryConfig ccipdata.RetryConfig + // Source + onRampReader ccipdata.OnRampReader + sourceChainSelector uint64 + sourceNative cciptypes.Address + // Dest + offRamp ccipdata.OffRampReader + commitStore ccipdata.CommitStoreReader + destChainSelector uint64 + priceRegistryProvider ccipdataprovider.PriceRegistry + // Offchain + metricsCollector ccip.PluginMetricsCollector + chainHealthcheck cache.ChainHealthcheck + priceService db.PriceService +} + +type CommitReportingPlugin struct { + lggr logger.Logger + // Source + onRampReader ccipdata.OnRampReader + sourceChainSelector uint64 + sourceNative cciptypes.Address + gasPriceEstimator prices.GasPriceEstimatorCommit + // Dest + destChainSelector uint64 + commitStoreReader ccipdata.CommitStoreReader + destPriceRegistryReader ccipdata.PriceRegistryReader + offchainConfig cciptypes.CommitOffchainConfig + offRampReader ccipdata.OffRampReader + F int + // Offchain + metricsCollector ccip.PluginMetricsCollector + // State + chainHealthcheck cache.ChainHealthcheck + // DB + priceService db.PriceService +} + +// Query is not used by the CCIP Commit plugin. +func (r *CommitReportingPlugin) Query(context.Context, types.ReportTimestamp) (types.Query, error) { + return types.Query{}, nil +} + +// Observation calculates the sequence number interval ready to be committed and +// the token and gas price updates required. A valid report could contain a merkle +// root and price updates. Price updates should never contain nil values, otherwise +// the observation will be considered invalid and rejected. +func (r *CommitReportingPlugin) Observation(ctx context.Context, epochAndRound types.ReportTimestamp, _ types.Query) (types.Observation, error) { + lggr := r.lggr.Named("CommitObservation") + if healthy, err := r.chainHealthcheck.IsHealthy(ctx); err != nil { + return nil, err + } else if !healthy { + return nil, ccip.ErrChainIsNotHealthy + } + + // Will return 0,0 if no messages are found. This is a valid case as the report could + // still contain fee updates. + minSeqNr, maxSeqNr, messageIDs, err := r.calculateMinMaxSequenceNumbers(ctx, lggr) + if err != nil { + return nil, err + } + + // Fetches multi-lane gasPricesUSD and tokenPricesUSD for the same dest chain + gasPricesUSD, sourceGasPriceUSD, tokenPricesUSD, err := r.observePriceUpdates(ctx) + if err != nil { + return nil, err + } + + lggr.Infow("Observation", + "minSeqNr", minSeqNr, + "maxSeqNr", maxSeqNr, + "gasPricesUSD", gasPricesUSD, + "tokenPricesUSD", tokenPricesUSD, + "epochAndRound", epochAndRound, + "messageIDs", messageIDs, + ) + r.metricsCollector.NumberOfMessagesBasedOnInterval(ccip.Observation, minSeqNr, maxSeqNr) + + // Even if all values are empty we still want to communicate our observation + // with the other nodes, therefore, we always return the observed values. + return ccip.CommitObservation{ + Interval: cciptypes.CommitStoreInterval{ + Min: minSeqNr, + Max: maxSeqNr, + }, + TokenPricesUSD: tokenPricesUSD, + SourceGasPriceUSD: sourceGasPriceUSD, + SourceGasPriceUSDPerChain: gasPricesUSD, + }.Marshal() +} + +// observePriceUpdates fetches latest gas and token prices from DB as long as price reporting is not disabled. +// The prices are aggregated for all lanes for the same destination chain. +func (r *CommitReportingPlugin) observePriceUpdates( + ctx context.Context, +) (gasPricesUSD map[uint64]*big.Int, sourceGasPriceUSD *big.Int, tokenPricesUSD map[cciptypes.Address]*big.Int, err error) { + // Do not observe prices if price reporting is disabled. Price reporting will be disabled for lanes that are not leader lanes. + if r.offchainConfig.PriceReportingDisabled { + r.lggr.Infow("Price reporting disabled, skipping gas and token price reads") + return map[uint64]*big.Int{}, nil, map[cciptypes.Address]*big.Int{}, nil + } + + // Fetches multi-lane gas prices and token prices, for the given dest chain + gasPricesUSD, tokenPricesUSD, err = r.priceService.GetGasAndTokenPrices(ctx, r.destChainSelector) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to get prices from PriceService: %w", err) + } + + // Set prices to empty maps if nil to be friendlier to JSON encoding + if gasPricesUSD == nil { + gasPricesUSD = map[uint64]*big.Int{} + } + if tokenPricesUSD == nil { + tokenPricesUSD = map[cciptypes.Address]*big.Int{} + } + + // For backwards compatibility with the older release during phased rollout, set the default gas price on this lane + sourceGasPriceUSD = gasPricesUSD[r.sourceChainSelector] + + return gasPricesUSD, sourceGasPriceUSD, tokenPricesUSD, nil +} + +func (r *CommitReportingPlugin) calculateMinMaxSequenceNumbers(ctx context.Context, lggr logger.Logger) (uint64, uint64, []cciptypes.Hash, error) { + nextSeqNum, err := r.commitStoreReader.GetExpectedNextSequenceNumber(ctx) + if err != nil { + return 0, 0, []cciptypes.Hash{}, err + } + + msgRequests, err := r.onRampReader.GetSendRequestsBetweenSeqNums(ctx, nextSeqNum, nextSeqNum+OnRampMessagesScanLimit, true) + if err != nil { + return 0, 0, []cciptypes.Hash{}, err + } + if len(msgRequests) == 0 { + lggr.Infow("No new requests", "nextSeqNum", nextSeqNum) + return 0, 0, []cciptypes.Hash{}, nil + } + + messageIDs := make([]cciptypes.Hash, 0, len(msgRequests)) + seqNrs := make([]uint64, 0, len(msgRequests)) + for _, msgReq := range msgRequests { + seqNrs = append(seqNrs, msgReq.SequenceNumber) + messageIDs = append(messageIDs, msgReq.MessageID) + } + + minSeqNr := seqNrs[0] + maxSeqNr := seqNrs[len(seqNrs)-1] + if minSeqNr != nextSeqNum { + // Still report the observation as even partial reports have value e.g. all nodes are + // missing a single, different log each, they would still be able to produce a valid report. + lggr.Warnf("Missing sequence number range [%d-%d]", nextSeqNum, minSeqNr) + } + if !ccipcalc.ContiguousReqs(lggr, minSeqNr, maxSeqNr, seqNrs) { + return 0, 0, []cciptypes.Hash{}, errors.New("unexpected gap in seq nums") + } + return minSeqNr, maxSeqNr, messageIDs, nil +} + +// Gets the latest token price updates based on logs within the heartbeat +// The updates returned by this function are guaranteed to not contain nil values. +func (r *CommitReportingPlugin) getLatestTokenPriceUpdates(ctx context.Context, now time.Time) (map[cciptypes.Address]update, error) { + tokenPriceUpdates, err := r.destPriceRegistryReader.GetTokenPriceUpdatesCreatedAfter( + ctx, + now.Add(-r.offchainConfig.TokenPriceHeartBeat), + 0, + ) + if err != nil { + return nil, err + } + + latestUpdates := make(map[cciptypes.Address]update) + for _, tokenUpdate := range tokenPriceUpdates { + priceUpdate := tokenUpdate.TokenPriceUpdate + // Ordered by ascending timestamps + timestamp := time.Unix(priceUpdate.TimestampUnixSec.Int64(), 0) + if priceUpdate.Value != nil && !timestamp.Before(latestUpdates[priceUpdate.Token].timestamp) { + latestUpdates[priceUpdate.Token] = update{ + timestamp: timestamp, + value: priceUpdate.Value, + } + } + } + + return latestUpdates, nil +} + +// getLatestGasPriceUpdate returns the latest gas price updates based on logs within the heartbeat. +// If an update is found, it is not expected to contain a nil value. +func (r *CommitReportingPlugin) getLatestGasPriceUpdate(ctx context.Context, now time.Time) (map[uint64]update, error) { + gasPriceUpdates, err := r.destPriceRegistryReader.GetAllGasPriceUpdatesCreatedAfter( + ctx, + now.Add(-r.offchainConfig.GasPriceHeartBeat), + 0, + ) + + if err != nil { + return nil, err + } + + latestUpdates := make(map[uint64]update) + for _, gasUpdate := range gasPriceUpdates { + priceUpdate := gasUpdate.GasPriceUpdate + // Ordered by ascending timestamps + timestamp := time.Unix(priceUpdate.TimestampUnixSec.Int64(), 0) + if priceUpdate.Value != nil && !timestamp.Before(latestUpdates[priceUpdate.DestChainSelector].timestamp) { + latestUpdates[priceUpdate.DestChainSelector] = update{ + timestamp: timestamp, + value: priceUpdate.Value, + } + } + } + + r.lggr.Infow("Latest gas price from log poller", "latestUpdates", latestUpdates) + return latestUpdates, nil +} + +func (r *CommitReportingPlugin) Report(ctx context.Context, epochAndRound types.ReportTimestamp, _ types.Query, observations []types.AttributedObservation) (bool, types.Report, error) { + now := time.Now() + lggr := r.lggr.Named("CommitReport") + if healthy, err := r.chainHealthcheck.IsHealthy(ctx); err != nil { + return false, nil, err + } else if !healthy { + return false, nil, ccip.ErrChainIsNotHealthy + } + + parsableObservations := ccip.GetParsableObservations[ccip.CommitObservation](lggr, observations) + + intervals, gasPriceObs, tokenPriceObs, err := extractObservationData(lggr, r.F, r.sourceChainSelector, parsableObservations) + if err != nil { + return false, nil, err + } + + agreedInterval, err := calculateIntervalConsensus(intervals, r.F, merklemulti.MaxNumberTreeLeaves) + if err != nil { + return false, nil, err + } + + gasPrices, tokenPrices, err := r.selectPriceUpdates(ctx, now, gasPriceObs, tokenPriceObs) + if err != nil { + return false, nil, err + } + // If there are no fee updates and the interval is zero there is no report to produce. + if agreedInterval.Max == 0 && len(gasPrices) == 0 && len(tokenPrices) == 0 { + lggr.Infow("Empty report, skipping") + return false, nil, nil + } + + report, err := r.buildReport(ctx, lggr, agreedInterval, gasPrices, tokenPrices) + if err != nil { + return false, nil, err + } + encodedReport, err := r.commitStoreReader.EncodeCommitReport(ctx, report) + if err != nil { + return false, nil, err + } + r.metricsCollector.SequenceNumber(ccip.Report, report.Interval.Max) + r.metricsCollector.NumberOfMessagesBasedOnInterval(ccip.Report, report.Interval.Min, report.Interval.Max) + lggr.Infow("Report", + "merkleRoot", hex.EncodeToString(report.MerkleRoot[:]), + "minSeqNr", report.Interval.Min, + "maxSeqNr", report.Interval.Max, + "gasPriceUpdates", report.GasPrices, + "tokenPriceUpdates", report.TokenPrices, + "epochAndRound", epochAndRound, + ) + return true, encodedReport, nil +} + +// calculateIntervalConsensus compresses a set of intervals into one interval +// taking into account f which is the maximum number of faults across the whole DON. +// OCR itself won't call Report unless there are 2*f+1 observations +// https://github.com/smartcontractkit/libocr/blob/master/offchainreporting2/internal/protocol/report_generation_follower.go#L415 +// and f of those observations may be either unparseable or adversarially set values. That means +// we'll either have f+1 parsed honest values here, 2f+1 parsed values with f adversarial values or somewhere +// in between. +// rangeLimit is the maximum range of the interval. If the interval is larger than this, it will be truncated. Zero means no limit. +func calculateIntervalConsensus(intervals []cciptypes.CommitStoreInterval, f int, rangeLimit uint64) (cciptypes.CommitStoreInterval, error) { + // To understand min/max selection here, we need to consider an adversary that controls f values + // and is intentionally trying to stall the protocol or influence the value returned. For simplicity + // consider f=1 and n=4 nodes. In that case adversary may try to bias the min or max high/low. + // We could end up (2f+1=3) with sorted_mins=[1,1,1e9] or [-1e9,1,1] as examples. Selecting + // sorted_mins[f] ensures: + // - At least one honest node has seen this value, so adversary cannot bias the value lower which + // would cause reverts + // - If an honest oracle reports sorted_min[f] which happens to be stale i.e. that oracle + // has a delayed view of the chain, then the report will revert onchain but still succeed upon retry + // - We minimize the risk of naturally hitting the error condition minSeqNum > maxSeqNum due to oracles + // delayed views of the chain (would be an issue with taking sorted_mins[-f]) + sort.Slice(intervals, func(i, j int) bool { + return intervals[i].Min < intervals[j].Min + }) + minSeqNum := intervals[f].Min + + // The only way a report could have a minSeqNum of 0 is when there are no messages to report + // and the report is potentially still valid for gas fee updates. + if minSeqNum == 0 { + return cciptypes.CommitStoreInterval{Min: 0, Max: 0}, nil + } + // Consider a similar example to the sorted_mins one above except where they are maxes. + // We choose the more "conservative" sorted_maxes[f] so: + // - We are ensured that at least one honest oracle has seen the max, so adversary cannot set it lower and + // cause the maxSeqNum < minSeqNum errors + // - If an honest oracle reports sorted_max[f] which happens to be stale i.e. that oracle + // has a delayed view of the source chain, then we simply lose a little bit of throughput. + // - If we were to pick sorted_max[-f] i.e. the maximum honest node view (a more "aggressive" setting in terms of throughput), + // then an adversary can continually send high values e.g. imagine we have observations from all 4 nodes + // [honest 1, honest 1, honest 2, malicious 2], in this case we pick 2, but it's not enough to be able + // to build a report since the first 2 honest nodes are unaware of message 2. + sort.Slice(intervals, func(i, j int) bool { + return intervals[i].Max < intervals[j].Max + }) + maxSeqNum := intervals[f].Max + if maxSeqNum < minSeqNum { + // If the consensus report is invalid for onchain acceptance, we do not vote for it as + // an early termination step. + return cciptypes.CommitStoreInterval{}, errors.New("max seq num smaller than min") + } + + // If the range is too large, truncate it. + if rangeLimit > 0 && maxSeqNum-minSeqNum+1 > rangeLimit { + maxSeqNum = minSeqNum + rangeLimit - 1 + } + + return cciptypes.CommitStoreInterval{ + Min: minSeqNum, + Max: maxSeqNum, + }, nil +} + +// extractObservationData extracts observation fields into their own slices +// and filters out observation data that are invalid +func extractObservationData(lggr logger.Logger, f int, sourceChainSelector uint64, observations []ccip.CommitObservation) (intervals []cciptypes.CommitStoreInterval, gasPrices map[uint64][]*big.Int, tokenPrices map[cciptypes.Address][]*big.Int, err error) { + // We require at least f+1 observations to reach consensus. Checking to ensure there are at least f+1 parsed observations. + if len(observations) <= f { + return nil, nil, nil, fmt.Errorf("not enough observations to form consensus: #obs=%d, f=%d", len(observations), f) + } + + gasPriceObservations := make(map[uint64][]*big.Int) + tokenPriceObservations := make(map[cciptypes.Address][]*big.Int) + for _, obs := range observations { + intervals = append(intervals, obs.Interval) + + for selector, price := range obs.SourceGasPriceUSDPerChain { + if price != nil { + gasPriceObservations[selector] = append(gasPriceObservations[selector], price) + } + } + // During phased rollout, NOPs running old release only report SourceGasPriceUSD. + // An empty `SourceGasPriceUSDPerChain` with a non-nil `SourceGasPriceUSD` can only happen with old release. + if len(obs.SourceGasPriceUSDPerChain) == 0 && obs.SourceGasPriceUSD != nil { + gasPriceObservations[sourceChainSelector] = append(gasPriceObservations[sourceChainSelector], obs.SourceGasPriceUSD) + } + + for token, price := range obs.TokenPricesUSD { + if price != nil { + tokenPriceObservations[token] = append(tokenPriceObservations[token], price) + } + } + } + + // Price is dropped if there are not enough valid observations. With a threshold of 2*(f-1) + 1, we achieve a balance between safety and liveness. + // During phased-rollout where some honest nodes may not have started observing the token yet, it requires 5 malicious node with 1 being the leader to successfully alter price. + // During regular operation, it requires 3 malicious nodes with 1 being the leader to temporarily delay price update for the token. + priceReportingThreshold := 2*(f-1) + 1 + + gasPrices = make(map[uint64][]*big.Int) + for selector, perChainPriceObservations := range gasPriceObservations { + if len(perChainPriceObservations) < priceReportingThreshold { + lggr.Warnf("Skipping chain with selector %d due to not enough valid observations: #obs=%d, f=%d, threshold=%d", selector, len(perChainPriceObservations), f, priceReportingThreshold) + continue + } + gasPrices[selector] = perChainPriceObservations + } + + tokenPrices = make(map[cciptypes.Address][]*big.Int) + for token, perTokenPriceObservations := range tokenPriceObservations { + if len(perTokenPriceObservations) < priceReportingThreshold { + lggr.Warnf("Skipping token %s due to not enough valid observations: #obs=%d, f=%d, threshold=%d", string(token), len(perTokenPriceObservations), f, priceReportingThreshold) + continue + } + tokenPrices[token] = perTokenPriceObservations + } + + return intervals, gasPrices, tokenPrices, nil +} + +// selectPriceUpdates filters out gas and token price updates that are already inflight +func (r *CommitReportingPlugin) selectPriceUpdates(ctx context.Context, now time.Time, gasPriceObs map[uint64][]*big.Int, tokenPriceObs map[cciptypes.Address][]*big.Int) ([]cciptypes.GasPrice, []cciptypes.TokenPrice, error) { + // If price reporting is disabled, there is no need to select price updates. + if r.offchainConfig.PriceReportingDisabled { + return nil, nil, nil + } + + latestGasPrice, err := r.getLatestGasPriceUpdate(ctx, now) + if err != nil { + return nil, nil, err + } + + latestTokenPrices, err := r.getLatestTokenPriceUpdates(ctx, now) + if err != nil { + return nil, nil, err + } + + return r.calculatePriceUpdates(gasPriceObs, tokenPriceObs, latestGasPrice, latestTokenPrices) +} + +// Note priceUpdates must be deterministic. +// The provided gasPriceObs and tokenPriceObs should not contain nil values. +// The returned latestGasPrice and latestTokenPrices should not contain nil values. +func (r *CommitReportingPlugin) calculatePriceUpdates(gasPriceObs map[uint64][]*big.Int, tokenPriceObs map[cciptypes.Address][]*big.Int, latestGasPrice map[uint64]update, latestTokenPrices map[cciptypes.Address]update) ([]cciptypes.GasPrice, []cciptypes.TokenPrice, error) { + var tokenPriceUpdates []cciptypes.TokenPrice + for token, tokenPriceObservations := range tokenPriceObs { + medianPrice := ccipcalc.BigIntSortedMiddle(tokenPriceObservations) + + latestTokenPrice, exists := latestTokenPrices[token] + if exists { + tokenPriceUpdatedRecently := time.Since(latestTokenPrice.timestamp) < r.offchainConfig.TokenPriceHeartBeat + tokenPriceNotChanged := !ccipcalc.Deviates(medianPrice, latestTokenPrice.value, int64(r.offchainConfig.TokenPriceDeviationPPB)) + if tokenPriceUpdatedRecently && tokenPriceNotChanged { + r.lggr.Debugw("token price was updated recently, skipping the update", + "token", token, "newPrice", medianPrice, "existingPrice", latestTokenPrice.value) + continue // skip the update if we recently had a price update close to the new value + } + } + + tokenPriceUpdates = append(tokenPriceUpdates, cciptypes.TokenPrice{ + Token: token, + Value: medianPrice, + }) + } + + // Determinism required. + sort.Slice(tokenPriceUpdates, func(i, j int) bool { + return tokenPriceUpdates[i].Token < tokenPriceUpdates[j].Token + }) + + var gasPriceUpdate []cciptypes.GasPrice + for chainSelector, gasPriceObservations := range gasPriceObs { + newGasPrice, err := r.gasPriceEstimator.Median(gasPriceObservations) // Compute the median price + if err != nil { + return nil, nil, fmt.Errorf("failed to calculate median gas price for chain selector %d: %w", chainSelector, err) + } + + // Default to updating so that we update if there are no prior updates. + latestGasPrice, exists := latestGasPrice[chainSelector] + if exists && latestGasPrice.value != nil { + gasPriceUpdatedRecently := time.Since(latestGasPrice.timestamp) < r.offchainConfig.GasPriceHeartBeat + gasPriceDeviated, err := r.gasPriceEstimator.Deviates(newGasPrice, latestGasPrice.value) + if err != nil { + return nil, nil, err + } + if gasPriceUpdatedRecently && !gasPriceDeviated { + r.lggr.Debugw("gas price was updated recently and not deviated sufficiently, skipping the update", + "chainSelector", chainSelector, "newPrice", newGasPrice, "existingPrice", latestGasPrice.value) + continue + } + } + + gasPriceUpdate = append(gasPriceUpdate, cciptypes.GasPrice{ + DestChainSelector: chainSelector, + Value: newGasPrice, + }) + } + + sort.Slice(gasPriceUpdate, func(i, j int) bool { + return gasPriceUpdate[i].DestChainSelector < gasPriceUpdate[j].DestChainSelector + }) + + return gasPriceUpdate, tokenPriceUpdates, nil +} + +// buildReport assumes there is at least one message in reqs. +func (r *CommitReportingPlugin) buildReport(ctx context.Context, lggr logger.Logger, interval cciptypes.CommitStoreInterval, gasPrices []cciptypes.GasPrice, tokenPrices []cciptypes.TokenPrice) (cciptypes.CommitStoreReport, error) { + // If no messages are needed only include fee updates + if interval.Min == 0 { + return cciptypes.CommitStoreReport{ + TokenPrices: tokenPrices, + GasPrices: gasPrices, + MerkleRoot: [32]byte{}, + Interval: interval, + }, nil + } + + // Logs are guaranteed to be in order of seq num, since these are finalized logs only + // and the contract's seq num is auto-incrementing. + sendRequests, err := r.onRampReader.GetSendRequestsBetweenSeqNums(ctx, interval.Min, interval.Max, true) + if err != nil { + return cciptypes.CommitStoreReport{}, err + } + if len(sendRequests) == 0 { + lggr.Warn("No messages found in interval", + "minSeqNr", interval.Min, + "maxSeqNr", interval.Max) + return cciptypes.CommitStoreReport{}, fmt.Errorf("tried building a tree without leaves") + } + + leaves := make([][32]byte, 0, len(sendRequests)) + var seqNrs []uint64 + for _, req := range sendRequests { + leaves = append(leaves, req.Hash) + seqNrs = append(seqNrs, req.SequenceNumber) + } + if !ccipcalc.ContiguousReqs(lggr, interval.Min, interval.Max, seqNrs) { + return cciptypes.CommitStoreReport{}, errors.Errorf("do not have full range [%v, %v] have %v", interval.Min, interval.Max, seqNrs) + } + tree, err := merklemulti.NewTree(hashutil.NewKeccak(), leaves) + if err != nil { + return cciptypes.CommitStoreReport{}, err + } + + return cciptypes.CommitStoreReport{ + GasPrices: gasPrices, + TokenPrices: tokenPrices, + MerkleRoot: tree.Root(), + Interval: interval, + }, nil +} + +func (r *CommitReportingPlugin) ShouldAcceptFinalizedReport(ctx context.Context, reportTimestamp types.ReportTimestamp, report types.Report) (bool, error) { + parsedReport, err := r.commitStoreReader.DecodeCommitReport(ctx, report) + if err != nil { + return false, err + } + lggr := r.lggr.Named("CommitShouldAcceptFinalizedReport").With( + "merkleRoot", parsedReport.MerkleRoot, + "minSeqNum", parsedReport.Interval.Min, + "maxSeqNum", parsedReport.Interval.Max, + "gasPriceUpdates", parsedReport.GasPrices, + "tokenPriceUpdates", parsedReport.TokenPrices, + "reportTimestamp", reportTimestamp, + ) + // Empty report, should not be put on chain + if parsedReport.MerkleRoot == [32]byte{} && len(parsedReport.GasPrices) == 0 && len(parsedReport.TokenPrices) == 0 { + lggr.Warn("Empty report, should not be put on chain") + return false, nil + } + + if healthy, err1 := r.chainHealthcheck.IsHealthy(ctx); err1 != nil { + return false, err1 + } else if !healthy { + return false, ccip.ErrChainIsNotHealthy + } + + if r.isStaleReport(ctx, lggr, parsedReport, reportTimestamp) { + lggr.Infow("Rejecting stale report") + return false, nil + } + + r.metricsCollector.SequenceNumber(ccip.ShouldAccept, parsedReport.Interval.Max) + lggr.Infow("Accepting finalized report", "merkleRoot", hexutil.Encode(parsedReport.MerkleRoot[:])) + return true, nil +} + +// ShouldTransmitAcceptedReport checks if the report is stale, if it is it should not be transmitted. +func (r *CommitReportingPlugin) ShouldTransmitAcceptedReport(ctx context.Context, reportTimestamp types.ReportTimestamp, report types.Report) (bool, error) { + lggr := r.lggr.Named("CommitShouldTransmitAcceptedReport") + parsedReport, err := r.commitStoreReader.DecodeCommitReport(ctx, report) + if err != nil { + return false, err + } + if healthy, err1 := r.chainHealthcheck.IsHealthy(ctx); err1 != nil { + return false, err1 + } else if !healthy { + return false, ccip.ErrChainIsNotHealthy + } + // If report is not stale we transmit. + // When the commitTransmitter enqueues the tx for tx manager, + // we mark it as fulfilled, effectively removing it from the set of inflight messages. + shouldTransmit := !r.isStaleReport(ctx, lggr, parsedReport, reportTimestamp) + + lggr.Infow("ShouldTransmitAcceptedReport", + "shouldTransmit", shouldTransmit, + "reportTimestamp", reportTimestamp) + return shouldTransmit, nil +} + +// isStaleReport checks a report to see if the contents have become stale. +// It does so in four ways: +// 1. if there is a merkle root, check if the sequence numbers match up with onchain data +// 2. if there is no merkle root, check if current price's epoch and round is after onchain epoch and round +// 3. if there is a gas price update check to see if the value is different from the last +// reported value +// 4. if there are token prices check to see if the values are different from the last +// reported values. +// +// If there is a merkle root present, staleness is only measured based on the merkle root +// If there is no merkle root but there is a gas update, only this gas update is used for staleness checks. +// If only price updates are included, the price updates are used to check for staleness +// If nothing is included the report is always considered stale. +func (r *CommitReportingPlugin) isStaleReport(ctx context.Context, lggr logger.Logger, report cciptypes.CommitStoreReport, reportTimestamp types.ReportTimestamp) bool { + // If there is a merkle root, ignore all other staleness checks and only check for sequence number staleness + if report.MerkleRoot != [32]byte{} { + return r.isStaleMerkleRoot(ctx, lggr, report.Interval) + } + + hasGasPriceUpdate := len(report.GasPrices) > 0 + hasTokenPriceUpdates := len(report.TokenPrices) > 0 + + // If there is no merkle root, no gas price update and no token price update + // we don't want to write anything on-chain, so we consider this report stale. + if !hasGasPriceUpdate && !hasTokenPriceUpdates { + return true + } + + // We consider a price update as stale when, there isn't an update or there is an update that is stale. + gasPriceStale := !hasGasPriceUpdate || r.isStaleGasPrice(ctx, lggr, report.GasPrices) + tokenPricesStale := !hasTokenPriceUpdates || r.isStaleTokenPrices(ctx, lggr, report.TokenPrices) + + if gasPriceStale && tokenPricesStale { + return true + } + + // If report only has price update, check if its epoch and round lags behind the latest onchain + lastPriceEpochAndRound, err := r.commitStoreReader.GetLatestPriceEpochAndRound(ctx) + if err != nil { + // Assume it's a transient issue getting the last report and try again on the next round + return true + } + + thisEpochAndRound := ccipcalc.MergeEpochAndRound(reportTimestamp.Epoch, reportTimestamp.Round) + return lastPriceEpochAndRound >= thisEpochAndRound +} + +func (r *CommitReportingPlugin) isStaleMerkleRoot(ctx context.Context, lggr logger.Logger, reportInterval cciptypes.CommitStoreInterval) bool { + nextSeqNum, err := r.commitStoreReader.GetExpectedNextSequenceNumber(ctx) + if err != nil { + // Assume it's a transient issue getting the last report and try again on the next round + return true + } + + // The report is not stale and correct only if nextSeqNum == reportInterval.Min. + // Mark it stale if the condition isn't met. + if nextSeqNum != reportInterval.Min { + lggr.Infow("The report is stale because of sequence number mismatch with the commit store interval min value", + "nextSeqNum", nextSeqNum, "reportIntervalMin", reportInterval.Min) + return true + } + + lggr.Infow("Report root is not stale", "nextSeqNum", nextSeqNum, "reportIntervalMin", reportInterval.Min) + + // If a report has root and valid sequence number, the report should be submitted, regardless of price staleness + return false +} + +func (r *CommitReportingPlugin) isStaleGasPrice(ctx context.Context, lggr logger.Logger, gasPriceUpdates []cciptypes.GasPrice) bool { + latestGasPrice, err := r.getLatestGasPriceUpdate(ctx, time.Now()) + if err != nil { + lggr.Errorw("Gas price is stale because getLatestGasPriceUpdate failed", "err", err) + return true + } + + for _, gasPriceUpdate := range gasPriceUpdates { + latestUpdate, exists := latestGasPrice[gasPriceUpdate.DestChainSelector] + if !exists || latestUpdate.value == nil { + lggr.Infow("Found non-stale gas price", "chainSelector", gasPriceUpdate.DestChainSelector, "gasPriceUSd", gasPriceUpdate.Value) + return false + } + + gasPriceDeviated, err := r.gasPriceEstimator.Deviates(gasPriceUpdate.Value, latestUpdate.value) + if err != nil { + lggr.Errorw("Gas price is stale because deviation check failed", "err", err) + return true + } + + if gasPriceDeviated { + lggr.Infow("Found non-stale gas price", "chainSelector", gasPriceUpdate.DestChainSelector, "gasPriceUSd", gasPriceUpdate.Value, "latestUpdate", latestUpdate.value) + return false + } + lggr.Infow("Gas price is stale", "chainSelector", gasPriceUpdate.DestChainSelector, "gasPriceUSd", gasPriceUpdate.Value, "latestGasPrice", latestUpdate.value) + } + + lggr.Infow("All gas prices are stale") + return true +} + +func (r *CommitReportingPlugin) isStaleTokenPrices(ctx context.Context, lggr logger.Logger, priceUpdates []cciptypes.TokenPrice) bool { + // getting the last price updates without including inflight is like querying + // current prices onchain, but uses logpoller's data to save on the RPC requests + latestTokenPriceUpdates, err := r.getLatestTokenPriceUpdates(ctx, time.Now()) + if err != nil { + return true + } + + for _, tokenUpdate := range priceUpdates { + latestUpdate, ok := latestTokenPriceUpdates[tokenUpdate.Token] + priceEqual := ok && !ccipcalc.Deviates(tokenUpdate.Value, latestUpdate.value, int64(r.offchainConfig.TokenPriceDeviationPPB)) + + if !priceEqual { + lggr.Infow("Found non-stale token price", "token", tokenUpdate.Token, "usdPerToken", tokenUpdate.Value, "latestUpdate", latestUpdate.value) + return false + } + lggr.Infow("Token price is stale", "latestTokenPrice", latestUpdate.value, "usdPerToken", tokenUpdate.Value, "token", tokenUpdate.Token) + } + + lggr.Infow("All token prices are stale") + return true +} + +func (r *CommitReportingPlugin) Close() error { + return nil +} diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go b/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go new file mode 100644 index 0000000000..6cf7e4bec7 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go @@ -0,0 +1,1861 @@ +package ccipcommit + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "math/rand" + "slices" + "sort" + "testing" + "time" + + "github.com/Masterminds/semver/v3" + "github.com/leanovate/gopter" + "github.com/leanovate/gopter/gen" + "github.com/leanovate/gopter/prop" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" + mocks2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + ccipcachemocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" + ccipdatamocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + + ccipdbmocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdb/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +func TestCommitReportingPlugin_Observation(t *testing.T) { + sourceNativeTokenAddr := ccipcalc.HexToAddress("1000") + destChainSelector := uint64(1) + sourceChainSelector := uint64(2) + + bridgedTokens := []cciptypes.Address{ + ccipcalc.HexToAddress("2000"), + ccipcalc.HexToAddress("3000"), + } + + // Token price of 1e18 token amount in 1e18 USD precision + expectedTokenPrice := map[cciptypes.Address]*big.Int{ + bridgedTokens[0]: big.NewInt(1e10), + bridgedTokens[1]: big.NewInt(2e18), + } + + testCases := []struct { + name string + epochAndRound types.ReportTimestamp + commitStorePaused bool + sourceChainCursed bool + commitStoreSeqNum uint64 + gasPrices map[uint64]*big.Int + tokenPrices map[cciptypes.Address]*big.Int + sendReqs []cciptypes.EVM2EVMMessageWithTxMeta + priceReportingDisabled bool + + expErr bool + expObs ccip.CommitObservation + }{ + { + name: "base report", + commitStoreSeqNum: 54, + gasPrices: map[uint64]*big.Int{ + sourceChainSelector: big.NewInt(2e18), + }, + tokenPrices: expectedTokenPrice, + sendReqs: []cciptypes.EVM2EVMMessageWithTxMeta{ + {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 54}}, + {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 55}}, + }, + expObs: ccip.CommitObservation{ + TokenPricesUSD: expectedTokenPrice, + SourceGasPriceUSD: big.NewInt(2e18), + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + sourceChainSelector: big.NewInt(2e18), + }, + Interval: cciptypes.CommitStoreInterval{ + Min: 54, + Max: 55, + }, + }, + }, + { + name: "base report with multi-chain gas prices", + commitStoreSeqNum: 54, + gasPrices: map[uint64]*big.Int{ + sourceChainSelector + 1: big.NewInt(2e18), + sourceChainSelector + 2: big.NewInt(3e18), + }, + tokenPrices: expectedTokenPrice, + sendReqs: []cciptypes.EVM2EVMMessageWithTxMeta{ + {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 54}}, + {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 55}}, + }, + expObs: ccip.CommitObservation{ + TokenPricesUSD: expectedTokenPrice, + SourceGasPriceUSD: nil, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + sourceChainSelector + 1: big.NewInt(2e18), + sourceChainSelector + 2: big.NewInt(3e18), + }, + Interval: cciptypes.CommitStoreInterval{ + Min: 54, + Max: 55, + }, + }, + }, + { + name: "base report with price reporting disabled", + commitStoreSeqNum: 54, + gasPrices: map[uint64]*big.Int{ + sourceChainSelector: big.NewInt(2e18), + }, + tokenPrices: expectedTokenPrice, + sendReqs: []cciptypes.EVM2EVMMessageWithTxMeta{ + {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 54}}, + {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 55}}, + }, + priceReportingDisabled: true, + expObs: ccip.CommitObservation{ + TokenPricesUSD: map[cciptypes.Address]*big.Int{}, + SourceGasPriceUSD: nil, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{}, + Interval: cciptypes.CommitStoreInterval{ + Min: 54, + Max: 55, + }, + }, + }, + { + name: "commit store is down", + commitStorePaused: true, + sourceChainCursed: false, + expErr: true, + }, + { + name: "source chain is cursed", + commitStorePaused: false, + sourceChainCursed: true, + expErr: true, + }, + } + + ctx := testutils.Context(t) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + commitStoreReader := ccipdatamocks.NewCommitStoreReader(t) + commitStoreReader.On("IsDown", ctx).Return(tc.commitStorePaused, nil) + commitStoreReader.On("IsDestChainHealthy", ctx).Return(true, nil) + if !tc.commitStorePaused && !tc.sourceChainCursed { + commitStoreReader.On("GetExpectedNextSequenceNumber", ctx).Return(tc.commitStoreSeqNum, nil) + } + + onRampReader := ccipdatamocks.NewOnRampReader(t) + onRampReader.On("IsSourceChainHealthy", ctx).Return(true, nil) + onRampReader.On("IsSourceCursed", ctx).Return(tc.sourceChainCursed, nil) + if len(tc.sendReqs) > 0 { + onRampReader.On("GetSendRequestsBetweenSeqNums", ctx, tc.commitStoreSeqNum, tc.commitStoreSeqNum+OnRampMessagesScanLimit, true). + Return(tc.sendReqs, nil) + } + + mockPriceService := ccipdbmocks.NewPriceService(t) + mockPriceService.On("GetGasAndTokenPrices", ctx, destChainSelector).Return( + tc.gasPrices, + tc.tokenPrices, + nil, + ).Maybe() + + p := &CommitReportingPlugin{} + p.lggr = logger.TestLogger(t) + p.commitStoreReader = commitStoreReader + p.onRampReader = onRampReader + p.sourceNative = sourceNativeTokenAddr + p.metricsCollector = ccip.NoopMetricsCollector + p.chainHealthcheck = cache.NewChainHealthcheck(p.lggr, onRampReader, commitStoreReader) + p.priceService = mockPriceService + p.destChainSelector = destChainSelector + p.sourceChainSelector = sourceChainSelector + p.offchainConfig = cciptypes.CommitOffchainConfig{ + PriceReportingDisabled: tc.priceReportingDisabled, + } + + obs, err := p.Observation(ctx, tc.epochAndRound, types.Query{}) + + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + + if tc.expObs.TokenPricesUSD != nil { + // field ordering in mapping is not guaranteed, if TokenPricesUSD exists, unmarshal to compare mapping + var obsStuct ccip.CommitObservation + err = json.Unmarshal(obs, &obsStuct) + assert.NoError(t, err) + + assert.Equal(t, tc.expObs, obsStuct) + } else { + // if TokenPricesUSD is nil, compare the bytes directly, marshal then unmarshal turns nil map to empty + expObsBytes, err := tc.expObs.Marshal() + assert.NoError(t, err) + assert.Equal(t, expObsBytes, []byte(obs)) + } + }) + } +} + +func TestCommitReportingPlugin_Report(t *testing.T) { + ctx := testutils.Context(t) + sourceChainSelector := uint64(rand.Int()) + var gasPrice = big.NewInt(1) + var gasPrice2 = big.NewInt(2) + gasPriceHeartBeat := *config.MustNewDuration(time.Hour) + + t.Run("not enough observations", func(t *testing.T) { + p := &CommitReportingPlugin{} + p.lggr = logger.TestLogger(t) + p.F = 1 + + chainHealthcheck := ccipcachemocks.NewChainHealthcheck(t) + chainHealthcheck.On("IsHealthy", ctx).Return(true, nil).Maybe() + p.chainHealthcheck = chainHealthcheck + + o := ccip.CommitObservation{Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, SourceGasPriceUSD: big.NewInt(0)} + obs, err := o.Marshal() + assert.NoError(t, err) + + aos := []types.AttributedObservation{{Observation: obs}} + + gotSomeReport, gotReport, err := p.Report(ctx, types.ReportTimestamp{}, types.Query{}, aos) + assert.False(t, gotSomeReport) + assert.Nil(t, gotReport) + assert.Error(t, err) + }) + + testCases := []struct { + name string + observations []ccip.CommitObservation + f int + gasPriceUpdates []cciptypes.GasPriceUpdateWithTxMeta + tokenDecimals map[cciptypes.Address]uint8 + tokenPriceUpdates []cciptypes.TokenPriceUpdateWithTxMeta + sendRequests []cciptypes.EVM2EVMMessageWithTxMeta + expCommitReport *cciptypes.CommitStoreReport + expSeqNumRange cciptypes.CommitStoreInterval + expErr bool + }{ + { + name: "base", + observations: []ccip.CommitObservation{ + {Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, SourceGasPriceUSDPerChain: map[uint64]*big.Int{sourceChainSelector: gasPrice}}, + {Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, SourceGasPriceUSDPerChain: map[uint64]*big.Int{sourceChainSelector: gasPrice}}, + }, + f: 1, + sendRequests: []cciptypes.EVM2EVMMessageWithTxMeta{ + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 1, + }, + }, + }, + gasPriceUpdates: []cciptypes.GasPriceUpdateWithTxMeta{ + { + GasPriceUpdate: cciptypes.GasPriceUpdate{ + GasPrice: cciptypes.GasPrice{ + DestChainSelector: sourceChainSelector, + Value: big.NewInt(1), + }, + TimestampUnixSec: big.NewInt(time.Now().Add(-2 * gasPriceHeartBeat.Duration()).Unix()), + }, + }, + }, + expSeqNumRange: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, + expCommitReport: &cciptypes.CommitStoreReport{ + MerkleRoot: [32]byte{}, + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, + TokenPrices: nil, + GasPrices: []cciptypes.GasPrice{{DestChainSelector: sourceChainSelector, Value: gasPrice}}, + }, + expErr: false, + }, + { + name: "observations with mix gas price formats", + observations: []ccip.CommitObservation{ + { + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + sourceChainSelector: gasPrice, + sourceChainSelector + 1: gasPrice2, + sourceChainSelector + 2: gasPrice2, + }, + }, + { + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + sourceChainSelector: gasPrice, + sourceChainSelector + 1: gasPrice2, + sourceChainSelector + 2: gasPrice2, + }, + }, + { + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + sourceChainSelector: gasPrice, + sourceChainSelector + 1: gasPrice2, + }, + }, + { + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, + SourceGasPriceUSD: gasPrice, + }, + }, + f: 2, + sendRequests: []cciptypes.EVM2EVMMessageWithTxMeta{ + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 1, + }, + }, + }, + gasPriceUpdates: []cciptypes.GasPriceUpdateWithTxMeta{ + { + GasPriceUpdate: cciptypes.GasPriceUpdate{ + GasPrice: cciptypes.GasPrice{ + DestChainSelector: sourceChainSelector, + Value: big.NewInt(1), + }, + TimestampUnixSec: big.NewInt(time.Now().Add(-2 * gasPriceHeartBeat.Duration()).Unix()), + }, + }, + }, + expSeqNumRange: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, + expCommitReport: &cciptypes.CommitStoreReport{ + MerkleRoot: [32]byte{}, + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, + TokenPrices: nil, + GasPrices: []cciptypes.GasPrice{ + {DestChainSelector: sourceChainSelector, Value: gasPrice}, + {DestChainSelector: sourceChainSelector + 1, Value: gasPrice2}, + }, + }, + expErr: false, + }, + { + name: "empty", + observations: []ccip.CommitObservation{ + {Interval: cciptypes.CommitStoreInterval{Min: 0, Max: 0}, SourceGasPriceUSD: big.NewInt(0)}, + {Interval: cciptypes.CommitStoreInterval{Min: 0, Max: 0}, SourceGasPriceUSD: big.NewInt(0)}, + }, + gasPriceUpdates: []cciptypes.GasPriceUpdateWithTxMeta{ + { + GasPriceUpdate: cciptypes.GasPriceUpdate{ + GasPrice: cciptypes.GasPrice{ + DestChainSelector: sourceChainSelector, + Value: big.NewInt(0), + }, + TimestampUnixSec: big.NewInt(time.Now().Add(-gasPriceHeartBeat.Duration() / 2).Unix()), + }, + }, + }, + f: 1, + expErr: false, + }, + { + name: "no leaves", + observations: []ccip.CommitObservation{ + {Interval: cciptypes.CommitStoreInterval{Min: 2, Max: 2}, SourceGasPriceUSD: big.NewInt(0)}, + {Interval: cciptypes.CommitStoreInterval{Min: 2, Max: 2}, SourceGasPriceUSD: big.NewInt(0)}, + }, + f: 1, + sendRequests: []cciptypes.EVM2EVMMessageWithTxMeta{{}}, + expSeqNumRange: cciptypes.CommitStoreInterval{Min: 2, Max: 2}, + expErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + destPriceRegistryReader := ccipdatamocks.NewPriceRegistryReader(t) + destPriceRegistryReader.On("GetAllGasPriceUpdatesCreatedAfter", ctx, mock.Anything, 0).Return(tc.gasPriceUpdates, nil) + destPriceRegistryReader.On("GetTokenPriceUpdatesCreatedAfter", ctx, mock.Anything, 0).Return(tc.tokenPriceUpdates, nil) + + onRampReader := ccipdatamocks.NewOnRampReader(t) + if len(tc.sendRequests) > 0 { + onRampReader.On("GetSendRequestsBetweenSeqNums", ctx, tc.expSeqNumRange.Min, tc.expSeqNumRange.Max, true).Return(tc.sendRequests, nil) + } + + evmEstimator := mocks.NewEvmFeeEstimator(t) + evmEstimator.On("L1Oracle").Return(nil) + gasPriceEstimator := prices.NewDAGasPriceEstimator(evmEstimator, nil, 2e9, 2e9) // 200% deviation + + var destTokens []cciptypes.Address + for tk := range tc.tokenDecimals { + destTokens = append(destTokens, tk) + } + sort.Slice(destTokens, func(i, j int) bool { + return destTokens[i] < destTokens[j] + }) + var destDecimals []uint8 + for _, token := range destTokens { + destDecimals = append(destDecimals, tc.tokenDecimals[token]) + } + + destPriceRegistryReader.On("GetTokensDecimals", ctx, mock.MatchedBy(func(tokens []cciptypes.Address) bool { + for _, token := range tokens { + if !slices.Contains(destTokens, token) { + return false + } + } + return true + })).Return(destDecimals, nil).Maybe() + + lp := mocks2.NewLogPoller(t) + commitStoreReader, err := v1_2_0.NewCommitStore(logger.TestLogger(t), utils.RandomAddress(), nil, lp) + assert.NoError(t, err) + + healthCheck := ccipcachemocks.NewChainHealthcheck(t) + healthCheck.On("IsHealthy", ctx).Return(true, nil) + + p := &CommitReportingPlugin{} + p.lggr = logger.TestLogger(t) + p.destPriceRegistryReader = destPriceRegistryReader + p.onRampReader = onRampReader + p.sourceChainSelector = sourceChainSelector + p.gasPriceEstimator = gasPriceEstimator + p.offchainConfig.GasPriceHeartBeat = gasPriceHeartBeat.Duration() + p.commitStoreReader = commitStoreReader + p.F = tc.f + p.metricsCollector = ccip.NoopMetricsCollector + p.chainHealthcheck = healthCheck + + aos := make([]types.AttributedObservation, 0, len(tc.observations)) + for _, o := range tc.observations { + obs, err2 := o.Marshal() + assert.NoError(t, err2) + aos = append(aos, types.AttributedObservation{Observation: obs}) + } + + gotSomeReport, gotReport, err := p.Report(ctx, types.ReportTimestamp{}, types.Query{}, aos) + if tc.expErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + + if tc.expCommitReport != nil { + assert.True(t, gotSomeReport) + encodedExpectedReport, err := encodeCommitReport(*tc.expCommitReport) + assert.NoError(t, err) + assert.Equal(t, types.Report(encodedExpectedReport), gotReport) + } + }) + } +} + +func TestCommitReportingPlugin_ShouldAcceptFinalizedReport(t *testing.T) { + ctx := testutils.Context(t) + + newPlugin := func() *CommitReportingPlugin { + p := &CommitReportingPlugin{} + p.lggr = logger.TestLogger(t) + p.metricsCollector = ccip.NoopMetricsCollector + return p + } + + t.Run("report cannot be decoded leads to error", func(t *testing.T) { + p := newPlugin() + + encodedReport := []byte("whatever") + + commitStoreReader := ccipdatamocks.NewCommitStoreReader(t) + p.commitStoreReader = commitStoreReader + commitStoreReader.On("DecodeCommitReport", mock.Anything, encodedReport). + Return(cciptypes.CommitStoreReport{}, errors.New("unable to decode report")) + + _, err := p.ShouldAcceptFinalizedReport(ctx, types.ReportTimestamp{}, encodedReport) + assert.Error(t, err) + }) + + t.Run("empty report should not be accepted", func(t *testing.T) { + p := newPlugin() + + report := cciptypes.CommitStoreReport{} + + commitStoreReader := ccipdatamocks.NewCommitStoreReader(t) + p.commitStoreReader = commitStoreReader + commitStoreReader.On("DecodeCommitReport", mock.Anything, mock.Anything).Return(report, nil) + + chainHealthCheck := ccipcachemocks.NewChainHealthcheck(t) + chainHealthCheck.On("IsHealthy", ctx).Return(true, nil).Maybe() + p.chainHealthcheck = chainHealthCheck + + encodedReport, err := encodeCommitReport(report) + assert.NoError(t, err) + shouldAccept, err := p.ShouldAcceptFinalizedReport(ctx, types.ReportTimestamp{}, encodedReport) + assert.NoError(t, err) + assert.False(t, shouldAccept) + }) + + t.Run("stale report should not be accepted", func(t *testing.T) { + onChainSeqNum := uint64(100) + + commitStoreReader := ccipdatamocks.NewCommitStoreReader(t) + p := newPlugin() + + p.commitStoreReader = commitStoreReader + + report := cciptypes.CommitStoreReport{ + GasPrices: []cciptypes.GasPrice{{Value: big.NewInt(int64(rand.Int()))}}, + MerkleRoot: [32]byte{123}, // this report is considered non-empty since it has a merkle root + } + + commitStoreReader.On("DecodeCommitReport", mock.Anything, mock.Anything).Return(report, nil) + commitStoreReader.On("GetExpectedNextSequenceNumber", mock.Anything).Return(onChainSeqNum, nil) + + chainHealthCheck := ccipcachemocks.NewChainHealthcheck(t) + chainHealthCheck.On("IsHealthy", ctx).Return(true, nil) + p.chainHealthcheck = chainHealthCheck + + // stale since report interval is behind on chain seq num + report.Interval = cciptypes.CommitStoreInterval{Min: onChainSeqNum - 2, Max: onChainSeqNum + 10} + encodedReport, err := encodeCommitReport(report) + assert.NoError(t, err) + + shouldAccept, err := p.ShouldAcceptFinalizedReport(ctx, types.ReportTimestamp{}, encodedReport) + assert.NoError(t, err) + assert.False(t, shouldAccept) + }) + + t.Run("non-stale report should be accepted", func(t *testing.T) { + onChainSeqNum := uint64(100) + + p := newPlugin() + + priceRegistryReader := ccipdatamocks.NewPriceRegistryReader(t) + p.destPriceRegistryReader = priceRegistryReader + + p.lggr = logger.TestLogger(t) + commitStoreReader := ccipdatamocks.NewCommitStoreReader(t) + p.commitStoreReader = commitStoreReader + + report := cciptypes.CommitStoreReport{ + Interval: cciptypes.CommitStoreInterval{ + Min: onChainSeqNum, + Max: onChainSeqNum + 10, + }, + TokenPrices: []cciptypes.TokenPrice{ + { + Token: cciptypes.Address(utils.RandomAddress().String()), + Value: big.NewInt(int64(rand.Int())), + }, + }, + GasPrices: []cciptypes.GasPrice{ + { + DestChainSelector: rand.Uint64(), + Value: big.NewInt(int64(rand.Int())), + }, + }, + MerkleRoot: [32]byte{123}, + } + commitStoreReader.On("DecodeCommitReport", mock.Anything, mock.Anything).Return(report, nil) + commitStoreReader.On("GetExpectedNextSequenceNumber", mock.Anything).Return(onChainSeqNum, nil) + + // non-stale since report interval is not behind on-chain seq num + report.Interval = cciptypes.CommitStoreInterval{Min: onChainSeqNum, Max: onChainSeqNum + 10} + encodedReport, err := encodeCommitReport(report) + assert.NoError(t, err) + + chainHealthCheck := ccipcachemocks.NewChainHealthcheck(t) + chainHealthCheck.On("IsHealthy", ctx).Return(true, nil) + p.chainHealthcheck = chainHealthCheck + + shouldAccept, err := p.ShouldAcceptFinalizedReport(ctx, types.ReportTimestamp{}, encodedReport) + assert.NoError(t, err) + assert.True(t, shouldAccept) + }) +} + +func TestCommitReportingPlugin_ShouldTransmitAcceptedReport(t *testing.T) { + report := cciptypes.CommitStoreReport{ + TokenPrices: []cciptypes.TokenPrice{ + {Token: cciptypes.Address(utils.RandomAddress().String()), Value: big.NewInt(9e18)}, + }, + GasPrices: []cciptypes.GasPrice{ + { + + DestChainSelector: rand.Uint64(), + Value: big.NewInt(2000e9), + }, + }, + MerkleRoot: [32]byte{123}, + } + + ctx := testutils.Context(t) + p := &CommitReportingPlugin{} + commitStoreReader := ccipdatamocks.NewCommitStoreReader(t) + onChainSeqNum := uint64(100) + commitStoreReader.On("GetExpectedNextSequenceNumber", mock.Anything).Return(onChainSeqNum, nil) + p.commitStoreReader = commitStoreReader + p.lggr = logger.TestLogger(t) + + chainHealthCheck := ccipcachemocks.NewChainHealthcheck(t) + chainHealthCheck.On("IsHealthy", ctx).Return(true, nil).Maybe() + p.chainHealthcheck = chainHealthCheck + + t.Run("should transmit when report is not stale", func(t *testing.T) { + // not-stale since report interval is not behind on chain seq num + report.Interval = cciptypes.CommitStoreInterval{Min: onChainSeqNum, Max: onChainSeqNum + 10} + encodedReport, err := encodeCommitReport(report) + assert.NoError(t, err) + commitStoreReader.On("DecodeCommitReport", mock.Anything, encodedReport).Return(report, nil).Once() + shouldTransmit, err := p.ShouldTransmitAcceptedReport(ctx, types.ReportTimestamp{}, encodedReport) + assert.NoError(t, err) + assert.True(t, shouldTransmit) + }) + + t.Run("should not transmit when report is stale", func(t *testing.T) { + // stale since report interval is behind on chain seq num + report.Interval = cciptypes.CommitStoreInterval{Min: onChainSeqNum - 2, Max: onChainSeqNum + 10} + encodedReport, err := encodeCommitReport(report) + assert.NoError(t, err) + commitStoreReader.On("DecodeCommitReport", mock.Anything, encodedReport).Return(report, nil).Once() + shouldTransmit, err := p.ShouldTransmitAcceptedReport(ctx, types.ReportTimestamp{}, encodedReport) + assert.NoError(t, err) + assert.False(t, shouldTransmit) + }) + + t.Run("error when report cannot be decoded", func(t *testing.T) { + reportBytes := []byte("whatever") + commitStoreReader.On("DecodeCommitReport", mock.Anything, reportBytes). + Return(cciptypes.CommitStoreReport{}, errors.New("decode error")).Once() + _, err := p.ShouldTransmitAcceptedReport(ctx, types.ReportTimestamp{}, reportBytes) + assert.Error(t, err) + }) +} + +func TestCommitReportingPlugin_observePriceUpdates(t *testing.T) { + destChainSelector := uint64(12345) + sourceChainSelector := uint64(67890) + + token1 := ccipcalc.HexToAddress("0x123") + token2 := ccipcalc.HexToAddress("0x234") + + gasPrices := map[uint64]*big.Int{ + sourceChainSelector: big.NewInt(1e18), + } + tokenPrices := map[cciptypes.Address]*big.Int{ + token1: big.NewInt(2e18), + token2: big.NewInt(3e18), + } + + testCases := []struct { + name string + psGasPricesResult map[uint64]*big.Int + psTokenPricesResult map[cciptypes.Address]*big.Int + PriceReportingDisabled bool + + expectedGasPrice map[uint64]*big.Int + expectedTokenPrices map[cciptypes.Address]*big.Int + + psError bool + expectedErr bool + }{ + { + name: "ORM called successfully", + psGasPricesResult: gasPrices, + psTokenPricesResult: tokenPrices, + expectedGasPrice: gasPrices, + expectedTokenPrices: tokenPrices, + }, + { + name: "price reporting disabled", + psGasPricesResult: gasPrices, + psTokenPricesResult: tokenPrices, + PriceReportingDisabled: true, + expectedGasPrice: map[uint64]*big.Int{}, + expectedTokenPrices: map[cciptypes.Address]*big.Int{}, + psError: false, + expectedErr: false, + }, + { + name: "price service error", + psGasPricesResult: map[uint64]*big.Int{}, + psTokenPricesResult: map[cciptypes.Address]*big.Int{}, + expectedGasPrice: nil, + expectedTokenPrices: nil, + psError: true, + expectedErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctx := tests.Context(t) + + mockPriceService := ccipdbmocks.NewPriceService(t) + var psError error + if tc.psError { + psError = fmt.Errorf("price service error") + } + mockPriceService.On("GetGasAndTokenPrices", ctx, destChainSelector).Return( + tc.psGasPricesResult, + tc.psTokenPricesResult, + psError, + ).Maybe() + + p := &CommitReportingPlugin{ + lggr: logger.TestLogger(t), + destChainSelector: destChainSelector, + sourceChainSelector: sourceChainSelector, + priceService: mockPriceService, + offchainConfig: cciptypes.CommitOffchainConfig{ + PriceReportingDisabled: tc.PriceReportingDisabled, + }, + } + gasPricesUSD, sourceGasPriceUSD, tokenPricesUSD, err := p.observePriceUpdates(ctx) + if tc.expectedErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tc.expectedGasPrice, gasPricesUSD) + assert.Equal(t, tc.expectedTokenPrices, tokenPricesUSD) + if tc.expectedGasPrice != nil { + assert.Equal(t, tc.expectedGasPrice[sourceChainSelector], sourceGasPriceUSD) + } + } + }) + } +} + +type CommitObservationLegacy struct { + Interval cciptypes.CommitStoreInterval `json:"interval"` + TokenPricesUSD map[cciptypes.Address]*big.Int `json:"tokensPerFeeCoin"` + SourceGasPriceUSD *big.Int `json:"sourceGasPrice"` +} + +func TestCommitReportingPlugin_extractObservationData(t *testing.T) { + token1 := ccipcalc.HexToAddress("0xa") + token2 := ccipcalc.HexToAddress("0xb") + token1Price := big.NewInt(1) + token2Price := big.NewInt(2) + unsupportedToken := ccipcalc.HexToAddress("0xc") + gasPrice1 := big.NewInt(100) + gasPrice2 := big.NewInt(100) + var sourceChainSelector1 uint64 = 10 + var sourceChainSelector2 uint64 = 20 + + tokenDecimals := make(map[cciptypes.Address]uint8) + tokenDecimals[token1] = 18 + tokenDecimals[token2] = 18 + + validInterval := cciptypes.CommitStoreInterval{Min: 1, Max: 2} + zeroInterval := cciptypes.CommitStoreInterval{Min: 0, Max: 0} + + // mix legacy commit observations with new commit observations to ensure they can work together + legacyObsRaw := CommitObservationLegacy{ + Interval: validInterval, + TokenPricesUSD: map[cciptypes.Address]*big.Int{ + token1: token1Price, + token2: token2Price, + }, + SourceGasPriceUSD: gasPrice1, + } + legacyObsBytes, err := json.Marshal(&legacyObsRaw) + assert.NoError(t, err) + + newObsRaw := ccip.CommitObservation{ + Interval: validInterval, + TokenPricesUSD: map[cciptypes.Address]*big.Int{ + token1: token1Price, + token2: token2Price, + }, + SourceGasPriceUSD: gasPrice1, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + sourceChainSelector1: gasPrice1, + sourceChainSelector2: gasPrice2, + }, + } + newObsBytes, err := newObsRaw.Marshal() + assert.NoError(t, err) + + lggr := logger.TestLogger(t) + observations := ccip.GetParsableObservations[ccip.CommitObservation](lggr, []types.AttributedObservation{ + {Observation: legacyObsBytes}, + {Observation: newObsBytes}, + }) + assert.Len(t, observations, 2) + legacyObs := observations[0] + newObs := observations[1] + + obWithNilGasPrice := ccip.CommitObservation{ + Interval: zeroInterval, + TokenPricesUSD: map[cciptypes.Address]*big.Int{ + token1: token1Price, + token2: token2Price, + }, + SourceGasPriceUSD: nil, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{}, + } + obWithNilTokenPrice := ccip.CommitObservation{ + Interval: zeroInterval, + TokenPricesUSD: map[cciptypes.Address]*big.Int{ + token1: token1Price, + token2: nil, + }, + SourceGasPriceUSD: gasPrice1, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + sourceChainSelector1: gasPrice1, + sourceChainSelector2: gasPrice2, + }, + } + obMissingTokenPrices := ccip.CommitObservation{ + Interval: zeroInterval, + TokenPricesUSD: map[cciptypes.Address]*big.Int{}, + SourceGasPriceUSD: gasPrice1, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + sourceChainSelector1: gasPrice1, + sourceChainSelector2: gasPrice2, + }, + } + obWithUnsupportedToken := ccip.CommitObservation{ + Interval: zeroInterval, + TokenPricesUSD: map[cciptypes.Address]*big.Int{ + token1: token1Price, + token2: token2Price, + unsupportedToken: token2Price, + }, + SourceGasPriceUSD: gasPrice1, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + sourceChainSelector1: gasPrice1, + sourceChainSelector2: gasPrice2, + }, + } + obEmpty := ccip.CommitObservation{ + Interval: zeroInterval, + TokenPricesUSD: nil, + SourceGasPriceUSD: nil, + SourceGasPriceUSDPerChain: nil, + } + + testCases := []struct { + name string + commitObservations []ccip.CommitObservation + f int + expIntervals []cciptypes.CommitStoreInterval + expGasPriceObs map[uint64][]*big.Int + expTokenPriceObs map[cciptypes.Address][]*big.Int + expError bool + }{ + { + name: "base", + commitObservations: []ccip.CommitObservation{newObs, newObs, newObs}, + f: 2, + expIntervals: []cciptypes.CommitStoreInterval{validInterval, validInterval, validInterval}, + expGasPriceObs: map[uint64][]*big.Int{ + sourceChainSelector1: {gasPrice1, gasPrice1, gasPrice1}, + sourceChainSelector2: {gasPrice2, gasPrice2, gasPrice2}, + }, + expTokenPriceObs: map[cciptypes.Address][]*big.Int{ + token1: {token1Price, token1Price, token1Price}, + token2: {token2Price, token2Price, token2Price}, + }, + expError: false, + }, + { + name: "pass with f=2 and mixed observations", + commitObservations: []ccip.CommitObservation{legacyObs, newObs, legacyObs, newObs, newObs, obWithNilGasPrice}, + f: 2, + expIntervals: []cciptypes.CommitStoreInterval{validInterval, validInterval, validInterval, validInterval, validInterval, zeroInterval}, + expGasPriceObs: map[uint64][]*big.Int{ + sourceChainSelector1: {gasPrice1, gasPrice1, gasPrice1, gasPrice1, gasPrice1}, + sourceChainSelector2: {gasPrice2, gasPrice2, gasPrice2}, + }, + expTokenPriceObs: map[cciptypes.Address][]*big.Int{ + token1: {token1Price, token1Price, token1Price, token1Price, token1Price, token1Price}, + token2: {token2Price, token2Price, token2Price, token2Price, token2Price, token2Price}, + }, + expError: false, + }, + { + name: "pass with f=2 and mixed observations with mostly legacy observations", + commitObservations: []ccip.CommitObservation{legacyObs, legacyObs, legacyObs, legacyObs, newObs}, + f: 2, + expIntervals: []cciptypes.CommitStoreInterval{validInterval, validInterval, validInterval, validInterval, validInterval}, + expGasPriceObs: map[uint64][]*big.Int{ + sourceChainSelector1: {gasPrice1, gasPrice1, gasPrice1, gasPrice1, gasPrice1}, + }, + expTokenPriceObs: map[cciptypes.Address][]*big.Int{ + token1: {token1Price, token1Price, token1Price, token1Price, token1Price}, + token2: {token2Price, token2Price, token2Price, token2Price, token2Price}, + }, + expError: false, + }, + { + name: "tolerate 1 faulty obs with f=2", + commitObservations: []ccip.CommitObservation{legacyObs, newObs, legacyObs, obWithNilGasPrice}, + f: 2, + expIntervals: []cciptypes.CommitStoreInterval{validInterval, validInterval, validInterval, zeroInterval}, + expGasPriceObs: map[uint64][]*big.Int{ + sourceChainSelector1: {gasPrice1, gasPrice1, gasPrice1}, + }, + expTokenPriceObs: map[cciptypes.Address][]*big.Int{ + token1: {token1Price, token1Price, token1Price, token1Price}, + token2: {token2Price, token2Price, token2Price, token2Price}, + }, + expError: false, + }, + { + name: "tolerate 1 nil token price with f=1", + commitObservations: []ccip.CommitObservation{legacyObs, newObs, obWithNilTokenPrice}, + f: 1, + expIntervals: []cciptypes.CommitStoreInterval{validInterval, validInterval, zeroInterval}, + expGasPriceObs: map[uint64][]*big.Int{ + sourceChainSelector1: {gasPrice1, gasPrice1, gasPrice1}, + sourceChainSelector2: {gasPrice2, gasPrice2}, + }, + expTokenPriceObs: map[cciptypes.Address][]*big.Int{ + token1: {token1Price, token1Price, token1Price}, + token2: {token2Price, token2Price}, + }, + expError: false, + }, + { + name: "tolerate 1 missing token prices with f=1", + commitObservations: []ccip.CommitObservation{legacyObs, newObs, obMissingTokenPrices}, + f: 1, + expIntervals: []cciptypes.CommitStoreInterval{validInterval, validInterval, zeroInterval}, + expGasPriceObs: map[uint64][]*big.Int{ + sourceChainSelector1: {gasPrice1, gasPrice1, gasPrice1}, + sourceChainSelector2: {gasPrice2, gasPrice2}, + }, + expTokenPriceObs: map[cciptypes.Address][]*big.Int{ + token1: {token1Price, token1Price}, + token2: {token2Price, token2Price}, + }, + expError: false, + }, + { + name: "tolerate 1 unsupported token with f=2", + commitObservations: []ccip.CommitObservation{legacyObs, newObs, obWithUnsupportedToken}, + f: 2, + expIntervals: []cciptypes.CommitStoreInterval{validInterval, validInterval, zeroInterval}, + expGasPriceObs: map[uint64][]*big.Int{ + sourceChainSelector1: {gasPrice1, gasPrice1, gasPrice1}, + }, + expTokenPriceObs: map[cciptypes.Address][]*big.Int{ + token1: {token1Price, token1Price, token1Price}, + token2: {token2Price, token2Price, token2Price}, + }, + expError: false, + }, + { + name: "tolerate mis-matched token observations with f=2", + commitObservations: []ccip.CommitObservation{legacyObs, newObs, obWithNilTokenPrice, obMissingTokenPrices}, + f: 2, + expIntervals: []cciptypes.CommitStoreInterval{validInterval, validInterval, zeroInterval, zeroInterval}, + expGasPriceObs: map[uint64][]*big.Int{ + sourceChainSelector1: {gasPrice1, gasPrice1, gasPrice1, gasPrice1}, + sourceChainSelector2: {gasPrice2, gasPrice2, gasPrice2}, + }, + expTokenPriceObs: map[cciptypes.Address][]*big.Int{ + token1: {token1Price, token1Price, token1Price}, + }, + expError: false, + }, + { + name: "tolerate all tokens filtered out with f=2", + commitObservations: []ccip.CommitObservation{newObs, obMissingTokenPrices, obMissingTokenPrices}, + f: 2, + expIntervals: []cciptypes.CommitStoreInterval{validInterval, zeroInterval, zeroInterval}, + expGasPriceObs: map[uint64][]*big.Int{ + sourceChainSelector1: {gasPrice1, gasPrice1, gasPrice1}, + sourceChainSelector2: {gasPrice2, gasPrice2, gasPrice2}, + }, + expTokenPriceObs: map[cciptypes.Address][]*big.Int{}, + expError: false, + }, + { + name: "not enough observations", + commitObservations: []ccip.CommitObservation{legacyObs, newObs}, + f: 2, + expError: true, + }, + { + name: "too many empty observations", + commitObservations: []ccip.CommitObservation{obWithNilGasPrice, obWithNilTokenPrice, obEmpty, obEmpty, obEmpty}, + f: 2, + expIntervals: []cciptypes.CommitStoreInterval{zeroInterval, zeroInterval, zeroInterval, zeroInterval, zeroInterval}, + expGasPriceObs: map[uint64][]*big.Int{}, + expTokenPriceObs: map[cciptypes.Address][]*big.Int{}, + expError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + intervals, gasPriceOps, tokenPriceOps, err := extractObservationData(logger.TestLogger(t), tc.f, sourceChainSelector1, tc.commitObservations) + + if tc.expError { + assert.Error(t, err) + return + } + assert.Equal(t, tc.expIntervals, intervals) + assert.Equal(t, tc.expGasPriceObs, gasPriceOps) + assert.Equal(t, tc.expTokenPriceObs, tokenPriceOps) + assert.NoError(t, err) + }) + } +} + +func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { + const defaultSourceChainSelector = 10 // we reuse this value across all test cases + feeToken1 := ccipcalc.HexToAddress("0xa") + feeToken2 := ccipcalc.HexToAddress("0xb") + + val1e18 := func(val int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(val)) } + + testCases := []struct { + name string + commitObservations []ccip.CommitObservation + f int + latestGasPrice map[uint64]update + latestTokenPrices map[cciptypes.Address]update + gasPriceHeartBeat config.Duration + daGasPriceDeviationPPB int64 + execGasPriceDeviationPPB int64 + tokenPriceHeartBeat config.Duration + tokenPriceDeviationPPB uint32 + expTokenUpdates []cciptypes.TokenPrice + expGasUpdates []cciptypes.GasPrice + }{ + { + name: "median", + commitObservations: []ccip.CommitObservation{ + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: big.NewInt(1)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: big.NewInt(2)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: big.NewInt(3)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: big.NewInt(4)}}, + }, + latestGasPrice: map[uint64]update{ + defaultSourceChainSelector: { + timestamp: time.Now().Add(-30 * time.Minute), // recent + value: val1e18(9), // median deviates + }, + }, + f: 2, + expGasUpdates: []cciptypes.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: big.NewInt(3)}}, + }, + { + name: "gas price update skipped because the latest is similar and was updated recently", + commitObservations: []ccip.CommitObservation{ + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(11)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(12)}}, + }, + gasPriceHeartBeat: *config.MustNewDuration(time.Hour), + daGasPriceDeviationPPB: 20e7, + execGasPriceDeviationPPB: 20e7, + tokenPriceHeartBeat: *config.MustNewDuration(time.Hour), + tokenPriceDeviationPPB: 20e7, + latestGasPrice: map[uint64]update{ + defaultSourceChainSelector: { + timestamp: time.Now().Add(-30 * time.Minute), // recent + value: val1e18(10), // median deviates + }, + }, + f: 1, + expGasUpdates: nil, + }, + { + name: "gas price update included, the latest is similar but was not updated recently", + commitObservations: []ccip.CommitObservation{ + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(10)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(11)}}, + }, + gasPriceHeartBeat: *config.MustNewDuration(time.Hour), + daGasPriceDeviationPPB: 20e7, + execGasPriceDeviationPPB: 20e7, + tokenPriceHeartBeat: *config.MustNewDuration(time.Hour), + tokenPriceDeviationPPB: 20e7, + latestGasPrice: map[uint64]update{ + defaultSourceChainSelector: { + timestamp: time.Now().Add(-90 * time.Minute), // stale + value: val1e18(9), // median deviates + }, + }, + f: 1, + expGasUpdates: []cciptypes.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: val1e18(11)}}, + }, + { + name: "gas price update deviates from latest", + commitObservations: []ccip.CommitObservation{ + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(10)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(20)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(20)}}, + }, + gasPriceHeartBeat: *config.MustNewDuration(time.Hour), + daGasPriceDeviationPPB: 20e7, + execGasPriceDeviationPPB: 20e7, + tokenPriceHeartBeat: *config.MustNewDuration(time.Hour), + tokenPriceDeviationPPB: 20e7, + latestGasPrice: map[uint64]update{ + defaultSourceChainSelector: { + timestamp: time.Now().Add(-30 * time.Minute), // recent + value: val1e18(11), // latest value close to the update + }, + }, + f: 2, + expGasUpdates: []cciptypes.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: val1e18(20)}}, + }, + { + name: "multichain gas prices", + commitObservations: []ccip.CommitObservation{ + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(1)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector + 1: val1e18(11)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector + 2: val1e18(111)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(2)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector + 1: val1e18(22)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector + 2: val1e18(222)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(3)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector + 1: val1e18(33)}}, + {SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector + 2: val1e18(333)}}, + }, + gasPriceHeartBeat: *config.MustNewDuration(time.Hour), + daGasPriceDeviationPPB: 20e7, + execGasPriceDeviationPPB: 20e7, + tokenPriceHeartBeat: *config.MustNewDuration(time.Hour), + tokenPriceDeviationPPB: 20e7, + latestGasPrice: map[uint64]update{ + defaultSourceChainSelector: { + timestamp: time.Now().Add(-90 * time.Minute), // stale + value: val1e18(9), // median deviates + }, + defaultSourceChainSelector + 1: { + timestamp: time.Now().Add(-30 * time.Minute), // recent + value: val1e18(20), // median does not deviate + }, + }, + f: 1, + expGasUpdates: []cciptypes.GasPrice{ + {DestChainSelector: defaultSourceChainSelector, Value: val1e18(2)}, + {DestChainSelector: defaultSourceChainSelector + 2, Value: val1e18(222)}, + }, + }, + { + name: "median one token", + commitObservations: []ccip.CommitObservation{ + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: big.NewInt(10)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(0)}, + }, + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: big.NewInt(12)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(0)}, + }, + }, + f: 1, + expTokenUpdates: []cciptypes.TokenPrice{ + {Token: feeToken1, Value: big.NewInt(12)}, + }, + // We expect a gas update because no latest + expGasUpdates: []cciptypes.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: big.NewInt(0)}}, + }, + { + name: "median two tokens", + commitObservations: []ccip.CommitObservation{ + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: big.NewInt(10), feeToken2: big.NewInt(13)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(0)}, + }, + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: big.NewInt(12), feeToken2: big.NewInt(7)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(0)}, + }, + }, + f: 1, + expTokenUpdates: []cciptypes.TokenPrice{ + {Token: feeToken1, Value: big.NewInt(12)}, + {Token: feeToken2, Value: big.NewInt(13)}, + }, + // We expect a gas update because no latest + expGasUpdates: []cciptypes.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: big.NewInt(0)}}, + }, + { + name: "token price update skipped because it is close to the latest", + commitObservations: []ccip.CommitObservation{ + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: val1e18(11)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(0)}, + }, + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: val1e18(12)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(0)}, + }, + }, + f: 1, + gasPriceHeartBeat: *config.MustNewDuration(time.Hour), + daGasPriceDeviationPPB: 20e7, + execGasPriceDeviationPPB: 20e7, + tokenPriceHeartBeat: *config.MustNewDuration(time.Hour), + tokenPriceDeviationPPB: 20e7, + latestTokenPrices: map[cciptypes.Address]update{ + feeToken1: { + timestamp: time.Now().Add(-30 * time.Minute), + value: val1e18(10), + }, + }, + // We expect a gas update because no latest + expGasUpdates: []cciptypes.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: big.NewInt(0)}}, + }, + { + name: "gas price and token price both included because they are not close to the latest", + commitObservations: []ccip.CommitObservation{ + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: val1e18(20)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + defaultSourceChainSelector: val1e18(10), + defaultSourceChainSelector + 1: val1e18(20), + }, + }, + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: val1e18(21)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + defaultSourceChainSelector: val1e18(11), + defaultSourceChainSelector + 1: val1e18(21), + }, + }, + }, + f: 1, + gasPriceHeartBeat: *config.MustNewDuration(time.Hour), + daGasPriceDeviationPPB: 10e7, + execGasPriceDeviationPPB: 10e7, + tokenPriceHeartBeat: *config.MustNewDuration(time.Hour), + tokenPriceDeviationPPB: 20e7, + latestGasPrice: map[uint64]update{ + defaultSourceChainSelector: { + timestamp: time.Now().Add(-30 * time.Minute), + value: val1e18(9), + }, + defaultSourceChainSelector + 1: { + timestamp: time.Now().Add(-30 * time.Minute), + value: val1e18(9), + }, + }, + latestTokenPrices: map[cciptypes.Address]update{ + feeToken1: { + timestamp: time.Now().Add(-30 * time.Minute), + value: val1e18(9), + }, + }, + expTokenUpdates: []cciptypes.TokenPrice{ + {Token: feeToken1, Value: val1e18(21)}, + }, + expGasUpdates: []cciptypes.GasPrice{ + {DestChainSelector: defaultSourceChainSelector, Value: val1e18(11)}, + {DestChainSelector: defaultSourceChainSelector + 1, Value: val1e18(21)}, + }, + }, + { + name: "gas price and token price both included because they not been updated recently", + commitObservations: []ccip.CommitObservation{ + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: val1e18(20)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + defaultSourceChainSelector: val1e18(10), + defaultSourceChainSelector + 1: val1e18(20), + }, + }, + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: val1e18(21)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + defaultSourceChainSelector: val1e18(11), + defaultSourceChainSelector + 1: val1e18(21), + }, + }, + }, + f: 1, + gasPriceHeartBeat: *config.MustNewDuration(time.Hour), + daGasPriceDeviationPPB: 10e7, + execGasPriceDeviationPPB: 10e7, + tokenPriceHeartBeat: *config.MustNewDuration(2 * time.Hour), + tokenPriceDeviationPPB: 20e7, + latestGasPrice: map[uint64]update{ + defaultSourceChainSelector: { + timestamp: time.Now().Add(-90 * time.Minute), + value: val1e18(11), + }, + defaultSourceChainSelector + 1: { + timestamp: time.Now().Add(-90 * time.Minute), + value: val1e18(21), + }, + }, + latestTokenPrices: map[cciptypes.Address]update{ + feeToken1: { + timestamp: time.Now().Add(-4 * time.Hour), + value: val1e18(21), + }, + }, + expTokenUpdates: []cciptypes.TokenPrice{ + {Token: feeToken1, Value: val1e18(21)}, + }, + expGasUpdates: []cciptypes.GasPrice{ + {DestChainSelector: defaultSourceChainSelector, Value: val1e18(11)}, + {DestChainSelector: defaultSourceChainSelector + 1, Value: val1e18(21)}, + }, + }, + { + name: "gas price included because it deviates from latest and token price skipped because it does not deviate", + commitObservations: []ccip.CommitObservation{ + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: val1e18(20)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(10)}, + }, + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: val1e18(21)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(11)}, + }, + }, + f: 1, + gasPriceHeartBeat: *config.MustNewDuration(time.Hour), + daGasPriceDeviationPPB: 10e7, + execGasPriceDeviationPPB: 10e7, + tokenPriceHeartBeat: *config.MustNewDuration(2 * time.Hour), + tokenPriceDeviationPPB: 200e7, + latestGasPrice: map[uint64]update{ + defaultSourceChainSelector: { + timestamp: time.Now().Add(-90 * time.Minute), + value: val1e18(9), + }, + }, + latestTokenPrices: map[cciptypes.Address]update{ + feeToken1: { + timestamp: time.Now().Add(-30 * time.Minute), + value: val1e18(9), + }, + }, + expGasUpdates: []cciptypes.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: val1e18(11)}}, + }, + { + name: "gas price skipped because it does not deviate and token price included because it has not been updated recently", + commitObservations: []ccip.CommitObservation{ + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: val1e18(20)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(10)}, + }, + { + TokenPricesUSD: map[cciptypes.Address]*big.Int{feeToken1: val1e18(21)}, + SourceGasPriceUSDPerChain: map[uint64]*big.Int{defaultSourceChainSelector: val1e18(11)}, + }, + }, + f: 1, + gasPriceHeartBeat: *config.MustNewDuration(time.Hour), + daGasPriceDeviationPPB: 10e7, + execGasPriceDeviationPPB: 10e7, + tokenPriceHeartBeat: *config.MustNewDuration(2 * time.Hour), + tokenPriceDeviationPPB: 20e7, + latestGasPrice: map[uint64]update{ + defaultSourceChainSelector: { + timestamp: time.Now().Add(-30 * time.Minute), + value: val1e18(11), + }, + }, + latestTokenPrices: map[cciptypes.Address]update{ + feeToken1: { + timestamp: time.Now().Add(-4 * time.Hour), + value: val1e18(21), + }, + }, + expTokenUpdates: []cciptypes.TokenPrice{ + {Token: feeToken1, Value: val1e18(21)}, + }, + expGasUpdates: nil, + }, + } + + evmEstimator := mocks.NewEvmFeeEstimator(t) + evmEstimator.On("L1Oracle").Return(nil) + estimatorCSVer, _ := semver.NewVersion("1.2.0") + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + estimator, _ := prices.NewGasPriceEstimatorForCommitPlugin( + *estimatorCSVer, + evmEstimator, + nil, + tc.daGasPriceDeviationPPB, + tc.execGasPriceDeviationPPB, + ) + + r := &CommitReportingPlugin{ + lggr: logger.TestLogger(t), + sourceChainSelector: defaultSourceChainSelector, + offchainConfig: cciptypes.CommitOffchainConfig{ + GasPriceHeartBeat: tc.gasPriceHeartBeat.Duration(), + TokenPriceHeartBeat: tc.tokenPriceHeartBeat.Duration(), + TokenPriceDeviationPPB: tc.tokenPriceDeviationPPB, + }, + gasPriceEstimator: estimator, + F: tc.f, + } + + gasPriceObs := make(map[uint64][]*big.Int) + tokenPriceObs := make(map[cciptypes.Address][]*big.Int) + for _, obs := range tc.commitObservations { + for selector, price := range obs.SourceGasPriceUSDPerChain { + gasPriceObs[selector] = append(gasPriceObs[selector], price) + } + for token, price := range obs.TokenPricesUSD { + tokenPriceObs[token] = append(tokenPriceObs[token], price) + } + } + + gotGas, gotTokens, err := r.calculatePriceUpdates(gasPriceObs, tokenPriceObs, tc.latestGasPrice, tc.latestTokenPrices) + + assert.Equal(t, tc.expGasUpdates, gotGas) + assert.Equal(t, tc.expTokenUpdates, gotTokens) + assert.NoError(t, err) + }) + } +} + +func TestCommitReportingPlugin_isStaleReport(t *testing.T) { + ctx := context.Background() + lggr := logger.TestLogger(t) + merkleRoot1 := utils.Keccak256Fixed([]byte("some merkle root 1")) + + t.Run("empty report", func(t *testing.T) { + commitStoreReader := ccipdatamocks.NewCommitStoreReader(t) + r := &CommitReportingPlugin{commitStoreReader: commitStoreReader} + isStale := r.isStaleReport(ctx, lggr, cciptypes.CommitStoreReport{}, types.ReportTimestamp{}) + assert.True(t, isStale) + }) + + t.Run("merkle root", func(t *testing.T) { + const expNextSeqNum = uint64(9) + commitStoreReader := ccipdatamocks.NewCommitStoreReader(t) + commitStoreReader.On("GetExpectedNextSequenceNumber", mock.Anything).Return(expNextSeqNum, nil) + + r := &CommitReportingPlugin{ + commitStoreReader: commitStoreReader, + } + + testCases := map[string]struct { + interval cciptypes.CommitStoreInterval + result bool + }{ + "The nextSeqNumber is equal to the commit store interval Min value": { + interval: cciptypes.CommitStoreInterval{Min: expNextSeqNum, Max: expNextSeqNum + 10}, + result: false, + }, + "The nextSeqNumber is less than the commit store interval Min value": { + interval: cciptypes.CommitStoreInterval{Min: expNextSeqNum + 1, Max: expNextSeqNum + 10}, + result: true, + }, + "The nextSeqNumber is greater than the commit store interval Min value": { + interval: cciptypes.CommitStoreInterval{Min: expNextSeqNum - 1, Max: expNextSeqNum + 10}, + result: true, + }, + "Empty interval": { + interval: cciptypes.CommitStoreInterval{}, + result: true, + }, + } + + for tcName, tc := range testCases { + t.Run(tcName, func(t *testing.T) { + assert.Equal(t, tc.result, r.isStaleReport(ctx, lggr, cciptypes.CommitStoreReport{ + MerkleRoot: merkleRoot1, + Interval: tc.interval, + }, types.ReportTimestamp{})) + }) + } + }) +} + +func TestCommitReportingPlugin_calculateMinMaxSequenceNumbers(t *testing.T) { + testCases := []struct { + name string + commitStoreSeqNum uint64 + msgSeqNums []uint64 + + expQueryMin uint64 // starting seq num that is used in the query to get messages + expMin uint64 + expMax uint64 + expErr bool + }{ + { + name: "happy flow", + commitStoreSeqNum: 9, + msgSeqNums: []uint64{11, 12, 13, 14}, + expQueryMin: 9, + expMin: 11, + expMax: 14, + expErr: false, + }, + { + name: "happy flow 2", + commitStoreSeqNum: 9, + msgSeqNums: []uint64{11, 12, 13, 14}, + expQueryMin: 9, // from commit store + expMin: 11, + expMax: 14, + expErr: false, + }, + { + name: "gap in msg seq nums", + commitStoreSeqNum: 10, + expQueryMin: 10, + msgSeqNums: []uint64{11, 12, 14}, + expErr: true, + }, + { + name: "no new messages", + commitStoreSeqNum: 9, + msgSeqNums: []uint64{}, + expQueryMin: 9, + expMin: 0, + expMax: 0, + expErr: false, + }, + { + name: "unordered seq nums", + commitStoreSeqNum: 9, + msgSeqNums: []uint64{11, 13, 14, 10}, + expQueryMin: 9, + expErr: true, + }, + } + + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + p := &CommitReportingPlugin{} + commitStoreReader := ccipdatamocks.NewCommitStoreReader(t) + commitStoreReader.On("GetExpectedNextSequenceNumber", mock.Anything).Return(tc.commitStoreSeqNum, nil) + p.commitStoreReader = commitStoreReader + + onRampReader := ccipdatamocks.NewOnRampReader(t) + var sendReqs []cciptypes.EVM2EVMMessageWithTxMeta + for _, seqNum := range tc.msgSeqNums { + sendReqs = append(sendReqs, cciptypes.EVM2EVMMessageWithTxMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: seqNum, + }, + }) + } + onRampReader.On("GetSendRequestsBetweenSeqNums", ctx, tc.expQueryMin, tc.expQueryMin+OnRampMessagesScanLimit, true).Return(sendReqs, nil) + p.onRampReader = onRampReader + + minSeqNum, maxSeqNum, _, err := p.calculateMinMaxSequenceNumbers(ctx, lggr) + if tc.expErr { + assert.Error(t, err) + return + } + + assert.Equal(t, tc.expMin, minSeqNum) + assert.Equal(t, tc.expMax, maxSeqNum) + }) + } +} + +func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { + now := time.Now() + chainSelector1 := uint64(1234) + chainSelector2 := uint64(5678) + + chain1Value := big.NewInt(1000) + chain2Value := big.NewInt(2000) + + testCases := []struct { + name string + priceRegistryUpdates []cciptypes.GasPriceUpdate + expUpdates map[uint64]update + expErr bool + }{ + { + name: "happy path", + priceRegistryUpdates: []cciptypes.GasPriceUpdate{ + { + GasPrice: cciptypes.GasPrice{DestChainSelector: chainSelector1, Value: chain1Value}, + TimestampUnixSec: big.NewInt(now.Unix()), + }, + }, + expUpdates: map[uint64]update{chainSelector1: {timestamp: now, value: chain1Value}}, + expErr: false, + }, + { + name: "happy path multiple updates", + priceRegistryUpdates: []cciptypes.GasPriceUpdate{ + { + GasPrice: cciptypes.GasPrice{DestChainSelector: chainSelector1, Value: big.NewInt(1)}, + TimestampUnixSec: big.NewInt(now.Unix()), + }, + { + GasPrice: cciptypes.GasPrice{DestChainSelector: chainSelector2, Value: big.NewInt(1)}, + TimestampUnixSec: big.NewInt(now.Add(1 * time.Minute).Unix()), + }, + { + GasPrice: cciptypes.GasPrice{DestChainSelector: chainSelector2, Value: chain2Value}, + TimestampUnixSec: big.NewInt(now.Add(2 * time.Minute).Unix()), + }, + { + GasPrice: cciptypes.GasPrice{DestChainSelector: chainSelector1, Value: chain1Value}, + TimestampUnixSec: big.NewInt(now.Add(3 * time.Minute).Unix()), + }, + }, + expUpdates: map[uint64]update{ + chainSelector1: {timestamp: now.Add(3 * time.Minute), value: chain1Value}, + chainSelector2: {timestamp: now.Add(2 * time.Minute), value: chain2Value}, + }, + expErr: false, + }, + } + + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + p := &CommitReportingPlugin{} + p.lggr = lggr + priceReg := ccipdatamocks.NewPriceRegistryReader(t) + p.destPriceRegistryReader = priceReg + + var events []cciptypes.GasPriceUpdateWithTxMeta + for _, update := range tc.priceRegistryUpdates { + events = append(events, cciptypes.GasPriceUpdateWithTxMeta{ + GasPriceUpdate: update, + }) + } + + priceReg.On("GetAllGasPriceUpdatesCreatedAfter", ctx, mock.Anything, 0).Return(events, nil) + + gotUpdates, err := p.getLatestGasPriceUpdate(ctx, now) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, len(tc.expUpdates), len(gotUpdates)) + for selector, gotUpdate := range gotUpdates { + assert.Equal(t, tc.expUpdates[selector].timestamp.Truncate(time.Second), gotUpdate.timestamp.Truncate(time.Second)) + assert.Equal(t, tc.expUpdates[selector].value.Uint64(), gotUpdate.value.Uint64()) + } + }) + } +} + +func TestCommitReportingPlugin_getLatestTokenPriceUpdates(t *testing.T) { + now := time.Now() + tk1 := cciptypes.Address(utils.RandomAddress().String()) + tk2 := cciptypes.Address(utils.RandomAddress().String()) + + testCases := []struct { + name string + priceRegistryUpdates []cciptypes.TokenPriceUpdate + expUpdates map[cciptypes.Address]update + expErr bool + }{ + { + name: "happy path", + priceRegistryUpdates: []cciptypes.TokenPriceUpdate{ + { + TokenPrice: cciptypes.TokenPrice{ + Token: tk1, + Value: big.NewInt(1000), + }, + TimestampUnixSec: big.NewInt(now.Add(1 * time.Minute).Unix()), + }, + { + TokenPrice: cciptypes.TokenPrice{ + Token: tk2, + Value: big.NewInt(2000), + }, + TimestampUnixSec: big.NewInt(now.Add(2 * time.Minute).Unix()), + }, + }, + expUpdates: map[cciptypes.Address]update{ + tk1: {timestamp: now.Add(1 * time.Minute), value: big.NewInt(1000)}, + tk2: {timestamp: now.Add(2 * time.Minute), value: big.NewInt(2000)}, + }, + expErr: false, + }, + } + + ctx := testutils.Context(t) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + p := &CommitReportingPlugin{} + + priceReg := ccipdatamocks.NewPriceRegistryReader(t) + p.destPriceRegistryReader = priceReg + + var events []cciptypes.TokenPriceUpdateWithTxMeta + for _, up := range tc.priceRegistryUpdates { + events = append(events, cciptypes.TokenPriceUpdateWithTxMeta{ + TokenPriceUpdate: up, + }) + } + + priceReg.On("GetTokenPriceUpdatesCreatedAfter", ctx, mock.Anything, 0).Return(events, nil) + + updates, err := p.getLatestTokenPriceUpdates(ctx, now) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, len(tc.expUpdates), len(updates)) + for k, v := range updates { + assert.Equal(t, tc.expUpdates[k].timestamp.Truncate(time.Second), v.timestamp.Truncate(time.Second)) + assert.Equal(t, tc.expUpdates[k].value.Uint64(), v.value.Uint64()) + } + }) + } +} + +func Test_commitReportSize(t *testing.T) { + testParams := gopter.DefaultTestParameters() + testParams.MinSuccessfulTests = 100 + p := gopter.NewProperties(testParams) + p.Property("bounded commit report size", prop.ForAll(func(root []byte, min, max uint64) bool { + var root32 [32]byte + copy(root32[:], root) + rep, err := encodeCommitReport(cciptypes.CommitStoreReport{ + MerkleRoot: root32, + Interval: cciptypes.CommitStoreInterval{Min: min, Max: max}, + TokenPrices: []cciptypes.TokenPrice{}, + GasPrices: []cciptypes.GasPrice{ + { + DestChainSelector: 1337, + Value: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, + }, + }) + require.NoError(t, err) + return len(rep) <= MaxCommitReportLength + }, gen.SliceOfN(32, gen.UInt8()), gen.UInt64(), gen.UInt64())) + p.TestingRun(t) +} + +func Test_calculateIntervalConsensus(t *testing.T) { + tests := []struct { + name string + intervals []cciptypes.CommitStoreInterval + rangeLimit uint64 + f int + wantMin uint64 + wantMax uint64 + wantErr bool + }{ + {"no obs", []cciptypes.CommitStoreInterval{{Min: 0, Max: 0}}, 0, 0, 0, 0, false}, + {"basic", []cciptypes.CommitStoreInterval{ + {Min: 9, Max: 14}, + {Min: 10, Max: 12}, + {Min: 10, Max: 14}, + }, 0, 1, 10, 14, false}, + {"min > max", []cciptypes.CommitStoreInterval{ + {Min: 9, Max: 4}, + {Min: 10, Max: 4}, + {Min: 10, Max: 6}, + }, 0, 1, 0, 0, true}, + { + "range limit", []cciptypes.CommitStoreInterval{ + {Min: 10, Max: 100}, + {Min: 1, Max: 1000}, + }, 256, 1, 10, 265, false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := calculateIntervalConsensus(tt.intervals, tt.f, tt.rangeLimit) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + assert.Equal(t, tt.wantMin, got.Min) + assert.Equal(t, tt.wantMax, got.Max) + }) + } +} + +func TestCommitReportToEthTxMeta(t *testing.T) { + mctx := hashutil.NewKeccak() + tree, err := merklemulti.NewTree(mctx, [][32]byte{mctx.Hash([]byte{0xaa})}) + require.NoError(t, err) + + tests := []struct { + name string + min, max uint64 + expectedRange []uint64 + }{ + { + "happy flow", + 1, 10, + []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + }, + { + "same sequence", + 1, 1, + []uint64{1}, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + report := cciptypes.CommitStoreReport{ + TokenPrices: []cciptypes.TokenPrice{}, + GasPrices: []cciptypes.GasPrice{ + { + DestChainSelector: uint64(1337), + Value: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, + }, + MerkleRoot: tree.Root(), + Interval: cciptypes.CommitStoreInterval{Min: tc.min, Max: tc.max}, + } + out, err := encodeCommitReport(report) + require.NoError(t, err) + + fn, err := factory.CommitReportToEthTxMeta(ccipconfig.CommitStore, *semver.MustParse("1.0.0")) + require.NoError(t, err) + txMeta, err := fn(out) + require.NoError(t, err) + require.NotNil(t, txMeta) + require.EqualValues(t, tc.expectedRange, txMeta.SeqNumbers) + }) + } +} + +// TODO should be removed, tests need to be updated to use the Reader interface. +// encodeCommitReport is only used in tests +func encodeCommitReport(report cciptypes.CommitStoreReport) ([]byte, error) { + commitStoreABI := abihelpers.MustParseABI(commit_store.CommitStoreABI) + return v1_2_0.EncodeCommitReport(abihelpers.MustGetEventInputs(v1_0_0.ReportAccepted, commitStoreABI), report) +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/batching.go b/core/services/ocr2/plugins/ccip/ccipexec/batching.go new file mode 100644 index 0000000000..b457dd986d --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/batching.go @@ -0,0 +1,540 @@ +package ccipexec + +import ( + "context" + "fmt" + "math/big" + "time" + + mapset "github.com/deckarep/golang-set/v2" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" + "github.com/smartcontractkit/chainlink-common/pkg/types" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/statuschecker" +) + +type BatchContext struct { + report commitReportWithSendRequests + inflight []InflightInternalExecutionReport + inflightAggregateValue *big.Int + lggr logger.Logger + availableDataLen int + availableGas uint64 + expectedNonces map[cciptypes.Address]uint64 + sendersNonce map[cciptypes.Address]uint64 + sourceTokenPricesUSD map[cciptypes.Address]*big.Int + destTokenPricesUSD map[cciptypes.Address]*big.Int + gasPrice *big.Int + sourceToDestToken map[cciptypes.Address]cciptypes.Address + aggregateTokenLimit *big.Int + tokenDataRemainingDuration time.Duration + tokenDataWorker tokendata.Worker + gasPriceEstimator prices.GasPriceEstimatorExec + destWrappedNative cciptypes.Address + offchainConfig cciptypes.ExecOffchainConfig +} + +type BatchingStrategy interface { + BuildBatch(ctx context.Context, batchCtx *BatchContext) ([]ccip.ObservedMessage, []messageExecStatus) +} + +type BestEffortBatchingStrategy struct{} + +type ZKOverflowBatchingStrategy struct { + statuschecker statuschecker.CCIPTransactionStatusChecker +} + +func NewBatchingStrategy(batchingStrategyID uint32, statusChecker statuschecker.CCIPTransactionStatusChecker) (BatchingStrategy, error) { + var batchingStrategy BatchingStrategy + switch batchingStrategyID { + case 0: + batchingStrategy = &BestEffortBatchingStrategy{} + case 1: + batchingStrategy = &ZKOverflowBatchingStrategy{ + statuschecker: statusChecker, + } + default: + return nil, errors.Errorf("unknown batching strategy ID %d", batchingStrategyID) + } + return batchingStrategy, nil +} + +// BestEffortBatchingStrategy is a batching strategy that tries to batch as many messages as possible (up to certain limits). +func (s *BestEffortBatchingStrategy) BuildBatch( + ctx context.Context, + batchCtx *BatchContext, +) ([]ccip.ObservedMessage, []messageExecStatus) { + batchBuilder := newBatchBuildContainer(len(batchCtx.report.sendRequestsWithMeta)) + for _, msg := range batchCtx.report.sendRequestsWithMeta { + msgLggr := batchCtx.lggr.With("messageID", hexutil.Encode(msg.MessageID[:]), "seqNr", msg.SequenceNumber) + status, messageMaxGas, tokenData, msgValue, err := performCommonChecks(ctx, batchCtx, msg, msgLggr) + + if err != nil { + return []ccip.ObservedMessage{}, []messageExecStatus{} + } + + if status.shouldBeSkipped() { + batchBuilder.skip(msg, status) + continue + } + + updateBatchContext(batchCtx, msg, messageMaxGas, msgValue, msgLggr) + batchBuilder.addToBatch(msg, tokenData) + } + return batchBuilder.batch, batchBuilder.statuses +} + +// ZKOverflowBatchingStrategy is a batching strategy for ZK chains overflowing under certain conditions. +// It is a simple batching strategy that only allows one message to be added to the batch. +// TXM is used to perform the ZK check: if the message failed the check, it will be skipped. +func (bs ZKOverflowBatchingStrategy) BuildBatch( + ctx context.Context, + batchCtx *BatchContext, +) ([]ccip.ObservedMessage, []messageExecStatus) { + batchBuilder := newBatchBuildContainer(len(batchCtx.report.sendRequestsWithMeta)) + inflightSeqNums := getInflightSeqNums(batchCtx.inflight) + + for _, msg := range batchCtx.report.sendRequestsWithMeta { + msgId := hexutil.Encode(msg.MessageID[:]) + msgLggr := batchCtx.lggr.With("messageID", msgId, "seqNr", msg.SequenceNumber) + + // Check if msg is inflight + if exists := inflightSeqNums.Contains(msg.SequenceNumber); exists { + // Message is inflight, skip it + msgLggr.Infow("Skipping message - already inflight", "message", msgId) + batchBuilder.skip(msg, SkippedInflight) + continue + } + // Message is not inflight, continue with checks + // Check if the messsage is overflown using TXM + statuses, count, err := bs.statuschecker.CheckMessageStatus(ctx, msgId) + if err != nil { + batchBuilder.skip(msg, TXMCheckError) + continue + } + + msgLggr.Infow("TXM check result", "statuses", statuses, "count", count) + + if len(statuses) == 0 { + // No status found for message = first time we see it + msgLggr.Infow("No status found for message - proceeding with checks", "message", msgId) + } else { + // Status(es) found for message = check if any of them is final to decide if we should add it to the batch + hasFatalStatus := false + for _, s := range statuses { + if s == types.Fatal { + msgLggr.Infow("Skipping message - found a fatal TXM status", "message", msgId) + batchBuilder.skip(msg, TXMFatalStatus) + hasFatalStatus = true + break + } + } + if hasFatalStatus { + continue + } + msgLggr.Infow("No fatal status found for message - proceeding with checks", "message", msgId) + } + + status, messageMaxGas, tokenData, msgValue, err := performCommonChecks(ctx, batchCtx, msg, msgLggr) + + if err != nil { + return []ccip.ObservedMessage{}, []messageExecStatus{} + } + + if status.shouldBeSkipped() { + batchBuilder.skip(msg, status) + continue + } + + updateBatchContext(batchCtx, msg, messageMaxGas, msgValue, msgLggr) + msgLggr.Infow("Adding message to batch", "message", msgId) + batchBuilder.addToBatch(msg, tokenData) + + // Batch size is limited to 1 for ZK Overflow chains + break + } + return batchBuilder.batch, batchBuilder.statuses +} + +func performCommonChecks( + ctx context.Context, + batchCtx *BatchContext, + msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, + msgLggr logger.Logger, +) (messageStatus, uint64, [][]byte, *big.Int, error) { + if msg.Executed { + msgLggr.Infow("Skipping message - already executed") + return AlreadyExecuted, 0, nil, nil, nil + } + + if len(msg.Data) > batchCtx.availableDataLen { + msgLggr.Infow("Skipping message - insufficient remaining batch data length", "msgDataLen", len(msg.Data), "availableBatchDataLen", batchCtx.availableDataLen) + return InsufficientRemainingBatchDataLength, 0, nil, nil, nil + } + + messageMaxGas, err1 := calculateMessageMaxGas( + msg.GasLimit, + len(batchCtx.report.sendRequestsWithMeta), + len(msg.Data), + len(msg.TokenAmounts), + ) + if err1 != nil { + msgLggr.Errorw("Skipping message - message max gas calculation error", "err", err1) + return MessageMaxGasCalcError, 0, nil, nil, nil + } + + // Check sufficient gas in batch + if batchCtx.availableGas < messageMaxGas { + msgLggr.Infow("Skipping message - insufficient remaining batch gas limit", "availableGas", batchCtx.availableGas, "messageMaxGas", messageMaxGas) + return InsufficientRemainingBatchGas, 0, nil, nil, nil + } + + if _, ok := batchCtx.expectedNonces[msg.Sender]; !ok { + nonce, ok1 := batchCtx.sendersNonce[msg.Sender] + if !ok1 { + msgLggr.Errorw("Skipping message - missing nonce", "sender", msg.Sender) + return MissingNonce, 0, nil, nil, nil + } + batchCtx.expectedNonces[msg.Sender] = nonce + 1 + } + + // Check expected nonce is valid for sequenced messages. + // Sequenced messages have non-zero nonces. + if msg.Nonce > 0 && msg.Nonce != batchCtx.expectedNonces[msg.Sender] { + msgLggr.Warnw("Skipping message - invalid nonce", "have", msg.Nonce, "want", batchCtx.expectedNonces[msg.Sender]) + return InvalidNonce, 0, nil, nil, nil + } + + msgValue, err1 := aggregateTokenValue(batchCtx.lggr, batchCtx.destTokenPricesUSD, batchCtx.sourceToDestToken, msg.TokenAmounts) + if err1 != nil { + msgLggr.Errorw("Skipping message - aggregate token value compute error", "err", err1) + return AggregateTokenValueComputeError, 0, nil, nil, nil + } + + // if token limit is smaller than message value skip message + if tokensLeft, hasCapacity := hasEnoughTokens(batchCtx.aggregateTokenLimit, msgValue, batchCtx.inflightAggregateValue); !hasCapacity { + msgLggr.Warnw("Skipping message - aggregate token limit exceeded", "aggregateTokenLimit", tokensLeft.String(), "msgValue", msgValue.String()) + return AggregateTokenLimitExceeded, 0, nil, nil, nil + } + + tokenData, elapsed, err1 := getTokenDataWithTimeout(ctx, msg, batchCtx.tokenDataRemainingDuration, batchCtx.tokenDataWorker) + batchCtx.tokenDataRemainingDuration -= elapsed + if err1 != nil { + if errors.Is(err1, tokendata.ErrNotReady) { + msgLggr.Warnw("Skipping message - token data not ready", "err", err1) + return TokenDataNotReady, 0, nil, nil, nil + } + msgLggr.Errorw("Skipping message - token data fetch error", "err", err1) + return TokenDataFetchError, 0, nil, nil, nil + } + + dstWrappedNativePrice, exists := batchCtx.destTokenPricesUSD[batchCtx.destWrappedNative] + if !exists { + msgLggr.Errorw("Skipping message - token not in destination token prices", "token", batchCtx.destWrappedNative) + return TokenNotInDestTokenPrices, 0, nil, nil, nil + } + + // calculating the source chain fee, dividing by 1e18 for denomination. + // For example: + // FeeToken=link; FeeTokenAmount=1e17 i.e. 0.1 link, price is 6e18 USD/link (1 USD = 1e18), + // availableFee is 1e17*6e18/1e18 = 6e17 = 0.6 USD + sourceFeeTokenPrice, exists := batchCtx.sourceTokenPricesUSD[msg.FeeToken] + if !exists { + msgLggr.Errorw("Skipping message - token not in source token prices", "token", msg.FeeToken) + return TokenNotInSrcTokenPrices, 0, nil, nil, nil + } + + // Fee boosting + execCostUsd, err1 := batchCtx.gasPriceEstimator.EstimateMsgCostUSD(batchCtx.gasPrice, dstWrappedNativePrice, msg) + if err1 != nil { + msgLggr.Errorw("Failed to estimate message cost USD", "err", err1) + return "", 0, nil, nil, errors.New("failed to estimate message cost USD") + } + + availableFee := big.NewInt(0).Mul(msg.FeeTokenAmount, sourceFeeTokenPrice) + availableFee = availableFee.Div(availableFee, big.NewInt(1e18)) + availableFeeUsd := waitBoostedFee(time.Since(msg.BlockTimestamp), availableFee, batchCtx.offchainConfig.RelativeBoostPerWaitHour) + if availableFeeUsd.Cmp(execCostUsd) < 0 { + msgLggr.Infow( + "Skipping message - insufficient remaining fee", + "availableFeeUsd", availableFeeUsd, + "execCostUsd", execCostUsd, + "sourceBlockTimestamp", msg.BlockTimestamp, + "waitTime", time.Since(msg.BlockTimestamp), + "boost", batchCtx.offchainConfig.RelativeBoostPerWaitHour, + ) + return InsufficientRemainingFee, 0, nil, nil, nil + } + + return SuccesfullyValidated, messageMaxGas, tokenData, msgValue, nil +} + +// getTokenDataWithCappedLatency gets the token data for the provided message. +// Stops and returns an error if more than allowedWaitingTime is passed. +func getTokenDataWithTimeout( + ctx context.Context, + msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, + timeout time.Duration, + tokenDataWorker tokendata.Worker, +) ([][]byte, time.Duration, error) { + if len(msg.TokenAmounts) == 0 { + return nil, 0, nil + } + + ctxTimeout, cf := context.WithTimeout(ctx, timeout) + defer cf() + tStart := time.Now() + tokenData, err := tokenDataWorker.GetMsgTokenData(ctxTimeout, msg) + tDur := time.Since(tStart) + return tokenData, tDur, err +} + +func getProofData( + ctx context.Context, + sourceReader ccipdata.OnRampReader, + interval cciptypes.CommitStoreInterval, +) (sendReqsInRoot []cciptypes.EVM2EVMMessageWithTxMeta, leaves [][32]byte, tree *merklemulti.Tree[[32]byte], err error) { + // We don't need to double-check if logs are finalized because we already checked that in the Commit phase. + sendReqs, err := sourceReader.GetSendRequestsBetweenSeqNums(ctx, interval.Min, interval.Max, false) + if err != nil { + return nil, nil, nil, err + } + + if err1 := validateSendRequests(sendReqs, interval); err1 != nil { + return nil, nil, nil, err1 + } + + leaves = make([][32]byte, 0, len(sendReqs)) + for _, req := range sendReqs { + leaves = append(leaves, req.Hash) + } + tree, err = merklemulti.NewTree(hashutil.NewKeccak(), leaves) + if err != nil { + return nil, nil, nil, err + } + return sendReqs, leaves, tree, nil +} + +func validateSendRequests(sendReqs []cciptypes.EVM2EVMMessageWithTxMeta, interval cciptypes.CommitStoreInterval) error { + if len(sendReqs) == 0 { + return fmt.Errorf("could not find any requests in the provided interval %v", interval) + } + + gotInterval := cciptypes.CommitStoreInterval{ + Min: sendReqs[0].SequenceNumber, + Max: sendReqs[0].SequenceNumber, + } + + for _, req := range sendReqs[1:] { + if req.SequenceNumber < gotInterval.Min { + gotInterval.Min = req.SequenceNumber + } + if req.SequenceNumber > gotInterval.Max { + gotInterval.Max = req.SequenceNumber + } + } + + if (gotInterval.Min != interval.Min) || (gotInterval.Max != interval.Max) { + return fmt.Errorf("interval %v is not the expected %v", gotInterval, interval) + } + return nil +} + +func getInflightSeqNums(inflight []InflightInternalExecutionReport) mapset.Set[uint64] { + seqNums := mapset.NewSet[uint64]() + for _, report := range inflight { + for _, msg := range report.messages { + seqNums.Add(msg.SequenceNumber) + } + } + return seqNums +} + +func aggregateTokenValue(lggr logger.Logger, destTokenPricesUSD map[cciptypes.Address]*big.Int, sourceToDest map[cciptypes.Address]cciptypes.Address, tokensAndAmount []cciptypes.TokenAmount) (*big.Int, error) { + sum := big.NewInt(0) + for i := 0; i < len(tokensAndAmount); i++ { + price, ok := destTokenPricesUSD[sourceToDest[tokensAndAmount[i].Token]] + if !ok { + // If we don't have a price for the token, we will assume it's worth 0. + lggr.Infof("No price for token %s, assuming 0", tokensAndAmount[i].Token) + continue + } + sum.Add(sum, new(big.Int).Quo(new(big.Int).Mul(price, tokensAndAmount[i].Amount), big.NewInt(1e18))) + } + return sum, nil +} + +func updateBatchContext( + batchCtx *BatchContext, + msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, + messageMaxGas uint64, + msgValue *big.Int, + msgLggr logger.Logger) { + batchCtx.availableGas -= messageMaxGas + batchCtx.availableDataLen -= len(msg.Data) + batchCtx.aggregateTokenLimit.Sub(batchCtx.aggregateTokenLimit, msgValue) + if msg.Nonce > 0 { + batchCtx.expectedNonces[msg.Sender] = msg.Nonce + 1 + } + + msgLggr.Infow( + "Message successfully added to execution batch", + "nonce", msg.Nonce, + "sender", msg.Sender, + "value", msgValue, + "availableAggrTokenLimit", batchCtx.aggregateTokenLimit, + "availableGas", batchCtx.availableGas, + "availableDataLen", batchCtx.availableDataLen, + ) +} + +func hasEnoughTokens(tokenLimit *big.Int, msgValue *big.Int, inflightValue *big.Int) (*big.Int, bool) { + tokensLeft := big.NewInt(0).Sub(tokenLimit, inflightValue) + return tokensLeft, tokensLeft.Cmp(msgValue) >= 0 +} + +func buildExecutionReportForMessages( + msgsInRoot []cciptypes.EVM2EVMMessageWithTxMeta, + tree *merklemulti.Tree[[32]byte], + commitInterval cciptypes.CommitStoreInterval, + observedMessages []ccip.ObservedMessage, +) (cciptypes.ExecReport, error) { + innerIdxs := make([]int, 0, len(observedMessages)) + var messages []cciptypes.EVM2EVMMessage + var offchainTokenData [][][]byte + for _, observedMessage := range observedMessages { + if observedMessage.SeqNr < commitInterval.Min || observedMessage.SeqNr > commitInterval.Max { + // We only return messages from a single root (the root of the first message). + continue + } + innerIdx := int(observedMessage.SeqNr - commitInterval.Min) + if innerIdx >= len(msgsInRoot) || innerIdx < 0 { + return cciptypes.ExecReport{}, fmt.Errorf("invalid inneridx SeqNr=%d IntervalMin=%d msgsInRoot=%d", + observedMessage.SeqNr, commitInterval.Min, len(msgsInRoot)) + } + messages = append(messages, msgsInRoot[innerIdx].EVM2EVMMessage) + offchainTokenData = append(offchainTokenData, observedMessage.TokenData) + innerIdxs = append(innerIdxs, innerIdx) + } + + merkleProof, err := tree.Prove(innerIdxs) + if err != nil { + return cciptypes.ExecReport{}, err + } + + // any capped proof will have length <= this one, so we reuse it to avoid proving inside loop, and update later if changed + return cciptypes.ExecReport{ + Messages: messages, + Proofs: merkleProof.Hashes, + ProofFlagBits: abihelpers.ProofFlagsToBits(merkleProof.SourceFlags), + OffchainTokenData: offchainTokenData, + }, nil +} + +// Validates the given message observations do not exceed the committed sequence numbers +// in the commitStoreReader. +func validateSeqNumbers(serviceCtx context.Context, commitStore ccipdata.CommitStoreReader, observedMessages []ccip.ObservedMessage) error { + nextMin, err := commitStore.GetExpectedNextSequenceNumber(serviceCtx) + if err != nil { + return err + } + // observedMessages are always sorted by SeqNr and never empty, so it's safe to take last element + maxSeqNumInBatch := observedMessages[len(observedMessages)-1].SeqNr + + if maxSeqNumInBatch >= nextMin { + return errors.Errorf("Cannot execute uncommitted seq num. nextMin %v, seqNums %v", nextMin, observedMessages) + } + return nil +} + +// Gets the commit report from the saved logs for a given sequence number. +func getCommitReportForSeqNum(ctx context.Context, commitStoreReader ccipdata.CommitStoreReader, seqNum uint64) (cciptypes.CommitStoreReport, error) { + acceptedReports, err := commitStoreReader.GetCommitReportMatchingSeqNum(ctx, seqNum, 0) + if err != nil { + return cciptypes.CommitStoreReport{}, err + } + + if len(acceptedReports) == 0 { + return cciptypes.CommitStoreReport{}, errors.Errorf("seq number not committed") + } + + return acceptedReports[0].CommitStoreReport, nil +} + +type messageStatus string + +const ( + SuccesfullyValidated messageStatus = "successfully_validated" + AlreadyExecuted messageStatus = "already_executed" + SenderAlreadySkipped messageStatus = "sender_already_skipped" + MessageMaxGasCalcError messageStatus = "message_max_gas_calc_error" + InsufficientRemainingBatchDataLength messageStatus = "insufficient_remaining_batch_data_length" + InsufficientRemainingBatchGas messageStatus = "insufficient_remaining_batch_gas" + MissingNonce messageStatus = "missing_nonce" + InvalidNonce messageStatus = "invalid_nonce" + AggregateTokenValueComputeError messageStatus = "aggregate_token_value_compute_error" + AggregateTokenLimitExceeded messageStatus = "aggregate_token_limit_exceeded" + TokenDataNotReady messageStatus = "token_data_not_ready" + TokenDataFetchError messageStatus = "token_data_fetch_error" + TokenNotInDestTokenPrices messageStatus = "token_not_in_dest_token_prices" + TokenNotInSrcTokenPrices messageStatus = "token_not_in_src_token_prices" + InsufficientRemainingFee messageStatus = "insufficient_remaining_fee" + AddedToBatch messageStatus = "added_to_batch" + TXMCheckError messageStatus = "txm_check_error" + TXMFatalStatus messageStatus = "txm_fatal_status" + SkippedInflight messageStatus = "skipped_inflight" +) + +func (m messageStatus) shouldBeSkipped() bool { + return m != SuccesfullyValidated +} + +type messageExecStatus struct { + SeqNr uint64 + MessageId string + Status messageStatus +} + +func newMessageExecState(seqNr uint64, messageId cciptypes.Hash, status messageStatus) messageExecStatus { + return messageExecStatus{ + SeqNr: seqNr, + MessageId: hexutil.Encode(messageId[:]), + Status: status, + } +} + +type batchBuildContainer struct { + batch []ccip.ObservedMessage + statuses []messageExecStatus +} + +func newBatchBuildContainer(capacity int) *batchBuildContainer { + return &batchBuildContainer{ + batch: make([]ccip.ObservedMessage, 0, capacity), + statuses: make([]messageExecStatus, 0, capacity), + } +} + +func (m *batchBuildContainer) skip(msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, status messageStatus) { + m.addState(msg, status) +} + +func (m *batchBuildContainer) addToBatch(msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, tokenData [][]byte) { + m.addState(msg, AddedToBatch) + m.batch = append(m.batch, ccip.NewObservedMessage(msg.SequenceNumber, tokenData)) +} + +func (m *batchBuildContainer) addState(msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, state messageStatus) { + m.statuses = append(m.statuses, newMessageExecState(msg.SequenceNumber, msg.MessageID, state)) +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/batching_test.go b/core/services/ocr2/plugins/ccip/ccipexec/batching_test.go new file mode 100644 index 0000000000..3647556a6d --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/batching_test.go @@ -0,0 +1,910 @@ +package ccipexec + +import ( + "bytes" + "context" + "encoding/binary" + "math" + "math/big" + "reflect" + "testing" + "time" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "github.com/smartcontractkit/chainlink-common/pkg/types" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" + mockstatuschecker "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/statuschecker/mocks" +) + +type testCase struct { + name string + reqs []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta + inflight []InflightInternalExecutionReport + tokenLimit, destGasPrice, inflightAggregateValue *big.Int + srcPrices, dstPrices map[cciptypes.Address]*big.Int + offRampNoncesBySender map[cciptypes.Address]uint64 + srcToDestTokens map[cciptypes.Address]cciptypes.Address + expectedSeqNrs []ccip.ObservedMessage + expectedStates []messageExecStatus + statuschecker func(m *mockstatuschecker.CCIPTransactionStatusChecker) + skipGasPriceEstimator bool +} + +func Test_NewBatchingStrategy(t *testing.T) { + t.Parallel() + + mockStatusChecker := mockstatuschecker.NewCCIPTransactionStatusChecker(t) + + testCases := []int{0, 1, 2} + + for _, batchingStrategyId := range testCases { + factory, err := NewBatchingStrategy(uint32(batchingStrategyId), mockStatusChecker) + if batchingStrategyId == 2 { + assert.Error(t, err) + } else { + assert.NotNil(t, factory) + assert.NoError(t, err) + } + } +} + +func Test_validateSendRequests(t *testing.T) { + testCases := []struct { + name string + seqNums []uint64 + providedInterval cciptypes.CommitStoreInterval + expErr bool + }{ + { + name: "zero interval no seq nums", + seqNums: nil, + providedInterval: cciptypes.CommitStoreInterval{Min: 0, Max: 0}, + expErr: true, + }, + { + name: "exp 1 seq num got none", + seqNums: nil, + providedInterval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, + expErr: true, + }, + { + name: "exp 10 seq num got none", + seqNums: nil, + providedInterval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}, + expErr: true, + }, + { + name: "got 1 seq num as expected", + seqNums: []uint64{1}, + providedInterval: cciptypes.CommitStoreInterval{Min: 1, Max: 1}, + expErr: false, + }, + { + name: "got 5 seq num as expected", + seqNums: []uint64{11, 12, 13, 14, 15}, + providedInterval: cciptypes.CommitStoreInterval{Min: 11, Max: 15}, + expErr: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + sendReqs := make([]cciptypes.EVM2EVMMessageWithTxMeta, 0, len(tc.seqNums)) + for _, seqNum := range tc.seqNums { + sendReqs = append(sendReqs, cciptypes.EVM2EVMMessageWithTxMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: seqNum}, + }) + } + err := validateSendRequests(sendReqs, tc.providedInterval) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + }) + } +} + +type delayedTokenDataWorker struct { + delay time.Duration + tokendata.Worker +} + +func (m delayedTokenDataWorker) GetMsgTokenData(ctx context.Context, msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) ([][]byte, error) { + time.Sleep(m.delay) + return nil, ctx.Err() +} + +func TestExecutionReportingPlugin_getTokenDataWithCappedLatency(t *testing.T) { + testCases := []struct { + name string + allowedWaitingTime time.Duration + workerLatency time.Duration + expErr bool + }{ + { + name: "happy flow", + allowedWaitingTime: 10 * time.Millisecond, + workerLatency: time.Nanosecond, + expErr: false, + }, + { + name: "worker takes long to reply", + allowedWaitingTime: 10 * time.Millisecond, + workerLatency: 20 * time.Millisecond, + expErr: true, + }, + } + + ctx := testutils.Context(t) + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + tokenDataWorker := delayedTokenDataWorker{delay: tc.workerLatency} + + msg := cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{TokenAmounts: make([]cciptypes.TokenAmount, 1)}, + } + + _, _, err := getTokenDataWithTimeout(ctx, msg, tc.allowedWaitingTime, tokenDataWorker) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + }) + } +} + +func TestBatchingStrategies(t *testing.T) { + sender1 := ccipcalc.HexToAddress("0xa") + destNative := ccipcalc.HexToAddress("0xb") + srcNative := ccipcalc.HexToAddress("0xc") + + msg1 := createTestMessage(1, sender1, 1, srcNative, big.NewInt(1e9), false, nil) + + msg2 := msg1 + msg2.Executed = true + + msg3 := msg1 + msg3.Executed = true + msg3.Finalized = true + + msg4 := msg1 + msg4.TokenAmounts = []cciptypes.TokenAmount{ + {Token: srcNative, Amount: big.NewInt(100)}, + } + + msg5 := msg4 + msg5.SequenceNumber = msg5.SequenceNumber + 1 + msg5.Nonce = msg5.Nonce + 1 + + zkMsg1 := createTestMessage(1, sender1, 0, srcNative, big.NewInt(1e9), false, nil) + zkMsg2 := createTestMessage(2, sender1, 0, srcNative, big.NewInt(1e9), false, nil) + zkMsg3 := createTestMessage(3, sender1, 0, srcNative, big.NewInt(1e9), false, nil) + zkMsg4 := createTestMessage(4, sender1, 0, srcNative, big.NewInt(1e9), false, nil) + + testCases := []testCase{ + { + name: "single message no tokens", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{msg1}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedSeqNrs: []ccip.ObservedMessage{{SeqNr: uint64(1)}}, + expectedStates: []messageExecStatus{newMessageExecState(msg1.SequenceNumber, msg1.MessageID, AddedToBatch)}, + }, + { + name: "gasPriceEstimator returns error", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{msg1}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + }, + { + name: "executed non finalized messages should be skipped", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{msg2}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedStates: []messageExecStatus{newMessageExecState(msg2.SequenceNumber, msg2.MessageID, AlreadyExecuted)}, + skipGasPriceEstimator: true, + }, + { + name: "finalized executed log", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{msg3}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedStates: []messageExecStatus{newMessageExecState(msg3.SequenceNumber, msg3.MessageID, AlreadyExecuted)}, + skipGasPriceEstimator: true, + }, + { + name: "dst token price does not exist", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{msg1}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedStates: []messageExecStatus{newMessageExecState(msg1.SequenceNumber, msg1.MessageID, TokenNotInDestTokenPrices)}, + skipGasPriceEstimator: true, + }, + { + name: "src token price does not exist", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{msg1}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedStates: []messageExecStatus{newMessageExecState(msg1.SequenceNumber, msg1.MessageID, TokenNotInSrcTokenPrices)}, + skipGasPriceEstimator: true, + }, + { + name: "message with tokens is not executed if limit is reached", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{msg4}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(99), + destGasPrice: big.NewInt(1), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1e18)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1e18)}, + srcToDestTokens: map[cciptypes.Address]cciptypes.Address{ + srcNative: destNative, + }, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedStates: []messageExecStatus{newMessageExecState(msg4.SequenceNumber, msg4.MessageID, AggregateTokenLimitExceeded)}, + skipGasPriceEstimator: true, + }, + { + name: "message with tokens is not executed if limit is reached when inflight is full", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{msg5}, + inflight: []InflightInternalExecutionReport{{createdAt: time.Now(), messages: []cciptypes.EVM2EVMMessage{msg4.EVM2EVMMessage}}}, + inflightAggregateValue: big.NewInt(100), + tokenLimit: big.NewInt(50), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1e18)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1e18)}, + srcToDestTokens: map[cciptypes.Address]cciptypes.Address{ + srcNative: destNative, + }, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 1}, + expectedStates: []messageExecStatus{newMessageExecState(msg5.SequenceNumber, msg5.MessageID, AggregateTokenLimitExceeded)}, + skipGasPriceEstimator: true, + }, + { + name: "skip when nonce doesn't match chain value", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{msg1}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 123}, + expectedStates: []messageExecStatus{newMessageExecState(msg1.SequenceNumber, msg1.MessageID, InvalidNonce)}, + skipGasPriceEstimator: true, + }, + { + name: "skip when nonce not found", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{msg1}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{}, + expectedStates: []messageExecStatus{newMessageExecState(msg1.SequenceNumber, msg1.MessageID, MissingNonce)}, + skipGasPriceEstimator: true, + }, + { + name: "unordered messages", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 10, + FeeTokenAmount: big.NewInt(1e9), + Sender: sender1, + Nonce: 0, + GasLimit: big.NewInt(1), + Data: bytes.Repeat([]byte{'a'}, 1000), + FeeToken: srcNative, + MessageID: [32]byte{}, + }, + BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), + }, + }, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedSeqNrs: []ccip.ObservedMessage{{SeqNr: uint64(10)}}, + expectedStates: []messageExecStatus{ + newMessageExecState(10, [32]byte{}, AddedToBatch), + }, + }, + { + name: "unordered messages not blocked by nonce", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 9, + FeeTokenAmount: big.NewInt(1e9), + Sender: sender1, + Nonce: 5, + GasLimit: big.NewInt(1), + Data: bytes.Repeat([]byte{'a'}, 1000), + FeeToken: srcNative, + MessageID: [32]byte{}, + }, + BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), + }, + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 10, + FeeTokenAmount: big.NewInt(1e9), + Sender: sender1, + Nonce: 0, + GasLimit: big.NewInt(1), + Data: bytes.Repeat([]byte{'a'}, 1000), + FeeToken: srcNative, + MessageID: [32]byte{}, + }, + BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), + }, + }, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 3}, + expectedSeqNrs: []ccip.ObservedMessage{{SeqNr: uint64(10)}}, + expectedStates: []messageExecStatus{ + newMessageExecState(9, [32]byte{}, InvalidNonce), + newMessageExecState(10, [32]byte{}, AddedToBatch), + }, + }, + } + + bestEffortTestCases := []testCase{ + { + name: "skip when batch gas limit is reached", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 10, + FeeTokenAmount: big.NewInt(1e9), + Sender: sender1, + Nonce: 1, + GasLimit: big.NewInt(1), + Data: bytes.Repeat([]byte{'a'}, 1000), + FeeToken: srcNative, + MessageID: [32]byte{}, + }, + BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), + }, + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 11, + FeeTokenAmount: big.NewInt(1e9), + Sender: sender1, + Nonce: 2, + GasLimit: big.NewInt(math.MaxInt64), + Data: bytes.Repeat([]byte{'a'}, 1000), + FeeToken: srcNative, + MessageID: [32]byte{}, + }, + BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), + }, + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 12, + FeeTokenAmount: big.NewInt(1e9), + Sender: sender1, + Nonce: 3, + GasLimit: big.NewInt(1), + Data: bytes.Repeat([]byte{'a'}, 1000), + FeeToken: srcNative, + MessageID: [32]byte{}, + }, + BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), + }, + }, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedSeqNrs: []ccip.ObservedMessage{{SeqNr: uint64(10)}}, + expectedStates: []messageExecStatus{ + newMessageExecState(10, [32]byte{}, AddedToBatch), + newMessageExecState(11, [32]byte{}, InsufficientRemainingBatchGas), + newMessageExecState(12, [32]byte{}, InvalidNonce), + }, + }, + { + name: "some messages skipped after hitting max batch data len", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 10, + FeeTokenAmount: big.NewInt(1e9), + Sender: sender1, + Nonce: 1, + GasLimit: big.NewInt(1), + Data: bytes.Repeat([]byte{'a'}, 1000), + FeeToken: srcNative, + MessageID: [32]byte{}, + }, + BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), + }, + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 11, + FeeTokenAmount: big.NewInt(1e9), + Sender: sender1, + Nonce: 2, + GasLimit: big.NewInt(1), + Data: bytes.Repeat([]byte{'a'}, MaxDataLenPerBatch-500), // skipped from batch + FeeToken: srcNative, + MessageID: [32]byte{}, + }, + BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), + }, + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 12, + FeeTokenAmount: big.NewInt(1e9), + Sender: sender1, + Nonce: 3, + GasLimit: big.NewInt(1), + Data: bytes.Repeat([]byte{'a'}, 1000), + FeeToken: srcNative, + MessageID: [32]byte{}, + }, + BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), + }, + }, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedSeqNrs: []ccip.ObservedMessage{{SeqNr: uint64(10)}}, + expectedStates: []messageExecStatus{ + newMessageExecState(10, [32]byte{}, AddedToBatch), + newMessageExecState(11, [32]byte{}, InsufficientRemainingBatchDataLength), + newMessageExecState(12, [32]byte{}, InvalidNonce), + }, + }, + { + name: "unordered messages then ordered messages", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 9, + FeeTokenAmount: big.NewInt(1e9), + Sender: sender1, + Nonce: 0, + GasLimit: big.NewInt(1), + Data: bytes.Repeat([]byte{'a'}, 1000), + FeeToken: srcNative, + MessageID: [32]byte{}, + }, + BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), + }, + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: 10, + FeeTokenAmount: big.NewInt(1e9), + Sender: sender1, + Nonce: 5, + GasLimit: big.NewInt(1), + Data: bytes.Repeat([]byte{'a'}, 1000), + FeeToken: srcNative, + MessageID: [32]byte{}, + }, + BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), + }, + }, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 4}, + expectedSeqNrs: []ccip.ObservedMessage{{SeqNr: uint64(9)}, {SeqNr: uint64(10)}}, + expectedStates: []messageExecStatus{ + newMessageExecState(9, [32]byte{}, AddedToBatch), + newMessageExecState(10, [32]byte{}, AddedToBatch), + }, + }, + } + + specificZkOverflowTestCases := []testCase{ + { + name: "batch size is 1", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{zkMsg1, zkMsg2, zkMsg3}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedSeqNrs: []ccip.ObservedMessage{{SeqNr: zkMsg1.SequenceNumber}}, + expectedStates: []messageExecStatus{ + newMessageExecState(zkMsg1.SequenceNumber, zkMsg1.MessageID, AddedToBatch), + }, + statuschecker: func(m *mockstatuschecker.CCIPTransactionStatusChecker) { + m.Mock = mock.Mock{} // reset mock + m.On("CheckMessageStatus", mock.Anything, mock.Anything).Return([]types.TransactionStatus{}, -1, nil) + }, + }, + { + name: "snooze fatal message and return empty batch", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{zkMsg1}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedStates: []messageExecStatus{ + newMessageExecState(zkMsg1.SequenceNumber, zkMsg1.MessageID, TXMFatalStatus), + }, + statuschecker: func(m *mockstatuschecker.CCIPTransactionStatusChecker) { + m.Mock = mock.Mock{} // reset mock + m.On("CheckMessageStatus", mock.Anything, zkMsg1.MessageID.String()).Return([]types.TransactionStatus{types.Fatal}, 0, nil) + }, + skipGasPriceEstimator: true, + }, + { + name: "snooze fatal message and add next message to batch", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{zkMsg1, zkMsg2}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedSeqNrs: []ccip.ObservedMessage{{SeqNr: zkMsg2.SequenceNumber}}, + expectedStates: []messageExecStatus{ + newMessageExecState(zkMsg1.SequenceNumber, zkMsg1.MessageID, TXMFatalStatus), + newMessageExecState(zkMsg2.SequenceNumber, zkMsg2.MessageID, AddedToBatch), + }, + statuschecker: func(m *mockstatuschecker.CCIPTransactionStatusChecker) { + m.Mock = mock.Mock{} // reset mock + m.On("CheckMessageStatus", mock.Anything, zkMsg1.MessageID.String()).Return([]types.TransactionStatus{types.Fatal}, 0, nil) + m.On("CheckMessageStatus", mock.Anything, zkMsg2.MessageID.String()).Return([]types.TransactionStatus{}, -1, nil) + }, + }, + { + name: "all messages are fatal and batch is empty", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{zkMsg1, zkMsg2}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedStates: []messageExecStatus{ + newMessageExecState(zkMsg1.SequenceNumber, zkMsg1.MessageID, TXMFatalStatus), + newMessageExecState(zkMsg2.SequenceNumber, zkMsg2.MessageID, TXMFatalStatus), + }, + statuschecker: func(m *mockstatuschecker.CCIPTransactionStatusChecker) { + m.Mock = mock.Mock{} // reset mock + m.On("CheckMessageStatus", mock.Anything, zkMsg1.MessageID.String()).Return([]types.TransactionStatus{types.Fatal}, 0, nil) + m.On("CheckMessageStatus", mock.Anything, zkMsg2.MessageID.String()).Return([]types.TransactionStatus{types.Fatal}, 0, nil) + }, + skipGasPriceEstimator: true, + }, + { + name: "message batched when unconfirmed or failed", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{zkMsg1, zkMsg2}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedSeqNrs: []ccip.ObservedMessage{{SeqNr: zkMsg1.SequenceNumber}}, + expectedStates: []messageExecStatus{ + newMessageExecState(zkMsg1.SequenceNumber, zkMsg1.MessageID, AddedToBatch), + }, + statuschecker: func(m *mockstatuschecker.CCIPTransactionStatusChecker) { + m.Mock = mock.Mock{} // reset mock + m.On("CheckMessageStatus", mock.Anything, zkMsg1.MessageID.String()).Return([]types.TransactionStatus{types.Unconfirmed, types.Failed}, 1, nil) + }, + }, + { + name: "message snoozed when multiple statuses with fatal", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{zkMsg1, zkMsg2}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedSeqNrs: []ccip.ObservedMessage{{SeqNr: zkMsg2.SequenceNumber}}, + expectedStates: []messageExecStatus{ + newMessageExecState(zkMsg1.SequenceNumber, zkMsg1.MessageID, TXMFatalStatus), + newMessageExecState(zkMsg2.SequenceNumber, zkMsg2.MessageID, AddedToBatch), + }, + statuschecker: func(m *mockstatuschecker.CCIPTransactionStatusChecker) { + m.Mock = mock.Mock{} // reset mock + m.On("CheckMessageStatus", mock.Anything, zkMsg1.MessageID.String()).Return([]types.TransactionStatus{types.Unconfirmed, types.Failed, types.Fatal}, 2, nil) + m.On("CheckMessageStatus", mock.Anything, zkMsg2.MessageID.String()).Return([]types.TransactionStatus{}, -1, nil) + }, + }, + { + name: "txm return error for message", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{zkMsg1, zkMsg2}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedSeqNrs: []ccip.ObservedMessage{{SeqNr: zkMsg2.SequenceNumber}}, + expectedStates: []messageExecStatus{ + newMessageExecState(zkMsg1.SequenceNumber, zkMsg1.MessageID, TXMCheckError), + newMessageExecState(zkMsg2.SequenceNumber, zkMsg2.MessageID, AddedToBatch), + }, + statuschecker: func(m *mockstatuschecker.CCIPTransactionStatusChecker) { + m.Mock = mock.Mock{} // reset mock + m.On("CheckMessageStatus", mock.Anything, zkMsg1.MessageID.String()).Return([]types.TransactionStatus{}, -1, errors.New("dummy txm error")) + m.On("CheckMessageStatus", mock.Anything, zkMsg2.MessageID.String()).Return([]types.TransactionStatus{}, -1, nil) + }, + }, + { + name: "snooze message when inflight", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{zkMsg1}, + inflight: createInflight(zkMsg1), + inflightAggregateValue: zkMsg1.FeeTokenAmount, + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedStates: []messageExecStatus{ + newMessageExecState(zkMsg1.SequenceNumber, zkMsg1.MessageID, SkippedInflight), + }, + skipGasPriceEstimator: true, + }, + { + name: "snooze when not inflight but txm returns error", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{zkMsg1}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedStates: []messageExecStatus{ + newMessageExecState(zkMsg1.SequenceNumber, zkMsg1.MessageID, TXMCheckError), + }, + statuschecker: func(m *mockstatuschecker.CCIPTransactionStatusChecker) { + m.Mock = mock.Mock{} // reset mock + m.On("CheckMessageStatus", mock.Anything, zkMsg1.MessageID.String()).Return([]types.TransactionStatus{}, -1, errors.New("dummy txm error")) + }, + skipGasPriceEstimator: true, + }, + { + name: "snooze when not inflight but txm returns fatal status", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{zkMsg1}, + inflight: []InflightInternalExecutionReport{}, + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedStates: []messageExecStatus{ + newMessageExecState(zkMsg1.SequenceNumber, zkMsg1.MessageID, TXMFatalStatus), + }, + statuschecker: func(m *mockstatuschecker.CCIPTransactionStatusChecker) { + m.Mock = mock.Mock{} // reset mock + m.On("CheckMessageStatus", mock.Anything, zkMsg1.MessageID.String()).Return([]types.TransactionStatus{types.Unconfirmed, types.Failed, types.Fatal}, 2, nil) + }, + skipGasPriceEstimator: true, + }, + { + name: "snooze messages when inflight but batch valid messages", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{zkMsg1, zkMsg2, zkMsg3, zkMsg4}, + inflight: createInflight(zkMsg1, zkMsg2), + inflightAggregateValue: big.NewInt(0), + tokenLimit: big.NewInt(0), + destGasPrice: big.NewInt(10), + srcPrices: map[cciptypes.Address]*big.Int{srcNative: big.NewInt(1)}, + dstPrices: map[cciptypes.Address]*big.Int{destNative: big.NewInt(1)}, + offRampNoncesBySender: map[cciptypes.Address]uint64{sender1: 0}, + expectedSeqNrs: []ccip.ObservedMessage{{SeqNr: zkMsg3.SequenceNumber}}, + expectedStates: []messageExecStatus{ + newMessageExecState(zkMsg1.SequenceNumber, zkMsg1.MessageID, SkippedInflight), + newMessageExecState(zkMsg2.SequenceNumber, zkMsg2.MessageID, SkippedInflight), + newMessageExecState(zkMsg3.SequenceNumber, zkMsg3.MessageID, AddedToBatch), + }, + statuschecker: func(m *mockstatuschecker.CCIPTransactionStatusChecker) { + m.Mock = mock.Mock{} // reset mock + m.On("CheckMessageStatus", mock.Anything, zkMsg3.MessageID.String()).Return([]types.TransactionStatus{}, -1, nil) + }, + skipGasPriceEstimator: false, + }, + } + + t.Run("BestEffortBatchingStrategy", func(t *testing.T) { + strategy := &BestEffortBatchingStrategy{} + runBatchingStrategyTests(t, strategy, 1_000_000, append(testCases, bestEffortTestCases...)) + }) + + t.Run("ZKOverflowBatchingStrategy", func(t *testing.T) { + mockedStatusChecker := mockstatuschecker.NewCCIPTransactionStatusChecker(t) + strategy := &ZKOverflowBatchingStrategy{ + statuschecker: mockedStatusChecker, + } + runBatchingStrategyTests(t, strategy, 1_000_000, append(testCases, specificZkOverflowTestCases...)) + }) +} + +// Function to set up and run tests for a given batching strategy +func runBatchingStrategyTests(t *testing.T, strategy BatchingStrategy, availableGas uint64, testCases []testCase) { + destNative := ccipcalc.HexToAddress("0xb") + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + lggr := logger.TestLogger(t) + + gasPriceEstimator := prices.NewMockGasPriceEstimatorExec(t) + if !tc.skipGasPriceEstimator { + if tc.expectedSeqNrs != nil { + gasPriceEstimator.On("EstimateMsgCostUSD", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(big.NewInt(0), nil) + } else { + gasPriceEstimator.On("EstimateMsgCostUSD", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(big.NewInt(0), errors.New("error")) + } + } + + // default case for ZKOverflowBatchingStrategy + if strategyType := reflect.TypeOf(strategy); tc.statuschecker == nil && strategyType == reflect.TypeOf(&ZKOverflowBatchingStrategy{}) { + strategy.(*ZKOverflowBatchingStrategy).statuschecker.(*mockstatuschecker.CCIPTransactionStatusChecker).On("CheckMessageStatus", mock.Anything, mock.Anything).Return([]types.TransactionStatus{}, -1, nil) + } + + // Mock calls to TXM + if tc.statuschecker != nil { + tc.statuschecker(strategy.(*ZKOverflowBatchingStrategy).statuschecker.(*mockstatuschecker.CCIPTransactionStatusChecker)) + } + + batchContext := &BatchContext{ + report: commitReportWithSendRequests{sendRequestsWithMeta: tc.reqs}, + inflight: tc.inflight, + inflightAggregateValue: tc.inflightAggregateValue, + lggr: lggr, + availableDataLen: MaxDataLenPerBatch, + availableGas: availableGas, + expectedNonces: make(map[cciptypes.Address]uint64), + sendersNonce: tc.offRampNoncesBySender, + sourceTokenPricesUSD: tc.srcPrices, + destTokenPricesUSD: tc.dstPrices, + gasPrice: tc.destGasPrice, + sourceToDestToken: tc.srcToDestTokens, + aggregateTokenLimit: tc.tokenLimit, + tokenDataRemainingDuration: 5 * time.Second, + tokenDataWorker: tokendata.NewBackgroundWorker(map[cciptypes.Address]tokendata.Reader{}, 10, 5*time.Second, time.Hour), + gasPriceEstimator: gasPriceEstimator, + destWrappedNative: destNative, + offchainConfig: cciptypes.ExecOffchainConfig{ + DestOptimisticConfirmations: 1, + BatchGasLimit: 300_000, + RelativeBoostPerWaitHour: 1, + }, + } + + seqNrs, execStates := strategy.BuildBatch(context.Background(), batchContext) + + runAssertions(t, tc, seqNrs, execStates) + }) + } +} + +// Utility function to run common assertions +func runAssertions(t *testing.T, tc testCase, seqNrs []ccip.ObservedMessage, execStates []messageExecStatus) { + if tc.expectedSeqNrs == nil { + assert.Len(t, seqNrs, 0) + } else { + assert.Equal(t, tc.expectedSeqNrs, seqNrs) + } + + if tc.expectedStates == nil { + assert.Len(t, execStates, 0) + } else { + assert.Equal(t, tc.expectedStates, execStates) + } +} + +func createTestMessage(seqNr uint64, sender cciptypes.Address, nonce uint64, feeToken cciptypes.Address, feeAmount *big.Int, executed bool, data []byte) cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta { + return cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: seqNr, + FeeTokenAmount: feeAmount, + Sender: sender, + Nonce: nonce, + GasLimit: big.NewInt(1), + Strict: false, + Receiver: "", + Data: data, + TokenAmounts: nil, + FeeToken: feeToken, + MessageID: generateMessageIDFromInt(seqNr), + }, + BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), + Executed: executed, + } +} + +func generateMessageIDFromInt(input uint64) [32]byte { + var messageID [32]byte + binary.LittleEndian.PutUint32(messageID[:], uint32(input)) + return messageID +} + +func createInflight(msgs ...cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) []InflightInternalExecutionReport { + reports := make([]InflightInternalExecutionReport, len(msgs)) + + for i, msg := range msgs { + reports[i] = InflightInternalExecutionReport{ + messages: []cciptypes.EVM2EVMMessage{msg.EVM2EVMMessage}, + createdAt: msg.BlockTimestamp, + } + } + + return reports +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/factory.go b/core/services/ocr2/plugins/ccip/ccipexec/factory.go new file mode 100644 index 0000000000..97caf2e719 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/factory.go @@ -0,0 +1,164 @@ +package ccipexec + +import ( + "context" + "fmt" + "sync" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +type ExecutionReportingPluginFactory struct { + // Config derived from job specs and does not change between instances. + config ExecutionPluginStaticConfig + + destPriceRegReader ccipdata.PriceRegistryReader + destPriceRegAddr cciptypes.Address + readersMu *sync.Mutex +} + +func NewExecutionReportingPluginFactory(config ExecutionPluginStaticConfig) *ExecutionReportingPluginFactory { + return &ExecutionReportingPluginFactory{ + config: config, + readersMu: &sync.Mutex{}, + + // the fields below are initially empty and populated on demand + destPriceRegReader: nil, + destPriceRegAddr: "", + } +} + +func (rf *ExecutionReportingPluginFactory) UpdateDynamicReaders(ctx context.Context, newPriceRegAddr cciptypes.Address) error { + rf.readersMu.Lock() + defer rf.readersMu.Unlock() + // TODO: Investigate use of Close() to cleanup. + // TODO: a true price registry upgrade on an existing lane may want some kind of start block in its config? Right now we + // essentially assume that plugins don't care about historical price reg logs. + if rf.destPriceRegAddr == newPriceRegAddr { + // No-op + return nil + } + // Close old reader (if present) and open new reader if address changed. + if rf.destPriceRegReader != nil { + if err := rf.destPriceRegReader.Close(); err != nil { + return err + } + } + + destPriceRegistryReader, err := rf.config.priceRegistryProvider.NewPriceRegistryReader(context.Background(), newPriceRegAddr) + if err != nil { + return err + } + rf.destPriceRegReader = destPriceRegistryReader + rf.destPriceRegAddr = newPriceRegAddr + return nil +} + +type reportingPluginAndInfo struct { + plugin types.ReportingPlugin + pluginInfo types.ReportingPluginInfo +} + +// NewReportingPlugin registers a new ReportingPlugin +func (rf *ExecutionReportingPluginFactory) NewReportingPlugin(config types.ReportingPluginConfig) (types.ReportingPlugin, types.ReportingPluginInfo, error) { + initialRetryDelay := rf.config.newReportingPluginRetryConfig.InitialDelay + maxDelay := rf.config.newReportingPluginRetryConfig.MaxDelay + + pluginAndInfo, err := ccipcommon.RetryUntilSuccess(rf.NewReportingPluginFn(config), initialRetryDelay, maxDelay) + if err != nil { + return nil, types.ReportingPluginInfo{}, err + } + return pluginAndInfo.plugin, pluginAndInfo.pluginInfo, err +} + +// NewReportingPluginFn implements the NewReportingPlugin logic. It is defined as a function so that it can easily be +// retried via RetryUntilSuccess. NewReportingPlugin must return successfully in order for the Exec plugin to function, +// hence why we can only keep retrying it until it succeeds. +func (rf *ExecutionReportingPluginFactory) NewReportingPluginFn(config types.ReportingPluginConfig) func() (reportingPluginAndInfo, error) { + return func() (reportingPluginAndInfo, error) { + ctx := context.Background() // todo: consider setting a timeout + + destPriceRegistry, destWrappedNative, err := rf.config.offRampReader.ChangeConfig(ctx, config.OnchainConfig, config.OffchainConfig) + if err != nil { + return reportingPluginAndInfo{}, err + } + + // Open dynamic readers + err = rf.UpdateDynamicReaders(ctx, destPriceRegistry) + if err != nil { + return reportingPluginAndInfo{}, err + } + + offchainConfig, err := rf.config.offRampReader.OffchainConfig(ctx) + if err != nil { + return reportingPluginAndInfo{}, fmt.Errorf("get offchain config from offramp: %w", err) + } + + gasPriceEstimator, err := rf.config.offRampReader.GasPriceEstimator(ctx) + if err != nil { + return reportingPluginAndInfo{}, fmt.Errorf("get gas price estimator from offramp: %w", err) + } + + onchainConfig, err := rf.config.offRampReader.OnchainConfig(ctx) + if err != nil { + return reportingPluginAndInfo{}, fmt.Errorf("get onchain config from offramp: %w", err) + } + + batchingStrategy, err := NewBatchingStrategy(offchainConfig.BatchingStrategyID, rf.config.txmStatusChecker) + if err != nil { + return reportingPluginAndInfo{}, fmt.Errorf("get batching strategy: %w", err) + } + + msgVisibilityInterval := offchainConfig.MessageVisibilityInterval.Duration() + if msgVisibilityInterval.Seconds() == 0 { + rf.config.lggr.Info("MessageVisibilityInterval not set, falling back to PermissionLessExecutionThreshold") + msgVisibilityInterval = onchainConfig.PermissionLessExecutionThresholdSeconds + } + rf.config.lggr.Infof("MessageVisibilityInterval set to: %s", msgVisibilityInterval) + + lggr := rf.config.lggr.Named("ExecutionReportingPlugin") + plugin := &ExecutionReportingPlugin{ + F: config.F, + lggr: lggr, + offchainConfig: offchainConfig, + tokenDataWorker: rf.config.tokenDataWorker, + gasPriceEstimator: gasPriceEstimator, + sourcePriceRegistryProvider: rf.config.sourcePriceRegistryProvider, + sourcePriceRegistryLock: sync.RWMutex{}, + sourceWrappedNativeToken: rf.config.sourceWrappedNativeToken, + onRampReader: rf.config.onRampReader, + commitStoreReader: rf.config.commitStoreReader, + destPriceRegistry: rf.destPriceRegReader, + destWrappedNative: destWrappedNative, + onchainConfig: onchainConfig, + offRampReader: rf.config.offRampReader, + tokenPoolBatchedReader: rf.config.tokenPoolBatchedReader, + inflightReports: newInflightExecReportsContainer(offchainConfig.InflightCacheExpiry.Duration()), + commitRootsCache: cache.NewCommitRootsCache(lggr, rf.config.commitStoreReader, msgVisibilityInterval, offchainConfig.RootSnoozeTime.Duration()), + metricsCollector: rf.config.metricsCollector, + chainHealthcheck: rf.config.chainHealthcheck, + batchingStrategy: batchingStrategy, + } + + pluginInfo := types.ReportingPluginInfo{ + Name: "CCIPExecution", + // Setting this to false saves on calldata since OffRamp doesn't require agreement between NOPs + // (OffRamp is only able to execute committed messages). + UniqueReports: false, + Limits: types.ReportingPluginLimits{ + MaxObservationLength: ccip.MaxObservationLength, + MaxReportLength: MaxExecutionReportLength, + }, + } + + return reportingPluginAndInfo{plugin, pluginInfo}, nil + } +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/factory_test.go b/core/services/ocr2/plugins/ccip/ccipexec/factory_test.go new file mode 100644 index 0000000000..7bbb9be0c6 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/factory_test.go @@ -0,0 +1,67 @@ +package ccipexec + +import ( + "errors" + "testing" + "time" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + ccipdataprovidermocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" +) + +// Assert that NewReportingPlugin keeps retrying until it succeeds. +// +// NewReportingPlugin makes several calls (e.g. OffRampReader.ChangeConfig()) that can fail. We use mocks to cause the +// first call to each of these functions to fail, then all subsequent calls succeed. We assert that NewReportingPlugin +// retries a sufficient number of times to get through the transient errors and eventually succeed. +func TestNewReportingPluginRetriesUntilSuccess(t *testing.T) { + execConfig := ExecutionPluginStaticConfig{} + + // For this unit test, ensure that there is no delay between retries + execConfig.newReportingPluginRetryConfig = ccipdata.RetryConfig{ + InitialDelay: 0 * time.Nanosecond, + MaxDelay: 0 * time.Nanosecond, + } + + // Set up the OffRampReader mock + mockOffRampReader := new(mocks.OffRampReader) + + // The first call is set to return an error, the following calls return a nil error + mockOffRampReader.On("ChangeConfig", mock.Anything, mock.Anything, mock.Anything).Return(ccip.Address(""), ccip.Address(""), errors.New("")).Once() + mockOffRampReader.On("ChangeConfig", mock.Anything, mock.Anything, mock.Anything).Return(ccip.Address("addr1"), ccip.Address("addr2"), nil).Times(5) + + mockOffRampReader.On("OffchainConfig", mock.Anything).Return(ccip.ExecOffchainConfig{}, errors.New("")).Once() + mockOffRampReader.On("OffchainConfig", mock.Anything).Return(ccip.ExecOffchainConfig{}, nil).Times(3) + + mockOffRampReader.On("GasPriceEstimator", mock.Anything).Return(nil, errors.New("")).Once() + mockOffRampReader.On("GasPriceEstimator", mock.Anything).Return(nil, nil).Times(2) + + mockOffRampReader.On("OnchainConfig", mock.Anything).Return(ccip.ExecOnchainConfig{}, errors.New("")).Once() + mockOffRampReader.On("OnchainConfig", mock.Anything).Return(ccip.ExecOnchainConfig{}, nil).Times(1) + + execConfig.offRampReader = mockOffRampReader + + // Set up the PriceRegistry mock + priceRegistryProvider := new(ccipdataprovidermocks.PriceRegistry) + priceRegistryProvider.On("NewPriceRegistryReader", mock.Anything, mock.Anything).Return(nil, errors.New("")).Once() + priceRegistryProvider.On("NewPriceRegistryReader", mock.Anything, mock.Anything).Return(nil, nil).Once() + execConfig.priceRegistryProvider = priceRegistryProvider + + execConfig.lggr, _ = logger.NewLogger() + + factory := NewExecutionReportingPluginFactory(execConfig) + reportingConfig := types.ReportingPluginConfig{} + reportingConfig.OnchainConfig = []byte{1, 2, 3} + reportingConfig.OffchainConfig = []byte{1, 2, 3} + + // Assert that NewReportingPlugin succeeds despite many transient internal failures (mocked out above) + _, _, err := factory.NewReportingPlugin(reportingConfig) + assert.Equal(t, nil, err) +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/gashelpers.go b/core/services/ocr2/plugins/ccip/ccipexec/gashelpers.go new file mode 100644 index 0000000000..7e208296c5 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/gashelpers.go @@ -0,0 +1,83 @@ +package ccipexec + +import ( + "math" + "math/big" + "time" +) + +const ( + EvmAddressLengthBytes = 20 + EvmWordBytes = 32 + CalldataGasPerByte = 16 + TokenAdminRegistryWarmupCost = 2_500 + TokenAdminRegistryPoolLookupGas = 100 + // WARM_ACCESS_COST TokenAdminRegistry + 700 + // CALL cost for TokenAdminRegistry + 2_100 // COLD_SLOAD_COST loading the pool address + SupportsInterfaceCheck = 2600 + // because the receiver will be untouched initially + 30_000*3 // supportsInterface of ERC165Checker library performs 3 static-calls of 30k gas each + PerTokenOverheadGas = TokenAdminRegistryPoolLookupGas + + SupportsInterfaceCheck + + 200_000 + // releaseOrMint using callWithExactGas + 50_000 // transfer using callWithExactGas + RateLimiterOverheadGas = 2_100 + // COLD_SLOAD_COST for accessing token bucket + 5_000 // SSTORE_RESET_GAS for updating & decreasing token bucket + ConstantMessagePartBytes = 10 * 32 // A message consists of 10 abi encoded fields 32B each (after encoding) + ExecutionStateProcessingOverheadGas = 2_100 + // COLD_SLOAD_COST for first reading the state + 20_000 + // SSTORE_SET_GAS for writing from 0 (untouched) to non-zero (in-progress) + 100 //# SLOAD_GAS = WARM_STORAGE_READ_COST for rewriting from non-zero (in-progress) to non-zero (success/failure) +) + +// return the size of bytes for msg tokens +func bytesForMsgTokens(numTokens int) int { + // token address (address) + token amount (uint256) + return (EvmAddressLengthBytes + EvmWordBytes) * numTokens +} + +// Offchain: we compute the max overhead gas to determine msg executability. +func overheadGas(dataLength, numTokens int) uint64 { + messageBytes := ConstantMessagePartBytes + + bytesForMsgTokens(numTokens) + + dataLength + + messageCallDataGas := uint64(messageBytes * CalldataGasPerByte) + + // Rate limiter only limits value in tokens. It's not called if there are no + // tokens in the message. The same goes for the admin registry, it's only loaded + // if there are tokens, and it's only loaded once. + rateLimiterOverhead := uint64(0) + adminRegistryOverhead := uint64(0) + if numTokens >= 1 { + rateLimiterOverhead = RateLimiterOverheadGas + adminRegistryOverhead = TokenAdminRegistryWarmupCost + } + + return messageCallDataGas + + ExecutionStateProcessingOverheadGas + + SupportsInterfaceCheck + + adminRegistryOverhead + + rateLimiterOverhead + + PerTokenOverheadGas*uint64(numTokens) +} + +func maxGasOverHeadGas(numMsgs, dataLength, numTokens int) uint64 { + merkleProofBytes := (math.Ceil(math.Log2(float64(numMsgs))))*32 + (1+2)*32 // only ever one outer root hash + merkleGasShare := uint64(merkleProofBytes * CalldataGasPerByte) + + return overheadGas(dataLength, numTokens) + merkleGasShare +} + +// waitBoostedFee boosts the given fee according to the time passed since the msg was sent. +// RelativeBoostPerWaitHour is used to normalize the time diff, +// it makes our loss taking "smooth" and gives us time to react without a hard deadline. +// At the same time, messages that are slightly underpaid will start going through after waiting for a little bit. +// +// wait_boosted_fee(m) = (1 + (now - m.send_time).hours * RELATIVE_BOOST_PER_WAIT_HOUR) * fee(m) +func waitBoostedFee(waitTime time.Duration, fee *big.Int, relativeBoostPerWaitHour float64) *big.Int { + k := 1.0 + waitTime.Hours()*relativeBoostPerWaitHour + + boostedFee := big.NewFloat(0).Mul(big.NewFloat(k), new(big.Float).SetInt(fee)) + res, _ := boostedFee.Int(nil) + + return res +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/gashelpers_test.go b/core/services/ocr2/plugins/ccip/ccipexec/gashelpers_test.go new file mode 100644 index 0000000000..15607cc310 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/gashelpers_test.go @@ -0,0 +1,179 @@ +package ccipexec + +import ( + "math/big" + "reflect" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestOverheadGas(t *testing.T) { + // Only Data and TokenAmounts are used from the messages + // And only the length is used so the contents doesn't matter. + tests := []struct { + dataLength int + numberOfTokens int + want uint64 + }{ + { + dataLength: 0, + numberOfTokens: 0, + want: 119920, + }, + { + dataLength: len([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}), + numberOfTokens: 1, + want: 475948, + }, + } + + for _, tc := range tests { + got := overheadGas(tc.dataLength, tc.numberOfTokens) + if !reflect.DeepEqual(tc.want, got) { + t.Fatalf("expected: %v, got: %v", tc.want, got) + } + } +} + +func TestMaxGasOverHeadGas(t *testing.T) { + // Only Data and TokenAmounts are used from the messages + // And only the length is used so the contents doesn't matter. + tests := []struct { + numMsgs int + dataLength int + numberOfTokens int + want uint64 + }{ + { + numMsgs: 6, + dataLength: 0, + numberOfTokens: 0, + want: 122992, + }, + { + numMsgs: 3, + dataLength: len([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}), + numberOfTokens: 1, + want: 478508, + }, + } + + for _, tc := range tests { + got := maxGasOverHeadGas(tc.numMsgs, tc.dataLength, tc.numberOfTokens) + if !reflect.DeepEqual(tc.want, got) { + t.Fatalf("expected: %v, got: %v", tc.want, got) + } + } +} + +func TestWaitBoostedFee(t *testing.T) { + tests := []struct { + name string + sendTimeDiff time.Duration + fee *big.Int + diff *big.Int + relativeBoostPerWaitHour float64 + }{ + { + "wait 10s", + time.Second * 10, + big.NewInt(6e18), // Fee: 6 LINK + + big.NewInt(1166666666665984), // Boost: 0.01 LINK + 0.07, + }, + { + "wait 5m", + time.Minute * 5, + big.NewInt(6e18), // Fee: 6 LINK + big.NewInt(35e15), // Boost: 0.35 LINK + 0.07, + }, + { + "wait 7m", + time.Minute * 7, + big.NewInt(6e18), // Fee: 6 LINK + big.NewInt(49e15), // Boost: 0.49 LINK + 0.07, + }, + { + "wait 12m", + time.Minute * 12, + big.NewInt(6e18), // Fee: 6 LINK + big.NewInt(84e15), // Boost: 0.84 LINK + 0.07, + }, + { + "wait 25m", + time.Minute * 25, + big.NewInt(6e18), // Fee: 6 LINK + big.NewInt(174999999999998976), // Boost: 1.75 LINK + 0.07, + }, + { + "wait 1h", + time.Hour * 1, + big.NewInt(6e18), // Fee: 6 LINK + big.NewInt(420e15), // Boost: 4.2 LINK + 0.07, + }, + { + "wait 5h", + time.Hour * 5, + big.NewInt(6e18), // Fee: 6 LINK + big.NewInt(2100000000000001024), // Boost: 21LINK + 0.07, + }, + { + "wait 24h", + time.Hour * 24, + big.NewInt(6e18), // Fee: 6 LINK + big.NewInt(0).Mul(big.NewInt(10), big.NewInt(1008e15)), // Boost: 100LINK + 0.07, + }, + { + "high boost wait 10s", + time.Second * 10, + big.NewInt(5e18), + big.NewInt(9722222222222336), // 1e16 + 0.7, + }, + { + "high boost wait 5m", + time.Minute * 5, + big.NewInt(5e18), + big.NewInt(291666666666667008), // 1e18 + 0.7, + }, + { + "high boost wait 25m", + time.Minute * 25, + big.NewInt(5e18), + big.NewInt(1458333333333334016), // 1e19 + 0.7, + }, + { + "high boost wait 5h", + time.Hour * 5, + big.NewInt(5e18), + big.NewInt(0).Mul(big.NewInt(10), big.NewInt(175e16)), // 1e20 + 0.7, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + boosted := waitBoostedFee(tc.sendTimeDiff, tc.fee, tc.relativeBoostPerWaitHour) + diff := big.NewInt(0).Sub(boosted, tc.fee) + assert.Equal(t, diff, tc.diff) + // we check that the actual diff is approximately equals to expected diff, + // as we might get slightly different results locally vs. CI therefore normal Equal() would be unstable + //diffUpperLimit := big.NewInt(0).Add(tc.diff, big.NewInt(1e9)) + //diffLowerLimit := big.NewInt(0).Add(tc.diff, big.NewInt(-1e9)) + //require.Equalf(t, -1, diff.Cmp(diffUpperLimit), "actual diff (%s) is larger than expected (%s)", diff.String(), diffUpperLimit.String()) + //require.Equal(t, 1, diff.Cmp(diffLowerLimit), "actual diff (%s) is smaller than expected (%s)", diff.String(), diffLowerLimit.String()) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/helpers.go b/core/services/ocr2/plugins/ccip/ccipexec/helpers.go new file mode 100644 index 0000000000..46df7d793b --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/helpers.go @@ -0,0 +1,53 @@ +package ccipexec + +import ( + mapset "github.com/deckarep/golang-set/v2" + "github.com/pkg/errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" +) + +// helper struct to hold the commitReport and the related send requests +type commitReportWithSendRequests struct { + commitReport cciptypes.CommitStoreReport + sendRequestsWithMeta []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta +} + +func (r *commitReportWithSendRequests) validate() error { + // make sure that number of messages is the expected + if exp := int(r.commitReport.Interval.Max - r.commitReport.Interval.Min + 1); len(r.sendRequestsWithMeta) != exp { + return errors.Errorf( + "unexpected missing sendRequestsWithMeta in committed root %x have %d want %d", r.commitReport.MerkleRoot, len(r.sendRequestsWithMeta), exp) + } + + return nil +} + +// uniqueSenders returns slice of unique senders based on the send requests. Order is preserved based on the order of the send requests (by sequence number). +func (r *commitReportWithSendRequests) uniqueSenders() []cciptypes.Address { + orderedUniqueSenders := make([]cciptypes.Address, 0, len(r.sendRequestsWithMeta)) + visitedSenders := mapset.NewSet[cciptypes.Address]() + + for _, req := range r.sendRequestsWithMeta { + if !visitedSenders.Contains(req.Sender) { + orderedUniqueSenders = append(orderedUniqueSenders, req.Sender) + visitedSenders.Add(req.Sender) + } + } + return orderedUniqueSenders +} + +func (r *commitReportWithSendRequests) allRequestsAreExecutedAndFinalized() bool { + for _, req := range r.sendRequestsWithMeta { + if !req.Executed || !req.Finalized { + return false + } + } + return true +} + +// checks if the send request fits the commit report interval +func (r *commitReportWithSendRequests) sendReqFits(sendReq cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) bool { + return sendReq.SequenceNumber >= r.commitReport.Interval.Min && + sendReq.SequenceNumber <= r.commitReport.Interval.Max +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/helpers_test.go b/core/services/ocr2/plugins/ccip/ccipexec/helpers_test.go new file mode 100644 index 0000000000..daa54fd242 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/helpers_test.go @@ -0,0 +1,96 @@ +package ccipexec + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" +) + +func Test_CommitReportWithSendRequests_uniqueSenders(t *testing.T) { + messageFn := func(address cciptypes.Address) cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta { + return cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{EVM2EVMMessage: cciptypes.EVM2EVMMessage{Sender: address}} + } + + tests := []struct { + name string + sendRequests []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta + expUniqueSenders int + expSendersOrder []cciptypes.Address + }{ + { + name: "all unique senders", + sendRequests: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + messageFn(cciptypes.Address(utils.RandomAddress().String())), + messageFn(cciptypes.Address(utils.RandomAddress().String())), + messageFn(cciptypes.Address(utils.RandomAddress().String())), + }, + expUniqueSenders: 3, + }, + { + name: "some senders are the same", + sendRequests: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + messageFn("0x1"), + messageFn("0x2"), + messageFn("0x1"), + messageFn("0x2"), + messageFn("0x3"), + }, + expUniqueSenders: 3, + expSendersOrder: []cciptypes.Address{ + cciptypes.Address("0x1"), + cciptypes.Address("0x2"), + cciptypes.Address("0x3"), + }, + }, + { + name: "all senders are the same", + sendRequests: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + messageFn("0x1"), + messageFn("0x1"), + messageFn("0x1"), + }, + expUniqueSenders: 1, + expSendersOrder: []cciptypes.Address{ + cciptypes.Address("0x1"), + }, + }, + { + name: "order is preserved", + sendRequests: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + messageFn("0x3"), + messageFn("0x1"), + messageFn("0x3"), + messageFn("0x2"), + messageFn("0x2"), + messageFn("0x1"), + }, + expUniqueSenders: 3, + expSendersOrder: []cciptypes.Address{ + cciptypes.Address("0x3"), + cciptypes.Address("0x1"), + cciptypes.Address("0x2"), + }, + }, + { + name: "no senders", + sendRequests: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{}, + expUniqueSenders: 0, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rep := commitReportWithSendRequests{sendRequestsWithMeta: tt.sendRequests} + uniqueSenders := rep.uniqueSenders() + + assert.Len(t, uniqueSenders, tt.expUniqueSenders) + if tt.expSendersOrder != nil { + assert.Equal(t, tt.expSendersOrder, uniqueSenders) + } + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/inflight.go b/core/services/ocr2/plugins/ccip/ccipexec/inflight.go new file mode 100644 index 0000000000..c76bfdf778 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/inflight.go @@ -0,0 +1,82 @@ +package ccipexec + +import ( + "sync" + "time" + + "github.com/pkg/errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +// InflightInternalExecutionReport serves the same purpose as InflightCommitReport +// see the comment on that struct for context. +type InflightInternalExecutionReport struct { + createdAt time.Time + messages []cciptypes.EVM2EVMMessage +} + +// inflightExecReportsContainer holds existing inflight reports. +// it provides a thread-safe access as it is called from multiple goroutines, +// e.g. reporting and transmission protocols. +type inflightExecReportsContainer struct { + locker sync.RWMutex + reports []InflightInternalExecutionReport + + cacheExpiry time.Duration +} + +func newInflightExecReportsContainer(inflightCacheExpiry time.Duration) *inflightExecReportsContainer { + return &inflightExecReportsContainer{ + locker: sync.RWMutex{}, + reports: make([]InflightInternalExecutionReport, 0), + cacheExpiry: inflightCacheExpiry, + } +} + +func (container *inflightExecReportsContainer) getAll() []InflightInternalExecutionReport { + container.locker.RLock() + defer container.locker.RUnlock() + + reports := make([]InflightInternalExecutionReport, len(container.reports)) + copy(reports[:], container.reports[:]) + + return reports +} + +func (container *inflightExecReportsContainer) expire(lggr logger.Logger) { + container.locker.Lock() + defer container.locker.Unlock() + // Reap old inflight txs and check if any messages in the report are inflight. + var stillInFlight []InflightInternalExecutionReport + for _, report := range container.reports { + if time.Since(report.createdAt) > container.cacheExpiry { + // Happy path: inflight report was successfully transmitted onchain, we remove it from inflight and onchain state reflects inflight. + // Sad path: inflight report reverts onchain, we remove it from inflight, onchain state does not reflect the change so we retry. + lggr.Infow("Inflight report expired", "messages", report.messages) + } else { + stillInFlight = append(stillInFlight, report) + } + } + container.reports = stillInFlight +} + +func (container *inflightExecReportsContainer) add(lggr logger.Logger, messages []cciptypes.EVM2EVMMessage) error { + container.locker.Lock() + defer container.locker.Unlock() + + for _, report := range container.reports { + if (len(report.messages) > 0) && (report.messages[0].SequenceNumber == messages[0].SequenceNumber) { + return errors.Errorf("report is already in flight") + } + } + + // Otherwise not already in flight, add it. + lggr.Info("Inflight report added") + container.reports = append(container.reports, InflightInternalExecutionReport{ + createdAt: time.Now(), + messages: messages, + }) + return nil +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/inflight_test.go b/core/services/ocr2/plugins/ccip/ccipexec/inflight_test.go new file mode 100644 index 0000000000..2a91457ef4 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/inflight_test.go @@ -0,0 +1,42 @@ +package ccipexec + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestInflightReportsContainer_add(t *testing.T) { + lggr := logger.TestLogger(t) + container := newInflightExecReportsContainer(time.Second) + + err := container.add(lggr, []cciptypes.EVM2EVMMessage{ + {SequenceNumber: 1}, {SequenceNumber: 2}, {SequenceNumber: 3}, + }) + require.NoError(t, err) + err = container.add(lggr, []cciptypes.EVM2EVMMessage{ + {SequenceNumber: 1}, + }) + require.Error(t, err) + require.Equal(t, "report is already in flight", err.Error()) + require.Equal(t, 1, len(container.getAll())) +} + +func TestInflightReportsContainer_expire(t *testing.T) { + lggr := logger.TestLogger(t) + container := newInflightExecReportsContainer(time.Second) + + err := container.add(lggr, []cciptypes.EVM2EVMMessage{ + {SequenceNumber: 1}, {SequenceNumber: 2}, {SequenceNumber: 3}, + }) + require.NoError(t, err) + container.reports[0].createdAt = time.Now().Add(-time.Second * 5) + require.Equal(t, 1, len(container.getAll())) + + container.expire(lggr) + require.Equal(t, 0, len(container.getAll())) +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/initializers.go b/core/services/ocr2/plugins/ccip/ccipexec/initializers.go new file mode 100644 index 0000000000..7826f6058f --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/initializers.go @@ -0,0 +1,228 @@ +package ccipexec + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "time" + + "github.com/smartcontractkit/chainlink-common/pkg/types" + + "github.com/Masterminds/semver/v3" + "go.uber.org/multierr" + + libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" + + commonlogger "github.com/smartcontractkit/chainlink-common/pkg/logger" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/statuschecker" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/observability" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/oraclelib" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/promwrapper" +) + +var ( + // tokenDataWorkerTimeout defines 1) The timeout while waiting for a bg call to the token data 3P provider. + // 2) When a client requests token data and does not specify a timeout this value is used as a default. + // 5 seconds is a reasonable value for a timeout. + // At this moment, minimum OCR Delta Round is set to 30s and deltaGrace to 5s. Based on this configuration + // 5s for token data worker timeout is a reasonable default. + tokenDataWorkerTimeout = 5 * time.Second + // tokenDataWorkerNumWorkers is the number of workers that will be processing token data in parallel. + tokenDataWorkerNumWorkers = 5 +) + +var defaultNewReportingPluginRetryConfig = ccipdata.RetryConfig{InitialDelay: time.Second, MaxDelay: 5 * time.Minute} + +func NewExecServices(ctx context.Context, lggr logger.Logger, jb job.Job, srcProvider types.CCIPExecProvider, dstProvider types.CCIPExecProvider, srcChainID int64, dstChainID int64, new bool, argsNoPlugin libocr2.OCR2OracleArgs, logError func(string)) ([]job.ServiceCtx, error) { + if jb.OCR2OracleSpec == nil { + return nil, fmt.Errorf("spec is nil") + } + spec := jb.OCR2OracleSpec + var pluginConfig ccipconfig.ExecPluginJobSpecConfig + err := json.Unmarshal(spec.PluginConfig.Bytes(), &pluginConfig) + if err != nil { + return nil, err + } + + offRampAddress := ccipcalc.HexToAddress(spec.ContractID) + offRampReader, err := dstProvider.NewOffRampReader(ctx, offRampAddress) + if err != nil { + return nil, fmt.Errorf("create offRampReader: %w", err) + } + + offRampConfig, err := offRampReader.GetStaticConfig(ctx) + if err != nil { + return nil, fmt.Errorf("get offRamp static config: %w", err) + } + + srcChainSelector := offRampConfig.SourceChainSelector + dstChainSelector := offRampConfig.ChainSelector + onRampReader, err := srcProvider.NewOnRampReader(ctx, offRampConfig.OnRamp, srcChainSelector, dstChainSelector) + if err != nil { + return nil, fmt.Errorf("create onRampReader: %w", err) + } + + dynamicOnRampConfig, err := onRampReader.GetDynamicConfig(ctx) + if err != nil { + return nil, fmt.Errorf("get onramp dynamic config: %w", err) + } + + sourceWrappedNative, err := srcProvider.SourceNativeToken(ctx, dynamicOnRampConfig.Router) + if err != nil { + return nil, fmt.Errorf("get source wrapped native token: %w", err) + } + + srcCommitStore, err := srcProvider.NewCommitStoreReader(ctx, offRampConfig.CommitStore) + if err != nil { + return nil, fmt.Errorf("could not create src commitStoreReader reader: %w", err) + } + + dstCommitStore, err := dstProvider.NewCommitStoreReader(ctx, offRampConfig.CommitStore) + if err != nil { + return nil, fmt.Errorf("could not create dst commitStoreReader reader: %w", err) + } + + var commitStoreReader ccipdata.CommitStoreReader + commitStoreReader = ccip.NewProviderProxyCommitStoreReader(srcCommitStore, dstCommitStore) + + tokenDataProviders := make(map[cciptypes.Address]tokendata.Reader) + // init usdc token data provider + if pluginConfig.USDCConfig.AttestationAPI != "" { + lggr.Infof("USDC token data provider enabled") + err2 := pluginConfig.USDCConfig.ValidateUSDCConfig() + if err2 != nil { + return nil, err2 + } + + usdcReader, err2 := srcProvider.NewTokenDataReader(ctx, ccip.EvmAddrToGeneric(pluginConfig.USDCConfig.SourceTokenAddress)) + if err2 != nil { + return nil, fmt.Errorf("new usdc reader: %w", err2) + } + tokenDataProviders[cciptypes.Address(pluginConfig.USDCConfig.SourceTokenAddress.String())] = usdcReader + } + + // Prom wrappers + onRampReader = observability.NewObservedOnRampReader(onRampReader, srcChainID, ccip.ExecPluginLabel) + commitStoreReader = observability.NewObservedCommitStoreReader(commitStoreReader, dstChainID, ccip.ExecPluginLabel) + offRampReader = observability.NewObservedOffRampReader(offRampReader, dstChainID, ccip.ExecPluginLabel) + metricsCollector := ccip.NewPluginMetricsCollector(ccip.ExecPluginLabel, srcChainID, dstChainID) + + tokenPoolBatchedReader, err := dstProvider.NewTokenPoolBatchedReader(ctx, offRampAddress, srcChainSelector) + if err != nil { + return nil, fmt.Errorf("new token pool batched reader: %w", err) + } + + chainHealthcheck := cache.NewObservedChainHealthCheck( + cache.NewChainHealthcheck( + // Adding more details to Logger to make healthcheck logs more informative + // It's safe because healthcheck logs only in case of unhealthy state + lggr.With( + "onramp", offRampConfig.OnRamp, + "commitStore", offRampConfig.CommitStore, + "offramp", offRampAddress, + ), + onRampReader, + commitStoreReader, + ), + ccip.ExecPluginLabel, + srcChainID, + dstChainID, + offRampConfig.OnRamp, + ) + + tokenBackgroundWorker := tokendata.NewBackgroundWorker( + tokenDataProviders, + tokenDataWorkerNumWorkers, + tokenDataWorkerTimeout, + 2*tokenDataWorkerTimeout, + ) + + wrappedPluginFactory := NewExecutionReportingPluginFactory(ExecutionPluginStaticConfig{ + lggr: lggr, + onRampReader: onRampReader, + commitStoreReader: commitStoreReader, + offRampReader: offRampReader, + sourcePriceRegistryProvider: ccip.NewChainAgnosticPriceRegistry(srcProvider), + sourceWrappedNativeToken: sourceWrappedNative, + destChainSelector: dstChainSelector, + priceRegistryProvider: ccip.NewChainAgnosticPriceRegistry(dstProvider), + tokenPoolBatchedReader: tokenPoolBatchedReader, + tokenDataWorker: tokenBackgroundWorker, + metricsCollector: metricsCollector, + chainHealthcheck: chainHealthcheck, + newReportingPluginRetryConfig: defaultNewReportingPluginRetryConfig, + txmStatusChecker: statuschecker.NewTxmStatusChecker(dstProvider.GetTransactionStatus), + }) + + argsNoPlugin.ReportingPluginFactory = promwrapper.NewPromFactory(wrappedPluginFactory, "CCIPExecution", jb.OCR2OracleSpec.Relay, big.NewInt(0).SetInt64(dstChainID)) + argsNoPlugin.Logger = commonlogger.NewOCRWrapper(lggr, true, logError) + oracle, err := libocr2.NewOracle(argsNoPlugin) + if err != nil { + return nil, err + } + // If this is a brand-new job, then we make use of the start blocks. If not then we're rebooting and log poller will pick up where we left off. + if new { + return []job.ServiceCtx{ + oraclelib.NewChainAgnosticBackFilledOracle( + lggr, + srcProvider, + dstProvider, + job.NewServiceAdapter(oracle), + ), + chainHealthcheck, + tokenBackgroundWorker, + }, nil + } + return []job.ServiceCtx{ + job.NewServiceAdapter(oracle), + chainHealthcheck, + tokenBackgroundWorker, + }, nil +} + +// UnregisterExecPluginLpFilters unregisters all the registered filters for both source and dest chains. +// See comment in UnregisterCommitPluginLpFilters +// It MUST mirror the filters registered in NewExecServices. +// This currently works because the filters registered by the created custom providers when the job is first added +// are stored in the db. Those same filters are unregistered (i.e. deleted from the db) by the newly created providers +// that are passed in from cleanupEVM, as while the providers have no knowledge of each other, they are created +// on the same source and dest relayer. +func UnregisterExecPluginLpFilters(srcProvider types.CCIPExecProvider, dstProvider types.CCIPExecProvider) error { + unregisterFuncs := []func() error{ + func() error { + return srcProvider.Close() + }, + func() error { + return dstProvider.Close() + }, + } + + var multiErr error + for _, fn := range unregisterFuncs { + if err := fn(); err != nil { + multiErr = multierr.Append(multiErr, err) + } + } + return multiErr +} + +// ExecReportToEthTxMeta generates a txmgr.EthTxMeta from the given report. +// Only MessageIDs will be populated in the TxMeta. +func ExecReportToEthTxMeta(ctx context.Context, typ ccipconfig.ContractType, ver semver.Version) (func(report []byte) (*txmgr.TxMeta, error), error) { + return factory.ExecReportToEthTxMeta(ctx, typ, ver) +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/ocr2.go b/core/services/ocr2/plugins/ccip/ccipexec/ocr2.go new file mode 100644 index 0000000000..4a09cf37b4 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/ocr2.go @@ -0,0 +1,845 @@ +package ccipexec + +import ( + "context" + "encoding/hex" + "fmt" + "math/big" + "sort" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/pkg/errors" + "golang.org/x/sync/errgroup" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/statuschecker" +) + +const ( + // exec Report should make sure to cap returned payload to this limit + MaxExecutionReportLength = 250_000 + + // MaxDataLenPerBatch limits the total length of msg data that can be in a batch. + MaxDataLenPerBatch = 60_000 + + // MaximumAllowedTokenDataWaitTimePerBatch defines the maximum time that is allowed + // for the plugin to wait for token data to be fetched from external providers per batch. + MaximumAllowedTokenDataWaitTimePerBatch = 2 * time.Second + + // MessagesIterationStep limits number of messages fetched to memory at once when iterating through unexpired CommitRoots + MessagesIterationStep = 1024 +) + +var ( + _ types.ReportingPluginFactory = &ExecutionReportingPluginFactory{} + _ types.ReportingPlugin = &ExecutionReportingPlugin{} +) + +type ExecutionPluginStaticConfig struct { + lggr logger.Logger + onRampReader ccipdata.OnRampReader + offRampReader ccipdata.OffRampReader + commitStoreReader ccipdata.CommitStoreReader + sourcePriceRegistryProvider ccipdataprovider.PriceRegistry + sourceWrappedNativeToken cciptypes.Address + tokenDataWorker tokendata.Worker + destChainSelector uint64 + priceRegistryProvider ccipdataprovider.PriceRegistry // destination price registry provider. + tokenPoolBatchedReader batchreader.TokenPoolBatchedReader + metricsCollector ccip.PluginMetricsCollector + chainHealthcheck cache.ChainHealthcheck + newReportingPluginRetryConfig ccipdata.RetryConfig + txmStatusChecker statuschecker.CCIPTransactionStatusChecker +} + +type ExecutionReportingPlugin struct { + // Misc + F int + lggr logger.Logger + offchainConfig cciptypes.ExecOffchainConfig + tokenDataWorker tokendata.Worker + metricsCollector ccip.PluginMetricsCollector + batchingStrategy BatchingStrategy + + // Source + gasPriceEstimator prices.GasPriceEstimatorExec + sourcePriceRegistry ccipdata.PriceRegistryReader + sourcePriceRegistryProvider ccipdataprovider.PriceRegistry + sourcePriceRegistryLock sync.RWMutex + sourceWrappedNativeToken cciptypes.Address + onRampReader ccipdata.OnRampReader + + // Dest + commitStoreReader ccipdata.CommitStoreReader + destPriceRegistry ccipdata.PriceRegistryReader + destWrappedNative cciptypes.Address + onchainConfig cciptypes.ExecOnchainConfig + offRampReader ccipdata.OffRampReader + tokenPoolBatchedReader batchreader.TokenPoolBatchedReader + + // State + inflightReports *inflightExecReportsContainer + commitRootsCache cache.CommitsRootsCache + chainHealthcheck cache.ChainHealthcheck +} + +func (r *ExecutionReportingPlugin) Query(context.Context, types.ReportTimestamp) (types.Query, error) { + return types.Query{}, nil +} + +func (r *ExecutionReportingPlugin) Observation(ctx context.Context, timestamp types.ReportTimestamp, query types.Query) (types.Observation, error) { + lggr := r.lggr.Named("ExecutionObservation") + if healthy, err := r.chainHealthcheck.IsHealthy(ctx); err != nil { + return nil, err + } else if !healthy { + return nil, ccip.ErrChainIsNotHealthy + } + + // Ensure that the source price registry is synchronized with the onRamp. + if err := r.ensurePriceRegistrySynchronization(ctx); err != nil { + return nil, fmt.Errorf("ensuring price registry synchronization: %w", err) + } + + // Expire any inflight reports. + r.inflightReports.expire(lggr) + inFlight := r.inflightReports.getAll() + + executableObservations, err := r.getExecutableObservations(ctx, lggr, inFlight) + if err != nil { + return nil, err + } + // cap observations which fits MaxObservationLength (after serialized) + capped := sort.Search(len(executableObservations), func(i int) bool { + var encoded []byte + encoded, err = ccip.NewExecutionObservation(executableObservations[:i+1]).Marshal() + if err != nil { + // false makes Search keep looking to the right, always including any "erroring" ObservedMessage and allowing us to detect in the bottom + return false + } + return len(encoded) > ccip.MaxObservationLength + }) + if err != nil { + return nil, err + } + executableObservations = executableObservations[:capped] + r.metricsCollector.NumberOfMessagesProcessed(ccip.Observation, len(executableObservations)) + lggr.Infow("Observation", "executableMessages", executableObservations) + // Note can be empty + return ccip.NewExecutionObservation(executableObservations).Marshal() +} + +func (r *ExecutionReportingPlugin) getExecutableObservations(ctx context.Context, lggr logger.Logger, inflight []InflightInternalExecutionReport) ([]ccip.ObservedMessage, error) { + unexpiredReports, err := r.commitRootsCache.RootsEligibleForExecution(ctx) + if err != nil { + return nil, err + } + r.metricsCollector.UnexpiredCommitRoots(len(unexpiredReports)) + + if len(unexpiredReports) == 0 { + return []ccip.ObservedMessage{}, nil + } + + getExecTokenData := cache.LazyFunction[execTokenData](func() (execTokenData, error) { + return r.prepareTokenExecData(ctx) + }) + + for j := 0; j < len(unexpiredReports); { + unexpiredReportsPart, step := selectReportsToFillBatch(unexpiredReports[j:], MessagesIterationStep) + j += step + + unexpiredReportsWithSendReqs, err := r.getReportsWithSendRequests(ctx, unexpiredReportsPart) + if err != nil { + return nil, err + } + + for _, unexpiredReport := range unexpiredReportsWithSendReqs { + r.tokenDataWorker.AddJobsFromMsgs(ctx, unexpiredReport.sendRequestsWithMeta) + } + + for _, rep := range unexpiredReportsWithSendReqs { + if ctx.Err() != nil { + lggr.Warn("Processing of roots killed by context") + break + } + + merkleRoot := rep.commitReport.MerkleRoot + + rootLggr := lggr.With("root", hexutil.Encode(merkleRoot[:]), + "minSeqNr", rep.commitReport.Interval.Min, + "maxSeqNr", rep.commitReport.Interval.Max, + ) + + if err := rep.validate(); err != nil { + rootLggr.Errorw("Skipping invalid report", "err", err) + continue + } + + // If all messages are already executed and finalized, snooze the root for + // config.PermissionLessExecutionThresholdSeconds so it will never be considered again. + if allMsgsExecutedAndFinalized := rep.allRequestsAreExecutedAndFinalized(); allMsgsExecutedAndFinalized { + rootLggr.Infow("Snoozing root forever since there are no executable txs anymore", "root", hex.EncodeToString(merkleRoot[:])) + r.commitRootsCache.MarkAsExecuted(merkleRoot) + continue + } + + blessed, err := r.commitStoreReader.IsBlessed(ctx, merkleRoot) + if err != nil { + return nil, err + } + if !blessed { + rootLggr.Infow("Report is accepted but not blessed") + continue + } + + tokenExecData, err := getExecTokenData() + if err != nil { + return nil, err + } + + batch, msgExecStates := r.buildBatch( + ctx, + inflight, + rootLggr, + rep, + tokenExecData.rateLimiterTokenBucket.Tokens, + tokenExecData.sourceTokenPrices, + tokenExecData.destTokenPrices, + tokenExecData.gasPrice, + tokenExecData.sourceToDestTokens) + if len(batch) != 0 { + lggr.Infow("Execution batch created", "batchSize", len(batch), "messageStates", msgExecStates) + return batch, nil + } + r.commitRootsCache.Snooze(merkleRoot) + } + } + return []ccip.ObservedMessage{}, nil +} + +// Calculates a map that indicates whether a sequence number has already been executed. +// It doesn't matter if the execution succeeded, since we don't retry previous +// attempts even if they failed. Value in the map indicates whether the log is finalized or not. +func (r *ExecutionReportingPlugin) getExecutedSeqNrsInRange(ctx context.Context, min, max uint64) (map[uint64]bool, error) { + stateChanges, err := r.offRampReader.GetExecutionStateChangesBetweenSeqNums( + ctx, + min, + max, + int(r.offchainConfig.DestOptimisticConfirmations), + ) + if err != nil { + return nil, err + } + executedMp := make(map[uint64]bool, len(stateChanges)) + for _, stateChange := range stateChanges { + executedMp[stateChange.SequenceNumber] = stateChange.TxMeta.IsFinalized() + } + return executedMp, nil +} + +// Builds a batch of transactions that can be executed, takes into account +// the available gas, rate limiting, execution state, nonce state, and +// profitability of execution. +func (r *ExecutionReportingPlugin) buildBatch( + ctx context.Context, + inflight []InflightInternalExecutionReport, + lggr logger.Logger, + report commitReportWithSendRequests, + aggregateTokenLimit *big.Int, + sourceTokenPricesUSD map[cciptypes.Address]*big.Int, + destTokenPricesUSD map[cciptypes.Address]*big.Int, + gasPrice *big.Int, + sourceToDestToken map[cciptypes.Address]cciptypes.Address, +) ([]ccip.ObservedMessage, []messageExecStatus) { + // We assume that next observation will start after previous epoch transmission so nonces should be already updated onchain. + // Worst case scenario we will try to process the same message again, and it will be skipped but protocol would progress anyway. + // We don't use inflightCache here to avoid cases in which inflight cache keeps progressing but due to transmission failures + // previous reports are not included onchain. That can lead to issues with IncorrectNonce skips, + // because we enforce sequential processing per sender (per sender's nonce ordering is enforced by Offramp contract) + sendersNonce, err := r.offRampReader.ListSenderNonces(ctx, report.uniqueSenders()) + if err != nil { + lggr.Errorw("Fetching senders nonce", "err", err) + return []ccip.ObservedMessage{}, []messageExecStatus{} + } + + inflightAggregateValue, err := getInflightAggregateRateLimit(lggr, inflight, destTokenPricesUSD, sourceToDestToken) + if err != nil { + lggr.Errorw("Unexpected error computing inflight values", "err", err) + return []ccip.ObservedMessage{}, nil + } + + batchCtx := &BatchContext{ + report, + inflight, + inflightAggregateValue, + lggr, + MaxDataLenPerBatch, + uint64(r.offchainConfig.BatchGasLimit), + make(map[cciptypes.Address]uint64), + sendersNonce, + sourceTokenPricesUSD, + destTokenPricesUSD, + gasPrice, + sourceToDestToken, + aggregateTokenLimit, + MaximumAllowedTokenDataWaitTimePerBatch, + r.tokenDataWorker, + r.gasPriceEstimator, + r.destWrappedNative, + r.offchainConfig, + } + + return r.batchingStrategy.BuildBatch(ctx, batchCtx) +} + +func calculateMessageMaxGas(gasLimit *big.Int, numRequests, dataLen, numTokens int) (uint64, error) { + if !gasLimit.IsUint64() { + return 0, fmt.Errorf("gas limit %s cannot be casted to uint64", gasLimit) + } + + gasLimitU64 := gasLimit.Uint64() + gasOverHeadGas := maxGasOverHeadGas(numRequests, dataLen, numTokens) + messageMaxGas := gasLimitU64 + gasOverHeadGas + + if messageMaxGas < gasLimitU64 || messageMaxGas < gasOverHeadGas { + return 0, fmt.Errorf("message max gas overflow, gasLimit=%d gasOverHeadGas=%d", gasLimitU64, gasOverHeadGas) + } + + return messageMaxGas, nil +} + +// getReportsWithSendRequests returns the target reports with populated send requests. +func (r *ExecutionReportingPlugin) getReportsWithSendRequests( + ctx context.Context, + reports []cciptypes.CommitStoreReport, +) ([]commitReportWithSendRequests, error) { + if len(reports) == 0 { + return nil, nil + } + + // find interval from all the reports + intervalMin := reports[0].Interval.Min + intervalMax := reports[0].Interval.Max + for _, report := range reports[1:] { + if report.Interval.Max > intervalMax { + intervalMax = report.Interval.Max + } + if report.Interval.Min < intervalMin { + intervalMin = report.Interval.Min + } + } + + // use errgroup to fetch send request logs and executed sequence numbers in parallel + eg := &errgroup.Group{} + + var sendRequests []cciptypes.EVM2EVMMessageWithTxMeta + eg.Go(func() error { + // We don't need to double-check if logs are finalized because we already checked that in the Commit phase. + sendReqs, err := r.onRampReader.GetSendRequestsBetweenSeqNums(ctx, intervalMin, intervalMax, false) + if err != nil { + return err + } + sendRequests = sendReqs + return nil + }) + + var executedSeqNums map[uint64]bool + eg.Go(func() error { + // get executed sequence numbers + executedMp, err := r.getExecutedSeqNrsInRange(ctx, intervalMin, intervalMax) + if err != nil { + return err + } + executedSeqNums = executedMp + return nil + }) + + if err := eg.Wait(); err != nil { + return nil, err + } + + reportsWithSendReqs := make([]commitReportWithSendRequests, len(reports)) + for i, report := range reports { + reportsWithSendReqs[i] = commitReportWithSendRequests{ + commitReport: report, + sendRequestsWithMeta: make([]cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, 0, report.Interval.Max-report.Interval.Min+1), + } + } + + for _, sendReq := range sendRequests { + // if value exists in the map then it's executed + // if value exists, and it's true then it's considered finalized + finalized, executed := executedSeqNums[sendReq.SequenceNumber] + + reqWithMeta := cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: sendReq.EVM2EVMMessage, + BlockTimestamp: time.UnixMilli(sendReq.BlockTimestampUnixMilli), + Executed: executed, + Finalized: finalized, + LogIndex: uint(sendReq.LogIndex), + TxHash: sendReq.TxHash, + } + + // attach the msg to the appropriate reports + for i := range reportsWithSendReqs { + if reportsWithSendReqs[i].sendReqFits(reqWithMeta) { + reportsWithSendReqs[i].sendRequestsWithMeta = append(reportsWithSendReqs[i].sendRequestsWithMeta, reqWithMeta) + } + } + } + + return reportsWithSendReqs, nil +} + +// Assumes non-empty report. Messages to execute can span more than one report, but are assumed to be in order of increasing +// sequence number. +func (r *ExecutionReportingPlugin) buildReport(ctx context.Context, lggr logger.Logger, observedMessages []ccip.ObservedMessage) ([]byte, error) { + if err := validateSeqNumbers(ctx, r.commitStoreReader, observedMessages); err != nil { + return nil, err + } + commitReport, err := getCommitReportForSeqNum(ctx, r.commitStoreReader, observedMessages[0].SeqNr) + if err != nil { + return nil, err + } + lggr.Infow("Building execution report", "observations", observedMessages, "merkleRoot", hexutil.Encode(commitReport.MerkleRoot[:]), "report", commitReport) + + sendReqsInRoot, _, tree, err := getProofData(ctx, r.onRampReader, commitReport.Interval) + if err != nil { + return nil, err + } + + // cap messages which fits MaxExecutionReportLength (after serialized) + capped := sort.Search(len(observedMessages), func(i int) bool { + report, err2 := buildExecutionReportForMessages(sendReqsInRoot, tree, commitReport.Interval, observedMessages[:i+1]) + if err2 != nil { + r.lggr.Errorw("build execution report", "err", err2) + return false + } + + encoded, err2 := r.offRampReader.EncodeExecutionReport(ctx, report) + if err2 != nil { + // false makes Search keep looking to the right, always including any "erroring" ObservedMessage and allowing us to detect in the bottom + return false + } + return len(encoded) > MaxExecutionReportLength + }) + + execReport, err := buildExecutionReportForMessages(sendReqsInRoot, tree, commitReport.Interval, observedMessages[:capped]) + if err != nil { + return nil, err + } + + encodedReport, err := r.offRampReader.EncodeExecutionReport(ctx, execReport) + if err != nil { + return nil, err + } + + if capped < len(observedMessages) { + lggr.Warnf( + "Capping report to fit MaxExecutionReportLength: msgsCount %d -> %d, bytes %d, bytesLimit %d", + len(observedMessages), capped, len(encodedReport), MaxExecutionReportLength, + ) + } + // Double check this verifies before sending. + valid, err := r.commitStoreReader.VerifyExecutionReport(ctx, execReport) + if err != nil { + return nil, errors.Wrap(err, "unable to verify") + } + if !valid { + return nil, errors.New("root does not verify") + } + if len(execReport.Messages) > 0 { + r.metricsCollector.NumberOfMessagesProcessed(ccip.Report, len(execReport.Messages)) + r.metricsCollector.SequenceNumber(ccip.Report, execReport.Messages[len(execReport.Messages)-1].SequenceNumber) + } + return encodedReport, nil +} + +func (r *ExecutionReportingPlugin) Report(ctx context.Context, timestamp types.ReportTimestamp, query types.Query, observations []types.AttributedObservation) (bool, types.Report, error) { + lggr := r.lggr.Named("ExecutionReport") + if healthy, err := r.chainHealthcheck.IsHealthy(ctx); err != nil { + return false, nil, err + } else if !healthy { + return false, nil, ccip.ErrChainIsNotHealthy + } + parsableObservations := ccip.GetParsableObservations[ccip.ExecutionObservation](lggr, observations) + // Need at least F+1 observations + if len(parsableObservations) <= r.F { + lggr.Warn("Non-empty observations <= F, need at least F+1 to continue") + return false, nil, nil + } + + observedMessages, err := calculateObservedMessagesConsensus(parsableObservations, r.F) + if err != nil { + return false, nil, err + } + if len(observedMessages) == 0 { + return false, nil, nil + } + + report, err := r.buildReport(ctx, lggr, observedMessages) + if err != nil { + return false, nil, err + } + lggr.Infow("Report", "executableObservations", observedMessages) + return true, report, nil +} + +type tallyKey struct { + seqNr uint64 + tokenDataHash [32]byte +} + +type tallyVal struct { + tally int + tokenData [][]byte +} + +func calculateObservedMessagesConsensus(observations []ccip.ExecutionObservation, f int) ([]ccip.ObservedMessage, error) { + tally := make(map[tallyKey]tallyVal) + for _, obs := range observations { + for seqNr, msgData := range obs.Messages { + tokenDataHash, err := hashutil.BytesOfBytesKeccak(msgData.TokenData) + if err != nil { + return nil, fmt.Errorf("bytes of bytes keccak: %w", err) + } + + key := tallyKey{seqNr: seqNr, tokenDataHash: tokenDataHash} + if val, ok := tally[key]; ok { + tally[key] = tallyVal{tally: val.tally + 1, tokenData: msgData.TokenData} + } else { + tally[key] = tallyVal{tally: 1, tokenData: msgData.TokenData} + } + } + } + + // We might have different token data for the same sequence number. + // For that purpose we want to keep the token data with the most occurrences. + seqNumTally := make(map[uint64]tallyVal) + + // order tally keys to make looping over the entries deterministic + tallyKeys := make([]tallyKey, 0, len(tally)) + for key := range tally { + tallyKeys = append(tallyKeys, key) + } + sort.Slice(tallyKeys, func(i, j int) bool { + return hex.EncodeToString(tallyKeys[i].tokenDataHash[:]) < hex.EncodeToString(tallyKeys[j].tokenDataHash[:]) + }) + + for _, key := range tallyKeys { + tallyInfo := tally[key] + existingTally, exists := seqNumTally[key.seqNr] + if tallyInfo.tally > f && (!exists || tallyInfo.tally > existingTally.tally) { + seqNumTally[key.seqNr] = tallyInfo + } + } + + finalSequenceNumbers := make([]ccip.ObservedMessage, 0, len(seqNumTally)) + for seqNr, tallyInfo := range seqNumTally { + finalSequenceNumbers = append(finalSequenceNumbers, ccip.NewObservedMessage(seqNr, tallyInfo.tokenData)) + } + // buildReport expects sorted sequence numbers (tally map is non-deterministic). + sort.Slice(finalSequenceNumbers, func(i, j int) bool { + return finalSequenceNumbers[i].SeqNr < finalSequenceNumbers[j].SeqNr + }) + return finalSequenceNumbers, nil +} + +func (r *ExecutionReportingPlugin) ShouldAcceptFinalizedReport(ctx context.Context, timestamp types.ReportTimestamp, report types.Report) (bool, error) { + lggr := r.lggr.Named("ShouldAcceptFinalizedReport") + execReport, err := r.offRampReader.DecodeExecutionReport(ctx, report) + if err != nil { + lggr.Errorw("Unable to decode report", "err", err) + return false, err + } + lggr = lggr.With("messageIDs", ccipcommon.GetMessageIDsAsHexString(execReport.Messages)) + + if healthy, err1 := r.chainHealthcheck.IsHealthy(ctx); err1 != nil { + return false, err1 + } else if !healthy { + return false, ccip.ErrChainIsNotHealthy + } + // If the first message is executed already, this execution report is stale, and we do not accept it. + stale, err := r.isStaleReport(ctx, execReport.Messages) + if err != nil { + return false, err + } + if stale { + lggr.Info("Execution report is stale") + return false, nil + } + // Else just assume in flight + if err = r.inflightReports.add(lggr, execReport.Messages); err != nil { + return false, err + } + if len(execReport.Messages) > 0 { + r.metricsCollector.SequenceNumber(ccip.ShouldAccept, execReport.Messages[len(execReport.Messages)-1].SequenceNumber) + } + lggr.Info("Accepting finalized report") + return true, nil +} + +func (r *ExecutionReportingPlugin) ShouldTransmitAcceptedReport(ctx context.Context, timestamp types.ReportTimestamp, report types.Report) (bool, error) { + lggr := r.lggr.Named("ShouldTransmitAcceptedReport") + execReport, err := r.offRampReader.DecodeExecutionReport(ctx, report) + if err != nil { + lggr.Errorw("Unable to decode report", "err", err) + return false, nil + } + lggr = lggr.With("messageIDs", ccipcommon.GetMessageIDsAsHexString(execReport.Messages)) + + if healthy, err1 := r.chainHealthcheck.IsHealthy(ctx); err1 != nil { + return false, err1 + } else if !healthy { + return false, ccip.ErrChainIsNotHealthy + } + // If report is not stale we transmit. + // When the executeTransmitter enqueues the tx for tx manager, + // we mark it as execution_sent, removing it from the set of inflight messages. + stale, err := r.isStaleReport(ctx, execReport.Messages) + if err != nil { + return false, err + } + if stale { + lggr.Info("Execution report is stale") + return false, nil + } + + lggr.Info("Transmitting finalized report") + return true, err +} + +func (r *ExecutionReportingPlugin) isStaleReport(ctx context.Context, messages []cciptypes.EVM2EVMMessage) (bool, error) { + if len(messages) == 0 { + return true, fmt.Errorf("messages are empty") + } + + // If the first message is executed already, this execution report is stale. + // Note the default execution state, including for arbitrary seq number not yet committed + // is ExecutionStateUntouched. + msgState, err := r.offRampReader.GetExecutionState(ctx, messages[0].SequenceNumber) + if err != nil { + return true, err + } + if state := cciptypes.MessageExecutionState(msgState); state == cciptypes.ExecutionStateFailure || state == cciptypes.ExecutionStateSuccess { + return true, nil + } + + return false, nil +} + +func (r *ExecutionReportingPlugin) Close() error { + return nil +} + +func getInflightAggregateRateLimit( + lggr logger.Logger, + inflight []InflightInternalExecutionReport, + destTokenPrices map[cciptypes.Address]*big.Int, + sourceToDest map[cciptypes.Address]cciptypes.Address, +) (*big.Int, error) { + inflightAggregateValue := big.NewInt(0) + + for _, rep := range inflight { + for _, message := range rep.messages { + msgValue, err := aggregateTokenValue(lggr, destTokenPrices, sourceToDest, message.TokenAmounts) + if err != nil { + return nil, err + } + inflightAggregateValue.Add(inflightAggregateValue, msgValue) + } + } + return inflightAggregateValue, nil +} + +// getTokensPrices returns token prices of the given price registry, +// price values are USD per 1e18 of smallest token denomination, in base units 1e18 (e.g. 5$ = 5e18 USD per 1e18 units). +// this function is used for price registry of both source and destination chains. +func getTokensPrices(ctx context.Context, priceRegistry ccipdata.PriceRegistryReader, tokens []cciptypes.Address) (map[cciptypes.Address]*big.Int, error) { + tokenPrices := make(map[cciptypes.Address]*big.Int) + + fetchedPrices, err := priceRegistry.GetTokenPrices(ctx, tokens) + if err != nil { + return nil, errors.Wrapf(err, "could not get token prices of %v", tokens) + } + + // price registry should always return a price per token ordered by input tokens + if len(fetchedPrices) != len(tokens) { + return nil, fmt.Errorf("token prices length exp=%d actual=%d", len(tokens), len(fetchedPrices)) + } + + for i, token := range tokens { + // price of a token can never be zero + if fetchedPrices[i].Value.BitLen() == 0 { + priceRegistryAddress, err := priceRegistry.Address(ctx) + if err != nil { + return nil, fmt.Errorf("get price registry address: %w", err) + } + return nil, fmt.Errorf("price of token %s is zero (price registry=%s)", token, priceRegistryAddress) + } + + // price registry should not report different price for the same token + price, exists := tokenPrices[token] + if exists && fetchedPrices[i].Value.Cmp(price) != 0 { + return nil, fmt.Errorf("price registry reported different prices (%s and %s) for the same token %s", + fetchedPrices[i].Value, price, token) + } + + tokenPrices[token] = fetchedPrices[i].Value + } + + return tokenPrices, nil +} + +type execTokenData struct { + rateLimiterTokenBucket cciptypes.TokenBucketRateLimit + sourceTokenPrices map[cciptypes.Address]*big.Int + destTokenPrices map[cciptypes.Address]*big.Int + sourceToDestTokens map[cciptypes.Address]cciptypes.Address + gasPrice *big.Int +} + +// prepareTokenExecData gather all the pre-execution data needed for token execution into a single lazy call. +// This is done to avoid fetching the data multiple times for each message. Additionally, most of the RPC calls +// within that function is cached, so it should be relatively fast and not require any RPC batching. +func (r *ExecutionReportingPlugin) prepareTokenExecData(ctx context.Context) (execTokenData, error) { + // This could result in slightly different values on each call as + // the function returns the allowed amount at the time of the last block. + // Since this will only increase over time, the highest observed value will + // always be the lower bound of what would be available on chain + // since we already account for inflight txs. + rateLimiterTokenBucket, err := r.offRampReader.CurrentRateLimiterState(ctx) + if err != nil { + return execTokenData{}, err + } + + sourceFeeTokens, err := r.sourcePriceRegistry.GetFeeTokens(ctx) + if err != nil { + return execTokenData{}, fmt.Errorf("get source fee tokens: %w", err) + } + sourceTokensPrices, err := getTokensPrices( + ctx, + r.sourcePriceRegistry, + ccipcommon.FlattenUniqueSlice( + sourceFeeTokens, + []cciptypes.Address{r.sourceWrappedNativeToken}, + ), + ) + if err != nil { + return execTokenData{}, err + } + + destFeeTokens, destBridgedTokens, err := ccipcommon.GetDestinationTokens(ctx, r.offRampReader, r.destPriceRegistry) + if err != nil { + return execTokenData{}, fmt.Errorf("get destination tokens: %w", err) + } + destTokenPrices, err := getTokensPrices( + ctx, + r.destPriceRegistry, + ccipcommon.FlattenUniqueSlice( + destFeeTokens, + destBridgedTokens, + []cciptypes.Address{r.destWrappedNative}, + ), + ) + if err != nil { + return execTokenData{}, err + } + + sourceToDestTokens, err := r.offRampReader.GetSourceToDestTokensMapping(ctx) + if err != nil { + return execTokenData{}, err + } + + gasPrice, err := r.gasPriceEstimator.GetGasPrice(ctx) + if err != nil { + return execTokenData{}, err + } + + return execTokenData{ + rateLimiterTokenBucket: rateLimiterTokenBucket, + sourceTokenPrices: sourceTokensPrices, + sourceToDestTokens: sourceToDestTokens, + destTokenPrices: destTokenPrices, + gasPrice: gasPrice, + }, nil +} + +// ensurePriceRegistrySynchronization ensures that the source price registry points to the same as the one configured on the onRamp. +// This is required since the price registry address on the onRamp can change over time. +func (r *ExecutionReportingPlugin) ensurePriceRegistrySynchronization(ctx context.Context) error { + needPriceRegistryUpdate := false + r.sourcePriceRegistryLock.RLock() + priceRegistryAddress, err := r.onRampReader.SourcePriceRegistryAddress(ctx) + if err != nil { + r.sourcePriceRegistryLock.RUnlock() + return fmt.Errorf("getting price registry from onramp: %w", err) + } + + currentPriceRegistryAddress := cciptypes.Address("") + if r.sourcePriceRegistry != nil { + currentPriceRegistryAddress, err = r.sourcePriceRegistry.Address(ctx) + if err != nil { + return fmt.Errorf("get current priceregistry address: %w", err) + } + } + + needPriceRegistryUpdate = r.sourcePriceRegistry == nil || priceRegistryAddress != currentPriceRegistryAddress + r.sourcePriceRegistryLock.RUnlock() + if !needPriceRegistryUpdate { + return nil + } + + // Update the price registry if required. + r.sourcePriceRegistryLock.Lock() + defer r.sourcePriceRegistryLock.Unlock() + + // Price registry address changed or not initialized yet, updating source price registry. + sourcePriceRegistry, err := r.sourcePriceRegistryProvider.NewPriceRegistryReader(ctx, priceRegistryAddress) + if err != nil { + return err + } + oldPriceRegistry := r.sourcePriceRegistry + r.sourcePriceRegistry = sourcePriceRegistry + // Close the old price registry + if oldPriceRegistry != nil { + if err1 := oldPriceRegistry.Close(); err1 != nil { + r.lggr.Warnw("failed to close old price registry", "err", err1) + } + } + return nil +} + +// selectReportsToFillBatch returns the reports to fill the message limit. Single Commit Root contains exactly (Interval.Max - Interval.Min + 1) messages. +// We keep adding reports until we reach the message limit. Please see the tests for more examples and edge cases. +// unexpiredReports have to be sorted by Interval.Min. Otherwise, the batching logic will not be efficient, +// because it picks messages and execution states based on the report[0].Interval.Min - report[len-1].Interval.Max range. +// Having unexpiredReports not sorted properly will lead to fetching more messages and execution states to the memory than the messagesLimit provided. +// However, logs from LogPoller are returned ordered by (block_number, log_index), so it should preserve the order of Interval.Min. +// Single CommitRoot can have up to 256 messages, with current MessagesIterationStep of 1024, it means processing 4 CommitRoots at once. +func selectReportsToFillBatch(unexpiredReports []cciptypes.CommitStoreReport, messagesLimit uint64) ([]cciptypes.CommitStoreReport, int) { + currentNumberOfMessages := uint64(0) + nbReports := 0 + for _, report := range unexpiredReports { + reportMsgCount := report.Interval.Max - report.Interval.Min + 1 + if currentNumberOfMessages+reportMsgCount > messagesLimit { + break + } + currentNumberOfMessages += reportMsgCount + nbReports++ + } + return unexpiredReports[:nbReports], nbReports +} diff --git a/core/services/ocr2/plugins/ccip/ccipexec/ocr2_test.go b/core/services/ocr2/plugins/ccip/ccipexec/ocr2_test.go new file mode 100644 index 0000000000..84cb73c664 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/ccipexec/ocr2_test.go @@ -0,0 +1,1421 @@ +package ccipexec + +import ( + "bytes" + "context" + "encoding/json" + "math" + "math/big" + "reflect" + "sort" + "sync" + "testing" + "time" + + "github.com/cometbft/cometbft/libs/rand" + mapset "github.com/deckarep/golang-set/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + lpMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + ccipcachemocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader" + ccipdataprovidermocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/mocks" + ccipdatamocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" +) + +func TestExecutionReportingPlugin_Observation(t *testing.T) { + testCases := []struct { + name string + commitStorePaused bool + sourceChainCursed bool + inflightReports []InflightInternalExecutionReport + unexpiredReports []cciptypes.CommitStoreReportWithTxMeta + sendRequests []cciptypes.EVM2EVMMessageWithTxMeta + executedSeqNums []uint64 + tokenPoolsMapping map[common.Address]common.Address + blessedRoots map[[32]byte]bool + senderNonce uint64 + rateLimiterState cciptypes.TokenBucketRateLimit + expErr bool + sourceChainHealthy bool + destChainHealthy bool + }{ + { + name: "commit store is down", + commitStorePaused: true, + sourceChainCursed: false, + sourceChainHealthy: true, + destChainHealthy: true, + expErr: true, + }, + { + name: "source chain is cursed", + commitStorePaused: false, + sourceChainCursed: true, + sourceChainHealthy: true, + destChainHealthy: true, + expErr: true, + }, + { + name: "source chain not healthy", + commitStorePaused: false, + sourceChainCursed: false, + sourceChainHealthy: false, + destChainHealthy: true, + expErr: true, + }, + { + name: "dest chain not healthy", + commitStorePaused: false, + sourceChainCursed: false, + sourceChainHealthy: true, + destChainHealthy: false, + expErr: true, + }, + { + name: "happy flow", + commitStorePaused: false, + sourceChainCursed: false, + sourceChainHealthy: true, + destChainHealthy: true, + inflightReports: []InflightInternalExecutionReport{}, + unexpiredReports: []cciptypes.CommitStoreReportWithTxMeta{ + { + CommitStoreReport: cciptypes.CommitStoreReport{ + Interval: cciptypes.CommitStoreInterval{Min: 10, Max: 12}, + MerkleRoot: [32]byte{123}, + }, + }, + }, + blessedRoots: map[[32]byte]bool{ + {123}: true, + }, + rateLimiterState: cciptypes.TokenBucketRateLimit{ + IsEnabled: false, + }, + tokenPoolsMapping: map[common.Address]common.Address{}, + senderNonce: 9, + sendRequests: []cciptypes.EVM2EVMMessageWithTxMeta{ + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 10, GasLimit: big.NewInt(0)}, + }, + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 11, GasLimit: big.NewInt(0)}, + }, + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 12, GasLimit: big.NewInt(0)}, + }, + }, + }, + } + + ctx := testutils.Context(t) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + p := &ExecutionReportingPlugin{} + p.inflightReports = newInflightExecReportsContainer(time.Minute) + p.inflightReports.reports = tc.inflightReports + p.lggr = logger.TestLogger(t) + p.tokenDataWorker = tokendata.NewBackgroundWorker( + make(map[cciptypes.Address]tokendata.Reader), 10, 5*time.Second, time.Hour) + p.metricsCollector = ccip.NoopMetricsCollector + + commitStoreReader := ccipdatamocks.NewCommitStoreReader(t) + commitStoreReader.On("IsDown", mock.Anything).Return(tc.commitStorePaused, nil).Maybe() + commitStoreReader.On("IsDestChainHealthy", mock.Anything).Return(tc.destChainHealthy, nil).Maybe() + // Blessed roots return true + for root, blessed := range tc.blessedRoots { + commitStoreReader.On("IsBlessed", mock.Anything, root).Return(blessed, nil).Maybe() + } + commitStoreReader.On("GetAcceptedCommitReportsGteTimestamp", ctx, mock.Anything, 0). + Return(tc.unexpiredReports, nil).Maybe() + p.commitStoreReader = commitStoreReader + + var executionEvents []cciptypes.ExecutionStateChangedWithTxMeta + for _, seqNum := range tc.executedSeqNums { + executionEvents = append(executionEvents, cciptypes.ExecutionStateChangedWithTxMeta{ + ExecutionStateChanged: cciptypes.ExecutionStateChanged{SequenceNumber: seqNum}, + }) + } + + offRamp, _ := testhelpers.NewFakeOffRamp(t) + offRamp.SetRateLimiterState(tc.rateLimiterState) + + tokenPoolBatchedReader, err := batchreader.NewEVMTokenPoolBatchedReader(p.lggr, 0, ccipcalc.EvmAddrToGeneric(offRamp.Address()), nil) + assert.NoError(t, err) + p.tokenPoolBatchedReader = tokenPoolBatchedReader + + mockOffRampReader := ccipdatamocks.NewOffRampReader(t) + mockOffRampReader.On("GetExecutionStateChangesBetweenSeqNums", ctx, mock.Anything, mock.Anything, 0). + Return(executionEvents, nil).Maybe() + mockOffRampReader.On("CurrentRateLimiterState", mock.Anything).Return(tc.rateLimiterState, nil).Maybe() + mockOffRampReader.On("Address", ctx).Return(cciptypes.Address(offRamp.Address().String()), nil).Maybe() + senderNonces := map[cciptypes.Address]uint64{ + cciptypes.Address(utils.RandomAddress().String()): tc.senderNonce, + } + mockOffRampReader.On("ListSenderNonces", mock.Anything, mock.Anything).Return(senderNonces, nil).Maybe() + mockOffRampReader.On("GetTokenPoolsRateLimits", ctx, []ccipdata.TokenPoolReader{}). + Return([]cciptypes.TokenBucketRateLimit{}, nil).Maybe() + + mockOffRampReader.On("GetSourceToDestTokensMapping", ctx).Return(nil, nil).Maybe() + mockOffRampReader.On("GetTokens", ctx).Return(cciptypes.OffRampTokens{ + DestinationTokens: []cciptypes.Address{}, + SourceTokens: []cciptypes.Address{}, + }, nil).Maybe() + p.offRampReader = mockOffRampReader + + mockOnRampReader := ccipdatamocks.NewOnRampReader(t) + mockOnRampReader.On("IsSourceCursed", ctx).Return(tc.sourceChainCursed, nil).Maybe() + mockOnRampReader.On("IsSourceChainHealthy", ctx).Return(tc.sourceChainHealthy, nil).Maybe() + mockOnRampReader.On("GetSendRequestsBetweenSeqNums", ctx, mock.Anything, mock.Anything, false). + Return(tc.sendRequests, nil).Maybe() + sourcePriceRegistryAddress := cciptypes.Address(utils.RandomAddress().String()) + mockOnRampReader.On("SourcePriceRegistryAddress", ctx).Return(sourcePriceRegistryAddress, nil).Maybe() + p.onRampReader = mockOnRampReader + + mockGasPriceEstimator := prices.NewMockGasPriceEstimatorExec(t) + mockGasPriceEstimator.On("GetGasPrice", ctx).Return(big.NewInt(1), nil).Maybe() + p.gasPriceEstimator = mockGasPriceEstimator + + destPriceRegReader := ccipdatamocks.NewPriceRegistryReader(t) + destPriceRegReader.On("GetTokenPrices", ctx, mock.Anything).Return( + []cciptypes.TokenPriceUpdate{{TokenPrice: cciptypes.TokenPrice{Token: ccipcalc.HexToAddress("0x1"), Value: big.NewInt(123)}, TimestampUnixSec: big.NewInt(time.Now().Unix())}}, nil).Maybe() + destPriceRegReader.On("Address", ctx).Return(cciptypes.Address(utils.RandomAddress().String()), nil).Maybe() + destPriceRegReader.On("GetFeeTokens", ctx).Return([]cciptypes.Address{}, nil).Maybe() + sourcePriceRegReader := ccipdatamocks.NewPriceRegistryReader(t) + sourcePriceRegReader.On("Address", ctx).Return(sourcePriceRegistryAddress, nil).Maybe() + sourcePriceRegReader.On("GetFeeTokens", ctx).Return([]cciptypes.Address{}, nil).Maybe() + sourcePriceRegReader.On("GetTokenPrices", ctx, mock.Anything).Return( + []cciptypes.TokenPriceUpdate{{TokenPrice: cciptypes.TokenPrice{Token: ccipcalc.HexToAddress("0x1"), Value: big.NewInt(123)}, TimestampUnixSec: big.NewInt(time.Now().Unix())}}, nil).Maybe() + p.destPriceRegistry = destPriceRegReader + + mockOnRampPriceRegistryProvider := ccipdataprovidermocks.NewPriceRegistry(t) + mockOnRampPriceRegistryProvider.On("NewPriceRegistryReader", ctx, sourcePriceRegistryAddress).Return(sourcePriceRegReader, nil).Maybe() + p.sourcePriceRegistryProvider = mockOnRampPriceRegistryProvider + + p.commitRootsCache = cache.NewCommitRootsCache(logger.TestLogger(t), commitStoreReader, time.Minute, time.Minute) + p.chainHealthcheck = cache.NewChainHealthcheck(p.lggr, mockOnRampReader, commitStoreReader) + + bs := &BestEffortBatchingStrategy{} + p.batchingStrategy = bs + + _, err = p.Observation(ctx, types.ReportTimestamp{}, types.Query{}) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + }) + } +} + +func TestExecutionReportingPlugin_Report(t *testing.T) { + testCases := []struct { + name string + f int + committedSeqNum uint64 + observations []ccip.ExecutionObservation + + expectingSomeReport bool + expectedReport cciptypes.ExecReport + expectingSomeErr bool + }{ + { + name: "not enough observations to form consensus", + f: 5, + committedSeqNum: 5, + observations: []ccip.ExecutionObservation{ + {Messages: map[uint64]ccip.MsgData{3: {}, 4: {}}}, + {Messages: map[uint64]ccip.MsgData{3: {}, 4: {}}}, + }, + expectingSomeErr: false, + expectingSomeReport: false, + }, + { + name: "zero observations", + f: 0, + committedSeqNum: 5, + observations: []ccip.ExecutionObservation{}, + expectingSomeErr: false, + expectingSomeReport: false, + }, + } + + ctx := testutils.Context(t) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + p := ExecutionReportingPlugin{} + p.lggr = logger.TestLogger(t) + p.F = tc.f + + p.commitStoreReader = ccipdatamocks.NewCommitStoreReader(t) + chainHealthcheck := ccipcachemocks.NewChainHealthcheck(t) + chainHealthcheck.On("IsHealthy", ctx).Return(true, nil) + p.chainHealthcheck = chainHealthcheck + + observations := make([]types.AttributedObservation, len(tc.observations)) + for i := range observations { + b, err := json.Marshal(tc.observations[i]) + assert.NoError(t, err) + observations[i] = types.AttributedObservation{Observation: b, Observer: commontypes.OracleID(i + 1)} + } + + _, _, err := p.Report(ctx, types.ReportTimestamp{}, types.Query{}, observations) + if tc.expectingSomeErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + }) + } +} + +func TestExecutionReportingPlugin_ShouldAcceptFinalizedReport(t *testing.T) { + msg := cciptypes.EVM2EVMMessage{ + SequenceNumber: 12, + FeeTokenAmount: big.NewInt(1e9), + Sender: cciptypes.Address(utils.RandomAddress().String()), + Nonce: 1, + GasLimit: big.NewInt(1), + Strict: false, + Receiver: cciptypes.Address(utils.RandomAddress().String()), + Data: nil, + TokenAmounts: nil, + FeeToken: cciptypes.Address(utils.RandomAddress().String()), + MessageID: [32]byte{}, + } + report := cciptypes.ExecReport{ + Messages: []cciptypes.EVM2EVMMessage{msg}, + OffchainTokenData: [][][]byte{{}}, + Proofs: [][32]byte{{}}, + ProofFlagBits: big.NewInt(1), + } + + encodedReport := encodeExecutionReport(t, report) + mockOffRampReader := ccipdatamocks.NewOffRampReader(t) + mockOffRampReader.On("DecodeExecutionReport", mock.Anything, encodedReport).Return(report, nil) + + chainHealthcheck := ccipcachemocks.NewChainHealthcheck(t) + chainHealthcheck.On("IsHealthy", mock.Anything).Return(true, nil) + + plugin := ExecutionReportingPlugin{ + offRampReader: mockOffRampReader, + lggr: logger.TestLogger(t), + inflightReports: newInflightExecReportsContainer(1 * time.Hour), + chainHealthcheck: chainHealthcheck, + metricsCollector: ccip.NoopMetricsCollector, + } + + mockedExecState := mockOffRampReader.On("GetExecutionState", mock.Anything, uint64(12)).Return(uint8(cciptypes.ExecutionStateUntouched), nil).Once() + + should, err := plugin.ShouldAcceptFinalizedReport(testutils.Context(t), ocrtypes.ReportTimestamp{}, encodedReport) + require.NoError(t, err) + assert.Equal(t, true, should) + + mockedExecState.Return(uint8(cciptypes.ExecutionStateSuccess), nil).Once() + + should, err = plugin.ShouldAcceptFinalizedReport(testutils.Context(t), ocrtypes.ReportTimestamp{}, encodedReport) + require.NoError(t, err) + assert.Equal(t, false, should) +} + +func TestExecutionReportingPlugin_ShouldTransmitAcceptedReport(t *testing.T) { + msg := cciptypes.EVM2EVMMessage{ + SequenceNumber: 12, + FeeTokenAmount: big.NewInt(1e9), + Sender: cciptypes.Address(utils.RandomAddress().String()), + Nonce: 1, + GasLimit: big.NewInt(1), + Strict: false, + Receiver: cciptypes.Address(utils.RandomAddress().String()), + Data: nil, + TokenAmounts: nil, + FeeToken: cciptypes.Address(utils.RandomAddress().String()), + MessageID: [32]byte{}, + } + report := cciptypes.ExecReport{ + Messages: []cciptypes.EVM2EVMMessage{msg}, + OffchainTokenData: [][][]byte{{}}, + Proofs: [][32]byte{{}}, + ProofFlagBits: big.NewInt(1), + } + encodedReport := encodeExecutionReport(t, report) + + mockCommitStoreReader := ccipdatamocks.NewCommitStoreReader(t) + mockOffRampReader := ccipdatamocks.NewOffRampReader(t) + mockOffRampReader.On("DecodeExecutionReport", mock.Anything, encodedReport).Return(report, nil) + mockedExecState := mockOffRampReader.On("GetExecutionState", mock.Anything, uint64(12)).Return(uint8(cciptypes.ExecutionStateUntouched), nil).Once() + + chainHealthcheck := ccipcachemocks.NewChainHealthcheck(t) + chainHealthcheck.On("IsHealthy", mock.Anything).Return(true, nil) + + plugin := ExecutionReportingPlugin{ + commitStoreReader: mockCommitStoreReader, + offRampReader: mockOffRampReader, + lggr: logger.TestLogger(t), + inflightReports: newInflightExecReportsContainer(1 * time.Hour), + chainHealthcheck: chainHealthcheck, + } + + should, err := plugin.ShouldTransmitAcceptedReport(testutils.Context(t), ocrtypes.ReportTimestamp{}, encodedReport) + require.NoError(t, err) + assert.Equal(t, true, should) + + mockedExecState.Return(uint8(cciptypes.ExecutionStateFailure), nil).Once() + should, err = plugin.ShouldTransmitAcceptedReport(testutils.Context(t), ocrtypes.ReportTimestamp{}, encodedReport) + require.NoError(t, err) + assert.Equal(t, false, should) +} + +func TestExecutionReportingPlugin_buildReport(t *testing.T) { + ctx := testutils.Context(t) + + const numMessages = 100 + const tokensPerMessage = 20 + const bytesPerMessage = 1000 + + executionReport := generateExecutionReport(t, numMessages, tokensPerMessage, bytesPerMessage) + encodedReport := encodeExecutionReport(t, executionReport) + // ensure "naive" full report would be bigger than limit + assert.Greater(t, len(encodedReport), MaxExecutionReportLength, "full execution report length") + + observations := make([]ccip.ObservedMessage, len(executionReport.Messages)) + for i, msg := range executionReport.Messages { + observations[i] = ccip.NewObservedMessage(msg.SequenceNumber, executionReport.OffchainTokenData[i]) + } + + // ensure that buildReport should cap the built report to fit in MaxExecutionReportLength + p := &ExecutionReportingPlugin{} + p.lggr = logger.TestLogger(t) + + commitStore := ccipdatamocks.NewCommitStoreReader(t) + commitStore.On("VerifyExecutionReport", mock.Anything, mock.Anything, mock.Anything).Return(true, nil) + commitStore.On("GetExpectedNextSequenceNumber", mock.Anything). + Return(executionReport.Messages[len(executionReport.Messages)-1].SequenceNumber+1, nil) + commitStore.On("GetCommitReportMatchingSeqNum", ctx, observations[0].SeqNr, 0). + Return([]cciptypes.CommitStoreReportWithTxMeta{ + { + CommitStoreReport: cciptypes.CommitStoreReport{ + Interval: cciptypes.CommitStoreInterval{ + Min: observations[0].SeqNr, + Max: observations[len(observations)-1].SeqNr, + }, + }, + }, + }, nil) + p.metricsCollector = ccip.NoopMetricsCollector + p.commitStoreReader = commitStore + + lp := lpMocks.NewLogPoller(t) + offRampReader, err := v1_0_0.NewOffRamp(logger.TestLogger(t), utils.RandomAddress(), nil, lp, nil, nil) + assert.NoError(t, err) + p.offRampReader = offRampReader + + sendReqs := make([]cciptypes.EVM2EVMMessageWithTxMeta, len(observations)) + sourceReader := ccipdatamocks.NewOnRampReader(t) + for i := range observations { + msg := cciptypes.EVM2EVMMessage{ + SourceChainSelector: math.MaxUint64, + SequenceNumber: uint64(i + 1), + FeeTokenAmount: big.NewInt(math.MaxInt64), + Sender: cciptypes.Address(utils.RandomAddress().String()), + Nonce: math.MaxUint64, + GasLimit: big.NewInt(math.MaxInt64), + Strict: false, + Receiver: cciptypes.Address(utils.RandomAddress().String()), + Data: bytes.Repeat([]byte{0}, bytesPerMessage), + TokenAmounts: nil, + FeeToken: cciptypes.Address(utils.RandomAddress().String()), + MessageID: [32]byte{12}, + } + sendReqs[i] = cciptypes.EVM2EVMMessageWithTxMeta{EVM2EVMMessage: msg} + } + sourceReader.On("GetSendRequestsBetweenSeqNums", + ctx, observations[0].SeqNr, observations[len(observations)-1].SeqNr, false).Return(sendReqs, nil) + p.onRampReader = sourceReader + + execReport, err := p.buildReport(ctx, p.lggr, observations) + assert.NoError(t, err) + assert.LessOrEqual(t, len(execReport), MaxExecutionReportLength, "built execution report length") +} + +func TestExecutionReportingPlugin_getReportsWithSendRequests(t *testing.T) { + testCases := []struct { + name string + reports []cciptypes.CommitStoreReport + expQueryMin uint64 // expected min/max used in the query to get ccipevents + expQueryMax uint64 + onchainEvents []cciptypes.EVM2EVMMessageWithTxMeta + destExecutedSeqNums []uint64 + + expReports []commitReportWithSendRequests + expErr bool + }{ + { + name: "no reports", + reports: nil, + expReports: nil, + expErr: false, + }, + { + name: "two reports happy flow", + reports: []cciptypes.CommitStoreReport{ + { + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 2}, + MerkleRoot: [32]byte{100}, + }, + { + Interval: cciptypes.CommitStoreInterval{Min: 3, Max: 3}, + MerkleRoot: [32]byte{200}, + }, + }, + expQueryMin: 1, + expQueryMax: 3, + onchainEvents: []cciptypes.EVM2EVMMessageWithTxMeta{ + {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 1}}, + {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 2}}, + {EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 3}}, + }, + destExecutedSeqNums: []uint64{1}, + expReports: []commitReportWithSendRequests{ + { + commitReport: cciptypes.CommitStoreReport{ + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 2}, + MerkleRoot: [32]byte{100}, + }, + sendRequestsWithMeta: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 1}, + Executed: true, + Finalized: true, + }, + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 2}, + Executed: false, + Finalized: false, + }, + }, + }, + { + commitReport: cciptypes.CommitStoreReport{ + Interval: cciptypes.CommitStoreInterval{Min: 3, Max: 3}, + MerkleRoot: [32]byte{200}, + }, + sendRequestsWithMeta: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + { + EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 3}, + Executed: false, + Finalized: false, + }, + }, + }, + }, + expErr: false, + }, + } + + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + p := &ExecutionReportingPlugin{} + p.lggr = lggr + + offRampReader := ccipdatamocks.NewOffRampReader(t) + p.offRampReader = offRampReader + + sourceReader := ccipdatamocks.NewOnRampReader(t) + sourceReader.On("GetSendRequestsBetweenSeqNums", ctx, tc.expQueryMin, tc.expQueryMax, false). + Return(tc.onchainEvents, nil).Maybe() + p.onRampReader = sourceReader + + finalized := make(map[uint64]cciptypes.FinalizedStatus) + for _, r := range tc.expReports { + for _, s := range r.sendRequestsWithMeta { + finalized[s.SequenceNumber] = cciptypes.FinalizedStatusNotFinalized + if s.Finalized { + finalized[s.SequenceNumber] = cciptypes.FinalizedStatusFinalized + } + } + } + + var executedEvents []cciptypes.ExecutionStateChangedWithTxMeta + for _, executedSeqNum := range tc.destExecutedSeqNums { + executedEvents = append(executedEvents, cciptypes.ExecutionStateChangedWithTxMeta{ + ExecutionStateChanged: cciptypes.ExecutionStateChanged{ + SequenceNumber: executedSeqNum, + }, + TxMeta: cciptypes.TxMeta{ + Finalized: finalized[executedSeqNum], + }, + }) + } + offRampReader.On("GetExecutionStateChangesBetweenSeqNums", ctx, tc.expQueryMin, tc.expQueryMax, 0).Return(executedEvents, nil).Maybe() + + populatedReports, err := p.getReportsWithSendRequests(ctx, tc.reports) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, len(tc.expReports), len(populatedReports)) + for i, expReport := range tc.expReports { + assert.Equal(t, len(expReport.sendRequestsWithMeta), len(populatedReports[i].sendRequestsWithMeta)) + for j, expReq := range expReport.sendRequestsWithMeta { + assert.Equal(t, expReq.Executed, populatedReports[i].sendRequestsWithMeta[j].Executed) + assert.Equal(t, expReq.Finalized, populatedReports[i].sendRequestsWithMeta[j].Finalized) + assert.Equal(t, expReq.SequenceNumber, populatedReports[i].sendRequestsWithMeta[j].SequenceNumber) + } + } + }) + } +} + +func Test_calculateObservedMessagesConsensus(t *testing.T) { + type args struct { + observations []ccip.ExecutionObservation + f int + } + tests := []struct { + name string + args args + want []ccip.ObservedMessage + }{ + { + name: "no observations", + args: args{ + observations: nil, + f: 0, + }, + want: []ccip.ObservedMessage{}, + }, + { + name: "common path", + args: args{ + observations: []ccip.ExecutionObservation{ + { + Messages: map[uint64]ccip.MsgData{ + 1: {TokenData: [][]byte{{0x1}, {0x1}, {0x1}}}, + 2: {TokenData: [][]byte{{0x2}, {0x2}, {0x2}}}, + }, + }, + { + Messages: map[uint64]ccip.MsgData{ + 1: {TokenData: [][]byte{{0x1}, {0x1}, {0xff}}}, // different token data - should not be picked + 2: {TokenData: [][]byte{{0x2}, {0x2}, {0x2}}}, + 3: {TokenData: [][]byte{{0x3}, {0x3}, {0x3}}}, + }, + }, + { + Messages: map[uint64]ccip.MsgData{ + 1: {TokenData: [][]byte{{0x1}, {0x1}, {0x1}}}, + 2: {TokenData: [][]byte{{0x2}, {0x2}, {0x2}}}, + }, + }, + }, + f: 1, + }, + want: []ccip.ObservedMessage{ + {SeqNr: 1, MsgData: ccip.MsgData{TokenData: [][]byte{{0x1}, {0x1}, {0x1}}}}, + {SeqNr: 2, MsgData: ccip.MsgData{TokenData: [][]byte{{0x2}, {0x2}, {0x2}}}}, + }, + }, + { + name: "similar token data", + args: args{ + observations: []ccip.ExecutionObservation{ + { + Messages: map[uint64]ccip.MsgData{ + 1: {TokenData: [][]byte{{0x1}, {0x1}, {0x1}}}, + }, + }, + { + Messages: map[uint64]ccip.MsgData{ + 1: {TokenData: [][]byte{{0x1}, {0x1, 0x1}}}, + }, + }, + { + Messages: map[uint64]ccip.MsgData{ + 1: {TokenData: [][]byte{{0x1}, {0x1, 0x1}}}, + }, + }, + }, + f: 1, + }, + want: []ccip.ObservedMessage{ + {SeqNr: 1, MsgData: ccip.MsgData{TokenData: [][]byte{{0x1}, {0x1, 0x1}}}}, + }, + }, + { + name: "results should be deterministic", + args: args{ + observations: []ccip.ExecutionObservation{ + {Messages: map[uint64]ccip.MsgData{1: {TokenData: [][]byte{{0x2}}}}}, + {Messages: map[uint64]ccip.MsgData{1: {TokenData: [][]byte{{0x2}}}}}, + {Messages: map[uint64]ccip.MsgData{1: {TokenData: [][]byte{{0x1}}}}}, + {Messages: map[uint64]ccip.MsgData{1: {TokenData: [][]byte{{0x3}}}}}, + {Messages: map[uint64]ccip.MsgData{1: {TokenData: [][]byte{{0x3}}}}}, + {Messages: map[uint64]ccip.MsgData{1: {TokenData: [][]byte{{0x1}}}}}, + }, + f: 1, + }, + want: []ccip.ObservedMessage{ + {SeqNr: 1, MsgData: ccip.MsgData{TokenData: [][]byte{{0x3}}}}, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + res, err := calculateObservedMessagesConsensus( + tt.args.observations, + tt.args.f, + ) + assert.NoError(t, err) + sort.Slice(res, func(i, j int) bool { + return res[i].SeqNr < res[j].SeqNr + }) + assert.Equalf(t, tt.want, res, "calculateObservedMessagesConsensus(%v, %v)", tt.args.observations, tt.args.f) + }) + } +} + +func Test_getTokensPrices(t *testing.T) { + tk1 := ccipcalc.HexToAddress("1") + tk2 := ccipcalc.HexToAddress("2") + tk3 := ccipcalc.HexToAddress("3") + + testCases := []struct { + name string + feeTokens []cciptypes.Address + tokens []cciptypes.Address + retPrices []cciptypes.TokenPriceUpdate + expPrices map[cciptypes.Address]*big.Int + expErr bool + }{ + { + name: "base", + feeTokens: []cciptypes.Address{tk1, tk2}, + tokens: []cciptypes.Address{tk3}, + retPrices: []cciptypes.TokenPriceUpdate{ + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(10)}}, + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(20)}}, + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(30)}}, + }, + expPrices: map[cciptypes.Address]*big.Int{ + tk1: big.NewInt(10), + tk2: big.NewInt(20), + tk3: big.NewInt(30), + }, + expErr: false, + }, + { + name: "token is both fee token and normal token", + feeTokens: []cciptypes.Address{tk1, tk2}, + tokens: []cciptypes.Address{tk3, tk1}, + retPrices: []cciptypes.TokenPriceUpdate{ + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(10)}}, + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(20)}}, + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(30)}}, + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(10)}}, + }, + expPrices: map[cciptypes.Address]*big.Int{ + tk1: big.NewInt(10), + tk2: big.NewInt(20), + tk3: big.NewInt(30), + }, + expErr: false, + }, + { + name: "token is both fee token and normal token and price registry gave different price", + feeTokens: []cciptypes.Address{tk1, tk2}, + tokens: []cciptypes.Address{tk3, tk1}, + retPrices: []cciptypes.TokenPriceUpdate{ + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(10)}}, + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(20)}}, + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(30)}}, + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(1000)}}, + }, + expErr: true, + }, + { + name: "contract returns less prices than requested", + feeTokens: []cciptypes.Address{tk1, tk2}, + tokens: []cciptypes.Address{tk3}, + retPrices: []cciptypes.TokenPriceUpdate{ + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(10)}}, + {TokenPrice: cciptypes.TokenPrice{Value: big.NewInt(20)}}, + }, + expErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + priceReg := ccipdatamocks.NewPriceRegistryReader(t) + priceReg.On("GetTokenPrices", mock.Anything, mock.Anything).Return(tc.retPrices, nil) + priceReg.On("Address", mock.Anything).Return(cciptypes.Address(utils.RandomAddress().String()), nil).Maybe() + + tokenPrices, err := getTokensPrices(context.Background(), priceReg, append(tc.feeTokens, tc.tokens...)) + if tc.expErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + for tk, price := range tc.expPrices { + assert.Equal(t, price, tokenPrices[tk]) + } + }) + } +} + +func Test_calculateMessageMaxGas(t *testing.T) { + type args struct { + gasLimit *big.Int + numRequests int + dataLen int + numTokens int + } + tests := []struct { + name string + args args + want uint64 + wantErr bool + }{ + { + name: "base", + args: args{gasLimit: big.NewInt(1000), numRequests: 5, dataLen: 5, numTokens: 2}, + want: 826_336, + wantErr: false, + }, + { + name: "large", + args: args{gasLimit: big.NewInt(1000), numRequests: 1000, dataLen: 1000, numTokens: 1000}, + want: 346_485_176, + wantErr: false, + }, + { + name: "gas limit overflow", + args: args{gasLimit: big.NewInt(0).Mul(big.NewInt(math.MaxInt64), big.NewInt(math.MaxInt64))}, + want: 36_391_540, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := calculateMessageMaxGas(tt.args.gasLimit, tt.args.numRequests, tt.args.dataLen, tt.args.numTokens) + if tt.wantErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equalf(t, tt.want, got, "calculateMessageMaxGas(%v, %v, %v, %v)", tt.args.gasLimit, tt.args.numRequests, tt.args.dataLen, tt.args.numTokens) + }) + } +} + +func Test_inflightAggregates(t *testing.T) { + const n = 10 + addrs := make([]cciptypes.Address, n) + tokenAddrs := make([]cciptypes.Address, n) + for i := range addrs { + addrs[i] = cciptypes.Address(utils.RandomAddress().String()) + tokenAddrs[i] = cciptypes.Address(utils.RandomAddress().String()) + } + lggr := logger.TestLogger(t) + + testCases := []struct { + name string + inflight []InflightInternalExecutionReport + destTokenPrices map[cciptypes.Address]*big.Int + sourceToDest map[cciptypes.Address]cciptypes.Address + + expInflightSeqNrs mapset.Set[uint64] + expInflightAggrVal *big.Int + expMaxInflightSenderNonces map[cciptypes.Address]uint64 + expInflightTokenAmounts map[cciptypes.Address]*big.Int + expErr bool + }{ + { + name: "base", + inflight: []InflightInternalExecutionReport{ + { + messages: []cciptypes.EVM2EVMMessage{ + { + Sender: addrs[0], + SequenceNumber: 100, + Nonce: 2, + TokenAmounts: []cciptypes.TokenAmount{ + {Token: tokenAddrs[0], Amount: big.NewInt(1e18)}, + {Token: tokenAddrs[0], Amount: big.NewInt(2e18)}, + }, + }, + { + Sender: addrs[0], + SequenceNumber: 106, + Nonce: 4, + TokenAmounts: []cciptypes.TokenAmount{ + {Token: tokenAddrs[0], Amount: big.NewInt(1e18)}, + {Token: tokenAddrs[0], Amount: big.NewInt(5e18)}, + {Token: tokenAddrs[2], Amount: big.NewInt(5e18)}, + }, + }, + }, + }, + }, + destTokenPrices: map[cciptypes.Address]*big.Int{ + tokenAddrs[1]: big.NewInt(1000), + tokenAddrs[3]: big.NewInt(500), + }, + sourceToDest: map[cciptypes.Address]cciptypes.Address{ + tokenAddrs[0]: tokenAddrs[1], + tokenAddrs[2]: tokenAddrs[3], + }, + expInflightSeqNrs: mapset.NewSet[uint64](100, 106), + expInflightAggrVal: big.NewInt(9*1000 + 5*500), + expMaxInflightSenderNonces: map[cciptypes.Address]uint64{ + addrs[0]: 4, + }, + expInflightTokenAmounts: map[cciptypes.Address]*big.Int{ + tokenAddrs[0]: big.NewInt(9e18), + tokenAddrs[2]: big.NewInt(5e18), + }, + expErr: false, + }, + { + name: "missing price should be 0", + inflight: []InflightInternalExecutionReport{ + { + messages: []cciptypes.EVM2EVMMessage{ + { + Sender: addrs[0], + SequenceNumber: 100, + Nonce: 2, + TokenAmounts: []cciptypes.TokenAmount{ + {Token: tokenAddrs[0], Amount: big.NewInt(1e18)}, + }, + }, + }, + }, + }, + destTokenPrices: map[cciptypes.Address]*big.Int{ + tokenAddrs[3]: big.NewInt(500), + }, + sourceToDest: map[cciptypes.Address]cciptypes.Address{ + tokenAddrs[2]: tokenAddrs[3], + }, + expInflightAggrVal: big.NewInt(0), + expErr: false, + }, + { + name: "nothing inflight", + inflight: []InflightInternalExecutionReport{}, + expInflightSeqNrs: mapset.NewSet[uint64](), + expInflightAggrVal: big.NewInt(0), + expMaxInflightSenderNonces: map[cciptypes.Address]uint64{}, + expInflightTokenAmounts: map[cciptypes.Address]*big.Int{}, + expErr: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + inflightAggrVal, err := getInflightAggregateRateLimit( + lggr, + tc.inflight, + tc.destTokenPrices, + tc.sourceToDest, + ) + + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.True(t, reflect.DeepEqual(tc.expInflightAggrVal, inflightAggrVal)) + }) + } +} + +func Test_commitReportWithSendRequests_validate(t *testing.T) { + testCases := []struct { + name string + reportInterval cciptypes.CommitStoreInterval + numReqs int + expValid bool + }{ + { + name: "valid report", + reportInterval: cciptypes.CommitStoreInterval{Min: 10, Max: 20}, + numReqs: 11, + expValid: true, + }, + { + name: "report with one request", + reportInterval: cciptypes.CommitStoreInterval{Min: 1234, Max: 1234}, + numReqs: 1, + expValid: true, + }, + { + name: "request is missing", + reportInterval: cciptypes.CommitStoreInterval{Min: 1234, Max: 1234}, + numReqs: 0, + expValid: false, + }, + { + name: "requests are missing", + reportInterval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}, + numReqs: 5, + expValid: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + rep := commitReportWithSendRequests{ + commitReport: cciptypes.CommitStoreReport{ + Interval: tc.reportInterval, + }, + sendRequestsWithMeta: make([]cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, tc.numReqs), + } + err := rep.validate() + isValid := err == nil + assert.Equal(t, tc.expValid, isValid) + }) + } +} + +func Test_commitReportWithSendRequests_allRequestsAreExecutedAndFinalized(t *testing.T) { + testCases := []struct { + name string + reqs []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta + expRes bool + }{ + { + name: "all requests executed and finalized", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + {Executed: true, Finalized: true}, + {Executed: true, Finalized: true}, + {Executed: true, Finalized: true}, + }, + expRes: true, + }, + { + name: "true when there are zero requests", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{}, + expRes: true, + }, + { + name: "some request not executed", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + {Executed: true, Finalized: true}, + {Executed: true, Finalized: true}, + {Executed: false, Finalized: true}, + }, + expRes: false, + }, + { + name: "some request not finalized", + reqs: []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + {Executed: true, Finalized: true}, + {Executed: true, Finalized: true}, + {Executed: true, Finalized: false}, + }, + expRes: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + rep := commitReportWithSendRequests{sendRequestsWithMeta: tc.reqs} + res := rep.allRequestsAreExecutedAndFinalized() + assert.Equal(t, tc.expRes, res) + }) + } +} + +func Test_commitReportWithSendRequests_sendReqFits(t *testing.T) { + testCases := []struct { + name string + req cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta + report cciptypes.CommitStoreReport + expRes bool + }{ + { + name: "all requests executed and finalized", + req: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 1}, + }, + report: cciptypes.CommitStoreReport{ + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}, + }, + expRes: true, + }, + { + name: "all requests executed and finalized", + req: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 10}, + }, + report: cciptypes.CommitStoreReport{ + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}, + }, + expRes: true, + }, + { + name: "all requests executed and finalized", + req: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 11}, + }, + report: cciptypes.CommitStoreReport{ + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}, + }, + expRes: false, + }, + { + name: "all requests executed and finalized", + req: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 10}, + }, + report: cciptypes.CommitStoreReport{ + Interval: cciptypes.CommitStoreInterval{Min: 10, Max: 10}, + }, + expRes: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + r := &commitReportWithSendRequests{commitReport: tc.report} + assert.Equal(t, tc.expRes, r.sendReqFits(tc.req)) + }) + } +} + +// generateExecutionReport generates an execution report that can be used in tests +func generateExecutionReport(t *testing.T, numMsgs, tokensPerMsg, bytesPerMsg int) cciptypes.ExecReport { + messages := make([]cciptypes.EVM2EVMMessage, numMsgs) + + randAddr := func() cciptypes.Address { + return cciptypes.Address(utils.RandomAddress().String()) + } + + offChainTokenData := make([][][]byte, numMsgs) + for i := range messages { + tokenAmounts := make([]cciptypes.TokenAmount, tokensPerMsg) + for j := range tokenAmounts { + tokenAmounts[j] = cciptypes.TokenAmount{ + Token: randAddr(), + Amount: big.NewInt(math.MaxInt64), + } + } + + messages[i] = cciptypes.EVM2EVMMessage{ + SourceChainSelector: rand.Uint64(), + SequenceNumber: uint64(i + 1), + FeeTokenAmount: big.NewInt(rand.Int64()), + Sender: randAddr(), + Nonce: rand.Uint64(), + GasLimit: big.NewInt(rand.Int64()), + Strict: false, + Receiver: randAddr(), + Data: bytes.Repeat([]byte{1}, bytesPerMsg), + TokenAmounts: tokenAmounts, + FeeToken: randAddr(), + MessageID: utils.RandomBytes32(), + } + + data := []byte(`{"foo": "bar"}`) + offChainTokenData[i] = [][]byte{data, data, data} + } + + return cciptypes.ExecReport{ + Messages: messages, + OffchainTokenData: offChainTokenData, + Proofs: make([][32]byte, numMsgs), + ProofFlagBits: big.NewInt(rand.Int64()), + } +} + +func Test_selectReportsToFillBatch(t *testing.T) { + tests := []struct { + name string + messagesLimit uint64 // maximum number of messages that can be included in a batch. + expectedBatches int // expected number of batches. + expectedReports int // expected number of selected reports. + }{ + { + name: "pick all at once when messages limit is high", + messagesLimit: 5000, + expectedBatches: 1, + expectedReports: 10, + }, + { + name: "pick none when messages limit is below commit report size", + messagesLimit: 199, + expectedBatches: 0, + expectedReports: 0, + }, + { + name: "pick exactly the number in each report", + messagesLimit: 200, + expectedBatches: 10, + expectedReports: 10, + }, + { + name: "messages limit larger than individual reports", + messagesLimit: 300, + expectedBatches: 10, + expectedReports: 10, + }, + { + name: "messages limit larger than several reports", + messagesLimit: 650, + expectedBatches: 4, + expectedReports: 10, + }, + { + name: "default limit", + messagesLimit: 1024, + expectedBatches: 2, + expectedReports: 10, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + nbCommitStoreReports := 10 + nbMsgPerRoot := 200 + + var reports []cciptypes.CommitStoreReport + for i := 0; i < nbCommitStoreReports; i++ { + reports = append(reports, cciptypes.CommitStoreReport{Interval: cciptypes.CommitStoreInterval{Min: uint64(i * nbMsgPerRoot), Max: uint64((i+1)*nbMsgPerRoot - 1)}}) + } + + var unexpiredReportsBatches [][]cciptypes.CommitStoreReport + for i := 0; i < len(reports); { + unexpiredReports, step := selectReportsToFillBatch(reports[i:], tt.messagesLimit) + if step == 0 { + break + } + unexpiredReportsBatches = append(unexpiredReportsBatches, unexpiredReports) + i += step + } + assert.Len(t, unexpiredReportsBatches, tt.expectedBatches) + + var flatten []cciptypes.CommitStoreReport + for _, r := range unexpiredReportsBatches { + flatten = append(flatten, r...) + } + assert.Equal(t, tt.expectedReports, len(flatten)) + if tt.expectedBatches > 0 { + assert.Equal(t, reports, flatten) + } else { + assert.Empty(t, flatten) + } + }) + } +} + +func Test_prepareTokenExecData(t *testing.T) { + ctx := testutils.Context(t) + + weth := cciptypes.Address(utils.RandomAddress().String()) + wavax := cciptypes.Address(utils.RandomAddress().String()) + link := cciptypes.Address(utils.RandomAddress().String()) + usdc := cciptypes.Address(utils.RandomAddress().String()) + + wethPriceUpdate := cciptypes.TokenPriceUpdate{TokenPrice: cciptypes.TokenPrice{Token: weth, Value: big.NewInt(2e18)}} + wavaxPriceUpdate := cciptypes.TokenPriceUpdate{TokenPrice: cciptypes.TokenPrice{Token: wavax, Value: big.NewInt(3e18)}} + linkPriceUpdate := cciptypes.TokenPriceUpdate{TokenPrice: cciptypes.TokenPrice{Token: link, Value: big.NewInt(4e18)}} + usdcPriceUpdate := cciptypes.TokenPriceUpdate{TokenPrice: cciptypes.TokenPrice{Token: usdc, Value: big.NewInt(5e18)}} + + tokenPrices := map[cciptypes.Address]cciptypes.TokenPriceUpdate{weth: wethPriceUpdate, wavax: wavaxPriceUpdate, link: linkPriceUpdate, usdc: usdcPriceUpdate} + + tests := []struct { + name string + sourceFeeTokens []cciptypes.Address + sourceFeeTokensErr error + destTokens []cciptypes.Address + destTokensErr error + destFeeTokens []cciptypes.Address + destFeeTokensErr error + sourcePrices []cciptypes.TokenPriceUpdate + destPrices []cciptypes.TokenPriceUpdate + }{ + { + name: "only native token", + sourcePrices: []cciptypes.TokenPriceUpdate{wethPriceUpdate}, + destPrices: []cciptypes.TokenPriceUpdate{wavaxPriceUpdate}, + }, + { + name: "additional dest fee token", + destFeeTokens: []cciptypes.Address{link}, + sourcePrices: []cciptypes.TokenPriceUpdate{wethPriceUpdate}, + destPrices: []cciptypes.TokenPriceUpdate{linkPriceUpdate, wavaxPriceUpdate}, + }, + { + name: "dest tokens", + destTokens: []cciptypes.Address{link, usdc}, + sourcePrices: []cciptypes.TokenPriceUpdate{wethPriceUpdate}, + destPrices: []cciptypes.TokenPriceUpdate{linkPriceUpdate, usdcPriceUpdate, wavaxPriceUpdate}, + }, + { + name: "source fee tokens", + sourceFeeTokens: []cciptypes.Address{usdc}, + sourcePrices: []cciptypes.TokenPriceUpdate{usdcPriceUpdate, wethPriceUpdate}, + destPrices: []cciptypes.TokenPriceUpdate{wavaxPriceUpdate}, + }, + { + name: "source, dest and fee tokens", + sourceFeeTokens: []cciptypes.Address{usdc}, + destTokens: []cciptypes.Address{link}, + destFeeTokens: []cciptypes.Address{usdc}, + sourcePrices: []cciptypes.TokenPriceUpdate{usdcPriceUpdate, wethPriceUpdate}, + destPrices: []cciptypes.TokenPriceUpdate{usdcPriceUpdate, linkPriceUpdate, wavaxPriceUpdate}, + }, + { + name: "source, dest and fee tokens with duplicates", + sourceFeeTokens: []cciptypes.Address{link, weth}, + destTokens: []cciptypes.Address{link, wavax}, + destFeeTokens: []cciptypes.Address{link, wavax}, + sourcePrices: []cciptypes.TokenPriceUpdate{linkPriceUpdate, wethPriceUpdate}, + destPrices: []cciptypes.TokenPriceUpdate{linkPriceUpdate, wavaxPriceUpdate}, + }, + { + name: "everything fails when source fails", + sourceFeeTokensErr: errors.New("source error"), + }, + { + name: "everything fails when dest fee fails", + destFeeTokensErr: errors.New("dest fee error"), + }, + { + name: "everything fails when dest fails", + destTokensErr: errors.New("dest error"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + onrampReader := ccipdatamocks.NewOnRampReader(t) + offrampReader := ccipdatamocks.NewOffRampReader(t) + sourcePriceRegistry := ccipdatamocks.NewPriceRegistryReader(t) + destPriceRegistry := ccipdatamocks.NewPriceRegistryReader(t) + gasPriceEstimator := prices.NewMockGasPriceEstimatorExec(t) + sourcePriceRegistryProvider := ccipdataprovidermocks.NewPriceRegistry(t) + + sourcePriceRegistryAddress := cciptypes.Address(utils.RandomAddress().String()) + onrampReader.On("SourcePriceRegistryAddress", ctx).Return(sourcePriceRegistryAddress, nil).Maybe() + offrampReader.On("CurrentRateLimiterState", ctx).Return(cciptypes.TokenBucketRateLimit{}, nil).Maybe() + offrampReader.On("GetSourceToDestTokensMapping", ctx).Return(map[cciptypes.Address]cciptypes.Address{}, nil).Maybe() + gasPriceEstimator.On("GetGasPrice", ctx).Return(big.NewInt(1e9), nil).Maybe() + + offrampReader.On("GetTokens", ctx).Return(cciptypes.OffRampTokens{DestinationTokens: tt.destTokens}, tt.destTokensErr).Maybe() + sourcePriceRegistry.On("Address", mock.Anything).Return(sourcePriceRegistryAddress, nil).Maybe() + sourcePriceRegistry.On("GetFeeTokens", ctx).Return(tt.sourceFeeTokens, tt.sourceFeeTokensErr).Maybe() + sourcePriceRegistry.On("GetTokenPrices", ctx, mock.Anything).Return(tt.sourcePrices, nil).Maybe() + destPriceRegistry.On("GetFeeTokens", ctx).Return(tt.destFeeTokens, tt.destFeeTokensErr).Maybe() + destPriceRegistry.On("GetTokenPrices", ctx, mock.Anything).Return(tt.destPrices, nil).Maybe() + + sourcePriceRegistryProvider.On("NewPriceRegistryReader", ctx, sourcePriceRegistryAddress).Return(sourcePriceRegistry, nil).Maybe() + + reportingPlugin := ExecutionReportingPlugin{ + onRampReader: onrampReader, + offRampReader: offrampReader, + sourcePriceRegistry: sourcePriceRegistry, + sourcePriceRegistryProvider: sourcePriceRegistryProvider, + destPriceRegistry: destPriceRegistry, + gasPriceEstimator: gasPriceEstimator, + sourceWrappedNativeToken: weth, + destWrappedNative: wavax, + } + + tokenData, err := reportingPlugin.prepareTokenExecData(ctx) + if tt.destFeeTokensErr != nil || tt.sourceFeeTokensErr != nil || tt.destTokensErr != nil { + require.Error(t, err) + return + } + + require.NoError(t, err) + assert.Len(t, tokenData.sourceTokenPrices, len(tt.sourcePrices)) + assert.Len(t, tokenData.destTokenPrices, len(tt.destPrices)) + + for token, price := range tokenData.sourceTokenPrices { + assert.Equal(t, tokenPrices[token].Value, price) + } + + for token, price := range tokenData.destTokenPrices { + assert.Equal(t, tokenPrices[token].Value, price) + } + }) + } +} + +func encodeExecutionReport(t *testing.T, report cciptypes.ExecReport) []byte { + reader, err := v1_2_0.NewOffRamp(logger.TestLogger(t), utils.RandomAddress(), nil, nil, nil, nil) + require.NoError(t, err) + ctx := testutils.Context(t) + encodedReport, err := reader.EncodeExecutionReport(ctx, report) + require.NoError(t, err) + return encodedReport +} + +// Verify the price registry update mechanism in case of configuration change on the source onRamp. +func TestExecutionReportingPlugin_ensurePriceRegistrySynchronization(t *testing.T) { + p := &ExecutionReportingPlugin{} + p.lggr = logger.TestLogger(t) + p.sourcePriceRegistryLock = sync.RWMutex{} + + sourcePriceRegistryAddress1 := cciptypes.Address(utils.RandomAddress().String()) + sourcePriceRegistryAddress2 := cciptypes.Address(utils.RandomAddress().String()) + + mockPriceRegistryReader1 := ccipdatamocks.NewPriceRegistryReader(t) + mockPriceRegistryReader2 := ccipdatamocks.NewPriceRegistryReader(t) + mockPriceRegistryReader1.On("Address", mock.Anything).Return(sourcePriceRegistryAddress1, nil) + mockPriceRegistryReader2.On("Address", mock.Anything).Return(sourcePriceRegistryAddress2, nil).Maybe() + mockPriceRegistryReader1.On("Close", mock.Anything).Return(nil) + mockPriceRegistryReader2.On("Close", mock.Anything).Return(nil).Maybe() + + mockSourcePriceRegistryProvider := ccipdataprovidermocks.NewPriceRegistry(t) + mockSourcePriceRegistryProvider.On("NewPriceRegistryReader", mock.Anything, sourcePriceRegistryAddress1).Return(mockPriceRegistryReader1, nil) + mockSourcePriceRegistryProvider.On("NewPriceRegistryReader", mock.Anything, sourcePriceRegistryAddress2).Return(mockPriceRegistryReader2, nil) + p.sourcePriceRegistryProvider = mockSourcePriceRegistryProvider + + mockOnRampReader := ccipdatamocks.NewOnRampReader(t) + p.onRampReader = mockOnRampReader + + mockOnRampReader.On("SourcePriceRegistryAddress", mock.Anything).Return(sourcePriceRegistryAddress1, nil).Once() + require.Equal(t, nil, p.sourcePriceRegistry) + err := p.ensurePriceRegistrySynchronization(context.Background()) + require.NoError(t, err) + require.Equal(t, mockPriceRegistryReader1, p.sourcePriceRegistry) + + mockOnRampReader.On("SourcePriceRegistryAddress", mock.Anything).Return(sourcePriceRegistryAddress2, nil).Once() + err = p.ensurePriceRegistrySynchronization(context.Background()) + require.NoError(t, err) + require.Equal(t, mockPriceRegistryReader2, p.sourcePriceRegistry) +} diff --git a/core/services/ocr2/plugins/ccip/clo_ccip_integration_test.go b/core/services/ocr2/plugins/ccip/clo_ccip_integration_test.go new file mode 100644 index 0000000000..142ba006be --- /dev/null +++ b/core/services/ocr2/plugins/ccip/clo_ccip_integration_test.go @@ -0,0 +1,137 @@ +package ccip_test + +import ( + "encoding/json" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" + integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/integration" +) + +func Test_CLOSpecApprovalFlow_pipeline(t *testing.T) { + ccipTH := integrationtesthelpers.SetupCCIPIntegrationTH(t, testhelpers.SourceChainID, testhelpers.SourceChainSelector, testhelpers.DestChainID, testhelpers.DestChainSelector) + + tokenPricesUSDPipeline, linkUSD, ethUSD := ccipTH.CreatePricesPipeline(t) + defer linkUSD.Close() + defer ethUSD.Close() + + test_CLOSpecApprovalFlow(t, ccipTH, tokenPricesUSDPipeline, "") +} + +func Test_CLOSpecApprovalFlow_dynamicPriceGetter(t *testing.T) { + ccipTH := integrationtesthelpers.SetupCCIPIntegrationTH(t, testhelpers.SourceChainID, testhelpers.SourceChainSelector, testhelpers.DestChainID, testhelpers.DestChainSelector) + + //Set up the aggregators here to avoid modifying ccipTH. + srcLinkAddr := ccipTH.Source.LinkToken.Address() + dstLinkAddr := ccipTH.Dest.LinkToken.Address() + srcNativeAddr, err := ccipTH.Source.Router.GetWrappedNative(nil) + require.NoError(t, err) + aggDstNativeAddr := ccipTH.Dest.WrappedNative.Address() + + aggSrcNatAddr, _, aggSrcNat, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Source.User, ccipTH.Source.Chain, 18, big.NewInt(2e18)) + require.NoError(t, err) + _, err = aggSrcNat.UpdateRoundData(ccipTH.Source.User, big.NewInt(50), big.NewInt(17000000), big.NewInt(1000), big.NewInt(1000)) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + aggSrcLnkAddr, _, aggSrcLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Source.User, ccipTH.Source.Chain, 18, big.NewInt(3e18)) + require.NoError(t, err) + ccipTH.Dest.Chain.Commit() + _, err = aggSrcLnk.UpdateRoundData(ccipTH.Source.User, big.NewInt(50), big.NewInt(8000000), big.NewInt(1000), big.NewInt(1000)) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + aggDstLnkAddr, _, aggDstLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Dest.User, ccipTH.Dest.Chain, 18, big.NewInt(3e18)) + require.NoError(t, err) + ccipTH.Dest.Chain.Commit() + _, err = aggDstLnk.UpdateRoundData(ccipTH.Dest.User, big.NewInt(50), big.NewInt(8000000), big.NewInt(1000), big.NewInt(1000)) + require.NoError(t, err) + ccipTH.Dest.Chain.Commit() + + // Check content is ok on aggregator. + tmp, err := aggDstLnk.LatestRoundData(&bind.CallOpts{}) + require.NoError(t, err) + require.Equal(t, big.NewInt(50), tmp.RoundId) + require.Equal(t, big.NewInt(8000000), tmp.Answer) + + // deploy dest wrapped native aggregator + aggDstNativeAggrAddr, _, aggDstNativeAggr, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Dest.User, ccipTH.Dest.Chain, 18, big.NewInt(3e18)) + require.NoError(t, err) + ccipTH.Dest.Chain.Commit() + _, err = aggDstNativeAggr.UpdateRoundData(ccipTH.Dest.User, big.NewInt(50), big.NewInt(500000), big.NewInt(1000), big.NewInt(1000)) + require.NoError(t, err) + ccipTH.Dest.Chain.Commit() + + priceGetterConfig := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ + srcLinkAddr: { + ChainID: ccipTH.Source.ChainID, + AggregatorContractAddress: aggSrcLnkAddr, + }, + srcNativeAddr: { + ChainID: ccipTH.Source.ChainID, + AggregatorContractAddress: aggSrcNatAddr, + }, + dstLinkAddr: { + ChainID: ccipTH.Dest.ChainID, + AggregatorContractAddress: aggDstLnkAddr, + }, + aggDstNativeAddr: { + ChainID: ccipTH.Dest.ChainID, + AggregatorContractAddress: aggDstNativeAggrAddr, + }, + }, + StaticPrices: map[common.Address]config.StaticPriceConfig{}, + } + priceGetterConfigBytes, err := json.MarshalIndent(priceGetterConfig, "", " ") + require.NoError(t, err) + priceGetterConfigJson := string(priceGetterConfigBytes) + + test_CLOSpecApprovalFlow(t, ccipTH, "", priceGetterConfigJson) +} + +func test_CLOSpecApprovalFlow(t *testing.T, ccipTH integrationtesthelpers.CCIPIntegrationTestHarness, tokenPricesUSDPipeline string, priceGetterConfiguration string) { + jobParams := ccipTH.SetUpNodesAndJobs(t, tokenPricesUSDPipeline, priceGetterConfiguration, "http://blah.com") + ccipTH.SetupFeedsManager(t) + + // Propose and approve new specs + ccipTH.ApproveJobSpecs(t, jobParams) + + // Sanity check that CCIP works after CLO flow + currentSeqNum := 1 + + extraArgs, err := testhelpers.GetEVMExtraArgsV1(big.NewInt(200_003), false) + require.NoError(t, err) + + msg := router.ClientEVM2AnyMessage{ + Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[0].Receiver.Address()), + Data: utils.RandomAddress().Bytes(), + TokenAmounts: []router.ClientEVMTokenAmount{}, + FeeToken: ccipTH.Source.LinkToken.Address(), + ExtraArgs: extraArgs, + } + fee, err := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) + require.NoError(t, err) + + _, err = ccipTH.Source.LinkToken.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), new(big.Int).Set(fee)) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + ccipTH.SendRequest(t, msg) + ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum) + ccipTH.EventuallyReportCommitted(t, currentSeqNum) + + executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum) + assert.Len(t, executionLogs, 1) + ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) +} diff --git a/core/services/ocr2/plugins/ccip/config/chain_config.go b/core/services/ocr2/plugins/ccip/config/chain_config.go new file mode 100644 index 0000000000..ff82def606 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/config/chain_config.go @@ -0,0 +1,48 @@ +package config + +import ( + "strconv" + + "github.com/pkg/errors" + chainselectors "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/services/job" +) + +func GetChainFromSpec(spec *job.OCR2OracleSpec, chainSet legacyevm.LegacyChainContainer) (legacyevm.Chain, int64, error) { + chainIDInterface, ok := spec.RelayConfig["chainID"] + if !ok { + return nil, 0, errors.New("chainID must be provided in relay config") + } + destChainID := uint64(chainIDInterface.(float64)) + return GetChainByChainID(chainSet, destChainID) +} + +func GetChainByChainSelector(chainSet legacyevm.LegacyChainContainer, chainSelector uint64) (legacyevm.Chain, int64, error) { + chainID, err := chainselectors.ChainIdFromSelector(chainSelector) + if err != nil { + return nil, 0, err + } + return GetChainByChainID(chainSet, chainID) +} + +func GetChainByChainID(chainSet legacyevm.LegacyChainContainer, chainID uint64) (legacyevm.Chain, int64, error) { + chain, err := chainSet.Get(strconv.FormatUint(chainID, 10)) + if err != nil { + return nil, 0, errors.Wrap(err, "chain not found in chainset") + } + return chain, chain.ID().Int64(), nil +} + +func ResolveChainNames(sourceChainId int64, destChainId int64) (string, string, error) { + sourceChainName, err := chainselectors.NameFromChainId(uint64(sourceChainId)) + if err != nil { + return "", "", err + } + destChainName, err := chainselectors.NameFromChainId(uint64(destChainId)) + if err != nil { + return "", "", err + } + return sourceChainName, destChainName, nil +} diff --git a/core/services/ocr2/plugins/ccip/config/chain_config_test.go b/core/services/ocr2/plugins/ccip/config/chain_config_test.go new file mode 100644 index 0000000000..df2351a5ea --- /dev/null +++ b/core/services/ocr2/plugins/ccip/config/chain_config_test.go @@ -0,0 +1,135 @@ +package config + +import ( + "math/big" + "strconv" + "testing" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/job" +) + +func TestGetChainFromSpec(t *testing.T) { + testChainID := int64(1337) + + tests := []struct { + name string + spec *job.OCR2OracleSpec + expectedErr bool + expectedErrMsg string + }{ + { + name: "success", + spec: &job.OCR2OracleSpec{ + RelayConfig: job.JSONConfig{ + "chainID": float64(testChainID), + }, + }, + expectedErr: false, + }, + { + name: "missing_chain_ID", + spec: &job.OCR2OracleSpec{}, + expectedErr: true, + expectedErrMsg: "chainID must be provided in relay config", + }, + } + + mockChain := mocks.NewChain(t) + mockChain.On("ID").Return(big.NewInt(testChainID)).Maybe() + + mockChainSet := mocks.NewLegacyChainContainer(t) + mockChainSet.On("Get", strconv.FormatInt(testChainID, 10)).Return(mockChain, nil).Maybe() + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + chain, chainID, err := GetChainFromSpec(test.spec, mockChainSet) + if test.expectedErr { + require.Error(t, err) + require.Contains(t, err.Error(), test.expectedErrMsg) + } else { + require.NoError(t, err) + require.Equal(t, mockChain, chain) + require.Equal(t, testChainID, chainID) + } + }) + } +} + +func TestGetChainByChainSelector_success(t *testing.T) { + mockChain := mocks.NewChain(t) + mockChain.On("ID").Return(big.NewInt(11155111)) + + mockChainSet := mocks.NewLegacyChainContainer(t) + mockChainSet.On("Get", "11155111").Return(mockChain, nil) + + // Ethereum Sepolia chain selector. + chain, chainID, err := GetChainByChainSelector(mockChainSet, uint64(16015286601757825753)) + require.NoError(t, err) + require.Equal(t, mockChain, chain) + require.Equal(t, int64(11155111), chainID) +} + +func TestGetChainByChainSelector_selectorNotFound(t *testing.T) { + mockChainSet := mocks.NewLegacyChainContainer(t) + + _, _, err := GetChainByChainSelector(mockChainSet, uint64(444000444)) + require.Error(t, err) +} + +func TestGetChainById_notFound(t *testing.T) { + mockChainSet := mocks.NewLegacyChainContainer(t) + mockChainSet.On("Get", "444").Return(nil, errors.New("test")).Maybe() + + _, _, err := GetChainByChainID(mockChainSet, uint64(444)) + require.Error(t, err) + require.Contains(t, err.Error(), "chain not found in chainset") +} + +func TestResolveChainNames(t *testing.T) { + tests := []struct { + name string + sourceChainId int64 + destChainId int64 + expectedSourceChainName string + expectedDestChainName string + expectedErr bool + }{ + { + name: "success", + sourceChainId: 1, + destChainId: 10, + expectedSourceChainName: "ethereum-mainnet", + expectedDestChainName: "ethereum-mainnet-optimism-1", + }, + { + name: "source chain not found", + sourceChainId: 901278309182, + destChainId: 10, + expectedErr: true, + }, + { + name: "dest chain not found", + sourceChainId: 1, + destChainId: 901278309182, + expectedErr: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + sourceChainName, destChainName, err := ResolveChainNames(test.sourceChainId, test.destChainId) + if test.expectedErr { + require.Error(t, err) + } else { + require.NoError(t, err) + assert.Equal(t, test.expectedSourceChainName, sourceChainName) + assert.Equal(t, test.expectedDestChainName, destChainName) + } + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/config/config.go b/core/services/ocr2/plugins/ccip/config/config.go new file mode 100644 index 0000000000..a24a6edfd1 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/config/config.go @@ -0,0 +1,152 @@ +package config + +import ( + "encoding/json" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/utils/bytes" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" +) + +// CommitPluginJobSpecConfig contains the plugin specific variables for the ccip.CCIPCommit plugin. +type CommitPluginJobSpecConfig struct { + SourceStartBlock, DestStartBlock uint64 // Only for first time job add. + OffRamp cciptypes.Address `json:"offRamp"` + // TokenPricesUSDPipeline should contain a token price pipeline for the following tokens: + // The SOURCE chain wrapped native + // The DESTINATION supported tokens (including fee tokens) as defined in destination OffRamp and PriceRegistry. + TokenPricesUSDPipeline string `json:"tokenPricesUSDPipeline,omitempty"` + // PriceGetterConfig defines where to get the token prices from (i.e. static or aggregator source). + PriceGetterConfig *DynamicPriceGetterConfig `json:"priceGetterConfig,omitempty"` +} + +type CommitPluginConfig struct { + IsSourceProvider bool + SourceStartBlock, DestStartBlock uint64 +} + +func (c CommitPluginConfig) Encode() ([]byte, error) { + bytes, err := json.Marshal(c) + if err != nil { + return nil, err + } + return bytes, nil +} + +// DynamicPriceGetterConfig specifies which configuration to use for getting the price of tokens (map keys). +type DynamicPriceGetterConfig struct { + AggregatorPrices map[common.Address]AggregatorPriceConfig `json:"aggregatorPrices"` + StaticPrices map[common.Address]StaticPriceConfig `json:"staticPrices"` +} + +// AggregatorPriceConfig specifies a price retrieved from an aggregator contract. +type AggregatorPriceConfig struct { + ChainID uint64 `json:"chainID,string"` + AggregatorContractAddress common.Address `json:"contractAddress"` +} + +// StaticPriceConfig specifies a price defined statically. +type StaticPriceConfig struct { + ChainID uint64 `json:"chainID,string"` + Price *big.Int `json:"price"` +} + +// UnmarshalJSON provides a custom un-marshaller to handle JSON embedded in Toml content. +func (c *DynamicPriceGetterConfig) UnmarshalJSON(data []byte) error { + type Alias DynamicPriceGetterConfig + if bytes.HasQuotes(data) { + trimmed := string(bytes.TrimQuotes(data)) + trimmed = strings.ReplaceAll(trimmed, "\\n", "") + trimmed = strings.ReplaceAll(trimmed, "\\t", "") + trimmed = strings.ReplaceAll(trimmed, "\\", "") + return json.Unmarshal([]byte(trimmed), (*Alias)(c)) + } + return json.Unmarshal(data, (*Alias)(c)) +} + +func (c *DynamicPriceGetterConfig) Validate() error { + for addr, v := range c.AggregatorPrices { + if addr == utils.ZeroAddress { + return fmt.Errorf("token address is zero") + } + if v.AggregatorContractAddress == utils.ZeroAddress { + return fmt.Errorf("aggregator contract address is zero") + } + if v.ChainID == 0 { + return fmt.Errorf("chain id is zero") + } + } + + for addr, v := range c.StaticPrices { + if addr == utils.ZeroAddress { + return fmt.Errorf("token address is zero") + } + if v.ChainID == 0 { + return fmt.Errorf("chain id is zero") + } + } + + // Ensure no duplication in token price resolution rules. + if c.AggregatorPrices != nil && c.StaticPrices != nil { + for tk := range c.AggregatorPrices { + if _, exists := c.StaticPrices[tk]; exists { + return fmt.Errorf("token %s defined in both aggregator and static price rules", tk) + } + } + } + return nil +} + +// ExecPluginJobSpecConfig contains the plugin specific variables for the ccip.CCIPExecution plugin. +type ExecPluginJobSpecConfig struct { + SourceStartBlock, DestStartBlock uint64 // Only for first time job add. + USDCConfig USDCConfig +} + +type USDCConfig struct { + SourceTokenAddress common.Address + SourceMessageTransmitterAddress common.Address + AttestationAPI string + AttestationAPITimeoutSeconds uint + // AttestationAPIIntervalMilliseconds can be set to -1 to disable or 0 to use a default interval. + AttestationAPIIntervalMilliseconds int +} + +type ExecPluginConfig struct { + SourceStartBlock, DestStartBlock uint64 // Only for first time job add. + IsSourceProvider bool + USDCConfig USDCConfig + JobID string +} + +func (e ExecPluginConfig) Encode() ([]byte, error) { + bytes, err := json.Marshal(e) + if err != nil { + return nil, err + } + return bytes, nil +} + +func (uc *USDCConfig) ValidateUSDCConfig() error { + if uc.AttestationAPI == "" { + return errors.New("AttestationAPI is required") + } + if uc.AttestationAPIIntervalMilliseconds < -1 { + return errors.New("AttestationAPIIntervalMilliseconds must be -1 to disable, 0 for default or greater to define the exact interval") + } + if uc.SourceTokenAddress == utils.ZeroAddress { + return errors.New("SourceTokenAddress is required") + } + if uc.SourceMessageTransmitterAddress == utils.ZeroAddress { + return errors.New("SourceMessageTransmitterAddress is required") + } + + return nil +} diff --git a/core/services/ocr2/plugins/ccip/config/config_test.go b/core/services/ocr2/plugins/ccip/config/config_test.go new file mode 100644 index 0000000000..e6207aa223 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/config/config_test.go @@ -0,0 +1,234 @@ +package config + +import ( + "encoding/json" + "fmt" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +func TestCommitConfig(t *testing.T) { + tests := []struct { + name string + cfg CommitPluginJobSpecConfig + expectedValidationError error + }{ + { + name: "valid config", + cfg: CommitPluginJobSpecConfig{ + SourceStartBlock: 222, + DestStartBlock: 333, + OffRamp: ccipcalc.HexToAddress("0x123"), + TokenPricesUSDPipeline: `merge [type=merge left="{}" right="{\"0xC79b96044906550A5652BCf20a6EA02f139B9Ae5\":\"1000000000000000000\"}"];`, + PriceGetterConfig: &DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]AggregatorPriceConfig{ + common.HexToAddress("0x0820c05e1fba1244763a494a52272170c321cad3"): { + ChainID: 1000, + AggregatorContractAddress: common.HexToAddress("0xb8dabd288955d302d05ca6b011bb46dfa3ea7acf"), + }, + common.HexToAddress("0x4a98bb4d65347016a7ab6f85bea24b129c9a1272"): { + ChainID: 1337, + AggregatorContractAddress: common.HexToAddress("0xb80244cc8b0bb18db071c150b36e9bcb8310b236"), + }, + }, + StaticPrices: map[common.Address]StaticPriceConfig{ + common.HexToAddress("0xec8c353470ccaa4f43067fcde40558e084a12927"): { + ChainID: 1057, + Price: big.NewInt(1000000000000000000), + }, + }, + }, + }, + expectedValidationError: nil, + }, + { + name: "missing dynamic aggregator contract address", + cfg: CommitPluginJobSpecConfig{ + SourceStartBlock: 222, + DestStartBlock: 333, + OffRamp: ccipcalc.HexToAddress("0x123"), + TokenPricesUSDPipeline: `merge [type=merge left="{}" right="{\"0xC79b96044906550A5652BCf20a6EA02f139B9Ae5\":\"1000000000000000000\"}"];`, + PriceGetterConfig: &DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]AggregatorPriceConfig{ + common.HexToAddress("0x0820c05e1fba1244763a494a52272170c321cad3"): { + ChainID: 1000, + AggregatorContractAddress: common.HexToAddress("0xb8dabd288955d302d05ca6b011bb46dfa3ea7acf"), + }, + common.HexToAddress("0x4a98bb4d65347016a7ab6f85bea24b129c9a1272"): { + ChainID: 1337, + AggregatorContractAddress: common.HexToAddress(""), + }, + }, + StaticPrices: map[common.Address]StaticPriceConfig{ + common.HexToAddress("0xec8c353470ccaa4f43067fcde40558e084a12927"): { + ChainID: 1057, + Price: big.NewInt(1000000000000000000), + }, + }, + }, + }, + expectedValidationError: fmt.Errorf("aggregator contract address is zero"), + }, + { + name: "missing chain ID", + cfg: CommitPluginJobSpecConfig{ + SourceStartBlock: 222, + DestStartBlock: 333, + OffRamp: ccipcalc.HexToAddress("0x123"), + TokenPricesUSDPipeline: `merge [type=merge left="{}" right="{\"0xC79b96044906550A5652BCf20a6EA02f139B9Ae5\":\"1000000000000000000\"}"];`, + PriceGetterConfig: &DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]AggregatorPriceConfig{ + common.HexToAddress("0x0820c05e1fba1244763a494a52272170c321cad3"): { + ChainID: 1000, + AggregatorContractAddress: common.HexToAddress("0xb8dabd288955d302d05ca6b011bb46dfa3ea7acf"), + }, + common.HexToAddress("0x4a98bb4d65347016a7ab6f85bea24b129c9a1272"): { + ChainID: 1337, + AggregatorContractAddress: common.HexToAddress("0xb80244cc8b0bb18db071c150b36e9bcb8310b236"), + }, + }, + StaticPrices: map[common.Address]StaticPriceConfig{ + common.HexToAddress("0xec8c353470ccaa4f43067fcde40558e084a12927"): { + ChainID: 0, + Price: big.NewInt(1000000000000000000), + }, + }, + }, + }, + expectedValidationError: fmt.Errorf("chain id is zero"), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + // Verify proper marshall/unmarshalling of the config. + bts, err := json.Marshal(test.cfg) + require.NoError(t, err) + parsedConfig := CommitPluginJobSpecConfig{} + require.NoError(t, json.Unmarshal(bts, &parsedConfig)) + require.Equal(t, test.cfg, parsedConfig) + + // Ensure correctness of price getter configuration. + pgc := test.cfg.PriceGetterConfig + err = pgc.Validate() + if test.expectedValidationError != nil { + require.ErrorContains(t, err, test.expectedValidationError.Error()) + } else { + require.NoError(t, err) + require.Equal(t, uint64(1000), pgc.AggregatorPrices[common.HexToAddress("0x0820c05e1fba1244763a494a52272170c321cad3")].ChainID) + require.Equal(t, uint64(1337), pgc.AggregatorPrices[common.HexToAddress("0x4a98bb4d65347016a7ab6f85bea24b129c9a1272")].ChainID) + require.Equal(t, uint64(1057), pgc.StaticPrices[common.HexToAddress("0xec8c353470ccaa4f43067fcde40558e084a12927")].ChainID) + } + }) + } +} + +func TestExecutionConfig(t *testing.T) { + exampleConfig := ExecPluginJobSpecConfig{ + SourceStartBlock: 222, + DestStartBlock: 333, + } + + bts, err := json.Marshal(exampleConfig) + require.NoError(t, err) + + parsedConfig := ExecPluginJobSpecConfig{} + require.NoError(t, json.Unmarshal(bts, &parsedConfig)) + + require.Equal(t, exampleConfig, parsedConfig) +} + +func TestUSDCValidate(t *testing.T) { + testcases := []struct { + config USDCConfig + err string + }{ + { + config: USDCConfig{}, + err: "AttestationAPI is required", + }, + { + config: USDCConfig{ + AttestationAPI: "api", + }, + err: "SourceTokenAddress is required", + }, + { + config: USDCConfig{ + AttestationAPI: "api", + SourceTokenAddress: utils.ZeroAddress, + }, + err: "SourceTokenAddress is required", + }, + { + config: USDCConfig{ + AttestationAPI: "api", + SourceTokenAddress: utils.RandomAddress(), + }, + err: "SourceMessageTransmitterAddress is required", + }, + { + config: USDCConfig{ + AttestationAPI: "api", + SourceTokenAddress: utils.RandomAddress(), + SourceMessageTransmitterAddress: utils.ZeroAddress, + }, + err: "SourceMessageTransmitterAddress is required", + }, + { + config: USDCConfig{ + AttestationAPI: "api", + SourceTokenAddress: utils.RandomAddress(), + SourceMessageTransmitterAddress: utils.RandomAddress(), + }, + err: "", + }, + } + + for _, tc := range testcases { + tc := tc + t.Run(fmt.Sprintf("error = %s", tc.err), func(t *testing.T) { + t.Parallel() + err := tc.config.ValidateUSDCConfig() + if tc.err != "" { + require.ErrorContains(t, err, tc.err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestUnmarshallDynamicPriceConfig(t *testing.T) { + jsonCfg := ` +{ + "aggregatorPrices": { + "0x0820c05e1fba1244763a494a52272170c321cad3": { + "chainID": "1000", + "contractAddress": "0xb8dabd288955d302d05ca6b011bb46dfa3ea7acf" + }, + "0x4a98bb4d65347016a7ab6f85bea24b129c9a1272": { + "chainID": "1337", + "contractAddress": "0xb80244cc8b0bb18db071c150b36e9bcb8310b236" + } + }, + "staticPrices": { + "0xec8c353470ccaa4f43067fcde40558e084a12927": { + "chainID": "1057", + "price": 1000000000000000000 + } + } +} +` + var cfg DynamicPriceGetterConfig + err := json.Unmarshal([]byte(jsonCfg), &cfg) + require.NoError(t, err) + err = cfg.Validate() + require.NoError(t, err) +} diff --git a/core/services/ocr2/plugins/ccip/config/offchain_config.go b/core/services/ocr2/plugins/ccip/config/offchain_config.go new file mode 100644 index 0000000000..f8fba3f1bc --- /dev/null +++ b/core/services/ocr2/plugins/ccip/config/offchain_config.go @@ -0,0 +1,26 @@ +package config + +import ( + "encoding/json" +) + +type OffchainConfig interface { + Validate() error +} + +func DecodeOffchainConfig[T OffchainConfig](encodedConfig []byte) (T, error) { + var result T + err := json.Unmarshal(encodedConfig, &result) + if err != nil { + return result, err + } + err = result.Validate() + if err != nil { + return result, err + } + return result, nil +} + +func EncodeOffchainConfig[T OffchainConfig](occ T) ([]byte, error) { + return json.Marshal(occ) +} diff --git a/core/services/ocr2/plugins/ccip/config/type_and_version.go b/core/services/ocr2/plugins/ccip/config/type_and_version.go new file mode 100644 index 0000000000..fdfd892b08 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/config/type_and_version.go @@ -0,0 +1,73 @@ +package config + +import ( + "fmt" + "strings" + + "github.com/Masterminds/semver/v3" + mapset "github.com/deckarep/golang-set/v2" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + + type_and_version "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/type_and_version_interface_wrapper" +) + +type ContractType string + +var ( + EVM2EVMOnRamp ContractType = "EVM2EVMOnRamp" + EVM2EVMOffRamp ContractType = "EVM2EVMOffRamp" + CommitStore ContractType = "CommitStore" + PriceRegistry ContractType = "PriceRegistry" + ContractTypes = mapset.NewSet[ContractType]( + EVM2EVMOffRamp, + EVM2EVMOnRamp, + CommitStore, + PriceRegistry, + ) +) + +func VerifyTypeAndVersion(addr common.Address, client bind.ContractBackend, expectedType ContractType) (semver.Version, error) { + contractType, version, err := TypeAndVersion(addr, client) + if err != nil { + return semver.Version{}, fmt.Errorf("failed getting type and version %w", err) + } + if contractType != expectedType { + return semver.Version{}, fmt.Errorf("wrong contract type %s", contractType) + } + return version, nil +} + +func TypeAndVersion(addr common.Address, client bind.ContractBackend) (ContractType, semver.Version, error) { + tv, err := type_and_version.NewTypeAndVersionInterface(addr, client) + if err != nil { + return "", semver.Version{}, err + } + tvStr, err := tv.TypeAndVersion(nil) + if err != nil { + return "", semver.Version{}, fmt.Errorf("error calling typeAndVersion on addr: %s %w", addr.String(), err) + } + + contractType, versionStr, err := ParseTypeAndVersion(tvStr) + if err != nil { + return "", semver.Version{}, err + } + v, err := semver.NewVersion(versionStr) + if err != nil { + return "", semver.Version{}, fmt.Errorf("failed parsing version %s: %w", versionStr, err) + } + + if !ContractTypes.Contains(ContractType(contractType)) { + return "", semver.Version{}, fmt.Errorf("unrecognized contract type %v", contractType) + } + return ContractType(contractType), *v, nil +} + +func ParseTypeAndVersion(tvStr string) (string, string, error) { + typeAndVersionValues := strings.Split(tvStr, " ") + + if len(typeAndVersionValues) < 2 { + return "", "", fmt.Errorf("invalid type and version %s", tvStr) + } + return typeAndVersionValues[0], typeAndVersionValues[1], nil +} diff --git a/core/services/ocr2/plugins/ccip/exportinternal.go b/core/services/ocr2/plugins/ccip/exportinternal.go new file mode 100644 index 0000000000..2a5767ac85 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/exportinternal.go @@ -0,0 +1,135 @@ +package ccip + +import ( + "context" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" +) + +func GenericAddrToEvm(addr ccip.Address) (common.Address, error) { + return ccipcalc.GenericAddrToEvm(addr) +} + +func EvmAddrToGeneric(addr common.Address) ccip.Address { + return ccipcalc.EvmAddrToGeneric(addr) +} + +func NewEvmPriceRegistry(lp logpoller.LogPoller, ec client.Client, lggr logger.Logger, pluginLabel string) *ccipdataprovider.EvmPriceRegistry { + return ccipdataprovider.NewEvmPriceRegistry(lp, ec, lggr, pluginLabel) +} + +type VersionFinder = factory.VersionFinder + +func NewCommitStoreReader(lggr logger.Logger, versionFinder VersionFinder, address ccip.Address, ec client.Client, lp logpoller.LogPoller) (ccipdata.CommitStoreReader, error) { + return factory.NewCommitStoreReader(lggr, versionFinder, address, ec, lp) +} + +func CloseCommitStoreReader(lggr logger.Logger, versionFinder VersionFinder, address ccip.Address, ec client.Client, lp logpoller.LogPoller) error { + return factory.CloseCommitStoreReader(lggr, versionFinder, address, ec, lp) +} + +func NewOffRampReader(lggr logger.Logger, versionFinder VersionFinder, addr ccip.Address, destClient client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, destMaxGasPrice *big.Int, registerFilters bool) (ccipdata.OffRampReader, error) { + return factory.NewOffRampReader(lggr, versionFinder, addr, destClient, lp, estimator, destMaxGasPrice, registerFilters) +} + +func CloseOffRampReader(lggr logger.Logger, versionFinder VersionFinder, addr ccip.Address, destClient client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, destMaxGasPrice *big.Int) error { + return factory.CloseOffRampReader(lggr, versionFinder, addr, destClient, lp, estimator, destMaxGasPrice) +} + +func NewEvmVersionFinder() factory.EvmVersionFinder { + return factory.NewEvmVersionFinder() +} + +func NewOnRampReader(lggr logger.Logger, versionFinder VersionFinder, sourceSelector, destSelector uint64, onRampAddress ccip.Address, sourceLP logpoller.LogPoller, source client.Client) (ccipdata.OnRampReader, error) { + return factory.NewOnRampReader(lggr, versionFinder, sourceSelector, destSelector, onRampAddress, sourceLP, source) +} + +func CloseOnRampReader(lggr logger.Logger, versionFinder VersionFinder, sourceSelector, destSelector uint64, onRampAddress ccip.Address, sourceLP logpoller.LogPoller, source client.Client) error { + return factory.CloseOnRampReader(lggr, versionFinder, sourceSelector, destSelector, onRampAddress, sourceLP, source) +} + +type OffRampReader = ccipdata.OffRampReader + +type DynamicPriceGetterClient = pricegetter.DynamicPriceGetterClient + +type DynamicPriceGetter = pricegetter.DynamicPriceGetter + +func NewDynamicPriceGetterClient(batchCaller rpclib.EvmBatchCaller) DynamicPriceGetterClient { + return pricegetter.NewDynamicPriceGetterClient(batchCaller) +} + +func NewDynamicPriceGetter(cfg config.DynamicPriceGetterConfig, evmClients map[uint64]DynamicPriceGetterClient) (*DynamicPriceGetter, error) { + return pricegetter.NewDynamicPriceGetter(cfg, evmClients) +} + +func NewDynamicLimitedBatchCaller( + lggr logger.Logger, batchSender rpclib.BatchSender, batchSizeLimit, backOffMultiplier, parallelRpcCallsLimit uint, +) *rpclib.DynamicLimitedBatchCaller { + return rpclib.NewDynamicLimitedBatchCaller(lggr, batchSender, batchSizeLimit, backOffMultiplier, parallelRpcCallsLimit) +} + +func NewUSDCReader(lggr logger.Logger, jobID string, transmitter common.Address, lp logpoller.LogPoller, registerFilters bool) (*ccipdata.USDCReaderImpl, error) { + return ccipdata.NewUSDCReader(lggr, jobID, transmitter, lp, registerFilters) +} + +func CloseUSDCReader(lggr logger.Logger, jobID string, transmitter common.Address, lp logpoller.LogPoller) error { + return ccipdata.CloseUSDCReader(lggr, jobID, transmitter, lp) +} + +type USDCReaderImpl = ccipdata.USDCReaderImpl + +var DefaultRpcBatchSizeLimit = rpclib.DefaultRpcBatchSizeLimit +var DefaultRpcBatchBackOffMultiplier = rpclib.DefaultRpcBatchBackOffMultiplier +var DefaultMaxParallelRpcCalls = rpclib.DefaultMaxParallelRpcCalls + +func NewEVMTokenPoolBatchedReader(lggr logger.Logger, remoteChainSelector uint64, offRampAddress ccip.Address, evmBatchCaller rpclib.EvmBatchCaller) (*batchreader.EVMTokenPoolBatchedReader, error) { + return batchreader.NewEVMTokenPoolBatchedReader(lggr, remoteChainSelector, offRampAddress, evmBatchCaller) +} + +type ChainAgnosticPriceRegistry struct { + p ChainAgnosticPriceRegistryFactory +} + +// [ChainAgnosticPriceRegistryFactory] is satisfied by [commontypes.CCIPCommitProvider] and [commontypes.CCIPExecProvider] +type ChainAgnosticPriceRegistryFactory interface { + NewPriceRegistryReader(ctx context.Context, addr ccip.Address) (ccip.PriceRegistryReader, error) +} + +func (c *ChainAgnosticPriceRegistry) NewPriceRegistryReader(ctx context.Context, addr ccip.Address) (ccip.PriceRegistryReader, error) { + return c.p.NewPriceRegistryReader(ctx, addr) +} + +func NewChainAgnosticPriceRegistry(provider ChainAgnosticPriceRegistryFactory) *ChainAgnosticPriceRegistry { + return &ChainAgnosticPriceRegistry{provider} +} + +type JSONCommitOffchainConfigV1_2_0 = v1_2_0.JSONCommitOffchainConfig +type CommitOnchainConfig = ccipdata.CommitOnchainConfig + +func NewCommitOffchainConfig( + gasPriceDeviationPPB uint32, + gasPriceHeartBeat time.Duration, + tokenPriceDeviationPPB uint32, + tokenPriceHeartBeat time.Duration, + inflightCacheExpiry time.Duration, + priceReportingDisabled bool, +) ccip.CommitOffchainConfig { + return ccipdata.NewCommitOffchainConfig(gasPriceDeviationPPB, gasPriceHeartBeat, tokenPriceDeviationPPB, tokenPriceHeartBeat, inflightCacheExpiry, priceReportingDisabled) +} diff --git a/core/services/ocr2/plugins/ccip/integration_legacy_test.go b/core/services/ocr2/plugins/ccip/integration_legacy_test.go new file mode 100644 index 0000000000..9bc94b5fe4 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/integration_legacy_test.go @@ -0,0 +1,599 @@ +package ccip_test + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + gethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + evm_2_evm_onramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + testhelpers_new "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" + testhelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0" +) + +func TestIntegration_legacy_CCIP(t *testing.T) { + // Run the batches of tests for both pipeline and dynamic price getter setups. + // We will remove the pipeline batch once the feature is deleted from the code. + tests := []struct { + name string + withPipeline bool + }{ + { + name: "with pipeline", + withPipeline: true, + }, + { + name: "with dynamic price getter", + withPipeline: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + ccipTH := testhelpers.SetupCCIPIntegrationTH(t, testhelpers.SourceChainID, testhelpers.SourceChainSelector, testhelpers.DestChainID, testhelpers.DestChainSelector) + + tokenPricesUSDPipeline := "" + priceGetterConfigJson := "" + + if test.withPipeline { + // Set up a test pipeline. + testPricePipeline, linkUSD, ethUSD := ccipTH.CreatePricesPipeline(t) + defer linkUSD.Close() + defer ethUSD.Close() + tokenPricesUSDPipeline = testPricePipeline + } else { + // Set up a test price getter. + // Set up the aggregators here to avoid modifying ccipTH. + aggSrcNatAddr, _, aggSrcNat, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Source.User, ccipTH.Source.Chain, 18, big.NewInt(2e18)) + require.NoError(t, err) + _, err = aggSrcNat.UpdateRoundData(ccipTH.Source.User, big.NewInt(50), big.NewInt(17000000), big.NewInt(1000), big.NewInt(1000)) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + aggSrcLnkAddr, _, aggSrcLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Source.User, ccipTH.Source.Chain, 18, big.NewInt(3e18)) + require.NoError(t, err) + ccipTH.Dest.Chain.Commit() + _, err = aggSrcLnk.UpdateRoundData(ccipTH.Source.User, big.NewInt(50), big.NewInt(8000000), big.NewInt(1000), big.NewInt(1000)) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + aggDstLnkAddr, _, aggDstLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Dest.User, ccipTH.Dest.Chain, 18, big.NewInt(3e18)) + require.NoError(t, err) + ccipTH.Dest.Chain.Commit() + _, err = aggDstLnk.UpdateRoundData(ccipTH.Dest.User, big.NewInt(50), big.NewInt(8000000), big.NewInt(1000), big.NewInt(1000)) + require.NoError(t, err) + ccipTH.Dest.Chain.Commit() + + priceGetterConfig := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ + ccipTH.Source.LinkToken.Address(): { + ChainID: ccipTH.Source.ChainID, + AggregatorContractAddress: aggSrcLnkAddr, + }, + ccipTH.Source.WrappedNative.Address(): { + ChainID: ccipTH.Source.ChainID, + AggregatorContractAddress: aggSrcNatAddr, + }, + ccipTH.Dest.LinkToken.Address(): { + ChainID: ccipTH.Dest.ChainID, + AggregatorContractAddress: aggDstLnkAddr, + }, + ccipTH.Dest.WrappedNative.Address(): { + ChainID: ccipTH.Dest.ChainID, + AggregatorContractAddress: aggDstLnkAddr, + }, + }, + StaticPrices: map[common.Address]config.StaticPriceConfig{}, + } + priceGetterConfigBytes, err := json.MarshalIndent(priceGetterConfig, "", " ") + require.NoError(t, err) + priceGetterConfigJson = string(priceGetterConfigBytes) + } + + jobParams := ccipTH.SetUpNodesAndJobs(t, tokenPricesUSDPipeline, priceGetterConfigJson, "") + + currentSeqNum := 1 + + t.Run("single", func(t *testing.T) { + tokenAmount := big.NewInt(500000003) // prime number + gasLimit := big.NewInt(200_003) // prime number + + extraArgs, err2 := testhelpers.GetEVMExtraArgsV1(gasLimit, false) + require.NoError(t, err2) + + sourceBalances, err2 := testhelpers.GetBalances(t, []testhelpers.BalanceReq{ + {Name: testhelpers.SourcePool, Addr: ccipTH.Source.LinkTokenPool.Address(), Getter: ccipTH.GetSourceLinkBalance}, + {Name: testhelpers.OnRamp, Addr: ccipTH.Source.OnRamp.Address(), Getter: ccipTH.GetSourceLinkBalance}, + {Name: testhelpers.SourceRouter, Addr: ccipTH.Source.Router.Address(), Getter: ccipTH.GetSourceLinkBalance}, + {Name: testhelpers.SourcePriceRegistry, Addr: ccipTH.Source.PriceRegistry.Address(), Getter: ccipTH.GetSourceLinkBalance}, + }) + require.NoError(t, err2) + destBalances, err2 := testhelpers.GetBalances(t, []testhelpers.BalanceReq{ + {Name: testhelpers.Receiver, Addr: ccipTH.Dest.Receivers[0].Receiver.Address(), Getter: ccipTH.GetDestLinkBalance}, + {Name: testhelpers.DestPool, Addr: ccipTH.Dest.LinkTokenPool.Address(), Getter: ccipTH.GetDestLinkBalance}, + {Name: testhelpers.OffRamp, Addr: ccipTH.Dest.OffRamp.Address(), Getter: ccipTH.GetDestLinkBalance}, + }) + require.NoError(t, err2) + + ccipTH.Source.User.Value = tokenAmount + _, err2 = ccipTH.Source.WrappedNative.Deposit(ccipTH.Source.User) + require.NoError(t, err2) + ccipTH.Source.Chain.Commit() + ccipTH.Source.User.Value = nil + + msg := router.ClientEVM2AnyMessage{ + Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[0].Receiver.Address()), + Data: []byte("hello"), + TokenAmounts: []router.ClientEVMTokenAmount{ + { + Token: ccipTH.Source.LinkToken.Address(), + Amount: tokenAmount, + }, + { + Token: ccipTH.Source.WrappedNative.Address(), + Amount: tokenAmount, + }, + }, + FeeToken: ccipTH.Source.LinkToken.Address(), + ExtraArgs: extraArgs, + } + fee, err2 := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) + require.NoError(t, err2) + // Currently no overhead and 10gwei dest gas price. So fee is simply (gasLimit * gasPrice)* link/native + // require.Equal(t, new(big.Int).Mul(gasLimit, gasPrice).String(), fee.String()) + // Approve the fee amount + the token amount + _, err2 = ccipTH.Source.LinkToken.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), new(big.Int).Add(fee, tokenAmount)) + require.NoError(t, err2) + ccipTH.Source.Chain.Commit() + _, err2 = ccipTH.Source.WrappedNative.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), tokenAmount) + require.NoError(t, err2) + ccipTH.Source.Chain.Commit() + + ccipTH.SendRequest(t, msg) + // Should eventually see this executed. + ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum) + ccipTH.EventuallyReportCommitted(t, currentSeqNum) + + executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum) + assert.Len(t, executionLogs, 1) + ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) + + // Asserts + // 1) The total pool input == total pool output + // 2) Pool flow equals tokens sent + // 3) Sent tokens arrive at the receiver + ccipTH.AssertBalances(t, []testhelpers.BalanceAssertion{ + { + Name: testhelpers.SourcePool, + Address: ccipTH.Source.LinkTokenPool.Address(), + Expected: testhelpers.MustAddBigInt(sourceBalances[testhelpers.SourcePool], tokenAmount.String()).String(), + Getter: ccipTH.GetSourceLinkBalance, + }, + { + Name: testhelpers.SourcePriceRegistry, + Address: ccipTH.Source.PriceRegistry.Address(), + Expected: sourceBalances[testhelpers.SourcePriceRegistry].String(), + Getter: ccipTH.GetSourceLinkBalance, + }, + { + // Fees end up in the onramp. + Name: testhelpers.OnRamp, + Address: ccipTH.Source.OnRamp.Address(), + Expected: testhelpers.MustAddBigInt(sourceBalances[testhelpers.SourcePriceRegistry], fee.String()).String(), + Getter: ccipTH.GetSourceLinkBalance, + }, + { + Name: testhelpers.SourceRouter, + Address: ccipTH.Source.Router.Address(), + Expected: sourceBalances[testhelpers.SourceRouter].String(), + Getter: ccipTH.GetSourceLinkBalance, + }, + { + Name: testhelpers.Receiver, + Address: ccipTH.Dest.Receivers[0].Receiver.Address(), + Expected: testhelpers.MustAddBigInt(destBalances[testhelpers.Receiver], tokenAmount.String()).String(), + Getter: ccipTH.GetDestLinkBalance, + }, + { + Name: testhelpers.DestPool, + Address: ccipTH.Dest.LinkTokenPool.Address(), + Expected: testhelpers.MustSubBigInt(destBalances[testhelpers.DestPool], tokenAmount.String()).String(), + Getter: ccipTH.GetDestLinkBalance, + }, + { + Name: testhelpers.OffRamp, + Address: ccipTH.Dest.OffRamp.Address(), + Expected: destBalances[testhelpers.OffRamp].String(), + Getter: ccipTH.GetDestLinkBalance, + }, + }) + currentSeqNum++ + }) + + t.Run("multiple batches", func(t *testing.T) { + tokenAmount := big.NewInt(500000003) + gasLimit := big.NewInt(250_000) + + var txs []*gethtypes.Transaction + // Enough to require batched executions as gasLimit per tx is 250k -> 500k -> 750k .... + // The actual gas usage of executing 15 messages is higher than the gas limit for + // a single tx. This means that when batching is turned off, and we simply include + // all txs without checking gas, this also fails. + n := 15 + for i := 0; i < n; i++ { + txGasLimit := new(big.Int).Mul(gasLimit, big.NewInt(int64(i+1))) + extraArgs, err2 := testhelpers.GetEVMExtraArgsV1(txGasLimit, false) + require.NoError(t, err2) + msg := router.ClientEVM2AnyMessage{ + Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[0].Receiver.Address()), + Data: []byte("hello"), + TokenAmounts: []router.ClientEVMTokenAmount{ + { + Token: ccipTH.Source.LinkToken.Address(), + Amount: tokenAmount, + }, + }, + FeeToken: ccipTH.Source.LinkToken.Address(), + ExtraArgs: extraArgs, + } + fee, err2 := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) + require.NoError(t, err2) + // Currently no overhead and 1gwei dest gas price. So fee is simply gasLimit * gasPrice. + // require.Equal(t, new(big.Int).Mul(txGasLimit, gasPrice).String(), fee.String()) + // Approve the fee amount + the token amount + _, err2 = ccipTH.Source.LinkToken.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), new(big.Int).Add(fee, tokenAmount)) + require.NoError(t, err2) + tx, err2 := ccipTH.Source.Router.CcipSend(ccipTH.Source.User, ccipTH.Dest.ChainSelector, msg) + require.NoError(t, err2) + txs = append(txs, tx) + } + + // Send a batch of requests in a single block + testhelpers_new.ConfirmTxs(t, txs, ccipTH.Source.Chain) + for i := 0; i < n; i++ { + ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum+i) + } + // Should see a report with the full range + ccipTH.EventuallyReportCommitted(t, currentSeqNum+n-1) + // Should all be executed + executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum+n-1) + for _, execLog := range executionLogs { + ccipTH.AssertExecState(t, execLog, testhelpers.ExecutionStateSuccess) + } + + currentSeqNum += n + }) + + // Deploy new on ramp,Commit store,off ramp + // Delete v1 jobs + // Send a number of requests + // Upgrade the router with new contracts + // create new jobs + // Verify all pending requests are sent after the contracts are upgraded + t.Run("upgrade contracts and verify requests can be sent with upgraded contract", func(t *testing.T) { + gasLimit := big.NewInt(200_003) // prime number + tokenAmount := big.NewInt(100) + commitStoreV1 := ccipTH.Dest.CommitStore + offRampV1 := ccipTH.Dest.OffRamp + onRampV1 := ccipTH.Source.OnRamp + // deploy v2 contracts + ccipTH.DeployNewOnRamp(t) + ccipTH.DeployNewCommitStore(t) + ccipTH.DeployNewOffRamp(t) + + // send a request as the v2 contracts are not enabled in router it should route through the v1 contracts + t.Logf("sending request for seqnum %d", currentSeqNum) + ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) + ccipTH.Source.Chain.Commit() + ccipTH.Dest.Chain.Commit() + t.Logf("verifying seqnum %d on previous onRamp %s", currentSeqNum, onRampV1.Address().Hex()) + ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum, onRampV1.Address()) + ccipTH.EventuallyReportCommitted(t, currentSeqNum, commitStoreV1.Address()) + executionLog := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum, offRampV1.Address()) + ccipTH.AssertExecState(t, executionLog[0], testhelpers.ExecutionStateSuccess, offRampV1.Address()) + + nonceAtOnRampV1, err := onRampV1.GetSenderNonce(nil, ccipTH.Source.User.From) + require.NoError(t, err, "getting nonce from onRamp") + require.Equal(t, currentSeqNum, int(nonceAtOnRampV1)) + nonceAtOffRampV1, err := offRampV1.GetSenderNonce(nil, ccipTH.Source.User.From) + require.NoError(t, err, "getting nonce from offRamp") + require.Equal(t, currentSeqNum, int(nonceAtOffRampV1)) + + // enable the newly deployed contracts + newConfigBlock := ccipTH.Dest.Chain.Blockchain().CurrentBlock().Number.Int64() + ccipTH.EnableOnRamp(t) + ccipTH.EnableCommitStore(t) + ccipTH.EnableOffRamp(t) + srcStartBlock := ccipTH.Source.Chain.Blockchain().CurrentBlock().Number.Uint64() + + // send a number of requests, the requests should not be delivered yet as the previous contracts are not configured + // with the router anymore + startSeq := 1 + noOfRequests := 5 + endSeqNum := startSeq + noOfRequests + for i := startSeq; i <= endSeqNum; i++ { + t.Logf("sending request for seqnum %d", i) + ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) + ccipTH.Source.Chain.Commit() + ccipTH.Dest.Chain.Commit() + ccipTH.EventuallySendRequested(t, uint64(i)) + } + + // delete v1 jobs + for _, node := range ccipTH.Nodes { + id := node.FindJobIDForContract(t, commitStoreV1.Address()) + require.Greater(t, id, int32(0)) + t.Logf("deleting job %d", id) + err = node.App.DeleteJob(context.Background(), id) + require.NoError(t, err) + id = node.FindJobIDForContract(t, offRampV1.Address()) + require.Greater(t, id, int32(0)) + t.Logf("deleting job %d", id) + err = node.App.DeleteJob(context.Background(), id) + require.NoError(t, err) + } + + // Commit on both chains to reach Finality + ccipTH.Source.Chain.Commit() + ccipTH.Dest.Chain.Commit() + + // create new jobs + jobParams = ccipTH.NewCCIPJobSpecParams(tokenPricesUSDPipeline, priceGetterConfigJson, newConfigBlock, "") + jobParams.Version = "v2" + jobParams.SourceStartBlock = srcStartBlock + ccipTH.AddAllJobs(t, jobParams) + committedSeqNum := uint64(0) + // Now the requests should be delivered + for i := startSeq; i <= endSeqNum; i++ { + t.Logf("verifying seqnum %d", i) + ccipTH.AllNodesHaveReqSeqNum(t, i) + if committedSeqNum < uint64(i+1) { + committedSeqNum = ccipTH.EventuallyReportCommitted(t, i) + } + ccipTH.EventuallyExecutionStateChangedToSuccess(t, []uint64{uint64(i)}, uint64(newConfigBlock)) + } + + // nonces should be correctly synced from v1 contracts for the sender + nonceAtOnRampV2, err := ccipTH.Source.OnRamp.GetSenderNonce(nil, ccipTH.Source.User.From) + require.NoError(t, err, "getting nonce from onRamp") + nonceAtOffRampV2, err := ccipTH.Dest.OffRamp.GetSenderNonce(nil, ccipTH.Source.User.From) + require.NoError(t, err, "getting nonce from offRamp") + require.Equal(t, nonceAtOnRampV1+uint64(noOfRequests)+1, nonceAtOnRampV2, "nonce should be synced from v1 onRamps") + require.Equal(t, nonceAtOffRampV1+uint64(noOfRequests)+1, nonceAtOffRampV2, "nonce should be synced from v1 offRamps") + currentSeqNum = endSeqNum + 1 + }) + + t.Run("pay nops", func(t *testing.T) { + linkToTransferToOnRamp := big.NewInt(1e18) + + // transfer some link to onramp to pay the nops + _, err := ccipTH.Source.LinkToken.Transfer(ccipTH.Source.User, ccipTH.Source.OnRamp.Address(), linkToTransferToOnRamp) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + srcBalReq := []testhelpers.BalanceReq{ + { + Name: testhelpers.Sender, + Addr: ccipTH.Source.User.From, + Getter: ccipTH.GetSourceWrappedTokenBalance, + }, + { + Name: testhelpers.OnRampNative, + Addr: ccipTH.Source.OnRamp.Address(), + Getter: ccipTH.GetSourceWrappedTokenBalance, + }, + { + Name: testhelpers.OnRamp, + Addr: ccipTH.Source.OnRamp.Address(), + Getter: ccipTH.GetSourceLinkBalance, + }, + { + Name: testhelpers.SourceRouter, + Addr: ccipTH.Source.Router.Address(), + Getter: ccipTH.GetSourceWrappedTokenBalance, + }, + } + + var nopsAndWeights []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight + var totalWeight uint16 + nodes := ccipTH.Nodes + for i := range nodes { + // For now set the transmitter addresses to be the same as the payee addresses + nodes[i].PaymentReceiver = nodes[i].Transmitter + nopsAndWeights = append(nopsAndWeights, evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{ + Nop: nodes[i].PaymentReceiver, + Weight: 5, + }) + totalWeight += 5 + srcBalReq = append(srcBalReq, testhelpers.BalanceReq{ + Name: fmt.Sprintf("node %d", i), + Addr: nodes[i].PaymentReceiver, + Getter: ccipTH.GetSourceLinkBalance, + }) + } + srcBalances, err := testhelpers.GetBalances(t, srcBalReq) + require.NoError(t, err) + + // set nops on the onramp + ccipTH.SetNopsOnRamp(t, nopsAndWeights) + + // send a message + extraArgs, err := testhelpers.GetEVMExtraArgsV1(big.NewInt(200_000), true) + require.NoError(t, err) + + // FeeToken is empty, indicating it should use native token + msg := router.ClientEVM2AnyMessage{ + Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[1].Receiver.Address()), + Data: []byte("hello"), + TokenAmounts: []router.ClientEVMTokenAmount{}, + ExtraArgs: extraArgs, + FeeToken: common.Address{}, + } + fee, err := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) + require.NoError(t, err) + + // verify message is sent + ccipTH.Source.User.Value = fee + ccipTH.SendRequest(t, msg) + ccipTH.Source.User.Value = nil + ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum) + ccipTH.EventuallyReportCommitted(t, currentSeqNum) + + executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum) + assert.Len(t, executionLogs, 1) + ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) + currentSeqNum++ + + // get the nop fee + nopFee, err := ccipTH.Source.OnRamp.GetNopFeesJuels(nil) + require.NoError(t, err) + t.Log("nopFee", nopFee) + + // withdraw fees and verify there is still fund left for nop payment + _, err = ccipTH.Source.OnRamp.WithdrawNonLinkFees( + ccipTH.Source.User, + ccipTH.Source.WrappedNative.Address(), + ccipTH.Source.User.From, + ) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + // pay nops + _, err = ccipTH.Source.OnRamp.PayNops(ccipTH.Source.User) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + srcBalanceAssertions := []testhelpers.BalanceAssertion{ + { + // Onramp should not have any balance left in wrapped native + Name: testhelpers.OnRampNative, + Address: ccipTH.Source.OnRamp.Address(), + Expected: big.NewInt(0).String(), + Getter: ccipTH.GetSourceWrappedTokenBalance, + }, + { + // Onramp should have the remaining link after paying nops + Name: testhelpers.OnRamp, + Address: ccipTH.Source.OnRamp.Address(), + Expected: new(big.Int).Sub(srcBalances[testhelpers.OnRamp], nopFee).String(), + Getter: ccipTH.GetSourceLinkBalance, + }, + { + Name: testhelpers.SourceRouter, + Address: ccipTH.Source.Router.Address(), + Expected: srcBalances[testhelpers.SourceRouter].String(), + Getter: ccipTH.GetSourceWrappedTokenBalance, + }, + // onRamp's balance (of previously sent fee during message sending) should have been transferred to + // the owner as a result of WithdrawNonLinkFees + { + Name: testhelpers.Sender, + Address: ccipTH.Source.User.From, + Expected: fee.String(), + Getter: ccipTH.GetSourceWrappedTokenBalance, + }, + } + + // the nodes should be paid according to the weights assigned + for i, node := range nodes { + paymentWeight := float64(nopsAndWeights[i].Weight) / float64(totalWeight) + paidInFloat := paymentWeight * float64(nopFee.Int64()) + paid, _ := new(big.Float).SetFloat64(paidInFloat).Int64() + bal := new(big.Int).Add( + new(big.Int).SetInt64(paid), + srcBalances[fmt.Sprintf("node %d", i)]).String() + srcBalanceAssertions = append(srcBalanceAssertions, testhelpers.BalanceAssertion{ + Name: fmt.Sprintf("node %d", i), + Address: node.PaymentReceiver, + Expected: bal, + Getter: ccipTH.GetSourceLinkBalance, + }) + } + ccipTH.AssertBalances(t, srcBalanceAssertions) + }) + + // Keep on sending a bunch of messages + // In the meantime update onchainConfig with new price registry address + // Verify if the jobs can pick up updated config + // Verify if all the messages are sent + t.Run("config change or price registry update while requests are inflight", func(t *testing.T) { + gasLimit := big.NewInt(200_003) // prime number + tokenAmount := big.NewInt(100) + msgWg := &sync.WaitGroup{} + msgWg.Add(1) + ticker := time.NewTicker(100 * time.Millisecond) + defer ticker.Stop() + startSeq := currentSeqNum + endSeq := currentSeqNum + 20 + + // send message with the old configs + ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) + ccipTH.Source.Chain.Commit() + + go func(ccipContracts testhelpers.CCIPContracts, currentSeqNum int) { + seqNumber := currentSeqNum + 1 + defer msgWg.Done() + for { + <-ticker.C // wait for ticker + t.Logf("sending request for seqnum %d", seqNumber) + ccipContracts.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) + ccipContracts.Source.Chain.Commit() + seqNumber++ + if seqNumber == endSeq { + return + } + } + }(ccipTH.CCIPContracts, currentSeqNum) + + ccipTH.DeployNewPriceRegistry(t) + commitOnchainConfig := ccipTH.CreateDefaultCommitOnchainConfig(t) + commitOffchainConfig := ccipTH.CreateDefaultCommitOffchainConfig(t) + execOnchainConfig := ccipTH.CreateDefaultExecOnchainConfig(t) + execOffchainConfig := ccipTH.CreateDefaultExecOffchainConfig(t) + + ccipTH.SetupOnchainConfig(t, commitOnchainConfig, commitOffchainConfig, execOnchainConfig, execOffchainConfig) + + // wait for all requests to be complete + msgWg.Wait() + for i := startSeq; i < endSeq; i++ { + ccipTH.AllNodesHaveReqSeqNum(t, i) + ccipTH.EventuallyReportCommitted(t, i) + + executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, i, i) + assert.Len(t, executionLogs, 1) + ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) + } + + for i, node := range ccipTH.Nodes { + t.Logf("verifying node %d", i) + node.EventuallyNodeUsesNewCommitConfig(t, ccipTH, ccipdata.CommitOnchainConfig{ + PriceRegistry: ccipTH.Dest.PriceRegistry.Address(), + }) + node.EventuallyNodeUsesNewExecConfig(t, ccipTH, v1_2_0.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: testhelpers.PermissionLessExecutionThresholdSeconds, + Router: ccipTH.Dest.Router.Address(), + PriceRegistry: ccipTH.Dest.PriceRegistry.Address(), + MaxDataBytes: 1e5, + MaxNumberOfTokensPerMsg: 5, + MaxPoolReleaseOrMintGas: 200_000, + }) + node.EventuallyNodeUsesUpdatedPriceRegistry(t, ccipTH) + } + currentSeqNum = endSeq + }) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/integration_test.go b/core/services/ocr2/plugins/ccip/integration_test.go new file mode 100644 index 0000000000..202d2ef230 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/integration_test.go @@ -0,0 +1,644 @@ +package ccip_test + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + gethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" + integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/integration" +) + +func TestIntegration_CCIP(t *testing.T) { + // Run the batches of tests for both pipeline and dynamic price getter setups. + // We will remove the pipeline batch once the feature is deleted from the code. + tests := []struct { + name string + withPipeline bool + allowOutOfOrderExecution bool + }{ + { + name: "with pipeline allowOutOfOrderExecution true", + withPipeline: true, + allowOutOfOrderExecution: true, + }, + { + name: "with dynamic price getter allowOutOfOrderExecution false", + withPipeline: false, + allowOutOfOrderExecution: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + ccipTH := integrationtesthelpers.SetupCCIPIntegrationTH(t, testhelpers.SourceChainID, testhelpers.SourceChainSelector, testhelpers.DestChainID, testhelpers.DestChainSelector) + + tokenPricesUSDPipeline := "" + priceGetterConfigJson := "" + + if test.withPipeline { + // Set up a test pipeline. + testPricePipeline, linkUSD, ethUSD := ccipTH.CreatePricesPipeline(t) + defer linkUSD.Close() + defer ethUSD.Close() + tokenPricesUSDPipeline = testPricePipeline + } else { + // Set up a test price getter. + // Set up the aggregators here to avoid modifying ccipTH. + aggSrcNatAddr, _, aggSrcNat, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Source.User, ccipTH.Source.Chain, 18, big.NewInt(2e18)) + require.NoError(t, err) + _, err = aggSrcNat.UpdateRoundData(ccipTH.Source.User, big.NewInt(50), big.NewInt(17000000), big.NewInt(1000), big.NewInt(1000)) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + aggSrcLnkAddr, _, aggSrcLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Source.User, ccipTH.Source.Chain, 18, big.NewInt(3e18)) + require.NoError(t, err) + ccipTH.Dest.Chain.Commit() + _, err = aggSrcLnk.UpdateRoundData(ccipTH.Source.User, big.NewInt(50), big.NewInt(8000000), big.NewInt(1000), big.NewInt(1000)) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + aggDstLnkAddr, _, aggDstLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Dest.User, ccipTH.Dest.Chain, 18, big.NewInt(3e18)) + require.NoError(t, err) + ccipTH.Dest.Chain.Commit() + _, err = aggDstLnk.UpdateRoundData(ccipTH.Dest.User, big.NewInt(50), big.NewInt(8000000), big.NewInt(1000), big.NewInt(1000)) + require.NoError(t, err) + ccipTH.Dest.Chain.Commit() + + priceGetterConfig := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ + ccipTH.Source.LinkToken.Address(): { + ChainID: ccipTH.Source.ChainID, + AggregatorContractAddress: aggSrcLnkAddr, + }, + ccipTH.Source.WrappedNative.Address(): { + ChainID: ccipTH.Source.ChainID, + AggregatorContractAddress: aggSrcNatAddr, + }, + ccipTH.Dest.LinkToken.Address(): { + ChainID: ccipTH.Dest.ChainID, + AggregatorContractAddress: aggDstLnkAddr, + }, + ccipTH.Dest.WrappedNative.Address(): { + ChainID: ccipTH.Dest.ChainID, + AggregatorContractAddress: aggDstLnkAddr, + }, + }, + StaticPrices: map[common.Address]config.StaticPriceConfig{}, + } + priceGetterConfigBytes, err := json.MarshalIndent(priceGetterConfig, "", " ") + require.NoError(t, err) + priceGetterConfigJson = string(priceGetterConfigBytes) + } + + jobParams := ccipTH.SetUpNodesAndJobs(t, tokenPricesUSDPipeline, priceGetterConfigJson, "") + + // track sequence number and nonce separately since nonce doesn't bump for messages with allowOutOfOrderExecution == true, + // but sequence number always bumps. + // for this test, when test.outOfOrder == false, sequence number and nonce are equal. + // when test.outOfOrder == true, nonce is not bumped at all, so sequence number and nonce are NOT equal. + currentSeqNum := 1 + currentNonce := uint64(1) + + t.Run("single", func(t *testing.T) { + tokenAmount := big.NewInt(500000003) // prime number + gasLimit := big.NewInt(200_003) // prime number + + extraArgs, err2 := testhelpers.GetEVMExtraArgsV2(gasLimit, test.allowOutOfOrderExecution) + require.NoError(t, err2) + + sourceBalances, err2 := testhelpers.GetBalances(t, []testhelpers.BalanceReq{ + {Name: testhelpers.SourcePool, Addr: ccipTH.Source.LinkTokenPool.Address(), Getter: ccipTH.GetSourceLinkBalance}, + {Name: testhelpers.OnRamp, Addr: ccipTH.Source.OnRamp.Address(), Getter: ccipTH.GetSourceLinkBalance}, + {Name: testhelpers.SourceRouter, Addr: ccipTH.Source.Router.Address(), Getter: ccipTH.GetSourceLinkBalance}, + {Name: testhelpers.SourcePriceRegistry, Addr: ccipTH.Source.PriceRegistry.Address(), Getter: ccipTH.GetSourceLinkBalance}, + }) + require.NoError(t, err2) + destBalances, err2 := testhelpers.GetBalances(t, []testhelpers.BalanceReq{ + {Name: testhelpers.Receiver, Addr: ccipTH.Dest.Receivers[0].Receiver.Address(), Getter: ccipTH.GetDestLinkBalance}, + {Name: testhelpers.DestPool, Addr: ccipTH.Dest.LinkTokenPool.Address(), Getter: ccipTH.GetDestLinkBalance}, + {Name: testhelpers.OffRamp, Addr: ccipTH.Dest.OffRamp.Address(), Getter: ccipTH.GetDestLinkBalance}, + }) + require.NoError(t, err2) + + ccipTH.Source.User.Value = tokenAmount + _, err2 = ccipTH.Source.WrappedNative.Deposit(ccipTH.Source.User) + require.NoError(t, err2) + ccipTH.Source.Chain.Commit() + ccipTH.Source.User.Value = nil + + msg := router.ClientEVM2AnyMessage{ + Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[0].Receiver.Address()), + Data: []byte("hello"), + TokenAmounts: []router.ClientEVMTokenAmount{ + { + Token: ccipTH.Source.LinkToken.Address(), + Amount: tokenAmount, + }, + { + Token: ccipTH.Source.WrappedNative.Address(), + Amount: tokenAmount, + }, + }, + FeeToken: ccipTH.Source.LinkToken.Address(), + ExtraArgs: extraArgs, + } + fee, err2 := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) + require.NoError(t, err2) + // Currently no overhead and 10gwei dest gas price. So fee is simply (gasLimit * gasPrice)* link/native + // require.Equal(t, new(big.Int).Mul(gasLimit, gasPrice).String(), fee.String()) + // Approve the fee amount + the token amount + _, err2 = ccipTH.Source.LinkToken.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), new(big.Int).Add(fee, tokenAmount)) + require.NoError(t, err2) + ccipTH.Source.Chain.Commit() + _, err2 = ccipTH.Source.WrappedNative.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), tokenAmount) + require.NoError(t, err2) + ccipTH.Source.Chain.Commit() + + beforeNonce, err := ccipTH.Source.OnRamp.GetSenderNonce(nil, ccipTH.Source.User.From) + require.NoError(t, err) + ccipTH.SendRequest(t, msg) + // TODO: can this be moved into SendRequest? + if test.allowOutOfOrderExecution { + // the nonce for that sender must not be bumped for allowOutOfOrderExecution == true messages. + nonce, err2 := ccipTH.Source.OnRamp.GetSenderNonce(nil, ccipTH.Source.User.From) + require.NoError(t, err2) + require.Equal(t, beforeNonce, nonce, "nonce must not be bumped for allowOutOfOrderExecution == true requests") + } else { + // the nonce for that sender must be bumped for allowOutOfOrderExecution == false messages. + nonce, err2 := ccipTH.Source.OnRamp.GetSenderNonce(nil, ccipTH.Source.User.From) + require.NoError(t, err2) + require.Equal(t, beforeNonce+1, nonce, "nonce must be bumped for allowOutOfOrderExecution == false requests") + } + + // Should eventually see this executed. + ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum) + ccipTH.EventuallyReportCommitted(t, currentSeqNum) + + executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum) + assert.Len(t, executionLogs, 1) + ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) + + // Asserts + // 1) The total pool input == total pool output + // 2) Pool flow equals tokens sent + // 3) Sent tokens arrive at the receiver + ccipTH.AssertBalances(t, []testhelpers.BalanceAssertion{ + { + Name: testhelpers.SourcePool, + Address: ccipTH.Source.LinkTokenPool.Address(), + Expected: testhelpers.MustAddBigInt(sourceBalances[testhelpers.SourcePool], tokenAmount.String()).String(), + Getter: ccipTH.GetSourceLinkBalance, + }, + { + Name: testhelpers.SourcePriceRegistry, + Address: ccipTH.Source.PriceRegistry.Address(), + Expected: sourceBalances[testhelpers.SourcePriceRegistry].String(), + Getter: ccipTH.GetSourceLinkBalance, + }, + { + // Fees end up in the onramp. + Name: testhelpers.OnRamp, + Address: ccipTH.Source.OnRamp.Address(), + Expected: testhelpers.MustAddBigInt(sourceBalances[testhelpers.SourcePriceRegistry], fee.String()).String(), + Getter: ccipTH.GetSourceLinkBalance, + }, + { + Name: testhelpers.SourceRouter, + Address: ccipTH.Source.Router.Address(), + Expected: sourceBalances[testhelpers.SourceRouter].String(), + Getter: ccipTH.GetSourceLinkBalance, + }, + { + Name: testhelpers.Receiver, + Address: ccipTH.Dest.Receivers[0].Receiver.Address(), + Expected: testhelpers.MustAddBigInt(destBalances[testhelpers.Receiver], tokenAmount.String()).String(), + Getter: ccipTH.GetDestLinkBalance, + }, + { + Name: testhelpers.DestPool, + Address: ccipTH.Dest.LinkTokenPool.Address(), + Expected: testhelpers.MustSubBigInt(destBalances[testhelpers.DestPool], tokenAmount.String()).String(), + Getter: ccipTH.GetDestLinkBalance, + }, + { + Name: testhelpers.OffRamp, + Address: ccipTH.Dest.OffRamp.Address(), + Expected: destBalances[testhelpers.OffRamp].String(), + Getter: ccipTH.GetDestLinkBalance, + }, + }) + currentSeqNum++ + if !test.allowOutOfOrderExecution { + currentNonce = uint64(currentSeqNum) + } + }) + + t.Run("multiple batches", func(t *testing.T) { + tokenAmount := big.NewInt(500000003) + gasLimit := big.NewInt(250_000) + + var txs []*gethtypes.Transaction + // Enough to require batched executions as gasLimit per tx is 250k -> 500k -> 750k .... + // The actual gas usage of executing 15 messages is higher than the gas limit for + // a single tx. This means that when batching is turned off, and we simply include + // all txs without checking gas, this also fails. + n := 15 + for i := 0; i < n; i++ { + txGasLimit := new(big.Int).Mul(gasLimit, big.NewInt(int64(i+1))) + + // interleave ordered and non-ordered messages. + allowOutOfOrderExecution := false + if i%2 == 0 { + allowOutOfOrderExecution = true + } + extraArgs, err2 := testhelpers.GetEVMExtraArgsV2(txGasLimit, allowOutOfOrderExecution) + require.NoError(t, err2) + msg := router.ClientEVM2AnyMessage{ + Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[0].Receiver.Address()), + Data: []byte("hello"), + TokenAmounts: []router.ClientEVMTokenAmount{ + { + Token: ccipTH.Source.LinkToken.Address(), + Amount: tokenAmount, + }, + }, + FeeToken: ccipTH.Source.LinkToken.Address(), + ExtraArgs: extraArgs, + } + fee, err2 := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) + require.NoError(t, err2) + // Currently no overhead and 1gwei dest gas price. So fee is simply gasLimit * gasPrice. + // require.Equal(t, new(big.Int).Mul(txGasLimit, gasPrice).String(), fee.String()) + // Approve the fee amount + the token amount + _, err2 = ccipTH.Source.LinkToken.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), new(big.Int).Add(fee, tokenAmount)) + require.NoError(t, err2) + tx, err2 := ccipTH.Source.Router.CcipSend(ccipTH.Source.User, ccipTH.Dest.ChainSelector, msg) + require.NoError(t, err2) + txs = append(txs, tx) + if !allowOutOfOrderExecution { + currentNonce++ + } + } + + // Send a batch of requests in a single block + testhelpers.ConfirmTxs(t, txs, ccipTH.Source.Chain) + for i := 0; i < n; i++ { + ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum+i) + } + // Should see a report with the full range + ccipTH.EventuallyReportCommitted(t, currentSeqNum+n-1) + // Should all be executed + executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum+n-1) + for _, execLog := range executionLogs { + ccipTH.AssertExecState(t, execLog, testhelpers.ExecutionStateSuccess) + } + + currentSeqNum += n + }) + + // Deploy new on ramp,Commit store,off ramp + // Delete v1 jobs + // Send a number of requests + // Upgrade the router with new contracts + // create new jobs + // Verify all pending requests are sent after the contracts are upgraded + t.Run("upgrade contracts and verify requests can be sent with upgraded contract", func(t *testing.T) { + gasLimit := big.NewInt(200_003) // prime number + tokenAmount := big.NewInt(100) + commitStoreV1 := ccipTH.Dest.CommitStore + offRampV1 := ccipTH.Dest.OffRamp + onRampV1 := ccipTH.Source.OnRamp + // deploy v2 contracts + ccipTH.DeployNewOnRamp(t) + ccipTH.DeployNewCommitStore(t) + ccipTH.DeployNewOffRamp(t) + + // send a request as the v2 contracts are not enabled in router it should route through the v1 contracts + t.Logf("sending request for seqnum %d", currentSeqNum) + ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) + ccipTH.Source.Chain.Commit() + ccipTH.Dest.Chain.Commit() + t.Logf("verifying seqnum %d on previous onRamp %s", currentSeqNum, onRampV1.Address().Hex()) + ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum, onRampV1.Address()) + ccipTH.EventuallyReportCommitted(t, currentSeqNum, commitStoreV1.Address()) + executionLog := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum, offRampV1.Address()) + ccipTH.AssertExecState(t, executionLog[0], testhelpers.ExecutionStateSuccess, offRampV1.Address()) + + nonceAtOnRampV1, err := onRampV1.GetSenderNonce(nil, ccipTH.Source.User.From) + require.NoError(t, err, "getting nonce from onRamp") + require.Equal(t, currentNonce, nonceAtOnRampV1, "nonce should be synced from v1 onRamp") + nonceAtOffRampV1, err := offRampV1.GetSenderNonce(nil, ccipTH.Source.User.From) + require.NoError(t, err, "getting nonce from offRamp") + require.Equal(t, currentNonce, nonceAtOffRampV1, "nonce should be synced from v1 offRamp") + + // enable the newly deployed contracts + newConfigBlock := ccipTH.Dest.Chain.Blockchain().CurrentBlock().Number.Int64() + ccipTH.EnableOnRamp(t) + ccipTH.EnableCommitStore(t) + ccipTH.EnableOffRamp(t) + srcStartBlock := ccipTH.Source.Chain.Blockchain().CurrentBlock().Number.Uint64() + + // send a number of requests, the requests should not be delivered yet as the previous contracts are not configured + // with the router anymore + startSeq := 1 + noOfRequests := 5 + endSeqNum := startSeq + noOfRequests + for i := startSeq; i <= endSeqNum; i++ { + t.Logf("sending request for seqnum %d", i) + ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) + ccipTH.Source.Chain.Commit() + ccipTH.Dest.Chain.Commit() + ccipTH.EventuallySendRequested(t, uint64(i)) + } + + // delete v1 jobs + for _, node := range ccipTH.Nodes { + id := node.FindJobIDForContract(t, commitStoreV1.Address()) + require.Greater(t, id, int32(0)) + t.Logf("deleting job %d", id) + err = node.App.DeleteJob(context.Background(), id) + require.NoError(t, err) + id = node.FindJobIDForContract(t, offRampV1.Address()) + require.Greater(t, id, int32(0)) + t.Logf("deleting job %d", id) + err = node.App.DeleteJob(context.Background(), id) + require.NoError(t, err) + } + + // Commit on both chains to reach Finality + ccipTH.Source.Chain.Commit() + ccipTH.Dest.Chain.Commit() + + // create new jobs + jobParams = ccipTH.NewCCIPJobSpecParams(tokenPricesUSDPipeline, priceGetterConfigJson, newConfigBlock, "") + jobParams.Version = "v2" + jobParams.SourceStartBlock = srcStartBlock + ccipTH.AddAllJobs(t, jobParams) + committedSeqNum := uint64(0) + // Now the requests should be delivered + for i := startSeq; i <= endSeqNum; i++ { + t.Logf("verifying seqnum %d", i) + ccipTH.AllNodesHaveReqSeqNum(t, i) + if committedSeqNum < uint64(i+1) { + committedSeqNum = ccipTH.EventuallyReportCommitted(t, i) + } + ccipTH.EventuallyExecutionStateChangedToSuccess(t, []uint64{uint64(i)}, uint64(newConfigBlock)) + } + + // nonces should be correctly synced from v1 contracts for the sender + nonceAtOnRampV2, err := ccipTH.Source.OnRamp.GetSenderNonce(nil, ccipTH.Source.User.From) + require.NoError(t, err, "getting nonce from onRamp") + nonceAtOffRampV2, err := ccipTH.Dest.OffRamp.GetSenderNonce(nil, ccipTH.Source.User.From) + require.NoError(t, err, "getting nonce from offRamp") + require.Equal(t, nonceAtOnRampV1+uint64(noOfRequests)+1, nonceAtOnRampV2, "nonce should be synced from v1 onRamps") + require.Equal(t, nonceAtOffRampV1+uint64(noOfRequests)+1, nonceAtOffRampV2, "nonce should be synced from v1 offRamps") + currentSeqNum = endSeqNum + 1 + if !test.allowOutOfOrderExecution { + currentNonce = uint64(currentSeqNum) + } + }) + + t.Run("pay nops", func(t *testing.T) { + linkToTransferToOnRamp := big.NewInt(1e18) + + // transfer some link to onramp to pay the nops + _, err := ccipTH.Source.LinkToken.Transfer(ccipTH.Source.User, ccipTH.Source.OnRamp.Address(), linkToTransferToOnRamp) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + srcBalReq := []testhelpers.BalanceReq{ + { + Name: testhelpers.Sender, + Addr: ccipTH.Source.User.From, + Getter: ccipTH.GetSourceWrappedTokenBalance, + }, + { + Name: testhelpers.OnRampNative, + Addr: ccipTH.Source.OnRamp.Address(), + Getter: ccipTH.GetSourceWrappedTokenBalance, + }, + { + Name: testhelpers.OnRamp, + Addr: ccipTH.Source.OnRamp.Address(), + Getter: ccipTH.GetSourceLinkBalance, + }, + { + Name: testhelpers.SourceRouter, + Addr: ccipTH.Source.Router.Address(), + Getter: ccipTH.GetSourceWrappedTokenBalance, + }, + } + + var nopsAndWeights []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight + var totalWeight uint16 + nodes := ccipTH.Nodes + for i := range nodes { + // For now set the transmitter addresses to be the same as the payee addresses + nodes[i].PaymentReceiver = nodes[i].Transmitter + nopsAndWeights = append(nopsAndWeights, evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{ + Nop: nodes[i].PaymentReceiver, + Weight: 5, + }) + totalWeight += 5 + srcBalReq = append(srcBalReq, testhelpers.BalanceReq{ + Name: fmt.Sprintf("node %d", i), + Addr: nodes[i].PaymentReceiver, + Getter: ccipTH.GetSourceLinkBalance, + }) + } + srcBalances, err := testhelpers.GetBalances(t, srcBalReq) + require.NoError(t, err) + + // set nops on the onramp + ccipTH.SetNopsOnRamp(t, nopsAndWeights) + + // send a message + extraArgs, err := testhelpers.GetEVMExtraArgsV2(big.NewInt(200_000), test.allowOutOfOrderExecution) + require.NoError(t, err) + + // FeeToken is empty, indicating it should use native token + msg := router.ClientEVM2AnyMessage{ + Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[1].Receiver.Address()), + Data: []byte("hello"), + TokenAmounts: []router.ClientEVMTokenAmount{}, + ExtraArgs: extraArgs, + FeeToken: common.Address{}, + } + fee, err := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) + require.NoError(t, err) + + // verify message is sent + ccipTH.Source.User.Value = fee + ccipTH.SendRequest(t, msg) + ccipTH.Source.User.Value = nil + ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum) + ccipTH.EventuallyReportCommitted(t, currentSeqNum) + + executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum) + assert.Len(t, executionLogs, 1) + ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) + currentSeqNum++ + if test.allowOutOfOrderExecution { + currentNonce = uint64(currentSeqNum) + } + + // get the nop fee + nopFee, err := ccipTH.Source.OnRamp.GetNopFeesJuels(nil) + require.NoError(t, err) + t.Log("nopFee", nopFee) + + // withdraw fees and verify there is still fund left for nop payment + _, err = ccipTH.Source.OnRamp.WithdrawNonLinkFees( + ccipTH.Source.User, + ccipTH.Source.WrappedNative.Address(), + ccipTH.Source.User.From, + ) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + // pay nops + _, err = ccipTH.Source.OnRamp.PayNops(ccipTH.Source.User) + require.NoError(t, err) + ccipTH.Source.Chain.Commit() + + srcBalanceAssertions := []testhelpers.BalanceAssertion{ + { + // Onramp should not have any balance left in wrapped native + Name: testhelpers.OnRampNative, + Address: ccipTH.Source.OnRamp.Address(), + Expected: big.NewInt(0).String(), + Getter: ccipTH.GetSourceWrappedTokenBalance, + }, + { + // Onramp should have the remaining link after paying nops + Name: testhelpers.OnRamp, + Address: ccipTH.Source.OnRamp.Address(), + Expected: new(big.Int).Sub(srcBalances[testhelpers.OnRamp], nopFee).String(), + Getter: ccipTH.GetSourceLinkBalance, + }, + { + Name: testhelpers.SourceRouter, + Address: ccipTH.Source.Router.Address(), + Expected: srcBalances[testhelpers.SourceRouter].String(), + Getter: ccipTH.GetSourceWrappedTokenBalance, + }, + // onRamp's balance (of previously sent fee during message sending) should have been transferred to + // the owner as a result of WithdrawNonLinkFees + { + Name: testhelpers.Sender, + Address: ccipTH.Source.User.From, + Expected: fee.String(), + Getter: ccipTH.GetSourceWrappedTokenBalance, + }, + } + + // the nodes should be paid according to the weights assigned + for i, node := range nodes { + paymentWeight := float64(nopsAndWeights[i].Weight) / float64(totalWeight) + paidInFloat := paymentWeight * float64(nopFee.Int64()) + paid, _ := new(big.Float).SetFloat64(paidInFloat).Int64() + bal := new(big.Int).Add( + new(big.Int).SetInt64(paid), + srcBalances[fmt.Sprintf("node %d", i)]).String() + srcBalanceAssertions = append(srcBalanceAssertions, testhelpers.BalanceAssertion{ + Name: fmt.Sprintf("node %d", i), + Address: node.PaymentReceiver, + Expected: bal, + Getter: ccipTH.GetSourceLinkBalance, + }) + } + ccipTH.AssertBalances(t, srcBalanceAssertions) + }) + + // Keep on sending a bunch of messages + // In the meantime update onchainConfig with new price registry address + // Verify if the jobs can pick up updated config + // Verify if all the messages are sent + t.Run("config change or price registry update while requests are inflight", func(t *testing.T) { + gasLimit := big.NewInt(200_003) // prime number + tokenAmount := big.NewInt(100) + msgWg := &sync.WaitGroup{} + msgWg.Add(1) + ticker := time.NewTicker(100 * time.Millisecond) + defer ticker.Stop() + startSeq := currentSeqNum + endSeq := currentSeqNum + 20 + + // send message with the old configs + ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) + ccipTH.Source.Chain.Commit() + + go func(ccipContracts testhelpers.CCIPContracts, currentSeqNum int) { + seqNumber := currentSeqNum + 1 + defer msgWg.Done() + for { + <-ticker.C // wait for ticker + t.Logf("sending request for seqnum %d", seqNumber) + ccipContracts.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) + ccipContracts.Source.Chain.Commit() + seqNumber++ + if seqNumber == endSeq { + return + } + } + }(ccipTH.CCIPContracts, currentSeqNum) + + ccipTH.DeployNewPriceRegistry(t) + commitOnchainConfig := ccipTH.CreateDefaultCommitOnchainConfig(t) + commitOffchainConfig := ccipTH.CreateDefaultCommitOffchainConfig(t) + execOnchainConfig := ccipTH.CreateDefaultExecOnchainConfig(t) + execOffchainConfig := ccipTH.CreateDefaultExecOffchainConfig(t) + + ccipTH.SetupOnchainConfig(t, commitOnchainConfig, commitOffchainConfig, execOnchainConfig, execOffchainConfig) + + // wait for all requests to be complete + msgWg.Wait() + for i := startSeq; i < endSeq; i++ { + ccipTH.AllNodesHaveReqSeqNum(t, i) + ccipTH.EventuallyReportCommitted(t, i) + + executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, i, i) + assert.Len(t, executionLogs, 1) + ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) + } + + for i, node := range ccipTH.Nodes { + t.Logf("verifying node %d", i) + node.EventuallyNodeUsesNewCommitConfig(t, ccipTH, ccipdata.CommitOnchainConfig{ + PriceRegistry: ccipTH.Dest.PriceRegistry.Address(), + }) + node.EventuallyNodeUsesNewExecConfig(t, ccipTH, v1_5_0.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: testhelpers.PermissionLessExecutionThresholdSeconds, + Router: ccipTH.Dest.Router.Address(), + PriceRegistry: ccipTH.Dest.PriceRegistry.Address(), + MaxDataBytes: 1e5, + MaxNumberOfTokensPerMsg: 5, + MaxPoolReleaseOrMintGas: 200_000, + MaxTokenTransferGas: 100_000, + }) + node.EventuallyNodeUsesUpdatedPriceRegistry(t, ccipTH) + } + currentSeqNum = endSeq + if test.allowOutOfOrderExecution { + currentNonce = uint64(currentSeqNum) + } + }) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/autosync.go b/core/services/ocr2/plugins/ccip/internal/cache/autosync.go new file mode 100644 index 0000000000..690b4dd05b --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/autosync.go @@ -0,0 +1,141 @@ +package cache + +import ( + "context" + "database/sql" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" +) + +type AutoSync[T any] interface { + Get(ctx context.Context, syncFunc func(ctx context.Context) (T, error)) (T, error) +} + +// LogpollerEventsBased IMPORTANT: Cache refresh relies on the events that are finalized. +// This introduces some delay between the event onchain occurrence and cache refreshing. +// This is intentional, because we want to prevent handling reorgs within the cache. +type LogpollerEventsBased[T any] struct { + logPoller logpoller.LogPoller + observedEvents []common.Hash + address common.Address + + lock *sync.RWMutex + value T + lastChangeBlock int64 +} + +func NewLogpollerEventsBased[T any]( + lp logpoller.LogPoller, + observedEvents []common.Hash, + contractAddress common.Address, +) *LogpollerEventsBased[T] { + var emptyValue T + return &LogpollerEventsBased[T]{ + logPoller: lp, + observedEvents: observedEvents, + address: contractAddress, + + lock: &sync.RWMutex{}, + value: emptyValue, + lastChangeBlock: 0, + } +} + +func (c *LogpollerEventsBased[T]) Get(ctx context.Context, syncFunc func(ctx context.Context) (T, error)) (T, error) { + var empty T + + hasExpired, newEventBlockNum, err := c.hasExpired(ctx) + if err != nil { + return empty, fmt.Errorf("check cache expiration: %w", err) + } + + if hasExpired { + var latestValue T + latestValue, err = syncFunc(ctx) + if err != nil { + return empty, fmt.Errorf("sync func: %w", err) + } + + c.set(latestValue, newEventBlockNum) + return latestValue, nil + } + + cachedValue := c.get() + if err != nil { + return empty, fmt.Errorf("get cached value: %w", err) + } + + c.lock.Lock() + if newEventBlockNum > c.lastChangeBlock { + // update the most recent block number + // that way the scanning window is shorter in the next run + c.lastChangeBlock = newEventBlockNum + } + c.lock.Unlock() + + return cachedValue, nil +} + +func (c *LogpollerEventsBased[T]) hasExpired(ctx context.Context) (expired bool, blockOfLatestEvent int64, err error) { + c.lock.RLock() + blockOfCurrentValue := c.lastChangeBlock + c.lock.RUnlock() + + // NOTE: latest block should be fetched before LatestBlockByEventSigsAddrsWithConfs + // Otherwise there might be new events between LatestBlockByEventSigsAddrsWithConfs and + // latestBlock which will be missed. + latestBlock, err := c.logPoller.LatestBlock(ctx) + latestFinalizedBlock := int64(0) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + return false, 0, fmt.Errorf("get latest log poller block: %w", err) + } else if err == nil { + // Since we know that we have all the events till latestBlock.FinalizedBlockNumber + // we want to return the block number instead of the block of the latest event + // for reducing the scan window on the next call. + latestFinalizedBlock = latestBlock.FinalizedBlockNumber + } + + if blockOfCurrentValue == 0 { + return true, latestFinalizedBlock, nil + } + + blockOfLatestEvent, err = c.logPoller.LatestBlockByEventSigsAddrsWithConfs( + ctx, + blockOfCurrentValue, + c.observedEvents, + []common.Address{c.address}, + evmtypes.Finalized, + ) + if err != nil { + return false, 0, fmt.Errorf("get latest events form lp: %w", err) + } + + if blockOfLatestEvent > latestFinalizedBlock { + latestFinalizedBlock = blockOfLatestEvent + } + return blockOfLatestEvent > blockOfCurrentValue, latestFinalizedBlock, nil +} + +func (c *LogpollerEventsBased[T]) set(value T, blockNum int64) { + c.lock.Lock() + defer c.lock.Unlock() + + if c.lastChangeBlock > blockNum { + return + } + + c.value = value + c.lastChangeBlock = blockNum +} + +func (c *LogpollerEventsBased[T]) get() T { + c.lock.RLock() + defer c.lock.RUnlock() + return c.value +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/autosync_test.go b/core/services/ocr2/plugins/ccip/internal/cache/autosync_test.go new file mode 100644 index 0000000000..0babfeb421 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/autosync_test.go @@ -0,0 +1,128 @@ +package cache_test + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" +) + +func TestLogpollerEventsBased(t *testing.T) { + ctx := testutils.Context(t) + lp := lpmocks.NewLogPoller(t) + observedEvents := []common.Hash{ + utils.Bytes32FromString("event a"), + utils.Bytes32FromString("event b"), + } + contractAddress := utils.RandomAddress() + c := cache.NewLogpollerEventsBased[[]int](lp, observedEvents, contractAddress) + + testRounds := []struct { + logPollerLatestBlock int64 // latest block that logpoller parsed + latestEventBlock int64 // latest block that an event was seen + stateLatestBlock int64 // block of the current cached value (before run) + shouldSync bool // whether we expect sync to happen in this round + syncData []int // data returned after sync + expData []int // expected data that cache will return + }{ + { + // this is the first 'Get' call to our cache, an event was seen at block 800 + // and now log poller has reached block 1000. + logPollerLatestBlock: 1000, + latestEventBlock: 800, + stateLatestBlock: 0, + shouldSync: true, + syncData: []int{1, 2, 3}, + expData: []int{1, 2, 3}, + }, + { + // log poller moved a few blocks and there weren't any new events + logPollerLatestBlock: 1010, + latestEventBlock: 800, + stateLatestBlock: 1000, + shouldSync: false, + expData: []int{1, 2, 3}, + }, + { + // log poller moved a few blocks and there was a new event + logPollerLatestBlock: 1020, + latestEventBlock: 1020, + stateLatestBlock: 1010, + shouldSync: true, + syncData: []int{111}, + expData: []int{111}, + }, + { + // log poller moved a few more blocks and there was another new event + logPollerLatestBlock: 1050, + latestEventBlock: 1040, + stateLatestBlock: 1020, + shouldSync: true, + syncData: []int{222}, + expData: []int{222}, + }, + { + // log poller moved a few more blocks and there wasn't any new event + logPollerLatestBlock: 1100, + latestEventBlock: 1040, + stateLatestBlock: 1050, + shouldSync: false, + expData: []int{222}, + }, + { + // log poller moved a few more blocks and there wasn't any new event + logPollerLatestBlock: 1300, + latestEventBlock: 1040, + stateLatestBlock: 1100, + shouldSync: false, + expData: []int{222}, + }, + { + // log poller moved a few more blocks and there was a new event + // more recent than latest block (for whatever internal reason) + logPollerLatestBlock: 1300, + latestEventBlock: 1305, + stateLatestBlock: 1300, + shouldSync: true, + syncData: []int{666}, + expData: []int{666}, + }, + { + // log poller moved a few more blocks and there wasn't any new event + logPollerLatestBlock: 1300, + latestEventBlock: 1305, + stateLatestBlock: 1305, // <-- that's what we are testing in this round + shouldSync: false, + expData: []int{666}, + }, + } + + for _, round := range testRounds { + lp.On("LatestBlock", mock.Anything). + Return(logpoller.LogPollerBlock{FinalizedBlockNumber: round.logPollerLatestBlock}, nil).Once() + + if round.stateLatestBlock > 0 { + lp.On( + "LatestBlockByEventSigsAddrsWithConfs", + mock.Anything, + round.stateLatestBlock, + observedEvents, + []common.Address{contractAddress}, + evmtypes.Finalized, + ).Return(round.latestEventBlock, nil).Once() + } + + data, err := c.Get(ctx, func(ctx context.Context) ([]int, error) { return round.syncData, nil }) + assert.NoError(t, err) + assert.Equal(t, round.expData, data) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/chain_health.go b/core/services/ocr2/plugins/ccip/internal/cache/chain_health.go new file mode 100644 index 0000000000..00f90615eb --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/chain_health.go @@ -0,0 +1,273 @@ +package cache + +import ( + "context" + "sync" + "time" + + "github.com/patrickmn/go-cache" + "github.com/pkg/errors" + "golang.org/x/sync/errgroup" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +// ChainHealthcheck checks the health of the both source and destination chain. +// Based on the values returned, CCIP can make a decision to stop or continue processing messages. +// There are four things verified here: +// 1. Source chain is healthy (this is verified by checking if source LogPoller saw finality violation) +// 2. Dest chain is healthy (this is verified by checking if destination LogPoller saw finality violation) +// 3. CommitStore is down (this is verified by checking if CommitStore is down and destination RMN is not cursed) +// 4. Source chain is cursed (this is verified by checking if source RMN is not cursed) +// +// Whenever any of the above checks fail, the chain is considered unhealthy and the CCIP should stop +// processing messages. Additionally, when the chain is unhealthy, this information is considered "sticky" +// and is cached for a certain period of time based on defaultGlobalStatusExpirationDuration. +// This may lead to some false-positives, but in this case we want to be extra cautious and avoid executing any reorged messages. +// +// Additionally, to reduce the number of calls to the RPC, we refresh RMN state in the background based on defaultRMNStateRefreshInterval +type ChainHealthcheck interface { + job.ServiceCtx + IsHealthy(ctx context.Context) (bool, error) +} + +const ( + // RMN curse state is refreshed every 10 seconds + defaultRMNStateRefreshInterval = 10 * time.Second + // Whenever we mark the chain as unhealthy, we cache this information for 30 minutes + defaultGlobalStatusExpirationDuration = 30 * time.Minute + + globalStatusKey = "globalStatus" + rmnStatusKey = "rmnCurseCheck" +) + +type chainHealthcheck struct { + cache *cache.Cache + globalStatusKey string + rmnStatusKey string + globalStatusExpiration time.Duration + rmnStatusRefreshInterval time.Duration + + lggr logger.Logger + onRamp ccipdata.OnRampReader + commitStore ccipdata.CommitStoreReader + + services.StateMachine + wg *sync.WaitGroup + backgroundCtx context.Context //nolint:containedctx + backgroundCancel context.CancelFunc +} + +func NewChainHealthcheck(lggr logger.Logger, onRamp ccipdata.OnRampReader, commitStore ccipdata.CommitStoreReader) *chainHealthcheck { + ctx, cancel := context.WithCancel(context.Background()) + + ch := &chainHealthcheck{ + // Different keys use different expiration times, so we don't need to worry about the default value + cache: cache.New(cache.NoExpiration, 0), + rmnStatusKey: rmnStatusKey, + globalStatusKey: globalStatusKey, + globalStatusExpiration: defaultGlobalStatusExpirationDuration, + rmnStatusRefreshInterval: defaultRMNStateRefreshInterval, + + lggr: lggr, + onRamp: onRamp, + commitStore: commitStore, + + wg: new(sync.WaitGroup), + backgroundCtx: ctx, + backgroundCancel: cancel, + } + return ch +} + +// newChainHealthcheckWithCustomEviction is used for testing purposes only. It doesn't start background worker +func newChainHealthcheckWithCustomEviction(lggr logger.Logger, onRamp ccipdata.OnRampReader, commitStore ccipdata.CommitStoreReader, globalStatusDuration time.Duration, rmnStatusRefreshInterval time.Duration) *chainHealthcheck { + ctx, cancel := context.WithCancel(context.Background()) + + return &chainHealthcheck{ + cache: cache.New(rmnStatusRefreshInterval, 0), + rmnStatusKey: rmnStatusKey, + globalStatusKey: globalStatusKey, + globalStatusExpiration: globalStatusDuration, + rmnStatusRefreshInterval: rmnStatusRefreshInterval, + + lggr: lggr, + onRamp: onRamp, + commitStore: commitStore, + + wg: new(sync.WaitGroup), + backgroundCtx: ctx, + backgroundCancel: cancel, + } +} + +type rmnResponse struct { + healthy bool + err error +} + +func (c *chainHealthcheck) IsHealthy(ctx context.Context) (bool, error) { + // Verify if flag is raised to indicate that the chain is not healthy + // If set to false then immediately return false without checking the chain + if cachedValue, found := c.cache.Get(c.globalStatusKey); found { + healthy, ok := cachedValue.(bool) + // If cached value is properly casted to bool and not healthy it means the sticky flag is raised + // and should be returned immediately + if !ok { + c.lggr.Criticalw("Failed to cast cached value to sticky healthcheck", "value", cachedValue) + } else if ok && !healthy { + return false, nil + } + } + + // These checks are cheap and don't require any communication with the database or RPC + if healthy, err := c.checkIfReadersAreHealthy(ctx); err != nil { + return false, err + } else if !healthy { + c.markStickyStatusUnhealthy() + return healthy, nil + } + + // First call might initialize cache if it's not initialized yet. Otherwise, it will use the cached value + if healthy, err := c.checkIfRMNsAreHealthy(ctx); err != nil { + return false, err + } else if !healthy { + c.markStickyStatusUnhealthy() + return healthy, nil + } + return true, nil +} + +func (c *chainHealthcheck) Start(context.Context) error { + return c.StateMachine.StartOnce("ChainHealthcheck", func() error { + c.lggr.Info("Starting ChainHealthcheck") + c.wg.Add(1) + c.run() + return nil + }) +} + +func (c *chainHealthcheck) Close() error { + return c.StateMachine.StopOnce("ChainHealthcheck", func() error { + c.lggr.Info("Closing ChainHealthcheck") + c.backgroundCancel() + c.wg.Wait() + return nil + }) +} + +func (c *chainHealthcheck) run() { + ticker := time.NewTicker(c.rmnStatusRefreshInterval) + go func() { + defer c.wg.Done() + // Refresh the RMN state immediately after starting the background refresher + _, _ = c.refresh(c.backgroundCtx) + + for { + select { + case <-c.backgroundCtx.Done(): + return + case <-ticker.C: + _, err := c.refresh(c.backgroundCtx) + if err != nil { + c.lggr.Errorw("Failed to refresh RMN state in the background", "err", err) + } + } + } + }() +} + +func (c *chainHealthcheck) refresh(ctx context.Context) (bool, error) { + healthy, err := c.fetchRMNCurseState(ctx) + c.cache.Set( + c.rmnStatusKey, + rmnResponse{healthy, err}, + // Cache the value for 3 refresh intervals, this is just a defensive approach + // that will enforce the RMN state to be refreshed in case of bg worker hiccup (it should never happen) + 3*c.rmnStatusRefreshInterval, + ) + return healthy, err +} + +// checkIfReadersAreHealthy checks if the source and destination chains are healthy by calling underlying LogPoller +// These calls are cheap because they don't require any communication with the database or RPC, so we don't have +// to cache the result of these calls. +func (c *chainHealthcheck) checkIfReadersAreHealthy(ctx context.Context) (bool, error) { + sourceChainHealthy, err := c.onRamp.IsSourceChainHealthy(ctx) + if err != nil { + return false, errors.Wrap(err, "onRamp IsSourceChainHealthy errored") + } + + destChainHealthy, err := c.commitStore.IsDestChainHealthy(ctx) + if err != nil { + return false, errors.Wrap(err, "commitStore IsDestChainHealthy errored") + } + + if !sourceChainHealthy || !destChainHealthy { + c.lggr.Criticalw( + "Lane processing is stopped because source or destination chain is reported unhealthy", + "sourceChainHealthy", sourceChainHealthy, + "destChainHealthy", destChainHealthy, + ) + } + return sourceChainHealthy && destChainHealthy, nil +} + +func (c *chainHealthcheck) checkIfRMNsAreHealthy(ctx context.Context) (bool, error) { + if cachedValue, found := c.cache.Get(c.rmnStatusKey); found { + rmn := cachedValue.(rmnResponse) + return rmn.healthy, rmn.err + } + + // If the value is not found in the cache, fetch the RMN curse state in a sync manner for the first time + c.lggr.Info("Refreshing RMN state from the plugin routine, this should happen only once per lane during boot") + return c.refresh(ctx) +} + +func (c *chainHealthcheck) markStickyStatusUnhealthy() { + c.cache.Set(c.globalStatusKey, false, c.globalStatusExpiration) +} + +func (c *chainHealthcheck) fetchRMNCurseState(ctx context.Context) (bool, error) { + var ( + eg = new(errgroup.Group) + isCommitStoreDown bool + isSourceCursed bool + ) + + eg.Go(func() error { + var err error + isCommitStoreDown, err = c.commitStore.IsDown(ctx) + if err != nil { + return errors.Wrap(err, "commitStore isDown check errored") + } + return nil + }) + + eg.Go(func() error { + var err error + isSourceCursed, err = c.onRamp.IsSourceCursed(ctx) + if err != nil { + return errors.Wrap(err, "onRamp isSourceCursed errored") + } + return nil + }) + + if err := eg.Wait(); err != nil { + return false, err + } + + if isCommitStoreDown || isSourceCursed { + c.lggr.Criticalw( + "Lane processing is stopped because source chain is cursed or CommitStore is down", + "isCommitStoreDown", isCommitStoreDown, + "isSourceCursed", isSourceCursed, + ) + return false, nil + } + return true, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/chain_health_test.go b/core/services/ocr2/plugins/ccip/internal/cache/chain_health_test.go new file mode 100644 index 0000000000..ccdc7c4b22 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/chain_health_test.go @@ -0,0 +1,303 @@ +package cache + +import ( + "context" + "errors" + "fmt" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" +) + +func Test_RMNStateCaching(t *testing.T) { + ctx := tests.Context(t) + lggr := logger.TestLogger(t) + mockCommitStore := mocks.NewCommitStoreReader(t) + mockOnRamp := mocks.NewOnRampReader(t) + + chainState := newChainHealthcheckWithCustomEviction(lggr, mockOnRamp, mockCommitStore, 10*time.Hour, 10*time.Hour) + + // Chain is not cursed and healthy + mockCommitStore.On("IsDown", ctx).Return(false, nil).Once() + mockCommitStore.On("IsDestChainHealthy", ctx).Return(true, nil).Maybe() + mockOnRamp.On("IsSourceCursed", ctx).Return(false, nil).Once() + mockOnRamp.On("IsSourceChainHealthy", ctx).Return(true, nil).Maybe() + healthy, err := chainState.IsHealthy(ctx) + assert.NoError(t, err) + assert.True(t, healthy) + + // Chain is cursed, but cache is stale + mockCommitStore.On("IsDown", ctx).Return(true, nil).Once() + mockOnRamp.On("IsSourceCursed", ctx).Return(true, nil).Once() + healthy, err = chainState.IsHealthy(ctx) + assert.NoError(t, err) + assert.True(t, healthy) + + // Enforce cache refresh + _, err = chainState.refresh(ctx) + assert.NoError(t, err) + + healthy, err = chainState.IsHealthy(ctx) + assert.Nil(t, err) + assert.False(t, healthy) + + // Chain is not cursed, but previous curse should be "sticky" even when force refreshing + mockCommitStore.On("IsDown", ctx).Return(false, nil).Maybe() + mockOnRamp.On("IsSourceCursed", ctx).Return(false, nil).Maybe() + // Enforce cache refresh + _, err = chainState.refresh(ctx) + assert.NoError(t, err) + + healthy, err = chainState.IsHealthy(ctx) + assert.Nil(t, err) + assert.False(t, healthy) +} + +func Test_ChainStateIsCached(t *testing.T) { + ctx := tests.Context(t) + lggr := logger.TestLogger(t) + mockCommitStore := mocks.NewCommitStoreReader(t) + mockOnRamp := mocks.NewOnRampReader(t) + + chainState := newChainHealthcheckWithCustomEviction(lggr, mockOnRamp, mockCommitStore, 10*time.Hour, 10*time.Hour) + + // Chain is not cursed and healthy + mockCommitStore.On("IsDown", ctx).Return(false, nil).Maybe() + mockCommitStore.On("IsDestChainHealthy", ctx).Return(true, nil).Once() + mockOnRamp.On("IsSourceCursed", ctx).Return(false, nil).Maybe() + mockOnRamp.On("IsSourceChainHealthy", ctx).Return(true, nil).Once() + + _, err := chainState.refresh(ctx) + assert.NoError(t, err) + + healthy, err := chainState.IsHealthy(ctx) + assert.NoError(t, err) + assert.True(t, healthy) + + // Chain is not healthy + mockCommitStore.On("IsDestChainHealthy", ctx).Return(false, nil).Once() + mockOnRamp.On("IsSourceChainHealthy", ctx).Return(false, nil).Once() + _, err = chainState.refresh(ctx) + assert.NoError(t, err) + + healthy, err = chainState.IsHealthy(ctx) + assert.NoError(t, err) + assert.False(t, healthy) + + // Previous value is returned + mockCommitStore.On("IsDestChainHealthy", ctx).Return(true, nil).Maybe() + mockOnRamp.On("IsSourceChainHealthy", ctx).Return(true, nil).Maybe() + + _, err = chainState.refresh(ctx) + assert.NoError(t, err) + + healthy, err = chainState.IsHealthy(ctx) + assert.NoError(t, err) + assert.False(t, healthy) +} + +func Test_ChainStateIsHealthy(t *testing.T) { + testCases := []struct { + name string + commitStoreDown bool + commitStoreErr error + onRampCursed bool + onRampErr error + sourceChainUnhealthy bool + sourceChainErr error + destChainUnhealthy bool + destChainErr error + + expectedState bool + expectedErr bool + }{ + { + name: "all components healthy", + expectedState: true, + }, + { + name: "CommitStore is down", + commitStoreDown: true, + expectedState: false, + }, + { + name: "CommitStore error", + commitStoreErr: errors.New("commit store error"), + expectedErr: true, + }, + { + name: "OnRamp is cursed", + onRampCursed: true, + expectedState: false, + }, + { + name: "OnRamp error", + onRampErr: errors.New("onramp error"), + expectedErr: true, + }, + { + name: "Source chain is unhealthy", + sourceChainUnhealthy: true, + expectedState: false, + }, + { + name: "Source chain error", + sourceChainErr: errors.New("source chain error"), + expectedErr: true, + }, + { + name: "Destination chain is unhealthy", + destChainUnhealthy: true, + expectedState: false, + }, + { + name: "Destination chain error", + destChainErr: errors.New("destination chain error"), + expectedErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctx := tests.Context(t) + mockCommitStore := mocks.NewCommitStoreReader(t) + mockOnRamp := mocks.NewOnRampReader(t) + + mockCommitStore.On("IsDown", ctx).Return(tc.commitStoreDown, tc.commitStoreErr).Maybe() + mockCommitStore.On("IsDestChainHealthy", ctx).Return(!tc.destChainUnhealthy, tc.destChainErr).Maybe() + mockOnRamp.On("IsSourceCursed", ctx).Return(tc.onRampCursed, tc.onRampErr).Maybe() + mockOnRamp.On("IsSourceChainHealthy", ctx).Return(!tc.sourceChainUnhealthy, tc.sourceChainErr).Maybe() + + chainState := newChainHealthcheckWithCustomEviction(logger.TestLogger(t), mockOnRamp, mockCommitStore, 10*time.Hour, 10*time.Hour) + + healthy, err := chainState.IsHealthy(ctx) + + if tc.expectedErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tc.expectedState, healthy) + } + }) + } +} + +func Test_RefreshingInBackground(t *testing.T) { + mockCommitStore := newCommitStoreWrapper(t, true, nil) + mockCommitStore.CommitStoreReader.On("IsDestChainHealthy", mock.Anything).Return(true, nil).Maybe() + + mockOnRamp := newOnRampWrapper(t, true, nil) + mockOnRamp.OnRampReader.On("IsSourceChainHealthy", mock.Anything).Return(true, nil).Maybe() + + chainState := newChainHealthcheckWithCustomEviction( + logger.TestLogger(t), + mockOnRamp, + mockCommitStore, + 10*time.Microsecond, + 10*time.Microsecond, + ) + require.NoError(t, chainState.Start(tests.Context(t))) + + // All healthy + assertHealthy(t, chainState, true) + + // Commit store not healthy + mockCommitStore.set(false, nil) + assertHealthy(t, chainState, false) + + // Commit store error + mockCommitStore.set(false, fmt.Errorf("commit store error")) + assertError(t, chainState) + + // Commit store is back + mockCommitStore.set(true, nil) + assertHealthy(t, chainState, true) + + // OnRamp not healthy + mockOnRamp.set(false, nil) + assertHealthy(t, chainState, false) + + // OnRamp error + mockOnRamp.set(false, fmt.Errorf("onramp error")) + assertError(t, chainState) + + // All back in healthy state + mockOnRamp.set(true, nil) + assertHealthy(t, chainState, true) + + require.NoError(t, chainState.Close()) +} + +func assertHealthy(t *testing.T, ch *chainHealthcheck, expected bool) { + assert.Eventually(t, func() bool { + healthy, err := ch.IsHealthy(testutils.Context(t)) + return err == nil && healthy == expected + }, testutils.WaitTimeout(t), testutils.TestInterval) +} + +func assertError(t *testing.T, ch *chainHealthcheck) { + assert.Eventually(t, func() bool { + _, err := ch.IsHealthy(testutils.Context(t)) + return err != nil + }, testutils.WaitTimeout(t), testutils.TestInterval) +} + +type fakeStatusWrapper struct { + *mocks.CommitStoreReader + *mocks.OnRampReader + + healthy bool + err error + mu *sync.Mutex +} + +func newCommitStoreWrapper(t *testing.T, healthy bool, err error) *fakeStatusWrapper { + return &fakeStatusWrapper{ + CommitStoreReader: mocks.NewCommitStoreReader(t), + healthy: healthy, + err: err, + mu: new(sync.Mutex), + } +} + +func newOnRampWrapper(t *testing.T, healthy bool, err error) *fakeStatusWrapper { + return &fakeStatusWrapper{ + OnRampReader: mocks.NewOnRampReader(t), + healthy: healthy, + err: err, + mu: new(sync.Mutex), + } +} + +func (f *fakeStatusWrapper) IsDown(context.Context) (bool, error) { + f.mu.Lock() + defer f.mu.Unlock() + return !f.healthy, f.err +} + +func (f *fakeStatusWrapper) IsSourceCursed(context.Context) (bool, error) { + f.mu.Lock() + defer f.mu.Unlock() + return !f.healthy, f.err +} + +func (f *fakeStatusWrapper) Close() error { + return nil +} + +func (f *fakeStatusWrapper) set(healthy bool, err error) { + f.mu.Lock() + defer f.mu.Unlock() + f.healthy = healthy + f.err = err +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/commit_roots.go b/core/services/ocr2/plugins/ccip/internal/cache/commit_roots.go new file mode 100644 index 0000000000..5f8bd5edc5 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/commit_roots.go @@ -0,0 +1,243 @@ +package cache + +import ( + "context" + "slices" + "sync" + "time" + + "github.com/patrickmn/go-cache" + orderedmap "github.com/wk8/go-ordered-map/v2" + + "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +const ( + // EvictionGracePeriod defines how long after the messageVisibilityInterval a root is still kept in the cache + EvictionGracePeriod = 1 * time.Hour + // CleanupInterval defines how often roots cache is scanned to evict stale roots + CleanupInterval = 30 * time.Minute +) + +type CommitsRootsCache interface { + RootsEligibleForExecution(ctx context.Context) ([]ccip.CommitStoreReport, error) + MarkAsExecuted(merkleRoot [32]byte) + Snooze(merkleRoot [32]byte) +} + +func NewCommitRootsCache( + lggr logger.Logger, + reader ccip.CommitStoreReader, + messageVisibilityInterval time.Duration, + rootSnoozeTime time.Duration, +) CommitsRootsCache { + return newCommitRootsCache( + lggr, + reader, + messageVisibilityInterval, + rootSnoozeTime, + CleanupInterval, + EvictionGracePeriod, + ) +} + +func newCommitRootsCache( + lggr logger.Logger, + reader ccip.CommitStoreReader, + messageVisibilityInterval time.Duration, + rootSnoozeTime time.Duration, + cleanupInterval time.Duration, + evictionGracePeriod time.Duration, +) *commitRootsCache { + snoozedRoots := cache.New(rootSnoozeTime, cleanupInterval) + executedRoots := cache.New(messageVisibilityInterval+evictionGracePeriod, cleanupInterval) + + return &commitRootsCache{ + lggr: lggr, + reader: reader, + rootSnoozeTime: rootSnoozeTime, + finalizedRoots: orderedmap.New[string, ccip.CommitStoreReportWithTxMeta](), + executedRoots: executedRoots, + snoozedRoots: snoozedRoots, + messageVisibilityInterval: messageVisibilityInterval, + latestFinalizedCommitRootTs: time.Now().Add(-messageVisibilityInterval), + cacheMu: sync.RWMutex{}, + } +} + +type commitRootsCache struct { + lggr logger.Logger + reader ccip.CommitStoreReader + messageVisibilityInterval time.Duration + rootSnoozeTime time.Duration + + // Mutable state. finalizedRoots is thread-safe by default, but updating latestFinalizedCommitRootTs and finalizedRoots requires locking. + cacheMu sync.RWMutex + // finalizedRoots is a map of merkleRoot -> CommitStoreReportWithTxMeta. It stores all the CommitReports that are + // marked as finalized by LogPoller, but not executed yet. Keeping only finalized reports doesn't require any state sync between LP and the cache. + // In order to keep this map size under control, we evict stale items every time we fetch new logs from the database. + // Also, ccip.CommitStoreReportWithTxMeta is a very tiny entity with almost fixed size, so it's not a big deal to keep it in memory. + // In case of high memory footprint caused by storing roots, we can make these even more lightweight by removing token/gas price updates. + // Whenever the root is executed (all messages executed and ExecutionStateChange events are finalized), we remove the root from the map. + finalizedRoots *orderedmap.OrderedMap[string, ccip.CommitStoreReportWithTxMeta] + // snoozedRoots used only for temporary snoozing roots. It's a cache with TTL (usually around 5 minutes, but this configuration is set up on chain using rootSnoozeTime) + snoozedRoots *cache.Cache + // executedRoots is a cache with TTL (usually around 8 hours, but this configuration is set up on chain using messageVisibilityInterval). + // We keep executed roots there to make sure we don't accidentally try to reprocess already executed CommitReport + executedRoots *cache.Cache + // latestFinalizedCommitRootTs is the timestamp of the latest finalized commit root (youngest in terms of timestamp). + // It's used get only the logs that were considered as unfinalized in a previous run. + // This way we limit database scans to the minimum and keep polling "unfinalized" part of the ReportAccepted events queue. + latestFinalizedCommitRootTs time.Time +} + +func (r *commitRootsCache) RootsEligibleForExecution(ctx context.Context) ([]ccip.CommitStoreReport, error) { + // 1. Fetch all the logs from the database after the latest finalized commit root timestamp. + // If this is a first run, it will fetch all the logs based on the messageVisibilityInterval. + // Worst case scenario, it will fetch around 480 reports (OCR Commit 60 seconds (fast chains default) * messageVisibilityInterval set to 8 hours (mainnet default)) + // Even with the larger messageVisibilityInterval window (e.g. 24 hours) it should be acceptable (around 1500 logs). + // Keep in mind that this potentially heavy operation happens only once during the plugin boot and it's no different from the previous implementation. + logs, err := r.fetchLogsFromCommitStore(ctx) + if err != nil { + return nil, err + } + + // 2. Iterate over the logs and check if the root is finalized or not. Return finalized and unfinalized reports + // It promotes finalized roots to the finalizedRoots map and evicts stale roots. + finalizedReports, unfinalizedReports := r.updateFinalizedRoots(logs) + + // 3. Join finalized commit reports with unfinalized reports and outfilter snoozed roots. + // Return only the reports that are not snoozed. + return r.pickReadyToExecute(finalizedReports, unfinalizedReports), nil +} + +// MarkAsExecuted marks the root as executed. It means that all the messages from the root were executed and the ExecutionStateChange event was finalized. +// Executed roots are removed from the cache. +func (r *commitRootsCache) MarkAsExecuted(merkleRoot [32]byte) { + prettyMerkleRoot := merkleRootToString(merkleRoot) + r.lggr.Infow("Marking root as executed and removing entirely from cache", "merkleRoot", prettyMerkleRoot) + + r.cacheMu.Lock() + defer r.cacheMu.Unlock() + r.finalizedRoots.Delete(prettyMerkleRoot) + r.executedRoots.SetDefault(prettyMerkleRoot, struct{}{}) +} + +// Snooze temporarily snoozes the root. It means that the root is not eligible for execution for a certain period of time. +// Snoozed roots are skipped when calling RootsEligibleForExecution +func (r *commitRootsCache) Snooze(merkleRoot [32]byte) { + prettyMerkleRoot := merkleRootToString(merkleRoot) + r.lggr.Infow("Snoozing root temporarily", "merkleRoot", prettyMerkleRoot, "rootSnoozeTime", r.rootSnoozeTime) + r.snoozedRoots.SetDefault(prettyMerkleRoot, struct{}{}) +} + +func (r *commitRootsCache) isSnoozed(merkleRoot [32]byte) bool { + _, snoozed := r.snoozedRoots.Get(merkleRootToString(merkleRoot)) + return snoozed +} + +func (r *commitRootsCache) isExecuted(merkleRoot [32]byte) bool { + _, executed := r.executedRoots.Get(merkleRootToString(merkleRoot)) + return executed +} + +func (r *commitRootsCache) fetchLogsFromCommitStore(ctx context.Context) ([]ccip.CommitStoreReportWithTxMeta, error) { + r.cacheMu.Lock() + messageVisibilityWindow := time.Now().Add(-r.messageVisibilityInterval) + if r.latestFinalizedCommitRootTs.Before(messageVisibilityWindow) { + r.latestFinalizedCommitRootTs = messageVisibilityWindow + } + commitRootsFilterTimestamp := r.latestFinalizedCommitRootTs + r.cacheMu.Unlock() + + // IO operation, release lock before! + r.lggr.Infow("Fetching Commit Reports with timestamp greater than or equal to", "blockTimestamp", commitRootsFilterTimestamp) + return r.reader.GetAcceptedCommitReportsGteTimestamp(ctx, commitRootsFilterTimestamp, 0) +} + +func (r *commitRootsCache) updateFinalizedRoots(logs []ccip.CommitStoreReportWithTxMeta) ([]ccip.CommitStoreReportWithTxMeta, []ccip.CommitStoreReportWithTxMeta) { + r.cacheMu.Lock() + defer r.cacheMu.Unlock() + + // Assuming logs are properly ordered by block_timestamp, log_index + var unfinalizedReports []ccip.CommitStoreReportWithTxMeta + for _, log := range logs { + prettyMerkleRoot := merkleRootToString(log.MerkleRoot) + // Defensive check, if something is marked as executed, never allow it to come back to the cache + if r.isExecuted(log.MerkleRoot) { + r.lggr.Debugw("Ignoring root marked as executed", "merkleRoot", prettyMerkleRoot, "blockTimestamp", log.BlockTimestampUnixMilli) + continue + } + + if log.IsFinalized() { + r.lggr.Debugw("Adding finalized root to cache", "merkleRoot", prettyMerkleRoot, "blockTimestamp", log.BlockTimestampUnixMilli) + r.finalizedRoots.Store(prettyMerkleRoot, log) + } else { + r.lggr.Debugw("Bypassing unfinalized root", "merkleRoot", prettyMerkleRoot, "blockTimestamp", log.BlockTimestampUnixMilli) + unfinalizedReports = append(unfinalizedReports, log) + } + } + + if newest := r.finalizedRoots.Newest(); newest != nil { + r.latestFinalizedCommitRootTs = time.UnixMilli(newest.Value.BlockTimestampUnixMilli) + } + + var finalizedRoots []ccip.CommitStoreReportWithTxMeta + var rootsToDelete []string + + messageVisibilityWindow := time.Now().Add(-r.messageVisibilityInterval) + for pair := r.finalizedRoots.Oldest(); pair != nil; pair = pair.Next() { + // Mark items as stale if they are older than the messageVisibilityInterval + // SortedMap doesn't allow to iterate and delete, so we mark roots for deletion and remove them in a separate loop + if time.UnixMilli(pair.Value.BlockTimestampUnixMilli).Before(messageVisibilityWindow) { + rootsToDelete = append(rootsToDelete, pair.Key) + continue + } + finalizedRoots = append(finalizedRoots, pair.Value) + } + + // Remove stale items + for _, root := range rootsToDelete { + r.finalizedRoots.Delete(root) + } + + return finalizedRoots, unfinalizedReports +} + +func (r *commitRootsCache) pickReadyToExecute(r1 []ccip.CommitStoreReportWithTxMeta, r2 []ccip.CommitStoreReportWithTxMeta) []ccip.CommitStoreReport { + allReports := append(r1, r2...) + eligibleReports := make([]ccip.CommitStoreReport, 0, len(allReports)) + for _, report := range allReports { + if r.isSnoozed(report.MerkleRoot) { + r.lggr.Debugw("Skipping snoozed root", + "minSeqNr", report.Interval.Min, + "maxSeqNr", report.Interval.Max, + "merkleRoot", merkleRootToString(report.MerkleRoot)) + continue + } + eligibleReports = append(eligibleReports, report.CommitStoreReport) + } + // safety check, probably not needed + slices.SortFunc(eligibleReports, func(i, j ccip.CommitStoreReport) int { + return int(i.Interval.Min - j.Interval.Min) + }) + return eligibleReports +} + +// internal use only for testing +func (r *commitRootsCache) finalizedCachedLogs() []ccip.CommitStoreReport { + r.cacheMu.RLock() + defer r.cacheMu.RUnlock() + + var finalizedRoots []ccip.CommitStoreReport + for pair := r.finalizedRoots.Oldest(); pair != nil; pair = pair.Next() { + finalizedRoots = append(finalizedRoots, pair.Value.CommitStoreReport) + } + return finalizedRoots +} + +func merkleRootToString(merkleRoot ccip.Hash) string { + return merkleRoot.String() +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/commit_roots_test.go b/core/services/ocr2/plugins/ccip/internal/cache/commit_roots_test.go new file mode 100644 index 0000000000..dc0a844349 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/commit_roots_test.go @@ -0,0 +1,297 @@ +package cache_test + +import ( + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" +) + +func Test_RootsEligibleForExecution(t *testing.T) { + ctx := testutils.Context(t) + chainID := testutils.NewRandomEVMChainID() + orm := logpoller.NewORM(chainID, pgtest.NewSqlxDB(t), logger.TestLogger(t)) + lpOpts := logpoller.Opts{ + PollPeriod: time.Hour, + FinalityDepth: 2, + BackfillBatchSize: 20, + RpcBatchSize: 10, + KeepFinalizedBlocksDepth: 1000, + } + lp := logpoller.NewLogPoller(orm, nil, logger.TestLogger(t), nil, lpOpts) + + commitStoreAddr := utils.RandomAddress() + + block2 := time.Now().Add(-8 * time.Hour) + block3 := time.Now().Add(-5 * time.Hour) + block4 := time.Now().Add(-1 * time.Hour) + newBlock4 := time.Now().Add(-2 * time.Hour) + block5 := time.Now() + + root1 := utils.RandomBytes32() + root2 := utils.RandomBytes32() + root3 := utils.RandomBytes32() + root4 := utils.RandomBytes32() + root5 := utils.RandomBytes32() + + inputLogs := []logpoller.Log{ + createReportAcceptedLog(t, chainID, commitStoreAddr, 2, 1, root1, block2), + createReportAcceptedLog(t, chainID, commitStoreAddr, 2, 2, root2, block2), + } + require.NoError(t, orm.InsertLogsWithBlock(ctx, inputLogs, logpoller.NewLogPollerBlock(utils.RandomBytes32(), 2, time.Now(), 1))) + + commitStore, err := v1_2_0.NewCommitStore(logger.TestLogger(t), commitStoreAddr, nil, lp) + require.NoError(t, err) + + rootsCache := cache.NewCommitRootsCache(logger.TestLogger(t), commitStore, 10*time.Hour, time.Second) + + roots, err := rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots, root1, root2) + + rootsCache.Snooze(root1) + rootsCache.Snooze(root2) + + // Roots are snoozed + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots) + + // Roots are unsnoozed + require.Eventually(t, func() bool { + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + return len(roots) == 2 + }, 5*time.Second, 1*time.Second) + + // Marking root as executed doesn't ignore other roots from the same block + rootsCache.MarkAsExecuted(root1) + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots, root2) + + // Finality progress, mark all roots as finalized + require.NoError(t, orm.InsertBlock(ctx, utils.RandomBytes32(), 3, time.Now(), 3)) + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots, root2) + + inputLogs = []logpoller.Log{ + createReportAcceptedLog(t, chainID, commitStoreAddr, 3, 1, root3, block3), + createReportAcceptedLog(t, chainID, commitStoreAddr, 4, 1, root4, block4), + createReportAcceptedLog(t, chainID, commitStoreAddr, 5, 1, root5, block5), + } + require.NoError(t, orm.InsertLogsWithBlock(ctx, inputLogs, logpoller.NewLogPollerBlock(utils.RandomBytes32(), 5, time.Now(), 3))) + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots, root2, root3, root4, root5) + + // Mark root in the middle as executed but keep the oldest one still waiting + rootsCache.MarkAsExecuted(root3) + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots, root2, root4, root5) + + // Simulate reorg by removing all unfinalized blocks + require.NoError(t, orm.DeleteLogsAndBlocksAfter(ctx, 4)) + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots, root2) + + // Root4 comes back but with the different block_timestamp (before the reorged block) + inputLogs = []logpoller.Log{ + createReportAcceptedLog(t, chainID, commitStoreAddr, 4, 1, root4, newBlock4), + } + require.NoError(t, orm.InsertLogsWithBlock(ctx, inputLogs, logpoller.NewLogPollerBlock(utils.RandomBytes32(), 5, time.Now(), 3))) + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots, root2, root4) + + // Mark everything as executed + rootsCache.MarkAsExecuted(root2) + rootsCache.MarkAsExecuted(root4) + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots) +} + +func Test_RootsEligibleForExecutionWithReorgs(t *testing.T) { + ctx := testutils.Context(t) + chainID := testutils.NewRandomEVMChainID() + orm := logpoller.NewORM(chainID, pgtest.NewSqlxDB(t), logger.TestLogger(t)) + lpOpts := logpoller.Opts{ + PollPeriod: time.Hour, + FinalityDepth: 2, + BackfillBatchSize: 20, + RpcBatchSize: 10, + KeepFinalizedBlocksDepth: 1000, + } + lp := logpoller.NewLogPoller(orm, nil, logger.TestLogger(t), nil, lpOpts) + + commitStoreAddr := utils.RandomAddress() + + block1 := time.Now().Add(-8 * time.Hour) + block2 := time.Now().Add(-5 * time.Hour) + block3 := time.Now().Add(-2 * time.Hour) + block4 := time.Now().Add(-1 * time.Hour) + + root1 := utils.RandomBytes32() + root2 := utils.RandomBytes32() + root3 := utils.RandomBytes32() + + // Genesis block + require.NoError(t, orm.InsertBlock(ctx, utils.RandomBytes32(), 1, block1, 1)) + inputLogs := []logpoller.Log{ + createReportAcceptedLog(t, chainID, commitStoreAddr, 2, 1, root1, block2), + createReportAcceptedLog(t, chainID, commitStoreAddr, 2, 2, root2, block2), + createReportAcceptedLog(t, chainID, commitStoreAddr, 3, 1, root3, block3), + } + require.NoError(t, orm.InsertLogsWithBlock(ctx, inputLogs, logpoller.NewLogPollerBlock(utils.RandomBytes32(), 3, time.Now(), 1))) + + commitStore, err := v1_2_0.NewCommitStore(logger.TestLogger(t), commitStoreAddr, nil, lp) + require.NoError(t, err) + + rootsCache := cache.NewCommitRootsCache(logger.TestLogger(t), commitStore, 10*time.Hour, time.Second) + + // Get all including finalized and unfinalized + roots, err := rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots, root1, root2, root3) + + // Reorg everything away + require.NoError(t, orm.DeleteLogsAndBlocksAfter(ctx, 2)) + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots) + + // Reinsert the logs, mark first one as finalized + inputLogs = []logpoller.Log{ + createReportAcceptedLog(t, chainID, commitStoreAddr, 3, 1, root1, block3), + createReportAcceptedLog(t, chainID, commitStoreAddr, 4, 1, root2, block4), + createReportAcceptedLog(t, chainID, commitStoreAddr, 4, 2, root3, block4), + } + require.NoError(t, orm.InsertLogsWithBlock(ctx, inputLogs, logpoller.NewLogPollerBlock(utils.RandomBytes32(), 5, time.Now(), 3))) + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots, root1, root2, root3) + + // Reorg away everything except the finalized one + require.NoError(t, orm.DeleteLogsAndBlocksAfter(ctx, 4)) + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots, root1) +} + +// Not very likely, but let's be more defensive here and verify if cache works properly and can deal with duplicates +func Test_BlocksWithTheSameTimestamps(t *testing.T) { + ctx := testutils.Context(t) + chainID := testutils.NewRandomEVMChainID() + orm := logpoller.NewORM(chainID, pgtest.NewSqlxDB(t), logger.TestLogger(t)) + lpOpts := logpoller.Opts{ + PollPeriod: time.Hour, + FinalityDepth: 2, + BackfillBatchSize: 20, + RpcBatchSize: 10, + KeepFinalizedBlocksDepth: 1000, + } + lp := logpoller.NewLogPoller(orm, nil, logger.TestLogger(t), nil, lpOpts) + + commitStoreAddr := utils.RandomAddress() + + block := time.Now().Add(-1 * time.Hour).Truncate(time.Second) + root1 := utils.RandomBytes32() + root2 := utils.RandomBytes32() + + inputLogs := []logpoller.Log{ + createReportAcceptedLog(t, chainID, commitStoreAddr, 2, 1, root1, block), + } + require.NoError(t, orm.InsertLogsWithBlock(ctx, inputLogs, logpoller.NewLogPollerBlock(utils.RandomBytes32(), 2, time.Now(), 2))) + + commitStore, err := v1_2_0.NewCommitStore(logger.TestLogger(t), commitStoreAddr, nil, lp) + require.NoError(t, err) + + rootsCache := cache.NewCommitRootsCache(logger.TestLogger(t), commitStore, 10*time.Hour, time.Second) + roots, err := rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots, root1) + + inputLogs = []logpoller.Log{ + createReportAcceptedLog(t, chainID, commitStoreAddr, 3, 1, root2, block), + } + require.NoError(t, orm.InsertLogsWithBlock(ctx, inputLogs, logpoller.NewLogPollerBlock(utils.RandomBytes32(), 3, time.Now(), 3))) + + roots, err = rootsCache.RootsEligibleForExecution(ctx) + require.NoError(t, err) + assertRoots(t, roots, root1, root2) +} + +func assertRoots(t *testing.T, roots []cciptypes.CommitStoreReport, root ...[32]byte) { + require.Len(t, roots, len(root)) + for i, r := range root { + require.Equal(t, r, roots[i].MerkleRoot) + } +} + +func createReportAcceptedLog(t testing.TB, chainID *big.Int, address common.Address, blockNumber int64, logIndex int64, merkleRoot common.Hash, blockTimestamp time.Time) logpoller.Log { + tAbi, err := commit_store_1_2_0.CommitStoreMetaData.GetAbi() + require.NoError(t, err) + eseEvent, ok := tAbi.Events["ReportAccepted"] + require.True(t, ok) + + gasPriceUpdates := make([]commit_store_1_2_0.InternalGasPriceUpdate, 100) + tokenPriceUpdates := make([]commit_store_1_2_0.InternalTokenPriceUpdate, 100) + + for i := 0; i < 100; i++ { + gasPriceUpdates[i] = commit_store_1_2_0.InternalGasPriceUpdate{ + DestChainSelector: uint64(i), + UsdPerUnitGas: big.NewInt(int64(i)), + } + tokenPriceUpdates[i] = commit_store_1_2_0.InternalTokenPriceUpdate{ + SourceToken: utils.RandomAddress(), + UsdPerToken: big.NewInt(int64(i)), + } + } + + message := commit_store_1_2_0.CommitStoreCommitReport{ + PriceUpdates: commit_store_1_2_0.InternalPriceUpdates{ + TokenPriceUpdates: tokenPriceUpdates, + GasPriceUpdates: gasPriceUpdates, + }, + Interval: commit_store_1_2_0.CommitStoreInterval{Min: 1, Max: 10}, + MerkleRoot: merkleRoot, + } + + logData, err := eseEvent.Inputs.Pack(message) + require.NoError(t, err) + + topic0 := commit_store_1_2_0.CommitStoreReportAccepted{}.Topic() + + return logpoller.Log{ + Topics: [][]byte{ + topic0[:], + }, + Data: logData, + LogIndex: logIndex, + BlockHash: utils.RandomBytes32(), + BlockNumber: blockNumber, + BlockTimestamp: blockTimestamp.Truncate(time.Millisecond), + EventSig: topic0, + Address: address, + TxHash: utils.RandomBytes32(), + EvmChainId: ubig.New(chainID), + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/commit_roots_unit_test.go b/core/services/ocr2/plugins/ccip/internal/cache/commit_roots_unit_test.go new file mode 100644 index 0000000000..34a470ef90 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/commit_roots_unit_test.go @@ -0,0 +1,212 @@ +package cache + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" +) + +func Test_CacheIsInitializedWithFirstCall(t *testing.T) { + commitStoreReader := mocks.NewCommitStoreReader(t) + cache := newCommitRootsCache(logger.TestLogger(t), commitStoreReader, time.Hour, time.Hour, time.Hour, time.Hour) + commitStoreReader.On("GetAcceptedCommitReportsGteTimestamp", mock.Anything, mock.Anything, mock.Anything).Return([]ccip.CommitStoreReportWithTxMeta{}, nil) + + roots, err := cache.RootsEligibleForExecution(tests.Context(t)) + require.NoError(t, err) + assertRoots(t, roots) +} + +func Test_CacheExpiration(t *testing.T) { + ts1 := time.Now().Add(-5 * time.Millisecond).Truncate(time.Millisecond) + ts2 := time.Now().Add(-3 * time.Millisecond).Truncate(time.Millisecond) + ts3 := time.Now().Add(-1 * time.Millisecond).Truncate(time.Millisecond) + + root1 := utils.RandomBytes32() + root2 := utils.RandomBytes32() + root3 := utils.RandomBytes32() + + commitStoreReader := mocks.NewCommitStoreReader(t) + cache := newCommitRootsCache(logger.TestLogger(t), commitStoreReader, time.Second, time.Hour, time.Hour, time.Hour) + mockCommitStoreReader(commitStoreReader, time.Time{}, []ccip.CommitStoreReportWithTxMeta{ + createCommitStoreEntry(root1, ts1, true), + createCommitStoreEntry(root2, ts2, true), + createCommitStoreEntry(root3, ts3, false), + }) + roots, err := cache.RootsEligibleForExecution(tests.Context(t)) + require.NoError(t, err) + assertRoots(t, roots, root1, root2, root3) + + require.Eventually(t, func() bool { + mockCommitStoreReader(commitStoreReader, time.Time{}, []ccip.CommitStoreReportWithTxMeta{ + createCommitStoreEntry(root3, ts3, false), + }) + roots, err = cache.RootsEligibleForExecution(tests.Context(t)) + require.NoError(t, err) + return len(roots) == 1 && roots[0].MerkleRoot == root3 + }, 5*time.Second, 1*time.Second) +} + +func Test_CacheFullEviction(t *testing.T) { + commitStoreReader := mocks.NewCommitStoreReader(t) + cache := newCommitRootsCache(logger.TestLogger(t), commitStoreReader, 2*time.Second, 1*time.Second, time.Second, time.Second) + + maxElements := 10000 + commitRoots := make([]ccip.CommitStoreReportWithTxMeta, maxElements) + for i := 0; i < maxElements; i++ { + finalized := i >= maxElements/2 + commitRoots[i] = createCommitStoreEntry(utils.RandomBytes32(), time.Now(), finalized) + } + mockCommitStoreReader(commitStoreReader, time.Time{}, commitRoots) + + roots, err := cache.RootsEligibleForExecution(tests.Context(t)) + require.NoError(t, err) + require.Len(t, roots, maxElements) + + // Marks some of them as exeucted and some of them as snoozed + for i := 0; i < maxElements; i++ { + if i%3 == 0 { + cache.MarkAsExecuted(commitRoots[i].MerkleRoot) + } + if i%3 == 1 { + cache.Snooze(commitRoots[i].MerkleRoot) + } + } + // Eventually everything should be entirely removed from cache. We need that check to verify if cache doesn't grow indefinitely + require.Eventually(t, func() bool { + mockCommitStoreReader(commitStoreReader, time.Time{}, []ccip.CommitStoreReportWithTxMeta{}) + roots1, err1 := cache.RootsEligibleForExecution(tests.Context(t)) + require.NoError(t, err1) + + return len(roots1) == 0 && + cache.finalizedRoots.Len() == 0 && + len(cache.snoozedRoots.Items()) == 0 && + len(cache.executedRoots.Items()) == 0 + }, 10*time.Second, time.Second) +} + +func Test_CacheProgression_Internal(t *testing.T) { + ts1 := time.Now().Add(-5 * time.Hour).Truncate(time.Millisecond) + ts2 := time.Now().Add(-3 * time.Hour).Truncate(time.Millisecond) + ts3 := time.Now().Add(-1 * time.Hour).Truncate(time.Millisecond) + + root1 := utils.RandomBytes32() + root2 := utils.RandomBytes32() + root3 := utils.RandomBytes32() + + commitStoreReader := mocks.NewCommitStoreReader(t) + + cache := newCommitRootsCache(logger.TestLogger(t), commitStoreReader, 10*time.Hour, time.Hour, time.Hour, time.Hour) + + // Empty cache, no results from the reader + mockCommitStoreReader(commitStoreReader, time.Time{}, []ccip.CommitStoreReportWithTxMeta{}) + roots, err := cache.RootsEligibleForExecution(tests.Context(t)) + require.NoError(t, err) + assertRoots(t, roots) + assertRoots(t, cache.finalizedCachedLogs()) + + // Single unfinalized root returned + mockCommitStoreReader(commitStoreReader, time.Time{}, []ccip.CommitStoreReportWithTxMeta{createCommitStoreEntry(root1, ts1, false)}) + roots, err = cache.RootsEligibleForExecution(tests.Context(t)) + require.NoError(t, err) + assertRoots(t, roots, root1) + assertRoots(t, cache.finalizedCachedLogs()) + + // Finalized and unfinalized roots returned + mockCommitStoreReader(commitStoreReader, time.Time{}, []ccip.CommitStoreReportWithTxMeta{ + createCommitStoreEntry(root1, ts1, true), + createCommitStoreEntry(root2, ts2, false), + }) + roots, err = cache.RootsEligibleForExecution(tests.Context(t)) + require.NoError(t, err) + assertRoots(t, roots, root1, root2) + assertRoots(t, cache.finalizedCachedLogs(), root1) + + // Returning the same data should not impact cache state (no duplicates) + mockCommitStoreReader(commitStoreReader, ts1, []ccip.CommitStoreReportWithTxMeta{ + createCommitStoreEntry(root1, ts1, true), + createCommitStoreEntry(root2, ts2, false), + }) + roots, err = cache.RootsEligibleForExecution(tests.Context(t)) + require.NoError(t, err) + assertRoots(t, roots, root1, root2) + assertRoots(t, cache.finalizedCachedLogs(), root1) + + // Snoozing oldest root + cache.Snooze(root1) + mockCommitStoreReader(commitStoreReader, ts1, []ccip.CommitStoreReportWithTxMeta{ + createCommitStoreEntry(root2, ts2, false), + createCommitStoreEntry(root3, ts3, false), + }) + roots, err = cache.RootsEligibleForExecution(tests.Context(t)) + require.NoError(t, err) + assertRoots(t, roots, root2, root3) + assertRoots(t, cache.finalizedCachedLogs(), root1) + + // Snoozing everything + cache.Snooze(root2) + cache.Snooze(root3) + mockCommitStoreReader(commitStoreReader, ts1, []ccip.CommitStoreReportWithTxMeta{ + createCommitStoreEntry(root2, ts2, true), + createCommitStoreEntry(root3, ts3, true), + }) + roots, err = cache.RootsEligibleForExecution(tests.Context(t)) + require.NoError(t, err) + assertRoots(t, roots) + assertRoots(t, cache.finalizedCachedLogs(), root1, root2, root3) + + // Marking everything as executed removes it entirely, even if root is returned from the CommitStore + cache.MarkAsExecuted(root1) + cache.MarkAsExecuted(root2) + cache.MarkAsExecuted(root3) + mockCommitStoreReader(commitStoreReader, ts3, []ccip.CommitStoreReportWithTxMeta{ + createCommitStoreEntry(root2, ts2, true), + createCommitStoreEntry(root3, ts3, true), + }) + roots, err = cache.RootsEligibleForExecution(tests.Context(t)) + require.NoError(t, err) + assertRoots(t, roots) + assertRoots(t, cache.finalizedCachedLogs()) +} + +func assertRoots(t *testing.T, reports []ccip.CommitStoreReport, expectedRoots ...[32]byte) { + require.Len(t, reports, len(expectedRoots)) + for i, report := range reports { + assert.Equal(t, expectedRoots[i], report.MerkleRoot) + } +} + +func mockCommitStoreReader(reader *mocks.CommitStoreReader, blockTimestamp time.Time, roots []ccip.CommitStoreReportWithTxMeta) { + if blockTimestamp.IsZero() { + reader.On("GetAcceptedCommitReportsGteTimestamp", mock.Anything, mock.Anything, mock.Anything). + Return(roots, nil).Once() + } else { + reader.On("GetAcceptedCommitReportsGteTimestamp", mock.Anything, blockTimestamp, mock.Anything). + Return(roots, nil).Once() + } +} + +func createCommitStoreEntry(root [32]byte, ts time.Time, finalized bool) ccip.CommitStoreReportWithTxMeta { + status := ccip.FinalizedStatusNotFinalized + if finalized { + status = ccip.FinalizedStatusFinalized + } + return ccip.CommitStoreReportWithTxMeta{ + CommitStoreReport: ccip.CommitStoreReport{ + MerkleRoot: root, + }, + TxMeta: ccip.TxMeta{ + BlockTimestampUnixMilli: ts.UnixMilli(), + Finalized: status, + }, + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/lazy.go b/core/services/ocr2/plugins/ccip/internal/cache/lazy.go new file mode 100644 index 0000000000..7b15abe271 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/lazy.go @@ -0,0 +1,20 @@ +package cache + +import "sync" + +type LazyFunction[T any] func() (T, error) + +// LazyFetch caches the results during the first call and then returns the cached value +// on each consecutive call. +func LazyFetch[T any](fun LazyFunction[T]) LazyFunction[T] { + var result T + var err error + var once sync.Once + + return func() (T, error) { + once.Do(func() { + result, err = fun() + }) + return result, err + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/lazy_test.go b/core/services/ocr2/plugins/ccip/internal/cache/lazy_test.go new file mode 100644 index 0000000000..2777a6c2e0 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/lazy_test.go @@ -0,0 +1,71 @@ +package cache + +import ( + "fmt" + "sync" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestLazyFetchPass(t *testing.T) { + counterFunction := createPassingCounter() + + counter, _ := counterFunction() + require.Equal(t, 1, counter) + + lazyCounter := LazyFetch(counterFunction) + counter, _ = lazyCounter() + require.Equal(t, 2, counter) + + counter, _ = lazyCounter() + require.Equal(t, 2, counter) +} + +func TestLazyFetchFail(t *testing.T) { + counterFunction := createFailingCounter() + + _, err := counterFunction() + require.Equal(t, "counter 1 failed", err.Error()) + + lazyCounter := LazyFetch(counterFunction) + _, err = lazyCounter() + require.Equal(t, "counter 2 failed", err.Error()) + + _, err = lazyCounter() + require.Equal(t, "counter 2 failed", err.Error()) +} + +func TestLazyFetchMultipleRoutines(t *testing.T) { + routines := 100 + counterFunction := LazyFetch(createPassingCounter()) + + var wg sync.WaitGroup + wg.Add(routines) + + for i := 0; i < routines; i++ { + go func() { + counter, _ := counterFunction() + require.Equal(t, 1, counter) + wg.Done() + }() + } + + wg.Wait() +} + +func createFailingCounter() func() (int, error) { + counter := 0 + return func() (int, error) { + counter++ + return 0, fmt.Errorf("counter %d failed", counter) + } +} + +func createPassingCounter() func() (int, error) { + counter := 0 + return func() (int, error) { + counter++ + return counter, nil + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/mocks/chain_health_mock.go b/core/services/ocr2/plugins/ccip/internal/cache/mocks/chain_health_mock.go new file mode 100644 index 0000000000..595b15774a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/mocks/chain_health_mock.go @@ -0,0 +1,183 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" +) + +// ChainHealthcheck is an autogenerated mock type for the ChainHealthcheck type +type ChainHealthcheck struct { + mock.Mock +} + +type ChainHealthcheck_Expecter struct { + mock *mock.Mock +} + +func (_m *ChainHealthcheck) EXPECT() *ChainHealthcheck_Expecter { + return &ChainHealthcheck_Expecter{mock: &_m.Mock} +} + +// Close provides a mock function with given fields: +func (_m *ChainHealthcheck) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ChainHealthcheck_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type ChainHealthcheck_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *ChainHealthcheck_Expecter) Close() *ChainHealthcheck_Close_Call { + return &ChainHealthcheck_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *ChainHealthcheck_Close_Call) Run(run func()) *ChainHealthcheck_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ChainHealthcheck_Close_Call) Return(_a0 error) *ChainHealthcheck_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ChainHealthcheck_Close_Call) RunAndReturn(run func() error) *ChainHealthcheck_Close_Call { + _c.Call.Return(run) + return _c +} + +// IsHealthy provides a mock function with given fields: ctx +func (_m *ChainHealthcheck) IsHealthy(ctx context.Context) (bool, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for IsHealthy") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (bool, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) bool); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ChainHealthcheck_IsHealthy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsHealthy' +type ChainHealthcheck_IsHealthy_Call struct { + *mock.Call +} + +// IsHealthy is a helper method to define mock.On call +// - ctx context.Context +func (_e *ChainHealthcheck_Expecter) IsHealthy(ctx interface{}) *ChainHealthcheck_IsHealthy_Call { + return &ChainHealthcheck_IsHealthy_Call{Call: _e.mock.On("IsHealthy", ctx)} +} + +func (_c *ChainHealthcheck_IsHealthy_Call) Run(run func(ctx context.Context)) *ChainHealthcheck_IsHealthy_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *ChainHealthcheck_IsHealthy_Call) Return(_a0 bool, _a1 error) *ChainHealthcheck_IsHealthy_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ChainHealthcheck_IsHealthy_Call) RunAndReturn(run func(context.Context) (bool, error)) *ChainHealthcheck_IsHealthy_Call { + _c.Call.Return(run) + return _c +} + +// Start provides a mock function with given fields: _a0 +func (_m *ChainHealthcheck) Start(_a0 context.Context) error { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for Start") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ChainHealthcheck_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start' +type ChainHealthcheck_Start_Call struct { + *mock.Call +} + +// Start is a helper method to define mock.On call +// - _a0 context.Context +func (_e *ChainHealthcheck_Expecter) Start(_a0 interface{}) *ChainHealthcheck_Start_Call { + return &ChainHealthcheck_Start_Call{Call: _e.mock.On("Start", _a0)} +} + +func (_c *ChainHealthcheck_Start_Call) Run(run func(_a0 context.Context)) *ChainHealthcheck_Start_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *ChainHealthcheck_Start_Call) Return(_a0 error) *ChainHealthcheck_Start_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ChainHealthcheck_Start_Call) RunAndReturn(run func(context.Context) error) *ChainHealthcheck_Start_Call { + _c.Call.Return(run) + return _c +} + +// NewChainHealthcheck creates a new instance of ChainHealthcheck. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewChainHealthcheck(t interface { + mock.TestingT + Cleanup(func()) +}) *ChainHealthcheck { + mock := &ChainHealthcheck{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/observed_chain_health.go b/core/services/ocr2/plugins/ccip/internal/cache/observed_chain_health.go new file mode 100644 index 0000000000..941162448a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/observed_chain_health.go @@ -0,0 +1,70 @@ +package cache + +import ( + "context" + "strconv" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" +) + +var ( + laneHealthStatus = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "ccip_lane_healthcheck_status", + Help: "Keep track of the chain healthcheck calls for each lane and plugin", + }, []string{"plugin", "source", "dest", "onramp"}) +) + +type ObservedChainHealthcheck struct { + ChainHealthcheck + + sourceChain string + destChain string + plugin string + // onrampAddress is used to distinguish between 1.0/2.0 lanes or blue/green lanes during deployment + // This changes very rarely, so it's not a performance concern for Prometheus + onrampAddress string + laneHealthStatus *prometheus.GaugeVec +} + +func NewObservedChainHealthCheck( + chainHealthcheck ChainHealthcheck, + plugin string, + sourceChain int64, + destChain int64, + onrampAddress cciptypes.Address, +) *ObservedChainHealthcheck { + return &ObservedChainHealthcheck{ + ChainHealthcheck: chainHealthcheck, + sourceChain: strconv.FormatInt(sourceChain, 10), + destChain: strconv.FormatInt(destChain, 10), + plugin: plugin, + laneHealthStatus: laneHealthStatus, + onrampAddress: string(onrampAddress), + } +} + +func (o *ObservedChainHealthcheck) IsHealthy(ctx context.Context) (bool, error) { + healthy, err := o.ChainHealthcheck.IsHealthy(ctx) + o.trackState(healthy, err) + return healthy, err +} + +func (o *ObservedChainHealthcheck) trackState(healthy bool, err error) { + if err != nil { + // Don't report errors as unhealthy, as they are not necessarily indicative of the chain's health + // Could be RPC issues, etc. + return + } + + status := 0 + if healthy { + status = 1 + } + + o.laneHealthStatus. + WithLabelValues(o.plugin, o.sourceChain, o.destChain, o.onrampAddress). + Set(float64(status)) +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/observed_chain_health_test.go b/core/services/ocr2/plugins/ccip/internal/cache/observed_chain_health_test.go new file mode 100644 index 0000000000..19583a37c7 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/observed_chain_health_test.go @@ -0,0 +1,62 @@ +package cache + +import ( + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache/mocks" +) + +var address = cciptypes.Address(common.HexToAddress("0x1234567890123456789012345678901234567890").String()) + +func Test_ObservedChainStateSkipErrors(t *testing.T) { + mockedHealthcheck := mocks.NewChainHealthcheck(t) + mockedHealthcheck.On("IsHealthy", mock.Anything).Return(false, fmt.Errorf("error")) + + observedChainState := NewObservedChainHealthCheck( + mockedHealthcheck, + "plugin", + 10, + 20, + address, + ) + + _, err := observedChainState.IsHealthy(tests.Context(t)) + assert.Error(t, err) + assert.Equal(t, float64(0), testutil.ToFloat64(laneHealthStatus.WithLabelValues("plugin", "10", "20", "0x1234567890123456789012345678901234567890"))) +} + +func Test_ObservedChainStateReportsStatus(t *testing.T) { + mockedHealthcheck := mocks.NewChainHealthcheck(t) + mockedHealthcheck.On("IsHealthy", mock.Anything).Return(true, nil).Once() + + observedChainState := NewObservedChainHealthCheck( + mockedHealthcheck, + "plugin", + 10, + 20, + address, + ) + + health, err := observedChainState.IsHealthy(tests.Context(t)) + require.NoError(t, err) + assert.True(t, health) + assert.Equal(t, float64(1), testutil.ToFloat64(laneHealthStatus.WithLabelValues("plugin", "10", "20", "0x1234567890123456789012345678901234567890"))) + + // Mark as unhealthy + mockedHealthcheck.On("IsHealthy", mock.Anything).Return(false, nil).Once() + + health, err = observedChainState.IsHealthy(tests.Context(t)) + require.NoError(t, err) + assert.False(t, health) + assert.Equal(t, float64(0), testutil.ToFloat64(laneHealthStatus.WithLabelValues("plugin", "10", "20", "0x1234567890123456789012345678901234567890"))) +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/once.go b/core/services/ocr2/plugins/ccip/internal/cache/once.go new file mode 100644 index 0000000000..713501a03e --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/once.go @@ -0,0 +1,38 @@ +package cache + +import ( + "context" + "sync" +) + +type OnceCtxFunction[T any] func(ctx context.Context) (T, error) + +// CallOnceOnNoError returns a new function that wraps the given function f with caching capabilities. +// If f returns an error, the result is not cached, allowing f to be retried on subsequent calls. +// Use case for that is to avoid caching an error forever in case of transient errors (e.g. flaky RPC) +func CallOnceOnNoError[T any](f OnceCtxFunction[T]) OnceCtxFunction[T] { + var ( + mu sync.Mutex + value T + err error + called bool + ) + + return func(ctx context.Context) (T, error) { + mu.Lock() + defer mu.Unlock() + + // If the function has been called successfully before, return the cached result. + if called && err == nil { + return value, nil + } + + // Call the function and cache the result only if there is no error. + value, err = f(ctx) + if err == nil { + called = true + } + + return value, err + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/once_test.go b/core/services/ocr2/plugins/ccip/internal/cache/once_test.go new file mode 100644 index 0000000000..6ba2fbddd5 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/once_test.go @@ -0,0 +1,83 @@ +package cache + +import ( + "context" + "errors" + "sync" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" +) + +// TestCallOnceOnNoErrorCachingSuccess tests caching behavior when the function succeeds. +func TestCallOnceOnNoErrorCachingSuccess(t *testing.T) { + callCount := 0 + testFunc := func(ctx context.Context) (string, error) { + callCount++ + return "test result", nil + } + + cachedFunc := CallOnceOnNoError(testFunc) + + // Call the function twice. + _, err := cachedFunc(tests.Context(t)) + assert.NoError(t, err, "Expected no error on the first call") + + _, err = cachedFunc(tests.Context(t)) + assert.NoError(t, err, "Expected no error on the second call") + + assert.Equal(t, 1, callCount, "Function should be called exactly once") +} + +// TestCallOnceOnNoErrorCachingError tests that the function is retried after an error. +func TestCallOnceOnNoErrorCachingError(t *testing.T) { + callCount := 0 + testFunc := func(ctx context.Context) (string, error) { + callCount++ + if callCount == 1 { + return "", errors.New("test error") + } + return "test result", nil + } + + cachedFunc := CallOnceOnNoError(testFunc) + + // First call should fail. + _, err := cachedFunc(tests.Context(t)) + require.Error(t, err, "Expected an error on the first call") + + // Second call should succeed. + r, err := cachedFunc(tests.Context(t)) + assert.NoError(t, err, "Expected no error on the second call") + assert.Equal(t, "test result", r) + assert.Equal(t, 2, callCount, "Function should be called exactly twice") +} + +// TestCallOnceOnNoErrorCachingConcurrency tests that the function works correctly under concurrent access. +func TestCallOnceOnNoErrorCachingConcurrency(t *testing.T) { + var wg sync.WaitGroup + callCount := 0 + testFunc := func(ctx context.Context) (string, error) { + callCount++ + return "test result", nil + } + + cachedFunc := CallOnceOnNoError(testFunc) + + // Simulate concurrent calls. + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + _, err := cachedFunc(tests.Context(t)) + assert.NoError(t, err, "Expected no error in concurrent execution") + }() + } + + wg.Wait() + + assert.Equal(t, 1, callCount, "Function should be called exactly once despite concurrent calls") +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipcalc/addr.go b/core/services/ocr2/plugins/ccip/internal/ccipcalc/addr.go new file mode 100644 index 0000000000..40cdab6df9 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipcalc/addr.go @@ -0,0 +1,44 @@ +package ccipcalc + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" +) + +func EvmAddrsToGeneric(evmAddrs ...common.Address) []cciptypes.Address { + res := make([]cciptypes.Address, 0, len(evmAddrs)) + for _, addr := range evmAddrs { + res = append(res, cciptypes.Address(addr.String())) + } + return res +} + +func EvmAddrToGeneric(evmAddr common.Address) cciptypes.Address { + return cciptypes.Address(evmAddr.String()) +} + +func GenericAddrsToEvm(genericAddrs ...cciptypes.Address) ([]common.Address, error) { + evmAddrs := make([]common.Address, 0, len(genericAddrs)) + for _, addr := range genericAddrs { + if !common.IsHexAddress(string(addr)) { + return nil, fmt.Errorf("%s not an evm address", addr) + } + evmAddrs = append(evmAddrs, common.HexToAddress(string(addr))) + } + return evmAddrs, nil +} + +func GenericAddrToEvm(genAddr cciptypes.Address) (common.Address, error) { + evmAddrs, err := GenericAddrsToEvm(genAddr) + if err != nil { + return common.Address{}, err + } + return evmAddrs[0], nil +} + +func HexToAddress(h string) cciptypes.Address { + return cciptypes.Address(common.HexToAddress(h).String()) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipcalc/calc.go b/core/services/ocr2/plugins/ccip/internal/ccipcalc/calc.go new file mode 100644 index 0000000000..8ba57e77ed --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipcalc/calc.go @@ -0,0 +1,69 @@ +package ccipcalc + +import ( + "math/big" + "sort" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +// ContiguousReqs checks if seqNrs contains all numbers from min to max. +func ContiguousReqs(lggr logger.Logger, min, max uint64, seqNrs []uint64) bool { + if int(max-min+1) != len(seqNrs) { + return false + } + + for i, j := min, 0; i <= max && j < len(seqNrs); i, j = i+1, j+1 { + if seqNrs[j] != i { + lggr.Errorw("unexpected gap in seq nums", "seqNr", i, "minSeqNr", min, "maxSeqNr", max) + return false + } + } + return true +} + +// CalculateUsdPerUnitGas returns: (sourceGasPrice * usdPerFeeCoin) / 1e18 +func CalculateUsdPerUnitGas(sourceGasPrice *big.Int, usdPerFeeCoin *big.Int) *big.Int { + // (wei / gas) * (usd / eth) * (1 eth / 1e18 wei) = usd/gas + tmp := new(big.Int).Mul(sourceGasPrice, usdPerFeeCoin) + return tmp.Div(tmp, big.NewInt(1e18)) +} + +// BigIntSortedMiddle returns the middle number after sorting the provided numbers. nil is returned if the provided slice is empty. +// If length of the provided slice is even, the right-hand-side value of the middle 2 numbers is returned. +// The objective of this function is to always pick within the range of values reported by honest nodes when we have 2f+1 values. +func BigIntSortedMiddle(vals []*big.Int) *big.Int { + if len(vals) == 0 { + return nil + } + + valsCopy := make([]*big.Int, len(vals)) + copy(valsCopy[:], vals[:]) + sort.Slice(valsCopy, func(i, j int) bool { + return valsCopy[i].Cmp(valsCopy[j]) == -1 + }) + return valsCopy[len(valsCopy)/2] +} + +// Deviates checks if x1 and x2 deviates based on the provided ppb (parts per billion) +// ppb is calculated based on the smaller value of the two +// e.g, if x1 > x2, deviation_parts_per_billion = ((x1 - x2) / x2) * 1e9 +func Deviates(x1, x2 *big.Int, ppb int64) bool { + // if x1 == 0 or x2 == 0, deviates if x2 != x1, to avoid the relative division by 0 error + if x1.BitLen() == 0 || x2.BitLen() == 0 { + return x1.Cmp(x2) != 0 + } + diff := big.NewInt(0).Sub(x1, x2) // diff = x1-x2 + diff.Mul(diff, big.NewInt(1e9)) // diff = diff * 1e9 + // dividing by the smaller value gives consistent ppb regardless of input order, and supports >100% deviation. + if x1.Cmp(x2) > 0 { + diff.Div(diff, x2) + } else { + diff.Div(diff, x1) + } + return diff.CmpAbs(big.NewInt(ppb)) > 0 // abs(diff) > ppb +} + +func MergeEpochAndRound(epoch uint32, round uint8) uint64 { + return uint64(epoch)<<8 + uint64(round) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipcalc/calc_test.go b/core/services/ocr2/plugins/ccip/internal/ccipcalc/calc_test.go new file mode 100644 index 0000000000..83384eca48 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipcalc/calc_test.go @@ -0,0 +1,220 @@ +package ccipcalc + +import ( + "math" + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestMergeEpochAndRound(t *testing.T) { + type args struct { + epoch uint32 + round uint8 + } + tests := []struct { + name string + args args + want uint64 + }{ + { + name: "zero round and epoch", + args: args{epoch: 0, round: 0}, + want: 0, + }, + { + name: "avg case", + args: args{ + epoch: 243, + round: 15, + }, + want: 62223, + }, + { + name: "largest epoch and round", + args: args{ + epoch: math.MaxUint32, + round: math.MaxUint8, + }, + want: 1099511627775, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, + MergeEpochAndRound(tt.args.epoch, tt.args.round), + "mergeEpochAndRound(%v, %v)", tt.args.epoch, tt.args.round) + }) + } +} + +func TestContiguousReqs(t *testing.T) { + testCases := []struct { + min uint64 + max uint64 + seqNrs []uint64 + exp bool + }{ + {min: 5, max: 10, seqNrs: []uint64{5, 6, 7, 8, 9, 10}, exp: true}, + {min: 5, max: 10, seqNrs: []uint64{5, 7, 8, 9, 10}, exp: false}, + {min: 5, max: 10, seqNrs: []uint64{5, 6, 7, 8, 9, 10, 11}, exp: false}, + {min: 5, max: 10, seqNrs: []uint64{}, exp: false}, + {min: 1, max: 1, seqNrs: []uint64{1}, exp: true}, + {min: 6, max: 10, seqNrs: []uint64{5, 7, 8, 9, 10}, exp: false}, + } + + for _, tc := range testCases { + res := ContiguousReqs(logger.NullLogger, tc.min, tc.max, tc.seqNrs) + assert.Equal(t, tc.exp, res) + } +} + +func TestCalculateUsdPerUnitGas(t *testing.T) { + testCases := []struct { + name string + sourceGasPrice *big.Int + usdPerFeeCoin *big.Int + exp *big.Int + }{ + { + name: "base case", + sourceGasPrice: big.NewInt(2e18), + usdPerFeeCoin: big.NewInt(3e18), + exp: big.NewInt(6e18), + }, + { + name: "small numbers", + sourceGasPrice: big.NewInt(1000), + usdPerFeeCoin: big.NewInt(2000), + exp: big.NewInt(0), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res := CalculateUsdPerUnitGas(tc.sourceGasPrice, tc.usdPerFeeCoin) + assert.Zero(t, tc.exp.Cmp(res)) + }) + } +} + +func TestBigIntSortedMiddle(t *testing.T) { + tests := []struct { + name string + vals []*big.Int + want *big.Int + }{ + { + name: "base case", + vals: []*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(4), big.NewInt(5)}, + want: big.NewInt(4), + }, + { + name: "not sorted", + vals: []*big.Int{big.NewInt(100), big.NewInt(50), big.NewInt(30), big.NewInt(110)}, + want: big.NewInt(100), + }, + { + name: "empty slice", + vals: []*big.Int{}, + want: nil, + }, + { + name: "one item", + vals: []*big.Int{big.NewInt(123)}, + want: big.NewInt(123), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, BigIntSortedMiddle(tt.vals), "BigIntSortedMiddle(%v)", tt.vals) + }) + } +} + +func TestDeviates(t *testing.T) { + type args struct { + x1 *big.Int + x2 *big.Int + ppb int64 + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "base case", + args: args{x1: big.NewInt(1e9), x2: big.NewInt(2e9), ppb: 1}, + want: true, + }, + { + name: "x1 is zero and x1 neq x2", + args: args{x1: big.NewInt(0), x2: big.NewInt(1), ppb: 999}, + want: true, + }, + { + name: "x2 is zero and x1 neq x2", + args: args{x1: big.NewInt(1), x2: big.NewInt(0), ppb: 999}, + want: true, + }, + { + name: "x1 and x2 are both zero", + args: args{x1: big.NewInt(0), x2: big.NewInt(0), ppb: 999}, + want: false, + }, + { + name: "deviates when ppb is 0", + args: args{x1: big.NewInt(0), x2: big.NewInt(1), ppb: 0}, + want: true, + }, + { + name: "does not deviate when x1 eq x2", + args: args{x1: big.NewInt(5), x2: big.NewInt(5), ppb: 1}, + want: false, + }, + { + name: "does not deviate with high ppb when x2 is greater", + args: args{x1: big.NewInt(5), x2: big.NewInt(10), ppb: 2e9}, + want: false, + }, + { + name: "does not deviate with high ppb when x1 is greater", + args: args{x1: big.NewInt(10), x2: big.NewInt(5), ppb: 2e9}, + want: false, + }, + { + name: "deviates with low ppb when x2 is greater", + args: args{x1: big.NewInt(5), x2: big.NewInt(10), ppb: 9e8}, + want: true, + }, + { + name: "deviates with low ppb when x1 is greater", + args: args{x1: big.NewInt(10), x2: big.NewInt(5), ppb: 9e8}, + want: true, + }, + { + name: "near deviation limit but deviates", + args: args{x1: big.NewInt(10), x2: big.NewInt(5), ppb: 1e9 - 1}, + want: true, + }, + { + name: "at deviation limit but does not deviate", + args: args{x1: big.NewInt(10), x2: big.NewInt(5), ppb: 1e9}, + want: false, + }, + { + name: "near deviation limit but does not deviate", + args: args{x1: big.NewInt(10), x2: big.NewInt(5), ppb: 1e9 + 1}, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, Deviates(tt.args.x1, tt.args.x2, tt.args.ppb), "Deviates(%v, %v, %v)", tt.args.x1, tt.args.x2, tt.args.ppb) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts.go b/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts.go new file mode 100644 index 0000000000..4f5ba6cfae --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts.go @@ -0,0 +1,140 @@ +package ccipcommon + +import ( + "context" + "encoding/binary" + "encoding/hex" + "fmt" + "sort" + "strings" + "time" + + "github.com/avast/retry-go/v4" + + "golang.org/x/sync/errgroup" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +func GetMessageIDsAsHexString(messages []cciptypes.EVM2EVMMessage) []string { + messageIDs := make([]string, 0, len(messages)) + for _, m := range messages { + messageIDs = append(messageIDs, "0x"+hex.EncodeToString(m.MessageID[:])) + } + return messageIDs +} + +type BackfillArgs struct { + SourceLP, DestLP logpoller.LogPoller + SourceStartBlock, DestStartBlock uint64 +} + +// GetFilteredSortedLaneTokens returns union of tokens supported on this lane, including fee tokens from the provided price registry +// and the bridgeable tokens from offRamp. Bridgeable tokens are only included if they are configured on the pricegetter +// Fee tokens are not filtered as they must always be priced +func GetFilteredSortedLaneTokens(ctx context.Context, offRamp ccipdata.OffRampReader, priceRegistry cciptypes.PriceRegistryReader, priceGetter cciptypes.PriceGetter) (laneTokens []cciptypes.Address, excludedTokens []cciptypes.Address, err error) { + destFeeTokens, destBridgeableTokens, err := GetDestinationTokens(ctx, offRamp, priceRegistry) + if err != nil { + return nil, nil, fmt.Errorf("get tokens with batch limit: %w", err) + } + + destTokensWithPrice, destTokensWithoutPrice, err := priceGetter.FilterConfiguredTokens(ctx, destBridgeableTokens) + if err != nil { + return nil, nil, fmt.Errorf("filter for priced tokens: %w", err) + } + + return flattenedAndSortedTokens(destFeeTokens, destTokensWithPrice), destTokensWithoutPrice, nil +} + +func flattenedAndSortedTokens(slices ...[]cciptypes.Address) (tokens []cciptypes.Address) { + // fee token can overlap with bridgeable tokens, we need to dedup them to arrive at lane token set + tokens = FlattenUniqueSlice(slices...) + + // return the tokens in deterministic order to aid with testing and debugging + sort.Slice(tokens, func(i, j int) bool { + return tokens[i] < tokens[j] + }) + + return tokens +} + +// GetDestinationTokens returns the destination chain fee tokens from the provided price registry +// and the bridgeable tokens from the offramp. +func GetDestinationTokens(ctx context.Context, offRamp ccipdata.OffRampReader, priceRegistry cciptypes.PriceRegistryReader) (fee, bridged []cciptypes.Address, err error) { + eg := new(errgroup.Group) + + var destFeeTokens []cciptypes.Address + var destBridgeableTokens []cciptypes.Address + + eg.Go(func() error { + tokens, err := priceRegistry.GetFeeTokens(ctx) + if err != nil { + return fmt.Errorf("get dest fee tokens: %w", err) + } + destFeeTokens = tokens + return nil + }) + + eg.Go(func() error { + tokens, err := offRamp.GetTokens(ctx) + if err != nil { + return fmt.Errorf("get dest bridgeable tokens: %w", err) + } + destBridgeableTokens = tokens.DestinationTokens + return nil + }) + + if err := eg.Wait(); err != nil { + return nil, nil, err + } + + return destFeeTokens, destBridgeableTokens, nil +} + +// FlattenUniqueSlice returns a flattened slice that contains unique elements by preserving their order. +func FlattenUniqueSlice[T comparable](slices ...[]T) []T { + seen := make(map[T]struct{}) + flattened := make([]T, 0) + + for _, sl := range slices { + for _, el := range sl { + if _, exists := seen[el]; !exists { + flattened = append(flattened, el) + seen[el] = struct{}{} + } + } + } + return flattened +} + +func IsTxRevertError(err error) bool { + if err == nil { + return false + } + + // Geth eth_call reverts with "execution reverted" + // Nethermind, Parity, OpenEthereum eth_call reverts with "VM execution error" + // See: https://github.com/ethereum/go-ethereum/issues/21886 + return strings.Contains(err.Error(), "execution reverted") || strings.Contains(err.Error(), "VM execution error") +} + +func SelectorToBytes(chainSelector uint64) [16]byte { + var b [16]byte + binary.BigEndian.PutUint64(b[:], chainSelector) + return b +} + +// RetryUntilSuccess repeatedly calls fn until it returns a nil error. After each failed call there is an exponential +// backoff applied, between initialDelay and maxDelay. +func RetryUntilSuccess[T any](fn func() (T, error), initialDelay time.Duration, maxDelay time.Duration) (T, error) { + return retry.DoWithData( + fn, + retry.Delay(initialDelay), + retry.MaxDelay(maxDelay), + retry.DelayType(retry.BackOffDelay), + retry.UntilSucceeded(), + ) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts_test.go b/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts_test.go new file mode 100644 index 0000000000..73a3b83495 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts_test.go @@ -0,0 +1,196 @@ +package ccipcommon + +import ( + "fmt" + "math/rand" + "sort" + "strconv" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + ccipdatamocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" +) + +func TestGetMessageIDsAsHexString(t *testing.T) { + t.Run("base", func(t *testing.T) { + hashes := make([]cciptypes.Hash, 10) + for i := range hashes { + hashes[i] = cciptypes.Hash(common.HexToHash(strconv.Itoa(rand.Intn(100000)))) + } + + msgs := make([]cciptypes.EVM2EVMMessage, len(hashes)) + for i := range msgs { + msgs[i] = cciptypes.EVM2EVMMessage{MessageID: hashes[i]} + } + + messageIDs := GetMessageIDsAsHexString(msgs) + for i := range messageIDs { + assert.Equal(t, hashes[i].String(), messageIDs[i]) + } + }) + + t.Run("empty", func(t *testing.T) { + messageIDs := GetMessageIDsAsHexString(nil) + assert.Empty(t, messageIDs) + }) +} + +func TestFlattenUniqueSlice(t *testing.T) { + testCases := []struct { + name string + inputSlices [][]int + expectedOutput []int + }{ + {name: "empty", inputSlices: nil, expectedOutput: []int{}}, + {name: "empty 2", inputSlices: [][]int{}, expectedOutput: []int{}}, + {name: "single", inputSlices: [][]int{{1, 2, 3, 3, 3, 4}}, expectedOutput: []int{1, 2, 3, 4}}, + {name: "simple", inputSlices: [][]int{{1, 2, 3}, {2, 3, 4}}, expectedOutput: []int{1, 2, 3, 4}}, + { + name: "more complex case", + inputSlices: [][]int{{1, 3}, {2, 4, 3}, {5, 2, -1, 7, 10}}, + expectedOutput: []int{1, 3, 2, 4, 5, -1, 7, 10}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res := FlattenUniqueSlice(tc.inputSlices...) + assert.Equal(t, tc.expectedOutput, res) + }) + } +} + +func TestGetFilteredChainTokens(t *testing.T) { + const numTokens = 6 + var tokens []cciptypes.Address + for i := 0; i < numTokens; i++ { + tokens = append(tokens, ccipcalc.EvmAddrToGeneric(utils.RandomAddress())) + } + + testCases := []struct { + name string + feeTokens []cciptypes.Address + destTokens []cciptypes.Address + expectedChainTokens []cciptypes.Address + expectedFilteredTokens []cciptypes.Address + }{ + { + name: "empty", + feeTokens: []cciptypes.Address{}, + destTokens: []cciptypes.Address{}, + expectedChainTokens: []cciptypes.Address{}, + expectedFilteredTokens: []cciptypes.Address{}, + }, + { + name: "unique tokens", + feeTokens: []cciptypes.Address{tokens[0]}, + destTokens: []cciptypes.Address{tokens[1], tokens[2], tokens[3]}, + expectedChainTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3]}, + expectedFilteredTokens: []cciptypes.Address{tokens[4], tokens[5]}, + }, + { + name: "all tokens", + feeTokens: []cciptypes.Address{tokens[0]}, + destTokens: []cciptypes.Address{tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]}, + expectedChainTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]}, + expectedFilteredTokens: []cciptypes.Address{}, + }, + { + name: "overlapping tokens", + feeTokens: []cciptypes.Address{tokens[0]}, + destTokens: []cciptypes.Address{tokens[1], tokens[2], tokens[5], tokens[3], tokens[0], tokens[2], tokens[3], tokens[4], tokens[5], tokens[5]}, + expectedChainTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]}, + expectedFilteredTokens: []cciptypes.Address{}, + }, + { + name: "unconfigured tokens", + feeTokens: []cciptypes.Address{tokens[0]}, + destTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3], tokens[0], tokens[2], tokens[3], tokens[4], tokens[5], tokens[5]}, + expectedChainTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3], tokens[4]}, + expectedFilteredTokens: []cciptypes.Address{tokens[5]}, + }, + } + + ctx := testutils.Context(t) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + priceRegistry := ccipdatamocks.NewPriceRegistryReader(t) + priceRegistry.On("GetFeeTokens", ctx).Return(tc.feeTokens, nil).Once() + + priceGet := pricegetter.NewMockPriceGetter(t) + priceGet.On("FilterConfiguredTokens", mock.Anything, mock.Anything).Return(tc.expectedChainTokens, tc.expectedFilteredTokens, nil) + + offRamp := ccipdatamocks.NewOffRampReader(t) + offRamp.On("GetTokens", ctx).Return(cciptypes.OffRampTokens{DestinationTokens: tc.destTokens}, nil).Once() + + chainTokens, filteredTokens, err := GetFilteredSortedLaneTokens(ctx, offRamp, priceRegistry, priceGet) + assert.NoError(t, err) + + sort.Slice(tc.expectedChainTokens, func(i, j int) bool { + return tc.expectedChainTokens[i] < tc.expectedChainTokens[j] + }) + assert.Equal(t, tc.expectedChainTokens, chainTokens) + assert.Equal(t, tc.expectedFilteredTokens, filteredTokens) + }) + } +} + +func TestIsTxRevertError(t *testing.T) { + testCases := []struct { + name string + inputError error + expectedOutput bool + }{ + {name: "empty", inputError: nil, expectedOutput: false}, + {name: "non-revert error", inputError: fmt.Errorf("nothing"), expectedOutput: false}, + {name: "geth error", inputError: fmt.Errorf("execution reverted"), expectedOutput: true}, + {name: "nethermind error", inputError: fmt.Errorf("VM execution error"), expectedOutput: true}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.expectedOutput, IsTxRevertError(tc.inputError)) + }) + } +} + +func TestRetryUntilSuccess(t *testing.T) { + // Set delays to 0 for tests + initialDelay := 0 * time.Nanosecond + maxDelay := 0 * time.Nanosecond + + numAttempts := 5 + numCalls := 0 + // A function that returns success only after numAttempts calls. RetryUntilSuccess will repeatedly call this + // function until it succeeds. + fn := func() (int, error) { + numCalls++ + numAttempts-- + if numAttempts > 0 { + return numCalls, fmt.Errorf("") + } + return numCalls, nil + } + + // Assert that RetryUntilSuccess returns the expected value when fn returns success on the 5th attempt + numCalls, err := RetryUntilSuccess(fn, initialDelay, maxDelay) + assert.Nil(t, err) + assert.Equal(t, 5, numCalls) + + // Assert that RetryUntilSuccess returns the expected value when fn returns success on the 8th attempt + numAttempts = 8 + numCalls = 0 + numCalls, err = RetryUntilSuccess(fn, initialDelay, maxDelay) + assert.Nil(t, err) + assert.Equal(t, 8, numCalls) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/mocks/token_pool_batched_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/mocks/token_pool_batched_reader_mock.go new file mode 100644 index 0000000000..551cd7c6a6 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/mocks/token_pool_batched_reader_mock.go @@ -0,0 +1,142 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + mock "github.com/stretchr/testify/mock" +) + +// TokenPoolBatchedReader is an autogenerated mock type for the TokenPoolBatchedReader type +type TokenPoolBatchedReader struct { + mock.Mock +} + +type TokenPoolBatchedReader_Expecter struct { + mock *mock.Mock +} + +func (_m *TokenPoolBatchedReader) EXPECT() *TokenPoolBatchedReader_Expecter { + return &TokenPoolBatchedReader_Expecter{mock: &_m.Mock} +} + +// Close provides a mock function with given fields: +func (_m *TokenPoolBatchedReader) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// TokenPoolBatchedReader_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type TokenPoolBatchedReader_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *TokenPoolBatchedReader_Expecter) Close() *TokenPoolBatchedReader_Close_Call { + return &TokenPoolBatchedReader_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *TokenPoolBatchedReader_Close_Call) Run(run func()) *TokenPoolBatchedReader_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *TokenPoolBatchedReader_Close_Call) Return(_a0 error) *TokenPoolBatchedReader_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *TokenPoolBatchedReader_Close_Call) RunAndReturn(run func() error) *TokenPoolBatchedReader_Close_Call { + _c.Call.Return(run) + return _c +} + +// GetInboundTokenPoolRateLimits provides a mock function with given fields: ctx, tokenPoolReaders +func (_m *TokenPoolBatchedReader) GetInboundTokenPoolRateLimits(ctx context.Context, tokenPoolReaders []ccip.Address) ([]ccip.TokenBucketRateLimit, error) { + ret := _m.Called(ctx, tokenPoolReaders) + + if len(ret) == 0 { + panic("no return value specified for GetInboundTokenPoolRateLimits") + } + + var r0 []ccip.TokenBucketRateLimit + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) ([]ccip.TokenBucketRateLimit, error)); ok { + return rf(ctx, tokenPoolReaders) + } + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) []ccip.TokenBucketRateLimit); ok { + r0 = rf(ctx, tokenPoolReaders) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccip.TokenBucketRateLimit) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []ccip.Address) error); ok { + r1 = rf(ctx, tokenPoolReaders) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// TokenPoolBatchedReader_GetInboundTokenPoolRateLimits_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetInboundTokenPoolRateLimits' +type TokenPoolBatchedReader_GetInboundTokenPoolRateLimits_Call struct { + *mock.Call +} + +// GetInboundTokenPoolRateLimits is a helper method to define mock.On call +// - ctx context.Context +// - tokenPoolReaders []ccip.Address +func (_e *TokenPoolBatchedReader_Expecter) GetInboundTokenPoolRateLimits(ctx interface{}, tokenPoolReaders interface{}) *TokenPoolBatchedReader_GetInboundTokenPoolRateLimits_Call { + return &TokenPoolBatchedReader_GetInboundTokenPoolRateLimits_Call{Call: _e.mock.On("GetInboundTokenPoolRateLimits", ctx, tokenPoolReaders)} +} + +func (_c *TokenPoolBatchedReader_GetInboundTokenPoolRateLimits_Call) Run(run func(ctx context.Context, tokenPoolReaders []ccip.Address)) *TokenPoolBatchedReader_GetInboundTokenPoolRateLimits_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]ccip.Address)) + }) + return _c +} + +func (_c *TokenPoolBatchedReader_GetInboundTokenPoolRateLimits_Call) Return(_a0 []ccip.TokenBucketRateLimit, _a1 error) *TokenPoolBatchedReader_GetInboundTokenPoolRateLimits_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *TokenPoolBatchedReader_GetInboundTokenPoolRateLimits_Call) RunAndReturn(run func(context.Context, []ccip.Address) ([]ccip.TokenBucketRateLimit, error)) *TokenPoolBatchedReader_GetInboundTokenPoolRateLimits_Call { + _c.Call.Return(run) + return _c +} + +// NewTokenPoolBatchedReader creates a new instance of TokenPoolBatchedReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewTokenPoolBatchedReader(t interface { + mock.TestingT + Cleanup(func()) +}) *TokenPoolBatchedReader { + mock := &TokenPoolBatchedReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader.go new file mode 100644 index 0000000000..57e8df1bde --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader.go @@ -0,0 +1,192 @@ +package batchreader + +import ( + "context" + "errors" + "fmt" + "sync" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + + "github.com/ethereum/go-ethereum/common" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + type_and_version "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/type_and_version_interface_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_4_0" +) + +var ( + typeAndVersionABI = abihelpers.MustParseABI(type_and_version.TypeAndVersionInterfaceABI) +) + +type EVMTokenPoolBatchedReader struct { + lggr logger.Logger + remoteChainSelector uint64 + offRampAddress common.Address + evmBatchCaller rpclib.EvmBatchCaller + + tokenPoolReaders map[cciptypes.Address]ccipdata.TokenPoolReader + tokenPoolReaderMu sync.RWMutex +} + +type TokenPoolBatchedReader interface { + cciptypes.TokenPoolBatchedReader +} + +var _ TokenPoolBatchedReader = (*EVMTokenPoolBatchedReader)(nil) + +func NewEVMTokenPoolBatchedReader(lggr logger.Logger, remoteChainSelector uint64, offRampAddress cciptypes.Address, evmBatchCaller rpclib.EvmBatchCaller) (*EVMTokenPoolBatchedReader, error) { + offRampAddrEvm, err := ccipcalc.GenericAddrToEvm(offRampAddress) + if err != nil { + return nil, err + } + + return &EVMTokenPoolBatchedReader{ + lggr: lggr, + remoteChainSelector: remoteChainSelector, + offRampAddress: offRampAddrEvm, + evmBatchCaller: evmBatchCaller, + tokenPoolReaders: make(map[cciptypes.Address]ccipdata.TokenPoolReader), + }, nil +} + +func (br *EVMTokenPoolBatchedReader) GetInboundTokenPoolRateLimits(ctx context.Context, tokenPools []cciptypes.Address) ([]cciptypes.TokenBucketRateLimit, error) { + if len(tokenPools) == 0 { + return []cciptypes.TokenBucketRateLimit{}, nil + } + + err := br.loadTokenPoolReaders(ctx, tokenPools) + if err != nil { + return nil, err + } + + tokenPoolReaders := make([]ccipdata.TokenPoolReader, 0, len(tokenPools)) + for _, poolAddress := range tokenPools { + br.tokenPoolReaderMu.RLock() + tokenPoolReader, exists := br.tokenPoolReaders[poolAddress] + br.tokenPoolReaderMu.RUnlock() + if !exists { + return nil, fmt.Errorf("token pool %s not found", poolAddress) + } + tokenPoolReaders = append(tokenPoolReaders, tokenPoolReader) + } + + evmCalls := make([]rpclib.EvmCall, 0, len(tokenPoolReaders)) + for _, poolReader := range tokenPoolReaders { + switch v := poolReader.(type) { + case *v1_2_0.TokenPool: + evmCalls = append(evmCalls, v1_2_0.GetInboundTokenPoolRateLimitCall(v.Address(), v.OffRampAddress)) + case *v1_4_0.TokenPool: + evmCalls = append(evmCalls, v1_4_0.GetInboundTokenPoolRateLimitCall(v.Address(), v.RemoteChainSelector)) + default: + return nil, fmt.Errorf("unsupported token pool version %T", v) + } + } + + results, err := br.evmBatchCaller.BatchCall(ctx, 0, evmCalls) + if err != nil { + return nil, fmt.Errorf("batch call limit: %w", err) + } + + resultsParsed, err := rpclib.ParseOutputs[cciptypes.TokenBucketRateLimit](results, func(d rpclib.DataAndErr) (cciptypes.TokenBucketRateLimit, error) { + return rpclib.ParseOutput[cciptypes.TokenBucketRateLimit](d, 0) + }) + if err != nil { + return nil, fmt.Errorf("parse outputs: %w", err) + } + return resultsParsed, nil +} + +// loadTokenPoolReaders loads the token pools into the factory's cache +func (br *EVMTokenPoolBatchedReader) loadTokenPoolReaders(ctx context.Context, tokenPoolAddresses []cciptypes.Address) error { + var missingTokens []common.Address + + br.tokenPoolReaderMu.RLock() + for _, poolAddress := range tokenPoolAddresses { + if _, exists := br.tokenPoolReaders[poolAddress]; !exists { + evmPoolAddr, err := ccipcalc.GenericAddrToEvm(poolAddress) + if err != nil { + return err + } + missingTokens = append(missingTokens, evmPoolAddr) + } + } + br.tokenPoolReaderMu.RUnlock() + + // Only continue if there are missing tokens + if len(missingTokens) == 0 { + return nil + } + + typeAndVersions, err := getBatchedTypeAndVersion(ctx, br.evmBatchCaller, missingTokens) + if err != nil { + return err + } + + br.tokenPoolReaderMu.Lock() + defer br.tokenPoolReaderMu.Unlock() + for i, tokenPoolAddress := range missingTokens { + typeAndVersion := typeAndVersions[i] + poolType, version, err := ccipconfig.ParseTypeAndVersion(typeAndVersion) + if err != nil { + return err + } + switch version { + case ccipdata.V1_0_0, ccipdata.V1_1_0, ccipdata.V1_2_0: + br.tokenPoolReaders[ccipcalc.EvmAddrToGeneric(tokenPoolAddress)] = v1_2_0.NewTokenPool(poolType, tokenPoolAddress, br.offRampAddress) + case ccipdata.V1_4_0: + br.tokenPoolReaders[ccipcalc.EvmAddrToGeneric(tokenPoolAddress)] = v1_4_0.NewTokenPool(poolType, tokenPoolAddress, br.remoteChainSelector) + default: + return fmt.Errorf("unsupported token pool version %v", version) + } + } + return nil +} + +func getBatchedTypeAndVersion(ctx context.Context, evmBatchCaller rpclib.EvmBatchCaller, poolAddresses []common.Address) ([]string, error) { + var evmCalls []rpclib.EvmCall + + for _, poolAddress := range poolAddresses { + // Add the typeAndVersion call to the batch + evmCalls = append(evmCalls, rpclib.NewEvmCall( + typeAndVersionABI, + "typeAndVersion", + poolAddress, + )) + } + + results, err := evmBatchCaller.BatchCall(ctx, 0, evmCalls) + if err != nil { + return nil, fmt.Errorf("batch call limit: %w", err) + } + + result, err := rpclib.ParseOutputs[string](results, func(d rpclib.DataAndErr) (string, error) { + tAndV, err1 := rpclib.ParseOutput[string](d, 0) + if err1 != nil { + // typeAndVersion method do not exist for 1.0 pools. We are going to get an ErrEmptyOutput in that case. + // Some chains, like the simulated chains, will simply revert with "execution reverted" + if errors.Is(err1, rpclib.ErrEmptyOutput) || ccipcommon.IsTxRevertError(err1) { + return "LegacyPool " + ccipdata.V1_0_0, nil + } + return "", err1 + } + + return tAndV, nil + }) + if err != nil { + return nil, fmt.Errorf("parse outputs: %w", err) + } + return result, nil +} + +func (br *EVMTokenPoolBatchedReader) Close() error { + return nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader_test.go new file mode 100644 index 0000000000..c67c3c1527 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader_test.go @@ -0,0 +1,86 @@ +package batchreader + +import ( + "context" + "fmt" + "math/big" + "testing" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib/rpclibmocks" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +func TestTokenPoolFactory(t *testing.T) { + lggr := logger.TestLogger(t) + offRamp := utils.RandomAddress() + ctx := context.Background() + remoteChainSelector := uint64(2000) + batchCallerMock := rpclibmocks.NewEvmBatchCaller(t) + + tokenPoolBatchReader, err := NewEVMTokenPoolBatchedReader(lggr, remoteChainSelector, ccipcalc.EvmAddrToGeneric(offRamp), batchCallerMock) + assert.NoError(t, err) + + poolTypes := []string{"BurnMint", "LockRelease"} + + rateLimits := cciptypes.TokenBucketRateLimit{ + Tokens: big.NewInt(333333), + LastUpdated: 33, + IsEnabled: true, + Capacity: big.NewInt(666666), + Rate: big.NewInt(444444), + } + + for _, versionStr := range []string{ccipdata.V1_0_0, ccipdata.V1_1_0, ccipdata.V1_2_0, ccipdata.V1_4_0} { + gotRateLimits, err := tokenPoolBatchReader.GetInboundTokenPoolRateLimits(ctx, []cciptypes.Address{}) + require.NoError(t, err) + assert.Empty(t, gotRateLimits) + + var batchCallResult []rpclib.DataAndErr + for _, poolType := range poolTypes { + if versionStr == ccipdata.V1_0_0 { + // simulating the behaviour for 1.0.0 pools where typeAndVersion method does not exist + batchCallResult = append(batchCallResult, rpclib.DataAndErr{ + Err: fmt.Errorf("unpack result: %w", rpclib.ErrEmptyOutput), + }) + } else { + batchCallResult = append(batchCallResult, rpclib.DataAndErr{ + Outputs: []any{poolType + " " + versionStr}, + Err: nil, + }) + } + } + + batchCallerMock.On("BatchCall", ctx, uint64(0), mock.Anything).Return(batchCallResult, nil).Once() + batchCallerMock.On("BatchCall", ctx, uint64(0), mock.Anything).Return([]rpclib.DataAndErr{{ + Outputs: []any{rateLimits}, + Err: nil, + }, { + Outputs: []any{rateLimits}, + Err: nil, + }}, nil).Once() + + var poolAddresses []cciptypes.Address + + for i := 0; i < len(poolTypes); i++ { + poolAddresses = append(poolAddresses, ccipcalc.EvmAddrToGeneric(utils.RandomAddress())) + } + + gotRateLimits, err = tokenPoolBatchReader.GetInboundTokenPoolRateLimits(ctx, poolAddresses) + require.NoError(t, err) + assert.Len(t, gotRateLimits, len(poolTypes)) + + for _, gotRateLimit := range gotRateLimits { + assert.Equal(t, rateLimits, gotRateLimit) + } + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/mocks/price_registry_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/mocks/price_registry_mock.go new file mode 100644 index 0000000000..59588a25d1 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/mocks/price_registry_mock.go @@ -0,0 +1,97 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + context "context" + + mock "github.com/stretchr/testify/mock" +) + +// PriceRegistry is an autogenerated mock type for the PriceRegistry type +type PriceRegistry struct { + mock.Mock +} + +type PriceRegistry_Expecter struct { + mock *mock.Mock +} + +func (_m *PriceRegistry) EXPECT() *PriceRegistry_Expecter { + return &PriceRegistry_Expecter{mock: &_m.Mock} +} + +// NewPriceRegistryReader provides a mock function with given fields: ctx, addr +func (_m *PriceRegistry) NewPriceRegistryReader(ctx context.Context, addr ccip.Address) (ccip.PriceRegistryReader, error) { + ret := _m.Called(ctx, addr) + + if len(ret) == 0 { + panic("no return value specified for NewPriceRegistryReader") + } + + var r0 ccip.PriceRegistryReader + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ccip.Address) (ccip.PriceRegistryReader, error)); ok { + return rf(ctx, addr) + } + if rf, ok := ret.Get(0).(func(context.Context, ccip.Address) ccip.PriceRegistryReader); ok { + r0 = rf(ctx, addr) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(ccip.PriceRegistryReader) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, ccip.Address) error); ok { + r1 = rf(ctx, addr) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistry_NewPriceRegistryReader_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewPriceRegistryReader' +type PriceRegistry_NewPriceRegistryReader_Call struct { + *mock.Call +} + +// NewPriceRegistryReader is a helper method to define mock.On call +// - ctx context.Context +// - addr ccip.Address +func (_e *PriceRegistry_Expecter) NewPriceRegistryReader(ctx interface{}, addr interface{}) *PriceRegistry_NewPriceRegistryReader_Call { + return &PriceRegistry_NewPriceRegistryReader_Call{Call: _e.mock.On("NewPriceRegistryReader", ctx, addr)} +} + +func (_c *PriceRegistry_NewPriceRegistryReader_Call) Run(run func(ctx context.Context, addr ccip.Address)) *PriceRegistry_NewPriceRegistryReader_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(ccip.Address)) + }) + return _c +} + +func (_c *PriceRegistry_NewPriceRegistryReader_Call) Return(_a0 ccip.PriceRegistryReader, _a1 error) *PriceRegistry_NewPriceRegistryReader_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistry_NewPriceRegistryReader_Call) RunAndReturn(run func(context.Context, ccip.Address) (ccip.PriceRegistryReader, error)) *PriceRegistry_NewPriceRegistryReader_Call { + _c.Call.Return(run) + return _c +} + +// NewPriceRegistry creates a new instance of PriceRegistry. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewPriceRegistry(t interface { + mock.TestingT + Cleanup(func()) +}) *PriceRegistry { + mock := &PriceRegistry{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/provider.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/provider.go new file mode 100644 index 0000000000..d1666d548a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/provider.go @@ -0,0 +1,40 @@ +package ccipdataprovider + +import ( + "context" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/observability" +) + +type PriceRegistry interface { + NewPriceRegistryReader(ctx context.Context, addr cciptypes.Address) (cciptypes.PriceRegistryReader, error) +} + +type EvmPriceRegistry struct { + lp logpoller.LogPoller + ec client.Client + lggr logger.Logger + pluginLabel string +} + +func NewEvmPriceRegistry(lp logpoller.LogPoller, ec client.Client, lggr logger.Logger, pluginLabel string) *EvmPriceRegistry { + return &EvmPriceRegistry{ + lp: lp, + ec: ec, + lggr: lggr, + pluginLabel: pluginLabel, + } +} + +func (p *EvmPriceRegistry) NewPriceRegistryReader(ctx context.Context, addr cciptypes.Address) (cciptypes.PriceRegistryReader, error) { + destPriceRegistryReader, err := factory.NewPriceRegistryReader(ctx, p.lggr, factory.NewEvmVersionFinder(), addr, p.lp, p.ec) + if err != nil { + return nil, err + } + return observability.NewPriceRegistryReader(destPriceRegistryReader, p.ec.ConfiguredChainID().Int64(), p.pluginLabel), nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go new file mode 100644 index 0000000000..2b144b765e --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go @@ -0,0 +1,81 @@ +package ccipdata + +import ( + "context" + "math/big" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" +) + +// Common to all versions +type CommitOnchainConfig commit_store.CommitStoreDynamicConfig + +func (d CommitOnchainConfig) AbiString() string { + return ` + [ + { + "components": [ + {"name": "priceRegistry", "type": "address"} + ], + "type": "tuple" + } + ]` +} + +func (d CommitOnchainConfig) Validate() error { + if d.PriceRegistry == (common.Address{}) { + return errors.New("must set Price Registry address") + } + return nil +} + +func NewCommitOffchainConfig( + gasPriceDeviationPPB uint32, + gasPriceHeartBeat time.Duration, + tokenPriceDeviationPPB uint32, + tokenPriceHeartBeat time.Duration, + inflightCacheExpiry time.Duration, + priceReportingDisabled bool, +) cciptypes.CommitOffchainConfig { + return cciptypes.CommitOffchainConfig{ + GasPriceDeviationPPB: gasPriceDeviationPPB, + GasPriceHeartBeat: gasPriceHeartBeat, + TokenPriceDeviationPPB: tokenPriceDeviationPPB, + TokenPriceHeartBeat: tokenPriceHeartBeat, + InflightCacheExpiry: inflightCacheExpiry, + PriceReportingDisabled: priceReportingDisabled, + } +} + +type CommitStoreReader interface { + cciptypes.CommitStoreReader + SetGasEstimator(ctx context.Context, gpe gas.EvmFeeEstimator) error + SetSourceMaxGasPrice(ctx context.Context, sourceMaxGasPrice *big.Int) error +} + +// FetchCommitStoreStaticConfig provides access to a commitStore's static config, which is required to access the source chain ID. +func FetchCommitStoreStaticConfig(address common.Address, ec client.Client) (commit_store.CommitStoreStaticConfig, error) { + commitStore, err := loadCommitStore(address, ec) + if err != nil { + return commit_store.CommitStoreStaticConfig{}, err + } + return commitStore.GetStaticConfig(&bind.CallOpts{}) +} + +func loadCommitStore(commitStoreAddress common.Address, client client.Client) (commit_store.CommitStoreInterface, error) { + _, err := ccipconfig.VerifyTypeAndVersion(commitStoreAddress, client, ccipconfig.CommitStore) + if err != nil { + return nil, errors.Wrap(err, "Invalid commitStore contract") + } + return commit_store.NewCommitStore(commitStoreAddress, client) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go new file mode 100644 index 0000000000..4e134b1f17 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -0,0 +1,423 @@ +package ccipdata_test + +import ( + "context" + "math/big" + "reflect" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + evmclientmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + gasmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" + rollupMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" +) + +func TestCommitOffchainConfig_Encoding(t *testing.T) { + tests := map[string]struct { + want v1_2_0.JSONCommitOffchainConfig + expectErr bool + }{ + "encodes and decodes config with all fields set": { + want: v1_2_0.JSONCommitOffchainConfig{ + SourceFinalityDepth: 3, + DestFinalityDepth: 3, + GasPriceHeartBeat: *config.MustNewDuration(1 * time.Hour), + DAGasPriceDeviationPPB: 5e7, + ExecGasPriceDeviationPPB: 5e7, + TokenPriceHeartBeat: *config.MustNewDuration(1 * time.Hour), + TokenPriceDeviationPPB: 5e7, + InflightCacheExpiry: *config.MustNewDuration(23456 * time.Second), + }, + }, + "fails decoding when all fields present but with 0 values": { + want: v1_2_0.JSONCommitOffchainConfig{ + SourceFinalityDepth: 0, + DestFinalityDepth: 0, + GasPriceHeartBeat: *config.MustNewDuration(0), + DAGasPriceDeviationPPB: 0, + ExecGasPriceDeviationPPB: 0, + TokenPriceHeartBeat: *config.MustNewDuration(0), + TokenPriceDeviationPPB: 0, + InflightCacheExpiry: *config.MustNewDuration(0), + }, + expectErr: true, + }, + "fails decoding when all fields are missing": { + want: v1_2_0.JSONCommitOffchainConfig{}, + expectErr: true, + }, + "fails decoding when some fields are missing": { + want: v1_2_0.JSONCommitOffchainConfig{ + SourceFinalityDepth: 3, + GasPriceHeartBeat: *config.MustNewDuration(1 * time.Hour), + DAGasPriceDeviationPPB: 5e7, + ExecGasPriceDeviationPPB: 5e7, + TokenPriceHeartBeat: *config.MustNewDuration(1 * time.Hour), + TokenPriceDeviationPPB: 5e7, + }, + expectErr: true, + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + encode, err := ccipconfig.EncodeOffchainConfig(tc.want) + require.NoError(t, err) + got, err := ccipconfig.DecodeOffchainConfig[v1_2_0.JSONCommitOffchainConfig](encode) + + if tc.expectErr { + require.ErrorContains(t, err, "must set") + } else { + require.NoError(t, err) + require.Equal(t, tc.want, got) + } + }) + } +} + +func TestCommitOnchainConfig(t *testing.T) { + tests := []struct { + name string + want ccipdata.CommitOnchainConfig + expectErr bool + }{ + { + name: "encodes and decodes config with all fields set", + want: ccipdata.CommitOnchainConfig{ + PriceRegistry: utils.RandomAddress(), + }, + expectErr: false, + }, + { + name: "encodes and fails decoding config with missing fields", + want: ccipdata.CommitOnchainConfig{}, + expectErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + encoded, err := abihelpers.EncodeAbiStruct(tt.want) + require.NoError(t, err) + + decoded, err := abihelpers.DecodeAbiStruct[ccipdata.CommitOnchainConfig](encoded) + if tt.expectErr { + require.ErrorContains(t, err, "must set") + } else { + require.NoError(t, err) + require.Equal(t, tt.want, decoded) + } + }) + } +} + +func TestCommitStoreReaders(t *testing.T) { + user, ec := newSim(t) + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + lpOpts := logpoller.Opts{ + PollPeriod: 100 * time.Millisecond, + FinalityDepth: 2, + BackfillBatchSize: 3, + RpcBatchSize: 2, + KeepFinalizedBlocksDepth: 1000, + } + headTracker := headtracker.NewSimulatedHeadTracker(ec, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + if lpOpts.PollPeriod == 0 { + lpOpts.PollPeriod = 1 * time.Hour + } + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, pgtest.NewSqlxDB(t), lggr), ec, lggr, headTracker, lpOpts) + + // Deploy 2 commit store versions + onramp1 := utils.RandomAddress() + onramp2 := utils.RandomAddress() + // Report + rep := cciptypes.CommitStoreReport{ + TokenPrices: []cciptypes.TokenPrice{{Token: ccipcalc.EvmAddrToGeneric(utils.RandomAddress()), Value: big.NewInt(1)}}, + GasPrices: []cciptypes.GasPrice{{DestChainSelector: 1, Value: big.NewInt(1)}}, + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}, + MerkleRoot: common.HexToHash("0x1"), + } + er := big.NewInt(1) + armAddr, _, arm, err := mock_arm_contract.DeployMockARMContract(user, ec) + require.NoError(t, err) + addr, _, ch, err := commit_store_helper_1_0_0.DeployCommitStoreHelper(user, ec, commit_store_helper_1_0_0.CommitStoreStaticConfig{ + ChainSelector: testutils.SimulatedChainID.Uint64(), + SourceChainSelector: testutils.SimulatedChainID.Uint64(), + OnRamp: onramp1, + ArmProxy: armAddr, + }) + require.NoError(t, err) + addr2, _, ch2, err := commit_store_helper_1_2_0.DeployCommitStoreHelper(user, ec, commit_store_helper_1_2_0.CommitStoreStaticConfig{ + ChainSelector: testutils.SimulatedChainID.Uint64(), + SourceChainSelector: testutils.SimulatedChainID.Uint64(), + OnRamp: onramp2, + ArmProxy: armAddr, + }) + require.NoError(t, err) + commitAndGetBlockTs(ec) // Deploy these + pr, _, _, err := price_registry_1_0_0.DeployPriceRegistry(user, ec, []common.Address{addr}, nil, 1e6) + require.NoError(t, err) + pr2, _, _, err := price_registry_1_2_0.DeployPriceRegistry(user, ec, []common.Address{addr2}, nil, 1e6) + require.NoError(t, err) + commitAndGetBlockTs(ec) // Deploy these + ge := new(gasmocks.EvmFeeEstimator) + lm := new(rollupMocks.L1Oracle) + ge.On("L1Oracle").Return(lm) + + maxGasPrice := big.NewInt(1e8) + c10r, err := factory.NewCommitStoreReader(lggr, factory.NewEvmVersionFinder(), ccipcalc.EvmAddrToGeneric(addr), ec, lp) // ge, maxGasPrice + require.NoError(t, err) + err = c10r.SetGasEstimator(ctx, ge) + require.NoError(t, err) + err = c10r.SetSourceMaxGasPrice(ctx, maxGasPrice) + require.NoError(t, err) + assert.Equal(t, reflect.TypeOf(c10r).String(), reflect.TypeOf(&v1_0_0.CommitStore{}).String()) + c12r, err := factory.NewCommitStoreReader(lggr, factory.NewEvmVersionFinder(), ccipcalc.EvmAddrToGeneric(addr2), ec, lp) + require.NoError(t, err) + err = c12r.SetGasEstimator(ctx, ge) + require.NoError(t, err) + err = c12r.SetSourceMaxGasPrice(ctx, maxGasPrice) + require.NoError(t, err) + assert.Equal(t, reflect.TypeOf(c12r).String(), reflect.TypeOf(&v1_2_0.CommitStore{}).String()) + + // Apply config + signers := []common.Address{utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress()} + transmitters := []common.Address{utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress()} + onchainConfig, err := abihelpers.EncodeAbiStruct[ccipdata.CommitOnchainConfig](ccipdata.CommitOnchainConfig{ + PriceRegistry: pr, + }) + require.NoError(t, err) + + sourceFinalityDepth := uint32(1) + destFinalityDepth := uint32(2) + commonOffchain := cciptypes.CommitOffchainConfig{ + GasPriceDeviationPPB: 1e6, + GasPriceHeartBeat: 1 * time.Hour, + TokenPriceDeviationPPB: 1e6, + TokenPriceHeartBeat: 1 * time.Hour, + InflightCacheExpiry: 3 * time.Hour, + PriceReportingDisabled: false, + } + offchainConfig, err := ccipconfig.EncodeOffchainConfig[v1_0_0.CommitOffchainConfig](v1_0_0.CommitOffchainConfig{ + SourceFinalityDepth: sourceFinalityDepth, + DestFinalityDepth: destFinalityDepth, + FeeUpdateHeartBeat: *config.MustNewDuration(commonOffchain.GasPriceHeartBeat), + FeeUpdateDeviationPPB: commonOffchain.GasPriceDeviationPPB, + InflightCacheExpiry: *config.MustNewDuration(commonOffchain.InflightCacheExpiry), + }) + require.NoError(t, err) + _, err = ch.SetOCR2Config(user, signers, transmitters, 1, onchainConfig, 1, []byte{}) + require.NoError(t, err) + onchainConfig2, err := abihelpers.EncodeAbiStruct[ccipdata.CommitOnchainConfig](ccipdata.CommitOnchainConfig{ + PriceRegistry: pr2, + }) + require.NoError(t, err) + offchainConfig2, err := ccipconfig.EncodeOffchainConfig[v1_2_0.JSONCommitOffchainConfig](v1_2_0.JSONCommitOffchainConfig{ + SourceFinalityDepth: sourceFinalityDepth, + DestFinalityDepth: destFinalityDepth, + GasPriceHeartBeat: *config.MustNewDuration(commonOffchain.GasPriceHeartBeat), + DAGasPriceDeviationPPB: 1e7, + ExecGasPriceDeviationPPB: commonOffchain.GasPriceDeviationPPB, + TokenPriceDeviationPPB: commonOffchain.TokenPriceDeviationPPB, + TokenPriceHeartBeat: *config.MustNewDuration(commonOffchain.TokenPriceHeartBeat), + InflightCacheExpiry: *config.MustNewDuration(commonOffchain.InflightCacheExpiry), + }) + require.NoError(t, err) + _, err = ch2.SetOCR2Config(user, signers, transmitters, 1, onchainConfig2, 1, []byte{}) + require.NoError(t, err) + commitAndGetBlockTs(ec) + + // Apply report + b, err := c10r.EncodeCommitReport(ctx, rep) + require.NoError(t, err) + _, err = ch.Report(user, b, er) + require.NoError(t, err) + b, err = c12r.EncodeCommitReport(ctx, rep) + require.NoError(t, err) + _, err = ch2.Report(user, b, er) + require.NoError(t, err) + commitAndGetBlockTs(ec) + + // Capture all logs. + lp.PollAndSaveLogs(context.Background(), 1) + + configs := map[string][][]byte{ + ccipdata.V1_0_0: {onchainConfig, offchainConfig}, + ccipdata.V1_2_0: {onchainConfig2, offchainConfig2}, + } + crs := map[string]ccipdata.CommitStoreReader{ + ccipdata.V1_0_0: c10r, + ccipdata.V1_2_0: c12r, + } + prs := map[string]common.Address{ + ccipdata.V1_0_0: pr, + ccipdata.V1_2_0: pr2, + } + gasPrice := big.NewInt(10) + daPrice := big.NewInt(20) + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, assets.NewWei(maxGasPrice)).Return(gas.EvmFee{Legacy: assets.NewWei(gasPrice)}, uint64(0), nil) + lm.On("GasPrice", mock.Anything).Return(assets.NewWei(daPrice), nil) + + for v, cr := range crs { + cr := cr + t.Run("CommitStoreReader "+v, func(t *testing.T) { + // Static config. + cfg, err := cr.GetCommitStoreStaticConfig(context.Background()) + require.NoError(t, err) + require.NotNil(t, cfg) + + // Assert encoding + b, err := cr.EncodeCommitReport(ctx, rep) + require.NoError(t, err) + d, err := cr.DecodeCommitReport(ctx, b) + require.NoError(t, err) + assert.Equal(t, d, rep) + + // Assert reading + latest, err := cr.GetLatestPriceEpochAndRound(context.Background()) + require.NoError(t, err) + assert.Equal(t, er.Uint64(), latest) + + // Assert cursing + down, err := cr.IsDown(context.Background()) + require.NoError(t, err) + assert.False(t, down) + _, err = arm.VoteToCurse(user, [32]byte{}) + require.NoError(t, err) + ec.Commit() + down, err = cr.IsDown(context.Background()) + require.NoError(t, err) + assert.True(t, down) + _, err = arm.OwnerUnvoteToCurse0(user, nil) + require.NoError(t, err) + ec.Commit() + + seqNr, err := cr.GetExpectedNextSequenceNumber(context.Background()) + require.NoError(t, err) + assert.Equal(t, rep.Interval.Max+1, seqNr) + + reps, err := cr.GetCommitReportMatchingSeqNum(context.Background(), rep.Interval.Max+1, 0) + require.NoError(t, err) + assert.Len(t, reps, 0) + + reps, err = cr.GetCommitReportMatchingSeqNum(context.Background(), rep.Interval.Max, 0) + require.NoError(t, err) + require.Len(t, reps, 1) + assert.Equal(t, reps[0].Interval, rep.Interval) + assert.Equal(t, reps[0].MerkleRoot, rep.MerkleRoot) + assert.Equal(t, reps[0].GasPrices, rep.GasPrices) + assert.Equal(t, reps[0].TokenPrices, rep.TokenPrices) + + reps, err = cr.GetCommitReportMatchingSeqNum(context.Background(), rep.Interval.Min, 0) + require.NoError(t, err) + require.Len(t, reps, 1) + assert.Equal(t, reps[0].Interval, rep.Interval) + assert.Equal(t, reps[0].MerkleRoot, rep.MerkleRoot) + assert.Equal(t, reps[0].GasPrices, rep.GasPrices) + assert.Equal(t, reps[0].TokenPrices, rep.TokenPrices) + + reps, err = cr.GetCommitReportMatchingSeqNum(context.Background(), rep.Interval.Min-1, 0) + require.NoError(t, err) + require.Len(t, reps, 0) + + // Sanity + reps, err = cr.GetAcceptedCommitReportsGteTimestamp(context.Background(), time.Unix(0, 0), 0) + require.NoError(t, err) + require.Len(t, reps, 1) + assert.Equal(t, reps[0].Interval, rep.Interval) + assert.Equal(t, reps[0].MerkleRoot, rep.MerkleRoot) + assert.Equal(t, reps[0].GasPrices, rep.GasPrices) + assert.Equal(t, reps[0].TokenPrices, rep.TokenPrices) + + // Until we detect the config, we'll have empty offchain config + c1, err := cr.OffchainConfig(ctx) + require.NoError(t, err) + assert.Equal(t, c1, cciptypes.CommitOffchainConfig{}) + newPr, err := cr.ChangeConfig(ctx, configs[v][0], configs[v][1]) + require.NoError(t, err) + assert.Equal(t, ccipcalc.EvmAddrToGeneric(prs[v]), newPr) + + c2, err := cr.OffchainConfig(ctx) + require.NoError(t, err) + assert.Equal(t, commonOffchain, c2) + // We should be able to query for gas prices now. + gpe, err := cr.GasPriceEstimator(ctx) + require.NoError(t, err) + gp, err := gpe.GetGasPrice(context.Background()) + require.NoError(t, err) + assert.True(t, gp.Cmp(big.NewInt(0)) > 0) + }) + } +} + +func TestNewCommitStoreReader(t *testing.T) { + var tt = []struct { + typeAndVersion string + expectedErr string + }{ + { + typeAndVersion: "blah", + expectedErr: "unable to read type and version: invalid type and version blah", + }, + { + typeAndVersion: "EVM2EVMOffRamp 1.0.0", + expectedErr: "expected CommitStore got EVM2EVMOffRamp", + }, + { + typeAndVersion: "CommitStore 1.2.0", + expectedErr: "", + }, + { + typeAndVersion: "CommitStore 2.0.0", + expectedErr: "unsupported commit store version 2.0.0", + }, + } + for _, tc := range tt { + t.Run(tc.typeAndVersion, func(t *testing.T) { + b, err := utils.ABIEncode(`[{"type":"string"}]`, tc.typeAndVersion) + require.NoError(t, err) + c := evmclientmocks.NewClient(t) + c.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(b, nil) + addr := ccipcalc.EvmAddrToGeneric(utils.RandomAddress()) + lp := lpmocks.NewLogPoller(t) + if tc.expectedErr == "" { + lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil) + } + _, err = factory.NewCommitStoreReader(logger.TestLogger(t), factory.NewEvmVersionFinder(), addr, c, lp) + if tc.expectedErr != "" { + require.EqualError(t, err, tc.expectedErr) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store.go new file mode 100644 index 0000000000..d431d2863a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store.go @@ -0,0 +1,121 @@ +package factory + +import ( + "github.com/Masterminds/semver/v3" + "github.com/pkg/errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0" +) + +func NewCommitStoreReader(lggr logger.Logger, versionFinder VersionFinder, address cciptypes.Address, ec client.Client, lp logpoller.LogPoller) (ccipdata.CommitStoreReader, error) { + return initOrCloseCommitStoreReader(lggr, versionFinder, address, ec, lp, false) +} + +func CloseCommitStoreReader(lggr logger.Logger, versionFinder VersionFinder, address cciptypes.Address, ec client.Client, lp logpoller.LogPoller) error { + _, err := initOrCloseCommitStoreReader(lggr, versionFinder, address, ec, lp, true) + return err +} + +func initOrCloseCommitStoreReader(lggr logger.Logger, versionFinder VersionFinder, address cciptypes.Address, ec client.Client, lp logpoller.LogPoller, closeReader bool) (ccipdata.CommitStoreReader, error) { + contractType, version, err := versionFinder.TypeAndVersion(address, ec) + if err != nil { + return nil, errors.Wrapf(err, "unable to read type and version") + } + if contractType != ccipconfig.CommitStore { + return nil, errors.Errorf("expected %v got %v", ccipconfig.CommitStore, contractType) + } + + evmAddr, err := ccipcalc.GenericAddrToEvm(address) + if err != nil { + return nil, err + } + + lggr.Infow("Initializing CommitStore Reader", "version", version.String()) + + switch version.String() { + case ccipdata.V1_0_0, ccipdata.V1_1_0: // Versions are identical + cs, err := v1_0_0.NewCommitStore(lggr, evmAddr, ec, lp) + if err != nil { + return nil, err + } + if closeReader { + return nil, cs.Close() + } + return cs, cs.RegisterFilters() + case ccipdata.V1_2_0: + cs, err := v1_2_0.NewCommitStore(lggr, evmAddr, ec, lp) + if err != nil { + return nil, err + } + if closeReader { + return nil, cs.Close() + } + return cs, cs.RegisterFilters() + case ccipdata.V1_5_0: + cs, err := v1_5_0.NewCommitStore(lggr, evmAddr, ec, lp) + if err != nil { + return nil, err + } + if closeReader { + return nil, cs.Close() + } + return cs, cs.RegisterFilters() + default: + return nil, errors.Errorf("unsupported commit store version %v", version.String()) + } +} + +func CommitReportToEthTxMeta(typ ccipconfig.ContractType, ver semver.Version) (func(report []byte) (*txmgr.TxMeta, error), error) { + if typ != ccipconfig.CommitStore { + return nil, errors.Errorf("expected %v got %v", ccipconfig.CommitStore, typ) + } + switch ver.String() { + case ccipdata.V1_0_0, ccipdata.V1_1_0: + commitStoreABI := abihelpers.MustParseABI(commit_store_1_0_0.CommitStoreABI) + return func(report []byte) (*txmgr.TxMeta, error) { + commitReport, err := v1_0_0.DecodeCommitReport(abihelpers.MustGetEventInputs(v1_0_0.ReportAccepted, commitStoreABI), report) + if err != nil { + return nil, err + } + return commitReportToEthTxMeta(commitReport) + }, nil + case ccipdata.V1_2_0, ccipdata.V1_5_0: + commitStoreABI := abihelpers.MustParseABI(commit_store.CommitStoreABI) + return func(report []byte) (*txmgr.TxMeta, error) { + commitReport, err := v1_2_0.DecodeCommitReport(abihelpers.MustGetEventInputs(v1_0_0.ReportAccepted, commitStoreABI), report) + if err != nil { + return nil, err + } + return commitReportToEthTxMeta(commitReport) + }, nil + default: + return nil, errors.Errorf("got unexpected version %v", ver.String()) + } +} + +// CommitReportToEthTxMeta generates a txmgr.EthTxMeta from the given commit report. +// sequence numbers of the committed messages will be added to tx metadata +func commitReportToEthTxMeta(commitReport cciptypes.CommitStoreReport) (*txmgr.TxMeta, error) { + n := (commitReport.Interval.Max - commitReport.Interval.Min) + 1 + seqRange := make([]uint64, n) + for i := uint64(0); i < n; i++ { + seqRange[i] = i + commitReport.Interval.Min + } + return &txmgr.TxMeta{ + SeqNumbers: seqRange, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store_test.go new file mode 100644 index 0000000000..e1b8ff929c --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store_test.go @@ -0,0 +1,37 @@ +package factory + +import ( + "testing" + + "github.com/Masterminds/semver/v3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + mocks2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" +) + +func TestCommitStore(t *testing.T) { + for _, versionStr := range []string{ccipdata.V1_0_0, ccipdata.V1_2_0} { + lggr := logger.TestLogger(t) + addr := cciptypes.Address(utils.RandomAddress().String()) + lp := mocks2.NewLogPoller(t) + + lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil) + versionFinder := newMockVersionFinder(ccipconfig.CommitStore, *semver.MustParse(versionStr), nil) + _, err := NewCommitStoreReader(lggr, versionFinder, addr, nil, lp) + assert.NoError(t, err) + + expFilterName := logpoller.FilterName(v1_0_0.EXEC_REPORT_ACCEPTS, addr) + lp.On("UnregisterFilter", mock.Anything, expFilterName).Return(nil) + err = CloseCommitStoreReader(lggr, versionFinder, addr, nil, lp) + assert.NoError(t, err) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp.go new file mode 100644 index 0000000000..c6fa63ee82 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp.go @@ -0,0 +1,125 @@ +package factory + +import ( + "context" + "math/big" + + "github.com/Masterminds/semver/v3" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/pkg/errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0" +) + +func NewOffRampReader(lggr logger.Logger, versionFinder VersionFinder, addr cciptypes.Address, destClient client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, destMaxGasPrice *big.Int, registerFilters bool) (ccipdata.OffRampReader, error) { + return initOrCloseOffRampReader(lggr, versionFinder, addr, destClient, lp, estimator, destMaxGasPrice, false, registerFilters) +} + +func CloseOffRampReader(lggr logger.Logger, versionFinder VersionFinder, addr cciptypes.Address, destClient client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, destMaxGasPrice *big.Int) error { + _, err := initOrCloseOffRampReader(lggr, versionFinder, addr, destClient, lp, estimator, destMaxGasPrice, true, false) + return err +} + +func initOrCloseOffRampReader(lggr logger.Logger, versionFinder VersionFinder, addr cciptypes.Address, destClient client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, destMaxGasPrice *big.Int, closeReader bool, registerFilters bool) (ccipdata.OffRampReader, error) { + contractType, version, err := versionFinder.TypeAndVersion(addr, destClient) + if err != nil { + return nil, errors.Wrapf(err, "unable to read type and version") + } + if contractType != ccipconfig.EVM2EVMOffRamp { + return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOffRamp, contractType) + } + + evmAddr, err := ccipcalc.GenericAddrToEvm(addr) + if err != nil { + return nil, err + } + + lggr.Infow("Initializing OffRamp Reader", "version", version.String(), "destMaxGasPrice", destMaxGasPrice.String()) + + switch version.String() { + case ccipdata.V1_0_0, ccipdata.V1_1_0: + offRamp, err := v1_0_0.NewOffRamp(lggr, evmAddr, destClient, lp, estimator, destMaxGasPrice) + if err != nil { + return nil, err + } + if closeReader { + return nil, offRamp.Close() + } + return offRamp, offRamp.RegisterFilters() + case ccipdata.V1_2_0: + offRamp, err := v1_2_0.NewOffRamp(lggr, evmAddr, destClient, lp, estimator, destMaxGasPrice) + if err != nil { + return nil, err + } + if closeReader { + return nil, offRamp.Close() + } + return offRamp, offRamp.RegisterFilters() + case ccipdata.V1_5_0: + offRamp, err := v1_5_0.NewOffRamp(lggr, evmAddr, destClient, lp, estimator, destMaxGasPrice) + if err != nil { + return nil, err + } + if closeReader { + return nil, offRamp.Close() + } + return offRamp, offRamp.RegisterFilters() + default: + return nil, errors.Errorf("unsupported offramp version %v", version.String()) + } + // TODO can validate it pointing to the correct version +} + +func ExecReportToEthTxMeta(ctx context.Context, typ ccipconfig.ContractType, ver semver.Version) (func(report []byte) (*txmgr.TxMeta, error), error) { + if typ != ccipconfig.EVM2EVMOffRamp { + return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOffRamp, typ) + } + switch ver.String() { + case ccipdata.V1_0_0, ccipdata.V1_1_0: + offRampABI := abihelpers.MustParseABI(evm_2_evm_offramp_1_0_0.EVM2EVMOffRampABI) + return func(report []byte) (*txmgr.TxMeta, error) { + execReport, err := v1_0_0.DecodeExecReport(ctx, abihelpers.MustGetMethodInputs(ccipdata.ManuallyExecute, offRampABI)[:1], report) + if err != nil { + return nil, err + } + return execReportToEthTxMeta(execReport) + }, nil + case ccipdata.V1_2_0, ccipdata.V1_5_0: + offRampABI := abihelpers.MustParseABI(evm_2_evm_offramp.EVM2EVMOffRampABI) + return func(report []byte) (*txmgr.TxMeta, error) { + execReport, err := v1_2_0.DecodeExecReport(ctx, abihelpers.MustGetMethodInputs(ccipdata.ManuallyExecute, offRampABI)[:1], report) + if err != nil { + return nil, err + } + return execReportToEthTxMeta(execReport) + }, nil + default: + return nil, errors.Errorf("got unexpected version %v", ver.String()) + } +} + +func execReportToEthTxMeta(execReport cciptypes.ExecReport) (*txmgr.TxMeta, error) { + msgIDs := make([]string, len(execReport.Messages)) + for i, msg := range execReport.Messages { + msgIDs[i] = hexutil.Encode(msg.MessageID[:]) + } + + return &txmgr.TxMeta{ + MessageIDs: msgIDs, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp_test.go new file mode 100644 index 0000000000..4b9e57ecfb --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp_test.go @@ -0,0 +1,44 @@ +package factory + +import ( + "testing" + + "github.com/Masterminds/semver/v3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + mocks2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" +) + +func TestOffRamp(t *testing.T) { + for _, versionStr := range []string{ccipdata.V1_0_0, ccipdata.V1_2_0} { + lggr := logger.TestLogger(t) + addr := cciptypes.Address(utils.RandomAddress().String()) + lp := mocks2.NewLogPoller(t) + + expFilterNames := []string{ + logpoller.FilterName(v1_0_0.EXEC_EXECUTION_STATE_CHANGES, addr), + logpoller.FilterName(v1_0_0.EXEC_TOKEN_POOL_ADDED, addr), + logpoller.FilterName(v1_0_0.EXEC_TOKEN_POOL_REMOVED, addr), + } + versionFinder := newMockVersionFinder(ccipconfig.EVM2EVMOffRamp, *semver.MustParse(versionStr), nil) + + lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil).Times(len(expFilterNames)) + _, err := NewOffRampReader(lggr, versionFinder, addr, nil, lp, nil, nil, true) + assert.NoError(t, err) + + for _, f := range expFilterNames { + lp.On("UnregisterFilter", mock.Anything, f).Return(nil) + } + err = CloseOffRampReader(lggr, versionFinder, addr, nil, lp, nil, nil) + assert.NoError(t, err) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp.go new file mode 100644 index 0000000000..e82584ac7c --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp.go @@ -0,0 +1,88 @@ +package factory + +import ( + "github.com/pkg/errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/logger" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_1_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0" +) + +// NewOnRampReader determines the appropriate version of the onramp and returns a reader for it +func NewOnRampReader(lggr logger.Logger, versionFinder VersionFinder, sourceSelector, destSelector uint64, onRampAddress cciptypes.Address, sourceLP logpoller.LogPoller, source client.Client) (ccipdata.OnRampReader, error) { + return initOrCloseOnRampReader(lggr, versionFinder, sourceSelector, destSelector, onRampAddress, sourceLP, source, false) +} + +func CloseOnRampReader(lggr logger.Logger, versionFinder VersionFinder, sourceSelector, destSelector uint64, onRampAddress cciptypes.Address, sourceLP logpoller.LogPoller, source client.Client) error { + _, err := initOrCloseOnRampReader(lggr, versionFinder, sourceSelector, destSelector, onRampAddress, sourceLP, source, true) + return err +} + +func initOrCloseOnRampReader(lggr logger.Logger, versionFinder VersionFinder, sourceSelector, destSelector uint64, onRampAddress cciptypes.Address, sourceLP logpoller.LogPoller, source client.Client, closeReader bool) (ccipdata.OnRampReader, error) { + contractType, version, err := versionFinder.TypeAndVersion(onRampAddress, source) + if err != nil { + return nil, errors.Wrapf(err, "unable to read type and version") + } + if contractType != ccipconfig.EVM2EVMOnRamp { + return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOnRamp, contractType) + } + + onRampAddrEvm, err := ccipcalc.GenericAddrToEvm(onRampAddress) + if err != nil { + return nil, err + } + + lggr.Infof("Initializing onRamp for version %v", version.String()) + + switch version.String() { + case ccipdata.V1_0_0: + onRamp, err := v1_0_0.NewOnRamp(lggr, sourceSelector, destSelector, onRampAddrEvm, sourceLP, source) + if err != nil { + return nil, err + } + if closeReader { + return nil, onRamp.Close() + } + return onRamp, onRamp.RegisterFilters() + case ccipdata.V1_1_0: + onRamp, err := v1_1_0.NewOnRamp(lggr, sourceSelector, destSelector, onRampAddrEvm, sourceLP, source) + if err != nil { + return nil, err + } + if closeReader { + return nil, onRamp.Close() + } + return onRamp, onRamp.RegisterFilters() + case ccipdata.V1_2_0: + onRamp, err := v1_2_0.NewOnRamp(lggr, sourceSelector, destSelector, onRampAddrEvm, sourceLP, source) + if err != nil { + return nil, err + } + if closeReader { + return nil, onRamp.Close() + } + return onRamp, onRamp.RegisterFilters() + case ccipdata.V1_5_0: + onRamp, err := v1_5_0.NewOnRamp(lggr, sourceSelector, destSelector, onRampAddrEvm, sourceLP, source) + if err != nil { + return nil, err + } + if closeReader { + return nil, onRamp.Close() + } + return onRamp, onRamp.RegisterFilters() + // Adding a new version? + // Please update the public factory function in leafer.go if the new version updates the leaf hash function. + default: + return nil, errors.Errorf("unsupported onramp version %v", version.String()) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp_test.go new file mode 100644 index 0000000000..8cf47ddc7b --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp_test.go @@ -0,0 +1,45 @@ +package factory + +import ( + "testing" + + "github.com/Masterminds/semver/v3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + mocks2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +func TestOnRamp(t *testing.T) { + for _, versionStr := range []string{ccipdata.V1_0_0, ccipdata.V1_1_0, ccipdata.V1_2_0, ccipdata.V1_5_0} { + lggr := logger.TestLogger(t) + addr := cciptypes.Address(utils.RandomAddress().String()) + lp := mocks2.NewLogPoller(t) + + sourceSelector := uint64(1000) + destSelector := uint64(2000) + + expFilterNames := []string{ + logpoller.FilterName(ccipdata.COMMIT_CCIP_SENDS, addr), + logpoller.FilterName(ccipdata.CONFIG_CHANGED, addr), + } + versionFinder := newMockVersionFinder(ccipconfig.EVM2EVMOnRamp, *semver.MustParse(versionStr), nil) + + lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil).Times(len(expFilterNames)) + _, err := NewOnRampReader(lggr, versionFinder, sourceSelector, destSelector, addr, lp, nil) + assert.NoError(t, err) + + for _, f := range expFilterNames { + lp.On("UnregisterFilter", mock.Anything, f).Return(nil) + } + err = CloseOnRampReader(lggr, versionFinder, sourceSelector, destSelector, addr, lp, nil) + assert.NoError(t, err) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry.go new file mode 100644 index 0000000000..f1fa7c4e81 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry.go @@ -0,0 +1,82 @@ +package factory + +import ( + "context" + + "github.com/pkg/errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/logger" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" +) + +// NewPriceRegistryReader determines the appropriate version of the price registry and returns a reader for it. +func NewPriceRegistryReader(ctx context.Context, lggr logger.Logger, versionFinder VersionFinder, priceRegistryAddress cciptypes.Address, lp logpoller.LogPoller, cl client.Client) (ccipdata.PriceRegistryReader, error) { + return initOrClosePriceRegistryReader(ctx, lggr, versionFinder, priceRegistryAddress, lp, cl, false) +} + +func ClosePriceRegistryReader(ctx context.Context, lggr logger.Logger, versionFinder VersionFinder, priceRegistryAddress cciptypes.Address, lp logpoller.LogPoller, cl client.Client) error { + _, err := initOrClosePriceRegistryReader(ctx, lggr, versionFinder, priceRegistryAddress, lp, cl, true) + return err +} + +func initOrClosePriceRegistryReader(ctx context.Context, lggr logger.Logger, versionFinder VersionFinder, priceRegistryAddress cciptypes.Address, lp logpoller.LogPoller, cl client.Client, closeReader bool) (ccipdata.PriceRegistryReader, error) { + registerFilters := !closeReader + + priceRegistryEvmAddr, err := ccipcalc.GenericAddrToEvm(priceRegistryAddress) + if err != nil { + return nil, err + } + + contractType, version, err := versionFinder.TypeAndVersion(priceRegistryAddress, cl) + isV1_0_0 := ccipcommon.IsTxRevertError(err) || (contractType == ccipconfig.PriceRegistry && version.String() == ccipdata.V1_0_0) + if isV1_0_0 { + lggr.Infof("Assuming %v is 1.0.0 price registry, got %v", priceRegistryEvmAddr, err) + // Unfortunately the v1 price registry doesn't have a method to get the version so assume if it reverts its v1. + pr, err2 := v1_0_0.NewPriceRegistry(lggr, priceRegistryEvmAddr, lp, cl, registerFilters) + if err2 != nil { + return nil, err2 + } + if closeReader { + return nil, pr.Close() + } + return pr, nil + } + if err != nil { + return nil, errors.Wrapf(err, "unable to read type and version") + } + + if contractType != ccipconfig.PriceRegistry { + return nil, errors.Errorf("expected %v got %v", ccipconfig.PriceRegistry, contractType) + } + switch version.String() { + case ccipdata.V1_2_0: + pr, err := v1_2_0.NewPriceRegistry(lggr, priceRegistryEvmAddr, lp, cl, registerFilters) + if err != nil { + return nil, err + } + if closeReader { + return nil, pr.Close() + } + return pr, nil + case ccipdata.V1_6_0: + pr, err := v1_2_0.NewPriceRegistry(lggr, priceRegistryEvmAddr, lp, cl, registerFilters) + if err != nil { + return nil, err + } + if closeReader { + return nil, pr.Close() + } + return pr, nil + default: + return nil, errors.Errorf("unsupported price registry version %v", version.String()) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry_test.go new file mode 100644 index 0000000000..b4a9d30714 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry_test.go @@ -0,0 +1,46 @@ +package factory + +import ( + "testing" + + "github.com/Masterminds/semver/v3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + mocks2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +func TestPriceRegistry(t *testing.T) { + ctx := testutils.Context(t) + + for _, versionStr := range []string{ccipdata.V1_0_0, ccipdata.V1_2_0} { + lggr := logger.TestLogger(t) + addr := cciptypes.Address(utils.RandomAddress().String()) + lp := mocks2.NewLogPoller(t) + + expFilterNames := []string{ + logpoller.FilterName(ccipdata.COMMIT_PRICE_UPDATES, addr), + logpoller.FilterName(ccipdata.FEE_TOKEN_ADDED, addr), + logpoller.FilterName(ccipdata.FEE_TOKEN_REMOVED, addr), + } + versionFinder := newMockVersionFinder(ccipconfig.PriceRegistry, *semver.MustParse(versionStr), nil) + + lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil).Times(len(expFilterNames)) + _, err := NewPriceRegistryReader(ctx, lggr, versionFinder, addr, lp, nil) + assert.NoError(t, err) + + for _, f := range expFilterNames { + lp.On("UnregisterFilter", mock.Anything, f).Return(nil) + } + err = ClosePriceRegistryReader(ctx, lggr, versionFinder, addr, lp, nil) + assert.NoError(t, err) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/versionfinder.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/versionfinder.go new file mode 100644 index 0000000000..ac16fc4df2 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/versionfinder.go @@ -0,0 +1,44 @@ +package factory + +import ( + "github.com/Masterminds/semver/v3" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +// VersionFinder accepts a contract address and a client and performs an on-chain call to +// determine the contract type. +type VersionFinder interface { + TypeAndVersion(addr cciptypes.Address, client bind.ContractBackend) (config.ContractType, semver.Version, error) +} + +type EvmVersionFinder struct{} + +func NewEvmVersionFinder() EvmVersionFinder { + return EvmVersionFinder{} +} + +func (e EvmVersionFinder) TypeAndVersion(addr cciptypes.Address, client bind.ContractBackend) (config.ContractType, semver.Version, error) { + evmAddr, err := ccipcalc.GenericAddrToEvm(addr) + if err != nil { + return "", semver.Version{}, err + } + return config.TypeAndVersion(evmAddr, client) +} + +type mockVersionFinder struct { + typ config.ContractType + version semver.Version + err error +} + +func newMockVersionFinder(typ config.ContractType, version semver.Version, err error) *mockVersionFinder { + return &mockVersionFinder{typ: typ, version: version, err: err} +} + +func (m mockVersionFinder) TypeAndVersion(addr cciptypes.Address, client bind.ContractBackend) (config.ContractType, semver.Version, error) { + return m.typ, m.version, m.err +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/commit_store_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/commit_store_reader_mock.go new file mode 100644 index 0000000000..f383a87a8a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/commit_store_reader_mock.go @@ -0,0 +1,985 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + big "math/big" + + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + context "context" + + gas "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + + mock "github.com/stretchr/testify/mock" + + time "time" +) + +// CommitStoreReader is an autogenerated mock type for the CommitStoreReader type +type CommitStoreReader struct { + mock.Mock +} + +type CommitStoreReader_Expecter struct { + mock *mock.Mock +} + +func (_m *CommitStoreReader) EXPECT() *CommitStoreReader_Expecter { + return &CommitStoreReader_Expecter{mock: &_m.Mock} +} + +// ChangeConfig provides a mock function with given fields: ctx, onchainConfig, offchainConfig +func (_m *CommitStoreReader) ChangeConfig(ctx context.Context, onchainConfig []byte, offchainConfig []byte) (ccip.Address, error) { + ret := _m.Called(ctx, onchainConfig, offchainConfig) + + if len(ret) == 0 { + panic("no return value specified for ChangeConfig") + } + + var r0 ccip.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []byte, []byte) (ccip.Address, error)); ok { + return rf(ctx, onchainConfig, offchainConfig) + } + if rf, ok := ret.Get(0).(func(context.Context, []byte, []byte) ccip.Address); ok { + r0 = rf(ctx, onchainConfig, offchainConfig) + } else { + r0 = ret.Get(0).(ccip.Address) + } + + if rf, ok := ret.Get(1).(func(context.Context, []byte, []byte) error); ok { + r1 = rf(ctx, onchainConfig, offchainConfig) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_ChangeConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ChangeConfig' +type CommitStoreReader_ChangeConfig_Call struct { + *mock.Call +} + +// ChangeConfig is a helper method to define mock.On call +// - ctx context.Context +// - onchainConfig []byte +// - offchainConfig []byte +func (_e *CommitStoreReader_Expecter) ChangeConfig(ctx interface{}, onchainConfig interface{}, offchainConfig interface{}) *CommitStoreReader_ChangeConfig_Call { + return &CommitStoreReader_ChangeConfig_Call{Call: _e.mock.On("ChangeConfig", ctx, onchainConfig, offchainConfig)} +} + +func (_c *CommitStoreReader_ChangeConfig_Call) Run(run func(ctx context.Context, onchainConfig []byte, offchainConfig []byte)) *CommitStoreReader_ChangeConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]byte), args[2].([]byte)) + }) + return _c +} + +func (_c *CommitStoreReader_ChangeConfig_Call) Return(_a0 ccip.Address, _a1 error) *CommitStoreReader_ChangeConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_ChangeConfig_Call) RunAndReturn(run func(context.Context, []byte, []byte) (ccip.Address, error)) *CommitStoreReader_ChangeConfig_Call { + _c.Call.Return(run) + return _c +} + +// Close provides a mock function with given fields: +func (_m *CommitStoreReader) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CommitStoreReader_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type CommitStoreReader_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *CommitStoreReader_Expecter) Close() *CommitStoreReader_Close_Call { + return &CommitStoreReader_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *CommitStoreReader_Close_Call) Run(run func()) *CommitStoreReader_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *CommitStoreReader_Close_Call) Return(_a0 error) *CommitStoreReader_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *CommitStoreReader_Close_Call) RunAndReturn(run func() error) *CommitStoreReader_Close_Call { + _c.Call.Return(run) + return _c +} + +// DecodeCommitReport provides a mock function with given fields: ctx, report +func (_m *CommitStoreReader) DecodeCommitReport(ctx context.Context, report []byte) (ccip.CommitStoreReport, error) { + ret := _m.Called(ctx, report) + + if len(ret) == 0 { + panic("no return value specified for DecodeCommitReport") + } + + var r0 ccip.CommitStoreReport + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []byte) (ccip.CommitStoreReport, error)); ok { + return rf(ctx, report) + } + if rf, ok := ret.Get(0).(func(context.Context, []byte) ccip.CommitStoreReport); ok { + r0 = rf(ctx, report) + } else { + r0 = ret.Get(0).(ccip.CommitStoreReport) + } + + if rf, ok := ret.Get(1).(func(context.Context, []byte) error); ok { + r1 = rf(ctx, report) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_DecodeCommitReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DecodeCommitReport' +type CommitStoreReader_DecodeCommitReport_Call struct { + *mock.Call +} + +// DecodeCommitReport is a helper method to define mock.On call +// - ctx context.Context +// - report []byte +func (_e *CommitStoreReader_Expecter) DecodeCommitReport(ctx interface{}, report interface{}) *CommitStoreReader_DecodeCommitReport_Call { + return &CommitStoreReader_DecodeCommitReport_Call{Call: _e.mock.On("DecodeCommitReport", ctx, report)} +} + +func (_c *CommitStoreReader_DecodeCommitReport_Call) Run(run func(ctx context.Context, report []byte)) *CommitStoreReader_DecodeCommitReport_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]byte)) + }) + return _c +} + +func (_c *CommitStoreReader_DecodeCommitReport_Call) Return(_a0 ccip.CommitStoreReport, _a1 error) *CommitStoreReader_DecodeCommitReport_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_DecodeCommitReport_Call) RunAndReturn(run func(context.Context, []byte) (ccip.CommitStoreReport, error)) *CommitStoreReader_DecodeCommitReport_Call { + _c.Call.Return(run) + return _c +} + +// EncodeCommitReport provides a mock function with given fields: ctx, report +func (_m *CommitStoreReader) EncodeCommitReport(ctx context.Context, report ccip.CommitStoreReport) ([]byte, error) { + ret := _m.Called(ctx, report) + + if len(ret) == 0 { + panic("no return value specified for EncodeCommitReport") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ccip.CommitStoreReport) ([]byte, error)); ok { + return rf(ctx, report) + } + if rf, ok := ret.Get(0).(func(context.Context, ccip.CommitStoreReport) []byte); ok { + r0 = rf(ctx, report) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, ccip.CommitStoreReport) error); ok { + r1 = rf(ctx, report) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_EncodeCommitReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EncodeCommitReport' +type CommitStoreReader_EncodeCommitReport_Call struct { + *mock.Call +} + +// EncodeCommitReport is a helper method to define mock.On call +// - ctx context.Context +// - report ccip.CommitStoreReport +func (_e *CommitStoreReader_Expecter) EncodeCommitReport(ctx interface{}, report interface{}) *CommitStoreReader_EncodeCommitReport_Call { + return &CommitStoreReader_EncodeCommitReport_Call{Call: _e.mock.On("EncodeCommitReport", ctx, report)} +} + +func (_c *CommitStoreReader_EncodeCommitReport_Call) Run(run func(ctx context.Context, report ccip.CommitStoreReport)) *CommitStoreReader_EncodeCommitReport_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(ccip.CommitStoreReport)) + }) + return _c +} + +func (_c *CommitStoreReader_EncodeCommitReport_Call) Return(_a0 []byte, _a1 error) *CommitStoreReader_EncodeCommitReport_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_EncodeCommitReport_Call) RunAndReturn(run func(context.Context, ccip.CommitStoreReport) ([]byte, error)) *CommitStoreReader_EncodeCommitReport_Call { + _c.Call.Return(run) + return _c +} + +// GasPriceEstimator provides a mock function with given fields: ctx +func (_m *CommitStoreReader) GasPriceEstimator(ctx context.Context) (ccip.GasPriceEstimatorCommit, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GasPriceEstimator") + } + + var r0 ccip.GasPriceEstimatorCommit + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.GasPriceEstimatorCommit, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.GasPriceEstimatorCommit); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(ccip.GasPriceEstimatorCommit) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_GasPriceEstimator_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GasPriceEstimator' +type CommitStoreReader_GasPriceEstimator_Call struct { + *mock.Call +} + +// GasPriceEstimator is a helper method to define mock.On call +// - ctx context.Context +func (_e *CommitStoreReader_Expecter) GasPriceEstimator(ctx interface{}) *CommitStoreReader_GasPriceEstimator_Call { + return &CommitStoreReader_GasPriceEstimator_Call{Call: _e.mock.On("GasPriceEstimator", ctx)} +} + +func (_c *CommitStoreReader_GasPriceEstimator_Call) Run(run func(ctx context.Context)) *CommitStoreReader_GasPriceEstimator_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *CommitStoreReader_GasPriceEstimator_Call) Return(_a0 ccip.GasPriceEstimatorCommit, _a1 error) *CommitStoreReader_GasPriceEstimator_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_GasPriceEstimator_Call) RunAndReturn(run func(context.Context) (ccip.GasPriceEstimatorCommit, error)) *CommitStoreReader_GasPriceEstimator_Call { + _c.Call.Return(run) + return _c +} + +// GetAcceptedCommitReportsGteTimestamp provides a mock function with given fields: ctx, ts, confirmations +func (_m *CommitStoreReader) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confirmations int) ([]ccip.CommitStoreReportWithTxMeta, error) { + ret := _m.Called(ctx, ts, confirmations) + + if len(ret) == 0 { + panic("no return value specified for GetAcceptedCommitReportsGteTimestamp") + } + + var r0 []ccip.CommitStoreReportWithTxMeta + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, time.Time, int) ([]ccip.CommitStoreReportWithTxMeta, error)); ok { + return rf(ctx, ts, confirmations) + } + if rf, ok := ret.Get(0).(func(context.Context, time.Time, int) []ccip.CommitStoreReportWithTxMeta); ok { + r0 = rf(ctx, ts, confirmations) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccip.CommitStoreReportWithTxMeta) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, time.Time, int) error); ok { + r1 = rf(ctx, ts, confirmations) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_GetAcceptedCommitReportsGteTimestamp_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAcceptedCommitReportsGteTimestamp' +type CommitStoreReader_GetAcceptedCommitReportsGteTimestamp_Call struct { + *mock.Call +} + +// GetAcceptedCommitReportsGteTimestamp is a helper method to define mock.On call +// - ctx context.Context +// - ts time.Time +// - confirmations int +func (_e *CommitStoreReader_Expecter) GetAcceptedCommitReportsGteTimestamp(ctx interface{}, ts interface{}, confirmations interface{}) *CommitStoreReader_GetAcceptedCommitReportsGteTimestamp_Call { + return &CommitStoreReader_GetAcceptedCommitReportsGteTimestamp_Call{Call: _e.mock.On("GetAcceptedCommitReportsGteTimestamp", ctx, ts, confirmations)} +} + +func (_c *CommitStoreReader_GetAcceptedCommitReportsGteTimestamp_Call) Run(run func(ctx context.Context, ts time.Time, confirmations int)) *CommitStoreReader_GetAcceptedCommitReportsGteTimestamp_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(time.Time), args[2].(int)) + }) + return _c +} + +func (_c *CommitStoreReader_GetAcceptedCommitReportsGteTimestamp_Call) Return(_a0 []ccip.CommitStoreReportWithTxMeta, _a1 error) *CommitStoreReader_GetAcceptedCommitReportsGteTimestamp_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_GetAcceptedCommitReportsGteTimestamp_Call) RunAndReturn(run func(context.Context, time.Time, int) ([]ccip.CommitStoreReportWithTxMeta, error)) *CommitStoreReader_GetAcceptedCommitReportsGteTimestamp_Call { + _c.Call.Return(run) + return _c +} + +// GetCommitReportMatchingSeqNum provides a mock function with given fields: ctx, seqNum, confirmations +func (_m *CommitStoreReader) GetCommitReportMatchingSeqNum(ctx context.Context, seqNum uint64, confirmations int) ([]ccip.CommitStoreReportWithTxMeta, error) { + ret := _m.Called(ctx, seqNum, confirmations) + + if len(ret) == 0 { + panic("no return value specified for GetCommitReportMatchingSeqNum") + } + + var r0 []ccip.CommitStoreReportWithTxMeta + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, int) ([]ccip.CommitStoreReportWithTxMeta, error)); ok { + return rf(ctx, seqNum, confirmations) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, int) []ccip.CommitStoreReportWithTxMeta); ok { + r0 = rf(ctx, seqNum, confirmations) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccip.CommitStoreReportWithTxMeta) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, int) error); ok { + r1 = rf(ctx, seqNum, confirmations) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_GetCommitReportMatchingSeqNum_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCommitReportMatchingSeqNum' +type CommitStoreReader_GetCommitReportMatchingSeqNum_Call struct { + *mock.Call +} + +// GetCommitReportMatchingSeqNum is a helper method to define mock.On call +// - ctx context.Context +// - seqNum uint64 +// - confirmations int +func (_e *CommitStoreReader_Expecter) GetCommitReportMatchingSeqNum(ctx interface{}, seqNum interface{}, confirmations interface{}) *CommitStoreReader_GetCommitReportMatchingSeqNum_Call { + return &CommitStoreReader_GetCommitReportMatchingSeqNum_Call{Call: _e.mock.On("GetCommitReportMatchingSeqNum", ctx, seqNum, confirmations)} +} + +func (_c *CommitStoreReader_GetCommitReportMatchingSeqNum_Call) Run(run func(ctx context.Context, seqNum uint64, confirmations int)) *CommitStoreReader_GetCommitReportMatchingSeqNum_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].(int)) + }) + return _c +} + +func (_c *CommitStoreReader_GetCommitReportMatchingSeqNum_Call) Return(_a0 []ccip.CommitStoreReportWithTxMeta, _a1 error) *CommitStoreReader_GetCommitReportMatchingSeqNum_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_GetCommitReportMatchingSeqNum_Call) RunAndReturn(run func(context.Context, uint64, int) ([]ccip.CommitStoreReportWithTxMeta, error)) *CommitStoreReader_GetCommitReportMatchingSeqNum_Call { + _c.Call.Return(run) + return _c +} + +// GetCommitStoreStaticConfig provides a mock function with given fields: ctx +func (_m *CommitStoreReader) GetCommitStoreStaticConfig(ctx context.Context) (ccip.CommitStoreStaticConfig, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetCommitStoreStaticConfig") + } + + var r0 ccip.CommitStoreStaticConfig + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.CommitStoreStaticConfig, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.CommitStoreStaticConfig); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.CommitStoreStaticConfig) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_GetCommitStoreStaticConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCommitStoreStaticConfig' +type CommitStoreReader_GetCommitStoreStaticConfig_Call struct { + *mock.Call +} + +// GetCommitStoreStaticConfig is a helper method to define mock.On call +// - ctx context.Context +func (_e *CommitStoreReader_Expecter) GetCommitStoreStaticConfig(ctx interface{}) *CommitStoreReader_GetCommitStoreStaticConfig_Call { + return &CommitStoreReader_GetCommitStoreStaticConfig_Call{Call: _e.mock.On("GetCommitStoreStaticConfig", ctx)} +} + +func (_c *CommitStoreReader_GetCommitStoreStaticConfig_Call) Run(run func(ctx context.Context)) *CommitStoreReader_GetCommitStoreStaticConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *CommitStoreReader_GetCommitStoreStaticConfig_Call) Return(_a0 ccip.CommitStoreStaticConfig, _a1 error) *CommitStoreReader_GetCommitStoreStaticConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_GetCommitStoreStaticConfig_Call) RunAndReturn(run func(context.Context) (ccip.CommitStoreStaticConfig, error)) *CommitStoreReader_GetCommitStoreStaticConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetExpectedNextSequenceNumber provides a mock function with given fields: ctx +func (_m *CommitStoreReader) GetExpectedNextSequenceNumber(ctx context.Context) (uint64, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetExpectedNextSequenceNumber") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (uint64, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) uint64); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_GetExpectedNextSequenceNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExpectedNextSequenceNumber' +type CommitStoreReader_GetExpectedNextSequenceNumber_Call struct { + *mock.Call +} + +// GetExpectedNextSequenceNumber is a helper method to define mock.On call +// - ctx context.Context +func (_e *CommitStoreReader_Expecter) GetExpectedNextSequenceNumber(ctx interface{}) *CommitStoreReader_GetExpectedNextSequenceNumber_Call { + return &CommitStoreReader_GetExpectedNextSequenceNumber_Call{Call: _e.mock.On("GetExpectedNextSequenceNumber", ctx)} +} + +func (_c *CommitStoreReader_GetExpectedNextSequenceNumber_Call) Run(run func(ctx context.Context)) *CommitStoreReader_GetExpectedNextSequenceNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *CommitStoreReader_GetExpectedNextSequenceNumber_Call) Return(_a0 uint64, _a1 error) *CommitStoreReader_GetExpectedNextSequenceNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_GetExpectedNextSequenceNumber_Call) RunAndReturn(run func(context.Context) (uint64, error)) *CommitStoreReader_GetExpectedNextSequenceNumber_Call { + _c.Call.Return(run) + return _c +} + +// GetLatestPriceEpochAndRound provides a mock function with given fields: ctx +func (_m *CommitStoreReader) GetLatestPriceEpochAndRound(ctx context.Context) (uint64, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetLatestPriceEpochAndRound") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (uint64, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) uint64); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_GetLatestPriceEpochAndRound_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLatestPriceEpochAndRound' +type CommitStoreReader_GetLatestPriceEpochAndRound_Call struct { + *mock.Call +} + +// GetLatestPriceEpochAndRound is a helper method to define mock.On call +// - ctx context.Context +func (_e *CommitStoreReader_Expecter) GetLatestPriceEpochAndRound(ctx interface{}) *CommitStoreReader_GetLatestPriceEpochAndRound_Call { + return &CommitStoreReader_GetLatestPriceEpochAndRound_Call{Call: _e.mock.On("GetLatestPriceEpochAndRound", ctx)} +} + +func (_c *CommitStoreReader_GetLatestPriceEpochAndRound_Call) Run(run func(ctx context.Context)) *CommitStoreReader_GetLatestPriceEpochAndRound_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *CommitStoreReader_GetLatestPriceEpochAndRound_Call) Return(_a0 uint64, _a1 error) *CommitStoreReader_GetLatestPriceEpochAndRound_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_GetLatestPriceEpochAndRound_Call) RunAndReturn(run func(context.Context) (uint64, error)) *CommitStoreReader_GetLatestPriceEpochAndRound_Call { + _c.Call.Return(run) + return _c +} + +// IsBlessed provides a mock function with given fields: ctx, root +func (_m *CommitStoreReader) IsBlessed(ctx context.Context, root [32]byte) (bool, error) { + ret := _m.Called(ctx, root) + + if len(ret) == 0 { + panic("no return value specified for IsBlessed") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, [32]byte) (bool, error)); ok { + return rf(ctx, root) + } + if rf, ok := ret.Get(0).(func(context.Context, [32]byte) bool); ok { + r0 = rf(ctx, root) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context, [32]byte) error); ok { + r1 = rf(ctx, root) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_IsBlessed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsBlessed' +type CommitStoreReader_IsBlessed_Call struct { + *mock.Call +} + +// IsBlessed is a helper method to define mock.On call +// - ctx context.Context +// - root [32]byte +func (_e *CommitStoreReader_Expecter) IsBlessed(ctx interface{}, root interface{}) *CommitStoreReader_IsBlessed_Call { + return &CommitStoreReader_IsBlessed_Call{Call: _e.mock.On("IsBlessed", ctx, root)} +} + +func (_c *CommitStoreReader_IsBlessed_Call) Run(run func(ctx context.Context, root [32]byte)) *CommitStoreReader_IsBlessed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([32]byte)) + }) + return _c +} + +func (_c *CommitStoreReader_IsBlessed_Call) Return(_a0 bool, _a1 error) *CommitStoreReader_IsBlessed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_IsBlessed_Call) RunAndReturn(run func(context.Context, [32]byte) (bool, error)) *CommitStoreReader_IsBlessed_Call { + _c.Call.Return(run) + return _c +} + +// IsDestChainHealthy provides a mock function with given fields: ctx +func (_m *CommitStoreReader) IsDestChainHealthy(ctx context.Context) (bool, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for IsDestChainHealthy") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (bool, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) bool); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_IsDestChainHealthy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsDestChainHealthy' +type CommitStoreReader_IsDestChainHealthy_Call struct { + *mock.Call +} + +// IsDestChainHealthy is a helper method to define mock.On call +// - ctx context.Context +func (_e *CommitStoreReader_Expecter) IsDestChainHealthy(ctx interface{}) *CommitStoreReader_IsDestChainHealthy_Call { + return &CommitStoreReader_IsDestChainHealthy_Call{Call: _e.mock.On("IsDestChainHealthy", ctx)} +} + +func (_c *CommitStoreReader_IsDestChainHealthy_Call) Run(run func(ctx context.Context)) *CommitStoreReader_IsDestChainHealthy_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *CommitStoreReader_IsDestChainHealthy_Call) Return(_a0 bool, _a1 error) *CommitStoreReader_IsDestChainHealthy_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_IsDestChainHealthy_Call) RunAndReturn(run func(context.Context) (bool, error)) *CommitStoreReader_IsDestChainHealthy_Call { + _c.Call.Return(run) + return _c +} + +// IsDown provides a mock function with given fields: ctx +func (_m *CommitStoreReader) IsDown(ctx context.Context) (bool, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for IsDown") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (bool, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) bool); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_IsDown_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsDown' +type CommitStoreReader_IsDown_Call struct { + *mock.Call +} + +// IsDown is a helper method to define mock.On call +// - ctx context.Context +func (_e *CommitStoreReader_Expecter) IsDown(ctx interface{}) *CommitStoreReader_IsDown_Call { + return &CommitStoreReader_IsDown_Call{Call: _e.mock.On("IsDown", ctx)} +} + +func (_c *CommitStoreReader_IsDown_Call) Run(run func(ctx context.Context)) *CommitStoreReader_IsDown_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *CommitStoreReader_IsDown_Call) Return(_a0 bool, _a1 error) *CommitStoreReader_IsDown_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_IsDown_Call) RunAndReturn(run func(context.Context) (bool, error)) *CommitStoreReader_IsDown_Call { + _c.Call.Return(run) + return _c +} + +// OffchainConfig provides a mock function with given fields: ctx +func (_m *CommitStoreReader) OffchainConfig(ctx context.Context) (ccip.CommitOffchainConfig, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for OffchainConfig") + } + + var r0 ccip.CommitOffchainConfig + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.CommitOffchainConfig, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.CommitOffchainConfig); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.CommitOffchainConfig) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_OffchainConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OffchainConfig' +type CommitStoreReader_OffchainConfig_Call struct { + *mock.Call +} + +// OffchainConfig is a helper method to define mock.On call +// - ctx context.Context +func (_e *CommitStoreReader_Expecter) OffchainConfig(ctx interface{}) *CommitStoreReader_OffchainConfig_Call { + return &CommitStoreReader_OffchainConfig_Call{Call: _e.mock.On("OffchainConfig", ctx)} +} + +func (_c *CommitStoreReader_OffchainConfig_Call) Run(run func(ctx context.Context)) *CommitStoreReader_OffchainConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *CommitStoreReader_OffchainConfig_Call) Return(_a0 ccip.CommitOffchainConfig, _a1 error) *CommitStoreReader_OffchainConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_OffchainConfig_Call) RunAndReturn(run func(context.Context) (ccip.CommitOffchainConfig, error)) *CommitStoreReader_OffchainConfig_Call { + _c.Call.Return(run) + return _c +} + +// SetGasEstimator provides a mock function with given fields: ctx, gpe +func (_m *CommitStoreReader) SetGasEstimator(ctx context.Context, gpe gas.EvmFeeEstimator) error { + ret := _m.Called(ctx, gpe) + + if len(ret) == 0 { + panic("no return value specified for SetGasEstimator") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, gas.EvmFeeEstimator) error); ok { + r0 = rf(ctx, gpe) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CommitStoreReader_SetGasEstimator_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetGasEstimator' +type CommitStoreReader_SetGasEstimator_Call struct { + *mock.Call +} + +// SetGasEstimator is a helper method to define mock.On call +// - ctx context.Context +// - gpe gas.EvmFeeEstimator +func (_e *CommitStoreReader_Expecter) SetGasEstimator(ctx interface{}, gpe interface{}) *CommitStoreReader_SetGasEstimator_Call { + return &CommitStoreReader_SetGasEstimator_Call{Call: _e.mock.On("SetGasEstimator", ctx, gpe)} +} + +func (_c *CommitStoreReader_SetGasEstimator_Call) Run(run func(ctx context.Context, gpe gas.EvmFeeEstimator)) *CommitStoreReader_SetGasEstimator_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(gas.EvmFeeEstimator)) + }) + return _c +} + +func (_c *CommitStoreReader_SetGasEstimator_Call) Return(_a0 error) *CommitStoreReader_SetGasEstimator_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *CommitStoreReader_SetGasEstimator_Call) RunAndReturn(run func(context.Context, gas.EvmFeeEstimator) error) *CommitStoreReader_SetGasEstimator_Call { + _c.Call.Return(run) + return _c +} + +// SetSourceMaxGasPrice provides a mock function with given fields: ctx, sourceMaxGasPrice +func (_m *CommitStoreReader) SetSourceMaxGasPrice(ctx context.Context, sourceMaxGasPrice *big.Int) error { + ret := _m.Called(ctx, sourceMaxGasPrice) + + if len(ret) == 0 { + panic("no return value specified for SetSourceMaxGasPrice") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *big.Int) error); ok { + r0 = rf(ctx, sourceMaxGasPrice) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CommitStoreReader_SetSourceMaxGasPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetSourceMaxGasPrice' +type CommitStoreReader_SetSourceMaxGasPrice_Call struct { + *mock.Call +} + +// SetSourceMaxGasPrice is a helper method to define mock.On call +// - ctx context.Context +// - sourceMaxGasPrice *big.Int +func (_e *CommitStoreReader_Expecter) SetSourceMaxGasPrice(ctx interface{}, sourceMaxGasPrice interface{}) *CommitStoreReader_SetSourceMaxGasPrice_Call { + return &CommitStoreReader_SetSourceMaxGasPrice_Call{Call: _e.mock.On("SetSourceMaxGasPrice", ctx, sourceMaxGasPrice)} +} + +func (_c *CommitStoreReader_SetSourceMaxGasPrice_Call) Run(run func(ctx context.Context, sourceMaxGasPrice *big.Int)) *CommitStoreReader_SetSourceMaxGasPrice_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*big.Int)) + }) + return _c +} + +func (_c *CommitStoreReader_SetSourceMaxGasPrice_Call) Return(_a0 error) *CommitStoreReader_SetSourceMaxGasPrice_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *CommitStoreReader_SetSourceMaxGasPrice_Call) RunAndReturn(run func(context.Context, *big.Int) error) *CommitStoreReader_SetSourceMaxGasPrice_Call { + _c.Call.Return(run) + return _c +} + +// VerifyExecutionReport provides a mock function with given fields: ctx, report +func (_m *CommitStoreReader) VerifyExecutionReport(ctx context.Context, report ccip.ExecReport) (bool, error) { + ret := _m.Called(ctx, report) + + if len(ret) == 0 { + panic("no return value specified for VerifyExecutionReport") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ccip.ExecReport) (bool, error)); ok { + return rf(ctx, report) + } + if rf, ok := ret.Get(0).(func(context.Context, ccip.ExecReport) bool); ok { + r0 = rf(ctx, report) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context, ccip.ExecReport) error); ok { + r1 = rf(ctx, report) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitStoreReader_VerifyExecutionReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'VerifyExecutionReport' +type CommitStoreReader_VerifyExecutionReport_Call struct { + *mock.Call +} + +// VerifyExecutionReport is a helper method to define mock.On call +// - ctx context.Context +// - report ccip.ExecReport +func (_e *CommitStoreReader_Expecter) VerifyExecutionReport(ctx interface{}, report interface{}) *CommitStoreReader_VerifyExecutionReport_Call { + return &CommitStoreReader_VerifyExecutionReport_Call{Call: _e.mock.On("VerifyExecutionReport", ctx, report)} +} + +func (_c *CommitStoreReader_VerifyExecutionReport_Call) Run(run func(ctx context.Context, report ccip.ExecReport)) *CommitStoreReader_VerifyExecutionReport_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(ccip.ExecReport)) + }) + return _c +} + +func (_c *CommitStoreReader_VerifyExecutionReport_Call) Return(_a0 bool, _a1 error) *CommitStoreReader_VerifyExecutionReport_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CommitStoreReader_VerifyExecutionReport_Call) RunAndReturn(run func(context.Context, ccip.ExecReport) (bool, error)) *CommitStoreReader_VerifyExecutionReport_Call { + _c.Call.Return(run) + return _c +} + +// NewCommitStoreReader creates a new instance of CommitStoreReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewCommitStoreReader(t interface { + mock.TestingT + Cleanup(func()) +}) *CommitStoreReader { + mock := &CommitStoreReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/offramp_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/offramp_reader_mock.go new file mode 100644 index 0000000000..f383ccdc0b --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/offramp_reader_mock.go @@ -0,0 +1,949 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + context "context" + + mock "github.com/stretchr/testify/mock" +) + +// OffRampReader is an autogenerated mock type for the OffRampReader type +type OffRampReader struct { + mock.Mock +} + +type OffRampReader_Expecter struct { + mock *mock.Mock +} + +func (_m *OffRampReader) EXPECT() *OffRampReader_Expecter { + return &OffRampReader_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: ctx +func (_m *OffRampReader) Address(ctx context.Context) (ccip.Address, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 ccip.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.Address, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.Address); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.Address) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type OffRampReader_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +// - ctx context.Context +func (_e *OffRampReader_Expecter) Address(ctx interface{}) *OffRampReader_Address_Call { + return &OffRampReader_Address_Call{Call: _e.mock.On("Address", ctx)} +} + +func (_c *OffRampReader_Address_Call) Run(run func(ctx context.Context)) *OffRampReader_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OffRampReader_Address_Call) Return(_a0 ccip.Address, _a1 error) *OffRampReader_Address_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_Address_Call) RunAndReturn(run func(context.Context) (ccip.Address, error)) *OffRampReader_Address_Call { + _c.Call.Return(run) + return _c +} + +// ChangeConfig provides a mock function with given fields: ctx, onchainConfig, offchainConfig +func (_m *OffRampReader) ChangeConfig(ctx context.Context, onchainConfig []byte, offchainConfig []byte) (ccip.Address, ccip.Address, error) { + ret := _m.Called(ctx, onchainConfig, offchainConfig) + + if len(ret) == 0 { + panic("no return value specified for ChangeConfig") + } + + var r0 ccip.Address + var r1 ccip.Address + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, []byte, []byte) (ccip.Address, ccip.Address, error)); ok { + return rf(ctx, onchainConfig, offchainConfig) + } + if rf, ok := ret.Get(0).(func(context.Context, []byte, []byte) ccip.Address); ok { + r0 = rf(ctx, onchainConfig, offchainConfig) + } else { + r0 = ret.Get(0).(ccip.Address) + } + + if rf, ok := ret.Get(1).(func(context.Context, []byte, []byte) ccip.Address); ok { + r1 = rf(ctx, onchainConfig, offchainConfig) + } else { + r1 = ret.Get(1).(ccip.Address) + } + + if rf, ok := ret.Get(2).(func(context.Context, []byte, []byte) error); ok { + r2 = rf(ctx, onchainConfig, offchainConfig) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// OffRampReader_ChangeConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ChangeConfig' +type OffRampReader_ChangeConfig_Call struct { + *mock.Call +} + +// ChangeConfig is a helper method to define mock.On call +// - ctx context.Context +// - onchainConfig []byte +// - offchainConfig []byte +func (_e *OffRampReader_Expecter) ChangeConfig(ctx interface{}, onchainConfig interface{}, offchainConfig interface{}) *OffRampReader_ChangeConfig_Call { + return &OffRampReader_ChangeConfig_Call{Call: _e.mock.On("ChangeConfig", ctx, onchainConfig, offchainConfig)} +} + +func (_c *OffRampReader_ChangeConfig_Call) Run(run func(ctx context.Context, onchainConfig []byte, offchainConfig []byte)) *OffRampReader_ChangeConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]byte), args[2].([]byte)) + }) + return _c +} + +func (_c *OffRampReader_ChangeConfig_Call) Return(_a0 ccip.Address, _a1 ccip.Address, _a2 error) *OffRampReader_ChangeConfig_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *OffRampReader_ChangeConfig_Call) RunAndReturn(run func(context.Context, []byte, []byte) (ccip.Address, ccip.Address, error)) *OffRampReader_ChangeConfig_Call { + _c.Call.Return(run) + return _c +} + +// Close provides a mock function with given fields: +func (_m *OffRampReader) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// OffRampReader_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type OffRampReader_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *OffRampReader_Expecter) Close() *OffRampReader_Close_Call { + return &OffRampReader_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *OffRampReader_Close_Call) Run(run func()) *OffRampReader_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *OffRampReader_Close_Call) Return(_a0 error) *OffRampReader_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *OffRampReader_Close_Call) RunAndReturn(run func() error) *OffRampReader_Close_Call { + _c.Call.Return(run) + return _c +} + +// CurrentRateLimiterState provides a mock function with given fields: ctx +func (_m *OffRampReader) CurrentRateLimiterState(ctx context.Context) (ccip.TokenBucketRateLimit, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for CurrentRateLimiterState") + } + + var r0 ccip.TokenBucketRateLimit + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.TokenBucketRateLimit, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.TokenBucketRateLimit); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.TokenBucketRateLimit) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_CurrentRateLimiterState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CurrentRateLimiterState' +type OffRampReader_CurrentRateLimiterState_Call struct { + *mock.Call +} + +// CurrentRateLimiterState is a helper method to define mock.On call +// - ctx context.Context +func (_e *OffRampReader_Expecter) CurrentRateLimiterState(ctx interface{}) *OffRampReader_CurrentRateLimiterState_Call { + return &OffRampReader_CurrentRateLimiterState_Call{Call: _e.mock.On("CurrentRateLimiterState", ctx)} +} + +func (_c *OffRampReader_CurrentRateLimiterState_Call) Run(run func(ctx context.Context)) *OffRampReader_CurrentRateLimiterState_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OffRampReader_CurrentRateLimiterState_Call) Return(_a0 ccip.TokenBucketRateLimit, _a1 error) *OffRampReader_CurrentRateLimiterState_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_CurrentRateLimiterState_Call) RunAndReturn(run func(context.Context) (ccip.TokenBucketRateLimit, error)) *OffRampReader_CurrentRateLimiterState_Call { + _c.Call.Return(run) + return _c +} + +// DecodeExecutionReport provides a mock function with given fields: ctx, report +func (_m *OffRampReader) DecodeExecutionReport(ctx context.Context, report []byte) (ccip.ExecReport, error) { + ret := _m.Called(ctx, report) + + if len(ret) == 0 { + panic("no return value specified for DecodeExecutionReport") + } + + var r0 ccip.ExecReport + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []byte) (ccip.ExecReport, error)); ok { + return rf(ctx, report) + } + if rf, ok := ret.Get(0).(func(context.Context, []byte) ccip.ExecReport); ok { + r0 = rf(ctx, report) + } else { + r0 = ret.Get(0).(ccip.ExecReport) + } + + if rf, ok := ret.Get(1).(func(context.Context, []byte) error); ok { + r1 = rf(ctx, report) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_DecodeExecutionReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DecodeExecutionReport' +type OffRampReader_DecodeExecutionReport_Call struct { + *mock.Call +} + +// DecodeExecutionReport is a helper method to define mock.On call +// - ctx context.Context +// - report []byte +func (_e *OffRampReader_Expecter) DecodeExecutionReport(ctx interface{}, report interface{}) *OffRampReader_DecodeExecutionReport_Call { + return &OffRampReader_DecodeExecutionReport_Call{Call: _e.mock.On("DecodeExecutionReport", ctx, report)} +} + +func (_c *OffRampReader_DecodeExecutionReport_Call) Run(run func(ctx context.Context, report []byte)) *OffRampReader_DecodeExecutionReport_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]byte)) + }) + return _c +} + +func (_c *OffRampReader_DecodeExecutionReport_Call) Return(_a0 ccip.ExecReport, _a1 error) *OffRampReader_DecodeExecutionReport_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_DecodeExecutionReport_Call) RunAndReturn(run func(context.Context, []byte) (ccip.ExecReport, error)) *OffRampReader_DecodeExecutionReport_Call { + _c.Call.Return(run) + return _c +} + +// EncodeExecutionReport provides a mock function with given fields: ctx, report +func (_m *OffRampReader) EncodeExecutionReport(ctx context.Context, report ccip.ExecReport) ([]byte, error) { + ret := _m.Called(ctx, report) + + if len(ret) == 0 { + panic("no return value specified for EncodeExecutionReport") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ccip.ExecReport) ([]byte, error)); ok { + return rf(ctx, report) + } + if rf, ok := ret.Get(0).(func(context.Context, ccip.ExecReport) []byte); ok { + r0 = rf(ctx, report) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, ccip.ExecReport) error); ok { + r1 = rf(ctx, report) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_EncodeExecutionReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EncodeExecutionReport' +type OffRampReader_EncodeExecutionReport_Call struct { + *mock.Call +} + +// EncodeExecutionReport is a helper method to define mock.On call +// - ctx context.Context +// - report ccip.ExecReport +func (_e *OffRampReader_Expecter) EncodeExecutionReport(ctx interface{}, report interface{}) *OffRampReader_EncodeExecutionReport_Call { + return &OffRampReader_EncodeExecutionReport_Call{Call: _e.mock.On("EncodeExecutionReport", ctx, report)} +} + +func (_c *OffRampReader_EncodeExecutionReport_Call) Run(run func(ctx context.Context, report ccip.ExecReport)) *OffRampReader_EncodeExecutionReport_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(ccip.ExecReport)) + }) + return _c +} + +func (_c *OffRampReader_EncodeExecutionReport_Call) Return(_a0 []byte, _a1 error) *OffRampReader_EncodeExecutionReport_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_EncodeExecutionReport_Call) RunAndReturn(run func(context.Context, ccip.ExecReport) ([]byte, error)) *OffRampReader_EncodeExecutionReport_Call { + _c.Call.Return(run) + return _c +} + +// GasPriceEstimator provides a mock function with given fields: ctx +func (_m *OffRampReader) GasPriceEstimator(ctx context.Context) (ccip.GasPriceEstimatorExec, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GasPriceEstimator") + } + + var r0 ccip.GasPriceEstimatorExec + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.GasPriceEstimatorExec, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.GasPriceEstimatorExec); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(ccip.GasPriceEstimatorExec) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_GasPriceEstimator_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GasPriceEstimator' +type OffRampReader_GasPriceEstimator_Call struct { + *mock.Call +} + +// GasPriceEstimator is a helper method to define mock.On call +// - ctx context.Context +func (_e *OffRampReader_Expecter) GasPriceEstimator(ctx interface{}) *OffRampReader_GasPriceEstimator_Call { + return &OffRampReader_GasPriceEstimator_Call{Call: _e.mock.On("GasPriceEstimator", ctx)} +} + +func (_c *OffRampReader_GasPriceEstimator_Call) Run(run func(ctx context.Context)) *OffRampReader_GasPriceEstimator_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OffRampReader_GasPriceEstimator_Call) Return(_a0 ccip.GasPriceEstimatorExec, _a1 error) *OffRampReader_GasPriceEstimator_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_GasPriceEstimator_Call) RunAndReturn(run func(context.Context) (ccip.GasPriceEstimatorExec, error)) *OffRampReader_GasPriceEstimator_Call { + _c.Call.Return(run) + return _c +} + +// GetExecutionState provides a mock function with given fields: ctx, sequenceNumber +func (_m *OffRampReader) GetExecutionState(ctx context.Context, sequenceNumber uint64) (uint8, error) { + ret := _m.Called(ctx, sequenceNumber) + + if len(ret) == 0 { + panic("no return value specified for GetExecutionState") + } + + var r0 uint8 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64) (uint8, error)); ok { + return rf(ctx, sequenceNumber) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64) uint8); ok { + r0 = rf(ctx, sequenceNumber) + } else { + r0 = ret.Get(0).(uint8) + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64) error); ok { + r1 = rf(ctx, sequenceNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_GetExecutionState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExecutionState' +type OffRampReader_GetExecutionState_Call struct { + *mock.Call +} + +// GetExecutionState is a helper method to define mock.On call +// - ctx context.Context +// - sequenceNumber uint64 +func (_e *OffRampReader_Expecter) GetExecutionState(ctx interface{}, sequenceNumber interface{}) *OffRampReader_GetExecutionState_Call { + return &OffRampReader_GetExecutionState_Call{Call: _e.mock.On("GetExecutionState", ctx, sequenceNumber)} +} + +func (_c *OffRampReader_GetExecutionState_Call) Run(run func(ctx context.Context, sequenceNumber uint64)) *OffRampReader_GetExecutionState_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64)) + }) + return _c +} + +func (_c *OffRampReader_GetExecutionState_Call) Return(_a0 uint8, _a1 error) *OffRampReader_GetExecutionState_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_GetExecutionState_Call) RunAndReturn(run func(context.Context, uint64) (uint8, error)) *OffRampReader_GetExecutionState_Call { + _c.Call.Return(run) + return _c +} + +// GetExecutionStateChangesBetweenSeqNums provides a mock function with given fields: ctx, seqNumMin, seqNumMax, confirmations +func (_m *OffRampReader) GetExecutionStateChangesBetweenSeqNums(ctx context.Context, seqNumMin uint64, seqNumMax uint64, confirmations int) ([]ccip.ExecutionStateChangedWithTxMeta, error) { + ret := _m.Called(ctx, seqNumMin, seqNumMax, confirmations) + + if len(ret) == 0 { + panic("no return value specified for GetExecutionStateChangesBetweenSeqNums") + } + + var r0 []ccip.ExecutionStateChangedWithTxMeta + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, int) ([]ccip.ExecutionStateChangedWithTxMeta, error)); ok { + return rf(ctx, seqNumMin, seqNumMax, confirmations) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, int) []ccip.ExecutionStateChangedWithTxMeta); ok { + r0 = rf(ctx, seqNumMin, seqNumMax, confirmations) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccip.ExecutionStateChangedWithTxMeta) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, uint64, int) error); ok { + r1 = rf(ctx, seqNumMin, seqNumMax, confirmations) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_GetExecutionStateChangesBetweenSeqNums_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExecutionStateChangesBetweenSeqNums' +type OffRampReader_GetExecutionStateChangesBetweenSeqNums_Call struct { + *mock.Call +} + +// GetExecutionStateChangesBetweenSeqNums is a helper method to define mock.On call +// - ctx context.Context +// - seqNumMin uint64 +// - seqNumMax uint64 +// - confirmations int +func (_e *OffRampReader_Expecter) GetExecutionStateChangesBetweenSeqNums(ctx interface{}, seqNumMin interface{}, seqNumMax interface{}, confirmations interface{}) *OffRampReader_GetExecutionStateChangesBetweenSeqNums_Call { + return &OffRampReader_GetExecutionStateChangesBetweenSeqNums_Call{Call: _e.mock.On("GetExecutionStateChangesBetweenSeqNums", ctx, seqNumMin, seqNumMax, confirmations)} +} + +func (_c *OffRampReader_GetExecutionStateChangesBetweenSeqNums_Call) Run(run func(ctx context.Context, seqNumMin uint64, seqNumMax uint64, confirmations int)) *OffRampReader_GetExecutionStateChangesBetweenSeqNums_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].(uint64), args[3].(int)) + }) + return _c +} + +func (_c *OffRampReader_GetExecutionStateChangesBetweenSeqNums_Call) Return(_a0 []ccip.ExecutionStateChangedWithTxMeta, _a1 error) *OffRampReader_GetExecutionStateChangesBetweenSeqNums_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_GetExecutionStateChangesBetweenSeqNums_Call) RunAndReturn(run func(context.Context, uint64, uint64, int) ([]ccip.ExecutionStateChangedWithTxMeta, error)) *OffRampReader_GetExecutionStateChangesBetweenSeqNums_Call { + _c.Call.Return(run) + return _c +} + +// GetRouter provides a mock function with given fields: ctx +func (_m *OffRampReader) GetRouter(ctx context.Context) (ccip.Address, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetRouter") + } + + var r0 ccip.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.Address, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.Address); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.Address) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_GetRouter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRouter' +type OffRampReader_GetRouter_Call struct { + *mock.Call +} + +// GetRouter is a helper method to define mock.On call +// - ctx context.Context +func (_e *OffRampReader_Expecter) GetRouter(ctx interface{}) *OffRampReader_GetRouter_Call { + return &OffRampReader_GetRouter_Call{Call: _e.mock.On("GetRouter", ctx)} +} + +func (_c *OffRampReader_GetRouter_Call) Run(run func(ctx context.Context)) *OffRampReader_GetRouter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OffRampReader_GetRouter_Call) Return(_a0 ccip.Address, _a1 error) *OffRampReader_GetRouter_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_GetRouter_Call) RunAndReturn(run func(context.Context) (ccip.Address, error)) *OffRampReader_GetRouter_Call { + _c.Call.Return(run) + return _c +} + +// GetSourceToDestTokensMapping provides a mock function with given fields: ctx +func (_m *OffRampReader) GetSourceToDestTokensMapping(ctx context.Context) (map[ccip.Address]ccip.Address, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetSourceToDestTokensMapping") + } + + var r0 map[ccip.Address]ccip.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (map[ccip.Address]ccip.Address, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) map[ccip.Address]ccip.Address); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[ccip.Address]ccip.Address) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_GetSourceToDestTokensMapping_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSourceToDestTokensMapping' +type OffRampReader_GetSourceToDestTokensMapping_Call struct { + *mock.Call +} + +// GetSourceToDestTokensMapping is a helper method to define mock.On call +// - ctx context.Context +func (_e *OffRampReader_Expecter) GetSourceToDestTokensMapping(ctx interface{}) *OffRampReader_GetSourceToDestTokensMapping_Call { + return &OffRampReader_GetSourceToDestTokensMapping_Call{Call: _e.mock.On("GetSourceToDestTokensMapping", ctx)} +} + +func (_c *OffRampReader_GetSourceToDestTokensMapping_Call) Run(run func(ctx context.Context)) *OffRampReader_GetSourceToDestTokensMapping_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OffRampReader_GetSourceToDestTokensMapping_Call) Return(_a0 map[ccip.Address]ccip.Address, _a1 error) *OffRampReader_GetSourceToDestTokensMapping_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_GetSourceToDestTokensMapping_Call) RunAndReturn(run func(context.Context) (map[ccip.Address]ccip.Address, error)) *OffRampReader_GetSourceToDestTokensMapping_Call { + _c.Call.Return(run) + return _c +} + +// GetStaticConfig provides a mock function with given fields: ctx +func (_m *OffRampReader) GetStaticConfig(ctx context.Context) (ccip.OffRampStaticConfig, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetStaticConfig") + } + + var r0 ccip.OffRampStaticConfig + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.OffRampStaticConfig, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.OffRampStaticConfig); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.OffRampStaticConfig) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_GetStaticConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStaticConfig' +type OffRampReader_GetStaticConfig_Call struct { + *mock.Call +} + +// GetStaticConfig is a helper method to define mock.On call +// - ctx context.Context +func (_e *OffRampReader_Expecter) GetStaticConfig(ctx interface{}) *OffRampReader_GetStaticConfig_Call { + return &OffRampReader_GetStaticConfig_Call{Call: _e.mock.On("GetStaticConfig", ctx)} +} + +func (_c *OffRampReader_GetStaticConfig_Call) Run(run func(ctx context.Context)) *OffRampReader_GetStaticConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OffRampReader_GetStaticConfig_Call) Return(_a0 ccip.OffRampStaticConfig, _a1 error) *OffRampReader_GetStaticConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_GetStaticConfig_Call) RunAndReturn(run func(context.Context) (ccip.OffRampStaticConfig, error)) *OffRampReader_GetStaticConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetTokens provides a mock function with given fields: ctx +func (_m *OffRampReader) GetTokens(ctx context.Context) (ccip.OffRampTokens, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetTokens") + } + + var r0 ccip.OffRampTokens + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.OffRampTokens, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.OffRampTokens); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.OffRampTokens) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_GetTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokens' +type OffRampReader_GetTokens_Call struct { + *mock.Call +} + +// GetTokens is a helper method to define mock.On call +// - ctx context.Context +func (_e *OffRampReader_Expecter) GetTokens(ctx interface{}) *OffRampReader_GetTokens_Call { + return &OffRampReader_GetTokens_Call{Call: _e.mock.On("GetTokens", ctx)} +} + +func (_c *OffRampReader_GetTokens_Call) Run(run func(ctx context.Context)) *OffRampReader_GetTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OffRampReader_GetTokens_Call) Return(_a0 ccip.OffRampTokens, _a1 error) *OffRampReader_GetTokens_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_GetTokens_Call) RunAndReturn(run func(context.Context) (ccip.OffRampTokens, error)) *OffRampReader_GetTokens_Call { + _c.Call.Return(run) + return _c +} + +// ListSenderNonces provides a mock function with given fields: ctx, senders +func (_m *OffRampReader) ListSenderNonces(ctx context.Context, senders []ccip.Address) (map[ccip.Address]uint64, error) { + ret := _m.Called(ctx, senders) + + if len(ret) == 0 { + panic("no return value specified for ListSenderNonces") + } + + var r0 map[ccip.Address]uint64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) (map[ccip.Address]uint64, error)); ok { + return rf(ctx, senders) + } + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) map[ccip.Address]uint64); ok { + r0 = rf(ctx, senders) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[ccip.Address]uint64) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []ccip.Address) error); ok { + r1 = rf(ctx, senders) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_ListSenderNonces_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListSenderNonces' +type OffRampReader_ListSenderNonces_Call struct { + *mock.Call +} + +// ListSenderNonces is a helper method to define mock.On call +// - ctx context.Context +// - senders []ccip.Address +func (_e *OffRampReader_Expecter) ListSenderNonces(ctx interface{}, senders interface{}) *OffRampReader_ListSenderNonces_Call { + return &OffRampReader_ListSenderNonces_Call{Call: _e.mock.On("ListSenderNonces", ctx, senders)} +} + +func (_c *OffRampReader_ListSenderNonces_Call) Run(run func(ctx context.Context, senders []ccip.Address)) *OffRampReader_ListSenderNonces_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]ccip.Address)) + }) + return _c +} + +func (_c *OffRampReader_ListSenderNonces_Call) Return(_a0 map[ccip.Address]uint64, _a1 error) *OffRampReader_ListSenderNonces_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_ListSenderNonces_Call) RunAndReturn(run func(context.Context, []ccip.Address) (map[ccip.Address]uint64, error)) *OffRampReader_ListSenderNonces_Call { + _c.Call.Return(run) + return _c +} + +// OffchainConfig provides a mock function with given fields: ctx +func (_m *OffRampReader) OffchainConfig(ctx context.Context) (ccip.ExecOffchainConfig, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for OffchainConfig") + } + + var r0 ccip.ExecOffchainConfig + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.ExecOffchainConfig, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.ExecOffchainConfig); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.ExecOffchainConfig) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_OffchainConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OffchainConfig' +type OffRampReader_OffchainConfig_Call struct { + *mock.Call +} + +// OffchainConfig is a helper method to define mock.On call +// - ctx context.Context +func (_e *OffRampReader_Expecter) OffchainConfig(ctx interface{}) *OffRampReader_OffchainConfig_Call { + return &OffRampReader_OffchainConfig_Call{Call: _e.mock.On("OffchainConfig", ctx)} +} + +func (_c *OffRampReader_OffchainConfig_Call) Run(run func(ctx context.Context)) *OffRampReader_OffchainConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OffRampReader_OffchainConfig_Call) Return(_a0 ccip.ExecOffchainConfig, _a1 error) *OffRampReader_OffchainConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_OffchainConfig_Call) RunAndReturn(run func(context.Context) (ccip.ExecOffchainConfig, error)) *OffRampReader_OffchainConfig_Call { + _c.Call.Return(run) + return _c +} + +// OnchainConfig provides a mock function with given fields: ctx +func (_m *OffRampReader) OnchainConfig(ctx context.Context) (ccip.ExecOnchainConfig, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for OnchainConfig") + } + + var r0 ccip.ExecOnchainConfig + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.ExecOnchainConfig, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.ExecOnchainConfig); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.ExecOnchainConfig) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffRampReader_OnchainConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OnchainConfig' +type OffRampReader_OnchainConfig_Call struct { + *mock.Call +} + +// OnchainConfig is a helper method to define mock.On call +// - ctx context.Context +func (_e *OffRampReader_Expecter) OnchainConfig(ctx interface{}) *OffRampReader_OnchainConfig_Call { + return &OffRampReader_OnchainConfig_Call{Call: _e.mock.On("OnchainConfig", ctx)} +} + +func (_c *OffRampReader_OnchainConfig_Call) Run(run func(ctx context.Context)) *OffRampReader_OnchainConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OffRampReader_OnchainConfig_Call) Return(_a0 ccip.ExecOnchainConfig, _a1 error) *OffRampReader_OnchainConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OffRampReader_OnchainConfig_Call) RunAndReturn(run func(context.Context) (ccip.ExecOnchainConfig, error)) *OffRampReader_OnchainConfig_Call { + _c.Call.Return(run) + return _c +} + +// NewOffRampReader creates a new instance of OffRampReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewOffRampReader(t interface { + mock.TestingT + Cleanup(func()) +}) *OffRampReader { + mock := &OffRampReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/onramp_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/onramp_reader_mock.go new file mode 100644 index 0000000000..ccf5bd7846 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/onramp_reader_mock.go @@ -0,0 +1,480 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + context "context" + + mock "github.com/stretchr/testify/mock" +) + +// OnRampReader is an autogenerated mock type for the OnRampReader type +type OnRampReader struct { + mock.Mock +} + +type OnRampReader_Expecter struct { + mock *mock.Mock +} + +func (_m *OnRampReader) EXPECT() *OnRampReader_Expecter { + return &OnRampReader_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: ctx +func (_m *OnRampReader) Address(ctx context.Context) (ccip.Address, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 ccip.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.Address, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.Address); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.Address) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OnRampReader_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type OnRampReader_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +// - ctx context.Context +func (_e *OnRampReader_Expecter) Address(ctx interface{}) *OnRampReader_Address_Call { + return &OnRampReader_Address_Call{Call: _e.mock.On("Address", ctx)} +} + +func (_c *OnRampReader_Address_Call) Run(run func(ctx context.Context)) *OnRampReader_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OnRampReader_Address_Call) Return(_a0 ccip.Address, _a1 error) *OnRampReader_Address_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OnRampReader_Address_Call) RunAndReturn(run func(context.Context) (ccip.Address, error)) *OnRampReader_Address_Call { + _c.Call.Return(run) + return _c +} + +// Close provides a mock function with given fields: +func (_m *OnRampReader) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// OnRampReader_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type OnRampReader_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *OnRampReader_Expecter) Close() *OnRampReader_Close_Call { + return &OnRampReader_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *OnRampReader_Close_Call) Run(run func()) *OnRampReader_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *OnRampReader_Close_Call) Return(_a0 error) *OnRampReader_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *OnRampReader_Close_Call) RunAndReturn(run func() error) *OnRampReader_Close_Call { + _c.Call.Return(run) + return _c +} + +// GetDynamicConfig provides a mock function with given fields: ctx +func (_m *OnRampReader) GetDynamicConfig(ctx context.Context) (ccip.OnRampDynamicConfig, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetDynamicConfig") + } + + var r0 ccip.OnRampDynamicConfig + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.OnRampDynamicConfig, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.OnRampDynamicConfig); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.OnRampDynamicConfig) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OnRampReader_GetDynamicConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDynamicConfig' +type OnRampReader_GetDynamicConfig_Call struct { + *mock.Call +} + +// GetDynamicConfig is a helper method to define mock.On call +// - ctx context.Context +func (_e *OnRampReader_Expecter) GetDynamicConfig(ctx interface{}) *OnRampReader_GetDynamicConfig_Call { + return &OnRampReader_GetDynamicConfig_Call{Call: _e.mock.On("GetDynamicConfig", ctx)} +} + +func (_c *OnRampReader_GetDynamicConfig_Call) Run(run func(ctx context.Context)) *OnRampReader_GetDynamicConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OnRampReader_GetDynamicConfig_Call) Return(_a0 ccip.OnRampDynamicConfig, _a1 error) *OnRampReader_GetDynamicConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OnRampReader_GetDynamicConfig_Call) RunAndReturn(run func(context.Context) (ccip.OnRampDynamicConfig, error)) *OnRampReader_GetDynamicConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetSendRequestsBetweenSeqNums provides a mock function with given fields: ctx, seqNumMin, seqNumMax, finalized +func (_m *OnRampReader) GetSendRequestsBetweenSeqNums(ctx context.Context, seqNumMin uint64, seqNumMax uint64, finalized bool) ([]ccip.EVM2EVMMessageWithTxMeta, error) { + ret := _m.Called(ctx, seqNumMin, seqNumMax, finalized) + + if len(ret) == 0 { + panic("no return value specified for GetSendRequestsBetweenSeqNums") + } + + var r0 []ccip.EVM2EVMMessageWithTxMeta + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, bool) ([]ccip.EVM2EVMMessageWithTxMeta, error)); ok { + return rf(ctx, seqNumMin, seqNumMax, finalized) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, bool) []ccip.EVM2EVMMessageWithTxMeta); ok { + r0 = rf(ctx, seqNumMin, seqNumMax, finalized) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccip.EVM2EVMMessageWithTxMeta) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, uint64, bool) error); ok { + r1 = rf(ctx, seqNumMin, seqNumMax, finalized) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OnRampReader_GetSendRequestsBetweenSeqNums_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSendRequestsBetweenSeqNums' +type OnRampReader_GetSendRequestsBetweenSeqNums_Call struct { + *mock.Call +} + +// GetSendRequestsBetweenSeqNums is a helper method to define mock.On call +// - ctx context.Context +// - seqNumMin uint64 +// - seqNumMax uint64 +// - finalized bool +func (_e *OnRampReader_Expecter) GetSendRequestsBetweenSeqNums(ctx interface{}, seqNumMin interface{}, seqNumMax interface{}, finalized interface{}) *OnRampReader_GetSendRequestsBetweenSeqNums_Call { + return &OnRampReader_GetSendRequestsBetweenSeqNums_Call{Call: _e.mock.On("GetSendRequestsBetweenSeqNums", ctx, seqNumMin, seqNumMax, finalized)} +} + +func (_c *OnRampReader_GetSendRequestsBetweenSeqNums_Call) Run(run func(ctx context.Context, seqNumMin uint64, seqNumMax uint64, finalized bool)) *OnRampReader_GetSendRequestsBetweenSeqNums_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].(uint64), args[3].(bool)) + }) + return _c +} + +func (_c *OnRampReader_GetSendRequestsBetweenSeqNums_Call) Return(_a0 []ccip.EVM2EVMMessageWithTxMeta, _a1 error) *OnRampReader_GetSendRequestsBetweenSeqNums_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OnRampReader_GetSendRequestsBetweenSeqNums_Call) RunAndReturn(run func(context.Context, uint64, uint64, bool) ([]ccip.EVM2EVMMessageWithTxMeta, error)) *OnRampReader_GetSendRequestsBetweenSeqNums_Call { + _c.Call.Return(run) + return _c +} + +// IsSourceChainHealthy provides a mock function with given fields: ctx +func (_m *OnRampReader) IsSourceChainHealthy(ctx context.Context) (bool, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for IsSourceChainHealthy") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (bool, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) bool); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OnRampReader_IsSourceChainHealthy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsSourceChainHealthy' +type OnRampReader_IsSourceChainHealthy_Call struct { + *mock.Call +} + +// IsSourceChainHealthy is a helper method to define mock.On call +// - ctx context.Context +func (_e *OnRampReader_Expecter) IsSourceChainHealthy(ctx interface{}) *OnRampReader_IsSourceChainHealthy_Call { + return &OnRampReader_IsSourceChainHealthy_Call{Call: _e.mock.On("IsSourceChainHealthy", ctx)} +} + +func (_c *OnRampReader_IsSourceChainHealthy_Call) Run(run func(ctx context.Context)) *OnRampReader_IsSourceChainHealthy_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OnRampReader_IsSourceChainHealthy_Call) Return(_a0 bool, _a1 error) *OnRampReader_IsSourceChainHealthy_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OnRampReader_IsSourceChainHealthy_Call) RunAndReturn(run func(context.Context) (bool, error)) *OnRampReader_IsSourceChainHealthy_Call { + _c.Call.Return(run) + return _c +} + +// IsSourceCursed provides a mock function with given fields: ctx +func (_m *OnRampReader) IsSourceCursed(ctx context.Context) (bool, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for IsSourceCursed") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (bool, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) bool); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OnRampReader_IsSourceCursed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsSourceCursed' +type OnRampReader_IsSourceCursed_Call struct { + *mock.Call +} + +// IsSourceCursed is a helper method to define mock.On call +// - ctx context.Context +func (_e *OnRampReader_Expecter) IsSourceCursed(ctx interface{}) *OnRampReader_IsSourceCursed_Call { + return &OnRampReader_IsSourceCursed_Call{Call: _e.mock.On("IsSourceCursed", ctx)} +} + +func (_c *OnRampReader_IsSourceCursed_Call) Run(run func(ctx context.Context)) *OnRampReader_IsSourceCursed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OnRampReader_IsSourceCursed_Call) Return(_a0 bool, _a1 error) *OnRampReader_IsSourceCursed_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OnRampReader_IsSourceCursed_Call) RunAndReturn(run func(context.Context) (bool, error)) *OnRampReader_IsSourceCursed_Call { + _c.Call.Return(run) + return _c +} + +// RouterAddress provides a mock function with given fields: _a0 +func (_m *OnRampReader) RouterAddress(_a0 context.Context) (ccip.Address, error) { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for RouterAddress") + } + + var r0 ccip.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.Address, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.Address); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(ccip.Address) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OnRampReader_RouterAddress_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RouterAddress' +type OnRampReader_RouterAddress_Call struct { + *mock.Call +} + +// RouterAddress is a helper method to define mock.On call +// - _a0 context.Context +func (_e *OnRampReader_Expecter) RouterAddress(_a0 interface{}) *OnRampReader_RouterAddress_Call { + return &OnRampReader_RouterAddress_Call{Call: _e.mock.On("RouterAddress", _a0)} +} + +func (_c *OnRampReader_RouterAddress_Call) Run(run func(_a0 context.Context)) *OnRampReader_RouterAddress_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OnRampReader_RouterAddress_Call) Return(_a0 ccip.Address, _a1 error) *OnRampReader_RouterAddress_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OnRampReader_RouterAddress_Call) RunAndReturn(run func(context.Context) (ccip.Address, error)) *OnRampReader_RouterAddress_Call { + _c.Call.Return(run) + return _c +} + +// SourcePriceRegistryAddress provides a mock function with given fields: ctx +func (_m *OnRampReader) SourcePriceRegistryAddress(ctx context.Context) (ccip.Address, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for SourcePriceRegistryAddress") + } + + var r0 ccip.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.Address, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.Address); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.Address) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OnRampReader_SourcePriceRegistryAddress_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SourcePriceRegistryAddress' +type OnRampReader_SourcePriceRegistryAddress_Call struct { + *mock.Call +} + +// SourcePriceRegistryAddress is a helper method to define mock.On call +// - ctx context.Context +func (_e *OnRampReader_Expecter) SourcePriceRegistryAddress(ctx interface{}) *OnRampReader_SourcePriceRegistryAddress_Call { + return &OnRampReader_SourcePriceRegistryAddress_Call{Call: _e.mock.On("SourcePriceRegistryAddress", ctx)} +} + +func (_c *OnRampReader_SourcePriceRegistryAddress_Call) Run(run func(ctx context.Context)) *OnRampReader_SourcePriceRegistryAddress_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *OnRampReader_SourcePriceRegistryAddress_Call) Return(_a0 ccip.Address, _a1 error) *OnRampReader_SourcePriceRegistryAddress_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OnRampReader_SourcePriceRegistryAddress_Call) RunAndReturn(run func(context.Context) (ccip.Address, error)) *OnRampReader_SourcePriceRegistryAddress_Call { + _c.Call.Return(run) + return _c +} + +// NewOnRampReader creates a new instance of OnRampReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewOnRampReader(t interface { + mock.TestingT + Cleanup(func()) +}) *OnRampReader { + mock := &OnRampReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/price_registry_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/price_registry_reader_mock.go new file mode 100644 index 0000000000..94e354acb2 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/price_registry_reader_mock.go @@ -0,0 +1,498 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + context "context" + + mock "github.com/stretchr/testify/mock" + + time "time" +) + +// PriceRegistryReader is an autogenerated mock type for the PriceRegistryReader type +type PriceRegistryReader struct { + mock.Mock +} + +type PriceRegistryReader_Expecter struct { + mock *mock.Mock +} + +func (_m *PriceRegistryReader) EXPECT() *PriceRegistryReader_Expecter { + return &PriceRegistryReader_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: ctx +func (_m *PriceRegistryReader) Address(ctx context.Context) (ccip.Address, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 ccip.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (ccip.Address, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) ccip.Address); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(ccip.Address) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryReader_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type PriceRegistryReader_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +// - ctx context.Context +func (_e *PriceRegistryReader_Expecter) Address(ctx interface{}) *PriceRegistryReader_Address_Call { + return &PriceRegistryReader_Address_Call{Call: _e.mock.On("Address", ctx)} +} + +func (_c *PriceRegistryReader_Address_Call) Run(run func(ctx context.Context)) *PriceRegistryReader_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *PriceRegistryReader_Address_Call) Return(_a0 ccip.Address, _a1 error) *PriceRegistryReader_Address_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryReader_Address_Call) RunAndReturn(run func(context.Context) (ccip.Address, error)) *PriceRegistryReader_Address_Call { + _c.Call.Return(run) + return _c +} + +// Close provides a mock function with given fields: +func (_m *PriceRegistryReader) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// PriceRegistryReader_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type PriceRegistryReader_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *PriceRegistryReader_Expecter) Close() *PriceRegistryReader_Close_Call { + return &PriceRegistryReader_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *PriceRegistryReader_Close_Call) Run(run func()) *PriceRegistryReader_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *PriceRegistryReader_Close_Call) Return(_a0 error) *PriceRegistryReader_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *PriceRegistryReader_Close_Call) RunAndReturn(run func() error) *PriceRegistryReader_Close_Call { + _c.Call.Return(run) + return _c +} + +// GetAllGasPriceUpdatesCreatedAfter provides a mock function with given fields: ctx, ts, confirmations +func (_m *PriceRegistryReader) GetAllGasPriceUpdatesCreatedAfter(ctx context.Context, ts time.Time, confirmations int) ([]ccip.GasPriceUpdateWithTxMeta, error) { + ret := _m.Called(ctx, ts, confirmations) + + if len(ret) == 0 { + panic("no return value specified for GetAllGasPriceUpdatesCreatedAfter") + } + + var r0 []ccip.GasPriceUpdateWithTxMeta + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, time.Time, int) ([]ccip.GasPriceUpdateWithTxMeta, error)); ok { + return rf(ctx, ts, confirmations) + } + if rf, ok := ret.Get(0).(func(context.Context, time.Time, int) []ccip.GasPriceUpdateWithTxMeta); ok { + r0 = rf(ctx, ts, confirmations) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccip.GasPriceUpdateWithTxMeta) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, time.Time, int) error); ok { + r1 = rf(ctx, ts, confirmations) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryReader_GetAllGasPriceUpdatesCreatedAfter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAllGasPriceUpdatesCreatedAfter' +type PriceRegistryReader_GetAllGasPriceUpdatesCreatedAfter_Call struct { + *mock.Call +} + +// GetAllGasPriceUpdatesCreatedAfter is a helper method to define mock.On call +// - ctx context.Context +// - ts time.Time +// - confirmations int +func (_e *PriceRegistryReader_Expecter) GetAllGasPriceUpdatesCreatedAfter(ctx interface{}, ts interface{}, confirmations interface{}) *PriceRegistryReader_GetAllGasPriceUpdatesCreatedAfter_Call { + return &PriceRegistryReader_GetAllGasPriceUpdatesCreatedAfter_Call{Call: _e.mock.On("GetAllGasPriceUpdatesCreatedAfter", ctx, ts, confirmations)} +} + +func (_c *PriceRegistryReader_GetAllGasPriceUpdatesCreatedAfter_Call) Run(run func(ctx context.Context, ts time.Time, confirmations int)) *PriceRegistryReader_GetAllGasPriceUpdatesCreatedAfter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(time.Time), args[2].(int)) + }) + return _c +} + +func (_c *PriceRegistryReader_GetAllGasPriceUpdatesCreatedAfter_Call) Return(_a0 []ccip.GasPriceUpdateWithTxMeta, _a1 error) *PriceRegistryReader_GetAllGasPriceUpdatesCreatedAfter_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryReader_GetAllGasPriceUpdatesCreatedAfter_Call) RunAndReturn(run func(context.Context, time.Time, int) ([]ccip.GasPriceUpdateWithTxMeta, error)) *PriceRegistryReader_GetAllGasPriceUpdatesCreatedAfter_Call { + _c.Call.Return(run) + return _c +} + +// GetFeeTokens provides a mock function with given fields: ctx +func (_m *PriceRegistryReader) GetFeeTokens(ctx context.Context) ([]ccip.Address, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetFeeTokens") + } + + var r0 []ccip.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]ccip.Address, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []ccip.Address); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccip.Address) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryReader_GetFeeTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFeeTokens' +type PriceRegistryReader_GetFeeTokens_Call struct { + *mock.Call +} + +// GetFeeTokens is a helper method to define mock.On call +// - ctx context.Context +func (_e *PriceRegistryReader_Expecter) GetFeeTokens(ctx interface{}) *PriceRegistryReader_GetFeeTokens_Call { + return &PriceRegistryReader_GetFeeTokens_Call{Call: _e.mock.On("GetFeeTokens", ctx)} +} + +func (_c *PriceRegistryReader_GetFeeTokens_Call) Run(run func(ctx context.Context)) *PriceRegistryReader_GetFeeTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *PriceRegistryReader_GetFeeTokens_Call) Return(_a0 []ccip.Address, _a1 error) *PriceRegistryReader_GetFeeTokens_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryReader_GetFeeTokens_Call) RunAndReturn(run func(context.Context) ([]ccip.Address, error)) *PriceRegistryReader_GetFeeTokens_Call { + _c.Call.Return(run) + return _c +} + +// GetGasPriceUpdatesCreatedAfter provides a mock function with given fields: ctx, chainSelector, ts, confirmations +func (_m *PriceRegistryReader) GetGasPriceUpdatesCreatedAfter(ctx context.Context, chainSelector uint64, ts time.Time, confirmations int) ([]ccip.GasPriceUpdateWithTxMeta, error) { + ret := _m.Called(ctx, chainSelector, ts, confirmations) + + if len(ret) == 0 { + panic("no return value specified for GetGasPriceUpdatesCreatedAfter") + } + + var r0 []ccip.GasPriceUpdateWithTxMeta + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, time.Time, int) ([]ccip.GasPriceUpdateWithTxMeta, error)); ok { + return rf(ctx, chainSelector, ts, confirmations) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, time.Time, int) []ccip.GasPriceUpdateWithTxMeta); ok { + r0 = rf(ctx, chainSelector, ts, confirmations) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccip.GasPriceUpdateWithTxMeta) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, time.Time, int) error); ok { + r1 = rf(ctx, chainSelector, ts, confirmations) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryReader_GetGasPriceUpdatesCreatedAfter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGasPriceUpdatesCreatedAfter' +type PriceRegistryReader_GetGasPriceUpdatesCreatedAfter_Call struct { + *mock.Call +} + +// GetGasPriceUpdatesCreatedAfter is a helper method to define mock.On call +// - ctx context.Context +// - chainSelector uint64 +// - ts time.Time +// - confirmations int +func (_e *PriceRegistryReader_Expecter) GetGasPriceUpdatesCreatedAfter(ctx interface{}, chainSelector interface{}, ts interface{}, confirmations interface{}) *PriceRegistryReader_GetGasPriceUpdatesCreatedAfter_Call { + return &PriceRegistryReader_GetGasPriceUpdatesCreatedAfter_Call{Call: _e.mock.On("GetGasPriceUpdatesCreatedAfter", ctx, chainSelector, ts, confirmations)} +} + +func (_c *PriceRegistryReader_GetGasPriceUpdatesCreatedAfter_Call) Run(run func(ctx context.Context, chainSelector uint64, ts time.Time, confirmations int)) *PriceRegistryReader_GetGasPriceUpdatesCreatedAfter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].(time.Time), args[3].(int)) + }) + return _c +} + +func (_c *PriceRegistryReader_GetGasPriceUpdatesCreatedAfter_Call) Return(_a0 []ccip.GasPriceUpdateWithTxMeta, _a1 error) *PriceRegistryReader_GetGasPriceUpdatesCreatedAfter_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryReader_GetGasPriceUpdatesCreatedAfter_Call) RunAndReturn(run func(context.Context, uint64, time.Time, int) ([]ccip.GasPriceUpdateWithTxMeta, error)) *PriceRegistryReader_GetGasPriceUpdatesCreatedAfter_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenPriceUpdatesCreatedAfter provides a mock function with given fields: ctx, ts, confirmations +func (_m *PriceRegistryReader) GetTokenPriceUpdatesCreatedAfter(ctx context.Context, ts time.Time, confirmations int) ([]ccip.TokenPriceUpdateWithTxMeta, error) { + ret := _m.Called(ctx, ts, confirmations) + + if len(ret) == 0 { + panic("no return value specified for GetTokenPriceUpdatesCreatedAfter") + } + + var r0 []ccip.TokenPriceUpdateWithTxMeta + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, time.Time, int) ([]ccip.TokenPriceUpdateWithTxMeta, error)); ok { + return rf(ctx, ts, confirmations) + } + if rf, ok := ret.Get(0).(func(context.Context, time.Time, int) []ccip.TokenPriceUpdateWithTxMeta); ok { + r0 = rf(ctx, ts, confirmations) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccip.TokenPriceUpdateWithTxMeta) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, time.Time, int) error); ok { + r1 = rf(ctx, ts, confirmations) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryReader_GetTokenPriceUpdatesCreatedAfter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenPriceUpdatesCreatedAfter' +type PriceRegistryReader_GetTokenPriceUpdatesCreatedAfter_Call struct { + *mock.Call +} + +// GetTokenPriceUpdatesCreatedAfter is a helper method to define mock.On call +// - ctx context.Context +// - ts time.Time +// - confirmations int +func (_e *PriceRegistryReader_Expecter) GetTokenPriceUpdatesCreatedAfter(ctx interface{}, ts interface{}, confirmations interface{}) *PriceRegistryReader_GetTokenPriceUpdatesCreatedAfter_Call { + return &PriceRegistryReader_GetTokenPriceUpdatesCreatedAfter_Call{Call: _e.mock.On("GetTokenPriceUpdatesCreatedAfter", ctx, ts, confirmations)} +} + +func (_c *PriceRegistryReader_GetTokenPriceUpdatesCreatedAfter_Call) Run(run func(ctx context.Context, ts time.Time, confirmations int)) *PriceRegistryReader_GetTokenPriceUpdatesCreatedAfter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(time.Time), args[2].(int)) + }) + return _c +} + +func (_c *PriceRegistryReader_GetTokenPriceUpdatesCreatedAfter_Call) Return(_a0 []ccip.TokenPriceUpdateWithTxMeta, _a1 error) *PriceRegistryReader_GetTokenPriceUpdatesCreatedAfter_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryReader_GetTokenPriceUpdatesCreatedAfter_Call) RunAndReturn(run func(context.Context, time.Time, int) ([]ccip.TokenPriceUpdateWithTxMeta, error)) *PriceRegistryReader_GetTokenPriceUpdatesCreatedAfter_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenPrices provides a mock function with given fields: ctx, wantedTokens +func (_m *PriceRegistryReader) GetTokenPrices(ctx context.Context, wantedTokens []ccip.Address) ([]ccip.TokenPriceUpdate, error) { + ret := _m.Called(ctx, wantedTokens) + + if len(ret) == 0 { + panic("no return value specified for GetTokenPrices") + } + + var r0 []ccip.TokenPriceUpdate + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) ([]ccip.TokenPriceUpdate, error)); ok { + return rf(ctx, wantedTokens) + } + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) []ccip.TokenPriceUpdate); ok { + r0 = rf(ctx, wantedTokens) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccip.TokenPriceUpdate) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []ccip.Address) error); ok { + r1 = rf(ctx, wantedTokens) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryReader_GetTokenPrices_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenPrices' +type PriceRegistryReader_GetTokenPrices_Call struct { + *mock.Call +} + +// GetTokenPrices is a helper method to define mock.On call +// - ctx context.Context +// - wantedTokens []ccip.Address +func (_e *PriceRegistryReader_Expecter) GetTokenPrices(ctx interface{}, wantedTokens interface{}) *PriceRegistryReader_GetTokenPrices_Call { + return &PriceRegistryReader_GetTokenPrices_Call{Call: _e.mock.On("GetTokenPrices", ctx, wantedTokens)} +} + +func (_c *PriceRegistryReader_GetTokenPrices_Call) Run(run func(ctx context.Context, wantedTokens []ccip.Address)) *PriceRegistryReader_GetTokenPrices_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]ccip.Address)) + }) + return _c +} + +func (_c *PriceRegistryReader_GetTokenPrices_Call) Return(_a0 []ccip.TokenPriceUpdate, _a1 error) *PriceRegistryReader_GetTokenPrices_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryReader_GetTokenPrices_Call) RunAndReturn(run func(context.Context, []ccip.Address) ([]ccip.TokenPriceUpdate, error)) *PriceRegistryReader_GetTokenPrices_Call { + _c.Call.Return(run) + return _c +} + +// GetTokensDecimals provides a mock function with given fields: ctx, tokenAddresses +func (_m *PriceRegistryReader) GetTokensDecimals(ctx context.Context, tokenAddresses []ccip.Address) ([]uint8, error) { + ret := _m.Called(ctx, tokenAddresses) + + if len(ret) == 0 { + panic("no return value specified for GetTokensDecimals") + } + + var r0 []uint8 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) ([]uint8, error)); ok { + return rf(ctx, tokenAddresses) + } + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) []uint8); ok { + r0 = rf(ctx, tokenAddresses) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]uint8) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []ccip.Address) error); ok { + r1 = rf(ctx, tokenAddresses) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryReader_GetTokensDecimals_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokensDecimals' +type PriceRegistryReader_GetTokensDecimals_Call struct { + *mock.Call +} + +// GetTokensDecimals is a helper method to define mock.On call +// - ctx context.Context +// - tokenAddresses []ccip.Address +func (_e *PriceRegistryReader_Expecter) GetTokensDecimals(ctx interface{}, tokenAddresses interface{}) *PriceRegistryReader_GetTokensDecimals_Call { + return &PriceRegistryReader_GetTokensDecimals_Call{Call: _e.mock.On("GetTokensDecimals", ctx, tokenAddresses)} +} + +func (_c *PriceRegistryReader_GetTokensDecimals_Call) Run(run func(ctx context.Context, tokenAddresses []ccip.Address)) *PriceRegistryReader_GetTokensDecimals_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]ccip.Address)) + }) + return _c +} + +func (_c *PriceRegistryReader_GetTokensDecimals_Call) Return(_a0 []uint8, _a1 error) *PriceRegistryReader_GetTokensDecimals_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryReader_GetTokensDecimals_Call) RunAndReturn(run func(context.Context, []ccip.Address) ([]uint8, error)) *PriceRegistryReader_GetTokensDecimals_Call { + _c.Call.Return(run) + return _c +} + +// NewPriceRegistryReader creates a new instance of PriceRegistryReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewPriceRegistryReader(t interface { + mock.TestingT + Cleanup(func()) +}) *PriceRegistryReader { + mock := &PriceRegistryReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/token_pool_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/token_pool_reader_mock.go new file mode 100644 index 0000000000..0bb23b9cc2 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/token_pool_reader_mock.go @@ -0,0 +1,127 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + common "github.com/ethereum/go-ethereum/common" + mock "github.com/stretchr/testify/mock" +) + +// TokenPoolReader is an autogenerated mock type for the TokenPoolReader type +type TokenPoolReader struct { + mock.Mock +} + +type TokenPoolReader_Expecter struct { + mock *mock.Mock +} + +func (_m *TokenPoolReader) EXPECT() *TokenPoolReader_Expecter { + return &TokenPoolReader_Expecter{mock: &_m.Mock} +} + +// Address provides a mock function with given fields: +func (_m *TokenPoolReader) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// TokenPoolReader_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type TokenPoolReader_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *TokenPoolReader_Expecter) Address() *TokenPoolReader_Address_Call { + return &TokenPoolReader_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *TokenPoolReader_Address_Call) Run(run func()) *TokenPoolReader_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *TokenPoolReader_Address_Call) Return(_a0 common.Address) *TokenPoolReader_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *TokenPoolReader_Address_Call) RunAndReturn(run func() common.Address) *TokenPoolReader_Address_Call { + _c.Call.Return(run) + return _c +} + +// Type provides a mock function with given fields: +func (_m *TokenPoolReader) Type() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Type") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// TokenPoolReader_Type_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Type' +type TokenPoolReader_Type_Call struct { + *mock.Call +} + +// Type is a helper method to define mock.On call +func (_e *TokenPoolReader_Expecter) Type() *TokenPoolReader_Type_Call { + return &TokenPoolReader_Type_Call{Call: _e.mock.On("Type")} +} + +func (_c *TokenPoolReader_Type_Call) Run(run func()) *TokenPoolReader_Type_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *TokenPoolReader_Type_Call) Return(_a0 string) *TokenPoolReader_Type_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *TokenPoolReader_Type_Call) RunAndReturn(run func() string) *TokenPoolReader_Type_Call { + _c.Call.Return(run) + return _c +} + +// NewTokenPoolReader creates a new instance of TokenPoolReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewTokenPoolReader(t interface { + mock.TestingT + Cleanup(func()) +}) *TokenPoolReader { + mock := &TokenPoolReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/usdc_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/usdc_reader_mock.go new file mode 100644 index 0000000000..ac72d59992 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks/usdc_reader_mock.go @@ -0,0 +1,97 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" +) + +// USDCReader is an autogenerated mock type for the USDCReader type +type USDCReader struct { + mock.Mock +} + +type USDCReader_Expecter struct { + mock *mock.Mock +} + +func (_m *USDCReader) EXPECT() *USDCReader_Expecter { + return &USDCReader_Expecter{mock: &_m.Mock} +} + +// GetUSDCMessagePriorToLogIndexInTx provides a mock function with given fields: ctx, logIndex, usdcTokenIndexOffset, txHash +func (_m *USDCReader) GetUSDCMessagePriorToLogIndexInTx(ctx context.Context, logIndex int64, usdcTokenIndexOffset int, txHash string) ([]byte, error) { + ret := _m.Called(ctx, logIndex, usdcTokenIndexOffset, txHash) + + if len(ret) == 0 { + panic("no return value specified for GetUSDCMessagePriorToLogIndexInTx") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, int64, int, string) ([]byte, error)); ok { + return rf(ctx, logIndex, usdcTokenIndexOffset, txHash) + } + if rf, ok := ret.Get(0).(func(context.Context, int64, int, string) []byte); ok { + r0 = rf(ctx, logIndex, usdcTokenIndexOffset, txHash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int64, int, string) error); ok { + r1 = rf(ctx, logIndex, usdcTokenIndexOffset, txHash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// USDCReader_GetUSDCMessagePriorToLogIndexInTx_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetUSDCMessagePriorToLogIndexInTx' +type USDCReader_GetUSDCMessagePriorToLogIndexInTx_Call struct { + *mock.Call +} + +// GetUSDCMessagePriorToLogIndexInTx is a helper method to define mock.On call +// - ctx context.Context +// - logIndex int64 +// - usdcTokenIndexOffset int +// - txHash string +func (_e *USDCReader_Expecter) GetUSDCMessagePriorToLogIndexInTx(ctx interface{}, logIndex interface{}, usdcTokenIndexOffset interface{}, txHash interface{}) *USDCReader_GetUSDCMessagePriorToLogIndexInTx_Call { + return &USDCReader_GetUSDCMessagePriorToLogIndexInTx_Call{Call: _e.mock.On("GetUSDCMessagePriorToLogIndexInTx", ctx, logIndex, usdcTokenIndexOffset, txHash)} +} + +func (_c *USDCReader_GetUSDCMessagePriorToLogIndexInTx_Call) Run(run func(ctx context.Context, logIndex int64, usdcTokenIndexOffset int, txHash string)) *USDCReader_GetUSDCMessagePriorToLogIndexInTx_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(int64), args[2].(int), args[3].(string)) + }) + return _c +} + +func (_c *USDCReader_GetUSDCMessagePriorToLogIndexInTx_Call) Return(_a0 []byte, _a1 error) *USDCReader_GetUSDCMessagePriorToLogIndexInTx_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *USDCReader_GetUSDCMessagePriorToLogIndexInTx_Call) RunAndReturn(run func(context.Context, int64, int, string) ([]byte, error)) *USDCReader_GetUSDCMessagePriorToLogIndexInTx_Call { + _c.Call.Return(run) + return _c +} + +// NewUSDCReader creates a new instance of USDCReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewUSDCReader(t interface { + mock.TestingT + Cleanup(func()) +}) *USDCReader { + mock := &USDCReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader.go new file mode 100644 index 0000000000..c3bad6235b --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader.go @@ -0,0 +1,13 @@ +package ccipdata + +import ( + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" +) + +const ( + ManuallyExecute = "manuallyExecute" +) + +type OffRampReader interface { + cciptypes.OffRampReader +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go new file mode 100644 index 0000000000..6f14fb8559 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go @@ -0,0 +1,416 @@ +package ccipdata_test + +import ( + "math/big" + "math/rand" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + evmclientmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" +) + +type offRampReaderTH struct { + user *bind.TransactOpts + reader ccipdata.OffRampReader +} + +func TestExecOnchainConfig100(t *testing.T) { + tests := []struct { + name string + want v1_0_0.ExecOnchainConfig + expectErr bool + }{ + { + name: "encodes and decodes config with all fields set", + want: v1_0_0.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: rand.Uint32(), + Router: utils.RandomAddress(), + PriceRegistry: utils.RandomAddress(), + MaxTokensLength: uint16(rand.Uint32()), + MaxDataSize: rand.Uint32(), + }, + }, + { + name: "encodes and fails decoding config with missing fields", + want: v1_0_0.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: rand.Uint32(), + MaxDataSize: rand.Uint32(), + }, + expectErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + encoded, err := abihelpers.EncodeAbiStruct(tt.want) + require.NoError(t, err) + + decoded, err := abihelpers.DecodeAbiStruct[v1_0_0.ExecOnchainConfig](encoded) + if tt.expectErr { + require.ErrorContains(t, err, "must set") + } else { + require.NoError(t, err) + require.Equal(t, tt.want, decoded) + } + }) + } +} + +func TestExecOnchainConfig120(t *testing.T) { + tests := []struct { + name string + want v1_2_0.ExecOnchainConfig + expectErr bool + }{ + { + name: "encodes and decodes config with all fields set", + want: v1_2_0.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: rand.Uint32(), + Router: utils.RandomAddress(), + PriceRegistry: utils.RandomAddress(), + MaxNumberOfTokensPerMsg: uint16(rand.Uint32()), + MaxDataBytes: rand.Uint32(), + MaxPoolReleaseOrMintGas: rand.Uint32(), + }, + }, + { + name: "encodes and fails decoding config with missing fields", + want: v1_2_0.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: rand.Uint32(), + MaxDataBytes: rand.Uint32(), + }, + expectErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + encoded, err := abihelpers.EncodeAbiStruct(tt.want) + require.NoError(t, err) + + decoded, err := abihelpers.DecodeAbiStruct[v1_2_0.ExecOnchainConfig](encoded) + if tt.expectErr { + require.ErrorContains(t, err, "must set") + } else { + require.NoError(t, err) + require.Equal(t, tt.want, decoded) + } + }) + } +} + +func TestOffRampReaderInit(t *testing.T) { + tests := []struct { + name string + version string + }{ + { + name: "OffRampReader_V1_0_0", + version: ccipdata.V1_0_0, + }, + { + name: "OffRampReader_V1_1_0", + version: ccipdata.V1_1_0, + }, + { + name: "OffRampReader_V1_2_0", + version: ccipdata.V1_2_0, + }, + { + name: "OffRampReader_V1_5_0", + version: ccipdata.V1_5_0, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + th := setupOffRampReaderTH(t, test.version) + testOffRampReader(t, th) + }) + } +} + +func setupOffRampReaderTH(t *testing.T, version string) offRampReaderTH { + ctx := testutils.Context(t) + user, bc := ccipdata.NewSimulation(t) + log := logger.TestLogger(t) + orm := logpoller.NewORM(testutils.SimulatedChainID, pgtest.NewSqlxDB(t), log) + lpOpts := logpoller.Opts{ + PollPeriod: 100 * time.Millisecond, + FinalityDepth: 2, + BackfillBatchSize: 3, + RpcBatchSize: 2, + KeepFinalizedBlocksDepth: 1000, + } + headTracker := headtracker.NewSimulatedHeadTracker(bc, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + if lpOpts.PollPeriod == 0 { + lpOpts.PollPeriod = 1 * time.Hour + } + lp := logpoller.NewLogPoller( + orm, + bc, + log, + headTracker, + lpOpts) + assert.NoError(t, orm.InsertBlock(ctx, common.Hash{}, 1, time.Now(), 1)) + // Setup offRamp. + var offRampAddress common.Address + switch version { + case ccipdata.V1_0_0: + offRampAddress = setupOffRampV1_0_0(t, user, bc) + case ccipdata.V1_1_0: + // Version 1.1.0 uses the same contracts as 1.0.0. + offRampAddress = setupOffRampV1_0_0(t, user, bc) + case ccipdata.V1_2_0: + offRampAddress = setupOffRampV1_2_0(t, user, bc) + case ccipdata.V1_5_0: + offRampAddress = setupOffRampV1_5_0(t, user, bc) + default: + require.Fail(t, "Unknown version: ", version) + } + + // Create the version-specific reader. + reader, err := factory.NewOffRampReader(log, factory.NewEvmVersionFinder(), ccipcalc.EvmAddrToGeneric(offRampAddress), bc, lp, nil, nil, true) + require.NoError(t, err) + addr, err := reader.Address(ctx) + require.NoError(t, err) + require.Equal(t, ccipcalc.EvmAddrToGeneric(offRampAddress), addr) + + return offRampReaderTH{ + user: user, + reader: reader, + } +} + +func setupOffRampV1_0_0(t *testing.T, user *bind.TransactOpts, bc *client.SimulatedBackendClient) common.Address { + onRampAddr := utils.RandomAddress() + armAddr := deployMockArm(t, user, bc) + csAddr := deployCommitStore(t, user, bc, onRampAddr, armAddr) + + // Deploy the OffRamp. + staticConfig := evm_2_evm_offramp_1_0_0.EVM2EVMOffRampStaticConfig{ + CommitStore: csAddr, + ChainSelector: testutils.SimulatedChainID.Uint64(), + SourceChainSelector: testutils.SimulatedChainID.Uint64(), + OnRamp: onRampAddr, + PrevOffRamp: common.Address{}, + ArmProxy: armAddr, + } + sourceTokens := []common.Address{} + pools := []common.Address{} + rateLimiterConfig := evm_2_evm_offramp_1_0_0.RateLimiterConfig{ + IsEnabled: false, + Capacity: big.NewInt(0), + Rate: big.NewInt(0), + } + + offRampAddr, tx, offRamp, err := evm_2_evm_offramp_1_0_0.DeployEVM2EVMOffRamp(user, bc, staticConfig, sourceTokens, pools, rateLimiterConfig) + bc.Commit() + require.NoError(t, err) + ccipdata.AssertNonRevert(t, tx, bc, user) + + // Verify the deployed OffRamp. + tav, err := offRamp.TypeAndVersion(&bind.CallOpts{ + Context: testutils.Context(t), + }) + require.NoError(t, err) + require.Equal(t, "EVM2EVMOffRamp 1.0.0", tav) + return offRampAddr +} + +func setupOffRampV1_2_0(t *testing.T, user *bind.TransactOpts, bc *client.SimulatedBackendClient) common.Address { + onRampAddr := utils.RandomAddress() + armAddr := deployMockArm(t, user, bc) + csAddr := deployCommitStore(t, user, bc, onRampAddr, armAddr) + + // Deploy the OffRamp. + staticConfig := evm_2_evm_offramp_1_2_0.EVM2EVMOffRampStaticConfig{ + CommitStore: csAddr, + ChainSelector: testutils.SimulatedChainID.Uint64(), + SourceChainSelector: testutils.SimulatedChainID.Uint64(), + OnRamp: onRampAddr, + PrevOffRamp: common.Address{}, + ArmProxy: armAddr, + } + sourceTokens := []common.Address{} + pools := []common.Address{} + rateLimiterConfig := evm_2_evm_offramp_1_2_0.RateLimiterConfig{ + IsEnabled: false, + Capacity: big.NewInt(0), + Rate: big.NewInt(0), + } + + offRampAddr, tx, offRamp, err := evm_2_evm_offramp_1_2_0.DeployEVM2EVMOffRamp(user, bc, staticConfig, sourceTokens, pools, rateLimiterConfig) + bc.Commit() + require.NoError(t, err) + ccipdata.AssertNonRevert(t, tx, bc, user) + + // Verify the deployed OffRamp. + tav, err := offRamp.TypeAndVersion(&bind.CallOpts{ + Context: testutils.Context(t), + }) + require.NoError(t, err) + require.Equal(t, "EVM2EVMOffRamp 1.2.0", tav) + return offRampAddr +} + +func setupOffRampV1_5_0(t *testing.T, user *bind.TransactOpts, bc *client.SimulatedBackendClient) common.Address { + onRampAddr := utils.RandomAddress() + tokenAdminRegAddr := utils.RandomAddress() + rmnAddr := deployMockArm(t, user, bc) + csAddr := deployCommitStore(t, user, bc, onRampAddr, rmnAddr) + + // Deploy the OffRamp. + staticConfig := evm_2_evm_offramp.EVM2EVMOffRampStaticConfig{ + CommitStore: csAddr, + ChainSelector: testutils.SimulatedChainID.Uint64(), + SourceChainSelector: testutils.SimulatedChainID.Uint64(), + OnRamp: onRampAddr, + PrevOffRamp: common.Address{}, + RmnProxy: rmnAddr, + TokenAdminRegistry: tokenAdminRegAddr, + } + rateLimiterConfig := evm_2_evm_offramp.RateLimiterConfig{ + IsEnabled: false, + Capacity: big.NewInt(0), + Rate: big.NewInt(0), + } + + offRampAddr, tx, offRamp, err := evm_2_evm_offramp.DeployEVM2EVMOffRamp(user, bc, staticConfig, rateLimiterConfig) + bc.Commit() + require.NoError(t, err) + ccipdata.AssertNonRevert(t, tx, bc, user) + + // Verify the deployed OffRamp. + tav, err := offRamp.TypeAndVersion(&bind.CallOpts{ + Context: testutils.Context(t), + }) + require.NoError(t, err) + require.Equal(t, "EVM2EVMOffRamp 1.5.0-dev", tav) + return offRampAddr +} + +func deployMockArm( + t *testing.T, + user *bind.TransactOpts, + bc *client.SimulatedBackendClient, +) common.Address { + armAddr, tx, _, err := mock_arm_contract.DeployMockARMContract(user, bc) + require.NoError(t, err) + bc.Commit() + ccipdata.AssertNonRevert(t, tx, bc, user) + require.NotEqual(t, common.Address{}, armAddr) + return armAddr +} + +// Deploy the CommitStore. We use the same CommitStore version for all versions of OffRamp tested. +func deployCommitStore( + t *testing.T, + user *bind.TransactOpts, + bc *client.SimulatedBackendClient, + onRampAddress common.Address, + armAddress common.Address, +) common.Address { + // Deploy the CommitStore using the helper. + csAddr, tx, cs, err := commit_store_helper.DeployCommitStoreHelper(user, bc, commit_store_helper.CommitStoreStaticConfig{ + ChainSelector: testutils.SimulatedChainID.Uint64(), + SourceChainSelector: testutils.SimulatedChainID.Uint64(), + OnRamp: onRampAddress, + RmnProxy: armAddress, + }) + require.NoError(t, err) + bc.Commit() + ccipdata.AssertNonRevert(t, tx, bc, user) + + // Test the deployed CommitStore. + callOpts := &bind.CallOpts{ + Context: testutils.Context(t), + } + tav, err := cs.TypeAndVersion(callOpts) + require.NoError(t, err) + require.Equal(t, "CommitStore 1.5.0-dev", tav) + return csAddr +} + +func testOffRampReader(t *testing.T, th offRampReaderTH) { + ctx := th.user.Context + tokens, err := th.reader.GetTokens(ctx) + require.NoError(t, err) + require.Equal(t, []cciptypes.Address{}, tokens.DestinationTokens) + + events, err := th.reader.GetExecutionStateChangesBetweenSeqNums(ctx, 0, 10, 0) + require.NoError(t, err) + require.Equal(t, []cciptypes.ExecutionStateChangedWithTxMeta{}, events) + + sourceToDestTokens, err := th.reader.GetSourceToDestTokensMapping(ctx) + require.NoError(t, err) + require.Empty(t, sourceToDestTokens) + + require.NoError(t, err) +} + +func TestNewOffRampReader(t *testing.T) { + var tt = []struct { + typeAndVersion string + expectedErr string + }{ + { + typeAndVersion: "blah", + expectedErr: "unable to read type and version: invalid type and version blah", + }, + { + typeAndVersion: "CommitStore 1.0.0", + expectedErr: "expected EVM2EVMOffRamp got CommitStore", + }, + { + typeAndVersion: "EVM2EVMOffRamp 1.2.0", + expectedErr: "", + }, + { + typeAndVersion: "EVM2EVMOffRamp 2.0.0", + expectedErr: "unsupported offramp version 2.0.0", + }, + } + for _, tc := range tt { + t.Run(tc.typeAndVersion, func(t *testing.T) { + b, err := utils.ABIEncode(`[{"type":"string"}]`, tc.typeAndVersion) + require.NoError(t, err) + c := evmclientmocks.NewClient(t) + c.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(b, nil) + addr := ccipcalc.EvmAddrToGeneric(utils.RandomAddress()) + lp := lpmocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil).Maybe() + _, err = factory.NewOffRampReader(logger.TestLogger(t), factory.NewEvmVersionFinder(), addr, c, lp, nil, nil, true) + if tc.expectedErr != "" { + assert.EqualError(t, err, tc.expectedErr) + } else { + assert.NoError(t, err) + } + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader.go new file mode 100644 index 0000000000..e2571de57f --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader.go @@ -0,0 +1,21 @@ +package ccipdata + +import ( + "github.com/ethereum/go-ethereum/core/types" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" +) + +type LeafHasherInterface[H hashutil.Hash] interface { + HashLeaf(log types.Log) (H, error) +} + +const ( + COMMIT_CCIP_SENDS = "Commit ccip sends" + CONFIG_CHANGED = "Dynamic config changed" +) + +type OnRampReader interface { + cciptypes.OnRampReader +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_test.go new file mode 100644 index 0000000000..9cfe3f628c --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_test.go @@ -0,0 +1,479 @@ +package ccipdata_test + +import ( + "fmt" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + evmclientmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_1_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" +) + +type onRampReaderTH struct { + user *bind.TransactOpts + reader ccipdata.OnRampReader +} + +func TestNewOnRampReader_noContractAtAddress(t *testing.T) { + _, bc := ccipdata.NewSimulation(t) + addr := ccipcalc.EvmAddrToGeneric(utils.RandomAddress()) + _, err := factory.NewOnRampReader(logger.TestLogger(t), factory.NewEvmVersionFinder(), testutils.SimulatedChainID.Uint64(), testutils.SimulatedChainID.Uint64(), addr, lpmocks.NewLogPoller(t), bc) + assert.EqualError(t, err, fmt.Sprintf("unable to read type and version: error calling typeAndVersion on addr: %s no contract code at given address", addr)) +} + +func TestOnRampReaderInit(t *testing.T) { + tests := []struct { + name string + version string + }{ + { + name: "OnRampReader_V1_0_0", + version: ccipdata.V1_0_0, + }, + { + name: "OnRampReader_V1_1_0", + version: ccipdata.V1_1_0, + }, + { + name: "OnRampReader_V1_2_0", + version: ccipdata.V1_2_0, + }, + { + name: "OnRampReader_V1_5_0", + version: ccipdata.V1_5_0, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + th := setupOnRampReaderTH(t, test.version) + testVersionSpecificOnRampReader(t, th, test.version) + }) + } +} + +func setupOnRampReaderTH(t *testing.T, version string) onRampReaderTH { + user, bc := ccipdata.NewSimulation(t) + log := logger.TestLogger(t) + orm := logpoller.NewORM(testutils.SimulatedChainID, pgtest.NewSqlxDB(t), log) + lpOpts := logpoller.Opts{ + PollPeriod: 100 * time.Millisecond, + FinalityDepth: 2, + BackfillBatchSize: 3, + RpcBatchSize: 2, + KeepFinalizedBlocksDepth: 1000, + } + headTracker := headtracker.NewSimulatedHeadTracker(bc, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + if lpOpts.PollPeriod == 0 { + lpOpts.PollPeriod = 1 * time.Hour + } + lp := logpoller.NewLogPoller( + orm, + bc, + log, + headTracker, + lpOpts) + + // Setup onRamp. + var onRampAddress common.Address + switch version { + case ccipdata.V1_0_0: + onRampAddress = setupOnRampV1_0_0(t, user, bc) + case ccipdata.V1_1_0: + onRampAddress = setupOnRampV1_1_0(t, user, bc) + case ccipdata.V1_2_0: + onRampAddress = setupOnRampV1_2_0(t, user, bc) + case ccipdata.V1_5_0: + onRampAddress = setupOnRampV1_5_0(t, user, bc) + default: + require.Fail(t, "Unknown version: ", version) + } + + // Create the version-specific reader. + reader, err := factory.NewOnRampReader(log, factory.NewEvmVersionFinder(), testutils.SimulatedChainID.Uint64(), testutils.SimulatedChainID.Uint64(), ccipcalc.EvmAddrToGeneric(onRampAddress), lp, bc) + require.NoError(t, err) + + return onRampReaderTH{ + user: user, + reader: reader, + } +} + +func setupOnRampV1_0_0(t *testing.T, user *bind.TransactOpts, bc *client.SimulatedBackendClient) common.Address { + linkTokenAddress := common.HexToAddress("0x000011") + staticConfig := evm_2_evm_onramp_1_0_0.EVM2EVMOnRampStaticConfig{ + LinkToken: linkTokenAddress, + ChainSelector: testutils.SimulatedChainID.Uint64(), + DestChainSelector: testutils.SimulatedChainID.Uint64(), + DefaultTxGasLimit: 30000, + MaxNopFeesJuels: big.NewInt(1000000), + PrevOnRamp: common.Address{}, + ArmProxy: utils.RandomAddress(), + } + dynamicConfig := evm_2_evm_onramp_1_0_0.EVM2EVMOnRampDynamicConfig{ + Router: common.HexToAddress("0x000100"), + MaxTokensLength: 4, + PriceRegistry: utils.RandomAddress(), + MaxDataSize: 100000, + MaxGasLimit: 100000, + } + rateLimiterConfig := evm_2_evm_onramp_1_0_0.RateLimiterConfig{ + IsEnabled: false, + Capacity: big.NewInt(5), + Rate: big.NewInt(5), + } + allowList := []common.Address{user.From} + feeTokenConfigs := []evm_2_evm_onramp_1_0_0.EVM2EVMOnRampFeeTokenConfigArgs{ + { + Token: linkTokenAddress, + GasMultiplier: 1, + NetworkFeeAmountUSD: big.NewInt(0), + DestGasOverhead: 50, + DestGasPerPayloadByte: 60, + Enabled: false, + }, + } + tokenTransferConfigArgs := []evm_2_evm_onramp_1_0_0.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + { + Token: utils.RandomAddress(), + MinFee: 10, + MaxFee: 1000, + Ratio: 1, + }, + } + nopsAndWeights := []evm_2_evm_onramp_1_0_0.EVM2EVMOnRampNopAndWeight{ + { + Nop: utils.RandomAddress(), + Weight: 1, + }, + } + tokenAndPool := []evm_2_evm_onramp_1_0_0.InternalPoolUpdate{} + onRampAddress, transaction, _, err := evm_2_evm_onramp_1_0_0.DeployEVM2EVMOnRamp( + user, + bc, + staticConfig, + dynamicConfig, + tokenAndPool, + allowList, + rateLimiterConfig, + feeTokenConfigs, + tokenTransferConfigArgs, + nopsAndWeights, + ) + bc.Commit() + require.NoError(t, err) + ccipdata.AssertNonRevert(t, transaction, bc, user) + return onRampAddress +} + +func setupOnRampV1_1_0(t *testing.T, user *bind.TransactOpts, bc *client.SimulatedBackendClient) common.Address { + linkTokenAddress := common.HexToAddress("0x000011") + staticConfig := evm_2_evm_onramp_1_1_0.EVM2EVMOnRampStaticConfig{ + LinkToken: linkTokenAddress, + ChainSelector: testutils.SimulatedChainID.Uint64(), + DestChainSelector: testutils.SimulatedChainID.Uint64(), + DefaultTxGasLimit: 30000, + MaxNopFeesJuels: big.NewInt(1000000), + PrevOnRamp: common.Address{}, + ArmProxy: utils.RandomAddress(), + } + dynamicConfig := evm_2_evm_onramp_1_1_0.EVM2EVMOnRampDynamicConfig{ + Router: common.HexToAddress("0x000110"), + MaxTokensLength: 4, + PriceRegistry: common.HexToAddress("0x000066"), + MaxDataSize: 100000, + MaxGasLimit: 100000, + } + rateLimiterConfig := evm_2_evm_onramp_1_1_0.RateLimiterConfig{ + IsEnabled: false, + Capacity: big.NewInt(5), + Rate: big.NewInt(5), + } + allowList := []common.Address{user.From} + feeTokenConfigs := []evm_2_evm_onramp_1_1_0.EVM2EVMOnRampFeeTokenConfigArgs{ + { + Token: linkTokenAddress, + NetworkFeeUSD: 0, + MinTokenTransferFeeUSD: 0, + MaxTokenTransferFeeUSD: 0, + GasMultiplier: 0, + PremiumMultiplier: 0, + Enabled: false, + }, + } + tokenTransferConfigArgs := []evm_2_evm_onramp_1_1_0.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + { + Token: linkTokenAddress, + Ratio: 0, + DestGasOverhead: 0, + }, + } + nopsAndWeights := []evm_2_evm_onramp_1_1_0.EVM2EVMOnRampNopAndWeight{ + { + Nop: common.HexToAddress("0x222222222"), + Weight: 1, + }, + } + tokenAndPool := []evm_2_evm_onramp_1_1_0.InternalPoolUpdate{} + onRampAddress, transaction, _, err := evm_2_evm_onramp_1_1_0.DeployEVM2EVMOnRamp( + user, + bc, + staticConfig, + dynamicConfig, + tokenAndPool, + allowList, + rateLimiterConfig, + feeTokenConfigs, + tokenTransferConfigArgs, + nopsAndWeights, + ) + bc.Commit() + require.NoError(t, err) + ccipdata.AssertNonRevert(t, transaction, bc, user) + return onRampAddress +} + +func setupOnRampV1_2_0(t *testing.T, user *bind.TransactOpts, bc *client.SimulatedBackendClient) common.Address { + linkTokenAddress := common.HexToAddress("0x000011") + staticConfig := evm_2_evm_onramp_1_2_0.EVM2EVMOnRampStaticConfig{ + LinkToken: linkTokenAddress, + ChainSelector: testutils.SimulatedChainID.Uint64(), + DestChainSelector: testutils.SimulatedChainID.Uint64(), + DefaultTxGasLimit: 30000, + MaxNopFeesJuels: big.NewInt(1000000), + PrevOnRamp: common.Address{}, + ArmProxy: utils.RandomAddress(), + } + dynamicConfig := evm_2_evm_onramp_1_2_0.EVM2EVMOnRampDynamicConfig{ + Router: common.HexToAddress("0x0000000000000000000000000000000000000120"), + MaxNumberOfTokensPerMsg: 0, + DestGasOverhead: 0, + DestGasPerPayloadByte: 0, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 0, + DestDataAvailabilityMultiplierBps: 0, + PriceRegistry: utils.RandomAddress(), + MaxDataBytes: 0, + MaxPerMsgGasLimit: 0, + } + rateLimiterConfig := evm_2_evm_onramp_1_2_0.RateLimiterConfig{ + IsEnabled: false, + Capacity: big.NewInt(5), + Rate: big.NewInt(5), + } + feeTokenConfigs := []evm_2_evm_onramp_1_2_0.EVM2EVMOnRampFeeTokenConfigArgs{ + { + Token: linkTokenAddress, + NetworkFeeUSDCents: 0, + GasMultiplierWeiPerEth: 0, + PremiumMultiplierWeiPerEth: 0, + Enabled: false, + }, + } + tokenTransferConfigArgs := []evm_2_evm_onramp_1_2_0.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + { + Token: linkTokenAddress, + MinFeeUSDCents: 0, + MaxFeeUSDCents: 0, + DeciBps: 0, + DestGasOverhead: 0, + DestBytesOverhead: 0, + }, + } + nopsAndWeights := []evm_2_evm_onramp_1_2_0.EVM2EVMOnRampNopAndWeight{ + { + Nop: utils.RandomAddress(), + Weight: 1, + }, + } + tokenAndPool := []evm_2_evm_onramp_1_2_0.InternalPoolUpdate{} + onRampAddress, transaction, _, err := evm_2_evm_onramp_1_2_0.DeployEVM2EVMOnRamp( + user, + bc, + staticConfig, + dynamicConfig, + tokenAndPool, + rateLimiterConfig, + feeTokenConfigs, + tokenTransferConfigArgs, + nopsAndWeights, + ) + bc.Commit() + require.NoError(t, err) + ccipdata.AssertNonRevert(t, transaction, bc, user) + return onRampAddress +} + +func setupOnRampV1_5_0(t *testing.T, user *bind.TransactOpts, bc *client.SimulatedBackendClient) common.Address { + linkTokenAddress := common.HexToAddress("0x000011") + staticConfig := evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ + LinkToken: linkTokenAddress, + ChainSelector: testutils.SimulatedChainID.Uint64(), + DestChainSelector: testutils.SimulatedChainID.Uint64(), + DefaultTxGasLimit: 30000, + MaxNopFeesJuels: big.NewInt(1000000), + PrevOnRamp: common.Address{}, + RmnProxy: utils.RandomAddress(), + TokenAdminRegistry: utils.RandomAddress(), + } + dynamicConfig := evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ + Router: common.HexToAddress("0x0000000000000000000000000000000000000150"), + MaxNumberOfTokensPerMsg: 0, + DestGasOverhead: 0, + DestGasPerPayloadByte: 0, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 0, + DestDataAvailabilityMultiplierBps: 0, + PriceRegistry: utils.RandomAddress(), + MaxDataBytes: 0, + MaxPerMsgGasLimit: 0, + DefaultTokenFeeUSDCents: 50, + DefaultTokenDestGasOverhead: 34_000, + DefaultTokenDestBytesOverhead: 500, + } + rateLimiterConfig := evm_2_evm_onramp.RateLimiterConfig{ + IsEnabled: false, + Capacity: big.NewInt(5), + Rate: big.NewInt(5), + } + feeTokenConfigs := []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ + { + Token: linkTokenAddress, + NetworkFeeUSDCents: 0, + GasMultiplierWeiPerEth: 0, + PremiumMultiplierWeiPerEth: 0, + Enabled: false, + }, + } + tokenTransferConfigArgs := []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + { + Token: linkTokenAddress, + MinFeeUSDCents: 0, + MaxFeeUSDCents: 0, + DeciBps: 0, + DestGasOverhead: 0, + DestBytesOverhead: 64, + AggregateRateLimitEnabled: true, + }, + } + nopsAndWeights := []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{ + { + Nop: utils.RandomAddress(), + Weight: 1, + }, + } + onRampAddress, transaction, _, err := evm_2_evm_onramp.DeployEVM2EVMOnRamp( + user, + bc, + staticConfig, + dynamicConfig, + rateLimiterConfig, + feeTokenConfigs, + tokenTransferConfigArgs, + nopsAndWeights, + ) + bc.Commit() + require.NoError(t, err) + ccipdata.AssertNonRevert(t, transaction, bc, user) + return onRampAddress +} + +func testVersionSpecificOnRampReader(t *testing.T, th onRampReaderTH, version string) { + switch version { + case ccipdata.V1_0_0: + testOnRampReader(t, th, common.HexToAddress("0x0000000000000000000000000000000000000100")) + case ccipdata.V1_1_0: + testOnRampReader(t, th, common.HexToAddress("0x0000000000000000000000000000000000000110")) + case ccipdata.V1_2_0: + testOnRampReader(t, th, common.HexToAddress("0x0000000000000000000000000000000000000120")) + case ccipdata.V1_5_0: + testOnRampReader(t, th, common.HexToAddress("0x0000000000000000000000000000000000000150")) + default: + require.Fail(t, "Unknown version: ", version) + } +} + +func testOnRampReader(t *testing.T, th onRampReaderTH, expectedRouterAddress common.Address) { + ctx := th.user.Context + res, err := th.reader.RouterAddress(ctx) + require.NoError(t, err) + require.Equal(t, ccipcalc.EvmAddrToGeneric(expectedRouterAddress), res) + + msg, err := th.reader.GetSendRequestsBetweenSeqNums(ctx, 0, 10, true) + require.NoError(t, err) + require.NotNil(t, msg) + require.Equal(t, []cciptypes.EVM2EVMMessageWithTxMeta{}, msg) + + address, err := th.reader.Address(ctx) + require.NoError(t, err) + require.NotNil(t, address) + + cfg, err := th.reader.GetDynamicConfig(ctx) + require.NoError(t, err) + require.NotNil(t, cfg) + require.Equal(t, ccipcalc.EvmAddrToGeneric(expectedRouterAddress), cfg.Router) +} + +func TestNewOnRampReader(t *testing.T) { + var tt = []struct { + typeAndVersion string + expectedErr string + }{ + { + typeAndVersion: "blah", + expectedErr: "unable to read type and version: invalid type and version blah", + }, + { + typeAndVersion: "EVM2EVMOffRamp 1.0.0", + expectedErr: "expected EVM2EVMOnRamp got EVM2EVMOffRamp", + }, + { + typeAndVersion: "EVM2EVMOnRamp 1.2.0", + expectedErr: "", + }, + { + typeAndVersion: "EVM2EVMOnRamp 2.0.0", + expectedErr: "unsupported onramp version 2.0.0", + }, + } + for _, tc := range tt { + t.Run(tc.typeAndVersion, func(t *testing.T) { + b, err := utils.ABIEncode(`[{"type":"string"}]`, tc.typeAndVersion) + require.NoError(t, err) + c := evmclientmocks.NewClient(t) + c.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(b, nil) + addr := ccipcalc.EvmAddrToGeneric(utils.RandomAddress()) + lp := lpmocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil).Maybe() + _, err = factory.NewOnRampReader(logger.TestLogger(t), factory.NewEvmVersionFinder(), 1, 2, addr, lp, c) + if tc.expectedErr != "" { + require.EqualError(t, err, tc.expectedErr) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go new file mode 100644 index 0000000000..02aef5e9ef --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go @@ -0,0 +1,14 @@ +package ccipdata + +import cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + +const ( + COMMIT_PRICE_UPDATES = "Commit price updates" + FEE_TOKEN_ADDED = "Fee token added" + FEE_TOKEN_REMOVED = "Fee token removed" + ExecPluginLabel = "exec" +) + +type PriceRegistryReader interface { + cciptypes.PriceRegistryReader +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go new file mode 100644 index 0000000000..e17b885cff --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go @@ -0,0 +1,296 @@ +package ccipdata_test + +import ( + "context" + "math/big" + "reflect" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + evmclientmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" +) + +type priceRegReaderTH struct { + lp logpoller.LogPollerTest + ec client.Client + lggr logger.Logger + user *bind.TransactOpts + readers map[string]ccipdata.PriceRegistryReader + + // Expected state + blockTs []uint64 + expectedFeeTokens []common.Address + expectedGasUpdates map[uint64][]cciptypes.GasPrice + expectedTokenUpdates map[uint64][]cciptypes.TokenPrice + destSelectors []uint64 +} + +func commitAndGetBlockTs(ec *client.SimulatedBackendClient) uint64 { + h := ec.Commit() + b, _ := ec.BlockByHash(context.Background(), h) + return b.Time() +} + +func newSim(t *testing.T) (*bind.TransactOpts, *client.SimulatedBackendClient) { + user := testutils.MustNewSimTransactor(t) + sim := backends.NewSimulatedBackend(map[common.Address]core.GenesisAccount{ + user.From: { + Balance: big.NewInt(0).Mul(big.NewInt(10), big.NewInt(1e18)), + }, + }, 10e6) + ec := client.NewSimulatedBackendClient(t, sim, testutils.SimulatedChainID) + return user, ec +} + +// setupPriceRegistryReaderTH instantiates all versions of the price registry reader +// with a snapshot of data so reader tests can do multi-version assertions. +func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { + user, ec := newSim(t) + lggr := logger.TestLogger(t) + lpOpts := logpoller.Opts{ + PollPeriod: 100 * time.Millisecond, + FinalityDepth: 2, + BackfillBatchSize: 3, + RpcBatchSize: 2, + KeepFinalizedBlocksDepth: 1000, + } + headTracker := headtracker.NewSimulatedHeadTracker(ec, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + if lpOpts.PollPeriod == 0 { + lpOpts.PollPeriod = 1 * time.Hour + } + // TODO: We should be able to use an in memory log poller ORM here to speed up the tests. + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, pgtest.NewSqlxDB(t), lggr), ec, lggr, headTracker, lpOpts) + + feeTokens := []common.Address{utils.RandomAddress(), utils.RandomAddress()} + dest1 := uint64(10) + dest2 := uint64(11) + gasPriceUpdatesBlock1 := []cciptypes.GasPrice{ + { + DestChainSelector: dest1, + Value: big.NewInt(11), + }, + } + gasPriceUpdatesBlock2 := []cciptypes.GasPrice{ + { + DestChainSelector: dest1, // Reset same gas price + Value: big.NewInt(12), // Intentionally different from block1 + }, + { + DestChainSelector: dest2, // Set gas price for different chain + Value: big.NewInt(12), + }, + } + token1 := ccipcalc.EvmAddrToGeneric(utils.RandomAddress()) + token2 := ccipcalc.EvmAddrToGeneric(utils.RandomAddress()) + tokenPriceUpdatesBlock1 := []cciptypes.TokenPrice{ + { + Token: token1, + Value: big.NewInt(12), + }, + } + tokenPriceUpdatesBlock2 := []cciptypes.TokenPrice{ + { + Token: token1, + Value: big.NewInt(13), // Intentionally change token1 value + }, + { + Token: token2, + Value: big.NewInt(12), // Intentionally set a same value different token + }, + } + ctx := testutils.Context(t) + addr, _, _, err := price_registry_1_0_0.DeployPriceRegistry(user, ec, nil, feeTokens, 1000) + require.NoError(t, err) + addr2, _, _, err := price_registry_1_2_0.DeployPriceRegistry(user, ec, nil, feeTokens, 1000) + require.NoError(t, err) + commitAndGetBlockTs(ec) // Deploy these + pr10r, err := factory.NewPriceRegistryReader(ctx, lggr, factory.NewEvmVersionFinder(), ccipcalc.EvmAddrToGeneric(addr), lp, ec) + require.NoError(t, err) + assert.Equal(t, reflect.TypeOf(pr10r).String(), reflect.TypeOf(&v1_0_0.PriceRegistry{}).String()) + pr12r, err := factory.NewPriceRegistryReader(ctx, lggr, factory.NewEvmVersionFinder(), ccipcalc.EvmAddrToGeneric(addr2), lp, ec) + require.NoError(t, err) + assert.Equal(t, reflect.TypeOf(pr12r).String(), reflect.TypeOf(&v1_2_0.PriceRegistry{}).String()) + // Apply block1. + v1_0_0.ApplyPriceRegistryUpdate(t, user, addr, ec, gasPriceUpdatesBlock1, tokenPriceUpdatesBlock1) + v1_2_0.ApplyPriceRegistryUpdate(t, user, addr2, ec, gasPriceUpdatesBlock1, tokenPriceUpdatesBlock1) + b1 := commitAndGetBlockTs(ec) + // Apply block2 + v1_0_0.ApplyPriceRegistryUpdate(t, user, addr, ec, gasPriceUpdatesBlock2, tokenPriceUpdatesBlock2) + v1_2_0.ApplyPriceRegistryUpdate(t, user, addr2, ec, gasPriceUpdatesBlock2, tokenPriceUpdatesBlock2) + b2 := commitAndGetBlockTs(ec) + + // Capture all lp data. + lp.PollAndSaveLogs(context.Background(), 1) + + return priceRegReaderTH{ + lp: lp, + ec: ec, + lggr: lggr, + user: user, + readers: map[string]ccipdata.PriceRegistryReader{ + ccipdata.V1_0_0: pr10r, ccipdata.V1_2_0: pr12r, + }, + expectedFeeTokens: feeTokens, + expectedGasUpdates: map[uint64][]cciptypes.GasPrice{ + b1: gasPriceUpdatesBlock1, + b2: gasPriceUpdatesBlock2, + }, + expectedTokenUpdates: map[uint64][]cciptypes.TokenPrice{ + b1: tokenPriceUpdatesBlock1, + b2: tokenPriceUpdatesBlock2, + }, + blockTs: []uint64{b1, b2}, + destSelectors: []uint64{dest1, dest2}, + } +} + +func testPriceRegistryReader(t *testing.T, th priceRegReaderTH, pr ccipdata.PriceRegistryReader) { + // Assert have expected fee tokens. + gotFeeTokens, err := pr.GetFeeTokens(context.Background()) + require.NoError(t, err) + evmAddrs, err := ccipcalc.GenericAddrsToEvm(gotFeeTokens...) + require.NoError(t, err) + assert.Equal(t, th.expectedFeeTokens, evmAddrs) + + // Note unsupported chain selector simply returns an empty set not an error + gasUpdates, err := pr.GetGasPriceUpdatesCreatedAfter(context.Background(), 1e6, time.Unix(0, 0), 0) + require.NoError(t, err) + assert.Len(t, gasUpdates, 0) + + for i, ts := range th.blockTs { + // Should see all updates >= ts. + var expectedGas []cciptypes.GasPrice + var expectedDest0Gas []cciptypes.GasPrice + var expectedToken []cciptypes.TokenPrice + for j := i; j < len(th.blockTs); j++ { + expectedGas = append(expectedGas, th.expectedGasUpdates[th.blockTs[j]]...) + for _, g := range th.expectedGasUpdates[th.blockTs[j]] { + if g.DestChainSelector == th.destSelectors[0] { + expectedDest0Gas = append(expectedDest0Gas, g) + } + } + expectedToken = append(expectedToken, th.expectedTokenUpdates[th.blockTs[j]]...) + } + gasUpdates, err = pr.GetAllGasPriceUpdatesCreatedAfter(context.Background(), time.Unix(int64(ts-1), 0), 0) + require.NoError(t, err) + assert.Len(t, gasUpdates, len(expectedGas)) + + gasUpdates, err = pr.GetGasPriceUpdatesCreatedAfter(context.Background(), th.destSelectors[0], time.Unix(int64(ts-1), 0), 0) + require.NoError(t, err) + assert.Len(t, gasUpdates, len(expectedDest0Gas)) + + tokenUpdates, err2 := pr.GetTokenPriceUpdatesCreatedAfter(context.Background(), time.Unix(int64(ts-1), 0), 0) + require.NoError(t, err2) + assert.Len(t, tokenUpdates, len(expectedToken)) + } + + // Empty token set should return empty set no error. + gotEmpty, err := pr.GetTokenPrices(context.Background(), []cciptypes.Address{}) + require.NoError(t, err) + assert.Len(t, gotEmpty, 0) + + // We expect latest token prices to apply + allTokenUpdates, err := pr.GetTokenPriceUpdatesCreatedAfter(context.Background(), time.Unix(0, 0), 0) + require.NoError(t, err) + // Build latest map + latest := make(map[cciptypes.Address]*big.Int) + // Comes back in ascending order (oldest first) + var allTokens []cciptypes.Address + for i := len(allTokenUpdates) - 1; i >= 0; i-- { + assert.NoError(t, err) + _, have := latest[allTokenUpdates[i].Token] + if have { + continue + } + latest[allTokenUpdates[i].Token] = allTokenUpdates[i].Value + allTokens = append(allTokens, allTokenUpdates[i].Token) + } + tokenPrices, err := pr.GetTokenPrices(context.Background(), allTokens) + require.NoError(t, err) + require.Len(t, tokenPrices, len(allTokens)) + for _, p := range tokenPrices { + assert.Equal(t, p.Value, latest[p.Token]) + } +} + +func TestPriceRegistryReader(t *testing.T) { + th := setupPriceRegistryReaderTH(t) + // Assert all readers produce the same expected results. + for version, pr := range th.readers { + pr := pr + t.Run("PriceRegistryReader"+version, func(t *testing.T) { + testPriceRegistryReader(t, th, pr) + }) + } +} + +func TestNewPriceRegistryReader(t *testing.T) { + var tt = []struct { + typeAndVersion string + expectedErr string + }{ + { + typeAndVersion: "blah", + expectedErr: "unable to read type and version: invalid type and version blah", + }, + { + typeAndVersion: "EVM2EVMOffRamp 1.0.0", + expectedErr: "expected PriceRegistry got EVM2EVMOffRamp", + }, + { + typeAndVersion: "PriceRegistry 1.2.0", + expectedErr: "", + }, + { + typeAndVersion: "PriceRegistry 1.6.0-dev", + expectedErr: "", + }, + { + typeAndVersion: "PriceRegistry 2.0.0", + expectedErr: "unsupported price registry version 2.0.0", + }, + } + ctx := testutils.Context(t) + for _, tc := range tt { + t.Run(tc.typeAndVersion, func(t *testing.T) { + b, err := utils.ABIEncode(`[{"type":"string"}]`, tc.typeAndVersion) + require.NoError(t, err) + c := evmclientmocks.NewClient(t) + c.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(b, nil) + addr := ccipcalc.EvmAddrToGeneric(utils.RandomAddress()) + lp := lpmocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil).Maybe() + _, err = factory.NewPriceRegistryReader(ctx, logger.TestLogger(t), factory.NewEvmVersionFinder(), addr, lp, c) + if tc.expectedErr != "" { + require.EqualError(t, err, tc.expectedErr) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go new file mode 100644 index 0000000000..a9a07f0879 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go @@ -0,0 +1,78 @@ +package ccipdata + +import ( + "fmt" + "time" + + "github.com/ethereum/go-ethereum/core/types" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +const ( + V1_0_0 = "1.0.0" + V1_1_0 = "1.1.0" + V1_2_0 = "1.2.0" + V1_4_0 = "1.4.0" + V1_5_0 = "1.5.0-dev" + V1_6_0 = "1.6.0-dev" +) + +const ( + // CommitExecLogsRetention defines the duration for which logs critical for Commit/Exec plugins processing are retained. + // Although Exec relies on permissionlessExecThreshold which is lower than 24hours for picking eligible CommitRoots, + // Commit still can reach to older logs because it filters them by sequence numbers. For instance, in case of RMN curse on chain, + // we might have logs waiting in OnRamp to be committed first. When outage takes days we still would + // be able to bring back processing without replaying any logs from chain. You can read that param as + // "how long CCIP can be down and still be able to process all the messages after getting back to life". + // Breaching this threshold would require replaying chain using LogPoller from the beginning of the outage. + CommitExecLogsRetention = 30 * 24 * time.Hour // 30 days + // CacheEvictionLogsRetention defines the duration for which logs used for caching on-chain data are kept. + // Restarting node clears the cache entirely and rebuilds it from scratch by fetching data from chain, + // so we don't need to keep these logs for very long. All events relying on cache.NewLogpollerEventsBased should use this retention. + CacheEvictionLogsRetention = 7 * 24 * time.Hour // 7 days + // PriceUpdatesLogsRetention defines the duration for which logs with price updates are kept. + // These logs are emitted whenever the token price or gas price is updated and Commit scans very small time windows (e.g. 2 hours) + PriceUpdatesLogsRetention = 1 * 24 * time.Hour // 1 day +) + +type Event[T any] struct { + Data T + cciptypes.TxMeta +} + +func LogsConfirmations(finalized bool) evmtypes.Confirmations { + if finalized { + return evmtypes.Finalized + } + return evmtypes.Unconfirmed +} + +func ParseLogs[T any](logs []logpoller.Log, lggr logger.Logger, parseFunc func(log types.Log) (*T, error)) ([]Event[T], error) { + reqs := make([]Event[T], 0, len(logs)) + + for _, log := range logs { + data, err := parseFunc(log.ToGethLog()) + if err != nil { + lggr.Errorw("Unable to parse log", "err", err) + continue + } + reqs = append(reqs, Event[T]{ + Data: *data, + TxMeta: cciptypes.TxMeta{ + BlockTimestampUnixMilli: log.BlockTimestamp.UnixMilli(), + BlockNumber: uint64(log.BlockNumber), + TxHash: log.TxHash.String(), + LogIndex: uint64(log.LogIndex), + }, + }) + } + + if len(logs) != len(reqs) { + return nil, fmt.Errorf("%d logs were not parsed", len(logs)-len(reqs)) + } + return reqs, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader_test.go new file mode 100644 index 0000000000..06766be81e --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader_test.go @@ -0,0 +1,72 @@ +package ccipdata + +import ( + "fmt" + "testing" + "time" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func Test_parseLogs(t *testing.T) { + // generate 100 logs + logs := make([]logpoller.Log, 100) + for i := range logs { + logs[i].LogIndex = int64(i + 1) + logs[i].BlockNumber = int64(i) * 1000 + logs[i].BlockTimestamp = time.Now() + } + + parseFn := func(log types.Log) (*uint, error) { + return &log.Index, nil + } + + parsedEvents, err := ParseLogs[uint](logs, logger.TestLogger(t), parseFn) + require.NoError(t, err) + assert.Len(t, parsedEvents, 100) + + // Make sure everything is parsed according to the parse func + for i, ev := range parsedEvents { + assert.Equal(t, i+1, int(ev.Data)) + assert.Equal(t, i*1000, int(ev.BlockNumber)) + assert.Greater(t, ev.BlockTimestampUnixMilli, time.Now().Add(-time.Minute).UnixMilli()) + } +} + +func Test_parseLogs_withErrors(t *testing.T) { + // generate 50 valid logs and 50 errors + actualErrorCount := 50 + logs := make([]logpoller.Log, actualErrorCount*2) + for i := range logs { + logs[i].LogIndex = int64(i + 1) + } + + // return an error for half of the logs. + parseFn := func(log types.Log) (*uint, error) { + if log.Index%2 == 0 { + return nil, fmt.Errorf("cannot parse %d", log.Index) + } + return &log.Index, nil + } + + log, observed := logger.TestLoggerObserved(t, zapcore.DebugLevel) + parsedEvents, err := ParseLogs[uint](logs, log, parseFn) + assert.ErrorContains(t, err, fmt.Sprintf("%d logs were not parsed", len(logs)/2)) + assert.Nil(t, parsedEvents, "No events are returned if there was an error.") + + // logs are written for errors. + require.Equal(t, actualErrorCount, observed.Len(), "Expect 51 warnings: one for each error and a summary.") + for i, entry := range observed.All() { + assert.Equal(t, zapcore.ErrorLevel, entry.Level) + assert.Contains(t, entry.Message, "Unable to parse log") + contextMap := entry.ContextMap() + require.Contains(t, contextMap, "err") + assert.Contains(t, contextMap["err"], fmt.Sprintf("cannot parse %d", (i+1)*2), "each error should be logged as a warning") + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/retry_config.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/retry_config.go new file mode 100644 index 0000000000..41161ee938 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/retry_config.go @@ -0,0 +1,9 @@ +package ccipdata + +import "time" + +// RetryConfig configures an initial delay between retries and a max delay between retries +type RetryConfig struct { + InitialDelay time.Duration + MaxDelay time.Duration +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/test_utils.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/test_utils.go new file mode 100644 index 0000000000..6dc51b888e --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/test_utils.go @@ -0,0 +1,36 @@ +package ccipdata + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" +) + +// NewSimulation returns a client and a simulated backend. +func NewSimulation(t testing.TB) (*bind.TransactOpts, *client.SimulatedBackendClient) { + user := testutils.MustNewSimTransactor(t) + simulatedBackend := backends.NewSimulatedBackend(map[common.Address]core.GenesisAccount{ + user.From: { + Balance: big.NewInt(0).Mul(big.NewInt(3), big.NewInt(1e18)), + }, + }, 10e6) + simulatedBackendClient := client.NewSimulatedBackendClient(t, simulatedBackend, testutils.SimulatedChainID) + return user, simulatedBackendClient +} + +// AssertNonRevert Verify that a transaction was not reverted. +func AssertNonRevert(t testing.TB, tx *types.Transaction, bc *client.SimulatedBackendClient, user *bind.TransactOpts) { + require.NotNil(t, tx, "Transaction should not be nil") + receipt, err := bc.TransactionReceipt(user.Context, tx.Hash()) + require.NoError(t, err) + require.NotEqual(t, uint64(0), receipt.Status, "Transaction should not have reverted") +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/token_pool_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/token_pool_reader.go new file mode 100644 index 0000000000..999061f491 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/token_pool_reader.go @@ -0,0 +1,10 @@ +package ccipdata + +import ( + "github.com/ethereum/go-ethereum/common" +) + +type TokenPoolReader interface { + Address() common.Address + Type() string +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go new file mode 100644 index 0000000000..51ce0db7c0 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go @@ -0,0 +1,169 @@ +package ccipdata + +import ( + "context" + "fmt" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/patrickmn/go-cache" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" +) + +var ( + // shortLivedInMemLogsCacheExpiration is used for the short-lived in meme logs cache. + // Value should usually be set to just a few seconds, a larger duration will not increase performance and might + // cause performance issues on re-orged logs. + shortLivedInMemLogsCacheExpiration = 20 * time.Second +) + +const ( + MESSAGE_SENT_FILTER_NAME = "USDC message sent" +) + +var _ USDCReader = &USDCReaderImpl{} + +type USDCReader interface { + // GetUSDCMessagePriorToLogIndexInTx returns the specified USDC message data. + // e.g. if msg contains 3 tokens: [usdc1, wETH, usdc2] ignoring non-usdc tokens + // if usdcTokenIndexOffset is 0 we select usdc2 + // if usdcTokenIndexOffset is 1 we select usdc1 + // The message logs are found using the provided transaction hash. + GetUSDCMessagePriorToLogIndexInTx(ctx context.Context, logIndex int64, usdcTokenIndexOffset int, txHash string) ([]byte, error) +} + +type USDCReaderImpl struct { + usdcMessageSent common.Hash + lp logpoller.LogPoller + filter logpoller.Filter + lggr logger.Logger + transmitterAddress common.Address + + // shortLivedInMemLogs is a short-lived cache (items expire every few seconds) + // used to prevent frequent log fetching from the log poller + shortLivedInMemLogs *cache.Cache +} + +func (u *USDCReaderImpl) Close() error { + // FIXME Dim pgOpts removed from LogPoller + return u.lp.UnregisterFilter(context.Background(), u.filter.Name) +} + +func (u *USDCReaderImpl) RegisterFilters() error { + // FIXME Dim pgOpts removed from LogPoller + return u.lp.RegisterFilter(context.Background(), u.filter) +} + +// usdcPayload has to match the onchain event emitted by the USDC message transmitter +type usdcPayload []byte + +func (d usdcPayload) AbiString() string { + return `[{"type": "bytes"}]` +} + +func (d usdcPayload) Validate() error { + if len(d) == 0 { + return errors.New("must be non-empty") + } + return nil +} + +func parseUSDCMessageSent(logData []byte) ([]byte, error) { + decodeAbiStruct, err := abihelpers.DecodeAbiStruct[usdcPayload](logData) + if err != nil { + return nil, err + } + return decodeAbiStruct, nil +} + +func (u *USDCReaderImpl) GetUSDCMessagePriorToLogIndexInTx(ctx context.Context, logIndex int64, usdcTokenIndexOffset int, txHash string) ([]byte, error) { + var lpLogs []logpoller.Log + + // fetch all the usdc logs for the provided tx hash + k := fmt.Sprintf("usdc-%s", txHash) // custom prefix to avoid key collision if someone re-uses the cache + if rawLogs, foundInMem := u.shortLivedInMemLogs.Get(k); foundInMem { + inMemLogs, ok := rawLogs.([]logpoller.Log) + if !ok { + return nil, errors.Errorf("unexpected in-mem logs type %T", rawLogs) + } + u.lggr.Debugw("found logs in memory", "k", k, "len", len(inMemLogs)) + lpLogs = inMemLogs + } + + if len(lpLogs) == 0 { + u.lggr.Debugw("fetching logs from lp", "k", k) + logs, err := u.lp.IndexedLogsByTxHash( + ctx, + u.usdcMessageSent, + u.transmitterAddress, + common.HexToHash(txHash), + ) + if err != nil { + return nil, err + } + lpLogs = logs + u.shortLivedInMemLogs.Set(k, logs, cache.DefaultExpiration) + u.lggr.Debugw("fetched logs from lp", "logs", len(lpLogs)) + } + + // collect the logs with log index less than the provided log index + allUsdcTokensData := make([][]byte, 0) + for _, current := range lpLogs { + if current.LogIndex < logIndex { + u.lggr.Infow("Found USDC message", "logIndex", current.LogIndex, "txHash", current.TxHash.Hex(), "data", hexutil.Encode(current.Data)) + allUsdcTokensData = append(allUsdcTokensData, current.Data) + } + } + + usdcTokenIndex := (len(allUsdcTokensData) - 1) - usdcTokenIndexOffset + + if usdcTokenIndex < 0 || usdcTokenIndex >= len(allUsdcTokensData) { + u.lggr.Errorw("usdc message not found", + "logIndex", logIndex, + "allUsdcTokenData", len(allUsdcTokensData), + "txHash", txHash, + "usdcTokenIndex", usdcTokenIndex, + ) + return nil, errors.Errorf("usdc token index %d is not valid", usdcTokenIndex) + } + return parseUSDCMessageSent(allUsdcTokensData[usdcTokenIndex]) +} + +func NewUSDCReader(lggr logger.Logger, jobID string, transmitter common.Address, lp logpoller.LogPoller, registerFilters bool) (*USDCReaderImpl, error) { + eventSig := utils.Keccak256Fixed([]byte("MessageSent(bytes)")) + + r := &USDCReaderImpl{ + lggr: lggr, + lp: lp, + usdcMessageSent: eventSig, + filter: logpoller.Filter{ + Name: logpoller.FilterName(MESSAGE_SENT_FILTER_NAME, jobID, transmitter.Hex()), + EventSigs: []common.Hash{eventSig}, + Addresses: []common.Address{transmitter}, + Retention: CommitExecLogsRetention, + }, + transmitterAddress: transmitter, + shortLivedInMemLogs: cache.New(shortLivedInMemLogsCacheExpiration, 2*shortLivedInMemLogsCacheExpiration), + } + + if registerFilters { + if err := r.RegisterFilters(); err != nil { + return nil, fmt.Errorf("register filters: %w", err) + } + } + return r, nil +} + +func CloseUSDCReader(lggr logger.Logger, jobID string, transmitter common.Address, lp logpoller.LogPoller) error { + r, err := NewUSDCReader(lggr, jobID, transmitter, lp, false) + if err != nil { + return err + } + return r.Close() +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_internal_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_internal_test.go new file mode 100644 index 0000000000..a5f0a1ffd0 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_internal_test.go @@ -0,0 +1,178 @@ +package ccipdata + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestLogPollerClient_GetUSDCMessagePriorToLogIndexInTx(t *testing.T) { + addr := utils.RandomAddress() + txHash := common.BytesToHash(addr[:]) + ccipLogIndex := int64(100) + + expectedData := "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000" + expectedPostParse := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" + lggr := logger.TestLogger(t) + + t.Run("multiple found - selected last", func(t *testing.T) { + lp := lpmocks.NewLogPoller(t) + u, _ := NewUSDCReader(lggr, "job_123", utils.RandomAddress(), lp, false) + + lp.On("IndexedLogsByTxHash", + mock.Anything, + u.usdcMessageSent, + u.transmitterAddress, + txHash, + ).Return([]logpoller.Log{ + {LogIndex: ccipLogIndex - 2, Data: []byte("-2")}, + {LogIndex: ccipLogIndex - 1, Data: hexutil.MustDecode(expectedData)}, + {LogIndex: ccipLogIndex, Data: []byte("0")}, + {LogIndex: ccipLogIndex + 1, Data: []byte("1")}, + }, nil) + usdcMessageData, err := u.GetUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, 0, txHash.String()) + assert.NoError(t, err) + assert.Equal(t, expectedPostParse, hexutil.Encode(usdcMessageData)) + lp.AssertExpectations(t) + }) + + t.Run("multiple found - selected first", func(t *testing.T) { + lp := lpmocks.NewLogPoller(t) + u, _ := NewUSDCReader(lggr, "job_123", utils.RandomAddress(), lp, false) + + lp.On("IndexedLogsByTxHash", + mock.Anything, + u.usdcMessageSent, + u.transmitterAddress, + txHash, + ).Return([]logpoller.Log{ + {LogIndex: ccipLogIndex - 2, Data: hexutil.MustDecode(expectedData)}, + {LogIndex: ccipLogIndex - 1, Data: []byte("-2")}, + {LogIndex: ccipLogIndex, Data: []byte("0")}, + {LogIndex: ccipLogIndex + 1, Data: []byte("1")}, + }, nil) + usdcMessageData, err := u.GetUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, 1, txHash.String()) + assert.NoError(t, err) + assert.Equal(t, expectedPostParse, hexutil.Encode(usdcMessageData)) + lp.AssertExpectations(t) + }) + + t.Run("logs fetched from memory in subsequent calls", func(t *testing.T) { + lp := lpmocks.NewLogPoller(t) + u, _ := NewUSDCReader(lggr, "job_123", utils.RandomAddress(), lp, false) + + lp.On("IndexedLogsByTxHash", + mock.Anything, + u.usdcMessageSent, + u.transmitterAddress, + txHash, + ).Return([]logpoller.Log{ + {LogIndex: ccipLogIndex - 2, Data: hexutil.MustDecode(expectedData)}, + {LogIndex: ccipLogIndex - 1, Data: []byte("-2")}, + {LogIndex: ccipLogIndex, Data: []byte("0")}, + {LogIndex: ccipLogIndex + 1, Data: []byte("1")}, + }, nil).Once() + + // first call logs must be fetched from lp + usdcMessageData, err := u.GetUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, 1, txHash.String()) + assert.NoError(t, err) + assert.Equal(t, expectedPostParse, hexutil.Encode(usdcMessageData)) + + // subsequent call, logs must be fetched from memory + usdcMessageData, err = u.GetUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, 1, txHash.String()) + assert.NoError(t, err) + assert.Equal(t, expectedPostParse, hexutil.Encode(usdcMessageData)) + + lp.AssertExpectations(t) + }) + + t.Run("none found", func(t *testing.T) { + lp := lpmocks.NewLogPoller(t) + u, _ := NewUSDCReader(lggr, "job_123", utils.RandomAddress(), lp, false) + lp.On("IndexedLogsByTxHash", + mock.Anything, + u.usdcMessageSent, + u.transmitterAddress, + txHash, + ).Return([]logpoller.Log{}, nil) + + usdcMessageData, err := u.GetUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, 0, txHash.String()) + assert.Errorf(t, err, fmt.Sprintf("no USDC message found prior to log index %d in tx %s", ccipLogIndex, txHash.Hex())) + assert.Nil(t, usdcMessageData) + + lp.AssertExpectations(t) + }) +} + +func TestParse(t *testing.T) { + expectedBody, err := hexutil.Decode("0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000") + require.NoError(t, err) + + parsedBody, err := parseUSDCMessageSent(expectedBody) + require.NoError(t, err) + + expectedPostParse := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" + + require.Equal(t, expectedPostParse, hexutil.Encode(parsedBody)) +} + +func TestFilters(t *testing.T) { + t.Run("filters of different jobs should be distinct", func(t *testing.T) { + lggr := logger.TestLogger(t) + chainID := testutils.NewRandomEVMChainID() + db := pgtest.NewSqlxDB(t) + o := logpoller.NewORM(chainID, db, lggr) + ec := backends.NewSimulatedBackend(map[common.Address]core.GenesisAccount{}, 10e6) + esc := client.NewSimulatedBackendClient(t, ec, chainID) + lpOpts := logpoller.Opts{ + PollPeriod: 1 * time.Hour, + FinalityDepth: 1, + BackfillBatchSize: 1, + RpcBatchSize: 1, + KeepFinalizedBlocksDepth: 100, + } + headTracker := headtracker.NewSimulatedHeadTracker(esc, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + if lpOpts.PollPeriod == 0 { + lpOpts.PollPeriod = 1 * time.Hour + } + lp := logpoller.NewLogPoller(o, esc, lggr, headTracker, lpOpts) + + jobID1 := "job-1" + jobID2 := "job-2" + transmitter := utils.RandomAddress() + + f1 := logpoller.FilterName("USDC message sent", jobID1, transmitter.Hex()) + f2 := logpoller.FilterName("USDC message sent", jobID2, transmitter.Hex()) + + _, err := NewUSDCReader(lggr, jobID1, transmitter, lp, true) + assert.NoError(t, err) + assert.True(t, lp.HasFilter(f1)) + + _, err = NewUSDCReader(lggr, jobID2, transmitter, lp, true) + assert.NoError(t, err) + assert.True(t, lp.HasFilter(f2)) + + err = CloseUSDCReader(lggr, jobID2, transmitter, lp) + assert.NoError(t, err) + assert.True(t, lp.HasFilter(f1)) + assert.False(t, lp.HasFilter(f2)) + }) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go new file mode 100644 index 0000000000..3e58143a28 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go @@ -0,0 +1,456 @@ +package v1_0_0 + +import ( + "context" + "fmt" + "math/big" + "sync" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/types/query" + "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +const ( + EXEC_REPORT_ACCEPTS = "Exec report accepts" + ReportAccepted = "ReportAccepted" +) + +var _ ccipdata.CommitStoreReader = &CommitStore{} + +type CommitStore struct { + // Static config + commitStore *commit_store_1_0_0.CommitStore + lggr logger.Logger + lp logpoller.LogPoller + address common.Address + estimator *gas.EvmFeeEstimator + sourceMaxGasPrice *big.Int + filters []logpoller.Filter + reportAcceptedSig common.Hash + reportAcceptedMaxSeqIndex int + commitReportArgs abi.Arguments + + // Dynamic config + configMu sync.RWMutex + gasPriceEstimator prices.ExecGasPriceEstimator + offchainConfig cciptypes.CommitOffchainConfig +} + +func (c *CommitStore) GetCommitStoreStaticConfig(ctx context.Context) (cciptypes.CommitStoreStaticConfig, error) { + legacyConfig, err := c.commitStore.GetStaticConfig(&bind.CallOpts{Context: ctx}) + if err != nil { + return cciptypes.CommitStoreStaticConfig{}, errors.New("Could not get commitStore static config") + } + return cciptypes.CommitStoreStaticConfig{ + ChainSelector: legacyConfig.ChainSelector, + SourceChainSelector: legacyConfig.SourceChainSelector, + OnRamp: ccipcalc.EvmAddrToGeneric(legacyConfig.OnRamp), + ArmProxy: ccipcalc.EvmAddrToGeneric(legacyConfig.ArmProxy), + }, nil +} + +func (c *CommitStore) EncodeCommitReport(_ context.Context, report cciptypes.CommitStoreReport) ([]byte, error) { + return encodeCommitReport(c.commitReportArgs, report) +} + +func encodeCommitReport(commitReportArgs abi.Arguments, report cciptypes.CommitStoreReport) ([]byte, error) { + var tokenPriceUpdates []commit_store_1_0_0.InternalTokenPriceUpdate + for _, tokenPriceUpdate := range report.TokenPrices { + sourceTokenEvmAddr, err := ccipcalc.GenericAddrToEvm(tokenPriceUpdate.Token) + if err != nil { + return nil, err + } + tokenPriceUpdates = append(tokenPriceUpdates, commit_store_1_0_0.InternalTokenPriceUpdate{ + SourceToken: sourceTokenEvmAddr, + UsdPerToken: tokenPriceUpdate.Value, + }) + } + var usdPerUnitGas = big.NewInt(0) + var destChainSelector = uint64(0) + if len(report.GasPrices) > 1 { + return []byte{}, errors.Errorf("CommitStore V1_0_0 can only accept 1 gas price, received: %d", len(report.GasPrices)) + } + if len(report.GasPrices) > 0 { + usdPerUnitGas = report.GasPrices[0].Value + destChainSelector = report.GasPrices[0].DestChainSelector + } + rep := commit_store_1_0_0.CommitStoreCommitReport{ + PriceUpdates: commit_store_1_0_0.InternalPriceUpdates{ + TokenPriceUpdates: tokenPriceUpdates, + UsdPerUnitGas: usdPerUnitGas, + DestChainSelector: destChainSelector, + }, + Interval: commit_store_1_0_0.CommitStoreInterval{Min: report.Interval.Min, Max: report.Interval.Max}, + MerkleRoot: report.MerkleRoot, + } + return commitReportArgs.PackValues([]interface{}{rep}) +} + +func DecodeCommitReport(commitReportArgs abi.Arguments, report []byte) (cciptypes.CommitStoreReport, error) { + unpacked, err := commitReportArgs.Unpack(report) + if err != nil { + return cciptypes.CommitStoreReport{}, err + } + if len(unpacked) != 1 { + return cciptypes.CommitStoreReport{}, errors.New("expected single struct value") + } + + commitReport, ok := unpacked[0].(struct { + PriceUpdates struct { + TokenPriceUpdates []struct { + SourceToken common.Address `json:"sourceToken"` + UsdPerToken *big.Int `json:"usdPerToken"` + } `json:"tokenPriceUpdates"` + DestChainSelector uint64 `json:"destChainSelector"` + UsdPerUnitGas *big.Int `json:"usdPerUnitGas"` + } `json:"priceUpdates"` + Interval struct { + Min uint64 `json:"min"` + Max uint64 `json:"max"` + } `json:"interval"` + MerkleRoot [32]byte `json:"merkleRoot"` + }) + if !ok { + return cciptypes.CommitStoreReport{}, errors.Errorf("invalid commit report got %T", unpacked[0]) + } + + var tokenPriceUpdates []cciptypes.TokenPrice + for _, u := range commitReport.PriceUpdates.TokenPriceUpdates { + tokenPriceUpdates = append(tokenPriceUpdates, cciptypes.TokenPrice{ + Token: cciptypes.Address(u.SourceToken.String()), + Value: u.UsdPerToken, + }) + } + + var gasPrices []cciptypes.GasPrice + if commitReport.PriceUpdates.DestChainSelector != 0 { + // No gas price update { + gasPrices = append(gasPrices, cciptypes.GasPrice{ + DestChainSelector: commitReport.PriceUpdates.DestChainSelector, + Value: commitReport.PriceUpdates.UsdPerUnitGas, + }) + } + + return cciptypes.CommitStoreReport{ + TokenPrices: tokenPriceUpdates, + GasPrices: gasPrices, + Interval: cciptypes.CommitStoreInterval{ + Min: commitReport.Interval.Min, + Max: commitReport.Interval.Max, + }, + MerkleRoot: commitReport.MerkleRoot, + }, nil +} + +func (c *CommitStore) DecodeCommitReport(_ context.Context, report []byte) (cciptypes.CommitStoreReport, error) { + return DecodeCommitReport(c.commitReportArgs, report) +} + +func (c *CommitStore) IsBlessed(ctx context.Context, root [32]byte) (bool, error) { + return c.commitStore.IsBlessed(&bind.CallOpts{Context: ctx}, root) +} + +func (c *CommitStore) OffchainConfig(context.Context) (cciptypes.CommitOffchainConfig, error) { + c.configMu.RLock() + defer c.configMu.RUnlock() + return c.offchainConfig, nil +} + +func (c *CommitStore) GasPriceEstimator(context.Context) (cciptypes.GasPriceEstimatorCommit, error) { + c.configMu.RLock() + defer c.configMu.RUnlock() + return c.gasPriceEstimator, nil +} + +func (c *CommitStore) SetGasEstimator(ctx context.Context, gpe gas.EvmFeeEstimator) error { + c.configMu.RLock() + defer c.configMu.RUnlock() + c.estimator = &gpe + return nil +} + +func (c *CommitStore) SetSourceMaxGasPrice(ctx context.Context, sourceMaxGasPrice *big.Int) error { + c.configMu.RLock() + defer c.configMu.RUnlock() + c.sourceMaxGasPrice = sourceMaxGasPrice + return nil +} + +// CommitOffchainConfig is a legacy version of CommitOffchainConfig, used for CommitStore version 1.0.0 and 1.1.0 +type CommitOffchainConfig struct { + SourceFinalityDepth uint32 + DestFinalityDepth uint32 + FeeUpdateHeartBeat config.Duration + FeeUpdateDeviationPPB uint32 + InflightCacheExpiry config.Duration + PriceReportingDisabled bool +} + +func (c CommitOffchainConfig) Validate() error { + if c.SourceFinalityDepth == 0 { + return errors.New("must set SourceFinalityDepth") + } + if c.DestFinalityDepth == 0 { + return errors.New("must set DestFinalityDepth") + } + if c.FeeUpdateHeartBeat.Duration() == 0 { + return errors.New("must set FeeUpdateHeartBeat") + } + if c.FeeUpdateDeviationPPB == 0 { + return errors.New("must set FeeUpdateDeviationPPB") + } + if c.InflightCacheExpiry.Duration() == 0 { + return errors.New("must set InflightCacheExpiry") + } + + return nil +} + +func (c *CommitStore) ChangeConfig(_ context.Context, onchainConfig []byte, offchainConfig []byte) (cciptypes.Address, error) { + onchainConfigParsed, err := abihelpers.DecodeAbiStruct[ccipdata.CommitOnchainConfig](onchainConfig) + if err != nil { + return "", err + } + + offchainConfigV1, err := ccipconfig.DecodeOffchainConfig[CommitOffchainConfig](offchainConfig) + if err != nil { + return "", err + } + c.configMu.Lock() + defer c.configMu.Unlock() + + if c.estimator == nil { + return "", fmt.Errorf("this CommitStore estimator is nil. SetGasEstimator should be called before ChangeConfig") + } + + if c.sourceMaxGasPrice == nil { + return "", fmt.Errorf("this CommitStore sourceMaxGasPrice is nil. SetSourceMaxGasPrice should be called before ChangeConfig") + } + + c.gasPriceEstimator = prices.NewExecGasPriceEstimator( + *c.estimator, + c.sourceMaxGasPrice, + int64(offchainConfigV1.FeeUpdateDeviationPPB)) + c.offchainConfig = ccipdata.NewCommitOffchainConfig( + offchainConfigV1.FeeUpdateDeviationPPB, + offchainConfigV1.FeeUpdateHeartBeat.Duration(), + offchainConfigV1.FeeUpdateDeviationPPB, + offchainConfigV1.FeeUpdateHeartBeat.Duration(), + offchainConfigV1.InflightCacheExpiry.Duration(), + offchainConfigV1.PriceReportingDisabled) + c.lggr.Infow("ChangeConfig", + "offchainConfig", offchainConfigV1, + "onchainConfig", onchainConfigParsed, + ) + return cciptypes.Address(onchainConfigParsed.PriceRegistry.String()), nil +} + +func (c *CommitStore) Close() error { + return logpollerutil.UnregisterLpFilters(c.lp, c.filters) +} + +func (c *CommitStore) parseReport(log types.Log) (*cciptypes.CommitStoreReport, error) { + repAccepted, err := c.commitStore.ParseReportAccepted(log) + if err != nil { + return nil, err + } + // Translate to common struct. + var tokenPrices []cciptypes.TokenPrice + for _, tpu := range repAccepted.Report.PriceUpdates.TokenPriceUpdates { + tokenPrices = append(tokenPrices, cciptypes.TokenPrice{ + Token: cciptypes.Address(tpu.SourceToken.String()), + Value: tpu.UsdPerToken, + }) + } + return &cciptypes.CommitStoreReport{ + TokenPrices: tokenPrices, + GasPrices: []cciptypes.GasPrice{{DestChainSelector: repAccepted.Report.PriceUpdates.DestChainSelector, Value: repAccepted.Report.PriceUpdates.UsdPerUnitGas}}, + MerkleRoot: repAccepted.Report.MerkleRoot, + Interval: cciptypes.CommitStoreInterval{Min: repAccepted.Report.Interval.Min, Max: repAccepted.Report.Interval.Max}, + }, nil +} + +func (c *CommitStore) GetCommitReportMatchingSeqNum(ctx context.Context, seqNr uint64, confs int) ([]cciptypes.CommitStoreReportWithTxMeta, error) { + logs, err := c.lp.LogsDataWordBetween( + ctx, + c.reportAcceptedSig, + c.address, + c.reportAcceptedMaxSeqIndex-1, + c.reportAcceptedMaxSeqIndex, + logpoller.EvmWord(seqNr), + evmtypes.Confirmations(confs), + ) + if err != nil { + return nil, err + } + + parsedLogs, err := ccipdata.ParseLogs[cciptypes.CommitStoreReport]( + logs, + c.lggr, + c.parseReport, + ) + if err != nil { + return nil, err + } + + res := make([]cciptypes.CommitStoreReportWithTxMeta, 0, len(parsedLogs)) + for _, log := range parsedLogs { + res = append(res, cciptypes.CommitStoreReportWithTxMeta{ + TxMeta: log.TxMeta, + CommitStoreReport: log.Data, + }) + } + + if len(res) > 1 { + c.lggr.Errorw("More than one report found for seqNr", "seqNr", seqNr, "commitReports", parsedLogs) + return res[:1], nil + } + return res, nil +} + +func (c *CommitStore) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confs int) ([]cciptypes.CommitStoreReportWithTxMeta, error) { + latestBlock, err := c.lp.LatestBlock(ctx) + if err != nil { + return nil, err + } + + reportsQuery, err := query.Where( + c.address.String(), + logpoller.NewAddressFilter(c.address), + logpoller.NewEventSigFilter(c.reportAcceptedSig), + query.Timestamp(uint64(ts.Unix()), primitives.Gte), + logpoller.NewConfirmationsFilter(evmtypes.Confirmations(confs)), + ) + if err != nil { + return nil, err + } + + logs, err := c.lp.FilteredLogs( + ctx, + reportsQuery, + query.NewLimitAndSort(query.Limit{}, query.NewSortBySequence(query.Asc)), + "GetAcceptedCommitReportsGteTimestamp", + ) + if err != nil { + return nil, err + } + + parsedLogs, err := ccipdata.ParseLogs[cciptypes.CommitStoreReport](logs, c.lggr, c.parseReport) + if err != nil { + return nil, fmt.Errorf("parse logs: %w", err) + } + + parsedReports := make([]cciptypes.CommitStoreReportWithTxMeta, 0, len(parsedLogs)) + for _, log := range parsedLogs { + parsedReports = append(parsedReports, cciptypes.CommitStoreReportWithTxMeta{ + TxMeta: log.TxMeta.WithFinalityStatus(uint64(latestBlock.FinalizedBlockNumber)), + CommitStoreReport: log.Data, + }) + } + + return parsedReports, nil +} + +func (c *CommitStore) GetExpectedNextSequenceNumber(ctx context.Context) (uint64, error) { + return c.commitStore.GetExpectedNextSequenceNumber(&bind.CallOpts{Context: ctx}) +} + +func (c *CommitStore) GetLatestPriceEpochAndRound(ctx context.Context) (uint64, error) { + return c.commitStore.GetLatestPriceEpochAndRound(&bind.CallOpts{Context: ctx}) +} + +func (c *CommitStore) IsDestChainHealthy(context.Context) (bool, error) { + if err := c.lp.Healthy(); err != nil { + return false, nil + } + return true, nil +} + +func (c *CommitStore) IsDown(ctx context.Context) (bool, error) { + unPausedAndHealthy, err := c.commitStore.IsUnpausedAndARMHealthy(&bind.CallOpts{Context: ctx}) + if err != nil { + return true, err + } + return !unPausedAndHealthy, nil +} + +func (c *CommitStore) VerifyExecutionReport(ctx context.Context, report cciptypes.ExecReport) (bool, error) { + var hashes [][32]byte + for _, msg := range report.Messages { + hashes = append(hashes, msg.Hash) + } + res, err := c.commitStore.Verify(&bind.CallOpts{Context: ctx}, hashes, report.Proofs, report.ProofFlagBits) + if err != nil { + c.lggr.Errorw("Unable to call verify", "messages", report.Messages, "err", err) + return false, nil + } + // No timestamp, means failed to verify root. + if res.Cmp(big.NewInt(0)) == 0 { + c.lggr.Errorw("Root does not verify", "messages", report.Messages) + return false, nil + } + return true, nil +} + +func (c *CommitStore) RegisterFilters() error { + return logpollerutil.RegisterLpFilters(c.lp, c.filters) +} + +func NewCommitStore(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller) (*CommitStore, error) { + commitStore, err := commit_store_1_0_0.NewCommitStore(addr, ec) + if err != nil { + return nil, err + } + commitStoreABI := abihelpers.MustParseABI(commit_store_1_0_0.CommitStoreABI) + eventSig := abihelpers.MustGetEventID(ReportAccepted, commitStoreABI) + commitReportArgs := abihelpers.MustGetEventInputs(ReportAccepted, commitStoreABI) + filters := []logpoller.Filter{ + { + Name: logpoller.FilterName(EXEC_REPORT_ACCEPTS, addr.String()), + EventSigs: []common.Hash{eventSig}, + Addresses: []common.Address{addr}, + Retention: ccipdata.CommitExecLogsRetention, + }, + } + return &CommitStore{ + commitStore: commitStore, + address: addr, + lggr: lggr, + lp: lp, + + // Note that sourceMaxGasPrice and estimator now have explicit setters (CCIP-2493) + + filters: filters, + commitReportArgs: commitReportArgs, + reportAcceptedSig: eventSig, + // offset || priceUpdatesOffset || minSeqNum || maxSeqNum || merkleRoot + reportAcceptedMaxSeqIndex: 3, + configMu: sync.RWMutex{}, + + // The fields below are initially empty and set on ChangeConfig method + offchainConfig: cciptypes.CommitOffchainConfig{}, + gasPriceEstimator: prices.ExecGasPriceEstimator{}, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store_test.go new file mode 100644 index 0000000000..31bcaf8a18 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store_test.go @@ -0,0 +1,49 @@ +package v1_0_0 + +import ( + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestCommitReportEncoding(t *testing.T) { + ctx := testutils.Context(t) + report := cciptypes.CommitStoreReport{ + TokenPrices: []cciptypes.TokenPrice{ + { + Token: cciptypes.Address(utils.RandomAddress().String()), + Value: big.NewInt(9e18), + }, + }, + GasPrices: []cciptypes.GasPrice{ + { + DestChainSelector: rand.Uint64(), + Value: big.NewInt(2000e9), + }, + }, + MerkleRoot: [32]byte{123}, + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}, + } + + c, err := NewCommitStore(logger.TestLogger(t), utils.RandomAddress(), nil, mocks.NewLogPoller(t)) + assert.NoError(t, err) + + encodedReport, err := c.EncodeCommitReport(ctx, report) + require.NoError(t, err) + assert.Greater(t, len(encodedReport), 0) + + decodedReport, err := c.DecodeCommitReport(ctx, encodedReport) + require.NoError(t, err) + require.Equal(t, report.TokenPrices, decodedReport.TokenPrices) + require.Equal(t, report, decodedReport) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/hasher.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/hasher.go new file mode 100644 index 0000000000..0d1b7f736f --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/hasher.go @@ -0,0 +1,85 @@ +package v1_0_0 + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" +) + +const ( + MetaDataHashPrefix = "EVM2EVMMessageEvent" +) + +var LeafDomainSeparator = [1]byte{0x00} + +type LeafHasher struct { + metaDataHash [32]byte + ctx hashutil.Hasher[[32]byte] + onRamp *evm_2_evm_onramp_1_0_0.EVM2EVMOnRamp +} + +func GetMetaDataHash[H hashutil.Hash](ctx hashutil.Hasher[H], prefix [32]byte, sourceChainSelector uint64, onRampId common.Address, destChainSelector uint64) H { + paddedOnRamp := common.BytesToHash(onRampId[:]) + return ctx.Hash(utils.ConcatBytes(prefix[:], math.U256Bytes(big.NewInt(0).SetUint64(sourceChainSelector)), math.U256Bytes(big.NewInt(0).SetUint64(destChainSelector)), paddedOnRamp[:])) +} + +func NewLeafHasher(sourceChainSelector uint64, destChainSelector uint64, onRampId common.Address, ctx hashutil.Hasher[[32]byte], onRamp *evm_2_evm_onramp_1_0_0.EVM2EVMOnRamp) *LeafHasher { + return &LeafHasher{ + metaDataHash: GetMetaDataHash(ctx, ctx.Hash([]byte(MetaDataHashPrefix)), sourceChainSelector, onRampId, destChainSelector), + ctx: ctx, + onRamp: onRamp, + } +} + +func (t *LeafHasher) HashLeaf(log types.Log) ([32]byte, error) { + message, err := t.onRamp.ParseCCIPSendRequested(log) + if err != nil { + return [32]byte{}, err + } + encodedTokens, err := abihelpers.ABIEncode( + `[ +{"components": [{"name":"token","type":"address"},{"name":"amount","type":"uint256"}], "type":"tuple[]"}]`, message.Message.TokenAmounts) + if err != nil { + return [32]byte{}, err + } + + packedValues, err := abihelpers.ABIEncode( + `[ +{"name": "leafDomainSeparator","type":"bytes1"}, +{"name": "metadataHash", "type":"bytes32"}, +{"name": "sequenceNumber", "type":"uint64"}, +{"name": "nonce", "type":"uint64"}, +{"name": "sender", "type":"address"}, +{"name": "receiver", "type":"address"}, +{"name": "dataHash", "type":"bytes32"}, +{"name": "tokenAmountsHash", "type":"bytes32"}, +{"name": "gasLimit", "type":"uint256"}, +{"name": "strict", "type":"bool"}, +{"name": "feeToken","type": "address"}, +{"name": "feeTokenAmount","type": "uint256"} +]`, + LeafDomainSeparator, + t.metaDataHash, + message.Message.SequenceNumber, + message.Message.Nonce, + message.Message.Sender, + message.Message.Receiver, + t.ctx.Hash(message.Message.Data), + t.ctx.Hash(encodedTokens), + message.Message.GasLimit, + message.Message.Strict, + message.Message.FeeToken, + message.Message.FeeTokenAmount, + ) + if err != nil { + return [32]byte{}, err + } + return t.ctx.Hash(packedValues), nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/hasher_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/hasher_test.go new file mode 100644 index 0000000000..b1219a27df --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/hasher_test.go @@ -0,0 +1,84 @@ +package v1_0_0 + +import ( + "encoding/hex" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" +) + +func TestHasherV1_0_0(t *testing.T) { + sourceChainSelector, destChainSelector := uint64(1), uint64(4) + onRampAddress := common.HexToAddress("0x5550000000000000000000000000000000000001") + onRampABI := abihelpers.MustParseABI(evm_2_evm_onramp_1_0_0.EVM2EVMOnRampABI) + + ramp, err := evm_2_evm_onramp_1_0_0.NewEVM2EVMOnRamp(onRampAddress, nil) + require.NoError(t, err) + hashingCtx := hashutil.NewKeccak() + hasher := NewLeafHasher(sourceChainSelector, destChainSelector, onRampAddress, hashingCtx, ramp) + + message := evm_2_evm_onramp_1_0_0.InternalEVM2EVMMessage{ + SourceChainSelector: sourceChainSelector, + Sender: common.HexToAddress("0x1110000000000000000000000000000000000001"), + Receiver: common.HexToAddress("0x2220000000000000000000000000000000000001"), + SequenceNumber: 1337, + GasLimit: big.NewInt(100), + Strict: false, + Nonce: 1337, + FeeToken: common.Address{}, + FeeTokenAmount: big.NewInt(1), + Data: []byte{}, + TokenAmounts: []evm_2_evm_onramp_1_0_0.ClientEVMTokenAmount{{Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}}, + MessageId: [32]byte{}, + } + + data, err := onRampABI.Events[CCIPSendRequestedEventName].Inputs.Pack(message) + require.NoError(t, err) + hash, err := hasher.HashLeaf(types.Log{Topics: []common.Hash{abihelpers.MustGetEventID("CCIPSendRequested", onRampABI)}, Data: data}) + require.NoError(t, err) + + // NOTE: Must match spec + require.Equal(t, "26f282c6ac8231933b1799648d01ff6cec792a33fb37408b4d135968f9168ace", hex.EncodeToString(hash[:])) + + message = evm_2_evm_onramp_1_0_0.InternalEVM2EVMMessage{ + SourceChainSelector: sourceChainSelector, + Sender: common.HexToAddress("0x1110000000000000000000000000000000000001"), + Receiver: common.HexToAddress("0x2220000000000000000000000000000000000001"), + SequenceNumber: 1337, + GasLimit: big.NewInt(100), + Strict: false, + Nonce: 1337, + FeeToken: common.Address{}, + FeeTokenAmount: big.NewInt(1e12), + Data: []byte("foo bar baz"), + TokenAmounts: []evm_2_evm_onramp_1_0_0.ClientEVMTokenAmount{ + {Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}, + {Token: common.HexToAddress("0x6660000000000000000000000000000000000001"), Amount: big.NewInt(4204242)}, + }, + MessageId: [32]byte{}, + } + + data, err = onRampABI.Events[CCIPSendRequestedEventName].Inputs.Pack(message) + require.NoError(t, err) + hash, err = hasher.HashLeaf(types.Log{Topics: []common.Hash{abihelpers.MustGetEventID("CCIPSendRequested", onRampABI)}, Data: data}) + require.NoError(t, err) + + // NOTE: Must match spec + require.Equal(t, "05cee92e7cb86a37b6536554828a5b21ff20ac3d4ef821ec47056f1d963313de", hex.EncodeToString(hash[:])) +} + +func TestMetaDataHash(t *testing.T) { + sourceChainSelector, destChainSelector := uint64(1), uint64(4) + onRampAddress := common.HexToAddress("0x5550000000000000000000000000000000000001") + ctx := hashutil.NewKeccak() + hash := GetMetaDataHash(ctx, ctx.Hash([]byte(MetaDataHashPrefix)), sourceChainSelector, onRampAddress, destChainSelector) + require.Equal(t, "1409948abde219f43870c3d6d1c16beabd8878eb5039a3fa765eb56e4b8ded9e", hex.EncodeToString(hash[:])) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp.go new file mode 100644 index 0000000000..137cbaf451 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp.go @@ -0,0 +1,689 @@ +package v1_0_0 + +import ( + "context" + "fmt" + "math/big" + "sync" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + + mapset "github.com/deckarep/golang-set/v2" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +const ( + EXEC_EXECUTION_STATE_CHANGES = "Exec execution state changes" + EXEC_TOKEN_POOL_ADDED = "Token pool added" + EXEC_TOKEN_POOL_REMOVED = "Token pool removed" +) + +var ( + abiOffRamp = abihelpers.MustParseABI(evm_2_evm_offramp_1_0_0.EVM2EVMOffRampABI) + _ ccipdata.OffRampReader = &OffRamp{} + ExecutionStateChangedEvent = abihelpers.MustGetEventID("ExecutionStateChanged", abiOffRamp) + PoolAddedEvent = abihelpers.MustGetEventID("PoolAdded", abiOffRamp) + PoolRemovedEvent = abihelpers.MustGetEventID("PoolRemoved", abiOffRamp) + ExecutionStateChangedSeqNrIndex = 1 +) + +var offRamp_poolAddedPoolRemovedEvents = []common.Hash{PoolAddedEvent, PoolRemovedEvent} + +type ExecOnchainConfig evm_2_evm_offramp_1_0_0.EVM2EVMOffRampDynamicConfig + +func (d ExecOnchainConfig) AbiString() string { + return ` + [ + { + "components": [ + {"name": "permissionLessExecutionThresholdSeconds", "type": "uint32"}, + {"name": "router", "type": "address"}, + {"name": "priceRegistry", "type": "address"}, + {"name": "maxTokensLength", "type": "uint16"}, + {"name": "maxDataSize", "type": "uint32"} + ], + "type": "tuple" + } + ]` +} + +func (d ExecOnchainConfig) Validate() error { + if d.PermissionLessExecutionThresholdSeconds == 0 { + return errors.New("must set PermissionLessExecutionThresholdSeconds") + } + if d.Router == (common.Address{}) { + return errors.New("must set Router address") + } + if d.PriceRegistry == (common.Address{}) { + return errors.New("must set PriceRegistry address") + } + if d.MaxTokensLength == 0 { + return errors.New("must set MaxTokensLength") + } + if d.MaxDataSize == 0 { + return errors.New("must set MaxDataSize") + } + return nil +} + +// ExecOffchainConfig is the configuration for nodes executing committed CCIP messages (v1.0–v1.2). +// It comes from the OffchainConfig field of the corresponding OCR2 plugin configuration. +// NOTE: do not change the JSON format of this struct without consulting with the RDD people first. +type ExecOffchainConfig struct { + // SourceFinalityDepth indicates how many confirmations a transaction should get on the source chain event before we consider it finalized. + SourceFinalityDepth uint32 + // See [ccipdata.ExecOffchainConfig.DestOptimisticConfirmations] + DestOptimisticConfirmations uint32 + // DestFinalityDepth indicates how many confirmations a transaction should get on the destination chain event before we consider it finalized. + DestFinalityDepth uint32 + // See [ccipdata.ExecOffchainConfig.BatchGasLimit] + BatchGasLimit uint32 + // See [ccipdata.ExecOffchainConfig.RelativeBoostPerWaitHour] + RelativeBoostPerWaitHour float64 + // See [ccipdata.ExecOffchainConfig.InflightCacheExpiry] + InflightCacheExpiry config.Duration + // See [ccipdata.ExecOffchainConfig.RootSnoozeTime] + RootSnoozeTime config.Duration + // See [ccipdata.ExecOffchainConfig.BatchingStrategyID] + BatchingStrategyID uint32 + // See [ccipdata.ExecOffchainConfig.MessageVisibilityInterval] + MessageVisibilityInterval config.Duration +} + +func (c ExecOffchainConfig) Validate() error { + if c.SourceFinalityDepth == 0 { + return errors.New("must set SourceFinalityDepth") + } + if c.DestFinalityDepth == 0 { + return errors.New("must set DestFinalityDepth") + } + if c.DestOptimisticConfirmations == 0 { + return errors.New("must set DestOptimisticConfirmations") + } + if c.BatchGasLimit == 0 { + return errors.New("must set BatchGasLimit") + } + if c.RelativeBoostPerWaitHour == 0 { + return errors.New("must set RelativeBoostPerWaitHour") + } + if c.InflightCacheExpiry.Duration() == 0 { + return errors.New("must set InflightCacheExpiry") + } + if c.RootSnoozeTime.Duration() == 0 { + return errors.New("must set RootSnoozeTime") + } + + return nil +} + +type OffRamp struct { + offRampV100 evm_2_evm_offramp_1_0_0.EVM2EVMOffRampInterface + addr common.Address + lp logpoller.LogPoller + Logger logger.Logger + Client client.Client + evmBatchCaller rpclib.EvmBatchCaller + filters []logpoller.Filter + Estimator gas.EvmFeeEstimator + DestMaxGasPrice *big.Int + ExecutionReportArgs abi.Arguments + eventIndex int + eventSig common.Hash + cachedOffRampTokens cache.AutoSync[cciptypes.OffRampTokens] + sourceToDestTokensCache sync.Map + + // Dynamic config + // configMu guards all the dynamic config fields. + configMu sync.RWMutex + gasPriceEstimator prices.GasPriceEstimatorExec + offchainConfig cciptypes.ExecOffchainConfig + onchainConfig cciptypes.ExecOnchainConfig +} + +func (o *OffRamp) GetStaticConfig(ctx context.Context) (cciptypes.OffRampStaticConfig, error) { + if o.offRampV100 == nil { + return cciptypes.OffRampStaticConfig{}, fmt.Errorf("offramp not initialized") + } + c, err := o.offRampV100.GetStaticConfig(&bind.CallOpts{Context: ctx}) + if err != nil { + return cciptypes.OffRampStaticConfig{}, fmt.Errorf("error while retrieving offramp config: %w", err) + } + return cciptypes.OffRampStaticConfig{ + CommitStore: cciptypes.Address(c.CommitStore.String()), + ChainSelector: c.ChainSelector, + SourceChainSelector: c.SourceChainSelector, + OnRamp: cciptypes.Address(c.OnRamp.String()), + PrevOffRamp: cciptypes.Address(c.PrevOffRamp.String()), + ArmProxy: cciptypes.Address(c.ArmProxy.String()), + }, nil +} + +func (o *OffRamp) GetExecutionState(ctx context.Context, sequenceNumber uint64) (uint8, error) { + return o.offRampV100.GetExecutionState(&bind.CallOpts{Context: ctx}, sequenceNumber) +} + +func (o *OffRamp) GetSenderNonce(ctx context.Context, sender cciptypes.Address) (uint64, error) { + evmAddr, err := ccipcalc.GenericAddrToEvm(sender) + if err != nil { + return 0, err + } + return o.offRampV100.GetSenderNonce(&bind.CallOpts{Context: ctx}, evmAddr) +} + +func (o *OffRamp) ListSenderNonces(ctx context.Context, senders []cciptypes.Address) (map[cciptypes.Address]uint64, error) { + if len(senders) == 0 { + return make(map[cciptypes.Address]uint64), nil + } + + evmSenders, err := ccipcalc.GenericAddrsToEvm(senders...) + if err != nil { + return nil, errors.Wrap(err, "failed to convert generic addresses to evm addresses") + } + + evmCalls := make([]rpclib.EvmCall, 0, len(evmSenders)) + for _, evmAddr := range evmSenders { + evmCalls = append(evmCalls, rpclib.NewEvmCall( + abiOffRamp, + "getSenderNonce", + o.addr, + evmAddr, + )) + } + + results, err := o.evmBatchCaller.BatchCall(ctx, 0, evmCalls) + if err != nil { + o.Logger.Errorw("error while batch fetching sender nonces", "err", err, "senders", evmSenders) + return nil, err + } + + nonces, err := rpclib.ParseOutputs[uint64](results, func(d rpclib.DataAndErr) (uint64, error) { + return rpclib.ParseOutput[uint64](d, 0) + }) + if err != nil { + o.Logger.Errorw("error while parsing sender nonces", "err", err, "senders", evmSenders) + return nil, err + } + + if len(senders) != len(nonces) { + o.Logger.Errorw("unexpected number of nonces returned", "senders", evmSenders, "nonces", nonces) + return nil, errors.New("unexpected number of nonces returned") + } + + senderNonce := make(map[cciptypes.Address]uint64, len(senders)) + for i, sender := range senders { + senderNonce[sender] = nonces[i] + } + return senderNonce, nil +} + +func (o *OffRamp) CurrentRateLimiterState(ctx context.Context) (cciptypes.TokenBucketRateLimit, error) { + state, err := o.offRampV100.CurrentRateLimiterState(&bind.CallOpts{Context: ctx}) + if err != nil { + return cciptypes.TokenBucketRateLimit{}, err + } + return cciptypes.TokenBucketRateLimit{ + Tokens: state.Tokens, + LastUpdated: state.LastUpdated, + IsEnabled: state.IsEnabled, + Capacity: state.Capacity, + Rate: state.Rate, + }, nil +} + +func (o *OffRamp) getDestinationTokensFromSourceTokens(ctx context.Context, tokenAddresses []cciptypes.Address) ([]cciptypes.Address, error) { + destTokens := make([]cciptypes.Address, len(tokenAddresses)) + found := make(map[cciptypes.Address]bool) + + for i, tokenAddress := range tokenAddresses { + if v, exists := o.sourceToDestTokensCache.Load(tokenAddress); exists { + if destToken, isAddr := v.(cciptypes.Address); isAddr { + destTokens[i] = destToken + found[tokenAddress] = true + } else { + o.Logger.Errorf("source to dest cache contains invalid type %T", v) + } + } + } + + if len(found) == len(tokenAddresses) { + return destTokens, nil + } + + evmAddrs, err := ccipcalc.GenericAddrsToEvm(tokenAddresses...) + if err != nil { + return nil, err + } + + evmCalls := make([]rpclib.EvmCall, 0, len(tokenAddresses)) + for i, sourceTk := range tokenAddresses { + if !found[sourceTk] { + evmCalls = append(evmCalls, rpclib.NewEvmCall(abiOffRamp, "getDestinationToken", o.addr, evmAddrs[i])) + } + } + + results, err := o.evmBatchCaller.BatchCall(ctx, 0, evmCalls) + if err != nil { + return nil, fmt.Errorf("batch call limit: %w", err) + } + + destTokensFromRpc, err := rpclib.ParseOutputs[common.Address](results, func(d rpclib.DataAndErr) (common.Address, error) { + return rpclib.ParseOutput[common.Address](d, 0) + }) + if err != nil { + return nil, fmt.Errorf("parse outputs: %w", err) + } + + j := 0 + for i, sourceToken := range tokenAddresses { + if !found[sourceToken] { + destTokens[i] = cciptypes.Address(destTokensFromRpc[j].String()) + o.sourceToDestTokensCache.Store(sourceToken, destTokens[i]) + j++ + } + } + + seenDestTokens := mapset.NewSet[cciptypes.Address]() + for _, destToken := range destTokens { + if seenDestTokens.Contains(destToken) { + return nil, fmt.Errorf("offRamp misconfig, destination token %s already exists", destToken) + } + seenDestTokens.Add(destToken) + } + + return destTokens, nil +} + +func (o *OffRamp) GetSourceToDestTokensMapping(ctx context.Context) (map[cciptypes.Address]cciptypes.Address, error) { + tokens, err := o.GetTokens(ctx) + if err != nil { + return nil, err + } + + destTokens, err := o.getDestinationTokensFromSourceTokens(ctx, tokens.SourceTokens) + if err != nil { + return nil, fmt.Errorf("get destination tokens from source tokens: %w", err) + } + + srcToDstTokenMapping := make(map[cciptypes.Address]cciptypes.Address, len(tokens.SourceTokens)) + for i, sourceToken := range tokens.SourceTokens { + srcToDstTokenMapping[sourceToken] = destTokens[i] + } + return srcToDstTokenMapping, nil +} + +func (o *OffRamp) GetTokens(ctx context.Context) (cciptypes.OffRampTokens, error) { + return o.cachedOffRampTokens.Get(ctx, func(ctx context.Context) (cciptypes.OffRampTokens, error) { + destTokens, err := o.offRampV100.GetDestinationTokens(&bind.CallOpts{Context: ctx}) + if err != nil { + return cciptypes.OffRampTokens{}, fmt.Errorf("get destination tokens: %w", err) + } + sourceTokens, err := o.offRampV100.GetSupportedTokens(&bind.CallOpts{Context: ctx}) + if err != nil { + return cciptypes.OffRampTokens{}, err + } + + return cciptypes.OffRampTokens{ + DestinationTokens: ccipcalc.EvmAddrsToGeneric(destTokens...), + SourceTokens: ccipcalc.EvmAddrsToGeneric(sourceTokens...), + }, nil + }) +} + +func (o *OffRamp) GetRouter(ctx context.Context) (cciptypes.Address, error) { + dynamicConfig, err := o.offRampV100.GetDynamicConfig(&bind.CallOpts{Context: ctx}) + if err != nil { + return "", err + } + return ccipcalc.EvmAddrToGeneric(dynamicConfig.Router), nil +} + +func (o *OffRamp) OffchainConfig(ctx context.Context) (cciptypes.ExecOffchainConfig, error) { + o.configMu.RLock() + defer o.configMu.RUnlock() + return o.offchainConfig, nil +} + +func (o *OffRamp) OnchainConfig(ctx context.Context) (cciptypes.ExecOnchainConfig, error) { + o.configMu.RLock() + defer o.configMu.RUnlock() + return o.onchainConfig, nil +} + +func (o *OffRamp) GasPriceEstimator(ctx context.Context) (cciptypes.GasPriceEstimatorExec, error) { + o.configMu.RLock() + defer o.configMu.RUnlock() + return o.gasPriceEstimator, nil +} + +func (o *OffRamp) Address(ctx context.Context) (cciptypes.Address, error) { + return cciptypes.Address(o.addr.String()), nil +} + +func (o *OffRamp) UpdateDynamicConfig(onchainConfig cciptypes.ExecOnchainConfig, offchainConfig cciptypes.ExecOffchainConfig, gasPriceEstimator prices.GasPriceEstimatorExec) { + o.configMu.Lock() + o.onchainConfig = onchainConfig + o.offchainConfig = offchainConfig + o.gasPriceEstimator = gasPriceEstimator + o.configMu.Unlock() +} + +func (o *OffRamp) ChangeConfig(ctx context.Context, onchainConfigBytes []byte, offchainConfigBytes []byte) (cciptypes.Address, cciptypes.Address, error) { + onchainConfigParsed, err := abihelpers.DecodeAbiStruct[ExecOnchainConfig](onchainConfigBytes) + if err != nil { + return "", "", err + } + + offchainConfigParsed, err := ccipconfig.DecodeOffchainConfig[ExecOffchainConfig](offchainConfigBytes) + if err != nil { + return "", "", err + } + destRouter, err := router.NewRouter(onchainConfigParsed.Router, o.Client) + if err != nil { + return "", "", err + } + destWrappedNative, err := destRouter.GetWrappedNative(nil) + if err != nil { + return "", "", err + } + + offchainConfig := cciptypes.ExecOffchainConfig{ + DestOptimisticConfirmations: offchainConfigParsed.DestOptimisticConfirmations, + BatchGasLimit: offchainConfigParsed.BatchGasLimit, + RelativeBoostPerWaitHour: offchainConfigParsed.RelativeBoostPerWaitHour, + InflightCacheExpiry: offchainConfigParsed.InflightCacheExpiry, + RootSnoozeTime: offchainConfigParsed.RootSnoozeTime, + MessageVisibilityInterval: offchainConfigParsed.MessageVisibilityInterval, + BatchingStrategyID: offchainConfigParsed.BatchingStrategyID, + } + onchainConfig := cciptypes.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: time.Second * time.Duration(onchainConfigParsed.PermissionLessExecutionThresholdSeconds), + Router: cciptypes.Address(onchainConfigParsed.Router.String()), + } + gasPriceEstimator := prices.NewExecGasPriceEstimator(o.Estimator, o.DestMaxGasPrice, 0) + + o.UpdateDynamicConfig(onchainConfig, offchainConfig, gasPriceEstimator) + + o.Logger.Infow("Starting exec plugin", + "offchainConfig", onchainConfigParsed, + "onchainConfig", offchainConfigParsed) + return cciptypes.Address(onchainConfigParsed.PriceRegistry.String()), + cciptypes.Address(destWrappedNative.String()), nil +} + +func (o *OffRamp) Close() error { + return logpollerutil.UnregisterLpFilters(o.lp, o.filters) +} + +func (o *OffRamp) GetExecutionStateChangesBetweenSeqNums(ctx context.Context, seqNumMin, seqNumMax uint64, confs int) ([]cciptypes.ExecutionStateChangedWithTxMeta, error) { + latestBlock, err := o.lp.LatestBlock(ctx) + if err != nil { + return nil, fmt.Errorf("get lp latest block: %w", err) + } + + logs, err := o.lp.IndexedLogsTopicRange( + ctx, + o.eventSig, + o.addr, + o.eventIndex, + logpoller.EvmWord(seqNumMin), + logpoller.EvmWord(seqNumMax), + evmtypes.Confirmations(confs), + ) + if err != nil { + return nil, err + } + + parsedLogs, err := ccipdata.ParseLogs[cciptypes.ExecutionStateChanged]( + logs, + o.Logger, + func(log types.Log) (*cciptypes.ExecutionStateChanged, error) { + sc, err1 := o.offRampV100.ParseExecutionStateChanged(log) + if err1 != nil { + return nil, err1 + } + + return &cciptypes.ExecutionStateChanged{ + SequenceNumber: sc.SequenceNumber, + }, nil + }, + ) + if err != nil { + return nil, fmt.Errorf("parse logs: %w", err) + } + + res := make([]cciptypes.ExecutionStateChangedWithTxMeta, 0, len(parsedLogs)) + for _, log := range parsedLogs { + res = append(res, cciptypes.ExecutionStateChangedWithTxMeta{ + TxMeta: log.TxMeta.WithFinalityStatus(uint64(latestBlock.FinalizedBlockNumber)), + ExecutionStateChanged: log.Data, + }) + } + return res, nil +} + +func encodeExecutionReport(args abi.Arguments, report cciptypes.ExecReport) ([]byte, error) { + var msgs []evm_2_evm_offramp_1_0_0.InternalEVM2EVMMessage + for _, msg := range report.Messages { + var ta []evm_2_evm_offramp_1_0_0.ClientEVMTokenAmount + for _, tokenAndAmount := range msg.TokenAmounts { + evmTokenAddr, err := ccipcalc.GenericAddrToEvm(tokenAndAmount.Token) + if err != nil { + return nil, err + } + + ta = append(ta, evm_2_evm_offramp_1_0_0.ClientEVMTokenAmount{ + Token: evmTokenAddr, + Amount: tokenAndAmount.Amount, + }) + } + + senderEvmAddr, err := ccipcalc.GenericAddrToEvm(msg.Sender) + if err != nil { + return nil, fmt.Errorf("msg sender is not evm addr: %w", err) + } + + receiverEvmAddr, err := ccipcalc.GenericAddrToEvm(msg.Receiver) + if err != nil { + return nil, fmt.Errorf("msg receiver is not evm addr: %w", err) + } + + feeTokenEvmAddr, err := ccipcalc.GenericAddrToEvm(msg.FeeToken) + if err != nil { + return nil, fmt.Errorf("fee token is not evm addr: %w", err) + } + + msgs = append(msgs, evm_2_evm_offramp_1_0_0.InternalEVM2EVMMessage{ + SourceChainSelector: msg.SourceChainSelector, + Sender: senderEvmAddr, + Receiver: receiverEvmAddr, + SequenceNumber: msg.SequenceNumber, + GasLimit: msg.GasLimit, + Strict: msg.Strict, + Nonce: msg.Nonce, + FeeToken: feeTokenEvmAddr, + FeeTokenAmount: msg.FeeTokenAmount, + Data: msg.Data, + TokenAmounts: ta, + MessageId: msg.MessageID, + }) + } + + rep := evm_2_evm_offramp_1_0_0.InternalExecutionReport{ + Messages: msgs, + OffchainTokenData: report.OffchainTokenData, + Proofs: report.Proofs, + ProofFlagBits: report.ProofFlagBits, + } + return args.PackValues([]interface{}{&rep}) +} + +func (o *OffRamp) EncodeExecutionReport(ctx context.Context, report cciptypes.ExecReport) ([]byte, error) { + return encodeExecutionReport(o.ExecutionReportArgs, report) +} + +func DecodeExecReport(ctx context.Context, args abi.Arguments, report []byte) (cciptypes.ExecReport, error) { + unpacked, err := args.Unpack(report) + if err != nil { + return cciptypes.ExecReport{}, err + } + if len(unpacked) == 0 { + return cciptypes.ExecReport{}, errors.New("assumptionViolation: expected at least one element") + } + + erStruct, ok := unpacked[0].(struct { + Messages []struct { + SourceChainSelector uint64 `json:"sourceChainSelector"` + SequenceNumber uint64 `json:"sequenceNumber"` + FeeTokenAmount *big.Int `json:"feeTokenAmount"` + Sender common.Address `json:"sender"` + Nonce uint64 `json:"nonce"` + GasLimit *big.Int `json:"gasLimit"` + Strict bool `json:"strict"` + Receiver common.Address `json:"receiver"` + Data []uint8 `json:"data"` + TokenAmounts []struct { + Token common.Address `json:"token"` + Amount *big.Int `json:"amount"` + } `json:"tokenAmounts"` + FeeToken common.Address `json:"feeToken"` + MessageId [32]uint8 `json:"messageId"` + } `json:"messages"` + OffchainTokenData [][][]uint8 `json:"offchainTokenData"` + Proofs [][32]uint8 `json:"proofs"` + ProofFlagBits *big.Int `json:"proofFlagBits"` + }) + + if !ok { + return cciptypes.ExecReport{}, fmt.Errorf("got %T", unpacked[0]) + } + messages := make([]cciptypes.EVM2EVMMessage, 0, len(erStruct.Messages)) + for _, msg := range erStruct.Messages { + var tokensAndAmounts []cciptypes.TokenAmount + for _, tokenAndAmount := range msg.TokenAmounts { + tokensAndAmounts = append(tokensAndAmounts, cciptypes.TokenAmount{ + Token: cciptypes.Address(tokenAndAmount.Token.String()), + Amount: tokenAndAmount.Amount, + }) + } + messages = append(messages, cciptypes.EVM2EVMMessage{ + SequenceNumber: msg.SequenceNumber, + GasLimit: msg.GasLimit, + Nonce: msg.Nonce, + MessageID: msg.MessageId, + SourceChainSelector: msg.SourceChainSelector, + Sender: cciptypes.Address(msg.Sender.String()), + Receiver: cciptypes.Address(msg.Receiver.String()), + Strict: msg.Strict, + FeeToken: cciptypes.Address(msg.FeeToken.String()), + FeeTokenAmount: msg.FeeTokenAmount, + Data: msg.Data, + TokenAmounts: tokensAndAmounts, + // TODO: Not needed for plugins, but should be recomputed for consistency. + // Requires the offramp knowing about onramp version + Hash: [32]byte{}, + }) + } + + // Unpack will populate with big.Int{false, } for 0 values, + // which is different from the expected big.NewInt(0). Rebuild to the expected value for this case. + return cciptypes.ExecReport{ + Messages: messages, + OffchainTokenData: erStruct.OffchainTokenData, + Proofs: erStruct.Proofs, + ProofFlagBits: new(big.Int).SetBytes(erStruct.ProofFlagBits.Bytes()), + }, nil +} + +func (o *OffRamp) DecodeExecutionReport(ctx context.Context, report []byte) (cciptypes.ExecReport, error) { + return DecodeExecReport(ctx, o.ExecutionReportArgs, report) +} + +func (o *OffRamp) RegisterFilters() error { + return logpollerutil.RegisterLpFilters(o.lp, o.filters) +} + +func NewOffRamp(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, destMaxGasPrice *big.Int) (*OffRamp, error) { + offRamp, err := evm_2_evm_offramp_1_0_0.NewEVM2EVMOffRamp(addr, ec) + if err != nil { + return nil, err + } + + executionStateChangedSequenceNumberIndex := 1 + executionReportArgs := abihelpers.MustGetMethodInputs("manuallyExecute", abiOffRamp)[:1] + filters := []logpoller.Filter{ + { + Name: logpoller.FilterName(EXEC_EXECUTION_STATE_CHANGES, addr.String()), + EventSigs: []common.Hash{ExecutionStateChangedEvent}, + Addresses: []common.Address{addr}, + Retention: ccipdata.CommitExecLogsRetention, + }, + { + Name: logpoller.FilterName(EXEC_TOKEN_POOL_ADDED, addr.String()), + EventSigs: []common.Hash{PoolAddedEvent}, + Addresses: []common.Address{addr}, + Retention: ccipdata.CacheEvictionLogsRetention, + }, + { + Name: logpoller.FilterName(EXEC_TOKEN_POOL_REMOVED, addr.String()), + EventSigs: []common.Hash{PoolRemovedEvent}, + Addresses: []common.Address{addr}, + Retention: ccipdata.CacheEvictionLogsRetention, + }, + } + + return &OffRamp{ + offRampV100: offRamp, + Client: ec, + addr: addr, + Logger: lggr, + lp: lp, + filters: filters, + Estimator: estimator, + DestMaxGasPrice: destMaxGasPrice, + ExecutionReportArgs: executionReportArgs, + eventSig: ExecutionStateChangedEvent, + eventIndex: executionStateChangedSequenceNumberIndex, + configMu: sync.RWMutex{}, + evmBatchCaller: rpclib.NewDynamicLimitedBatchCaller( + lggr, + ec, + rpclib.DefaultRpcBatchSizeLimit, + rpclib.DefaultRpcBatchBackOffMultiplier, + rpclib.DefaultMaxParallelRpcCalls, + ), + cachedOffRampTokens: cache.NewLogpollerEventsBased[cciptypes.OffRampTokens]( + lp, + offRamp_poolAddedPoolRemovedEvents, + offRamp.Address(), + ), + // values set on the fly after ChangeConfig is called + gasPriceEstimator: prices.ExecGasPriceEstimator{}, + offchainConfig: cciptypes.ExecOffchainConfig{}, + onchainConfig: cciptypes.ExecOnchainConfig{}, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_test.go new file mode 100644 index 0000000000..d834b792ce --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_test.go @@ -0,0 +1,38 @@ +package v1_0_0_test + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" +) + +func TestExecutionReportEncodingV100(t *testing.T) { + // Note could consider some fancier testing here (fuzz/property) + // but I think that would essentially be testing geth's abi library + // as our encode/decode is a thin wrapper around that. + report := cciptypes.ExecReport{ + Messages: []cciptypes.EVM2EVMMessage{}, + OffchainTokenData: [][][]byte{{}}, + Proofs: [][32]byte{testutils.Random32Byte()}, + ProofFlagBits: big.NewInt(133), + } + + offRamp, err := v1_0_0.NewOffRamp(logger.TestLogger(t), utils.RandomAddress(), nil, lpmocks.NewLogPoller(t), nil, nil) + require.NoError(t, err) + + ctx := testutils.Context(t) + encodeExecutionReport, err := offRamp.EncodeExecutionReport(ctx, report) + require.NoError(t, err) + decodeCommitReport, err := offRamp.DecodeExecutionReport(ctx, encodeExecutionReport) + require.NoError(t, err) + require.Equal(t, report.Proofs, decodeCommitReport.Proofs) + require.Equal(t, report, decodeCommitReport) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_unit_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_unit_test.go new file mode 100644 index 0000000000..f8b1dc4e61 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_unit_test.go @@ -0,0 +1,231 @@ +package v1_0_0 + +import ( + "fmt" + "math/rand" + "slices" + "testing" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib/rpclibmocks" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0" + mock_contracts "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/mocks/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +func TestOffRampGetDestinationTokensFromSourceTokens(t *testing.T) { + ctx := testutils.Context(t) + const numSrcTokens = 20 + + testCases := []struct { + name string + outputChangeFn func(outputs []rpclib.DataAndErr) []rpclib.DataAndErr + expErr bool + }{ + { + name: "happy path", + outputChangeFn: func(outputs []rpclib.DataAndErr) []rpclib.DataAndErr { return outputs }, + expErr: false, + }, + { + name: "rpc error", + outputChangeFn: func(outputs []rpclib.DataAndErr) []rpclib.DataAndErr { + outputs[2].Err = fmt.Errorf("some error") + return outputs + }, + expErr: true, + }, + { + name: "unexpected outputs length should be fine if the type is correct", + outputChangeFn: func(outputs []rpclib.DataAndErr) []rpclib.DataAndErr { + outputs[0].Outputs = append(outputs[0].Outputs, "unexpected", 123) + return outputs + }, + expErr: false, + }, + { + name: "different compatible type", + outputChangeFn: func(outputs []rpclib.DataAndErr) []rpclib.DataAndErr { + outputs[0].Outputs = []any{outputs[0].Outputs[0].(common.Address)} + return outputs + }, + expErr: false, + }, + { + name: "different incompatible type", + outputChangeFn: func(outputs []rpclib.DataAndErr) []rpclib.DataAndErr { + outputs[0].Outputs = []any{outputs[0].Outputs[0].(common.Address).Bytes()} + return outputs + }, + expErr: true, + }, + } + + lp := mocks.NewLogPoller(t) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + batchCaller := rpclibmocks.NewEvmBatchCaller(t) + o := &OffRamp{evmBatchCaller: batchCaller, lp: lp} + srcTks, dstTks, outputs := generateTokensAndOutputs(numSrcTokens) + outputs = tc.outputChangeFn(outputs) + batchCaller.On("BatchCall", mock.Anything, mock.Anything, mock.Anything).Return(outputs, nil) + genericAddrs := ccipcalc.EvmAddrsToGeneric(srcTks...) + actualDstTokens, err := o.getDestinationTokensFromSourceTokens(ctx, genericAddrs) + + if tc.expErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + assert.Equal(t, ccipcalc.EvmAddrsToGeneric(dstTks...), actualDstTokens) + }) + } +} + +func TestCachedOffRampTokens(t *testing.T) { + // Test data. + srcTks, dstTks, _ := generateTokensAndOutputs(3) + + // Mock contract wrapper. + mockOffRamp := mock_contracts.NewEVM2EVMOffRampInterface(t) + mockOffRamp.On("GetDestinationTokens", mock.Anything).Return(dstTks, nil) + mockOffRamp.On("GetSupportedTokens", mock.Anything).Return(srcTks, nil) + mockOffRamp.On("Address").Return(utils.RandomAddress()) + + lp := mocks.NewLogPoller(t) + lp.On("LatestBlock", mock.Anything).Return(logpoller.LogPollerBlock{BlockNumber: rand.Int63()}, nil) + + offRamp := OffRamp{ + offRampV100: mockOffRamp, + lp: lp, + Logger: logger.TestLogger(t), + Client: evmclimocks.NewClient(t), + evmBatchCaller: rpclibmocks.NewEvmBatchCaller(t), + cachedOffRampTokens: cache.NewLogpollerEventsBased[cciptypes.OffRampTokens]( + lp, + offRamp_poolAddedPoolRemovedEvents, + mockOffRamp.Address(), + ), + } + + ctx := testutils.Context(t) + tokens, err := offRamp.GetTokens(ctx) + require.NoError(t, err) + + // Verify data is properly loaded in the cache. + expectedPools := make(map[cciptypes.Address]cciptypes.Address) + for i := range dstTks { + expectedPools[cciptypes.Address(dstTks[i].String())] = cciptypes.Address(dstTks[i].String()) + } + require.Equal(t, cciptypes.OffRampTokens{ + DestinationTokens: ccipcalc.EvmAddrsToGeneric(dstTks...), + SourceTokens: ccipcalc.EvmAddrsToGeneric(srcTks...), + }, tokens) +} + +func generateTokensAndOutputs(nbTokens uint) ([]common.Address, []common.Address, []rpclib.DataAndErr) { + srcTks := make([]common.Address, nbTokens) + dstTks := make([]common.Address, nbTokens) + outputs := make([]rpclib.DataAndErr, nbTokens) + for i := range srcTks { + srcTks[i] = utils.RandomAddress() + dstTks[i] = utils.RandomAddress() + outputs[i] = rpclib.DataAndErr{ + Outputs: []any{dstTks[i]}, Err: nil, + } + } + return srcTks, dstTks, outputs +} + +func Test_LogsAreProperlyMarkedAsFinalized(t *testing.T) { + minSeqNr := uint64(10) + maxSeqNr := uint64(14) + inputLogs := []logpoller.Log{ + CreateExecutionStateChangeEventLog(t, 10, 2, utils.RandomBytes32()), + CreateExecutionStateChangeEventLog(t, 11, 3, utils.RandomBytes32()), + CreateExecutionStateChangeEventLog(t, 12, 5, utils.RandomBytes32()), + CreateExecutionStateChangeEventLog(t, 14, 7, utils.RandomBytes32()), + } + + tests := []struct { + name string + lastFinalizedBlock uint64 + expectedFinalizedSequenceNr []uint64 + }{ + { + "all logs are finalized", + 10, + []uint64{10, 11, 12, 14}, + }, + { + "some logs are finalized", + 5, + []uint64{10, 11, 12}, + }, + { + "no logs are finalized", + 1, + []uint64{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + offrampAddress := utils.RandomAddress() + + lp := mocks.NewLogPoller(t) + lp.On("LatestBlock", mock.Anything). + Return(logpoller.LogPollerBlock{FinalizedBlockNumber: int64(tt.lastFinalizedBlock)}, nil) + lp.On("IndexedLogsTopicRange", mock.Anything, ExecutionStateChangedEvent, offrampAddress, 1, logpoller.EvmWord(minSeqNr), logpoller.EvmWord(maxSeqNr), evmtypes.Confirmations(0)). + Return(inputLogs, nil) + + offRamp, err := NewOffRamp(logger.TestLogger(t), offrampAddress, evmclimocks.NewClient(t), lp, nil, nil) + require.NoError(t, err) + logs, err := offRamp.GetExecutionStateChangesBetweenSeqNums(testutils.Context(t), minSeqNr, maxSeqNr, 0) + require.NoError(t, err) + assert.Len(t, logs, len(inputLogs)) + + for _, log := range logs { + assert.Equal(t, slices.Contains(tt.expectedFinalizedSequenceNr, log.SequenceNumber), log.IsFinalized()) + } + }) + } +} + +func TestGetRouter(t *testing.T) { + routerAddr := utils.RandomAddress() + + mockOffRamp := mock_contracts.NewEVM2EVMOffRampInterface(t) + mockOffRamp.On("GetDynamicConfig", mock.Anything).Return(evm_2_evm_offramp_1_0_0.EVM2EVMOffRampDynamicConfig{ + Router: routerAddr, + }, nil) + + offRamp := OffRamp{ + offRampV100: mockOffRamp, + } + + ctx := testutils.Context(t) + gotRouterAddr, err := offRamp.GetRouter(ctx) + require.NoError(t, err) + + gotRouterEvmAddr, err := ccipcalc.GenericAddrToEvm(gotRouterAddr) + require.NoError(t, err) + assert.Equal(t, routerAddr, gotRouterEvmAddr) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_test.go new file mode 100644 index 0000000000..44fb6ca063 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_test.go @@ -0,0 +1,232 @@ +package v1_0_0 + +import ( + "encoding/json" + "testing" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib/rpclibmocks" + + "github.com/pkg/errors" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" +) + +func TestExecOffchainConfig100_Encoding(t *testing.T) { + tests := []struct { + name string + want ExecOffchainConfig + expectErr bool + }{ + { + name: "encodes and decodes config with all fields set", + want: ExecOffchainConfig{ + SourceFinalityDepth: 3, + DestOptimisticConfirmations: 6, + DestFinalityDepth: 3, + BatchGasLimit: 5_000_000, + RelativeBoostPerWaitHour: 0.07, + InflightCacheExpiry: *config.MustNewDuration(64 * time.Second), + RootSnoozeTime: *config.MustNewDuration(128 * time.Minute), + MessageVisibilityInterval: *config.MustNewDuration(6 * time.Hour), + }, + }, + { + name: "fails decoding when all fields present but with 0 values", + want: ExecOffchainConfig{ + SourceFinalityDepth: 0, + DestFinalityDepth: 0, + DestOptimisticConfirmations: 0, + BatchGasLimit: 0, + RelativeBoostPerWaitHour: 0, + InflightCacheExpiry: *config.MustNewDuration(0), + RootSnoozeTime: *config.MustNewDuration(0), + MessageVisibilityInterval: *config.MustNewDuration(0), + }, + expectErr: true, + }, + { + name: "fails decoding when all fields are missing", + want: ExecOffchainConfig{}, + expectErr: true, + }, + { + name: "fails decoding when some fields are missing", + want: ExecOffchainConfig{ + SourceFinalityDepth: 99999999, + InflightCacheExpiry: *config.MustNewDuration(64 * time.Second), + }, + expectErr: true, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + exp := tc.want + encode, err := ccipconfig.EncodeOffchainConfig(&exp) + require.NoError(t, err) + got, err := ccipconfig.DecodeOffchainConfig[ExecOffchainConfig](encode) + + if tc.expectErr { + require.ErrorContains(t, err, "must set") + } else { + require.NoError(t, err) + require.Equal(t, tc.want, got) + } + }) + } +} + +func TestExecOffchainConfig100_AllFieldsRequired(t *testing.T) { + cfg := ExecOffchainConfig{ + SourceFinalityDepth: 3, + DestOptimisticConfirmations: 6, + DestFinalityDepth: 3, + BatchGasLimit: 5_000_000, + RelativeBoostPerWaitHour: 0.07, + InflightCacheExpiry: *config.MustNewDuration(64 * time.Second), + RootSnoozeTime: *config.MustNewDuration(128 * time.Minute), + BatchingStrategyID: 0, + } + encoded, err := ccipconfig.EncodeOffchainConfig(&cfg) + require.NoError(t, err) + + var configAsMap map[string]any + err = json.Unmarshal(encoded, &configAsMap) + require.NoError(t, err) + for keyToDelete := range configAsMap { + if keyToDelete == "MessageVisibilityInterval" { + continue // this field is optional + } + + partialConfig := make(map[string]any) + for k, v := range configAsMap { + if k != keyToDelete { + partialConfig[k] = v + } + } + encodedPartialConfig, err := json.Marshal(partialConfig) + require.NoError(t, err) + _, err = ccipconfig.DecodeOffchainConfig[ExecOffchainConfig](encodedPartialConfig) + if keyToDelete == "BatchingStrategyID" { + require.NoError(t, err) + } else { + require.ErrorContains(t, err, keyToDelete) + } + } +} + +func Test_GetSendersNonce(t *testing.T) { + sender1 := cciptypes.Address(utils.RandomAddress().String()) + sender2 := cciptypes.Address(utils.RandomAddress().String()) + + tests := []struct { + name string + addresses []cciptypes.Address + batchCaller *rpclibmocks.EvmBatchCaller + expectedResult map[cciptypes.Address]uint64 + expectedError bool + }{ + { + name: "return empty map when input is empty", + addresses: []cciptypes.Address{}, + batchCaller: rpclibmocks.NewEvmBatchCaller(t), + expectedResult: map[cciptypes.Address]uint64{}, + }, + { + name: "return error when batch call fails", + addresses: []cciptypes.Address{sender1}, + batchCaller: func() *rpclibmocks.EvmBatchCaller { + mockBatchCaller := rpclibmocks.NewEvmBatchCaller(t) + mockBatchCaller.On("BatchCall", mock.Anything, mock.Anything, mock.Anything). + Return(nil, errors.New("batch call error")) + return mockBatchCaller + }(), + expectedError: true, + }, + { + name: "return error when nonces dont match senders", + addresses: []cciptypes.Address{sender1, sender2}, + batchCaller: func() *rpclibmocks.EvmBatchCaller { + mockBatchCaller := rpclibmocks.NewEvmBatchCaller(t) + results := []rpclib.DataAndErr{ + { + Outputs: []any{uint64(1)}, + Err: nil, + }, + } + mockBatchCaller.On("BatchCall", mock.Anything, mock.Anything, mock.Anything). + Return(results, nil) + return mockBatchCaller + }(), + expectedError: true, + }, + { + name: "return error when single request from batch fails", + addresses: []cciptypes.Address{sender1, sender2}, + batchCaller: func() *rpclibmocks.EvmBatchCaller { + mockBatchCaller := rpclibmocks.NewEvmBatchCaller(t) + results := []rpclib.DataAndErr{ + { + Outputs: []any{uint64(1)}, + Err: nil, + }, + { + Outputs: []any{}, + Err: errors.New("request failed"), + }, + } + mockBatchCaller.On("BatchCall", mock.Anything, mock.Anything, mock.Anything). + Return(results, nil) + return mockBatchCaller + }(), + expectedError: true, + }, + { + name: "return map of nonce per sender", + addresses: []cciptypes.Address{sender1, sender2}, + batchCaller: func() *rpclibmocks.EvmBatchCaller { + mockBatchCaller := rpclibmocks.NewEvmBatchCaller(t) + results := []rpclib.DataAndErr{ + { + Outputs: []any{uint64(1)}, + Err: nil, + }, + { + Outputs: []any{uint64(2)}, + Err: nil, + }, + } + mockBatchCaller.On("BatchCall", mock.Anything, mock.Anything, mock.Anything). + Return(results, nil) + return mockBatchCaller + }(), + expectedResult: map[cciptypes.Address]uint64{ + sender1: uint64(1), + sender2: uint64(2), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + offramp := OffRamp{evmBatchCaller: test.batchCaller, Logger: logger.TestLogger(t)} + nonce, err := offramp.ListSenderNonces(testutils.Context(t), test.addresses) + + if test.expectedError { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.expectedResult, nonce) + } + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go new file mode 100644 index 0000000000..29cb357223 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go @@ -0,0 +1,240 @@ +package v1_0_0 + +import ( + "context" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" +) + +const ( + CCIPSendRequestedEventName = "CCIPSendRequested" + ConfigSetEventName = "ConfigSet" +) + +var _ ccipdata.OnRampReader = &OnRamp{} + +type OnRamp struct { + address common.Address + onRamp *evm_2_evm_onramp_1_0_0.EVM2EVMOnRamp + lp logpoller.LogPoller + lggr logger.Logger + client client.Client + leafHasher ccipdata.LeafHasherInterface[[32]byte] + sendRequestedEventSig common.Hash + sendRequestedSeqNumberWord int + filters []logpoller.Filter + cachedSourcePriceRegistryAddress cache.AutoSync[cciptypes.Address] + // Static config can be cached, because it's never expected to change. + // The only way to change that is through the contract's constructor (redeployment) + cachedStaticConfig cache.OnceCtxFunction[evm_2_evm_onramp_1_0_0.EVM2EVMOnRampStaticConfig] + cachedRmnContract cache.OnceCtxFunction[*arm_contract.ARMContract] +} + +func NewOnRamp(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAddress common.Address, sourceLP logpoller.LogPoller, source client.Client) (*OnRamp, error) { + onRamp, err := evm_2_evm_onramp_1_0_0.NewEVM2EVMOnRamp(onRampAddress, source) + if err != nil { + return nil, err + } + onRampABI := abihelpers.MustParseABI(evm_2_evm_onramp_1_0_0.EVM2EVMOnRampABI) + eventSig := abihelpers.MustGetEventID(CCIPSendRequestedEventName, onRampABI) + configSetEventSig := abihelpers.MustGetEventID(ConfigSetEventName, onRampABI) + filters := []logpoller.Filter{ + { + Name: logpoller.FilterName(ccipdata.COMMIT_CCIP_SENDS, onRampAddress), + EventSigs: []common.Hash{eventSig}, + Addresses: []common.Address{onRampAddress}, + Retention: ccipdata.CommitExecLogsRetention, + }, + { + Name: logpoller.FilterName(ccipdata.CONFIG_CHANGED, onRampAddress), + EventSigs: []common.Hash{configSetEventSig}, + Addresses: []common.Address{onRampAddress}, + Retention: ccipdata.CacheEvictionLogsRetention, + }, + } + cachedStaticConfig := cache.OnceCtxFunction[evm_2_evm_onramp_1_0_0.EVM2EVMOnRampStaticConfig](func(ctx context.Context) (evm_2_evm_onramp_1_0_0.EVM2EVMOnRampStaticConfig, error) { + return onRamp.GetStaticConfig(&bind.CallOpts{Context: ctx}) + }) + cachedRmnContract := cache.OnceCtxFunction[*arm_contract.ARMContract](func(ctx context.Context) (*arm_contract.ARMContract, error) { + staticConfig, err := cachedStaticConfig(ctx) + if err != nil { + return nil, err + } + + return arm_contract.NewARMContract(staticConfig.ArmProxy, source) + }) + return &OnRamp{ + lggr: lggr, + address: onRampAddress, + onRamp: onRamp, + client: source, + filters: filters, + lp: sourceLP, + leafHasher: NewLeafHasher(sourceSelector, destSelector, onRampAddress, hashutil.NewKeccak(), onRamp), + // offset || sourceChainID || seqNum || ... + sendRequestedSeqNumberWord: 2, + sendRequestedEventSig: eventSig, + cachedSourcePriceRegistryAddress: cache.NewLogpollerEventsBased[cciptypes.Address]( + sourceLP, + []common.Hash{configSetEventSig}, + onRampAddress, + ), + cachedStaticConfig: cache.CallOnceOnNoError(cachedStaticConfig), + cachedRmnContract: cache.CallOnceOnNoError(cachedRmnContract), + }, nil +} + +func (o *OnRamp) Address(context.Context) (cciptypes.Address, error) { + return cciptypes.Address(o.onRamp.Address().String()), nil +} + +func (o *OnRamp) GetDynamicConfig(context.Context) (cciptypes.OnRampDynamicConfig, error) { + if o.onRamp == nil { + return cciptypes.OnRampDynamicConfig{}, fmt.Errorf("onramp not initialized") + } + legacyDynamicConfig, err := o.onRamp.GetDynamicConfig(nil) + if err != nil { + return cciptypes.OnRampDynamicConfig{}, err + } + return cciptypes.OnRampDynamicConfig{ + Router: cciptypes.Address(legacyDynamicConfig.Router.String()), + MaxNumberOfTokensPerMsg: legacyDynamicConfig.MaxTokensLength, + DestGasOverhead: 0, + DestGasPerPayloadByte: 0, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 0, + DestDataAvailabilityMultiplierBps: 0, + PriceRegistry: cciptypes.Address(legacyDynamicConfig.PriceRegistry.String()), + MaxDataBytes: legacyDynamicConfig.MaxDataSize, + MaxPerMsgGasLimit: uint32(legacyDynamicConfig.MaxGasLimit), + }, nil +} + +func (o *OnRamp) SourcePriceRegistryAddress(ctx context.Context) (cciptypes.Address, error) { + return o.cachedSourcePriceRegistryAddress.Get(ctx, func(ctx context.Context) (cciptypes.Address, error) { + c, err := o.GetDynamicConfig(ctx) + if err != nil { + return "", err + } + return c.PriceRegistry, nil + }) +} + +func (o *OnRamp) GetSendRequestsBetweenSeqNums(ctx context.Context, seqNumMin, seqNumMax uint64, finalized bool) ([]cciptypes.EVM2EVMMessageWithTxMeta, error) { + logs, err := o.lp.LogsDataWordRange( + ctx, + o.sendRequestedEventSig, + o.address, + o.sendRequestedSeqNumberWord, + logpoller.EvmWord(seqNumMin), + logpoller.EvmWord(seqNumMax), + ccipdata.LogsConfirmations(finalized), + ) + if err != nil { + return nil, err + } + + parsedLogs, err := ccipdata.ParseLogs[cciptypes.EVM2EVMMessage](logs, o.lggr, o.logToMessage) + if err != nil { + return nil, err + } + + res := make([]cciptypes.EVM2EVMMessageWithTxMeta, 0, len(parsedLogs)) + for _, log := range parsedLogs { + res = append(res, cciptypes.EVM2EVMMessageWithTxMeta{ + TxMeta: log.TxMeta, + EVM2EVMMessage: log.Data, + }) + } + return res, nil +} + +func (o *OnRamp) RouterAddress(context.Context) (cciptypes.Address, error) { + config, err := o.onRamp.GetDynamicConfig(nil) + if err != nil { + return "", err + } + return cciptypes.Address(config.Router.String()), nil +} + +func (o *OnRamp) IsSourceChainHealthy(context.Context) (bool, error) { + if err := o.lp.Healthy(); err != nil { + return false, nil + } + return true, nil +} + +func (o *OnRamp) IsSourceCursed(ctx context.Context) (bool, error) { + arm, err := o.cachedRmnContract(ctx) + if err != nil { + return false, fmt.Errorf("intializing Arm contract through the ArmProxy: %w", err) + } + + cursed, err := arm.IsCursed0(&bind.CallOpts{Context: ctx}) + if err != nil { + return false, fmt.Errorf("checking if source Arm is cursed: %w", err) + } + return cursed, nil +} + +func (o *OnRamp) GetUSDCMessagePriorToLogIndexInTx(ctx context.Context, logIndex, offsetFromFinal int64, txHash common.Hash) ([]byte, error) { + return nil, errors.New("USDC not supported in < 1.2.0") +} + +func (o *OnRamp) Close() error { + return logpollerutil.UnregisterLpFilters(o.lp, o.filters) +} + +func (o *OnRamp) RegisterFilters() error { + return logpollerutil.RegisterLpFilters(o.lp, o.filters) +} + +func (o *OnRamp) logToMessage(log types.Log) (*cciptypes.EVM2EVMMessage, error) { + msg, err := o.onRamp.ParseCCIPSendRequested(log) + if err != nil { + return nil, err + } + h, err := o.leafHasher.HashLeaf(log) + if err != nil { + return nil, err + } + tokensAndAmounts := make([]cciptypes.TokenAmount, len(msg.Message.TokenAmounts)) + for i, tokenAndAmount := range msg.Message.TokenAmounts { + tokensAndAmounts[i] = cciptypes.TokenAmount{ + Token: cciptypes.Address(tokenAndAmount.Token.String()), + Amount: tokenAndAmount.Amount, + } + } + return &cciptypes.EVM2EVMMessage{ + SequenceNumber: msg.Message.SequenceNumber, + GasLimit: msg.Message.GasLimit, + Nonce: msg.Message.Nonce, + MessageID: msg.Message.MessageId, + SourceChainSelector: msg.Message.SourceChainSelector, + Sender: cciptypes.Address(msg.Message.Sender.String()), + Receiver: cciptypes.Address(msg.Message.Receiver.String()), + Strict: msg.Message.Strict, + FeeToken: cciptypes.Address(msg.Message.FeeToken.String()), + FeeTokenAmount: msg.Message.FeeTokenAmount, + Data: msg.Message.Data, + TokenAmounts: tokensAndAmounts, + SourceTokenData: make([][]byte, len(msg.Message.TokenAmounts)), // Always empty in 1.0 + Hash: h, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/price_registry.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/price_registry.go new file mode 100644 index 0000000000..d2104f985b --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/price_registry.go @@ -0,0 +1,310 @@ +package v1_0_0 + +import ( + "context" + "fmt" + "math/big" + "sync" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/erc20" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" +) + +var ( + abiERC20 = abihelpers.MustParseABI(erc20.ERC20ABI) + _ ccipdata.PriceRegistryReader = &PriceRegistry{} + // Exposed only for backwards compatibility with tests. + UsdPerUnitGasUpdated = abihelpers.MustGetEventID("UsdPerUnitGasUpdated", abihelpers.MustParseABI(price_registry_1_0_0.PriceRegistryABI)) +) + +type PriceRegistry struct { + priceRegistry price_registry_1_0_0.PriceRegistryInterface + address common.Address + lp logpoller.LogPoller + evmBatchCaller rpclib.EvmBatchCaller + lggr logger.Logger + filters []logpoller.Filter + tokenUpdated common.Hash + gasUpdated common.Hash + feeTokenAdded common.Hash + feeTokenRemoved common.Hash + + feeTokensCache cache.AutoSync[[]common.Address] + tokenDecimalsCache sync.Map +} + +func NewPriceRegistry(lggr logger.Logger, priceRegistryAddr common.Address, lp logpoller.LogPoller, ec client.Client, registerFilters bool) (*PriceRegistry, error) { + priceRegistry, err := price_registry_1_0_0.NewPriceRegistry(priceRegistryAddr, ec) + if err != nil { + return nil, err + } + priceRegABI := abihelpers.MustParseABI(price_registry_1_0_0.PriceRegistryABI) + usdPerTokenUpdated := abihelpers.MustGetEventID("UsdPerTokenUpdated", priceRegABI) + feeTokenRemoved := abihelpers.MustGetEventID("FeeTokenRemoved", priceRegABI) + feeTokenAdded := abihelpers.MustGetEventID("FeeTokenAdded", priceRegABI) + var filters = []logpoller.Filter{ + { + Name: logpoller.FilterName(ccipdata.COMMIT_PRICE_UPDATES, priceRegistryAddr.String()), + EventSigs: []common.Hash{UsdPerUnitGasUpdated, usdPerTokenUpdated}, + Addresses: []common.Address{priceRegistryAddr}, + Retention: ccipdata.PriceUpdatesLogsRetention, + }, + { + Name: logpoller.FilterName(ccipdata.FEE_TOKEN_ADDED, priceRegistryAddr.String()), + EventSigs: []common.Hash{feeTokenAdded}, + Addresses: []common.Address{priceRegistryAddr}, + Retention: ccipdata.CacheEvictionLogsRetention, + }, + { + Name: logpoller.FilterName(ccipdata.FEE_TOKEN_REMOVED, priceRegistryAddr.String()), + EventSigs: []common.Hash{feeTokenRemoved}, + Addresses: []common.Address{priceRegistryAddr}, + Retention: ccipdata.CacheEvictionLogsRetention, + }} + if registerFilters { + err = logpollerutil.RegisterLpFilters(lp, filters) + if err != nil { + return nil, err + } + } + return &PriceRegistry{ + priceRegistry: priceRegistry, + address: priceRegistryAddr, + lp: lp, + evmBatchCaller: rpclib.NewDynamicLimitedBatchCaller( + lggr, + ec, + rpclib.DefaultRpcBatchSizeLimit, + rpclib.DefaultRpcBatchBackOffMultiplier, + rpclib.DefaultMaxParallelRpcCalls, + ), + lggr: lggr, + gasUpdated: UsdPerUnitGasUpdated, + tokenUpdated: usdPerTokenUpdated, + feeTokenRemoved: feeTokenRemoved, + feeTokenAdded: feeTokenAdded, + filters: filters, + feeTokensCache: cache.NewLogpollerEventsBased[[]common.Address]( + lp, + []common.Hash{feeTokenAdded, feeTokenRemoved}, + priceRegistryAddr, + ), + }, nil +} + +func (p *PriceRegistry) GetTokenPrices(ctx context.Context, wantedTokens []cciptypes.Address) ([]cciptypes.TokenPriceUpdate, error) { + evmAddrs, err := ccipcalc.GenericAddrsToEvm(wantedTokens...) + if err != nil { + return nil, err + } + + tps, err := p.priceRegistry.GetTokenPrices(&bind.CallOpts{Context: ctx}, evmAddrs) + if err != nil { + return nil, err + } + var tpu []cciptypes.TokenPriceUpdate + for i, tp := range tps { + tpu = append(tpu, cciptypes.TokenPriceUpdate{ + TokenPrice: cciptypes.TokenPrice{ + Token: cciptypes.Address(evmAddrs[i].String()), + Value: tp.Value, + }, + TimestampUnixSec: big.NewInt(int64(tp.Timestamp)), + }) + } + return tpu, nil +} + +func (p *PriceRegistry) Address(ctx context.Context) (cciptypes.Address, error) { + return cciptypes.Address(p.address.String()), nil +} + +func (p *PriceRegistry) GetFeeTokens(ctx context.Context) ([]cciptypes.Address, error) { + feeTokens, err := p.feeTokensCache.Get(ctx, func(ctx context.Context) ([]common.Address, error) { + return p.priceRegistry.GetFeeTokens(&bind.CallOpts{Context: ctx}) + }) + if err != nil { + return nil, fmt.Errorf("get fee tokens: %w", err) + } + + return ccipcalc.EvmAddrsToGeneric(feeTokens...), nil +} + +func (p *PriceRegistry) Close() error { + return logpollerutil.UnregisterLpFilters(p.lp, p.filters) +} + +func (p *PriceRegistry) GetTokenPriceUpdatesCreatedAfter(ctx context.Context, ts time.Time, confs int) ([]cciptypes.TokenPriceUpdateWithTxMeta, error) { + logs, err := p.lp.LogsCreatedAfter( + ctx, + p.tokenUpdated, + p.address, + ts, + evmtypes.Confirmations(confs), + ) + if err != nil { + return nil, err + } + + parsedLogs, err := ccipdata.ParseLogs[cciptypes.TokenPriceUpdate]( + logs, + p.lggr, + func(log types.Log) (*cciptypes.TokenPriceUpdate, error) { + tp, err1 := p.priceRegistry.ParseUsdPerTokenUpdated(log) + if err1 != nil { + return nil, err1 + } + return &cciptypes.TokenPriceUpdate{ + TokenPrice: cciptypes.TokenPrice{ + Token: cciptypes.Address(tp.Token.String()), + Value: tp.Value, + }, + TimestampUnixSec: tp.Timestamp, + }, nil + }, + ) + if err != nil { + return nil, err + } + + res := make([]cciptypes.TokenPriceUpdateWithTxMeta, 0, len(parsedLogs)) + for _, log := range parsedLogs { + res = append(res, cciptypes.TokenPriceUpdateWithTxMeta{ + TxMeta: log.TxMeta, + TokenPriceUpdate: log.Data, + }) + } + return res, nil +} + +func (p *PriceRegistry) GetGasPriceUpdatesCreatedAfter(ctx context.Context, chainSelector uint64, ts time.Time, confs int) ([]cciptypes.GasPriceUpdateWithTxMeta, error) { + logs, err := p.lp.IndexedLogsCreatedAfter( + ctx, + p.gasUpdated, + p.address, + 1, + []common.Hash{abihelpers.EvmWord(chainSelector)}, + ts, + evmtypes.Confirmations(confs), + ) + if err != nil { + return nil, err + } + return p.parseGasPriceUpdatesLogs(logs) +} + +func (p *PriceRegistry) GetAllGasPriceUpdatesCreatedAfter(ctx context.Context, ts time.Time, confs int) ([]cciptypes.GasPriceUpdateWithTxMeta, error) { + logs, err := p.lp.LogsCreatedAfter( + ctx, + p.gasUpdated, + p.address, + ts, + evmtypes.Confirmations(confs), + ) + if err != nil { + return nil, err + } + return p.parseGasPriceUpdatesLogs(logs) +} + +func (p *PriceRegistry) parseGasPriceUpdatesLogs(logs []logpoller.Log) ([]cciptypes.GasPriceUpdateWithTxMeta, error) { + parsedLogs, err := ccipdata.ParseLogs[cciptypes.GasPriceUpdate]( + logs, + p.lggr, + func(log types.Log) (*cciptypes.GasPriceUpdate, error) { + p, err1 := p.priceRegistry.ParseUsdPerUnitGasUpdated(log) + if err1 != nil { + return nil, err1 + } + return &cciptypes.GasPriceUpdate{ + GasPrice: cciptypes.GasPrice{ + DestChainSelector: p.DestChain, + Value: p.Value, + }, + TimestampUnixSec: p.Timestamp, + }, nil + }, + ) + if err != nil { + return nil, err + } + + res := make([]cciptypes.GasPriceUpdateWithTxMeta, 0, len(parsedLogs)) + for _, log := range parsedLogs { + res = append(res, cciptypes.GasPriceUpdateWithTxMeta{ + TxMeta: log.TxMeta, + GasPriceUpdate: log.Data, + }) + } + return res, nil +} + +func (p *PriceRegistry) GetTokensDecimals(ctx context.Context, tokenAddresses []cciptypes.Address) ([]uint8, error) { + evmAddrs, err := ccipcalc.GenericAddrsToEvm(tokenAddresses...) + if err != nil { + return nil, err + } + + found := make(map[common.Address]bool) + tokenDecimals := make([]uint8, len(evmAddrs)) + for i, tokenAddress := range evmAddrs { + if v, ok := p.tokenDecimalsCache.Load(tokenAddress); ok { + if decimals, isUint8 := v.(uint8); isUint8 { + tokenDecimals[i] = decimals + found[tokenAddress] = true + } else { + p.lggr.Errorf("token decimals cache contains invalid type %T", v) + } + } + } + if len(found) == len(evmAddrs) { + return tokenDecimals, nil + } + + evmCalls := make([]rpclib.EvmCall, 0, len(evmAddrs)) + for _, tokenAddress := range evmAddrs { + if !found[tokenAddress] { + evmCalls = append(evmCalls, rpclib.NewEvmCall(abiERC20, "decimals", tokenAddress)) + } + } + + results, err := p.evmBatchCaller.BatchCall(ctx, 0, evmCalls) + if err != nil { + return nil, fmt.Errorf("batch call limit: %w", err) + } + + decimals, err := rpclib.ParseOutputs[uint8](results, func(d rpclib.DataAndErr) (uint8, error) { + return rpclib.ParseOutput[uint8](d, 0) + }) + if err != nil { + return nil, fmt.Errorf("parse outputs: %w", err) + } + + j := 0 + for i, tokenAddress := range evmAddrs { + if !found[tokenAddress] { + tokenDecimals[i] = decimals[j] + p.tokenDecimalsCache.Store(tokenAddress, tokenDecimals[i]) + j++ + } + } + return tokenDecimals, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/test_helpers.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/test_helpers.go new file mode 100644 index 0000000000..34f832e17f --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/test_helpers.go @@ -0,0 +1,90 @@ +package v1_0_0 + +import ( + "encoding/binary" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +// ApplyPriceRegistryUpdate is a helper function used in tests only. +func ApplyPriceRegistryUpdate(t *testing.T, user *bind.TransactOpts, addr common.Address, ec client.Client, gasPrice []cciptypes.GasPrice, tokenPrices []cciptypes.TokenPrice) { + require.True(t, len(gasPrice) <= 2) + pr, err := price_registry_1_0_0.NewPriceRegistry(addr, ec) + require.NoError(t, err) + var tps []price_registry_1_0_0.InternalTokenPriceUpdate + for _, tp := range tokenPrices { + evmAddrs, err1 := ccipcalc.GenericAddrsToEvm(tp.Token) + assert.NoError(t, err1) + tps = append(tps, price_registry_1_0_0.InternalTokenPriceUpdate{ + SourceToken: evmAddrs[0], + UsdPerToken: tp.Value, + }) + } + dest := uint64(0) + gas := big.NewInt(0) + if len(gasPrice) >= 1 { + dest = gasPrice[0].DestChainSelector + gas = gasPrice[0].Value + } + _, err = pr.UpdatePrices(user, price_registry_1_0_0.InternalPriceUpdates{ + TokenPriceUpdates: tps, + DestChainSelector: dest, + UsdPerUnitGas: gas, + }) + require.NoError(t, err) + + for i := 1; i < len(gasPrice); i++ { + dest = gasPrice[i].DestChainSelector + gas = gasPrice[i].Value + _, err = pr.UpdatePrices(user, price_registry_1_0_0.InternalPriceUpdates{ + TokenPriceUpdates: []price_registry_1_0_0.InternalTokenPriceUpdate{}, + DestChainSelector: dest, + UsdPerUnitGas: gas, + }) + require.NoError(t, err) + } +} + +func CreateExecutionStateChangeEventLog(t *testing.T, seqNr uint64, blockNumber int64, messageID common.Hash) logpoller.Log { + tAbi, err := evm_2_evm_offramp.EVM2EVMOffRampMetaData.GetAbi() + require.NoError(t, err) + eseEvent, ok := tAbi.Events["ExecutionStateChanged"] + require.True(t, ok) + + logData, err := eseEvent.Inputs.NonIndexed().Pack(uint8(1), []byte("some return data")) + require.NoError(t, err) + seqNrBytes := make([]byte, 8) + binary.BigEndian.PutUint64(seqNrBytes, seqNr) + seqNrTopic := common.BytesToHash(seqNrBytes) + topic0 := evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged{}.Topic() + + return logpoller.Log{ + Topics: [][]byte{ + topic0[:], + seqNrTopic[:], + messageID[:], + }, + Data: logData, + LogIndex: 1, + BlockHash: utils.RandomBytes32(), + BlockNumber: blockNumber, + EventSig: topic0, + Address: testutils.NewAddress(), + TxHash: utils.RandomBytes32(), + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_1_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_1_0/onramp.go new file mode 100644 index 0000000000..d4d73219fc --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_1_0/onramp.go @@ -0,0 +1,70 @@ +package v1_1_0 + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/common" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_1_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" +) + +var _ ccipdata.OnRampReader = &OnRamp{} + +// OnRamp The only difference that the plugins care about in 1.1 is that the dynamic config struct has changed. +type OnRamp struct { + *v1_0_0.OnRamp + onRamp *evm_2_evm_onramp_1_1_0.EVM2EVMOnRamp +} + +func NewOnRamp(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAddress common.Address, sourceLP logpoller.LogPoller, source client.Client) (*OnRamp, error) { + onRamp, err := evm_2_evm_onramp_1_1_0.NewEVM2EVMOnRamp(onRampAddress, source) + if err != nil { + return nil, err + } + onRamp100, err := v1_0_0.NewOnRamp(lggr, sourceSelector, destSelector, onRampAddress, sourceLP, source) + if err != nil { + return nil, err + } + return &OnRamp{ + OnRamp: onRamp100, + onRamp: onRamp, + }, nil +} + +func (o *OnRamp) RouterAddress(context.Context) (cciptypes.Address, error) { + config, err := o.onRamp.GetDynamicConfig(nil) + if err != nil { + return "", err + } + return cciptypes.Address(config.Router.String()), nil +} + +func (o *OnRamp) GetDynamicConfig(context.Context) (cciptypes.OnRampDynamicConfig, error) { + if o.onRamp == nil { + return cciptypes.OnRampDynamicConfig{}, fmt.Errorf("onramp not initialized") + } + legacyDynamicConfig, err := o.onRamp.GetDynamicConfig(nil) + if err != nil { + return cciptypes.OnRampDynamicConfig{}, err + } + return cciptypes.OnRampDynamicConfig{ + Router: cciptypes.Address(legacyDynamicConfig.Router.String()), + MaxNumberOfTokensPerMsg: legacyDynamicConfig.MaxTokensLength, + DestGasOverhead: legacyDynamicConfig.DestGasOverhead, + DestGasPerPayloadByte: legacyDynamicConfig.DestGasPerPayloadByte, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 0, + DestDataAvailabilityMultiplierBps: 0, + PriceRegistry: cciptypes.Address(legacyDynamicConfig.PriceRegistry.String()), + MaxDataBytes: legacyDynamicConfig.MaxDataSize, + MaxPerMsgGasLimit: uint32(legacyDynamicConfig.MaxGasLimit), + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go new file mode 100644 index 0000000000..7612e54419 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go @@ -0,0 +1,469 @@ +package v1_2_0 + +import ( + "context" + "fmt" + "math/big" + "sync" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/types/query" + "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +var _ ccipdata.CommitStoreReader = &CommitStore{} + +type CommitStore struct { + // Static config + commitStore *commit_store_1_2_0.CommitStore + lggr logger.Logger + lp logpoller.LogPoller + address common.Address + estimator *gas.EvmFeeEstimator + sourceMaxGasPrice *big.Int + filters []logpoller.Filter + reportAcceptedSig common.Hash + reportAcceptedMaxSeqIndex int + commitReportArgs abi.Arguments + + // Dynamic config + configMu sync.RWMutex + gasPriceEstimator *prices.DAGasPriceEstimator + offchainConfig cciptypes.CommitOffchainConfig +} + +func (c *CommitStore) GetCommitStoreStaticConfig(ctx context.Context) (cciptypes.CommitStoreStaticConfig, error) { + staticConfig, err := c.commitStore.GetStaticConfig(&bind.CallOpts{Context: ctx}) + if err != nil { + return cciptypes.CommitStoreStaticConfig{}, err + } + return cciptypes.CommitStoreStaticConfig{ + ChainSelector: staticConfig.ChainSelector, + SourceChainSelector: staticConfig.SourceChainSelector, + OnRamp: cciptypes.Address(staticConfig.OnRamp.String()), + ArmProxy: cciptypes.Address(staticConfig.ArmProxy.String()), + }, nil +} + +func (c *CommitStore) EncodeCommitReport(_ context.Context, report cciptypes.CommitStoreReport) ([]byte, error) { + return EncodeCommitReport(c.commitReportArgs, report) +} + +func EncodeCommitReport(commitReportArgs abi.Arguments, report cciptypes.CommitStoreReport) ([]byte, error) { + var tokenPriceUpdates []commit_store_1_2_0.InternalTokenPriceUpdate + for _, tokenPriceUpdate := range report.TokenPrices { + tokenAddressEvm, err := ccipcalc.GenericAddrToEvm(tokenPriceUpdate.Token) + if err != nil { + return nil, fmt.Errorf("token price update address to evm: %w", err) + } + + tokenPriceUpdates = append(tokenPriceUpdates, commit_store_1_2_0.InternalTokenPriceUpdate{ + SourceToken: tokenAddressEvm, + UsdPerToken: tokenPriceUpdate.Value, + }) + } + + var gasPriceUpdates []commit_store_1_2_0.InternalGasPriceUpdate + for _, gasPriceUpdate := range report.GasPrices { + gasPriceUpdates = append(gasPriceUpdates, commit_store_1_2_0.InternalGasPriceUpdate{ + DestChainSelector: gasPriceUpdate.DestChainSelector, + UsdPerUnitGas: gasPriceUpdate.Value, + }) + } + + rep := commit_store_1_2_0.CommitStoreCommitReport{ + PriceUpdates: commit_store_1_2_0.InternalPriceUpdates{ + TokenPriceUpdates: tokenPriceUpdates, + GasPriceUpdates: gasPriceUpdates, + }, + Interval: commit_store_1_2_0.CommitStoreInterval{Min: report.Interval.Min, Max: report.Interval.Max}, + MerkleRoot: report.MerkleRoot, + } + return commitReportArgs.PackValues([]interface{}{rep}) +} + +func DecodeCommitReport(commitReportArgs abi.Arguments, report []byte) (cciptypes.CommitStoreReport, error) { + unpacked, err := commitReportArgs.Unpack(report) + if err != nil { + return cciptypes.CommitStoreReport{}, err + } + if len(unpacked) != 1 { + return cciptypes.CommitStoreReport{}, errors.New("expected single struct value") + } + + commitReport, ok := unpacked[0].(struct { + PriceUpdates struct { + TokenPriceUpdates []struct { + SourceToken common.Address `json:"sourceToken"` + UsdPerToken *big.Int `json:"usdPerToken"` + } `json:"tokenPriceUpdates"` + GasPriceUpdates []struct { + DestChainSelector uint64 `json:"destChainSelector"` + UsdPerUnitGas *big.Int `json:"usdPerUnitGas"` + } `json:"gasPriceUpdates"` + } `json:"priceUpdates"` + Interval struct { + Min uint64 `json:"min"` + Max uint64 `json:"max"` + } `json:"interval"` + MerkleRoot [32]byte `json:"merkleRoot"` + }) + if !ok { + return cciptypes.CommitStoreReport{}, errors.Errorf("invalid commit report got %T", unpacked[0]) + } + + var tokenPriceUpdates []cciptypes.TokenPrice + for _, u := range commitReport.PriceUpdates.TokenPriceUpdates { + tokenPriceUpdates = append(tokenPriceUpdates, cciptypes.TokenPrice{ + Token: cciptypes.Address(u.SourceToken.String()), + Value: u.UsdPerToken, + }) + } + + var gasPrices []cciptypes.GasPrice + for _, u := range commitReport.PriceUpdates.GasPriceUpdates { + gasPrices = append(gasPrices, cciptypes.GasPrice{ + DestChainSelector: u.DestChainSelector, + Value: u.UsdPerUnitGas, + }) + } + + return cciptypes.CommitStoreReport{ + TokenPrices: tokenPriceUpdates, + GasPrices: gasPrices, + Interval: cciptypes.CommitStoreInterval{ + Min: commitReport.Interval.Min, + Max: commitReport.Interval.Max, + }, + MerkleRoot: commitReport.MerkleRoot, + }, nil +} + +func (c *CommitStore) DecodeCommitReport(_ context.Context, report []byte) (cciptypes.CommitStoreReport, error) { + return DecodeCommitReport(c.commitReportArgs, report) +} + +func (c *CommitStore) IsBlessed(ctx context.Context, root [32]byte) (bool, error) { + return c.commitStore.IsBlessed(&bind.CallOpts{Context: ctx}, root) +} + +func (c *CommitStore) OffchainConfig(context.Context) (cciptypes.CommitOffchainConfig, error) { + c.configMu.RLock() + defer c.configMu.RUnlock() + return c.offchainConfig, nil +} + +func (c *CommitStore) GasPriceEstimator(context.Context) (cciptypes.GasPriceEstimatorCommit, error) { + c.configMu.RLock() + defer c.configMu.RUnlock() + return c.gasPriceEstimator, nil +} + +func (c *CommitStore) SetGasEstimator(ctx context.Context, gpe gas.EvmFeeEstimator) error { + c.configMu.RLock() + defer c.configMu.RUnlock() + c.estimator = &gpe + return nil +} + +func (c *CommitStore) SetSourceMaxGasPrice(ctx context.Context, sourceMaxGasPrice *big.Int) error { + c.configMu.RLock() + defer c.configMu.RUnlock() + c.sourceMaxGasPrice = sourceMaxGasPrice + return nil +} + +// Do not change the JSON format of this struct without consulting with the RDD people first. +type JSONCommitOffchainConfig struct { + SourceFinalityDepth uint32 + DestFinalityDepth uint32 + GasPriceHeartBeat config.Duration + DAGasPriceDeviationPPB uint32 + ExecGasPriceDeviationPPB uint32 + TokenPriceHeartBeat config.Duration + TokenPriceDeviationPPB uint32 + InflightCacheExpiry config.Duration + PriceReportingDisabled bool +} + +func (c JSONCommitOffchainConfig) Validate() error { + if c.GasPriceHeartBeat.Duration() == 0 { + return errors.New("must set GasPriceHeartBeat") + } + if c.ExecGasPriceDeviationPPB == 0 { + return errors.New("must set ExecGasPriceDeviationPPB") + } + if c.TokenPriceHeartBeat.Duration() == 0 { + return errors.New("must set TokenPriceHeartBeat") + } + if c.TokenPriceDeviationPPB == 0 { + return errors.New("must set TokenPriceDeviationPPB") + } + if c.InflightCacheExpiry.Duration() == 0 { + return errors.New("must set InflightCacheExpiry") + } + // DAGasPriceDeviationPPB is not validated because it can be 0 on non-rollups + + return nil +} + +func (c *CommitStore) ChangeConfig(_ context.Context, onchainConfig []byte, offchainConfig []byte) (cciptypes.Address, error) { + onchainConfigParsed, err := abihelpers.DecodeAbiStruct[ccipdata.CommitOnchainConfig](onchainConfig) + if err != nil { + return "", err + } + + offchainConfigParsed, err := ccipconfig.DecodeOffchainConfig[JSONCommitOffchainConfig](offchainConfig) + if err != nil { + return "", err + } + c.configMu.Lock() + defer c.configMu.Unlock() + + if c.estimator == nil { + return "", fmt.Errorf("this CommitStore estimator is nil. SetGasEstimator should be called before ChangeConfig") + } + + if c.sourceMaxGasPrice == nil { + return "", fmt.Errorf("this CommitStore sourceMaxGasPrice is nil. SetSourceMaxGasPrice should be called before ChangeConfig") + } + + c.gasPriceEstimator = prices.NewDAGasPriceEstimator( + *c.estimator, + c.sourceMaxGasPrice, + int64(offchainConfigParsed.ExecGasPriceDeviationPPB), + int64(offchainConfigParsed.DAGasPriceDeviationPPB), + ) + c.offchainConfig = ccipdata.NewCommitOffchainConfig( + offchainConfigParsed.ExecGasPriceDeviationPPB, + offchainConfigParsed.GasPriceHeartBeat.Duration(), + offchainConfigParsed.TokenPriceDeviationPPB, + offchainConfigParsed.TokenPriceHeartBeat.Duration(), + offchainConfigParsed.InflightCacheExpiry.Duration(), + offchainConfigParsed.PriceReportingDisabled, + ) + + c.lggr.Infow("ChangeConfig", + "offchainConfig", offchainConfigParsed, + "onchainConfig", onchainConfigParsed, + ) + return cciptypes.Address(onchainConfigParsed.PriceRegistry.String()), nil +} + +func (c *CommitStore) Close() error { + return logpollerutil.UnregisterLpFilters(c.lp, c.filters) +} + +func (c *CommitStore) parseReport(log types.Log) (*cciptypes.CommitStoreReport, error) { + repAccepted, err := c.commitStore.ParseReportAccepted(log) + if err != nil { + return nil, err + } + // Translate to common struct. + var tokenPrices []cciptypes.TokenPrice + for _, tpu := range repAccepted.Report.PriceUpdates.TokenPriceUpdates { + tokenPrices = append(tokenPrices, cciptypes.TokenPrice{ + Token: cciptypes.Address(tpu.SourceToken.String()), + Value: tpu.UsdPerToken, + }) + } + var gasPrices []cciptypes.GasPrice + for _, tpu := range repAccepted.Report.PriceUpdates.GasPriceUpdates { + gasPrices = append(gasPrices, cciptypes.GasPrice{ + DestChainSelector: tpu.DestChainSelector, + Value: tpu.UsdPerUnitGas, + }) + } + + return &cciptypes.CommitStoreReport{ + TokenPrices: tokenPrices, + GasPrices: gasPrices, + MerkleRoot: repAccepted.Report.MerkleRoot, + Interval: cciptypes.CommitStoreInterval{Min: repAccepted.Report.Interval.Min, Max: repAccepted.Report.Interval.Max}, + }, nil +} + +func (c *CommitStore) GetCommitReportMatchingSeqNum(ctx context.Context, seqNr uint64, confs int) ([]cciptypes.CommitStoreReportWithTxMeta, error) { + logs, err := c.lp.LogsDataWordBetween( + ctx, + c.reportAcceptedSig, + c.address, + c.reportAcceptedMaxSeqIndex-1, + c.reportAcceptedMaxSeqIndex, + logpoller.EvmWord(seqNr), + evmtypes.Confirmations(confs), + ) + if err != nil { + return nil, err + } + + parsedLogs, err := ccipdata.ParseLogs[cciptypes.CommitStoreReport]( + logs, + c.lggr, + c.parseReport, + ) + if err != nil { + return nil, err + } + + res := make([]cciptypes.CommitStoreReportWithTxMeta, 0, len(parsedLogs)) + for _, log := range parsedLogs { + res = append(res, cciptypes.CommitStoreReportWithTxMeta{ + TxMeta: log.TxMeta, + CommitStoreReport: log.Data, + }) + } + + if len(res) > 1 { + c.lggr.Errorw("More than one report found for seqNr", "seqNr", seqNr, "commitReports", parsedLogs) + return res[:1], nil + } + return res, nil +} + +func (c *CommitStore) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confs int) ([]cciptypes.CommitStoreReportWithTxMeta, error) { + latestBlock, err := c.lp.LatestBlock(ctx) + if err != nil { + return nil, err + } + + reportsQuery, err := query.Where( + c.address.String(), + logpoller.NewAddressFilter(c.address), + logpoller.NewEventSigFilter(c.reportAcceptedSig), + query.Timestamp(uint64(ts.Unix()), primitives.Gte), + logpoller.NewConfirmationsFilter(evmtypes.Confirmations(confs)), + ) + if err != nil { + return nil, err + } + + logs, err := c.lp.FilteredLogs( + ctx, + reportsQuery, + query.NewLimitAndSort(query.Limit{}, query.NewSortBySequence(query.Asc)), + "GetAcceptedCommitReportsGteTimestamp", + ) + if err != nil { + return nil, err + } + + parsedLogs, err := ccipdata.ParseLogs[cciptypes.CommitStoreReport](logs, c.lggr, c.parseReport) + if err != nil { + return nil, fmt.Errorf("parse logs: %w", err) + } + + res := make([]cciptypes.CommitStoreReportWithTxMeta, 0, len(parsedLogs)) + for _, log := range parsedLogs { + res = append(res, cciptypes.CommitStoreReportWithTxMeta{ + TxMeta: log.TxMeta.WithFinalityStatus(uint64(latestBlock.FinalizedBlockNumber)), + CommitStoreReport: log.Data, + }) + } + return res, nil +} + +func (c *CommitStore) GetExpectedNextSequenceNumber(ctx context.Context) (uint64, error) { + return c.commitStore.GetExpectedNextSequenceNumber(&bind.CallOpts{Context: ctx}) +} + +func (c *CommitStore) GetLatestPriceEpochAndRound(ctx context.Context) (uint64, error) { + return c.commitStore.GetLatestPriceEpochAndRound(&bind.CallOpts{Context: ctx}) +} + +func (c *CommitStore) IsDestChainHealthy(context.Context) (bool, error) { + if err := c.lp.Healthy(); err != nil { + return false, nil + } + return true, nil +} + +func (c *CommitStore) IsDown(ctx context.Context) (bool, error) { + unPausedAndHealthy, err := c.commitStore.IsUnpausedAndARMHealthy(&bind.CallOpts{Context: ctx}) + if err != nil { + return true, err + } + return !unPausedAndHealthy, nil +} + +func (c *CommitStore) VerifyExecutionReport(ctx context.Context, report cciptypes.ExecReport) (bool, error) { + var hashes [][32]byte + for _, msg := range report.Messages { + hashes = append(hashes, msg.Hash) + } + res, err := c.commitStore.Verify(&bind.CallOpts{Context: ctx}, hashes, report.Proofs, report.ProofFlagBits) + if err != nil { + c.lggr.Errorw("Unable to call verify", "messages", report.Messages, "err", err) + return false, nil + } + // No timestamp, means failed to verify root. + if res.Cmp(big.NewInt(0)) == 0 { + c.lggr.Errorw("Root does not verify", "messages", report.Messages) + return false, nil + } + return true, nil +} + +func (c *CommitStore) RegisterFilters() error { + return logpollerutil.RegisterLpFilters(c.lp, c.filters) +} + +func NewCommitStore(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller) (*CommitStore, error) { + commitStore, err := commit_store_1_2_0.NewCommitStore(addr, ec) + if err != nil { + return nil, err + } + commitStoreABI := abihelpers.MustParseABI(commit_store_1_2_0.CommitStoreABI) + eventSig := abihelpers.MustGetEventID(v1_0_0.ReportAccepted, commitStoreABI) + commitReportArgs := abihelpers.MustGetEventInputs(v1_0_0.ReportAccepted, commitStoreABI) + filters := []logpoller.Filter{ + { + Name: logpoller.FilterName(v1_0_0.EXEC_REPORT_ACCEPTS, addr.String()), + EventSigs: []common.Hash{eventSig}, + Addresses: []common.Address{addr}, + Retention: ccipdata.CommitExecLogsRetention, + }, + } + + return &CommitStore{ + commitStore: commitStore, + address: addr, + lggr: lggr, + lp: lp, + + // Note that sourceMaxGasPrice and estimator now have explicit setters (CCIP-2493) + + filters: filters, + commitReportArgs: commitReportArgs, + reportAcceptedSig: eventSig, + // offset || priceUpdatesOffset || minSeqNum || maxSeqNum || merkleRoot + reportAcceptedMaxSeqIndex: 3, + configMu: sync.RWMutex{}, + + // The fields below are initially empty and set on ChangeConfig method + offchainConfig: cciptypes.CommitOffchainConfig{}, + gasPriceEstimator: nil, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go new file mode 100644 index 0000000000..8b29309633 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go @@ -0,0 +1,224 @@ +package v1_2_0 + +import ( + "math/big" + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" +) + +func TestCommitReportEncoding(t *testing.T) { + t.Parallel() + ctx := testutils.Context(t) + report := cciptypes.CommitStoreReport{ + TokenPrices: []cciptypes.TokenPrice{ + { + Token: cciptypes.Address(utils.RandomAddress().String()), + Value: big.NewInt(9e18), + }, + { + Token: cciptypes.Address(utils.RandomAddress().String()), + Value: big.NewInt(1e18), + }, + }, + GasPrices: []cciptypes.GasPrice{ + { + DestChainSelector: rand.Uint64(), + Value: big.NewInt(2000e9), + }, + { + DestChainSelector: rand.Uint64(), + Value: big.NewInt(3000e9), + }, + }, + MerkleRoot: [32]byte{123}, + Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}, + } + + c, err := NewCommitStore(logger.TestLogger(t), utils.RandomAddress(), nil, mocks.NewLogPoller(t)) + assert.NoError(t, err) + + encodedReport, err := c.EncodeCommitReport(ctx, report) + require.NoError(t, err) + assert.Greater(t, len(encodedReport), 0) + + decodedReport, err := c.DecodeCommitReport(ctx, encodedReport) + require.NoError(t, err) + require.Equal(t, report, decodedReport) +} + +func TestCommitStoreV120ffchainConfigEncoding(t *testing.T) { + t.Parallel() + validConfig := JSONCommitOffchainConfig{ + SourceFinalityDepth: 3, + DestFinalityDepth: 4, + GasPriceHeartBeat: *config.MustNewDuration(1 * time.Minute), + DAGasPriceDeviationPPB: 10, + ExecGasPriceDeviationPPB: 11, + TokenPriceHeartBeat: *config.MustNewDuration(2 * time.Minute), + TokenPriceDeviationPPB: 12, + InflightCacheExpiry: *config.MustNewDuration(3 * time.Minute), + } + + require.NoError(t, validConfig.Validate()) + + tests := []struct { + name string + want JSONCommitOffchainConfig + errPattern string + }{ + { + name: "legacy offchain config format parses", + want: validConfig, + }, + { + name: "can omit finality depth", + want: modifyCopy(validConfig, func(c *JSONCommitOffchainConfig) { + c.SourceFinalityDepth = 0 + c.DestFinalityDepth = 0 + }), + }, + { + name: "can set PriceReportingDisabled", + want: modifyCopy(validConfig, func(c *JSONCommitOffchainConfig) { + c.PriceReportingDisabled = true + }), + }, + { + name: "must set GasPriceHeartBeat", + want: modifyCopy(validConfig, func(c *JSONCommitOffchainConfig) { + c.GasPriceHeartBeat = *config.MustNewDuration(0) + }), + errPattern: "GasPriceHeartBeat", + }, + { + name: "must set ExecGasPriceDeviationPPB", + want: modifyCopy(validConfig, func(c *JSONCommitOffchainConfig) { + c.ExecGasPriceDeviationPPB = 0 + }), + errPattern: "ExecGasPriceDeviationPPB", + }, + { + name: "must set TokenPriceHeartBeat", + want: modifyCopy(validConfig, func(c *JSONCommitOffchainConfig) { + c.TokenPriceHeartBeat = *config.MustNewDuration(0) + }), + errPattern: "TokenPriceHeartBeat", + }, + { + name: "must set TokenPriceDeviationPPB", + want: modifyCopy(validConfig, func(c *JSONCommitOffchainConfig) { + c.TokenPriceDeviationPPB = 0 + }), + errPattern: "TokenPriceDeviationPPB", + }, + { + name: "must set InflightCacheExpiry", + want: modifyCopy(validConfig, func(c *JSONCommitOffchainConfig) { + c.InflightCacheExpiry = *config.MustNewDuration(0) + }), + errPattern: "InflightCacheExpiry", + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + exp := tc.want + encode, err := ccipconfig.EncodeOffchainConfig(&exp) + require.NoError(t, err) + got, err := ccipconfig.DecodeOffchainConfig[JSONCommitOffchainConfig](encode) + + if tc.errPattern != "" { + require.ErrorContains(t, err, tc.errPattern) + } else { + require.NoError(t, err) + require.Equal(t, tc.want, got) + } + }) + } +} + +func TestCommitStoreV120ffchainConfigDecodingCompatibility(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + config []byte + priceReportingDisabled bool + }{ + { + name: "with MaxGasPrice", + config: []byte(`{ + "SourceFinalityDepth": 3, + "DestFinalityDepth": 4, + "GasPriceHeartBeat": "60s", + "DAGasPriceDeviationPPB": 10, + "ExecGasPriceDeviationPPB": 11, + "TokenPriceHeartBeat": "120s", + "TokenPriceDeviationPPB": 12, + "MaxGasPrice": 100000000, + "SourceMaxGasPrice": 100000000, + "InflightCacheExpiry": "180s" + }`), + priceReportingDisabled: false, + }, + { + name: "without MaxGasPrice", + config: []byte(`{ + "SourceFinalityDepth": 3, + "DestFinalityDepth": 4, + "GasPriceHeartBeat": "60s", + "DAGasPriceDeviationPPB": 10, + "ExecGasPriceDeviationPPB": 11, + "TokenPriceHeartBeat": "120s", + "TokenPriceDeviationPPB": 12, + "InflightCacheExpiry": "180s" + }`), + priceReportingDisabled: false, + }, + { + name: "with PriceReportingDisabled", + config: []byte(`{ + "SourceFinalityDepth": 3, + "DestFinalityDepth": 4, + "GasPriceHeartBeat": "60s", + "DAGasPriceDeviationPPB": 10, + "ExecGasPriceDeviationPPB": 11, + "TokenPriceHeartBeat": "120s", + "TokenPriceDeviationPPB": 12, + "InflightCacheExpiry": "180s", + "PriceReportingDisabled": true + }`), + priceReportingDisabled: true, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + decoded, err := ccipconfig.DecodeOffchainConfig[JSONCommitOffchainConfig](tc.config) + require.NoError(t, err) + require.Equal(t, JSONCommitOffchainConfig{ + SourceFinalityDepth: 3, + DestFinalityDepth: 4, + GasPriceHeartBeat: *config.MustNewDuration(1 * time.Minute), + DAGasPriceDeviationPPB: 10, + ExecGasPriceDeviationPPB: 11, + TokenPriceHeartBeat: *config.MustNewDuration(2 * time.Minute), + TokenPriceDeviationPPB: 12, + InflightCacheExpiry: *config.MustNewDuration(3 * time.Minute), + PriceReportingDisabled: tc.priceReportingDisabled, + }, decoded) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/hasher.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/hasher.go new file mode 100644 index 0000000000..4739c946c3 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/hasher.go @@ -0,0 +1,101 @@ +package v1_2_0 + +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" +) + +const ( + MetaDataHashPrefix = "EVM2EVMMessageHashV2" +) + +type LeafHasher struct { + metaDataHash [32]byte + ctx hashutil.Hasher[[32]byte] + onRamp *evm_2_evm_onramp_1_2_0.EVM2EVMOnRamp +} + +func NewLeafHasher(sourceChainSelector uint64, destChainSelector uint64, onRampId common.Address, ctx hashutil.Hasher[[32]byte], onRamp *evm_2_evm_onramp_1_2_0.EVM2EVMOnRamp) *LeafHasher { + return &LeafHasher{ + metaDataHash: v1_0_0.GetMetaDataHash(ctx, ctx.Hash([]byte(MetaDataHashPrefix)), sourceChainSelector, onRampId, destChainSelector), + ctx: ctx, + onRamp: onRamp, + } +} + +func (t *LeafHasher) HashLeaf(log types.Log) ([32]byte, error) { + msg, err := t.onRamp.ParseCCIPSendRequested(log) + if err != nil { + return [32]byte{}, err + } + message := msg.Message + encodedTokens, err := abihelpers.ABIEncode( + `[ +{"components": [{"name":"token","type":"address"},{"name":"amount","type":"uint256"}], "type":"tuple[]"}]`, message.TokenAmounts) + if err != nil { + return [32]byte{}, err + } + + bytesArray, err := abi.NewType("bytes[]", "bytes[]", nil) + if err != nil { + return [32]byte{}, err + } + + encodedSourceTokenData, err := abi.Arguments{abi.Argument{Type: bytesArray}}.PackValues([]interface{}{message.SourceTokenData}) + if err != nil { + return [32]byte{}, err + } + + packedFixedSizeValues, err := abihelpers.ABIEncode( + `[ +{"name": "sender", "type":"address"}, +{"name": "receiver", "type":"address"}, +{"name": "sequenceNumber", "type":"uint64"}, +{"name": "gasLimit", "type":"uint256"}, +{"name": "strict", "type":"bool"}, +{"name": "nonce", "type":"uint64"}, +{"name": "feeToken","type": "address"}, +{"name": "feeTokenAmount","type": "uint256"} +]`, + message.Sender, + message.Receiver, + message.SequenceNumber, + message.GasLimit, + message.Strict, + message.Nonce, + message.FeeToken, + message.FeeTokenAmount, + ) + if err != nil { + return [32]byte{}, err + } + fixedSizeValuesHash := t.ctx.Hash(packedFixedSizeValues) + + packedValues, err := abihelpers.ABIEncode( + `[ +{"name": "leafDomainSeparator","type":"bytes1"}, +{"name": "metadataHash", "type":"bytes32"}, +{"name": "fixedSizeValuesHash", "type":"bytes32"}, +{"name": "dataHash", "type":"bytes32"}, +{"name": "tokenAmountsHash", "type":"bytes32"}, +{"name": "sourceTokenDataHash", "type":"bytes32"} +]`, + v1_0_0.LeafDomainSeparator, + t.metaDataHash, + fixedSizeValuesHash, + t.ctx.Hash(message.Data), + t.ctx.Hash(encodedTokens), + t.ctx.Hash(encodedSourceTokenData), + ) + if err != nil { + return [32]byte{}, err + } + return t.ctx.Hash(packedValues), nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/hasher_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/hasher_test.go new file mode 100644 index 0000000000..4bfbf7295e --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/hasher_test.go @@ -0,0 +1,78 @@ +package v1_2_0 + +import ( + "encoding/hex" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" +) + +func TestHasherV1_2_0(t *testing.T) { + sourceChainSelector, destChainSelector := uint64(1), uint64(4) + onRampAddress := common.HexToAddress("0x5550000000000000000000000000000000000001") + onRampABI := abihelpers.MustParseABI(evm_2_evm_onramp_1_2_0.EVM2EVMOnRampABI) + + hashingCtx := hashutil.NewKeccak() + ramp, err := evm_2_evm_onramp_1_2_0.NewEVM2EVMOnRamp(onRampAddress, nil) + require.NoError(t, err) + hasher := NewLeafHasher(sourceChainSelector, destChainSelector, onRampAddress, hashingCtx, ramp) + + message := evm_2_evm_onramp_1_2_0.InternalEVM2EVMMessage{ + SourceChainSelector: sourceChainSelector, + Sender: common.HexToAddress("0x1110000000000000000000000000000000000001"), + Receiver: common.HexToAddress("0x2220000000000000000000000000000000000001"), + SequenceNumber: 1337, + GasLimit: big.NewInt(100), + Strict: false, + Nonce: 1337, + FeeToken: common.Address{}, + FeeTokenAmount: big.NewInt(1), + Data: []byte{}, + TokenAmounts: []evm_2_evm_onramp_1_2_0.ClientEVMTokenAmount{{Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}}, + SourceTokenData: [][]byte{}, + MessageId: [32]byte{}, + } + + data, err := onRampABI.Events[CCIPSendRequestedEventName].Inputs.Pack(message) + require.NoError(t, err) + hash, err := hasher.HashLeaf(types.Log{Topics: []common.Hash{CCIPSendRequestEventSig}, Data: data}) + require.NoError(t, err) + + // NOTE: Must match spec + require.Equal(t, "46ad031bfb052db2e4a2514fed8dc480b98e5ce4acb55d5640d91407e0d8a3e9", hex.EncodeToString(hash[:])) + + message = evm_2_evm_onramp_1_2_0.InternalEVM2EVMMessage{ + SourceChainSelector: sourceChainSelector, + Sender: common.HexToAddress("0x1110000000000000000000000000000000000001"), + Receiver: common.HexToAddress("0x2220000000000000000000000000000000000001"), + SequenceNumber: 1337, + GasLimit: big.NewInt(100), + Strict: false, + Nonce: 1337, + FeeToken: common.Address{}, + FeeTokenAmount: big.NewInt(1e12), + Data: []byte("foo bar baz"), + TokenAmounts: []evm_2_evm_onramp_1_2_0.ClientEVMTokenAmount{ + {Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}, + {Token: common.HexToAddress("0x6660000000000000000000000000000000000001"), Amount: big.NewInt(4204242)}, + }, + SourceTokenData: [][]byte{{0x2, 0x1}}, + MessageId: [32]byte{}, + } + + data, err = onRampABI.Events[CCIPSendRequestedEventName].Inputs.Pack(message) + require.NoError(t, err) + hash, err = hasher.HashLeaf(types.Log{Topics: []common.Hash{CCIPSendRequestEventSig}, Data: data}) + require.NoError(t, err) + + // NOTE: Must match spec + require.Equal(t, "4362a13a42e52ff5ce4324e7184dc7aa41704c3146bc842d35d95b94b32a78b6", hex.EncodeToString(hash[:])) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp.go new file mode 100644 index 0000000000..fa00894b38 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp.go @@ -0,0 +1,340 @@ +package v1_2_0 + +import ( + "context" + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +var ( + abiOffRamp = abihelpers.MustParseABI(evm_2_evm_offramp_1_2_0.EVM2EVMOffRampABI) + _ ccipdata.OffRampReader = &OffRamp{} +) + +type ExecOnchainConfig evm_2_evm_offramp_1_2_0.EVM2EVMOffRampDynamicConfig + +func (d ExecOnchainConfig) AbiString() string { + return ` + [ + { + "components": [ + {"name": "permissionLessExecutionThresholdSeconds", "type": "uint32"}, + {"name": "router", "type": "address"}, + {"name": "priceRegistry", "type": "address"}, + {"name": "maxNumberOfTokensPerMsg", "type": "uint16"}, + {"name": "maxDataBytes", "type": "uint32"}, + {"name": "maxPoolReleaseOrMintGas", "type": "uint32"} + ], + "type": "tuple" + } + ]` +} + +func (d ExecOnchainConfig) Validate() error { + if d.PermissionLessExecutionThresholdSeconds == 0 { + return errors.New("must set PermissionLessExecutionThresholdSeconds") + } + if d.Router == (common.Address{}) { + return errors.New("must set Router address") + } + if d.PriceRegistry == (common.Address{}) { + return errors.New("must set PriceRegistry address") + } + if d.MaxNumberOfTokensPerMsg == 0 { + return errors.New("must set MaxNumberOfTokensPerMsg") + } + if d.MaxPoolReleaseOrMintGas == 0 { + return errors.New("must set MaxPoolReleaseOrMintGas") + } + return nil +} + +// JSONExecOffchainConfig is the configuration for nodes executing committed CCIP messages (v1.2). +// It comes from the OffchainConfig field of the corresponding OCR2 plugin configuration. +// NOTE: do not change the JSON format of this struct without consulting with the RDD people first. +type JSONExecOffchainConfig struct { + // SourceFinalityDepth indicates how many confirmations a transaction should get on the source chain event before we consider it finalized. + // + // Deprecated: we now use the source chain finality instead. + SourceFinalityDepth uint32 + // See [ccipdata.ExecOffchainConfig.DestOptimisticConfirmations] + DestOptimisticConfirmations uint32 + // DestFinalityDepth indicates how many confirmations a transaction should get on the destination chain event before we consider it finalized. + // + // Deprecated: we now use the destination chain finality instead. + DestFinalityDepth uint32 + // See [ccipdata.ExecOffchainConfig.BatchGasLimit] + BatchGasLimit uint32 + // See [ccipdata.ExecOffchainConfig.RelativeBoostPerWaitHour] + RelativeBoostPerWaitHour float64 + // See [ccipdata.ExecOffchainConfig.InflightCacheExpiry] + InflightCacheExpiry config.Duration + // See [ccipdata.ExecOffchainConfig.RootSnoozeTime] + RootSnoozeTime config.Duration + // See [ccipdata.ExecOffchainConfig.BatchingStrategyID] + BatchingStrategyID uint32 + // See [ccipdata.ExecOffchainConfig.MessageVisibilityInterval] + MessageVisibilityInterval config.Duration +} + +func (c JSONExecOffchainConfig) Validate() error { + if c.DestOptimisticConfirmations == 0 { + return errors.New("must set DestOptimisticConfirmations") + } + if c.BatchGasLimit == 0 { + return errors.New("must set BatchGasLimit") + } + if c.RelativeBoostPerWaitHour == 0 { + return errors.New("must set RelativeBoostPerWaitHour") + } + if c.InflightCacheExpiry.Duration() == 0 { + return errors.New("must set InflightCacheExpiry") + } + if c.RootSnoozeTime.Duration() == 0 { + return errors.New("must set RootSnoozeTime") + } + + return nil +} + +// OffRamp In 1.2 we have a different estimator impl +type OffRamp struct { + *v1_0_0.OffRamp + offRampV120 evm_2_evm_offramp_1_2_0.EVM2EVMOffRampInterface +} + +func (o *OffRamp) CurrentRateLimiterState(ctx context.Context) (cciptypes.TokenBucketRateLimit, error) { + bucket, err := o.offRampV120.CurrentRateLimiterState(&bind.CallOpts{Context: ctx}) + if err != nil { + return cciptypes.TokenBucketRateLimit{}, err + } + return cciptypes.TokenBucketRateLimit{ + Tokens: bucket.Tokens, + LastUpdated: bucket.LastUpdated, + IsEnabled: bucket.IsEnabled, + Capacity: bucket.Capacity, + Rate: bucket.Rate, + }, nil +} + +func (o *OffRamp) GetRouter(ctx context.Context) (cciptypes.Address, error) { + dynamicConfig, err := o.offRampV120.GetDynamicConfig(&bind.CallOpts{Context: ctx}) + if err != nil { + return "", err + } + return ccipcalc.EvmAddrToGeneric(dynamicConfig.Router), nil +} + +func (o *OffRamp) ChangeConfig(ctx context.Context, onchainConfigBytes []byte, offchainConfigBytes []byte) (cciptypes.Address, cciptypes.Address, error) { + // Same as the v1.0.0 method, except for the ExecOnchainConfig type. + onchainConfigParsed, err := abihelpers.DecodeAbiStruct[ExecOnchainConfig](onchainConfigBytes) + if err != nil { + return "", "", err + } + + offchainConfigParsed, err := ccipconfig.DecodeOffchainConfig[JSONExecOffchainConfig](offchainConfigBytes) + if err != nil { + return "", "", err + } + destRouter, err := router.NewRouter(onchainConfigParsed.Router, o.Client) + if err != nil { + return "", "", err + } + destWrappedNative, err := destRouter.GetWrappedNative(nil) + if err != nil { + return "", "", err + } + offchainConfig := cciptypes.ExecOffchainConfig{ + DestOptimisticConfirmations: offchainConfigParsed.DestOptimisticConfirmations, + BatchGasLimit: offchainConfigParsed.BatchGasLimit, + RelativeBoostPerWaitHour: offchainConfigParsed.RelativeBoostPerWaitHour, + InflightCacheExpiry: offchainConfigParsed.InflightCacheExpiry, + RootSnoozeTime: offchainConfigParsed.RootSnoozeTime, + MessageVisibilityInterval: offchainConfigParsed.MessageVisibilityInterval, + BatchingStrategyID: offchainConfigParsed.BatchingStrategyID, + } + onchainConfig := cciptypes.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: time.Second * time.Duration(onchainConfigParsed.PermissionLessExecutionThresholdSeconds), + Router: cciptypes.Address(onchainConfigParsed.Router.String()), + } + priceEstimator := prices.NewDAGasPriceEstimator(o.Estimator, o.DestMaxGasPrice, 0, 0) + + o.UpdateDynamicConfig(onchainConfig, offchainConfig, priceEstimator) + + o.Logger.Infow("Starting exec plugin", + "offchainConfig", onchainConfigParsed, + "onchainConfig", offchainConfigParsed) + return cciptypes.Address(onchainConfigParsed.PriceRegistry.String()), + cciptypes.Address(destWrappedNative.String()), nil +} + +func EncodeExecutionReport(ctx context.Context, args abi.Arguments, report cciptypes.ExecReport) ([]byte, error) { + var msgs []evm_2_evm_offramp_1_2_0.InternalEVM2EVMMessage + for _, msg := range report.Messages { + var ta []evm_2_evm_offramp_1_2_0.ClientEVMTokenAmount + for _, tokenAndAmount := range msg.TokenAmounts { + evmAddrs, err := ccipcalc.GenericAddrsToEvm(tokenAndAmount.Token) + if err != nil { + return nil, err + } + ta = append(ta, evm_2_evm_offramp_1_2_0.ClientEVMTokenAmount{ + Token: evmAddrs[0], + Amount: tokenAndAmount.Amount, + }) + } + + evmAddrs, err := ccipcalc.GenericAddrsToEvm(msg.Sender, msg.Receiver, msg.FeeToken) + if err != nil { + return nil, err + } + + msgs = append(msgs, evm_2_evm_offramp_1_2_0.InternalEVM2EVMMessage{ + SourceChainSelector: msg.SourceChainSelector, + Sender: evmAddrs[0], + Receiver: evmAddrs[1], + SequenceNumber: msg.SequenceNumber, + GasLimit: msg.GasLimit, + Strict: msg.Strict, + Nonce: msg.Nonce, + FeeToken: evmAddrs[2], + FeeTokenAmount: msg.FeeTokenAmount, + Data: msg.Data, + TokenAmounts: ta, + MessageId: msg.MessageID, + // NOTE: this field is new in v1.2. + SourceTokenData: msg.SourceTokenData, + }) + } + + rep := evm_2_evm_offramp_1_2_0.InternalExecutionReport{ + Messages: msgs, + OffchainTokenData: report.OffchainTokenData, + Proofs: report.Proofs, + ProofFlagBits: report.ProofFlagBits, + } + return args.PackValues([]interface{}{&rep}) +} + +func (o *OffRamp) EncodeExecutionReport(ctx context.Context, report cciptypes.ExecReport) ([]byte, error) { + return EncodeExecutionReport(ctx, o.ExecutionReportArgs, report) +} + +func DecodeExecReport(ctx context.Context, args abi.Arguments, report []byte) (cciptypes.ExecReport, error) { + unpacked, err := args.Unpack(report) + if err != nil { + return cciptypes.ExecReport{}, err + } + if len(unpacked) == 0 { + return cciptypes.ExecReport{}, errors.New("assumptionViolation: expected at least one element") + } + // Must be anonymous struct here + erStruct, ok := unpacked[0].(struct { + Messages []struct { + SourceChainSelector uint64 `json:"sourceChainSelector"` + Sender common.Address `json:"sender"` + Receiver common.Address `json:"receiver"` + SequenceNumber uint64 `json:"sequenceNumber"` + GasLimit *big.Int `json:"gasLimit"` + Strict bool `json:"strict"` + Nonce uint64 `json:"nonce"` + FeeToken common.Address `json:"feeToken"` + FeeTokenAmount *big.Int `json:"feeTokenAmount"` + Data []uint8 `json:"data"` + TokenAmounts []struct { + Token common.Address `json:"token"` + Amount *big.Int `json:"amount"` + } `json:"tokenAmounts"` + SourceTokenData [][]uint8 `json:"sourceTokenData"` + MessageId [32]uint8 `json:"messageId"` + } `json:"messages"` + OffchainTokenData [][][]uint8 `json:"offchainTokenData"` + Proofs [][32]uint8 `json:"proofs"` + ProofFlagBits *big.Int `json:"proofFlagBits"` + }) + if !ok { + return cciptypes.ExecReport{}, fmt.Errorf("got %T", unpacked[0]) + } + messages := make([]cciptypes.EVM2EVMMessage, 0, len(erStruct.Messages)) + for _, msg := range erStruct.Messages { + var tokensAndAmounts []cciptypes.TokenAmount + for _, tokenAndAmount := range msg.TokenAmounts { + tokensAndAmounts = append(tokensAndAmounts, cciptypes.TokenAmount{ + Token: cciptypes.Address(tokenAndAmount.Token.String()), + Amount: tokenAndAmount.Amount, + }) + } + messages = append(messages, cciptypes.EVM2EVMMessage{ + SequenceNumber: msg.SequenceNumber, + GasLimit: msg.GasLimit, + Nonce: msg.Nonce, + MessageID: msg.MessageId, + SourceChainSelector: msg.SourceChainSelector, + Sender: cciptypes.Address(msg.Sender.String()), + Receiver: cciptypes.Address(msg.Receiver.String()), + Strict: msg.Strict, + FeeToken: cciptypes.Address(msg.FeeToken.String()), + FeeTokenAmount: msg.FeeTokenAmount, + Data: msg.Data, + TokenAmounts: tokensAndAmounts, + SourceTokenData: msg.SourceTokenData, + // TODO: Not needed for plugins, but should be recomputed for consistency. + // Requires the offramp knowing about onramp version + Hash: [32]byte{}, + }) + } + + // Unpack will populate with big.Int{false, } for 0 values, + // which is different from the expected big.NewInt(0). Rebuild to the expected value for this case. + return cciptypes.ExecReport{ + Messages: messages, + OffchainTokenData: erStruct.OffchainTokenData, + Proofs: erStruct.Proofs, + ProofFlagBits: new(big.Int).SetBytes(erStruct.ProofFlagBits.Bytes()), + }, nil +} + +func (o *OffRamp) DecodeExecutionReport(ctx context.Context, report []byte) (cciptypes.ExecReport, error) { + return DecodeExecReport(ctx, o.ExecutionReportArgs, report) +} + +func NewOffRamp(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, destMaxGasPrice *big.Int) (*OffRamp, error) { + v100, err := v1_0_0.NewOffRamp(lggr, addr, ec, lp, estimator, destMaxGasPrice) + if err != nil { + return nil, err + } + + offRamp, err := evm_2_evm_offramp_1_2_0.NewEVM2EVMOffRamp(addr, ec) + if err != nil { + return nil, err + } + + v100.ExecutionReportArgs = abihelpers.MustGetMethodInputs("manuallyExecute", abiOffRamp)[:1] + + return &OffRamp{ + OffRamp: v100, + offRampV120: offRamp, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_test.go new file mode 100644 index 0000000000..f87fc8842f --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_test.go @@ -0,0 +1,38 @@ +package v1_2_0_test + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" +) + +func TestExecutionReportEncodingV120(t *testing.T) { + // Note could consider some fancier testing here (fuzz/property) + // but I think that would essentially be testing geth's abi library + // as our encode/decode is a thin wrapper around that. + report := cciptypes.ExecReport{ + Messages: []cciptypes.EVM2EVMMessage{}, + OffchainTokenData: [][][]byte{{}}, + Proofs: [][32]byte{testutils.Random32Byte()}, + ProofFlagBits: big.NewInt(133), + } + + offRamp, err := v1_2_0.NewOffRamp(logger.TestLogger(t), utils.RandomAddress(), nil, lpmocks.NewLogPoller(t), nil, nil) + require.NoError(t, err) + + ctx := testutils.Context(t) + encodeExecutionReport, err := offRamp.EncodeExecutionReport(ctx, report) + require.NoError(t, err) + decodeCommitReport, err := offRamp.DecodeExecutionReport(ctx, encodeExecutionReport) + require.NoError(t, err) + require.Equal(t, report.Proofs, decodeCommitReport.Proofs) + require.Equal(t, report, decodeCommitReport) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_unit_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_unit_test.go new file mode 100644 index 0000000000..98454ce59b --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_unit_test.go @@ -0,0 +1,36 @@ +package v1_2_0 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" + mock_contracts "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/mocks/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +func TestGetRouter(t *testing.T) { + routerAddr := utils.RandomAddress() + + mockOffRamp := mock_contracts.NewEVM2EVMOffRampInterface(t) + mockOffRamp.On("GetDynamicConfig", mock.Anything).Return(evm_2_evm_offramp_1_2_0.EVM2EVMOffRampDynamicConfig{ + Router: routerAddr, + }, nil) + + offRamp := OffRamp{ + offRampV120: mockOffRamp, + } + + ctx := testutils.Context(t) + gotRouterAddr, err := offRamp.GetRouter(ctx) + require.NoError(t, err) + + gotRouterEvmAddr, err := ccipcalc.GenericAddrToEvm(gotRouterAddr) + require.NoError(t, err) + assert.Equal(t, routerAddr, gotRouterEvmAddr) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_test.go new file mode 100644 index 0000000000..7d174d5db7 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_test.go @@ -0,0 +1,173 @@ +package v1_2_0 + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" +) + +func modifyCopy[T any](c T, f func(c *T)) T { + f(&c) + return c +} + +func TestExecOffchainConfig120_Encoding(t *testing.T) { + t.Parallel() + validConfig := JSONExecOffchainConfig{ + SourceFinalityDepth: 3, + DestOptimisticConfirmations: 6, + DestFinalityDepth: 3, + BatchGasLimit: 5_000_000, + RelativeBoostPerWaitHour: 0.07, + InflightCacheExpiry: *config.MustNewDuration(64 * time.Second), + RootSnoozeTime: *config.MustNewDuration(128 * time.Minute), + BatchingStrategyID: 0, + } + + tests := []struct { + name string + want JSONExecOffchainConfig + errPattern string + }{ + { + name: "legacy offchain config format parses", + want: validConfig, + }, + { + name: "can omit finality depth", + want: modifyCopy(validConfig, func(c *JSONExecOffchainConfig) { + c.SourceFinalityDepth = 0 + c.DestFinalityDepth = 0 + }), + }, + { + name: "must set BatchGasLimit", + want: modifyCopy(validConfig, func(c *JSONExecOffchainConfig) { + c.BatchGasLimit = 0 + }), + errPattern: "BatchGasLimit", + }, + { + name: "must set DestOptimisticConfirmations", + want: modifyCopy(validConfig, func(c *JSONExecOffchainConfig) { + c.DestOptimisticConfirmations = 0 + }), + errPattern: "DestOptimisticConfirmations", + }, + { + name: "must set RelativeBoostPerWaitHour", + want: modifyCopy(validConfig, func(c *JSONExecOffchainConfig) { + c.RelativeBoostPerWaitHour = 0 + }), + errPattern: "RelativeBoostPerWaitHour", + }, + { + name: "must set InflightCacheExpiry", + want: modifyCopy(validConfig, func(c *JSONExecOffchainConfig) { + c.InflightCacheExpiry = *config.MustNewDuration(0) + }), + errPattern: "InflightCacheExpiry", + }, + { + name: "must set RootSnoozeTime", + want: modifyCopy(validConfig, func(c *JSONExecOffchainConfig) { + c.RootSnoozeTime = *config.MustNewDuration(0) + }), + errPattern: "RootSnoozeTime", + }, + { + name: "must set BatchingStrategyId", + want: modifyCopy(validConfig, func(c *JSONExecOffchainConfig) { + c.BatchingStrategyID = 1 + }), + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + exp := tc.want + encode, err := ccipconfig.EncodeOffchainConfig(&exp) + require.NoError(t, err) + got, err := ccipconfig.DecodeOffchainConfig[JSONExecOffchainConfig](encode) + + if tc.errPattern != "" { + require.ErrorContains(t, err, tc.errPattern) + } else { + require.NoError(t, err) + require.Equal(t, tc.want, got) + } + }) + } +} + +func TestExecOffchainConfig120_ParseRawJson(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + config []byte + }{ + { + name: "with MaxGasPrice", + config: []byte(`{ + "DestOptimisticConfirmations": 6, + "BatchGasLimit": 5000000, + "RelativeBoostPerWaitHour": 0.07, + "MaxGasPrice": 200000000000, + "InflightCacheExpiry": "64s", + "RootSnoozeTime": "128m" + }`), + }, + { + name: "without MaxGasPrice", + config: []byte(`{ + "DestOptimisticConfirmations": 6, + "BatchGasLimit": 5000000, + "RelativeBoostPerWaitHour": 0.07, + "InflightCacheExpiry": "64s", + "RootSnoozeTime": "128m" + }`), + }, + { + name: "with BatchingStrategyId", + config: []byte(`{ + "DestOptimisticConfirmations": 6, + "BatchGasLimit": 5000000, + "RelativeBoostPerWaitHour": 0.07, + "InflightCacheExpiry": "64s", + "RootSnoozeTime": "128m", + "BatchingStrategyId": 1 + }`), + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + decoded, err := ccipconfig.DecodeOffchainConfig[JSONExecOffchainConfig](tc.config) + require.NoError(t, err) + + if tc.name == "with BatchingStrategyId" { + require.Equal(t, JSONExecOffchainConfig{ + DestOptimisticConfirmations: 6, + BatchGasLimit: 5_000_000, + RelativeBoostPerWaitHour: 0.07, + InflightCacheExpiry: *config.MustNewDuration(64 * time.Second), + RootSnoozeTime: *config.MustNewDuration(128 * time.Minute), + BatchingStrategyID: 1, // Actual value + }, decoded) + } else { + require.Equal(t, JSONExecOffchainConfig{ + DestOptimisticConfirmations: 6, + BatchGasLimit: 5_000_000, + RelativeBoostPerWaitHour: 0.07, + InflightCacheExpiry: *config.MustNewDuration(64 * time.Second), + RootSnoozeTime: *config.MustNewDuration(128 * time.Minute), + BatchingStrategyID: 0, // Default + }, decoded) + } + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go new file mode 100644 index 0000000000..f727d7fd5f --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go @@ -0,0 +1,255 @@ +package v1_2_0 + +import ( + "context" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" +) + +var ( + // Backwards compat for integration tests + CCIPSendRequestEventSig common.Hash + ConfigSetEventSig common.Hash +) + +const ( + CCIPSendRequestSeqNumIndex = 4 + CCIPSendRequestedEventName = "CCIPSendRequested" + ConfigSetEventName = "ConfigSet" +) + +func init() { + onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp_1_2_0.EVM2EVMOnRampABI)) + if err != nil { + panic(err) + } + CCIPSendRequestEventSig = abihelpers.MustGetEventID(CCIPSendRequestedEventName, onRampABI) + ConfigSetEventSig = abihelpers.MustGetEventID(ConfigSetEventName, onRampABI) +} + +var _ ccipdata.OnRampReader = &OnRamp{} + +// Significant change in 1.2: +// - CCIPSendRequested event signature has changed +type OnRamp struct { + onRamp *evm_2_evm_onramp_1_2_0.EVM2EVMOnRamp + address common.Address + lggr logger.Logger + lp logpoller.LogPoller + leafHasher ccipdata.LeafHasherInterface[[32]byte] + client client.Client + sendRequestedEventSig common.Hash + sendRequestedSeqNumberWord int + filters []logpoller.Filter + cachedSourcePriceRegistryAddress cache.AutoSync[cciptypes.Address] + // Static config can be cached, because it's never expected to change. + // The only way to change that is through the contract's constructor (redeployment) + cachedStaticConfig cache.OnceCtxFunction[evm_2_evm_onramp_1_2_0.EVM2EVMOnRampStaticConfig] + cachedRmnContract cache.OnceCtxFunction[*arm_contract.ARMContract] +} + +func NewOnRamp(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAddress common.Address, sourceLP logpoller.LogPoller, source client.Client) (*OnRamp, error) { + onRamp, err := evm_2_evm_onramp_1_2_0.NewEVM2EVMOnRamp(onRampAddress, source) + if err != nil { + return nil, err + } + // Subscribe to the relevant logs + // Note we can keep the same prefix across 1.0/1.1 and 1.2 because the onramp addresses will be different + filters := []logpoller.Filter{ + { + Name: logpoller.FilterName(ccipdata.COMMIT_CCIP_SENDS, onRampAddress), + EventSigs: []common.Hash{CCIPSendRequestEventSig}, + Addresses: []common.Address{onRampAddress}, + Retention: ccipdata.CommitExecLogsRetention, + }, + { + Name: logpoller.FilterName(ccipdata.CONFIG_CHANGED, onRampAddress), + EventSigs: []common.Hash{ConfigSetEventSig}, + Addresses: []common.Address{onRampAddress}, + Retention: ccipdata.CacheEvictionLogsRetention, + }, + } + cachedStaticConfig := cache.OnceCtxFunction[evm_2_evm_onramp_1_2_0.EVM2EVMOnRampStaticConfig](func(ctx context.Context) (evm_2_evm_onramp_1_2_0.EVM2EVMOnRampStaticConfig, error) { + return onRamp.GetStaticConfig(&bind.CallOpts{Context: ctx}) + }) + cachedRmnContract := cache.OnceCtxFunction[*arm_contract.ARMContract](func(ctx context.Context) (*arm_contract.ARMContract, error) { + staticConfig, err := cachedStaticConfig(ctx) + if err != nil { + return nil, err + } + + return arm_contract.NewARMContract(staticConfig.ArmProxy, source) + }) + return &OnRamp{ + lggr: lggr, + client: source, + lp: sourceLP, + leafHasher: NewLeafHasher(sourceSelector, destSelector, onRampAddress, hashutil.NewKeccak(), onRamp), + onRamp: onRamp, + filters: filters, + address: onRampAddress, + sendRequestedSeqNumberWord: CCIPSendRequestSeqNumIndex, + sendRequestedEventSig: CCIPSendRequestEventSig, + cachedSourcePriceRegistryAddress: cache.NewLogpollerEventsBased[cciptypes.Address]( + sourceLP, + []common.Hash{ConfigSetEventSig}, + onRampAddress, + ), + cachedStaticConfig: cache.CallOnceOnNoError(cachedStaticConfig), + cachedRmnContract: cache.CallOnceOnNoError(cachedRmnContract), + }, nil +} + +func (o *OnRamp) Address(context.Context) (cciptypes.Address, error) { + return cciptypes.Address(o.onRamp.Address().String()), nil +} + +func (o *OnRamp) GetDynamicConfig(context.Context) (cciptypes.OnRampDynamicConfig, error) { + if o.onRamp == nil { + return cciptypes.OnRampDynamicConfig{}, fmt.Errorf("onramp not initialized") + } + config, err := o.onRamp.GetDynamicConfig(&bind.CallOpts{}) + if err != nil { + return cciptypes.OnRampDynamicConfig{}, fmt.Errorf("get dynamic config v1.2: %w", err) + } + return cciptypes.OnRampDynamicConfig{ + Router: cciptypes.Address(config.Router.String()), + MaxNumberOfTokensPerMsg: config.MaxNumberOfTokensPerMsg, + DestGasOverhead: config.DestGasOverhead, + DestGasPerPayloadByte: config.DestGasPerPayloadByte, + DestDataAvailabilityOverheadGas: config.DestDataAvailabilityOverheadGas, + DestGasPerDataAvailabilityByte: config.DestGasPerDataAvailabilityByte, + DestDataAvailabilityMultiplierBps: config.DestDataAvailabilityMultiplierBps, + PriceRegistry: cciptypes.Address(config.PriceRegistry.String()), + MaxDataBytes: config.MaxDataBytes, + MaxPerMsgGasLimit: config.MaxPerMsgGasLimit, + }, nil +} + +func (o *OnRamp) SourcePriceRegistryAddress(ctx context.Context) (cciptypes.Address, error) { + return o.cachedSourcePriceRegistryAddress.Get(ctx, func(ctx context.Context) (cciptypes.Address, error) { + c, err := o.GetDynamicConfig(ctx) + if err != nil { + return "", err + } + return c.PriceRegistry, nil + }) +} + +func (o *OnRamp) GetSendRequestsBetweenSeqNums(ctx context.Context, seqNumMin, seqNumMax uint64, finalized bool) ([]cciptypes.EVM2EVMMessageWithTxMeta, error) { + logs, err := o.lp.LogsDataWordRange( + ctx, + o.sendRequestedEventSig, + o.address, + o.sendRequestedSeqNumberWord, + logpoller.EvmWord(seqNumMin), + logpoller.EvmWord(seqNumMax), + ccipdata.LogsConfirmations(finalized), + ) + if err != nil { + return nil, err + } + + parsedLogs, err := ccipdata.ParseLogs[cciptypes.EVM2EVMMessage](logs, o.lggr, o.logToMessage) + if err != nil { + return nil, err + } + + res := make([]cciptypes.EVM2EVMMessageWithTxMeta, 0, len(logs)) + for _, log := range parsedLogs { + res = append(res, cciptypes.EVM2EVMMessageWithTxMeta{ + TxMeta: log.TxMeta, + EVM2EVMMessage: log.Data, + }) + } + + return res, nil +} + +func (o *OnRamp) RouterAddress(context.Context) (cciptypes.Address, error) { + config, err := o.onRamp.GetDynamicConfig(nil) + if err != nil { + return "", err + } + return cciptypes.Address(config.Router.String()), nil +} + +func (o *OnRamp) IsSourceChainHealthy(context.Context) (bool, error) { + if err := o.lp.Healthy(); err != nil { + return false, nil + } + return true, nil +} + +func (o *OnRamp) IsSourceCursed(ctx context.Context) (bool, error) { + arm, err := o.cachedRmnContract(ctx) + if err != nil { + return false, fmt.Errorf("intializing Arm contract through the ArmProxy: %w", err) + } + + cursed, err := arm.IsCursed0(&bind.CallOpts{Context: ctx}) + if err != nil { + return false, fmt.Errorf("checking if source Arm is cursed: %w", err) + } + return cursed, nil +} + +func (o *OnRamp) Close() error { + return logpollerutil.UnregisterLpFilters(o.lp, o.filters) +} + +func (o *OnRamp) RegisterFilters() error { + return logpollerutil.RegisterLpFilters(o.lp, o.filters) +} + +func (o *OnRamp) logToMessage(log types.Log) (*cciptypes.EVM2EVMMessage, error) { + msg, err := o.onRamp.ParseCCIPSendRequested(log) + if err != nil { + return nil, err + } + h, err := o.leafHasher.HashLeaf(log) + if err != nil { + return nil, err + } + tokensAndAmounts := make([]cciptypes.TokenAmount, len(msg.Message.TokenAmounts)) + for i, tokenAndAmount := range msg.Message.TokenAmounts { + tokensAndAmounts[i] = cciptypes.TokenAmount{ + Token: cciptypes.Address(tokenAndAmount.Token.String()), + Amount: tokenAndAmount.Amount, + } + } + + return &cciptypes.EVM2EVMMessage{ + SequenceNumber: msg.Message.SequenceNumber, + GasLimit: msg.Message.GasLimit, + Nonce: msg.Message.Nonce, + MessageID: msg.Message.MessageId, + SourceChainSelector: msg.Message.SourceChainSelector, + Sender: cciptypes.Address(msg.Message.Sender.String()), + Receiver: cciptypes.Address(msg.Message.Receiver.String()), + Strict: msg.Message.Strict, + FeeToken: cciptypes.Address(msg.Message.FeeToken.String()), + FeeTokenAmount: msg.Message.FeeTokenAmount, + Data: msg.Message.Data, + TokenAmounts: tokensAndAmounts, + SourceTokenData: msg.Message.SourceTokenData, // Breaking change 1.2 + Hash: h, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp_test.go new file mode 100644 index 0000000000..ec912667ac --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp_test.go @@ -0,0 +1,57 @@ +package v1_2_0 + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" +) + +func TestLogPollerClient_GetSendRequestsBetweenSeqNumsV1_2_0(t *testing.T) { + onRampAddr := utils.RandomAddress() + seqNum := uint64(100) + limit := uint64(10) + lggr := logger.TestLogger(t) + + tests := []struct { + name string + finalized bool + confirmations evmtypes.Confirmations + }{ + {"finalized", true, evmtypes.Finalized}, + {"unfinalized", false, evmtypes.Confirmations(0)}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + lp := mocks.NewLogPoller(t) + onRampV2, err := NewOnRamp(lggr, 1, 1, onRampAddr, lp, nil) + require.NoError(t, err) + + lp.On("LogsDataWordRange", + mock.Anything, + onRampV2.sendRequestedEventSig, + onRampAddr, + onRampV2.sendRequestedSeqNumberWord, + abihelpers.EvmWord(seqNum), + abihelpers.EvmWord(seqNum+limit), + tt.confirmations, + ).Once().Return([]logpoller.Log{}, nil) + + events, err1 := onRampV2.GetSendRequestsBetweenSeqNums(context.Background(), seqNum, seqNum+limit, tt.finalized) + assert.NoError(t, err1) + assert.Empty(t, events) + + lp.AssertExpectations(t) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/price_registry.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/price_registry.go new file mode 100644 index 0000000000..9aac30e612 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/price_registry.go @@ -0,0 +1,68 @@ +package v1_2_0 + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" +) + +var ( + _ ccipdata.PriceRegistryReader = &PriceRegistry{} +) + +type PriceRegistry struct { + *v1_0_0.PriceRegistry + pr *price_registry_1_2_0.PriceRegistry +} + +func NewPriceRegistry(lggr logger.Logger, priceRegistryAddr common.Address, lp logpoller.LogPoller, ec client.Client, registerFilters bool) (*PriceRegistry, error) { + v100, err := v1_0_0.NewPriceRegistry(lggr, priceRegistryAddr, lp, ec, registerFilters) + if err != nil { + return nil, err + } + priceRegistry, err := price_registry_1_2_0.NewPriceRegistry(priceRegistryAddr, ec) + if err != nil { + return nil, err + } + return &PriceRegistry{ + PriceRegistry: v100, + pr: priceRegistry, + }, nil +} + +// GetTokenPrices must be overridden to use the 1.2 ABI (return parameter changed from uint192 to uint224) +// See https://github.com/smartcontractkit/ccip/blob/ccip-develop/contracts/src/v0.8/ccip/PriceRegistry.sol#L141 +func (p *PriceRegistry) GetTokenPrices(ctx context.Context, wantedTokens []cciptypes.Address) ([]cciptypes.TokenPriceUpdate, error) { + evmAddrs, err := ccipcalc.GenericAddrsToEvm(wantedTokens...) + if err != nil { + return nil, err + } + + // Make call using 224 ABI. + tps, err := p.pr.GetTokenPrices(&bind.CallOpts{Context: ctx}, evmAddrs) + if err != nil { + return nil, err + } + var tpu []cciptypes.TokenPriceUpdate + for i, tp := range tps { + tpu = append(tpu, cciptypes.TokenPriceUpdate{ + TokenPrice: cciptypes.TokenPrice{ + Token: wantedTokens[i], + Value: tp.Value, + }, + TimestampUnixSec: big.NewInt(int64(tp.Timestamp)), + }) + } + return tpu, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/test_helpers.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/test_helpers.go new file mode 100644 index 0000000000..e7972d5f5f --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/test_helpers.go @@ -0,0 +1,48 @@ +package v1_2_0 + +import ( + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +// ApplyPriceRegistryUpdate is a helper function used in tests only. +func ApplyPriceRegistryUpdate(t *testing.T, user *bind.TransactOpts, addr common.Address, ec client.Client, gasPrices []cciptypes.GasPrice, tokenPrices []cciptypes.TokenPrice) common.Hash { + require.True(t, len(gasPrices) <= 2) + pr, err := price_registry.NewPriceRegistry(addr, ec) + require.NoError(t, err) + o, err := pr.Owner(nil) + require.NoError(t, err) + require.Equal(t, user.From, o) + var tps []price_registry.InternalTokenPriceUpdate + for _, tp := range tokenPrices { + evmAddrs, err1 := ccipcalc.GenericAddrsToEvm(tp.Token) + assert.NoError(t, err1) + tps = append(tps, price_registry.InternalTokenPriceUpdate{ + SourceToken: evmAddrs[0], + UsdPerToken: tp.Value, + }) + } + var gps []price_registry.InternalGasPriceUpdate + for _, gp := range gasPrices { + gps = append(gps, price_registry.InternalGasPriceUpdate{ + DestChainSelector: gp.DestChainSelector, + UsdPerUnitGas: gp.Value, + }) + } + tx, err := pr.UpdatePrices(user, price_registry.InternalPriceUpdates{ + TokenPriceUpdates: tps, + GasPriceUpdates: gps, + }) + require.NoError(t, err) + return tx.Hash() +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/token_pool.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/token_pool.go new file mode 100644 index 0000000000..a0850ebb2e --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/token_pool.go @@ -0,0 +1,48 @@ +package v1_2_0 + +import ( + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +var ( + poolABI = abihelpers.MustParseABI(burn_mint_token_pool_1_2_0.BurnMintTokenPoolABI) +) + +var _ ccipdata.TokenPoolReader = &TokenPool{} + +type TokenPool struct { + addr common.Address + OffRampAddress common.Address + poolType string +} + +func NewTokenPool(poolType string, addr common.Address, offRampAddress common.Address) *TokenPool { + return &TokenPool{ + addr: addr, + OffRampAddress: offRampAddress, + poolType: poolType, + } +} + +func (p *TokenPool) Address() common.Address { + return p.addr +} + +func (p *TokenPool) Type() string { + return p.poolType +} + +func GetInboundTokenPoolRateLimitCall(tokenPoolAddress common.Address, offRampAddress common.Address) rpclib.EvmCall { + return rpclib.NewEvmCall( + poolABI, + "currentOffRampRateLimiterState", + tokenPoolAddress, + offRampAddress, + ) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/token_pool_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/token_pool_test.go new file mode 100644 index 0000000000..3308ab05ce --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/token_pool_test.go @@ -0,0 +1,24 @@ +package v1_2_0 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" +) + +func TestTokenPool(t *testing.T) { + addr := utils.RandomAddress() + offRamp := utils.RandomAddress() + poolType := "BurnMint" + + tokenPool := NewTokenPool(poolType, addr, offRamp) + + assert.Equal(t, addr, tokenPool.Address()) + assert.Equal(t, poolType, tokenPool.Type()) + + inboundRateLimitCall := GetInboundTokenPoolRateLimitCall(addr, offRamp) + + assert.Equal(t, "currentOffRampRateLimiterState", inboundRateLimitCall.MethodName()) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_4_0/token_pool.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_4_0/token_pool.go new file mode 100644 index 0000000000..caf652b9e4 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_4_0/token_pool.go @@ -0,0 +1,48 @@ +package v1_4_0 + +import ( + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_4_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +var ( + poolABI = abihelpers.MustParseABI(burn_mint_token_pool_1_4_0.BurnMintTokenPoolABI) +) + +var _ ccipdata.TokenPoolReader = &TokenPool{} + +type TokenPool struct { + addr common.Address + RemoteChainSelector uint64 + poolType string +} + +func NewTokenPool(poolType string, addr common.Address, remoteChainSelector uint64) *TokenPool { + return &TokenPool{ + addr: addr, + RemoteChainSelector: remoteChainSelector, + poolType: poolType, + } +} + +func (p *TokenPool) Address() common.Address { + return p.addr +} + +func (p *TokenPool) Type() string { + return p.poolType +} + +func GetInboundTokenPoolRateLimitCall(tokenPoolAddress common.Address, remoteChainSelector uint64) rpclib.EvmCall { + return rpclib.NewEvmCall( + poolABI, + "getCurrentInboundRateLimiterState", + tokenPoolAddress, + remoteChainSelector, + ) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_4_0/token_pool_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_4_0/token_pool_test.go new file mode 100644 index 0000000000..8aaddc3312 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_4_0/token_pool_test.go @@ -0,0 +1,24 @@ +package v1_4_0 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" +) + +func TestTokenPool(t *testing.T) { + addr := utils.RandomAddress() + chainSelector := uint64(2000) + poolType := "BurnMint" + + tokenPool := NewTokenPool(poolType, addr, chainSelector) + + assert.Equal(t, addr, tokenPool.Address()) + assert.Equal(t, poolType, tokenPool.Type()) + + inboundRateLimitCall := GetInboundTokenPoolRateLimitCall(addr, chainSelector) + + assert.Equal(t, "getCurrentInboundRateLimiterState", inboundRateLimitCall.MethodName()) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/commit_store.go new file mode 100644 index 0000000000..3bb582f3a2 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/commit_store.go @@ -0,0 +1,59 @@ +package v1_5_0 + +import ( + "context" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" +) + +type CommitStore struct { + *v1_2_0.CommitStore + commitStore *commit_store.CommitStore +} + +func (c *CommitStore) GetCommitStoreStaticConfig(ctx context.Context) (cciptypes.CommitStoreStaticConfig, error) { + staticConfig, err := c.commitStore.GetStaticConfig(&bind.CallOpts{Context: ctx}) + if err != nil { + return cciptypes.CommitStoreStaticConfig{}, err + } + return cciptypes.CommitStoreStaticConfig{ + ChainSelector: staticConfig.ChainSelector, + SourceChainSelector: staticConfig.SourceChainSelector, + OnRamp: cciptypes.Address(staticConfig.OnRamp.String()), + ArmProxy: cciptypes.Address(staticConfig.RmnProxy.String()), + }, nil +} + +func (c *CommitStore) IsDown(ctx context.Context) (bool, error) { + unPausedAndNotCursed, err := c.commitStore.IsUnpausedAndNotCursed(&bind.CallOpts{Context: ctx}) + if err != nil { + return true, err + } + return !unPausedAndNotCursed, nil +} + +func NewCommitStore(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller) (*CommitStore, error) { + v120, err := v1_2_0.NewCommitStore(lggr, addr, ec, lp) + if err != nil { + return nil, err + } + + commitStore, err := commit_store.NewCommitStore(addr, ec) + if err != nil { + return nil, err + } + + return &CommitStore{ + commitStore: commitStore, + CommitStore: v120, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/hasher.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/hasher.go new file mode 100644 index 0000000000..a00ec376cd --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/hasher.go @@ -0,0 +1,101 @@ +package v1_5_0 + +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" +) + +const ( + MetaDataHashPrefix = "EVM2EVMMessageHashV2" +) + +type LeafHasher struct { + metaDataHash [32]byte + ctx hashutil.Hasher[[32]byte] + onRamp *evm_2_evm_onramp.EVM2EVMOnRamp +} + +func NewLeafHasher(sourceChainSelector uint64, destChainSelector uint64, onRampId common.Address, ctx hashutil.Hasher[[32]byte], onRamp *evm_2_evm_onramp.EVM2EVMOnRamp) *LeafHasher { + return &LeafHasher{ + metaDataHash: v1_0_0.GetMetaDataHash(ctx, ctx.Hash([]byte(MetaDataHashPrefix)), sourceChainSelector, onRampId, destChainSelector), + ctx: ctx, + onRamp: onRamp, + } +} + +func (t *LeafHasher) HashLeaf(log types.Log) ([32]byte, error) { + msg, err := t.onRamp.ParseCCIPSendRequested(log) + if err != nil { + return [32]byte{}, err + } + message := msg.Message + encodedTokens, err := abihelpers.ABIEncode( + `[ +{"components": [{"name":"token","type":"address"},{"name":"amount","type":"uint256"}], "type":"tuple[]"}]`, message.TokenAmounts) + if err != nil { + return [32]byte{}, err + } + + bytesArray, err := abi.NewType("bytes[]", "bytes[]", nil) + if err != nil { + return [32]byte{}, err + } + + encodedSourceTokenData, err := abi.Arguments{abi.Argument{Type: bytesArray}}.PackValues([]interface{}{message.SourceTokenData}) + if err != nil { + return [32]byte{}, err + } + + packedFixedSizeValues, err := abihelpers.ABIEncode( + `[ +{"name": "sender", "type":"address"}, +{"name": "receiver", "type":"address"}, +{"name": "sequenceNumber", "type":"uint64"}, +{"name": "gasLimit", "type":"uint256"}, +{"name": "strict", "type":"bool"}, +{"name": "nonce", "type":"uint64"}, +{"name": "feeToken","type": "address"}, +{"name": "feeTokenAmount","type": "uint256"} +]`, + message.Sender, + message.Receiver, + message.SequenceNumber, + message.GasLimit, + message.Strict, + message.Nonce, + message.FeeToken, + message.FeeTokenAmount, + ) + if err != nil { + return [32]byte{}, err + } + fixedSizeValuesHash := t.ctx.Hash(packedFixedSizeValues) + + packedValues, err := abihelpers.ABIEncode( + `[ +{"name": "leafDomainSeparator","type":"bytes1"}, +{"name": "metadataHash", "type":"bytes32"}, +{"name": "fixedSizeValuesHash", "type":"bytes32"}, +{"name": "dataHash", "type":"bytes32"}, +{"name": "tokenAmountsHash", "type":"bytes32"}, +{"name": "sourceTokenDataHash", "type":"bytes32"} +]`, + v1_0_0.LeafDomainSeparator, + t.metaDataHash, + fixedSizeValuesHash, + t.ctx.Hash(message.Data), + t.ctx.Hash(encodedTokens), + t.ctx.Hash(encodedSourceTokenData), + ) + if err != nil { + return [32]byte{}, err + } + return t.ctx.Hash(packedValues), nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/hasher_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/hasher_test.go new file mode 100644 index 0000000000..2a585f7bd1 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/hasher_test.go @@ -0,0 +1,78 @@ +package v1_5_0 + +import ( + "encoding/hex" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" +) + +func TestHasherV1_4_0(t *testing.T) { + sourceChainSelector, destChainSelector := uint64(1), uint64(4) + onRampAddress := common.HexToAddress("0x5550000000000000000000000000000000000001") + onRampABI := abihelpers.MustParseABI(evm_2_evm_onramp.EVM2EVMOnRampABI) + + hashingCtx := hashutil.NewKeccak() + ramp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, nil) + require.NoError(t, err) + hasher := NewLeafHasher(sourceChainSelector, destChainSelector, onRampAddress, hashingCtx, ramp) + + message := evm_2_evm_onramp.InternalEVM2EVMMessage{ + SourceChainSelector: sourceChainSelector, + Sender: common.HexToAddress("0x1110000000000000000000000000000000000001"), + Receiver: common.HexToAddress("0x2220000000000000000000000000000000000001"), + SequenceNumber: 1337, + GasLimit: big.NewInt(100), + Strict: false, + Nonce: 1337, + FeeToken: common.Address{}, + FeeTokenAmount: big.NewInt(1), + Data: []byte{}, + TokenAmounts: []evm_2_evm_onramp.ClientEVMTokenAmount{{Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}}, + SourceTokenData: [][]byte{}, + MessageId: [32]byte{}, + } + + data, err := onRampABI.Events[CCIPSendRequestedEventName].Inputs.Pack(message) + require.NoError(t, err) + hash, err := hasher.HashLeaf(types.Log{Topics: []common.Hash{CCIPSendRequestEventSig}, Data: data}) + require.NoError(t, err) + + // NOTE: Must match spec + require.Equal(t, "46ad031bfb052db2e4a2514fed8dc480b98e5ce4acb55d5640d91407e0d8a3e9", hex.EncodeToString(hash[:])) + + message = evm_2_evm_onramp.InternalEVM2EVMMessage{ + SourceChainSelector: sourceChainSelector, + Sender: common.HexToAddress("0x1110000000000000000000000000000000000001"), + Receiver: common.HexToAddress("0x2220000000000000000000000000000000000001"), + SequenceNumber: 1337, + GasLimit: big.NewInt(100), + Strict: false, + Nonce: 1337, + FeeToken: common.Address{}, + FeeTokenAmount: big.NewInt(1e12), + Data: []byte("foo bar baz"), + TokenAmounts: []evm_2_evm_onramp.ClientEVMTokenAmount{ + {Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}, + {Token: common.HexToAddress("0x6660000000000000000000000000000000000001"), Amount: big.NewInt(4204242)}, + }, + SourceTokenData: [][]byte{{0x2, 0x1}}, + MessageId: [32]byte{}, + } + + data, err = onRampABI.Events[CCIPSendRequestedEventName].Inputs.Pack(message) + require.NoError(t, err) + hash, err = hasher.HashLeaf(types.Log{Topics: []common.Hash{CCIPSendRequestEventSig}, Data: data}) + require.NoError(t, err) + + // NOTE: Must match spec + require.Equal(t, "4362a13a42e52ff5ce4324e7184dc7aa41704c3146bc842d35d95b94b32a78b6", hex.EncodeToString(hash[:])) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp.go new file mode 100644 index 0000000000..cac61c6787 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp.go @@ -0,0 +1,199 @@ +package v1_5_0 + +import ( + "context" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +var ( + abiOffRamp = abihelpers.MustParseABI(evm_2_evm_offramp.EVM2EVMOffRampABI) + _ ccipdata.OffRampReader = &OffRamp{} + RateLimitTokenAddedEvent = abihelpers.MustGetEventID("TokenAggregateRateLimitAdded", abiOffRamp) + RateLimitTokenRemovedEvent = abihelpers.MustGetEventID("TokenAggregateRateLimitRemoved", abiOffRamp) +) + +type ExecOnchainConfig evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig + +func (d ExecOnchainConfig) AbiString() string { + return ` + [ + { + "components": [ + {"name": "permissionLessExecutionThresholdSeconds", "type": "uint32"}, + {"name": "maxDataBytes", "type": "uint32"}, + {"name": "maxNumberOfTokensPerMsg", "type": "uint16"}, + {"name": "router", "type": "address"}, + {"name": "priceRegistry", "type": "address"}, + {"name": "maxPoolReleaseOrMintGas", "type": "uint32"}, + {"name": "maxTokenTransferGas", "type": "uint32"} + ], + "type": "tuple" + } + ]` +} + +func (d ExecOnchainConfig) Validate() error { + if d.PermissionLessExecutionThresholdSeconds == 0 { + return errors.New("must set PermissionLessExecutionThresholdSeconds") + } + if d.Router == (common.Address{}) { + return errors.New("must set Router address") + } + if d.PriceRegistry == (common.Address{}) { + return errors.New("must set PriceRegistry address") + } + if d.MaxNumberOfTokensPerMsg == 0 { + return errors.New("must set MaxNumberOfTokensPerMsg") + } + if d.MaxPoolReleaseOrMintGas == 0 { + return errors.New("must set MaxPoolReleaseOrMintGas") + } + if d.MaxTokenTransferGas == 0 { + return errors.New("must set MaxTokenTransferGas") + } + return nil +} + +type OffRamp struct { + *v1_2_0.OffRamp + offRampV150 evm_2_evm_offramp.EVM2EVMOffRampInterface + cachedRateLimitTokens cache.AutoSync[cciptypes.OffRampTokens] +} + +// GetTokens Returns no data as the offRamps no longer have this information. +func (o *OffRamp) GetTokens(ctx context.Context) (cciptypes.OffRampTokens, error) { + sourceTokens, destTokens, err := o.GetSourceAndDestRateLimitTokens(ctx) + if err != nil { + return cciptypes.OffRampTokens{}, err + } + return cciptypes.OffRampTokens{ + SourceTokens: sourceTokens, + DestinationTokens: destTokens, + }, nil +} + +func (o *OffRamp) GetSourceAndDestRateLimitTokens(ctx context.Context) (sourceTokens []cciptypes.Address, destTokens []cciptypes.Address, err error) { + cachedTokens, err := o.cachedRateLimitTokens.Get(ctx, func(ctx context.Context) (cciptypes.OffRampTokens, error) { + tokens, err2 := o.offRampV150.GetAllRateLimitTokens(&bind.CallOpts{Context: ctx}) + if err2 != nil { + return cciptypes.OffRampTokens{}, err2 + } + + if len(tokens.SourceTokens) != len(tokens.DestTokens) { + return cciptypes.OffRampTokens{}, errors.New("source and destination tokens are not the same length") + } + + return cciptypes.OffRampTokens{ + DestinationTokens: ccipcalc.EvmAddrsToGeneric(tokens.DestTokens...), + SourceTokens: ccipcalc.EvmAddrsToGeneric(tokens.SourceTokens...), + }, nil + }) + if err != nil { + return nil, nil, errors.Wrap(err, "failed to get rate limit tokens, if token set is large (~400k) batching may be needed") + } + return cachedTokens.SourceTokens, cachedTokens.DestinationTokens, nil +} + +func (o *OffRamp) GetSourceToDestTokensMapping(ctx context.Context) (map[cciptypes.Address]cciptypes.Address, error) { + sourceTokens, destTokens, err := o.GetSourceAndDestRateLimitTokens(ctx) + if err != nil { + return nil, errors.Wrap(err, "failed to get rate limit tokens, if token set is large (~400k) batching may be needed") + } + + if sourceTokens == nil || destTokens == nil { + return nil, errors.New("source or destination tokens are nil") + } + + mapping := make(map[cciptypes.Address]cciptypes.Address) + for i, sourceToken := range sourceTokens { + mapping[sourceToken] = destTokens[i] + } + return mapping, nil +} + +func (o *OffRamp) ChangeConfig(ctx context.Context, onchainConfigBytes []byte, offchainConfigBytes []byte) (cciptypes.Address, cciptypes.Address, error) { + // Same as the v1.2.0 method, except for the ExecOnchainConfig type. + onchainConfigParsed, err := abihelpers.DecodeAbiStruct[ExecOnchainConfig](onchainConfigBytes) + if err != nil { + return "", "", err + } + + offchainConfigParsed, err := ccipconfig.DecodeOffchainConfig[v1_2_0.JSONExecOffchainConfig](offchainConfigBytes) + if err != nil { + return "", "", err + } + destRouter, err := router.NewRouter(onchainConfigParsed.Router, o.Client) + if err != nil { + return "", "", err + } + destWrappedNative, err := destRouter.GetWrappedNative(nil) + if err != nil { + return "", "", err + } + offchainConfig := cciptypes.ExecOffchainConfig{ + DestOptimisticConfirmations: offchainConfigParsed.DestOptimisticConfirmations, + BatchGasLimit: offchainConfigParsed.BatchGasLimit, + RelativeBoostPerWaitHour: offchainConfigParsed.RelativeBoostPerWaitHour, + InflightCacheExpiry: offchainConfigParsed.InflightCacheExpiry, + RootSnoozeTime: offchainConfigParsed.RootSnoozeTime, + MessageVisibilityInterval: offchainConfigParsed.MessageVisibilityInterval, + BatchingStrategyID: offchainConfigParsed.BatchingStrategyID, + } + onchainConfig := cciptypes.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: time.Second * time.Duration(onchainConfigParsed.PermissionLessExecutionThresholdSeconds), + Router: cciptypes.Address(onchainConfigParsed.Router.String()), + } + priceEstimator := prices.NewDAGasPriceEstimator(o.Estimator, o.DestMaxGasPrice, 0, 0) + + o.UpdateDynamicConfig(onchainConfig, offchainConfig, priceEstimator) + + o.Logger.Infow("Starting exec plugin", + "offchainConfig", onchainConfigParsed, + "onchainConfig", offchainConfigParsed) + return cciptypes.Address(onchainConfigParsed.PriceRegistry.String()), + cciptypes.Address(destWrappedNative.String()), nil +} + +func NewOffRamp(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, destMaxGasPrice *big.Int) (*OffRamp, error) { + v120, err := v1_2_0.NewOffRamp(lggr, addr, ec, lp, estimator, destMaxGasPrice) + if err != nil { + return nil, err + } + + offRamp, err := evm_2_evm_offramp.NewEVM2EVMOffRamp(addr, ec) + if err != nil { + return nil, err + } + + v120.ExecutionReportArgs = abihelpers.MustGetMethodInputs("manuallyExecute", abiOffRamp)[:1] + + return &OffRamp{ + OffRamp: v120, + offRampV150: offRamp, + cachedRateLimitTokens: cache.NewLogpollerEventsBased[cciptypes.OffRampTokens]( + lp, + []common.Hash{RateLimitTokenAddedEvent, RateLimitTokenRemovedEvent}, + offRamp.Address(), + ), + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp_test.go new file mode 100644 index 0000000000..a95445ec02 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp_test.go @@ -0,0 +1 @@ +package v1_5_0 diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go new file mode 100644 index 0000000000..481933f89a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go @@ -0,0 +1,259 @@ +package v1_5_0 + +import ( + "context" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" +) + +var ( + // Backwards compat for integration tests + CCIPSendRequestEventSig common.Hash + ConfigSetEventSig common.Hash +) + +const ( + CCIPSendRequestSeqNumIndex = 4 + CCIPSendRequestedEventName = "CCIPSendRequested" + ConfigSetEventName = "ConfigSet" +) + +func init() { + onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp.EVM2EVMOnRampABI)) + if err != nil { + panic(err) + } + CCIPSendRequestEventSig = abihelpers.MustGetEventID(CCIPSendRequestedEventName, onRampABI) + ConfigSetEventSig = abihelpers.MustGetEventID(ConfigSetEventName, onRampABI) +} + +var _ ccipdata.OnRampReader = &OnRamp{} + +type OnRamp struct { + onRamp *evm_2_evm_onramp.EVM2EVMOnRamp + address common.Address + destChainSelectorBytes [16]byte + lggr logger.Logger + lp logpoller.LogPoller + leafHasher ccipdata.LeafHasherInterface[[32]byte] + client client.Client + sendRequestedEventSig common.Hash + sendRequestedSeqNumberWord int + filters []logpoller.Filter + cachedSourcePriceRegistryAddress cache.AutoSync[cciptypes.Address] + // Static config can be cached, because it's never expected to change. + // The only way to change that is through the contract's constructor (redeployment) + cachedStaticConfig cache.OnceCtxFunction[evm_2_evm_onramp.EVM2EVMOnRampStaticConfig] + cachedRmnContract cache.OnceCtxFunction[*arm_contract.ARMContract] +} + +func NewOnRamp(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAddress common.Address, sourceLP logpoller.LogPoller, source client.Client) (*OnRamp, error) { + onRamp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, source) + if err != nil { + return nil, err + } + + // Subscribe to the relevant logs + // Note we can keep the same prefix across 1.0/1.1 and 1.2 because the onramp addresses will be different + filters := []logpoller.Filter{ + { + Name: logpoller.FilterName(ccipdata.COMMIT_CCIP_SENDS, onRampAddress), + EventSigs: []common.Hash{CCIPSendRequestEventSig}, + Addresses: []common.Address{onRampAddress}, + Retention: ccipdata.CommitExecLogsRetention, + }, + { + Name: logpoller.FilterName(ccipdata.CONFIG_CHANGED, onRampAddress), + EventSigs: []common.Hash{ConfigSetEventSig}, + Addresses: []common.Address{onRampAddress}, + Retention: ccipdata.CacheEvictionLogsRetention, + }, + } + cachedStaticConfig := cache.OnceCtxFunction[evm_2_evm_onramp.EVM2EVMOnRampStaticConfig](func(ctx context.Context) (evm_2_evm_onramp.EVM2EVMOnRampStaticConfig, error) { + return onRamp.GetStaticConfig(&bind.CallOpts{Context: ctx}) + }) + cachedRmnContract := cache.OnceCtxFunction[*arm_contract.ARMContract](func(ctx context.Context) (*arm_contract.ARMContract, error) { + staticConfig, err := cachedStaticConfig(ctx) + if err != nil { + return nil, err + } + + return arm_contract.NewARMContract(staticConfig.RmnProxy, source) + }) + + return &OnRamp{ + lggr: lggr, + client: source, + destChainSelectorBytes: ccipcommon.SelectorToBytes(destSelector), + lp: sourceLP, + leafHasher: NewLeafHasher(sourceSelector, destSelector, onRampAddress, hashutil.NewKeccak(), onRamp), + onRamp: onRamp, + filters: filters, + address: onRampAddress, + sendRequestedSeqNumberWord: CCIPSendRequestSeqNumIndex, + sendRequestedEventSig: CCIPSendRequestEventSig, + cachedSourcePriceRegistryAddress: cache.NewLogpollerEventsBased[cciptypes.Address]( + sourceLP, + []common.Hash{ConfigSetEventSig}, + onRampAddress, + ), + cachedStaticConfig: cache.CallOnceOnNoError(cachedStaticConfig), + cachedRmnContract: cache.CallOnceOnNoError(cachedRmnContract), + }, nil +} + +func (o *OnRamp) Address(context.Context) (cciptypes.Address, error) { + return ccipcalc.EvmAddrToGeneric(o.onRamp.Address()), nil +} + +func (o *OnRamp) GetDynamicConfig(context.Context) (cciptypes.OnRampDynamicConfig, error) { + if o.onRamp == nil { + return cciptypes.OnRampDynamicConfig{}, fmt.Errorf("onramp not initialized") + } + config, err := o.onRamp.GetDynamicConfig(&bind.CallOpts{}) + if err != nil { + return cciptypes.OnRampDynamicConfig{}, fmt.Errorf("get dynamic config v1.5: %w", err) + } + return cciptypes.OnRampDynamicConfig{ + Router: ccipcalc.EvmAddrToGeneric(config.Router), + MaxNumberOfTokensPerMsg: config.MaxNumberOfTokensPerMsg, + DestGasOverhead: config.DestGasOverhead, + DestGasPerPayloadByte: config.DestGasPerPayloadByte, + DestDataAvailabilityOverheadGas: config.DestDataAvailabilityOverheadGas, + DestGasPerDataAvailabilityByte: config.DestGasPerDataAvailabilityByte, + DestDataAvailabilityMultiplierBps: config.DestDataAvailabilityMultiplierBps, + PriceRegistry: ccipcalc.EvmAddrToGeneric(config.PriceRegistry), + MaxDataBytes: config.MaxDataBytes, + MaxPerMsgGasLimit: config.MaxPerMsgGasLimit, + }, nil +} + +func (o *OnRamp) SourcePriceRegistryAddress(ctx context.Context) (cciptypes.Address, error) { + return o.cachedSourcePriceRegistryAddress.Get(ctx, func(ctx context.Context) (cciptypes.Address, error) { + c, err := o.GetDynamicConfig(ctx) + if err != nil { + return "", err + } + return c.PriceRegistry, nil + }) +} + +func (o *OnRamp) GetSendRequestsBetweenSeqNums(ctx context.Context, seqNumMin, seqNumMax uint64, finalized bool) ([]cciptypes.EVM2EVMMessageWithTxMeta, error) { + logs, err := o.lp.LogsDataWordRange( + ctx, + o.sendRequestedEventSig, + o.address, + o.sendRequestedSeqNumberWord, + logpoller.EvmWord(seqNumMin), + logpoller.EvmWord(seqNumMax), + ccipdata.LogsConfirmations(finalized), + ) + if err != nil { + return nil, err + } + + parsedLogs, err := ccipdata.ParseLogs[cciptypes.EVM2EVMMessage](logs, o.lggr, o.logToMessage) + if err != nil { + return nil, err + } + + res := make([]cciptypes.EVM2EVMMessageWithTxMeta, 0, len(logs)) + for _, log := range parsedLogs { + res = append(res, cciptypes.EVM2EVMMessageWithTxMeta{ + TxMeta: log.TxMeta, + EVM2EVMMessage: log.Data, + }) + } + return res, nil +} + +func (o *OnRamp) RouterAddress(context.Context) (cciptypes.Address, error) { + config, err := o.onRamp.GetDynamicConfig(nil) + if err != nil { + return "", err + } + return ccipcalc.EvmAddrToGeneric(config.Router), nil +} + +func (o *OnRamp) IsSourceChainHealthy(context.Context) (bool, error) { + if err := o.lp.Healthy(); err != nil { + return false, nil + } + return true, nil +} + +func (o *OnRamp) IsSourceCursed(ctx context.Context) (bool, error) { + arm, err := o.cachedRmnContract(ctx) + if err != nil { + return false, fmt.Errorf("initializing RMN contract through the RmnProxy: %w", err) + } + + cursed, err := arm.IsCursed(&bind.CallOpts{Context: ctx}, o.destChainSelectorBytes) + if err != nil { + return false, fmt.Errorf("checking if source is cursed by RMN: %w", err) + } + return cursed, nil +} + +func (o *OnRamp) Close() error { + return logpollerutil.UnregisterLpFilters(o.lp, o.filters) +} + +func (o *OnRamp) RegisterFilters() error { + return logpollerutil.RegisterLpFilters(o.lp, o.filters) +} + +func (o *OnRamp) logToMessage(log types.Log) (*cciptypes.EVM2EVMMessage, error) { + msg, err := o.onRamp.ParseCCIPSendRequested(log) + if err != nil { + return nil, err + } + h, err := o.leafHasher.HashLeaf(log) + if err != nil { + return nil, err + } + tokensAndAmounts := make([]cciptypes.TokenAmount, len(msg.Message.TokenAmounts)) + for i, tokenAndAmount := range msg.Message.TokenAmounts { + tokensAndAmounts[i] = cciptypes.TokenAmount{ + Token: ccipcalc.EvmAddrToGeneric(tokenAndAmount.Token), + Amount: tokenAndAmount.Amount, + } + } + + return &cciptypes.EVM2EVMMessage{ + SequenceNumber: msg.Message.SequenceNumber, + GasLimit: msg.Message.GasLimit, + Nonce: msg.Message.Nonce, + MessageID: msg.Message.MessageId, + SourceChainSelector: msg.Message.SourceChainSelector, + Sender: ccipcalc.EvmAddrToGeneric(msg.Message.Sender), + Receiver: ccipcalc.EvmAddrToGeneric(msg.Message.Receiver), + Strict: msg.Message.Strict, + FeeToken: ccipcalc.EvmAddrToGeneric(msg.Message.FeeToken), + FeeTokenAmount: msg.Message.FeeTokenAmount, + Data: msg.Message.Data, + TokenAmounts: tokensAndAmounts, + SourceTokenData: msg.Message.SourceTokenData, // Breaking change 1.2 + Hash: h, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go new file mode 100644 index 0000000000..3ca360c8ff --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go @@ -0,0 +1,210 @@ +package v1_5_0 + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +func TestLogPollerClient_GetSendRequestsBetweenSeqNums1_4_0(t *testing.T) { + onRampAddr := utils.RandomAddress() + seqNum := uint64(100) + limit := uint64(10) + lggr := logger.TestLogger(t) + + tests := []struct { + name string + finalized bool + confirmations evmtypes.Confirmations + }{ + {"finalized", true, evmtypes.Finalized}, + {"unfinalized", false, evmtypes.Confirmations(0)}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + lp := mocks.NewLogPoller(t) + onRampV2, err := NewOnRamp(lggr, 1, 1, onRampAddr, lp, nil) + require.NoError(t, err) + + lp.On("LogsDataWordRange", + mock.Anything, + onRampV2.sendRequestedEventSig, + onRampAddr, + onRampV2.sendRequestedSeqNumberWord, + abihelpers.EvmWord(seqNum), + abihelpers.EvmWord(seqNum+limit), + tt.confirmations, + ).Once().Return([]logpoller.Log{}, nil) + + events, err1 := onRampV2.GetSendRequestsBetweenSeqNums(context.Background(), seqNum, seqNum+limit, tt.finalized) + assert.NoError(t, err1) + assert.Empty(t, events) + + lp.AssertExpectations(t) + }) + } +} + +func Test_ProperlyRecognizesPerLaneCurses(t *testing.T) { + user, bc := ccipdata.NewSimulation(t) + ctx := testutils.Context(t) + destChainSelector := uint64(100) + sourceChainSelector := uint64(200) + onRampAddress, mockRMN, mockRMNAddress := setupOnRampV1_5_0(t, user, bc) + + onRamp, err := NewOnRamp(logger.TestLogger(t), 1, destChainSelector, onRampAddress, mocks.NewLogPoller(t), bc) + require.NoError(t, err) + + onRamp.cachedStaticConfig = func(ctx context.Context) (evm_2_evm_onramp.EVM2EVMOnRampStaticConfig, error) { + return evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ + RmnProxy: mockRMNAddress, + }, nil + } + + // Lane is not cursed right after deployment + isCursed, err := onRamp.IsSourceCursed(ctx) + require.NoError(t, err) + assert.False(t, isCursed) + + // Cursing different chain selector + _, err = mockRMN.VoteToCurse0(user, [32]byte{}, ccipcommon.SelectorToBytes(sourceChainSelector)) + require.NoError(t, err) + bc.Commit() + + isCursed, err = onRamp.IsSourceCursed(ctx) + require.NoError(t, err) + assert.False(t, isCursed) + + // Cursing the correct chain selector + _, err = mockRMN.VoteToCurse0(user, [32]byte{}, ccipcommon.SelectorToBytes(destChainSelector)) + require.NoError(t, err) + bc.Commit() + + isCursed, err = onRamp.IsSourceCursed(ctx) + require.NoError(t, err) + assert.True(t, isCursed) + + // Uncursing the chain selector + _, err = mockRMN.OwnerUnvoteToCurse(user, []mock_arm_contract.RMNUnvoteToCurseRecord{}, ccipcommon.SelectorToBytes(destChainSelector)) + require.NoError(t, err) + bc.Commit() + + isCursed, err = onRamp.IsSourceCursed(ctx) + require.NoError(t, err) + assert.False(t, isCursed) +} + +// This is written to benchmark before and after the caching of StaticConfig and RMNContract +func BenchmarkIsSourceCursedWithCache(b *testing.B) { + user, bc := ccipdata.NewSimulation(b) + ctx := testutils.Context(b) + destChainSelector := uint64(100) + onRampAddress, _, _ := setupOnRampV1_5_0(b, user, bc) + + onRamp, err := NewOnRamp(logger.TestLogger(b), 1, destChainSelector, onRampAddress, mocks.NewLogPoller(b), bc) + require.NoError(b, err) + + for i := 0; i < b.N; i++ { + _, _ = onRamp.IsSourceCursed(ctx) + } +} + +func setupOnRampV1_5_0(t testing.TB, user *bind.TransactOpts, bc *client.SimulatedBackendClient) (common.Address, *mock_arm_contract.MockARMContract, common.Address) { + rmnAddress, transaction, rmnContract, err := mock_arm_contract.DeployMockARMContract(user, bc) + bc.Commit() + require.NoError(t, err) + ccipdata.AssertNonRevert(t, transaction, bc, user) + + linkTokenAddress := common.HexToAddress("0x000011") + staticConfig := evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ + LinkToken: linkTokenAddress, + ChainSelector: testutils.SimulatedChainID.Uint64(), + DestChainSelector: testutils.SimulatedChainID.Uint64(), + DefaultTxGasLimit: 30000, + MaxNopFeesJuels: big.NewInt(1000000), + PrevOnRamp: common.Address{}, + RmnProxy: rmnAddress, + TokenAdminRegistry: utils.RandomAddress(), + } + dynamicConfig := evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ + Router: common.HexToAddress("0x0000000000000000000000000000000000000150"), + MaxNumberOfTokensPerMsg: 0, + DestGasOverhead: 0, + DestGasPerPayloadByte: 0, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 0, + DestDataAvailabilityMultiplierBps: 0, + PriceRegistry: utils.RandomAddress(), + MaxDataBytes: 0, + MaxPerMsgGasLimit: 0, + DefaultTokenFeeUSDCents: 50, + DefaultTokenDestGasOverhead: 34_000, + DefaultTokenDestBytesOverhead: 500, + } + rateLimiterConfig := evm_2_evm_onramp.RateLimiterConfig{ + IsEnabled: false, + Capacity: big.NewInt(5), + Rate: big.NewInt(5), + } + feeTokenConfigs := []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ + { + Token: linkTokenAddress, + NetworkFeeUSDCents: 0, + GasMultiplierWeiPerEth: 0, + PremiumMultiplierWeiPerEth: 0, + Enabled: false, + }, + } + tokenTransferConfigArgs := []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + { + Token: linkTokenAddress, + MinFeeUSDCents: 0, + MaxFeeUSDCents: 0, + DeciBps: 0, + DestGasOverhead: 0, + DestBytesOverhead: 32, + AggregateRateLimitEnabled: true, + }, + } + nopsAndWeights := []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{ + { + Nop: utils.RandomAddress(), + Weight: 1, + }, + } + onRampAddress, transaction, _, err := evm_2_evm_onramp.DeployEVM2EVMOnRamp( + user, + bc, + staticConfig, + dynamicConfig, + rateLimiterConfig, + feeTokenConfigs, + tokenTransferConfigArgs, + nopsAndWeights, + ) + bc.Commit() + require.NoError(t, err) + ccipdata.AssertNonRevert(t, transaction, bc, user) + + return onRampAddress, rmnContract, rmnAddress +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdb/mocks/price_service_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdb/mocks/price_service_mock.go new file mode 100644 index 0000000000..39ba632aff --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdb/mocks/price_service_mock.go @@ -0,0 +1,250 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + big "math/big" + + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + ccipdata "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + + context "context" + + mock "github.com/stretchr/testify/mock" + + prices "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +// PriceService is an autogenerated mock type for the PriceService type +type PriceService struct { + mock.Mock +} + +type PriceService_Expecter struct { + mock *mock.Mock +} + +func (_m *PriceService) EXPECT() *PriceService_Expecter { + return &PriceService_Expecter{mock: &_m.Mock} +} + +// Close provides a mock function with given fields: +func (_m *PriceService) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// PriceService_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type PriceService_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *PriceService_Expecter) Close() *PriceService_Close_Call { + return &PriceService_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *PriceService_Close_Call) Run(run func()) *PriceService_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *PriceService_Close_Call) Return(_a0 error) *PriceService_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *PriceService_Close_Call) RunAndReturn(run func() error) *PriceService_Close_Call { + _c.Call.Return(run) + return _c +} + +// GetGasAndTokenPrices provides a mock function with given fields: ctx, destChainSelector +func (_m *PriceService) GetGasAndTokenPrices(ctx context.Context, destChainSelector uint64) (map[uint64]*big.Int, map[ccip.Address]*big.Int, error) { + ret := _m.Called(ctx, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for GetGasAndTokenPrices") + } + + var r0 map[uint64]*big.Int + var r1 map[ccip.Address]*big.Int + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, uint64) (map[uint64]*big.Int, map[ccip.Address]*big.Int, error)); ok { + return rf(ctx, destChainSelector) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64) map[uint64]*big.Int); ok { + r0 = rf(ctx, destChainSelector) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[uint64]*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64) map[ccip.Address]*big.Int); ok { + r1 = rf(ctx, destChainSelector) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(map[ccip.Address]*big.Int) + } + } + + if rf, ok := ret.Get(2).(func(context.Context, uint64) error); ok { + r2 = rf(ctx, destChainSelector) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// PriceService_GetGasAndTokenPrices_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGasAndTokenPrices' +type PriceService_GetGasAndTokenPrices_Call struct { + *mock.Call +} + +// GetGasAndTokenPrices is a helper method to define mock.On call +// - ctx context.Context +// - destChainSelector uint64 +func (_e *PriceService_Expecter) GetGasAndTokenPrices(ctx interface{}, destChainSelector interface{}) *PriceService_GetGasAndTokenPrices_Call { + return &PriceService_GetGasAndTokenPrices_Call{Call: _e.mock.On("GetGasAndTokenPrices", ctx, destChainSelector)} +} + +func (_c *PriceService_GetGasAndTokenPrices_Call) Run(run func(ctx context.Context, destChainSelector uint64)) *PriceService_GetGasAndTokenPrices_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64)) + }) + return _c +} + +func (_c *PriceService_GetGasAndTokenPrices_Call) Return(_a0 map[uint64]*big.Int, _a1 map[ccip.Address]*big.Int, _a2 error) *PriceService_GetGasAndTokenPrices_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *PriceService_GetGasAndTokenPrices_Call) RunAndReturn(run func(context.Context, uint64) (map[uint64]*big.Int, map[ccip.Address]*big.Int, error)) *PriceService_GetGasAndTokenPrices_Call { + _c.Call.Return(run) + return _c +} + +// Start provides a mock function with given fields: _a0 +func (_m *PriceService) Start(_a0 context.Context) error { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for Start") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// PriceService_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start' +type PriceService_Start_Call struct { + *mock.Call +} + +// Start is a helper method to define mock.On call +// - _a0 context.Context +func (_e *PriceService_Expecter) Start(_a0 interface{}) *PriceService_Start_Call { + return &PriceService_Start_Call{Call: _e.mock.On("Start", _a0)} +} + +func (_c *PriceService_Start_Call) Run(run func(_a0 context.Context)) *PriceService_Start_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *PriceService_Start_Call) Return(_a0 error) *PriceService_Start_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *PriceService_Start_Call) RunAndReturn(run func(context.Context) error) *PriceService_Start_Call { + _c.Call.Return(run) + return _c +} + +// UpdateDynamicConfig provides a mock function with given fields: ctx, gasPriceEstimator, destPriceRegistryReader +func (_m *PriceService) UpdateDynamicConfig(ctx context.Context, gasPriceEstimator prices.GasPriceEstimatorCommit, destPriceRegistryReader ccipdata.PriceRegistryReader) error { + ret := _m.Called(ctx, gasPriceEstimator, destPriceRegistryReader) + + if len(ret) == 0 { + panic("no return value specified for UpdateDynamicConfig") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, prices.GasPriceEstimatorCommit, ccipdata.PriceRegistryReader) error); ok { + r0 = rf(ctx, gasPriceEstimator, destPriceRegistryReader) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// PriceService_UpdateDynamicConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateDynamicConfig' +type PriceService_UpdateDynamicConfig_Call struct { + *mock.Call +} + +// UpdateDynamicConfig is a helper method to define mock.On call +// - ctx context.Context +// - gasPriceEstimator prices.GasPriceEstimatorCommit +// - destPriceRegistryReader ccipdata.PriceRegistryReader +func (_e *PriceService_Expecter) UpdateDynamicConfig(ctx interface{}, gasPriceEstimator interface{}, destPriceRegistryReader interface{}) *PriceService_UpdateDynamicConfig_Call { + return &PriceService_UpdateDynamicConfig_Call{Call: _e.mock.On("UpdateDynamicConfig", ctx, gasPriceEstimator, destPriceRegistryReader)} +} + +func (_c *PriceService_UpdateDynamicConfig_Call) Run(run func(ctx context.Context, gasPriceEstimator prices.GasPriceEstimatorCommit, destPriceRegistryReader ccipdata.PriceRegistryReader)) *PriceService_UpdateDynamicConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(prices.GasPriceEstimatorCommit), args[2].(ccipdata.PriceRegistryReader)) + }) + return _c +} + +func (_c *PriceService_UpdateDynamicConfig_Call) Return(_a0 error) *PriceService_UpdateDynamicConfig_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *PriceService_UpdateDynamicConfig_Call) RunAndReturn(run func(context.Context, prices.GasPriceEstimatorCommit, ccipdata.PriceRegistryReader) error) *PriceService_UpdateDynamicConfig_Call { + _c.Call.Return(run) + return _c +} + +// NewPriceService creates a new instance of PriceService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewPriceService(t interface { + mock.TestingT + Cleanup(func()) +}) *PriceService { + mock := &PriceService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go new file mode 100644 index 0000000000..7d7d5bda3a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go @@ -0,0 +1,400 @@ +package db + +import ( + "context" + "fmt" + "math/big" + "sort" + "sync" + "time" + + "golang.org/x/sync/errgroup" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/utils" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + cciporm "github.com/smartcontractkit/chainlink/v2/core/services/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +// PriceService manages DB access for gas and token price data. +// In the background, PriceService periodically inserts latest gas and token prices into the DB. +// During `Observation` phase, Commit plugin calls PriceService to fetch the latest prices from DB. +// This enables all lanes connected to a chain to feed price data to the leader lane's Commit plugin for that chain. +type PriceService interface { + job.ServiceCtx + + // UpdateDynamicConfig updates gasPriceEstimator and destPriceRegistryReader during Commit plugin dynamic config change. + UpdateDynamicConfig(ctx context.Context, gasPriceEstimator prices.GasPriceEstimatorCommit, destPriceRegistryReader ccipdata.PriceRegistryReader) error + + // GetGasAndTokenPrices fetches source chain gas prices and relevant token prices from all lanes that touch the given dest chain. + // The prices have been written into the DB by each lane's PriceService in the background. The prices are denoted in USD. + GetGasAndTokenPrices(ctx context.Context, destChainSelector uint64) (map[uint64]*big.Int, map[cciptypes.Address]*big.Int, error) +} + +var _ PriceService = (*priceService)(nil) + +const ( + // Prices should expire after 10 minutes in DB. Prices should be fresh in the Commit plugin. + // 10 min provides sufficient buffer for the Commit plugin to withstand transient price update outages, while + // surfacing price update outages quickly enough. + priceExpireSec = 600 + // Cleanups are called every 10 minutes. For a given job, on average we may expect 3 token prices and 1 gas price. + // 10 minutes should result in 40 rows being cleaned up per job, it is not a heavy load on DB, so there is no need + // to run cleanup more frequently. We shouldn't clean up less frequently than `priceExpireSec`. + priceCleanupInterval = 600 * time.Second + + // Prices are refreshed every 1 minute, they are sufficiently accurate, and consistent with Commit OCR round time. + priceUpdateInterval = 60 * time.Second +) + +type priceService struct { + priceExpireSec int + cleanupInterval time.Duration + updateInterval time.Duration + + lggr logger.Logger + orm cciporm.ORM + jobId int32 + destChainSelector uint64 + + sourceChainSelector uint64 + sourceNative cciptypes.Address + priceGetter pricegetter.PriceGetter + offRampReader ccipdata.OffRampReader + gasPriceEstimator prices.GasPriceEstimatorCommit + destPriceRegistryReader ccipdata.PriceRegistryReader + + services.StateMachine + wg *sync.WaitGroup + backgroundCtx context.Context //nolint:containedctx + backgroundCancel context.CancelFunc + dynamicConfigMu *sync.RWMutex +} + +func NewPriceService( + lggr logger.Logger, + orm cciporm.ORM, + jobId int32, + destChainSelector uint64, + sourceChainSelector uint64, + + sourceNative cciptypes.Address, + priceGetter pricegetter.PriceGetter, + offRampReader ccipdata.OffRampReader, +) PriceService { + ctx, cancel := context.WithCancel(context.Background()) + + pw := &priceService{ + priceExpireSec: priceExpireSec, + cleanupInterval: utils.WithJitter(priceCleanupInterval), // use WithJitter to avoid multiple services impacting DB at same time + updateInterval: utils.WithJitter(priceUpdateInterval), + + lggr: lggr, + orm: orm, + jobId: jobId, + destChainSelector: destChainSelector, + + sourceChainSelector: sourceChainSelector, + sourceNative: sourceNative, + priceGetter: priceGetter, + offRampReader: offRampReader, + + wg: new(sync.WaitGroup), + backgroundCtx: ctx, + backgroundCancel: cancel, + dynamicConfigMu: &sync.RWMutex{}, + } + return pw +} + +func (p *priceService) Start(context.Context) error { + return p.StateMachine.StartOnce("PriceService", func() error { + p.lggr.Info("Starting PriceService") + p.wg.Add(1) + p.run() + return nil + }) +} + +func (p *priceService) Close() error { + return p.StateMachine.StopOnce("PriceService", func() error { + p.lggr.Info("Closing PriceService") + p.backgroundCancel() + p.wg.Wait() + return nil + }) +} + +func (p *priceService) run() { + cleanupTicker := time.NewTicker(p.cleanupInterval) + updateTicker := time.NewTicker(p.updateInterval) + + go func() { + defer p.wg.Done() + + for { + select { + case <-p.backgroundCtx.Done(): + return + case <-cleanupTicker.C: + err := p.runCleanup(p.backgroundCtx) + if err != nil { + p.lggr.Errorw("Error when cleaning up in-db prices in the background", "err", err) + } + case <-updateTicker.C: + err := p.runUpdate(p.backgroundCtx) + if err != nil { + p.lggr.Errorw("Error when updating prices in the background", "err", err) + } + } + } + }() +} + +func (p *priceService) UpdateDynamicConfig(ctx context.Context, gasPriceEstimator prices.GasPriceEstimatorCommit, destPriceRegistryReader ccipdata.PriceRegistryReader) error { + p.dynamicConfigMu.Lock() + p.gasPriceEstimator = gasPriceEstimator + p.destPriceRegistryReader = destPriceRegistryReader + p.dynamicConfigMu.Unlock() + + // Config update may substantially change the prices, refresh the prices immediately, this also makes testing easier + // for not having to wait to the full update interval. + if err := p.runUpdate(ctx); err != nil { + p.lggr.Errorw("Error when updating prices after dynamic config update", "err", err) + } + + return nil +} + +func (p *priceService) GetGasAndTokenPrices(ctx context.Context, destChainSelector uint64) (map[uint64]*big.Int, map[cciptypes.Address]*big.Int, error) { + eg := new(errgroup.Group) + + var gasPricesInDB []cciporm.GasPrice + var tokenPricesInDB []cciporm.TokenPrice + + eg.Go(func() error { + gasPrices, err := p.orm.GetGasPricesByDestChain(ctx, destChainSelector) + if err != nil { + return fmt.Errorf("failed to get gas prices from db: %w", err) + } + gasPricesInDB = gasPrices + return nil + }) + + eg.Go(func() error { + tokenPrices, err := p.orm.GetTokenPricesByDestChain(ctx, destChainSelector) + if err != nil { + return fmt.Errorf("failed to get token prices from db: %w", err) + } + tokenPricesInDB = tokenPrices + return nil + }) + + if err := eg.Wait(); err != nil { + return nil, nil, err + } + + gasPrices := make(map[uint64]*big.Int, len(gasPricesInDB)) + tokenPrices := make(map[cciptypes.Address]*big.Int, len(tokenPricesInDB)) + + for _, gasPrice := range gasPricesInDB { + if gasPrice.GasPrice != nil { + gasPrices[gasPrice.SourceChainSelector] = gasPrice.GasPrice.ToInt() + } + } + + for _, tokenPrice := range tokenPricesInDB { + if tokenPrice.TokenPrice != nil { + tokenPrices[cciptypes.Address(tokenPrice.TokenAddr)] = tokenPrice.TokenPrice.ToInt() + } + } + + return gasPrices, tokenPrices, nil +} + +func (p *priceService) runCleanup(ctx context.Context) error { + eg := new(errgroup.Group) + + eg.Go(func() error { + err := p.orm.ClearGasPricesByDestChain(ctx, p.destChainSelector, p.priceExpireSec) + if err != nil { + return fmt.Errorf("error clearing gas prices: %w", err) + } + return nil + }) + + eg.Go(func() error { + err := p.orm.ClearTokenPricesByDestChain(ctx, p.destChainSelector, p.priceExpireSec) + if err != nil { + return fmt.Errorf("error clearing token prices: %w", err) + } + return nil + }) + + return eg.Wait() +} + +func (p *priceService) runUpdate(ctx context.Context) error { + // Protect against concurrent updates of `gasPriceEstimator` and `destPriceRegistryReader` + // Price updates happen infrequently - once every `priceUpdateInterval` seconds. + // It does not happen on any code path that is performance sensitive. + // We can afford to have non-performant unlocks here that is simple and safe. + p.dynamicConfigMu.RLock() + defer p.dynamicConfigMu.RUnlock() + + // There may be a period of time between service is started and dynamic config is updated + if p.gasPriceEstimator == nil || p.destPriceRegistryReader == nil { + p.lggr.Info("Skipping price update due to gasPriceEstimator and/or destPriceRegistry not ready") + return nil + } + + sourceGasPriceUSD, tokenPricesUSD, err := p.observePriceUpdates(ctx, p.lggr) + if err != nil { + return fmt.Errorf("failed to observe price updates: %w", err) + } + + err = p.writePricesToDB(ctx, sourceGasPriceUSD, tokenPricesUSD) + if err != nil { + return fmt.Errorf("failed to write prices to db: %w", err) + } + + return nil +} + +func (p *priceService) observePriceUpdates( + ctx context.Context, + lggr logger.Logger, +) (sourceGasPriceUSD *big.Int, tokenPricesUSD map[cciptypes.Address]*big.Int, err error) { + if p.gasPriceEstimator == nil || p.destPriceRegistryReader == nil { + return nil, nil, fmt.Errorf("gasPriceEstimator and/or destPriceRegistry is not set yet") + } + + sortedLaneTokens, filteredLaneTokens, err := ccipcommon.GetFilteredSortedLaneTokens(ctx, p.offRampReader, p.destPriceRegistryReader, p.priceGetter) + + lggr.Debugw("Filtered bridgeable tokens with no configured price getter", "filteredLaneTokens", filteredLaneTokens) + + if err != nil { + return nil, nil, fmt.Errorf("get destination tokens: %w", err) + } + + return p.generatePriceUpdates(ctx, lggr, sortedLaneTokens) +} + +// All prices are USD ($1=1e18) denominated. All prices must be not nil. +// Return token prices should contain the exact same tokens as in tokenDecimals. +func (p *priceService) generatePriceUpdates( + ctx context.Context, + lggr logger.Logger, + sortedLaneTokens []cciptypes.Address, +) (sourceGasPriceUSD *big.Int, tokenPricesUSD map[cciptypes.Address]*big.Int, err error) { + // Include wrapped native in our token query as way to identify the source native USD price. + // notice USD is in 1e18 scale, i.e. $1 = 1e18 + queryTokens := ccipcommon.FlattenUniqueSlice([]cciptypes.Address{p.sourceNative}, sortedLaneTokens) + + rawTokenPricesUSD, err := p.priceGetter.TokenPricesUSD(ctx, queryTokens) + if err != nil { + return nil, nil, err + } + lggr.Infow("Raw token prices", "rawTokenPrices", rawTokenPricesUSD) + + // make sure that we got prices for all the tokens of our query + for _, token := range queryTokens { + if rawTokenPricesUSD[token] == nil { + return nil, nil, fmt.Errorf("missing token price: %+v", token) + } + } + + sourceNativePriceUSD, exists := rawTokenPricesUSD[p.sourceNative] + if !exists { + return nil, nil, fmt.Errorf("missing source native (%s) price", p.sourceNative) + } + + destTokensDecimals, err := p.destPriceRegistryReader.GetTokensDecimals(ctx, sortedLaneTokens) + if err != nil { + return nil, nil, fmt.Errorf("get tokens decimals: %w", err) + } + + tokenPricesUSD = make(map[cciptypes.Address]*big.Int, len(rawTokenPricesUSD)) + for i, token := range sortedLaneTokens { + tokenPricesUSD[token] = calculateUsdPer1e18TokenAmount(rawTokenPricesUSD[token], destTokensDecimals[i]) + } + + sourceGasPrice, err := p.gasPriceEstimator.GetGasPrice(ctx) + if err != nil { + return nil, nil, err + } + if sourceGasPrice == nil { + return nil, nil, fmt.Errorf("missing gas price") + } + sourceGasPriceUSD, err = p.gasPriceEstimator.DenoteInUSD(sourceGasPrice, sourceNativePriceUSD) + if err != nil { + return nil, nil, err + } + + lggr.Infow("PriceService observed latest price", + "sourceChainSelector", p.sourceChainSelector, + "destChainSelector", p.destChainSelector, + "gasPriceWei", sourceGasPrice, + "sourceNativePriceUSD", sourceNativePriceUSD, + "sourceGasPriceUSD", sourceGasPriceUSD, + "tokenPricesUSD", tokenPricesUSD, + ) + return sourceGasPriceUSD, tokenPricesUSD, nil +} + +func (p *priceService) writePricesToDB( + ctx context.Context, + sourceGasPriceUSD *big.Int, + tokenPricesUSD map[cciptypes.Address]*big.Int, +) (err error) { + eg := new(errgroup.Group) + + if sourceGasPriceUSD != nil { + eg.Go(func() error { + return p.orm.InsertGasPricesForDestChain(ctx, p.destChainSelector, p.jobId, []cciporm.GasPriceUpdate{ + { + SourceChainSelector: p.sourceChainSelector, + GasPrice: assets.NewWei(sourceGasPriceUSD), + }, + }) + }) + } + + if tokenPricesUSD != nil { + var tokenPrices []cciporm.TokenPriceUpdate + + for token, price := range tokenPricesUSD { + tokenPrices = append(tokenPrices, cciporm.TokenPriceUpdate{ + TokenAddr: string(token), + TokenPrice: assets.NewWei(price), + }) + } + + // Sort token by addr to make price updates ordering deterministic, easier to testing and debugging + sort.Slice(tokenPrices, func(i, j int) bool { + return tokenPrices[i].TokenAddr < tokenPrices[j].TokenAddr + }) + + eg.Go(func() error { + return p.orm.InsertTokenPricesForDestChain(ctx, p.destChainSelector, p.jobId, tokenPrices) + }) + } + + return eg.Wait() +} + +// Input price is USD per full token, with 18 decimal precision +// Result price is USD per 1e18 of smallest token denomination, with 18 decimal precision +// Example: 1 USDC = 1.00 USD per full token, each full token is 6 decimals -> 1 * 1e18 * 1e18 / 1e6 = 1e30 +func calculateUsdPer1e18TokenAmount(price *big.Int, decimals uint8) *big.Int { + tmp := big.NewInt(0).Mul(price, big.NewInt(1e18)) + return tmp.Div(tmp, big.NewInt(0).Exp(big.NewInt(10), big.NewInt(int64(decimals)), nil)) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go new file mode 100644 index 0000000000..0bea8af9a1 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go @@ -0,0 +1,755 @@ +package db + +import ( + "context" + "fmt" + "math/big" + "reflect" + "sort" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + cciporm "github.com/smartcontractkit/chainlink/v2/core/services/ccip" + ccipmocks "github.com/smartcontractkit/chainlink/v2/core/services/ccip/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" + ccipdatamocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +func TestPriceService_priceCleanup(t *testing.T) { + lggr := logger.TestLogger(t) + jobId := int32(1) + destChainSelector := uint64(12345) + sourceChainSelector := uint64(67890) + + testCases := []struct { + name string + gasPriceError bool + tokenPriceError bool + expectedErr bool + }{ + { + name: "ORM called successfully", + gasPriceError: false, + tokenPriceError: false, + expectedErr: false, + }, + { + name: "gasPrice clear failed", + gasPriceError: true, + tokenPriceError: false, + expectedErr: true, + }, + { + name: "tokenPrice clear failed", + gasPriceError: false, + tokenPriceError: true, + expectedErr: true, + }, + { + name: "both ORM calls failed", + gasPriceError: true, + tokenPriceError: true, + expectedErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctx := tests.Context(t) + + var gasPricesError error + var tokenPricesError error + if tc.gasPriceError { + gasPricesError = fmt.Errorf("gas prices error") + } + if tc.tokenPriceError { + tokenPricesError = fmt.Errorf("token prices error") + } + + mockOrm := ccipmocks.NewORM(t) + mockOrm.On("ClearGasPricesByDestChain", ctx, destChainSelector, priceExpireSec).Return(gasPricesError).Once() + mockOrm.On("ClearTokenPricesByDestChain", ctx, destChainSelector, priceExpireSec).Return(tokenPricesError).Once() + + priceService := NewPriceService( + lggr, + mockOrm, + jobId, + destChainSelector, + sourceChainSelector, + "", + nil, + nil, + ).(*priceService) + err := priceService.runCleanup(ctx) + if tc.expectedErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPriceService_priceWrite(t *testing.T) { + lggr := logger.TestLogger(t) + jobId := int32(1) + destChainSelector := uint64(12345) + sourceChainSelector := uint64(67890) + + gasPrice := big.NewInt(1e18) + tokenPrices := map[cciptypes.Address]*big.Int{ + "0x123": big.NewInt(2e18), + "0x234": big.NewInt(3e18), + } + + expectedGasPriceUpdate := []cciporm.GasPriceUpdate{ + { + SourceChainSelector: sourceChainSelector, + GasPrice: assets.NewWei(gasPrice), + }, + } + expectedTokenPriceUpdate := []cciporm.TokenPriceUpdate{ + { + TokenAddr: "0x123", + TokenPrice: assets.NewWei(big.NewInt(2e18)), + }, + { + TokenAddr: "0x234", + TokenPrice: assets.NewWei(big.NewInt(3e18)), + }, + } + + testCases := []struct { + name string + gasPriceError bool + tokenPriceError bool + expectedErr bool + }{ + { + name: "ORM called successfully", + gasPriceError: false, + tokenPriceError: false, + expectedErr: false, + }, + { + name: "gasPrice clear failed", + gasPriceError: true, + tokenPriceError: false, + expectedErr: true, + }, + { + name: "tokenPrice clear failed", + gasPriceError: false, + tokenPriceError: true, + expectedErr: true, + }, + { + name: "both ORM calls failed", + gasPriceError: true, + tokenPriceError: true, + expectedErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctx := tests.Context(t) + + var gasPricesError error + var tokenPricesError error + if tc.gasPriceError { + gasPricesError = fmt.Errorf("gas prices error") + } + if tc.tokenPriceError { + tokenPricesError = fmt.Errorf("token prices error") + } + + mockOrm := ccipmocks.NewORM(t) + mockOrm.On("InsertGasPricesForDestChain", ctx, destChainSelector, jobId, expectedGasPriceUpdate).Return(gasPricesError).Once() + mockOrm.On("InsertTokenPricesForDestChain", ctx, destChainSelector, jobId, expectedTokenPriceUpdate).Return(tokenPricesError).Once() + + priceService := NewPriceService( + lggr, + mockOrm, + jobId, + destChainSelector, + sourceChainSelector, + "", + nil, + nil, + ).(*priceService) + err := priceService.writePricesToDB(ctx, gasPrice, tokenPrices) + if tc.expectedErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPriceService_generatePriceUpdates(t *testing.T) { + lggr := logger.TestLogger(t) + jobId := int32(1) + destChainSelector := uint64(12345) + sourceChainSelector := uint64(67890) + + const nTokens = 10 + tokens := make([]cciptypes.Address, nTokens) + for i := range tokens { + tokens[i] = cciptypes.Address(utils.RandomAddress().String()) + } + sort.Slice(tokens, func(i, j int) bool { return tokens[i] < tokens[j] }) + + testCases := []struct { + name string + tokenDecimals map[cciptypes.Address]uint8 + sourceNativeToken cciptypes.Address + priceGetterRespData map[cciptypes.Address]*big.Int + priceGetterRespErr error + feeEstimatorRespFee *big.Int + feeEstimatorRespErr error + maxGasPrice uint64 + expSourceGasPriceUSD *big.Int + expTokenPricesUSD map[cciptypes.Address]*big.Int + expErr bool + }{ + { + name: "base", + tokenDecimals: map[cciptypes.Address]uint8{ + tokens[0]: 18, + tokens[1]: 12, + }, + sourceNativeToken: tokens[0], + priceGetterRespData: map[cciptypes.Address]*big.Int{ + tokens[0]: val1e18(100), + tokens[1]: val1e18(200), + tokens[2]: val1e18(300), // price getter returned a price for this token even though we didn't request it (should be skipped) + }, + priceGetterRespErr: nil, + feeEstimatorRespFee: big.NewInt(10), + feeEstimatorRespErr: nil, + maxGasPrice: 1e18, + expSourceGasPriceUSD: big.NewInt(1000), + expTokenPricesUSD: map[cciptypes.Address]*big.Int{ + tokens[0]: val1e18(100), + tokens[1]: val1e18(200 * 1e6), + }, + expErr: false, + }, + { + name: "price getter returned an error", + tokenDecimals: map[cciptypes.Address]uint8{ + tokens[0]: 18, + tokens[1]: 18, + }, + sourceNativeToken: tokens[0], + priceGetterRespData: nil, + priceGetterRespErr: fmt.Errorf("some random network error"), + expErr: true, + }, + { + name: "price getter skipped a requested price", + tokenDecimals: map[cciptypes.Address]uint8{ + tokens[0]: 18, + tokens[1]: 18, + }, + sourceNativeToken: tokens[0], + priceGetterRespData: map[cciptypes.Address]*big.Int{ + tokens[0]: val1e18(100), + }, + priceGetterRespErr: nil, + expErr: true, + }, + { + name: "price getter skipped source native price", + tokenDecimals: map[cciptypes.Address]uint8{ + tokens[0]: 18, + tokens[1]: 18, + }, + sourceNativeToken: tokens[2], + priceGetterRespData: map[cciptypes.Address]*big.Int{ + tokens[0]: val1e18(100), + tokens[1]: val1e18(200), + }, + priceGetterRespErr: nil, + expErr: true, + }, + { + name: "dynamic fee cap overrides legacy", + tokenDecimals: map[cciptypes.Address]uint8{ + tokens[0]: 18, + tokens[1]: 18, + }, + sourceNativeToken: tokens[0], + priceGetterRespData: map[cciptypes.Address]*big.Int{ + tokens[0]: val1e18(100), + tokens[1]: val1e18(200), + tokens[2]: val1e18(300), // price getter returned a price for this token even though we didn't request it (should be skipped) + }, + priceGetterRespErr: nil, + feeEstimatorRespFee: big.NewInt(20), + feeEstimatorRespErr: nil, + maxGasPrice: 1e18, + expSourceGasPriceUSD: big.NewInt(2000), + expTokenPricesUSD: map[cciptypes.Address]*big.Int{ + tokens[0]: val1e18(100), + tokens[1]: val1e18(200), + }, + expErr: false, + }, + { + name: "nil gas price", + tokenDecimals: map[cciptypes.Address]uint8{ + tokens[0]: 18, + tokens[1]: 18, + }, + sourceNativeToken: tokens[0], + priceGetterRespData: map[cciptypes.Address]*big.Int{ + tokens[0]: val1e18(100), + tokens[1]: val1e18(200), + tokens[2]: val1e18(300), // price getter returned a price for this token even though we didn't request it (should be skipped) + }, + feeEstimatorRespFee: nil, + maxGasPrice: 1e18, + expErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + priceGetter := pricegetter.NewMockPriceGetter(t) + defer priceGetter.AssertExpectations(t) + + gasPriceEstimator := prices.NewMockGasPriceEstimatorCommit(t) + defer gasPriceEstimator.AssertExpectations(t) + + var destTokens []cciptypes.Address + for tk := range tc.tokenDecimals { + destTokens = append(destTokens, tk) + } + sort.Slice(destTokens, func(i, j int) bool { + return destTokens[i] < destTokens[j] + }) + var destDecimals []uint8 + for _, token := range destTokens { + destDecimals = append(destDecimals, tc.tokenDecimals[token]) + } + + queryTokens := ccipcommon.FlattenUniqueSlice([]cciptypes.Address{tc.sourceNativeToken}, destTokens) + + if len(queryTokens) > 0 { + priceGetter.On("TokenPricesUSD", mock.Anything, queryTokens).Return(tc.priceGetterRespData, tc.priceGetterRespErr) + } + + if tc.maxGasPrice > 0 { + gasPriceEstimator.On("GetGasPrice", mock.Anything).Return(tc.feeEstimatorRespFee, tc.feeEstimatorRespErr) + if tc.feeEstimatorRespFee != nil { + pUSD := ccipcalc.CalculateUsdPerUnitGas(tc.feeEstimatorRespFee, tc.expTokenPricesUSD[tc.sourceNativeToken]) + gasPriceEstimator.On("DenoteInUSD", mock.Anything, mock.Anything).Return(pUSD, nil) + } + } + + destPriceReg := ccipdatamocks.NewPriceRegistryReader(t) + destPriceReg.On("GetTokensDecimals", mock.Anything, destTokens).Return(destDecimals, nil).Maybe() + + priceService := NewPriceService( + lggr, + nil, + jobId, + destChainSelector, + sourceChainSelector, + tc.sourceNativeToken, + priceGetter, + nil, + ).(*priceService) + priceService.gasPriceEstimator = gasPriceEstimator + priceService.destPriceRegistryReader = destPriceReg + + sourceGasPriceUSD, tokenPricesUSD, err := priceService.generatePriceUpdates(context.Background(), lggr, destTokens) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.True(t, tc.expSourceGasPriceUSD.Cmp(sourceGasPriceUSD) == 0) + assert.True(t, reflect.DeepEqual(tc.expTokenPricesUSD, tokenPricesUSD)) + }) + } +} + +func TestPriceService_calculateUsdPer1e18TokenAmount(t *testing.T) { + testCases := []struct { + name string + price *big.Int + decimal uint8 + wantResult *big.Int + }{ + { + name: "18-decimal token, $6.5 per token", + price: big.NewInt(65e17), + decimal: 18, + wantResult: big.NewInt(65e17), + }, + { + name: "6-decimal token, $1 per token", + price: big.NewInt(1e18), + decimal: 6, + wantResult: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e12)), // 1e30 + }, + { + name: "0-decimal token, $1 per token", + price: big.NewInt(1e18), + decimal: 0, + wantResult: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e18)), // 1e36 + }, + { + name: "36-decimal token, $1 per token", + price: big.NewInt(1e18), + decimal: 36, + wantResult: big.NewInt(1), + }, + } + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + got := calculateUsdPer1e18TokenAmount(tt.price, tt.decimal) + assert.Equal(t, tt.wantResult, got) + }) + } +} + +func TestPriceService_GetGasAndTokenPrices(t *testing.T) { + lggr := logger.TestLogger(t) + jobId := int32(1) + destChainSelector := uint64(12345) + sourceChainSelector := uint64(67890) + + token1 := ccipcalc.HexToAddress("0x123") + token2 := ccipcalc.HexToAddress("0x234") + + gasPrice := big.NewInt(1e18) + tokenPrices := map[cciptypes.Address]*big.Int{ + token1: big.NewInt(2e18), + token2: big.NewInt(3e18), + } + + testCases := []struct { + name string + ormGasPricesResult []cciporm.GasPrice + ormTokenPricesResult []cciporm.TokenPrice + + expectedGasPrices map[uint64]*big.Int + expectedTokenPrices map[cciptypes.Address]*big.Int + + gasPriceError bool + tokenPriceError bool + expectedErr bool + }{ + { + name: "ORM called successfully", + ormGasPricesResult: []cciporm.GasPrice{ + { + SourceChainSelector: sourceChainSelector, + GasPrice: assets.NewWei(gasPrice), + }, + }, + ormTokenPricesResult: []cciporm.TokenPrice{ + { + TokenAddr: string(token1), + TokenPrice: assets.NewWei(tokenPrices[token1]), + }, + { + TokenAddr: string(token2), + TokenPrice: assets.NewWei(tokenPrices[token2]), + }, + }, + expectedGasPrices: map[uint64]*big.Int{ + sourceChainSelector: gasPrice, + }, + expectedTokenPrices: tokenPrices, + gasPriceError: false, + tokenPriceError: false, + expectedErr: false, + }, + { + name: "multiple gas prices with nil token price", + ormGasPricesResult: []cciporm.GasPrice{ + { + SourceChainSelector: sourceChainSelector, + GasPrice: assets.NewWei(gasPrice), + }, + { + SourceChainSelector: sourceChainSelector + 1, + GasPrice: assets.NewWei(big.NewInt(200)), + }, + { + SourceChainSelector: sourceChainSelector + 2, + GasPrice: assets.NewWei(big.NewInt(300)), + }, + }, + ormTokenPricesResult: nil, + expectedGasPrices: map[uint64]*big.Int{ + sourceChainSelector: gasPrice, + sourceChainSelector + 1: big.NewInt(200), + sourceChainSelector + 2: big.NewInt(300), + }, + expectedTokenPrices: map[cciptypes.Address]*big.Int{}, + gasPriceError: false, + tokenPriceError: false, + expectedErr: false, + }, + { + name: "multiple token prices with nil gas price", + ormGasPricesResult: nil, + ormTokenPricesResult: []cciporm.TokenPrice{ + { + TokenAddr: string(token1), + TokenPrice: assets.NewWei(tokenPrices[token1]), + }, + { + TokenAddr: string(token2), + TokenPrice: assets.NewWei(tokenPrices[token2]), + }, + }, + expectedGasPrices: map[uint64]*big.Int{}, + expectedTokenPrices: tokenPrices, + gasPriceError: false, + tokenPriceError: false, + expectedErr: false, + }, + { + name: "nil prices filtered out", + ormGasPricesResult: []cciporm.GasPrice{ + { + SourceChainSelector: sourceChainSelector, + GasPrice: nil, + }, + { + SourceChainSelector: sourceChainSelector + 1, + GasPrice: assets.NewWei(gasPrice), + }, + }, + ormTokenPricesResult: []cciporm.TokenPrice{ + { + TokenAddr: string(token1), + TokenPrice: assets.NewWei(tokenPrices[token1]), + }, + { + TokenAddr: string(token2), + TokenPrice: nil, + }, + }, + expectedGasPrices: map[uint64]*big.Int{ + sourceChainSelector + 1: gasPrice, + }, + expectedTokenPrices: map[cciptypes.Address]*big.Int{ + token1: tokenPrices[token1], + }, + gasPriceError: false, + tokenPriceError: false, + expectedErr: false, + }, + { + name: "gasPrice clear failed", + gasPriceError: true, + tokenPriceError: false, + expectedErr: true, + }, + { + name: "tokenPrice clear failed", + gasPriceError: false, + tokenPriceError: true, + expectedErr: true, + }, + { + name: "both ORM calls failed", + gasPriceError: true, + tokenPriceError: true, + expectedErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctx := tests.Context(t) + + mockOrm := ccipmocks.NewORM(t) + if tc.gasPriceError { + mockOrm.On("GetGasPricesByDestChain", ctx, destChainSelector).Return(nil, fmt.Errorf("gas prices error")).Once() + } else { + mockOrm.On("GetGasPricesByDestChain", ctx, destChainSelector).Return(tc.ormGasPricesResult, nil).Once() + } + if tc.tokenPriceError { + mockOrm.On("GetTokenPricesByDestChain", ctx, destChainSelector).Return(nil, fmt.Errorf("token prices error")).Once() + } else { + mockOrm.On("GetTokenPricesByDestChain", ctx, destChainSelector).Return(tc.ormTokenPricesResult, nil).Once() + } + + priceService := NewPriceService( + lggr, + mockOrm, + jobId, + destChainSelector, + sourceChainSelector, + "", + nil, + nil, + ).(*priceService) + gasPricesResult, tokenPricesResult, err := priceService.GetGasAndTokenPrices(ctx, destChainSelector) + if tc.expectedErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tc.expectedGasPrices, gasPricesResult) + assert.Equal(t, tc.expectedTokenPrices, tokenPricesResult) + } + }) + } +} + +func val1e18(val int64) *big.Int { + return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(val)) +} + +func setupORM(t *testing.T) cciporm.ORM { + t.Helper() + + db := pgtest.NewSqlxDB(t) + orm, err := cciporm.NewORM(db) + + require.NoError(t, err) + + return orm +} + +func checkResultLen(t *testing.T, priceService PriceService, destChainSelector uint64, gasCount int, tokenCount int) error { + ctx := tests.Context(t) + dbGasResult, dbTokenResult, err := priceService.GetGasAndTokenPrices(ctx, destChainSelector) + if err != nil { + return nil + } + if len(dbGasResult) != gasCount { + return fmt.Errorf("expected %d gas prices, got %d", gasCount, len(dbGasResult)) + } + if len(dbTokenResult) != tokenCount { + return fmt.Errorf("expected %d token prices, got %d", tokenCount, len(dbTokenResult)) + } + return nil +} + +func TestPriceService_priceWriteAndCleanupInBackground(t *testing.T) { + lggr := logger.TestLogger(t) + jobId := int32(1) + destChainSelector := uint64(12345) + sourceChainSelector := uint64(67890) + ctx := tests.Context(t) + + sourceNative := cciptypes.Address("0x123") + feeTokens := []cciptypes.Address{"0x234"} + rampTokens := []cciptypes.Address{"0x345", "0x456"} + rampFilteredTokens := []cciptypes.Address{"0x345"} + rampFilterOutTokens := []cciptypes.Address{"0x456"} + + laneTokens := []cciptypes.Address{"0x234", "0x345"} + laneTokenDecimals := []uint8{18, 18} + + tokens := []cciptypes.Address{sourceNative, "0x234", "0x345"} + tokenPrices := []int64{2, 3, 4} + gasPrice := big.NewInt(10) + + orm := setupORM(t) + + priceGetter := pricegetter.NewMockPriceGetter(t) + defer priceGetter.AssertExpectations(t) + + gasPriceEstimator := prices.NewMockGasPriceEstimatorCommit(t) + defer gasPriceEstimator.AssertExpectations(t) + + priceGetter.On("TokenPricesUSD", mock.Anything, tokens).Return(map[cciptypes.Address]*big.Int{ + tokens[0]: val1e18(tokenPrices[0]), + tokens[1]: val1e18(tokenPrices[1]), + tokens[2]: val1e18(tokenPrices[2]), + }, nil) + priceGetter.On("FilterConfiguredTokens", mock.Anything, rampTokens).Return(rampFilteredTokens, rampFilterOutTokens, nil) + + offRampReader := ccipdatamocks.NewOffRampReader(t) + offRampReader.On("GetTokens", mock.Anything).Return(cciptypes.OffRampTokens{ + DestinationTokens: rampTokens, + }, nil).Maybe() + + gasPriceEstimator.On("GetGasPrice", mock.Anything).Return(gasPrice, nil) + pUSD := ccipcalc.CalculateUsdPerUnitGas(gasPrice, val1e18(tokenPrices[0])) + gasPriceEstimator.On("DenoteInUSD", mock.Anything, mock.Anything).Return(pUSD, nil) + + destPriceReg := ccipdatamocks.NewPriceRegistryReader(t) + destPriceReg.On("GetTokensDecimals", mock.Anything, laneTokens).Return(laneTokenDecimals, nil).Maybe() + destPriceReg.On("GetFeeTokens", mock.Anything).Return(feeTokens, nil).Maybe() + + priceService := NewPriceService( + lggr, + orm, + jobId, + destChainSelector, + sourceChainSelector, + tokens[0], + priceGetter, + offRampReader, + ).(*priceService) + + updateInterval := 2000 * time.Millisecond + cleanupInterval := 3000 * time.Millisecond + + // run write task every 2 second + priceService.updateInterval = updateInterval + // run cleanup every 3 seconds + priceService.cleanupInterval = cleanupInterval + // expire all prices during every cleanup + priceService.priceExpireSec = 0 + + // initially, db is empty + assert.NoError(t, checkResultLen(t, priceService, destChainSelector, 0, 0)) + + // starts PriceService in the background + assert.NoError(t, priceService.Start(ctx)) + + // setting dynamicConfig triggers initial price update + err := priceService.UpdateDynamicConfig(ctx, gasPriceEstimator, destPriceReg) + assert.NoError(t, err) + assert.NoError(t, checkResultLen(t, priceService, destChainSelector, 1, len(laneTokens))) + + // eventually prices will be cleaned + assert.Eventually(t, func() bool { + err := checkResultLen(t, priceService, destChainSelector, 0, 0) + return err == nil + }, testutils.WaitTimeout(t), testutils.TestInterval) + + // then prices will be updated again + assert.Eventually(t, func() bool { + err := checkResultLen(t, priceService, destChainSelector, 1, len(laneTokens)) + return err == nil + }, testutils.WaitTimeout(t), testutils.TestInterval) + + assert.NoError(t, priceService.Close()) + assert.NoError(t, priceService.runCleanup(ctx)) + + // after stopping PriceService and runCleanup, no more updates are inserted + for i := 0; i < 5; i++ { + time.Sleep(time.Second) + assert.NoError(t, checkResultLen(t, priceService, destChainSelector, 0, 0)) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/logpollerutil/filters.go b/core/services/ocr2/plugins/ccip/internal/logpollerutil/filters.go new file mode 100644 index 0000000000..e42dd8c154 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/logpollerutil/filters.go @@ -0,0 +1,73 @@ +package logpollerutil + +import ( + "context" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" +) + +func RegisterLpFilters(lp logpoller.LogPoller, filters []logpoller.Filter) error { + for _, lpFilter := range filters { + if filterContainsZeroAddress(lpFilter.Addresses) { + continue + } + // FIXME Dim pgOpts removed from LogPoller + if err := lp.RegisterFilter(context.Background(), lpFilter); err != nil { + return err + } + } + return nil +} + +func UnregisterLpFilters(lp logpoller.LogPoller, filters []logpoller.Filter) error { + for _, lpFilter := range filters { + if filterContainsZeroAddress(lpFilter.Addresses) { + continue + } + // FIXME Dim pgOpts removed from LogPoller + if err := lp.UnregisterFilter(context.Background(), lpFilter.Name); err != nil { + return err + } + } + return nil +} + +func FiltersDiff(filtersBefore, filtersNow []logpoller.Filter) (created, deleted []logpoller.Filter) { + created = make([]logpoller.Filter, 0, len(filtersNow)) + deleted = make([]logpoller.Filter, 0, len(filtersBefore)) + + for _, f := range filtersNow { + if !containsFilter(filtersBefore, f) { + created = append(created, f) + } + } + + for _, f := range filtersBefore { + if !containsFilter(filtersNow, f) { + deleted = append(deleted, f) + } + } + + return created, deleted +} + +func containsFilter(filters []logpoller.Filter, f logpoller.Filter) bool { + for _, existing := range filters { + if existing.Name == f.Name { + return true + } + } + return false +} + +func filterContainsZeroAddress(addrs []common.Address) bool { + for _, addr := range addrs { + if addr == utils.ZeroAddress { + return true + } + } + return false +} diff --git a/core/services/ocr2/plugins/ccip/internal/logpollerutil/filters_test.go b/core/services/ocr2/plugins/ccip/internal/logpollerutil/filters_test.go new file mode 100644 index 0000000000..9ea08ec142 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/logpollerutil/filters_test.go @@ -0,0 +1,156 @@ +package logpollerutil + +import ( + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" +) + +func Test_FiltersDiff(t *testing.T) { + type args struct { + filtersBefore []logpoller.Filter + filtersNow []logpoller.Filter + } + tests := []struct { + name string + args args + wantCreated []logpoller.Filter + wantDeleted []logpoller.Filter + }{ + { + name: "no diff, both empty", + args: args{ + filtersBefore: []logpoller.Filter{}, + filtersNow: []logpoller.Filter{}, + }, + wantCreated: []logpoller.Filter{}, + wantDeleted: []logpoller.Filter{}, + }, + { + name: "no diff, both non-empty", + args: args{ + filtersBefore: []logpoller.Filter{{Name: "a"}}, + filtersNow: []logpoller.Filter{{Name: "a"}}, + }, + wantCreated: []logpoller.Filter{}, + wantDeleted: []logpoller.Filter{}, + }, + { + name: "no diff, only name matters", + args: args{ + filtersBefore: []logpoller.Filter{{Name: "a", Retention: time.Minute}}, + filtersNow: []logpoller.Filter{{Name: "a", Retention: time.Second}}, + }, + wantCreated: []logpoller.Filter{}, + wantDeleted: []logpoller.Filter{}, + }, + { + name: "diff for both created and deleted", + args: args{ + filtersBefore: []logpoller.Filter{{Name: "e"}, {Name: "a"}, {Name: "b"}}, + filtersNow: []logpoller.Filter{{Name: "a"}, {Name: "c"}, {Name: "d"}}, + }, + wantCreated: []logpoller.Filter{{Name: "c"}, {Name: "d"}}, + wantDeleted: []logpoller.Filter{{Name: "e"}, {Name: "b"}}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotCreated, gotDeleted := FiltersDiff(tt.args.filtersBefore, tt.args.filtersNow) + assert.Equalf(t, tt.wantCreated, gotCreated, "filtersDiff(%v, %v)", tt.args.filtersBefore, tt.args.filtersNow) + assert.Equalf(t, tt.wantDeleted, gotDeleted, "filtersDiff(%v, %v)", tt.args.filtersBefore, tt.args.filtersNow) + }) + } +} + +func Test_filterContainsZeroAddress(t *testing.T) { + type args struct { + addrs []common.Address + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "non-zero addrs", + args: args{ + addrs: []common.Address{ + common.HexToAddress("1"), + common.HexToAddress("2"), + common.HexToAddress("3"), + }, + }, + want: false, + }, + { + name: "empty", + args: args{addrs: []common.Address{}}, + want: false, + }, + { + name: "zero addr", + args: args{ + addrs: []common.Address{ + common.HexToAddress("1"), + common.HexToAddress("0"), + common.HexToAddress("2"), + common.HexToAddress("3"), + }, + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, filterContainsZeroAddress(tt.args.addrs), "filterContainsZeroAddress(%v)", tt.args.addrs) + }) + } +} + +func Test_containsFilter(t *testing.T) { + type args struct { + filters []logpoller.Filter + f logpoller.Filter + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "empty", + args: args{ + filters: []logpoller.Filter{}, + f: logpoller.Filter{}, + }, + want: false, + }, + { + name: "contains", + args: args{ + filters: []logpoller.Filter{{Name: "a"}, {Name: "b"}}, + f: logpoller.Filter{Name: "b"}, + }, + want: true, + }, + { + name: "does not contain", + args: args{ + filters: []logpoller.Filter{{Name: "a"}, {Name: "b"}}, + f: logpoller.Filter{Name: "c"}, + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, + containsFilter(tt.args.filters, tt.args.f), "containsFilter(%v, %v)", tt.args.filters, tt.args.f) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/observability/commit_store.go b/core/services/ocr2/plugins/ccip/internal/observability/commit_store.go new file mode 100644 index 0000000000..6a1fb48f49 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/observability/commit_store.go @@ -0,0 +1,75 @@ +package observability + +import ( + "context" + "time" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +type ObservedCommitStoreReader struct { + ccipdata.CommitStoreReader + metric metricDetails +} + +func NewObservedCommitStoreReader(origin ccipdata.CommitStoreReader, chainID int64, pluginName string) *ObservedCommitStoreReader { + return &ObservedCommitStoreReader{ + CommitStoreReader: origin, + metric: metricDetails{ + interactionDuration: readerHistogram, + resultSetSize: readerDatasetSize, + pluginName: pluginName, + readerName: "CommitStoreReader", + chainId: chainID, + }, + } +} + +func (o *ObservedCommitStoreReader) GetExpectedNextSequenceNumber(context context.Context) (uint64, error) { + return withObservedInteraction(o.metric, "GetExpectedNextSequenceNumber", func() (uint64, error) { + return o.CommitStoreReader.GetExpectedNextSequenceNumber(context) + }) +} + +func (o *ObservedCommitStoreReader) GetLatestPriceEpochAndRound(context context.Context) (uint64, error) { + return withObservedInteraction(o.metric, "GetLatestPriceEpochAndRound", func() (uint64, error) { + return o.CommitStoreReader.GetLatestPriceEpochAndRound(context) + }) +} + +func (o *ObservedCommitStoreReader) GetCommitReportMatchingSeqNum(ctx context.Context, seqNum uint64, confs int) ([]cciptypes.CommitStoreReportWithTxMeta, error) { + return withObservedInteractionAndResults(o.metric, "GetCommitReportMatchingSeqNum", func() ([]cciptypes.CommitStoreReportWithTxMeta, error) { + return o.CommitStoreReader.GetCommitReportMatchingSeqNum(ctx, seqNum, confs) + }) +} + +func (o *ObservedCommitStoreReader) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confs int) ([]cciptypes.CommitStoreReportWithTxMeta, error) { + return withObservedInteractionAndResults(o.metric, "GetAcceptedCommitReportsGteTimestamp", func() ([]cciptypes.CommitStoreReportWithTxMeta, error) { + return o.CommitStoreReader.GetAcceptedCommitReportsGteTimestamp(ctx, ts, confs) + }) +} + +func (o *ObservedCommitStoreReader) IsDown(ctx context.Context) (bool, error) { + return withObservedInteraction(o.metric, "IsDown", func() (bool, error) { + return o.CommitStoreReader.IsDown(ctx) + }) +} + +func (o *ObservedCommitStoreReader) IsBlessed(ctx context.Context, root [32]byte) (bool, error) { + return withObservedInteraction(o.metric, "IsBlessed", func() (bool, error) { + return o.CommitStoreReader.IsBlessed(ctx, root) + }) +} + +func (o *ObservedCommitStoreReader) VerifyExecutionReport(ctx context.Context, report cciptypes.ExecReport) (bool, error) { + return withObservedInteraction(o.metric, "VerifyExecutionReport", func() (bool, error) { + return o.CommitStoreReader.VerifyExecutionReport(ctx, report) + }) +} + +func (o *ObservedCommitStoreReader) GetCommitStoreStaticConfig(ctx context.Context) (cciptypes.CommitStoreStaticConfig, error) { + return withObservedInteraction(o.metric, "GetCommitStoreStaticConfig", func() (cciptypes.CommitStoreStaticConfig, error) { + return o.CommitStoreReader.GetCommitStoreStaticConfig(ctx) + }) +} diff --git a/core/services/ocr2/plugins/ccip/internal/observability/metrics.go b/core/services/ocr2/plugins/ccip/internal/observability/metrics.go new file mode 100644 index 0000000000..9e161fdd9a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/observability/metrics.go @@ -0,0 +1,75 @@ +package observability + +import ( + "strconv" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +var ( + latencyBuckets = []float64{ + float64(10 * time.Millisecond), + float64(25 * time.Millisecond), + float64(50 * time.Millisecond), + float64(75 * time.Millisecond), + float64(100 * time.Millisecond), + float64(200 * time.Millisecond), + float64(300 * time.Millisecond), + float64(400 * time.Millisecond), + float64(500 * time.Millisecond), + float64(750 * time.Millisecond), + float64(1 * time.Second), + float64(2 * time.Second), + float64(3 * time.Second), + float64(4 * time.Second), + } + labels = []string{"evmChainID", "plugin", "reader", "function", "success"} + readerHistogram = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "ccip_reader_duration", + Help: "Duration of calls to Reader instance", + Buckets: latencyBuckets, + }, labels) + readerDatasetSize = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "ccip_reader_dataset_size", + Help: "Size of the dataset returned from the Reader instance", + }, labels) +) + +type metricDetails struct { + interactionDuration *prometheus.HistogramVec + resultSetSize *prometheus.GaugeVec + pluginName string + readerName string + chainId int64 +} + +func withObservedInteraction[T any](metric metricDetails, function string, f func() (T, error)) (T, error) { + contractExecutionStarted := time.Now() + value, err := f() + metric.interactionDuration. + WithLabelValues( + strconv.FormatInt(metric.chainId, 10), + metric.pluginName, + metric.readerName, + function, + strconv.FormatBool(err == nil), + ). + Observe(float64(time.Since(contractExecutionStarted))) + return value, err +} + +func withObservedInteractionAndResults[T any](metric metricDetails, function string, f func() ([]T, error)) ([]T, error) { + results, err := withObservedInteraction(metric, function, f) + if err == nil { + metric.resultSetSize.WithLabelValues( + strconv.FormatInt(metric.chainId, 10), + metric.pluginName, + metric.readerName, + function, + strconv.FormatBool(err == nil), + ).Set(float64(len(results))) + } + return results, err +} diff --git a/core/services/ocr2/plugins/ccip/internal/observability/metrics_test.go b/core/services/ocr2/plugins/ccip/internal/observability/metrics_test.go new file mode 100644 index 0000000000..3d84acf961 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/observability/metrics_test.go @@ -0,0 +1,87 @@ +package observability + +import ( + "fmt" + "testing" + + "github.com/prometheus/client_golang/prometheus" + io_prometheus_client "github.com/prometheus/client_model/go" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + ccipdatamocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" +) + +func TestProperLabelsArePassed(t *testing.T) { + histogram := readerHistogram + successCounter := 10 + failedCounter := 5 + + details := metricDetails{ + interactionDuration: histogram, + pluginName: "plugin", + readerName: "reader", + chainId: 123, + } + + for i := 0; i < successCounter; i++ { + _, err := withObservedInteraction[string](details, "successFun", successfulContract) + require.NoError(t, err) + } + + for i := 0; i < failedCounter; i++ { + _, err := withObservedInteraction[string](details, "failedFun", failedContract) + require.Error(t, err) + } + + assert.Equal(t, successCounter, counterFromHistogramByLabels(t, histogram, "123", "plugin", "reader", "successFun", "true")) + assert.Equal(t, failedCounter, counterFromHistogramByLabels(t, histogram, "123", "plugin", "reader", "failedFun", "false")) + + assert.Equal(t, 0, counterFromHistogramByLabels(t, histogram, "123", "plugin", "reader", "failedFun", "true")) + assert.Equal(t, 0, counterFromHistogramByLabels(t, histogram, "123", "plugin", "reader", "successFun", "false")) +} + +func TestMetricsSendFromContractDirectly(t *testing.T) { + expectedCounter := 4 + ctx := testutils.Context(t) + chainId := int64(420) + + mockedOfframp := ccipdatamocks.NewOffRampReader(t) + mockedOfframp.On("GetTokens", ctx).Return(cciptypes.OffRampTokens{}, fmt.Errorf("execution error")) + + observedOfframp := NewObservedOffRampReader(mockedOfframp, chainId, "plugin") + + for i := 0; i < expectedCounter; i++ { + _, _ = observedOfframp.GetTokens(ctx) + } + + assert.Equal(t, expectedCounter, counterFromHistogramByLabels(t, observedOfframp.metric.interactionDuration, "420", "plugin", "OffRampReader", "GetTokens", "false")) + assert.Equal(t, 0, counterFromHistogramByLabels(t, observedOfframp.metric.interactionDuration, "420", "plugin", "OffRampReader", "GetPoolByDestToken", "false")) + assert.Equal(t, 0, counterFromHistogramByLabels(t, observedOfframp.metric.interactionDuration, "420", "plugin", "OffRampReader", "GetPoolByDestToken", "true")) +} + +func counterFromHistogramByLabels(t *testing.T, histogramVec *prometheus.HistogramVec, labels ...string) int { + observer, err := histogramVec.GetMetricWithLabelValues(labels...) + require.NoError(t, err) + + metricCh := make(chan prometheus.Metric, 1) + observer.(prometheus.Histogram).Collect(metricCh) + close(metricCh) + + metric := <-metricCh + pb := &io_prometheus_client.Metric{} + err = metric.Write(pb) + require.NoError(t, err) + + return int(pb.GetHistogram().GetSampleCount()) +} + +func successfulContract() (string, error) { + return "success", nil +} + +func failedContract() (string, error) { + return "", fmt.Errorf("just error") +} diff --git a/core/services/ocr2/plugins/ccip/internal/observability/offramp.go b/core/services/ocr2/plugins/ccip/internal/observability/offramp.go new file mode 100644 index 0000000000..b426bc8c91 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/observability/offramp.go @@ -0,0 +1,69 @@ +package observability + +import ( + "context" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +type ObservedOffRampReader struct { + ccipdata.OffRampReader + metric metricDetails +} + +func NewObservedOffRampReader(origin ccipdata.OffRampReader, chainID int64, pluginName string) *ObservedOffRampReader { + return &ObservedOffRampReader{ + OffRampReader: origin, + metric: metricDetails{ + interactionDuration: readerHistogram, + resultSetSize: readerDatasetSize, + pluginName: pluginName, + readerName: "OffRampReader", + chainId: chainID, + }, + } +} + +func (o *ObservedOffRampReader) GetExecutionStateChangesBetweenSeqNums(ctx context.Context, seqNumMin, seqNumMax uint64, confs int) ([]cciptypes.ExecutionStateChangedWithTxMeta, error) { + return withObservedInteraction(o.metric, "GetExecutionStateChangesBetweenSeqNums", func() ([]cciptypes.ExecutionStateChangedWithTxMeta, error) { + return o.OffRampReader.GetExecutionStateChangesBetweenSeqNums(ctx, seqNumMin, seqNumMax, confs) + }) +} + +func (o *ObservedOffRampReader) CurrentRateLimiterState(ctx context.Context) (cciptypes.TokenBucketRateLimit, error) { + return withObservedInteraction(o.metric, "CurrentRateLimiterState", func() (cciptypes.TokenBucketRateLimit, error) { + return o.OffRampReader.CurrentRateLimiterState(ctx) + }) +} + +func (o *ObservedOffRampReader) GetExecutionState(ctx context.Context, sequenceNumber uint64) (uint8, error) { + return withObservedInteraction(o.metric, "GetExecutionState", func() (uint8, error) { + return o.OffRampReader.GetExecutionState(ctx, sequenceNumber) + }) +} + +func (o *ObservedOffRampReader) GetStaticConfig(ctx context.Context) (cciptypes.OffRampStaticConfig, error) { + return withObservedInteraction(o.metric, "GetStaticConfig", func() (cciptypes.OffRampStaticConfig, error) { + return o.OffRampReader.GetStaticConfig(ctx) + }) +} + +func (o *ObservedOffRampReader) GetSourceToDestTokensMapping(ctx context.Context) (map[cciptypes.Address]cciptypes.Address, error) { + return withObservedInteraction(o.metric, "GetSourceToDestTokensMapping", func() (map[cciptypes.Address]cciptypes.Address, error) { + return o.OffRampReader.GetSourceToDestTokensMapping(ctx) + }) +} + +func (o *ObservedOffRampReader) GetTokens(ctx context.Context) (cciptypes.OffRampTokens, error) { + return withObservedInteraction(o.metric, "GetTokens", func() (cciptypes.OffRampTokens, error) { + return o.OffRampReader.GetTokens(ctx) + }) +} + +func (o *ObservedOffRampReader) GetSendersNonce(ctx context.Context, senders []cciptypes.Address) (map[cciptypes.Address]uint64, error) { + return withObservedInteraction(o.metric, "ListSenderNonces", func() (map[cciptypes.Address]uint64, error) { + return o.OffRampReader.ListSenderNonces(ctx, senders) + }) +} diff --git a/core/services/ocr2/plugins/ccip/internal/observability/onramp.go b/core/services/ocr2/plugins/ccip/internal/observability/onramp.go new file mode 100644 index 0000000000..b167bd57b0 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/observability/onramp.go @@ -0,0 +1,63 @@ +package observability + +import ( + "context" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +type ObservedOnRampReader struct { + ccipdata.OnRampReader + metric metricDetails +} + +func NewObservedOnRampReader(origin ccipdata.OnRampReader, chainID int64, pluginName string) *ObservedOnRampReader { + return &ObservedOnRampReader{ + OnRampReader: origin, + metric: metricDetails{ + interactionDuration: readerHistogram, + resultSetSize: readerDatasetSize, + pluginName: pluginName, + readerName: "OnRampReader", + chainId: chainID, + }, + } +} + +func (o ObservedOnRampReader) GetSendRequestsBetweenSeqNums(ctx context.Context, seqNumMin, seqNumMax uint64, finalized bool) ([]cciptypes.EVM2EVMMessageWithTxMeta, error) { + return withObservedInteractionAndResults(o.metric, "GetSendRequestsBetweenSeqNums", func() ([]cciptypes.EVM2EVMMessageWithTxMeta, error) { + return o.OnRampReader.GetSendRequestsBetweenSeqNums(ctx, seqNumMin, seqNumMax, finalized) + }) +} + +func (o ObservedOnRampReader) RouterAddress(ctx context.Context) (cciptypes.Address, error) { + return withObservedInteraction(o.metric, "RouterAddress", func() (cciptypes.Address, error) { + return o.OnRampReader.RouterAddress(ctx) + }) +} + +func (o ObservedOnRampReader) GetDynamicConfig(ctx context.Context) (cciptypes.OnRampDynamicConfig, error) { + return withObservedInteraction(o.metric, "GetDynamicConfig", func() (cciptypes.OnRampDynamicConfig, error) { + return o.OnRampReader.GetDynamicConfig(ctx) + }) +} + +func (o ObservedOnRampReader) IsSourceCursed(ctx context.Context) (bool, error) { + return withObservedInteraction(o.metric, "IsSourceCursed", func() (bool, error) { + return o.OnRampReader.IsSourceCursed(ctx) + }) +} + +func (o ObservedOnRampReader) IsSourceChainHealthy(ctx context.Context) (bool, error) { + return withObservedInteraction(o.metric, "IsSourceChainHealthy", func() (bool, error) { + return o.OnRampReader.IsSourceChainHealthy(ctx) + }) +} + +func (o ObservedOnRampReader) SourcePriceRegistryAddress(ctx context.Context) (cciptypes.Address, error) { + return withObservedInteraction(o.metric, "SourcePriceRegistryAddress", func() (cciptypes.Address, error) { + return o.OnRampReader.SourcePriceRegistryAddress(ctx) + }) +} diff --git a/core/services/ocr2/plugins/ccip/internal/observability/onramp_observed_test.go b/core/services/ocr2/plugins/ccip/internal/observability/onramp_observed_test.go new file mode 100644 index 0000000000..1918f632b9 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/observability/onramp_observed_test.go @@ -0,0 +1,155 @@ +package observability + +import ( + "fmt" + "reflect" + "runtime" + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" +) + +type MethodCall struct { + MethodName string + Arguments []interface{} + Returns []interface{} +} + +// The class expected to override the observed methods. +const expectedWrapper = "core/services/ocr2/plugins/ccip/internal/observability.ObservedOnRampReader" + +// TestOnRampObservedMethods tests that all methods of OnRampReader are observed by a wrapper. +// It uses the runtime to detect if the call stack contains the wrapper class. +func TestOnRampObservedMethods(t *testing.T) { + // Methods not expected to be observed. + // Add a method name here to exclude it from the test. + excludedMethods := []string{ + "Address", + "Close", + } + + // Defines the overridden method calls to test. + // Not defining a non-excluded method here will cause the test to fail with an explicit error. + methodCalls := make(map[string]MethodCall) + methodCalls["GetDynamicConfig"] = MethodCall{ + MethodName: "GetDynamicConfig", + Arguments: []interface{}{testutils.Context(t)}, + Returns: []interface{}{cciptypes.OnRampDynamicConfig{}, nil}, + } + methodCalls["GetSendRequestsBetweenSeqNums"] = MethodCall{ + MethodName: "GetSendRequestsBetweenSeqNums", + Arguments: []interface{}{testutils.Context(t), uint64(0), uint64(100), true}, + Returns: []interface{}{nil, nil}, + } + methodCalls["IsSourceChainHealthy"] = MethodCall{ + MethodName: "IsSourceChainHealthy", + Arguments: []interface{}{testutils.Context(t)}, + Returns: []interface{}{false, nil}, + } + methodCalls["IsSourceCursed"] = MethodCall{ + MethodName: "IsSourceCursed", + Arguments: []interface{}{testutils.Context(t)}, + Returns: []interface{}{false, nil}, + } + methodCalls["RouterAddress"] = MethodCall{ + MethodName: "RouterAddress", + Arguments: []interface{}{testutils.Context(t)}, + Returns: []interface{}{cciptypes.Address("0x0"), nil}, + } + methodCalls["SourcePriceRegistryAddress"] = MethodCall{ + MethodName: "SourcePriceRegistryAddress", + Arguments: []interface{}{testutils.Context(t)}, + Returns: []interface{}{cciptypes.Address("0x0"), nil}, + } + + // Test each method defined in the embedded type. + observed, reader := buildReader(t) + observedType := reflect.TypeOf(observed) + for i := 0; i < observedType.NumMethod(); i++ { + method := observedType.Method(i) + testMethod(t, method, methodCalls, excludedMethods, reader, observed) + } +} + +func testMethod(t *testing.T, method reflect.Method, methodCalls map[string]MethodCall, excludedMethods []string, reader *mocks.OnRampReader, observed ObservedOnRampReader) { + t.Run(fmt.Sprintf("observability_wrapper_%s", method.Name), func(t *testing.T) { + // Skip excluded methods. + for _, em := range excludedMethods { + if method.Name == em { + // Skipping ignore method (not an error). + return + } + } + + // Retrieve method call from definition (fail if not present). + mc := methodCalls[method.Name] + if mc.MethodName == "" { + assert.Fail(t, fmt.Sprintf("method %s not defined in methodCalls, please define it or exclude it.", method.Name)) + return + } + + assertCallByWrapper(t, reader, mc) + + // Perform call on observed object. + callParams := buildCallParams(mc) + methodc := reflect.ValueOf(&observed).MethodByName(mc.MethodName) + methodc.Call(callParams) + }) +} + +// Set the mock to fail if not called by the wrapper. +func assertCallByWrapper(t *testing.T, reader *mocks.OnRampReader, mc MethodCall) { + reader.On(mc.MethodName, mc.Arguments...).Maybe().Return(mc.Returns...).Run(func(args mock.Arguments) { + var i = 0 + var pc uintptr + var ok = true + for ok { + pc, _, _, ok = runtime.Caller(i) + f := runtime.FuncForPC(pc) + if strings.Contains(f.Name(), expectedWrapper) { + // Found the expected wrapper in the call stack. + return + } + i++ + } + assert.Fail(t, fmt.Sprintf("method %s not observed by wrapper. Please implement the method or add it to the excluded list.", mc.MethodName)) + }) +} + +func buildCallParams(mc MethodCall) []reflect.Value { + callParams := make([]reflect.Value, len(mc.Arguments)) + for i, arg := range mc.Arguments { + callParams[i] = reflect.ValueOf(arg) + } + return callParams +} + +// Build a mock reader and an observed wrapper to be used in the tests. +func buildReader(t *testing.T) (ObservedOnRampReader, *mocks.OnRampReader) { + labels = []string{"evmChainID", "plugin", "reader", "function", "success"} + ph := promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "test_histogram", + }, labels) + pg := promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "test_gauge", + }, labels) + metric := metricDetails{ + interactionDuration: ph, + resultSetSize: pg, + pluginName: "test plugin", + readerName: "test reader", + chainId: 1337, + } + reader := mocks.NewOnRampReader(t) + observed := ObservedOnRampReader{reader, metric} + return observed, reader +} diff --git a/core/services/ocr2/plugins/ccip/internal/observability/price_registry.go b/core/services/ocr2/plugins/ccip/internal/observability/price_registry.go new file mode 100644 index 0000000000..f5b87686d3 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/observability/price_registry.go @@ -0,0 +1,64 @@ +package observability + +import ( + "context" + "time" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" +) + +type ObservedPriceRegistryReader struct { + ccipdata.PriceRegistryReader + metric metricDetails +} + +func NewPriceRegistryReader(origin ccipdata.PriceRegistryReader, chainID int64, pluginName string) *ObservedPriceRegistryReader { + return &ObservedPriceRegistryReader{ + PriceRegistryReader: origin, + metric: metricDetails{ + interactionDuration: readerHistogram, + resultSetSize: readerDatasetSize, + pluginName: pluginName, + readerName: "PriceRegistryReader", + chainId: chainID, + }, + } +} + +func (o *ObservedPriceRegistryReader) GetTokenPriceUpdatesCreatedAfter(ctx context.Context, ts time.Time, confs int) ([]cciptypes.TokenPriceUpdateWithTxMeta, error) { + return withObservedInteractionAndResults(o.metric, "GetTokenPriceUpdatesCreatedAfter", func() ([]cciptypes.TokenPriceUpdateWithTxMeta, error) { + return o.PriceRegistryReader.GetTokenPriceUpdatesCreatedAfter(ctx, ts, confs) + }) +} + +func (o *ObservedPriceRegistryReader) GetGasPriceUpdatesCreatedAfter(ctx context.Context, chainSelector uint64, ts time.Time, confs int) ([]cciptypes.GasPriceUpdateWithTxMeta, error) { + return withObservedInteractionAndResults(o.metric, "GetGasPriceUpdatesCreatedAfter", func() ([]cciptypes.GasPriceUpdateWithTxMeta, error) { + return o.PriceRegistryReader.GetGasPriceUpdatesCreatedAfter(ctx, chainSelector, ts, confs) + }) +} + +func (o *ObservedPriceRegistryReader) GetAllGasPriceUpdatesCreatedAfter(ctx context.Context, ts time.Time, confs int) ([]cciptypes.GasPriceUpdateWithTxMeta, error) { + return withObservedInteractionAndResults(o.metric, "GetAllGasPriceUpdatesCreatedAfter", func() ([]cciptypes.GasPriceUpdateWithTxMeta, error) { + return o.PriceRegistryReader.GetAllGasPriceUpdatesCreatedAfter(ctx, ts, confs) + }) +} + +func (o *ObservedPriceRegistryReader) GetFeeTokens(ctx context.Context) ([]cciptypes.Address, error) { + return withObservedInteraction(o.metric, "GetFeeTokens", func() ([]cciptypes.Address, error) { + return o.PriceRegistryReader.GetFeeTokens(ctx) + }) +} + +func (o *ObservedPriceRegistryReader) GetTokenPrices(ctx context.Context, wantedTokens []cciptypes.Address) ([]cciptypes.TokenPriceUpdate, error) { + return withObservedInteractionAndResults(o.metric, "GetTokenPrices", func() ([]cciptypes.TokenPriceUpdate, error) { + return o.PriceRegistryReader.GetTokenPrices(ctx, wantedTokens) + }) +} + +func (o *ObservedPriceRegistryReader) GetTokensDecimals(ctx context.Context, tokenAddresses []cciptypes.Address) ([]uint8, error) { + return withObservedInteractionAndResults(o.metric, "GetTokensDecimals", func() ([]uint8, error) { + return o.PriceRegistryReader.GetTokensDecimals(ctx, tokenAddresses) + }) +} diff --git a/core/services/ocr2/plugins/ccip/internal/oraclelib/backfilled_oracle.go b/core/services/ocr2/plugins/ccip/internal/oraclelib/backfilled_oracle.go new file mode 100644 index 0000000000..d2851e3a07 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/oraclelib/backfilled_oracle.go @@ -0,0 +1,218 @@ +package oraclelib + +import ( + "context" + "sync" + "sync/atomic" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/services" + + "go.uber.org/multierr" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" +) + +type BackfilledOracle struct { + srcStartBlock, dstStartBlock uint64 + oracleStarted atomic.Bool + cancelFn context.CancelFunc + src, dst logpoller.LogPoller + oracle job.ServiceCtx + lggr logger.Logger +} + +func NewBackfilledOracle(lggr logger.Logger, src, dst logpoller.LogPoller, srcStartBlock, dstStartBlock uint64, oracle job.ServiceCtx) *BackfilledOracle { + return &BackfilledOracle{ + srcStartBlock: srcStartBlock, + dstStartBlock: dstStartBlock, + oracleStarted: atomic.Bool{}, + cancelFn: nil, + src: src, + dst: dst, + oracle: oracle, + lggr: lggr, + } +} + +func (r *BackfilledOracle) Start(_ context.Context) error { + go r.Run() + return nil +} + +func (r *BackfilledOracle) IsRunning() bool { + return r.oracleStarted.Load() +} + +func (r *BackfilledOracle) Run() { + ctx, cancelFn := context.WithCancel(context.Background()) + r.cancelFn = cancelFn + var err error + var errMu sync.Mutex + var wg sync.WaitGroup + // Replay in parallel if both requested. + if r.srcStartBlock != 0 { + wg.Add(1) + go func() { + defer wg.Done() + s := time.Now() + r.lggr.Infow("start replaying src chain", "fromBlock", r.srcStartBlock) + srcReplayErr := r.src.Replay(ctx, int64(r.srcStartBlock)) + errMu.Lock() + err = multierr.Combine(err, srcReplayErr) + errMu.Unlock() + r.lggr.Infow("finished replaying src chain", "time", time.Since(s)) + }() + } + if r.dstStartBlock != 0 { + wg.Add(1) + go func() { + defer wg.Done() + s := time.Now() + r.lggr.Infow("start replaying dst chain", "fromBlock", r.dstStartBlock) + dstReplayErr := r.dst.Replay(ctx, int64(r.dstStartBlock)) + errMu.Lock() + err = multierr.Combine(err, dstReplayErr) + errMu.Unlock() + r.lggr.Infow("finished replaying dst chain", "time", time.Since(s)) + }() + } + wg.Wait() + if err != nil { + r.lggr.Criticalw("unexpected error replaying, continuing plugin boot without all the logs backfilled", "err", err) + } + if err := ctx.Err(); err != nil { + r.lggr.Errorw("context already cancelled", "err", err) + return + } + // Start oracle with all logs present from dstStartBlock on dst and + // all logs from srcStartBlock on src. + if err := r.oracle.Start(ctx); err != nil { + // Should never happen. + r.lggr.Errorw("unexpected error starting oracle", "err", err) + } else { + r.oracleStarted.Store(true) + } +} + +func (r *BackfilledOracle) Close() error { + if r.oracleStarted.Load() { + // If the oracle is running, it must be Closed/stopped + if err := r.oracle.Close(); err != nil { + r.lggr.Errorw("unexpected error stopping oracle", "err", err) + return err + } + // Flag the oracle as closed with our internal variable that keeps track + // of its state. This will allow to re-start the process + r.oracleStarted.Store(false) + } + if r.cancelFn != nil { + // This is useful to step the previous tasks that are spawned in + // parallel before starting the Oracle. This will use the context to + // signal them to exit immediately. + // + // It can be possible this is the only way to stop the Start() async + // flow, specially when the previusly task are running (the replays) and + // `oracleStarted` would be false in that example. Calling `cancelFn()` + // will stop the replays and will prevent the oracle to start + r.cancelFn() + } + return nil +} + +func NewChainAgnosticBackFilledOracle(lggr logger.Logger, srcProvider services.ServiceCtx, dstProvider services.ServiceCtx, oracle job.ServiceCtx) *ChainAgnosticBackFilledOracle { + return &ChainAgnosticBackFilledOracle{ + srcProvider: srcProvider, + dstProvider: dstProvider, + oracle: oracle, + lggr: lggr, + } +} + +type ChainAgnosticBackFilledOracle struct { + srcProvider services.ServiceCtx + dstProvider services.ServiceCtx + oracle job.ServiceCtx + lggr logger.Logger + oracleStarted atomic.Bool + cancelFn context.CancelFunc +} + +func (r *ChainAgnosticBackFilledOracle) Start(_ context.Context) error { + go r.run() + return nil +} + +func (r *ChainAgnosticBackFilledOracle) run() { + ctx, cancelFn := context.WithCancel(context.Background()) + r.cancelFn = cancelFn + var err error + var errMu sync.Mutex + var wg sync.WaitGroup + // Replay in parallel if both requested. + wg.Add(1) + go func() { + defer wg.Done() + s := time.Now() + srcReplayErr := r.srcProvider.Start(ctx) + errMu.Lock() + err = multierr.Combine(err, srcReplayErr) + errMu.Unlock() + r.lggr.Infow("finished replaying src chain", "time", time.Since(s)) + }() + + wg.Add(1) + go func() { + defer wg.Done() + s := time.Now() + dstReplayErr := r.dstProvider.Start(ctx) + errMu.Lock() + err = multierr.Combine(err, dstReplayErr) + errMu.Unlock() + r.lggr.Infow("finished replaying dst chain", "time", time.Since(s)) + }() + + wg.Wait() + if err != nil { + r.lggr.Criticalw("unexpected error replaying, continuing plugin boot without all the logs backfilled", "err", err) + } + if err := ctx.Err(); err != nil { + r.lggr.Errorw("context already cancelled", "err", err) + } + // Start oracle with all logs present from dstStartBlock on dst and + // all logs from srcStartBlock on src. + if err := r.oracle.Start(ctx); err != nil { + // Should never happen. + r.lggr.Errorw("unexpected error starting oracle", "err", err) + } else { + r.oracleStarted.Store(true) + } +} + +func (r *ChainAgnosticBackFilledOracle) Close() error { + if r.oracleStarted.Load() { + // If the oracle is running, it must be Closed/stopped + // TODO: Close should be safe to call in either case? + if err := r.oracle.Close(); err != nil { + r.lggr.Errorw("unexpected error stopping oracle", "err", err) + return err + } + // Flag the oracle as closed with our internal variable that keeps track + // of its state. This will allow to re-start the process + r.oracleStarted.Store(false) + } + if r.cancelFn != nil { + // This is useful to step the previous tasks that are spawned in + // parallel before starting the Oracle. This will use the context to + // signal them to exit immediately. + // + // It can be possible this is the only way to stop the Start() async + // flow, specially when the previusly task are running (the replays) and + // `oracleStarted` would be false in that example. Calling `cancelFn()` + // will stop the replays and will prevent the oracle to start + r.cancelFn() + } + return nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/oraclelib/backfilled_oracle_test.go b/core/services/ocr2/plugins/ccip/internal/oraclelib/backfilled_oracle_test.go new file mode 100644 index 0000000000..6db1ebbadd --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/oraclelib/backfilled_oracle_test.go @@ -0,0 +1,56 @@ +package oraclelib + +import ( + "testing" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/logger" + jobmocks "github.com/smartcontractkit/chainlink/v2/core/services/job/mocks" +) + +func TestBackfilledOracle(t *testing.T) { + // First scenario: Start() fails, check that all Replay are being called. + lp1 := lpmocks.NewLogPoller(t) + lp2 := lpmocks.NewLogPoller(t) + lp1.On("Replay", mock.Anything, int64(1)).Return(nil) + lp2.On("Replay", mock.Anything, int64(2)).Return(nil) + oracle1 := jobmocks.NewServiceCtx(t) + oracle1.On("Start", mock.Anything).Return(errors.New("Failed to start")).Twice() + job := NewBackfilledOracle(logger.TestLogger(t), lp1, lp2, 1, 2, oracle1) + + job.Run() + assert.False(t, job.IsRunning()) + job.Run() + assert.False(t, job.IsRunning()) + + /// Start -> Stop -> Start + oracle2 := jobmocks.NewServiceCtx(t) + oracle2.On("Start", mock.Anything).Return(nil).Twice() + oracle2.On("Close").Return(nil).Once() + + job2 := NewBackfilledOracle(logger.TestLogger(t), lp1, lp2, 1, 2, oracle2) + job2.Run() + assert.True(t, job2.IsRunning()) + assert.Nil(t, job2.Close()) + assert.False(t, job2.IsRunning()) + assert.Nil(t, job2.Close()) + assert.False(t, job2.IsRunning()) + job2.Run() + assert.True(t, job2.IsRunning()) + + /// Replay fails, but it starts anyway + lp11 := lpmocks.NewLogPoller(t) + lp12 := lpmocks.NewLogPoller(t) + lp11.On("Replay", mock.Anything, int64(1)).Return(errors.New("Replay failed")).Once() + lp12.On("Replay", mock.Anything, int64(2)).Return(errors.New("Replay failed")).Once() + + oracle := jobmocks.NewServiceCtx(t) + oracle.On("Start", mock.Anything).Return(nil).Once() + job3 := NewBackfilledOracle(logger.NullLogger, lp11, lp12, 1, 2, oracle) + job3.Run() + assert.True(t, job3.IsRunning()) +} diff --git a/core/services/ocr2/plugins/ccip/internal/parseutil/bigint.go b/core/services/ocr2/plugins/ccip/internal/parseutil/bigint.go new file mode 100644 index 0000000000..48d0d26165 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/parseutil/bigint.go @@ -0,0 +1,44 @@ +package parseutil + +import ( + "math/big" + + "github.com/pkg/errors" + "github.com/shopspring/decimal" +) + +func ParseBigIntFromAny(val any) (*big.Int, error) { + if val == nil { + return nil, errors.Errorf("nil value passed") + } + + switch v := val.(type) { + case decimal.Decimal: + return ParseBigIntFromString(v.String()) + case *decimal.Decimal: + return ParseBigIntFromString(v.String()) + case *big.Int: + return v, nil + case string: + return ParseBigIntFromString(v) + case int: + return big.NewInt(int64(v)), nil + case int64: + return big.NewInt(v), nil + case float64: + i := new(big.Int) + big.NewFloat(v).Int(i) + return i, nil + default: + return nil, errors.Errorf("unsupported big int type %T", val) + } +} + +func ParseBigIntFromString(v string) (*big.Int, error) { + valBigInt, success := new(big.Int).SetString(v, 10) + if !success { + return nil, errors.Errorf("unable to convert to integer %s", v) + } + + return valBigInt, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/parseutil/bigint_test.go b/core/services/ocr2/plugins/ccip/internal/parseutil/bigint_test.go new file mode 100644 index 0000000000..cea2f8cc19 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/parseutil/bigint_test.go @@ -0,0 +1,42 @@ +package parseutil + +import ( + "math/big" + "testing" + + "github.com/shopspring/decimal" + "github.com/stretchr/testify/assert" +) + +func TestParseBigIntFromAny(t *testing.T) { + decimalVal := decimal.New(123, 0) + + testCases := []struct { + name string + val any + res *big.Int + expErr bool + }{ + {name: "nil", val: nil, expErr: true}, + {name: "string", val: "123", res: big.NewInt(123)}, + {name: "decimal", val: decimal.New(123, 0), res: big.NewInt(123)}, + {name: "decimal pointer", val: &decimalVal, res: big.NewInt(123)}, + {name: "int64", val: int64(123), res: big.NewInt(123)}, + {name: "int", val: 123, res: big.NewInt(123)}, + {name: "float", val: 123.12, res: big.NewInt(123)}, + {name: "uint8", val: uint8(12), expErr: true}, + {name: "struct", val: struct{ name string }{name: "asd"}, expErr: true}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := ParseBigIntFromAny(tc.val) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, tc.res, res) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/pricegetter/evm.go b/core/services/ocr2/plugins/ccip/internal/pricegetter/evm.go new file mode 100644 index 0000000000..ed54428bd9 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/pricegetter/evm.go @@ -0,0 +1,239 @@ +package pricegetter + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "strings" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/internal/gethwrappers2/generated/offchainaggregator" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +const decimalsMethodName = "decimals" +const latestRoundDataMethodName = "latestRoundData" + +func init() { + // Ensure existence of latestRoundData method on the Aggregator contract. + aggregatorABI, err := abi.JSON(strings.NewReader(offchainaggregator.OffchainAggregatorABI)) + if err != nil { + panic(err) + } + ensureMethodOnContract(aggregatorABI, decimalsMethodName) + ensureMethodOnContract(aggregatorABI, latestRoundDataMethodName) +} + +func ensureMethodOnContract(abi abi.ABI, methodName string) { + if _, ok := abi.Methods[methodName]; !ok { + panic(fmt.Errorf("method %s not found on ABI: %+v", methodName, abi.Methods)) + } +} + +type DynamicPriceGetterClient struct { + BatchCaller rpclib.EvmBatchCaller +} + +func NewDynamicPriceGetterClient(batchCaller rpclib.EvmBatchCaller) DynamicPriceGetterClient { + return DynamicPriceGetterClient{ + BatchCaller: batchCaller, + } +} + +type DynamicPriceGetter struct { + cfg config.DynamicPriceGetterConfig + evmClients map[uint64]DynamicPriceGetterClient + aggregatorAbi abi.ABI +} + +func NewDynamicPriceGetterConfig(configJson string) (config.DynamicPriceGetterConfig, error) { + priceGetterConfig := config.DynamicPriceGetterConfig{} + err := json.Unmarshal([]byte(configJson), &priceGetterConfig) + if err != nil { + return config.DynamicPriceGetterConfig{}, fmt.Errorf("parsing dynamic price getter config: %w", err) + } + err = priceGetterConfig.Validate() + if err != nil { + return config.DynamicPriceGetterConfig{}, fmt.Errorf("validating price getter config: %w", err) + } + return priceGetterConfig, nil +} + +// NewDynamicPriceGetter build a DynamicPriceGetter from a configuration and a map of chain ID to batch callers. +// A batch caller should be provided for all retrieved prices. +func NewDynamicPriceGetter(cfg config.DynamicPriceGetterConfig, evmClients map[uint64]DynamicPriceGetterClient) (*DynamicPriceGetter, error) { + if err := cfg.Validate(); err != nil { + return nil, fmt.Errorf("validating dynamic price getter config: %w", err) + } + aggregatorAbi, err := abi.JSON(strings.NewReader(offchainaggregator.OffchainAggregatorABI)) + if err != nil { + return nil, fmt.Errorf("parsing offchainaggregator abi: %w", err) + } + priceGetter := DynamicPriceGetter{cfg, evmClients, aggregatorAbi} + return &priceGetter, nil +} + +// FilterConfiguredTokens implements the PriceGetter interface. +// It filters a list of token addresses for only those that have a price resolution rule configured on the PriceGetterConfig +func (d *DynamicPriceGetter) FilterConfiguredTokens(ctx context.Context, tokens []cciptypes.Address) (configured []cciptypes.Address, unconfigured []cciptypes.Address, err error) { + configured = []cciptypes.Address{} + unconfigured = []cciptypes.Address{} + for _, tk := range tokens { + evmAddr, err := ccipcalc.GenericAddrToEvm(tk) + if err != nil { + return nil, nil, err + } + + if _, isAgg := d.cfg.AggregatorPrices[evmAddr]; isAgg { + configured = append(configured, tk) + } else if _, isStatic := d.cfg.StaticPrices[evmAddr]; isStatic { + configured = append(configured, tk) + } else { + unconfigured = append(unconfigured, tk) + } + } + return configured, unconfigured, nil +} + +// TokenPricesUSD implements the PriceGetter interface. +// It returns static prices stored in the price getter, and batch calls aggregators (one per chain) to retrieve aggregator-based prices. +func (d *DynamicPriceGetter) TokenPricesUSD(ctx context.Context, tokens []cciptypes.Address) (map[cciptypes.Address]*big.Int, error) { + prices, batchCallsPerChain, err := d.preparePricesAndBatchCallsPerChain(tokens) + if err != nil { + return nil, err + } + if err = d.performBatchCalls(ctx, batchCallsPerChain, prices); err != nil { + return nil, err + } + return prices, nil +} + +// performBatchCalls performs batch calls on all chains to retrieve token prices. +func (d *DynamicPriceGetter) performBatchCalls(ctx context.Context, batchCallsPerChain map[uint64]*batchCallsForChain, prices map[cciptypes.Address]*big.Int) error { + for chainID, batchCalls := range batchCallsPerChain { + if err := d.performBatchCall(ctx, chainID, batchCalls, prices); err != nil { + return err + } + } + return nil +} + +// performBatchCall performs a batch call on a given chain to retrieve token prices. +func (d *DynamicPriceGetter) performBatchCall(ctx context.Context, chainID uint64, batchCalls *batchCallsForChain, prices map[cciptypes.Address]*big.Int) error { + // Retrieve the EVM caller for the chain. + client, exists := d.evmClients[chainID] + if !exists { + return fmt.Errorf("evm caller for chain %d not found", chainID) + } + evmCaller := client.BatchCaller + + nbDecimalCalls := len(batchCalls.decimalCalls) + nbLatestRoundDataCalls := len(batchCalls.decimalCalls) + + // Perform batched call (all decimals calls followed by latest round data calls). + calls := make([]rpclib.EvmCall, 0, nbDecimalCalls+nbLatestRoundDataCalls) + calls = append(calls, batchCalls.decimalCalls...) + calls = append(calls, batchCalls.latestRoundDataCalls...) + + results, err := evmCaller.BatchCall(ctx, 0, calls) + if err != nil { + return fmt.Errorf("batch call on chain %d failed: %w", chainID, err) + } + + // Extract results. + decimals := make([]uint8, 0, nbDecimalCalls) + latestRounds := make([]*big.Int, 0, nbLatestRoundDataCalls) + + for i, res := range results[0:nbDecimalCalls] { + v, err1 := rpclib.ParseOutput[uint8](res, 0) + if err1 != nil { + callSignature := batchCalls.decimalCalls[i].String() + return fmt.Errorf("parse contract output while calling %v on chain %d: %w", callSignature, chainID, err1) + } + decimals = append(decimals, v) + } + + for i, res := range results[nbDecimalCalls : nbDecimalCalls+nbLatestRoundDataCalls] { + // latestRoundData function has multiple outputs (roundId,answer,startedAt,updatedAt,answeredInRound). + // we want the second one (answer, at idx=1). + v, err1 := rpclib.ParseOutput[*big.Int](res, 1) + if err1 != nil { + callSignature := batchCalls.latestRoundDataCalls[i].String() + return fmt.Errorf("parse contract output while calling %v on chain %d: %w", callSignature, chainID, err1) + } + latestRounds = append(latestRounds, v) + } + + // Normalize and store prices. + for i := range batchCalls.tokenOrder { + // Normalize to 1e18. + if decimals[i] < 18 { + latestRounds[i].Mul(latestRounds[i], big.NewInt(0).Exp(big.NewInt(10), big.NewInt(18-int64(decimals[i])), nil)) + } else if decimals[i] > 18 { + latestRounds[i].Div(latestRounds[i], big.NewInt(0).Exp(big.NewInt(10), big.NewInt(int64(decimals[i])-18), nil)) + } + prices[ccipcalc.EvmAddrToGeneric(batchCalls.tokenOrder[i])] = latestRounds[i] + } + return nil +} + +// preparePricesAndBatchCallsPerChain uses this price getter to prepare for a list of tokens: +// - the map of token address to their prices (static prices) +// - the map of and batch calls per chain for the given tokens (dynamic prices) +func (d *DynamicPriceGetter) preparePricesAndBatchCallsPerChain(tokens []cciptypes.Address) (map[cciptypes.Address]*big.Int, map[uint64]*batchCallsForChain, error) { + prices := make(map[cciptypes.Address]*big.Int, len(tokens)) + batchCallsPerChain := make(map[uint64]*batchCallsForChain) + evmAddrs, err := ccipcalc.GenericAddrsToEvm(tokens...) + if err != nil { + return nil, nil, err + } + for _, tk := range evmAddrs { + if aggCfg, isAgg := d.cfg.AggregatorPrices[tk]; isAgg { + // Batch calls for aggregator-based token prices (one per chain). + if _, exists := batchCallsPerChain[aggCfg.ChainID]; !exists { + batchCallsPerChain[aggCfg.ChainID] = &batchCallsForChain{ + decimalCalls: []rpclib.EvmCall{}, + latestRoundDataCalls: []rpclib.EvmCall{}, + tokenOrder: []common.Address{}, + } + } + chainCalls := batchCallsPerChain[aggCfg.ChainID] + chainCalls.decimalCalls = append(chainCalls.decimalCalls, rpclib.NewEvmCall( + d.aggregatorAbi, + decimalsMethodName, + aggCfg.AggregatorContractAddress, + )) + chainCalls.latestRoundDataCalls = append(chainCalls.latestRoundDataCalls, rpclib.NewEvmCall( + d.aggregatorAbi, + latestRoundDataMethodName, + aggCfg.AggregatorContractAddress, + )) + chainCalls.tokenOrder = append(chainCalls.tokenOrder, tk) + } else if staticCfg, isStatic := d.cfg.StaticPrices[tk]; isStatic { + // Fill static prices. + prices[ccipcalc.EvmAddrToGeneric(tk)] = staticCfg.Price + } else { + return nil, nil, fmt.Errorf("no price resolution rule for token %s", tk.Hex()) + } + } + return prices, batchCallsPerChain, nil +} + +// batchCallsForChain Defines the batch calls to perform on a given chain. +type batchCallsForChain struct { + decimalCalls []rpclib.EvmCall + latestRoundDataCalls []rpclib.EvmCall + tokenOrder []common.Address // required to maintain the order of the batched rpc calls for mapping the results. +} + +func (d *DynamicPriceGetter) Close() error { + return nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/pricegetter/evm_test.go b/core/services/ocr2/plugins/ccip/internal/pricegetter/evm_test.go new file mode 100644 index 0000000000..673b9776c7 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/pricegetter/evm_test.go @@ -0,0 +1,546 @@ +package pricegetter + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib/rpclibmocks" +) + +type testParameters struct { + cfg config.DynamicPriceGetterConfig + evmClients map[uint64]DynamicPriceGetterClient + tokens []common.Address + expectedTokenPrices map[common.Address]big.Int + evmCallErr bool + invalidConfigErrorExpected bool + priceResolutionErrorExpected bool +} + +func TestDynamicPriceGetter(t *testing.T) { + tests := []struct { + name string + param testParameters + }{ + { + name: "aggregator_only_valid", + param: testParamAggregatorOnly(t), + }, + { + name: "aggregator_only_valid_multi", + param: testParamAggregatorOnlyMulti(t), + }, + { + name: "static_only_valid", + param: testParamStaticOnly(), + }, + { + name: "aggregator_and_static_valid", + param: testParamAggregatorAndStaticValid(t), + }, + { + name: "aggregator_and_static_token_collision", + param: testParamAggregatorAndStaticTokenCollision(t), + }, + { + name: "no_aggregator_for_token", + param: testParamNoAggregatorForToken(t), + }, + { + name: "batchCall_returns_err", + param: testParamBatchCallReturnsErr(t), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + pg, err := NewDynamicPriceGetter(test.param.cfg, test.param.evmClients) + if test.param.invalidConfigErrorExpected { + require.Error(t, err) + return + } + require.NoError(t, err) + ctx := testutils.Context(t) + // Check configured token + unconfiguredTk := cciptypes.Address(utils.RandomAddress().String()) + cfgTokens, uncfgTokens, err := pg.FilterConfiguredTokens(ctx, []cciptypes.Address{unconfiguredTk}) + require.NoError(t, err) + assert.Equal(t, []cciptypes.Address{}, cfgTokens) + assert.Equal(t, []cciptypes.Address{unconfiguredTk}, uncfgTokens) + // Build list of tokens to query. + tokens := make([]cciptypes.Address, 0, len(test.param.tokens)) + for _, tk := range test.param.tokens { + tokenAddr := ccipcalc.EvmAddrToGeneric(tk) + tokens = append(tokens, tokenAddr) + } + prices, err := pg.TokenPricesUSD(ctx, tokens) + + if test.param.evmCallErr { + require.Error(t, err) + return + } + + if test.param.priceResolutionErrorExpected { + require.Error(t, err) + return + } + require.NoError(t, err) + // we expect prices for at least all queried tokens (it is possible that additional tokens are returned). + assert.True(t, len(prices) >= len(test.param.expectedTokenPrices)) + // Check prices are matching expected result. + for tk, expectedPrice := range test.param.expectedTokenPrices { + if prices[cciptypes.Address(tk.String())] == nil { + assert.Fail(t, "Token price not found") + } + assert.Equal(t, 0, expectedPrice.Cmp(prices[cciptypes.Address(tk.String())]), + "Token price mismatch: expected price %v, got %v", expectedPrice, *prices[cciptypes.Address(tk.String())]) + } + }) + } +} + +func testParamAggregatorOnly(t *testing.T) testParameters { + tk1 := utils.RandomAddress() + tk2 := utils.RandomAddress() + tk3 := utils.RandomAddress() + tk4 := utils.RandomAddress() + cfg := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ + tk1: { + ChainID: 101, + AggregatorContractAddress: utils.RandomAddress(), + }, + tk2: { + ChainID: 102, + AggregatorContractAddress: utils.RandomAddress(), + }, + tk3: { + ChainID: 103, + AggregatorContractAddress: utils.RandomAddress(), + }, + tk4: { + ChainID: 104, + AggregatorContractAddress: utils.RandomAddress(), + }, + }, + StaticPrices: map[common.Address]config.StaticPriceConfig{}, + } + // Real LINK/USD example from OP. + round1 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(1000), + Answer: big.NewInt(1396818990), + StartedAt: big.NewInt(1704896575), + UpdatedAt: big.NewInt(1704896575), + AnsweredInRound: big.NewInt(1000), + } + // Real ETH/USD example from OP. + round2 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(2000), + Answer: big.NewInt(238879815123), + StartedAt: big.NewInt(1704897197), + UpdatedAt: big.NewInt(1704897197), + AnsweredInRound: big.NewInt(2000), + } + // Real LINK/ETH example from OP. + round3 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(3000), + Answer: big.NewInt(4468862777874802), + StartedAt: big.NewInt(1715743907), + UpdatedAt: big.NewInt(1715743907), + AnsweredInRound: big.NewInt(3000), + } + // Fake data for a token with more than 18 decimals. + round4 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(4000), + Answer: multExp(big.NewInt(1234567890), 10), // 20 digits. + StartedAt: big.NewInt(1715753907), + UpdatedAt: big.NewInt(1715753907), + AnsweredInRound: big.NewInt(4000), + } + evmClients := map[uint64]DynamicPriceGetterClient{ + uint64(101): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round1}), + uint64(102): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round2}), + uint64(103): mockClient(t, []uint8{18}, []aggregator_v3_interface.LatestRoundData{round3}), + uint64(104): mockClient(t, []uint8{20}, []aggregator_v3_interface.LatestRoundData{round4}), + } + expectedTokenPrices := map[common.Address]big.Int{ + tk1: *multExp(round1.Answer, 10), // expected in 1e18 format. + tk2: *multExp(round2.Answer, 10), // expected in 1e18 format. + tk3: *round3.Answer, // already in 1e18 format (contract decimals==18). + tk4: *multExp(big.NewInt(1234567890), 8), // expected in 1e18 format. + } + return testParameters{ + cfg: cfg, + evmClients: evmClients, + tokens: []common.Address{tk1, tk2, tk3, tk4}, + expectedTokenPrices: expectedTokenPrices, + invalidConfigErrorExpected: false, + } +} + +// testParamAggregatorOnlyMulti test with several tokens on chain 102. +func testParamAggregatorOnlyMulti(t *testing.T) testParameters { + tk1 := utils.RandomAddress() + tk2 := utils.RandomAddress() + tk3 := utils.RandomAddress() + cfg := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ + tk1: { + ChainID: 101, + AggregatorContractAddress: utils.RandomAddress(), + }, + tk2: { + ChainID: 102, + AggregatorContractAddress: utils.RandomAddress(), + }, + tk3: { + ChainID: 102, + AggregatorContractAddress: utils.RandomAddress(), + }, + }, + StaticPrices: map[common.Address]config.StaticPriceConfig{}, + } + // Real LINK/USD example from OP. + round1 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(1000), + Answer: big.NewInt(1396818990), + StartedAt: big.NewInt(1704896575), + UpdatedAt: big.NewInt(1704896575), + AnsweredInRound: big.NewInt(1000), + } + // Real ETH/USD example from OP. + round2 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(2000), + Answer: big.NewInt(238879815123), + StartedAt: big.NewInt(1704897197), + UpdatedAt: big.NewInt(1704897197), + AnsweredInRound: big.NewInt(2000), + } + round3 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(3000), + Answer: big.NewInt(238879815125), + StartedAt: big.NewInt(1704897198), + UpdatedAt: big.NewInt(1704897198), + AnsweredInRound: big.NewInt(3000), + } + evmClients := map[uint64]DynamicPriceGetterClient{ + uint64(101): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round1}), + uint64(102): mockClient(t, []uint8{8, 8}, []aggregator_v3_interface.LatestRoundData{round2, round3}), + } + expectedTokenPrices := map[common.Address]big.Int{ + tk1: *multExp(round1.Answer, 10), + tk2: *multExp(round2.Answer, 10), + tk3: *multExp(round3.Answer, 10), + } + return testParameters{ + cfg: cfg, + evmClients: evmClients, + invalidConfigErrorExpected: false, + tokens: []common.Address{tk1, tk2, tk3}, + expectedTokenPrices: expectedTokenPrices, + } +} + +func testParamStaticOnly() testParameters { + tk1 := utils.RandomAddress() + tk2 := utils.RandomAddress() + tk3 := utils.RandomAddress() + cfg := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{}, + StaticPrices: map[common.Address]config.StaticPriceConfig{ + tk1: { + ChainID: 101, + Price: big.NewInt(1_234_000), + }, + tk2: { + ChainID: 102, + Price: big.NewInt(2_234_000), + }, + tk3: { + ChainID: 103, + Price: big.NewInt(3_234_000), + }, + }, + } + // Real LINK/USD example from OP. + evmClients := map[uint64]DynamicPriceGetterClient{} + expectedTokenPrices := map[common.Address]big.Int{ + tk1: *cfg.StaticPrices[tk1].Price, + tk2: *cfg.StaticPrices[tk2].Price, + tk3: *cfg.StaticPrices[tk3].Price, + } + return testParameters{ + cfg: cfg, + evmClients: evmClients, + tokens: []common.Address{tk1, tk2, tk3}, + expectedTokenPrices: expectedTokenPrices, + } +} + +func testParamAggregatorAndStaticValid(t *testing.T) testParameters { + tk1 := utils.RandomAddress() + tk2 := utils.RandomAddress() + tk3 := utils.RandomAddress() + cfg := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ + tk1: { + ChainID: 101, + AggregatorContractAddress: utils.RandomAddress(), + }, + tk2: { + ChainID: 102, + AggregatorContractAddress: utils.RandomAddress(), + }, + }, + StaticPrices: map[common.Address]config.StaticPriceConfig{ + tk3: { + ChainID: 103, + Price: big.NewInt(1_234_000), + }, + }, + } + // Real LINK/USD example from OP. + round1 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(1000), + Answer: big.NewInt(1396818990), + StartedAt: big.NewInt(1704896575), + UpdatedAt: big.NewInt(1704896575), + AnsweredInRound: big.NewInt(1000), + } + // Real ETH/USD example from OP. + round2 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(2000), + Answer: big.NewInt(238879815123), + StartedAt: big.NewInt(1704897197), + UpdatedAt: big.NewInt(1704897197), + AnsweredInRound: big.NewInt(2000), + } + evmClients := map[uint64]DynamicPriceGetterClient{ + uint64(101): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round1}), + uint64(102): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round2}), + } + expectedTokenPrices := map[common.Address]big.Int{ + tk1: *multExp(round1.Answer, 10), + tk2: *multExp(round2.Answer, 10), + tk3: *cfg.StaticPrices[tk3].Price, + } + return testParameters{ + cfg: cfg, + evmClients: evmClients, + tokens: []common.Address{tk1, tk2, tk3}, + expectedTokenPrices: expectedTokenPrices, + } +} + +func testParamAggregatorAndStaticTokenCollision(t *testing.T) testParameters { + tk1 := utils.RandomAddress() + tk2 := utils.RandomAddress() + tk3 := utils.RandomAddress() + cfg := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ + tk1: { + ChainID: 101, + AggregatorContractAddress: utils.RandomAddress(), + }, + tk2: { + ChainID: 102, + AggregatorContractAddress: utils.RandomAddress(), + }, + tk3: { + ChainID: 103, + AggregatorContractAddress: utils.RandomAddress(), + }, + }, + StaticPrices: map[common.Address]config.StaticPriceConfig{ + tk3: { + ChainID: 103, + Price: big.NewInt(1_234_000), + }, + }, + } + // Real LINK/USD example from OP. + round1 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(1000), + Answer: big.NewInt(1396818990), + StartedAt: big.NewInt(1704896575), + UpdatedAt: big.NewInt(1704896575), + AnsweredInRound: big.NewInt(1000), + } + // Real ETH/USD example from OP. + round2 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(2000), + Answer: big.NewInt(238879815123), + StartedAt: big.NewInt(1704897197), + UpdatedAt: big.NewInt(1704897197), + AnsweredInRound: big.NewInt(2000), + } + round3 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(3000), + Answer: big.NewInt(238879815124), + StartedAt: big.NewInt(1704897198), + UpdatedAt: big.NewInt(1704897198), + AnsweredInRound: big.NewInt(3000), + } + evmClients := map[uint64]DynamicPriceGetterClient{ + uint64(101): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round1}), + uint64(102): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round2}), + uint64(103): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round3}), + } + return testParameters{ + cfg: cfg, + evmClients: evmClients, + tokens: []common.Address{tk1, tk2, tk3}, + invalidConfigErrorExpected: true, + } +} + +func testParamNoAggregatorForToken(t *testing.T) testParameters { + tk1 := utils.RandomAddress() + tk2 := utils.RandomAddress() + tk3 := utils.RandomAddress() + tk4 := utils.RandomAddress() + cfg := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ + tk1: { + ChainID: 101, + AggregatorContractAddress: utils.RandomAddress(), + }, + tk2: { + ChainID: 102, + AggregatorContractAddress: utils.RandomAddress(), + }, + }, + StaticPrices: map[common.Address]config.StaticPriceConfig{ + tk3: { + ChainID: 103, + Price: big.NewInt(1_234_000), + }, + }, + } + // Real LINK/USD example from OP. + round1 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(1000), + Answer: big.NewInt(1396818990), + StartedAt: big.NewInt(1704896575), + UpdatedAt: big.NewInt(1704896575), + AnsweredInRound: big.NewInt(1000), + } + // Real ETH/USD example from OP. + round2 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(2000), + Answer: big.NewInt(238879815123), + StartedAt: big.NewInt(1704897197), + UpdatedAt: big.NewInt(1704897197), + AnsweredInRound: big.NewInt(2000), + } + evmClients := map[uint64]DynamicPriceGetterClient{ + uint64(101): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round1}), + uint64(102): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round2}), + } + expectedTokenPrices := map[common.Address]big.Int{ + tk1: *round1.Answer, + tk2: *round2.Answer, + tk3: *cfg.StaticPrices[tk3].Price, + tk4: *big.NewInt(0), + } + return testParameters{ + cfg: cfg, + evmClients: evmClients, + tokens: []common.Address{tk1, tk2, tk3, tk4}, + expectedTokenPrices: expectedTokenPrices, + priceResolutionErrorExpected: true, + } +} + +func testParamBatchCallReturnsErr(t *testing.T) testParameters { + tk1 := utils.RandomAddress() + tk2 := utils.RandomAddress() + tk3 := utils.RandomAddress() + cfg := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ + tk1: { + ChainID: 101, + AggregatorContractAddress: utils.RandomAddress(), + }, + tk2: { + ChainID: 102, + AggregatorContractAddress: utils.RandomAddress(), + }, + }, + StaticPrices: map[common.Address]config.StaticPriceConfig{ + tk3: { + ChainID: 103, + Price: big.NewInt(1_234_000), + }, + }, + } + // Real LINK/USD example from OP. + round1 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(1000), + Answer: big.NewInt(1396818990), + StartedAt: big.NewInt(1704896575), + UpdatedAt: big.NewInt(1704896575), + AnsweredInRound: big.NewInt(1000), + } + evmClients := map[uint64]DynamicPriceGetterClient{ + uint64(101): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round1}), + uint64(102): { + BatchCaller: mockErrCaller(t), + }, + } + return testParameters{ + cfg: cfg, + evmClients: evmClients, + tokens: []common.Address{tk1, tk2, tk3}, + evmCallErr: true, + } +} + +func mockClient(t *testing.T, decimals []uint8, rounds []aggregator_v3_interface.LatestRoundData) DynamicPriceGetterClient { + return DynamicPriceGetterClient{ + BatchCaller: mockCaller(t, decimals, rounds), + } +} + +func mockCaller(t *testing.T, decimals []uint8, rounds []aggregator_v3_interface.LatestRoundData) *rpclibmocks.EvmBatchCaller { + caller := rpclibmocks.NewEvmBatchCaller(t) + + // Mock batch calls per chain: all decimals calls then all latestRoundData calls. + dataAndErrs := make([]rpclib.DataAndErr, 0, len(decimals)+len(rounds)) + for _, d := range decimals { + dataAndErrs = append(dataAndErrs, rpclib.DataAndErr{ + Outputs: []any{d}, + }) + } + for _, round := range rounds { + dataAndErrs = append(dataAndErrs, rpclib.DataAndErr{ + Outputs: []any{round.RoundId, round.Answer, round.StartedAt, round.UpdatedAt, round.AnsweredInRound}, + }) + } + caller.On("BatchCall", mock.Anything, uint64(0), mock.Anything).Return(dataAndErrs, nil).Maybe() + return caller +} + +func mockErrCaller(t *testing.T) *rpclibmocks.EvmBatchCaller { + caller := rpclibmocks.NewEvmBatchCaller(t) + caller.On("BatchCall", mock.Anything, uint64(0), mock.Anything).Return(nil, assert.AnError).Maybe() + return caller +} + +// multExp returns the result of multiplying x by 10^e. +func multExp(x *big.Int, e int64) *big.Int { + return big.NewInt(0).Mul(x, big.NewInt(0).Exp(big.NewInt(10), big.NewInt(e), nil)) +} diff --git a/core/services/ocr2/plugins/ccip/internal/pricegetter/mock.go b/core/services/ocr2/plugins/ccip/internal/pricegetter/mock.go new file mode 100644 index 0000000000..195649685b --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/pricegetter/mock.go @@ -0,0 +1,211 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package pricegetter + +import ( + context "context" + big "math/big" + + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + mock "github.com/stretchr/testify/mock" +) + +// MockPriceGetter is an autogenerated mock type for the PriceGetter type +type MockPriceGetter struct { + mock.Mock +} + +type MockPriceGetter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockPriceGetter) EXPECT() *MockPriceGetter_Expecter { + return &MockPriceGetter_Expecter{mock: &_m.Mock} +} + +// Close provides a mock function with given fields: +func (_m *MockPriceGetter) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockPriceGetter_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type MockPriceGetter_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *MockPriceGetter_Expecter) Close() *MockPriceGetter_Close_Call { + return &MockPriceGetter_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *MockPriceGetter_Close_Call) Run(run func()) *MockPriceGetter_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockPriceGetter_Close_Call) Return(_a0 error) *MockPriceGetter_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockPriceGetter_Close_Call) RunAndReturn(run func() error) *MockPriceGetter_Close_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfiguredTokens provides a mock function with given fields: ctx, tokens +func (_m *MockPriceGetter) FilterConfiguredTokens(ctx context.Context, tokens []ccip.Address) ([]ccip.Address, []ccip.Address, error) { + ret := _m.Called(ctx, tokens) + + if len(ret) == 0 { + panic("no return value specified for FilterConfiguredTokens") + } + + var r0 []ccip.Address + var r1 []ccip.Address + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) ([]ccip.Address, []ccip.Address, error)); ok { + return rf(ctx, tokens) + } + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) []ccip.Address); ok { + r0 = rf(ctx, tokens) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccip.Address) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []ccip.Address) []ccip.Address); ok { + r1 = rf(ctx, tokens) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).([]ccip.Address) + } + } + + if rf, ok := ret.Get(2).(func(context.Context, []ccip.Address) error); ok { + r2 = rf(ctx, tokens) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockPriceGetter_FilterConfiguredTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfiguredTokens' +type MockPriceGetter_FilterConfiguredTokens_Call struct { + *mock.Call +} + +// FilterConfiguredTokens is a helper method to define mock.On call +// - ctx context.Context +// - tokens []ccip.Address +func (_e *MockPriceGetter_Expecter) FilterConfiguredTokens(ctx interface{}, tokens interface{}) *MockPriceGetter_FilterConfiguredTokens_Call { + return &MockPriceGetter_FilterConfiguredTokens_Call{Call: _e.mock.On("FilterConfiguredTokens", ctx, tokens)} +} + +func (_c *MockPriceGetter_FilterConfiguredTokens_Call) Run(run func(ctx context.Context, tokens []ccip.Address)) *MockPriceGetter_FilterConfiguredTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]ccip.Address)) + }) + return _c +} + +func (_c *MockPriceGetter_FilterConfiguredTokens_Call) Return(configured []ccip.Address, unconfigured []ccip.Address, err error) *MockPriceGetter_FilterConfiguredTokens_Call { + _c.Call.Return(configured, unconfigured, err) + return _c +} + +func (_c *MockPriceGetter_FilterConfiguredTokens_Call) RunAndReturn(run func(context.Context, []ccip.Address) ([]ccip.Address, []ccip.Address, error)) *MockPriceGetter_FilterConfiguredTokens_Call { + _c.Call.Return(run) + return _c +} + +// TokenPricesUSD provides a mock function with given fields: ctx, tokens +func (_m *MockPriceGetter) TokenPricesUSD(ctx context.Context, tokens []ccip.Address) (map[ccip.Address]*big.Int, error) { + ret := _m.Called(ctx, tokens) + + if len(ret) == 0 { + panic("no return value specified for TokenPricesUSD") + } + + var r0 map[ccip.Address]*big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) (map[ccip.Address]*big.Int, error)); ok { + return rf(ctx, tokens) + } + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) map[ccip.Address]*big.Int); ok { + r0 = rf(ctx, tokens) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[ccip.Address]*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []ccip.Address) error); ok { + r1 = rf(ctx, tokens) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockPriceGetter_TokenPricesUSD_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TokenPricesUSD' +type MockPriceGetter_TokenPricesUSD_Call struct { + *mock.Call +} + +// TokenPricesUSD is a helper method to define mock.On call +// - ctx context.Context +// - tokens []ccip.Address +func (_e *MockPriceGetter_Expecter) TokenPricesUSD(ctx interface{}, tokens interface{}) *MockPriceGetter_TokenPricesUSD_Call { + return &MockPriceGetter_TokenPricesUSD_Call{Call: _e.mock.On("TokenPricesUSD", ctx, tokens)} +} + +func (_c *MockPriceGetter_TokenPricesUSD_Call) Run(run func(ctx context.Context, tokens []ccip.Address)) *MockPriceGetter_TokenPricesUSD_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]ccip.Address)) + }) + return _c +} + +func (_c *MockPriceGetter_TokenPricesUSD_Call) Return(_a0 map[ccip.Address]*big.Int, _a1 error) *MockPriceGetter_TokenPricesUSD_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockPriceGetter_TokenPricesUSD_Call) RunAndReturn(run func(context.Context, []ccip.Address) (map[ccip.Address]*big.Int, error)) *MockPriceGetter_TokenPricesUSD_Call { + _c.Call.Return(run) + return _c +} + +// NewMockPriceGetter creates a new instance of MockPriceGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockPriceGetter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockPriceGetter { + mock := &MockPriceGetter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline.go b/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline.go new file mode 100644 index 0000000000..ae9a10deb6 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline.go @@ -0,0 +1,114 @@ +package pricegetter + +import ( + "context" + "math/big" + "strings" + "time" + + mapset "github.com/deckarep/golang-set/v2" + "github.com/google/uuid" + "github.com/pkg/errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/parseutil" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" +) + +var _ PriceGetter = &PipelineGetter{} + +type PipelineGetter struct { + source string + runner pipeline.Runner + jobID int32 + externalJobID uuid.UUID + name string + lggr logger.Logger +} + +func NewPipelineGetter(source string, runner pipeline.Runner, jobID int32, externalJobID uuid.UUID, name string, lggr logger.Logger) (*PipelineGetter, error) { + _, err := pipeline.Parse(source) + if err != nil { + return nil, err + } + + return &PipelineGetter{ + source: source, + runner: runner, + jobID: jobID, + externalJobID: externalJobID, + name: name, + lggr: lggr, + }, nil +} + +// FilterForConfiguredTokens implements the PriceGetter interface. +// It filters a list of token addresses for only those that have a pipeline job configured on the TokenPricesUSDPipeline +func (d *PipelineGetter) FilterConfiguredTokens(ctx context.Context, tokens []cciptypes.Address) (configured []cciptypes.Address, unconfigured []cciptypes.Address, err error) { + lcSource := strings.ToLower(d.source) + for _, tk := range tokens { + lcToken := strings.ToLower(string(tk)) + if strings.Contains(lcSource, lcToken) { + configured = append(configured, tk) + } else { + unconfigured = append(unconfigured, tk) + } + } + return configured, unconfigured, nil +} + +func (d *PipelineGetter) TokenPricesUSD(ctx context.Context, tokens []cciptypes.Address) (map[cciptypes.Address]*big.Int, error) { + _, trrs, err := d.runner.ExecuteRun(ctx, pipeline.Spec{ + ID: d.jobID, + DotDagSource: d.source, + CreatedAt: time.Now(), + JobID: d.jobID, + JobName: d.name, + JobType: "", + }, pipeline.NewVarsFrom(map[string]interface{}{})) + if err != nil { + return nil, err + } + finalResult := trrs.FinalResult() + if finalResult.HasErrors() { + return nil, errors.Errorf("error getting prices %v", finalResult.AllErrors) + } + if len(finalResult.Values) != 1 { + return nil, errors.Errorf("invalid number of price results, expected 1 got %v", len(finalResult.Values)) + } + prices, ok := finalResult.Values[0].(map[string]interface{}) + if !ok { + return nil, errors.Errorf("expected map output of price pipeline, got %T", finalResult.Values[0]) + } + + providedTokensSet := mapset.NewSet(tokens...) + tokenPrices := make(map[cciptypes.Address]*big.Int) + for tokenAddressStr, rawPrice := range prices { + tokenAddressStr := ccipcalc.HexToAddress(tokenAddressStr) + castedPrice, err := parseutil.ParseBigIntFromAny(rawPrice) + if err != nil { + return nil, err + } + + if providedTokensSet.Contains(tokenAddressStr) { + tokenPrices[tokenAddressStr] = castedPrice + } + } + + // The mapping of token address to source of token price has to live offchain. + // Best we can do is sanity check that the token price spec covers all our desired execution token prices. + for _, token := range tokens { + if _, ok = tokenPrices[token]; !ok { + return nil, errors.Errorf("missing token %s from tokensForFeeCoin spec, got %v", token, prices) + } + } + + return tokenPrices, nil +} + +func (d *PipelineGetter) Close() error { + return d.runner.Close() +} diff --git a/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline_test.go b/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline_test.go new file mode 100644 index 0000000000..3797075073 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline_test.go @@ -0,0 +1,178 @@ +package pricegetter_test + +import ( + "context" + "fmt" + "math/big" + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + config2 "github.com/smartcontractkit/chainlink-common/pkg/config" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/bridges" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + + pipelinemocks "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/mocks" + + config "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" +) + +func TestDataSource(t *testing.T) { + linkEth := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, err := w.Write([]byte(`{"JuelsPerETH": "200000000000000000000"}`)) + require.NoError(t, err) + })) + defer linkEth.Close() + usdcEth := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, err := w.Write([]byte(`{"USDCWeiPerETH": "1000000000000000000000"}`)) // 1000 USDC / ETH + require.NoError(t, err) + })) + defer usdcEth.Close() + linkTokenAddress := ccipcalc.HexToAddress("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") + usdcTokenAddress := ccipcalc.HexToAddress("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e10") + source := fmt.Sprintf(` + // Price 1 + link [type=http method=GET url="%s"]; + link_parse [type=jsonparse path="JuelsPerETH"]; + link->link_parse; + // Price 2 + usdc [type=http method=GET url="%s"]; + usdc_parse [type=jsonparse path="USDCWeiPerETH"]; + usdc->usdc_parse; + merge [type=merge left="{}" right="{\"%s\":$(link_parse), \"%s\":$(usdc_parse)}"]; +`, linkEth.URL, usdcEth.URL, linkTokenAddress, usdcTokenAddress) + + priceGetter := newTestPipelineGetter(t, source) + + // USDC & LINK are configured + confTokens, _, err := priceGetter.FilterConfiguredTokens(context.Background(), []cciptypes.Address{linkTokenAddress, usdcTokenAddress}) + require.NoError(t, err) + assert.Equal(t, linkTokenAddress, confTokens[0]) + assert.Equal(t, usdcTokenAddress, confTokens[1]) + + // Ask for all prices present in spec. + prices, err := priceGetter.TokenPricesUSD(context.Background(), []cciptypes.Address{ + linkTokenAddress, + usdcTokenAddress, + }) + require.NoError(t, err) + assert.Equal(t, prices, map[cciptypes.Address]*big.Int{ + linkTokenAddress: big.NewInt(0).Mul(big.NewInt(200), big.NewInt(1000000000000000000)), + usdcTokenAddress: big.NewInt(0).Mul(big.NewInt(1000), big.NewInt(1000000000000000000)), + }) + + // Ask a non-existent price. + _, err = priceGetter.TokenPricesUSD(context.Background(), []cciptypes.Address{ + ccipcalc.HexToAddress("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e11"), + }) + require.Error(t, err) + + // Ask only one price + prices, err = priceGetter.TokenPricesUSD(context.Background(), []cciptypes.Address{linkTokenAddress}) + require.NoError(t, err) + assert.Equal(t, prices, map[cciptypes.Address]*big.Int{ + linkTokenAddress: big.NewInt(0).Mul(big.NewInt(200), big.NewInt(1000000000000000000)), + }) +} + +func TestParsingDifferentFormats(t *testing.T) { + tests := []struct { + name string + inputValue string + expectedValue *big.Int + expectedError bool + }{ + { + name: "number as string", + inputValue: "\"200000000000000000000\"", + expectedValue: new(big.Int).Mul(big.NewInt(200), big.NewInt(1e18)), + }, + { + name: "number as big number", + inputValue: "500000000000000000000", + expectedValue: new(big.Int).Mul(big.NewInt(500), big.NewInt(1e18)), + }, + { + name: "number as int64", + inputValue: "150", + expectedValue: big.NewInt(150), + }, + { + name: "number in scientific notation", + inputValue: "3e22", + expectedValue: new(big.Int).Mul(big.NewInt(30000), big.NewInt(1e18)), + }, + { + name: "number as string in scientific notation returns error", + inputValue: "\"3e22\"", + expectedError: true, + }, + { + name: "invalid value should return error", + inputValue: "\"NaN\"", + expectedError: true, + }, + { + name: "null should return error", + inputValue: "null", + expectedError: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + token := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, err := fmt.Fprintf(w, `{"MyCoin": %s}`, tt.inputValue) + require.NoError(t, err) + })) + defer token.Close() + + address := common.HexToAddress("0x94025780a1aB58868D9B2dBBB775f44b32e8E6e5") + source := fmt.Sprintf(` + // Price 1 + coin [type=http method=GET url="%s"]; + coin_parse [type=jsonparse path="MyCoin"]; + coin->coin_parse; + merge [type=merge left="{}" right="{\"%s\":$(coin_parse)}"]; + `, token.URL, strings.ToLower(address.String())) + + prices, err := newTestPipelineGetter(t, source). + TokenPricesUSD(context.Background(), []cciptypes.Address{ccipcalc.EvmAddrToGeneric(address)}) + + if tt.expectedError { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, prices[ccipcalc.EvmAddrToGeneric(address)], tt.expectedValue) + } + }) + } +} + +func newTestPipelineGetter(t *testing.T, source string) *pricegetter.PipelineGetter { + lggr, _ := logger.NewLogger() + cfg := pipelinemocks.NewConfig(t) + cfg.On("MaxRunDuration").Return(time.Second) + cfg.On("DefaultHTTPTimeout").Return(*config2.MustNewDuration(time.Second)) + cfg.On("DefaultHTTPLimit").Return(int64(1024 * 10)) + cfg.On("VerboseLogging").Return(true) + db := pgtest.NewSqlxDB(t) + bridgeORM := bridges.NewORM(db) + runner := pipeline.NewRunner(pipeline.NewORM(db, lggr, config.NewTestGeneralConfig(t).JobPipeline().MaxSuccessfulRuns()), + bridgeORM, cfg, nil, nil, nil, nil, lggr, &http.Client{}, &http.Client{}) + ds, err := pricegetter.NewPipelineGetter(source, runner, 1, uuid.New(), "test", lggr) + require.NoError(t, err) + return ds +} diff --git a/core/services/ocr2/plugins/ccip/internal/pricegetter/pricegetter.go b/core/services/ocr2/plugins/ccip/internal/pricegetter/pricegetter.go new file mode 100644 index 0000000000..9ee0e8f3d0 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/pricegetter/pricegetter.go @@ -0,0 +1,7 @@ +package pricegetter + +import cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + +type PriceGetter interface { + cciptypes.PriceGetter +} diff --git a/core/services/ocr2/plugins/ccip/internal/rpclib/evm.go b/core/services/ocr2/plugins/ccip/internal/rpclib/evm.go new file mode 100644 index 0000000000..71357029dd --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/rpclib/evm.go @@ -0,0 +1,337 @@ +package rpclib + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "reflect" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rpc" + "github.com/pkg/errors" + "golang.org/x/sync/errgroup" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +var ErrEmptyOutput = errors.New("rpc call output is empty (make sure that the contract method exists and rpc is healthy)") + +type EvmBatchCaller interface { + // BatchCall executes all the provided EvmCall and returns the results in the same order + // of the calls. Pass blockNumber=0 to use the latest block. + BatchCall(ctx context.Context, blockNumber uint64, calls []EvmCall) ([]DataAndErr, error) +} + +type BatchSender interface { + BatchCallContext(ctx context.Context, calls []rpc.BatchElem) error +} + +const ( + // DefaultRpcBatchSizeLimit defines the maximum number of rpc requests to be included in a batch. + DefaultRpcBatchSizeLimit = 100 + + // DefaultRpcBatchBackOffMultiplier defines the rate of reducing the batch size limit for retried calls. + // For example if limit is 20 and multiplier is 4: + // 1. 20 + // 2. 20/4 = 5 + // 3. 5/4 = 1 + DefaultRpcBatchBackOffMultiplier = 5 + + // DefaultMaxParallelRpcCalls defines the default maximum number of individual in-parallel rpc calls. + DefaultMaxParallelRpcCalls = 10 +) + +// DynamicLimitedBatchCaller makes batched rpc calls and perform retries by reducing the batch size on each retry. +type DynamicLimitedBatchCaller struct { + bc *defaultEvmBatchCaller +} + +func NewDynamicLimitedBatchCaller( + lggr logger.Logger, batchSender BatchSender, batchSizeLimit, backOffMultiplier, parallelRpcCallsLimit uint, +) *DynamicLimitedBatchCaller { + return &DynamicLimitedBatchCaller{ + bc: newDefaultEvmBatchCaller(lggr, batchSender, batchSizeLimit, backOffMultiplier, parallelRpcCallsLimit), + } +} + +func (c *DynamicLimitedBatchCaller) BatchCall(ctx context.Context, blockNumber uint64, calls []EvmCall) ([]DataAndErr, error) { + return c.bc.batchCallDynamicLimitRetries(ctx, blockNumber, calls) +} + +type defaultEvmBatchCaller struct { + lggr logger.Logger + batchSender BatchSender + batchSizeLimit uint + parallelRpcCallsLimit uint + backOffMultiplier uint +} + +// NewDefaultEvmBatchCaller returns a new batch caller instance. +// batchCallLimit defines the maximum number of calls for BatchCallLimit method, pass 0 to keep the default. +// backOffMultiplier defines the back-off strategy for retries on BatchCallDynamicLimitRetries method, pass 0 to keep the default. +func newDefaultEvmBatchCaller( + lggr logger.Logger, batchSender BatchSender, batchSizeLimit, backOffMultiplier, parallelRpcCallsLimit uint, +) *defaultEvmBatchCaller { + batchSize := uint(DefaultRpcBatchSizeLimit) + if batchSizeLimit > 0 { + batchSize = batchSizeLimit + } + + multiplier := uint(DefaultRpcBatchBackOffMultiplier) + if backOffMultiplier > 0 { + multiplier = backOffMultiplier + } + + parallelRpcCalls := uint(DefaultMaxParallelRpcCalls) + if parallelRpcCallsLimit > 0 { + parallelRpcCalls = parallelRpcCallsLimit + } + + return &defaultEvmBatchCaller{ + lggr: lggr, + batchSender: batchSender, + batchSizeLimit: batchSize, + parallelRpcCallsLimit: parallelRpcCalls, + backOffMultiplier: multiplier, + } +} + +func (c *defaultEvmBatchCaller) batchCall(ctx context.Context, blockNumber uint64, calls []EvmCall) ([]DataAndErr, error) { + if len(calls) == 0 { + return nil, nil + } + + packedOutputs := make([]string, len(calls)) + rpcBatchCalls := make([]rpc.BatchElem, len(calls)) + + for i, call := range calls { + packedInputs, err := call.abi.Pack(call.methodName, call.args...) + if err != nil { + return nil, fmt.Errorf("pack %s(%+v): %w", call.methodName, call.args, err) + } + + blockNumStr := "latest" + if blockNumber > 0 { + blockNumStr = hexutil.EncodeBig(big.NewInt(0).SetUint64(blockNumber)) + } + + rpcBatchCalls[i] = rpc.BatchElem{ + Method: "eth_call", + Args: []any{ + map[string]interface{}{ + "from": common.Address{}, + "to": call.contractAddress, + "data": hexutil.Bytes(packedInputs), + }, + blockNumStr, + }, + Result: &packedOutputs[i], + } + } + + err := c.batchSender.BatchCallContext(ctx, rpcBatchCalls) + if err != nil { + return nil, fmt.Errorf("batch call context: %w", err) + } + + results := make([]DataAndErr, len(calls)) + for i, call := range calls { + if rpcBatchCalls[i].Error != nil { + results[i].Err = rpcBatchCalls[i].Error + continue + } + + if packedOutputs[i] == "" { + // Some RPCs instead of returning "0x" are returning an empty string. + // We are overriding this behaviour for consistent handling of this scenario. + packedOutputs[i] = "0x" + } + + b, err := hexutil.Decode(packedOutputs[i]) + if err != nil { + return nil, fmt.Errorf("decode result %s: packedOutputs %s: %w", call, packedOutputs[i], err) + } + + unpackedOutputs, err := call.abi.Unpack(call.methodName, b) + if err != nil { + if len(b) == 0 { + results[i].Err = fmt.Errorf("unpack result %s: %s: %w", call, err.Error(), ErrEmptyOutput) + } else { + results[i].Err = fmt.Errorf("unpack result %s: %w", call, err) + } + continue + } + + results[i].Outputs = unpackedOutputs + } + + return results, nil +} + +func (c *defaultEvmBatchCaller) batchCallDynamicLimitRetries(ctx context.Context, blockNumber uint64, calls []EvmCall) ([]DataAndErr, error) { + lim := c.batchSizeLimit + // Limit the batch size to the number of calls + if uint(len(calls)) < lim { + lim = uint(len(calls)) + } + for { + results, err := c.batchCallLimit(ctx, blockNumber, calls, lim) + if err == nil { + return results, nil + } + + if lim <= 1 { + return nil, errors.Wrapf(err, "calls %+v", EVMCallsToString(calls)) + } + + newLim := lim / c.backOffMultiplier + if newLim == 0 || newLim == lim { + newLim = 1 + } + lim = newLim + c.lggr.Errorf("retrying batch call with %d calls and %d limit that failed with error=%s", + len(calls), lim, err) + } +} + +func (c *defaultEvmBatchCaller) batchCallLimit(ctx context.Context, blockNumber uint64, calls []EvmCall, batchSizeLimit uint) ([]DataAndErr, error) { + if batchSizeLimit <= 0 { + return c.batchCall(ctx, blockNumber, calls) + } + + type job struct { + blockNumber uint64 + calls []EvmCall + results []DataAndErr + } + + jobs := make([]job, 0) + for i := 0; i < len(calls); i += int(batchSizeLimit) { + idxFrom := i + idxTo := idxFrom + int(batchSizeLimit) + if idxTo > len(calls) { + idxTo = len(calls) + } + jobs = append(jobs, job{blockNumber: blockNumber, calls: calls[idxFrom:idxTo], results: nil}) + } + + if c.parallelRpcCallsLimit > 1 { + eg := new(errgroup.Group) + eg.SetLimit(int(c.parallelRpcCallsLimit)) + for jobIdx := range jobs { + jobIdx := jobIdx + eg.Go(func() error { + res, err := c.batchCall(ctx, jobs[jobIdx].blockNumber, jobs[jobIdx].calls) + if err != nil { + return err + } + jobs[jobIdx].results = res + return nil + }) + } + if err := eg.Wait(); err != nil { + return nil, err + } + } else { + var err error + for jobIdx := range jobs { + jobs[jobIdx].results, err = c.batchCall(ctx, jobs[jobIdx].blockNumber, jobs[jobIdx].calls) + if err != nil { + return nil, err + } + } + } + + results := make([]DataAndErr, 0) + for _, jb := range jobs { + results = append(results, jb.results...) + } + return results, nil +} + +type AbiPackerUnpacker interface { + Pack(name string, args ...interface{}) ([]byte, error) + Unpack(name string, data []byte) ([]interface{}, error) +} + +type EvmCall struct { + abi AbiPackerUnpacker + methodName string + contractAddress common.Address + args []any +} + +func NewEvmCall(abi AbiPackerUnpacker, methodName string, contractAddress common.Address, args ...any) EvmCall { + return EvmCall{ + abi: abi, + methodName: methodName, + contractAddress: contractAddress, + args: args, + } +} + +func (c EvmCall) MethodName() string { + return c.methodName +} + +func (c EvmCall) String() string { + return fmt.Sprintf("%s: %s(%+v)", c.contractAddress.String(), c.methodName, c.args) +} + +func EVMCallsToString(calls []EvmCall) string { + callString := "" + for _, call := range calls { + callString += fmt.Sprintf("%s\n", call.String()) + } + return callString +} + +type DataAndErr struct { + Outputs []any + Err error +} + +func ParseOutputs[T any](results []DataAndErr, parseFunc func(d DataAndErr) (T, error)) ([]T, error) { + parsed := make([]T, 0, len(results)) + + for _, res := range results { + v, err := parseFunc(res) + if err != nil { + return nil, fmt.Errorf("parse contract output: %w", err) + } + parsed = append(parsed, v) + } + + return parsed, nil +} + +func ParseOutput[T any](dataAndErr DataAndErr, idx int) (T, error) { + var parsed T + + if dataAndErr.Err != nil { + return parsed, fmt.Errorf("rpc call error: %w", dataAndErr.Err) + } + + if idx < 0 || idx >= len(dataAndErr.Outputs) { + return parsed, fmt.Errorf("idx %d is out of bounds for %d outputs", idx, len(dataAndErr.Outputs)) + } + + res, is := dataAndErr.Outputs[idx].(T) + if !is { + // some rpc types are not strictly defined + // for that reason we try to manually map the fields using json encoding + b, err := json.Marshal(dataAndErr.Outputs[idx]) + if err == nil { + var empty T + if err := json.Unmarshal(b, &parsed); err == nil && !reflect.DeepEqual(parsed, empty) { + return parsed, nil + } + } + + return parsed, fmt.Errorf("the result type is: %T, expected: %T", dataAndErr.Outputs[idx], parsed) + } + + return res, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/rpclib/evm_test.go b/core/services/ocr2/plugins/ccip/internal/rpclib/evm_test.go new file mode 100644 index 0000000000..1a3d7baf0f --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/rpclib/evm_test.go @@ -0,0 +1,223 @@ +package rpclib_test + +import ( + "fmt" + "strconv" + "testing" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + + "github.com/cometbft/cometbft/libs/rand" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rpc" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" +) + +func TestDefaultEvmBatchCaller_BatchCallDynamicLimit(t *testing.T) { + testCases := []struct { + name string + maxBatchSize uint + backOffMultiplier uint + numCalls int + expectedBatchSizesOnEachRetry []int + }{ + { + name: "defaults", + maxBatchSize: rpclib.DefaultRpcBatchSizeLimit, + backOffMultiplier: rpclib.DefaultRpcBatchBackOffMultiplier, + numCalls: 200, + expectedBatchSizesOnEachRetry: []int{100, 20, 4, 1}, + }, + { + name: "base simple scenario", + maxBatchSize: 20, + backOffMultiplier: 2, + numCalls: 100, + expectedBatchSizesOnEachRetry: []int{20, 10, 5, 2, 1}, + }, + { + name: "remainder", + maxBatchSize: 99, + backOffMultiplier: 5, + numCalls: 100, + expectedBatchSizesOnEachRetry: []int{99, 19, 3, 1}, + }, + { + name: "large back off multiplier", + maxBatchSize: 20, + backOffMultiplier: 18, + numCalls: 100, + expectedBatchSizesOnEachRetry: []int{20, 1}, + }, + { + name: "back off equal to batch size", + maxBatchSize: 20, + backOffMultiplier: 20, + numCalls: 100, + expectedBatchSizesOnEachRetry: []int{20, 1}, + }, + { + name: "back off larger than batch size", + maxBatchSize: 20, + backOffMultiplier: 220, + numCalls: 100, + expectedBatchSizesOnEachRetry: []int{20, 1}, + }, + { + name: "back off 1", + maxBatchSize: 20, + backOffMultiplier: 1, + numCalls: 100, + expectedBatchSizesOnEachRetry: []int{20, 1}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + batchSizes := make([]int, 0) + + ec := mocks.NewClient(t) + bc := rpclib.NewDynamicLimitedBatchCaller(logger.TestLogger(t), ec, tc.maxBatchSize, tc.backOffMultiplier, 1) + ctx := testutils.Context(t) + calls := make([]rpclib.EvmCall, tc.numCalls) + emptyAbi := abihelpers.MustParseABI("[]") + for i := range calls { + calls[i] = rpclib.NewEvmCall(emptyAbi, "", common.Address{}) + } + ec.On("BatchCallContext", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { + evmCalls := args.Get(1).([]rpc.BatchElem) + batchSizes = append(batchSizes, len(evmCalls)) + }).Return(errors.New("some error")) + _, _ = bc.BatchCall(ctx, 123, calls) + + assert.Equal(t, tc.expectedBatchSizesOnEachRetry, batchSizes) + }) + } +} + +func TestDefaultEvmBatchCaller_batchCallLimit(t *testing.T) { + ctx := testutils.Context(t) + + testCases := []struct { + numCalls uint + batchSize uint + parallelRpcCallsLimit uint + }{ + {numCalls: 100, batchSize: 10, parallelRpcCallsLimit: 5}, + {numCalls: 10, batchSize: 100, parallelRpcCallsLimit: 10}, + {numCalls: 1, batchSize: 100, parallelRpcCallsLimit: 10}, + {numCalls: 1000, batchSize: 10, parallelRpcCallsLimit: 2}, + {numCalls: rand.Uint() % 1000, batchSize: rand.Uint() % 500, parallelRpcCallsLimit: rand.Uint() % 500}, + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("%v", tc), func(t *testing.T) { + ec := mocks.NewClient(t) + bc := rpclib.NewDynamicLimitedBatchCaller(logger.TestLogger(t), ec, tc.batchSize, 99999, tc.parallelRpcCallsLimit) + + // generate the abi and the rpc calls + intTyp, err := abi.NewType("uint64", "uint64", nil) + assert.NoError(t, err) + calls := make([]rpclib.EvmCall, tc.numCalls) + mockAbi := abihelpers.MustParseABI("[]") + for i := range calls { + name := fmt.Sprintf("method_%d", i) + meth := abi.NewMethod(name, name, abi.Function, "nonpayable", true, false, abi.Arguments{abi.Argument{Name: "a", Type: intTyp}}, abi.Arguments{abi.Argument{Name: "b", Type: intTyp}}) + mockAbi.Methods[name] = meth + calls[i] = rpclib.NewEvmCall(mockAbi, name, common.Address{}, uint64(i)) + } + + // mock the rpc call to batch call context + // for simplicity we just set an error + ec.On("BatchCallContext", mock.Anything, mock.Anything). + Run(func(args mock.Arguments) { + evmCalls := args.Get(1).([]rpc.BatchElem) + for i := range evmCalls { + arg := evmCalls[i].Args[0].(map[string]interface{})["data"].(hexutil.Bytes) + arg = arg[len(arg)-10:] + evmCalls[i].Error = fmt.Errorf("%s", arg) + } + }).Return(nil) + + // make the call and make sure the results are received in order + results, _ := bc.BatchCall(ctx, 0, calls) + assert.Len(t, results, len(calls)) + for i, res := range results { + resNum, err := strconv.ParseInt(res.Err.Error()[2:], 16, 64) + assert.NoError(t, err) + assert.Equal(t, int64(i), resNum) + } + }) + } +} + +func TestParseOutput(t *testing.T) { + type testCase[T any] struct { + name string + dataAndErr rpclib.DataAndErr + outputIdx int + expRes T + expErr bool + } + + testCases := []testCase[string]{ + { + name: "success", + dataAndErr: rpclib.DataAndErr{Outputs: []any{"abc"}, Err: nil}, + outputIdx: 0, + expRes: "abc", + expErr: false, + }, + { + name: "index error on empty list", + dataAndErr: rpclib.DataAndErr{Outputs: []any{}, Err: nil}, + outputIdx: 0, + expErr: true, + }, + { + name: "index error on non-empty list", + dataAndErr: rpclib.DataAndErr{Outputs: []any{"a", "b"}, Err: nil}, + outputIdx: 2, + expErr: true, + }, + { + name: "negative index", + dataAndErr: rpclib.DataAndErr{Outputs: []any{"a", "b"}, Err: nil}, + outputIdx: -1, + expErr: true, + }, + { + name: "wrong type", + dataAndErr: rpclib.DataAndErr{Outputs: []any{1234}, Err: nil}, + outputIdx: 0, + expErr: true, + }, + { + name: "has err", + dataAndErr: rpclib.DataAndErr{Outputs: []any{"abc"}, Err: fmt.Errorf("some err")}, + outputIdx: 0, + expErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := rpclib.ParseOutput[string](tc.dataAndErr, tc.outputIdx) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, tc.expRes, res) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/rpclib/rpclibmocks/evm_mock.go b/core/services/ocr2/plugins/ccip/internal/rpclib/rpclibmocks/evm_mock.go new file mode 100644 index 0000000000..aa42814186 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/rpclib/rpclibmocks/evm_mock.go @@ -0,0 +1,97 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package rpclibmocks + +import ( + context "context" + + rpclib "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + mock "github.com/stretchr/testify/mock" +) + +// EvmBatchCaller is an autogenerated mock type for the EvmBatchCaller type +type EvmBatchCaller struct { + mock.Mock +} + +type EvmBatchCaller_Expecter struct { + mock *mock.Mock +} + +func (_m *EvmBatchCaller) EXPECT() *EvmBatchCaller_Expecter { + return &EvmBatchCaller_Expecter{mock: &_m.Mock} +} + +// BatchCall provides a mock function with given fields: ctx, blockNumber, calls +func (_m *EvmBatchCaller) BatchCall(ctx context.Context, blockNumber uint64, calls []rpclib.EvmCall) ([]rpclib.DataAndErr, error) { + ret := _m.Called(ctx, blockNumber, calls) + + if len(ret) == 0 { + panic("no return value specified for BatchCall") + } + + var r0 []rpclib.DataAndErr + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, []rpclib.EvmCall) ([]rpclib.DataAndErr, error)); ok { + return rf(ctx, blockNumber, calls) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, []rpclib.EvmCall) []rpclib.DataAndErr); ok { + r0 = rf(ctx, blockNumber, calls) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]rpclib.DataAndErr) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, []rpclib.EvmCall) error); ok { + r1 = rf(ctx, blockNumber, calls) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EvmBatchCaller_BatchCall_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BatchCall' +type EvmBatchCaller_BatchCall_Call struct { + *mock.Call +} + +// BatchCall is a helper method to define mock.On call +// - ctx context.Context +// - blockNumber uint64 +// - calls []rpclib.EvmCall +func (_e *EvmBatchCaller_Expecter) BatchCall(ctx interface{}, blockNumber interface{}, calls interface{}) *EvmBatchCaller_BatchCall_Call { + return &EvmBatchCaller_BatchCall_Call{Call: _e.mock.On("BatchCall", ctx, blockNumber, calls)} +} + +func (_c *EvmBatchCaller_BatchCall_Call) Run(run func(ctx context.Context, blockNumber uint64, calls []rpclib.EvmCall)) *EvmBatchCaller_BatchCall_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].([]rpclib.EvmCall)) + }) + return _c +} + +func (_c *EvmBatchCaller_BatchCall_Call) Return(_a0 []rpclib.DataAndErr, _a1 error) *EvmBatchCaller_BatchCall_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EvmBatchCaller_BatchCall_Call) RunAndReturn(run func(context.Context, uint64, []rpclib.EvmCall) ([]rpclib.DataAndErr, error)) *EvmBatchCaller_BatchCall_Call { + _c.Call.Return(run) + return _c +} + +// NewEvmBatchCaller creates a new instance of EvmBatchCaller. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewEvmBatchCaller(t interface { + mock.TestingT + Cleanup(func()) +}) *EvmBatchCaller { + mock := &EvmBatchCaller{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/metrics.go b/core/services/ocr2/plugins/ccip/metrics.go new file mode 100644 index 0000000000..f481b5d447 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/metrics.go @@ -0,0 +1,99 @@ +package ccip + +import ( + "strconv" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +var ( + unexpiredCommitRoots = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "ccip_unexpired_commit_roots", + Help: "Number of unexpired commit roots processed by the plugin", + }, []string{"plugin", "source", "dest"}) + messagesProcessed = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "ccip_number_of_messages_processed", + Help: "Number of messages processed by the plugin during different OCR phases", + }, []string{"plugin", "source", "dest", "ocrPhase"}) + sequenceNumberCounter = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "ccip_sequence_number_counter", + Help: "Sequence number of the last message processed by the plugin", + }, []string{"plugin", "source", "dest", "ocrPhase"}) +) + +type ocrPhase string + +const ( + Observation ocrPhase = "observation" + Report ocrPhase = "report" + ShouldAccept ocrPhase = "shouldAccept" +) + +type PluginMetricsCollector interface { + NumberOfMessagesProcessed(phase ocrPhase, count int) + NumberOfMessagesBasedOnInterval(phase ocrPhase, seqNrMin, seqNrMax uint64) + UnexpiredCommitRoots(count int) + SequenceNumber(phase ocrPhase, seqNr uint64) +} + +type pluginMetricsCollector struct { + pluginName string + source, dest string +} + +func NewPluginMetricsCollector(pluginLabel string, sourceChainId, destChainId int64) *pluginMetricsCollector { + return &pluginMetricsCollector{ + pluginName: pluginLabel, + source: strconv.FormatInt(sourceChainId, 10), + dest: strconv.FormatInt(destChainId, 10), + } +} + +func (p *pluginMetricsCollector) NumberOfMessagesProcessed(phase ocrPhase, count int) { + messagesProcessed. + WithLabelValues(p.pluginName, p.source, p.dest, string(phase)). + Set(float64(count)) +} + +func (p *pluginMetricsCollector) NumberOfMessagesBasedOnInterval(phase ocrPhase, seqNrMin, seqNrMax uint64) { + messagesProcessed. + WithLabelValues(p.pluginName, p.source, p.dest, string(phase)). + Set(float64(seqNrMax - seqNrMin + 1)) +} + +func (p *pluginMetricsCollector) UnexpiredCommitRoots(count int) { + unexpiredCommitRoots. + WithLabelValues(p.pluginName, p.source, p.dest). + Set(float64(count)) +} + +func (p *pluginMetricsCollector) SequenceNumber(phase ocrPhase, seqNr uint64) { + // Don't publish price reports + if seqNr == 0 { + return + } + + sequenceNumberCounter. + WithLabelValues(p.pluginName, p.source, p.dest, string(phase)). + Set(float64(seqNr)) +} + +var ( + // NoopMetricsCollector is a no-op implementation of PluginMetricsCollector + NoopMetricsCollector PluginMetricsCollector = noop{} +) + +type noop struct{} + +func (d noop) NumberOfMessagesProcessed(ocrPhase, int) { +} + +func (d noop) NumberOfMessagesBasedOnInterval(ocrPhase, uint64, uint64) { +} + +func (d noop) UnexpiredCommitRoots(int) { +} + +func (d noop) SequenceNumber(ocrPhase, uint64) { +} diff --git a/core/services/ocr2/plugins/ccip/metrics_test.go b/core/services/ocr2/plugins/ccip/metrics_test.go new file mode 100644 index 0000000000..eec67db7dd --- /dev/null +++ b/core/services/ocr2/plugins/ccip/metrics_test.go @@ -0,0 +1,47 @@ +package ccip + +import ( + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/stretchr/testify/assert" +) + +const ( + sourceChainId = 1337 + destChainId = 2337 +) + +func Test_SequenceNumbers(t *testing.T) { + collector := NewPluginMetricsCollector("test", sourceChainId, destChainId) + + collector.SequenceNumber(Report, 10) + assert.Equal(t, float64(10), testutil.ToFloat64(sequenceNumberCounter.WithLabelValues("test", "1337", "2337", "report"))) + + collector.SequenceNumber(Report, 0) + assert.Equal(t, float64(10), testutil.ToFloat64(sequenceNumberCounter.WithLabelValues("test", "1337", "2337", "report"))) +} + +func Test_NumberOfMessages(t *testing.T) { + collector := NewPluginMetricsCollector("test", sourceChainId, destChainId) + collector2 := NewPluginMetricsCollector("test2", destChainId, sourceChainId) + + collector.NumberOfMessagesBasedOnInterval(Observation, 1, 10) + assert.Equal(t, float64(10), testutil.ToFloat64(messagesProcessed.WithLabelValues("test", "1337", "2337", "observation"))) + + collector.NumberOfMessagesBasedOnInterval(Report, 5, 30) + assert.Equal(t, float64(26), testutil.ToFloat64(messagesProcessed.WithLabelValues("test", "1337", "2337", "report"))) + + collector2.NumberOfMessagesProcessed(Report, 15) + assert.Equal(t, float64(15), testutil.ToFloat64(messagesProcessed.WithLabelValues("test2", "2337", "1337", "report"))) +} + +func Test_UnexpiredCommitRoots(t *testing.T) { + collector := NewPluginMetricsCollector("test", sourceChainId, destChainId) + + collector.UnexpiredCommitRoots(10) + assert.Equal(t, float64(10), testutil.ToFloat64(unexpiredCommitRoots.WithLabelValues("test", "1337", "2337"))) + + collector.UnexpiredCommitRoots(5) + assert.Equal(t, float64(5), testutil.ToFloat64(unexpiredCommitRoots.WithLabelValues("test", "1337", "2337"))) +} diff --git a/core/services/ocr2/plugins/ccip/observations.go b/core/services/ocr2/plugins/ccip/observations.go new file mode 100644 index 0000000000..f79d667a55 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/observations.go @@ -0,0 +1,149 @@ +package ccip + +import ( + "encoding/json" + "fmt" + "math/big" + "strings" + + "github.com/smartcontractkit/libocr/commontypes" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +// Note if a breaking change is introduced to this struct nodes running different versions +// will not be able to unmarshal each other's observations. Do not modify unless you +// know what you are doing. +type CommitObservation struct { + Interval cciptypes.CommitStoreInterval `json:"interval"` + TokenPricesUSD map[cciptypes.Address]*big.Int `json:"tokensPerFeeCoin"` + SourceGasPriceUSD *big.Int `json:"sourceGasPrice"` // Deprecated + SourceGasPriceUSDPerChain map[uint64]*big.Int `json:"sourceGasPriceUSDPerChain"` +} + +// Marshal MUST be used instead of raw json.Marshal(o) since it contains backwards compatibility related changes. +func (o CommitObservation) Marshal() ([]byte, error) { + obsCopy := o + + // Similar to: commitObservationJSONBackComp but for commit observation marshaling. + tokenPricesUSD := make(map[cciptypes.Address]*big.Int, len(obsCopy.TokenPricesUSD)) + for k, v := range obsCopy.TokenPricesUSD { + tokenPricesUSD[cciptypes.Address(strings.ToLower(string(k)))] = v + } + obsCopy.TokenPricesUSD = tokenPricesUSD + + return json.Marshal(&obsCopy) +} + +// ExecutionObservation stores messages as a map pointing from a sequence number (uint) to the message payload (MsgData) +// Having it structured this way is critical because: +// * it prevents having duplicated sequence numbers within a single ExecutionObservation (compared to the list representation) +// * prevents malicious actors from passing multiple messages with the same sequence number +// Note if a breaking change is introduced to this struct nodes running different versions +// will not be able to unmarshal each other's observations. Do not modify unless you +// know what you are doing. +type ExecutionObservation struct { + Messages map[uint64]MsgData `json:"messages"` +} + +type MsgData struct { + TokenData [][]byte `json:"tokenData"` +} + +// ObservedMessage is a transient struct used for processing convenience within the plugin. It's easier to process observed messages +// when all properties are flattened into a single structure. +// It should not be serialized and returned from types.ReportingPlugin functions, please serialize/deserialize to/from ExecutionObservation instead using NewObservedMessage +type ObservedMessage struct { + SeqNr uint64 + MsgData +} + +func NewExecutionObservation(observations []ObservedMessage) ExecutionObservation { + denormalized := make(map[uint64]MsgData, len(observations)) + for _, o := range observations { + denormalized[o.SeqNr] = MsgData{TokenData: o.TokenData} + } + return ExecutionObservation{Messages: denormalized} +} + +func NewObservedMessage(seqNr uint64, tokenData [][]byte) ObservedMessage { + return ObservedMessage{ + SeqNr: seqNr, + MsgData: MsgData{TokenData: tokenData}, + } +} + +func (o ExecutionObservation) Marshal() ([]byte, error) { + return json.Marshal(&o) +} + +// GetParsableObservations checks the given observations for formatting and value errors. +// It returns all valid observations, potentially being an empty list. It will log +// malformed observations but never error. +// +// GetParsableObservations MUST be used instead of raw json.Unmarshal(o) since it contains backwards compatibility changes. +func GetParsableObservations[O CommitObservation | ExecutionObservation](l logger.Logger, observations []types.AttributedObservation) []O { + var parseableObservations []O + var observers []commontypes.OracleID + for _, ao := range observations { + if len(ao.Observation) == 0 { + // Empty observation + l.Infow("Discarded empty observation", "observer", ao.Observer) + continue + } + var ob O + var err error + obsJSON := ao.Observation + + switch any(ob).(type) { + case CommitObservation: + commitObservation, err1 := commitObservationJSONBackComp(ao.Observation) + if err1 != nil { + l.Errorw("commit observation json backwards compatibility format failed", "err", err, + "observation", string(ao.Observation), "observer", ao.Observer) + continue + } + ob = any(commitObservation).(O) + default: + err = json.Unmarshal(obsJSON, &ob) + if err != nil { + l.Errorw("Received unmarshallable observation", "err", err, "observation", string(ao.Observation), "observer", ao.Observer) + continue + } + } + + parseableObservations = append(parseableObservations, ob) + observers = append(observers, ao.Observer) + } + l.Infow( + "Parsed observations", + "observers", observers, + "observersLength", len(observers), + "observationsLength", len(parseableObservations), + "rawObservationLength", len(observations), + ) + return parseableObservations +} + +// For backwards compatibility, converts token prices to eip55. +// Prior to cciptypes.Address we were using go-ethereum common.Address type which is +// marshalled to lower-case while the string representation we used was eip55. +// Nodes that run different ccip version should generate the same observations. +func commitObservationJSONBackComp(obsJson []byte) (CommitObservation, error) { + var obs CommitObservation + err := json.Unmarshal(obsJson, &obs) + if err != nil { + return CommitObservation{}, fmt.Errorf("unmarshal observation: %w", err) + } + tokenPricesUSD := make(map[cciptypes.Address]*big.Int, len(obs.TokenPricesUSD)) + for k, v := range obs.TokenPricesUSD { + tokenPricesUSD[ccipcalc.HexToAddress(string(k))] = v + } + obs.TokenPricesUSD = tokenPricesUSD + return obs, nil +} diff --git a/core/services/ocr2/plugins/ccip/observations_test.go b/core/services/ocr2/plugins/ccip/observations_test.go new file mode 100644 index 0000000000..a3143f157d --- /dev/null +++ b/core/services/ocr2/plugins/ccip/observations_test.go @@ -0,0 +1,305 @@ +package ccip + +import ( + "encoding/json" + "math/big" + "strings" + "testing" + + "github.com/leanovate/gopter" + "github.com/leanovate/gopter/gen" + "github.com/leanovate/gopter/prop" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" +) + +func TestObservationFilter(t *testing.T) { + lggr := logger.TestLogger(t) + obs1 := CommitObservation{Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}} + b1, err := obs1.Marshal() + require.NoError(t, err) + nonEmpty := GetParsableObservations[CommitObservation](lggr, []types.AttributedObservation{{Observation: b1}, {Observation: []byte{}}}) + require.Equal(t, 1, len(nonEmpty)) + assert.Equal(t, nonEmpty[0].Interval, obs1.Interval) +} + +// This is the observation format up to 1.4.16 release +type CommitObservationLegacy struct { + Interval cciptypes.CommitStoreInterval `json:"interval"` + TokenPricesUSD map[cciptypes.Address]*big.Int `json:"tokensPerFeeCoin"` + SourceGasPriceUSD *big.Int `json:"sourceGasPrice"` +} + +func TestObservationCompat_MultiChainGas(t *testing.T) { + obsLegacy := CommitObservationLegacy{ + Interval: cciptypes.CommitStoreInterval{ + Min: 1, + Max: 12, + }, + TokenPricesUSD: map[cciptypes.Address]*big.Int{ccipcalc.HexToAddress("0x1"): big.NewInt(1)}, + SourceGasPriceUSD: big.NewInt(3)} + bL, err := json.Marshal(obsLegacy) + require.NoError(t, err) + obsNew := CommitObservation{ + Interval: cciptypes.CommitStoreInterval{ + Min: 1, + Max: 12, + }, + TokenPricesUSD: map[cciptypes.Address]*big.Int{ccipcalc.HexToAddress("0x1"): big.NewInt(1)}, + SourceGasPriceUSD: big.NewInt(3), + } + bN, err := json.Marshal(obsNew) + require.NoError(t, err) + + observations := GetParsableObservations[CommitObservation](logger.TestLogger(t), []types.AttributedObservation{{Observation: bL}, {Observation: bN}}) + + assert.Equal(t, 2, len(observations)) + assert.Equal(t, observations[0], observations[1]) +} + +func TestCommitObservationJsonDeserialization(t *testing.T) { + expectedObservation := CommitObservation{ + Interval: cciptypes.CommitStoreInterval{ + Min: 1, + Max: 12, + }, + TokenPricesUSD: map[cciptypes.Address]*big.Int{ + ccipcalc.HexToAddress("0x1"): big.NewInt(1)}, + SourceGasPriceUSD: big.NewInt(3), + } + + json := `{ + "interval": { + "Min":1, + "Max":12 + }, + "tokensPerFeeCoin": { + "0x0000000000000000000000000000000000000001": 1 + }, + "sourceGasPrice": 3 + }` + + observations := GetParsableObservations[CommitObservation](logger.TestLogger(t), []types.AttributedObservation{{Observation: []byte(json)}}) + assert.Equal(t, 1, len(observations)) + assert.Equal(t, expectedObservation, observations[0]) +} + +func TestCommitObservationMarshal(t *testing.T) { + obs := CommitObservation{ + Interval: cciptypes.CommitStoreInterval{ + Min: 1, + Max: 12, + }, + TokenPricesUSD: map[cciptypes.Address]*big.Int{"0xAaAaAa": big.NewInt(1)}, + SourceGasPriceUSD: big.NewInt(3), + SourceGasPriceUSDPerChain: map[uint64]*big.Int{123: big.NewInt(3)}, + } + + b, err := obs.Marshal() + require.NoError(t, err) + assert.Equal(t, `{"interval":{"Min":1,"Max":12},"tokensPerFeeCoin":{"0xaaaaaa":1},"sourceGasPrice":3,"sourceGasPriceUSDPerChain":{"123":3}}`, string(b)) + + // Make sure that the call to Marshal did not alter the original observation object. + assert.Len(t, obs.TokenPricesUSD, 1) + _, exists := obs.TokenPricesUSD["0xAaAaAa"] + assert.True(t, exists) + _, exists = obs.TokenPricesUSD["0xaaaaaa"] + assert.False(t, exists) + + assert.Len(t, obs.SourceGasPriceUSDPerChain, 1) + _, exists = obs.SourceGasPriceUSDPerChain[123] + assert.True(t, exists) +} + +func TestExecutionObservationJsonDeserialization(t *testing.T) { + expectedObservation := ExecutionObservation{Messages: map[uint64]MsgData{ + 2: {TokenData: tokenData("c")}, + 1: {TokenData: tokenData("c")}, + }} + + // ["YQ=="] is "a" + // ["Yw=="] is "c" + json := `{ + "messages": { + "2":{"tokenData":["YQ=="]}, + "1":{"tokenData":["Yw=="]}, + "2":{"tokenData":["Yw=="]} + } + }` + + observations := GetParsableObservations[ExecutionObservation](logger.TestLogger(t), []types.AttributedObservation{{Observation: []byte(json)}}) + assert.Equal(t, 1, len(observations)) + assert.Equal(t, 2, len(observations[0].Messages)) + assert.Equal(t, expectedObservation, observations[0]) +} + +func TestObservationSize(t *testing.T) { + testParams := gopter.DefaultTestParameters() + testParams.MinSuccessfulTests = 100 + p := gopter.NewProperties(testParams) + p.Property("bounded observation size", prop.ForAll(func(min, max uint64) bool { + o := NewExecutionObservation( + []ObservedMessage{ + { + SeqNr: min, + MsgData: MsgData{}, + }, + { + SeqNr: max, + MsgData: MsgData{}, + }, + }, + ) + b, err := o.Marshal() + require.NoError(t, err) + return len(b) <= MaxObservationLength + }, gen.UInt64(), gen.UInt64())) + p.TestingRun(t) +} + +func TestNewExecutionObservation(t *testing.T) { + tests := []struct { + name string + observations []ObservedMessage + want ExecutionObservation + }{ + { + name: "nil observations", + observations: nil, + want: ExecutionObservation{Messages: map[uint64]MsgData{}}, + }, + { + name: "empty observations", + observations: []ObservedMessage{}, + want: ExecutionObservation{Messages: map[uint64]MsgData{}}, + }, + { + name: "observations with different sequence numbers", + observations: []ObservedMessage{ + NewObservedMessage(1, tokenData("a")), + NewObservedMessage(2, tokenData("b")), + NewObservedMessage(3, tokenData("c")), + }, + want: ExecutionObservation{ + Messages: map[uint64]MsgData{ + 1: {TokenData: tokenData("a")}, + 2: {TokenData: tokenData("b")}, + 3: {TokenData: tokenData("c")}, + }, + }, + }, + { + name: "last one wins in case of duplicates", + observations: []ObservedMessage{ + NewObservedMessage(1, tokenData("a")), + NewObservedMessage(1, tokenData("b")), + NewObservedMessage(1, tokenData("c")), + }, + want: ExecutionObservation{ + Messages: map[uint64]MsgData{ + 1: {TokenData: tokenData("c")}, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, NewExecutionObservation(tt.observations), "NewExecutionObservation(%v)", tt.observations) + }) + } +} + +func tokenData(value string) [][]byte { + return [][]byte{[]byte(value)} +} + +func TestCommitObservationJsonSerializationDeserialization(t *testing.T) { + jsonEncoded := `{ + "interval": { + "Min":1, + "Max":12 + }, + "tokensPerFeeCoin": { + "0x0000000000000000000000000000000000000001": 1, + "0x507877C2E26f1387432D067D2DaAfa7d0420d90a": 2, + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": 3 + }, + "sourceGasPrice": 3, + "sourceGasPriceUSDPerChain": { + "123":3 + } + }` + + expectedObservation := CommitObservation{ + Interval: cciptypes.CommitStoreInterval{ + Min: 1, + Max: 12, + }, + TokenPricesUSD: map[cciptypes.Address]*big.Int{ + cciptypes.Address("0x0000000000000000000000000000000000000001"): big.NewInt(1), + cciptypes.Address("0x507877C2E26f1387432D067D2DaAfa7d0420d90a"): big.NewInt(2), // json eip55->eip55 parsed + cciptypes.Address("0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa"): big.NewInt(3), // json lower->eip55 parsed + }, + SourceGasPriceUSD: big.NewInt(3), + SourceGasPriceUSDPerChain: map[uint64]*big.Int{ + 123: big.NewInt(3), + }, + } + + observations := GetParsableObservations[CommitObservation](logger.TestLogger(t), []types.AttributedObservation{ + {Observation: []byte(jsonEncoded)}, + }) + assert.Equal(t, 1, len(observations)) + assert.Equal(t, expectedObservation, observations[0]) + + backToJson, err := expectedObservation.Marshal() + // we expect the json encoded addresses to be lower-case + exp := strings.ReplaceAll( + jsonEncoded, "0x507877C2E26f1387432D067D2DaAfa7d0420d90a", strings.ToLower("0x507877C2E26f1387432D067D2DaAfa7d0420d90a")) + assert.NoError(t, err) + assert.JSONEq(t, exp, string(backToJson)) + + // and we expect to get the same results after we parse the lower-case addresses + observations = GetParsableObservations[CommitObservation](logger.TestLogger(t), []types.AttributedObservation{ + {Observation: []byte(jsonEncoded)}, + }) + assert.Equal(t, 1, len(observations)) + assert.Equal(t, expectedObservation, observations[0]) +} + +func TestAddressEncodingBackwardsCompatibility(t *testing.T) { + // The intention of this test is to remind including proper formatting of addresses after config is updated. + // + // The following tests will fail when a new cciptypes.Address field is added or removed. + // If you notice that the test is failing, make sure to apply proper address formatting + // after the struct is marshalled/unmarshalled and then include your new field in the expected fields slice to + // make this test pass or if you removed a field, remove it from the expected fields slice. + + t.Run("job spec config", func(t *testing.T) { + exp := []string{"ccip.Address OffRamp"} + + fields := testhelpers.FindStructFieldsOfCertainType( + "ccip.Address", + config.CommitPluginJobSpecConfig{PriceGetterConfig: &config.DynamicPriceGetterConfig{}}, + ) + assert.Equal(t, exp, fields) + }) + + t.Run("commit observation", func(t *testing.T) { + exp := []string{"map[ccip.Address]*big.Int TokenPricesUSD"} + + fields := testhelpers.FindStructFieldsOfCertainType( + "ccip.Address", + CommitObservation{SourceGasPriceUSD: big.NewInt(0)}, + ) + assert.Equal(t, exp, fields) + }) +} diff --git a/core/services/ocr2/plugins/ccip/pkg/leafer/leafer.go b/core/services/ocr2/plugins/ccip/pkg/leafer/leafer.go new file mode 100644 index 0000000000..c334f159fd --- /dev/null +++ b/core/services/ocr2/plugins/ccip/pkg/leafer/leafer.go @@ -0,0 +1,61 @@ +package leafer + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0" +) + +// LeafHasher converts a CCIPSendRequested event into something that can be hashed and hashes it. +type LeafHasher interface { + HashLeaf(log types.Log) ([32]byte, error) +} + +// Version is the contract to use. +type Version string + +const ( + V1_0_0 Version = "v1_0_0" + V1_2_0 Version = "v1_2_0" + V1_5_0 Version = "v1_5_0" +) + +// MakeLeafHasher is a factory function to construct the onramp implementing the HashLeaf function for a given version. +func MakeLeafHasher(ver Version, cl bind.ContractBackend, sourceChainSelector uint64, destChainSelector uint64, onRampId common.Address, ctx hashutil.Hasher[[32]byte]) (LeafHasher, error) { + switch ver { + case V1_0_0: + or, err := evm_2_evm_onramp_1_0_0.NewEVM2EVMOnRamp(onRampId, cl) + if err != nil { + return nil, err + } + h := v1_0_0.NewLeafHasher(sourceChainSelector, destChainSelector, onRampId, ctx, or) + return h, nil + case V1_2_0: + or, err := evm_2_evm_onramp_1_2_0.NewEVM2EVMOnRamp(onRampId, cl) + if err != nil { + return nil, err + } + h := v1_2_0.NewLeafHasher(sourceChainSelector, destChainSelector, onRampId, ctx, or) + return h, nil + case V1_5_0: + or, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampId, cl) + if err != nil { + return nil, err + } + h := v1_5_0.NewLeafHasher(sourceChainSelector, destChainSelector, onRampId, ctx, or) + return h, nil + default: + return nil, fmt.Errorf("unknown version %q", ver) + } +} diff --git a/core/services/ocr2/plugins/ccip/prices/da_price_estimator.go b/core/services/ocr2/plugins/ccip/prices/da_price_estimator.go new file mode 100644 index 0000000000..7c75b9bdd9 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/da_price_estimator.go @@ -0,0 +1,176 @@ +package prices + +import ( + "context" + "fmt" + "math/big" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +type DAGasPriceEstimator struct { + execEstimator GasPriceEstimator + l1Oracle rollups.L1Oracle + priceEncodingLength uint + daDeviationPPB int64 + daOverheadGas int64 + gasPerDAByte int64 + daMultiplier int64 +} + +func NewDAGasPriceEstimator( + estimator gas.EvmFeeEstimator, + maxGasPrice *big.Int, + deviationPPB int64, + daDeviationPPB int64, +) *DAGasPriceEstimator { + return &DAGasPriceEstimator{ + execEstimator: NewExecGasPriceEstimator(estimator, maxGasPrice, deviationPPB), + l1Oracle: estimator.L1Oracle(), + priceEncodingLength: daGasPriceEncodingLength, + daDeviationPPB: daDeviationPPB, + } +} + +func (g DAGasPriceEstimator) GetGasPrice(ctx context.Context) (*big.Int, error) { + execGasPrice, err := g.execEstimator.GetGasPrice(ctx) + if err != nil { + return nil, err + } + var gasPrice *big.Int = execGasPrice + if gasPrice.BitLen() > int(g.priceEncodingLength) { + return nil, fmt.Errorf("native gas price exceeded max range %+v", gasPrice) + } + + if g.l1Oracle == nil { + return gasPrice, nil + } + + daGasPriceWei, err := g.l1Oracle.GasPrice(ctx) + if err != nil { + return nil, err + } + + if daGasPrice := daGasPriceWei.ToInt(); daGasPrice.Cmp(big.NewInt(0)) > 0 { + if daGasPrice.BitLen() > int(g.priceEncodingLength) { + return nil, fmt.Errorf("data availability gas price exceeded max range %+v", daGasPrice) + } + + daGasPrice = new(big.Int).Lsh(daGasPrice, g.priceEncodingLength) + gasPrice = new(big.Int).Add(gasPrice, daGasPrice) + } + + return gasPrice, nil +} + +func (g DAGasPriceEstimator) DenoteInUSD(p *big.Int, wrappedNativePrice *big.Int) (*big.Int, error) { + daGasPrice, execGasPrice, err := g.parseEncodedGasPrice(p) + if err != nil { + return nil, err + } + + // This assumes l1GasPrice is priced using the same native token as l2 native + daUSD := ccipcalc.CalculateUsdPerUnitGas(daGasPrice, wrappedNativePrice) + if daUSD.BitLen() > int(g.priceEncodingLength) { + return nil, fmt.Errorf("data availability gas price USD exceeded max range %+v", daUSD) + } + execUSD := ccipcalc.CalculateUsdPerUnitGas(execGasPrice, wrappedNativePrice) + if execUSD.BitLen() > int(g.priceEncodingLength) { + return nil, fmt.Errorf("exec gas price USD exceeded max range %+v", execUSD) + } + + daUSD = new(big.Int).Lsh(daUSD, g.priceEncodingLength) + return new(big.Int).Add(daUSD, execUSD), nil +} + +func (g DAGasPriceEstimator) Median(gasPrices []*big.Int) (*big.Int, error) { + daPrices := make([]*big.Int, len(gasPrices)) + execPrices := make([]*big.Int, len(gasPrices)) + + for i := range gasPrices { + daGasPrice, execGasPrice, err := g.parseEncodedGasPrice(gasPrices[i]) + if err != nil { + return nil, err + } + + daPrices[i] = daGasPrice + execPrices[i] = execGasPrice + } + + daMedian := ccipcalc.BigIntSortedMiddle(daPrices) + execMedian := ccipcalc.BigIntSortedMiddle(execPrices) + + daMedian = new(big.Int).Lsh(daMedian, g.priceEncodingLength) + return new(big.Int).Add(daMedian, execMedian), nil +} + +func (g DAGasPriceEstimator) Deviates(p1, p2 *big.Int) (bool, error) { + p1DAGasPrice, p1ExecGasPrice, err := g.parseEncodedGasPrice(p1) + if err != nil { + return false, err + } + p2DAGasPrice, p2ExecGasPrice, err := g.parseEncodedGasPrice(p2) + if err != nil { + return false, err + } + + execDeviates, err := g.execEstimator.Deviates(p1ExecGasPrice, p2ExecGasPrice) + if err != nil { + return false, err + } + if execDeviates { + return execDeviates, nil + } + + return ccipcalc.Deviates(p1DAGasPrice, p2DAGasPrice, g.daDeviationPPB), nil +} + +func (g DAGasPriceEstimator) EstimateMsgCostUSD(p *big.Int, wrappedNativePrice *big.Int, msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error) { + daGasPrice, execGasPrice, err := g.parseEncodedGasPrice(p) + if err != nil { + return nil, err + } + + execCostUSD, err := g.execEstimator.EstimateMsgCostUSD(execGasPrice, wrappedNativePrice, msg) + if err != nil { + return nil, err + } + + // If there is data availability price component, then include data availability cost in fee estimation + if daGasPrice.Cmp(big.NewInt(0)) > 0 { + daGasCostUSD := g.estimateDACostUSD(daGasPrice, wrappedNativePrice, msg) + execCostUSD = new(big.Int).Add(daGasCostUSD, execCostUSD) + } + return execCostUSD, nil +} + +func (g DAGasPriceEstimator) parseEncodedGasPrice(p *big.Int) (*big.Int, *big.Int, error) { + if p.BitLen() > int(g.priceEncodingLength*2) { + return nil, nil, fmt.Errorf("encoded gas price exceeded max range %+v", p) + } + + daGasPrice := new(big.Int).Rsh(p, g.priceEncodingLength) + + daStart := new(big.Int).Lsh(big.NewInt(1), g.priceEncodingLength) + execGasPrice := new(big.Int).Mod(p, daStart) + + return daGasPrice, execGasPrice, nil +} + +func (g DAGasPriceEstimator) estimateDACostUSD(daGasPrice *big.Int, wrappedNativePrice *big.Int, msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) *big.Int { + var sourceTokenDataLen int + for _, tokenData := range msg.SourceTokenData { + sourceTokenDataLen += len(tokenData) + } + + dataLen := evmMessageFixedBytes + len(msg.Data) + len(msg.TokenAmounts)*evmMessageBytesPerToken + sourceTokenDataLen + dataGas := big.NewInt(int64(dataLen)*g.gasPerDAByte + g.daOverheadGas) + + dataGasEstimate := new(big.Int).Mul(dataGas, daGasPrice) + dataGasEstimate = new(big.Int).Div(new(big.Int).Mul(dataGasEstimate, big.NewInt(g.daMultiplier)), big.NewInt(daMultiplierBase)) + + return ccipcalc.CalculateUsdPerUnitGas(dataGasEstimate, wrappedNativePrice) +} diff --git a/core/services/ocr2/plugins/ccip/prices/da_price_estimator_test.go b/core/services/ocr2/plugins/ccip/prices/da_price_estimator_test.go new file mode 100644 index 0000000000..2f8616a866 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/da_price_estimator_test.go @@ -0,0 +1,440 @@ +package prices + +import ( + "context" + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks" +) + +func encodeGasPrice(daPrice, execPrice *big.Int) *big.Int { + return new(big.Int).Add(new(big.Int).Lsh(daPrice, daGasPriceEncodingLength), execPrice) +} + +func TestDAPriceEstimator_GetGasPrice(t *testing.T) { + ctx := context.Background() + + testCases := []struct { + name string + daGasPrice *big.Int + execGasPrice *big.Int + expPrice *big.Int + expErr bool + }{ + { + name: "base", + daGasPrice: big.NewInt(1), + execGasPrice: big.NewInt(0), + expPrice: encodeGasPrice(big.NewInt(1), big.NewInt(0)), + expErr: false, + }, + { + name: "large values", + daGasPrice: big.NewInt(1e9), // 1 gwei + execGasPrice: big.NewInt(200e9), // 200 gwei + expPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(200e9)), + expErr: false, + }, + { + name: "zero DA price", + daGasPrice: big.NewInt(0), + execGasPrice: big.NewInt(200e9), + expPrice: encodeGasPrice(big.NewInt(0), big.NewInt(200e9)), + expErr: false, + }, + { + name: "zero exec price", + daGasPrice: big.NewInt(1e9), + execGasPrice: big.NewInt(0), + expPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(0)), + expErr: false, + }, + { + name: "price out of bounds", + daGasPrice: new(big.Int).Lsh(big.NewInt(1), daGasPriceEncodingLength), + execGasPrice: big.NewInt(1), + expPrice: nil, + expErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + execEstimator := NewMockGasPriceEstimator(t) + execEstimator.On("GetGasPrice", ctx).Return(tc.execGasPrice, nil) + + l1Oracle := mocks.NewL1Oracle(t) + l1Oracle.On("GasPrice", ctx).Return(assets.NewWei(tc.daGasPrice), nil) + + g := DAGasPriceEstimator{ + execEstimator: execEstimator, + l1Oracle: l1Oracle, + priceEncodingLength: daGasPriceEncodingLength, + } + + gasPrice, err := g.GetGasPrice(ctx) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, tc.expPrice, gasPrice) + }) + } + + t.Run("nil L1 oracle", func(t *testing.T) { + expPrice := big.NewInt(1) + + execEstimator := NewMockGasPriceEstimator(t) + execEstimator.On("GetGasPrice", ctx).Return(expPrice, nil) + + g := DAGasPriceEstimator{ + execEstimator: execEstimator, + l1Oracle: nil, + priceEncodingLength: daGasPriceEncodingLength, + } + + gasPrice, err := g.GetGasPrice(ctx) + assert.NoError(t, err) + assert.Equal(t, expPrice, gasPrice) + }) +} + +func TestDAPriceEstimator_DenoteInUSD(t *testing.T) { + val1e18 := func(val int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(val)) } + + testCases := []struct { + name string + gasPrice *big.Int + nativePrice *big.Int + expPrice *big.Int + }{ + { + name: "base", + gasPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(10e9)), + nativePrice: val1e18(2_000), + expPrice: encodeGasPrice(big.NewInt(2000e9), big.NewInt(20000e9)), + }, + { + name: "low price truncates to 0", + gasPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(10e9)), + nativePrice: big.NewInt(1), + expPrice: big.NewInt(0), + }, + { + name: "high price", + gasPrice: encodeGasPrice(val1e18(1), val1e18(10)), + nativePrice: val1e18(2000), + expPrice: encodeGasPrice(val1e18(2_000), val1e18(20_000)), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := DAGasPriceEstimator{ + priceEncodingLength: daGasPriceEncodingLength, + } + + gasPrice, err := g.DenoteInUSD(tc.gasPrice, tc.nativePrice) + assert.NoError(t, err) + assert.True(t, tc.expPrice.Cmp(gasPrice) == 0) + }) + } +} + +func TestDAPriceEstimator_Median(t *testing.T) { + val1e18 := func(val int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(val)) } + + testCases := []struct { + name string + gasPrices []*big.Int + expMedian *big.Int + }{ + { + name: "base", + gasPrices: []*big.Int{ + encodeGasPrice(big.NewInt(1), big.NewInt(1)), + encodeGasPrice(big.NewInt(2), big.NewInt(2)), + encodeGasPrice(big.NewInt(3), big.NewInt(3)), + }, + expMedian: encodeGasPrice(big.NewInt(2), big.NewInt(2)), + }, + { + name: "median 2", + gasPrices: []*big.Int{ + encodeGasPrice(big.NewInt(1), big.NewInt(1)), + encodeGasPrice(big.NewInt(2), big.NewInt(2)), + }, + expMedian: encodeGasPrice(big.NewInt(2), big.NewInt(2)), + }, + { + name: "large values", + gasPrices: []*big.Int{ + encodeGasPrice(val1e18(5), val1e18(5)), + encodeGasPrice(val1e18(4), val1e18(4)), + encodeGasPrice(val1e18(3), val1e18(3)), + encodeGasPrice(val1e18(2), val1e18(2)), + encodeGasPrice(val1e18(1), val1e18(1)), + }, + expMedian: encodeGasPrice(val1e18(3), val1e18(3)), + }, + { + name: "zeros", + gasPrices: []*big.Int{big.NewInt(0), big.NewInt(0), big.NewInt(0)}, + expMedian: big.NewInt(0), + }, + { + name: "picks median of each price component individually", + gasPrices: []*big.Int{ + encodeGasPrice(val1e18(1), val1e18(3)), + encodeGasPrice(val1e18(2), val1e18(2)), + encodeGasPrice(val1e18(3), val1e18(1)), + }, + expMedian: encodeGasPrice(val1e18(2), val1e18(2)), + }, + { + name: "unsorted even number of price components", + gasPrices: []*big.Int{ + encodeGasPrice(val1e18(1), val1e18(22)), + encodeGasPrice(val1e18(4), val1e18(33)), + encodeGasPrice(val1e18(2), val1e18(44)), + encodeGasPrice(val1e18(3), val1e18(11)), + }, + expMedian: encodeGasPrice(val1e18(3), val1e18(33)), + }, + { + name: "equal DA price components", + gasPrices: []*big.Int{ + encodeGasPrice(val1e18(2), val1e18(22)), + encodeGasPrice(val1e18(2), val1e18(33)), + encodeGasPrice(val1e18(2), val1e18(44)), + encodeGasPrice(val1e18(2), val1e18(11)), + }, + expMedian: encodeGasPrice(val1e18(2), val1e18(33)), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := DAGasPriceEstimator{ + priceEncodingLength: daGasPriceEncodingLength, + } + + gasPrice, err := g.Median(tc.gasPrices) + assert.NoError(t, err) + assert.True(t, tc.expMedian.Cmp(gasPrice) == 0) + }) + } +} + +func TestDAPriceEstimator_Deviates(t *testing.T) { + testCases := []struct { + name string + gasPrice1 *big.Int + gasPrice2 *big.Int + daDeviationPPB int64 + execDeviationPPB int64 + expDeviates bool + }{ + { + name: "base", + gasPrice1: encodeGasPrice(big.NewInt(100e8), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(79e8), big.NewInt(79e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: true, + }, + { + name: "negative difference also deviates", + gasPrice1: encodeGasPrice(big.NewInt(100e8), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(121e8), big.NewInt(121e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: true, + }, + { + name: "only DA component deviates", + gasPrice1: encodeGasPrice(big.NewInt(100e8), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(150e8), big.NewInt(110e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: true, + }, + { + name: "only exec component deviates", + gasPrice1: encodeGasPrice(big.NewInt(100e8), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(110e8), big.NewInt(150e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: true, + }, + { + name: "both do not deviate", + gasPrice1: encodeGasPrice(big.NewInt(100e8), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(110e8), big.NewInt(110e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: false, + }, + { + name: "zero DA price and exec deviates", + gasPrice1: encodeGasPrice(big.NewInt(0), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(0), big.NewInt(121e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: true, + }, + { + name: "zero DA price and exec does not deviate", + gasPrice1: encodeGasPrice(big.NewInt(0), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(0), big.NewInt(110e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := DAGasPriceEstimator{ + execEstimator: ExecGasPriceEstimator{ + deviationPPB: tc.execDeviationPPB, + }, + daDeviationPPB: tc.daDeviationPPB, + priceEncodingLength: daGasPriceEncodingLength, + } + + deviated, err := g.Deviates(tc.gasPrice1, tc.gasPrice2) + assert.NoError(t, err) + if tc.expDeviates { + assert.True(t, deviated) + } else { + assert.False(t, deviated) + } + }) + } +} + +func TestDAPriceEstimator_EstimateMsgCostUSD(t *testing.T) { + execCostUSD := big.NewInt(100_000) + + testCases := []struct { + name string + gasPrice *big.Int + wrappedNativePrice *big.Int + msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta + daOverheadGas int64 + gasPerDAByte int64 + daMultiplier int64 + expUSD *big.Int + }{ + { + name: "only DA overhead", + gasPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(0)), // 1 gwei DA price, 0 exec price + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + Data: []byte{}, + TokenAmounts: []cciptypes.TokenAmount{}, + SourceTokenData: [][]byte{}, + }, + }, + daOverheadGas: 100_000, + gasPerDAByte: 0, + daMultiplier: 10_000, // 1x multiplier + expUSD: new(big.Int).Add(execCostUSD, big.NewInt(100_000e9)), + }, + { + name: "include message data gas", + gasPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(0)), // 1 gwei DA price, 0 exec price + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + Data: make([]byte, 1_000), + TokenAmounts: make([]cciptypes.TokenAmount, 5), + SourceTokenData: [][]byte{ + make([]byte, 10), make([]byte, 10), make([]byte, 10), make([]byte, 10), make([]byte, 10), + }, + }, + }, + daOverheadGas: 100_000, + gasPerDAByte: 16, + daMultiplier: 10_000, // 1x multiplier + expUSD: new(big.Int).Add(execCostUSD, big.NewInt(134_208e9)), + }, + { + name: "zero DA price", + gasPrice: big.NewInt(0), // 1 gwei DA price, 0 exec price + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + Data: []byte{}, + TokenAmounts: []cciptypes.TokenAmount{}, + SourceTokenData: [][]byte{}, + }, + }, + daOverheadGas: 100_000, + gasPerDAByte: 16, + daMultiplier: 10_000, // 1x multiplier + expUSD: execCostUSD, + }, + { + name: "double native price", + gasPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(0)), // 1 gwei DA price, 0 exec price + wrappedNativePrice: big.NewInt(2e18), // $1 + msg: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + Data: []byte{}, + TokenAmounts: []cciptypes.TokenAmount{}, + SourceTokenData: [][]byte{}, + }, + }, + daOverheadGas: 100_000, + gasPerDAByte: 0, + daMultiplier: 10_000, // 1x multiplier + expUSD: new(big.Int).Add(execCostUSD, big.NewInt(200_000e9)), + }, + { + name: "half multiplier", + gasPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(0)), // 1 gwei DA price, 0 exec price + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + Data: []byte{}, + TokenAmounts: []cciptypes.TokenAmount{}, + SourceTokenData: [][]byte{}, + }, + }, + daOverheadGas: 100_000, + gasPerDAByte: 0, + daMultiplier: 5_000, // 0.5x multiplier + expUSD: new(big.Int).Add(execCostUSD, big.NewInt(50_000e9)), + }, + } + + for _, tc := range testCases { + execEstimator := NewMockGasPriceEstimator(t) + execEstimator.On("EstimateMsgCostUSD", mock.Anything, tc.wrappedNativePrice, tc.msg).Return(execCostUSD, nil) + + t.Run(tc.name, func(t *testing.T) { + g := DAGasPriceEstimator{ + execEstimator: execEstimator, + l1Oracle: nil, + priceEncodingLength: daGasPriceEncodingLength, + daOverheadGas: tc.daOverheadGas, + gasPerDAByte: tc.gasPerDAByte, + daMultiplier: tc.daMultiplier, + } + + costUSD, err := g.EstimateMsgCostUSD(tc.gasPrice, tc.wrappedNativePrice, tc.msg) + assert.NoError(t, err) + assert.Equal(t, tc.expUSD, costUSD) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go new file mode 100644 index 0000000000..56e1ddb583 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go @@ -0,0 +1,65 @@ +package prices + +import ( + "context" + "fmt" + "math/big" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +type ExecGasPriceEstimator struct { + estimator gas.EvmFeeEstimator + maxGasPrice *big.Int + deviationPPB int64 +} + +func NewExecGasPriceEstimator(estimator gas.EvmFeeEstimator, maxGasPrice *big.Int, deviationPPB int64) ExecGasPriceEstimator { + return ExecGasPriceEstimator{ + estimator: estimator, + maxGasPrice: maxGasPrice, + deviationPPB: deviationPPB, + } +} + +func (g ExecGasPriceEstimator) GetGasPrice(ctx context.Context) (*big.Int, error) { + gasPriceWei, _, err := g.estimator.GetFee(ctx, nil, 0, assets.NewWei(g.maxGasPrice)) + if err != nil { + return nil, err + } + // Use legacy if no dynamic is available. + gasPrice := gasPriceWei.Legacy.ToInt() + if gasPriceWei.DynamicFeeCap != nil { + gasPrice = gasPriceWei.DynamicFeeCap.ToInt() + } + if gasPrice == nil { + return nil, fmt.Errorf("missing gas price %+v", gasPriceWei) + } + + return gasPrice, nil +} + +func (g ExecGasPriceEstimator) DenoteInUSD(p *big.Int, wrappedNativePrice *big.Int) (*big.Int, error) { + return ccipcalc.CalculateUsdPerUnitGas(p, wrappedNativePrice), nil +} + +func (g ExecGasPriceEstimator) Median(gasPrices []*big.Int) (*big.Int, error) { + return ccipcalc.BigIntSortedMiddle(gasPrices), nil +} + +func (g ExecGasPriceEstimator) Deviates(p1 *big.Int, p2 *big.Int) (bool, error) { + return ccipcalc.Deviates(p1, p2, g.deviationPPB), nil +} + +func (g ExecGasPriceEstimator) EstimateMsgCostUSD(p *big.Int, wrappedNativePrice *big.Int, msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error) { + execGasAmount := new(big.Int).Add(big.NewInt(feeBoostingOverheadGas), msg.GasLimit) + execGasAmount = new(big.Int).Add(execGasAmount, new(big.Int).Mul(big.NewInt(int64(len(msg.Data))), big.NewInt(execGasPerPayloadByte))) + execGasAmount = new(big.Int).Add(execGasAmount, new(big.Int).Mul(big.NewInt(int64(len(msg.TokenAmounts))), big.NewInt(execGasPerToken))) + + execGasCost := new(big.Int).Mul(execGasAmount, p) + + return ccipcalc.CalculateUsdPerUnitGas(execGasCost, wrappedNativePrice), nil +} diff --git a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go new file mode 100644 index 0000000000..e1c2fa0398 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go @@ -0,0 +1,351 @@ +package prices + +import ( + "context" + "math/big" + "testing" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" +) + +func TestExecPriceEstimator_GetGasPrice(t *testing.T) { + ctx := context.Background() + + testCases := []struct { + name string + sourceFeeEstimatorRespFee gas.EvmFee + sourceFeeEstimatorRespErr error + maxGasPrice *big.Int + expPrice *big.Int + expErr bool + }{ + { + name: "gets legacy gas price", + sourceFeeEstimatorRespFee: gas.EvmFee{ + Legacy: assets.NewWei(big.NewInt(10)), + DynamicFeeCap: nil, + }, + sourceFeeEstimatorRespErr: nil, + maxGasPrice: big.NewInt(1), + expPrice: big.NewInt(10), + expErr: false, + }, + { + name: "gets dynamic gas price", + sourceFeeEstimatorRespFee: gas.EvmFee{ + Legacy: nil, + DynamicFeeCap: assets.NewWei(big.NewInt(20)), + }, + sourceFeeEstimatorRespErr: nil, + maxGasPrice: big.NewInt(1), + expPrice: big.NewInt(20), + expErr: false, + }, + { + name: "gets dynamic gas price over legacy gas price", + sourceFeeEstimatorRespFee: gas.EvmFee{ + Legacy: assets.NewWei(big.NewInt(10)), + DynamicFeeCap: assets.NewWei(big.NewInt(20)), + }, + sourceFeeEstimatorRespErr: nil, + maxGasPrice: big.NewInt(1), + expPrice: big.NewInt(20), + expErr: false, + }, + { + name: "fee estimator error", + sourceFeeEstimatorRespFee: gas.EvmFee{ + Legacy: assets.NewWei(big.NewInt(10)), + DynamicFeeCap: nil, + }, + sourceFeeEstimatorRespErr: errors.New("fee estimator error"), + maxGasPrice: big.NewInt(1), + expPrice: nil, + expErr: true, + }, + { + name: "nil gas price error", + sourceFeeEstimatorRespFee: gas.EvmFee{ + Legacy: nil, + DynamicFeeCap: nil, + }, + sourceFeeEstimatorRespErr: nil, + maxGasPrice: big.NewInt(1), + expPrice: nil, + expErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + sourceFeeEstimator := mocks.NewEvmFeeEstimator(t) + sourceFeeEstimator.On("GetFee", ctx, []byte(nil), uint64(0), assets.NewWei(tc.maxGasPrice)).Return( + tc.sourceFeeEstimatorRespFee, uint64(0), tc.sourceFeeEstimatorRespErr) + + g := ExecGasPriceEstimator{ + estimator: sourceFeeEstimator, + maxGasPrice: tc.maxGasPrice, + } + + gasPrice, err := g.GetGasPrice(ctx) + if tc.expErr { + assert.Nil(t, gasPrice) + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, tc.expPrice, gasPrice) + }) + } +} + +func TestExecPriceEstimator_DenoteInUSD(t *testing.T) { + val1e18 := func(val int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(val)) } + + testCases := []struct { + name string + gasPrice *big.Int + nativePrice *big.Int + expPrice *big.Int + }{ + { + name: "base", + gasPrice: big.NewInt(1e9), + nativePrice: val1e18(2_000), + expPrice: big.NewInt(2_000e9), + }, + { + name: "low price truncates to 0", + gasPrice: big.NewInt(1e9), + nativePrice: big.NewInt(1), + expPrice: big.NewInt(0), + }, + { + name: "high price", + gasPrice: val1e18(1), + nativePrice: val1e18(2_000), + expPrice: val1e18(2_000), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := ExecGasPriceEstimator{} + + gasPrice, err := g.DenoteInUSD(tc.gasPrice, tc.nativePrice) + assert.NoError(t, err) + assert.True(t, tc.expPrice.Cmp(gasPrice) == 0) + }) + } +} + +func TestExecPriceEstimator_Median(t *testing.T) { + val1e18 := func(val int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(val)) } + + testCases := []struct { + name string + gasPrices []*big.Int + expMedian *big.Int + }{ + { + name: "base", + gasPrices: []*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}, + expMedian: big.NewInt(2), + }, + { + name: "median 1", + gasPrices: []*big.Int{big.NewInt(1)}, + expMedian: big.NewInt(1), + }, + { + name: "median 2", + gasPrices: []*big.Int{big.NewInt(1), big.NewInt(2)}, + expMedian: big.NewInt(2), + }, + { + name: "large values", + gasPrices: []*big.Int{val1e18(5), val1e18(4), val1e18(3), val1e18(2), val1e18(1)}, + expMedian: val1e18(3), + }, + { + name: "zeros", + gasPrices: []*big.Int{big.NewInt(0), big.NewInt(0), big.NewInt(0)}, + expMedian: big.NewInt(0), + }, + { + name: "unsorted even number of prices", + gasPrices: []*big.Int{big.NewInt(4), big.NewInt(2), big.NewInt(3), big.NewInt(1)}, + expMedian: big.NewInt(3), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := ExecGasPriceEstimator{} + + gasPrice, err := g.Median(tc.gasPrices) + assert.NoError(t, err) + assert.True(t, tc.expMedian.Cmp(gasPrice) == 0) + }) + } +} + +func TestExecPriceEstimator_Deviates(t *testing.T) { + testCases := []struct { + name string + gasPrice1 *big.Int + gasPrice2 *big.Int + deviationPPB int64 + expDeviates bool + }{ + { + name: "base", + gasPrice1: big.NewInt(100e8), + gasPrice2: big.NewInt(79e8), + deviationPPB: 2e8, + expDeviates: true, + }, + { + name: "negative difference also deviates", + gasPrice1: big.NewInt(100e8), + gasPrice2: big.NewInt(121e8), + deviationPPB: 2e8, + expDeviates: true, + }, + { + name: "larger difference deviates", + gasPrice1: big.NewInt(100e8), + gasPrice2: big.NewInt(70e8), + deviationPPB: 2e8, + expDeviates: true, + }, + { + name: "smaller difference does not deviate", + gasPrice1: big.NewInt(100e8), + gasPrice2: big.NewInt(90e8), + deviationPPB: 2e8, + expDeviates: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := ExecGasPriceEstimator{ + deviationPPB: tc.deviationPPB, + } + + deviated, err := g.Deviates(tc.gasPrice1, tc.gasPrice2) + assert.NoError(t, err) + if tc.expDeviates { + assert.True(t, deviated) + } else { + assert.False(t, deviated) + } + }) + } +} + +func TestExecPriceEstimator_EstimateMsgCostUSD(t *testing.T) { + testCases := []struct { + name string + gasPrice *big.Int + wrappedNativePrice *big.Int + msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta + expUSD *big.Int + }{ + { + name: "base", + gasPrice: big.NewInt(1e9), // 1 gwei + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + GasLimit: big.NewInt(100_000), + Data: []byte{}, + TokenAmounts: []cciptypes.TokenAmount{}, + }, + }, + expUSD: big.NewInt(300_000e9), + }, + { + name: "base with data", + gasPrice: big.NewInt(1e9), // 1 gwei + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + GasLimit: big.NewInt(100_000), + Data: make([]byte, 1_000), + TokenAmounts: []cciptypes.TokenAmount{}, + }, + }, + expUSD: big.NewInt(316_000e9), + }, + { + name: "base with data and tokens", + gasPrice: big.NewInt(1e9), // 1 gwei + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + GasLimit: big.NewInt(100_000), + Data: make([]byte, 1_000), + TokenAmounts: make([]cciptypes.TokenAmount, 5), + }, + }, + expUSD: big.NewInt(366_000e9), + }, + { + name: "empty msg", + gasPrice: big.NewInt(1e9), // 1 gwei + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + GasLimit: big.NewInt(0), + Data: []byte{}, + TokenAmounts: []cciptypes.TokenAmount{}, + }, + }, + expUSD: big.NewInt(200_000e9), + }, + { + name: "double native price", + gasPrice: big.NewInt(1e9), // 1 gwei + wrappedNativePrice: big.NewInt(2e18), // $1 + msg: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + GasLimit: big.NewInt(0), + Data: []byte{}, + TokenAmounts: []cciptypes.TokenAmount{}, + }, + }, + expUSD: big.NewInt(400_000e9), + }, + { + name: "zero gas price", + gasPrice: big.NewInt(0), // 1 gwei + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + GasLimit: big.NewInt(0), + Data: []byte{}, + TokenAmounts: []cciptypes.TokenAmount{}, + }, + }, + expUSD: big.NewInt(0), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := ExecGasPriceEstimator{} + + costUSD, err := g.EstimateMsgCostUSD(tc.gasPrice, tc.wrappedNativePrice, tc.msg) + assert.NoError(t, err) + assert.Equal(t, tc.expUSD, costUSD) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/prices/gas_price_estimator.go b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator.go new file mode 100644 index 0000000000..49a6fbcc4a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator.go @@ -0,0 +1,59 @@ +package prices + +import ( + "math/big" + + "github.com/Masterminds/semver/v3" + "github.com/pkg/errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" +) + +const ( + feeBoostingOverheadGas = 200_000 + // execGasPerToken is lower-bound estimation of ERC20 releaseOrMint gas cost (Mint with static minter). + // Use this in per-token gas cost calc as heuristic to simplify estimation logic. + execGasPerToken = 10_000 + // execGasPerPayloadByte is gas charged for passing each byte of `data` payload to CCIP receiver, ignores 4 gas per 0-byte rule. + // This can be a constant as it is part of EVM spec. Changes should be rare. + execGasPerPayloadByte = 16 + // evmMessageFixedBytes is byte size of fixed-size fields in EVM2EVMMessage + // Updating EVM2EVMMessage involves an offchain upgrade, safe to keep this as constant in code. + evmMessageFixedBytes = 448 + evmMessageBytesPerToken = 128 // Byte size of each token transfer, consisting of 1 EVMTokenAmount and 1 bytes, excl length of bytes + daMultiplierBase = int64(10000) // DA multiplier is in multiples of 0.0001, i.e. 1/daMultiplierBase + daGasPriceEncodingLength = 112 // Each gas price takes up at most GasPriceEncodingLength number of bits +) + +// GasPriceEstimatorCommit provides gasPriceEstimatorCommon + features needed in commit plugin, e.g. price deviation check. +type GasPriceEstimatorCommit interface { + cciptypes.GasPriceEstimatorCommit +} + +// GasPriceEstimatorExec provides gasPriceEstimatorCommon + features needed in exec plugin, e.g. message cost estimation. +type GasPriceEstimatorExec interface { + cciptypes.GasPriceEstimatorExec +} + +// GasPriceEstimator provides complete gas price estimator functions. +type GasPriceEstimator interface { + cciptypes.GasPriceEstimator +} + +func NewGasPriceEstimatorForCommitPlugin( + commitStoreVersion semver.Version, + estimator gas.EvmFeeEstimator, + maxExecGasPrice *big.Int, + daDeviationPPB int64, + execDeviationPPB int64, +) (GasPriceEstimatorCommit, error) { + switch commitStoreVersion.String() { + case "1.0.0", "1.1.0": + return NewExecGasPriceEstimator(estimator, maxExecGasPrice, execDeviationPPB), nil + case "1.2.0": + return NewDAGasPriceEstimator(estimator, maxExecGasPrice, execDeviationPPB, daDeviationPPB), nil + default: + return nil, errors.Errorf("Invalid commitStore version: %s", commitStoreVersion) + } +} diff --git a/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_commit_mock.go b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_commit_mock.go new file mode 100644 index 0000000000..0a366a66ac --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_commit_mock.go @@ -0,0 +1,269 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package prices + +import ( + context "context" + big "math/big" + + mock "github.com/stretchr/testify/mock" +) + +// MockGasPriceEstimatorCommit is an autogenerated mock type for the GasPriceEstimatorCommit type +type MockGasPriceEstimatorCommit struct { + mock.Mock +} + +type MockGasPriceEstimatorCommit_Expecter struct { + mock *mock.Mock +} + +func (_m *MockGasPriceEstimatorCommit) EXPECT() *MockGasPriceEstimatorCommit_Expecter { + return &MockGasPriceEstimatorCommit_Expecter{mock: &_m.Mock} +} + +// DenoteInUSD provides a mock function with given fields: p, wrappedNativePrice +func (_m *MockGasPriceEstimatorCommit) DenoteInUSD(p *big.Int, wrappedNativePrice *big.Int) (*big.Int, error) { + ret := _m.Called(p, wrappedNativePrice) + + if len(ret) == 0 { + panic("no return value specified for DenoteInUSD") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) (*big.Int, error)); ok { + return rf(p, wrappedNativePrice) + } + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) *big.Int); ok { + r0 = rf(p, wrappedNativePrice) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*big.Int, *big.Int) error); ok { + r1 = rf(p, wrappedNativePrice) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimatorCommit_DenoteInUSD_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DenoteInUSD' +type MockGasPriceEstimatorCommit_DenoteInUSD_Call struct { + *mock.Call +} + +// DenoteInUSD is a helper method to define mock.On call +// - p *big.Int +// - wrappedNativePrice *big.Int +func (_e *MockGasPriceEstimatorCommit_Expecter) DenoteInUSD(p interface{}, wrappedNativePrice interface{}) *MockGasPriceEstimatorCommit_DenoteInUSD_Call { + return &MockGasPriceEstimatorCommit_DenoteInUSD_Call{Call: _e.mock.On("DenoteInUSD", p, wrappedNativePrice)} +} + +func (_c *MockGasPriceEstimatorCommit_DenoteInUSD_Call) Run(run func(p *big.Int, wrappedNativePrice *big.Int)) *MockGasPriceEstimatorCommit_DenoteInUSD_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(*big.Int)) + }) + return _c +} + +func (_c *MockGasPriceEstimatorCommit_DenoteInUSD_Call) Return(_a0 *big.Int, _a1 error) *MockGasPriceEstimatorCommit_DenoteInUSD_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimatorCommit_DenoteInUSD_Call) RunAndReturn(run func(*big.Int, *big.Int) (*big.Int, error)) *MockGasPriceEstimatorCommit_DenoteInUSD_Call { + _c.Call.Return(run) + return _c +} + +// Deviates provides a mock function with given fields: p1, p2 +func (_m *MockGasPriceEstimatorCommit) Deviates(p1 *big.Int, p2 *big.Int) (bool, error) { + ret := _m.Called(p1, p2) + + if len(ret) == 0 { + panic("no return value specified for Deviates") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) (bool, error)); ok { + return rf(p1, p2) + } + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) bool); ok { + r0 = rf(p1, p2) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*big.Int, *big.Int) error); ok { + r1 = rf(p1, p2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimatorCommit_Deviates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Deviates' +type MockGasPriceEstimatorCommit_Deviates_Call struct { + *mock.Call +} + +// Deviates is a helper method to define mock.On call +// - p1 *big.Int +// - p2 *big.Int +func (_e *MockGasPriceEstimatorCommit_Expecter) Deviates(p1 interface{}, p2 interface{}) *MockGasPriceEstimatorCommit_Deviates_Call { + return &MockGasPriceEstimatorCommit_Deviates_Call{Call: _e.mock.On("Deviates", p1, p2)} +} + +func (_c *MockGasPriceEstimatorCommit_Deviates_Call) Run(run func(p1 *big.Int, p2 *big.Int)) *MockGasPriceEstimatorCommit_Deviates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(*big.Int)) + }) + return _c +} + +func (_c *MockGasPriceEstimatorCommit_Deviates_Call) Return(_a0 bool, _a1 error) *MockGasPriceEstimatorCommit_Deviates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimatorCommit_Deviates_Call) RunAndReturn(run func(*big.Int, *big.Int) (bool, error)) *MockGasPriceEstimatorCommit_Deviates_Call { + _c.Call.Return(run) + return _c +} + +// GetGasPrice provides a mock function with given fields: ctx +func (_m *MockGasPriceEstimatorCommit) GetGasPrice(ctx context.Context) (*big.Int, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetGasPrice") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*big.Int, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *big.Int); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimatorCommit_GetGasPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGasPrice' +type MockGasPriceEstimatorCommit_GetGasPrice_Call struct { + *mock.Call +} + +// GetGasPrice is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockGasPriceEstimatorCommit_Expecter) GetGasPrice(ctx interface{}) *MockGasPriceEstimatorCommit_GetGasPrice_Call { + return &MockGasPriceEstimatorCommit_GetGasPrice_Call{Call: _e.mock.On("GetGasPrice", ctx)} +} + +func (_c *MockGasPriceEstimatorCommit_GetGasPrice_Call) Run(run func(ctx context.Context)) *MockGasPriceEstimatorCommit_GetGasPrice_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockGasPriceEstimatorCommit_GetGasPrice_Call) Return(_a0 *big.Int, _a1 error) *MockGasPriceEstimatorCommit_GetGasPrice_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimatorCommit_GetGasPrice_Call) RunAndReturn(run func(context.Context) (*big.Int, error)) *MockGasPriceEstimatorCommit_GetGasPrice_Call { + _c.Call.Return(run) + return _c +} + +// Median provides a mock function with given fields: gasPrices +func (_m *MockGasPriceEstimatorCommit) Median(gasPrices []*big.Int) (*big.Int, error) { + ret := _m.Called(gasPrices) + + if len(ret) == 0 { + panic("no return value specified for Median") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func([]*big.Int) (*big.Int, error)); ok { + return rf(gasPrices) + } + if rf, ok := ret.Get(0).(func([]*big.Int) *big.Int); ok { + r0 = rf(gasPrices) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func([]*big.Int) error); ok { + r1 = rf(gasPrices) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimatorCommit_Median_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Median' +type MockGasPriceEstimatorCommit_Median_Call struct { + *mock.Call +} + +// Median is a helper method to define mock.On call +// - gasPrices []*big.Int +func (_e *MockGasPriceEstimatorCommit_Expecter) Median(gasPrices interface{}) *MockGasPriceEstimatorCommit_Median_Call { + return &MockGasPriceEstimatorCommit_Median_Call{Call: _e.mock.On("Median", gasPrices)} +} + +func (_c *MockGasPriceEstimatorCommit_Median_Call) Run(run func(gasPrices []*big.Int)) *MockGasPriceEstimatorCommit_Median_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]*big.Int)) + }) + return _c +} + +func (_c *MockGasPriceEstimatorCommit_Median_Call) Return(_a0 *big.Int, _a1 error) *MockGasPriceEstimatorCommit_Median_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimatorCommit_Median_Call) RunAndReturn(run func([]*big.Int) (*big.Int, error)) *MockGasPriceEstimatorCommit_Median_Call { + _c.Call.Return(run) + return _c +} + +// NewMockGasPriceEstimatorCommit creates a new instance of MockGasPriceEstimatorCommit. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockGasPriceEstimatorCommit(t interface { + mock.TestingT + Cleanup(func()) +}) *MockGasPriceEstimatorCommit { + mock := &MockGasPriceEstimatorCommit{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_exec_mock.go b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_exec_mock.go new file mode 100644 index 0000000000..8f778555b1 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_exec_mock.go @@ -0,0 +1,274 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package prices + +import ( + context "context" + big "math/big" + + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + mock "github.com/stretchr/testify/mock" +) + +// MockGasPriceEstimatorExec is an autogenerated mock type for the GasPriceEstimatorExec type +type MockGasPriceEstimatorExec struct { + mock.Mock +} + +type MockGasPriceEstimatorExec_Expecter struct { + mock *mock.Mock +} + +func (_m *MockGasPriceEstimatorExec) EXPECT() *MockGasPriceEstimatorExec_Expecter { + return &MockGasPriceEstimatorExec_Expecter{mock: &_m.Mock} +} + +// DenoteInUSD provides a mock function with given fields: p, wrappedNativePrice +func (_m *MockGasPriceEstimatorExec) DenoteInUSD(p *big.Int, wrappedNativePrice *big.Int) (*big.Int, error) { + ret := _m.Called(p, wrappedNativePrice) + + if len(ret) == 0 { + panic("no return value specified for DenoteInUSD") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) (*big.Int, error)); ok { + return rf(p, wrappedNativePrice) + } + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) *big.Int); ok { + r0 = rf(p, wrappedNativePrice) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*big.Int, *big.Int) error); ok { + r1 = rf(p, wrappedNativePrice) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimatorExec_DenoteInUSD_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DenoteInUSD' +type MockGasPriceEstimatorExec_DenoteInUSD_Call struct { + *mock.Call +} + +// DenoteInUSD is a helper method to define mock.On call +// - p *big.Int +// - wrappedNativePrice *big.Int +func (_e *MockGasPriceEstimatorExec_Expecter) DenoteInUSD(p interface{}, wrappedNativePrice interface{}) *MockGasPriceEstimatorExec_DenoteInUSD_Call { + return &MockGasPriceEstimatorExec_DenoteInUSD_Call{Call: _e.mock.On("DenoteInUSD", p, wrappedNativePrice)} +} + +func (_c *MockGasPriceEstimatorExec_DenoteInUSD_Call) Run(run func(p *big.Int, wrappedNativePrice *big.Int)) *MockGasPriceEstimatorExec_DenoteInUSD_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(*big.Int)) + }) + return _c +} + +func (_c *MockGasPriceEstimatorExec_DenoteInUSD_Call) Return(_a0 *big.Int, _a1 error) *MockGasPriceEstimatorExec_DenoteInUSD_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimatorExec_DenoteInUSD_Call) RunAndReturn(run func(*big.Int, *big.Int) (*big.Int, error)) *MockGasPriceEstimatorExec_DenoteInUSD_Call { + _c.Call.Return(run) + return _c +} + +// EstimateMsgCostUSD provides a mock function with given fields: p, wrappedNativePrice, msg +func (_m *MockGasPriceEstimatorExec) EstimateMsgCostUSD(p *big.Int, wrappedNativePrice *big.Int, msg ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error) { + ret := _m.Called(p, wrappedNativePrice, msg) + + if len(ret) == 0 { + panic("no return value specified for EstimateMsgCostUSD") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int, ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error)); ok { + return rf(p, wrappedNativePrice, msg) + } + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int, ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta) *big.Int); ok { + r0 = rf(p, wrappedNativePrice, msg) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*big.Int, *big.Int, ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta) error); ok { + r1 = rf(p, wrappedNativePrice, msg) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimatorExec_EstimateMsgCostUSD_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EstimateMsgCostUSD' +type MockGasPriceEstimatorExec_EstimateMsgCostUSD_Call struct { + *mock.Call +} + +// EstimateMsgCostUSD is a helper method to define mock.On call +// - p *big.Int +// - wrappedNativePrice *big.Int +// - msg ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta +func (_e *MockGasPriceEstimatorExec_Expecter) EstimateMsgCostUSD(p interface{}, wrappedNativePrice interface{}, msg interface{}) *MockGasPriceEstimatorExec_EstimateMsgCostUSD_Call { + return &MockGasPriceEstimatorExec_EstimateMsgCostUSD_Call{Call: _e.mock.On("EstimateMsgCostUSD", p, wrappedNativePrice, msg)} +} + +func (_c *MockGasPriceEstimatorExec_EstimateMsgCostUSD_Call) Run(run func(p *big.Int, wrappedNativePrice *big.Int, msg ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta)) *MockGasPriceEstimatorExec_EstimateMsgCostUSD_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(*big.Int), args[2].(ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta)) + }) + return _c +} + +func (_c *MockGasPriceEstimatorExec_EstimateMsgCostUSD_Call) Return(_a0 *big.Int, _a1 error) *MockGasPriceEstimatorExec_EstimateMsgCostUSD_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimatorExec_EstimateMsgCostUSD_Call) RunAndReturn(run func(*big.Int, *big.Int, ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error)) *MockGasPriceEstimatorExec_EstimateMsgCostUSD_Call { + _c.Call.Return(run) + return _c +} + +// GetGasPrice provides a mock function with given fields: ctx +func (_m *MockGasPriceEstimatorExec) GetGasPrice(ctx context.Context) (*big.Int, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetGasPrice") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*big.Int, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *big.Int); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimatorExec_GetGasPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGasPrice' +type MockGasPriceEstimatorExec_GetGasPrice_Call struct { + *mock.Call +} + +// GetGasPrice is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockGasPriceEstimatorExec_Expecter) GetGasPrice(ctx interface{}) *MockGasPriceEstimatorExec_GetGasPrice_Call { + return &MockGasPriceEstimatorExec_GetGasPrice_Call{Call: _e.mock.On("GetGasPrice", ctx)} +} + +func (_c *MockGasPriceEstimatorExec_GetGasPrice_Call) Run(run func(ctx context.Context)) *MockGasPriceEstimatorExec_GetGasPrice_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockGasPriceEstimatorExec_GetGasPrice_Call) Return(_a0 *big.Int, _a1 error) *MockGasPriceEstimatorExec_GetGasPrice_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimatorExec_GetGasPrice_Call) RunAndReturn(run func(context.Context) (*big.Int, error)) *MockGasPriceEstimatorExec_GetGasPrice_Call { + _c.Call.Return(run) + return _c +} + +// Median provides a mock function with given fields: gasPrices +func (_m *MockGasPriceEstimatorExec) Median(gasPrices []*big.Int) (*big.Int, error) { + ret := _m.Called(gasPrices) + + if len(ret) == 0 { + panic("no return value specified for Median") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func([]*big.Int) (*big.Int, error)); ok { + return rf(gasPrices) + } + if rf, ok := ret.Get(0).(func([]*big.Int) *big.Int); ok { + r0 = rf(gasPrices) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func([]*big.Int) error); ok { + r1 = rf(gasPrices) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimatorExec_Median_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Median' +type MockGasPriceEstimatorExec_Median_Call struct { + *mock.Call +} + +// Median is a helper method to define mock.On call +// - gasPrices []*big.Int +func (_e *MockGasPriceEstimatorExec_Expecter) Median(gasPrices interface{}) *MockGasPriceEstimatorExec_Median_Call { + return &MockGasPriceEstimatorExec_Median_Call{Call: _e.mock.On("Median", gasPrices)} +} + +func (_c *MockGasPriceEstimatorExec_Median_Call) Run(run func(gasPrices []*big.Int)) *MockGasPriceEstimatorExec_Median_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]*big.Int)) + }) + return _c +} + +func (_c *MockGasPriceEstimatorExec_Median_Call) Return(_a0 *big.Int, _a1 error) *MockGasPriceEstimatorExec_Median_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimatorExec_Median_Call) RunAndReturn(run func([]*big.Int) (*big.Int, error)) *MockGasPriceEstimatorExec_Median_Call { + _c.Call.Return(run) + return _c +} + +// NewMockGasPriceEstimatorExec creates a new instance of MockGasPriceEstimatorExec. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockGasPriceEstimatorExec(t interface { + mock.TestingT + Cleanup(func()) +}) *MockGasPriceEstimatorExec { + mock := &MockGasPriceEstimatorExec{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_mock.go b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_mock.go new file mode 100644 index 0000000000..a513083319 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_mock.go @@ -0,0 +1,331 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package prices + +import ( + context "context" + big "math/big" + + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + mock "github.com/stretchr/testify/mock" +) + +// MockGasPriceEstimator is an autogenerated mock type for the GasPriceEstimator type +type MockGasPriceEstimator struct { + mock.Mock +} + +type MockGasPriceEstimator_Expecter struct { + mock *mock.Mock +} + +func (_m *MockGasPriceEstimator) EXPECT() *MockGasPriceEstimator_Expecter { + return &MockGasPriceEstimator_Expecter{mock: &_m.Mock} +} + +// DenoteInUSD provides a mock function with given fields: p, wrappedNativePrice +func (_m *MockGasPriceEstimator) DenoteInUSD(p *big.Int, wrappedNativePrice *big.Int) (*big.Int, error) { + ret := _m.Called(p, wrappedNativePrice) + + if len(ret) == 0 { + panic("no return value specified for DenoteInUSD") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) (*big.Int, error)); ok { + return rf(p, wrappedNativePrice) + } + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) *big.Int); ok { + r0 = rf(p, wrappedNativePrice) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*big.Int, *big.Int) error); ok { + r1 = rf(p, wrappedNativePrice) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimator_DenoteInUSD_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DenoteInUSD' +type MockGasPriceEstimator_DenoteInUSD_Call struct { + *mock.Call +} + +// DenoteInUSD is a helper method to define mock.On call +// - p *big.Int +// - wrappedNativePrice *big.Int +func (_e *MockGasPriceEstimator_Expecter) DenoteInUSD(p interface{}, wrappedNativePrice interface{}) *MockGasPriceEstimator_DenoteInUSD_Call { + return &MockGasPriceEstimator_DenoteInUSD_Call{Call: _e.mock.On("DenoteInUSD", p, wrappedNativePrice)} +} + +func (_c *MockGasPriceEstimator_DenoteInUSD_Call) Run(run func(p *big.Int, wrappedNativePrice *big.Int)) *MockGasPriceEstimator_DenoteInUSD_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(*big.Int)) + }) + return _c +} + +func (_c *MockGasPriceEstimator_DenoteInUSD_Call) Return(_a0 *big.Int, _a1 error) *MockGasPriceEstimator_DenoteInUSD_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimator_DenoteInUSD_Call) RunAndReturn(run func(*big.Int, *big.Int) (*big.Int, error)) *MockGasPriceEstimator_DenoteInUSD_Call { + _c.Call.Return(run) + return _c +} + +// Deviates provides a mock function with given fields: p1, p2 +func (_m *MockGasPriceEstimator) Deviates(p1 *big.Int, p2 *big.Int) (bool, error) { + ret := _m.Called(p1, p2) + + if len(ret) == 0 { + panic("no return value specified for Deviates") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) (bool, error)); ok { + return rf(p1, p2) + } + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) bool); ok { + r0 = rf(p1, p2) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(*big.Int, *big.Int) error); ok { + r1 = rf(p1, p2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimator_Deviates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Deviates' +type MockGasPriceEstimator_Deviates_Call struct { + *mock.Call +} + +// Deviates is a helper method to define mock.On call +// - p1 *big.Int +// - p2 *big.Int +func (_e *MockGasPriceEstimator_Expecter) Deviates(p1 interface{}, p2 interface{}) *MockGasPriceEstimator_Deviates_Call { + return &MockGasPriceEstimator_Deviates_Call{Call: _e.mock.On("Deviates", p1, p2)} +} + +func (_c *MockGasPriceEstimator_Deviates_Call) Run(run func(p1 *big.Int, p2 *big.Int)) *MockGasPriceEstimator_Deviates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(*big.Int)) + }) + return _c +} + +func (_c *MockGasPriceEstimator_Deviates_Call) Return(_a0 bool, _a1 error) *MockGasPriceEstimator_Deviates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimator_Deviates_Call) RunAndReturn(run func(*big.Int, *big.Int) (bool, error)) *MockGasPriceEstimator_Deviates_Call { + _c.Call.Return(run) + return _c +} + +// EstimateMsgCostUSD provides a mock function with given fields: p, wrappedNativePrice, msg +func (_m *MockGasPriceEstimator) EstimateMsgCostUSD(p *big.Int, wrappedNativePrice *big.Int, msg ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error) { + ret := _m.Called(p, wrappedNativePrice, msg) + + if len(ret) == 0 { + panic("no return value specified for EstimateMsgCostUSD") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int, ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error)); ok { + return rf(p, wrappedNativePrice, msg) + } + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int, ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta) *big.Int); ok { + r0 = rf(p, wrappedNativePrice, msg) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*big.Int, *big.Int, ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta) error); ok { + r1 = rf(p, wrappedNativePrice, msg) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimator_EstimateMsgCostUSD_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EstimateMsgCostUSD' +type MockGasPriceEstimator_EstimateMsgCostUSD_Call struct { + *mock.Call +} + +// EstimateMsgCostUSD is a helper method to define mock.On call +// - p *big.Int +// - wrappedNativePrice *big.Int +// - msg ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta +func (_e *MockGasPriceEstimator_Expecter) EstimateMsgCostUSD(p interface{}, wrappedNativePrice interface{}, msg interface{}) *MockGasPriceEstimator_EstimateMsgCostUSD_Call { + return &MockGasPriceEstimator_EstimateMsgCostUSD_Call{Call: _e.mock.On("EstimateMsgCostUSD", p, wrappedNativePrice, msg)} +} + +func (_c *MockGasPriceEstimator_EstimateMsgCostUSD_Call) Run(run func(p *big.Int, wrappedNativePrice *big.Int, msg ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta)) *MockGasPriceEstimator_EstimateMsgCostUSD_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(*big.Int), args[2].(ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta)) + }) + return _c +} + +func (_c *MockGasPriceEstimator_EstimateMsgCostUSD_Call) Return(_a0 *big.Int, _a1 error) *MockGasPriceEstimator_EstimateMsgCostUSD_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimator_EstimateMsgCostUSD_Call) RunAndReturn(run func(*big.Int, *big.Int, ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error)) *MockGasPriceEstimator_EstimateMsgCostUSD_Call { + _c.Call.Return(run) + return _c +} + +// GetGasPrice provides a mock function with given fields: ctx +func (_m *MockGasPriceEstimator) GetGasPrice(ctx context.Context) (*big.Int, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetGasPrice") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*big.Int, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *big.Int); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimator_GetGasPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGasPrice' +type MockGasPriceEstimator_GetGasPrice_Call struct { + *mock.Call +} + +// GetGasPrice is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockGasPriceEstimator_Expecter) GetGasPrice(ctx interface{}) *MockGasPriceEstimator_GetGasPrice_Call { + return &MockGasPriceEstimator_GetGasPrice_Call{Call: _e.mock.On("GetGasPrice", ctx)} +} + +func (_c *MockGasPriceEstimator_GetGasPrice_Call) Run(run func(ctx context.Context)) *MockGasPriceEstimator_GetGasPrice_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockGasPriceEstimator_GetGasPrice_Call) Return(_a0 *big.Int, _a1 error) *MockGasPriceEstimator_GetGasPrice_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimator_GetGasPrice_Call) RunAndReturn(run func(context.Context) (*big.Int, error)) *MockGasPriceEstimator_GetGasPrice_Call { + _c.Call.Return(run) + return _c +} + +// Median provides a mock function with given fields: gasPrices +func (_m *MockGasPriceEstimator) Median(gasPrices []*big.Int) (*big.Int, error) { + ret := _m.Called(gasPrices) + + if len(ret) == 0 { + panic("no return value specified for Median") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func([]*big.Int) (*big.Int, error)); ok { + return rf(gasPrices) + } + if rf, ok := ret.Get(0).(func([]*big.Int) *big.Int); ok { + r0 = rf(gasPrices) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func([]*big.Int) error); ok { + r1 = rf(gasPrices) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockGasPriceEstimator_Median_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Median' +type MockGasPriceEstimator_Median_Call struct { + *mock.Call +} + +// Median is a helper method to define mock.On call +// - gasPrices []*big.Int +func (_e *MockGasPriceEstimator_Expecter) Median(gasPrices interface{}) *MockGasPriceEstimator_Median_Call { + return &MockGasPriceEstimator_Median_Call{Call: _e.mock.On("Median", gasPrices)} +} + +func (_c *MockGasPriceEstimator_Median_Call) Run(run func(gasPrices []*big.Int)) *MockGasPriceEstimator_Median_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]*big.Int)) + }) + return _c +} + +func (_c *MockGasPriceEstimator_Median_Call) Return(_a0 *big.Int, _a1 error) *MockGasPriceEstimator_Median_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockGasPriceEstimator_Median_Call) RunAndReturn(run func([]*big.Int) (*big.Int, error)) *MockGasPriceEstimator_Median_Call { + _c.Call.Return(run) + return _c +} + +// NewMockGasPriceEstimator creates a new instance of MockGasPriceEstimator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockGasPriceEstimator(t interface { + mock.TestingT + Cleanup(func()) +}) *MockGasPriceEstimator { + mock := &MockGasPriceEstimator{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/proxycommitstore.go b/core/services/ocr2/plugins/ccip/proxycommitstore.go new file mode 100644 index 0000000000..b06f957bd5 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/proxycommitstore.go @@ -0,0 +1,135 @@ +package ccip + +import ( + "context" + "fmt" + "io" + "math/big" + "time" + + "go.uber.org/multierr" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" +) + +// The disjunct methods in IncompleteSourceCommitStoreReader and IncompleteDestCommitStoreReader satisfy the full +// CommitStoreReader iface in Union +var _ cciptypes.CommitStoreReader = (*ProviderProxyCommitStoreReader)(nil) + +// ProviderProxyCommitStoreReader is a CommitStoreReader that proxies to two custom provider grpc backed implementations +// of a CommitStoreReader. +// [ProviderProxyCommitStoreReader] lives in the memory space of the reporting plugin factory and reporting plugin, and should have no chain-specific details. +// Why? Historical implementations of a commit store consumed in reporting plugins mixed usage of a gas estimator from +// the source relayer and contract read and write abilities to a dest relayer. This is not valid in LOOP world. +type ProviderProxyCommitStoreReader struct { + srcCommitStoreReader IncompleteSourceCommitStoreReader + dstCommitStoreReader IncompleteDestCommitStoreReader +} + +// IncompleteSourceCommitStoreReader contains only the methods of CommitStoreReader that are serviced by the source chain/relayer. +type IncompleteSourceCommitStoreReader interface { + ChangeConfig(ctx context.Context, onchainConfig []byte, offchainConfig []byte) (cciptypes.Address, error) + GasPriceEstimator(ctx context.Context) (cciptypes.GasPriceEstimatorCommit, error) + OffchainConfig(ctx context.Context) (cciptypes.CommitOffchainConfig, error) + io.Closer +} + +// IncompleteDestCommitStoreReader contains only the methods of CommitStoreReader that are serviced by the dest chain/relayer. +type IncompleteDestCommitStoreReader interface { + DecodeCommitReport(ctx context.Context, report []byte) (cciptypes.CommitStoreReport, error) + EncodeCommitReport(ctx context.Context, report cciptypes.CommitStoreReport) ([]byte, error) + GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confirmations int) ([]cciptypes.CommitStoreReportWithTxMeta, error) + GetCommitReportMatchingSeqNum(ctx context.Context, seqNum uint64, confirmations int) ([]cciptypes.CommitStoreReportWithTxMeta, error) + GetCommitStoreStaticConfig(ctx context.Context) (cciptypes.CommitStoreStaticConfig, error) + GetExpectedNextSequenceNumber(ctx context.Context) (uint64, error) + GetLatestPriceEpochAndRound(ctx context.Context) (uint64, error) + IsBlessed(ctx context.Context, root [32]byte) (bool, error) + IsDestChainHealthy(ctx context.Context) (bool, error) + IsDown(ctx context.Context) (bool, error) + VerifyExecutionReport(ctx context.Context, report cciptypes.ExecReport) (bool, error) + io.Closer +} + +func NewProviderProxyCommitStoreReader(srcReader cciptypes.CommitStoreReader, dstReader cciptypes.CommitStoreReader) *ProviderProxyCommitStoreReader { + return &ProviderProxyCommitStoreReader{ + srcCommitStoreReader: srcReader, + dstCommitStoreReader: dstReader, + } +} + +// ChangeConfig updates the offchainConfig values for the source relayer gas estimator by calling ChangeConfig +// on the source relayer. Once this is called, GasPriceEstimator and OffchainConfig can be called. +func (p *ProviderProxyCommitStoreReader) ChangeConfig(ctx context.Context, onchainConfig []byte, offchainConfig []byte) (cciptypes.Address, error) { + return p.srcCommitStoreReader.ChangeConfig(ctx, onchainConfig, offchainConfig) +} + +func (p *ProviderProxyCommitStoreReader) DecodeCommitReport(ctx context.Context, report []byte) (cciptypes.CommitStoreReport, error) { + return p.dstCommitStoreReader.DecodeCommitReport(ctx, report) +} + +func (p *ProviderProxyCommitStoreReader) EncodeCommitReport(ctx context.Context, report cciptypes.CommitStoreReport) ([]byte, error) { + return p.dstCommitStoreReader.EncodeCommitReport(ctx, report) +} + +// GasPriceEstimator constructs a gas price estimator on the source relayer +func (p *ProviderProxyCommitStoreReader) GasPriceEstimator(ctx context.Context) (cciptypes.GasPriceEstimatorCommit, error) { + return p.srcCommitStoreReader.GasPriceEstimator(ctx) +} + +func (p *ProviderProxyCommitStoreReader) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confirmations int) ([]cciptypes.CommitStoreReportWithTxMeta, error) { + return p.dstCommitStoreReader.GetAcceptedCommitReportsGteTimestamp(ctx, ts, confirmations) +} + +func (p *ProviderProxyCommitStoreReader) GetCommitReportMatchingSeqNum(ctx context.Context, seqNum uint64, confirmations int) ([]cciptypes.CommitStoreReportWithTxMeta, error) { + return p.dstCommitStoreReader.GetCommitReportMatchingSeqNum(ctx, seqNum, confirmations) +} + +func (p *ProviderProxyCommitStoreReader) GetCommitStoreStaticConfig(ctx context.Context) (cciptypes.CommitStoreStaticConfig, error) { + return p.dstCommitStoreReader.GetCommitStoreStaticConfig(ctx) +} + +func (p *ProviderProxyCommitStoreReader) GetExpectedNextSequenceNumber(ctx context.Context) (uint64, error) { + return p.dstCommitStoreReader.GetExpectedNextSequenceNumber(ctx) +} + +func (p *ProviderProxyCommitStoreReader) GetLatestPriceEpochAndRound(ctx context.Context) (uint64, error) { + return p.dstCommitStoreReader.GetLatestPriceEpochAndRound(ctx) +} + +func (p *ProviderProxyCommitStoreReader) IsBlessed(ctx context.Context, root [32]byte) (bool, error) { + return p.dstCommitStoreReader.IsBlessed(ctx, root) +} + +func (p *ProviderProxyCommitStoreReader) IsDestChainHealthy(ctx context.Context) (bool, error) { + return p.dstCommitStoreReader.IsDestChainHealthy(ctx) +} + +func (p *ProviderProxyCommitStoreReader) IsDown(ctx context.Context) (bool, error) { + return p.dstCommitStoreReader.IsDown(ctx) +} + +func (p *ProviderProxyCommitStoreReader) OffchainConfig(ctx context.Context) (cciptypes.CommitOffchainConfig, error) { + return p.srcCommitStoreReader.OffchainConfig(ctx) +} + +func (p *ProviderProxyCommitStoreReader) VerifyExecutionReport(ctx context.Context, report cciptypes.ExecReport) (bool, error) { + return p.dstCommitStoreReader.VerifyExecutionReport(ctx, report) +} + +// SetGasEstimator is invalid on ProviderProxyCommitStoreReader. The provider based impl's do not have SetGasEstimator +// defined, so this serves no purpose other than satisfying an interface. +func (p *ProviderProxyCommitStoreReader) SetGasEstimator(ctx context.Context, gpe gas.EvmFeeEstimator) error { + return fmt.Errorf("invalid usage of ProviderProxyCommitStoreReader") +} + +// SetSourceMaxGasPrice is invalid on ProviderProxyCommitStoreReader. The provider based impl's do not have SetSourceMaxGasPrice +// defined, so this serves no purpose other than satisfying an interface. +func (p *ProviderProxyCommitStoreReader) SetSourceMaxGasPrice(ctx context.Context, sourceMaxGasPrice *big.Int) error { + return fmt.Errorf("invalid usage of ProviderProxyCommitStoreReader") +} + +func (p *ProviderProxyCommitStoreReader) Close() error { + return multierr.Append(p.srcCommitStoreReader.Close(), p.dstCommitStoreReader.Close()) +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go new file mode 100644 index 0000000000..805c49d91a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -0,0 +1,1580 @@ +package testhelpers + +import ( + "context" + "fmt" + "math" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0" +) + +var ( + // Source + SourcePool = "source Link pool" + SourcePriceRegistry = "source PriceRegistry" + OnRamp = "onramp" + OnRampNative = "onramp-native" + SourceRouter = "source router" + + // Dest + OffRamp = "offramp" + DestPool = "dest Link pool" + + Receiver = "receiver" + Sender = "sender" + Link = func(amount int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(amount)) } + HundredLink = Link(100) + LinkUSDValue = func(amount int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(amount)) } + SourceChainID = uint64(1000) + SourceChainSelector = uint64(11787463284727550157) + DestChainID = uint64(1337) + DestChainSelector = uint64(3379446385462418246) +) + +// Backwards compat, in principle these statuses are version dependent +// TODO: Adjust integration tests to be version agnostic using readers +var ( + ExecutionStateSuccess = MessageExecutionState(cciptypes.ExecutionStateSuccess) + ExecutionStateFailure = MessageExecutionState(cciptypes.ExecutionStateFailure) +) + +type MessageExecutionState cciptypes.MessageExecutionState +type CommitOffchainConfig struct { + v1_2_0.JSONCommitOffchainConfig +} + +func (c CommitOffchainConfig) Encode() ([]byte, error) { + return ccipconfig.EncodeOffchainConfig(c.JSONCommitOffchainConfig) +} + +func NewCommitOffchainConfig( + GasPriceHeartBeat config.Duration, + DAGasPriceDeviationPPB uint32, + ExecGasPriceDeviationPPB uint32, + TokenPriceHeartBeat config.Duration, + TokenPriceDeviationPPB uint32, + InflightCacheExpiry config.Duration) CommitOffchainConfig { + return CommitOffchainConfig{v1_2_0.JSONCommitOffchainConfig{ + GasPriceHeartBeat: GasPriceHeartBeat, + DAGasPriceDeviationPPB: DAGasPriceDeviationPPB, + ExecGasPriceDeviationPPB: ExecGasPriceDeviationPPB, + TokenPriceHeartBeat: TokenPriceHeartBeat, + TokenPriceDeviationPPB: TokenPriceDeviationPPB, + InflightCacheExpiry: InflightCacheExpiry, + }} +} + +type CommitOnchainConfig struct { + ccipdata.CommitOnchainConfig +} + +func NewCommitOnchainConfig( + PriceRegistry common.Address, +) CommitOnchainConfig { + return CommitOnchainConfig{ccipdata.CommitOnchainConfig{ + PriceRegistry: PriceRegistry, + }} +} + +type ExecOnchainConfig struct { + v1_5_0.ExecOnchainConfig +} + +func NewExecOnchainConfig( + PermissionLessExecutionThresholdSeconds uint32, + Router common.Address, + PriceRegistry common.Address, + MaxNumberOfTokensPerMsg uint16, + MaxDataBytes uint32, + MaxPoolReleaseOrMintGas uint32, + MaxTokenTransferGas uint32, +) ExecOnchainConfig { + return ExecOnchainConfig{v1_5_0.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: PermissionLessExecutionThresholdSeconds, + Router: Router, + PriceRegistry: PriceRegistry, + MaxNumberOfTokensPerMsg: MaxNumberOfTokensPerMsg, + MaxDataBytes: MaxDataBytes, + MaxPoolReleaseOrMintGas: MaxPoolReleaseOrMintGas, + MaxTokenTransferGas: MaxTokenTransferGas, + }} +} + +type ExecOffchainConfig struct { + v1_2_0.JSONExecOffchainConfig +} + +func (c ExecOffchainConfig) Encode() ([]byte, error) { + return ccipconfig.EncodeOffchainConfig(c.JSONExecOffchainConfig) +} + +func NewExecOffchainConfig( + DestOptimisticConfirmations uint32, + BatchGasLimit uint32, + RelativeBoostPerWaitHour float64, + InflightCacheExpiry config.Duration, + RootSnoozeTime config.Duration, +) ExecOffchainConfig { + return ExecOffchainConfig{v1_2_0.JSONExecOffchainConfig{ + DestOptimisticConfirmations: DestOptimisticConfirmations, + BatchGasLimit: BatchGasLimit, + RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, + InflightCacheExpiry: InflightCacheExpiry, + RootSnoozeTime: RootSnoozeTime, + }} +} + +type MaybeRevertReceiver struct { + Receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver + Strict bool +} + +type Common struct { + ChainID uint64 + ChainSelector uint64 + User *bind.TransactOpts + Chain *backends.SimulatedBackend + LinkToken *link_token_interface.LinkToken + LinkTokenPool *lock_release_token_pool.LockReleaseTokenPool + CustomToken *link_token_interface.LinkToken + WrappedNative *weth9.WETH9 + WrappedNativePool *lock_release_token_pool.LockReleaseTokenPool + ARM *mock_arm_contract.MockARMContract + ARMProxy *arm_proxy_contract.ARMProxyContract + PriceRegistry *price_registry_1_2_0.PriceRegistry + TokenAdminRegistry *token_admin_registry.TokenAdminRegistry +} + +type SourceChain struct { + Common + Router *router.Router + OnRamp *evm_2_evm_onramp.EVM2EVMOnRamp +} + +type DestinationChain struct { + Common + + CommitStoreHelper *commit_store_helper.CommitStoreHelper + CommitStore *commit_store.CommitStore + Router *router.Router + OffRamp *evm_2_evm_offramp.EVM2EVMOffRamp + Receivers []MaybeRevertReceiver +} + +type OCR2Config struct { + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte +} + +type BalanceAssertion struct { + Name string + Address common.Address + Expected string + Getter func(t *testing.T, addr common.Address) *big.Int + Within string +} + +type BalanceReq struct { + Name string + Addr common.Address + Getter func(t *testing.T, addr common.Address) *big.Int +} + +type CCIPContracts struct { + Source SourceChain + Dest DestinationChain + Oracles []confighelper.OracleIdentityExtra + + commitOCRConfig, execOCRConfig *OCR2Config +} + +func (c *CCIPContracts) DeployNewOffRamp(t *testing.T) { + prevOffRamp := common.HexToAddress("") + if c.Dest.OffRamp != nil { + prevOffRamp = c.Dest.OffRamp.Address() + } + offRampAddress, _, _, err := evm_2_evm_offramp.DeployEVM2EVMOffRamp( + c.Dest.User, + c.Dest.Chain, + evm_2_evm_offramp.EVM2EVMOffRampStaticConfig{ + CommitStore: c.Dest.CommitStore.Address(), + ChainSelector: c.Dest.ChainSelector, + SourceChainSelector: c.Source.ChainSelector, + OnRamp: c.Source.OnRamp.Address(), + PrevOffRamp: prevOffRamp, + RmnProxy: c.Dest.ARMProxy.Address(), // RMN formerly ARM + TokenAdminRegistry: c.Dest.TokenAdminRegistry.Address(), + }, + evm_2_evm_offramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: LinkUSDValue(100), + Rate: LinkUSDValue(1), + }, + ) + require.NoError(t, err) + c.Dest.Chain.Commit() + + c.Dest.OffRamp, err = evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampAddress, c.Dest.Chain) + require.NoError(t, err) + + c.Dest.Chain.Commit() + c.Source.Chain.Commit() +} + +func (c *CCIPContracts) EnableOffRamp(t *testing.T) { + _, err := c.Dest.Router.ApplyRampUpdates(c.Dest.User, nil, nil, []router.RouterOffRamp{{SourceChainSelector: SourceChainSelector, OffRamp: c.Dest.OffRamp.Address()}}) + require.NoError(t, err) + c.Dest.Chain.Commit() + + onChainConfig := c.CreateDefaultExecOnchainConfig(t) + offChainConfig := c.CreateDefaultExecOffchainConfig(t) + + c.SetupExecOCR2Config(t, onChainConfig, offChainConfig) +} + +func (c *CCIPContracts) EnableCommitStore(t *testing.T) { + onChainConfig := c.CreateDefaultCommitOnchainConfig(t) + offChainConfig := c.CreateDefaultCommitOffchainConfig(t) + + c.SetupCommitOCR2Config(t, onChainConfig, offChainConfig) + + _, err := c.Dest.PriceRegistry.ApplyPriceUpdatersUpdates(c.Dest.User, []common.Address{c.Dest.CommitStore.Address()}, []common.Address{}) + require.NoError(t, err) + c.Dest.Chain.Commit() +} + +func (c *CCIPContracts) DeployNewOnRamp(t *testing.T) { + t.Log("Deploying new onRamp") + // find the last onRamp + prevOnRamp := common.HexToAddress("") + if c.Source.OnRamp != nil { + prevOnRamp = c.Source.OnRamp.Address() + } + onRampAddress, _, _, err := evm_2_evm_onramp.DeployEVM2EVMOnRamp( + c.Source.User, // user + c.Source.Chain, // client + evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ + LinkToken: c.Source.LinkToken.Address(), + ChainSelector: c.Source.ChainSelector, + DestChainSelector: c.Dest.ChainSelector, + DefaultTxGasLimit: 200_000, + MaxNopFeesJuels: big.NewInt(0).Mul(big.NewInt(100_000_000), big.NewInt(1e18)), + PrevOnRamp: prevOnRamp, + RmnProxy: c.Source.ARM.Address(), // RMN, formerly ARM + TokenAdminRegistry: c.Source.TokenAdminRegistry.Address(), + }, + evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ + Router: c.Source.Router.Address(), + MaxNumberOfTokensPerMsg: 5, + DestGasOverhead: 350_000, + DestGasPerPayloadByte: 16, + DestDataAvailabilityOverheadGas: 33_596, + DestGasPerDataAvailabilityByte: 16, + DestDataAvailabilityMultiplierBps: 6840, // 0.684 + PriceRegistry: c.Source.PriceRegistry.Address(), + MaxDataBytes: 1e5, + MaxPerMsgGasLimit: 4_000_000, + DefaultTokenFeeUSDCents: 50, + DefaultTokenDestGasOverhead: 34_000, + DefaultTokenDestBytesOverhead: 500, + }, + evm_2_evm_onramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: LinkUSDValue(100), + Rate: LinkUSDValue(1), + }, + []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ + { + Token: c.Source.LinkToken.Address(), + NetworkFeeUSDCents: 1_00, + GasMultiplierWeiPerEth: 1e18, + PremiumMultiplierWeiPerEth: 9e17, + Enabled: true, + }, + { + Token: c.Source.WrappedNative.Address(), + NetworkFeeUSDCents: 1_00, + GasMultiplierWeiPerEth: 1e18, + PremiumMultiplierWeiPerEth: 1e18, + Enabled: true, + }, + }, + []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + { + Token: c.Source.LinkToken.Address(), + MinFeeUSDCents: 50, // $0.5 + MaxFeeUSDCents: 1_000_000_00, // $ 1 million + DeciBps: 5_0, // 5 bps + DestGasOverhead: 34_000, + DestBytesOverhead: 32, + AggregateRateLimitEnabled: true, + }, + }, + []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{}, + ) + + require.NoError(t, err) + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + c.Source.OnRamp, err = evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, c.Source.Chain) + require.NoError(t, err) + c.Source.Chain.Commit() + c.Dest.Chain.Commit() +} + +func (c *CCIPContracts) EnableOnRamp(t *testing.T) { + t.Log("Setting onRamp on source router") + _, err := c.Source.Router.ApplyRampUpdates(c.Source.User, []router.RouterOnRamp{{DestChainSelector: c.Dest.ChainSelector, OnRamp: c.Source.OnRamp.Address()}}, nil, nil) + require.NoError(t, err) + c.Source.Chain.Commit() + c.Dest.Chain.Commit() +} + +func (c *CCIPContracts) DeployNewCommitStore(t *testing.T) { + commitStoreAddress, _, _, err := commit_store_helper_1_2_0.DeployCommitStoreHelper( + c.Dest.User, // user + c.Dest.Chain, // client + commit_store_helper_1_2_0.CommitStoreStaticConfig{ + ChainSelector: c.Dest.ChainSelector, + SourceChainSelector: c.Source.ChainSelector, + OnRamp: c.Source.OnRamp.Address(), + ArmProxy: c.Dest.ARMProxy.Address(), + }, + ) + require.NoError(t, err) + c.Dest.Chain.Commit() + c.Dest.CommitStoreHelper, err = commit_store_helper.NewCommitStoreHelper(commitStoreAddress, c.Dest.Chain) + require.NoError(t, err) + // since CommitStoreHelper derives from CommitStore, it's safe to instantiate both on same address + c.Dest.CommitStore, err = commit_store.NewCommitStore(commitStoreAddress, c.Dest.Chain) + require.NoError(t, err) +} + +func (c *CCIPContracts) DeployNewPriceRegistry(t *testing.T) { + t.Log("Deploying new Price Registry") + destPricesAddress, _, _, err := price_registry_1_2_0.DeployPriceRegistry( + c.Dest.User, + c.Dest.Chain, + []common.Address{c.Dest.CommitStore.Address()}, + []common.Address{c.Dest.LinkToken.Address()}, + 60*60*24*14, // two weeks + ) + require.NoError(t, err) + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + c.Dest.PriceRegistry, err = price_registry_1_2_0.NewPriceRegistry(destPricesAddress, c.Dest.Chain) + require.NoError(t, err) + + priceUpdates := price_registry_1_2_0.InternalPriceUpdates{ + TokenPriceUpdates: []price_registry_1_2_0.InternalTokenPriceUpdate{ + { + SourceToken: c.Dest.LinkToken.Address(), + UsdPerToken: big.NewInt(8e18), // 8usd + }, + { + SourceToken: c.Dest.WrappedNative.Address(), + UsdPerToken: big.NewInt(1e18), // 1usd + }, + }, + GasPriceUpdates: []price_registry_1_2_0.InternalGasPriceUpdate{ + { + DestChainSelector: c.Source.ChainSelector, + UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, + }, + } + _, err = c.Dest.PriceRegistry.UpdatePrices(c.Dest.User, priceUpdates) + require.NoError(t, err) + + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + + t.Logf("New Price Registry deployed at %s", destPricesAddress.String()) +} + +func (c *CCIPContracts) SetNopsOnRamp(t *testing.T, nopsAndWeights []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight) { + tx, err := c.Source.OnRamp.SetNops(c.Source.User, nopsAndWeights) + require.NoError(t, err) + c.Source.Chain.Commit() + _, err = bind.WaitMined(context.Background(), c.Source.Chain, tx) + require.NoError(t, err) +} + +func (c *CCIPContracts) GetSourceLinkBalance(t *testing.T, addr common.Address) *big.Int { + return GetBalance(t, c.Source.Chain, c.Source.LinkToken.Address(), addr) +} + +func (c *CCIPContracts) GetDestLinkBalance(t *testing.T, addr common.Address) *big.Int { + return GetBalance(t, c.Dest.Chain, c.Dest.LinkToken.Address(), addr) +} + +func (c *CCIPContracts) GetSourceWrappedTokenBalance(t *testing.T, addr common.Address) *big.Int { + return GetBalance(t, c.Source.Chain, c.Source.WrappedNative.Address(), addr) +} + +func (c *CCIPContracts) GetDestWrappedTokenBalance(t *testing.T, addr common.Address) *big.Int { + return GetBalance(t, c.Dest.Chain, c.Dest.WrappedNative.Address(), addr) +} + +func (c *CCIPContracts) AssertBalances(t *testing.T, bas []BalanceAssertion) { + for _, b := range bas { + actual := b.Getter(t, b.Address) + t.Log("Checking balance for", b.Name, "at", b.Address.Hex(), "got", actual) + require.NotNil(t, actual, "%v getter return nil", b.Name) + if b.Within == "" { + require.Equal(t, b.Expected, actual.String(), "wrong balance for %s got %s want %s", b.Name, actual, b.Expected) + } else { + bi, _ := big.NewInt(0).SetString(b.Expected, 10) + withinI, _ := big.NewInt(0).SetString(b.Within, 10) + high := big.NewInt(0).Add(bi, withinI) + low := big.NewInt(0).Sub(bi, withinI) + require.Equal(t, -1, actual.Cmp(high), "wrong balance for %s got %s outside expected range [%s, %s]", b.Name, actual, low, high) + require.Equal(t, 1, actual.Cmp(low), "wrong balance for %s got %s outside expected range [%s, %s]", b.Name, actual, low, high) + } + } +} + +func AccountToAddress(accounts []ocr2types.Account) (addresses []common.Address, err error) { + for _, signer := range accounts { + bytes, err := hexutil.Decode(string(signer)) + if err != nil { + return []common.Address{}, errors.Wrap(err, fmt.Sprintf("given address is not valid %s", signer)) + } + if len(bytes) != 20 { + return []common.Address{}, errors.Errorf("address is not 20 bytes %s", signer) + } + addresses = append(addresses, common.BytesToAddress(bytes)) + } + return addresses, nil +} + +func OnchainPublicKeyToAddress(publicKeys []ocrtypes.OnchainPublicKey) (addresses []common.Address, err error) { + for _, signer := range publicKeys { + if len(signer) != 20 { + return []common.Address{}, errors.Errorf("address is not 20 bytes %s", signer) + } + addresses = append(addresses, common.BytesToAddress(signer)) + } + return addresses, nil +} + +func (c *CCIPContracts) DeriveOCR2Config(t *testing.T, oracles []confighelper.OracleIdentityExtra, rawOnchainConfig []byte, rawOffchainConfig []byte) *OCR2Config { + signers, transmitters, threshold, onchainConfig, offchainConfigVersion, offchainConfig, err := confighelper.ContractSetConfigArgsForTests( + 2*time.Second, // deltaProgress + 1*time.Second, // deltaResend + 1*time.Second, // deltaRound + 500*time.Millisecond, // deltaGrace + 2*time.Second, // deltaStage + 3, + []int{1, 1, 1, 1}, + oracles, + rawOffchainConfig, + 50*time.Millisecond, // Max duration query + 1*time.Second, // Max duration observation + 100*time.Millisecond, + 100*time.Millisecond, + 100*time.Millisecond, + 1, // faults + rawOnchainConfig, + ) + require.NoError(t, err) + lggr := logger.TestLogger(t) + lggr.Infow("Setting Config on Oracle Contract", + "signers", signers, + "transmitters", transmitters, + "threshold", threshold, + "onchainConfig", onchainConfig, + "encodedConfigVersion", offchainConfigVersion, + ) + signerAddresses, err := OnchainPublicKeyToAddress(signers) + require.NoError(t, err) + transmitterAddresses, err := AccountToAddress(transmitters) + require.NoError(t, err) + + return &OCR2Config{ + Signers: signerAddresses, + Transmitters: transmitterAddresses, + F: threshold, + OnchainConfig: onchainConfig, + OffchainConfigVersion: offchainConfigVersion, + OffchainConfig: offchainConfig, + } +} + +func (c *CCIPContracts) SetupCommitOCR2Config(t *testing.T, commitOnchainConfig, commitOffchainConfig []byte) { + c.commitOCRConfig = c.DeriveOCR2Config(t, c.Oracles, commitOnchainConfig, commitOffchainConfig) + // Set the DON on the commit store + _, err := c.Dest.CommitStore.SetOCR2Config( + c.Dest.User, + c.commitOCRConfig.Signers, + c.commitOCRConfig.Transmitters, + c.commitOCRConfig.F, + c.commitOCRConfig.OnchainConfig, + c.commitOCRConfig.OffchainConfigVersion, + c.commitOCRConfig.OffchainConfig, + ) + require.NoError(t, err) + c.Dest.Chain.Commit() +} + +func (c *CCIPContracts) SetupExecOCR2Config(t *testing.T, execOnchainConfig, execOffchainConfig []byte) { + c.execOCRConfig = c.DeriveOCR2Config(t, c.Oracles, execOnchainConfig, execOffchainConfig) + // Same DON on the offramp + _, err := c.Dest.OffRamp.SetOCR2Config( + c.Dest.User, + c.execOCRConfig.Signers, + c.execOCRConfig.Transmitters, + c.execOCRConfig.F, + c.execOCRConfig.OnchainConfig, + c.execOCRConfig.OffchainConfigVersion, + c.execOCRConfig.OffchainConfig, + ) + require.NoError(t, err) + c.Dest.Chain.Commit() +} + +func (c *CCIPContracts) SetupOnchainConfig(t *testing.T, commitOnchainConfig, commitOffchainConfig, execOnchainConfig, execOffchainConfig []byte) int64 { + // Note We do NOT set the payees, payment is done in the OCR2Base implementation + blockBeforeConfig, err := c.Dest.Chain.BlockByNumber(context.Background(), nil) + require.NoError(t, err) + + c.SetupCommitOCR2Config(t, commitOnchainConfig, commitOffchainConfig) + c.SetupExecOCR2Config(t, execOnchainConfig, execOffchainConfig) + + return blockBeforeConfig.Number().Int64() +} + +func (c *CCIPContracts) SendMessage(t *testing.T, gasLimit, tokenAmount *big.Int, receiverAddr common.Address) { + extraArgs, err := GetEVMExtraArgsV1(gasLimit, false) + require.NoError(t, err) + msg := router.ClientEVM2AnyMessage{ + Receiver: MustEncodeAddress(t, receiverAddr), + Data: []byte("hello"), + TokenAmounts: []router.ClientEVMTokenAmount{ + { + Token: c.Source.LinkToken.Address(), + Amount: tokenAmount, + }, + }, + FeeToken: c.Source.LinkToken.Address(), + ExtraArgs: extraArgs, + } + fee, err := c.Source.Router.GetFee(nil, c.Dest.ChainSelector, msg) + require.NoError(t, err) + // Currently no overhead and 1gwei dest gas price. So fee is simply gasLimit * gasPrice. + // require.Equal(t, new(big.Int).Mul(gasLimit, gasPrice).String(), fee.String()) + // Approve the fee amount + the token amount + _, err = c.Source.LinkToken.Approve(c.Source.User, c.Source.Router.Address(), new(big.Int).Add(fee, tokenAmount)) + require.NoError(t, err) + c.Source.Chain.Commit() + c.SendRequest(t, msg) +} + +func GetBalances(t *testing.T, brs []BalanceReq) (map[string]*big.Int, error) { + m := make(map[string]*big.Int) + for _, br := range brs { + m[br.Name] = br.Getter(t, br.Addr) + if m[br.Name] == nil { + return nil, fmt.Errorf("%v getter return nil", br.Name) + } + } + return m, nil +} + +func MustAddBigInt(a *big.Int, b string) *big.Int { + bi, _ := big.NewInt(0).SetString(b, 10) + return big.NewInt(0).Add(a, bi) +} + +func MustSubBigInt(a *big.Int, b string) *big.Int { + bi, _ := big.NewInt(0).SetString(b, 10) + return big.NewInt(0).Sub(a, bi) +} + +func MustEncodeAddress(t *testing.T, address common.Address) []byte { + bts, err := utils.ABIEncode(`[{"type":"address"}]`, address) + require.NoError(t, err) + return bts +} + +func SetAdminAndRegisterPool(t *testing.T, + chain *backends.SimulatedBackend, + user *bind.TransactOpts, + tokenAdminRegistry *token_admin_registry.TokenAdminRegistry, + tokenAddress common.Address, + poolAddress common.Address) { + _, err := tokenAdminRegistry.ProposeAdministrator(user, tokenAddress, user.From) + require.NoError(t, err) + _, err = tokenAdminRegistry.AcceptAdminRole(user, tokenAddress) + require.NoError(t, err) + _, err = tokenAdminRegistry.SetPool(user, tokenAddress, poolAddress) + require.NoError(t, err) + + chain.Commit() +} + +func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destChainID, destChainSelector uint64) CCIPContracts { + sourceChain, sourceUser := SetupChain(t) + destChain, destUser := SetupChain(t) + + // ================================================================ + // │ Deploy RMN │ + // ================================================================ + + armSourceAddress, _, _, err := mock_arm_contract.DeployMockARMContract( + sourceUser, + sourceChain, + ) + require.NoError(t, err) + sourceARM, err := mock_arm_contract.NewMockARMContract(armSourceAddress, sourceChain) + require.NoError(t, err) + armProxySourceAddress, _, _, err := arm_proxy_contract.DeployARMProxyContract( + sourceUser, + sourceChain, + armSourceAddress, + ) + require.NoError(t, err) + sourceARMProxy, err := arm_proxy_contract.NewARMProxyContract(armProxySourceAddress, sourceChain) + require.NoError(t, err) + sourceChain.Commit() + + armDestAddress, _, _, err := mock_arm_contract.DeployMockARMContract( + destUser, + destChain, + ) + require.NoError(t, err) + armProxyDestAddress, _, _, err := arm_proxy_contract.DeployARMProxyContract( + destUser, + destChain, + armDestAddress, + ) + require.NoError(t, err) + destChain.Commit() + destARM, err := mock_arm_contract.NewMockARMContract(armDestAddress, destChain) + require.NoError(t, err) + destARMProxy, err := arm_proxy_contract.NewARMProxyContract(armProxyDestAddress, destChain) + require.NoError(t, err) + + // ================================================================ + // │ Deploy TokenAdminRegistry │ + // ================================================================ + + sourceTokenAdminRegistryAddress, _, _, err := token_admin_registry.DeployTokenAdminRegistry(sourceUser, sourceChain) + require.NoError(t, err) + sourceTokenAdminRegistry, err := token_admin_registry.NewTokenAdminRegistry(sourceTokenAdminRegistryAddress, sourceChain) + require.NoError(t, err) + sourceChain.Commit() + + destTokenAdminRegistryAddress, _, _, err := token_admin_registry.DeployTokenAdminRegistry(destUser, destChain) + require.NoError(t, err) + destTokenAdminRegistry, err := token_admin_registry.NewTokenAdminRegistry(destTokenAdminRegistryAddress, destChain) + require.NoError(t, err) + destChain.Commit() + + // ================================================================ + // │ Deploy Tokens │ + // ================================================================ + + // Deploy link token and pool on source chain + sourceLinkTokenAddress, _, _, err := link_token_interface.DeployLinkToken(sourceUser, sourceChain) + require.NoError(t, err) + sourceChain.Commit() + sourceLinkToken, err := link_token_interface.NewLinkToken(sourceLinkTokenAddress, sourceChain) + require.NoError(t, err) + t.Logf("Deloyed LINK token on source chain at %s", sourceLinkTokenAddress.String()) + + sourceWeth9addr, _, _, err := weth9.DeployWETH9(sourceUser, sourceChain) + require.NoError(t, err) + sourceWrapped, err := weth9.NewWETH9(sourceWeth9addr, sourceChain) + require.NoError(t, err) + t.Logf("Deloyed WETH9 token on source chain at %s", sourceWeth9addr.String()) + + sourceCustomTokenAddress, _, _, err := link_token_interface.DeployLinkToken(sourceUser, sourceChain) + require.NoError(t, err) + sourceCustomToken, err := link_token_interface.NewLinkToken(sourceCustomTokenAddress, sourceChain) + require.NoError(t, err) + destChain.Commit() + t.Logf("Deloyed custom token on source chain at %s", sourceCustomTokenAddress.String()) + + // Dest chain + + destLinkTokenAddress, _, _, err := link_token_interface.DeployLinkToken(destUser, destChain) + require.NoError(t, err) + destChain.Commit() + destLinkToken, err := link_token_interface.NewLinkToken(destLinkTokenAddress, destChain) + require.NoError(t, err) + t.Logf("Deloyed LINK token on dest chain at %s", destLinkTokenAddress.String()) + + destWeth9addr, _, _, err := weth9.DeployWETH9(destUser, destChain) + require.NoError(t, err) + destWrapped, err := weth9.NewWETH9(destWeth9addr, destChain) + require.NoError(t, err) + t.Logf("Deloyed WETH9 token on dest chain at %s", destWeth9addr.String()) + + destCustomTokenAddress, _, _, err := link_token_interface.DeployLinkToken(destUser, destChain) + require.NoError(t, err) + destCustomToken, err := link_token_interface.NewLinkToken(destCustomTokenAddress, destChain) + require.NoError(t, err) + destChain.Commit() + t.Logf("Deloyed custom token on dest chain at %s", destCustomTokenAddress.String()) + + // ================================================================ + // │ Deploy Routers │ + // ================================================================ + + sourceRouterAddress, _, _, err := router.DeployRouter(sourceUser, sourceChain, sourceWeth9addr, armProxySourceAddress) + require.NoError(t, err) + sourceRouter, err := router.NewRouter(sourceRouterAddress, sourceChain) + require.NoError(t, err) + sourceChain.Commit() + + destRouterAddress, _, _, err := router.DeployRouter(destUser, destChain, destWeth9addr, armProxyDestAddress) + require.NoError(t, err) + destRouter, err := router.NewRouter(destRouterAddress, destChain) + require.NoError(t, err) + destChain.Commit() + + // ================================================================ + // │ Deploy Pools │ + // ================================================================ + + sourcePoolLinkAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( + sourceUser, + sourceChain, + sourceLinkTokenAddress, + []common.Address{}, + armProxySourceAddress, + true, + sourceRouterAddress, + ) + require.NoError(t, err) + sourceChain.Commit() + SetAdminAndRegisterPool(t, sourceChain, sourceUser, sourceTokenAdminRegistry, sourceLinkTokenAddress, sourcePoolLinkAddress) + + sourceLinkPool, err := lock_release_token_pool.NewLockReleaseTokenPool(sourcePoolLinkAddress, sourceChain) + require.NoError(t, err) + + sourceWeth9PoolAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( + sourceUser, + sourceChain, + sourceWeth9addr, + []common.Address{}, + armProxySourceAddress, + true, + sourceRouterAddress, + ) + require.NoError(t, err) + sourceChain.Commit() + SetAdminAndRegisterPool(t, sourceChain, sourceUser, sourceTokenAdminRegistry, sourceWeth9addr, sourceWeth9PoolAddress) + + sourceWeth9Pool, err := lock_release_token_pool.NewLockReleaseTokenPool(sourceWeth9PoolAddress, sourceChain) + require.NoError(t, err) + + // dest + + destPoolLinkAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( + destUser, + destChain, + destLinkTokenAddress, + []common.Address{}, + armProxyDestAddress, + true, + destRouterAddress, + ) + require.NoError(t, err) + destChain.Commit() + SetAdminAndRegisterPool(t, destChain, destUser, destTokenAdminRegistry, destLinkTokenAddress, destPoolLinkAddress) + + destLinkPool, err := lock_release_token_pool.NewLockReleaseTokenPool(destPoolLinkAddress, destChain) + require.NoError(t, err) + destChain.Commit() + + // Float the offramp pool + o, err := destLinkPool.Owner(nil) + require.NoError(t, err) + require.Equal(t, destUser.From.String(), o.String()) + _, err = destLinkPool.SetRebalancer(destUser, destUser.From) + require.NoError(t, err) + _, err = destLinkToken.Approve(destUser, destPoolLinkAddress, Link(200)) + require.NoError(t, err) + _, err = destLinkPool.ProvideLiquidity(destUser, Link(200)) + require.NoError(t, err) + destChain.Commit() + + destWrappedPoolAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( + destUser, + destChain, + destWeth9addr, + []common.Address{}, + armProxyDestAddress, + true, + destRouterAddress, + ) + require.NoError(t, err) + destChain.Commit() + SetAdminAndRegisterPool(t, destChain, destUser, destTokenAdminRegistry, destWeth9addr, destWrappedPoolAddress) + + destWrappedPool, err := lock_release_token_pool.NewLockReleaseTokenPool(destWrappedPoolAddress, destChain) + require.NoError(t, err) + + poolFloatValue := big.NewInt(1e18) + + destUser.Value = poolFloatValue + _, err = destWrapped.Deposit(destUser) + require.NoError(t, err) + destChain.Commit() + destUser.Value = nil + + _, err = destWrapped.Transfer(destUser, destWrappedPool.Address(), poolFloatValue) + require.NoError(t, err) + destChain.Commit() + + // ================================================================ + // │ Configure token pools │ + // ================================================================ + + abiEncodedDestLinkPool, err := abihelpers.EncodeAddress(destLinkPool.Address()) + require.NoError(t, err) + abiEncodedDestLinkTokenAddress, err := abihelpers.EncodeAddress(destLinkToken.Address()) + require.NoError(t, err) + _, err = sourceLinkPool.ApplyChainUpdates( + sourceUser, + []lock_release_token_pool.TokenPoolChainUpdate{{ + RemoteChainSelector: DestChainSelector, + RemotePoolAddress: abiEncodedDestLinkPool, + RemoteTokenAddress: abiEncodedDestLinkTokenAddress, + Allowed: true, + OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + }}, + ) + require.NoError(t, err) + + abiEncodedDestWrappedPool, err := abihelpers.EncodeAddress(destWrappedPool.Address()) + require.NoError(t, err) + abiEncodedDestWrappedTokenAddr, err := abihelpers.EncodeAddress(destWeth9addr) + require.NoError(t, err) + _, err = sourceWeth9Pool.ApplyChainUpdates( + sourceUser, + []lock_release_token_pool.TokenPoolChainUpdate{{ + RemoteChainSelector: DestChainSelector, + RemotePoolAddress: abiEncodedDestWrappedPool, + RemoteTokenAddress: abiEncodedDestWrappedTokenAddr, + Allowed: true, + OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + }}, + ) + require.NoError(t, err) + sourceChain.Commit() + + abiEncodedSourceLinkPool, err := abihelpers.EncodeAddress(sourceLinkPool.Address()) + require.NoError(t, err) + abiEncodedSourceLinkTokenAddr, err := abihelpers.EncodeAddress(sourceLinkTokenAddress) + require.NoError(t, err) + _, err = destLinkPool.ApplyChainUpdates( + destUser, + []lock_release_token_pool.TokenPoolChainUpdate{{ + RemoteChainSelector: SourceChainSelector, + RemotePoolAddress: abiEncodedSourceLinkPool, + RemoteTokenAddress: abiEncodedSourceLinkTokenAddr, + Allowed: true, + OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + }}, + ) + require.NoError(t, err) + + abiEncodedSourceWrappedPool, err := abihelpers.EncodeAddress(sourceWeth9Pool.Address()) + require.NoError(t, err) + abiEncodedSourceWrappedTokenAddr, err := abihelpers.EncodeAddress(sourceWrapped.Address()) + require.NoError(t, err) + _, err = destWrappedPool.ApplyChainUpdates( + destUser, + []lock_release_token_pool.TokenPoolChainUpdate{{ + RemoteChainSelector: SourceChainSelector, + RemotePoolAddress: abiEncodedSourceWrappedPool, + RemoteTokenAddress: abiEncodedSourceWrappedTokenAddr, + Allowed: true, + OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + }}, + ) + require.NoError(t, err) + destChain.Commit() + + // ================================================================ + // │ Deploy Price Registry │ + // ================================================================ + + sourcePricesAddress, _, _, err := price_registry_1_2_0.DeployPriceRegistry( + sourceUser, + sourceChain, + nil, + []common.Address{sourceLinkTokenAddress, sourceWeth9addr}, + 60*60*24*14, // two weeks + ) + require.NoError(t, err) + + srcPriceRegistry, err := price_registry_1_2_0.NewPriceRegistry(sourcePricesAddress, sourceChain) + require.NoError(t, err) + + _, err = srcPriceRegistry.UpdatePrices(sourceUser, price_registry_1_2_0.InternalPriceUpdates{ + TokenPriceUpdates: []price_registry_1_2_0.InternalTokenPriceUpdate{ + { + SourceToken: sourceLinkTokenAddress, + UsdPerToken: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(20)), + }, + { + SourceToken: sourceWeth9addr, + UsdPerToken: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2000)), + }, + }, + GasPriceUpdates: []price_registry_1_2_0.InternalGasPriceUpdate{ + { + DestChainSelector: destChainSelector, + UsdPerUnitGas: big.NewInt(20000e9), + }, + }, + }) + require.NoError(t, err) + + // ================================================================ + // │ Deploy Lane │ + // ================================================================ + + onRampAddress, _, _, err := evm_2_evm_onramp.DeployEVM2EVMOnRamp( + sourceUser, // user + sourceChain, // client + evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ + LinkToken: sourceLinkTokenAddress, + ChainSelector: sourceChainSelector, + DestChainSelector: destChainSelector, + DefaultTxGasLimit: 200_000, + MaxNopFeesJuels: big.NewInt(0).Mul(big.NewInt(100_000_000), big.NewInt(1e18)), + PrevOnRamp: common.HexToAddress(""), + RmnProxy: armProxySourceAddress, // RMN, formerly ARM + TokenAdminRegistry: sourceTokenAdminRegistry.Address(), + }, + evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ + Router: sourceRouterAddress, + MaxNumberOfTokensPerMsg: 5, + DestGasOverhead: 350_000, + DestGasPerPayloadByte: 16, + DestDataAvailabilityOverheadGas: 33_596, + DestGasPerDataAvailabilityByte: 16, + DestDataAvailabilityMultiplierBps: 6840, // 0.684 + PriceRegistry: sourcePricesAddress, + MaxDataBytes: 1e5, + MaxPerMsgGasLimit: 4_000_000, + DefaultTokenFeeUSDCents: 50, + DefaultTokenDestGasOverhead: 34_000, + DefaultTokenDestBytesOverhead: 500, + }, + evm_2_evm_onramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: LinkUSDValue(100), + Rate: LinkUSDValue(1), + }, + []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ + { + Token: sourceLinkTokenAddress, + NetworkFeeUSDCents: 1_00, + GasMultiplierWeiPerEth: 1e18, + PremiumMultiplierWeiPerEth: 9e17, + Enabled: true, + }, + { + Token: sourceWeth9addr, + NetworkFeeUSDCents: 1_00, + GasMultiplierWeiPerEth: 1e18, + PremiumMultiplierWeiPerEth: 1e18, + Enabled: true, + }, + }, + []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + { + Token: sourceLinkTokenAddress, + MinFeeUSDCents: 50, // $0.5 + MaxFeeUSDCents: 1_000_000_00, // $ 1 million + DeciBps: 5_0, // 5 bps + DestGasOverhead: 34_000, + DestBytesOverhead: 32, + AggregateRateLimitEnabled: true, + }, + }, + []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{}, + ) + require.NoError(t, err) + onRamp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, sourceChain) + require.NoError(t, err) + + _, err = sourceRouter.ApplyRampUpdates(sourceUser, []router.RouterOnRamp{{DestChainSelector: destChainSelector, OnRamp: onRampAddress}}, nil, nil) + require.NoError(t, err) + sourceChain.Commit() + + destPriceRegistryAddress, _, _, err := price_registry_1_2_0.DeployPriceRegistry( + destUser, + destChain, + nil, + []common.Address{destLinkTokenAddress, destWeth9addr}, + 60*60*24*14, // two weeks + ) + require.NoError(t, err) + destPriceRegistry, err := price_registry_1_2_0.NewPriceRegistry(destPriceRegistryAddress, destChain) + require.NoError(t, err) + + // Deploy commit store. + commitStoreAddress, _, _, err := commit_store_helper_1_2_0.DeployCommitStoreHelper( + destUser, // user + destChain, // client + commit_store_helper_1_2_0.CommitStoreStaticConfig{ + ChainSelector: destChainSelector, + SourceChainSelector: sourceChainSelector, + OnRamp: onRamp.Address(), + ArmProxy: destARMProxy.Address(), + }, + ) + require.NoError(t, err) + destChain.Commit() + commitStore, err := commit_store.NewCommitStore(commitStoreAddress, destChain) + require.NoError(t, err) + commitStoreHelper, err := commit_store_helper.NewCommitStoreHelper(commitStoreAddress, destChain) + require.NoError(t, err) + + offRampAddress, _, _, err := evm_2_evm_offramp.DeployEVM2EVMOffRamp( + destUser, + destChain, + evm_2_evm_offramp.EVM2EVMOffRampStaticConfig{ + CommitStore: commitStore.Address(), + ChainSelector: destChainSelector, + SourceChainSelector: sourceChainSelector, + OnRamp: onRampAddress, + PrevOffRamp: common.HexToAddress(""), + RmnProxy: armProxyDestAddress, // RMN, formerly ARM + TokenAdminRegistry: destTokenAdminRegistryAddress, + }, + evm_2_evm_offramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: LinkUSDValue(100), + Rate: LinkUSDValue(1), + }, + ) + require.NoError(t, err) + offRamp, err := evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampAddress, destChain) + require.NoError(t, err) + destChain.Commit() + + _, err = destPriceRegistry.ApplyPriceUpdatersUpdates(destUser, []common.Address{commitStoreAddress}, []common.Address{}) + require.NoError(t, err) + _, err = destRouter.ApplyRampUpdates( + destUser, + nil, + nil, + []router.RouterOffRamp{{SourceChainSelector: sourceChainSelector, OffRamp: offRampAddress}}, + ) + require.NoError(t, err) + + // Deploy 2 revertable (one SS one non-SS) + revertingMessageReceiver1Address, _, _, err := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver(destUser, destChain, false) + require.NoError(t, err) + revertingMessageReceiver1, _ := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(revertingMessageReceiver1Address, destChain) + revertingMessageReceiver2Address, _, _, err := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver(destUser, destChain, false) + require.NoError(t, err) + revertingMessageReceiver2, _ := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(revertingMessageReceiver2Address, destChain) + // Need to commit here, or we will hit the block gas limit when deploying the executor + sourceChain.Commit() + destChain.Commit() + + // Ensure we have at least finality blocks. + for i := 0; i < 50; i++ { + sourceChain.Commit() + destChain.Commit() + } + + source := SourceChain{ + Common: Common{ + ChainID: sourceChainID, + ChainSelector: sourceChainSelector, + User: sourceUser, + Chain: sourceChain, + LinkToken: sourceLinkToken, + LinkTokenPool: sourceLinkPool, + CustomToken: sourceCustomToken, + ARM: sourceARM, + ARMProxy: sourceARMProxy, + PriceRegistry: srcPriceRegistry, + WrappedNative: sourceWrapped, + WrappedNativePool: sourceWeth9Pool, + TokenAdminRegistry: sourceTokenAdminRegistry, + }, + Router: sourceRouter, + OnRamp: onRamp, + } + dest := DestinationChain{ + Common: Common{ + ChainID: destChainID, + ChainSelector: destChainSelector, + User: destUser, + Chain: destChain, + LinkToken: destLinkToken, + LinkTokenPool: destLinkPool, + CustomToken: destCustomToken, + ARM: destARM, + ARMProxy: destARMProxy, + PriceRegistry: destPriceRegistry, + WrappedNative: destWrapped, + WrappedNativePool: destWrappedPool, + TokenAdminRegistry: destTokenAdminRegistry, + }, + CommitStoreHelper: commitStoreHelper, + CommitStore: commitStore, + Router: destRouter, + OffRamp: offRamp, + Receivers: []MaybeRevertReceiver{{Receiver: revertingMessageReceiver1, Strict: false}, {Receiver: revertingMessageReceiver2, Strict: true}}, + } + + return CCIPContracts{ + Source: source, + Dest: dest, + } +} + +func (c *CCIPContracts) SendRequest(t *testing.T, msg router.ClientEVM2AnyMessage) *types.Transaction { + tx, err := c.Source.Router.CcipSend(c.Source.User, c.Dest.ChainSelector, msg) + require.NoError(t, err) + ConfirmTxs(t, []*types.Transaction{tx}, c.Source.Chain) + return tx +} + +func (c *CCIPContracts) AssertExecState(t *testing.T, log logpoller.Log, state MessageExecutionState, offRampOpts ...common.Address) { + var offRamp *evm_2_evm_offramp.EVM2EVMOffRamp + var err error + if len(offRampOpts) > 0 { + offRamp, err = evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampOpts[0], c.Dest.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Dest.OffRamp, "no offRamp configured") + offRamp = c.Dest.OffRamp + } + executionStateChanged, err := offRamp.ParseExecutionStateChanged(log.ToGethLog()) + require.NoError(t, err) + if MessageExecutionState(executionStateChanged.State) != state { + t.Log("Execution failed", hexutil.Encode(executionStateChanged.ReturnData)) + t.Fail() + } +} + +func GetEVMExtraArgsV1(gasLimit *big.Int, strict bool) ([]byte, error) { + EVMV1Tag := []byte{0x97, 0xa6, 0x57, 0xc9} + + encodedArgs, err := utils.ABIEncode(`[{"type":"uint256"},{"type":"bool"}]`, gasLimit, strict) + if err != nil { + return nil, err + } + + return append(EVMV1Tag, encodedArgs...), nil +} + +func GetEVMExtraArgsV2(gasLimit *big.Int, allowOutOfOrder bool) ([]byte, error) { + // see Client.sol. + EVMV2Tag := hexutil.MustDecode("0x181dcf10") + + encodedArgs, err := utils.ABIEncode(`[{"type":"uint256"},{"type":"bool"}]`, gasLimit, allowOutOfOrder) + if err != nil { + return nil, err + } + + return append(EVMV2Tag, encodedArgs...), nil +} + +type ManualExecArgs struct { + SourceChainID, DestChainID uint64 + DestUser *bind.TransactOpts + SourceChain, DestChain bind.ContractBackend + SourceStartBlock *big.Int // the block in/after which failed ccip-send transaction was triggered + DestStartBlock uint64 // the start block for filtering ReportAccepted event (including the failed seq num) + // in destination chain. if not provided to be derived by ApproxDestStartBlock method + DestLatestBlockNum uint64 // current block number in destination + DestDeployedAt uint64 // destination block number for the initial destination contract deployment. + // Can be any number before the tx was reverted in destination chain. Preferably this needs to be set up with + // a value greater than zero to avoid performance issue in locating approximate destination block + SendReqLogIndex uint // log index of the CCIPSendRequested log in source chain + SendReqTxHash string // tx hash of the ccip-send transaction for which execution was reverted + CommitStore string + OnRamp string + OffRamp string + SeqNr uint64 + GasLimit *big.Int +} + +// ApproxDestStartBlock attempts to locate a block in destination chain with timestamp closest to the timestamp of the block +// in source chain in which ccip-send transaction was included +// it uses binary search to locate the block with the closest timestamp +// if the block located has a timestamp greater than the timestamp of mentioned source block +// it just returns the first block found with lesser timestamp of the source block +// providing a value of args.DestDeployedAt ensures better performance by reducing the range of block numbers to be traversed +func (args *ManualExecArgs) ApproxDestStartBlock() error { + sourceBlockHdr, err := args.SourceChain.HeaderByNumber(context.Background(), args.SourceStartBlock) + if err != nil { + return err + } + sendTxTime := sourceBlockHdr.Time + maxBlockNum := args.DestLatestBlockNum + // setting this to an approx value of 1000 considering destination chain would have at least 1000 blocks before the transaction started + minBlockNum := args.DestDeployedAt + closestBlockNum := uint64(math.Floor((float64(maxBlockNum) + float64(minBlockNum)) / 2)) + var closestBlockHdr *types.Header + closestBlockHdr, err = args.DestChain.HeaderByNumber(context.Background(), big.NewInt(int64(closestBlockNum))) + if err != nil { + return err + } + // to reduce the number of RPC calls increase the value of blockOffset + blockOffset := uint64(10) + for { + blockNum := closestBlockHdr.Number.Uint64() + if minBlockNum > maxBlockNum { + break + } + timeDiff := math.Abs(float64(closestBlockHdr.Time - sendTxTime)) + // break if the difference in timestamp is lesser than 1 minute + if timeDiff < 60 { + break + } else if closestBlockHdr.Time > sendTxTime { + maxBlockNum = blockNum - 1 + } else { + minBlockNum = blockNum + 1 + } + closestBlockNum = uint64(math.Floor((float64(maxBlockNum) + float64(minBlockNum)) / 2)) + closestBlockHdr, err = args.DestChain.HeaderByNumber(context.Background(), big.NewInt(int64(closestBlockNum))) + if err != nil { + return err + } + } + + for closestBlockHdr.Time > sendTxTime { + closestBlockNum = closestBlockNum - blockOffset + if closestBlockNum <= 0 { + return fmt.Errorf("approx destination blocknumber not found") + } + closestBlockHdr, err = args.DestChain.HeaderByNumber(context.Background(), big.NewInt(int64(closestBlockNum))) + if err != nil { + return err + } + } + args.DestStartBlock = closestBlockHdr.Number.Uint64() + fmt.Println("using approx destination start block number", args.DestStartBlock) + return nil +} + +func (args *ManualExecArgs) FindSeqNrFromCCIPSendRequested() (uint64, error) { + var seqNr uint64 + onRampContract, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(common.HexToAddress(args.OnRamp), args.SourceChain) + if err != nil { + return seqNr, err + } + iterator, err := onRampContract.FilterCCIPSendRequested(&bind.FilterOpts{ + Start: args.SourceStartBlock.Uint64(), + }) + if err != nil { + return seqNr, err + } + for iterator.Next() { + if iterator.Event.Raw.Index == args.SendReqLogIndex && + iterator.Event.Raw.TxHash.Hex() == args.SendReqTxHash { + seqNr = iterator.Event.Message.SequenceNumber + break + } + } + if seqNr == 0 { + return seqNr, + fmt.Errorf("no CCIPSendRequested logs found for logIndex %d starting from block number %d", args.SendReqLogIndex, args.SourceStartBlock) + } + return seqNr, nil +} + +func (args *ManualExecArgs) ExecuteManually() (*types.Transaction, error) { + if args.SourceChainID == 0 || + args.DestChainID == 0 || + args.DestUser == nil { + return nil, fmt.Errorf("chain ids and owners are mandatory for source and dest chain") + } + if !common.IsHexAddress(args.CommitStore) || + !common.IsHexAddress(args.OffRamp) || + !common.IsHexAddress(args.OnRamp) { + return nil, fmt.Errorf("contract addresses must be valid hex address") + } + if args.SendReqTxHash == "" { + return nil, fmt.Errorf("tx hash of ccip-send request are required") + } + if args.SourceStartBlock == nil { + return nil, fmt.Errorf("must provide the value of source block in/after which ccip-send tx was included") + } + if args.SeqNr == 0 { + if args.SendReqLogIndex == 0 { + return nil, fmt.Errorf("must provide the value of log index of ccip-send request") + } + // locate seq nr from CCIPSendRequested log + seqNr, err := args.FindSeqNrFromCCIPSendRequested() + if err != nil { + return nil, err + } + args.SeqNr = seqNr + } + commitStore, err := commit_store.NewCommitStore(common.HexToAddress(args.CommitStore), args.DestChain) + if err != nil { + return nil, err + } + if args.DestStartBlock < 1 { + err = args.ApproxDestStartBlock() + if err != nil { + return nil, err + } + } + iterator, err := commitStore.FilterReportAccepted(&bind.FilterOpts{Start: args.DestStartBlock}) + if err != nil { + return nil, err + } + + var commitReport *commit_store.CommitStoreCommitReport + for iterator.Next() { + if iterator.Event.Report.Interval.Min <= args.SeqNr && iterator.Event.Report.Interval.Max >= args.SeqNr { + commitReport = &iterator.Event.Report + fmt.Println("Found root") + break + } + } + if commitReport == nil { + return nil, fmt.Errorf("unable to find seq num %d in commit report", args.SeqNr) + } + + return args.execute(commitReport) +} + +func (args *ManualExecArgs) execute(report *commit_store.CommitStoreCommitReport) (*types.Transaction, error) { + log.Info().Msg("Executing request manually") + seqNr := args.SeqNr + // Build a merkle tree for the report + mctx := hashutil.NewKeccak() + onRampContract, err := evm_2_evm_onramp_1_2_0.NewEVM2EVMOnRamp(common.HexToAddress(args.OnRamp), args.SourceChain) + if err != nil { + return nil, err + } + leafHasher := v1_2_0.NewLeafHasher(args.SourceChainID, args.DestChainID, common.HexToAddress(args.OnRamp), mctx, onRampContract) + if leafHasher == nil { + return nil, fmt.Errorf("unable to create leaf hasher") + } + + var leaves [][32]byte + var curr, prove int + var msgs []evm_2_evm_offramp.InternalEVM2EVMMessage + var manualExecGasLimits []*big.Int + var tokenData [][][]byte + sendRequestedIterator, err := onRampContract.FilterCCIPSendRequested(&bind.FilterOpts{ + Start: args.SourceStartBlock.Uint64(), + }) + if err != nil { + return nil, err + } + for sendRequestedIterator.Next() { + if sendRequestedIterator.Event.Message.SequenceNumber <= report.Interval.Max && + sendRequestedIterator.Event.Message.SequenceNumber >= report.Interval.Min { + fmt.Println("Found seq num", sendRequestedIterator.Event.Message.SequenceNumber, report.Interval) + hash, err2 := leafHasher.HashLeaf(sendRequestedIterator.Event.Raw) + if err2 != nil { + return nil, err2 + } + leaves = append(leaves, hash) + if sendRequestedIterator.Event.Message.SequenceNumber == seqNr { + fmt.Printf("Found proving %d %+v\n", curr, sendRequestedIterator.Event.Message) + var tokensAndAmounts []evm_2_evm_offramp.ClientEVMTokenAmount + for _, tokenAndAmount := range sendRequestedIterator.Event.Message.TokenAmounts { + tokensAndAmounts = append(tokensAndAmounts, evm_2_evm_offramp.ClientEVMTokenAmount{ + Token: tokenAndAmount.Token, + Amount: tokenAndAmount.Amount, + }) + } + msg := evm_2_evm_offramp.InternalEVM2EVMMessage{ + SourceChainSelector: sendRequestedIterator.Event.Message.SourceChainSelector, + Sender: sendRequestedIterator.Event.Message.Sender, + Receiver: sendRequestedIterator.Event.Message.Receiver, + SequenceNumber: sendRequestedIterator.Event.Message.SequenceNumber, + GasLimit: sendRequestedIterator.Event.Message.GasLimit, + Strict: sendRequestedIterator.Event.Message.Strict, + Nonce: sendRequestedIterator.Event.Message.Nonce, + FeeToken: sendRequestedIterator.Event.Message.FeeToken, + FeeTokenAmount: sendRequestedIterator.Event.Message.FeeTokenAmount, + Data: sendRequestedIterator.Event.Message.Data, + TokenAmounts: tokensAndAmounts, + SourceTokenData: sendRequestedIterator.Event.Message.SourceTokenData, + MessageId: sendRequestedIterator.Event.Message.MessageId, + } + msgs = append(msgs, msg) + if args.GasLimit != nil { + msg.GasLimit = args.GasLimit + } + manualExecGasLimits = append(manualExecGasLimits, msg.GasLimit) + var msgTokenData [][]byte + for range sendRequestedIterator.Event.Message.TokenAmounts { + msgTokenData = append(msgTokenData, []byte{}) + } + + tokenData = append(tokenData, msgTokenData) + prove = curr + } + curr++ + } + } + sendRequestedIterator.Close() + if msgs == nil { + return nil, fmt.Errorf("unable to find msg with seqNr %d", seqNr) + } + tree, err := merklemulti.NewTree(mctx, leaves) + if err != nil { + return nil, err + } + if tree.Root() != report.MerkleRoot { + return nil, fmt.Errorf("root doesn't match") + } + + proof, err := tree.Prove([]int{prove}) + if err != nil { + return nil, err + } + + offRampProof := evm_2_evm_offramp.InternalExecutionReport{ + Messages: msgs, + OffchainTokenData: tokenData, + Proofs: proof.Hashes, + ProofFlagBits: abihelpers.ProofFlagsToBits(proof.SourceFlags), + } + offRamp, err := evm_2_evm_offramp.NewEVM2EVMOffRamp(common.HexToAddress(args.OffRamp), args.DestChain) + if err != nil { + return nil, err + } + // Execute. + return offRamp.ManuallyExecute(args.DestUser, offRampProof, manualExecGasLimits) +} + +func (c *CCIPContracts) ExecuteMessage( + t *testing.T, + req logpoller.Log, + txHash common.Hash, + destStartBlock uint64, +) uint64 { + t.Log("Executing request manually") + sendReqReceipt, err := c.Source.Chain.TransactionReceipt(context.Background(), txHash) + require.NoError(t, err) + args := ManualExecArgs{ + SourceChainID: c.Source.ChainID, + DestChainID: c.Dest.ChainID, + DestUser: c.Dest.User, + SourceChain: c.Source.Chain, + DestChain: c.Dest.Chain, + SourceStartBlock: sendReqReceipt.BlockNumber, + DestStartBlock: destStartBlock, + DestLatestBlockNum: c.Dest.Chain.Blockchain().CurrentBlock().Number.Uint64(), + SendReqLogIndex: uint(req.LogIndex), + SendReqTxHash: txHash.String(), + CommitStore: c.Dest.CommitStore.Address().String(), + OnRamp: c.Source.OnRamp.Address().String(), + OffRamp: c.Dest.OffRamp.Address().String(), + } + tx, err := args.ExecuteManually() + require.NoError(t, err) + c.Dest.Chain.Commit() + c.Source.Chain.Commit() + rec, err := c.Dest.Chain.TransactionReceipt(context.Background(), tx.Hash()) + require.NoError(t, err) + require.Equal(t, uint64(1), rec.Status, "manual execution failed") + t.Logf("Manual Execution completed for seqNum %d", args.SeqNr) + return args.SeqNr +} + +func GetBalance(t *testing.T, chain bind.ContractBackend, tokenAddr common.Address, addr common.Address) *big.Int { + token, err := link_token_interface.NewLinkToken(tokenAddr, chain) + require.NoError(t, err) + bal, err := token.BalanceOf(nil, addr) + require.NoError(t, err) + return bal +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/config.go b/core/services/ocr2/plugins/ccip/testhelpers/config.go new file mode 100644 index 0000000000..f70f1954f1 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/testhelpers/config.go @@ -0,0 +1,73 @@ +// Package with set of configs that should be used only within tests suites + +package testhelpers + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0" +) + +var PermissionLessExecutionThresholdSeconds = uint32(FirstBlockAge.Seconds()) + +func (c *CCIPContracts) CreateDefaultCommitOnchainConfig(t *testing.T) []byte { + config, err := abihelpers.EncodeAbiStruct(ccipdata.CommitOnchainConfig{ + PriceRegistry: c.Dest.PriceRegistry.Address(), + }) + require.NoError(t, err) + return config +} + +func (c *CCIPContracts) CreateDefaultCommitOffchainConfig(t *testing.T) []byte { + return c.createCommitOffchainConfig(t, 10*time.Second, 5*time.Second) +} + +func (c *CCIPContracts) createCommitOffchainConfig(t *testing.T, feeUpdateHearBeat time.Duration, inflightCacheExpiry time.Duration) []byte { + config, err := NewCommitOffchainConfig( + *config.MustNewDuration(feeUpdateHearBeat), + 1, + 1, + *config.MustNewDuration(feeUpdateHearBeat), + 1, + *config.MustNewDuration(inflightCacheExpiry), + ).Encode() + require.NoError(t, err) + return config +} + +func (c *CCIPContracts) CreateDefaultExecOnchainConfig(t *testing.T) []byte { + config, err := abihelpers.EncodeAbiStruct(v1_5_0.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: PermissionLessExecutionThresholdSeconds, + Router: c.Dest.Router.Address(), + PriceRegistry: c.Dest.PriceRegistry.Address(), + MaxDataBytes: 1e5, + MaxNumberOfTokensPerMsg: 5, + MaxPoolReleaseOrMintGas: 200_000, + MaxTokenTransferGas: 100_000, + }) + require.NoError(t, err) + return config +} + +func (c *CCIPContracts) CreateDefaultExecOffchainConfig(t *testing.T) []byte { + return c.createExecOffchainConfig(t, 1*time.Minute, 1*time.Minute) +} + +func (c *CCIPContracts) createExecOffchainConfig(t *testing.T, inflightCacheExpiry time.Duration, rootSnoozeTime time.Duration) []byte { + config, err := NewExecOffchainConfig( + 1, + 5_000_000, + 0.07, + *config.MustNewDuration(inflightCacheExpiry), + *config.MustNewDuration(rootSnoozeTime), + ).Encode() + require.NoError(t, err) + return config +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go new file mode 100644 index 0000000000..177ccf323b --- /dev/null +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go @@ -0,0 +1,1035 @@ +package integrationtesthelpers + +import ( + "context" + "encoding/hex" + "fmt" + "math/big" + "net/http" + "net/http/httptest" + "strconv" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + types3 "github.com/ethereum/go-ethereum/core/types" + "github.com/google/uuid" + "github.com/hashicorp/consul/sdk/freeport" + "github.com/jmoiron/sqlx" + "github.com/onsi/gomega" + "github.com/pkg/errors" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "k8s.io/utils/pointer" //nolint:staticcheck + + "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" + types4 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core/mocks" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + v2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + evmUtils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + configv2 "github.com/smartcontractkit/chainlink/v2/core/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/logger/audit" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + feeds2 "github.com/smartcontractkit/chainlink/v2/core/services/feeds" + feedsMocks "github.com/smartcontractkit/chainlink/v2/core/services/feeds/mocks" + pb "github.com/smartcontractkit/chainlink/v2/core/services/feeds/proto" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + ksMocks "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + clutils "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" + "github.com/smartcontractkit/chainlink/v2/plugins" +) + +const ( + execSpecTemplate = ` + type = "offchainreporting2" + schemaVersion = 1 + name = "ccip-exec-1" + externalJobID = "67ffad71-d90f-4fe3-b4e4-494924b707fb" + forwardingAllowed = false + maxTaskDuration = "0s" + contractID = "%s" + contractConfigConfirmations = 1 + contractConfigTrackerPollInterval = "20s" + ocrKeyBundleID = "%s" + relay = "evm" + pluginType = "ccip-execution" + transmitterID = "%s" + + [relayConfig] + chainID = 1_337 + + [pluginConfig] + destStartBlock = 50 + + [pluginConfig.USDCConfig] + AttestationAPI = "http://blah.com" + SourceMessageTransmitterAddress = "%s" + SourceTokenAddress = "%s" + AttestationAPITimeoutSeconds = 10 + ` + commitSpecTemplatePipeline = ` + type = "offchainreporting2" + schemaVersion = 1 + name = "ccip-commit-1" + externalJobID = "13c997cf-1a14-4ab7-9068-07ee6d2afa55" + forwardingAllowed = false + maxTaskDuration = "0s" + contractID = "%s" + contractConfigConfirmations = 1 + contractConfigTrackerPollInterval = "20s" + ocrKeyBundleID = "%s" + relay = "evm" + pluginType = "ccip-commit" + transmitterID = "%s" + + [relayConfig] + chainID = 1_337 + + [pluginConfig] + destStartBlock = 50 + offRamp = "%s" + tokenPricesUSDPipeline = """ + %s + """ + ` + commitSpecTemplateDynamicPriceGetter = ` + type = "offchainreporting2" + schemaVersion = 1 + name = "ccip-commit-1" + externalJobID = "13c997cf-1a14-4ab7-9068-07ee6d2afa55" + forwardingAllowed = false + maxTaskDuration = "0s" + contractID = "%s" + contractConfigConfirmations = 1 + contractConfigTrackerPollInterval = "20s" + ocrKeyBundleID = "%s" + relay = "evm" + pluginType = "ccip-commit" + transmitterID = "%s" + + [relayConfig] + chainID = 1_337 + + [pluginConfig] + destStartBlock = 50 + offRamp = "%s" + priceGetterConfig = """ + %s + """ + ` +) + +type Node struct { + App chainlink.Application + Transmitter common.Address + PaymentReceiver common.Address + KeyBundle ocr2key.KeyBundle +} + +func (node *Node) FindJobIDForContract(t *testing.T, addr common.Address) int32 { + jobs := node.App.JobSpawner().ActiveJobs() + for _, j := range jobs { + if j.Type == job.OffchainReporting2 && j.OCR2OracleSpec.ContractID == addr.Hex() { + return j.ID + } + } + t.Fatalf("Could not find job for contract %s", addr.Hex()) + return 0 +} + +func (node *Node) EventuallyNodeUsesUpdatedPriceRegistry(t *testing.T, ccipContracts CCIPIntegrationTestHarness) logpoller.Log { + c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) + require.NoError(t, err) + var log logpoller.Log + gomega.NewGomegaWithT(t).Eventually(func() bool { + ccipContracts.Source.Chain.Commit() + ccipContracts.Dest.Chain.Commit() + log, err := c.LogPoller().LatestLogByEventSigWithConfs( + testutils.Context(t), + v1_0_0.UsdPerUnitGasUpdated, + ccipContracts.Dest.PriceRegistry.Address(), + 0, + ) + // err can be transient errors such as sql row set empty + if err != nil { + return false + } + return log != nil + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "node is not using updated price registry %s", ccipContracts.Dest.PriceRegistry.Address().Hex()) + return log +} + +func (node *Node) EventuallyNodeUsesNewCommitConfig(t *testing.T, ccipContracts CCIPIntegrationTestHarness, commitCfg ccipdata.CommitOnchainConfig) logpoller.Log { + c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) + require.NoError(t, err) + var log logpoller.Log + gomega.NewGomegaWithT(t).Eventually(func() bool { + ccipContracts.Source.Chain.Commit() + ccipContracts.Dest.Chain.Commit() + log, err := c.LogPoller().LatestLogByEventSigWithConfs( + testutils.Context(t), + evmrelay.OCR2AggregatorLogDecoder.EventSig(), + ccipContracts.Dest.CommitStore.Address(), + 0, + ) + require.NoError(t, err) + var latestCfg ccipdata.CommitOnchainConfig + if log != nil { + latestCfg, err = DecodeCommitOnChainConfig(log.Data) + require.NoError(t, err) + return latestCfg == commitCfg + } + return false + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "node is using old cfg") + return log +} + +func (node *Node) EventuallyNodeUsesNewExecConfig(t *testing.T, ccipContracts CCIPIntegrationTestHarness, execCfg v1_5_0.ExecOnchainConfig) logpoller.Log { + c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) + require.NoError(t, err) + var log logpoller.Log + gomega.NewGomegaWithT(t).Eventually(func() bool { + ccipContracts.Source.Chain.Commit() + ccipContracts.Dest.Chain.Commit() + log, err := c.LogPoller().LatestLogByEventSigWithConfs( + testutils.Context(t), + evmrelay.OCR2AggregatorLogDecoder.EventSig(), + ccipContracts.Dest.OffRamp.Address(), + 0, + ) + require.NoError(t, err) + var latestCfg v1_5_0.ExecOnchainConfig + if log != nil { + latestCfg, err = DecodeExecOnChainConfig(log.Data) + require.NoError(t, err) + return latestCfg == execCfg + } + return false + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "node is using old cfg") + return log +} + +func (node *Node) EventuallyHasReqSeqNum(t *testing.T, ccipContracts *CCIPIntegrationTestHarness, onRamp common.Address, seqNum int) logpoller.Log { + c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Source.ChainID, 10)) + require.NoError(t, err) + var log logpoller.Log + gomega.NewGomegaWithT(t).Eventually(func() bool { + ccipContracts.Source.Chain.Commit() + ccipContracts.Dest.Chain.Commit() + lgs, err := c.LogPoller().LogsDataWordRange( + testutils.Context(t), + v1_2_0.CCIPSendRequestEventSig, + onRamp, + v1_2_0.CCIPSendRequestSeqNumIndex, + abihelpers.EvmWord(uint64(seqNum)), + abihelpers.EvmWord(uint64(seqNum)), + 1, + ) + require.NoError(t, err) + t.Log("Send requested", len(lgs)) + if len(lgs) == 1 { + log = lgs[0] + return true + } + return false + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "eventually has seq num") + return log +} + +func (node *Node) EventuallyHasExecutedSeqNums(t *testing.T, ccipContracts *CCIPIntegrationTestHarness, offRamp common.Address, minSeqNum int, maxSeqNum int) []logpoller.Log { + c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) + require.NoError(t, err) + var logs []logpoller.Log + gomega.NewGomegaWithT(t).Eventually(func() bool { + ccipContracts.Source.Chain.Commit() + ccipContracts.Dest.Chain.Commit() + lgs, err := c.LogPoller().IndexedLogsTopicRange( + testutils.Context(t), + v1_0_0.ExecutionStateChangedEvent, + offRamp, + v1_0_0.ExecutionStateChangedSeqNrIndex, + abihelpers.EvmWord(uint64(minSeqNum)), + abihelpers.EvmWord(uint64(maxSeqNum)), + 1, + ) + require.NoError(t, err) + t.Logf("Have executed logs %d want %d", len(lgs), maxSeqNum-minSeqNum+1) + if len(lgs) == maxSeqNum-minSeqNum+1 { + logs = lgs + t.Logf("Seq Num %d-%d executed", minSeqNum, maxSeqNum) + return true + } + return false + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "eventually has not executed seq num") + return logs +} + +func (node *Node) ConsistentlySeqNumHasNotBeenExecuted(t *testing.T, ccipContracts *CCIPIntegrationTestHarness, offRamp common.Address, seqNum int) logpoller.Log { + c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) + require.NoError(t, err) + var log logpoller.Log + gomega.NewGomegaWithT(t).Consistently(func() bool { + ccipContracts.Source.Chain.Commit() + ccipContracts.Dest.Chain.Commit() + lgs, err := c.LogPoller().IndexedLogsTopicRange( + testutils.Context(t), + v1_0_0.ExecutionStateChangedEvent, + offRamp, + v1_0_0.ExecutionStateChangedSeqNrIndex, + abihelpers.EvmWord(uint64(seqNum)), + abihelpers.EvmWord(uint64(seqNum)), + 1, + ) + require.NoError(t, err) + t.Log("Executed logs", lgs) + if len(lgs) == 1 { + log = lgs[0] + return true + } + return false + }, 10*time.Second, 1*time.Second).Should(gomega.BeFalse(), "seq number got executed") + return log +} + +func (node *Node) AddJob(t *testing.T, spec *OCR2TaskJobSpec) { + specString, err := spec.String() + require.NoError(t, err) + ccipJob, err := validate.ValidatedOracleSpecToml( + testutils.Context(t), + node.App.GetConfig().OCR2(), + node.App.GetConfig().Insecure(), + specString, + // FIXME Ani + nil, + ) + require.NoError(t, err) + err = node.App.AddJobV2(context.Background(), &ccipJob) + require.NoError(t, err) +} + +func (node *Node) AddBootstrapJob(t *testing.T, spec *OCR2TaskJobSpec) { + specString, err := spec.String() + require.NoError(t, err) + ccipJob, err := ocrbootstrap.ValidatedBootstrapSpecToml(specString) + require.NoError(t, err) + err = node.App.AddJobV2(context.Background(), &ccipJob) + require.NoError(t, err) +} + +func (node *Node) AddJobsWithSpec(t *testing.T, jobSpec *OCR2TaskJobSpec) { + // set node specific values + jobSpec.OCR2OracleSpec.OCRKeyBundleID.SetValid(node.KeyBundle.ID()) + jobSpec.OCR2OracleSpec.TransmitterID.SetValid(node.Transmitter.Hex()) + node.AddJob(t, jobSpec) +} + +func setupNodeCCIP( + t *testing.T, + owner *bind.TransactOpts, + port int64, + dbName string, + sourceChain *backends.SimulatedBackend, destChain *backends.SimulatedBackend, + sourceChainID *big.Int, destChainID *big.Int, + bootstrapPeerID string, + bootstrapPort int64, +) (chainlink.Application, string, common.Address, ocr2key.KeyBundle) { + trueRef, falseRef := true, false + + // Do not want to load fixtures as they contain a dummy chainID. + loglevel := configv2.LogLevel(zap.DebugLevel) + config, db := heavyweight.FullTestDBNoFixturesV2(t, func(c *chainlink.Config, _ *chainlink.Secrets) { + p2pAddresses := []string{ + fmt.Sprintf("127.0.0.1:%d", port), + } + c.Log.Level = &loglevel + c.Feature.UICSAKeys = &trueRef + c.Feature.FeedsManager = &trueRef + c.OCR.Enabled = &falseRef + c.OCR.DefaultTransactionQueueDepth = pointer.Uint32(200) + c.OCR2.Enabled = &trueRef + c.Feature.LogPoller = &trueRef + c.P2P.V2.Enabled = &trueRef + + dur, err := config.NewDuration(500 * time.Millisecond) + if err != nil { + panic(err) + } + c.P2P.V2.DeltaDial = &dur + + dur2, err := config.NewDuration(5 * time.Second) + if err != nil { + panic(err) + } + + c.P2P.V2.DeltaReconcile = &dur2 + c.P2P.V2.ListenAddresses = &p2pAddresses + c.P2P.V2.AnnounceAddresses = &p2pAddresses + + c.EVM = []*v2.EVMConfig{createConfigV2Chain(sourceChainID), createConfigV2Chain(destChainID)} + + if bootstrapPeerID != "" { + // Supply the bootstrap IP and port as a V2 peer address + c.P2P.V2.DefaultBootstrappers = &[]commontypes.BootstrapperLocator{ + { + PeerID: bootstrapPeerID, Addrs: []string{ + fmt.Sprintf("127.0.0.1:%d", bootstrapPort), + }, + }, + } + } + }) + + lggr := logger.TestLogger(t) + ctx := testutils.Context(t) + + // The in-memory geth sim does not let you create a custom ChainID, it will always be 1337. + // In particular this means that if you sign an eip155 tx, the chainID used MUST be 1337 + // and the CHAINID op code will always emit 1337. To work around this to simulate a "multichain" + // test, we fake different chainIDs using the wrapped sim cltest.SimulatedBackend so the RPC + // appears to operate on different chainIDs and we use an EthKeyStoreSim wrapper which always + // signs 1337 see https://github.com/smartcontractkit/chainlink-ccip/blob/a24dd436810250a458d27d8bb3fb78096afeb79c/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go#L35 + sourceClient := client.NewSimulatedBackendClient(t, sourceChain, sourceChainID) + destClient := client.NewSimulatedBackendClient(t, destChain, destChainID) + csaKeyStore := ksMocks.NewCSA(t) + + key, err := csakey.NewV2() + require.NoError(t, err) + csaKeyStore.On("GetAll").Return([]csakey.KeyV2{key}, nil) + keyStore := NewKsa(db, lggr, csaKeyStore) + + simEthKeyStore := testhelpers.EthKeyStoreSim{ + ETHKS: keyStore.Eth(), + CSAKS: keyStore.CSA(), + } + mailMon := mailbox.NewMonitor("CCIP", lggr.Named("Mailbox")) + evmOpts := chainlink.EVMFactoryConfig{ + ChainOpts: legacyevm.ChainOpts{ + AppConfig: config, + GenEthClient: func(chainID *big.Int) client.Client { + if chainID.String() == sourceChainID.String() { + return sourceClient + } else if chainID.String() == destChainID.String() { + return destClient + } + t.Fatalf("invalid chain ID %v", chainID.String()) + return nil + }, + MailMon: mailMon, + DS: db, + }, + CSAETHKeystore: simEthKeyStore, + } + loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing()) + relayerFactory := chainlink.RelayerFactory{ + Logger: lggr, + LoopRegistry: loopRegistry, + GRPCOpts: loop.GRPCOpts{}, + CapabilitiesRegistry: coretypes.NewCapabilitiesRegistry(t), + } + testCtx := testutils.Context(t) + // evm alway enabled for backward compatibility + initOps := []chainlink.CoreRelayerChainInitFunc{ + chainlink.InitEVM(testCtx, relayerFactory, evmOpts), + } + + relayChainInterops, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) + if err != nil { + t.Fatal(err) + } + + app, err := chainlink.NewApplication(chainlink.ApplicationOpts{ + Config: config, + DS: db, + KeyStore: keyStore, + RelayerChainInteroperators: relayChainInterops, + Logger: lggr, + ExternalInitiatorManager: nil, + CloseLogger: lggr.Sync, + UnrestrictedHTTPClient: &http.Client{}, + RestrictedHTTPClient: &http.Client{}, + AuditLogger: audit.NoopLogger, + MailMon: mailMon, + LoopRegistry: plugins.NewLoopRegistry(lggr, config.Tracing()), + }) + require.NoError(t, err) + require.NoError(t, app.GetKeyStore().Unlock(ctx, "password")) + _, err = app.GetKeyStore().P2P().Create(ctx) + require.NoError(t, err) + + p2pIDs, err := app.GetKeyStore().P2P().GetAll() + require.NoError(t, err) + require.Len(t, p2pIDs, 1) + peerID := p2pIDs[0].PeerID() + + _, err = app.GetKeyStore().Eth().Create(testCtx, destChainID) + require.NoError(t, err) + sendingKeys, err := app.GetKeyStore().Eth().EnabledKeysForChain(testCtx, destChainID) + require.NoError(t, err) + require.Len(t, sendingKeys, 1) + transmitter := sendingKeys[0].Address + s, err := app.GetKeyStore().Eth().GetState(testCtx, sendingKeys[0].ID(), destChainID) + require.NoError(t, err) + lggr.Debug(fmt.Sprintf("Transmitter address %s chainID %s", transmitter, s.EVMChainID.String())) + + // Fund the commitTransmitter address with some ETH + n, err := destChain.NonceAt(context.Background(), owner.From, nil) + require.NoError(t, err) + + tx := types3.NewTransaction(n, transmitter, big.NewInt(1000000000000000000), 21000, big.NewInt(1000000000), nil) + signedTx, err := owner.Signer(owner.From, tx) + require.NoError(t, err) + err = destChain.SendTransaction(context.Background(), signedTx) + require.NoError(t, err) + destChain.Commit() + + kb, err := app.GetKeyStore().OCR2().Create(ctx, chaintype.EVM) + require.NoError(t, err) + return app, peerID.Raw(), transmitter, kb +} + +func createConfigV2Chain(chainId *big.Int) *v2.EVMConfig { + // NOTE: For the executor jobs, the default of 500k is insufficient for a 3 message batch + defaultGasLimit := uint64(5000000) + tr := true + + sourceC := v2.Defaults((*evmUtils.Big)(chainId)) + sourceC.GasEstimator.LimitDefault = &defaultGasLimit + fixedPrice := "FixedPrice" + sourceC.GasEstimator.Mode = &fixedPrice + d, _ := config.NewDuration(100 * time.Millisecond) + sourceC.LogPollInterval = &d + fd := uint32(2) + sourceC.FinalityDepth = &fd + return &v2.EVMConfig{ + ChainID: (*evmUtils.Big)(chainId), + Enabled: &tr, + Chain: sourceC, + Nodes: v2.EVMNodes{&v2.Node{}}, + } +} + +type CCIPIntegrationTestHarness struct { + testhelpers.CCIPContracts + Nodes []Node + Bootstrap Node +} + +func SetupCCIPIntegrationTH(t *testing.T, sourceChainID, sourceChainSelector, destChainId, destChainSelector uint64) CCIPIntegrationTestHarness { + return CCIPIntegrationTestHarness{ + CCIPContracts: testhelpers.SetupCCIPContracts(t, sourceChainID, sourceChainSelector, destChainId, destChainSelector), + } +} + +func (c *CCIPIntegrationTestHarness) CreatePricesPipeline(t *testing.T) (string, *httptest.Server, *httptest.Server) { + linkUSD := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, err := w.Write([]byte(`{"UsdPerLink": "8000000000000000000"}`)) + require.NoError(t, err) + })) + t.Cleanup(linkUSD.Close) + + ethUSD := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, err := w.Write([]byte(`{"UsdPerETH": "1700000000000000000000"}`)) + require.NoError(t, err) + })) + t.Cleanup(ethUSD.Close) + + sourceWrappedNative, err := c.Source.Router.GetWrappedNative(nil) + require.NoError(t, err) + destWrappedNative, err := c.Dest.Router.GetWrappedNative(nil) + require.NoError(t, err) + tokenPricesUSDPipeline := fmt.Sprintf(` +// Price 1 +link [type=http method=GET url="%s"]; +link_parse [type=jsonparse path="UsdPerLink"]; +link->link_parse; +eth [type=http method=GET url="%s"]; +eth_parse [type=jsonparse path="UsdPerETH"]; +eth->eth_parse; +merge [type=merge left="{}" right="{\\\"%s\\\":$(link_parse), \\\"%s\\\":$(eth_parse), \\\"%s\\\":$(eth_parse)}"];`, + linkUSD.URL, ethUSD.URL, c.Dest.LinkToken.Address(), sourceWrappedNative, destWrappedNative) + + return tokenPricesUSDPipeline, linkUSD, ethUSD +} + +func (c *CCIPIntegrationTestHarness) AddAllJobs(t *testing.T, jobParams CCIPJobSpecParams) { + jobParams.OffRamp = c.Dest.OffRamp.Address() + + commitSpec, err := jobParams.CommitJobSpec() + require.NoError(t, err) + geExecutionSpec, err := jobParams.ExecutionJobSpec() + require.NoError(t, err) + nodes := c.Nodes + for _, node := range nodes { + node.AddJobsWithSpec(t, commitSpec) + node.AddJobsWithSpec(t, geExecutionSpec) + } +} + +func (c *CCIPIntegrationTestHarness) jobSpecProposal(t *testing.T, specTemplate string, f func() (*OCR2TaskJobSpec, error), feedsManagerId int64, version int32, opts ...any) feeds2.ProposeJobArgs { + spec, err := f() + require.NoError(t, err) + + args := []any{spec.OCR2OracleSpec.ContractID} + args = append(args, opts...) + + return feeds2.ProposeJobArgs{ + FeedsManagerID: feedsManagerId, + RemoteUUID: uuid.New(), + Multiaddrs: nil, + Version: version, + Spec: fmt.Sprintf(specTemplate, args...), + } +} + +func (c *CCIPIntegrationTestHarness) SetupFeedsManager(t *testing.T) { + ctx := testutils.Context(t) + for _, node := range c.Nodes { + f := node.App.GetFeedsService() + + managers, err := f.ListManagers(ctx) + require.NoError(t, err) + if len(managers) > 0 { + // Use at most one feeds manager, don't register if one already exists + continue + } + + secret := utils.RandomBytes32() + pkey, err := crypto.PublicKeyFromHex(hex.EncodeToString(secret[:])) + require.NoError(t, err) + + m := feeds2.RegisterManagerParams{ + Name: "CCIP", + URI: "http://localhost:8080", + PublicKey: *pkey, + } + + connManager := feedsMocks.NewConnectionsManager(t) + connManager.On("Connect", mock.Anything).Maybe() + connManager.On("GetClient", mock.Anything).Maybe().Return(NoopFeedsClient{}, nil) + connManager.On("Close").Maybe().Return() + connManager.On("IsConnected", mock.Anything).Maybe().Return(true) + f.Unsafe_SetConnectionsManager(connManager) + + _, err = f.RegisterManager(testutils.Context(t), m) + require.NoError(t, err) + } +} + +func (c *CCIPIntegrationTestHarness) ApproveJobSpecs(t *testing.T, jobParams CCIPJobSpecParams) { + ctx := testutils.Context(t) + + for _, node := range c.Nodes { + f := node.App.GetFeedsService() + managers, err := f.ListManagers(ctx) + require.NoError(t, err) + require.Len(t, managers, 1, "expected exactly one feeds manager") + + execSpec := c.jobSpecProposal( + t, + execSpecTemplate, + jobParams.ExecutionJobSpec, + managers[0].ID, + 1, + node.KeyBundle.ID(), + node.Transmitter.Hex(), + utils.RandomAddress().String(), + utils.RandomAddress().String(), + ) + execId, err := f.ProposeJob(ctx, &execSpec) + require.NoError(t, err) + + err = f.ApproveSpec(ctx, execId, true) + require.NoError(t, err) + + var commitSpec feeds2.ProposeJobArgs + if jobParams.TokenPricesUSDPipeline != "" { + commitSpec = c.jobSpecProposal( + t, + commitSpecTemplatePipeline, + jobParams.CommitJobSpec, + managers[0].ID, + 2, + node.KeyBundle.ID(), + node.Transmitter.Hex(), + jobParams.OffRamp.String(), + jobParams.TokenPricesUSDPipeline, + ) + } else { + commitSpec = c.jobSpecProposal( + t, + commitSpecTemplateDynamicPriceGetter, + jobParams.CommitJobSpec, + managers[0].ID, + 2, + node.KeyBundle.ID(), + node.Transmitter.Hex(), + jobParams.OffRamp.String(), + jobParams.PriceGetterConfig, + ) + } + + commitId, err := f.ProposeJob(ctx, &commitSpec) + require.NoError(t, err) + + err = f.ApproveSpec(ctx, commitId, true) + require.NoError(t, err) + } +} + +func (c *CCIPIntegrationTestHarness) AllNodesHaveReqSeqNum(t *testing.T, seqNum int, onRampOpts ...common.Address) logpoller.Log { + var log logpoller.Log + nodes := c.Nodes + var onRamp common.Address + if len(onRampOpts) > 0 { + onRamp = onRampOpts[0] + } else { + require.NotNil(t, c.Source.OnRamp, "no onramp configured") + onRamp = c.Source.OnRamp.Address() + } + for _, node := range nodes { + log = node.EventuallyHasReqSeqNum(t, c, onRamp, seqNum) + } + return log +} + +func (c *CCIPIntegrationTestHarness) AllNodesHaveExecutedSeqNums(t *testing.T, minSeqNum int, maxSeqNum int, offRampOpts ...common.Address) []logpoller.Log { + var logs []logpoller.Log + nodes := c.Nodes + var offRamp common.Address + + if len(offRampOpts) > 0 { + offRamp = offRampOpts[0] + } else { + require.NotNil(t, c.Dest.OffRamp, "no offramp configured") + offRamp = c.Dest.OffRamp.Address() + } + for _, node := range nodes { + logs = node.EventuallyHasExecutedSeqNums(t, c, offRamp, minSeqNum, maxSeqNum) + } + return logs +} + +func (c *CCIPIntegrationTestHarness) NoNodesHaveExecutedSeqNum(t *testing.T, seqNum int, offRampOpts ...common.Address) logpoller.Log { + var log logpoller.Log + nodes := c.Nodes + var offRamp common.Address + if len(offRampOpts) > 0 { + offRamp = offRampOpts[0] + } else { + require.NotNil(t, c.Dest.OffRamp, "no offramp configured") + offRamp = c.Dest.OffRamp.Address() + } + for _, node := range nodes { + log = node.ConsistentlySeqNumHasNotBeenExecuted(t, c, offRamp, seqNum) + } + return log +} + +func (c *CCIPIntegrationTestHarness) EventuallyCommitReportAccepted(t *testing.T, currentBlock uint64, commitStoreOpts ...common.Address) commit_store.CommitStoreCommitReport { + var commitStore *commit_store.CommitStore + var err error + if len(commitStoreOpts) > 0 { + commitStore, err = commit_store.NewCommitStore(commitStoreOpts[0], c.Dest.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Dest.CommitStore, "no commitStore configured") + commitStore = c.Dest.CommitStore + } + g := gomega.NewGomegaWithT(t) + var report commit_store.CommitStoreCommitReport + g.Eventually(func() bool { + it, err := commitStore.FilterReportAccepted(&bind.FilterOpts{Start: currentBlock}) + g.Expect(err).NotTo(gomega.HaveOccurred(), "Error filtering ReportAccepted event") + g.Expect(it.Next()).To(gomega.BeTrue(), "No ReportAccepted event found") + report = it.Event.Report + if report.MerkleRoot != [32]byte{} { + t.Log("Report Accepted by commitStore") + return true + } + return false + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "report has not been committed") + return report +} + +func (c *CCIPIntegrationTestHarness) EventuallyExecutionStateChangedToSuccess(t *testing.T, seqNum []uint64, blockNum uint64, offRampOpts ...common.Address) { + var offRamp *evm_2_evm_offramp.EVM2EVMOffRamp + var err error + if len(offRampOpts) > 0 { + offRamp, err = evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampOpts[0], c.Dest.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Dest.OffRamp, "no offRamp configured") + offRamp = c.Dest.OffRamp + } + gomega.NewGomegaWithT(t).Eventually(func() bool { + it, err := offRamp.FilterExecutionStateChanged(&bind.FilterOpts{Start: blockNum}, seqNum, [][32]byte{}) + require.NoError(t, err) + for it.Next() { + if cciptypes.MessageExecutionState(it.Event.State) == cciptypes.ExecutionStateSuccess { + t.Logf("ExecutionStateChanged event found for seqNum %d", it.Event.SequenceNumber) + return true + } + } + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + return false + }, testutils.WaitTimeout(t), time.Second). + Should(gomega.BeTrue(), "ExecutionStateChanged Event") +} + +func (c *CCIPIntegrationTestHarness) EventuallyReportCommitted(t *testing.T, max int, commitStoreOpts ...common.Address) uint64 { + var commitStore *commit_store.CommitStore + var err error + var committedSeqNum uint64 + if len(commitStoreOpts) > 0 { + commitStore, err = commit_store.NewCommitStore(commitStoreOpts[0], c.Dest.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Dest.CommitStore, "no commitStore configured") + commitStore = c.Dest.CommitStore + } + gomega.NewGomegaWithT(t).Eventually(func() bool { + minSeqNum, err := commitStore.GetExpectedNextSequenceNumber(nil) + require.NoError(t, err) + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + t.Log("next expected seq num reported", minSeqNum) + committedSeqNum = minSeqNum + return minSeqNum > uint64(max) + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue(), "report has not been committed") + return committedSeqNum +} + +func (c *CCIPIntegrationTestHarness) EventuallySendRequested(t *testing.T, seqNum uint64, onRampOpts ...common.Address) { + var onRamp *evm_2_evm_onramp.EVM2EVMOnRamp + var err error + if len(onRampOpts) > 0 { + onRamp, err = evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampOpts[0], c.Source.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Source.OnRamp, "no onRamp configured") + onRamp = c.Source.OnRamp + } + gomega.NewGomegaWithT(t).Eventually(func() bool { + it, err := onRamp.FilterCCIPSendRequested(nil) + require.NoError(t, err) + for it.Next() { + if it.Event.Message.SequenceNumber == seqNum { + t.Log("sendRequested generated for", seqNum) + return true + } + } + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + return false + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue(), "sendRequested has not been generated") +} + +func (c *CCIPIntegrationTestHarness) ConsistentlyReportNotCommitted(t *testing.T, max int, commitStoreOpts ...common.Address) { + var commitStore *commit_store.CommitStore + var err error + if len(commitStoreOpts) > 0 { + commitStore, err = commit_store.NewCommitStore(commitStoreOpts[0], c.Dest.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Dest.CommitStore, "no commitStore configured") + commitStore = c.Dest.CommitStore + } + gomega.NewGomegaWithT(t).Consistently(func() bool { + minSeqNum, err := commitStore.GetExpectedNextSequenceNumber(nil) + require.NoError(t, err) + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + t.Log("min seq num reported", minSeqNum) + return minSeqNum > uint64(max) + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeFalse(), "report has been committed") +} + +func (c *CCIPIntegrationTestHarness) SetupAndStartNodes(ctx context.Context, t *testing.T, bootstrapNodePort int64) (Node, []Node, int64) { + appBootstrap, bootstrapPeerID, bootstrapTransmitter, bootstrapKb := setupNodeCCIP(t, c.Dest.User, bootstrapNodePort, + "bootstrap_ccip", c.Source.Chain, c.Dest.Chain, big.NewInt(0).SetUint64(c.Source.ChainID), + big.NewInt(0).SetUint64(c.Dest.ChainID), "", 0) + var ( + oracles []confighelper.OracleIdentityExtra + nodes []Node + ) + err := appBootstrap.Start(ctx) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, appBootstrap.Stop()) + }) + bootstrapNode := Node{ + App: appBootstrap, + Transmitter: bootstrapTransmitter, + KeyBundle: bootstrapKb, + } + // Set up the minimum 4 oracles all funded with destination ETH + for i := int64(0); i < 4; i++ { + app, peerID, transmitter, kb := setupNodeCCIP( + t, + c.Dest.User, + int64(freeport.GetOne(t)), + fmt.Sprintf("oracle_ccip%d", i), + c.Source.Chain, + c.Dest.Chain, + big.NewInt(0).SetUint64(c.Source.ChainID), + big.NewInt(0).SetUint64(c.Dest.ChainID), + bootstrapPeerID, + bootstrapNodePort, + ) + nodes = append(nodes, Node{ + App: app, + Transmitter: transmitter, + KeyBundle: kb, + }) + offchainPublicKey, _ := hex.DecodeString(strings.TrimPrefix(kb.OnChainPublicKey(), "0x")) + oracles = append(oracles, confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: offchainPublicKey, + TransmitAccount: types4.Account(transmitter.String()), + OffchainPublicKey: kb.OffchainPublicKey(), + PeerID: peerID, + }, + ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), + }) + err = app.Start(ctx) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, app.Stop()) + }) + } + + c.Oracles = oracles + commitOnchainConfig := c.CreateDefaultCommitOnchainConfig(t) + commitOffchainConfig := c.CreateDefaultCommitOffchainConfig(t) + execOnchainConfig := c.CreateDefaultExecOnchainConfig(t) + execOffchainConfig := c.CreateDefaultExecOffchainConfig(t) + + configBlock := c.SetupOnchainConfig(t, commitOnchainConfig, commitOffchainConfig, execOnchainConfig, execOffchainConfig) + c.Nodes = nodes + c.Bootstrap = bootstrapNode + return bootstrapNode, nodes, configBlock +} + +func (c *CCIPIntegrationTestHarness) SetUpNodesAndJobs(t *testing.T, pricePipeline string, priceGetterConfig string, usdcAttestationAPI string) CCIPJobSpecParams { + // setup Jobs + ctx := context.Background() + // Starts nodes and configures them in the OCR contracts. + bootstrapNode, _, configBlock := c.SetupAndStartNodes(ctx, t, int64(freeport.GetOne(t))) + + jobParams := c.NewCCIPJobSpecParams(pricePipeline, priceGetterConfig, configBlock, usdcAttestationAPI) + + // Add the bootstrap job + c.Bootstrap.AddBootstrapJob(t, jobParams.BootstrapJob(c.Dest.CommitStore.Address().Hex())) + c.AddAllJobs(t, jobParams) + + // Replay for bootstrap. + bc, err := bootstrapNode.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(c.Dest.ChainID, 10)) + require.NoError(t, err) + require.NoError(t, bc.LogPoller().Replay(context.Background(), configBlock)) + c.Dest.Chain.Commit() + + return jobParams +} +func DecodeCommitOnChainConfig(encoded []byte) (ccipdata.CommitOnchainConfig, error) { + var onchainConfig ccipdata.CommitOnchainConfig + unpacked, err := abihelpers.DecodeOCR2Config(encoded) + if err != nil { + return onchainConfig, err + } + onChainCfg := unpacked.OnchainConfig + onchainConfig, err = abihelpers.DecodeAbiStruct[ccipdata.CommitOnchainConfig](onChainCfg) + if err != nil { + return onchainConfig, err + } + return onchainConfig, nil +} + +func DecodeExecOnChainConfig(encoded []byte) (v1_5_0.ExecOnchainConfig, error) { + var onchainConfig v1_5_0.ExecOnchainConfig + unpacked, err := abihelpers.DecodeOCR2Config(encoded) + if err != nil { + return onchainConfig, errors.Wrap(err, "failed to unpack log data") + } + onChainCfg := unpacked.OnchainConfig + onchainConfig, err = abihelpers.DecodeAbiStruct[v1_5_0.ExecOnchainConfig](onChainCfg) + if err != nil { + return onchainConfig, err + } + return onchainConfig, nil +} + +type ksa struct { + keystore.Master + csa keystore.CSA +} + +func (k *ksa) CSA() keystore.CSA { + return k.csa +} + +func NewKsa(db *sqlx.DB, lggr logger.Logger, csa keystore.CSA) *ksa { + return &ksa{ + Master: keystore.New(db, clutils.FastScryptParams, lggr), + csa: csa, + } +} + +type NoopFeedsClient struct{} + +func (n NoopFeedsClient) ApprovedJob(context.Context, *pb.ApprovedJobRequest) (*pb.ApprovedJobResponse, error) { + return &pb.ApprovedJobResponse{}, nil +} + +func (n NoopFeedsClient) Healthcheck(context.Context, *pb.HealthcheckRequest) (*pb.HealthcheckResponse, error) { + return &pb.HealthcheckResponse{}, nil +} + +func (n NoopFeedsClient) UpdateNode(context.Context, *pb.UpdateNodeRequest) (*pb.UpdateNodeResponse, error) { + return &pb.UpdateNodeResponse{}, nil +} + +func (n NoopFeedsClient) RejectedJob(context.Context, *pb.RejectedJobRequest) (*pb.RejectedJobResponse, error) { + return &pb.RejectedJobResponse{}, nil +} + +func (n NoopFeedsClient) CancelledJob(context.Context, *pb.CancelledJobRequest) (*pb.CancelledJobResponse, error) { + return &pb.CancelledJobResponse{}, nil +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/jobspec.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/jobspec.go new file mode 100644 index 0000000000..961e26d1ce --- /dev/null +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/jobspec.go @@ -0,0 +1,334 @@ +package integrationtesthelpers + +import ( + "bytes" + "fmt" + "text/template" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/lib/pq" + + "github.com/smartcontractkit/chainlink-common/pkg/types" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" + "github.com/smartcontractkit/chainlink/v2/core/store/models" +) + +// OCR2TaskJobSpec represents an OCR2 job that is given to other nodes, meant to communicate with the bootstrap node, +// and provide their answers +type OCR2TaskJobSpec struct { + Name string `toml:"name"` + JobType string `toml:"type"` + MaxTaskDuration string `toml:"maxTaskDuration"` // Optional + ForwardingAllowed bool `toml:"forwardingAllowed"` + OCR2OracleSpec job.OCR2OracleSpec + ObservationSource string `toml:"observationSource"` // List of commands for the Chainlink node +} + +// Type returns the type of the job +func (o *OCR2TaskJobSpec) Type() string { return o.JobType } + +// String representation of the job +func (o *OCR2TaskJobSpec) String() (string, error) { + var feedID string + if o.OCR2OracleSpec.FeedID != nil { + feedID = o.OCR2OracleSpec.FeedID.Hex() + } + specWrap := struct { + Name string + JobType string + MaxTaskDuration string + ForwardingAllowed bool + ContractID string + FeedID string + Relay string + PluginType string + RelayConfig map[string]interface{} + PluginConfig map[string]interface{} + P2PV2Bootstrappers []string + OCRKeyBundleID string + MonitoringEndpoint string + TransmitterID string + BlockchainTimeout time.Duration + TrackerSubscribeInterval time.Duration + TrackerPollInterval time.Duration + ContractConfirmations uint16 + ObservationSource string + }{ + Name: o.Name, + JobType: o.JobType, + ForwardingAllowed: o.ForwardingAllowed, + MaxTaskDuration: o.MaxTaskDuration, + ContractID: o.OCR2OracleSpec.ContractID, + FeedID: feedID, + Relay: o.OCR2OracleSpec.Relay, + PluginType: string(o.OCR2OracleSpec.PluginType), + RelayConfig: o.OCR2OracleSpec.RelayConfig, + PluginConfig: o.OCR2OracleSpec.PluginConfig, + P2PV2Bootstrappers: o.OCR2OracleSpec.P2PV2Bootstrappers, + OCRKeyBundleID: o.OCR2OracleSpec.OCRKeyBundleID.String, + MonitoringEndpoint: o.OCR2OracleSpec.MonitoringEndpoint.String, + TransmitterID: o.OCR2OracleSpec.TransmitterID.String, + BlockchainTimeout: o.OCR2OracleSpec.BlockchainTimeout.Duration(), + ContractConfirmations: o.OCR2OracleSpec.ContractConfigConfirmations, + TrackerPollInterval: o.OCR2OracleSpec.ContractConfigTrackerPollInterval.Duration(), + ObservationSource: o.ObservationSource, + } + ocr2TemplateString := ` +type = "{{ .JobType }}" +name = "{{.Name}}" +forwardingAllowed = {{.ForwardingAllowed}} +{{if .MaxTaskDuration}} +maxTaskDuration = "{{ .MaxTaskDuration }}" {{end}} +{{if .PluginType}} +pluginType = "{{ .PluginType }}" {{end}} +relay = "{{.Relay}}" +schemaVersion = 1 +contractID = "{{.ContractID}}" +{{if .FeedID}} +feedID = "{{.FeedID}}" +{{end}} +{{if eq .JobType "offchainreporting2" }} +ocrKeyBundleID = "{{.OCRKeyBundleID}}" {{end}} +{{if eq .JobType "offchainreporting2" }} +transmitterID = "{{.TransmitterID}}" {{end}} +{{if .BlockchainTimeout}} +blockchainTimeout = "{{.BlockchainTimeout}}" +{{end}} +{{if .ContractConfirmations}} +contractConfigConfirmations = {{.ContractConfirmations}} +{{end}} +{{if .TrackerPollInterval}} +contractConfigTrackerPollInterval = "{{.TrackerPollInterval}}" +{{end}} +{{if .TrackerSubscribeInterval}} +contractConfigTrackerSubscribeInterval = "{{.TrackerSubscribeInterval}}" +{{end}} +{{if .P2PV2Bootstrappers}} +p2pv2Bootstrappers = [{{range .P2PV2Bootstrappers}}"{{.}}",{{end}}]{{end}} +{{if .MonitoringEndpoint}} +monitoringEndpoint = "{{.MonitoringEndpoint}}" {{end}} +{{if .ObservationSource}} +observationSource = """ +{{.ObservationSource}} +"""{{end}} +{{if eq .JobType "offchainreporting2" }} +[pluginConfig]{{range $key, $value := .PluginConfig}} +{{$key}} = {{$value}}{{end}} +{{end}} +[relayConfig]{{range $key, $value := .RelayConfig}} +{{$key}} = {{$value}}{{end}} +` + return MarshallTemplate(specWrap, "OCR2 Job", ocr2TemplateString) +} + +// MarshallTemplate Helper to marshall templates +func MarshallTemplate(jobSpec interface{}, name, templateString string) (string, error) { + var buf bytes.Buffer + tmpl, err := template.New(name).Parse(templateString) + if err != nil { + return "", err + } + err = tmpl.Execute(&buf, jobSpec) + if err != nil { + return "", err + } + return buf.String(), err +} + +type JobType string + +const ( + Commit JobType = "commit" + Execution JobType = "exec" + Boostrap JobType = "bootstrap" +) + +func JobName(jobType JobType, source string, destination, version string) string { + if version != "" { + return fmt.Sprintf("ccip-%s-%s-%s-%s", jobType, source, destination, version) + } + return fmt.Sprintf("ccip-%s-%s-%s", jobType, source, destination) +} + +type CCIPJobSpecParams struct { + Name string + Version string + OffRamp common.Address + CommitStore common.Address + SourceChainName string + DestChainName string + DestEvmChainId uint64 + TokenPricesUSDPipeline string + PriceGetterConfig string + SourceStartBlock uint64 + DestStartBlock uint64 + USDCAttestationAPI string + USDCConfig *config.USDCConfig + P2PV2Bootstrappers pq.StringArray +} + +func (params CCIPJobSpecParams) Validate() error { + if params.CommitStore == common.HexToAddress("0x0") { + return fmt.Errorf("must set commit store address") + } + return nil +} + +func (params CCIPJobSpecParams) ValidateCommitJobSpec() error { + commonErr := params.Validate() + if commonErr != nil { + return commonErr + } + if params.OffRamp == common.HexToAddress("0x0") { + return fmt.Errorf("OffRamp cannot be empty for execution job") + } + // Validate token prices config + // NB: only validate the dynamic price getter config if present since we could also be using the pipeline instead. + // NB: make this test mandatory once we switch to dynamic price getter only. + if params.PriceGetterConfig != "" { + if _, err := pricegetter.NewDynamicPriceGetterConfig(params.PriceGetterConfig); err != nil { + return fmt.Errorf("invalid price getter config: %w", err) + } + } + return nil +} + +func (params CCIPJobSpecParams) ValidateExecJobSpec() error { + commonErr := params.Validate() + if commonErr != nil { + return commonErr + } + if params.OffRamp == common.HexToAddress("0x0") { + return fmt.Errorf("OffRamp cannot be empty for execution job") + } + return nil +} + +// CommitJobSpec generates template for CCIP-relay job spec. +// OCRKeyBundleID,TransmitterID need to be set from the calling function +func (params CCIPJobSpecParams) CommitJobSpec() (*OCR2TaskJobSpec, error) { + err := params.ValidateCommitJobSpec() + if err != nil { + return nil, fmt.Errorf("invalid job spec params: %w", err) + } + + pluginConfig := map[string]interface{}{ + "offRamp": fmt.Sprintf(`"%s"`, params.OffRamp.Hex()), + } + if params.TokenPricesUSDPipeline != "" { + pluginConfig["tokenPricesUSDPipeline"] = fmt.Sprintf(`""" +%s +"""`, params.TokenPricesUSDPipeline) + } + if params.PriceGetterConfig != "" { + pluginConfig["priceGetterConfig"] = fmt.Sprintf(`""" +%s +"""`, params.PriceGetterConfig) + } + + ocrSpec := job.OCR2OracleSpec{ + Relay: relay.NetworkEVM, + PluginType: types.CCIPCommit, + ContractID: params.CommitStore.Hex(), + ContractConfigConfirmations: 1, + ContractConfigTrackerPollInterval: models.Interval(20 * time.Second), + P2PV2Bootstrappers: params.P2PV2Bootstrappers, + PluginConfig: pluginConfig, + RelayConfig: map[string]interface{}{ + "chainID": params.DestEvmChainId, + }, + } + if params.DestStartBlock > 0 { + ocrSpec.PluginConfig["destStartBlock"] = params.DestStartBlock + } + if params.SourceStartBlock > 0 { + ocrSpec.PluginConfig["sourceStartBlock"] = params.SourceStartBlock + } + return &OCR2TaskJobSpec{ + OCR2OracleSpec: ocrSpec, + JobType: "offchainreporting2", + Name: JobName(Commit, params.SourceChainName, params.DestChainName, params.Version), + }, nil +} + +// ExecutionJobSpec generates template for CCIP-execution job spec. +// OCRKeyBundleID,TransmitterID need to be set from the calling function +func (params CCIPJobSpecParams) ExecutionJobSpec() (*OCR2TaskJobSpec, error) { + err := params.ValidateExecJobSpec() + if err != nil { + return nil, err + } + ocrSpec := job.OCR2OracleSpec{ + Relay: relay.NetworkEVM, + PluginType: types.CCIPExecution, + ContractID: params.OffRamp.Hex(), + ContractConfigConfirmations: 1, + ContractConfigTrackerPollInterval: models.Interval(20 * time.Second), + + P2PV2Bootstrappers: params.P2PV2Bootstrappers, + PluginConfig: map[string]interface{}{}, + RelayConfig: map[string]interface{}{ + "chainID": params.DestEvmChainId, + }, + } + if params.DestStartBlock > 0 { + ocrSpec.PluginConfig["destStartBlock"] = params.DestStartBlock + } + if params.SourceStartBlock > 0 { + ocrSpec.PluginConfig["sourceStartBlock"] = params.SourceStartBlock + } + if params.USDCAttestationAPI != "" { + ocrSpec.PluginConfig["USDCConfig.AttestationAPI"] = fmt.Sprintf("\"%s\"", params.USDCAttestationAPI) + ocrSpec.PluginConfig["USDCConfig.SourceTokenAddress"] = fmt.Sprintf("\"%s\"", utils.RandomAddress().String()) + ocrSpec.PluginConfig["USDCConfig.SourceMessageTransmitterAddress"] = fmt.Sprintf("\"%s\"", utils.RandomAddress().String()) + ocrSpec.PluginConfig["USDCConfig.AttestationAPITimeoutSeconds"] = 5 + } + if params.USDCConfig != nil { + ocrSpec.PluginConfig["USDCConfig.AttestationAPI"] = fmt.Sprintf(`"%s"`, params.USDCConfig.AttestationAPI) + ocrSpec.PluginConfig["USDCConfig.SourceTokenAddress"] = fmt.Sprintf(`"%s"`, params.USDCConfig.SourceTokenAddress) + ocrSpec.PluginConfig["USDCConfig.SourceMessageTransmitterAddress"] = fmt.Sprintf(`"%s"`, params.USDCConfig.SourceMessageTransmitterAddress) + ocrSpec.PluginConfig["USDCConfig.AttestationAPITimeoutSeconds"] = params.USDCConfig.AttestationAPITimeoutSeconds + } + return &OCR2TaskJobSpec{ + OCR2OracleSpec: ocrSpec, + JobType: "offchainreporting2", + Name: JobName(Execution, params.SourceChainName, params.DestChainName, params.Version), + }, err +} + +func (params CCIPJobSpecParams) BootstrapJob(contractID string) *OCR2TaskJobSpec { + bootstrapSpec := job.OCR2OracleSpec{ + ContractID: contractID, + Relay: relay.NetworkEVM, + ContractConfigConfirmations: 1, + ContractConfigTrackerPollInterval: models.Interval(20 * time.Second), + RelayConfig: map[string]interface{}{ + "chainID": params.DestEvmChainId, + }, + } + return &OCR2TaskJobSpec{ + Name: fmt.Sprintf("%s-%s", Boostrap, params.DestChainName), + JobType: "bootstrap", + OCR2OracleSpec: bootstrapSpec, + } +} + +func (c *CCIPIntegrationTestHarness) NewCCIPJobSpecParams(tokenPricesUSDPipeline string, priceGetterConfig string, configBlock int64, usdcAttestationAPI string) CCIPJobSpecParams { + return CCIPJobSpecParams{ + CommitStore: c.Dest.CommitStore.Address(), + OffRamp: c.Dest.OffRamp.Address(), + DestEvmChainId: c.Dest.ChainID, + SourceChainName: "SimulatedSource", + DestChainName: "SimulatedDest", + TokenPricesUSDPipeline: tokenPricesUSDPipeline, + PriceGetterConfig: priceGetterConfig, + DestStartBlock: uint64(configBlock), + USDCAttestationAPI: usdcAttestationAPI, + } +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/offramp.go b/core/services/ocr2/plugins/ccip/testhelpers/offramp.go new file mode 100644 index 0000000000..d10e693325 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/testhelpers/offramp.go @@ -0,0 +1,119 @@ +package testhelpers + +import ( + "sync" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + mock_contracts "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +type FakeOffRamp struct { + *mock_contracts.EVM2EVMOffRampInterface + + rateLimiterState cciptypes.TokenBucketRateLimit + senderNonces map[common.Address]uint64 + tokenToPool map[common.Address]common.Address + dynamicConfig evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig + sourceToDestTokens map[common.Address]common.Address + + mu sync.RWMutex +} + +func NewFakeOffRamp(t *testing.T) (*FakeOffRamp, common.Address) { + addr := utils.RandomAddress() + mockOffRamp := mock_contracts.NewEVM2EVMOffRampInterface(t) + mockOffRamp.On("Address").Return(addr).Maybe() + + offRamp := &FakeOffRamp{EVM2EVMOffRampInterface: mockOffRamp} + return offRamp, addr +} + +func (o *FakeOffRamp) CurrentRateLimiterState(opts *bind.CallOpts) (cciptypes.TokenBucketRateLimit, error) { + return getOffRampVal(o, func(o *FakeOffRamp) (cciptypes.TokenBucketRateLimit, error) { return o.rateLimiterState, nil }) +} + +func (o *FakeOffRamp) SetRateLimiterState(state cciptypes.TokenBucketRateLimit) { + setOffRampVal(o, func(o *FakeOffRamp) { o.rateLimiterState = state }) +} + +func (o *FakeOffRamp) GetSenderNonce(opts *bind.CallOpts, sender common.Address) (uint64, error) { + return getOffRampVal(o, func(o *FakeOffRamp) (uint64, error) { return o.senderNonces[sender], nil }) +} + +func (o *FakeOffRamp) SetSenderNonces(senderNonces map[cciptypes.Address]uint64) { + evmSenderNonces := make(map[common.Address]uint64) + for k, v := range senderNonces { + addrs, _ := ccipcalc.GenericAddrsToEvm(k) + evmSenderNonces[addrs[0]] = v + } + + setOffRampVal(o, func(o *FakeOffRamp) { o.senderNonces = evmSenderNonces }) +} + +func (o *FakeOffRamp) GetPoolByDestToken(opts *bind.CallOpts, destToken common.Address) (common.Address, error) { + return getOffRampVal(o, func(o *FakeOffRamp) (common.Address, error) { + addr, exists := o.tokenToPool[destToken] + if !exists { + return common.Address{}, errors.New("not found") + } + return addr, nil + }) +} + +func (o *FakeOffRamp) SetTokenPools(tokenToPool map[common.Address]common.Address) { + setOffRampVal(o, func(o *FakeOffRamp) { o.tokenToPool = tokenToPool }) +} + +func (o *FakeOffRamp) GetDynamicConfig(opts *bind.CallOpts) (evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig, error) { + return getOffRampVal(o, func(o *FakeOffRamp) (evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig, error) { + return o.dynamicConfig, nil + }) +} + +func (o *FakeOffRamp) SetDynamicConfig(cfg evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig) { + setOffRampVal(o, func(o *FakeOffRamp) { o.dynamicConfig = cfg }) +} + +func (o *FakeOffRamp) SetSourceToDestTokens(m map[common.Address]common.Address) { + setOffRampVal(o, func(o *FakeOffRamp) { o.sourceToDestTokens = m }) +} + +func (o *FakeOffRamp) GetSupportedTokens(opts *bind.CallOpts) ([]common.Address, error) { + return getOffRampVal(o, func(o *FakeOffRamp) ([]common.Address, error) { + tks := make([]common.Address, 0, len(o.sourceToDestTokens)) + for tk := range o.sourceToDestTokens { + tks = append(tks, tk) + } + return tks, nil + }) +} + +func (o *FakeOffRamp) GetDestinationTokens(opts *bind.CallOpts) ([]common.Address, error) { + return getOffRampVal(o, func(o *FakeOffRamp) ([]common.Address, error) { + tokens := make([]common.Address, 0, len(o.sourceToDestTokens)) + for _, dst := range o.sourceToDestTokens { + tokens = append(tokens, dst) + } + return tokens, nil + }) +} + +func getOffRampVal[T any](o *FakeOffRamp, getter func(o *FakeOffRamp) (T, error)) (T, error) { + o.mu.RLock() + defer o.mu.RUnlock() + return getter(o) +} + +func setOffRampVal(o *FakeOffRamp, setter func(o *FakeOffRamp)) { + o.mu.Lock() + defer o.mu.Unlock() + setter(o) +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go b/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go new file mode 100644 index 0000000000..ea91362aaa --- /dev/null +++ b/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go @@ -0,0 +1,75 @@ +package testhelpers + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/services/keystore" +) + +// FirstBlockAge is used to compute first block's timestamp in SimulatedBackend (time.Now() - FirstBlockAge) +const FirstBlockAge = 24 * time.Hour + +func SetupChain(t *testing.T) (*backends.SimulatedBackend, *bind.TransactOpts) { + key, err := crypto.GenerateKey() + require.NoError(t, err) + user, err := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + require.NoError(t, err) + chain := backends.NewSimulatedBackend(core.GenesisAlloc{ + user.From: {Balance: new(big.Int).Mul(big.NewInt(1000), big.NewInt(1e18))}}, + ethconfig.Defaults.Miner.GasCeil) + // CCIP relies on block timestamps, but SimulatedBackend uses by default clock starting from 1970-01-01 + // This trick is used to move the clock closer to the current time. We set first block to be X hours ago. + // Tests create plenty of transactions so this number can't be too low, every new block mined will tick the clock, + // if you mine more than "X hours" transactions, SimulatedBackend will panic because generated timestamps will be in the future. + // IMPORTANT: Any adjustments to FirstBlockAge will automatically update PermissionLessExecutionThresholdSeconds in tests + blockTime := time.UnixMilli(int64(chain.Blockchain().CurrentHeader().Time)) + err = chain.AdjustTime(time.Since(blockTime) - FirstBlockAge) + require.NoError(t, err) + chain.Commit() + return chain, user +} + +type EthKeyStoreSim struct { + ETHKS keystore.Eth + CSAKS keystore.CSA +} + +func (ks EthKeyStoreSim) CSA() keystore.CSA { + return ks.CSAKS +} + +func (ks EthKeyStoreSim) Eth() keystore.Eth { + return ks.ETHKS +} + +func (ks EthKeyStoreSim) SignTx(address common.Address, tx *ethtypes.Transaction, chainID *big.Int) (*ethtypes.Transaction, error) { + if chainID.String() == "1000" { + // A terrible hack, just for the multichain test. All simulation clients run on chainID 1337. + // We let the DestChainSelector actually use 1337 to make sure the offchainConfig digests are properly generated. + return ks.ETHKS.SignTx(context.Background(), address, tx, big.NewInt(1337)) + } + return ks.ETHKS.SignTx(context.Background(), address, tx, chainID) +} + +var _ keystore.Eth = EthKeyStoreSim{}.ETHKS + +func ConfirmTxs(t *testing.T, txs []*ethtypes.Transaction, chain *backends.SimulatedBackend) { + chain.Commit() + for _, tx := range txs { + rec, err := bind.WaitMined(context.Background(), chain, tx) + require.NoError(t, err) + require.Equal(t, uint64(1), rec.Status) + } +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/structfields.go b/core/services/ocr2/plugins/ccip/testhelpers/structfields.go new file mode 100644 index 0000000000..88e0fffa67 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/testhelpers/structfields.go @@ -0,0 +1,44 @@ +package testhelpers + +import ( + "fmt" + "reflect" + "strings" +) + +// FindStructFieldsOfCertainType recursively iterates over struct fields and returns all the fields of the provided type. +func FindStructFieldsOfCertainType(targetType string, v any) []string { + typesAndFields := TypesAndFields("", reflect.ValueOf(v)) + results := make([]string, 0) + for _, field := range typesAndFields { + if strings.Contains(field, targetType) { + results = append(results, field) + } + } + return results +} + +// TypesAndFields will find and return all the fields and their types of the provided value. +// NOTE: This is not intended for production use, it's a helper method for tests. +func TypesAndFields(prefix string, v reflect.Value) []string { + results := make([]string, 0) + + s := v + typeOfT := s.Type() + for i := 0; i < s.NumField(); i++ { + f := s.Field(i) + typeAndName := fmt.Sprintf("%s%s %v", prefix, f.Type(), typeOfT.Field(i).Name) + results = append(results, typeAndName) + + if f.Kind().String() == "ptr" { + results = append(results, TypesAndFields(typeOfT.Field(i).Name, f.Elem())...) + } + + if f.Kind().String() == "struct" { + x1 := reflect.ValueOf(f.Interface()) + results = append(results, TypesAndFields(typeOfT.Field(i).Name, x1)...) + } + } + + return results +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go new file mode 100644 index 0000000000..4ea5bb18d7 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go @@ -0,0 +1,1585 @@ +package testhelpers_1_4_0 + +import ( + "context" + "fmt" + "math" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" + burn_mint_token_pool "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_4_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" + evm_2_evm_offramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + evm_2_evm_onramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_0_0" + lock_release_token_pool "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" +) + +var ( + // Source + SourcePool = "source Link pool" + SourcePriceRegistry = "source PriceRegistry" + OnRamp = "onramp" + OnRampNative = "onramp-native" + SourceRouter = "source router" + + // Dest + OffRamp = "offramp" + DestPool = "dest Link pool" + + Receiver = "receiver" + Sender = "sender" + Link = func(amount int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(amount)) } + HundredLink = Link(100) + LinkUSDValue = func(amount int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(amount)) } + SourceChainID = uint64(1000) + SourceChainSelector = uint64(11787463284727550157) + DestChainID = uint64(1337) + DestChainSelector = uint64(3379446385462418246) +) + +// Backwards compat, in principle these statuses are version dependent +// TODO: Adjust integration tests to be version agnostic using readers +var ( + ExecutionStateSuccess = MessageExecutionState(cciptypes.ExecutionStateSuccess) + ExecutionStateFailure = MessageExecutionState(cciptypes.ExecutionStateFailure) +) + +type MessageExecutionState cciptypes.MessageExecutionState +type CommitOffchainConfig struct { + v1_2_0.JSONCommitOffchainConfig +} + +func (c CommitOffchainConfig) Encode() ([]byte, error) { + return ccipconfig.EncodeOffchainConfig(c.JSONCommitOffchainConfig) +} + +func NewCommitOffchainConfig( + GasPriceHeartBeat config.Duration, + DAGasPriceDeviationPPB uint32, + ExecGasPriceDeviationPPB uint32, + TokenPriceHeartBeat config.Duration, + TokenPriceDeviationPPB uint32, + InflightCacheExpiry config.Duration) CommitOffchainConfig { + return CommitOffchainConfig{v1_2_0.JSONCommitOffchainConfig{ + GasPriceHeartBeat: GasPriceHeartBeat, + DAGasPriceDeviationPPB: DAGasPriceDeviationPPB, + ExecGasPriceDeviationPPB: ExecGasPriceDeviationPPB, + TokenPriceHeartBeat: TokenPriceHeartBeat, + TokenPriceDeviationPPB: TokenPriceDeviationPPB, + InflightCacheExpiry: InflightCacheExpiry, + }} +} + +type CommitOnchainConfig struct { + ccipdata.CommitOnchainConfig +} + +func NewCommitOnchainConfig( + PriceRegistry common.Address, +) CommitOnchainConfig { + return CommitOnchainConfig{ccipdata.CommitOnchainConfig{ + PriceRegistry: PriceRegistry, + }} +} + +type ExecOnchainConfig struct { + v1_2_0.ExecOnchainConfig +} + +func NewExecOnchainConfig( + PermissionLessExecutionThresholdSeconds uint32, + Router common.Address, + PriceRegistry common.Address, + MaxNumberOfTokensPerMsg uint16, + MaxDataBytes uint32, + MaxPoolReleaseOrMintGas uint32, +) ExecOnchainConfig { + return ExecOnchainConfig{v1_2_0.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: PermissionLessExecutionThresholdSeconds, + Router: Router, + PriceRegistry: PriceRegistry, + MaxNumberOfTokensPerMsg: MaxNumberOfTokensPerMsg, + MaxDataBytes: MaxDataBytes, + MaxPoolReleaseOrMintGas: MaxPoolReleaseOrMintGas, + }} +} + +type ExecOffchainConfig struct { + v1_2_0.JSONExecOffchainConfig +} + +func (c ExecOffchainConfig) Encode() ([]byte, error) { + return ccipconfig.EncodeOffchainConfig(c.JSONExecOffchainConfig) +} + +func NewExecOffchainConfig( + DestOptimisticConfirmations uint32, + BatchGasLimit uint32, + RelativeBoostPerWaitHour float64, + InflightCacheExpiry config.Duration, + RootSnoozeTime config.Duration, +) ExecOffchainConfig { + return ExecOffchainConfig{v1_2_0.JSONExecOffchainConfig{ + DestOptimisticConfirmations: DestOptimisticConfirmations, + BatchGasLimit: BatchGasLimit, + RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, + InflightCacheExpiry: InflightCacheExpiry, + RootSnoozeTime: RootSnoozeTime, + }} +} + +type MaybeRevertReceiver struct { + Receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver + Strict bool +} + +type Common struct { + ChainID uint64 + ChainSelector uint64 + User *bind.TransactOpts + Chain *backends.SimulatedBackend + LinkToken *link_token_interface.LinkToken + LinkTokenPool *lock_release_token_pool.LockReleaseTokenPool + CustomToken *link_token_interface.LinkToken + WrappedNative *weth9.WETH9 + WrappedNativePool *lock_release_token_pool_1_0_0.LockReleaseTokenPool + ARM *mock_arm_contract.MockARMContract + ARMProxy *arm_proxy_contract.ARMProxyContract + PriceRegistry *price_registry_1_2_0.PriceRegistry +} + +type SourceChain struct { + Common + Router *router.Router + OnRamp *evm_2_evm_onramp.EVM2EVMOnRamp +} + +type DestinationChain struct { + Common + + CommitStore *commit_store_1_2_0.CommitStore + Router *router.Router + OffRamp *evm_2_evm_offramp.EVM2EVMOffRamp + Receivers []MaybeRevertReceiver +} + +type OCR2Config struct { + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte +} + +type BalanceAssertion struct { + Name string + Address common.Address + Expected string + Getter func(t *testing.T, addr common.Address) *big.Int + Within string +} + +type BalanceReq struct { + Name string + Addr common.Address + Getter func(t *testing.T, addr common.Address) *big.Int +} + +type CCIPContracts struct { + Source SourceChain + Dest DestinationChain + Oracles []confighelper.OracleIdentityExtra + + commitOCRConfig, execOCRConfig *OCR2Config +} + +func (c *CCIPContracts) DeployNewOffRamp(t *testing.T) { + prevOffRamp := common.HexToAddress("") + if c.Dest.OffRamp != nil { + prevOffRamp = c.Dest.OffRamp.Address() + } + offRampAddress, _, _, err := evm_2_evm_offramp.DeployEVM2EVMOffRamp( + c.Dest.User, + c.Dest.Chain, + evm_2_evm_offramp.EVM2EVMOffRampStaticConfig{ + CommitStore: c.Dest.CommitStore.Address(), + ChainSelector: c.Dest.ChainSelector, + SourceChainSelector: c.Source.ChainSelector, + OnRamp: c.Source.OnRamp.Address(), + PrevOffRamp: prevOffRamp, + ArmProxy: c.Dest.ARMProxy.Address(), + }, + []common.Address{c.Source.LinkToken.Address()}, // source tokens + []common.Address{c.Dest.LinkTokenPool.Address()}, // pools + evm_2_evm_offramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: LinkUSDValue(100), + Rate: LinkUSDValue(1), + }, + ) + require.NoError(t, err) + c.Dest.Chain.Commit() + + c.Dest.OffRamp, err = evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampAddress, c.Dest.Chain) + require.NoError(t, err) + + c.Dest.Chain.Commit() + c.Source.Chain.Commit() +} + +func (c *CCIPContracts) EnableOffRamp(t *testing.T) { + _, err := c.Dest.Router.ApplyRampUpdates(c.Dest.User, nil, nil, []router.RouterOffRamp{{SourceChainSelector: SourceChainSelector, OffRamp: c.Dest.OffRamp.Address()}}) + require.NoError(t, err) + c.Dest.Chain.Commit() + + onChainConfig := c.CreateDefaultExecOnchainConfig(t) + offChainConfig := c.CreateDefaultExecOffchainConfig(t) + + c.SetupExecOCR2Config(t, onChainConfig, offChainConfig) +} + +func (c *CCIPContracts) EnableCommitStore(t *testing.T) { + onChainConfig := c.CreateDefaultCommitOnchainConfig(t) + offChainConfig := c.CreateDefaultCommitOffchainConfig(t) + + c.SetupCommitOCR2Config(t, onChainConfig, offChainConfig) + + _, err := c.Dest.PriceRegistry.ApplyPriceUpdatersUpdates(c.Dest.User, []common.Address{c.Dest.CommitStore.Address()}, []common.Address{}) + require.NoError(t, err) + c.Dest.Chain.Commit() +} + +func (c *CCIPContracts) DeployNewOnRamp(t *testing.T) { + t.Log("Deploying new onRamp") + // find the last onRamp + prevOnRamp := common.HexToAddress("") + if c.Source.OnRamp != nil { + prevOnRamp = c.Source.OnRamp.Address() + } + onRampAddress, _, _, err := evm_2_evm_onramp.DeployEVM2EVMOnRamp( + c.Source.User, // user + c.Source.Chain, // client + evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ + LinkToken: c.Source.LinkToken.Address(), + ChainSelector: c.Source.ChainSelector, + DestChainSelector: c.Dest.ChainSelector, + DefaultTxGasLimit: 200_000, + MaxNopFeesJuels: big.NewInt(0).Mul(big.NewInt(100_000_000), big.NewInt(1e18)), + PrevOnRamp: prevOnRamp, + ArmProxy: c.Source.ARM.Address(), // ARM + }, + evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ + Router: c.Source.Router.Address(), + MaxNumberOfTokensPerMsg: 5, + DestGasOverhead: 350_000, + DestGasPerPayloadByte: 16, + DestDataAvailabilityOverheadGas: 33_596, + DestGasPerDataAvailabilityByte: 16, + DestDataAvailabilityMultiplierBps: 6840, // 0.684 + PriceRegistry: c.Source.PriceRegistry.Address(), + MaxDataBytes: 1e5, + MaxPerMsgGasLimit: 4_000_000, + }, + []evm_2_evm_onramp.InternalPoolUpdate{ + { + Token: c.Source.LinkToken.Address(), + Pool: c.Source.LinkTokenPool.Address(), + }, + }, + evm_2_evm_onramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: LinkUSDValue(100), + Rate: LinkUSDValue(1), + }, + []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ + { + Token: c.Source.LinkToken.Address(), + NetworkFeeUSDCents: 1_00, + GasMultiplierWeiPerEth: 1e18, + PremiumMultiplierWeiPerEth: 9e17, + Enabled: true, + }, + { + Token: c.Source.WrappedNative.Address(), + NetworkFeeUSDCents: 1_00, + GasMultiplierWeiPerEth: 1e18, + PremiumMultiplierWeiPerEth: 1e18, + Enabled: true, + }, + }, + []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + { + Token: c.Source.LinkToken.Address(), + MinFeeUSDCents: 50, // $0.5 + MaxFeeUSDCents: 1_000_000_00, // $ 1 million + DeciBps: 5_0, // 5 bps + DestGasOverhead: 34_000, + DestBytesOverhead: 32, + }, + }, + []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{}, + ) + + require.NoError(t, err) + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + c.Source.OnRamp, err = evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, c.Source.Chain) + require.NoError(t, err) + c.Source.Chain.Commit() + c.Dest.Chain.Commit() +} + +func (c *CCIPContracts) EnableOnRamp(t *testing.T) { + t.Log("Setting onRamp on source router") + _, err := c.Source.Router.ApplyRampUpdates(c.Source.User, []router.RouterOnRamp{{DestChainSelector: c.Dest.ChainSelector, OnRamp: c.Source.OnRamp.Address()}}, nil, nil) + require.NoError(t, err) + c.Source.Chain.Commit() + c.Dest.Chain.Commit() +} + +func (c *CCIPContracts) DeployNewCommitStore(t *testing.T) { + commitStoreAddress, _, _, err := commit_store_1_2_0.DeployCommitStore( + c.Dest.User, // user + c.Dest.Chain, // client + commit_store_1_2_0.CommitStoreStaticConfig{ + ChainSelector: c.Dest.ChainSelector, + SourceChainSelector: c.Source.ChainSelector, + OnRamp: c.Source.OnRamp.Address(), + ArmProxy: c.Dest.ARMProxy.Address(), + }, + ) + require.NoError(t, err) + c.Dest.Chain.Commit() + // since CommitStoreHelper derives from CommitStore, it's safe to instantiate both on same address + c.Dest.CommitStore, err = commit_store_1_2_0.NewCommitStore(commitStoreAddress, c.Dest.Chain) + require.NoError(t, err) +} + +func (c *CCIPContracts) DeployNewPriceRegistry(t *testing.T) { + t.Log("Deploying new Price Registry") + destPricesAddress, _, _, err := price_registry_1_2_0.DeployPriceRegistry( + c.Dest.User, + c.Dest.Chain, + []common.Address{c.Dest.CommitStore.Address()}, + []common.Address{c.Dest.LinkToken.Address()}, + 60*60*24*14, // two weeks + ) + require.NoError(t, err) + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + c.Dest.PriceRegistry, err = price_registry_1_2_0.NewPriceRegistry(destPricesAddress, c.Dest.Chain) + require.NoError(t, err) + + priceUpdates := price_registry_1_2_0.InternalPriceUpdates{ + TokenPriceUpdates: []price_registry_1_2_0.InternalTokenPriceUpdate{ + { + SourceToken: c.Dest.LinkToken.Address(), + UsdPerToken: big.NewInt(8e18), // 8usd + }, + { + SourceToken: c.Dest.WrappedNative.Address(), + UsdPerToken: big.NewInt(1e18), // 1usd + }, + }, + GasPriceUpdates: []price_registry_1_2_0.InternalGasPriceUpdate{ + { + DestChainSelector: c.Source.ChainSelector, + UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, + }, + } + _, err = c.Dest.PriceRegistry.UpdatePrices(c.Dest.User, priceUpdates) + require.NoError(t, err) + + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + + t.Logf("New Price Registry deployed at %s", destPricesAddress.String()) +} + +func (c *CCIPContracts) SetNopsOnRamp(t *testing.T, nopsAndWeights []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight) { + tx, err := c.Source.OnRamp.SetNops(c.Source.User, nopsAndWeights) + require.NoError(t, err) + c.Source.Chain.Commit() + _, err = bind.WaitMined(context.Background(), c.Source.Chain, tx) + require.NoError(t, err) +} + +func (c *CCIPContracts) GetSourceLinkBalance(t *testing.T, addr common.Address) *big.Int { + return GetBalance(t, c.Source.Chain, c.Source.LinkToken.Address(), addr) +} + +func (c *CCIPContracts) GetDestLinkBalance(t *testing.T, addr common.Address) *big.Int { + return GetBalance(t, c.Dest.Chain, c.Dest.LinkToken.Address(), addr) +} + +func (c *CCIPContracts) GetSourceWrappedTokenBalance(t *testing.T, addr common.Address) *big.Int { + return GetBalance(t, c.Source.Chain, c.Source.WrappedNative.Address(), addr) +} + +func (c *CCIPContracts) GetDestWrappedTokenBalance(t *testing.T, addr common.Address) *big.Int { + return GetBalance(t, c.Dest.Chain, c.Dest.WrappedNative.Address(), addr) +} + +func (c *CCIPContracts) AssertBalances(t *testing.T, bas []BalanceAssertion) { + for _, b := range bas { + actual := b.Getter(t, b.Address) + t.Log("Checking balance for", b.Name, "at", b.Address.Hex(), "got", actual) + require.NotNil(t, actual, "%v getter return nil", b.Name) + if b.Within == "" { + require.Equal(t, b.Expected, actual.String(), "wrong balance for %s got %s want %s", b.Name, actual, b.Expected) + } else { + bi, _ := big.NewInt(0).SetString(b.Expected, 10) + withinI, _ := big.NewInt(0).SetString(b.Within, 10) + high := big.NewInt(0).Add(bi, withinI) + low := big.NewInt(0).Sub(bi, withinI) + require.Equal(t, -1, actual.Cmp(high), "wrong balance for %s got %s outside expected range [%s, %s]", b.Name, actual, low, high) + require.Equal(t, 1, actual.Cmp(low), "wrong balance for %s got %s outside expected range [%s, %s]", b.Name, actual, low, high) + } + } +} + +func AccountToAddress(accounts []ocr2types.Account) (addresses []common.Address, err error) { + for _, signer := range accounts { + bytes, err := hexutil.Decode(string(signer)) + if err != nil { + return []common.Address{}, errors.Wrap(err, fmt.Sprintf("given address is not valid %s", signer)) + } + if len(bytes) != 20 { + return []common.Address{}, errors.Errorf("address is not 20 bytes %s", signer) + } + addresses = append(addresses, common.BytesToAddress(bytes)) + } + return addresses, nil +} + +func OnchainPublicKeyToAddress(publicKeys []ocrtypes.OnchainPublicKey) (addresses []common.Address, err error) { + for _, signer := range publicKeys { + if len(signer) != 20 { + return []common.Address{}, errors.Errorf("address is not 20 bytes %s", signer) + } + addresses = append(addresses, common.BytesToAddress(signer)) + } + return addresses, nil +} + +func (c *CCIPContracts) DeriveOCR2Config(t *testing.T, oracles []confighelper.OracleIdentityExtra, rawOnchainConfig []byte, rawOffchainConfig []byte) *OCR2Config { + signers, transmitters, threshold, onchainConfig, offchainConfigVersion, offchainConfig, err := confighelper.ContractSetConfigArgsForTests( + 2*time.Second, // deltaProgress + 1*time.Second, // deltaResend + 1*time.Second, // deltaRound + 500*time.Millisecond, // deltaGrace + 2*time.Second, // deltaStage + 3, + []int{1, 1, 1, 1}, + oracles, + rawOffchainConfig, + 50*time.Millisecond, // Max duration query + 1*time.Second, // Max duration observation + 100*time.Millisecond, + 100*time.Millisecond, + 100*time.Millisecond, + 1, // faults + rawOnchainConfig, + ) + require.NoError(t, err) + lggr := logger.TestLogger(t) + lggr.Infow("Setting Config on Oracle Contract", + "signers", signers, + "transmitters", transmitters, + "threshold", threshold, + "onchainConfig", onchainConfig, + "encodedConfigVersion", offchainConfigVersion, + ) + signerAddresses, err := OnchainPublicKeyToAddress(signers) + require.NoError(t, err) + transmitterAddresses, err := AccountToAddress(transmitters) + require.NoError(t, err) + + return &OCR2Config{ + Signers: signerAddresses, + Transmitters: transmitterAddresses, + F: threshold, + OnchainConfig: onchainConfig, + OffchainConfigVersion: offchainConfigVersion, + OffchainConfig: offchainConfig, + } +} + +func (c *CCIPContracts) SetupCommitOCR2Config(t *testing.T, commitOnchainConfig, commitOffchainConfig []byte) { + c.commitOCRConfig = c.DeriveOCR2Config(t, c.Oracles, commitOnchainConfig, commitOffchainConfig) + // Set the DON on the commit store + _, err := c.Dest.CommitStore.SetOCR2Config( + c.Dest.User, + c.commitOCRConfig.Signers, + c.commitOCRConfig.Transmitters, + c.commitOCRConfig.F, + c.commitOCRConfig.OnchainConfig, + c.commitOCRConfig.OffchainConfigVersion, + c.commitOCRConfig.OffchainConfig, + ) + require.NoError(t, err) + c.Dest.Chain.Commit() +} + +func (c *CCIPContracts) SetupExecOCR2Config(t *testing.T, execOnchainConfig, execOffchainConfig []byte) { + c.execOCRConfig = c.DeriveOCR2Config(t, c.Oracles, execOnchainConfig, execOffchainConfig) + // Same DON on the offramp + _, err := c.Dest.OffRamp.SetOCR2Config( + c.Dest.User, + c.execOCRConfig.Signers, + c.execOCRConfig.Transmitters, + c.execOCRConfig.F, + c.execOCRConfig.OnchainConfig, + c.execOCRConfig.OffchainConfigVersion, + c.execOCRConfig.OffchainConfig, + ) + require.NoError(t, err) + c.Dest.Chain.Commit() +} + +func (c *CCIPContracts) SetupOnchainConfig(t *testing.T, commitOnchainConfig, commitOffchainConfig, execOnchainConfig, execOffchainConfig []byte) int64 { + // Note We do NOT set the payees, payment is done in the OCR2Base implementation + blockBeforeConfig, err := c.Dest.Chain.BlockByNumber(context.Background(), nil) + require.NoError(t, err) + + c.SetupCommitOCR2Config(t, commitOnchainConfig, commitOffchainConfig) + c.SetupExecOCR2Config(t, execOnchainConfig, execOffchainConfig) + + return blockBeforeConfig.Number().Int64() +} + +func (c *CCIPContracts) SetupLockAndMintTokenPool( + sourceTokenAddress common.Address, + wrappedTokenName, + wrappedTokenSymbol string) (common.Address, *burn_mint_erc677.BurnMintERC677, error) { + // Deploy dest token & pool + destTokenAddress, _, _, err := burn_mint_erc677.DeployBurnMintERC677(c.Dest.User, c.Dest.Chain, wrappedTokenName, wrappedTokenSymbol, 18, big.NewInt(0)) + if err != nil { + return [20]byte{}, nil, err + } + c.Dest.Chain.Commit() + + destToken, err := burn_mint_erc677.NewBurnMintERC677(destTokenAddress, c.Dest.Chain) + if err != nil { + return [20]byte{}, nil, err + } + + destPoolAddress, _, destPool, err := burn_mint_token_pool.DeployBurnMintTokenPool( + c.Dest.User, + c.Dest.Chain, + destTokenAddress, + []common.Address{}, // pool originalSender allowList + c.Dest.ARMProxy.Address(), + c.Dest.Router.Address(), + ) + if err != nil { + return [20]byte{}, nil, err + } + c.Dest.Chain.Commit() + + _, err = destToken.GrantMintAndBurnRoles(c.Dest.User, destPoolAddress) + if err != nil { + return [20]byte{}, nil, err + } + + _, err = destPool.ApplyChainUpdates(c.Dest.User, + []burn_mint_token_pool.TokenPoolChainUpdate{ + { + RemoteChainSelector: c.Source.ChainSelector, + Allowed: true, + OutboundRateLimiterConfig: burn_mint_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + InboundRateLimiterConfig: burn_mint_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + }, + }) + if err != nil { + return [20]byte{}, nil, err + } + c.Dest.Chain.Commit() + + sourcePoolAddress, _, sourcePool, err := lock_release_token_pool.DeployLockReleaseTokenPool( + c.Source.User, + c.Source.Chain, + sourceTokenAddress, + []common.Address{}, // empty allowList at deploy time indicates pool has no original sender restrictions + c.Source.ARMProxy.Address(), + true, + c.Source.Router.Address(), + ) + if err != nil { + return [20]byte{}, nil, err + } + c.Source.Chain.Commit() + + // set onRamp as valid caller for source pool + _, err = sourcePool.ApplyChainUpdates(c.Source.User, []lock_release_token_pool.TokenPoolChainUpdate{ + { + RemoteChainSelector: c.Dest.ChainSelector, + Allowed: true, + OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + }, + }) + if err != nil { + return [20]byte{}, nil, err + } + c.Source.Chain.Commit() + + wrappedNativeAddress, err := c.Source.Router.GetWrappedNative(nil) + if err != nil { + return [20]byte{}, nil, err + } + + //native token is used as fee token + _, err = c.Source.PriceRegistry.UpdatePrices(c.Source.User, price_registry_1_2_0.InternalPriceUpdates{ + TokenPriceUpdates: []price_registry_1_2_0.InternalTokenPriceUpdate{ + { + SourceToken: sourceTokenAddress, + UsdPerToken: big.NewInt(5), + }, + }, + GasPriceUpdates: []price_registry_1_2_0.InternalGasPriceUpdate{}, + }) + if err != nil { + return [20]byte{}, nil, err + } + c.Source.Chain.Commit() + + _, err = c.Source.PriceRegistry.ApplyFeeTokensUpdates(c.Source.User, []common.Address{wrappedNativeAddress}, nil) + if err != nil { + return [20]byte{}, nil, err + } + c.Source.Chain.Commit() + + // add new token pool created above + _, err = c.Source.OnRamp.ApplyPoolUpdates(c.Source.User, nil, []evm_2_evm_onramp.InternalPoolUpdate{ + { + Token: sourceTokenAddress, + Pool: sourcePoolAddress, + }, + }) + if err != nil { + return [20]byte{}, nil, err + } + + _, err = c.Dest.OffRamp.ApplyPoolUpdates(c.Dest.User, nil, []evm_2_evm_offramp.InternalPoolUpdate{ + { + Token: sourceTokenAddress, + Pool: destPoolAddress, + }, + }) + if err != nil { + return [20]byte{}, nil, err + } + c.Dest.Chain.Commit() + + return sourcePoolAddress, destToken, err +} + +func (c *CCIPContracts) SendMessage(t *testing.T, gasLimit, tokenAmount *big.Int, receiverAddr common.Address) { + extraArgs, err := GetEVMExtraArgsV1(gasLimit, false) + require.NoError(t, err) + msg := router.ClientEVM2AnyMessage{ + Receiver: MustEncodeAddress(t, receiverAddr), + Data: []byte("hello"), + TokenAmounts: []router.ClientEVMTokenAmount{ + { + Token: c.Source.LinkToken.Address(), + Amount: tokenAmount, + }, + }, + FeeToken: c.Source.LinkToken.Address(), + ExtraArgs: extraArgs, + } + fee, err := c.Source.Router.GetFee(nil, c.Dest.ChainSelector, msg) + require.NoError(t, err) + // Currently no overhead and 1gwei dest gas price. So fee is simply gasLimit * gasPrice. + // require.Equal(t, new(big.Int).Mul(gasLimit, gasPrice).String(), fee.String()) + // Approve the fee amount + the token amount + _, err = c.Source.LinkToken.Approve(c.Source.User, c.Source.Router.Address(), new(big.Int).Add(fee, tokenAmount)) + require.NoError(t, err) + c.Source.Chain.Commit() + c.SendRequest(t, msg) +} + +func GetBalances(t *testing.T, brs []BalanceReq) (map[string]*big.Int, error) { + m := make(map[string]*big.Int) + for _, br := range brs { + m[br.Name] = br.Getter(t, br.Addr) + if m[br.Name] == nil { + return nil, fmt.Errorf("%v getter return nil", br.Name) + } + } + return m, nil +} + +func MustAddBigInt(a *big.Int, b string) *big.Int { + bi, _ := big.NewInt(0).SetString(b, 10) + return big.NewInt(0).Add(a, bi) +} + +func MustSubBigInt(a *big.Int, b string) *big.Int { + bi, _ := big.NewInt(0).SetString(b, 10) + return big.NewInt(0).Sub(a, bi) +} + +func MustEncodeAddress(t *testing.T, address common.Address) []byte { + bts, err := utils.ABIEncode(`[{"type":"address"}]`, address) + require.NoError(t, err) + return bts +} + +func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destChainID, destChainSelector uint64) CCIPContracts { + sourceChain, sourceUser := testhelpers.SetupChain(t) + destChain, destUser := testhelpers.SetupChain(t) + + armSourceAddress, _, _, err := mock_arm_contract.DeployMockARMContract( + sourceUser, + sourceChain, + ) + require.NoError(t, err) + sourceARM, err := mock_arm_contract.NewMockARMContract(armSourceAddress, sourceChain) + require.NoError(t, err) + armProxySourceAddress, _, _, err := arm_proxy_contract.DeployARMProxyContract( + sourceUser, + sourceChain, + armSourceAddress, + ) + require.NoError(t, err) + sourceARMProxy, err := arm_proxy_contract.NewARMProxyContract(armProxySourceAddress, sourceChain) + require.NoError(t, err) + sourceChain.Commit() + + armDestAddress, _, _, err := mock_arm_contract.DeployMockARMContract( + destUser, + destChain, + ) + require.NoError(t, err) + armProxyDestAddress, _, _, err := arm_proxy_contract.DeployARMProxyContract( + destUser, + destChain, + armDestAddress, + ) + require.NoError(t, err) + destChain.Commit() + destARM, err := mock_arm_contract.NewMockARMContract(armDestAddress, destChain) + require.NoError(t, err) + destARMProxy, err := arm_proxy_contract.NewARMProxyContract(armProxyDestAddress, destChain) + require.NoError(t, err) + + // Deploy link token and pool on source chain + sourceLinkTokenAddress, _, _, err := link_token_interface.DeployLinkToken(sourceUser, sourceChain) + require.NoError(t, err) + sourceChain.Commit() + sourceLinkToken, err := link_token_interface.NewLinkToken(sourceLinkTokenAddress, sourceChain) + require.NoError(t, err) + + // Create router + sourceWeth9addr, _, _, err := weth9.DeployWETH9(sourceUser, sourceChain) + require.NoError(t, err) + sourceWrapped, err := weth9.NewWETH9(sourceWeth9addr, sourceChain) + require.NoError(t, err) + + sourceRouterAddress, _, _, err := router.DeployRouter(sourceUser, sourceChain, sourceWeth9addr, armProxySourceAddress) + require.NoError(t, err) + sourceRouter, err := router.NewRouter(sourceRouterAddress, sourceChain) + require.NoError(t, err) + sourceChain.Commit() + + sourceWeth9PoolAddress, _, _, err := lock_release_token_pool_1_0_0.DeployLockReleaseTokenPool( + sourceUser, + sourceChain, + sourceWeth9addr, + []common.Address{}, + armProxySourceAddress, + ) + require.NoError(t, err) + sourceChain.Commit() + + sourceWeth9Pool, err := lock_release_token_pool_1_0_0.NewLockReleaseTokenPool(sourceWeth9PoolAddress, sourceChain) + require.NoError(t, err) + + sourcePoolAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( + sourceUser, + sourceChain, + sourceLinkTokenAddress, + []common.Address{}, + armProxySourceAddress, + true, + sourceRouterAddress, + ) + require.NoError(t, err) + sourceChain.Commit() + sourcePool, err := lock_release_token_pool.NewLockReleaseTokenPool(sourcePoolAddress, sourceChain) + require.NoError(t, err) + + // Deploy custom token pool source + sourceCustomTokenAddress, _, _, err := link_token_interface.DeployLinkToken(sourceUser, sourceChain) // Just re-use this, it's an ERC20. + require.NoError(t, err) + sourceCustomToken, err := link_token_interface.NewLinkToken(sourceCustomTokenAddress, sourceChain) + require.NoError(t, err) + destChain.Commit() + + // Deploy custom token pool dest + destCustomTokenAddress, _, _, err := link_token_interface.DeployLinkToken(destUser, destChain) // Just re-use this, it's an ERC20. + require.NoError(t, err) + destCustomToken, err := link_token_interface.NewLinkToken(destCustomTokenAddress, destChain) + require.NoError(t, err) + destChain.Commit() + + // Deploy and configure onramp + sourcePricesAddress, _, _, err := price_registry_1_2_0.DeployPriceRegistry( + sourceUser, + sourceChain, + nil, + []common.Address{sourceLinkTokenAddress, sourceWeth9addr}, + 60*60*24*14, // two weeks + ) + require.NoError(t, err) + + srcPriceRegistry, err := price_registry_1_2_0.NewPriceRegistry(sourcePricesAddress, sourceChain) + require.NoError(t, err) + + _, err = srcPriceRegistry.UpdatePrices(sourceUser, price_registry_1_2_0.InternalPriceUpdates{ + TokenPriceUpdates: []price_registry_1_2_0.InternalTokenPriceUpdate{ + { + SourceToken: sourceLinkTokenAddress, + UsdPerToken: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(20)), + }, + { + SourceToken: sourceWeth9addr, + UsdPerToken: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2000)), + }, + }, + GasPriceUpdates: []price_registry_1_2_0.InternalGasPriceUpdate{ + { + DestChainSelector: destChainSelector, + UsdPerUnitGas: big.NewInt(20000e9), + }, + }, + }) + require.NoError(t, err) + + onRampAddress, _, _, err := evm_2_evm_onramp.DeployEVM2EVMOnRamp( + sourceUser, // user + sourceChain, // client + evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ + LinkToken: sourceLinkTokenAddress, + ChainSelector: sourceChainSelector, + DestChainSelector: destChainSelector, + DefaultTxGasLimit: 200_000, + MaxNopFeesJuels: big.NewInt(0).Mul(big.NewInt(100_000_000), big.NewInt(1e18)), + PrevOnRamp: common.HexToAddress(""), + ArmProxy: armProxySourceAddress, // ARM + }, + evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ + Router: sourceRouterAddress, + MaxNumberOfTokensPerMsg: 5, + DestGasOverhead: 350_000, + DestGasPerPayloadByte: 16, + DestDataAvailabilityOverheadGas: 33_596, + DestGasPerDataAvailabilityByte: 16, + DestDataAvailabilityMultiplierBps: 6840, // 0.684 + PriceRegistry: sourcePricesAddress, + MaxDataBytes: 1e5, + MaxPerMsgGasLimit: 4_000_000, + }, + []evm_2_evm_onramp.InternalPoolUpdate{ + { + Token: sourceLinkTokenAddress, + Pool: sourcePoolAddress, + }, + { + Token: sourceWeth9addr, + Pool: sourceWeth9PoolAddress, + }, + }, + evm_2_evm_onramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: LinkUSDValue(100), + Rate: LinkUSDValue(1), + }, + []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ + { + Token: sourceLinkTokenAddress, + NetworkFeeUSDCents: 1_00, + GasMultiplierWeiPerEth: 1e18, + PremiumMultiplierWeiPerEth: 9e17, + Enabled: true, + }, + { + Token: sourceWeth9addr, + NetworkFeeUSDCents: 1_00, + GasMultiplierWeiPerEth: 1e18, + PremiumMultiplierWeiPerEth: 1e18, + Enabled: true, + }, + }, + []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + { + Token: sourceLinkTokenAddress, + MinFeeUSDCents: 50, // $0.5 + MaxFeeUSDCents: 1_000_000_00, // $ 1 million + DeciBps: 5_0, // 5 bps + DestGasOverhead: 34_000, + DestBytesOverhead: 32, + }, + }, + []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{}, + ) + require.NoError(t, err) + onRamp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, sourceChain) + require.NoError(t, err) + _, err = sourcePool.ApplyChainUpdates( + sourceUser, + []lock_release_token_pool.TokenPoolChainUpdate{{ + RemoteChainSelector: DestChainSelector, + Allowed: true, + OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + }}, + ) + require.NoError(t, err) + _, err = sourceWeth9Pool.ApplyRampUpdates(sourceUser, + []lock_release_token_pool_1_0_0.TokenPoolRampUpdate{{Ramp: onRampAddress, Allowed: true, + RateLimiterConfig: lock_release_token_pool_1_0_0.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + }}, + []lock_release_token_pool_1_0_0.TokenPoolRampUpdate{}, + ) + require.NoError(t, err) + sourceChain.Commit() + _, err = sourceRouter.ApplyRampUpdates(sourceUser, []router.RouterOnRamp{{DestChainSelector: destChainSelector, OnRamp: onRampAddress}}, nil, nil) + require.NoError(t, err) + sourceChain.Commit() + + destWethaddr, _, _, err := weth9.DeployWETH9(destUser, destChain) + require.NoError(t, err) + destWrapped, err := weth9.NewWETH9(destWethaddr, destChain) + require.NoError(t, err) + + // Create dest router + destRouterAddress, _, _, err := router.DeployRouter(destUser, destChain, destWethaddr, armProxyDestAddress) + require.NoError(t, err) + destChain.Commit() + destRouter, err := router.NewRouter(destRouterAddress, destChain) + require.NoError(t, err) + + // Deploy link token and pool on destination chain + destLinkTokenAddress, _, _, err := link_token_interface.DeployLinkToken(destUser, destChain) + require.NoError(t, err) + destChain.Commit() + destLinkToken, err := link_token_interface.NewLinkToken(destLinkTokenAddress, destChain) + require.NoError(t, err) + destPoolAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( + destUser, + destChain, + destLinkTokenAddress, + []common.Address{}, + armProxyDestAddress, + true, + destRouterAddress, + ) + require.NoError(t, err) + destChain.Commit() + destPool, err := lock_release_token_pool.NewLockReleaseTokenPool(destPoolAddress, destChain) + require.NoError(t, err) + destChain.Commit() + + // Float the offramp pool + o, err := destPool.Owner(nil) + require.NoError(t, err) + require.Equal(t, destUser.From.String(), o.String()) + _, err = destPool.SetRebalancer(destUser, destUser.From) + require.NoError(t, err) + _, err = destLinkToken.Approve(destUser, destPoolAddress, Link(200)) + require.NoError(t, err) + _, err = destPool.ProvideLiquidity(destUser, Link(200)) + require.NoError(t, err) + destChain.Commit() + + destWrappedPoolAddress, _, _, err := lock_release_token_pool_1_0_0.DeployLockReleaseTokenPool( + destUser, + destChain, + destWethaddr, + []common.Address{}, + armProxyDestAddress, + ) + require.NoError(t, err) + destWrappedPool, err := lock_release_token_pool_1_0_0.NewLockReleaseTokenPool(destWrappedPoolAddress, destChain) + require.NoError(t, err) + + poolFloatValue := big.NewInt(1e18) + + destUser.Value = poolFloatValue + _, err = destWrapped.Deposit(destUser) + require.NoError(t, err) + destChain.Commit() + destUser.Value = nil + + _, err = destWrapped.Transfer(destUser, destWrappedPool.Address(), poolFloatValue) + require.NoError(t, err) + destChain.Commit() + + // Deploy and configure ge offramp. + destPricesAddress, _, _, err := price_registry_1_2_0.DeployPriceRegistry( + destUser, + destChain, + nil, + []common.Address{destLinkTokenAddress}, + 60*60*24*14, // two weeks + ) + require.NoError(t, err) + destPriceRegistry, err := price_registry_1_2_0.NewPriceRegistry(destPricesAddress, destChain) + require.NoError(t, err) + + // Deploy commit store. + commitStoreAddress, _, _, err := commit_store_1_2_0.DeployCommitStore( + destUser, // user + destChain, // client + commit_store_1_2_0.CommitStoreStaticConfig{ + ChainSelector: destChainSelector, + SourceChainSelector: sourceChainSelector, + OnRamp: onRamp.Address(), + ArmProxy: destARMProxy.Address(), + }, + ) + require.NoError(t, err) + destChain.Commit() + commitStore, err := commit_store_1_2_0.NewCommitStore(commitStoreAddress, destChain) + require.NoError(t, err) + + offRampAddress, _, _, err := evm_2_evm_offramp.DeployEVM2EVMOffRamp( + destUser, + destChain, + evm_2_evm_offramp.EVM2EVMOffRampStaticConfig{ + CommitStore: commitStore.Address(), + ChainSelector: destChainSelector, + SourceChainSelector: sourceChainSelector, + OnRamp: onRampAddress, + PrevOffRamp: common.HexToAddress(""), + ArmProxy: armProxyDestAddress, + }, + []common.Address{sourceLinkTokenAddress, sourceWeth9addr}, + []common.Address{destPoolAddress, destWrappedPool.Address()}, + evm_2_evm_offramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: LinkUSDValue(100), + Rate: LinkUSDValue(1), + }, + ) + require.NoError(t, err) + offRamp, err := evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampAddress, destChain) + require.NoError(t, err) + _, err = destPool.ApplyChainUpdates(destUser, + []lock_release_token_pool.TokenPoolChainUpdate{{ + RemoteChainSelector: sourceChainSelector, + Allowed: true, + OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + }}, + ) + require.NoError(t, err) + + _, err = destWrappedPool.ApplyRampUpdates(destUser, + []lock_release_token_pool_1_0_0.TokenPoolRampUpdate{}, + []lock_release_token_pool_1_0_0.TokenPoolRampUpdate{{ + Ramp: offRampAddress, + Allowed: true, + RateLimiterConfig: lock_release_token_pool_1_0_0.RateLimiterConfig{ + IsEnabled: true, + Capacity: HundredLink, + Rate: big.NewInt(1e18), + }, + }}, + ) + require.NoError(t, err) + + destChain.Commit() + _, err = destPriceRegistry.ApplyPriceUpdatersUpdates(destUser, []common.Address{commitStoreAddress}, []common.Address{}) + require.NoError(t, err) + _, err = destRouter.ApplyRampUpdates(destUser, nil, + nil, []router.RouterOffRamp{{SourceChainSelector: sourceChainSelector, OffRamp: offRampAddress}}) + require.NoError(t, err) + + // Deploy 2 revertable (one SS one non-SS) + revertingMessageReceiver1Address, _, _, err := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver(destUser, destChain, false) + require.NoError(t, err) + revertingMessageReceiver1, _ := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(revertingMessageReceiver1Address, destChain) + revertingMessageReceiver2Address, _, _, err := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver(destUser, destChain, false) + require.NoError(t, err) + revertingMessageReceiver2, _ := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(revertingMessageReceiver2Address, destChain) + // Need to commit here, or we will hit the block gas limit when deploying the executor + sourceChain.Commit() + destChain.Commit() + + // Ensure we have at least finality blocks. + for i := 0; i < 50; i++ { + sourceChain.Commit() + destChain.Commit() + } + + source := SourceChain{ + Common: Common{ + ChainID: sourceChainID, + ChainSelector: sourceChainSelector, + User: sourceUser, + Chain: sourceChain, + LinkToken: sourceLinkToken, + LinkTokenPool: sourcePool, + CustomToken: sourceCustomToken, + ARM: sourceARM, + ARMProxy: sourceARMProxy, + PriceRegistry: srcPriceRegistry, + WrappedNative: sourceWrapped, + WrappedNativePool: sourceWeth9Pool, + }, + Router: sourceRouter, + OnRamp: onRamp, + } + dest := DestinationChain{ + Common: Common{ + ChainID: destChainID, + ChainSelector: destChainSelector, + User: destUser, + Chain: destChain, + LinkToken: destLinkToken, + LinkTokenPool: destPool, + CustomToken: destCustomToken, + ARM: destARM, + ARMProxy: destARMProxy, + PriceRegistry: destPriceRegistry, + WrappedNative: destWrapped, + WrappedNativePool: destWrappedPool, + }, + CommitStore: commitStore, + Router: destRouter, + OffRamp: offRamp, + Receivers: []MaybeRevertReceiver{{Receiver: revertingMessageReceiver1, Strict: false}, {Receiver: revertingMessageReceiver2, Strict: true}}, + } + + return CCIPContracts{ + Source: source, + Dest: dest, + } +} + +func (c *CCIPContracts) SendRequest(t *testing.T, msg router.ClientEVM2AnyMessage) *types.Transaction { + tx, err := c.Source.Router.CcipSend(c.Source.User, c.Dest.ChainSelector, msg) + require.NoError(t, err) + testhelpers.ConfirmTxs(t, []*types.Transaction{tx}, c.Source.Chain) + return tx +} + +func (c *CCIPContracts) AssertExecState(t *testing.T, log logpoller.Log, state MessageExecutionState, offRampOpts ...common.Address) { + var offRamp *evm_2_evm_offramp.EVM2EVMOffRamp + var err error + if len(offRampOpts) > 0 { + offRamp, err = evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampOpts[0], c.Dest.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Dest.OffRamp, "no offRamp configured") + offRamp = c.Dest.OffRamp + } + executionStateChanged, err := offRamp.ParseExecutionStateChanged(log.ToGethLog()) + require.NoError(t, err) + if MessageExecutionState(executionStateChanged.State) != state { + t.Log("Execution failed", hexutil.Encode(executionStateChanged.ReturnData)) + t.Fail() + } +} + +func GetEVMExtraArgsV1(gasLimit *big.Int, strict bool) ([]byte, error) { + EVMV1Tag := []byte{0x97, 0xa6, 0x57, 0xc9} + + encodedArgs, err := utils.ABIEncode(`[{"type":"uint256"},{"type":"bool"}]`, gasLimit, strict) + if err != nil { + return nil, err + } + + return append(EVMV1Tag, encodedArgs...), nil +} + +type ManualExecArgs struct { + SourceChainID, DestChainID uint64 + DestUser *bind.TransactOpts + SourceChain, DestChain bind.ContractBackend + SourceStartBlock *big.Int // the block in/after which failed ccip-send transaction was triggered + DestStartBlock uint64 // the start block for filtering ReportAccepted event (including the failed seq num) + // in destination chain. if not provided to be derived by ApproxDestStartBlock method + DestLatestBlockNum uint64 // current block number in destination + DestDeployedAt uint64 // destination block number for the initial destination contract deployment. + // Can be any number before the tx was reverted in destination chain. Preferably this needs to be set up with + // a value greater than zero to avoid performance issue in locating approximate destination block + SendReqLogIndex uint // log index of the CCIPSendRequested log in source chain + SendReqTxHash string // tx hash of the ccip-send transaction for which execution was reverted + CommitStore string + OnRamp string + OffRamp string + SeqNr uint64 + GasLimit *big.Int +} + +// ApproxDestStartBlock attempts to locate a block in destination chain with timestamp closest to the timestamp of the block +// in source chain in which ccip-send transaction was included +// it uses binary search to locate the block with the closest timestamp +// if the block located has a timestamp greater than the timestamp of mentioned source block +// it just returns the first block found with lesser timestamp of the source block +// providing a value of args.DestDeployedAt ensures better performance by reducing the range of block numbers to be traversed +func (args *ManualExecArgs) ApproxDestStartBlock() error { + sourceBlockHdr, err := args.SourceChain.HeaderByNumber(context.Background(), args.SourceStartBlock) + if err != nil { + return err + } + sendTxTime := sourceBlockHdr.Time + maxBlockNum := args.DestLatestBlockNum + // setting this to an approx value of 1000 considering destination chain would have at least 1000 blocks before the transaction started + minBlockNum := args.DestDeployedAt + closestBlockNum := uint64(math.Floor((float64(maxBlockNum) + float64(minBlockNum)) / 2)) + var closestBlockHdr *types.Header + closestBlockHdr, err = args.DestChain.HeaderByNumber(context.Background(), big.NewInt(int64(closestBlockNum))) + if err != nil { + return err + } + // to reduce the number of RPC calls increase the value of blockOffset + blockOffset := uint64(10) + for { + blockNum := closestBlockHdr.Number.Uint64() + if minBlockNum > maxBlockNum { + break + } + timeDiff := math.Abs(float64(closestBlockHdr.Time - sendTxTime)) + // break if the difference in timestamp is lesser than 1 minute + if timeDiff < 60 { + break + } else if closestBlockHdr.Time > sendTxTime { + maxBlockNum = blockNum - 1 + } else { + minBlockNum = blockNum + 1 + } + closestBlockNum = uint64(math.Floor((float64(maxBlockNum) + float64(minBlockNum)) / 2)) + closestBlockHdr, err = args.DestChain.HeaderByNumber(context.Background(), big.NewInt(int64(closestBlockNum))) + if err != nil { + return err + } + } + + for closestBlockHdr.Time > sendTxTime { + closestBlockNum = closestBlockNum - blockOffset + if closestBlockNum <= 0 { + return fmt.Errorf("approx destination blocknumber not found") + } + closestBlockHdr, err = args.DestChain.HeaderByNumber(context.Background(), big.NewInt(int64(closestBlockNum))) + if err != nil { + return err + } + } + args.DestStartBlock = closestBlockHdr.Number.Uint64() + fmt.Println("using approx destination start block number", args.DestStartBlock) + return nil +} + +func (args *ManualExecArgs) FindSeqNrFromCCIPSendRequested() (uint64, error) { + var seqNr uint64 + onRampContract, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(common.HexToAddress(args.OnRamp), args.SourceChain) + if err != nil { + return seqNr, err + } + iterator, err := onRampContract.FilterCCIPSendRequested(&bind.FilterOpts{ + Start: args.SourceStartBlock.Uint64(), + }) + if err != nil { + return seqNr, err + } + for iterator.Next() { + if iterator.Event.Raw.Index == args.SendReqLogIndex && + iterator.Event.Raw.TxHash.Hex() == args.SendReqTxHash { + seqNr = iterator.Event.Message.SequenceNumber + break + } + } + if seqNr == 0 { + return seqNr, + fmt.Errorf("no CCIPSendRequested logs found for logIndex %d starting from block number %d", args.SendReqLogIndex, args.SourceStartBlock) + } + return seqNr, nil +} + +func (args *ManualExecArgs) ExecuteManually() (*types.Transaction, error) { + if args.SourceChainID == 0 || + args.DestChainID == 0 || + args.DestUser == nil { + return nil, fmt.Errorf("chain ids and owners are mandatory for source and dest chain") + } + if !common.IsHexAddress(args.CommitStore) || + !common.IsHexAddress(args.OffRamp) || + !common.IsHexAddress(args.OnRamp) { + return nil, fmt.Errorf("contract addresses must be valid hex address") + } + if args.SendReqTxHash == "" { + return nil, fmt.Errorf("tx hash of ccip-send request are required") + } + if args.SourceStartBlock == nil { + return nil, fmt.Errorf("must provide the value of source block in/after which ccip-send tx was included") + } + if args.SeqNr == 0 { + if args.SendReqLogIndex == 0 { + return nil, fmt.Errorf("must provide the value of log index of ccip-send request") + } + // locate seq nr from CCIPSendRequested log + seqNr, err := args.FindSeqNrFromCCIPSendRequested() + if err != nil { + return nil, err + } + args.SeqNr = seqNr + } + commitStore, err := commit_store_1_2_0.NewCommitStore(common.HexToAddress(args.CommitStore), args.DestChain) + if err != nil { + return nil, err + } + if args.DestStartBlock < 1 { + err = args.ApproxDestStartBlock() + if err != nil { + return nil, err + } + } + iterator, err := commitStore.FilterReportAccepted(&bind.FilterOpts{Start: args.DestStartBlock}) + if err != nil { + return nil, err + } + + var commitReport *commit_store_1_2_0.CommitStoreCommitReport + for iterator.Next() { + if iterator.Event.Report.Interval.Min <= args.SeqNr && iterator.Event.Report.Interval.Max >= args.SeqNr { + commitReport = &iterator.Event.Report + fmt.Println("Found root") + break + } + } + if commitReport == nil { + return nil, fmt.Errorf("unable to find seq num %d in commit report", args.SeqNr) + } + + return args.execute(commitReport) +} + +func (args *ManualExecArgs) execute(report *commit_store_1_2_0.CommitStoreCommitReport) (*types.Transaction, error) { + log.Info().Msg("Executing request manually") + seqNr := args.SeqNr + // Build a merkle tree for the report + mctx := hashutil.NewKeccak() + onRampContract, err := evm_2_evm_onramp_1_2_0.NewEVM2EVMOnRamp(common.HexToAddress(args.OnRamp), args.SourceChain) + if err != nil { + return nil, err + } + leafHasher := v1_2_0.NewLeafHasher(args.SourceChainID, args.DestChainID, common.HexToAddress(args.OnRamp), mctx, onRampContract) + if leafHasher == nil { + return nil, fmt.Errorf("unable to create leaf hasher") + } + + var leaves [][32]byte + var curr, prove int + var msgs []evm_2_evm_offramp.InternalEVM2EVMMessage + var manualExecGasLimits []*big.Int + var tokenData [][][]byte + sendRequestedIterator, err := onRampContract.FilterCCIPSendRequested(&bind.FilterOpts{ + Start: args.SourceStartBlock.Uint64(), + }) + if err != nil { + return nil, err + } + for sendRequestedIterator.Next() { + if sendRequestedIterator.Event.Message.SequenceNumber <= report.Interval.Max && + sendRequestedIterator.Event.Message.SequenceNumber >= report.Interval.Min { + fmt.Println("Found seq num", sendRequestedIterator.Event.Message.SequenceNumber, report.Interval) + hash, err2 := leafHasher.HashLeaf(sendRequestedIterator.Event.Raw) + if err2 != nil { + return nil, err2 + } + leaves = append(leaves, hash) + if sendRequestedIterator.Event.Message.SequenceNumber == seqNr { + fmt.Printf("Found proving %d %+v\n", curr, sendRequestedIterator.Event.Message) + var tokensAndAmounts []evm_2_evm_offramp.ClientEVMTokenAmount + for _, tokenAndAmount := range sendRequestedIterator.Event.Message.TokenAmounts { + tokensAndAmounts = append(tokensAndAmounts, evm_2_evm_offramp.ClientEVMTokenAmount{ + Token: tokenAndAmount.Token, + Amount: tokenAndAmount.Amount, + }) + } + msg := evm_2_evm_offramp.InternalEVM2EVMMessage{ + SourceChainSelector: sendRequestedIterator.Event.Message.SourceChainSelector, + Sender: sendRequestedIterator.Event.Message.Sender, + Receiver: sendRequestedIterator.Event.Message.Receiver, + SequenceNumber: sendRequestedIterator.Event.Message.SequenceNumber, + GasLimit: sendRequestedIterator.Event.Message.GasLimit, + Strict: sendRequestedIterator.Event.Message.Strict, + Nonce: sendRequestedIterator.Event.Message.Nonce, + FeeToken: sendRequestedIterator.Event.Message.FeeToken, + FeeTokenAmount: sendRequestedIterator.Event.Message.FeeTokenAmount, + Data: sendRequestedIterator.Event.Message.Data, + TokenAmounts: tokensAndAmounts, + SourceTokenData: sendRequestedIterator.Event.Message.SourceTokenData, + MessageId: sendRequestedIterator.Event.Message.MessageId, + } + msgs = append(msgs, msg) + if args.GasLimit != nil { + msg.GasLimit = args.GasLimit + } + manualExecGasLimits = append(manualExecGasLimits, msg.GasLimit) + var msgTokenData [][]byte + for range sendRequestedIterator.Event.Message.TokenAmounts { + msgTokenData = append(msgTokenData, []byte{}) + } + + tokenData = append(tokenData, msgTokenData) + prove = curr + } + curr++ + } + } + sendRequestedIterator.Close() + if msgs == nil { + return nil, fmt.Errorf("unable to find msg with seqNr %d", seqNr) + } + tree, err := merklemulti.NewTree(mctx, leaves) + if err != nil { + return nil, err + } + if tree.Root() != report.MerkleRoot { + return nil, fmt.Errorf("root doesn't match") + } + + proof, err := tree.Prove([]int{prove}) + if err != nil { + return nil, err + } + + offRampProof := evm_2_evm_offramp.InternalExecutionReport{ + Messages: msgs, + OffchainTokenData: tokenData, + Proofs: proof.Hashes, + ProofFlagBits: abihelpers.ProofFlagsToBits(proof.SourceFlags), + } + offRamp, err := evm_2_evm_offramp.NewEVM2EVMOffRamp(common.HexToAddress(args.OffRamp), args.DestChain) + if err != nil { + return nil, err + } + // Execute. + return offRamp.ManuallyExecute(args.DestUser, offRampProof, manualExecGasLimits) +} + +func (c *CCIPContracts) ExecuteMessage( + t *testing.T, + req logpoller.Log, + txHash common.Hash, + destStartBlock uint64, +) uint64 { + t.Log("Executing request manually") + sendReqReceipt, err := c.Source.Chain.TransactionReceipt(context.Background(), txHash) + require.NoError(t, err) + args := ManualExecArgs{ + SourceChainID: c.Source.ChainID, + DestChainID: c.Dest.ChainID, + DestUser: c.Dest.User, + SourceChain: c.Source.Chain, + DestChain: c.Dest.Chain, + SourceStartBlock: sendReqReceipt.BlockNumber, + DestStartBlock: destStartBlock, + DestLatestBlockNum: c.Dest.Chain.Blockchain().CurrentBlock().Number.Uint64(), + SendReqLogIndex: uint(req.LogIndex), + SendReqTxHash: txHash.String(), + CommitStore: c.Dest.CommitStore.Address().String(), + OnRamp: c.Source.OnRamp.Address().String(), + OffRamp: c.Dest.OffRamp.Address().String(), + } + tx, err := args.ExecuteManually() + require.NoError(t, err) + c.Dest.Chain.Commit() + c.Source.Chain.Commit() + rec, err := c.Dest.Chain.TransactionReceipt(context.Background(), tx.Hash()) + require.NoError(t, err) + require.Equal(t, uint64(1), rec.Status, "manual execution failed") + t.Logf("Manual Execution completed for seqNum %d", args.SeqNr) + return args.SeqNr +} + +func GetBalance(t *testing.T, chain bind.ContractBackend, tokenAddr common.Address, addr common.Address) *big.Int { + token, err := link_token_interface.NewLinkToken(tokenAddr, chain) + require.NoError(t, err) + bal, err := token.BalanceOf(nil, addr) + require.NoError(t, err) + return bal +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go new file mode 100644 index 0000000000..25be1c2a9a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go @@ -0,0 +1,1045 @@ +package testhelpers_1_4_0 + +import ( + "context" + "encoding/hex" + "fmt" + "math/big" + "net/http" + "net/http/httptest" + "strconv" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + types3 "github.com/ethereum/go-ethereum/core/types" + "github.com/google/uuid" + "github.com/hashicorp/consul/sdk/freeport" + "github.com/jmoiron/sqlx" + "github.com/onsi/gomega" + "github.com/pkg/errors" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "k8s.io/utils/pointer" //nolint:staticcheck + + "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" + types4 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core/mocks" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + v2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + evmUtils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + configv2 "github.com/smartcontractkit/chainlink/v2/core/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/logger/audit" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + feeds2 "github.com/smartcontractkit/chainlink/v2/core/services/feeds" + feedsMocks "github.com/smartcontractkit/chainlink/v2/core/services/feeds/mocks" + pb "github.com/smartcontractkit/chainlink/v2/core/services/feeds/proto" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + ksMocks "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" + integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/integration" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + clutils "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" + "github.com/smartcontractkit/chainlink/v2/plugins" +) + +const ( + execSpecTemplate = ` + type = "offchainreporting2" + schemaVersion = 1 + name = "ccip-exec-1" + externalJobID = "67ffad71-d90f-4fe3-b4e4-494924b707fb" + forwardingAllowed = false + maxTaskDuration = "0s" + contractID = "%s" + contractConfigConfirmations = 1 + contractConfigTrackerPollInterval = "20s" + ocrKeyBundleID = "%s" + relay = "evm" + pluginType = "ccip-execution" + transmitterID = "%s" + + [relayConfig] + chainID = 1_337 + + [pluginConfig] + destStartBlock = 50 + + [pluginConfig.USDCConfig] + AttestationAPI = "http://blah.com" + SourceMessageTransmitterAddress = "%s" + SourceTokenAddress = "%s" + AttestationAPITimeoutSeconds = 10 + ` + commitSpecTemplatePipeline = ` + type = "offchainreporting2" + schemaVersion = 1 + name = "ccip-commit-1" + externalJobID = "13c997cf-1a14-4ab7-9068-07ee6d2afa55" + forwardingAllowed = false + maxTaskDuration = "0s" + contractID = "%s" + contractConfigConfirmations = 1 + contractConfigTrackerPollInterval = "20s" + ocrKeyBundleID = "%s" + relay = "evm" + pluginType = "ccip-commit" + transmitterID = "%s" + + [relayConfig] + chainID = 1_337 + + [pluginConfig] + destStartBlock = 50 + offRamp = "%s" + tokenPricesUSDPipeline = """ + %s + """ + ` + commitSpecTemplateDynamicPriceGetter = ` + type = "offchainreporting2" + schemaVersion = 1 + name = "ccip-commit-1" + externalJobID = "13c997cf-1a14-4ab7-9068-07ee6d2afa55" + forwardingAllowed = false + maxTaskDuration = "0s" + contractID = "%s" + contractConfigConfirmations = 1 + contractConfigTrackerPollInterval = "20s" + ocrKeyBundleID = "%s" + relay = "evm" + pluginType = "ccip-commit" + transmitterID = "%s" + + [relayConfig] + chainID = 1_337 + + [pluginConfig] + destStartBlock = 50 + offRamp = "%s" + priceGetterConfig = """ + %s + """ + ` +) + +type Node struct { + App chainlink.Application + Transmitter common.Address + PaymentReceiver common.Address + KeyBundle ocr2key.KeyBundle +} + +func (node *Node) FindJobIDForContract(t *testing.T, addr common.Address) int32 { + jobs := node.App.JobSpawner().ActiveJobs() + for _, j := range jobs { + if j.Type == job.OffchainReporting2 && j.OCR2OracleSpec.ContractID == addr.Hex() { + return j.ID + } + } + t.Fatalf("Could not find job for contract %s", addr.Hex()) + return 0 +} + +func (node *Node) EventuallyNodeUsesUpdatedPriceRegistry(t *testing.T, ccipContracts CCIPIntegrationTestHarness) logpoller.Log { + c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) + require.NoError(t, err) + var log logpoller.Log + gomega.NewGomegaWithT(t).Eventually(func() bool { + ccipContracts.Source.Chain.Commit() + ccipContracts.Dest.Chain.Commit() + log, err := c.LogPoller().LatestLogByEventSigWithConfs( + testutils.Context(t), + v1_0_0.UsdPerUnitGasUpdated, + ccipContracts.Dest.PriceRegistry.Address(), + 0, + ) + // err can be transient errors such as sql row set empty + if err != nil { + return false + } + return log != nil + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "node is not using updated price registry %s", ccipContracts.Dest.PriceRegistry.Address().Hex()) + return log +} + +func (node *Node) EventuallyNodeUsesNewCommitConfig(t *testing.T, ccipContracts CCIPIntegrationTestHarness, commitCfg ccipdata.CommitOnchainConfig) logpoller.Log { + c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) + require.NoError(t, err) + var log logpoller.Log + gomega.NewGomegaWithT(t).Eventually(func() bool { + ccipContracts.Source.Chain.Commit() + ccipContracts.Dest.Chain.Commit() + log, err := c.LogPoller().LatestLogByEventSigWithConfs( + testutils.Context(t), + evmrelay.OCR2AggregatorLogDecoder.EventSig(), + ccipContracts.Dest.CommitStore.Address(), + 0, + ) + require.NoError(t, err) + var latestCfg ccipdata.CommitOnchainConfig + if log != nil { + latestCfg, err = DecodeCommitOnChainConfig(log.Data) + require.NoError(t, err) + return latestCfg == commitCfg + } + return false + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "node is using old cfg") + return log +} + +func (node *Node) EventuallyNodeUsesNewExecConfig(t *testing.T, ccipContracts CCIPIntegrationTestHarness, execCfg v1_2_0.ExecOnchainConfig) logpoller.Log { + c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) + require.NoError(t, err) + var log logpoller.Log + gomega.NewGomegaWithT(t).Eventually(func() bool { + ccipContracts.Source.Chain.Commit() + ccipContracts.Dest.Chain.Commit() + log, err := c.LogPoller().LatestLogByEventSigWithConfs( + testutils.Context(t), + evmrelay.OCR2AggregatorLogDecoder.EventSig(), + ccipContracts.Dest.OffRamp.Address(), + 0, + ) + require.NoError(t, err) + var latestCfg v1_2_0.ExecOnchainConfig + if log != nil { + latestCfg, err = DecodeExecOnChainConfig(log.Data) + require.NoError(t, err) + return latestCfg == execCfg + } + return false + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "node is using old cfg") + return log +} + +func (node *Node) EventuallyHasReqSeqNum(t *testing.T, ccipContracts *CCIPIntegrationTestHarness, onRamp common.Address, seqNum int) logpoller.Log { + c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Source.ChainID, 10)) + require.NoError(t, err) + var log logpoller.Log + gomega.NewGomegaWithT(t).Eventually(func() bool { + ccipContracts.Source.Chain.Commit() + ccipContracts.Dest.Chain.Commit() + lgs, err := c.LogPoller().LogsDataWordRange( + testutils.Context(t), + v1_2_0.CCIPSendRequestEventSig, + onRamp, + v1_2_0.CCIPSendRequestSeqNumIndex, + abihelpers.EvmWord(uint64(seqNum)), + abihelpers.EvmWord(uint64(seqNum)), + 1, + ) + require.NoError(t, err) + t.Log("Send requested", len(lgs)) + if len(lgs) == 1 { + log = lgs[0] + return true + } + return false + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "eventually has seq num") + return log +} + +func (node *Node) EventuallyHasExecutedSeqNums(t *testing.T, ccipContracts *CCIPIntegrationTestHarness, offRamp common.Address, minSeqNum int, maxSeqNum int) []logpoller.Log { + c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) + require.NoError(t, err) + var logs []logpoller.Log + gomega.NewGomegaWithT(t).Eventually(func() bool { + ccipContracts.Source.Chain.Commit() + ccipContracts.Dest.Chain.Commit() + lgs, err := c.LogPoller().IndexedLogsTopicRange( + testutils.Context(t), + v1_0_0.ExecutionStateChangedEvent, + offRamp, + v1_0_0.ExecutionStateChangedSeqNrIndex, + abihelpers.EvmWord(uint64(minSeqNum)), + abihelpers.EvmWord(uint64(maxSeqNum)), + 1, + ) + require.NoError(t, err) + t.Logf("Have executed logs %d want %d", len(lgs), maxSeqNum-minSeqNum+1) + if len(lgs) == maxSeqNum-minSeqNum+1 { + logs = lgs + t.Logf("Seq Num %d-%d executed", minSeqNum, maxSeqNum) + return true + } + return false + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "eventually has not executed seq num") + return logs +} + +func (node *Node) ConsistentlySeqNumHasNotBeenExecuted(t *testing.T, ccipContracts *CCIPIntegrationTestHarness, offRamp common.Address, seqNum int) logpoller.Log { + c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) + require.NoError(t, err) + var log logpoller.Log + gomega.NewGomegaWithT(t).Consistently(func() bool { + ccipContracts.Source.Chain.Commit() + ccipContracts.Dest.Chain.Commit() + lgs, err := c.LogPoller().IndexedLogsTopicRange( + testutils.Context(t), + v1_0_0.ExecutionStateChangedEvent, + offRamp, + v1_0_0.ExecutionStateChangedSeqNrIndex, + abihelpers.EvmWord(uint64(seqNum)), + abihelpers.EvmWord(uint64(seqNum)), + 1, + ) + require.NoError(t, err) + t.Log("Executed logs", lgs) + if len(lgs) == 1 { + log = lgs[0] + return true + } + return false + }, 10*time.Second, 1*time.Second).Should(gomega.BeFalse(), "seq number got executed") + return log +} + +func (node *Node) AddJob(t *testing.T, spec *integrationtesthelpers.OCR2TaskJobSpec) { + specString, err := spec.String() + require.NoError(t, err) + ccipJob, err := validate.ValidatedOracleSpecToml( + testutils.Context(t), + node.App.GetConfig().OCR2(), + node.App.GetConfig().Insecure(), + specString, + // FIXME Ani + nil, + ) + require.NoError(t, err) + err = node.App.AddJobV2(context.Background(), &ccipJob) + require.NoError(t, err) +} + +func (node *Node) AddBootstrapJob(t *testing.T, spec *integrationtesthelpers.OCR2TaskJobSpec) { + specString, err := spec.String() + require.NoError(t, err) + ccipJob, err := ocrbootstrap.ValidatedBootstrapSpecToml(specString) + require.NoError(t, err) + err = node.App.AddJobV2(context.Background(), &ccipJob) + require.NoError(t, err) +} + +func (node *Node) AddJobsWithSpec(t *testing.T, jobSpec *integrationtesthelpers.OCR2TaskJobSpec) { + // set node specific values + jobSpec.OCR2OracleSpec.OCRKeyBundleID.SetValid(node.KeyBundle.ID()) + jobSpec.OCR2OracleSpec.TransmitterID.SetValid(node.Transmitter.Hex()) + node.AddJob(t, jobSpec) +} + +func setupNodeCCIP( + t *testing.T, + owner *bind.TransactOpts, + port int64, + dbName string, + sourceChain *backends.SimulatedBackend, destChain *backends.SimulatedBackend, + sourceChainID *big.Int, destChainID *big.Int, + bootstrapPeerID string, + bootstrapPort int64, +) (chainlink.Application, string, common.Address, ocr2key.KeyBundle) { + trueRef, falseRef := true, false + + // Do not want to load fixtures as they contain a dummy chainID. + loglevel := configv2.LogLevel(zap.DebugLevel) + config, db := heavyweight.FullTestDBNoFixturesV2(t, func(c *chainlink.Config, _ *chainlink.Secrets) { + p2pAddresses := []string{ + fmt.Sprintf("127.0.0.1:%d", port), + } + c.Log.Level = &loglevel + c.Feature.UICSAKeys = &trueRef + c.Feature.FeedsManager = &trueRef + c.OCR.Enabled = &falseRef + c.OCR.DefaultTransactionQueueDepth = pointer.Uint32(200) + c.OCR2.Enabled = &trueRef + c.Feature.LogPoller = &trueRef + c.P2P.V2.Enabled = &trueRef + + dur, err := config.NewDuration(500 * time.Millisecond) + if err != nil { + panic(err) + } + c.P2P.V2.DeltaDial = &dur + + dur2, err := config.NewDuration(5 * time.Second) + if err != nil { + panic(err) + } + + c.P2P.V2.DeltaReconcile = &dur2 + c.P2P.V2.ListenAddresses = &p2pAddresses + c.P2P.V2.AnnounceAddresses = &p2pAddresses + + c.EVM = []*v2.EVMConfig{createConfigV2Chain(sourceChainID), createConfigV2Chain(destChainID)} + + if bootstrapPeerID != "" { + // Supply the bootstrap IP and port as a V2 peer address + c.P2P.V2.DefaultBootstrappers = &[]commontypes.BootstrapperLocator{ + { + PeerID: bootstrapPeerID, Addrs: []string{ + fmt.Sprintf("127.0.0.1:%d", bootstrapPort), + }, + }, + } + } + }) + + lggr := logger.TestLogger(t) + + // The in-memory geth sim does not let you create a custom ChainID, it will always be 1337. + // In particular this means that if you sign an eip155 tx, the chainID used MUST be 1337 + // and the CHAINID op code will always emit 1337. To work around this to simulate a "multichain" + // test, we fake different chainIDs using the wrapped sim cltest.SimulatedBackend so the RPC + // appears to operate on different chainIDs and we use an EthKeyStoreSim wrapper which always + // signs 1337 see https://github.com/smartcontractkit/chainlink-ccip/blob/a24dd436810250a458d27d8bb3fb78096afeb79c/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go#L35 + sourceClient := client.NewSimulatedBackendClient(t, sourceChain, sourceChainID) + destClient := client.NewSimulatedBackendClient(t, destChain, destChainID) + csaKeyStore := ksMocks.NewCSA(t) + + key, err := csakey.NewV2() + require.NoError(t, err) + csaKeyStore.On("GetAll").Return([]csakey.KeyV2{key}, nil) + keyStore := NewKsa(db, lggr, csaKeyStore) + + simEthKeyStore := testhelpers.EthKeyStoreSim{ + ETHKS: keyStore.Eth(), + CSAKS: keyStore.CSA(), + } + mailMon := mailbox.NewMonitor("CCIP", lggr.Named("Mailbox")) + evmOpts := chainlink.EVMFactoryConfig{ + ChainOpts: legacyevm.ChainOpts{ + AppConfig: config, + GenEthClient: func(chainID *big.Int) client.Client { + if chainID.String() == sourceChainID.String() { + return sourceClient + } else if chainID.String() == destChainID.String() { + return destClient + } + t.Fatalf("invalid chain ID %v", chainID.String()) + return nil + }, + MailMon: mailMon, + DS: db, + }, + CSAETHKeystore: simEthKeyStore, + } + loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing()) + relayerFactory := chainlink.RelayerFactory{ + Logger: lggr, + LoopRegistry: loopRegistry, + GRPCOpts: loop.GRPCOpts{}, + CapabilitiesRegistry: coretypes.NewCapabilitiesRegistry(t), + } + testCtx := testutils.Context(t) + // evm alway enabled for backward compatibility + initOps := []chainlink.CoreRelayerChainInitFunc{ + chainlink.InitEVM(testCtx, relayerFactory, evmOpts), + } + + relayChainInterops, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) + if err != nil { + t.Fatal(err) + } + + app, err := chainlink.NewApplication(chainlink.ApplicationOpts{ + Config: config, + DS: db, + KeyStore: keyStore, + RelayerChainInteroperators: relayChainInterops, + Logger: lggr, + ExternalInitiatorManager: nil, + CloseLogger: lggr.Sync, + UnrestrictedHTTPClient: &http.Client{}, + RestrictedHTTPClient: &http.Client{}, + AuditLogger: audit.NoopLogger, + MailMon: mailMon, + LoopRegistry: plugins.NewLoopRegistry(lggr, config.Tracing()), + }) + ctx := testutils.Context(t) + require.NoError(t, err) + require.NoError(t, app.GetKeyStore().Unlock(ctx, "password")) + _, err = app.GetKeyStore().P2P().Create(ctx) + require.NoError(t, err) + + p2pIDs, err := app.GetKeyStore().P2P().GetAll() + require.NoError(t, err) + require.Len(t, p2pIDs, 1) + peerID := p2pIDs[0].PeerID() + + _, err = app.GetKeyStore().Eth().Create(testCtx, destChainID) + require.NoError(t, err) + sendingKeys, err := app.GetKeyStore().Eth().EnabledKeysForChain(testCtx, destChainID) + require.NoError(t, err) + require.Len(t, sendingKeys, 1) + transmitter := sendingKeys[0].Address + s, err := app.GetKeyStore().Eth().GetState(testCtx, sendingKeys[0].ID(), destChainID) + require.NoError(t, err) + lggr.Debug(fmt.Sprintf("Transmitter address %s chainID %s", transmitter, s.EVMChainID.String())) + + // Fund the commitTransmitter address with some ETH + n, err := destChain.NonceAt(context.Background(), owner.From, nil) + require.NoError(t, err) + + tx := types3.NewTransaction(n, transmitter, big.NewInt(1000000000000000000), 21000, big.NewInt(1000000000), nil) + signedTx, err := owner.Signer(owner.From, tx) + require.NoError(t, err) + err = destChain.SendTransaction(context.Background(), signedTx) + require.NoError(t, err) + destChain.Commit() + + kb, err := app.GetKeyStore().OCR2().Create(ctx, chaintype.EVM) + require.NoError(t, err) + return app, peerID.Raw(), transmitter, kb +} + +func createConfigV2Chain(chainId *big.Int) *v2.EVMConfig { + // NOTE: For the executor jobs, the default of 500k is insufficient for a 3 message batch + defaultGasLimit := uint64(5000000) + tr := true + + sourceC := v2.Defaults((*evmUtils.Big)(chainId)) + sourceC.GasEstimator.LimitDefault = &defaultGasLimit + fixedPrice := "FixedPrice" + sourceC.GasEstimator.Mode = &fixedPrice + d, _ := config.NewDuration(100 * time.Millisecond) + sourceC.LogPollInterval = &d + fd := uint32(2) + sourceC.FinalityDepth = &fd + return &v2.EVMConfig{ + ChainID: (*evmUtils.Big)(chainId), + Enabled: &tr, + Chain: sourceC, + Nodes: v2.EVMNodes{&v2.Node{}}, + } +} + +type CCIPIntegrationTestHarness struct { + CCIPContracts + Nodes []Node + Bootstrap Node +} + +func SetupCCIPIntegrationTH(t *testing.T, sourceChainID, sourceChainSelector, destChainId, destChainSelector uint64) CCIPIntegrationTestHarness { + return CCIPIntegrationTestHarness{ + CCIPContracts: SetupCCIPContracts(t, sourceChainID, sourceChainSelector, destChainId, destChainSelector), + } +} + +func (c *CCIPIntegrationTestHarness) CreatePricesPipeline(t *testing.T) (string, *httptest.Server, *httptest.Server) { + linkUSD := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, err := w.Write([]byte(`{"UsdPerLink": "8000000000000000000"}`)) + require.NoError(t, err) + })) + ethUSD := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, err := w.Write([]byte(`{"UsdPerETH": "1700000000000000000000"}`)) + require.NoError(t, err) + })) + sourceWrappedNative, err := c.Source.Router.GetWrappedNative(nil) + require.NoError(t, err) + destWrappedNative, err := c.Dest.Router.GetWrappedNative(nil) + require.NoError(t, err) + tokenPricesUSDPipeline := fmt.Sprintf(` +// Price 1 +link [type=http method=GET url="%s"]; +link_parse [type=jsonparse path="UsdPerLink"]; +link->link_parse; +eth [type=http method=GET url="%s"]; +eth_parse [type=jsonparse path="UsdPerETH"]; +eth->eth_parse; +merge [type=merge left="{}" right="{\\\"%s\\\":$(link_parse), \\\"%s\\\":$(eth_parse), \\\"%s\\\":$(eth_parse)}"];`, + linkUSD.URL, ethUSD.URL, c.Dest.LinkToken.Address(), sourceWrappedNative, destWrappedNative) + + return tokenPricesUSDPipeline, linkUSD, ethUSD +} + +func (c *CCIPIntegrationTestHarness) AddAllJobs(t *testing.T, jobParams integrationtesthelpers.CCIPJobSpecParams) { + jobParams.OffRamp = c.Dest.OffRamp.Address() + + commitSpec, err := jobParams.CommitJobSpec() + require.NoError(t, err) + geExecutionSpec, err := jobParams.ExecutionJobSpec() + require.NoError(t, err) + nodes := c.Nodes + for _, node := range nodes { + node.AddJobsWithSpec(t, commitSpec) + node.AddJobsWithSpec(t, geExecutionSpec) + } +} + +func (c *CCIPIntegrationTestHarness) jobSpecProposal(t *testing.T, specTemplate string, f func() (*integrationtesthelpers.OCR2TaskJobSpec, error), feedsManagerId int64, version int32, opts ...any) feeds2.ProposeJobArgs { + spec, err := f() + require.NoError(t, err) + + args := []any{spec.OCR2OracleSpec.ContractID} + args = append(args, opts...) + + return feeds2.ProposeJobArgs{ + FeedsManagerID: feedsManagerId, + RemoteUUID: uuid.New(), + Multiaddrs: nil, + Version: version, + Spec: fmt.Sprintf(specTemplate, args...), + } +} + +func (c *CCIPIntegrationTestHarness) SetupFeedsManager(t *testing.T) { + ctx := testutils.Context(t) + for _, node := range c.Nodes { + f := node.App.GetFeedsService() + + managers, err := f.ListManagers(ctx) + require.NoError(t, err) + if len(managers) > 0 { + // Use at most one feeds manager, don't register if one already exists + continue + } + + secret := utils.RandomBytes32() + pkey, err := crypto.PublicKeyFromHex(hex.EncodeToString(secret[:])) + require.NoError(t, err) + + m := feeds2.RegisterManagerParams{ + Name: "CCIP", + URI: "http://localhost:8080", + PublicKey: *pkey, + } + + _, err = f.RegisterManager(testutils.Context(t), m) + require.NoError(t, err) + + connManager := feedsMocks.NewConnectionsManager(t) + connManager.On("GetClient", mock.Anything).Maybe().Return(NoopFeedsClient{}, nil) + connManager.On("Close").Maybe().Return() + connManager.On("IsConnected", mock.Anything).Maybe().Return(true) + f.Unsafe_SetConnectionsManager(connManager) + } +} + +func (c *CCIPIntegrationTestHarness) ApproveJobSpecs(t *testing.T, jobParams integrationtesthelpers.CCIPJobSpecParams) { + ctx := testutils.Context(t) + + for _, node := range c.Nodes { + f := node.App.GetFeedsService() + managers, err := f.ListManagers(ctx) + require.NoError(t, err) + require.Len(t, managers, 1, "expected exactly one feeds manager") + + execSpec := c.jobSpecProposal( + t, + execSpecTemplate, + jobParams.ExecutionJobSpec, + managers[0].ID, + 1, + node.KeyBundle.ID(), + node.Transmitter.Hex(), + utils.RandomAddress().String(), + utils.RandomAddress().String(), + ) + execId, err := f.ProposeJob(ctx, &execSpec) + require.NoError(t, err) + + err = f.ApproveSpec(ctx, execId, true) + require.NoError(t, err) + + var commitSpec feeds2.ProposeJobArgs + if jobParams.TokenPricesUSDPipeline != "" { + commitSpec = c.jobSpecProposal( + t, + commitSpecTemplatePipeline, + jobParams.CommitJobSpec, + managers[0].ID, + 2, + node.KeyBundle.ID(), + node.Transmitter.Hex(), + jobParams.OffRamp.String(), + jobParams.TokenPricesUSDPipeline, + ) + } else { + commitSpec = c.jobSpecProposal( + t, + commitSpecTemplateDynamicPriceGetter, + jobParams.CommitJobSpec, + managers[0].ID, + 2, + node.KeyBundle.ID(), + node.Transmitter.Hex(), + jobParams.OffRamp.String(), + jobParams.PriceGetterConfig, + ) + } + + commitId, err := f.ProposeJob(ctx, &commitSpec) + require.NoError(t, err) + + err = f.ApproveSpec(ctx, commitId, true) + require.NoError(t, err) + } +} + +func (c *CCIPIntegrationTestHarness) AllNodesHaveReqSeqNum(t *testing.T, seqNum int, onRampOpts ...common.Address) logpoller.Log { + var log logpoller.Log + nodes := c.Nodes + var onRamp common.Address + if len(onRampOpts) > 0 { + onRamp = onRampOpts[0] + } else { + require.NotNil(t, c.Source.OnRamp, "no onramp configured") + onRamp = c.Source.OnRamp.Address() + } + for _, node := range nodes { + log = node.EventuallyHasReqSeqNum(t, c, onRamp, seqNum) + } + return log +} + +func (c *CCIPIntegrationTestHarness) AllNodesHaveExecutedSeqNums(t *testing.T, minSeqNum int, maxSeqNum int, offRampOpts ...common.Address) []logpoller.Log { + var logs []logpoller.Log + nodes := c.Nodes + var offRamp common.Address + + if len(offRampOpts) > 0 { + offRamp = offRampOpts[0] + } else { + require.NotNil(t, c.Dest.OffRamp, "no offramp configured") + offRamp = c.Dest.OffRamp.Address() + } + for _, node := range nodes { + logs = node.EventuallyHasExecutedSeqNums(t, c, offRamp, minSeqNum, maxSeqNum) + } + return logs +} + +func (c *CCIPIntegrationTestHarness) NoNodesHaveExecutedSeqNum(t *testing.T, seqNum int, offRampOpts ...common.Address) logpoller.Log { + var log logpoller.Log + nodes := c.Nodes + var offRamp common.Address + if len(offRampOpts) > 0 { + offRamp = offRampOpts[0] + } else { + require.NotNil(t, c.Dest.OffRamp, "no offramp configured") + offRamp = c.Dest.OffRamp.Address() + } + for _, node := range nodes { + log = node.ConsistentlySeqNumHasNotBeenExecuted(t, c, offRamp, seqNum) + } + return log +} + +func (c *CCIPIntegrationTestHarness) EventuallyCommitReportAccepted(t *testing.T, currentBlock uint64, commitStoreOpts ...common.Address) commit_store_1_2_0.CommitStoreCommitReport { + var commitStore *commit_store_1_2_0.CommitStore + var err error + if len(commitStoreOpts) > 0 { + commitStore, err = commit_store_1_2_0.NewCommitStore(commitStoreOpts[0], c.Dest.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Dest.CommitStore, "no commitStore configured") + commitStore = c.Dest.CommitStore + } + g := gomega.NewGomegaWithT(t) + var report commit_store_1_2_0.CommitStoreCommitReport + g.Eventually(func() bool { + it, err := commitStore.FilterReportAccepted(&bind.FilterOpts{Start: currentBlock}) + g.Expect(err).NotTo(gomega.HaveOccurred(), "Error filtering ReportAccepted event") + g.Expect(it.Next()).To(gomega.BeTrue(), "No ReportAccepted event found") + report = it.Event.Report + if report.MerkleRoot != [32]byte{} { + t.Log("Report Accepted by commitStore") + return true + } + return false + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "report has not been committed") + return report +} + +func (c *CCIPIntegrationTestHarness) EventuallyExecutionStateChangedToSuccess(t *testing.T, seqNum []uint64, blockNum uint64, offRampOpts ...common.Address) { + var offRamp *evm_2_evm_offramp_1_2_0.EVM2EVMOffRamp + var err error + if len(offRampOpts) > 0 { + offRamp, err = evm_2_evm_offramp_1_2_0.NewEVM2EVMOffRamp(offRampOpts[0], c.Dest.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Dest.OffRamp, "no offRamp configured") + offRamp = c.Dest.OffRamp + } + gomega.NewGomegaWithT(t).Eventually(func() bool { + it, err := offRamp.FilterExecutionStateChanged(&bind.FilterOpts{Start: blockNum}, seqNum, [][32]byte{}) + require.NoError(t, err) + for it.Next() { + if cciptypes.MessageExecutionState(it.Event.State) == cciptypes.ExecutionStateSuccess { + t.Logf("ExecutionStateChanged event found for seqNum %d", it.Event.SequenceNumber) + return true + } + } + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + return false + }, testutils.WaitTimeout(t), time.Second). + Should(gomega.BeTrue(), "ExecutionStateChanged Event") +} + +func (c *CCIPIntegrationTestHarness) EventuallyReportCommitted(t *testing.T, max int, commitStoreOpts ...common.Address) uint64 { + var commitStore *commit_store_1_2_0.CommitStore + var err error + var committedSeqNum uint64 + if len(commitStoreOpts) > 0 { + commitStore, err = commit_store_1_2_0.NewCommitStore(commitStoreOpts[0], c.Dest.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Dest.CommitStore, "no commitStore configured") + commitStore = c.Dest.CommitStore + } + gomega.NewGomegaWithT(t).Eventually(func() bool { + minSeqNum, err := commitStore.GetExpectedNextSequenceNumber(nil) + require.NoError(t, err) + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + t.Log("next expected seq num reported", minSeqNum) + committedSeqNum = minSeqNum + return minSeqNum > uint64(max) + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue(), "report has not been committed") + return committedSeqNum +} + +func (c *CCIPIntegrationTestHarness) EventuallySendRequested(t *testing.T, seqNum uint64, onRampOpts ...common.Address) { + var onRamp *evm_2_evm_onramp_1_2_0.EVM2EVMOnRamp + var err error + if len(onRampOpts) > 0 { + onRamp, err = evm_2_evm_onramp_1_2_0.NewEVM2EVMOnRamp(onRampOpts[0], c.Source.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Source.OnRamp, "no onRamp configured") + onRamp = c.Source.OnRamp + } + gomega.NewGomegaWithT(t).Eventually(func() bool { + it, err := onRamp.FilterCCIPSendRequested(nil) + require.NoError(t, err) + for it.Next() { + if it.Event.Message.SequenceNumber == seqNum { + t.Log("sendRequested generated for", seqNum) + return true + } + } + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + return false + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue(), "sendRequested has not been generated") +} + +func (c *CCIPIntegrationTestHarness) ConsistentlyReportNotCommitted(t *testing.T, max int, commitStoreOpts ...common.Address) { + var commitStore *commit_store_1_2_0.CommitStore + var err error + if len(commitStoreOpts) > 0 { + commitStore, err = commit_store_1_2_0.NewCommitStore(commitStoreOpts[0], c.Dest.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Dest.CommitStore, "no commitStore configured") + commitStore = c.Dest.CommitStore + } + gomega.NewGomegaWithT(t).Consistently(func() bool { + minSeqNum, err := commitStore.GetExpectedNextSequenceNumber(nil) + require.NoError(t, err) + c.Source.Chain.Commit() + c.Dest.Chain.Commit() + t.Log("min seq num reported", minSeqNum) + return minSeqNum > uint64(max) + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeFalse(), "report has been committed") +} + +func (c *CCIPIntegrationTestHarness) SetupAndStartNodes(ctx context.Context, t *testing.T, bootstrapNodePort int64) (Node, []Node, int64) { + appBootstrap, bootstrapPeerID, bootstrapTransmitter, bootstrapKb := setupNodeCCIP(t, c.Dest.User, bootstrapNodePort, + "bootstrap_ccip", c.Source.Chain, c.Dest.Chain, big.NewInt(0).SetUint64(c.Source.ChainID), + big.NewInt(0).SetUint64(c.Dest.ChainID), "", 0) + var ( + oracles []confighelper.OracleIdentityExtra + nodes []Node + ) + err := appBootstrap.Start(ctx) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, appBootstrap.Stop()) + }) + bootstrapNode := Node{ + App: appBootstrap, + Transmitter: bootstrapTransmitter, + KeyBundle: bootstrapKb, + } + // Set up the minimum 4 oracles all funded with destination ETH + for i := int64(0); i < 4; i++ { + app, peerID, transmitter, kb := setupNodeCCIP( + t, + c.Dest.User, + int64(freeport.GetOne(t)), + fmt.Sprintf("oracle_ccip%d", i), + c.Source.Chain, + c.Dest.Chain, + big.NewInt(0).SetUint64(c.Source.ChainID), + big.NewInt(0).SetUint64(c.Dest.ChainID), + bootstrapPeerID, + bootstrapNodePort, + ) + nodes = append(nodes, Node{ + App: app, + Transmitter: transmitter, + KeyBundle: kb, + }) + offchainPublicKey, _ := hex.DecodeString(strings.TrimPrefix(kb.OnChainPublicKey(), "0x")) + oracles = append(oracles, confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: offchainPublicKey, + TransmitAccount: types4.Account(transmitter.String()), + OffchainPublicKey: kb.OffchainPublicKey(), + PeerID: peerID, + }, + ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), + }) + err = app.Start(ctx) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, app.Stop()) + }) + } + + c.Oracles = oracles + commitOnchainConfig := c.CreateDefaultCommitOnchainConfig(t) + commitOffchainConfig := c.CreateDefaultCommitOffchainConfig(t) + execOnchainConfig := c.CreateDefaultExecOnchainConfig(t) + execOffchainConfig := c.CreateDefaultExecOffchainConfig(t) + + configBlock := c.SetupOnchainConfig(t, commitOnchainConfig, commitOffchainConfig, execOnchainConfig, execOffchainConfig) + c.Nodes = nodes + c.Bootstrap = bootstrapNode + return bootstrapNode, nodes, configBlock +} + +func (c *CCIPIntegrationTestHarness) SetUpNodesAndJobs(t *testing.T, pricePipeline string, priceGetterConfig string, usdcAttestationAPI string) integrationtesthelpers.CCIPJobSpecParams { + // setup Jobs + ctx := context.Background() + // Starts nodes and configures them in the OCR contracts. + bootstrapNode, _, configBlock := c.SetupAndStartNodes(ctx, t, int64(freeport.GetOne(t))) + + jobParams := c.NewCCIPJobSpecParams(pricePipeline, priceGetterConfig, configBlock, usdcAttestationAPI) + + // Add the bootstrap job + c.Bootstrap.AddBootstrapJob(t, jobParams.BootstrapJob(c.Dest.CommitStore.Address().Hex())) + c.AddAllJobs(t, jobParams) + + // Replay for bootstrap. + bc, err := bootstrapNode.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(c.Dest.ChainID, 10)) + require.NoError(t, err) + require.NoError(t, bc.LogPoller().Replay(context.Background(), configBlock)) + c.Dest.Chain.Commit() + + return jobParams +} + +func (c *CCIPIntegrationTestHarness) NewCCIPJobSpecParams(tokenPricesUSDPipeline string, priceGetterConfig string, configBlock int64, usdcAttestationAPI string) integrationtesthelpers.CCIPJobSpecParams { + return integrationtesthelpers.CCIPJobSpecParams{ + CommitStore: c.Dest.CommitStore.Address(), + OffRamp: c.Dest.OffRamp.Address(), + DestEvmChainId: c.Dest.ChainID, + SourceChainName: "SimulatedSource", + DestChainName: "SimulatedDest", + TokenPricesUSDPipeline: tokenPricesUSDPipeline, + PriceGetterConfig: priceGetterConfig, + DestStartBlock: uint64(configBlock), + USDCAttestationAPI: usdcAttestationAPI, + } +} + +func DecodeCommitOnChainConfig(encoded []byte) (ccipdata.CommitOnchainConfig, error) { + var onchainConfig ccipdata.CommitOnchainConfig + unpacked, err := abihelpers.DecodeOCR2Config(encoded) + if err != nil { + return onchainConfig, err + } + onChainCfg := unpacked.OnchainConfig + onchainConfig, err = abihelpers.DecodeAbiStruct[ccipdata.CommitOnchainConfig](onChainCfg) + if err != nil { + return onchainConfig, err + } + return onchainConfig, nil +} + +func DecodeExecOnChainConfig(encoded []byte) (v1_2_0.ExecOnchainConfig, error) { + var onchainConfig v1_2_0.ExecOnchainConfig + unpacked, err := abihelpers.DecodeOCR2Config(encoded) + if err != nil { + return onchainConfig, errors.Wrap(err, "failed to unpack log data") + } + onChainCfg := unpacked.OnchainConfig + onchainConfig, err = abihelpers.DecodeAbiStruct[v1_2_0.ExecOnchainConfig](onChainCfg) + if err != nil { + return onchainConfig, err + } + return onchainConfig, nil +} + +type ksa struct { + keystore.Master + csa keystore.CSA +} + +func (k *ksa) CSA() keystore.CSA { + return k.csa +} + +func NewKsa(db *sqlx.DB, lggr logger.Logger, csa keystore.CSA) *ksa { + return &ksa{ + Master: keystore.New(db, clutils.FastScryptParams, lggr), + csa: csa, + } +} + +type NoopFeedsClient struct{} + +func (n NoopFeedsClient) ApprovedJob(context.Context, *pb.ApprovedJobRequest) (*pb.ApprovedJobResponse, error) { + return &pb.ApprovedJobResponse{}, nil +} + +func (n NoopFeedsClient) Healthcheck(context.Context, *pb.HealthcheckRequest) (*pb.HealthcheckResponse, error) { + return &pb.HealthcheckResponse{}, nil +} + +func (n NoopFeedsClient) UpdateNode(context.Context, *pb.UpdateNodeRequest) (*pb.UpdateNodeResponse, error) { + return &pb.UpdateNodeResponse{}, nil +} + +func (n NoopFeedsClient) RejectedJob(context.Context, *pb.RejectedJobRequest) (*pb.RejectedJobResponse, error) { + return &pb.RejectedJobResponse{}, nil +} + +func (n NoopFeedsClient) CancelledJob(context.Context, *pb.CancelledJobRequest) (*pb.CancelledJobResponse, error) { + return &pb.CancelledJobResponse{}, nil +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go new file mode 100644 index 0000000000..751ae5c1a9 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go @@ -0,0 +1,73 @@ +// Package with set of configs that should be used only within tests suites + +package testhelpers_1_4_0 + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" +) + +var PermissionLessExecutionThresholdSeconds = uint32(testhelpers.FirstBlockAge.Seconds()) + +func (c *CCIPContracts) CreateDefaultCommitOnchainConfig(t *testing.T) []byte { + config, err := abihelpers.EncodeAbiStruct(ccipdata.CommitOnchainConfig{ + PriceRegistry: c.Dest.PriceRegistry.Address(), + }) + require.NoError(t, err) + return config +} + +func (c *CCIPContracts) CreateDefaultCommitOffchainConfig(t *testing.T) []byte { + return c.createCommitOffchainConfig(t, 10*time.Second, 5*time.Second) +} + +func (c *CCIPContracts) createCommitOffchainConfig(t *testing.T, feeUpdateHearBeat time.Duration, inflightCacheExpiry time.Duration) []byte { + config, err := NewCommitOffchainConfig( + *config.MustNewDuration(feeUpdateHearBeat), + 1, + 1, + *config.MustNewDuration(feeUpdateHearBeat), + 1, + *config.MustNewDuration(inflightCacheExpiry), + ).Encode() + require.NoError(t, err) + return config +} + +func (c *CCIPContracts) CreateDefaultExecOnchainConfig(t *testing.T) []byte { + config, err := abihelpers.EncodeAbiStruct(v1_2_0.ExecOnchainConfig{ + PermissionLessExecutionThresholdSeconds: PermissionLessExecutionThresholdSeconds, + Router: c.Dest.Router.Address(), + PriceRegistry: c.Dest.PriceRegistry.Address(), + MaxDataBytes: 1e5, + MaxNumberOfTokensPerMsg: 5, + MaxPoolReleaseOrMintGas: 200_000, + }) + require.NoError(t, err) + return config +} + +func (c *CCIPContracts) CreateDefaultExecOffchainConfig(t *testing.T) []byte { + return c.createExecOffchainConfig(t, 1*time.Minute, 1*time.Minute) +} + +func (c *CCIPContracts) createExecOffchainConfig(t *testing.T, inflightCacheExpiry time.Duration, rootSnoozeTime time.Duration) []byte { + config, err := NewExecOffchainConfig( + 1, + 5_000_000, + 0.07, + *config.MustNewDuration(inflightCacheExpiry), + *config.MustNewDuration(rootSnoozeTime), + ).Encode() + require.NoError(t, err) + return config +} diff --git a/core/services/ocr2/plugins/ccip/tokendata/bgworker.go b/core/services/ocr2/plugins/ccip/tokendata/bgworker.go new file mode 100644 index 0000000000..1a74ab2305 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/tokendata/bgworker.go @@ -0,0 +1,213 @@ +package tokendata + +import ( + "context" + "fmt" + "strconv" + "sync" + "time" + + "github.com/patrickmn/go-cache" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/job" +) + +type msgResult struct { + TokenAmountIndex int + Err error + Data []byte +} + +type Worker interface { + job.ServiceCtx + // AddJobsFromMsgs will include the provided msgs for background processing. + AddJobsFromMsgs(ctx context.Context, msgs []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) + + // GetMsgTokenData returns the token data for the provided msg. If data are not ready it keeps waiting + // until they get ready. Important: Make sure to pass a proper context with timeout. + GetMsgTokenData(ctx context.Context, msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) ([][]byte, error) + + GetReaders() map[cciptypes.Address]Reader +} + +type BackgroundWorker struct { + tokenDataReaders map[cciptypes.Address]Reader + numWorkers int + jobsChan chan cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta + resultsCache *cache.Cache + timeoutDur time.Duration + + services.StateMachine + wg *sync.WaitGroup + backgroundCtx context.Context //nolint:containedctx + backgroundCancel context.CancelFunc +} + +func NewBackgroundWorker( + tokenDataReaders map[cciptypes.Address]Reader, + numWorkers int, + timeoutDur time.Duration, + expirationDur time.Duration, +) *BackgroundWorker { + if expirationDur == 0 { + expirationDur = 24 * time.Hour + } + + ctx, cancel := context.WithCancel(context.Background()) + return &BackgroundWorker{ + tokenDataReaders: tokenDataReaders, + numWorkers: numWorkers, + jobsChan: make(chan cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, numWorkers*100), + resultsCache: cache.New(expirationDur, expirationDur/2), + timeoutDur: timeoutDur, + + wg: new(sync.WaitGroup), + backgroundCtx: ctx, + backgroundCancel: cancel, + } +} + +func (w *BackgroundWorker) Start(context.Context) error { + return w.StateMachine.StartOnce("Token BackgroundWorker", func() error { + for i := 0; i < w.numWorkers; i++ { + w.wg.Add(1) + w.run() + } + return nil + }) +} + +func (w *BackgroundWorker) Close() error { + return w.StateMachine.StopOnce("Token BackgroundWorker", func() error { + w.backgroundCancel() + w.wg.Wait() + return nil + }) +} + +func (w *BackgroundWorker) AddJobsFromMsgs(ctx context.Context, msgs []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) { + w.wg.Add(1) + go func() { + defer w.wg.Done() + for _, msg := range msgs { + select { + case <-w.backgroundCtx.Done(): + return + case <-ctx.Done(): + return + default: + if len(msg.TokenAmounts) > 0 { + w.jobsChan <- msg + } + } + } + }() +} + +func (w *BackgroundWorker) GetReaders() map[cciptypes.Address]Reader { + return w.tokenDataReaders +} + +func (w *BackgroundWorker) GetMsgTokenData(ctx context.Context, msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) ([][]byte, error) { + res, err := w.getMsgTokenData(ctx, msg.SequenceNumber) + if err != nil { + return nil, err + } + + tokenDatas := make([][]byte, len(msg.TokenAmounts)) + for _, r := range res { + if r.Err != nil { + return nil, r.Err + } + if r.TokenAmountIndex < 0 || r.TokenAmountIndex >= len(msg.TokenAmounts) { + return nil, fmt.Errorf("token data index inconsistency") + } + tokenDatas[r.TokenAmountIndex] = r.Data + } + + return tokenDatas, nil +} + +func (w *BackgroundWorker) run() { + go func() { + defer w.wg.Done() + for { + select { + case <-w.backgroundCtx.Done(): + return + case msg := <-w.jobsChan: + w.workOnMsg(w.backgroundCtx, msg) + } + } + }() +} + +func (w *BackgroundWorker) workOnMsg(ctx context.Context, msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) { + results := make([]msgResult, 0, len(msg.TokenAmounts)) + + cachedTokenData := make(map[int]msgResult) // tokenAmount index -> token data + if cachedData, exists := w.getFromCache(msg.SequenceNumber); exists { + for _, r := range cachedData { + cachedTokenData[r.TokenAmountIndex] = r + } + } + + for i, token := range msg.TokenAmounts { + offchainTokenDataProvider, exists := w.tokenDataReaders[token.Token] + if !exists { + // No token data required + continue + } + + // if the result exists in the cache and there wasn't any error keep the existing result + if cachedResult, exists := cachedTokenData[i]; exists && cachedResult.Err == nil { + results = append(results, cachedResult) + continue + } + + // if there was any error or if the data do not exist in the cache make a call to the provider + timeoutCtx, cf := context.WithTimeout(ctx, w.timeoutDur) + tknData, err := offchainTokenDataProvider.ReadTokenData(timeoutCtx, msg, i) + cf() + results = append(results, msgResult{ + TokenAmountIndex: i, + Err: err, + Data: tknData, + }) + } + + w.resultsCache.Set(strconv.FormatUint(msg.SequenceNumber, 10), results, cache.DefaultExpiration) +} + +func (w *BackgroundWorker) getMsgTokenData(ctx context.Context, seqNum uint64) ([]msgResult, error) { + if msgTokenData, exists := w.getFromCache(seqNum); exists { + return msgTokenData, nil + } + + ctx, cf := context.WithTimeout(ctx, w.timeoutDur) + defer cf() + + // wait until the results are ready or until context timeout is reached + tick := time.NewTicker(100 * time.Millisecond) + for { + select { + case <-ctx.Done(): + return nil, context.DeadlineExceeded + case <-tick.C: + if msgTokenData, exists := w.getFromCache(seqNum); exists { + return msgTokenData, nil + } + } + } +} + +func (w *BackgroundWorker) getFromCache(seqNum uint64) ([]msgResult, bool) { + rawResult, found := w.resultsCache.Get(strconv.FormatUint(seqNum, 10)) + if !found { + return nil, false + } + return rawResult.([]msgResult), true +} diff --git a/core/services/ocr2/plugins/ccip/tokendata/bgworker_test.go b/core/services/ocr2/plugins/ccip/tokendata/bgworker_test.go new file mode 100644 index 0000000000..5d505363ac --- /dev/null +++ b/core/services/ocr2/plugins/ccip/tokendata/bgworker_test.go @@ -0,0 +1,188 @@ +package tokendata_test + +import ( + "context" + "fmt" + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" +) + +func TestBackgroundWorker(t *testing.T) { + ctx := testutils.Context(t) + + const numTokens = 100 + const numWorkers = 20 + const numMessages = 40 + const maxReaderLatencyMS = 200 + const percentOfTokensWithoutTokenData = 10 + + tokens := make([]cciptypes.Address, numTokens) + readers := make(map[cciptypes.Address]*tokendata.MockReader, numTokens) + tokenDataReaders := make(map[cciptypes.Address]tokendata.Reader, numTokens) + tokenData := make(map[cciptypes.Address][]byte) + delays := make(map[cciptypes.Address]time.Duration) + + for i := range tokens { + tokens[i] = cciptypes.Address(utils.RandomAddress().String()) + readers[tokens[i]] = tokendata.NewMockReader(t) + if rand.Intn(100) >= percentOfTokensWithoutTokenData { + tokenDataReaders[tokens[i]] = readers[tokens[i]] + tokenData[tokens[i]] = []byte(fmt.Sprintf("...token %x data...", tokens[i])) + } + + // specify a random latency for the reader implementation + readerLatency := rand.Intn(maxReaderLatencyMS) + delays[tokens[i]] = time.Duration(readerLatency) * time.Millisecond + } + w := tokendata.NewBackgroundWorker(tokenDataReaders, numWorkers, 5*time.Second, time.Hour) + require.NoError(t, w.Start(ctx)) + + msgs := make([]cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, numMessages) + for i := range msgs { + tk := tokens[i%len(tokens)] + + msgs[i] = cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: uint64(i + 1), + TokenAmounts: []cciptypes.TokenAmount{{Token: tk}}, + }, + } + + reader := readers[tk] + reader.On("ReadTokenData", mock.Anything, msgs[i], 0).Run(func(args mock.Arguments) { + time.Sleep(delays[tk]) + }).Return(tokenData[tk], nil).Maybe() + } + + w.AddJobsFromMsgs(ctx, msgs) + // processing of the messages should have started at this point + + tStart := time.Now() + for _, msg := range msgs { + b, err := w.GetMsgTokenData(ctx, msg) // fetched from provider + assert.NoError(t, err) + assert.Equal(t, tokenData[msg.TokenAmounts[0].Token], b[0]) + } + assert.True(t, time.Since(tStart) < 600*time.Millisecond) + assert.True(t, time.Since(tStart) > 200*time.Millisecond) + + tStart = time.Now() + for _, msg := range msgs { + b, err := w.GetMsgTokenData(ctx, msg) // fetched from cache + assert.NoError(t, err) + assert.Equal(t, tokenData[msg.TokenAmounts[0].Token], b[0]) + } + assert.True(t, time.Since(tStart) < 200*time.Millisecond) + + w.AddJobsFromMsgs(ctx, msgs) // same messages are added but they should already be in cache + tStart = time.Now() + for _, msg := range msgs { + b, err := w.GetMsgTokenData(ctx, msg) + assert.NoError(t, err) + assert.Equal(t, tokenData[msg.TokenAmounts[0].Token], b[0]) + } + assert.True(t, time.Since(tStart) < 200*time.Millisecond) + + require.NoError(t, w.Close()) +} + +func TestBackgroundWorker_RetryOnErrors(t *testing.T) { + ctx := testutils.Context(t) + + tk1 := cciptypes.Address(utils.RandomAddress().String()) + tk2 := cciptypes.Address(utils.RandomAddress().String()) + + rdr1 := tokendata.NewMockReader(t) + rdr2 := tokendata.NewMockReader(t) + + w := tokendata.NewBackgroundWorker(map[cciptypes.Address]tokendata.Reader{ + tk1: rdr1, + tk2: rdr2, + }, 10, 5*time.Second, time.Hour) + require.NoError(t, w.Start(ctx)) + + msgs := []cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + {EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: uint64(1), + TokenAmounts: []cciptypes.TokenAmount{{Token: tk1}}, + }}, + {EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: uint64(2), + TokenAmounts: []cciptypes.TokenAmount{{Token: tk2}}, + }}, + } + + rdr1.On("ReadTokenData", mock.Anything, msgs[0], 0). + Return([]byte("some data"), nil).Once() + + // reader2 returns an error + rdr2.On("ReadTokenData", mock.Anything, msgs[1], 0). + Return(nil, fmt.Errorf("some err")).Once() + + w.AddJobsFromMsgs(ctx, msgs) + // processing of the messages should have started at this point + + tokenData, err := w.GetMsgTokenData(ctx, msgs[0]) + assert.NoError(t, err) + assert.Equal(t, []byte("some data"), tokenData[0]) + + _, err = w.GetMsgTokenData(ctx, msgs[1]) + assert.Error(t, err) + assert.Errorf(t, err, "some error") + + // we make the second reader to return data + rdr2.On("ReadTokenData", mock.Anything, msgs[1], 0). + Return([]byte("some other data"), nil).Once() + + // add the jobs again, at this point jobs that previously returned + // an error are removed from the cache + w.AddJobsFromMsgs(ctx, msgs) + + // since reader1 returned some data before, we expect to get the cached result + tokenData, err = w.GetMsgTokenData(ctx, msgs[0]) + assert.NoError(t, err) + assert.Equal(t, []byte("some data"), tokenData[0]) + + // wait some time for msg2 to be re-processed and error overwritten + time.Sleep(20 * time.Millisecond) // todo: improve the test + + // for reader2 that returned an error before we expect to get data now + tokenData, err = w.GetMsgTokenData(ctx, msgs[1]) + assert.NoError(t, err) + assert.Equal(t, []byte("some other data"), tokenData[0]) + + require.NoError(t, w.Close()) +} + +func TestBackgroundWorker_Timeout(t *testing.T) { + ctx := testutils.Context(t) + + tk1 := cciptypes.Address(utils.RandomAddress().String()) + tk2 := cciptypes.Address(utils.RandomAddress().String()) + + rdr1 := tokendata.NewMockReader(t) + rdr2 := tokendata.NewMockReader(t) + + w := tokendata.NewBackgroundWorker( + map[cciptypes.Address]tokendata.Reader{tk1: rdr1, tk2: rdr2}, 10, 5*time.Second, time.Hour) + require.NoError(t, w.Start(ctx)) + + ctx, cf := context.WithTimeout(ctx, 500*time.Millisecond) + defer cf() + + _, err := w.GetMsgTokenData(ctx, cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{SequenceNumber: 1}}, + ) + assert.Error(t, err) + require.NoError(t, w.Close()) +} diff --git a/core/services/ocr2/plugins/ccip/tokendata/http/http_client.go b/core/services/ocr2/plugins/ccip/tokendata/http/http_client.go new file mode 100644 index 0000000000..79ec21b1b8 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/tokendata/http/http_client.go @@ -0,0 +1,48 @@ +package http + +import ( + "context" + "io" + "net/http" + "time" + + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" +) + +type IHttpClient interface { + // Get issue a GET request to the given url and return the response body and status code. + Get(ctx context.Context, url string, timeout time.Duration) ([]byte, int, http.Header, error) +} + +type HttpClient struct { +} + +func (s *HttpClient) Get(ctx context.Context, url string, timeout time.Duration) ([]byte, int, http.Header, error) { + // Use a timeout to guard against attestation API hanging, causing observation timeout and failing to make any progress. + timeoutCtx, cancel := context.WithTimeoutCause(ctx, timeout, tokendata.ErrTimeout) + defer cancel() + req, err := http.NewRequestWithContext(timeoutCtx, http.MethodGet, url, nil) + if err != nil { + return nil, http.StatusBadRequest, nil, err + } + req.Header.Add("accept", "application/json") + res, err := http.DefaultClient.Do(req) + if err != nil { + if errors.Is(err, context.DeadlineExceeded) { + return nil, http.StatusRequestTimeout, nil, tokendata.ErrTimeout + } + // On error, res is nil in most cases, do not read res.StatusCode, return BadRequest + return nil, http.StatusBadRequest, nil, err + } + defer res.Body.Close() + + // Explicitly signal if the API is being rate limited + if res.StatusCode == http.StatusTooManyRequests { + return nil, res.StatusCode, res.Header, tokendata.ErrRateLimit + } + + body, err := io.ReadAll(res.Body) + return body, res.StatusCode, res.Header, err +} diff --git a/core/services/ocr2/plugins/ccip/tokendata/http/observed_http_client.go b/core/services/ocr2/plugins/ccip/tokendata/http/observed_http_client.go new file mode 100644 index 0000000000..d8fb9b1c57 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/tokendata/http/observed_http_client.go @@ -0,0 +1,69 @@ +package http + +import ( + "context" + "net/http" + "strconv" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +var ( + usdcLatencyBuckets = []float64{ + float64(10 * time.Millisecond), + float64(25 * time.Millisecond), + float64(50 * time.Millisecond), + float64(75 * time.Millisecond), + float64(100 * time.Millisecond), + float64(250 * time.Millisecond), + float64(500 * time.Millisecond), + float64(750 * time.Millisecond), + float64(1 * time.Second), + float64(2 * time.Second), + float64(3 * time.Second), + float64(4 * time.Second), + float64(5 * time.Second), + } + usdcClientHistogram = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "ccip_usdc_client_request_total", + Help: "Latency of calls to the USDC client", + Buckets: usdcLatencyBuckets, + }, []string{"status", "success"}) +) + +type ObservedIHttpClient struct { + IHttpClient + histogram *prometheus.HistogramVec +} + +// NewObservedIHttpClient Create a new ObservedIHttpClient with the USDC client metric. +func NewObservedIHttpClient(origin IHttpClient) *ObservedIHttpClient { + return NewObservedIHttpClientWithMetric(origin, usdcClientHistogram) +} + +func NewObservedIHttpClientWithMetric(origin IHttpClient, histogram *prometheus.HistogramVec) *ObservedIHttpClient { + return &ObservedIHttpClient{ + IHttpClient: origin, + histogram: histogram, + } +} + +func (o *ObservedIHttpClient) Get(ctx context.Context, url string, timeout time.Duration) ([]byte, int, http.Header, error) { + return withObservedHttpClient(o.histogram, func() ([]byte, int, http.Header, error) { + return o.IHttpClient.Get(ctx, url, timeout) + }) +} + +func withObservedHttpClient[T any](histogram *prometheus.HistogramVec, contract func() (T, int, http.Header, error)) (T, int, http.Header, error) { + contractExecutionStarted := time.Now() + value, status, headers, err := contract() + histogram. + WithLabelValues( + strconv.FormatInt(int64(status), 10), + strconv.FormatBool(err == nil), + ). + Observe(float64(time.Since(contractExecutionStarted))) + return value, status, headers, err +} diff --git a/core/services/ocr2/plugins/ccip/tokendata/observability/usdc_client_test.go b/core/services/ocr2/plugins/ccip/tokendata/observability/usdc_client_test.go new file mode 100644 index 0000000000..0567b725a8 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/tokendata/observability/usdc_client_test.go @@ -0,0 +1,151 @@ +package observability + +import ( + "context" + "encoding/json" + "math/big" + "math/rand" + "net/http" + "net/http/httptest" + "net/url" + "testing" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + io_prometheus_client "github.com/prometheus/client_model/go" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" + http2 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata/http" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata/usdc" +) + +type expected struct { + status string + result string + count int +} + +func TestUSDCClientMonitoring(t *testing.T) { + tests := []struct { + name string + server *httptest.Server + requests int + expected []expected + }{ + { + name: "success", + server: newSuccessServer(t), + requests: 5, + expected: []expected{ + {"200", "true", 5}, + {"429", "false", 0}, + }, + }, + { + name: "rate_limited", + server: newRateLimitedServer(), + requests: 26, + expected: []expected{ + {"200", "true", 0}, + {"429", "false", 1}, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + testMonitoring(t, test.name, test.server, test.requests, test.expected, logger.TestLogger(t)) + }) + } +} + +func testMonitoring(t *testing.T, name string, server *httptest.Server, requests int, expected []expected, log logger.Logger) { + server.Start() + defer server.Close() + attestationURI, err := url.ParseRequestURI(server.URL) + require.NoError(t, err) + + // Define test histogram (avoid side effects from other tests if using the real usdcHistogram). + histogram := promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "test_client_histogram_" + name, + Help: "Latency of calls to the USDC mock client", + Buckets: []float64{float64(250 * time.Millisecond), float64(1 * time.Second), float64(5 * time.Second)}, + }, []string{"status", "success"}) + + // Mock USDC reader. + usdcReader := mocks.NewUSDCReader(t) + msgBody := []byte{0xb0, 0xd1} + usdcReader.On("GetUSDCMessagePriorToLogIndexInTx", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(msgBody, nil) + + // Service with monitored http client. + usdcTokenAddr := utils.RandomAddress() + observedHttpClient := http2.NewObservedIHttpClientWithMetric(&http2.HttpClient{}, histogram) + tokenDataReaderDefault := usdc.NewUSDCTokenDataReader(log, usdcReader, attestationURI, 0, usdcTokenAddr, usdc.APIIntervalRateLimitDisabled) + tokenDataReader := usdc.NewUSDCTokenDataReaderWithHttpClient(*tokenDataReaderDefault, observedHttpClient, usdcTokenAddr, usdc.APIIntervalRateLimitDisabled) + require.NotNil(t, tokenDataReader) + + for i := 0; i < requests; i++ { + _, _ = tokenDataReader.ReadTokenData(context.Background(), cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + TokenAmounts: []cciptypes.TokenAmount{ + { + Token: ccipcalc.EvmAddrToGeneric(usdcTokenAddr), + Amount: big.NewInt(rand.Int63()), + }, + }, + }, + }, 0) + } + + // Check that the metrics are updated as expected. + for _, e := range expected { + assert.Equal(t, e.count, counterFromHistogramByLabels(t, histogram, e.status, e.result)) + } +} + +func counterFromHistogramByLabels(t *testing.T, histogramVec *prometheus.HistogramVec, labels ...string) int { + observer, err := histogramVec.GetMetricWithLabelValues(labels...) + require.NoError(t, err) + + metricCh := make(chan prometheus.Metric, 1) + observer.(prometheus.Histogram).Collect(metricCh) + close(metricCh) + + metric := <-metricCh + pb := &io_prometheus_client.Metric{} + err = metric.Write(pb) + require.NoError(t, err) + + return int(pb.GetHistogram().GetSampleCount()) +} + +func newSuccessServer(t *testing.T) *httptest.Server { + return httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + response := struct { + Status string `json:"status"` + Attestation string `json:"attestation"` + }{ + Status: "complete", + Attestation: "720502893578a89a8a87982982ef781c18b193", + } + responseBytes, err := json.Marshal(response) + require.NoError(t, err) + _, err = w.Write(responseBytes) + require.NoError(t, err) + })) +} + +func newRateLimitedServer() *httptest.Server { + return httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusTooManyRequests) + })) +} diff --git a/core/services/ocr2/plugins/ccip/tokendata/reader.go b/core/services/ocr2/plugins/ccip/tokendata/reader.go new file mode 100644 index 0000000000..16646bc7c5 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/tokendata/reader.go @@ -0,0 +1,19 @@ +package tokendata + +import ( + "errors" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" +) + +var ( + ErrNotReady = errors.New("token data not ready") + ErrRateLimit = errors.New("token data API is being rate limited") + ErrTimeout = errors.New("token data API timed out") + ErrRequestsBlocked = errors.New("requests are currently blocked") +) + +// Reader is an interface for fetching offchain token data +type Reader interface { + cciptypes.TokenDataReader +} diff --git a/core/services/ocr2/plugins/ccip/tokendata/reader_mock.go b/core/services/ocr2/plugins/ccip/tokendata/reader_mock.go new file mode 100644 index 0000000000..39166d6159 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/tokendata/reader_mock.go @@ -0,0 +1,143 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package tokendata + +import ( + context "context" + + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + mock "github.com/stretchr/testify/mock" +) + +// MockReader is an autogenerated mock type for the Reader type +type MockReader struct { + mock.Mock +} + +type MockReader_Expecter struct { + mock *mock.Mock +} + +func (_m *MockReader) EXPECT() *MockReader_Expecter { + return &MockReader_Expecter{mock: &_m.Mock} +} + +// Close provides a mock function with given fields: +func (_m *MockReader) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockReader_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type MockReader_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *MockReader_Expecter) Close() *MockReader_Close_Call { + return &MockReader_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *MockReader_Close_Call) Run(run func()) *MockReader_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockReader_Close_Call) Return(_a0 error) *MockReader_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockReader_Close_Call) RunAndReturn(run func() error) *MockReader_Close_Call { + _c.Call.Return(run) + return _c +} + +// ReadTokenData provides a mock function with given fields: ctx, msg, tokenIndex +func (_m *MockReader) ReadTokenData(ctx context.Context, msg ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta, tokenIndex int) ([]byte, error) { + ret := _m.Called(ctx, msg, tokenIndex) + + if len(ret) == 0 { + panic("no return value specified for ReadTokenData") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta, int) ([]byte, error)); ok { + return rf(ctx, msg, tokenIndex) + } + if rf, ok := ret.Get(0).(func(context.Context, ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta, int) []byte); ok { + r0 = rf(ctx, msg, tokenIndex) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta, int) error); ok { + r1 = rf(ctx, msg, tokenIndex) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockReader_ReadTokenData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadTokenData' +type MockReader_ReadTokenData_Call struct { + *mock.Call +} + +// ReadTokenData is a helper method to define mock.On call +// - ctx context.Context +// - msg ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta +// - tokenIndex int +func (_e *MockReader_Expecter) ReadTokenData(ctx interface{}, msg interface{}, tokenIndex interface{}) *MockReader_ReadTokenData_Call { + return &MockReader_ReadTokenData_Call{Call: _e.mock.On("ReadTokenData", ctx, msg, tokenIndex)} +} + +func (_c *MockReader_ReadTokenData_Call) Run(run func(ctx context.Context, msg ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta, tokenIndex int)) *MockReader_ReadTokenData_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta), args[2].(int)) + }) + return _c +} + +func (_c *MockReader_ReadTokenData_Call) Return(tokenData []byte, err error) *MockReader_ReadTokenData_Call { + _c.Call.Return(tokenData, err) + return _c +} + +func (_c *MockReader_ReadTokenData_Call) RunAndReturn(run func(context.Context, ccip.EVM2EVMOnRampCCIPSendRequestedWithMeta, int) ([]byte, error)) *MockReader_ReadTokenData_Call { + _c.Call.Return(run) + return _c +} + +// NewMockReader creates a new instance of MockReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockReader(t interface { + mock.TestingT + Cleanup(func()) +}) *MockReader { + mock := &MockReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go new file mode 100644 index 0000000000..fe3a86d2af --- /dev/null +++ b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go @@ -0,0 +1,339 @@ +package usdc + +import ( + "context" + "encoding/hex" + "encoding/json" + "fmt" + "net/url" + "strconv" + "strings" + "sync" + "time" + + "github.com/pkg/errors" + "golang.org/x/time/rate" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata/http" +) + +const ( + apiVersion = "v1" + attestationPath = "attestations" + defaultAttestationTimeout = 5 * time.Second + + // defaultCoolDownDurationSec defines the default time to wait after getting rate limited. + // this value is only used if the 429 response does not contain the Retry-After header + defaultCoolDownDuration = 5 * time.Minute + + // maxCoolDownDuration defines the maximum duration we can wait till firing the next request + maxCoolDownDuration = 10 * time.Minute + + // defaultRequestInterval defines the rate in requests per second that the attestation API can be called. + // this is set according to the APIs documentated 10 requests per second rate limit. + defaultRequestInterval = 100 * time.Millisecond + + // APIIntervalRateLimitDisabled is a special value to disable the rate limiting. + APIIntervalRateLimitDisabled = -1 + // APIIntervalRateLimitDefault is a special value to select the default rate limit interval. + APIIntervalRateLimitDefault = 0 +) + +type attestationStatus string + +const ( + attestationStatusSuccess attestationStatus = "complete" + attestationStatusPending attestationStatus = "pending_confirmations" +) + +var ( + ErrUnknownResponse = errors.New("unexpected response from attestation API") +) + +// messageAndAttestation has to match the onchain struct `MessageAndAttestation` in the +// USDC token pool. +type messageAndAttestation struct { + Message []byte + Attestation []byte +} + +func (m messageAndAttestation) AbiString() string { + return ` + [{ + "components": [ + {"name": "message", "type": "bytes"}, + {"name": "attestation", "type": "bytes"} + ], + "type": "tuple" + }]` +} + +func (m messageAndAttestation) Validate() error { + if len(m.Message) == 0 { + return errors.New("message must be non-empty") + } + if len(m.Attestation) == 0 { + return errors.New("attestation must be non-empty") + } + return nil +} + +type TokenDataReader struct { + lggr logger.Logger + usdcReader ccipdata.USDCReader + httpClient http.IHttpClient + attestationApi *url.URL + attestationApiTimeout time.Duration + usdcTokenAddress common.Address + rate *rate.Limiter + + // coolDownUntil defines whether requests are blocked or not. + coolDownUntil time.Time + coolDownMu *sync.RWMutex +} + +type attestationResponse struct { + Status attestationStatus `json:"status"` + Attestation string `json:"attestation"` + Error string `json:"error"` +} + +var _ tokendata.Reader = &TokenDataReader{} + +func NewUSDCTokenDataReader( + lggr logger.Logger, + usdcReader ccipdata.USDCReader, + usdcAttestationApi *url.URL, + usdcAttestationApiTimeoutSeconds int, + usdcTokenAddress common.Address, + requestInterval time.Duration, +) *TokenDataReader { + timeout := time.Duration(usdcAttestationApiTimeoutSeconds) * time.Second + if usdcAttestationApiTimeoutSeconds == 0 { + timeout = defaultAttestationTimeout + } + + if requestInterval == APIIntervalRateLimitDisabled { + requestInterval = 0 + } else if requestInterval == APIIntervalRateLimitDefault { + requestInterval = defaultRequestInterval + } + + return &TokenDataReader{ + lggr: lggr, + usdcReader: usdcReader, + httpClient: http.NewObservedIHttpClient(&http.HttpClient{}), + attestationApi: usdcAttestationApi, + attestationApiTimeout: timeout, + usdcTokenAddress: usdcTokenAddress, + coolDownMu: &sync.RWMutex{}, + rate: rate.NewLimiter(rate.Every(requestInterval), 1), + } +} + +func NewUSDCTokenDataReaderWithHttpClient( + origin TokenDataReader, + httpClient http.IHttpClient, + usdcTokenAddress common.Address, + requestInterval time.Duration, +) *TokenDataReader { + return &TokenDataReader{ + lggr: origin.lggr, + usdcReader: origin.usdcReader, + httpClient: httpClient, + attestationApi: origin.attestationApi, + attestationApiTimeout: origin.attestationApiTimeout, + coolDownMu: origin.coolDownMu, + usdcTokenAddress: usdcTokenAddress, + rate: rate.NewLimiter(rate.Every(requestInterval), 1), + } +} + +// ReadTokenData queries the USDC attestation API to construct a message and +// attestation response. When called back to back, or multiple times +// concurrently, responses are delayed according how the request interval is +// configured. +func (s *TokenDataReader) ReadTokenData(ctx context.Context, msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, tokenIndex int) ([]byte, error) { + if tokenIndex < 0 || tokenIndex >= len(msg.TokenAmounts) { + return nil, fmt.Errorf("token index out of bounds") + } + + if s.inCoolDownPeriod() { + // rate limiting cool-down period, we prevent new requests from being sent + return nil, tokendata.ErrRequestsBlocked + } + + if s.rate != nil { + // Wait blocks until it the attestation API can be called or the + // context is Done. + if waitErr := s.rate.Wait(ctx); waitErr != nil { + return nil, fmt.Errorf("usdc rate limiting error: %w", waitErr) + } + } + + messageBody, err := s.getUSDCMessageBody(ctx, msg, tokenIndex) + if err != nil { + return []byte{}, errors.Wrap(err, "failed getting the USDC message body") + } + + msgID := hexutil.Encode(msg.MessageID[:]) + msgBody := hexutil.Encode(messageBody) + s.lggr.Infow("Calling attestation API", "messageBodyHash", msgBody, "messageID", msgID) + + // The attestation API expects the hash of the message body + attestationResp, err := s.callAttestationApi(ctx, utils.Keccak256Fixed(messageBody)) + if err != nil { + return []byte{}, errors.Wrap(err, "failed calling usdc attestation API ") + } + + s.lggr.Infow("Got response from attestation API", "messageID", msgID, + "attestationStatus", attestationResp.Status, "attestation", attestationResp.Attestation, + "attestationError", attestationResp.Error) + + switch attestationResp.Status { + case attestationStatusSuccess: + // The USDC pool needs a combination of the message body and the attestation + messageAndAttestation, err := encodeMessageAndAttestation(messageBody, attestationResp.Attestation) + if err != nil { + return nil, fmt.Errorf("failed to encode messageAndAttestation : %w", err) + } + return messageAndAttestation, nil + case attestationStatusPending: + return nil, tokendata.ErrNotReady + default: + s.lggr.Errorw("Unexpected response from attestation API", "attestationResp", attestationResp) + return nil, ErrUnknownResponse + } +} + +// encodeMessageAndAttestation encodes the message body and attestation into a single byte array +// that is readable onchain. +func encodeMessageAndAttestation(messageBody []byte, attestation string) ([]byte, error) { + attestationBytes, err := hex.DecodeString(strings.TrimPrefix(attestation, "0x")) + if err != nil { + return nil, fmt.Errorf("failed to decode response attestation: %w", err) + } + + return abihelpers.EncodeAbiStruct[messageAndAttestation](messageAndAttestation{ + Message: messageBody, + Attestation: attestationBytes, + }) +} + +func (s *TokenDataReader) getUSDCMessageBody( + ctx context.Context, + msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, + tokenIndex int, +) ([]byte, error) { + usdcTokenEndOffset, err := s.getUsdcTokenEndOffset(msg, tokenIndex) + if err != nil { + return nil, fmt.Errorf("get usdc token %d end offset: %w", tokenIndex, err) + } + + parsedMsgBody, err := s.usdcReader.GetUSDCMessagePriorToLogIndexInTx(ctx, int64(msg.LogIndex), usdcTokenEndOffset, msg.TxHash) + if err != nil { + return []byte{}, err + } + + s.lggr.Infow("Got USDC message body", "messageBody", hexutil.Encode(parsedMsgBody), "messageID", hexutil.Encode(msg.MessageID[:])) + return parsedMsgBody, nil +} + +func (s *TokenDataReader) getUsdcTokenEndOffset(msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, tokenIndex int) (int, error) { + if tokenIndex >= len(msg.TokenAmounts) || tokenIndex < 0 { + return 0, fmt.Errorf("invalid token index %d for msg with %d tokens", tokenIndex, len(msg.TokenAmounts)) + } + + if msg.TokenAmounts[tokenIndex].Token != ccipcalc.EvmAddrToGeneric(s.usdcTokenAddress) { + return 0, fmt.Errorf("the specified token index %d is not a usdc token", tokenIndex) + } + + usdcTokenEndOffset := 0 + for i := tokenIndex + 1; i < len(msg.TokenAmounts); i++ { + evmTokenAddr, err := ccipcalc.GenericAddrToEvm(msg.TokenAmounts[i].Token) + if err != nil { + continue + } + + if evmTokenAddr == s.usdcTokenAddress { + usdcTokenEndOffset++ + } + } + + return usdcTokenEndOffset, nil +} + +// callAttestationApi calls the USDC attestation API with the given USDC message hash. +// The attestation service rate limit is 10 requests per second. If you exceed 10 requests +// per second, the service blocks all API requests for the next 5 minutes and returns an +// HTTP 429 response. +// +// Documentation: +// +// https://developers.circle.com/stablecoins/reference/getattestation +// https://developers.circle.com/stablecoins/docs/transfer-usdc-on-testnet-from-ethereum-to-avalanche +func (s *TokenDataReader) callAttestationApi(ctx context.Context, usdcMessageHash [32]byte) (attestationResponse, error) { + body, _, headers, err := s.httpClient.Get( + ctx, + fmt.Sprintf("%s/%s/%s/0x%x", s.attestationApi, apiVersion, attestationPath, usdcMessageHash), + s.attestationApiTimeout, + ) + switch { + case errors.Is(err, tokendata.ErrRateLimit): + coolDownDuration := defaultCoolDownDuration + if retryAfterHeader, exists := headers["Retry-After"]; exists && len(retryAfterHeader) > 0 { + if retryAfterSec, errParseInt := strconv.ParseInt(retryAfterHeader[0], 10, 64); errParseInt == nil { + coolDownDuration = time.Duration(retryAfterSec) * time.Second + } + } + s.setCoolDownPeriod(coolDownDuration) + + // Explicitly signal if the API is being rate limited + return attestationResponse{}, tokendata.ErrRateLimit + case err != nil: + return attestationResponse{}, fmt.Errorf("request error: %w", err) + } + + var response attestationResponse + err = json.Unmarshal(body, &response) + if err != nil { + return attestationResponse{}, err + } + if response.Error != "" { + return attestationResponse{}, fmt.Errorf("attestation API error: %s", response.Error) + } + if response.Status == "" { + return attestationResponse{}, fmt.Errorf("invalid attestation response: %s", string(body)) + } + return response, nil +} + +func (s *TokenDataReader) setCoolDownPeriod(d time.Duration) { + s.coolDownMu.Lock() + if d > maxCoolDownDuration { + d = maxCoolDownDuration + } + s.coolDownUntil = time.Now().Add(d) + s.coolDownMu.Unlock() +} + +func (s *TokenDataReader) inCoolDownPeriod() bool { + s.coolDownMu.RLock() + defer s.coolDownMu.RUnlock() + return time.Now().Before(s.coolDownUntil) +} + +func (s *TokenDataReader) Close() error { + return nil +} diff --git a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go new file mode 100644 index 0000000000..95b309ff74 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go @@ -0,0 +1,119 @@ +package usdc_test + +import ( + "context" + "encoding/hex" + "encoding/json" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + ccipdatamocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata/usdc" +) + +type attestationResponse struct { + Status string `json:"status"` + Attestation string `json:"attestation"` +} + +func TestUSDCReader_ReadTokenData(t *testing.T) { + tests := []struct { + name string + attestationResponse attestationResponse + expectedError error + }{ + { + name: "status complete", + attestationResponse: attestationResponse{ + Status: "complete", + Attestation: "0x9049623e91719ef2aa63c55f357be2529b0e7122ae552c18aff8db58b4633c4d3920ff03d3a6d1ddf11f06bf64d7fd60d45447ac81f527ba628877dc5ca759651b08ffae25a6d3b1411749765244f0a1c131cbfe04430d687a2e12fd9d2e6dc08e118ad95d94ad832332cf3c4f7a4f3da0baa803b7be024b02db81951c0f0714de1b", + }, + expectedError: nil, + }, + { + name: "status pending", + attestationResponse: attestationResponse{ + Status: "pending_confirmations", + Attestation: "720502893578a89a8a87982982ef781c18b193", + }, + expectedError: tokendata.ErrNotReady, + }, + { + name: "status invalid", + attestationResponse: attestationResponse{ + Status: "invalid", + Attestation: "720502893578a89a8a87982982ef781c18b193", + }, + expectedError: usdc.ErrUnknownResponse, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + // Message is the bytes itself from MessageSend(bytes message) + // i.e. ABI parsed. + message := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" + expectedMessageAndAttestation := "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861000000000000000000000000000000000000000000000000000000000000000000000000000000829049623e91719ef2aa63c55f357be2529b0e7122ae552c18aff8db58b4633c4d3920ff03d3a6d1ddf11f06bf64d7fd60d45447ac81f527ba628877dc5ca759651b08ffae25a6d3b1411749765244f0a1c131cbfe04430d687a2e12fd9d2e6dc08e118ad95d94ad832332cf3c4f7a4f3da0baa803b7be024b02db81951c0f0714de1b000000000000000000000000000000000000000000000000000000000000" + lggr := logger.TestLogger(t) + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + messageHash := utils.Keccak256Fixed(hexutil.MustDecode(message)) + expectedUrl := "/v1/attestations/0x" + hex.EncodeToString(messageHash[:]) + require.Equal(t, expectedUrl, r.URL.Path) + + responseBytes, err2 := json.Marshal(test.attestationResponse) + require.NoError(t, err2) + + _, err2 = w.Write(responseBytes) + require.NoError(t, err2) + })) + + defer ts.Close() + + seqNum := uint64(23825) + txHash := utils.RandomBytes32() + logIndex := int64(4) + + usdcReader := ccipdatamocks.USDCReader{} + usdcReader.On("GetUSDCMessagePriorToLogIndexInTx", + mock.Anything, + logIndex, + 0, + common.Hash(txHash).String(), + ).Return(hexutil.MustDecode(message), nil) + attestationURI, err := url.ParseRequestURI(ts.URL) + require.NoError(t, err) + + addr := utils.RandomAddress() + usdcService := usdc.NewUSDCTokenDataReader(lggr, &usdcReader, attestationURI, 0, addr, usdc.APIIntervalRateLimitDisabled) + msgAndAttestation, err := usdcService.ReadTokenData(context.Background(), cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + SequenceNumber: seqNum, + TokenAmounts: []cciptypes.TokenAmount{{Token: ccipcalc.EvmAddrToGeneric(addr), Amount: nil}}, + }, + TxHash: cciptypes.Hash(txHash).String(), + LogIndex: uint(logIndex), + }, 0) + if test.expectedError != nil { + require.Error(t, err) + require.Equal(t, test.expectedError, err) + return + } + require.NoError(t, err) + // Expected attestation for parsed body. + require.Equal(t, expectedMessageAndAttestation, hexutil.Encode(msgAndAttestation)) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go new file mode 100644 index 0000000000..c4221b2dc0 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go @@ -0,0 +1,423 @@ +package usdc + +import ( + "context" + "encoding/json" + "math/big" + "math/rand" + "net/http" + "net/http/httptest" + "net/url" + "strings" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + ccipdatamocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" +) + +var ( + mockMsgTransmitter = utils.RandomAddress() +) + +func TestUSDCReader_callAttestationApi(t *testing.T) { + t.Skipf("Skipping test because it uses the real USDC attestation API") + usdcMessageHash := "912f22a13e9ccb979b621500f6952b2afd6e75be7eadaed93fc2625fe11c52a2" + attestationURI, err := url.ParseRequestURI("https://iris-api-sandbox.circle.com") + require.NoError(t, err) + lggr := logger.TestLogger(t) + usdcReader, _ := ccipdata.NewUSDCReader(lggr, "job_123", mockMsgTransmitter, nil, false) + usdcService := NewUSDCTokenDataReader(lggr, usdcReader, attestationURI, 0, common.Address{}, APIIntervalRateLimitDisabled) + + attestation, err := usdcService.callAttestationApi(context.Background(), [32]byte(common.FromHex(usdcMessageHash))) + require.NoError(t, err) + + require.Equal(t, attestationStatusPending, attestation.Status) + require.Equal(t, "PENDING", attestation.Attestation) +} + +func TestUSDCReader_callAttestationApiMock(t *testing.T) { + response := attestationResponse{ + Status: attestationStatusSuccess, + Attestation: "720502893578a89a8a87982982ef781c18b193", + } + + ts := getMockUSDCEndpoint(t, response) + defer ts.Close() + attestationURI, err := url.ParseRequestURI(ts.URL) + require.NoError(t, err) + + lggr := logger.TestLogger(t) + lp := mocks.NewLogPoller(t) + usdcReader, _ := ccipdata.NewUSDCReader(lggr, "job_123", mockMsgTransmitter, lp, false) + usdcService := NewUSDCTokenDataReader(lggr, usdcReader, attestationURI, 0, common.Address{}, APIIntervalRateLimitDisabled) + attestation, err := usdcService.callAttestationApi(context.Background(), utils.RandomBytes32()) + require.NoError(t, err) + + require.Equal(t, response.Status, attestation.Status) + require.Equal(t, response.Attestation, attestation.Attestation) +} + +func TestUSDCReader_callAttestationApiMockError(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + getTs func() *httptest.Server + parentTimeoutSeconds int + customTimeoutSeconds int + expectedError error + }{ + { + name: "server error", + getTs: func() *httptest.Server { + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + })) + }, + parentTimeoutSeconds: 60, + expectedError: nil, + }, + { + name: "default timeout", + getTs: func() *httptest.Server { + response := attestationResponse{ + Status: attestationStatusSuccess, + Attestation: "720502893578a89a8a87982982ef781c18b193", + } + responseBytes, _ := json.Marshal(response) + + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + time.Sleep(defaultAttestationTimeout + time.Second) + _, err := w.Write(responseBytes) + require.NoError(t, err) + })) + }, + parentTimeoutSeconds: 60, + expectedError: tokendata.ErrTimeout, + }, + { + name: "custom timeout", + getTs: func() *httptest.Server { + response := attestationResponse{ + Status: attestationStatusSuccess, + Attestation: "720502893578a89a8a87982982ef781c18b193", + } + responseBytes, _ := json.Marshal(response) + + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + time.Sleep(2*time.Second + time.Second) + _, err := w.Write(responseBytes) + require.NoError(t, err) + })) + }, + parentTimeoutSeconds: 60, + customTimeoutSeconds: 2, + expectedError: tokendata.ErrTimeout, + }, + { + name: "error response", + getTs: func() *httptest.Server { + response := attestationResponse{ + Error: "some error", + } + responseBytes, _ := json.Marshal(response) + + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := w.Write(responseBytes) + require.NoError(t, err) + })) + }, + parentTimeoutSeconds: 60, + expectedError: nil, + }, + { + name: "invalid status", + getTs: func() *httptest.Server { + response := attestationResponse{ + Status: "", + Attestation: "720502893578a89a8a87982982ef781c18b193", + } + responseBytes, _ := json.Marshal(response) + + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := w.Write(responseBytes) + require.NoError(t, err) + })) + }, + parentTimeoutSeconds: 60, + expectedError: nil, + }, + { + name: "rate limit", + getTs: func() *httptest.Server { + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusTooManyRequests) + })) + }, + parentTimeoutSeconds: 60, + expectedError: tokendata.ErrRateLimit, + }, + { + name: "parent context timeout", + getTs: func() *httptest.Server { + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + time.Sleep(defaultAttestationTimeout + time.Second) + })) + }, + parentTimeoutSeconds: 1, + expectedError: nil, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + ts := test.getTs() + defer ts.Close() + + attestationURI, err := url.ParseRequestURI(ts.URL) + require.NoError(t, err) + + lggr := logger.TestLogger(t) + lp := mocks.NewLogPoller(t) + usdcReader, _ := ccipdata.NewUSDCReader(lggr, "job_123", mockMsgTransmitter, lp, false) + usdcService := NewUSDCTokenDataReader(lggr, usdcReader, attestationURI, test.customTimeoutSeconds, common.Address{}, APIIntervalRateLimitDisabled) + lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil) + require.NoError(t, usdcReader.RegisterFilters()) + + parentCtx, cancel := context.WithTimeout(context.Background(), time.Duration(test.parentTimeoutSeconds)*time.Second) + defer cancel() + + _, err = usdcService.callAttestationApi(parentCtx, utils.RandomBytes32()) + require.Error(t, err) + + if test.expectedError != nil { + require.True(t, errors.Is(err, test.expectedError)) + } + lp.On("UnregisterFilter", mock.Anything, mock.Anything).Return(nil) + require.NoError(t, usdcReader.Close()) + }) + } +} + +func getMockUSDCEndpoint(t *testing.T, response attestationResponse) *httptest.Server { + responseBytes, err := json.Marshal(response) + require.NoError(t, err) + + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := w.Write(responseBytes) + require.NoError(t, err) + })) +} + +func TestGetUSDCMessageBody(t *testing.T) { + expectedBody := []byte("0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861") + usdcReader := ccipdatamocks.USDCReader{} + usdcReader.On("GetUSDCMessagePriorToLogIndexInTx", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(expectedBody, nil) + + usdcTokenAddr := utils.RandomAddress() + lggr := logger.TestLogger(t) + usdcService := NewUSDCTokenDataReader(lggr, &usdcReader, nil, 0, usdcTokenAddr, APIIntervalRateLimitDisabled) + + // Make the first call and assert the underlying function is called + body, err := usdcService.getUSDCMessageBody(context.Background(), cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + TokenAmounts: []cciptypes.TokenAmount{ + { + Token: ccipcalc.EvmAddrToGeneric(usdcTokenAddr), + Amount: big.NewInt(rand.Int63()), + }, + }, + }, + }, 0) + require.NoError(t, err) + require.Equal(t, body, expectedBody) + + usdcReader.AssertNumberOfCalls(t, "GetUSDCMessagePriorToLogIndexInTx", 1) +} + +func TestTokenDataReader_getUsdcTokenEndOffset(t *testing.T) { + usdcToken := utils.RandomAddress() + nonUsdcToken := utils.RandomAddress() + + multipleTokens := []common.Address{ + usdcToken, // 2 + nonUsdcToken, + nonUsdcToken, + usdcToken, // 1 + usdcToken, // 0 + nonUsdcToken, + } + + testCases := []struct { + name string + tokens []common.Address + tokenIndex int + expOffset int + expErr bool + }{ + {name: "one non usdc token", tokens: []common.Address{nonUsdcToken}, tokenIndex: 0, expOffset: 0, expErr: true}, + {name: "one usdc token", tokens: []common.Address{usdcToken}, tokenIndex: 0, expOffset: 0, expErr: false}, + {name: "one usdc token wrong index", tokens: []common.Address{usdcToken}, tokenIndex: 1, expOffset: 0, expErr: true}, + {name: "multiple tokens 1", tokens: multipleTokens, tokenIndex: 0, expOffset: 2}, + {name: "multiple tokens - non usdc selected", tokens: multipleTokens, tokenIndex: 2, expErr: true}, + {name: "multiple tokens 2", tokens: multipleTokens, tokenIndex: 3, expOffset: 1}, + {name: "multiple tokens 3", tokens: multipleTokens, tokenIndex: 4, expOffset: 0}, + {name: "multiple tokens not found", tokens: multipleTokens, tokenIndex: 5, expErr: true}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + r := &TokenDataReader{usdcTokenAddress: usdcToken} + tokenAmounts := make([]cciptypes.TokenAmount, len(tc.tokens)) + for i := range tokenAmounts { + tokenAmounts[i] = cciptypes.TokenAmount{ + Token: ccipcalc.EvmAddrToGeneric(tc.tokens[i]), + Amount: big.NewInt(rand.Int63()), + } + } + msg := cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{EVM2EVMMessage: cciptypes.EVM2EVMMessage{TokenAmounts: tokenAmounts}} + offset, err := r.getUsdcTokenEndOffset(msg, tc.tokenIndex) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, tc.expOffset, offset) + }) + } +} + +func TestUSDCReader_rateLimiting(t *testing.T) { + testCases := []struct { + name string + requests uint64 + rateConfig time.Duration + testDuration time.Duration + timeout time.Duration + err string + }{ + { + name: "no rate limit when disabled", + requests: 10, + rateConfig: APIIntervalRateLimitDisabled, + testDuration: 1 * time.Millisecond, + }, + { + name: "yes rate limited with default config", + requests: 5, + rateConfig: APIIntervalRateLimitDefault, + testDuration: 4 * defaultRequestInterval, + }, + { + name: "yes rate limited with config", + requests: 10, + rateConfig: 50 * time.Millisecond, + testDuration: 9 * 50 * time.Millisecond, + }, + { + name: "timeout after first request", + requests: 5, + rateConfig: 100 * time.Millisecond, + testDuration: 1 * time.Millisecond, + timeout: 1 * time.Millisecond, + err: "usdc rate limiting error:", + }, + { + name: "timeout after second request", + requests: 5, + rateConfig: 100 * time.Millisecond, + testDuration: 100 * time.Millisecond, + timeout: 150 * time.Millisecond, + err: "usdc rate limiting error:", + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + response := attestationResponse{ + Status: attestationStatusSuccess, + Attestation: "720502893578a89a8a87982982ef781c18b193", + } + + ts := getMockUSDCEndpoint(t, response) + defer ts.Close() + attestationURI, err := url.ParseRequestURI(ts.URL) + require.NoError(t, err) + + lggr := logger.TestLogger(t) + lp := mocks.NewLogPoller(t) + usdcReader, _ := ccipdata.NewUSDCReader(lggr, "job_123", mockMsgTransmitter, lp, false) + usdcService := NewUSDCTokenDataReader(lggr, usdcReader, attestationURI, 0, utils.RandomAddress(), tc.rateConfig) + + ctx := context.Background() + if tc.timeout > 0 { + var cf context.CancelFunc + ctx, cf = context.WithTimeout(ctx, tc.timeout) + defer cf() + } + + trigger := make(chan struct{}) + errorChan := make(chan error, tc.requests) + wg := sync.WaitGroup{} + for i := 0; i < int(tc.requests); i++ { + wg.Add(1) + go func() { + defer wg.Done() + + <-trigger + _, err := usdcService.ReadTokenData(ctx, cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: cciptypes.EVM2EVMMessage{ + TokenAmounts: []cciptypes.TokenAmount{{Token: ccipcalc.EvmAddrToGeneric(utils.ZeroAddress), Amount: nil}}, // trigger failure due to wrong address + }, + }, 0) + + errorChan <- err + }() + } + + // Start the test + start := time.Now() + close(trigger) + + // Wait for requests to complete + wg.Wait() + finish := time.Now() + close(errorChan) + + // Collect errors + errorFound := false + for err := range errorChan { + if tc.err != "" && strings.Contains(err.Error(), tc.err) { + errorFound = true + } else if err != nil && !strings.Contains(err.Error(), "get usdc token 0 end offset") { + // Ignore that one error, it's expected because of how mocking is used. + // Anything else is unexpected. + require.Fail(t, "unexpected error", err) + } + } + + if tc.err != "" { + assert.True(t, errorFound) + } + assert.WithinDuration(t, start.Add(tc.testDuration), finish, 50*time.Millisecond) + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/transactions.rlp b/core/services/ocr2/plugins/ccip/transactions.rlp new file mode 100644 index 0000000000000000000000000000000000000000..96cfc2f48238eef5e38307f425334221e5a48903 GIT binary patch literal 115794 zcmeI5TZmRw6vxkLnz2U5%QT~oI{E2%ziW6)s$*7Ggpol(B}^BCh#=7l?B!@yLf40) zD2fl%E|5{FJtV}z%Zq_obbaaz3HfuAMX9I_x^t`-KARt?*-?5#t|mJz>hOJ2L7>#HYj|8wuMaa&ezxPQxa8$UVI(V2gd?mxQc z$#oAW@~a}2)BRPko+R@9Nus%bkla3fswQ5L?!Rz(=&4`M{`M*V>R`0ntHFMex;^9UQ@4V>Jv2eiJE$!rannipRB1*(bT7E z>eDp!>6-csO?{@OK1)-dt*Ot^)aPpI^ECDOn!3&(ntEF%_wUH%dRHOWb-%s(GWq@) zxm=%L$n~XiImt5lf|a>kUscHUyX11RCX+9CD3|Mx7IJ;PTuwG-@&%i6xxTfK>#xe? zsA=eMd<>Z@8zTl@^uK!ZV^<#25`8|^__#>C= ze-~ms)%@`?9h}Mccjj`vr;zI!eWueg`Tn`NTwhek^=rj)lHQn!7o@l4a{bOiuHP$` zlk|a1ydZrf7wgHOid;`L_0}bt`%|g@-(NxLYxmUEKY#e`Gp8rtdiwW++aKDoaK@|s zw62K7{z>{=RdLS+Qz!bK|9RKh&(ocYcfIocq0=v{-Fo1)3toJ#kmho|wMy%))9mJ!^OOv~?fbeaD>#zB~SGZAnk-;Z65_kUnty@adx; zy-n}uam(>`yg&d1f+xU#?;B+XeEmnYe>7bN?AO@u=d7IjQ~dg%1%HbD;m_dL3I+s$ zC-x8P5)Kl~Z|TET!I5Cs9Efo4MZlhE?e zpW^p_vEWa!Kl~ZRYQc~o5Ig~*fo4MZlhE?epY7!MEVSTHu|ND7{93_)AP@xswmi)e z@F(Hqp+Cj%A8Ns$Vt@EEiq(Q4K_GYnL<7x)@F$_=p+Cj%uWiAfVt@EE__cxoK_ChO zL<7x)@F$_=p+7sw@mXlWpJIRbGm6!MAweK`0&IDjCE!oO$wPmNKcC5hKgIs=XYgwU z1A;&l1c(Nj3E@vd%R_&PKflm|KgIs=XB4XiLxMo?1c(Nj3E@vd%R_&PKi}7aKgIs= zXYgwU1A;&l1c(Nj3E@vd%R_&TAjfB+1%HbD;m;^m3x))N;0dthX_kOL2`3Nz*-4Ji zLJR&B`@^5XuN4dk0#OiP%hN0Ye-cg}`tu5Md=^^pr`R96iaa~wH73oZCl><@nizg93H2t+}EEl;xq z{7E=@=+9nqd=^^pr`R9Kkt%hN0Ye-cg}`m;ig&q53S6#K)U z!LJnz2m(S!ltZVt@EEiq(Q4K_GYnY*w*(4SMu@mXlWpJIRbGm6!M zAweK`0&IDjCE!oO$wPlmBgbc<1%HbD;m_dL3I+s$CCSS=V51cE2PmZw<){v@0{^ydt6d=^^pr`R9<41TR(KoE$609&4B3HXz6^3b0% z$?;ie!JlG(_%n*tf+0a5cmiyBnkC>*!pTE_&LYQWp#^`6{o&8x*9ry%fhY*D+tRt};|c-TlgRBRR5YgvwxaMVW3Sd-6u8 z493)y=|*x~)(DkBZ&jIYB*!-*bx`S7=j+)CMLkl#_f^#SdUjG?kJRszYwCPGJ2k6E z>i20?b-tdJzr9D2%Fv4bR)U6(g>Bo)wwd=NG_{2LS=AGrc5`I*H#;$GRTzKGP%6Jj8)O~ zg(_R-Zm5*8D!MUOWy{=6wK7&kH)pDBnY*Q0#>!}bzZF;L?k^Pg&{U0nz~hvs24vF8 zfDirq0DRs4nt?C)x+UPYJDy+gbxXi)cRat~>z07q?s$H|*DV3J-SPZ_uUi6cyW{x< zU$+F@cE|GzzHSM)?T+UceBBao+a1p@__`(FwmY6*@O4YTZFfAs;Omxv+wORN!PhMT zx83plg0EWwZoA|81z)!W+;+$F3%+g%xb2ST7ku3kaN8ZvFZjA8;I=!SU+{HHz-@Ot zzu@bZfZOhPe!d22B2VYv8!-m9zeQzgjuebLq<`58ko< f%sW4PJ^b+#k36<=Maz-pBVSzc_B*Fe4&U$(Vy%t% literal 0 HcmV?d00001 diff --git a/core/services/ocr2/plugins/ccip/transmitter/transmitter.go b/core/services/ocr2/plugins/ccip/transmitter/transmitter.go new file mode 100644 index 0000000000..3e2962b33a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/transmitter/transmitter.go @@ -0,0 +1,143 @@ +package transmitter + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + statuschecker "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/statuschecker" +) + +type roundRobinKeystore interface { + GetRoundRobinAddress(ctx context.Context, chainID *big.Int, addresses ...common.Address) (address common.Address, err error) +} + +type txManager interface { + CreateTransaction(ctx context.Context, txRequest txmgr.TxRequest) (tx txmgr.Tx, err error) + GetTransactionStatus(ctx context.Context, transactionID string) (state commontypes.TransactionStatus, err error) +} + +type Transmitter interface { + CreateEthTransaction(ctx context.Context, toAddress common.Address, payload []byte, txMeta *txmgr.TxMeta) error + FromAddress() common.Address +} + +type transmitter struct { + txm txManager + fromAddresses []common.Address + gasLimit uint64 + effectiveTransmitterAddress common.Address + strategy types.TxStrategy + checker txmgr.TransmitCheckerSpec + chainID *big.Int + keystore roundRobinKeystore + statuschecker statuschecker.CCIPTransactionStatusChecker // Used for CCIP's idempotency key generation +} + +// NewTransmitter creates a new eth transmitter +func NewTransmitter( + txm txManager, + fromAddresses []common.Address, + gasLimit uint64, + effectiveTransmitterAddress common.Address, + strategy types.TxStrategy, + checker txmgr.TransmitCheckerSpec, + chainID *big.Int, + keystore roundRobinKeystore, +) (Transmitter, error) { + // Ensure that a keystore is provided. + if keystore == nil { + return nil, errors.New("nil keystore provided to transmitter") + } + + return &transmitter{ + txm: txm, + fromAddresses: fromAddresses, + gasLimit: gasLimit, + effectiveTransmitterAddress: effectiveTransmitterAddress, + strategy: strategy, + checker: checker, + chainID: chainID, + keystore: keystore, + }, nil +} + +func NewTransmitterWithStatusChecker( + txm txManager, + fromAddresses []common.Address, + gasLimit uint64, + effectiveTransmitterAddress common.Address, + strategy types.TxStrategy, + checker txmgr.TransmitCheckerSpec, + chainID *big.Int, + keystore roundRobinKeystore, +) (Transmitter, error) { + t, err := NewTransmitter(txm, fromAddresses, gasLimit, effectiveTransmitterAddress, strategy, checker, chainID, keystore) + + if err != nil { + return nil, err + } + + transmitter, ok := t.(*transmitter) + if !ok { + return nil, errors.New("failed to type assert Transmitter to *transmitter") + } + transmitter.statuschecker = statuschecker.NewTxmStatusChecker(txm.GetTransactionStatus) + + return transmitter, nil +} + +func (t *transmitter) CreateEthTransaction(ctx context.Context, toAddress common.Address, payload []byte, txMeta *txmgr.TxMeta) error { + roundRobinFromAddress, err := t.keystore.GetRoundRobinAddress(ctx, t.chainID, t.fromAddresses...) + if err != nil { + return fmt.Errorf("skipped OCR transmission, error getting round-robin address: %w", err) + } + + var idempotencyKey *string + + // Define idempotency key for CCIP Execution Plugin + if len(txMeta.MessageIDs) == 1 && t.statuschecker != nil { + messageId := txMeta.MessageIDs[0] + _, count, err1 := t.statuschecker.CheckMessageStatus(ctx, messageId) + + if err1 != nil { + return errors.Wrap(err, "skipped OCR transmission, error getting message status") + } + idempotencyKey = func() *string { + s := fmt.Sprintf("%s-%d", messageId, count+1) + return &s + }() + } + + _, err = t.txm.CreateTransaction(ctx, txmgr.TxRequest{ + IdempotencyKey: idempotencyKey, + FromAddress: roundRobinFromAddress, + ToAddress: toAddress, + EncodedPayload: payload, + FeeLimit: t.gasLimit, + ForwarderAddress: t.forwarderAddress(), + Strategy: t.strategy, + Checker: t.checker, + Meta: txMeta, + }) + return errors.Wrap(err, "skipped OCR transmission") +} + +func (t *transmitter) FromAddress() common.Address { + return t.effectiveTransmitterAddress +} + +func (t *transmitter) forwarderAddress() common.Address { + for _, a := range t.fromAddresses { + if a == t.effectiveTransmitterAddress { + return common.Address{} + } + } + return t.effectiveTransmitterAddress +} diff --git a/core/services/ocr2/plugins/ccip/transmitter/transmitter_test.go b/core/services/ocr2/plugins/ccip/transmitter/transmitter_test.go new file mode 100644 index 0000000000..d177f1baa5 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/transmitter/transmitter_test.go @@ -0,0 +1,282 @@ +package transmitter + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink-common/pkg/types" + commontxmmocks "github.com/smartcontractkit/chainlink/v2/common/txmgr/types/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + txmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +var ( + FixtureChainID = *testutils.FixtureChainID + Password = testutils.Password +) + +func newMockTxStrategy(t *testing.T) *commontxmmocks.TxStrategy { + return commontxmmocks.NewTxStrategy(t) +} + +func Test_DefaultTransmitter_CreateEthTransaction(t *testing.T) { + t.Parallel() + + db := pgtest.NewSqlxDB(t) + ethKeyStore := NewKeyStore(t, db).Eth() + + _, fromAddress := MustInsertRandomKey(t, ethKeyStore) + + gasLimit := uint64(1000) + chainID := big.NewInt(0) + effectiveTransmitterAddress := fromAddress + toAddress := testutils.NewAddress() + payload := []byte{1, 2, 3} + txm := txmmocks.NewMockEvmTxManager(t) + strategy := newMockTxStrategy(t) + + transmitter, err := ocrcommon.NewTransmitter( + txm, + []common.Address{fromAddress}, + gasLimit, + effectiveTransmitterAddress, + strategy, + txmgr.TransmitCheckerSpec{}, + chainID, + ethKeyStore, + ) + require.NoError(t, err) + + txm.On("CreateTransaction", mock.Anything, txmgr.TxRequest{ + FromAddress: fromAddress, + ToAddress: toAddress, + EncodedPayload: payload, + FeeLimit: gasLimit, + ForwarderAddress: common.Address{}, + Meta: nil, + Strategy: strategy, + }).Return(txmgr.Tx{}, nil).Once() + require.NoError(t, transmitter.CreateEthTransaction(testutils.Context(t), toAddress, payload, nil)) +} + +func Test_DefaultTransmitter_Forwarding_Enabled_CreateEthTransaction(t *testing.T) { + t.Parallel() + + db := pgtest.NewSqlxDB(t) + ethKeyStore := NewKeyStore(t, db).Eth() + + _, fromAddress := MustInsertRandomKey(t, ethKeyStore) + _, fromAddress2 := MustInsertRandomKey(t, ethKeyStore) + + gasLimit := uint64(1000) + chainID := big.NewInt(0) + effectiveTransmitterAddress := common.Address{} + toAddress := testutils.NewAddress() + payload := []byte{1, 2, 3} + txm := txmmocks.NewMockEvmTxManager(t) + strategy := newMockTxStrategy(t) + + transmitter, err := ocrcommon.NewTransmitter( + txm, + []common.Address{fromAddress, fromAddress2}, + gasLimit, + effectiveTransmitterAddress, + strategy, + txmgr.TransmitCheckerSpec{}, + chainID, + ethKeyStore, + ) + require.NoError(t, err) + + txm.On("CreateTransaction", mock.Anything, txmgr.TxRequest{ + FromAddress: fromAddress, + ToAddress: toAddress, + EncodedPayload: payload, + FeeLimit: gasLimit, + ForwarderAddress: common.Address{}, + Meta: nil, + Strategy: strategy, + }).Return(txmgr.Tx{}, nil).Once() + txm.On("CreateTransaction", mock.Anything, txmgr.TxRequest{ + FromAddress: fromAddress2, + ToAddress: toAddress, + EncodedPayload: payload, + FeeLimit: gasLimit, + ForwarderAddress: common.Address{}, + Meta: nil, + Strategy: strategy, + }).Return(txmgr.Tx{}, nil).Once() + require.NoError(t, transmitter.CreateEthTransaction(testutils.Context(t), toAddress, payload, nil)) + require.NoError(t, transmitter.CreateEthTransaction(testutils.Context(t), toAddress, payload, nil)) +} + +func Test_DefaultTransmitter_Forwarding_Enabled_CreateEthTransaction_Round_Robin_Error(t *testing.T) { + t.Parallel() + + db := pgtest.NewSqlxDB(t) + ethKeyStore := NewKeyStore(t, db).Eth() + + fromAddress := common.Address{} + + gasLimit := uint64(1000) + chainID := big.NewInt(0) + effectiveTransmitterAddress := common.Address{} + toAddress := testutils.NewAddress() + payload := []byte{1, 2, 3} + txm := txmmocks.NewMockEvmTxManager(t) + strategy := newMockTxStrategy(t) + + transmitter, err := ocrcommon.NewTransmitter( + txm, + []common.Address{fromAddress}, + gasLimit, + effectiveTransmitterAddress, + strategy, + txmgr.TransmitCheckerSpec{}, + chainID, + ethKeyStore, + ) + require.NoError(t, err) + require.Error(t, transmitter.CreateEthTransaction(testutils.Context(t), toAddress, payload, nil)) +} + +func Test_DefaultTransmitter_Forwarding_Enabled_CreateEthTransaction_No_Keystore_Error(t *testing.T) { + t.Parallel() + + db := pgtest.NewSqlxDB(t) + ethKeyStore := NewKeyStore(t, db).Eth() + + _, fromAddress := MustInsertRandomKey(t, ethKeyStore) + _, fromAddress2 := MustInsertRandomKey(t, ethKeyStore) + + gasLimit := uint64(1000) + chainID := big.NewInt(0) + effectiveTransmitterAddress := common.Address{} + txm := txmmocks.NewMockEvmTxManager(t) + strategy := newMockTxStrategy(t) + + _, err := ocrcommon.NewTransmitter( + txm, + []common.Address{fromAddress, fromAddress2}, + gasLimit, + effectiveTransmitterAddress, + strategy, + txmgr.TransmitCheckerSpec{}, + chainID, + nil, + ) + require.Error(t, err) +} + +func Test_Transmitter_With_StatusChecker_CreateEthTransaction(t *testing.T) { + t.Parallel() + + db := pgtest.NewSqlxDB(t) + ethKeyStore := NewKeyStore(t, db).Eth() + + _, fromAddress := MustInsertRandomKey(t, ethKeyStore) + + gasLimit := uint64(1000) + chainID := big.NewInt(0) + effectiveTransmitterAddress := fromAddress + txm := txmmocks.NewMockEvmTxManager(t) + strategy := newMockTxStrategy(t) + toAddress := testutils.NewAddress() + payload := []byte{1, 2, 3} + idempotencyKey := "1-0" + txMeta := &txmgr.TxMeta{MessageIDs: []string{"1"}} + + transmitter, err := NewTransmitterWithStatusChecker( + txm, + []common.Address{fromAddress}, + gasLimit, + effectiveTransmitterAddress, + strategy, + txmgr.TransmitCheckerSpec{}, + chainID, + ethKeyStore, + ) + require.NoError(t, err) + + // This case is for when the message ID was not found in the status checker + txm.On("GetTransactionStatus", mock.Anything, idempotencyKey).Return(types.Unknown, errors.New("dummy")).Once() + + txm.On("CreateTransaction", mock.Anything, txmgr.TxRequest{ + IdempotencyKey: &idempotencyKey, + FromAddress: fromAddress, + ToAddress: toAddress, + EncodedPayload: payload, + FeeLimit: gasLimit, + ForwarderAddress: common.Address{}, + Meta: txMeta, + Strategy: strategy, + }).Return(txmgr.Tx{}, nil).Once() + + require.NoError(t, transmitter.CreateEthTransaction(testutils.Context(t), toAddress, payload, txMeta)) + txm.AssertExpectations(t) +} + +func NewKeyStore(t testing.TB, ds sqlutil.DataSource) keystore.Master { + ctx := testutils.Context(t) + keystore := keystore.NewInMemory(ds, utils.FastScryptParams, logger.TestLogger(t)) + require.NoError(t, keystore.Unlock(ctx, Password)) + return keystore +} + +type RandomKey struct { + Nonce int64 + Disabled bool + + chainIDs []ubig.Big // nil: Fixture, set empty for none +} + +func (r RandomKey) MustInsert(t testing.TB, keystore keystore.Eth) (ethkey.KeyV2, common.Address) { + ctx := testutils.Context(t) + chainIDs := r.chainIDs + if chainIDs == nil { + chainIDs = []ubig.Big{*ubig.New(&FixtureChainID)} + } + + key := MustGenerateRandomKey(t) + keystore.XXXTestingOnlyAdd(ctx, key) + + for _, cid := range chainIDs { + require.NoError(t, keystore.Add(ctx, key.Address, cid.ToInt())) + require.NoError(t, keystore.Enable(ctx, key.Address, cid.ToInt())) + if r.Disabled { + require.NoError(t, keystore.Disable(ctx, key.Address, cid.ToInt())) + } + } + + return key, key.Address +} + +func MustInsertRandomKey(t testing.TB, keystore keystore.Eth, chainIDs ...ubig.Big) (ethkey.KeyV2, common.Address) { + r := RandomKey{} + if len(chainIDs) > 0 { + r.chainIDs = chainIDs + } + return r.MustInsert(t, keystore) +} + +func MustGenerateRandomKey(t testing.TB) ethkey.KeyV2 { + key, err := ethkey.NewV2() + require.NoError(t, err) + return key +} diff --git a/core/services/ocr2/plugins/ccip/vars.go b/core/services/ocr2/plugins/ccip/vars.go new file mode 100644 index 0000000000..a44f5e41d6 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/vars.go @@ -0,0 +1,14 @@ +package ccip + +import ( + "github.com/pkg/errors" +) + +const ( + MaxQueryLength = 0 // empty for both plugins + MaxObservationLength = 250_000 // plugins's Observation should make sure to cap to this limit + CommitPluginLabel = "commit" + ExecPluginLabel = "exec" +) + +var ErrChainIsNotHealthy = errors.New("lane processing is stopped because of healthcheck failure, please see crit logs") diff --git a/core/services/ocr2/validate/validate.go b/core/services/ocr2/validate/validate.go index 2993a67114..8d98a28267 100644 --- a/core/services/ocr2/validate/validate.go +++ b/core/services/ocr2/validate/validate.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "os/exec" + "strings" "github.com/lib/pq" "github.com/pelletier/go-toml" @@ -19,9 +20,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" lloconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/llo/config" mercuryconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/plugins" ) @@ -115,6 +118,10 @@ func validateSpec(ctx context.Context, tree *toml.Tree, spec job.Job, rc plugins return nil case types.Mercury: return validateOCR2MercurySpec(spec.OCR2OracleSpec.PluginConfig, *spec.OCR2OracleSpec.FeedID) + case types.CCIPExecution: + return validateOCR2CCIPExecutionSpec(spec.OCR2OracleSpec.PluginConfig) + case types.CCIPCommit: + return validateOCR2CCIPCommitSpec(spec.OCR2OracleSpec.PluginConfig) case types.LLO: return validateOCR2LLOSpec(spec.OCR2OracleSpec.PluginConfig) case types.GenericPlugin: @@ -313,11 +320,61 @@ func validateOCR2MercurySpec(jsonConfig job.JSONConfig, feedId [32]byte) error { var pluginConfig mercuryconfig.PluginConfig err := json.Unmarshal(jsonConfig.Bytes(), &pluginConfig) if err != nil { - return pkgerrors.Wrap(err, "error while unmarshaling plugin config") + return pkgerrors.Wrap(err, "error while unmarshalling plugin config") } return pkgerrors.Wrap(mercuryconfig.ValidatePluginConfig(pluginConfig, feedId), "Mercury PluginConfig is invalid") } +func validateOCR2CCIPExecutionSpec(jsonConfig job.JSONConfig) error { + if jsonConfig == nil { + return errors.New("pluginConfig is empty") + } + var cfg config.ExecPluginJobSpecConfig + err := json.Unmarshal(jsonConfig.Bytes(), &cfg) + if err != nil { + return pkgerrors.Wrap(err, "error while unmarshalling plugin config") + } + if cfg.USDCConfig != (config.USDCConfig{}) { + return cfg.USDCConfig.ValidateUSDCConfig() + } + return nil +} + +func validateOCR2CCIPCommitSpec(jsonConfig job.JSONConfig) error { + if jsonConfig == nil { + return errors.New("pluginConfig is empty") + } + var cfg config.CommitPluginJobSpecConfig + err := json.Unmarshal(jsonConfig.Bytes(), &cfg) + if err != nil { + return pkgerrors.Wrap(err, "error while unmarshalling plugin config") + } + + // Ensure that either the tokenPricesUSDPipeline or the priceGetterConfig is set, but not both. + emptyPipeline := strings.Trim(cfg.TokenPricesUSDPipeline, "\n\t ") == "" + emptyPriceGetter := cfg.PriceGetterConfig == nil + if emptyPipeline && emptyPriceGetter { + return fmt.Errorf("either tokenPricesUSDPipeline or priceGetterConfig must be set") + } + if !emptyPipeline && !emptyPriceGetter { + return fmt.Errorf("only one of tokenPricesUSDPipeline or priceGetterConfig must be set: %s and %v", cfg.TokenPricesUSDPipeline, cfg.PriceGetterConfig) + } + + if !emptyPipeline { + _, err = pipeline.Parse(cfg.TokenPricesUSDPipeline) + if err != nil { + return pkgerrors.Wrap(err, "invalid token prices pipeline") + } + } else { + // Validate prices config (like it was done for the pipeline). + if emptyPriceGetter { + return pkgerrors.New("priceGetterConfig is empty") + } + } + + return nil +} + func validateOCR2LLOSpec(jsonConfig job.JSONConfig) error { var pluginConfig lloconfig.PluginConfig err := json.Unmarshal(jsonConfig.Bytes(), &pluginConfig) diff --git a/core/services/relay/evm/ccip.go b/core/services/relay/evm/ccip.go new file mode 100644 index 0000000000..34a732e145 --- /dev/null +++ b/core/services/relay/evm/ccip.go @@ -0,0 +1,205 @@ +package evm + +import ( + "context" + "fmt" + "math/big" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/logger" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" +) + +var _ cciptypes.CommitStoreReader = (*IncompleteSourceCommitStoreReader)(nil) +var _ cciptypes.CommitStoreReader = (*IncompleteDestCommitStoreReader)(nil) + +// IncompleteSourceCommitStoreReader is an implementation of CommitStoreReader with the only valid methods being +// GasPriceEstimator, ChangeConfig, and OffchainConfig +type IncompleteSourceCommitStoreReader struct { + estimator gas.EvmFeeEstimator + gasPriceEstimator *prices.DAGasPriceEstimator + sourceMaxGasPrice *big.Int + offchainConfig cciptypes.CommitOffchainConfig +} + +func NewIncompleteSourceCommitStoreReader(estimator gas.EvmFeeEstimator, sourceMaxGasPrice *big.Int) *IncompleteSourceCommitStoreReader { + return &IncompleteSourceCommitStoreReader{ + estimator: estimator, + sourceMaxGasPrice: sourceMaxGasPrice, + } +} + +func (i *IncompleteSourceCommitStoreReader) ChangeConfig(ctx context.Context, onchainConfig []byte, offchainConfig []byte) (cciptypes.Address, error) { + onchainConfigParsed, err := abihelpers.DecodeAbiStruct[ccip.CommitOnchainConfig](onchainConfig) + if err != nil { + return "", err + } + + offchainConfigParsed, err := ccipconfig.DecodeOffchainConfig[ccip.JSONCommitOffchainConfigV1_2_0](offchainConfig) + if err != nil { + return "", err + } + + i.gasPriceEstimator = prices.NewDAGasPriceEstimator( + i.estimator, + i.sourceMaxGasPrice, + int64(offchainConfigParsed.ExecGasPriceDeviationPPB), + int64(offchainConfigParsed.DAGasPriceDeviationPPB), + ) + i.offchainConfig = ccip.NewCommitOffchainConfig( + offchainConfigParsed.ExecGasPriceDeviationPPB, + offchainConfigParsed.GasPriceHeartBeat.Duration(), + offchainConfigParsed.TokenPriceDeviationPPB, + offchainConfigParsed.TokenPriceHeartBeat.Duration(), + offchainConfigParsed.InflightCacheExpiry.Duration(), + offchainConfigParsed.PriceReportingDisabled, + ) + + return cciptypes.Address(onchainConfigParsed.PriceRegistry.String()), nil +} + +func (i *IncompleteSourceCommitStoreReader) DecodeCommitReport(ctx context.Context, report []byte) (cciptypes.CommitStoreReport, error) { + return cciptypes.CommitStoreReport{}, fmt.Errorf("invalid usage of IncompleteSourceCommitStoreReader") +} + +func (i *IncompleteSourceCommitStoreReader) EncodeCommitReport(ctx context.Context, report cciptypes.CommitStoreReport) ([]byte, error) { + return []byte{}, fmt.Errorf("invalid usage of IncompleteSourceCommitStoreReader") +} + +// GasPriceEstimator returns an ExecGasPriceEstimator to satisfy the GasPriceEstimatorCommit interface, +// with deviationPPB values hardcoded to 0 when this implementation is first constructed. +// When ChangeConfig is called, another call to this method must be made to fetch a GasPriceEstimator with updated values +func (i *IncompleteSourceCommitStoreReader) GasPriceEstimator(ctx context.Context) (cciptypes.GasPriceEstimatorCommit, error) { + return i.gasPriceEstimator, nil +} + +func (i *IncompleteSourceCommitStoreReader) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confirmations int) ([]cciptypes.CommitStoreReportWithTxMeta, error) { + return nil, fmt.Errorf("invalid usage of IncompleteSourceCommitStoreReader") +} + +func (i *IncompleteSourceCommitStoreReader) GetCommitReportMatchingSeqNum(ctx context.Context, seqNum uint64, confirmations int) ([]cciptypes.CommitStoreReportWithTxMeta, error) { + return nil, fmt.Errorf("invalid usage of IncompleteSourceCommitStoreReader") +} + +func (i *IncompleteSourceCommitStoreReader) GetCommitStoreStaticConfig(ctx context.Context) (cciptypes.CommitStoreStaticConfig, error) { + return cciptypes.CommitStoreStaticConfig{}, fmt.Errorf("invalid usage of IncompleteSourceCommitStoreReader") +} + +func (i *IncompleteSourceCommitStoreReader) GetExpectedNextSequenceNumber(ctx context.Context) (uint64, error) { + return 0, fmt.Errorf("invalid usage of IncompleteSourceCommitStoreReader") +} + +func (i *IncompleteSourceCommitStoreReader) GetLatestPriceEpochAndRound(ctx context.Context) (uint64, error) { + return 0, fmt.Errorf("invalid usage of IncompleteSourceCommitStoreReader") +} + +func (i *IncompleteSourceCommitStoreReader) IsBlessed(ctx context.Context, root [32]byte) (bool, error) { + return false, fmt.Errorf("invalid usage of IncompleteSourceCommitStoreReader") +} + +func (i *IncompleteSourceCommitStoreReader) IsDestChainHealthy(ctx context.Context) (bool, error) { + return false, fmt.Errorf("invalid usage of IncompleteSourceCommitStoreReader") +} + +func (i *IncompleteSourceCommitStoreReader) IsDown(ctx context.Context) (bool, error) { + return false, fmt.Errorf("invalid usage of IncompleteSourceCommitStoreReader") +} + +func (i *IncompleteSourceCommitStoreReader) OffchainConfig(ctx context.Context) (cciptypes.CommitOffchainConfig, error) { + return i.offchainConfig, nil +} + +func (i *IncompleteSourceCommitStoreReader) VerifyExecutionReport(ctx context.Context, report cciptypes.ExecReport) (bool, error) { + return false, fmt.Errorf("invalid usage of IncompleteSourceCommitStoreReader") +} + +func (i *IncompleteSourceCommitStoreReader) Close() error { + return fmt.Errorf("invalid usage of IncompleteSourceCommitStoreReader") +} + +// IncompleteDestCommitStoreReader is an implementation of CommitStoreReader with all valid methods except +// GasPriceEstimator, ChangeConfig, and OffchainConfig. +type IncompleteDestCommitStoreReader struct { + cs cciptypes.CommitStoreReader +} + +func NewIncompleteDestCommitStoreReader(lggr logger.Logger, versionFinder ccip.VersionFinder, address cciptypes.Address, ec client.Client, lp logpoller.LogPoller) (*IncompleteDestCommitStoreReader, error) { + cs, err := ccip.NewCommitStoreReader(lggr, versionFinder, address, ec, lp) + if err != nil { + return nil, err + } + + return &IncompleteDestCommitStoreReader{ + cs: cs, + }, nil +} + +func (i *IncompleteDestCommitStoreReader) ChangeConfig(ctx context.Context, onchainConfig []byte, offchainConfig []byte) (cciptypes.Address, error) { + return "", fmt.Errorf("invalid usage of IncompleteDestCommitStoreReader") +} + +func (i *IncompleteDestCommitStoreReader) DecodeCommitReport(ctx context.Context, report []byte) (cciptypes.CommitStoreReport, error) { + return i.cs.DecodeCommitReport(ctx, report) +} + +func (i *IncompleteDestCommitStoreReader) EncodeCommitReport(ctx context.Context, report cciptypes.CommitStoreReport) ([]byte, error) { + return i.cs.EncodeCommitReport(ctx, report) +} + +func (i *IncompleteDestCommitStoreReader) GasPriceEstimator(ctx context.Context) (cciptypes.GasPriceEstimatorCommit, error) { + return nil, fmt.Errorf("invalid usage of IncompleteDestCommitStoreReader") +} + +func (i *IncompleteDestCommitStoreReader) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confirmations int) ([]cciptypes.CommitStoreReportWithTxMeta, error) { + return i.cs.GetAcceptedCommitReportsGteTimestamp(ctx, ts, confirmations) +} + +func (i *IncompleteDestCommitStoreReader) GetCommitReportMatchingSeqNum(ctx context.Context, seqNum uint64, confirmations int) ([]cciptypes.CommitStoreReportWithTxMeta, error) { + return i.cs.GetCommitReportMatchingSeqNum(ctx, seqNum, confirmations) +} + +func (i *IncompleteDestCommitStoreReader) GetCommitStoreStaticConfig(ctx context.Context) (cciptypes.CommitStoreStaticConfig, error) { + return i.cs.GetCommitStoreStaticConfig(ctx) +} + +func (i *IncompleteDestCommitStoreReader) GetExpectedNextSequenceNumber(ctx context.Context) (uint64, error) { + return i.cs.GetExpectedNextSequenceNumber(ctx) +} + +func (i *IncompleteDestCommitStoreReader) GetLatestPriceEpochAndRound(ctx context.Context) (uint64, error) { + return i.cs.GetLatestPriceEpochAndRound(ctx) +} + +func (i *IncompleteDestCommitStoreReader) IsBlessed(ctx context.Context, root [32]byte) (bool, error) { + return i.cs.IsBlessed(ctx, root) +} + +func (i *IncompleteDestCommitStoreReader) IsDestChainHealthy(ctx context.Context) (bool, error) { + return i.cs.IsDestChainHealthy(ctx) +} + +func (i *IncompleteDestCommitStoreReader) IsDown(ctx context.Context) (bool, error) { + return i.cs.IsDown(ctx) +} + +func (i *IncompleteDestCommitStoreReader) OffchainConfig(ctx context.Context) (cciptypes.CommitOffchainConfig, error) { + return cciptypes.CommitOffchainConfig{}, fmt.Errorf("invalid usage of IncompleteDestCommitStoreReader") +} + +func (i *IncompleteDestCommitStoreReader) VerifyExecutionReport(ctx context.Context, report cciptypes.ExecReport) (bool, error) { + return i.cs.VerifyExecutionReport(ctx, report) +} + +func (i *IncompleteDestCommitStoreReader) Close() error { + return i.cs.Close() +} diff --git a/core/services/relay/evm/ccip_test.go b/core/services/relay/evm/ccip_test.go new file mode 100644 index 0000000000..8c0bfe182e --- /dev/null +++ b/core/services/relay/evm/ccip_test.go @@ -0,0 +1,18 @@ +package evm + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_CCIPSubjectUUID(t *testing.T) { + // We want the function to be + // (1) an actual function (i.e., deterministic) + assert.Equal(t, chainToUUID(big.NewInt(1)), chainToUUID(big.NewInt(1))) + // (2) injective (produce different results for different inputs) + assert.NotEqual(t, chainToUUID(big.NewInt(1)), chainToUUID(big.NewInt(2))) + // (3) stable across runs + assert.Equal(t, "c980e777-c95c-577b-83f6-ceb26a1a982d", chainToUUID(big.NewInt(1)).String()) +} diff --git a/core/services/relay/evm/commit_provider.go b/core/services/relay/evm/commit_provider.go new file mode 100644 index 0000000000..fe3e327c7f --- /dev/null +++ b/core/services/relay/evm/commit_provider.go @@ -0,0 +1,309 @@ +package evm + +import ( + "context" + "fmt" + "math/big" + + "go.uber.org/multierr" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" +) + +var _ commontypes.CCIPCommitProvider = (*SrcCommitProvider)(nil) +var _ commontypes.CCIPCommitProvider = (*DstCommitProvider)(nil) + +type SrcCommitProvider struct { + lggr logger.Logger + startBlock uint64 + client client.Client + lp logpoller.LogPoller + estimator gas.EvmFeeEstimator + maxGasPrice *big.Int + + // these values will be lazily initialized + seenOnRampAddress *cciptypes.Address + seenSourceChainSelector *uint64 + seenDestChainSelector *uint64 +} + +func NewSrcCommitProvider( + lggr logger.Logger, + startBlock uint64, + client client.Client, + lp logpoller.LogPoller, + srcEstimator gas.EvmFeeEstimator, + maxGasPrice *big.Int, +) commontypes.CCIPCommitProvider { + return &SrcCommitProvider{ + lggr: lggr, + startBlock: startBlock, + client: client, + lp: lp, + estimator: srcEstimator, + maxGasPrice: maxGasPrice, + } +} + +type DstCommitProvider struct { + lggr logger.Logger + versionFinder ccip.VersionFinder + startBlock uint64 + client client.Client + lp logpoller.LogPoller + contractTransmitter *contractTransmitter + configWatcher *configWatcher + gasEstimator gas.EvmFeeEstimator + maxGasPrice big.Int + + // these values will be lazily initialized + seenCommitStoreAddress *cciptypes.Address + seenOffRampAddress *cciptypes.Address +} + +func NewDstCommitProvider( + lggr logger.Logger, + versionFinder ccip.VersionFinder, + startBlock uint64, + client client.Client, + lp logpoller.LogPoller, + gasEstimator gas.EvmFeeEstimator, + maxGasPrice big.Int, + contractTransmitter contractTransmitter, + configWatcher *configWatcher, +) commontypes.CCIPCommitProvider { + return &DstCommitProvider{ + lggr: lggr, + versionFinder: versionFinder, + startBlock: startBlock, + client: client, + lp: lp, + contractTransmitter: &contractTransmitter, + configWatcher: configWatcher, + gasEstimator: gasEstimator, + maxGasPrice: maxGasPrice, + } +} + +func (P *SrcCommitProvider) Name() string { + return "CCIPCommitProvider.SrcRelayerProvider" +} + +// Close is called when the job that created this provider is deleted. +// At this time, any of the methods on the provider may or may not have been called. +// If NewOnRampReader has not been called, their corresponding +// Close methods will be expected to error. +func (P *SrcCommitProvider) Close() error { + versionFinder := ccip.NewEvmVersionFinder() + + unregisterFuncs := make([]func() error, 0, 2) + unregisterFuncs = append(unregisterFuncs, func() error { + // avoid panic in the case NewOnRampReader wasn't called + if P.seenOnRampAddress == nil { + return nil + } + return ccip.CloseOnRampReader(P.lggr, versionFinder, *P.seenSourceChainSelector, *P.seenDestChainSelector, *P.seenOnRampAddress, P.lp, P.client) + }) + + var multiErr error + for _, fn := range unregisterFuncs { + if err := fn(); err != nil { + multiErr = multierr.Append(multiErr, err) + } + } + return multiErr +} + +func (P *SrcCommitProvider) Ready() error { + return nil +} + +func (P *SrcCommitProvider) HealthReport() map[string]error { + return make(map[string]error) +} + +func (P *SrcCommitProvider) OffchainConfigDigester() ocrtypes.OffchainConfigDigester { + // TODO CCIP-2494 + // "OffchainConfigDigester called on SrcCommitProvider. Valid on DstCommitProvider." + return UnimplementedOffchainConfigDigester{} +} + +func (P *SrcCommitProvider) ContractConfigTracker() ocrtypes.ContractConfigTracker { + // // TODO CCIP-2494 + // "ContractConfigTracker called on SrcCommitProvider. Valid on DstCommitProvider.") + return UnimplementedContractConfigTracker{} +} + +func (P *SrcCommitProvider) ContractTransmitter() ocrtypes.ContractTransmitter { + // // TODO CCIP-2494 + // "ContractTransmitter called on SrcCommitProvider. Valid on DstCommitProvider." + return UnimplementedContractTransmitter{} +} + +func (P *SrcCommitProvider) ChainReader() commontypes.ContractReader { + return nil +} + +func (P *SrcCommitProvider) Codec() commontypes.Codec { + return nil +} + +func (P *DstCommitProvider) Name() string { + return "CCIPCommitProvider.DstRelayerProvider" +} + +func (P *DstCommitProvider) Close() error { + versionFinder := ccip.NewEvmVersionFinder() + + unregisterFuncs := make([]func() error, 0, 2) + unregisterFuncs = append(unregisterFuncs, func() error { + if P.seenCommitStoreAddress == nil { + return nil + } + return ccip.CloseCommitStoreReader(P.lggr, versionFinder, *P.seenCommitStoreAddress, P.client, P.lp) + }) + unregisterFuncs = append(unregisterFuncs, func() error { + if P.seenOffRampAddress == nil { + return nil + } + return ccip.CloseOffRampReader(P.lggr, versionFinder, *P.seenOffRampAddress, P.client, P.lp, nil, big.NewInt(0)) + }) + + var multiErr error + for _, fn := range unregisterFuncs { + if err := fn(); err != nil { + multiErr = multierr.Append(multiErr, err) + } + } + return multiErr +} + +func (P *DstCommitProvider) Ready() error { + return nil +} + +func (P *DstCommitProvider) HealthReport() map[string]error { + return make(map[string]error) +} + +func (P *DstCommitProvider) OffchainConfigDigester() ocrtypes.OffchainConfigDigester { + return P.configWatcher.OffchainConfigDigester() +} + +func (P *DstCommitProvider) ContractConfigTracker() ocrtypes.ContractConfigTracker { + return P.configWatcher.ContractConfigTracker() +} + +func (P *DstCommitProvider) ContractTransmitter() ocrtypes.ContractTransmitter { + return P.contractTransmitter +} + +func (P *DstCommitProvider) ChainReader() commontypes.ContractReader { + return nil +} + +func (P *DstCommitProvider) Codec() commontypes.Codec { + return nil +} + +func (P *SrcCommitProvider) Start(ctx context.Context) error { + if P.startBlock != 0 { + P.lggr.Infow("start replaying src chain", "fromBlock", P.startBlock) + return P.lp.Replay(ctx, int64(P.startBlock)) + } + return nil +} + +func (P *DstCommitProvider) Start(ctx context.Context) error { + if P.startBlock != 0 { + P.lggr.Infow("start replaying dst chain", "fromBlock", P.startBlock) + return P.lp.Replay(ctx, int64(P.startBlock)) + } + return nil +} + +func (P *SrcCommitProvider) NewPriceGetter(ctx context.Context) (priceGetter cciptypes.PriceGetter, err error) { + return nil, fmt.Errorf("can't construct a price getter from one relayer") +} + +func (P *DstCommitProvider) NewPriceGetter(ctx context.Context) (priceGetter cciptypes.PriceGetter, err error) { + return nil, fmt.Errorf("can't construct a price getter from one relayer") +} + +func (P *SrcCommitProvider) NewCommitStoreReader(ctx context.Context, commitStoreAddress cciptypes.Address) (commitStoreReader cciptypes.CommitStoreReader, err error) { + commitStoreReader = NewIncompleteSourceCommitStoreReader(P.estimator, P.maxGasPrice) + return +} + +func (P *DstCommitProvider) NewCommitStoreReader(ctx context.Context, commitStoreAddress cciptypes.Address) (commitStoreReader cciptypes.CommitStoreReader, err error) { + P.seenCommitStoreAddress = &commitStoreAddress + + versionFinder := ccip.NewEvmVersionFinder() + commitStoreReader, err = NewIncompleteDestCommitStoreReader(P.lggr, versionFinder, commitStoreAddress, P.client, P.lp) + return +} + +func (P *SrcCommitProvider) NewOnRampReader(ctx context.Context, onRampAddress cciptypes.Address, sourceChainSelector uint64, destChainSelector uint64) (onRampReader cciptypes.OnRampReader, err error) { + P.seenOnRampAddress = &onRampAddress + P.seenSourceChainSelector = &sourceChainSelector + P.seenDestChainSelector = &destChainSelector + + versionFinder := ccip.NewEvmVersionFinder() + onRampReader, err = ccip.NewOnRampReader(P.lggr, versionFinder, sourceChainSelector, destChainSelector, onRampAddress, P.lp, P.client) + return +} + +func (P *DstCommitProvider) NewOnRampReader(ctx context.Context, onRampAddress cciptypes.Address, sourceChainSelector uint64, destChainSelector uint64) (onRampReader cciptypes.OnRampReader, err error) { + return nil, fmt.Errorf("invalid: NewOnRampReader called for DstCommitProvider.NewOnRampReader should be called on SrcCommitProvider") +} + +func (P *SrcCommitProvider) NewOffRampReader(ctx context.Context, offRampAddr cciptypes.Address) (offRampReader cciptypes.OffRampReader, err error) { + return nil, fmt.Errorf("invalid: NewOffRampReader called for SrcCommitProvider. NewOffRampReader should be called on DstCommitProvider") +} + +func (P *DstCommitProvider) NewOffRampReader(ctx context.Context, offRampAddr cciptypes.Address) (offRampReader cciptypes.OffRampReader, err error) { + offRampReader, err = ccip.NewOffRampReader(P.lggr, P.versionFinder, offRampAddr, P.client, P.lp, P.gasEstimator, &P.maxGasPrice, true) + return +} + +func (P *SrcCommitProvider) NewPriceRegistryReader(ctx context.Context, addr cciptypes.Address) (priceRegistryReader cciptypes.PriceRegistryReader, err error) { + return nil, fmt.Errorf("invalid: NewPriceRegistryReader called for SrcCommitProvider. NewOffRampReader should be called on DstCommitProvider") +} + +func (P *DstCommitProvider) NewPriceRegistryReader(ctx context.Context, addr cciptypes.Address) (priceRegistryReader cciptypes.PriceRegistryReader, err error) { + destPriceRegistry := ccip.NewEvmPriceRegistry(P.lp, P.client, P.lggr, ccip.CommitPluginLabel) + priceRegistryReader, err = destPriceRegistry.NewPriceRegistryReader(ctx, addr) + return +} + +func (P *SrcCommitProvider) SourceNativeToken(ctx context.Context, sourceRouterAddr cciptypes.Address) (cciptypes.Address, error) { + sourceRouterAddrHex, err := ccip.GenericAddrToEvm(sourceRouterAddr) + if err != nil { + return "", err + } + sourceRouter, err := router.NewRouter(sourceRouterAddrHex, P.client) + if err != nil { + return "", err + } + sourceNative, err := sourceRouter.GetWrappedNative(&bind.CallOpts{Context: ctx}) + if err != nil { + return "", err + } + + return ccip.EvmAddrToGeneric(sourceNative), nil +} + +func (P *DstCommitProvider) SourceNativeToken(ctx context.Context, sourceRouterAddr cciptypes.Address) (cciptypes.Address, error) { + return "", fmt.Errorf("invalid: SourceNativeToken called for DstCommitProvider. SourceNativeToken should be called on SrcCommitProvider") +} diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index a0782380b5..e310464a55 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -1,13 +1,24 @@ package evm import ( + "bytes" "context" + "crypto/sha256" "encoding/json" "errors" "fmt" + "math/big" "strings" "sync" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/ccipcommit" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/ccipexec" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + cciptransmitter "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/transmitter" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" @@ -72,6 +83,57 @@ func init() { var _ commontypes.Relayer = &Relayer{} //nolint:staticcheck +// The current PluginProvider interface does not support an error return. This was fine up until CCIP. +// CCIP is the first product to introduce the idea of incomplete implementations of a provider based on +// what chain (for CCIP, src or dest) the provider is created for. The Unimplemented* implementations below allow us to return +// a non nil value, which is hopefully a better developer experience should you find yourself using the right methods +// but on the *wrong* provider. + +// [UnimplementedOffchainConfigDigester] satisfies the OCR OffchainConfigDigester interface +type UnimplementedOffchainConfigDigester struct{} + +func (e UnimplementedOffchainConfigDigester) ConfigDigest(config ocrtypes.ContractConfig) (ocrtypes.ConfigDigest, error) { + return ocrtypes.ConfigDigest{}, fmt.Errorf("unimplemented for this relayer") +} + +func (e UnimplementedOffchainConfigDigester) ConfigDigestPrefix() (ocrtypes.ConfigDigestPrefix, error) { + return 0, fmt.Errorf("unimplemented for this relayer") +} + +// [UnimplementedContractConfigTracker] satisfies the OCR ContractConfigTracker interface +type UnimplementedContractConfigTracker struct{} + +func (u UnimplementedContractConfigTracker) Notify() <-chan struct{} { + return nil +} + +func (u UnimplementedContractConfigTracker) LatestConfigDetails(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error) { + return 0, ocrtypes.ConfigDigest{}, fmt.Errorf("unimplemented for this relayer") +} + +func (u UnimplementedContractConfigTracker) LatestConfig(ctx context.Context, changedInBlock uint64) (ocrtypes.ContractConfig, error) { + return ocrtypes.ContractConfig{}, fmt.Errorf("unimplemented for this relayer") +} + +func (u UnimplementedContractConfigTracker) LatestBlockHeight(ctx context.Context) (blockHeight uint64, err error) { + return 0, fmt.Errorf("unimplemented for this relayer") +} + +// [UnimplementedContractTransmitter] satisfies the OCR ContractTransmitter interface +type UnimplementedContractTransmitter struct{} + +func (u UnimplementedContractTransmitter) Transmit(context.Context, ocrtypes.ReportContext, ocrtypes.Report, []ocrtypes.AttributedOnchainSignature) error { + return fmt.Errorf("unimplemented for this relayer") +} + +func (u UnimplementedContractTransmitter) FromAccount() (ocrtypes.Account, error) { + return "", fmt.Errorf("unimplemented for this relayer") +} + +func (u UnimplementedContractTransmitter) LatestConfigDigestAndEpoch(ctx context.Context) (configDigest ocrtypes.ConfigDigest, epoch uint32, err error) { + return ocrtypes.ConfigDigest{}, 0, fmt.Errorf("unimplemented for this relayer") +} + type Relayer struct { ds sqlutil.DataSource chain legacyevm.Chain @@ -618,6 +680,17 @@ func generateTransmitterFrom(ctx context.Context, rargs commontypes.RelayArgs, e configWatcher.chain.ID(), ethKeystore, ) + case commontypes.CCIPExecution: + transmitter, err = cciptransmitter.NewTransmitterWithStatusChecker( + configWatcher.chain.TxManager(), + fromAddresses, + gasLimit, + effectiveTransmitterAddress, + strategy, + checker, + configWatcher.chain.ID(), + ethKeystore, + ) default: transmitter, err = ocrcommon.NewTransmitter( configWatcher.chain.TxManager(), @@ -734,12 +807,158 @@ func (r *Relayer) NewAutomationProvider(rargs commontypes.RelayArgs, pargs commo return ocr2keeperRelayer.NewOCR2KeeperProvider(rargs, pargs) } -func (r *Relayer) NewCCIPCommitProvider(_ commontypes.RelayArgs, _ commontypes.PluginArgs) (commontypes.CCIPCommitProvider, error) { - return nil, errors.New("ccip.commit is not supported for evm") +func chainToUUID(chainID *big.Int) uuid.UUID { + // See https://www.rfc-editor.org/rfc/rfc4122.html#section-4.1.3 for the list of supported versions. + const VersionSHA1 = 5 + var buf bytes.Buffer + buf.WriteString("CCIP:") + buf.Write(chainID.Bytes()) + // We use SHA-256 instead of SHA-1 because the former has better collision resistance. + // The UUID will contain only the first 16 bytes of the hash. + // You can't say which algorithms was used just by looking at the UUID bytes. + return uuid.NewHash(sha256.New(), uuid.NameSpaceOID, buf.Bytes(), VersionSHA1) } -func (r *Relayer) NewCCIPExecProvider(_ commontypes.RelayArgs, _ commontypes.PluginArgs) (commontypes.CCIPExecProvider, error) { - return nil, errors.New("ccip.exec is not supported for evm") +// NewCCIPCommitProvider constructs a provider of type CCIPCommitProvider. Since this is happening in the Relayer, +// which lives in a separate process from delegate which is requesting a provider, we need to wire in through pargs +// which *type* (impl) of CCIPCommitProvider should be created. CCIP is currently a special case where the provider has a +// subset of implementations of the complete interface as certain contracts in a CCIP lane are only deployed on the src +// chain or on the dst chain. This results in the two implementations of providers: a src and dst implementation. +func (r *Relayer) NewCCIPCommitProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.CCIPCommitProvider, error) { + // TODO https://smartcontract-it.atlassian.net/browse/BCF-2887 + ctx := context.Background() + + versionFinder := ccip.NewEvmVersionFinder() + + var commitPluginConfig ccipconfig.CommitPluginConfig + err := json.Unmarshal(pargs.PluginConfig, &commitPluginConfig) + if err != nil { + return nil, err + } + sourceStartBlock := commitPluginConfig.SourceStartBlock + destStartBlock := commitPluginConfig.DestStartBlock + + // The src chain implementation of this provider does not need a configWatcher or contractTransmitter; + // bail early. + if commitPluginConfig.IsSourceProvider { + return NewSrcCommitProvider( + r.lggr, + sourceStartBlock, + r.chain.Client(), + r.chain.LogPoller(), + r.chain.GasEstimator(), + r.chain.Config().EVM().GasEstimator().PriceMax().ToInt(), + ), nil + } + + relayOpts := types.NewRelayOpts(rargs) + configWatcher, err := newStandardConfigProvider(ctx, r.lggr, r.chain, relayOpts) + if err != nil { + return nil, err + } + address := common.HexToAddress(relayOpts.ContractID) + typ, ver, err := ccipconfig.TypeAndVersion(address, r.chain.Client()) + if err != nil { + return nil, err + } + fn, err := ccipcommit.CommitReportToEthTxMeta(typ, ver) + if err != nil { + return nil, err + } + subjectID := chainToUUID(configWatcher.chain.ID()) + contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, r.ks.Eth(), configWatcher, configTransmitterOpts{ + subjectID: &subjectID, + }, OCR2AggregatorTransmissionContractABI, WithReportToEthMetadata(fn), WithRetention(0)) + if err != nil { + return nil, err + } + + return NewDstCommitProvider( + r.lggr, + versionFinder, + destStartBlock, + r.chain.Client(), + r.chain.LogPoller(), + r.chain.GasEstimator(), + *r.chain.Config().EVM().GasEstimator().PriceMax().ToInt(), + *contractTransmitter, + configWatcher, + ), nil +} + +// NewCCIPExecProvider constructs a provider of type CCIPExecProvider. Since this is happening in the Relayer, +// which lives in a separate process from delegate which is requesting a provider, we need to wire in through pargs +// which *type* (impl) of CCIPExecProvider should be created. CCIP is currently a special case where the provider has a +// subset of implementations of the complete interface as certain contracts in a CCIP lane are only deployed on the src +// chain or on the dst chain. This results in the two implementations of providers: a src and dst implementation. +func (r *Relayer) NewCCIPExecProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.CCIPExecProvider, error) { + // TODO https://smartcontract-it.atlassian.net/browse/BCF-2887 + ctx := context.Background() + + versionFinder := ccip.NewEvmVersionFinder() + + var execPluginConfig ccipconfig.ExecPluginConfig + err := json.Unmarshal(pargs.PluginConfig, &execPluginConfig) + if err != nil { + return nil, err + } + + usdcConfig := execPluginConfig.USDCConfig + + // The src chain implementation of this provider does not need a configWatcher or contractTransmitter; + // bail early. + if execPluginConfig.IsSourceProvider { + return NewSrcExecProvider( + r.lggr, + versionFinder, + r.chain.Client(), + r.chain.GasEstimator(), + r.chain.Config().EVM().GasEstimator().PriceMax().ToInt(), + r.chain.LogPoller(), + execPluginConfig.SourceStartBlock, + execPluginConfig.JobID, + usdcConfig.AttestationAPI, + int(usdcConfig.AttestationAPITimeoutSeconds), + usdcConfig.AttestationAPIIntervalMilliseconds, + usdcConfig.SourceMessageTransmitterAddress, + ) + } + + relayOpts := types.NewRelayOpts(rargs) + configWatcher, err := newStandardConfigProvider(ctx, r.lggr, r.chain, relayOpts) + if err != nil { + return nil, err + } + address := common.HexToAddress(relayOpts.ContractID) + typ, ver, err := ccipconfig.TypeAndVersion(address, r.chain.Client()) + if err != nil { + return nil, err + } + fn, err := ccipexec.ExecReportToEthTxMeta(ctx, typ, ver) + if err != nil { + return nil, err + } + subjectID := chainToUUID(configWatcher.chain.ID()) + contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, r.ks.Eth(), configWatcher, configTransmitterOpts{ + subjectID: &subjectID, + }, OCR2AggregatorTransmissionContractABI, WithReportToEthMetadata(fn), WithRetention(0)) + if err != nil { + return nil, err + } + + return NewDstExecProvider( + r.lggr, + versionFinder, + r.chain.Client(), + r.chain.LogPoller(), + execPluginConfig.DestStartBlock, + contractTransmitter, + configWatcher, + r.chain.GasEstimator(), + *r.chain.Config().EVM().GasEstimator().PriceMax().ToInt(), + r.chain.TxManager(), + cciptypes.Address(rargs.ContractID), + ) } var _ commontypes.MedianProvider = (*medianProvider)(nil) diff --git a/core/services/relay/evm/exec_provider.go b/core/services/relay/evm/exec_provider.go new file mode 100644 index 0000000000..ae3ce56532 --- /dev/null +++ b/core/services/relay/evm/exec_provider.go @@ -0,0 +1,391 @@ +package evm + +import ( + "context" + "fmt" + "math/big" + "net/url" + "time" + + "go.uber.org/multierr" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/types" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata/usdc" +) + +type SrcExecProvider struct { + lggr logger.Logger + versionFinder ccip.VersionFinder + client client.Client + lp logpoller.LogPoller + startBlock uint64 + estimator gas.EvmFeeEstimator + maxGasPrice *big.Int + usdcReader *ccip.USDCReaderImpl + usdcAttestationAPI string + usdcAttestationAPITimeoutSeconds int + usdcAttestationAPIIntervalMilliseconds int + usdcSrcMsgTransmitterAddr common.Address + + // these values are nil and are updated for Close() + seenOnRampAddress *cciptypes.Address + seenSourceChainSelector *uint64 + seenDestChainSelector *uint64 +} + +func NewSrcExecProvider( + lggr logger.Logger, + versionFinder ccip.VersionFinder, + client client.Client, + estimator gas.EvmFeeEstimator, + maxGasPrice *big.Int, + lp logpoller.LogPoller, + startBlock uint64, + jobID string, + usdcAttestationAPI string, + usdcAttestationAPITimeoutSeconds int, + usdcAttestationAPIIntervalMilliseconds int, + usdcSrcMsgTransmitterAddr common.Address, +) (commontypes.CCIPExecProvider, error) { + var usdcReader *ccip.USDCReaderImpl + var err error + if usdcAttestationAPI != "" { + usdcReader, err = ccip.NewUSDCReader(lggr, jobID, usdcSrcMsgTransmitterAddr, lp, true) + if err != nil { + return nil, fmt.Errorf("new usdc reader: %w", err) + } + } + + return &SrcExecProvider{ + lggr: lggr, + versionFinder: versionFinder, + client: client, + estimator: estimator, + maxGasPrice: maxGasPrice, + lp: lp, + startBlock: startBlock, + usdcReader: usdcReader, + usdcAttestationAPI: usdcAttestationAPI, + usdcAttestationAPITimeoutSeconds: usdcAttestationAPITimeoutSeconds, + usdcAttestationAPIIntervalMilliseconds: usdcAttestationAPIIntervalMilliseconds, + usdcSrcMsgTransmitterAddr: usdcSrcMsgTransmitterAddr, + }, nil +} + +func (s *SrcExecProvider) Name() string { + return "CCIP.SrcExecProvider" +} + +func (s *SrcExecProvider) Start(ctx context.Context) error { + if s.startBlock != 0 { + s.lggr.Infow("start replaying src chain", "fromBlock", s.startBlock) + return s.lp.Replay(ctx, int64(s.startBlock)) + } + return nil +} + +// Close is called when the job that created this provider is closed. +func (s *SrcExecProvider) Close() error { + versionFinder := ccip.NewEvmVersionFinder() + + unregisterFuncs := make([]func() error, 0, 2) + unregisterFuncs = append(unregisterFuncs, func() error { + // avoid panic in the case NewOnRampReader wasn't called + if s.seenOnRampAddress == nil { + return nil + } + return ccip.CloseOnRampReader(s.lggr, versionFinder, *s.seenSourceChainSelector, *s.seenDestChainSelector, *s.seenOnRampAddress, s.lp, s.client) + }) + unregisterFuncs = append(unregisterFuncs, func() error { + if s.usdcAttestationAPI == "" { + return nil + } + return ccip.CloseUSDCReader(s.lggr, s.lggr.Name(), s.usdcSrcMsgTransmitterAddr, s.lp) + }) + var multiErr error + for _, fn := range unregisterFuncs { + if err := fn(); err != nil { + multiErr = multierr.Append(multiErr, err) + } + } + return multiErr +} + +func (s *SrcExecProvider) Ready() error { + return nil +} + +func (s *SrcExecProvider) HealthReport() map[string]error { + return make(map[string]error) +} + +func (s *SrcExecProvider) OffchainConfigDigester() ocrtypes.OffchainConfigDigester { + // TODO CCIP-2494 + // OffchainConfigDigester called on SrcExecProvider. It should only be called on DstExecProvider + return UnimplementedOffchainConfigDigester{} +} + +func (s *SrcExecProvider) ContractConfigTracker() ocrtypes.ContractConfigTracker { + // TODO CCIP-2494 + // "ContractConfigTracker called on SrcExecProvider. It should only be called on DstExecProvider + return UnimplementedContractConfigTracker{} +} + +func (s *SrcExecProvider) ContractTransmitter() ocrtypes.ContractTransmitter { + // TODO CCIP-2494 + // "ContractTransmitter called on SrcExecProvider. It should only be called on DstExecProvider + return UnimplementedContractTransmitter{} +} + +func (s *SrcExecProvider) ChainReader() commontypes.ContractReader { + return nil +} + +func (s *SrcExecProvider) Codec() commontypes.Codec { + return nil +} + +func (s *SrcExecProvider) GetTransactionStatus(ctx context.Context, transactionID string) (types.TransactionStatus, error) { + return 0, fmt.Errorf("invalid: GetTransactionStatus called on SrcExecProvider. It should only be called on DstExecProvider") +} + +func (s *SrcExecProvider) NewCommitStoreReader(ctx context.Context, addr cciptypes.Address) (commitStoreReader cciptypes.CommitStoreReader, err error) { + commitStoreReader = NewIncompleteSourceCommitStoreReader(s.estimator, s.maxGasPrice) + return +} + +func (s *SrcExecProvider) NewOffRampReader(ctx context.Context, addr cciptypes.Address) (cciptypes.OffRampReader, error) { + return nil, fmt.Errorf("invalid: NewOffRampReader called on SrcExecProvider. Valid on DstExecProvider") +} + +func (s *SrcExecProvider) NewOnRampReader(ctx context.Context, onRampAddress cciptypes.Address, sourceChainSelector uint64, destChainSelector uint64) (onRampReader cciptypes.OnRampReader, err error) { + s.seenOnRampAddress = &onRampAddress + + versionFinder := ccip.NewEvmVersionFinder() + onRampReader, err = ccip.NewOnRampReader(s.lggr, versionFinder, sourceChainSelector, destChainSelector, onRampAddress, s.lp, s.client) + return +} + +func (s *SrcExecProvider) NewPriceRegistryReader(ctx context.Context, addr cciptypes.Address) (priceRegistryReader cciptypes.PriceRegistryReader, err error) { + srcPriceRegistry := ccip.NewEvmPriceRegistry(s.lp, s.client, s.lggr, ccip.ExecPluginLabel) + priceRegistryReader, err = srcPriceRegistry.NewPriceRegistryReader(ctx, addr) + return +} + +func (s *SrcExecProvider) NewTokenDataReader(ctx context.Context, tokenAddress cciptypes.Address) (tokenDataReader cciptypes.TokenDataReader, err error) { + attestationURI, err2 := url.ParseRequestURI(s.usdcAttestationAPI) + if err2 != nil { + return nil, fmt.Errorf("failed to parse USDC attestation API: %w", err2) + } + tokenAddr, err2 := ccip.GenericAddrToEvm(tokenAddress) + if err2 != nil { + return nil, fmt.Errorf("failed to parse token address: %w", err2) + } + tokenDataReader = usdc.NewUSDCTokenDataReader( + s.lggr, + s.usdcReader, + attestationURI, + s.usdcAttestationAPITimeoutSeconds, + tokenAddr, + time.Duration(s.usdcAttestationAPIIntervalMilliseconds)*time.Millisecond, + ) + return +} + +func (s *SrcExecProvider) NewTokenPoolBatchedReader(ctx context.Context, offRampAddr cciptypes.Address, sourceChainSelector uint64) (cciptypes.TokenPoolBatchedReader, error) { + return nil, fmt.Errorf("invalid: NewTokenPoolBatchedReader called on SrcExecProvider. It should only be called on DstExecProvdier") +} + +func (s *SrcExecProvider) SourceNativeToken(ctx context.Context, sourceRouterAddr cciptypes.Address) (cciptypes.Address, error) { + sourceRouterAddrHex, err := ccip.GenericAddrToEvm(sourceRouterAddr) + if err != nil { + return "", err + } + sourceRouter, err := router.NewRouter(sourceRouterAddrHex, s.client) + if err != nil { + return "", err + } + sourceNative, err := sourceRouter.GetWrappedNative(&bind.CallOpts{Context: ctx}) + if err != nil { + return "", err + } + + return ccip.EvmAddrToGeneric(sourceNative), nil +} + +type DstExecProvider struct { + lggr logger.Logger + versionFinder ccip.VersionFinder + client client.Client + lp logpoller.LogPoller + startBlock uint64 + contractTransmitter *contractTransmitter + configWatcher *configWatcher + gasEstimator gas.EvmFeeEstimator + maxGasPrice big.Int + txm txmgr.TxManager + offRampAddress cciptypes.Address + + // these values are nil and are updated for Close() + seenCommitStoreAddr *cciptypes.Address +} + +func NewDstExecProvider( + lggr logger.Logger, + versionFinder ccip.VersionFinder, + client client.Client, + lp logpoller.LogPoller, + startBlock uint64, + contractTransmitter *contractTransmitter, + configWatcher *configWatcher, + gasEstimator gas.EvmFeeEstimator, + maxGasPrice big.Int, + txm txmgr.TxManager, + offRampAddress cciptypes.Address, +) (commontypes.CCIPExecProvider, error) { + return &DstExecProvider{ + lggr: lggr, + versionFinder: versionFinder, + client: client, + lp: lp, + startBlock: startBlock, + contractTransmitter: contractTransmitter, + configWatcher: configWatcher, + gasEstimator: gasEstimator, + maxGasPrice: maxGasPrice, + txm: txm, + offRampAddress: offRampAddress, + }, nil +} + +func (d *DstExecProvider) Name() string { + return "CCIP.DestRelayerExecProvider" +} + +func (d *DstExecProvider) Start(ctx context.Context) error { + if d.startBlock != 0 { + d.lggr.Infow("start replaying dst chain", "fromBlock", d.startBlock) + return d.lp.Replay(ctx, int64(d.startBlock)) + } + return nil +} + +// Close is called when the job that created this provider is deleted +// At this time, any of the methods on the provider may or may not have been called. +// If NewOnRampReader and NewCommitStoreReader have not been called, their corresponding +// Close methods will be expected to error. +func (d *DstExecProvider) Close() error { + versionFinder := ccip.NewEvmVersionFinder() + + unregisterFuncs := make([]func() error, 0, 2) + unregisterFuncs = append(unregisterFuncs, func() error { + if d.seenCommitStoreAddr == nil { + return nil + } + return ccip.CloseCommitStoreReader(d.lggr, versionFinder, *d.seenCommitStoreAddr, d.client, d.lp) + }) + unregisterFuncs = append(unregisterFuncs, func() error { + return ccip.CloseOffRampReader(d.lggr, versionFinder, d.offRampAddress, d.client, d.lp, nil, big.NewInt(0)) + }) + + var multiErr error + for _, fn := range unregisterFuncs { + if err := fn(); err != nil { + multiErr = multierr.Append(multiErr, err) + } + } + return multiErr +} + +func (d *DstExecProvider) Ready() error { + return nil +} + +func (d *DstExecProvider) HealthReport() map[string]error { + return make(map[string]error) +} + +func (d *DstExecProvider) OffchainConfigDigester() ocrtypes.OffchainConfigDigester { + return d.configWatcher.OffchainConfigDigester() +} + +func (d *DstExecProvider) ContractConfigTracker() ocrtypes.ContractConfigTracker { + return d.configWatcher.ContractConfigTracker() +} + +func (d *DstExecProvider) ContractTransmitter() ocrtypes.ContractTransmitter { + return d.contractTransmitter +} + +func (d *DstExecProvider) ChainReader() commontypes.ContractReader { + return nil +} + +func (d *DstExecProvider) Codec() commontypes.Codec { + return nil +} + +func (d *DstExecProvider) GetTransactionStatus(ctx context.Context, transactionID string) (types.TransactionStatus, error) { + return d.txm.GetTransactionStatus(ctx, transactionID) +} + +func (d *DstExecProvider) NewCommitStoreReader(ctx context.Context, addr cciptypes.Address) (commitStoreReader cciptypes.CommitStoreReader, err error) { + d.seenCommitStoreAddr = &addr + + versionFinder := ccip.NewEvmVersionFinder() + commitStoreReader, err = NewIncompleteDestCommitStoreReader(d.lggr, versionFinder, addr, d.client, d.lp) + return +} + +func (d *DstExecProvider) NewOffRampReader(ctx context.Context, offRampAddress cciptypes.Address) (offRampReader cciptypes.OffRampReader, err error) { + offRampReader, err = ccip.NewOffRampReader(d.lggr, d.versionFinder, offRampAddress, d.client, d.lp, d.gasEstimator, &d.maxGasPrice, true) + return +} + +func (d *DstExecProvider) NewOnRampReader(ctx context.Context, addr cciptypes.Address, sourceChainSelector uint64, destChainSelector uint64) (cciptypes.OnRampReader, error) { + return nil, fmt.Errorf("invalid: NewOnRampReader called on DstExecProvider. It should only be called on SrcExecProvider") +} + +func (d *DstExecProvider) NewPriceRegistryReader(ctx context.Context, addr cciptypes.Address) (priceRegistryReader cciptypes.PriceRegistryReader, err error) { + destPriceRegistry := ccip.NewEvmPriceRegistry(d.lp, d.client, d.lggr, ccip.ExecPluginLabel) + priceRegistryReader, err = destPriceRegistry.NewPriceRegistryReader(ctx, addr) + return +} + +func (d *DstExecProvider) NewTokenDataReader(ctx context.Context, tokenAddress cciptypes.Address) (cciptypes.TokenDataReader, error) { + return nil, fmt.Errorf("invalid: NewTokenDataReader called on DstExecProvider. It should only be called on SrcExecProvider") +} + +func (d *DstExecProvider) NewTokenPoolBatchedReader(ctx context.Context, offRampAddress cciptypes.Address, sourceChainSelector uint64) (tokenPoolBatchedReader cciptypes.TokenPoolBatchedReader, err error) { + batchCaller := ccip.NewDynamicLimitedBatchCaller( + d.lggr, + d.client, + uint(ccip.DefaultRpcBatchSizeLimit), + uint(ccip.DefaultRpcBatchBackOffMultiplier), + uint(ccip.DefaultMaxParallelRpcCalls), + ) + + tokenPoolBatchedReader, err = ccip.NewEVMTokenPoolBatchedReader(d.lggr, sourceChainSelector, offRampAddress, batchCaller) + if err != nil { + return nil, fmt.Errorf("new token pool batched reader: %w", err) + } + return +} + +func (d *DstExecProvider) SourceNativeToken(ctx context.Context, addr cciptypes.Address) (cciptypes.Address, error) { + return "", fmt.Errorf("invalid: SourceNativeToken called on DstExecProvider. It should only be called on SrcExecProvider") +} diff --git a/core/services/relay/evm/statuschecker/mocks/ccip_transaction_status_checker.go b/core/services/relay/evm/statuschecker/mocks/ccip_transaction_status_checker.go new file mode 100644 index 0000000000..9bd59ccf4e --- /dev/null +++ b/core/services/relay/evm/statuschecker/mocks/ccip_transaction_status_checker.go @@ -0,0 +1,104 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + + types "github.com/smartcontractkit/chainlink-common/pkg/types" +) + +// CCIPTransactionStatusChecker is an autogenerated mock type for the CCIPTransactionStatusChecker type +type CCIPTransactionStatusChecker struct { + mock.Mock +} + +type CCIPTransactionStatusChecker_Expecter struct { + mock *mock.Mock +} + +func (_m *CCIPTransactionStatusChecker) EXPECT() *CCIPTransactionStatusChecker_Expecter { + return &CCIPTransactionStatusChecker_Expecter{mock: &_m.Mock} +} + +// CheckMessageStatus provides a mock function with given fields: ctx, msgID +func (_m *CCIPTransactionStatusChecker) CheckMessageStatus(ctx context.Context, msgID string) ([]types.TransactionStatus, int, error) { + ret := _m.Called(ctx, msgID) + + if len(ret) == 0 { + panic("no return value specified for CheckMessageStatus") + } + + var r0 []types.TransactionStatus + var r1 int + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, string) ([]types.TransactionStatus, int, error)); ok { + return rf(ctx, msgID) + } + if rf, ok := ret.Get(0).(func(context.Context, string) []types.TransactionStatus); ok { + r0 = rf(ctx, msgID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]types.TransactionStatus) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) int); ok { + r1 = rf(ctx, msgID) + } else { + r1 = ret.Get(1).(int) + } + + if rf, ok := ret.Get(2).(func(context.Context, string) error); ok { + r2 = rf(ctx, msgID) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// CCIPTransactionStatusChecker_CheckMessageStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CheckMessageStatus' +type CCIPTransactionStatusChecker_CheckMessageStatus_Call struct { + *mock.Call +} + +// CheckMessageStatus is a helper method to define mock.On call +// - ctx context.Context +// - msgID string +func (_e *CCIPTransactionStatusChecker_Expecter) CheckMessageStatus(ctx interface{}, msgID interface{}) *CCIPTransactionStatusChecker_CheckMessageStatus_Call { + return &CCIPTransactionStatusChecker_CheckMessageStatus_Call{Call: _e.mock.On("CheckMessageStatus", ctx, msgID)} +} + +func (_c *CCIPTransactionStatusChecker_CheckMessageStatus_Call) Run(run func(ctx context.Context, msgID string)) *CCIPTransactionStatusChecker_CheckMessageStatus_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string)) + }) + return _c +} + +func (_c *CCIPTransactionStatusChecker_CheckMessageStatus_Call) Return(transactionStatuses []types.TransactionStatus, retryCounter int, err error) *CCIPTransactionStatusChecker_CheckMessageStatus_Call { + _c.Call.Return(transactionStatuses, retryCounter, err) + return _c +} + +func (_c *CCIPTransactionStatusChecker_CheckMessageStatus_Call) RunAndReturn(run func(context.Context, string) ([]types.TransactionStatus, int, error)) *CCIPTransactionStatusChecker_CheckMessageStatus_Call { + _c.Call.Return(run) + return _c +} + +// NewCCIPTransactionStatusChecker creates a new instance of CCIPTransactionStatusChecker. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewCCIPTransactionStatusChecker(t interface { + mock.TestingT + Cleanup(func()) +}) *CCIPTransactionStatusChecker { + mock := &CCIPTransactionStatusChecker{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/relay/evm/statuschecker/txm_status_checker.go b/core/services/relay/evm/statuschecker/txm_status_checker.go new file mode 100644 index 0000000000..f22e6d78b9 --- /dev/null +++ b/core/services/relay/evm/statuschecker/txm_status_checker.go @@ -0,0 +1,54 @@ +package statuschecker + +import ( + "context" + "fmt" + + "github.com/smartcontractkit/chainlink-common/pkg/types" +) + +// CCIPTransactionStatusChecker is an interface that defines the method for checking the status of a transaction. +// CheckMessageStatus checks the status of a transaction for a given message ID. +// It returns a list of transaction statuses, the retry counter, and an error if any occurred during the process. +// + +type CCIPTransactionStatusChecker interface { + CheckMessageStatus(ctx context.Context, msgID string) (transactionStatuses []types.TransactionStatus, retryCounter int, err error) +} + +type TxmStatusChecker struct { + getTransactionStatus func(ctx context.Context, transactionID string) (types.TransactionStatus, error) +} + +func NewTxmStatusChecker(getTransactionStatus func(ctx context.Context, transactionID string) (types.TransactionStatus, error)) *TxmStatusChecker { + return &TxmStatusChecker{getTransactionStatus: getTransactionStatus} +} + +// CheckMessageStatus checks the status of a message by checking the status of all transactions associated with the message ID. +// It returns a slice of all statuses and the number of transactions found (-1 if none). +// The key will follow the format: -. TXM will be queried for each key until a NotFound error is returned. +// The goal is to find all transactions associated with a message ID and snooze messages if they are fatal in the Execution Plugin. +func (tsc *TxmStatusChecker) CheckMessageStatus(ctx context.Context, msgID string) ([]types.TransactionStatus, int, error) { + var counter int + const maxStatuses = 1000 // Cap the number of statuses to avoid infinite loop + + allStatuses := make([]types.TransactionStatus, 0) + + for { + transactionID := fmt.Sprintf("%s-%d", msgID, counter) + status, err := tsc.getTransactionStatus(ctx, transactionID) + if err != nil && status == types.Unknown { + // If the status is unknown and err not nil, it means the transaction was not found + break + } + allStatuses = append(allStatuses, status) + counter++ + + // Break the loop if the cap is reached + if counter >= maxStatuses { + return allStatuses, counter - 1, fmt.Errorf("maximum number of statuses reached, possible infinite loop") + } + } + + return allStatuses, counter - 1, nil +} diff --git a/core/services/relay/evm/statuschecker/txm_status_checker_test.go b/core/services/relay/evm/statuschecker/txm_status_checker_test.go new file mode 100644 index 0000000000..456d07e7a7 --- /dev/null +++ b/core/services/relay/evm/statuschecker/txm_status_checker_test.go @@ -0,0 +1,103 @@ +package statuschecker + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" +) + +func Test_CheckMessageStatus(t *testing.T) { + testutils.SkipShort(t, "") + ctx := context.Background() + mockTxManager := mocks.NewMockEvmTxManager(t) + checker := NewTxmStatusChecker(mockTxManager.GetTransactionStatus) + + msgID := "test-message-id" + + // Define test cases + testCases := []struct { + name string + setupMock func() + expectedStatus []types.TransactionStatus + expectedCounter int + expectedError error + }{ + { + name: "No transactions found", + setupMock: func() { + mockTxManager.Mock = mock.Mock{} + mockTxManager.On("GetTransactionStatus", ctx, "test-message-id-0").Return(types.Unknown, errors.New("failed to find transaction with IdempotencyKey test-message-id-0")) + }, + expectedStatus: []types.TransactionStatus{}, + expectedCounter: -1, + expectedError: nil, + }, + { + name: "Single transaction found", + setupMock: func() { + mockTxManager.Mock = mock.Mock{} + mockTxManager.On("GetTransactionStatus", ctx, "test-message-id-0").Return(types.Finalized, nil) + mockTxManager.On("GetTransactionStatus", ctx, "test-message-id-1").Return(types.Unknown, errors.New("failed to find transaction with IdempotencyKey test-message-id-1")) + }, + expectedStatus: []types.TransactionStatus{types.Finalized}, + expectedCounter: 0, + expectedError: nil, + }, + { + name: "Multiple transactions found", + setupMock: func() { + mockTxManager.Mock = mock.Mock{} + mockTxManager.On("GetTransactionStatus", ctx, "test-message-id-0").Return(types.Finalized, nil) + mockTxManager.On("GetTransactionStatus", ctx, "test-message-id-1").Return(types.Failed, nil) + mockTxManager.On("GetTransactionStatus", ctx, "test-message-id-2").Return(types.Unknown, errors.New("failed to find transaction with IdempotencyKey test-message-id-2")) + }, + expectedStatus: []types.TransactionStatus{types.Finalized, types.Failed}, + expectedCounter: 1, + expectedError: nil, + }, + { + name: "Unknown status without nil (in progress)", + setupMock: func() { + mockTxManager.Mock = mock.Mock{} + mockTxManager.On("GetTransactionStatus", ctx, "test-message-id-0").Return(types.Unknown, nil) + mockTxManager.On("GetTransactionStatus", ctx, "test-message-id-1").Return(types.Unknown, errors.New("failed to find transaction with IdempotencyKey test-message-id-1")) + }, + expectedStatus: []types.TransactionStatus{types.Unknown}, + expectedCounter: 0, + expectedError: nil, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + tc.setupMock() + statuses, counter, err := checker.CheckMessageStatus(ctx, msgID) + assert.Equal(t, tc.expectedStatus, statuses) + assert.Equal(t, tc.expectedCounter, counter) + assert.Equal(t, tc.expectedError, err) + mockTxManager.AssertExpectations(t) + }) + } +} + +func Test_FailForMoreThan1000Retries(t *testing.T) { + ctx := context.Background() + mockTxManager := mocks.NewMockEvmTxManager(t) + checker := NewTxmStatusChecker(mockTxManager.GetTransactionStatus) + + for i := 0; i < 1000; i++ { + mockTxManager.On("GetTransactionStatus", ctx, fmt.Sprintf("test-message-id-%d", i)).Return(types.Finalized, nil) + } + + msgID := "test-message-id" + _, _, err := checker.CheckMessageStatus(ctx, msgID) + assert.EqualError(t, err, "maximum number of statuses reached, possible infinite loop") +} diff --git a/core/services/synchronization/common.go b/core/services/synchronization/common.go index 5f469c055d..bfb9fba6de 100644 --- a/core/services/synchronization/common.go +++ b/core/services/synchronization/common.go @@ -16,6 +16,8 @@ const ( OCR TelemetryType = "ocr" OCR2Automation TelemetryType = "ocr2-automation" OCR2Functions TelemetryType = "ocr2-functions" + OCR2CCIPCommit TelemetryType = "ocr2-ccip-commit" + OCR2CCIPExec TelemetryType = "ocr2-ccip-exec" OCR2Threshold TelemetryType = "ocr2-threshold" OCR2S4 TelemetryType = "ocr2-s4" OCR2Median TelemetryType = "ocr2-median" diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index 1bad3fd91c..f1325d824e 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -6,6 +6,7 @@ ShutdownGracePeriod = '5s' FeedsManager = true LogPoller = false UICSAKeys = false +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 1672eb1b41..9421e6198e 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -6,6 +6,7 @@ ShutdownGracePeriod = '10s' FeedsManager = true LogPoller = true UICSAKeys = true +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1m0s' diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 0e12af9a7e..1c4093cbfc 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -6,6 +6,7 @@ ShutdownGracePeriod = '5s' FeedsManager = true LogPoller = false UICSAKeys = false +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 5caab7614e..47935390ce 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -51,6 +51,7 @@ ShutdownGracePeriod is the maximum time allowed to shut down gracefully. If exce FeedsManager = true # Default LogPoller = false # Default UICSAKeys = false # Default +CCIP = true # Default ``` @@ -72,6 +73,12 @@ UICSAKeys = false # Default ``` UICSAKeys enables CSA Keys in the UI. +### CCIP +```toml +CCIP = true # Default +``` +CCIP enables the CCIP service. + ## Database ```toml [Database] diff --git a/go.mod b/go.mod index 45e0b62d52..4b216ddc0d 100644 --- a/go.mod +++ b/go.mod @@ -9,11 +9,12 @@ require ( github.com/NethermindEth/juno v0.3.1 github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb github.com/XSAM/otelsql v0.27.0 - github.com/avast/retry-go/v4 v4.5.1 + github.com/avast/retry-go/v4 v4.6.0 github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/cometbft/cometbft v0.37.2 github.com/cosmos/cosmos-sdk v0.47.4 github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e + github.com/deckarep/golang-set/v2 v2.3.0 github.com/dominikbraun/graph v0.23.0 github.com/esote/minmaxheap v1.0.0 github.com/ethereum/go-ethereum v1.13.8 @@ -67,6 +68,7 @@ require ( github.com/prometheus/prometheus v0.48.1 github.com/robfig/cron/v3 v3.0.1 github.com/rogpeppe/go-internal v1.12.0 + github.com/rs/zerolog v1.30.0 github.com/scylladb/go-reflectx v1.0.1 github.com/shirou/gopsutil/v3 v3.24.3 github.com/shopspring/decimal v1.4.0 @@ -92,6 +94,7 @@ require ( github.com/umbracle/ethgo v0.1.3 github.com/unrolled/secure v1.13.0 github.com/urfave/cli v1.22.14 + github.com/wk8/go-ordered-map/v2 v2.1.8 go.dedis.ch/fixbuf v1.0.3 go.dedis.ch/kyber/v3 v3.1.0 go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 @@ -112,6 +115,7 @@ require ( google.golang.org/protobuf v1.34.2 gopkg.in/guregu/null.v4 v4.0.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 + k8s.io/utils v0.0.0-20230711102312-30195339c3c7 ) require ( @@ -174,7 +178,6 @@ require ( github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/deckarep/golang-set/v2 v2.3.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect @@ -312,7 +315,6 @@ require ( github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 // indirect github.com/valyala/fastjson v1.4.1 // indirect - github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zondax/hid v0.9.1 // indirect diff --git a/go.sum b/go.sum index 4a6b294c12..6b0ec5aa5c 100644 --- a/go.sum +++ b/go.sum @@ -150,8 +150,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o= -github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc= +github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= +github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= @@ -264,6 +264,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= @@ -491,6 +492,7 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -1093,6 +1095,7 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= @@ -1911,6 +1914,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= +k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 8f9652099b..0c0ce33769 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -6,7 +6,7 @@ go 1.22.5 replace github.com/smartcontractkit/chainlink/v2 => ../ require ( - github.com/avast/retry-go/v4 v4.5.1 + github.com/avast/retry-go/v4 v4.6.0 github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f github.com/cli/go-gh/v2 v2.0.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index bca92f4a97..8b7bd1d2a1 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -207,8 +207,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o= -github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc= +github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= +github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index f0554f2c72..4395a3ce48 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -76,7 +76,7 @@ require ( github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/avast/retry-go v3.0.0+incompatible // indirect - github.com/avast/retry-go/v4 v4.5.1 // indirect + github.com/avast/retry-go/v4 v4.6.0 // indirect github.com/aws/aws-sdk-go v1.45.25 // indirect github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect github.com/aws/jsii-runtime-go v1.75.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index f31a11d389..4015287541 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -207,8 +207,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o= -github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc= +github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= +github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index 1063d9c2a5..ff8b4889c4 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -18,6 +18,7 @@ ShutdownGracePeriod = '5s' FeedsManager = true LogPoller = false UICSAKeys = false +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index 56ce1ea7ba..f4dd43cb90 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -62,6 +62,7 @@ ShutdownGracePeriod = '5s' FeedsManager = true LogPoller = false UICSAKeys = false +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index e534c67a2f..75a6ae3641 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -62,6 +62,7 @@ ShutdownGracePeriod = '5s' FeedsManager = true LogPoller = false UICSAKeys = false +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 29bc189e56..97bae5a84b 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -62,6 +62,7 @@ ShutdownGracePeriod = '5s' FeedsManager = true LogPoller = false UICSAKeys = false +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar index 6a09dd06c4..0cdf001ecc 100644 --- a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -47,6 +47,7 @@ ShutdownGracePeriod = '5s' FeedsManager = true LogPoller = false UICSAKeys = false +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 60c42c7c39..ab6860ec79 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -52,6 +52,7 @@ ShutdownGracePeriod = '5s' FeedsManager = true LogPoller = false UICSAKeys = false +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index 719bb8bcc4..603fdaada6 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -59,6 +59,7 @@ ShutdownGracePeriod = '5s' FeedsManager = true LogPoller = false UICSAKeys = false +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index a652943e26..dea40ec8da 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -41,6 +41,7 @@ ShutdownGracePeriod = '5s' FeedsManager = true LogPoller = false UICSAKeys = false +CCIP = true [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' From 1d81278edace2411f0d87b7e111321bd67b6b0a5 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 6 Aug 2024 13:56:03 +0200 Subject: [PATCH 037/432] update readme's with information about CL node TOML config (#14028) --- integration-tests/README.md | 5 +-- integration-tests/testconfig/README.md | 9 +++-- integration-tests/testconfig/default.toml | 41 +++++++++++++++++++++-- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/integration-tests/README.md b/integration-tests/README.md index fcfefe97a7..180021efee 100644 --- a/integration-tests/README.md +++ b/integration-tests/README.md @@ -27,6 +27,8 @@ version = "your tag" The `./testconfig/overrides.toml` file **should never be committed** and has been added to the [.gitignore](../.gitignore) file as it can often contain secrets like private keys and RPC URLs. +For more information on how to configure the tests, see the [testconfig README](./testconfig/README.md). + ## Build If you'd like to run the tests on a local build of Chainlink, you can point to your own docker image, or build a fresh one with `make`. @@ -76,8 +78,7 @@ make test_soak_ocr_reorg_2 Run reorg/automation_reorg_test.go with reorg settings: -1. Use Simulated Geth network and put GethReorgConfig in overrides.toml - +1. Use Simulated Geth network and put GethReorgConfig in overrides.toml ```toml [Network] diff --git a/integration-tests/testconfig/README.md b/integration-tests/testconfig/README.md index 7ff6cedd24..878b36bc75 100644 --- a/integration-tests/testconfig/README.md +++ b/integration-tests/testconfig/README.md @@ -137,7 +137,9 @@ DefaultTransactionQueueDepth = 0 """ ``` Note that you cannot override individual values in BaseConfigTOML. You must provide the entire configuration. +This corresponds to [Config struct](../../core/services/chainlink/config.go) in Chainlink Node that excludes all chain-specific configuration, which is built based on selected_networks and either Chainlink Node's defaults for each network, or `ChainConfigTOMLByChainID` (if an entry with matching chain id is defined) or `CommonChainConfigTOML` (if no entry with matching chain id is defined). +If BaseConfigTOML is empty, then default base config provided by the Chainlink Node is used. If tracing is enabled unique id will be generated and shared between all Chainlink nodes in the same test. To set base config for EVM chains use `NodeConfig.CommonChainConfigTOML`. Example: ```toml @@ -153,12 +155,12 @@ FeeCapDefault = '200 gwei' """ ``` -This is the default configuration used for all EVM chains unless ChainConfigTOMLByChainID is specified. +This is the default configuration used for all EVM chains unless `ChainConfigTOMLByChainID` is specified. Do remember that if either `ChainConfigTOMLByChainID` or `CommonChainConfigTOML` is defined, it will override any defaults that Chainlink Node might have for the given network. Part of the configuration that defines blockchain node URLs is always dynamically generated based on the EVMNetwork configuration. To set custom per-chain config use `[NodeConfig.ChainConfigTOMLByChainID]`. Example: ```toml [NodeConfig.ChainConfigTOMLByChainID] -# applicable for arbitrum-goerli chain +# applicable only to arbitrum-goerli chain 421613 = """ [GasEstimator] PriceMax = '400 gwei' @@ -170,7 +172,8 @@ BumpMin = '100 gwei' """ ``` -For more examples see `example.toml` in product TOML configs like `testconfig/automation/example.toml`. +For more examples see `example.toml` in product TOML configs like `testconfig/automation/example.toml`. If either ChainConfigTOMLByChainID or CommonChainConfigTOML is defined, it will override any defaults that Chainlink Node might have for the given network. Part of the configuration that defines blockchain node URLs is always dynamically generated based on the EVMNetwork configuration. +Currently, all networks are treated as EVM networks. There's no way to provide Solana, Starknet, Cosmos or Aptos configuration yet. ### Setting env vars for Chainlink Node diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index e4e216cf4a..0d0bb14da9 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -1,37 +1,72 @@ [Logging] +# set to true to flush logs to selected target regardless of test result; otherwise logs are only flushed if test failed test_log_collect = false [Logging.LogStream] +# supported targets: file, loki, in-memory. if empty no logs will be persisted log_targets = ["file"] +# context timeout for starting log producer and also time-frame for requesting logs log_producer_timeout = "10s" +# number of retries before log producer gives up and stops listening to logs log_producer_retry_limit = 10 [ChainlinkImage] +# postgres version to use postgres_version = "15.6" +# chainlink image to use image = "public.ecr.aws/chainlink/chainlink" +# chainlink image tag to use version = "2.12.0" [Common] +# chainlink node funding in native token chainlink_node_funding = 0.5 [Network] +# slice of networks to use; at lesat one network must be selected; each selected network must either be already defined in the CTF as a known network, or be defined in +# TOML test files as a new network selected_networks = ["simulated"] [PrivateEthereumNetwork] +# ethereum version to use; eth1 or eth2 (post-merge) ethereum_version = "eth1" +# execution layer to use; geth, besu, nethermind, erigon or reth execution_layer = "geth" [PrivateEthereumNetwork.EthereumChainConfig] +# duration of single slot, lower => faster block production, must be >= 3 seconds_per_slot = 3 +# number of slots in epoch, lower => faster epoch finalisation, must be >= 2 slots_per_epoch = 2 +# extra genesis delay, no need to modify, but it should be after all validators/beacon chain starts genesis_delay = 15 +# number of validators in the network validator_count = 4 +# chain id to use chain_id = 1337 +# slice of addresses that will be funded with native token in genesis addresses_to_fund = ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"] +# map of hard fork epochs for each network; key is fork name, value is hard fork epoch +# keep in mind that this depends on the specific version of eth2 client you are using +# this configuration is fault-tolerant and incorrect forks will be ignored [PrivateEthereumNetwork.EthereumChainConfig.HardForkEpochs] Deneb = 500 +# General config of the Chainklink node corresponding to core/services/chainlink/config.go (Config struct) that excludes +# all chain-specific configuration, which is built based on selected_networks and either Chainlink Node's defaults for +# each network, or ChainConfigTOMLByChainID (if an entry with matching chain id is defined) or CommonChainConfigTOML (if no +# entry with matching chain id is defined). +# +# Please remember that if either ChainConfigTOMLByChainID or CommonChainConfigTOML is defined, it will override any defaults +# that Chainlink Node might have for the given network. Part of the configuration that defines blockchain node URLs is always +# dynamically generated based on the EVMNetwork configuration. +# +# Last, but not least, currently all selected networks are treated as EVM networks. There's no way to provide Solana, Starknet, +# Cosmos or Aptos configuration yet. +# +# If BaseConfigTOML is empty, then default base config provided by the Chainlink Node is used. +# Also, if tracing is enabled unique id will be generated and shared between all Chainlink nodes in the same test. [NodeConfig] BaseConfigTOML = """ [Feature] @@ -78,12 +113,14 @@ DeltaDial = '500ms' DeltaReconcile = '5s' """ -# override config toml related to EVMNode configs for chainlink nodes; applicable to all EVM node configs in chainlink toml +# Overrides default config TOML related to EVMNode configs for chainlink nodes; applicable to all EVM node configs in chainlink TOML. +# Do not use it, if you want the default values to be used. Passing blockchain nodes URLs here will have no effect. CommonChainConfigTOML = """ """ [NodeConfig.ChainConfigTOMLByChainID] -# applicable for simulated chain +# Chain-specific EVMNode config TOML for chainlink nodes; applicable to all EVM node configs in chainlink TOML. It takes precedence +# over CommonChainConfigTOML and Chainlink Node's defaults. Passing blockchain nodes URLs here will have no effect. 1337 = """ AutoCreateKey = true FinalityDepth = 1 From d963b0aaac2117902742cf1d6fc8471e82ae711b Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Tue, 6 Aug 2024 15:15:24 +0100 Subject: [PATCH 038/432] ks-409 fix the mock trigger to ensure events are sent (#14047) --- .changeset/odd-hats-repeat.md | 5 +++++ .../integration_tests/mock_trigger.go | 18 ++++++++++-------- .../integration_tests/streams_test.go | 6 +++--- 3 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 .changeset/odd-hats-repeat.md diff --git a/.changeset/odd-hats-repeat.md b/.changeset/odd-hats-repeat.md new file mode 100644 index 0000000000..ce80b45caf --- /dev/null +++ b/.changeset/odd-hats-repeat.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal fix the mock trigger to ensure events are sent diff --git a/core/capabilities/integration_tests/mock_trigger.go b/core/capabilities/integration_tests/mock_trigger.go index cb673f54ff..0ed1fe5c8d 100644 --- a/core/capabilities/integration_tests/mock_trigger.go +++ b/core/capabilities/integration_tests/mock_trigger.go @@ -88,18 +88,20 @@ func (s *streamsTrigger) RegisterTrigger(ctx context.Context, request capabiliti responseCh := make(chan capabilities.CapabilityResponse) - ctxWithCancel, cancel := context.WithCancel(ctx) + ctxWithCancel, cancel := context.WithCancel(context.Background()) s.cancel = cancel s.wg.Add(1) go func() { defer s.wg.Done() - select { - case <-s.stopCh: - return - case <-ctxWithCancel.Done(): - return - case resp := <-s.toSend: - responseCh <- resp + for { + select { + case <-s.stopCh: + return + case <-ctxWithCancel.Done(): + return + case resp := <-s.toSend: + responseCh <- resp + } } }() diff --git a/core/capabilities/integration_tests/streams_test.go b/core/capabilities/integration_tests/streams_test.go index 7be392932f..8c8f51914c 100644 --- a/core/capabilities/integration_tests/streams_test.go +++ b/core/capabilities/integration_tests/streams_test.go @@ -24,7 +24,7 @@ func Test_AllAtOnceTransmissionSchedule(t *testing.T) { // in the setupCapabilitiesRegistryContract function, should this order change the don IDs will need updating. workflowDonInfo := createDonInfo(t, don{id: 1, numNodes: 7, f: 2}) triggerDonInfo := createDonInfo(t, don{id: 2, numNodes: 7, f: 2}) - targetDonInfo := createDonInfo(t, don{id: 3, numNodes: 4, f: 2}) + targetDonInfo := createDonInfo(t, don{id: 3, numNodes: 4, f: 1}) consumer, feedIDs, triggerSink := setupStreamDonsWithTransmissionSchedule(ctx, t, workflowDonInfo, triggerDonInfo, targetDonInfo, 3, "2s", "allAtOnce") @@ -45,8 +45,8 @@ func Test_OneAtATimeTransmissionSchedule(t *testing.T) { // The don IDs set in the below calls are inferred from the order in which the dons are added to the capabilities registry // in the setupCapabilitiesRegistryContract function, should this order change the don IDs will need updating. - workflowDonInfo := createDonInfo(t, don{id: 1, numNodes: 5, f: 1}) - triggerDonInfo := createDonInfo(t, don{id: 2, numNodes: 7, f: 1}) + workflowDonInfo := createDonInfo(t, don{id: 1, numNodes: 7, f: 2}) + triggerDonInfo := createDonInfo(t, don{id: 2, numNodes: 7, f: 2}) targetDonInfo := createDonInfo(t, don{id: 3, numNodes: 4, f: 1}) consumer, feedIDs, triggerSink := setupStreamDonsWithTransmissionSchedule(ctx, t, workflowDonInfo, triggerDonInfo, targetDonInfo, 3, From d1d0f445de2e7f4cca132d805be8194be4e50703 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 6 Aug 2024 17:20:41 +0200 Subject: [PATCH 039/432] [TT-1262] dump pg on failure (#14029) * bump CTF * bump bump * go mod * bump bump * bump to 1.34.0 * dump Postgres db on failure and upload as artifacts * test dump in CI * remove test failing on demand, fix test-summary action input name * use tagged CTF, save sql dump also if flag is set --- .../workflows/client-compatibility-tests.yml | 1 + .github/workflows/integration-tests.yml | 7 ++- .github/workflows/live-testnet-tests.yml | 2 +- .github/workflows/live-vrf-tests.yml | 4 +- .../on-demand-keeper-smoke-tests.yml | 3 +- .../on-demand-vrfv2-eth2-clients-test.yml | 22 ++++--- .../on-demand-vrfv2plus-eth2-clients-test.yml | 16 ++--- .../run-e2e-tests-reusable-workflow.yml | 63 ++++++++++--------- .gitignore | 1 + integration-tests/actions/private_network.go | 5 +- integration-tests/chaos/ocr_chaos_test.go | 4 +- .../citool/cmd/create_test_config_cmd.go | 9 +-- .../citool/cmd/test_config_cmd_test.go | 5 +- .../docker/test_env/test_env_builder.go | 43 ++++++++++++- integration-tests/go.mod | 5 +- integration-tests/go.sum | 10 +-- integration-tests/load/go.mod | 5 +- integration-tests/load/go.sum | 10 +-- integration-tests/testsetups/ocr.go | 7 +-- 19 files changed, 138 insertions(+), 84 deletions(-) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 91ada8b7ab..9c1971abb6 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -641,6 +641,7 @@ jobs: artifacts_name: ${{ env.TEST_LOG_NAME }} artifacts_location: | ./integration-tests/smoke/logs/ + ./integration-tests/smoke/db_dumps/ /tmp/gotest.log publish_check_name: ${{ matrix.evm_node.product }}-${{ matrix.evm_node.eth_implementation }} token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index ec9168133d..950add5596 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -359,6 +359,7 @@ jobs: artifacts_name: ${{ matrix.product.name }}-test-logs artifacts_location: | ./integration-tests/smoke/logs/ + ./integration-tests/smoke/db_dumps/ /tmp/gotest.log publish_check_name: ${{ matrix.product.name }} token: ${{ secrets.GITHUB_TOKEN }} @@ -472,6 +473,7 @@ jobs: artifacts_name: ${{ matrix.product.name }}-test-logs artifacts_location: | ./integration-tests/smoke/logs/ + ./integration-tests/smoke/db_dumps/ /tmp/gotest.log publish_check_name: ${{ matrix.product.name }} token: ${{ secrets.GITHUB_TOKEN }} @@ -709,6 +711,7 @@ jobs: artifacts_name: ${{ matrix.product.name }}${{ matrix.product.tag_suffix }}-test-logs artifacts_location: | ./integration-tests/smoke/logs/ + ./integration-tests/smoke/db_dumps/ /tmp/gotest.log publish_check_name: ${{ matrix.product.name }} token: ${{ secrets.GITHUB_TOKEN }} @@ -777,7 +780,7 @@ jobs: if: always() uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 with: - test_directory: ./integration-tests/smoke/ + test_directories: ./integration-tests/smoke/ ### Used to check the required checks box when the matrix completes eth-smoke-tests: @@ -978,7 +981,7 @@ jobs: DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - + - name: Upload Coverage Data uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 timeout-minutes: 2 diff --git a/.github/workflows/live-testnet-tests.yml b/.github/workflows/live-testnet-tests.yml index a7eaa19f7f..bcf4dfea19 100644 --- a/.github/workflows/live-testnet-tests.yml +++ b/.github/workflows/live-testnet-tests.yml @@ -302,7 +302,7 @@ jobs: if: always() uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 with: - test_directory: "./" + test_directories: "./" bsc-testnet-smoke-tests: environment: integration diff --git a/.github/workflows/live-vrf-tests.yml b/.github/workflows/live-vrf-tests.yml index faa4042e66..28f5867954 100644 --- a/.github/workflows/live-vrf-tests.yml +++ b/.github/workflows/live-vrf-tests.yml @@ -120,7 +120,7 @@ jobs: needs: [build-chainlink, build-tests] strategy: fail-fast: false - matrix: + matrix: network: ${{fromJson(needs.build-tests.outputs.matrix)}} name: Smoke Tests on ${{ matrix.network }} runs-on: ubuntu-latest @@ -190,4 +190,4 @@ jobs: if: always() uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 with: - test_directory: "./" \ No newline at end of file + test_directories: "./" diff --git a/.github/workflows/on-demand-keeper-smoke-tests.yml b/.github/workflows/on-demand-keeper-smoke-tests.yml index 75359c7501..626daf0057 100644 --- a/.github/workflows/on-demand-keeper-smoke-tests.yml +++ b/.github/workflows/on-demand-keeper-smoke-tests.yml @@ -149,6 +149,7 @@ jobs: artifacts_name: ${{ matrix.product.name }}-test-logs artifacts_location: | ./integration-tests/smoke/logs/ + ./integration-tests/smoke/db_dumps/ /tmp/gotest.log publish_check_name: ${{ matrix.product.name }} token: ${{ secrets.GITHUB_TOKEN }} @@ -286,4 +287,4 @@ jobs: go test -run=NonExistentTest ./smoke/... || echo "ignore expected test failure" go_mod_path: ./integration-tests/go.mod cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "false" \ No newline at end of file + cache_restore_only: "false" diff --git a/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml b/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml index 5f24fa81c3..6d92acd9ea 100644 --- a/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml +++ b/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml @@ -5,12 +5,12 @@ on: base64Config: description: base64-ed config required: true - type: string + type: string test_secrets_override_key: description: 'Key to run tests with custom test secrets' required: false - type: string - + type: string + jobs: vrfv2_smoke_test: name: VRFV2 Smoke Test with custom EL client client @@ -24,11 +24,11 @@ jobs: env: TEST_LOG_LEVEL: debug REF_NAME: ${{ github.head_ref || github.ref_name }} - steps: + steps: - name: Checkout code uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: - fetch-depth: 0 + fetch-depth: 0 - name: Mask base64 config run: | BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64Config' $GITHUB_EVENT_PATH) @@ -37,7 +37,7 @@ jobs: - name: Parse base64 config uses: ./.github/actions/setup-parse-base64-config with: - base64Config: ${{ env.BASE64_CONFIG_OVERRIDE }} + base64Config: ${{ env.BASE64_CONFIG_OVERRIDE }} - name: Send details to Step Summary shell: bash run: | @@ -48,7 +48,7 @@ jobs: echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY echo "### Execution client used" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.ETH2_EL_CLIENT }}\`" >>$GITHUB_STEP_SUMMARY + echo "\`${{ env.ETH2_EL_CLIENT }}\`" >>$GITHUB_STEP_SUMMARY - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 with: @@ -59,12 +59,14 @@ jobs: cl_image_tag: ${{ env.CHAINLINK_VERSION }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_name: vrf-test-logs - artifacts_location: ./integration-tests/smoke/logs/ + artifacts_location: | + ./integration-tests/smoke/logs/ + ./integration-tests/smoke/db_dumps/ token: ${{ secrets.GITHUB_TOKEN }} go_mod_path: ./integration-tests/go.mod should_cleanup: false QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: "" DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} @@ -72,4 +74,4 @@ jobs: DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} \ No newline at end of file + DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} diff --git a/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml b/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml index 58ecd39763..1e58002fc1 100644 --- a/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml @@ -5,11 +5,11 @@ on: base64Config: description: base64-ed config required: true - type: string + type: string test_secrets_override_key: description: 'Key to run tests with custom test secrets' required: false - type: string + type: string jobs: vrfv2plus_smoke_test: @@ -24,7 +24,7 @@ jobs: env: TEST_LOG_LEVEL: debug REF_NAME: ${{ github.head_ref || github.ref_name }} - steps: + steps: - name: Checkout code uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: @@ -48,7 +48,7 @@ jobs: echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY echo "### Execution client used" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.ETH2_EL_CLIENT }}\`" >>$GITHUB_STEP_SUMMARY + echo "\`${{ env.ETH2_EL_CLIENT }}\`" >>$GITHUB_STEP_SUMMARY - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 with: @@ -59,12 +59,14 @@ jobs: cl_image_tag: ${{ env.CHAINLINK_VERSION }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_name: vrfplus-test-logs - artifacts_location: ./integration-tests/smoke/logs/ + artifacts_location: | + ./integration-tests/smoke/logs/ + ./integration-tests/smoke/db_dumps/ token: ${{ secrets.GITHUB_TOKEN }} go_mod_path: ./integration-tests/go.mod should_cleanup: false QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: "" DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} @@ -72,4 +74,4 @@ jobs: DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} \ No newline at end of file + DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index 2d3f31aa3b..4c177f9a13 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -1,4 +1,4 @@ -# This is a reusable workflow that runs E2E tests for Chainlink. +# This is a reusable workflow that runs E2E tests for Chainlink. # It is not meant to be run on its own. name: Run E2E Tests on: @@ -7,7 +7,7 @@ on: chainlink_version: description: 'Enter Chainlink version to use for the tests. Example: "v2.10.0" or sha' required: false - type: string + type: string test_ids: description: 'Run tests by test ids separated by commas. Example: "run_all_in_ocr_tests_go,run_TestOCRv2Request_in_ocr2_test_go". Check all test IDs in .github/e2e-tests.yml' required: false @@ -15,12 +15,12 @@ on: test_list: description: 'Base64 encoded list of tests (YML objects) to run. Example in run-automation-ondemand-e2e-tests.yml' required: false - type: string + type: string test_workflow: description: 'Run tests by workflow name. Example: "Run Nightly E2E Tests"' required: false type: string - # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 + # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 # test_config_override_base64: # required: false # description: The base64-encoded test config override @@ -64,7 +64,7 @@ on: description: 'Number of days to retain the test log. Default is 3 days' required: false type: number - default: 3 + default: 3 secrets: TEST_SECRETS_OVERRIDE_BASE64: required: false @@ -89,17 +89,17 @@ on: GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: required: true GH_TOKEN: - required: true + required: true AWS_REGION: required: true AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: required: true AWS_API_GW_HOST_GRAFANA: - required: true + required: true SLACK_BOT_TOKEN: required: false - -env: + +env: CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink QA_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink GITHUB_SHA_PLUGINS: ${{ github.sha }}-plugins @@ -127,7 +127,7 @@ jobs: echo "Will run tests with custom test secrets" fi - name: Install jq - run: sudo apt-get install jq + run: sudo apt-get install jq - name: Create matrix for required Chainlink image versions id: set-required-chainlink-image-versions-matrix run: | @@ -328,11 +328,11 @@ jobs: tag_suffix: '' check_image_exists: 'true' AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} # Build Chainlink plugins required for the tests require-chainlink-plugin-versions-in-qa-ecr: - name: Build Chainlink plugins + name: Build Chainlink plugins needs: [validate-inputs, load-test-configurations] if: ${{ needs.validate-inputs.outputs.require_chainlink_plugin_versions_in_qa_ecr_matrix != '' }} runs-on: ubuntu-latest @@ -357,14 +357,14 @@ jobs: tag_suffix: '-plugins' check_image_exists: 'true' AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} # Run Docker tests run-docker-tests: name: Run ${{ matrix.tests.id }} needs: [load-test-configurations, require-chainlink-image-versions-in-qa-ecr, require-chainlink-plugin-versions-in-qa-ecr, get_latest_chainlink_release_version] - # Run when none of the needed jobs fail or are cancelled (skipped or successful jobs are ok) - if: ${{ needs.load-test-configurations.outputs.run-docker-tests == 'true' && always() && !failure() && !cancelled() }} + # Run when none of the needed jobs fail or are cancelled (skipped or successful jobs are ok) + if: ${{ needs.load-test-configurations.outputs.run-docker-tests == 'true' && always() && !failure() && !cancelled() }} runs-on: ${{ matrix.tests.runs_on }} strategy: fail-fast: false @@ -417,7 +417,7 @@ jobs: test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download test_secrets_override_base64: ${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }} - # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 + # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 # test_config_override_base64: ${{ inputs.test_config_override_base64 }} test_config_chainlink_version: ${{ matrix.tests.test_inputs.chainlink_version || inputs.chainlink_version || github.sha }} test_config_chainlink_upgrade_version: ${{ matrix.tests.test_inputs.chainlink_upgrade_version }} @@ -431,6 +431,7 @@ jobs: artifacts_name: ${{ matrix.tests.id_sanitized }}-test-logs artifacts_location: | ./integration-tests/smoke/logs/ + ./integration-tests/smoke/db_dumps/ /tmp/gotest.log publish_check_name: ${{ matrix.tests.id_sanitized }} token: ${{ secrets.GH_TOKEN }} @@ -462,13 +463,13 @@ jobs: name: test_log_${{ matrix.tests.id_sanitized }} path: /tmp/gotest.log retention-days: ${{ inputs.test_log_upload_retention_days }} - continue-on-error: true + continue-on-error: true # Run K8s tests using old remote runner prepare-remote-runner-test-image: needs: [load-test-configurations, require-chainlink-image-versions-in-qa-ecr, require-chainlink-plugin-versions-in-qa-ecr] - if: ${{ needs.load-test-configurations.outputs.run-k8s-tests == 'true' && always() && !failure() && !cancelled() }} + if: ${{ needs.load-test-configurations.outputs.run-k8s-tests == 'true' && always() && !failure() && !cancelled() }} name: Prepare remote runner test image runs-on: ubuntu-latest environment: integration @@ -484,7 +485,7 @@ jobs: ENV_JOB_IMAGE_BASE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests steps: - name: Checkout repository - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Build Test Runner Image uses: ./.github/actions/build-test-image if: ${{ inputs.with_existing_remote_runner_version == '' }} @@ -503,7 +504,7 @@ jobs: run-k8s-runner-tests: needs: [load-test-configurations, prepare-remote-runner-test-image, require-chainlink-image-versions-in-qa-ecr, require-chainlink-plugin-versions-in-qa-ecr, get_latest_chainlink_release_version] - if: ${{ needs.load-test-configurations.outputs.run-k8s-tests == 'true' && always() && !failure() && !cancelled() }} + if: ${{ needs.load-test-configurations.outputs.run-k8s-tests == 'true' && always() && !failure() && !cancelled() }} name: Run ${{ matrix.tests.id }} runs-on: ${{ matrix.tests.runs_on }} strategy: @@ -517,7 +518,7 @@ jobs: id-token: write contents: read env: - LATEST_CHAINLINK_RELEASE_VERSION: ${{ needs.get_latest_chainlink_release_version.outputs.latest_chainlink_release_version }} + LATEST_CHAINLINK_RELEASE_VERSION: ${{ needs.get_latest_chainlink_release_version.outputs.latest_chainlink_release_version }} steps: - name: Collect Metrics if: always() @@ -558,7 +559,7 @@ jobs: test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: make gomod test_secrets_override_base64: ${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }} - # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 + # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 # test_config_override_base64: ${{ inputs.test_config_override_base64 }} test_config_chainlink_version: ${{ matrix.tests.test_inputs.chainlink_version || inputs.chainlink_version || github.sha }} test_config_chainlink_upgrade_version: ${{ matrix.tests.test_inputs.chainlink_upgrade_version }} @@ -574,7 +575,7 @@ jobs: go_mod_path: ./integration-tests/go.mod QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} DEFAULT_CHAINLINK_IMAGE: ${{ matrix.tests.test_inputs.chainlink_image || env.CHAINLINK_IMAGE }} DEFAULT_CHAINLINK_UPGRADE_IMAGE: ${{ matrix.tests.test_inputs.chainlink_upgrade_image }} DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} @@ -587,7 +588,7 @@ jobs: DEFAULT_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} DEFAULT_PYROSCOPE_KEY: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_KEY || '' }} DEFAULT_PYROSCOPE_ENABLED: ${{ matrix.tests.pyroscope_env != '' && 'true' || '' }} - + - name: Upload test log as Github artifact uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 if: inputs.test_log_upload_on_failure && failure() @@ -595,7 +596,7 @@ jobs: name: test_log_${{ matrix.tests.id_sanitized }} path: /tmp/gotest.log retention-days: ${{ inputs.test_log_upload_retention_days }} - continue-on-error: true + continue-on-error: true after_tests: needs: [run-docker-tests, run-k8s-runner-tests] @@ -670,12 +671,12 @@ jobs: # steps: # - name: Checkout repository # uses: actions/checkout@v2 - + # - name: Set up Go # uses: actions/setup-go@v2 # with: # go-version: '1.18' - + # - name: Load Runner Config # run: echo "$RUNNER_CONFIG" > runner.toml # env: @@ -683,7 +684,7 @@ jobs: # # Runner configuration # detached_mode = true # debug = false - + # [[test_runs]] # namespace = "dev-env" # rbac_role_name = "dev-role" @@ -708,7 +709,7 @@ jobs: # WASP_LOG_LEVEL = "info" # TEST_LOG_LEVEL = "info" # MERCURY_TEST_LOG_LEVEL = "info" - + # [[test_runs]] # namespace = "prod-env" # rbac_role_name = "prod-role" @@ -733,7 +734,7 @@ jobs: # WASP_LOG_LEVEL = "info" # TEST_LOG_LEVEL = "info" # MERCURY_TEST_LOG_LEVEL = "info" - + # # Schedule the tests in K8s in remote runner # - name: Run Kubernetes Tests - # run: go run ./cmd/main.go run -c runner.toml \ No newline at end of file + # run: go run ./cmd/main.go run -c runner.toml diff --git a/.gitignore b/.gitignore index 2b31c9d3a5..10636f88d8 100644 --- a/.gitignore +++ b/.gitignore @@ -69,6 +69,7 @@ ztarrepo.tar.gz **/test-ledger/* __debug_bin* .test_summary/ +db_dumps/ .run.id integration-tests/**/traces/ benchmark_report.csv diff --git a/integration-tests/actions/private_network.go b/integration-tests/actions/private_network.go index 70239a6006..f10371d41a 100644 --- a/integration-tests/actions/private_network.go +++ b/integration-tests/actions/private_network.go @@ -4,6 +4,7 @@ import ( "github.com/rs/zerolog" ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" + ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/config/types" ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" ) @@ -12,8 +13,8 @@ func EthereumNetworkConfigFromConfig(l zerolog.Logger, config ctf_config.GlobalT l.Warn().Msg("No TOML private ethereum network config found, will use old geth") ethBuilder := ctf_test_env.NewEthereumNetworkBuilder() network, err = ethBuilder. - WithEthereumVersion(ctf_config.EthereumVersion_Eth1). - WithExecutionLayer(ctf_config.ExecutionLayer_Geth). + WithEthereumVersion(ctf_config_types.EthereumVersion_Eth1). + WithExecutionLayer(ctf_config_types.ExecutionLayer_Geth). Build() return diff --git a/integration-tests/chaos/ocr_chaos_test.go b/integration-tests/chaos/ocr_chaos_test.go index 54a02cf64f..200c97a795 100644 --- a/integration-tests/chaos/ocr_chaos_test.go +++ b/integration-tests/chaos/ocr_chaos_test.go @@ -178,9 +178,7 @@ func TestOCRChaos(t *testing.T) { require.NoError(t, err, "Error tearing down environment") }) - ms, err := ctfClient.ConnectMockServer(testEnvironment) - require.NoError(t, err, "Creating mockserver clients shouldn't fail") - + ms := ctfClient.ConnectMockServer(testEnvironment) linkContract, err := contracts.DeployLinkTokenContract(l, seth) require.NoError(t, err, "Error deploying link token contract") diff --git a/integration-tests/citool/cmd/create_test_config_cmd.go b/integration-tests/citool/cmd/create_test_config_cmd.go index bc1b65bcdc..c0cd91b05f 100644 --- a/integration-tests/citool/cmd/create_test_config_cmd.go +++ b/integration-tests/citool/cmd/create_test_config_cmd.go @@ -8,6 +8,7 @@ import ( "github.com/spf13/cobra" ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" + ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/config/types" ) var createTestConfigCmd = &cobra.Command{ @@ -148,13 +149,13 @@ var createTestConfigCmd = &cobra.Command{ privateEthereumNetworkCustomDockerImage = &oc.PrivateEthereumNetworkCustomDockerImages } if privateEthereumNetworkExecutionLayer != nil || privateEthereumNetworkEthereumVersion != nil || privateEthereumNetworkCustomDockerImage != nil { - var el ctf_config.ExecutionLayer + var el ctf_config_types.ExecutionLayer if privateEthereumNetworkExecutionLayer != nil { - el = ctf_config.ExecutionLayer(*privateEthereumNetworkExecutionLayer) + el = ctf_config_types.ExecutionLayer(*privateEthereumNetworkExecutionLayer) } - var ev ctf_config.EthereumVersion + var ev ctf_config_types.EthereumVersion if privateEthereumNetworkEthereumVersion != nil { - ev = ctf_config.EthereumVersion(*privateEthereumNetworkEthereumVersion) + ev = ctf_config_types.EthereumVersion(*privateEthereumNetworkEthereumVersion) } var customImages map[ctf_config.ContainerType]string if privateEthereumNetworkCustomDockerImage != nil { diff --git a/integration-tests/citool/cmd/test_config_cmd_test.go b/integration-tests/citool/cmd/test_config_cmd_test.go index fb1ef5332b..79185e6082 100644 --- a/integration-tests/citool/cmd/test_config_cmd_test.go +++ b/integration-tests/citool/cmd/test_config_cmd_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/assert" ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" + ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/config/types" ) func TestCreateTestConfigCmd(t *testing.T) { @@ -34,8 +35,8 @@ func TestCreateTestConfigCmd(t *testing.T) { check: func(t *testing.T, tc *ctf_config.TestConfig) { assert.NotNil(t, tc.PrivateEthereumNetwork) assert.NotNil(t, tc.PrivateEthereumNetwork.ExecutionLayer) - assert.Equal(t, ctf_config.ExecutionLayer("geth"), *tc.PrivateEthereumNetwork.ExecutionLayer) - assert.Equal(t, ctf_config.EthereumVersion("1.10.0"), *tc.PrivateEthereumNetwork.EthereumVersion) + assert.Equal(t, ctf_config_types.ExecutionLayer("geth"), *tc.PrivateEthereumNetwork.ExecutionLayer) + assert.Equal(t, ctf_config_types.EthereumVersion("1.10.0"), *tc.PrivateEthereumNetwork.EthereumVersion) }, }, { diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go index df399cbb46..fbd4a7e870 100644 --- a/integration-tests/docker/test_env/test_env_builder.go +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -3,9 +3,11 @@ package test_env import ( "fmt" "os" + "path/filepath" "slices" "strings" "testing" + "time" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -255,7 +257,7 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { b.t.Cleanup(func() { b.l.Info().Msg("Shutting down LogStream") logPath, err := osutil.GetAbsoluteFolderPath("logs") - if err != nil { + if err == nil { b.l.Info().Str("Absolute path", logPath).Msg("LogStream logs folder location") } @@ -281,7 +283,7 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { LogScanningLoop: for i := 0; i < b.clNodesCount; i++ { // if something went wrong during environment setup we might not have all nodes, and we don't want an NPE - if b == nil || b.te == nil || b.te.ClCluster == nil || b.te.ClCluster.Nodes == nil || b.te.ClCluster.Nodes[i] == nil || len(b.te.ClCluster.Nodes)-1 < i { + if b == nil || b.te == nil || b.te.ClCluster == nil || b.te.ClCluster.Nodes == nil || len(b.te.ClCluster.Nodes)-1 < i || b.te.ClCluster.Nodes[i] == nil { continue } // ignore count return, because we are only interested in the error @@ -308,6 +310,43 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { b.te.LogStream.SaveLogLocationInTestSummary() } b.l.Info().Msg("Finished shutting down LogStream") + + if b.t.Failed() || *b.testConfig.GetLoggingConfig().TestLogCollect { + b.l.Info().Msg("Dump state of all Postgres DBs used by Chainlink Nodes") + + dbDumpFolder := "db_dumps" + dbDumpPath := fmt.Sprintf("%s/%s-%s", dbDumpFolder, b.t.Name(), time.Now().Format("2006-01-02T15-04-05")) + if err := os.MkdirAll(dbDumpPath, os.ModePerm); err != nil { + b.l.Error().Err(err).Msg("Error creating folder for Postgres DB dump") + return + } + + absDbDumpPath, err := osutil.GetAbsoluteFolderPath(dbDumpFolder) + if err == nil { + b.l.Info().Str("Absolute path", absDbDumpPath).Msg("PostgresDB dump folder location") + } + + for i := 0; i < b.clNodesCount; i++ { + // if something went wrong during environment setup we might not have all nodes, and we don't want an NPE + if b == nil || b.te == nil || b.te.ClCluster == nil || b.te.ClCluster.Nodes == nil || len(b.te.ClCluster.Nodes)-1 < i || b.te.ClCluster.Nodes[i] == nil || b.te.ClCluster.Nodes[i].PostgresDb == nil { + continue + } + + filePath := filepath.Join(dbDumpPath, fmt.Sprintf("postgres_db_dump_%s.sql", b.te.ClCluster.Nodes[i].ContainerName)) + localDbDumpFile, err := os.Create(filePath) + if err != nil { + b.l.Error().Err(err).Msg("Error creating localDbDumpFile for Postgres DB dump") + _ = localDbDumpFile.Close() + continue + } + + if err := b.te.ClCluster.Nodes[i].PostgresDb.ExecPgDumpFromContainer(localDbDumpFile); err != nil { + b.l.Error().Err(err).Msg("Error dumping Postgres DB") + } + _ = localDbDumpFile.Close() + } + b.l.Info().Msg("Finished dumping state of all Postgres DBs used by Chainlink Nodes") + } }) } else { b.l.Warn().Msg("LogStream won't be cleaned up, because either test instance is not set or cleanup type is set to none") diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 0c0ce33769..3168a702b1 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -29,12 +29,12 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c - github.com/smartcontractkit/chainlink-testing-framework v1.33.0 + github.com/smartcontractkit/chainlink-testing-framework v1.34.2 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/smartcontractkit/seth v1.0.12 + github.com/smartcontractkit/seth v1.1.1 github.com/smartcontractkit/wasp v0.4.5 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.9.0 @@ -90,6 +90,7 @@ require ( github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/avast/retry-go v3.0.0+incompatible // indirect + github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect github.com/aws/aws-sdk-go v1.45.25 // indirect github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect github.com/aws/jsii-runtime-go v1.75.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 8b7bd1d2a1..0de6dc281d 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -209,6 +209,8 @@ github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHS github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= +github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= +github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= @@ -1498,8 +1500,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.33.0 h1:vHQODEdsq5AIbRiyZZ30de6uwJUNFXLYvCr+Odr8TIs= -github.com/smartcontractkit/chainlink-testing-framework v1.33.0/go.mod h1:GrhHthZ5AmceF82+Ypw6Fov1EvB05JJbb1T0EKyO1x0= +github.com/smartcontractkit/chainlink-testing-framework v1.34.2 h1:YL3ft7KJB7SAopdmJeyeR4/kv0j4jOdagNihXq8OZ38= +github.com/smartcontractkit/chainlink-testing-framework v1.34.2/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= @@ -1510,8 +1512,8 @@ github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1 github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= -github.com/smartcontractkit/seth v1.0.12 h1:iVdgMx42XWanPPnBaM5StR4c1XsTr/0/B/kKRZL5BsY= -github.com/smartcontractkit/seth v1.0.12/go.mod h1:thWtbLyW4nRHJGzC5heknQDORoJPErE15sF34LHkorg= +github.com/smartcontractkit/seth v1.1.1 h1:6hvexjJD7ek8ht/CLlEwQcH21K2E/WEYwbSRdKInZmM= +github.com/smartcontractkit/seth v1.1.1/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 4395a3ce48..46b3dd293d 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,11 +17,11 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c - github.com/smartcontractkit/chainlink-testing-framework v1.33.0 + github.com/smartcontractkit/chainlink-testing-framework v1.34.2 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/smartcontractkit/seth v1.0.12 + github.com/smartcontractkit/seth v1.1.1 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 github.com/smartcontractkit/wasp v0.4.7 github.com/stretchr/testify v1.9.0 @@ -35,6 +35,7 @@ require ( cosmossdk.io/depinject v1.0.0-alpha.3 // indirect cosmossdk.io/errors v1.0.0 // indirect cosmossdk.io/math v1.0.1 // indirect + github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 4015287541..0434fe8f42 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -209,6 +209,8 @@ github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHS github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= +github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= +github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= @@ -1480,8 +1482,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.33.0 h1:vHQODEdsq5AIbRiyZZ30de6uwJUNFXLYvCr+Odr8TIs= -github.com/smartcontractkit/chainlink-testing-framework v1.33.0/go.mod h1:GrhHthZ5AmceF82+Ypw6Fov1EvB05JJbb1T0EKyO1x0= +github.com/smartcontractkit/chainlink-testing-framework v1.34.2 h1:YL3ft7KJB7SAopdmJeyeR4/kv0j4jOdagNihXq8OZ38= +github.com/smartcontractkit/chainlink-testing-framework v1.34.2/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= @@ -1492,8 +1494,8 @@ github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1 github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= -github.com/smartcontractkit/seth v1.0.12 h1:iVdgMx42XWanPPnBaM5StR4c1XsTr/0/B/kKRZL5BsY= -github.com/smartcontractkit/seth v1.0.12/go.mod h1:thWtbLyW4nRHJGzC5heknQDORoJPErE15sF34LHkorg= +github.com/smartcontractkit/seth v1.1.1 h1:6hvexjJD7ek8ht/CLlEwQcH21K2E/WEYwbSRdKInZmM= +github.com/smartcontractkit/seth v1.1.1/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= diff --git a/integration-tests/testsetups/ocr.go b/integration-tests/testsetups/ocr.go index 45c334bf69..b38c39eebe 100644 --- a/integration-tests/testsetups/ocr.go +++ b/integration-tests/testsetups/ocr.go @@ -277,7 +277,7 @@ func (o *OCRSoakTest) Setup(ocrTestConfig tt.OcrTestConfig) { nodes, err := client.ConnectChainlinkNodes(o.testEnvironment) require.NoError(o.t, err, "Connecting to chainlink nodes shouldn't fail") o.bootstrapNode, o.workerNodes = nodes[0], nodes[1:] - o.mockServer, err = ctf_client.ConnectMockServer(o.testEnvironment) + o.mockServer = ctf_client.ConnectMockServer(o.testEnvironment) require.NoError(o.t, err, "Creating mockserver clients shouldn't fail") linkContract, err := contracts.DeployLinkTokenContract(o.log, sethClient) @@ -546,10 +546,7 @@ func (o *OCRSoakTest) LoadState() error { } } - o.mockServer, err = ctf_client.ConnectMockServerURL(testState.MockServerURL) - if err != nil { - return err - } + o.mockServer = ctf_client.ConnectMockServerURL(testState.MockServerURL) return err } From e014a137b8a11a39e943cbee1705076bd2e5891a Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Tue, 6 Aug 2024 08:38:04 -0700 Subject: [PATCH 040/432] [KS-411] Extra validation for FeedIDs in Streams Codec (#14038) Make sure the ID extracted from FullReport matcheds the top-level one. --- core/capabilities/streams/codec.go | 4 ++++ core/capabilities/streams/codec_test.go | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/core/capabilities/streams/codec.go b/core/capabilities/streams/codec.go index d2bc451a39..26011cb7f3 100644 --- a/core/capabilities/streams/codec.go +++ b/core/capabilities/streams/codec.go @@ -1,6 +1,7 @@ package streams import ( + "encoding/hex" "fmt" "github.com/ethereum/go-ethereum/common" @@ -34,6 +35,9 @@ func (c *codec) Unwrap(wrapped values.Value) ([]datastreams.FeedReport, error) { if err2 != nil { return nil, fmt.Errorf("failed to decode: %v", err2) } + if decoded.FeedId != id.Bytes() { + return nil, fmt.Errorf("feed ID mismatch: FeedID: %s, FullReport.FeedId: %s", id, hex.EncodeToString(decoded.FeedId[:])) + } dest[i].BenchmarkPrice = decoded.BenchmarkPrice.Bytes() dest[i].ObservationTimestamp = int64(decoded.ObservationsTimestamp) } diff --git a/core/capabilities/streams/codec_test.go b/core/capabilities/streams/codec_test.go index e3ada731e4..02ec474fec 100644 --- a/core/capabilities/streams/codec_test.go +++ b/core/capabilities/streams/codec_test.go @@ -69,7 +69,7 @@ func TestCodec_WrapUnwrap(t *testing.T) { _, err = codec.Unwrap(values.NewBool(true)) require.Error(t, err) - // correct reports byt wrong signatures + // correct reports but wrong signatures unwrapped, err := codec.Unwrap(wrapped) require.NoError(t, err) require.Equal(t, 2, len(unwrapped)) @@ -85,6 +85,20 @@ func TestCodec_WrapUnwrap(t *testing.T) { for _, report := range unwrapped { require.NoError(t, codec.Validate(report, allowedSigners, 2)) } + + // invalid FeedID + wrappedInvalid, err := codec.Wrap([]datastreams.FeedReport{ + { + FeedID: id2Str, // ID #2 doesn't match what's in report #1 + FullReport: report1, + ReportContext: rawCtx, + Signatures: [][]byte{signatureK1R1, signatureK2R1}, + }, + }) + require.NoError(t, err) + _, err = codec.Unwrap(wrappedInvalid) + require.Error(t, err) + require.Contains(t, err.Error(), "feed ID mismatch") } func newFeedID(t *testing.T) ([32]byte, string) { From 537d2ec1ad846898f820874442c3f69915096bad Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Tue, 6 Aug 2024 18:08:44 +0100 Subject: [PATCH 041/432] fix data race in syncer/launcher (#14050) --- .changeset/twelve-balloons-turn.md | 5 +++++ core/capabilities/registry.go | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 .changeset/twelve-balloons-turn.md diff --git a/.changeset/twelve-balloons-turn.md b/.changeset/twelve-balloons-turn.md new file mode 100644 index 0000000000..f4f0e2670e --- /dev/null +++ b/.changeset/twelve-balloons-turn.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal fix data race in syncer launcher diff --git a/core/capabilities/registry.go b/core/capabilities/registry.go index 8a99450c09..d6891c81ab 100644 --- a/core/capabilities/registry.go +++ b/core/capabilities/registry.go @@ -37,6 +37,8 @@ func (r *Registry) LocalNode(ctx context.Context) (capabilities.Node, error) { } func (r *Registry) ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error) { + r.mu.RLock() + defer r.mu.RUnlock() if r.metadataRegistry == nil { return capabilities.CapabilityConfiguration{}, errors.New("metadataRegistry information not available") } From 0a7372cdcd287862069e26c591a5d1ade36d45cf Mon Sep 17 00:00:00 2001 From: Aaron Lu <50029043+aalu1418@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:43:37 -0600 Subject: [PATCH 042/432] update solana e2e test build deps (#13978) * bump solana commit * replace projectserum with backpackapp * handle tagged versions * quick solana bump again * use tagged version --- .github/workflows/integration-tests.yml | 4 ++-- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 950add5596..96a2a7a39f 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -1040,7 +1040,7 @@ jobs: id: getsha run: | cd solanapath - full_sha=$(git rev-parse ${{steps.getshortsha.outputs.short_sha}}) + full_sha=$(git rev-parse ${{steps.getshortsha.outputs.short_sha}}^{}) # additional suffix allows handling tagged versions as well if [ -z "${full_sha}" ]; then echo "Error: could not get the full sha from the short sha using git, look above for error(s)" exit 1 @@ -1125,7 +1125,7 @@ jobs: uses: smartcontractkit/chainlink-solana/.github/actions/build_contract_artifacts@46b1311a5a83f33d08ffa8e1e0ab04f9ad51665d # node20 update on may 10, 2024 with: ref: ${{ needs.get_solana_sha.outputs.sha }} - image: projectserum/build + image: backpackapp/build image-version: ${{ needs.get_projectserum_version.outputs.projectserum_version }} solana-build-test-image: diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 0b7f510bcd..45b5ee5905 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -273,7 +273,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect + github.com/smartcontractkit/chainlink-solana v1.1.0 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 6abc303888..dff6f3f356 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1192,8 +1192,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= +github.com/smartcontractkit/chainlink-solana v1.1.0 h1:+xBeVqx2x0Sx3CBbF8RLSblczsxJDYTkta8h7i8+23I= +github.com/smartcontractkit/chainlink-solana v1.1.0/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= diff --git a/go.mod b/go.mod index 4b216ddc0d..78ec7d29ee 100644 --- a/go.mod +++ b/go.mod @@ -78,7 +78,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e + github.com/smartcontractkit/chainlink-solana v1.1.0 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 diff --git a/go.sum b/go.sum index 6b0ec5aa5c..f5ef0f91e7 100644 --- a/go.sum +++ b/go.sum @@ -1147,8 +1147,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= +github.com/smartcontractkit/chainlink-solana v1.1.0 h1:+xBeVqx2x0Sx3CBbF8RLSblczsxJDYTkta8h7i8+23I= +github.com/smartcontractkit/chainlink-solana v1.1.0/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 3168a702b1..a648e46e9f 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -380,7 +380,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect + github.com/smartcontractkit/chainlink-solana v1.1.0 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 0de6dc281d..03e4a9082f 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1496,8 +1496,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= +github.com/smartcontractkit/chainlink-solana v1.1.0 h1:+xBeVqx2x0Sx3CBbF8RLSblczsxJDYTkta8h7i8+23I= +github.com/smartcontractkit/chainlink-solana v1.1.0/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/chainlink-testing-framework v1.34.2 h1:YL3ft7KJB7SAopdmJeyeR4/kv0j4jOdagNihXq8OZ38= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 46b3dd293d..1aa754f8cf 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -372,7 +372,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect + github.com/smartcontractkit/chainlink-solana v1.1.0 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 // indirect github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 0434fe8f42..698623c50f 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1478,8 +1478,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= +github.com/smartcontractkit/chainlink-solana v1.1.0 h1:+xBeVqx2x0Sx3CBbF8RLSblczsxJDYTkta8h7i8+23I= +github.com/smartcontractkit/chainlink-solana v1.1.0/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/chainlink-testing-framework v1.34.2 h1:YL3ft7KJB7SAopdmJeyeR4/kv0j4jOdagNihXq8OZ38= From c2c31c05ac3fe19d4df8313af25eb740953b935a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ot=C3=A1vio=20Migliavacca=20Madalosso?= Date: Tue, 6 Aug 2024 15:02:57 -0300 Subject: [PATCH 043/432] Set PriceMin to match pip-35 definition (#14014) --- .changeset/tasty-walls-collect.md | 5 +++++ core/chains/evm/config/toml/defaults/Polygon_Amoy.toml | 4 +++- core/chains/evm/config/toml/defaults/Polygon_Mumbai.toml | 3 ++- docs/CONFIG.md | 8 ++++---- 4 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 .changeset/tasty-walls-collect.md diff --git a/.changeset/tasty-walls-collect.md b/.changeset/tasty-walls-collect.md new file mode 100644 index 0000000000..eefe444150 --- /dev/null +++ b/.changeset/tasty-walls-collect.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#updated Update Polygon configs to match PIP-35 diff --git a/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml b/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml index 77438343e2..bca42d9b40 100644 --- a/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml +++ b/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml @@ -11,8 +11,10 @@ NoNewFinalizedHeadsThreshold = '12m' MaxQueued = 5000 [GasEstimator] -EIP1559DynamicFees = true +PriceDefault = '25 gwei' PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '25 gwei' +EIP1559DynamicFees = true BumpMin = '20 gwei' BumpThreshold = 5 diff --git a/core/chains/evm/config/toml/defaults/Polygon_Mumbai.toml b/core/chains/evm/config/toml/defaults/Polygon_Mumbai.toml index ce0f8861de..b9c993c6b2 100644 --- a/core/chains/evm/config/toml/defaults/Polygon_Mumbai.toml +++ b/core/chains/evm/config/toml/defaults/Polygon_Mumbai.toml @@ -11,8 +11,9 @@ RPCDefaultBatchSize = 100 MaxQueued = 5000 [GasEstimator] -PriceDefault = '1 gwei' +PriceDefault = '25 gwei' PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '25 gwei' BumpMin = '20 gwei' BumpThreshold = 5 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 47935390ce..74afcec740 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -6322,9 +6322,9 @@ Enabled = true [GasEstimator] Mode = 'BlockHistory' -PriceDefault = '1 gwei' +PriceDefault = '25 gwei' PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' -PriceMin = '1 gwei' +PriceMin = '25 gwei' LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' @@ -6415,9 +6415,9 @@ Enabled = true [GasEstimator] Mode = 'BlockHistory' -PriceDefault = '20 gwei' +PriceDefault = '25 gwei' PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' -PriceMin = '1 gwei' +PriceMin = '25 gwei' LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' From ce90bc32f562e92af3d22c895446a963109c36e3 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Tue, 6 Aug 2024 14:56:12 -0400 Subject: [PATCH 044/432] auto: adjust cron contract imports (#13927) * auto: adjust cron contract imports * update --- contracts/.changeset/seven-donkeys-live.md | 5 +++++ contracts/src/v0.8/automation/upkeeps/CronUpkeep.sol | 12 ++++++------ .../v0.8/automation/upkeeps/CronUpkeepDelegate.sol | 2 +- .../v0.8/automation/upkeeps/CronUpkeepFactory.sol | 6 +++--- 4 files changed, 15 insertions(+), 10 deletions(-) create mode 100644 contracts/.changeset/seven-donkeys-live.md diff --git a/contracts/.changeset/seven-donkeys-live.md b/contracts/.changeset/seven-donkeys-live.md new file mode 100644 index 0000000000..141588f5b9 --- /dev/null +++ b/contracts/.changeset/seven-donkeys-live.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +improve cron contracts imports diff --git a/contracts/src/v0.8/automation/upkeeps/CronUpkeep.sol b/contracts/src/v0.8/automation/upkeeps/CronUpkeep.sol index 614b84635a..b9eda1f400 100644 --- a/contracts/src/v0.8/automation/upkeeps/CronUpkeep.sol +++ b/contracts/src/v0.8/automation/upkeeps/CronUpkeep.sol @@ -18,12 +18,12 @@ pragma solidity 0.8.6; -import "@openzeppelin/contracts/security/Pausable.sol"; -import "@openzeppelin/contracts/proxy/Proxy.sol"; -import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import "../../shared/access/ConfirmedOwner.sol"; -import "../KeeperBase.sol"; -import "../interfaces/KeeperCompatibleInterface.sol"; +import {Pausable} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/security/Pausable.sol"; +import {Proxy} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/proxy/Proxy.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {KeeperBase as KeeperBase} from "../KeeperBase.sol"; +import {KeeperCompatibleInterface as KeeperCompatibleInterface} from "../interfaces/KeeperCompatibleInterface.sol"; import {Cron as CronInternal, Spec} from "../libraries/internal/Cron.sol"; import {Cron as CronExternal} from "../libraries/external/Cron.sol"; diff --git a/contracts/src/v0.8/automation/upkeeps/CronUpkeepDelegate.sol b/contracts/src/v0.8/automation/upkeeps/CronUpkeepDelegate.sol index ec2c2a0fd9..ed8d031c86 100644 --- a/contracts/src/v0.8/automation/upkeeps/CronUpkeepDelegate.sol +++ b/contracts/src/v0.8/automation/upkeeps/CronUpkeepDelegate.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.6; -import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; import {Cron, Spec} from "../libraries/internal/Cron.sol"; /** diff --git a/contracts/src/v0.8/automation/upkeeps/CronUpkeepFactory.sol b/contracts/src/v0.8/automation/upkeeps/CronUpkeepFactory.sol index cd9ae5d7a9..2b6e97e4d0 100644 --- a/contracts/src/v0.8/automation/upkeeps/CronUpkeepFactory.sol +++ b/contracts/src/v0.8/automation/upkeeps/CronUpkeepFactory.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.6; -import "./CronUpkeep.sol"; -import "./CronUpkeepDelegate.sol"; -import "../../shared/access/ConfirmedOwner.sol"; +import {CronUpkeep} from "./CronUpkeep.sol"; +import {CronUpkeepDelegate} from "./CronUpkeepDelegate.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; import {Spec, Cron as CronExternal} from "../libraries/external/Cron.sol"; /** From 2312827156f24fa4a6e420aec12e5a3aeac81e2b Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Tue, 6 Aug 2024 14:33:16 -0500 Subject: [PATCH 045/432] Add finalizer component to TXM (#13638) * Added a finalizer component that assesses confirmed transactions for finality * Moved Finalizer component into EVM code and addressed feedback * Fixed linting and renumbered sql migration * Added limit to Finalizer RPC batch calls * Cleaned up unneeded code * Renumbered sql migration * Updated Finalizer to use LatestAndFinalizedBlock method from HeadTracker * Fixed health check tests and fixed linting * Fixed lint error * Fixed lint error * Added finalized state to replace finalized column * Updated finalizer batch RPC validation to use blockByNumber and added filter to DB query * Updated reaper to reap old confirmed transactions * Fixed migration test * Fixed lint error * Changed log level * Renumbered sql migration * Updated Finalizer to only process on new finalized heads and improved query performance * Fixed mocks * Updated TxStore method name and fixed mocks * Fixed mock * Updated TxStore method to exit early * Removed unused error --------- Co-authored-by: Silas Lenihan <32529249+silaslenihan@users.noreply.github.com> --- .changeset/itchy-bugs-clean.md | 5 + common/txmgr/models.go | 1 + common/txmgr/reaper.go | 9 +- common/txmgr/txmgr.go | 20 +- common/txmgr/types/config.go | 6 - common/txmgr/types/finalizer.go | 12 + .../txmgr/types/mocks/reaper_chain_config.go | 77 ----- common/txmgr/types/mocks/tx_store.go | 80 +---- common/txmgr/types/tx_store.go | 3 +- .../evm/headtracker/simulated_head_tracker.go | 29 ++ core/chains/evm/txmgr/builder.go | 12 +- core/chains/evm/txmgr/client.go | 4 + core/chains/evm/txmgr/config.go | 1 - core/chains/evm/txmgr/evm_tx_store.go | 124 ++++++-- core/chains/evm/txmgr/evm_tx_store_test.go | 83 +++-- core/chains/evm/txmgr/finalizer.go | 294 ++++++++++++++++++ core/chains/evm/txmgr/finalizer_test.go | 240 ++++++++++++++ core/chains/evm/txmgr/mocks/evm_tx_store.go | 190 ++++++----- core/chains/evm/txmgr/models.go | 3 +- core/chains/evm/txmgr/reaper_test.go | 64 ++-- core/chains/evm/txmgr/test_helpers.go | 13 +- core/chains/evm/txmgr/txmgr_test.go | 72 ++++- core/chains/legacyevm/chain.go | 2 +- core/chains/legacyevm/evm_txm.go | 5 +- .../promreporter/prom_reporter_test.go | 3 +- core/services/vrf/delegate_test.go | 2 +- core/services/vrf/v2/integration_v2_test.go | 2 +- core/services/vrf/v2/listener_v2_test.go | 2 +- core/store/migrate/migrate_test.go | 11 + .../0248_add_tx_finalized_state.sql | 135 ++++++++ core/web/testdata/body/health.html | 3 + core/web/testdata/body/health.json | 9 + core/web/testdata/body/health.txt | 1 + testdata/scripts/health/multi-chain.txtar | 10 + 34 files changed, 1170 insertions(+), 357 deletions(-) create mode 100644 .changeset/itchy-bugs-clean.md create mode 100644 common/txmgr/types/finalizer.go delete mode 100644 common/txmgr/types/mocks/reaper_chain_config.go create mode 100644 core/chains/evm/txmgr/finalizer.go create mode 100644 core/chains/evm/txmgr/finalizer_test.go create mode 100644 core/store/migrate/migrations/0248_add_tx_finalized_state.sql diff --git a/.changeset/itchy-bugs-clean.md b/.changeset/itchy-bugs-clean.md new file mode 100644 index 0000000000..beeed8ace1 --- /dev/null +++ b/.changeset/itchy-bugs-clean.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Introduced finalized transaction state. Added a finalizer component to the TXM to mark transactions as finalized. #internal diff --git a/common/txmgr/models.go b/common/txmgr/models.go index dd121a2c7c..ca5e7d4f25 100644 --- a/common/txmgr/models.go +++ b/common/txmgr/models.go @@ -11,4 +11,5 @@ const ( TxUnconfirmed = txmgrtypes.TxState("unconfirmed") TxConfirmed = txmgrtypes.TxState("confirmed") TxConfirmedMissingReceipt = txmgrtypes.TxState("confirmed_missing_receipt") + TxFinalized = txmgrtypes.TxState("finalized") ) diff --git a/common/txmgr/reaper.go b/common/txmgr/reaper.go index 932b58f643..0c797548b1 100644 --- a/common/txmgr/reaper.go +++ b/common/txmgr/reaper.go @@ -14,7 +14,6 @@ import ( // Reaper handles periodic database cleanup for Txm type Reaper[CHAIN_ID types.ID] struct { store txmgrtypes.TxHistoryReaper[CHAIN_ID] - config txmgrtypes.ReaperChainConfig txConfig txmgrtypes.ReaperTransactionsConfig chainID CHAIN_ID log logger.Logger @@ -25,10 +24,9 @@ type Reaper[CHAIN_ID types.ID] struct { } // NewReaper instantiates a new reaper object -func NewReaper[CHAIN_ID types.ID](lggr logger.Logger, store txmgrtypes.TxHistoryReaper[CHAIN_ID], config txmgrtypes.ReaperChainConfig, txConfig txmgrtypes.ReaperTransactionsConfig, chainID CHAIN_ID) *Reaper[CHAIN_ID] { +func NewReaper[CHAIN_ID types.ID](lggr logger.Logger, store txmgrtypes.TxHistoryReaper[CHAIN_ID], txConfig txmgrtypes.ReaperTransactionsConfig, chainID CHAIN_ID) *Reaper[CHAIN_ID] { r := &Reaper[CHAIN_ID]{ store, - config, txConfig, chainID, logger.Named(lggr, "Reaper"), @@ -103,13 +101,12 @@ func (r *Reaper[CHAIN_ID]) ReapTxes(headNum int64) error { r.log.Debug("Transactions.ReaperThreshold set to 0; skipping ReapTxes") return nil } - minBlockNumberToKeep := headNum - int64(r.config.FinalityDepth()) mark := time.Now() timeThreshold := mark.Add(-threshold) - r.log.Debugw(fmt.Sprintf("reaping old txes created before %s", timeThreshold.Format(time.RFC3339)), "ageThreshold", threshold, "timeThreshold", timeThreshold, "minBlockNumberToKeep", minBlockNumberToKeep) + r.log.Debugw(fmt.Sprintf("reaping old txes created before %s", timeThreshold.Format(time.RFC3339)), "ageThreshold", threshold, "timeThreshold", timeThreshold) - if err := r.store.ReapTxHistory(ctx, minBlockNumberToKeep, timeThreshold, r.chainID); err != nil { + if err := r.store.ReapTxHistory(ctx, timeThreshold, r.chainID); err != nil { return err } diff --git a/common/txmgr/txmgr.go b/common/txmgr/txmgr.go index fc27e930c3..49ac8a89b7 100644 --- a/common/txmgr/txmgr.go +++ b/common/txmgr/txmgr.go @@ -108,6 +108,7 @@ type Txm[ broadcaster *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] confirmer *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE] tracker *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE] + finalizer txmgrtypes.Finalizer[BLOCK_HASH, HEAD] fwdMgr txmgrtypes.ForwarderManager[ADDR] txAttemptBuilder txmgrtypes.TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] newErrorClassifier NewErrorClassifier @@ -143,6 +144,7 @@ func NewTxm[ confirmer *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE], resender *Resender[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE], tracker *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE], + finalizer txmgrtypes.Finalizer[BLOCK_HASH, HEAD], newErrorClassifierFunc NewErrorClassifier, ) *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { b := Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]{ @@ -165,13 +167,14 @@ func NewTxm[ resender: resender, tracker: tracker, newErrorClassifier: newErrorClassifierFunc, + finalizer: finalizer, } if txCfg.ResendAfterThreshold() <= 0 { b.logger.Info("Resender: Disabled") } if txCfg.ReaperThreshold() > 0 && txCfg.ReaperInterval() > 0 { - b.reaper = NewReaper[CHAIN_ID](lggr, b.txStore, cfg, txCfg, chainId) + b.reaper = NewReaper[CHAIN_ID](lggr, b.txStore, txCfg, chainId) } else { b.logger.Info("TxReaper: Disabled") } @@ -199,6 +202,10 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Start(ctx return fmt.Errorf("Txm: Tracker failed to start: %w", err) } + if err := ms.Start(ctx, b.finalizer); err != nil { + return fmt.Errorf("Txm: Finalizer failed to start: %w", err) + } + b.logger.Info("Txm starting runLoop") b.wg.Add(1) go b.runLoop() @@ -293,6 +300,7 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) HealthRepo services.CopyHealth(report, b.broadcaster.HealthReport()) services.CopyHealth(report, b.confirmer.HealthReport()) services.CopyHealth(report, b.txAttemptBuilder.HealthReport()) + services.CopyHealth(report, b.finalizer.HealthReport()) }) if b.txConfig.ForwardersEnabled() { @@ -415,6 +423,7 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) runLoop() case head := <-b.chHeads: b.confirmer.mb.Deliver(head) b.tracker.mb.Deliver(head.BlockNumber()) + b.finalizer.DeliverLatestHead(head) case reset := <-b.reset: // This check prevents the weird edge-case where you can select // into this block after chStop has already been closed and the @@ -446,6 +455,10 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) runLoop() if err != nil && (!errors.Is(err, services.ErrAlreadyStopped) || !errors.Is(err, services.ErrCannotStopUnstarted)) { b.logger.Errorw(fmt.Sprintf("Failed to Close Tracker: %v", err), "err", err) } + err = b.finalizer.Close() + if err != nil && (!errors.Is(err, services.ErrAlreadyStopped) || !errors.Is(err, services.ErrCannotStopUnstarted)) { + b.logger.Errorw(fmt.Sprintf("Failed to Close Finalizer: %v", err), "err", err) + } return case <-keysChanged: // This check prevents the weird edge-case where you can select @@ -644,9 +657,10 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) GetTransac // Return unconfirmed for ConfirmedMissingReceipt since a receipt is required to determine if it is finalized return commontypes.Unconfirmed, nil case TxConfirmed: - // TODO: Check for finality and return finalized status - // Return unconfirmed if tx receipt's block is newer than the latest finalized block + // Return unconfirmed for confirmed transactions because they are not yet finalized return commontypes.Unconfirmed, nil + case TxFinalized: + return commontypes.Finalized, nil case TxFatalError: // Use an ErrorClassifier to determine if the transaction is considered Fatal txErr := b.newErrorClassifier(tx.GetError()) diff --git a/common/txmgr/types/config.go b/common/txmgr/types/config.go index 4d9af5f067..8b11a45d11 100644 --- a/common/txmgr/types/config.go +++ b/common/txmgr/types/config.go @@ -5,7 +5,6 @@ import "time" type TransactionManagerChainConfig interface { BroadcasterChainConfig ConfirmerChainConfig - ReaperChainConfig } type TransactionManagerFeeConfig interface { @@ -74,11 +73,6 @@ type ResenderTransactionsConfig interface { MaxInFlight() uint32 } -// ReaperConfig is the config subset used by the reaper -type ReaperChainConfig interface { - FinalityDepth() uint32 -} - type ReaperTransactionsConfig interface { ReaperInterval() time.Duration ReaperThreshold() time.Duration diff --git a/common/txmgr/types/finalizer.go b/common/txmgr/types/finalizer.go new file mode 100644 index 0000000000..be3c897d0e --- /dev/null +++ b/common/txmgr/types/finalizer.go @@ -0,0 +1,12 @@ +package types + +import ( + "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink/v2/common/types" +) + +type Finalizer[BLOCK_HASH types.Hashable, HEAD types.Head[BLOCK_HASH]] interface { + // interfaces for running the underlying estimator + services.Service + DeliverLatestHead(head HEAD) bool +} diff --git a/common/txmgr/types/mocks/reaper_chain_config.go b/common/txmgr/types/mocks/reaper_chain_config.go deleted file mode 100644 index 0531b07170..0000000000 --- a/common/txmgr/types/mocks/reaper_chain_config.go +++ /dev/null @@ -1,77 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package mocks - -import mock "github.com/stretchr/testify/mock" - -// ReaperConfig is an autogenerated mock type for the ReaperChainConfig type -type ReaperConfig struct { - mock.Mock -} - -type ReaperConfig_Expecter struct { - mock *mock.Mock -} - -func (_m *ReaperConfig) EXPECT() *ReaperConfig_Expecter { - return &ReaperConfig_Expecter{mock: &_m.Mock} -} - -// FinalityDepth provides a mock function with given fields: -func (_m *ReaperConfig) FinalityDepth() uint32 { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for FinalityDepth") - } - - var r0 uint32 - if rf, ok := ret.Get(0).(func() uint32); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(uint32) - } - - return r0 -} - -// ReaperConfig_FinalityDepth_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FinalityDepth' -type ReaperConfig_FinalityDepth_Call struct { - *mock.Call -} - -// FinalityDepth is a helper method to define mock.On call -func (_e *ReaperConfig_Expecter) FinalityDepth() *ReaperConfig_FinalityDepth_Call { - return &ReaperConfig_FinalityDepth_Call{Call: _e.mock.On("FinalityDepth")} -} - -func (_c *ReaperConfig_FinalityDepth_Call) Run(run func()) *ReaperConfig_FinalityDepth_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *ReaperConfig_FinalityDepth_Call) Return(_a0 uint32) *ReaperConfig_FinalityDepth_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ReaperConfig_FinalityDepth_Call) RunAndReturn(run func() uint32) *ReaperConfig_FinalityDepth_Call { - _c.Call.Return(run) - return _c -} - -// NewReaperConfig creates a new instance of ReaperConfig. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewReaperConfig(t interface { - mock.TestingT - Cleanup(func()) -}) *ReaperConfig { - mock := &ReaperConfig{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/common/txmgr/types/mocks/tx_store.go b/common/txmgr/types/mocks/tx_store.go index ee166638e3..0b9c711066 100644 --- a/common/txmgr/types/mocks/tx_store.go +++ b/common/txmgr/types/mocks/tx_store.go @@ -1760,65 +1760,6 @@ func (_c *TxStore_HasInProgressTransaction_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_H return _c } -// IsTxFinalized provides a mock function with given fields: ctx, blockHeight, txID, chainID -func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) IsTxFinalized(ctx context.Context, blockHeight int64, txID int64, chainID CHAIN_ID) (bool, error) { - ret := _m.Called(ctx, blockHeight, txID, chainID) - - if len(ret) == 0 { - panic("no return value specified for IsTxFinalized") - } - - var r0 bool - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, int64, int64, CHAIN_ID) (bool, error)); ok { - return rf(ctx, blockHeight, txID, chainID) - } - if rf, ok := ret.Get(0).(func(context.Context, int64, int64, CHAIN_ID) bool); ok { - r0 = rf(ctx, blockHeight, txID, chainID) - } else { - r0 = ret.Get(0).(bool) - } - - if rf, ok := ret.Get(1).(func(context.Context, int64, int64, CHAIN_ID) error); ok { - r1 = rf(ctx, blockHeight, txID, chainID) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// TxStore_IsTxFinalized_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsTxFinalized' -type TxStore_IsTxFinalized_Call[ADDR types.Hashable, CHAIN_ID types.ID, TX_HASH types.Hashable, BLOCK_HASH types.Hashable, R txmgrtypes.ChainReceipt[TX_HASH, BLOCK_HASH], SEQ types.Sequence, FEE feetypes.Fee] struct { - *mock.Call -} - -// IsTxFinalized is a helper method to define mock.On call -// - ctx context.Context -// - blockHeight int64 -// - txID int64 -// - chainID CHAIN_ID -func (_e *TxStore_Expecter[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) IsTxFinalized(ctx interface{}, blockHeight interface{}, txID interface{}, chainID interface{}) *TxStore_IsTxFinalized_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { - return &TxStore_IsTxFinalized_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]{Call: _e.mock.On("IsTxFinalized", ctx, blockHeight, txID, chainID)} -} - -func (_c *TxStore_IsTxFinalized_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Run(run func(ctx context.Context, blockHeight int64, txID int64, chainID CHAIN_ID)) *TxStore_IsTxFinalized_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(int64), args[2].(int64), args[3].(CHAIN_ID)) - }) - return _c -} - -func (_c *TxStore_IsTxFinalized_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Return(finalized bool, err error) *TxStore_IsTxFinalized_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { - _c.Call.Return(finalized, err) - return _c -} - -func (_c *TxStore_IsTxFinalized_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) RunAndReturn(run func(context.Context, int64, int64, CHAIN_ID) (bool, error)) *TxStore_IsTxFinalized_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { - _c.Call.Return(run) - return _c -} - // LoadTxAttempts provides a mock function with given fields: ctx, etx func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) LoadTxAttempts(ctx context.Context, etx *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) error { ret := _m.Called(ctx, etx) @@ -2069,17 +2010,17 @@ func (_c *TxStore_PruneUnstartedTxQueue_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH return _c } -// ReapTxHistory provides a mock function with given fields: ctx, minBlockNumberToKeep, timeThreshold, chainID -func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) ReapTxHistory(ctx context.Context, minBlockNumberToKeep int64, timeThreshold time.Time, chainID CHAIN_ID) error { - ret := _m.Called(ctx, minBlockNumberToKeep, timeThreshold, chainID) +// ReapTxHistory provides a mock function with given fields: ctx, timeThreshold, chainID +func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) ReapTxHistory(ctx context.Context, timeThreshold time.Time, chainID CHAIN_ID) error { + ret := _m.Called(ctx, timeThreshold, chainID) if len(ret) == 0 { panic("no return value specified for ReapTxHistory") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, int64, time.Time, CHAIN_ID) error); ok { - r0 = rf(ctx, minBlockNumberToKeep, timeThreshold, chainID) + if rf, ok := ret.Get(0).(func(context.Context, time.Time, CHAIN_ID) error); ok { + r0 = rf(ctx, timeThreshold, chainID) } else { r0 = ret.Error(0) } @@ -2094,16 +2035,15 @@ type TxStore_ReapTxHistory_Call[ADDR types.Hashable, CHAIN_ID types.ID, TX_HASH // ReapTxHistory is a helper method to define mock.On call // - ctx context.Context -// - minBlockNumberToKeep int64 // - timeThreshold time.Time // - chainID CHAIN_ID -func (_e *TxStore_Expecter[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) ReapTxHistory(ctx interface{}, minBlockNumberToKeep interface{}, timeThreshold interface{}, chainID interface{}) *TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { - return &TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]{Call: _e.mock.On("ReapTxHistory", ctx, minBlockNumberToKeep, timeThreshold, chainID)} +func (_e *TxStore_Expecter[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) ReapTxHistory(ctx interface{}, timeThreshold interface{}, chainID interface{}) *TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { + return &TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]{Call: _e.mock.On("ReapTxHistory", ctx, timeThreshold, chainID)} } -func (_c *TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Run(run func(ctx context.Context, minBlockNumberToKeep int64, timeThreshold time.Time, chainID CHAIN_ID)) *TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { +func (_c *TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Run(run func(ctx context.Context, timeThreshold time.Time, chainID CHAIN_ID)) *TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(int64), args[2].(time.Time), args[3].(CHAIN_ID)) + run(args[0].(context.Context), args[1].(time.Time), args[2].(CHAIN_ID)) }) return _c } @@ -2113,7 +2053,7 @@ func (_c *TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ return _c } -func (_c *TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) RunAndReturn(run func(context.Context, int64, time.Time, CHAIN_ID) error) *TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { +func (_c *TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) RunAndReturn(run func(context.Context, time.Time, CHAIN_ID) error) *TxStore_ReapTxHistory_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { _c.Call.Return(run) return _c } diff --git a/common/txmgr/types/tx_store.go b/common/txmgr/types/tx_store.go index 875339cfba..63b56dd169 100644 --- a/common/txmgr/types/tx_store.go +++ b/common/txmgr/types/tx_store.go @@ -105,11 +105,10 @@ type TransactionStore[ UpdateTxUnstartedToInProgress(ctx context.Context, etx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt *TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) error UpdateTxFatalError(ctx context.Context, etx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) error UpdateTxForRebroadcast(ctx context.Context, etx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], etxAttempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) error - IsTxFinalized(ctx context.Context, blockHeight int64, txID int64, chainID CHAIN_ID) (finalized bool, err error) } type TxHistoryReaper[CHAIN_ID types.ID] interface { - ReapTxHistory(ctx context.Context, minBlockNumberToKeep int64, timeThreshold time.Time, chainID CHAIN_ID) error + ReapTxHistory(ctx context.Context, timeThreshold time.Time, chainID CHAIN_ID) error } type UnstartedTxQueuePruner interface { diff --git a/core/chains/evm/headtracker/simulated_head_tracker.go b/core/chains/evm/headtracker/simulated_head_tracker.go index e1e550de99..62bb4968c2 100644 --- a/core/chains/evm/headtracker/simulated_head_tracker.go +++ b/core/chains/evm/headtracker/simulated_head_tracker.go @@ -2,6 +2,7 @@ package headtracker import ( "context" + "errors" "fmt" "math/big" @@ -51,3 +52,31 @@ func (ht *simulatedHeadTracker) LatestAndFinalizedBlock(ctx context.Context) (*e return latest, finalizedBlock, nil } + +func (ht *simulatedHeadTracker) LatestChain() *evmtypes.Head { + return nil +} + +func (ht *simulatedHeadTracker) HealthReport() map[string]error { + return nil +} + +func (ht *simulatedHeadTracker) Start(_ context.Context) error { + return nil +} + +func (ht *simulatedHeadTracker) Close() error { + return nil +} + +func (ht *simulatedHeadTracker) Backfill(_ context.Context, _ *evmtypes.Head) error { + return errors.New("unimplemented") +} + +func (ht *simulatedHeadTracker) Name() string { + return "SimulatedHeadTracker" +} + +func (ht *simulatedHeadTracker) Ready() error { + return nil +} diff --git a/core/chains/evm/txmgr/builder.go b/core/chains/evm/txmgr/builder.go index 8234d55b96..d85d6acdc8 100644 --- a/core/chains/evm/txmgr/builder.go +++ b/core/chains/evm/txmgr/builder.go @@ -13,6 +13,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/forwarders" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/keystore" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -32,6 +33,7 @@ func NewTxm( logPoller logpoller.LogPoller, keyStore keystore.Eth, estimator gas.EvmFeeEstimator, + headTracker httypes.HeadTracker, ) (txm TxManager, err error, ) { @@ -54,11 +56,12 @@ func NewTxm( evmTracker := NewEvmTracker(txStore, keyStore, chainID, lggr) stuckTxDetector := NewStuckTxDetector(lggr, client.ConfiguredChainID(), chainConfig.ChainType(), fCfg.PriceMax(), txConfig.AutoPurge(), estimator, txStore, client) evmConfirmer := NewEvmConfirmer(txStore, txmClient, txmCfg, feeCfg, txConfig, dbConfig, keyStore, txAttemptBuilder, lggr, stuckTxDetector) + evmFinalizer := NewEvmFinalizer(lggr, client.ConfiguredChainID(), chainConfig.RPCDefaultBatchSize(), txStore, client, headTracker) var evmResender *Resender if txConfig.ResendAfterThreshold() > 0 { evmResender = NewEvmResender(lggr, txStore, txmClient, evmTracker, keyStore, txmgr.DefaultResenderPollInterval, chainConfig, txConfig) } - txm = NewEvmTxm(chainID, txmCfg, txConfig, keyStore, lggr, checker, fwdMgr, txAttemptBuilder, txStore, evmBroadcaster, evmConfirmer, evmResender, evmTracker) + txm = NewEvmTxm(chainID, txmCfg, txConfig, keyStore, lggr, checker, fwdMgr, txAttemptBuilder, txStore, evmBroadcaster, evmConfirmer, evmResender, evmTracker, evmFinalizer) return txm, nil } @@ -77,8 +80,9 @@ func NewEvmTxm( confirmer *Confirmer, resender *Resender, tracker *Tracker, + finalizer Finalizer, ) *Txm { - return txmgr.NewTxm(chainId, cfg, txCfg, keyStore, lggr, checkerFactory, fwdMgr, txAttemptBuilder, txStore, broadcaster, confirmer, resender, tracker, client.NewTxError) + return txmgr.NewTxm(chainId, cfg, txCfg, keyStore, lggr, checkerFactory, fwdMgr, txAttemptBuilder, txStore, broadcaster, confirmer, resender, tracker, finalizer, client.NewTxError) } // NewEvmResender creates a new concrete EvmResender @@ -96,8 +100,8 @@ func NewEvmResender( } // NewEvmReaper instantiates a new EVM-specific reaper object -func NewEvmReaper(lggr logger.Logger, store txmgrtypes.TxHistoryReaper[*big.Int], config EvmReaperConfig, txConfig txmgrtypes.ReaperTransactionsConfig, chainID *big.Int) *Reaper { - return txmgr.NewReaper(lggr, store, config, txConfig, chainID) +func NewEvmReaper(lggr logger.Logger, store txmgrtypes.TxHistoryReaper[*big.Int], txConfig txmgrtypes.ReaperTransactionsConfig, chainID *big.Int) *Reaper { + return txmgr.NewReaper(lggr, store, txConfig, chainID) } // NewEvmConfirmer instantiates a new EVM confirmer diff --git a/core/chains/evm/txmgr/client.go b/core/chains/evm/txmgr/client.go index 661a180af5..e995080a26 100644 --- a/core/chains/evm/txmgr/client.go +++ b/core/chains/evm/txmgr/client.go @@ -183,3 +183,7 @@ func (c *evmTxmClient) CallContract(ctx context.Context, a TxAttempt, blockNumbe }, blockNumber) return client.ExtractRPCError(errCall) } + +func (c *evmTxmClient) HeadByHash(ctx context.Context, hash common.Hash) (*evmtypes.Head, error) { + return c.client.HeadByHash(ctx, hash) +} diff --git a/core/chains/evm/txmgr/config.go b/core/chains/evm/txmgr/config.go index b53f99840b..af20c9a590 100644 --- a/core/chains/evm/txmgr/config.go +++ b/core/chains/evm/txmgr/config.go @@ -48,7 +48,6 @@ type ( EvmBroadcasterConfig txmgrtypes.BroadcasterChainConfig EvmConfirmerConfig txmgrtypes.ConfirmerChainConfig EvmResenderConfig txmgrtypes.ResenderChainConfig - EvmReaperConfig txmgrtypes.ReaperChainConfig ) var _ EvmTxmConfig = (*evmTxmConfig)(nil) diff --git a/core/chains/evm/txmgr/evm_tx_store.go b/core/chains/evm/txmgr/evm_tx_store.go index e83a83907e..45de437e44 100644 --- a/core/chains/evm/txmgr/evm_tx_store.go +++ b/core/chains/evm/txmgr/evm_tx_store.go @@ -44,6 +44,10 @@ type EvmTxStore interface { // redeclare TxStore for mockery txmgrtypes.TxStore[common.Address, *big.Int, common.Hash, common.Hash, *evmtypes.Receipt, evmtypes.Nonce, gas.EvmFee] TxStoreWebApi + + // methods used solely in EVM components + FindConfirmedTxesReceipts(ctx context.Context, finalizedBlockNum int64, chainID *big.Int) (receipts []Receipt, err error) + UpdateTxStatesToFinalizedUsingReceiptIds(ctx context.Context, etxIDs []int64, chainId *big.Int) error } // TxStoreWebApi encapsulates the methods that are not used by the txmgr and only used by the various web controllers, readers, or evm specific components @@ -87,7 +91,7 @@ var _ TestEvmTxStore = (*evmTxStore)(nil) // Directly maps to columns of database table "evm.receipts". // Do not modify type unless you // intend to modify the database schema -type dbReceipt struct { +type DbReceipt struct { ID int64 TxHash common.Hash BlockHash common.Hash @@ -97,8 +101,8 @@ type dbReceipt struct { CreatedAt time.Time } -func DbReceiptFromEvmReceipt(evmReceipt *evmtypes.Receipt) dbReceipt { - return dbReceipt{ +func DbReceiptFromEvmReceipt(evmReceipt *evmtypes.Receipt) DbReceipt { + return DbReceipt{ TxHash: evmReceipt.TxHash, BlockHash: evmReceipt.BlockHash, BlockNumber: evmReceipt.BlockNumber.Int64(), @@ -107,7 +111,7 @@ func DbReceiptFromEvmReceipt(evmReceipt *evmtypes.Receipt) dbReceipt { } } -func DbReceiptToEvmReceipt(receipt *dbReceipt) *evmtypes.Receipt { +func DbReceiptToEvmReceipt(receipt *DbReceipt) *evmtypes.Receipt { return &receipt.Receipt } @@ -131,7 +135,7 @@ type dbReceiptPlus struct { FailOnRevert bool `db:"FailOnRevert"` } -func fromDBReceipts(rs []dbReceipt) []*evmtypes.Receipt { +func fromDBReceipts(rs []DbReceipt) []*evmtypes.Receipt { receipts := make([]*evmtypes.Receipt, len(rs)) for i := 0; i < len(rs); i++ { receipts[i] = DbReceiptToEvmReceipt(&rs[i]) @@ -677,7 +681,7 @@ func (o *evmTxStore) loadEthTxesAttemptsReceipts(ctx context.Context, etxs []*Tx attemptHashes = append(attemptHashes, attempt.Hash.Bytes()) } } - var rs []dbReceipt + var rs []DbReceipt if err = o.q.SelectContext(ctx, &rs, `SELECT * FROM evm.receipts WHERE tx_hash = ANY($1)`, pq.Array(attemptHashes)); err != nil { return pkgerrors.Wrap(err, "loadEthTxesAttemptsReceipts failed to load evm.receipts") } @@ -700,7 +704,7 @@ func loadConfirmedAttemptsReceipts(ctx context.Context, q sqlutil.DataSource, at byHash[attempt.Hash.String()] = &attempts[i] hashes = append(hashes, attempt.Hash.Bytes()) } - var rs []dbReceipt + var rs []DbReceipt if err := q.SelectContext(ctx, &rs, `SELECT * FROM evm.receipts WHERE tx_hash = ANY($1)`, pq.Array(hashes)); err != nil { return pkgerrors.Wrap(err, "loadConfirmedAttemptsReceipts failed to load evm.receipts") } @@ -1116,7 +1120,7 @@ func updateEthTxAttemptUnbroadcast(ctx context.Context, orm *evmTxStore, attempt func updateEthTxUnconfirm(ctx context.Context, orm *evmTxStore, etx Tx) error { if etx.State != txmgr.TxConfirmed { - return errors.New("expected eth_tx state to be confirmed") + return errors.New("expected tx state to be confirmed") } _, err := orm.q.ExecContext(ctx, `UPDATE evm.txes SET state = 'unconfirmed' WHERE id = $1`, etx.ID) return pkgerrors.Wrap(err, "updateEthTxUnconfirm failed") @@ -1205,24 +1209,6 @@ AND evm_chain_id = $1`, chainID.String()).Scan(&earliestUnconfirmedTxBlock) return earliestUnconfirmedTxBlock, err } -func (o *evmTxStore) IsTxFinalized(ctx context.Context, blockHeight int64, txID int64, chainID *big.Int) (finalized bool, err error) { - var cancel context.CancelFunc - ctx, cancel = o.stopCh.Ctx(ctx) - defer cancel() - - var count int32 - err = o.q.GetContext(ctx, &count, ` - SELECT COUNT(evm.receipts.receipt) FROM evm.txes - INNER JOIN evm.tx_attempts ON evm.txes.id = evm.tx_attempts.eth_tx_id - INNER JOIN evm.receipts ON evm.tx_attempts.hash = evm.receipts.tx_hash - WHERE evm.receipts.block_number <= ($1 - evm.txes.min_confirmations) - AND evm.txes.id = $2 AND evm.txes.evm_chain_id = $3`, blockHeight, txID, chainID.String()) - if err != nil { - return false, fmt.Errorf("failed to retrieve transaction reciepts: %w", err) - } - return count > 0, nil -} - func (o *evmTxStore) saveAttemptWithNewState(ctx context.Context, attempt TxAttempt, broadcastAt time.Time) error { var dbAttempt DbEthTxAttempt dbAttempt.FromTxAttempt(&attempt) @@ -1872,7 +1858,7 @@ id < ( return } -func (o *evmTxStore) ReapTxHistory(ctx context.Context, minBlockNumberToKeep int64, timeThreshold time.Time, chainID *big.Int) error { +func (o *evmTxStore) ReapTxHistory(ctx context.Context, timeThreshold time.Time, chainID *big.Int) error { var cancel context.CancelFunc ctx, cancel = o.stopCh.Ctx(ctx) defer cancel() @@ -1885,19 +1871,18 @@ func (o *evmTxStore) ReapTxHistory(ctx context.Context, minBlockNumberToKeep int res, err := o.q.ExecContext(ctx, ` WITH old_enough_receipts AS ( SELECT tx_hash FROM evm.receipts - WHERE block_number < $1 ORDER BY block_number ASC, id ASC - LIMIT $2 + LIMIT $1 ) DELETE FROM evm.txes USING old_enough_receipts, evm.tx_attempts WHERE evm.tx_attempts.eth_tx_id = evm.txes.id AND evm.tx_attempts.hash = old_enough_receipts.tx_hash -AND evm.txes.created_at < $3 -AND evm.txes.state = 'confirmed' -AND evm_chain_id = $4`, minBlockNumberToKeep, limit, timeThreshold, chainID.String()) +AND evm.txes.created_at < $2 +AND evm.txes.state = 'finalized' +AND evm_chain_id = $3`, limit, timeThreshold, chainID.String()) if err != nil { - return count, pkgerrors.Wrap(err, "ReapTxes failed to delete old confirmed evm.txes") + return count, pkgerrors.Wrap(err, "ReapTxes failed to delete old finalized evm.txes") } rowsAffected, err := res.RowsAffected() if err != nil { @@ -1906,7 +1891,7 @@ AND evm_chain_id = $4`, minBlockNumberToKeep, limit, timeThreshold, chainID.Stri return uint(rowsAffected), err }, batchSize) if err != nil { - return pkgerrors.Wrap(err, "TxmReaper#reapEthTxes batch delete of confirmed evm.txes failed") + return pkgerrors.Wrap(err, "TxmReaper#reapEthTxes batch delete of finalized evm.txes failed") } // Delete old 'fatal_error' evm.txes err = sqlutil.Batch(func(_, limit uint) (count uint, err error) { @@ -1927,6 +1912,38 @@ AND evm_chain_id = $2`, timeThreshold, chainID.String()) if err != nil { return pkgerrors.Wrap(err, "TxmReaper#reapEthTxes batch delete of fatally errored evm.txes failed") } + // Delete old 'confirmed' evm.txes that were never finalized + // This query should never result in changes but added just in case transactions slip through the cracks + // to avoid them building up in the DB + err = sqlutil.Batch(func(_, limit uint) (count uint, err error) { + res, err := o.q.ExecContext(ctx, ` +WITH old_enough_receipts AS ( + SELECT tx_hash FROM evm.receipts + ORDER BY block_number ASC, id ASC + LIMIT $1 +) +DELETE FROM evm.txes +USING old_enough_receipts, evm.tx_attempts +WHERE evm.tx_attempts.eth_tx_id = evm.txes.id +AND evm.tx_attempts.hash = old_enough_receipts.tx_hash +AND evm.txes.created_at < $2 +AND evm.txes.state = 'confirmed' +AND evm_chain_id = $3`, limit, timeThreshold, chainID.String()) + if err != nil { + return count, pkgerrors.Wrap(err, "ReapTxes failed to delete old confirmed evm.txes") + } + rowsAffected, err := res.RowsAffected() + if err != nil { + return count, pkgerrors.Wrap(err, "ReapTxes failed to get rows affected") + } + if rowsAffected > 0 { + o.logger.Errorf("%d confirmed transactions were reaped before being marked as finalized. This should never happen unless the threshold is set too low or the transactions were lost track of", rowsAffected) + } + return uint(rowsAffected), err + }, batchSize) + if err != nil { + return pkgerrors.Wrap(err, "TxmReaper#reapEthTxes batch delete of confirmed evm.txes failed") + } return nil } @@ -2055,3 +2072,42 @@ func (o *evmTxStore) UpdateTxAttemptBroadcastBeforeBlockNum(ctx context.Context, _, err := o.q.ExecContext(ctx, sql, blockNum, id) return err } + +// Returns all confirmed transactions with receipt block nums older than or equal to the finalized block number +func (o *evmTxStore) FindConfirmedTxesReceipts(ctx context.Context, finalizedBlockNum int64, chainID *big.Int) (receipts []Receipt, err error) { + var cancel context.CancelFunc + ctx, cancel = o.stopCh.Ctx(ctx) + defer cancel() + err = o.Transact(ctx, true, func(orm *evmTxStore) error { + sql := `SELECT evm.receipts.* FROM evm.receipts + INNER JOIN evm.tx_attempts ON evm.tx_attempts.hash = evm.receipts.tx_hash + INNER JOIN evm.txes ON evm.txes.id = evm.tx_attempts.eth_tx_id + WHERE evm.txes.state = 'confirmed' AND evm.receipts.block_number <= $1 AND evm.txes.evm_chain_id = $2` + var dbReceipts []DbReceipt + err = o.q.SelectContext(ctx, &dbReceipts, sql, finalizedBlockNum, chainID.String()) + if len(dbReceipts) == 0 { + return nil + } + receipts = dbReceipts + return nil + }) + return receipts, err +} + +// Mark transactions corresponding to receipt IDs as finalized +func (o *evmTxStore) UpdateTxStatesToFinalizedUsingReceiptIds(ctx context.Context, receiptIDs []int64, chainId *big.Int) error { + if len(receiptIDs) == 0 { + return nil + } + var cancel context.CancelFunc + ctx, cancel = o.stopCh.Ctx(ctx) + defer cancel() + sql := ` +UPDATE evm.txes SET state = 'finalized' WHERE evm.txes.evm_chain_id = $1 AND evm.txes.id IN (SELECT evm.txes.id FROM evm.txes + INNER JOIN evm.tx_attempts ON evm.tx_attempts.eth_tx_id = evm.txes.id + INNER JOIN evm.receipts ON evm.receipts.tx_hash = evm.tx_attempts.hash + WHERE evm.receipts.id = ANY($2)) +` + _, err := o.q.ExecContext(ctx, sql, chainId.String(), pq.Array(receiptIDs)) + return err +} diff --git a/core/chains/evm/txmgr/evm_tx_store_test.go b/core/chains/evm/txmgr/evm_tx_store_test.go index afb8de4ca5..191a0a5fed 100644 --- a/core/chains/evm/txmgr/evm_tx_store_test.go +++ b/core/chains/evm/txmgr/evm_tx_store_test.go @@ -783,30 +783,6 @@ func TestORM_UpdateTxForRebroadcast(t *testing.T) { }) } -func TestORM_IsTxFinalized(t *testing.T) { - t.Parallel() - - db := pgtest.NewSqlxDB(t) - txStore := cltest.NewTestTxStore(t, db) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - - t.Run("confirmed tx not past finality_depth", func(t *testing.T) { - confirmedAddr := cltest.MustGenerateRandomKey(t).Address - tx := mustInsertConfirmedEthTxWithReceipt(t, txStore, confirmedAddr, 123, 1) - finalized, err := txStore.IsTxFinalized(tests.Context(t), 2, tx.ID, ethClient.ConfiguredChainID()) - require.NoError(t, err) - require.False(t, finalized) - }) - - t.Run("confirmed tx past finality_depth", func(t *testing.T) { - confirmedAddr := cltest.MustGenerateRandomKey(t).Address - tx := mustInsertConfirmedEthTxWithReceipt(t, txStore, confirmedAddr, 123, 1) - finalized, err := txStore.IsTxFinalized(tests.Context(t), 10, tx.ID, ethClient.ConfiguredChainID()) - require.NoError(t, err) - require.True(t, finalized) - }) -} - func TestORM_FindTransactionsConfirmedInBlockRange(t *testing.T) { t.Parallel() @@ -1382,7 +1358,7 @@ func TestORM_UpdateTxUnstartedToInProgress(t *testing.T) { evmTxmCfg := txmgr.NewEvmTxmConfig(ccfg.EVM()) ec := evmtest.NewEthClientMockWithDefaultChain(t) txMgr := txmgr.NewEvmTxm(ec.ConfiguredChainID(), evmTxmCfg, ccfg.EVM().Transactions(), nil, logger.Test(t), nil, nil, - nil, txStore, nil, nil, nil, nil) + nil, txStore, nil, nil, nil, nil, nil) err := txMgr.XXXTestAbandon(fromAddress) // mark transaction as abandoned require.NoError(t, err) @@ -1871,3 +1847,60 @@ func AssertCountPerSubject(t *testing.T, txStore txmgr.TestEvmTxStore, expected require.NoError(t, err) require.Equal(t, int(expected), count) } + +func TestORM_FindTransactionsByState(t *testing.T) { + t.Parallel() + + ctx := tests.Context(t) + db := pgtest.NewSqlxDB(t) + txStore := cltest.NewTestTxStore(t, db) + kst := cltest.NewKeyStore(t, db) + _, fromAddress := cltest.MustInsertRandomKey(t, kst.Eth()) + finalizedBlockNum := int64(100) + + mustInsertUnstartedTx(t, txStore, fromAddress) + mustInsertInProgressEthTxWithAttempt(t, txStore, 0, fromAddress) + mustInsertUnconfirmedEthTxWithAttemptState(t, txStore, 1, fromAddress, txmgrtypes.TxAttemptBroadcast) + mustInsertConfirmedMissingReceiptEthTxWithLegacyAttempt(t, txStore, 2, finalizedBlockNum, time.Now(), fromAddress) + mustInsertConfirmedEthTxWithReceipt(t, txStore, fromAddress, 3, finalizedBlockNum+1) + mustInsertConfirmedEthTxWithReceipt(t, txStore, fromAddress, 4, finalizedBlockNum) + mustInsertFatalErrorEthTx(t, txStore, fromAddress) + + receipts, err := txStore.FindConfirmedTxesReceipts(ctx, finalizedBlockNum, testutils.FixtureChainID) + require.NoError(t, err) + require.Len(t, receipts, 1) +} + +func TestORM_UpdateTxesFinalized(t *testing.T) { + t.Parallel() + + ctx := tests.Context(t) + db := pgtest.NewSqlxDB(t) + txStore := cltest.NewTestTxStore(t, db) + kst := cltest.NewKeyStore(t, db) + broadcast := time.Now() + _, fromAddress := cltest.MustInsertRandomKey(t, kst.Eth()) + + t.Run("successfully finalizes a confirmed transaction", func(t *testing.T) { + nonce := evmtypes.Nonce(0) + tx := &txmgr.Tx{ + Sequence: &nonce, + FromAddress: fromAddress, + EncodedPayload: []byte{1, 2, 3}, + State: txmgrcommon.TxConfirmed, + BroadcastAt: &broadcast, + InitialBroadcastAt: &broadcast, + } + err := txStore.InsertTx(ctx, tx) + require.NoError(t, err) + attempt := newBroadcastLegacyEthTxAttempt(t, tx.ID) + err = txStore.InsertTxAttempt(ctx, &attempt) + require.NoError(t, err) + receipt := mustInsertEthReceipt(t, txStore, 100, testutils.NewHash(), attempt.Hash) + err = txStore.UpdateTxStatesToFinalizedUsingReceiptIds(ctx, []int64{receipt.ID}, testutils.FixtureChainID) + require.NoError(t, err) + etx, err := txStore.FindTxWithAttempts(ctx, tx.ID) + require.NoError(t, err) + require.Equal(t, txmgrcommon.TxFinalized, etx.State) + }) +} diff --git a/core/chains/evm/txmgr/finalizer.go b/core/chains/evm/txmgr/finalizer.go new file mode 100644 index 0000000000..6d5fb81782 --- /dev/null +++ b/core/chains/evm/txmgr/finalizer.go @@ -0,0 +1,294 @@ +package txmgr + +import ( + "context" + "fmt" + "math/big" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rpc" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" +) + +var _ Finalizer = (*evmFinalizer)(nil) + +// processHeadTimeout represents a sanity limit on how long ProcessHead should take to complete +const processHeadTimeout = 10 * time.Minute + +type finalizerTxStore interface { + FindConfirmedTxesReceipts(ctx context.Context, finalizedBlockNum int64, chainID *big.Int) ([]Receipt, error) + UpdateTxStatesToFinalizedUsingReceiptIds(ctx context.Context, txs []int64, chainId *big.Int) error +} + +type finalizerChainClient interface { + BatchCallContext(ctx context.Context, elems []rpc.BatchElem) error +} + +type finalizerHeadTracker interface { + LatestAndFinalizedBlock(ctx context.Context) (latest, finalized *evmtypes.Head, err error) +} + +// Finalizer handles processing new finalized blocks and marking transactions as finalized accordingly in the TXM DB +type evmFinalizer struct { + services.StateMachine + lggr logger.SugaredLogger + chainId *big.Int + rpcBatchSize int + + txStore finalizerTxStore + client finalizerChainClient + headTracker finalizerHeadTracker + + mb *mailbox.Mailbox[*evmtypes.Head] + stopCh services.StopChan + wg sync.WaitGroup + + lastProcessedFinalizedBlockNum int64 +} + +func NewEvmFinalizer( + lggr logger.Logger, + chainId *big.Int, + rpcBatchSize uint32, + txStore finalizerTxStore, + client finalizerChainClient, + headTracker finalizerHeadTracker, +) *evmFinalizer { + lggr = logger.Named(lggr, "Finalizer") + return &evmFinalizer{ + lggr: logger.Sugared(lggr), + chainId: chainId, + rpcBatchSize: int(rpcBatchSize), + txStore: txStore, + client: client, + headTracker: headTracker, + mb: mailbox.NewSingle[*evmtypes.Head](), + } +} + +// Start the finalizer +func (f *evmFinalizer) Start(ctx context.Context) error { + return f.StartOnce("Finalizer", func() error { + f.lggr.Debugf("started Finalizer with RPC batch size limit: %d", f.rpcBatchSize) + f.stopCh = make(chan struct{}) + f.wg.Add(1) + go f.runLoop() + return nil + }) +} + +// Close the finalizer +func (f *evmFinalizer) Close() error { + return f.StopOnce("Finalizer", func() error { + f.lggr.Debug("closing Finalizer") + close(f.stopCh) + f.wg.Wait() + return nil + }) +} + +func (f *evmFinalizer) Name() string { + return f.lggr.Name() +} + +func (f *evmFinalizer) HealthReport() map[string]error { + return map[string]error{f.Name(): f.Healthy()} +} + +func (f *evmFinalizer) runLoop() { + defer f.wg.Done() + ctx, cancel := f.stopCh.NewCtx() + defer cancel() + for { + select { + case <-f.mb.Notify(): + for { + if ctx.Err() != nil { + return + } + head, exists := f.mb.Retrieve() + if !exists { + break + } + if err := f.ProcessHead(ctx, head); err != nil { + f.lggr.Errorw("Error processing head", "err", err) + f.SvcErrBuffer.Append(err) + continue + } + } + case <-ctx.Done(): + return + } + } +} + +func (f *evmFinalizer) DeliverLatestHead(head *evmtypes.Head) bool { + return f.mb.Deliver(head) +} + +func (f *evmFinalizer) ProcessHead(ctx context.Context, head *evmtypes.Head) error { + ctx, cancel := context.WithTimeout(ctx, processHeadTimeout) + defer cancel() + _, latestFinalizedHead, err := f.headTracker.LatestAndFinalizedBlock(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve latest finalized head: %w", err) + } + return f.processFinalizedHead(ctx, latestFinalizedHead) +} + +// Determines if any confirmed transactions can be marked as finalized by comparing their receipts against the latest finalized block +func (f *evmFinalizer) processFinalizedHead(ctx context.Context, latestFinalizedHead *evmtypes.Head) error { + // Cannot determine finality without a finalized head for comparison + if latestFinalizedHead == nil || !latestFinalizedHead.IsValid() { + return fmt.Errorf("invalid latestFinalizedHead") + } + // Only continue processing if the latestFinalizedHead has not already been processed + // Helps avoid unnecessary processing on every head if blocks are finalized in batches + if latestFinalizedHead.BlockNumber() == f.lastProcessedFinalizedBlockNum { + return nil + } + if latestFinalizedHead.BlockNumber() < f.lastProcessedFinalizedBlockNum { + f.lggr.Errorw("Received finalized block older than one already processed. This should never happen and could be an issue with RPCs.", "lastProcessedFinalizedBlockNum", f.lastProcessedFinalizedBlockNum, "retrievedFinalizedBlockNum", latestFinalizedHead.BlockNumber()) + return nil + } + + earliestBlockNumInChain := latestFinalizedHead.EarliestHeadInChain().BlockNumber() + f.lggr.Debugw("processing latest finalized head", "blockNum", latestFinalizedHead.BlockNumber(), "blockHash", latestFinalizedHead.BlockHash(), "earliestBlockNumInChain", earliestBlockNumInChain) + + // Retrieve all confirmed transactions with receipts older than or equal to the finalized block, loaded with attempts and receipts + unfinalizedReceipts, err := f.txStore.FindConfirmedTxesReceipts(ctx, latestFinalizedHead.BlockNumber(), f.chainId) + if err != nil { + return fmt.Errorf("failed to retrieve receipts for confirmed, unfinalized transactions: %w", err) + } + + var finalizedReceipts []Receipt + // Group by block hash transactions whose receipts cannot be validated using the cached heads + blockNumToReceiptsMap := make(map[int64][]Receipt) + // Find transactions with receipt block nums older than the latest finalized block num and block hashes still in chain + for _, receipt := range unfinalizedReceipts { + // The tx store query ensures transactions have receipts but leaving this check here for a belts and braces approach + if receipt.Receipt.IsZero() || receipt.Receipt.IsUnmined() { + f.lggr.AssumptionViolationw("invalid receipt found for confirmed transaction", "receipt", receipt) + continue + } + // The tx store query only returns transactions with receipts older than or equal to the finalized block but leaving this check here for a belts and braces approach + if receipt.BlockNumber > latestFinalizedHead.BlockNumber() { + continue + } + // Receipt block num older than earliest head in chain. Validate hash using RPC call later + if receipt.BlockNumber < earliestBlockNumInChain { + blockNumToReceiptsMap[receipt.BlockNumber] = append(blockNumToReceiptsMap[receipt.BlockNumber], receipt) + continue + } + blockHashInChain := latestFinalizedHead.HashAtHeight(receipt.BlockNumber) + // Receipt block hash does not match the block hash in chain. Transaction has been re-org'd out but DB state has not been updated yet + if blockHashInChain.String() != receipt.BlockHash.String() { + // Log error if a transaction is marked as confirmed with a receipt older than the finalized block + // This scenario could potentially point to a re-org'd transaction the Confirmer has lost track of + f.lggr.Errorw("found confirmed transaction with re-org'd receipt older than finalized block", "receipt", receipt, "onchainBlockHash", blockHashInChain.String()) + continue + } + finalizedReceipts = append(finalizedReceipts, receipt) + } + + // Check if block hashes exist for receipts on-chain older than the earliest cached head + // Transactions are grouped by their receipt block hash to avoid repeat requests on the same hash in case transactions were confirmed in the same block + validatedReceipts := f.batchCheckReceiptHashesOnchain(ctx, blockNumToReceiptsMap) + finalizedReceipts = append(finalizedReceipts, validatedReceipts...) + + receiptIDs := f.buildReceiptIdList(finalizedReceipts) + + err = f.txStore.UpdateTxStatesToFinalizedUsingReceiptIds(ctx, receiptIDs, f.chainId) + if err != nil { + return fmt.Errorf("failed to update transactions as finalized: %w", err) + } + // Update lastProcessedFinalizedBlockNum after processing has completed to allow failed processing to retry on subsequent heads + // Does not need to be protected with mutex lock because the Finalizer only runs in a single loop + f.lastProcessedFinalizedBlockNum = latestFinalizedHead.BlockNumber() + return nil +} + +func (f *evmFinalizer) batchCheckReceiptHashesOnchain(ctx context.Context, blockNumToReceiptsMap map[int64][]Receipt) []Receipt { + if len(blockNumToReceiptsMap) == 0 { + return nil + } + // Group the RPC batch calls in groups of rpcBatchSize + var rpcBatchGroups [][]rpc.BatchElem + var rpcBatch []rpc.BatchElem + for blockNum := range blockNumToReceiptsMap { + elem := rpc.BatchElem{ + Method: "eth_getBlockByNumber", + Args: []any{ + hexutil.EncodeBig(big.NewInt(blockNum)), + false, + }, + Result: new(evmtypes.Head), + } + rpcBatch = append(rpcBatch, elem) + if len(rpcBatch) >= f.rpcBatchSize { + rpcBatchGroups = append(rpcBatchGroups, rpcBatch) + rpcBatch = []rpc.BatchElem{} + } + } + if len(rpcBatch) > 0 { + rpcBatchGroups = append(rpcBatchGroups, rpcBatch) + } + + var finalizedReceipts []Receipt + for _, rpcBatch := range rpcBatchGroups { + err := f.client.BatchCallContext(ctx, rpcBatch) + if err != nil { + // Continue if batch RPC call failed so other batches can still be considered for finalization + f.lggr.Errorw("failed to find blocks due to batch call failure", "error", err) + continue + } + for _, req := range rpcBatch { + if req.Error != nil { + // Continue if particular RPC call failed so other txs can still be considered for finalization + f.lggr.Errorw("failed to find block by number", "blockNum", req.Args[0], "error", req.Error) + continue + } + head, ok := req.Result.(*evmtypes.Head) + if !ok || !head.IsValid() { + // Continue if particular RPC call yielded a nil block so other txs can still be considered for finalization + f.lggr.Errorw("retrieved nil head for block number", "blockNum", req.Args[0]) + continue + } + receipts := blockNumToReceiptsMap[head.BlockNumber()] + // Check if transaction receipts match the block hash at the given block num + // If they do not, the transactions may have been re-org'd out + // The expectation is for the Confirmer to pick up on these re-orgs and get the transaction included + for _, receipt := range receipts { + if receipt.BlockHash.String() == head.BlockHash().String() { + finalizedReceipts = append(finalizedReceipts, receipt) + } else { + // Log error if a transaction is marked as confirmed with a receipt older than the finalized block + // This scenario could potentially point to a re-org'd transaction the Confirmer has lost track of + f.lggr.Errorw("found confirmed transaction with re-org'd receipt older than finalized block", "receipt", receipt, "onchainBlockHash", head.BlockHash().String()) + } + } + } + } + return finalizedReceipts +} + +// Build list of transaction IDs +func (f *evmFinalizer) buildReceiptIdList(finalizedReceipts []Receipt) []int64 { + receiptIds := make([]int64, len(finalizedReceipts)) + for i, receipt := range finalizedReceipts { + f.lggr.Debugw("transaction considered finalized", + "txHash", receipt.TxHash.String(), + "receiptBlockNum", receipt.BlockNumber, + "receiptBlockHash", receipt.BlockHash.String(), + ) + receiptIds[i] = receipt.ID + } + return receiptIds +} diff --git a/core/chains/evm/txmgr/finalizer_test.go b/core/chains/evm/txmgr/finalizer_test.go new file mode 100644 index 0000000000..f83a53bf49 --- /dev/null +++ b/core/chains/evm/txmgr/finalizer_test.go @@ -0,0 +1,240 @@ +package txmgr_test + +import ( + "errors" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rpc" + "github.com/google/uuid" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + + txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/testutils" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" +) + +func TestFinalizer_MarkTxFinalized(t *testing.T) { + t.Parallel() + ctx := tests.Context(t) + db := pgtest.NewSqlxDB(t) + txStore := cltest.NewTestTxStore(t, db) + ethKeyStore := cltest.NewKeyStore(t, db).Eth() + feeLimit := uint64(10_000) + ethClient := testutils.NewEthClientMockWithDefaultChain(t) + rpcBatchSize := uint32(1) + ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) + + head := &evmtypes.Head{ + Hash: utils.NewHash(), + Number: 100, + Parent: &evmtypes.Head{ + Hash: utils.NewHash(), + Number: 99, + IsFinalized: true, + }, + } + + t.Run("returns not finalized for tx with receipt newer than finalized block", func(t *testing.T) { + finalizer := txmgr.NewEvmFinalizer(logger.Test(t), testutils.FixtureChainID, rpcBatchSize, txStore, ethClient, ht) + servicetest.Run(t, finalizer) + + idempotencyKey := uuid.New().String() + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + nonce := evmtypes.Nonce(0) + broadcast := time.Now() + tx := &txmgr.Tx{ + Sequence: &nonce, + IdempotencyKey: &idempotencyKey, + FromAddress: fromAddress, + EncodedPayload: []byte{1, 2, 3}, + FeeLimit: feeLimit, + State: txmgrcommon.TxConfirmed, + BroadcastAt: &broadcast, + InitialBroadcastAt: &broadcast, + } + attemptHash := insertTxAndAttemptWithIdempotencyKey(t, txStore, tx, idempotencyKey) + // Insert receipt for unfinalized block num + mustInsertEthReceipt(t, txStore, head.Number, head.Hash, attemptHash) + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(head.Parent, nil).Once() + err := finalizer.ProcessHead(ctx, head) + require.NoError(t, err) + tx, err = txStore.FindTxWithIdempotencyKey(ctx, idempotencyKey, testutils.FixtureChainID) + require.NoError(t, err) + require.Equal(t, txmgrcommon.TxConfirmed, tx.State) + }) + + t.Run("returns not finalized for tx with receipt re-org'd out", func(t *testing.T) { + finalizer := txmgr.NewEvmFinalizer(logger.Test(t), testutils.FixtureChainID, rpcBatchSize, txStore, ethClient, ht) + servicetest.Run(t, finalizer) + + idempotencyKey := uuid.New().String() + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + nonce := evmtypes.Nonce(0) + broadcast := time.Now() + tx := &txmgr.Tx{ + Sequence: &nonce, + IdempotencyKey: &idempotencyKey, + FromAddress: fromAddress, + EncodedPayload: []byte{1, 2, 3}, + FeeLimit: feeLimit, + State: txmgrcommon.TxConfirmed, + BroadcastAt: &broadcast, + InitialBroadcastAt: &broadcast, + } + attemptHash := insertTxAndAttemptWithIdempotencyKey(t, txStore, tx, idempotencyKey) + // Insert receipt for finalized block num + mustInsertEthReceipt(t, txStore, head.Parent.Number, utils.NewHash(), attemptHash) + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(head.Parent, nil).Once() + err := finalizer.ProcessHead(ctx, head) + require.NoError(t, err) + tx, err = txStore.FindTxWithIdempotencyKey(ctx, idempotencyKey, testutils.FixtureChainID) + require.NoError(t, err) + require.Equal(t, txmgrcommon.TxConfirmed, tx.State) + }) + + t.Run("returns finalized for tx with receipt in a finalized block", func(t *testing.T) { + finalizer := txmgr.NewEvmFinalizer(logger.Test(t), testutils.FixtureChainID, rpcBatchSize, txStore, ethClient, ht) + servicetest.Run(t, finalizer) + + idempotencyKey := uuid.New().String() + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + nonce := evmtypes.Nonce(0) + broadcast := time.Now() + tx := &txmgr.Tx{ + Sequence: &nonce, + IdempotencyKey: &idempotencyKey, + FromAddress: fromAddress, + EncodedPayload: []byte{1, 2, 3}, + FeeLimit: feeLimit, + State: txmgrcommon.TxConfirmed, + BroadcastAt: &broadcast, + InitialBroadcastAt: &broadcast, + } + attemptHash := insertTxAndAttemptWithIdempotencyKey(t, txStore, tx, idempotencyKey) + // Insert receipt for finalized block num + mustInsertEthReceipt(t, txStore, head.Parent.Number, head.Parent.Hash, attemptHash) + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(head.Parent, nil).Once() + err := finalizer.ProcessHead(ctx, head) + require.NoError(t, err) + tx, err = txStore.FindTxWithIdempotencyKey(ctx, idempotencyKey, testutils.FixtureChainID) + require.NoError(t, err) + require.Equal(t, txmgrcommon.TxFinalized, tx.State) + }) + + t.Run("returns finalized for tx with receipt older than block history depth", func(t *testing.T) { + finalizer := txmgr.NewEvmFinalizer(logger.Test(t), testutils.FixtureChainID, rpcBatchSize, txStore, ethClient, ht) + servicetest.Run(t, finalizer) + + idempotencyKey := uuid.New().String() + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + nonce := evmtypes.Nonce(0) + broadcast := time.Now() + tx := &txmgr.Tx{ + Sequence: &nonce, + IdempotencyKey: &idempotencyKey, + FromAddress: fromAddress, + EncodedPayload: []byte{1, 2, 3}, + FeeLimit: feeLimit, + State: txmgrcommon.TxConfirmed, + BroadcastAt: &broadcast, + InitialBroadcastAt: &broadcast, + } + attemptHash := insertTxAndAttemptWithIdempotencyKey(t, txStore, tx, idempotencyKey) + // Insert receipt for finalized block num + receiptBlockHash1 := utils.NewHash() + mustInsertEthReceipt(t, txStore, head.Parent.Number-2, receiptBlockHash1, attemptHash) + idempotencyKey = uuid.New().String() + nonce = evmtypes.Nonce(1) + tx = &txmgr.Tx{ + Sequence: &nonce, + IdempotencyKey: &idempotencyKey, + FromAddress: fromAddress, + EncodedPayload: []byte{1, 2, 3}, + FeeLimit: feeLimit, + State: txmgrcommon.TxConfirmed, + BroadcastAt: &broadcast, + InitialBroadcastAt: &broadcast, + } + attemptHash = insertTxAndAttemptWithIdempotencyKey(t, txStore, tx, idempotencyKey) + // Insert receipt for finalized block num + receiptBlockHash2 := utils.NewHash() + mustInsertEthReceipt(t, txStore, head.Parent.Number-1, receiptBlockHash2, attemptHash) + // Separate batch calls will be made for each tx due to RPC batch size set to 1 when finalizer initialized above + ethClient.On("BatchCallContext", mock.Anything, mock.IsType([]rpc.BatchElem{})).Run(func(args mock.Arguments) { + rpcElements := args.Get(1).([]rpc.BatchElem) + require.Equal(t, 1, len(rpcElements)) + + require.Equal(t, "eth_getBlockByNumber", rpcElements[0].Method) + require.Equal(t, false, rpcElements[0].Args[1]) + + reqBlockNum := rpcElements[0].Args[0].(string) + req1BlockNum := hexutil.EncodeBig(big.NewInt(head.Parent.Number - 2)) + req2BlockNum := hexutil.EncodeBig(big.NewInt(head.Parent.Number - 1)) + var headResult evmtypes.Head + if req1BlockNum == reqBlockNum { + headResult = evmtypes.Head{Number: head.Parent.Number - 2, Hash: receiptBlockHash1} + } else if req2BlockNum == reqBlockNum { + headResult = evmtypes.Head{Number: head.Parent.Number - 1, Hash: receiptBlockHash2} + } else { + require.Fail(t, "unrecognized block hash") + } + rpcElements[0].Result = &headResult + }).Return(nil).Twice() + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(head.Parent, nil).Once() + err := finalizer.ProcessHead(ctx, head) + require.NoError(t, err) + tx, err = txStore.FindTxWithIdempotencyKey(ctx, idempotencyKey, testutils.FixtureChainID) + require.NoError(t, err) + require.Equal(t, txmgrcommon.TxFinalized, tx.State) + }) + + t.Run("returns error if failed to retrieve latest head in headtracker", func(t *testing.T) { + finalizer := txmgr.NewEvmFinalizer(logger.Test(t), testutils.FixtureChainID, rpcBatchSize, txStore, ethClient, ht) + servicetest.Run(t, finalizer) + + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(nil, errors.New("failed to get latest head")).Once() + err := finalizer.ProcessHead(ctx, head) + require.Error(t, err) + }) + + t.Run("returns error if failed to calculate latest finalized head in headtracker", func(t *testing.T) { + finalizer := txmgr.NewEvmFinalizer(logger.Test(t), testutils.FixtureChainID, rpcBatchSize, txStore, ethClient, ht) + servicetest.Run(t, finalizer) + + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(nil, errors.New("failed to calculate latest finalized head")).Once() + err := finalizer.ProcessHead(ctx, head) + require.Error(t, err) + }) +} + +func insertTxAndAttemptWithIdempotencyKey(t *testing.T, txStore txmgr.TestEvmTxStore, tx *txmgr.Tx, idempotencyKey string) common.Hash { + ctx := tests.Context(t) + err := txStore.InsertTx(ctx, tx) + require.NoError(t, err) + tx, err = txStore.FindTxWithIdempotencyKey(ctx, idempotencyKey, testutils.FixtureChainID) + require.NoError(t, err) + attempt := cltest.NewLegacyEthTxAttempt(t, tx.ID) + err = txStore.InsertTxAttempt(ctx, &attempt) + require.NoError(t, err) + return attempt.Hash +} diff --git a/core/chains/evm/txmgr/mocks/evm_tx_store.go b/core/chains/evm/txmgr/mocks/evm_tx_store.go index b28e55ec32..b40c0ca837 100644 --- a/core/chains/evm/txmgr/mocks/evm_tx_store.go +++ b/core/chains/evm/txmgr/mocks/evm_tx_store.go @@ -18,6 +18,8 @@ import ( time "time" + txmgr "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + types "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" uuid "github.com/google/uuid" @@ -444,6 +446,66 @@ func (_c *EvmTxStore_DeleteInProgressAttempt_Call) RunAndReturn(run func(context return _c } +// FindConfirmedTxesReceipts provides a mock function with given fields: ctx, finalizedBlockNum, chainID +func (_m *EvmTxStore) FindConfirmedTxesReceipts(ctx context.Context, finalizedBlockNum int64, chainID *big.Int) ([]txmgr.DbReceipt, error) { + ret := _m.Called(ctx, finalizedBlockNum, chainID) + + if len(ret) == 0 { + panic("no return value specified for FindConfirmedTxesReceipts") + } + + var r0 []txmgr.DbReceipt + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, int64, *big.Int) ([]txmgr.DbReceipt, error)); ok { + return rf(ctx, finalizedBlockNum, chainID) + } + if rf, ok := ret.Get(0).(func(context.Context, int64, *big.Int) []txmgr.DbReceipt); ok { + r0 = rf(ctx, finalizedBlockNum, chainID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]txmgr.DbReceipt) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int64, *big.Int) error); ok { + r1 = rf(ctx, finalizedBlockNum, chainID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EvmTxStore_FindConfirmedTxesReceipts_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindConfirmedTxesReceipts' +type EvmTxStore_FindConfirmedTxesReceipts_Call struct { + *mock.Call +} + +// FindConfirmedTxesReceipts is a helper method to define mock.On call +// - ctx context.Context +// - finalizedBlockNum int64 +// - chainID *big.Int +func (_e *EvmTxStore_Expecter) FindConfirmedTxesReceipts(ctx interface{}, finalizedBlockNum interface{}, chainID interface{}) *EvmTxStore_FindConfirmedTxesReceipts_Call { + return &EvmTxStore_FindConfirmedTxesReceipts_Call{Call: _e.mock.On("FindConfirmedTxesReceipts", ctx, finalizedBlockNum, chainID)} +} + +func (_c *EvmTxStore_FindConfirmedTxesReceipts_Call) Run(run func(ctx context.Context, finalizedBlockNum int64, chainID *big.Int)) *EvmTxStore_FindConfirmedTxesReceipts_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(int64), args[2].(*big.Int)) + }) + return _c +} + +func (_c *EvmTxStore_FindConfirmedTxesReceipts_Call) Return(receipts []txmgr.DbReceipt, err error) *EvmTxStore_FindConfirmedTxesReceipts_Call { + _c.Call.Return(receipts, err) + return _c +} + +func (_c *EvmTxStore_FindConfirmedTxesReceipts_Call) RunAndReturn(run func(context.Context, int64, *big.Int) ([]txmgr.DbReceipt, error)) *EvmTxStore_FindConfirmedTxesReceipts_Call { + _c.Call.Return(run) + return _c +} + // FindEarliestUnconfirmedBroadcastTime provides a mock function with given fields: ctx, chainID func (_m *EvmTxStore) FindEarliestUnconfirmedBroadcastTime(ctx context.Context, chainID *big.Int) (null.Time, error) { ret := _m.Called(ctx, chainID) @@ -2058,65 +2120,6 @@ func (_c *EvmTxStore_HasInProgressTransaction_Call) RunAndReturn(run func(contex return _c } -// IsTxFinalized provides a mock function with given fields: ctx, blockHeight, txID, chainID -func (_m *EvmTxStore) IsTxFinalized(ctx context.Context, blockHeight int64, txID int64, chainID *big.Int) (bool, error) { - ret := _m.Called(ctx, blockHeight, txID, chainID) - - if len(ret) == 0 { - panic("no return value specified for IsTxFinalized") - } - - var r0 bool - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, int64, int64, *big.Int) (bool, error)); ok { - return rf(ctx, blockHeight, txID, chainID) - } - if rf, ok := ret.Get(0).(func(context.Context, int64, int64, *big.Int) bool); ok { - r0 = rf(ctx, blockHeight, txID, chainID) - } else { - r0 = ret.Get(0).(bool) - } - - if rf, ok := ret.Get(1).(func(context.Context, int64, int64, *big.Int) error); ok { - r1 = rf(ctx, blockHeight, txID, chainID) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// EvmTxStore_IsTxFinalized_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsTxFinalized' -type EvmTxStore_IsTxFinalized_Call struct { - *mock.Call -} - -// IsTxFinalized is a helper method to define mock.On call -// - ctx context.Context -// - blockHeight int64 -// - txID int64 -// - chainID *big.Int -func (_e *EvmTxStore_Expecter) IsTxFinalized(ctx interface{}, blockHeight interface{}, txID interface{}, chainID interface{}) *EvmTxStore_IsTxFinalized_Call { - return &EvmTxStore_IsTxFinalized_Call{Call: _e.mock.On("IsTxFinalized", ctx, blockHeight, txID, chainID)} -} - -func (_c *EvmTxStore_IsTxFinalized_Call) Run(run func(ctx context.Context, blockHeight int64, txID int64, chainID *big.Int)) *EvmTxStore_IsTxFinalized_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(int64), args[2].(int64), args[3].(*big.Int)) - }) - return _c -} - -func (_c *EvmTxStore_IsTxFinalized_Call) Return(finalized bool, err error) *EvmTxStore_IsTxFinalized_Call { - _c.Call.Return(finalized, err) - return _c -} - -func (_c *EvmTxStore_IsTxFinalized_Call) RunAndReturn(run func(context.Context, int64, int64, *big.Int) (bool, error)) *EvmTxStore_IsTxFinalized_Call { - _c.Call.Return(run) - return _c -} - // LoadTxAttempts provides a mock function with given fields: ctx, etx func (_m *EvmTxStore) LoadTxAttempts(ctx context.Context, etx *types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]) error { ret := _m.Called(ctx, etx) @@ -2367,17 +2370,17 @@ func (_c *EvmTxStore_PruneUnstartedTxQueue_Call) RunAndReturn(run func(context.C return _c } -// ReapTxHistory provides a mock function with given fields: ctx, minBlockNumberToKeep, timeThreshold, chainID -func (_m *EvmTxStore) ReapTxHistory(ctx context.Context, minBlockNumberToKeep int64, timeThreshold time.Time, chainID *big.Int) error { - ret := _m.Called(ctx, minBlockNumberToKeep, timeThreshold, chainID) +// ReapTxHistory provides a mock function with given fields: ctx, timeThreshold, chainID +func (_m *EvmTxStore) ReapTxHistory(ctx context.Context, timeThreshold time.Time, chainID *big.Int) error { + ret := _m.Called(ctx, timeThreshold, chainID) if len(ret) == 0 { panic("no return value specified for ReapTxHistory") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, int64, time.Time, *big.Int) error); ok { - r0 = rf(ctx, minBlockNumberToKeep, timeThreshold, chainID) + if rf, ok := ret.Get(0).(func(context.Context, time.Time, *big.Int) error); ok { + r0 = rf(ctx, timeThreshold, chainID) } else { r0 = ret.Error(0) } @@ -2392,16 +2395,15 @@ type EvmTxStore_ReapTxHistory_Call struct { // ReapTxHistory is a helper method to define mock.On call // - ctx context.Context -// - minBlockNumberToKeep int64 // - timeThreshold time.Time // - chainID *big.Int -func (_e *EvmTxStore_Expecter) ReapTxHistory(ctx interface{}, minBlockNumberToKeep interface{}, timeThreshold interface{}, chainID interface{}) *EvmTxStore_ReapTxHistory_Call { - return &EvmTxStore_ReapTxHistory_Call{Call: _e.mock.On("ReapTxHistory", ctx, minBlockNumberToKeep, timeThreshold, chainID)} +func (_e *EvmTxStore_Expecter) ReapTxHistory(ctx interface{}, timeThreshold interface{}, chainID interface{}) *EvmTxStore_ReapTxHistory_Call { + return &EvmTxStore_ReapTxHistory_Call{Call: _e.mock.On("ReapTxHistory", ctx, timeThreshold, chainID)} } -func (_c *EvmTxStore_ReapTxHistory_Call) Run(run func(ctx context.Context, minBlockNumberToKeep int64, timeThreshold time.Time, chainID *big.Int)) *EvmTxStore_ReapTxHistory_Call { +func (_c *EvmTxStore_ReapTxHistory_Call) Run(run func(ctx context.Context, timeThreshold time.Time, chainID *big.Int)) *EvmTxStore_ReapTxHistory_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(int64), args[2].(time.Time), args[3].(*big.Int)) + run(args[0].(context.Context), args[1].(time.Time), args[2].(*big.Int)) }) return _c } @@ -2411,7 +2413,7 @@ func (_c *EvmTxStore_ReapTxHistory_Call) Return(_a0 error) *EvmTxStore_ReapTxHis return _c } -func (_c *EvmTxStore_ReapTxHistory_Call) RunAndReturn(run func(context.Context, int64, time.Time, *big.Int) error) *EvmTxStore_ReapTxHistory_Call { +func (_c *EvmTxStore_ReapTxHistory_Call) RunAndReturn(run func(context.Context, time.Time, *big.Int) error) *EvmTxStore_ReapTxHistory_Call { _c.Call.Return(run) return _c } @@ -3197,6 +3199,54 @@ func (_c *EvmTxStore_UpdateTxForRebroadcast_Call) RunAndReturn(run func(context. return _c } +// UpdateTxStatesToFinalizedUsingReceiptIds provides a mock function with given fields: ctx, etxIDs, chainId +func (_m *EvmTxStore) UpdateTxStatesToFinalizedUsingReceiptIds(ctx context.Context, etxIDs []int64, chainId *big.Int) error { + ret := _m.Called(ctx, etxIDs, chainId) + + if len(ret) == 0 { + panic("no return value specified for UpdateTxStatesToFinalizedUsingReceiptIds") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []int64, *big.Int) error); ok { + r0 = rf(ctx, etxIDs, chainId) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// EvmTxStore_UpdateTxStatesToFinalizedUsingReceiptIds_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateTxStatesToFinalizedUsingReceiptIds' +type EvmTxStore_UpdateTxStatesToFinalizedUsingReceiptIds_Call struct { + *mock.Call +} + +// UpdateTxStatesToFinalizedUsingReceiptIds is a helper method to define mock.On call +// - ctx context.Context +// - etxIDs []int64 +// - chainId *big.Int +func (_e *EvmTxStore_Expecter) UpdateTxStatesToFinalizedUsingReceiptIds(ctx interface{}, etxIDs interface{}, chainId interface{}) *EvmTxStore_UpdateTxStatesToFinalizedUsingReceiptIds_Call { + return &EvmTxStore_UpdateTxStatesToFinalizedUsingReceiptIds_Call{Call: _e.mock.On("UpdateTxStatesToFinalizedUsingReceiptIds", ctx, etxIDs, chainId)} +} + +func (_c *EvmTxStore_UpdateTxStatesToFinalizedUsingReceiptIds_Call) Run(run func(ctx context.Context, etxIDs []int64, chainId *big.Int)) *EvmTxStore_UpdateTxStatesToFinalizedUsingReceiptIds_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]int64), args[2].(*big.Int)) + }) + return _c +} + +func (_c *EvmTxStore_UpdateTxStatesToFinalizedUsingReceiptIds_Call) Return(_a0 error) *EvmTxStore_UpdateTxStatesToFinalizedUsingReceiptIds_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *EvmTxStore_UpdateTxStatesToFinalizedUsingReceiptIds_Call) RunAndReturn(run func(context.Context, []int64, *big.Int) error) *EvmTxStore_UpdateTxStatesToFinalizedUsingReceiptIds_Call { + _c.Call.Return(run) + return _c +} + // UpdateTxUnstartedToInProgress provides a mock function with given fields: ctx, etx, attempt func (_m *EvmTxStore) UpdateTxUnstartedToInProgress(ctx context.Context, etx *types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], attempt *types.TxAttempt[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]) error { ret := _m.Called(ctx, etx, attempt) diff --git a/core/chains/evm/txmgr/models.go b/core/chains/evm/txmgr/models.go index f8682ffd50..1ba3d193cb 100644 --- a/core/chains/evm/txmgr/models.go +++ b/core/chains/evm/txmgr/models.go @@ -36,12 +36,13 @@ type ( Tx = txmgrtypes.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee] TxMeta = txmgrtypes.TxMeta[common.Address, common.Hash] TxAttempt = txmgrtypes.TxAttempt[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee] - Receipt = dbReceipt // EvmReceipt is the exported DB table model for receipts + Receipt = DbReceipt // DbReceipt is the exported DB table model for receipts ReceiptPlus = txmgrtypes.ReceiptPlus[*evmtypes.Receipt] StuckTxDetector = txmgrtypes.StuckTxDetector[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee] TxmClient = txmgrtypes.TxmClient[*big.Int, common.Address, common.Hash, common.Hash, *evmtypes.Receipt, evmtypes.Nonce, gas.EvmFee] TransactionClient = txmgrtypes.TransactionClient[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee] ChainReceipt = txmgrtypes.ChainReceipt[common.Hash, common.Hash] + Finalizer = txmgrtypes.Finalizer[common.Hash, *evmtypes.Head] ) var _ KeyStore = (keystore.Eth)(nil) // check interface in txmgr to avoid circular import diff --git a/core/chains/evm/txmgr/reaper_test.go b/core/chains/evm/txmgr/reaper_test.go index b3ce48b702..cfaccdf04e 100644 --- a/core/chains/evm/txmgr/reaper_test.go +++ b/core/chains/evm/txmgr/reaper_test.go @@ -12,18 +12,17 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils" txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" - txmgrmocks "github.com/smartcontractkit/chainlink/v2/common/txmgr/types/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" ) -func newReaperWithChainID(t *testing.T, db txmgrtypes.TxHistoryReaper[*big.Int], cfg txmgrtypes.ReaperChainConfig, txConfig txmgrtypes.ReaperTransactionsConfig, cid *big.Int) *txmgr.Reaper { - return txmgr.NewEvmReaper(logger.Test(t), db, cfg, txConfig, cid) +func newReaperWithChainID(t *testing.T, db txmgrtypes.TxHistoryReaper[*big.Int], txConfig txmgrtypes.ReaperTransactionsConfig, cid *big.Int) *txmgr.Reaper { + return txmgr.NewEvmReaper(logger.Test(t), db, txConfig, cid) } -func newReaper(t *testing.T, db txmgrtypes.TxHistoryReaper[*big.Int], cfg txmgrtypes.ReaperChainConfig, txConfig txmgrtypes.ReaperTransactionsConfig) *txmgr.Reaper { - return newReaperWithChainID(t, db, cfg, txConfig, &cltest.FixtureChainID) +func newReaper(t *testing.T, db txmgrtypes.TxHistoryReaper[*big.Int], txConfig txmgrtypes.ReaperTransactionsConfig) *txmgr.Reaper { + return newReaperWithChainID(t, db, txConfig, &cltest.FixtureChainID) } type reaperConfig struct { @@ -51,12 +50,9 @@ func TestReaper_ReapTxes(t *testing.T) { oneDayAgo := time.Now().Add(-24 * time.Hour) t.Run("with nothing in the database, doesn't error", func(t *testing.T) { - config := txmgrmocks.NewReaperConfig(t) - config.On("FinalityDepth").Return(uint32(10)) - tc := &reaperConfig{reaperThreshold: 1 * time.Hour} - r := newReaper(t, txStore, config, tc) + r := newReaper(t, txStore, tc) err := r.ReapTxes(42) assert.NoError(t, err) @@ -66,11 +62,9 @@ func TestReaper_ReapTxes(t *testing.T) { mustInsertConfirmedEthTxWithReceipt(t, txStore, from, nonce, 5) t.Run("skips if threshold=0", func(t *testing.T) { - config := txmgrmocks.NewReaperConfig(t) - tc := &reaperConfig{reaperThreshold: 0 * time.Second} - r := newReaper(t, txStore, config, tc) + r := newReaper(t, txStore, tc) err := r.ReapTxes(42) assert.NoError(t, err) @@ -79,12 +73,9 @@ func TestReaper_ReapTxes(t *testing.T) { }) t.Run("doesn't touch ethtxes with different chain ID", func(t *testing.T) { - config := txmgrmocks.NewReaperConfig(t) - config.On("FinalityDepth").Return(uint32(10)) - tc := &reaperConfig{reaperThreshold: 1 * time.Hour} - r := newReaperWithChainID(t, txStore, config, tc, big.NewInt(42)) + r := newReaperWithChainID(t, txStore, tc, big.NewInt(42)) err := r.ReapTxes(42) assert.NoError(t, err) @@ -92,41 +83,30 @@ func TestReaper_ReapTxes(t *testing.T) { cltest.AssertCount(t, db, "evm.txes", 1) }) - t.Run("deletes confirmed evm.txes that exceed the age threshold with at least EVM.FinalityDepth blocks above their receipt", func(t *testing.T) { - config := txmgrmocks.NewReaperConfig(t) - config.On("FinalityDepth").Return(uint32(10)) - + t.Run("deletes finalized evm.txes that exceed the age threshold", func(t *testing.T) { tc := &reaperConfig{reaperThreshold: 1 * time.Hour} - r := newReaper(t, txStore, config, tc) + r := newReaper(t, txStore, tc) err := r.ReapTxes(42) assert.NoError(t, err) // Didn't delete because eth_tx was not old enough cltest.AssertCount(t, db, "evm.txes", 1) - pgtest.MustExec(t, db, `UPDATE evm.txes SET created_at=$1`, oneDayAgo) - - err = r.ReapTxes(12) - assert.NoError(t, err) - // Didn't delete because eth_tx although old enough, was still within EVM.FinalityDepth of the current head - cltest.AssertCount(t, db, "evm.txes", 1) + pgtest.MustExec(t, db, `UPDATE evm.txes SET created_at=$1, state='finalized'`, oneDayAgo) err = r.ReapTxes(42) assert.NoError(t, err) - // Now it deleted because the eth_tx was past EVM.FinalityDepth + // Now it deleted because the eth_tx was past the age threshold cltest.AssertCount(t, db, "evm.txes", 0) }) mustInsertFatalErrorEthTx(t, txStore, from) t.Run("deletes errored evm.txes that exceed the age threshold", func(t *testing.T) { - config := txmgrmocks.NewReaperConfig(t) - config.On("FinalityDepth").Return(uint32(10)) - tc := &reaperConfig{reaperThreshold: 1 * time.Hour} - r := newReaper(t, txStore, config, tc) + r := newReaper(t, txStore, tc) err := r.ReapTxes(42) assert.NoError(t, err) @@ -140,4 +120,24 @@ func TestReaper_ReapTxes(t *testing.T) { // Deleted because it is old enough now cltest.AssertCount(t, db, "evm.txes", 0) }) + + mustInsertConfirmedEthTxWithReceipt(t, txStore, from, 0, 42) + + t.Run("deletes confirmed evm.txes that exceed the age threshold", func(t *testing.T) { + tc := &reaperConfig{reaperThreshold: 1 * time.Hour} + + r := newReaper(t, txStore, tc) + + err := r.ReapTxes(42) + assert.NoError(t, err) + // Didn't delete because eth_tx was not old enough + cltest.AssertCount(t, db, "evm.txes", 1) + + pgtest.MustExec(t, db, `UPDATE evm.txes SET created_at=$1`, oneDayAgo) + + err = r.ReapTxes(42) + assert.NoError(t, err) + // Now it deleted because the eth_tx was past the age threshold + cltest.AssertCount(t, db, "evm.txes", 0) + }) } diff --git a/core/chains/evm/txmgr/test_helpers.go b/core/chains/evm/txmgr/test_helpers.go index 3b3584a988..8d20874432 100644 --- a/core/chains/evm/txmgr/test_helpers.go +++ b/core/chains/evm/txmgr/test_helpers.go @@ -53,6 +53,7 @@ type TestEvmConfig struct { Threshold uint32 MinAttempts uint32 DetectionApiUrl *url.URL + RpcDefaultBatchSize uint32 } func (e *TestEvmConfig) Transactions() evmconfig.Transactions { @@ -65,6 +66,8 @@ func (e *TestEvmConfig) FinalityDepth() uint32 { return 42 } func (e *TestEvmConfig) ChainType() chaintype.ChainType { return "" } +func (e *TestEvmConfig) RPCDefaultBatchSize() uint32 { return e.RpcDefaultBatchSize } + type TestGasEstimatorConfig struct { bumpThreshold uint64 } @@ -141,10 +144,9 @@ type autoPurgeConfig struct { func (a *autoPurgeConfig) Enabled() bool { return false } type MockConfig struct { - EvmConfig *TestEvmConfig - RpcDefaultBatchSize uint32 - finalityDepth uint32 - finalityTagEnabled bool + EvmConfig *TestEvmConfig + finalityDepth uint32 + finalityTagEnabled bool } func (c *MockConfig) EVM() evmconfig.EVM { @@ -156,11 +158,10 @@ func (c *MockConfig) ChainType() chaintype.ChainType { return "" } func (c *MockConfig) FinalityDepth() uint32 { return c.finalityDepth } func (c *MockConfig) SetFinalityDepth(fd uint32) { c.finalityDepth = fd } func (c *MockConfig) FinalityTagEnabled() bool { return c.finalityTagEnabled } -func (c *MockConfig) RPCDefaultBatchSize() uint32 { return c.RpcDefaultBatchSize } func MakeTestConfigs(t *testing.T) (*MockConfig, *TestDatabaseConfig, *TestEvmConfig) { db := &TestDatabaseConfig{defaultQueryTimeout: utils.DefaultQueryTimeout} - ec := &TestEvmConfig{BumpThreshold: 42, MaxInFlight: uint32(42), MaxQueued: uint64(0), ReaperInterval: time.Duration(0), ReaperThreshold: time.Duration(0)} + ec := &TestEvmConfig{BumpThreshold: 42, MaxInFlight: uint32(42), MaxQueued: uint64(0), ReaperInterval: time.Duration(0), ReaperThreshold: time.Duration(0), RpcDefaultBatchSize: uint32(250)} config := &MockConfig{EvmConfig: ec} return config, db, ec } diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index 40df5616c9..5f932db872 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -85,7 +85,8 @@ func makeTestEvmTxm( lggr, lp, keyStore, - estimator) + estimator, + ht) } func TestTxm_SendNativeToken_DoesNotSendToZero(t *testing.T) { @@ -489,14 +490,20 @@ func TestTxm_Lifecycle(t *testing.T) { config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) config.SetFinalityDepth(uint32(42)) - config.RpcDefaultBatchSize = uint32(4) + evmConfig.RpcDefaultBatchSize = uint32(4) evmConfig.ResendAfterThreshold = 1 * time.Hour evmConfig.ReaperThreshold = 1 * time.Hour evmConfig.ReaperInterval = 1 * time.Hour kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return([]common.Address{}, nil) + head := cltest.Head(42) + finalizedHead := cltest.Head(0) + + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(finalizedHead, nil).Once() + keyChangeCh := make(chan struct{}) unsub := cltest.NewAwaiter() kst.On("SubscribeToKeyChanges", mock.Anything).Return(keyChangeCh, unsub.ItHappened) @@ -505,7 +512,6 @@ func TestTxm_Lifecycle(t *testing.T) { txm, err := makeTestEvmTxm(t, db, ethClient, estimator, evmConfig, evmConfig.GasEstimator(), evmConfig.Transactions(), dbConfig, dbConfig.Listener(), kst) require.NoError(t, err) - head := cltest.Head(42) // It should not hang or panic txm.OnNewLongestChain(tests.Context(t), head) @@ -607,8 +613,20 @@ func TestTxm_GetTransactionStatus(t *testing.T) { gcfg := configtest.NewTestGeneralConfig(t) cfg := evmtest.NewChainScopedConfig(t, gcfg) + head := &evmtypes.Head{ + Hash: utils.NewHash(), + Number: 100, + Parent: &evmtypes.Head{ + Hash: utils.NewHash(), + Number: 99, + IsFinalized: true, + }, + } + ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("PendingNonceAt", mock.Anything, mock.Anything).Return(uint64(0), nil).Maybe() + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head.Parent, nil).Once() feeEstimator := gasmocks.NewEvmFeeEstimator(t) feeEstimator.On("Start", mock.Anything).Return(nil).Once() feeEstimator.On("Close", mock.Anything).Return(nil).Once() @@ -617,15 +635,6 @@ func TestTxm_GetTransactionStatus(t *testing.T) { require.NoError(t, err) servicetest.Run(t, txm) - head := &evmtypes.Head{ - Hash: utils.NewHash(), - Number: 100, - Parent: &evmtypes.Head{ - Hash: utils.NewHash(), - Number: 99, - IsFinalized: true, - }, - } txm.OnNewLongestChain(ctx, head) t.Run("returns error if transaction not found", func(t *testing.T) { @@ -715,13 +724,42 @@ func TestTxm_GetTransactionStatus(t *testing.T) { attempt := cltest.NewLegacyEthTxAttempt(t, tx.ID) err = txStore.InsertTxAttempt(ctx, &attempt) require.NoError(t, err) - // Insert receipt for finalized block num - mustInsertEthReceipt(t, txStore, head.Parent.Number, head.ParentHash, attempt.Hash) + // Insert receipt for unfinalized block num + mustInsertEthReceipt(t, txStore, head.Number, head.Hash, attempt.Hash) state, err := txm.GetTransactionStatus(ctx, idempotencyKey) require.NoError(t, err) require.Equal(t, commontypes.Unconfirmed, state) }) + t.Run("returns finalized for finalized state", func(t *testing.T) { + idempotencyKey := uuid.New().String() + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + nonce := evmtypes.Nonce(0) + broadcast := time.Now() + tx := &txmgr.Tx{ + Sequence: &nonce, + IdempotencyKey: &idempotencyKey, + FromAddress: fromAddress, + EncodedPayload: []byte{1, 2, 3}, + FeeLimit: feeLimit, + State: txmgrcommon.TxFinalized, + BroadcastAt: &broadcast, + InitialBroadcastAt: &broadcast, + } + err := txStore.InsertTx(ctx, tx) + require.NoError(t, err) + tx, err = txStore.FindTxWithIdempotencyKey(ctx, idempotencyKey, testutils.FixtureChainID) + require.NoError(t, err) + attempt := cltest.NewLegacyEthTxAttempt(t, tx.ID) + err = txStore.InsertTxAttempt(ctx, &attempt) + require.NoError(t, err) + // Insert receipt for finalized block num + mustInsertEthReceipt(t, txStore, head.Parent.Number, head.Parent.Hash, attempt.Hash) + state, err := txm.GetTransactionStatus(ctx, idempotencyKey) + require.NoError(t, err) + require.Equal(t, commontypes.Finalized, state) + }) + t.Run("returns unconfirmed for confirmed missing receipt state", func(t *testing.T) { idempotencyKey := uuid.New().String() _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) @@ -1018,6 +1056,12 @@ func mustCreateUnstartedTxFromEvmTxRequest(t testing.TB, txStore txmgr.EvmTxStor return tx } +func mustInsertUnstartedTx(t testing.TB, txStore txmgr.TestEvmTxStore, fromAddress common.Address) { + etx := cltest.NewEthTx(fromAddress) + ctx := tests.Context(t) + require.NoError(t, txStore.InsertTx(ctx, &etx)) +} + func txRequestWithStrategy(strategy txmgrtypes.TxStrategy) func(*txmgr.TxRequest) { return func(tx *txmgr.TxRequest) { tx.Strategy = strategy diff --git a/core/chains/legacyevm/chain.go b/core/chains/legacyevm/chain.go index 129c031882..68ff8d4e11 100644 --- a/core/chains/legacyevm/chain.go +++ b/core/chains/legacyevm/chain.go @@ -247,7 +247,7 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod } // note: gas estimator is started as a part of the txm - txm, gasEstimator, err := newEvmTxm(opts.DS, cfg.EVM(), opts.AppConfig.EVMRPCEnabled(), opts.AppConfig.Database(), opts.AppConfig.Database().Listener(), client, l, logPoller, opts) + txm, gasEstimator, err := newEvmTxm(opts.DS, cfg.EVM(), opts.AppConfig.EVMRPCEnabled(), opts.AppConfig.Database(), opts.AppConfig.Database().Listener(), client, l, logPoller, opts, headTracker) if err != nil { return nil, fmt.Errorf("failed to instantiate EvmTxm for chain with ID %s: %w", chainID.String(), err) } diff --git a/core/chains/legacyevm/evm_txm.go b/core/chains/legacyevm/evm_txm.go index cecfd4ffaf..ab11674966 100644 --- a/core/chains/legacyevm/evm_txm.go +++ b/core/chains/legacyevm/evm_txm.go @@ -7,6 +7,7 @@ import ( evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -22,6 +23,7 @@ func newEvmTxm( lggr logger.Logger, logPoller logpoller.LogPoller, opts ChainRelayExtenderConfig, + headTracker httypes.HeadTracker, ) (txm txmgr.TxManager, estimator gas.EvmFeeEstimator, err error, @@ -63,7 +65,8 @@ func newEvmTxm( lggr, logPoller, opts.KeyStore, - estimator) + estimator, + headTracker) } else { txm = opts.GenTxManager(chainID) } diff --git a/core/services/promreporter/prom_reporter_test.go b/core/services/promreporter/prom_reporter_test.go index b61fa25bdc..a0a4a247c2 100644 --- a/core/services/promreporter/prom_reporter_test.go +++ b/core/services/promreporter/prom_reporter_test.go @@ -62,7 +62,8 @@ func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainCon lggr, lp, keyStore, - estimator) + estimator, + ht) require.NoError(t, err) cfg := configtest.NewGeneralConfig(t, nil) diff --git a/core/services/vrf/delegate_test.go b/core/services/vrf/delegate_test.go index 889b19d0e0..9718dc376a 100644 --- a/core/services/vrf/delegate_test.go +++ b/core/services/vrf/delegate_test.go @@ -83,7 +83,7 @@ func buildVrfUni(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralConfig) vrfUniv btORM := bridges.NewORM(db) ks := keystore.NewInMemory(db, utils.FastScryptParams, lggr) _, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) - txm, err := txmgr.NewTxm(db, evmConfig, evmConfig.GasEstimator(), evmConfig.Transactions(), nil, dbConfig, dbConfig.Listener(), ec, logger.TestLogger(t), nil, ks.Eth(), nil) + txm, err := txmgr.NewTxm(db, evmConfig, evmConfig.GasEstimator(), evmConfig.Transactions(), nil, dbConfig, dbConfig.Listener(), ec, logger.TestLogger(t), nil, ks.Eth(), nil, nil) orm := headtracker.NewORM(*testutils.FixtureChainID, db) require.NoError(t, orm.IdempotentInsertHead(testutils.Context(t), cltest.Head(51))) jrm := job.NewORM(db, prm, btORM, ks, lggr) diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index e9ae908565..178b555667 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -142,7 +142,7 @@ func makeTestTxm(t *testing.T, txStore txmgr.TestEvmTxStore, keyStore keystore.M _, _, evmConfig := txmgr.MakeTestConfigs(t) txmConfig := txmgr.NewEvmTxmConfig(evmConfig) txm := txmgr.NewEvmTxm(ec.ConfiguredChainID(), txmConfig, evmConfig.Transactions(), keyStore.Eth(), logger.TestLogger(t), nil, nil, - nil, txStore, nil, nil, nil, nil) + nil, txStore, nil, nil, nil, nil, nil) return txm } diff --git a/core/services/vrf/v2/listener_v2_test.go b/core/services/vrf/v2/listener_v2_test.go index ac59f1fdb6..b7a8710c4f 100644 --- a/core/services/vrf/v2/listener_v2_test.go +++ b/core/services/vrf/v2/listener_v2_test.go @@ -40,7 +40,7 @@ func makeTestTxm(t *testing.T, txStore txmgr.TestEvmTxStore, keyStore keystore.M ec := evmtest.NewEthClientMockWithDefaultChain(t) txmConfig := txmgr.NewEvmTxmConfig(evmConfig) txm := txmgr.NewEvmTxm(ec.ConfiguredChainID(), txmConfig, evmConfig.Transactions(), keyStore.Eth(), logger.TestLogger(t), nil, nil, - nil, txStore, nil, nil, nil, nil) + nil, txStore, nil, nil, nil, nil, nil) return txm } diff --git a/core/store/migrate/migrate_test.go b/core/store/migrate/migrate_test.go index 9a8bf96573..f4e91f0a2d 100644 --- a/core/store/migrate/migrate_test.go +++ b/core/store/migrate/migrate_test.go @@ -618,3 +618,14 @@ func BenchmarkBackfillingRecordsWithMigration202(b *testing.B) { require.NoError(b, err) } } + +func TestRollback_247_TxStateEnumUpdate(t *testing.T) { + ctx := testutils.Context(t) + _, db := heavyweight.FullTestDBV2(t, nil) + p, err := migrate.NewProvider(ctx, db.DB) + require.NoError(t, err) + _, err = p.DownTo(ctx, 54) + require.NoError(t, err) + _, err = p.UpTo(ctx, 247) + require.NoError(t, err) +} diff --git a/core/store/migrate/migrations/0248_add_tx_finalized_state.sql b/core/store/migrate/migrations/0248_add_tx_finalized_state.sql new file mode 100644 index 0000000000..dcfe8eec73 --- /dev/null +++ b/core/store/migrate/migrations/0248_add_tx_finalized_state.sql @@ -0,0 +1,135 @@ +-- +goose Up +-- Creating new column and enum instead of just adding new value to the existing enum so the migration changes match the rollback logic +-- Otherwise, migration will complain about mismatching column order + +-- +goose StatementBegin +-- Rename the existing enum with finalized state to mark it as old +ALTER TYPE evm.txes_state RENAME TO txes_state_old; + +-- Create new enum without finalized state +CREATE TYPE evm.txes_state AS ENUM ( + 'unstarted', + 'in_progress', + 'fatal_error', + 'unconfirmed', + 'confirmed_missing_receipt', + 'confirmed', + 'finalized' +); + +-- Add a new state column with the new enum type to the txes table +ALTER TABLE evm.txes ADD COLUMN state_new evm.txes_state; + +-- Copy data from the old column to the new +UPDATE evm.txes SET state_new = state::text::evm.txes_state; + +-- Drop constraints referring to old enum type on the old state column +ALTER TABLE evm.txes ALTER COLUMN state DROP DEFAULT; +ALTER TABLE evm.txes DROP CONSTRAINT chk_eth_txes_fsm; +DROP INDEX IF EXISTS idx_eth_txes_state_from_address_evm_chain_id; +DROP INDEX IF EXISTS idx_eth_txes_min_unconfirmed_nonce_for_key_evm_chain_id; +DROP INDEX IF EXISTS idx_only_one_in_progress_tx_per_account_id_per_evm_chain_id; +DROP INDEX IF EXISTS idx_eth_txes_unstarted_subject_id_evm_chain_id; + +-- Drop the old state column +ALTER TABLE evm.txes DROP state; + +-- Drop the old enum type +DROP TYPE evm.txes_state_old; + +-- Rename the new column name state to replace the old column +ALTER TABLE evm.txes RENAME state_new TO state; + +-- Reset the state column's default +ALTER TABLE evm.txes ALTER COLUMN state SET DEFAULT 'unstarted'::evm.txes_state, ALTER COLUMN state SET NOT NULL; + +-- Recreate constraint with finalized state +ALTER TABLE evm.txes ADD CONSTRAINT chk_eth_txes_fsm CHECK ( + state = 'unstarted'::evm.txes_state AND nonce IS NULL AND error IS NULL AND broadcast_at IS NULL AND initial_broadcast_at IS NULL + OR + state = 'in_progress'::evm.txes_state AND nonce IS NOT NULL AND error IS NULL AND broadcast_at IS NULL AND initial_broadcast_at IS NULL + OR + state = 'fatal_error'::evm.txes_state AND error IS NOT NULL + OR + state = 'unconfirmed'::evm.txes_state AND nonce IS NOT NULL AND error IS NULL AND broadcast_at IS NOT NULL AND initial_broadcast_at IS NOT NULL + OR + state = 'confirmed'::evm.txes_state AND nonce IS NOT NULL AND error IS NULL AND broadcast_at IS NOT NULL AND initial_broadcast_at IS NOT NULL + OR + state = 'confirmed_missing_receipt'::evm.txes_state AND nonce IS NOT NULL AND error IS NULL AND broadcast_at IS NOT NULL AND initial_broadcast_at IS NOT NULL + OR + state = 'finalized'::evm.txes_state AND nonce IS NOT NULL AND error IS NULL AND broadcast_at IS NOT NULL AND initial_broadcast_at IS NOT NULL +) NOT VALID; + +-- Recreate index to include finalized state +CREATE INDEX idx_eth_txes_state_from_address_evm_chain_id ON evm.txes(evm_chain_id, from_address, state) WHERE state <> 'confirmed'::evm.txes_state AND state <> 'finalized'::evm.txes_state; +CREATE INDEX idx_eth_txes_min_unconfirmed_nonce_for_key_evm_chain_id ON evm.txes(evm_chain_id, from_address, nonce) WHERE state = 'unconfirmed'::evm.txes_state; +CREATE UNIQUE INDEX idx_only_one_in_progress_tx_per_account_id_per_evm_chain_id ON evm.txes(evm_chain_id, from_address) WHERE state = 'in_progress'::evm.txes_state; +CREATE INDEX idx_eth_txes_unstarted_subject_id_evm_chain_id ON evm.txes(evm_chain_id, subject, id) WHERE subject IS NOT NULL AND state = 'unstarted'::evm.txes_state; +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin + +-- Rename the existing enum with finalized state to mark it as old +ALTER TYPE evm.txes_state RENAME TO txes_state_old; + +-- Create new enum without finalized state +CREATE TYPE evm.txes_state AS ENUM ( + 'unstarted', + 'in_progress', + 'fatal_error', + 'unconfirmed', + 'confirmed_missing_receipt', + 'confirmed' +); + +-- Add a new state column with the new enum type to the txes table +ALTER TABLE evm.txes ADD COLUMN state_new evm.txes_state; + +-- Update all transactions with finalized state to confirmed in the old state column +UPDATE evm.txes SET state = 'confirmed'::evm.txes_state_old WHERE state = 'finalized'::evm.txes_state_old; + +-- Copy data from the old column to the new +UPDATE evm.txes SET state_new = state::text::evm.txes_state; + +-- Drop constraints referring to old enum type on the old state column +ALTER TABLE evm.txes ALTER COLUMN state DROP DEFAULT; +ALTER TABLE evm.txes DROP CONSTRAINT chk_eth_txes_fsm; +DROP INDEX IF EXISTS idx_eth_txes_state_from_address_evm_chain_id; +DROP INDEX IF EXISTS idx_eth_txes_min_unconfirmed_nonce_for_key_evm_chain_id; +DROP INDEX IF EXISTS idx_only_one_in_progress_tx_per_account_id_per_evm_chain_id; +DROP INDEX IF EXISTS idx_eth_txes_unstarted_subject_id_evm_chain_id; + +-- Drop the old state column +ALTER TABLE evm.txes DROP state; + +-- Drop the old enum type +DROP TYPE evm.txes_state_old; + +-- Rename the new column name state to replace the old column +ALTER TABLE evm.txes RENAME state_new TO state; + +-- Reset the state column's default +ALTER TABLE evm.txes ALTER COLUMN state SET DEFAULT 'unstarted'::evm.txes_state, ALTER COLUMN state SET NOT NULL; + +-- Recereate constraint without finalized state +ALTER TABLE evm.txes ADD CONSTRAINT chk_eth_txes_fsm CHECK ( + state = 'unstarted'::evm.txes_state AND nonce IS NULL AND error IS NULL AND broadcast_at IS NULL AND initial_broadcast_at IS NULL + OR + state = 'in_progress'::evm.txes_state AND nonce IS NOT NULL AND error IS NULL AND broadcast_at IS NULL AND initial_broadcast_at IS NULL + OR + state = 'fatal_error'::evm.txes_state AND error IS NOT NULL + OR + state = 'unconfirmed'::evm.txes_state AND nonce IS NOT NULL AND error IS NULL AND broadcast_at IS NOT NULL AND initial_broadcast_at IS NOT NULL + OR + state = 'confirmed'::evm.txes_state AND nonce IS NOT NULL AND error IS NULL AND broadcast_at IS NOT NULL AND initial_broadcast_at IS NOT NULL + OR + state = 'confirmed_missing_receipt'::evm.txes_state AND nonce IS NOT NULL AND error IS NULL AND broadcast_at IS NOT NULL AND initial_broadcast_at IS NOT NULL +) NOT VALID; + +-- Recreate index with new enum type +CREATE INDEX idx_eth_txes_state_from_address_evm_chain_id ON evm.txes(evm_chain_id, from_address, state) WHERE state <> 'confirmed'::evm.txes_state; +CREATE INDEX idx_eth_txes_min_unconfirmed_nonce_for_key_evm_chain_id ON evm.txes(evm_chain_id, from_address, nonce) WHERE state = 'unconfirmed'::evm.txes_state; +CREATE UNIQUE INDEX idx_only_one_in_progress_tx_per_account_id_per_evm_chain_id ON evm.txes(evm_chain_id, from_address) WHERE state = 'in_progress'::evm.txes_state; +CREATE INDEX idx_eth_txes_unstarted_subject_id_evm_chain_id ON evm.txes(evm_chain_id, subject, id) WHERE subject IS NOT NULL AND state = 'unstarted'::evm.txes_state; +-- +goose StatementEnd diff --git a/core/web/testdata/body/health.html b/core/web/testdata/body/health.html index 2a1b222753..90d301bc8b 100644 --- a/core/web/testdata/body/health.html +++ b/core/web/testdata/body/health.html @@ -63,6 +63,9 @@

    Confirmer
    +
    + Finalizer +
    WrappedEvmEstimator
    diff --git a/core/web/testdata/body/health.json b/core/web/testdata/body/health.json index 10415c0abd..839428a510 100644 --- a/core/web/testdata/body/health.json +++ b/core/web/testdata/body/health.json @@ -90,6 +90,15 @@ "output": "" } }, + { + "type": "checks", + "id": "EVM.0.Txm.Finalizer", + "attributes": { + "name": "EVM.0.Txm.Finalizer", + "status": "passing", + "output": "" + } + }, { "type": "checks", "id": "EVM.0.Txm.WrappedEvmEstimator", diff --git a/core/web/testdata/body/health.txt b/core/web/testdata/body/health.txt index 09c8cff6c2..3709b4e15f 100644 --- a/core/web/testdata/body/health.txt +++ b/core/web/testdata/body/health.txt @@ -9,6 +9,7 @@ ok EVM.0.Txm ok EVM.0.Txm.BlockHistoryEstimator ok EVM.0.Txm.Broadcaster ok EVM.0.Txm.Confirmer +ok EVM.0.Txm.Finalizer ok EVM.0.Txm.WrappedEvmEstimator ok JobSpawner ok Mailbox.Monitor diff --git a/testdata/scripts/health/multi-chain.txtar b/testdata/scripts/health/multi-chain.txtar index 7e01493b30..76937329cb 100644 --- a/testdata/scripts/health/multi-chain.txtar +++ b/testdata/scripts/health/multi-chain.txtar @@ -82,6 +82,7 @@ ok EVM.1.Txm ok EVM.1.Txm.BlockHistoryEstimator ok EVM.1.Txm.Broadcaster ok EVM.1.Txm.Confirmer +ok EVM.1.Txm.Finalizer ok EVM.1.Txm.WrappedEvmEstimator ok JobSpawner ok Mailbox.Monitor @@ -219,6 +220,15 @@ ok TelemetryManager "output": "" } }, + { + "type": "checks", + "id": "EVM.1.Txm.Finalizer", + "attributes": { + "name": "EVM.1.Txm.Finalizer", + "status": "passing", + "output": "" + } + }, { "type": "checks", "id": "EVM.1.Txm.WrappedEvmEstimator", From 69f7bd68199b91c4ef4be65b5701e4d45a250350 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 6 Aug 2024 23:55:49 +0200 Subject: [PATCH 046/432] use services.Config.NewService/Engine (#13851) * use services.Config.NewService/Engine * feedback --- common/headtracker/head_broadcaster.go | 70 +++---- common/headtracker/head_listener.go | 73 ++++--- common/headtracker/head_tracker.go | 105 ++++------ core/bridges/cache.go | 76 ++----- core/chains/evm/headtracker/head_listener.go | 28 --- .../evm/headtracker/head_listener_test.go | 188 ++++++++--------- core/chains/evm/headtracker/head_tracker.go | 4 +- core/chains/evm/monitor/balance.go | 76 +++---- core/recovery/recover.go | 42 ++-- core/services/chainlink/application.go | 13 +- .../fluxmonitorv2/deviation_checker.go | 4 +- core/services/fluxmonitorv2/flux_monitor.go | 95 ++++----- .../fluxmonitorv2/flux_monitor_test.go | 16 +- core/services/fluxmonitorv2/helpers_test.go | 12 +- core/services/fluxmonitorv2/poll_manager.go | 10 +- core/services/nurse.go | 192 ++++++++---------- core/services/nurse_test.go | 3 +- .../relay/evm/functions/logpoller_wrapper.go | 116 +++++------ core/services/synchronization/helpers_test.go | 6 +- .../telemetry_ingress_batch_client.go | 133 ++++++------ .../telemetry_ingress_batch_worker.go | 64 ++---- .../telemetry_ingress_batch_worker_test.go | 4 - .../telemetry_ingress_client.go | 90 +++----- core/services/telemetry/manager.go | 92 ++++----- core/services/telemetry/manager_test.go | 2 +- 25 files changed, 608 insertions(+), 906 deletions(-) delete mode 100644 core/chains/evm/headtracker/head_listener.go diff --git a/common/headtracker/head_broadcaster.go b/common/headtracker/head_broadcaster.go index 7edcccfccb..c81c61141f 100644 --- a/common/headtracker/head_broadcaster.go +++ b/common/headtracker/head_broadcaster.go @@ -42,13 +42,12 @@ type HeadBroadcaster[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] interf } type headBroadcaster[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] struct { - services.StateMachine - logger logger.Logger + services.Service + eng *services.Engine + callbacks callbackSet[H, BLOCK_HASH] mailbox *mailbox.Mailbox[H] mutex sync.Mutex - chClose services.StopChan - wgDone sync.WaitGroup latest H lastCallbackID int } @@ -60,41 +59,29 @@ func NewHeadBroadcaster[ ]( lggr logger.Logger, ) HeadBroadcaster[H, BLOCK_HASH] { - return &headBroadcaster[H, BLOCK_HASH]{ - logger: logger.Named(lggr, "HeadBroadcaster"), + hb := &headBroadcaster[H, BLOCK_HASH]{ callbacks: make(callbackSet[H, BLOCK_HASH]), mailbox: mailbox.NewSingle[H](), - chClose: make(chan struct{}), } + hb.Service, hb.eng = services.Config{ + Name: "HeadBroadcaster", + Start: hb.start, + Close: hb.close, + }.NewServiceEngine(lggr) + return hb } -func (hb *headBroadcaster[H, BLOCK_HASH]) Start(context.Context) error { - return hb.StartOnce("HeadBroadcaster", func() error { - hb.wgDone.Add(1) - go hb.run() - return nil - }) -} - -func (hb *headBroadcaster[H, BLOCK_HASH]) Close() error { - return hb.StopOnce("HeadBroadcaster", func() error { - hb.mutex.Lock() - // clear all callbacks - hb.callbacks = make(callbackSet[H, BLOCK_HASH]) - hb.mutex.Unlock() - - close(hb.chClose) - hb.wgDone.Wait() - return nil - }) +func (hb *headBroadcaster[H, BLOCK_HASH]) start(context.Context) error { + hb.eng.Go(hb.run) + return nil } -func (hb *headBroadcaster[H, BLOCK_HASH]) Name() string { - return hb.logger.Name() -} - -func (hb *headBroadcaster[H, BLOCK_HASH]) HealthReport() map[string]error { - return map[string]error{hb.Name(): hb.Healthy()} +func (hb *headBroadcaster[H, BLOCK_HASH]) close() error { + hb.mutex.Lock() + // clear all callbacks + hb.callbacks = make(callbackSet[H, BLOCK_HASH]) + hb.mutex.Unlock() + return nil } func (hb *headBroadcaster[H, BLOCK_HASH]) BroadcastNewLongestChain(head H) { @@ -121,15 +108,13 @@ func (hb *headBroadcaster[H, BLOCK_HASH]) Subscribe(callback HeadTrackable[H, BL return } -func (hb *headBroadcaster[H, BLOCK_HASH]) run() { - defer hb.wgDone.Done() - +func (hb *headBroadcaster[H, BLOCK_HASH]) run(ctx context.Context) { for { select { - case <-hb.chClose: + case <-ctx.Done(): return case <-hb.mailbox.Notify(): - hb.executeCallbacks() + hb.executeCallbacks(ctx) } } } @@ -137,10 +122,10 @@ func (hb *headBroadcaster[H, BLOCK_HASH]) run() { // DEV: the head relayer makes no promises about head delivery! Subscribing // Jobs should expect to the relayer to skip heads if there is a large number of listeners // and all callbacks cannot be completed in the allotted time. -func (hb *headBroadcaster[H, BLOCK_HASH]) executeCallbacks() { +func (hb *headBroadcaster[H, BLOCK_HASH]) executeCallbacks(ctx context.Context) { head, exists := hb.mailbox.Retrieve() if !exists { - hb.logger.Info("No head to retrieve. It might have been skipped") + hb.eng.Info("No head to retrieve. It might have been skipped") return } @@ -149,7 +134,7 @@ func (hb *headBroadcaster[H, BLOCK_HASH]) executeCallbacks() { hb.latest = head hb.mutex.Unlock() - hb.logger.Debugw("Initiating callbacks", + hb.eng.Debugw("Initiating callbacks", "headNum", head.BlockNumber(), "numCallbacks", len(callbacks), ) @@ -157,9 +142,6 @@ func (hb *headBroadcaster[H, BLOCK_HASH]) executeCallbacks() { wg := sync.WaitGroup{} wg.Add(len(callbacks)) - ctx, cancel := hb.chClose.NewCtx() - defer cancel() - for _, callback := range callbacks { go func(trackable HeadTrackable[H, BLOCK_HASH]) { defer wg.Done() @@ -168,7 +150,7 @@ func (hb *headBroadcaster[H, BLOCK_HASH]) executeCallbacks() { defer cancel() trackable.OnNewLongestChain(cctx, head) elapsed := time.Since(start) - hb.logger.Debugw(fmt.Sprintf("Finished callback in %s", elapsed), + hb.eng.Debugw(fmt.Sprintf("Finished callback in %s", elapsed), "callbackType", reflect.TypeOf(trackable), "blockNumber", head.BlockNumber(), "time", elapsed) }(callback) } diff --git a/common/headtracker/head_listener.go b/common/headtracker/head_listener.go index 25715b3528..d240caab3c 100644 --- a/common/headtracker/head_listener.go +++ b/common/headtracker/head_listener.go @@ -29,14 +29,15 @@ var ( }, []string{"ChainID"}) ) -// headHandler is a callback that handles incoming heads -type headHandler[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] func(ctx context.Context, header H) error +// HeadHandler is a callback that handles incoming heads +type HeadHandler[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] func(ctx context.Context, header H) error // HeadListener is a chain agnostic interface that manages connection of Client that receives heads from the blockchain node type HeadListener[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] interface { - // ListenForNewHeads kicks off the listen loop (not thread safe) - // done() must be executed upon leaving ListenForNewHeads() - ListenForNewHeads(onSubscribe func(), handleNewHead headHandler[H, BLOCK_HASH], done func()) + services.Service + + // ListenForNewHeads runs the listen loop (not thread safe) + ListenForNewHeads(ctx context.Context) // ReceivingHeads returns true if the listener is receiving heads (thread safe) ReceivingHeads() bool @@ -54,10 +55,13 @@ type headListener[ ID types.ID, BLOCK_HASH types.Hashable, ] struct { + services.Service + eng *services.Engine + config htrktypes.Config client htrktypes.Client[HTH, S, ID, BLOCK_HASH] - logger logger.Logger - chStop services.StopChan + onSubscription func(context.Context) + handleNewHead HeadHandler[HTH, BLOCK_HASH] chHeaders chan HTH headSubscription types.Subscription connected atomic.Bool @@ -74,38 +78,43 @@ func NewHeadListener[ lggr logger.Logger, client CLIENT, config htrktypes.Config, - chStop chan struct{}, + onSubscription func(context.Context), + handleNewHead HeadHandler[HTH, BLOCK_HASH], ) HeadListener[HTH, BLOCK_HASH] { - return &headListener[HTH, S, ID, BLOCK_HASH]{ - config: config, - client: client, - logger: logger.Named(lggr, "HeadListener"), - chStop: chStop, + hl := &headListener[HTH, S, ID, BLOCK_HASH]{ + config: config, + client: client, + onSubscription: onSubscription, + handleNewHead: handleNewHead, } + hl.Service, hl.eng = services.Config{ + Name: "HeadListener", + Start: hl.start, + }.NewServiceEngine(lggr) + return hl } -func (hl *headListener[HTH, S, ID, BLOCK_HASH]) Name() string { - return hl.logger.Name() +func (hl *headListener[HTH, S, ID, BLOCK_HASH]) start(context.Context) error { + hl.eng.Go(hl.ListenForNewHeads) + return nil } -func (hl *headListener[HTH, S, ID, BLOCK_HASH]) ListenForNewHeads(onSubscription func(), handleNewHead headHandler[HTH, BLOCK_HASH], done func()) { - defer done() +func (hl *headListener[HTH, S, ID, BLOCK_HASH]) ListenForNewHeads(ctx context.Context) { defer hl.unsubscribe() - ctx, cancel := hl.chStop.NewCtx() - defer cancel() - for { if !hl.subscribe(ctx) { break } - onSubscription() - err := hl.receiveHeaders(ctx, handleNewHead) + if hl.onSubscription != nil { + hl.onSubscription(ctx) + } + err := hl.receiveHeaders(ctx, hl.handleNewHead) if ctx.Err() != nil { break } else if err != nil { - hl.logger.Errorw("Error in new head subscription, unsubscribed", "err", err) + hl.eng.Errorw("Error in new head subscription, unsubscribed", "err", err) continue } break @@ -131,7 +140,7 @@ func (hl *headListener[HTH, S, ID, BLOCK_HASH]) HealthReport() map[string]error return map[string]error{hl.Name(): err} } -func (hl *headListener[HTH, S, ID, BLOCK_HASH]) receiveHeaders(ctx context.Context, handleNewHead headHandler[HTH, BLOCK_HASH]) error { +func (hl *headListener[HTH, S, ID, BLOCK_HASH]) receiveHeaders(ctx context.Context, handleNewHead HeadHandler[HTH, BLOCK_HASH]) error { var noHeadsAlarmC <-chan time.Time var noHeadsAlarmT *time.Ticker noHeadsAlarmDuration := hl.config.BlockEmissionIdleWarningThreshold() @@ -142,7 +151,7 @@ func (hl *headListener[HTH, S, ID, BLOCK_HASH]) receiveHeaders(ctx context.Conte for { select { - case <-hl.chStop: + case <-ctx.Done(): return nil case blockHeader, open := <-hl.chHeaders: @@ -158,13 +167,13 @@ func (hl *headListener[HTH, S, ID, BLOCK_HASH]) receiveHeaders(ctx context.Conte return errors.New("head listener: chHeaders prematurely closed") } if !blockHeader.IsValid() { - hl.logger.Error("got nil block header") + hl.eng.Error("got nil block header") continue } // Compare the chain ID of the block header to the chain ID of the client if !blockHeader.HasChainID() || blockHeader.ChainID().String() != chainId.String() { - hl.logger.Panicf("head listener for %s received block header for %s", chainId, blockHeader.ChainID()) + hl.eng.Panicf("head listener for %s received block header for %s", chainId, blockHeader.ChainID()) } promNumHeadsReceived.WithLabelValues(chainId.String()).Inc() @@ -184,7 +193,7 @@ func (hl *headListener[HTH, S, ID, BLOCK_HASH]) receiveHeaders(ctx context.Conte case <-noHeadsAlarmC: // We haven't received a head on the channel for a long time, log a warning - hl.logger.Warnf("have not received a head for %v", noHeadsAlarmDuration) + hl.eng.Warnf("have not received a head for %v", noHeadsAlarmDuration) hl.receivingHeads.Store(false) } } @@ -198,19 +207,19 @@ func (hl *headListener[HTH, S, ID, BLOCK_HASH]) subscribe(ctx context.Context) b for { hl.unsubscribe() - hl.logger.Debugf("Subscribing to new heads on chain %s", chainId.String()) + hl.eng.Debugf("Subscribing to new heads on chain %s", chainId.String()) select { - case <-hl.chStop: + case <-ctx.Done(): return false case <-time.After(subscribeRetryBackoff.Duration()): err := hl.subscribeToHead(ctx) if err != nil { promEthConnectionErrors.WithLabelValues(chainId.String()).Inc() - hl.logger.Warnw("Failed to subscribe to heads on chain", "chainID", chainId.String(), "err", err) + hl.eng.Warnw("Failed to subscribe to heads on chain", "chainID", chainId.String(), "err", err) } else { - hl.logger.Debugf("Subscribed to heads on chain %s", chainId.String()) + hl.eng.Debugf("Subscribed to heads on chain %s", chainId.String()) return true } } diff --git a/common/headtracker/head_tracker.go b/common/headtracker/head_tracker.go index 851458591b..8546d856b6 100644 --- a/common/headtracker/head_tracker.go +++ b/common/headtracker/head_tracker.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "math/big" - "sync" "time" "github.com/prometheus/client_golang/prometheus" @@ -51,7 +50,9 @@ type headTracker[ ID types.ID, BLOCK_HASH types.Hashable, ] struct { - services.StateMachine + services.Service + eng *services.Engine + log logger.SugaredLogger headBroadcaster HeadBroadcaster[HTH, BLOCK_HASH] headSaver HeadSaver[HTH, BLOCK_HASH] @@ -64,8 +65,6 @@ type headTracker[ backfillMB *mailbox.Mailbox[HTH] broadcastMB *mailbox.Mailbox[HTH] headListener HeadListener[HTH, BLOCK_HASH] - chStop services.StopChan - wgDone sync.WaitGroup getNilHead func() HTH } @@ -85,52 +84,52 @@ func NewHeadTracker[ mailMon *mailbox.Monitor, getNilHead func() HTH, ) HeadTracker[HTH, BLOCK_HASH] { - chStop := make(chan struct{}) - lggr = logger.Named(lggr, "HeadTracker") - return &headTracker[HTH, S, ID, BLOCK_HASH]{ + ht := &headTracker[HTH, S, ID, BLOCK_HASH]{ headBroadcaster: headBroadcaster, client: client, chainID: client.ConfiguredChainID(), config: config, htConfig: htConfig, - log: logger.Sugared(lggr), backfillMB: mailbox.NewSingle[HTH](), broadcastMB: mailbox.New[HTH](HeadsBufferSize), - chStop: chStop, - headListener: NewHeadListener[HTH, S, ID, BLOCK_HASH](lggr, client, config, chStop), headSaver: headSaver, mailMon: mailMon, getNilHead: getNilHead, } + ht.Service, ht.eng = services.Config{ + Name: "HeadTracker", + NewSubServices: func(lggr logger.Logger) []services.Service { + ht.headListener = NewHeadListener[HTH, S, ID, BLOCK_HASH](lggr, client, config, + // NOTE: Always try to start the head tracker off with whatever the + // latest head is, without waiting for the subscription to send us one. + // + // In some cases the subscription will send us the most recent head + // anyway when we connect (but we should not rely on this because it is + // not specced). If it happens this is fine, and the head will be + // ignored as a duplicate. + func(ctx context.Context) { + err := ht.handleInitialHead(ctx) + if err != nil { + ht.log.Errorw("Error handling initial head", "err", err.Error()) + } + }, ht.handleNewHead) + return []services.Service{ht.headListener} + }, + Start: ht.start, + Close: ht.close, + }.NewServiceEngine(lggr) + ht.log = logger.Sugared(ht.eng) + return ht } // Start starts HeadTracker service. -func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) Start(ctx context.Context) error { - return ht.StartOnce("HeadTracker", func() error { - ht.log.Debugw("Starting HeadTracker", "chainID", ht.chainID) - // NOTE: Always try to start the head tracker off with whatever the - // latest head is, without waiting for the subscription to send us one. - // - // In some cases the subscription will send us the most recent head - // anyway when we connect (but we should not rely on this because it is - // not specced). If it happens this is fine, and the head will be - // ignored as a duplicate. - onSubscribe := func() { - err := ht.handleInitialHead(ctx) - if err != nil { - ht.log.Errorw("Error handling initial head", "err", err.Error()) - } - } +func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) start(context.Context) error { + ht.eng.Go(ht.backfillLoop) + ht.eng.Go(ht.broadcastLoop) - ht.wgDone.Add(3) - go ht.headListener.ListenForNewHeads(onSubscribe, ht.handleNewHead, ht.wgDone.Done) - go ht.backfillLoop() - go ht.broadcastLoop() + ht.mailMon.Monitor(ht.broadcastMB, "HeadTracker", "Broadcast", ht.chainID.String()) - ht.mailMon.Monitor(ht.broadcastMB, "HeadTracker", "Broadcast", ht.chainID.String()) - - return nil - }) + return nil } func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) handleInitialHead(ctx context.Context) error { @@ -176,23 +175,8 @@ func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) handleInitialHead(ctx context.Con return nil } -// Close stops HeadTracker service. -func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) Close() error { - return ht.StopOnce("HeadTracker", func() error { - close(ht.chStop) - ht.wgDone.Wait() - return ht.broadcastMB.Close() - }) -} - -func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) Name() string { - return ht.log.Name() -} - -func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) HealthReport() map[string]error { - report := map[string]error{ht.Name(): ht.Healthy()} - services.CopyHealth(report, ht.headListener.HealthReport()) - return report +func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) close() error { + return ht.broadcastMB.Close() } func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) Backfill(ctx context.Context, headWithChain HTH) (err error) { @@ -265,15 +249,13 @@ func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) handleNewHead(ctx context.Context promOldHead.WithLabelValues(ht.chainID.String()).Inc() err := fmt.Errorf("got very old block with number %d (highest seen was %d)", head.BlockNumber(), prevHead.BlockNumber()) ht.log.Critical("Got very old block. Either a very deep re-org occurred, one of the RPC nodes has gotten far out of sync, or the chain went backwards in block numbers. This node may not function correctly without manual intervention.", "err", err) - ht.SvcErrBuffer.Append(err) + ht.eng.EmitHealthErr(err) } } return nil } -func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) broadcastLoop() { - defer ht.wgDone.Done() - +func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) broadcastLoop(ctx context.Context) { samplingInterval := ht.htConfig.SamplingInterval() if samplingInterval > 0 { ht.log.Debugf("Head sampling is enabled - sampling interval is set to: %v", samplingInterval) @@ -281,7 +263,7 @@ func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) broadcastLoop() { defer debounceHead.Stop() for { select { - case <-ht.chStop: + case <-ctx.Done(): return case <-debounceHead.C: item := ht.broadcastMB.RetrieveLatestAndClear() @@ -295,7 +277,7 @@ func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) broadcastLoop() { ht.log.Info("Head sampling is disabled - callback will be called on every head") for { select { - case <-ht.chStop: + case <-ctx.Done(): return case <-ht.broadcastMB.Notify(): for { @@ -310,15 +292,10 @@ func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) broadcastLoop() { } } -func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) backfillLoop() { - defer ht.wgDone.Done() - - ctx, cancel := ht.chStop.NewCtx() - defer cancel() - +func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) backfillLoop(ctx context.Context) { for { select { - case <-ht.chStop: + case <-ctx.Done(): return case <-ht.backfillMB.Notify(): for { diff --git a/core/bridges/cache.go b/core/bridges/cache.go index 4b5a655244..e97874a35e 100644 --- a/core/bridges/cache.go +++ b/core/bridges/cache.go @@ -10,11 +10,9 @@ import ( "golang.org/x/exp/maps" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) const ( @@ -25,13 +23,11 @@ const ( type Cache struct { // dependencies and configurations ORM - lggr logger.Logger interval time.Duration // service state - services.StateMachine - wg sync.WaitGroup - chStop services.StopChan + services.Service + eng *services.Engine // data state bridgeTypesCache sync.Map @@ -43,17 +39,20 @@ var _ ORM = (*Cache)(nil) var _ services.Service = (*Cache)(nil) func NewCache(base ORM, lggr logger.Logger, upsertInterval time.Duration) *Cache { - return &Cache{ + c := &Cache{ ORM: base, - lggr: lggr.Named(CacheServiceName), interval: upsertInterval, - chStop: make(chan struct{}), bridgeLastValueCache: make(map[string]BridgeResponse), } + c.Service, c.eng = services.Config{ + Name: CacheServiceName, + Start: c.start, + }.NewServiceEngine(lggr) + return c } func (c *Cache) WithDataSource(ds sqlutil.DataSource) ORM { - return NewCache(NewORM(ds), c.lggr, c.interval) + return NewCache(NewORM(ds), c.eng, c.interval) } func (c *Cache) FindBridge(ctx context.Context, name BridgeName) (BridgeType, error) { @@ -190,51 +189,17 @@ func (c *Cache) UpsertBridgeResponse(ctx context.Context, dotId string, specId i return nil } -func (c *Cache) Start(_ context.Context) error { - return c.StartOnce(CacheServiceName, func() error { - c.wg.Add(1) - - go c.run() - - return nil - }) -} - -func (c *Cache) Close() error { - return c.StopOnce(CacheServiceName, func() error { - close(c.chStop) - c.wg.Wait() - - return nil - }) -} - -func (c *Cache) HealthReport() map[string]error { - return map[string]error{c.Name(): c.Healthy()} -} - -func (c *Cache) Name() string { - return c.lggr.Name() -} - -func (c *Cache) run() { - defer c.wg.Done() - - for { - timer := time.NewTimer(utils.WithJitter(c.interval)) +func (c *Cache) start(_ context.Context) error { + ticker := services.TickerConfig{ + Initial: c.interval, + JitterPct: services.DefaultJitter, + }.NewTicker(c.interval) + c.eng.GoTick(ticker, c.doBulkUpsert) - select { - case <-timer.C: - c.doBulkUpsert() - case <-c.chStop: - timer.Stop() - - return - } - } + return nil } -func (c *Cache) doBulkUpsert() { +func (c *Cache) doBulkUpsert(ctx context.Context) { c.mu.RLock() values := maps.Values(c.bridgeLastValueCache) c.mu.RUnlock() @@ -243,11 +208,8 @@ func (c *Cache) doBulkUpsert() { return } - ctx, cancel := c.chStop.NewCtx() - defer cancel() - if err := c.ORM.BulkUpsertBridgeResponse(ctx, values); err != nil { - c.lggr.Warnf("bulk upsert of bridge responses failed: %s", err.Error()) + c.eng.Warnf("bulk upsert of bridge responses failed: %s", err.Error()) } } diff --git a/core/chains/evm/headtracker/head_listener.go b/core/chains/evm/headtracker/head_listener.go deleted file mode 100644 index 04535a3486..0000000000 --- a/core/chains/evm/headtracker/head_listener.go +++ /dev/null @@ -1,28 +0,0 @@ -package headtracker - -import ( - "math/big" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common" - - "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink/v2/common/headtracker" - - htrktypes "github.com/smartcontractkit/chainlink/v2/common/headtracker/types" - evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" -) - -type headListener = headtracker.HeadListener[*evmtypes.Head, common.Hash] - -func NewHeadListener( - lggr logger.Logger, - ethClient evmclient.Client, - config htrktypes.Config, chStop chan struct{}, -) headListener { - return headtracker.NewHeadListener[ - *evmtypes.Head, - ethereum.Subscription, *big.Int, common.Hash, - ](lggr, ethClient, config, chStop) -} diff --git a/core/chains/evm/headtracker/head_listener_test.go b/core/chains/evm/headtracker/head_listener_test.go index 29b090bbff..2e459af2a2 100644 --- a/core/chains/evm/headtracker/head_listener_test.go +++ b/core/chains/evm/headtracker/head_listener_test.go @@ -16,9 +16,9 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/v2/common/headtracker" commonmocks "github.com/smartcontractkit/chainlink/v2/common/types/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/testutils" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) @@ -40,17 +40,10 @@ func Test_HeadListener_HappyPath(t *testing.T) { evmcfg := testutils.NewTestChainScopedConfig(t, func(c *toml.EVMConfig) { c.NoNewHeadsThreshold = &commonconfig.Duration{} }) - chStop := make(chan struct{}) - hl := headtracker.NewHeadListener(lggr, ethClient, evmcfg.EVM(), chStop) var headCount atomic.Int32 - handler := func(context.Context, *evmtypes.Head) error { - headCount.Add(1) - return nil - } - - subscribeAwaiter := testutils.NewAwaiter() unsubscribeAwaiter := testutils.NewAwaiter() + subscribeAwaiter := testutils.NewAwaiter() var chHeads chan<- *evmtypes.Head var chErr = make(chan error) var chSubErr <-chan error = chErr @@ -66,23 +59,23 @@ func Test_HeadListener_HappyPath(t *testing.T) { close(chErr) }) - doneAwaiter := testutils.NewAwaiter() - done := func() { - doneAwaiter.ItHappened() - } - go hl.ListenForNewHeads(func() {}, handler, done) - - subscribeAwaiter.AwaitOrFail(t, tests.WaitTimeout(t)) - require.Eventually(t, hl.Connected, tests.WaitTimeout(t), tests.TestInterval) + func() { + hl := headtracker.NewHeadListener(lggr, ethClient, evmcfg.EVM(), nil, func(context.Context, *evmtypes.Head) error { + headCount.Add(1) + return nil + }) + require.NoError(t, hl.Start(tests.Context(t))) + defer func() { assert.NoError(t, hl.Close()) }() - chHeads <- testutils.Head(0) - chHeads <- testutils.Head(1) - chHeads <- testutils.Head(2) + subscribeAwaiter.AwaitOrFail(t, tests.WaitTimeout(t)) + require.Eventually(t, hl.Connected, tests.WaitTimeout(t), tests.TestInterval) - require.True(t, hl.ReceivingHeads()) + chHeads <- testutils.Head(0) + chHeads <- testutils.Head(1) + chHeads <- testutils.Head(2) - close(chStop) - doneAwaiter.AwaitOrFail(t) + require.True(t, hl.ReceivingHeads()) + }() unsubscribeAwaiter.AwaitOrFail(t) require.Equal(t, int32(3), headCount.Load()) @@ -101,14 +94,8 @@ func Test_HeadListener_NotReceivingHeads(t *testing.T) { evmcfg := testutils.NewTestChainScopedConfig(t, func(c *toml.EVMConfig) { c.NoNewHeadsThreshold = commonconfig.MustNewDuration(time.Second) }) - chStop := make(chan struct{}) - hl := headtracker.NewHeadListener(lggr, ethClient, evmcfg.EVM(), chStop) firstHeadAwaiter := testutils.NewAwaiter() - handler := func(context.Context, *evmtypes.Head) error { - firstHeadAwaiter.ItHappened() - return nil - } subscribeAwaiter := testutils.NewAwaiter() var chHeads chan<- *evmtypes.Head @@ -125,25 +112,25 @@ func Test_HeadListener_NotReceivingHeads(t *testing.T) { close(chErr) }) - doneAwaiter := testutils.NewAwaiter() - done := func() { - doneAwaiter.ItHappened() - } - go hl.ListenForNewHeads(func() {}, handler, done) - - subscribeAwaiter.AwaitOrFail(t, tests.WaitTimeout(t)) + func() { + hl := headtracker.NewHeadListener(lggr, ethClient, evmcfg.EVM(), nil, func(context.Context, *evmtypes.Head) error { + firstHeadAwaiter.ItHappened() + return nil + }) + require.NoError(t, hl.Start(tests.Context(t))) + defer func() { assert.NoError(t, hl.Close()) }() - chHeads <- testutils.Head(0) - firstHeadAwaiter.AwaitOrFail(t) + subscribeAwaiter.AwaitOrFail(t, tests.WaitTimeout(t)) - require.True(t, hl.ReceivingHeads()) + chHeads <- testutils.Head(0) + firstHeadAwaiter.AwaitOrFail(t) - time.Sleep(time.Second * 2) + require.True(t, hl.ReceivingHeads()) - require.False(t, hl.ReceivingHeads()) + time.Sleep(time.Second * 2) - close(chStop) - doneAwaiter.AwaitOrFail(t) + require.False(t, hl.ReceivingHeads()) + }() } func Test_HeadListener_SubscriptionErr(t *testing.T) { @@ -161,19 +148,11 @@ func Test_HeadListener_SubscriptionErr(t *testing.T) { for _, test := range cases { test := test t.Run(test.name, func(t *testing.T) { - l := logger.Test(t) + lggr := logger.Test(t) ethClient := testutils.NewEthClientMockWithDefaultChain(t) evmcfg := testutils.NewTestChainScopedConfig(t, nil) - chStop := make(chan struct{}) - hl := headtracker.NewHeadListener(l, ethClient, evmcfg.EVM(), chStop) hnhCalled := make(chan *evmtypes.Head) - hnh := func(_ context.Context, header *evmtypes.Head) error { - hnhCalled <- header - return nil - } - doneAwaiter := testutils.NewAwaiter() - done := doneAwaiter.ItHappened chSubErrTest := make(chan error) var chSubErr <-chan error = chSubErrTest @@ -189,63 +168,66 @@ func Test_HeadListener_SubscriptionErr(t *testing.T) { headsCh = args.Get(1).(chan<- *evmtypes.Head) subscribeAwaiter.ItHappened() }) - go func() { - hl.ListenForNewHeads(func() {}, hnh, done) - }() - - // Put a head on the channel to ensure we test all code paths - subscribeAwaiter.AwaitOrFail(t, tests.WaitTimeout(t)) - head := testutils.Head(0) - headsCh <- head - - h := <-hnhCalled - assert.Equal(t, head, h) - - // Expect a call to unsubscribe on error - sub.On("Unsubscribe").Once().Run(func(_ mock.Arguments) { - close(headsCh) - // geth guarantees that Unsubscribe closes the errors channel - if !test.closeErr { + func() { + hl := headtracker.NewHeadListener(lggr, ethClient, evmcfg.EVM(), nil, func(_ context.Context, header *evmtypes.Head) error { + hnhCalled <- header + return nil + }) + require.NoError(t, hl.Start(tests.Context(t))) + defer func() { assert.NoError(t, hl.Close()) }() + + // Put a head on the channel to ensure we test all code paths + subscribeAwaiter.AwaitOrFail(t, tests.WaitTimeout(t)) + head := testutils.Head(0) + headsCh <- head + + h := <-hnhCalled + assert.Equal(t, head, h) + + // Expect a call to unsubscribe on error + sub.On("Unsubscribe").Once().Run(func(_ mock.Arguments) { + close(headsCh) + // geth guarantees that Unsubscribe closes the errors channel + if !test.closeErr { + close(chSubErrTest) + } + }) + // Expect a resubscribe + chSubErrTest2 := make(chan error) + var chSubErr2 <-chan error = chSubErrTest2 + sub2 := commonmocks.NewSubscription(t) + sub2.On("Err").Return(chSubErr2) + subscribeAwaiter2 := testutils.NewAwaiter() + + var headsCh2 chan<- *evmtypes.Head + ethClient.On("SubscribeNewHead", mock.Anything, mock.AnythingOfType("chan<- *types.Head")).Return(sub2, nil).Once().Run(func(args mock.Arguments) { + headsCh2 = args.Get(1).(chan<- *evmtypes.Head) + subscribeAwaiter2.ItHappened() + }) + + // Sending test error + if test.closeErr { close(chSubErrTest) + } else { + chSubErrTest <- test.err } - }) - // Expect a resubscribe - chSubErrTest2 := make(chan error) - var chSubErr2 <-chan error = chSubErrTest2 - sub2 := commonmocks.NewSubscription(t) - sub2.On("Err").Return(chSubErr2) - subscribeAwaiter2 := testutils.NewAwaiter() - - var headsCh2 chan<- *evmtypes.Head - ethClient.On("SubscribeNewHead", mock.Anything, mock.AnythingOfType("chan<- *types.Head")).Return(sub2, nil).Once().Run(func(args mock.Arguments) { - headsCh2 = args.Get(1).(chan<- *evmtypes.Head) - subscribeAwaiter2.ItHappened() - }) - - // Sending test error - if test.closeErr { - close(chSubErrTest) - } else { - chSubErrTest <- test.err - } - // Wait for it to resubscribe - subscribeAwaiter2.AwaitOrFail(t, tests.WaitTimeout(t)) + // Wait for it to resubscribe + subscribeAwaiter2.AwaitOrFail(t, tests.WaitTimeout(t)) - head2 := testutils.Head(1) - headsCh2 <- head2 + head2 := testutils.Head(1) + headsCh2 <- head2 - h2 := <-hnhCalled - assert.Equal(t, head2, h2) + h2 := <-hnhCalled + assert.Equal(t, head2, h2) - // Second call to unsubscribe on close - sub2.On("Unsubscribe").Once().Run(func(_ mock.Arguments) { - close(headsCh2) - // geth guarantees that Unsubscribe closes the errors channel - close(chSubErrTest2) - }) - close(chStop) - doneAwaiter.AwaitOrFail(t) + // Second call to unsubscribe on close + sub2.On("Unsubscribe").Once().Run(func(_ mock.Arguments) { + close(headsCh2) + // geth guarantees that Unsubscribe closes the errors channel + close(chSubErrTest2) + }) + }() }) } } diff --git a/core/chains/evm/headtracker/head_tracker.go b/core/chains/evm/headtracker/head_tracker.go index d6c2cdc64e..f7607189f7 100644 --- a/core/chains/evm/headtracker/head_tracker.go +++ b/core/chains/evm/headtracker/head_tracker.go @@ -2,10 +2,8 @@ package headtracker import ( "context" - "math/big" "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common" "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink-common/pkg/logger" @@ -27,7 +25,7 @@ func NewHeadTracker( headSaver httypes.HeadSaver, mailMon *mailbox.Monitor, ) httypes.HeadTracker { - return headtracker.NewHeadTracker[*evmtypes.Head, ethereum.Subscription, *big.Int, common.Hash]( + return headtracker.NewHeadTracker[*evmtypes.Head, ethereum.Subscription]( lggr, ethClient, config, diff --git a/core/chains/evm/monitor/balance.go b/core/chains/evm/monitor/balance.go index b8194a38af..3e28d5c436 100644 --- a/core/chains/evm/monitor/balance.go +++ b/core/chains/evm/monitor/balance.go @@ -33,14 +33,15 @@ type ( } balanceMonitor struct { - services.StateMachine - logger logger.Logger + services.Service + eng *services.Engine + ethClient evmclient.Client chainID *big.Int chainIDStr string ethKeyStore keystore.Eth ethBalances map[gethCommon.Address]*assets.Eth - ethBalancesMtx *sync.RWMutex + ethBalancesMtx sync.RWMutex sleeperTask *utils.SleeperTask } @@ -53,59 +54,42 @@ var _ BalanceMonitor = (*balanceMonitor)(nil) func NewBalanceMonitor(ethClient evmclient.Client, ethKeyStore keystore.Eth, lggr logger.Logger) *balanceMonitor { chainId := ethClient.ConfiguredChainID() bm := &balanceMonitor{ - services.StateMachine{}, - logger.Named(lggr, "BalanceMonitor"), - ethClient, - chainId, - chainId.String(), - ethKeyStore, - make(map[gethCommon.Address]*assets.Eth), - new(sync.RWMutex), - nil, + ethClient: ethClient, + chainID: chainId, + chainIDStr: chainId.String(), + ethKeyStore: ethKeyStore, + ethBalances: make(map[gethCommon.Address]*assets.Eth), } + bm.Service, bm.eng = services.Config{ + Name: "BalanceMonitor", + Start: bm.start, + Close: bm.close, + }.NewServiceEngine(lggr) bm.sleeperTask = utils.NewSleeperTask(&worker{bm: bm}) return bm } -func (bm *balanceMonitor) Start(ctx context.Context) error { - return bm.StartOnce("BalanceMonitor", func() error { - // Always query latest balance on start - (&worker{bm}).WorkCtx(ctx) - return nil - }) -} - -// Close shuts down the BalanceMonitor, should not be used after this -func (bm *balanceMonitor) Close() error { - return bm.StopOnce("BalanceMonitor", func() error { - return bm.sleeperTask.Stop() - }) -} - -func (bm *balanceMonitor) Ready() error { +func (bm *balanceMonitor) start(ctx context.Context) error { + // Always query latest balance on start + (&worker{bm}).WorkCtx(ctx) return nil } -func (bm *balanceMonitor) Name() string { - return bm.logger.Name() -} - -func (bm *balanceMonitor) HealthReport() map[string]error { - return map[string]error{bm.Name(): bm.Healthy()} +// Close shuts down the BalanceMonitor, should not be used after this +func (bm *balanceMonitor) close() error { + return bm.sleeperTask.Stop() } // OnNewLongestChain checks the balance for each key -func (bm *balanceMonitor) OnNewLongestChain(_ context.Context, head *evmtypes.Head) { - ok := bm.IfStarted(func() { - bm.checkBalance(head) - }) +func (bm *balanceMonitor) OnNewLongestChain(_ context.Context, _ *evmtypes.Head) { + ok := bm.sleeperTask.IfStarted(bm.checkBalances) if !ok { - bm.logger.Debugw("BalanceMonitor: ignoring OnNewLongestChain call, balance monitor is not started", "state", bm.State()) + bm.eng.Debugw("BalanceMonitor: ignoring OnNewLongestChain call, balance monitor is not started", "state", bm.sleeperTask.State()) } } -func (bm *balanceMonitor) checkBalance(head *evmtypes.Head) { - bm.logger.Debugw("BalanceMonitor: signalling balance worker") +func (bm *balanceMonitor) checkBalances() { + bm.eng.Debugw("BalanceMonitor: signalling balance worker") bm.sleeperTask.WakeUp() } @@ -117,7 +101,7 @@ func (bm *balanceMonitor) updateBalance(ethBal assets.Eth, address gethCommon.Ad bm.ethBalances[address] = ðBal bm.ethBalancesMtx.Unlock() - lgr := logger.Named(bm.logger, "BalanceLog") + lgr := logger.Named(bm.eng, "BalanceLog") lgr = logger.With(lgr, "address", address.Hex(), "ethBalance", ethBal.String(), @@ -151,7 +135,7 @@ func (bm *balanceMonitor) promUpdateEthBalance(balance *assets.Eth, from gethCom balanceFloat, err := ApproximateFloat64(balance) if err != nil { - bm.logger.Error(fmt.Errorf("updatePrometheusEthBalance: %v", err)) + bm.eng.Error(fmt.Errorf("updatePrometheusEthBalance: %v", err)) return } @@ -174,7 +158,7 @@ func (w *worker) Work() { func (w *worker) WorkCtx(ctx context.Context) { enabledAddresses, err := w.bm.ethKeyStore.EnabledAddressesForChain(ctx, w.bm.chainID) if err != nil { - w.bm.logger.Error("BalanceMonitor: error getting keys", err) + w.bm.eng.Error("BalanceMonitor: error getting keys", err) } var wg sync.WaitGroup @@ -198,12 +182,12 @@ func (w *worker) checkAccountBalance(ctx context.Context, address gethCommon.Add bal, err := w.bm.ethClient.BalanceAt(ctx, address, nil) if err != nil { - w.bm.logger.Errorw(fmt.Sprintf("BalanceMonitor: error getting balance for key %s", address.Hex()), + w.bm.eng.Errorw(fmt.Sprintf("BalanceMonitor: error getting balance for key %s", address.Hex()), "err", err, "address", address, ) } else if bal == nil { - w.bm.logger.Errorw(fmt.Sprintf("BalanceMonitor: error getting balance for key %s: invariant violation, bal may not be nil", address.Hex()), + w.bm.eng.Errorw(fmt.Sprintf("BalanceMonitor: error getting balance for key %s: invariant violation, bal may not be nil", address.Hex()), "err", err, "address", address, ) diff --git a/core/recovery/recover.go b/core/recovery/recover.go index 8e485abc55..61315defa9 100644 --- a/core/recovery/recover.go +++ b/core/recovery/recover.go @@ -3,38 +3,38 @@ package recovery import ( "github.com/getsentry/sentry-go" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + + corelogger "github.com/smartcontractkit/chainlink/v2/core/logger" ) func ReportPanics(fn func()) { - defer func() { - if err := recover(); err != nil { - sentry.CurrentHub().Recover(err) - sentry.Flush(logger.SentryFlushDeadline) + HandleFn(fn, func(err any) { + sentry.CurrentHub().Recover(err) + sentry.Flush(corelogger.SentryFlushDeadline) - panic(err) - } - }() - fn() + panic(err) + }) } func WrapRecover(lggr logger.Logger, fn func()) { - defer func() { - if err := recover(); err != nil { - lggr.Recover(err) + WrapRecoverHandle(lggr, fn, nil) +} + +func WrapRecoverHandle(lggr logger.Logger, fn func(), onPanic func(recovered any)) { + HandleFn(fn, func(recovered any) { + logger.Sugared(lggr).Criticalw("Recovered goroutine panic", "panic", recovered) + + if onPanic != nil { + onPanic(recovered) } - }() - fn() + }) } -func WrapRecoverHandle(lggr logger.Logger, fn func(), onPanic func(interface{})) { +func HandleFn(fn func(), onPanic func(recovered any)) { defer func() { - if err := recover(); err != nil { - lggr.Recover(err) - - if onPanic != nil { - onPanic(err) - } + if recovered := recover(); recovered != nil { + onPanic(recovered) } }() fn() diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 138ca25ed3..c23ec08a69 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -148,7 +148,6 @@ type ChainlinkApplication struct { shutdownOnce sync.Once srvcs []services.ServiceCtx HealthChecker services.Checker - Nurse *services.Nurse logger logger.SugaredLogger AuditLogger audit.AuditLogger closeLogger func() error @@ -277,14 +276,9 @@ func NewApplication(opts ApplicationOpts) (Application, error) { } ap := cfg.AutoPprof() - var nurse *services.Nurse if ap.Enabled() { globalLogger.Info("Nurse service (automatic pprof profiling) is enabled") - nurse = services.NewNurse(ap, globalLogger) - err := nurse.Start() - if err != nil { - return nil, err - } + srvcs = append(srvcs, services.NewNurse(ap, globalLogger)) } else { globalLogger.Info("Nurse service (automatic pprof profiling) is disabled") } @@ -588,7 +582,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) { SessionReaper: sessionReaper, ExternalInitiatorManager: externalInitiatorManager, HealthChecker: healthChecker, - Nurse: nurse, logger: globalLogger, AuditLogger: auditLogger, closeLogger: opts.CloseLogger, @@ -708,10 +701,6 @@ func (app *ChainlinkApplication) stop() (err error) { err = multierr.Append(err, app.FeedsService.Close()) } - if app.Nurse != nil { - err = multierr.Append(err, app.Nurse.Close()) - } - if app.profiler != nil { err = multierr.Append(err, app.profiler.Stop()) } diff --git a/core/services/fluxmonitorv2/deviation_checker.go b/core/services/fluxmonitorv2/deviation_checker.go index 51e85de371..9dc399b09f 100644 --- a/core/services/fluxmonitorv2/deviation_checker.go +++ b/core/services/fluxmonitorv2/deviation_checker.go @@ -3,7 +3,7 @@ package fluxmonitorv2 import ( "github.com/shopspring/decimal" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink-common/pkg/logger" ) // DeviationThresholds carries parameters used by the threshold-trigger logic @@ -26,7 +26,7 @@ func NewDeviationChecker(rel, abs float64, lggr logger.Logger) *DeviationChecker Rel: rel, Abs: abs, }, - lggr: lggr.Named("DeviationChecker").With("threshold", rel, "absoluteThreshold", abs), + lggr: logger.Sugared(lggr).Named("DeviationChecker").With("threshold", rel, "absoluteThreshold", abs), } } diff --git a/core/services/fluxmonitorv2/flux_monitor.go b/core/services/fluxmonitorv2/flux_monitor.go index 9175feb1a6..b8154ab679 100644 --- a/core/services/fluxmonitorv2/flux_monitor.go +++ b/core/services/fluxmonitorv2/flux_monitor.go @@ -13,6 +13,7 @@ import ( "github.com/pkg/errors" "github.com/shopspring/decimal" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" @@ -22,7 +23,6 @@ import ( evmutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flags_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/recovery" "github.com/smartcontractkit/chainlink/v2/core/services/fluxmonitorv2/promfm" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -56,7 +56,10 @@ const DefaultHibernationPollPeriod = 24 * time.Hour // FluxMonitor polls external price adapters via HTTP to check for price swings. type FluxMonitor struct { - services.StateMachine + services.Service + eng *services.Engine + logger logger.SugaredLogger + contractAddress common.Address oracleAddress common.Address jobSpec job.Job @@ -77,13 +80,8 @@ type FluxMonitor struct { logBroadcaster log.Broadcaster chainID *big.Int - logger logger.SugaredLogger - backlog *utils.BoundedPriorityQueue[log.Broadcast] chProcessLogs chan struct{} - - chStop services.StopChan - waitOnStop chan struct{} } // NewFluxMonitor returns a new instance of PollingDeviationChecker. @@ -105,7 +103,7 @@ func NewFluxMonitor( flags Flags, fluxAggregator flux_aggregator_wrapper.FluxAggregatorInterface, logBroadcaster log.Broadcaster, - fmLogger logger.Logger, + lggr logger.Logger, chainID *big.Int, ) (*FluxMonitor, error) { fm := &FluxMonitor{ @@ -126,7 +124,6 @@ func NewFluxMonitor( flags: flags, logBroadcaster: logBroadcaster, fluxAggregator: fluxAggregator, - logger: logger.Sugared(fmLogger), chainID: chainID, backlog: utils.NewBoundedPriorityQueue[log.Broadcast](map[uint]int{ // We want reconnecting nodes to be able to submit to a round @@ -136,9 +133,13 @@ func NewFluxMonitor( PriorityFlagChangedLog: 2, }), chProcessLogs: make(chan struct{}, 1), - chStop: make(services.StopChan), - waitOnStop: make(chan struct{}), } + fm.Service, fm.eng = services.Config{ + Name: "FluxMonitor", + Start: fm.start, + Close: fm.close, + }.NewServiceEngine(lggr) + fm.logger = logger.Sugared(fm.eng) return fm, nil } @@ -220,7 +221,7 @@ func NewFromJobSpec( return nil, err } - fmLogger := lggr.With( + fmLogger := logger.With(lggr, "jobID", jobSpec.ID, "contract", fmSpec.ContractAddress.Hex(), ) @@ -279,14 +280,9 @@ const ( // Start implements the job.Service interface. It begins the CSP consumer in a // single goroutine to poll the price adapters and listen to NewRound events. -func (fm *FluxMonitor) Start(context.Context) error { - return fm.StartOnce("FluxMonitor", func() error { - fm.logger.Debug("Starting Flux Monitor for job") - - go fm.consume() - - return nil - }) +func (fm *FluxMonitor) start(context.Context) error { + fm.eng.Go(fm.consume) + return nil } func (fm *FluxMonitor) IsHibernating() bool { @@ -304,16 +300,12 @@ func (fm *FluxMonitor) IsHibernating() bool { return !isFlagLowered } -// Close implements the job.Service interface. It stops this instance from +// close stops this instance from // polling, cleaning up resources. -func (fm *FluxMonitor) Close() error { - return fm.StopOnce("FluxMonitor", func() error { - fm.pollManager.Stop() - close(fm.chStop) - <-fm.waitOnStop +func (fm *FluxMonitor) close() error { + fm.pollManager.Stop() - return nil - }) + return nil } // JobID implements the listener.Listener interface. @@ -354,10 +346,8 @@ func (fm *FluxMonitor) HandleLog(ctx context.Context, broadcast log.Broadcast) { } } -func (fm *FluxMonitor) consume() { - defer close(fm.waitOnStop) - - if err := fm.SetOracleAddress(); err != nil { +func (fm *FluxMonitor) consume(ctx context.Context) { + if err := fm.SetOracleAddress(ctx); err != nil { fm.logger.Warnw( "unable to set oracle address, this flux monitor job may not work correctly", "err", err, @@ -398,46 +388,46 @@ func (fm *FluxMonitor) consume() { for { select { - case <-fm.chStop: + case <-ctx.Done(): return case <-fm.chProcessLogs: - recovery.WrapRecover(fm.logger, fm.processLogs) + recovery.WrapRecover(fm.logger, func() { fm.processLogs(ctx) }) case at := <-fm.pollManager.PollTickerTicks(): tickLogger.Debugf("Poll ticker fired on %v", formatTime(at)) recovery.WrapRecover(fm.logger, func() { - fm.pollIfEligible(PollRequestTypePoll, fm.deviationChecker, nil) + fm.pollIfEligible(ctx, PollRequestTypePoll, fm.deviationChecker, nil) }) case at := <-fm.pollManager.IdleTimerTicks(): tickLogger.Debugf("Idle timer fired on %v", formatTime(at)) recovery.WrapRecover(fm.logger, func() { - fm.pollIfEligible(PollRequestTypeIdle, NewZeroDeviationChecker(fm.logger), nil) + fm.pollIfEligible(ctx, PollRequestTypeIdle, NewZeroDeviationChecker(fm.logger), nil) }) case at := <-fm.pollManager.RoundTimerTicks(): tickLogger.Debugf("Round timer fired on %v", formatTime(at)) recovery.WrapRecover(fm.logger, func() { - fm.pollIfEligible(PollRequestTypeRound, fm.deviationChecker, nil) + fm.pollIfEligible(ctx, PollRequestTypeRound, fm.deviationChecker, nil) }) case at := <-fm.pollManager.HibernationTimerTicks(): tickLogger.Debugf("Hibernation timer fired on %v", formatTime(at)) recovery.WrapRecover(fm.logger, func() { - fm.pollIfEligible(PollRequestTypeHibernation, NewZeroDeviationChecker(fm.logger), nil) + fm.pollIfEligible(ctx, PollRequestTypeHibernation, NewZeroDeviationChecker(fm.logger), nil) }) case at := <-fm.pollManager.RetryTickerTicks(): tickLogger.Debugf("Retry ticker fired on %v", formatTime(at)) recovery.WrapRecover(fm.logger, func() { - fm.pollIfEligible(PollRequestTypeRetry, NewZeroDeviationChecker(fm.logger), nil) + fm.pollIfEligible(ctx, PollRequestTypeRetry, NewZeroDeviationChecker(fm.logger), nil) }) case at := <-fm.pollManager.DrumbeatTicks(): tickLogger.Debugf("Drumbeat ticker fired on %v", formatTime(at)) recovery.WrapRecover(fm.logger, func() { - fm.pollIfEligible(PollRequestTypeDrumbeat, NewZeroDeviationChecker(fm.logger), nil) + fm.pollIfEligible(ctx, PollRequestTypeDrumbeat, NewZeroDeviationChecker(fm.logger), nil) }) case request := <-fm.pollManager.Poll(): @@ -446,7 +436,7 @@ func (fm *FluxMonitor) consume() { break default: recovery.WrapRecover(fm.logger, func() { - fm.pollIfEligible(request.Type, fm.deviationChecker, nil) + fm.pollIfEligible(ctx, request.Type, fm.deviationChecker, nil) }) } } @@ -460,11 +450,7 @@ func formatTime(at time.Time) string { // SetOracleAddress sets the oracle address which matches the node's keys. // If none match, it uses the first available key -func (fm *FluxMonitor) SetOracleAddress() error { - // fm on deprecation path, using dangling context - ctx, cancel := fm.chStop.NewCtx() - defer cancel() - +func (fm *FluxMonitor) SetOracleAddress(ctx context.Context) error { oracleAddrs, err := fm.fluxAggregator.GetOracles(nil) if err != nil { fm.logger.Error("failed to get list of oracles from FluxAggregator contract") @@ -502,10 +488,7 @@ func (fm *FluxMonitor) SetOracleAddress() error { return errors.New("No keys found") } -func (fm *FluxMonitor) processLogs() { - ctx, cancel := fm.chStop.NewCtx() - defer cancel() - +func (fm *FluxMonitor) processLogs(ctx context.Context) { for ctx.Err() == nil && !fm.backlog.Empty() { broadcast := fm.backlog.Take() fm.processBroadcast(ctx, broadcast) @@ -529,7 +512,7 @@ func (fm *FluxMonitor) processBroadcast(ctx context.Context, broadcast log.Broad decodedLog := broadcast.DecodedLog() switch log := decodedLog.(type) { case *flux_aggregator_wrapper.FluxAggregatorNewRound: - fm.respondToNewRoundLog(*log, broadcast) + fm.respondToNewRoundLog(ctx, *log, broadcast) case *flux_aggregator_wrapper.FluxAggregatorAnswerUpdated: fm.respondToAnswerUpdatedLog(*log) fm.markLogAsConsumed(ctx, broadcast, decodedLog, started) @@ -540,7 +523,7 @@ func (fm *FluxMonitor) processBroadcast(ctx context.Context, broadcast log.Broad // Only reactivate if it is hibernating if fm.pollManager.isHibernating.Load() { fm.pollManager.Awaken(fm.initialRoundState()) - fm.pollIfEligible(PollRequestTypeAwaken, NewZeroDeviationChecker(fm.logger), broadcast) + fm.pollIfEligible(ctx, PollRequestTypeAwaken, NewZeroDeviationChecker(fm.logger), broadcast) } default: fm.logger.Errorf("unknown log %v of type %T", log, log) @@ -589,10 +572,8 @@ func (fm *FluxMonitor) respondToAnswerUpdatedLog(log flux_aggregator_wrapper.Flu // The NewRound log tells us that an oracle has initiated a new round. This tells us that we // need to poll and submit an answer to the contract regardless of the deviation. -func (fm *FluxMonitor) respondToNewRoundLog(log flux_aggregator_wrapper.FluxAggregatorNewRound, lb log.Broadcast) { +func (fm *FluxMonitor) respondToNewRoundLog(ctx context.Context, log flux_aggregator_wrapper.FluxAggregatorNewRound, lb log.Broadcast) { started := time.Now() - ctx, cancel := fm.chStop.NewCtx() - defer cancel() newRoundLogger := fm.logger.With( "round", log.RoundId, @@ -819,10 +800,8 @@ func (fm *FluxMonitor) checkEligibilityAndAggregatorFunding(roundState flux_aggr return nil } -func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker *DeviationChecker, broadcast log.Broadcast) { +func (fm *FluxMonitor) pollIfEligible(ctx context.Context, pollReq PollRequestType, deviationChecker *DeviationChecker, broadcast log.Broadcast) { started := time.Now() - ctx, cancel := fm.chStop.NewCtx() - defer cancel() l := fm.logger.With( "threshold", deviationChecker.Thresholds.Rel, diff --git a/core/services/fluxmonitorv2/flux_monitor_test.go b/core/services/fluxmonitorv2/flux_monitor_test.go index b3a5bcee6b..1d1ed676e4 100644 --- a/core/services/fluxmonitorv2/flux_monitor_test.go +++ b/core/services/fluxmonitorv2/flux_monitor_test.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/google/uuid" + "github.com/jmoiron/sqlx" "github.com/onsi/gomega" "github.com/pkg/errors" "github.com/shopspring/decimal" @@ -18,11 +19,10 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" - "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/chainlink-common/pkg/assets" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" logmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log/mocks" @@ -491,7 +491,7 @@ func TestFluxMonitor_PollIfEligible(t *testing.T) { oracles := []common.Address{nodeAddr, testutils.NewAddress()} tm.fluxAggregator.On("GetOracles", nilOpts).Return(oracles, nil) - require.NoError(t, fm.SetOracleAddress()) + require.NoError(t, fm.SetOracleAddress(tests.Context(t))) fm.ExportedPollIfEligible(thresholds.rel, thresholds.abs) }) } @@ -526,7 +526,7 @@ func TestFluxMonitor_PollIfEligible_Creates_JobErr(t *testing.T) { Once() tm.fluxAggregator.On("GetOracles", nilOpts).Return(oracles, nil) - require.NoError(t, fm.SetOracleAddress()) + require.NoError(t, fm.SetOracleAddress(tests.Context(t))) fm.ExportedPollIfEligible(1, 1) } @@ -1171,7 +1171,7 @@ func TestFluxMonitor_RoundTimeoutCausesPoll_timesOutAtZero(t *testing.T) { tm.fluxAggregator.On("Address").Return(common.Address{}) tm.fluxAggregator.On("GetOracles", nilOpts).Return(oracles, nil) - require.NoError(t, fm.SetOracleAddress()) + require.NoError(t, fm.SetOracleAddress(tests.Context(t))) fm.ExportedRoundState(t) servicetest.Run(t, fm) @@ -1506,7 +1506,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) { Return(nil) tm.fluxAggregator.On("GetOracles", nilOpts).Return(oracles, nil) - require.NoError(t, fm.SetOracleAddress()) + require.NoError(t, fm.SetOracleAddress(tests.Context(t))) tm.fluxAggregator.On("LatestRoundData", nilOpts).Return(flux_aggregator_wrapper.LatestRoundData{ Answer: big.NewInt(10), @@ -1635,7 +1635,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) { Once() tm.fluxAggregator.On("GetOracles", nilOpts).Return(oracles, nil) - require.NoError(t, fm.SetOracleAddress()) + require.NoError(t, fm.SetOracleAddress(tests.Context(t))) fm.ExportedPollIfEligible(0, 0) // Now fire off the NewRound log and ensure it does not respond this time @@ -1732,7 +1732,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) { Once() tm.fluxAggregator.On("GetOracles", nilOpts).Return(oracles, nil) - require.NoError(t, fm.SetOracleAddress()) + require.NoError(t, fm.SetOracleAddress(tests.Context(t))) fm.ExportedPollIfEligible(0, 0) // Now fire off the NewRound log and ensure it does not respond this time diff --git a/core/services/fluxmonitorv2/helpers_test.go b/core/services/fluxmonitorv2/helpers_test.go index d321ddc35c..80db82351c 100644 --- a/core/services/fluxmonitorv2/helpers_test.go +++ b/core/services/fluxmonitorv2/helpers_test.go @@ -19,11 +19,15 @@ func (fm *FluxMonitor) Format(f fmt.State, verb rune) { } func (fm *FluxMonitor) ExportedPollIfEligible(threshold, absoluteThreshold float64) { - fm.pollIfEligible(PollRequestTypePoll, NewDeviationChecker(threshold, absoluteThreshold, fm.logger), nil) + ctx, cancel := fm.eng.NewCtx() + defer cancel() + fm.pollIfEligible(ctx, PollRequestTypePoll, NewDeviationChecker(threshold, absoluteThreshold, fm.logger), nil) } func (fm *FluxMonitor) ExportedProcessLogs() { - fm.processLogs() + ctx, cancel := fm.eng.NewCtx() + defer cancel() + fm.processLogs(ctx) } func (fm *FluxMonitor) ExportedBacklog() *utils.BoundedPriorityQueue[log.Broadcast] { @@ -36,7 +40,9 @@ func (fm *FluxMonitor) ExportedRoundState(t *testing.T) { } func (fm *FluxMonitor) ExportedRespondToNewRoundLog(log *flux_aggregator_wrapper.FluxAggregatorNewRound, broadcast log.Broadcast) { - fm.respondToNewRoundLog(*log, broadcast) + ctx, cancel := fm.eng.NewCtx() + defer cancel() + fm.respondToNewRoundLog(ctx, *log, broadcast) } func (fm *FluxMonitor) ExportedRespondToFlagsRaisedLog() { diff --git a/core/services/fluxmonitorv2/poll_manager.go b/core/services/fluxmonitorv2/poll_manager.go index 78b99aec4d..aca6c75a31 100644 --- a/core/services/fluxmonitorv2/poll_manager.go +++ b/core/services/fluxmonitorv2/poll_manager.go @@ -5,8 +5,8 @@ import ( "sync/atomic" "time" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -64,7 +64,7 @@ type PollManager struct { } // NewPollManager initializes a new PollManager -func NewPollManager(cfg PollManagerConfig, logger logger.Logger) (*PollManager, error) { +func NewPollManager(cfg PollManagerConfig, lggr logger.Logger) (*PollManager, error) { minBackoffDuration := cfg.MinRetryBackoffDuration if cfg.IdleTimerPeriod < minBackoffDuration { minBackoffDuration = cfg.IdleTimerPeriod @@ -82,7 +82,7 @@ func NewPollManager(cfg PollManagerConfig, logger logger.Logger) (*PollManager, p := &PollManager{ cfg: cfg, - logger: logger.Named("PollManager"), + logger: logger.Named(lggr, "PollManager"), hibernationTimer: utils.NewResettableTimer(), pollTicker: utils.NewPausableTicker(cfg.PollTickerInterval), @@ -277,7 +277,7 @@ func (pm *PollManager) startIdleTimer(roundStartedAtUTC uint64) { deadline := startedAt.Add(pm.cfg.IdleTimerPeriod) deadlineDuration := time.Until(deadline) - log := pm.logger.With( + log := logger.With(pm.logger, "pollFrequency", pm.cfg.PollTickerInterval, "idleDuration", pm.cfg.IdleTimerPeriod, "startedAt", roundStartedAtUTC, @@ -300,7 +300,7 @@ func (pm *PollManager) startIdleTimer(roundStartedAtUTC uint64) { // startRoundTimer starts the round timer func (pm *PollManager) startRoundTimer(roundTimesOutAt uint64) { - log := pm.logger.With( + log := logger.With(pm.logger, "pollFrequency", pm.cfg.PollTickerInterval, "idleDuration", pm.cfg.IdleTimerPeriod, "timesOutAt", roundTimesOutAt, diff --git a/core/services/nurse.go b/core/services/nurse.go index a9069b5181..7f3cad13e7 100644 --- a/core/services/nurse.go +++ b/core/services/nurse.go @@ -3,6 +3,7 @@ package services import ( "bytes" "compress/gzip" + "context" "fmt" "io/fs" "os" @@ -19,22 +20,21 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/timeutil" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/utils" ) type Nurse struct { - services.StateMachine + services.Service + eng *services.Engine cfg Config - log logger.Logger checks map[string]CheckFunc checksMu sync.RWMutex chGather chan gatherRequest - chStop chan struct{} - wgDone sync.WaitGroup } type Config interface { @@ -66,85 +66,63 @@ const ( ) func NewNurse(cfg Config, log logger.Logger) *Nurse { - return &Nurse{ + n := &Nurse{ cfg: cfg, - log: log.Named("Nurse"), checks: make(map[string]CheckFunc), chGather: make(chan gatherRequest, 1), - chStop: make(chan struct{}), } + n.Service, n.eng = services.Config{ + Name: "Nurse", + Start: n.start, + }.NewServiceEngine(log) + + return n } -func (n *Nurse) Start() error { - return n.StartOnce("Nurse", func() error { - // This must be set *once*, and it must occur as early as possible - if n.cfg.MemProfileRate() != runtime.MemProfileRate { - runtime.MemProfileRate = n.cfg.BlockProfileRate() - } +func (n *Nurse) start(_ context.Context) error { + // This must be set *once*, and it must occur as early as possible + if n.cfg.MemProfileRate() != runtime.MemProfileRate { + runtime.MemProfileRate = n.cfg.BlockProfileRate() + } - n.log.Debugf("Starting nurse with config %+v", n.cfg) - runtime.SetCPUProfileRate(n.cfg.CPUProfileRate()) - runtime.SetBlockProfileRate(n.cfg.BlockProfileRate()) - runtime.SetMutexProfileFraction(n.cfg.MutexProfileFraction()) + n.eng.Debugf("Starting nurse with config %+v", n.cfg) + runtime.SetCPUProfileRate(n.cfg.CPUProfileRate()) + runtime.SetBlockProfileRate(n.cfg.BlockProfileRate()) + runtime.SetMutexProfileFraction(n.cfg.MutexProfileFraction()) - err := utils.EnsureDirAndMaxPerms(n.cfg.ProfileRoot(), 0744) - if err != nil { - return err - } + err := utils.EnsureDirAndMaxPerms(n.cfg.ProfileRoot(), 0744) + if err != nil { + return err + } - n.AddCheck("mem", n.checkMem) - n.AddCheck("goroutines", n.checkGoroutines) - - n.wgDone.Add(1) - // Checker - go func() { - defer n.wgDone.Done() - for { - select { - case <-n.chStop: - return - case <-time.After(n.cfg.PollInterval().Duration()): - } - - func() { - n.checksMu.RLock() - defer n.checksMu.RUnlock() - for reason, checkFunc := range n.checks { - if unwell, meta := checkFunc(); unwell { - n.GatherVitals(reason, meta) - break - } - } - }() - } - }() - - n.wgDone.Add(1) - // Responder - go func() { - defer n.wgDone.Done() - for { - select { - case <-n.chStop: - return - case req := <-n.chGather: - n.gatherVitals(req.reason, req.meta) - } - } - }() + n.AddCheck("mem", n.checkMem) + n.AddCheck("goroutines", n.checkGoroutines) - return nil + // Checker + n.eng.GoTick(timeutil.NewTicker(n.cfg.PollInterval().Duration), func(ctx context.Context) { + n.checksMu.RLock() + defer n.checksMu.RUnlock() + for reason, checkFunc := range n.checks { + if unwell, meta := checkFunc(); unwell { + n.GatherVitals(ctx, reason, meta) + break + } + } }) -} -func (n *Nurse) Close() error { - return n.StopOnce("Nurse", func() error { - n.log.Debug("Nurse closing...") - defer n.log.Debug("Nurse closed") - close(n.chStop) - n.wgDone.Wait() - return nil + // Responder + n.eng.Go(func(ctx context.Context) { + for { + select { + case <-ctx.Done(): + return + case req := <-n.chGather: + n.gatherVitals(req.reason, req.meta) + } + } }) + + return nil } func (n *Nurse) AddCheck(reason string, checkFunc CheckFunc) { @@ -153,9 +131,9 @@ func (n *Nurse) AddCheck(reason string, checkFunc CheckFunc) { n.checks[reason] = checkFunc } -func (n *Nurse) GatherVitals(reason string, meta Meta) { +func (n *Nurse) GatherVitals(ctx context.Context, reason string, meta Meta) { select { - case <-n.chStop: + case <-ctx.Done(): case n.chGather <- gatherRequest{reason, meta}: default: } @@ -189,14 +167,14 @@ func (n *Nurse) checkGoroutines() (bool, Meta) { func (n *Nurse) gatherVitals(reason string, meta Meta) { loggerFields := (logger.Fields{"reason": reason}).Merge(logger.Fields(meta)) - n.log.Debugw("Nurse is gathering vitals", loggerFields.Slice()...) + n.eng.Debugw("Nurse is gathering vitals", loggerFields.Slice()...) size, err := n.totalProfileBytes() if err != nil { - n.log.Errorw("could not fetch total profile bytes", loggerFields.With("err", err).Slice()...) + n.eng.Errorw("could not fetch total profile bytes", loggerFields.With("err", err).Slice()...) return } else if size >= uint64(n.cfg.MaxProfileSize()) { - n.log.Warnw("cannot write pprof profile, total profile size exceeds configured PPROF_MAX_PROFILE_SIZE", + n.eng.Warnw("cannot write pprof profile, total profile size exceeds configured PPROF_MAX_PROFILE_SIZE", loggerFields.With("total", size, "max", n.cfg.MaxProfileSize()).Slice()..., ) return @@ -206,7 +184,7 @@ func (n *Nurse) gatherVitals(reason string, meta Meta) { err = n.appendLog(now, reason, meta) if err != nil { - n.log.Warnw("cannot write pprof profile", loggerFields.With("err", err).Slice()...) + n.eng.Warnw("cannot write pprof profile", loggerFields.With("err", err).Slice()...) return } var wg sync.WaitGroup @@ -227,7 +205,7 @@ func (n *Nurse) gatherVitals(reason string, meta Meta) { wg.Add(1) go n.gather("heap", now, &wg) } else { - n.log.Info("skipping heap collection because runtime.MemProfileRate = 0") + n.eng.Info("skipping heap collection because runtime.MemProfileRate = 0") } wg.Add(1) @@ -236,15 +214,13 @@ func (n *Nurse) gatherVitals(reason string, meta Meta) { go n.gather("threadcreate", now, &wg) ch := make(chan struct{}) - n.wgDone.Add(1) - go func() { - defer n.wgDone.Done() + n.eng.Go(func(ctx context.Context) { defer close(ch) wg.Wait() - }() + }) select { - case <-n.chStop: + case <-n.eng.StopChan: case <-ch: } } @@ -252,7 +228,7 @@ func (n *Nurse) gatherVitals(reason string, meta Meta) { func (n *Nurse) appendLog(now time.Time, reason string, meta Meta) error { filename := filepath.Join(n.cfg.ProfileRoot(), "nurse.log") - n.log.Debugf("creating nurse log %s", filename) + n.eng.Debugf("creating nurse log %s", filename) file, err := os.Create(filename) if err != nil { @@ -288,34 +264,34 @@ func (n *Nurse) appendLog(now time.Time, reason string, meta Meta) error { func (n *Nurse) gatherCPU(now time.Time, wg *sync.WaitGroup) { defer wg.Done() - n.log.Debugf("gather cpu %d ...", now.UnixMicro()) - defer n.log.Debugf("gather cpu %d done", now.UnixMicro()) + n.eng.Debugf("gather cpu %d ...", now.UnixMicro()) + defer n.eng.Debugf("gather cpu %d done", now.UnixMicro()) wc, err := n.createFile(now, cpuProfName, false) if err != nil { - n.log.Errorw("could not write cpu profile", "err", err) + n.eng.Errorw("could not write cpu profile", "err", err) return } defer wc.Close() err = pprof.StartCPUProfile(wc) if err != nil { - n.log.Errorw("could not start cpu profile", "err", err) + n.eng.Errorw("could not start cpu profile", "err", err) return } select { - case <-n.chStop: - n.log.Debug("gather cpu received stop") + case <-n.eng.StopChan: + n.eng.Debug("gather cpu received stop") case <-time.After(n.cfg.GatherDuration().Duration()): - n.log.Debugf("gather cpu duration elapsed %s. stoping profiling.", n.cfg.GatherDuration().Duration().String()) + n.eng.Debugf("gather cpu duration elapsed %s. stoping profiling.", n.cfg.GatherDuration().Duration().String()) } pprof.StopCPUProfile() err = wc.Close() if err != nil { - n.log.Errorw("could not close cpu profile", "err", err) + n.eng.Errorw("could not close cpu profile", "err", err) return } } @@ -323,23 +299,23 @@ func (n *Nurse) gatherCPU(now time.Time, wg *sync.WaitGroup) { func (n *Nurse) gatherTrace(now time.Time, wg *sync.WaitGroup) { defer wg.Done() - n.log.Debugf("gather trace %d ...", now.UnixMicro()) - defer n.log.Debugf("gather trace %d done", now.UnixMicro()) + n.eng.Debugf("gather trace %d ...", now.UnixMicro()) + defer n.eng.Debugf("gather trace %d done", now.UnixMicro()) wc, err := n.createFile(now, traceProfName, true) if err != nil { - n.log.Errorw("could not write trace profile", "err", err) + n.eng.Errorw("could not write trace profile", "err", err) return } defer wc.Close() err = trace.Start(wc) if err != nil { - n.log.Errorw("could not start trace profile", "err", err) + n.eng.Errorw("could not start trace profile", "err", err) return } select { - case <-n.chStop: + case <-n.eng.StopChan: case <-time.After(n.cfg.GatherTraceDuration().Duration()): } @@ -347,7 +323,7 @@ func (n *Nurse) gatherTrace(now time.Time, wg *sync.WaitGroup) { err = wc.Close() if err != nil { - n.log.Errorw("could not close trace profile", "err", err) + n.eng.Errorw("could not close trace profile", "err", err) return } } @@ -355,18 +331,18 @@ func (n *Nurse) gatherTrace(now time.Time, wg *sync.WaitGroup) { func (n *Nurse) gather(typ string, now time.Time, wg *sync.WaitGroup) { defer wg.Done() - n.log.Debugf("gather %s %d ...", typ, now.UnixMicro()) - n.log.Debugf("gather %s %d done", typ, now.UnixMicro()) + n.eng.Debugf("gather %s %d ...", typ, now.UnixMicro()) + n.eng.Debugf("gather %s %d done", typ, now.UnixMicro()) p := pprof.Lookup(typ) if p == nil { - n.log.Errorf("Invariant violation: pprof type '%v' does not exist", typ) + n.eng.Errorf("Invariant violation: pprof type '%v' does not exist", typ) return } p0, err := collectProfile(p) if err != nil { - n.log.Errorw(fmt.Sprintf("could not collect %v profile", typ), "err", err) + n.eng.Errorw(fmt.Sprintf("could not collect %v profile", typ), "err", err) return } @@ -374,14 +350,14 @@ func (n *Nurse) gather(typ string, now time.Time, wg *sync.WaitGroup) { defer t.Stop() select { - case <-n.chStop: + case <-n.eng.StopChan: return case <-t.C: } p1, err := collectProfile(p) if err != nil { - n.log.Errorw(fmt.Sprintf("could not collect %v profile", typ), "err", err) + n.eng.Errorw(fmt.Sprintf("could not collect %v profile", typ), "err", err) return } ts := p1.TimeNanos @@ -391,7 +367,7 @@ func (n *Nurse) gather(typ string, now time.Time, wg *sync.WaitGroup) { p1, err = profile.Merge([]*profile.Profile{p0, p1}) if err != nil { - n.log.Errorw(fmt.Sprintf("could not compute delta for %v profile", typ), "err", err) + n.eng.Errorw(fmt.Sprintf("could not compute delta for %v profile", typ), "err", err) return } @@ -400,19 +376,19 @@ func (n *Nurse) gather(typ string, now time.Time, wg *sync.WaitGroup) { wc, err := n.createFile(now, typ, false) if err != nil { - n.log.Errorw(fmt.Sprintf("could not write %v profile", typ), "err", err) + n.eng.Errorw(fmt.Sprintf("could not write %v profile", typ), "err", err) return } defer wc.Close() err = p1.Write(wc) if err != nil { - n.log.Errorw(fmt.Sprintf("could not write %v profile", typ), "err", err) + n.eng.Errorw(fmt.Sprintf("could not write %v profile", typ), "err", err) return } err = wc.Close() if err != nil { - n.log.Errorw(fmt.Sprintf("could not close file for %v profile", typ), "err", err) + n.eng.Errorw(fmt.Sprintf("could not close file for %v profile", typ), "err", err) return } } @@ -437,7 +413,7 @@ func (n *Nurse) createFile(now time.Time, typ string, shouldGzip bool) (*utils.D filename += ".gz" } fullpath := filepath.Join(n.cfg.ProfileRoot(), filename) - n.log.Debugf("creating file %s", fullpath) + n.eng.Debugf("creating file %s", fullpath) file, err := os.Create(fullpath) if err != nil { diff --git a/core/services/nurse_test.go b/core/services/nurse_test.go index 4597eeb456..ed6f6872dc 100644 --- a/core/services/nurse_test.go +++ b/core/services/nurse_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -102,7 +103,7 @@ func TestNurse(t *testing.T) { nrse := NewNurse(newMockConfig(t), l) nrse.AddCheck("test", func() (bool, Meta) { return true, Meta{} }) - require.NoError(t, nrse.Start()) + require.NoError(t, nrse.Start(tests.Context(t))) defer func() { require.NoError(t, nrse.Close()) }() require.NoError(t, nrse.appendLog(time.Now(), "test", Meta{})) diff --git a/core/services/relay/evm/functions/logpoller_wrapper.go b/core/services/relay/evm/functions/logpoller_wrapper.go index 559b1ec33f..b0d04b1187 100644 --- a/core/services/relay/evm/functions/logpoller_wrapper.go +++ b/core/services/relay/evm/functions/logpoller_wrapper.go @@ -22,7 +22,8 @@ import ( ) type logPollerWrapper struct { - services.StateMachine + services.Service + eng *services.Engine routerContract *functions_router.FunctionsRouter pluginConfig config.PluginConfig @@ -38,9 +39,6 @@ type logPollerWrapper struct { detectedRequests detectedEvents detectedResponses detectedEvents mu sync.Mutex - closeWait sync.WaitGroup - stopCh services.StopChan - lggr logger.Logger } type detectedEvent struct { @@ -94,7 +92,7 @@ func NewLogPollerWrapper(routerContractAddress common.Address, pluginConfig conf return nil, errors.Errorf("invalid config: number of required confirmation blocks >= pastBlocksToPoll") } - return &logPollerWrapper{ + w := &logPollerWrapper{ routerContract: routerContract, pluginConfig: pluginConfig, requestBlockOffset: requestBlockOffset, @@ -106,40 +104,25 @@ func NewLogPollerWrapper(routerContractAddress common.Address, pluginConfig conf logPoller: logPoller, client: client, subscribers: make(map[string]evmRelayTypes.RouteUpdateSubscriber), - stopCh: make(services.StopChan), - lggr: lggr.Named("LogPollerWrapper"), - }, nil -} - -func (l *logPollerWrapper) Start(context.Context) error { - return l.StartOnce("LogPollerWrapper", func() error { - l.lggr.Infow("starting LogPollerWrapper", "routerContract", l.routerContract.Address().Hex(), "contractVersion", l.pluginConfig.ContractVersion) - l.mu.Lock() - defer l.mu.Unlock() - if l.pluginConfig.ContractVersion != 1 { - return errors.New("only contract version 1 is supported") - } - l.closeWait.Add(1) - go l.checkForRouteUpdates() - return nil - }) -} - -func (l *logPollerWrapper) Close() error { - return l.StopOnce("LogPollerWrapper", func() (err error) { - l.lggr.Info("closing LogPollerWrapper") - close(l.stopCh) - l.closeWait.Wait() - return nil - }) + } + w.Service, w.eng = services.Config{ + Name: "LoggPollerWrapper", + Start: w.start, + }.NewServiceEngine(lggr) + return w, nil } -func (l *logPollerWrapper) HealthReport() map[string]error { - return map[string]error{l.Name(): l.Ready()} +func (l *logPollerWrapper) start(context.Context) error { + l.eng.Infow("starting LogPollerWrapper", "routerContract", l.routerContract.Address().Hex(), "contractVersion", l.pluginConfig.ContractVersion) + l.mu.Lock() + defer l.mu.Unlock() + if l.pluginConfig.ContractVersion != 1 { + return errors.New("only contract version 1 is supported") + } + l.eng.Go(l.checkForRouteUpdates) + return nil } -func (l *logPollerWrapper) Name() string { return l.lggr.Name() } - // methods of LogPollerWrapper func (l *logPollerWrapper) LatestEvents(ctx context.Context) ([]evmRelayTypes.OracleRequest, []evmRelayTypes.OracleResponse, error) { l.mu.Lock() @@ -166,7 +149,7 @@ func (l *logPollerWrapper) LatestEvents(ctx context.Context) ([]evmRelayTypes.Or resultsReq := []evmRelayTypes.OracleRequest{} resultsResp := []evmRelayTypes.OracleResponse{} if len(coordinators) == 0 { - l.lggr.Debug("LatestEvents: no non-zero coordinators to check") + l.eng.Debug("LatestEvents: no non-zero coordinators to check") return resultsReq, resultsResp, errors.New("no non-zero coordinators to check") } @@ -174,32 +157,32 @@ func (l *logPollerWrapper) LatestEvents(ctx context.Context) ([]evmRelayTypes.Or requestEndBlock := latestBlockNum - l.requestBlockOffset requestLogs, err := l.logPoller.Logs(ctx, startBlockNum, requestEndBlock, functions_coordinator.FunctionsCoordinatorOracleRequest{}.Topic(), coordinator) if err != nil { - l.lggr.Errorw("LatestEvents: fetching request logs from LogPoller failed", "startBlock", startBlockNum, "endBlock", requestEndBlock) + l.eng.Errorw("LatestEvents: fetching request logs from LogPoller failed", "startBlock", startBlockNum, "endBlock", requestEndBlock) return nil, nil, err } - l.lggr.Debugw("LatestEvents: fetched request logs", "nRequestLogs", len(requestLogs), "latestBlock", latest, "startBlock", startBlockNum, "endBlock", requestEndBlock) + l.eng.Debugw("LatestEvents: fetched request logs", "nRequestLogs", len(requestLogs), "latestBlock", latest, "startBlock", startBlockNum, "endBlock", requestEndBlock) requestLogs = l.filterPreviouslyDetectedEvents(requestLogs, &l.detectedRequests, "requests") responseEndBlock := latestBlockNum - l.responseBlockOffset responseLogs, err := l.logPoller.Logs(ctx, startBlockNum, responseEndBlock, functions_coordinator.FunctionsCoordinatorOracleResponse{}.Topic(), coordinator) if err != nil { - l.lggr.Errorw("LatestEvents: fetching response logs from LogPoller failed", "startBlock", startBlockNum, "endBlock", responseEndBlock) + l.eng.Errorw("LatestEvents: fetching response logs from LogPoller failed", "startBlock", startBlockNum, "endBlock", responseEndBlock) return nil, nil, err } - l.lggr.Debugw("LatestEvents: fetched request logs", "nResponseLogs", len(responseLogs), "latestBlock", latest, "startBlock", startBlockNum, "endBlock", responseEndBlock) + l.eng.Debugw("LatestEvents: fetched request logs", "nResponseLogs", len(responseLogs), "latestBlock", latest, "startBlock", startBlockNum, "endBlock", responseEndBlock) responseLogs = l.filterPreviouslyDetectedEvents(responseLogs, &l.detectedResponses, "responses") parsingContract, err := functions_coordinator.NewFunctionsCoordinator(coordinator, l.client) if err != nil { - l.lggr.Error("LatestEvents: creating a contract instance for parsing failed") + l.eng.Error("LatestEvents: creating a contract instance for parsing failed") return nil, nil, err } - l.lggr.Debugw("LatestEvents: parsing logs", "nRequestLogs", len(requestLogs), "nResponseLogs", len(responseLogs), "coordinatorAddress", coordinator.Hex()) + l.eng.Debugw("LatestEvents: parsing logs", "nRequestLogs", len(requestLogs), "nResponseLogs", len(responseLogs), "coordinatorAddress", coordinator.Hex()) for _, log := range requestLogs { gethLog := log.ToGethLog() oracleRequest, err := parsingContract.ParseOracleRequest(gethLog) if err != nil { - l.lggr.Errorw("LatestEvents: failed to parse a request log, skipping", "err", err) + l.eng.Errorw("LatestEvents: failed to parse a request log, skipping", "err", err) continue } @@ -212,7 +195,7 @@ func (l *logPollerWrapper) LatestEvents(ctx context.Context) ([]evmRelayTypes.Or bytes32Type, errType7 := abi.NewType("bytes32", "bytes32", nil) if errType1 != nil || errType2 != nil || errType3 != nil || errType4 != nil || errType5 != nil || errType6 != nil || errType7 != nil { - l.lggr.Errorw("LatestEvents: failed to initialize types", "errType1", errType1, + l.eng.Errorw("LatestEvents: failed to initialize types", "errType1", errType1, "errType2", errType2, "errType3", errType3, "errType4", errType4, "errType5", errType5, "errType6", errType6, "errType7", errType7, ) continue @@ -244,7 +227,7 @@ func (l *logPollerWrapper) LatestEvents(ctx context.Context) ([]evmRelayTypes.Or oracleRequest.Commitment.TimeoutTimestamp, ) if err != nil { - l.lggr.Errorw("LatestEvents: failed to pack commitment bytes, skipping", "err", err) + l.eng.Errorw("LatestEvents: failed to pack commitment bytes, skipping", "err", err) } resultsReq = append(resultsReq, evmRelayTypes.OracleRequest{ @@ -266,7 +249,7 @@ func (l *logPollerWrapper) LatestEvents(ctx context.Context) ([]evmRelayTypes.Or gethLog := log.ToGethLog() oracleResponse, err := parsingContract.ParseOracleResponse(gethLog) if err != nil { - l.lggr.Errorw("LatestEvents: failed to parse a response log, skipping") + l.eng.Errorw("LatestEvents: failed to parse a response log, skipping") continue } resultsResp = append(resultsResp, evmRelayTypes.OracleResponse{ @@ -275,13 +258,13 @@ func (l *logPollerWrapper) LatestEvents(ctx context.Context) ([]evmRelayTypes.Or } } - l.lggr.Debugw("LatestEvents: done", "nRequestLogs", len(resultsReq), "nResponseLogs", len(resultsResp), "startBlock", startBlockNum, "endBlock", latestBlockNum) + l.eng.Debugw("LatestEvents: done", "nRequestLogs", len(resultsReq), "nResponseLogs", len(resultsResp), "startBlock", startBlockNum, "endBlock", latestBlockNum) return resultsReq, resultsResp, nil } func (l *logPollerWrapper) filterPreviouslyDetectedEvents(logs []logpoller.Log, detectedEvents *detectedEvents, filterType string) []logpoller.Log { if len(logs) > maxLogsToProcess { - l.lggr.Errorw("filterPreviouslyDetectedEvents: too many logs to process, only processing latest maxLogsToProcess logs", "filterType", filterType, "nLogs", len(logs), "maxLogsToProcess", maxLogsToProcess) + l.eng.Errorw("filterPreviouslyDetectedEvents: too many logs to process, only processing latest maxLogsToProcess logs", "filterType", filterType, "nLogs", len(logs), "maxLogsToProcess", maxLogsToProcess) logs = logs[len(logs)-maxLogsToProcess:] } l.mu.Lock() @@ -290,7 +273,7 @@ func (l *logPollerWrapper) filterPreviouslyDetectedEvents(logs []logpoller.Log, for _, log := range logs { var requestId [32]byte if len(log.Topics) < 2 || len(log.Topics[1]) != 32 { - l.lggr.Errorw("filterPreviouslyDetectedEvents: invalid log, skipping", "filterType", filterType, "log", log) + l.eng.Errorw("filterPreviouslyDetectedEvents: invalid log, skipping", "filterType", filterType, "log", log) continue } copy(requestId[:], log.Topics[1]) // requestId is the second topic (1st topic is the event signature) @@ -310,7 +293,7 @@ func (l *logPollerWrapper) filterPreviouslyDetectedEvents(logs []logpoller.Log, expiredRequests++ } detectedEvents.detectedEventsOrdered = detectedEvents.detectedEventsOrdered[expiredRequests:] - l.lggr.Debugw("filterPreviouslyDetectedEvents: done", "filterType", filterType, "nLogs", len(logs), "nFilteredLogs", len(filteredLogs), "nExpiredRequests", expiredRequests, "previouslyDetectedCacheSize", len(detectedEvents.detectedEventsOrdered)) + l.eng.Debugw("filterPreviouslyDetectedEvents: done", "filterType", filterType, "nLogs", len(logs), "nFilteredLogs", len(filteredLogs), "nExpiredRequests", expiredRequests, "previouslyDetectedCacheSize", len(detectedEvents.detectedEventsOrdered)) return filteredLogs } @@ -319,7 +302,7 @@ func (l *logPollerWrapper) SubscribeToUpdates(ctx context.Context, subscriberNam if l.pluginConfig.ContractVersion == 0 { // in V0, immediately set contract address to Oracle contract and never update again if err := subscriber.UpdateRoutes(ctx, l.routerContract.Address(), l.routerContract.Address()); err != nil { - l.lggr.Errorw("LogPollerWrapper: Failed to update routes", "subscriberName", subscriberName, "err", err) + l.eng.Errorw("LogPollerWrapper: Failed to update routes", "subscriberName", subscriberName, "err", err) } } else if l.pluginConfig.ContractVersion == 1 { l.mu.Lock() @@ -328,37 +311,36 @@ func (l *logPollerWrapper) SubscribeToUpdates(ctx context.Context, subscriberNam } } -func (l *logPollerWrapper) checkForRouteUpdates() { - defer l.closeWait.Done() +func (l *logPollerWrapper) checkForRouteUpdates(ctx context.Context) { freqSec := l.pluginConfig.ContractUpdateCheckFrequencySec if freqSec == 0 { - l.lggr.Errorw("LogPollerWrapper: ContractUpdateCheckFrequencySec is zero - route update checks disabled") + l.eng.Errorw("LogPollerWrapper: ContractUpdateCheckFrequencySec is zero - route update checks disabled") return } - updateOnce := func() { + updateOnce := func(ctx context.Context) { // NOTE: timeout == frequency here, could be changed to a separate config value timeout := time.Duration(l.pluginConfig.ContractUpdateCheckFrequencySec) * time.Second - ctx, cancel := l.stopCh.CtxCancel(context.WithTimeout(context.Background(), timeout)) + ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() active, proposed, err := l.getCurrentCoordinators(ctx) if err != nil { - l.lggr.Errorw("LogPollerWrapper: error calling getCurrentCoordinators", "err", err) + l.eng.Errorw("LogPollerWrapper: error calling getCurrentCoordinators", "err", err) return } l.handleRouteUpdate(ctx, active, proposed) } - updateOnce() // update once right away + updateOnce(ctx) // update once right away ticker := time.NewTicker(time.Duration(freqSec) * time.Second) defer ticker.Stop() for { select { - case <-l.stopCh: + case <-ctx.Done(): return case <-ticker.C: - updateOnce() + updateOnce(ctx) } } } @@ -394,22 +376,22 @@ func (l *logPollerWrapper) handleRouteUpdate(ctx context.Context, activeCoordina defer l.mu.Unlock() if activeCoordinator == (common.Address{}) { - l.lggr.Error("LogPollerWrapper: cannot update activeCoordinator to zero address") + l.eng.Error("LogPollerWrapper: cannot update activeCoordinator to zero address") return } if activeCoordinator == l.activeCoordinator && proposedCoordinator == l.proposedCoordinator { - l.lggr.Debug("LogPollerWrapper: no changes to routes") + l.eng.Debug("LogPollerWrapper: no changes to routes") return } errActive := l.registerFilters(ctx, activeCoordinator) errProposed := l.registerFilters(ctx, proposedCoordinator) if errActive != nil || errProposed != nil { - l.lggr.Errorw("LogPollerWrapper: Failed to register filters", "errorActive", errActive, "errorProposed", errProposed) + l.eng.Errorw("LogPollerWrapper: Failed to register filters", "errorActive", errActive, "errorProposed", errProposed) return } - l.lggr.Debugw("LogPollerWrapper: new routes", "activeCoordinator", activeCoordinator.Hex(), "proposedCoordinator", proposedCoordinator.Hex()) + l.eng.Debugw("LogPollerWrapper: new routes", "activeCoordinator", activeCoordinator.Hex(), "proposedCoordinator", proposedCoordinator.Hex()) l.activeCoordinator = activeCoordinator l.proposedCoordinator = proposedCoordinator @@ -417,7 +399,7 @@ func (l *logPollerWrapper) handleRouteUpdate(ctx context.Context, activeCoordina for _, subscriber := range l.subscribers { err := subscriber.UpdateRoutes(ctx, activeCoordinator, proposedCoordinator) if err != nil { - l.lggr.Errorw("LogPollerWrapper: Failed to update routes", "err", err) + l.eng.Errorw("LogPollerWrapper: Failed to update routes", "err", err) } } @@ -430,9 +412,9 @@ func (l *logPollerWrapper) handleRouteUpdate(ctx context.Context, activeCoordina continue } if err := l.logPoller.UnregisterFilter(ctx, filter.Name); err != nil { - l.lggr.Errorw("LogPollerWrapper: Failed to unregister filter", "filterName", filter.Name, "err", err) + l.eng.Errorw("LogPollerWrapper: Failed to unregister filter", "filterName", filter.Name, "err", err) } - l.lggr.Debugw("LogPollerWrapper: Successfully unregistered filter", "filterName", filter.Name) + l.eng.Debugw("LogPollerWrapper: Successfully unregistered filter", "filterName", filter.Name) } } diff --git a/core/services/synchronization/helpers_test.go b/core/services/synchronization/helpers_test.go index 7bb2dde763..aea9bf77f4 100644 --- a/core/services/synchronization/helpers_test.go +++ b/core/services/synchronization/helpers_test.go @@ -12,15 +12,15 @@ import ( // NewTestTelemetryIngressClient calls NewTelemetryIngressClient and injects telemClient. func NewTestTelemetryIngressClient(t *testing.T, url *url.URL, serverPubKeyHex string, ks keystore.CSA, logging bool, telemClient telemPb.TelemClient) TelemetryService { - tc := NewTelemetryIngressClient(url, serverPubKeyHex, ks, logging, logger.TestLogger(t), 100, "test", "test") + tc := NewTelemetryIngressClient(url, serverPubKeyHex, ks, logging, logger.TestLogger(t), 100) tc.(*telemetryIngressClient).telemClient = telemClient return tc } // NewTestTelemetryIngressBatchClient calls NewTelemetryIngressBatchClient and injects telemClient. func NewTestTelemetryIngressBatchClient(t *testing.T, url *url.URL, serverPubKeyHex string, ks keystore.CSA, logging bool, telemClient telemPb.TelemClient, sendInterval time.Duration, uniconn bool) TelemetryService { - tc := NewTelemetryIngressBatchClient(url, serverPubKeyHex, ks, logging, logger.TestLogger(t), 100, 50, sendInterval, time.Second, uniconn, "test", "test") - tc.(*telemetryIngressBatchClient).close = func() error { return nil } + tc := NewTelemetryIngressBatchClient(url, serverPubKeyHex, ks, logging, logger.TestLogger(t), 100, 50, sendInterval, time.Second, uniconn) + tc.(*telemetryIngressBatchClient).closeFn = func() error { return nil } tc.(*telemetryIngressBatchClient).telemClient = telemClient return tc } diff --git a/core/services/synchronization/telemetry_ingress_batch_client.go b/core/services/synchronization/telemetry_ingress_batch_client.go index cade98cf60..26ce1e3066 100644 --- a/core/services/synchronization/telemetry_ingress_batch_client.go +++ b/core/services/synchronization/telemetry_ingress_batch_client.go @@ -12,8 +12,9 @@ import ( "github.com/smartcontractkit/wsrpc" "github.com/smartcontractkit/wsrpc/examples/simple/keys" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink-common/pkg/timeutil" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" telemPb "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" ) @@ -37,21 +38,18 @@ func (NoopTelemetryIngressBatchClient) Name() string { return func (NoopTelemetryIngressBatchClient) Ready() error { return nil } type telemetryIngressBatchClient struct { - services.StateMachine + services.Service + eng *services.Engine + url *url.URL ks keystore.CSA serverPubKeyHex string connected atomic.Bool telemClient telemPb.TelemClient - close func() error - - globalLogger logger.Logger - logging bool - lggr logger.Logger + closeFn func() error - wgDone sync.WaitGroup - chDone services.StopChan + logging bool telemBufferSize uint telemMaxBatchSize uint @@ -66,8 +64,8 @@ type telemetryIngressBatchClient struct { // NewTelemetryIngressBatchClient returns a client backed by wsrpc that // can send telemetry to the telemetry ingress server -func NewTelemetryIngressBatchClient(url *url.URL, serverPubKeyHex string, ks keystore.CSA, logging bool, lggr logger.Logger, telemBufferSize uint, telemMaxBatchSize uint, telemSendInterval time.Duration, telemSendTimeout time.Duration, useUniconn bool, network string, chainID string) TelemetryService { - return &telemetryIngressBatchClient{ +func NewTelemetryIngressBatchClient(url *url.URL, serverPubKeyHex string, ks keystore.CSA, logging bool, lggr logger.Logger, telemBufferSize uint, telemMaxBatchSize uint, telemSendInterval time.Duration, telemSendTimeout time.Duration, useUniconn bool) TelemetryService { + c := &telemetryIngressBatchClient{ telemBufferSize: telemBufferSize, telemMaxBatchSize: telemMaxBatchSize, telemSendInterval: telemSendInterval, @@ -75,13 +73,17 @@ func NewTelemetryIngressBatchClient(url *url.URL, serverPubKeyHex string, ks key url: url, ks: ks, serverPubKeyHex: serverPubKeyHex, - globalLogger: lggr, logging: logging, - lggr: lggr.Named("TelemetryIngressBatchClient").Named(network).Named(chainID), - chDone: make(services.StopChan), workers: make(map[string]*telemetryIngressBatchWorker), useUniConn: useUniconn, } + c.Service, c.eng = services.Config{ + Name: "TelemetryIngressBatchClient", + Start: c.start, + Close: c.close, + }.NewServiceEngine(lggr) + + return c } // Start connects the wsrpc client to the telemetry ingress server @@ -90,71 +92,53 @@ func NewTelemetryIngressBatchClient(url *url.URL, serverPubKeyHex string, ks key // an error and wsrpc will continue to retry the connection. Eventually when the ingress // server does come back up, wsrpc will establish the connection without any interaction // on behalf of the node operator. -func (tc *telemetryIngressBatchClient) Start(ctx context.Context) error { - return tc.StartOnce("TelemetryIngressBatchClient", func() error { - clientPrivKey, err := tc.getCSAPrivateKey() - if err != nil { - return err - } +func (tc *telemetryIngressBatchClient) start(ctx context.Context) error { + clientPrivKey, err := tc.getCSAPrivateKey() + if err != nil { + return err + } - serverPubKey := keys.FromHex(tc.serverPubKeyHex) - - // Initialize a new wsrpc client caller - // This is used to call RPC methods on the server - if tc.telemClient == nil { // only preset for tests - if tc.useUniConn { - tc.wgDone.Add(1) - go func() { - defer tc.wgDone.Done() - ctx2, cancel := tc.chDone.NewCtx() - defer cancel() - conn, err := wsrpc.DialUniWithContext(ctx2, tc.lggr, tc.url.String(), clientPrivKey, serverPubKey) - if err != nil { - if ctx2.Err() != nil { - tc.lggr.Warnw("gave up connecting to telemetry endpoint", "err", err) - } else { - tc.lggr.Criticalw("telemetry endpoint dial errored unexpectedly", "err", err, "server pubkey", tc.serverPubKeyHex) - tc.SvcErrBuffer.Append(err) - } - return - } - tc.telemClient = telemPb.NewTelemClient(conn) - tc.close = conn.Close - tc.connected.Store(true) - }() - } else { - // Spawns a goroutine that will eventually connect - conn, err := wsrpc.DialWithContext(ctx, tc.url.String(), wsrpc.WithTransportCreds(clientPrivKey, serverPubKey), wsrpc.WithLogger(tc.lggr)) + serverPubKey := keys.FromHex(tc.serverPubKeyHex) + + // Initialize a new wsrpc client caller + // This is used to call RPC methods on the server + if tc.telemClient == nil { // only preset for tests + if tc.useUniConn { + tc.eng.Go(func(ctx context.Context) { + conn, err := wsrpc.DialUniWithContext(ctx, tc.eng, tc.url.String(), clientPrivKey, serverPubKey) if err != nil { - return fmt.Errorf("could not start TelemIngressBatchClient, Dial returned error: %v", err) + if ctx.Err() != nil { + tc.eng.Warnw("gave up connecting to telemetry endpoint", "err", err) + } else { + tc.eng.Criticalw("telemetry endpoint dial errored unexpectedly", "err", err, "server pubkey", tc.serverPubKeyHex) + tc.eng.EmitHealthErr(err) + } + return } tc.telemClient = telemPb.NewTelemClient(conn) - tc.close = func() error { conn.Close(); return nil } + tc.closeFn = conn.Close + tc.connected.Store(true) + }) + } else { + // Spawns a goroutine that will eventually connect + conn, err := wsrpc.DialWithContext(ctx, tc.url.String(), wsrpc.WithTransportCreds(clientPrivKey, serverPubKey), wsrpc.WithLogger(tc.eng)) + if err != nil { + return fmt.Errorf("could not start TelemIngressBatchClient, Dial returned error: %v", err) } + tc.telemClient = telemPb.NewTelemClient(conn) + tc.closeFn = func() error { conn.Close(); return nil } } + } - return nil - }) + return nil } // Close disconnects the wsrpc client from the ingress server and waits for all workers to exit -func (tc *telemetryIngressBatchClient) Close() error { - return tc.StopOnce("TelemetryIngressBatchClient", func() error { - close(tc.chDone) - tc.wgDone.Wait() - if (tc.useUniConn && tc.connected.Load()) || !tc.useUniConn { - return tc.close() - } - return nil - }) -} - -func (tc *telemetryIngressBatchClient) Name() string { - return tc.lggr.Name() -} - -func (tc *telemetryIngressBatchClient) HealthReport() map[string]error { - return map[string]error{tc.Name(): tc.Healthy()} +func (tc *telemetryIngressBatchClient) close() error { + if (tc.useUniConn && tc.connected.Load()) || !tc.useUniConn { + return tc.closeFn() + } + return nil } // getCSAPrivateKey gets the client's CSA private key @@ -175,7 +159,7 @@ func (tc *telemetryIngressBatchClient) getCSAPrivateKey() (privkey []byte, err e // and a warning is logged. func (tc *telemetryIngressBatchClient) Send(ctx context.Context, telemData []byte, contractID string, telemType TelemetryType) { if tc.useUniConn && !tc.connected.Load() { - tc.lggr.Warnw("not connected to telemetry endpoint", "endpoint", tc.url.String()) + tc.eng.Warnw("not connected to telemetry endpoint", "endpoint", tc.url.String()) return } payload := TelemPayload{ @@ -206,18 +190,17 @@ func (tc *telemetryIngressBatchClient) findOrCreateWorker(payload TelemPayload) if !found { worker = NewTelemetryIngressBatchWorker( tc.telemMaxBatchSize, - tc.telemSendInterval, tc.telemSendTimeout, tc.telemClient, - &tc.wgDone, - tc.chDone, make(chan TelemPayload, tc.telemBufferSize), payload.ContractID, payload.TelemType, - tc.globalLogger, + tc.eng, tc.logging, ) - worker.Start() + tc.eng.GoTick(timeutil.NewTicker(func() time.Duration { + return tc.telemSendInterval + }), worker.Send) tc.workers[workerKey] = worker } diff --git a/core/services/synchronization/telemetry_ingress_batch_worker.go b/core/services/synchronization/telemetry_ingress_batch_worker.go index e7ea659581..7eca26f02c 100644 --- a/core/services/synchronization/telemetry_ingress_batch_worker.go +++ b/core/services/synchronization/telemetry_ingress_batch_worker.go @@ -2,13 +2,12 @@ package synchronization import ( "context" - "sync" "sync/atomic" "time" "github.com/smartcontractkit/chainlink-common/pkg/services" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink-common/pkg/logger" telemPb "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" ) @@ -18,11 +17,8 @@ type telemetryIngressBatchWorker struct { services.Service telemMaxBatchSize uint - telemSendInterval time.Duration telemSendTimeout time.Duration telemClient telemPb.TelemClient - wgDone *sync.WaitGroup - chDone services.StopChan chTelemetry chan TelemPayload contractID string telemType TelemetryType @@ -35,65 +31,45 @@ type telemetryIngressBatchWorker struct { // telemetry to the ingress server via WSRPC func NewTelemetryIngressBatchWorker( telemMaxBatchSize uint, - telemSendInterval time.Duration, telemSendTimeout time.Duration, telemClient telemPb.TelemClient, - wgDone *sync.WaitGroup, - chDone chan struct{}, chTelemetry chan TelemPayload, contractID string, telemType TelemetryType, - globalLogger logger.Logger, + lggr logger.Logger, logging bool, ) *telemetryIngressBatchWorker { return &telemetryIngressBatchWorker{ - telemSendInterval: telemSendInterval, telemSendTimeout: telemSendTimeout, telemMaxBatchSize: telemMaxBatchSize, telemClient: telemClient, - wgDone: wgDone, - chDone: chDone, chTelemetry: chTelemetry, contractID: contractID, telemType: telemType, logging: logging, - lggr: globalLogger.Named("TelemetryIngressBatchWorker"), + lggr: logger.Named(lggr, "TelemetryIngressBatchWorker"), } } -// Start sends batched telemetry to the ingress server on an interval -func (tw *telemetryIngressBatchWorker) Start() { - tw.wgDone.Add(1) - sendTicker := time.NewTicker(tw.telemSendInterval) - - go func() { - defer tw.wgDone.Done() - - for { - select { - case <-sendTicker.C: - if len(tw.chTelemetry) == 0 { - continue - } +// Send sends batched telemetry to the ingress server on an interval +func (tw *telemetryIngressBatchWorker) Send(ctx context.Context) { + if len(tw.chTelemetry) == 0 { + return + } - // Send batched telemetry to the ingress server, log any errors - telemBatchReq := tw.BuildTelemBatchReq() - ctx, cancel := tw.chDone.CtxCancel(context.WithTimeout(context.Background(), tw.telemSendTimeout)) - _, err := tw.telemClient.TelemBatch(ctx, telemBatchReq) - cancel() + // Send batched telemetry to the ingress server, log any errors + telemBatchReq := tw.BuildTelemBatchReq() + ctx, cancel := context.WithTimeout(ctx, tw.telemSendTimeout) + _, err := tw.telemClient.TelemBatch(ctx, telemBatchReq) + cancel() - if err != nil { - tw.lggr.Warnf("Could not send telemetry: %v", err) - continue - } - if tw.logging { - tw.lggr.Debugw("Successfully sent telemetry to ingress server", "contractID", telemBatchReq.ContractId, "telemType", telemBatchReq.TelemetryType, "telemetry", telemBatchReq.Telemetry) - } - case <-tw.chDone: - return - } - } - }() + if err != nil { + tw.lggr.Warnf("Could not send telemetry: %v", err) + return + } + if tw.logging { + tw.lggr.Debugw("Successfully sent telemetry to ingress server", "contractID", telemBatchReq.ContractId, "telemType", telemBatchReq.TelemetryType, "telemetry", telemBatchReq.Telemetry) + } } // logBufferFullWithExpBackoff logs messages at diff --git a/core/services/synchronization/telemetry_ingress_batch_worker_test.go b/core/services/synchronization/telemetry_ingress_batch_worker_test.go index 109022c713..bf44ee9195 100644 --- a/core/services/synchronization/telemetry_ingress_batch_worker_test.go +++ b/core/services/synchronization/telemetry_ingress_batch_worker_test.go @@ -1,7 +1,6 @@ package synchronization_test import ( - "sync" "testing" "time" @@ -22,11 +21,8 @@ func TestTelemetryIngressWorker_BuildTelemBatchReq(t *testing.T) { chTelemetry := make(chan synchronization.TelemPayload, 10) worker := synchronization.NewTelemetryIngressBatchWorker( uint(maxTelemBatchSize), - time.Millisecond*1, time.Second, mocks.NewTelemClient(t), - &sync.WaitGroup{}, - make(chan struct{}), chTelemetry, "0xa", synchronization.OCR, diff --git a/core/services/synchronization/telemetry_ingress_client.go b/core/services/synchronization/telemetry_ingress_client.go index dc4ced31d0..1ed55bb546 100644 --- a/core/services/synchronization/telemetry_ingress_client.go +++ b/core/services/synchronization/telemetry_ingress_client.go @@ -4,15 +4,14 @@ import ( "context" "errors" "net/url" - "sync" "sync/atomic" "time" "github.com/smartcontractkit/wsrpc" "github.com/smartcontractkit/wsrpc/examples/simple/keys" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" telemPb "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" ) @@ -35,82 +34,59 @@ func (NoopTelemetryIngressClient) Name() string { return "Noop func (NoopTelemetryIngressClient) Ready() error { return nil } type telemetryIngressClient struct { - services.StateMachine + services.Service + eng *services.Engine + url *url.URL ks keystore.CSA serverPubKeyHex string telemClient telemPb.TelemClient logging bool - lggr logger.Logger - wgDone sync.WaitGroup - chDone services.StopChan dropMessageCount atomic.Uint32 chTelemetry chan TelemPayload } // NewTelemetryIngressClient returns a client backed by wsrpc that // can send telemetry to the telemetry ingress server -func NewTelemetryIngressClient(url *url.URL, serverPubKeyHex string, ks keystore.CSA, logging bool, lggr logger.Logger, telemBufferSize uint, network string, chainID string) TelemetryService { - return &telemetryIngressClient{ +func NewTelemetryIngressClient(url *url.URL, serverPubKeyHex string, ks keystore.CSA, logging bool, lggr logger.Logger, telemBufferSize uint) TelemetryService { + c := &telemetryIngressClient{ url: url, ks: ks, serverPubKeyHex: serverPubKeyHex, logging: logging, - lggr: lggr.Named("TelemetryIngressClient").Named(network).Named(chainID), chTelemetry: make(chan TelemPayload, telemBufferSize), - chDone: make(services.StopChan), } + c.Service, c.eng = services.Config{ + Name: "TelemetryIngressClient", + Start: c.start, + }.NewServiceEngine(lggr) + return c } // Start connects the wsrpc client to the telemetry ingress server -func (tc *telemetryIngressClient) Start(context.Context) error { - return tc.StartOnce("TelemetryIngressClient", func() error { - privkey, err := tc.getCSAPrivateKey() - if err != nil { - return err - } - - tc.connect(privkey) - - return nil - }) -} - -// Close disconnects the wsrpc client from the ingress server -func (tc *telemetryIngressClient) Close() error { - return tc.StopOnce("TelemetryIngressClient", func() error { - close(tc.chDone) - tc.wgDone.Wait() - return nil - }) -} +func (tc *telemetryIngressClient) start(context.Context) error { + privkey, err := tc.getCSAPrivateKey() + if err != nil { + return err + } -func (tc *telemetryIngressClient) Name() string { - return tc.lggr.Name() -} + tc.connect(privkey) -func (tc *telemetryIngressClient) HealthReport() map[string]error { - return map[string]error{tc.Name(): tc.Healthy()} + return nil } func (tc *telemetryIngressClient) connect(clientPrivKey []byte) { - tc.wgDone.Add(1) - - go func() { - defer tc.wgDone.Done() - ctx, cancel := tc.chDone.NewCtx() - defer cancel() - + tc.eng.Go(func(ctx context.Context) { serverPubKey := keys.FromHex(tc.serverPubKeyHex) - conn, err := wsrpc.DialWithContext(ctx, tc.url.String(), wsrpc.WithTransportCreds(clientPrivKey, serverPubKey), wsrpc.WithLogger(tc.lggr)) + conn, err := wsrpc.DialWithContext(ctx, tc.url.String(), wsrpc.WithTransportCreds(clientPrivKey, serverPubKey), wsrpc.WithLogger(tc.eng)) if err != nil { if ctx.Err() != nil { - tc.lggr.Warnw("gave up connecting to telemetry endpoint", "err", err) + tc.eng.Warnw("gave up connecting to telemetry endpoint", "err", err) } else { - tc.lggr.Criticalw("telemetry endpoint dial errored unexpectedly", "err", err) - tc.SvcErrBuffer.Append(err) + tc.eng.Criticalw("telemetry endpoint dial errored unexpectedly", "err", err) + tc.eng.EmitHealthErr(err) } return } @@ -126,16 +102,12 @@ func (tc *telemetryIngressClient) connect(clientPrivKey []byte) { tc.handleTelemetry() // Wait for close - <-tc.chDone - }() + <-ctx.Done() + }) } func (tc *telemetryIngressClient) handleTelemetry() { - tc.wgDone.Add(1) - go func() { - defer tc.wgDone.Done() - ctx, cancel := tc.chDone.NewCtx() - defer cancel() + tc.eng.Go(func(ctx context.Context) { for { select { case p := <-tc.chTelemetry: @@ -148,17 +120,17 @@ func (tc *telemetryIngressClient) handleTelemetry() { } _, err := tc.telemClient.Telem(ctx, telemReq) if err != nil { - tc.lggr.Errorf("Could not send telemetry: %v", err) + tc.eng.Errorf("Could not send telemetry: %v", err) continue } if tc.logging { - tc.lggr.Debugw("successfully sent telemetry to ingress server", "contractID", p.ContractID, "telemetry", p.Telemetry) + tc.eng.Debugw("successfully sent telemetry to ingress server", "contractID", p.ContractID, "telemetry", p.Telemetry) } - case <-tc.chDone: + case <-ctx.Done(): return } } - }() + }) } // logBufferFullWithExpBackoff logs messages at @@ -176,7 +148,7 @@ func (tc *telemetryIngressClient) handleTelemetry() { func (tc *telemetryIngressClient) logBufferFullWithExpBackoff(payload TelemPayload) { count := tc.dropMessageCount.Add(1) if count > 0 && (count%100 == 0 || count&(count-1) == 0) { - tc.lggr.Warnw("telemetry ingress client buffer full, dropping message", "telemetry", payload.Telemetry, "droppedCount", count) + tc.eng.Warnw("telemetry ingress client buffer full, dropping message", "telemetry", payload.Telemetry, "droppedCount", count) } } diff --git a/core/services/telemetry/manager.go b/core/services/telemetry/manager.go index a65759a5c6..73a94b4b12 100644 --- a/core/services/telemetry/manager.go +++ b/core/services/telemetry/manager.go @@ -1,29 +1,29 @@ package telemetry import ( - "context" "net/url" "strings" "time" "github.com/pkg/errors" - "go.uber.org/multierr" - "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + common "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink/v2/core/config" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" ) type Manager struct { - services.StateMachine - bufferSize uint - endpoints []*telemetryEndpoint - ks keystore.CSA - lggr logger.Logger + services.Service + eng *services.Engine + + bufferSize uint + endpoints []*telemetryEndpoint + ks keystore.CSA + logging bool maxBatchSize uint sendInterval time.Duration @@ -45,9 +45,7 @@ type telemetryEndpoint struct { func NewManager(cfg config.TelemetryIngress, csaKeyStore keystore.CSA, lggr logger.Logger) *Manager { m := &Manager{ bufferSize: cfg.BufferSize(), - endpoints: nil, ks: csaKeyStore, - lggr: lggr.Named("TelemetryManager"), logging: cfg.Logging(), maxBatchSize: cfg.MaxBatchSize(), sendInterval: cfg.SendInterval(), @@ -55,44 +53,21 @@ func NewManager(cfg config.TelemetryIngress, csaKeyStore keystore.CSA, lggr logg uniConn: cfg.UniConn(), useBatchSend: cfg.UseBatchSend(), } - for _, e := range cfg.Endpoints() { - if err := m.addEndpoint(e); err != nil { - m.lggr.Error(err) - } - } - return m -} - -func (m *Manager) Start(ctx context.Context) error { - return m.StartOnce("TelemetryManager", func() error { - var err error - for _, e := range m.endpoints { - err = multierr.Append(err, e.client.Start(ctx)) - } - return err - }) -} -func (m *Manager) Close() error { - return m.StopOnce("TelemetryManager", func() error { - var err error - for _, e := range m.endpoints { - err = multierr.Append(err, e.client.Close()) - } - return err - }) -} - -func (m *Manager) Name() string { - return m.lggr.Name() -} + m.Service, m.eng = services.Config{ + Name: "TelemetryManager", + NewSubServices: func(lggr common.Logger) (subs []services.Service) { + for _, e := range cfg.Endpoints() { + if sub, err := m.newEndpoint(e, lggr, cfg); err != nil { + lggr.Error(err) + } else { + subs = append(subs, sub) + } + } + return + }, + }.NewServiceEngine(lggr) -func (m *Manager) HealthReport() map[string]error { - hr := map[string]error{m.Name(): m.Healthy()} - - for _, e := range m.endpoints { - services.CopyHealth(hr, e.client.HealthReport()) - } - return hr + return m } // GenMonitoringEndpoint creates a new monitoring endpoints based on the existing available endpoints defined in the core config TOML, if no endpoint for the network and chainID exists, a NOOP agent will be used and the telemetry will not be sent @@ -100,7 +75,7 @@ func (m *Manager) GenMonitoringEndpoint(network string, chainID string, contract e, found := m.getEndpoint(network, chainID) if !found { - m.lggr.Warnf("no telemetry endpoint found for network %q chainID %q, telemetry %q for contactID %q will NOT be sent", network, chainID, telemType, contractID) + m.eng.Warnf("no telemetry endpoint found for network %q chainID %q, telemetry %q for contactID %q will NOT be sent", network, chainID, telemType, contractID) return &NoopAgent{} } @@ -111,32 +86,33 @@ func (m *Manager) GenMonitoringEndpoint(network string, chainID string, contract return NewIngressAgent(e.client, network, chainID, contractID, telemType) } -func (m *Manager) addEndpoint(e config.TelemetryIngressEndpoint) error { +func (m *Manager) newEndpoint(e config.TelemetryIngressEndpoint, lggr logger.Logger, cfg config.TelemetryIngress) (services.Service, error) { if e.Network() == "" { - return errors.New("cannot add telemetry endpoint, network cannot be empty") + return nil, errors.New("cannot add telemetry endpoint, network cannot be empty") } if e.ChainID() == "" { - return errors.New("cannot add telemetry endpoint, chainID cannot be empty") + return nil, errors.New("cannot add telemetry endpoint, chainID cannot be empty") } if e.URL() == nil { - return errors.New("cannot add telemetry endpoint, URL cannot be empty") + return nil, errors.New("cannot add telemetry endpoint, URL cannot be empty") } if e.ServerPubKey() == "" { - return errors.New("cannot add telemetry endpoint, ServerPubKey cannot be empty") + return nil, errors.New("cannot add telemetry endpoint, ServerPubKey cannot be empty") } if _, found := m.getEndpoint(e.Network(), e.ChainID()); found { - return errors.Errorf("cannot add telemetry endpoint for network %q and chainID %q, endpoint already exists", e.Network(), e.ChainID()) + return nil, errors.Errorf("cannot add telemetry endpoint for network %q and chainID %q, endpoint already exists", e.Network(), e.ChainID()) } + lggr = logger.Sugared(lggr).Named(e.Network()).Named(e.ChainID()) var tClient synchronization.TelemetryService if m.useBatchSend { - tClient = synchronization.NewTelemetryIngressBatchClient(e.URL(), e.ServerPubKey(), m.ks, m.logging, m.lggr, m.bufferSize, m.maxBatchSize, m.sendInterval, m.sendTimeout, m.uniConn, e.Network(), e.ChainID()) + tClient = synchronization.NewTelemetryIngressBatchClient(e.URL(), e.ServerPubKey(), m.ks, cfg.Logging(), lggr, cfg.BufferSize(), cfg.MaxBatchSize(), cfg.SendInterval(), cfg.SendTimeout(), cfg.UniConn()) } else { - tClient = synchronization.NewTelemetryIngressClient(e.URL(), e.ServerPubKey(), m.ks, m.logging, m.lggr, m.bufferSize, e.Network(), e.ChainID()) + tClient = synchronization.NewTelemetryIngressClient(e.URL(), e.ServerPubKey(), m.ks, cfg.Logging(), lggr, cfg.BufferSize()) } te := telemetryEndpoint{ @@ -148,7 +124,7 @@ func (m *Manager) addEndpoint(e config.TelemetryIngressEndpoint) error { } m.endpoints = append(m.endpoints, &te) - return nil + return te.client, nil } func (m *Manager) getEndpoint(network string, chainID string) (*telemetryEndpoint, bool) { diff --git a/core/services/telemetry/manager_test.go b/core/services/telemetry/manager_test.go index 4e55cb7575..fef065b572 100644 --- a/core/services/telemetry/manager_test.go +++ b/core/services/telemetry/manager_test.go @@ -156,7 +156,7 @@ func TestNewManager(t *testing.T) { require.Equal(t, uint(123), m.bufferSize) require.Equal(t, ks, m.ks) - require.Equal(t, "TelemetryManager", m.lggr.Name()) + require.Equal(t, "TelemetryManager", m.Name()) require.Equal(t, true, m.logging) require.Equal(t, uint(51), m.maxBatchSize) require.Equal(t, time.Millisecond*512, m.sendInterval) From 4843d84c260c0300eecfad413cca60af481280bf Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Wed, 7 Aug 2024 15:39:35 +0200 Subject: [PATCH 047/432] Update e2e tests definition for CI and automation workflow (#13908) * Update e2e tests definition for CI * Update test --- .github/e2e-tests.yml | 32 ++++++++++++++++--- .../run-automation-ondemand-e2e-tests.yml | 10 +++++- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 0d92d1900d..b2c9f12fca 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -47,6 +47,8 @@ runner-test-matrix: test_env_type: k8s-remote-runner runs_on: ubuntu-latest test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRv1Soak$ -test.parallel=1 -timeout 30m -count=1 -json + test_config_override_required: true + test_secrets_required: true test_inputs: test_suite: soak @@ -543,15 +545,37 @@ runner-test-matrix: chainlink_upgrade_version: develop pyroscope_env: ci-smoke-automation-upgrade-tests - - id: integration-tests/reorg/automation_reorg_test.go + - id: integration-tests/reorg/automation_reorg_test.go^TestAutomationReorg/registry_2_0 path: integration-tests/reorg/automation_reorg_test.go runs_on: ubuntu-latest - test_env_type: k8s-remote-runner + test_env_type: docker + test_inputs: + test_suite: reorg + workflows: + - Run Automation On Demand Tests (TEST WORKFLOW) + test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_0 -test.parallel=1 -timeout 30m -count=1 -json + pyroscope_env: ci-automation-on-demand-reorg + + - id: integration-tests/reorg/automation_reorg_test.go^TestAutomationReorg/registry_2_1 + path: integration-tests/reorg/automation_reorg_test.go + runs_on: ubuntu-latest + test_env_type: docker + test_inputs: + test_suite: reorg + workflows: + - Run Automation On Demand Tests (TEST WORKFLOW) + test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_1 -test.parallel=2 -timeout 30m -count=1 -json + pyroscope_env: ci-automation-on-demand-reorg + + - id: integration-tests/reorg/automation_reorg_test.go^TestAutomationReorg/registry_2_2 + path: integration-tests/reorg/automation_reorg_test.go + runs_on: ubuntu-latest + test_env_type: docker test_inputs: test_suite: reorg workflows: - Run Automation On Demand Tests (TEST WORKFLOW) - test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg$ -test.parallel=7 -timeout 60m -count=1 -json + test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_2 -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg - id: integration-tests/chaos/automation_chaos_test.go @@ -560,7 +584,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - Run Automation On Demand Tests (TEST WORKFLOW) - test_cmd: cd integration-tests/chaos && DETACH_RUNNER=false go test -v -test.run ^TestAutomationChaos$ -test.parallel=15 -timeout 60m -count=1 -json + test_cmd: cd integration-tests/chaos && DETACH_RUNNER=false go test -v -test.run ^TestAutomationChaos$ -test.parallel=20 -timeout 60m -count=1 -json pyroscope_env: ci-automation-on-demand-chaos test_inputs: test_suite: chaos diff --git a/.github/workflows/run-automation-ondemand-e2e-tests.yml b/.github/workflows/run-automation-ondemand-e2e-tests.yml index 7bf4691ecc..8dac3c5699 100644 --- a/.github/workflows/run-automation-ondemand-e2e-tests.yml +++ b/.github/workflows/run-automation-ondemand-e2e-tests.yml @@ -116,10 +116,18 @@ jobs: # Run reorg tests if enabled if [[ "${{ github.event.inputs.enableReorg }}" == 'true' ]]; then cat >> test_list.yaml < Date: Wed, 7 Aug 2024 07:42:01 -0600 Subject: [PATCH 048/432] bump solana commit (#14062) --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 45b5ee5905..94504897ab 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -273,7 +273,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.0 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index dff6f3f356..f770498cff 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1192,8 +1192,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.0 h1:+xBeVqx2x0Sx3CBbF8RLSblczsxJDYTkta8h7i8+23I= -github.com/smartcontractkit/chainlink-solana v1.1.0/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 h1:8ZzsGNhqYxmQ/QMO1fuXO7u9Vpl9YUvPJK+td/ZaBJA= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= diff --git a/go.mod b/go.mod index 78ec7d29ee..2179ffc2d2 100644 --- a/go.mod +++ b/go.mod @@ -78,7 +78,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 - github.com/smartcontractkit/chainlink-solana v1.1.0 + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 diff --git a/go.sum b/go.sum index f5ef0f91e7..b953f315e9 100644 --- a/go.sum +++ b/go.sum @@ -1147,8 +1147,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.0 h1:+xBeVqx2x0Sx3CBbF8RLSblczsxJDYTkta8h7i8+23I= -github.com/smartcontractkit/chainlink-solana v1.1.0/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 h1:8ZzsGNhqYxmQ/QMO1fuXO7u9Vpl9YUvPJK+td/ZaBJA= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index a648e46e9f..ff60a8f78b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -380,7 +380,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.0 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 03e4a9082f..5d15dfd92f 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1496,8 +1496,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.0 h1:+xBeVqx2x0Sx3CBbF8RLSblczsxJDYTkta8h7i8+23I= -github.com/smartcontractkit/chainlink-solana v1.1.0/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 h1:8ZzsGNhqYxmQ/QMO1fuXO7u9Vpl9YUvPJK+td/ZaBJA= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/chainlink-testing-framework v1.34.2 h1:YL3ft7KJB7SAopdmJeyeR4/kv0j4jOdagNihXq8OZ38= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 1aa754f8cf..c464231c74 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -372,7 +372,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.0 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 // indirect github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 698623c50f..d1d6f3a4d5 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1478,8 +1478,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.0 h1:+xBeVqx2x0Sx3CBbF8RLSblczsxJDYTkta8h7i8+23I= -github.com/smartcontractkit/chainlink-solana v1.1.0/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 h1:8ZzsGNhqYxmQ/QMO1fuXO7u9Vpl9YUvPJK+td/ZaBJA= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/chainlink-testing-framework v1.34.2 h1:YL3ft7KJB7SAopdmJeyeR4/kv0j4jOdagNihXq8OZ38= From 5a1dd1f74007f365bc52e323e5d6a3a638e6d7ed Mon Sep 17 00:00:00 2001 From: Akshay Aggarwal Date: Wed, 7 Aug 2024 15:49:50 +0100 Subject: [PATCH 049/432] Update log trigger default values (#14051) --- .../ocr2keeper/evmregistry/v21/logprovider/factory.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/factory.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/factory.go index 7ec65ff474..25cc5e939b 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/factory.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/factory.go @@ -74,7 +74,7 @@ func (o *LogTriggersOptions) Defaults(finalityDepth int64) { func (o *LogTriggersOptions) defaultBlockRate() uint32 { switch o.chainID.Int64() { - case 42161, 421613, 421614: // Arbitrum + case 42161, 421613, 421614: // Arbitrum, Arb Goerli, Arb Sepolia return 2 default: return 1 @@ -83,10 +83,10 @@ func (o *LogTriggersOptions) defaultBlockRate() uint32 { func (o *LogTriggersOptions) defaultLogLimit() uint32 { switch o.chainID.Int64() { - case 1, 4, 5, 42, 11155111: // Eth + case 1, 4, 5, 42, 11155111: // Eth, Rinkeby, Goerli, Kovan, Sepolia return 20 - case 10, 420, 56, 97, 137, 80001, 43113, 43114, 8453, 84531: // Optimism, BSC, Polygon, Avax, Base - return 5 + case 10, 420, 11155420, 56, 97, 137, 80001, 80002, 43114, 43113, 8453, 84531, 84532: // Optimism, OP Goerli, OP Sepolia, BSC, BSC Test, Polygon, Mumbai, Amoy, Avax, Avax Fuji, Base, Base Goerli, Base Sepolia + return 4 default: return 1 } From e500c1a471c4e9bb66a89ff27a763a83824f767c Mon Sep 17 00:00:00 2001 From: frank zhu Date: Wed, 7 Aug 2024 10:02:24 -0500 Subject: [PATCH 050/432] chore: update dependabot config gomod (#14063) --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 19e008c8ce..cea4f07b90 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,7 +4,7 @@ updates: directory: "/" schedule: interval: monthly - open-pull-requests-limit: 10 + open-pull-requests-limit: 0 ignore: # Old versions are pinned for libocr. - dependency-name: github.com/libp2p/go-libp2p-core From 215277f9e041d18dc5686c697e6959d5edaaf346 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Wed, 7 Aug 2024 11:21:31 -0400 Subject: [PATCH 051/432] auto-10161: replicate v2_3 to v2_3_zksync (#14035) * auto-10161: replicate v2_3 to v2_3_zksync * update * small fixes * add an zksync automation forwarder * fix linter * update * update * lint --- contracts/.changeset/loud-lobsters-guess.md | 5 + contracts/.solhintignore | 1 + .../native_solc_compile_all_automation | 2 +- .../automation/ZKSyncAutomationForwarder.sol | 92 ++ .../v0.8/automation/test/{v2_3 => }/WETH9.sol | 0 .../v0.8/automation/test/v2_3/BaseTest.t.sol | 4 +- .../ZKSyncAutomationRegistry2_3.sol | 391 ++++++ .../ZKSyncAutomationRegistryBase2_3.sol | 1216 +++++++++++++++++ .../ZKSyncAutomationRegistryLogicA2_3.sol | 283 ++++ .../ZKSyncAutomationRegistryLogicB2_3.sol | 449 ++++++ .../ZKSyncAutomationRegistryLogicC2_3.sol | 638 +++++++++ .../automation/AutomationRegistry2_3.test.ts | 1 - contracts/test/v0.8/automation/helpers.ts | 4 +- 13 files changed, 3080 insertions(+), 6 deletions(-) create mode 100644 contracts/.changeset/loud-lobsters-guess.md create mode 100644 contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol rename contracts/src/v0.8/automation/test/{v2_3 => }/WETH9.sol (100%) create mode 100644 contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol create mode 100644 contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryBase2_3.sol create mode 100644 contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicA2_3.sol create mode 100644 contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicB2_3.sol create mode 100644 contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicC2_3.sol diff --git a/contracts/.changeset/loud-lobsters-guess.md b/contracts/.changeset/loud-lobsters-guess.md new file mode 100644 index 0000000000..e470267e4e --- /dev/null +++ b/contracts/.changeset/loud-lobsters-guess.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +auto: create a replication from v2_3 to v2_3_zksync diff --git a/contracts/.solhintignore b/contracts/.solhintignore index bad1935442..55d195c305 100644 --- a/contracts/.solhintignore +++ b/contracts/.solhintignore @@ -18,6 +18,7 @@ ./src/v0.8/automation/libraries/internal/Cron.sol ./src/v0.8/automation/AutomationForwarder.sol ./src/v0.8/automation/AutomationForwarderLogic.sol +./src/v0.8/automation/ZKSyncAutomationForwarder.sol ./src/v0.8/automation/interfaces/v2_2/IAutomationRegistryMaster.sol ./src/v0.8/automation/interfaces/v2_3/IAutomationRegistryMaster2_3.sol diff --git a/contracts/scripts/native_solc_compile_all_automation b/contracts/scripts/native_solc_compile_all_automation index f144e4f7dc..29326a15c0 100755 --- a/contracts/scripts/native_solc_compile_all_automation +++ b/contracts/scripts/native_solc_compile_all_automation @@ -108,4 +108,4 @@ compileContract automation/v2_3/AutomationUtils2_3.sol compileContract automation/interfaces/v2_3/IAutomationRegistryMaster2_3.sol compileContract automation/testhelpers/MockETHUSDAggregator.sol -compileContract automation/test/v2_3/WETH9.sol +compileContract automation/test/WETH9.sol diff --git a/contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol b/contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol new file mode 100644 index 0000000000..cfbff1365e --- /dev/null +++ b/contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.16; + +import {IAutomationRegistryConsumer} from "./interfaces/IAutomationRegistryConsumer.sol"; + +uint256 constant PERFORM_GAS_CUSHION = 5_000; + +/** + * @title AutomationForwarder is a relayer that sits between the registry and the customer's target contract + * @dev The purpose of the forwarder is to give customers a consistent address to authorize against, + * which stays consistent between migrations. The Forwarder also exposes the registry address, so that users who + * want to programmatically interact with the registry (ie top up funds) can do so. + */ +contract ZKSyncAutomationForwarder { + /// @notice the user's target contract address + address private immutable i_target; + + /// @notice the shared logic address + address private immutable i_logic; + + IAutomationRegistryConsumer private s_registry; + + constructor(address target, address registry, address logic) { + s_registry = IAutomationRegistryConsumer(registry); + i_target = target; + i_logic = logic; + } + + /** + * @notice forward is called by the registry and forwards the call to the target + * @param gasAmount is the amount of gas to use in the call + * @param data is the 4 bytes function selector + arbitrary function data + * @return success indicating whether the target call succeeded or failed + */ + function forward(uint256 gasAmount, bytes memory data) external returns (bool success, uint256 gasUsed) { + if (msg.sender != address(s_registry)) revert(); + address target = i_target; + gasUsed = gasleft(); + assembly { + let g := gas() + // Compute g -= PERFORM_GAS_CUSHION and check for underflow + if lt(g, PERFORM_GAS_CUSHION) { + revert(0, 0) + } + g := sub(g, PERFORM_GAS_CUSHION) + // if g - g//64 <= gasAmount, revert + // (we subtract g//64 because of EIP-150) + if iszero(gt(sub(g, div(g, 64)), gasAmount)) { + revert(0, 0) + } + // solidity calls check that a contract actually exists at the destination, so we do the same + if iszero(extcodesize(target)) { + revert(0, 0) + } + // call with exact gas + success := call(gasAmount, target, 0, add(data, 0x20), mload(data), 0, 0) + } + gasUsed = gasUsed - gasleft(); + return (success, gasUsed); + } + + function getTarget() external view returns (address) { + return i_target; + } + + fallback() external { + // copy to memory for assembly access + address logic = i_logic; + // copied directly from OZ's Proxy contract + assembly { + // Copy msg.data. We take full control of memory in this inline assembly + // block because it will not return to Solidity code. We overwrite the + // Solidity scratch pad at memory position 0. + calldatacopy(0, 0, calldatasize()) + + // out and outsize are 0 because we don't know the size yet. + let result := delegatecall(gas(), logic, 0, calldatasize(), 0, 0) + + // Copy the returned data. + returndatacopy(0, 0, returndatasize()) + + switch result + // delegatecall returns 0 on error. + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } +} diff --git a/contracts/src/v0.8/automation/test/v2_3/WETH9.sol b/contracts/src/v0.8/automation/test/WETH9.sol similarity index 100% rename from contracts/src/v0.8/automation/test/v2_3/WETH9.sol rename to contracts/src/v0.8/automation/test/WETH9.sol diff --git a/contracts/src/v0.8/automation/test/v2_3/BaseTest.t.sol b/contracts/src/v0.8/automation/test/v2_3/BaseTest.t.sol index 9016f52c55..9e46e7bb40 100644 --- a/contracts/src/v0.8/automation/test/v2_3/BaseTest.t.sol +++ b/contracts/src/v0.8/automation/test/v2_3/BaseTest.t.sol @@ -20,14 +20,14 @@ import {ChainModuleBase} from "../../chains/ChainModuleBase.sol"; import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import {MockUpkeep} from "../../mocks/MockUpkeep.sol"; import {IWrappedNative} from "../../interfaces/v2_3/IWrappedNative.sol"; -import {WETH9} from "./WETH9.sol"; +import {WETH9} from "../WETH9.sol"; /** * @title BaseTest provides basic test setup procedures and dependencies for use by other * unit tests */ contract BaseTest is Test { - // test state (not exposed to derrived tests) + // test state (not exposed to derived tests) uint256 private nonce; // constants diff --git a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol new file mode 100644 index 0000000000..027fe59aca --- /dev/null +++ b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol @@ -0,0 +1,391 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {ZKSyncAutomationRegistryBase2_3} from "./ZKSyncAutomationRegistryBase2_3.sol"; +import {ZKSyncAutomationRegistryLogicA2_3} from "./ZKSyncAutomationRegistryLogicA2_3.sol"; +import {ZKSyncAutomationRegistryLogicC2_3} from "./ZKSyncAutomationRegistryLogicC2_3.sol"; +import {Chainable} from "../Chainable.sol"; +import {OCR2Abstract} from "../../shared/ocr2/OCR2Abstract.sol"; +import {IERC20Metadata as IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol"; + +/** + * @notice Registry for adding work for Chainlink nodes to perform on client + * contracts. Clients must support the AutomationCompatibleInterface interface. + */ +contract ZKSyncAutomationRegistry2_3 is ZKSyncAutomationRegistryBase2_3, OCR2Abstract, Chainable { + using Address for address; + using EnumerableSet for EnumerableSet.UintSet; + using EnumerableSet for EnumerableSet.AddressSet; + + /** + * @notice versions: + * AutomationRegistry 2.3.0: supports native and ERC20 billing + * changes flat fee to USD-denominated + * adds support for custom billing overrides + * AutomationRegistry 2.2.0: moves chain-specific integration code into a separate module + * KeeperRegistry 2.1.0: introduces support for log triggers + * removes the need for "wrapped perform data" + * KeeperRegistry 2.0.2: pass revert bytes as performData when target contract reverts + * fixes issue with arbitrum block number + * does an early return in case of stale report instead of revert + * KeeperRegistry 2.0.1: implements workaround for buggy migrate function in 1.X + * KeeperRegistry 2.0.0: implement OCR interface + * KeeperRegistry 1.3.0: split contract into Proxy and Logic + * account for Arbitrum and Optimism L1 gas fee + * allow users to configure upkeeps + * KeeperRegistry 1.2.0: allow funding within performUpkeep + * allow configurable registry maxPerformGas + * add function to let admin change upkeep gas limit + * add minUpkeepSpend requirement + * upgrade to solidity v0.8 + * KeeperRegistry 1.1.0: added flatFeeMicroLink + * KeeperRegistry 1.0.0: initial release + */ + string public constant override typeAndVersion = "AutomationRegistry 2.3.0"; + + /** + * @param logicA the address of the first logic contract + * @dev we cast the contract to logicC in order to call logicC functions (via fallback) + */ + constructor( + ZKSyncAutomationRegistryLogicA2_3 logicA + ) + ZKSyncAutomationRegistryBase2_3( + ZKSyncAutomationRegistryLogicC2_3(address(logicA)).getLinkAddress(), + ZKSyncAutomationRegistryLogicC2_3(address(logicA)).getLinkUSDFeedAddress(), + ZKSyncAutomationRegistryLogicC2_3(address(logicA)).getNativeUSDFeedAddress(), + ZKSyncAutomationRegistryLogicC2_3(address(logicA)).getFastGasFeedAddress(), + ZKSyncAutomationRegistryLogicC2_3(address(logicA)).getAutomationForwarderLogic(), + ZKSyncAutomationRegistryLogicC2_3(address(logicA)).getAllowedReadOnlyAddress(), + ZKSyncAutomationRegistryLogicC2_3(address(logicA)).getPayoutMode(), + ZKSyncAutomationRegistryLogicC2_3(address(logicA)).getWrappedNativeTokenAddress() + ) + Chainable(address(logicA)) + {} + + /** + * @notice holds the variables used in the transmit function, necessary to avoid stack too deep errors + */ + struct TransmitVars { + uint16 numUpkeepsPassedChecks; + uint96 totalReimbursement; + uint96 totalPremium; + uint256 totalCalldataWeight; + } + + // ================================================================ + // | HOT PATH ACTIONS | + // ================================================================ + + /** + * @inheritdoc OCR2Abstract + */ + function transmit( + bytes32[3] calldata reportContext, + bytes calldata rawReport, + bytes32[] calldata rs, + bytes32[] calldata ss, + bytes32 rawVs + ) external override { + uint256 gasOverhead = gasleft(); + // use this msg.data length check to ensure no extra data is included in the call + // 4 is first 4 bytes of the keccak-256 hash of the function signature. ss.length == rs.length so use one of them + // 4 + (32 * 3) + (rawReport.length + 32 + 32) + (32 * rs.length + 32 + 32) + (32 * ss.length + 32 + 32) + 32 + uint256 requiredLength = 324 + rawReport.length + 64 * rs.length; + if (msg.data.length != requiredLength) revert InvalidDataLength(); + HotVars memory hotVars = s_hotVars; + + if (hotVars.paused) revert RegistryPaused(); + if (!s_transmitters[msg.sender].active) revert OnlyActiveTransmitters(); + + // Verify signatures + if (s_latestConfigDigest != reportContext[0]) revert ConfigDigestMismatch(); + if (rs.length != hotVars.f + 1 || rs.length != ss.length) revert IncorrectNumberOfSignatures(); + _verifyReportSignature(reportContext, rawReport, rs, ss, rawVs); + + Report memory report = _decodeReport(rawReport); + + uint40 epochAndRound = uint40(uint256(reportContext[1])); + uint32 epoch = uint32(epochAndRound >> 8); + + _handleReport(hotVars, report, gasOverhead); + + if (epoch > hotVars.latestEpoch) { + s_hotVars.latestEpoch = epoch; + } + } + + /** + * @notice handles the report by performing the upkeeps and updating the state + * @param hotVars the hot variables of the registry + * @param report the report to be handled (already verified and decoded) + * @param gasOverhead the running tally of gas overhead to be split across the upkeeps + * @dev had to split this function from transmit() to avoid stack too deep errors + * @dev all other internal / private functions are generally defined in the Base contract + * we leave this here because it is essentially a continuation of the transmit() function, + */ + function _handleReport(HotVars memory hotVars, Report memory report, uint256 gasOverhead) private { + UpkeepTransmitInfo[] memory upkeepTransmitInfo = new UpkeepTransmitInfo[](report.upkeepIds.length); + TransmitVars memory transmitVars = TransmitVars({ + numUpkeepsPassedChecks: 0, + totalCalldataWeight: 0, + totalReimbursement: 0, + totalPremium: 0 + }); + + uint256 blocknumber = hotVars.chainModule.blockNumber(); + uint256 l1Fee = hotVars.chainModule.getCurrentL1Fee(); + + for (uint256 i = 0; i < report.upkeepIds.length; i++) { + upkeepTransmitInfo[i].upkeep = s_upkeep[report.upkeepIds[i]]; + upkeepTransmitInfo[i].triggerType = _getTriggerType(report.upkeepIds[i]); + + (upkeepTransmitInfo[i].earlyChecksPassed, upkeepTransmitInfo[i].dedupID) = _prePerformChecks( + report.upkeepIds[i], + blocknumber, + report.triggers[i], + upkeepTransmitInfo[i], + hotVars + ); + + if (upkeepTransmitInfo[i].earlyChecksPassed) { + transmitVars.numUpkeepsPassedChecks += 1; + } else { + continue; + } + + // Actually perform the target upkeep + (upkeepTransmitInfo[i].performSuccess, upkeepTransmitInfo[i].gasUsed) = _performUpkeep( + upkeepTransmitInfo[i].upkeep.forwarder, + report.gasLimits[i], + report.performDatas[i] + ); + + // To split L1 fee across the upkeeps, assign a weight to this upkeep based on the length + // of the perform data and calldata overhead + upkeepTransmitInfo[i].calldataWeight = + report.performDatas[i].length + + TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD + + (TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD * (hotVars.f + 1)); + transmitVars.totalCalldataWeight += upkeepTransmitInfo[i].calldataWeight; + + // Deduct the gasUsed by upkeep from the overhead tally - upkeeps pay for their own gas individually + gasOverhead -= upkeepTransmitInfo[i].gasUsed; + + // Store last perform block number / deduping key for upkeep + _updateTriggerMarker(report.upkeepIds[i], blocknumber, upkeepTransmitInfo[i]); + } + // No upkeeps to be performed in this report + if (transmitVars.numUpkeepsPassedChecks == 0) { + return; + } + + // This is the overall gas overhead that will be split across performed upkeeps + // Take upper bound of 16 gas per callData bytes + gasOverhead = (gasOverhead - gasleft()) + (16 * msg.data.length) + ACCOUNTING_FIXED_GAS_OVERHEAD; + gasOverhead = gasOverhead / transmitVars.numUpkeepsPassedChecks + ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD; + + { + BillingTokenPaymentParams memory billingTokenParams; + uint256 nativeUSD = _getNativeUSD(hotVars); + for (uint256 i = 0; i < report.upkeepIds.length; i++) { + if (upkeepTransmitInfo[i].earlyChecksPassed) { + if (i == 0 || upkeepTransmitInfo[i].upkeep.billingToken != upkeepTransmitInfo[i - 1].upkeep.billingToken) { + billingTokenParams = _getBillingTokenPaymentParams(hotVars, upkeepTransmitInfo[i].upkeep.billingToken); + } + PaymentReceipt memory receipt = _handlePayment( + hotVars, + PaymentParams({ + gasLimit: upkeepTransmitInfo[i].gasUsed, + gasOverhead: gasOverhead, + l1CostWei: (l1Fee * upkeepTransmitInfo[i].calldataWeight) / transmitVars.totalCalldataWeight, + fastGasWei: report.fastGasWei, + linkUSD: report.linkUSD, + nativeUSD: nativeUSD, + billingToken: upkeepTransmitInfo[i].upkeep.billingToken, + billingTokenParams: billingTokenParams, + isTransaction: true + }), + report.upkeepIds[i], + upkeepTransmitInfo[i].upkeep + ); + transmitVars.totalPremium += receipt.premiumInJuels; + transmitVars.totalReimbursement += receipt.gasReimbursementInJuels; + + emit UpkeepPerformed( + report.upkeepIds[i], + upkeepTransmitInfo[i].performSuccess, + receipt.gasChargeInBillingToken + receipt.premiumInBillingToken, + upkeepTransmitInfo[i].gasUsed, + gasOverhead, + report.triggers[i] + ); + } + } + } + // record payments to NOPs, all in LINK + s_transmitters[msg.sender].balance += transmitVars.totalReimbursement; + s_hotVars.totalPremium += transmitVars.totalPremium; + s_reserveAmounts[IERC20(address(i_link))] += transmitVars.totalReimbursement + transmitVars.totalPremium; + } + + // ================================================================ + // | OCR2ABSTRACT | + // ================================================================ + + /** + * @inheritdoc OCR2Abstract + * @dev prefer the type-safe version of setConfig (below) whenever possible. The OnchainConfig could differ between registry versions + * @dev this function takes up precious space on the root contract, but must be implemented to conform to the OCR2Abstract interface + */ + function setConfig( + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfigBytes, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external override { + (OnchainConfig memory config, IERC20[] memory billingTokens, BillingConfig[] memory billingConfigs) = abi.decode( + onchainConfigBytes, + (OnchainConfig, IERC20[], BillingConfig[]) + ); + + setConfigTypeSafe( + signers, + transmitters, + f, + config, + offchainConfigVersion, + offchainConfig, + billingTokens, + billingConfigs + ); + } + + /** + * @notice sets the configuration for the registry + * @param signers the list of permitted signers + * @param transmitters the list of permitted transmitters + * @param f the maximum tolerance for faulty nodes + * @param onchainConfig configuration values that are used on-chain + * @param offchainConfigVersion the version of the offchainConfig + * @param offchainConfig configuration values that are used off-chain + * @param billingTokens the list of valid billing tokens + * @param billingConfigs the configurations for each billing token + */ + function setConfigTypeSafe( + address[] memory signers, + address[] memory transmitters, + uint8 f, + OnchainConfig memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + IERC20[] memory billingTokens, + BillingConfig[] memory billingConfigs + ) public onlyOwner { + if (signers.length > MAX_NUM_ORACLES) revert TooManyOracles(); + if (f == 0) revert IncorrectNumberOfFaultyOracles(); + if (signers.length != transmitters.length || signers.length <= 3 * f) revert IncorrectNumberOfSigners(); + if (billingTokens.length != billingConfigs.length) revert ParameterLengthError(); + // set billing config for tokens + _setBillingConfig(billingTokens, billingConfigs); + + _updateTransmitters(signers, transmitters); + + s_hotVars = HotVars({ + f: f, + stalenessSeconds: onchainConfig.stalenessSeconds, + gasCeilingMultiplier: onchainConfig.gasCeilingMultiplier, + paused: s_hotVars.paused, + reentrancyGuard: s_hotVars.reentrancyGuard, + totalPremium: s_hotVars.totalPremium, + latestEpoch: 0, // DON restarts epoch + reorgProtectionEnabled: onchainConfig.reorgProtectionEnabled, + chainModule: onchainConfig.chainModule + }); + + uint32 previousConfigBlockNumber = s_storage.latestConfigBlockNumber; + uint32 newLatestConfigBlockNumber = uint32(onchainConfig.chainModule.blockNumber()); + uint32 newConfigCount = s_storage.configCount + 1; + + s_storage = Storage({ + checkGasLimit: onchainConfig.checkGasLimit, + maxPerformGas: onchainConfig.maxPerformGas, + transcoder: onchainConfig.transcoder, + maxCheckDataSize: onchainConfig.maxCheckDataSize, + maxPerformDataSize: onchainConfig.maxPerformDataSize, + maxRevertDataSize: onchainConfig.maxRevertDataSize, + upkeepPrivilegeManager: onchainConfig.upkeepPrivilegeManager, + financeAdmin: onchainConfig.financeAdmin, + nonce: s_storage.nonce, + configCount: newConfigCount, + latestConfigBlockNumber: newLatestConfigBlockNumber + }); + s_fallbackGasPrice = onchainConfig.fallbackGasPrice; + s_fallbackLinkPrice = onchainConfig.fallbackLinkPrice; + s_fallbackNativePrice = onchainConfig.fallbackNativePrice; + + bytes memory onchainConfigBytes = abi.encode(onchainConfig); + + s_latestConfigDigest = _configDigestFromConfigData( + block.chainid, + address(this), + s_storage.configCount, + signers, + transmitters, + f, + onchainConfigBytes, + offchainConfigVersion, + offchainConfig + ); + + for (uint256 idx = s_registrars.length(); idx > 0; idx--) { + s_registrars.remove(s_registrars.at(idx - 1)); + } + + for (uint256 idx = 0; idx < onchainConfig.registrars.length; idx++) { + s_registrars.add(onchainConfig.registrars[idx]); + } + + emit ConfigSet( + previousConfigBlockNumber, + s_latestConfigDigest, + s_storage.configCount, + signers, + transmitters, + f, + onchainConfigBytes, + offchainConfigVersion, + offchainConfig + ); + } + + /** + * @inheritdoc OCR2Abstract + * @dev this function takes up precious space on the root contract, but must be implemented to conform to the OCR2Abstract interface + */ + function latestConfigDetails() + external + view + override + returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) + { + return (s_storage.configCount, s_storage.latestConfigBlockNumber, s_latestConfigDigest); + } + + /** + * @inheritdoc OCR2Abstract + * @dev this function takes up precious space on the root contract, but must be implemented to conform to the OCR2Abstract interface + */ + function latestConfigDigestAndEpoch() + external + view + override + returns (bool scanLogs, bytes32 configDigest, uint32 epoch) + { + return (false, s_latestConfigDigest, s_hotVars.latestEpoch); + } +} diff --git a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryBase2_3.sol b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryBase2_3.sol new file mode 100644 index 0000000000..524ecacc82 --- /dev/null +++ b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryBase2_3.sol @@ -0,0 +1,1216 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {StreamsLookupCompatibleInterface} from "../interfaces/StreamsLookupCompatibleInterface.sol"; +import {ILogAutomation, Log} from "../interfaces/ILogAutomation.sol"; +import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {AggregatorV3Interface} from "../../shared/interfaces/AggregatorV3Interface.sol"; +import {LinkTokenInterface} from "../../shared/interfaces/LinkTokenInterface.sol"; +import {KeeperCompatibleInterface} from "../interfaces/KeeperCompatibleInterface.sol"; +import {IChainModule} from "../interfaces/IChainModule.sol"; +import {IERC20Metadata as IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import {SafeCast} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/SafeCast.sol"; +import {IWrappedNative} from "../interfaces/v2_3/IWrappedNative.sol"; + +/** + * @notice Base Keeper Registry contract, contains shared logic between + * AutomationRegistry and AutomationRegistryLogic + * @dev all errors, events, and internal functions should live here + */ +// solhint-disable-next-line max-states-count +abstract contract ZKSyncAutomationRegistryBase2_3 is ConfirmedOwner { + using Address for address; + using EnumerableSet for EnumerableSet.UintSet; + using EnumerableSet for EnumerableSet.AddressSet; + + address internal constant ZERO_ADDRESS = address(0); + address internal constant IGNORE_ADDRESS = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF; + bytes4 internal constant CHECK_SELECTOR = KeeperCompatibleInterface.checkUpkeep.selector; + bytes4 internal constant PERFORM_SELECTOR = KeeperCompatibleInterface.performUpkeep.selector; + bytes4 internal constant CHECK_CALLBACK_SELECTOR = StreamsLookupCompatibleInterface.checkCallback.selector; + bytes4 internal constant CHECK_LOG_SELECTOR = ILogAutomation.checkLog.selector; + uint256 internal constant PERFORM_GAS_MIN = 2_300; + uint256 internal constant CANCELLATION_DELAY = 50; + uint256 internal constant PERFORM_GAS_CUSHION = 5_000; + uint256 internal constant PPB_BASE = 1_000_000_000; + uint32 internal constant UINT32_MAX = type(uint32).max; + // The first byte of the mask can be 0, because we only ever have 31 oracles + uint256 internal constant ORACLE_MASK = 0x0001010101010101010101010101010101010101010101010101010101010101; + uint8 internal constant UPKEEP_VERSION_BASE = 4; + + // Next block of constants are only used in maxPayment estimation during checkUpkeep simulation + // These values are calibrated using hardhat tests which simulate various cases and verify that + // the variables result in accurate estimation + uint256 internal constant REGISTRY_CONDITIONAL_OVERHEAD = 98_200; // Fixed gas overhead for conditional upkeeps + uint256 internal constant REGISTRY_LOG_OVERHEAD = 122_500; // Fixed gas overhead for log upkeeps + uint256 internal constant REGISTRY_PER_SIGNER_GAS_OVERHEAD = 5_600; // Value scales with f + uint256 internal constant REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD = 24; // Per perform data byte overhead + + // The overhead (in bytes) in addition to perform data for upkeep sent in calldata + // This includes overhead for all struct encoding as well as report signatures + // There is a fixed component and a per signer component. This is calculated exactly by doing abi encoding + uint256 internal constant TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD = 932; + uint256 internal constant TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD = 64; + + // Next block of constants are used in actual payment calculation. We calculate the exact gas used within the + // tx itself, but since payment processing itself takes gas, and it needs the overhead as input, we use fixed constants + // to account for gas used in payment processing. These values are calibrated using hardhat tests which simulates various cases and verifies that + // the variables result in accurate estimation + uint256 internal constant ACCOUNTING_FIXED_GAS_OVERHEAD = 51_200; // Fixed overhead per tx + uint256 internal constant ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD = 14_200; // Overhead per upkeep performed in batch + + LinkTokenInterface internal immutable i_link; + AggregatorV3Interface internal immutable i_linkUSDFeed; + AggregatorV3Interface internal immutable i_nativeUSDFeed; + AggregatorV3Interface internal immutable i_fastGasFeed; + address internal immutable i_automationForwarderLogic; + address internal immutable i_allowedReadOnlyAddress; + IWrappedNative internal immutable i_wrappedNativeToken; + + /** + * @dev - The storage is gas optimised for one and only one function - transmit. All the storage accessed in transmit + * is stored compactly. Rest of the storage layout is not of much concern as transmit is the only hot path + */ + + // Upkeep storage + EnumerableSet.UintSet internal s_upkeepIDs; + mapping(uint256 => Upkeep) internal s_upkeep; // accessed during transmit + mapping(uint256 => address) internal s_upkeepAdmin; + mapping(uint256 => address) internal s_proposedAdmin; + mapping(uint256 => bytes) internal s_checkData; + mapping(bytes32 => bool) internal s_dedupKeys; + // Registry config and state + EnumerableSet.AddressSet internal s_registrars; + mapping(address => Transmitter) internal s_transmitters; + mapping(address => Signer) internal s_signers; + address[] internal s_signersList; // s_signersList contains the signing address of each oracle + address[] internal s_transmittersList; // s_transmittersList contains the transmission address of each oracle + EnumerableSet.AddressSet internal s_deactivatedTransmitters; + mapping(address => address) internal s_transmitterPayees; // s_payees contains the mapping from transmitter to payee. + mapping(address => address) internal s_proposedPayee; // proposed payee for a transmitter + bytes32 internal s_latestConfigDigest; // Read on transmit path in case of signature verification + HotVars internal s_hotVars; // Mixture of config and state, used in transmit + Storage internal s_storage; // Mixture of config and state, not used in transmit + uint256 internal s_fallbackGasPrice; + uint256 internal s_fallbackLinkPrice; + uint256 internal s_fallbackNativePrice; + mapping(address => MigrationPermission) internal s_peerRegistryMigrationPermission; // Permissions for migration to and fro + mapping(uint256 => bytes) internal s_upkeepTriggerConfig; // upkeep triggers + mapping(uint256 => bytes) internal s_upkeepOffchainConfig; // general config set by users for each upkeep + mapping(uint256 => bytes) internal s_upkeepPrivilegeConfig; // general config set by an administrative role for an upkeep + mapping(address => bytes) internal s_adminPrivilegeConfig; // general config set by an administrative role for an admin + // billing + mapping(IERC20 billingToken => uint256 reserveAmount) internal s_reserveAmounts; // unspent user deposits + unwithdrawn NOP payments + mapping(IERC20 billingToken => BillingConfig billingConfig) internal s_billingConfigs; // billing configurations for different tokens + mapping(uint256 upkeepID => BillingOverrides billingOverrides) internal s_billingOverrides; // billing overrides for specific upkeeps + IERC20[] internal s_billingTokens; // list of billing tokens + PayoutMode internal s_payoutMode; + + error ArrayHasNoEntries(); + error CannotCancel(); + error CheckDataExceedsLimit(); + error ConfigDigestMismatch(); + error DuplicateEntry(); + error DuplicateSigners(); + error GasLimitCanOnlyIncrease(); + error GasLimitOutsideRange(); + error IncorrectNumberOfFaultyOracles(); + error IncorrectNumberOfSignatures(); + error IncorrectNumberOfSigners(); + error IndexOutOfRange(); + error InsufficientBalance(uint256 available, uint256 requested); + error InsufficientLinkLiquidity(); + error InvalidDataLength(); + error InvalidFeed(); + error InvalidTrigger(); + error InvalidPayee(); + error InvalidRecipient(); + error InvalidReport(); + error InvalidSigner(); + error InvalidToken(); + error InvalidTransmitter(); + error InvalidTriggerType(); + error MigrationNotPermitted(); + error MustSettleOffchain(); + error MustSettleOnchain(); + error NotAContract(); + error OnlyActiveSigners(); + error OnlyActiveTransmitters(); + error OnlyCallableByAdmin(); + error OnlyCallableByLINKToken(); + error OnlyCallableByOwnerOrAdmin(); + error OnlyCallableByOwnerOrRegistrar(); + error OnlyCallableByPayee(); + error OnlyCallableByProposedAdmin(); + error OnlyCallableByProposedPayee(); + error OnlyCallableByUpkeepPrivilegeManager(); + error OnlyFinanceAdmin(); + error OnlyPausedUpkeep(); + error OnlySimulatedBackend(); + error OnlyUnpausedUpkeep(); + error ParameterLengthError(); + error ReentrantCall(); + error RegistryPaused(); + error RepeatedSigner(); + error RepeatedTransmitter(); + error TargetCheckReverted(bytes reason); + error TooManyOracles(); + error TranscoderNotSet(); + error TransferFailed(); + error UpkeepAlreadyExists(); + error UpkeepCancelled(); + error UpkeepNotCanceled(); + error UpkeepNotNeeded(); + error ValueNotChanged(); + error ZeroAddressNotAllowed(); + + enum MigrationPermission { + NONE, + OUTGOING, + INCOMING, + BIDIRECTIONAL + } + + enum Trigger { + CONDITION, + LOG + } + + enum UpkeepFailureReason { + NONE, + UPKEEP_CANCELLED, + UPKEEP_PAUSED, + TARGET_CHECK_REVERTED, + UPKEEP_NOT_NEEDED, + PERFORM_DATA_EXCEEDS_LIMIT, + INSUFFICIENT_BALANCE, + CALLBACK_REVERTED, + REVERT_DATA_EXCEEDS_LIMIT, + REGISTRY_PAUSED + } + + enum PayoutMode { + ON_CHAIN, + OFF_CHAIN + } + + /** + * @notice OnchainConfig of the registry + * @dev used only in setConfig() + * @member checkGasLimit gas limit when checking for upkeep + * @member stalenessSeconds number of seconds that is allowed for feed data to + * be stale before switching to the fallback pricing + * @member gasCeilingMultiplier multiplier to apply to the fast gas feed price + * when calculating the payment ceiling for keepers + * @member maxPerformGas max performGas allowed for an upkeep on this registry + * @member maxCheckDataSize max length of checkData bytes + * @member maxPerformDataSize max length of performData bytes + * @member maxRevertDataSize max length of revertData bytes + * @member fallbackGasPrice gas price used if the gas price feed is stale + * @member fallbackLinkPrice LINK price used if the LINK price feed is stale + * @member transcoder address of the transcoder contract + * @member registrars addresses of the registrar contracts + * @member upkeepPrivilegeManager address which can set privilege for upkeeps + * @member reorgProtectionEnabled if this registry enables re-org protection checks + * @member chainModule the chain specific module + */ + struct OnchainConfig { + uint32 checkGasLimit; + uint32 maxPerformGas; + uint32 maxCheckDataSize; + address transcoder; + // 1 word full + bool reorgProtectionEnabled; + uint24 stalenessSeconds; + uint32 maxPerformDataSize; + uint32 maxRevertDataSize; + address upkeepPrivilegeManager; + // 2 words full + uint16 gasCeilingMultiplier; + address financeAdmin; + // 3 words + uint256 fallbackGasPrice; + uint256 fallbackLinkPrice; + uint256 fallbackNativePrice; + address[] registrars; + IChainModule chainModule; + } + + /** + * @notice relevant state of an upkeep which is used in transmit function + * @member paused if this upkeep has been paused + * @member overridesEnabled if this upkeep has overrides enabled + * @member performGas the gas limit of upkeep execution + * @member maxValidBlocknumber until which block this upkeep is valid + * @member forwarder the forwarder contract to use for this upkeep + * @member amountSpent the amount this upkeep has spent, in the upkeep's billing token + * @member balance the balance of this upkeep + * @member lastPerformedBlockNumber the last block number when this upkeep was performed + */ + struct Upkeep { + bool paused; + bool overridesEnabled; + uint32 performGas; + uint32 maxValidBlocknumber; + IAutomationForwarder forwarder; + // 2 bytes left in 1st EVM word - read in transmit path + uint128 amountSpent; + uint96 balance; + uint32 lastPerformedBlockNumber; + // 0 bytes left in 2nd EVM word - written in transmit path + IERC20 billingToken; + // 12 bytes left in 3rd EVM word - read in transmit path + } + + /// @dev Config + State storage struct which is on hot transmit path + struct HotVars { + uint96 totalPremium; // ─────────╮ total historical payment to oracles for premium + uint32 latestEpoch; // │ latest epoch for which a report was transmitted + uint24 stalenessSeconds; // │ Staleness tolerance for feeds + uint16 gasCeilingMultiplier; // │ multiplier on top of fast gas feed for upper bound + uint8 f; // │ maximum number of faulty oracles + bool paused; // │ pause switch for all upkeeps in the registry + bool reentrancyGuard; // | guard against reentrancy + bool reorgProtectionEnabled; // ─╯ if this registry should enable the re-org protection mechanism + IChainModule chainModule; // the interface of chain specific module + } + + /// @dev Config + State storage struct which is not on hot transmit path + struct Storage { + address transcoder; // Address of transcoder contract used in migrations + uint32 checkGasLimit; // Gas limit allowed in checkUpkeep + uint32 maxPerformGas; // Max gas an upkeep can use on this registry + uint32 nonce; // Nonce for each upkeep created + // 1 EVM word full + address upkeepPrivilegeManager; // address which can set privilege for upkeeps + uint32 configCount; // incremented each time a new config is posted, The count is incorporated into the config digest to prevent replay attacks. + uint32 latestConfigBlockNumber; // makes it easier for offchain systems to extract config from logs + uint32 maxCheckDataSize; // max length of checkData bytes + // 2 EVM word full + address financeAdmin; // address which can withdraw funds from the contract + uint32 maxPerformDataSize; // max length of performData bytes + uint32 maxRevertDataSize; // max length of revertData bytes + // 4 bytes left in 3rd EVM word + } + + /// @dev Report transmitted by OCR to transmit function + struct Report { + uint256 fastGasWei; + uint256 linkUSD; + uint256[] upkeepIds; + uint256[] gasLimits; + bytes[] triggers; + bytes[] performDatas; + } + + /** + * @dev This struct is used to maintain run time information about an upkeep in transmit function + * @member upkeep the upkeep struct + * @member earlyChecksPassed whether the upkeep passed early checks before perform + * @member performSuccess whether the perform was successful + * @member triggerType the type of trigger + * @member gasUsed gasUsed by this upkeep in perform + * @member calldataWeight weight assigned to this upkeep for its contribution to calldata. It is used to split L1 fee + * @member dedupID unique ID used to dedup an upkeep/trigger combo + */ + struct UpkeepTransmitInfo { + Upkeep upkeep; + bool earlyChecksPassed; + bool performSuccess; + Trigger triggerType; + uint256 gasUsed; + uint256 calldataWeight; + bytes32 dedupID; + } + + /** + * @notice holds information about a transmiter / node in the DON + * @member active can this transmitter submit reports + * @member index of oracle in s_signersList/s_transmittersList + * @member balance a node's balance in LINK + * @member lastCollected the total balance at which the node last withdrew + * @dev uint96 is safe for balance / last collected because transmitters are only ever paid in LINK + */ + struct Transmitter { + bool active; + uint8 index; + uint96 balance; + uint96 lastCollected; + } + + struct TransmitterPayeeInfo { + address transmitterAddress; + address payeeAddress; + } + + struct Signer { + bool active; + // Index of oracle in s_signersList/s_transmittersList + uint8 index; + } + + /** + * @notice the trigger structure conditional trigger type + */ + struct ConditionalTrigger { + uint32 blockNum; + bytes32 blockHash; + } + + /** + * @notice the trigger structure of log upkeeps + * @dev NOTE that blockNum / blockHash describe the block used for the callback, + * not necessarily the block number that the log was emitted in!!!! + */ + struct LogTrigger { + bytes32 logBlockHash; + bytes32 txHash; + uint32 logIndex; + uint32 blockNum; + bytes32 blockHash; + } + + /** + * @notice the billing config of a token + * @dev this is a storage struct + */ + // solhint-disable-next-line gas-struct-packing + struct BillingConfig { + uint32 gasFeePPB; + uint24 flatFeeMilliCents; // min fee is $0.00001, max fee is $167 + AggregatorV3Interface priceFeed; + uint8 decimals; + // 1st word, read in calculating BillingTokenPaymentParams + uint256 fallbackPrice; + // 2nd word only read if stale + uint96 minSpend; + // 3rd word only read during cancellation + } + + /** + * @notice override-able billing params of a billing token + */ + struct BillingOverrides { + uint32 gasFeePPB; + uint24 flatFeeMilliCents; + } + + /** + * @notice pricing params for a billing token + * @dev this is a memory-only struct, so struct packing is less important + */ + struct BillingTokenPaymentParams { + uint8 decimals; + uint32 gasFeePPB; + uint24 flatFeeMilliCents; + uint256 priceUSD; + } + + /** + * @notice struct containing price & payment information used in calculating payment amount + * @member gasLimit the amount of gas used + * @member gasOverhead the amount of gas overhead + * @member l1CostWei the amount to be charged for L1 fee in wei + * @member fastGasWei the fast gas price + * @member linkUSD the exchange ratio between LINK and USD + * @member nativeUSD the exchange ratio between the chain's native token and USD + * @member billingToken the billing token + * @member billingTokenParams the payment params specific to a particular payment token + * @member isTransaction is this an eth_call or a transaction + */ + struct PaymentParams { + uint256 gasLimit; + uint256 gasOverhead; + uint256 l1CostWei; + uint256 fastGasWei; + uint256 linkUSD; + uint256 nativeUSD; + IERC20 billingToken; + BillingTokenPaymentParams billingTokenParams; + bool isTransaction; + } + + /** + * @notice struct containing receipt information about a payment or cost estimation + * @member gasChargeInBillingToken the amount to charge a user for gas spent using the billing token's native decimals + * @member premiumInBillingToken the premium charged to the user, shared between all nodes, using the billing token's native decimals + * @member gasReimbursementInJuels the amount to reimburse a node for gas spent + * @member premiumInJuels the premium paid to NOPs, shared between all nodes + */ + // solhint-disable-next-line gas-struct-packing + struct PaymentReceipt { + uint96 gasChargeInBillingToken; + uint96 premiumInBillingToken; + // one word ends + uint96 gasReimbursementInJuels; + uint96 premiumInJuels; + // second word ends + IERC20 billingToken; + uint96 linkUSD; + // third word ends + uint96 nativeUSD; + uint96 billingUSD; + // fourth word ends + } + + event AdminPrivilegeConfigSet(address indexed admin, bytes privilegeConfig); + event BillingConfigOverridden(uint256 indexed id, BillingOverrides overrides); + event BillingConfigOverrideRemoved(uint256 indexed id); + event BillingConfigSet(IERC20 indexed token, BillingConfig config); + event CancelledUpkeepReport(uint256 indexed id, bytes trigger); + event ChainSpecificModuleUpdated(address newModule); + event DedupKeyAdded(bytes32 indexed dedupKey); + event FeesWithdrawn(address indexed assetAddress, address indexed recipient, uint256 amount); + event FundsAdded(uint256 indexed id, address indexed from, uint96 amount); + event FundsWithdrawn(uint256 indexed id, uint256 amount, address to); + event InsufficientFundsUpkeepReport(uint256 indexed id, bytes trigger); + event NOPsSettledOffchain(address[] payees, uint256[] payments); + event Paused(address account); + event PayeesUpdated(address[] transmitters, address[] payees); + event PayeeshipTransferRequested(address indexed transmitter, address indexed from, address indexed to); + event PayeeshipTransferred(address indexed transmitter, address indexed from, address indexed to); + event PaymentWithdrawn(address indexed transmitter, uint256 indexed amount, address indexed to, address payee); + event ReorgedUpkeepReport(uint256 indexed id, bytes trigger); + event StaleUpkeepReport(uint256 indexed id, bytes trigger); + event UpkeepAdminTransferred(uint256 indexed id, address indexed from, address indexed to); + event UpkeepAdminTransferRequested(uint256 indexed id, address indexed from, address indexed to); + event UpkeepCanceled(uint256 indexed id, uint64 indexed atBlockHeight); + event UpkeepCheckDataSet(uint256 indexed id, bytes newCheckData); + event UpkeepGasLimitSet(uint256 indexed id, uint96 gasLimit); + event UpkeepMigrated(uint256 indexed id, uint256 remainingBalance, address destination); + event UpkeepOffchainConfigSet(uint256 indexed id, bytes offchainConfig); + event UpkeepPaused(uint256 indexed id); + event UpkeepPerformed( + uint256 indexed id, + bool indexed success, + uint96 totalPayment, + uint256 gasUsed, + uint256 gasOverhead, + bytes trigger + ); + event UpkeepCharged(uint256 indexed id, PaymentReceipt receipt); + event UpkeepPrivilegeConfigSet(uint256 indexed id, bytes privilegeConfig); + event UpkeepReceived(uint256 indexed id, uint256 startingBalance, address importedFrom); + event UpkeepRegistered(uint256 indexed id, uint32 performGas, address admin); + event UpkeepTriggerConfigSet(uint256 indexed id, bytes triggerConfig); + event UpkeepUnpaused(uint256 indexed id); + event Unpaused(address account); + + /** + * @param link address of the LINK Token + * @param linkUSDFeed address of the LINK/USD price feed + * @param nativeUSDFeed address of the Native/USD price feed + * @param fastGasFeed address of the Fast Gas price feed + * @param automationForwarderLogic the address of automation forwarder logic + * @param allowedReadOnlyAddress the address of the allowed read only address + * @param payoutMode the payout mode + */ + constructor( + address link, + address linkUSDFeed, + address nativeUSDFeed, + address fastGasFeed, + address automationForwarderLogic, + address allowedReadOnlyAddress, + PayoutMode payoutMode, + address wrappedNativeTokenAddress + ) ConfirmedOwner(msg.sender) { + i_link = LinkTokenInterface(link); + i_linkUSDFeed = AggregatorV3Interface(linkUSDFeed); + i_nativeUSDFeed = AggregatorV3Interface(nativeUSDFeed); + i_fastGasFeed = AggregatorV3Interface(fastGasFeed); + i_automationForwarderLogic = automationForwarderLogic; + i_allowedReadOnlyAddress = allowedReadOnlyAddress; + s_payoutMode = payoutMode; + i_wrappedNativeToken = IWrappedNative(wrappedNativeTokenAddress); + if (i_linkUSDFeed.decimals() != i_nativeUSDFeed.decimals()) { + revert InvalidFeed(); + } + } + + // ================================================================ + // | INTERNAL FUNCTIONS ONLY | + // ================================================================ + + /** + * @dev creates a new upkeep with the given fields + * @param id the id of the upkeep + * @param upkeep the upkeep to create + * @param admin address to cancel upkeep and withdraw remaining funds + * @param checkData data which is passed to user's checkUpkeep + * @param triggerConfig the trigger config for this upkeep + * @param offchainConfig the off-chain config of this upkeep + */ + function _createUpkeep( + uint256 id, + Upkeep memory upkeep, + address admin, + bytes memory checkData, + bytes memory triggerConfig, + bytes memory offchainConfig + ) internal { + if (s_hotVars.paused) revert RegistryPaused(); + if (checkData.length > s_storage.maxCheckDataSize) revert CheckDataExceedsLimit(); + if (upkeep.performGas < PERFORM_GAS_MIN || upkeep.performGas > s_storage.maxPerformGas) + revert GasLimitOutsideRange(); + if (address(s_upkeep[id].forwarder) != address(0)) revert UpkeepAlreadyExists(); + if (address(s_billingConfigs[upkeep.billingToken].priceFeed) == address(0)) revert InvalidToken(); + s_upkeep[id] = upkeep; + s_upkeepAdmin[id] = admin; + s_checkData[id] = checkData; + s_reserveAmounts[upkeep.billingToken] = s_reserveAmounts[upkeep.billingToken] + upkeep.balance; + s_upkeepTriggerConfig[id] = triggerConfig; + s_upkeepOffchainConfig[id] = offchainConfig; + s_upkeepIDs.add(id); + } + + /** + * @dev creates an ID for the upkeep based on the upkeep's type + * @dev the format of the ID looks like this: + * ****00000000000X**************** + * 4 bytes of entropy + * 11 bytes of zeros + * 1 identifying byte for the trigger type + * 16 bytes of entropy + * @dev this maintains the same level of entropy as eth addresses, so IDs will still be unique + * @dev we add the "identifying" part in the middle so that it is mostly hidden from users who usually only + * see the first 4 and last 4 hex values ex 0x1234...ABCD + */ + function _createID(Trigger triggerType) internal view returns (uint256) { + bytes1 empty; + IChainModule chainModule = s_hotVars.chainModule; + bytes memory idBytes = abi.encodePacked( + keccak256(abi.encode(chainModule.blockHash((chainModule.blockNumber() - 1)), address(this), s_storage.nonce)) + ); + for (uint256 idx = 4; idx < 15; idx++) { + idBytes[idx] = empty; + } + idBytes[15] = bytes1(uint8(triggerType)); + return uint256(bytes32(idBytes)); + } + + /** + * @dev retrieves feed data for fast gas/native and link/native prices. if the feed + * data is stale it uses the configured fallback price. Once a price is picked + * for gas it takes the min of gas price in the transaction or the fast gas + * price in order to reduce costs for the upkeep clients. + */ + function _getFeedData( + HotVars memory hotVars + ) internal view returns (uint256 gasWei, uint256 linkUSD, uint256 nativeUSD) { + uint32 stalenessSeconds = hotVars.stalenessSeconds; + bool staleFallback = stalenessSeconds > 0; + uint256 timestamp; + int256 feedValue; + (, feedValue, , timestamp, ) = i_fastGasFeed.latestRoundData(); + if ( + feedValue <= 0 || block.timestamp < timestamp || (staleFallback && stalenessSeconds < block.timestamp - timestamp) + ) { + gasWei = s_fallbackGasPrice; + } else { + gasWei = uint256(feedValue); + } + (, feedValue, , timestamp, ) = i_linkUSDFeed.latestRoundData(); + if ( + feedValue <= 0 || block.timestamp < timestamp || (staleFallback && stalenessSeconds < block.timestamp - timestamp) + ) { + linkUSD = s_fallbackLinkPrice; + } else { + linkUSD = uint256(feedValue); + } + return (gasWei, linkUSD, _getNativeUSD(hotVars)); + } + + /** + * @dev this price has it's own getter for use in the transmit() hot path + * in the future, all price data should be included in the report instead of + * getting read during execution + */ + function _getNativeUSD(HotVars memory hotVars) internal view returns (uint256) { + (, int256 feedValue, , uint256 timestamp, ) = i_nativeUSDFeed.latestRoundData(); + if ( + feedValue <= 0 || + block.timestamp < timestamp || + (hotVars.stalenessSeconds > 0 && hotVars.stalenessSeconds < block.timestamp - timestamp) + ) { + return s_fallbackNativePrice; + } else { + return uint256(feedValue); + } + } + + /** + * @dev gets the price and billing params for a specific billing token + */ + function _getBillingTokenPaymentParams( + HotVars memory hotVars, + IERC20 billingToken + ) internal view returns (BillingTokenPaymentParams memory paymentParams) { + BillingConfig storage config = s_billingConfigs[billingToken]; + paymentParams.flatFeeMilliCents = config.flatFeeMilliCents; + paymentParams.gasFeePPB = config.gasFeePPB; + paymentParams.decimals = config.decimals; + (, int256 feedValue, , uint256 timestamp, ) = config.priceFeed.latestRoundData(); + if ( + feedValue <= 0 || + block.timestamp < timestamp || + (hotVars.stalenessSeconds > 0 && hotVars.stalenessSeconds < block.timestamp - timestamp) + ) { + paymentParams.priceUSD = config.fallbackPrice; + } else { + paymentParams.priceUSD = uint256(feedValue); + } + return paymentParams; + } + + /** + * @param hotVars the hot path variables + * @param paymentParams the pricing data and gas usage data + * @return receipt the receipt of payment with pricing breakdown + * @dev use of PaymentParams struct is necessary to avoid stack too deep errors + * @dev calculates LINK paid for gas spent plus a configure premium percentage + * @dev 1 USD = 1e18 attoUSD + * @dev 1 USD = 1e26 hexaicosaUSD (had to borrow this prefix from geometry because there is no metric prefix for 1e-26) + * @dev 1 millicent = 1e-5 USD = 1e13 attoUSD + */ + function _calculatePaymentAmount( + HotVars memory hotVars, + PaymentParams memory paymentParams + ) internal view returns (PaymentReceipt memory receipt) { + uint256 decimals = paymentParams.billingTokenParams.decimals; + uint256 gasWei = paymentParams.fastGasWei * hotVars.gasCeilingMultiplier; + // in case it's actual execution use actual gas price, capped by fastGasWei * gasCeilingMultiplier + if (paymentParams.isTransaction && tx.gasprice < gasWei) { + gasWei = tx.gasprice; + } + + // scaling factor is based on decimals of billing token, and applies to premium and gasCharge + uint256 numeratorScalingFactor = decimals > 18 ? 10 ** (decimals - 18) : 1; + uint256 denominatorScalingFactor = decimals < 18 ? 10 ** (18 - decimals) : 1; + + // gas calculation + uint256 gasPaymentHexaicosaUSD = (gasWei * + (paymentParams.gasLimit + paymentParams.gasOverhead) + + paymentParams.l1CostWei) * paymentParams.nativeUSD; // gasPaymentHexaicosaUSD has an extra 8 zeros because of decimals on nativeUSD feed + // gasChargeInBillingToken is scaled by the billing token's decimals. Round up to ensure a minimum billing token is charged for gas + receipt.gasChargeInBillingToken = SafeCast.toUint96( + ((gasPaymentHexaicosaUSD * numeratorScalingFactor) + + (paymentParams.billingTokenParams.priceUSD * denominatorScalingFactor - 1)) / + (paymentParams.billingTokenParams.priceUSD * denominatorScalingFactor) + ); + // 18 decimals: 26 decimals / 8 decimals + receipt.gasReimbursementInJuels = SafeCast.toUint96(gasPaymentHexaicosaUSD / paymentParams.linkUSD); + + // premium calculation + uint256 flatFeeHexaicosaUSD = uint256(paymentParams.billingTokenParams.flatFeeMilliCents) * 1e21; // 1e13 for milliCents to attoUSD and 1e8 for attoUSD to hexaicosaUSD + uint256 premiumHexaicosaUSD = ((((gasWei * paymentParams.gasLimit) + paymentParams.l1CostWei) * + paymentParams.billingTokenParams.gasFeePPB * + paymentParams.nativeUSD) / 1e9) + flatFeeHexaicosaUSD; + // premium is scaled by the billing token's decimals. Round up to ensure at least minimum charge + receipt.premiumInBillingToken = SafeCast.toUint96( + ((premiumHexaicosaUSD * numeratorScalingFactor) + + (paymentParams.billingTokenParams.priceUSD * denominatorScalingFactor - 1)) / + (paymentParams.billingTokenParams.priceUSD * denominatorScalingFactor) + ); + receipt.premiumInJuels = SafeCast.toUint96(premiumHexaicosaUSD / paymentParams.linkUSD); + + receipt.billingToken = paymentParams.billingToken; + receipt.linkUSD = SafeCast.toUint96(paymentParams.linkUSD); + receipt.nativeUSD = SafeCast.toUint96(paymentParams.nativeUSD); + receipt.billingUSD = SafeCast.toUint96(paymentParams.billingTokenParams.priceUSD); + + return receipt; + } + + /** + * @dev calculates the max payment for an upkeep. Called during checkUpkeep simulation and assumes + * maximum gas overhead, L1 fee + */ + function _getMaxPayment( + uint256 upkeepId, + HotVars memory hotVars, + Trigger triggerType, + uint32 performGas, + uint256 fastGasWei, + uint256 linkUSD, + uint256 nativeUSD, + IERC20 billingToken + ) internal view returns (uint96) { + uint256 maxL1Fee; + uint256 maxGasOverhead; + + { + if (triggerType == Trigger.CONDITION) { + maxGasOverhead = REGISTRY_CONDITIONAL_OVERHEAD; + } else if (triggerType == Trigger.LOG) { + maxGasOverhead = REGISTRY_LOG_OVERHEAD; + } else { + revert InvalidTriggerType(); + } + uint256 maxCalldataSize = s_storage.maxPerformDataSize + + TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD + + (TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD * (hotVars.f + 1)); + (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead) = s_hotVars.chainModule.getGasOverhead(); + maxGasOverhead += + (REGISTRY_PER_SIGNER_GAS_OVERHEAD * (hotVars.f + 1)) + + ((REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD + chainModulePerByteOverhead) * maxCalldataSize) + + chainModuleFixedOverhead; + maxL1Fee = hotVars.gasCeilingMultiplier * hotVars.chainModule.getMaxL1Fee(maxCalldataSize); + } + + BillingTokenPaymentParams memory paymentParams = _getBillingTokenPaymentParams(hotVars, billingToken); + if (s_upkeep[upkeepId].overridesEnabled) { + BillingOverrides memory billingOverrides = s_billingOverrides[upkeepId]; + // use the overridden configs + paymentParams.gasFeePPB = billingOverrides.gasFeePPB; + paymentParams.flatFeeMilliCents = billingOverrides.flatFeeMilliCents; + } + + PaymentReceipt memory receipt = _calculatePaymentAmount( + hotVars, + PaymentParams({ + gasLimit: performGas, + gasOverhead: maxGasOverhead, + l1CostWei: maxL1Fee, + fastGasWei: fastGasWei, + linkUSD: linkUSD, + nativeUSD: nativeUSD, + billingToken: billingToken, + billingTokenParams: paymentParams, + isTransaction: false + }) + ); + + return receipt.gasChargeInBillingToken + receipt.premiumInBillingToken; + } + + /** + * @dev move a transmitter's balance from total pool to withdrawable balance + */ + function _updateTransmitterBalanceFromPool( + address transmitterAddress, + uint96 totalPremium, + uint96 payeeCount + ) internal returns (uint96) { + Transmitter memory transmitter = s_transmitters[transmitterAddress]; + + if (transmitter.active) { + uint96 uncollected = totalPremium - transmitter.lastCollected; + uint96 due = uncollected / payeeCount; + transmitter.balance += due; + transmitter.lastCollected += due * payeeCount; + s_transmitters[transmitterAddress] = transmitter; + } + + return transmitter.balance; + } + + /** + * @dev gets the trigger type from an upkeepID (trigger type is encoded in the middle of the ID) + */ + function _getTriggerType(uint256 upkeepId) internal pure returns (Trigger) { + bytes32 rawID = bytes32(upkeepId); + bytes1 empty = bytes1(0); + for (uint256 idx = 4; idx < 15; idx++) { + if (rawID[idx] != empty) { + // old IDs that were created before this standard and migrated to this registry + return Trigger.CONDITION; + } + } + return Trigger(uint8(rawID[15])); + } + + function _checkPayload( + uint256 upkeepId, + Trigger triggerType, + bytes memory triggerData + ) internal view returns (bytes memory) { + if (triggerType == Trigger.CONDITION) { + return abi.encodeWithSelector(CHECK_SELECTOR, s_checkData[upkeepId]); + } else if (triggerType == Trigger.LOG) { + Log memory log = abi.decode(triggerData, (Log)); + return abi.encodeWithSelector(CHECK_LOG_SELECTOR, log, s_checkData[upkeepId]); + } + revert InvalidTriggerType(); + } + + /** + * @dev _decodeReport decodes a serialized report into a Report struct + */ + function _decodeReport(bytes calldata rawReport) internal pure returns (Report memory) { + Report memory report = abi.decode(rawReport, (Report)); + uint256 expectedLength = report.upkeepIds.length; + if ( + report.gasLimits.length != expectedLength || + report.triggers.length != expectedLength || + report.performDatas.length != expectedLength + ) { + revert InvalidReport(); + } + return report; + } + + /** + * @dev Does some early sanity checks before actually performing an upkeep + * @return bool whether the upkeep should be performed + * @return bytes32 dedupID for preventing duplicate performances of this trigger + */ + function _prePerformChecks( + uint256 upkeepId, + uint256 blocknumber, + bytes memory rawTrigger, + UpkeepTransmitInfo memory transmitInfo, + HotVars memory hotVars + ) internal returns (bool, bytes32) { + bytes32 dedupID; + if (transmitInfo.triggerType == Trigger.CONDITION) { + if (!_validateConditionalTrigger(upkeepId, blocknumber, rawTrigger, transmitInfo, hotVars)) + return (false, dedupID); + } else if (transmitInfo.triggerType == Trigger.LOG) { + bool valid; + (valid, dedupID) = _validateLogTrigger(upkeepId, blocknumber, rawTrigger, hotVars); + if (!valid) return (false, dedupID); + } else { + revert InvalidTriggerType(); + } + if (transmitInfo.upkeep.maxValidBlocknumber <= blocknumber) { + // Can happen when an upkeep got cancelled after report was generated. + // However we have a CANCELLATION_DELAY of 50 blocks so shouldn't happen in practice + emit CancelledUpkeepReport(upkeepId, rawTrigger); + return (false, dedupID); + } + return (true, dedupID); + } + + /** + * @dev Does some early sanity checks before actually performing an upkeep + */ + function _validateConditionalTrigger( + uint256 upkeepId, + uint256 blocknumber, + bytes memory rawTrigger, + UpkeepTransmitInfo memory transmitInfo, + HotVars memory hotVars + ) internal returns (bool) { + ConditionalTrigger memory trigger = abi.decode(rawTrigger, (ConditionalTrigger)); + if (trigger.blockNum < transmitInfo.upkeep.lastPerformedBlockNumber) { + // Can happen when another report performed this upkeep after this report was generated + emit StaleUpkeepReport(upkeepId, rawTrigger); + return false; + } + if ( + (hotVars.reorgProtectionEnabled && + (trigger.blockHash != bytes32("") && hotVars.chainModule.blockHash(trigger.blockNum) != trigger.blockHash)) || + trigger.blockNum >= blocknumber + ) { + // There are two cases of reorged report + // 1. trigger block number is in future: this is an edge case during extreme deep reorgs of chain + // which is always protected against + // 2. blockHash at trigger block number was same as trigger time. This is an optional check which is + // applied if DON sends non empty trigger.blockHash. Note: It only works for last 256 blocks on chain + // when it is sent + emit ReorgedUpkeepReport(upkeepId, rawTrigger); + return false; + } + return true; + } + + function _validateLogTrigger( + uint256 upkeepId, + uint256 blocknumber, + bytes memory rawTrigger, + HotVars memory hotVars + ) internal returns (bool, bytes32) { + LogTrigger memory trigger = abi.decode(rawTrigger, (LogTrigger)); + bytes32 dedupID = keccak256(abi.encodePacked(upkeepId, trigger.logBlockHash, trigger.txHash, trigger.logIndex)); + if ( + (hotVars.reorgProtectionEnabled && + (trigger.blockHash != bytes32("") && hotVars.chainModule.blockHash(trigger.blockNum) != trigger.blockHash)) || + trigger.blockNum >= blocknumber + ) { + // Reorg protection is same as conditional trigger upkeeps + emit ReorgedUpkeepReport(upkeepId, rawTrigger); + return (false, dedupID); + } + if (s_dedupKeys[dedupID]) { + emit StaleUpkeepReport(upkeepId, rawTrigger); + return (false, dedupID); + } + return (true, dedupID); + } + + /** + * @dev Verify signatures attached to report + */ + function _verifyReportSignature( + bytes32[3] calldata reportContext, + bytes calldata report, + bytes32[] calldata rs, + bytes32[] calldata ss, + bytes32 rawVs + ) internal view { + bytes32 h = keccak256(abi.encode(keccak256(report), reportContext)); + // i-th byte counts number of sigs made by i-th signer + uint256 signedCount = 0; + + Signer memory signer; + address signerAddress; + for (uint256 i = 0; i < rs.length; i++) { + signerAddress = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]); + signer = s_signers[signerAddress]; + if (!signer.active) revert OnlyActiveSigners(); + unchecked { + signedCount += 1 << (8 * signer.index); + } + } + + if (signedCount & ORACLE_MASK != signedCount) revert DuplicateSigners(); + } + + /** + * @dev updates a storage marker for this upkeep to prevent duplicate and out of order performances + * @dev for conditional triggers we set the latest block number, for log triggers we store a dedupID + */ + function _updateTriggerMarker( + uint256 upkeepID, + uint256 blocknumber, + UpkeepTransmitInfo memory upkeepTransmitInfo + ) internal { + if (upkeepTransmitInfo.triggerType == Trigger.CONDITION) { + s_upkeep[upkeepID].lastPerformedBlockNumber = uint32(blocknumber); + } else if (upkeepTransmitInfo.triggerType == Trigger.LOG) { + s_dedupKeys[upkeepTransmitInfo.dedupID] = true; + emit DedupKeyAdded(upkeepTransmitInfo.dedupID); + } + } + + /** + * @dev calls the Upkeep target with the performData param passed in by the + * transmitter and the exact gas required by the Upkeep + */ + function _performUpkeep( + IAutomationForwarder forwarder, + uint256 performGas, + bytes memory performData + ) internal nonReentrant returns (bool success, uint256 gasUsed) { + performData = abi.encodeWithSelector(PERFORM_SELECTOR, performData); + return forwarder.forward(performGas, performData); + } + + /** + * @dev handles the payment processing after an upkeep has been performed. + * Deducts an upkeep's balance and increases the amount spent. + */ + function _handlePayment( + HotVars memory hotVars, + PaymentParams memory paymentParams, + uint256 upkeepId, + Upkeep memory upkeep + ) internal returns (PaymentReceipt memory) { + if (upkeep.overridesEnabled) { + BillingOverrides memory billingOverrides = s_billingOverrides[upkeepId]; + // use the overridden configs + paymentParams.billingTokenParams.gasFeePPB = billingOverrides.gasFeePPB; + paymentParams.billingTokenParams.flatFeeMilliCents = billingOverrides.flatFeeMilliCents; + } + + PaymentReceipt memory receipt = _calculatePaymentAmount(hotVars, paymentParams); + + // balance is in the token's native decimals + uint96 balance = upkeep.balance; + // payment is in the token's native decimals + uint96 payment = receipt.gasChargeInBillingToken + receipt.premiumInBillingToken; + + // scaling factors to adjust decimals between billing token and LINK + uint256 decimals = paymentParams.billingTokenParams.decimals; + uint256 scalingFactor1 = decimals < 18 ? 10 ** (18 - decimals) : 1; + uint256 scalingFactor2 = decimals > 18 ? 10 ** (decimals - 18) : 1; + + // this shouldn't happen, but in rare edge cases, we charge the full balance in case the user + // can't cover the amount owed + if (balance < receipt.gasChargeInBillingToken) { + // if the user can't cover the gas fee, then direct all of the payment to the transmitter and distribute no premium to the DON + payment = balance; + receipt.gasReimbursementInJuels = SafeCast.toUint96( + (balance * paymentParams.billingTokenParams.priceUSD * scalingFactor1) / + (paymentParams.linkUSD * scalingFactor2) + ); + receipt.premiumInJuels = 0; + receipt.premiumInBillingToken = 0; + receipt.gasChargeInBillingToken = balance; + } else if (balance < payment) { + // if the user can cover the gas fee, but not the premium, then reduce the premium + payment = balance; + receipt.premiumInJuels = SafeCast.toUint96( + ((balance * paymentParams.billingTokenParams.priceUSD * scalingFactor1) / + (paymentParams.linkUSD * scalingFactor2)) - receipt.gasReimbursementInJuels + ); + // round up + receipt.premiumInBillingToken = SafeCast.toUint96( + ((receipt.premiumInJuels * paymentParams.linkUSD * scalingFactor2) + + (paymentParams.billingTokenParams.priceUSD * scalingFactor1 - 1)) / + (paymentParams.billingTokenParams.priceUSD * scalingFactor1) + ); + } + + s_upkeep[upkeepId].balance -= payment; + s_upkeep[upkeepId].amountSpent += payment; + s_reserveAmounts[paymentParams.billingToken] -= payment; + + emit UpkeepCharged(upkeepId, receipt); + return receipt; + } + + /** + * @dev ensures the upkeep is not cancelled and the caller is the upkeep admin + */ + function _requireAdminAndNotCancelled(uint256 upkeepId) internal view { + if (msg.sender != s_upkeepAdmin[upkeepId]) revert OnlyCallableByAdmin(); + if (s_upkeep[upkeepId].maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); + } + + /** + * @dev replicates Open Zeppelin's ReentrancyGuard but optimized to fit our storage + */ + modifier nonReentrant() { + if (s_hotVars.reentrancyGuard) revert ReentrantCall(); + s_hotVars.reentrancyGuard = true; + _; + s_hotVars.reentrancyGuard = false; + } + + /** + * @notice only allows a pre-configured address to initiate offchain read + */ + function _preventExecution() internal view { + // solhint-disable-next-line avoid-tx-origin + if (tx.origin != i_allowedReadOnlyAddress) { + revert OnlySimulatedBackend(); + } + } + + /** + * @notice only allows finance admin to call the function + */ + function _onlyFinanceAdminAllowed() internal view { + if (msg.sender != s_storage.financeAdmin) { + revert OnlyFinanceAdmin(); + } + } + + /** + * @notice only allows privilege manager to call the function + */ + function _onlyPrivilegeManagerAllowed() internal view { + if (msg.sender != s_storage.upkeepPrivilegeManager) { + revert OnlyCallableByUpkeepPrivilegeManager(); + } + } + + /** + * @notice sets billing configuration for a token + * @param billingTokens the addresses of tokens + * @param billingConfigs the configs for tokens + */ + function _setBillingConfig(IERC20[] memory billingTokens, BillingConfig[] memory billingConfigs) internal { + // Clear existing data + for (uint256 i = 0; i < s_billingTokens.length; i++) { + delete s_billingConfigs[s_billingTokens[i]]; + } + delete s_billingTokens; + + PayoutMode mode = s_payoutMode; + for (uint256 i = 0; i < billingTokens.length; i++) { + IERC20 token = billingTokens[i]; + BillingConfig memory config = billingConfigs[i]; + + // most ERC20 tokens are 18 decimals, priceFeed must be 8 decimals + if (config.decimals != token.decimals() || config.priceFeed.decimals() != 8) { + revert InvalidToken(); + } + + // if LINK is a billing option, payout mode must be ON_CHAIN + if (address(token) == address(i_link) && mode == PayoutMode.OFF_CHAIN) { + revert InvalidToken(); + } + if (address(token) == ZERO_ADDRESS || address(config.priceFeed) == ZERO_ADDRESS) { + revert ZeroAddressNotAllowed(); + } + + // if this is a new token, add it to tokens list. Otherwise revert + if (address(s_billingConfigs[token].priceFeed) != ZERO_ADDRESS) { + revert DuplicateEntry(); + } + s_billingTokens.push(token); + + // update the billing config for an existing token or add a new one + s_billingConfigs[token] = config; + + emit BillingConfigSet(token, config); + } + } + + /** + * @notice updates the signers and transmitters lists + */ + function _updateTransmitters(address[] memory signers, address[] memory transmitters) internal { + uint96 transmittersListLength = uint96(s_transmittersList.length); + uint96 totalPremium = s_hotVars.totalPremium; + + // move all pooled payments out of the pool to each transmitter's balance + for (uint256 i = 0; i < s_transmittersList.length; i++) { + _updateTransmitterBalanceFromPool(s_transmittersList[i], totalPremium, transmittersListLength); + } + + // remove any old signer/transmitter addresses + address transmitterAddress; + PayoutMode mode = s_payoutMode; + for (uint256 i = 0; i < s_transmittersList.length; i++) { + transmitterAddress = s_transmittersList[i]; + delete s_signers[s_signersList[i]]; + // Do not delete the whole transmitter struct as it has balance information stored + s_transmitters[transmitterAddress].active = false; + if (mode == PayoutMode.OFF_CHAIN && s_transmitters[transmitterAddress].balance > 0) { + s_deactivatedTransmitters.add(transmitterAddress); + } + } + delete s_signersList; + delete s_transmittersList; + + // add new signer/transmitter addresses + Transmitter memory transmitter; + for (uint256 i = 0; i < signers.length; i++) { + if (s_signers[signers[i]].active) revert RepeatedSigner(); + if (signers[i] == ZERO_ADDRESS) revert InvalidSigner(); + s_signers[signers[i]] = Signer({active: true, index: uint8(i)}); + + transmitterAddress = transmitters[i]; + if (transmitterAddress == ZERO_ADDRESS) revert InvalidTransmitter(); + transmitter = s_transmitters[transmitterAddress]; + if (transmitter.active) revert RepeatedTransmitter(); + transmitter.active = true; + transmitter.index = uint8(i); + // new transmitters start afresh from current totalPremium + // some spare change of premium from previous pool will be forfeited + transmitter.lastCollected = s_hotVars.totalPremium; + s_transmitters[transmitterAddress] = transmitter; + if (mode == PayoutMode.OFF_CHAIN) { + s_deactivatedTransmitters.remove(transmitterAddress); + } + } + + s_signersList = signers; + s_transmittersList = transmitters; + } + + /** + * @notice returns the size of the LINK liquidity pool + # @dev LINK max supply < 2^96, so casting to int256 is safe + */ + function _linkAvailableForPayment() internal view returns (int256) { + return int256(i_link.balanceOf(address(this))) - int256(s_reserveAmounts[IERC20(address(i_link))]); + } +} diff --git a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicA2_3.sol b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicA2_3.sol new file mode 100644 index 0000000000..64d697c70f --- /dev/null +++ b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicA2_3.sol @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {ZKSyncAutomationRegistryBase2_3} from "./ZKSyncAutomationRegistryBase2_3.sol"; +import {ZKSyncAutomationRegistryLogicC2_3} from "./ZKSyncAutomationRegistryLogicC2_3.sol"; +import {ZKSyncAutomationRegistryLogicB2_3} from "./ZKSyncAutomationRegistryLogicB2_3.sol"; +import {Chainable} from "../Chainable.sol"; +import {ZKSyncAutomationForwarder} from "../ZKSyncAutomationForwarder.sol"; +import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol"; +import {UpkeepTranscoderInterfaceV2} from "../interfaces/UpkeepTranscoderInterfaceV2.sol"; +import {MigratableKeeperRegistryInterfaceV2} from "../interfaces/MigratableKeeperRegistryInterfaceV2.sol"; +import {IERC20Metadata as IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IERC677Receiver} from "../../shared/interfaces/IERC677Receiver.sol"; + +/** + * @notice Logic contract, works in tandem with AutomationRegistry as a proxy + */ +contract ZKSyncAutomationRegistryLogicA2_3 is ZKSyncAutomationRegistryBase2_3, Chainable, IERC677Receiver { + using Address for address; + using EnumerableSet for EnumerableSet.UintSet; + using EnumerableSet for EnumerableSet.AddressSet; + using SafeERC20 for IERC20; + + /** + * @param logicB the address of the second logic contract + * @dev we cast the contract to logicC in order to call logicC functions (via fallback) + */ + constructor( + ZKSyncAutomationRegistryLogicB2_3 logicB + ) + ZKSyncAutomationRegistryBase2_3( + ZKSyncAutomationRegistryLogicC2_3(address(logicB)).getLinkAddress(), + ZKSyncAutomationRegistryLogicC2_3(address(logicB)).getLinkUSDFeedAddress(), + ZKSyncAutomationRegistryLogicC2_3(address(logicB)).getNativeUSDFeedAddress(), + ZKSyncAutomationRegistryLogicC2_3(address(logicB)).getFastGasFeedAddress(), + ZKSyncAutomationRegistryLogicC2_3(address(logicB)).getAutomationForwarderLogic(), + ZKSyncAutomationRegistryLogicC2_3(address(logicB)).getAllowedReadOnlyAddress(), + ZKSyncAutomationRegistryLogicC2_3(address(logicB)).getPayoutMode(), + ZKSyncAutomationRegistryLogicC2_3(address(logicB)).getWrappedNativeTokenAddress() + ) + Chainable(address(logicB)) + {} + + /** + * @notice uses LINK's transferAndCall to LINK and add funding to an upkeep + * @dev safe to cast uint256 to uint96 as total LINK supply is under UINT96MAX + * @param sender the account which transferred the funds + * @param amount number of LINK transfer + */ + function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external override { + if (msg.sender != address(i_link)) revert OnlyCallableByLINKToken(); + if (data.length != 32) revert InvalidDataLength(); + uint256 id = abi.decode(data, (uint256)); + if (s_upkeep[id].maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); + if (address(s_upkeep[id].billingToken) != address(i_link)) revert InvalidToken(); + s_upkeep[id].balance = s_upkeep[id].balance + uint96(amount); + s_reserveAmounts[IERC20(address(i_link))] = s_reserveAmounts[IERC20(address(i_link))] + amount; + emit FundsAdded(id, sender, uint96(amount)); + } + + // ================================================================ + // | UPKEEP MANAGEMENT | + // ================================================================ + + /** + * @notice adds a new upkeep + * @param target address to perform upkeep on + * @param gasLimit amount of gas to provide the target contract when + * performing upkeep + * @param admin address to cancel upkeep and withdraw remaining funds + * @param triggerType the trigger for the upkeep + * @param billingToken the billing token for the upkeep + * @param checkData data passed to the contract when checking for upkeep + * @param triggerConfig the config for the trigger + * @param offchainConfig arbitrary offchain config for the upkeep + */ + function registerUpkeep( + address target, + uint32 gasLimit, + address admin, + Trigger triggerType, + IERC20 billingToken, + bytes calldata checkData, + bytes memory triggerConfig, + bytes memory offchainConfig + ) public returns (uint256 id) { + if (msg.sender != owner() && !s_registrars.contains(msg.sender)) revert OnlyCallableByOwnerOrRegistrar(); + if (!target.isContract()) revert NotAContract(); + id = _createID(triggerType); + IAutomationForwarder forwarder = IAutomationForwarder( + address(new ZKSyncAutomationForwarder(target, address(this), i_automationForwarderLogic)) + ); + _createUpkeep( + id, + Upkeep({ + overridesEnabled: false, + performGas: gasLimit, + balance: 0, + maxValidBlocknumber: UINT32_MAX, + lastPerformedBlockNumber: 0, + amountSpent: 0, + paused: false, + forwarder: forwarder, + billingToken: billingToken + }), + admin, + checkData, + triggerConfig, + offchainConfig + ); + s_storage.nonce++; + emit UpkeepRegistered(id, gasLimit, admin); + emit UpkeepCheckDataSet(id, checkData); + emit UpkeepTriggerConfigSet(id, triggerConfig); + emit UpkeepOffchainConfigSet(id, offchainConfig); + return (id); + } + + /** + * @notice cancels an upkeep + * @param id the upkeepID to cancel + * @dev if a user cancels an upkeep, their funds are locked for CANCELLATION_DELAY blocks to + * allow any pending performUpkeep txs time to get confirmed + */ + function cancelUpkeep(uint256 id) external { + Upkeep memory upkeep = s_upkeep[id]; + bool isOwner = msg.sender == owner(); + uint96 minSpend = s_billingConfigs[upkeep.billingToken].minSpend; + + uint256 height = s_hotVars.chainModule.blockNumber(); + if (upkeep.maxValidBlocknumber == 0) revert CannotCancel(); + if (upkeep.maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); + if (!isOwner && msg.sender != s_upkeepAdmin[id]) revert OnlyCallableByOwnerOrAdmin(); + + if (!isOwner) { + height = height + CANCELLATION_DELAY; + } + s_upkeep[id].maxValidBlocknumber = uint32(height); + s_upkeepIDs.remove(id); + + // charge the cancellation fee if the minSpend is not met + uint96 cancellationFee = 0; + // cancellationFee is min(max(minSpend - amountSpent, 0), amountLeft) + if (upkeep.amountSpent < minSpend) { + cancellationFee = minSpend - uint96(upkeep.amountSpent); + if (cancellationFee > upkeep.balance) { + cancellationFee = upkeep.balance; + } + } + s_upkeep[id].balance = upkeep.balance - cancellationFee; + s_reserveAmounts[upkeep.billingToken] = s_reserveAmounts[upkeep.billingToken] - cancellationFee; + + emit UpkeepCanceled(id, uint64(height)); + } + + /** + * @notice migrates upkeeps from one registry to another. + * @param ids the upkeepIDs to migrate + * @param destination the destination registry address + * @dev a transcoder must be set in order to enable migration + * @dev migration permissions must be set on *both* sending and receiving registries + * @dev only an upkeep admin can migrate their upkeeps + * @dev this function is most gas-efficient if upkeepIDs are sorted by billing token + * @dev s_billingOverrides and s_upkeepPrivilegeConfig are not migrated in this function + */ + function migrateUpkeeps(uint256[] calldata ids, address destination) external { + if ( + s_peerRegistryMigrationPermission[destination] != MigrationPermission.OUTGOING && + s_peerRegistryMigrationPermission[destination] != MigrationPermission.BIDIRECTIONAL + ) revert MigrationNotPermitted(); + if (s_storage.transcoder == ZERO_ADDRESS) revert TranscoderNotSet(); + if (ids.length == 0) revert ArrayHasNoEntries(); + + IERC20 billingToken; + uint256 balanceToTransfer; + uint256 id; + Upkeep memory upkeep; + address[] memory admins = new address[](ids.length); + Upkeep[] memory upkeeps = new Upkeep[](ids.length); + bytes[] memory checkDatas = new bytes[](ids.length); + bytes[] memory triggerConfigs = new bytes[](ids.length); + bytes[] memory offchainConfigs = new bytes[](ids.length); + + for (uint256 idx = 0; idx < ids.length; idx++) { + id = ids[idx]; + upkeep = s_upkeep[id]; + + if (idx == 0) { + billingToken = upkeep.billingToken; + balanceToTransfer = upkeep.balance; + } + + // if we encounter a new billing token, send the sum from the last billing token to the destination registry + if (upkeep.billingToken != billingToken) { + s_reserveAmounts[billingToken] = s_reserveAmounts[billingToken] - balanceToTransfer; + billingToken.safeTransfer(destination, balanceToTransfer); + billingToken = upkeep.billingToken; + balanceToTransfer = upkeep.balance; + } else if (idx != 0) { + balanceToTransfer += upkeep.balance; + } + + _requireAdminAndNotCancelled(id); + upkeep.forwarder.updateRegistry(destination); + + upkeeps[idx] = upkeep; + admins[idx] = s_upkeepAdmin[id]; + checkDatas[idx] = s_checkData[id]; + triggerConfigs[idx] = s_upkeepTriggerConfig[id]; + offchainConfigs[idx] = s_upkeepOffchainConfig[id]; + delete s_upkeep[id]; + delete s_checkData[id]; + delete s_upkeepTriggerConfig[id]; + delete s_upkeepOffchainConfig[id]; + // nullify existing proposed admin change if an upkeep is being migrated + delete s_proposedAdmin[id]; + delete s_upkeepAdmin[id]; + s_upkeepIDs.remove(id); + emit UpkeepMigrated(id, upkeep.balance, destination); + } + // always transfer the rolling sum in the end + s_reserveAmounts[billingToken] = s_reserveAmounts[billingToken] - balanceToTransfer; + billingToken.safeTransfer(destination, balanceToTransfer); + + bytes memory encodedUpkeeps = abi.encode( + ids, + upkeeps, + new address[](ids.length), + admins, + checkDatas, + triggerConfigs, + offchainConfigs + ); + MigratableKeeperRegistryInterfaceV2(destination).receiveUpkeeps( + UpkeepTranscoderInterfaceV2(s_storage.transcoder).transcodeUpkeeps( + UPKEEP_VERSION_BASE, + MigratableKeeperRegistryInterfaceV2(destination).upkeepVersion(), + encodedUpkeeps + ) + ); + } + + /** + * @notice received upkeeps migrated from another registry + * @param encodedUpkeeps the raw upkeep data to import + * @dev this function is never called directly, it is only called by another registry's migrate function + * @dev s_billingOverrides and s_upkeepPrivilegeConfig are not handled in this function + */ + function receiveUpkeeps(bytes calldata encodedUpkeeps) external { + if ( + s_peerRegistryMigrationPermission[msg.sender] != MigrationPermission.INCOMING && + s_peerRegistryMigrationPermission[msg.sender] != MigrationPermission.BIDIRECTIONAL + ) revert MigrationNotPermitted(); + ( + uint256[] memory ids, + Upkeep[] memory upkeeps, + address[] memory targets, + address[] memory upkeepAdmins, + bytes[] memory checkDatas, + bytes[] memory triggerConfigs, + bytes[] memory offchainConfigs + ) = abi.decode(encodedUpkeeps, (uint256[], Upkeep[], address[], address[], bytes[], bytes[], bytes[])); + for (uint256 idx = 0; idx < ids.length; idx++) { + if (address(upkeeps[idx].forwarder) == ZERO_ADDRESS) { + upkeeps[idx].forwarder = IAutomationForwarder( + address(new ZKSyncAutomationForwarder(targets[idx], address(this), i_automationForwarderLogic)) + ); + } + _createUpkeep( + ids[idx], + upkeeps[idx], + upkeepAdmins[idx], + checkDatas[idx], + triggerConfigs[idx], + offchainConfigs[idx] + ); + emit UpkeepReceived(ids[idx], upkeeps[idx].balance, msg.sender); + } + } +} diff --git a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicB2_3.sol b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicB2_3.sol new file mode 100644 index 0000000000..55af99fde8 --- /dev/null +++ b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicB2_3.sol @@ -0,0 +1,449 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {ZKSyncAutomationRegistryBase2_3} from "./ZKSyncAutomationRegistryBase2_3.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {ZKSyncAutomationRegistryLogicC2_3} from "./ZKSyncAutomationRegistryLogicC2_3.sol"; +import {Chainable} from "../Chainable.sol"; +import {IERC20Metadata as IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {SafeCast} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/SafeCast.sol"; + +contract ZKSyncAutomationRegistryLogicB2_3 is ZKSyncAutomationRegistryBase2_3, Chainable { + using Address for address; + using EnumerableSet for EnumerableSet.UintSet; + using EnumerableSet for EnumerableSet.AddressSet; + using SafeERC20 for IERC20; + + /** + * @param logicC the address of the third logic contract + */ + constructor( + ZKSyncAutomationRegistryLogicC2_3 logicC + ) + ZKSyncAutomationRegistryBase2_3( + logicC.getLinkAddress(), + logicC.getLinkUSDFeedAddress(), + logicC.getNativeUSDFeedAddress(), + logicC.getFastGasFeedAddress(), + logicC.getAutomationForwarderLogic(), + logicC.getAllowedReadOnlyAddress(), + logicC.getPayoutMode(), + logicC.getWrappedNativeTokenAddress() + ) + Chainable(address(logicC)) + {} + + // ================================================================ + // | PIPELINE FUNCTIONS | + // ================================================================ + + /** + * @notice called by the automation DON to check if work is needed + * @param id the upkeep ID to check for work needed + * @param triggerData extra contextual data about the trigger (not used in all code paths) + * @dev this one of the core functions called in the hot path + * @dev there is a 2nd checkUpkeep function (below) that is being maintained for backwards compatibility + * @dev there is an incongruency on what gets returned during failure modes + * ex sometimes we include price data, sometimes we omit it depending on the failure + */ + function checkUpkeep( + uint256 id, + bytes memory triggerData + ) + public + returns ( + bool upkeepNeeded, + bytes memory performData, + UpkeepFailureReason upkeepFailureReason, + uint256 gasUsed, + uint256 gasLimit, + uint256 fastGasWei, + uint256 linkUSD + ) + { + _preventExecution(); + + Trigger triggerType = _getTriggerType(id); + HotVars memory hotVars = s_hotVars; + Upkeep memory upkeep = s_upkeep[id]; + + { + uint256 nativeUSD; + uint96 maxPayment; + if (hotVars.paused) return (false, bytes(""), UpkeepFailureReason.REGISTRY_PAUSED, 0, upkeep.performGas, 0, 0); + if (upkeep.maxValidBlocknumber != UINT32_MAX) + return (false, bytes(""), UpkeepFailureReason.UPKEEP_CANCELLED, 0, upkeep.performGas, 0, 0); + if (upkeep.paused) return (false, bytes(""), UpkeepFailureReason.UPKEEP_PAUSED, 0, upkeep.performGas, 0, 0); + (fastGasWei, linkUSD, nativeUSD) = _getFeedData(hotVars); + maxPayment = _getMaxPayment( + id, + hotVars, + triggerType, + upkeep.performGas, + fastGasWei, + linkUSD, + nativeUSD, + upkeep.billingToken + ); + if (upkeep.balance < maxPayment) { + return (false, bytes(""), UpkeepFailureReason.INSUFFICIENT_BALANCE, 0, upkeep.performGas, 0, 0); + } + } + + bytes memory callData = _checkPayload(id, triggerType, triggerData); + + gasUsed = gasleft(); + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory result) = upkeep.forwarder.getTarget().call{gas: s_storage.checkGasLimit}(callData); + gasUsed = gasUsed - gasleft(); + + if (!success) { + // User's target check reverted. We capture the revert data here and pass it within performData + if (result.length > s_storage.maxRevertDataSize) { + return ( + false, + bytes(""), + UpkeepFailureReason.REVERT_DATA_EXCEEDS_LIMIT, + gasUsed, + upkeep.performGas, + fastGasWei, + linkUSD + ); + } + return ( + upkeepNeeded, + result, + UpkeepFailureReason.TARGET_CHECK_REVERTED, + gasUsed, + upkeep.performGas, + fastGasWei, + linkUSD + ); + } + + (upkeepNeeded, performData) = abi.decode(result, (bool, bytes)); + if (!upkeepNeeded) + return (false, bytes(""), UpkeepFailureReason.UPKEEP_NOT_NEEDED, gasUsed, upkeep.performGas, fastGasWei, linkUSD); + + if (performData.length > s_storage.maxPerformDataSize) + return ( + false, + bytes(""), + UpkeepFailureReason.PERFORM_DATA_EXCEEDS_LIMIT, + gasUsed, + upkeep.performGas, + fastGasWei, + linkUSD + ); + + return (upkeepNeeded, performData, upkeepFailureReason, gasUsed, upkeep.performGas, fastGasWei, linkUSD); + } + + /** + * @notice see other checkUpkeep function for description + * @dev this function may be deprecated in a future version of chainlink automation + */ + function checkUpkeep( + uint256 id + ) + external + returns ( + bool upkeepNeeded, + bytes memory performData, + UpkeepFailureReason upkeepFailureReason, + uint256 gasUsed, + uint256 gasLimit, + uint256 fastGasWei, + uint256 linkUSD + ) + { + return checkUpkeep(id, bytes("")); + } + + /** + * @dev checkCallback is used specifically for automation data streams lookups (see StreamsLookupCompatibleInterface.sol) + * @param id the upkeepID to execute a callback for + * @param values the values returned from the data streams lookup + * @param extraData the user-provided extra context data + */ + function checkCallback( + uint256 id, + bytes[] memory values, + bytes calldata extraData + ) + external + returns (bool upkeepNeeded, bytes memory performData, UpkeepFailureReason upkeepFailureReason, uint256 gasUsed) + { + bytes memory payload = abi.encodeWithSelector(CHECK_CALLBACK_SELECTOR, values, extraData); + return executeCallback(id, payload); + } + + /** + * @notice this is a generic callback executor that forwards a call to a user's contract with the configured + * gas limit + * @param id the upkeepID to execute a callback for + * @param payload the data (including function selector) to call on the upkeep target contract + */ + function executeCallback( + uint256 id, + bytes memory payload + ) + public + returns (bool upkeepNeeded, bytes memory performData, UpkeepFailureReason upkeepFailureReason, uint256 gasUsed) + { + _preventExecution(); + + Upkeep memory upkeep = s_upkeep[id]; + gasUsed = gasleft(); + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory result) = upkeep.forwarder.getTarget().call{gas: s_storage.checkGasLimit}(payload); + gasUsed = gasUsed - gasleft(); + if (!success) { + return (false, bytes(""), UpkeepFailureReason.CALLBACK_REVERTED, gasUsed); + } + (upkeepNeeded, performData) = abi.decode(result, (bool, bytes)); + if (!upkeepNeeded) { + return (false, bytes(""), UpkeepFailureReason.UPKEEP_NOT_NEEDED, gasUsed); + } + if (performData.length > s_storage.maxPerformDataSize) { + return (false, bytes(""), UpkeepFailureReason.PERFORM_DATA_EXCEEDS_LIMIT, gasUsed); + } + return (upkeepNeeded, performData, upkeepFailureReason, gasUsed); + } + + /** + * @notice simulates the upkeep with the perform data returned from checkUpkeep + * @param id identifier of the upkeep to execute the data with. + * @param performData calldata parameter to be passed to the target upkeep. + * @return success whether the call reverted or not + * @return gasUsed the amount of gas the target contract consumed + */ + function simulatePerformUpkeep( + uint256 id, + bytes calldata performData + ) external returns (bool success, uint256 gasUsed) { + _preventExecution(); + + if (s_hotVars.paused) revert RegistryPaused(); + Upkeep memory upkeep = s_upkeep[id]; + (success, gasUsed) = _performUpkeep(upkeep.forwarder, upkeep.performGas, performData); + return (success, gasUsed); + } + + // ================================================================ + // | UPKEEP MANAGEMENT | + // ================================================================ + + /** + * @notice adds fund to an upkeep + * @param id the upkeepID + * @param amount the amount of funds to add, in the upkeep's billing token + */ + function addFunds(uint256 id, uint96 amount) external payable { + Upkeep memory upkeep = s_upkeep[id]; + if (upkeep.maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); + + if (msg.value != 0) { + if (upkeep.billingToken != IERC20(i_wrappedNativeToken)) { + revert InvalidToken(); + } + amount = SafeCast.toUint96(msg.value); + } + + s_upkeep[id].balance = upkeep.balance + amount; + s_reserveAmounts[upkeep.billingToken] = s_reserveAmounts[upkeep.billingToken] + amount; + + if (msg.value == 0) { + // ERC20 payment + upkeep.billingToken.safeTransferFrom(msg.sender, address(this), amount); + } else { + // native payment + i_wrappedNativeToken.deposit{value: amount}(); + } + + emit FundsAdded(id, msg.sender, amount); + } + + /** + * @notice overrides the billing config for an upkeep + * @param id the upkeepID + * @param billingOverrides the override-able billing config + */ + function setBillingOverrides(uint256 id, BillingOverrides calldata billingOverrides) external { + _onlyPrivilegeManagerAllowed(); + if (s_upkeep[id].maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); + + s_upkeep[id].overridesEnabled = true; + s_billingOverrides[id] = billingOverrides; + emit BillingConfigOverridden(id, billingOverrides); + } + + /** + * @notice remove the overridden billing config for an upkeep + * @param id the upkeepID + */ + function removeBillingOverrides(uint256 id) external { + _onlyPrivilegeManagerAllowed(); + + s_upkeep[id].overridesEnabled = false; + delete s_billingOverrides[id]; + emit BillingConfigOverrideRemoved(id); + } + + /** + * @notice transfers the address of an admin for an upkeep + */ + function transferUpkeepAdmin(uint256 id, address proposed) external { + _requireAdminAndNotCancelled(id); + if (proposed == msg.sender) revert ValueNotChanged(); + + if (s_proposedAdmin[id] != proposed) { + s_proposedAdmin[id] = proposed; + emit UpkeepAdminTransferRequested(id, msg.sender, proposed); + } + } + + /** + * @notice accepts the transfer of an upkeep admin + */ + function acceptUpkeepAdmin(uint256 id) external { + Upkeep memory upkeep = s_upkeep[id]; + if (upkeep.maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); + if (s_proposedAdmin[id] != msg.sender) revert OnlyCallableByProposedAdmin(); + address past = s_upkeepAdmin[id]; + s_upkeepAdmin[id] = msg.sender; + s_proposedAdmin[id] = ZERO_ADDRESS; + + emit UpkeepAdminTransferred(id, past, msg.sender); + } + + /** + * @notice pauses an upkeep - an upkeep will be neither checked nor performed while paused + */ + function pauseUpkeep(uint256 id) external { + _requireAdminAndNotCancelled(id); + Upkeep memory upkeep = s_upkeep[id]; + if (upkeep.paused) revert OnlyUnpausedUpkeep(); + s_upkeep[id].paused = true; + s_upkeepIDs.remove(id); + emit UpkeepPaused(id); + } + + /** + * @notice unpauses an upkeep + */ + function unpauseUpkeep(uint256 id) external { + _requireAdminAndNotCancelled(id); + Upkeep memory upkeep = s_upkeep[id]; + if (!upkeep.paused) revert OnlyPausedUpkeep(); + s_upkeep[id].paused = false; + s_upkeepIDs.add(id); + emit UpkeepUnpaused(id); + } + + /** + * @notice updates the checkData for an upkeep + */ + function setUpkeepCheckData(uint256 id, bytes calldata newCheckData) external { + _requireAdminAndNotCancelled(id); + if (newCheckData.length > s_storage.maxCheckDataSize) revert CheckDataExceedsLimit(); + s_checkData[id] = newCheckData; + emit UpkeepCheckDataSet(id, newCheckData); + } + + /** + * @notice updates the gas limit for an upkeep + */ + function setUpkeepGasLimit(uint256 id, uint32 gasLimit) external { + if (gasLimit < PERFORM_GAS_MIN || gasLimit > s_storage.maxPerformGas) revert GasLimitOutsideRange(); + _requireAdminAndNotCancelled(id); + s_upkeep[id].performGas = gasLimit; + + emit UpkeepGasLimitSet(id, gasLimit); + } + + /** + * @notice updates the offchain config for an upkeep + */ + function setUpkeepOffchainConfig(uint256 id, bytes calldata config) external { + _requireAdminAndNotCancelled(id); + s_upkeepOffchainConfig[id] = config; + emit UpkeepOffchainConfigSet(id, config); + } + + /** + * @notice sets the upkeep trigger config + * @param id the upkeepID to change the trigger for + * @param triggerConfig the new trigger config + */ + function setUpkeepTriggerConfig(uint256 id, bytes calldata triggerConfig) external { + _requireAdminAndNotCancelled(id); + s_upkeepTriggerConfig[id] = triggerConfig; + emit UpkeepTriggerConfigSet(id, triggerConfig); + } + + /** + * @notice withdraws an upkeep's funds from an upkeep + * @dev note that an upkeep must be cancelled first!! + */ + function withdrawFunds(uint256 id, address to) external nonReentrant { + if (to == ZERO_ADDRESS) revert InvalidRecipient(); + Upkeep memory upkeep = s_upkeep[id]; + if (s_upkeepAdmin[id] != msg.sender) revert OnlyCallableByAdmin(); + if (upkeep.maxValidBlocknumber > s_hotVars.chainModule.blockNumber()) revert UpkeepNotCanceled(); + uint96 amountToWithdraw = s_upkeep[id].balance; + s_reserveAmounts[upkeep.billingToken] = s_reserveAmounts[upkeep.billingToken] - amountToWithdraw; + s_upkeep[id].balance = 0; + upkeep.billingToken.safeTransfer(to, amountToWithdraw); + emit FundsWithdrawn(id, amountToWithdraw, to); + } + + // ================================================================ + // | FINANCE ACTIONS | + // ================================================================ + + /** + * @notice withdraws excess LINK from the liquidity pool + * @param to the address to send the fees to + * @param amount the amount to withdraw + */ + function withdrawLink(address to, uint256 amount) external { + _onlyFinanceAdminAllowed(); + if (to == ZERO_ADDRESS) revert InvalidRecipient(); + + int256 available = _linkAvailableForPayment(); + if (available < 0) { + revert InsufficientBalance(0, amount); + } else if (amount > uint256(available)) { + revert InsufficientBalance(uint256(available), amount); + } + + bool transferStatus = i_link.transfer(to, amount); + if (!transferStatus) { + revert TransferFailed(); + } + emit FeesWithdrawn(address(i_link), to, amount); + } + + /** + * @notice withdraws non-LINK fees earned by the contract + * @param asset the asset to withdraw + * @param to the address to send the fees to + * @param amount the amount to withdraw + * @dev in ON_CHAIN mode, we prevent withdrawing non-LINK fees unless there is sufficient LINK liquidity + * to cover all outstanding debts on the registry + */ + function withdrawERC20Fees(IERC20 asset, address to, uint256 amount) external { + _onlyFinanceAdminAllowed(); + if (to == ZERO_ADDRESS) revert InvalidRecipient(); + if (address(asset) == address(i_link)) revert InvalidToken(); + if (_linkAvailableForPayment() < 0 && s_payoutMode == PayoutMode.ON_CHAIN) revert InsufficientLinkLiquidity(); + uint256 available = asset.balanceOf(address(this)) - s_reserveAmounts[asset]; + if (amount > available) revert InsufficientBalance(available, amount); + + asset.safeTransfer(to, amount); + emit FeesWithdrawn(address(asset), to, amount); + } +} diff --git a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicC2_3.sol b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicC2_3.sol new file mode 100644 index 0000000000..61d0eecfba --- /dev/null +++ b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicC2_3.sol @@ -0,0 +1,638 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {ZKSyncAutomationRegistryBase2_3} from "./ZKSyncAutomationRegistryBase2_3.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol"; +import {IChainModule} from "../interfaces/IChainModule.sol"; +import {IERC20Metadata as IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import {IAutomationV21PlusCommon} from "../interfaces/IAutomationV21PlusCommon.sol"; + +contract ZKSyncAutomationRegistryLogicC2_3 is ZKSyncAutomationRegistryBase2_3 { + using Address for address; + using EnumerableSet for EnumerableSet.UintSet; + using EnumerableSet for EnumerableSet.AddressSet; + + /** + * @dev see AutomationRegistry master contract for constructor description + */ + constructor( + address link, + address linkUSDFeed, + address nativeUSDFeed, + address fastGasFeed, + address automationForwarderLogic, + address allowedReadOnlyAddress, + PayoutMode payoutMode, + address wrappedNativeTokenAddress + ) + ZKSyncAutomationRegistryBase2_3( + link, + linkUSDFeed, + nativeUSDFeed, + fastGasFeed, + automationForwarderLogic, + allowedReadOnlyAddress, + payoutMode, + wrappedNativeTokenAddress + ) + {} + + // ================================================================ + // | NODE ACTIONS | + // ================================================================ + + /** + * @notice transfers the address of payee for a transmitter + */ + function transferPayeeship(address transmitter, address proposed) external { + if (s_transmitterPayees[transmitter] != msg.sender) revert OnlyCallableByPayee(); + if (proposed == msg.sender) revert ValueNotChanged(); + + if (s_proposedPayee[transmitter] != proposed) { + s_proposedPayee[transmitter] = proposed; + emit PayeeshipTransferRequested(transmitter, msg.sender, proposed); + } + } + + /** + * @notice accepts the transfer of the payee + */ + function acceptPayeeship(address transmitter) external { + if (s_proposedPayee[transmitter] != msg.sender) revert OnlyCallableByProposedPayee(); + address past = s_transmitterPayees[transmitter]; + s_transmitterPayees[transmitter] = msg.sender; + s_proposedPayee[transmitter] = ZERO_ADDRESS; + + emit PayeeshipTransferred(transmitter, past, msg.sender); + } + + /** + * @notice this is for NOPs to withdraw LINK received as payment for work performed + */ + function withdrawPayment(address from, address to) external { + if (to == ZERO_ADDRESS) revert InvalidRecipient(); + if (s_payoutMode == PayoutMode.OFF_CHAIN) revert MustSettleOffchain(); + if (s_transmitterPayees[from] != msg.sender) revert OnlyCallableByPayee(); + uint96 balance = _updateTransmitterBalanceFromPool(from, s_hotVars.totalPremium, uint96(s_transmittersList.length)); + s_transmitters[from].balance = 0; + s_reserveAmounts[IERC20(address(i_link))] = s_reserveAmounts[IERC20(address(i_link))] - balance; + bool transferStatus = i_link.transfer(to, balance); + if (!transferStatus) { + revert TransferFailed(); + } + emit PaymentWithdrawn(from, balance, to, msg.sender); + } + + // ================================================================ + // | OWNER / MANAGER ACTIONS | + // ================================================================ + + /** + * @notice sets the privilege config for an upkeep + */ + function setUpkeepPrivilegeConfig(uint256 upkeepId, bytes calldata newPrivilegeConfig) external { + _onlyPrivilegeManagerAllowed(); + s_upkeepPrivilegeConfig[upkeepId] = newPrivilegeConfig; + emit UpkeepPrivilegeConfigSet(upkeepId, newPrivilegeConfig); + } + + /** + * @notice this is used by the owner to set the initial payees for newly added transmitters. The owner is not allowed to change payees for existing transmitters. + * @dev the IGNORE_ADDRESS is a "helper" that makes it easier to construct a list of payees when you only care about setting the payee for a small number of transmitters. + */ + function setPayees(address[] calldata payees) external onlyOwner { + if (s_transmittersList.length != payees.length) revert ParameterLengthError(); + for (uint256 i = 0; i < s_transmittersList.length; i++) { + address transmitter = s_transmittersList[i]; + address oldPayee = s_transmitterPayees[transmitter]; + address newPayee = payees[i]; + + if ( + (newPayee == ZERO_ADDRESS) || (oldPayee != ZERO_ADDRESS && oldPayee != newPayee && newPayee != IGNORE_ADDRESS) + ) { + revert InvalidPayee(); + } + + if (newPayee != IGNORE_ADDRESS) { + s_transmitterPayees[transmitter] = newPayee; + } + } + emit PayeesUpdated(s_transmittersList, payees); + } + + /** + * @notice sets the migration permission for a peer registry + * @dev this must be done before upkeeps can be migrated to/from another registry + */ + function setPeerRegistryMigrationPermission(address peer, MigrationPermission permission) external onlyOwner { + s_peerRegistryMigrationPermission[peer] = permission; + } + + /** + * @notice pauses the entire registry + */ + function pause() external onlyOwner { + s_hotVars.paused = true; + emit Paused(msg.sender); + } + + /** + * @notice unpauses the entire registry + */ + function unpause() external onlyOwner { + s_hotVars.paused = false; + emit Unpaused(msg.sender); + } + + /** + * @notice sets a generic bytes field used to indicate the privilege that this admin address had + * @param admin the address to set privilege for + * @param newPrivilegeConfig the privileges that this admin has + */ + function setAdminPrivilegeConfig(address admin, bytes calldata newPrivilegeConfig) external { + _onlyPrivilegeManagerAllowed(); + s_adminPrivilegeConfig[admin] = newPrivilegeConfig; + emit AdminPrivilegeConfigSet(admin, newPrivilegeConfig); + } + + /** + * @notice settles NOPs' LINK payment offchain + */ + function settleNOPsOffchain() external { + _onlyFinanceAdminAllowed(); + if (s_payoutMode == PayoutMode.ON_CHAIN) revert MustSettleOnchain(); + + uint96 totalPremium = s_hotVars.totalPremium; + uint256 activeTransmittersLength = s_transmittersList.length; + uint256 deactivatedTransmittersLength = s_deactivatedTransmitters.length(); + uint256 length = activeTransmittersLength + deactivatedTransmittersLength; + uint256[] memory payments = new uint256[](length); + address[] memory payees = new address[](length); + + for (uint256 i = 0; i < activeTransmittersLength; i++) { + address transmitterAddr = s_transmittersList[i]; + uint96 balance = _updateTransmitterBalanceFromPool( + transmitterAddr, + totalPremium, + uint96(activeTransmittersLength) + ); + + payments[i] = balance; + payees[i] = s_transmitterPayees[transmitterAddr]; + s_transmitters[transmitterAddr].balance = 0; + } + + for (uint256 i = 0; i < deactivatedTransmittersLength; i++) { + address deactivatedAddr = s_deactivatedTransmitters.at(i); + Transmitter memory transmitter = s_transmitters[deactivatedAddr]; + + payees[i + activeTransmittersLength] = s_transmitterPayees[deactivatedAddr]; + payments[i + activeTransmittersLength] = transmitter.balance; + s_transmitters[deactivatedAddr].balance = 0; + } + + // reserve amount of LINK is reset to 0 since no user deposits of LINK are expected in offchain mode + s_reserveAmounts[IERC20(address(i_link))] = 0; + + for (uint256 idx = s_deactivatedTransmitters.length(); idx > 0; idx--) { + s_deactivatedTransmitters.remove(s_deactivatedTransmitters.at(idx - 1)); + } + + emit NOPsSettledOffchain(payees, payments); + } + + /** + * @notice disables offchain payment for NOPs + */ + function disableOffchainPayments() external onlyOwner { + s_payoutMode = PayoutMode.ON_CHAIN; + } + + // ================================================================ + // | GETTERS | + // ================================================================ + + function getConditionalGasOverhead() external pure returns (uint256) { + return REGISTRY_CONDITIONAL_OVERHEAD; + } + + function getLogGasOverhead() external pure returns (uint256) { + return REGISTRY_LOG_OVERHEAD; + } + + function getPerPerformByteGasOverhead() external pure returns (uint256) { + return REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD; + } + + function getPerSignerGasOverhead() external pure returns (uint256) { + return REGISTRY_PER_SIGNER_GAS_OVERHEAD; + } + + function getTransmitCalldataFixedBytesOverhead() external pure returns (uint256) { + return TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD; + } + + function getTransmitCalldataPerSignerBytesOverhead() external pure returns (uint256) { + return TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD; + } + + function getCancellationDelay() external pure returns (uint256) { + return CANCELLATION_DELAY; + } + + function getLinkAddress() external view returns (address) { + return address(i_link); + } + + function getLinkUSDFeedAddress() external view returns (address) { + return address(i_linkUSDFeed); + } + + function getNativeUSDFeedAddress() external view returns (address) { + return address(i_nativeUSDFeed); + } + + function getFastGasFeedAddress() external view returns (address) { + return address(i_fastGasFeed); + } + + function getAutomationForwarderLogic() external view returns (address) { + return i_automationForwarderLogic; + } + + function getAllowedReadOnlyAddress() external view returns (address) { + return i_allowedReadOnlyAddress; + } + + function getWrappedNativeTokenAddress() external view returns (address) { + return address(i_wrappedNativeToken); + } + + function getBillingToken(uint256 upkeepID) external view returns (IERC20) { + return s_upkeep[upkeepID].billingToken; + } + + function getBillingTokens() external view returns (IERC20[] memory) { + return s_billingTokens; + } + + function supportsBillingToken(IERC20 token) external view returns (bool) { + return address(s_billingConfigs[token].priceFeed) != address(0); + } + + function getBillingTokenConfig(IERC20 token) external view returns (BillingConfig memory) { + return s_billingConfigs[token]; + } + + function getBillingOverridesEnabled(uint256 upkeepID) external view returns (bool) { + return s_upkeep[upkeepID].overridesEnabled; + } + + function getPayoutMode() external view returns (PayoutMode) { + return s_payoutMode; + } + + function upkeepVersion() public pure returns (uint8) { + return UPKEEP_VERSION_BASE; + } + + /** + * @notice gets the number of upkeeps on the registry + */ + function getNumUpkeeps() external view returns (uint256) { + return s_upkeepIDs.length(); + } + + /** + * @notice read all of the details about an upkeep + * @dev this function may be deprecated in a future version of automation in favor of individual + * getters for each field + */ + function getUpkeep(uint256 id) external view returns (IAutomationV21PlusCommon.UpkeepInfoLegacy memory upkeepInfo) { + Upkeep memory reg = s_upkeep[id]; + address target = address(reg.forwarder) == address(0) ? address(0) : reg.forwarder.getTarget(); + upkeepInfo = IAutomationV21PlusCommon.UpkeepInfoLegacy({ + target: target, + performGas: reg.performGas, + checkData: s_checkData[id], + balance: reg.balance, + admin: s_upkeepAdmin[id], + maxValidBlocknumber: reg.maxValidBlocknumber, + lastPerformedBlockNumber: reg.lastPerformedBlockNumber, + amountSpent: uint96(reg.amountSpent), // force casting to uint96 for backwards compatibility. Not an issue if it overflows. + paused: reg.paused, + offchainConfig: s_upkeepOffchainConfig[id] + }); + return upkeepInfo; + } + + /** + * @notice retrieve active upkeep IDs. Active upkeep is defined as an upkeep which is not paused and not canceled. + * @param startIndex starting index in list + * @param maxCount max count to retrieve (0 = unlimited) + * @dev the order of IDs in the list is **not guaranteed**, therefore, if making successive calls, one + * should consider keeping the blockheight constant to ensure a holistic picture of the contract state + */ + function getActiveUpkeepIDs(uint256 startIndex, uint256 maxCount) external view returns (uint256[] memory) { + uint256 numUpkeeps = s_upkeepIDs.length(); + if (startIndex >= numUpkeeps) revert IndexOutOfRange(); + uint256 endIndex = startIndex + maxCount; + endIndex = endIndex > numUpkeeps || maxCount == 0 ? numUpkeeps : endIndex; + uint256[] memory ids = new uint256[](endIndex - startIndex); + for (uint256 idx = 0; idx < ids.length; idx++) { + ids[idx] = s_upkeepIDs.at(idx + startIndex); + } + return ids; + } + + /** + * @notice returns the upkeep's trigger type + */ + function getTriggerType(uint256 upkeepId) external pure returns (Trigger) { + return _getTriggerType(upkeepId); + } + + /** + * @notice returns the trigger config for an upkeeep + */ + function getUpkeepTriggerConfig(uint256 upkeepId) public view returns (bytes memory) { + return s_upkeepTriggerConfig[upkeepId]; + } + + /** + * @notice read the current info about any transmitter address + */ + function getTransmitterInfo( + address query + ) external view returns (bool active, uint8 index, uint96 balance, uint96 lastCollected, address payee) { + Transmitter memory transmitter = s_transmitters[query]; + + uint96 pooledShare = 0; + if (transmitter.active) { + uint96 totalDifference = s_hotVars.totalPremium - transmitter.lastCollected; + pooledShare = totalDifference / uint96(s_transmittersList.length); + } + + return ( + transmitter.active, + transmitter.index, + (transmitter.balance + pooledShare), + transmitter.lastCollected, + s_transmitterPayees[query] + ); + } + + /** + * @notice read the current info about any signer address + */ + function getSignerInfo(address query) external view returns (bool active, uint8 index) { + Signer memory signer = s_signers[query]; + return (signer.active, signer.index); + } + + /** + * @notice read the current on-chain config of the registry + * @dev this function will change between versions, it should never be used where + * backwards compatibility matters! + */ + function getConfig() external view returns (OnchainConfig memory) { + return + OnchainConfig({ + checkGasLimit: s_storage.checkGasLimit, + stalenessSeconds: s_hotVars.stalenessSeconds, + gasCeilingMultiplier: s_hotVars.gasCeilingMultiplier, + maxPerformGas: s_storage.maxPerformGas, + maxCheckDataSize: s_storage.maxCheckDataSize, + maxPerformDataSize: s_storage.maxPerformDataSize, + maxRevertDataSize: s_storage.maxRevertDataSize, + fallbackGasPrice: s_fallbackGasPrice, + fallbackLinkPrice: s_fallbackLinkPrice, + fallbackNativePrice: s_fallbackNativePrice, + transcoder: s_storage.transcoder, + registrars: s_registrars.values(), + upkeepPrivilegeManager: s_storage.upkeepPrivilegeManager, + chainModule: s_hotVars.chainModule, + reorgProtectionEnabled: s_hotVars.reorgProtectionEnabled, + financeAdmin: s_storage.financeAdmin + }); + } + + /** + * @notice read the current state of the registry + * @dev this function is deprecated + */ + function getState() + external + view + returns ( + IAutomationV21PlusCommon.StateLegacy memory state, + IAutomationV21PlusCommon.OnchainConfigLegacy memory config, + address[] memory signers, + address[] memory transmitters, + uint8 f + ) + { + state = IAutomationV21PlusCommon.StateLegacy({ + nonce: s_storage.nonce, + ownerLinkBalance: 0, // deprecated + expectedLinkBalance: 0, // deprecated + totalPremium: s_hotVars.totalPremium, + numUpkeeps: s_upkeepIDs.length(), + configCount: s_storage.configCount, + latestConfigBlockNumber: s_storage.latestConfigBlockNumber, + latestConfigDigest: s_latestConfigDigest, + latestEpoch: s_hotVars.latestEpoch, + paused: s_hotVars.paused + }); + + config = IAutomationV21PlusCommon.OnchainConfigLegacy({ + paymentPremiumPPB: 0, // deprecated + flatFeeMicroLink: 0, // deprecated + checkGasLimit: s_storage.checkGasLimit, + stalenessSeconds: s_hotVars.stalenessSeconds, + gasCeilingMultiplier: s_hotVars.gasCeilingMultiplier, + minUpkeepSpend: 0, // deprecated + maxPerformGas: s_storage.maxPerformGas, + maxCheckDataSize: s_storage.maxCheckDataSize, + maxPerformDataSize: s_storage.maxPerformDataSize, + maxRevertDataSize: s_storage.maxRevertDataSize, + fallbackGasPrice: s_fallbackGasPrice, + fallbackLinkPrice: s_fallbackLinkPrice, + transcoder: s_storage.transcoder, + registrars: s_registrars.values(), + upkeepPrivilegeManager: s_storage.upkeepPrivilegeManager + }); + + return (state, config, s_signersList, s_transmittersList, s_hotVars.f); + } + + /** + * @notice read the Storage data + * @dev this function signature will change with each version of automation + * this should not be treated as a stable function + */ + function getStorage() external view returns (Storage memory) { + return s_storage; + } + + /** + * @notice read the HotVars data + * @dev this function signature will change with each version of automation + * this should not be treated as a stable function + */ + function getHotVars() external view returns (HotVars memory) { + return s_hotVars; + } + + /** + * @notice get the chain module + */ + function getChainModule() external view returns (IChainModule chainModule) { + return s_hotVars.chainModule; + } + + /** + * @notice if this registry has reorg protection enabled + */ + function getReorgProtectionEnabled() external view returns (bool reorgProtectionEnabled) { + return s_hotVars.reorgProtectionEnabled; + } + + /** + * @notice calculates the minimum balance required for an upkeep to remain eligible + * @param id the upkeep id to calculate minimum balance for + */ + function getBalance(uint256 id) external view returns (uint96 balance) { + return s_upkeep[id].balance; + } + + /** + * @notice calculates the minimum balance required for an upkeep to remain eligible + * @param id the upkeep id to calculate minimum balance for + */ + function getMinBalance(uint256 id) external view returns (uint96) { + return getMinBalanceForUpkeep(id); + } + + /** + * @notice calculates the minimum balance required for an upkeep to remain eligible + * @param id the upkeep id to calculate minimum balance for + * @dev this will be deprecated in a future version in favor of getMinBalance + */ + function getMinBalanceForUpkeep(uint256 id) public view returns (uint96 minBalance) { + Upkeep memory upkeep = s_upkeep[id]; + return getMaxPaymentForGas(id, _getTriggerType(id), upkeep.performGas, upkeep.billingToken); + } + + /** + * @notice calculates the maximum payment for a given gas limit + * @param gasLimit the gas to calculate payment for + */ + function getMaxPaymentForGas( + uint256 id, + Trigger triggerType, + uint32 gasLimit, + IERC20 billingToken + ) public view returns (uint96 maxPayment) { + HotVars memory hotVars = s_hotVars; + (uint256 fastGasWei, uint256 linkUSD, uint256 nativeUSD) = _getFeedData(hotVars); + return _getMaxPayment(id, hotVars, triggerType, gasLimit, fastGasWei, linkUSD, nativeUSD, billingToken); + } + + /** + * @notice retrieves the migration permission for a peer registry + */ + function getPeerRegistryMigrationPermission(address peer) external view returns (MigrationPermission) { + return s_peerRegistryMigrationPermission[peer]; + } + + /** + * @notice returns the upkeep privilege config + */ + function getUpkeepPrivilegeConfig(uint256 upkeepId) external view returns (bytes memory) { + return s_upkeepPrivilegeConfig[upkeepId]; + } + + /** + * @notice returns the admin's privilege config + */ + function getAdminPrivilegeConfig(address admin) external view returns (bytes memory) { + return s_adminPrivilegeConfig[admin]; + } + + /** + * @notice returns the upkeep's forwarder contract + */ + function getForwarder(uint256 upkeepID) external view returns (IAutomationForwarder) { + return s_upkeep[upkeepID].forwarder; + } + + /** + * @notice returns if the dedupKey exists or not + */ + function hasDedupKey(bytes32 dedupKey) external view returns (bool) { + return s_dedupKeys[dedupKey]; + } + + /** + * @notice returns the fallback native price + */ + function getFallbackNativePrice() external view returns (uint256) { + return s_fallbackNativePrice; + } + + /** + * @notice returns the amount of a particular token that is reserved as + * user deposits / NOP payments + */ + function getReserveAmount(IERC20 billingToken) external view returns (uint256) { + return s_reserveAmounts[billingToken]; + } + + /** + * @notice returns the amount of a particular token that is withdraw-able by finance admin + */ + function getAvailableERC20ForPayment(IERC20 billingToken) external view returns (uint256) { + return billingToken.balanceOf(address(this)) - s_reserveAmounts[IERC20(address(billingToken))]; + } + + /** + * @notice returns the size of the LINK liquidity pool + */ + function linkAvailableForPayment() public view returns (int256) { + return _linkAvailableForPayment(); + } + + /** + * @notice returns the BillingOverrides config for a given upkeep + */ + function getBillingOverrides(uint256 upkeepID) external view returns (BillingOverrides memory) { + return s_billingOverrides[upkeepID]; + } + + /** + * @notice returns the BillingConfig for a given billing token, this includes decimals and price feed etc + */ + function getBillingConfig(IERC20 billingToken) external view returns (BillingConfig memory) { + return s_billingConfigs[billingToken]; + } + + /** + * @notice returns all active transmitters with their associated payees + */ + function getTransmittersWithPayees() external view returns (TransmitterPayeeInfo[] memory) { + uint256 transmitterCount = s_transmittersList.length; + TransmitterPayeeInfo[] memory transmitters = new TransmitterPayeeInfo[](transmitterCount); + + for (uint256 i = 0; i < transmitterCount; i++) { + address transmitterAddress = s_transmittersList[i]; + address payeeAddress = s_transmitterPayees[transmitterAddress]; + + transmitters[i] = TransmitterPayeeInfo(transmitterAddress, payeeAddress); + } + + return transmitters; + } +} diff --git a/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts b/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts index 9a57226969..f993271fbb 100644 --- a/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts +++ b/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts @@ -25,7 +25,6 @@ import { ChainModuleBase__factory as ChainModuleBaseFactory } from '../../../typ import { ArbitrumModule__factory as ArbitrumModuleFactory } from '../../../typechain/factories/ArbitrumModule__factory' import { OptimismModule__factory as OptimismModuleFactory } from '../../../typechain/factories/OptimismModule__factory' import { ILogAutomation__factory as ILogAutomationactory } from '../../../typechain/factories/ILogAutomation__factory' -import { IAutomationForwarder__factory as IAutomationForwarderFactory } from '../../../typechain/factories/IAutomationForwarder__factory' import { MockArbSys__factory as MockArbSysFactory } from '../../../typechain/factories/MockArbSys__factory' import { AutomationCompatibleUtils } from '../../../typechain/AutomationCompatibleUtils' import { MockArbGasInfo } from '../../../typechain/MockArbGasInfo' diff --git a/contracts/test/v0.8/automation/helpers.ts b/contracts/test/v0.8/automation/helpers.ts index 5a95fb482c..b2cdfb4efd 100644 --- a/contracts/test/v0.8/automation/helpers.ts +++ b/contracts/test/v0.8/automation/helpers.ts @@ -170,10 +170,10 @@ export const deployRegistry23 = async ( link: Parameters[0], linkUSD: Parameters[1], nativeUSD: Parameters[2], - fastgas: Parameters[2], + fastgas: Parameters[3], allowedReadOnlyAddress: Parameters< AutomationRegistryLogicC2_3Factory['deploy'] - >[3], + >[5], payoutMode: Parameters[6], wrappedNativeTokenAddress: Parameters< AutomationRegistryLogicC2_3Factory['deploy'] From 477c8ce4b5b0a33a1645c15027bce3d23cff8c44 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 7 Aug 2024 17:38:04 +0200 Subject: [PATCH 052/432] enable gomods (#14042) --- GNUmakefile | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 3cba1738d5..3b781a665d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -27,12 +27,8 @@ gomod: ## Ensure chainlink's go dependencies are installed. go mod download .PHONY: gomodtidy -gomodtidy: ## Run go mod tidy on all modules. - go mod tidy - cd ./core/scripts && go mod tidy - cd ./integration-tests && go mod tidy - cd ./integration-tests/load && go mod tidy - cd ./dashboard-lib && go mod tidy +gomodtidy: gomods ## Run go mod tidy on all modules. + gomods tidy .PHONY: docs docs: ## Install and run pkgsite to view Go docs @@ -89,12 +85,8 @@ abigen: ## Build & install abigen. ./tools/bin/build_abigen .PHONY: generate -generate: abigen codecgen mockery protoc ## Execute all go:generate commands. - go generate -x ./... - cd ./core/scripts && go generate -x ./... - cd ./integration-tests && go generate -x ./... - cd ./integration-tests/load && go generate -x ./... - cd ./dashboard-lib && go generate -x ./... +generate: abigen codecgen mockery protoc gomods ## Execute all go:generate commands. + gomods -w go generate -x ./... mockery .PHONY: rm-mocked @@ -136,7 +128,7 @@ presubmit: ## Format go files and imports. .PHONY: gomods gomods: ## Install gomods - go install github.com/jmank88/gomods@v0.1.1 + go install github.com/jmank88/gomods@v0.1.3 .PHONY: mockery mockery: $(mockery) ## Install mockery. From 499a67705ac7ea525685c4a064ff4aa52b08fa44 Mon Sep 17 00:00:00 2001 From: Ryan Hall Date: Wed, 7 Aug 2024 12:51:02 -0400 Subject: [PATCH 053/432] add OZ 5.0.2 contracts (#14065) --- contracts/.changeset/mean-zoos-fly.md | 5 + .../v5.0.2/contracts/access/AccessControl.sol | 209 +++ .../contracts/access/IAccessControl.sol | 98 ++ .../v5.0.2/contracts/interfaces/IERC165.sol | 6 + .../v5.0.2/contracts/interfaces/IERC20.sol | 6 + .../v5.0.2/contracts/interfaces/IERC5267.sol | 28 + .../contracts/interfaces/draft-IERC6093.sol | 161 +++ .../v5.0.2/contracts/token/ERC20/ERC20.sol | 316 +++++ .../v5.0.2/contracts/token/ERC20/IERC20.sol | 79 ++ .../token/ERC20/extensions/ERC20Burnable.sol | 39 + .../token/ERC20/extensions/IERC20Metadata.sol | 26 + .../token/ERC20/extensions/IERC20Permit.sol | 90 ++ .../contracts/token/ERC20/utils/SafeERC20.sol | 118 ++ .../v5.0.2/contracts/utils/Address.sol | 159 +++ .../v5.0.2/contracts/utils/Context.sol | 28 + .../v5.0.2/contracts/utils/Pausable.sol | 119 ++ .../v5.0.2/contracts/utils/ShortStrings.sol | 123 ++ .../v5.0.2/contracts/utils/StorageSlot.sol | 135 ++ .../v5.0.2/contracts/utils/Strings.sol | 94 ++ .../contracts/utils/cryptography/ECDSA.sol | 174 +++ .../contracts/utils/cryptography/EIP712.sol | 160 +++ .../utils/cryptography/MessageHashUtils.sol | 86 ++ .../contracts/utils/introspection/ERC165.sol | 27 + .../utils/introspection/ERC165Checker.sol | 124 ++ .../contracts/utils/introspection/IERC165.sol | 25 + .../v5.0.2/contracts/utils/math/Math.sol | 415 ++++++ .../v5.0.2/contracts/utils/math/SafeCast.sol | 1153 +++++++++++++++++ .../contracts/utils/math/SignedMath.sol | 43 + .../contracts/utils/structs/EnumerableMap.sol | 533 ++++++++ .../contracts/utils/structs/EnumerableSet.sol | 378 ++++++ 30 files changed, 4957 insertions(+) create mode 100644 contracts/.changeset/mean-zoos-fly.md create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/access/AccessControl.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/access/IAccessControl.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC165.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC20.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC5267.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/draft-IERC6093.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/ERC20.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/IERC20.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/ERC20Burnable.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/IERC20Metadata.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/IERC20Permit.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/utils/SafeERC20.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Address.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Context.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Pausable.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/ShortStrings.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/StorageSlot.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Strings.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/cryptography/ECDSA.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/cryptography/EIP712.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/cryptography/MessageHashUtils.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165Checker.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/math/Math.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/math/SafeCast.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/math/SignedMath.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableMap.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol diff --git a/contracts/.changeset/mean-zoos-fly.md b/contracts/.changeset/mean-zoos-fly.md new file mode 100644 index 0000000000..72eb98198d --- /dev/null +++ b/contracts/.changeset/mean-zoos-fly.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +add OZ v0.5 contracts diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/access/AccessControl.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/access/AccessControl.sol new file mode 100644 index 0000000000..3e3341e9cf --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/access/AccessControl.sol @@ -0,0 +1,209 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol) + +pragma solidity ^0.8.20; + +import {IAccessControl} from "./IAccessControl.sol"; +import {Context} from "../utils/Context.sol"; +import {ERC165} from "../utils/introspection/ERC165.sol"; + +/** + * @dev Contract module that allows children to implement role-based access + * control mechanisms. This is a lightweight version that doesn't allow enumerating role + * members except through off-chain means by accessing the contract event logs. Some + * applications may benefit from on-chain enumerability, for those cases see + * {AccessControlEnumerable}. + * + * Roles are referred to by their `bytes32` identifier. These should be exposed + * in the external API and be unique. The best way to achieve this is by + * using `public constant` hash digests: + * + * ```solidity + * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); + * ``` + * + * Roles can be used to represent a set of permissions. To restrict access to a + * function call, use {hasRole}: + * + * ```solidity + * function foo() public { + * require(hasRole(MY_ROLE, msg.sender)); + * ... + * } + * ``` + * + * Roles can be granted and revoked dynamically via the {grantRole} and + * {revokeRole} functions. Each role has an associated admin role, and only + * accounts that have a role's admin role can call {grantRole} and {revokeRole}. + * + * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means + * that only accounts with this role will be able to grant or revoke other + * roles. More complex role relationships can be created by using + * {_setRoleAdmin}. + * + * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to + * grant and revoke this role. Extra precautions should be taken to secure + * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} + * to enforce additional security measures for this role. + */ +abstract contract AccessControl is Context, IAccessControl, ERC165 { + struct RoleData { + mapping(address account => bool) hasRole; + bytes32 adminRole; + } + + mapping(bytes32 role => RoleData) private _roles; + + bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; + + /** + * @dev Modifier that checks that an account has a specific role. Reverts + * with an {AccessControlUnauthorizedAccount} error including the required role. + */ + modifier onlyRole(bytes32 role) { + _checkRole(role); + _; + } + + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); + } + + /** + * @dev Returns `true` if `account` has been granted `role`. + */ + function hasRole(bytes32 role, address account) public view virtual returns (bool) { + return _roles[role].hasRole[account]; + } + + /** + * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()` + * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier. + */ + function _checkRole(bytes32 role) internal view virtual { + _checkRole(role, _msgSender()); + } + + /** + * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account` + * is missing `role`. + */ + function _checkRole(bytes32 role, address account) internal view virtual { + if (!hasRole(role, account)) { + revert AccessControlUnauthorizedAccount(account, role); + } + } + + /** + * @dev Returns the admin role that controls `role`. See {grantRole} and + * {revokeRole}. + * + * To change a role's admin, use {_setRoleAdmin}. + */ + function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) { + return _roles[role].adminRole; + } + + /** + * @dev Grants `role` to `account`. + * + * If `account` had not been already granted `role`, emits a {RoleGranted} + * event. + * + * Requirements: + * + * - the caller must have ``role``'s admin role. + * + * May emit a {RoleGranted} event. + */ + function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { + _grantRole(role, account); + } + + /** + * @dev Revokes `role` from `account`. + * + * If `account` had been granted `role`, emits a {RoleRevoked} event. + * + * Requirements: + * + * - the caller must have ``role``'s admin role. + * + * May emit a {RoleRevoked} event. + */ + function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { + _revokeRole(role, account); + } + + /** + * @dev Revokes `role` from the calling account. + * + * Roles are often managed via {grantRole} and {revokeRole}: this function's + * purpose is to provide a mechanism for accounts to lose their privileges + * if they are compromised (such as when a trusted device is misplaced). + * + * If the calling account had been revoked `role`, emits a {RoleRevoked} + * event. + * + * Requirements: + * + * - the caller must be `callerConfirmation`. + * + * May emit a {RoleRevoked} event. + */ + function renounceRole(bytes32 role, address callerConfirmation) public virtual { + if (callerConfirmation != _msgSender()) { + revert AccessControlBadConfirmation(); + } + + _revokeRole(role, callerConfirmation); + } + + /** + * @dev Sets `adminRole` as ``role``'s admin role. + * + * Emits a {RoleAdminChanged} event. + */ + function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { + bytes32 previousAdminRole = getRoleAdmin(role); + _roles[role].adminRole = adminRole; + emit RoleAdminChanged(role, previousAdminRole, adminRole); + } + + /** + * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted. + * + * Internal function without access restriction. + * + * May emit a {RoleGranted} event. + */ + function _grantRole(bytes32 role, address account) internal virtual returns (bool) { + if (!hasRole(role, account)) { + _roles[role].hasRole[account] = true; + emit RoleGranted(role, account, _msgSender()); + return true; + } else { + return false; + } + } + + /** + * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked. + * + * Internal function without access restriction. + * + * May emit a {RoleRevoked} event. + */ + function _revokeRole(bytes32 role, address account) internal virtual returns (bool) { + if (hasRole(role, account)) { + _roles[role].hasRole[account] = false; + emit RoleRevoked(role, account, _msgSender()); + return true; + } else { + return false; + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/access/IAccessControl.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/access/IAccessControl.sol new file mode 100644 index 0000000000..2ac89ca735 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/access/IAccessControl.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol) + +pragma solidity ^0.8.20; + +/** + * @dev External interface of AccessControl declared to support ERC165 detection. + */ +interface IAccessControl { + /** + * @dev The `account` is missing a role. + */ + error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); + + /** + * @dev The caller of a function is not the expected one. + * + * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. + */ + error AccessControlBadConfirmation(); + + /** + * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` + * + * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite + * {RoleAdminChanged} not being emitted signaling this. + */ + event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); + + /** + * @dev Emitted when `account` is granted `role`. + * + * `sender` is the account that originated the contract call, an admin role + * bearer except when using {AccessControl-_setupRole}. + */ + event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); + + /** + * @dev Emitted when `account` is revoked `role`. + * + * `sender` is the account that originated the contract call: + * - if using `revokeRole`, it is the admin role bearer + * - if using `renounceRole`, it is the role bearer (i.e. `account`) + */ + event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); + + /** + * @dev Returns `true` if `account` has been granted `role`. + */ + function hasRole(bytes32 role, address account) external view returns (bool); + + /** + * @dev Returns the admin role that controls `role`. See {grantRole} and + * {revokeRole}. + * + * To change a role's admin, use {AccessControl-_setRoleAdmin}. + */ + function getRoleAdmin(bytes32 role) external view returns (bytes32); + + /** + * @dev Grants `role` to `account`. + * + * If `account` had not been already granted `role`, emits a {RoleGranted} + * event. + * + * Requirements: + * + * - the caller must have ``role``'s admin role. + */ + function grantRole(bytes32 role, address account) external; + + /** + * @dev Revokes `role` from `account`. + * + * If `account` had been granted `role`, emits a {RoleRevoked} event. + * + * Requirements: + * + * - the caller must have ``role``'s admin role. + */ + function revokeRole(bytes32 role, address account) external; + + /** + * @dev Revokes `role` from the calling account. + * + * Roles are often managed via {grantRole} and {revokeRole}: this function's + * purpose is to provide a mechanism for accounts to lose their privileges + * if they are compromised (such as when a trusted device is misplaced). + * + * If the calling account had been granted `role`, emits a {RoleRevoked} + * event. + * + * Requirements: + * + * - the caller must be `callerConfirmation`. + */ + function renounceRole(bytes32 role, address callerConfirmation) external; +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC165.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC165.sol new file mode 100644 index 0000000000..944dd0d591 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC165.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) + +pragma solidity ^0.8.20; + +import {IERC165} from "../utils/introspection/IERC165.sol"; diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC20.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC20.sol new file mode 100644 index 0000000000..21d5a41327 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC20.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) + +pragma solidity ^0.8.20; + +import {IERC20} from "../token/ERC20/IERC20.sol"; diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC5267.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC5267.sol new file mode 100644 index 0000000000..47a9fd5885 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC5267.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol) + +pragma solidity ^0.8.20; + +interface IERC5267 { + /** + * @dev MAY be emitted to signal that the domain could have changed. + */ + event EIP712DomainChanged(); + + /** + * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 + * signature. + */ + function eip712Domain() + external + view + returns ( + bytes1 fields, + string memory name, + string memory version, + uint256 chainId, + address verifyingContract, + bytes32 salt, + uint256[] memory extensions + ); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/draft-IERC6093.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/draft-IERC6093.sol new file mode 100644 index 0000000000..f6990e607c --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/draft-IERC6093.sol @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) +pragma solidity ^0.8.20; + +/** + * @dev Standard ERC20 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. + */ +interface IERC20Errors { + /** + * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param balance Current balance for the interacting account. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC20InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC20InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. + * @param spender Address that may be allowed to operate on tokens without being their owner. + * @param allowance Amount of tokens a `spender` is allowed to operate with. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC20InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `spender` to be approved. Used in approvals. + * @param spender Address that may be allowed to operate on tokens without being their owner. + */ + error ERC20InvalidSpender(address spender); +} + +/** + * @dev Standard ERC721 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. + */ +interface IERC721Errors { + /** + * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. + * Used in balance queries. + * @param owner Address of the current owner of a token. + */ + error ERC721InvalidOwner(address owner); + + /** + * @dev Indicates a `tokenId` whose `owner` is the zero address. + * @param tokenId Identifier number of a token. + */ + error ERC721NonexistentToken(uint256 tokenId); + + /** + * @dev Indicates an error related to the ownership over a particular token. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param tokenId Identifier number of a token. + * @param owner Address of the current owner of a token. + */ + error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC721InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC721InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `operator`’s approval. Used in transfers. + * @param operator Address that may be allowed to operate on tokens without being their owner. + * @param tokenId Identifier number of a token. + */ + error ERC721InsufficientApproval(address operator, uint256 tokenId); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC721InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `operator` to be approved. Used in approvals. + * @param operator Address that may be allowed to operate on tokens without being their owner. + */ + error ERC721InvalidOperator(address operator); +} + +/** + * @dev Standard ERC1155 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. + */ +interface IERC1155Errors { + /** + * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param balance Current balance for the interacting account. + * @param needed Minimum amount required to perform a transfer. + * @param tokenId Identifier number of a token. + */ + error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC1155InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC1155InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `operator`’s approval. Used in transfers. + * @param operator Address that may be allowed to operate on tokens without being their owner. + * @param owner Address of the current owner of a token. + */ + error ERC1155MissingApprovalForAll(address operator, address owner); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC1155InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `operator` to be approved. Used in approvals. + * @param operator Address that may be allowed to operate on tokens without being their owner. + */ + error ERC1155InvalidOperator(address operator); + + /** + * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. + * Used in batch transfers. + * @param idsLength Length of the array of token identifiers + * @param valuesLength Length of the array of token amounts + */ + error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/ERC20.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/ERC20.sol new file mode 100644 index 0000000000..1fde5279d0 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/ERC20.sol @@ -0,0 +1,316 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) + +pragma solidity ^0.8.20; + +import {IERC20} from "./IERC20.sol"; +import {IERC20Metadata} from "./extensions/IERC20Metadata.sol"; +import {Context} from "../../utils/Context.sol"; +import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol"; + +/** + * @dev Implementation of the {IERC20} interface. + * + * This implementation is agnostic to the way tokens are created. This means + * that a supply mechanism has to be added in a derived contract using {_mint}. + * + * TIP: For a detailed writeup see our guide + * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How + * to implement supply mechanisms]. + * + * The default value of {decimals} is 18. To change this, you should override + * this function so it returns a different value. + * + * We have followed general OpenZeppelin Contracts guidelines: functions revert + * instead returning `false` on failure. This behavior is nonetheless + * conventional and does not conflict with the expectations of ERC20 + * applications. + * + * Additionally, an {Approval} event is emitted on calls to {transferFrom}. + * This allows applications to reconstruct the allowance for all accounts just + * by listening to said events. Other implementations of the EIP may not emit + * these events, as it isn't required by the specification. + */ +abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { + mapping(address account => uint256) private _balances; + + mapping(address account => mapping(address spender => uint256)) private _allowances; + + uint256 private _totalSupply; + + string private _name; + string private _symbol; + + /** + * @dev Sets the values for {name} and {symbol}. + * + * All two of these values are immutable: they can only be set once during + * construction. + */ + constructor(string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + } + + /** + * @dev Returns the name of the token. + */ + function name() public view virtual returns (string memory) { + return _name; + } + + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() public view virtual returns (string memory) { + return _symbol; + } + + /** + * @dev Returns the number of decimals used to get its user representation. + * For example, if `decimals` equals `2`, a balance of `505` tokens should + * be displayed to a user as `5.05` (`505 / 10 ** 2`). + * + * Tokens usually opt for a value of 18, imitating the relationship between + * Ether and Wei. This is the default value returned by this function, unless + * it's overridden. + * + * NOTE: This information is only used for _display_ purposes: it in + * no way affects any of the arithmetic of the contract, including + * {IERC20-balanceOf} and {IERC20-transfer}. + */ + function decimals() public view virtual returns (uint8) { + return 18; + } + + /** + * @dev See {IERC20-totalSupply}. + */ + function totalSupply() public view virtual returns (uint256) { + return _totalSupply; + } + + /** + * @dev See {IERC20-balanceOf}. + */ + function balanceOf(address account) public view virtual returns (uint256) { + return _balances[account]; + } + + /** + * @dev See {IERC20-transfer}. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - the caller must have a balance of at least `value`. + */ + function transfer(address to, uint256 value) public virtual returns (bool) { + address owner = _msgSender(); + _transfer(owner, to, value); + return true; + } + + /** + * @dev See {IERC20-allowance}. + */ + function allowance(address owner, address spender) public view virtual returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev See {IERC20-approve}. + * + * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on + * `transferFrom`. This is semantically equivalent to an infinite approval. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve(address spender, uint256 value) public virtual returns (bool) { + address owner = _msgSender(); + _approve(owner, spender, value); + return true; + } + + /** + * @dev See {IERC20-transferFrom}. + * + * Emits an {Approval} event indicating the updated allowance. This is not + * required by the EIP. See the note at the beginning of {ERC20}. + * + * NOTE: Does not update the allowance if the current allowance + * is the maximum `uint256`. + * + * Requirements: + * + * - `from` and `to` cannot be the zero address. + * - `from` must have a balance of at least `value`. + * - the caller must have allowance for ``from``'s tokens of at least + * `value`. + */ + function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { + address spender = _msgSender(); + _spendAllowance(from, spender, value); + _transfer(from, to, value); + return true; + } + + /** + * @dev Moves a `value` amount of tokens from `from` to `to`. + * + * This internal function is equivalent to {transfer}, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a {Transfer} event. + * + * NOTE: This function is not virtual, {_update} should be overridden instead. + */ + function _transfer(address from, address to, uint256 value) internal { + if (from == address(0)) { + revert ERC20InvalidSender(address(0)); + } + if (to == address(0)) { + revert ERC20InvalidReceiver(address(0)); + } + _update(from, to, value); + } + + /** + * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` + * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding + * this function. + * + * Emits a {Transfer} event. + */ + function _update(address from, address to, uint256 value) internal virtual { + if (from == address(0)) { + // Overflow check required: The rest of the code assumes that totalSupply never overflows + _totalSupply += value; + } else { + uint256 fromBalance = _balances[from]; + if (fromBalance < value) { + revert ERC20InsufficientBalance(from, fromBalance, value); + } + unchecked { + // Overflow not possible: value <= fromBalance <= totalSupply. + _balances[from] = fromBalance - value; + } + } + + if (to == address(0)) { + unchecked { + // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. + _totalSupply -= value; + } + } else { + unchecked { + // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. + _balances[to] += value; + } + } + + emit Transfer(from, to, value); + } + + /** + * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). + * Relies on the `_update` mechanism + * + * Emits a {Transfer} event with `from` set to the zero address. + * + * NOTE: This function is not virtual, {_update} should be overridden instead. + */ + function _mint(address account, uint256 value) internal { + if (account == address(0)) { + revert ERC20InvalidReceiver(address(0)); + } + _update(address(0), account, value); + } + + /** + * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. + * Relies on the `_update` mechanism. + * + * Emits a {Transfer} event with `to` set to the zero address. + * + * NOTE: This function is not virtual, {_update} should be overridden instead + */ + function _burn(address account, uint256 value) internal { + if (account == address(0)) { + revert ERC20InvalidSender(address(0)); + } + _update(account, address(0), value); + } + + /** + * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens. + * + * This internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + * + * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. + */ + function _approve(address owner, address spender, uint256 value) internal { + _approve(owner, spender, value, true); + } + + /** + * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. + * + * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by + * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any + * `Approval` event during `transferFrom` operations. + * + * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to + * true using the following override: + * ``` + * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { + * super._approve(owner, spender, value, true); + * } + * ``` + * + * Requirements are the same as {_approve}. + */ + function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { + if (owner == address(0)) { + revert ERC20InvalidApprover(address(0)); + } + if (spender == address(0)) { + revert ERC20InvalidSpender(address(0)); + } + _allowances[owner][spender] = value; + if (emitEvent) { + emit Approval(owner, spender, value); + } + } + + /** + * @dev Updates `owner` s allowance for `spender` based on spent `value`. + * + * Does not update the allowance value in case of infinite allowance. + * Revert if not enough allowance is available. + * + * Does not emit an {Approval} event. + */ + function _spendAllowance(address owner, address spender, uint256 value) internal virtual { + uint256 currentAllowance = allowance(owner, spender); + if (currentAllowance != type(uint256).max) { + if (currentAllowance < value) { + revert ERC20InsufficientAllowance(spender, currentAllowance, value); + } + unchecked { + _approve(owner, spender, currentAllowance - value, false); + } + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/IERC20.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/IERC20.sol new file mode 100644 index 0000000000..db01cf4c75 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/IERC20.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC20 { + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); + + /** + * @dev Returns the value of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the value of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves a `value` amount of tokens from the caller's account to `to`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address to, uint256 value) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets a `value` amount of tokens as the allowance of `spender` over the + * caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 value) external returns (bool); + + /** + * @dev Moves a `value` amount of tokens from `from` to `to` using the + * allowance mechanism. `value` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom(address from, address to, uint256 value) external returns (bool); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/ERC20Burnable.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/ERC20Burnable.sol new file mode 100644 index 0000000000..4d482d8ec8 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/ERC20Burnable.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol) + +pragma solidity ^0.8.20; + +import {ERC20} from "../ERC20.sol"; +import {Context} from "../../../utils/Context.sol"; + +/** + * @dev Extension of {ERC20} that allows token holders to destroy both their own + * tokens and those that they have an allowance for, in a way that can be + * recognized off-chain (via event analysis). + */ +abstract contract ERC20Burnable is Context, ERC20 { + /** + * @dev Destroys a `value` amount of tokens from the caller. + * + * See {ERC20-_burn}. + */ + function burn(uint256 value) public virtual { + _burn(_msgSender(), value); + } + + /** + * @dev Destroys a `value` amount of tokens from `account`, deducting from + * the caller's allowance. + * + * See {ERC20-_burn} and {ERC20-allowance}. + * + * Requirements: + * + * - the caller must have allowance for ``accounts``'s tokens of at least + * `value`. + */ + function burnFrom(address account, uint256 value) public virtual { + _spendAllowance(account, _msgSender(), value); + _burn(account, value); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/IERC20Metadata.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/IERC20Metadata.sol new file mode 100644 index 0000000000..1a38cba3e0 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/IERC20Metadata.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) + +pragma solidity ^0.8.20; + +import {IERC20} from "../IERC20.sol"; + +/** + * @dev Interface for the optional metadata functions from the ERC20 standard. + */ +interface IERC20Metadata is IERC20 { + /** + * @dev Returns the name of the token. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the symbol of the token. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the decimals places of the token. + */ + function decimals() external view returns (uint8); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/IERC20Permit.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/IERC20Permit.sol new file mode 100644 index 0000000000..5af48101ab --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/IERC20Permit.sol @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in + * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. + * + * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by + * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't + * need to send a transaction, and thus is not required to hold Ether at all. + * + * ==== Security Considerations + * + * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature + * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be + * considered as an intention to spend the allowance in any specific way. The second is that because permits have + * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should + * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be + * generally recommended is: + * + * ```solidity + * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { + * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} + * doThing(..., value); + * } + * + * function doThing(..., uint256 value) public { + * token.safeTransferFrom(msg.sender, address(this), value); + * ... + * } + * ``` + * + * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of + * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also + * {SafeERC20-safeTransferFrom}). + * + * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so + * contracts should have entry points that don't rely on permit. + */ +interface IERC20Permit { + /** + * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, + * given ``owner``'s signed approval. + * + * IMPORTANT: The same issues {IERC20-approve} has related to transaction + * ordering also apply here. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `deadline` must be a timestamp in the future. + * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` + * over the EIP712-formatted function arguments. + * - the signature must use ``owner``'s current nonce (see {nonces}). + * + * For more information on the signature format, see the + * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP + * section]. + * + * CAUTION: See Security Considerations above. + */ + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external; + + /** + * @dev Returns the current nonce for `owner`. This value must be + * included whenever a signature is generated for {permit}. + * + * Every successful call to {permit} increases ``owner``'s nonce by one. This + * prevents a signature from being used multiple times. + */ + function nonces(address owner) external view returns (uint256); + + /** + * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. + */ + // solhint-disable-next-line func-name-mixedcase + function DOMAIN_SEPARATOR() external view returns (bytes32); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/utils/SafeERC20.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/utils/SafeERC20.sol new file mode 100644 index 0000000000..bb65709b46 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/utils/SafeERC20.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol) + +pragma solidity ^0.8.20; + +import {IERC20} from "../IERC20.sol"; +import {IERC20Permit} from "../extensions/IERC20Permit.sol"; +import {Address} from "../../../utils/Address.sol"; + +/** + * @title SafeERC20 + * @dev Wrappers around ERC20 operations that throw on failure (when the token + * contract returns false). Tokens that return no value (and instead revert or + * throw on failure) are also supported, non-reverting calls are assumed to be + * successful. + * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, + * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. + */ +library SafeERC20 { + using Address for address; + + /** + * @dev An operation with an ERC20 token failed. + */ + error SafeERC20FailedOperation(address token); + + /** + * @dev Indicates a failed `decreaseAllowance` request. + */ + error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); + + /** + * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, + * non-reverting calls are assumed to be successful. + */ + function safeTransfer(IERC20 token, address to, uint256 value) internal { + _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); + } + + /** + * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the + * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. + */ + function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { + _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); + } + + /** + * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, + * non-reverting calls are assumed to be successful. + */ + function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { + uint256 oldAllowance = token.allowance(address(this), spender); + forceApprove(token, spender, oldAllowance + value); + } + + /** + * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no + * value, non-reverting calls are assumed to be successful. + */ + function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { + unchecked { + uint256 currentAllowance = token.allowance(address(this), spender); + if (currentAllowance < requestedDecrease) { + revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); + } + forceApprove(token, spender, currentAllowance - requestedDecrease); + } + } + + /** + * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, + * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval + * to be set to zero before setting it to a non-zero value, such as USDT. + */ + function forceApprove(IERC20 token, address spender, uint256 value) internal { + bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); + + if (!_callOptionalReturnBool(token, approvalCall)) { + _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); + _callOptionalReturn(token, approvalCall); + } + } + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + */ + function _callOptionalReturn(IERC20 token, bytes memory data) private { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that + // the target address contains contract code and also asserts for success in the low-level call. + + bytes memory returndata = address(token).functionCall(data); + if (returndata.length != 0 && !abi.decode(returndata, (bool))) { + revert SafeERC20FailedOperation(address(token)); + } + } + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + * + * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. + */ + function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false + // and not revert is the subcall reverts. + + (bool success, bytes memory returndata) = address(token).call(data); + return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Address.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Address.sol new file mode 100644 index 0000000000..b7e3059529 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Address.sol @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Collection of functions related to the address type + */ +library Address { + /** + * @dev The ETH balance of the account is not enough to perform the operation. + */ + error AddressInsufficientBalance(address account); + + /** + * @dev There's no code at `target` (it is not a contract). + */ + error AddressEmptyCode(address target); + + /** + * @dev A call to an address target failed. The target may have reverted. + */ + error FailedInnerCall(); + + /** + * @dev Replacement for Solidity's `transfer`: sends `amount` wei to + * `recipient`, forwarding all available gas and reverting on errors. + * + * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost + * of certain opcodes, possibly making contracts go over the 2300 gas limit + * imposed by `transfer`, making them unable to receive funds via + * `transfer`. {sendValue} removes this limitation. + * + * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. + * + * IMPORTANT: because control is transferred to `recipient`, care must be + * taken to not create reentrancy vulnerabilities. Consider using + * {ReentrancyGuard} or the + * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. + */ + function sendValue(address payable recipient, uint256 amount) internal { + if (address(this).balance < amount) { + revert AddressInsufficientBalance(address(this)); + } + + (bool success, ) = recipient.call{value: amount}(""); + if (!success) { + revert FailedInnerCall(); + } + } + + /** + * @dev Performs a Solidity function call using a low level `call`. A + * plain `call` is an unsafe replacement for a function call: use this + * function instead. + * + * If `target` reverts with a revert reason or custom error, it is bubbled + * up by this function (like regular Solidity function calls). However, if + * the call reverted with no returned reason, this function reverts with a + * {FailedInnerCall} error. + * + * Returns the raw returned data. To convert to the expected return value, + * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. + * + * Requirements: + * + * - `target` must be a contract. + * - calling `target` with `data` must not revert. + */ + function functionCall(address target, bytes memory data) internal returns (bytes memory) { + return functionCallWithValue(target, data, 0); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but also transferring `value` wei to `target`. + * + * Requirements: + * + * - the calling contract must have an ETH balance of at least `value`. + * - the called Solidity function must be `payable`. + */ + function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { + if (address(this).balance < value) { + revert AddressInsufficientBalance(address(this)); + } + (bool success, bytes memory returndata) = target.call{value: value}(data); + return verifyCallResultFromTarget(target, success, returndata); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but performing a static call. + */ + function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { + (bool success, bytes memory returndata) = target.staticcall(data); + return verifyCallResultFromTarget(target, success, returndata); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but performing a delegate call. + */ + function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { + (bool success, bytes memory returndata) = target.delegatecall(data); + return verifyCallResultFromTarget(target, success, returndata); + } + + /** + * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target + * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an + * unsuccessful call. + */ + function verifyCallResultFromTarget( + address target, + bool success, + bytes memory returndata + ) internal view returns (bytes memory) { + if (!success) { + _revert(returndata); + } else { + // only check if target is a contract if the call was successful and the return data is empty + // otherwise we already know that it was a contract + if (returndata.length == 0 && target.code.length == 0) { + revert AddressEmptyCode(target); + } + return returndata; + } + } + + /** + * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the + * revert reason or with a default {FailedInnerCall} error. + */ + function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { + if (!success) { + _revert(returndata); + } else { + return returndata; + } + } + + /** + * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. + */ + function _revert(bytes memory returndata) private pure { + // Look for revert reason and bubble it up if present + if (returndata.length > 0) { + // The easiest way to bubble the revert reason is using memory via assembly + /// @solidity memory-safe-assembly + assembly { + let returndata_size := mload(returndata) + revert(add(32, returndata), returndata_size) + } + } else { + revert FailedInnerCall(); + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Context.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Context.sol new file mode 100644 index 0000000000..4e535fe03c --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Context.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Provides information about the current execution context, including the + * sender of the transaction and its data. While these are generally available + * via msg.sender and msg.data, they should not be accessed in such a direct + * manner, since when dealing with meta-transactions the account sending and + * paying for execution may not be the actual sender (as far as an application + * is concerned). + * + * This contract is only required for intermediate, library-like contracts. + */ +abstract contract Context { + function _msgSender() internal view virtual returns (address) { + return msg.sender; + } + + function _msgData() internal view virtual returns (bytes calldata) { + return msg.data; + } + + function _contextSuffixLength() internal view virtual returns (uint256) { + return 0; + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Pausable.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Pausable.sol new file mode 100644 index 0000000000..312f1cb90f --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Pausable.sol @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol) + +pragma solidity ^0.8.20; + +import {Context} from "../utils/Context.sol"; + +/** + * @dev Contract module which allows children to implement an emergency stop + * mechanism that can be triggered by an authorized account. + * + * This module is used through inheritance. It will make available the + * modifiers `whenNotPaused` and `whenPaused`, which can be applied to + * the functions of your contract. Note that they will not be pausable by + * simply including this module, only once the modifiers are put in place. + */ +abstract contract Pausable is Context { + bool private _paused; + + /** + * @dev Emitted when the pause is triggered by `account`. + */ + event Paused(address account); + + /** + * @dev Emitted when the pause is lifted by `account`. + */ + event Unpaused(address account); + + /** + * @dev The operation failed because the contract is paused. + */ + error EnforcedPause(); + + /** + * @dev The operation failed because the contract is not paused. + */ + error ExpectedPause(); + + /** + * @dev Initializes the contract in unpaused state. + */ + constructor() { + _paused = false; + } + + /** + * @dev Modifier to make a function callable only when the contract is not paused. + * + * Requirements: + * + * - The contract must not be paused. + */ + modifier whenNotPaused() { + _requireNotPaused(); + _; + } + + /** + * @dev Modifier to make a function callable only when the contract is paused. + * + * Requirements: + * + * - The contract must be paused. + */ + modifier whenPaused() { + _requirePaused(); + _; + } + + /** + * @dev Returns true if the contract is paused, and false otherwise. + */ + function paused() public view virtual returns (bool) { + return _paused; + } + + /** + * @dev Throws if the contract is paused. + */ + function _requireNotPaused() internal view virtual { + if (paused()) { + revert EnforcedPause(); + } + } + + /** + * @dev Throws if the contract is not paused. + */ + function _requirePaused() internal view virtual { + if (!paused()) { + revert ExpectedPause(); + } + } + + /** + * @dev Triggers stopped state. + * + * Requirements: + * + * - The contract must not be paused. + */ + function _pause() internal virtual whenNotPaused { + _paused = true; + emit Paused(_msgSender()); + } + + /** + * @dev Returns to normal state. + * + * Requirements: + * + * - The contract must be paused. + */ + function _unpause() internal virtual whenPaused { + _paused = false; + emit Unpaused(_msgSender()); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/ShortStrings.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/ShortStrings.sol new file mode 100644 index 0000000000..fdfe774d63 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/ShortStrings.sol @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/ShortStrings.sol) + +pragma solidity ^0.8.20; + +import {StorageSlot} from "./StorageSlot.sol"; + +// | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | +// | length | 0x BB | +type ShortString is bytes32; + +/** + * @dev This library provides functions to convert short memory strings + * into a `ShortString` type that can be used as an immutable variable. + * + * Strings of arbitrary length can be optimized using this library if + * they are short enough (up to 31 bytes) by packing them with their + * length (1 byte) in a single EVM word (32 bytes). Additionally, a + * fallback mechanism can be used for every other case. + * + * Usage example: + * + * ```solidity + * contract Named { + * using ShortStrings for *; + * + * ShortString private immutable _name; + * string private _nameFallback; + * + * constructor(string memory contractName) { + * _name = contractName.toShortStringWithFallback(_nameFallback); + * } + * + * function name() external view returns (string memory) { + * return _name.toStringWithFallback(_nameFallback); + * } + * } + * ``` + */ +library ShortStrings { + // Used as an identifier for strings longer than 31 bytes. + bytes32 private constant FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; + + error StringTooLong(string str); + error InvalidShortString(); + + /** + * @dev Encode a string of at most 31 chars into a `ShortString`. + * + * This will trigger a `StringTooLong` error is the input string is too long. + */ + function toShortString(string memory str) internal pure returns (ShortString) { + bytes memory bstr = bytes(str); + if (bstr.length > 31) { + revert StringTooLong(str); + } + return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); + } + + /** + * @dev Decode a `ShortString` back to a "normal" string. + */ + function toString(ShortString sstr) internal pure returns (string memory) { + uint256 len = byteLength(sstr); + // using `new string(len)` would work locally but is not memory safe. + string memory str = new string(32); + /// @solidity memory-safe-assembly + assembly { + mstore(str, len) + mstore(add(str, 0x20), sstr) + } + return str; + } + + /** + * @dev Return the length of a `ShortString`. + */ + function byteLength(ShortString sstr) internal pure returns (uint256) { + uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; + if (result > 31) { + revert InvalidShortString(); + } + return result; + } + + /** + * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. + */ + function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { + if (bytes(value).length < 32) { + return toShortString(value); + } else { + StorageSlot.getStringSlot(store).value = value; + return ShortString.wrap(FALLBACK_SENTINEL); + } + } + + /** + * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. + */ + function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { + if (ShortString.unwrap(value) != FALLBACK_SENTINEL) { + return toString(value); + } else { + return store; + } + } + + /** + * @dev Return the length of a string that was encoded to `ShortString` or written to storage using + * {setWithFallback}. + * + * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of + * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. + */ + function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { + if (ShortString.unwrap(value) != FALLBACK_SENTINEL) { + return byteLength(value); + } else { + return bytes(store).length; + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/StorageSlot.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/StorageSlot.sol new file mode 100644 index 0000000000..08418327a5 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/StorageSlot.sol @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol) +// This file was procedurally generated from scripts/generate/templates/StorageSlot.js. + +pragma solidity ^0.8.20; + +/** + * @dev Library for reading and writing primitive types to specific storage slots. + * + * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. + * This library helps with reading and writing to such slots without the need for inline assembly. + * + * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. + * + * Example usage to set ERC1967 implementation slot: + * ```solidity + * contract ERC1967 { + * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + * + * function _getImplementation() internal view returns (address) { + * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; + * } + * + * function _setImplementation(address newImplementation) internal { + * require(newImplementation.code.length > 0); + * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; + * } + * } + * ``` + */ +library StorageSlot { + struct AddressSlot { + address value; + } + + struct BooleanSlot { + bool value; + } + + struct Bytes32Slot { + bytes32 value; + } + + struct Uint256Slot { + uint256 value; + } + + struct StringSlot { + string value; + } + + struct BytesSlot { + bytes value; + } + + /** + * @dev Returns an `AddressSlot` with member `value` located at `slot`. + */ + function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `BooleanSlot` with member `value` located at `slot`. + */ + function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. + */ + function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `Uint256Slot` with member `value` located at `slot`. + */ + function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `StringSlot` with member `value` located at `slot`. + */ + function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `StringSlot` representation of the string storage pointer `store`. + */ + function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := store.slot + } + } + + /** + * @dev Returns an `BytesSlot` with member `value` located at `slot`. + */ + function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. + */ + function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := store.slot + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Strings.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Strings.sol new file mode 100644 index 0000000000..b2c0a40fb2 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Strings.sol @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol) + +pragma solidity ^0.8.20; + +import {Math} from "./math/Math.sol"; +import {SignedMath} from "./math/SignedMath.sol"; + +/** + * @dev String operations. + */ +library Strings { + bytes16 private constant HEX_DIGITS = "0123456789abcdef"; + uint8 private constant ADDRESS_LENGTH = 20; + + /** + * @dev The `value` string doesn't fit in the specified `length`. + */ + error StringsInsufficientHexLength(uint256 value, uint256 length); + + /** + * @dev Converts a `uint256` to its ASCII `string` decimal representation. + */ + function toString(uint256 value) internal pure returns (string memory) { + unchecked { + uint256 length = Math.log10(value) + 1; + string memory buffer = new string(length); + uint256 ptr; + /// @solidity memory-safe-assembly + assembly { + ptr := add(buffer, add(32, length)) + } + while (true) { + ptr--; + /// @solidity memory-safe-assembly + assembly { + mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) + } + value /= 10; + if (value == 0) break; + } + return buffer; + } + } + + /** + * @dev Converts a `int256` to its ASCII `string` decimal representation. + */ + function toStringSigned(int256 value) internal pure returns (string memory) { + return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); + } + + /** + * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. + */ + function toHexString(uint256 value) internal pure returns (string memory) { + unchecked { + return toHexString(value, Math.log256(value) + 1); + } + } + + /** + * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. + */ + function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { + uint256 localValue = value; + bytes memory buffer = new bytes(2 * length + 2); + buffer[0] = "0"; + buffer[1] = "x"; + for (uint256 i = 2 * length + 1; i > 1; --i) { + buffer[i] = HEX_DIGITS[localValue & 0xf]; + localValue >>= 4; + } + if (localValue != 0) { + revert StringsInsufficientHexLength(value, length); + } + return string(buffer); + } + + /** + * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal + * representation. + */ + function toHexString(address addr) internal pure returns (string memory) { + return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); + } + + /** + * @dev Returns true if the two strings are equal. + */ + function equal(string memory a, string memory b) internal pure returns (bool) { + return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/cryptography/ECDSA.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/cryptography/ECDSA.sol new file mode 100644 index 0000000000..04b3e5e064 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/cryptography/ECDSA.sol @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. + * + * These functions can be used to verify that a message was signed by the holder + * of the private keys of a given address. + */ +library ECDSA { + enum RecoverError { + NoError, + InvalidSignature, + InvalidSignatureLength, + InvalidSignatureS + } + + /** + * @dev The signature derives the `address(0)`. + */ + error ECDSAInvalidSignature(); + + /** + * @dev The signature has an invalid length. + */ + error ECDSAInvalidSignatureLength(uint256 length); + + /** + * @dev The signature has an S value that is in the upper half order. + */ + error ECDSAInvalidSignatureS(bytes32 s); + + /** + * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not + * return address(0) without also returning an error description. Errors are documented using an enum (error type) + * and a bytes32 providing additional information about the error. + * + * If no error is returned, then the address can be used for verification purposes. + * + * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: + * this function rejects them by requiring the `s` value to be in the lower + * half order, and the `v` value to be either 27 or 28. + * + * IMPORTANT: `hash` _must_ be the result of a hash operation for the + * verification to be secure: it is possible to craft signatures that + * recover to arbitrary addresses for non-hashed data. A safe way to ensure + * this is by receiving a hash of the original message (which may otherwise + * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. + * + * Documentation for signature generation: + * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] + * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] + */ + function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) { + if (signature.length == 65) { + bytes32 r; + bytes32 s; + uint8 v; + // ecrecover takes the signature parameters, and the only way to get them + // currently is to use assembly. + /// @solidity memory-safe-assembly + assembly { + r := mload(add(signature, 0x20)) + s := mload(add(signature, 0x40)) + v := byte(0, mload(add(signature, 0x60))) + } + return tryRecover(hash, v, r, s); + } else { + return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length)); + } + } + + /** + * @dev Returns the address that signed a hashed message (`hash`) with + * `signature`. This address can then be used for verification purposes. + * + * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: + * this function rejects them by requiring the `s` value to be in the lower + * half order, and the `v` value to be either 27 or 28. + * + * IMPORTANT: `hash` _must_ be the result of a hash operation for the + * verification to be secure: it is possible to craft signatures that + * recover to arbitrary addresses for non-hashed data. A safe way to ensure + * this is by receiving a hash of the original message (which may otherwise + * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. + */ + function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { + (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); + _throwError(error, errorArg); + return recovered; + } + + /** + * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. + * + * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] + */ + function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) { + unchecked { + bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); + // We do not check for an overflow here since the shift operation results in 0 or 1. + uint8 v = uint8((uint256(vs) >> 255) + 27); + return tryRecover(hash, v, r, s); + } + } + + /** + * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. + */ + function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { + (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); + _throwError(error, errorArg); + return recovered; + } + + /** + * @dev Overload of {ECDSA-tryRecover} that receives the `v`, + * `r` and `s` signature fields separately. + */ + function tryRecover( + bytes32 hash, + uint8 v, + bytes32 r, + bytes32 s + ) internal pure returns (address, RecoverError, bytes32) { + // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature + // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines + // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most + // signatures from current libraries generate a unique signature with an s-value in the lower half order. + // + // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value + // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or + // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept + // these malleable signatures as well. + if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { + return (address(0), RecoverError.InvalidSignatureS, s); + } + + // If the signature is valid (and not malleable), return the signer address + address signer = ecrecover(hash, v, r, s); + if (signer == address(0)) { + return (address(0), RecoverError.InvalidSignature, bytes32(0)); + } + + return (signer, RecoverError.NoError, bytes32(0)); + } + + /** + * @dev Overload of {ECDSA-recover} that receives the `v`, + * `r` and `s` signature fields separately. + */ + function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { + (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s); + _throwError(error, errorArg); + return recovered; + } + + /** + * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. + */ + function _throwError(RecoverError error, bytes32 errorArg) private pure { + if (error == RecoverError.NoError) { + return; // no error: do nothing + } else if (error == RecoverError.InvalidSignature) { + revert ECDSAInvalidSignature(); + } else if (error == RecoverError.InvalidSignatureLength) { + revert ECDSAInvalidSignatureLength(uint256(errorArg)); + } else if (error == RecoverError.InvalidSignatureS) { + revert ECDSAInvalidSignatureS(errorArg); + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/cryptography/EIP712.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/cryptography/EIP712.sol new file mode 100644 index 0000000000..8e548cdd8f --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/cryptography/EIP712.sol @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol) + +pragma solidity ^0.8.20; + +import {MessageHashUtils} from "./MessageHashUtils.sol"; +import {ShortStrings, ShortString} from "../ShortStrings.sol"; +import {IERC5267} from "../../interfaces/IERC5267.sol"; + +/** + * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. + * + * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose + * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract + * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to + * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`. + * + * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding + * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA + * ({_hashTypedDataV4}). + * + * The implementation of the domain separator was designed to be as efficient as possible while still properly updating + * the chain id to protect against replay attacks on an eventual fork of the chain. + * + * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method + * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. + * + * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain + * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the + * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. + * + * @custom:oz-upgrades-unsafe-allow state-variable-immutable + */ +abstract contract EIP712 is IERC5267 { + using ShortStrings for *; + + bytes32 private constant TYPE_HASH = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + + // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to + // invalidate the cached domain separator if the chain id changes. + bytes32 private immutable _cachedDomainSeparator; + uint256 private immutable _cachedChainId; + address private immutable _cachedThis; + + bytes32 private immutable _hashedName; + bytes32 private immutable _hashedVersion; + + ShortString private immutable _name; + ShortString private immutable _version; + string private _nameFallback; + string private _versionFallback; + + /** + * @dev Initializes the domain separator and parameter caches. + * + * The meaning of `name` and `version` is specified in + * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: + * + * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. + * - `version`: the current major version of the signing domain. + * + * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart + * contract upgrade]. + */ + constructor(string memory name, string memory version) { + _name = name.toShortStringWithFallback(_nameFallback); + _version = version.toShortStringWithFallback(_versionFallback); + _hashedName = keccak256(bytes(name)); + _hashedVersion = keccak256(bytes(version)); + + _cachedChainId = block.chainid; + _cachedDomainSeparator = _buildDomainSeparator(); + _cachedThis = address(this); + } + + /** + * @dev Returns the domain separator for the current chain. + */ + function _domainSeparatorV4() internal view returns (bytes32) { + if (address(this) == _cachedThis && block.chainid == _cachedChainId) { + return _cachedDomainSeparator; + } else { + return _buildDomainSeparator(); + } + } + + function _buildDomainSeparator() private view returns (bytes32) { + return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); + } + + /** + * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this + * function returns the hash of the fully encoded EIP712 message for this domain. + * + * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: + * + * ```solidity + * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( + * keccak256("Mail(address to,string contents)"), + * mailTo, + * keccak256(bytes(mailContents)) + * ))); + * address signer = ECDSA.recover(digest, signature); + * ``` + */ + function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { + return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash); + } + + /** + * @dev See {IERC-5267}. + */ + function eip712Domain() + public + view + virtual + returns ( + bytes1 fields, + string memory name, + string memory version, + uint256 chainId, + address verifyingContract, + bytes32 salt, + uint256[] memory extensions + ) + { + return ( + hex"0f", // 01111 + _EIP712Name(), + _EIP712Version(), + block.chainid, + address(this), + bytes32(0), + new uint256[](0) + ); + } + + /** + * @dev The name parameter for the EIP712 domain. + * + * NOTE: By default this function reads _name which is an immutable value. + * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). + */ + // solhint-disable-next-line func-name-mixedcase + function _EIP712Name() internal view returns (string memory) { + return _name.toStringWithFallback(_nameFallback); + } + + /** + * @dev The version parameter for the EIP712 domain. + * + * NOTE: By default this function reads _version which is an immutable value. + * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). + */ + // solhint-disable-next-line func-name-mixedcase + function _EIP712Version() internal view returns (string memory) { + return _version.toStringWithFallback(_versionFallback); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/cryptography/MessageHashUtils.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/cryptography/MessageHashUtils.sol new file mode 100644 index 0000000000..8836693e79 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/cryptography/MessageHashUtils.sol @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol) + +pragma solidity ^0.8.20; + +import {Strings} from "../Strings.sol"; + +/** + * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing. + * + * The library provides methods for generating a hash of a message that conforms to the + * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712] + * specifications. + */ +library MessageHashUtils { + /** + * @dev Returns the keccak256 digest of an EIP-191 signed data with version + * `0x45` (`personal_sign` messages). + * + * The digest is calculated by prefixing a bytes32 `messageHash` with + * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the + * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. + * + * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with + * keccak256, although any bytes32 value can be safely used because the final digest will + * be re-hashed. + * + * See {ECDSA-recover}. + */ + function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) { + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash + mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix + digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20) + } + } + + /** + * @dev Returns the keccak256 digest of an EIP-191 signed data with version + * `0x45` (`personal_sign` messages). + * + * The digest is calculated by prefixing an arbitrary `message` with + * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the + * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. + * + * See {ECDSA-recover}. + */ + function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) { + return + keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message)); + } + + /** + * @dev Returns the keccak256 digest of an EIP-191 signed data with version + * `0x00` (data with intended validator). + * + * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended + * `validator` address. Then hashing the result. + * + * See {ECDSA-recover}. + */ + function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(hex"19_00", validator, data)); + } + + /** + * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`). + * + * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with + * `\x19\x01` and hashing the result. It corresponds to the hash signed by the + * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712. + * + * See {ECDSA-recover}. + */ + function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { + /// @solidity memory-safe-assembly + assembly { + let ptr := mload(0x40) + mstore(ptr, hex"19_01") + mstore(add(ptr, 0x02), domainSeparator) + mstore(add(ptr, 0x22), structHash) + digest := keccak256(ptr, 0x42) + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165.sol new file mode 100644 index 0000000000..1e77b60d73 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) + +pragma solidity ^0.8.20; + +import {IERC165} from "./IERC165.sol"; + +/** + * @dev Implementation of the {IERC165} interface. + * + * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check + * for the additional interface id that will be supported. For example: + * + * ```solidity + * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); + * } + * ``` + */ +abstract contract ERC165 is IERC165 { + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { + return interfaceId == type(IERC165).interfaceId; + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165Checker.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165Checker.sol new file mode 100644 index 0000000000..7b52241446 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165Checker.sol @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165Checker.sol) + +pragma solidity ^0.8.20; + +import {IERC165} from "./IERC165.sol"; + +/** + * @dev Library used to query support of an interface declared via {IERC165}. + * + * Note that these functions return the actual result of the query: they do not + * `revert` if an interface is not supported. It is up to the caller to decide + * what to do in these cases. + */ +library ERC165Checker { + // As per the EIP-165 spec, no interface should ever match 0xffffffff + bytes4 private constant INTERFACE_ID_INVALID = 0xffffffff; + + /** + * @dev Returns true if `account` supports the {IERC165} interface. + */ + function supportsERC165(address account) internal view returns (bool) { + // Any contract that implements ERC165 must explicitly indicate support of + // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid + return + supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) && + !supportsERC165InterfaceUnchecked(account, INTERFACE_ID_INVALID); + } + + /** + * @dev Returns true if `account` supports the interface defined by + * `interfaceId`. Support for {IERC165} itself is queried automatically. + * + * See {IERC165-supportsInterface}. + */ + function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { + // query support of both ERC165 as per the spec and support of _interfaceId + return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId); + } + + /** + * @dev Returns a boolean array where each value corresponds to the + * interfaces passed in and whether they're supported or not. This allows + * you to batch check interfaces for a contract where your expectation + * is that some interfaces may not be supported. + * + * See {IERC165-supportsInterface}. + */ + function getSupportedInterfaces( + address account, + bytes4[] memory interfaceIds + ) internal view returns (bool[] memory) { + // an array of booleans corresponding to interfaceIds and whether they're supported or not + bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); + + // query support of ERC165 itself + if (supportsERC165(account)) { + // query support of each interface in interfaceIds + for (uint256 i = 0; i < interfaceIds.length; i++) { + interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]); + } + } + + return interfaceIdsSupported; + } + + /** + * @dev Returns true if `account` supports all the interfaces defined in + * `interfaceIds`. Support for {IERC165} itself is queried automatically. + * + * Batch-querying can lead to gas savings by skipping repeated checks for + * {IERC165} support. + * + * See {IERC165-supportsInterface}. + */ + function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { + // query support of ERC165 itself + if (!supportsERC165(account)) { + return false; + } + + // query support of each interface in interfaceIds + for (uint256 i = 0; i < interfaceIds.length; i++) { + if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) { + return false; + } + } + + // all interfaces supported + return true; + } + + /** + * @notice Query if a contract implements an interface, does not check ERC165 support + * @param account The address of the contract to query for support of an interface + * @param interfaceId The interface identifier, as specified in ERC-165 + * @return true if the contract at account indicates support of the interface with + * identifier interfaceId, false otherwise + * @dev Assumes that account contains a contract that supports ERC165, otherwise + * the behavior of this method is undefined. This precondition can be checked + * with {supportsERC165}. + * + * Some precompiled contracts will falsely indicate support for a given interface, so caution + * should be exercised when using this function. + * + * Interface identification is specified in ERC-165. + */ + function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) { + // prepare call + bytes memory encodedParams = abi.encodeCall(IERC165.supportsInterface, (interfaceId)); + + // perform static call + bool success; + uint256 returnSize; + uint256 returnValue; + assembly { + success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) + returnSize := returndatasize() + returnValue := mload(0x00) + } + + return success && returnSize >= 0x20 && returnValue > 0; + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol new file mode 100644 index 0000000000..c09f31fe12 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Interface of the ERC165 standard, as defined in the + * https://eips.ethereum.org/EIPS/eip-165[EIP]. + * + * Implementers can declare support of contract interfaces, which can then be + * queried by others ({ERC165Checker}). + * + * For an implementation, see {ERC165}. + */ +interface IERC165 { + /** + * @dev Returns true if this contract implements the interface defined by + * `interfaceId`. See the corresponding + * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] + * to learn more about how these ids are created. + * + * This function call must use less than 30 000 gas. + */ + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/math/Math.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/math/Math.sol new file mode 100644 index 0000000000..9681524529 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/math/Math.sol @@ -0,0 +1,415 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Standard math utilities missing in the Solidity language. + */ +library Math { + /** + * @dev Muldiv operation overflow. + */ + error MathOverflowedMulDiv(); + + enum Rounding { + Floor, // Toward negative infinity + Ceil, // Toward positive infinity + Trunc, // Toward zero + Expand // Away from zero + } + + /** + * @dev Returns the addition of two unsigned integers, with an overflow flag. + */ + function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { + unchecked { + uint256 c = a + b; + if (c < a) return (false, 0); + return (true, c); + } + } + + /** + * @dev Returns the subtraction of two unsigned integers, with an overflow flag. + */ + function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { + unchecked { + if (b > a) return (false, 0); + return (true, a - b); + } + } + + /** + * @dev Returns the multiplication of two unsigned integers, with an overflow flag. + */ + function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { + unchecked { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 + if (a == 0) return (true, 0); + uint256 c = a * b; + if (c / a != b) return (false, 0); + return (true, c); + } + } + + /** + * @dev Returns the division of two unsigned integers, with a division by zero flag. + */ + function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { + unchecked { + if (b == 0) return (false, 0); + return (true, a / b); + } + } + + /** + * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. + */ + function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { + unchecked { + if (b == 0) return (false, 0); + return (true, a % b); + } + } + + /** + * @dev Returns the largest of two numbers. + */ + function max(uint256 a, uint256 b) internal pure returns (uint256) { + return a > b ? a : b; + } + + /** + * @dev Returns the smallest of two numbers. + */ + function min(uint256 a, uint256 b) internal pure returns (uint256) { + return a < b ? a : b; + } + + /** + * @dev Returns the average of two numbers. The result is rounded towards + * zero. + */ + function average(uint256 a, uint256 b) internal pure returns (uint256) { + // (a + b) / 2 can overflow. + return (a & b) + (a ^ b) / 2; + } + + /** + * @dev Returns the ceiling of the division of two numbers. + * + * This differs from standard division with `/` in that it rounds towards infinity instead + * of rounding towards zero. + */ + function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { + if (b == 0) { + // Guarantee the same behavior as in a regular Solidity division. + return a / b; + } + + // (a + b - 1) / b can overflow on addition, so we distribute. + return a == 0 ? 0 : (a - 1) / b + 1; + } + + /** + * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or + * denominator == 0. + * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by + * Uniswap Labs also under MIT license. + */ + function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { + unchecked { + // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use + // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 + // variables such that product = prod1 * 2^256 + prod0. + uint256 prod0 = x * y; // Least significant 256 bits of the product + uint256 prod1; // Most significant 256 bits of the product + assembly { + let mm := mulmod(x, y, not(0)) + prod1 := sub(sub(mm, prod0), lt(mm, prod0)) + } + + // Handle non-overflow cases, 256 by 256 division. + if (prod1 == 0) { + // Solidity will revert if denominator == 0, unlike the div opcode on its own. + // The surrounding unchecked block does not change this fact. + // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. + return prod0 / denominator; + } + + // Make sure the result is less than 2^256. Also prevents denominator == 0. + if (denominator <= prod1) { + revert MathOverflowedMulDiv(); + } + + /////////////////////////////////////////////// + // 512 by 256 division. + /////////////////////////////////////////////// + + // Make division exact by subtracting the remainder from [prod1 prod0]. + uint256 remainder; + assembly { + // Compute remainder using mulmod. + remainder := mulmod(x, y, denominator) + + // Subtract 256 bit number from 512 bit number. + prod1 := sub(prod1, gt(remainder, prod0)) + prod0 := sub(prod0, remainder) + } + + // Factor powers of two out of denominator and compute largest power of two divisor of denominator. + // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. + + uint256 twos = denominator & (0 - denominator); + assembly { + // Divide denominator by twos. + denominator := div(denominator, twos) + + // Divide [prod1 prod0] by twos. + prod0 := div(prod0, twos) + + // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. + twos := add(div(sub(0, twos), twos), 1) + } + + // Shift in bits from prod1 into prod0. + prod0 |= prod1 * twos; + + // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such + // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for + // four bits. That is, denominator * inv = 1 mod 2^4. + uint256 inverse = (3 * denominator) ^ 2; + + // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also + // works in modular arithmetic, doubling the correct bits in each step. + inverse *= 2 - denominator * inverse; // inverse mod 2^8 + inverse *= 2 - denominator * inverse; // inverse mod 2^16 + inverse *= 2 - denominator * inverse; // inverse mod 2^32 + inverse *= 2 - denominator * inverse; // inverse mod 2^64 + inverse *= 2 - denominator * inverse; // inverse mod 2^128 + inverse *= 2 - denominator * inverse; // inverse mod 2^256 + + // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. + // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is + // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 + // is no longer required. + result = prod0 * inverse; + return result; + } + } + + /** + * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. + */ + function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { + uint256 result = mulDiv(x, y, denominator); + if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) { + result += 1; + } + return result; + } + + /** + * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded + * towards zero. + * + * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). + */ + function sqrt(uint256 a) internal pure returns (uint256) { + if (a == 0) { + return 0; + } + + // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. + // + // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have + // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. + // + // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` + // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` + // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` + // + // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. + uint256 result = 1 << (log2(a) >> 1); + + // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, + // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at + // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision + // into the expected uint128 result. + unchecked { + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + return min(result, a / result); + } + } + + /** + * @notice Calculates sqrt(a), following the selected rounding direction. + */ + function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { + unchecked { + uint256 result = sqrt(a); + return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); + } + } + + /** + * @dev Return the log in base 2 of a positive value rounded towards zero. + * Returns 0 if given 0. + */ + function log2(uint256 value) internal pure returns (uint256) { + uint256 result = 0; + unchecked { + if (value >> 128 > 0) { + value >>= 128; + result += 128; + } + if (value >> 64 > 0) { + value >>= 64; + result += 64; + } + if (value >> 32 > 0) { + value >>= 32; + result += 32; + } + if (value >> 16 > 0) { + value >>= 16; + result += 16; + } + if (value >> 8 > 0) { + value >>= 8; + result += 8; + } + if (value >> 4 > 0) { + value >>= 4; + result += 4; + } + if (value >> 2 > 0) { + value >>= 2; + result += 2; + } + if (value >> 1 > 0) { + result += 1; + } + } + return result; + } + + /** + * @dev Return the log in base 2, following the selected rounding direction, of a positive value. + * Returns 0 if given 0. + */ + function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { + unchecked { + uint256 result = log2(value); + return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); + } + } + + /** + * @dev Return the log in base 10 of a positive value rounded towards zero. + * Returns 0 if given 0. + */ + function log10(uint256 value) internal pure returns (uint256) { + uint256 result = 0; + unchecked { + if (value >= 10 ** 64) { + value /= 10 ** 64; + result += 64; + } + if (value >= 10 ** 32) { + value /= 10 ** 32; + result += 32; + } + if (value >= 10 ** 16) { + value /= 10 ** 16; + result += 16; + } + if (value >= 10 ** 8) { + value /= 10 ** 8; + result += 8; + } + if (value >= 10 ** 4) { + value /= 10 ** 4; + result += 4; + } + if (value >= 10 ** 2) { + value /= 10 ** 2; + result += 2; + } + if (value >= 10 ** 1) { + result += 1; + } + } + return result; + } + + /** + * @dev Return the log in base 10, following the selected rounding direction, of a positive value. + * Returns 0 if given 0. + */ + function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { + unchecked { + uint256 result = log10(value); + return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); + } + } + + /** + * @dev Return the log in base 256 of a positive value rounded towards zero. + * Returns 0 if given 0. + * + * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. + */ + function log256(uint256 value) internal pure returns (uint256) { + uint256 result = 0; + unchecked { + if (value >> 128 > 0) { + value >>= 128; + result += 16; + } + if (value >> 64 > 0) { + value >>= 64; + result += 8; + } + if (value >> 32 > 0) { + value >>= 32; + result += 4; + } + if (value >> 16 > 0) { + value >>= 16; + result += 2; + } + if (value >> 8 > 0) { + result += 1; + } + } + return result; + } + + /** + * @dev Return the log in base 256, following the selected rounding direction, of a positive value. + * Returns 0 if given 0. + */ + function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { + unchecked { + uint256 result = log256(value); + return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); + } + } + + /** + * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. + */ + function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { + return uint8(rounding) % 2 == 1; + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/math/SafeCast.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/math/SafeCast.sol new file mode 100644 index 0000000000..0ed458b43c --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/math/SafeCast.sol @@ -0,0 +1,1153 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol) +// This file was procedurally generated from scripts/generate/templates/SafeCast.js. + +pragma solidity ^0.8.20; + +/** + * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow + * checks. + * + * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can + * easily result in undesired exploitation or bugs, since developers usually + * assume that overflows raise errors. `SafeCast` restores this intuition by + * reverting the transaction when such an operation overflows. + * + * Using this library instead of the unchecked operations eliminates an entire + * class of bugs, so it's recommended to use it always. + */ +library SafeCast { + /** + * @dev Value doesn't fit in an uint of `bits` size. + */ + error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); + + /** + * @dev An int value doesn't fit in an uint of `bits` size. + */ + error SafeCastOverflowedIntToUint(int256 value); + + /** + * @dev Value doesn't fit in an int of `bits` size. + */ + error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); + + /** + * @dev An uint value doesn't fit in an int of `bits` size. + */ + error SafeCastOverflowedUintToInt(uint256 value); + + /** + * @dev Returns the downcasted uint248 from uint256, reverting on + * overflow (when the input is greater than largest uint248). + * + * Counterpart to Solidity's `uint248` operator. + * + * Requirements: + * + * - input must fit into 248 bits + */ + function toUint248(uint256 value) internal pure returns (uint248) { + if (value > type(uint248).max) { + revert SafeCastOverflowedUintDowncast(248, value); + } + return uint248(value); + } + + /** + * @dev Returns the downcasted uint240 from uint256, reverting on + * overflow (when the input is greater than largest uint240). + * + * Counterpart to Solidity's `uint240` operator. + * + * Requirements: + * + * - input must fit into 240 bits + */ + function toUint240(uint256 value) internal pure returns (uint240) { + if (value > type(uint240).max) { + revert SafeCastOverflowedUintDowncast(240, value); + } + return uint240(value); + } + + /** + * @dev Returns the downcasted uint232 from uint256, reverting on + * overflow (when the input is greater than largest uint232). + * + * Counterpart to Solidity's `uint232` operator. + * + * Requirements: + * + * - input must fit into 232 bits + */ + function toUint232(uint256 value) internal pure returns (uint232) { + if (value > type(uint232).max) { + revert SafeCastOverflowedUintDowncast(232, value); + } + return uint232(value); + } + + /** + * @dev Returns the downcasted uint224 from uint256, reverting on + * overflow (when the input is greater than largest uint224). + * + * Counterpart to Solidity's `uint224` operator. + * + * Requirements: + * + * - input must fit into 224 bits + */ + function toUint224(uint256 value) internal pure returns (uint224) { + if (value > type(uint224).max) { + revert SafeCastOverflowedUintDowncast(224, value); + } + return uint224(value); + } + + /** + * @dev Returns the downcasted uint216 from uint256, reverting on + * overflow (when the input is greater than largest uint216). + * + * Counterpart to Solidity's `uint216` operator. + * + * Requirements: + * + * - input must fit into 216 bits + */ + function toUint216(uint256 value) internal pure returns (uint216) { + if (value > type(uint216).max) { + revert SafeCastOverflowedUintDowncast(216, value); + } + return uint216(value); + } + + /** + * @dev Returns the downcasted uint208 from uint256, reverting on + * overflow (when the input is greater than largest uint208). + * + * Counterpart to Solidity's `uint208` operator. + * + * Requirements: + * + * - input must fit into 208 bits + */ + function toUint208(uint256 value) internal pure returns (uint208) { + if (value > type(uint208).max) { + revert SafeCastOverflowedUintDowncast(208, value); + } + return uint208(value); + } + + /** + * @dev Returns the downcasted uint200 from uint256, reverting on + * overflow (when the input is greater than largest uint200). + * + * Counterpart to Solidity's `uint200` operator. + * + * Requirements: + * + * - input must fit into 200 bits + */ + function toUint200(uint256 value) internal pure returns (uint200) { + if (value > type(uint200).max) { + revert SafeCastOverflowedUintDowncast(200, value); + } + return uint200(value); + } + + /** + * @dev Returns the downcasted uint192 from uint256, reverting on + * overflow (when the input is greater than largest uint192). + * + * Counterpart to Solidity's `uint192` operator. + * + * Requirements: + * + * - input must fit into 192 bits + */ + function toUint192(uint256 value) internal pure returns (uint192) { + if (value > type(uint192).max) { + revert SafeCastOverflowedUintDowncast(192, value); + } + return uint192(value); + } + + /** + * @dev Returns the downcasted uint184 from uint256, reverting on + * overflow (when the input is greater than largest uint184). + * + * Counterpart to Solidity's `uint184` operator. + * + * Requirements: + * + * - input must fit into 184 bits + */ + function toUint184(uint256 value) internal pure returns (uint184) { + if (value > type(uint184).max) { + revert SafeCastOverflowedUintDowncast(184, value); + } + return uint184(value); + } + + /** + * @dev Returns the downcasted uint176 from uint256, reverting on + * overflow (when the input is greater than largest uint176). + * + * Counterpart to Solidity's `uint176` operator. + * + * Requirements: + * + * - input must fit into 176 bits + */ + function toUint176(uint256 value) internal pure returns (uint176) { + if (value > type(uint176).max) { + revert SafeCastOverflowedUintDowncast(176, value); + } + return uint176(value); + } + + /** + * @dev Returns the downcasted uint168 from uint256, reverting on + * overflow (when the input is greater than largest uint168). + * + * Counterpart to Solidity's `uint168` operator. + * + * Requirements: + * + * - input must fit into 168 bits + */ + function toUint168(uint256 value) internal pure returns (uint168) { + if (value > type(uint168).max) { + revert SafeCastOverflowedUintDowncast(168, value); + } + return uint168(value); + } + + /** + * @dev Returns the downcasted uint160 from uint256, reverting on + * overflow (when the input is greater than largest uint160). + * + * Counterpart to Solidity's `uint160` operator. + * + * Requirements: + * + * - input must fit into 160 bits + */ + function toUint160(uint256 value) internal pure returns (uint160) { + if (value > type(uint160).max) { + revert SafeCastOverflowedUintDowncast(160, value); + } + return uint160(value); + } + + /** + * @dev Returns the downcasted uint152 from uint256, reverting on + * overflow (when the input is greater than largest uint152). + * + * Counterpart to Solidity's `uint152` operator. + * + * Requirements: + * + * - input must fit into 152 bits + */ + function toUint152(uint256 value) internal pure returns (uint152) { + if (value > type(uint152).max) { + revert SafeCastOverflowedUintDowncast(152, value); + } + return uint152(value); + } + + /** + * @dev Returns the downcasted uint144 from uint256, reverting on + * overflow (when the input is greater than largest uint144). + * + * Counterpart to Solidity's `uint144` operator. + * + * Requirements: + * + * - input must fit into 144 bits + */ + function toUint144(uint256 value) internal pure returns (uint144) { + if (value > type(uint144).max) { + revert SafeCastOverflowedUintDowncast(144, value); + } + return uint144(value); + } + + /** + * @dev Returns the downcasted uint136 from uint256, reverting on + * overflow (when the input is greater than largest uint136). + * + * Counterpart to Solidity's `uint136` operator. + * + * Requirements: + * + * - input must fit into 136 bits + */ + function toUint136(uint256 value) internal pure returns (uint136) { + if (value > type(uint136).max) { + revert SafeCastOverflowedUintDowncast(136, value); + } + return uint136(value); + } + + /** + * @dev Returns the downcasted uint128 from uint256, reverting on + * overflow (when the input is greater than largest uint128). + * + * Counterpart to Solidity's `uint128` operator. + * + * Requirements: + * + * - input must fit into 128 bits + */ + function toUint128(uint256 value) internal pure returns (uint128) { + if (value > type(uint128).max) { + revert SafeCastOverflowedUintDowncast(128, value); + } + return uint128(value); + } + + /** + * @dev Returns the downcasted uint120 from uint256, reverting on + * overflow (when the input is greater than largest uint120). + * + * Counterpart to Solidity's `uint120` operator. + * + * Requirements: + * + * - input must fit into 120 bits + */ + function toUint120(uint256 value) internal pure returns (uint120) { + if (value > type(uint120).max) { + revert SafeCastOverflowedUintDowncast(120, value); + } + return uint120(value); + } + + /** + * @dev Returns the downcasted uint112 from uint256, reverting on + * overflow (when the input is greater than largest uint112). + * + * Counterpart to Solidity's `uint112` operator. + * + * Requirements: + * + * - input must fit into 112 bits + */ + function toUint112(uint256 value) internal pure returns (uint112) { + if (value > type(uint112).max) { + revert SafeCastOverflowedUintDowncast(112, value); + } + return uint112(value); + } + + /** + * @dev Returns the downcasted uint104 from uint256, reverting on + * overflow (when the input is greater than largest uint104). + * + * Counterpart to Solidity's `uint104` operator. + * + * Requirements: + * + * - input must fit into 104 bits + */ + function toUint104(uint256 value) internal pure returns (uint104) { + if (value > type(uint104).max) { + revert SafeCastOverflowedUintDowncast(104, value); + } + return uint104(value); + } + + /** + * @dev Returns the downcasted uint96 from uint256, reverting on + * overflow (when the input is greater than largest uint96). + * + * Counterpart to Solidity's `uint96` operator. + * + * Requirements: + * + * - input must fit into 96 bits + */ + function toUint96(uint256 value) internal pure returns (uint96) { + if (value > type(uint96).max) { + revert SafeCastOverflowedUintDowncast(96, value); + } + return uint96(value); + } + + /** + * @dev Returns the downcasted uint88 from uint256, reverting on + * overflow (when the input is greater than largest uint88). + * + * Counterpart to Solidity's `uint88` operator. + * + * Requirements: + * + * - input must fit into 88 bits + */ + function toUint88(uint256 value) internal pure returns (uint88) { + if (value > type(uint88).max) { + revert SafeCastOverflowedUintDowncast(88, value); + } + return uint88(value); + } + + /** + * @dev Returns the downcasted uint80 from uint256, reverting on + * overflow (when the input is greater than largest uint80). + * + * Counterpart to Solidity's `uint80` operator. + * + * Requirements: + * + * - input must fit into 80 bits + */ + function toUint80(uint256 value) internal pure returns (uint80) { + if (value > type(uint80).max) { + revert SafeCastOverflowedUintDowncast(80, value); + } + return uint80(value); + } + + /** + * @dev Returns the downcasted uint72 from uint256, reverting on + * overflow (when the input is greater than largest uint72). + * + * Counterpart to Solidity's `uint72` operator. + * + * Requirements: + * + * - input must fit into 72 bits + */ + function toUint72(uint256 value) internal pure returns (uint72) { + if (value > type(uint72).max) { + revert SafeCastOverflowedUintDowncast(72, value); + } + return uint72(value); + } + + /** + * @dev Returns the downcasted uint64 from uint256, reverting on + * overflow (when the input is greater than largest uint64). + * + * Counterpart to Solidity's `uint64` operator. + * + * Requirements: + * + * - input must fit into 64 bits + */ + function toUint64(uint256 value) internal pure returns (uint64) { + if (value > type(uint64).max) { + revert SafeCastOverflowedUintDowncast(64, value); + } + return uint64(value); + } + + /** + * @dev Returns the downcasted uint56 from uint256, reverting on + * overflow (when the input is greater than largest uint56). + * + * Counterpart to Solidity's `uint56` operator. + * + * Requirements: + * + * - input must fit into 56 bits + */ + function toUint56(uint256 value) internal pure returns (uint56) { + if (value > type(uint56).max) { + revert SafeCastOverflowedUintDowncast(56, value); + } + return uint56(value); + } + + /** + * @dev Returns the downcasted uint48 from uint256, reverting on + * overflow (when the input is greater than largest uint48). + * + * Counterpart to Solidity's `uint48` operator. + * + * Requirements: + * + * - input must fit into 48 bits + */ + function toUint48(uint256 value) internal pure returns (uint48) { + if (value > type(uint48).max) { + revert SafeCastOverflowedUintDowncast(48, value); + } + return uint48(value); + } + + /** + * @dev Returns the downcasted uint40 from uint256, reverting on + * overflow (when the input is greater than largest uint40). + * + * Counterpart to Solidity's `uint40` operator. + * + * Requirements: + * + * - input must fit into 40 bits + */ + function toUint40(uint256 value) internal pure returns (uint40) { + if (value > type(uint40).max) { + revert SafeCastOverflowedUintDowncast(40, value); + } + return uint40(value); + } + + /** + * @dev Returns the downcasted uint32 from uint256, reverting on + * overflow (when the input is greater than largest uint32). + * + * Counterpart to Solidity's `uint32` operator. + * + * Requirements: + * + * - input must fit into 32 bits + */ + function toUint32(uint256 value) internal pure returns (uint32) { + if (value > type(uint32).max) { + revert SafeCastOverflowedUintDowncast(32, value); + } + return uint32(value); + } + + /** + * @dev Returns the downcasted uint24 from uint256, reverting on + * overflow (when the input is greater than largest uint24). + * + * Counterpart to Solidity's `uint24` operator. + * + * Requirements: + * + * - input must fit into 24 bits + */ + function toUint24(uint256 value) internal pure returns (uint24) { + if (value > type(uint24).max) { + revert SafeCastOverflowedUintDowncast(24, value); + } + return uint24(value); + } + + /** + * @dev Returns the downcasted uint16 from uint256, reverting on + * overflow (when the input is greater than largest uint16). + * + * Counterpart to Solidity's `uint16` operator. + * + * Requirements: + * + * - input must fit into 16 bits + */ + function toUint16(uint256 value) internal pure returns (uint16) { + if (value > type(uint16).max) { + revert SafeCastOverflowedUintDowncast(16, value); + } + return uint16(value); + } + + /** + * @dev Returns the downcasted uint8 from uint256, reverting on + * overflow (when the input is greater than largest uint8). + * + * Counterpart to Solidity's `uint8` operator. + * + * Requirements: + * + * - input must fit into 8 bits + */ + function toUint8(uint256 value) internal pure returns (uint8) { + if (value > type(uint8).max) { + revert SafeCastOverflowedUintDowncast(8, value); + } + return uint8(value); + } + + /** + * @dev Converts a signed int256 into an unsigned uint256. + * + * Requirements: + * + * - input must be greater than or equal to 0. + */ + function toUint256(int256 value) internal pure returns (uint256) { + if (value < 0) { + revert SafeCastOverflowedIntToUint(value); + } + return uint256(value); + } + + /** + * @dev Returns the downcasted int248 from int256, reverting on + * overflow (when the input is less than smallest int248 or + * greater than largest int248). + * + * Counterpart to Solidity's `int248` operator. + * + * Requirements: + * + * - input must fit into 248 bits + */ + function toInt248(int256 value) internal pure returns (int248 downcasted) { + downcasted = int248(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(248, value); + } + } + + /** + * @dev Returns the downcasted int240 from int256, reverting on + * overflow (when the input is less than smallest int240 or + * greater than largest int240). + * + * Counterpart to Solidity's `int240` operator. + * + * Requirements: + * + * - input must fit into 240 bits + */ + function toInt240(int256 value) internal pure returns (int240 downcasted) { + downcasted = int240(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(240, value); + } + } + + /** + * @dev Returns the downcasted int232 from int256, reverting on + * overflow (when the input is less than smallest int232 or + * greater than largest int232). + * + * Counterpart to Solidity's `int232` operator. + * + * Requirements: + * + * - input must fit into 232 bits + */ + function toInt232(int256 value) internal pure returns (int232 downcasted) { + downcasted = int232(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(232, value); + } + } + + /** + * @dev Returns the downcasted int224 from int256, reverting on + * overflow (when the input is less than smallest int224 or + * greater than largest int224). + * + * Counterpart to Solidity's `int224` operator. + * + * Requirements: + * + * - input must fit into 224 bits + */ + function toInt224(int256 value) internal pure returns (int224 downcasted) { + downcasted = int224(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(224, value); + } + } + + /** + * @dev Returns the downcasted int216 from int256, reverting on + * overflow (when the input is less than smallest int216 or + * greater than largest int216). + * + * Counterpart to Solidity's `int216` operator. + * + * Requirements: + * + * - input must fit into 216 bits + */ + function toInt216(int256 value) internal pure returns (int216 downcasted) { + downcasted = int216(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(216, value); + } + } + + /** + * @dev Returns the downcasted int208 from int256, reverting on + * overflow (when the input is less than smallest int208 or + * greater than largest int208). + * + * Counterpart to Solidity's `int208` operator. + * + * Requirements: + * + * - input must fit into 208 bits + */ + function toInt208(int256 value) internal pure returns (int208 downcasted) { + downcasted = int208(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(208, value); + } + } + + /** + * @dev Returns the downcasted int200 from int256, reverting on + * overflow (when the input is less than smallest int200 or + * greater than largest int200). + * + * Counterpart to Solidity's `int200` operator. + * + * Requirements: + * + * - input must fit into 200 bits + */ + function toInt200(int256 value) internal pure returns (int200 downcasted) { + downcasted = int200(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(200, value); + } + } + + /** + * @dev Returns the downcasted int192 from int256, reverting on + * overflow (when the input is less than smallest int192 or + * greater than largest int192). + * + * Counterpart to Solidity's `int192` operator. + * + * Requirements: + * + * - input must fit into 192 bits + */ + function toInt192(int256 value) internal pure returns (int192 downcasted) { + downcasted = int192(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(192, value); + } + } + + /** + * @dev Returns the downcasted int184 from int256, reverting on + * overflow (when the input is less than smallest int184 or + * greater than largest int184). + * + * Counterpart to Solidity's `int184` operator. + * + * Requirements: + * + * - input must fit into 184 bits + */ + function toInt184(int256 value) internal pure returns (int184 downcasted) { + downcasted = int184(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(184, value); + } + } + + /** + * @dev Returns the downcasted int176 from int256, reverting on + * overflow (when the input is less than smallest int176 or + * greater than largest int176). + * + * Counterpart to Solidity's `int176` operator. + * + * Requirements: + * + * - input must fit into 176 bits + */ + function toInt176(int256 value) internal pure returns (int176 downcasted) { + downcasted = int176(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(176, value); + } + } + + /** + * @dev Returns the downcasted int168 from int256, reverting on + * overflow (when the input is less than smallest int168 or + * greater than largest int168). + * + * Counterpart to Solidity's `int168` operator. + * + * Requirements: + * + * - input must fit into 168 bits + */ + function toInt168(int256 value) internal pure returns (int168 downcasted) { + downcasted = int168(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(168, value); + } + } + + /** + * @dev Returns the downcasted int160 from int256, reverting on + * overflow (when the input is less than smallest int160 or + * greater than largest int160). + * + * Counterpart to Solidity's `int160` operator. + * + * Requirements: + * + * - input must fit into 160 bits + */ + function toInt160(int256 value) internal pure returns (int160 downcasted) { + downcasted = int160(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(160, value); + } + } + + /** + * @dev Returns the downcasted int152 from int256, reverting on + * overflow (when the input is less than smallest int152 or + * greater than largest int152). + * + * Counterpart to Solidity's `int152` operator. + * + * Requirements: + * + * - input must fit into 152 bits + */ + function toInt152(int256 value) internal pure returns (int152 downcasted) { + downcasted = int152(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(152, value); + } + } + + /** + * @dev Returns the downcasted int144 from int256, reverting on + * overflow (when the input is less than smallest int144 or + * greater than largest int144). + * + * Counterpart to Solidity's `int144` operator. + * + * Requirements: + * + * - input must fit into 144 bits + */ + function toInt144(int256 value) internal pure returns (int144 downcasted) { + downcasted = int144(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(144, value); + } + } + + /** + * @dev Returns the downcasted int136 from int256, reverting on + * overflow (when the input is less than smallest int136 or + * greater than largest int136). + * + * Counterpart to Solidity's `int136` operator. + * + * Requirements: + * + * - input must fit into 136 bits + */ + function toInt136(int256 value) internal pure returns (int136 downcasted) { + downcasted = int136(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(136, value); + } + } + + /** + * @dev Returns the downcasted int128 from int256, reverting on + * overflow (when the input is less than smallest int128 or + * greater than largest int128). + * + * Counterpart to Solidity's `int128` operator. + * + * Requirements: + * + * - input must fit into 128 bits + */ + function toInt128(int256 value) internal pure returns (int128 downcasted) { + downcasted = int128(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(128, value); + } + } + + /** + * @dev Returns the downcasted int120 from int256, reverting on + * overflow (when the input is less than smallest int120 or + * greater than largest int120). + * + * Counterpart to Solidity's `int120` operator. + * + * Requirements: + * + * - input must fit into 120 bits + */ + function toInt120(int256 value) internal pure returns (int120 downcasted) { + downcasted = int120(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(120, value); + } + } + + /** + * @dev Returns the downcasted int112 from int256, reverting on + * overflow (when the input is less than smallest int112 or + * greater than largest int112). + * + * Counterpart to Solidity's `int112` operator. + * + * Requirements: + * + * - input must fit into 112 bits + */ + function toInt112(int256 value) internal pure returns (int112 downcasted) { + downcasted = int112(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(112, value); + } + } + + /** + * @dev Returns the downcasted int104 from int256, reverting on + * overflow (when the input is less than smallest int104 or + * greater than largest int104). + * + * Counterpart to Solidity's `int104` operator. + * + * Requirements: + * + * - input must fit into 104 bits + */ + function toInt104(int256 value) internal pure returns (int104 downcasted) { + downcasted = int104(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(104, value); + } + } + + /** + * @dev Returns the downcasted int96 from int256, reverting on + * overflow (when the input is less than smallest int96 or + * greater than largest int96). + * + * Counterpart to Solidity's `int96` operator. + * + * Requirements: + * + * - input must fit into 96 bits + */ + function toInt96(int256 value) internal pure returns (int96 downcasted) { + downcasted = int96(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(96, value); + } + } + + /** + * @dev Returns the downcasted int88 from int256, reverting on + * overflow (when the input is less than smallest int88 or + * greater than largest int88). + * + * Counterpart to Solidity's `int88` operator. + * + * Requirements: + * + * - input must fit into 88 bits + */ + function toInt88(int256 value) internal pure returns (int88 downcasted) { + downcasted = int88(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(88, value); + } + } + + /** + * @dev Returns the downcasted int80 from int256, reverting on + * overflow (when the input is less than smallest int80 or + * greater than largest int80). + * + * Counterpart to Solidity's `int80` operator. + * + * Requirements: + * + * - input must fit into 80 bits + */ + function toInt80(int256 value) internal pure returns (int80 downcasted) { + downcasted = int80(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(80, value); + } + } + + /** + * @dev Returns the downcasted int72 from int256, reverting on + * overflow (when the input is less than smallest int72 or + * greater than largest int72). + * + * Counterpart to Solidity's `int72` operator. + * + * Requirements: + * + * - input must fit into 72 bits + */ + function toInt72(int256 value) internal pure returns (int72 downcasted) { + downcasted = int72(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(72, value); + } + } + + /** + * @dev Returns the downcasted int64 from int256, reverting on + * overflow (when the input is less than smallest int64 or + * greater than largest int64). + * + * Counterpart to Solidity's `int64` operator. + * + * Requirements: + * + * - input must fit into 64 bits + */ + function toInt64(int256 value) internal pure returns (int64 downcasted) { + downcasted = int64(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(64, value); + } + } + + /** + * @dev Returns the downcasted int56 from int256, reverting on + * overflow (when the input is less than smallest int56 or + * greater than largest int56). + * + * Counterpart to Solidity's `int56` operator. + * + * Requirements: + * + * - input must fit into 56 bits + */ + function toInt56(int256 value) internal pure returns (int56 downcasted) { + downcasted = int56(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(56, value); + } + } + + /** + * @dev Returns the downcasted int48 from int256, reverting on + * overflow (when the input is less than smallest int48 or + * greater than largest int48). + * + * Counterpart to Solidity's `int48` operator. + * + * Requirements: + * + * - input must fit into 48 bits + */ + function toInt48(int256 value) internal pure returns (int48 downcasted) { + downcasted = int48(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(48, value); + } + } + + /** + * @dev Returns the downcasted int40 from int256, reverting on + * overflow (when the input is less than smallest int40 or + * greater than largest int40). + * + * Counterpart to Solidity's `int40` operator. + * + * Requirements: + * + * - input must fit into 40 bits + */ + function toInt40(int256 value) internal pure returns (int40 downcasted) { + downcasted = int40(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(40, value); + } + } + + /** + * @dev Returns the downcasted int32 from int256, reverting on + * overflow (when the input is less than smallest int32 or + * greater than largest int32). + * + * Counterpart to Solidity's `int32` operator. + * + * Requirements: + * + * - input must fit into 32 bits + */ + function toInt32(int256 value) internal pure returns (int32 downcasted) { + downcasted = int32(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(32, value); + } + } + + /** + * @dev Returns the downcasted int24 from int256, reverting on + * overflow (when the input is less than smallest int24 or + * greater than largest int24). + * + * Counterpart to Solidity's `int24` operator. + * + * Requirements: + * + * - input must fit into 24 bits + */ + function toInt24(int256 value) internal pure returns (int24 downcasted) { + downcasted = int24(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(24, value); + } + } + + /** + * @dev Returns the downcasted int16 from int256, reverting on + * overflow (when the input is less than smallest int16 or + * greater than largest int16). + * + * Counterpart to Solidity's `int16` operator. + * + * Requirements: + * + * - input must fit into 16 bits + */ + function toInt16(int256 value) internal pure returns (int16 downcasted) { + downcasted = int16(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(16, value); + } + } + + /** + * @dev Returns the downcasted int8 from int256, reverting on + * overflow (when the input is less than smallest int8 or + * greater than largest int8). + * + * Counterpart to Solidity's `int8` operator. + * + * Requirements: + * + * - input must fit into 8 bits + */ + function toInt8(int256 value) internal pure returns (int8 downcasted) { + downcasted = int8(value); + if (downcasted != value) { + revert SafeCastOverflowedIntDowncast(8, value); + } + } + + /** + * @dev Converts an unsigned uint256 into a signed int256. + * + * Requirements: + * + * - input must be less than or equal to maxInt256. + */ + function toInt256(uint256 value) internal pure returns (int256) { + // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive + if (value > uint256(type(int256).max)) { + revert SafeCastOverflowedUintToInt(value); + } + return int256(value); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/math/SignedMath.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/math/SignedMath.sol new file mode 100644 index 0000000000..66a6151629 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/math/SignedMath.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Standard signed math utilities missing in the Solidity language. + */ +library SignedMath { + /** + * @dev Returns the largest of two signed numbers. + */ + function max(int256 a, int256 b) internal pure returns (int256) { + return a > b ? a : b; + } + + /** + * @dev Returns the smallest of two signed numbers. + */ + function min(int256 a, int256 b) internal pure returns (int256) { + return a < b ? a : b; + } + + /** + * @dev Returns the average of two signed numbers without overflow. + * The result is rounded towards zero. + */ + function average(int256 a, int256 b) internal pure returns (int256) { + // Formula from the book "Hacker's Delight" + int256 x = (a & b) + ((a ^ b) >> 1); + return x + (int256(uint256(x) >> 255) & (a ^ b)); + } + + /** + * @dev Returns the absolute unsigned value of a signed value. + */ + function abs(int256 n) internal pure returns (uint256) { + unchecked { + // must be unchecked in order to support `n = type(int256).min` + return uint256(n >= 0 ? n : -n); + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableMap.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableMap.sol new file mode 100644 index 0000000000..929ae7c536 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableMap.sol @@ -0,0 +1,533 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableMap.sol) +// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js. + +pragma solidity ^0.8.20; + +import {EnumerableSet} from "./EnumerableSet.sol"; + +/** + * @dev Library for managing an enumerable variant of Solidity's + * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] + * type. + * + * Maps have the following properties: + * + * - Entries are added, removed, and checked for existence in constant time + * (O(1)). + * - Entries are enumerated in O(n). No guarantees are made on the ordering. + * + * ```solidity + * contract Example { + * // Add the library methods + * using EnumerableMap for EnumerableMap.UintToAddressMap; + * + * // Declare a set state variable + * EnumerableMap.UintToAddressMap private myMap; + * } + * ``` + * + * The following map types are supported: + * + * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0 + * - `address -> uint256` (`AddressToUintMap`) since v4.6.0 + * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0 + * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0 + * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0 + * + * [WARNING] + * ==== + * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure + * unusable. + * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. + * + * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an + * array of EnumerableMap. + * ==== + */ +library EnumerableMap { + using EnumerableSet for EnumerableSet.Bytes32Set; + + // To implement this library for multiple types with as little code repetition as possible, we write it in + // terms of a generic Map type with bytes32 keys and values. The Map implementation uses private functions, + // and user-facing implementations such as `UintToAddressMap` are just wrappers around the underlying Map. + // This means that we can only create new EnumerableMaps for types that fit in bytes32. + + /** + * @dev Query for a nonexistent map key. + */ + error EnumerableMapNonexistentKey(bytes32 key); + + struct Bytes32ToBytes32Map { + // Storage of keys + EnumerableSet.Bytes32Set _keys; + mapping(bytes32 key => bytes32) _values; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) { + map._values[key] = value; + return map._keys.add(key); + } + + /** + * @dev Removes a key-value pair from a map. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { + delete map._values[key]; + return map._keys.remove(key); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { + return map._keys.contains(key); + } + + /** + * @dev Returns the number of key-value pairs in the map. O(1). + */ + function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { + return map._keys.length(); + } + + /** + * @dev Returns the key-value pair stored at position `index` in the map. O(1). + * + * Note that there are no guarantees on the ordering of entries inside the + * array, and it may change when more entries are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) { + bytes32 key = map._keys.at(index); + return (key, map._values[key]); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) { + bytes32 value = map._values[key]; + if (value == bytes32(0)) { + return (contains(map, key), bytes32(0)); + } else { + return (true, value); + } + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) { + bytes32 value = map._values[key]; + if (value == 0 && !contains(map, key)) { + revert EnumerableMapNonexistentKey(key); + } + return value; + } + + /** + * @dev Return the an array containing all the keys + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) { + return map._keys.values(); + } + + // UintToUintMap + + struct UintToUintMap { + Bytes32ToBytes32Map _inner; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) { + return set(map._inner, bytes32(key), bytes32(value)); + } + + /** + * @dev Removes a value from a map. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(UintToUintMap storage map, uint256 key) internal returns (bool) { + return remove(map._inner, bytes32(key)); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) { + return contains(map._inner, bytes32(key)); + } + + /** + * @dev Returns the number of elements in the map. O(1). + */ + function length(UintToUintMap storage map) internal view returns (uint256) { + return length(map._inner); + } + + /** + * @dev Returns the element stored at position `index` in the map. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) { + (bytes32 key, bytes32 value) = at(map._inner, index); + return (uint256(key), uint256(value)); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) { + (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); + return (success, uint256(value)); + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) { + return uint256(get(map._inner, bytes32(key))); + } + + /** + * @dev Return the an array containing all the keys + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function keys(UintToUintMap storage map) internal view returns (uint256[] memory) { + bytes32[] memory store = keys(map._inner); + uint256[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } + + // UintToAddressMap + + struct UintToAddressMap { + Bytes32ToBytes32Map _inner; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { + return set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); + } + + /** + * @dev Removes a value from a map. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { + return remove(map._inner, bytes32(key)); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { + return contains(map._inner, bytes32(key)); + } + + /** + * @dev Returns the number of elements in the map. O(1). + */ + function length(UintToAddressMap storage map) internal view returns (uint256) { + return length(map._inner); + } + + /** + * @dev Returns the element stored at position `index` in the map. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { + (bytes32 key, bytes32 value) = at(map._inner, index); + return (uint256(key), address(uint160(uint256(value)))); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { + (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); + return (success, address(uint160(uint256(value)))); + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { + return address(uint160(uint256(get(map._inner, bytes32(key))))); + } + + /** + * @dev Return the an array containing all the keys + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) { + bytes32[] memory store = keys(map._inner); + uint256[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } + + // AddressToUintMap + + struct AddressToUintMap { + Bytes32ToBytes32Map _inner; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) { + return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value)); + } + + /** + * @dev Removes a value from a map. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(AddressToUintMap storage map, address key) internal returns (bool) { + return remove(map._inner, bytes32(uint256(uint160(key)))); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(AddressToUintMap storage map, address key) internal view returns (bool) { + return contains(map._inner, bytes32(uint256(uint160(key)))); + } + + /** + * @dev Returns the number of elements in the map. O(1). + */ + function length(AddressToUintMap storage map) internal view returns (uint256) { + return length(map._inner); + } + + /** + * @dev Returns the element stored at position `index` in the map. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) { + (bytes32 key, bytes32 value) = at(map._inner, index); + return (address(uint160(uint256(key))), uint256(value)); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) { + (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key)))); + return (success, uint256(value)); + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(AddressToUintMap storage map, address key) internal view returns (uint256) { + return uint256(get(map._inner, bytes32(uint256(uint160(key))))); + } + + /** + * @dev Return the an array containing all the keys + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function keys(AddressToUintMap storage map) internal view returns (address[] memory) { + bytes32[] memory store = keys(map._inner); + address[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } + + // Bytes32ToUintMap + + struct Bytes32ToUintMap { + Bytes32ToBytes32Map _inner; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) { + return set(map._inner, key, bytes32(value)); + } + + /** + * @dev Removes a value from a map. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) { + return remove(map._inner, key); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) { + return contains(map._inner, key); + } + + /** + * @dev Returns the number of elements in the map. O(1). + */ + function length(Bytes32ToUintMap storage map) internal view returns (uint256) { + return length(map._inner); + } + + /** + * @dev Returns the element stored at position `index` in the map. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) { + (bytes32 key, bytes32 value) = at(map._inner, index); + return (key, uint256(value)); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) { + (bool success, bytes32 value) = tryGet(map._inner, key); + return (success, uint256(value)); + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) { + return uint256(get(map._inner, key)); + } + + /** + * @dev Return the an array containing all the keys + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) { + bytes32[] memory store = keys(map._inner); + bytes32[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol new file mode 100644 index 0000000000..4c7fc5e1d7 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol @@ -0,0 +1,378 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol) +// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. + +pragma solidity ^0.8.20; + +/** + * @dev Library for managing + * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive + * types. + * + * Sets have the following properties: + * + * - Elements are added, removed, and checked for existence in constant time + * (O(1)). + * - Elements are enumerated in O(n). No guarantees are made on the ordering. + * + * ```solidity + * contract Example { + * // Add the library methods + * using EnumerableSet for EnumerableSet.AddressSet; + * + * // Declare a set state variable + * EnumerableSet.AddressSet private mySet; + * } + * ``` + * + * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) + * and `uint256` (`UintSet`) are supported. + * + * [WARNING] + * ==== + * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure + * unusable. + * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. + * + * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an + * array of EnumerableSet. + * ==== + */ +library EnumerableSet { + // To implement this library for multiple types with as little code + // repetition as possible, we write it in terms of a generic Set type with + // bytes32 values. + // The Set implementation uses private functions, and user-facing + // implementations (such as AddressSet) are just wrappers around the + // underlying Set. + // This means that we can only create new EnumerableSets for types that fit + // in bytes32. + + struct Set { + // Storage of set values + bytes32[] _values; + // Position is the index of the value in the `values` array plus 1. + // Position 0 is used to mean a value is not in the set. + mapping(bytes32 value => uint256) _positions; + } + + /** + * @dev Add a value to a set. O(1). + * + * Returns true if the value was added to the set, that is if it was not + * already present. + */ + function _add(Set storage set, bytes32 value) private returns (bool) { + if (!_contains(set, value)) { + set._values.push(value); + // The value is stored at length-1, but we add 1 to all indexes + // and use 0 as a sentinel value + set._positions[value] = set._values.length; + return true; + } else { + return false; + } + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the value was removed from the set, that is if it was + * present. + */ + function _remove(Set storage set, bytes32 value) private returns (bool) { + // We cache the value's position to prevent multiple reads from the same storage slot + uint256 position = set._positions[value]; + + if (position != 0) { + // Equivalent to contains(set, value) + // To delete an element from the _values array in O(1), we swap the element to delete with the last one in + // the array, and then remove the last element (sometimes called as 'swap and pop'). + // This modifies the order of the array, as noted in {at}. + + uint256 valueIndex = position - 1; + uint256 lastIndex = set._values.length - 1; + + if (valueIndex != lastIndex) { + bytes32 lastValue = set._values[lastIndex]; + + // Move the lastValue to the index where the value to delete is + set._values[valueIndex] = lastValue; + // Update the tracked position of the lastValue (that was just moved) + set._positions[lastValue] = position; + } + + // Delete the slot where the moved value was stored + set._values.pop(); + + // Delete the tracked position for the deleted slot + delete set._positions[value]; + + return true; + } else { + return false; + } + } + + /** + * @dev Returns true if the value is in the set. O(1). + */ + function _contains(Set storage set, bytes32 value) private view returns (bool) { + return set._positions[value] != 0; + } + + /** + * @dev Returns the number of values on the set. O(1). + */ + function _length(Set storage set) private view returns (uint256) { + return set._values.length; + } + + /** + * @dev Returns the value stored at position `index` in the set. O(1). + * + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function _at(Set storage set, uint256 index) private view returns (bytes32) { + return set._values[index]; + } + + /** + * @dev Return the entire set in an array + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function _values(Set storage set) private view returns (bytes32[] memory) { + return set._values; + } + + // Bytes32Set + + struct Bytes32Set { + Set _inner; + } + + /** + * @dev Add a value to a set. O(1). + * + * Returns true if the value was added to the set, that is if it was not + * already present. + */ + function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { + return _add(set._inner, value); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the value was removed from the set, that is if it was + * present. + */ + function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { + return _remove(set._inner, value); + } + + /** + * @dev Returns true if the value is in the set. O(1). + */ + function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { + return _contains(set._inner, value); + } + + /** + * @dev Returns the number of values in the set. O(1). + */ + function length(Bytes32Set storage set) internal view returns (uint256) { + return _length(set._inner); + } + + /** + * @dev Returns the value stored at position `index` in the set. O(1). + * + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { + return _at(set._inner, index); + } + + /** + * @dev Return the entire set in an array + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { + bytes32[] memory store = _values(set._inner); + bytes32[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } + + // AddressSet + + struct AddressSet { + Set _inner; + } + + /** + * @dev Add a value to a set. O(1). + * + * Returns true if the value was added to the set, that is if it was not + * already present. + */ + function add(AddressSet storage set, address value) internal returns (bool) { + return _add(set._inner, bytes32(uint256(uint160(value)))); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the value was removed from the set, that is if it was + * present. + */ + function remove(AddressSet storage set, address value) internal returns (bool) { + return _remove(set._inner, bytes32(uint256(uint160(value)))); + } + + /** + * @dev Returns true if the value is in the set. O(1). + */ + function contains(AddressSet storage set, address value) internal view returns (bool) { + return _contains(set._inner, bytes32(uint256(uint160(value)))); + } + + /** + * @dev Returns the number of values in the set. O(1). + */ + function length(AddressSet storage set) internal view returns (uint256) { + return _length(set._inner); + } + + /** + * @dev Returns the value stored at position `index` in the set. O(1). + * + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(AddressSet storage set, uint256 index) internal view returns (address) { + return address(uint160(uint256(_at(set._inner, index)))); + } + + /** + * @dev Return the entire set in an array + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function values(AddressSet storage set) internal view returns (address[] memory) { + bytes32[] memory store = _values(set._inner); + address[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } + + // UintSet + + struct UintSet { + Set _inner; + } + + /** + * @dev Add a value to a set. O(1). + * + * Returns true if the value was added to the set, that is if it was not + * already present. + */ + function add(UintSet storage set, uint256 value) internal returns (bool) { + return _add(set._inner, bytes32(value)); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the value was removed from the set, that is if it was + * present. + */ + function remove(UintSet storage set, uint256 value) internal returns (bool) { + return _remove(set._inner, bytes32(value)); + } + + /** + * @dev Returns true if the value is in the set. O(1). + */ + function contains(UintSet storage set, uint256 value) internal view returns (bool) { + return _contains(set._inner, bytes32(value)); + } + + /** + * @dev Returns the number of values in the set. O(1). + */ + function length(UintSet storage set) internal view returns (uint256) { + return _length(set._inner); + } + + /** + * @dev Returns the value stored at position `index` in the set. O(1). + * + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(UintSet storage set, uint256 index) internal view returns (uint256) { + return uint256(_at(set._inner, index)); + } + + /** + * @dev Return the entire set in an array + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function values(UintSet storage set) internal view returns (uint256[] memory) { + bytes32[] memory store = _values(set._inner); + uint256[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } +} From 6ab3eb5b67739ff88d3c4cf8ea125fd8273bc2b1 Mon Sep 17 00:00:00 2001 From: "Abdelrahman Soliman (Boda)" <2677789+asoliman92@users.noreply.github.com> Date: Wed, 7 Aug 2024 22:32:07 +0400 Subject: [PATCH 054/432] [CCIP Merge] Capabilities [CCIP-2943] (#14068) * [CCIP Merge] Add ccip capabilities directory [CCIP-2943] (#14044) * Add ccip capabilities directory * [CCIP Merge] Capabilities fix [CCIP-2943] (#14048) * Fix compilation for launcher, diff Make application.go ready for adding more fixes * Fix launcher tests * ks-409 fix the mock trigger to ensure events are sent (#14047) * Add ccip to job orm * Add capabilities directory under BUSL license * Prep to instantiate separate registrysyncer for CCIP * Move registrySyncer creation into ccip delegate * [chore] Change registrysyncer config to bytes * Fix launcher diff tests after changing structs in syncer * Fix linting * MAke simulated backend client work with chains other than 1337 * core/capabilities/ccip: use OCR offchain config (#1264) We want to define and use the appropriate OCR offchain config for each plugin. Requires https://github.com/smartcontractkit/chainlink-ccip/pull/36/ * Cleaning up * Add capabilities types to mockery --------- Co-authored-by: Cedric Cordenier Co-authored-by: Matthew Pendrey Co-authored-by: Makram * make modgraph * Add changeset * Fix test with new TxMgr constructor --------- Co-authored-by: Cedric Cordenier Co-authored-by: Matthew Pendrey Co-authored-by: Makram --- .changeset/eight-radios-hear.md | 5 + .mockery.yaml | 4 + LICENSE | 2 +- .../ccip/ccip_integration_tests/.gitignore | 1 + .../ccipreader/ccipreader_test.go | 411 +++++++ .../chainreader/Makefile | 12 + .../chainreader/chainreader_test.go | 273 +++++ .../chainreader/mycontract.go | 519 ++++++++ .../chainreader/mycontract.sol | 31 + .../ccip/ccip_integration_tests/helpers.go | 938 +++++++++++++++ .../ccip_integration_tests/home_chain_test.go | 103 ++ .../integrationhelpers/integration_helpers.go | 304 +++++ .../ccip_integration_tests/ocr3_node_test.go | 281 +++++ .../ccip_integration_tests/ocr_node_helper.go | 316 +++++ .../ccip_integration_tests/ping_pong_test.go | 95 ++ core/capabilities/ccip/ccipevm/commitcodec.go | 138 +++ .../ccip/ccipevm/commitcodec_test.go | 135 +++ .../capabilities/ccip/ccipevm/executecodec.go | 181 +++ .../ccip/ccipevm/executecodec_test.go | 174 +++ core/capabilities/ccip/ccipevm/helpers.go | 33 + .../capabilities/ccip/ccipevm/helpers_test.go | 41 + core/capabilities/ccip/ccipevm/msghasher.go | 127 ++ .../ccip/ccipevm/msghasher_test.go | 189 +++ core/capabilities/ccip/common/common.go | 23 + core/capabilities/ccip/common/common_test.go | 51 + .../ccip/configs/evm/chain_writer.go | 75 ++ .../ccip/configs/evm/contract_reader.go | 219 ++++ core/capabilities/ccip/delegate.go | 321 +++++ core/capabilities/ccip/delegate_test.go | 1 + core/capabilities/ccip/launcher/README.md | 69 ++ core/capabilities/ccip/launcher/bluegreen.go | 178 +++ .../ccip/launcher/bluegreen_test.go | 1043 +++++++++++++++++ .../launcher/ccip_capability_launcher.png | Bin 0 -> 253433 bytes .../launcher/ccip_config_state_machine.png | Bin 0 -> 96958 bytes core/capabilities/ccip/launcher/diff.go | 141 +++ core/capabilities/ccip/launcher/diff_test.go | 352 ++++++ .../ccip/launcher/integration_test.go | 120 ++ core/capabilities/ccip/launcher/launcher.go | 432 +++++++ .../ccip/launcher/launcher_test.go | 472 ++++++++ .../ccip/launcher/test_helpers.go | 56 + .../ccip/ocrimpls/config_digester.go | 23 + .../ccip/ocrimpls/config_tracker.go | 77 ++ .../ccip/ocrimpls/contract_transmitter.go | 188 +++ .../ocrimpls/contract_transmitter_test.go | 691 +++++++++++ core/capabilities/ccip/ocrimpls/keyring.go | 61 + .../ccip/oraclecreator/inprocess.go | 371 ++++++ .../ccip/oraclecreator/inprocess_test.go | 239 ++++ .../ccip/types/mocks/ccip_oracle.go | 122 ++ .../ccip/types/mocks/home_chain_reader.go | 129 ++ .../ccip/types/mocks/oracle_creator.go | 152 +++ core/capabilities/ccip/types/types.go | 46 + core/capabilities/ccip/validate/validate.go | 94 ++ .../ccip/validate/validate_test.go | 58 + core/capabilities/launcher.go | 56 +- core/capabilities/launcher_test.go | 29 +- core/capabilities/registry.go | 10 +- .../evm/client/simulated_backend_client.go | 13 +- core/scripts/go.mod | 5 +- core/scripts/go.sum | 10 +- core/services/chainlink/application.go | 87 +- core/services/job/models.go | 50 + core/services/job/orm.go | 64 +- core/services/pipeline/common.go | 1 + .../services/registrysyncer/local_registry.go | 19 +- core/services/registrysyncer/syncer.go | 57 +- core/services/registrysyncer/syncer_test.go | 44 +- core/services/synchronization/common.go | 4 + core/services/workflows/engine_test.go | 26 +- core/web/presenters/job.go | 23 + core/web/presenters/job_test.go | 98 +- go.md | 4 + go.mod | 5 +- go.sum | 10 +- integration-tests/go.mod | 5 +- integration-tests/go.sum | 10 +- integration-tests/load/go.mod | 5 +- integration-tests/load/go.sum | 10 +- 77 files changed, 10565 insertions(+), 197 deletions(-) create mode 100644 .changeset/eight-radios-hear.md create mode 100644 core/capabilities/ccip/ccip_integration_tests/.gitignore create mode 100644 core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go create mode 100644 core/capabilities/ccip/ccip_integration_tests/chainreader/Makefile create mode 100644 core/capabilities/ccip/ccip_integration_tests/chainreader/chainreader_test.go create mode 100644 core/capabilities/ccip/ccip_integration_tests/chainreader/mycontract.go create mode 100644 core/capabilities/ccip/ccip_integration_tests/chainreader/mycontract.sol create mode 100644 core/capabilities/ccip/ccip_integration_tests/helpers.go create mode 100644 core/capabilities/ccip/ccip_integration_tests/home_chain_test.go create mode 100644 core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go create mode 100644 core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go create mode 100644 core/capabilities/ccip/ccip_integration_tests/ocr_node_helper.go create mode 100644 core/capabilities/ccip/ccip_integration_tests/ping_pong_test.go create mode 100644 core/capabilities/ccip/ccipevm/commitcodec.go create mode 100644 core/capabilities/ccip/ccipevm/commitcodec_test.go create mode 100644 core/capabilities/ccip/ccipevm/executecodec.go create mode 100644 core/capabilities/ccip/ccipevm/executecodec_test.go create mode 100644 core/capabilities/ccip/ccipevm/helpers.go create mode 100644 core/capabilities/ccip/ccipevm/helpers_test.go create mode 100644 core/capabilities/ccip/ccipevm/msghasher.go create mode 100644 core/capabilities/ccip/ccipevm/msghasher_test.go create mode 100644 core/capabilities/ccip/common/common.go create mode 100644 core/capabilities/ccip/common/common_test.go create mode 100644 core/capabilities/ccip/configs/evm/chain_writer.go create mode 100644 core/capabilities/ccip/configs/evm/contract_reader.go create mode 100644 core/capabilities/ccip/delegate.go create mode 100644 core/capabilities/ccip/delegate_test.go create mode 100644 core/capabilities/ccip/launcher/README.md create mode 100644 core/capabilities/ccip/launcher/bluegreen.go create mode 100644 core/capabilities/ccip/launcher/bluegreen_test.go create mode 100644 core/capabilities/ccip/launcher/ccip_capability_launcher.png create mode 100644 core/capabilities/ccip/launcher/ccip_config_state_machine.png create mode 100644 core/capabilities/ccip/launcher/diff.go create mode 100644 core/capabilities/ccip/launcher/diff_test.go create mode 100644 core/capabilities/ccip/launcher/integration_test.go create mode 100644 core/capabilities/ccip/launcher/launcher.go create mode 100644 core/capabilities/ccip/launcher/launcher_test.go create mode 100644 core/capabilities/ccip/launcher/test_helpers.go create mode 100644 core/capabilities/ccip/ocrimpls/config_digester.go create mode 100644 core/capabilities/ccip/ocrimpls/config_tracker.go create mode 100644 core/capabilities/ccip/ocrimpls/contract_transmitter.go create mode 100644 core/capabilities/ccip/ocrimpls/contract_transmitter_test.go create mode 100644 core/capabilities/ccip/ocrimpls/keyring.go create mode 100644 core/capabilities/ccip/oraclecreator/inprocess.go create mode 100644 core/capabilities/ccip/oraclecreator/inprocess_test.go create mode 100644 core/capabilities/ccip/types/mocks/ccip_oracle.go create mode 100644 core/capabilities/ccip/types/mocks/home_chain_reader.go create mode 100644 core/capabilities/ccip/types/mocks/oracle_creator.go create mode 100644 core/capabilities/ccip/types/types.go create mode 100644 core/capabilities/ccip/validate/validate.go create mode 100644 core/capabilities/ccip/validate/validate_test.go diff --git a/.changeset/eight-radios-hear.md b/.changeset/eight-radios-hear.md new file mode 100644 index 0000000000..b422f37832 --- /dev/null +++ b/.changeset/eight-radios-hear.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#added merging core/capabilities/ccip from https://github.com/smartcontractkit/ccip diff --git a/.mockery.yaml b/.mockery.yaml index 8fab61a5b9..abb3105b13 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -43,6 +43,10 @@ packages: github.com/smartcontractkit/chainlink/v2/core/bridges: interfaces: ORM: + github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types: + interfaces: + CCIPOracle: + OracleCreator: github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types: interfaces: Dispatcher: diff --git a/LICENSE b/LICENSE index 4a10bfc38b..3af9faa6c6 100644 --- a/LICENSE +++ b/LICENSE @@ -24,7 +24,7 @@ THE SOFTWARE. *All content residing under (1) “/contracts/src/v0.8/ccip”; (2) -“/core/gethwrappers/ccip”; (3) “/core/services/ocr2/plugins/ccip” are licensed +“/core/gethwrappers/ccip”; (3) “/core/services/ocr2/plugins/ccip”; (4) "/core/capabilities/ccip" are licensed under “Business Source License 1.1” with a Change Date of May 23, 2027 and Change License to “MIT License” diff --git a/core/capabilities/ccip/ccip_integration_tests/.gitignore b/core/capabilities/ccip/ccip_integration_tests/.gitignore new file mode 100644 index 0000000000..567609b123 --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go new file mode 100644 index 0000000000..66c47f4741 --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go @@ -0,0 +1,411 @@ +package ccipreader + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + "golang.org/x/exp/maps" + + "github.com/smartcontractkit/chainlink-common/pkg/types" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_reader_tester" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" + + "github.com/smartcontractkit/chainlink-ccip/pkg/consts" + "github.com/smartcontractkit/chainlink-ccip/pkg/contractreader" + ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + "github.com/smartcontractkit/chainlink-ccip/plugintypes" +) + +const ( + chainS1 = cciptypes.ChainSelector(1) + chainS2 = cciptypes.ChainSelector(2) + chainS3 = cciptypes.ChainSelector(3) + chainD = cciptypes.ChainSelector(4) +) + +func TestCCIPReader_CommitReportsGTETimestamp(t *testing.T) { + ctx := testutils.Context(t) + + cfg := evmtypes.ChainReaderConfig{ + Contracts: map[string]evmtypes.ChainContractReader{ + consts.ContractNameOffRamp: { + ContractPollingFilter: evmtypes.ContractPollingFilter{ + GenericEventNames: []string{consts.EventNameCommitReportAccepted}, + }, + ContractABI: ccip_reader_tester.CCIPReaderTesterABI, + Configs: map[string]*evmtypes.ChainReaderDefinition{ + consts.EventNameCommitReportAccepted: { + ChainSpecificName: consts.EventNameCommitReportAccepted, + ReadType: evmtypes.Event, + }, + }, + }, + }, + } + + s := testSetup(ctx, t, chainD, chainD, nil, cfg) + + tokenA := common.HexToAddress("123") + const numReports = 5 + + for i := uint8(0); i < numReports; i++ { + _, err := s.contract.EmitCommitReportAccepted(s.auth, ccip_reader_tester.EVM2EVMMultiOffRampCommitReport{ + PriceUpdates: ccip_reader_tester.InternalPriceUpdates{ + TokenPriceUpdates: []ccip_reader_tester.InternalTokenPriceUpdate{ + { + SourceToken: tokenA, + UsdPerToken: big.NewInt(1000), + }, + }, + GasPriceUpdates: []ccip_reader_tester.InternalGasPriceUpdate{ + { + DestChainSelector: uint64(chainD), + UsdPerUnitGas: big.NewInt(90), + }, + }, + }, + MerkleRoots: []ccip_reader_tester.EVM2EVMMultiOffRampMerkleRoot{ + { + SourceChainSelector: uint64(chainS1), + Interval: ccip_reader_tester.EVM2EVMMultiOffRampInterval{ + Min: 10, + Max: 20, + }, + MerkleRoot: [32]byte{i + 1}, + }, + }, + }) + assert.NoError(t, err) + s.sb.Commit() + } + + var reports []plugintypes.CommitPluginReportWithMeta + var err error + require.Eventually(t, func() bool { + reports, err = s.reader.CommitReportsGTETimestamp( + ctx, + chainD, + time.Unix(30, 0), // Skips first report, simulated backend report timestamps are [20, 30, 40, ...] + 10, + ) + require.NoError(t, err) + return len(reports) == numReports-1 + }, testutils.WaitTimeout(t), 50*time.Millisecond) + + assert.Len(t, reports[0].Report.MerkleRoots, 1) + assert.Equal(t, chainS1, reports[0].Report.MerkleRoots[0].ChainSel) + assert.Equal(t, cciptypes.SeqNum(10), reports[0].Report.MerkleRoots[0].SeqNumsRange.Start()) + assert.Equal(t, cciptypes.SeqNum(20), reports[0].Report.MerkleRoots[0].SeqNumsRange.End()) + assert.Equal(t, "0x0200000000000000000000000000000000000000000000000000000000000000", + reports[0].Report.MerkleRoots[0].MerkleRoot.String()) + + assert.Equal(t, tokenA.String(), string(reports[0].Report.PriceUpdates.TokenPriceUpdates[0].TokenID)) + assert.Equal(t, uint64(1000), reports[0].Report.PriceUpdates.TokenPriceUpdates[0].Price.Uint64()) + + assert.Equal(t, chainD, reports[0].Report.PriceUpdates.GasPriceUpdates[0].ChainSel) + assert.Equal(t, uint64(90), reports[0].Report.PriceUpdates.GasPriceUpdates[0].GasPrice.Uint64()) +} + +func TestCCIPReader_ExecutedMessageRanges(t *testing.T) { + ctx := testutils.Context(t) + cfg := evmtypes.ChainReaderConfig{ + Contracts: map[string]evmtypes.ChainContractReader{ + consts.ContractNameOffRamp: { + ContractPollingFilter: evmtypes.ContractPollingFilter{ + GenericEventNames: []string{consts.EventNameExecutionStateChanged}, + }, + ContractABI: ccip_reader_tester.CCIPReaderTesterABI, + Configs: map[string]*evmtypes.ChainReaderDefinition{ + consts.EventNameExecutionStateChanged: { + ChainSpecificName: consts.EventNameExecutionStateChanged, + ReadType: evmtypes.Event, + }, + }, + }, + }, + } + + s := testSetup(ctx, t, chainD, chainD, nil, cfg) + + _, err := s.contract.EmitExecutionStateChanged( + s.auth, + uint64(chainS1), + 14, + cciptypes.Bytes32{1, 0, 0, 1}, + 1, + []byte{1, 2, 3, 4}, + ) + assert.NoError(t, err) + s.sb.Commit() + + _, err = s.contract.EmitExecutionStateChanged( + s.auth, + uint64(chainS1), + 15, + cciptypes.Bytes32{1, 0, 0, 2}, + 1, + []byte{1, 2, 3, 4, 5}, + ) + assert.NoError(t, err) + s.sb.Commit() + + // Need to replay as sometimes the logs are not picked up by the log poller (?) + // Maybe another situation where chain reader doesn't register filters as expected. + require.NoError(t, s.lp.Replay(ctx, 1)) + + var executedRanges []cciptypes.SeqNumRange + require.Eventually(t, func() bool { + executedRanges, err = s.reader.ExecutedMessageRanges( + ctx, + chainS1, + chainD, + cciptypes.NewSeqNumRange(14, 15), + ) + require.NoError(t, err) + return len(executedRanges) == 2 + }, testutils.WaitTimeout(t), 50*time.Millisecond) + + assert.Equal(t, cciptypes.SeqNum(14), executedRanges[0].Start()) + assert.Equal(t, cciptypes.SeqNum(14), executedRanges[0].End()) + + assert.Equal(t, cciptypes.SeqNum(15), executedRanges[1].Start()) + assert.Equal(t, cciptypes.SeqNum(15), executedRanges[1].End()) +} + +func TestCCIPReader_MsgsBetweenSeqNums(t *testing.T) { + ctx := testutils.Context(t) + + cfg := evmtypes.ChainReaderConfig{ + Contracts: map[string]evmtypes.ChainContractReader{ + consts.ContractNameOnRamp: { + ContractPollingFilter: evmtypes.ContractPollingFilter{ + GenericEventNames: []string{consts.EventNameCCIPSendRequested}, + }, + ContractABI: ccip_reader_tester.CCIPReaderTesterABI, + Configs: map[string]*evmtypes.ChainReaderDefinition{ + consts.EventNameCCIPSendRequested: { + ChainSpecificName: consts.EventNameCCIPSendRequested, + ReadType: evmtypes.Event, + }, + }, + }, + }, + } + + s := testSetup(ctx, t, chainS1, chainD, nil, cfg) + + _, err := s.contract.EmitCCIPSendRequested(s.auth, uint64(chainD), ccip_reader_tester.InternalEVM2AnyRampMessage{ + Header: ccip_reader_tester.InternalRampMessageHeader{ + MessageId: [32]byte{1, 0, 0, 0, 0}, + SourceChainSelector: uint64(chainS1), + DestChainSelector: uint64(chainD), + SequenceNumber: 10, + }, + Sender: utils.RandomAddress(), + Data: make([]byte, 0), + Receiver: utils.RandomAddress().Bytes(), + ExtraArgs: make([]byte, 0), + FeeToken: utils.RandomAddress(), + FeeTokenAmount: big.NewInt(0), + TokenAmounts: make([]ccip_reader_tester.InternalRampTokenAmount, 0), + }) + assert.NoError(t, err) + + _, err = s.contract.EmitCCIPSendRequested(s.auth, uint64(chainD), ccip_reader_tester.InternalEVM2AnyRampMessage{ + Header: ccip_reader_tester.InternalRampMessageHeader{ + MessageId: [32]byte{1, 0, 0, 0, 1}, + SourceChainSelector: uint64(chainS1), + DestChainSelector: uint64(chainD), + SequenceNumber: 15, + }, + Sender: utils.RandomAddress(), + Data: make([]byte, 0), + Receiver: utils.RandomAddress().Bytes(), + ExtraArgs: make([]byte, 0), + FeeToken: utils.RandomAddress(), + FeeTokenAmount: big.NewInt(0), + TokenAmounts: make([]ccip_reader_tester.InternalRampTokenAmount, 0), + }) + assert.NoError(t, err) + + s.sb.Commit() + + var msgs []cciptypes.Message + require.Eventually(t, func() bool { + msgs, err = s.reader.MsgsBetweenSeqNums( + ctx, + chainS1, + cciptypes.NewSeqNumRange(5, 20), + ) + require.NoError(t, err) + return len(msgs) == 2 + }, 10*time.Second, 100*time.Millisecond) + + require.Len(t, msgs, 2) + require.Equal(t, cciptypes.SeqNum(10), msgs[0].Header.SequenceNumber) + require.Equal(t, cciptypes.SeqNum(15), msgs[1].Header.SequenceNumber) + for _, msg := range msgs { + require.Equal(t, chainS1, msg.Header.SourceChainSelector) + require.Equal(t, chainD, msg.Header.DestChainSelector) + } +} + +func TestCCIPReader_NextSeqNum(t *testing.T) { + ctx := testutils.Context(t) + + onChainSeqNums := map[cciptypes.ChainSelector]cciptypes.SeqNum{ + chainS1: 10, + chainS2: 20, + chainS3: 30, + } + + cfg := evmtypes.ChainReaderConfig{ + Contracts: map[string]evmtypes.ChainContractReader{ + consts.ContractNameOffRamp: { + ContractABI: ccip_reader_tester.CCIPReaderTesterABI, + Configs: map[string]*evmtypes.ChainReaderDefinition{ + consts.MethodNameGetSourceChainConfig: { + ChainSpecificName: "getSourceChainConfig", + ReadType: evmtypes.Method, + }, + }, + }, + }, + } + + s := testSetup(ctx, t, chainD, chainD, onChainSeqNums, cfg) + + seqNums, err := s.reader.NextSeqNum(ctx, []cciptypes.ChainSelector{chainS1, chainS2, chainS3}) + assert.NoError(t, err) + assert.Len(t, seqNums, 3) + assert.Equal(t, cciptypes.SeqNum(10), seqNums[0]) + assert.Equal(t, cciptypes.SeqNum(20), seqNums[1]) + assert.Equal(t, cciptypes.SeqNum(30), seqNums[2]) +} + +func testSetup(ctx context.Context, t *testing.T, readerChain, destChain cciptypes.ChainSelector, onChainSeqNums map[cciptypes.ChainSelector]cciptypes.SeqNum, cfg evmtypes.ChainReaderConfig) *testSetupData { + const chainID = 1337 + + // Generate a new key pair for the simulated account + privateKey, err := crypto.GenerateKey() + assert.NoError(t, err) + // Set up the genesis account with balance + blnc, ok := big.NewInt(0).SetString("999999999999999999999999999999999999", 10) + assert.True(t, ok) + alloc := map[common.Address]core.GenesisAccount{crypto.PubkeyToAddress(privateKey.PublicKey): {Balance: blnc}} + simulatedBackend := backends.NewSimulatedBackend(alloc, 0) + // Create a transactor + + auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(chainID)) + assert.NoError(t, err) + auth.GasLimit = uint64(0) + + // Deploy the contract + address, _, _, err := ccip_reader_tester.DeployCCIPReaderTester(auth, simulatedBackend) + assert.NoError(t, err) + simulatedBackend.Commit() + + // Setup contract client + contract, err := ccip_reader_tester.NewCCIPReaderTester(address, simulatedBackend) + assert.NoError(t, err) + + lggr := logger.TestLogger(t) + lggr.SetLogLevel(zapcore.ErrorLevel) + db := pgtest.NewSqlxDB(t) + lpOpts := logpoller.Opts{ + PollPeriod: time.Millisecond, + FinalityDepth: 0, + BackfillBatchSize: 10, + RpcBatchSize: 10, + KeepFinalizedBlocksDepth: 100000, + } + cl := client.NewSimulatedBackendClient(t, simulatedBackend, big.NewInt(0).SetUint64(uint64(readerChain))) + headTracker := headtracker.NewSimulatedHeadTracker(cl, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + lp := logpoller.NewLogPoller(logpoller.NewORM(big.NewInt(0).SetUint64(uint64(readerChain)), db, lggr), + cl, + lggr, + headTracker, + lpOpts, + ) + assert.NoError(t, lp.Start(ctx)) + + for sourceChain, seqNum := range onChainSeqNums { + _, err1 := contract.SetSourceChainConfig(auth, uint64(sourceChain), ccip_reader_tester.EVM2EVMMultiOffRampSourceChainConfig{ + IsEnabled: true, + MinSeqNr: uint64(seqNum), + }) + assert.NoError(t, err1) + simulatedBackend.Commit() + scc, err1 := contract.GetSourceChainConfig(&bind.CallOpts{Context: ctx}, uint64(sourceChain)) + assert.NoError(t, err1) + assert.Equal(t, seqNum, cciptypes.SeqNum(scc.MinSeqNr)) + } + + contractNames := maps.Keys(cfg.Contracts) + assert.Len(t, contractNames, 1, "test setup assumes there is only one contract") + + cr, err := evm.NewChainReaderService(ctx, lggr, lp, headTracker, cl, cfg) + require.NoError(t, err) + + extendedCr := contractreader.NewExtendedContractReader(cr) + err = extendedCr.Bind(ctx, []types.BoundContract{ + { + Address: address.String(), + Name: contractNames[0], + }, + }) + require.NoError(t, err) + + err = cr.Start(ctx) + require.NoError(t, err) + + contractReaders := map[cciptypes.ChainSelector]contractreader.Extended{readerChain: extendedCr} + contractWriters := make(map[cciptypes.ChainSelector]types.ChainWriter) + reader := ccipreaderpkg.NewCCIPReaderWithExtendedContractReaders(lggr, contractReaders, contractWriters, destChain) + + t.Cleanup(func() { + require.NoError(t, cr.Close()) + require.NoError(t, lp.Close()) + require.NoError(t, db.Close()) + }) + + return &testSetupData{ + contractAddr: address, + contract: contract, + sb: simulatedBackend, + auth: auth, + lp: lp, + cl: cl, + reader: reader, + } +} + +type testSetupData struct { + contractAddr common.Address + contract *ccip_reader_tester.CCIPReaderTester + sb *backends.SimulatedBackend + auth *bind.TransactOpts + lp logpoller.LogPoller + cl client.Client + reader ccipreaderpkg.CCIPReader +} diff --git a/core/capabilities/ccip/ccip_integration_tests/chainreader/Makefile b/core/capabilities/ccip/ccip_integration_tests/chainreader/Makefile new file mode 100644 index 0000000000..e9c88564e6 --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/chainreader/Makefile @@ -0,0 +1,12 @@ + +# IMPORTANT: If you encounter any issues try using solc 0.8.18 and abigen 1.14.5 + +.PHONY: build +build: + rm -rf build/ + solc --evm-version paris --abi --bin mycontract.sol -o build + abigen --abi build/mycontract_sol_SimpleContract.abi --bin build/mycontract_sol_SimpleContract.bin --pkg=chainreader --out=mycontract.go + +.PHONY: test +test: build + go test -v --tags "playground" ./... diff --git a/core/capabilities/ccip/ccip_integration_tests/chainreader/chainreader_test.go b/core/capabilities/ccip/ccip_integration_tests/chainreader/chainreader_test.go new file mode 100644 index 0000000000..52a3de0dae --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/chainreader/chainreader_test.go @@ -0,0 +1,273 @@ +//go:build playground +// +build playground + +package chainreader + +import ( + "context" + _ "embed" + "math/big" + "strconv" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink-common/pkg/codec" + types2 "github.com/smartcontractkit/chainlink-common/pkg/types" + query2 "github.com/smartcontractkit/chainlink-common/pkg/types/query" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + logger2 "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" +) + +const chainID = 1337 + +type testSetupData struct { + contractAddr common.Address + contract *Chainreader + sb *backends.SimulatedBackend + auth *bind.TransactOpts +} + +func TestChainReader(t *testing.T) { + ctx := testutils.Context(t) + lggr := logger2.NullLogger + d := testSetup(t, ctx) + + db := pgtest.NewSqlxDB(t) + lpOpts := logpoller.Opts{ + PollPeriod: time.Millisecond, + FinalityDepth: 0, + BackfillBatchSize: 10, + RpcBatchSize: 10, + KeepFinalizedBlocksDepth: 100000, + } + cl := client.NewSimulatedBackendClient(t, d.sb, big.NewInt(chainID)) + headTracker := headtracker.NewSimulatedHeadTracker(cl, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + lp := logpoller.NewLogPoller(logpoller.NewORM(big.NewInt(chainID), db, lggr), + cl, + lggr, + headTracker, + lpOpts, + ) + assert.NoError(t, lp.Start(ctx)) + + const ( + ContractNameAlias = "myCoolContract" + + FnAliasGetCount = "myCoolFunction" + FnGetCount = "getEventCount" + + FnAliasGetNumbers = "GetNumbers" + FnGetNumbers = "getNumbers" + + FnAliasGetPerson = "GetPerson" + FnGetPerson = "getPerson" + + EventNameAlias = "myCoolEvent" + EventName = "SimpleEvent" + ) + + // Initialize chainReader + cfg := evmtypes.ChainReaderConfig{ + Contracts: map[string]evmtypes.ChainContractReader{ + ContractNameAlias: { + ContractPollingFilter: evmtypes.ContractPollingFilter{ + GenericEventNames: []string{EventNameAlias}, + }, + ContractABI: ChainreaderMetaData.ABI, + Configs: map[string]*evmtypes.ChainReaderDefinition{ + EventNameAlias: { + ChainSpecificName: EventName, + ReadType: evmtypes.Event, + ConfidenceConfirmations: map[string]int{"0.0": 0, "1.0": 0}, + }, + FnAliasGetCount: { + ChainSpecificName: FnGetCount, + }, + FnAliasGetNumbers: { + ChainSpecificName: FnGetNumbers, + OutputModifications: codec.ModifiersConfig{}, + }, + FnAliasGetPerson: { + ChainSpecificName: FnGetPerson, + OutputModifications: codec.ModifiersConfig{ + &codec.RenameModifierConfig{ + Fields: map[string]string{"Name": "NameField"}, // solidity name -> go struct name + }, + }, + }, + }, + }, + }, + } + + cr, err := evm.NewChainReaderService(ctx, lggr, lp, cl, cfg) + assert.NoError(t, err) + err = cr.Bind(ctx, []types2.BoundContract{ + { + Address: d.contractAddr.String(), + Name: ContractNameAlias, + Pending: false, + }, + }) + assert.NoError(t, err) + + err = cr.Start(ctx) + assert.NoError(t, err) + for { + if err := cr.Ready(); err == nil { + break + } + } + + emitEvents(t, d, ctx) // Calls the contract to emit events + + // (hack) Sometimes LP logs are missing, commit several times and wait few seconds to make it work. + for i := 0; i < 100; i++ { + d.sb.Commit() + } + time.Sleep(5 * time.Second) + + t.Run("simple contract read", func(t *testing.T) { + var cnt big.Int + err = cr.GetLatestValue(ctx, ContractNameAlias, FnAliasGetCount, map[string]interface{}{}, &cnt) + assert.NoError(t, err) + assert.Equal(t, int64(10), cnt.Int64()) + }) + + t.Run("read array", func(t *testing.T) { + var nums []big.Int + err = cr.GetLatestValue(ctx, ContractNameAlias, FnAliasGetNumbers, map[string]interface{}{}, &nums) + assert.NoError(t, err) + assert.Len(t, nums, 10) + for i := 1; i <= 10; i++ { + assert.Equal(t, int64(i), nums[i-1].Int64()) + } + }) + + t.Run("read struct", func(t *testing.T) { + person := struct { + NameField string + Age *big.Int // WARN: specifying a wrong data type e.g. int instead of *big.Int fails silently with a default value of 0 + }{} + err = cr.GetLatestValue(ctx, ContractNameAlias, FnAliasGetPerson, map[string]interface{}{}, &person) + assert.Equal(t, "Dim", person.NameField) + assert.Equal(t, int64(18), person.Age.Int64()) + }) + + t.Run("read events", func(t *testing.T) { + var myDataType *big.Int + seq, err := cr.QueryKey( + ctx, + ContractNameAlias, + query2.KeyFilter{ + Key: EventNameAlias, + Expressions: []query2.Expression{}, + }, + query2.LimitAndSort{}, + myDataType, + ) + assert.NoError(t, err) + assert.Equal(t, 10, len(seq), "expected 10 events from chain reader") + for _, v := range seq { + // TODO: for some reason log poller does not populate event data + blockNum, err := strconv.ParseUint(v.Identifier, 10, 64) + assert.NoError(t, err) + assert.Positive(t, blockNum) + t.Logf("(chain reader) got event: (data=%v) (hash=%x)", v.Data, v.Hash) + } + }) +} + +func testSetup(t *testing.T, ctx context.Context) *testSetupData { + // Generate a new key pair for the simulated account + privateKey, err := crypto.GenerateKey() + assert.NoError(t, err) + // Set up the genesis account with balance + blnc, ok := big.NewInt(0).SetString("999999999999999999999999999999999999", 10) + assert.True(t, ok) + alloc := map[common.Address]core.GenesisAccount{crypto.PubkeyToAddress(privateKey.PublicKey): {Balance: blnc}} + simulatedBackend := backends.NewSimulatedBackend(alloc, 0) + // Create a transactor + + auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(chainID)) + assert.NoError(t, err) + auth.GasLimit = uint64(0) + + // Deploy the contract + address, tx, _, err := DeployChainreader(auth, simulatedBackend) + assert.NoError(t, err) + simulatedBackend.Commit() + t.Logf("contract deployed: addr=%s tx=%s", address.Hex(), tx.Hash()) + + // Setup contract client + contract, err := NewChainreader(address, simulatedBackend) + assert.NoError(t, err) + + return &testSetupData{ + contractAddr: address, + contract: contract, + sb: simulatedBackend, + auth: auth, + } +} + +func emitEvents(t *testing.T, d *testSetupData, ctx context.Context) { + var wg sync.WaitGroup + wg.Add(2) + + // Start emitting events + go func() { + defer wg.Done() + for i := 0; i < 10; i++ { + _, err := d.contract.EmitEvent(d.auth) + assert.NoError(t, err) + d.sb.Commit() + } + }() + + // Listen events using go-ethereum lib + go func() { + query := ethereum.FilterQuery{ + FromBlock: big.NewInt(0), + Addresses: []common.Address{d.contractAddr}, + } + logs := make(chan types.Log) + sub, err := d.sb.SubscribeFilterLogs(ctx, query, logs) + assert.NoError(t, err) + + numLogs := 0 + defer wg.Done() + for { + // Wait for the events + select { + case err := <-sub.Err(): + assert.NoError(t, err, "got an unexpected error") + case vLog := <-logs: + assert.Equal(t, d.contractAddr, vLog.Address, "got an unexpected address") + t.Logf("(geth) got new log (cnt=%d) (data=%x) (topics=%s)", numLogs, vLog.Data, vLog.Topics) + numLogs++ + if numLogs == 10 { + return + } + } + } + }() + + wg.Wait() // wait for all the events to be consumed +} diff --git a/core/capabilities/ccip/ccip_integration_tests/chainreader/mycontract.go b/core/capabilities/ccip/ccip_integration_tests/chainreader/mycontract.go new file mode 100644 index 0000000000..c7d480eed4 --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/chainreader/mycontract.go @@ -0,0 +1,519 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package chainreader + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// SimpleContractPerson is an auto generated low-level Go binding around an user-defined struct. +type SimpleContractPerson struct { + Name string + Age *big.Int +} + +// ChainreaderMetaData contains all meta data concerning the Chainreader contract. +var ChainreaderMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SimpleEvent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"emitEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eventCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getEventCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNumbers\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerson\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"age\",\"type\":\"uint256\"}],\"internalType\":\"structSimpleContract.Person\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"numbers\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506105a1806100206000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c806371be2e4a146100675780637b0cb8391461008557806389f915f61461008f5780638ec4dc95146100ad578063d39fa233146100cb578063d9e48f5c146100fb575b600080fd5b61006f610119565b60405161007c91906102ac565b60405180910390f35b61008d61011f565b005b61009761019c565b6040516100a49190610385565b60405180910390f35b6100b56101f4565b6040516100c29190610474565b60405180910390f35b6100e560048036038101906100e091906104c7565b61024c565b6040516100f291906102ac565b60405180910390f35b610103610270565b60405161011091906102ac565b60405180910390f35b60005481565b60008081548092919061013190610523565b9190505550600160005490806001815401808255809150506001900390600052602060002001600090919091909150557f12d199749b3f4c44df8d9386c63d725b7756ec47204f3aa0bf05ea832f89effb60005460405161019291906102ac565b60405180910390a1565b606060018054806020026020016040519081016040528092919081815260200182805480156101ea57602002820191906000526020600020905b8154815260200190600101908083116101d6575b5050505050905090565b6101fc610279565b60405180604001604052806040518060400160405280600381526020017f44696d000000000000000000000000000000000000000000000000000000000081525081526020016012815250905090565b6001818154811061025c57600080fd5b906000526020600020016000915090505481565b60008054905090565b604051806040016040528060608152602001600081525090565b6000819050919050565b6102a681610293565b82525050565b60006020820190506102c1600083018461029d565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6102fc81610293565b82525050565b600061030e83836102f3565b60208301905092915050565b6000602082019050919050565b6000610332826102c7565b61033c81856102d2565b9350610347836102e3565b8060005b8381101561037857815161035f8882610302565b975061036a8361031a565b92505060018101905061034b565b5085935050505092915050565b6000602082019050818103600083015261039f8184610327565b905092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156103e15780820151818401526020810190506103c6565b60008484015250505050565b6000601f19601f8301169050919050565b6000610409826103a7565b61041381856103b2565b93506104238185602086016103c3565b61042c816103ed565b840191505092915050565b6000604083016000830151848203600086015261045482826103fe565b915050602083015161046960208601826102f3565b508091505092915050565b6000602082019050818103600083015261048e8184610437565b905092915050565b600080fd5b6104a481610293565b81146104af57600080fd5b50565b6000813590506104c18161049b565b92915050565b6000602082840312156104dd576104dc610496565b5b60006104eb848285016104b2565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061052e82610293565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036105605761055f6104f4565b5b60018201905091905056fea2646970667358221220f7986dc9efbc0d9ef58e2925ffddc62ea13a6bab8b3a2c03ad2d85d50653129664736f6c63430008120033", +} + +// ChainreaderABI is the input ABI used to generate the binding from. +// Deprecated: Use ChainreaderMetaData.ABI instead. +var ChainreaderABI = ChainreaderMetaData.ABI + +// ChainreaderBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ChainreaderMetaData.Bin instead. +var ChainreaderBin = ChainreaderMetaData.Bin + +// DeployChainreader deploys a new Ethereum contract, binding an instance of Chainreader to it. +func DeployChainreader(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Chainreader, error) { + parsed, err := ChainreaderMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ChainreaderBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Chainreader{ChainreaderCaller: ChainreaderCaller{contract: contract}, ChainreaderTransactor: ChainreaderTransactor{contract: contract}, ChainreaderFilterer: ChainreaderFilterer{contract: contract}}, nil +} + +// Chainreader is an auto generated Go binding around an Ethereum contract. +type Chainreader struct { + ChainreaderCaller // Read-only binding to the contract + ChainreaderTransactor // Write-only binding to the contract + ChainreaderFilterer // Log filterer for contract events +} + +// ChainreaderCaller is an auto generated read-only Go binding around an Ethereum contract. +type ChainreaderCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ChainreaderTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ChainreaderTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ChainreaderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ChainreaderFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ChainreaderSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ChainreaderSession struct { + Contract *Chainreader // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ChainreaderCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ChainreaderCallerSession struct { + Contract *ChainreaderCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ChainreaderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ChainreaderTransactorSession struct { + Contract *ChainreaderTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ChainreaderRaw is an auto generated low-level Go binding around an Ethereum contract. +type ChainreaderRaw struct { + Contract *Chainreader // Generic contract binding to access the raw methods on +} + +// ChainreaderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ChainreaderCallerRaw struct { + Contract *ChainreaderCaller // Generic read-only contract binding to access the raw methods on +} + +// ChainreaderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ChainreaderTransactorRaw struct { + Contract *ChainreaderTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewChainreader creates a new instance of Chainreader, bound to a specific deployed contract. +func NewChainreader(address common.Address, backend bind.ContractBackend) (*Chainreader, error) { + contract, err := bindChainreader(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Chainreader{ChainreaderCaller: ChainreaderCaller{contract: contract}, ChainreaderTransactor: ChainreaderTransactor{contract: contract}, ChainreaderFilterer: ChainreaderFilterer{contract: contract}}, nil +} + +// NewChainreaderCaller creates a new read-only instance of Chainreader, bound to a specific deployed contract. +func NewChainreaderCaller(address common.Address, caller bind.ContractCaller) (*ChainreaderCaller, error) { + contract, err := bindChainreader(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ChainreaderCaller{contract: contract}, nil +} + +// NewChainreaderTransactor creates a new write-only instance of Chainreader, bound to a specific deployed contract. +func NewChainreaderTransactor(address common.Address, transactor bind.ContractTransactor) (*ChainreaderTransactor, error) { + contract, err := bindChainreader(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ChainreaderTransactor{contract: contract}, nil +} + +// NewChainreaderFilterer creates a new log filterer instance of Chainreader, bound to a specific deployed contract. +func NewChainreaderFilterer(address common.Address, filterer bind.ContractFilterer) (*ChainreaderFilterer, error) { + contract, err := bindChainreader(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ChainreaderFilterer{contract: contract}, nil +} + +// bindChainreader binds a generic wrapper to an already deployed contract. +func bindChainreader(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ChainreaderMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Chainreader *ChainreaderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Chainreader.Contract.ChainreaderCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Chainreader *ChainreaderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Chainreader.Contract.ChainreaderTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Chainreader *ChainreaderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Chainreader.Contract.ChainreaderTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Chainreader *ChainreaderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Chainreader.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Chainreader *ChainreaderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Chainreader.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Chainreader *ChainreaderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Chainreader.Contract.contract.Transact(opts, method, params...) +} + +// EventCount is a free data retrieval call binding the contract method 0x71be2e4a. +// +// Solidity: function eventCount() view returns(uint256) +func (_Chainreader *ChainreaderCaller) EventCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Chainreader.contract.Call(opts, &out, "eventCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// EventCount is a free data retrieval call binding the contract method 0x71be2e4a. +// +// Solidity: function eventCount() view returns(uint256) +func (_Chainreader *ChainreaderSession) EventCount() (*big.Int, error) { + return _Chainreader.Contract.EventCount(&_Chainreader.CallOpts) +} + +// EventCount is a free data retrieval call binding the contract method 0x71be2e4a. +// +// Solidity: function eventCount() view returns(uint256) +func (_Chainreader *ChainreaderCallerSession) EventCount() (*big.Int, error) { + return _Chainreader.Contract.EventCount(&_Chainreader.CallOpts) +} + +// GetEventCount is a free data retrieval call binding the contract method 0xd9e48f5c. +// +// Solidity: function getEventCount() view returns(uint256) +func (_Chainreader *ChainreaderCaller) GetEventCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Chainreader.contract.Call(opts, &out, "getEventCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetEventCount is a free data retrieval call binding the contract method 0xd9e48f5c. +// +// Solidity: function getEventCount() view returns(uint256) +func (_Chainreader *ChainreaderSession) GetEventCount() (*big.Int, error) { + return _Chainreader.Contract.GetEventCount(&_Chainreader.CallOpts) +} + +// GetEventCount is a free data retrieval call binding the contract method 0xd9e48f5c. +// +// Solidity: function getEventCount() view returns(uint256) +func (_Chainreader *ChainreaderCallerSession) GetEventCount() (*big.Int, error) { + return _Chainreader.Contract.GetEventCount(&_Chainreader.CallOpts) +} + +// GetNumbers is a free data retrieval call binding the contract method 0x89f915f6. +// +// Solidity: function getNumbers() view returns(uint256[]) +func (_Chainreader *ChainreaderCaller) GetNumbers(opts *bind.CallOpts) ([]*big.Int, error) { + var out []interface{} + err := _Chainreader.contract.Call(opts, &out, "getNumbers") + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +// GetNumbers is a free data retrieval call binding the contract method 0x89f915f6. +// +// Solidity: function getNumbers() view returns(uint256[]) +func (_Chainreader *ChainreaderSession) GetNumbers() ([]*big.Int, error) { + return _Chainreader.Contract.GetNumbers(&_Chainreader.CallOpts) +} + +// GetNumbers is a free data retrieval call binding the contract method 0x89f915f6. +// +// Solidity: function getNumbers() view returns(uint256[]) +func (_Chainreader *ChainreaderCallerSession) GetNumbers() ([]*big.Int, error) { + return _Chainreader.Contract.GetNumbers(&_Chainreader.CallOpts) +} + +// GetPerson is a free data retrieval call binding the contract method 0x8ec4dc95. +// +// Solidity: function getPerson() pure returns((string,uint256)) +func (_Chainreader *ChainreaderCaller) GetPerson(opts *bind.CallOpts) (SimpleContractPerson, error) { + var out []interface{} + err := _Chainreader.contract.Call(opts, &out, "getPerson") + + if err != nil { + return *new(SimpleContractPerson), err + } + + out0 := *abi.ConvertType(out[0], new(SimpleContractPerson)).(*SimpleContractPerson) + + return out0, err + +} + +// GetPerson is a free data retrieval call binding the contract method 0x8ec4dc95. +// +// Solidity: function getPerson() pure returns((string,uint256)) +func (_Chainreader *ChainreaderSession) GetPerson() (SimpleContractPerson, error) { + return _Chainreader.Contract.GetPerson(&_Chainreader.CallOpts) +} + +// GetPerson is a free data retrieval call binding the contract method 0x8ec4dc95. +// +// Solidity: function getPerson() pure returns((string,uint256)) +func (_Chainreader *ChainreaderCallerSession) GetPerson() (SimpleContractPerson, error) { + return _Chainreader.Contract.GetPerson(&_Chainreader.CallOpts) +} + +// Numbers is a free data retrieval call binding the contract method 0xd39fa233. +// +// Solidity: function numbers(uint256 ) view returns(uint256) +func (_Chainreader *ChainreaderCaller) Numbers(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _Chainreader.contract.Call(opts, &out, "numbers", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Numbers is a free data retrieval call binding the contract method 0xd39fa233. +// +// Solidity: function numbers(uint256 ) view returns(uint256) +func (_Chainreader *ChainreaderSession) Numbers(arg0 *big.Int) (*big.Int, error) { + return _Chainreader.Contract.Numbers(&_Chainreader.CallOpts, arg0) +} + +// Numbers is a free data retrieval call binding the contract method 0xd39fa233. +// +// Solidity: function numbers(uint256 ) view returns(uint256) +func (_Chainreader *ChainreaderCallerSession) Numbers(arg0 *big.Int) (*big.Int, error) { + return _Chainreader.Contract.Numbers(&_Chainreader.CallOpts, arg0) +} + +// EmitEvent is a paid mutator transaction binding the contract method 0x7b0cb839. +// +// Solidity: function emitEvent() returns() +func (_Chainreader *ChainreaderTransactor) EmitEvent(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Chainreader.contract.Transact(opts, "emitEvent") +} + +// EmitEvent is a paid mutator transaction binding the contract method 0x7b0cb839. +// +// Solidity: function emitEvent() returns() +func (_Chainreader *ChainreaderSession) EmitEvent() (*types.Transaction, error) { + return _Chainreader.Contract.EmitEvent(&_Chainreader.TransactOpts) +} + +// EmitEvent is a paid mutator transaction binding the contract method 0x7b0cb839. +// +// Solidity: function emitEvent() returns() +func (_Chainreader *ChainreaderTransactorSession) EmitEvent() (*types.Transaction, error) { + return _Chainreader.Contract.EmitEvent(&_Chainreader.TransactOpts) +} + +// ChainreaderSimpleEventIterator is returned from FilterSimpleEvent and is used to iterate over the raw logs and unpacked data for SimpleEvent events raised by the Chainreader contract. +type ChainreaderSimpleEventIterator struct { + Event *ChainreaderSimpleEvent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ChainreaderSimpleEventIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ChainreaderSimpleEvent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ChainreaderSimpleEvent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ChainreaderSimpleEventIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ChainreaderSimpleEventIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ChainreaderSimpleEvent represents a SimpleEvent event raised by the Chainreader contract. +type ChainreaderSimpleEvent struct { + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSimpleEvent is a free log retrieval operation binding the contract event 0x12d199749b3f4c44df8d9386c63d725b7756ec47204f3aa0bf05ea832f89effb. +// +// Solidity: event SimpleEvent(uint256 value) +func (_Chainreader *ChainreaderFilterer) FilterSimpleEvent(opts *bind.FilterOpts) (*ChainreaderSimpleEventIterator, error) { + + logs, sub, err := _Chainreader.contract.FilterLogs(opts, "SimpleEvent") + if err != nil { + return nil, err + } + return &ChainreaderSimpleEventIterator{contract: _Chainreader.contract, event: "SimpleEvent", logs: logs, sub: sub}, nil +} + +// WatchSimpleEvent is a free log subscription operation binding the contract event 0x12d199749b3f4c44df8d9386c63d725b7756ec47204f3aa0bf05ea832f89effb. +// +// Solidity: event SimpleEvent(uint256 value) +func (_Chainreader *ChainreaderFilterer) WatchSimpleEvent(opts *bind.WatchOpts, sink chan<- *ChainreaderSimpleEvent) (event.Subscription, error) { + + logs, sub, err := _Chainreader.contract.WatchLogs(opts, "SimpleEvent") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ChainreaderSimpleEvent) + if err := _Chainreader.contract.UnpackLog(event, "SimpleEvent", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSimpleEvent is a log parse operation binding the contract event 0x12d199749b3f4c44df8d9386c63d725b7756ec47204f3aa0bf05ea832f89effb. +// +// Solidity: event SimpleEvent(uint256 value) +func (_Chainreader *ChainreaderFilterer) ParseSimpleEvent(log types.Log) (*ChainreaderSimpleEvent, error) { + event := new(ChainreaderSimpleEvent) + if err := _Chainreader.contract.UnpackLog(event, "SimpleEvent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/core/capabilities/ccip/ccip_integration_tests/chainreader/mycontract.sol b/core/capabilities/ccip/ccip_integration_tests/chainreader/mycontract.sol new file mode 100644 index 0000000000..0fae1f4baa --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/chainreader/mycontract.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.18; + +contract SimpleContract { + event SimpleEvent(uint256 value); + uint256 public eventCount; + uint[] public numbers; + + struct Person { + string name; + uint age; + } + + function emitEvent() public { + eventCount++; + numbers.push(eventCount); + emit SimpleEvent(eventCount); + } + + function getEventCount() public view returns (uint256) { + return eventCount; + } + + function getNumbers() public view returns (uint256[] memory) { + return numbers; + } + + function getPerson() public pure returns (Person memory) { + return Person("Dim", 18); + } +} diff --git a/core/capabilities/ccip/ccip_integration_tests/helpers.go b/core/capabilities/ccip/ccip_integration_tests/helpers.go new file mode 100644 index 0000000000..7606c8bbeb --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/helpers.go @@ -0,0 +1,938 @@ +package ccip_integration_tests + +import ( + "bytes" + "encoding/hex" + "math/big" + "sort" + "testing" + "time" + + "github.com/smartcontractkit/chainlink-ccip/chainconfig" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccip_integration_tests/integrationhelpers" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ocr3_config_encoder" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/link_token" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + + chainsel "github.com/smartcontractkit/chain-selectors" + + "github.com/stretchr/testify/require" +) + +var ( + homeChainID = chainsel.GETH_TESTNET.EvmChainID + ccipSendRequestedTopic = evm_2_evm_multi_onramp.EVM2EVMMultiOnRampCCIPSendRequested{}.Topic() + commitReportAcceptedTopic = evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReportAccepted{}.Topic() + executionStateChangedTopic = evm_2_evm_multi_offramp.EVM2EVMMultiOffRampExecutionStateChanged{}.Topic() +) + +const ( + CapabilityLabelledName = "ccip" + CapabilityVersion = "v1.0.0" + NodeOperatorID = 1 + + // These constants drive what is set in the plugin offchain configs. + FirstBlockAge = 8 * time.Hour + RemoteGasPriceBatchWriteFrequency = 30 * time.Minute + BatchGasLimit = 6_500_000 + RelativeBoostPerWaitHour = 1.5 + InflightCacheExpiry = 10 * time.Minute + RootSnoozeTime = 30 * time.Minute + BatchingStrategyID = 0 + DeltaProgress = 30 * time.Second + DeltaResend = 10 * time.Second + DeltaInitial = 20 * time.Second + DeltaRound = 2 * time.Second + DeltaGrace = 2 * time.Second + DeltaCertifiedCommitRequest = 10 * time.Second + DeltaStage = 10 * time.Second + Rmax = 3 + MaxDurationQuery = 50 * time.Millisecond + MaxDurationObservation = 5 * time.Second + MaxDurationShouldAcceptAttestedReport = 10 * time.Second + MaxDurationShouldTransmitAcceptedReport = 10 * time.Second +) + +func e18Mult(amount uint64) *big.Int { + return new(big.Int).Mul(uBigInt(amount), uBigInt(1e18)) +} + +func uBigInt(i uint64) *big.Int { + return new(big.Int).SetUint64(i) +} + +type homeChain struct { + backend *backends.SimulatedBackend + owner *bind.TransactOpts + chainID uint64 + capabilityRegistry *kcr.CapabilitiesRegistry + ccipConfig *ccip_config.CCIPConfig +} + +type onchainUniverse struct { + backend *backends.SimulatedBackend + owner *bind.TransactOpts + chainID uint64 + linkToken *link_token.LinkToken + weth *weth9.WETH9 + router *router.Router + rmnProxy *arm_proxy_contract.ARMProxyContract + rmn *mock_arm_contract.MockARMContract + onramp *evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp + offramp *evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp + priceRegistry *price_registry.PriceRegistry + tokenAdminRegistry *token_admin_registry.TokenAdminRegistry + nonceManager *nonce_manager.NonceManager + receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver +} + +type requestData struct { + destChainSelector uint64 + receiverAddress common.Address + data []byte +} + +func (u *onchainUniverse) SendCCIPRequests(t *testing.T, requestDatas []requestData) { + for _, reqData := range requestDatas { + msg := router.ClientEVM2AnyMessage{ + Receiver: common.LeftPadBytes(reqData.receiverAddress.Bytes(), 32), + Data: reqData.data, + TokenAmounts: nil, // TODO: no tokens for now + FeeToken: u.weth.Address(), + ExtraArgs: nil, // TODO: no extra args for now, falls back to default + } + fee, err := u.router.GetFee(&bind.CallOpts{Context: testutils.Context(t)}, reqData.destChainSelector, msg) + require.NoError(t, err) + _, err = u.weth.Deposit(&bind.TransactOpts{ + From: u.owner.From, + Signer: u.owner.Signer, + Value: fee, + }) + require.NoError(t, err) + u.backend.Commit() + _, err = u.weth.Approve(u.owner, u.router.Address(), fee) + require.NoError(t, err) + u.backend.Commit() + + t.Logf("Sending CCIP request from chain %d (selector %d) to chain selector %d", + u.chainID, getSelector(u.chainID), reqData.destChainSelector) + _, err = u.router.CcipSend(u.owner, reqData.destChainSelector, msg) + require.NoError(t, err) + u.backend.Commit() + } +} + +type chainBase struct { + backend *backends.SimulatedBackend + owner *bind.TransactOpts +} + +// createUniverses does the following: +// 1. Creates 1 home chain and `numChains`-1 non-home chains +// 2. Sets up home chain with the capability registry and the CCIP config contract +// 2. Deploys the CCIP contracts to all chains. +// 3. Sets up the initial configurations for the contracts on all chains. +// 4. Wires the chains together. +// +// Conceptually one universe is ONE chain with all the contracts deployed on it and all the dependencies initialized. +func createUniverses( + t *testing.T, + numChains int, +) (homeChainUni homeChain, universes map[uint64]onchainUniverse) { + chains := createChains(t, numChains) + + homeChainBase, ok := chains[homeChainID] + require.True(t, ok, "home chain backend not available") + // Set up home chain first + homeChainUniverse := setupHomeChain(t, homeChainBase.owner, homeChainBase.backend) + + // deploy the ccip contracts on all chains + universes = make(map[uint64]onchainUniverse) + for chainID, base := range chains { + owner := base.owner + backend := base.backend + // deploy the CCIP contracts + linkToken := deployLinkToken(t, owner, backend, chainID) + rmn := deployMockARMContract(t, owner, backend, chainID) + rmnProxy := deployARMProxyContract(t, owner, backend, rmn.Address(), chainID) + weth := deployWETHContract(t, owner, backend, chainID) + rout := deployRouter(t, owner, backend, weth.Address(), rmnProxy.Address(), chainID) + priceRegistry := deployPriceRegistry(t, owner, backend, linkToken.Address(), weth.Address(), big.NewInt(1e18), chainID) + tokenAdminRegistry := deployTokenAdminRegistry(t, owner, backend, chainID) + nonceManager := deployNonceManager(t, owner, backend, chainID) + + // ====================================================================== + // OnRamp + // ====================================================================== + onRampAddr, _, _, err := evm_2_evm_multi_onramp.DeployEVM2EVMMultiOnRamp( + owner, + backend, + evm_2_evm_multi_onramp.EVM2EVMMultiOnRampStaticConfig{ + ChainSelector: getSelector(chainID), + RmnProxy: rmnProxy.Address(), + NonceManager: nonceManager.Address(), + TokenAdminRegistry: tokenAdminRegistry.Address(), + }, + evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDynamicConfig{ + Router: rout.Address(), + PriceRegistry: priceRegistry.Address(), + // `withdrawFeeTokens` onRamp function is not part of the message flow + // so we can set this to any address + FeeAggregator: testutils.NewAddress(), + }, + ) + require.NoErrorf(t, err, "failed to deploy onramp on chain id %d", chainID) + backend.Commit() + onramp, err := evm_2_evm_multi_onramp.NewEVM2EVMMultiOnRamp(onRampAddr, backend) + require.NoError(t, err) + + // ====================================================================== + // OffRamp + // ====================================================================== + offrampAddr, _, _, err := evm_2_evm_multi_offramp.DeployEVM2EVMMultiOffRamp( + owner, + backend, + evm_2_evm_multi_offramp.EVM2EVMMultiOffRampStaticConfig{ + ChainSelector: getSelector(chainID), + RmnProxy: rmnProxy.Address(), + TokenAdminRegistry: tokenAdminRegistry.Address(), + NonceManager: nonceManager.Address(), + }, + evm_2_evm_multi_offramp.EVM2EVMMultiOffRampDynamicConfig{ + Router: rout.Address(), + PriceRegistry: priceRegistry.Address(), + }, + // Source chain configs will be set up later once we have all chains + []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{}, + ) + require.NoErrorf(t, err, "failed to deploy offramp on chain id %d", chainID) + backend.Commit() + offramp, err := evm_2_evm_multi_offramp.NewEVM2EVMMultiOffRamp(offrampAddr, backend) + require.NoError(t, err) + + receiverAddress, _, _, err := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver( + owner, + backend, + false, + ) + require.NoError(t, err, "failed to deploy MaybeRevertMessageReceiver on chain id %d", chainID) + backend.Commit() + receiver, err := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(receiverAddress, backend) + require.NoError(t, err) + + universe := onchainUniverse{ + backend: backend, + owner: owner, + chainID: chainID, + linkToken: linkToken, + weth: weth, + router: rout, + rmnProxy: rmnProxy, + rmn: rmn, + onramp: onramp, + offramp: offramp, + priceRegistry: priceRegistry, + tokenAdminRegistry: tokenAdminRegistry, + nonceManager: nonceManager, + receiver: receiver, + } + // Set up the initial configurations for the contracts + setupUniverseBasics(t, universe) + + universes[chainID] = universe + } + + // Once we have all chains created and contracts deployed, we can set up the initial configurations and wire chains together + connectUniverses(t, universes) + + // print out all contract addresses for debugging purposes + for chainID, uni := range universes { + t.Logf("Chain ID: %d\n Chain Selector: %d\n LinkToken: %s\n WETH: %s\n Router: %s\n RMNProxy: %s\n RMN: %s\n OnRamp: %s\n OffRamp: %s\n PriceRegistry: %s\n TokenAdminRegistry: %s\n NonceManager: %s\n", + chainID, + getSelector(chainID), + uni.linkToken.Address().Hex(), + uni.weth.Address().Hex(), + uni.router.Address().Hex(), + uni.rmnProxy.Address().Hex(), + uni.rmn.Address().Hex(), + uni.onramp.Address().Hex(), + uni.offramp.Address().Hex(), + uni.priceRegistry.Address().Hex(), + uni.tokenAdminRegistry.Address().Hex(), + uni.nonceManager.Address().Hex(), + ) + } + + // print out topic hashes of relevant events for debugging purposes + t.Logf("Topic hash of CommitReportAccepted: %s", commitReportAcceptedTopic.Hex()) + t.Logf("Topic hash of ExecutionStateChanged: %s", executionStateChangedTopic.Hex()) + t.Logf("Topic hash of CCIPSendRequested: %s", ccipSendRequestedTopic.Hex()) + + return homeChainUniverse, universes +} + +// Creates 1 home chain and `numChains`-1 non-home chains +func createChains(t *testing.T, numChains int) map[uint64]chainBase { + chains := make(map[uint64]chainBase) + + homeChainOwner := testutils.MustNewSimTransactor(t) + homeChainBackend := backends.NewSimulatedBackend(core.GenesisAlloc{ + homeChainOwner.From: core.GenesisAccount{ + Balance: assets.Ether(10_000).ToInt(), + }, + }, 30e6) + tweakChainTimestamp(t, homeChainBackend, FirstBlockAge) + + chains[homeChainID] = chainBase{ + owner: homeChainOwner, + backend: homeChainBackend, + } + + for chainID := chainsel.TEST_90000001.EvmChainID; len(chains) < numChains && chainID < chainsel.TEST_90000020.EvmChainID; chainID++ { + owner := testutils.MustNewSimTransactor(t) + backend := backends.NewSimulatedBackend(core.GenesisAlloc{ + owner.From: core.GenesisAccount{ + Balance: assets.Ether(10_000).ToInt(), + }, + }, 30e6) + + tweakChainTimestamp(t, backend, FirstBlockAge) + + chains[chainID] = chainBase{ + owner: owner, + backend: backend, + } + } + + return chains +} + +// CCIP relies on block timestamps, but SimulatedBackend uses by default clock starting from 1970-01-01 +// This trick is used to move the clock closer to the current time. We set first block to be X hours ago. +// Tests create plenty of transactions so this number can't be too low, every new block mined will tick the clock, +// if you mine more than "X hours" transactions, SimulatedBackend will panic because generated timestamps will be in the future. +func tweakChainTimestamp(t *testing.T, backend *backends.SimulatedBackend, tweak time.Duration) { + blockTime := time.Unix(int64(backend.Blockchain().CurrentHeader().Time), 0) + sinceBlockTime := time.Since(blockTime) + diff := sinceBlockTime - tweak + err := backend.AdjustTime(diff) + require.NoError(t, err, "unable to adjust time on simulated chain") + backend.Commit() + backend.Commit() +} + +func setupHomeChain(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend) homeChain { + // deploy the capability registry on the home chain + crAddress, _, _, err := kcr.DeployCapabilitiesRegistry(owner, backend) + require.NoError(t, err, "failed to deploy capability registry on home chain") + backend.Commit() + + capabilityRegistry, err := kcr.NewCapabilitiesRegistry(crAddress, backend) + require.NoError(t, err) + + ccAddress, _, _, err := ccip_config.DeployCCIPConfig(owner, backend, crAddress) + require.NoError(t, err) + backend.Commit() + + capabilityConfig, err := ccip_config.NewCCIPConfig(ccAddress, backend) + require.NoError(t, err) + + _, err = capabilityRegistry.AddCapabilities(owner, []kcr.CapabilitiesRegistryCapability{ + { + LabelledName: CapabilityLabelledName, + Version: CapabilityVersion, + CapabilityType: 2, // consensus. not used (?) + ResponseType: 0, // report. not used (?) + ConfigurationContract: ccAddress, + }, + }) + require.NoError(t, err, "failed to add capabilities to the capability registry") + backend.Commit() + + // Add NodeOperator, for simplicity we'll add one NodeOperator only + // First NodeOperator will have NodeOperatorId = 1 + _, err = capabilityRegistry.AddNodeOperators(owner, []kcr.CapabilitiesRegistryNodeOperator{ + { + Admin: owner.From, + Name: "NodeOperator", + }, + }) + require.NoError(t, err, "failed to add node operator to the capability registry") + backend.Commit() + + return homeChain{ + backend: backend, + owner: owner, + chainID: homeChainID, + capabilityRegistry: capabilityRegistry, + ccipConfig: capabilityConfig, + } +} + +func sortP2PIDS(p2pIDs [][32]byte) { + sort.Slice(p2pIDs, func(i, j int) bool { + return bytes.Compare(p2pIDs[i][:], p2pIDs[j][:]) < 0 + }) +} + +func (h *homeChain) AddNodes( + t *testing.T, + p2pIDs [][32]byte, + capabilityIDs [][32]byte, +) { + // Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail + sortP2PIDS(p2pIDs) + var nodeParams []kcr.CapabilitiesRegistryNodeParams + for _, p2pID := range p2pIDs { + nodeParam := kcr.CapabilitiesRegistryNodeParams{ + NodeOperatorId: NodeOperatorID, + Signer: p2pID, // Not used in tests + P2pId: p2pID, + HashedCapabilityIds: capabilityIDs, + } + nodeParams = append(nodeParams, nodeParam) + } + _, err := h.capabilityRegistry.AddNodes(h.owner, nodeParams) + require.NoError(t, err, "failed to add node operator oracles") + h.backend.Commit() +} + +func AddChainConfig( + t *testing.T, + h homeChain, + chainSelector uint64, + p2pIDs [][32]byte, + f uint8, +) ccip_config.CCIPConfigTypesChainConfigInfo { + // Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail + sortP2PIDS(p2pIDs) + // First Add ChainConfig that includes all p2pIDs as readers + encodedExtraChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ + GasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(1000), + DAGasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(0), + FinalityDepth: 10, + OptimisticConfirmations: 1, + }) + require.NoError(t, err) + chainConfig := integrationhelpers.SetupConfigInfo(chainSelector, p2pIDs, f, encodedExtraChainConfig) + inputConfig := []ccip_config.CCIPConfigTypesChainConfigInfo{ + chainConfig, + } + _, err = h.ccipConfig.ApplyChainConfigUpdates(h.owner, nil, inputConfig) + require.NoError(t, err) + h.backend.Commit() + return chainConfig +} + +func (h *homeChain) AddDON( + t *testing.T, + ccipCapabilityID [32]byte, + chainSelector uint64, + uni onchainUniverse, + f uint8, + bootstrapP2PID [32]byte, + p2pIDs [][32]byte, + oracles []confighelper2.OracleIdentityExtra, +) { + // Get OCR3 Config from helper + var schedule []int + for range oracles { + schedule = append(schedule, 1) + } + + tabi, err := ocr3_config_encoder.IOCR3ConfigEncoderMetaData.GetAbi() + require.NoError(t, err) + + // Add DON on capability registry contract + var ocr3Configs []ocr3_config_encoder.CCIPConfigTypesOCR3Config + for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { + var encodedOffchainConfig []byte + var err2 error + if pluginType == cctypes.PluginTypeCCIPCommit { + encodedOffchainConfig, err2 = pluginconfig.EncodeCommitOffchainConfig(pluginconfig.CommitOffchainConfig{ + RemoteGasPriceBatchWriteFrequency: *commonconfig.MustNewDuration(RemoteGasPriceBatchWriteFrequency), + // TODO: implement token price writes + // TokenPriceBatchWriteFrequency: *commonconfig.MustNewDuration(tokenPriceBatchWriteFrequency), + }) + require.NoError(t, err2) + } else { + encodedOffchainConfig, err2 = pluginconfig.EncodeExecuteOffchainConfig(pluginconfig.ExecuteOffchainConfig{ + BatchGasLimit: BatchGasLimit, + RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, + MessageVisibilityInterval: *commonconfig.MustNewDuration(FirstBlockAge), + InflightCacheExpiry: *commonconfig.MustNewDuration(InflightCacheExpiry), + RootSnoozeTime: *commonconfig.MustNewDuration(RootSnoozeTime), + BatchingStrategyID: BatchingStrategyID, + }) + require.NoError(t, err2) + } + signers, transmitters, configF, _, offchainConfigVersion, offchainConfig, err2 := ocr3confighelper.ContractSetConfigArgsForTests( + DeltaProgress, + DeltaResend, + DeltaInitial, + DeltaRound, + DeltaGrace, + DeltaCertifiedCommitRequest, + DeltaStage, + Rmax, + schedule, + oracles, + encodedOffchainConfig, + MaxDurationQuery, + MaxDurationObservation, + MaxDurationShouldAcceptAttestedReport, + MaxDurationShouldTransmitAcceptedReport, + int(f), + []byte{}, // empty OnChainConfig + ) + require.NoError(t, err2, "failed to create contract config") + + signersBytes := make([][]byte, len(signers)) + for i, signer := range signers { + signersBytes[i] = signer + } + + transmittersBytes := make([][]byte, len(transmitters)) + for i, transmitter := range transmitters { + // anotherErr because linting doesn't want to shadow err + parsed, anotherErr := common.ParseHexOrString(string(transmitter)) + require.NoError(t, anotherErr) + transmittersBytes[i] = parsed + } + + ocr3Configs = append(ocr3Configs, ocr3_config_encoder.CCIPConfigTypesOCR3Config{ + PluginType: uint8(pluginType), + ChainSelector: chainSelector, + F: configF, + OffchainConfigVersion: offchainConfigVersion, + OfframpAddress: uni.offramp.Address().Bytes(), + BootstrapP2PIds: [][32]byte{bootstrapP2PID}, + P2pIds: p2pIDs, + Signers: signersBytes, + Transmitters: transmittersBytes, + OffchainConfig: offchainConfig, + }) + } + + encodedCall, err := tabi.Pack("exposeOCR3Config", ocr3Configs) + require.NoError(t, err) + + // Trim first four bytes to remove function selector. + encodedConfigs := encodedCall[4:] + + // commit so that we have an empty block to filter events from + h.backend.Commit() + + _, err = h.capabilityRegistry.AddDON(h.owner, p2pIDs, []kcr.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: ccipCapabilityID, + Config: encodedConfigs, + }, + }, false, false, f) + require.NoError(t, err) + h.backend.Commit() + + endBlock := h.backend.Blockchain().CurrentBlock().Number.Uint64() + iter, err := h.capabilityRegistry.FilterConfigSet(&bind.FilterOpts{ + Start: h.backend.Blockchain().CurrentBlock().Number.Uint64() - 1, + End: &endBlock, + }) + require.NoError(t, err, "failed to filter config set events") + var donID uint32 + for iter.Next() { + donID = iter.Event.DonId + break + } + require.NotZero(t, donID, "failed to get donID from config set event") + + var signerAddresses []common.Address + for _, oracle := range oracles { + signerAddresses = append(signerAddresses, common.BytesToAddress(oracle.OnchainPublicKey)) + } + + var transmitterAddresses []common.Address + for _, oracle := range oracles { + transmitterAddresses = append(transmitterAddresses, common.HexToAddress(string(oracle.TransmitAccount))) + } + + // get the config digest from the ccip config contract and set config on the offramp. + var offrampOCR3Configs []evm_2_evm_multi_offramp.MultiOCR3BaseOCRConfigArgs + for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { + ocrConfig, err1 := h.ccipConfig.GetOCRConfig(&bind.CallOpts{ + Context: testutils.Context(t), + }, donID, uint8(pluginType)) + require.NoError(t, err1, "failed to get OCR3 config from ccip config contract") + require.Len(t, ocrConfig, 1, "expected exactly one OCR3 config") + offrampOCR3Configs = append(offrampOCR3Configs, evm_2_evm_multi_offramp.MultiOCR3BaseOCRConfigArgs{ + ConfigDigest: ocrConfig[0].ConfigDigest, + OcrPluginType: uint8(pluginType), + F: f, + IsSignatureVerificationEnabled: pluginType == cctypes.PluginTypeCCIPCommit, + Signers: signerAddresses, + Transmitters: transmitterAddresses, + }) + } + + uni.backend.Commit() + + _, err = uni.offramp.SetOCR3Configs(uni.owner, offrampOCR3Configs) + require.NoError(t, err, "failed to set ocr3 configs on offramp") + uni.backend.Commit() + + for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { + ocrConfig, err := uni.offramp.LatestConfigDetails(&bind.CallOpts{ + Context: testutils.Context(t), + }, uint8(pluginType)) + require.NoError(t, err, "failed to get latest commit OCR3 config") + require.Equalf(t, offrampOCR3Configs[pluginType].ConfigDigest, ocrConfig.ConfigInfo.ConfigDigest, "%s OCR3 config digest mismatch", pluginType.String()) + require.Equalf(t, offrampOCR3Configs[pluginType].F, ocrConfig.ConfigInfo.F, "%s OCR3 config F mismatch", pluginType.String()) + require.Equalf(t, offrampOCR3Configs[pluginType].IsSignatureVerificationEnabled, ocrConfig.ConfigInfo.IsSignatureVerificationEnabled, "%s OCR3 config signature verification mismatch", pluginType.String()) + if pluginType == cctypes.PluginTypeCCIPCommit { + // only commit will set signers, exec doesn't need them. + require.Equalf(t, offrampOCR3Configs[pluginType].Signers, ocrConfig.Signers, "%s OCR3 config signers mismatch", pluginType.String()) + } + require.Equalf(t, offrampOCR3Configs[pluginType].Transmitters, ocrConfig.Transmitters, "%s OCR3 config transmitters mismatch", pluginType.String()) + } + + t.Logf("set ocr3 config on the offramp, signers: %+v, transmitters: %+v", signerAddresses, transmitterAddresses) +} + +func connectUniverses( + t *testing.T, + universes map[uint64]onchainUniverse, +) { + for _, uni := range universes { + wireRouter(t, uni, universes) + wirePriceRegistry(t, uni, universes) + wireOffRamp(t, uni, universes) + initRemoteChainsGasPrices(t, uni, universes) + } +} + +// setupUniverseBasics sets up the initial configurations for the CCIP contracts on a single chain. +// 1. Mint 1000 LINK to the owner +// 2. Set the price registry with local token prices +// 3. Authorize the onRamp and offRamp on the nonce manager +func setupUniverseBasics(t *testing.T, uni onchainUniverse) { + // ============================================================================= + // Universe specific updates/configs + // These updates are specific to each universe and are set up here + // These updates don't depend on other chains + // ============================================================================= + owner := uni.owner + // ============================================================================= + // Mint 1000 LINK to owner + // ============================================================================= + _, err := uni.linkToken.GrantMintRole(owner, owner.From) + require.NoError(t, err) + _, err = uni.linkToken.Mint(owner, owner.From, e18Mult(1000)) + require.NoError(t, err) + uni.backend.Commit() + + // ============================================================================= + // Price updates for tokens + // These are the prices of the fee tokens of local chain in USD + // ============================================================================= + tokenPriceUpdates := []price_registry.InternalTokenPriceUpdate{ + { + SourceToken: uni.linkToken.Address(), + UsdPerToken: e18Mult(20), + }, + { + SourceToken: uni.weth.Address(), + UsdPerToken: e18Mult(4000), + }, + } + _, err = uni.priceRegistry.UpdatePrices(owner, price_registry.InternalPriceUpdates{ + TokenPriceUpdates: tokenPriceUpdates, + }) + require.NoErrorf(t, err, "failed to update prices in price registry on chain id %d", uni.chainID) + uni.backend.Commit() + + _, err = uni.priceRegistry.ApplyAuthorizedCallerUpdates(owner, price_registry.AuthorizedCallersAuthorizedCallerArgs{ + AddedCallers: []common.Address{ + uni.offramp.Address(), + }, + }) + require.NoError(t, err, "failed to authorize offramp on price registry") + uni.backend.Commit() + + // ============================================================================= + // Authorize OnRamp & OffRamp on NonceManager + // Otherwise the onramp will not be able to call the nonceManager to get next Nonce + // ============================================================================= + authorizedCallersAuthorizedCallerArgs := nonce_manager.AuthorizedCallersAuthorizedCallerArgs{ + AddedCallers: []common.Address{ + uni.onramp.Address(), + uni.offramp.Address(), + }, + } + _, err = uni.nonceManager.ApplyAuthorizedCallerUpdates(owner, authorizedCallersAuthorizedCallerArgs) + require.NoError(t, err) + uni.backend.Commit() +} + +// As we can't change router contract. The contract was expecting onRamp and offRamp per lane and not per chain +// In the new architecture we have only one onRamp and one offRamp per chain. +// hence we add the mapping for all remote chains to the onRamp/offRamp contract of the local chain +func wireRouter(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { + owner := uni.owner + var ( + routerOnrampUpdates []router.RouterOnRamp + routerOfframpUpdates []router.RouterOffRamp + ) + for remoteChainID := range universes { + if remoteChainID == uni.chainID { + continue + } + routerOnrampUpdates = append(routerOnrampUpdates, router.RouterOnRamp{ + DestChainSelector: getSelector(remoteChainID), + OnRamp: uni.onramp.Address(), + }) + routerOfframpUpdates = append(routerOfframpUpdates, router.RouterOffRamp{ + SourceChainSelector: getSelector(remoteChainID), + OffRamp: uni.offramp.Address(), + }) + } + _, err := uni.router.ApplyRampUpdates(owner, routerOnrampUpdates, []router.RouterOffRamp{}, routerOfframpUpdates) + require.NoErrorf(t, err, "failed to apply ramp updates on router on chain id %d", uni.chainID) + uni.backend.Commit() +} + +// Setting OnRampDestChainConfigs +func wirePriceRegistry(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { + owner := uni.owner + var priceRegistryDestChainConfigArgs []price_registry.PriceRegistryDestChainConfigArgs + for remoteChainID := range universes { + if remoteChainID == uni.chainID { + continue + } + priceRegistryDestChainConfigArgs = append(priceRegistryDestChainConfigArgs, price_registry.PriceRegistryDestChainConfigArgs{ + DestChainSelector: getSelector(remoteChainID), + DestChainConfig: defaultPriceRegistryDestChainConfig(t), + }) + } + _, err := uni.priceRegistry.ApplyDestChainConfigUpdates(owner, priceRegistryDestChainConfigArgs) + require.NoErrorf(t, err, "failed to apply dest chain config updates on price registry on chain id %d", uni.chainID) + uni.backend.Commit() +} + +// Setting OffRampSourceChainConfigs +func wireOffRamp(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { + owner := uni.owner + var offrampSourceChainConfigArgs []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs + for remoteChainID, remoteUniverse := range universes { + if remoteChainID == uni.chainID { + continue + } + offrampSourceChainConfigArgs = append(offrampSourceChainConfigArgs, evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{ + SourceChainSelector: getSelector(remoteChainID), // for each destination chain, add a source chain config + IsEnabled: true, + OnRamp: remoteUniverse.onramp.Address().Bytes(), + }) + } + _, err := uni.offramp.ApplySourceChainConfigUpdates(owner, offrampSourceChainConfigArgs) + require.NoErrorf(t, err, "failed to apply source chain config updates on offramp on chain id %d", uni.chainID) + uni.backend.Commit() + for remoteChainID, remoteUniverse := range universes { + if remoteChainID == uni.chainID { + continue + } + sourceCfg, err2 := uni.offramp.GetSourceChainConfig(&bind.CallOpts{}, getSelector(remoteChainID)) + require.NoError(t, err2) + require.True(t, sourceCfg.IsEnabled, "source chain config should be enabled") + require.Equal(t, remoteUniverse.onramp.Address(), common.BytesToAddress(sourceCfg.OnRamp), "source chain config onRamp address mismatch") + } +} + +func getSelector(chainID uint64) uint64 { + selector, err := chainsel.SelectorFromChainId(chainID) + if err != nil { + panic(err) + } + return selector +} + +// initRemoteChainsGasPrices sets the gas prices for all chains except the local chain in the local price registry +func initRemoteChainsGasPrices(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { + var gasPriceUpdates []price_registry.InternalGasPriceUpdate + for remoteChainID := range universes { + if remoteChainID == uni.chainID { + continue + } + gasPriceUpdates = append(gasPriceUpdates, + price_registry.InternalGasPriceUpdate{ + DestChainSelector: getSelector(remoteChainID), + UsdPerUnitGas: big.NewInt(2e12), + }, + ) + } + _, err := uni.priceRegistry.UpdatePrices(uni.owner, price_registry.InternalPriceUpdates{ + GasPriceUpdates: gasPriceUpdates, + }) + require.NoError(t, err) +} + +func defaultPriceRegistryDestChainConfig(t *testing.T) price_registry.PriceRegistryDestChainConfig { + // https://github.com/smartcontractkit/ccip/blob/c4856b64bd766f1ddbaf5d13b42d3c4b12efde3a/contracts/src/v0.8/ccip/libraries/Internal.sol#L337-L337 + /* + ```Solidity + // bytes4(keccak256("CCIP ChainFamilySelector EVM")) + bytes4 public constant CHAIN_FAMILY_SELECTOR_EVM = 0x2812d52c; + ``` + */ + evmFamilySelector, err := hex.DecodeString("2812d52c") + require.NoError(t, err) + return price_registry.PriceRegistryDestChainConfig{ + IsEnabled: true, + MaxNumberOfTokensPerMsg: 10, + MaxDataBytes: 256, + MaxPerMsgGasLimit: 3_000_000, + DestGasOverhead: 50_000, + DefaultTokenFeeUSDCents: 1, + DestGasPerPayloadByte: 10, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 100, + DestDataAvailabilityMultiplierBps: 1, + DefaultTokenDestGasOverhead: 125_000, + DefaultTokenDestBytesOverhead: 32, + DefaultTxGasLimit: 200_000, + GasMultiplierWeiPerEth: 1, + NetworkFeeUSDCents: 1, + ChainFamilySelector: [4]byte(evmFamilySelector), + } +} + +func deployLinkToken(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, chainID uint64) *link_token.LinkToken { + linkAddr, _, _, err := link_token.DeployLinkToken(owner, backend) + require.NoErrorf(t, err, "failed to deploy link token on chain id %d", chainID) + backend.Commit() + linkToken, err := link_token.NewLinkToken(linkAddr, backend) + require.NoError(t, err) + return linkToken +} + +func deployMockARMContract(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, chainID uint64) *mock_arm_contract.MockARMContract { + rmnAddr, _, _, err := mock_arm_contract.DeployMockARMContract(owner, backend) + require.NoErrorf(t, err, "failed to deploy mock arm on chain id %d", chainID) + backend.Commit() + rmn, err := mock_arm_contract.NewMockARMContract(rmnAddr, backend) + require.NoError(t, err) + return rmn +} + +func deployARMProxyContract(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, rmnAddr common.Address, chainID uint64) *arm_proxy_contract.ARMProxyContract { + rmnProxyAddr, _, _, err := arm_proxy_contract.DeployARMProxyContract(owner, backend, rmnAddr) + require.NoErrorf(t, err, "failed to deploy arm proxy on chain id %d", chainID) + backend.Commit() + rmnProxy, err := arm_proxy_contract.NewARMProxyContract(rmnProxyAddr, backend) + require.NoError(t, err) + return rmnProxy +} + +func deployWETHContract(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, chainID uint64) *weth9.WETH9 { + wethAddr, _, _, err := weth9.DeployWETH9(owner, backend) + require.NoErrorf(t, err, "failed to deploy weth contract on chain id %d", chainID) + backend.Commit() + weth, err := weth9.NewWETH9(wethAddr, backend) + require.NoError(t, err) + return weth +} + +func deployRouter(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, wethAddr, rmnProxyAddr common.Address, chainID uint64) *router.Router { + routerAddr, _, _, err := router.DeployRouter(owner, backend, wethAddr, rmnProxyAddr) + require.NoErrorf(t, err, "failed to deploy router on chain id %d", chainID) + backend.Commit() + rout, err := router.NewRouter(routerAddr, backend) + require.NoError(t, err) + return rout +} + +func deployPriceRegistry( + t *testing.T, + owner *bind.TransactOpts, + backend *backends.SimulatedBackend, + linkAddr, + wethAddr common.Address, + maxFeeJuelsPerMsg *big.Int, + chainID uint64, +) *price_registry.PriceRegistry { + priceRegistryAddr, _, _, err := price_registry.DeployPriceRegistry( + owner, + backend, + price_registry.PriceRegistryStaticConfig{ + MaxFeeJuelsPerMsg: maxFeeJuelsPerMsg, + LinkToken: linkAddr, + StalenessThreshold: 24 * 60 * 60, // 24 hours + }, + []common.Address{ + owner.From, // owner can update prices in this test + }, // price updaters, will be set to offramp later + []common.Address{linkAddr, wethAddr}, // fee tokens + // empty for now, need to fill in when testing token transfers + []price_registry.PriceRegistryTokenPriceFeedUpdate{}, + // empty for now, need to fill in when testing token transfers + []price_registry.PriceRegistryTokenTransferFeeConfigArgs{}, + []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs{ + { + PremiumMultiplierWeiPerEth: 9e17, // 0.9 ETH + Token: linkAddr, + }, + { + PremiumMultiplierWeiPerEth: 1e18, + Token: wethAddr, + }, + }, + // Destination chain configs will be set up later once we have all chains + []price_registry.PriceRegistryDestChainConfigArgs{}, + ) + require.NoErrorf(t, err, "failed to deploy price registry on chain id %d", chainID) + backend.Commit() + priceRegistry, err := price_registry.NewPriceRegistry(priceRegistryAddr, backend) + require.NoError(t, err) + return priceRegistry +} + +func deployTokenAdminRegistry(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, chainID uint64) *token_admin_registry.TokenAdminRegistry { + tarAddr, _, _, err := token_admin_registry.DeployTokenAdminRegistry(owner, backend) + require.NoErrorf(t, err, "failed to deploy token admin registry on chain id %d", chainID) + backend.Commit() + tokenAdminRegistry, err := token_admin_registry.NewTokenAdminRegistry(tarAddr, backend) + require.NoError(t, err) + return tokenAdminRegistry +} + +func deployNonceManager(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, chainID uint64) *nonce_manager.NonceManager { + nonceManagerAddr, _, _, err := nonce_manager.DeployNonceManager(owner, backend, []common.Address{owner.From}) + require.NoErrorf(t, err, "failed to deploy nonce_manager on chain id %d", chainID) + backend.Commit() + nonceManager, err := nonce_manager.NewNonceManager(nonceManagerAddr, backend) + require.NoError(t, err) + return nonceManager +} diff --git a/core/capabilities/ccip/ccip_integration_tests/home_chain_test.go b/core/capabilities/ccip/ccip_integration_tests/home_chain_test.go new file mode 100644 index 0000000000..c78fd37b80 --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/home_chain_test.go @@ -0,0 +1,103 @@ +package ccip_integration_tests + +import ( + "testing" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccip_integration_tests/integrationhelpers" + + mapset "github.com/deckarep/golang-set/v2" + "github.com/onsi/gomega" + + libocrtypes "github.com/smartcontractkit/libocr/ragep2p/types" + + "github.com/smartcontractkit/chainlink-ccip/chainconfig" + ccipreader "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + "github.com/stretchr/testify/require" + + capcfg "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestHomeChainReader(t *testing.T) { + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + uni := integrationhelpers.NewTestUniverse(ctx, t, lggr) + // We need 3*f + 1 p2pIDs to have enough nodes to bootstrap + var arr []int64 + n := int(integrationhelpers.FChainA*3 + 1) + for i := 0; i <= n; i++ { + arr = append(arr, int64(i)) + } + p2pIDs := integrationhelpers.P2pIDsFromInts(arr) + uni.AddCapability(p2pIDs) + //==============================Apply configs to Capability Contract================================= + encodedChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ + GasPriceDeviationPPB: cciptypes.NewBigIntFromInt64(1000), + DAGasPriceDeviationPPB: cciptypes.NewBigIntFromInt64(1_000_000), + FinalityDepth: -1, + OptimisticConfirmations: 1, + }) + require.NoError(t, err) + chainAConf := integrationhelpers.SetupConfigInfo(integrationhelpers.ChainA, p2pIDs, integrationhelpers.FChainA, encodedChainConfig) + chainBConf := integrationhelpers.SetupConfigInfo(integrationhelpers.ChainB, p2pIDs[1:], integrationhelpers.FChainB, encodedChainConfig) + chainCConf := integrationhelpers.SetupConfigInfo(integrationhelpers.ChainC, p2pIDs[2:], integrationhelpers.FChainC, encodedChainConfig) + inputConfig := []capcfg.CCIPConfigTypesChainConfigInfo{ + chainAConf, + chainBConf, + chainCConf, + } + _, err = uni.CcipCfg.ApplyChainConfigUpdates(uni.Transactor, nil, inputConfig) + require.NoError(t, err) + uni.Backend.Commit() + //================================Setup HomeChainReader=============================== + + pollDuration := time.Second + homeChain := uni.HomeChainReader + + gomega.NewWithT(t).Eventually(func() bool { + configs, _ := homeChain.GetAllChainConfigs() + return configs != nil + }, testutils.WaitTimeout(t), pollDuration*5).Should(gomega.BeTrue()) + + t.Logf("homchain reader is ready") + //================================Test HomeChain Reader=============================== + expectedChainConfigs := map[cciptypes.ChainSelector]ccipreader.ChainConfig{} + for _, c := range inputConfig { + expectedChainConfigs[cciptypes.ChainSelector(c.ChainSelector)] = ccipreader.ChainConfig{ + FChain: int(c.ChainConfig.FChain), + SupportedNodes: toPeerIDs(c.ChainConfig.Readers), + Config: mustDecodeChainConfig(t, c.ChainConfig.Config), + } + } + configs, err := homeChain.GetAllChainConfigs() + require.NoError(t, err) + require.Equal(t, expectedChainConfigs, configs) + //=================================Remove ChainC from OnChainConfig========================================= + _, err = uni.CcipCfg.ApplyChainConfigUpdates(uni.Transactor, []uint64{integrationhelpers.ChainC}, nil) + require.NoError(t, err) + uni.Backend.Commit() + time.Sleep(pollDuration * 5) // Wait for the chain reader to update + configs, err = homeChain.GetAllChainConfigs() + require.NoError(t, err) + delete(expectedChainConfigs, cciptypes.ChainSelector(integrationhelpers.ChainC)) + require.Equal(t, expectedChainConfigs, configs) +} + +func toPeerIDs(readers [][32]byte) mapset.Set[libocrtypes.PeerID] { + peerIDs := mapset.NewSet[libocrtypes.PeerID]() + for _, r := range readers { + peerIDs.Add(r) + } + return peerIDs +} + +func mustDecodeChainConfig(t *testing.T, encodedChainConfig []byte) chainconfig.ChainConfig { + chainConfig, err := chainconfig.DecodeChainConfig(encodedChainConfig) + require.NoError(t, err) + return chainConfig +} diff --git a/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go b/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go new file mode 100644 index 0000000000..7520b12633 --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go @@ -0,0 +1,304 @@ +package integrationhelpers + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "sort" + "testing" + "time" + + configsevm "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/configs/evm" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + + "github.com/smartcontractkit/chainlink-ccip/pkg/consts" + ccipreader "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ocr3_config_encoder" + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + + "github.com/smartcontractkit/chainlink-common/pkg/types" + + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" +) + +const chainID = 1337 + +func NewReader( + t *testing.T, + logPoller logpoller.LogPoller, + headTracker logpoller.HeadTracker, + client client.Client, + address common.Address, + chainReaderConfig evmrelaytypes.ChainReaderConfig, +) types.ContractReader { + cr, err := evm.NewChainReaderService(testutils.Context(t), logger.TestLogger(t), logPoller, headTracker, client, chainReaderConfig) + require.NoError(t, err) + err = cr.Bind(testutils.Context(t), []types.BoundContract{ + { + Address: address.String(), + Name: consts.ContractNameCCIPConfig, + }, + }) + require.NoError(t, err) + require.NoError(t, cr.Start(testutils.Context(t))) + for { + if err := cr.Ready(); err == nil { + break + } + } + + return cr +} + +const ( + ChainA uint64 = 1 + FChainA uint8 = 1 + + ChainB uint64 = 2 + FChainB uint8 = 2 + + ChainC uint64 = 3 + FChainC uint8 = 3 + + CcipCapabilityLabelledName = "ccip" + CcipCapabilityVersion = "v1.0" +) + +var CapabilityID = fmt.Sprintf("%s@%s", CcipCapabilityLabelledName, CcipCapabilityVersion) + +type TestUniverse struct { + Transactor *bind.TransactOpts + Backend *backends.SimulatedBackend + CapReg *kcr.CapabilitiesRegistry + CcipCfg *ccip_config.CCIPConfig + TestingT *testing.T + LogPoller logpoller.LogPoller + HeadTracker logpoller.HeadTracker + SimClient client.Client + HomeChainReader ccipreader.HomeChain +} + +func NewTestUniverse(ctx context.Context, t *testing.T, lggr logger.Logger) TestUniverse { + transactor := testutils.MustNewSimTransactor(t) + backend := backends.NewSimulatedBackend(core.GenesisAlloc{ + transactor.From: {Balance: assets.Ether(1000).ToInt()}, + }, 30e6) + + crAddress, _, _, err := kcr.DeployCapabilitiesRegistry(transactor, backend) + require.NoError(t, err) + backend.Commit() + + capReg, err := kcr.NewCapabilitiesRegistry(crAddress, backend) + require.NoError(t, err) + + ccAddress, _, _, err := ccip_config.DeployCCIPConfig(transactor, backend, crAddress) + require.NoError(t, err) + backend.Commit() + + cc, err := ccip_config.NewCCIPConfig(ccAddress, backend) + require.NoError(t, err) + + db := pgtest.NewSqlxDB(t) + lpOpts := logpoller.Opts{ + PollPeriod: time.Millisecond, + FinalityDepth: 0, + BackfillBatchSize: 10, + RpcBatchSize: 10, + KeepFinalizedBlocksDepth: 100000, + } + cl := client.NewSimulatedBackendClient(t, backend, big.NewInt(chainID)) + headTracker := headtracker.NewSimulatedHeadTracker(cl, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + if lpOpts.PollPeriod == 0 { + lpOpts.PollPeriod = 1 * time.Hour + } + lp := logpoller.NewLogPoller(logpoller.NewORM(big.NewInt(chainID), db, lggr), cl, logger.NullLogger, headTracker, lpOpts) + require.NoError(t, lp.Start(ctx)) + t.Cleanup(func() { require.NoError(t, lp.Close()) }) + + hcr := NewHomeChainReader(t, lp, headTracker, cl, ccAddress) + return TestUniverse{ + Transactor: transactor, + Backend: backend, + CapReg: capReg, + CcipCfg: cc, + TestingT: t, + SimClient: cl, + LogPoller: lp, + HeadTracker: headTracker, + HomeChainReader: hcr, + } +} + +func (t TestUniverse) NewContractReader(ctx context.Context, cfg []byte) (types.ContractReader, error) { + var config evmrelaytypes.ChainReaderConfig + err := json.Unmarshal(cfg, &config) + require.NoError(t.TestingT, err) + return evm.NewChainReaderService(ctx, logger.TestLogger(t.TestingT), t.LogPoller, t.HeadTracker, t.SimClient, config) +} + +func P2pIDsFromInts(ints []int64) [][32]byte { + var p2pIDs [][32]byte + for _, i := range ints { + p2pID := p2pkey.MustNewV2XXXTestingOnly(big.NewInt(i)).PeerID() + p2pIDs = append(p2pIDs, p2pID) + } + sort.Slice(p2pIDs, func(i, j int) bool { + for k := 0; k < 32; k++ { + if p2pIDs[i][k] < p2pIDs[j][k] { + return true + } else if p2pIDs[i][k] > p2pIDs[j][k] { + return false + } + } + return false + }) + return p2pIDs +} + +func (t *TestUniverse) AddCapability(p2pIDs [][32]byte) { + _, err := t.CapReg.AddCapabilities(t.Transactor, []kcr.CapabilitiesRegistryCapability{ + { + LabelledName: CcipCapabilityLabelledName, + Version: CcipCapabilityVersion, + CapabilityType: 0, + ResponseType: 0, + ConfigurationContract: t.CcipCfg.Address(), + }, + }) + require.NoError(t.TestingT, err, "failed to add capability to registry") + t.Backend.Commit() + + ccipCapabilityID, err := t.CapReg.GetHashedCapabilityId(nil, CcipCapabilityLabelledName, CcipCapabilityVersion) + require.NoError(t.TestingT, err) + + for i := 0; i < len(p2pIDs); i++ { + _, err = t.CapReg.AddNodeOperators(t.Transactor, []kcr.CapabilitiesRegistryNodeOperator{ + { + Admin: t.Transactor.From, + Name: fmt.Sprintf("nop-%d", i), + }, + }) + require.NoError(t.TestingT, err) + t.Backend.Commit() + + // get the node operator id from the event + it, err := t.CapReg.FilterNodeOperatorAdded(nil, nil, nil) + require.NoError(t.TestingT, err) + var nodeOperatorID uint32 + for it.Next() { + if it.Event.Name == fmt.Sprintf("nop-%d", i) { + nodeOperatorID = it.Event.NodeOperatorId + break + } + } + require.NotZero(t.TestingT, nodeOperatorID) + + _, err = t.CapReg.AddNodes(t.Transactor, []kcr.CapabilitiesRegistryNodeParams{ + { + NodeOperatorId: nodeOperatorID, + Signer: testutils.Random32Byte(), + P2pId: p2pIDs[i], + HashedCapabilityIds: [][32]byte{ccipCapabilityID}, + }, + }) + require.NoError(t.TestingT, err) + t.Backend.Commit() + + // verify that the node was added successfully + nodeInfo, err := t.CapReg.GetNode(nil, p2pIDs[i]) + require.NoError(t.TestingT, err) + + require.Equal(t.TestingT, nodeOperatorID, nodeInfo.NodeOperatorId) + require.Equal(t.TestingT, p2pIDs[i][:], nodeInfo.P2pId[:]) + } +} + +func NewHomeChainReader(t *testing.T, logPoller logpoller.LogPoller, headTracker logpoller.HeadTracker, client client.Client, ccAddress common.Address) ccipreader.HomeChain { + cr := NewReader(t, logPoller, headTracker, client, ccAddress, configsevm.HomeChainReaderConfigRaw()) + + hcr := ccipreader.NewHomeChainReader(cr, logger.TestLogger(t), 500*time.Millisecond) + require.NoError(t, hcr.Start(testutils.Context(t))) + t.Cleanup(func() { require.NoError(t, hcr.Close()) }) + + return hcr +} + +func (t *TestUniverse) AddDONToRegistry( + ccipCapabilityID [32]byte, + chainSelector uint64, + f uint8, + bootstrapP2PID [32]byte, + p2pIDs [][32]byte, +) { + tabi, err := ocr3_config_encoder.IOCR3ConfigEncoderMetaData.GetAbi() + require.NoError(t.TestingT, err) + + var ( + signers [][]byte + transmitters [][]byte + ) + for range p2pIDs { + signers = append(signers, testutils.NewAddress().Bytes()) + transmitters = append(transmitters, testutils.NewAddress().Bytes()) + } + + var ocr3Configs []ocr3_config_encoder.CCIPConfigTypesOCR3Config + for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { + ocr3Configs = append(ocr3Configs, ocr3_config_encoder.CCIPConfigTypesOCR3Config{ + PluginType: uint8(pluginType), + ChainSelector: chainSelector, + F: f, + OffchainConfigVersion: 30, + OfframpAddress: testutils.NewAddress().Bytes(), + BootstrapP2PIds: [][32]byte{bootstrapP2PID}, + P2pIds: p2pIDs, + Signers: signers, + Transmitters: transmitters, + OffchainConfig: []byte("offchain config"), + }) + } + + encodedCall, err := tabi.Pack("exposeOCR3Config", ocr3Configs) + require.NoError(t.TestingT, err) + + // Trim first four bytes to remove function selector. + encodedConfigs := encodedCall[4:] + + _, err = t.CapReg.AddDON(t.Transactor, p2pIDs, []kcr.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: ccipCapabilityID, + Config: encodedConfigs, + }, + }, false, false, f) + require.NoError(t.TestingT, err) + t.Backend.Commit() +} + +func SetupConfigInfo(chainSelector uint64, readers [][32]byte, fChain uint8, cfg []byte) ccip_config.CCIPConfigTypesChainConfigInfo { + return ccip_config.CCIPConfigTypesChainConfigInfo{ + ChainSelector: chainSelector, + ChainConfig: ccip_config.CCIPConfigTypesChainConfig{ + Readers: readers, + FChain: fChain, + Config: cfg, + }, + } +} diff --git a/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go b/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go new file mode 100644 index 0000000000..8cafb90172 --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go @@ -0,0 +1,281 @@ +package ccip_integration_tests + +import ( + "fmt" + "math/big" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/hashicorp/consul/sdk/freeport" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/stretchr/testify/require" +) + +const STATE_SUCCESS = uint8(2) + +/* +* If you want to debug, set log level to info and use the following commands for easier logs filtering. +* +* // Run the test and redirect logs to logs.txt +* go test -v -run "^TestIntegration_OCR3Nodes" ./core/capabilities/ccip/ccip_integration_tests 2>&1 > logs.txt +* +* // Reads logs.txt as a stream and apply filters using grep +* tail -fn0 logs.txt | grep "CCIPExecPlugin" + */ +func TestIntegration_OCR3Nodes(t *testing.T) { + const ( + numChains = 3 // number of chains that this test will run on + numNodes = 4 // number of OCR3 nodes, test assumes that every node supports every chain + + simulatedBackendBlockTime = 900 * time.Millisecond // Simulated backend blocks committing interval + oraclesBootWaitTime = 30 * time.Second // Time to wait for oracles to come up (HACK) + fChain = 1 // fChain value for all the chains + oracleLogLevel = zapcore.InfoLevel // Log level for the oracle / plugins. + ) + + t.Logf("creating %d universes", numChains) + homeChainUni, universes := createUniverses(t, numChains) + + var ( + oracles = make(map[uint64][]confighelper2.OracleIdentityExtra) + apps []chainlink.Application + nodes []*ocr3Node + p2pIDs [][32]byte + + // The bootstrap node will be: nodes[0] + bootstrapPort int + bootstrapP2PID p2pkey.PeerID + ) + + ports := freeport.GetN(t, numNodes) + ctx := testutils.Context(t) + callCtx := &bind.CallOpts{Context: ctx} + + for i := 0; i < numNodes; i++ { + t.Logf("Setting up ocr3 node:%d at port:%d", i, ports[i]) + node := setupNodeOCR3(t, ports[i], universes, homeChainUni, oracleLogLevel) + + for chainID, transmitter := range node.transmitters { + identity := confighelper2.OracleIdentityExtra{ + OracleIdentity: confighelper2.OracleIdentity{ + OnchainPublicKey: node.keybundle.PublicKey(), // Different for each chain + TransmitAccount: ocrtypes.Account(transmitter.Hex()), + OffchainPublicKey: node.keybundle.OffchainPublicKey(), // Same for each family + PeerID: node.peerID, + }, + ConfigEncryptionPublicKey: node.keybundle.ConfigEncryptionPublicKey(), // Different for each chain + } + oracles[chainID] = append(oracles[chainID], identity) + } + + apps = append(apps, node.app) + nodes = append(nodes, node) + + peerID, err := p2pkey.MakePeerID(node.peerID) + require.NoError(t, err) + p2pIDs = append(p2pIDs, peerID) + } + + bootstrapPort = ports[0] + bootstrapP2PID = p2pIDs[0] + bootstrapAddr := fmt.Sprintf("127.0.0.1:%d", bootstrapPort) + t.Logf("[bootstrap node] peerID:%s p2pID:%d address:%s", nodes[0].peerID, bootstrapP2PID, bootstrapAddr) + + // Start committing periodically in the background for all the chains + tick := time.NewTicker(simulatedBackendBlockTime) + defer tick.Stop() + commitBlocksBackground(t, universes, tick) + + ccipCapabilityID, err := homeChainUni.capabilityRegistry.GetHashedCapabilityId( + callCtx, CapabilityLabelledName, CapabilityVersion) + require.NoError(t, err, "failed to get hashed capability id for ccip") + require.NotEqual(t, [32]byte{}, ccipCapabilityID, "ccip capability id is empty") + + // Need to Add nodes and assign capabilities to them before creating DONS + homeChainUni.AddNodes(t, p2pIDs, [][32]byte{ccipCapabilityID}) + + for _, uni := range universes { + t.Logf("Adding chainconfig for chain %d", uni.chainID) + AddChainConfig(t, homeChainUni, getSelector(uni.chainID), p2pIDs, fChain) + } + + cfgs, err := homeChainUni.ccipConfig.GetAllChainConfigs(callCtx) + require.NoError(t, err) + require.Len(t, cfgs, numChains) + + // Create a DON for each chain + for _, uni := range universes { + // Add nodes and give them the capability + t.Log("Adding DON for universe: ", uni.chainID) + chainSelector := getSelector(uni.chainID) + homeChainUni.AddDON( + t, + ccipCapabilityID, + chainSelector, + uni, + fChain, + bootstrapP2PID, + p2pIDs, + oracles[uni.chainID], + ) + } + + t.Log("Creating ocr3 jobs, starting oracles") + for i := 0; i < len(nodes); i++ { + err1 := nodes[i].app.Start(ctx) + require.NoError(t, err1) + tApp := apps[i] + t.Cleanup(func() { require.NoError(t, tApp.Stop()) }) + + jb := mustGetJobSpec(t, bootstrapP2PID, bootstrapPort, nodes[i].peerID, nodes[i].keybundle.ID()) + require.NoErrorf(t, tApp.AddJobV2(ctx, &jb), "Wasn't able to create ccip job for node %d", i) + } + + t.Logf("Sending ccip requests from each chain to all other chains") + for _, uni := range universes { + requests := genRequestData(uni.chainID, universes) + uni.SendCCIPRequests(t, requests) + } + + // Wait for the oracles to come up. + // TODO: We need some data driven way to do this e.g. wait until LP filters to be registered. + time.Sleep(oraclesBootWaitTime) + + // Replay the log poller on all the chains so that the logs are in the db. + // otherwise the plugins won't pick them up. + for _, node := range nodes { + for chainID := range universes { + t.Logf("Replaying logs for chain %d from block %d", chainID, 1) + require.NoError(t, node.app.ReplayFromBlock(big.NewInt(int64(chainID)), 1, false), "failed to replay logs") + } + } + + // with only one request sent from each chain to each other chain, + // and with sequence numbers on incrementing by 1 on a per-dest chain + // basis, we expect the min sequence number to be 1 on all chains. + expectedSeqNrRange := ccipocr3.NewSeqNumRange(1, 1) + var wg sync.WaitGroup + for _, uni := range universes { + for remoteSelector := range universes { + if remoteSelector == uni.chainID { + continue + } + wg.Add(1) + go func(uni onchainUniverse, remoteSelector uint64) { + defer wg.Done() + waitForCommitWithInterval(t, uni, getSelector(remoteSelector), expectedSeqNrRange) + }(uni, remoteSelector) + } + } + + start := time.Now() + wg.Wait() + t.Logf("All chains received the expected commit report in %s", time.Since(start)) + + // with only one request sent from each chain to each other chain, + // all ExecutionStateChanged events should have the sequence number 1. + expectedSeqNr := uint64(1) + for _, uni := range universes { + for remoteSelector := range universes { + if remoteSelector == uni.chainID { + continue + } + wg.Add(1) + go func(uni onchainUniverse, remoteSelector uint64) { + defer wg.Done() + waitForExecWithSeqNr(t, uni, getSelector(remoteSelector), expectedSeqNr) + }(uni, remoteSelector) + } + } + + start = time.Now() + wg.Wait() + t.Logf("All chains received the expected ExecutionStateChanged event in %s", time.Since(start)) +} + +func genRequestData(chainID uint64, universes map[uint64]onchainUniverse) []requestData { + var res []requestData + for destChainID, destUni := range universes { + if destChainID == chainID { + continue + } + res = append(res, requestData{ + destChainSelector: getSelector(destChainID), + receiverAddress: destUni.receiver.Address(), + data: []byte(fmt.Sprintf("msg from chain %d to chain %d", chainID, destChainID)), + }) + } + return res +} + +func waitForCommitWithInterval( + t *testing.T, + uni onchainUniverse, + expectedSourceChainSelector uint64, + expectedSeqNumRange ccipocr3.SeqNumRange, +) { + sink := make(chan *evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReportAccepted) + subscription, err := uni.offramp.WatchCommitReportAccepted(&bind.WatchOpts{ + Context: testutils.Context(t), + }, sink) + require.NoError(t, err) + + for { + select { + case <-time.After(10 * time.Second): + t.Logf("Waiting for commit report on chain id %d (selector %d) from source selector %d expected seq nr range %s", + uni.chainID, getSelector(uni.chainID), expectedSourceChainSelector, expectedSeqNumRange.String()) + case subErr := <-subscription.Err(): + t.Fatalf("Subscription error: %+v", subErr) + case report := <-sink: + if len(report.Report.MerkleRoots) > 0 { + // Check the interval of sequence numbers and make sure it matches + // the expected range. + for _, mr := range report.Report.MerkleRoots { + if mr.SourceChainSelector == expectedSourceChainSelector && + uint64(expectedSeqNumRange.Start()) == mr.Interval.Min && + uint64(expectedSeqNumRange.End()) == mr.Interval.Max { + t.Logf("Received commit report on chain id %d (selector %d) from source selector %d expected seq nr range %s", + uni.chainID, getSelector(uni.chainID), expectedSourceChainSelector, expectedSeqNumRange.String()) + return + } + } + } + } + } +} + +func waitForExecWithSeqNr(t *testing.T, uni onchainUniverse, expectedSourceChainSelector, expectedSeqNr uint64) { + for { + scc, err := uni.offramp.GetSourceChainConfig(nil, expectedSourceChainSelector) + require.NoError(t, err) + t.Logf("Waiting for ExecutionStateChanged on chain %d (selector %d) from chain %d with expected sequence number %d, current onchain minSeqNr: %d", + uni.chainID, getSelector(uni.chainID), expectedSourceChainSelector, expectedSeqNr, scc.MinSeqNr) + iter, err := uni.offramp.FilterExecutionStateChanged(nil, []uint64{expectedSourceChainSelector}, []uint64{expectedSeqNr}, nil) + require.NoError(t, err) + var count int + for iter.Next() { + if iter.Event.SequenceNumber == expectedSeqNr && iter.Event.SourceChainSelector == expectedSourceChainSelector { + count++ + } + } + if count == 1 { + t.Logf("Received ExecutionStateChanged on chain %d (selector %d) from chain %d with expected sequence number %d", + uni.chainID, getSelector(uni.chainID), expectedSourceChainSelector, expectedSeqNr) + return + } + time.Sleep(5 * time.Second) + } +} diff --git a/core/capabilities/ccip/ccip_integration_tests/ocr_node_helper.go b/core/capabilities/ccip/ccip_integration_tests/ocr_node_helper.go new file mode 100644 index 0000000000..75b0e0ee94 --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/ocr_node_helper.go @@ -0,0 +1,316 @@ +package ccip_integration_tests + +import ( + "context" + "fmt" + "math/big" + "net/http" + "strconv" + "sync" + "testing" + "time" + + coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core/mocks" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + gethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/jmoiron/sqlx" + + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + v2toml "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + evmutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + configv2 "github.com/smartcontractkit/chainlink/v2/core/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/logger/audit" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/plugins" + + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" +) + +type ocr3Node struct { + app chainlink.Application + peerID string + transmitters map[uint64]common.Address + keybundle ocr2key.KeyBundle + db *sqlx.DB +} + +// setupNodeOCR3 creates a chainlink node and any associated keys in order to run +// ccip. +func setupNodeOCR3( + t *testing.T, + port int, + universes map[uint64]onchainUniverse, + homeChainUniverse homeChain, + logLevel zapcore.Level, +) *ocr3Node { + // Do not want to load fixtures as they contain a dummy chainID. + cfg, db := heavyweight.FullTestDBNoFixturesV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.Insecure.OCRDevelopmentMode = ptr(true) // Disables ocr spec validation so we can have fast polling for the test. + + c.Feature.LogPoller = ptr(true) + + // P2P V2 configs. + c.P2P.V2.Enabled = ptr(true) + c.P2P.V2.DeltaDial = config.MustNewDuration(500 * time.Millisecond) + c.P2P.V2.DeltaReconcile = config.MustNewDuration(5 * time.Second) + c.P2P.V2.ListenAddresses = &[]string{fmt.Sprintf("127.0.0.1:%d", port)} + + // Enable Capabilities, This is a pre-requisite for registrySyncer to work. + c.Capabilities.ExternalRegistry.NetworkID = ptr(relay.NetworkEVM) + c.Capabilities.ExternalRegistry.ChainID = ptr(strconv.FormatUint(homeChainUniverse.chainID, 10)) + c.Capabilities.ExternalRegistry.Address = ptr(homeChainUniverse.capabilityRegistry.Address().String()) + + // OCR configs + c.OCR.Enabled = ptr(false) + c.OCR.DefaultTransactionQueueDepth = ptr(uint32(200)) + c.OCR2.Enabled = ptr(true) + c.OCR2.ContractPollInterval = config.MustNewDuration(5 * time.Second) + + c.Log.Level = ptr(configv2.LogLevel(logLevel)) + + var chains v2toml.EVMConfigs + for chainID := range universes { + chains = append(chains, createConfigV2Chain(uBigInt(chainID))) + } + c.EVM = chains + }) + + lggr := logger.TestLogger(t) + lggr.SetLogLevel(logLevel) + ctx := testutils.Context(t) + clients := make(map[uint64]client.Client) + + for chainID, uni := range universes { + clients[chainID] = client.NewSimulatedBackendClient(t, uni.backend, uBigInt(chainID)) + } + + master := keystore.New(db, utils.FastScryptParams, lggr) + + kStore := KeystoreSim{ + eks: &EthKeystoreSim{ + Eth: master.Eth(), + t: t, + }, + csa: master.CSA(), + } + mailMon := mailbox.NewMonitor("ccip", lggr.Named("mailbox")) + evmOpts := chainlink.EVMFactoryConfig{ + ChainOpts: legacyevm.ChainOpts{ + AppConfig: cfg, + GenEthClient: func(i *big.Int) client.Client { + client, ok := clients[i.Uint64()] + if !ok { + t.Fatal("no backend for chainID", i) + } + return client + }, + MailMon: mailMon, + DS: db, + }, + CSAETHKeystore: kStore, + } + relayerFactory := chainlink.RelayerFactory{ + Logger: lggr, + LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), cfg.Tracing()), + GRPCOpts: loop.GRPCOpts{}, + CapabilitiesRegistry: coretypes.NewCapabilitiesRegistry(t), + } + initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitEVM(testutils.Context(t), relayerFactory, evmOpts)} + rci, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) + require.NoError(t, err) + + app, err := chainlink.NewApplication(chainlink.ApplicationOpts{ + Config: cfg, + DS: db, + KeyStore: master, + RelayerChainInteroperators: rci, + Logger: lggr, + ExternalInitiatorManager: nil, + CloseLogger: lggr.Sync, + UnrestrictedHTTPClient: &http.Client{}, + RestrictedHTTPClient: &http.Client{}, + AuditLogger: audit.NoopLogger, + MailMon: mailMon, + LoopRegistry: plugins.NewLoopRegistry(lggr, cfg.Tracing()), + }) + require.NoError(t, err) + require.NoError(t, app.GetKeyStore().Unlock(ctx, "password")) + _, err = app.GetKeyStore().P2P().Create(ctx) + require.NoError(t, err) + + p2pIDs, err := app.GetKeyStore().P2P().GetAll() + require.NoError(t, err) + require.Len(t, p2pIDs, 1) + peerID := p2pIDs[0].PeerID() + // create a transmitter for each chain + transmitters := make(map[uint64]common.Address) + for chainID, uni := range universes { + backend := uni.backend + owner := uni.owner + cID := uBigInt(chainID) + addrs, err2 := app.GetKeyStore().Eth().EnabledAddressesForChain(testutils.Context(t), cID) + require.NoError(t, err2) + if len(addrs) == 1 { + // just fund the address + fundAddress(t, owner, addrs[0], assets.Ether(10).ToInt(), backend) + transmitters[chainID] = addrs[0] + } else { + // create key and fund it + _, err3 := app.GetKeyStore().Eth().Create(testutils.Context(t), cID) + require.NoError(t, err3, "failed to create key for chain", chainID) + sendingKeys, err3 := app.GetKeyStore().Eth().EnabledAddressesForChain(testutils.Context(t), cID) + require.NoError(t, err3) + require.Len(t, sendingKeys, 1) + fundAddress(t, owner, sendingKeys[0], assets.Ether(10).ToInt(), backend) + transmitters[chainID] = sendingKeys[0] + } + } + require.Len(t, transmitters, len(universes)) + + keybundle, err := app.GetKeyStore().OCR2().Create(ctx, chaintype.EVM) + require.NoError(t, err) + + t.Cleanup(func() { + require.NoError(t, db.Close()) + }) + + return &ocr3Node{ + // can't use this app because it doesn't have the right toml config + // missing bootstrapp + app: app, + peerID: peerID.Raw(), + transmitters: transmitters, + keybundle: keybundle, + db: db, + } +} + +func ptr[T any](v T) *T { return &v } + +var _ keystore.Eth = &EthKeystoreSim{} + +type EthKeystoreSim struct { + keystore.Eth + t *testing.T +} + +// override +func (e *EthKeystoreSim) SignTx(ctx context.Context, address common.Address, tx *gethtypes.Transaction, chainID *big.Int) (*gethtypes.Transaction, error) { + // always sign with chain id 1337 for the simulated backend + return e.Eth.SignTx(ctx, address, tx, big.NewInt(1337)) +} + +type KeystoreSim struct { + eks keystore.Eth + csa keystore.CSA +} + +func (e KeystoreSim) Eth() keystore.Eth { + return e.eks +} + +func (e KeystoreSim) CSA() keystore.CSA { + return e.csa +} + +func fundAddress(t *testing.T, from *bind.TransactOpts, to common.Address, amount *big.Int, backend *backends.SimulatedBackend) { + nonce, err := backend.PendingNonceAt(testutils.Context(t), from.From) + require.NoError(t, err) + gp, err := backend.SuggestGasPrice(testutils.Context(t)) + require.NoError(t, err) + rawTx := gethtypes.NewTx(&gethtypes.LegacyTx{ + Nonce: nonce, + GasPrice: gp, + Gas: 21000, + To: &to, + Value: amount, + }) + signedTx, err := from.Signer(from.From, rawTx) + require.NoError(t, err) + err = backend.SendTransaction(testutils.Context(t), signedTx) + require.NoError(t, err) + backend.Commit() +} + +func createConfigV2Chain(chainID *big.Int) *v2toml.EVMConfig { + chain := v2toml.Defaults((*evmutils.Big)(chainID)) + chain.GasEstimator.LimitDefault = ptr(uint64(5e6)) + chain.LogPollInterval = config.MustNewDuration(100 * time.Millisecond) + chain.Transactions.ForwardersEnabled = ptr(false) + chain.FinalityDepth = ptr(uint32(2)) + return &v2toml.EVMConfig{ + ChainID: (*evmutils.Big)(chainID), + Enabled: ptr(true), + Chain: chain, + Nodes: v2toml.EVMNodes{&v2toml.Node{}}, + } +} + +// Commit blocks periodically in the background for all chains +func commitBlocksBackground(t *testing.T, universes map[uint64]onchainUniverse, tick *time.Ticker) { + t.Log("starting ticker to commit blocks") + tickCtx, tickCancel := context.WithCancel(testutils.Context(t)) + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + for { + select { + case <-tick.C: + for _, uni := range universes { + uni.backend.Commit() + } + case <-tickCtx.Done(): + return + } + } + }() + t.Cleanup(func() { + tickCancel() + wg.Wait() + }) +} + +// p2pKeyID: nodes p2p id +// ocrKeyBundleID: nodes ocr key bundle id +func mustGetJobSpec(t *testing.T, bootstrapP2PID p2pkey.PeerID, bootstrapPort int, p2pKeyID string, ocrKeyBundleID string) job.Job { + specArgs := validate.SpecArgs{ + P2PV2Bootstrappers: []string{ + fmt.Sprintf("%s@127.0.0.1:%d", bootstrapP2PID.Raw(), bootstrapPort), + }, + CapabilityVersion: CapabilityVersion, + CapabilityLabelledName: CapabilityLabelledName, + OCRKeyBundleIDs: map[string]string{ + relay.NetworkEVM: ocrKeyBundleID, + }, + P2PKeyID: p2pKeyID, + PluginConfig: map[string]any{}, + } + specToml, err := validate.NewCCIPSpecToml(specArgs) + require.NoError(t, err) + jb, err := validate.ValidatedCCIPSpec(specToml) + require.NoError(t, err) + return jb +} diff --git a/core/capabilities/ccip/ccip_integration_tests/ping_pong_test.go b/core/capabilities/ccip/ccip_integration_tests/ping_pong_test.go new file mode 100644 index 0000000000..8a65ff5167 --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/ping_pong_test.go @@ -0,0 +1,95 @@ +package ccip_integration_tests + +import ( + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + gethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/stretchr/testify/require" + + "golang.org/x/exp/maps" + + pp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ping_pong_demo" +) + +/* +* Test is setting up 3 chains (let's call them A, B, C), each chain deploys and starts 2 ping pong contracts for the other 2. +* A ---deploy+start---> (pingPongB, pingPongC) +* B ---deploy+start---> (pingPongA, pingPongC) +* C ---deploy+start---> (pingPongA, pingPongB) +* and then checks that each ping pong contract emitted `CCIPSendRequested` event from the expected source to destination. +* Test fails if any wiring between contracts is not correct. + */ +func TestPingPong(t *testing.T) { + _, universes := createUniverses(t, 3) + pingPongs := initializePingPongContracts(t, universes) + for chainID, universe := range universes { + for otherChain, pingPong := range pingPongs[chainID] { + t.Log("PingPong From: ", chainID, " To: ", otherChain) + _, err := pingPong.StartPingPong(universe.owner) + require.NoError(t, err) + universe.backend.Commit() + + logIter, err := universe.onramp.FilterCCIPSendRequested(&bind.FilterOpts{Start: 0}, nil) + require.NoError(t, err) + // Iterate until latest event + for logIter.Next() { + } + log := logIter.Event + require.Equal(t, getSelector(otherChain), log.DestChainSelector) + require.Equal(t, pingPong.Address(), log.Message.Sender) + chainPingPongAddr := pingPongs[otherChain][chainID].Address().Bytes() + // With chain agnostic addresses we need to pad the address to the correct length if the receiver is zero prefixed + paddedAddr := gethcommon.LeftPadBytes(chainPingPongAddr, len(log.Message.Receiver)) + require.Equal(t, paddedAddr, log.Message.Receiver) + } + } +} + +// InitializeContracts initializes ping pong contracts on all chains and +// connects them all to each other. +func initializePingPongContracts( + t *testing.T, + chainUniverses map[uint64]onchainUniverse, +) map[uint64]map[uint64]*pp.PingPongDemo { + pingPongs := make(map[uint64]map[uint64]*pp.PingPongDemo) + chainIDs := maps.Keys(chainUniverses) + // For each chain initialize N ping pong contracts, where N is the (number of chains - 1) + for chainID, universe := range chainUniverses { + pingPongs[chainID] = make(map[uint64]*pp.PingPongDemo) + for _, chainToConnect := range chainIDs { + if chainToConnect == chainID { + continue // don't connect chain to itself + } + backend := universe.backend + owner := universe.owner + pingPongAddr, _, _, err := pp.DeployPingPongDemo(owner, backend, universe.router.Address(), universe.linkToken.Address()) + require.NoError(t, err) + backend.Commit() + pingPong, err := pp.NewPingPongDemo(pingPongAddr, backend) + require.NoError(t, err) + backend.Commit() + // Fund the ping pong contract with LINK + _, err = universe.linkToken.Transfer(owner, pingPong.Address(), e18Mult(10)) + backend.Commit() + require.NoError(t, err) + pingPongs[chainID][chainToConnect] = pingPong + } + } + + // Set up each ping pong contract to its counterpart on the other chain + for chainID, universe := range chainUniverses { + for chainToConnect, pingPong := range pingPongs[chainID] { + _, err := pingPong.SetCounterpart( + universe.owner, + getSelector(chainUniverses[chainToConnect].chainID), + // This is the address of the ping pong contract on the other chain + pingPongs[chainToConnect][chainID].Address(), + ) + require.NoError(t, err) + universe.backend.Commit() + } + } + return pingPongs +} diff --git a/core/capabilities/ccip/ccipevm/commitcodec.go b/core/capabilities/ccip/ccipevm/commitcodec.go new file mode 100644 index 0000000000..928cecd0a4 --- /dev/null +++ b/core/capabilities/ccip/ccipevm/commitcodec.go @@ -0,0 +1,138 @@ +package ccipevm + +import ( + "context" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" +) + +// CommitPluginCodecV1 is a codec for encoding and decoding commit plugin reports. +// Compatible with: +// - "EVM2EVMMultiOffRamp 1.6.0-dev" +type CommitPluginCodecV1 struct { + commitReportAcceptedEventInputs abi.Arguments +} + +func NewCommitPluginCodecV1() *CommitPluginCodecV1 { + abiParsed, err := abi.JSON(strings.NewReader(evm_2_evm_multi_offramp.EVM2EVMMultiOffRampABI)) + if err != nil { + panic(fmt.Errorf("parse multi offramp abi: %s", err)) + } + eventInputs := abihelpers.MustGetEventInputs("CommitReportAccepted", abiParsed) + return &CommitPluginCodecV1{commitReportAcceptedEventInputs: eventInputs} +} + +func (c *CommitPluginCodecV1) Encode(ctx context.Context, report cciptypes.CommitPluginReport) ([]byte, error) { + merkleRoots := make([]evm_2_evm_multi_offramp.EVM2EVMMultiOffRampMerkleRoot, 0, len(report.MerkleRoots)) + for _, root := range report.MerkleRoots { + merkleRoots = append(merkleRoots, evm_2_evm_multi_offramp.EVM2EVMMultiOffRampMerkleRoot{ + SourceChainSelector: uint64(root.ChainSel), + Interval: evm_2_evm_multi_offramp.EVM2EVMMultiOffRampInterval{ + Min: uint64(root.SeqNumsRange.Start()), + Max: uint64(root.SeqNumsRange.End()), + }, + MerkleRoot: root.MerkleRoot, + }) + } + + tokenPriceUpdates := make([]evm_2_evm_multi_offramp.InternalTokenPriceUpdate, 0, len(report.PriceUpdates.TokenPriceUpdates)) + for _, update := range report.PriceUpdates.TokenPriceUpdates { + if !common.IsHexAddress(string(update.TokenID)) { + return nil, fmt.Errorf("invalid token address: %s", update.TokenID) + } + if update.Price.IsEmpty() { + return nil, fmt.Errorf("empty price for token: %s", update.TokenID) + } + tokenPriceUpdates = append(tokenPriceUpdates, evm_2_evm_multi_offramp.InternalTokenPriceUpdate{ + SourceToken: common.HexToAddress(string(update.TokenID)), + UsdPerToken: update.Price.Int, + }) + } + + gasPriceUpdates := make([]evm_2_evm_multi_offramp.InternalGasPriceUpdate, 0, len(report.PriceUpdates.GasPriceUpdates)) + for _, update := range report.PriceUpdates.GasPriceUpdates { + if update.GasPrice.IsEmpty() { + return nil, fmt.Errorf("empty gas price for chain: %d", update.ChainSel) + } + + gasPriceUpdates = append(gasPriceUpdates, evm_2_evm_multi_offramp.InternalGasPriceUpdate{ + DestChainSelector: uint64(update.ChainSel), + UsdPerUnitGas: update.GasPrice.Int, + }) + } + + evmReport := evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReport{ + PriceUpdates: evm_2_evm_multi_offramp.InternalPriceUpdates{ + TokenPriceUpdates: tokenPriceUpdates, + GasPriceUpdates: gasPriceUpdates, + }, + MerkleRoots: merkleRoots, + } + + return c.commitReportAcceptedEventInputs.PackValues([]interface{}{evmReport}) +} + +func (c *CommitPluginCodecV1) Decode(ctx context.Context, bytes []byte) (cciptypes.CommitPluginReport, error) { + unpacked, err := c.commitReportAcceptedEventInputs.Unpack(bytes) + if err != nil { + return cciptypes.CommitPluginReport{}, err + } + if len(unpacked) != 1 { + return cciptypes.CommitPluginReport{}, fmt.Errorf("expected 1 argument, got %d", len(unpacked)) + } + + commitReportRaw := abi.ConvertType(unpacked[0], new(evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReport)) + commitReport, is := commitReportRaw.(*evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReport) + if !is { + return cciptypes.CommitPluginReport{}, + fmt.Errorf("expected EVM2EVMMultiOffRampCommitReport, got %T", unpacked[0]) + } + + merkleRoots := make([]cciptypes.MerkleRootChain, 0, len(commitReport.MerkleRoots)) + for _, root := range commitReport.MerkleRoots { + merkleRoots = append(merkleRoots, cciptypes.MerkleRootChain{ + ChainSel: cciptypes.ChainSelector(root.SourceChainSelector), + SeqNumsRange: cciptypes.NewSeqNumRange( + cciptypes.SeqNum(root.Interval.Min), + cciptypes.SeqNum(root.Interval.Max), + ), + MerkleRoot: root.MerkleRoot, + }) + } + + tokenPriceUpdates := make([]cciptypes.TokenPrice, 0, len(commitReport.PriceUpdates.TokenPriceUpdates)) + for _, update := range commitReport.PriceUpdates.TokenPriceUpdates { + tokenPriceUpdates = append(tokenPriceUpdates, cciptypes.TokenPrice{ + TokenID: types.Account(update.SourceToken.String()), + Price: cciptypes.NewBigInt(big.NewInt(0).Set(update.UsdPerToken)), + }) + } + + gasPriceUpdates := make([]cciptypes.GasPriceChain, 0, len(commitReport.PriceUpdates.GasPriceUpdates)) + for _, update := range commitReport.PriceUpdates.GasPriceUpdates { + gasPriceUpdates = append(gasPriceUpdates, cciptypes.GasPriceChain{ + GasPrice: cciptypes.NewBigInt(big.NewInt(0).Set(update.UsdPerUnitGas)), + ChainSel: cciptypes.ChainSelector(update.DestChainSelector), + }) + } + + return cciptypes.CommitPluginReport{ + MerkleRoots: merkleRoots, + PriceUpdates: cciptypes.PriceUpdates{ + TokenPriceUpdates: tokenPriceUpdates, + GasPriceUpdates: gasPriceUpdates, + }, + }, nil +} + +// Ensure CommitPluginCodec implements the CommitPluginCodec interface +var _ cciptypes.CommitPluginCodec = (*CommitPluginCodecV1)(nil) diff --git a/core/capabilities/ccip/ccipevm/commitcodec_test.go b/core/capabilities/ccip/ccipevm/commitcodec_test.go new file mode 100644 index 0000000000..737f7be1d6 --- /dev/null +++ b/core/capabilities/ccip/ccipevm/commitcodec_test.go @@ -0,0 +1,135 @@ +package ccipevm + +import ( + "math/big" + "math/rand" + "testing" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" +) + +var randomCommitReport = func() cciptypes.CommitPluginReport { + return cciptypes.CommitPluginReport{ + MerkleRoots: []cciptypes.MerkleRootChain{ + { + ChainSel: cciptypes.ChainSelector(rand.Uint64()), + SeqNumsRange: cciptypes.NewSeqNumRange( + cciptypes.SeqNum(rand.Uint64()), + cciptypes.SeqNum(rand.Uint64()), + ), + MerkleRoot: utils.RandomBytes32(), + }, + { + ChainSel: cciptypes.ChainSelector(rand.Uint64()), + SeqNumsRange: cciptypes.NewSeqNumRange( + cciptypes.SeqNum(rand.Uint64()), + cciptypes.SeqNum(rand.Uint64()), + ), + MerkleRoot: utils.RandomBytes32(), + }, + }, + PriceUpdates: cciptypes.PriceUpdates{ + TokenPriceUpdates: []cciptypes.TokenPrice{ + { + TokenID: types.Account(utils.RandomAddress().String()), + Price: cciptypes.NewBigInt(utils.RandUint256()), + }, + }, + GasPriceUpdates: []cciptypes.GasPriceChain{ + {GasPrice: cciptypes.NewBigInt(utils.RandUint256()), ChainSel: cciptypes.ChainSelector(rand.Uint64())}, + {GasPrice: cciptypes.NewBigInt(utils.RandUint256()), ChainSel: cciptypes.ChainSelector(rand.Uint64())}, + {GasPrice: cciptypes.NewBigInt(utils.RandUint256()), ChainSel: cciptypes.ChainSelector(rand.Uint64())}, + }, + }, + } +} + +func TestCommitPluginCodecV1(t *testing.T) { + testCases := []struct { + name string + report func(report cciptypes.CommitPluginReport) cciptypes.CommitPluginReport + expErr bool + }{ + { + name: "base report", + report: func(report cciptypes.CommitPluginReport) cciptypes.CommitPluginReport { + return report + }, + }, + { + name: "empty token address", + report: func(report cciptypes.CommitPluginReport) cciptypes.CommitPluginReport { + report.PriceUpdates.TokenPriceUpdates[0].TokenID = "" + return report + }, + expErr: true, + }, + { + name: "empty merkle root", + report: func(report cciptypes.CommitPluginReport) cciptypes.CommitPluginReport { + report.MerkleRoots[0].MerkleRoot = cciptypes.Bytes32{} + return report + }, + }, + { + name: "zero token price", + report: func(report cciptypes.CommitPluginReport) cciptypes.CommitPluginReport { + report.PriceUpdates.TokenPriceUpdates[0].Price = cciptypes.NewBigInt(big.NewInt(0)) + return report + }, + }, + { + name: "zero gas price", + report: func(report cciptypes.CommitPluginReport) cciptypes.CommitPluginReport { + report.PriceUpdates.GasPriceUpdates[0].GasPrice = cciptypes.NewBigInt(big.NewInt(0)) + return report + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + report := tc.report(randomCommitReport()) + commitCodec := NewCommitPluginCodecV1() + ctx := testutils.Context(t) + encodedReport, err := commitCodec.Encode(ctx, report) + if tc.expErr { + assert.Error(t, err) + return + } + require.NoError(t, err) + decodedReport, err := commitCodec.Decode(ctx, encodedReport) + require.NoError(t, err) + require.Equal(t, report, decodedReport) + }) + } +} + +func BenchmarkCommitPluginCodecV1_Encode(b *testing.B) { + commitCodec := NewCommitPluginCodecV1() + ctx := testutils.Context(b) + + rep := randomCommitReport() + for i := 0; i < b.N; i++ { + _, err := commitCodec.Encode(ctx, rep) + require.NoError(b, err) + } +} + +func BenchmarkCommitPluginCodecV1_Decode(b *testing.B) { + commitCodec := NewCommitPluginCodecV1() + ctx := testutils.Context(b) + encodedReport, err := commitCodec.Encode(ctx, randomCommitReport()) + require.NoError(b, err) + + for i := 0; i < b.N; i++ { + _, err := commitCodec.Decode(ctx, encodedReport) + require.NoError(b, err) + } +} diff --git a/core/capabilities/ccip/ccipevm/executecodec.go b/core/capabilities/ccip/ccipevm/executecodec.go new file mode 100644 index 0000000000..a64c775112 --- /dev/null +++ b/core/capabilities/ccip/ccipevm/executecodec.go @@ -0,0 +1,181 @@ +package ccipevm + +import ( + "context" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" +) + +// ExecutePluginCodecV1 is a codec for encoding and decoding execute plugin reports. +// Compatible with: +// - "EVM2EVMMultiOffRamp 1.6.0-dev" +type ExecutePluginCodecV1 struct { + executeReportMethodInputs abi.Arguments +} + +func NewExecutePluginCodecV1() *ExecutePluginCodecV1 { + abiParsed, err := abi.JSON(strings.NewReader(evm_2_evm_multi_offramp.EVM2EVMMultiOffRampABI)) + if err != nil { + panic(fmt.Errorf("parse multi offramp abi: %s", err)) + } + methodInputs := abihelpers.MustGetMethodInputs("manuallyExecute", abiParsed) + if len(methodInputs) == 0 { + panic("no inputs found for method: manuallyExecute") + } + + return &ExecutePluginCodecV1{ + executeReportMethodInputs: methodInputs[:1], + } +} + +func (e *ExecutePluginCodecV1) Encode(ctx context.Context, report cciptypes.ExecutePluginReport) ([]byte, error) { + evmReport := make([]evm_2_evm_multi_offramp.InternalExecutionReportSingleChain, 0, len(report.ChainReports)) + + for _, chainReport := range report.ChainReports { + if chainReport.ProofFlagBits.IsEmpty() { + return nil, fmt.Errorf("proof flag bits are empty") + } + + evmProofs := make([][32]byte, 0, len(chainReport.Proofs)) + for _, proof := range chainReport.Proofs { + evmProofs = append(evmProofs, proof) + } + + evmMessages := make([]evm_2_evm_multi_offramp.InternalAny2EVMRampMessage, 0, len(chainReport.Messages)) + for _, message := range chainReport.Messages { + receiver := common.BytesToAddress(message.Receiver) + + tokenAmounts := make([]evm_2_evm_multi_offramp.InternalRampTokenAmount, 0, len(message.TokenAmounts)) + for _, tokenAmount := range message.TokenAmounts { + if tokenAmount.Amount.IsEmpty() { + return nil, fmt.Errorf("empty amount for token: %s", tokenAmount.DestTokenAddress) + } + + tokenAmounts = append(tokenAmounts, evm_2_evm_multi_offramp.InternalRampTokenAmount{ + SourcePoolAddress: tokenAmount.SourcePoolAddress, + DestTokenAddress: tokenAmount.DestTokenAddress, + ExtraData: tokenAmount.ExtraData, + Amount: tokenAmount.Amount.Int, + }) + } + + gasLimit, err := decodeExtraArgsV1V2(message.ExtraArgs) + if err != nil { + return nil, fmt.Errorf("decode extra args to get gas limit: %w", err) + } + + evmMessages = append(evmMessages, evm_2_evm_multi_offramp.InternalAny2EVMRampMessage{ + Header: evm_2_evm_multi_offramp.InternalRampMessageHeader{ + MessageId: message.Header.MessageID, + SourceChainSelector: uint64(message.Header.SourceChainSelector), + DestChainSelector: uint64(message.Header.DestChainSelector), + SequenceNumber: uint64(message.Header.SequenceNumber), + Nonce: message.Header.Nonce, + }, + Sender: message.Sender, + Data: message.Data, + Receiver: receiver, + GasLimit: gasLimit, + TokenAmounts: tokenAmounts, + }) + } + + evmChainReport := evm_2_evm_multi_offramp.InternalExecutionReportSingleChain{ + SourceChainSelector: uint64(chainReport.SourceChainSelector), + Messages: evmMessages, + OffchainTokenData: chainReport.OffchainTokenData, + Proofs: evmProofs, + ProofFlagBits: chainReport.ProofFlagBits.Int, + } + evmReport = append(evmReport, evmChainReport) + } + + return e.executeReportMethodInputs.PackValues([]interface{}{&evmReport}) +} + +func (e *ExecutePluginCodecV1) Decode(ctx context.Context, encodedReport []byte) (cciptypes.ExecutePluginReport, error) { + unpacked, err := e.executeReportMethodInputs.Unpack(encodedReport) + if err != nil { + return cciptypes.ExecutePluginReport{}, fmt.Errorf("unpack encoded report: %w", err) + } + if len(unpacked) != 1 { + return cciptypes.ExecutePluginReport{}, fmt.Errorf("unpacked report is empty") + } + + evmReportRaw := abi.ConvertType(unpacked[0], new([]evm_2_evm_multi_offramp.InternalExecutionReportSingleChain)) + evmReportPtr, is := evmReportRaw.(*[]evm_2_evm_multi_offramp.InternalExecutionReportSingleChain) + if !is { + return cciptypes.ExecutePluginReport{}, fmt.Errorf("got an unexpected report type %T", unpacked[0]) + } + if evmReportPtr == nil { + return cciptypes.ExecutePluginReport{}, fmt.Errorf("evm report is nil") + } + + evmReport := *evmReportPtr + executeReport := cciptypes.ExecutePluginReport{ + ChainReports: make([]cciptypes.ExecutePluginReportSingleChain, 0, len(evmReport)), + } + + for _, evmChainReport := range evmReport { + proofs := make([]cciptypes.Bytes32, 0, len(evmChainReport.Proofs)) + for _, proof := range evmChainReport.Proofs { + proofs = append(proofs, proof) + } + + messages := make([]cciptypes.Message, 0, len(evmChainReport.Messages)) + for _, evmMessage := range evmChainReport.Messages { + tokenAmounts := make([]cciptypes.RampTokenAmount, 0, len(evmMessage.TokenAmounts)) + for _, tokenAmount := range evmMessage.TokenAmounts { + tokenAmounts = append(tokenAmounts, cciptypes.RampTokenAmount{ + SourcePoolAddress: tokenAmount.SourcePoolAddress, + DestTokenAddress: tokenAmount.DestTokenAddress, + ExtraData: tokenAmount.ExtraData, + Amount: cciptypes.NewBigInt(tokenAmount.Amount), + }) + } + + message := cciptypes.Message{ + Header: cciptypes.RampMessageHeader{ + MessageID: evmMessage.Header.MessageId, + SourceChainSelector: cciptypes.ChainSelector(evmMessage.Header.SourceChainSelector), + DestChainSelector: cciptypes.ChainSelector(evmMessage.Header.DestChainSelector), + SequenceNumber: cciptypes.SeqNum(evmMessage.Header.SequenceNumber), + Nonce: evmMessage.Header.Nonce, + MsgHash: cciptypes.Bytes32{}, // <-- todo: info not available, but not required atm + OnRamp: cciptypes.Bytes{}, // <-- todo: info not available, but not required atm + }, + Sender: evmMessage.Sender, + Data: evmMessage.Data, + Receiver: evmMessage.Receiver.Bytes(), + ExtraArgs: cciptypes.Bytes{}, // <-- todo: info not available, but not required atm + FeeToken: cciptypes.Bytes{}, // <-- todo: info not available, but not required atm + FeeTokenAmount: cciptypes.BigInt{}, // <-- todo: info not available, but not required atm + TokenAmounts: tokenAmounts, + } + messages = append(messages, message) + } + + chainReport := cciptypes.ExecutePluginReportSingleChain{ + SourceChainSelector: cciptypes.ChainSelector(evmChainReport.SourceChainSelector), + Messages: messages, + OffchainTokenData: evmChainReport.OffchainTokenData, + Proofs: proofs, + ProofFlagBits: cciptypes.NewBigInt(evmChainReport.ProofFlagBits), + } + + executeReport.ChainReports = append(executeReport.ChainReports, chainReport) + } + + return executeReport, nil +} + +// Ensure ExecutePluginCodec implements the ExecutePluginCodec interface +var _ cciptypes.ExecutePluginCodec = (*ExecutePluginCodecV1)(nil) diff --git a/core/capabilities/ccip/ccipevm/executecodec_test.go b/core/capabilities/ccip/ccipevm/executecodec_test.go new file mode 100644 index 0000000000..4f207fdb0e --- /dev/null +++ b/core/capabilities/ccip/ccipevm/executecodec_test.go @@ -0,0 +1,174 @@ +package ccipevm + +import ( + "math/rand" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/core" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/message_hasher" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/report_codec" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var randomExecuteReport = func(t *testing.T, d *testSetupData) cciptypes.ExecutePluginReport { + const numChainReports = 10 + const msgsPerReport = 10 + const numTokensPerMsg = 3 + + chainReports := make([]cciptypes.ExecutePluginReportSingleChain, numChainReports) + for i := 0; i < numChainReports; i++ { + reportMessages := make([]cciptypes.Message, msgsPerReport) + for j := 0; j < msgsPerReport; j++ { + data, err := cciptypes.NewBytesFromString(utils.RandomAddress().String()) + assert.NoError(t, err) + + tokenAmounts := make([]cciptypes.RampTokenAmount, numTokensPerMsg) + for z := 0; z < numTokensPerMsg; z++ { + tokenAmounts[z] = cciptypes.RampTokenAmount{ + SourcePoolAddress: utils.RandomAddress().Bytes(), + DestTokenAddress: utils.RandomAddress().Bytes(), + ExtraData: data, + Amount: cciptypes.NewBigInt(utils.RandUint256()), + } + } + + extraArgs, err := d.contract.EncodeEVMExtraArgsV1(nil, message_hasher.ClientEVMExtraArgsV1{ + GasLimit: utils.RandUint256(), + }) + assert.NoError(t, err) + + reportMessages[j] = cciptypes.Message{ + Header: cciptypes.RampMessageHeader{ + MessageID: utils.RandomBytes32(), + SourceChainSelector: cciptypes.ChainSelector(rand.Uint64()), + DestChainSelector: cciptypes.ChainSelector(rand.Uint64()), + SequenceNumber: cciptypes.SeqNum(rand.Uint64()), + Nonce: rand.Uint64(), + MsgHash: utils.RandomBytes32(), + OnRamp: utils.RandomAddress().Bytes(), + }, + Sender: utils.RandomAddress().Bytes(), + Data: data, + Receiver: utils.RandomAddress().Bytes(), + ExtraArgs: extraArgs, + FeeToken: utils.RandomAddress().Bytes(), + FeeTokenAmount: cciptypes.NewBigInt(utils.RandUint256()), + TokenAmounts: tokenAmounts, + } + } + + tokenData := make([][][]byte, numTokensPerMsg) + for j := 0; j < numTokensPerMsg; j++ { + tokenData[j] = [][]byte{{0x1}, {0x2, 0x3}} + } + + chainReports[i] = cciptypes.ExecutePluginReportSingleChain{ + SourceChainSelector: cciptypes.ChainSelector(rand.Uint64()), + Messages: reportMessages, + OffchainTokenData: tokenData, + Proofs: []cciptypes.Bytes32{utils.RandomBytes32(), utils.RandomBytes32()}, + ProofFlagBits: cciptypes.NewBigInt(utils.RandUint256()), + } + } + + return cciptypes.ExecutePluginReport{ChainReports: chainReports} +} + +func TestExecutePluginCodecV1(t *testing.T) { + d := testSetup(t) + + testCases := []struct { + name string + report func(report cciptypes.ExecutePluginReport) cciptypes.ExecutePluginReport + expErr bool + }{ + { + name: "base report", + report: func(report cciptypes.ExecutePluginReport) cciptypes.ExecutePluginReport { return report }, + expErr: false, + }, + { + name: "reports have empty msgs", + report: func(report cciptypes.ExecutePluginReport) cciptypes.ExecutePluginReport { + report.ChainReports[0].Messages = []cciptypes.Message{} + report.ChainReports[4].Messages = []cciptypes.Message{} + return report + }, + expErr: false, + }, + { + name: "reports have empty offchain token data", + report: func(report cciptypes.ExecutePluginReport) cciptypes.ExecutePluginReport { + report.ChainReports[0].OffchainTokenData = [][][]byte{} + report.ChainReports[4].OffchainTokenData[1] = [][]byte{} + return report + }, + expErr: false, + }, + } + + ctx := testutils.Context(t) + + // Deploy the contract + transactor := testutils.MustNewSimTransactor(t) + simulatedBackend := backends.NewSimulatedBackend(core.GenesisAlloc{ + transactor.From: {Balance: assets.Ether(1000).ToInt()}, + }, 30e6) + address, _, _, err := report_codec.DeployReportCodec(transactor, simulatedBackend) + require.NoError(t, err) + simulatedBackend.Commit() + contract, err := report_codec.NewReportCodec(address, simulatedBackend) + require.NoError(t, err) + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + codec := NewExecutePluginCodecV1() + report := tc.report(randomExecuteReport(t, d)) + bytes, err := codec.Encode(ctx, report) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + + testSetup(t) + + // ignore msg hash in comparison + for i := range report.ChainReports { + for j := range report.ChainReports[i].Messages { + report.ChainReports[i].Messages[j].Header.MsgHash = cciptypes.Bytes32{} + report.ChainReports[i].Messages[j].Header.OnRamp = cciptypes.Bytes{} + report.ChainReports[i].Messages[j].FeeToken = cciptypes.Bytes{} + report.ChainReports[i].Messages[j].ExtraArgs = cciptypes.Bytes{} + report.ChainReports[i].Messages[j].FeeTokenAmount = cciptypes.BigInt{} + } + } + + // decode using the contract + contractDecodedReport, err := contract.DecodeExecuteReport(&bind.CallOpts{Context: ctx}, bytes) + assert.NoError(t, err) + assert.Equal(t, len(report.ChainReports), len(contractDecodedReport)) + for i, expReport := range report.ChainReports { + actReport := contractDecodedReport[i] + assert.Equal(t, expReport.OffchainTokenData, actReport.OffchainTokenData) + assert.Equal(t, len(expReport.Messages), len(actReport.Messages)) + assert.Equal(t, uint64(expReport.SourceChainSelector), actReport.SourceChainSelector) + } + + // decode using the codec + codecDecoded, err := codec.Decode(ctx, bytes) + assert.NoError(t, err) + assert.Equal(t, report, codecDecoded) + }) + } +} diff --git a/core/capabilities/ccip/ccipevm/helpers.go b/core/capabilities/ccip/ccipevm/helpers.go new file mode 100644 index 0000000000..ee83230a4c --- /dev/null +++ b/core/capabilities/ccip/ccipevm/helpers.go @@ -0,0 +1,33 @@ +package ccipevm + +import ( + "bytes" + "fmt" + "math/big" +) + +func decodeExtraArgsV1V2(extraArgs []byte) (gasLimit *big.Int, err error) { + if len(extraArgs) < 4 { + return nil, fmt.Errorf("extra args too short: %d, should be at least 4 (i.e the extraArgs tag)", len(extraArgs)) + } + + var method string + if bytes.Equal(extraArgs[:4], evmExtraArgsV1Tag) { + method = "decodeEVMExtraArgsV1" + } else if bytes.Equal(extraArgs[:4], evmExtraArgsV2Tag) { + method = "decodeEVMExtraArgsV2" + } else { + return nil, fmt.Errorf("unknown extra args tag: %x", extraArgs) + } + ifaces, err := messageHasherABI.Methods[method].Inputs.UnpackValues(extraArgs[4:]) + if err != nil { + return nil, fmt.Errorf("abi decode extra args v1: %w", err) + } + // gas limit is always the first argument, and allow OOO isn't set explicitly + // on the message. + _, ok := ifaces[0].(*big.Int) + if !ok { + return nil, fmt.Errorf("expected *big.Int, got %T", ifaces[0]) + } + return ifaces[0].(*big.Int), nil +} diff --git a/core/capabilities/ccip/ccipevm/helpers_test.go b/core/capabilities/ccip/ccipevm/helpers_test.go new file mode 100644 index 0000000000..95a5d4439b --- /dev/null +++ b/core/capabilities/ccip/ccipevm/helpers_test.go @@ -0,0 +1,41 @@ +package ccipevm + +import ( + "math/big" + "math/rand" + "testing" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/message_hasher" + + "github.com/stretchr/testify/require" +) + +func Test_decodeExtraArgs(t *testing.T) { + d := testSetup(t) + gasLimit := big.NewInt(rand.Int63()) + + t.Run("v1", func(t *testing.T) { + encoded, err := d.contract.EncodeEVMExtraArgsV1(nil, message_hasher.ClientEVMExtraArgsV1{ + GasLimit: gasLimit, + }) + require.NoError(t, err) + + decodedGasLimit, err := decodeExtraArgsV1V2(encoded) + require.NoError(t, err) + + require.Equal(t, gasLimit, decodedGasLimit) + }) + + t.Run("v2", func(t *testing.T) { + encoded, err := d.contract.EncodeEVMExtraArgsV2(nil, message_hasher.ClientEVMExtraArgsV2{ + GasLimit: gasLimit, + AllowOutOfOrderExecution: true, + }) + require.NoError(t, err) + + decodedGasLimit, err := decodeExtraArgsV1V2(encoded) + require.NoError(t, err) + + require.Equal(t, gasLimit, decodedGasLimit) + }) +} diff --git a/core/capabilities/ccip/ccipevm/msghasher.go b/core/capabilities/ccip/ccipevm/msghasher.go new file mode 100644 index 0000000000..0df0a8254a --- /dev/null +++ b/core/capabilities/ccip/ccipevm/msghasher.go @@ -0,0 +1,127 @@ +package ccipevm + +import ( + "context" + "fmt" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/message_hasher" +) + +var ( + // bytes32 internal constant LEAF_DOMAIN_SEPARATOR = 0x0000000000000000000000000000000000000000000000000000000000000000; + leafDomainSeparator = [32]byte{} + + // bytes32 internal constant ANY_2_EVM_MESSAGE_HASH = keccak256("Any2EVMMessageHashV1"); + ANY_2_EVM_MESSAGE_HASH = utils.Keccak256Fixed([]byte("Any2EVMMessageHashV1")) + + messageHasherABI = types.MustGetABI(message_hasher.MessageHasherABI) + + // bytes4 public constant EVM_EXTRA_ARGS_V1_TAG = 0x97a657c9; + evmExtraArgsV1Tag = hexutil.MustDecode("0x97a657c9") + + // bytes4 public constant EVM_EXTRA_ARGS_V2_TAG = 0x181dcf10; + evmExtraArgsV2Tag = hexutil.MustDecode("0x181dcf10") +) + +// MessageHasherV1 implements the MessageHasher interface. +// Compatible with: +// - "EVM2EVMMultiOnRamp 1.6.0-dev" +type MessageHasherV1 struct{} + +func NewMessageHasherV1() *MessageHasherV1 { + return &MessageHasherV1{} +} + +// Hash implements the MessageHasher interface. +// It constructs all of the inputs to the final keccak256 hash in Internal._hash(Any2EVMRampMessage). +// The main structure of the hash is as follows: +/* + keccak256( + leafDomainSeparator, + keccak256(any_2_evm_message_hash, header.sourceChainSelector, header.destinationChainSelector, onRamp), + keccak256(fixedSizeMessageFields), + keccak256(messageData), + keccak256(encodedRampTokenAmounts), + ) +*/ +func (h *MessageHasherV1) Hash(_ context.Context, msg cciptypes.Message) (cciptypes.Bytes32, error) { + var rampTokenAmounts []message_hasher.InternalRampTokenAmount + for _, rta := range msg.TokenAmounts { + rampTokenAmounts = append(rampTokenAmounts, message_hasher.InternalRampTokenAmount{ + SourcePoolAddress: rta.SourcePoolAddress, + DestTokenAddress: rta.DestTokenAddress, + ExtraData: rta.ExtraData, + Amount: rta.Amount.Int, + }) + } + encodedRampTokenAmounts, err := abiEncode("encodeTokenAmountsHashPreimage", rampTokenAmounts) + if err != nil { + return [32]byte{}, fmt.Errorf("abi encode token amounts: %w", err) + } + + metaDataHashInput, err := abiEncode( + "encodeMetadataHashPreimage", + ANY_2_EVM_MESSAGE_HASH, + uint64(msg.Header.SourceChainSelector), + uint64(msg.Header.DestChainSelector), + []byte(msg.Header.OnRamp), + ) + if err != nil { + return [32]byte{}, fmt.Errorf("abi encode metadata hash input: %w", err) + } + + // Need to decode the extra args to get the gas limit. + // TODO: we assume that extra args is always abi-encoded for now, but we need + // to decode according to source chain selector family. We should add a family + // lookup API to the chain-selectors library. + gasLimit, err := decodeExtraArgsV1V2(msg.ExtraArgs) + if err != nil { + return [32]byte{}, fmt.Errorf("decode extra args: %w", err) + } + + fixedSizeFieldsEncoded, err := abiEncode( + "encodeFixedSizeFieldsHashPreimage", + msg.Header.MessageID, + []byte(msg.Sender), + common.BytesToAddress(msg.Receiver), + uint64(msg.Header.SequenceNumber), + gasLimit, + msg.Header.Nonce, + ) + if err != nil { + return [32]byte{}, fmt.Errorf("abi encode fixed size values: %w", err) + } + + packedValues, err := abiEncode( + "encodeFinalHashPreimage", + leafDomainSeparator, + utils.Keccak256Fixed(metaDataHashInput), + utils.Keccak256Fixed(fixedSizeFieldsEncoded), + utils.Keccak256Fixed(msg.Data), + utils.Keccak256Fixed(encodedRampTokenAmounts), + ) + if err != nil { + return [32]byte{}, fmt.Errorf("abi encode packed values: %w", err) + } + + return utils.Keccak256Fixed(packedValues), nil +} + +func abiEncode(method string, values ...interface{}) ([]byte, error) { + res, err := messageHasherABI.Pack(method, values...) + if err != nil { + return nil, err + } + // trim the method selector. + return res[4:], nil +} + +// Interface compliance check +var _ cciptypes.MessageHasher = (*MessageHasherV1)(nil) diff --git a/core/capabilities/ccip/ccipevm/msghasher_test.go b/core/capabilities/ccip/ccipevm/msghasher_test.go new file mode 100644 index 0000000000..911a10b26a --- /dev/null +++ b/core/capabilities/ccip/ccipevm/msghasher_test.go @@ -0,0 +1,189 @@ +package ccipevm + +import ( + "context" + cryptorand "crypto/rand" + "fmt" + "math/big" + "math/rand" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/stretchr/testify/require" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/message_hasher" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" +) + +// NOTE: these test cases are only EVM <-> EVM. +// Update these cases once we have non-EVM examples. +func TestMessageHasher_EVM2EVM(t *testing.T) { + ctx := testutils.Context(t) + d := testSetup(t) + + testCases := []evmExtraArgs{ + {version: "v1", gasLimit: big.NewInt(rand.Int63())}, + {version: "v2", gasLimit: big.NewInt(rand.Int63()), allowOOO: false}, + {version: "v2", gasLimit: big.NewInt(rand.Int63()), allowOOO: true}, + } + for i, tc := range testCases { + t.Run(fmt.Sprintf("tc_%d", i), func(tt *testing.T) { + testHasherEVM2EVM(ctx, tt, d, tc) + }) + } +} + +func testHasherEVM2EVM(ctx context.Context, t *testing.T, d *testSetupData, evmExtraArgs evmExtraArgs) { + ccipMsg := createEVM2EVMMessage(t, d.contract, evmExtraArgs) + + var tokenAmounts []message_hasher.InternalRampTokenAmount + for _, rta := range ccipMsg.TokenAmounts { + tokenAmounts = append(tokenAmounts, message_hasher.InternalRampTokenAmount{ + SourcePoolAddress: rta.SourcePoolAddress, + DestTokenAddress: rta.DestTokenAddress, + ExtraData: rta.ExtraData[:], + Amount: rta.Amount.Int, + }) + } + evmMsg := message_hasher.InternalAny2EVMRampMessage{ + Header: message_hasher.InternalRampMessageHeader{ + MessageId: ccipMsg.Header.MessageID, + SourceChainSelector: uint64(ccipMsg.Header.SourceChainSelector), + DestChainSelector: uint64(ccipMsg.Header.DestChainSelector), + SequenceNumber: uint64(ccipMsg.Header.SequenceNumber), + Nonce: ccipMsg.Header.Nonce, + }, + Sender: ccipMsg.Sender, + Receiver: common.BytesToAddress(ccipMsg.Receiver), + GasLimit: evmExtraArgs.gasLimit, + Data: ccipMsg.Data, + TokenAmounts: tokenAmounts, + } + + expectedHash, err := d.contract.Hash(&bind.CallOpts{Context: ctx}, evmMsg, ccipMsg.Header.OnRamp) + require.NoError(t, err) + + evmMsgHasher := NewMessageHasherV1() + actualHash, err := evmMsgHasher.Hash(ctx, ccipMsg) + require.NoError(t, err) + + require.Equal(t, fmt.Sprintf("%x", expectedHash), strings.TrimPrefix(actualHash.String(), "0x")) +} + +type evmExtraArgs struct { + version string + gasLimit *big.Int + allowOOO bool +} + +func createEVM2EVMMessage(t *testing.T, messageHasher *message_hasher.MessageHasher, evmExtraArgs evmExtraArgs) cciptypes.Message { + messageID := utils.RandomBytes32() + + sourceTokenData := make([]byte, rand.Intn(2048)) + _, err := cryptorand.Read(sourceTokenData) + require.NoError(t, err) + + sourceChain := rand.Uint64() + seqNum := rand.Uint64() + nonce := rand.Uint64() + destChain := rand.Uint64() + + var extraArgsBytes []byte + if evmExtraArgs.version == "v1" { + extraArgsBytes, err = messageHasher.EncodeEVMExtraArgsV1(nil, message_hasher.ClientEVMExtraArgsV1{ + GasLimit: evmExtraArgs.gasLimit, + }) + require.NoError(t, err) + } else if evmExtraArgs.version == "v2" { + extraArgsBytes, err = messageHasher.EncodeEVMExtraArgsV2(nil, message_hasher.ClientEVMExtraArgsV2{ + GasLimit: evmExtraArgs.gasLimit, + AllowOutOfOrderExecution: evmExtraArgs.allowOOO, + }) + require.NoError(t, err) + } else { + require.FailNowf(t, "unknown extra args version", "version: %s", evmExtraArgs.version) + } + + messageData := make([]byte, rand.Intn(2048)) + _, err = cryptorand.Read(messageData) + require.NoError(t, err) + + numTokens := rand.Intn(10) + var sourceTokenDatas [][]byte + for i := 0; i < numTokens; i++ { + sourceTokenDatas = append(sourceTokenDatas, sourceTokenData) + } + + var tokenAmounts []cciptypes.RampTokenAmount + for i := 0; i < len(sourceTokenDatas); i++ { + extraData := utils.RandomBytes32() + tokenAmounts = append(tokenAmounts, cciptypes.RampTokenAmount{ + SourcePoolAddress: abiEncodedAddress(t), + DestTokenAddress: abiEncodedAddress(t), + ExtraData: extraData[:], + Amount: cciptypes.NewBigInt(big.NewInt(0).SetUint64(rand.Uint64())), + }) + } + + return cciptypes.Message{ + Header: cciptypes.RampMessageHeader{ + MessageID: messageID, + SourceChainSelector: cciptypes.ChainSelector(sourceChain), + DestChainSelector: cciptypes.ChainSelector(destChain), + SequenceNumber: cciptypes.SeqNum(seqNum), + Nonce: nonce, + OnRamp: abiEncodedAddress(t), + }, + Sender: abiEncodedAddress(t), + Receiver: abiEncodedAddress(t), + Data: messageData, + TokenAmounts: tokenAmounts, + FeeToken: abiEncodedAddress(t), + FeeTokenAmount: cciptypes.NewBigInt(big.NewInt(0).SetUint64(rand.Uint64())), + ExtraArgs: extraArgsBytes, + } +} + +func abiEncodedAddress(t *testing.T) []byte { + addr := utils.RandomAddress() + encoded, err := utils.ABIEncode(`[{"type": "address"}]`, addr) + require.NoError(t, err) + return encoded +} + +type testSetupData struct { + contractAddr common.Address + contract *message_hasher.MessageHasher + sb *backends.SimulatedBackend + auth *bind.TransactOpts +} + +func testSetup(t *testing.T) *testSetupData { + transactor := testutils.MustNewSimTransactor(t) + simulatedBackend := backends.NewSimulatedBackend(core.GenesisAlloc{ + transactor.From: {Balance: assets.Ether(1000).ToInt()}, + }, 30e6) + + // Deploy the contract + address, _, _, err := message_hasher.DeployMessageHasher(transactor, simulatedBackend) + require.NoError(t, err) + simulatedBackend.Commit() + + // Setup contract client + contract, err := message_hasher.NewMessageHasher(address, simulatedBackend) + require.NoError(t, err) + + return &testSetupData{ + contractAddr: address, + contract: contract, + sb: simulatedBackend, + auth: transactor, + } +} diff --git a/core/capabilities/ccip/common/common.go b/core/capabilities/ccip/common/common.go new file mode 100644 index 0000000000..6409345ed9 --- /dev/null +++ b/core/capabilities/ccip/common/common.go @@ -0,0 +1,23 @@ +package common + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/crypto" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" +) + +// HashedCapabilityID returns the hashed capability id in a manner equivalent to the capability registry. +func HashedCapabilityID(capabilityLabelledName, capabilityVersion string) (r [32]byte, err error) { + // TODO: investigate how to avoid parsing the ABI everytime. + tabi := `[{"type": "string"}, {"type": "string"}]` + abiEncoded, err := utils.ABIEncode(tabi, capabilityLabelledName, capabilityVersion) + if err != nil { + return r, fmt.Errorf("failed to ABI encode capability version and labelled name: %w", err) + } + + h := crypto.Keccak256(abiEncoded) + copy(r[:], h) + return r, nil +} diff --git a/core/capabilities/ccip/common/common_test.go b/core/capabilities/ccip/common/common_test.go new file mode 100644 index 0000000000..a7484a83ad --- /dev/null +++ b/core/capabilities/ccip/common/common_test.go @@ -0,0 +1,51 @@ +package common_test + +import ( + "testing" + + capcommon "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/common" + + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" +) + +func Test_HashedCapabilityId(t *testing.T) { + transactor := testutils.MustNewSimTransactor(t) + sb := backends.NewSimulatedBackend(core.GenesisAlloc{ + transactor.From: {Balance: assets.Ether(1000).ToInt()}, + }, 30e6) + + crAddress, _, _, err := kcr.DeployCapabilitiesRegistry(transactor, sb) + require.NoError(t, err) + sb.Commit() + + cr, err := kcr.NewCapabilitiesRegistry(crAddress, sb) + require.NoError(t, err) + + // add a capability, ignore cap config for simplicity. + _, err = cr.AddCapabilities(transactor, []kcr.CapabilitiesRegistryCapability{ + { + LabelledName: "ccip", + Version: "v1.0.0", + CapabilityType: 0, + ResponseType: 0, + ConfigurationContract: common.Address{}, + }, + }) + require.NoError(t, err) + sb.Commit() + + hidExpected, err := cr.GetHashedCapabilityId(nil, "ccip", "v1.0.0") + require.NoError(t, err) + + hid, err := capcommon.HashedCapabilityID("ccip", "v1.0.0") + require.NoError(t, err) + + require.Equal(t, hidExpected, hid) +} diff --git a/core/capabilities/ccip/configs/evm/chain_writer.go b/core/capabilities/ccip/configs/evm/chain_writer.go new file mode 100644 index 0000000000..6d3b73c6f5 --- /dev/null +++ b/core/capabilities/ccip/configs/evm/chain_writer.go @@ -0,0 +1,75 @@ +package evm + +import ( + "encoding/json" + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink-ccip/pkg/consts" + "github.com/smartcontractkit/chainlink/v2/common/txmgr" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" +) + +var ( + offrampABI = evmtypes.MustGetABI(evm_2_evm_multi_offramp.EVM2EVMMultiOffRampABI) +) + +func MustChainWriterConfig( + fromAddress common.Address, + maxGasPrice *assets.Wei, + commitGasLimit, + execBatchGasLimit uint64, +) []byte { + rawConfig := ChainWriterConfigRaw(fromAddress, maxGasPrice, commitGasLimit, execBatchGasLimit) + encoded, err := json.Marshal(rawConfig) + if err != nil { + panic(fmt.Errorf("failed to marshal ChainWriterConfig: %w", err)) + } + + return encoded +} + +// ChainWriterConfigRaw returns a ChainWriterConfig that can be used to transmit commit and execute reports. +func ChainWriterConfigRaw( + fromAddress common.Address, + maxGasPrice *assets.Wei, + commitGasLimit, + execBatchGasLimit uint64, +) evmrelaytypes.ChainWriterConfig { + return evmrelaytypes.ChainWriterConfig{ + Contracts: map[string]*evmrelaytypes.ContractConfig{ + consts.ContractNameOffRamp: { + ContractABI: evm_2_evm_multi_offramp.EVM2EVMMultiOffRampABI, + Configs: map[string]*evmrelaytypes.ChainWriterDefinition{ + consts.MethodCommit: { + ChainSpecificName: mustGetMethodName("commit", offrampABI), + FromAddress: fromAddress, + GasLimit: commitGasLimit, + }, + consts.MethodExecute: { + ChainSpecificName: mustGetMethodName("execute", offrampABI), + FromAddress: fromAddress, + GasLimit: execBatchGasLimit, + }, + }, + }, + }, + SendStrategy: txmgr.NewSendEveryStrategy(), + MaxGasPrice: maxGasPrice, + } +} + +// mustGetMethodName panics if the method name is not found in the provided ABI. +func mustGetMethodName(name string, tabi abi.ABI) (methodName string) { + m, ok := tabi.Methods[name] + if !ok { + panic(fmt.Sprintf("missing method %s in the abi", name)) + } + return m.Name +} diff --git a/core/capabilities/ccip/configs/evm/contract_reader.go b/core/capabilities/ccip/configs/evm/contract_reader.go new file mode 100644 index 0000000000..085729690d --- /dev/null +++ b/core/capabilities/ccip/configs/evm/contract_reader.go @@ -0,0 +1,219 @@ +package evm + +import ( + "encoding/json" + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" + + "github.com/smartcontractkit/chainlink-ccip/pkg/consts" + + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" +) + +var ( + onrampABI = evmtypes.MustGetABI(evm_2_evm_multi_onramp.EVM2EVMMultiOnRampABI) + capabilitiesRegsitryABI = evmtypes.MustGetABI(kcr.CapabilitiesRegistryABI) + ccipConfigABI = evmtypes.MustGetABI(ccip_config.CCIPConfigABI) + priceRegistryABI = evmtypes.MustGetABI(price_registry.PriceRegistryABI) +) + +// MustSourceReaderConfig returns a ChainReaderConfig that can be used to read from the onramp. +// The configuration is marshaled into JSON so that it can be passed to the relayer NewContractReader() method. +func MustSourceReaderConfig() []byte { + rawConfig := SourceReaderConfig() + encoded, err := json.Marshal(rawConfig) + if err != nil { + panic(fmt.Errorf("failed to marshal ChainReaderConfig into JSON: %w", err)) + } + + return encoded +} + +// MustDestReaderConfig returns a ChainReaderConfig that can be used to read from the offramp. +// The configuration is marshaled into JSON so that it can be passed to the relayer NewContractReader() method. +func MustDestReaderConfig() []byte { + rawConfig := DestReaderConfig() + encoded, err := json.Marshal(rawConfig) + if err != nil { + panic(fmt.Errorf("failed to marshal ChainReaderConfig into JSON: %w", err)) + } + + return encoded +} + +// DestReaderConfig returns a ChainReaderConfig that can be used to read from the offramp. +func DestReaderConfig() evmrelaytypes.ChainReaderConfig { + return evmrelaytypes.ChainReaderConfig{ + Contracts: map[string]evmrelaytypes.ChainContractReader{ + consts.ContractNameOffRamp: { + ContractABI: evm_2_evm_multi_offramp.EVM2EVMMultiOffRampABI, + ContractPollingFilter: evmrelaytypes.ContractPollingFilter{ + GenericEventNames: []string{ + mustGetEventName(consts.EventNameExecutionStateChanged, offrampABI), + mustGetEventName(consts.EventNameCommitReportAccepted, offrampABI), + }, + }, + Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ + consts.MethodNameGetExecutionState: { + ChainSpecificName: mustGetMethodName("getExecutionState", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameGetMerkleRoot: { + ChainSpecificName: mustGetMethodName("getMerkleRoot", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameIsBlessed: { + ChainSpecificName: mustGetMethodName("isBlessed", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameGetLatestPriceSequenceNumber: { + ChainSpecificName: mustGetMethodName("getLatestPriceSequenceNumber", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameOfframpGetStaticConfig: { + ChainSpecificName: mustGetMethodName("getStaticConfig", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameOfframpGetDynamicConfig: { + ChainSpecificName: mustGetMethodName("getDynamicConfig", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameGetSourceChainConfig: { + ChainSpecificName: mustGetMethodName("getSourceChainConfig", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.EventNameCommitReportAccepted: { + ChainSpecificName: mustGetEventName(consts.EventNameCommitReportAccepted, offrampABI), + ReadType: evmrelaytypes.Event, + }, + consts.EventNameExecutionStateChanged: { + ChainSpecificName: mustGetEventName(consts.EventNameExecutionStateChanged, offrampABI), + ReadType: evmrelaytypes.Event, + }, + }, + }, + }, + } +} + +// SourceReaderConfig returns a ChainReaderConfig that can be used to read from the onramp. +func SourceReaderConfig() evmrelaytypes.ChainReaderConfig { + return evmrelaytypes.ChainReaderConfig{ + Contracts: map[string]evmrelaytypes.ChainContractReader{ + consts.ContractNameOnRamp: { + ContractABI: evm_2_evm_multi_onramp.EVM2EVMMultiOnRampABI, + ContractPollingFilter: evmrelaytypes.ContractPollingFilter{ + GenericEventNames: []string{ + mustGetEventName(consts.EventNameCCIPSendRequested, onrampABI), + }, + }, + Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ + // all "{external|public} view" functions in the onramp except for getFee and getPoolBySourceToken are here. + // getFee is not expected to get called offchain and is only called by end-user contracts. + consts.MethodNameGetExpectedNextSequenceNumber: { + ChainSpecificName: mustGetMethodName("getExpectedNextSequenceNumber", onrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameOnrampGetStaticConfig: { + ChainSpecificName: mustGetMethodName("getStaticConfig", onrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameOnrampGetDynamicConfig: { + ChainSpecificName: mustGetMethodName("getDynamicConfig", onrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.EventNameCCIPSendRequested: { + ChainSpecificName: mustGetEventName(consts.EventNameCCIPSendRequested, onrampABI), + ReadType: evmrelaytypes.Event, + EventDefinitions: &evmrelaytypes.EventDefinitions{ + GenericDataWordNames: map[string]uint8{ + consts.EventAttributeSequenceNumber: 5, + }, + }, + }, + }, + }, + consts.ContractNamePriceRegistry: { + ContractABI: price_registry.PriceRegistryABI, + Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ + // TODO: update with the consts from https://github.com/smartcontractkit/chainlink-ccip/pull/39 + // in a followup. + "GetStaticConfig": { + ChainSpecificName: mustGetMethodName("getStaticConfig", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "GetDestChainConfig": { + ChainSpecificName: mustGetMethodName("getDestChainConfig", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "GetPremiumMultiplierWeiPerEth": { + ChainSpecificName: mustGetMethodName("getPremiumMultiplierWeiPerEth", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "GetTokenTransferFeeConfig": { + ChainSpecificName: mustGetMethodName("getTokenTransferFeeConfig", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "ProcessMessageArgs": { + ChainSpecificName: mustGetMethodName("processMessageArgs", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "ValidatePoolReturnData": { + ChainSpecificName: mustGetMethodName("validatePoolReturnData", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "GetValidatedTokenPrice": { + ChainSpecificName: mustGetMethodName("getValidatedTokenPrice", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "GetFeeTokens": { + ChainSpecificName: mustGetMethodName("getFeeTokens", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + }, + }, + }, + } +} + +// HomeChainReaderConfigRaw returns a ChainReaderConfig that can be used to read from the home chain. +func HomeChainReaderConfigRaw() evmrelaytypes.ChainReaderConfig { + return evmrelaytypes.ChainReaderConfig{ + Contracts: map[string]evmrelaytypes.ChainContractReader{ + consts.ContractNameCapabilitiesRegistry: { + ContractABI: kcr.CapabilitiesRegistryABI, + Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ + consts.MethodNameGetCapability: { + ChainSpecificName: mustGetMethodName("getCapability", capabilitiesRegsitryABI), + }, + }, + }, + consts.ContractNameCCIPConfig: { + ContractABI: ccip_config.CCIPConfigABI, + Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ + consts.MethodNameGetAllChainConfigs: { + ChainSpecificName: mustGetMethodName("getAllChainConfigs", ccipConfigABI), + }, + consts.MethodNameGetOCRConfig: { + ChainSpecificName: mustGetMethodName("getOCRConfig", ccipConfigABI), + }, + }, + }, + }, + } +} + +func mustGetEventName(event string, tabi abi.ABI) string { + e, ok := tabi.Events[event] + if !ok { + panic(fmt.Sprintf("missing event %s in onrampABI", event)) + } + return e.Name +} diff --git a/core/capabilities/ccip/delegate.go b/core/capabilities/ccip/delegate.go new file mode 100644 index 0000000000..c9974d62e9 --- /dev/null +++ b/core/capabilities/ccip/delegate.go @@ -0,0 +1,321 @@ +package ccip + +import ( + "context" + "fmt" + "time" + + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/common" + configsevm "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/configs/evm" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/launcher" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/oraclecreator" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" + "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" + + ragep2ptypes "github.com/smartcontractkit/libocr/ragep2p/types" + + "github.com/smartcontractkit/chainlink-ccip/pkg/consts" + ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/config" + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" + "github.com/smartcontractkit/chainlink/v2/plugins" +) + +type RelayGetter interface { + Get(types.RelayID) (loop.Relayer, error) + GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) +} + +type Delegate struct { + lggr logger.Logger + registrarConfig plugins.RegistrarConfig + pipelineRunner pipeline.Runner + chains legacyevm.LegacyChainContainer + relayers RelayGetter + keystore keystore.Master + ds sqlutil.DataSource + peerWrapper *ocrcommon.SingletonPeerWrapper + monitoringEndpointGen telemetry.MonitoringEndpointGenerator + capabilityConfig config.Capabilities + + isNewlyCreatedJob bool +} + +func NewDelegate( + lggr logger.Logger, + registrarConfig plugins.RegistrarConfig, + pipelineRunner pipeline.Runner, + chains legacyevm.LegacyChainContainer, + relayers RelayGetter, + keystore keystore.Master, + ds sqlutil.DataSource, + peerWrapper *ocrcommon.SingletonPeerWrapper, + monitoringEndpointGen telemetry.MonitoringEndpointGenerator, + capabilityConfig config.Capabilities, +) *Delegate { + return &Delegate{ + lggr: lggr, + registrarConfig: registrarConfig, + pipelineRunner: pipelineRunner, + chains: chains, + relayers: relayers, + ds: ds, + keystore: keystore, + peerWrapper: peerWrapper, + monitoringEndpointGen: monitoringEndpointGen, + capabilityConfig: capabilityConfig, + } +} + +func (d *Delegate) JobType() job.Type { + return job.CCIP +} + +func (d *Delegate) BeforeJobCreated(job.Job) { + // This is only called first time the job is created + d.isNewlyCreatedJob = true +} + +func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services []job.ServiceCtx, err error) { + // In general there should only be one P2P key but the node may have multiple. + // The job spec should specify the correct P2P key to use. + peerID, err := p2pkey.MakePeerID(spec.CCIPSpec.P2PKeyID) + if err != nil { + return nil, fmt.Errorf("failed to make peer ID from provided spec p2p id (%s): %w", spec.CCIPSpec.P2PKeyID, err) + } + + p2pID, err := d.keystore.P2P().Get(peerID) + if err != nil { + return nil, fmt.Errorf("failed to get all p2p keys: %w", err) + } + + cfg := d.capabilityConfig + rid := cfg.ExternalRegistry().RelayID() + relayer, err := d.relayers.Get(rid) + if err != nil { + return nil, fmt.Errorf("could not fetch relayer %s configured for capabilities registry: %w", rid, err) + } + registrySyncer, err := registrysyncer.New( + d.lggr, + func() (p2ptypes.PeerID, error) { + return p2ptypes.PeerID(p2pID.PeerID()), nil + }, + relayer, + cfg.ExternalRegistry().Address(), + ) + if err != nil { + return nil, fmt.Errorf("could not configure syncer: %w", err) + } + + ocrKeys, err := d.getOCRKeys(spec.CCIPSpec.OCRKeyBundleIDs) + if err != nil { + return nil, err + } + + transmitterKeys, err := d.getTransmitterKeys(ctx, d.chains) + if err != nil { + return nil, err + } + + bootstrapperLocators, err := ocrcommon.ParseBootstrapPeers(spec.CCIPSpec.P2PV2Bootstrappers) + if err != nil { + return nil, fmt.Errorf("failed to parse bootstrapper locators: %w", err) + } + + // NOTE: we can use the same DB for all plugin instances, + // since all queries are scoped by config digest. + ocrDB := ocr2.NewDB(d.ds, spec.ID, 0, d.lggr) + + homeChainContractReader, err := d.getHomeChainContractReader( + ctx, + d.chains, + spec.CCIPSpec.CapabilityLabelledName, + spec.CCIPSpec.CapabilityVersion) + if err != nil { + return nil, fmt.Errorf("failed to get home chain contract reader: %w", err) + } + + hcr := ccipreaderpkg.NewHomeChainReader( + homeChainContractReader, + d.lggr.Named("HomeChainReader"), + 100*time.Millisecond, + ) + + oracleCreator := oraclecreator.New( + ocrKeys, + transmitterKeys, + d.chains, + d.peerWrapper, + spec.ExternalJobID, + spec.ID, + d.isNewlyCreatedJob, + spec.CCIPSpec.PluginConfig, + ocrDB, + d.lggr, + d.monitoringEndpointGen, + bootstrapperLocators, + hcr, + ) + + capabilityID := fmt.Sprintf("%s@%s", spec.CCIPSpec.CapabilityLabelledName, spec.CCIPSpec.CapabilityVersion) + capLauncher := launcher.New( + capabilityID, + ragep2ptypes.PeerID(p2pID.PeerID()), + d.lggr, + hcr, + oracleCreator, + 12*time.Second, + ) + + // register the capability launcher with the registry syncer + registrySyncer.AddLauncher(capLauncher) + + return []job.ServiceCtx{ + registrySyncer, + hcr, + capLauncher, + }, nil +} + +func (d *Delegate) AfterJobCreated(spec job.Job) {} + +func (d *Delegate) BeforeJobDeleted(spec job.Job) {} + +func (d *Delegate) OnDeleteJob(ctx context.Context, spec job.Job) error { + // TODO: shut down needed services? + return nil +} + +func (d *Delegate) getOCRKeys(ocrKeyBundleIDs job.JSONConfig) (map[string]ocr2key.KeyBundle, error) { + ocrKeys := make(map[string]ocr2key.KeyBundle) + for networkType, bundleIDRaw := range ocrKeyBundleIDs { + if networkType != relay.NetworkEVM { + return nil, fmt.Errorf("unsupported chain type: %s", networkType) + } + + bundleID, ok := bundleIDRaw.(string) + if !ok { + return nil, fmt.Errorf("OCRKeyBundleIDs must be a map of chain types to OCR key bundle IDs, got: %T", bundleIDRaw) + } + + bundle, err2 := d.keystore.OCR2().Get(bundleID) + if err2 != nil { + return nil, fmt.Errorf("OCR key bundle with ID %s not found: %w", bundleID, err2) + } + + ocrKeys[networkType] = bundle + } + return ocrKeys, nil +} + +func (d *Delegate) getTransmitterKeys(ctx context.Context, chains legacyevm.LegacyChainContainer) (map[types.RelayID][]string, error) { + transmitterKeys := make(map[types.RelayID][]string) + for _, chain := range chains.Slice() { + relayID := types.NewRelayID(relay.NetworkEVM, chain.ID().String()) + ethKeys, err2 := d.keystore.Eth().EnabledAddressesForChain(ctx, chain.ID()) + if err2 != nil { + return nil, fmt.Errorf("error getting enabled addresses for chain: %s %w", chain.ID().String(), err2) + } + + transmitterKeys[relayID] = func() (r []string) { + for _, key := range ethKeys { + r = append(r, key.Hex()) + } + return + }() + } + return transmitterKeys, nil +} + +func (d *Delegate) getHomeChainContractReader( + ctx context.Context, + chains legacyevm.LegacyChainContainer, + capabilityLabelledName, + capabilityVersion string, +) (types.ContractReader, error) { + // home chain is where the capability registry is deployed, + // which should be set correctly in toml config. + homeChainRelayID := d.capabilityConfig.ExternalRegistry().RelayID() + homeChain, err := chains.Get(homeChainRelayID.ChainID) + if err != nil { + return nil, fmt.Errorf("home chain relayer not found, chain id: %s, err: %w", homeChainRelayID.String(), err) + } + + reader, err := evm.NewChainReaderService( + context.Background(), + d.lggr, + homeChain.LogPoller(), + homeChain.HeadTracker(), + homeChain.Client(), + configsevm.HomeChainReaderConfigRaw(), + ) + if err != nil { + return nil, fmt.Errorf("failed to create home chain contract reader: %w", err) + } + + reader, err = bindReader(ctx, reader, d.capabilityConfig.ExternalRegistry().Address(), capabilityLabelledName, capabilityVersion) + if err != nil { + return nil, fmt.Errorf("failed to bind home chain contract reader: %w", err) + } + + return reader, nil +} + +func bindReader(ctx context.Context, + reader types.ContractReader, + capRegAddress, + capabilityLabelledName, + capabilityVersion string) (types.ContractReader, error) { + err := reader.Bind(ctx, []types.BoundContract{ + { + Address: capRegAddress, + Name: consts.ContractNameCapabilitiesRegistry, + }, + }) + if err != nil { + return nil, fmt.Errorf("failed to bind home chain contract reader: %w", err) + } + + hid, err := common.HashedCapabilityID(capabilityLabelledName, capabilityVersion) + if err != nil { + return nil, fmt.Errorf("failed to hash capability id: %w", err) + } + + var ccipCapabilityInfo kcr.CapabilitiesRegistryCapabilityInfo + err = reader.GetLatestValue(ctx, consts.ContractNameCapabilitiesRegistry, consts.MethodNameGetCapability, primitives.Unconfirmed, map[string]any{ + "hashedId": hid, + }, &ccipCapabilityInfo) + if err != nil { + return nil, fmt.Errorf("failed to get CCIP capability info from chain reader: %w", err) + } + + // bind the ccip capability configuration contract + err = reader.Bind(ctx, []types.BoundContract{ + { + Address: ccipCapabilityInfo.ConfigurationContract.String(), + Name: consts.ContractNameCCIPConfig, + }, + }) + if err != nil { + return nil, fmt.Errorf("failed to bind CCIP capability configuration contract: %w", err) + } + + return reader, nil +} diff --git a/core/capabilities/ccip/delegate_test.go b/core/capabilities/ccip/delegate_test.go new file mode 100644 index 0000000000..dd8a5124b5 --- /dev/null +++ b/core/capabilities/ccip/delegate_test.go @@ -0,0 +1 @@ +package ccip diff --git a/core/capabilities/ccip/launcher/README.md b/core/capabilities/ccip/launcher/README.md new file mode 100644 index 0000000000..41fbecfdbd --- /dev/null +++ b/core/capabilities/ccip/launcher/README.md @@ -0,0 +1,69 @@ +# CCIP Capability Launcher + +The CCIP capability launcher is responsible for listening to +[Capabilities Registry](../../../../contracts/src/v0.8/keystone/CapabilitiesRegistry.sol) (CR) updates +for the particular CCIP capability (labelled name, version) pair and reacting to them. In +particular, there are three kinds of events that would affect a particular capability: + +1. DON Creation: when `addDON` is called on the CR, the capabilities of this new DON are specified. +If CCIP is one of those capabilities, the launcher will launch a commit and an execution plugin +with the OCR configuration specified in the DON creation process. See +[Types.sol](../../../../contracts/src/v0.8/ccip/capability/libraries/Types.sol) for more details +on what the OCR configuration contains. +2. DON update: when `updateDON` is called on the CR, capabilities of the DON can be updated. In the +CCIP use case specifically, `updateDON` is used to update OCR configuration of that DON. Updates +follow the blue/green deployment pattern (explained in detail below with a state diagram). In this +scenario the launcher must either launch brand new instances of the commit and execution plugins +(in the event a green deployment is made) or promote the currently running green instance to be +the blue instance. +3. DON deletion: when `deleteDON` is called on the CR, the launcher must shut down all running plugins +related to that DON. When a DON is deleted it effectively means that it should no longer function. +DON deletion is permanent. + +## Architecture Diagram + +![CCIP Capability Launcher](ccip_capability_launcher.png) + +The above diagram shows how the CCIP capability launcher interacts with the rest of the components +in the CCIP system. + +The CCIP capability job, which is created on the Chainlink node, will spin up the CCIP capability +launcher alongside the home chain reader, which reads the [CCIPConfig.sol](../../../../contracts/src/v0.8/ccip/capability/CCIPConfig.sol) +contract deployed on the home chain (typically Ethereum Mainnet, though could be "any chain" in theory). + +Injected into the launcher is the [OracleCreator](../types/types.go) object which knows how to spin up CCIP +oracles (both bootstrap and plugin oracles). This is used by the launcher at the appropriate time in order +to create oracle instances but not start them right away. + +After all the required oracles have been created, the launcher will start and shut them down as required +in order to match the configuration that was posted on-chain in the CR and the CCIPConfig.sol contract. + + +## Config State Diagram + +![CCIP Config State Machine](ccip_config_state_machine.png) + +CCIP's blue/green deployment paradigm is intentionally kept as simple as possible. + +Every CCIP DON starts in the `Init` state. Upon DON creation, which must provide a valid OCR +configuration, the CCIP DON will move into the `Running` state. In this state, the DON is +presumed to be fully functional from a configuration standpoint. + +When we want to update configuration, we propose a new configuration to the CR that consists of +an array of two OCR configurations: + +1. The first element of the array is the current OCR configuration that is running (termed "blue"). +2. The second element of the array is the future OCR configuration that we want to run (termed "green"). + +Various checks are done on-chain in order to validate this particular state transition, in particular, +related to config counts. Doing this will move the state of the configuration to the `Staging` state. + +In the `Staging` state, there are effectively four plugins running - one (commit, execution) pair for the +blue configuration, and one (commit, execution) pair for the green configuration. However, only the blue +configuration will actually be writing on-chain, where as the green configuration will be "dry running", +i.e doing everything except transmitting. + +This allows us to test out new configurations without committing to them immediately. + +Finally, from the `Staging` state, there is only one transition, which is to promote the green configuration +to be the new blue configuration, and go back into the `Running` state. diff --git a/core/capabilities/ccip/launcher/bluegreen.go b/core/capabilities/ccip/launcher/bluegreen.go new file mode 100644 index 0000000000..6245846629 --- /dev/null +++ b/core/capabilities/ccip/launcher/bluegreen.go @@ -0,0 +1,178 @@ +package launcher + +import ( + "fmt" + + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + + "go.uber.org/multierr" + + ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" +) + +// blueGreenDeployment represents a blue-green deployment of OCR instances. +type blueGreenDeployment struct { + // blue is the blue OCR instance. + // blue must always be present. + blue cctypes.CCIPOracle + + // bootstrapBlue is the bootstrap node of the blue OCR instance. + // Only a subset of the DON will be running bootstrap instances, + // so this may be nil. + bootstrapBlue cctypes.CCIPOracle + + // green is the green OCR instance. + // green may or may not be present. + // green must never be present if blue is not present. + // TODO: should we enforce this invariant somehow? + green cctypes.CCIPOracle + + // bootstrapGreen is the bootstrap node of the green OCR instance. + // Only a subset of the DON will be running bootstrap instances, + // so this may be nil, even when green is not nil. + bootstrapGreen cctypes.CCIPOracle +} + +// ccipDeployment represents blue-green deployments of both commit and exec +// OCR instances. +type ccipDeployment struct { + commit blueGreenDeployment + exec blueGreenDeployment +} + +// Close shuts down all OCR instances in the deployment. +func (c *ccipDeployment) Close() error { + var err error + + // shutdown blue commit instances. + err = multierr.Append(err, c.commit.blue.Close()) + if c.commit.bootstrapBlue != nil { + err = multierr.Append(err, c.commit.bootstrapBlue.Close()) + } + + // shutdown green commit instances. + if c.commit.green != nil { + err = multierr.Append(err, c.commit.green.Close()) + } + if c.commit.bootstrapGreen != nil { + err = multierr.Append(err, c.commit.bootstrapGreen.Close()) + } + + // shutdown blue exec instances. + err = multierr.Append(err, c.exec.blue.Close()) + if c.exec.bootstrapBlue != nil { + err = multierr.Append(err, c.exec.bootstrapBlue.Close()) + } + + // shutdown green exec instances. + if c.exec.green != nil { + err = multierr.Append(err, c.exec.green.Close()) + } + if c.exec.bootstrapGreen != nil { + err = multierr.Append(err, c.exec.bootstrapGreen.Close()) + } + + return err +} + +// StartBlue starts the blue OCR instances. +func (c *ccipDeployment) StartBlue() error { + var err error + + err = multierr.Append(err, c.commit.blue.Start()) + if c.commit.bootstrapBlue != nil { + err = multierr.Append(err, c.commit.bootstrapBlue.Start()) + } + err = multierr.Append(err, c.exec.blue.Start()) + if c.exec.bootstrapBlue != nil { + err = multierr.Append(err, c.exec.bootstrapBlue.Start()) + } + + return err +} + +// CloseBlue shuts down the blue OCR instances. +func (c *ccipDeployment) CloseBlue() error { + var err error + + err = multierr.Append(err, c.commit.blue.Close()) + if c.commit.bootstrapBlue != nil { + err = multierr.Append(err, c.commit.bootstrapBlue.Close()) + } + err = multierr.Append(err, c.exec.blue.Close()) + if c.exec.bootstrapBlue != nil { + err = multierr.Append(err, c.exec.bootstrapBlue.Close()) + } + + return err +} + +// HandleBlueGreen handles the blue-green deployment transition. +// prevDeployment is the previous deployment state. +// there are two possible cases: +// +// 1. both blue and green are present in prevDeployment, but only blue is present in c. +// this is a promotion of green to blue, so we need to shut down the blue deployment +// and make green the new blue. In this case green is already running, so there's no +// need to start it. However, we need to shut down the blue deployment. +// +// 2. only blue is present in prevDeployment, both blue and green are present in c. +// In this case, blue is already running, so there's no need to start it. We need to +// start green. +func (c *ccipDeployment) HandleBlueGreen(prevDeployment *ccipDeployment) error { + if prevDeployment == nil { + return fmt.Errorf("previous deployment is nil") + } + + var err error + if prevDeployment.commit.green != nil && c.commit.green == nil { + err = multierr.Append(err, prevDeployment.commit.blue.Close()) + if prevDeployment.commit.bootstrapBlue != nil { + err = multierr.Append(err, prevDeployment.commit.bootstrapBlue.Close()) + } + } else if prevDeployment.commit.green == nil && c.commit.green != nil { + err = multierr.Append(err, c.commit.green.Start()) + if c.commit.bootstrapGreen != nil { + err = multierr.Append(err, c.commit.bootstrapGreen.Start()) + } + } else { + return fmt.Errorf("invalid blue-green deployment transition") + } + + if prevDeployment.exec.green != nil && c.exec.green == nil { + err = multierr.Append(err, prevDeployment.exec.blue.Close()) + if prevDeployment.exec.bootstrapBlue != nil { + err = multierr.Append(err, prevDeployment.exec.bootstrapBlue.Close()) + } + } else if prevDeployment.exec.green == nil && c.exec.green != nil { + err = multierr.Append(err, c.exec.green.Start()) + if c.exec.bootstrapGreen != nil { + err = multierr.Append(err, c.exec.bootstrapGreen.Start()) + } + } else { + return fmt.Errorf("invalid blue-green deployment transition") + } + + return err +} + +// HasGreenInstance returns true if the deployment has a green instance for the +// given plugin type. +func (c *ccipDeployment) HasGreenInstance(pluginType cctypes.PluginType) bool { + switch pluginType { + case cctypes.PluginTypeCCIPCommit: + return c.commit.green != nil + case cctypes.PluginTypeCCIPExec: + return c.exec.green != nil + default: + return false + } +} + +func isNewGreenInstance(pluginType cctypes.PluginType, ocrConfigs []ccipreaderpkg.OCR3ConfigWithMeta, prevDeployment ccipDeployment) bool { + return len(ocrConfigs) == 2 && !prevDeployment.HasGreenInstance(pluginType) +} + +func isPromotion(pluginType cctypes.PluginType, ocrConfigs []ccipreaderpkg.OCR3ConfigWithMeta, prevDeployment ccipDeployment) bool { + return len(ocrConfigs) == 1 && prevDeployment.HasGreenInstance(pluginType) +} diff --git a/core/capabilities/ccip/launcher/bluegreen_test.go b/core/capabilities/ccip/launcher/bluegreen_test.go new file mode 100644 index 0000000000..9fd71a0cb4 --- /dev/null +++ b/core/capabilities/ccip/launcher/bluegreen_test.go @@ -0,0 +1,1043 @@ +package launcher + +import ( + "errors" + "testing" + + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + mocktypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types/mocks" + + "github.com/stretchr/testify/require" + + ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" +) + +func Test_ccipDeployment_Close(t *testing.T) { + type args struct { + commitBlue *mocktypes.CCIPOracle + commitBlueBootstrap *mocktypes.CCIPOracle + commitGreen *mocktypes.CCIPOracle + commitGreenBootstrap *mocktypes.CCIPOracle + execBlue *mocktypes.CCIPOracle + execBlueBootstrap *mocktypes.CCIPOracle + execGreen *mocktypes.CCIPOracle + execGreenBootstrap *mocktypes.CCIPOracle + } + tests := []struct { + name string + args args + expect func(t *testing.T, args args) + asserts func(t *testing.T, args args) + wantErr bool + }{ + { + name: "no errors, blue only", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: nil, + commitGreenBootstrap: nil, + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: nil, + execGreenBootstrap: nil, + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Close").Return(nil).Once() + args.execBlue.On("Close").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + }, + wantErr: false, + }, + { + name: "no errors, blue and green", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Close").Return(nil).Once() + args.commitGreen.On("Close").Return(nil).Once() + args.execBlue.On("Close").Return(nil).Once() + args.execGreen.On("Close").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.commitGreen.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + args.execGreen.AssertExpectations(t) + }, + wantErr: false, + }, + { + name: "error on commit blue", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: nil, + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: nil, + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Close").Return(errors.New("failed")).Once() + args.execBlue.On("Close").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + }, + wantErr: true, + }, + { + name: "bootstrap blue also closed", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execBlueBootstrap: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Close").Return(nil).Once() + args.commitBlueBootstrap.On("Close").Return(nil).Once() + args.execBlue.On("Close").Return(nil).Once() + args.execBlueBootstrap.On("Close").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.commitBlueBootstrap.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + args.execBlueBootstrap.AssertExpectations(t) + }, + wantErr: false, + }, + { + name: "bootstrap green also closed", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: mocktypes.NewCCIPOracle(t), + commitGreen: mocktypes.NewCCIPOracle(t), + commitGreenBootstrap: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execBlueBootstrap: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + execGreenBootstrap: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Close").Return(nil).Once() + args.commitBlueBootstrap.On("Close").Return(nil).Once() + args.commitGreen.On("Close").Return(nil).Once() + args.commitGreenBootstrap.On("Close").Return(nil).Once() + args.execBlue.On("Close").Return(nil).Once() + args.execBlueBootstrap.On("Close").Return(nil).Once() + args.execGreen.On("Close").Return(nil).Once() + args.execGreenBootstrap.On("Close").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.commitBlueBootstrap.AssertExpectations(t) + args.commitGreen.AssertExpectations(t) + args.commitGreenBootstrap.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + args.execBlueBootstrap.AssertExpectations(t) + args.execGreen.AssertExpectations(t) + args.execGreenBootstrap.AssertExpectations(t) + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &ccipDeployment{ + commit: blueGreenDeployment{ + blue: tt.args.commitBlue, + }, + exec: blueGreenDeployment{ + blue: tt.args.execBlue, + }, + } + if tt.args.commitGreen != nil { + c.commit.green = tt.args.commitGreen + } + if tt.args.commitBlueBootstrap != nil { + c.commit.bootstrapBlue = tt.args.commitBlueBootstrap + } + if tt.args.commitGreenBootstrap != nil { + c.commit.bootstrapGreen = tt.args.commitGreenBootstrap + } + + if tt.args.execGreen != nil { + c.exec.green = tt.args.execGreen + } + if tt.args.execBlueBootstrap != nil { + c.exec.bootstrapBlue = tt.args.execBlueBootstrap + } + if tt.args.execGreenBootstrap != nil { + c.exec.bootstrapGreen = tt.args.execGreenBootstrap + } + + tt.expect(t, tt.args) + defer tt.asserts(t, tt.args) + err := c.Close() + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func Test_ccipDeployment_StartBlue(t *testing.T) { + type args struct { + commitBlue *mocktypes.CCIPOracle + commitBlueBootstrap *mocktypes.CCIPOracle + execBlue *mocktypes.CCIPOracle + execBlueBootstrap *mocktypes.CCIPOracle + } + tests := []struct { + name string + args args + expect func(t *testing.T, args args) + asserts func(t *testing.T, args args) + wantErr bool + }{ + { + name: "no errors, no bootstrap", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: nil, + execBlueBootstrap: nil, + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Start").Return(nil).Once() + args.execBlue.On("Start").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + }, + wantErr: false, + }, + { + name: "no errors, with bootstrap", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: mocktypes.NewCCIPOracle(t), + execBlueBootstrap: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Start").Return(nil).Once() + args.commitBlueBootstrap.On("Start").Return(nil).Once() + args.execBlue.On("Start").Return(nil).Once() + args.execBlueBootstrap.On("Start").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.commitBlueBootstrap.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + args.execBlueBootstrap.AssertExpectations(t) + }, + wantErr: false, + }, + { + name: "error on commit blue", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: nil, + execBlueBootstrap: nil, + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Start").Return(errors.New("failed")).Once() + args.execBlue.On("Start").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + }, + wantErr: true, + }, + { + name: "error on exec blue", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: nil, + execBlueBootstrap: nil, + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Start").Return(nil).Once() + args.execBlue.On("Start").Return(errors.New("failed")).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + }, + wantErr: true, + }, + { + name: "error on commit blue bootstrap", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: mocktypes.NewCCIPOracle(t), + execBlueBootstrap: nil, + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Start").Return(nil).Once() + args.commitBlueBootstrap.On("Start").Return(errors.New("failed")).Once() + args.execBlue.On("Start").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.commitBlueBootstrap.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + }, + wantErr: true, + }, + { + name: "error on exec blue bootstrap", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: nil, + execBlueBootstrap: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Start").Return(nil).Once() + args.execBlue.On("Start").Return(nil).Once() + args.execBlueBootstrap.On("Start").Return(errors.New("failed")).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + args.execBlueBootstrap.AssertExpectations(t) + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &ccipDeployment{ + commit: blueGreenDeployment{ + blue: tt.args.commitBlue, + }, + exec: blueGreenDeployment{ + blue: tt.args.execBlue, + }, + } + if tt.args.commitBlueBootstrap != nil { + c.commit.bootstrapBlue = tt.args.commitBlueBootstrap + } + if tt.args.execBlueBootstrap != nil { + c.exec.bootstrapBlue = tt.args.execBlueBootstrap + } + + tt.expect(t, tt.args) + defer tt.asserts(t, tt.args) + err := c.StartBlue() + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func Test_ccipDeployment_CloseBlue(t *testing.T) { + type args struct { + commitBlue *mocktypes.CCIPOracle + commitBlueBootstrap *mocktypes.CCIPOracle + execBlue *mocktypes.CCIPOracle + execBlueBootstrap *mocktypes.CCIPOracle + } + tests := []struct { + name string + args args + expect func(t *testing.T, args args) + asserts func(t *testing.T, args args) + wantErr bool + }{ + { + name: "no errors, no bootstrap", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: nil, + execBlueBootstrap: nil, + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Close").Return(nil).Once() + args.execBlue.On("Close").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + }, + wantErr: false, + }, + { + name: "no errors, with bootstrap", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: mocktypes.NewCCIPOracle(t), + execBlueBootstrap: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Close").Return(nil).Once() + args.commitBlueBootstrap.On("Close").Return(nil).Once() + args.execBlue.On("Close").Return(nil).Once() + args.execBlueBootstrap.On("Close").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.commitBlueBootstrap.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + args.execBlueBootstrap.AssertExpectations(t) + }, + wantErr: false, + }, + { + name: "error on commit blue", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: nil, + execBlueBootstrap: nil, + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Close").Return(errors.New("failed")).Once() + args.execBlue.On("Close").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + }, + wantErr: true, + }, + { + name: "error on exec blue", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: nil, + execBlueBootstrap: nil, + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Close").Return(nil).Once() + args.execBlue.On("Close").Return(errors.New("failed")).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + }, + wantErr: true, + }, + { + name: "error on commit blue bootstrap", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: mocktypes.NewCCIPOracle(t), + execBlueBootstrap: nil, + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Close").Return(nil).Once() + args.commitBlueBootstrap.On("Close").Return(errors.New("failed")).Once() + args.execBlue.On("Close").Return(nil).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.commitBlueBootstrap.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + }, + wantErr: true, + }, + { + name: "error on exec blue bootstrap", + args: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: nil, + execBlueBootstrap: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args) { + args.commitBlue.On("Close").Return(nil).Once() + args.execBlue.On("Close").Return(nil).Once() + args.execBlueBootstrap.On("Close").Return(errors.New("failed")).Once() + }, + asserts: func(t *testing.T, args args) { + args.commitBlue.AssertExpectations(t) + args.execBlue.AssertExpectations(t) + args.execBlueBootstrap.AssertExpectations(t) + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &ccipDeployment{ + commit: blueGreenDeployment{ + blue: tt.args.commitBlue, + }, + exec: blueGreenDeployment{ + blue: tt.args.execBlue, + }, + } + if tt.args.commitBlueBootstrap != nil { + c.commit.bootstrapBlue = tt.args.commitBlueBootstrap + } + if tt.args.execBlueBootstrap != nil { + c.exec.bootstrapBlue = tt.args.execBlueBootstrap + } + + tt.expect(t, tt.args) + defer tt.asserts(t, tt.args) + err := c.CloseBlue() + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func Test_ccipDeployment_HandleBlueGreen_PrevDeploymentNil(t *testing.T) { + require.Error(t, (&ccipDeployment{}).HandleBlueGreen(nil)) +} + +func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { + type args struct { + commitBlue *mocktypes.CCIPOracle + commitBlueBootstrap *mocktypes.CCIPOracle + commitGreen *mocktypes.CCIPOracle + commitGreenBootstrap *mocktypes.CCIPOracle + execBlue *mocktypes.CCIPOracle + execBlueBootstrap *mocktypes.CCIPOracle + execGreen *mocktypes.CCIPOracle + execGreenBootstrap *mocktypes.CCIPOracle + } + tests := []struct { + name string + argsPrevDeployment args + argsFutureDeployment args + expect func(t *testing.T, args args, argsPrevDeployment args) + asserts func(t *testing.T, args args, argsPrevDeployment args) + wantErr bool + }{ + { + name: "promotion blue to green, no bootstrap", + argsPrevDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + }, + argsFutureDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: nil, + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: nil, + }, + expect: func(t *testing.T, args args, argsPrevDeployment args) { + argsPrevDeployment.commitBlue.On("Close").Return(nil).Once() + argsPrevDeployment.execBlue.On("Close").Return(nil).Once() + }, + asserts: func(t *testing.T, args args, argsPrevDeployment args) { + argsPrevDeployment.commitBlue.AssertExpectations(t) + argsPrevDeployment.execBlue.AssertExpectations(t) + }, + wantErr: false, + }, + { + name: "promotion blue to green, with bootstrap", + argsPrevDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: mocktypes.NewCCIPOracle(t), + commitGreen: mocktypes.NewCCIPOracle(t), + commitGreenBootstrap: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execBlueBootstrap: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + execGreenBootstrap: mocktypes.NewCCIPOracle(t), + }, + argsFutureDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: mocktypes.NewCCIPOracle(t), + commitGreen: nil, + commitGreenBootstrap: nil, + execBlue: mocktypes.NewCCIPOracle(t), + execBlueBootstrap: mocktypes.NewCCIPOracle(t), + execGreen: nil, + execGreenBootstrap: nil, + }, + expect: func(t *testing.T, args args, argsPrevDeployment args) { + argsPrevDeployment.commitBlue.On("Close").Return(nil).Once() + argsPrevDeployment.commitBlueBootstrap.On("Close").Return(nil).Once() + argsPrevDeployment.execBlue.On("Close").Return(nil).Once() + argsPrevDeployment.execBlueBootstrap.On("Close").Return(nil).Once() + }, + asserts: func(t *testing.T, args args, argsPrevDeployment args) { + argsPrevDeployment.commitBlue.AssertExpectations(t) + argsPrevDeployment.commitBlueBootstrap.AssertExpectations(t) + argsPrevDeployment.execBlue.AssertExpectations(t) + argsPrevDeployment.execBlueBootstrap.AssertExpectations(t) + }, + wantErr: false, + }, + { + name: "new green deployment, no bootstrap", + argsPrevDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: nil, + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: nil, + }, + argsFutureDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args, argsPrevDeployment args) { + args.commitGreen.On("Start").Return(nil).Once() + args.execGreen.On("Start").Return(nil).Once() + }, + asserts: func(t *testing.T, args args, argsPrevDeployment args) { + args.commitGreen.AssertExpectations(t) + args.execGreen.AssertExpectations(t) + }, + wantErr: false, + }, + { + name: "new green deployment, with bootstrap", + argsPrevDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: mocktypes.NewCCIPOracle(t), + commitGreen: nil, + commitGreenBootstrap: nil, + execBlue: mocktypes.NewCCIPOracle(t), + execBlueBootstrap: mocktypes.NewCCIPOracle(t), + execGreen: nil, + execGreenBootstrap: nil, + }, + argsFutureDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: mocktypes.NewCCIPOracle(t), + commitGreen: mocktypes.NewCCIPOracle(t), + commitGreenBootstrap: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execBlueBootstrap: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + execGreenBootstrap: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args, argsPrevDeployment args) { + args.commitGreen.On("Start").Return(nil).Once() + args.commitGreenBootstrap.On("Start").Return(nil).Once() + args.execGreen.On("Start").Return(nil).Once() + args.execGreenBootstrap.On("Start").Return(nil).Once() + }, + asserts: func(t *testing.T, args args, argsPrevDeployment args) { + args.commitGreen.AssertExpectations(t) + args.commitGreenBootstrap.AssertExpectations(t) + args.execGreen.AssertExpectations(t) + args.execGreenBootstrap.AssertExpectations(t) + }, + wantErr: false, + }, + { + name: "error on commit green start", + argsPrevDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: nil, + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: nil, + }, + argsFutureDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args, argsPrevDeployment args) { + args.commitGreen.On("Start").Return(errors.New("failed")).Once() + args.execGreen.On("Start").Return(nil).Once() + }, + asserts: func(t *testing.T, args args, argsPrevDeployment args) { + args.commitGreen.AssertExpectations(t) + args.execGreen.AssertExpectations(t) + }, + wantErr: true, + }, + { + name: "error on exec green start", + argsPrevDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: nil, + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: nil, + }, + argsFutureDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args, argsPrevDeployment args) { + args.commitGreen.On("Start").Return(nil).Once() + args.execGreen.On("Start").Return(errors.New("failed")).Once() + }, + asserts: func(t *testing.T, args args, argsPrevDeployment args) { + args.commitGreen.AssertExpectations(t) + args.execGreen.AssertExpectations(t) + }, + wantErr: true, + }, + { + name: "error on commit green bootstrap start", + argsPrevDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: mocktypes.NewCCIPOracle(t), + commitGreen: nil, + commitGreenBootstrap: nil, + execBlue: mocktypes.NewCCIPOracle(t), + execBlueBootstrap: mocktypes.NewCCIPOracle(t), + execGreen: nil, + execGreenBootstrap: nil, + }, + argsFutureDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitBlueBootstrap: mocktypes.NewCCIPOracle(t), + commitGreen: mocktypes.NewCCIPOracle(t), + commitGreenBootstrap: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execBlueBootstrap: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + execGreenBootstrap: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args, argsPrevDeployment args) { + args.commitGreen.On("Start").Return(nil).Once() + args.commitGreenBootstrap.On("Start").Return(errors.New("failed")).Once() + args.execGreen.On("Start").Return(nil).Once() + args.execGreenBootstrap.On("Start").Return(nil).Once() + }, + asserts: func(t *testing.T, args args, argsPrevDeployment args) { + args.commitGreen.AssertExpectations(t) + args.commitGreenBootstrap.AssertExpectations(t) + args.execGreen.AssertExpectations(t) + args.execGreenBootstrap.AssertExpectations(t) + }, + wantErr: true, + }, + { + name: "invalid blue-green deployment transition commit: both prev and future deployment have green", + argsPrevDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + }, + argsFutureDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args, argsPrevDeployment args) {}, + asserts: func(t *testing.T, args args, argsPrevDeployment args) {}, + wantErr: true, + }, + { + name: "invalid blue-green deployment transition exec: both prev and future deployment have green", + argsPrevDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: nil, + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + }, + argsFutureDeployment: args{ + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: mocktypes.NewCCIPOracle(t), + }, + expect: func(t *testing.T, args args, argsPrevDeployment args) { + args.commitGreen.On("Start").Return(nil).Once() + }, + asserts: func(t *testing.T, args args, argsPrevDeployment args) { + args.commitGreen.AssertExpectations(t) + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + futDeployment := &ccipDeployment{ + commit: blueGreenDeployment{ + blue: tt.argsFutureDeployment.commitBlue, + }, + exec: blueGreenDeployment{ + blue: tt.argsFutureDeployment.execBlue, + }, + } + if tt.argsFutureDeployment.commitGreen != nil { + futDeployment.commit.green = tt.argsFutureDeployment.commitGreen + } + if tt.argsFutureDeployment.commitBlueBootstrap != nil { + futDeployment.commit.bootstrapBlue = tt.argsFutureDeployment.commitBlueBootstrap + } + if tt.argsFutureDeployment.commitGreenBootstrap != nil { + futDeployment.commit.bootstrapGreen = tt.argsFutureDeployment.commitGreenBootstrap + } + if tt.argsFutureDeployment.execGreen != nil { + futDeployment.exec.green = tt.argsFutureDeployment.execGreen + } + if tt.argsFutureDeployment.execBlueBootstrap != nil { + futDeployment.exec.bootstrapBlue = tt.argsFutureDeployment.execBlueBootstrap + } + if tt.argsFutureDeployment.execGreenBootstrap != nil { + futDeployment.exec.bootstrapGreen = tt.argsFutureDeployment.execGreenBootstrap + } + + prevDeployment := &ccipDeployment{ + commit: blueGreenDeployment{ + blue: tt.argsPrevDeployment.commitBlue, + }, + exec: blueGreenDeployment{ + blue: tt.argsPrevDeployment.execBlue, + }, + } + if tt.argsPrevDeployment.commitGreen != nil { + prevDeployment.commit.green = tt.argsPrevDeployment.commitGreen + } + if tt.argsPrevDeployment.commitBlueBootstrap != nil { + prevDeployment.commit.bootstrapBlue = tt.argsPrevDeployment.commitBlueBootstrap + } + if tt.argsPrevDeployment.commitGreenBootstrap != nil { + prevDeployment.commit.bootstrapGreen = tt.argsPrevDeployment.commitGreenBootstrap + } + if tt.argsPrevDeployment.execGreen != nil { + prevDeployment.exec.green = tt.argsPrevDeployment.execGreen + } + if tt.argsPrevDeployment.execBlueBootstrap != nil { + prevDeployment.exec.bootstrapBlue = tt.argsPrevDeployment.execBlueBootstrap + } + if tt.argsPrevDeployment.execGreenBootstrap != nil { + prevDeployment.exec.bootstrapGreen = tt.argsPrevDeployment.execGreenBootstrap + } + + tt.expect(t, tt.argsFutureDeployment, tt.argsPrevDeployment) + defer tt.asserts(t, tt.argsFutureDeployment, tt.argsPrevDeployment) + err := futDeployment.HandleBlueGreen(prevDeployment) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func Test_isNewGreenInstance(t *testing.T) { + type args struct { + pluginType cctypes.PluginType + ocrConfigs []ccipreaderpkg.OCR3ConfigWithMeta + prevDeployment ccipDeployment + } + tests := []struct { + name string + args args + want bool + }{ + { + "prev deployment only blue", + args{ + pluginType: cctypes.PluginTypeCCIPCommit, + ocrConfigs: []ccipreaderpkg.OCR3ConfigWithMeta{ + {}, {}, + }, + prevDeployment: ccipDeployment{ + commit: blueGreenDeployment{ + blue: mocktypes.NewCCIPOracle(t), + }, + }, + }, + true, + }, + { + "green -> blue promotion", + args{ + pluginType: cctypes.PluginTypeCCIPCommit, + ocrConfigs: []ccipreaderpkg.OCR3ConfigWithMeta{ + {}, + }, + prevDeployment: ccipDeployment{ + commit: blueGreenDeployment{ + blue: mocktypes.NewCCIPOracle(t), + green: mocktypes.NewCCIPOracle(t), + }, + }, + }, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := isNewGreenInstance(tt.args.pluginType, tt.args.ocrConfigs, tt.args.prevDeployment) + require.Equal(t, tt.want, got) + }) + } +} + +func Test_isPromotion(t *testing.T) { + type args struct { + pluginType cctypes.PluginType + ocrConfigs []ccipreaderpkg.OCR3ConfigWithMeta + prevDeployment ccipDeployment + } + tests := []struct { + name string + args args + want bool + }{ + { + "prev deployment only blue", + args{ + pluginType: cctypes.PluginTypeCCIPCommit, + ocrConfigs: []ccipreaderpkg.OCR3ConfigWithMeta{ + {}, {}, + }, + prevDeployment: ccipDeployment{ + commit: blueGreenDeployment{ + blue: mocktypes.NewCCIPOracle(t), + }, + }, + }, + false, + }, + { + "green -> blue promotion", + args{ + pluginType: cctypes.PluginTypeCCIPCommit, + ocrConfigs: []ccipreaderpkg.OCR3ConfigWithMeta{ + {}, + }, + prevDeployment: ccipDeployment{ + commit: blueGreenDeployment{ + blue: mocktypes.NewCCIPOracle(t), + green: mocktypes.NewCCIPOracle(t), + }, + }, + }, + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := isPromotion(tt.args.pluginType, tt.args.ocrConfigs, tt.args.prevDeployment); got != tt.want { + t.Errorf("isPromotion() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_ccipDeployment_HasGreenInstance(t *testing.T) { + type fields struct { + commit blueGreenDeployment + exec blueGreenDeployment + } + type args struct { + pluginType cctypes.PluginType + } + tests := []struct { + name string + fields fields + args args + want bool + }{ + { + "commit green present", + fields{ + commit: blueGreenDeployment{ + blue: mocktypes.NewCCIPOracle(t), + green: mocktypes.NewCCIPOracle(t), + }, + }, + args{ + pluginType: cctypes.PluginTypeCCIPCommit, + }, + true, + }, + { + "commit green not present", + fields{ + commit: blueGreenDeployment{ + blue: mocktypes.NewCCIPOracle(t), + }, + }, + args{ + pluginType: cctypes.PluginTypeCCIPCommit, + }, + false, + }, + { + "exec green present", + fields{ + exec: blueGreenDeployment{ + blue: mocktypes.NewCCIPOracle(t), + green: mocktypes.NewCCIPOracle(t), + }, + }, + args{ + pluginType: cctypes.PluginTypeCCIPExec, + }, + true, + }, + { + "exec green not present", + fields{ + exec: blueGreenDeployment{ + blue: mocktypes.NewCCIPOracle(t), + }, + }, + args{ + pluginType: cctypes.PluginTypeCCIPExec, + }, + false, + }, + { + "invalid plugin type", + fields{}, + args{ + pluginType: cctypes.PluginType(100), + }, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &ccipDeployment{} + if tt.fields.commit.blue != nil { + c.commit.blue = tt.fields.commit.blue + } + if tt.fields.commit.green != nil { + c.commit.green = tt.fields.commit.green + } + if tt.fields.exec.blue != nil { + c.exec.blue = tt.fields.exec.blue + } + if tt.fields.exec.green != nil { + c.exec.green = tt.fields.exec.green + } + got := c.HasGreenInstance(tt.args.pluginType) + require.Equal(t, tt.want, got) + }) + } +} diff --git a/core/capabilities/ccip/launcher/ccip_capability_launcher.png b/core/capabilities/ccip/launcher/ccip_capability_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..5e90d5ff7daa3643fde8185f49b4c83840b2c298 GIT binary patch literal 253433 zcmeEubyQSe^e-TaiinB=(kh68lyrkADWPdt&eX*>U#SM;|#EF}#Z;7cnp}@Fc_^KgYnhIE#US zZGQe7&|>^CKLi8gl8}jrh@6Co2$h_*rJ;$r0S1P+Pna@}ihMI+oO(#GkTGTwfiuBl zQ;hq!3NgC;bnZ}NKJsC?qOd&w>6IDL)!dI6w|&X4@ah>oGan#&a{awso{sWp(#!1q z7Ub;yY`gmr_eMPHTszDK2ct-y?A<*aMI0*SNTxu%3kg9|G9N>oF))cS=yJ~uk%8jg z-Xtf-)VXPTq%}H%^|r7QPSv|-bmY!J!Uv%s!k{LZWYePHB$^b#7+2JI$3=I&}# zC#+i-rnYb0Y;023sAN0`&JDe#3SVUHf^;_TL>ms}-t`V;@t?7IcOzLyIPRV|>(tTH z#v{g3?vPuQO1bGTd`0w=ZM>YyWBF+`d=;tS1SwBMg)=W8a4=;J@mVCB-@m!rwDL>@ zM1ebdXn&DYaqoCeMm=LjK8Q}RD_jL%JMv0u=Pp$X{@bvi`um?^j6L~54ILNW zts7n`pS@9czhTm6*Gjl$3t{^VVq3u{Q^D*QSMx8-3snp$^9dK!8(XhWU!AMbI7eA+oD@i zdRJJ2i6t-H9h%%LVS)#U)no`}wsW09l0`K-xO|m=#5=(ucch zW6|b2O@}X{yt!z0*hYbSAO7In7mfoXDRUP4E4)Fm4UBq? zx#xr$W%L46=r?rkGsZr@UERZq&ok` zGGDo^}ji0=!kM~`2%J|d(_ZlX)V z8hq75wg2u;lgae$u0WVD#jVOFvuOg~k9402P2Z?}Oq4s<^0@Z9qwVb|51A*p-#zCa z7LsL&IwWq*n`}OGCRll_op6S@<~<8}>vfwNVq#psug`OBpZd3bk<5LVNs>_;HEvTC zXs72kAQtns+lmK{p=@<8?xhVPZHLVDzLv*o-4cTEfamc1YGd`)&)6cb_`mqo-1Wcn z;!4U@-wOtBR^HUUDX?O)BN)Bv^O*b-`}Z^O`WJeH;Je`a;4@$*#Pz(`fhS~C@5G&{ zT|)5h`_|o>3H6m&k|>v;mFO2ANy3+Gk-RI}F8M|BzT~6i+sO};H6>}^XW!?S-+QV= zs~%F>^y~$N(>W(@C(=?MS5KJq;nVL4D)O%P5bqzfxJq&-2U>?)$FGa3st!IKl;;*z zP2iI))o_YmKRYAVLaE56xU8T;N1#AW_f5h6bIkM7#C0#pWVL6gwEI1-iw{llwk~bm z+ImeV-TN#ot3^IGLoH1$$60zSnMAeic|aP6M3!9E)0Kpw8$|+k`DI}|Qn85wVwKNP zZ=JpOUY?WIFBE+*n%(d`K$C=s-I+}yN-0V>im%NxN}avK*#0|n6nDUrsV>6K;_vNU zWkqk*`qa#`9%Mbw;#ad!Lk&d@We@obbr;bW1(`W4>hLJ>n8%XE&hX&af)-p!blF~U zzY^4Iep`06U$mm1y>qL7W+{9g-dmZrFALHMAnM#=`DD9qjsEQIe z!*Is(Ot!Gk7tGh?UY|e4>Sj(ntFpU{VA*q+?&?UxRql)ooqb{dS&&6ZJPxjid0{zz8lmkz?r=cnC!A$ zk`2QR2rhwN9$~=)QwF$N2*b_r58+D>I@GJ6`Nfj?YA&JL7o$U?O;Nk-WAiV9*``%Ala zy>NSJ1`M*L62H+ayC_#JiS`eJ*r0hJKUmaARhdhP-^dcoh5rHHbN+Nb9%40rR*Laa*WLtBQ8x zMLk7vL3$xUs5X?-;V>$m#o~i%>qu(^rVQrf%UaA;RjtgyOnDC#9dR8A9ra*CxkqwO zI%{?9z} z8XaVOwS|hH{7Er(Am;`rIKIGVvIk&V9yYxiGyD!su5X zxc_RdL%nusW`9i?5ud!Dlq0#?ywR)h$03D?JDqDu%}ghRv3id zA-hXOu_WDWYoK?_Y~D<=uR@d8X{G*Qf4=n6y(Q`;o^N+rNc+_@wet?8o*34*wY+Sp zRP<7mN*}cxw~herW5~SYy*|H zZ%KY$u+uddoC^=0`Iuf?SWB}dj`H6-^lJ5LZ-vDh>{4>E9l-(us@<>h9ir zrUb+M{Q78>#cgdh<;+XB;c*1+VumyZRn$eH3R)pe4X>q6RcZU|_k_3kaLfbuqQaxk z9ZJ88=XQU)KSwC8sQIO1r5a;P%hh(E&%F!SQurFENEk{>W6%N5=P|G`Nifa=Pnf`u z04C|LXHm?17-x>#u`n>aO)#*3d?N$=M*j&0e$ahRexC{P!oUIkbq)A&Ou+j2^~KqQ zGe4iP&4G6q!tx>#62NbHeQN^)kd3jWZG^F23ea%DN?g?j1A~wT{evm-oO%ryf51dR z#a2c7DUZIT1*7f@OFaWdM++KV*9NkOBCD!Nv(>tLw-Bvbl3I$j@;e8`$Vun^@VJSc0g~6E{9RXOeYkdvGF_pZOa`n#*5je)g@r3Emlt-z_kesuo*<&Tbh zOlaDF`&nLL(N0Dc27L;u0z0RFmn@*8-@d=u3Z ze;xpa5QfBKVFgFbWtBHOi!5t#Cc@kI6#w7j98q5n8`}^}XPySGO;6C^+Ak zR=k3JT><-kmx7#d-K)lLD9nN8N+ZX;w=hc+a zQ$?1;1$bF$e|9zgh*j^7T?HR)KI<_@n|*$!Snk@lyFyg79^`u$AajpRh|xJgaqI*4 z^nP^i&5l6)$lcYdI@{Cljop%AD(9c6LSsp+SEbSmCXu+m+C50HC2LFA&ytZmlvC~| zGmWgOJ;?+9;BKcsHpzNNeB0ZshUA`2qh&oge8e`O;R7A~Bh<)}2$6Fu$U zf}LGu^c-f}kzvs2dvxBp6;qus5L!s-q3*4Q1+sD9>k~U28er2>*-IUG*&%jY z{7*zCs9sc1YTm-PY+Gkhzy6EY#}6vWLVL(F3rea_`o{<|L)s+%1XW^6bwcelS-qRLF#@Ulx`o(G33Wd$g>$(5#z+XP>S|>Ds+>HYnnj zFk`a6ScWZ$Eh-yHK&!#d!8=Ln%6bv+ufgWggB_lKddim?9IWzKzWmNBty`jh5`c-7 zK_JKOVE3q<;E!oM8mvjk4i+1Gj!dD4ICaE1xr?co*|0*f(we z&eqF;j^Ekd(1vKhR8R9R*QDo!J%Wd5!xVd zG+c-6%+AQ(Alx3gbFSf*hzm#c6Sb?y^BaG~N>;Q%#Xcf{$fby$vJH(-Ng-zF6Mm52 zFFqKjW7X?qQ}PZf#0NVauM!ih_rk&9$NS*=6@rVYWp*Z{$T-2wGEm@;w_Eq*4tURg zfjK|sVEYpipI^V!0g>n0{u-Q0juI=m*8BBD4~~kXL4dtle2OSvVBPS`sIo@9Mtnw!ZHXUr8n0uy zJKCCRY|nu`or=}mD;*EIP*Ddl(!s~9X5$3JH@p2f%li+`_t^o>cBl(cfO@7v!W>MLZQK$!UE}(@7@b#(Zj9M<8GrQL*w^~mk(_w&KU#=IH zcD1!RpCDL=VBtdezkQ$PU8g3m)B@1!NBK0tKY}=bB ziwVB)zztc+wU)L#ds;bWIdW!Y$++k!p(w{pNl5@aQKb+jyL13N}*Xfq&Vk0 z8#c*ar7=kc2QI+ILNb81@Quu@_kWU%hbDQ7`vc8Sl7(2&#<>B%zv~2LXK)piax14v zdFus+Efg#ZN)EL{r@VNzn;YB#o_2jyyk64cSI?-SR-S9c?Q*BJu!2I%Dhy5W8mRu6y`edgiWw*j&} z*l!H1OuzG#%HaZ8U0TT*I*8&a3;c6U(==3((Gf}DW8oja%KQlUQCw$d%%8e=BARPH^@0Aa_aceLJFt z-?^dG8}9*s(#Rw1ZSIXPnO!T{!ysa1iUONhgI_q&K9 zsm2%kCi<(foIXyLOn&`F48Beq$MEiGPub{6xV_Uf)iY=b>_WdFL87)}MyEwnO?t^<^y_>n3b%!DuxY@y#{P-`|^B)p$|Yx3$G-?a^* zaP`9jb>2pbVeu%6+5JK zpgSKA1MWP;d`;|=UB=ebVXC2FV+&*YRC}MgZNOL@Us9kly9Sb$w%vyy2U2F9wZdV1 z!y#7i0ngp|t;(5QtsbOCfGpYw*%1-*>&nCcJAkjAbhCXU9XEc6@`nTy1OVceM0$V3 zI%r-jQUP`g=Yb|#&2_@C{2~~c6eu*^E8iaS^NK|)N!0e~Vc(_3T)D$^Gb{_)(_umG zy*kJ{tlixJ*dzVzSIK$0bH(2?(%lA`#k6?t-hKK(o6CM&%mq*c{0F?+FbVo88JYCS zstvdc*yvglYDpxANVa!@6|eB}(^nEq3iGG)jd=(3H$3|GjTL4|pjrIeYvQUybHT1{$(w z1LXlusEA=}MU_zd6z(IeEVK1crQw`` zi764z0L?u+zmYv<8g2CzUvIO6ry{wWf^0N~ZR#X0mot5@zIN^zfI8mByDZ4-1S&MC zgrF_@Yr!zuYMGRj?=O;JV%H6u7y$D1s+sG1$> zw=OMs9d*$*qiOb+&xEGORUd387?0U+31%N=C;84lad*5QPBT%ySX_%7ejvkN;%=9^ zXuCW^{rDhsxUtdwZd+TnR7NnIbLS3X3k6k4yKUN+MnUStLzwzu`a!79Y)B-Fkwis& zVL2`4bh?a1q7*}|e?6E^aH*Clr!-|^jdEoDIme7P8RzFKhHaO7M5bQaQ23N?L=cJ! z?4hF!`~lMBgNwBX9pObzh^%k%zHG$tAX2+Aszcj8u|$z|yYB#8?)a z8dAR`@LRUlL-b0?>W8BSe8~PI!r2Uyi_svM0EpWSN+JR=G2ZNQfBJS99{;@i${+&e zFv7;TGg&+c(In**SW`P#5A?~XSVlXe`|*p_eVBcUqe;^*v;ymI5izP#R8w$sgUGp) zhm1nKZUzBPfoo4cnusZF%V-qh)Ug#(9S~H_x8qzKXC?!qIcL$!Fq{+AAYddwEH$dC zMZ8xcvey`a95F9~sumxhxVHK`8s>>ceJMzbg7~3h_XOBqbQ2Gh+f01G<3)Ka4=UOX zQ^60vXl0NW6xLFtj>c=oQyjsso|y{%$S+m?z9^{F)SQo3_en4(|KJsSgV4{0b8)Fg z4fXD1M1J8F>TQGTA|@q=ow}7%C1>_UmwexV^ec#F3JQ)BD_i#g+ZA8da2kIcN6=<> zfe_vhbR1ZoU^^IX=0Wez0imYQ>kF{m9)GSQ2d2I~NXEqnaU0%5Q=`vVP5Jv)s|(aO zR|id!4^3*2TZ4XyvWojEIZ-Vis@<$4HMXD^=rxr`JPP&Z+fwlZK;*+p4m?nOC!Unh zsDp-2JB!KsN~ABI)|M*AGjrLG=5K%Otw1g6XKPn2HxnZlE0%XP><-2UKn08}E)!jm z1y-u9+V2n4Djreun)+J#4d{@kkD>A~ zes1Lkx!Gq(wAULXxBinWC5{s)qE+=N_Id%cjnaD;SfQXIt@qB?8>8bCoCKCqj^6Ws zn=I{h+m?+(vNv81lvzH&C;LmLYcB^_v}7$L~99{gG#$YJ8S*f`ud*}MFT zkCd(fR@bNQH`9U#btkrb%R>-b@^?Ia&9Z8rhU~w6;>7 z%?7o&i~6t?Rd(Z4%hPK&52r0KlxDK;^g7?({W=} z>uHZ75o@TB4V;Mh`0AYzVnj85L|fYC-r~>#8HigSIuEO|vrFyYQ;7>)cyY*T0C8O+ zlC95o7|Q^I7Fg+&9He>Oz(;LUb+7k&2dW)!TUPHyE!`p#pkOs*V3a9WiXTR<5XKK@ zDEkxl=qDd4!`Sab+{ZG$-@VX13Tdav17DlXg82$3Z0S26SQ0ht?B7rTHtt!SdLo!wAX=o*PcSR->y=7AgymBX|=aOX}j<^Oj)}$jU}HB(=W!!|tCi)B*ef z;lUci@wN~x#{?5}+Ad&DhY)ZEp95;#L(}7Nj>hxC$|%C$=*sTBs9qLps^+s3Cfn-% zu3BA)wGulA4_iqMaEafwjIo(=ZwX8e)9BdkDmIvCXpzjqfq!Rh=Qr0Gw8O7jGmLRU z`R1+>2vTY(u|rcZta!xLo^5)ISx_QrHqtU-nji>Q3rK>TvnNpiGyr$_n&EZqMmKn zR^vvgt++d{j)MC>sz+=w;Mr23d>E#Nam*F%4@anN%jeRNMvai|wpjff4^l%Qv^Kf+ zp2B|b%wV3G?2tiGm~T+kL9?UDx^GK$(7~pDuTps1IR+C2h^E`zn#Ck5Wmc81rSqU_ zHAackfToGBfdIz>1necVqso(<4zi5p>rFwHS82>PS!lQR@qi&amZ2 zV-yn1n}Mq<&+Ij4f+A#PwIIt018zc!s?`SH#)6Kx_dh;pQr0}%*`fm{m&j$t`$P!s zINb3GqgzdxaF^en0vu+Mhs zz(;v4uL*KHd*_1*0moI_;mpjdq&Z*wFw$jq4yWN`IkGi7Ejy3n3v7&^jV8Oo?GeYa z9WB03Y>1GV-SDfVkWI`RVM+KBSS@2&=kF;ytPGLuAIOR}PMhFf6iL!O5OXiqrl#~< zK|7pM&l1)nqa!)%bXU5f$;<)#+GMU8!*J|fV^(=x~L&>P-O+kUY5vT46k1+2_~ zX16gNu-lcMk%+|k&CUVsJLn3<=u?ZB@D9Cw-o-582fkaRvg&jS3P;WF6nS~2fhd-8#+);bje58v@m+*IPejX0n+O?;$?eq@)z8<}xcdpR-S3K4 zuPMz;?6_T%fsYk*OEz|&aoX!eYIxJ$>h97p1Ph}$m#%r!dUUTiJNUGPbgt(o`L3)a zrl3uh_Hu~ZsNI*`WfaeH$TP&yrl+Tk`t~9jG>(OBDT2cgh+74m+7k!!#%Kc1(2;dl zY>LU={IJD6>CVBV5Yc{Fp_}XBg-Dsmhl0Et<23uC`^8!LC`ES2Hu3^^7$u+2$QdWV zc5WLUvl77p*-4F_()pRU2Q~q*5%f(h`Op(jx3b6NFpXMa2pJUo{ z7}VUpSty}lt>AR8EVI^|x7&~@utRfgb=j;^J)#)Ax?6jD75S;mh4(l&9f0;*C5LdC zUt!wu105hz`X|e$X?$a}0X=ulffqnV=0_nl%?tPUSb)NscxS#}IC>{;vyH|5!8n;0WHHWm+6+3URA%zHQaA!avRCJ1gk1m4Z}2T z#&Rxoxg+0tfSWq;)6Xk&=HOgIUiNXfD6VCc`P#!Oa9%zYMJZKfF9>eGV-WVff4lN? z8{a1S6vV>|*q>OaSpFSvWB_S4&Dh|L-?lBPfVGVCzytQh9x>Q-8L#b)`*|qDflO}x z2#cYphV6#mV6w|f1^8fjp1c56#xYC#aRMdvsMck<vOCnIcQ}#J{Wwpx zq&~Pa$mtMRc@CuF#I?Teaxep3bj!w}#%u+)D~4tRE_2e8v|>4BU8Xba+B`abT!#d1 zxcV{s-Vu{=N%ld@vwk8_Sm_D zQ>WVSt0}5?mUhfZdKJaom@dr3fxB%G^Q;B=kY4sKjOi7l)vGH*+1mCzOw}&&ki^kB z=a!uKfW~+i)@XMUj>@G9-R~)iTe{t)mP`R>LKmC9$tU4MJMhOI$m}W{eH{&Rko6rK z**8Tf#KgT36O4Ex?l(*?kvz-vUcof`KC#<$vcBHe_q+AqCYk1zuU2L#VY?O(P;ykc zfAa&6&EFiHSd23xu@#t!y3q?^5(M(K0ts}7h-v?laU}htRf~{Z_!i*VJSdfVq{ph6 zw0U?^D)a7<3R=W$d3qogMg%^qsoQ^wvll?T7SrE`Ib2M%jB~{s4R>WoQ8!?QqRpD+ zHDaxia4)xRp$(}}Un$u z#PsYd?JsBNAqqtK7SxXD3Wgez^9o9FPrbPoSkFx2x@`GurFRG@xkR+2=b5Ck3GMh% zYj8PcfO@qG%3f3QE`3xfoF2&>9wEBq2W;-A%G{*`wMTX(?JEl39g6Rh%95f3xm&y% zs-7JDh?@F+QST&6Ep@HHurIKceS1H%K=PQg&yGUh2s4$f%tW%;2@m#k`+gm^9A(em zZ%oRcs=VgCBnzYAcnb4X*MdN4!;GXv>b6+=-*r@8H9Feco$SGlUr=-34vYPif5n^x zgP%PuN#mv*>U+QaTa^7klGTbukZeHw2nQpn<&h?50B%)@MX}&aRz0GWQXp=H@@U}@ zk?h9tZQC!PMQ6TLdx-HeELjY(DH*R!<1s!Kj{PbF_dpBWpR|K=%Q5Uf-1Z+qA57?t zelkG#tnxo6&u4BsN+? zY*B!;62F)KdB}g|Gy1?sjS%NlwrnxLhqbEZ1VFDorEv#*X&-va_}ngLbjm@XKzVh* zXg@%|0M9HNTg_S5ggIw(Cm}0iGC|X&F4u!p6dFj6^(omc-Hg(DVv0q-Z*sY(8d4~0 zYcj?IIp_z2_iN<~rosZ)u5+2EN{5(Ml20Y~6V(C9y=Q$iSp!ZE&+UpH4yg8}1@by^ zD=864r@mA2S*et0jNEG&W^td$4>MFEd5aotV``{w$o$+IWe@MklZFMqvFR4lFPoX+ zoN0Rk-tjzQ^jAG#SS@8#KZGpXG@LQ`*uJS{GVYj4T?pgPbK*=3+@IgD%)Z_vy}z~a zo#oJW7OvWK@P%m9pEYz11SWl_@SdM3?SVRM6k_DG>@fSfe&q8dIHBypJtv$arS;2k z?wi}-ns&{Y!_*N0C?DpFa9pzcPyJZJ@nMgfh^8A;fq4%}E}Nnw1CW z>EyJ3FK*jov1tz>W(CW@kkhS>`r9Fs%!5WI?5lu$m+u~zS9HF>u7b=AI122pe*JOE z40^cn@amtIw(~gE5LP0;2m{g>%oB4#7)-H0ED zb3LXqCKwxCIq>&48D$@(kIBI3a%3|C(EBr7MM-M&+XlpJjGN6nC?rlTRiE=KCwJ zdT=3e10`M?EPxxC)u z)TUL!CJ?Kzt{H;uZC0SU7Pg{)6l;3>qt+6VCHs#X(YIUUQ*^^eW|)VBK{ zUK}p$tM)UvIk-n+$9u2t2=`7+ZaGyE)w8%AC$78El^#4DU!R`(KeU+@qN9pj;y<;w zolWSIv;zznI^|+_UA(|ruw<*g#6iI+xmOV{R4G=vwyb<}g(6;-ZYgD=)HWJwtm-=D zn}-iYVBGZ**c0Mezg2?E-P=We9or31}+OHrgV2& z+sX&iJ9Ket9c;zw4HT0q#kCj+GBuhM5H(&U3R1H;zd;Y|;M8%hAu?7=DOfUPb@A|N!a&vX&ll{IJr&9398j)^eyk8BqR^%=(2FVMkjFp0@`B)GH}4yhk+O3)7cm14lnvRXmJD z7xZ{eAq6(Zb{2r+j|0zd7x(MOy5v^BxNQ3~t(2>p_c*5S zxJoo~pl823v2Q_`N&yobX5t8Z`l^&5_@EfXmWo>Y@QN|Uge^f;hAJFqsx4^=m!7QR4c9A0+xoVJq^GY8^<_&gzlRbw4*RUsjK*e^ zKhXd}4`Nn`jQK#abc~fw^*}l`m4>sh8aFiEW?0cH$q!}Js(Q^k2B`vuF0qbpxquC^2^q)9q$%i*Levqu%U+Ya9CLvg4ZO{d5 z_XE0gOh}AffeInIa<)6wh zIoN#$$QJuaIP#Bl<#>BT*7J$EPa)KDE7-U8v-RH!Qr~r0!LR(#b3+q71vM_tIWZ}zw z@YdMf7u~2CpYpo#tTOcEKl707AeXTxF8w@K@tR2|{|&%3bV=6dtLk-mclI9sUF%4K z-p9YAd^voYX#vVAFCV*1w~HDsWAuona-}y%hpS@ykLR|tmNvrMOwA!}b6^VF(L}^- zjKf9TMId7IudrH$5pfEp!S_3H3nr^=BI5>9w{fb=e~56W`3 zZPlF)XTh$XMa0AdA-n6;oUEbW?&M)~qYus&P&Z~=0c6l!x4KyJ4l0qjwdA?ODd0n* z;wyv&{7C}>`>R{+Qhf?-9njiF3!?OvuuhtBVmKErc`GnQ3M^cR=w5g#@v zJ1)m=e!v9Re6|0qnI!F8m5PB*+m)U?|f<+v8&mT339 zt-IJ66OzGcy2uYFX1&8$wp(u=HOB24z0)e@VzBSTez;e+S+dg?kxmZpc0mRb;4dmG z@jIaRe~1Fg_PtefB=S9?_}e!7iS@GpB6TzRWXfOacKl#W3~jW|- zrsm6?IW91(gK?65?h{SwQy9;-83vSfHuqj0q`Oe-Zrz~;>~*3a13m^QWswO`KU^)!T=k$_ zxj9E6z&zZ45~UX107|A$>h;Ddiz62PtaS&9XF>ra@P8o*|8>wLWO3H_3#{l z?T5$4=cQ2AS;%3~1@KbSebplmb^8EPSrP!~nQAY`(%qug2Y+U~r1NBh0ugfs_8r?x zi7eoTVMOd0A5r(HibCo{&`x~YRFdp=MmIapv6=8t021&nzvnIhW=4er>*;o;FckTj z)9A!HD+yFa4;R)D)r0_%Lnj8-QEWN&<-;$&R(j=0YV#rzy>jX+*gL)LY4^9&FDX)% z$;NYSbe~ytOJAkwwQ=7cHv`wk=G38&5qnV(Ff3sp%Uv;RZ}IW*6q0Ci6GegApul-` zXUXVaj5v8P#s*|7D&+91-X0Sx?6`2;N}L(`yg>jBfN2`59}yMZrJq#`PIx1?8z!J2 zfmsnCo2@!CM1W6zMH^Nw`_wFf9psa{JEbv6MdY*`+^C`Ug;p(|`{ z9DVzKVJ5d7_j<-~67Ef)cGM2SPx$kN@kK0x6efRt2twh36rCt#p;*Tb{G&Rjr^$yi z#~Rxtt+V-t8~jyKA9w1)>}-Q6)v4;D-9@ev;5*Ff=k!jSchB#57rK%KoEpbt_^5@{ z^dg`7M#G(oa$k(i4~N866rD;3P(mSjbU}2BY$NQKEY;o%A;e_iKMVt5k^N~U{fX9M zFEWm=URwmsUOb&2y)3ygU|CxX=B}sBMb~%s!t|$heQYjPqIR0qJ}vxNtdFhsS;(a5 zC%}gv(LDGI;cN^5z*DyPTD^WUJK-$uPva$ABlx*!oajr}X(kHoa%)VnB}Gb2l*h)) zNtjdrd?$1U@Wvce#p*vQ{eg9>#J)`bGmJc*s?gk{MK0SCZZWv}y7x44K=Z5{I4ZDk z?x^!Wbs^@Z&^Lm6sPb1`y&2)^=^u|zcTXdUC@-{~a=dJK zf?D)46Q0%tB|n(T{bjjM(5RLqMAB3V-1$Nr)N#{ijd5;dKc4)_>K{hV_!=Nr=}DHz zl+P~Q1 zF^i_0FD_B>7v*gF9xaQd3(x&-jofm}xJXYqRPDk_n9FvGCp3wjuD~^^R%vMALr|Hb zGC9<0vUV&RsQKP;dHMXR#b4hRqK^;yHke6I+j}o29f>2SlLo=v{5eW45NZ6B8}{Z5 zQaZp@HU_gVO2aSC`i`k|zMwVMJLaekIidK`vd$ejx?m-(BKE+V#Ye?Ov5JU})kd=1 zWI2$<_rD{R-%ihekgFqo*7w$kB1-%lJNdBPsi2MlB-DLHytc&T3g?JIlLbjf-Gg7S zI(cn@j+qmaev6{*9w+QfF_BuANhgyi%V%PQDH|ktxyHed%gB#MPoM#8Pe?KL>)GvY zw!WG8CMw(EYgLn(?@k2(EKMy0z=@ReP~Y!$Wgd#>*+g?)Zge-J6yz_wo2$xorpUeT zHM-=~>_sa_?=iDlsXgCsirO;m)uzR2W59rB^MAMF&h766ZaLsFz#)H;2h7+e4MgCj z{LhyDGRwf1pE*6w`i%udq%gkK8*r~);qZ({B~33 zC&vP)m@T#^(OFOb_$uZGSxsWrP!yz+r}3%_(q~8^B8J07LbtCneTe<*^2o_uh+pVC zeK5X|o}yChaIDec5ir2~v>djvE^9I5ba z1y;31*B|C(ol|OL4dZln2BIu=SL^wdJhSTbD_xp2(V_qH=(t5E7T5!5(o#lC{9$p9 zInWa!#1gy@;1+#_F_O(f_<`C1=vFZAXKmyF&4qq=l$&n z-?{mxSw>IUC!?e20sDd~YY47VWXW}yL)TlyTE0JLvr5d*50^}zX_p*YP|6HfC+TFM zIGTN%g>8!~`H$uK35BH;^i9cKSZmbZ^a$xNoLyuMR_884?~lgBI{Z^<+X*|f>hg{& zp#L|bi2_Q$L9EV^;eWYTV6I$e53ftpO6_;?<^v_ZmL~UFcV8@9*gmK$H5lohqMHwY z_s`wCpDUEs0<@x8@HPSU?{@K+QB5K`L(BCN_w0Y+I5dUf-lbuv@*FWN$L!LA`VHW6 zNgz;?I|nZB4Sd%=GvuPxj8#giTtu(YJyqMGC&!655BUMP`K^i4-pko1!Nm_B{&Nv% zYCG=%20q{`Jmp`~@ovdw2J(XTUJ(mg=<>zB(KTw*x<($dW}$!9n!aE2W+y{jPG(Xx z9A5^Kj5(sYZ^vZ6@$;VAKQpo20`%(cCi7Fze?&q>>7hr3Y?dg{U#@fVTrBY;tR7Cn zDh;F0VoXrKG!+=j1pt_Z0fp|MgV6OeRxbZQ(BlBx^x`x~ zqnGgKWDJ1{_)j@F|6p*o+pW)H%d1Ws_h#gKbbDD(V>y$~{ zrxC;NgbDcp8f)<`XynsBh;EZgC=&veeGO753ObY^c8GwCT%73DYCbH>2c}|?;DQzc z3e+hLoeRBKmaOiqAp});{8#+*%P6r00uY=kDgTuYI;HqB7W-N2eIVKNdfzS}E40HR zM0@Eu6_h8OEy-ntKj(!9tPsnptSzcCDYN_~=%zRMKb$#H&dzZF26!@XuYX}+MxR?I z1V7cwt)bC$2~BN4{4&}3A)vCO=8w^L6<=k9$gSht8r9Q2KD+-1)d1gwP{7UYzWA(n z|8NW2nlO^X1)Ma|1Kh7_0Mc{%U4>^od9Tw?bMy;=X!JF)%3g;C1N<5((nhxE{#G{g zyEp)@a039Cy=2Pu50xH3;ILTIJ*q~=B&&TzRyu}Mmi7xwwIJfLcM=Im3U^wmMTw|W zI%6h97nbMKyV0CuOHV=2nRUJJ|6~`|(WUPF-NyeijQc{82Mq1hXldI55#59hb<+_- zpsf-UA&1twL3&Sc_h`Kp2+_ipwBL4BJuN{U8}WZq8*2byZCAVH{++~(Nsgq6oENP1 zG^&`2kmi==4QpjfUWPR4m~*yA+|HteP13JR7VajLI}7svuJ6AIrUspz%Faqy`rpXo z>gW5xGTw=?{^3umg9WG;MhQ zx*LQB-85Bhx)3}8GNK=mG`Yk9+!x8g8^)c^_HdBK9BGj(!zwd-x%AHk?;p^Y0|H2O zOudL-n(*@>K^Hq6cRIxZKAd55X+Bn=X=U&}a9&pm_e$(kqkPr{s>5yUH-4=TYqems?l!`$JU9nV?ssCuO?5=D*wi=nS!4im} zV&j6PT+)Ww!ZYHm@9k7(=J= z)V7-xBp7Fp;G~KtCU!3`X0EbT&Ok@P_6I?`gQ5eTGWrU0>ix|Q3D}jR5<1_&;ZVev z8`d4el)4UwOB`2$&L^h!47xI7_dR#Mi#8Tcr4e#{$gB*9z;dYF`?j;^$|v0tB;Pa= zVXGR3i183uSTO<%`dO5=zMj+tqMmeS?=VIGfK1Tn6IgbZ#nF|zhc$9moD|O6TrlO^ivWIW~^l|FlcXhg6-~aNmz_|Ze@7IB5;lQHp3^i z=U}>SwpDc7q&u1gJmKPIQFtj}o3P1ceVk1980Y9b-Whf3UQx$c zdf1HztrxyOXC=9yDtGU8$CcuUcC{95^Dp(;8Cc^cwNb5jh4|aCw6RUioYsaKa)_(a zS75tQ`}powoZb1A+e)XHKi#ZYHwdg(hU6ICVu7yM}%5{r*r9_n|i*Ll5%)hym62>8DBuU z&A*Ml9uFTG<3=nsrOzEThz+}|Wvxsl&zjL2HQ@ypdiTV{=IvFE@H~rR2NH|~UCY*I z{T48V_o^mIviLrJ6S-#VC#=XKSZ!pmS;Z>ITlA8CrwH4mKl zFr&)m`{W7shremq->UvCt3shbFm}(3`R0mra1-xcG740OHMen6{$r%Fbw^&%9#RYT zG3xWb3sat8+Xu!}+h`dZqYAE)VV3TVZR5rj)r7)>k~=u_gL;N7qmsbx(@>RhpBx}H zl0qP1GTFzs`w`F+5VryJync5Z4&zNC1CyCq@cc29;)RWA3fL1LidGTl^KBYz)Nj6S zB@wVQYan!fg58sR)Ba}Lgx+(odZ~Y$ybx@6IusuKpiyPp9V?I2VFf#avO2akkU;LP z2gKT3B#Tx!^%JR8N&=4*t(9_uU*b~}mzpq>oy8fk43NwsT4)7W)zN)(G|xM{o_fREXRI-wsLC{bV&0v*`K`m>LGcJKjsvzx zNj@}V+DE=kWv=kDyEMePmrU)pgnY=U7<>?PWqJ2++Q%6_a*J&CcqkKc)(g(9SQH;y zepSNQ`eIcqT^W;4Z>LCPVI zs2lur+h8szt9I$uKGa#S0GGpwva}MWhU2g78`2TjAAa^>W8AEv zX!H-}9Un&}lnbW*vZV{N4JJOLNR5)p%rLsqWS#+ZCPkmgs?N+#2nY%}>Ncu>RYKbO ztltOu<48Gac6Uh<5)57_wq*5mV|~k4FHlLK8V@coD4n=v7}Q=?Ir9Dlz}M5&IbjiL zc`8hV=MIX2zD1cgNAydQX{zFHpy^=LnmW-Wn34o>!Px|HI5no~&z9%>W%W>KHNU2R z9^K0N-Ckt7Df*k6`adT*T|0ZdD=Nwpfjw?%sB?@0a8g>eYN#Wm1@e8bas+aPqCdDh z?!41xkVF0Q^Pt*RY63;@;&7SfUs+L<=IjgNzpCRvk(xd}N-^Z*T%GQ;E4!@>=-vw2 zNyR#*5Kq+Y9aWr;0x&O<@6pv;NJs+90~*{upj9HY1Exy5$|t^zO7=TXR1RtsQgrv( zRx`5t2hQUFLmwzq5NpYuYI;gg?Yq_?iK@Shbu>#}Q$o&|<98fYV8ec=c= zxPpf@RNYCQdm9v8SsmiJPD0dXSOq@krPyw$v#~(qQBZf&kR9jQerOJ3;y(N=p&c}6@vjH1!p4Y8Z^`FCZEt+ky-6QT5W@2D^q0yDc0D3 z1FiM8s>N%!LJJVsRGQpXdl2IVPt1;Oe;}Q2@MG@NT^Q*BO`Wd*KE1rkp;G|h6Rp+3 zAa%+eSHM6Iw!KgH=>9DQfK);q&;l4o^?x*EJDiQH{^DVu$zHj*cb_~0f%Man*%8eY zl7b_spu)GNLt6$b{6tCK&z${?|3*pyp5} zFiYUh7N!h!hj@}BG=tB79Y?Mh|5c`Rp~$-bqnQRpK}}T`|8;Nu&QTHtFM#LCq+cX# zHAnBcy%bB0^9uM(Fzw7OQ3f9w@9-jl%}I~}afO+VVJ4LK;j$~)u}Y@QU!MYlS*4;B zA{(N5vT6VLe{j7EScg*Cze8KMSuP8v%1ZF%9#2Y$;PzL8f4<~MYQcrfpK>qkp`xl2 zJvM^f=4?O)7gYf@lF7YPe{w5fu8?lF=xv{`n7G{XF`iB}27_`c}qAXZ8=4#xIZbzsE*gY(GPajzV}&OpA;DV0|H z)0J`W`pQO5btYgl%rY#$@|O{Lj_u4LawO1Fc=u+nFYfQfJ8cAO#zLgpDS%-A?jf0# zq-V!UD~oN`MUD=zb26{NR%bMt26!Vc@4C;Lx$f=+i3Z) zI(K(hgfpt+5r?h)m3&T_n|C`-PxI-iQVcYQ8$%5^OOgxaVA&teg#;`Ge2`tP4iNTz z8H3xA8yMaK3hG(3TWvi!d1yT9em1l@HSMH-y4Alo4eiIqMW|F+At8ZWQ^TAJ;f4zc~f)SE|);0Z0-Hqz*J@FI-QLTX`1xfa=gAKV+_z)8}GNkEd{RR8#4C zLw>sCh5v{OFAqJXp`~}MzrvEtL+GHJT5i?R&FZ26k!0%MpLp->MAixj1k+u6vz090 z0fx*{Ju@~p#nrUxE7{PM1^GVBVDFFZO{FQ(Y*0)ySNgdsVC3%Zg$NRi?XX=-){&DDId1Klis)z*a$mOm$lrJS)k`^g|*MDomZ3=<@AUTKCCG3F*2F?AFl0h z;58?(Z%$p>(KxQ{Ef5vN5n#|NpG0qM!@Esu68#2{|7lk67L&F4`|T`xA2eFx-t`$M zeqsx_MHg)Q3RHsb{y+Q0JMiAIjD4^Cw>|2A92ZpA9Qi-{h1_mnMJ})!Y{kj{^HabE z>Hq(bb_?nL?`}}2Giq@U^J_R3!-z(XyPfnDIuUF;m*ky)7Bs$1$eYc7*w%SS_R{=w zq2bmTA3XtRuXKiBojDR2{$=`hIGO%7L7Q!og7OA#0n?+q_XWQ0?QQ7!*@a^^UGUL*N>&QJh+_m_^}=Bhn&ra z7i^p4Wtp1E^OxLm`s9}z6>&TZ@j;_%ec17X`-V-ZPy5-==h^E`grEE@pv`~kgOvCq zOaCr{!{R{Zc!KDnjrB;qWHCR><2wbV^TNN=3~?Tn1&b=Ygm@ky(WR+e|9qJ=Pe`3= z720PkOM<_g1F(|0$Q(nJ9UMA2C&2R)0S22gji|45=g;ivo4{rK@N~*CF2pli_a8Fv zxl~$uNb=aB7EJ2Nqx4m-&JN`t&vTOrm5xr-eRqEK!BN+^qqDt}|A*U$s@Dhe#?1BX zGPVDdkK>D3jF=l3#3tuTRMf-`uMa+8*EFBj#DC;6eB>Bt9rB^rI_#dRaSvq~=d^6Y`*t$0K?6;>utfi`=27 z)L{k{fA;sxxR`w(&(ZxAmB4e!s_k@CiDAh3f_q&mZGVQ|OXJ0#RUrvUfogBvOmmGN z6Et@vI1k6bb(;uku7kP1IoONUgRRxf;p%P9-QIo}>W%gw#31Vtm2ovkDj z`&gW(FPVQkQaaP#)#AakG&S?5h`0JOIlp2X>G*I;gjQFll2@! ziyq?YR9tkm9M}wCrcijc?mYO^k?GDizdM=cCVOw~u%MHmYz5v>)K1J!g+f$+q~+Cf zhf^4LA1hC$DRP*Vm+?4low8fR^u)0$r-+$Y@f0zW&fM60nX1uK^eoO6_qz1%W{n^T zB{>DDN#U_gK(f!bvEY)eWJwb#)I)2>T&`@%rJ43xM zKj@&ZhIs3>@8yksv8Jj5t&co_=Fz!DVT(Ip+MbKdL%t;Z5ZWO=!L~l{bHYCP(OTgE#&SQe4bn zQnA?4<$b|I$BWFR=JcWm%76Z3%W7zJn2ffvBrbRCH1Ulwf05eV#{9|vSv5`EuZhUqOl$JykDktP~iP`@$&MOf>+9*2AR^QZX zJ}+;_6#JY>b;+_XC`S)n19;*w>$IgsRgfZW)G_BIauRlVYB zXnm1=?^CDXGWt!@cz%uTL~mbTA`lCF!`XLs$aZc1U(pZ!lr=lF%emHA)J?N0X2D79 zap2>Isos1nSJw?iQ}Kn64680$j6@mFLaTqKsA8F@-~E9p4)f-PkLD#evZ4dznJ9gF z_VPtB-;#$i!wdbW053ZDLz}wCSt@XAkQ^xB?%yE#!puzEO&$8(;mpyc8rvT6rR-X% zsK!VcS7mKAdgqDf{y>Be-DgyuG5iAjVZ#oqmf+T;`EPz7iwdSEJzndd`^XpWn$o47 z!7VoNM!oOTF3+j9s1(@%T2m(*$3XMmu*;3wrUq`HR`P|9{Zr{}Dt2S-~=S4qLb z*V9XVrAV5C&V3l!SMr`AN*&B272N9WeH9n61I->noR1$|?wzbHD{ZV1yBjS%C5&qi zz`1E-?3|4Z(e#p0F&R;Tyxixste}Y8w6GxBTd^|lPmuD5DuTEM&;pBrOY>&h^Uv^A z1@rfB*e}m0SGr#Aoa~yLbQ=8J|2frLQP*jJdZ4%=`(sk77)xU;+qB4ih4d61WW`B! z$P$eJQ~vC&JTcdFTw z;5Ponz^wK(Wsg|kl~&BIpY#!~-&qzXuZqetHQ3B7SChX+C*Qj#|kvljlSZe&m)!6wa-P7Eu*ZlaHsNln;wL;kijdL9ZdbQ8+ zF_nopzQVT2r|iL^a51Mg)jUprlh#}=t+(wAH5Y)y=Ps#Q;{~-j_YdUbAMeNeP|6-l z{o<+FM$?r&hwXi=dVMyECD*JBRmak0CYy_M?fO7!@Ak%8y?kzVIwP2|@s6K$=r084 z^xRCMk-Ih~Q!lhJ+k+`20p4;VBPFQ+z?2+Xpgl0&tzwJj+pO z#g-xF*bduex0*912lanRmQRRcV9m1HVuDLO#k(@zljVx#*jZ{k9{1JCs3@w`cC1X+ znjeQ4_aV70ZYF*#Z$8?MVA56lGH(m;hFp^aAc~0X2__+IvR(`{Dj`LQA+wincKl2> zEbI(%t{MANNo##uaL|vWw(>w{SCY8aLVZ_Bg6RAn(G0Vqg4~4jz9C9#?`Q6ZXfR46 zXAT@_IVR4XTxcXYC~;a*lhRl^*y`TTV6$5topUOz(^>RlY9BMqWVE}O=9xXB3g-QN zWuzGYZ{5Z_h=cYSAg!fRg*OAFk zdg2`bp{i;$^Y!=F)OW{M%}v~td7~`u=v2^Cqj_-5^FugiJYn47>yP8&lS8)Ee51WT zX<`;1#gxpA8>at|*u%^bJXtkq&@0L#l$YrU0CJxT%Yrq4WS8J%Nb!%H8O)9G6-G7% zxOg;kY<|m~1}&vw!hC@Nx0beYz)f0%5A+%HYFP_=s_|(d9jYQ12Q$G-3ruT9DMFTv z`ttC>i3|Co%*&}0fkMuAA2qcZn&$I#&df5pwa_U=M&^r|*N?T@IqNHz2~ncyeBTZ# zmOAGxb`(7*N7C6X#`1JAv@BxteHK+SXOd~7!l^991S0DuTAZEqUt25j6YO!1bzAt6 zm<++Csa>8&X5t*w8_YfmB=?B+a4XZQ!{2eHDR-rw?8Fy$(V{Dqk~wR%=VI@h+xgcP zB@d(r;X4x-#oBG&i&?t#IZr)*jL#PLXDR*lLU}sNEDs{T`|~FRljj8NCvnxzoR=oi zWIJrhE|AK3AiR%Zlas&ihE8elo<7Ecj>BE~HaEvG$k1BD`%HY|H!3f1=i>GyC=xq?|IsFF|9a2Ea%hLBbNH&N1t+!{du{ZpLR+mK(TBQYahap z6?4NyUMfE&#y(^jKcJHGNPny~ji>W>;M||CE+e-9`K#SV<*=ZFg($cA{WJtx(xoDG z-x5{!+M(Wwy6Qs%91LnZ4CFbDC3@v)D1XHr%|TdCu2~r*5(%FU7o*ZK?IrzE&{Y^_!uSvvc`< zRiW8YoSj3}M{_HOez^4M+8YGw<)PfiUn(XS{6sZbGjiOlVWgZl3+)L>v%fnXt8|47 zJ9EC*Tb$cOZ-7+*$nJr*qPDV)SU6aDpCFWyraxqKuqZE#)%?+%tkKdB#_)0}<)tUZ z`Wy9hXIpiSisj{hZJS>Fk)mJv68HqSZrrUX@=>%{bgNAC)U={ZO4X~K%Zunq zyP(F-$E@dObF|+n{1dDtdMQ6RX4K~3#|L-&Gn{6Tr!No1UBN*vt8#!Ue~OCt>t})lcOFKB25#g zq*=u8Npv%Y3)=^M7#Gr8suD7pdzZ=MVos@OloQg*XFK1I)RMoGL?~s+<$Z7~pkvYJ za*MrEvSWFpjEA6DN`8yA_EH-YJ`0ylL(uPOUUsZ~e16iel(W&P*FK|I5S-fD8vTqu zyVeV!CQ*F$o$fS7e`%2i@?z*b@6);{FW!IjFw5-g{rO$^+Ar}pzO?_oPakqvKWZdL z^uxiW+Q>g$+9GN}8G}i02bD@+vnv#T=lJTc=;J6f&(w_ZWj`x?ZfW+tK61SLO8kl? zkW4X;UwTRT*`VTfvE#|422s|Z+J9_?2-UDM=NWJ94-5orN1H^?yoETi?=6l&rchXd z6F?QgB75YJY!m@o7azF8v7}BWh_HO8wcMQIvrjejOWH{-e0kbwMGfUZIM343Rmz-p zmAt$5xdg5P77KffY#=;`Gk-dP{YUso&ofvtT%wcGVc|v97?}Mn3f}|BtbWG=_jFCq z7Y|Z6W0f6;KI?`G7{(@Y7KAudUo!6;F7@pg5l_hCTKWagpd~m?ng&xvRRzQtqG;*LIdQpZ_@6 z^aCE!B6sIortQ~TT$o)~*3`$m(dH}**^1q8?5TQKh==^(rPKv&hKuKa#-u&yO(Lyh_Q`OoJR zHS@;G*(Jg8>erIx?;s-3!i-O`@n}JnZuHR4iVZXE(*}GKW^zEtbx5sJqeAfe9oSlQ8X6?ywz(-}2 z(&ras**>OItBE;eT9Am7`r$&IB8PpcZLOqXTVn2_soACab@V>Vym5JcTs6~{ z^77QGScsjohLl$OO|#y zze-$K@c2_3i{;!~@L>O~#NcDHnitqRr>f@sgnyOk2DDXl?qTs@FX$WbaTLGt-X!WE z-}OL#vp%MrzNY2egjOX1Y;A7-c>~W_*GjP@0jx1vSww(+ypoe3BQ}x*!11$DkPy+L z<>YvmuLeGv`KO<&#>2z$V5xlPV{3Eg^oay|9{0g>AE;usCObz*? zN{eQeNpq$>&y7SXYsyN|%eI$qM06D4$L387Y%CYMpP6I1`4O#bG{^y zt;|sa147>0t5xkZRuKtB$mj{nb8lrizTDFg@lwLJrSWLZ;rWxI`aWTEZZ?Zge{k!= z@1ON?gkrzIImtz`G!Z%-e}1zkm@PfB+6nLN0dF?4|827=d%ZA|{?E9vF}|eMXo$at zZ}dUQ>6?T9>QOul<~1}>J~Qntd4jpsnU(oEN!wYK)P%?S3lot{Nyd_onwklV1*OHO z-&pG2RM!_-UTmR7I~9HI>kZLE;j%<-Te@(q~DYM_y zxgJ=5eli7+yKr-6zja@-Y`mMgNtbB%uB8&&*As*xF2a`qt8fr{~=Ot$`~nXC*$0M8OxRa z(u<4b(WakoND*qCkmag1Xxo_$!)*}YJ@l(dh*&$7 zq!;Gpu(<2z5kA~!{BhOI)6;Wl_H)9Fol=CTNpn5^86nuYj?kVo_$_lvG{SMQn~Sbk zzD9T{v^^JOtZMjjCLBn0=>DZ&0)iNyy5whAY)_rD9j$dM&GE#?wsg>jEY%nn>$$ui zQ&tvVUTDu8s%l%@?L;|9mtX5Rsp!&_fMap$ekzo1Csm&RtPO0&08b}FOILgI;4f97 zbnFiek-EpMSlL=B?aQr$;s4-rLJC4_M{{rv=mJxBL(|NROz>6_4H|kLJ0ooJNCC?q z&j7bldY&?%-EuNBgW|_-EdKdP2PCD(xX=PO-3ZbR7vztlwc>L_}qAUZ<5h3 zzC=^^i0Ks9dFW)wmheG># zgH*W~Bhb$b#*l#oCbE7>esG6EW6}!HYFS-NHl8>&Oh~b_tiZ}XoS{8n( z(=R5Jxng3jwyTayWIl3G@P`|ZkoooM{Dq0pzJY4b>>y;bIlf#uP%{_neeZX^X-5Z_ zm72&W&-Wi2qpV!4Km4qArH`!0R{cHo=1a`DscCj%|5)(1CZA_}lDwyw_-?vQG3JIJ8ZQ;dYa~}-q)An@Ezi;3j2<(f|Rg8HdtUvH`>>bGm$V5dpi+V4P z;Pe_qoik1B7aSHviw*PV(k;V2MP_F@@^a0~r=bav6tM;9T)t#4d_V}AO4hE!T*71| zTOH?_5l;0mJ-5$=vhT4c&;B#|^C_W2dzKC5JF?H6zC9}?wl{8;ukVIFGd+Fac{p2?zV4Zu&Dh3eEd8?=PLq6|9;UgA9e(GHEt1+2 zHSLiaOXHEfHg|tD4qsAhj*l_9>pYVOMb)rePAmnopN7XeRsDuzzhK^a#E&@nL$L3d z(qFFrJ||gMO?-^-SNR?TjkK_rx4wF+;`HwZ*|;}oYKk6SRg&RHh#WVX->AMa%Wu#V6 z%$SxnhSMdQrjo)v+bt_E%JMu_K&iECmxMHIASCg720%NU)dbDdNe!|0vLU!o6s~Z>c7R zq|2%Wn|Z%7ICC~(=3#q7r(#e#Z!{F251DgI0mpr}HFJ_uuxX9=E#Ua7Yx*A`9 zx0a>Pt0l|fEyc|=&sQxVc|^lvM@+Q`+d%~)>h-zqJT!qC1jDYk*f-l};0C{I5zFFV zTl^i$Tk`O=+{7n3|B?z5!~?HH6u9jVXg`p>csgpZk2+BZ9w~EaA`~4xMVaFIO&w_y z>6*k5C(@TBRfL&eY-(!I`lkV0@CIO&-K}2(v>c6}8`~ZS0LFYcdz?tLv=>gO4A%r}(;7 z$oiUyH6D+Ti?DQ4w0&un^cGlJgiaMWqVv@s$wgN7Mbqv;u)eDxrzp27+?*K9=me7A zYZ^|-n$7<+yq{3QL=d5hCt%;~k-v%wi#kSY2_U!pz%gn!8PK#+6r1TMc=P^GRAe4- zOY^4#njf~cA5ym&do$zlQg@>Nq@Ilh9RDXq#kO}UQ>VxLONG%n4t$LIh3oI({SgQGGfYUez||C%N(=<}w2UjEZb zV&n8*H?QBL2b%mL&(;R#6CZhOA@rs-L7{tc1(0uOQhdwBWBXVC!zcf5!!{9i=MD4P zJ0|}7`j}n!r`CMnp4B=4mE;(Xw;pGip?rZ= zcB(5V^bkE*QjN?gbsWz5dQ5O}NT~0JMwLw0j`dClKz|uR-GavEJe~W8AL2x)GK?O1 z{;jr5O-(QDOilc{b79rm*t`y?v}(8>$ns1|daR7^y$TX(f4R;k#W^XNhwP+ZNMAtt z7$Q9Sn^+I=kxUIO+}BJ~gn1_h%er6EbnLIF=um-bhItG>T2I1Kee5B+#oC6hF3)PV zgQl)pQrc;Rm0M_AaWmk51QMtT?9okW22kB)GQxz8G)qkJQBHi?N$d?YhO56u=D1h! z7d7?u(yN~jO8!=6qF$fzT3k*};|R)#b+GT!+oT<#;cp&6*B5IU|+8x_He^+}*Ai&Kb* z9|^_&I6Y-l-Ra|gVu zl^R-A+H_2PL%Y@;CP7N5Z0pX|^dm{Ejv>K-;4cl+JJwnQ{EkM{J~2rbjQyMg6$Wb_ zTzR4AW(h|*fh5OyRMO@Q4^R{%gzAW}o>fr^aMPd|R$C_mrzA+)w-~r0yZ*`g1*bMh zFPs>>evo+1yaS}97Ns5UhX1}n9ibx!YT+)w4%})Ez_eINEk#M!RU336Cjj!!lW!ZW zy?hj8?5iROIfm(_F9y(disLqLVoHNCmBv9(dPajxSzJ3{Edl#DcKODUNv zAw-FvW5mFsUPXK-CVx_Ro&4T%mld!rc`MZzjFlskx8H^cAI@mnE@1zll0jyf?|XSY zV(yPNLS3=$kXA>B0W2yI{`tm~{2W_5D>1cJ2>o71aWs^COsj6F4x zbpu{83FdnRZh(08tFr$cw8UXz^J^q#9bP(8(1SweZ_RXcyvK{jO`1(5K<5@!jhy^T z8K}4eD&%c5ebNfmnthE9RrmV688$$}$?XL)`JR_@j#xRPF6`aM?*-Z+tZywxxZy_j z4X+Xq@zRQ0!y9k6SsPUs?4wN8V?l#8-UVNje1xjp1LVH1KLIM>hYCC`6DhJmK~1Bn zOBr(U!K>r^{ile2w?^6f;Ke!I)Zq`-{tr#tOo(&^bAZD9cVeJ2UGnB!C;D+{>-$Gv zj+%gm846|GJ}MjIy@WZES*?`j(bPDu*x)|1n(aa^_XQ$`Fy9=phC-3701vTD&={ek zx&06!+!)nCQh02=sKJj4dU^`#Z@&hfQ26m+*fU~1v7!NwX#oZDeH4c!-erblgni6& z`$}I0CZwVLMF1pT&{Sc7mFu^owYVu{w9Z4fARD?@82@717DoRAo=f3Js=3NBt4}XP zz+4bmP}c*hTj0Pj-Hhpb&_dCF;MCB15<}s?v{ZFL(R`*I#1n!Zg8B|%p8cOO%*S=r z4K8+3>^toRUui2)>$<55<)Ti`fep#>dk73RsB)Y+h_L|;131nSo9iNzoeHcEr~y

    }`U=fGbo%nS)w* zI5w*FA7bUUqJ~a_IwkmtxTD0U358)W%r2-2g(OsuCw&})b)(3_@DtTvMxR})osR0V zO*-$G&Es~54D+6AAT|`uRJ?97)_7XyDX^U~zxNdWCK{jN2vl7QG{rSXY3qyOwSTt~ zoH3VKU5_PN`Y|8S6z4cTYg_Y9-n(Ek*{c*7&#c)fFkskm-k%6;@0@DVDa97y)q3~C zWlV3%%@3}T12nYxTQ;q9IpbEa|GM&86Ki*NAm{jt0VV6cBLETv=MI8PC6Ol(C}ra;(+$!X?xb3;4)~WXdFqLWvk+MIY|u znh6Q5wn>1BxiPWACe5I|+qbrC*ERNfQfRw^1=qa`3_S^Et5XXBuRch67OEn=iFAeB z1Kf6HVbS9&q0exGw3utQ}EGOW_&v6;q)2RV~ozdZ!#nIv@C@3%NOpZ?Anq znyjH|K)XWQ!$Ulw0dLH2Qw$|&oELWi4IN4w0~w)8-8Jv;4ck=;QYrmCA}*hYtvmw?6o_(_JXjREe^VSuo)ruY=#vP079 z!k;73L}zT6&!mG6E&|Q9uXggKp`|u#acKK(+!{=OL#3xJ;z!S3(%GI@9;yqd!}WmE zipT>%dDEOxD8;0viGt1u4F|K3Gjqo?5ZLQAPgWw9_8g7#;J>O?O- zP+mjM>-$^*-Zif-Ahn<9$WrbGXutCQBI6v9QUfm9YUcra#k%VDniz<2v_ac|y6tTP zjy(n2a=bf>sP`Du{Gn`X^9OKP8oKqcbY;yIpbw9_jI=S)l+0Q|_~IaA9wX8G&HMo3 zJxHC4CbDp=00g2OZ42SytYe*9Z3ti5I(5{0qk)z2Of>7{55&;=k{HF2%cPkaZ*Pd;KP zh6HIJ-1 zaT>USGh`MA72BqXM<7MTxk7#7$gJ3l?lG>pS!;r0rUKO=a1{g)4OsW#31VyWmhL*B zhK7K4aKAr2JN41JOfbiyx;ay9@noewPl&wl%z-S4qid^LU!FU}=4V)Q$ksUk9JR=i z*FES{hk|uY;Sxs;K8ey=9DH40Of+XI1_hmqu4FBu zz>*N~5P#|H%9j|;OW7FfFI8TGFe>49EsA-4$Eg_jV4@OPQ9t{8n`(tl2U|4bC5}qi zIL=6Pj>=C*pw-~L!KoNgFL=Dcou3f`j4S;i(?H{5g`iEflHP~PmX^{%b4n+!Apx63 zi3$hM+HCg-%5109h(2(*fXuCq#uH8BI4by4N8IP}5KSvx5#(%cSp)*q(`@xwr=DTr z8cYZgR783PPu7qKSnK z5*$<#)UJ~5!3~xT6?lwog@i@prw41^e9*AfO_TyK_vIs>j*XZ7fXTeP5vpI7t}i%8 ziAhf%cdL!h7j?>gVAyhcF{mX)^nW+fZdCr2tU(@OF&7KNzNvPNBuRj$DTweiIhCK+ zs&~HDgJ{r)%#=q{Oc3gODLxUXCgO0PV!-JskagZlXKlG#~)8ChvnvO%bl5U4-P8;)?GNk25zj=-pD zn4D`-hlngNM99~mOD()Uo0yYK%c~rF`Q zT5T%_5yQ4XzhF*GXErcKo0@9568wBUT0kScPXdZ%LCWCO7tx?8lZeTBynn?+umvLs zb;jCZJf!9+dM>P{ceOvom}s}OZR^JztpH{r6?9~A1J&|YK(k1Z%2I7Y8$E*B6MgBe z2Q6Vvi*k`}YC)!c;@)QL_~LM#@h#_Njjr6-*b3~}!cW^KSNT4W3-)bWdWky+823EC zrtn6)9i4lmb}uYaa_)(f#>>*0!S5(`1OwaH2g~~Sbo1(7oa9wOWZ0`0tvlqXWzW3% ze?EK`W)xcDWI8uaas7kG8L2&2e_V-seflW>`PZk<8~jVnfAr?Wm!yp7q*K@MZY8o| zk@DeWA?H?F9 z>ywqg5DKK^Rd1xEy=6(M5dV;@{zY-BoBo~Qf%`DiYQtyLeuf3)Woi6=*VevXxv@gM z+hwoYy`Mvu_C9ZZzyC1KIFKOl-dfWyy~Y7OusI!+B^-~jR_K_4*$J3QD0!_B$)bDaK8b7sTj@-zQ%(?b@ zyv3wLt9R2F_^& z+{WGlFLGV>2sgA*!G-rQ-EIl+Y8#X+wee+PZm!R9eN046Xju&8e)Xp8HE}-We9Gkt zgWAWn+ym9g6&wEDMAKCQQ2A~7h7|_W3kvO!EUBs%IwRP4;?eJfBeU0+9frO0)XVe7 z8TI{1(Z@G0Ra~~@}tr_Kd3hUh>OLM4hY1(RgtDjP=38-TA=ekTa5;X^D$AlcNJNwjrV1Y z|6stW`5op#26`Z6=%k)<-{2ZVCRvG$Ca1GG%(6PxIV1AISHp-YgRWLVa>0(%$C2Au zfAeOoh~jgJCxsnmKX+xVOCc2^bO=TnD^NjC*&=+hv-vn{#?ag`stvaMuPas$80kPs zk`f2?x|nZF^?$xX)RU1{aSLDCvyCzTYp_reQno6UBd?#z_$$)BcJL{;rQA2Bb|e;d z0NW{|^y?EZ`8`gAj!EPlqnH2l(CgpI3BZP7QqKT9U~f+;;*j-?%GS|9Y=#nb&9-xVQJTjv${5%#zPimus_Z{}*BY zLHUvU=|EEJed}3eF3QhEx9p<0i?G7uy5Oe<{e+;q9>rxx6U$2lHDc*+ zHLQ$UgpzkFvB4~Ng`GP7za5H~GMuuki8X4{b2#wKm5ysQF;1(qT3RpQV$$ zg0G()`QMJ8xp%>7>g;3PsSbnU3zx4hJi;2BJ^L#9$?m4B7w7N6Wl>*u+YhLowK<4- zGJAlZrvP`mnmKGJ=0^e&X8BgsPhvw2hU&mRitMY`W}!PvtyDC_1Ai2)&U@>`4id8> zHb11gbN8^bzxkto&Gcee?}U+vQq!%wD;mO;Rc9_&IwW1&3mBjrE+AeQx?4ml&&&G> zlaAq0rY}qP?qrLPde@_*GQF2>9KnUy9rw$4{=VqbAtG4>Gn_bFH) zBr%l?^5sDvfMXJmbxQB5#CrADI=z>Om%p}&>a6x8#+IYOPR^Iunhxq%vrIA%2xK2Q zeqDQRmom&o@i}t!Zddm1{dBrC1-)&Sr=U+z6Ni604f;2T^Cmm1dft-NF?sB``waKG zMtCBLfRnNu;bTu?3-J)em0e=H3|DEYGJF~MamJpk>2}nwWY3=Qu_+s?0ePEwq0UF} zhaaA3CLWmFBxQ&xvN3_^bkT7E{ZH)yEdr!gN~w#`Pkecmo=*lWs_*K=KiKvaIN4Bof5yG@`f>PMvJ zqk>e7iEo=R5>sOGJz&CbkW|(^I5w6V$5wrto*=8{JM13$$l-z`R;M8yT}sb{=5PF- z#PpX|;Z$FrJ)M{}k@XgF`^yomZ~p1}o?}K{C2i^Rm1123u=>N=te&?8*+%Y?g=5ER zvLABNu(#Nh#xbAoI-oZ0b#IE5_7~Io?GWRfNqCYz{q)c1g|_|<^fkeG1Gr}6-k3ZS zB#nP+b<(q=H*gSp!z`z3ZAL69ECX*nvw6hG$gQ=y3-@?*@{v4`A13GMUGn@nc!C$T zLIZ?1*cAd~=q(lwaiX%WiVX`LTiT1;NqkVkMu!Qo|y7H$-Iyvt-<2OSDC=Bsuy5$tbBdR@-C%Yxr{f0Z;n`Mr#{ zd0{gK!ZSG-fq|EC>H8X2r+A8T2$`!YC5}kmZ@KyjjeOyO8tziuJ(#82<8*VP%|?*k z8hn2wjlEHv@=K7>K=<6uS*svD)IFbnlMmO)RNk^lhM(N~v-)3mVvNNhQ%0OVl8*RKNiS8qAuy!7 zmRHpQ>x|{V7024|YZm<@m~+Zw6W)>DrH?p@P`!lSm(B zSRZj_}QEa@QE0G_j3}(iWv&r)lakj zQ?RQ~>B~~3$3-uYWNLZ;t}+ZYNk2K#Aa+2O$%lGHe-!O)MP)4%=N4UhdtsG#+9)1s ze{D+)%n#dJRXua-uKgN8{y{z6>la`#X?L$G@TlbVCXXV2m^r1d>fr+}2(};}w(bx0 zPp{n8ytk?p|4xG9jF)skd(8_>zCh&>vXXUU2YO_UB$hfD{|J$DVGq2FHRHV zpob=a$R(}7+xr)G*am%nw|i|Vufh=mVSoHQPCYe0sak!t+)5e@c)cZ;f&0w2Lg!VE zTd@?ZROTd&!NC_}ImfkW@pQL$U7RHeQ)X+QYzwAb`2V>2?m(*l?|*JrR#v2BXO|V( z>y{!JAthP2?47;2mx{^=C7ZIdw`*Q4d+)96aVhKKqTln1-k;z1U+#Uqp3n0<<8dD6 zoaYS|8`)A{J$h>-(Mq=y>xJQD){9&l!hg>X)=bpl{j^v{SQq7^OB>ar3Z}q(W=1FPoNQj-MwLaj8wZdOdlZ!{Ms3ybl!9f` z*=yLjbg!+ofolbd@vPg6uic*C`4vV0i6x6!Yf@#2OBfn6AXhdVQ|LA1sAfi@BJ!j~ zz`y^l=jJ__47H6Hfr))nyCOvC*GqG`Ac4WT8d0k2_lN>|Ng2v7awz=o(&6N$BhlhG z>R_AJt9d}>fSNqG`uB)FUV?{5+tf9Z9Srug`Nn#hZ761EJ&e2ybvoB2FIVFKK_L(| z7jXcf>?UM83pKsQsI_y)@1JK&&=-4BNO4bHsjebzj++-*_2Yb2I)pxeMU9Y>hc%#4}t8KjXqiq1mP%tz^&-1%hUmm} z@h^EL1Rv>|+iHrDid^da-19=vulDKJaY%-*tOPQV^DK98|3B=)&7*0M?WXLs1x80T|a-@Rj7HM-(O!F#%2xK zcDJun_(bYGOxi}_O%b8+ZyjGDu`b+4I;=tJ$Q)VL23;YpnUGsR{9hpB2PyqiPiOs7_8*>Rr~4(JTU^q#P+5Mu*YWIa_lbC?bpk$( zGIhQGiLoR~Y=$xc+s?w@)3l|LI`a}hOZrKb@r+Q53cM-Zg!WtemUkmgjvgC(KJ*YJ=yGd@vj+ z(x%RHPt^XI-D4Yy|Nqe@wK{;zB^7j~$+ef-lnvSL%M6!>6T9Wj6!6`u4QN)t3q_ld zVx@W3Gk1KD28&L4^MG~u25g7P=`5RO66AV_2P=^j#5q+{b%y3d2}zKMamn%$MT?Jl z4K66sv?ULnAOjYXE(M*qDn2~Sf^cZwMi9L3s9;k*>cafp9>f74C zvie0bf&v$-wMNk(qMopaANEy8HS@z#Y2q4{HZEoV}9}k!?Rb1ExvYoPb zRvg4OYS!SDFcj$!Vfiq0>kP`pHsICT2PYX5UWXx~6`E_iJ}+v^n^+;cq%(WWNt0Ty z>m@km=qD36{^{R`<4tGfgtk4`L>KgGl{71I9lK1RUO=!&OR_X;nfRVAzcBN}$mO3T zM=w9$n3Reaog-}%S5_nCek*s3guUBaV&M9RlC@T8zC2Q$AxG{LIqgz*{>l1w7l|JG z8Sng`=9NPH5;Z3^8 z1isM5U;3v{MuZNEgSk9xgE?PifoO)P{4j6T8dE(DLGJ%m<`|RyRX*4bRGVlfuH5;L zy*etH%J^MGYA}BPq+Ox6XCu_{e&{P?q~P&tqmtoR{r53T0_sUoG3_Ek2-mqn<@Qi# zw2?}Llq7_mx@&D#(!T?^p@x@A^e3i`)F$0=?}n8=>rmNvqn z|6_KG&`JxTL^)-_yM!CDqCyat){;X$G4Oyld5DP|v$K_%sq4R2#PrR|l|dZ5SZEQ( zGM`f0v*4ry{mh<{ydmlTo#Cnk)BMGwLp$2`EAAAkoJ~Z?o1C*X9GX5zoy0J19$8L7 zKi{YSv;!z!2x2l^uia^+Qwez<^8EZS`RX2y9*qab&@=?$XWT~@lQSCYyCZlN#AuRw zg4DSe^X#q|dZ(+M+3)q|LNK{C)e%(9?S9m$X&rO~0r|d`bQk$1! z9B---^8PP3=HqFcofQ;@{_*L-&k)8i!NgY)S<)hUFCcru!}>1L%)oj6Q$^r0a}jcv zqB7J*^|(BgQ%WJF?^KsNyMfCAhO~fHtU?>$Si&uGALps8KS$IfPGe%reEbeVAHIUU zCE65aneUW9qO{}{n`KT;RWlGFAJfymprZq1MN)ylme@Ek&cCp#vC+LlS-AG(UdA&>X)7DKSN?KODY?*125Yc}@$YDSNY~rddEE7c&i`6|n0D{#&v$pWTQ%73XL2OZ7R#LD6+T%Z0)~XH zz$oOP*ZnRx$UuJ3{lbmKCG2JxT<~F~EwpkB7<8 z1P2g+?PhVU2me#jDY6|98L}7Fg^@5$qRk&giJsC-b`%-^AMz|*_isUGGAGQ%)d)i4C z#j5?irkKxYm~>%Yrem_(d&R}bOt*yY!bt=TjzCP_RtSk?OeM?UC3y&$+mN?<@J{xs zSAO-|&T7>L=)a{BK=_FEM>@<+q}}gD7D13rB$n`Ki7$?;Q(MvR@BlJ}iD+{#`LeL? zAS0vF2!EsKGm*yY2m+jB-z75`+8BX0@IN2@FLsbTyNUKIG%db~FuHyDg)N&VoN&!z zk|~U`5t179U-W{R60LL?2;BTcKxx2Ku1O9=iRaoTo>B_z@Ycs7v2?#pjvJS%-aeZTW4hZTl+wckCL zo7t(cOF89poo(bON#KQj>hvmA1*gbsjC9&b0yKk9r^B6-6prRxSCD#~Z!fhRNc%zb zaW?!4_VpH=gV^pwke^MMA@q7Far=(kvrrbqb(U<4Nm2*{4g9md*BL634J96>y$0OJb{T-24I6^!9u3PP87gIN5M$dVL28BgOvk0kpr2 zR4c=v7OHo^1CPc01CXMEYGG>d@4JmI(GBDAK^%cIfZw^nGi7%r{)`ib#851P9dFV~ zgtbYT zl{DABfsX?p-qA~UP#6es{0~F}>X|6{=#jMbeUN%lXQ`mQ54tc`qB%z}4z@$I`DoRh zD#qS$M^%ZE28O2ZlBcZitg2-OL6us7@E||TneqQ<*c1K~iDWk#E7OsSpauz(hwSk@ zR=enEKQm|YweG*|chmeT|A1-?)fkVs2mQGaY7J(AAltrqD$nahqN=&PFCh@Y*tjQZ9)gXrc-HrsF|1(HuT!cwkKDf* zpb(NF5GnARz>_9mqoc3UV><~2Z;z5!prDs{;TNOALt;7ZS>&s=$R)l~VQK^Ff`E*4 z^>d;ovi=tdYf%@jS*TN=9JMn0GCqI0!4EgqzZUO@G^z^w%ewTCFO-e0c_rE#E;?&a z0!e^huy!u#exeWk$e~F&*$ zrRuxSFdDQyi%=rSmzab;qRjW)kYG8sQ40Lqba%c+~A*X zlkAWWT}O>o?=cnu#x#JYus|a2(jfESb&-T4wo9mE7?Y&gc}VDPu#H>PQa5q{B+eTK zlkzDCSib}HRqF&`0~2=;87Jz1QelrEK}rn7Er?_A6uBfc)qu;yBne@8E4%d+xOf&``hQZPq(Kt381n zNMJ6fdnaCM+&c1jyw4H7c0c2EUR|7u`A>!YAp7r#70yMoBVa|)mGWYiDDjdb5|QLB zcvmk-6YB(<2qDkuZe#U?W*k)*K_TFZCS|f6#F^ZiGD7+!s!x$Ew5M02W2YY1G}Zs*n|-z-kF01(G{}*#AKDOMY~N973*c-b{jjEjMJ3zjrMTyf*fi zrW*7K2Y9XceU0XS zkpu!Z2Z7F-+kXRzxTXPN((iMF@u_&oD@MBDtOjwmiF_glGU=|)D!y+!IHjA_!ZU#2 zHy}K)#rcL;Gv4wEK#v9MvJD@HP~=ncUugNUEk(QwF@`aIF&Ah+9V+qP`UfsZj1Vbf zQ|cUGQ*M5DSQC&>d9-Jk68gM<+t-)oh4EtNYpp%d@u>!9hkzX z-{kajY4f69F5!xypG;II@%0AUg5wU06-~Akf+O%xxHuJnp#(vbMe9Z5)e`dRTx0C{;DYM*{I4nc`a%VmvmB&av)8-%*VH zP1~hZ#K+Kp`kiBZ=bvAEb_;E<-0MgA_xx}3z$@On$^qxI)qu ztwqiI0^v8%UIbbkUPw0L|NHmd8kA)IbU>{g+GvgqHzfqR(s5J3Ey01iECet?Fdw4Q z$F_HFKehK+j*a}6#-!7+J^lE0j|td@699~@ai<$l_>=;izXxG0C2p(XslT3we;D4x zz^20h#wzNQq6GP5S7-So*5gOGQ340(_hGUK3pjT4W|!a!D_3uYZG@V}>hOI7eHh9x z#>UfuQwAE~432nNfLPgxR@|-;+FfsnqzAr15p6HD{JS#xFMR=fOtg7%Wsu5b(&TKD z?vNLoE0jzCJ&)@8oE8qVg7)}^zvotNV10)^R-L1V0%YaDQnmvv_-j_ggt&{1TLP3~ zcNqS?vxj_$ITu>|u1+4f1(F$VAZan8e5>RAN)px{o{iC$G|^UKI|Fg6j)38W`$#-t zY!{F&lhX}MA2zeWM)#!Ih)>-ADZ*OEzK_(U86Xcwz!Crf3OAVlsZ;XyA3+Qnk9-|e z2=sp+Na1bn%9O9TrS|*?eeTt4{1F%t)^4ATS$_AJ1?fRLWTy=1`}-AdGir#y78`H9 zK#x`San7DdERu9VJ=Gk&#{MRM8XsSRs}Kj&AyZ>ngWS9SFzX!-ctt9y!4-Apr#e94 zjnH-FR!auc$8jAT>FVBA^H8TS=?wWq5*-b120`-t6KmkgU-7(I^{(+i@vcMw<;oSx zKF&sAZA73uhVQ-XwPAtu$y03ZT(n^Ourtt_LAd~D6U}To!jo9X`w`(*6Qg*x@WD+F z%I5@-TOjT@&LL#4@RP|9UkA6eo$Ip6pDc@p)rrXQ@w)L7?Z`G3KjNc@eLl9gyBshtnpLxM{WkYt`x$c72n~&e+ zj~|FYaKI&?6eLKi1bSct8junAfQT~%o(VWU2SVsRbOomz;B@fpA@Eg>XA28FGYkx{ zKXt0{=Z=5lBZ%`CZH}2!$j>B02SsPz=v*+-zLi1;S*&YRjYz)16onqUkrl~(ywk5n zFbBG_6lmI!;(}LhpSoI4JT+^2UGKklYLgGySqAiK%M^jI3R-z8V%3`~55ML3@lk+) zWdvKhdXS_#G6;w4-Z9plAwc>-cVy>N8|y$90j$1JopO555M)3eoeEBP|BClc?B@y{ z&Z^Uswoq8ziVy(N{}tjuvu%ytLrbLL`iaQ^jC4i#@%KBZnGek`_i5hJk62$a0dip@ ztZuiZY;gVxxgNz27LbnE?%$D%Vscu1ILMjbAa73?3uBvuY#-1i&&TMBf4g!8z+{Q% zVapcr=&@qybUyHVR`yDJ1oX zm+^0WE_f0rC<#b%MU>Q_6ou@0&Lf zlzqWEbi)9t1(11+w#~sEF&=`voGI*;QDs74(LkU^BB*{Kr;_bEu zqsq`Zr>bK!!qbOC5T9}P=f|K67_f?M9w)~XNNTphZ( z=VE<#cDRZ|;1 z6uu*aM~r`uKe(E}ZlQ8ecoqo80J>t6I-G0~g5oWv0*fishZW?A5zVcKI8`v*`+a_> z)GTO!Dv5NxKXOauIc5<$cR1H}kmj88LZvlT*aR!{Rm?+(YzxLhL-Gi(kX4QcwzM&f zn|g{~$CgK}O6X_E+-jY!3B&^ua<4_KW(`3Qr^7VoA*=D6UE z?^jGAITE(-QVV>mzZ)c8{g`UtcLRH|g1q(gb}cPd{c-lWBPX>dXRrMV*b0sFhQi(3 zCl2-rKYWt9C;P(ms|-uupwQmn~6@W3;r0t`e7&hcu8bU@KLw9+_64 zjPY&KWBqx;n?mJ4(h~Z3R+|&Jmn?*l!WNsOosP}!f9z6=A$nDledohi=jj$8NHJ26 zKxfbGhfx=n@vPPo#On`3GvvsMw@yi=xsxvrqOv#FMhvz;W$D|+^YRZBdRFrrSKN|b?Pnt!R*!95J`_>^9%8(b zzcyH+y}H|tEVl0zM{Rb8n+*h%txAhJuK(J0YUh)Sihl0+ebpu5IdeJo(j^3}0a}w7;z!j)?)LQTf4%0sp8yKH@l;Q1QR)KV z?jEA++~S`6N_|11%dH3K8o-&l_N}2(nVWQjmzOgHWM&dO-#7Pp+N2pJ%B4T9eI#P@ z`?RO)&nJuHWwEku&4?PcfII$spIwU!tpk~=j8(Jm+2|Jja^ty#t;)=7wuy?q{d#W8 zbO)Jd`Yo<~eR!<@Ntpg1UuPXNW2?aAS|aazzNXZIjtDKG&io=Z?%K!1rEh77OCyov zaTZKF`X-+V?F&DXqJ1&b>0zx(*~XdC*KBl@jXeA#+Vo2`{MPdXohBrti9Jexa=ZRu z&1ibNcz^Y}ag}3CsjarqRfna6f%?1e-%sc-sGSN&b^* zXmm_DiS{q85QrP@oy(&1$`Y)N+;2jMqi&%Rxha!mwI~t40eN;Nsv4El^f)H zZBD0sQ;^Mw%5{cxCi{C|f8r^_Q@H=T^|VUV>9VNuE8jwV3vR}j(21e1((r=XRCs*f z^d2BTDum}LvyV3idq!kAb*pl{31sfiG|(*9+f6&xu6r(ssK59RuZWy2l+hyLZVe6z z1%E_ZLnhor6)f|VzCwT)(Ymm;TeY2xMH)*XgD`XGQM^FU3^qDuHD6c@L|3j z(2mNx_v-tJ^xWpjja$Hs!R6^vb(Un5)6?&xK~{>@{u?ttFtc&@yfWG*>bV7?Tb#dpGSirm6(f`0=I09r32Z_W%_@)syRYF|c5`}Q92%k7UOK4Go z6(mk9XGrjhO|r^{;GR4;*#4#5Z{Y22$F0mXq`fql$AvvOXtm~8Omccij9MC%`-GV{ z)C}H~upbuWnb=9n)vM_Du1xc!MRma2ed1i>Vm)NisSt+}9 z2!wkEGLku6%Sr*9PIrs?dSd+d`{W|vH#81rD-ZJwUks}bwCcIv&7x1hb&M)Jldtf>d_cf~)#I%{3!HCB19TCdLaTs$GkI4s4gHptm8)E7q`_pu>o1X8g zV+XJ6+Byd~Da2MknmF)5g~UJLa;DGkzrTtTv)GP|BCc?q4@|m%Yt}|>`$s8Dif%z7;!?V(SmJjF4l;{3e2cqBzuUjnq#sT?h5J; zt8vw9A!$@~g0F|NdtJuMX?qXdPY>+eBp7{LKlIdS8M@2&e^qvV(0t!N?sCq6t;)#E zr?u_Kdz57IlJ33H%uZvjYfUfIN5`i79U*DSsBJbY<6*R62JLw{*<14aPu%6=Bc3&m zJE!G`wN;OI?jEFWMbMw$H{}~VDcJOhWiw4AYQp6V zy7MlE-GXJLVem=wCv~SDiZ!mh>TMjZStW4))J5_{KW(K$nT=mD!|R#4bCo&8yEIJ$ z7#Xu6AtQIJ-9TD?2cUX-Ew<*ncR_ixK5mbHxcL0jt_8-HkL4zR2ivvIGwLsXN! zT$AG8l9u|;^dNhxO=#U?<$mw)+;YMh%U7IlR+XTPidJ9Z5+KL5b+sD1E4v>Kuw!QY zHAXAG^ZTPL6UPqr-)oO%2jV)Gr^9~PF4;tjo-I}686Op=tO>Jjizy>SqUcXYk$k<4 zPZIza5vuh~o9@_VK>?)DVXtkya$;xL%p6p9r~xxP`NcdRm7YZ!_OE~jn4QVa-yAt( zXNJkaXR=h#l=98o@J|^odUz)Kt2zwlMs_a7d%!o!bZ^X%Pj;#LzyhG%UgS|$F>kEd;g8_M&Vu{rd-_>(wXY!}3DSfW=h+2}A_nsm)x zbJU>({oYsFKU6J2k8AvqM0Adl?@F}yvD1M1)o62CPBL~UYaTJ>bV_&`E&A zpq7V)#wcEF+OwZ$ofM-%jC^L$bEC2_?Jr=eh*cfnf;d_TJ`&ofn_wePNEyS(BrF&t z>jn*k&N%3@&XjOtZ*|sz%TRWgT_ljcBRWmax)hG{_tX=7S|#;rY*VZE{`g6KW#B9S zoQRDVzK-_y^+)cvle!rd`(W$L^`}P*ES#mjFg*5rSU~?W!s4K(%WRY>b;R7`QD6ec=+lNf%OOl4jQ|rV#8w&C z9POSe*Jpscq>evVsE@W+*hn217d)B)dQL65*3c~CI@fZur!g1}Aq z>VZ(_+f1Xxd67i7o64x4X{)O~pGaw+dVe!XZqij9Pz4#nO!k%2swGOUId(=1n>ozC z>d8A?lxh-ZLwszE^7OC0IqxsGS#M+QhiflMZmpj**4cQ$VBcNnXXm*(5}1}w+s8Q5 zDwwK*ogl}xbopXG{iZfi(7RlrfPD@C!hN-_-v{$sD%G6}e5x~H7MZQU+4k65JQyg@ zRn?FxtqpO3#MU-cv?ge|)q6L3=vDaTYz}3<1o;g?_A+!TZqT?<;B9rHtf%o^>FZzQ z5>kFR8t1-gWjSoB9!ZpFXt2{4du!iOE;n+&sSa~dRhQ?2*P8j(xLrWp!!p0uZSDb4 z@%Q`QxwS9zK%xTgjIQ2IVU^&$-*X+`#Z6`Pb7T%==bQ5kQYYlzpbMn*LhJ=#h|i*0~^z+K7JG0ib zWtkg`^{47vS0tMI@A_QsozE|KZ?zl=d4l_O>mdE(;i}W0aRwT!h7IS>Ab)Y#o~so% zYr7uT`TbSJNtaQnhVnm^+wfhN!;8DWl9+;ZX>Cj!Px zw6eBrP?w{q$9p$}q-_f!e9~w>3)t0}8Y=r1Wn?5C)q{RcD=fi>ww=!%;YUCW* zXiawpn1gsS0{05K7ICxA%iD=BQ|=qOe~)0EU8l8SA$nNB>h_HhpX(*IFN{MG;tr2= zr7N=Ecq-j?d1Ud#xGDd0Ry~CScd%wwXfv5XPBMJ!fJ9jbVE|zys-Hnc(NrB~xpXyrx%0SmY{0$6V(8 zkjzWNSo$V8|HRdJqfQO=*#`2xJ0Kq%-%{0eh$c2l;`$R?IAmzftyYL_t(UrX)oGQ^ z!gP*2ktS}-wYzzIc5!gN`IDHwOT-#(xFfjqJahGx1=rn?b`h`j!FBY8s82<^%MV5k zg1u+4S7tvcE4aDuPEFACE48c7PpvMffs57D;rV$j*C4-X3X>(imE|eI?R`3Q@0^sf z^hkz6C8g<05GMD4=CQ#Ds{^|^Tel=(29f^;%phmG5X4bT3Tb2{?@aNI;S6ZjvUZr# zd!bT@Zxp50C#=1@WyI==qL+OSPyUNkF&8nVj}J!Hzhi=|oRBr=rG4wwG@KxU%JP!K zhFkMjf^K)Zom=&(dP!B68=3sa?^X3nQhqtyf`&-0F1eNdFdGegDWCtx*H2seGcm>( zN;Z~(iuC>Mgj1(lyYU`(k4HWydg7|$NE5{*_!&XM0AFKn-n}tz?v|=8{qe0#rh)7E zdv4*@9CKBS4{3FiiVFCh0>bdnuG%HJ{M`DOP*CND`Ol1cKX#$oiY`O935n{a6#I6w z-T~%fbn};xZ_6_!C>zu5fU7c_a7~fnq9bxW5)f-_Z;BA(3j>KiM|K9*fB)-f zx~YPXnjD{a`6u?F>Q$ga&8zr5c!_~L8` z31eRl-iK_=Qk`!Ny{qA@TZoL(APmN~v($4EVzt76FD zJpEyPtdeM5pT|qFbMjhoMxXL75*k2Z5= z1YzyC27NL!bsqGox2?IX?`S! zqE|Ue3&grF-`X2H8xubfRCWSe6bY*dl^dU&xe{{;&{1j76-uQj$F;!C+vi@i{iCC< z(spf&VlA)cJbVRu5+eXPlZ#?e{>6cm`YAvD7iIe1bU+3lQq?tJ>U$s*1ulD}@gi%U~)7o=ivxPcu z)W+ku%Dv9y7RIQ0x022F515&ydtRpJNS0PtVq=c*sj3rvmC>C^kRp*_O3f&9@~Y9C zRO-Oea;K7BGZi0&RMFK{NPV<_L@2KHEhsR`up|!f_{y658Iw zhO$!pZ%5c)@4X0J*%no>7BG~1Y6`xF1{}Y2s7$WyxN0jIX}-cA}13GrdTZ%S&e`fQWC z5Bu9Q3#u~?IL>3HY)XEG0bKnB>+mDL)AVylns=X=11g?UuJHL7E>-^J?ql5*mZCxa zU#+RtsiH;py>3!_BNby>0qxSvd_xoY8CIY}uXtCXMr*4%Nd)(F@H#BH7gYwqbBiI?`93WTrW_UV+_L`hOS z7Y#aB2@KX;wcgtlIZ{BSk(~6|b;gLfBKFD(Wt8OIz<}9akgms7qZumscnH3A2_E z;fHhUkei%9kEsQ!RoITQ&nsNhlTR*rRKig!E%C0=UtUwtZ-ygQ((ZZnn3~SDPaHyr zo$T6L3Z9%3;d8l>)fnb^X5JvI{bI)-+!wC(cpe4k`C5+Esw>tpg*a_7#L$XU zPy4iK^Lps&g!#DhAj=HnFWFJ4LBBm*bFp~TunA^ShpMRZnoRfzPfKXkB#_&Gm|)*Q|(N{ttMx%0DbN!YhqTG z8rvPvDOp;}q>xf}Evs7QSAWQp8jo2ey;W#r+$;ub%@)eor!nG>r;}#-9k@dYyc4YB_|(=p1W|WMmWl>@|sgX zT8Sr3OnfN)=p|}q!fFTMd<-M-KF;!ycyt3$Hg(fIw0&iFQ49}vH6A(=f_|A0ZmaxW z!c$TIrtjZ8N0cX{cv>N$>i8NR1bk-DAelTweH~yOQsfip+{IvpkXV86dJ&%Vm!zB5 z3eM$7v;x?XV>bwjbe_Kl6>|gziJsq?ghps2)oM=w3c5yocR3BMDd$#&Z4_kXtd$X0 zvHeNWCu;(d*ZpU!i*7=@(xP`T>8bM3RP|Zw?XOA0Fe4v|awjVVwA|yx9SX|FRWu0J z$}+dr9{DX#X12aw<0Q_cTpPXf0yBBTtIUSqb$KP0q%BF(Iep)v=d9kNGCnJRQRnv9 z+L@UKJKEOT@<8mQD$9<_q&03K;25KkMNVX@KbM_{?kw5F(?<9-%@!=@y11=xw7m-) z-&NzOY4}_);TChvG2rcc8NxB1KjsFP5Hh``D;U51c0s2@twhW%26Y=;pKTk0g(0Gd z1_FlDMkPQG>Bp8P&SR6oH@8z+x(HAe{B8IG*KoL<8k=d7>A5B8q$2qDT!5TGg&t!u z((${%;SQMG=ssKM-**Ror*tW73@`@2KtK4BZ&+6AR`B()UJaae=-76};`(fjSe)(m zHEsfzF*)UoaruQ!|9y1O`eN>Vt8l&E7KK9}#3p8pzi7Dd%EWE5?<@VFUG8uLDaJ+f zYAZF9Kf*gXIl>iQ-0ZWK-#$~MdYbc{Ns;Kq^=yey)r(>hR)N<<=L{+r6DCA{q93e2 znCK2Rt~`A6^>*v(>7k0i5sbnVq<2!Z?4i~+Fsdi`mVIRNv^|^n{ zrF$7`l$M78lNUF#RB!uD>iK1t$iE*v3JQr@t|h)eU-K@Ea!^wcRvW(o?e2XHsDBsx zfNlvTeQK)5K2)D?;1w8IbA&-O4H$oVvKQeeOo0xA5*VDY`arEq7g?l&zm1?t8@*aH z$6yidVGBTF5p5U27|_|v6P&Z~phFG@ z8xNEkH%7A*mzA6>*XW(P9Szep@(jCU+zK;?=VRFIX1=ds<}18;-%FipZh1{h-yHZS zVNvE&k#WZIU=El2{tiqkOWCZfAJ3G41hLP$^`3w*AxfFjQed8WTt&LfHl}oV{~Y5i zD8Zc>&RPjFNt_sTs2`du|^TTxtr;+xx>emylrG?=4#H6?8Zc*3X5wjSewj z#N!8#>$(~%J$RmGdizVH+aHj(GVBI57n>Vy(R_>&FE#gav%c(KcdY_$KaxeyiDz2T z_M>0R6rP4Bc3e?%Rr=TZ3yNoZPnC3kbv^n!5Aqq@AoN+iqlT*g%R7B10O$S+`0HJO zuzTIYj1RQI;CXNm;xOx-xU=k16lf0z9p7GSOSLRZPUH#&cU-`~qOsYb>%R^~>Yd-a2NTeC7>WSZP5 z?Ri3d3|w)yI(TbJ5;rU#7Sy_EjbOD3+TVdf4HtL4fAt(Z8v{LDYE9cp{1dh?iZV3u zTsj~46?)oY;}Od5b;8pFZ_@Z5zWU9E^Gx7oRCRr~rZ%o+(}q_RpmZPQQ)}(~F$A-1 z&4#(m*uP`P)-(tG~N>BNZzmAb4zQGgSN6xhPd>6536%X>b&6Qe%u$tZ8X~DOU zrNbcV-_2NTdk{BVY`OF1a@1L%#x+En%6X-+(}taIK_LcA2^{2LA7!<=I;`5^-S#V< zr+;e+{Vz`qfM$Uj=Rq0<;s9@Fm6NdvIF|Uk>l+r(;OUsJO?Dh^Z?nS{5WnRUREo&| z-pg}`KZQ9YF0@j-sm$kyyg9P4$J8k$qG!rrEO;N+25tF3DFYkTChFO7tc*79bA1Le(FGr__|NOu@O;^h4drw9>X78=N1?^!U1ybxR zM%udbm7PF61x3Cfmy4Co8dO$~#p#0?1LRK<+sUGPFN_YWybE7ztO{DNPIM=Bx_w?< zX7-;9wsp4v_pXp+gE>U@ybHzns_K!WHocTWW#*!P(dI7&OKneBebwG+$+wbabu3Ee zSY$9ZFNlkaQb9-4Rq!=e5>4c22kR4>gHhd*=bO2XS1`i{m+0HMVG}% zM|QYGlX_S!)ljMynbW`e7MLNydt6F?-v~vpE-)3uTGnG;eji+LiFBgr!aZCQ(<}&G zLWg(a`+i?>{A&Eu7X9Y{oA9+^3B)0XaYqj$VlY@DB=4pK8phld;0FGdO~I%SatBR# zCIufhK?^>WsoF(ZmuBTiUp&z30b|}{YJwzme1?WcX(t{q24@o3&3g=7Ne9}vPE#mT zVkP?iZtXp7=*LTiz{l~s9H!OQjbQp=BliaehifLcj6geA4W9}D81MiM0XlxzpK5v~ z_Bjb6HMIs#K7(lo{#*XZ_$DUK=q-Fbz;ieyZELt==m0vlW}4HueRL~UE0|uH@VaF2 zccs8Q#R#h-l;HMaEcE!bM^OI?v!@w+;mLV9Q0=65grDeIOaomQWyiw@SD%B`icoiz zi`vbJWZAw7hCPECfwmx}&?Ju5gee1De-CLJW-w3tw2RHc{hqpHrcI4SIWX|Nevct*IqC3OEk~&h`PP-{JJXo5LO=7tiRZqH zB?ZzrfAL&B8qqz1+lnyO@0Mq;^&GcnKZ3ZWj?IkW-pD;lXRr9TyB%n0U=%L*S3iXm zo^=Fm)a9as>uTSIfGc{%F6=mWXLtS?mx!79{W7rl9by+7?#YW|+?i~K81i+aKbyql zUI~?_ah9O(4ovTu$nQPM_ulWd4r20ja+g~E6((Y_czSm=Z>@S+NVX^^!P}I_UH(0( zT}7Pl;zs+eH@?&)nTT=|HSi-Q_#R@(PC2I&oAo3aqB8vHMf;wZsv0k7!0!|+a!<>8 zyw=(JcV!7l5#qE+41bRsrQ@v#F`%z0rwOYSVCZ0ayj$rUVJA; zKzVC;G_lhR44@eF4G|-M0k|AfDgXYGu*Cj6JD9UN^8QGEBFhvr((iLXwyb{9b%l%1U@2rzoNKG`ZpMGkkQ}94(G-D*#Z&F8uUl~lt zy8SUeYQ_!Smb!B?&&v(lx5ws9KYe$@kE+>! z`MNbsheZ8QplSv!$$$McJ5c5x$yP|%Q36O!?!lVj>`Ucnc67K$Uf~&H+%3#zUYYZ9 zz>xtGl38|<`CD6vw@)VA*=~YP^>fVe?4K?a z;~oDDdkWH0_I&%P2tyiJN(#hnDvyEL-Lap3eo{&A=f3_Nbark}Iz?ZU!Sy$RyE}ll z5XjNI4jG5ASIb${^zdTw<6dzr!G8@Q^0XsZo1T<|xNuI~C2B!1RruvT>&(A9z;1)N zGzkYQ!iRVt|5XQFR~LV&r};wftBi-oZb0)IA!dm4_6N%uCVa0AZzX|36|dw~VxTb> zp=9Sg^uIjL3606YR#mZLYw!{DIqguDZ>H?lwoh!WX{~{a!Fj9kTt7H*i2|66JN^C6 z4U)G8=vCb7W%n%>nMB>@^k(qtqXTB6Mi5XXpMr6c;uSs(vi(H@;;i^c#T4I6f#(S> zv4g-nJ@T98py&7*g4qN2qpkmCw|)C7ALW{@_43?Yp}Z@M zm9J|T8vN7ujDEnEPS(eNZce7@B{8=p6$!(IMWI*C^XqlOwMS=mQZPg=F z0ar1=IsU$yIyeAv=y?fJ{!vr^=n9-B4OqeNs`FG+e|_kYowLah$_T&r{-Ka_&9fef*g})YR;%y{x-eucl}WZ~k0u70Xp`4OF}KPJAFg_2EK? zte#$GE$~gyu#UmGczpEK>(3UKQ~ZstP1Ec_@P+}=ix!XTz6_)@hUcG95f`xMgsqIo zXRfw8-~`$w*lFVg%kaN0dEl<7&Yx?n1I17*)ATk+zuy5AJ|ww<+5;GE?-pikB14$yMsYhxUCfph30ORm{JSW?<)X0?H)c z!m53F?bzJgur1)53~N=Y;=TS?S|SY@^_bA#^LIB9tona}AjpcUt2BcDx2iycH}EDL z&u(d03|DqJSr%<>=hR@No4KNA>?TJJVZAxblXNcIbpu-e#giM-npfqh68<8i!ml`92-) z1uOs@b=~0REk6m^gmwu=IGG%MBqa>06$XC%4Y`giL-dx?Q7(0-`O4B`HSss9o> z($}D2(X*e>>u>*6*B>!luwvKpH(PQKw&c@lX~JW&Uve#ie|1@^4y4l^&vWI}Ds$mx zFw}mzs>?y9L?DEVNh;Q)*NV;aAzuNGo;ASr|6aBB{`)O_2}n0%K1T zRQ6y}r(mGz-ze7#P(?8i%P?g7=e>$+^j`;Z^WUH{S&O;-g9d^Fk_~4HdA!B#TVk8% zztB;*4FP{))t`MYD6!-=`R{yh4K)ixt=(CNR1Z1YpK4!D7y|X1}fC`^(8s zK=6XZ+EcBZH(1gpumyD}|7a7O(Ww7!Ak1rM@Yy{(99(vC(`iZ1_8%A6DI>E*>LBeS z!4F&A$TAI={QCQF8LZr?Cgw=X-Ttqidy?CPOEGijhR20%WB1S>5mMxUR(`h#*|dKk z(!~eQ*S5xfsA{3>8qI&uoi{(^WV7gFvk~l-vwfyj67#j|u8eNy*b@dEqS=8gbFxm6 z%vW%(fjWed_amys4xoWs^6}lcxTZ-W*VO|r1C{jsyHyT$*;#J|1~QDK# z!H2KhnT_29i`|X<#0!7LgpqJ`Zbt5fUaP;9OOn}p=uHNj9?h=k1W{oH!RI>`1x9)@ZL-z&nHXS z_ShU`?|ChtV zL)h%Tf9C-Q$dy*0zq&(l;a{c#>?%#%lJUoJ9mSdv#Qfh!hAr^lka9#(YguW%YGvNt zb40*^VJS!ji`9mHqBQy5xPfViA9GHS4BDL4)ORQ6c#o{#E4}&m~CJQ@v^=`k_ zEq_M^EmrtoP}jQJTW&=?sz)sT)eRzm!NIZM6ZB-;bnZCA7qt;3pZojq7)Rmja_)6k zoa`mF3BmdV{z)iELojFB(z+j7W+sz^gR#r)_av!#q?5wmU_ru|c>xj(Tbyh$Qik4O zDqEoepBpgEjM)sq|Mod}+V1sQf0oVoA^)cHpd_1}AwXI;pk}Fg+|E>iTbXfrGG(8@LN$L{Ad==cOWpJB($$ zbr1+s`QI*Oz%67$*6a&Z-F>#-c%1p*gnNSL`vzJ#NM;?HS3Xr_je0YknK@dU0t^&> zktvct6Wl8mt=fwcUm5L^SCmZEGiz9o($6BF zpd}^x8JJwNcIp+Smz6O>?7K3_ZSYlC+-z_*_LQcZr>@-||A~P^bSyG+t4J;;>nUMw z{PQBn4C#d8O~+N}==rRDyevUW9+1sVGr7Bc5bMkEqf0BJv^k)YZm;X+nQf(-*eEQ; zvKAigoFnb?9wN7oY#rq?5(`lBVz8eiticdhm54?@u=b$#M4IBQ^+5!Ok;{aS@+ zbMa5AOE;0`;+cgf(J+rj@WFuw=VQ_dX0ODxTu7(+FEy?kU8JuQF;)iEa3g{*)o}CY zFAZzH7Z0(g)Z%R#&s7m)^~{;X@?ecB6nA&lDrYj-2m_giYmxIN<-?c{MU6?oKM681 z_050R(;PW~1_3-c@2&iw{|I;safReY$eZ@_2l&6vz2J?*bw%!h{Yj@}r9Bl@s1bm{ z#0(PKc_dc7;SHDNh06@`x;wMwG1M+#oAco0?)oi7jct*(?+t7UDjoP8p<(5y-#I$F z9x(R8{oD}WCQpK2GX^DVu!b-(r24{Bke_xVtzRsD0|LVl(-GFU|7(#`9c2h;1;|e@bsz4vzZ%0{eXCr zvP49~*@rVA-8B>Rt&`cAuyq*^sl~Tb%jwtD{Y-&wuzP~l&3@PGh!XKAm3iTEx?YNJ zNr|`p*OzpzQLk4&@FZ;acw^3~)nvK+6VKHyjKgKby8D*hBst5)!mIUuF8kif-E;n# z@o!`3Vl%I3Wsb^WG!crEb#hCbd1DTS+3fi4`$>JYM%E7qaDlna(i)R$7;{dqnlGcQ zKJL+&9cI6|o;I?GRS|Ud6{J@i(V{Jp)Y)4p{VDNXu}zpt#`Gxte4VqS-d!Z37dt*@ zTK{x>)qWxJZM!iJ>GrE-LHqeW4pH^Dd_LQmGp}vwJW!8o(due($KT7NTIK2OuRLYX z+C4uMQeHP=IINZWG9FFU=cRhzyRDF=bqJ+3Yn{I@G7P)-Ya?|;pI9`feJx&<{OCN+ zg+s6^@rk!!>C@eebyl-Iu=_^=ZmP9!oa;)}g+_a*)pSR;_epNk%rNid`{Rg>W(R`@ z#X9nY`MJG(u1}(V&V)X>aF@A}GFk{&Q&O>LpH!1<8#iy=M4>x7hB7D5Q<$Z5cSa=r zl6WHfPZc^&eo1!{?4xxjfIfW_0;go1k@Wzw4*q5h4wKiJTfe6YD*}V6=&_ z{@2rwl>N!dzbc7q%-YY#lK$3y9@#L7_yH~O9e=isTCavJr3cs{*ukk%u1mN>+(Igd zHS40=^H>G%VfebRZ)=$-$o-{}3|C2s+ z=}*ddEaAb;bo}Chuv!#+vou=yWBw+4cxFyaB8NZcmcoig4AFijD`mEQeE0W^$nTml zM--O*WO0mw>^6iQhAkDTk^E5coZ9i14t zQ$JRKrTZ|L<8;SBXLAa5A4ZqAKlhCCQ)g28)v{20ng3Diu9NrJt<;N8ba-_zxcIu{ z)%;h!S^Q&uLr!FA2<)d0Ew8#d^kXZlJ+{0mvB&i(va0CumV2htutZX83{%b)h}qO9IVb}7S&ZI-~+_?(9e49tVmcAZ3q z8L`?1)lZe)2TczZ(CgWr-$MI&tArm}A5hHK`IWk~>V?W=^4&VQ_jHe<=7dLS2f>F& zMzmE@MmY|I*j6=Ko9su1C%aIX7oR8YoqO(K0ir+8FTmze@SKwW$|rMAp-w}`IDYNu zzMf=-$_?s2$nT`=3?f_7cR%UXe8Wkd0gIhvAYMdubUvTZB20p@{IIH@*Nqu_{U@7W z@cQQ_@LVsHs8OwIILPUfA9$%QLogf^4j0`x!ZmDHWN*YIfaYG+!p)oPZXAKhHYYva-OK z>uHD6`m;jKWK!rm@96saTfp}tp6<6J%ja7sT=bt8m;F`KGI)voyEk z({4MV=4OI<^TpDt`)iWo&1~=%pf|;nr}+#g`3GVrkuRFNe_9Wj52~a`ZvHBdcn>@+ zy8luJ?a_FhXVuQg4jLIsILuG4iG?RsnwGu>H)A!($uSc&j~g207m8l|7;Dxr18F2H z@8%bDKMPvg4s9dbq2K~U9NgU*8JTRSl{skHcEczg&FxiruhK z13_+<|BTN?AKi1C^6asZHu%%rGeLOFy5S}awJU9>9F=*m>-%6$(L7WH>yqv`Hlj39 z`5o#o7mZq-BP>>l*QxN!2f^di3cm`{=`x0=&f;Xbi4T;%4Fc2yS0PxlR#w;5iigE~ zzPgSO*mhk^5zVcYLDT%7IN10UOT)uc`F-~&f#JxAm2MUJzwuT#B*(HE@AzcDnmKOe zS12M7R*#*}MmFn<736s#;gq}HAx=TQXrJ56Ng)D^1n;2d-;69)vM6=MQeVY;rcCaJ z1eCCZJ%s!Zz6)NLj7FP5$)d$|Yj(I+$6`6lF$-RpK;c42`lA_uKNLho5IZhE{3y|> zn`%zzDE^FGhsaU&Ttq>C5JDtBF%0{S19E3sfx2hXFSaXj?HdZfpGqv{yd63tW<6NL z{yi{nb2n%gPIGtzE5&I`-+cQbOVllrtY|3>n0);ZZp^I_&_l~vk_pvp&GS`Y zmh;y|Ss;@fhoO!Vv(eOEPB~D8k6K`@h3xJqQ`_I@&g$zqKgx)r4`>F>;nP2?7)oHC zU#qD<*0<#3Au7B6Q6W=bCdE~9Vs_(9eX}=)l|6Unm(U!CeJ>qu^@UqV_yA42{)=U@O(EyfuR9`_83NKm_cvNm(MQ14T`aE*KxmE3HR=QkKeqc2?(NJH<#JUv)tb5gY6 zJkH&AkjYs}_q?d!ez$n(E1zPN`p%+iVr^U+($=rr{G`{&P851 zww;`8PXEv8!P%#JD^R8oOR)q|AHR;B7qsmA&YqW#hR3Nm;u~LR*I5j`vAW*e&~u*U z=V)#daWcDe|DZUuEE)E~s8FBc7Oty2K8v*-D4`rXVc)8|VT|7`5%xPvaZDaMVK^rV zQyk>VHvkS_kY~N}-nHQPgd{pk#|Z2<9>{C%Na~IX@sHdX&fq~LyCR*TVCG0V4SRkWBf=Ea{t(UQ78$_WF6}V6yeAoM# zeS<;@K3=AXO6`*0Cb#+xy12Tb^mv-WUed3hN`nF}1kT>QlMmR0zJOo0|Qw4@q zQ+>SC#wk-Usi3@=L{qe`E84zoOEGt#FAB%g*>Mwy46zJz|$O{umJoAJhO=dMEatetp=_JWC@HHYHM){z8VPM@p&1L zMCZAsxX|Eco2Cqc6$+ ziQz`!MxyFt^X@YA!&mP79UgY7>w-2UTBA@-w7fNKw11P(xUnlQcPEg^3j6NJDxHT^ z@#>}xXC4;JG|Q-|60ecrBu*x+nX!r|X9gCn+T+K#SEXQ?*|r>`2iqx+ygDZ|Dl-Yz zT$=z9&Fuw#9M3LPY@uXTn6ov6b9W#>uu7IrpoAafP@_4k?Rg$Y{+TaGU4QVY@hCCu z3s`-YD1wEa<%i-oJ>n;t$GdBfoUX?io&^w-dRU{`j8D#Aq;&NKiidnqgdK%Qy zXT{^|IS@l<<82=J>6>30)~_&kg#6_x+svq%UkAfcBi zN6uzuJ7Z!~9DY3U+x<)(I6&H)6uovaljc3;rDInUm)PO9f1jTnh7$Fmt^t=QBQj?K zx^=8ya28FMq9STI1W&elxB-Bo)raUp9c9F*`{6-#_-1REQ zFYX9=O^{u&Fq{*HB>OYV+~tW2TRNoVVupj#;|qG<3}wV4e)N_qD3Lp)SQ3$C?Tb=p zKh_oW;i*0(!IhD9E8<|UR%@xBHDeG7G|^OJKo~o<|M`?(TN+7r7bUra1B%Z`R)Fz{ zLnO_p+>kd+IKfmfB{5RbI%ZdANJQ^r-{g!Fp~JZfena{$UY-F8wvBd7eZ?*%A`{@I z%L-AKv%PqdnsV$#drbwWW4aDcF&)yzttTK|iSNal?V{nD@)zLQ`P~mOLe+JX8$>85 z!)UFFw@(7U5nGZ-MRRY)e%GEX`BX66>W~er5nrYe#@kcDb9Q5Ap#(7^F&I9)G$_}c zrSnw-6(-}8d}PEDrVTX?^+GS2gl5{Kk8^L1Z(Q9T8FB`sP3{*?SctH8gVlNtT(&fp z`>B{aQ6a7}RSrS{n;NLj>#umg&0s7~8+M+)D7y@l2vfM2VuO>JvKXExmRE|ggCUxg z-c!a!18O1mxi=!(qs3nHUpNDQNbt~I&z6OkE)|5HhsyQuVAVSKb*a<9-FsCxY zMcJikd?vHqF`g zev3qR(FGAfmBizV$mj`xv~m6#l^EYX#$$KPAhn17Y1WUXRAM{#EUY*7*ohkBfiKdf zWmavwi3QS7N+kP4WpmGvd0kM(U_j@g1$hnre~|_Y4avs3xDKN(=IEIz0e;QKOp~yo zNj6NN@=^bWR~A?I$NZ^**ew;cVgGR<6o0Oy+4e##j$8!*4E~hga_4eqM{_Z;e{ajcWRd*6lg`$ArP;! zhRO{F+QChJmtwaGJ|ZhFSFlF!>CoO_?TJloy-X!;js*s{in_%QziPCG?>mzxHG#}Z)+ncc=ERaZQ5(h*txSuIDGfmhz5&`^!AJ$)U z$-)jjqS4Z+;-%HnfK&< zsvYTvDX+MVAN6;3nS|w7xAQ>wocj$!5@JM)WDL4JX+w#zyFT;R`0RmQBb(}k0);Xr z?c3j$KEHc<&m}6uT0J4D)ei+eag9Q+#~F}TI>Z#RRIBOLS*q-5C>WRr!y0#Xk6BSm z93q2$i%L+m!jkt67L%Hia0w-d8*{>(E=UikCd-%%$MFe8*=J~wYgA0CDZA)QmjtO- z$zB!_uAi8T*H<*6vw?I=FYXS*gTFGY$Snq`I@^Ly!%Ws3hV(!Ld<#hGOxXNThSD~X zlpta32Zr*8GGJ#_NMY~M$Xjh`LdtfiKS`Y;(gxo&q3@xG-tes~*_~`_EK?4&Aon4W zo$3hjOELDH1aEXlHJ|CqiTIEYlG3kQb&p(GWa1PW7j8Ts)CpZ5x`>5jGoO`*_cs)} z`?X^J%z2t47-7Hd=ZDBV(hjsT*sz1l=O~N|UIo&9qJALtSrL#r|9u};=Xu;c(^J(s zx7f=Y@m~Bi`YeuoUXcK1#rHP5AiweVZPf~1meF_@!eC_w>@QPD))le64%!9* z0EaD$P0c*6#?_h-OSuP8E|+_@BjSCICu||S4jHu&b*+6S(u>k9L4j}Op)sX2CdR@o zM;tCe)bv1gYgiJlk%%QXa1QDUjAgjM9WWqmrwyf}tZg&%EM z!Z#h==G4oCQ7rhlYaw@SYOJg-1O^#nKyl2CsN4bVMyy$a=P~cC7$mWra>&9l$|j12 zVz4%sD173Bl6J*ivwBkI_v3P#>{x#XtGfkhWcM~PdRCotW@m*}n|SK9X{JE{>fmUA(W#Vc^syM*vX++Hx)I%B2QZ$(d)Z=one_?&iJ6BPWoA)b$?ttXbW=xGDKU+%{Sfo?P;Td z&a*nBU5L8Rw-cK-Y1?;wW!ksHSYVo#L;Rxf+g121O zisFZ&W)@V6oN5Yfp7>bw*jD2+|%S4EFfTHP8Mj(Jf z<0_ZaqsithTiT^0{|O6Vh1zxhfZ<%QG!Xl9w$q8)LBW?*oL0#~euGH3fpjKj zW|CxlQC51kl$K2g(BOZ4UIwv z_3e_XIf`{pj ztd8a9>l3>bsdGhBIPHb0rdQLn3-bAM(w;DL z-4#`;N{_gWdSNZbUPXA3lWbPjlnq?7ij z`S>b*;?;@}G^#E~mG>}}5`WSJ3f%zt!YJuxRUEf6sVW1B+qcL}+C)P(l;zfzUqagUk_E_x^4L=r+?D#uz%oKKw zY%L#gWzXpnOpiTtDA1_}bTX8byae1Hwr;V-)OpWZQGNK6E=TJe?il_$26%ega8N+hc`^VSDqC}qO~ zWp`?Ej2B#?eiEXg20G4h5yd$V((e-5@jYvv;|^~2E!Nh47Dzg2jYf)hi`0n{boBTFvl8~q4M+W zX;j)x@7Rdhev-oKbp|rHOFW@nRn=2azjiuBYYpECE5e~b$*LP|3u89rablKXi7!a; zskU+ykxsjNUnv-IhD|=>@K*6x#p*l5nH7K~z=Y%@%c{r}&|RPU9`J@nXhCZ(2XEFO zUG126CSlBe>7mP7na-xqz8Th^62DVymja4H{uDbufAaTcob0AbR)8>YZKrA zoSn^pP_z7)s2R^QvX;rJYLlCu$eS^&A)8rI$GZ2bEr+^-Ha(gjLEn4d(Zl2CENp4_ z<7JqGk&`!X@&kl9hdwn%eg#$vPYObR2K^+7T9L7ev|9cT68ROj`8_vkmC|LS)%yYZ zks>U-{PIdp+8|#?gK1pVPTI6vbeMzdg{0{?WiW4-qp3PtMxM0tgq(?uHaYtap$#X% zBn)A>v&7zTEF$t#rllVkrX#5}bUO@E!Z9H)VN|wYM_^^7UsfWz>e}!;hH%O8lx6yK z%FA;nRb-mh(rNpZR~K(d5!Swi5b_$p%^5SOuzrpn>=j5O_7P3{fK>G14`-xvjt;BO zXncV#7+gf!B#|2=fFe7D)1GVRd8CeJsqXIiAul3=(|Cfu2d&$k`RTpgLZPG!%hb=*Sv z$qK98415Um?wSM>L%c`!F1Zo!q@K~~p#-hP2E@L?=!O>s3EH9Qc$`w@6H5p21#5~q z6*6_Iib5J}z~~s6T^m=N*~O#oRmDQV5?YX=IyCl6{coK`izsy3e3R)Vh54UZA*^+B z;v-@mU$LF)hUl65B64(+`KuzmvJN2Dj>;XhaRX|}N&ITQoxG0suhqWGw?O@Go(rRZ z>feG_oBTKmazP`jUFkd^79E6>y2Ur0Cj!F?e__EyQ4yN%X*jPF7_Y?ER6FndaxH$& zBr3cdBjD8M2mJv2i0n^C6)Bg2=Z)jy@XZ-6P{>(6Cg6@zh#yvs6@eBo^0D-k&7cSG zBU}P}?r>CaX>L4UxT8^G%yd5lQhx|wC9hOok008yxB3U8Yn6o;j^NgwmP=*&1KUIIZ0O*p`iBKyX;zbaAzD(0|XqP z9u&WDEi^z18h%Ndan1H1a3gH5F~^I*xHfgB`j|wc0M{jE+P8*Fml{^J8{~|DW!aqN z`#~FJlU;U2MXSy4$anJa^B)GK;U9@1&%_na$wBj>7hlnw$5lP&&4V1kH>uCr#&nEH zDKIQaYxTIw$!2UPnocfPm967pY3~;#8aLR&8f7@xt#8Q@i{4t%WwK^CUj#m^sLI0H1`M2GqEm-HP4@8;Ie>)Lo|7*vSrK^gJN2ZQ81d zlLwB~*xu3y88?xuTQWE35OV60+}S*SRt zU6RNYQJ2-J_Tn*KO zn7=9lo&Tg@Om27*{`z8KPPH$z@A2UYruQVuABW^;zYcRtm^XaX2XG$>j=>M)TUp?` z8k6p>*E*Fm@0MwE$~TaIXjD9d`aHu+4gRNZ_>i(=cMbIWcxRNH&4a);61G)Mg8ogn z9f-_dsI#P;Kj1FLsn11YkEmrM^TVT`1S3``6qVaOCwSpjW7gPrspF6J1tTm0LQg+` zc2D$f@-rTjxG;Qa3t}l&v-^0|w3%aWaF?y^q;Bz*wW>JLWGVbJonvB5Cwrydqk@jaK)EI52)8f!zBE`7ueW0LqOR^_EL9dZnSc*hV>uyDBaqr=CV6q|FR zd}X_eukT1$&IjI#V?~>N=lY|O;#?_T6hYr;=*ZzCKU3p(c$*@se2JiEXC3jUw|%U? zxx}HfgZn%ufTKE;rDGE^sw`VR5?oO(bj|9nMZI?rS?ZleWl3-;9$bezEga&85&N?a zA@;*^cTg-{pl1bgvOGk3y2$jt-cwDocH?1pUrpLMt zmVX?Re-<6+Lh7=Q$^5|+d`74yYJI}zGIdP;+C;PIFS&f@G?x^*BwS4fiXR8AS`lry z5ko;)Mr-YcznVOVvi;E(D_kWx<&R(Y{DY6I>kZ#L4H0;X%yi*La<1@{_hDB$1-NQ| z&kQ?D6^%1nT+azI9jtD%*ejJbon|+`j}2}-7&`xfQl;8<^d!G&3iztc;DZt7R(iY& zriFdq_61c>eyFJCF@`JhU=RB|@usIkq?ERhW;}7nv6^!$?B~^CjOUr4!y=6LsvK^01=k68KefC#9p zd`1>BV8=063QGqRv(j?kP#4$b7tc;evX+i^eD$A6hupZ}Nqc})%Njo9Zi0AdpHZDz zMpq5EWmmFuGtDyVUy}y%OdRB4T%A!92Lzfk0LplIEK_(1FuU({zd>!rHUlzI7yG9# zzNje|O3$kWP)fMzdE!FmPwrM>5S+X5rbi2!I2@Di?1S-80xlJGf`rX8@s#XP%2kF5 z)EM}D#ZK4J!VoIcS*wv!r{^l_3-Jfb!8_d?qxat_Aw4Ft>9_X&@SBCzG8ZwMb(;n! z%Wtm@#3F|RDWjoOVSh;%YdWn)9h(N?cSxX zEq7Vl_>n45u6NZg!k?sG@g_C(b1RNCs(rZ2mxzOA;?CKyX11e+H0-w+tGZ`lhm=~r%c4u&L2;lg|RBM}SC zHd~3D;S@?ZRmMbg8PhLTDrtK5h&A6RA$RZ&j{4VDV>d;reA{oWG0}G_vxg@lWJs`L z4BYAuLsjG7QuhAjeHoWExX+SL3$tizF;{xc?udkM;C$Aa7}sln7^#WjwE+ygKbAh$ z;M1<2^WC62<*FoAK5KW}nDsqw?B|(g#e67`1m>QQNae<@ipZlDR$7}a*P=Y}^Qot$ ztzDG-HeNjlBulfQhs{VbwAcT7^+UtWgb2)7_$^BAt8KO6K`fG!{HiQ9vG43oOFens zL`oU@Ps#jSInn(6D-%nR+W;bWIuaBlxgpT-WhE{Y9LvAUGi&eJ#I1lWMcFC8nrBFw4A}tt$D==<M#&j#QW~C3u5~$FkDs13{d)k{PGVCw^N$a+*I= zDMjqw2Cy<-f88!O{pp9r(n*p(({&B4+`Cod9M(rvml)1Ix5dcghzaAT9}_jS;sx4T zF8nU+oy=U6{f9~(RnYSdIsR9yVZzrUYUFL1Jt6)ra3kzlo%H%eE7*AsrOjaAv{`DP zT9mqqf*2D*S5YnqJCE)%PK-_Nv2~>>%k#r}u@;%U;?wo3Sw$E3#arODuqGxe?fMuo zf~Z^OrHL~Vzds1F!94Z~4_qkN+scC0~`+1!ae z;3uDky8Zi6|7+)F&zu%NiT}Yr!=>Q|(b)`ox zTY0F`ds&@#aF*0w^HW&U2CP0PjRm4^l87d4K$iB!N$RWRi{(R;S z`R$Gm;;JTjI(hriyi^lmp5P+67qS49_MYl>b~tPD5v$blt+2w&H63u7vL}`NEMl%+ z&u2O#^01ONUs$|a@3dUX<&pPop-@XdbmN_UQKxQ1T>gvhv58wLl%?cElG+k+w>QlE zM|VqPB^SmJ?s3!7$f1>68-?tt%m!-eVz4bg1!AY?4a%)pQO9v<;^00WEG!v9WAdP4 z-$gpy4CB0k!WlS%Df%uiXs55nao*ugWWz2%OIlnJU0b1prwA3M-~ROiSVoI_ocWXm z2%2s$C8V?TQyQBbQBo;nb?#mB2k<i_EwRw}97tt8@engG%i{BqQ1Xac@guQlq&T*<(rEsYFh$@Fu^uamPlPjKc zN{LiW{I9*`!g8+*GCbITnEknjqE<3|eR3EVvi*@JV*qc)q%bdGRSmB<%=1JO08|@1 z`#yDalEErzs@qrz+T0J0Kjg^OD$-kRd}~>(U+T!iPOGbDr+Ku*(*1tFt7(*I>4I7rAQzvwBbX3#H%m4@dFPFmGJ*x5hQZra1 zCeCMmMEbWzO!c(_`Jm6ADN*BumyUv-(oiXxyu#$;hp7E7x}gDPt?##0#d9E5@K*=` zElJRPx%W!fr+!%#6*6g%7?a73_j1?0N-K?cJxzSEVCgSC#K+#D2}Z9Dmm#m;v5AiN zy}ZHE6h+cjNWh5n!h!KRQzg`=K>~5B*-08Pq21~2Pz<>%KiVocz2<32sz4$) z+7EAN*IxN6Wqti6t`<`?Jl`Gn)y7_|aj|2zcKfGo=P)lj#rGpZ_`}tS$|;YvzRh83 z9>)v<#V6Yq%I7^H^&Igbp5^QT(BlX|M2e!_ z%Ceo0XtuqPh4funPwmS`UoiKB3KP3ePCv?7a#A2e0cLbsFSzCylHt=efaWX6P9d!~ zkBonAF8m$^USP$KB?CDgs}aKsP|9e3h2xE%x6d~?SyBt?=XCql(C1B)I#rj=c!lQ0 zioFbj$}s3?)W@=VQ6V3R8Gh5C4{>F+psZeHfAc?}j0!X12LaIZB>NlxBA^h6v%VMN z7T>&FheuuuzrGVUW%UkKOnhw`X$hwLCOpmu_rBHcCwn3g(nWIzGg07lF78r#C5MSH z^YSa$g4AK5I_jfkRXSklLcPoHe-SL9wQ3FCpau`-|qYsneqfw6|ov2QlRL%949mK~UQJ=&Y8@*hSEjnusiM}l?B@xVd6Ry5BtOvEB}twh3chnx zZrbDhW+i_vr|bGhRG5}v@tWrZZ}^o5KkWL9@xZnl!Z;;!F(Gw6dR^p@?}X=6z*Aqr zyh%*H?u!?8GroTLihW7mCVgypS`x;L4>+<5T_sFB9c!HRsmPQL+HeCd!2*PXn|~sE z`<;IW|9_E9LVy|vlQb`y;!qkB>GBckZOs+KSJy?}I-GGP?lZ@1K?X@e-q@Ur!1Hd) zm0q|%u1QIPu~D^#-i~4xW|{gQpG&SNUALa%assq5&$;1z5bY;MA(&D3wTAM@4bD0x zQlNTqfrEF(r{pFXYx__wA2@)M2aG(!43j7*rdZ2b%z)x`=z@CWI=BIZo0k0c4RC{7T42^H^&K<;rrYUy^2dyU^bmW-X(P2B42QYnpitHl>%LBeuE!r!0$%$L&FP0r(sS<-S(1h zYWG<&X=VpcHgIm>iAe}_=*dbBez^Wb5$~Q>t^be0X{~_RS<+HNVT|4l zjl^h@B1*ZAC`&3VHDQ{Ws8Gy^3FLyX?Q;=&{H>aUHDGviyc&=+3U*Kdaq}tgSxL~K z9hEUB;m)t+?C{4Ydf93Md~a0r4|nfM9QOCwd3;`ZGrOO3+_Q7<_l6U3e{Ho-O!N0G zv|jrDrM}|^!P7xKe$!eu$nnCpdu8WsQ%o74iMsTs zpxvG6QuqYsZe|>xhfa&fMbWmVU1Xe;YYRB$x*k%9TcC}Tb!wkOez-Cj34`FAOE~$M z!;Cv_b)anSTnAD~1s?_YKMG%wm zNP%K&)rpLJ=dH$1-@j-z`nRdkA8EqSJT~boKi`zz1}oF@-v>>GdzG*iWV4T)DF*j# z6-F3is@8*5T~N-8+B0M4T2S>{?pTIb9yNrXdRl3LgKWQ9&1EU~XC9sl-Jb3oA)MZb zgXAkyYP)H)!8(RGj2vdLMke0eNLQYJ_eoF zr(vpN*+DD-*1f3BW_p-1kFBG zD7n=&eoGXQd09_+6TDi!N|!m5Kv+T)EN)J08MMM`dt*fxd_SY0>4*1M?W(V>ZE5M} zL^07=9lyb0a+8{bWBB&V8h;}|&gpP5S@q**#8qoW(Y$(#dNb7ZF9V@tEkynpTibd2pX0r1!02Z!UeZ%g(r6B32*)rjmw1DK+a2xLh9^>t z-naY&n4R2f`No~HT=67C{OQ~Mf0fx61PB0VQ**IIjH3#` zxyj`$jwWJ)N&Zxg6rumkVzwnlvPu_o>7x7dFLn#w`yvi5OG5L|@Y zN+B^$#NsnDwMLjrJ7f~4g1$$2g~|;3vG$*;h28^*Wir(c!hnR3USOlsNnE`;g_EO> zZn=z*UqQSxysEPa!e_|B)b{sYa*9#`|JBEruE2!DhpSkiz*8KLNcm|s#bJa!7zqtI zYjda?RTu;5zEGc$W0FcBGpOg;?S>iq@#jSW&s zGz z?W}KO-*;Jb9_7Pg`=4NVwC7jB!xl?OhkHoaDP5>o!v1wN5b#r7Un2_76Q4CDcg^=1 z;x^M!?0rIIyU6h+2p4IeHC~Zeuns_gdUUAmZke+aV$V&ssPVQ8{944C_G#}ADNOnC zOF`SMu}gYeM9|CKH+@2Z*Qw(tQDgE*U%KLGX@)f)3`r(LY$de2i4#3cw*2evG|;u% zU!+{TU}ZOWM>FAg^?D?}QPUCYa@ zWt+?H{kHpl-skzNqkbJ7eQ{mad46;TQ}~ElqcfvzPa2s2P+Uq&7*)A&f7i8imT|DN z2sK_%uAMs_)iWzA6}(cRBh#*|IzD^jLHmMYLnI_epNYEQTw&ux@_ zV4Qx)(s;KvkOF`o-v4TUP(;-l&z zy17I`skhz0C2Xy;MuODdb<#!lQeD0gXrf5mf) z`ZeQWLX0Eie4)+l_moq*Kf;Zn)ytn;6#4|nT$k$A=UIftq7H@Bo*o)&8J}mE+P~SV zKdGVIZeX|~F13>F&B7)AmTMdL_m{ALxe7v^Jr zVNGJv)HggSe<@#>{CL(~X0%;L`3||W7jAgg1D?XxmePIL)TV*g<&w|i; zJKXuLUa7e8!goGK+v~fUL$O|A1VYN&a5o|^aO0bJ_!~*CHh`{G0Sjrbo&+lgAu!qC` z(aPAUsg@5TefvV)HVi&>UQC1%l-unWpG@^hZX_MNo+1z^jSqH?j$Yh*I}vGg3j7Pg zB2td?Z-N$+dhQ*rtU_iLJSHZn_$tkYm)Vf#nuXnBk!T)e*&;<@xSLW+`<>5My&o|u zAaT$wD~KYa`WSd@0;Nv$qVKv%vmQ){iJa4`is(@DsRfZoY46sIG{|WU(#STl*f6r& z9>*O8qaUr3Y{5`ULP%n_9ZF#jT?qWJG2I5Aywr`P% zoEf+gkc2hL4wU0kq+X#Zz{zKZTfY(?0w-!}m0`EIPYSXlJSZB3=btql$BQk}7NKC@A0QzHxb`w|JCSXP&({8i0;1f^kKnC;5R^ss5k{<@UU z%oZi$^l%H?65tmlf$+_I37#ro%n|n9PM(`wx_wB!kIep}#9^*bM zu1iAv*l`g{dx<}F4%73$f*Nk<;Q_sV5M11AyI+n60_`TLDc`YC?3OdcJczQh;`uFk z6exK2DqNU3z7(F9xcm%?Lw#WC8wK?FwsChM;DVhjoVv(&Jg6?K7h8_WSb*Xf1{P>K>lYc4f z@vQ$dKRSM=?;atA>gQ$XkN^qOz?~4vN902H?k*v>LTZo-8{VZI}HIVse)i`o@C0$-*y*Jy1ARsiQA8!zeN$luog${D@r%c z0+swzi#Yh)JOYWJoFIg^g63%YvNQ~ho{brYobI%@^-evkx|p06{L!%z6J7__la z|D}}?=w6*g$Vk)XE}J-d-`Q005R?5bIhXtVC2vFe`ibVh@Y~m4J*$pSuQv3NT3C)6 ztKOHM(YHvEzpz95zm*aQ-IWiCarkEb;v{%SoRB`Br*_3t+`p|jsSITxm`dRj?zvM} zl`27BJc8(crGiCO;^tv}eGTaZlx5?KZt&*c+O6l)GeT$#9u!Zb0a&K{`}b5`U{0zAOS@g2>asd8f1`% zH!O5Y^98@h({wwc0!c%sPk>$<}b&C1u?jw0t?5NLN zDfZfyQ#Wt_T32Fvy^ddArr)Oe5KzMgQil6GaoLQ(dPgs~RO{|o;WM^uJW!&q@U zdy$Oz1QD0cBOT41#YyS5e%@~7n390;F4Wm`)!erxYl9ad=V=IJuV~iygj-kd=kdvs z(ZpTlAVd=l<<`LV^?Z&kTB?)M^a?z}Ggog=W!e<|AyTv&5|z$xk&Tq)mTs`==~k6C zZLaCop81fkLn`#KwaAYLT69g&_Z8uwfde0*Rsv0!Jy#+ub`t~ZNBmXfa)sD}==Wbm zf5svA?2yT%cUeEw?ArMJS`%?5kY~Ae_<~BaFAwtaI*{P)ZNK^F{=)YLuC0DoSQRT} zp6#$NWjGlw%qM47D8CZ`Hyd%hhmj_dRK*4h9?SV*VVToM=@-qSU-?Q#lI%psmMSOC zn7ts?UOn6O3CLgf8a@EN7cWik9R#omp5p!Uu%ld8CE8+*kR+hm~BeT31j%B$s`|-22_Um^1Z!H`mE`hl zu6b@Nwf_IotO@8Y@X!LbWRl;Zoe_-s}gIRyB1 zm(~e7?k%x?d{9QCS|UYtkp)Ph{;WL|>Bi#9Gyc>K;ZRg&Pw_mIu%`({ZuQw03t9YVCI_JB2=q8l z=R=@7)RI#K;t5s z!x@ZsNPY4W6IG^P5ECgI@fBW8w!S3`g_^LilXWh-OLD1CinD@3fPraEE=RV8CBN1R zuQ!@HU9>YbO2k!9I%el)n+gt|&x-vq7Q!LBUBbyiwBsis{LT%ah>Q4~`Hjs^ctsdV z9zSEc3J+Un!AXB*lwZ%Zh)!}-vZrpg0WJ~F&wU8rkcIDbr(8UukqMujI*5vXPw~y9 zB_lT0E#q*VnMRMxE*LGY5&ibwL)Ptc@R!_^vLvFr=dR$bkBjzR)rs^@45eKdgKGH* zx~20&=iC8U^8Gb2%m1^$i6wwzm&!y+L?*n2WMYE@YFG>fMv@O&y6`q;Sa)?**H%y-DYqkTwT3`bm?$FIHTZniXhFN0tnzXuhL+JSmyNK zW{)Mqi#Q4s6Cf=V&V%T`)ebddj3Zbq{F0SC9C81690gnJc;(vZqeBbG>aAsxE}cBL za&Hm;ao$i+PA^zF?h95;O~yfX_Qp;h8Tm2oFcz< zJdu#{(~1-kg)rC>UkuUQdq}kRw5ext$Hl z{KaJdD13|58?c*j-@HCBE1c1g>iCVrzCUbch=abn46u zugjME!zoQgoQ^N_UUj$32)m6AD=8a&y1H$cr`7GUi`Xc7YPFyjrq`Q2^t|?0K$1Pj z1)1_>l@;hnJ2N{&=_HpCKT0PCm(zaA6Qg6TG;<0_dFH6Ci4|sV=zm!y=dKc1W#f5K zu@NJ?nTWq(%@|TSZf0DdS7hmnrmC=z)G;1dE2XjX`paN`@s7WYtW9lXh)UEH8k#bTK^i#JN z+U!Vs>tbT z=1y!f;a(6Z1-cow9i*DB#y=8mbyd>)og6%#FU^~IYkL+Ecx?WXZ3&pvNbNC|m`R;< zxQg_yHPvyPL#Egp9lqfCTa_xof_UQ1r=EWl?r=?AqSr&GSZjN8aCx`#;NusEzJ&QI zZ&Fd*{z*cPpaS*)Mj8|sQkd=Giv15fTX)YdAp#Ua>yxgs_f|@GeIgQZRaZ_;`Z%Rr zE?3yE{Nb|;dHvkFYaLI@?v5qHTHDJz!PiNb)mn>dVRQW9fe%pn|C7AIC@SO=GHu1oyfDU49Xo5qe1??WaV^GsBo!IRSECazXiKEL zNQJ@k>n9w%Oo`JdtS))Aa^@^ACJTA;@Xg2$lrRPAkeNt4-m9j7L83a{zuuwRTxT=quS_5SB zF!-(uIVY{evW82K{l~gIC@cRL)j1jRU*;ebkO!V}1D%!#bF*dzr05M!j@T;oSjfNK zay+59XUGDo%D0c%-GKNNq{nI!6dp*DudHMeV&eo2!Sez;J}l)aQlo%@wEB~#Vw-@0 z#Sk>C0k>?~f|>|9I$M*k09De6w$=+XO2zUgKI@80Vzh*xI0ZCb2{5A_XW~R3(2w+t zXqeT?3VBpGkl$p#KGrcQo9IQ@p?(ZE?glvN;^iOw(bh6Ajq!a7zY?J0{x$eU?<^@Z zR3cUUc@3-RAZE`blQFf_`ns5UNANw`FWmr+BT3t;n;sIE=NBp|k?kWANMO_Hi$tki z2aJk_eu1gFI)gt9)(lx`mjU_S(h=<;c2O$w7-LTXJw|DXlHH|sl&Eu_lnlZS5eEom z??9o+;;Rmm$167f2wKdMA>)b#>t`08*a->KBhQ1-j4IW$hW@E^?U~XR`5{v87paF< zBjs45^ooI1-2PZ~mA=?7$c^x!A1UX@2a z)XX<_{QQ6I?eL47#X4lrXW57rnbWjU<1PBH8;cZovWM*!s65g2%%F*(0U4CW#`dOq zffqIDgMrd!8e%`8-*8qN!XPKttrZ5!m8isHB)Mjl9eO{l9Iwf&xa?^=<4E-AApd7= zEa>>R`sn{h@*9v&N+i&Czy@GFyO>Y?ha*v;snPc$ZxD;}pR$LAeo7Fsky}Q=iOr>m zQlS#NnGXdajA+er>V;C%#(*V0NWqP5^zdpSXvx`S01!nE8BKT(g=;e)sWaMY8@qV= zLR-+PKK2g)5*yW9l=8Gs0b4F+O0s2}3m3V05^DkRLxM*iu^-tztq(b`AE{M7>>O2V zvlL=6pCil?qsh`8DMr&n-S$Yf!enIfhij_r%ZKWOB{NdE_UDa1I-Z;f7VcRU*hC+s zzvIS3(t3_86j?h79$cxZ^G~9~jp-83N12T!Q!~f(Azc@tQO6wV1cu~|c;xI{eo<9` zJQbWIO8PS+i!u6fWR(r=f+s{k z5&MN#^1JX>ErK*_P+W4DeljT_(w{R_!BARx?C3YPkv9o$U)T zOH*9XCfOxK)@p)hEKRQZW#n-xpzL8MqhJ-mL{7Ul@mIHRra_$x1KK@WlJ57?OMCAe z5c(`*-3KsCASA(X+CCVsYgY2rD4A+WHNV%*w~)DX| zzbg0^tff=kM|e<`kMjAjRS!8&7{AgS%nOstq;o$n?B>bgSo$Yadi$h6h(dDQk=0=1 z7^FBWB<%=_=L0L*X~q6jg*JqxK5>qGDl7>cP}5D%9g+azvim|CWchiO8Z-_4?kCKn zLXn3Y$eP_%?ct}$-zBEd#yGd(rom7dYToB;rVsx%i~RzwCe%q{;Y3=h-zTU36cX|T zlu3Zi40<5Y=!*@Wg)4ARE0L2omY}$R_bw}W7KN?6J4qiJ-<_mvpJ2)ae@n5I)-NrL zg2|6Q>Yy)!;fDhe0TrjEHZ2_*PNFzko}&a-^9j<6_jW(YGaAk+x|(5mT74oX7^*w& zRE_u0;mUtomff%ydV3o$`#_-Bd<$%M-7jw}Tk1xde^P4?=?-+5Dwpi?r?!(Odzx5w zl>fwlx}s)$b_7yPWYvM?rL99-afPF_(TO5|_+K{0xeP_97 zuXAJat)e(Q4gKS_9q{YM4fG=CqruIa?|tx(Iffh_uIJtGbprgAfYEhmys~NimK%|F zOmQQzu(dE#%RZ?lz}wT4+aSTx>9dma3s60UBV*X|rnIQ&7<9a9L_-+W$ls!UmUe0( zqnS1s90tXl7LJeU&N}@%GV~8rWDj<*{6Hol^hoFf7P%!EPC2v5g}6G6Yr_~7oExEm73e4iptCH@oOr@}1=t{*LP9IYa^tSS(Y^8j zj}rr!qV?dYFo*t!5)7aPJk>_37@wHhK$Y$o3$43z+Kwu)kt3k^TosknC`ge5H#p%M zayWa+PHrxK@RrTkgl`r_9<&lb>)k>LIv*H~p2X0EU=!OY)fjJ_qe@m9sE@O=9rQz# zPa`6LqhHniUtalD$gDO>h$)|ac(6=1?a=P_%4z4%_@gU$L#sp-Zi zl}NRN`eQrsfJ=vj=S#WKzui%V20yNJgVyub;c_rWUhpoj{n4^<=y0ZB0gmnAiNI3z zyY5znGq-Pv)ZJ*iw>@mXD|`P=0i4)L*JXydbGu8V{vbO2TpYt!I_mglYO}zUgYYBq zJvq(Gnn+b{rynBp_P~cX(>nM`E1G~1-Dv5koW@Bl<6|qb(C>u)14lj;XrhpbUcYu$ z`qT4-bbJ`gB+hSSLX|~2QOb#Jj_$+y<1acKzE&_LawivPH)vT3s;x%CWUSN$s0j)) zc)S;7?_N`-47Bt})plI`Pi>$0DJa9?epf%}!QkFT#=e&EFw#Of;HpmuApz(K6dsR_ zlerdeZOYGMx>411SoigiMA*s0cEGMOpKW9r4&XGMj#j%+`mA32l_Az7u;=lty;?Lyz; zEkEiWeQI~fI`ota@nS7}*$>w5ON@@+=qe~t2w8#i`$OzM7^27|ijvW?SO3bp-<5>@ zr6d0RNDM3s6iQYK-*~<$J@AOl@q!#2(1H9QzS)1>sr_2|&C5W~wIaT6>Y`kd1k^Y; zBC<8n1G&W-$O}P2dM7kUKiF0WAx9Vjv0Avj0WPlpsX*VoXI#Mn_fUn6z}kmkp8TXz zzToC@OOjzahmd;ErId0&@vR*WP(?Fmmt|I9lPjWMiBU+Bg$|YtdV`31!s1TRQKC>N zN660>S2UKPxb4*bvIY@|H0kppb0?2M#h*i30`g@-dBk6OVoXt6Nr=@Jq@bUXDj4kfES385gNsgdkWz`}Us$wa_q?nT>&vzd zL;W;I;*1h}YqKGxM3khNQ^d&ED!90D3$(wbH+RB<07vHD%}TK8Afci>ZzBh~bb0G6 zMTkk+>u(%%snBUw7d1oay2JY2ccledWM-c#`*`J@fv_l9AB;#rW(66)0d67a0e`3v z`6$_bSO&8|9Z7Z6wz2eRx**^eCt`^*xlDo@vGZq5I@;M5`z&{ii%38UeX*I`?6thh z_L8+1GU^$7&UK?DH-XX3F-C9E(E7Tw%WKK`hf252%BenoK=0Trlric-Yj^n{ok?H* z7aGcf;~b=sk@&=fC#Xqb_P)=6#zfupb|+)ue1@_Mft;1=%A}8U90*FXzsq7G*&O+sA8P*KBaVdt7dg5^4Zh|37kH={s0da zakiBDtn-PVDIwI%%ot!w9-*mdA*YB-w?jxvx+xz|0oNNW8@>zDgf6r?e94L5$hHtX znI)x!>oWWAbw#yX>Yo57{8cDypwT+j-|Q_3$4QO6LwV^#M=pERqevVZG!gYJ_u1z8 z4&3YOuY$gX2b;84ykhd?$h{nMyx`R#LNLOfH!%|Z*_tABBRw+3CvTnb)X?7^pOTTS zeAXW%YjLF)bP(3RKV)H;jmUcC+7c*BRBFH}M{kQY)&vZ!HkY9Y_+PPC?!$8D&`Vg< zl10!XdrOyV@RdgBc9qoJTwVH1!Txr-1(7pw)%rwxV?ou z*d2JqY0yLdS=&4GDKaLDMA}v=lZ?Vtq7;c_$6S;WB#Mq0C};OFx0V_<{u8@H0vovD zHy~M-{v zMo8$|9cb;))0001A=gF*yp#Gis3Zb_lamhAczjmp{5*b&cc#v}Xh>hcp6kC1qX+G~ z)NUd^vUSZXHFlpooC=7KoEbEWAubR+Z=V$!Khzh*MbS{fhV7+SMk7^YWko?uB$Q&; zQ1?xRwTvjD$y78gk)bUWj3isbklIWArVTB4@KP*ZtnTADY-O1PMHKCg5h_NAhJ0R- zq#fJUer@`1mk&s}y@A%@oDyX;sCrMv*NX&~wnmY;PWSHHqf(zJ0;xQtlv%URDIE^= z$dn+JToNfH(z5FFL9T)I3(&X-|EK=P5MboS=EnYy z0HZIjOp#iU)~?(-slfEA4ssJGEF7^Mx!2w@dPR{-g^7DQ^SLNVz-}8oBiOq8@@h7- zBc;S_{(7oHIe@seqDA{(7=k#qGj`$pH56dpnadoL>JN*W9^@MM0jrJ#L%StZs`Zzt zK?PRGoEyn=5eHQn_}J-oPwk-~qySUpdRI+#!g4yToL^Nw^O+J9LCRh?IcLL0!&Pyx z_fOV*wt0S1FZ^v=YqPMNT6K~Wb}FPFE3UeO$(QXjb{f~j$qtC=U5=w>QiA5vvtk>s zzky)~NO0Ob*N;VITkBOkoay!#K;YgFVQaRZr{!{89OEe#3(5HE=xN28uKQvA z($I8Jg=Pp+kdv<^wEVS?c9^YohOH*7((-CNtl#3aU(BjS1mw^#b*d0wNCw5$YU$MU zhnQgwPz(<^k|4V0c!DbEv(P|A56}o03o`a&f{<)Od@U58GEw!HL^<1x{^ZKSFi%&x zon#WY4ylZe>>LURb>+s<%Px}sIgP>t_-+TzgUj4s^jrt6*(#B-It$Pw>I_Z5NKiqh z*T0L8quXs;vQ2fmncHE8A}}%{8|{8JHzm<3 zSIpl2Cn`eLax2L*xp%l^q8xMdW|{{%zv8wjBtktN_A>f+_tm)Qy;FT?6-9WhP2gs{ znX@F2543UrgA(HM3zejPQqb}a0yvx)3P}nwvqsb3w2*Jfvwzy$Ndb%ZWLH-a!Qn6_mvc_K@g?P1h^+%@alwIGm^R#t%U{?j@{cY%77aOw540-p?qibId_`OHqhTeT= z)AW~?Ark!{D_CvU9kV-%qp|}BZDz`%$@NymfnpwoCjDtS;Xia7J|s%LooRsjYz-By za-5bfQnJsh$|PW`dF>NyNn&~XhV_2Yh`u-OsQf4wM9mIBq; z%vHBR{e5XjFo{OoF~7U`k=T)tl2<=BJqtwOEUe61NWZKm3E~XxVQe(J3q`e5S4WMR zfQf_z9GnBamsqWnu|&@{P^7grqulYG1vv&|gJ6;nb*a5uijAvb{pobk{(CTp;k_RW z)~3ex1Dgby?5QX9;*{D@$`zKAW~zub0c4s+|Ma4eiG+#kxMZOGNq8Y>J@KrAZVERr@2Hn3vS9fM-`q} z^eu8qLPVoj^JVFb1(JPQL~b`~0$e(f zDYj_T-(?|Hz2vh+U@KN|2=8+%0GJQG87N{1@so_&UlO4-DZ&v`hL22c5R@}uoB!5y- zAk@3NMUA&E8qzLS5sl~3Iw4<(Pn5ZAn*EG`xN$viae?E6wl8%4h3*wP-*9i> zOTCpf+=$Jj)V$xXJsU@?_4y#OsuIdA+imApMP_&B_M!oxU$Ft3*?~Syb}siJS(!g* zmL*NO6H%K#0{4ZVzt!=8P(Mddx5i)NiT}A?M4VjD>^3i+0ocTw+?CF^AS^Hw*{bex zsfK=C@>KZvMJw-NsTy%)hFm%BbGMCMxCrVH^N zE!UOt^6fyzSNn#dD8$8!R{F~AFW(hk?afKjutomAmkP)@DQVcf6P|0?s}_(wipDr? z98sj>{fWD=5i2F~w{F9g#tf)510#U~ajNmAbz%%M+_A<2X%_qc!>jpu(W&si&ZQpY z_q90#@Lb5+YfifA(d0Mt&{7a6B`CU)j&=Fo$Wm!U8APHXmCUpZ+Q`@_ zjg^oq=H=v}HW&-3XDGe(`^k3R{hD{TT8{b@!Pf==WVGOOgIF}Lphs*Qaq^Vpgao6k?9Fg9S=MFzkRN|(48EBpqK>YJfn(LiPQycsS-9;Ys~T`xAL5k zui6z_ufr>n2pA3tJ_ixM$(s{X#PT}*;wuK2H%Uny6czU7c#sQ4E5Yb!i1y*@xunM7 zza<(!1459^JpZ?Tmq(~&H24{!Ufz!3h`Bw>JRehSf%0^FL03YbTEt}3$ic7dUXxv7 zC``zAA|?|n-f^SF>!ShU7DlUG%U&~T-6?ZtsLBet4L3ZxqLk!376xQnvj*s&XPm?; zO8Nji3#bDlZKdCF7|?S;%?tF7b%X9V%-4R`BbR%_^-q2j2kY7B#PdY$L{^S5b!|KCuYIo9+*<%Z^W*xDn`ACQ_+v9QUMk z&2EXR3agOssns8)q-wGmLnXKU>qnw=m6f=c!Ch@=%R$v0L9vec3o+?s;;; z_b3%s&^RD-BG4p;E7Szc8sYahNr=L_K6=qnu89F^03DPN8b>W3(5*92o%A&d1Y^Vo znG_RRnFUy_tMSUdZ|3h>?|bz>e@%SV4>^w1|HTxLdZ8lXnJUr%-!7aVnVLrD8$(NY zRFtV$nO^wUzEI>pUxQF4vZ0W$X9vQ=rTmZ{#Jsdo0Bl8-mDIIeE!-YJQ%ZOHmmdF3 z9SVE-M>ojFbW#XUVx9=SD`3|@*lmAPFS2UvSL=8ukJUO=wqX;ECLykLaM;!G>99D? zIvF#{LLTN+G3RbdOV-jUkqFT1Dt=d#p$aWRXV0#aB4yMdZ2S1Kr#Xr_6j7v0Bx+n| zrTO}u5-Lo#!W|8xl_tqryRfZ>NjXRdT~paM%tIOsCDn(o%#)!k04B^<2^S4)xn#paN_+i_S}>XcDq6R;I{5Q{T@i{*~Pdw$ITWXMZ1Ij~a!*>hVC z1?~)elII(@g$s_*^P2{neyl9j zgh@51192E6lrYnZ5BlaTK|-PFF+vAOMB(d4ff%K~sRhv*vCW7+vpX_K5IrMp+zHBLTp3{=WubLC3G$hu}YNgb><48h|S>lew1r3X&}VU|0M$S&+bCGOL!+v6ZA^ zh@|w{YbYp;X*^W=#u0ZkK)29N3pil`G5-e=Acyvc6uWL?E|LaS zqc;MaeD25jJ7*#z?r?vRN~WRiS6`6V6(79`h&Yj$8bKg``etn-NP&i{H_bDZ} zA*X~eoOHh`2ThJOuz^i>) z;-;$v(GJx3y3@x&I)NIC=lX2H&*hoY>wD-DJvr|yoYw%~9v7$~L%;!eEDW4~VhqXy z0o0hF2hd#Qx{$XN#{?Yzm!Q7s#%4(TF9}ETA@BtYa8TX%Ys&*X97sUBF#5l}zyW=^ z#u_2dLakg7GIL{Z#EawUFIfKAMVWW%@;wX%TCGrBHvl{&Jsywveb`MI`8;nGWQC7nc_mY3fBo=G+&Wu-k>OIM zda}Be{_T8UoyO_11jbaVLTs0FWEmQ=Y14d~*PV9XFK7VwHJjI$getjTQYBAqWMqy4 zhTD!-tdZ&%6HcWQaMLtN?>Cuva8uP#VI_Y@Ggi}`r*CQM(c);z5|Lf5RK5Ph+mJx z!;>=kgJy+=ql3T|8R};zrt9<;s|A=yoDdStj=g{r;RIwS*g6?A5qgrd3V9rSHOclU zJxVfe<0my_piz7m@o-7xPZE~?J&XE`TYU^aNAo>$0Lgr3F#*p48x9ukUCJvQfS?A7 z8r0ZU@$@+ArGU@x7Mjch7+gc~o(eX8JP2&b+3&42K%`4(%YXFiILIUKl42|u< z0trUub^Y&gx}MFN*PZ;N88>Ws&Wsd}4BOaNLe z+&StmqcqFrs;ys|&S-SSS(xVKcV_#vl10?WJW_jhB?-0a6@QN*OEIkZZh@pQCV)P2 z)>3WT^LrB3mr8#aK^<%~t*w)giDiF04bpIU4b+cq5WNXXt95#NBJ2S=aKrH=*d-@i z@r<*Qi_=V>?cRm54)2fs*vat!DD2F?=&wE8@AASOw!*HxUF9`-FVyTBZP&FUaUG{* z%c-2^JnQ)dE7uVRHvZZA+3g6F|48;uCgQ>Kkmm;>rZOC*v?$llC#cs&TORYW$O({( zo&l>*43~YYoJKo+E{~DZ4dggHa9k{281}p`A2Ay5ezNf5z7DdxRmzmf}mU%9`>)Tf}}Eb~dN zLeh72ZjA|OCYeIQ4`lqh^}Uva+t<)mmSPWv&*N|nAbCH&y1AX({P<=9K>P{BM1v6X zUDdxCW&R7Dy!S&L_AAyBJ=kCa%~8!LE^mk*KD@n2T59+GCpF|`6*?R3$HT>+aBtxq zEO4!h4NW0cGP-aG2YIlX44uMAifOFvL|!G-ZM&FhtoUwD3TuR9tXQ0@C<`>D{@4Pl zHawCOXN0lV+K3LdLiV}qiSdbP)>&YB*rY|~VXi<$*Zk~fHGaKW^YAYr(Ekn+MuN)h zX}tS28rnQ5Q}oz$Wn*@-kxM)VGD0tAICHXlIZS&qQxZE|9)3)H zLkc_Ym*O_bRJf`&@ug-p++8kutxm01R+m=WwKhEg7efc^>2B{hoiq#foa)=tC8?oX zyIBIq|g*pezo}fZ`mTVFagM+` zRHtC>RV9g!agYhlI-I>7YCiP4M4Q!*&Zft$$ojoL5L4%|qRIyb``!DHZ1>xEjSj$C z7e;P4R{OsU`*=R@7DwU@dVNkRt>&8BTuEXF3nJ}tXXG*ymO-LY?^&Tee97ki+MUg5 zq*&K(>J3Ih>o_3JIEtZ$$vHdxmAUoUoAf7L4HTGm&+D7v(a#|;o^NCbz|9_(+&Fp5 zB6m6d)zq@UKK8S#Bii18-x2e4ZGg!^jBm1Nj_+__fUoDanmXG0yFN~Q{lAphCnY&0*BT1cW2POHxLcl zlhkDR!Nl(JYC;D_?R2T}-!JaT%UxIHhGa3SL>nz1*7=8EGfu>1-fx2(Y6fn30cC># z>_NCmymDacZR4l)>dW{%LQ}>qe$YU)T1d|PGrVCE5+x`i#gG8#o}0DfFT3UoV0$=! zFZ@Gb>n0s1aKQ|qC8wkFZ7_kYt=ZsJ!GEVPegOUe6Q}i>M7j_~niw$>69|8Weg6{0 z;aaiiR*mY2jrAIXVB0x-CcmKm1+l~_ZgSQfRfih>Y&??gMcg9OHR!V-(iusI$&84n zSZu^{ov6;kA54fb3(1qjq_2O{JF|TvHe&v~>^^T}?J|N#V1vP+ZM16;;bjpciGc7D z_0A*2Az{EuBYX|O|81GHUZ^AK`B>3E{{Cpydj$L+x`}Fki1i@}{U@UcH zFo6-Ue3wfsnfKQuk(?!j{0n2V-)tbU1uenJ)Mo2VexYQ{%D%w~-tAVs$JsG8M^DqGvAC zH4JLdxkPhB3LK0=pjqn7*V$+^5g5L_X-LrnN|7K=nb_tM02@^V3>6dx-Sb=U_HC%~ z^%`P;ctismlz<9R?eQrsUkGdbAk6`)_4m4d{BvE(_df4~i-`h0fc9bx&mEwgs3!A( z70}k2gb&MJsgJq1sE=-;XPGXJ{;XGvEn6-(;Vob5Y`8veh=w~~*Ngk@?|!)4K+~qU z!$%3?JxA!U?G23jDvpBDeVtlnv9k7+!CCrlNBZV2{A~{5gxKHTtbFDA;(2Eu@%4lV zd#T38IhPZ7!!kasclNFPh6${N$>3>_?vBRCqj2aTQIrWBBltr3>64ul_ke!I>*HiJ zqJq{S9H=lFQy?9W-CRzvrbrR69Y!HD-LN&_zX7D z?cFr)!JAt@4W;(hA~`RbfdthSU?n(zSOm|0P%QokOno1O78e9MKb-|%rJDJI z1(6$e&4TSgRO(8>gZe=sWgLf-JpDUF9Ry5(Br z0yF5j1_!49KG&0kLhaBB8QOOlSH=JP0zsun_r#=0iC4*O-~l%W2`VALDrQ!igo#rK zJXuotbHK*HKE}w)C;FsQFN*%_?HagL6@*3B{!%)L4}m`5_h-AbgO5-l8a-VGGp$5K zv>j&BqqMY+NAUE7RJ_Fb>F$Vm&vHGFkZ6&P7$j5dXa1P-2QbD^c3gYrXo_Gw*sKv^u-AmKu@E&$P&W-H++KE4#}S^15%;tTg9Sl3r*hR}3g(PLk`Z zQdm=Dsa;psnyq-}TZ_(4+_aK;!3wAnsF@bvj*R76UjI2(0?L^pLyH0bo)3CH^MuAk)VW-IhWAiW=;f5lIi=*}X?~Cs z;q##;_HT>ysM2^aqKyjR4A78G^C7;d3urZ9A^5wQ&qBW+`V*ZlP2&a~468#kuIUJu zyZv`54T7vfJdG;I?c8$jHAAU6eL8t1=h*EjuW60Gp6OhEuJgSgFb8wREwNuorh61x zLm_eArnv;~AoMssMUUsZtX7&;30AmrifqZ}`W1PQSvMJ?=&W7YYNUuZU^yxYejN5! z1(RD%d&(?J;d+Qk3Mj8R;A_7pf(Jh2$r_>k=fNSsWQ1XYy5Q64*1vC6rpQbS{-AR8 zM4=aj_k-rGPnqH~-(0*OZkb<-U4~YI@I^Azl46AN!S2t%E4ZZKK)awlBw-3sXF0X^ z-R7P*C7lP)ErtusaJ7GCy^05CO%M?G->$H4w~gU851$iwf1;Sw%5=lW-|^mm_|8(~ zu+W%Ss?#D5e#=qzQmxqCG*vFDvuL*vH{+5XH$y(O@%!^rWBTET-+PG7vUd#lsKBU_ zJm1@yk$S)Frkw)fr_afPFP3u70<&4h_|FXKa)+j^?Vz`BALnvb=`EbYgi^p+z9TLz z2%c^m=YL8W%juB(6wtGBkjl*+7YE#>X=)qi_o3SFJ2WvG6FlQ*rm)%zDHh--z`0yr zHQTBQMw0dKIQoED(6s=tqn`?x?n;@w$4!}+dqIO8w@zpK5F^cTXY0mUPj63MD-Rxe z(YtHlr*jFd?k|QZcrBmY&n2m^WPh=Z*u7PcVeKpzS9Ct_Rc$&?ZD@|VwT@S5ceDSg zglAog92>n)8=&CPGr3!r_j^e7E!JpOh%}Sbdrq=lyEJl67rdWA;y$hIOu9N;yWiZf zXf2W@9b3U<5~kxR1+JLU!8t+*4VcxKaEAjZy zl+x?^B!nTmaE~GXv-uItfvOIQ==qQl0NVA*ClZ; zOLTV0fw*2)d%bO_!`AS>y+La{#vec2Y$Zs1!!1`6C=O#ckp zs5R~>?Ks8`_c%Fk8~IUdPJf3YAFqQ6 zWJ~uGBu`(b!j(UBBAzd+->HwkJpJkJdJbH<9B!x1JIvf3x=Brz(1<3;xphcRALT=b zvi&sq{CFXDQQ0Zi{kCs2wiDLfy{(t+`WogUF}(S7n(K=HvRSk^wtES=X6@Q}p3NmS z!R740EeF20lswYVIo@$M)?4Gue7ME_1(d>2eqUhO6IUMJIral6160Oww)=o?4yOyD z98n%DxjaDugW==HdjZK8IifcPn2a}IRK0Fh1Cw!ev<1DV2=HKmV^Rdv&5!{<2ARgA z9#{v77)v_IWG+~C{1lnC#; z7?IikarNc#P=DY5%^2BAmZS({mpzgYrm`FR76v0*B4iC=P*j%eOR|)`>}02DQT9Fi zR@wJt3DNJq481?!-#;D?nt8qMJ@?$_d7kGv_m(LAYv@nqpY4V%EAx+BbG$XSh$&K%amf|pi%r~xlo&co%F&Yq|q7+1s=lx7Q_ zyFoCQBz!t3jPmnrjD&>zG5^~XmUgbs%1=}&9{el#p-tTC6K$xXm<5>%?IR>O{?5mp zhCLqNH`&~mR5*UgWX!l^%!tjoe@n5c(O){M#TB_Y+QA=1!X=<0*yG4tzur@_wQLgA zlH%j@2($A=Jo?v8TUYu{qh9tBH`7q2!bj7cc+a)P^`ICxztv1u=OJ_NO#V`v_9_eg z5G}uFuSeO7|AzA>+|&SotMuSTsidi~#IMh`0s;3OB^)!(U$vZh{K5LKuf%UXK`xV8 z1p|CpViv{CkOFcEFo}3z4TtK57gfid|1M}hiH^@9Pq_9RxX{K4+3cC+}mdfq>C zR#rYQ8hKiny=AUd$0L050xFC8@k3NO9`ozm*1O0nbd4E5;8~_ETZ2CXxV*s!_k1LO zA*L19P9u8=@Pedrg)!U=Fuk5}3YcKk0I%D7?!u^9YLJ7L#szmy=g8g6ZcV$GYpJ8@4 z_Kfqg>1%Tpj>)KoAznDl_q`3g>fQG30?YQ?gkn_&M|h$V`G9{_Z!)_ld4w&3jTO5S z)Gdv}%CJWW(PYCDT`~AxyKNaM(@smFD0tR84V$rs&DWQudQUe+aUM;5A{1wf?KwfQ=o3k5lk0YW0<;cJ-&y7U73J@q)fcO2XBetkb!^(WQMN?Abf+Q-3{_o%cFe z>a#Ix4KJIv`^N4E8VrN%CcT%mqG!ygXDG}0^Y4A<{dq+O8a2(4Uu2qxqnBo&qXc0?YaJ}mJ^(D>1P#3>S?b!M!@3k#@_vtMSSt+HU^@Zmp z;VHHwz5Ll2Sv`h+@rvKA{FQ&REvyDoYPhWT+))@?%SxU4nkj&rrIE*0W6mGNgR}YTm%Fyt1|~C`tO`e5 z%gPMC6lb>?SG3rQtH%cEsWmk)4OPUNrCjE>x-=erYFNkjXXdlOgagw=kK)}Fa+?K6Ga9HZcmCvK7?tENWn`e9z-NIaF|6)DFO}%{q+3yi|H-awA*s^f6 zrZJ-4Br~1dx$TmPQ^)y48ONF1HRD$ua1R{+;6KgpRIsE%VEcFV!C0gZh8K2n|$EFGGKFJ9_98bL3BOh9WFN`+s>)O&(Yrh z5KBlag|GoMX!TriMlw?&-&M8kl{`A-$7993+gnz_95cq=E}z>(wG|rbc9KXMi&KZv z-?oYP?r#~yHLLNi_NDA>EVG%s9%}i%6IQbH@!8@tniaKG2c2K;5*rmdR@?K*?4$E^ z>!fuazK$7-ui&;TzSb}QeETb)vV3D@%O!X{*4%rUSCsxzGp&w$IJ3RJhvYZy=rI#qRuB-x2IH8CulTDL9)Kd^BH#9{v)3c0Dl?9q?Sg`w{eK%>ni2H&;MQAuL8~1m+Ulz_BMHP=My}2 zjlE4)HYG_n-?N058#FD{Q5GbxzKORAVXzgCpR3_M8Rf{*BU?2;f6{m=W*mL@;wuNh zH70G$n0W#E#;3m4@^neA_qF${TK#>k>FWk5o*N@0f7x+cxY)i>rlwI=Nap4r_tj+$ z7XDOcWv&GANIK#7w;6B?K9(9pBH%yjMxftO{o@}s>QX-gM*P09f3UP<^6vx^1>^Hq zY%h;CjTKDiLeFu8o%}W$xk8GZC^?oKA{Z~|NgyZ3{I$skn3#61^d_n1GNt&KZ9Mas zlr78(r;(cSP*e?ezw6xm>4r{RbK74u)3;4~u@8$LGUv=MXD8p+_u3DOT?>(I-QZVC zUh1sR$80STO%?6AtL~xN#PUYjvQ1>g&Rw-DT#X=qC9N8^W(T)h>Zn~2l5|UW@N=Sm ztYPhY(woUwPaHYo7jT1qYHzl_f+bhx3Ww&~|Hsw;PNY2R4>05mD3JEpe0p4^envX+ zX##GJeq#50aR7HsB$comeX=1v3$Nv;5v3QOEg>NWq#s+vX!ely3v{AeElKCuaHvbf zC1T}@Iu9|2^z<0KiY#H5r}XlMH9PfEf5V&0Ef@OhvE=!Ng^v2L#5-(!$4-Yup^Gd{o{OgXIP<+i}#HK?)dZNi{0mbqB* zT1RU8ySXechYo)y07FW$(sT;g5vCGu|MyyH5` z>Qlp2u~EO>wCC6uBk?9fRnOaVxj&d&X0yjU)zoCtyP_S>q*yH==zb>PEN@7!-5wwr8zSIf!! zS)XekTXtf0l(TT815>2mUUOGJ7!r6A|dV_OYYYkk#c(AuZFa*V;gR zNelP;TFH}siM4WLMkS_~#qP$NN=quc<*9tm#ZPJldRY%yHLt~w8437!>o-kk!0+$5 z|9(zxFPH`BdJ8%Ofu4BUerYK^lGjTl1O?c8Dzsq$duL*Wx%l0XzI^?Wx;{HQc4yBu z$RzI_*fWVbiJ^p?eWD(+j|AuKmc2EuV4zD0z~I*3(`exCHo-D7 z8`CN=0ZCtKSGF6RJKoV-wqnr4^~X+_j5mk zsid{H+<5@M+gM0FT zq|TQiOM&9EBI$OMgd(0_-W1AO;-sPot>x{dLCGuN#8g7!^Ebyhp4o zem-H5{&3J#PRe*n_0H{AIz5@)ClyTNJ||7~`SmxcmKsdINV^8&K`?Vs&4cZpy$p{n zbqPoMNxFNa&U2N?mw%z&v~ym&?GP_kb>o=-Gh%d+Y4zsy-7)denX_PP-$$Uwaq7h( z{@&j%kZC`~{e>6!y*qcY|F27s^q~fWA_lp7s5<;)Cmla2CCGb8fAe6)GkR91+4*Y- zIV~VuWCKjhlD~SB*geQ&I6uA-w~u|NVaWR{E-#*w?{dq~M%$Agn~Qx~oAaac$2XRE zgBNR(LK%8>B+Ed&zohpac}4fS^w5_wA{SuAT?}%IR8AhhPGUt~E4EdCHR4RHXuyMN zUTl4fq~FMoN~7jUzSq!5$y&qa6V>VoPUWPFryP4#+|YHM%NY2b1gxhjAvaRm8EJX; z$c#Lic!W?w8=*7;a_w*Q!pTFu$sf()CP6CcObZ0_!~*YWmz}51zbpk10X(R8j#R3T zF0oFe;&MOEN>`t~uYoP_n<4i;nmCR$f$<81Fnuw zDd3lTdlR$9&L_U&P6v=&iSzOCD84cL^E~u=iqc_gah4Y zEjwj3zkQfkC5=JhKe^4C)cp1n^RME(VmrWjmK;kywx!Mk5xl*ALucLQMbKaW6v zWDIkVz!sAqegYX0h$F)azoE&%{(E)75-_%LPzGQkYxIp%LpE^VN}1`EmNTS?YxoDj zZbmsZ$6v}R5yAJ#2gdKgUH0BuIUa^$9I6R{4h)q!M)x-AVyOj~U)m%*OI!ViXH%}k zKTFHueG~L-5=o5MwO1`^VTc!WMTHB3?$%PqPL?Nt@O?&j4>dS+vQ2X2*O|69N-CZj zoX@lLQ|&(LgCRH~Hce+(4@u6c$?qO7s9jWj$?qLIv}4Xg+&ObC7AfO&G-vnciw6$p zOj}eqC8*!%qVper#{0o&)3BSZb#b6>0{np#_>EN0afbR5z_5^-FK|`aZSH%b3$yI^ zI*eb48?$RVz+9eLgtvGMD6KxlNx>1*)jDyLM_|Rqft8hSitaoVi`2;yf-3C87Syd0 zS|R=Pz%*7gMGLJv5r4YTi4zhhz~40Cu%1M<(JDkGR9S%wU;`XVP5v(Knl5`1nY`ej z^gja%Nd>Zvo6?TOtQ0^&xCGAF+tsr28QE;uXU3 zPF||ktLImO9jFm8^d_lt9}%nhuAL_1sf5yz&ZE=qlv^*)nL9)Ar& z=>X!zAaQ!WAH*MvSdaW`A{u96(^r#`-UCj@LN%`#ExfB`#hDoW&m8x7AP2FBb4`@L zwM+9EZ;^H!d>Tx|su_bDmF*nzsLdfNz6dAP)y4PPxUyjuDL8~HUS-ph9Lh@m+7tug zE|)4}jFR>s(z8#Nupl1hu%B4MeYCOgeAwlxb!X<=8}q_Y!3bfD!^L9bPvrub?WUMy zNO+@jt8Xf$VtwiZHB_qy)82jcEbXRNxgxR>?p|}+zv{gJxAu`hL7G8V#OJ6x(oIuL z1^LYjoX?VbF&pz0Cz_*rW+YwFO3fwsmT9CkUE>uv=|fF?eUQr@r8z9h5+IKe9x)8= zZvU85CGS#7glOi%j{leqbWYW|>_zzyH3$S*0VxR*sJ?PQWd6_zi@RPWTPo!9hRCc6 zCzfH%*;ZFbk6}RQ$ih@~Fddt|?Wuh}-b{5FY80Lr=CU_Ev~=AziUhn-4w;I_)cKXx z`*sNN-y!Bg1aM<_j-#6^J1&CC^F$Udw`X>w>g>aD(Bm<}FX?=cIY4gvfFEn{{kHwL zJSYGL0Jr)ssQ)3bP=lNRezIIS0K<4oeUFTK5GrR6OJt5 z_!@?>mniN*)KQ6_^r1R_-_R`iKJ)F9Ce%?_1l8j-+#Eh@`8=V(76Ei8nQaV3+lI~x zN9s}($<#^Ua%fP9ZiD3{L0tq+2Kary!G@Kq{#DBrH0j(JTQ5Bc@339(Vw^ zU$V=QagrH6^Fs475IOXTe>;?`d?F{kasj)8aGS=2enSfPH}%A!Sqa#HlJvjMVB5VE zY<2LOOlsjU$4ignKgZV{hW2CdM8smS;fAE3dyr+b6jYt?FCy#we6E~^y$%2gumAPJ zU~8#pL1wflSW(S$upS|7xcXllWalkN;(r&~bhIDkK~1B zo`!uod>f7(a6X>*WZ|cI2f@P6Aa0Ml7AQ4Qfr>0E7H&^rt9og8C|Jl+c5|~<@tFS~ z;zh5VvFFvd_k-;HQ3=H8cWLc`AwL;I6BwsUqstC+5!4twtN77VlQCC&XwosdAXUBR zBX~hn>ToN=5G7Cv-n6NKGBPi5<_1_3Bm$nbj9$G-N*=-iI8YODYn>fyzufLM5~-Ju z7F)(rwm{+!m?UMAz$~LM)I`AqRDyJ!zRA;vOA6{U;^m!9XZ_*aAprLnU^?4bKcz0o zD_lSHVEi>$O*=X}Cy*E&2VU3<=i)K238;3-35oi|j>BodxpE3S?Oyqqyp7J-%Fh19 zbwZ_f?G&I^eAs@ewiJpz=ABH7AuXU(ubN! zjGQwV5A8tJh{Vc1QMM8yq6vYVM}$1#smH~z*~BP2xYI)a<)+qZw{9xOsHu6!Sn}4k zOH5Mbg)gMckG-!-#N9mNN9q&q!Ge}$7~1=9D*E47Z1B#OvyQ#cIaVcr{E;BfQtSkG)fT2M$OyYs?L8u z4`|>ABzDCSps2kn^mG^?V*{gbWr)6cCEP0703 zI6kiBkk5Keh7#XP%=E2lmy#^F%!&k3>+x*`WGU`Rf2SQ)Lek(94MO${*0_^w;3U7` z*zBVMl#(!rS`{;=2$c2W|~=dXOSgt%xQG$s{R ztmK>RsY3195)BaNN>LZ!E@8nwLiTZQH(wX_yuCwpOgfDDbaZi`cX_$;cmGO#gA)DD zYtOdTC6&56E|}mmQ+GYw%y$0pxQomf$n18_+$zwipUIP85heaU|Ks_CR8e1)`uGz} zPqP=;7(uw)h1rqHfz4hh2=VYbA2AHlNg*tQ!|j3g@o)i%z}`YEeqOSVy(_Bi;8UwC zZ9ATmQs#*E9{46Et^3jA)Z80|_e?sp7VE=hD*XR~=o)QW`-@b1JIJ)Yz>Q}x%y%|+ ze=kB+2+|TN@(Zpp-*`f~7Nvt*J);(Qy5?#P0X^xW6W(AFn7CC#%Ra5JHNrJ>7_(NN z;B0HVN(IMOwK~C{P@RZHYQL@wL)V)4YaXf>B9GOM9yw_2Np4HhqpU+j~&&e zUKg0!WH2aKNcLU4_-gqqi?1ZV-G^<6^BiQuPJmQ+iz}9(FGGuhA|2>A8{#L@;@|*v z3{ZdFaW9en&GL|AA$YV_ryAAm`aVsIbbWnD&U1`${dveEvd}gwlR9-)|6U7{tyZ_K z0}*o)C^`;yiez9Y z>YM$==!?LAaJZ_mX~vi&!8tC?ttQ)(wu(((hZ7>5H){qEu& zOB01&HK(5-fDqDx2r6)fJF~r28S?fRQ~Yw8!&1DpN-9G*6eJNk_zw5a*y#ve0#TSK z$C<3$E3V6JqZF$$0Vnm27UQ-Fe%Z3uuIB!a{%W`#^yo~wBE>&HOD*nsjT(908d{6N z88bz^$=16QW3rM#F80*OP9H+tF@GMAVM_Sg za*=1MF;k<`qTthBZ+a%a+{lk@rT7BHHJv%z;Aju7^F5lvpzNCG*=?T%tS~N?DF>qI)aTv&xeC_4Tri7q%ZZ{A%+_i zH$D))0{YZUw(i}VxTMf}vgwJE$l-(1uEIClSi&TxF3#{ABtqVwQnfw!WiIENa;Y1| zoFz6OnMt`)E_qI=1|1d!uv~ECPRxj*TUZm)wB|HAt$?y~=~oj^mCM)au_na4{ufEE zO<7Qn_n`Y{H&`}e(Jbj+@yAcOAJ`y_P=VDfqlYbdLL%hYaj0_;!Dqi5Ob{m05O8<< zppYdrVmfXj!#w`bFQ`mmHPKo#9~v0(t8tVU0Lv;O*L`Jiadft7JXu(ixU>93%GZT? z>?qp5ddP(2_q=Tt`Qq1}*BYj@qN#swq!r}9KZ=1)dUynCRaLYgPI&wJF@F`Z0XLh1 z;#gkd@Q`D0a~k2T%&U!5S=#LRgjX+uE)kDx;+214M2U1DY(ny5CiCD$njA=ZW&^yq zZ_0sV>-fz4^-frMBHUGtH4!x$bicG!A67FL;IxDql__rL#a3MS;q`Vt!RM=_#hqK- zE78>V+lmjwjf01O;KIsw8ZGbE6d6XELOYuUrsL5!EPN9s&gQdez z3;&H@_)~e4;s8Q{TG+w9~^m8*Q)_1u7$fBbDWZX zSaDt%KtPNE9wSxd5Z9laez*_gaog`OD;*7+oIv`J)EPM1&sR8sW|<+X@G)GcLDd>0 zwrIFJULmtEeQW~5q~!f);Esf+{dlcnahteiMF)5KWP84yJ!@glMeVQ*sn=Oj?DOTF z=0`a@!Vnk96o`?`I0=Xf2ev=?91@A>nTNWkKK_i~|kJWhc%r-h8n4cmnUBgMkKiClj%NsH@DZ}@KHRG<85otSUh z6BhR-&}r#HkEEm~g!|MvQoyzA$W{(F&oO^I>A;pZB8oWcrV=TjfN0$2mk7GEO@IKS z$P%zA$hXqR$sd0rU>lVa?3Z7adR9pBS&#~>(nd@kr8`!{i%Hj#qg3`zcw5n3kp$=g z%6HNMMpT8#?zrXRJG~<=+$S2nCr9jgt#wBe-4={a_I`y`bKUM|%(GMI<PB z&dJBRX3X&PYq>@c5^t1XK zGFit)=5wkC-DUp^`f#^W<)7ycjXKGW^~j+@Mm{^g0Fqi=#A0=6yXf5ztqY!OK#9ww z65dJ~@rb(~??YfRnqH7=$V7$sgn$^afBrk^p<_%$;Cx(iN*j1klyriIfU*MZEnJ@A z1BEsJ?Hlii+;%@patFBWHoPWRImLLiTgr$JTqBoeiG~Yg&zhk)6OX>#m;0Ddu3_kX zY+3Ju7B1Kj5ytxMGz7Z6H3LC%ScfYes@hOh0ovVkr;8k^+(d4#=VHyBZX>92DsiL5 zjT=SZ8(3Su8`H4Q_kBsS)Hg|Q)$@CVww5!2yHRvmFcMbdl>l~}RG|50jv= zlAL-~rV_PRMJ0c*WZJ}(JKugiA;#$Fm?RKb7m^?DKJqAJNf9v}G==5>ml#3x2uZ~Q z>zS~ik^lJYK*W8;f%V{bW;$Wrv`d#WtQwXkRl>z};FAu*A55{72J8QrbO3s(LPlp3*WvOZJD=m2LaqDU zep+`;h8cj5A(L^r!nF30>fDtrS^fEHp|6Lj9ODMv?ipq(47PcQ_*Z`|4u66gy(lLA zYm|85aF^nKz^6^MY@)GbUnr6m!TAY&*shn-o&+Bq3$zfPpx&QEPtQmAG}RSYO~K@? zJYx3g_KM7}8P3&u~{Y-+#{?)Xb_2}FQaJ9TDjaQ=v6{1?lx$~@lTHwy8*=925c$MLt(G#wzfO8${C>4 zpY-89B$$I=UqbywuJQ^2|3cCl`F+MgvUY(&Sw#^4*T@I@uPR9M75Z>KyIkjxk1h;R zy-`~=q2=bCiyw)+b7@pdY?Q1w-_qRKo-qDqe(bpH{0)~=hSTr~CtwO{Sb-0n`Aiz{ zuZvLAiT;G;L3s~22izr@Pg~?j=Oz6uG;!CS`%1r`#U@BHV(E(t-4MFE^;dZl;i9jX zfutf&a=;MbZeM!W^DN`8Tt4)n7@!D0>ka;9TJmsUkpU?7g819t=!D=jV20GxV1{hO zYCxL<2=fAvp#H&EoEC>Gj>El!Z-%9hi86)l@05rG2hPJWq2F)hmsnAMN>4(K?%a=V zeQg(0H7_*Y6q=)&=1}i^cuoR!1+loRoP2Bf!bdHK3_#@8z@dy=UaAFd+q=cYU}O<* zKqBLu-=-J3aR8fCq;WVVvwOp!8{NIgn5eRB@MRV@GMeGvy4M0Oo!(A-66iFl+CU|e zB3?w2Dw5RcyHn; zzX2pUgKsaK-=vSfSiPcaWQ4vMCThH30r~B(onv8SsVEtNXgi?TGhPFZoqy z05qkNQpL37PQ>F<{i}T}l4;*p@7>b#<$ShBfD0T7sHp1nK1%bgRsl1@V5yy9yE_V+ z4oy`Dg()Or+L`7MSsY+Bl=4`I%9g0!e`Lyv8hNFHzx6x_P0dJ@ro*`i_6LuxehNGR z^zw(A$eRMK>DTWbWSjB|dt@-EL9!3r?N@_^&*9$T!3OZ4X)ucqE_y-{@)axAgNHVT zF-(LTuzpQXn2SbJplPfSg*N2%Ag5u4yGu7Wl)nURgu0|Bh7ace{>_rU$dO~?`6WuL zt?xjeAdNeAt?E7Rvz&~q0WCMRGzYgl3pPy;v|2|_XC#nrAUC?s8L{lIPcMbNuE)ax zC;<7HqTyp?%>oILCxM&!*Mgj+Eh+Tm;j+izOyZr3O&;S%P{|G)2S5Ox0Vs?km)jU= zyIcOlrc-bSa;lgG>#CrO28j8f;$9_D!a`M%QN2h?qO}8nRzzHT*H6b$hHHR~%MHv3 zcLP+-By|%ki6Lk~M#0^Ep5jN8Qs9ON&7H*bxgetM4IT+YShH3SR-FG<(qhI};=W#<4)lQ3K-QQ_{|918R3l$mKY| zOx3hk33Kw-Bp-0&rMKV#nr%!r=ac{9{D63@DSrnH@!SH+vqyb{m*W9OXMJHm?rvCO#q0~tPz4&;w4?E)9k@?Iq8ZPI(ATk z?#TGl5y_Av1G6L$%mR%e4fMGGc^I<63wPmjy>;*A;VL}N0?Z7n)Eqt zG*?N}p;IMz{WKr;fcX{Vpho9!evwOCK1)~GeuRko6u{{3E_eg7{g-%gr*y0)B>Bt! zn_@-iU6;V>$9;}HtZ8Tp!lc|kG=TpCs%lCy`U)^1!NGxAIB9Z(J zqKhLU$VtIk@bxTw2V%M4ZQW5II%eqaZG^e0gP<>@ujh|(QX)KigbI13Kg^kfp0tu{ zB475G<{LXsv@aN4C@{nS>=%G~UT6HPq)hJrYvV&|W&ppEhnE1-e40NkkZIY|E0W=Y z>)l%{SI=t-b23Wu5*8sGWun-UV1M9@2xFv)li;Z+;+j?^CU^n){e=!p2u8qm4IryI zbn+uKQ{g!wXbu3`W?7wL>>rSl{^mzH6?CL60zt`$ZuPhXRm?E&IX)zkOS3{|jH7g( zK~K}$!j$*_`W)w%=7TlUI`_LFj zX-@Ghx&KN&a1cQ!xs?Q0Xsa|NwPBBb~„JG$8DMFvpn~5IY)uJ z!3rqBidgW1+9&m6B|xKi2?gs*^77XSmQ~`zeo?F(a2y00cK7s)M}%oZueYKvV%)b~ z7m|`Ck;5CpYHq#p^ZNDTCz0hMR$?#dNf0mYtHNDcE_4(V%m9&G^7~T9Ftuc1x4WY5BANv!_U6o(VnDm) zP)T+m5gQKw1#YbiD7*wa;VV37ys=rIH|y;JVbyXVDa8T6D%y{^TotFl54|#g1BC7f zmB2E>h61_035iSbe#7Ic?Nr+Tx^rVN_~Ah%MT@2;5PjRpX46I}98+Uk>H8x&h#jd& zLvduicOQ$lELK^NC4hMgachxv9+4A>O0Q8ShQ`3D)SCJ>kUawY?;M;~HQ zg`eqZzU@y5a5fsLDLycDWBy>cptGYtUhNKPJ9J_khq8ma?->@hY@~}_l!3NX0HmK6 zH3#+{8XmNTaJ&38P=)%0>v{f#M!+^qVU9NJOvFIotn4IEKMi4(aDV z=VnKnK7aXBl2ti_iAOAhm3Y4`fxbbUDt&%4L~pA40>S!7s+%xJA4Be#U?U=9495vj z2mrt%snz?ENb3?*3ZQCK1$(}>^6qjOjPNbN83bX!K)&BVyhw?VJjH8zo&%5q^81S0tgC6S8s5LB20}H+3I1(7 z=VY&3YFEX+PnLkgDfG6{g%Jobh}XdUA1W2WX&pAIyD-N+Lpvv*$D0z@mVs#a2LkqY zCz=lQJ5(7U8e#6+(MK{Y3K;<(Ygdq@fg7U1>HR43`-Mb;GRj8UDEDyGLj=ehW9QuN z**+GZ5qn(#1{3avM$Cuj&YfcwgN~np3F^aEd`jAbeRJHt6TdZYqnQKrh>h4)a~ZmY zW02ym?S=CP%|v$U5wA2j&0T4J#ki@=MkBb{G{{vMqo2WS;uJ{yYpc zfGUvw1}`pfj9Da{%>=A(U@t{*U*tA80rmPZKM8>xKo(h5!?i1n^9)jh+ai>Y!Z;~3lmHB8R-`fG&Cjhj0MeJ*%}D|ualCs5MDO3YTizB z5E2VmZhW2)`g*SYarG1r523{>LJPuLK5d)!#s(5npvNuuik+MAb|7@>jeu;pzfJ_| z=>m3!bUr6R8FbU*sxHaYCa87}{z@u`!nJ=UJuPDBYKk;L6|`SsdfHAeeNGOvll}i% zO%?iIq*ai%#}jBBh#5Je@j6KsteVXJuH$xlnhOLvHsTnUefkR2MyTlvfvRIWHNoXp zfeA3OVuSSm`P?9)+f9Y4*Wj`*=y7@vpR2D4jWQPIW&|jfh#>71puH4)AlI$RBS)ph zH>}KV50b&H=q6tFl{mWygB^`@0^93&fsztvLxHCCfAtY)o(N?yPh{+I+iS=g+_Glv z>ZYN9zVpv)V}=Q-BK@O5AwVYtt^jOD;ZeBJ6`!h>7W`Z4|7aT>~cxJeFWPwpF_d!*8in{Skg!e%-a_U&)c$f~Ej*dq7f5dDvL7gMl)7}!c=;dRdpMLdO z@?bVqr1y#TNjux*!`!HNp5eB3ZNradl)AVshjR$<_oL#;MP=bIKAMuJRaH9L0bU~hMss0E|89O%~;QuwXe9Ahc|V;{NOJZ&YRMUK&jo)!!aY~j~AhpX@J?O z&iJFDUYC=qWKr!!ptFYZ`BiFuN5Zaq1ua5ZOX|qMiyoQ*JFLdDN*ti=!H-6^h=TOM zW25}o2M9#qCc(>9zPZ=CZ}%MK2sW z$%)5I)F}aX>)e<*NAZ0PbS2n&wBN|LHM~i{V(`kwGt%b{c(juoFufvql>I-`1BIZm zcQB{o)yIo9OsQ-U>PTZ$foUqWZ+C7n)a=%1h6QEeL{s|sp!+WE>GL!>N$*6Bp|5Mv zH|pAC)t}!G4g9mq+G(_xh{MRn43a>em;yX;Irf6YLE-Xo9Qdt^*U=e}V1nbz8KFEb z%{NJjkg?Ay?35vYd6Jg(CFXc!N}UGf`=l?Xh6iNN(=nPZnSFoujT1+3933=Vd)yqA*O?TEk!NuZM$5Z0MpY!#P(6g zAMi5&Rnl3>UwPGTA_meYZfX4C4T4IiA{1r%!CCt+2Ez&cH0~gX*7O8;5T^Q23)o*c zj=}aH#8Uy>GPX&VIVL+eM*lQ3=t*Ly(&Hu6z5sw z_0!%;UfP&xOkuEuNDGe=cxu4Fz+wEtLr0tvULjfk`*JKzXL6XA7q}R+Ul{lJ% z9)QCara8kw9oX$D>D4?;mD6N1=xhm|_SQ-)`IZC5kK+U2U9BB83ANs%kgvgS3U4Qy z4*Lec2T=O{Xr}OL9jgOQG9tRL`QS0?EW%asRSJ~+w&w5t_Q`UkjYv`sn)=Tkq;jfA z9UntJO`Gt(DyoJNnh3@QZElEgqpT1>qz;u*Bt(6@5O9vYC`;M@zN=1dIqzh7+Jrkq zN+hv4lf4T|6=C;(YMVB*5drPUP&=s~mNBy+bW?t!1a&YNa2 z2QxA2>jBq#ahultokg0!UF&#TgRdcVq=(d{+-!^kLCFR@)EB&EA)9OWu!R63o^j(Z z*#CRd!<$Is;B+#ljE@&T5ij2C7IkBL?h=c|d;zrVpDTh$cFo^@!z!6yp(`Kz&1v=p zvB=l-B_^s+JG)irz6(^EF7#xTxIMy?HJPEn_oG$oaLqwHI)A#cZ%!#VJ&>3=ihoZ1 z69B6y!C7~Q(V?=cG@XkA6chwTK)}W{6qsN8rGSDl&h*(cq%GE*)Qy~H4OkMYU6g+h zLj93A)N$|*QG5~MB#3_mv(MQ?T!v<6#$2 zcsGA}zROK^E1#`?f@`P#j*U)EUi?~MllW(wzv#}Me%1C9Nza8nH|OpC&FDxXZ*YZ` z(+W8I{C^}3D$)d0xw_(LqKp%e!u)h6(_^pdnK}6junI1r>cC;CI|cip z>hk~fARMeqj1F=bbQCjP?KNuee!N`lO!oP!WN&i1cQ{CnfV=TP?v}}+L;_zvxIM>r zJ6?S1tGIr)O{Ac& z$iFHzQd0#sI+q|Qtj*Gcm(eI~$S_cGICN#o7g3a%u?52$Avvgj)g=ytAm zx*=T*SELMU`s=f$)1C6T`82(C2?b_r z_JODUT6avWjNk7R=O+5#EdG%B6X2#E0ndZ=BRI6CzP~;D-2B7YaK!-E79)Uplq<0d;oRu|K?8fD_BUB;LG%m-*o;yd;8Cbap&6ApH=eCE726ukA~FU zki9vnl= zg(R66PH?#L>1P4$(NdMo;Wx$#4~vF6%*wU)(9;YOsHwYUJMz?Ah#Wo_$`}=7Di)I* z1l)Dv{hT)4@!bQA`XBT!A$^d+>>vvc8Bgs6g*Cl>E%`QjxT7$ZNY|Kw7QRhhYw%91 zzM%cWiffW&_Gikh(O^7gCGq{${|PgkXN1#Z9kbo?|Y|t&7((k z6RyVvI%Y=2jIHZwJD#(QHaTI#$a|Sa6~iT*PJ!z7ovHnAh5M2kDT#d%0~4x>%bc=* z|3r+4Tem&Le-;>?`f0ndR%j641n#-Y%n3c)t+Ra9BV!ipvT|C%o2l3DyOj=&VV9@Z z{PT~!H%>Cu8d}JFfL9^rQowzQ4<9vp*}=19MvY92`ja>0gdOZ&JveAd)>H;q!I#@n z44i19?{9CDS&ENrqJ)X~-(MZ4qWpc_l?8vOts}TPj0Gs-9AhjL7FoSl`Xn5WnVi}k z{M2vN(zn!f7rGCFyYQ;6yVl(jtrU>6JI_UXfUO4H9sB@#hULP8-eh^es%hseg`RWj!+)AChb>F+AmGy4Mxbr10hCUQJ7& z?0KfAuJqB3X;a%7Z%iX&e+o$0Q+1XvS;`^hm_DEaDeB}oj zQZA;|-*^I2dah*}UQTz&zj|qkC{e^l@41GD;Lb27NefQe$UWjwmv1q{$=@+{W~$c9 z#$QfGxO_Qgbh;YCamrFPD(L` zS-W3fg*S(ws*$bw**+qaQVBvc~i~}fsUNoZ{zQ9@69xj(8qj`2w|A2sc1zH zZZiJZZ6W?5zx&My?xLek2Ku82Mh2G7$wQU5D@Kb*-Hh)F2vxanx`e_c&)YKv&pFH6 z+>)e=1LdRv;zg7O(}*}Yu^r+?*5Ep;@t1E{<_}M#zBCQq&(B4Ur`rV078p0dli*EEy!CHh-<82#Ai2+5T;``eE5| zbD!PLl9#1FPAE*g>0=>(Ecf4jB%}D}?u ze%^A>J%W}roo+cG_H_>xwo~OKDRekzwKd-eeM?3pv`B5)SRTwmlZ1t;VQ{JUr;-_G^+)~=ZIElL^Jy}no7%QcGzJsQ6 zQp2%{LNuN`{(-{Y>)y9!iYjOw+~cJx=3{BpT=_?;x z-pO2lEm7j0a16x4bpv3jxI$`Jhh;P;2+|WVnkW*NkT%ssNty1m&-#KXGgfICZ&E>#cVq9k`-rL8z?u=f322`-%<6y^nqMG3fiG<9Uud zngzQve`3-)TnB#-g9~Yhba&;m=Hj>)GV<@FN;rPNna-)Eznaqgj#;Cz4HogtQJdaggExLn&gGtb zqPKxR?(qh>#7gJYh~Z|lpRx&6{kaq0#L}4mx~&;4yEk9I7JF~6)!wuax)>^2aNILx zF0AA5;*?)Q&s6!qv3YIVDEfb(2b&=_TELaT7O^IEFVvNdzx>^DSA03a$3ef<{H)y3`9+aT05Ex^LHw$Z@885L45%yG%{{MHY8ny@Oa_g-b=luPcE zTe~ms3BK)nT^!E22a5!`6RJM{TS%{*7xY?TO3!ye!ErP4_^v8c>M2Wh{I^OvqzThq?$ zmoKp>E7FxQHz+^Oe$pF`v%ZRzbJW zV!K~Wt_ht7H~;*BZvMGG_GkIY)+CD%zw+REjKyXgOX{U7;GU+R<(%^qBQu3kuh`xt zocX+F2b=#9K=SqNFL3pM=X-F2t$6rA%>+AUZ&hk-lCLFdc%j4>+`FJyo*axHnasr> zwq_md^bgz-s@#^GBV@4nO!VJZR`xxSlvF*u#PaR8{i>S8HQ9tpjjYW;A^T@f;dd#n^kIgb; zKY#2rPnj`U3-QkFmO3O|a1EQ_K4jwaEQ~pQ+A8isgU+%$KT~q$!4aR zuhvYg*%@SlAKTr8_mf|LT+niJ7~0nGxb0JS#rwhE80@s`LZnT{c0TIZSM&ZQg_md=ZelCW+TOk4N@61b`L2#)mmxVrn!l4)e0 z+cwkqPL)o}HK`mVDwL!Nl4iO@E*h22PxDN7e-`r1eXsq)xZCnGeaDi2uqMTn$M3-% zn~87P!7GB|sbXwDb{=Tf;wfAVnmM=H+B_AjO|ac>gKhr2WpQaI*`v>0)}0yJ>#NFw zIlN2LSMU>=RcS|BVSbjztE<}*c>~(S(f778(zov2WO`|O%kPG9=EODJrZpY@L9e_} zdE?RzdKP}7-I%`y@gHvb3amcBtOn1}w~YQZjTrfn%Uijlm@+YM{k4AdrOEJ%A(ei6 z`?w!MJ`z>3d(+LLTk&Ml|C2(>8RHT2(?jRxzKSqmyvojr&f!g@ zN*ZQuFjDaL0iwzVgt zf|B*l{e>2hww&L}p0~W}M%HG%1>ihFy6HC_{6DI`GoH;oZvT{)E>u+&MJH|5 zsJ&GOZOzuI6>Y6rN$nA&s;$~pwMXm~#NLsr+OvoeBs5|Z5fMb>ALl&h`Jd;ld_G>> zzxz9`abG{gm)}>V1V#q&{x`;uDyb!~eavILlIG#?R5=k&mRHa;!_Z{H&0Q`2WrFa1^7`Ew~p0VW_)w$tJ$roaowu+$B>GS?&&!I#+ztMGj$ zo8kEbfrBGLtV6cN&Z*v~X)r1OaPz50tv_7;)@aZ9ALGisg!(aUtuAFP2=QBNtLK3* z7OuI>J~C|zYJP=74WVGR;h=XZQr*ciJx-(~)Hh$Sww z+Jbf$Hs=GfK+#Qa!hfMMk7K%(mwq1D@#7=;^ZiX>FU##Gdf+G02G9H(3hfR*ig&7K z_U|4>rP}SKVE@QkMRFIgY-#czk@Q&YHb9_jNDET_cev{=j%z0aK2^5tf<(ooEwGWr6x6>v$+hk zhj|?>=}{K7y%k7b1~vKT%T-mpplpi$P=2WK!#`p%wQD-JZlqiJEMMU$`rO6XF}N!m zB&L=)ZM@!9uqQE0qVF21W$EUTzUMxx&F5O?aL1eqnSbjQ zR7<(!(DUljI+={$3dQKDyvxG!C@(+n5IUG!dgIf!!^tB_{_|kv*YVYTpRJ_*I`&`v zCW~@pM-$zY& z6qZDGuIoyK2gy!mIP5^$d8xf_HOgA;mW6`DD!2~E+v{TfGddjjDddnRN}l5@5sGeG zQ!;?}8Y}lK%j?8Nt&Cf*IjWP-9SWh^b~RFgzH3%{ixEOM;*6h6nYr7nMm1=fMVtpA zf{~3;L{09(<@BKc31;-;NeobP!7s{x5u|zJ_e;0R_&omzaLdr3MdaH#af|NF{|4B0 z7@L+&-4U@;yNM^ULcG78T_2aVGrM5VfNBqJ#~nF~{zVZgO!nJX5DHMvk19>wj$@w1 z%kk^40IHx5CSfHw;#xSYP%K^#FyRk82(Y=d|hsR(l z_501mO;vVHq?Gp}y;G(Oe}T5?Vmuf%SZ2=Bm0!Vket7))u_5&`>a4*?0qpE^xB%)F zA3p7f9FQ2axT)W7c@-oM7=I%ZaTGKby1!RH;Pi`G_0!G4#;befjI`EITVo`x9*q#2 zN=AmWpTn}|WRp)~n&wT~Zy`XUDfVUhwCPb0^h)@{IFbfrWVBiJ-kqXo%H?SvQ!>fD zsI|s>-`aHX2i*{hC<4J_*sIFqOqU4#0QrY+mceZdVF zYuiR^RTpKQnr_KGhRTCUy*)wFmk^7kQ^&!#!@7**LW|`xT#HM!^fl-;0yASfb+?7O zXoGk4Se6(Ijz$JzVe@-4%j*RgGW`w##@f`sy<~^WwZ2QS-n=(830JBo&x-;ocy3}> zYxBD0FUPykySD!#QS{1UL4q~^>N1*D>93=pga74Fd5?Q8CZDoJ!Ipl1-2Ps~EJn=2(UbHZr0aeF2}rn9 zGCW<}ob_v2ep}n4pXV!}O&cdCYdom)0p~CWc3Z6OFg`JcyW-a@BhmU;Q*Tnr%WEg= zbQgBJ(!3S@Fiw7tX)3QC21IziV4I>*maZM$rD3=@>_UzsaRYlC%*m7WHxu|{OIao;+9`+vYONJg;O^Bg@4s#NIf|5a)Ik( z8S`_mMN9y@^$zGNzaPMF zJaV1WfY3Sk{h~*|i&$yE1|!^pl}9QCC>ML{_{IX)d*_nKGr@hD9~n-mqsAe1hJouS z)=n2Xv4z$+NkeBOy9dUq%5Fhfi0+?>SwM~p-L@KSgXkQdUIO1IFt1H&s_F9l*ozpU z#Km=1ALK!8f)o{b=bh?wcT<_^l>8~nKl~|nbymt31vXb8D~~#?cPeFyL!tfK^TweU zXY9!b{Gvxm&d%PGf5?o~f36VX5m;1%3GV92r&IP?-4|lP1=PZl-VcDFpjTCh${A=Z9{+Z%v@`}x4; z19BV5P_w$6t$I8i3yUu^E=t$&zc87a;j5nkt;v3jURy^H2rtxY_|0(jOM!Y7io+EyuA7R##Q&qRq@{>*h`n*LOFEJ?r^|nx9mja!EuRh7{PeW zm_oPdJc$CUI!5T+WU=N-jTZWr=cscaCWA=jRrET)^g9xy1b%c)!HV?})N5qhcHi^W zCN42rd!PX9F^BN5MO!E{Ya!uGcKYhmSg2kzY59{o-7sQUK&?V2=Egz#DQ4TBU20(- z(lg=sN`0TTH)YAlAlnv|!>!?qO(-mEV5Rj8wLs0QoJ<nkh44HQ-6%Z)wCha1yk zi&5W0LVtZDVdO=uNyT@qXTHBISv@oas`NBHi|`}GZS=3SVgbcsodi~Si_1fyCmPEN zg(Lw(qO{=Xd?7m-~}Dft0f=3 z%SpaVa(10g3xD&ME3KZY%dA+!^VW2o_A?V@{-DP7k_qdZjsKI^YNsYjImJy|97Ih<6Ux`ZFx`YYCtu@$ccr+#g&KnY${ggc3i+tQSYvggU~G~-=^DF_eNLpTbKh@NqTZF5hzf# z_LUPc-vJU#I@nXIQkij%JMA85ePU>Z{TIUMy`x%AfBqB}Yi)K%zG!x1OgP;^Ah$(( zk$w1KI*)uH^~d*2^7uk0-htARG0`9FWIJMG?0~JfzVoESW`N5hl5t6dI;V@%f=3`Z zD8_wqV|tM7yug*fI@I$i^UOtMZTYSvu4FQ>Nbs~Tu@vQA%Evv;-wYD6gs=`?##-ws z+74C=6ynS4MsS_7hOFenT@JX&2dG!(_Eo3jL`KTH2vd>QIm+vmf~UHYb?lWvjLl~K z#yqWM!r30fY8%pZdivfnF7xY)6RWi>&L1q-$<1DGsnP_nRm{#2%Py_ne+`VWL*IKBMl9N9x~ExEjxZc@e;6^j2=>#&x{Y)U|7SQzY$gUU#TTO6&Wt&8+Bm zP}RODdqq5Y{9Ds_X8;3Y=QcT6^vL=3N*Uf?Foh_~?!DhvLs{X4cm%$?)}08up=L1Z~2kUnToM?WLOZ-o-FQC3#A zX#}EdThRSs{V8Hwf7(Z;6Z9mL{(R`L-uiXHhn!z)eTXShD{f#7A&e()AK zO=x;_To75qxHZ~>q7Wwl_rYbZqAY^`VIWcJF+f<=gk|&fE6Lv<9W2X2d#nh&AZ&D|z?)9SJ zYLAzeS6!%?E9&(Ru|b(hVOHRjhB$R(%eb+!N8tg_^}Z+rhv&v8@BhVg?)_iKul#lF zq!H6Gfz9fWbnk}LXK&?QKQjJm;CTE%P!51_D)|2S!1EG9ZqK4&GdRW&ko{+j8bwr& zPqg6vt8896*Lk6>uQL34-&VNX4gOn|j^|yyt}Gkj`aPx#bhRafpE=_=uz}YVU7>u7 zo60y@JNR*ou2;D&R6waac*^Tr3cK@-?O{g}%JnLGO-y2jmWki=yuTE5JvV5fA3oBr z=S`Rah%5MxC_FD#=duf^=e>1$t9n)6ImVEdk*rYjyi87Wg}3VBly=(TBtjpoNdKXm zXBUBOAZjS1^{rFwxa7aogg0qXnr$OxWDYNQhHXy<2q^yay*ZihVcc`TEd7#G(S5ki zy@K<>)VrOm)E*6*(qx-~g)2Qwb7_s^PNl0uLdQr&M6&&+KI@$WjZaWa@F>?#X@U)_ z=Z=U+48hN<_<)3W+^E3~v*P?+Zp?D0 z#nuK-fI(KL$$it*;d@e$)-CD_))h>>y#q*g7(KX?oNV&?#%D&K6&*tvn#`w^mCIh4 z`W8|7#{#}-BHDd?^4sd2JI9Y59iN?M=J2Nm2ld_O(~njw6c^j2`zuyB~ZZ!4EEENCk#W-Z5aLPLv)0Bk0 zcmg6y;7y{~)TH)#Ad0tVlA_CgAiiV0T^G{W4c&(mVg|a2t`ewj8+iXal9KN@8@@zc zZgEZcWkt>hOw|T`h%>bKB)Ot$pCyPY=uKnYc&5~C^6UBYKYfIRX9Zs7EPC$bM0jV7 z*O~c_MWiQ*QZV_WB*k;_sp<CDfPzp5Xa$fZ2;QY6Ic&y$HB(<4nOr^d$*?6fHgGXivMDggd~@j9fgne!FIxp7VA zZ8s-I2#TC}zNVf&0hy>FD2uW#=WbHSyO(af=%1Yll10mjZgmBj%I%Q%!Pu@_ffYO}esKn5hBxNv$Lc zan+~FN2T;{RT;1x_k2al;vAVtxGY;(b(Ys?U9gJz@89tnuk>&)_HZ`|^-rGUX^~mi`-$?2!+Wxn71Ir z3mI+}*NUDV_hBop`7>>z#s;rvfrzm{6FOfhq8^XFjcsr{Oz&^3PGF6Cr}Er@ zqd@$3Bs=@W%J$7VX21JkOz6?U#ZT~OC?KIDKA8G| zHKeQ^<5rvD(T^eT&GQct)^0i!gA8Z)R!nWx*FhaP>kTnF&4OjZDYvG-U0S-7>FL?v zvnMA|w#^w%5w~Y+m@K9)thyx{JKp82{ihoS4_`A_{yE*&Pw_#RkspQV*&DqEX3tW3 zmaN4C6FBqIsY9Jxd)uGFDxX|}U#o2j-Tp3X(E)KTUIKOx(&O019q|B|=od@c+M-m? zmn&ZGMd8E^0ko)|i(gR%bMpak$Io=5i!fsL3 zZ1_)}UOs6YQl@`_((HEYU6kA1S0RV0%i)F??)tR`$tg(l3yGM>G{MAe^~AL+p#U1- z7O@`jj#`TD>F)%(a&Q52(2zks>b934wYr8^KV|He$TT|OLnG6YtxLopud;FW*LBi; z*V{pzTtUQ=vO}+tdlol~AE1d~%UzRcrx&10Q|V>X#hO(?g9d0)z znY|cfv2u4?L?T~vq^~cndV8_@4fxJJ^mA~Jo5KoM3wqG)n^*0f5BiK#U1y|b#!~He z+2wnQer>&)Nlnpnc9*|()eLq@fE`C}N2KaaYc}$6Tu6~~Q6QFuNfAlDppGW8lZ5Gk zA4vhO8q}J*gF{M8sFfvk+e;d-jx}qyx8Ho}mMQ43$sgjCohkTopuwjSyss)fWW%-= z)(m?4M+^p=e_==@^bJ-7ed4(!FV!6#p3Vx`^tKGgQ6?wO z7JG$7kOZ5Z_h*00J20%M>Rmq{_fEHV8(~b5vRq7uv&rW&{T7DLe5s4>-cgqa#0m<~ z;v@OwJ4>6?X%%3vSgs&sg}Ty)g2j$pRi;L3fSPnni&t8JQmLb)%E&RCrK+?TYwfvP z+)O+CimCgv-E#c?mS_HHf42mf;>G)B_R{37Vxf9(F5CRdmn-BMCbU=!lcE$%MAiWZ zLn3b2aS6bfHM$g$5@)G8A{dBcJ%vQd5P~dfy@a3Xm01tDNR`=VUwdxlT4a-&pqHV} z_j`R~G0J;O<(JMkRgd-?W^|tvVKpEj%5GDz7wIN+5Bq^G39vwD^g>9DR!r;9g&;Lg zSg=xMW;5i}!?#uDIuXXE-yleNDh=bx=9h>bdJf9u+=<*chY~{bf6-QlmHUm+y8>pert@f{b19e!_82`$M4p=1+0{LYB?n9ZStCJ)(@j@Fznr*6ySkfp`uNBm!K* zn@yCJ%lbyxrysFn-9qZ?jaVDb6$K&Zc_vBObvTyTF@T4$-}I$B>-WEn*${`V@prE` zlfxgaXIzRHvq&{c_16LB;55seB=8m~-^B)WDg3QxfDmE{Zi-^ZKQl z*A~)0e5R~ZRo)j$k|f5FApK6)8bE2(OW%C61vesxdW1M}cewm8+f{Yss+kCn@|d04h6H%a=Sf);L)>uWG1q~0Y!nged$ zh9k7wQ6kf7Excz^3wHLti28)DYLUypJ)2M6l=x+fe^H)!!2*T`yHyoBAD)dEMk5f(M#ZoeX%YzP%kmij$1f>RUZEP##bd450&d2jml|DAKZyf9SKWCK8SwX1`>r-OE5RKYx5%A(UlrKmbapR@6Rs*$U4yx|rbu@WlT(}A zxl`3Q2f-W)ONRN!O}s*wY{7U9c4y-Vmbe<-w72E=6|J|sM560Q7*7wi8@Ri{-~GD@ z_`Q~O#zFfyd6J4?BQa9P}J2X@fvd(o_V*8z;4EdEXPuhK~y zxB2KFV%CHzUI;o!KbYI{1>G3?vhMJXI+W2L#G@;J4a;DO(!Ea&)qgO(%(w^w@Oh)A z!t>ck$c8UY_ifj@?gzX&-{9z?(1cjwmmdoB%AjT6a@0*p9|fG3Jhn7aYYnUmVL2f% zN@hQNn{u7iJ0Xrz!u|{}q~O|#w|8vgw0C?88VYV7hfm(jdaq`&)9!CC=w?_N;MlA- znVFGgUh@QWsx3f8+BI%s$W z$72uswyC6VZE`%MW$sHY`@pcvHZ9hk!zFC2Yt6xFRdnG$jCLaSr{*cPXOm~e^@R`Y z=QLO3&_+276H#T>aH?-WFi=SWM)buU)bgknFg-~(0GjsvR!A=gAJT+6CL<2L4dnL> z>3Hvxx^b}b#hW&{Sws<$CL`FG?TZDh(Ebxm{j^m}rxRmJ4SNdL?~u{d4_iABob}GA z!`ASGFQGK7{%rH^y8WAO2roR3pVe24oUqQluu$nDvKh`UV9m7fu{C*Ns8n|}T4 z<%l^Io|xPb)9kKQWS+CDnc5?yK*Zk38CnijrtlnY5-nM$KCcG{X#F{JyS3P|%Fdcc&32!O#>to|tr+>UxtKt>m`&G3V z=ZZ?A_4(1JZ{DWUTJJXO6ZLW8&pA{nXO}sB;Z8rt)l)Yqb&f60&gO&=Xa;=^&%Q3oSQ8Ko+#NtohHlIS1?N-sX?#bW#^qk@%Ky& z^36B3t9JubrK6>6D``(t9gMAOnz}EJC=4)^0aI*mqu^68_;0K90fr}#q z+cP+X!w7l2^7pqvhkT2Z%KuVON4WXcF(#8+#*ROyJ2Cs_jKzl7BT>}YL3dT?KN-N$ zv@%oQ>%CD?X6a)T_eE+Wckxv|XP-bodsEqx@u$e^5>pk)l9Y2crhY4AxQeOV`VKZf zJwVPTw$HlUatQ62?+Di}sF@F|qBe3WJ*RNArKm(Siu6V6Rbv{RN~Y@sjbZZ-z)%bTdHcjQ$xWT);M~?ug%{0WTU#w^X%?J%-Lpa-JzNa4H{>+ z7TSxT`@??+*0i(9iypc-HdFT3m4brdbhJw}oJ!%@DyiV~Z`-k`iRX`*RLZ(PlPb3a zZYEq@?ON{y;eVj;!6qmf_={*u|(3moM3#ah&^8*!*HL7OsD609;V{WH*x1??mA+KE)nB9GG ze?oEUscxuj<$(Mh-Yb1k&-9<`|1ZPAD8mcM@44sLg%taXp1$M+4yKGnn_3{cM1Qh5 zMO!C1f2!qLx%ez;>%*4O)$%cowyzrPl<cva#RaKAY5j$ueqn-_&I8HpF zW27~h_9yYe=ynJp=}KIb&uKP{-SWZDN8Ikkp(cdc4<4}u_0mOI$jmcubo0~sRqa25 zcR*H^hxcp(=s(Z0oH)@BqNk4~j_edYy=~H0+pmFlI8UkIeXlfdcF4D_T?;4Y+%( z((F4fK->JHE)MEa0#jjAZ_vu@G$eSvroaOhr1y~bbOAu)k89lcI|XwEJKo1Lg5d4u zpVN1j=@?yMZ^Z0x{dpvA;ke23_9~0i?$NLh;~h9c8**AoPYv24x%mRp!rVuJllw~I z>V)L*3)h#zRavcQWqlbu>aW3}rBmH(9SLzgALr`k-U^^rK_F?CMK(GgDQf!78c5E? z%<3kEpPKa9IfH7M0f9N9%Co3m@yNCF5=r8ThfU7&Mt+;|cwAA!r6L3=R2pUt2eg;BlrMl8{C+xhL zUIUZ8ZuJNMcmEeZdEvoFext!FuggqzV2hn738-$wOZhKX+>RRSv()$DrQRy5QT5MS z>_2+GR;}rn5pgs_E{`>v71H5&IxQzA4A~71{d;2MlS;$S3T6>V4Lm`!0fUNCMPc#t}{g z7VyPflSgjaRoN}N@L7qkL+!uX^e2c;71~d^OikZyJ9~Z9<`;%1Dy(V$R+Y;9R}KEo z_C1adA5&87zj8VOoQ|hrGD9vZU%J=8rZlvbLNu>fOT<7kD9uLJW2ts%bLc| zfNK~fTNaxj_D8jHpEX$~@T3NmyKuA2x+J;n)tiLoznMG&en!>DPlun&j2Y>l(7lxnPWtg72r;tI8ul7i zdU{CkH-0Y|@fKo6xHnPp?zZ$u>GA(NBqfhgOHCO=@(L(99N?-d+tIePliJ?b!&hoY z^DJVM$69o3WX>&8W|{qCuu~=B1BxW&JhI z@dXEL`fY}VA(@}DVyygh6=fR#K$W98T4v2-ptLVsfEzDpv$n$b^K@5~nK29C0;q}K zSy(<-IX3Vy_q7I%B>rw-&hUTNnJ$52qTa??u+Neij-@R+?tLY5N1souk@Sw%jX$ zbsF&N393DHDhP1kXkU#tL_`;NPB=pkr^)wUb7i=_ljoInEL-g#>sZa~#6vJDSsLhk z633-I)vC9RMDiKiu63@pn}5jR<*N-jRyOtQQogFWODC|r_Rt_2;;z|Fgb}N$EN<`>ZnIfa5)`o=L${^*X)|6WJ2;RcY&+rzDYfwnl z6B7$ByJh=FC95ZVoobh{DN@!0f*6^*vPo zCbw=?u=6d0-*oaJ5%Z95uZLT?BTU2iM^VXna)Ezr3jsNjjz5cFhNL9&^$=9@3S36= zid3Q~EXprS+%!U@v=eA|nEL{Oq_Nyx}GxNWzb6H(kxu(*uOj3J}qzII*R5sGHchlwA+5x z{%~_dVv81o>=IeP@KWq@nq~cf)3m}hsAO*pT0<4m;-AJweWNN(@Xb>L4jl~V)PB`q zT<9h{NVwW7?pGAnOaY5Slij#y|HH~Lg5>W1IK;qZUYBK4PLsA@B2f~OfL9?VseT1N(#3Jrn* zZk=3F^+`y6;=j4mYijl)weLvL)1TtbJFvO2!*AZ(jLRzuX0oyhTsEje_Z&%o3yJV_ zp8iK$y+TpYzhHK>^-Q2yB7_0^&gd9FK&kCJ{+`;5Wg!yRa? zppdG#QwPhj>3?@tL3l zxgAMhs%t7vs(0&$=uAD`2YPyCM?z`NI|sSmi=vK(ZybPB>J zPh`vt*Ni}V=rZx@ zv8&ry?HRFg=wa&^$!Al_Iv5g2IbPRTsZU!IvR$c*$SXB_)?!gm<6e0_UQD9TM1+E& zz6q?#ZG6ywsCl{Mj}1YJ;&djt>0MFZJ-KQuZ?piqI#L-Vt+YSp=Jwz%KlH6EFEZ)* zi5_~(E2_flvIV!!Zq+r%4wi$x+nD?9GT)0 z3*KJ7Vw&{yFo;-`j{;34imwuMCQvpY0|zD^wap5CuNtD{F3T~?}aB6 zJiUP-=R*h)EQ)OFbKSAaGHA3LpzJ7komu->aO!c;wRhc2~*hX z$Mx;!vKF2t@qgs10G{Li8>L>z_;Jh>Au7Fim{j!vb*XZ*j$TwX#S@`~r_JI<7I&T+X$2 zZ~o0H68a(Ghqg&Hd%|T;a+6!&Jo!~N#+m-^Y22nc>6zS>q>{T}ASN3+{}q-Z!T)wp zWC|Uu1WMr|q}<|C2c0)TIwT-19rN(FJvVy^#=b|W7rF6UG3%uT>!q0HjSvMwsp;ja zyoQ1hI?F*|ruG(_;KbumXOf4FLpvL03A+k2U0?HOQKYuU%!}bF(EOU#b;G_byV${b+k3G z?FT54-Jk0ZlVpUhF-rNubpm!7fsFVpb-eDJf23;v15<7%h25}c^d z9#?l_r)9F_x*`^h2ZJzu5v8Z?sG#2_a?(G?F2W86IHShK#J-w#_J^ffy7m(FGIVbA z1s+VV+m@QZx?0*gCVJCKgCf*G$8!Lwk$M*eeKkgkUpQ$ikvOdSKTZ}gTHna@DovDH zFB0C2qin6fqxIOwHfJ74&mD$BX$9@-6;@nF464Gt>W-qsKMY!I9jz!cz<s7gV zA|~iAAxH+Bs?!Lpuf0p%gKR}5XKrwxMnAgKGXsoEy0Ik;-Yn~-cA_n|8|BrLB^IZr zs_zVEx+?eNLC`v$c6lKZLe5p*wFLt8VV7HM%6-h}r)|u~%phxgK7nfN+d-xlug-Be zC!VYnb+n4c7MLG4f)^u;@pZV%P8&4oJ_M)@y8*SlNLxh8$0=$I)iS=d0FJ)a_3P0& zev2{xKv2?@khNq+C4AGjX9un4id;4!B%&Kxcop5snr(%7eIGW)5fS5>enPK--@!4B z5C5}{{5V&BZF;VwE%|fdmv`ws`-i;+lH;b|J-#rI=jp$Z=a%-Xf4nlz9_C#eh^gLq zEtjh~YH6a2bW%>PAME7XicQ@&0eO&`vbAcfATYt5>b5M=zvcVqAZWPVSMAhk4Q5u2 zWtk1Y^=mu+cU8$P-CKv9#E=sJ{c~YkPcN#s`XUsTYxD7gF6OS(0sGmfi1VFeE>~eC z&EJ;XJ&%^zX6KbzP#ya%MygmFK(MYqzu%45&M))96L=lggMDiB?!EfyDc6Y-hvXpj zVc+-~=EoMigWME8j*EOoE)7$DIk<_XN)P??IxCZmD3tO#c7tk=pVV@i-)MAyjIBw| zqLG9d&+iVjSJY-(nb~2(Rs7;#dsQZ{NAbF!+3WAzrPR@;r!9T5i20uM0__%ocPPtz{MQ~E*#!J<52$lQ~|9 zIKli^{Mzr{Yie}h?Pq8hT=DuU|LuF>Pk#jU8mDwlU%5JKv*;osEAU~RD~Qu}hyp`{ z*<~JdUpe-sSZxeM?2W;^U~#D_OO<(&`Rjp*gfr*%jH}098mTQ2iI>|4spugN}#5)S%C@93;J8SiK}n6?`n_CN+o`g9@(rg=^yM(NG>vuyk6>kyi<9t- z^X_oTkk?1E;9eHx3L_C)f{jUKSymj^*ge@Q$Ymn&R>d5yOeT)%b?$3Xj~n!`RxYn z9yG}G>tbuoAcV8-Lqho5K`9u2(K#A2Zn39}f?E&LsC8bitD^5^$;ikl7H-zooJZiD zsGJM_1g4$;3Ka%_j`uwM$p5i%=;!n!uS=%L>5<8gji0hU4ruIo%4Z9b)k?B_ymZ3n zf)xq@{~*E>Ok|Isuf5QN(R&0ty98db(bV;dkS`sZc1b?T0ylSa&&C z2NHazXI{<7&bLYM{9F+@6L&86vA3F=mF_m@M3AhGdL zR}M`{J}`?w@ftwRr|l*4o61Rf2iw-!i#i7Fm9If0(GF=+AFKNJdvObsca8(&+tLfR zU1}{$*$Wr(vi+Lj>k!CIQN#e@_TKw+`L7;3*c*-sL7=KJn@a1qm%fLEa}XpgAmx_K)5!tz*NjQQ3)O3O_B6 zGf|}`a>7AtZtMo^w1PO6Xqlhuc?-ODs^>&(@O8wcaH~>NYhwnn>g#uKxnVojcgi8V z5qQMYLeGPsM*1U%{{C=@?>uio$$6DAl66M@AN>EdY#!-~KeT@MdlU9i(-3^gCvrh7|R~m0|hR`l3|lmR$1N39rDJS2|fI9CdoY=)lA#f&Og4 zstsUMcjsad>g0;BuJtYco%LJJNlG_Puk=4gT)DBuh=KG)s*K+?t7EVttoFnh z(-nMd>_}?*R1mCI%5#vf)49~ANQK-?%qPB6?(x05d4{8O*Yt5CB?-@gdY2Klt2lWc zZ2p_U!j@E+Jt`c>KGqJB3v4z|Tau2u>-EmHKcSzxe-h`2*T(I&3XSsjK>J>NT#p<# zcL2y9~N$I|#CzNlp_v~Ai6XZj;WgDmhWi+sW%)Wi? zf~Qrn!g{E{K)?)wP7{3j!b&KfG+9omt@t|Fcg3x=G=lx0=*PibTwcSvxh}+Xrx{2h z_H8c=s{MDmJqvzc6PFks)%;bbBWNf6EO?vi$a`=KXZL$G`9*uRsZhh?S6*IBcxL$E z*Ly|hq^QI1R0R|uHxQ*)COa^@*C_lW<9l{K$L zJL@$%XY0ttJzF0p^MO7g8bKjJB39nJ3t7$IS12>p4eH_O7$-FRc53P7rW2`We20`A zfiJyHnqSv%iGxR3{c4hm^ADbBCZQ{7`L1@aV#v1ZCNLRT#~GY`6W4cnsW>Mg?orA^)x)?-_C+3ndxQ3~*Kv

    q)*yZZGJ|G0u*#`zvW(_ z{}98Sj*Z+@<*kz>H;pQ|`0mY^0biuMs84^%MPyyx*Ed~GajGXX6lT!K`3)=uyX+3H zz2_(i%8eT+mdt$+7^NSpHespD_jS}wo)36Jq8a_PfV$|MNO2Z2|rE6nsE2{q}h2qD!&p_R< zq0ybjd6}Pk0&CZ=u=4BkuGX?&Of)mUQ>-%MyH_fkAsh1HGzy&@e3g4~zE%0TiN})RB**Y-1`>n!SjXsrtdj2|ntmAz&-hHY2ff_Wqy9a;yzi;^I zr$5l$+LM}qCxYEQjZ4JaTPv(p={LGRHeggnM>ft@g+~M#((J!i!|Gl>MyC??ue26Y zln5<);eg3Y&gQkd>GDeJfmWvq$SY!&6**}49jR*#P~Dkk4P=eJJQvaj>x8I(+OUsM z@75U;ushxf;=Nadj&?Bsw_n1Mt6$E6M-mdmOxSOhqm+ujR$xlLRILlU=6)&yCuOdy z6BtyDHm-s)9U>pUE*I92m~1Fzv%#^2I=K0nc&DSR(xeBZM|o3~L#89qlMDMoc?D+O zOB4(ExXX+BaC3;{awYfu)w+#gJ7kafv1~g~`c@4ba>i7JmW*4UOdv88)VT0o*GA7e zXfih}x^XU~z85Gke7%gYZF_SE>K`1t!N>he45U-26&AvHj}6R@kA6XHFVgd5zuKIdQG8RZB9r~}izBWLXnZyx#_ZYM zx2M!(Z6PD&kMaiqcdb((XM%Po?`^|ELncySJxU$YdEssr$*tc!A2MFYx{^2f)^Av} z^pNz2$-90JJ5WnCjygaoj6>U5bhpuk$ zAU33cmt|Wrz9)L1<5lohSP26b9FCATu z1e>0z!aVn9Ymdu0KGl35prCM{*`rx=Rh8t!ZG|X%yP3&-n$F1AUrND2j#X-(uV-Js zGiV&A?yIj;V;i|$@f*ZO>!|ZrrO&W`&R;kqP*awJ%!8Bp`iTL(y!sX<-7?jUg*Wb{gHNVx3ZE#qTNC4SeB{+Z9HFw8{GhSWcCwP* z{_Nf;qA9I1Vy)K4Egrn6wQ+gyp2@_gwvZ5$KYps0$4&WvES!n0*I0}Z=Dj_Q%&$&0 z+27AwGRZGQr%8ItKdIrTjU$4kC(rgqy@3A(L2QNy%!ZYlh{o&t;Ov#x>h==zWp8J2 zE248vIEI=0bOVi=dv~pNWi%lGx| zrgU2Z15lRun~w`tt7q-N3$Dyp&#JAGy-_>{mJ^R1EGM$jz^|Wk;C|mAq`i2XE5V_s zFMNV#m9>z%G;ihei#XCjJLVL-vZ{5x4|;+E-OVYw6vW3_%=BvGdbQ`e@3X#*|2nac z0nIcvNvf#2LaL}&bf2ppy;~WI{+4Fc{m$q`d}Q8xKH~axF+*SDod+&o&0l|c|Mk}7 zIxEGgWaG=wDXsN@3-yT!{Vhc!Z0^&@wVsEsUc&zKSS%H)%zeYTGG@N+!5Qv7UCZQn zf5ERcmL<uoXUmqnZz!2q_%o-;n3mqI0@rLnbS#Q1x*dfsNi|?KjDyUskl2>S}d$vk? z6;CBOf^gKIJs{>@n|Qu5=;UJWxP&FEh~Eu+8gA`8LD8^*`i^`X_tz<|&Nowo{+Z{4 zHuFP3UGyJCG_=)aeFLC%vML(tq`kn%iIb`bg*>4doF3l&krQbgY~Tb-cXf zYvVXj$T_x8AlO}`3mu>GKP!xuUTG&YGwHc0rt#-3j| zBiP%6PI-Jze}=4f7!suHxHLpsMX2!hZ1xS8x=^>2%k+eYv4RpfD2P>_{M5XwO_s!H&%V@8_>(s@Q%$yF-9Wfb zBY_Zo^e^29b2V82apf_Inol(;59Pvw*Q?Ft!5-xNWBpkv0<^vLcJ?;o@$4HlP0~d) zkrdDHXH{~slhqTlTlLOGJ;}{&#p>1Xif8?_eY)Oo4pa|`Z`X?d85DZ=tIAFnQp1>4L+vekjENoJUVRZ5mP0 zj}&6-H4OVdMx_E9#-mP~q2i5Kox9wAb@80( zJm2b>61+V+@f%3?@)jdpBX1%)Y?+()!Svtf(>Z~#82VfAP!|EXa$9@==2ez6d)H-S=-}cY$tSk<9J&;BZSE#mR`uwi7 zk!($FZ|`{2>A>3B6^gdH+F2$0LoN8JB7fTkRyQ|Ka{Yq(f|sIni&<0>_o+SXS69Tk z+CywVU*tl+B~IO&RM;5I0jsJh8l&=66RvdINp%0Y*FieaqQ~(FaY)EX;QKKz5e+xS zkuCvLX#9Bdy4Ac~M4KRd0}-=d}x42W)Bqgz!VX&t?29$Z6PZjV%C!u$73QcKE{ zorZMm5|T~U&I9Q8CBZO!|o*09QIhhbgAqK$e-s%Vn`r6OYB{zlSiQo4A@ zp+c=idNKCACBP*9Vfnb707}2zoagC&QK%^ ze%}owz1}#>u>raT-O8NIs;yy^i1GA|v{Zq+kGgN@GIrA42&_f?Z*?#Mb%Zy{r{UG1 zcBqb&nlhq)vL^zrcTyP25Tfah4?YkxYvusgH@7Et?F{D_Zq|?(Xzq30zp_`nVA?P5 zJ@~>s%SXQ>2ZZlF6D__`%n{u3%E6b}H4eU17J& z{I<*gMGs~;(j|MqXn^uihaXab^V68yyIg7eS5@YL*rOhlep_u z^z$FSIhYdI|(^nNiX55Ee9orH?9ECtCJs^@3xZ*MOSX$8~OB?Dk{ zhEH(+l5>}Ic#)F-M{s54b#}G$|4-3wDz$_=hD4>#&BT=?s>#+|bH^gMw;{12%!nRy zFb+moHfz}&n1=0&AGFBJ9r1)w;afu{SXC(aNf~ZHdI`Lu5uC_UFf1LD{zluUU3aeZ z|DQ3VVScu2`(RqOP9-%((l@Ysr^5(2d;uYekMcYZv~* zmH&~LFq)PC7Za|9^wA!Ooi7Yb#97j9&GYvIoun|zDUc&kCQYU?z;V!1b9rQM1kQqs ze186RB*>szgu(*v{QnE>pr2xTX3rm0hA9C2thO&y{>NIpSV01|zXykRij(7l(w&*wcfL5m83c}XJS?qA(z_#-i`#ToA+4Ybj7@2c-a>E&U%VfzpBx zp7>U?LwH#;r5355=%r8pn6S+X-AKh?Y}Xj2QG3I`-#?qsEdlri<0y53sVyAf>e#V3 zGW>P0O-RhZ+q2ie>-zpWG!DB?41mP0XZ><3@qcO}ju1FwZZFvYzJ!Qo2melf^hNZqx-_wH zy+EDCR zsd^_<>g*(ONso~dc1t5)kS8|RY_^jq9U;sV$KmFcEw;Qh5LgLu*Q7H6MZVA1SMop;WgW=56 zY2an3E-t~39&TU>%I(i*JYqh&x*Xp3l2-fVzpH&tdU0vYrl3dpqHZ7WAW3PRl9Cho zVWK!x`zPow=p;*m50!Nq0w#-Xg4v^Ss3scmn_<-Tcn!(3U6NH<=m<&@eQR;3(NhMR zFrI3LdWpUW`68OH-?BH3g3c3}!#PlC>gMzDg?#?fROh85(V#!5Ug$ln<6mTZ@R zb=zk(z8-xzjvfXu@QU-}eo@()Tf<%a?4>{>bClf4XG5`<+UpEwfs?!68Lt;*QSEWm z{148LGiVxBWA7|c-*kV)muyw_ojQT#;wKU}u{J|t>9H%EEJ-X4IEtgo9E2Vg11|1o za5Sfo4F>n#=}Jj?6d@U>i7~BQ?WURPTC70oMG3_{3N*GTCG_O_(f7!PVMV1)?DV%E zb9}YlcY9dbT4*09`nc{NQg}KZd~MeBQ%8J=4MHIn5qBNH z|2qp*%Ywnl#kgxH;ag)_x0ZI9V?7>Jk9!Vo_L*J48_!P~m1HfxP@pijK3A>E5mje+ z0nFPLDBs{S40MB`qA=STtyQVTLuJQ90g^ibd-3->ED<_Px#q_AWb_!GeY5O(mo88& zmq<6%()Z;Q;eG&?4StSJ#+*SbnY^>oV5lkT^iZ_a$6Lw~mPb8KO%6nnrib1u^6zS6 zRxIZQSc(nn4OG5rQN%(HuP}CH&gk*K(e0FITP65>DA8ZF9>Gm#IR3yz7b}HE z5Qk^qVQ8Z|iD5Rb1I?wo>fe%M#k&x2Ef$=C(3?huG5jav)d(`}Z*5B!|CdlvouJf= zSt7ZnTJ`=Ry*^&%a3!Dw-mlt%M^1U1IhqW8$<*=0=b+PiQi!5nw7LCpH&HdU6atH} z7cowM%Wr1sj4FG-fkA=J<=|UP~#*8juCp zZo>!VBYCP*eUibO=Yi?4A|Tw2-ZiR>;LT5|+7cemGQj1^Hq%ORiD8taDbvdPC9y#^ zW9z7Y_R|(VjN^Q$_fyK9Q#~_#^Ku#Y0~XPyGOLS8YnOiXng6w?owDXlO!{*TXu;e!jIJk`^6>4fuPKr`Zg%zqbHHl+UoUYNYO_@ZH^eTcych5V5Y z)k_Qqk%mt>m^X-`2wG_0BIa=40?Q1kqpMM41aC()X%f;iGLB7j5Ck{^P%Q_ z7(D*5yyCL-&Ep{t{tFze-5C5?u}$sB_w(XG)1uto>jz^o-o$a7e#x%`O1uZ? z99T#~*7FN#QHu#nW7zs5iEx040(aZFCrgUgTNiS8-Ciw#M~I63;1nhFP0`VK3{r~a zgn)s9VIF~alaAZdl!6XusvYZ21^&;sYW5iKg`vP_2GTy3wG}P)vt3BO|4jOSf}nui zRg+e)qkIktb5j<8ko<5B^3aVm`4G#V)p|&C`!3fLlz4l@U4nu3!HCenN%*YnflF{b zHO=Kh8K}2#4yKuj58e{Z?AQ>$qj~#wHQ2038o2SS>?m=8_c|fn`kCebk_gZz@VJq;HgJBRV7lELKkDhEX7LAt>2t+D}DAT zeeU}IJK6Jd1*A(Y@!VIuHFD)34=4tlTyH{?2A?ipA`Q4}zAVzv@;*HC5Ls>ZlO1Rc zi7}JZLCq1i(38L^rGXm+x$?iod$(*TmPLBZT|Q|fn}wzEjv?bfgywba|DFe?X$u1L zA7K>8#i6Qc;9_g32(?%~pvdaLc zA+Xuam*=LY+rYZ!{Ud)P0sPVJw!lSRPI7_AA492S;>Q64|Gl68D6(A7 z^CPL;L)oKX!)E-31p0F&FX&L9aUf8F$Dh7K?wyYTAjO&g+?oTyfdhGiWZ~vxq@OrB zU_=TvH;;-%tQGJ*nQR97{~{d+vW)Qs)G54j(TsphSpb)ze>iS{9^C^prSm=~4{tjO&3T)l1G=_OpGtv%tE%#0w#z z>LiLURPUZMFQNRjSrSS7{)NRB%Pkp99b(x<)+mD_z2aAKuGhjU*S#uh#UFQF)HnWX zF&Ice%7@}Xz6=ToWkIByHUq<7PJs#)2R4jZm8L$VNt6&p3z{I{KTPb(AxGy=bp%^c zhrNN=v;LKRUvJ-m!;lwQ%_71<>z9hHfRwSP^1|h?4IEU3_^A>vTvn7RX|Gdd>U^P4 za|#bLA_z-r^Fw?j4FcGl24S18&vTTmcf>_Mz8xHAeI5Gy|t7PF2DN-2@Z z+ohmQOF7!iPj~R;%5k8pN4|2d;5axn`w+K>>J3AHC;?~vp9R+L&`Qik62Ehs{Yl?{ z5{U+S?FCW8<$YH3s5X@&FOwd-Myk@2lPUjYs+spR(UNX;;`-dgQx+EBP3DaMi@DJpd{KrGpKEQfiq z#1rM3!j=1f5@1^G*hYHrZgP;fXx2~V>>NgcACkONFMou7uobzWu<`W;J6o&1L2;H@u2An4$It zO+uF}<8azg8Nberk#}|u$}iVq9O`EG(b`kh z$KQrv+aXNgHBpnnN4gvZ<8p(6fU`YjvEIiM)P zESleLd`7x-?`-9Q-B1)STjEja5%S2(m!W%oDclW60z){*SG`7PUC;H$;>`oPxo~Ss%HYanDkHW1EKqKicnBTm3rd-?uYlyjR?_ zE0nrFVJY_VB8P>EfQ9vkom1ecg3I6k!s#!1Jme=Nq$`ZMmnZar3{PjlMH^Ljucr+I zKXkBzGHVA>#6>ISxwBk@j}T1~D3?idYZ5^ba!VR}9PTSsB3K-K;h`ZBsa{}8grd}U zt(YW2*&3+!g?QjuxYPw^sa9i$RJ}IN;kPR7ou{GL4MZ+nt{82v8{ZD{yg1~G6Eh>SL*mCC5@W9x1w`Zw|mE2}^ciOR_2$>Su<0GIvstD;8+&INlLugbmR zgPhp2qq*D3mL{q;-c!Hd5`@Dl;`cP0kr|7rb1~A) ze?2dgUJ<+|Por}4f#bS=O8B{hFN-?`yLZ8WzU1DM;Tz37XM1(O{-6Lc_hirOP}6;_ zAVrtkk@rZY|96TA=(P(ygdzmso#ad#%9NIqMx`I2@TM9b+Os9v79d+9PL%Sgp${vipj&@1tPCmk^bK-N+r#-Hcbs7-*|Qx^ixt z<^ZY(-NHTiC!`xbmAL}aE)E#LMBINtg1QA_Bzx3n;E?lRF#bG=^-$mgeo2m`9^Ufq ztOVyq7@vy#GC=G0sm7+t1|E^lI1wnIMs%7LJvuY)tXdy#&u1Wr7d!%kiQP_&g`G*( z(Vl?SDF=h{o|jlm>HQzN0FPwV1sBpo8)ei0`bJh)`8xKS=XW0llc+kR+k+7g;39|m z!ft^OuzVj)i?@6`7=%_Q{a~koK#Q0{( zH|qr>U7nwq@mvUi+f~r%t=91g_QrSKS^?PkBz`%!t=yc9I(7VTy`Y7Bjm&i9r)||> zf4p~XA8N2)SMZkeVar4|3d>Mh`UlHJy$_FLB`ca7=50wzin}T)+#j&3=q?MyR%}#&Zc6+pv;NXdp zOF|EjLKObSheMpf$pu!w&^H=^Hz3{4Dq(|OfD$zIwFJL~_v?rkvBw0C?FsgZH~v~T z?K;PG7T+#WPWV4f80xx`zaa6rX4CgQ8zE8R5)6xYvnv zZ}9VY_;*C+x4{q{p{cLr`nL*iSWFlyma@US2(t#zO_v9n5+9IE%#(EA<&#oQQ?f!( zrb7rbQ65~9;~3NPX}n5GrIYq;HV5BeRs0}}men3TcOdyBYcywh$y~S3YmLMMjRBAI zB0uU+12o^tFO&t%nE88Bh4@S7DuPS1Z;`m+r!;|3hh3cWDx{u#B%Grs&Fo}9^}vae zU@%=1W?-*RElLNcu${?SeuD81oJaOxK!KG8ZOMFMlnQfO+u`hR4c)0zR5)=F6d(PG zGzUkNp)1CT;d?a0vNREIpYs;8R6nSUJ1@Zd6*R~^2Uc$QY9Fxm1NX&Vf*Pe;>&73L z$PUzv!%jhkvAD}YM%5HVGz5%)4R`w$dNE}L7Yu!-^8{=)gk<$$1BOK#`p7LQY_k&o z0+Y1ZOU-x3I(A46&efuNtaq_lyk+1U`C{eA$D}0#(rz%Y*Av!0sicI(HygJp!+K`Kum0 z?3Y0nqlin1{5e=M-3zjF)#rMKQ2A-zA-Pw7PyU|&KTVrw^R|m)pfK#~|Gjk1X4doL z%FTvla=bu5Mh<|1+URNgX{(GEkYZN$GuTXjB;>lh7hB()O$dyRiC_wWB=O8}*RE1)~#}^iYYI>^5MA9 zD4l)?TKMb(sU7)$oXOg-y$T;^y8YBqb=EPAc*cPdMHD3wncKVWJUk$;K=ua2a=q~v z)SP!$*+EhYB=&4q<)};3tp4z9Md5WuO4NtOyohU}#g(y@B-tpL*#JH-$S$CHzGb4D zza7{2#YES18&wQd)zJ>%hq<#%k9#`XqVI0Qe;ox~2Ev*7s4afZ=hD$Lp8TvR$}G+Y z*7kl=xO3N(P0WET+bnr)?yf>DHMBZ^5FYH6cM8i#AE(IrGpna8U_MsNCiD-Nf51a;Np*P zbmFHtTQ|uNHYR=R3pcyJ`-D_5|fSHC5QuL-T% zwWgBI^`=*SUiY8zY9C9VJgV9H5PV*ev-K~>R~g0ye&wm{AKKh+gZ0pblZcBVEGx8b zEXWsPw*#eUX#DJ_!^$%+Gyd)V9cMIa7e~6B2u?j(y%1qGo0xsf-a49^#e5mk-ZNqY zsTh*5M`32*ksBq))t=eZhzAuvJ)c`(qnWPvJ5W<7^c1Me!OCDF7`C$hspmM`I%3NRO--C_DSsP^6DjtHTCeyWKX+~f+fRM1V&^>k4$&Q9Na{ArjYgF z>3SUoNcUBYJ;iNeI6>fA$C)!;_vn}su9y`I*d|o)_H%lBTebc8aPdDzdz=}yC6OC{ z6|H?5JnIMdwV{4_mn5^~2}1`Y7KuX3mFidOs2}0>-#1J8M6Ju<@nvo&vMihb{Gg?v z3PAqd*})p%!;C&tVQc~{jWw&?=yNYVW1lcSahW>#L6_p=s691HR;)Gc#31M}9R?^; zqb1x6Y7xofTSQoPG{BQ$3NQ~`q*?@YBks6g8T{$XWA(x-T({8n!>77#PL5JrQH7pT zNp^)qtY9^hlQU;|Xk|V7qhzDM-bJ>NB3{|xR=f5|mK|c}li)%a4@BRu^fLdbtKJHq zb~s~nR^u^uwoJ0;e_kPBko|kYL%GGb--ueztgvH;M)uWoZgc1Kh5HG=PWV2W@ZEhI zW@OFGyZg>w>(BT7xhb0Zd=sgu1IvL3JirWM4{}{RtTE9;&V(?xC)Z4cm;@>qM;E9j zNKh!>ag|#5RDX$Wp8?Bb1-?sFCmSdX$!!n(BmqbFLWQM`OU_T*o;|Sp?d~__IrO+# zbf_l>t0xiJf`;o{k>4x}3w<&o1ake4+_Y|yuSoFJukt>oKN%cUQq z9I@T|VOXkfDsd^!Y> zr4p78rY`%aYUy(Izpca#?eF*2tre#gDc})Ri`8tR7>GO` zJ8;-U=QvP0IJ2y`Xo9T=9p4~UdIg1H_ zyHC8I9V9L&C5ij-G>7y(i*NcO5Vx_)DmIyPr>wW4{Jf_N{b*&gUmUtQ08spc`sIxu z?p`%R4_C-|4(Xwrhe3&OBz@6HB>b)(7!29*y@{0o2bl^L=vzuhpi?5uzfmKj-;1g0wDGq%zcoNk~24UhT7$Ar6)`Gmutd5EA9k4kW@reFKTlsBW z37b?k%ecy8A42;pq~C(J3Ro@6@s_my_=8UO&A4-TXerZ!s(`q#@#`ngCETpmVh3;n z^V3;nZ^|aeb<4ciyV6%gp+;EV{&|%tkUas3Uq8UkA%4)M+FD#KNL>-i_{=R}=A$mB z+O}J-pv}6|q#hTWDAGWo#c)_FDhJ^xzXQS=e?Ig4fvySsejtZEYE8k@$0gizz!DVb zIZ&@YqFNcihJ0WbrK7FV@B!<;)IkP9qW4tP=)sKc$F)5Am=1S|j$I}8I1OyR(Up5j zDi}?6#1E5r#k*OnY@|DML7kaDJ!A_!9uA_+mDhK}s3Dc%urH8IyIgSv%;Vc7d9&MB zIV`5$+cZP0eH*@8&)@sT#$NjQs~qOP05X6)0FbLoREzlKLZku+NdbY@QO6!dXr>X0 z)1S%tsDAUI_6<7eQKXw~ctJ2#;NZm~DdX++bGguAUMxK^@YjYXBuY)L-6Y@lEk2aF z?nXV90@KGF@+WI_lxe0zO|<$GlRCn^OuFEW0ADrkkQ^8}h|%mm8S{=kSwR?Ou!X~^ ztk_-Q6-LTA!mxy8hYX!U6072$TyeWi^a_VA5ebxwX#7&qom>dvEOgIo2*@caP;+Pe zg>Qi$crj-L3zBv1-fr^4kxGW6u8EF@w(dk}+|XgWyFze8X@29ze_ zGw(g6TdFb(I)U%lrx;cUTnl#PQ(ADY#2!q#0oX7Kt&wH3Q)RsE^-BD2>r;!Vm+(1yYTaR!C}oclD${ zJP$!)dxa{K9|n7lkGaQ*UwvREMR0^*Iiwyun%vV7*_NR7se-qnIt#)hx*#R|{358Ps5m9bKUXispXZ_49QqWrDp5r-w&iI2)KC!JfPCtg6M z9F`sM>-4KW+XhD3sO&Q7!3>*#=|0Mayq$YzbqJkiHCpyd$nIE+!p(geDM=U!t7M^P zriVe;k*<)G5=y=fzC#K*d|~}rV9i!Y>?vBCNg@rYx~Ewulmt*KA+K6qJVAD#*vLS_ zXG!+3yQi@3%MrC7>CL&kSFobUpOL>^NS(G8PPI9nw~q>CMa|WRZ|jO*j%=kUTTPU0 z4)LrGysdOd-Ppuo_o9L*XZWn2t?g;wVa}@{PJFCbFz{3B!eJbygE&0>J&oe^ySRHQ zT`+hri`k0#XOh=OS!0O<=i#+15NG0U9X0M}hBiCcVXI`nZayFS5%Q2QP+iH%xdIC^ zq%4u{vCM<#M1lTV>+eQJTaG>7oZxQaz{V%&MduDI<}u=jgZL+e!m1D@1x@y+j$Fef z9)HSWvBC#&cgU`CBY#W!%)?mZ$}6X2OsA*AXK0xf&!C9m-e`(o8@(PhMd@kF0 zZQYEluBVF{x?1n`RMe!%)K}X?GVZLHpMmd*M?MAjtFK;4z!1RSF<`1vZH}9lfLDA~ z!eH;wWsJxv`R*1vY2){4@O0Z~RoRg5=Wf}95sR}+SeNx>I@JM- z@7)u*XTeIzE;Dz+B202-Ig>&!hu}RSTGjpI-imhzp$Pca*F=tW7=^p zoE`Hs0wfe<9iuzMl!K73RbeAjp+*M9kutFu`-Y zWHY>>8dgG>=cg$`e>e^naPWz|-Q~elGXx5w6wkxN+?83r)|@HR=vq24lj;k1Up{*t zliU16^VlEqXriXxz#3KL6O*k~ujv;F&+Wo~h!eQCTT2A*0EOdlLddlm_P(Srqb@-t zcerPEbN@#Yue_U^(&SIBd%jC4NtdbxcY>MZf-}r1RoRtOOPcSG8_km&#@>bVU72}Q z^g5LG$?^nWq962E7vUD&wR)&I(Lx7J8k8d)?7XdG=+-2~F|Q#vE)H5&7!^+8@k7De zT+$}0r;@tNXb>bCE$~R0 zf>sGfv_y+(bGx~narG1v%8u`I!5eYmd7M%J0pagseo08+IvdepmtP0uC9N@(zX$&| zFS~X{jQzuCAVqW+>YebT4B0DG$olxTOW0s`hL-udyWid`x3zvmt)DhEP}O>xaSlZQ zLpk!osAS}5B+Zv+rq$h*KGJ`1Q&Px$e4ua!Na4ZJ?`^9eX$3#f%r3x0^TYLAIQfLa zeByG<6<%W|&q3Oj2HMUu(nO;iSzuyt))EmiCSkKyVI1ra7IP6+=;t}y_GcNlz)nrS zynPw?3JC+5&)k~iYxiDHzQ?Cp@#ka7t?sLA%k zvW>j_l0R}i`PSsDQ~yYHr9f3V9Qf2-IBK5d39m8%j1`SCdgtcPGo&ODP=~`(BZrgO z=I*Rx(vFD>9p{<6fMg27rFB`kyhKSPhnbDoAeM*Of1hd?T(XLyAr2*d{umdx6`Dbk zpi#;wEAGtcfFx$BrTD{(yrTLN^Qh0+>i+EUZ z^`jLSqE-}LBo>4lWo+K=FUa6vR=!CY$1Zqi7jZdA@nuwVPC5)5KTg~76C$oE5;S+5 zZk5-`jIa^^E+L^GY>Nx}@F^C0xASG!L`jS4ld&&$Ih#tS3F>F(Oy$S=m9VzT zIf;_8`418$`#x#2(LlnJtKd2e>O6!bJiP29ZV!r57Kz2+uHjy~wKbMe_>j24A*Y!~ zp?EdSb9@IBOod4(}eH{Y3am}A%#N;BpV)XeNreX5$~LFLpmkH;mDeh1Gll6jCiSv82QS8 ziM2KMtqBtx59t!j!x6y888J6>?XT6GRmbFSm^Rnf%9Rgu*|UBt9vvOYuOC5%s)fy{ zC5|v{OQRO+ibJ%n1Gy#9(Y%QtUEp&#VjIac(s4UZMBVs`(TkG@MuA)<2tD_BMa_Ie zS*Jdl48#fy*0dc{8n9;E34EVxI7|S1%Mb<1=-bB$A@RAo{nK*CESOt@Q(mRq&@&`S zWs*cX1tAikRN&5<{kAxv%i7bDC-$X#7O||D!lx@vX7rbckdNW#*2oZdWiX!w{G~$Q z`e(cmdMal~^JboD!pNzNJh;U^x6(&b7%9tS){*B(SjLIwwP1yEe@-gyns}Bzfi!s< z;b5b5%VKIr?YH=GIWfrDGaNy@Qk0tTj3jw}XE)|_y| z_qgddXI5cQvY5{|d0FQ!c#Q-nBVaNpQCl2to_GzLE+fnxs7K(~SeE5q<4If=F^&2f zguXJ5X^TkYi97~#peSQ3m?nBdyXLG!aBQFQ5%z@-XVo>@$*#ue3@2e^jvtOLrS)U$ zo+h;@k(@u2KN&Dz${e|6%zp>#ao?GT0Tb)cV~&^F<;I+ zrJ#+)_#vjzi_&XxEvMF`^lY<*v7t+E-=#M)ge2H~mU;RjU$#S+ZT78vmTn{q#{FX7 z?KkGtv|~Y$g{eqvjm4BKrh$w*n&&tIwRQ$3_FfM>Q*_b0aH5wQ*!wm)&k6F}guA4{ z7=0_VuV>+N6EY1J7n|3l#iW4rE!~jbqquMq>l?{_RbDX!l27aQ;;;GTy|gJg>vPU- zgA>3yYHnxqB(~l}s->hej3$66zGR^D~qM+&?pYqN-ly|}-n4mIh*{`q#( zRHcbktw-&xd0)}pDJA)1;|+xpl?5r*wl|I=`lPUdbyMQ6UfJhn>!%v!`Cf0Y3`7mp z-V1u{hZRK*H%j{3DJiUGr~>Ir$)o3q^}bYiBG^o41Koc`;jXE+Bi2&ZCcJQGAW8}7 zP+Y^doI3H-*{yuFW4nTU zQ0`F2px!1(sm=zPDx1&^n>vMVZ6KfeDHuaB4X|d?rt{(KC%=40ZrqxBIafpEF2liZ z2;f`Dq;>}9)7SOadyIe?Jb)R(9*XhIt?efJZGjv483f%4dhShm4@df!z1DLp2#}m6 zZ)*Yf$vH1&g3VY%w4MLnI0{Ab-QZK*nVnjcw0f*MM2L&Toq-xT?>FAaD80*&$-Zk| za?3LG$7vWcQ~YCE$sJXGr`THF4YQhi0T+$4dmN3M=-$dZO}MnQC3lO7DsP6|ZHRuY zI%bt4`ZZ7)JT+hMwV)ohB@B`EiLb$Iy3O=Kv$}1ma2aZ7aaMkuD5d>$D&?9R>h>nl z9g1|^!!Qv!rp!yLA@|HlkWk_^Q^S=$oqBD9iZHk=Q`Ah{c~17i{mJU-RTp?MK;Jbo zC|JD5gqnw84z>Ftw?ACnroasuZ*S8Z62L`)tAV_0UZPI8go%d3W6n!Eum64(IG=ag zHSpB~9O}&!-AwkP9EDJ_mKon?)i#L{+b6<-DQx|6YN@BVAMhMs4e6Fw&7NIyry^Y$ z&LVI0lnAUPL=_3A<5Vr3iZyc0ARen9a6iJ$5#3j67#`=NF; zmgFpV`aY{ga?(n(b+{38dDUQZiaW?Ufmoj+0Af@ ztNv4_rJBNW?Z*z6-9x+TQd&{xIQLaC#aqghPam~EsB09-Zzcsm*&6Xy6-;C5iDkT}%tZnp-rYRaP$&gWXk%`#Fr8kuyw4rMHd3o?PMJLwEKYuK#e`}gl<2RhzH%^DaUkeJ7lNBK1%xK*L{6qQt?`U0bLUECV6At)b|dY* zohOmrafO5PMLn4sEG5~=Dizl6$7R~Kl%;DcnDbq}E4%7Oi4K$*UJHBO_XY8@PWXnG zU=W3Nms<=kHb3QetWA7xM4GoZN6RBh18TCLXm921Tb!N^gP+zI_>q{24VKu+$I^LR2AHlSC3as=o_5v?`K*<+Cgzc&g~o_ z)ZD`BcC*y;L5CCgu{8sRTVOh!U5yTBAq9ZGEx~7V+ju6Qgm@;X2#eu>d41?4eoICp z5_#WtO}LW@wTyDCM}-Th3pI;AnA>N(IxpBPR(4FF_}aMo_n6nS2-$oaUq#!G7r_~) ze5On9B5T4{D2VPZiaCuo#!)+3~Zk>w5hp0a|xz*Q8okZ(GaQ-@ee3hFgg5xChZ)y0)>s zkk1_on8){GjAzdibDu||FM`Z5s@QVzWQ<@N!=;!TP@RBeHrtPws-}E{j2G66UkEx&(Pr?c(3@^e<+6LgYP_0dXWC{Q5}H0=aqln79r9gV#yq+etuE^sbKqC>HN~C z4mqq>jL-R>X&pr|HAQ}4&158Y!MKLseT?i-JSjqyOz_3cljS2B_Ghd$I?|oF@46}vd&hAa`46+(fBP1YV12%}KqPHEuVD6y>`p9>F0&*wKPh_R zx?uT@!oah#xA%Xl)$T1}_7|96@R=Z%jW0Vz#g&X7bO(BoYXUuspF{%bdppe~k*6bZ z*D@YV7*BalTY=y}Il>PdUoG)Q%{~MkwHQ`crbPlcFZrYo2YPPWgO*X8i3k>gM%AA* zFL@|;rqIU#iRwV3>rd1!|2btZ!<*aI zI90Ucy53cpulmfwFYlspii(DBQ{b7>&r}01^dfY99NaW~0yv@~awtMK>v||R>NFFR z9m~jXIf{?4ovMi8^yBnJjn8@I_pa%gBZ_WbN>*_@?^F$=-{ z-gn}@6>_EzhjStBbO4!QehYmkfe`+iAci$sB#>gd$}UN1Z6+@G-TJi{`_t0k;C0-k zbNfVgqjm2qsxdv4ZT_7|#4^&Y@e($|G7<6QlC!^pai;$*2Bh(?->!xgqC#wi_uca4 zqf7@cvc2n~X$(=#NgX{VrF(ZVSkG1YyRwv1gVPVT-h0{L<#^8pX?6|T#Aa*Lp~Q~? zT`-fWHtn5qQ}osH;%St6X!q{Tt4TxVPm}zc15%n#O|PcQETu_f9u=?e?8RvB5NrYu zK(d&fL2Q^do%dSTj(Ew{aRwW8BeKoN+q`BzS2tU&0Ro2T>DTtqsB>=?BZRB?k*$Fjc(Qhw(&95n56U?W0>CJ~U z-ss^sto7B`9NhCB%H6+5jc6C~`tn-evUl`;V1V&^tMm8u?Z;&j*;ZG{F+G&z2CtP{ zBFFl^yFSnyiY)ez=<_+VWC^$56Ai7U8zzLY0?@P>wJ=I;A$J3}9vX#HrCw6F0l)Ut z&kdz00Sk4}eoxB`)ehJ!;?SgyZ#Choq_a!1?ompvX)zbTk1dd$5@&q7!=}QFu^1Dm zCwMpc>~-T{9wC$42`Apn`dRar)}TadGZ-aI<%CEwy-%Lk@cDi!Xa&FpxZy})Vu&Qz zrd=AC6?6=pxy2KW-3#bcQZ!3ehRBLtw0}fL?Un$E?%?!h{j-V7+7aS} zCVg@5R&~aP1xsx|)joOW>-h*xYF^?8=L}*(b-l_Iv3dH5TWnj?-k0}v&xMgL=E>Kk z0ZfTVXCl8gbm&c+R7)fBp*u4O&_lTd=QF=J+wF4VF1=K!88Q4TBWBxi)tZ(Qn z8x>TOPSay7&esn)G<^d+oXnc`82lahqic8X&&u&W`5u}rkBO#*?7d?I?p$O(g41Qz z&x(oc!EeS%g3_9jWz+Y1pChF6nFNIY82h2de{ae?I||byplQae zgvc^ktu^oseK|GQ-#@<+yVOPh_}tkob{z4aKGn${1(x0_y4`>~yj#z-^KGA5NIB`z z_{2$=#n_Zv$mKi#x*Dfdk*`}3*S7N6Bb4RhsB*5#nQZ&FQQ6aS4+6QiA4m#)(0+1} zZ!3|_G>#==!5k`K$fdBhgFceQ74aqoD`$teKX*Sgb{duWw0MPy5AFD6NJ>?$g#}sT zj~jmMc%4?M($48PzYgg9vKL)`fSV%Y_rvu30F4BVN}gi=et!J!>fMAfHr37egb{Z=9g>5m7m_p@-}C>;XQ z-6_(INP~1qNjK8nNOyOKt*E_MF-pcUm zI$NFn`0Dpt(Lhgp0_6G=!dEGE<6T7x6*i|^-^2cTnWs=nXKwb`*oPDEy_cVXEp1sY?$`YC6lHo$Izkm z0Qe;xd42N{j#|LeQw@-Gl)Cn>zf5ofS65He+y*6pf*v5qC;4%MSct$Qv*7%NKUhKY zi(5|L?DM#oNH+w(TNENki+fm$)3b|)(V{_{?0)w{E;G=WChB?G8>*MgyU{{}613$m zru!Z)XE_AyD+gxNQOSh4uV1c7REnMGZ+T;c=d3V%MQ=NM!Y?STVYXul`7JLN8%;sf@h6KBIeu;`t~lXBiTm={`$f&X2|evOp1xF zS?sKkwMT7<=&=#;mskm34Q!G ztLUBhh&~!P&}0zG!-$ci8Q}l^;vQ^&eb?E0@|;(sQ@!z_qJ`i{o8d-SC#to(Rl;Dn zs7?UU_|F=f!QEhJtnnd%27Kia9ca)SDqr6FKq2GXZw<)jiu*g_XZc_Mg0EXNI5L-Q z*nH?KGF%DnK3w^B7mZE5sU=p#bN36*c85c_ayW*pL8EG7yo}hj)VaOQ3!g`B58tWr zR%&#AU&&^f5xHpMW9cfhQ1U?~-mou_`8;5XxB66#5OIghrP$Skre8ZnKYoUdt1{i9 zpFw>;nEJRC&2+1sgjtkV| zQ-{`r63L)cq!I4qB6l%o2(hYC=3ymmLg0XU;tjQvi9VR0^o0XuSfGqAO?H)bEPq(> z7b`yi=Qn)Lv;y@{96-Y7`N)STJ#ixz%D|G{ZNDo2J@_~MuL4<+|DZ*@Jf|X+ZS)`C zjtv!o*+0yd2@AeT>u492ekt-Q3?HlO36d5}7OB1j8R7xcd3@6S1aC!3=u~ieQvz~TCU+;$|wurpM! z9VeX@_j(}AGuuB)hknHRs_~+u5RHCg-Ii#GLttmSy95go2E!Rpm07z?6L9tLwC(FD z(bJd}LSuT4FVU>1jUw}it?o~Nxk2LXI_X}X)*7p~7-3O=)=p|FuHFoamL0$5WR2h4 zZX_181uwwBa@jfXrJ2Yi0`Q{mAa0~X+7C~*eWUdG9uOdUQ{le2ugnm*kblh)!2~aJ zyo8?sPwNeIwlML}UjArZZfyGv{IlK02`m85zu1N+wc*JfdTyEOIJ{_R&*y}ji$&>9 zHU@L}C!*hRe|Z40pw#h@Cf%Y4cvw{JUh>9b+wgwutV7Lcc$S*ahiEp#oPfwdovro5 zUUm|H&%C`bnnv)5%Cqb*sP0kKculFQt3VvOgV2}pWST9(ic-}XJDX2NN^Rs3no^za zXvSV$m&c#jL* z7vXG29~`yG(>q`|fnI;Ou&gbp-cO?ZZ6;I0PF^{5YTLZJ$iJkmI8`P>&5ZRj&Ny^c zuoU`kheP)qUNqk_iN$@GWNQ=Y>=lkG@I^C3v45Dam*}PaMJX921QU-tUdYpe7>4KL zg^0SD>Qv?;T{y!~aEoOO$zQaExSo?|r+n@}Qhs75^M02AY;Ot@LwxT5|T+JBQLWy zGhF#ze~iaF{dLK4IueVNVuzw>Q~xQv!m&9+DzJlPR&pf<=2V8qz4ux#+dZiJmzY%U z+ityb4nCI5K3%n{@AHKPPtIDwxr=`=lXi4cIhub~=ab)!eK2Lq42pN%Uy?p(mq$A= zG|49~>l%8r&W6k`w@3>{BZ9+e$x;&phIXFLd1yVWO?NdHKnJkl3&_=NxIxe0?lfm# z<_ASf7}$#ksMT>^e;h5;9xX4^WNgD0<$&YnO)evW?rSJ6C z^kwiC9zg}e3E0cKoh9r5 zoBxh;;d!9 z#v++h(8kmJLK@01do`J+3+Bq|S}rZSX^6Cl$^GnzEBpP4MvR5|nM7D;Hd za-BS_&-gDRe3t!70T`jT(zU*O)7wcKD}LYyKB2{V&NwlrzQ3cxguZ^&e3Mw^avs0U zo5l~!9p{h_!5K@(k%VT#rZ~v+#zXM??Hwh|cH~mv8nh?ggJ=owMS*0DjK`>b)5>-i zi(g>Gj=l96^oGHgHMmgr5sPfJ(hTc zqrQA|E_l)Z`f6d4LsCMDvA8VM^ebDXA+^yULhWT<-q&bX;dIe&2UxqpuS~yTw^DYx)HKa=6dyz0||lg ze|6ME{)8q`jw?ku-=&?&8)b8Byu$*VPaE@}Pm8ZQN z8Z}KvZVB1Z%;0PJm3E%C#c7#?Rf#e2Yt@WgY7!AuT*G;Y%W1Ky%4XD(=e7*u&h4PN z_^krkEs0}OB%AS3ezG^a3S&%mG5Icu-LARiKLI$ zE3D4vuE>+b~t&GPt7wmba@FyhgOIaum+yidF&fUd0(Y=v{Ps#uF0Bh?)uNJDcL^ zk3f25{WvT4;oPBgBn}@4cgYI>!d*Mt*8r27H#yu5bxJ}ws5m8fJV#zz9rI_oVj23B zucQ3QT_^=B&0FQ&6g2#O&c5Qmn8~rcOcaxSFG~nd~4zK_Ul_Fy|CG zrj?JZHvMVxa1oKfQA%5BB29jn6|OF1%RFvyu_cajG@tCix;Kv8&E|^f|D?h-`gccyy{4FT zm+90qBUwwNU87$sxhIB6 zq)A|&iJ(gv8MW%tR8YGRmbYs7noc z)W&6m9xi=X@OGEhI-F9Jn zW|;!wjsk_wW7agEgXUIR{6 z>7`9-*ZHSy1pT3VfBTI+#3ji?#g3ZW3pwBW-TE>mW=t+~f{kawbQD{_^{_G*$qQ`? zmC}e1Yy1F%9I7{E4M86rb!>e}z6HW`JkYFseh0AjjDazq@d~YvsK&~uMWgtD=wAhtz?eWL|Jrb<_=rDpIgvg4r z0?2td5qmRwKDg!7d9p3r6-iP7Fc<+kDH(r|(Z@-T&wk~qMMR=py=|Mgo+rv z(PKiXlj0xE!jP56OZONK`ngGgu~G~6JVXy6$Ox#mn2+8eAgJL-7%|=So$k#{*VZzr z#`t$?Ffxz@2eWVW(Q>-_`KXD8+t*?wuBcIbohrchyt?j8)6|&!ocnVE^|1e;tKHAz zkG++jTSFUml>H_D>;#&5Qq>_vT2RV7V_}3yeO1bta9{b{Cab!|Z81dsYU@T}T+AUn zu_*?*;Widm=x&P)KzznJ*Lf_lLxd|6MAzwshrtYlK;Q{gw$ByaS{CU}z59gbE@)xi z9KFvKo+KaB6N^4=IsfG5&h5(m_qwp1{#usf=^QPQjH=nR*aW@z_YCIY*$2>iy^&Hi0G``2bBwO7<;T!$hKE=LSSc6CUj#G(jMTlsU zf=+?c&z;Dve_}5=Q)X?XFTS_&rkvNVGai$v!1}zTyPTSjr9{y)vV-*{r3efeqLu!5`m?dt!;ycN(0VKY+ zGC_R((jd^9$Fkr-ouLGhbvI2jBrj1rLB_eqHBH4>wTW`>;(%tX+J&cJ&b!)m{x+DV ze@gcGkK40A3j~B1s+1<0*m>f*gpc$HH~Ru8)V#*sEmMpxW7%&$sABPQ(nU_|;98Zv zC&;z=XrRnYUS+yK!7Jrnnb=;1tu-7nV4=-KSC=G!viZmI+o&ZQ*D!FhKIf&K^D_e` z(i`><2`Evh-x3eH*L}Uam`M<3=U-3Q(&5vB0G>`<16INbW5{NpdDu7xy@p?a-H~WU zJa^?D&f(64$ZiR}SwdmWwMo-Y^>K!eL&AoxIX4ykT~X!};o){^Q9UOmDo&f=D!-HR z(2gQ&#Z*y%J+r}iCJt!gWy)VlUpee}*@08mO%3zGW^OOqd{)CDx(|M!@a#KAL$$?m zRPyL{;6I-41Zo#||NfI#O3J{N4UuF)mg^6OP*%Pm!n#z$9=LE59=1 zUir1krV#ZOAD|$gu6~l*%>Z8B*sJZ2BiD`b-!dtpO$;lIl>P-O7Uq+^g+h7aDa3w>ObZl=cMyNc(FJ^=$57IVf z^17`_zrvZy@ZS~-a_~kXC?$uNRrnD7CzLC{?d=t_aXy_Aa5J>!&CpcQpQ%6o?1H-% zIgAmq=|3jNXcVvY{-py5Z1T`ag`-|dl0Fs=8PD|fUMN?(UP&}AM# zSio8IM^kSywZ;ZPhd5=eo#GDN4AjoJ!Nn-OQQCb2a=LtM4;W z^8&HR1Z6k)dEg0I-Wzlup^0igp2?!0@9N-N}I5@PE&1ZRk z18!iF0tR`hfMH!kst4j5FintDPiWTZbGW;qP-rhrt^hp?7cj)pIYc^gD4rOQZns&9 zGc!MHmJDgwYGF+4<;5DeXF^B`Vb&@SFx?3c;*0f4-r<=L98N)g^GbZWdri{y7c`YZ z(f;83-=eaFrg>stdLDU=4wv`Hp;ns+*A;(HFmT6ZXA9E_kkk<%9)EbdN_$$bMpId` zvn$x>%gn49)YIvXGza$UTff$Az(A{q&a>tMwm0t@a8AxmqGCndOMf~gmTZ!Sw|;JH zox~KrXREqC^ope~6R$mZWb@uG(?xbD_yI)TtN4N>9nE@%vyW<48>+NKj_MTV#XMcY zczQ?zWk&^kKxPOf-pXg|+W-s-tiKTD40JWY^unbe{OFJaIujR(1LvQo&Nb^7J*z{G zfdIC7z>A3@rf_;&6e?z$w@4^sh$>dx2xOTy0W=ORt7WZxc;kqmnC3^Q!|!_DwiaRG z{pKexRf1Je@7ga?6!}aPI8zzUK1lXTHf2+5krACWR!X0vwf+E`4w4)ex^B3$k7!ce z%e-UR@DyYwZFs*G_xkjGE7p1CcY_q~c z%oSd(Ub?{W>$Q@f$RcyC!g~dZ!cBfw4~w30v%x#NFlQ*37)thG^&v!o_Ir5EBErm8 z!>VJ8p<{ER*e2-1K-MDN=aaJH{5sYFHr;PP6sc>wxzK|-XDE{fJ^|9Pn<&UW_h zn1l#0ATrwK2`#MQdQ2Ol;`$dp*HrtjpiOwy%Qai&cCRd^6NEOSRzQsB7*Q2OcOdsR zzEGZ}2n7YV8d{7++Qc~u9{^;Xx4??(i-d^o?XZ!k+HC& zb3C7uUrZo08fhWm!A(@6$>28p#v;;b_))2bwLRBu3-4`_opr@q&rjMqx2cAC%MzcD zd-9cnK7EYIPVXt(8^NsGx+46jG=JCX&2FAxFx<;kk-c1xj{t4K32@L{Z-upCB4Q82 z7N0?C-yv$nx{VzfGoVs=dwB>f?d}D2L@5y%fIS0QIGlZBRQDJY(K{D<$rE0W3hq{U zt04_vA@CdhI%EP{281KLe}&LF5)v_DdUwm2N@sd4ZlzF;HAO>H6OQD)cDS-a5wdOdRwG8Oil3<+<)x4hYp zIEqwK-j8)>KCWO?YW=iES70W?5G6dfTd8@ym7|`RcW!N%D>o{O@T=&WJ{>8L3TIC+ zsMiOFE3z$;5Vbnhi#ffut?2q1p9v7}aE6K*HOMtSBn>gbds<$x0JGc4niu~d4C92{ z%%Zf+PR3DipmIlo?Nrz$80%I6>?vY}O)C7MSvsd68A#d#l)?9z+>(JK-0ljBa9xx+Gc-?1dduB zbhY+L_Y4fssAn@B#K!uvQn_{6)0lI91=GNTm2h)E)Xo~es#SKetuhdizY^ueqbqIj zg%gXJ7tx2J(rL=i5J3pR#wpRysgAD>KNdF1K!cMlYlT~ja-SiMi{gS6Ap?x{{#hyw zBmS{cV|1|n(;$UNJZBb05{8+B_=e+KW6~P#BLdTfu4;7`T*yd-Asi!F~4o1!6|9y0WZ;e5pl|ELQNEHaDs#bwI1ivB;=*QQfJcw~NoNf+*0Dr$xmi>rAQ3`0 za;~^5pZW4j$g}FG5;l_^hDQ$}FePb_Xz$KT{Zb{s)5 zX;ic;Ta(4{IBwmA6wWqplcKU1&LJa09jENZvkN5>e?locR=9d1AjXS1>LlOj+q-y} z05A(1v;eOVxuutw^>(zeTsClquOQgOY0_TZn~hsr%5kREgJ{e7cqtWDwp{7Rx3T*N z$CvSVzBPA(C_^rmIKa+{Zv#}FLcHX~rH-Gpzw%q`)+Y^L2M_{k8=LcU75_~c=}Xh@ zjfbwc%Q!OPNOfz)Cy+uUZv)&C(;S`XsBy%+{)wW{rT4!EGAk{Wh`=+wK&U&Xzoc`r z;yP*O1fQ2to!pOUturI=!H0BUAkt8(q#R8O_4FPoL162!MGg?BTneQ?1#PO8B!i*0 zs#KV7xOH2nmQ)414?RU&wMxClQX_8MxAIb(wer1rYB^ycBD^+uf>?;`{SKUb>S;Ms*2jKQ zv+vOA7#rqJygwlEtrRs%n2R)<10yGkpXuNXK1kzkW-N-wsssTOFitMMaROGUxIrL4 zJm@w*M!3CdMG;Oi#URFmE2F%qfsrtk!dSmRYaiYuW0CRV(H*5RCJd|Z6=apzc@nk{ zCa->>1tozy^Y^oT8sPHluCXgF=n>*?me!??<>{88fLRIGY9Zk0Kx{ArX{^wtFrvGb zx?qAN2s|53O{8^5%9`9!0VoKbI1#3j?0nSvni_03)>^)%S#!mqhezB-Ez08Xwg5ZC zERh=!8Vz-x4q}ADsm^Aq56JJpb5g~7F$aByF?W|l0s{gMjT_ai5Fi6@r^6|<#0WJh z)1;%iBu|L7Gs6_V|06wH!Im`dEkt7-@}AzpGNn-wJRXDCC8|V;k0Z?pPcDPVzkCK8 zJ((QgH<8=+Qc3}~_!z=(6%JD98C2Zh4=&RJXOD(SCnm#`Vn>&d@c(LXsB|V2evvts z-Q&+O)UX7Bc8NSsjuWwiWG>({!J454^+bErkyhoGS1kzIkI|%1kH8~#Q^BGI-I!di zD=WL7qdWiAAW$Qa$puFE;xD=w1foU$eUBIrag=c>M553(TV{y|@)aji6YkGasR)C2 z2@u@*4b_sct-u!tp1}r<>#z9WY2SvfRH!iQ5Ac+fB7mjbC=A@PEaYZpL+Kp_^M<#K zLAF-}1H{4iEsj!FK9>>}Dpf4NUf~kDlSAgX*}FrReTUuP7ZJ8$RTN_c4DY}gJ+wu# zo@@7z$3Ae!I4Py2gd)GUqXnwl>RwB<}3BB~202HP)(Y z36ti}cgw7p(b3F(4b^JqL{<(NFX(ZTjUhMnvRZa6+zi8ZfXkK{2HrDIKQu}hRtTN6 z8hn>Rn){hQsUkl@UJ^_gmO!zFE%HOIsBC_uzKQvLc#wkVTP+Heqs1v<%#0$GhkdsZ zEl$INs|L&oe5-$(;Uv019QK08Odv{r;+Kbr^87Ay_LY$#aWry}ZNK*QkV6(wJj(zsB zir>j#iw_`_E_dI zxbEuRljzD}X9^_X8@5q5Cuo@oCUVD0rDVW+?9+nxxW0Z7$;6$1TAI9n*WdN?eX^?CM!zeyoAu8rf~^#dHw+pDj*WnUrI;MBX(n8s?42MY2;GFisiWA* zft)_Vtf*ZEk2jdG9s1XFD5rr852nNoxv49AW)buj-B%I*a%yM+5e#6jW*tgDTvFAj z4MNKqrvL(AU7}y06CO23+$BT+ZEN(cBWDF@&cjZzT+{5&<~Y*)-tTr_XO7q>wr>Gt znK%Yq2$m!%OxPfDxL!Ul;toE>d7<|Db^xWLUOn}Tzd~AXROsrJiDO7kIL05ri9oF$ z^@cLHQL=ostcL`Q@2Nz0N_*vX9OrenIh>Mk=V}b8UGAn;I~-V5?R58<+=)lV1-2jM z#|etjDmx6^36l-Zk0sQy3sfroasH#@u}-ZmQR<3$$ckN#3FqcxH|e9=&N+Qd9{}YK zA?7)6E5&RZJ54(2jC*dJ7~0`MPgphm>$5dSlr&u`*~twq2xaC^#xX-d9Hl>d&qZAK zaCG?Ee}xr}NW8*fpGpg6x1fTZQ_tQ;s3czgqDKiC|EmH-mw-L4dz1&8{2^^uf(`7- z9D3S)ocGMNrtm741-N%?)WatVzSOfCWWhYj&(}W}3FCucrXkt9*D_m=C}q5yUdV1~ z&m6;`{I%yRgJdt)ewKE&W#(f{hLPNvnVKI`BOm54`Hna1rD%v_xOY~GPKUm963+x` z@i<-5+1D8Th};t(4c%V}ILiTvc7BG`U_ING%^ zEKZo+l{#q~L>#7*t=T;;qK6baN)$-|@a}4nFtc>dzn0?e}{b`W)B31m1AvQ1$nGXZ? zron;`4CYS2wYE=nv6DNv>Tr0@_`&w#&3V!1u}sOD68}AA$aIRVG^1`;O#fz|!?*!k ziAIefOAMWsFDNpxg0QQG4Hpjp_b#$|pY>_`)&*^yzufkUOkp?Mfk>_}$v{+^0U_(lA7Z+$;y|FL!0#k^0 zzkwyude+>81os-^ue5gD%W0oN^-5V@3wnHjyJ}caJM)*7FRr;(2H=ljixQB-Z#(T; zXNrkM&ek+c8j)fZ`QNfG4g_B=N(>4WUTDiXC!rMA-0e7)Kl!U0ou%tbE;r`GBs+_x zXbcfwJRaR1A~oU+`3k*ehrEgXI7(XF$Ek;`J^giH=iS_7W!>>AVenQj+76`Kluq}w z?h}b>n%z-EYZ+j%3Suj;FZ*jdLeBWpY;+PEwzU4t+QGTwI(0^M`Rq46>ypz}jI}SS z#E;V1O~k{kWZcP%!;^P|PTa9E9|$+={%2vjw50hfLJ$CW6c66c>v0x2w7pv5-iq$R zS@O&9bpjp);coAzQtW3ZVstfh03me2<}sm{8XL`(pXPtwoLQauy?a6OwC%H(JEU}y zuv^8$wI1_e4;WxE-q0Ri)yo9)pUdAD#Ev{>rPP&0Nx)G9@^iA`7s@;BWal1+-(s>(El(6SKoI>xJBcQ^S_m-y2G(mk<8of00}@PVhiQ(foncjmeJ z88^r4K#!HE6=$-$LcmAn#)thx&ObbNkmd%TMqnmd_7UTyT?<7;cvJrOPMP;jOn>6z z>&JXwMlZOK@13E;T{mDg_e=#jIDu(#X+`qlEBMhVTMmj`zM&?%U#j6bX?%hb?OH9${I2`5&w z?#z$$R9xzySs=~hj`K?Nt$A}dui)4uNbCDC7?~hXs&|Dh!{8;+pFdGJinSY##S(yx zN@7DoDT?OCZq3y2{fX@5YNNv2Vp;X6@&@)9J;B3}f$^=S-~{Bg(vR1IwTHv>lCvKi zt8%{Cvm(xn#*Bu~Xr&nLM#ucejOzN>HS)aAeCqH?51q=_-)8f2Gq&d_$>h&xEnag) zYt_|+@_GjOt*)J+diWv3!{F1s6W;&U@=87Aye8#=c0jtjEQt^8gkxC_QS*jby{Lwh z&GA^CSI1?9mnKEbB$Fgm(O-~Xd1Th0@(sx@y0zu5CQAg_JQ5;Y=shCZT;x8?i1OFB zDbRYk(&b#>Z2#xeJR*u4nq8xaU2*I`LTX=J_?2ysp5?4Br22$ap&d>tiPOx!_6R#a zH#cvXGcL#a3zbtXKGxm$BXvHtq+T2oNVAFdKQ~oypH}5~-=sH6w#}vYKH@UUQGsOm zv+U!G)WeYn`nGHTDLyz~hr4e-V)&3BS8DFqo)k`!gJH>IvG%ROt{dO8%i_w(iZ)-H zLmSl%kgjWwV${p6B*IEl)!xbX-ge8KyVcnqAiOU#C%{oGU7j7xr@7X(~{yWN2wCoAMblh}(lqQJXw_;Q$d1zZJRN9;m{fI$N zLz z+UgYl()~u66`a}&w9Rx43#R%tm!`otQ!VZ&#{!ezRJHb^NI}$ZZ}>FoRYpu*C%t-r z1EFM(-flK6ifH~jLc#~F>ujWmPLZ58`?%ddQ9JQf8KDu1%3YwT;&&}3MwIrWj?E*} z%{7)-2y&de*|A@T9H)KuBt`z~g!NBq{q*3{{L}YV z|9U5l_RVjbrJTZPb}!`Xdv zjcBUkmFmMwjV~7tjI03wA%6faToM2Ni~fZOaSHx9)Hfd>bliSkA=kTMe?}&J4=(g*W&gnHNN=8rkJIw^9OSz z)UTrhniYU9z$63>#=W59(^ATX&pFFk{vOYahCr(>R5sQ6wY|&ba&|}Mxay`L%BXr(a7uz~0oS@~c41PC$O0A*Pu}>` zCLQA2jlvqqr*Bero;rE=29&(}W7YEB#n?8lu zN~QW6=4qv#<{1o~U(+%8CQy%-P3;!}|Bv1BY(SW2sjXeLGm9-OwW&K;-k}&_>jz5@ zz~)e?7yTDr`qre~hCRVKd<3$i5gb0}{9gQ#CxVuG1k0kkUvW;mpinnOpee(Xru^=4eeVkYlQS3O2M_B={sxRN7b&U+Yee^fgw8popec?F%yTR^g#q-IYet3?M z;BS?wWjw%c=s9G0JgSEO`)S=(>P)~@^6Qz&%Ceu1_qy+!+{yPQZ6g@ySc=rwoLoaX3HFL3>x=770;o$$aldM+Ya%DIQny!~f>%9@;# zM0>zV81<=(4rEVtZ%wIK()nt29;=ju%y#;~$RblWgOI3m%9%bwqU<6x!H6WI_$?p+ z**I=YXfHRpXJV)fJf}`njy;)J9kCyL#WkW*_%@-@T&k1&M9vpU|yi zi{E6)q2gHYhC5}eFKmVVzoWx&Q2vF;(3Q4k3fQ6pgq4DH!1j@Et;NC8+xB!#X z31=6N*zO}fZ4y9<2Zf_vRk~(|P7`|PRG?Iu`?8Ky0ETWfJ_vje1S9;2moFw*XB#5t z!7Xd{MDI3EXcOE==$8a#;gUdrMMz^I%pnrR>KN(q^Ke*O6g_8NQ#|@z@S5gh+GpDj zF$oEK1AOug$l+}0JF`FW1U$_d_4%HHH1pzHBj(mNnLWCSd}>-W9iNdWEZoTQ(<{vc zvJbg8R#wMo0gLjoJ`)-g-e6S01JqUgh@DJLT+Xuww7Ylq#?^VaWIk*dIo1l6;zc6 z%ItQd3@ZJZKiW2HO>Bxxs~kxek#JdTS;=c;c=n##ZI#Yl!2DUm`P@&Om-!^FHU%rj zZR1ScVS=#@mv9O*iEN%z;I?P<#IWss6}QsIz-0-OkpMEuKar~QclHDgXLB|TfYxl! zefJLDo8NYGQ`K?vn3H2OxjQCVIeZ!JSTT3uHstB~LBi6lZk9Wx_j2#ZqNCDz?ZCcn zGaq-IALBE z`sso8?E}rWuG|Up!5b&frU5cVRN3R|9{w0O*y_(-%;n8(&*{VU{}#5}(d9L7^Tm}J z-sC@FTBwfoh;NL1$NqBr++lz7o&T6kYZyQ8L1ee2`2cSXvOuOUZ8tg!HhC8FMF_{w zrj2wOJLQdp4hMe5Ih4>0{xyMcvFO_P(>u+*m2TwD%!mi!LK0Rj?Z@0~Qn?ibjW%-{OGj~N zf@jt57?VlE{#?6mJ>^jwpPB-Pk97TQf^q!mA+pK=Pgo;1MoskhFKp^x|L zzrWO+&U#D`xXkZ3&_hzY^(9`?0rS(h9PEQF;Tgw+oMcxl<$)B$?E@I8vSmK0TG}I( zqBxQ9@a`8Q9|{lU%uUNKlnZ~1d|L}{{uUleXAg%H?9*^6yfK%Y+i1Nzh zleg3|i=SOKQNCN9ZdWIUN#9tg8`=_Yb7C>ys>-FpCe)79@0B7Js zYwwjhJOcO#12L~+TZgvV5^dcF+4S$P`oo%u^uyTg@qz#o3dVOK6(Z9yQtz>|_2s(n z#fEnTd=THGiKy!oI5Q3D8!1uy#a2i2FF-tmJ8c|71kJC#PcNrFSnM~7vEP)nvpcM3 z2Rs+5xu?oktC4SGpHvra-hH*ZEqJ#1ZT<`cudSq#!%@iafcJ@VT$vP_stW@}p)Z9R zX9nAhN_2m-4M=p~raR&0o4olkEa4o&ddz-`oVkA^5rD;^7HS4msw=9HmTq5Q}(nFPaX6~!NI?Uo-UNC9oPa|!o9N} zk(bvB+GKn{2UU4l?eGAUl_orS+$a|loR?)VBT^e@nGNB1cs4Jtvpr%~yAm@cxw|NrIO0rNKs@81mU5%_(w#?F6XuLb9pZ7Z zkDmuvh!p-tprh?E7aTd}njIHC72L+xT9uAG~bk23IPcaK~T~B1AG{@HB z!{yNf0(o@H2}`Sm2A;k@lt2~CcI^DbzB}@ZTWUX%3Rc{R8GFF%`n+w4jcU=LBIz-Y&uO?O19td()Z3+?-O$j zF5;Mf5eT?Fb*h4uikIu()ZhPCmk^`=6|;RxGBlgf93E5=%r2Qx<$1EbJUS{wdkdn|FG5S+`*9RGPtdqDzuh0Sx<^@gDxdjiTdSLT_i8~=o&1seL{s8WmZqr0 z4RZ@E0DvRF1;JM#V*$92c>;74L5 zfm6>K;TJ7c{iNS#J_0QkYAkfgX${}ooL@Gjj!$yTa<3Jb5F1}g1#_Edc<&td4@J`h zf?xB|N8SC2Puifm6mb?h-lDwH?eP;PaXlj~)T(Ah(TwXQbMbs*9`FdAv2R?vErzR$(LO?>P*afOQ@Ml0tvd42?0#=fa^=XU%hT;b*Nd~KZoJp4|k6lu}b?yaeJ2&zAIu*cY*s|_;q zd*0tN`)zxkKjW?P`!Z)1bG3AexlvXOws(C;)BWaSf8MZDv504Wdl0TKA>BcpBP#!G z`f)ltJR1cQD}aMgqdO>(n^+|Zb#>H1S^HI4U#dA7GsS4LxlU+=Y-oG!9J(2_U-5a_ zNgocd1mblhhyh{$Y0oS3zTu8@4u<H#R{^@K&UFsEs zWzF-rZ&ro}wRRs;k$-MoW(f*{0iZ{7U(kI(JNnkq%s#n-zsoQZXTA1EtCA*;6)yrG zC2a#HAXY#XdE3?H$GRh;I#fIk6YMnag7_sUw-0VIT1Rd`n0 z(c80xV%Howg60K8b3gxIP>kUhMAQJn;?Wc$c$3wfF*%u|koFTO`vkl6ih0Oo(g7qk z@H}O>Vd{vsz|zf7H9*?0ong^J6l& zEKS7-dcT$1I*qYoyO+P{YIHQ!j8Cb#g7&VEUFsm*@;=iR|DN<3iENaQcKl z<$RqKed;Xv_=k(em)9ak{CC`@lT_1{&lcof9DIElwl5I3g7R-xNwV5!NU+=>8Ryg? z`;P;ING8{QCjFPl*A^X;E~lTrxY+2W?KNz0R-XRsUCHZBO_nU++T{$(dzVHP`t&zP zNrOgcGK=f6qW;1^00%kP=YPuV2%4nkKc4|cmc-Cp3SUhh<4bgxS!c26uV6d^-lZ{6*{O#AbI#tW1ihamhf5(dg5A+UDcTB}| zduuL_$hs3!?0>wdc-Ce<^8%m0@FnG6C5DE?gL#`k3lDS7eyt?ZF-t`aSIF5XbsoAf zE=fk+=H7%CUMqNeHK8Y`dM_}v(O2S~1M$4-GkqIJADeM02{=ix@z%L>=(~1b&DpJi z=`rR7gS6pq^g`4;-{Dfx)%^c3U}%WmyQM)U&zsb+w>)g`?C`}NOD70J_$^L9Sk*xCNcLJ9vNX%e;sQWDXTvH^5OlPI^;iCvFM1BgmtQ*hQG74qLtHK zd%kvb{y5r5vtjnHNN4+ zw`W%=!3jeW$)-dz>oNCtl|l2D4mG&9slnkn7z+8iX1(Z5nH(47n!o-@^NzJMN3`D? zl>&0H*HAP$OVkfY@2^$C?rsF6yQRCkK{^!a?(S|xy1To%bT_;Q zd_Ldt{)YEI#zoHAd#yd!TyxFs5zSVgIOsf9NzWv$x zE^qmAiro94*`mBUe)(SV+eDF9UXc`snQAQ#i?Wo9LR|y{DU65@Szw5ZcwOb2sYW|; z^g-6LZ3eH?hB0LSb;972-gbZN=E=P?YEzAri!WJz2nHZ|T1I-RGx_#YbQuqXdj=MH5Vn2ftsCXj>Io#C4!%4+K1;EhFWq#@=!%W9 zXVdeP8{wT7w<&JKqlK+_3&%#xgKU;ttbglB*?e0RoubaqvA?a7Q}@Y5W@*%

    esQpm zy&r<;&ja^12Ip0y5$rSD*Of_qe=-kn?U~X7wfr6RK-B{SR6{vBxzjs`A8 zANeuiAX8S9OYOGHa+~02`^t6jeA9(TKAM%Y(eo!L%Ja2aT{8qHN~O=Tml0>P_vyV`Hc}NR?B}D5{}+5 z3qW%oS5Pp$>UosKeH#u6O2PR>_7iy%(<1w&g=Mx+9y8?A&%9Vf@{(N4c2)gQ`1bjt z@h?-QBEUr%ddmC(=GS>fj$3oC8YYK2iv_4vU*E-V_IOK>Ejlds6h4P! zjiE7~rF`dH7HB)stoJ*_QT(Q(9$jy%orZ?l%V@Q`7g%ubhZm)lD@6Mr>MrXutd||` z7p6C9;9%q@cm)tCnwT&&pw{)f&sCqRJT5^Pm*q1`;kU8LH)GSI()lebYKiNtIHVY6yNm`^w1y0P_pnk49;OAC9rhgoE<~&1b_&&IZ&cojaHf zR?0eG8}f{o`L#zqY6Ez&>scvuc0AQa7npUf@~2c}ZSG7R_ad3FL2_lPv%Ml-Etn1> zT?Z6&pC?`4uTg6o}IO`(T#+@2fl=ofPM8JqlhFVJXi^x_S?k z=D6{^!~`(g84y^mk}2|)B}K+}D2j4lHd+i|TJaKegH=G&6td|{*!P7Ss^?*G*AI!< zrgMAX)<#Yv))>PpY-VYOGc=Fmt@*ZD*7*B^u}pBn{BclbKi_C=NekjXG}=F1JY63& z>`h*~bW^yyYrB!UguU&^u}_zkc-PT73ihjb?@itB1Bv>@hb`9&6?+`v{j8 zd9FCB*Njq_1X+z^ZRq?D`ozV3kS(|Q#{V)S>UF=QDd(13<*RMoyT~8(yV#6c0{W=aKOpUE* zV7_XiSKS&AocU2Z0JTsYX1dLe5#t4b0^iC|S4|RAyyiT})R`jwPmfLdkC7o?qV72B z*yD!=s4Xfuw*D=bTUhDzq?p#tWcCh!}yRe1j}{ z5c;V$bs81WVeFoZKmJ&c+v2!?`Q5QWTHKL_e1#NNA;A|pEAo4r(qEx`?ui@(GTxE3>|npUewp*MMl8xbh=tN1JjH{ z67M%wpki;9q&Zxf_m0}bp8#HqQW)Ceutv4%1J8QBLJ>3}G zs{|Qv)d5Wd`{+5l0tf&QiP@2I1e^kfm#}`{N{;`@8Z~YTBSfUz5I%m zthth!r!PS~@4Y9Br2>%&jPhM;7U-%?nO?%YHk=Htj zt@0b#!-DA|p4!GPa)FTOH_L-gJ>{7Gjx5^tb{r#sd&CgxYn6S0Go92c@1nEC)lE(S zZX^J{=;F`MeIv7ER|!Y7u+8p@OoAu7Z*g*o6m_f2mv+$WC{>@JT8=vNdME-_shH1E z>hpOvexT`Wf$S2UVtP~T>Ay~bhpZY3rm5@yH52;(H4~t`F=nY=0MnC6hO7Sd3DPjN zBZQFTW;60-b~{n=79|KcN$vJ(tv=(htD3{%n^*r$`R!#E^@a<-9tYESbpdd=VuSzF z5b1+;1>HDg95vrej_?Fgh`Evt%B}cE6(A~}8y8Tk3}t{oF_S;Ry$9_quX&4dTk6p( zZC0qkHAaYky^G^hNNv6$P?9s0Tx%&k_qg2@xtyE=kLo)7Q}%;u)#}svS*H&1O9d~Nljo=W)ap!qfbS-Cr@?2W^ zPd&OrBCrUMdT-{hw(G0_q13uPcbixqH)gz<6}4P`tD@EP6#iko%GsfXmkeM*#glSC?s-$D@DpHx)mh_o^+>p#`I+}Bhrs_baHSL^3keg`CGGw1TnDamI9uYHH_e>G z=Bn$L@p8lJ$EJ_mQv__yUbk@u>KNbl@ho6h=ieijh5~5u*1K-=WnfCk@6#u~jlIXG z$*5#v3mi^@gugeARukt`cLfh4liB`A?`ov3irAtIX{Yw;+BVD_PN7>AGrc998_Vk+U|Cu8SH2-S{&3mRxBA5ldXB7_a zQChFGFXG|ld=F1#s7ewhX@I_>u4SCdjyObbMhVO;>sWgAlixNsPx z{4MQ-TJD5ZslYF35CPNW>uDbpTtsDN&gPe{2v3m0D#A3e7wKAkd)?UIlieuFEmg01 z(9pG#e?VjT%1Yb<3;T~b>gNhsjB&f#srOM)O$FsBn%?R>W+lQ!I~|)M7|m@L2B%?M zDUmuJSOpMOmf7LbC0&jFbf%KK&P7&ez1qfnX$^6rPYpx?AtW1T7w7}oC)>+r3W*Gx zpYb%(o=&$qRKr}k?XO_$Ty*=7I1Ki32#}AyZ%@y0m!+KFI5j<7d4QESmI-`*u0FfN zKiJ=Yd9tjfrZ~R7z#2ziHirWIZ3bD7Gk4q71ij1WMLv^;$(Ifo?$fhCr9QC^n=sqILqqM6Z#M=rgZTrbDjh4!H6X ztw576F;|B;?3_$C2q+_BwDS6}&md!QUBRCyydAyH+frYqGde zEp%0E6@2mECsWHuSR=obe{8Fv+&<lmE*xfvn{?_9W*!k!I^Pl@PGOaNY>=3;hY;Kj-P(>{zsE+ zHCe~Q)FPZDCaXYug^@SaVw*)qcIe4=WUSu}?dn)H;)m7(4WK1E1595kIH364;G?2& zB7wfiDVFbx@d-8^j+W7MBv}uu%VIDP5X(eR)YBq zetg#gIsYMdG*fekglF|f=Z#x~qHN=`u}b^dt_7MPq@EpnN_H0NALS1RKR*3@DH6hQ zm%SpYv6xj$WpFN1HCMzmN7#2sbz0jZwN1s*?|tV@l`t!tCVAbbY98UFzG+M~dP7hzf2>4QKo9qe!sS{7!Pn3~aX*4(__H5;F9|Z90bzDBo-p8M1nkZ4$Y6M5^Ad0Y$%s8LaE-Q+4V@e7wkC`kPW`2t z+pJ}gUpM$#7~)6(KJv9(_`gpDFmmGj>qdHsOtz#h`Ac-C25%4|)-W{Tn_`o{Ljhb= zudEz);uv+Nacl7YxA3nt#<+d4p%p1OWwF7G&D#OuZRz@ZmPNZ8E^@&noLrYiWrc)(6P26b^4Rq~o%L#rb!AjwsORgK51xUFCR=0;d zmk*$rNQyepgLHcn$TUa?eWxmLr8^70zp)0^KDp&S%E*$Pl<>5-9XChK8-Kd!FUI9g zl*vY&uGk=SloWW;woP+em(#pU%Igd9<$^e*7`n~U_H!~jBD9f~idEa@VLWWg^HG$xN#lX>GONPMLMb2i9`I^6 zqt9Atli`2jsypD3u6qf%xQY~g0J4oo&^yFK1x!&GIjgL1@tCGG4cqKabLaieUT`Lq zZ;1xTHUB>RAehtESkN_0F@E|=rIGP$kcpZ5IxuSq{Jnjg;6}Pz`)hr)!3->SbQ$&B~NzfZdjmW0}Uy;X+j%Bl*x4KCf&9t^_b8;rcij-H$;vn zswt24O8_Nl;1snBp5 zi8du=Hx7x9?YLc7O1{(rEa_UFmbS!gq(>(oDzH}5F?lP0F)l0qIP6=@pL9`h`S6}@ zm%mPjrWOcQZgra8SSzeZVr5}3O!s_elrn?G$HFAbi%N`Odp~B zTD5YxuU3Ilp{72z%zw__avj_x z=hKuG>&6(KfP}ms??jfy{UelL_AP$ge47$PT}O00p-2zwwS8e(W7NwbhNS|&n>ZLb z9>4)rW9Q{kO&Cj+q5+4^v+0E{xI!u+xZ>QToat_c_Ju5)T3=(&kZTl01EsCmjLJ(dqG|G>SID>s`D7fMfat|QTCJ4*3&cnB9141aBFoU-yo=x3Mv+&g8@^6P5@89?EfZzuRt_r|q zOsx=8t>YeE0PY_!un^&I9qkmd)o`T6db2yx7T`}cZV+sv5jHq8h9mslLRn%W(YrAb z?J}=X!i;o4khmZ+a=sahU&p8zFTKJCivuxI&_*=G=oH!j<38esz1g+`Z32 zSjW=D$C{p1-@cL?_I!2Jqew!*kD32r2ky&>xPOAmv-W2Bau%z9ylFqS61DJVdU;vk zJd;fif_mFkI5C}|s$d!^4H5QoXKB9aUU;hdrBCm`q=CM>fy!}Mx0uPmqtL?sET>9F z5cUsqy?s}?PgQeH#?BB*KH2KUMwLgut*rxD#hf4z7hJAm z2$DED7^V2;kdx=nR4Rr(;NE~W;Hn_@z2gfgrFSH&m=7OI6qz0Vmpb!{qugpBPF-lh zHk-z$gDkWc-^GOf3qZ1N0$3ne;9i%`sWsiVdx_@JcYOlb44-9vpw0{7vQ2vbbXh99 z$|;i*sbbFNS$(2iK=MCIV{GHHfqXmZd>x1~+QQ@LuO|vk(B75~_;w*#$BoV*D_&@B z`7`&%>842h`}fbUN^(FCNDf}afJCnoGDOqJ2vWhLl$8ZWI>sFGxsre*h3vi*1z9-# z#{Kaleu$>euCww2VJzx}M9stVpiok=P?dlu zQ#Ji)CG%tJSW}Hc<7z3l0RB_WDCNqhvnOo$LWkfL&|&4p?B2Mu^1&|zw5%DiufnB_ z<0gbeY1zTS99~xqalfC+gh`9~9@MR|tmP8tyP->WLrl|(;vG=7vyEKO!b3=t^ znK1d5C-qY>cx8Hi2CayWhSp12QQd1djg(4$dwC$n{lh90r|`I)e2%tE-Bl-qSDc{+ zpGKZm*?v>HQe~sNl5#oAHJk#`qE2|46XJuGV@s&&oDW0F2qab2-#$1{%UYO4-~{2x zl+O3_w+B;tdy=&4gQ)}KF~gV2&$Th9E-b#gT|o}b-B6B)E<8=DB|P?b94Bb&(-91c zGEeSK&L0`jdzj>u*DEkEO#FQ0M8dpiY-;D1=>)W?T& z)`oS6Hsmz##WNu9DegO@5|N?6mXKh|gGsgxkn-uXLs)8z>BzSk2ix+b%N-T2{qtB7F!Eh*C200Wx{1%U z75y%*%|v;3cvp3zPv4{Ro7hM=GcD_xT`kR))&xbXWi*l9RqJ%lB9K?5^5LOgBR36su-9^QTnw-&HnV|=wb}R^;`=IJ* z(SQ38+q*x>0X1c!U;Ovt2lK>+dP`e)8QIcAr+2u8xQtZ69NL3oGM6f83AaX1H5S-s2a=4o_kWrr93aB7fb>Ws#NW2+=&TiNJ6T<} z?P&1VE3Eb_2#QOcgj-v-gQCJpnK+=wp%ip=B~$44mXY}-4L4rx0(MaT?EuZ|hBrM0 zu;1=8w0WZ$!xZR=tXJ4a%KY0Fv~T|vX(b~3sl5$5E@Qf-&q9`O8>S56c0KWaJlGV0ajw>-=Cv>D_{FOch1 z&?g5xXvm(9Ywyv1t)^pGgk~bI?v=LKHT@h_%4D4m>!V>-V|bqENa$|7Dn`r6`qM}e z@9o5CdyPfA>ef@Ztl0;(T&!?05Lk20+18w-FYLCD5n(3d+i2HE5RuRtk5Lji()x!*(AK}Bvy3s1Spi1;wIA1~ceHmNcg)e$1&RbuhUCdP9GYmyL z%^OaImlWjX)+(^0{7yxR32d{~PiqG5-|8mmWxWFswF4I;DX5D-^Vfo(34ajcQnkof-Rf~<_p;KfXI z@Q1!$+d?DB#TmuPj8o;tfRR2D$mOq}wNU;im0u-}dc3xIH4iS_5%;F}M|@Z(9*lvX zFcQk}X656}b}L;#WHeJvo9r*QX)Fa^-z(xg{{DfxoXD4mQ`v^WxIsXkv6t;89n08X zG-PHeQSXz0E=grRb1>EVb?+oz({XB-96wj?6*TB*aTfC^RyVS2<7ow9=QWFB)t2e*Ul#;5uDi_)OK?{Q2vy^d)1PgF z+tgfyKkOeFQ%!o-3f5L!7Q{smhi+%9mCwZFr$jFOAbTITw}Fp3W3{M=n2EdL%yf{R z?I07Jk;_DFomDV9E7|&8z1l!hP_LRh_#(yUUi!dE=$oKpc_B`uQ#x?aYNghR zA>a#9wu)m0oSD%dz(E3XruNsg0>|mJ65MO$v-Q*PW!=rJs5XV4x_CZo%w9c@`q;BP*Ywn73JlIM8Y^qo@ zn%AX{YWsY!tc%R8ca)ERm7aG8ZPb;_p?p2q7_N4i%)(CNama6*7dX^Vr9(Mli$i_w zp|&!-McHO^)f#uX;S;Kq!VHRgs{^mpv)zwlq-!2*Qiz-6Y6Y2}??62yO*V^})D(2j zKj=o3bk*BA6-&Q+jmezue@LFwd#G`fJjK8q4_H*&x`2G)FTN!qe?0*AzJ%I=&{eZ8$a|<_Nz9 za?Q!b4j%CLK|}%)>d}4Mt0CttVRi_?8XUw_e9QTIOv~rZ>p^yB)dE9Xw`Q4l#})jq zx5NTbT0)#LVo-(Q(m)`w2K^RH(Mk|gL54k?ISwb^hr(Qk#gX*>Eu#uV_~=1}e=xPY z#Mwg@{p9(wv1xbNg~Q_%dQ*~(6xV08J+W9xNcn8ozyix*BD4hRAg7T%wW`gJ@ac^j zi=C=zhzRHTm?zXih%?lZg5IDB+7+)KKRjE*tYGDe9fr*UzCCbea_Su$dz#4|1%ubz zbdh46J>hYZL>3wRG>-uV?gz5w7N#H-V&R6_s~z5N$rRIJ9H{wi}cFhl`W7U-9) z`$B80Jb9KDX$jUYLx*%$d z^k`o*N%L1U%_{zf87zX*d(aX{R-aNDY}+Z5wE?mrA_CVRT<#Ca1CUQsWxVh!Z)X zrT1u4oys?TT1rc}?@Ly+r|=;TMfp?X72N7|r|X0g%%{_YT7ekEfpE!Cre!(HDwYwh zP|z%Q=XqdUy{%X+i+SfI`Y&Csi1D|={H)y!3IN5eF{VYO;KgMr5}m$Q&A=ar26opu zsM?lKUp-}ay0#>a`rqm^fhTYc6}aFz?=R32W(~=3RFh}tuu#U;#)*w;W*Y34$vrP| z1Te6sOZ_R7aMFXh!FXyS6y0hEA@!~(v_jJ^Ix3S7rQS>87HL!UbDFpG+5cnW(1?UP zATRC{(T~u20VXc&C~j1zNkC5kOp%NxN~{yPY|~FVe-CuEIMt*cTqXnRR?TPzQv4AH z_(quE_hh~({8)s3>Hn9BtI$_2bRpP=x4}3)#@qnGwBw^~uVxu3!H&a~N+rfQo`Iwn zsA))Msjdt5cZue+^Gw*kQxIAh6d1Z(&`@pEC;ROKoxCd$BZFB>& z*kHYGPN$5Po;|sxNLgm>IL^7Hy7U9U1#Fm(ABw=i3kfnt1_65pfrR8x{0~*Y8n{4# zIY#ebo$>!)zJ-iI{lbBgbBf>9NcpbQ^k3*YkQ3mO6hV^Te3MIsi;>EYgW`K#!Pj3P z$)9Q+?yA7`QgEYT+Um?S1M}Z1J|IWa11=DSsqTkj-3zq(|JW{;jsHK}RoDOl;`3}a zicKiRcSc$S4vvC^#Vq|z$a?%%@#S9YsjTK&dLeq)gC3hiA%3m$#j8N4o#-wl01K9g z^7G0%J9`#H#sfOq)kV>;2m2o^d0CL)OZ4w3s{=Yhmv{H43q!c5Z6NJn1&$>NhiYSD zZbAUE#mS6o0dT;5dl{`!z6`Sn?TR&E5FXJ!XQaoM@n%0;?(}i?Yj5St|86fhGOpGA zd2N`#MN`|^H(Eg0*uZr1z3Y*@JnA28cn4i@5iUv0(^b>+Ps7~|kN7gJDbOeV{yNWoN zG-hNU22$zUXyCHDjw~Ry;hfXS3&07SFI3T_n^Yc>4SP+Vn?8Y7>dB=yqb9>!yE7(l><~|f(=4x-P1Lh7gme>vE@EF$pZ_Mw3ho%L$JG8%1^Sl4p zxy)^)1QEjD0SBYma{Dzu#{Sx?5dXe8~H6Ix9KadX!?(JQ!>n&j&*V&kb54REO zxhwnXfyael2j*BvaIP3uJkmnOhf`+UduO3jg#vQ4A7yutzRjLi(4=t;*`mK5isS^d zA;)FN)6T=kJN@^{Ssw_Z-N3Df7o@}3(y|_Xy)MwT0IJtK>l2UkZI?xjl%st*jD{ean-^=h zXea@nr;LR0zX%4bamA({Xlk<(zvO?~?Hy{!TM+%P5^9O@@t7Z|tv(3DIw47~tmVY^ zPUZZlRj9SKEwjDXZ`57Oz&%5FnleY^T0cjXsCC_3HNG)EOc}4^^tPBv=`icdfzq7l z!>@eDt4Ss$ksvry1q+yKd9ZPC-LVn#NDsu6`=@5!6Ce(I_;i`!ArARFZuJu|l^luu z3P-z!)h`$?2xBf{{QHT*GD1HMN?%f zMiw+^Qmz%|d!wG*0OJx5`Bfrs3Wsz;-QdP|O?697}DUR%1t}`W23=u1Mm#iJ8*9Kbl8z!R$FC-8)sJ3Ha< zgvn$^I<*2ne-1Q<(JOPlK{o^DCUsH4xlgem88Ok;9Z_le2lI z;QiN-dWHzMhpboiviYTEpIC{IP=5H*EClzuI0U5NJr8s&t@W*4Y@zmFq6%9f-*Ww2 zx{t^B0B!Ao6xPE{)&WLjsB;GyRiU1j52yiQ-8~-n%aNg$ry^!nvb+`A-si!D#YyV(8n<_@& z3BAXDwr%M&dBwE5aR^$2wI{6xY(!j?r2t14 z^2h_s$COI{IBTA4B?pfvtf>M)0U!m=AVqJIIVJaDJvUGR+{`^{aHO;i8WtYTnqq^8 z*g?NNIEReeuipJmZM3uDDuc`Yl=uBJ!LzE!-529LwV`AFSE2H{WjOtLy%IOjEiC42 zPqn-~KX2EY!zRsf2OHy&3nwCc9^HGI$d{wD2$1>|!HYzP%J4A+6Os%0C^dn>?GALX zE0N+Fl7djX)~6lum0R0~me#Ve`**JfjIXgG5-e&xmBHa9LMJ)un*r#3BH|Wj)*DWLhVv6Nut=Y@xHjz)2iYg$)O)8 z(TQs%#b$ii_M^mZ3px)@O==jeDXsCEbrnMkOOKB*72v3TUob$C{d9ivxpOI;EaF^% zzyP{n)RSOn_)`xBI`HTB!hF&xJC{aker2rL)%OjHTkbYP7q^W@fN^KQgYESZEx|?C zsf{n|IR2=LSr?}-Rsf#k|NQ{;p3Z=*c=&xnZ#Yjd!&}}3_TA2=NU`U`-7d@cY}s0~&4AWcl0jD;7BU4*D}c086qW z?o+xg^UNfvO3JgZ*ji-hPjNi~AIj?~&FxPw(Rv(VBWZv^80g{jnY>-wEu3sbdPTqN zGgRatkW3scaAZ=kF|&aNdf6{m%SV7s-e9wd83@`P{>6EnRu#y495P+@bTKBXNW&hF z@q>I5rmx+2iQb6YToVj}(a-081sr%;1mTQ8oOmSpaP~1mYcmvLd?|i#ohIHRHWTaVrjRj z;DbMqS5uv!)pb(GBnRG=OI*dvmLV2{Cw3|_xRDds^L(MpPi{2IfTBk>&-DT6P)^6d z$WU*_2!tOfdvhh9;N1$iVg8oK*<^dqi`mDe+f2pI5;EOS=XPjvFxDRPkXdHZKKu%3 zTtzVBH~f44-3-^`N&oz0USqZU&g~`Ri69yUOo_>8c9(bl8I_I{i5>7`1ENiu-?M^F z2l^(lL9IDF7E{)2@z6#g-w~Gk^}W0U&x4q<)gh}G7(_H!{$kya*YyU$N@V#x3k)qH zaC_W0ag1UcXXh}X{}q-EWbbSf%~{#sgR4oeP1I^kxt%hWVo95!9+o3Igj zCU*R7YlI$|IP0=Bq#lbkSm$!ZRbcN*o-IgTyWe(~>iWJs&4Q4RrYjl|ltFNYmP3IM zN!7FWE4)OaG%+P5I3hAyyADv6%PdskqO zQ4e+zcPR080(3M%gc~$3pcD@)m@N-K_B4LFNcc?J^;-S-u)y@imwZ|*o%b%NeS&$- zy0j}Uq32Nd-T04rl$JdS zYx~Mq9^nMNx-g57YessJoTors4&*~@M6C?QOjkySFlP+%vIX}vFU-veQ$qF;;()+z zxLvX`<5(15v)HwIFfhuoC);_LCMsTxFZN}^O-^bCbc>FW+R1g&vzO0Narq+=Vf!0H z;0Fj@6TKG*6Pc*-DKbzYu1`S%SCkY{>60ARq0vtTGlg2&Sj%&&&TBmlX$61KIuq{-&-1C`k9s_PPB7vope}@a!sbANkV{~kgUPo&{ZTH zq_*<_S4CS$@Z%~r`aXX1y!aEg5!Ta1-+y==t>yXIs=jXi94b`w?JYt9xB|<#wu%(R zaRktZto$$bdBC~(q_sZfE*limR-AL^*8LrdavchX-FRECdx$M5<)w7hcKUJfSA;;E z!CUPoPI}Scz8Pz^bRXaIW6Vq$8_Jf(t7s*MMCzRxpWpTmQw1AYWW>exXCA1Hpzi_$ItP7346 z0fvjmwtckL8=&vHJmrw85ts3dC|o3Wx)|`zyQEnGy1iJKFP9HcSPtXhw(#YO8+&!)z}@t`k7HNcJDO-B8NPp@sJ!aa>*Tav#1g?#+X$SVBLV8&#R@?tiCau=Mzz*}ebE=k4=3fclT{sQNW{!LBC_Zik6`_fhxwKIU@qUcrIt zI_a-|VWkqynBf_nRI9slc+UCy-QHH9xr2O8IgqUgmsobrW*9WGt-hEPmbu|#1x;#1 zDUWsMq9Jj*g6_{m7o4}U==KK?HS#DzXAS%OI-X|EQ*f}zN{Qj>r#%rY0^U!jTkoM*+CjU3%U{@Zpx-w+PEH`F09?{h1d$`&jk(gUS{udKw6YtxJ?|u>oS^+9P>*KCy+MFI7JhJ(M38Bi zgy?0-F7$_ItrV9QPt`l=BP}UFV?twe!0VMwmsIa+Y@58a(yH0df1jtLC5E*bcWT!2 zMX+zCM4pgkU>*N{*-E{Eu7`3(scUE!qyV%4%VZwDdel_hex?lwF0_^J0!geS%wcy9 z6ztC0la^g=Eu`htZd~|Bo|NS!R7+UkTPyk9FXKzhS}l=1V-Ib|FVh}WR;#3EAR3=c zu1oe4)zR5vKsB@m1x)LFX$fgR^XP{St%m_SKS`DyZ{peAAG(8B?tRZ;za)|#_61NN zZLt5@*q!l@-=A=qn5yV(EXZR}RhEJ782qtg3;pLkKt0t3+sBtpTIsPoYCggTDV;G8 zV$i8GV8$Z7tfc@p@`&L>?9~Dvp;dtx;C=u~bl7&`DP#y5N&crM-{cN9<|2yOP&W3$ zBUnelvs|bAIL!06JXeqWt=CqKjVo%m=X#;Bw2II6txHag!Vo!YhV9{csLY38NY*wa z_$1x&h5?j`2zJ@S*FVpiTNv7mG{w}oESfgCJ?Xf;%u@lKOukLJ;9mgvVgyDu5CK7= zXl=QpQ7*xN}zJ!zBwYGy5UmT&p`4APG}(kugdls7@$BXM>@e(ww1 zguxcvxzi%yGSfhuaO3*kgz8^M4C_o{4}PhyQ|%60oKfjaMn=-^KcB2H##I5sqo-?q z(+(ibUkvr`LC|gm0&;HOx3Hw&>5viyi}ETZs;-$je8EK78zdDo?T)NQ!;b%6nnY_# zk2OD(utfQaM=pyizRQvJ?v<>s?o3p|g$0TKe9g8@{*PtU^>2AA;_c{F?< zZOn#JgWW-a<6K%OrRHL(ZGurz>IYPX3f$fvHrC7EiimqMK)L5J=}7lY2dWTD1``vKt-+sU@h#D0GU-YZ2JLQLSf4qMkUA~vP*Uk3 zGb@rtv7dlz3=GOM0P}lZu)D(``?;%Z3%~{Xg@@o3gg`+|f&IpRu2{4^_1oMtS5C%> zz<4SAdMYm<|K|;|wIur_q6_LI_Pz#lzskbVa=ZA{Tg8n6lQ1m%3%=(-7^TPca|BD3Ng9eODdedbC;gy zQ%9OZKV2{5-79#E5iY0bMHCikKumqnm>HPu zv0_?}FaHwl`Hw<(fdi|)lbC@ws3H03!fX&&dUP3%^rpM9CiTHA`Mk>1N@krY?QRg$ z`ppN)LJ1XPYhe~9S9vmqrgR%bgp(L%GZ_HD=bE(s9SGWxTR`@yn-T!6HH-11 zyPFiW*}Q(;{aGxzrM|CwyVw91O?lHmFaD?2(|)q}ENvE@O;Dhz#jF`gsPy3>PP<}>ZW*(N-ILxl4A#wN8(R5boXH(=Aa|pkd~^jGw@f%6NDR*Wx_hF7%g<9A zb5)@jdRd`0n0WZIJqmgzsK)%GcU{%-=DQ`N{)F$XM#n;;Wa%#bMR*?`|TLL9|oo5GgPPqbD&M8l1Z|G60i3 zvrj#R2GNq{b0(Us1M3Ym{!3R}z>VLPKla8U5ET49Xy%CMM86|)#@bm!M272 zj7gwqVQbobbW&sW(9U%FSMLp7sg(RI2C1VybM41#zUyaBPAvO*>!PExDxaXVY>zmb@-OLO&H5%FQcxkqKcRJr%;^*f?b6 z2ytlD3G9W7jIN+DJ4L8rC59J%#j)R|bh)ID;v)~C8f*gf>z3r!N}iP*h_Y*6d1ub+ zR+7_sz3GR|++-}Jcreq0^h!~8;{l}_b9qIVdPFEGaobLNI~^eHXt>2b#*m`qDGzOo z=EonJ7b~t$pNv%l4z(YSg~Fs=);t`&1|zm-U}Cm%Cl;aaRG*Lr656eD{Vu1LNee^^ z3F>*jGVH|bWnUfprc#d)!~fkjt&h||=#@hxbYSJgn8!eXwFyqjR;%#XegB>XSEG-| zk#2u8_9dk9)D_c!a5wpUR_}h}hN2c)f3U}zTT>g;IQQK#cIlKx0W~x`>bF%sz(Rfq z>dR}M$p8e?Uoq$_{~bjK`eaZLf4xPuk#@1(5xzAF)P&z{;Lfg1H-;&!Z=%eW*nD{9 zuO^ax<{wGQea}>Xi9b{5%=9bv#5*zKiT&$>mXK$RxKpNV3RI7-}rhcb>cFpQ?>fx~eE~V`9>*tlpIf&0e!9r~)vR>fX*x@3)1!tg+ z0}LZw`k5*883mlVp@cLV$WX`XP%L%P-I=t-Xc$?ODLo2J4AwCtak$=^ZcDioaou&V z<=1XN0X2gPf|eIT0lotX`OuTAG_&XFUu~`D^1!(|4;O8*6g0Vgl;C$^V_sg_zDVd~ zu*R}*#p#GGt&&nbGoJ1>v_dpBxaZq4v~3P9y!T$ZJODFojU0V*?-BK)+j@%D-SFt_ z#>y(!$C(Mx5SWR#GK)o1>aC5MlBAKCjwRx z#}7$+*%J#lm$7%+m%ALkZhY(=(LtT5W#a&KZK}LL5!Kp-TWp1>1c>IIw;UgE$+M&cdFljUIQ32%FDR?GAGFZzi}9Gt|2>z88&mUWITFY5yzbRosN<9K z&K$HMuh@EOri{|v8E|y7h8GEQtN^unXJ=-gOtBZ=+OC?!rU~*0bg+P3Ei(l)mT|0q z1VBv`YBU>9_#cXa?m?MZJ_N^Ke+C_9Q~qri#xNgFI>3(F!mHBKbdWDaO4dtMRFie* z{*olT>aB7IM!Dvw74$yFkt}gxscrBM@mPri=5X)86Q%ia%a88$$*L2v%5P?8CYkkj ztfZNdDe8`BapU5N0&;7jAHDP!Zy`8w>;ofHnzB&cKMm@A=}neZ&bb!MFo*2bNaEwM zdM^TFo^_}WyFNfcsM~Lm4{JX!zdcY%%h(LtkOmJ^V31$WLSGC~Tv%&lW-OIc->rN` zWAUU6?Qnx1!S+;mI`{moT7RluNbMZe;J1So--@_<7To~B)2%Wwxm4UkHod|u;w-9; zSd$Tppvl+SqR2ILy|c>P3M{J~UQ7(fV(7u9B8Ad}x>9^m;U%-Xr z3A~5u(g5A90g?8(UE(orv*0(9iB6l7La-HT%DdA~Q)Su-NXHnCs=curHe4R>^2#V1 z)`il`a!Lm=pbtig+a&HaFyAa?nYX=L%O?DBqXG}q`SL0UwHkUbDh5tE_e2snJ4c1 zGhzCZKuu$Mm=gXqL3f~eu`3b9p1p6bnBE8F+E!ecTK;1_O3b=e(;gl|a-B@58c$ms z1^uI~18aC%>618^!qB4SmuPED^#|H<3Mb%9C2=5ZmzNro4@>joX|(Z(?;f)HtC_W7 z0=fEN^pYssn(KyNS6FY3Wk=NBit070MbuMy>>J(B_zc9Z6{)wy-6L(P7uL(EA~8~C zF8!LhxPbtM92OgX{g=s+3-qpjkm9M7j9Q;edeTWrKN3Sg_*W!=@eK5Ih&v2UCIaN= z@Oo4OM*7&?j_v-uHF=I9B0jjp@cJrucU}?+XHO-<%f5xgD{{F18g@Le1qQWRI)jGf zW=p4@fQ?BVT^-1aoHFd_WEWj%(>=9uWkRPi#{65g#^mf@$f9LO7DNTAxHJRfk~xh zljLkEeZXXx&T4`BHiZe}RUH~{$xRMH&3Gy?L7L&%dl9S$TzvLjJ|8Fybu#CoL{C#FU&?FlBx$pUwZP6)iJr2 zkBr-jdQ1&sJ48vWvuk2Zz2_Jk1!cAuovgPz)Z9={mG-KIca$j~Wnsl~i*<65JWhoi zuycxqGM`48iyh3?CF)YOG}V^)yiT~&8cD0Pk7ZH&i64jVq!%}@Gcy70F3!35o8BNO zF}=fkGjh|6g6%#9eZBz$s=GJfz-;u$vBx<{5N&|MOt*_eZacTq|U z!1uqz5Q;4F1veod2W$xdB=`B@H*b8rZGd}GTsdk0jfnALzdn;5=jRZMqd4F^0v=i? z&m1zTqFv~aLg^z6-zPGcOvfC0;j>W!UEz{s%(YTUQU}iq0_pfyWznFQwpr8#Xu<`l zbK(3bQeNL;tue4Pd~vojzSOqzmGPKO(8tG9nf#E+VokYVdUNMm&V+za25b@Xg(zgL zVmYAal{yzIk1VEV&8Bxu((y#k?RZO_7TH{eT3c!A8-NkxI+63LoopZuTbU!)0ug%G z6?0G1?c7XV9U0$E2DbcOD}tCd{=x94pnB^=>bTK6^yB<;mdX*zS$ODDVWbO)6 zh``V?*Q$wL!1OlBv))yRl_pJIr1zwUm6?w46Rbr7y#J)sPQ1s6FFpA}&Ie)D{*S%i zMFTU=izI6M8z`A4jKn$=K+g0}%I>r^qVB=V5e}NwJrYdClYd_yf8s^BrJG{2?J(Hb zsTAw}YHJx+JDpSdRXq4>_|V67w)8DVovo}ZmF6024T<|j^mpgk_CjIJfQC~M`GJrQ zl7>q;SqPL?vV@@HzsJ9~ipCb>;LUCrw32k4=4xZEu{^ zqVp!e?m-Va~Fzh(CKE=NsUTfiEfX5rpqjI8oXUH zKM?c~?7#$C`e%f|+mI&-;p~239Jm%D0_~!B+eS|89^v$fpURjKNLzUk#C9)TA4-t( z0-JhY_w^p!&#szXgqXo_7@~in0$AIC3NOC%Y~sJEJ2dmVURFR{WYCZyLn>$Z?7RRB zG(;JEs|0ju-Z&vl>I19ehr!H-OhT{0?be(Ugim%IeYffvK_okcn?o3gMoT69OTZMo zmD9F5#?(K+2=F$ISp7-`XbVgO-NhW+GmREC9JeS3oG1{l(#VsB>zBqjQmV_~A61ru zBixFfi%A_p{bmO3R*8dv;JDJ6Qy8>g1my*v8`z@td=6(C@66WHMFs{=dACwVS_4UE zc3RocJT{AX<5nw=er*7c$gZk4%@#vOf~v2~^e)|b3ZQ^aVs>bZ&p*EuxgTrWCj@h) zETW6#mH_sH$>|u>XJ6vMUZBEw$Qxi5;ZO=TM+p2x+TpuEoS2kysP@rtbb#X0T5NyBLd zYAc%O0fcZ#Gz`ccljkvXHPBS1Khx0 zEiuZ^E9?jI2Tjo4)?28>20E0PN^c@{m0=i6 z-3&|@YL&|U=|4Vi&o-U2393CmzzrB5>7_PZS?5*t-&l$Fi#L~0BYMbHV@Pg<0-jd@ z9?7XyYc?at(A4jQd(OwjS)d%gGr<3nX(n5_84aVO z@MzRNbX&?Fa7T<$;(n#>A$h<)aHs=Ebs+M}pfJsq<-%%~q(t=+X}({oSB1)rPc5Fn z4C_!K%7`68i!-^PSF7L=Nj@Nbc)isuQ|L_+rPXl3ijY>RI576F*$*@^heB=Z7Nf`n z2{dZmj|%&{rU)~z>wWYC;%rsvmBNPO0=iH7$)OAFPTW@$Gwh5x-cOY=lP(p*4x(e+ z<--f+niD4kG-P!)?G(;{KHXPe#ph^WHJLmpMnpO~Q|i`q{#CyZZ=rb<)8sPdGM^&I zAD`_0v`pw!F57rt#gn$ju7`TS8%q{krbV1s2k*lQ{}^NcQ}B^B7h**%&)E0wpnf27 zoKoK-r-^XMQatxvN~j&z;&XOC*d9^vdAl^9T0V$d4~?N@w+_2SnrFH|ofzlI-GR<> za~4QLbRO(qMupWx#d)Q`{fdAQZ}aONs9;p~v9sD0p zJAS(2tGy;+59_c-cMNOrf9!>OyOf zl>PN3S|hyOe*$o5yI2LU!$2f?;4MW$EvSt1GKmXPznz8LJwSqPM2#G+LHT2ZTm|}} zZ6_S$K4U zBbJ~KGM&+?w6!x@OJ#%8rL8q?&vh#0fY-Bzh$hkunD|)R>tQo1h3Nohua7}UC8zfl zTi4|3)n}YH4a)A-Guyw;1m+RE+4SLye{ zUz*8%qm#69QSLM*kOJZH-H?1c#_@nMu#PCw6iT-q*+b@GNPO17U3D>J-dSV_IFNWB ziMo}Of``?hM}?euJ_p-9q4+A8q1VfbK)u7%AO3Q37k71*zVK_{Wc0(4?)>}DvcUY) zJT3Dv-1Pg~;UOTM-m0dP_1fz0{(C*WdPGz270r1Se~ndW`$SgU0=2sE!ztz4$*KUc zHJ{L5I{rT#NQwxXx;ep7b zdAop~uRQJ%16t`bWHuu;xV!Kv%(_hKh#HBK_C!|etN$jwfF5_ctw#P;>6%((BlR!S zKhtrObD#W`|E}qm_LSwQ{r!VMs9EW@)!WKV({uH%a{mi)vcoj?UB($AGKSN}C)od0 zQ|P@9Xa89xn?x|+3M{O7?)fx8JVkKOJCfj`HO-IyjXNP20l*!s_RX7Ge-&nROp?AH zDl|20M;XZPa10 za@V;lvyL(0?AZFWR7`yV#oqZPOPuI~Fuov*#TVwZ+3%$jY^d?GyYUE)!C%7ThXzl7 zH@xoLJ(ALwx&pdU%#u#;F-i6gui~e6dni9|pB|hV)ZERG7b%etI#_EC=59#WGPX_a zgiaUw%uw?OA$51Sa6nNhb$SFiT`7u9AI^o(Pv~7!H@TBbG$bTjNQO2tGr-SLzz(d@ zIHl%#b!RHjk|CyX+KW;m?JqJ#r#CkH5B}h(+BlW$e!W-)@{~~PatGI}n0M0QkdzoM zF_aieUS(hnZ(4Cu(Z&*fLBZ~4EsGexoy-DM4$Z*Snt`NaRnw8Si;eq6vpdEi8;|hd z`0?U|X^)EfHad_T7%gB#m=*M5A?Bt-Szmxuc^B)q&gzdSU{6F??$kx7!2lVF@QKjZ zcJf^kIyL)f6cN{Kw0tlb=3=y;d8w5Wy2<-z0ME;>k_7Mnjtrw+)ji=VNmc0!-&V$hJDw6lV^9 zc<^Tj9{L8Y^IC7Y#alkXCE$TlpA8RM&@G8f>g_SCL^a>Zm=9rXt$Qj(`+x(wO%zPO zYgEh>B!Pl$&w9F9?0l-rYG4k4o}c6R4z^&=!{A{5*zWfXMX~>%O{Vi8Wmm)tU;

    j#E!8a{;^ic**L3%PFs%{p91&%QJl)>04h zN8I$P;|k#xBlgR@iKaHhglu}5(EQji?bL>(x^Gt@V-NIQwq^cbn8TYtr8mzMmDB94 zSk9*QF16REXZ`u{;Sl!w-y`j`LyUO)l@b~7(l56v>sTR4o`pSJCx+uLecDKvqv2V| znM&%&11ydzgY;T@@n-Nmh2uNtlkD)hn`gDt&x)FZ2u9CGs9tqBnu*tlgkze(_Q$JmzD#u9C(9f#LS+R^Ehtf&zx*4mE9 zpG+BWFc^xyI?ChKFC|;VWpNr^4bL}>a{U&Gk=}YX>T8aiih4}{{w#=nYAkPEZ`Ag# zUM0D#SZm{9;4mq>LJh>s68M z*iqk~@IgO=T|hczk~;r^Be*czTNC*4^LuB;go(Nzr0}I6_DQ9r9ZQNK;=q(zR~33! z*uVhy;Qm$rjEc<%1A?>7CBa4D;@_7AwFt~DUn+MX0!8+qI;nTKGY*Jy>S-_5tAWyAlG!Dv{Qs6yQ5o~A7iFU zj#TF`RjE;l2;ndXv#x5R)~p?$#8|OhNYI?J1dgK!X@91vb>3fwdkX%qm877{U}-~R z6Te2W`*mwAH*s)r4RiXN+9Ri8F`Zzm6y+1mvt;7)pVi7n%=v4WLce)Lkx%V>P5f({ zmO^T|^QD7-+d-c$LLV|!wa~QWL7#MoHOK*HF~Ucp#* z)8SQPr)9O3t}nO~yKH&yFh^V>dWbOvzQPO5_Zv;9jfB5ONz;hSe7yRUH$EvRt%4F| z@d+{&?g+qKDpb&;Pj3xJe;X4xe3QrPU!9HvjA;Fwbo{?vmk*SiPV>%7)Ao}g2{U9J zVrCgnhNK6`Dz`GZxQBN9pR2{YN&FHxRRy|-bzwF%l)y* z8C#d;C&a5l+a$ng-Cnss=7NOz+u=*;MmP0iY!YLy6>~m5&s2Vhp%}6|<$jMmr*p)X z4>YAZ7oTl#b|->9yU+aq==(#3?C1-~{Th-->#=y1*?QkOlFC3;%Sr*iK>*`4t}Dpl z71S`?ZwGgC{bRj8_F&@Iffdf(haF>? z3L{<{3~gc%aTzVCoh!Zl1mtdeyKg|<5re0u441m3T}51eq{CNxiTd-R_09bT?u7O4 zccr|Ozl@wr@njJ>V4WF;>S|x*(*_FhBui*RUFB=pasB1!=Cs~3ONEhg6`fM0$o2OD$*NF;o&yz3VwuM4+ zH-K?5ktLgmarqW8G{}Hn)4nEV{+$UTwB5mWU(={;=YmZFVLk+?cO8tYafn&-iuWR| zYWzcjp4hLmvphPv>3Ou*N(iRMR<>%Tr7EpklA~&@mm?#L5v`*rLTB!6UmeLU@63%$ zqYXAQN$Y%>k=J1f{aMwH4;TBi3y7<8L)Wu>eIC)G&ggrSceZDXYaFj!xE<*Gpczbd z&g97WCR_ZYdHQ(P=ND^Cg{2ilnA;BVNuHa>HE5*9N4al`vuhdMR6J+Kavij_gvc3< z4?XME_#GfryW{jieP&h+z%2AoV1fX6-aEDTz^@NB|x_jw*| z&HuSlzka1Kc3hVIxjn1Br8rU!7bs8ekULl^!j8rjJ5Oi*-VT`14qgm=Pji)>lfH}W z$ybBJ;HxRo@+T!sTS{(Bt+bA`%G(o$^P&%f*aa5zDY z%&GCD@baE&cG5KZrvtTx#z{nUsnJ27>pTq_W5hR8RQKdZp`p|-aesIWIHu)BZW3hL zW0qN*&|(;8AvDYB894*J;BQbdPYjd`c`D@$lWBT_Lm8yWuCxH&&lens8ns5XbYRG7 zt_enxqf@CWu-SoeqP(+xlj#F?MUEOy=W|)24M=vJDLh{f0J-X)tM^8LEa?)ap|b=f zETEjY&gS&jA#OWPdMj)tU+9zXjK}7dhw1W76V*5hBc>4*wTm{UYMtpS8MxD(5fVO? z5T__p=b(3AY^5Q}rnXZ&YUNsRJfa)jDmwqvjEIbH0yGx681u2t(V|+VU_{;{pbB?Vl`X1IzL;q&KHvV$W*%GE?inX^ZdJm zOZ;WaDdu$Q1$i~a`X@tS{bwQ#>*Mr8&D9KfFN}G&@ac$S)`Q&iGK)?zHvQ z(3yQRKPm^$E_`TX{0_Sk8tChPIT!}4y@OT+z(=5m;#y8ZK3+HOp%qvi3-X@(v>kJ< z7ozZd9EpPQDI1NDhMXZ!ICp^-fsKQ1w=itLjQ+P8w6Q^E3rUZVL}zoPu}5&**&)C1 z0q{E|Qs8%e4R5e4Sn>!F;b@Aq{Jn)8+JQpzXNzZ-3fkX{>PVny%1U><{tRL&`-IRt z;4ZrtVW4NKq35GgTh();?NI{FH}_Ff)nC43PTrD*w?WZGE7__u8dqbH@diVVB2(He)oPKa#2)h!d6_fo!xj-4epqC}D=%~;u6tA1S`2XiT z+)iqKBnwZj{e;PPKimJ+=8v2f9yDNkj>rcRv;&U`k7_Y7i#6j;&c9@SDkg8CT-py` z&M8gf!87;$jlE8s8l7Z;|LC7%?a*IB3P9bJq}qYp_#I7B8Skx-R!pW&AY_W6US@vyOoMvab`(*osc z@po`5p>~vYr(XE$XEoTX2>><`+#^tqIe{}EK4eaRWIUo#LO4IkuESHhV4oi7)jTj7 zIo=&)lq+n98wycQyvurVB`54v>Z-*k#ch-(0nW;)bir0|hX=GBLH!vYp!zv{B8Wl( zSxSNVGnv?td?`r3mmm&&`)0A)Cu2M{jmP%l{tqM9O&wqqGp0S7h%Fn^V-~oTi0%MX zVI2{m!IIK`$5m~q=!zlavqXp6cWi*~vVtAzV(G&bJob3Pe57{H;Tp&8y9|LAxPWyC ziqd@@Q{YlkqeepDYfJotv$op8sF}?Le2$eXVb-&9(xw~+C+bf?c=?sqN!EXz=5k#- zJ4pWGy{6-m!^=0ClPFC>TdI|3(o-_tSroJvrxP6T`D?!~JQeS9-G{`w@G>|lE34fA zZvQsGmqVhQI54Gy**-5#6Hyvc+0beFQGxkv*Q)%bI$r<9v zRcH+DVU_MWsh-at{NAaFbaw%X#6MO$qjg~eC6SSz%TXu%;VXYL*sy+0BA{#u^2UQ4 z+(*y5ncg|dreUf^K)! z(k2W5!His_)NAE^-^sry7M_$$_L3$WKmIQ8dsPcFXKxZHSzDX^-@CfEkWV?=19f>H z`~vFssq1O(-N2Yf?ckeQ^EcN9HTCU(g#i+m-2OFbWwQlZ){smmzP=utmGMou#iRAX zz(}Z-q{-9<%LX^nrtv#tO%RAV_J5a?b>O4F94D+ZhtIk;nw#D0wZ+mJorCrDE;?a> z*>bN@65w(fhArS&V$R2}%Z#?FT$69ZQkW0qS2TOped@wM?9XXXJno+C--5`*s0U}Cyfvq1c9Bw75LaW#kQvL zoiVuBzW6FVzrJmDW2_3NK1*sZdZJcTB9d+!=gq*sBQe~>ov4^I{NmteUwFQnKkQ29@HV$wxO%-d;39=Wd`~!Mqi}pm~ zTTV!`c1ywizWWL!&%g|?jKzg-3gRwaD_TOXuxG9cn`hg3YYE^Ws4(cC0-4pR5cC^ZnxAjFK54({g37@M2-eJXVEAz0>5 z%F-h;AkO!l996Gu4>$c$ZCR35QSr$`py4oE1;ZMy=mT_{6wqjLY%>8Qz)oI&O&bAO z#OqY-x4{Mgs6jP#&MSSv(p8n_C7D1H$AxmBU60;xF@@k#9SvCR^OO;9vK;MEP5|P- z4twZ6kNe-bE7}A0c}t1HA$Su_dIbN41At4T%#5hS(oh^`YD^t)%EK=YLQ^`yyDiP&9%%Pxgl+((|>k zHCbq*q=ZLTQo3S?;E5@o_Ey7og_60|U-F>Hod^J=S}}jD5W&!TeG3Ycn=mKZj;ic>FiW zx~*)l0>?ibh~WZvIk-dm+&{>4>Q1ZREU|=dlSKmhStUh-B1iZZcQ4Y7jud$>h$-@O zJL0ot1u)BG^4E7g2=<(h%Iam+%{L%4bq4WkeFHo|L#`KYo$=QPZ|a zTzOvYa<7zyaq!^Ovso*ZB86kd?}b@cRA5-{Gq4Qw_qfBlAwo53cdPC4dFb~hWA%mr z@U9=nx~*>f^1XRqz*c-t^+qKB5J%3XfjB-peh*0|X(Odmmg|NF2=N zCLBLbw41=%TTQo`Mnxh;oi(KW%>XCvkqQ{Iq5@?`Qj|pW&tKRQo$8;sd#ZbscR5w`Pssj2=!gT^61z|F?2@&k2tD9hW; z5*~@{_IZP_Jhwf}+!ct@M0YVm-wi0#D*v)f^ttQV^(H6{l#xmSq};m;Eg-(puFphw zhd>@a9Vel2V&|%=;>kc6Y!#nxlYIb#`ld8BUaK+M=UfJ$x$31L_R0@KqG@@XQ1U4@ zC!V~nC(v;Oo?ev#eipA)*#f|$ao#=P@X^M*kz7aivUgMQ{BpXv=H6JvVpiQ|T=i*m z?5j0k%J@sT1N&D%A3g1x%*ar#VXK3{9?=O!A&p!ZN5yqSL z1k@-C<*;1sC3%c8?dQh%#-3DdB%?DPz-}jnuZLBxCxL?Wayx`WKYP=!{YX{E3+<=z z;w&`;!o+yx`{j(?cDX`;Vu+sG5**RalSptvIE zZ#)G28?{dqg~`E0fOi$@k25*JGLa{fLZyn@fd;Q(waVYDI^a${L|w++FVuI-!S4@c z3v)RWmod8go+xwJ2n!3;9tD% z*UUg}_Ua0ReI|v}qf@BY-c=jfB1BVJd+Y{Lju%YmUF=;eyy~L+%C-_uFVh?-YNobD zW_uV}oNczh->RPcpGPkSRNvBin3YKL_4?e18f_c05rAF;7)fi+#fI(lzFPt4yB<^5 z3Nxl6CEko*+-o}xAoaR4ywW*O71VEq*c7drDduq!HJony_iV1`X_Iq10NhZW^G6|u zF{B0w8FO$C0_7q4iX7NvfUV;i?>oItSSeXVh%KiVFsS{y|sYt>62J_?wXKp2{#5>eL1EW{8aaL z$w@yes!oxpLsv71a}OzMPbn;SYKNtGa^m`D52+Joz7PJu=Thu~@@_b1?x{i{{)Kus zr!9`%b`g#73y%go2Q&2r;L9ej<#~Z?$lSsX4-u*YR8pX&)Q5;P`3eefySd)kxf2ELFl`l^KmPiR1et z)uuq00G6oxlXc><UqWMXq)GPsNLG8-q!Z$M6(9HiR3{JO{_Y zM@!+k`|Cn>`YQ{MGK%j41MoC7cQ%_k#uz=;lt_ABsH%;E8?k8vRms#8z(@=HcHjlS zaW*|vOn|W+k=C36n6Z_!@oxZ1S{5LsNQ8%*u)U_n&XKF!IBOx6P@$N8w~?Jay?xgT>mBP~9nEv3rHJ`Vb1NgTXXu1kB- zvsC#hjexK^{l|}(P2Wm}sm#2%cXQdcrU6E<|9wTU_SI!6Eezi9%6-E}fOVh_cdXxKswEfyEr==F-y_0qY!zeHWwi|HhQm^0d=ji2A1KB#KkK5GjE{ z%7h!(sb^%pzmsbk#NApS2-rd|=bSajQCn$ELo=dAOnrsjOu}`MGWmHa8Thb@L*Cz8}RsFERG2CBty*HYcq&Wu0tSa4G zGew{F&uv?U0m5KUWpP^T-e4E7aVHVmXMK;|U0+K@*4#r<;8e&rCw@%I@KU=gp?x!XodH zLH;}|XonvHIFkJHzf3t{XA-^fI>KbSLiI_J-2x^(>(ADW%C&_pfE;KLC~PL&3CY6BR&~AHlLpZ>M4l8B~*;}*5-cfdn1;`JBo}`B*202IwSGG&D zJ0FMwVZ_8`}HCRb@h2*Vg>MnZBv>)E>e|k_pY6DaY-1A))Ph zE&gWC|JZ^D3lF3!J0&|f0nO^2hP;-AWk&#A;!Lie_8BB={s~Pyk2UpF4BC#j+arYI zGU8&dYuESf1Ikgpk%dZd<ov)$UAnkSuim)fo$)-U^`)-BCfsoi% zcIl_CSbNh4+e4ZRn`}0oA+C4pwF|qpbc+lNL5euj75FLW*?_-xK0f&N>b+i>RWmk1 zHP_1>c!TKQ$o_*0kV(=uYjT1Bs1$>*5I$(@Ita6+@ z^k+4sfZ^>#5!n@w;u%?jEFGdJklrFykV0MXzZ$M(E(=QdugF+w06SC$Ce371Y@m@S zLKXvnqx0&&qm#Mq`kz-+Ox2Ku*c^W}7iHsAYIb!NxZ*-kR6J%CtY=4Bl;qWFje7Mf zUNa@^81A!$M95^KZk5Zk%U>KXYp&|N(voZtB{eymD$|g#bi2=;d7Rn)Cwz1eL3C~T zfkc5h8C@Z|{Nb0X*$;yQ{~!WY4Ex5!jA;?zjhTI!$}WCH(J{q8QrlyHw7jCl{>)`} zU+e-3+oe)ScAE6hY9+Otl-pjt5H6?icc5D?k=~Tc9`i=EuoideP*%92+Ro)ZCFpcd z|HQ($U)`31%Rj#t@5Ey9%v9D6007H+(dH3Y3!tm&xX>D@a?}c(flY1fo@5jjoqG|! zf{$}EohQWl9voh#21%e^L)ia;Vsf$mX1`@Cl9Pj<|C9a52jB+lmqguwYYAwF-`~S@ zYU+k4e^Circ0I?!9W#GW3Fz%l|JOqa}PV8;!RB-Lnm{1mG?OH1(D&~ z3Sbmjwg633qMljyT=HwUhPOM$yxY8Rg4GzeW2S=%C zXvGeI2O?{wKl9Br0&?fNd4|SL4@|zQOsM5lDyZpy?R{w6Kts4QPl!M7z9TKrC{_TF z^c8QGT1OKKv}biG->R1V&7*=x9EV6nj$6rdK(us5dw_{<^I(r?Rc*se!(N_Qe?mW` zJd_z|^0D#>0QD;C+VDqeV%k$r@{)mEF*Pfd)o9@L3g4 zojyp4685m0)s^v#SKEGPCTvAXb z;HmprcZY~b6iEb(lpEp;>sZkfJ+mjEf|lJAC@&Y*nldA25Nawd#AuF&4g#U?WU}sz z4OG!u>3zN)c5ya7O5r$LYN;RJ;>Z|299-~hze?8_ZuWCXTS(;D2<=siytn7~;PcR$ zBYJYtVKASq5L4%PcjI{Ke!BFum;x$;pnonHH$OHGOhd0(J&sd(LFC3DEdjzJG1F5iRCf(Bfmdt8#bbXA@vni3A~ zWjed@pAA=?(qJnXF2WgI1beeX$X$pG&(3YTbTu#blM5KFIa$pD%c7;f|xK60CUq5W-sfdN6>>(Z(nPaXIT@GhJ_OJ-_N&| z#4qUGr8208I#rh48IrS|YLrb;$Rk)v)k>zt(dw_ac4K9++Df`lN9W}H_9-RBUK#z- z-wxUC}Ghwf%cT#@LiC`P$kGDU$GdsInJRb=< zGaD;;Hh@)r?ZW@0cu^GRz{0DBI#ZMec0XM{Y4YRO!WkV`#V>6CbRrmMGKib4*7;iz z4^~{@1F&4N?5D8M#H2(Bu}rg$lmud4&XMd;1|F3xvt7FEa}Lmruc7kc3J${3;3|r~ zbedI;({rU6`(w&Nn`$@TPpP$V9P=e?;InsFl%87a}&5q-I@2>+jV3VG112u_8iB!4?uGY z2RSoybKk1})IiYctrcQi>qRfvIyp0u?ac_?-^Ko8#8dt{Uor!DY+h4#6m#GayjXj@YXSVD%s9HmO(lFU|&is>CNd| zXgzYG2TnBmU+TW%9I*cW-XAGv@fpR}3h=* zO>)$h^=XE!^=keNR{$phVJS#Kq+_tc`UBy;ox~dkD|hB2IH$;Q)XU|#pmFaqnR6%L zi~mSB|LNiIKDqz$P>R#sUe4+uwkdszKo`{%8cXVJlXDa&kUhb`{k~UEgXF_&YY}#G zvfxwA_<)b$f_V)xn68Zi(0skopLY~(Z``F>0{W{&;DBj>fHB1PSy_1-7@|r@bwE|Q3!^Is{PyJ zs-!8onB+dB-4;;h;aEg419Np5axbChYD{x|yi>!*y1&@y`q4?}D^{A5wEY7<;tEM- z*<=DqC}=ge;@Je6XMt@82v_e|)uM#qnWtNTaL-(&GN;Z;`*}^4zUw^{5x(%-az>33ERy@J6l92u=%-E`2%sB*mhC}C z$sDS+(*$8WcvONscq;@&ZZFe6P9~%K!hUyE2!}H>+_@Jxd5QEvVF&($tznzyb)~ng zlL+a8nLhxV4;dU}H=`(#!g%%V^ZFqLGegyQ$8X$qoAPmzR=x02xO8_x`PDIr8xqBBVuV%Ycn1fDwQ zGGcy$)29CZJQqSL;Dq`-U&&*lawR^>uaYVt^a@G<_}WdX3D-?rkpVFy#t1Qz&&BC`%r zy0avlu}NZjsVjxTP6rvf$CW~Fw$P?($ELT`KNMIlurqL8!hCo5?opkpYtR$+Zg7E2 zw7Su4qJJ846gdUC@N5`t4!C7WU16w0HZ1^U$xqV{_p=4!s8&leru= zJF+F>{nG}dm?K^kCDObcB|72!_;ZveVO~3MB{bAo)r5&TJiFt$$b24?-*0&cIz>Ag zE^X?xG0X5?;(qWEj;kE5#wF>$D5!=lkn$U1$NgNsK`guD>sLcH{0l`O|Q#IduU=2$B`_ z82cCc@B_a}#9xS#KeRA?qj-{9u*daFQpDV91qRorwlR-@HTy}Kd8s^xiQsD6WY$@o zl%jXmgGT(G27u=fD*8#Qeo}UFelaRmpvujQ)OhGI$ZU=2wAdr2F+00UdVg{<7l-J0 zkj2FvWLF2u)7@^nQ`yOUPE8P8O}$}BXV)l z1HY151(wto0Wad!&5gvp{TlR+%-HjJd0#>6k!D8hjUEM-o-at*6y`a*?PgGn zL`3sZeP=CD4VRSckKP~JUQ7+t{Gt}3ft7>8DY4dMb>|siT!(+vb)qE4#xO}NEhGq@ zI_0V~6&98^6ej~h6X3b=&K+ug#y1gSs)t@)K?gyDfrVI0dxiEk`V}-6%I`YDVI~}% zRzap|)%#%H2vCmRN{faJiV{a>FbvxCg^dhfttD~C zpC1(V5IaYYh50n<)Sa&lqRQ{#rZ!{QTkDeDrN^-KhXt0z8d~MRn@N>yzm9?Xm#uF0nuFZvt}?bIw%)1`*D;VtzE&&dXI z6k(8Ue`ODH+o^EKe=)HquruW`i8N_T(UVAx&Fcrgh6Qei7Sy&X;9r1YfuIO&XIung zB5zDcT^It!LGKH;?HKlhsYXrOm!%-nTo5F}gx=jO|D1;E_TJh)3toT-i4J-fy1fRI z87e+Cq_G9qKH8{^5zSPm zijH$j++qjxC7bhwFD3hdxoCz(5r8KLXd%AC|9$5ybjba6IejDkcKOO@9%;0 zW#y#Cv4k#WJ>GurIon7YJ!s{vGbv)3j z5Lhc)Cwv+VtiSOdxVQGC28&_V^W8XfQIx@gmxZo`gHl5MGtG9 zmrGF>Pe8rY3lNBjzmSF1P@^1&t=%XOxkNs0s@n%3!20`mZ_|UBINs+5u=;v)LG2_Q z{Qn1`5GY4*g%%qZeNwh649Y*MW6=V7w&Iq8cc)*#5#ICa*_VG%0G;G z$&`JkNnh$>P~VN_VFA7x324ou!8Y*@+eEA50mMQ%hBVqY{%@d{fFnZLQQz2QOVReG z6KEG9`QcK+{%+Vl7*0rf+q*{H=2~M0_R~&HcUF1I%1|&{1`zE;At1w;xU+b(GVJbq zQphDNty*pP;nN+Y#{Ccb;;)_7ILg{I9F44Gd*wE(9xu(SFdmb zfV37i75Js>`Me(BOHj^Y_59K|w+Oh9#@Vw#L?l=gs3aEsa9Z(P-x_bQBPd6wZa&fk z)0I&ZsNS$Pyp=>!y;&)uWw5t3s6s>;aX62u&bUqBA_!W>s&fNa2L z8AW_rRiY>>n1<{N;yb8fe#x=k2YK!{OFpmXf)y8ly$U8`2HMn(P3-7N?@34_P;@uO zAo-=a19!DK^rd@TIF1vq=c}CvA1+6aOds-4%*TJQKODpp#Ac{c?aoG6K8BqUS6?&% z(qL>r{~t^al?0jB>P5eLFLk+R0QVv3tq&|x6c_1cDDp>XL*lys79a>24M>00%*E}u zVGBZu$1=rVXB&&L2ir=>!cLaBP)% zXls*o5lvus@9c5nojZvEkNyAUB__zjzt!YUx-4YP{xQ)Pl z5$H~cLn%|f4Sz_C<9W_Vy}>iEzmto&kKSt#L}@=~H^(>aczev|em+)1 zxmtxQAHrP6Vi^PvY9Z5A&Y0vbx^x(Oa!C^F0{9bA0KNbE0!Vfhdm0*pK4cIr<3k;m zUso09gf=EQ8TlmwMP3V#DDTOo9!K!#10W_?N~q6A%MR~ve)7%@eTgSm06gQm8QwJ> zj#snYe7)Z6WBeu!ARi)>C=a~-6;S2ZC<>$sAmj7c2+a8S>J|8vgovQh{^i=G5JEi7 z$IZ9Jyiv))z<1+q7|PK<7@JVxL*f7BD#V-ngtf z>YabPwI=g@{u>2IQJ!gMeoQV(lIS$FfyIEU5i|73}8(KRb2}5<@I1b&d*_^Zd0c1x+6doL>%Hszj zkUQ>v*Xn-a`wrs=>c`_@C}<#Y#7dpJ!CtIPOI`54H6;sjLJG!!TBAH>-jI#8oyC{! z{UZW@>50mCX%kJb^E&r&9=rOR&ht*Xr|hu*crN&u@LFM+0P3*)THi>kO}o7j*S0mI zse$o?e)AjVh7Pc^cWsPyq(|va0N(=ek~c9CZfPoBiNKp2xv2NRXYN2@Jp80bM_M5o z;19^lImN+KPDXqjiX*G(i$HOKN;l&Nu7CqRqCvWD0;&QG^bYKAydLZSulfi`_vWtP z7zk7TMUrBslE0#>t0#tPj7}a^)@G*_ClzbEk#LGRV?|A zXrHRTo%<7oh8GRA-Qh>1#1_!`)>HUETX+$p~ zIerg41u{hL+V+LH-8E@tp<1o-Qr>}k2NC<>>=gY9B7TEHPS&g^Ox#IN)$rQq3z8gq z`UIMkS66?C+=5)+GM6bR=fgmschYV#?XqD%jI8``5!g$jWqPRZRyVXXy%Zj(0>#Y3 zM~OU4Z#3m8h?sx6C~f@s;j)P!)Asg*X-vb~%QFDLUCwUSFuaA@X)Bu1QPi1szLFDn z-ri?X;H+V$5csbP7DdML+@?bM_5(X|ZG8l@S<-wNz}W-&Ck4?##$u&@-Qlmnw`MRv z0utqc-+W5wK=7Lo*8jVA$&HB1Ay7UsPD$r*9fJ(zY@`cVDXLuJt=Ga}kT^X?#F37) zk(asqGX!gkGee=uRmuIFpVghr-!~F-7<~0(?iP^!s)5p?Byi9{{r|A_mO*)K!M13C z4^40gZowrGAh>&QcMq}JncXxMpcXtc!?*0~g?{jXwTeoUeD*Q-=HP@UyM~@z( z8|`i+CbXo_3gu78&U;k)0QL)JA(1Cn9Cnyi+t4PxqJsws1{N$1vTeJ^xLDuTvp@dY zxrjq)<}dZCi|?V<tSEY5@5~xm#BxB7ldAa%Uw!r*&>bC_HgPTKh?k&b&>Iso( z!5NfmsNXh*@Z>&%Ul4xiU2%$Gw1EW=Lx})urI*n{iqxjUIl0$l9-EoA8(r!A1ZpAE zQOplL@T!W6gjwSwOabYC`Iv}c^guMb18R8N6lcyEvKUHlNW03VIx;xCvl4Ry$9nbl zA_p}{59N3zSny})Cw!%ExC7F6u>5X`#JD57GM>YoiU;UKw_Nq|AFTH`1bqSTX9H+U z%E!A~fQ!+$sfBdM9F`~^yq_MeG&w&#FT1$rjz#SM(^6Q_3P~RP5>mvH9J-a2iw`WQ zk-qfP05eQah*!zZlH$nlocoB?mu5mFs(;@!a|jpZBRD+~@TLi9->YE3rBEUukvMdf z^dUy2?yVqzpDVKe`u1{@2NKh~UrHaq@?jPZx}7xo$Ujy^mC;Nj^@a=KGg5tn0AM6i zuRt6hckFZ-1MP5j>aawj>~rAp)^{1A->yh76%ywLWFO_uRv%@{Q@Nw34R5zTGxz_~ z%g7Qbpj$W;XXQ8UZhZCJB;(sdB3!UTuB2fw8B?KSKZG#=`fFUrwVGa5>g>e!Af_L^ zNnv_Iy-IWkR{nTqgb>L0mVPE|eO>2{;bGBZc~xn`XMuYbCuhxs>B> zqDoO+KFVrHR`TFDO;UcuwXQawBw-U7iV#@qtcYY$>$r=6sj`eAr8QPsHmsQL3U*1H zp+EeXj^(iWa($yW3M)ao-InczY24bAtQ!RH8#e@0v0+MrGUmvQeAf)=m&AX{uU6|J zvLs;#aH*Eu+3@zJs^p~{DgbKqFMa_upuMG%Pch{Ih5X#Bw&qwA604Y40p?;%eedl zbY_Y4_jTY{Un5LhpGaNEj%8|4mtS=LYZVLz0Nzl+>{nxXrtxDO=;fPq+tWMxN}Kl& zWP^>LL+pEo8kLl_cEs%D!pW|m?L*=oVMgN9Nr1JBjoNk-)$iq=CbUJit)(0X&iz*s=rYlnfy7Q)C$q54KU*;GWY9 z;ek%#j%Za1e8_T*h<`XDpfeJv0a3lx1jC)pK+>=u-Kz7WASSue2f`NN-@NRkf@2xl zLlsr@dQgky-xG5o4JV0oNI&w)_tkzGW9Y^}TP}t9=XW##uTq8R)yN+N`V;)ad`q?o zexaW)mXGytUE#BnP5%s35`r+_`FI^4uVe8_d5Ybo4^ZU5eu^X}JYsV|zsgyyIpVhI zh#*1=Kmr@E^@T%K4g3nGdK7qxFOloMguaX--1m-w|9uGaKu%pl80jut?vtOz;cO1c z(aydicYfIhseCSxqN<6m6^1XGKHy5;ml8_5pN>qVO*6jq8}}st_E-B8%z$AaeKDV! zU8NXtJ{E%+4O`0|e@D?eY%qVBYT7jA0hDOl=oA7Yum#SMB1W+(WPS5TNOD_$5tzBi zS%xFP*U*jP@dFk-PYc24zwhr9?lq#VU)IHw)OA0M&(Q!Nx&SCJ6X=sLWTD7#TR`)l zEejnHe2+4q^tvSu$Mz4Ns!gL9*9GwC%AjJtvLKta*`NZJMprBkxkx({Ej30!ixlA}7b_Sc z-LiFEmDQ@s0p_eIjy%4I^er0VmLQkiAhw@y*p=A;rXE=OS7e!3iix~?WrW6_mA$a? zLc8%bv~ovHC(P9KV&@>XPbg8I+8=<#oJmv zFpEs!hr-Mv0AQP!A=Uww%nN{u6lk^(YP>%_!!-OLRDW=!r-Z=<4uA+S>V&Mw1zKig zw9=*n=YL-L0}Lqf!!NZLQ;V!QFE@IgoxOnPy%I zn&l#$_7}uP3c0|nGGAQ@5n5gB?hXzZP^cG8*^j0!h4JZHEZrghivCps@Ri%-(7}>N z98b9e^Af`)Z!&>{Bpk7`XlcZWXG4>R}7-x){ zSy1Mpmfl`Teq}Ywl=n^XHp=@kB;XAUKLW9(l-(Oeil7&6mlRlR(N~t@>$;qD_eZ@m463Dmb zh=42FHTZND=}DIn-ll4DNLy}0$}TIuY|+jZgHWJ2I|Kj8N0fI-i2Fu1?PAMMCk|Z> zxDzf*<&*;~Fr zUa^}Zw26OvX=G%VHfK^Wa5%u>c@~u z5y!-rh{5gZe$hFOKDLYk(T6Kp1YF1NKmArQ?fii{+zAAxd=fI+lNMQr&8V{&aDOm> zD<=l&cax3i!HMwt(nJ8*!>(I=`k=p8D30=MsSQkXzMaXQBPT5vXLhq6z4!XbC~sd_ z68rOn$lcA{`Y1kBD|58Ry-BpC{jl@N{#4u7fN3KKwPSNh@4Hi$y@|NZ)t;cbH%Aw< zrq>w(yEi4ox8%Awd}q(J1Io_hy)IPssS~66+RL<`WBDs>w>xr=IwL`X>>&s$g%0PW zc>5*zlA%hEPuT#aTmZW(*4RXRLews1fbDjnn*?5IuTtd7`6SNUr&@(iZuas1dvp8F z?*$ zL;#$K2&4$u0!15VU9ncdjkwW!`Bj@l_bT<{ZCbG(mzKAMzpNpINHcw#wLw#Ze+D3b zeW>1SOpjM(&urN?3M4!YLisj#P(V|Hc}1E+Sk4dbNDRi-D8UpS#981hc4r=gbLy$x z-l)z__wWBH4_>9)9cOJOF6r$%ATw>2+a9Va?D@2gBEKUyCZI zNiKU8S}#s-7?KNhN~3PrS61r^{_RO4+KsVgZioIPPY%#$JdF+jVl0xUPXDt$<)g+@ z7HP$J7yq+qcd?Mtq;>0eH%k5$8RYfRF!$H+akpnicUA|#MEj^kN)e`99_=Oi!I5LX zSpQQu_s_A%RE*V949z$7CkLC{(4>hM!$;a*v*)=fjbb-DdNO{+_g$YG_{%Fw%3>&6 z!Tv}tpxXVZg|c$VKLo`66(Yhb$>u8wirpr81Q>MCGhsyO^HZd7&$}2P&1=LYtECU3 zcjemt!@C%l5J?=IlRg#5=0sJ)WAE>KBpMgij^$P>TGxZ53{8BoV0=@(1}KJchO<%v zGIzxlS@o~X4P-YXzKzEG>J2-?O^=nMV}?|abGi-kq8Uo)?Z07y8EWXOu}*qm82YY1 z@B{9QkF4XR|9n#XhMTD1QVIEw(#gj?^r1iKL^xdSRTTxhG(*85rre`xp;bQ9DjV(th(F5lB(fRyp|8eu#MgQris&QU>vg>m8sqW>LpiQ+t6U)#^lC+F<#YSB+8AC*uKq7ZSBu?*S#T25!l#`L=Z z#~Ra@Fp{hK(|u88%KUu<)+Q`?VE)A>d)}YaZBbV&J4^MZ6769UJ#NZ7f~2a-3)7Vh zc6&?t^j$OZ^Vcc|*Qgsm^4gr`anoddGCH0zioByVajwdG`D7Qn*gP){rgoIjM-TYW z)HP@%Qs}ln+2L{|F0LTiiT80X8mC6MglR_q^Ek#xucm6JaPrbfS)% zi4wXib#AIC@=dzsUedQH?UiU)%p*u{(pPh?6yv*>Ww` zN)4zFJU&)>7_Olh9@U`gj(h0HMY+FaCr?!ba~$S}RP6+=CQr6DDf@?BURGK|F$1%SE4Oj+#@S;6_gBl8eL*ON>011X=x3mEfu|tW6WP}c!(`zpn zJw%_6c)2FyYCH~e<%zFD%zKdPYm4qsylmv$5La^br$K|8K-bE6j{a_IUOwdj0Np+T zjpBr;q6rZc8r>_i3xZ$ezKU}0iFFk5Y`ykK``u_<>0KKsoc>{hFxg(_A}fOsST z`QU8VwYp_zTkYSbi9P+RCfe@p{&0lkC{Q~6$Afb$ilMSG`7*7FQXACJA7P=N%vk3aAZbvt z`g~-6^lN##*BwEurPBFqxj#s8^R*M0G%ZCSW#bh;ffNC6j&D>no;mmd<)49&2*8Yv zKMs3qhuBg`cgnc@K03UFQy_)K{wBGcVC=-;Z(xdH*((GoMKI=eNt*zF;pmkY)B_9nftR zc~p!_F+K00z}jI3oC3D`my)$}y`1X!YLX@ou91nB1pP6K8|z&RIohs(au zA`Z-=^6!8q%+Z`GDK_=Ii4RG@P50vTGg||`peEm$H@^Y(NE|?0OFK<@$RDjAt z!K+EQX&01I6;d@Ng1OUGga@am^;^R+D~&l0ek)u;;UU2ERqFCtzh)h! zr{^sfB5E$PWB}7K#9}?UG96|Riw`D|uk6UXYf)V|%*b!5vQFH8y%r?bTWTe9H&o}p zrk!+0-0kIUFIr+6;V-A0zG*(dw(yt^HMe^j2A#HA`y5_hMCiRs5#qg`S-tzEN@9jF z`eXsx8X#AZ1i%j)CQcuN525u2F_p0O*-$_;Obry&*Fsqp5wJ)Vgh&`{K+RPM(#yIA z=KKQ(j*td-V>lhhP#|vIETxxlkP0q6N@ue&NDwLnZii3t=cZHwovI3&6pet}251!o z^&HF!X8&zSHB^n@=Lo?baj5R%H-so!YZGV22pHXA6`3{f-R&mbmpHvs&#IUN7LD#C)280?L5wQ z?IfC^R7qoEZO1)~Q7l$k#P9CbR{JM1CC$h@N@)I+m~-4tdIUyW^oE?hCAK8tyS8g2 z#*LmfHbA7h+A(@a$QDUrn!cINj^w|Y!j&);?*t-aNvFG?4|SXH&XZkF#xPwExZ2t~ zx;K5#$}eY^^BmvJtT89JX}&tjnRb^xUi0mfQctE&7+XSYcyn=&_wA}=eYNBxT7A6y zZxNtnt#lN}% zTq>&&uRf+Li4?LBD=)qPP9+OjDUT#l8ztgNt6~)-ctuRZQb)28sw&0u4y>X8qM$V5v>8r z$v-+uq=U`eWeuR+vnuocu2O@mJWEKc#mYNi&EHaSXYoR3WXm-b^Nb{2i__EJ=mNivY4(-0$iGQQlpwmd_m+XMDPvgx=t9!1?_N z$jW%Cu~3WjL~F9?OF0J|jA4N=#Q5O>-h%$i24Tdtk2=L}7QYwo510f>^90gV7MChE z^m&?3&4!%c{tiosVn9GPqixUv5{wLm8@ikIvA~HUp7!+7O9-sXW(A~n9MEPRVGeCd zA!oI!p!~}QTM}pjIw!7p2y_`W1Wk5|643?+XLrE%k=ze`LAq+_cjeJP;4 z_TX^Ui^6Nya2e{f8^-cK+zk)Y;LRp0nOPrQDTp(IPZm7-D2^ihHEAZtbJg~f1#smU zAtV;CXFpTL9{71{7B0U-T*lVtt7XOO8UHJLqx!cpE=?!%#;y~5Nj~R`q>~!`Rc2F_ zeC*m^TFHlK3X`ii1h4t2HBWz=c@FwU9+r)yW&kCr6gWfwUwi9C+pY!16oWv8_wyja z>p_t`s)2Ilw0BQTf^?qbMb$omexAg=2?1sV(_aaOT6c z_VT&{&Dj4fD9;CO--kyZBrcK+xMI~BKAAoyag6+Ax(A`^hCmk|;)kA9JaFM$Zao^= zrHpSw-1_}0OHPPDn*`m|Y5aM1i7cI27LRP~2?RLioD;|^VaaFD*C z$QUq)>51!cr@FD+Uf?n>u!%0bRVXwLIG|3v%|O#Z?$7^LCi{U5u#{dkSSi9aot@N$ zT>x;|Bqx)Xy*Py<4U=}kvvC%|o~RX-W2N(`OIX8dr5PMK%>D1=i_QtGr;DUZYn3L$ zw?133x4PQkHs#*xaC+aq4zo`sawU;TjkazkQYxs_h})-KujJ^0;jIfZ=O+UQLefczdeGk2}QMsO9b_9GBPQqlJzs$TK z{guI^KUMW0gP0HKNKxQGo(HUlM1o{e#2?5A>^kpKEe!; z0_0P{FvB}{3maK-4VpoiA2CpgVIH|ez7g&(Y0*)#2DIRtkK^$voLD=9IZ3|;qyt;>fEc^JIFqj~J7&s1jpWTnJoo~nZ?lww~u*E|$_iJuM0GH#U%%o3do zX%*NEY-^0DQqOt%O^_#pr{s1Z^?2z5h!K!rSiovW|EB0?2OyuO_>naX!2VUcdUSvEvehIT zoc%JwW#;VskKI&csL4UoiQQ!OI(Z|Hocf;oO`c`W!M>rpJDVBa>fLU*=&M#sBhJme z{Ru13qb!qahrc5B)2wP@@?7-Ki*%_5>qmD;vQwe1xW;oYB8-nV#?t z2eg2`iaWhB&X9JIU%h79uHHDPsrh^FYDJ(7E#8yuZkjDn_J=6=)&FNk zltY(!y4HBq!R5C7qsePfsY0u%f$3xe+32e?W9-RlzU#}ArilEqVePe}^Fm{D2-(Q$ z4{|$GLB-m8Moq@}&yzRf(&9NcnqNoelK9Ito@(~Fld6)^2p$+uC>DwP>Q2j7=X}CA z8))I3J!wPJTF3^a*J(pd7D(|dQd64C3Vh?r)+1SazyyRve_<5#Efny?e$fp?{Y|A%t zbx^d?T5bfuG^j?!OW;?)tR#$JRtw`Rd2yJk)FBcCGSfy|4D#t^c)_C5tloYEtll{?f2spwCDTU)B~rJ z?Ui?y@cOAeQ|{!u_RY`SrRA|-BIE?lgtJpI@jFY|lmz1%a)Nrh<{7Zn^V5B!%{^3^ zoX_E|;h8*b^!`f5iao9~U(hrML1}Fxo+2$Es<7G7l z*|Z3#i^l^U_ChcPC*ROCsraYdK83%w|CD&SE**k;q}~$;cTc*KK>h+F_)j1gp|}=l z%sJVyxV`*pcTz2H-`~!&h17H!Gxyj$kBAfGIEnjJ(pK3r*O@xVB+|jgO7_B%3kxG{ zCd!hhxb*e)rHjAmB{s3?XQk!Ekw9tEgF?H*Y)@e~z!`?lJ-PzL-0KrY^22{{_m&#$ z9>})(JdRurC>H|d8+*4=~nb5dH(Iy4hnI%#NEaU zYJ8nz>#_9llKr+QJ_Frj`0=Z?afG=7H0wjG*K?3B`mZKDwfMDHH`Ok((;!w;SFl9y z22iY5WoUTw$`U2{Kpmdgq!sZC&K}f>)2%^K9i1!zosl#&w+)fkEenR}!An8#z%dGN z#FQf}6dwj0rs)PA;KY_D@*#6cB7j&74aDLOTn=1=T|+8=ch+?77l&BabP1pRKmTG#Xn=Ys*cm`=?Crg|ur_Lo=9((>EGpaxY1G8Tl z9PD)wg@J~IR{jUf;Z}X;pY$6}8WzZ(oxXg%svmwzlFe~=2DtLey zxtV!N0`%wjT&13~vN`BDST;(QvP)e>2nDGK3~I4&cRpTfENmVFmJYcYm)&H74#&Sw z)xIukU`Y9-iIh*}Q@vz{UIe*(-;&)yu_&uHFi$!9U0&_h3L|M@ChKvEjG@}O(81LQ zg9XYG#R+3 zqC|V1MoaKBXjSH6V=__?bx<66}fl?cffuY3@Z0*Jw6_xD<| zR|E9m37a1MOujpc%6_?Wj-{SV=zo;un{9FG;w>ZQ?NDW*48j$k&$rZaKeADiuw(XwmD zh>8q?|I4Fe_2r(10QXe9yAb)`0|Ec9F#00AXekRAOJ~Omg=MqW;H*XZT~8ql_W8#- zh`uQe-7JThMK)ORy~yRm3i>fyqxRJUN8gFtY`_`H1aQ>HdP>Q4LmSK0eUWKl1c7mC zfB4?8ORH+5li_=t_eY3O?epE6zvq#cv-5lQL%{fkdM)KyFVWwAQiuK03e?a%kYw)U zZ8fLmy8m)!yxe4yARDE?>U=`mn-W>e{=pk-qE(z&ZERces6??VT&d*GDlP2YQs!xP z!YFYgkV0$}ZJ7dNwV&{bb(pmvbI>p+iQ8PF==(^zVxo6R0^{#O7NB`=sNRS@-$3#V z6wl{cNkMhY=gXlOeoE<@>BJufM&)%J5z)sBolMBvQ!i>6Ve)Lu1BFi`sX=@e+Vpw0 zK}GhgSv?4l9A?55fO+-@8Q~Ttv(Q`82-)E;x^ON2U+#4Z<77kHBHsQHC^G%2DUcyt z0%{RIn1KrQ9w;SAr0C?^ZcZ8o@s|)HFfBSfZWj}NlknZ{)W1F$UQIdfq8b!%Kq` zLc%hJQgXEj;!f2cYeeT#bO5_OAUCpLnNW(i4eXx&kHH8mnJY?^*26!=@i!+9MXQFoa;6)IbV)L%}LpRf?*Cd4_7iJ>BwF|_fwMicPUa8WKgY(a2O zbX=jvM%B;B0##p?55dlHRp~*`6Cwd#T_r|{8oY}F*y(t*$xu3pX+~G6bsyt%=M#W3 ze3yI|1nHCV!K^Y^ZUJA2Ok;lN8T27~%uI|&lgoJ!2`XIbhU@FY9&~2PU z(ek%yotz<9{T{9{Svb}0 zs4HLY;p8YqbpMVOoL%%lp;+W=ZFHij&HwXJ>O+MBYdr*38lk_nAk zj$f5E5m8fph%iyXUz0+C{%<+ie%zZj7hB z084DTQy&k&S?hzhD0gB|H%e>Q`0dgxz0sCsL;!XHXm4XA8T${UB2w4AC`t*ZG9&Qv zCPLp!r4WONg9g8=Q*k(W`5DSfWC9&m|86eHvMG9*?uGYCXzc`Z zSNx=TIsdxj|2nGqIQ7OSyt0EEJ0YvxLMN&_MlWzM;rhDRS1{HotF<^ayxKYd+xMxF z(O3FCS|Q@8i*>V#`4X z%E193eeOXM+ak#wha|e}-kz2Jg+Xhz>4Okl=;VWiMQVTO|su zwy@BOZ|3bdWn;|wyIu4=-D~Nts4%cN3<1q{R?W*u8)o1OWelWE_b>CAZ%%`udPwet zAFWc_8XOd)Vnba_3AcMFi(ts{zy_??*~b>Jo_Njc*t=(gWfUHG-*#!OYu|iA8iv`A zGmGsZ^+?aeP*+;@P6Q>YJUVqV-)w#tw0_fH@v~+GvT<0KM|=h>t(TJ znZ)ZhI!qjyN3$U}4Qg!QB`g8yj|4ias)!>U0M0%@+-|=rG_|AfG_)nzHX`*F(_nQM z|6v@$icO$Htde@RsFwG82mDpg3Knc+n-y zO?SeyKbw+(C^TUL&(}gxh4RS)H%K=nh7?J;2Lc%-kb{`OYAybJQnxJ%2(2vbF*Fl0 zb~#eshN#+rcie!-y7=R$qSv`H(jFB}Po+Q8&QO6@0yQ39Bcu@NL|F1 zg0NKLfC_(Ccb;Da%&BHy!`Mt1((v8+efXM9zvppR*>`<^gV3wdK0vG`2i?BlR^sF* z<7{Irt7KQmTKdXmuJ4iFhTht#q#&+^|Z_P%=H`YfXl0v`6)$olyAZc;!xvM zU?$S^w+e+$S0zKn3QI!22Apw%mpmaQr9PLf38zbHi&Hb7W>i(V&t%EMAFkzb-<&K= z+!6S*%8C_*WDwZ?rs(?M?SvdbkFdvXeB#(5*0s8_#`BXlG_fh}aIR2{4*pme@Oj%> zd%uV9Eyi zQ)xj)*=Q<`<{$9CGVqtw+)Mn@qYqy6sTzKpH8Fhp*O%$6gyD_sH`}DD>W#rZCp3M% zb?z*de%kDL9!-9OrGtjVGWOcbgNLJLnf}lA3~cr@THC%5ewR(z#>D6eBcvJEyV8}v z+j&;10~H_XZc$^n%`IeMxwsCElD^rtnkc>3apHd+3ZEp+GSt$|#yE|7d}DBZ_}ug~ z%2t!>%5H z8pH|~6fl7082&??kDUy88k1^XB)~R^*Jh2Vco+|igT_6Zj6tkFp~=ObEs~j~iX}~M zTb-3uk{uIz+f%n*2vT`$tO$otO+1*JH=3GpzU3h$^IB`XGB#ab(GV3|VRetMgLO}z z*3U*w8!()CEUk!%7%*N~?yEQ-BTfB6e9Qu~b3Hdde6SP#*eK#KXYNOMPDB)N`|BLwd#BYZSuV_|01b z3}?#YGw#lo!~uF$APx9=h1gFB@9-mf0N{p~&=LHQb&?9rGWlUsUd;MY8(hfv?ZN}) z-8ZTaZag35{5KRutf7l2nt`_2hreusp&i&l|16l75R~JG;vrF72sFBtjbp=tLl9E1 z)oG-X0VGcIsdbpyz*N8WYc^s3J4FS(UXo+-@uSI87?-FRwi}%KSvSs9EIF=(KXd7U zdSvlPcGoIP0=^*44!XlmdnaH|)ypqsBJC5Csbvz%FI^Uk))&TQ0o=>nt{LGiE;bms zJYk>Q)5!+}&;vt4zj>aQF9-_DLcPZFer_LV>Vw=9@)wY?U<8A_YKT)PYe*xh)byc1 z{L;LusJu^TkDG!}z!LI{c`g5JduJ0iE%yk@H|#jRKZsN~JhSZ>0tRI%$Q>tE+s}Mp zbJhhgNWglVfv-qGzg$)mATyhK{;YqA<3{39Lk^mA1pKAd-l5_k{m9O|IWy%@jZy2%}BDXBrH7~Hm z{w8oTvEOCi$;H>3)uNujKL$%C(}y=@4yKkIh|;5qPu%9$g{0m_WQ0{%HMh2DbI_qc zrQ++9J}q523R9^zuRA+)hCDj~X5;VZwh+e8ySMZM%NW=yt0!gBR(P$m-!2O z0!mZeiAIZqDvz&<#N%l~!V~_^e{hk#dAEVc=seNK8R--H>0N&XV0!x7zk8U|4!<{m zwFb(B{9emOZ7QmRWl?ex6NJf7;GFdxkl&IlPYcjd)$q^!azZu@kHZ~l1>2bisMbz5V1UD(v6YDz9U zQIUEX!%xc04%tKO#2;9#{JfeH@OPVf-3LqQ#=mhLFyb|2b1>y#lpUmu1yVZ*pXwT( z!DW1aq%uIi4Lz66E6enMXBBsN{J_)jSUpF>OY z5R?A+x%KDgd?$Skw3w#Op|ko{?r1=#WuW#6Pi;Oo{@1Y>q~evti4fu%1z=t6fVMp- zrZhvnT&VD1dR!)Onee_TO8&Ezn;8SvAIO#xzkSk6`V!x8YsRJLO@^b4>46!goy*Yr zy#NQ#+3J##3&Z$j>~eOQWbpc57E~PCrqFgAwV5TeltbKPXhrg;h08BTD?FFGx@?J) z6=pQ7i{RGf2Z4Ja%B~^FEZbh!uYD7t0e+eThVrsE2W@(I*`MkH3EBtnjV~P*buN;c z8U<}+X|t%%@-)+!ypy!>DFG^ha_WLrKITq8KAiaYR|sIn%3B1dEDh(c7h#}TDPlMB z0Qw(Chx0@TF#8MC;7@EHY7T^$OBS4EnCC6XxaP(HO~|I%Q;h^>@0o) z+LX)z#ye*QQ9q4lq2`|(Lztu`mqd*$@*yrF9ANeCNvKx8To!t$_Zqhf9QUuq&x z-Sr&0-Wr!oPVZ9Yxi{R?^I}}*mu-!^Ms7qqX8}J5chi|lkyfouRO39IZ2Cv1(dmQx znahoem&1NqS3|g$l9vV9R;|Wd4tuVgG|L|Hn)b(Dxf5z|aeGFO`#ty80)uXBSjMfu zMo|P$_k-nJ`WImi(Yx^SF^Q_Q`|H4%@>HFZ8`6^)?c>%lI-oj>WEJjJLyikEm%q9d z5&@{V8BinG*qeJW$rtog*dBD~9~x zZ2lEN+@{kEz#RdUK(SgrXEp!dd#oKe@AdY;9k+e5gLA*H_T9gF zR{-O9rtTS8x^QaPuH;@#E_K+i#O>|yU!!?}j4bs+pKo6w}??u{{8Z+3x}W!wdD zEk%v-$-vBUkRkD30@W!*p5ujacm_bnSeWOslGr`v3A-v-Z~|Hv@WBcS&mB^XF?>iSnG4-FR6wTh|Q`jdQKZtA5^D*^%{aF!y0EPr)! zPdMubz^K8Hg4w$TUPw{|BL%*qlj9>xWqnZZu6#`5) zDR7e?B3<;Z(&LnVXvLL5%f%nz1l!*O$@plst>TQl@uz0?%RJlCx@mYU~Y)fmC3PBNT zS?9LRdOe->p&EZSJD><-YWaC!$SEhqhnY+>!+rL$cwJlba|?lrdRgQv_H4$f#i9Iq z7(A+&n*-~}6xwur$#NQNVMXjN&#L_t(9xvsWQSZbnG!AU>dZIwe6QlS43yM1tS+kn z@8O?xy)0N;mZ{Wkqg?#}bhvP?EacKTkNsLJXX`1^CTNyoA%Zn~yQp;kS2peR=*r&s z@Z0PM>iVe+jN$f`h;2UC!TA`hcIQi9UzDuLv0_Jiy|rPu`^8JQI-z*>QRJl}2_KJM+L7UT4u7Um zQS)WB7}_NNS?5d<9~o%(<>d&Z(r>i_t*0G#&kL&yaN z_$2lq)S&@+DZH$@@r0et!JqiN>5_Doqn@>)@s;V5#*e7j9Ev4IA7N>f-M&H0Th%@E( z1lOQe?rcum102_PD;AW9i@@~cb+ceGza9E17+8Na{+Lp9f6Bc54;C zqJO)d_La?u%X?g2$}Lm!40jB364SbZo?pEe*d=M-<-=k>=~w~v%EpL5VbEMX;7_kp z=DzVcE&E@^4^PYe;!hW&YlhVjbQJ%#7x^gua?3)_mPh~7nOu9W-kxO$w#FAZ4<9&aOPT!ox#hijSM9yZOEx|dc$Z%TI4CKgfVZ7H>3r>3Qc0ZlpoO)UQRPaRRfIT>fHv+*5lQ7~|mY^(b% zN%}3d;VnmF<1Kp+*Xk3?)p#kCBt47RO7<5F-C=*KeqBpP zjFKf`WllELe$P80y!{rvq=U0Q{~L9ONmT*z!#*H1it$%e5|RA2kH5&!wm4PSrpu4# zQHw!_o8MCYPTES0=&&o;fx)dQc;?>7Nx4Rce;{sewoRVc_>u(-vMpz@;s}S~VF9nA zKURLb8QLek-Zc`BM)6!MEH$1u7##9F{`)81Xd(pC54Qe4qmk655hp#%pq#7jgU7|L z<#iW%u*qrEm(|BEpxNAsQSIz{tA|WKGA;|6ZwsyW^##^&znQA@YqZe!&EiXs?LXDa z6SL%XS%pi=;0?5N6H-gF2x{dP`)umE1d&!8Oly^$>UK%q$DXu`kLU?C6gz2O7@$He+?Bm_pb$c)_JI&%^$ zVBkJ0DA^>vR>5=Zqnuo=mRRYw{LV=jHtFswtMvVSLz^5TOI3{6t|=<*+0cPvCxd2d zfJ!E25lw2R(jdlrh$6Dt|7VR~68Wxf-iVBnxe)7gqKUTEO>f?}s?=0#a&LJ(MKapZ zV!{XZcNY<@?**m&6oPU8Y^F!rjp&yavHd08z;*ZK|_#}dg<~h(tu$D zFiI2pf@ZieUw*-SL=uI1_uO6NkYL!_5P1X5=>D(M6aRjC)a$&55}WpsVkOa(`ncYJ zo;jm`Qu9h)lty+02m8=@MEp4RNQ2^I6l2f^@1yhGO!q#Wpmu)6K{w84p3UR%AD;?F z3~FSD;}rDuN>6sy9?=j%Y`Ka)KonAFkz`WEweFu($W}`;O}S!BAL|=ZI7C!{!d(r) zZ)p%1)7?FkRb<`%mNk>MJ46!jDk#;08&5M4Ggt0pV}pXgz4(yJx4J*z6D_^e@;7j> z#_fiA^<-<_ArF|bRM2kpBva)|chm04KV{N5%k=PcxzQFkB)!-dS?Y>qtAqMY-Dc8( zu4=IHT8^8ITPcLcc0kZWLW8MDIkTLpcSVElMqipKBzfFIJpRtC5PR}pRru+fwWyEF z?0z-$BgvxcLslGE|HocJx&x!I;WO*L)L)~Su#EFZu%!iG9wzSgCikM1k2e03v!TAM z-k-Odm>qOFdQOF&wU-d57QR&U7K`s7E}jRmZ-RN>11S{d2=SKu=>R2+lPK>h!IsnH zoRcVl_5ZOx|ND`=JV8K#l;BCFmj>=b%0Yp7R?GRp7nif)owyxLP_Kr)?fenEgZQ_K zA4D0JA3&O-hM9RK*Z*(4CCafvbMmf7YP!C-9EXG!qF4SbTuGQzcdujOR1+vcIs#|&1P{Bv=xmWZSKm<>h`OP?z(GWTmDCSYv#ur?&A+W;&zL4v`1$lYdIV3|4CZhu@vWsCqjrWHHtp!7IrY8xuxA4@BK z@(ERW%Jxm{6?>4$2$z38ZHhgAbFp-AKym3{Dj3kV{C|~wby$?!_Wuzv5D}!MRYE{g zx-D?%kS+yj7@DC|5b5qxx+MpO7^Ox@X@wb(9AFr_^Y`NMoGa(v?|pukKX~4UXLx7r zm7lft+H22;TYdfP;gL&_|2*|D{rD>*+x@Y4JII{x2%p`@+ZM+{7Oai}H%Ka{7`1`H zT?`CB74q`Tt9Slq^Ds$pkLYAXqOZILPLcf$7yf*Rq6X02d{e?- z1bM#j2FLh*#^YaU<)k2-OF? zOH`XI$#h_rRx!J04bC#V^qABzJ0n0h*a8^;aK*cS0glK%t~tpmaD@{rAnOjSNeS7q(xt(dsp&Hn&B^mCxbd#1d7m^HzrQ&UXw6jvl%;z zD_*y~@o>lCHB;7i)0RHENURZts&j)ImE;&lxe#yVdg+eE#I{>O2W4%nwd!nuqa~vQ ziuv;uvv}!L-$mNJ<_GS;PWCO@c(=<060A#Ex7?jU)Pd{inr#4nZ;SP<=1=noi=WZH z5@mHZ5z9Vpb(`=u>N80T(5>@lvi$e&4>ABQ+!6YuehHWhmZCEDL>uOPB|N1uWbeTQ zYJ4bLDX%1#)lqOU$3H8nxDw%CX~5^_q1?q9jPGdc)s$v%Vy+?$b{mVXFF$(c(P{Rn zeMT_F6UpP5*Epa;OPB>W7=7xqi+PB8wd>%BDnGhouzNN5zQ^!r=^*L+PwXAU`4{%? zEJtYdjVeBB*eIlTf)HRdvz6Xx9I2uH1R&QAmz-O_+bk@R=oU(6NQAcBmRV94c1`(o z^$9bzszJD%qQ{H(-Y~=3y%SGo7LnXdzk~^cQ%lySoiD_49_*n8GJHA3iegEyYEH?D z(auup`8zBRX&mdK4PRSC0u4+X*~gxcqiY8kpO`~ZMYloeOHSUI0R@?PLfGlDkT5H9*B0>X-togcdzgZMdF z?{a1ehYEOj!?u3ae)50Jkl3!C=zA==JoD=8V?PbUD_56Kfk$`rPCT1Dsq>SqhSa+| znM-jQWV(k`f73;U)~=4kA&bXUaci&LrEq+?I=pu~k?(9QvlJgNb}P^^VBLYQleGS9 zEbM2UcR3e~Z~cc@*>;9BXHj;I&Y3`eM%QsNDs@Xj|gg1_r9YI z^lvVHDURTF#^k;OdI!3o8z`@nUkjP6Vt~+E~ig0Un(1u;RlZ6 z(xXO2+Z6;Z7hmIV&zJN`bRxDTzz)^)`$+VTytVq?79XywGWJ4pVYl)&I$ihs!pdC<`Y`j{N-0DAgytQ+ z$q$h9W4gB@y+2C!`XicoOm7jKx>hiO$~O6Hc)sVo*Jow1U`pryT zg1Z^tn&{$qE+qZzY&^+%=e&M4&uA~M##UIJ zg2BIT?}M^hTN8FWnKkn@=?mKGp2=Ue*S61F-uqQ*#F_XMa`)!1;UOOYy|9eW@K5eG z?+0d_?zY6u{#636m~Op7qA`GEdI|zJyXKTH=KIV1%n)8=tn6$V^q4OM(r!T{>0iZ) zKRY^}^{aEd%TT!-&)aj0P*HxVK?GW=RDNUG)ZPD<4{WbK(kG8?j8Lgeq=L*DtS)H7 zyoU|-?aSrnxBDnE2 zlBeIGbk*%gKs}%P2GzKm(Ni6b5iGE4s-Kfy(sga`Y>3Dw+iuY7^|QkB-t~=k$zD&V zC;ODck&SZW_ipW4-oL#*1&;K+XKBB`_O{+Teh}9t%%u-g73Apbbpmueid7q z0Zc_bS-E>3UFp_-^Rmr_X?!eh-<64d)|nu3pGVGT)8xY~M>^}#;v2N3I`GHngHJz< z3%33Ew;_^rLxHnd6}tg4$}`VR+6bTi@qiPbFL0YZBQ5P!d*@>=f+cAg%lz2F(MwA5 zd2_|kMQM#|L_VVuDn}G^B<*nV=1V9yMNw2{CgJ;FV$u`uN-1PLNz_vam%xga%FfwV zdt0S{JJ45Wa&+_U%I%(3OCW*ipvWHthCmP2$<|CaZ-iwiECORd26qw*CDI?<)Sf5m zUlm3Se~Ef!Jsp^a+<|IumG10=>!oijDggDq&+O|g&FJzmSxks*!P8c%p)zd_T^0%W z$*`(BHkQd<=;-Up50R~9ewl&1X;s+4B0X;eN356?7f>+`Dif}c@BbDL0or)n%6u6Cf@rr(PC?6`pyRCjWKUf zRNH$(65>xVIeO;8jrUx!bz!^lW25*6d#*RbGb<*{P4*|GW8X-mQw`X9@aK0p7i+`t zQv%uO7aIIEM4k~|eUj)qwv%NT0T#Y%#_;2^A4B*p)Mxtt6ot>`TJ30mGKs)_wVBy; z#p3qnpoNwBw+2TW^irPV*Z>&;NaQVd?4z{hvKdGFbB(`S#QX~3fI zQHLj5WS*R8AL7=zH@){-sxIF7qE_EoZQNsUY{c4hysye5i~M=vMIo!ut@0^D&RjtW z4$W7cTgi6WKF|quVZ3WT(2Wo~6cdB<7knmynS7X)dFK5S9kuS#h4v|fwa>e(`BSDO zob2n95Q{5k=VSyXXzYt?^A~n$9xk~u++m^lFmAI#)~BE#LbiJw`y8!CD>S@cTAn!A zMb9B?)S7w2_C4z{l~S~sjEp4<`wfv|g5!eiV#fqBE7|85c`^u>NFfu-MPoe24&{1N z*gh3bZ6TAiLaa>Y81OZy_iJxJ#-d36>O;Q0#+~G}O9vZy-ok;s`7!2u3|UO)Btee}XaAC>ej48VX^F(J&NM zfIXd|8j?Qj|5EXWHcCic#PHDJ5hd44y4NnOVMkG>z|J!gui*H>SQb*ah2?4+a2dk< z?fo5(#(Rq&fl1MS8t31?KYE-M0y5l|jp7tYdtH?UDE9{=Avb_IB;><2B=$cGzZ2E5 zzpfSli`Y4erv$ zF&N3UVKQ+V5TA+R<=%_A;iTAS3NroPj1==^R!DAOZKuxstP2OL12r1Wko5S6t9Pjf zGP$r%_y^MjZ07_u9c#o1I+N~>Ha_{D85cWl;)Dja8e6(IVsXczMRKdivFsM}eDh2$ z_OZ2L<&f<<%W3r`g-8LYIeVs{04z_4_q5 z4^^dCoZ3KRK}3FM&#~Q1lAAT~(oe<03zkp~_ z^vThmg(ul#@j=!h*yBX{As4o*NBX^-{*Y*2oy5k4)dNBx%kdT`Q>fg2vpL@1?xmxg zO9P|F5?L>8A}TFrckC;!GRw=`+4P6ldn zJ6+(q8gXdXf)^I|6Z)hkOUwwnnDXGpJ1ZrN^j8VkE(ryV49c1)>4;ON(or4$&BZ2B z51o(P_UpN?`TT*oy9G0Ms}K9R zY-fpZ9hkCe$!IR`7&|cG`TPUbFc8rK))TI%eVLc#A+p;2*O5d}Bd2H$8G%TXLd-2V za&6;!N<|j;%L(9sotKm0Dyg8+*TbDxCV5%buezAI$o+G2{2`hY*rPJRqh#!)Bk)gW7#)<4@Vayz5zs5egZsKnjE8wWVhHQ929wO=QX-J@Kt$r5?T zOI1(D3yg;Lz#xe7Ecgi;P3n8LSGw% zGOIymb2C16LQUGST5TRasMv2%RR6%hGiC>VGQ_^vrkqWkKM^ST1`Y98dYp|mQ+6=tQ#&=%x&$b{QNeuylVZ=!L;}|pkOecJS z>upr5gDOI!KK+}^n^pj#*E*-qs3Uz_VAlh>w4|J@PnqIg&MySj=B{gWxUS4(7Rnkh z!Is)IhJg4~Im|>YZQU0_=4k{b;sjBU2ly*f&08o_tQ={?{3^}Qxj(WMY9P=r9X>7` zGixy1d&R?{Rr?egd*y_0ug9$VT}I0N+=ei~?Hxm~i!H{4vgmdaQI(*Nc`%l`yYz2A zS5er2frElDY`8X`NmV5%|4JE8Tj@Z#d%^F7?YdkW%_;wWwOL#4Ab)CDp&-NU!WHKRxc2+GYjb&?8g;jg@BG4@U z@ted8q^f=1Rp6G6zk}4zhxd;Fxv8*z@tuE+`ZmXS&}3c@U~&<+HP>`<_OB5?uO;aj z>~V1W)?~&-3qg#+Mm-g78BeRREUbD<1mgrvE+4-l+Nv9F7ln5%*1~(<+wz+*{z7kY znRQ>T$!*q<@QjkhD~AU07wA{%)W%1Ghe@x(Q`P8pP!zP%Xxc%&_ZwKwqj#Rux;LM& z8L14d6-iiJ@gKNI&j@U4wNmbH!P`-3f@BloaH*ch65sMwKe2 zm_gI>Bu{}Wy$-N!sN(oX*()FYt~hu5DG*)ph0(kYQ)*N;bvN$jr8-$R>Y_Q@-nP^z zf0P>Hl3RL6%b)ulxSIrgOYtkm^IPjh;nze+a{AJIw@j=tfnh26cO>!#=wu^4={>{U zEvwB>lZB)0J~63R#J%GvqLc)NjS$&o_?FOvKAWGO4HX53vv#;#z^JU3;(z|P-JYbI zzD8wdQ{$x>%&9g0N+|b>-?6^*EM=Y7*cz+Mj#F%c_|pL+8k|X8KRlGu|G4R)a(YeS zwvss6?z>`<{zCm5)zP8dikF*t1M+&fhG-`s+A<==GHS=D@+;rh+FJ?@nTSeVb0zG{ z8lRUW*H;JA?b}@dPQ`MtXZ=FO>M@z`u?>sgPdW2=21is2cUnod&w5S35{Jqny9=g8 z6^ok>#@=q8QdZr0iQax&A7wUp2QTj3=Mc@~iP!biiy5P4YPYN+&~_C#hcly2c{3t( zQ30zjTvZU%QPD5rK+0&92mbw#(|4v5S? z%Jm1Xz_gh;*U6Qwh;o8EV*m1P*&|}k_Z1Bef+z=`pW{!`j8_zIEURlr2ec| zHpiobsh`#pbVVfJ%=A(=qf!usg!tC-73Rgf;o`aeJw)Uv;K`NuJqj7-HN9J@%5@aI zxfUk(M`+GkJR>T-ieX#5rQ%z=A!2F#*2JY;_xl4}e~s%nXaElR7DlwI!DShA)(<%P z9wds6#wtXZYx@neipI>#!wAD*{<7$?0nMtX1H4|{yvXBSv%@B{3K z>fS1|-c!DH`94VnPO$oNu*=*NC$jdu`x+vuydZj;^wMlvs+DGwiFFim1-pXnUg_>N zJE=S7-<)siOI__=PF?Le=|wBOW`TR}3keq7-C0Q?yaH|#IGR3m38Ecsbo;tob0QXb z6Va#xQRiSwB%Wrzm0e@L_nJL=C(xp%xr*uSf#f{ev!eE(3@OnSscqd=qfT`JX9j=v zus|ziHFGAF%};6&H{|fbWJT&oz>=Kr9~W?NuM#mx`TpVeaIwt-A(?>oAFZP52tLRZ{$e=uvnVe7bqkern3*!<$0ddl##NV=Nc+|^Rhriac3TbaH<4#}STK1yS}--bgPjTX zYQ4r=Z6#fGlRO5=tXBE=LEb8DJmn|i$wnqrARn}bHz^&KW;MfOv1V-mVnB#KJ!rH$ z9JamI0MR4cnb=EMJJFpWpQwU(xXzI2iV2szq{x}kFG(>rAP_AuRqrH`w&5CfR-{XG z-Ye77mouw+Wv{9a&-+G1F?@?X`47K!+>O=D3P!ZtjGIo1R4i`D`l@Fxs42hf7c+ly zHL1k64f(|#>R_|zFKg{ddzsby^h;t3%jqaoV5^;Av?tI|=mR^_9^*WPwM`vg+c&jM zbDeuL@8x;$w%#JjoC?HcMVWD(^w}4XeTT)a`qA4}pDk)1;@x3t^yAi|d`JYaIOx_O? zl;4+r%_?nliHSAWU{k0}Dg><+f$unDc?0e#GHKUMJz+iOn5PxJrRk+Ki)g45Kr}A( zn7t%ml{VI;>FZqWcS6cCg?2Iam&n+wdi&&lvs2V;E+xhzx@VZ>nt@F#^fYE7E(n$4 znMf}l$~7Ab_?N9-z}Y5?O46NdPEJmlqbOR6aqX{XHQ(Eo$-tM%@HR0=LtVTlgqSfM znf%RgM>7k(T3_Cm(O0Jl?hg>j@R>KbOOHPuA>yw^zgmK_Qy4hf)`n0LF?1~ zNw4WwLPz@)2LcStnWsJM(7;viRhg-6e2T-~-QLtmD(_XpW-}C;N4S|&k{|<#skGI( zGWXQ@(ndpm{XM~CaCZ;wCbO|Yht7s~acf0+n80vNSllcr2A!liYEWd@v_V;8%K`P# z8{!&uOv!y4>#)7~?ZYJNsD=gZ)#ofxs}0jS%kZKq4PHMByx>iXFS=a6t4az70}u53 z@o4Z^ej8NlJB$hE=zHiS{%L)z^5Ln${-{Q;#87ZQc1|mfkm!K)VsG^kfA( zWo^=DuE{D>2?LUC;bsskrK9w2+P{Q?F>cU$t?2Cy_lZ$^6F>M4<$Gqu{Z zX``#<&KnvW{Y40B&tWlMG;VLJad-zVb>~x+c2im}3C3aBDq+H|rf23Z=TxJekf5VJ z@iXA2tMBjxsCv%kYpwT=fg5`H>Z-KxE`=_mwC#BWJEF**kweb+BOmUDmzEy<_#2=5 zClS2ocNvtE5~nCT)BP5y3J=1S zYo{lfjm9?3nJydTr&zPdH`zWec^)jNKb`B&s@9<=m6F4*NQzQx&I(4JVgbYF3a@UY z@vvWQIXI4d7fWCKP?s6`usyA2S3_b-dzZ~k-fH{CYPS%%F(!$ zKH9oJ>W#Gdx>Gz!>atqLw%oMNF?9@Wyk_1da$TXZj8pbnex9NZ^3)ooyPowXX^&OGw)xD> zsq}qYm<919#ASH@@%@LsQeLZ6a_{zsY1awSA#tcjx1TG)(C2vFPb;o=Q8H*W#ESC#^bK!0M%!0Oy zx!<%@j_5@K1!(Rq0y>+wrR4azTK2c0V=JGH+fE8}Ftv#pG1Bc${JQ>HWgX5`xgsa= zkBxi=H3b^qLCzMp8yZebasSrd;1G6M^hBX&(OC7dvX2&9W+6xx$3{ANsN zl?7T?4Ri+H5-=$|a?OJauGTowQJ@_-q4n`fctqy4Qr=)XU8Bs=<&)=!-${efc5fmZ zza6j8=$c=*6*$x`{+(sq768X$$!*sUHbOZ$r8S_pNw0XIZk38)iewcljIx@kro^Nv zHH}M#x^Ubaf{Z6k5_vP`Dwef0gBG^Bo+02`Bwiv0KC|o5zzA$cv531-wz|F9L9yLE z)5J#hLQv+uc=|pg(YDTxiS8NyK56<@A_i^`oPBSu+TLc{odd1V6n5n>B~X12R*s(q zfTMqTK`9i#xRFvB(>jUvP_@fKMT^TvVEM~##XM!OA+hMbz{8E2P0A_V=5k`eYqJ-R zBD|=*Y7Z1cOc1crYa_PxM|=5(&PUl-A5<6&WS+kWJ|-cN8N0f+ih2qIX3o?c+d^^H^w&UCqsVJ^vkCQT|MiBywCxKPaLqU@aZ zNN!Htlco12!s0QAV0^l{BsLR1zql}lJQ+v!-t?XD>AHIlM9VifpRV(I!sik73ob`( zZg6EDu}op;y{Mfp_V$N!a=~u*9qL~V%){HUw{_aQoKn4EVsxW~^llX%da~HlZkb8c ze9xnC!0CP^TW}7ulQ5ZKP)?UxPh%|mvR$~;7%%@X9sJX=;ZjLbThEkvYl5Jw$Xb{QHZO3K(OP6No81@|L}2w*F9-Ad{xKa zns+~bx5jJdhe6jamjxL89n@kRkJD~bj$QA}?kp{>H$fw+8_8^fDR`oH>(D?J@$KGM z3}t`NOsh2BDp7$(7Nu1)mnNpv>6{C$V`ShNO;E1?SU5MlhCuWM#Sg=;NkT9YYdS2T zUE@r5Q=2AYtC4%PM>#?tNb%hdNFd;PG5ir32BlXN?7FLofOG!w4VKM>p!f`Z$|Ig) z24;znsj^x^M)YenlSg;-@F-}!jUU&;he7!mI+!Ikzw8T-aJqOU6bd`A3k}h9+ zLb2^hRjo=5lhg|s&Q9{+HgxAZIgw!%3a%sb8z=ol@Sk;;I<9t0p^Q{l&=Ki34256v4@C+`ZA>v|f{<{wQOCL8Ep8;uaPhSt_bi zN#hrnbUW|OZa3Ha;HfE;=}X0R-a3j{6^Z;Dq+aVL2yb@WXnbebZ9E%FnKq;`TCz8V`o`c=EF+fTO@WaVZjCFT;BM`hVh)p9T^nRg~1m6f>NzsjQEq|yBIB7g6bNeiX z9RXd$1gl%v8a1kqcn<$r9eod9W%E-u$T+^vNZaqxT(<~Z41N6drTASpx z_?cqTbGkuk0EFi?jd_}fS(>UV&iI-^4HV^syZ0w3T{yb~kKUJt^56YoT18dT!)>}} zkr79lx@dH|maZRm6VI!4Jh@88&vV=qLuH{15N zvDQ@|#KJe)g5ERHffXv>S)PyCtlY@N9iu}mjfO_IYX*^ z<_Spz!5rSbw;$JVntDN=N^}!_04DkkqbY|2YGA3St7|FWc|1^M)^b-SvE_>zyZ##k zP(9u~`WJE5Nza2ky0HVqm(60^tR?2XI1MiE+OIGPT=qyd7Qu;e^k_h@Q=^Gmo6^U2 z%4U&r;u))g)1uSaHql?xcF4IR5H{OQ9uzIp&Db7`C-3swXJSK-FEMb*klzEVHC-#1 z@ouJ^te9{vG2>EN1-yQi#ZMmBD`1{(m#Sv%(F&Kzg*|62vp%mA8UUj|sLoT%{&=gX zx-xZ_Wi-a2JY}3*!u62g%mQ0`1M4$PW-qeD5O@&VxDNU*Uyd1RjNWa!&~bvw5N)qV zMmNCYmGao5Sg1Nugl+^WhZ!;tqNFjkJ4W5ri(2>aiom+r2iMt^k>!Fs;82@j8(SmM zAnb!p1%s?n0gaNUVl3{veR>b#ad%y>AB^F5O(l~|5+an+3^i-CxF9x$GSim;jgX~S za83(G-%&Wt&mVY4`i;%cz#iBMP*3&kApR|mWbFV@*=q7>PvMVEIrgbRnP%E%ha)}c z01xY#Pf5=~>Q5!;Z>9>g_4U|xR;{!eJ(4|A9vBdLpX?J&C?b1x0fpLOZPIVlRq_+d zGbR{sRO&m`&c~8(BXuw;#nbi5)DeMAJ0vk#OBLcp?RGe zopR@QEM!-=#^w)7nLCuzBsTn-P>9NtHrH@9_!DF`T}2e57(nt12S7d~3PSlQX;J(& z4;eCwX(TqLgM7$|@og5oY#4tF+fr2k;t?o@Tk4J{#T~Bo=dKN{KbYDc4n?^)+n&}; zwY~w!^OCqJpwQfCcs0;64olqB4SXT^bXJtmtt2N?-(?TFEJ?Jl)h$QDX9eQn!fTGE3 z0P6yb|AbJf;&L;Kd@X&6jR;^u(P{Zg`CKLOe21Qn3hC?J?^U|Bf(L1~Lipx#`J@pRwS9`~^V~uuN^X?^nn%M-4C)5G_lk7uru2jl zow|i_TNujoHMP6R=hs%h6kQo!`Q{CDX^^=h<+JLJyH&eM$LEb^Om+SHQka#I&1%Op zE_AWiSkkvfxo!!L$SvnitP2tNQL@{!F&iqtIHz9>OpgGO%kL9Fd%o%7;nx=z9IHVL z8Rb69YJJw`l@-|pj1#}9A@ETuJRr8InDJGx0jlSSP<+Eh5noy zO%_&&H+cM6Pv;d<0>-lZE}H?Cu$U(v^qbiC*zw2Un_M(Vl?;SX zs9NKoUZa{hyy118^XQynb9QxqV-+jW43lCj<6;LEIyz+QvC3~Na?;k<5#C@h=Mi}( zj?SA4&Jz4xGgs#dSaVr%nwsw-V2DjpW4OZN)9rKW>2Zm1z81QQ0K1jvATi`+*LP7B zqR0l2ZVw|RF<^(ch z7DZ>+rb*ZvAzHx5VWKV~3C`L_7KKt_Q$q2{)!_u_h&hu7BjQ{s7KChESQdtY z>Ut2Y%nvEx|wKwQ?WI5M2CoJ&SwMg%Qx$HmkPKcK%f}XXDL~g=_l&Qzr3vFpsx<*v8 zC`St;6vQ}ptmLfKNXBCiT8zanUAD2U7#S3j$ZIP!0I6~EjX3J67BAwp2}P)tyWYyz z;2D`_ylqeOwCk5Ab|!y@R%!Qf*+4b)HjS*n$PjL^L91UtEq4L6`d8HCQ;{+PlX%#K zIA=Up1zQ@W#yW=LFkCSy?LRnmXUMTCgMf~Y6Ul?_G)AR;6Ig8d^9ejLa~k%i$kq+ zX8KumSTwd&*K@bwL(FJB2V$$SCqqezp+gDqnPF@r_rQrf(OgXH?R|oBvvO~tg=u>a zrki3e4WbwOcQSv5i@#vAa*Y&x{k2en@~|YU28wx3P&aF`E_$`IXGOE-_bmAjzioid zQ4iN)nX^2_b@|)k+CnVXo2o7fn4><_&ZN#`{lKnoI{YQNMK6=7%dJ7kRSSxn$s0JXqCtb~UcHwJg%z%=(R|=nPTeg++YsLa=F8L~_96ylBtAe7g%%~- zg~BnB6;%005kU$lLTBn}rI|}c*V`?WW5CG-3ifMX-=zvDY;icIci#CuuyKC16}#vuD?kv;HS2pV6Tul6o38Hlsc6rD#%u37N^^7=d{Z@Xfi~%yLjWW`(iI`g793(zffrn#HeF^|6>LMx< z2;lsSpQjmFw_Dgx=88Un816m(OO*gY_@&@)Q9lTqoIyQ>&Zlc`E^Sj!Dh#{K1Ts#Y zcPggp08T8~u?At?y@6e~gU`@b&4^50_I0nrasqk@r_JXv4x?=SZmKkV@*o+7!!M-< zSaTif4e#~FW}JYS-8|tR&D!q`N#ln!C$X|UOH4#Fo=FYfd9L(v1*t|4m|1VAfmI$a zlRs@_{!KpszqU$$%yEy*r^Fl2UO4%=roA0Bt&ngpY~{G^^2U)DD7pOR%7_YLKW0_D7TS?m z$n?Yv(K#oFNztrgx4UF5upMt>UjIxf|HcRAu|TpQu)TBDM!cqR4Aki*EOxTRj)`$t zm8@e&4ud+=GsguUSq%5-$U7)ll^Dl>%V7uK^M;J+SU9-lW56Y9G-3*B2j5q=V3Wq{ zEbv37N%BNNWnI$sl#hEjtRu#t;}sp=UL93r2QT@q{)AzeTAs-{Ck9A<5pRnM(QBoK zsMu}v&d_9MxCQ-ZO-5=H2h>U51DQ94wriiC!~deR1GB=S4j$h8``or z-otlVHpaTdJ~b!B(XU34u)M9a(#tp}(Lel>NrH`6?8lZV+!z;o^`N`f%2YB-&ZT!b zqfYF{wN#WOY<~y;zEWL)3e=XgUg3xS%5V=?zR|AeH&(bnITw<4JLVbU`4&7vjf&L=74xkb|I3R6X~ouZDHWv?-)t!7=|+%a(`) zIH5X~m~8Nf=OqtHeGLd!kk1O4bCH(|0Cbni88ywow4Aq-qxE^UEP18m7TO;1nsM&D zRsJMW>cOQT&_Fnc9Apq>-Pn|jQ>BaHTVcNiaXHlLI=750ccA z6DQT6ynot#A3(5*USem=kYgf-xIDA%2~udg!FyT+VZzmS z?mK)xG5}u^@LFfhjXK7`!`WDNC_K|^CzQpbr*dw0`VaNAY1+pqycb&7}9e$V|> zaJ1?9f{h6|pP7%2v5WnO@%_Cj^9Cu235n$%o@q)?8Y`uQtRRIjZO;FKUQC0y2t;pCjP+PU)4|FLo)!T5lq&Vsq28wu)8jIlMIw##5xmS&Ir3cYdu zUq0{yEY)?inpOQR6@ID;zU!f!`wvI{w^I4_;2I5p(+*I%F6@vzl(pB4XF?3v_|{@X z6YIXlG*+lGf$2Oy27#6VQT@}mrQ(3ztN;Kp(6~J43?O2fz*C)ele7)3O`(D?wUsva zmXPyS{x6aEiCo>1n?_lpGKANUYjDT4q-866x?=58ty~q)^Uzcc5S;Z62Bxts*V%Li zKb3$C7~O(|?Kl0)7|xS;UekWPk5V6a(Sm8X&LdTDHcalHq3v&u{QHC7S&hNQ4oy%5 z%RxSTBykQg|NF}0KzF;XYF}NN{D@se} zwJ~Ssvi}GgsM%wKPv3YPwD$263IO8B>$N(u{}-dr5%ViL{gU9oC|#@rd}}#*?Q?&w z-NukC^e8FL2>nhtH7%h}KuVMe4&3;4x!Cy5PSRp|oYHI)g6!~=kRSz4z z#O?Aml628IItd2{tYW==@3CZ+_+JI~(@S2D&MU@$e?NCE;BhPPFe)E^tLPzh0(bsl zcvvr`|Nf$XEV+{cXqahUY?BKE)f3X|UsIx$Brz~-`lb)hLB53qke!P%|I+vWBnA%P zRpV;}KZZ6eSy*@H*7gR=OPJ;i&a$l42-MU>J2i?GI(1xp@IUB`<5|rwzg%F5?;pmQ ziO50zEZjTAI6yeNZL~V5|NmbLtYaAH>MQN2*-&Mg(@?a&^gsNsUo=2dM4NhKGSeIY zw1@ovJ6F!VISMem9)7AdJ=K3tssF1s_-UNweacX|P8(&j!gIYa|6SZ)MF1a4u(WwsTRsI?AX@QPjKo`%M$p{pzR;HPQ5ekEj%^bXGxPt+1bPgw!_ z5~fe}0O?668_u(>wah>(0^E|f`H+`nIJ|~tiq;bZV)tTQO7+#|-uV}u_a1*c|2E)v z&3%~8u{tp0g$}AzCXJ>;S3w7>C9*_f-OPxRmU|oH2|^+SF_hexBDGC}5s{H0=@VIA z>(0$0!zvngz@uko*M3aIe7@uapa;Z@k95hQ1dAe|1r_aRE(%a)EHpiy<+Y)DKs@0M zjD17;fmcfm^l~vvKI|zc>iF$UAi59sT#J~XXT?v_bXz|86X#vx@ZR)5rUY3!!+e~a za`(V;FD7nG!NBnw9AA7t_nf4dPL>OkB9&<~}--yeT%DR8Q=4n(l2y5nJ-x-!RvNw%V6a zgGH<{97u zjE4{5aD~^YEzj1P2bRn4pCwuvn0nuBzXxNwg&G=-lmBEZF@cPrsDwy4vF9ae8LqTp z_P&-7X&*r_YB#(z(AmMh;A7JRsGWJ!#5WlvUZnu+WwXwZ-ov0ud+xH6ui7Q~-jo~$ zPean7%!cO7e7^dxym!>G^%8M%Kc9kov0-sh9rT%R%wO=^b`IW*J}||p|8~EfzH>43 z)Lyt3zVEE)>)gO6*T5QvhtCv+u7?Bx-9|;`dDW79BgdZ+Y`$r=7UXu2rr&~O_zLNy zMYt6+;^}KR#@EMp?ga``E(SGxbwDc96`=FK7&lP$bpfrH%^^?1toQCMYUA8-Txb;K zl;YZA!sQDHU!a)dE^#zy;4YCmzvdTg_ccp=6{^7cnlj3{l2Y0bhwT-i6ei8o;#m#L zPJ~2DzF@%s7s@eda+jOeN98BHU)jFWyp6FpE6aF#p&V-@Ogn!Avy zGA;8&zT@TPu15x6Hg)Ui*%=zoV~OU%d8-$&LEdtA?%W~29C(q6s^5%0b0yK_#EE&b zu5e@FBW{tXHh9&3{RL?LuBCnMI+Bt89qR?}HvznRH?F`K&jaXiuwS=6AoQWpUNvOJ z>PJ2lW}`!U*rKU`#2HYiPdkBf$Nz>s=9?RzBshC!&GIn-3;%LCj&>o=h0N%7R!(?ku$>N zl#Sh1%Xlx}GQ7vPe6IO6OW{VZXxosxGbA}cPVDy3i#7HN(n4{!Eclwm5xXbewy0hP z3Smnu8(IH7rxrrO+hHG-N}OfFKebAguon>LwC*h2 z_CK7EdeiF$?6z<2<6rPxVeED_pOA z*>~7dy;3w%15&M0^iofc@n3S1R<`&n;;FGV__DDZKTaoCcPk8Sm!=+^t|0T zKl1s}$TP#bj*3r5i{y+-d;I+gcT zs(OG4AD#v*3m($?eqtp{7MbcS)57oTXnl{D9r)?iq zm)eHSB+oY0dDVo?Zq9h|Gx90%=kf6nYKEJ4Ds`gC2b%e>Y7ZKvQ8dmp9yH!@zg*c~ zNZoGit2YaW6J90S7}a_AdvghBdGq+JH+^VI@!`Fcx#aR4^^Lmxbm?(5eVNW?lcdo< z+n<0WhqUP5hP11pTQFIm9H6fMR9{kG>y@d(69uu)ZTjU4;R{m>S2)$Lk|=YZ+ z?L!gX32|%Y`ruiLZ@8Si1=QNqe9R4y3y0@A&$%)!7CV>}Yh0o|?_XtGDGOW8bRFP2N65f$!^>=w|3Jt?rw5g7juz z_IoU2xMQ$$?kdG7xn=u)6?MqtMzPqc$gA*W4y%tm4_qD8YTH~n-&5O9&pv-wEVbLS z*Q1^~l(L?n5kE<*f0F^Vxa>(er%B^rWba%we_~8*IaG}v`uG^8pq$8Lon**oau(|v z-S}R8gnQI#W9q}@qW%7Nz6W-Ox<*a-7twZc6Hk4k`55+?-ZP%CGC54Ot`iTx7}heI z_@vIhq+wwH)sAC7X(s7Yxs2JTbhtUE)AxAp?l%?OpPW9eGQXMTXEB}|IE_7>JoIC6 zWYAPOauxm(nDavX_A1lX8TE3)l;NnMgF_c&S1bj8DGV)aI=+Tcqj_2DX7RGp2W1P5 z^@Qx1>;zx3ORLl3puR5&l}v7WO%7-dFYG%C<9r{w6@5`xsmZf~PmIE?)~uw)8gzI) zwmaCz%Vam{HXm&A^ilPajB6F>m0n4UnRa~Y_3v#|309HLo3mT6si_+BGn%EzlFd#L zu)()(YNR%n_Ni2HnN(dI3oMkcrncq1CRwUZ-aea_uJ)UyoEfU+a5a;TkdXbv+@{lK zHKZwNv%7P%zIf;6%&_{ZLbXZpz}y!f{dD8`!^;onc4QcWpS@o>l@(7D|CoytHWIi(@x4uuO}-BRLuY46fhS3-Km8+CWXJ>#!E0m_-mKDiun zZja?{o7_xil1P}?m~71226edzym$INzMaMpcr%mMuet1ZQ+H+u_w6KXYRzh5U+;WB z|H^q>b@q^4jkwrT*T#}!*mp5`zH)dRr8vF5waMYsbotYFt((=hZZd0Y4WH^~ooH7F z^6Syu1m{!S((Rj<1I~iVLV~gLuS+hC>~g(U_ay?NG%33Ho5nk~J@+5%_9X1QkpCdx zmzKnrzwWTZJw`I)1wTDmon;Ya5jeho{bAp1R5~RgD0;UWkIl0b{bZ!~9NI}I zi$OOYCa2wL*(3ug#2{s~9uk=}TwKsTgkAJAh%5*ioDwOj&LF)Hy542;+1t%Q@%Nct z*uTAzFAD-E-x6w|71GfT-u$c~>sl0x58*?%jyy|_Pq}d=8=cPW2RmQIf2yL>I=I~o zg6n!aPmK9}0YZwGChC%=va%os;1~mhibM=T1CEe@j{p+M&tq{UIuOcV=aE665DO6M zKljK1--y3gzz6Zn-`^;&gF)!P|Ly`G_YCA8cVpORp!_&SAqK92gq1}kC4p~cBS#Yx zTPJfnXC@M?5a7g3`==UCAP_z^;)5iq^k5Gdf864ky0f~h43CkW4YPrd-r2&=7K|9zz|hXcnI8f{O!V{b?{%8ETl{AxTc>}> z0tjS5Tw!5jW@Y&~Ht;AP;w+DXg}aHhhNy)NuxG#=0#NQpe1F~l|GM&@8UOX9`hT8e zXX9l3_oM&1^uHffaWZifv9kf@bQbszzy5jn-xvRRkdFmH`oFf~?|uI3EU?i6xA<6o zGELytR&GuMz(-OGQTb=UHy~w*KcooYAG*K45yuDaSAAURAdnD9QdIbvJJQx{Xf>(W zB-g^NU}~_IDrPiw_gz+hnwKY~y%2^>2!-bXdY<4Nh%M|DxVwp}n+C^~mGY(}&PSSy zgQ_v_$EiuRPOAd~@~L<^xw-XqXCInG(L$wdDL9tHz&CLH?0{geI{dR?a-$z*L4~oQf^Z)dJ zSSG4H*Ns2X4U9^KkJG}oc&EhU&jk5{?sWZ`6e0a~WMnS!86-~m-);Hd1L3rMCH(V_ zV}z>olpb(=!lLBTn1O$U> z2b4nlXHH@)*kk^g6jX6Wu)k3|nf~FQ2?FMh{4**3E&mnDA8h?4OaCjBzqJMb70N$q z<9{vXZ;ji3E#;qm-hbWq@9gw{-S_Wy=WiVFUrhO1JN;iw`RC~1FHDI?v$x+xkxQWK zPT6=o=Vh_K*s-2y6e&rY>a6sb-=IFT_P6_t1K!g^L`-PNcn@$|NvdZYrOy_Eu#+`? zCJaKdBS@e*cye5CEt;Tz7=@Jxfc7+5=@qYqsQ32Tu+=7^Qw{|>^_)J3Df2SuWX=lp zV*P)B-T`d)fM_Q;HB%B*^QQOFki`0U^OZ|}RPwh%-9{cA`&P8zXBJBP!M|6oB_;rs zH=IjsVmw0C^;n5>p7%L^JlEB(C_xq{aK2T3RP1+|Z*kQd_i&gxL7V+hm^9t*%44eB zOn$1~&F&0X`@<+gQ&V6cWpz(w8Lz)cvt-ZKyQ#GeJzshdOQ^X@aeX53a-3s;i;B$m z+ZMzMxHWhwvZvb3{ZfiC+RV!tV*A%L`sQ zdmi-AlB9RE=c(j>=^)UX;Z%QX@s-{S4~dDT`NHvj_&s&`;hP@lMfE#%&fSzD%hjX4^B$|I5yxz7(!!)eT|>vw!b{uL^R|xf zn?tuAu#LzxHe8);uJ6?E+VHPtQ8wUZT0pl#oZWaE20>o%-+ zb&z0L^XkIDm^@U56rIA`{&DP6Ozbklj+YEp!n&rf_1v~56w#_gJ0ma_*K)LdPgg#u zh{uoXdNIv94f01YaN5o!%JFVjbe=n;!i)ri6?&-I!%3a`*-p1dnmS8$Z)}Q!Brft3 z2sOWTlGs`INA3nnvou!FgYx#jK9?2!tcm(T%zi5Qu@(Nv8KEiNRa(? z&YyHbHLD&6W7ck0O)GIbKb@I~@Z;7JF5se{q}JS7zDkN#qzsM=Ex45`WlR}rAht;3 zTY%TfVl`f5Q`?(g+?2cn7@Dje!udgNQ&{%Y3bq*|?T@LT%>eE%BNK7T^7_&M~7Jn9~4v?tYWN z{+!otw&3Nuyetv@Vz948rThNkQRA*pF|kr+(^XB=^>OpHjtS-I`TVsmR>JUyR6uDB zHLGoPH0zu#ayya*yjJ4WzW5x^jwcedlHj&S_eoIr#4gSYqm#vcWGPE-SK!ZL#uhly zf9xz{+a*SzGt%9OBXV0Tg=&I+>dkeBfQ+LDpf`#wfU-`r&tbAOY-w{TrL?L1YK2>qy=mb4>cz z`B7WM`^)Z_6u7Oo9E|F9i|RJ=JZ49Viv{zJO+a0>t7$0%e24v!vZ4L=s^>hdjFPA# zxgZ^~yJhVPH`R1KOnA0R+IlCApk$Y1lbmUOSEt<5_`(FyZ*LuG+&u`<|^gB!6a5?r2~j z-2YfuX1Po=8g$3D`SLqTV58yW_2vBa_L+N+OVsoxpzk9X&%*o*tcq%La%npEodC;| zduIRap=!ZXHEjnmc^A#lU%NhiU%&x>TQyl{!+CEO52Gp6D5nvtyH;&`Vm(<#Z8Kd} zICLOM#`86p#MXS~-7e=EB#<0(LfJds^u5y3{RLpE3VV&CLzI)Albiy+L;j`fxb%^i zI;q!IDLiVbDGC&UVI8^<;u~ulWPx8-=y!FPt}>SNVhnGyi(o#h*k3^Cz zivPR1=T7aarY&#TuxNZT9qyXr;U{Rd_D-(gr3KH?XAv!5PI`__4I}(y731^o+v}5N z>9TfBr>0`8{h(|~wsE;%W;j|hP*LqMrBoYH@Fp5OoL;7c*S6y=Cg^%vxG3`sKGa*H zv76aq>U(1681I5*Rfo9%Gk5~A*Dt!8L<~`uY)Auqm#p}HyN|ImEakKiS?^n(S7N## zuq1kR<`HS*`=KqV6Ct*JHr2E7u3HmB+lvt^h9nQwiVA{bVBr+e+u$p#Hs-TkgpIB+ z5x`@6_Y~E#eO?lkrQ_4jkz|bb@iSHGz-zkMo{c+on_nnHNWVNPo=vHVCX(OxJNX(i3ULtOyMk}#d|OTT)19T$sW2Zx zauFYU;Wp=yOPsR=pb2Z^1=!aoG!BG`uANSwu!9J1WT}Lv!1XRS)P?~FIikYaAq$-y zS?g1U#~t1gyx3!C>nbzp%UcLp%TkO5@FvUU)p7H#=P+)G!^Vf)9P?vb3DP0B=Qe)$ zlHcZ7;V3Hy+m=j?DC^V2uA>rZRD4k(<=lhIUBBjAs;Ap_e$!RWtB3rbEwnDr7@LeB z!!pLru#D7`$Xly~#P4j#QcZeOWnDE?RMz~rgUzrlf-3h-~CmTUQQ3} z80Wc<;qlqk`K~;hu@EyGV|Sg)=D~DTG28PeGlcysXPd=>V0DOJyxvmI>1~z<1ruKw zNhjR#<4xLk81J}tYLwum4j}t_VRprZ~v0! zr!m~I+ny0dbisB#T?Q3w zS7P^-0=)BJ#o^wr7gOmhq1+OHvTU`)j9o)P$p-PYkuS{q zxL4oAAaEGzE1z8J)yi>Qt=K&mva2!#7?Rf;ys^X-dHQyOH> zVUch?69JD_!ewlXjpvt zaOy_dNXp})F3rZ&x!)iR#9qIu+t|q$ngL&o7WYmVVT-YgCzi9+?4yZ;q=? z-b`j-m}{3kFiZ2Gxdgb+@~tX8oTM7z+3xcx41UIeZeH(&2tI?(MR9*ibOt;tC$hvw zD~ZQ#Hq!otrlV}j#6&`xOy$rmJViUcRKF2L36*O@Sh%kVde3wu$(RAbIRTty+0><| zJYk&Q>-)Pd3crSpLAgx{aF<1H>KHq(=nP$CMpAeG-Bu_YrgTHF#*rGT)bc@Gu{Sj$ zLg}~j@{CwWCG5;q#u0^zEQ)&V*6%hksMAe(UF>(MwbhEIH=J$cuLGdLreb$`{>n9u zEQ>8GB$O~`ZGd-|4{ZKUMP;_4dDOFUAnYovIlZg^VSn`{0M`fiPXL@=1S8r0F^5{{ zZra3LjJ&`kXNm-7u~QFqLjSoPOJtYVPHnDJO(al7Hza zSj~ZOF9=`NZyt3HKrcstP5z)bA4;2+c(v+x1t22|Jcpozw;|+~#*&HhsR*=|Z;iDQ zF+_NW(stmRYk5})^wFkJ~B;j!M#$MtxagtengJv=H{IPp9yOpSq1L3h{kYJA zdU`ncZAtw?;O#n%$`y8pHoidngFRj*g0tOzuK1!UCtvWNz5|xUpNVO?$>+?IEW+UdC*-Tyrt8Cf7e-vQ`7yx zjErmi}Po-0dRDDq}na%Sgv~ z16V3{R+G2FR35xejh%Z?xKIQ}_{*l3Tl6L=8!lo(azsaXL=PY_qV;!O#5zMgLCUq> zM+U~hJ=AkupDCTtBsz|tj?8X&J(#*T>9V-{D6qFz3H#^+cIC6drZ3FH@~95&^Sgj> zYO3m)5QT1uICyuinkdNiM=?IAZO3_3dO2;^%s*&(I>oH~rG~Ts4z@K;pf2NY|BQ)9W8|4(O_msl zcg>GgCD~2kpM8^XAlt&indr$fB7RlV{CI32#C^lVmzew1B=(NEc9_8$P-J+;=VD? zBxa_bk^7q(dU9xYmY`kD*WetQ<%QIoB&UWC^X)8A>D;O|XIzn$^Ve6$=*Afqaif%h zVLQ#&SDj~H&kOB*^7nle@S?G@Fd1)kbxYy;A>xhssXHoo+hL$2_LHm_Wz1Z>zA-@j z%5WzI4C&sIUf>{M;#x;bLy;aKpd9=%dOUQTaA0LIjK%g=vOD1Bl`i_I!;SPDKVYBZ ziCndR7F0}gUkpWQNau5yB1y0OpG(R8(CS_ znDc8LX#=t)Y?vm~Yhglsq2%%ft6z38N%xIC_zZMe*hYkm=gid(@YYshuGt!%8he|& zP&Mny^C?mUU^^J`B)Fdm1S`@@U#=fxh^qr|^gb6Z)FF!um-R06bzeA0QG$`6O-z&? zg=+&Ew3$SjcmL`EIlMr-0*wQ%f7ow zk0Df|L~rnr#N1|G)P@Dp03$zY|9GYDGVKb8K;nR`!~A0vts4d-K}5Z1RPPxssH6dh z!Gg=G%mNG{Ol0C3i_sFg8;DUxCyffZXudwa?$sD|HqNCBVP+sOe~c+Jl0L1@d=BJ4 z)I>U$J>Wq6(r^TU#ifu;q403H8Bs2$+O1*3WQR$KCjh=ng=`e6` zjYYb&?evcn0N=U)_<^Z4X8v91kyFnk)4_QSC9(YW>fJUH(O{S=HM?PZ#B9wei3YM` zj=y>pDa82l3{HO~7V00QWm~)A|5gWbLKSGTc*BX=0fk4(m>-sr?3fthsqj?SY@&EO zIP&Bxwx7C*y!m)qH!M1c#qpI?y@}SRVlPn&A7EDt*=`~c5ATs|nEm99fJo*Edu z@ldp707%|-b#AFb`$;IOl3<{B7`hf}nf$n~aHbhhNDdB4qu8E*221CM-^CTZcNr^< zy32RAmUU_aCvKw7-Ct36dsz6Q6IMq$j zJ#l`n2gTOb^iv}{W%?+p7N{#? zp~nbr#%9x@+qJuH2-5=i#XC;p!8pgwE=}8fwO`vXR)h^xp02`YwBIbO&e5rNeY~-5 zRwBgjpXGa4RyxFqw{Prc41(Q-)-BzWO(<(bW3=_~?4DU2W=_ z^W*?wAWg6^Oo<|s=3B=qZiAw!9_+MMR8KTLHXBolel^OFC(swdN`r1JN&*piYHVY! z)(c8dO;R}U#O=nJ6o7Dn(Q!t~DcfbYcYOc|iz03~Ie+!NTGpn|MdGtWf!f^r!SqVc zLUgFu_k?cb;XF~*#N&BCL7&q;JzJh8O|11H%S+Wm9-HFPgU0@IAng8P=X;n!Q;fk} zw^i1coEHX;ARNmgHO(fCr(t&&rHRtkH0gy2<*rllEoV0pOH0u6JIbPXj1}^F zbv(pVr{C*Spf)Yg&O)*}v zLjySw@J49(0c-jK_!6B)Js{l!Buw&&(<9DH$IRc~{53CLA$UPF^9`Ry0lN$~1?dJO zb1#}MJ&|hMaWoIE-6+J~eQn2BP2vbndmbeeQr2Gbz=4A+;SBGZrSV9~bFUTsuuI1b z-J)P`K9rCcf{YEk#A8n3z7Sx!7Ie+5iuSgB?^bFc#>QrQUE_`TVz%eP$#13RDn?6_1!L+CMIXK&|vzu>XNCfBfF_OXiZzXIE;tVs# zh(D}<&ywKjFP}EQQ7Pd3lqgY|nL-%L<9!;tv;@~YkSCFaUM&UtB(K zwBd7evu7jx*hF9Wsz66yY)hVzqL}SM`hx$P(jWvE3B0lj-@;9eOmNlEJ*e7f#r5#z z_cx$y6CRyTsgBkg1QPHJ?o`di*wryXpAJ^xy9MlRlKj#Ny0pPgw^qwyMFisfBx39f z;?50z17T$V2-`MNRfu-G{ZlhxCZr4_mO5=OQs!u3pbi(4l!>`nP8sOp+Srf(2m@EXj(CZ18_i%P`M0O4Ij0NqBc zIL$vY9iiDEy6+31LkgTnN_J`k6?+GLEV<{q&CQBN^#)=a&^?le_wXFNwVggaRsqYh z)vp*|=){TyEmMkY+)fatVk4D6T@wv`>$UjJo0%K*AP@y|C~a)>-pmD-5ds7bwYTzm zHnBD;G5LC?VJ$(m$l(WND^{fE`_Na?{6bWLFCc&q*}fXsfG@9X7Q;c&Ck^BeaN8o= zaac?`Q$6{&=Oj4ex|hG?iQ3CvG>%B~-#bp3dhy z1VAW{=7wKJ+Nk1`K=^lWqpB7hKqzI<7tbV%gjf5q#(+pZP~x+2(g(`1P*5mF71zl^ zP`&}yVkINofNrt;VNngFLxEvi%6JZzvPj{3Vqg?q!$yuo?7&e)j)`+y2dLUu0Ks#_ zN?$06ZOvPUtc!2`+c7@8(xYM^ldpC>WZF(1Y2XQu5Dr%!oEJp zEI!_u)k33gkGM``miBoca!{Vw1mFNA)Wc<^xtW2(4Gq$w=BqOXa4tFOJ)3YwTn~(7 zu1>>~@a_@Cc*21P-{}KmdhbF;YW zvOvbfPWQ-v;q3`HvRVE3vj}!!@beGo;K!;vhoYCkenq}OTti<5>#uHSLjaJvQcXe$ zid7|S7)IYoO2jzbe)ZLi)1ZnllSit1#9&r2BH56$8+1}|<)%0|f!B9L{CsS~>)}S& z_vPKU?t1ZOZbC$is@O6;^BnNEnwd>pHz2Sal?BO09S`$t2Z1pus^55hMGU~}zo@fe zRtMW=&H;rC`d~5(mBmg&V@g;`rPuc@3nJ^!8#nAxgJUO&Gj|B3AhxbuvPU&H$pgTp zGBdF7T=-@-=I8f<>*PeY4QrmeQkRJ>r<}t{`Vb|zvlSM-+OwmZ`O0OP*zwLk#A0Bj}yg@ zn5foXtcm>kICG?&`3;bzwP*{*@)(M45-$-oW~7%+)b`r0L^m#_Pgs9+xhi-k4xU5pvi=kVD@A`ccbDGVfA7X&Z^E>(nVnO!@!ZcQkd&|sk`2^9rhTt?Iri3g~18# zn*4%2>8o+Y@RU)wH7-1yJcZMSL2cKvE{z%zYzs^2P&DigH+RYx3aVv@YKg7Eo!LDA z#8M>y>vkcO{bsxDkyseMOF`ZoI#AzmKAReEQk|8Fdh2EQKB+7giIuIHH0Pam(Wo;=P;Y`zRm|FZGoej%1PsUA$FXc8&m}Oc6_SryHVP+toSm z;q4|SBopg-<2A-Xs8MlR?St>U$a*}N{9@usC9u0)BR~;VtuacdRJ(Isz0c-A>X!|O zgmFN9RIz8;b{-W{={I8^K~gq*!?FESSIvG}dL9eO@J6utsfQ1bt*>}zp!-L@-~>8p zzDjbSV)7xY-(7)OSxy2Z#&?;1OvTR89&w_*AzwUR&bYk7(ER28A`&y95L6ZdZg>Z5)_uCcCt35QuxMs&%f@05JUEP2Z6MAKcAA)8N) zb?NL3C4%F-_i%jXKeR_&ln?OauRwt82eRZw_He{024m<#l&zFCv?^WtGRLPs>aG2v z-8*vDSK~xuRu{4}-iMze7&8@~wMVoR0sIY~*sI?7cM1mI$`ji!xuWMz)Hhsdv45P;~k z&X``-M}@qi`f@FSA8|qe6+4veu30C6@-GFO%{YhWPW7ei!0|gGMr&G6zfaq#iIj{8 zMjb24quKz>l7rSR1z&mXHjcZ1ga?9g0?-|@pi^nmTk@EFcZKnRh=53t$A-69%`f7s z84!mUqnr*!`Hp;nOp)3|2|cfArGQo%ot_Z1`ONs9Z%0_R9oElZ+AdvY&_Her9Z4F0 zgjIDk19wr|@`Z?@MvH=Fk6dQ9?&O{lkA_T`R|VU`#%vGnrNUm`SpFu;nJN9@?H0oV# z;wsRY@=5>&>v0rTX$|f$r9)E38aQ-UTa{N54^_ z7YG%4KmF}9>LQH^sw=7YUMs&HhpkLk#9Yl=5^7u1Rd8_H!&IY=3DbIOe1|Ln05SKI z!c+E~o=qP)%)laSDsBmxYnF7Rc-{!IEeor7Z)$B8mvmzzBK#^!hL8<)P&)w2LBtm* zB9F2WLc0#J4m?u<=p!U*8~`(7L4KiW5>7w99s7c6EW(#({asA23i0sJ7{;AmVfoXb z?&T7LwqORjj0@hEoE=SK_F|}HFEli6Bt>V>$Q2Lc7TgU$t!?-1EMbQ?e>k}ls-I&Y zY7)tJ(2Ww`<5J=INo1n^3|D4^8BgXU#0b@}z1dT+BCozb4ettY4jnAMrK6cls~v7F z02q5jx`7H$v`rfM@#|qpJo?TfB6g#}}26Fkb^Je9)1)sY5%6=7^w^#$6@`>A5 z)yJrwcVYd=2!LTU+s9mA(Ca#s$cBbj8WkmQX1*luX*>X9M2_~z_Koq=c7+CF0jZuh zl2phtkTCHI-m-W7Du&%*-Ojks39UE`jRC^v#7MT*Bxpu1veYT&>^9 zYxce6WUHbiHBdV^g^cJqM2IGk5n+sbd9f?+Ue-A*b>`WjPX-H*@k@72fyqW?f2GDU z34j!=Z^(Oz=+hy?x6lLu3z3{QMW?P>i3oECq>BYg?FDZqAT4u4!RAICqzA!DD_2<{r(%<^8*bh2g zhx|2o#_ASIFn-yD55BozkAnkdwF4?W?qHkQx=Kx!;O8|L2YstLA@@7gz{qGo9>wq7 zYMNJ3bbxWuSf>I>zFKinu%||;VTX3u`5PhX1$8IzudDM{@<4I^S|br6lp!5}$Wt}~ zdD_u0h$6@okWoyq(zJe!3K8kBDsEIYdGEg4c$`;2>d?j?tQhJaK^4VUMx1Oinx~?o z3X`0I+K{mzbxpa$L&knNVHPfsN+WjDqGlaJhR)cFyd*hQ1Zoux&Oj|(=IF}&5ARlp zBl@UD`1Q|GX=L>0n|#)x&8MS5;=y&dK^RCl25y#^?ZaO^6uSAG{+v9>>A;!Mik=(8Zn6MJy7G!w4D3VOJR9d(soB0@K!cP8hF3bp??t9=M-SQb29~E z`V43Smq)|SZCFs!61&_qPfG-U?zaP$*zFxqNmuDBP%nk(ICR`cXSBQVONshh?E4X1 zzi42T)z3piw4XTx`J!BGppxo;8Ll5eEgk<3;Y;@?fo7)R>Lz$$r`P{|ot9{ZC$WU$ z*(nD=DU~|ZBn|Jp=-TL6kWk!S?A$lUSBkV|L=@Wj z0rh=ch-f|p(m41HY#fbt62DywVKBgY1G?!yF%vOc5OC`qE&<3d`{#ZtB&Gt3M2*kIc<#lqgKxxFf@#n03`O z?pY|IKL!X=zh>05-ftP%DF;U8bSx2PNqQ8iQ`TUS9#1}ZAt1nK+Ve8U0TQR`EoTZr0=-|1AJ zqMkioD?IcFjv^c?Z;O5-Z4ub$`2T8aaL7Ep*)XY#ZPR zU4N<)Dycg=?iQ;~PO32|+y|R)9;*Ad+(Y2Z#eqtz-|9!W95|3O&2!^}rFpDeAsq^* zc(h`c^7PsM*w{!E1%y6k!fHz9cQm)C-&)RyFrTTi znbxdwm_p&y+;L_rPw|f=ZI9Lq8%SjM^H-To~cC37l*sXcb(AcK` z@$#}`Rm1^Q^uyf%l0Z(W=-S-+o8P)c3j1|Zs4-;X0iV&c!BR;5zg$2aPPZ_T1MXw_ zF3WA^JXgh)H(|>{QKU0p0~g;IRAag#2)?Y*40OQ*Wtpc^Ie;4(yFm` zB*XQ`jl+q|w2P7@Wffiw1==|Rsp0_Bp?P z$0dg&Si;w)GTh@|j{@z$3!MuQ1a&W5HMmh78J~@vWg+@67(Ax`Hy4sozu}eO1`uc6 z`C@MAonQw66kuR&Xd|@LQ-%8#Rr8qO@xNXY54gI8F|$^@%4&(%ji^-r${2rE%9wpI zboSAtrIU``a%6gV_t>G7tydd~EMK)y3g{`cHeO$I;~kOsDf#;GXj7L0Y|na^N$(?b z)8rOcR8#_jGsgVwe`nxP?sgN1Wt{<7v~s4m0^Pb|X5G*fibTduCE?4Y3YGjhq<;$^ z>VaMC*)CoH$)ONwxfq&bxJHP%+&JLD>T=4!2)~G_36^`knayVqnTxeaohI4Lf#zt{QD0A3si?cl{3Mtk>g=_xyF*8HcQ0CMgcs@$ZVW7q%e z32U{`8=&YyKViPLkhphe#2eVk z@F!q7d#AtbzoX~Y%=he&Yg!#wUy9-`Mh(R#8=2j?V>zR`H?XiV6AL$_dW4Qp*&JG3 zI_>_1r#!bS>T!szJYE-;>j(KYT?c?fz3}6HNkK+p?{-orW08`)8V}&$eSJ zzB~Krf4dV>I&FYNYBWww3}A?WeY}5p3BnHbZ}s2Ny_Ykha16>!MBj8n#` z`vM?KH{`4luk|PL1)QQByNfZEw=+P5X&9)2VcJ5doc2lQE7rS#Zkqs8Rurvdx> z?WU;%AYU?dLT_rsEgp+|^hbs5DvmL0tr}OoHoqDK$mE7mHFFkkll|CXb~IF58PjGL zOP9+`W8JZi9>%XfYYX~HXd5CxBSZQ~8mUgb)}=1{yWX`kqp>PRf1@$anX9{C)^g-+ z<~lPR+ER_o^Ksii?gNE~v*VVM|KNxg_nRXuzT%s2cq7#)nBF}uWR?;4LFUHKwAA_M z4p4yN&5;lpZj(tOi|sEQ5~HNksrmsr=W~);ZUQNDv(;Ip1irM7>0~ew{s!cr0;Guo z6mJ6psEghHVpoS^%bX|aVf9XX(Fp5586=rNp?oLF0Fs!`PK}ia`E#0>V=NT=VeDAF z15}&!Q0*|ADRLab;PXT`i z)-5~O;_o%eya?th0Ai4VL#N3<`~GK z>xGTBCXo^A@fsm7f+EBRov#5*l7Wvh;;xcs#OZ?s|>H z4Z1zClAy;7%aUwQ@kNA9A(=b~nKVQSAfejvXXc#WfVdaXyvn-G7xvG5CRezup8l8+QUh%!ocgJhSRn1ooMNb^L7rAWDos!v_ST#T-pDyUI0?XG&mwb!?N?v(}cNz5Mw< z4Lccn$nZm{)!56|si~ftsrAH4Ca!1mX+ONVIHiJLjpFwf#iKx*s=M#61sr9Y<6e6l zBJy?=OnnGZLPdt-4VwpsZBebkC~eAo%Lr0jK0+UOr%?WdBsste0)_bXUcF@;U#7Cn z23pdlJA7|%O&!Zk)g4YA?KF`^XCHaW z;{Y~H7F90+F05WCza_%Fd}M5C&gs%Z@A5f|rOTIb3a!e&#sFZTxr;5myAgiW^Q&E_ z%Z5>ItLuo-r~fEnq6tzfN%_oqOyw@_@)bf>iMOj2gFd$NA(D1@{fmGZCJYwhFLbe1 zezwoL++{@q5BoY)r;@Ll4On&6R??+W&BDKlL+w<_@U^8+nXdUhvRsw#J4d`);84mw zpmqNTbC8f5Z;b>&QQsajSTq{k90}rDtR6B+(BUljG(8ZDa1O5{D}aDrCPXNomP$uI zJ+eusTX%#7CZUt*MgaN8R4xqnxIb>^>4AhHNsL95*YJkk`I4s+a+J< z4nfDXMbbaNv@>TXp{te79mZ8XRe{ z`?Yl^9TeGmmX``>s?N<=+N{#RuS#`>DLpSX2-;Cv#rBiF|kvZYye>&Bg+c`_GV-Y z`CvAycXzw;{yKxCoibVEW)n3?Kj* z5tb=*WK?>vs%DeiFY9MtT(?*0E0_y z8zqzBr!X-pT+1#cpWbu(j=4KUWp`1z56%Hc5((hcO}HSD>VP$#0}H;yc`tz@Z83|j z;u4DtzrEyemoR`7h#MFQIDR<9Xrap|xeF2W8#DCNaowcH2!;DD)#4EJ5%mWQ$U)m^ zwm`M(Kl;iF=heI6a3cE%K0AAO=hnhn(!fhV9oKX-$Q!;ssPN*I9*_rU;v3`4nY+Mb z`g;x1RFKA$lQ3!d$aLd&{@*Ed zz?T=Hq1rjinzRbs8Yy>xecPrg%KMA{mPCvTM2~qz`-_1aFGAS}-lIEk$&(%48Rq*T zr69Ckt5x4&OdQQoBWhr)mXZ2PH_}SY!$FayYd0bQE@`6mu6>>8!m?tPkxnQ`9Gk7w zGok^*jQV**o&K5yh#GqjWe9lAG4k`?VvMk;-&!QRRUh%g4t7cbA_oiBaoDId8Wo73 zWPKWN0FCZ{9u%9_Ux#K7;3kX5NXU3#1>I*+-)_w%`pcz!qyhBhqg|bUIs}vs0qG8D6_Ah=>5^_% zT3T9CL6DYimhMKnyIFdHCBC!1`ui^aP=pNYN|sfmnI1KnsNOK_Br3;k(vJ#c>{{UD070ht0H68oP7+|J~+N|K-R#&jQ;@ zz=gcY50IausaE}KWXTdGt{UXzT8;DPh6J(VB`JOJBTexmb5#IhuQfY_E6s1YIGB5# z=8ZtpW~J3+R4wJzmhC1uqrBQ2LBbkwi0IR36SXfq4NTX0G(hw4HIllxn#<_NXY~`R z|70|a6%Vo27q{JUMWP*Y_gx&Ov9B}hRVvO{m@kG$Vy>AW{V={tS1Ca$JjW6APYKeL#@AGe7i)}Hj0 zWAT`mqI_mlvmpzFEu-i%n!t-l90i*iy+YX~Z2Ba~^kb_s4snq`=w$hpJncMUqrn|- zfSTdUbI+;t645SBn3<*eS_0Fk~`YZL3$6 z;WX%Rs$&d7MR8O%%CqG8cSZ5Qo<`RQ1K0gnjETz&6#OcsNzA^c8zeZ}n+!M)Fb9gh zIuz7PZ^{a&xJ`px`+q9_WEt~0dK(+o?_mv55B_j@Fe0x;2q;&j#Xi+?PXo@&0_MqD zu>U6cG}^BTB-jOsu8esA=6=MYCKUayT*MYgB9p7%RA5w+{xqab3d?RvQ2X=f7B192 zr@`qG=HJ2j_IlYQEW;YOFoE60Uq1h?Xd6o35`Q@s$H3U^IOlTB2+*e>;KkyfP4T23 zIJPV%^$cgM#h)wg!j2#_t7?nJp2e^|DO|++fu9m{DK8Pb7QFkKByqK#Lc8WMs*{X( zZG=K;fi~9dWM5s0>z|$aw3P$Xx^-*Gyq$f5rn*%$UeZ7-xl{Qlq7VN#N~h(rK>R5aid-6l55wQm?mYuyhT!jB zd8K{_e`+8RrT*AyYjXm+{JKbhV9sk?{vN0VC&0|3~9Dp_n;s6|!SLx))J@AXQif258Dga^u!%(FpY%y?1`Q-%yN z3bLxt|E`Y@;SoHSGvXOtOyAy_FZ$pR5}m)P>-8)U36Es^#|=`i6!DLOIKHSk!z}+) zrInK**fx$_nDiT}I6$i@OAH}mo#H`%&mq%4JoUEX&G;EM z23N+NSaryMmcQja_N5Q+%x&KJ+S6sX5%-IJTD>QK1|^v!jJ~6$*{A~F)EjV7w0LX# z=Y(3CfBww~B0sbwCtq5cdMv2{`YKS!PnD#^zOI{iN=wmiSq**%B{6jsY` zP7j1qPt2mm_xC<)0Br;jEx@r8HkY{pt$tsd(<}e0)B(A~#)~`~dxq@?scCP)bB49~ zqpn-IfYtuztzxm)AGl2YmS24In9B^b@%$PQl>@CLHhmW(hw%Uk@e+3&_}j};39-?L zn!op>HMm6?J6=slNHT3lx^)PVmLYtvlj@AXHQ;;mNm+(ffJ3@ItPc1qn?MW<^~{*4 zv4OBhEENtI?=z?E_6t@3Jkq3`00~sVxGdw8=sDLsB%dWB>HN)G>|^48*cUpM;Ficp z2PNo~5O^l;sQ}FjM2__54AB^9C49I_te(W6_OVg=BAX@bct2|4PQSG(1tJ`cmY_3) zjsaH%(`5fwTt~{btMDI?6#1cpqm#t1f^>55$^4t(+LRqv;lFK55&8amyQZ_;U!S{x zJOmXX;M@}HR9A%u@_??1uM*g?|C0k$*%-Y%) zoE+Fh7Ob?`@_LVH{uzhhXXBT1JGM4mC^u+dBk@RExG8RJI57#frLshNMgC$Y z4R8DDQ9h`(D6a0G*NOhIop)G0&7+2DRf8q|Y?Kvqu#2?+6p@S*d_&Rga(=u^TAU(= z1iWmin%+U|gD9Wd6TJ?n)Ae#hKYoeGvAeBa~Sw)Z%~SrQ3j~OZ(Ha z@eNcm$oa;haSD*-;%&AIfNM)i1RfE@*qS^;eZP|2XIJ(5&$pHUdoOzIf7!5H`x=f` z`$Ur{nH_wBS@}=bs~_yM|C56Z$m~JLz$C*iN@}_ylH~sQ!U0Gyx4{nqvN>VIGbiV< z2{RPG^W3DgzD#}qe$^6YlK*#Zp^_AM9-GW3SYzJp8{->5afu}#6H2m zk&+;Q)4u7>Q$+$i1gWl+e+vf63FZeI-M}LZp%x})gO;$>4!3Vq2rUQGVG2SiA65cvfhl+xz{?%82euJ26M8AQA7nrhx1KZduTk%%rL3hqYnk!IRG(uud#%6kh z1O_lkmM#j?ek$TWH*#45X)7K5YqGQv0my^Wf|LvWTj4(j1_>a55;jKwlVeX}jt=R%iGuSAS&+-G6 z6I={`OtX5}!mZl$jU7-5S&5@A^<>-kT`2l&nPqr24G0;GRQWp%m*lf4WO0H(;qbPf z5C6GEc_fIF(8*;?%Lt&g;($SYJnL#}@e2WY?-ja&P`cDxdN;^iKQpNWNqCgAn9aR$ z&QJeyTw)mOd1K!TSXG;<@t+rbdH_}hnHe2lpYOfCdHpBILdfEpRo%c8CY%SUwqoD{ zVg*>V^~q^01=I}HA;Rt60?;#Lf*#V*f5F;=>a3Tbil^!sY%g_0Q@j0}{uqT1;FIsU zE3d!WHZlNtOq!fv^~%#q$(Mzx|4BPp6KQJNylU$JR*PB7ByJ}7Q$a59G#C z66YQ*I`J+3C?`-Fd`&zIca#aNWiq6C6#zgM0#lMxvO5s^INuuekF%=F-PFGoYr3^T z3H@2$Q_n2sZuSWs&im+^&XZziEu(KZ76A890S9%C?wBfI8B6@ z-~G(_AI-)f=!LrIrl&&rOqVbyn}7v*8j$yQ^lOL;66LLcCIb@4^qIPW3@N!tZhDT+ zYq}WD#O@(M&MR;ibvw!+R7lSM)!l;v#%m~1-_?l6* z$k&Y?NRf#`}=jgUYbCjVRj;-g7GB^5Oi+~F-`81YkUfZ63k zV;>6)0?@O!p^FivaGfd6rtT_F18oClvzojTg1hR_$}KDh~hUdq44{eN(@RnC&o z+Jd&OfF8&fuB`2cy_{TfN4dNBKV~wU(=SRKia?jAU1R2Cn9c%J@lcI)gt-n@>GK6u z=2rD1)KVC6SJ-4|&HaR3drvAI2W7GI`|5#TNn|yK)&ac^&NF67>{#m629DjyHc{*Bd6W0QCekKBg4;fvJ2;#kQRpH`eUtQ)8E)eEA@$@%{ zkApK}$1_KAB&&T?v-GAb7b2Cml5 zdYLnGfYw4ms*gQ%8}grci9kmEE zej~R;qx)Y-hoM~ZFT^UON~n~;OKt1YQc!@gREQ7IQ}A8DU=L^@D!ohoIoWv9$GQVdcw1M#_#{9d z%8&$fN3(Q70R3WNH)yP_pP|tRiZcL2?gVMNzk@#wj-6@pauZq&Wf&{#rq;U+-*IH) z$ci>CwHRl^T#xITHYXi0&)+&gR6{;!(~8HEfVu)R5NTm_v_#6Ip{wo7v+#da%{XSR zy{TF8>&xu3&FZPKNdW`pSjFtuS1V7ZasxT0++D;nQ=aGNJ_9{65=b+ z$i>^H{X}p-^)<%^2x^t+ryzLav?Qt4hzC|co`)|=QREnwKY94gBPQG{fu`z8fT^E& zT%OwFz0h$7Q6Y5x&PEb&n-Qrki%njy)7-l1&Jpy3z{qm!WRcD|Kki;_m0#jq+_1R$ zZCIs_7}`Gk5>w%ch_BCg*}oTV9TOljt9V#+2OYjkuRd`1@~e*29-D(U&bZ{=ZjWUi z(lD7FBlRaCQHI0(dsJe;8QI1kfe0^t+BIPSeh{CI7ewy(B-1}&{%v8P}pvS|T25m71V6C_ zX^O+$|3#_E5JdJ|fG%u0Xo2ERtQ`*U{*K(Y?PVCr9)^%iTTF_t5#lmgIkW@ zftPr?>ngeB40pd?$?2BYee&WG%nvqE(sX0ao|GD#QrdL;(sO+Wouc97z=>12o8551 z-TwPMh&p#4vh&l580d1j;+{S<&-Bq+@b^PBk{he8ZhDD~>Lu1n`T_igxfrwC@?msZ zCO;D#IVS9(d?i4~JPU$?E0q*a|AOM*}a}cCS9}Q@+BTD8%YPX2e4ndHB z?zH2JDk5Pl!ADEVqk2?t0lK|E1{y)(8EL(>!INvQL~GuV(e)q-U(8!v z^mu-4CsSAmKdyXzqE55YW7ITr@}&ge(HIv5&mtkX}~u!fIrnm4rPdR z$Z7N0S~%FTHn&k=E{(b2BP))V_facjomaLQbPs*9+rrQb8;&(s$YRk<1{JRdDpt%AykVRLD1F_4= znI+XiZQr_uZd2j=CKxOio>2?;S7zFq%t)9lzTKU!_8Ox|42cG8$&Bbzf75b!sp;O@ z2l+IkLFNFt`LjBJ4U6Jjj<#L={%W`jE<%{{eAQ24V=x;SQGbyRa722g zKu@CtVt}W2ona=87q1Zf3dFI43-M$xnSvAZlO&;TK3;Lx%^3*{i}HS(1C)dv8fZ>9 zCZP!@JM!&$%Db^S3*(G2nV!I#Knx=9la}iISSs`p4v3@aY>XHw>39av^KoZsfjeZj@<}^QWu)&6g$M|=$~~U{AyEA%4MBf^Ln`* z?}g1i=sNZB!QcSG!EwAF(ud6%gNT?Bhq_x1a7=vflZw@IS@hV_oMAbE8yKK#m~$Q^ zTc-ouXjMDckfk-JFqQkQ@f)u#H@_>F>$9ay>XEQKDBuncL_!oj?h?$$$2rA3B;GX* z2wsPG=bR2V8Tp|_F?j0utnUG17v?*We$9ynp0`1j)=)ocIlYE^I)5jaI8GLh94)#- zEuJ{plJUedf77>P(u=A%(GQ5<%&_bLgfsSf=7soePcBZC46nyp zU=0%&d1eMczw`nDD|evEyo1Qav}qw5752hCkH7TwZjhC3W=k9D#|QGi*Ymp%MQiL9 zbZ`9xO9|U^I_^W9!i?Gh>R{G`g$9A)f=^VXwX2_rTSLdy=~Zmsqx5e8wyLPyYy)P1 zshld2g2ef$dKLO2sfUGhtM`~uUk4yic$}R+M9P=<-2ZZ-raD(X)5BeLUE$R0rr^1z z?h0^psZJi)K<9x!cFKR<_}6s6G5NAwlt#J#q^Hj6c@oSWv4TVT3Qc26YIfXe!QK5- z8*;5VE?=_6=QyyQYI)amn%CfGXx8`BZQr{>)@G@Sec^OE{oJbF)9*K-{13D45(TAb z-LFw1tJ_w!vC{Z2DhpkhjlcOp@nf!FchJOI=%flsoZ@tzqfPdb=-M>vseK$`K1!wI zaeBE*8jxA-RF10_f}R7Z&fy!i1J_#Lhot8Q0PFPuNv4zUy!R|nXVaEWx*5K|Q9}f0 zTSdGip*GZxbRq`*57nS|eiuU>wx3r$=gc0G#>>vc`n(RzqNl}Rd1joiDHu~O6I}L zHFGh1cL9^VWhDjOmB_1Hjz<@($(ep!3wcrTidMWCc!J~QvxaUcso<$zHKJEyq&5tmOv%2N%hOGMA#-*2KKT=Vt|BUCI4V%5qebD7qMhfGFB^bfvqyZ8bNKKoLhV;>3mXPyIty>ykY~^@ z<8^=%3U@Ld=blj_x4KU*0iM}^a4vIm1`lA z>V?>emEin4BEpp?$b^@M>z&AY-4n64X9dJ7)@X?%hHf&;EZy!~pIg8+=p^or_-S%S zWTRGsk$fBGDY)rbn$Re8=CVzXT=7dWGOpXldEH>*@Vou~MvqglEyr^^-!B_fPB1SdOd!vX4&&EF(m$y zk<^Cc0Uh~H%nN#{Q#dSZ!IA+B%c1kWt7pdr=J@O$e9eX~6`kSs&9}4fZZ5vV58+Cq zT^ok7fic!5uX;M(IAW|~@Ld01x+=90(KC-j9# zX}goS9TAC^O;P$1^cLcM9sv|Q66a`Y(Z}}*u`R7_yo^z7LGN6v`a0YdZ)`F{ja(|S zDvVk`2_{xASf6iK1kt@kSW^|!a{!BJcy3+bH)6qX%ixV^Ku+tx__XF5>s3x)yWpz( zVGEgo($B4NHF1|b)%1`1*Ql%*D9!Ij?I9vVS2#I7u=d9E=0irLFt-G83`!R8W&*MZ z!D(MB*)$DoS5cfL?)Z_ke&u-)zFIU4SgOW#f_9$*#zc#l+ANj1S(W870ec(9)&>84jdNLsI z#4^a6;EN>SU^2TeN@ucHNGx6g*P3<7jqK^s_J?k}^95#y_)+Bf-U`FoK^ps?wU4NU zPd!G6H^!%Yugz2_@>vTvm44FA%@(Ct$7CI0YkWet5{ zlZxWmt?tLIrcu>~RMsh>9T5Ir@mxFV_WC4jLO|OpX_2VIq)fiv!bN3U>M0K3QCoG z+zajiKgf_yD5pZ?eoiTK%#v2A!Mm#iW@R!ua_5sDRVH=Lua9(P4j>^%t+J(7&#C^S-#xo>Ax zWRY9_WqK*nZ!PluEk&Q)a_!N1lHK_=>pDG-e_^7?7mFg4*RC(qg}lb7!bDsH(FEEl zk!Q;r4&B;=E6rspPfmRG?^lEmFMC;yg}Ft%L-N#GCtvTXs| z!7#B!3J=^D&M7%*Z!#Ascumq8tS{P<-Hl;m)O3>jp|jrm9V-QF?u>OlliuBB8U9;W zJw$W{3MF@%=W;OHh8mf`L^al#Oz)%UGSbmo`HOnnSXd-uilA$`-sRq`j8G_(7lX1` zSl2M=W>(G8$GlWQyU%_N&RgZJNu~-;(#uAzV44SaHd{VLNWa#m`q}w@Q!)uvL+_zB=m`ZPtxY0UE{dDAorO^&+YxQZCzUoiS zdaYmY{PZp$6iX60pc4odQtfsD8~Kjx%ggcf*TG}-4u|tEU_f}$Fa`;s@tww{S)3+V zB}%08q7pYa_>utPzGL2*PUw5-(5C+diX$BSuI=cB%kJ;#2fE=Hl$(~Dvlx^DxQ};8 zlxs^Q%z|K}Nz?Nu*vxaT_1o)`dRPJ8iLrm&h9)X-FK>> zf*hYx*2^u`vh+TR**J(9Z;@eokut6$VoQW|?yx)OZa0H~1q;+Xs*e)ooP7cC3kdqs z#Asy8)d2^AT!Z8jQh;Q5=<~eSf4E+06A`p((WT^Q?grSKfCp&QVl9uuPDdZJ0~36;WJbobnM!yvtF%hYo|b- zhk`@z1otLweqIC%y4>&yK&ylDzZFzrW7$)a-HZ)MzSd5z2z2Leeg4Z{;zwAGN-ELq zt&n*!ySbD1yEiCNAEU}VpP=;l`>U-&r?|d)JeFT#&8@P&KHISa@H5w$voazx{)JFt za^;%yIG*7Q9<$GWN?TM?{vOJroB`>Kxl_BZAogDwbFkL^Z{@{`74ed3JZh7@oo>0L z-B}pRK%}}B!?efr>wXfX-HGF|2tTu-O!ruomlA7X!52^sQ``n_jKH4yLF;6I1!lz=MF5%zl zNP_856#*7hq?MTm*tEH08FuRYph2Vt4uO)Av__0|=ci3Zmj*%(n9*%kuZH8g00KWl zfySW)x21y*1Ifm+no-8n335c4FT2o~56&92MhCx8eqI;NC47pkyp6x|+KPOJ&TiQQ znL!xMtw(TP>0zo-{HS}zZ^H#5kgTMH-07w~)+=PloC2>w&c)#Zg;%LRfl-HIpAj9Y z6e?s!u|t0Bs9_MwEI$V1MJ#t~UIMn$kJ=^Cbv{F|i+o_}9FcTV($^e)TWwHnlC4coGT1Q5Vh88c zJmK7^-{ihWipxkQefHdG#wf1MQ8Sn{>I15F^&Eo$q`9bmEB2+b#l7#$Q0wvbR)}dd zr4i*SAYSPaUAR=p|=B)Sn1(A}ypBzV+@x@u^Hwvp~s&k#d# zh^a^G2a#FzY@+VfukpJz8f_ANb}Hj{9-L1Wr2VgaYr=M_Jg1;2cu!2AM$`E;awk)@aNx4u z?Kd!d>Hqz*Oc-Vx-RQkvq#wc@m=AXNC`jLY>4UeWK_Tud{?(catD@ULL2h1f?3OHY zF2yOf>2yrs@URZ3!<#Z`_OMHr(5!w?Nq+|{2%&etamU5-kVc7;!qelAyxXrBHX+G7 z=)zS}AsWX^(qSQFLNJb_vtfKQl4#+&T7dd)Ip{HlgV}@N`(ETbk751XVy?WZ9^XyZ7ik|a%QpRJO3QOM=v!SX3WgT* z5{=MD4A?cRDecZ9y11!vQ=Sujb&6zZj8 zFaW;00xhyGj3#lu&;CQRm51{H8d$EwnZJT7#Q1KyPoGJJ)rUe(JV-r12-oQ_z&~{>W_sO16V3e5+lm_m z8i3SQGXu^nw@Ai+DF^eBdFEkxV8+95*%d_zO_Vv1#G{^ricMEN6@%Reuz@)4Jau@VUkKr}JItT(v!i??DNTa{zpUlOx3S z^P}3IyCUQ{KCb1ZGOpBg6Gj-xpr@b^I-a9TfJw6xy9YT_5C)J9^Xprv^(Ac@JZ{TL z2!KV**)_0dWF6}%=}$6>wvC0zFENk~1JLmf&;v`t6ds1dmL=W8x5F3Pxof#;fqira z?!0Ggy{vcM8GF_iMswJ8!e-bkl0eEA`he{2=Gw}`db!4Js^pzrcN8lJZ?Twgc|b(^ z`>LD?ShkkO!D8Ohw&`8NN>cA97Ej~H?T_k_jnUZkHQwTRG9Oyf1^*^u@D0qNKLi#B z%{dB6o=9&RZ+-Q6h#e;AOXWRu*=Qz9f82ivJLP*H^w#NR3&nQP(oVjW(C**GIb6B)m$)%~9i`}6y%AKQ!z23aU{0UslNoOQrJ}2_cHXV2JGq2sb1=;1=Ps-aG0nGR^ z>!GRiUu3=n(n%jiiMSG6GZKfQF{{!kFl_ zE$pG4{_j1=!M)e`OH>3{T^XW4Hs>B?IR&-zVeJaE-pmk@*Mh*HNQ+X3>Gu-rnD3o$ zM0OzOG|fa_ugc5`?5XQum2`tb7+sQ``TuJ9I(kw9)jLJyxSo6zomVd-!Z--V}BYz#%5t7quE|49Ktv$5unx zlHZ{rAxc#gXt=Hda(z3UJreeI-xN_8Tu0|Sxf`CRPF8C5g=BgYG!#|ON6Qz@TGP80 z=XhZ#fQzD^hl>H51NvyH^8axGEbTJ2z5QfP-^_fRVPq^l%l-XVEd;2Q*PjRDbE7T$ z-b4x%xM_s!)H3m57@%K9cC(^V)6|-`!LW_r90|7h_(JJK-e%rVy>$QV-}8l3GSdT~ z##)Pc9yuH6`zgZ&`^LBy=Y&(gc4RQ^MTLe&Sst-MIa7QX_h4T&{AN??gKUizW8h*7 zvK~uuGYx^(*Yi(=lj+WpB`-5unqz;DoAyR$q{+-HJWCp;c>g&khAAd0l6K8&Py)TJ z|K(4^)2mi&LNqcA^~U@2z+vG`uh|xwb(^zIwlFHW8#(PYru(2_CLyHUDVBa;j0SQ<=_JXU z+R>;Uo6ISaEg(-yHnxMr2LILI+r|WT6dSY zHL^)VRT58>_NR(xM#KZBWK~b{GwUB5r}Vl^pza^gW*6b_T+}y-MAtb67KAkT_ulOn z=ZDi_?Fo8HTMMKKag=u33dEbHuZa)a-y0CCI$9BHaT7Osd0#sv6KC2Scfs#nwje^J z%rs)oGQm03R8 zD48RX@yLVM6b$Kf`=71!*J=>Wi@LF$+dsOP--pgh=uFc^P;h|c%eqUA_ht^<)_Y=K z3gHZq(WHnlVT!*ZE1wCn0MQ|v02`YmJ2JS-T8dwE8Mw-r#9W}_Q@D?C(N$t~jqynd zbA`f#-$yJMQ^lj|1W|=oBH?&jt{cp&>FqTx_)a~mQHJUKqBZzl=O*2{mIl8m3+<)} z#5F~68v29;(|eTJQf9R|UQCkhjRX>x?K+6mz-cfw)V~tL{KD7B7&X7Y<3y3Gl=^_= zB%j5OD)`rEdv{J>HTy@kt%fQ+00gp|j-hzHq50j0VA}6P-kh7KoBlMg%9Mg5*zC1+ z*-J&9&72)1NVGe~varj^dhhXS;YI*$D~M;QV#SRO8@~Sli}aE%Se-gYQ3NB9x{M`N zsNGwO88U}hB&OVB;TB8&1p^JUa2y|Ea(=#w!9m9PMIo9VC>KF^o^ z{%ebJbc(k16-4pXws7Nj1U{I^I58@zoqFM2le0BWP<$|}ETdi`dv3A?{z z4%PVD8%Z2zUa#8b*gj8;IbsAT9Tkqj85zU^ydiYoI1bGb&1n0Yb^zU=U3)MXd)aqZ zcgtIq&h5yfJvF_QdF_HM9s9O1!yi54_=`x-h+1PsC7irO+ix-BTg7*^S+}SqvANa{ z^7kqB18jxpcuU)IOJNiP&~SV2Gj2sE>MmgO=J96m#G?R4xw;VFsJ!`~B0W#GAR>ER zkr~Tqvg`P9!)iX8i{U+8p%CndJpf`Aiim9PaFIjn+iT=;w+oid;57X8{kyb@2r7kN z4f&4Vs859z>v>39iC{!(U}LN3QB12eI)O%;h*@JIcSS_@EL^Ni5>=|S6xcT>#oQ+6 zf>_gVrxJuCl`M!s7ib*N7-k2=$gXi8P!}-adb8?&mi_Y4SvJlw2HV)b2ZQ-A>Za3@ z8zeq<-lfRY+y3UnXpUe=mXQPpj{} zP7M>h(jw|DBLZaNa#Bac`Llyh1sqU@c|tcu%*bT75XCgX$^9T2fl;;ha`JPy{iN)| zC|qYD4Fofo;m4wiH#7%1TX&*;t?*#T-h=iN#Ga*KVV0Q#1;Hf7{Eab+fK#BiYXN8q zC@428Gn%%86h3}aj!lB~R=;(7a6JXWXivdr_baBSBTv(wLUH6O+?(Ekk?!|w(@2#b z>yPDfoGCLM46Mo7$U@e`8q**9B??cimrsNu^4;#+5;%H0-AHWTkoRJw)wz$^zVP%Q zd=d^_Ti5;UleA<);xwEozN968RNwhs49!3R&AoFKegUjcE&1BQRTrYZ6VA>ChjH8nrRN|NvmBQI(R|rxR9p#EztlrnS1VKxcjLHj_5knYTbk7H9bBzTMQTfwzsiI z4s#J!mr{G08@Lka&$U^v>*)F#gs;%stldzX#dL29Mk?o(!Nbr7)&hnr{S-j+=9Hkv zS~7*~^5xKr`{)djtBJL{;=s*Lp9+78f<1W33PxV&hyCi}_yv?RCKe_ht$vuw4vBVg zlcg3ZfgE}^JfdkA?3h>1E|q-gzERx2NJaP7h;2PI5M_~>CZerMW{LFtOwVq}*_jHqSu3-dc?f_1BMOhA6i2p$Np_bCyp6&{5i`3I` zfeP+?YK`$eWvp}a;pyadn3jS`mVVE#7!$%XZs%!TimswYwrB$N(LF27oD0O#x9_DB zFXd@=&~tVf)%3S*wtcsc&wF@{+9>IIk>CA%4X2*7(0-+WYi<9tfA-e*#V6LaPq-;% ztMAtF7m^^ZL9n?lD&ZeHFfBWU>Xt>EZw(pF-<5$4AuwdK6N5GOo}`??2ZP?QOS7Fu z0Sqqjd|Bl@*#XlrAP(0voO}^Ylh}UUuW!vg%T`jUzHi(%DmC zT|SDYfF5~y#$-bjAAjV$cz*;gt-!;)Ah6`Sc6U0Yl-Ri-w81Z6-gR*7qTqfc9rSDE z*kOIe6rN$LX-m(Lf#!BFx1yTS)F|191!1Rm82BobS8j)X4DWn?U)i0o7RVjPVA7!= zAoz7jeYg(WoZ+PFuA^>b0HdL&z9`F`q24i5jzQ3Ri%ayJ)0F~m` z&lVKBR8lzyb=@0&?aN^6&l^rf!2d;oLV4W-olEz< z;_Oiw7pPk$K&~E@=R^T-R51yW^_-8<^t_A6+}=-3G0c{Wv_?eS)|w8Dh_zJM`~=DOUT$!Xv) z7h?rWl4RfhVxx0px)E(3QQQvKZG-Z6smum_3m5lAms){S^GL7?FSV6RMZfb1ZGZzC zx4RnXZ>voP0-Sf%E?c^zsUkQY)~DmbVSrA1_^*uYwmMt^OV2gg9};{CzzvRK7ZWLfTXr!r3aHD0FzGE$IMahN3|gSiGa!9RiIXm(T?o70GgG(S0)(Zr-^?_XvW1F2{hr{vwaJM?*$* z9rgnEl@>^zOnZ9%lKO=&7k9)%*syQP*W{OJ?^bjceyfc zvAcvlEG^J+7bUPX$ZZ~6;m-b(oB=sR!S@1I+6km0^YfpynrMT7Nj;fZg zF-L12hA@*!+lRYWr5sUpstV#XwWBRg}<41f9jN z9d1h-GCgt1pN8hleU&E_H@*+FH^I%m*uge3{*93(!@QfC%{M!0etjLehe`RTLkumO zFS~dtoeERxa5A3=&)(|FGdxeQ96CMDqp24~cbnS%I1ZyA9H9e4Dlh6@))6%L5qVJY zwaVSzg+PTGPgB?$_U=BT@5Y>|JXTl>#1wZq%rVOs;z+L%!NWza^IFKAT2tTl{iHZ5 zVr#IzvX%s?ZM3U~_GGwIujE;7roBj_!8(mY7GC3euGO_Vmn3uA7KR-9Oax!rMwdFu z=(LSOd(-SS<~#DL)JQZNK?_ZsOs&%`_Dl>)4~p2ySq6~2b?u{Pq}UQH4a$vQ6FfVx zS+O^MyQa>F3V**TO9r1zDWu5he1Oq};}P)h#_|_=-}jWDU-zIyEFf2BgL~15lxBNX zL)b{Z{1hnkh5N9Kd1NS1h}q@Jd~R9E9=m(dfHx&`d_HjS80`{RySs~2Ho)CAob0XC zm>nayHf2C{@HuooIpt)^SBWDjMrL^#vjM|gxxVVd^KVKb*N$r=D`kWbE&U5mZft9< z9Q5ae3c$W&5u>tE*QVbC`sL`STf@-{EK_@0mwN5re|bD!hT#s-4oK#_XKv!W39hi{ zhvwT8oZ)ued;r?!{mv^o4~@9dav$L=uo+Cvw%SuaZIeB&+=$~~6ub;y9E^|CoXuHK zAi$($z3kHO0$Rxz^9dC5X&BhMbPZ|IF6ovqt|Ygk8IQw2B5L&W5>{0~?^y$?jU&z! zi^v?0#+E7AZjWen8fmor8syJ(Tx+gBsdldhsU@#m9j|q-bz&(|1P8T-%PT~b4`XBV zS9QRwj4hA6KhcTiD=W1VGH}vi(%oHVY930yz37B(w)!wgW_y(hwwOl_i}+wD3X#3T z^jIYljQG7WMd;~RX1={g@)>m%tM)X#9qx3tJ=({it>5xmEwm{iKs)7^?L|?M{3e$- z4ezAcXY_;UBxqX_yxRKnX+>=7ep9i%rnBr}3IRO%of*M<3PlAYvX8d}HP1eV&naN6 zfx_B5@CP40j3t%rk_sh_WMt$Qfn6`L>NptRNb_yVHwm%gHxc3FyRUFz;zsR%q98xm zT76b&jNxQZ3O0yfcQlx)RSNDr~c{`{j z$Fpg`-u6_8yShddD-iqiCN`Iv;pL@eD=Izf+IW$XeIVcRaLQ5gr$u{{oGV7E$uX|r zz*VEN#yMlYVq907Ehi(h_Z}VNXs6V(6AHhCPd%*OyH$UrHRCdD(=t#>4qwp-u8fGp zTtZg^_J%&7swFbhO{c85_B9d%M~X1!!d+5eqM0q7r*_`ex31fbyckF6-CKQ8#_WIk zG1B&UW*6z+5R9RCIW?>fOYbIZ46`e^?ZxZF)`Th^wrOuIfKB0rp=1M3wPbQ!Q~ijj z&Caj2_Z}H~pwam_R)RJGcJG7(I388M& zzV?3V(q%o?cd>^QVChuma6T*Kxo4nm3FVhw=nR})^L#RR@dm{FCeD*i_!dTGdNJ?X zx0P>8N$HgC5Tpd8rA4H>L6(vRDUlKoq)WQH8|m&`y5qfhe4g*`^Zv~; z_slsnXHHz_nr~ujgt#3=oNWi^LOSycZ61t@zq+CdX?wR!WZEO{Y5m9stmPVA5)U&$ zqh`8UDWP*SWOui=^JKwtiph_OP#SI5D3c)HV#%`Ew3PiQzH7x%2wy83;oiCVq|eJ` zfp3dO-gWFO(`$o`Bt4r<@F>w#0FNzihku=6PqU7K#N-SL$U+bikY?NIOrI}!kA5~U zYs~f9UUBYIP2tbts&`n1&y1Okqq7{Ke~`%f2u6Xz(?h`=D#rCWmp0iahOg2DVk$_2LL!Mn}S4ZuF-4ji!go2NEj(k0@zE*C=kjL!j+w+o04Y z9ZaK6AoB@FkUG{E?=9hweNq!-8Bwn(JRRgxjK7>sfkNu3-;AsPKt3spN+{@D4NbnD zwApyx%vV_(ONPnLoZ-b#A=UeeEKZepH3&Gb*sdRa-*%WUR5RBsihVPzf?~W9Yj>w- z1Jv?d>N3d;euFX>fhzRe@(||R?ca?qyulc(NOo~;$Fd?q$NfiUYtIL}wxd0Kc9EoD zX0)`nFr)?M8F``KVTF4KBzCK^7sjXab{liQrsj|49pH92)W%0ecN8){0;E|)M!Gk~ zuaiunP`+M{nEeZXvYx3@O8P%B?zQYqEw}eKFsaeVlLDw*p@M)J-p&vmOqGZBWA|*n=H%k?Opk4l>jDtH208t+xJgz?Q3T$qzP`M@BmsZ)I*&OHYR}5znlt`XVzV+m-2N~( zBNUNBKh`_6bK?hR1|QWwgu{l|PHaTR^PmF6>o0d4gwbx})Gx_VZ!|;O4G9lZdap5M zd@>8C6M8G%u)QAMuQePrk9fsJ%?C<-Tb+vLl}XKje-W2lh(`F=<%jrXmE6*Y0l(Iv8*mu=Q!5F*OjK(}##h)pS1B&$yzcB2VALuu~3VRla? zZ#6~$9zLUEb%WN{DLQJt;P+kdMoJ-lSumUqy`HFO*0Dokc(pGrtRXV$A(WGj8vYzk zdmg$eXa8E#tgFr_slBS9@5aeaMgtVF5~0`k(j2=DhE~ZhvOrjqq`N{K(Sw46ccMS? z>A3i~~mJpX95nO(Us!o2m*oO+)R+e24Q+4X{PKNyB)=Q`M zFLeyZA4XnY?Ifcej0KC@UtYF+F$#pb8=Kq?iO0O_)%rRMH%-Lup@m>UJ<~*&z;vC zziB98-gzHQXrm>~hB5}5%$N+(wo7L}FFg!rX|qwKqwPVHm~m&j6aspV)b-hzi{VZP zpPzZ1p8Y!1qog=UZy8AdnsX@0pFZf%oD5f|oZUoMlF4niDzlvF640$*zym-L+At!K z$dr?a8!9{IwXki9_`!&+@rnsY>R@~z$r7h`E5}}OcahTJ=MKWmrxOe`q44pe>uLTj zNqf|%Fmp!W&T}+Y4)%+#MsH1=wC7cLxNK}GLGgR~RN&FCuYS!OQjI3IoJnuebx)5g zPhXxRV_lOu)q7^*W%B7nBIa`W;Nv>l{86AjYvsWLDTz_+F^SvLRkN*LSHS#R_oO8F zu(lD78)^wp)6g2iu1h1035}kIR+5J~?|GG2s!g?b;~mXgt5%QW3{>ICus(UYi z9DVQ1(yk1e^jW%X*C@XuV!wl}*IRLe7X_O+eT?G_Z0{E~dli!B>hR{!Bv&o%;@in5yR3C-fY zz`%k?{iRs+TTkZ$)-NX!V%l5Mgo-;uD-Q4Px_7`-Uxv)K_>oeQTu^^7pId^cqv6vm z;cwDTYqFUI57;h@o<6IkX!U5WgOPt|-HbmBYXs5;Od@@7WF8$DE!&QvKe*aBfqeyM z(bTi)3dDWVYi^bAV$#^QDXr=WO58o1Hd?SWa#$>b@)h`ymh!GHFP~m*n(uOR+ zs}7xJh`fT(y2{Qp9#H&ox^LybxR-%ztak}e>LYsj9CoX&PPPTWFB@_H0?YrIQQwkqn+s!{C4xfCEqwaV#=DK{j8ww_pDC#*julJ zCAUU|h7vJI{~3VB`zG#-!YS>EuN_{|0u3mdUEql!ww5slY19xqbUp_Jp zaH$J-oqf-{oNx1B@LJtCmz>-4(^{uHjD(b-wj_4?rIyl&)h}vOdn!MPsB!5hZFr?$ z6+NG(&A)ay4cEE<%qA`19FVlc@T3@N9~C4LHb(f8{nc|6B#Txj7zmbCvHaQN<+)YFD; zv(_>7xwIzwJ)~p)w@typ_{~V}OSvH`;wvQEImJwm3hL#X@qTKF50@t9%*&FVlfB-_ zF$?Nx1*{bIqN4#VdtBU->Dta!<$^HcAd z(A6r%!@HS9*;C#7{txhrlzS43Hs{O?G~?6Clqyr;=1iq&rlO^=9a>Ya@UVJqqJVDN zI@M#Ru&TX$wlI7C#)Mf&qi3Vby=d8s<5_^PO4Nj#O59G~S+2>f=&5 zd@H@Xg(l?o3Lb(E4JB9f5Kcl~ikgcMHZ6uCsU=z7uydhA7NzUl z_}4H+CC}nnqnGaF%Ll_!m-Dd8?jJ1VtqSiz>lc+;hS6W2y*Hq&k&v#0<2eeR?y!B5 z!_MFyU!+gqk-%pcXSleuk|;iFAcbYzgV|M-A|)x(F`|yB?2@_4hb`SkNm1^QlV%7O zJ-+)aUL+DkC~iRqj=8Cyq#H|6iVbnF>#>YC?A7=HSXK*#C&zO1Tew@l8!ulyyJ(3O z0V6@AiRzqNKd72%q&*GZ)Ix#tpJ>S9zKBYCY;K!c_;A4&nDxO!gLVAHdUFW z_0o1H$fhWan~%;d`Dl|0xW;E%*z@5*Sw|c5#^kV@R1jHL$u`&wG zI-r%sWJtKT0@$nj1AS4&rd{W4qKppZ8DiBn~l)| zyD9GUQ3~IRBf`YnOJCElWf_Eq{jo3|S2UihKpC4?YzxeBwo9n|l${^$3nu+tijsCn zbVv}$&S>2HQG<=|#?E@08z%OOi|da)%IqgEZ+G-jSkDoL-TjHQz=Iq~txaX(s5d|1 zjMqhF6qHTFoIwHdPp9~o_V*zKh+(@B4N60pBqm!2CHSh7PUbD@)fFx6Zd82f3z5|z zs!147s23FXZy@?gHD2N$bAI&Z>a$p&UdVj}vByIAMcd9t$J6k`tn7v;-A{&@D&7xn zvPEH`pxk;x1@_m2ZP&=cmO)OWl1P*`Y}sl zAo+K5P{s~vG3IXOWxL@gQ|BCLP!gGC#;0&W8OX`B$za$l;4xd5_vO*lu3QHn8p6;# z_}p}z`qzJx7`T`>)|U~QY#-EGWh8TWf79#inn!l7PPt);U10Mx>X)$XxEVyYTy=O5 z5sxW&cbm*eV^N=2zCjUZa$+{%qLz8c_@eqIV9oE+$#&jaC)RNpsPaP2PB^HdUWud3 z6Py|zn{Tq+sz;v`$Up}tN1@So1o_p4aAMLw&D;!D8&3JD8MVO4`RVI`8F;^s|hFLD>v{wXk z^N5UNTNGF8i8AZr-!>@LNTlFs-Vzj*R0>SUXP#H8@!}6{Y<|Ma`~_%rcufEsr3<2< z;^l24(EZ{}L@|cF?iNI;ar5c{=u6miEmH5xN5;E!h_wyt?+fJyH=w~CUi@~H_rSbg z@~6|iwzw{x?vmXM8tFfFh~f$=apv|wmv|DB#ul_SlQDk$C2?(j@Ho(cq{K+Sr=AaY z!z)ZJ_i60l#h2+2j>4B(-Xd%in?tY?p~n~hZU?7?1Og4Y_JzA>0Y-?q!A0O1&j^oI z2?DG$yZojtnd^XohS*j(!RdNws$!Wj4!k~dcJ#UV%1+SnaRXK{EI@Ep!^ay zs}+6xp7xlw9E|0HS8XsA-%am3PtNbw+ONA!@J7|6S21gLS+57S-f>ggI-<`M5ildl zOj2nE08KTHs0fR;K(j}RculRYGj$mal!((v7dPjiaR=m7WNUuj^g-2gU}ExZb}OOM z2Ye$;YQjpp`3-nPLGO~@(lv25d)T535zHBIio3mLvTYdoV|0Bq$#=4h!HLVH5)5^H zv}e%6wlua7OqUN6Lta6CQZhKkK34Et`0ixjK3|c7jc?UG@!W8{=($z{#qVC54ezb1&-H|1?CF1YB~;0nB}*s`Tg8!R zQJnW)pul<2xL`R)&x)Tj|AAT8%HbTmKRXEkaQDizQGSQ5hDK?cb#ENd3HWc}m@Az) zA`1j;?_Khs4p)K_*R3boF@nGY8{9|o@@bnMrxW-#$=v$acgJVLW!QY44Uvr!um+d= zJ7M&vgX~*YVY=(YhAr5lo}x`{vq`Lme7KI)LGi-)H5(0Ohtlq+9YDVaUuyuYwTNB3 zIPsF4bx(gQyX}BNz^>hD%6t9fLK!!isQ435;BicL*1aMtJ7vPZ>%<_jH{HyezX<_-|96^pBU@l(b^SnItg-}BDscc}9V2P(ckkHN>(?gF*S|w78GJ#kW$R%QlU_sEqRxz|xRMSd0JAcl@hPhmEd463aVVv3ZwT(=k2&nu7YK?{$W29|x z#v~Wchd0=QAH-v#aS8m~9Vj-!Aa|E-`UKd#1(VWCOYRf>I|JZ&>8=e( z^M>fV7)xsSuvDzt=9}6op5k9z$^7J5!S%gLBZ9|QyhTy_W3a1!OM{QUEgzCntQWWY zQb%HVnkRa5ZmuLmK@qp%A=$8mxnMJQ&Jh{xcoMvIt!3Ew zk+FjOm+L{Dd=FZ(=m0MJs7fcUU?Eat_u^!tH891Y9;;q}8K3s0^7XpyV3EXPImQJ& zvN0_PX~9^R&UkKRzRmYFxxv)0pgvpO=%99@(FyA5LuOqtDvI3liS$7|11B!JC;&)X zWULx^Cdf-kbmVpWGYB?fuvA>02+>G!1-+g2WV#6%ZG&<{I+K z{Oj`4v2|&;Gd#ViY!AJZ-x@||{}F$!a$~ap)4-E8C(fPfZEJvw_k&hK_?E`Y% zFqL!J%|e#ev2CuVIC&z!!_V2@mI-)TC$2a9Rb8)K5-E3;eKK;u`K&!B0dV%nMmF;v zRq+N~YF3kV4cJhv($WX%94xuA@knIM>oi>J&Wq1xR%cE~2Lbvo#D_dB8vNf~ITzqb zb9&~?UXi8?m{VmCB)F$?T{iy2`VE2y^(ToR$w{9rs2m1W;O#tkyW!^n(0x@U0D02L zi=WoNdJ%F$Yaf{wc(ie&q{sKzB{quCC5iP6iKwOtqf0+ z{k^Q063AGN`9wc4v|0u#_?cf%7Sg;AbdZmto+gx8B$VH&uzr0P(?%xQ*=!ahw9M~m z@#j)uflU%E6~%UJ7v6ia`<@*uvkLB9n@Yu?JKVVx7;28cceK^Q!sEkUtGDubQ3LSa z-q!(4U{ejh(~43~h6P{-8ZV6-vQaQ*mtc0$#!Nu=bVPn$&W(+)(7-1EM({HuO?s`l zy8A}clAY;RH^6kF&P)b7m6tifvzn%2k*$o3`#+y91;MotCod{#j=GBed4VDE z&;Dt``!)Mn)a0i=3vRy{b%d}!xt_bW%tmu_qn2{8qW&&(y4d*Q!iU=C-`(p$US#q8 z_VkbrYGJCAtq-Qb-{e2#D7!p=ey}luvpO}QRdLpzVE#jyIiJai*Q3mF;kdh8pChAe zy6iYnKjZe8k8$2oZ4~|hkWN70xmY?aHnik;;&A2-y;cKKI-7E;x0D}00nhKM?zaY@ z86zTxb_u?oL5OS&OBMSNr~C@KGc@_UppjM_ai}$5@sVYt$VHfmb)S8_s++(aK~6_Q zc1aXjc6A*>hRJGuKQ;B)Ic5^E*Yp5?XT>o1%dn+>E}9vcG-uzCn07x&Hd@b&AsLWkIyo+Oy%bi(mkkehRnSY}~iL@JnHT0`t|v zvuf@yhh?x+ga$uMA}x@g%-wTY#m)<1$alyB1xNNyxk8}9o$?u?Dy5q5S3_)Pp`z(S z?QBV1P8{jy;g?4pat}b~o%FIIOSMz-Vs3H@-`d_cE`IOhL>-`A^=KU^b4qu@QO@a) z2oLhUb30Wg3wc=^Y0vMGBC66RxADw*m4BM%2s)}HLUFN6a`9y|V>KnN$xJ$yV5N#D z$Rz4yZ*?k}3OBqO&3?_k-Ri=x=#Fme$|Z|kPjw44;^>mT$S(CDlw~KJL=7_B))rc! zYUB0hLTwt67s_DL@0DGB#m^-ji>0~Xs{5;|{HvoJu*0L@I_F=A$H-^ehmE(~bZjC? zy!wnlz5*@k979FpVg6Q<&)PnwYp6zn_GHhbfUZ&H5Bh_*dm8S#$I#&z*DE@7w6&MC z40Bj;b^#|U*=#(W3i)JVtnGf+q=|@fcdxSfaMS15LG4dv(VIeAleuW*Oy;{1MAX+Y z{G(i56$I?AUGsiWS)$i?e^B4T>3;6Ie0h%y?qYr0OXS|BTxE3BrVfklZA()+#15+B z12vq4+@#spQDc#sC9ZkXG;q?YTxKoPbmg~|P8Aiy8=Jn$=@i%Q5J0Eb#)2Ko0)Fy5 zcSUn^onCc1vdC*DeSz;s6XZYI@ghagZM1ZW7&Y|kZD+=0Mm{z<#)>rd$Ve+oiNxXq zhGJ&^)tNZRx7rdLn|xUPvM?}9p>Ehv{I2cTo>nhDRpq4n6 zaeUDP&FXQnk9tt>522``BpWW8_h=gT)Lxmxkp3J>Y>Cfj0c@T$(qXo8R6>cf>HaTJ z7MAwzsKdx$PYgVd6|_Hxq@|r`8*-K3lER!S-N^=xT{l}IXzscm%p|X0JcZZ6lUQjD zk4Qfq#cZRcG1Z$KAFMVEW#Pen<2AbmX_Rda+FVdhS~XC1|F|#S>;G|!JX7!L1b+%{ zl_0<27c?nkiwl3ft&i#>+^ZY;JFqNdLtvdq1u*cO@jD@qEf3Hd(3?{1tCX5<779)M ziPu;rc`Y?ED1qB3jZNI=MJ@Y{Z!bzx-vi#;?(hg^+OO)jd|Q}m9tOnu15ZB&QlZO6 zvGzwzD9CN7Ce^n;Gppi+p*j;L9VJPbr(OjXa5EH@QtrrOgU364n(eMY#qc;Iiy6~M(=ls&@3(tJ$-hJbU=|+xv`)bBwf2WQ-s64pc(ssevhjA8{DvS3z6`f^$_1%RJIUPQ4>AaD5nw zKqFvj4;5yC187?Hqd6U`P)$?KH@ieE7QRHRSD(0cEi(0y!Hg@aUAb52@cwpz|8=GcN+EMTLv zBt6eH6YYIh>5?Z)A$=?4c8+#&9?!eFXHoz9yRc7h;jCl8+uO@yx=i>`zOf$O9YHZw zA3+f~nRDrS9;l+va5{_@S|7Z0>9k;xyx#h#L}8jh>?KzAA-`kL%w_rpI&u|6kuM?I zfj4mpkMAj;D>h$HS+(G|P8I`tz;5NPvHY~#SGi=Te!R3Wa9hW7xxc-VuQY4ZO|-Ut z_AXeW&ib4XoBkULTFhHbSumC27DMY$(3@peY`SRd+tb4DbZ#~2r1f!PC8jDI;pEb( zw5+&W&sICb9o`2C!}MX~=tratjJRnPI5G7k16F?ubu_84>7ZP#7hHX8-%e?mMfP+W zEFT<{S@p_?^u4dvUCE8EhTBF8p~;a`oDo}jt`d?7tNdAc%D3#tD5F`%-xUd9;{)F* zaTjBe$sH&SlLdj=%27R9G35)buRY(N@4}JCR0>mEos#(Mj1*9BPREqUvd9fCNtc&9 zd89;_mIROtb!U!_w1J2nqyn+2R-3KYZ~OEABu`?miUZS1{g z8(G0(6`P{Q)-kALLg}2L99gl-nXz-c*UGDSTnbgbZ7} zEhn1Abz_dfh2dD)ZxXB3W623)CGbIC;_Z}!ZGyn*w3y3S2{bw(?0MYJ?+-imb&R$0 zIQEeWvzdo<9+_(?RxesJZ}Rp4o1VJ%M>g1;k#4- zf||Ft54%Pa(l23Cscmg;wB5)_|55 zX2F9N>5;oXau`?ZO}Ah#-O7uACmGD$Q~hI!yrRxZOv{2VJZapKXym;t*IWfEw=WB$O&;IWRH}VgQw-Z&TuQ)(p? zc7)YE9K`)%!dMNyAquZ&|8y80J-Z8^e{ESzm;p3PQV_)_sK*2yb@*H?QS1Tzw?>11f1%5@tEgr;peznecTZfdJKs?eQnObW4<}^FP&zKo^&SkJ{{EecO$MR1 z`H;vnDqUy&d91Qv4}@v!>v%eUu_#5QR8%BaD;r9XHrrkF$C=+^*YX9~9SmacwC0vc z<|ld-`hma&yNBop(z?MSHA?5q#2cMETlTN!`mYQ2%E(NInP-D57bqOF0GiZS_1)Yw z5Nw6b_SpC)%alc8=iQt*i6G1xmqo8CMz>5ha`g}#7I9YKx{s3Ae(rn2gOBfc^hQN# zSZv^iVA~sj>vxgQ@2p##6B!4&eCBe%U?NdP)~5lZEC>BKy)m~SAp;mR@w?L80!vOI zex)*El!`b;h(e^;QQLX0Cnq7NTjkzUUzpoIXeXCnlD^Z@BE1qaj+prHiAVwrl4~cG zC9bE)IK*UwyB~EBw8=azVn`_Yv4#@RVK2T-nFa6`c5$%ccnRzR6_VrDM!NyskYP@_ z6OnH2s80~V1-7afM*;*{l3VsoIcn>vxh}yz$1*4BrSu4OPD`7ZEfbQr&YRFFj}KL| zjTfj#7yzv!nx;lQo%hvQ0@UzsLSEwA(V$+>*X93udM5)5-pvRIQeV*A4wekQCr8~J z(%*WqC^!%kzf%3s|E3CldQi<;2VVyu=Cwx_3lCAKq-Z79w-u|+wZ59v>h8&IM@Rzd3C$#JFZtY7zjX$s;%%t z4I3Eyo1c^udXmCdHdmbZr)5Z;0mFw$m65J^zKUrk6|Z%q>$VS5n^!7{O0^jxQ{o95 zn`tdug2Qs6q(R~CXW|8hRoV@%yJyFn%S3fDZU*m~>Fq__1F~%rEu9VXlC3rzz;^xh z){bMY+ZSVpqi?t<@KQF35Ej>ux&iR|4Sq%AjmXelMP*2{q3qTNaC-jA2wFpk6#J>V zBho!M13|8h_O!%rlf&^Pj>ud8`Fxiwmfnj7o~TrNv%&8~yR~P>Ct=Pfvq6piT`1Ql z8_5Y0(pviX8M7#7$k9(4NbK#2*@qCq#e=gL^7V=FuYTogDKTbfJ}a56vN6~j7@%9b zbn>S{`=Rzz;TOd9cGG#VuANX6SB~Z!lbw#5REDo=`z_%>iPgR*W^36@!-hkPt7r*o zKn+e^2-VRfPB*G+qKWXw&pFb;+%N&EuktSq9T1k8V!`O~U4jF{nDujxKldH#Ik?`Dka3zUyg7Qaqj}FgKc+Y02~sPWfb-k>&s;mKoubZ@hQ93%vO>J$;k_SE zNi)||g*=Qd<|^xoRmkTQaLSBtFOM+7GsAmFPgZDrnVdab`VUhk^)rymf+rN)OoIc! zq*T$X)Y}-z`BKWCPL*H_+ zEe+@*mRjHTgc!UX~CRN_`gTy1*QoE?Zz3KVhy>*B4oY|iOrOKlS96T zydIVydfMuCnHC^zD#qjcPRv_pu2K+UMH!+j49}0QOnh2OxFFlzW*#*pMGRug|-+Fmb{ zG1_E02`bXnfy}NtFPU=<@@y0XrG{}*33wt5Ft z-D^S<8h0;<(qk;qU8|uB(T7^D?+{1wS)%Sm_}gdvJI$S z=BpRe>^l-Zr4M|iTWFNqZX0xj;ZL*QO8I3ZZO9~_rE=CH?RWzRVIlgFEO4~?4eaI@ zu6_&-jqNa54K_~jY_bL{V;@DbE68Fa{P(!T3o5e_|bMfaO(UE$qqk1uGVI3DNyoz0FoRddG{-SEQd@?|{6f=p)pCP8L+RDLFe z0pC7LUuin3r?X!l)%l@{w@GW-R=fBm%>Qa&v}@-%!&>=-2W!xegn@>rHs16RfI-Ap zk{9L+p=U%?C9mVP&lyUw-{omi`E>~7<>p_;+BhXN-u&?*xwE?!{&KbNZGR9b##=o? z(^btO04%9le%Zz&V*>}80 z*i5fd7sWh0w|AEoF@vtI>)=KYcj&tIjmGpznHOS^bJm$BpZ($!!2++#<+y72Ba8S7 z*>1`QzDo2~4$;(4>fky}qm2KkwAv$^o}einkeu@Yxa{b$ zNT(w)P-m0qO;C?kA|&N!v*E1V>OGm!Dwnn0^rV688Btf|1hqZ9nn7<$TP2E#)M%vP z^=U*6%jHy)Satvf-A65)NK2mj4S>W+$L+kkp~=a=i0p06J+11ov*)$Sy1T}jmWlJ4 zp=1mh;!lMy7~jc$GRi%QHi{e3)e4|4>RWE7zZvqmcTg+JFSk~L_MY^#pU})bl6Anr_ zNwK##85a$zXkQ|H-6(MVGPh`witgy%_#E(fo?4r#Wu;m62isY1*WcXg2#Gu}&Lq~@ z-CXB!Ke5DJ*4J1#k(JbM`ePlpvK2cawM5?$^$N)Qut)3!0QNwiG`Leorf}Eq5mE(@e(ZM>PlA*Ff{e~GJH^^~t zR#>$_9JH{71WI7hvq#1x4VLhMaCEf(EIIjB0?-g*IAltP+eh&pGDb@ulkTu8-o*WM z0iW(T4A+rw)@=apz*=3`N4-=i8zQn5uA9&hO`P8BA?$AX0Ba6_!o5Z9s5|oy)mR^m zrO>Z-rkH}>?H5!e#Fhm{0F@L}0xj;ffCh+PW{E^jAR4f#U_ic1F1Nx3D{#L~XY#i$ z7!+cs0*+%?&C%>_4(*!N0bYdpk3h*S-qHTm@olN~SX|Ug0D8-TT4kT~yl#8-Vm^9^ zwGMzaSwAA}>{Ov~9(5ORTY-y7mrSz|D(C(ryE?s{L@1(}Ab}qZji`DUplR`RIZ)%n zy~jV?zcnA}UI?PSeF1O0DKg$<;c(h{>oO#CF-1eROG&9$fyw7St`5Qk>P48O^8~S3 z=8DOy(pVH~>JN1~i}sJ~A@G6kj-kmOef4>pru9*n+MO!d(>qJgL%$#2Py#3ZaN@;>~o$04gFUdfQWH@Vm(VIq7wKI3dp*z~@VY%AOFR zJaZNQeA4!4)`pb4Dq4p|X||E>V2!k+-qL|go7Kj@gS4$=g4z}qyrm7KUc_lAGu_VH zf;7Ki%r08KJ1lA8tp%E#9sG-%T9(y~0lKN95kXVfvwzbB{9N)00Ca46RPH){4^W3`kD+AE`*XY1ne<*IcEWbGUG(FF)&G|sXGOHs5OR6YQ_N$evdAH4t? z@wx8khR9v({Sg(g<5L7L%v!&)9SCBFw5ao?QDmC70Xc|kl40oGwa_C*OJWm%h~SbV z5Df@$!e%d|*Fu7|UWZka1Yt%76HClhL7^)E%bLTa0dKcr_*5l8RP&27?m?F^aD&48 zwngtQKOcGgqz!Aa?!*9SJP3*ib|J!)h0Ha3%?x_==<@~YinI@WnX1Mifrx#kc1prV zVED@5r^@lq5k`hKlidKXdVhcS6!e%ktscu!(oAL5ub)y(<|(uWqO333nh-4Jf* zF!+szAkmz*`{8LshU#r5n6!gJ;ta^yAz&e>k^bHtc`B9j6mq$!^x#lOjTls;)Rry; zl>FH(j9n#_qa85;hx}Dgp*;R06*8Cq6EsZ$=RMiDb(f}_l)B|W64mVe3rQd{ak-_k ze?AAdk$_+OY?a?x_YEqBU?f5VUh}(t^69ui3IWJBKCDUE$QoUj&7FpS100@s6{`jc z%gG|AG_P~5Y+n?d7u5jnv#N|}>5*C(;HC*nGjN%AI@r#U>dyDgjvb{0j*vy5Dj5_} zNJ7-`tvgZ!BR--!_>=H;ynx5iTTdm26vhvzUQ~!O89_?n1i7T~JxqQz_tOX0Jle#7~3oW2UE)go*=Nq}*QfGzz+(EVc_ zq#FzIeoiKt;e?arquc{ki96iEE@#~*e;10`AAj1hGlOkE(Y^^wKMZtUG9Ce0F>^CjUY?vfq9Te z#525;%IQ@EcqbI^oY^xs64{OCzTh$SF6f;VV zzqxmUJmHrVt)p<@qyHH5C}>LYrKJ}C1K{bVTse$Wft{X|_E7Yd# z{lr>vlc9F|CJTk$#d*bx!ISsN}~LUTQwR@pu?N#ximS>XnwbpOS3CdOWi}&xzF$XeWz!( zOCN>l0=O#NsXO6-(sz8l$P;5S;LrDR43$y^aSWQ1 zJNf{{@Be?!Dlb#Tioe{D`f(B{)xMNjj8KUxZ180D2j)ehb|(9%WHT<{h&B4)fkX!( zQL0Jh2r3Rhgz$LT(ttk@Xv@4;&k#>H1%-(!Ak4)5;Rwqf3*$^ zKfnm}5K?~o_Wi}CMPMQWir@KE02TluuOMGxWG~*eof1el2qCSx2qP{@G*28R$_SEt ztMp9G5GSNrWhz6h4Y>Mp10Ej^Bl8J<*YsO?)Qf7^3*-re7b4CSJ`?nhABG^#ONhc& z4h##w!9;~Xo_A_>qdQdD=6}`o&)k5g7YBT_yWa2zh%$jcq>iC}?C1qb^QE1y3m?7z zXNbbPnxF_=Uk0E$iH(>X*|Wm;HO3FKjC$zOx ze?R~DcfWq*ytuo$u2ADK}>=m~z@B?k|CDO?@jaiLFoB5=C z-VN|yj!*=LT^_T3!YZSVFD!ow^8Tt5_yYlg0Yx0i@_|wD49qvucRTI4aXIsc!(U1N zV?a%STSsJi<=5!rnsHy0k-u7Z1Lo`2sVW3T6mOOgwd)dMb7TbBfA&S+;wJ)g1LW2S z!2j2N_N{^9`(-lO=3`T_Jwfo%{01g{x-^3Ezhi q^%lt6$0)pb>!L#|YvY`t>=p zf`HogtMi8mcBi{p4$6fQ!W_=Xa9yE#|Vvk)tM4S=@c+IM2mUuh>4uKb|K*0k{YO zXS?+EjJn`)Nm08DOYuzP{~ekTv8=}hT^o-XWCSuXhNlsTfgEMC=P!VU6H2lQr{&!Ty$5HXD)&IzVKSYel z_>(!Q1H%&AoN0hh@emtZbXjJvKWxgeIvT2(cZ!uoe2d$5C5U?SXV7{ne9v5ApOgXjIwMP-b!C zCa?z(_+1WkyV4~8Zcy{GtGIxXD*mY98>hu@CA;v$&f1=kdCJf%ud8%l_<(s9qM3wxnpUX=pP;@?V*J zMM8-F@|yGOjw}Koz@I%OTD}NsIRALtk4yDarB3HpW(ZPG*?}UK6<>fa$u*e}Wg?M9 zANSy}7AUM)?4{9-GrnaU3n&J1h^Mgcs~|3W@$WgHfJD8S!OAQU-atSwxWM(J!J_%W z^H*Vy=iu&(uL$xtVWaqD9#7{c@eFS?ze)%j{15IA{x>?x_>AR%O&vw^JBI=v0#avPYR~`GK0EZ#N!2ZoX@f9tqC-@)*8E?@(Lc8pC8#$N_|T84 zd^2Ia`#1SP;*`c9N#!BJVMIJSL>WJ%*NT7zOy>rr0y!1F%&_&s?puVsy-U(-9EAEpk1{#Uc-F9zpgmU_nKoT3UJMfp4SKY2N@9Pd@?f z*Nw;g{Geto@qY&i_X)zjFjF(-uaE$VrT&gs>%NhyRp&?|&d$Pjr9W)Fl>Ps2w*skr zGY}UR6FkmcP3TA#e+zV??PfXp=k!na*20y zoZ$UW{^IEh;L8)r>*qI~Nz$5LJ*Wr+Hf7>vm+L@}&@KC0EI=HxA-=`53;&w9ul#We zkLLms6Z*5ch4Nn;n@)_7*3UxX#m!T@ zBLcdu!DyKL*?sSU9ODl3iC{C<(gCjEFX-WXMUS%nPKL&2ZJ2NIr``dbgcePwzk5qr z7IZsr&Y_EM51!Z}r=oX(&Vd5-6xY zy0m~3PJ}?zdm{MiqYeNfb2!SHwLjgjzB29%vt!aIp#P}(|3t4R)y%8=MR!hpOI=G0 z3bCk8f0|?VpT_{~07_9&a+If{j?*sS57uKY5~;Oq)V5iH@+g2n=y4D^z9v|3O(Y0X zQkrsNWv2gYu0^3xNKJKc=1-mrYy_X6Z*yoD_Ox%S{znlr5~2O(L9!Uk5X8nZ240(I#C+W9e{HM1zpoNY{LRuFdMI&> z1hAJjY?a4p|4#$J<2HW(I>4>+l?Yj7_&{4uGB<`njeRzWkh^2Xb$X{W{$utav{?Qz z7ViRgE2plusEnZo_%@-b0vzNRDL`cQk4fPdYo;R@qYY5)>1oa-su34m3)jU6BBuFQ z+yD5nkf;=4PI`4^F-Vk91Lf0+HZvgdlsHuX4XmRJ6jg(- z|IZhHB`nGU9Ud&##SA5m!vVFDeMC)(iS<+A{Lh#HmOKgpF(XA^ABFRYy3`uJ-+;`b zy*X>@m)V?ws2Z}Lsk{oHh*T^;Vqo`)vO*6r)>Y9x__6cqa>19M42ecVUw!%buhiF` zA?yqG^~vUvxk-ph57vhV&;0KqK0zTNG&+Ln+QQI7UWtgm_L4dcLp|R;0?3K}ho;h} zIRxIKd;5*jWde`hks3ryy~On02#pu^8s)!9b4gNiY0L9kfs?RL5fDfDZ{9~uNd1p; zB*B--FA*e9s2cE10TVeHT(9yodSAf+D5|0tF#;;~Lj)2ay*9*Lqc0O}4g9o=f1>&= zJRXCFHhu1Y<>m%lUh$)feFB3!TCYH!G<5uHM=!~&<^OdY9}kk>59+0%pe=t{QYkXI z-?K85-zN)nYevJ#g=Un1xIh_*xJcD)x5R;8dP_CCXuixYF<3-At0Mw=W~(jmeiM6R z@!wU!CEYx!h__M9t}m~m5Atj+aU47bK({ac-zGqyKuBw+Qmu;&8w?HhwUNoWqqf1d z!>wC1gYwlz)_i<~GY5gY(PS`@r4)O)5gXa{1gIQ@-hTZ4_e|gd-t!gHR`ajvBw+Ec zq!zl-HSmBInE&(t#VMC!XQWo>+oOI(qx?&ucGn~9%fbph)>#X@XU z%}t58<2=~0I01JjE(n_S{ug$oYk?%$tnt~iS#b~>8-HC6n-XiC{Zpy>*L-b5qZ)*T zG~|;+K#~jHi;1|uqyV1lf3KuhKs-R3Lmi;HO+Uw2pANq4bYu@i`~Mib?s%&I@6YYh zMMOqrWt5eXWJKvUP-I3KiPDfQLdv+2B&0$jAz4uU+bLb+2{3s%llen5)VO5`IbSvLMtg|Ganp8nm4`y;}EKJejK%(0j6^x_C!8^pCY zJ)I(J52}0t=W5F{O`l4{xmr%7NsM=dxKiigJCQoSsBu+3FLtZjmc;bEh8JK=GU?6( zJ4-n!H-D14sY?}#Cd<-Q{tvIVdOfotEQ1|k3VOG5`ruRQ^S+*wpVz(9)h4KAJcWd4 zP~prWXL;tMIrwZR-|;vn-G*C$H0F9BOIUkG4C{d#I>MC=NpX<}u`$QU=}DNn3WL+y zSNr0XvTy$tCZ@5e&yr>(S*+WSv!ruayjn&h$h|URdJmD_r?W;n=`e2 zHn@hbvQs=8loK|JKUzz~Z4s3?uZM7gTgXwBbx$_lW+Th7LKqoLtF&{3cIeqtHArs9 zmvR`RjB826gdawGVrJT20jR!Hgl2qNyyhcbcJ=a+wb{2@H{fD#nO4G($+h2dDQ?r#b8Ho^mNvOu9o)S%?ihW9o{{%O=t<@ELG-np zyu+M(IWc-%{EU?s4z*R?zDtGTvpb7>Qig0K1GDF6g;YrX#Rq0ow2_lcsC<-2&#ODs zr;NeXMr65#@B4kZvndtBJCaTdgZHlf(l__+2Dxp__^&BpqXxkLTLyB660e!t!W5T;TF%6*xS*L62`JiF(I^Gx+D3%M*=aum63fUL5JEtEa3 zsxo{>Qo>Avl|S1*_L(9?L@+sC4x_JPX1bj$SZ~E%ZAcdAz1Fdg_RxO2pVPJee6vtF}hj&Yu>i`@8th3<*U>t^z(4CEnyigNA%NJ zHaGNqD(Jk)_ON6`3z1OPM~&jWwMMh)n{vw!pY`mu0Rws}TX-0Kj`DWPW&W&=RhiyD zTKmBUf%O}v6K*h)g^hA^DV>6&g$pxg#!pDK4|2cZrO%&|C&j*D3JPqpF4i+ihBH-* zTq*;XilisOU{d4kYz}c-7a#R{1dppOY#%#pXzgm{9rpOmZ6Mt+U*ZBx1<3*4`_7Br zS3h(PC(A~+M6zCqZRtvGBXApg1?~fe49OtLfe9!5z1ulK{#a~EYfMRe#BUTdjKl_& z(>GuC(reN_Ru9_8z1DVl}RJk@PG4>DDk|tY^Zv&=((e9sn6K zW7!#}c*-?g43VPS3929n(V7rZV}(83cJ^%>IiKk7m#f|R?sz>ByOS8-V(mFzaox2C z_a5sGI6xmoa&eGlpjOA|D)LlnqC~roci6D2=!*Y=0B3qvJxCbv+4bq+)k=o1r+=3i zD!~feppg^@X-*4#;Sw2slyPiImp1rg)=^VEUUks^dzISEH(y}>CXjT8)XdA@UejGO5>r&|-40nEM2CLBkSaIHP)1N?D^ zIX`d|@x9US4&b}%Aa`I-BY(m8rxKmAk&$s<7;Pl`!K z${#A;db{mA55=*1t88)qeHbZalj@Xcft%Y7BnAKWTR)*yBev3sXa zp4}u-Gd6Y3OsTD}{Pc+gVpO3C-dC*V+WfVx8cnY=NvXRGWxZuyKSJiS==ZxfB%S@H zS@NvH`Th@yiEQm3OcKZ2AwyK>lJpvA-OU0beF@TXbrfL1H&NUonl;cCdr>jCd&cL9 zqNq2QpX}ATpQq)uK+y$fyAxu|7{!Qs4iLL9bmUNA-MFYuWtAn5^@I8Vz5vr%co>|@ z>_`2*pfRJ>Fy31k)^*VdwA9Bn=>;&F`+Jsh1W4-8lIVF(iKj-dKf(Y0Ij-T6U)y)N zmyIgp*tGIer-Cg<#Bau#IeBpE z#{Okt=P}+tx2o2hOmaKs8fXOJ%+eKEE=pN zn-)EW@h&-XH;``MQ{z!=qDk3I;}p1)f6X8?2H+6}1!Z%32^s>#(%P`@Bmz$2r9J_A{bl?2XGV-t;`4PMQ(irUTDdtO_sH zv}hFsmv?Z|2Zr-4*LhVks3Th$Xm6C_jzX?MaiCyFk4MFlmElIU#U4kz zYh22L(`sbC#ed924=TY2y0S|-=qbLLkr?LYi%m=|Q@7iaj~32(bQT@r{&2&dQ!m8@atm$)c1Tmu`Z`?zNn&azcwl6 z{Hrrbb<5e4sn{51(ozsu^3^F?Jvi;`b2p_G@I($KA zO_884xF&c;_#p`(?n)GHA!#C@a}%*+e;RYldNZ#`F%+IGXgD|+U-|VzQ~0YlmBtIU z7Y15BXUD6>#ohiY_u!pI{g0m32)>0cb)Ap3nR~t^SF^P=>dzKmn!x;g=J5v z`>-2vmoypBF!B&qiWjVMZfAM!do@Am_U-B6x_w2o-EOLnUY~T6Kh>+s!PKUOIckjc zG#l8PxQNCaRpoK7o#`mL88u*aU_p>U;*`+$yTTIQKc(@jVWUq(+aCCu_4>iHY}uTy zGV^GYG`;%I?1u=4g6()>+ue>mJ|4!u?Nq_%@5-_nOc&U8dE})^`D?-=*W8{c!`ZRX z3TaZC6}>d}X)(`JrwTNz_a4qbPJ=Z)k7|{)+_kUddBJ@C^+$T$1M_BmFMhCz`G2Zv zZf>4qPgcVJ4!<5X3v#Nr!;hQXbWe2Gr_TS#E4QVw31f{C=)(NjDlu}`|4jJzxu z9EUg>FcG=3w|GcIfH(i`+UvfGbT>^NawqI zh?YIDjcOLKF*?n!=zsN|(D=a*LO*hhsQ*;x13XG1Q~QC6nmhu9Icwfx9G3+`zVPlF9EJ7b)<(+VgR9lkYc2L0yNq zfK8erOR|7DsusP@A$Z=*Qi)pnOh~~c534ENEhw{%jNdn1U7xgt67_0hUj)USPou{~ zZ_CVA%Av6B8|oz+^78WbzOOYVuEn$C5w=}U=8Jg6-3_Vj=j~!SntY``%I!SB!F_+i z^}+=bgh0?`a2SU}jaD+lne*9h4uu{&gP9UU53?*S7r5{t^glQ(# zJ&gigRrhA)yl`V46=-pem<=YJEzAe&Zx-8~X=K^a{h~D0WIBMW+;+1{DElw6{=(F3 z8=IMFkm(y5vKsX{mleBkfO=nAs3?-lRqGw!%fAW|U{`iy9fpH5?t)(=Nd-?G2JFEK6XSq6_W_Fn@j(H#dKhu6H}g zU3-50B@|kO(f7!x(A&=fG?$(h&txV`{4rm={O5}xtJHV*1D*7Q2}}i0yF)(@XP&R; z>}!xsW0KizX~IY638#s|Zgc#7vehh*;-%0Qvs z-rmo(wR-b2EO#`L^5>=PN>C_HsgY~yg4k$9+&a7NOsmr=WxS=@ew^+e&1O2CWs;Op z_s4Fg-r7!@FJ3rke_+eVH@}??Odq58TJG`&WGxOXnpriy+@5&%BgX14R?gBE@71dK zX)6=K#`~V5zP{et#VlXMP{WiP7XI0H;rUjqsSiprtC_7E!*DvVXhHj|Ie%qaWb~I1 z8MG{e*=Py@I@sT+&E2KL4n~|EfiF+y&dy$TXN$R$zaja2@U|0GLhXZrl;vOMeo@KH z>E;sDJ>Hb%qtZJ|F1?*B4W3=3F`uoVLd%_BTpK-$#?&CzfJy9*-tH$Dhm3WpbAnzR zZp^-EVgBI?~J$Yc`g1D@18}PV$+#) z^WMFlCdzUQ%7+ncY-*VN2o+beU3li?)k z&Su4?m}xu;edj;nkenQ{T;3U7lCZM5rvqo>?&YgQGXPZO=d`y2MaRy7%CRyE;n!gQ zLUZSW*BATCfjiTf*bZ>SM3Vr55T0bZ;qZ*8xTnD31!B$=8kCzj+iWiqip*36}F30;z(@N_9EGEoO3_COzTW_~2zWLVC zXUN59cT+wde7liEzg7-0O&m%)S>4CZfBwSDwwuC@E*+P&d%Ii=KC|0H{jad$*D(o zNGD!`2L3OTGdP%?ix8aKO36h_N;Qf5MA6*>@q-dk&S;PE060V7YE<9{Z98TR|;kmxVD@$CLG5 z5t*O^Bs0F!H8eC-^}xv;gnt9L-HB4tH~v9y{5f%5OH_Z)@zKnA8>$w99^K~G?8^VK zB6+I97&Kq5y|Z&YwOl7VVoRo`E;A?F3IXw5ZUJT0YOWF8!{sV~Je&g8NPBH=GKt>S zN+zNX>tdGaLCdaTss%#3e|Mz+((mwu0WL0V5clg5HAc0LmE<^&hDSt1 z{Fs<{`NGG79+42n?{e~Q={Brb`6i3d14)^?u7@x73XqwwV;^Nl!0gmpHfFi_!ao!g z6o3BIF0^hVy*F~G_4a+y6UJ-D;056isU+XEZbjP(P*XYwA3Ct1a1-M?z9&isp)+ga zMbr3Lg}tLorHVH(Nzw5gaYAjCoIc>vcXC5F)9hu*!MAP~epOcfbev8|mQhgn*4q2% zi|xqB**S&Y-0!ndwx3qf+Wc1G4Z4kA&3CDO{P?lf_t&pqItA^TUhjCOT=PQxzwTJ3 zS{pJ8p)WZ3PrV#88P!g{d$*sR;pRmT507T!YHmuD7^@48LPc%6rT%ik;K4>0p_sn= zre6E`!{SAU%rZ1zVDj~xsjk)zKPpgrnu+nwm`~7*0n4zOXJHSBx42-p{R&x&wnt6L zo=8~Z+bGAdetmMIT>SK`#xn5WuAn4~OcwrpaM|fGO>N@9J zpJwtb;4EC2{P}0yV`enQN)2KpqpwXX?M0>tJ>Wa8?$|3 z+oZEP9>coCMqHM)K*eD&cELI{ze(Saeo`kAqzqT_D|7mLnVoI0ad3 zNXuXt`}{q}lrN}SN2C2fvk7JIkzc8DQuuZlD{rf`cX84G{9fC`OeXZiLu!Qy9+ip) zNn_V@A&PRLq-}u>e@PYpr+vr6qt628Ja8`uBGAPtN}qnQ0xIGTi61W-B&&53q2; z;)%*K&LBrB3`b9#)19DDfk(Z>%B;8O?g(u75|I^Sx}lV2N}*X-uFz0@CD#DN&Y; zjNkRwJUO=PTfC0xq3xEkUU##I#pK)b#S&|`(7-t>&MT#6t_oYsBk_j^nx0NhQ%SA2^z;>9GBoCIK$vm{EgjKKA^`fjGWLyRLJ&UK-Ni0ak6e_p zEZ#qxU-vQJw|f23_Wjs=$DDE>M~PqA6f@*rVDdSi*UH$j-!YH^7X|)+3;RlRMKYEi z-25Oyes@$lzn%CS4?zn0dt}ODJ5W>g;}0UVQ^z{`zz}e;Fn;edt)_oS{ssPnqc)F+ zl=EGza=wR)u}xi|csRQhdDA!@^gwF+4O!JBe|JcYumPlAnK!QDUIt!szV3^7+xsOd z_18X7H19v|Vn5uwguPu_(cEom>&~pXomh^>K)sdoF=pxH1jb!Jq?avHn}1&k$GgZY z&o&8>HiA8fo~XL)*l797hebn{hA~VSSbzURi$^#=m`KINT z@{#9Q$q%c@hZMM0(7Qt=#>p!tC}coS>?nCso_I+1r>xJHODzmOiAP9KrbGd~O=3TK ze$K7F^^#*Nt`3-zkzY(rOi7Ws(~XL)7Wz!I25;xSbj{5Z9?%Z@&`N%sX?M;d60K=G>628yo~x7K~(wPN`4&l9wZVXt<8e-OOo} zT5t61^+il~%UcIUs;uB>uO%8)Y-DT;v+ZI+p_^bQ)oo4en@K1n&XsnWQZ319Q$s(Q zck;qo>uvQj)9!1o@e-&y0#c$8+8Ry%nlL%;GL64-EQ?9Hf$BNqXO#y@+O$d!cP&0= z2V+~`fYiGz8t@G~3BJMK6g5>x%_gjQ{wYsDH-YSP^gRWIBUo-zg~pr(k=pDN@%JDw z$mh@#vf(%6LYW+qi~xQs*m|mo`kK?He+0bP$L}A7l?4`N8#u=<0hM5R>O}3XU3(N5 z82I(<&h+52aO=oG5;>z=5eMW&YBdv2S{A6y&f~vUm@B9(u$Dg1xfSVCbb3m9nqvJj zh6Z`d?xBILjQxR4|FP|0Bkhbdz3DdG!siQWNhyc=O-bU1W59H$Mww-Ky^E&ZKkb^w z;NQjwB(_U}<>LfK$TT6jQler(5^-l*N8&bfkp;Bs5^mwL!#X{e*d8j`Jt#CA*nWNA zPa3PJ_5nShmgK_kDk*!FoT_(J0k2KrwTuo5T`2${m65o*%$N{JCcZsLlge5+r2JAN zIZ%l{h`QoZWZA>O+NK4r>tXO4c?A^6(~{^?DG*d32}55sHb#)>5bcJVdN|-M+jPQ= zpATz#8IV;=A4#5>1R=Xy*x&RPYDp&#bTg326^N-Z;h?j1d^+ZH#Ix`r@VN5m4+_%P zB#IZFL51oVRD3!`Cc!Xk;!W8Kjrul24nTe~=(rS{zIEiUi63xpVcbKtF48;{xKO%o z9CYcADVNjPxPW2-w=aEX3^VC?WC_#QxG6wcIRDJ6;IjVX+}lV_j`>Z1vciBl3%J%N zfJ8ZMhD%->;Yad9L7E)ad7})9l6?TiSIRuk4wFJ1k)PIk z$m!TBZW#2d=Idb$V*`=^`StlV86w2}IO@U}F0tIxBo@o_@#I$DJ-{JAiQ<3?P{XF@ z%%rc#M-yjD3oiS>?GE`50te0SVE5)qZd&)%PVQ*lsnoq*yEXs=tdR0bQK80?KTrI5 zDV1p4Jj%#YLa(m{u;}z6^IMJ z5?k9NBZorEAbdEDPd}1SMVP(@7Sq`{PB!*fW~zy?lD4)}1Jm<*o<%Q()l=dXAt`+w zDrz)(RcluuC)xouyX)K9wQFnVzR%CkM>_0SlGO9GHANhd7y>za7+Y-#BZDE@(^lr1 zB$YNu1nP^%F2=t}idUFH?>I|b0lS83qOtqQyyQ=xG37OMN#HNAfW6l~Yv8zKJqTy% zyN+G_@kTa3N6VhR^557+ z5iL%gMzBMEtS~Hdm;B1m+))XJ87F1flZJ&02i*)bL%-+voDzEq=mmgMnU(%}a3#HZ zK!0ymKiE2Ph6B7Yyck8F1}#dzJ#1tHPn9{yw(5*jZ4cJ@tpzue3OU7=6_^{u?q!$&^KV%d%^2HHHxCGK_h? zJ&AIq9#Usb3syb0J)xbnm=g`gHY545@^xH-9b?D&LST8%}==gQD}013!O$cjW}D4tyP~a(K0RN5J*lah7O| zqcTXmRGf^~N+8`r%?k2~#eFTN9UuuW1jHQy#DEw>Ny+eqTz4g@3y1~~r}TtXsE%;1 zel{t{7di=UIpYTLTvPZHHUY>buV>@6lE2|XK?R>|ECvORYmu`U=P-}54t9DJ>`eTI{8g%v7F46^yARdGg0&}h%@P!U0)-+yXemgRo5YcDguU^) zs{2ToItNe;)?1$k>?}l50Ps)}QVR!Z42DGj2EC_!qCmnCH3o1LeK;F5JkA8XW)~6i zZ%H56x55}|R<#qPg%sEr+ZyaCcOg{?De%-EF;$EZ=OYo60%uI8uX?VYwMvmB&DU_Q zE@nG6J?*dybIm(78(EL&07ocj$Hv}}wOYwW#DHG38J>JZRLg1fxNCKp=9(^M90N^2 zioyXPOEQQ2N{x>-9R$~U0@1t)!qd~!Z`#(=lXMX#cw10`hW}$4Ak!8+nJ&U43H>fB zQ>r{#X`XSqwBms;NU(I`3A!mu$TOy*I78JN_e<_N0>|G5mV94htofZv-Cs>Qh zjl{K~Q#_|OD!Z8N;ZFE;_8w%1@lxQ_uCN#R1x^Wo!4~pzWu6Kfjm0e-3k6iBVY5jp zx*-kAJrEG@Ei1EbWD@A!5Di9}+CDP;ZwrRc<$)`H(13%)>-$+W$vINhXz}I{eYJ2`W`qG45AgfP9_3rVszcMpfB&4dO6ooUzFpFKb89Cg}@_nC~8^`M$3r0 zo)g*cR@g7U%V#qFNK}yl9KN#^4pA3YfIb=gu1pnBvz9sL+E{0W5kq9p;;_6^%nS8Z zB=!N%s1{qNhhTOpB9hu)ilST6YlCJy3 zAk&ahga`Fyx^COWEu5T)$U{n~zSaLHX$nlr{%FP9;bSH2T9Js?Ll2>bxmLPk$V%4Q z9mmZnQ4GdM=~Y3`7k&ZQca6y#IPXW}|Go7!phFrdo*g66zfK5Tn6TZ}0a+SKAam4^ zx!aYfpS?0kz^H#5oS5>m-K2Of%>cK@ibD)mtZPP65?U|8iTPApExU?0;pl;=feZ)+ zO(T7XCrP^wX%$)*27nlr4y4>rU-ux{118a{Vne9}qy90s(4ct|5u2GyO(K+%&$l%^ z&I^SXjy@;7w?<&RYX6v^wD7m>arbI2R8uxCAK zu^d*==+6u4{^#MS(G$0+5sIdfDf$C~&Z099-kApZ6rCQJa&-u_lSL5Zh`>p$R_6Gs z%}T&#JCn$ee1Tn@+iu9#*6^aB4mMMT1}q8a9@#=NHDpX#BEduWesYX$=ZEEP^W9uE z_uHNI`;MO_!sgsSRqR@zu)MzG!Ii-}#v7}6;|&~HkaXn1jlNY@-m)e5{K_ZG7gHPx z{IK;VklE^Z3-(ol@ZBFg)cxxj7@kQtfL;0G!j?le<26(RQeahTZY&%{1P2L3|Eg#Z zsm`?_(L_Iu?dnZG+eE^_3QHh^m=2m;dAJzX~yMMM`?MkMH_ zNi1)9m346QCm31f3aiyUXrNfN+6Cs)eM%O~^9g-{5Mn!9SU-iGH-v%?&3yWroQ5I+ z);tL7zW+V@2))Ro7euvU#8hgsUFrL4aExEsPP*nj&q#&z7%&s6a4HIe7PqPz&3!iCZnTRz3u`hV=&_3-Gu#xg@g^CF~2AP}(t=v0H1GKB31y(XM@V2XRvlT5ru&}b86~|CD=4N@CJ+% zE$_o_TcIM?=kz;ZwKtGPC{;$p>9U=Fg$Ol57A%aUW>ZJnm8wucA~u$4xZh8bC*p@@ zM!=v<@N44nh71w^|77cBr3}Q^9YM0n33bY=4Tb^iayzp;lyH!>w9>GPhJx9`x!QK= zjz|tx42lcpr?u&CErEdW%d{g%vQ(%3EfEUFG~FEm(C1h)I-N`b1(asJ2N`$|jSIr` zKK*y}D~k&}Y0p3cj>B6@iA&$Z=4Rd+DOh37)Dm2-!E*SFIv@1WT!e>rBRgKwKm-xu^dIDcc|O*8T#1 zW2B*rS?l{sJlxBH2coe*Hmwv23Y;oW!A!^dn}UdYi7*_ETbNRtthWpk&{aq5$-f1I zgIP{dQA0&V<>JnVPsz57!}7~5k_?qYv@N>57ZOIG8+<@FEMa5`Lgwk%{9x5}QYg;x zbEM>4@K&B&Z5`=Je4EL6pxcVdJAs6S5785Jd=Opt1G~Zlx{eB_lVVrXgQ!{m)79Pv zMKWkY<9XUWSYP!T!zvTU7)IN@QTZgx!)G(Z27@6(9*=+xZsYP0h*jeQF;L^*NoxEr z?Bk@s74A8D(up{&j3{HOI$y3N_nmKNcOH>c(=TX;z$fpNZP9auy?6@C<-k4~KXa1w z_0n`ZR6raYOk0Q^sFhwcx9IEQ=Hs){_;isPs2Ne3-W{u1*a%6p9thnKzxwy@-;D}6 zB)q4c2l18mlIKE}wo(WCV_Cz#N>4c+jCQXsmjBtBn4^u?&bSTeiN?Yw``$m@rmM6C z!JVl#fKVxJh!o;4?K&+D>por_+(Y-O@h(A5^})0L&6EI5SCrpk5Kg5r!{Ep?OJYm# z(%33@kmDu6Qbh_taT^F)G8qt?@}w8q)K}nsMUogi?e`p(#f~C)kRf?{jaljCog#Ru zo4)}A^g%~t_{D3eE+EoqjOmtgSDN=CrIMVgxvU9?4*{)uywhO^K_HeXb?8-@pxa*e zq~KBLN22CY0z19Q-hZs*$)#TicyT)5NvS^fcVBJfx8f_?AAWSI-lnxgdYXW$Yf)3@ znkpt(Ke#ttf807{OXN>RXu}R(O5TO){SRr zMem6dK*9y59AY&2hD?(tg`l|FGHj(asgiHe=61y>3N_=$Tk<20Z2%WLB>%Ciq26N``d->sulu0PjL5YkNMZvmy{bXG(cdx>&50h;cp z;@0M7HK;DsQbh^`>^C8b_biI30fZZR%+9y^6-@tjFPOV3kt^B$8Q&lBZ_^mSRJ!l( zRVY!ru{(Qs6iEKA*Cy=VG!yHVDR%lZF+{+P0Eivm{8C<}u!MA?-R(aH4=9BmNx*X& zF?I%-o!E{5sqsd9p$dveg~Z|!0p_G5MIS-UDsgXg3D@22M$jY=XuCb?yR@aOj4isk z@jGDz6g^)1_c%oQlxQKlU;45SuMQaH?n4y*Flz`OpK*cQ^vy6Aj;)foZFJqd43M}x zDeOkD;157yMFGZgq#CR}7-N3%>&C)xPZxBC(64^q_qhHG6}1 zEe1muGgH3h?IF0&KM-f=zWu&c#tCbWnx*2~c++qD9R@_JKukYT z@LBSjN0h?MRzexuV->t_t5^<9L#1y)N~Qf{$Dt2R7k-s1(Gui1}-f3#MePou-akU@jo~ zaoKhmpB2psJ($o&bUm1}+&iqX};-A+1{YmJ0?aZ^xdNcr;h zAwin|l|sixyWkd{+)HY?E%AT>ukVY{69uoTFGKk$#WNePeglxKpYB`7Wi66KIGBbm zQ>ZuM46q{vUa4WaJxsdn%0t9(eT)QXQG+#;GHqOyImAXE#m(u6i0=q75X?gqI_^BC zxV;u{%|tji=ly!~dh_dVYRDw!nIHqN1{0=Nldb@o$T&lF#xn>cEvM=B(Ck{b7%$%2 zCq%%KKVWI6Mc`^rLrCZQ!tBqByV&C#dMn?4*FAfKAV;cfrGEmI_d(y-i_m;L!a2a# zYSPy;TkX*5^Tc1xtgupoH!D^@P3H04*-x zmS0sy@GR7z8aP(4p4v;KxO#BPsYxOL?|p%n=PgU}@<7o*r^|8sE`q9EMhizQPXXh( zxoJ`b)AS)x4w6M4Q3$3?Awt}h@*YzWuu5F+(wJB57uXO!?QpKeWv6Yo&^?- z>3t8zl!a@n@q6z>(wir?+qSHn0BLNA5>b?sON7*8d;4f%DLnzh6&n*JWY1?ln?24= zpnWq$*$wfTND^c@fB{jNB3cF5p8Fq+dg?bJ0Ampf`l7|!%G@TDc9>9Bi3CmBXVp(n zDmRfQsG`R$90<9s+nV?mA5s)r;TCMq44rm*Moy0XqeT{37pb;A*S5s>T+l*}RVZUe zHl&{6tDV59bw#VP`w*f7xia2lD&t+31iEgIHD;P>evulmAPTmkA+C3{6mWLdwEto(fNb^ zJio2MMXm?j?vD*5vI@+s9oft-9SLMMl&*NE2q84jO01nQ#CHc|3qZHYYd;Qr@gxJu zHLKU|V#ABTUxRO;#ZP7hDaUI2@u*lqXVl!;OVHca=R#;N!fl|M@H{j5rGjJI@gq?L zZFUW)J1av3)N&|7aQ~aRO!DA2870St-wfXQ?Axl#jhC zEqi7)={G|e{^9hmUtc>qPWv^=5u&DO7I<(usR*ibxx7LyX9R~1@kDJC zkvEM`j11l%i|4dy7Z9F9ux^z*k;ZL_y;c@5zRIb`H2?3x5a$ z{2twQ4GHH6%qD*rgC~xkd8oPjsv$zq!WZa?xV$Ip-*eWE zJl@U)Al}HmCUyBn}1|bRJ1l^$N3RlHe|s58WI6zY1X(oQO)t`IB>tzoZzmIwX@1qJnJFZ4kp;?B*o{|MA)Umv)(?e zDS!9nZ^+H*V6Yt{EWeoD=ZrX6vu_M zejUImi2B6iX@%Vne4}DLcmgj2e_^L=BV(sffwC*om~ju>wMS2)-g9g_q1H|i7bn0KbbhH*o4|&6NESiF!n8-^q+;#sO+jnU~&W;_abw!`)7g>Q> zAop$%-^3eoWl6Um18$=a;pT?a$DL!_M-wo1P~+H;lcGr^90S1D$@9gsK5)Vppf4~G zOdb3FCN^Ff*26(H_?66ux4-lB-=q=hz_?%Fv1TNMD*uNkeGWG#_)PsqK@Z9tDZ}2N z>)v0`2kny`RNvsfBf?BGP}N);u|J8+Ejzfu?-|jDUl->%c=0Fs*Tpdy`V%$9c=NVPq=zarB1L~dy$U_r zKRqw(K22wvku~Onrx02OX?Wn(PgvzZGWNZ|{=WX0QN=lm4pIczt5gF8gP*f&2wk+m z!G9Lqc&dbP3-8+qyhu^J+bWDkq8+Rn)tOJhv9YoDw;h8r5}{%S>^6d;P{YowA9x{I z5(+q7Ha}>hNJ9>|j?~KNd+sGZx2*{`?hFQ$hXV)~L#z%$6vk18^cVd#7Q*%v?4q!B zRMp7Px57diMspmNyXIYw&dixMZ4H?2L%Q~Ny=E4qAAjr9S%%{CaO!Or$UVGsF*>!@+Fye`CxkI5+QNk3_|Et;9HkKb7ZH$^dsw%m& zBfzP)-W-2u>=95Y+w=~atR{iscC9~?nT#ryYSyM`OvWLe_s(R=h@HsE+4ezt9Uhcg ziQtUK+^8l5@5_mS`$YrMAjBab9^fw*lx;}-livmzCxj0BfesXB?fLtTJIEKCqF^m#dK8IlMyx zKO=m=G0+qTFMwlM8@wRC&M9%s2O1iy5m=5ZWcS_cNBVETP)EY}K~)Rv%HfnKbw*GU z2SO(AQs7>|#l_aNv#KXVYzZww(V`%fF9%{|R}bT2^3`;`12+}+2R2+Q%i+Hv3+#gLJ4dHtc^G~qbTFDb`u3^W-$u&TlZ4h`NANpi%WGwkyDKZ`1<%=%^Aqxd zw09K~Zf>*%s*Gnp1qZUU?;vQy4uH*#jfV+Y>c7yR%^PH*{v1G{Hc#l$TkYvx<1<@x zPk#!QIo=e8-!>Mx2p4X=FK@L&1r>irm2z4OIW%VIBu`X_kUTTxTlaz}zCt9fZQI91 zlHGr`S_0h;AqKszAm~XSH6<#51)P}$4ePU;;o=a&h<|mKg6@sS6zl$ptxgOd**7Zu@tDOB?ZDQFg)~sf@S&fDT{njb4ddfGEjNTIr*kuM4{Qmw4yE- z-4hNFPpBjW;~GG><<07(qX5gc;#_@~nkVo3#2{{HLwI4zSP9}_w?`4I2`I*X;A7m0 z!+%!rA5JDOrd6;>xVXAM!Rs9}4;1O{2`?4tcBuk#w0pj;>NcRji9-zFm_AT))U)sj zYO4LN{iC$zC$9J^5zMLzIUJ!R_PNzI9BUegb;n(@wUsc~V9F4jL&Mk?j9tu;q#l_z zODMBV!$aeroz?&kz3($Ka$HxztSTb)E>M7NrL3ce9GL`;ZNc(dsbB`dNJX-_k|E4NrmZ6>`dTv|@%n7%|uSJL8O|WDN1+tMouGyg1&L zwOTK*OMrcv*}x7Mq{Ha%JV&`Thq%UbsC1YsZKhv&I{=Pw8#R7wvf4bDuaqg`pK(J?wB)sRO3TOUfSut3)Z=xUi2OQ7?1Wf&ne#-Ks;8T*n!GtbewFHPxK{N>uiRqXnxW@nPV57ikz(a9- zXzd-J3{f9}+x?P*%AyZ<5`wb1(P_P|vcw{S)+=NOHCE@_zp4WW5gVq&n{uK`TB_$J z;Ta~3iGKoj4*K*Gdl#@g+n`GwwF=Y7^9mA8cvw5lFUHW{#(JU8f6iv=2q-ElviKBC zO|L}m(6$7c>nkKN;|p&HIG5lmqypG}WY|Z8dqG#@vE{~1Q-k^_))L}vn{I&j-*@^+ zBMpVL3d~)}@V4zRhjtc7p#b`$QS`td_gmtSKZX97V{oy#5aUQ}65xSrtCWHGYpZ_~8fGc1L=S8<_*|U+O2<45 z?rAL1sx}PVSKylncu4!n9+IgSke{RYG7_k-JpVROXTc}A-1w_FaiAU`s|+az*_gB> zZ$bti%+m*e8{3d*_IvU91ym(4|2(pAz?Yuxb2xHEJ(^Ga_Ek=?^LMm8Y zOy~*k%B5j5`byF6ly!o=C#oGqaW-)GpF^?>s)>pQJ3ovG#+;{)$ya*?TjzSgZ!X&$ZRtEOBvzLLapZJ4HVu(%;>0Wd54oC7; z!etgZ9(ZN}JQKdyyA7@@8OWBU-sL6=(l8T@(-aHvUb#u&brU#Pb;|vR(Cpx5?=`Ip zC<)aebyxU+I@|SBiN7p8C|_w6PXXVSO<=Tma>t2$!=d2rX;9=Yq?piTM8#xY|IiBu6D zfPyb1DEL*ffqe_*#XRJm#!*hVA=l$%_yzK4!a%o&q9de88hGf5=i%}ggfLarQLqE& z>(o-&Q$$>Jk1DK0#4DcOh@^){Wyd2xUkEyUYh8GM63C)XN7=V zMO(qHUk=7Pqv2UBqq|0=29<>xNSlKTJa)tjJop_hlfx=G+}yo&<4KF4Gj?rS$1cmp zB~T>*#Lh?xFCiL9M=*J@bb2y`(CKfAaj=28dGZ!x2T$98>t-@7+0eSLwQ;HM?a`jI zbpgz@z;}WmDM3b)#egjmsoJdIT@}>Tl*~5zM;NH&*}N!BfdZR-xREBw^g_z7kd*Qx z%|=vbxBxo17Nr=V9P0=jJkP{<0|V|`dSYLm^b;huPGX~x+j^fUmdu z)571AMc)N!4-k#e*a*>w3`h9}Rvpe(k_t?LiinwdkjAR+W%vP7GvsBET6?msg1eP1 zjI{;B^s2#e{>o`W!;dFc0gOnK!HL-aV7yjJVahh1lm6nFC*?B_;#|KAXP>DH;9@(3 zZz}>W;pm}|@Ymh{WdH~hTNXGvF?NOxcejnuRM76Gv2h%|Vp>ep=+j^cvQIeh6J=@H z1Uy>)ST`S#pEIhl{0fX=Z%&q(?m%jykjdqmR3+B55TS>Vq#-oJY576_L0~;sPAm^dl$`1#!twY`vWjh1hmYgn^EZ`^-&)Cxk3i%mI0fIG_a6ko`Ct~x3l`K| zyYH$zYs>#3oqEL9W4@W=s{^@jKSKpf(B9Yhd;I@JhP2?qgX{MO=PypBp7?m`>hSA+ zu2GkdI=%LcB)S$(z$wa`cP~Au=kJ{i9sRy`-^_m3#o69(+fR-Ah0F(iDYQqxl{1oU z+2cU!!3Ry(2%4nw$2r^o5@n!GngdQ{i`%ZfGvB@R_SxhNXM$ZlKJabL`aMC2E9P*B zr#o-dZB(^)se!hz5tL)4%@54KraXqbI`UR5UTWs<8^Sgii zLR=(;u8(AjFUqg|k1!31Qbi@k8_e#+je7i<@0U)!q7G>`iM;YT6;oau zy#IavY{B4*9P!pGy^(_ZBpkXNqUKM|)xF8r<8u8hUH{ZM|7T?RqY_CnceevLQ#^ZD zUYN$4_cAt@iBE#xE-3zd`0W0PQ&-Np!t1G{USxIpy;OMaj27n~yC1c%)vfQ~7Wu~Q zp_;eO=^k%X{N1maknq^`nf!;TdXuP;tgb*kjiol{e_oA67W~ZUyP4|Dd0ao+E0$s_ zDj8G`xA(_x`Q7&^2Hv6U;QD*e#AD*;PFcm- zPnz)v_G@Eg+g!}DdqRyucL$h}1@1WVyfex#_@42VDk@lPEWq{}zgq{LiCllTytrf3 zqY8S|1;&}iFYcj=6L;@C?R|W8q&v|vHBTn5N6hv}-l@^C=Yqo9C5sbA>?0N2JW6%7zN znIboZny2d6NrJz8b4D!CDc677WT8_@>=eA8zW@CVx_%J*cS_Tm9(LodA|3PDRPGb^ zqn_UJSm+WC#U|O-pL9@n9W-hWcb|RW@piFl+rE0QBcoT_=fA=$Y$w!yDU@@iZ!OO- zk(^hqcz>E~r5j!Vb)52E6Y5uF2I4;y`k)u5J^s82SLZ)p<4ad98Bxfrx#zCH{Z9`K z{pmXF_qQmUGNZmI&RfmZBq&NtVOcr?6h?EU5DS+e^ZRwGn;6(I6Zyv8FMk%kd{a9$ zaSvgb{b=6w;{~I)0GhAx&YZ0OFSAUiQA}07JzL{ntxai))jzW>)G(c?AsFi&aOQlN zVAQos=b7KMIvGLiD7EFbLcv0hL_(_jRI=b5k1?+;CtYSk?t59tj=b%CJlW##MQ^&z zeSR1o=1~7@j9hvwj0g25BQ~@^))`A5LRox!*r5A9%6+D2OMKRMj;OSPiL&kA%1`}z zIbiweTjogG{78<38=!Re&#Y6EPd3KE4UWmO6ZtR0$4w!@_Mx8j#7X-f4zI^O_0RkO z#`u!k(GOqR~G(%3EIM&d3d?Q{7aJ%-!Fn2BZORgyyT^t#$yr!r;!ymfVPwf2g zOyOF^pe@-o!-)Rt&VqNU^Ba5oo)X-bL-I^`(zqZ@9hS5Fk5&jX)cBEKSrpu-JuxSX zmFiwuA+4ggwcKG>4~wSTxwvFiDb@9mYTB1a{r{X#T2|w@Top~*9QrAd%tb^ot@4Z)x~0u z1tnuYU5p6>MRPf%OXBxe39((pi5KKPyp%~VRwBFOwZ!0sNbR= z-gaG)9i0umY$hgKG`~1MstK}Hv#s~GU3GK&;x9G-Gc=(IQSRAI``rJpz3={NGV9t_ z1`CR!Fo39l1;IiQ0#Z#Bl_FI-NRe(Rh9bRWKtK=_q=c%mpg<6i-icC$1fpO-ii9ds z0upLMNWPPKhw*vGXT9tD1BM^7Sa&)1IeTAapMCi2rYs=D4Ymsc%g%|DchnTIhJ<9n6}FxV0a2Sx*H!nA%-e`v54-0b(#hi>+< zP?nqU>9%ZXHHrF!q=^Mh*a9e)wD0P$z!C?2`kjEj+F`k+s%s0Jsa(kQCb3%Ps4&A; z4$|2!h^;z^`~BMPoW5D(?O7fcYZWdJ`@RZKZAB6{(3s3Vb6{YLNBo_T4%{w(2M*lr zhB3xrPnBAC3l9Y^brQP;OMTchiJYL>~5LhAvD!cM%PmPMvL8P&3(b>l}`@1p5J z_@M**WjR_ZS2d0~or~FvV@1ZA`I=eG!lxXCHFc0;lA4g?@}VbL*+r2WkbcCoYqw%E z=eg9uP;y_WM2p+b(qKuyxwG+YZpWBQFs5N-WS7iu+W0zYSJCJm8h5E@vv&>D{@Q0) z7yt7Fockg@+B>VFU`A;C0i&7E_SsEDeR+)_lRAZDOlhf_-YA7plVF;~ckvY!X~yGV ziqC16rp1UleHGx`IekT#_E9r+jD%2WGwGjU>JD!VuUS(zjy1y9hJzL~A<|8FE06&w zOK|xU+I)n2eGRMS(~(laqeE7v1&c#GL4V>GFpobT0P8;L_v`Y%X8sPo=u@&#kSN86 z+Cj(|7x^PW_;>!aS^kgXs$LP?b^(vjjO82_VMz-JlXtoj9s5mswpC{EjU&&AqX*wd z@3x)b|1KP|{Au||6Bk8CUaDIuKop?%m^+Y+*J2KQ!fp;? ztz>64vX+QNp*}1`p=+fi77k-&{8LuZ2d+n4vi=dyZ#4c??xhx`1ZAT`c%P|KVBhnO7$c$CT$pwL{i$yDWS~r7EbvaSQ?*g#P0THKHP`8 ziBnQ}ciNUDgkq7UhOskY5V{znz6JXv08)F^f0~7R^tukM`V9v-^O`(B7WEW;IZor< zp1k|wlU{V1`AMghv^y+VYKZSnLfCB1nC1&OQ#KegMU1md&u?TE1s-hMi=xsBpU?ii z0bjTF+T8{_7uAz6uUOvYKbTm{p5|+tyY;dhWA~U*f3MZdRCD?b|Lkx z(jKkao5a%Dycux%p|&;<9kgf$Tm>vNPLvVpshA;+j|Je(xHmZmgU=*SH%PzUEjj`1 zX?slq*=2sZ^Q;3m?uvNnCI}Ch#v?1~@?&g)__za*w5xxdKykKj93G7!ZPb%)zHX0< zul5*K<&B8(Ak;}nj)CaJT&%m_!;f8W0p)s9f%JIB_jpNjHIW&i_n9;=VPTNSFn@fg zJ8!6xngc0rj^jMI`vdw)@$dThZ#PK2lR~BMuYSK>a}8;aO2l>gFYzN6`Nbf)&EBvs z9-9^SUMx0EP^?uD*9-=1Du}L|UcT9j*zC>I>c%UH()dbkB9JOvGdJnF>l;|+MpA7~ zxk~l;l)RmJPVV5{SnsIL$%?dnr`c?J+!D`L=xnugzHV*&mD*^tQ zdUI7I{IGP;Wy@m(DYLd6AJbCoXqszMNGgtajXeEsjNz}cnpu94NnaxFAnrE1ntMz# zi!d-2PF`R#7SLsouVPREVg9nEx0h8=ghL0>9r2gc+@zaS#cxp1Oe#7RpK%bU+#K1z zzKq0=oxk{6=?6bE4@rZf?4un8W^TsGHwt|+X=uT-A3VGcs7?yWYKN}wO}bMCw?9pcuz z=3j`Mvlq@>(O+4BH0t5p77^z{g|B@-O`3tco_L-z9lDZW5#fH~u6MNrDySWuSuC!D z|DK4L#dwD5{;g;0uy&H$5tp|b{QYDX&rXLG1y7#imw+eu%@@|rW1NbjH^##KB92fF zs0+E|N}&^XouPPl)d=!`gwaR2Y$*C!Fi9iA-mvEF#YeBi+16Ye86hy{2pDq-%C@$G z%3+Jn=*LI{Y$)Ctw$ZPJ`Xhawhm?aeX(qpo-rGjygYY$L3$N_0qeA~wdGOBAB$DwC zE4!U>=7UOXM_2X^ebU7r;O2jugL7^UxiP+b$HenA7OQEY$Yy@gt^Fum9zO}OL&c z{vwJRxoNI7_NM1zBXIb;(pF)Nhs|^1EL6v0N6YgrCJAu;=Rze){nN=uMunz2(PB%! z@!PcVcVrNnsh|OQXEZmnOR}=X--{H?Op7^%j(OQI@rlJWVpTOg-7ZEi&ii4NTPR97 z?knbzFZ2#BcOZoeN?UVQTDFWvux|^fw9l{8wyIx#MmAtPg}}q$&i2*eRSHiLrIIGP zslVqEG^FccFh<#6@f*zs@$2HQ-2CSJ)w`MRe&aIYFU*;W-`mCdkcL7dtdfOpiGv2Y zh=a6ff#1j2z`jN(&*cz!WL54FepFEXFgzz$D4#Iw(W4{(O1^G%A0!?prJ{F*6XK^b z*=25EBDOBSN4@THZ{}FIz4(sGmR6D6>?tJDF}1w8ns3^J&}eUv~CXRIf{M$1CpB7AfHm z+;t>e47KZTY4E;cJ||XK9I>xst1v#t&K=jP#VgMD@vMflM27WkXi}H&@X~xk>4!&k zH=ibb@9LVIOLz7q*>v4sXkT+MDo^wMk~eLiIA7~a#xxz&A(8urkPS;5+f#@dC`l^| z)3@zZMbwY0LDkuo8-Q9BH2A&`-$9Jw5t|9pt`ap?FKO26nszbYDTZx|xEWO*Azu=F zy}`bT?I?Bsx9S$f?O7_baq`;>B2)*+fcrZM&bh3nJkNb?pyjPnM1B=b3B{o#o;*)B ziqcfbhBq~sCIz>4PWf+@4`}BDo>&G|9RF38PLpSI{P9A-3}fbCQ10e9auS#6kXR)s z`$2A8JE3Aj^0%X%iDG1LHTTr8X!dQ~UvBSGP_t5YVa^cqXOWYnLeYflzvpQ@Hrc7r z`^Ma`z^c~Q$PcnAR(4?R^+Su$lWl`Mg!C`E(GF%>Z;#XFA0x9MH5nRh#(iO0CYo#pm~7Oe%pKf5?pl6eXYCFZ+u_HdfDS@w~DMUTj%` zxIL09;!qb6k=9jsS?%=MRaJnam(!J6pUtLWm?FBSzf*xyt6BB3K3T7}h*F8NCnu;; ztz3j%X>jJF62xq8!AY#MqV;Nei1|!zy*MEo?FqfI1)jA_!RX4uF4}KZZ~RO=3gc{f zZa&0tHz4UPylxld+Kxa6huOp?WxZ`y<1=k;Tu3 zddBLHjtbl*iO2s403RVD*xWO_UR+x-FBm6LX#_s^kvQAJhhAr5eP(-!JYSj$;k6DW zn=C%)V}TJ>p?!b3!YH|}E>P9(b&Mm>At1Wif~KjElkSh69U^$Yd6Us?O>;6rPRc1R zu;OjLQga!c1-4U8>9o321?iMjY*w*@I-8=mgn9S!6X&N3*90Qc$~JPZbD1ALO(^>+ zGcR79cwt7l2g+Q!(gt@@o>+nFIrB;U|+axY^;KT0(! z5;A~&x!hwk4PWbb%Q>utX(~&N?I;#K)SD$g?L4$RyR{MSd;w5cdT0}Izna{)taq1* zF>u=-S}56*8bVeKI6A56**ZI7j7Dx(uCluZF>}dY;XXz?5-2n;6~*D;)!c3BqF-S^ z)>rzVznXgX080+D+V{-Th&dSVHqX1thHpJu|7(amqsm6-=Orm&$7OM{RbV zId?O;&w(RFMugIXW|Ub}dDw=yG~lEf*2hLlY>~?EZNk06@Iwi`b(gIR<`nGtK(I&~AVN&CWQe zd-ZkZ9n3ks?C{IADLAFF_Gna@(dTTB4VMBCeA@AqErBK3lob>5JhN;Y^UOyg3gc zDyx-iYdeS6z?(3<4qnRRa0|@c2`H1XhBZxJM_91!$~*D#jwhaSj>9K=pf!BQ-hul; zgO5TQv>dh8PrQ%w7j;;Azf1Ttp^8&~qDFMxz(jUhMgj)0jo`QTw|%QjnwCjBh>Nfq zIT#Go-6F9b2*<#F#6*p_?PCt2x=?_FntV=4wua=<3n=iivsa-fdGgW0 z6wMTlLG21uL0;C!Iq+d_i%#(fodyS`rh1L7y-KyltS*pj{Q93NbVVS{eMH(ygVkvo zhbDxX>*_0&*v$g#v6IK+WFitAugiE|bmMNQzAuxN(7rh2+|zOFD!wE_+d}cNa2wFM zYO9yyu#DA8tRU@Zn}AtEQn3~;dxK@ARf#hKP~#Qst_Gto;dvzqE_>0HIs^5bdmSu0 z*ZjX6;t9Sj^)UI=BZEmh1NV(pGI6x&zOzs2q=7;86j%{YeBRWLlPgJu=f0G!IVx{| zNxuW+I4PoSu{gni;pAm)P8L0m25PkA{TUM>LYEO-Rj{S zWQ-t(?F1AuO$VYG!AwbHDo0i0Y-IMnAW05CkqK#G3k*_abGgUIG1gE}?`(`iBg}nm z{wpyP(V+M;c4GmHR6CU-uq#%667tCXskb#uFS9J@>|;9cBMx((B89OV8OS*r4Hnz0 z3m)xQ9BM;J+*G>9`;vBc4Mv?vDn%Wdw%GaVt2&z~P>zH#5gEGWEak#S0~2B;@cIL( zcp-GHmTWjfj*x$fWKhkImzj$({My_rznUBo9qB21{h$*h#U8BbU*^&~SztSAFZDqF zOEEV@66D)Z`nYgkQe!%uOyi#>QM>#wa<09fr*gWRr9u~D1=dP^$pf_YxF>=LnKK#f zqee#$RXSG3(Q!<1gnot0fs%lwZ!?X1rQYbdn$kbiPhf2&_UB1<`#Yp3Ye`mTL*;lr znb(Ytyua5ZDOe+gyO-VA1R}h2Z$w~F))i$pvbOO9cG&@*4J@@2;iPTmC$Z8!GrzY# zZWgrq)C-V-g+++cfkIq_-&5lDwWhpq;(V7*_Vo_?_=^|DKflsS?X^uSbm4|by40ta z1#JZV06t6Z^+WK&)lcfe#L={GSs*PS>~Q1Byjp6J=nR6;Y6eLcrPj`UX1pvypL_TN zqTa0ul_ubW<=E#~on^~=H6zqMbDIVxYyxqEAv%dLw5X-vz>qFct+zCx9>8v;3-r4F zOa1M)$V&nvw=och^u+q0wXO`yP7#;zT^z@fwH_wp%s6j8a>&Z;YQBSVX>Y#M+Q%+7 z&?g%4)~@BjS*SC2+e^Q)0&%2y~r-3thGanwG^tR?p5Lb`SLLfR64(NBGv6&B7YMB7?;Ixor6k7rJ{Wh6ZO;VH zYg8Ri>dsS5i1|#H$2c0u^0ZR>sCoFudyeJ|%EX}Cdm?t1JZYcRek5gC$|Uu#^5 z7~|5XuJgx}mhSHt%-|hsFX7fgiJz&RSqW)8$5AZn{$*{pi3|4TT)>2)BPI0Hi))?J z_VwRtpFY^*xJ`^iU779cTN~PcV1nwT`ADJV0wMRS!Eq5>M3&}SoHWrh9BoAE*RlbrG$N|Qa7vD#DhMSiLWdH=kaBLa&e!ya*6w3#dBjD%JICq#0SSX zz8}39c(;pC4@B45@t!&8)IKG%z1kZH+~1AkwGDv4otQ!URp3^bWj*4Q)#}8Xd&>9Z zhm1~t-{YQqMLRMaa2aEecg}G=+=Oa5vV?CR-sEDbjCV2S10qD;j0%9f1I<&uZHm|! zhKLyR*03G+4sk-!HGGm(Uc!CRvqFL!=s%q4u)Y7&@&b7J65wbFUl`JF3vc~o+a4Kg zlif!rxzFbG*W;$1U&5G+9Ppg`Qe3Q-I&&1D{e13Wjmd{S=6jspa2@qBK%Ibxi=|oz z!pl9!TaP>I+%ZKNwi{eR)Gf9?8`Csh;J3PaqaNSU{YoppC6=F{6ms~h^VbML?>+vl z-V}wu$bJ^9WY+op72nuj(Zwc*12+?B%7=pANmLFQ==E~>ep$!z`ZG7z^6%~9G65^Q zh(YVan&hcGeyfJ!Xh(90h?G4hL%u!@_?AAynu7N|0m3w%?JHucMkSwe+<#O-|CK=} z@cIl)CpD^0;&Pjv!Sp1aO0_hQnkw-aZ7gn;)tR^dnvmqg;on-SG56Q#ba4YvS~_vL z_P_KS2xW(YoH+AXT}a?A0~9iZ!f`_`Rlv0>l%*$h)=x71y!hWBM+1lGvr)%F1R01=wV}>S1$y_^!Mk*mmtsH z{%zb{x@8UO-SGKsw!gGL-Oko?`p2vdv&I^F(jL3qt(E`qh`jE&`=O=eJtEJF{T7C2 zUdBT)C~gF z5GX>(f1>QyI|!`i)O>(h{X7c)*X`n2w+rA?`*l0R`B!X34K$Y(kSICTm}CU9wgy;e zf8I}P1h{U_E5LIg%!IDY5Q(&v+1Uea74Cx=P{{KP>byACLIn5?IvcF~AA-69t6{t| zL*UR>N#)O1e3!g8Sec7zH3J052WScJ zi&M^-n#g~>+w+gX`#;{Mg)JV&@b{swFTNKvQ**pz`_ef~9G&QB)Cvcp8W#qTvN&&y z_kTR@dN?qh8*X_BZ$ZePEBXiX%v&UrF$2)_;h`a5gjj{FcE z;JgX}6o-{>nFtf0kq89t1-eCkVg2gB^R~IInq+Y45j=oqSybm+?7va)u&5wigUI9=lfl{70PVnm@3$Yz+a`4pa1h$Ubzcudhc>8{&GOhuW9Gsi~c*N t|4yl2*Tp}7`FBPA8&LlL;^{l&Hpt4$I6=PSliR?b<~7}`g{rs0{~s87eYOAq literal 0 HcmV?d00001 diff --git a/core/capabilities/ccip/launcher/diff.go b/core/capabilities/ccip/launcher/diff.go new file mode 100644 index 0000000000..e631ea9fc7 --- /dev/null +++ b/core/capabilities/ccip/launcher/diff.go @@ -0,0 +1,141 @@ +package launcher + +import ( + "fmt" + + ragep2ptypes "github.com/smartcontractkit/libocr/ragep2p/types" + + "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" +) + +// diffResult contains the added, removed and updated CCIP DONs. +// It is determined by using the `diff` function below. +type diffResult struct { + added map[registrysyncer.DonID]registrysyncer.DON + removed map[registrysyncer.DonID]registrysyncer.DON + updated map[registrysyncer.DonID]registrysyncer.DON +} + +// diff compares the old and new state and returns the added, removed and updated CCIP DONs. +func diff( + capabilityID string, + oldState, + newState registrysyncer.LocalRegistry, +) (diffResult, error) { + ccipCapability, err := checkCapabilityPresence(capabilityID, newState) + if err != nil { + return diffResult{}, fmt.Errorf("failed to check capability presence: %w", err) + } + + newCCIPDONs, err := filterCCIPDONs(ccipCapability, newState) + if err != nil { + return diffResult{}, fmt.Errorf("failed to filter CCIP DONs from new state: %w", err) + } + + currCCIPDONs, err := filterCCIPDONs(ccipCapability, oldState) + if err != nil { + return diffResult{}, fmt.Errorf("failed to filter CCIP DONs from old state: %w", err) + } + + // compare curr with new and launch or update OCR instances as needed + diffRes, err := compareDONs(currCCIPDONs, newCCIPDONs) + if err != nil { + return diffResult{}, fmt.Errorf("failed to compare CCIP DONs: %w", err) + } + + return diffRes, nil +} + +// compareDONs compares the current and new CCIP DONs and returns the added, removed and updated DONs. +func compareDONs( + currCCIPDONs, + newCCIPDONs map[registrysyncer.DonID]registrysyncer.DON, +) ( + dr diffResult, + err error, +) { + added := make(map[registrysyncer.DonID]registrysyncer.DON) + removed := make(map[registrysyncer.DonID]registrysyncer.DON) + updated := make(map[registrysyncer.DonID]registrysyncer.DON) + + for id, don := range newCCIPDONs { + if currDONState, ok := currCCIPDONs[id]; !ok { + // Not in current state, so mark as added. + added[id] = don + } else { + // If its in the current state and the config count for the DON has changed, mark as updated. + // Since the registry returns the full state we need to compare the config count. + if don.ConfigVersion > currDONState.ConfigVersion { + updated[id] = don + } + } + } + + for id, don := range currCCIPDONs { + if _, ok := newCCIPDONs[id]; !ok { + // In current state but not in latest registry state, so should remove. + removed[id] = don + } + } + + return diffResult{ + added: added, + removed: removed, + updated: updated, + }, nil +} + +// filterCCIPDONs filters the CCIP DONs from the given state. +func filterCCIPDONs( + ccipCapability registrysyncer.Capability, + state registrysyncer.LocalRegistry, +) (map[registrysyncer.DonID]registrysyncer.DON, error) { + ccipDONs := make(map[registrysyncer.DonID]registrysyncer.DON) + for _, don := range state.IDsToDONs { + _, ok := don.CapabilityConfigurations[ccipCapability.ID] + if ok { + ccipDONs[registrysyncer.DonID(don.ID)] = don + } + } + + return ccipDONs, nil +} + +// checkCapabilityPresence checks if the capability with the given capabilityID +// is present in the given capability registry state. +func checkCapabilityPresence( + capabilityID string, + state registrysyncer.LocalRegistry, +) (registrysyncer.Capability, error) { + // Sanity check to make sure the capability registry has the capability we are looking for. + ccipCapability, ok := state.IDsToCapabilities[capabilityID] + if !ok { + return registrysyncer.Capability{}, + fmt.Errorf("failed to find capability with capabilityID %s in capability registry state", capabilityID) + } + + return ccipCapability, nil +} + +// isMemberOfDON returns true if and only if the given p2pID is a member of the given DON. +func isMemberOfDON(don registrysyncer.DON, p2pID ragep2ptypes.PeerID) bool { + for _, node := range don.Members { + if node == p2pID { + return true + } + } + return false +} + +// isMemberOfBootstrapSubcommittee returns true if and only if the given p2pID is a member of the given bootstrap subcommittee. +func isMemberOfBootstrapSubcommittee( + bootstrapP2PIDs [][32]byte, + p2pID ragep2ptypes.PeerID, +) bool { + for _, bootstrapID := range bootstrapP2PIDs { + if bootstrapID == p2pID { + return true + } + } + return false +} diff --git a/core/capabilities/ccip/launcher/diff_test.go b/core/capabilities/ccip/launcher/diff_test.go new file mode 100644 index 0000000000..f3dd327fe9 --- /dev/null +++ b/core/capabilities/ccip/launcher/diff_test.go @@ -0,0 +1,352 @@ +package launcher + +import ( + "math/big" + "reflect" + "testing" + + ragep2ptypes "github.com/smartcontractkit/libocr/ragep2p/types" + + "github.com/stretchr/testify/require" + + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" + "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" +) + +func Test_diff(t *testing.T) { + type args struct { + capabilityID string + oldState registrysyncer.LocalRegistry + newState registrysyncer.LocalRegistry + } + tests := []struct { + name string + args args + want diffResult + wantErr bool + }{ + { + name: "no diff", + args: args{ + capabilityID: defaultCapability.ID, + oldState: registrysyncer.LocalRegistry{ + IDsToCapabilities: map[string]registrysyncer.Capability{ + defaultCapability.ID: defaultCapability, + }, + IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + IDsToNodes: map[types.PeerID]kcr.CapabilitiesRegistryNodeInfo{}, + }, + newState: registrysyncer.LocalRegistry{ + IDsToCapabilities: map[string]registrysyncer.Capability{ + defaultCapability.ID: defaultCapability, + }, + IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + IDsToNodes: map[types.PeerID]kcr.CapabilitiesRegistryNodeInfo{}, + }, + }, + want: diffResult{ + added: map[registrysyncer.DonID]registrysyncer.DON{}, + removed: map[registrysyncer.DonID]registrysyncer.DON{}, + updated: map[registrysyncer.DonID]registrysyncer.DON{}, + }, + }, + { + "capability not present", + args{ + capabilityID: defaultCapability.ID, + oldState: registrysyncer.LocalRegistry{ + IDsToCapabilities: map[string]registrysyncer.Capability{ + newCapability.ID: newCapability, + }, + }, + newState: registrysyncer.LocalRegistry{ + IDsToCapabilities: map[string]registrysyncer.Capability{ + newCapability.ID: newCapability, + }, + }, + }, + diffResult{}, + true, + }, + { + "diff present, new don", + args{ + capabilityID: defaultCapability.ID, + oldState: registrysyncer.LocalRegistry{ + IDsToCapabilities: map[string]registrysyncer.Capability{ + defaultCapability.ID: defaultCapability, + }, + IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{}, + }, + newState: registrysyncer.LocalRegistry{ + IDsToCapabilities: map[string]registrysyncer.Capability{ + defaultCapability.ID: defaultCapability, + }, + IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + }, + }, + diffResult{ + added: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + removed: map[registrysyncer.DonID]registrysyncer.DON{}, + updated: map[registrysyncer.DonID]registrysyncer.DON{}, + }, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := diff(tt.args.capabilityID, tt.args.oldState, tt.args.newState) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.want, got) + } + }) + } +} + +func Test_compareDONs(t *testing.T) { + type args struct { + currCCIPDONs map[registrysyncer.DonID]registrysyncer.DON + newCCIPDONs map[registrysyncer.DonID]registrysyncer.DON + } + tests := []struct { + name string + args args + wantAdded map[registrysyncer.DonID]registrysyncer.DON + wantRemoved map[registrysyncer.DonID]registrysyncer.DON + wantUpdated map[registrysyncer.DonID]registrysyncer.DON + wantErr bool + }{ + { + "added dons", + args{ + currCCIPDONs: map[registrysyncer.DonID]registrysyncer.DON{}, + newCCIPDONs: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + }, + map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + map[registrysyncer.DonID]registrysyncer.DON{}, + map[registrysyncer.DonID]registrysyncer.DON{}, + false, + }, + { + "removed dons", + args{ + currCCIPDONs: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + newCCIPDONs: map[registrysyncer.DonID]registrysyncer.DON{}, + }, + map[registrysyncer.DonID]registrysyncer.DON{}, + map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + map[registrysyncer.DonID]registrysyncer.DON{}, + false, + }, + { + "updated dons", + args{ + currCCIPDONs: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + newCCIPDONs: map[registrysyncer.DonID]registrysyncer.DON{ + 1: { + DON: getDON(defaultRegistryDon.ID, defaultRegistryDon.Members, defaultRegistryDon.ConfigVersion+1), + CapabilityConfigurations: defaultCapCfgs, + }, + }, + }, + map[registrysyncer.DonID]registrysyncer.DON{}, + map[registrysyncer.DonID]registrysyncer.DON{}, + map[registrysyncer.DonID]registrysyncer.DON{ + 1: { + DON: getDON(defaultRegistryDon.ID, defaultRegistryDon.Members, defaultRegistryDon.ConfigVersion+1), + CapabilityConfigurations: defaultCapCfgs, + }, + }, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dr, err := compareDONs(tt.args.currCCIPDONs, tt.args.newCCIPDONs) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.wantAdded, dr.added) + require.Equal(t, tt.wantRemoved, dr.removed) + require.Equal(t, tt.wantUpdated, dr.updated) + } + }) + } +} + +func Test_filterCCIPDONs(t *testing.T) { + type args struct { + ccipCapability registrysyncer.Capability + state registrysyncer.LocalRegistry + } + tests := []struct { + name string + args args + want map[registrysyncer.DonID]registrysyncer.DON + wantErr bool + }{ + { + "one ccip don", + args{ + ccipCapability: defaultCapability, + state: registrysyncer.LocalRegistry{ + IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + }, + }, + map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + false, + }, + { + "no ccip dons - different capability", + args{ + ccipCapability: newCapability, + state: registrysyncer.LocalRegistry{ + IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + }, + }, + map[registrysyncer.DonID]registrysyncer.DON{}, + false, + }, + { + "don with multiple capabilities, one of them ccip", + args{ + ccipCapability: defaultCapability, + state: registrysyncer.LocalRegistry{ + IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{ + 1: { + DON: getDON(1, []ragep2ptypes.PeerID{p2pID1}, 0), + CapabilityConfigurations: map[string]registrysyncer.CapabilityConfiguration{ + defaultCapability.ID: {}, + newCapability.ID: {}, + }, + }, + }, + }, + }, + map[registrysyncer.DonID]registrysyncer.DON{ + 1: { + DON: getDON(1, []ragep2ptypes.PeerID{p2pID1}, 0), + CapabilityConfigurations: map[string]registrysyncer.CapabilityConfiguration{ + defaultCapability.ID: {}, + newCapability.ID: {}, + }, + }, + }, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := filterCCIPDONs(tt.args.ccipCapability, tt.args.state) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.want, got) + } + }) + } +} + +func Test_checkCapabilityPresence(t *testing.T) { + type args struct { + capabilityID string + state registrysyncer.LocalRegistry + } + tests := []struct { + name string + args args + want registrysyncer.Capability + wantErr bool + }{ + { + "in registry state", + args{ + capabilityID: defaultCapability.ID, + state: registrysyncer.LocalRegistry{ + IDsToCapabilities: map[string]registrysyncer.Capability{ + defaultCapability.ID: defaultCapability, + }, + }, + }, + defaultCapability, + false, + }, + { + "not in registry state", + args{ + capabilityID: defaultCapability.ID, + state: registrysyncer.LocalRegistry{ + IDsToCapabilities: map[string]registrysyncer.Capability{ + newCapability.ID: newCapability, + }, + }, + }, + registrysyncer.Capability{}, + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := checkCapabilityPresence(tt.args.capabilityID, tt.args.state) + if (err != nil) != tt.wantErr { + t.Errorf("checkCapabilityPresence() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("checkCapabilityPresence() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_isMemberOfDON(t *testing.T) { + var p2pIDs []ragep2ptypes.PeerID + for i := range [4]struct{}{} { + p2pIDs = append(p2pIDs, ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(int64(i+1))).PeerID())) + } + don := registrysyncer.DON{ + DON: getDON(1, p2pIDs, 0), + } + require.True(t, isMemberOfDON(don, ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(1)).PeerID()))) + require.False(t, isMemberOfDON(don, ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(5)).PeerID()))) +} + +func Test_isMemberOfBootstrapSubcommittee(t *testing.T) { + var bootstrapKeys [][32]byte + for i := range [4]struct{}{} { + bootstrapKeys = append(bootstrapKeys, p2pkey.MustNewV2XXXTestingOnly(big.NewInt(int64(i+1))).PeerID()) + } + require.True(t, isMemberOfBootstrapSubcommittee(bootstrapKeys, p2pID1)) + require.False(t, isMemberOfBootstrapSubcommittee(bootstrapKeys, getP2PID(5))) +} diff --git a/core/capabilities/ccip/launcher/integration_test.go b/core/capabilities/ccip/launcher/integration_test.go new file mode 100644 index 0000000000..db3daf4d9b --- /dev/null +++ b/core/capabilities/ccip/launcher/integration_test.go @@ -0,0 +1,120 @@ +package launcher + +import ( + "testing" + "time" + + it "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccip_integration_tests/integrationhelpers" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" + + "github.com/onsi/gomega" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" +) + +func TestIntegration_Launcher(t *testing.T) { + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + uni := it.NewTestUniverse(ctx, t, lggr) + // We need 3*f + 1 p2pIDs to have enough nodes to bootstrap + var arr []int64 + n := int(it.FChainA*3 + 1) + for i := 0; i <= n; i++ { + arr = append(arr, int64(i)) + } + p2pIDs := it.P2pIDsFromInts(arr) + uni.AddCapability(p2pIDs) + + regSyncer, err := registrysyncer.New(lggr, + func() (p2ptypes.PeerID, error) { + return p2pIDs[0], nil + }, + uni, + uni.CapReg.Address().String(), + ) + require.NoError(t, err) + + hcr := uni.HomeChainReader + + launcher := New( + it.CapabilityID, + p2pIDs[0], + logger.TestLogger(t), + hcr, + &oracleCreatorPrints{ + t: t, + }, + 1*time.Second, + ) + regSyncer.AddLauncher(launcher) + + require.NoError(t, launcher.Start(ctx)) + require.NoError(t, regSyncer.Start(ctx)) + t.Cleanup(func() { require.NoError(t, regSyncer.Close()) }) + t.Cleanup(func() { require.NoError(t, launcher.Close()) }) + + chainAConf := it.SetupConfigInfo(it.ChainA, p2pIDs, it.FChainA, []byte("ChainA")) + chainBConf := it.SetupConfigInfo(it.ChainB, p2pIDs[1:], it.FChainB, []byte("ChainB")) + chainCConf := it.SetupConfigInfo(it.ChainC, p2pIDs[2:], it.FChainC, []byte("ChainC")) + inputConfig := []ccip_config.CCIPConfigTypesChainConfigInfo{ + chainAConf, + chainBConf, + chainCConf, + } + _, err = uni.CcipCfg.ApplyChainConfigUpdates(uni.Transactor, nil, inputConfig) + require.NoError(t, err) + uni.Backend.Commit() + + ccipCapabilityID, err := uni.CapReg.GetHashedCapabilityId(nil, it.CcipCapabilityLabelledName, it.CcipCapabilityVersion) + require.NoError(t, err) + + uni.AddDONToRegistry( + ccipCapabilityID, + it.ChainA, + it.FChainA, + p2pIDs[1], + p2pIDs) + + gomega.NewWithT(t).Eventually(func() bool { + return len(launcher.runningDONIDs()) == 1 + }, testutils.WaitTimeout(t), testutils.TestInterval).Should(gomega.BeTrue()) +} + +type oraclePrints struct { + t *testing.T + pluginType cctypes.PluginType + config cctypes.OCR3ConfigWithMeta + isBootstrap bool +} + +func (o *oraclePrints) Start() error { + o.t.Logf("Starting oracle (pluginType: %s, isBootstrap: %t) with config %+v\n", o.pluginType, o.isBootstrap, o.config) + return nil +} + +func (o *oraclePrints) Close() error { + o.t.Logf("Closing oracle (pluginType: %s, isBootstrap: %t) with config %+v\n", o.pluginType, o.isBootstrap, o.config) + return nil +} + +type oracleCreatorPrints struct { + t *testing.T +} + +func (o *oracleCreatorPrints) CreatePluginOracle(pluginType cctypes.PluginType, config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { + o.t.Logf("Creating plugin oracle (pluginType: %s) with config %+v\n", pluginType, config) + return &oraclePrints{pluginType: pluginType, config: config, t: o.t}, nil +} + +func (o *oracleCreatorPrints) CreateBootstrapOracle(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { + o.t.Logf("Creating bootstrap oracle with config %+v\n", config) + return &oraclePrints{pluginType: cctypes.PluginTypeCCIPCommit, config: config, isBootstrap: true, t: o.t}, nil +} + +var _ cctypes.OracleCreator = &oracleCreatorPrints{} +var _ cctypes.CCIPOracle = &oraclePrints{} diff --git a/core/capabilities/ccip/launcher/launcher.go b/core/capabilities/ccip/launcher/launcher.go new file mode 100644 index 0000000000..2dc1a1954f --- /dev/null +++ b/core/capabilities/ccip/launcher/launcher.go @@ -0,0 +1,432 @@ +package launcher + +import ( + "context" + "fmt" + "sync" + "time" + + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" + "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" + + "go.uber.org/multierr" + + ragep2ptypes "github.com/smartcontractkit/libocr/ragep2p/types" + + ccipreader "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" +) + +var ( + _ job.ServiceCtx = (*launcher)(nil) + _ registrysyncer.Launcher = (*launcher)(nil) +) + +func New( + capabilityID string, + p2pID ragep2ptypes.PeerID, + lggr logger.Logger, + homeChainReader ccipreader.HomeChain, + oracleCreator cctypes.OracleCreator, + tickInterval time.Duration, +) *launcher { + return &launcher{ + p2pID: p2pID, + capabilityID: capabilityID, + lggr: lggr, + homeChainReader: homeChainReader, + regState: registrysyncer.LocalRegistry{ + IDsToDONs: make(map[registrysyncer.DonID]registrysyncer.DON), + IDsToNodes: make(map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo), + IDsToCapabilities: make(map[string]registrysyncer.Capability), + }, + oracleCreator: oracleCreator, + dons: make(map[registrysyncer.DonID]*ccipDeployment), + tickInterval: tickInterval, + } +} + +// launcher manages the lifecycles of the CCIP capability on all chains. +type launcher struct { + services.StateMachine + + capabilityID string + p2pID ragep2ptypes.PeerID + lggr logger.Logger + homeChainReader ccipreader.HomeChain + stopChan chan struct{} + // latestState is the latest capability registry state received from the syncer. + latestState registrysyncer.LocalRegistry + // regState is the latest capability registry state that we have successfully processed. + regState registrysyncer.LocalRegistry + oracleCreator cctypes.OracleCreator + lock sync.RWMutex + wg sync.WaitGroup + tickInterval time.Duration + + // dons is a map of CCIP DON IDs to the OCR instances that are running on them. + // we can have up to two OCR instances per CCIP plugin, since we are running two plugins, + // thats four OCR instances per CCIP DON maximum. + dons map[registrysyncer.DonID]*ccipDeployment +} + +// Launch implements registrysyncer.Launcher. +func (l *launcher) Launch(ctx context.Context, state *registrysyncer.LocalRegistry) error { + l.lock.Lock() + defer l.lock.Unlock() + l.lggr.Debugw("Received new state from syncer", "dons", state.IDsToDONs) + l.latestState = *state + return nil +} + +func (l *launcher) getLatestState() registrysyncer.LocalRegistry { + l.lock.RLock() + defer l.lock.RUnlock() + return l.latestState +} + +func (l *launcher) runningDONIDs() []registrysyncer.DonID { + l.lock.RLock() + defer l.lock.RUnlock() + var runningDONs []registrysyncer.DonID + for id := range l.dons { + runningDONs = append(runningDONs, id) + } + return runningDONs +} + +// Close implements job.ServiceCtx. +func (l *launcher) Close() error { + return l.StateMachine.StopOnce("launcher", func() error { + // shut down the monitor goroutine. + close(l.stopChan) + l.wg.Wait() + + // shut down all running oracles. + var err error + for _, ceDep := range l.dons { + err = multierr.Append(err, ceDep.Close()) + } + + return err + }) +} + +// Start implements job.ServiceCtx. +func (l *launcher) Start(context.Context) error { + return l.StartOnce("launcher", func() error { + l.stopChan = make(chan struct{}) + l.wg.Add(1) + go l.monitor() + return nil + }) +} + +func (l *launcher) monitor() { + defer l.wg.Done() + ticker := time.NewTicker(l.tickInterval) + for { + select { + case <-l.stopChan: + return + case <-ticker.C: + if err := l.tick(); err != nil { + l.lggr.Errorw("Failed to tick", "err", err) + } + } + } +} + +func (l *launcher) tick() error { + // Ensure that the home chain reader is healthy. + // For new jobs it may be possible that the home chain reader is not yet ready + // so we won't be able to fetch configs and start any OCR instances. + if ready := l.homeChainReader.Ready(); ready != nil { + return fmt.Errorf("home chain reader is not ready: %w", ready) + } + + // Fetch the latest state from the capability registry and determine if we need to + // launch or update any OCR instances. + latestState := l.getLatestState() + + diffRes, err := diff(l.capabilityID, l.regState, latestState) + if err != nil { + return fmt.Errorf("failed to diff capability registry states: %w", err) + } + + err = l.processDiff(diffRes) + if err != nil { + return fmt.Errorf("failed to process diff: %w", err) + } + + return nil +} + +// processDiff processes the diff between the current and latest capability registry states. +// for any added OCR instances, it will launch them. +// for any removed OCR instances, it will shut them down. +// for any updated OCR instances, it will restart them with the new configuration. +func (l *launcher) processDiff(diff diffResult) error { + err := l.processRemoved(diff.removed) + err = multierr.Append(err, l.processAdded(diff.added)) + err = multierr.Append(err, l.processUpdate(diff.updated)) + + return err +} + +func (l *launcher) processUpdate(updated map[registrysyncer.DonID]registrysyncer.DON) error { + l.lock.Lock() + defer l.lock.Unlock() + + for donID, don := range updated { + prevDeployment, ok := l.dons[registrysyncer.DonID(don.ID)] + if !ok { + return fmt.Errorf("invariant violation: expected to find CCIP DON %d in the map of running deployments", don.ID) + } + + futDeployment, err := updateDON( + l.lggr, + l.p2pID, + l.homeChainReader, + l.oracleCreator, + *prevDeployment, + don, + ) + if err != nil { + return err + } + if err := futDeployment.HandleBlueGreen(prevDeployment); err != nil { + // TODO: how to handle a failed blue-green deployment? + return fmt.Errorf("failed to handle blue-green deployment for CCIP DON %d: %w", donID, err) + } + + // update state. + l.dons[donID] = futDeployment + // update the state with the latest config. + // this way if one of the starts errors, we don't retry all of them. + l.regState.IDsToDONs[donID] = updated[donID] + } + + return nil +} + +func (l *launcher) processAdded(added map[registrysyncer.DonID]registrysyncer.DON) error { + l.lock.Lock() + defer l.lock.Unlock() + + for donID, don := range added { + dep, err := createDON( + l.lggr, + l.p2pID, + l.homeChainReader, + l.oracleCreator, + don, + ) + if err != nil { + return err + } + if dep == nil { + // not a member of this DON. + continue + } + + if err := dep.StartBlue(); err != nil { + if shutdownErr := dep.CloseBlue(); shutdownErr != nil { + l.lggr.Errorw("Failed to shutdown blue instance after failed start", "donId", donID, "err", shutdownErr) + } + return fmt.Errorf("failed to start oracles for CCIP DON %d: %w", donID, err) + } + + // update state. + l.dons[donID] = dep + // update the state with the latest config. + // this way if one of the starts errors, we don't retry all of them. + l.regState.IDsToDONs[donID] = added[donID] + } + + return nil +} + +func (l *launcher) processRemoved(removed map[registrysyncer.DonID]registrysyncer.DON) error { + l.lock.Lock() + defer l.lock.Unlock() + + for id := range removed { + ceDep, ok := l.dons[id] + if !ok { + // not running this particular DON. + continue + } + + if err := ceDep.Close(); err != nil { + return fmt.Errorf("failed to shutdown oracles for CCIP DON %d: %w", id, err) + } + + // after a successful shutdown we can safely remove the DON deployment from the map. + delete(l.dons, id) + delete(l.regState.IDsToDONs, id) + } + + return nil +} + +// updateDON is a pure function that handles the case where a DON in the capability registry +// has received a new configuration. +// It returns a new ccipDeployment that can then be used to perform the blue-green deployment, +// based on the previous deployment. +func updateDON( + lggr logger.Logger, + p2pID ragep2ptypes.PeerID, + homeChainReader ccipreader.HomeChain, + oracleCreator cctypes.OracleCreator, + prevDeployment ccipDeployment, + don registrysyncer.DON, +) (futDeployment *ccipDeployment, err error) { + if !isMemberOfDON(don, p2pID) { + lggr.Infow("Not a member of this DON, skipping", "donId", don.ID, "p2pId", p2pID.String()) + return nil, nil + } + + // this should be a retryable error. + commitOCRConfigs, err := homeChainReader.GetOCRConfigs(context.Background(), don.ID, uint8(cctypes.PluginTypeCCIPCommit)) + if err != nil { + return nil, fmt.Errorf("failed to fetch OCR configs for CCIP commit plugin (don id: %d) from home chain config contract: %w", + don.ID, err) + } + + execOCRConfigs, err := homeChainReader.GetOCRConfigs(context.Background(), don.ID, uint8(cctypes.PluginTypeCCIPExec)) + if err != nil { + return nil, fmt.Errorf("failed to fetch OCR configs for CCIP exec plugin (don id: %d) from home chain config contract: %w", + don.ID, err) + } + + commitBgd, err := createFutureBlueGreenDeployment(prevDeployment, commitOCRConfigs, oracleCreator, cctypes.PluginTypeCCIPCommit) + if err != nil { + return nil, fmt.Errorf("failed to create future blue-green deployment for CCIP commit plugin: %w, don id: %d", err, don.ID) + } + + execBgd, err := createFutureBlueGreenDeployment(prevDeployment, execOCRConfigs, oracleCreator, cctypes.PluginTypeCCIPExec) + if err != nil { + return nil, fmt.Errorf("failed to create future blue-green deployment for CCIP exec plugin: %w, don id: %d", err, don.ID) + } + + return &ccipDeployment{ + commit: commitBgd, + exec: execBgd, + }, nil +} + +// valid cases: +// a) len(ocrConfigs) == 2 && !prevDeployment.HasGreenInstance(pluginType): this is a new green instance. +// b) len(ocrConfigs) == 1 && prevDeployment.HasGreenInstance(): this is a promotion of green->blue. +// All other cases are invalid. This is enforced in the ccip config contract. +func createFutureBlueGreenDeployment( + prevDeployment ccipDeployment, + ocrConfigs []ccipreader.OCR3ConfigWithMeta, + oracleCreator cctypes.OracleCreator, + pluginType cctypes.PluginType, +) (blueGreenDeployment, error) { + var deployment blueGreenDeployment + if isNewGreenInstance(pluginType, ocrConfigs, prevDeployment) { + // this is a new green instance. + greenOracle, err := oracleCreator.CreatePluginOracle(pluginType, cctypes.OCR3ConfigWithMeta(ocrConfigs[1])) + if err != nil { + return blueGreenDeployment{}, fmt.Errorf("failed to create CCIP commit oracle: %w", err) + } + + deployment.blue = prevDeployment.commit.blue + deployment.green = greenOracle + } else if isPromotion(pluginType, ocrConfigs, prevDeployment) { + // this is a promotion of green->blue. + deployment.blue = prevDeployment.commit.green + } else { + return blueGreenDeployment{}, fmt.Errorf("invariant violation: expected 1 or 2 OCR configs for CCIP plugin (type: %d), got %d", pluginType, len(ocrConfigs)) + } + + return deployment, nil +} + +// createDON is a pure function that handles the case where a new DON is added to the capability registry. +// It returns a new ccipDeployment that can then be used to start the blue instance. +func createDON( + lggr logger.Logger, + p2pID ragep2ptypes.PeerID, + homeChainReader ccipreader.HomeChain, + oracleCreator cctypes.OracleCreator, + don registrysyncer.DON, +) (*ccipDeployment, error) { + if !isMemberOfDON(don, p2pID) { + lggr.Infow("Not a member of this DON, skipping", "donId", don.ID, "p2pId", p2pID.String()) + return nil, nil + } + + // this should be a retryable error. + commitOCRConfigs, err := homeChainReader.GetOCRConfigs(context.Background(), don.ID, uint8(cctypes.PluginTypeCCIPCommit)) + if err != nil { + return nil, fmt.Errorf("failed to fetch OCR configs for CCIP commit plugin (don id: %d) from home chain config contract: %w", + don.ID, err) + } + + execOCRConfigs, err := homeChainReader.GetOCRConfigs(context.Background(), don.ID, uint8(cctypes.PluginTypeCCIPExec)) + if err != nil { + return nil, fmt.Errorf("failed to fetch OCR configs for CCIP exec plugin (don id: %d) from home chain config contract: %w", + don.ID, err) + } + + // upon creation we should only have one OCR config per plugin type. + if len(commitOCRConfigs) != 1 { + return nil, fmt.Errorf("expected exactly one OCR config for CCIP commit plugin (don id: %d), got %d", don.ID, len(commitOCRConfigs)) + } + + if len(execOCRConfigs) != 1 { + return nil, fmt.Errorf("expected exactly one OCR config for CCIP exec plugin (don id: %d), got %d", don.ID, len(execOCRConfigs)) + } + + commitOracle, commitBootstrap, err := createOracle(p2pID, oracleCreator, cctypes.PluginTypeCCIPCommit, commitOCRConfigs) + if err != nil { + return nil, fmt.Errorf("failed to create CCIP commit oracle: %w", err) + } + + execOracle, execBootstrap, err := createOracle(p2pID, oracleCreator, cctypes.PluginTypeCCIPExec, execOCRConfigs) + if err != nil { + return nil, fmt.Errorf("failed to create CCIP exec oracle: %w", err) + } + + return &ccipDeployment{ + commit: blueGreenDeployment{ + blue: commitOracle, + bootstrapBlue: commitBootstrap, + }, + exec: blueGreenDeployment{ + blue: execOracle, + bootstrapBlue: execBootstrap, + }, + }, nil +} + +func createOracle( + p2pID ragep2ptypes.PeerID, + oracleCreator cctypes.OracleCreator, + pluginType cctypes.PluginType, + ocrConfigs []ccipreader.OCR3ConfigWithMeta, +) (pluginOracle, bootstrapOracle cctypes.CCIPOracle, err error) { + pluginOracle, err = oracleCreator.CreatePluginOracle(pluginType, cctypes.OCR3ConfigWithMeta(ocrConfigs[0])) + if err != nil { + return nil, nil, fmt.Errorf("failed to create CCIP plugin oracle (plugintype: %d): %w", pluginType, err) + } + + if isMemberOfBootstrapSubcommittee(ocrConfigs[0].Config.BootstrapP2PIds, p2pID) { + bootstrapOracle, err = oracleCreator.CreateBootstrapOracle(cctypes.OCR3ConfigWithMeta(ocrConfigs[0])) + if err != nil { + return nil, nil, fmt.Errorf("failed to create CCIP bootstrap oracle (plugintype: %d): %w", pluginType, err) + } + } + + return pluginOracle, bootstrapOracle, nil +} diff --git a/core/capabilities/ccip/launcher/launcher_test.go b/core/capabilities/ccip/launcher/launcher_test.go new file mode 100644 index 0000000000..242dd0be24 --- /dev/null +++ b/core/capabilities/ccip/launcher/launcher_test.go @@ -0,0 +1,472 @@ +package launcher + +import ( + "errors" + "math/big" + "reflect" + "testing" + + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types/mocks" + + ragep2ptypes "github.com/smartcontractkit/libocr/ragep2p/types" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" +) + +func Test_createOracle(t *testing.T) { + var p2pKeys []ragep2ptypes.PeerID + for i := 0; i < 3; i++ { + p2pKeys = append(p2pKeys, ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(int64(i+1))).PeerID())) + } + myP2PKey := p2pKeys[0] + type args struct { + p2pID ragep2ptypes.PeerID + oracleCreator *mocks.OracleCreator + pluginType cctypes.PluginType + ocrConfigs []ccipreaderpkg.OCR3ConfigWithMeta + } + tests := []struct { + name string + args args + expect func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) + wantErr bool + }{ + { + "success, no bootstrap", + args{ + myP2PKey, + mocks.NewOracleCreator(t), + cctypes.PluginTypeCCIPCommit, + []ccipreaderpkg.OCR3ConfigWithMeta{ + { + Config: ccipreaderpkg.OCR3Config{}, + ConfigCount: 1, + ConfigDigest: testutils.Random32Byte(), + }, + }, + }, + func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) { + oracleCreator. + On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). + Return(mocks.NewCCIPOracle(t), nil) + }, + false, + }, + { + "success, with bootstrap", + args{ + myP2PKey, + mocks.NewOracleCreator(t), + cctypes.PluginTypeCCIPCommit, + []ccipreaderpkg.OCR3ConfigWithMeta{ + { + Config: ccipreaderpkg.OCR3Config{ + BootstrapP2PIds: [][32]byte{myP2PKey}, + }, + ConfigCount: 1, + ConfigDigest: testutils.Random32Byte(), + }, + }, + }, + func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) { + oracleCreator. + On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). + Return(mocks.NewCCIPOracle(t), nil) + oracleCreator. + On("CreateBootstrapOracle", cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). + Return(mocks.NewCCIPOracle(t), nil) + }, + false, + }, + { + "error creating plugin oracle", + args{ + myP2PKey, + mocks.NewOracleCreator(t), + cctypes.PluginTypeCCIPCommit, + []ccipreaderpkg.OCR3ConfigWithMeta{ + { + Config: ccipreaderpkg.OCR3Config{}, + ConfigCount: 1, + ConfigDigest: testutils.Random32Byte(), + }, + }, + }, + func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) { + oracleCreator. + On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). + Return(nil, errors.New("error creating oracle")) + }, + true, + }, + { + "error creating bootstrap oracle", + args{ + myP2PKey, + mocks.NewOracleCreator(t), + cctypes.PluginTypeCCIPCommit, + []ccipreaderpkg.OCR3ConfigWithMeta{ + { + Config: ccipreaderpkg.OCR3Config{ + BootstrapP2PIds: [][32]byte{myP2PKey}, + }, + ConfigCount: 1, + ConfigDigest: testutils.Random32Byte(), + }, + }, + }, + func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) { + oracleCreator. + On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). + Return(mocks.NewCCIPOracle(t), nil) + oracleCreator. + On("CreateBootstrapOracle", cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). + Return(nil, errors.New("error creating oracle")) + }, + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.expect(t, tt.args, tt.args.oracleCreator) + _, _, err := createOracle(tt.args.p2pID, tt.args.oracleCreator, tt.args.pluginType, tt.args.ocrConfigs) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func Test_createDON(t *testing.T) { + type args struct { + lggr logger.Logger + p2pID ragep2ptypes.PeerID + homeChainReader *mocks.HomeChainReader + oracleCreator *mocks.OracleCreator + don registrysyncer.DON + } + tests := []struct { + name string + args args + expect func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) + wantErr bool + }{ + { + "not a member of the DON", + args{ + logger.TestLogger(t), + p2pID1, + mocks.NewHomeChainReader(t), + mocks.NewOracleCreator(t), + registrysyncer.DON{ + DON: getDON(2, []ragep2ptypes.PeerID{p2pID2}, 0), + CapabilityConfigurations: defaultCapCfgs, + }, + }, + func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) { + }, + false, + }, + { + "success, no bootstrap", + args{ + logger.TestLogger(t), + p2pID1, + mocks.NewHomeChainReader(t), + mocks.NewOracleCreator(t), + defaultRegistryDon, + }, + func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) { + homeChainReader. + On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPCommit)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}}, nil) + homeChainReader. + On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPExec)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}}, nil) + oracleCreator. + On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, mock.Anything). + Return(mocks.NewCCIPOracle(t), nil) + oracleCreator. + On("CreatePluginOracle", cctypes.PluginTypeCCIPExec, mock.Anything). + Return(mocks.NewCCIPOracle(t), nil) + }, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.expect != nil { + tt.expect(t, tt.args, tt.args.oracleCreator, tt.args.homeChainReader) + } + _, err := createDON(tt.args.lggr, tt.args.p2pID, tt.args.homeChainReader, tt.args.oracleCreator, tt.args.don) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func Test_createFutureBlueGreenDeployment(t *testing.T) { + type args struct { + prevDeployment ccipDeployment + ocrConfigs []ccipreaderpkg.OCR3ConfigWithMeta + oracleCreator *mocks.OracleCreator + pluginType cctypes.PluginType + } + tests := []struct { + name string + args args + want blueGreenDeployment + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := createFutureBlueGreenDeployment(tt.args.prevDeployment, tt.args.ocrConfigs, tt.args.oracleCreator, tt.args.pluginType) + if (err != nil) != tt.wantErr { + t.Errorf("createFutureBlueGreenDeployment() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("createFutureBlueGreenDeployment() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_updateDON(t *testing.T) { + type args struct { + lggr logger.Logger + p2pID ragep2ptypes.PeerID + homeChainReader *mocks.HomeChainReader + oracleCreator *mocks.OracleCreator + prevDeployment ccipDeployment + don registrysyncer.DON + } + tests := []struct { + name string + args args + wantFutDeployment *ccipDeployment + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotFutDeployment, err := updateDON(tt.args.lggr, tt.args.p2pID, tt.args.homeChainReader, tt.args.oracleCreator, tt.args.prevDeployment, tt.args.don) + if (err != nil) != tt.wantErr { + t.Errorf("updateDON() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(gotFutDeployment, tt.wantFutDeployment) { + t.Errorf("updateDON() = %v, want %v", gotFutDeployment, tt.wantFutDeployment) + } + }) + } +} + +func Test_launcher_processDiff(t *testing.T) { + type fields struct { + lggr logger.Logger + p2pID ragep2ptypes.PeerID + homeChainReader *mocks.HomeChainReader + oracleCreator *mocks.OracleCreator + dons map[registrysyncer.DonID]*ccipDeployment + regState registrysyncer.LocalRegistry + } + type args struct { + diff diffResult + } + tests := []struct { + name string + fields fields + args args + assert func(t *testing.T, l *launcher) + wantErr bool + }{ + { + "don removed success", + fields{ + dons: map[registrysyncer.DonID]*ccipDeployment{ + 1: { + commit: blueGreenDeployment{ + blue: newMock(t, + func(t *testing.T) *mocks.CCIPOracle { return mocks.NewCCIPOracle(t) }, + func(m *mocks.CCIPOracle) { + m.On("Close").Return(nil) + }), + }, + exec: blueGreenDeployment{ + blue: newMock(t, + func(t *testing.T) *mocks.CCIPOracle { return mocks.NewCCIPOracle(t) }, + func(m *mocks.CCIPOracle) { + m.On("Close").Return(nil) + }), + }, + }, + }, + regState: registrysyncer.LocalRegistry{ + IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + }, + }, + args{ + diff: diffResult{ + removed: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + }, + }, + func(t *testing.T, l *launcher) { + require.Len(t, l.dons, 0) + require.Len(t, l.regState.IDsToDONs, 0) + }, + false, + }, + { + "don added success", + fields{ + lggr: logger.TestLogger(t), + p2pID: p2pID1, + homeChainReader: newMock(t, func(t *testing.T) *mocks.HomeChainReader { + return mocks.NewHomeChainReader(t) + }, func(m *mocks.HomeChainReader) { + m.On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPCommit)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}}, nil) + m.On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPExec)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}}, nil) + }), + oracleCreator: newMock(t, func(t *testing.T) *mocks.OracleCreator { + return mocks.NewOracleCreator(t) + }, func(m *mocks.OracleCreator) { + commitOracle := mocks.NewCCIPOracle(t) + commitOracle.On("Start").Return(nil) + execOracle := mocks.NewCCIPOracle(t) + execOracle.On("Start").Return(nil) + m.On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, mock.Anything). + Return(commitOracle, nil) + m.On("CreatePluginOracle", cctypes.PluginTypeCCIPExec, mock.Anything). + Return(execOracle, nil) + }), + dons: map[registrysyncer.DonID]*ccipDeployment{}, + regState: registrysyncer.LocalRegistry{ + IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{}, + }, + }, + args{ + diff: diffResult{ + added: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + }, + }, + func(t *testing.T, l *launcher) { + require.Len(t, l.dons, 1) + require.Len(t, l.regState.IDsToDONs, 1) + }, + false, + }, + { + "don updated new green instance success", + fields{ + lggr: logger.TestLogger(t), + p2pID: p2pID1, + homeChainReader: newMock(t, func(t *testing.T) *mocks.HomeChainReader { + return mocks.NewHomeChainReader(t) + }, func(m *mocks.HomeChainReader) { + m.On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPCommit)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}, {}}, nil) + m.On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPExec)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}, {}}, nil) + }), + oracleCreator: newMock(t, func(t *testing.T) *mocks.OracleCreator { + return mocks.NewOracleCreator(t) + }, func(m *mocks.OracleCreator) { + commitOracle := mocks.NewCCIPOracle(t) + commitOracle.On("Start").Return(nil) + execOracle := mocks.NewCCIPOracle(t) + execOracle.On("Start").Return(nil) + m.On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, mock.Anything). + Return(commitOracle, nil) + m.On("CreatePluginOracle", cctypes.PluginTypeCCIPExec, mock.Anything). + Return(execOracle, nil) + }), + dons: map[registrysyncer.DonID]*ccipDeployment{ + 1: { + commit: blueGreenDeployment{ + blue: newMock(t, func(t *testing.T) *mocks.CCIPOracle { + return mocks.NewCCIPOracle(t) + }, func(m *mocks.CCIPOracle) {}), + }, + exec: blueGreenDeployment{ + blue: newMock(t, func(t *testing.T) *mocks.CCIPOracle { + return mocks.NewCCIPOracle(t) + }, func(m *mocks.CCIPOracle) {}), + }, + }, + }, + regState: registrysyncer.LocalRegistry{ + IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{ + 1: defaultRegistryDon, + }, + }, + }, + args{ + diff: diffResult{ + updated: map[registrysyncer.DonID]registrysyncer.DON{ + 1: { + // new Node in Don: p2pID2 + DON: getDON(1, []ragep2ptypes.PeerID{p2pID1, p2pID2}, 0), + CapabilityConfigurations: defaultCapCfgs, + }, + }, + }, + }, + func(t *testing.T, l *launcher) { + require.Len(t, l.dons, 1) + require.Len(t, l.regState.IDsToDONs, 1) + require.Len(t, l.regState.IDsToDONs[1].Members, 2) + }, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + l := &launcher{ + dons: tt.fields.dons, + regState: tt.fields.regState, + p2pID: tt.fields.p2pID, + lggr: tt.fields.lggr, + homeChainReader: tt.fields.homeChainReader, + oracleCreator: tt.fields.oracleCreator, + } + err := l.processDiff(tt.args.diff) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + tt.assert(t, l) + }) + } +} + +func newMock[T any](t *testing.T, newer func(t *testing.T) T, expect func(m T)) T { + o := newer(t) + expect(o) + return o +} diff --git a/core/capabilities/ccip/launcher/test_helpers.go b/core/capabilities/ccip/launcher/test_helpers.go new file mode 100644 index 0000000000..a2ebf3fdba --- /dev/null +++ b/core/capabilities/ccip/launcher/test_helpers.go @@ -0,0 +1,56 @@ +package launcher + +import ( + "fmt" + "math/big" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" + + ragep2ptypes "github.com/smartcontractkit/libocr/ragep2p/types" +) + +const ( + ccipCapVersion = "v1.0.0" + ccipCapNewVersion = "v1.1.0" + ccipCapName = "ccip" +) + +var ( + defaultCapability = getCapability(ccipCapName, ccipCapVersion) + newCapability = getCapability(ccipCapName, ccipCapNewVersion) + p2pID1 = getP2PID(1) + p2pID2 = getP2PID(2) + defaultCapCfgs = map[string]registrysyncer.CapabilityConfiguration{ + defaultCapability.ID: registrysyncer.CapabilityConfiguration{}, + } + defaultRegistryDon = registrysyncer.DON{ + DON: getDON(1, []ragep2ptypes.PeerID{p2pID1}, 0), + CapabilityConfigurations: defaultCapCfgs, + } +) + +func getP2PID(id uint32) ragep2ptypes.PeerID { + return ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(int64(id))).PeerID()) +} + +func getCapability(ccipCapName, ccipCapVersion string) registrysyncer.Capability { + id := fmt.Sprintf("%s@%s", ccipCapName, ccipCapVersion) + return registrysyncer.Capability{ + CapabilityType: capabilities.CapabilityTypeTarget, + ID: id, + } +} + +func getDON(id uint32, members []ragep2ptypes.PeerID, cfgVersion uint32) capabilities.DON { + return capabilities.DON{ + ID: id, + ConfigVersion: cfgVersion, + F: uint8(1), + IsPublic: true, + AcceptsWorkflows: true, + Members: members, + } +} diff --git a/core/capabilities/ccip/ocrimpls/config_digester.go b/core/capabilities/ccip/ocrimpls/config_digester.go new file mode 100644 index 0000000000..ef0c5e7ca3 --- /dev/null +++ b/core/capabilities/ccip/ocrimpls/config_digester.go @@ -0,0 +1,23 @@ +package ocrimpls + +import "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + +type configDigester struct { + d types.ConfigDigest +} + +func NewConfigDigester(d types.ConfigDigest) *configDigester { + return &configDigester{d: d} +} + +// ConfigDigest implements types.OffchainConfigDigester. +func (c *configDigester) ConfigDigest(types.ContractConfig) (types.ConfigDigest, error) { + return c.d, nil +} + +// ConfigDigestPrefix implements types.OffchainConfigDigester. +func (c *configDigester) ConfigDigestPrefix() (types.ConfigDigestPrefix, error) { + return types.ConfigDigestPrefixCCIPMultiRole, nil +} + +var _ types.OffchainConfigDigester = (*configDigester)(nil) diff --git a/core/capabilities/ccip/ocrimpls/config_tracker.go b/core/capabilities/ccip/ocrimpls/config_tracker.go new file mode 100644 index 0000000000..3a6a27fa40 --- /dev/null +++ b/core/capabilities/ccip/ocrimpls/config_tracker.go @@ -0,0 +1,77 @@ +package ocrimpls + +import ( + "context" + + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + + gethcommon "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" +) + +type configTracker struct { + cfg cctypes.OCR3ConfigWithMeta +} + +func NewConfigTracker(cfg cctypes.OCR3ConfigWithMeta) *configTracker { + return &configTracker{cfg: cfg} +} + +// LatestBlockHeight implements types.ContractConfigTracker. +func (c *configTracker) LatestBlockHeight(ctx context.Context) (blockHeight uint64, err error) { + return 0, nil +} + +// LatestConfig implements types.ContractConfigTracker. +func (c *configTracker) LatestConfig(ctx context.Context, changedInBlock uint64) (types.ContractConfig, error) { + return c.contractConfig(), nil +} + +// LatestConfigDetails implements types.ContractConfigTracker. +func (c *configTracker) LatestConfigDetails(ctx context.Context) (changedInBlock uint64, configDigest types.ConfigDigest, err error) { + return 0, c.cfg.ConfigDigest, nil +} + +// Notify implements types.ContractConfigTracker. +func (c *configTracker) Notify() <-chan struct{} { + return nil +} + +func (c *configTracker) contractConfig() types.ContractConfig { + return types.ContractConfig{ + ConfigDigest: c.cfg.ConfigDigest, + ConfigCount: c.cfg.ConfigCount, + Signers: toOnchainPublicKeys(c.cfg.Config.Signers), + Transmitters: toOCRAccounts(c.cfg.Config.Transmitters), + F: c.cfg.Config.F, + OnchainConfig: []byte{}, + OffchainConfigVersion: c.cfg.Config.OffchainConfigVersion, + OffchainConfig: c.cfg.Config.OffchainConfig, + } +} + +// PublicConfig returns the OCR configuration as a PublicConfig so that we can +// access ReportingPluginConfig and other fields prior to launching the plugins. +func (c *configTracker) PublicConfig() (ocr3confighelper.PublicConfig, error) { + return ocr3confighelper.PublicConfigFromContractConfig(false, c.contractConfig()) +} + +func toOnchainPublicKeys(signers [][]byte) []types.OnchainPublicKey { + keys := make([]types.OnchainPublicKey, len(signers)) + for i, signer := range signers { + keys[i] = types.OnchainPublicKey(signer) + } + return keys +} + +func toOCRAccounts(transmitters [][]byte) []types.Account { + accounts := make([]types.Account, len(transmitters)) + for i, transmitter := range transmitters { + // TODO: string-encode the transmitter appropriately to the dest chain family. + accounts[i] = types.Account(gethcommon.BytesToAddress(transmitter).Hex()) + } + return accounts +} + +var _ types.ContractConfigTracker = (*configTracker)(nil) diff --git a/core/capabilities/ccip/ocrimpls/contract_transmitter.go b/core/capabilities/ccip/ocrimpls/contract_transmitter.go new file mode 100644 index 0000000000..fd8e206d0e --- /dev/null +++ b/core/capabilities/ccip/ocrimpls/contract_transmitter.go @@ -0,0 +1,188 @@ +package ocrimpls + +import ( + "context" + "errors" + "fmt" + "math/big" + + "github.com/google/uuid" + "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-ccip/pkg/consts" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" +) + +type ToCalldataFunc func(rawReportCtx [3][32]byte, report []byte, rs, ss [][32]byte, vs [32]byte) any + +func ToCommitCalldata(rawReportCtx [3][32]byte, report []byte, rs, ss [][32]byte, vs [32]byte) any { + // Note that the name of the struct field is very important, since the encoder used + // by the chainwriter uses mapstructure, which will use the struct field name to map + // to the argument name in the function call. + // If, for whatever reason, we want to change the field name, make sure to add a `mapstructure:""` tag + // for that field. + return struct { + ReportContext [3][32]byte + Report []byte + Rs [][32]byte + Ss [][32]byte + RawVs [32]byte + }{ + ReportContext: rawReportCtx, + Report: report, + Rs: rs, + Ss: ss, + RawVs: vs, + } +} + +func ToExecCalldata(rawReportCtx [3][32]byte, report []byte, _, _ [][32]byte, _ [32]byte) any { + // Note that the name of the struct field is very important, since the encoder used + // by the chainwriter uses mapstructure, which will use the struct field name to map + // to the argument name in the function call. + // If, for whatever reason, we want to change the field name, make sure to add a `mapstructure:""` tag + // for that field. + return struct { + ReportContext [3][32]byte + Report []byte + }{ + ReportContext: rawReportCtx, + Report: report, + } +} + +var _ ocr3types.ContractTransmitter[[]byte] = &commitTransmitter[[]byte]{} + +type commitTransmitter[RI any] struct { + cw commontypes.ChainWriter + fromAccount ocrtypes.Account + contractName string + method string + offrampAddress string + toCalldataFn ToCalldataFunc +} + +func XXXNewContractTransmitterTestsOnly[RI any]( + cw commontypes.ChainWriter, + fromAccount ocrtypes.Account, + contractName string, + method string, + offrampAddress string, + toCalldataFn ToCalldataFunc, +) ocr3types.ContractTransmitter[RI] { + return &commitTransmitter[RI]{ + cw: cw, + fromAccount: fromAccount, + contractName: contractName, + method: method, + offrampAddress: offrampAddress, + toCalldataFn: toCalldataFn, + } +} + +func NewCommitContractTransmitter[RI any]( + cw commontypes.ChainWriter, + fromAccount ocrtypes.Account, + offrampAddress string, +) ocr3types.ContractTransmitter[RI] { + return &commitTransmitter[RI]{ + cw: cw, + fromAccount: fromAccount, + contractName: consts.ContractNameOffRamp, + method: consts.MethodCommit, + offrampAddress: offrampAddress, + toCalldataFn: ToCommitCalldata, + } +} + +func NewExecContractTransmitter[RI any]( + cw commontypes.ChainWriter, + fromAccount ocrtypes.Account, + offrampAddress string, +) ocr3types.ContractTransmitter[RI] { + return &commitTransmitter[RI]{ + cw: cw, + fromAccount: fromAccount, + contractName: consts.ContractNameOffRamp, + method: consts.MethodExecute, + offrampAddress: offrampAddress, + toCalldataFn: ToExecCalldata, + } +} + +// FromAccount implements ocr3types.ContractTransmitter. +func (c *commitTransmitter[RI]) FromAccount() (ocrtypes.Account, error) { + return c.fromAccount, nil +} + +// Transmit implements ocr3types.ContractTransmitter. +func (c *commitTransmitter[RI]) Transmit( + ctx context.Context, + configDigest ocrtypes.ConfigDigest, + seqNr uint64, + reportWithInfo ocr3types.ReportWithInfo[RI], + sigs []ocrtypes.AttributedOnchainSignature, +) error { + var rs [][32]byte + var ss [][32]byte + var vs [32]byte + if len(sigs) > 32 { + return errors.New("too many signatures, maximum is 32") + } + for i, as := range sigs { + r, s, v, err := evmutil.SplitSignature(as.Signature) + if err != nil { + return fmt.Errorf("failed to split signature: %w", err) + } + rs = append(rs, r) + ss = append(ss, s) + vs[i] = v + } + + // report ctx for OCR3 consists of the following + // reportContext[0]: ConfigDigest + // reportContext[1]: 24 byte padding, 8 byte sequence number + // reportContext[2]: unused + // convert seqNum, which is a uint64, into a uint32 epoch and uint8 round + // while this does truncate the sequence number, it is not a problem because + // it still gives us 2^40 - 1 possible sequence numbers. + // assuming a sequence number is generated every second, this gives us + // 1099511627775 seconds, or approximately 34,865 years, before we run out + // of sequence numbers. + epoch, round := uint64ToUint32AndUint8(seqNr) + rawReportCtx := evmutil.RawReportContext(ocrtypes.ReportContext{ + ReportTimestamp: ocrtypes.ReportTimestamp{ + ConfigDigest: configDigest, + Epoch: epoch, + Round: round, + }, + // ExtraData not used in OCR3 + }) + + if c.toCalldataFn == nil { + return errors.New("toCalldataFn is nil") + } + + // chain writer takes in the raw calldata and packs it on its own. + args := c.toCalldataFn(rawReportCtx, reportWithInfo.Report, rs, ss, vs) + + // TODO: no meta fields yet, what should we add? + // probably whats in the info part of the report? + meta := commontypes.TxMeta{} + txID, err := uuid.NewRandom() // NOTE: CW expects us to generate an ID, rather than return one + if err != nil { + return fmt.Errorf("failed to generate UUID: %w", err) + } + zero := big.NewInt(0) + if err := c.cw.SubmitTransaction(ctx, c.contractName, c.method, args, fmt.Sprintf("%s-%s-%s", c.contractName, c.offrampAddress, txID.String()), c.offrampAddress, &meta, zero); err != nil { + return fmt.Errorf("failed to submit transaction thru chainwriter: %w", err) + } + + return nil +} + +func uint64ToUint32AndUint8(x uint64) (uint32, uint8) { + return uint32(x >> 32), uint8(x) +} diff --git a/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go b/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go new file mode 100644 index 0000000000..871afbb669 --- /dev/null +++ b/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go @@ -0,0 +1,691 @@ +package ocrimpls_test + +import ( + "crypto/rand" + "math/big" + "net/url" + "testing" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ocrimpls" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/jmoiron/sqlx" + "github.com/onsi/gomega" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/keystore" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/multi_ocr3_helper" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + kschaintype "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" +) + +func Test_ContractTransmitter_TransmitWithoutSignatures(t *testing.T) { + type testCase struct { + name string + pluginType uint8 + withSigs bool + expectedSigsEnabled bool + report []byte + } + + testCases := []testCase{ + { + "empty report with sigs", + uint8(cctypes.PluginTypeCCIPCommit), + true, + true, + []byte{}, + }, + { + "empty report without sigs", + uint8(cctypes.PluginTypeCCIPExec), + false, + false, + []byte{}, + }, + { + "report with data with sigs", + uint8(cctypes.PluginTypeCCIPCommit), + true, + true, + randomReport(t, 96), + }, + { + "report with data without sigs", + uint8(cctypes.PluginTypeCCIPExec), + false, + false, + randomReport(t, 96), + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + tc := tc + t.Parallel() + testTransmitter(t, tc.pluginType, tc.withSigs, tc.expectedSigsEnabled, tc.report) + }) + } +} + +func testTransmitter( + t *testing.T, + pluginType uint8, + withSigs bool, + expectedSigsEnabled bool, + report []byte, +) { + uni := newTestUniverse[[]byte](t, nil) + + c, err := uni.wrapper.LatestConfigDetails(nil, pluginType) + require.NoError(t, err, "failed to get latest config details") + configDigest := c.ConfigInfo.ConfigDigest + require.Equal(t, expectedSigsEnabled, c.ConfigInfo.IsSignatureVerificationEnabled, "signature verification enabled setting not correct") + + // set the plugin type on the helper so it fetches the right config info. + // the important aspect is whether signatures should be enabled or not. + _, err = uni.wrapper.SetTransmitOcrPluginType(uni.deployer, pluginType) + require.NoError(t, err, "failed to set plugin type") + uni.backend.Commit() + + // create attributed sigs + // only need f+1 which is 2 in this case + rwi := ocr3types.ReportWithInfo[[]byte]{ + Report: report, + Info: []byte{}, + } + seqNr := uint64(1) + attributedSigs := uni.SignReport(t, configDigest, rwi, seqNr) + + account, err := uni.transmitterWithSigs.FromAccount() + require.NoError(t, err, "failed to get from account") + require.Equal(t, ocrtypes.Account(uni.transmitters[0].Hex()), account, "from account mismatch") + if withSigs { + err = uni.transmitterWithSigs.Transmit(testutils.Context(t), configDigest, seqNr, rwi, attributedSigs) + } else { + err = uni.transmitterWithoutSigs.Transmit(testutils.Context(t), configDigest, seqNr, rwi, attributedSigs) + } + require.NoError(t, err, "failed to transmit") + uni.backend.Commit() + + var txStatus uint64 + gomega.NewWithT(t).Eventually(func() bool { + uni.backend.Commit() + rows, err := uni.db.QueryContext(testutils.Context(t), `SELECT hash FROM evm.tx_attempts LIMIT 1`) + require.NoError(t, err, "failed to query txes") + defer rows.Close() + var txHash []byte + for rows.Next() { + require.NoError(t, rows.Scan(&txHash), "failed to scan") + } + t.Log("txHash:", txHash) + receipt, err := uni.simClient.TransactionReceipt(testutils.Context(t), common.BytesToHash(txHash)) + if err != nil { + t.Log("tx not found yet:", hexutil.Encode(txHash)) + return false + } + t.Log("tx found:", hexutil.Encode(txHash), "status:", receipt.Status) + txStatus = receipt.Status + return true + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue()) + + // wait for receipt to be written to the db + gomega.NewWithT(t).Eventually(func() bool { + rows, err := uni.db.QueryContext(testutils.Context(t), `SELECT count(*) as cnt FROM evm.receipts LIMIT 1`) + require.NoError(t, err, "failed to query receipts") + defer rows.Close() + var count int + for rows.Next() { + require.NoError(t, rows.Scan(&count), "failed to scan") + } + return count == 1 + }, testutils.WaitTimeout(t), 2*time.Second).Should(gomega.BeTrue()) + + require.Equal(t, uint64(1), txStatus, "tx status should be success") + + // check that the event was emitted + events := uni.TransmittedEvents(t) + require.Len(t, events, 1, "expected 1 event") + require.Equal(t, configDigest, events[0].ConfigDigest, "config digest mismatch") + require.Equal(t, seqNr, events[0].SequenceNumber, "seq num mismatch") +} + +type testUniverse[RI any] struct { + simClient *client.SimulatedBackendClient + backend *backends.SimulatedBackend + deployer *bind.TransactOpts + transmitters []common.Address + signers []common.Address + wrapper *multi_ocr3_helper.MultiOCR3Helper + transmitterWithSigs ocr3types.ContractTransmitter[RI] + transmitterWithoutSigs ocr3types.ContractTransmitter[RI] + keyrings []ocr3types.OnchainKeyring[RI] + f uint8 + db *sqlx.DB + txm txmgr.TxManager + gasEstimator gas.EvmFeeEstimator +} + +type keyringsAndSigners[RI any] struct { + keyrings []ocr3types.OnchainKeyring[RI] + signers []common.Address +} + +func newTestUniverse[RI any](t *testing.T, ks *keyringsAndSigners[RI]) *testUniverse[RI] { + t.Helper() + + db := pgtest.NewSqlxDB(t) + owner := testutils.MustNewSimTransactor(t) + + // create many transmitters but only need to fund one, rest are to get + // setOCR3Config to pass. + keyStore := cltest.NewKeyStore(t, db) + var transmitters []common.Address + for i := 0; i < 4; i++ { + key, err := keyStore.Eth().Create(testutils.Context(t), big.NewInt(1337)) + require.NoError(t, err, "failed to create key") + transmitters = append(transmitters, key.Address) + } + + backend := backends.NewSimulatedBackend(core.GenesisAlloc{ + owner.From: core.GenesisAccount{ + Balance: assets.Ether(1000).ToInt(), + }, + transmitters[0]: core.GenesisAccount{ + Balance: assets.Ether(1000).ToInt(), + }, + }, 30e6) + + ocr3HelperAddr, _, _, err := multi_ocr3_helper.DeployMultiOCR3Helper(owner, backend) + require.NoError(t, err) + backend.Commit() + wrapper, err := multi_ocr3_helper.NewMultiOCR3Helper(ocr3HelperAddr, backend) + require.NoError(t, err) + + // create the oracle identities for setConfig + // need to create at least 4 identities otherwise setConfig will fail + var ( + keyrings []ocr3types.OnchainKeyring[RI] + signers []common.Address + ) + if ks != nil { + keyrings = ks.keyrings + signers = ks.signers + } else { + for i := 0; i < 4; i++ { + kb, err2 := ocr2key.New(kschaintype.EVM) + require.NoError(t, err2, "failed to create key") + kr := ocrimpls.NewOnchainKeyring[RI](kb, logger.TestLogger(t)) + signers = append(signers, common.BytesToAddress(kr.PublicKey())) + keyrings = append(keyrings, kr) + } + } + f := uint8(1) + commitConfigDigest := testutils.Random32Byte() + execConfigDigest := testutils.Random32Byte() + _, err = wrapper.SetOCR3Configs( + owner, + []multi_ocr3_helper.MultiOCR3BaseOCRConfigArgs{ + { + ConfigDigest: commitConfigDigest, + OcrPluginType: uint8(cctypes.PluginTypeCCIPCommit), + F: f, + IsSignatureVerificationEnabled: true, + Signers: signers, + Transmitters: []common.Address{ + transmitters[0], + transmitters[1], + transmitters[2], + transmitters[3], + }, + }, + { + ConfigDigest: execConfigDigest, + OcrPluginType: uint8(cctypes.PluginTypeCCIPExec), + F: f, + IsSignatureVerificationEnabled: false, + Signers: signers, + Transmitters: []common.Address{ + transmitters[0], + transmitters[1], + transmitters[2], + transmitters[3], + }, + }, + }, + ) + require.NoError(t, err) + backend.Commit() + + commitConfig, err := wrapper.LatestConfigDetails(nil, uint8(cctypes.PluginTypeCCIPCommit)) + require.NoError(t, err, "failed to get latest commit config") + require.Equal(t, commitConfigDigest, commitConfig.ConfigInfo.ConfigDigest, "commit config digest mismatch") + execConfig, err := wrapper.LatestConfigDetails(nil, uint8(cctypes.PluginTypeCCIPExec)) + require.NoError(t, err, "failed to get latest exec config") + require.Equal(t, execConfigDigest, execConfig.ConfigInfo.ConfigDigest, "exec config digest mismatch") + + simClient := client.NewSimulatedBackendClient(t, backend, testutils.SimulatedChainID) + + // create the chain writer service + txm, gasEstimator := makeTestEvmTxm(t, db, simClient, keyStore.Eth()) + require.NoError(t, txm.Start(testutils.Context(t)), "failed to start tx manager") + t.Cleanup(func() { require.NoError(t, txm.Close()) }) + + chainWriter, err := evm.NewChainWriterService( + logger.TestLogger(t), + simClient, + txm, + gasEstimator, + chainWriterConfigRaw(transmitters[0], assets.GWei(1))) + require.NoError(t, err, "failed to create chain writer") + require.NoError(t, chainWriter.Start(testutils.Context(t)), "failed to start chain writer") + t.Cleanup(func() { require.NoError(t, chainWriter.Close()) }) + + transmitterWithSigs := ocrimpls.XXXNewContractTransmitterTestsOnly[RI]( + chainWriter, + ocrtypes.Account(transmitters[0].Hex()), + contractName, + methodTransmitWithSignatures, + ocr3HelperAddr.Hex(), + ocrimpls.ToCommitCalldata, + ) + transmitterWithoutSigs := ocrimpls.XXXNewContractTransmitterTestsOnly[RI]( + chainWriter, + ocrtypes.Account(transmitters[0].Hex()), + contractName, + methodTransmitWithoutSignatures, + ocr3HelperAddr.Hex(), + ocrimpls.ToExecCalldata, + ) + + return &testUniverse[RI]{ + simClient: simClient, + backend: backend, + deployer: owner, + transmitters: transmitters, + signers: signers, + wrapper: wrapper, + transmitterWithSigs: transmitterWithSigs, + transmitterWithoutSigs: transmitterWithoutSigs, + keyrings: keyrings, + f: f, + db: db, + txm: txm, + gasEstimator: gasEstimator, + } +} + +func (uni testUniverse[RI]) SignReport(t *testing.T, configDigest ocrtypes.ConfigDigest, rwi ocr3types.ReportWithInfo[RI], seqNum uint64) []ocrtypes.AttributedOnchainSignature { + var attributedSigs []ocrtypes.AttributedOnchainSignature + for i := uint8(0); i < uni.f+1; i++ { + t.Log("signing report with", hexutil.Encode(uni.keyrings[i].PublicKey())) + sig, err := uni.keyrings[i].Sign(configDigest, seqNum, rwi) + require.NoError(t, err, "failed to sign report") + attributedSigs = append(attributedSigs, ocrtypes.AttributedOnchainSignature{ + Signature: sig, + Signer: commontypes.OracleID(i), + }) + } + return attributedSigs +} + +func (uni testUniverse[RI]) TransmittedEvents(t *testing.T) []*multi_ocr3_helper.MultiOCR3HelperTransmitted { + iter, err := uni.wrapper.FilterTransmitted(&bind.FilterOpts{ + Start: 0, + }, nil) + require.NoError(t, err, "failed to create filter iterator") + var events []*multi_ocr3_helper.MultiOCR3HelperTransmitted + for iter.Next() { + event := iter.Event + events = append(events, event) + } + return events +} + +func randomReport(t *testing.T, len int) []byte { + report := make([]byte, len) + _, err := rand.Reader.Read(report) + require.NoError(t, err, "failed to read random bytes") + return report +} + +const ( + contractName = "MultiOCR3Helper" + methodTransmitWithSignatures = "TransmitWithSignatures" + methodTransmitWithoutSignatures = "TransmitWithoutSignatures" +) + +func chainWriterConfigRaw(fromAddress common.Address, maxGasPrice *assets.Wei) evmrelaytypes.ChainWriterConfig { + return evmrelaytypes.ChainWriterConfig{ + Contracts: map[string]*evmrelaytypes.ContractConfig{ + contractName: { + ContractABI: multi_ocr3_helper.MultiOCR3HelperABI, + Configs: map[string]*evmrelaytypes.ChainWriterDefinition{ + methodTransmitWithSignatures: { + ChainSpecificName: "transmitWithSignatures", + GasLimit: 1e6, + FromAddress: fromAddress, + }, + methodTransmitWithoutSignatures: { + ChainSpecificName: "transmitWithoutSignatures", + GasLimit: 1e6, + FromAddress: fromAddress, + }, + }, + }, + }, + SendStrategy: txmgrcommon.NewSendEveryStrategy(), + MaxGasPrice: maxGasPrice, + } +} + +func makeTestEvmTxm( + t *testing.T, + db *sqlx.DB, + ethClient client.Client, + keyStore keystore.Eth) (txmgr.TxManager, gas.EvmFeeEstimator) { + config, dbConfig, evmConfig := MakeTestConfigs(t) + + estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator()) + require.NoError(t, err, "failed to create gas estimator") + + lggr := logger.TestLogger(t) + lpOpts := logpoller.Opts{ + PollPeriod: 100 * time.Millisecond, + FinalityDepth: 2, + BackfillBatchSize: 3, + RpcBatchSize: 2, + KeepFinalizedBlocksDepth: 1000, + } + + chainID := big.NewInt(1337) + headSaver := headtracker.NewHeadSaver( + logger.NullLogger, + headtracker.NewORM(*chainID, db), + evmConfig, + evmConfig.HeadTrackerConfig, + ) + + broadcaster := headtracker.NewHeadBroadcaster(logger.NullLogger) + require.NoError(t, broadcaster.Start(testutils.Context(t)), "failed to start head broadcaster") + t.Cleanup(func() { require.NoError(t, broadcaster.Close()) }) + + ht := headtracker.NewHeadTracker( + logger.NullLogger, + ethClient, + evmConfig, + evmConfig.HeadTrackerConfig, + broadcaster, + headSaver, + mailbox.NewMonitor("contract_transmitter_test", logger.NullLogger), + ) + require.NoError(t, ht.Start(testutils.Context(t)), "failed to start head tracker") + t.Cleanup(func() { require.NoError(t, ht.Close()) }) + + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, logger.NullLogger), + ethClient, logger.NullLogger, ht, lpOpts) + require.NoError(t, lp.Start(testutils.Context(t)), "failed to start log poller") + t.Cleanup(func() { require.NoError(t, lp.Close()) }) + + // logic for building components (from evm/evm_txm.go) ------- + lggr.Infow("Initializing EVM transaction manager", + "bumpTxDepth", evmConfig.GasEstimator().BumpTxDepth(), + "maxInFlightTransactions", config.EvmConfig.Transactions().MaxInFlight(), + "maxQueuedTransactions", config.EvmConfig.Transactions().MaxQueued(), + "nonceAutoSync", evmConfig.NonceAutoSync(), + "limitDefault", evmConfig.GasEstimator().LimitDefault(), + ) + + txm, err := txmgr.NewTxm( + db, + config, + config.EvmConfig.GasEstimator(), + config.EvmConfig.Transactions(), + nil, + dbConfig, + dbConfig.Listener(), + ethClient, + lggr, + lp, + keyStore, + estimator, + ht) + require.NoError(t, err, "can't create tx manager") + + _, unsub := broadcaster.Subscribe(txm) + t.Cleanup(unsub) + + return txm, estimator +} + +// Code below copied/pasted and slightly modified in order to work from core/chains/evm/txmgr/test_helpers.go. + +func ptr[T any](t T) *T { return &t } + +type TestDatabaseConfig struct { + config.Database + defaultQueryTimeout time.Duration +} + +func (d *TestDatabaseConfig) DefaultQueryTimeout() time.Duration { + return d.defaultQueryTimeout +} + +func (d *TestDatabaseConfig) LogSQL() bool { + return false +} + +type TestListenerConfig struct { + config.Listener +} + +func (l *TestListenerConfig) FallbackPollInterval() time.Duration { + return 1 * time.Minute +} + +func (d *TestDatabaseConfig) Listener() config.Listener { + return &TestListenerConfig{} +} + +type TestHeadTrackerConfig struct{} + +// FinalityTagBypass implements config.HeadTracker. +func (t *TestHeadTrackerConfig) FinalityTagBypass() bool { + return false +} + +// HistoryDepth implements config.HeadTracker. +func (t *TestHeadTrackerConfig) HistoryDepth() uint32 { + return 50 +} + +// MaxAllowedFinalityDepth implements config.HeadTracker. +func (t *TestHeadTrackerConfig) MaxAllowedFinalityDepth() uint32 { + return 100 +} + +// MaxBufferSize implements config.HeadTracker. +func (t *TestHeadTrackerConfig) MaxBufferSize() uint32 { + return 100 +} + +// SamplingInterval implements config.HeadTracker. +func (t *TestHeadTrackerConfig) SamplingInterval() time.Duration { + return 1 * time.Second +} + +var _ evmconfig.HeadTracker = (*TestHeadTrackerConfig)(nil) + +type TestEvmConfig struct { + evmconfig.EVM + HeadTrackerConfig evmconfig.HeadTracker + MaxInFlight uint32 + ReaperInterval time.Duration + ReaperThreshold time.Duration + ResendAfterThreshold time.Duration + BumpThreshold uint64 + MaxQueued uint64 + Enabled bool + Threshold uint32 + MinAttempts uint32 + DetectionApiUrl *url.URL +} + +func (e *TestEvmConfig) FinalityTagEnabled() bool { + return false +} + +func (e *TestEvmConfig) FinalityDepth() uint32 { + return 42 +} + +func (e *TestEvmConfig) FinalizedBlockOffset() uint32 { + return 42 +} + +func (e *TestEvmConfig) BlockEmissionIdleWarningThreshold() time.Duration { + return 10 * time.Second +} + +func (e *TestEvmConfig) Transactions() evmconfig.Transactions { + return &transactionsConfig{e: e, autoPurge: &autoPurgeConfig{}} +} + +func (e *TestEvmConfig) NonceAutoSync() bool { return true } + +func (e *TestEvmConfig) ChainType() chaintype.ChainType { return "" } + +type TestGasEstimatorConfig struct { + bumpThreshold uint64 +} + +func (g *TestGasEstimatorConfig) BlockHistory() evmconfig.BlockHistory { + return &TestBlockHistoryConfig{} +} + +func (g *TestGasEstimatorConfig) EIP1559DynamicFees() bool { return false } +func (g *TestGasEstimatorConfig) LimitDefault() uint64 { return 1e6 } +func (g *TestGasEstimatorConfig) BumpPercent() uint16 { return 2 } +func (g *TestGasEstimatorConfig) BumpThreshold() uint64 { return g.bumpThreshold } +func (g *TestGasEstimatorConfig) BumpMin() *assets.Wei { return assets.GWei(1) } +func (g *TestGasEstimatorConfig) FeeCapDefault() *assets.Wei { return assets.GWei(1) } +func (g *TestGasEstimatorConfig) PriceDefault() *assets.Wei { return assets.GWei(1) } +func (g *TestGasEstimatorConfig) TipCapDefault() *assets.Wei { return assets.GWei(1) } +func (g *TestGasEstimatorConfig) TipCapMin() *assets.Wei { return assets.GWei(1) } +func (g *TestGasEstimatorConfig) LimitMax() uint64 { return 0 } +func (g *TestGasEstimatorConfig) LimitMultiplier() float32 { return 1 } +func (g *TestGasEstimatorConfig) BumpTxDepth() uint32 { return 42 } +func (g *TestGasEstimatorConfig) LimitTransfer() uint64 { return 42 } +func (g *TestGasEstimatorConfig) PriceMax() *assets.Wei { return assets.GWei(1) } +func (g *TestGasEstimatorConfig) PriceMin() *assets.Wei { return assets.GWei(1) } +func (g *TestGasEstimatorConfig) Mode() string { return "FixedPrice" } +func (g *TestGasEstimatorConfig) LimitJobType() evmconfig.LimitJobType { + return &TestLimitJobTypeConfig{} +} +func (g *TestGasEstimatorConfig) PriceMaxKey(addr common.Address) *assets.Wei { + return assets.GWei(1) +} + +func (e *TestEvmConfig) GasEstimator() evmconfig.GasEstimator { + return &TestGasEstimatorConfig{bumpThreshold: e.BumpThreshold} +} + +type TestLimitJobTypeConfig struct { +} + +func (l *TestLimitJobTypeConfig) OCR() *uint32 { return ptr(uint32(0)) } +func (l *TestLimitJobTypeConfig) OCR2() *uint32 { return ptr(uint32(0)) } +func (l *TestLimitJobTypeConfig) DR() *uint32 { return ptr(uint32(0)) } +func (l *TestLimitJobTypeConfig) FM() *uint32 { return ptr(uint32(0)) } +func (l *TestLimitJobTypeConfig) Keeper() *uint32 { return ptr(uint32(0)) } +func (l *TestLimitJobTypeConfig) VRF() *uint32 { return ptr(uint32(0)) } + +type TestBlockHistoryConfig struct { + evmconfig.BlockHistory +} + +func (b *TestBlockHistoryConfig) BatchSize() uint32 { return 42 } +func (b *TestBlockHistoryConfig) BlockDelay() uint16 { return 42 } +func (b *TestBlockHistoryConfig) BlockHistorySize() uint16 { return 42 } +func (b *TestBlockHistoryConfig) EIP1559FeeCapBufferBlocks() uint16 { return 42 } +func (b *TestBlockHistoryConfig) TransactionPercentile() uint16 { return 42 } + +type transactionsConfig struct { + evmconfig.Transactions + e *TestEvmConfig + autoPurge evmconfig.AutoPurgeConfig +} + +func (*transactionsConfig) ForwardersEnabled() bool { return false } +func (t *transactionsConfig) MaxInFlight() uint32 { return t.e.MaxInFlight } +func (t *transactionsConfig) MaxQueued() uint64 { return t.e.MaxQueued } +func (t *transactionsConfig) ReaperInterval() time.Duration { return t.e.ReaperInterval } +func (t *transactionsConfig) ReaperThreshold() time.Duration { return t.e.ReaperThreshold } +func (t *transactionsConfig) ResendAfterThreshold() time.Duration { return t.e.ResendAfterThreshold } +func (t *transactionsConfig) AutoPurge() evmconfig.AutoPurgeConfig { return t.autoPurge } + +type autoPurgeConfig struct { + evmconfig.AutoPurgeConfig +} + +func (a *autoPurgeConfig) Enabled() bool { return false } + +type MockConfig struct { + EvmConfig *TestEvmConfig + RpcDefaultBatchSize uint32 + finalityDepth uint32 + finalityTagEnabled bool +} + +func (c *MockConfig) EVM() evmconfig.EVM { + return c.EvmConfig +} + +func (c *MockConfig) NonceAutoSync() bool { return true } +func (c *MockConfig) ChainType() chaintype.ChainType { return "" } +func (c *MockConfig) FinalityDepth() uint32 { return c.finalityDepth } +func (c *MockConfig) SetFinalityDepth(fd uint32) { c.finalityDepth = fd } +func (c *MockConfig) FinalityTagEnabled() bool { return c.finalityTagEnabled } +func (c *MockConfig) RPCDefaultBatchSize() uint32 { return c.RpcDefaultBatchSize } + +func MakeTestConfigs(t *testing.T) (*MockConfig, *TestDatabaseConfig, *TestEvmConfig) { + db := &TestDatabaseConfig{defaultQueryTimeout: utils.DefaultQueryTimeout} + ec := &TestEvmConfig{ + HeadTrackerConfig: &TestHeadTrackerConfig{}, + BumpThreshold: 42, + MaxInFlight: uint32(42), + MaxQueued: uint64(0), + ReaperInterval: time.Duration(0), + ReaperThreshold: time.Duration(0), + } + config := &MockConfig{EvmConfig: ec} + return config, db, ec +} diff --git a/core/capabilities/ccip/ocrimpls/keyring.go b/core/capabilities/ccip/ocrimpls/keyring.go new file mode 100644 index 0000000000..4b15c75b09 --- /dev/null +++ b/core/capabilities/ccip/ocrimpls/keyring.go @@ -0,0 +1,61 @@ +package ocrimpls + +import ( + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +var _ ocr3types.OnchainKeyring[[]byte] = &ocr3Keyring[[]byte]{} + +type ocr3Keyring[RI any] struct { + core types.OnchainKeyring + lggr logger.Logger +} + +func NewOnchainKeyring[RI any](keyring types.OnchainKeyring, lggr logger.Logger) *ocr3Keyring[RI] { + return &ocr3Keyring[RI]{ + core: keyring, + lggr: lggr.Named("OCR3Keyring"), + } +} + +func (w *ocr3Keyring[RI]) PublicKey() types.OnchainPublicKey { + return w.core.PublicKey() +} + +func (w *ocr3Keyring[RI]) MaxSignatureLength() int { + return w.core.MaxSignatureLength() +} + +func (w *ocr3Keyring[RI]) Sign(configDigest types.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[RI]) (signature []byte, err error) { + epoch, round := uint64ToUint32AndUint8(seqNr) + rCtx := types.ReportContext{ + ReportTimestamp: types.ReportTimestamp{ + ConfigDigest: configDigest, + Epoch: epoch, + Round: round, + }, + } + + w.lggr.Debugw("signing report", "configDigest", configDigest.Hex(), "seqNr", seqNr, "report", hexutil.Encode(r.Report)) + + return w.core.Sign(rCtx, r.Report) +} + +func (w *ocr3Keyring[RI]) Verify(key types.OnchainPublicKey, configDigest types.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[RI], signature []byte) bool { + epoch, round := uint64ToUint32AndUint8(seqNr) + rCtx := types.ReportContext{ + ReportTimestamp: types.ReportTimestamp{ + ConfigDigest: configDigest, + Epoch: epoch, + Round: round, + }, + } + + w.lggr.Debugw("verifying report", "configDigest", configDigest.Hex(), "seqNr", seqNr, "report", hexutil.Encode(r.Report)) + + return w.core.Verify(key, rCtx, r.Report, signature) +} diff --git a/core/capabilities/ccip/oraclecreator/inprocess.go b/core/capabilities/ccip/oraclecreator/inprocess.go new file mode 100644 index 0000000000..6616d35675 --- /dev/null +++ b/core/capabilities/ccip/oraclecreator/inprocess.go @@ -0,0 +1,371 @@ +package oraclecreator + +import ( + "context" + "fmt" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccipevm" + evmconfig "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/configs/evm" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ocrimpls" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/google/uuid" + "github.com/prometheus/client_golang/prometheus" + + chainsel "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink-ccip/pkg/consts" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + + "github.com/smartcontractkit/libocr/commontypes" + libocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + commitocr3 "github.com/smartcontractkit/chainlink-ccip/commit" + execocr3 "github.com/smartcontractkit/chainlink-ccip/execute" + ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + + "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" +) + +var _ cctypes.OracleCreator = &inprocessOracleCreator{} + +const ( + defaultCommitGasLimit = 500_000 +) + +// inprocessOracleCreator creates oracles that reference plugins running +// in the same process as the chainlink node, i.e not LOOPPs. +type inprocessOracleCreator struct { + ocrKeyBundles map[string]ocr2key.KeyBundle + transmitters map[types.RelayID][]string + chains legacyevm.LegacyChainContainer + peerWrapper *ocrcommon.SingletonPeerWrapper + externalJobID uuid.UUID + jobID int32 + isNewlyCreatedJob bool + pluginConfig job.JSONConfig + db ocr3types.Database + lggr logger.Logger + monitoringEndpointGen telemetry.MonitoringEndpointGenerator + bootstrapperLocators []commontypes.BootstrapperLocator + homeChainReader ccipreaderpkg.HomeChain +} + +func New( + ocrKeyBundles map[string]ocr2key.KeyBundle, + transmitters map[types.RelayID][]string, + chains legacyevm.LegacyChainContainer, + peerWrapper *ocrcommon.SingletonPeerWrapper, + externalJobID uuid.UUID, + jobID int32, + isNewlyCreatedJob bool, + pluginConfig job.JSONConfig, + db ocr3types.Database, + lggr logger.Logger, + monitoringEndpointGen telemetry.MonitoringEndpointGenerator, + bootstrapperLocators []commontypes.BootstrapperLocator, + homeChainReader ccipreaderpkg.HomeChain, +) cctypes.OracleCreator { + return &inprocessOracleCreator{ + ocrKeyBundles: ocrKeyBundles, + transmitters: transmitters, + chains: chains, + peerWrapper: peerWrapper, + externalJobID: externalJobID, + jobID: jobID, + isNewlyCreatedJob: isNewlyCreatedJob, + pluginConfig: pluginConfig, + db: db, + lggr: lggr, + monitoringEndpointGen: monitoringEndpointGen, + bootstrapperLocators: bootstrapperLocators, + homeChainReader: homeChainReader, + } +} + +// CreateBootstrapOracle implements types.OracleCreator. +func (i *inprocessOracleCreator) CreateBootstrapOracle(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { + // Assuming that the chain selector is referring to an evm chain for now. + // TODO: add an api that returns chain family. + chainID, err := chainsel.ChainIdFromSelector(uint64(config.Config.ChainSelector)) + if err != nil { + return nil, fmt.Errorf("failed to get chain ID from selector: %w", err) + } + + destChainFamily := chaintype.EVM + destRelayID := types.NewRelayID(string(destChainFamily), fmt.Sprintf("%d", chainID)) + + bootstrapperArgs := libocr3.BootstrapperArgs{ + BootstrapperFactory: i.peerWrapper.Peer2, + V2Bootstrappers: i.bootstrapperLocators, + ContractConfigTracker: ocrimpls.NewConfigTracker(config), + Database: i.db, + LocalConfig: defaultLocalConfig(), + Logger: ocrcommon.NewOCRWrapper( + i.lggr. + Named("CCIPBootstrap"). + Named(destRelayID.String()). + Named(config.Config.ChainSelector.String()). + Named(hexutil.Encode(config.Config.OfframpAddress)), + false, /* traceLogging */ + func(ctx context.Context, msg string) {}), + MonitoringEndpoint: i.monitoringEndpointGen.GenMonitoringEndpoint( + string(destChainFamily), + destRelayID.ChainID, + hexutil.Encode(config.Config.OfframpAddress), + synchronization.OCR3CCIPBootstrap, + ), + OffchainConfigDigester: ocrimpls.NewConfigDigester(config.ConfigDigest), + } + bootstrapper, err := libocr3.NewBootstrapper(bootstrapperArgs) + if err != nil { + return nil, err + } + return bootstrapper, nil +} + +// CreatePluginOracle implements types.OracleCreator. +func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginType, config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { + // Assuming that the chain selector is referring to an evm chain for now. + // TODO: add an api that returns chain family. + destChainID, err := chainsel.ChainIdFromSelector(uint64(config.Config.ChainSelector)) + if err != nil { + return nil, fmt.Errorf("failed to get chain ID from selector %d: %w", config.Config.ChainSelector, err) + } + destChainFamily := relay.NetworkEVM + destRelayID := types.NewRelayID(destChainFamily, fmt.Sprintf("%d", destChainID)) + + configTracker := ocrimpls.NewConfigTracker(config) + publicConfig, err := configTracker.PublicConfig() + if err != nil { + return nil, fmt.Errorf("failed to get public config from OCR config: %w", err) + } + var execBatchGasLimit uint64 + if pluginType == cctypes.PluginTypeCCIPExec { + execOffchainConfig, err2 := pluginconfig.DecodeExecuteOffchainConfig(publicConfig.ReportingPluginConfig) + if err2 != nil { + return nil, fmt.Errorf("failed to decode execute offchain config: %w, raw: %s", + err2, string(publicConfig.ReportingPluginConfig)) + } + if execOffchainConfig.BatchGasLimit == 0 && destChainFamily == relay.NetworkEVM { + return nil, fmt.Errorf("BatchGasLimit not set in execute offchain config, must be > 0") + } + execBatchGasLimit = execOffchainConfig.BatchGasLimit + } + + // this is so that we can use the msg hasher and report encoder from that dest chain relayer's provider. + contractReaders := make(map[cciptypes.ChainSelector]types.ContractReader) + chainWriters := make(map[cciptypes.ChainSelector]types.ChainWriter) + for _, chain := range i.chains.Slice() { + var chainReaderConfig evmrelaytypes.ChainReaderConfig + if chain.ID().Uint64() == destChainID { + chainReaderConfig = evmconfig.DestReaderConfig() + } else { + chainReaderConfig = evmconfig.SourceReaderConfig() + } + cr, err2 := evm.NewChainReaderService( + context.Background(), + i.lggr. + Named("EVMChainReaderService"). + Named(chain.ID().String()). + Named(pluginType.String()), + chain.LogPoller(), + chain.HeadTracker(), + chain.Client(), + chainReaderConfig, + ) + if err2 != nil { + return nil, fmt.Errorf("failed to create contract reader for chain %s: %w", chain.ID(), err2) + } + + if chain.ID().Uint64() == destChainID { + // bind the chain reader to the dest chain's offramp. + offrampAddressHex := common.BytesToAddress(config.Config.OfframpAddress).Hex() + err3 := cr.Bind(context.Background(), []types.BoundContract{ + { + Address: offrampAddressHex, + Name: consts.ContractNameOffRamp, + }, + }) + if err3 != nil { + return nil, fmt.Errorf("failed to bind chain reader for dest chain %s's offramp at %s: %w", chain.ID(), offrampAddressHex, err3) + } + } + + // TODO: figure out shutdown. + // maybe from the plugin directly? + err2 = cr.Start(context.Background()) + if err2 != nil { + return nil, fmt.Errorf("failed to start contract reader for chain %s: %w", chain.ID(), err2) + } + + // Even though we only write to the dest chain, we need to create chain writers for all chains + // we know about in order to post gas prices on the dest. + var fromAddress common.Address + transmitter, ok := i.transmitters[types.NewRelayID(relay.NetworkEVM, chain.ID().String())] + if ok { + fromAddress = common.HexToAddress(transmitter[0]) + } + cw, err2 := evm.NewChainWriterService( + i.lggr.Named("EVMChainWriterService"). + Named(chain.ID().String()). + Named(pluginType.String()), + chain.Client(), + chain.TxManager(), + chain.GasEstimator(), + evmconfig.ChainWriterConfigRaw( + fromAddress, + chain.Config().EVM().GasEstimator().PriceMaxKey(fromAddress), + defaultCommitGasLimit, + execBatchGasLimit, + ), + ) + if err2 != nil { + return nil, fmt.Errorf("failed to create chain writer for chain %s: %w", chain.ID(), err2) + } + + // TODO: figure out shutdown. + // maybe from the plugin directly? + err2 = cw.Start(context.Background()) + if err2 != nil { + return nil, fmt.Errorf("failed to start chain writer for chain %s: %w", chain.ID(), err2) + } + + chainSelector, ok := chainsel.EvmChainIdToChainSelector()[chain.ID().Uint64()] + if !ok { + return nil, fmt.Errorf("failed to get chain selector from chain ID %s", chain.ID()) + } + + contractReaders[cciptypes.ChainSelector(chainSelector)] = cr + chainWriters[cciptypes.ChainSelector(chainSelector)] = cw + } + + // build the onchain keyring. it will be the signing key for the destination chain family. + keybundle, ok := i.ocrKeyBundles[destChainFamily] + if !ok { + return nil, fmt.Errorf("no OCR key bundle found for chain family %s, forgot to create one?", destChainFamily) + } + onchainKeyring := ocrimpls.NewOnchainKeyring[[]byte](keybundle, i.lggr) + + // build the contract transmitter + // assume that we are using the first account in the keybundle as the from account + // and that we are able to transmit to the dest chain. + // TODO: revisit this in the future, since not all oracles will be able to transmit to the dest chain. + destChainWriter, ok := chainWriters[config.Config.ChainSelector] + if !ok { + return nil, fmt.Errorf("no chain writer found for dest chain selector %d, can't create contract transmitter", + config.Config.ChainSelector) + } + destFromAccounts, ok := i.transmitters[destRelayID] + if !ok { + return nil, fmt.Errorf("no transmitter found for dest relay ID %s, can't create contract transmitter", destRelayID) + } + + // TODO: Extract the correct transmitter address from the destsFromAccount + var factory ocr3types.ReportingPluginFactory[[]byte] + var transmitter ocr3types.ContractTransmitter[[]byte] + if config.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) { + factory = commitocr3.NewPluginFactory( + i.lggr. + Named("CCIPCommitPlugin"). + Named(destRelayID.String()). + Named(fmt.Sprintf("%d", config.Config.ChainSelector)). + Named(hexutil.Encode(config.Config.OfframpAddress)), + ccipreaderpkg.OCR3ConfigWithMeta(config), + ccipevm.NewCommitPluginCodecV1(), + ccipevm.NewMessageHasherV1(), + i.homeChainReader, + contractReaders, + chainWriters, + ) + transmitter = ocrimpls.NewCommitContractTransmitter[[]byte](destChainWriter, + ocrtypes.Account(destFromAccounts[0]), + hexutil.Encode(config.Config.OfframpAddress), // TODO: this works for evm only, how about non-evm? + ) + } else if config.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) { + factory = execocr3.NewPluginFactory( + i.lggr. + Named("CCIPExecPlugin"). + Named(destRelayID.String()). + Named(hexutil.Encode(config.Config.OfframpAddress)), + ccipreaderpkg.OCR3ConfigWithMeta(config), + ccipevm.NewExecutePluginCodecV1(), + ccipevm.NewMessageHasherV1(), + i.homeChainReader, + contractReaders, + chainWriters, + ) + transmitter = ocrimpls.NewExecContractTransmitter[[]byte](destChainWriter, + ocrtypes.Account(destFromAccounts[0]), + hexutil.Encode(config.Config.OfframpAddress), // TODO: this works for evm only, how about non-evm? + ) + } else { + return nil, fmt.Errorf("unsupported plugin type %d", config.Config.PluginType) + } + + oracleArgs := libocr3.OCR3OracleArgs[[]byte]{ + BinaryNetworkEndpointFactory: i.peerWrapper.Peer2, + Database: i.db, + V2Bootstrappers: i.bootstrapperLocators, + ContractConfigTracker: configTracker, + ContractTransmitter: transmitter, + LocalConfig: defaultLocalConfig(), + Logger: ocrcommon.NewOCRWrapper( + i.lggr. + Named(fmt.Sprintf("CCIP%sOCR3", pluginType.String())). + Named(destRelayID.String()). + Named(hexutil.Encode(config.Config.OfframpAddress)), + false, + func(ctx context.Context, msg string) {}), + MetricsRegisterer: prometheus.WrapRegistererWith(map[string]string{"name": fmt.Sprintf("commit-%d", config.Config.ChainSelector)}, prometheus.DefaultRegisterer), + MonitoringEndpoint: i.monitoringEndpointGen.GenMonitoringEndpoint( + destChainFamily, + destRelayID.ChainID, + string(config.Config.OfframpAddress), + synchronization.OCR3CCIPCommit, + ), + OffchainConfigDigester: ocrimpls.NewConfigDigester(config.ConfigDigest), + OffchainKeyring: keybundle, + OnchainKeyring: onchainKeyring, + ReportingPluginFactory: factory, + } + oracle, err := libocr3.NewOracle(oracleArgs) + if err != nil { + return nil, err + } + return oracle, nil +} + +func defaultLocalConfig() ocrtypes.LocalConfig { + return ocrtypes.LocalConfig{ + BlockchainTimeout: 10 * time.Second, + // Config tracking is handled by the launcher, since we're doing blue-green + // deployments we're not going to be using OCR's built-in config switching, + // which always shuts down the previous instance. + ContractConfigConfirmations: 1, + SkipContractConfigConfirmations: true, + ContractConfigTrackerPollInterval: 10 * time.Second, + ContractTransmitterTransmitTimeout: 10 * time.Second, + DatabaseTimeout: 10 * time.Second, + MinOCR2MaxDurationQuery: 1 * time.Second, + DevelopmentMode: "false", + } +} diff --git a/core/capabilities/ccip/oraclecreator/inprocess_test.go b/core/capabilities/ccip/oraclecreator/inprocess_test.go new file mode 100644 index 0000000000..639f01e62e --- /dev/null +++ b/core/capabilities/ccip/oraclecreator/inprocess_test.go @@ -0,0 +1,239 @@ +package oraclecreator_test + +import ( + "fmt" + "testing" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/oraclecreator" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/google/uuid" + "github.com/hashicorp/consul/sdk/freeport" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/guregu/null.v4" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/libocr/offchainreporting2/types" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + + "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + + "github.com/smartcontractkit/libocr/commontypes" + + "github.com/smartcontractkit/chainlink/v2/core/bridges" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2" + ocr2validate "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" + "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +func TestOracleCreator_CreateBootstrap(t *testing.T) { + db := pgtest.NewSqlxDB(t) + + keyStore := keystore.New(db, utils.DefaultScryptParams, logger.NullLogger) + require.NoError(t, keyStore.Unlock(testutils.Context(t), cltest.Password), "unable to unlock keystore") + p2pKey, err := keyStore.P2P().Create(testutils.Context(t)) + require.NoError(t, err) + peerID := p2pKey.PeerID() + listenPort := freeport.GetOne(t) + generalConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.P2P.PeerID = ptr(peerID) + c.P2P.TraceLogging = ptr(false) + c.P2P.V2.Enabled = ptr(true) + c.P2P.V2.ListenAddresses = ptr([]string{fmt.Sprintf("127.0.0.1:%d", listenPort)}) + + c.OCR2.Enabled = ptr(true) + }) + peerWrapper := ocrcommon.NewSingletonPeerWrapper(keyStore, generalConfig.P2P(), generalConfig.OCR(), db, logger.NullLogger) + require.NoError(t, peerWrapper.Start(testutils.Context(t))) + t.Cleanup(func() { assert.NoError(t, peerWrapper.Close()) }) + + // NOTE: this is a bit of a hack to get the OCR2 job created in order to use the ocr db + // the ocr2_contract_configs table has a foreign key constraint on ocr2_oracle_spec_id + // which is passed into ocr2.NewDB. + pipelineORM := pipeline.NewORM(db, + logger.NullLogger, generalConfig.JobPipeline().MaxSuccessfulRuns()) + bridgesORM := bridges.NewORM(db) + + jobORM := job.NewORM(db, pipelineORM, bridgesORM, keyStore, logger.TestLogger(t)) + t.Cleanup(func() { assert.NoError(t, jobORM.Close()) }) + + jb, err := ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), generalConfig.OCR2(), generalConfig.Insecure(), testspecs.GetOCR2EVMSpecMinimal(), nil) + require.NoError(t, err) + const juelsPerFeeCoinSource = ` + ds [type=http method=GET url="https://chain.link/ETH-USD"]; + ds_parse [type=jsonparse path="data.price" separator="."]; + ds_multiply [type=multiply times=100]; + ds -> ds_parse -> ds_multiply;` + + _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) + jb.Name = null.StringFrom("Job 1") + jb.OCR2OracleSpec.TransmitterID = null.StringFrom(address.String()) + jb.OCR2OracleSpec.PluginConfig["juelsPerFeeCoinSource"] = juelsPerFeeCoinSource + + err = jobORM.CreateJob(testutils.Context(t), &jb) + require.NoError(t, err) + + cltest.AssertCount(t, db, "ocr2_oracle_specs", 1) + cltest.AssertCount(t, db, "jobs", 1) + + var oracleSpecID int32 + err = db.Get(&oracleSpecID, "SELECT id FROM ocr2_oracle_specs LIMIT 1") + require.NoError(t, err) + + ocrdb := ocr2.NewDB(db, oracleSpecID, 0, logger.NullLogger) + + oc := oraclecreator.New( + nil, + nil, + nil, + peerWrapper, + uuid.Max, + 0, + false, + nil, + ocrdb, + logger.TestLogger(t), + &mockEndpointGen{}, + []commontypes.BootstrapperLocator{}, + nil, + ) + + chainSelector := chainsel.GETH_TESTNET.Selector + oracles, offchainConfig := ocrOffchainConfig(t, keyStore) + bootstrapP2PID, err := p2pkey.MakePeerID(oracles[0].PeerID) + require.NoError(t, err) + transmitters := func() [][]byte { + var transmitters [][]byte + for _, o := range oracles { + transmitters = append(transmitters, hexutil.MustDecode(string(o.TransmitAccount))) + } + return transmitters + }() + configDigest := ccipConfigDigest() + bootstrap, err := oc.CreateBootstrapOracle(cctypes.OCR3ConfigWithMeta{ + ConfigDigest: configDigest, + ConfigCount: 1, + Config: reader.OCR3Config{ + ChainSelector: ccipocr3.ChainSelector(chainSelector), + OfframpAddress: testutils.NewAddress().Bytes(), + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + F: 1, + OffchainConfigVersion: 30, + BootstrapP2PIds: [][32]byte{bootstrapP2PID}, + P2PIds: func() [][32]byte { + var ids [][32]byte + for _, o := range oracles { + id, err2 := p2pkey.MakePeerID(o.PeerID) + require.NoError(t, err2) + ids = append(ids, id) + } + return ids + }(), + Signers: func() [][]byte { + var signers [][]byte + for _, o := range oracles { + signers = append(signers, o.OnchainPublicKey) + } + return signers + }(), + Transmitters: transmitters, + OffchainConfig: offchainConfig, + }, + }) + require.NoError(t, err) + require.NoError(t, bootstrap.Start()) + t.Cleanup(func() { assert.NoError(t, bootstrap.Close()) }) + + tests.AssertEventually(t, func() bool { + c, err := ocrdb.ReadConfig(testutils.Context(t)) + require.NoError(t, err) + return c.ConfigDigest == configDigest + }) +} + +func ccipConfigDigest() [32]byte { + rand32Bytes := testutils.Random32Byte() + // overwrite first four bytes to be 0x000a, to match the prefix in libocr. + rand32Bytes[0] = 0x00 + rand32Bytes[1] = 0x0a + return rand32Bytes +} + +type mockEndpointGen struct{} + +func (m *mockEndpointGen) GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) commontypes.MonitoringEndpoint { + return &telemetry.NoopAgent{} +} + +func ptr[T any](b T) *T { + return &b +} + +func ocrOffchainConfig(t *testing.T, ks keystore.Master) (oracles []confighelper2.OracleIdentityExtra, offchainConfig []byte) { + for i := 0; i < 4; i++ { + kb, err := ks.OCR2().Create(testutils.Context(t), chaintype.EVM) + require.NoError(t, err) + p2pKey, err := ks.P2P().Create(testutils.Context(t)) + require.NoError(t, err) + ethKey, err := ks.Eth().Create(testutils.Context(t)) + require.NoError(t, err) + oracles = append(oracles, confighelper2.OracleIdentityExtra{ + OracleIdentity: confighelper2.OracleIdentity{ + OffchainPublicKey: kb.OffchainPublicKey(), + OnchainPublicKey: types.OnchainPublicKey(kb.OnChainPublicKey()), + PeerID: p2pKey.ID(), + TransmitAccount: types.Account(ethKey.Address.Hex()), + }, + ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), + }) + } + var schedule []int + for range oracles { + schedule = append(schedule, 1) + } + offchainConfig, onchainConfig := []byte{}, []byte{} + f := uint8(1) + + _, _, _, _, _, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( + 30*time.Second, // deltaProgress + 10*time.Second, // deltaResend + 20*time.Second, // deltaInitial + 2*time.Second, // deltaRound + 20*time.Second, // deltaGrace + 10*time.Second, // deltaCertifiedCommitRequest + 10*time.Second, // deltaStage + 3, // rmax + schedule, + oracles, + offchainConfig, + 50*time.Millisecond, // maxDurationQuery + 5*time.Second, // maxDurationObservation + 10*time.Second, // maxDurationShouldAcceptAttestedReport + 10*time.Second, // maxDurationShouldTransmitAcceptedReport + int(f), + onchainConfig) + require.NoError(t, err, "failed to create contract config") + + return oracles, offchainConfig +} diff --git a/core/capabilities/ccip/types/mocks/ccip_oracle.go b/core/capabilities/ccip/types/mocks/ccip_oracle.go new file mode 100644 index 0000000000..c849b3d941 --- /dev/null +++ b/core/capabilities/ccip/types/mocks/ccip_oracle.go @@ -0,0 +1,122 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import mock "github.com/stretchr/testify/mock" + +// CCIPOracle is an autogenerated mock type for the CCIPOracle type +type CCIPOracle struct { + mock.Mock +} + +type CCIPOracle_Expecter struct { + mock *mock.Mock +} + +func (_m *CCIPOracle) EXPECT() *CCIPOracle_Expecter { + return &CCIPOracle_Expecter{mock: &_m.Mock} +} + +// Close provides a mock function with given fields: +func (_m *CCIPOracle) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CCIPOracle_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type CCIPOracle_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *CCIPOracle_Expecter) Close() *CCIPOracle_Close_Call { + return &CCIPOracle_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *CCIPOracle_Close_Call) Run(run func()) *CCIPOracle_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *CCIPOracle_Close_Call) Return(_a0 error) *CCIPOracle_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *CCIPOracle_Close_Call) RunAndReturn(run func() error) *CCIPOracle_Close_Call { + _c.Call.Return(run) + return _c +} + +// Start provides a mock function with given fields: +func (_m *CCIPOracle) Start() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Start") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CCIPOracle_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start' +type CCIPOracle_Start_Call struct { + *mock.Call +} + +// Start is a helper method to define mock.On call +func (_e *CCIPOracle_Expecter) Start() *CCIPOracle_Start_Call { + return &CCIPOracle_Start_Call{Call: _e.mock.On("Start")} +} + +func (_c *CCIPOracle_Start_Call) Run(run func()) *CCIPOracle_Start_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *CCIPOracle_Start_Call) Return(_a0 error) *CCIPOracle_Start_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *CCIPOracle_Start_Call) RunAndReturn(run func() error) *CCIPOracle_Start_Call { + _c.Call.Return(run) + return _c +} + +// NewCCIPOracle creates a new instance of CCIPOracle. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewCCIPOracle(t interface { + mock.TestingT + Cleanup(func()) +}) *CCIPOracle { + mock := &CCIPOracle{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/capabilities/ccip/types/mocks/home_chain_reader.go b/core/capabilities/ccip/types/mocks/home_chain_reader.go new file mode 100644 index 0000000000..a5a581a1d2 --- /dev/null +++ b/core/capabilities/ccip/types/mocks/home_chain_reader.go @@ -0,0 +1,129 @@ +package mocks + +import ( + "context" + + mapset "github.com/deckarep/golang-set/v2" + "github.com/stretchr/testify/mock" + + ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + "github.com/smartcontractkit/libocr/ragep2p/types" +) + +var _ ccipreaderpkg.HomeChain = (*HomeChainReader)(nil) + +type HomeChainReader struct { + mock.Mock +} + +func (_m *HomeChainReader) GetChainConfig(chainSelector cciptypes.ChainSelector) (ccipreaderpkg.ChainConfig, error) { + //TODO implement me + panic("implement me") +} + +func (_m *HomeChainReader) GetAllChainConfigs() (map[cciptypes.ChainSelector]ccipreaderpkg.ChainConfig, error) { + //TODO implement me + panic("implement me") +} + +func (_m *HomeChainReader) GetSupportedChainsForPeer(id types.PeerID) (mapset.Set[cciptypes.ChainSelector], error) { + //TODO implement me + panic("implement me") +} + +func (_m *HomeChainReader) GetKnownCCIPChains() (mapset.Set[cciptypes.ChainSelector], error) { + //TODO implement me + panic("implement me") +} + +func (_m *HomeChainReader) GetFChain() (map[cciptypes.ChainSelector]int, error) { + //TODO implement me + panic("implement me") +} + +func (_m *HomeChainReader) Start(ctx context.Context) error { + //TODO implement me + panic("implement me") +} + +func (_m *HomeChainReader) Close() error { + //TODO implement me + panic("implement me") +} + +func (_m *HomeChainReader) HealthReport() map[string]error { + //TODO implement me + panic("implement me") +} + +func (_m *HomeChainReader) Name() string { + //TODO implement me + panic("implement me") +} + +// GetOCRConfigs provides a mock function with given fields: ctx, donID, pluginType +func (_m *HomeChainReader) GetOCRConfigs(ctx context.Context, donID uint32, pluginType uint8) ([]ccipreaderpkg.OCR3ConfigWithMeta, error) { + ret := _m.Called(ctx, donID, pluginType) + + if len(ret) == 0 { + panic("no return value specified for GetOCRConfigs") + } + + var r0 []ccipreaderpkg.OCR3ConfigWithMeta + var r1 error + if rf, ok := ret.Get(0).(func(ctx context.Context, donID uint32, pluginType uint8) ([]ccipreaderpkg.OCR3ConfigWithMeta, error)); ok { + return rf(ctx, donID, pluginType) + } + if rf, ok := ret.Get(0).(func(ctx context.Context, donID uint32, pluginType uint8) []ccipreaderpkg.OCR3ConfigWithMeta); ok { + r0 = rf(ctx, donID, pluginType) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccipreaderpkg.OCR3ConfigWithMeta) + } + } + + if rf, ok := ret.Get(1).(func(ctx context.Context, donID uint32, pluginType uint8) error); ok { + r1 = rf(ctx, donID, pluginType) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +func (_m *HomeChainReader) Ready() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Ready") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// NewHomeChainReader creates a new instance of HomeChainReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewHomeChainReader(t interface { + mock.TestingT + Cleanup(func()) +}) *HomeChainReader { + mock := &HomeChainReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/capabilities/ccip/types/mocks/oracle_creator.go b/core/capabilities/ccip/types/mocks/oracle_creator.go new file mode 100644 index 0000000000..d83ad042bf --- /dev/null +++ b/core/capabilities/ccip/types/mocks/oracle_creator.go @@ -0,0 +1,152 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + types "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + mock "github.com/stretchr/testify/mock" +) + +// OracleCreator is an autogenerated mock type for the OracleCreator type +type OracleCreator struct { + mock.Mock +} + +type OracleCreator_Expecter struct { + mock *mock.Mock +} + +func (_m *OracleCreator) EXPECT() *OracleCreator_Expecter { + return &OracleCreator_Expecter{mock: &_m.Mock} +} + +// CreateBootstrapOracle provides a mock function with given fields: config +func (_m *OracleCreator) CreateBootstrapOracle(config types.OCR3ConfigWithMeta) (types.CCIPOracle, error) { + ret := _m.Called(config) + + if len(ret) == 0 { + panic("no return value specified for CreateBootstrapOracle") + } + + var r0 types.CCIPOracle + var r1 error + if rf, ok := ret.Get(0).(func(types.OCR3ConfigWithMeta) (types.CCIPOracle, error)); ok { + return rf(config) + } + if rf, ok := ret.Get(0).(func(types.OCR3ConfigWithMeta) types.CCIPOracle); ok { + r0 = rf(config) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(types.CCIPOracle) + } + } + + if rf, ok := ret.Get(1).(func(types.OCR3ConfigWithMeta) error); ok { + r1 = rf(config) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OracleCreator_CreateBootstrapOracle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateBootstrapOracle' +type OracleCreator_CreateBootstrapOracle_Call struct { + *mock.Call +} + +// CreateBootstrapOracle is a helper method to define mock.On call +// - config types.OCR3ConfigWithMeta +func (_e *OracleCreator_Expecter) CreateBootstrapOracle(config interface{}) *OracleCreator_CreateBootstrapOracle_Call { + return &OracleCreator_CreateBootstrapOracle_Call{Call: _e.mock.On("CreateBootstrapOracle", config)} +} + +func (_c *OracleCreator_CreateBootstrapOracle_Call) Run(run func(config types.OCR3ConfigWithMeta)) *OracleCreator_CreateBootstrapOracle_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.OCR3ConfigWithMeta)) + }) + return _c +} + +func (_c *OracleCreator_CreateBootstrapOracle_Call) Return(_a0 types.CCIPOracle, _a1 error) *OracleCreator_CreateBootstrapOracle_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OracleCreator_CreateBootstrapOracle_Call) RunAndReturn(run func(types.OCR3ConfigWithMeta) (types.CCIPOracle, error)) *OracleCreator_CreateBootstrapOracle_Call { + _c.Call.Return(run) + return _c +} + +// CreatePluginOracle provides a mock function with given fields: pluginType, config +func (_m *OracleCreator) CreatePluginOracle(pluginType types.PluginType, config types.OCR3ConfigWithMeta) (types.CCIPOracle, error) { + ret := _m.Called(pluginType, config) + + if len(ret) == 0 { + panic("no return value specified for CreatePluginOracle") + } + + var r0 types.CCIPOracle + var r1 error + if rf, ok := ret.Get(0).(func(types.PluginType, types.OCR3ConfigWithMeta) (types.CCIPOracle, error)); ok { + return rf(pluginType, config) + } + if rf, ok := ret.Get(0).(func(types.PluginType, types.OCR3ConfigWithMeta) types.CCIPOracle); ok { + r0 = rf(pluginType, config) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(types.CCIPOracle) + } + } + + if rf, ok := ret.Get(1).(func(types.PluginType, types.OCR3ConfigWithMeta) error); ok { + r1 = rf(pluginType, config) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OracleCreator_CreatePluginOracle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePluginOracle' +type OracleCreator_CreatePluginOracle_Call struct { + *mock.Call +} + +// CreatePluginOracle is a helper method to define mock.On call +// - pluginType types.PluginType +// - config types.OCR3ConfigWithMeta +func (_e *OracleCreator_Expecter) CreatePluginOracle(pluginType interface{}, config interface{}) *OracleCreator_CreatePluginOracle_Call { + return &OracleCreator_CreatePluginOracle_Call{Call: _e.mock.On("CreatePluginOracle", pluginType, config)} +} + +func (_c *OracleCreator_CreatePluginOracle_Call) Run(run func(pluginType types.PluginType, config types.OCR3ConfigWithMeta)) *OracleCreator_CreatePluginOracle_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.PluginType), args[1].(types.OCR3ConfigWithMeta)) + }) + return _c +} + +func (_c *OracleCreator_CreatePluginOracle_Call) Return(_a0 types.CCIPOracle, _a1 error) *OracleCreator_CreatePluginOracle_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *OracleCreator_CreatePluginOracle_Call) RunAndReturn(run func(types.PluginType, types.OCR3ConfigWithMeta) (types.CCIPOracle, error)) *OracleCreator_CreatePluginOracle_Call { + _c.Call.Return(run) + return _c +} + +// NewOracleCreator creates a new instance of OracleCreator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewOracleCreator(t interface { + mock.TestingT + Cleanup(func()) +}) *OracleCreator { + mock := &OracleCreator{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/capabilities/ccip/types/types.go b/core/capabilities/ccip/types/types.go new file mode 100644 index 0000000000..952b8fe446 --- /dev/null +++ b/core/capabilities/ccip/types/types.go @@ -0,0 +1,46 @@ +package types + +import ( + ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" +) + +// OCR3ConfigWithMeta is a type alias in order to generate correct mocks for the OracleCreator interface. +type OCR3ConfigWithMeta ccipreaderpkg.OCR3ConfigWithMeta + +// PluginType represents the type of CCIP plugin. +// It mirrors the OCRPluginType in Internal.sol. +type PluginType uint8 + +const ( + PluginTypeCCIPCommit PluginType = 0 + PluginTypeCCIPExec PluginType = 1 +) + +func (pt PluginType) String() string { + switch pt { + case PluginTypeCCIPCommit: + return "CCIPCommit" + case PluginTypeCCIPExec: + return "CCIPExec" + default: + return "Unknown" + } +} + +// CCIPOracle represents either a CCIP commit or exec oracle or a bootstrap node. +type CCIPOracle interface { + Close() error + Start() error +} + +// OracleCreator is an interface for creating CCIP oracles. +// Whether the oracle uses a LOOPP or not is an implementation detail. +type OracleCreator interface { + // CreatePlugin creates a new oracle that will run either the commit or exec ccip plugin. + // The oracle must be returned unstarted. + CreatePluginOracle(pluginType PluginType, config OCR3ConfigWithMeta) (CCIPOracle, error) + + // CreateBootstrapOracle creates a new bootstrap node with the given OCR config. + // The oracle must be returned unstarted. + CreateBootstrapOracle(config OCR3ConfigWithMeta) (CCIPOracle, error) +} diff --git a/core/capabilities/ccip/validate/validate.go b/core/capabilities/ccip/validate/validate.go new file mode 100644 index 0000000000..04f4f4a495 --- /dev/null +++ b/core/capabilities/ccip/validate/validate.go @@ -0,0 +1,94 @@ +package validate + +import ( + "fmt" + + "github.com/google/uuid" + "github.com/pelletier/go-toml" + + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" +) + +// ValidatedCCIPSpec validates the given toml string as a CCIP spec. +func ValidatedCCIPSpec(tomlString string) (jb job.Job, err error) { + var spec job.CCIPSpec + tree, err := toml.Load(tomlString) + if err != nil { + return job.Job{}, fmt.Errorf("toml error on load: %w", err) + } + // Note this validates all the fields which implement an UnmarshalText + err = tree.Unmarshal(&spec) + if err != nil { + return job.Job{}, fmt.Errorf("toml unmarshal error on spec: %w", err) + } + err = tree.Unmarshal(&jb) + if err != nil { + return job.Job{}, fmt.Errorf("toml unmarshal error on job: %w", err) + } + jb.CCIPSpec = &spec + + if jb.Type != job.CCIP { + return job.Job{}, fmt.Errorf("the only supported type is currently 'ccip', got %s", jb.Type) + } + if jb.CCIPSpec.CapabilityLabelledName == "" { + return job.Job{}, fmt.Errorf("capabilityLabelledName must be set") + } + if jb.CCIPSpec.CapabilityVersion == "" { + return job.Job{}, fmt.Errorf("capabilityVersion must be set") + } + if jb.CCIPSpec.P2PKeyID == "" { + return job.Job{}, fmt.Errorf("p2pKeyID must be set") + } + if len(jb.CCIPSpec.P2PV2Bootstrappers) == 0 { + return job.Job{}, fmt.Errorf("p2pV2Bootstrappers must be set") + } + + // ensure that the P2PV2Bootstrappers is in the right format. + for _, bootstrapperLocator := range jb.CCIPSpec.P2PV2Bootstrappers { + // needs to be of the form @: + _, err := ocrcommon.ParseBootstrapPeers([]string{bootstrapperLocator}) + if err != nil { + return job.Job{}, fmt.Errorf("p2p v2 bootstrapper locator %s is not in the correct format: %w", bootstrapperLocator, err) + } + } + + return jb, nil +} + +type SpecArgs struct { + P2PV2Bootstrappers []string `toml:"p2pV2Bootstrappers"` + CapabilityVersion string `toml:"capabilityVersion"` + CapabilityLabelledName string `toml:"capabilityLabelledName"` + OCRKeyBundleIDs map[string]string `toml:"ocrKeyBundleIDs"` + P2PKeyID string `toml:"p2pKeyID"` + RelayConfigs map[string]any `toml:"relayConfigs"` + PluginConfig map[string]any `toml:"pluginConfig"` +} + +// NewCCIPSpecToml creates a new CCIP spec in toml format from the given spec args. +func NewCCIPSpecToml(spec SpecArgs) (string, error) { + type fullSpec struct { + SpecArgs + Type string `toml:"type"` + SchemaVersion uint64 `toml:"schemaVersion"` + Name string `toml:"name"` + ExternalJobID string `toml:"externalJobID"` + } + extJobID, err := uuid.NewRandom() + if err != nil { + return "", fmt.Errorf("failed to generate external job id: %w", err) + } + marshaled, err := toml.Marshal(fullSpec{ + SpecArgs: spec, + Type: "ccip", + SchemaVersion: 1, + Name: fmt.Sprintf("%s-%s", "ccip", extJobID.String()), + ExternalJobID: extJobID.String(), + }) + if err != nil { + return "", fmt.Errorf("failed to marshal spec into toml: %w", err) + } + + return string(marshaled), nil +} diff --git a/core/capabilities/ccip/validate/validate_test.go b/core/capabilities/ccip/validate/validate_test.go new file mode 100644 index 0000000000..97958f4cf9 --- /dev/null +++ b/core/capabilities/ccip/validate/validate_test.go @@ -0,0 +1,58 @@ +package validate_test + +import ( + "testing" + + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" + + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/services/job" +) + +func TestNewCCIPSpecToml(t *testing.T) { + tests := []struct { + name string + specArgs validate.SpecArgs + want string + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := validate.NewCCIPSpecToml(tt.specArgs) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.want, got) + } + }) + } +} + +func TestValidatedCCIPSpec(t *testing.T) { + type args struct { + tomlString string + } + tests := []struct { + name string + args args + wantJb job.Job + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotJb, err := validate.ValidatedCCIPSpec(tt.args.tomlString) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.wantJb, gotJb) + } + }) + } +} diff --git a/core/capabilities/launcher.go b/core/capabilities/launcher.go index b30477e4c8..3fc321087b 100644 --- a/core/capabilities/launcher.go +++ b/core/capabilities/launcher.go @@ -7,13 +7,17 @@ import ( "strings" "time" + "google.golang.org/protobuf/proto" + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/triggers" "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/values" "github.com/smartcontractkit/libocr/ragep2p" ragetypes "github.com/smartcontractkit/libocr/ragep2p/types" + capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/target" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" @@ -46,6 +50,42 @@ type launcher struct { subServices []services.Service } +func unmarshalCapabilityConfig(data []byte) (capabilities.CapabilityConfiguration, error) { + cconf := &capabilitiespb.CapabilityConfig{} + err := proto.Unmarshal(data, cconf) + if err != nil { + return capabilities.CapabilityConfiguration{}, err + } + + var remoteTriggerConfig *capabilities.RemoteTriggerConfig + var remoteTargetConfig *capabilities.RemoteTargetConfig + + switch cconf.GetRemoteConfig().(type) { + case *capabilitiespb.CapabilityConfig_RemoteTriggerConfig: + prtc := cconf.GetRemoteTriggerConfig() + remoteTriggerConfig = &capabilities.RemoteTriggerConfig{} + remoteTriggerConfig.RegistrationRefresh = prtc.RegistrationRefresh.AsDuration() + remoteTriggerConfig.RegistrationExpiry = prtc.RegistrationExpiry.AsDuration() + remoteTriggerConfig.MinResponsesToAggregate = prtc.MinResponsesToAggregate + remoteTriggerConfig.MessageExpiry = prtc.MessageExpiry.AsDuration() + case *capabilitiespb.CapabilityConfig_RemoteTargetConfig: + prtc := cconf.GetRemoteTargetConfig() + remoteTargetConfig = &capabilities.RemoteTargetConfig{} + remoteTargetConfig.RequestHashExcludedAttributes = prtc.RequestHashExcludedAttributes + } + + dc, err := values.FromMapValueProto(cconf.DefaultConfig) + if err != nil { + return capabilities.CapabilityConfiguration{}, err + } + + return capabilities.CapabilityConfiguration{ + DefaultConfig: dc, + RemoteTriggerConfig: remoteTriggerConfig, + RemoteTargetConfig: remoteTargetConfig, + }, nil +} + func NewLauncher( lggr logger.Logger, peerWrapper p2ptypes.PeerWrapper, @@ -196,6 +236,11 @@ func (w *launcher) addRemoteCapabilities(ctx context.Context, myDON registrysync return fmt.Errorf("could not find capability matching id %s", cid) } + capabilityConfig, err := unmarshalCapabilityConfig(c.Config) + if err != nil { + return fmt.Errorf("could not unmarshal capability config for id %s", cid) + } + switch capability.CapabilityType { case capabilities.CapabilityTypeTrigger: newTriggerFn := func(info capabilities.CapabilityInfo) (capabilityService, error) { @@ -224,7 +269,7 @@ func (w *launcher) addRemoteCapabilities(ctx context.Context, myDON registrysync // When this is solved, we can move to a generic aggregator // and remove this. triggerCap := remote.NewTriggerSubscriber( - c.RemoteTriggerConfig, + capabilityConfig.RemoteTriggerConfig, info, remoteDON.DON, myDON.DON, @@ -333,11 +378,16 @@ func (w *launcher) exposeCapabilities(ctx context.Context, myPeerID p2ptypes.Pee return fmt.Errorf("could not find capability matching id %s", cid) } + capabilityConfig, err := unmarshalCapabilityConfig(c.Config) + if err != nil { + return fmt.Errorf("could not unmarshal capability config for id %s", cid) + } + switch capability.CapabilityType { case capabilities.CapabilityTypeTrigger: newTriggerPublisher := func(capability capabilities.BaseCapability, info capabilities.CapabilityInfo) (receiverService, error) { publisher := remote.NewTriggerPublisher( - c.RemoteTriggerConfig, + capabilityConfig.RemoteTriggerConfig, capability.(capabilities.TriggerCapability), info, don.DON, @@ -359,7 +409,7 @@ func (w *launcher) exposeCapabilities(ctx context.Context, myPeerID p2ptypes.Pee case capabilities.CapabilityTypeTarget: newTargetServer := func(capability capabilities.BaseCapability, info capabilities.CapabilityInfo) (receiverService, error) { return target.NewServer( - c.RemoteTargetConfig, + capabilityConfig.RemoteTargetConfig, myPeerID, capability.(capabilities.TargetCapability), info, diff --git a/core/capabilities/launcher_test.go b/core/capabilities/launcher_test.go index 82b03edcec..8bca3be0db 100644 --- a/core/capabilities/launcher_test.go +++ b/core/capabilities/launcher_test.go @@ -4,14 +4,18 @@ import ( "context" "crypto/rand" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/durationpb" ragetypes "github.com/smartcontractkit/libocr/ragep2p/types" "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" remoteMocks "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types/mocks" @@ -121,7 +125,7 @@ func TestLauncher_WiresUpExternalCapabilities(t *testing.T) { AcceptsWorkflows: true, Members: nodes, }, - CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{ + CapabilityConfigurations: map[string]registrysyncer.CapabilityConfiguration{ fullTriggerCapID: {}, fullTargetID: {}, }, @@ -223,7 +227,7 @@ func TestSyncer_IgnoresCapabilitiesForPrivateDON(t *testing.T) { AcceptsWorkflows: true, Members: nodes, }, - CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{ + CapabilityConfigurations: map[string]registrysyncer.CapabilityConfiguration{ triggerID: {}, targetID: {}, }, @@ -326,6 +330,15 @@ func TestLauncher_WiresUpClientsForPublicWorkflowDON(t *testing.T) { rtc := &capabilities.RemoteTriggerConfig{} rtc.ApplyDefaults() + cfg, err := proto.Marshal(&capabilitiespb.CapabilityConfig{ + RemoteConfig: &capabilitiespb.CapabilityConfig_RemoteTriggerConfig{ + RemoteTriggerConfig: &capabilitiespb.RemoteTriggerConfig{ + RegistrationRefresh: durationpb.New(1 * time.Second), + }, + }, + }) + require.NoError(t, err) + state := ®istrysyncer.LocalRegistry{ IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{ registrysyncer.DonID(dID): { @@ -347,12 +360,12 @@ func TestLauncher_WiresUpClientsForPublicWorkflowDON(t *testing.T) { AcceptsWorkflows: false, Members: capabilityDonNodes, }, - CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{ + CapabilityConfigurations: map[string]registrysyncer.CapabilityConfiguration{ fullTriggerCapID: { - RemoteTriggerConfig: rtc, + Config: cfg, }, fullTargetID: { - RemoteTriggerConfig: rtc, + Config: cfg, }, }, }, @@ -496,7 +509,7 @@ func TestLauncher_WiresUpClientsForPublicWorkflowDONButIgnoresPrivateCapabilitie AcceptsWorkflows: false, Members: capabilityDonNodes, }, - CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{ + CapabilityConfigurations: map[string]registrysyncer.CapabilityConfiguration{ fullTriggerCapID: {}, }, }, @@ -509,7 +522,7 @@ func TestLauncher_WiresUpClientsForPublicWorkflowDONButIgnoresPrivateCapabilitie AcceptsWorkflows: false, Members: capabilityDonNodes, }, - CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{ + CapabilityConfigurations: map[string]registrysyncer.CapabilityConfiguration{ fullTargetID: {}, }, }, @@ -653,7 +666,7 @@ func TestLauncher_SucceedsEvenIfDispatcherAlreadyHasReceiver(t *testing.T) { AcceptsWorkflows: false, Members: capabilityDonNodes, }, - CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{ + CapabilityConfigurations: map[string]registrysyncer.CapabilityConfiguration{ fullTriggerCapID: {}, }, }, diff --git a/core/capabilities/registry.go b/core/capabilities/registry.go index d6891c81ab..4da51a27b6 100644 --- a/core/capabilities/registry.go +++ b/core/capabilities/registry.go @@ -8,6 +8,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" ) var ( @@ -16,7 +17,7 @@ var ( type metadataRegistry interface { LocalNode(ctx context.Context) (capabilities.Node, error) - ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error) + ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (registrysyncer.CapabilityConfiguration, error) } // Registry is a struct for the registry of capabilities. @@ -43,7 +44,12 @@ func (r *Registry) ConfigForCapability(ctx context.Context, capabilityID string, return capabilities.CapabilityConfiguration{}, errors.New("metadataRegistry information not available") } - return r.metadataRegistry.ConfigForCapability(ctx, capabilityID, donID) + cfc, err := r.metadataRegistry.ConfigForCapability(ctx, capabilityID, donID) + if err != nil { + return capabilities.CapabilityConfiguration{}, err + } + + return unmarshalCapabilityConfig(cfc.Config) } // SetLocalRegistry sets a local copy of the offchain registry for the registry to use. diff --git a/core/chains/evm/client/simulated_backend_client.go b/core/chains/evm/client/simulated_backend_client.go index 6bcc1f3696..7dfd39f444 100644 --- a/core/chains/evm/client/simulated_backend_client.go +++ b/core/chains/evm/client/simulated_backend_client.go @@ -360,9 +360,18 @@ func (c *SimulatedBackendClient) SendTransactionReturnCode(ctx context.Context, // SendTransaction sends a transaction. func (c *SimulatedBackendClient) SendTransaction(ctx context.Context, tx *types.Transaction) error { - sender, err := types.Sender(types.NewLondonSigner(c.chainId), tx) + var ( + sender common.Address + err error + ) + // try to recover the sender from the transaction using the configured chain id + // first. if that fails, try again with the simulated chain id (1337) + sender, err = types.Sender(types.NewLondonSigner(c.chainId), tx) if err != nil { - logger.Test(c.t).Panic(fmt.Errorf("invalid transaction: %v (tx: %#v)", err, tx)) + sender, err = types.Sender(types.NewLondonSigner(big.NewInt(1337)), tx) + if err != nil { + logger.Test(c.t).Panic(fmt.Errorf("invalid transaction: %v (tx: %#v)", err, tx)) + } } pendingNonce, err := c.b.PendingNonceAt(ctx, sender) if err != nil { diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 94504897ab..cd13612743 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -102,7 +102,7 @@ require ( github.com/danieljoos/wincred v1.1.2 // indirect github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/deckarep/golang-set/v2 v2.3.0 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect @@ -270,6 +270,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect @@ -330,7 +331,7 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.19.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index f770498cff..d8ca90e8b4 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -330,8 +330,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= -github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= @@ -1184,6 +1184,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c h1:3apUsez/6Pkp1ckXzSwIhzPRuWjDGjzMjKapEKi0Fcw= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= @@ -1484,8 +1486,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7 h1:wDLEX9a7YQoKdKNQt88rtydkqDxeGaBUTnIYc3iG/mA= -golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index c23ec08a69..6a381b1ffa 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -23,15 +23,14 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-common/pkg/utils/jsonserializable" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - "github.com/smartcontractkit/chainlink/v2/core/capabilities" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/services/standardcapabilities" - "github.com/smartcontractkit/chainlink/v2/core/static" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/build" + "github.com/smartcontractkit/chainlink/v2/core/capabilities" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" evmutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" @@ -61,6 +60,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" + "github.com/smartcontractkit/chainlink/v2/core/services/standardcapabilities" "github.com/smartcontractkit/chainlink/v2/core/services/streams" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" "github.com/smartcontractkit/chainlink/v2/core/services/vrf" @@ -70,6 +70,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/sessions" "github.com/smartcontractkit/chainlink/v2/core/sessions/ldapauth" "github.com/smartcontractkit/chainlink/v2/core/sessions/localauth" + "github.com/smartcontractkit/chainlink/v2/core/static" "github.com/smartcontractkit/chainlink/v2/plugins" ) @@ -212,41 +213,51 @@ func NewApplication(opts ApplicationOpts) (Application, error) { externalPeer := externalp2p.NewExternalPeerWrapper(keyStore.P2P(), cfg.Capabilities().Peering(), opts.DS, globalLogger) signer := externalPeer externalPeerWrapper = externalPeer - dispatcher = remote.NewDispatcher(externalPeerWrapper, signer, opts.CapabilitiesRegistry, globalLogger) - srvcs = append(srvcs, externalPeerWrapper) // peer wrapper must be started before dispatcher - srvcs = append(srvcs, dispatcher) - } else { // tests only + remoteDispatcher := remote.NewDispatcher(externalPeerWrapper, signer, opts.CapabilitiesRegistry, globalLogger) + srvcs = append(srvcs, remoteDispatcher) + + dispatcher = remoteDispatcher + } else { dispatcher = opts.CapabilitiesDispatcher externalPeerWrapper = opts.CapabilitiesPeerWrapper - srvcs = append(srvcs, externalPeerWrapper) } - rid := cfg.Capabilities().ExternalRegistry().RelayID() - registryAddress := cfg.Capabilities().ExternalRegistry().Address() - relayer, err := relayerChainInterops.Get(rid) - if err != nil { - return nil, fmt.Errorf("could not fetch relayer %s configured for capabilities registry: %w", rid, err) - } + srvcs = append(srvcs, externalPeerWrapper, dispatcher) - registrySyncer, err := registrysyncer.New( - globalLogger, - externalPeerWrapper, - relayer, - registryAddress, - ) - if err != nil { - return nil, fmt.Errorf("could not configure syncer: %w", err) - } + if cfg.Capabilities().ExternalRegistry().Address() != "" { + rid := cfg.Capabilities().ExternalRegistry().RelayID() + registryAddress := cfg.Capabilities().ExternalRegistry().Address() + relayer, err := relayerChainInterops.Get(rid) + if err != nil { + return nil, fmt.Errorf("could not fetch relayer %s configured for capabilities registry: %w", rid, err) + } + registrySyncer, err := registrysyncer.New( + globalLogger, + func() (p2ptypes.PeerID, error) { + p := externalPeerWrapper.GetPeer() + if p == nil { + return p2ptypes.PeerID{}, errors.New("could not get peer") + } - wfLauncher := capabilities.NewLauncher( - globalLogger, - externalPeerWrapper, - dispatcher, - opts.CapabilitiesRegistry, - ) - registrySyncer.AddLauncher(wfLauncher) + return p.ID(), nil + }, + relayer, + registryAddress, + ) + if err != nil { + return nil, fmt.Errorf("could not configure syncer: %w", err) + } + + wfLauncher := capabilities.NewLauncher( + globalLogger, + externalPeerWrapper, + dispatcher, + opts.CapabilitiesRegistry, + ) + registrySyncer.AddLauncher(wfLauncher) - srvcs = append(srvcs, dispatcher, wfLauncher, registrySyncer) + srvcs = append(srvcs, wfLauncher, registrySyncer) + } } // LOOPs can be created as options, in the case of LOOP relayers, or @@ -512,6 +523,18 @@ func NewApplication(opts ApplicationOpts) (Application, error) { cfg.Insecure(), opts.RelayerChainInteroperators, ) + delegates[job.CCIP] = ccip.NewDelegate( + globalLogger, + loopRegistrarConfig, + pipelineRunner, + opts.RelayerChainInteroperators.LegacyEVMChains(), + relayerChainInterops, + opts.KeyStore, + opts.DS, + peerWrapper, + telemetryManager, + cfg.Capabilities(), + ) } else { globalLogger.Debug("Off-chain reporting v2 disabled") } diff --git a/core/services/job/models.go b/core/services/job/models.go index 2f864efe30..1c46d08c59 100644 --- a/core/services/job/models.go +++ b/core/services/job/models.go @@ -38,6 +38,7 @@ const ( BlockhashStore Type = (Type)(pipeline.BlockhashStoreJobType) Bootstrap Type = (Type)(pipeline.BootstrapJobType) Cron Type = (Type)(pipeline.CronJobType) + CCIP Type = (Type)(pipeline.CCIPJobType) DirectRequest Type = (Type)(pipeline.DirectRequestJobType) FluxMonitor Type = (Type)(pipeline.FluxMonitorJobType) Gateway Type = (Type)(pipeline.GatewayJobType) @@ -78,6 +79,7 @@ var ( BlockhashStore: false, Bootstrap: false, Cron: true, + CCIP: false, DirectRequest: true, FluxMonitor: true, Gateway: false, @@ -97,6 +99,7 @@ var ( BlockhashStore: false, Bootstrap: false, Cron: true, + CCIP: false, DirectRequest: true, FluxMonitor: false, Gateway: false, @@ -116,6 +119,7 @@ var ( BlockhashStore: 1, Bootstrap: 1, Cron: 1, + CCIP: 1, DirectRequest: 1, FluxMonitor: 1, Gateway: 1, @@ -176,6 +180,7 @@ type Job struct { StandardCapabilitiesSpecID *int32 StandardCapabilitiesSpec *StandardCapabilitiesSpec CCIPSpecID *int32 + CCIPSpec *CCIPSpec CCIPBootstrapSpecID *int32 JobSpecErrors []SpecError Type Type `toml:"type"` @@ -910,3 +915,48 @@ func (w *StandardCapabilitiesSpec) SetID(value string) error { w.ID = int32(ID) return nil } + +type CCIPSpec struct { + ID int32 + CreatedAt time.Time `toml:"-"` + UpdatedAt time.Time `toml:"-"` + + // P2PV2Bootstrappers is a list of "peer_id@ip_address:port" strings that are used to + // identify the bootstrap nodes of the P2P network. + // These bootstrappers will be used to bootstrap all CCIP DONs. + P2PV2Bootstrappers pq.StringArray `toml:"p2pV2Bootstrappers" db:"p2pv2_bootstrappers"` + + // CapabilityVersion is the semantic version of the CCIP capability. + // This capability version must exist in the onchain capability registry. + CapabilityVersion string `toml:"capabilityVersion" db:"capability_version"` + + // CapabilityLabelledName is the labelled name of the CCIP capability. + // Corresponds to the labelled name of the capability in the onchain capability registry. + CapabilityLabelledName string `toml:"capabilityLabelledName" db:"capability_labelled_name"` + + // OCRKeyBundleIDs is a mapping from chain type to OCR key bundle ID. + // These are explicitly specified here so that we don't run into strange errors auto-detecting + // the valid bundle, since nops can create as many bundles as they want. + // This will most likely never change for a particular CCIP capability version, + // since new chain families will likely require a new capability version. + // {"evm": "evm_key_bundle_id", "solana": "solana_key_bundle_id", ... } + OCRKeyBundleIDs JSONConfig `toml:"ocrKeyBundleIDs" db:"ocr_key_bundle_ids"` + + // RelayConfigs consists of relay specific configuration. + // Chain reader configurations are stored here, and are defined on a chain family basis, e.g + // we will have one chain reader config for EVM, one for solana, starknet, etc. + // Chain writer configurations are also stored here, and are also defined on a chain family basis, + // e.g we will have one chain writer config for EVM, one for solana, starknet, etc. + // See tests for examples of relay configs in TOML. + // { "evm": {"chainReader": {...}, "chainWriter": {...}}, "solana": {...}, ... } + // see core/services/relay/evm/types/types.go for EVM configs. + RelayConfigs JSONConfig `toml:"relayConfigs" db:"relay_configs"` + + // P2PKeyID is the ID of the P2P key of the node. + // This must be present in the capability registry otherwise the job will not start correctly. + P2PKeyID string `toml:"p2pKeyID" db:"p2p_key_id"` + + // PluginConfig contains plugin-specific config, like token price pipelines + // and RMN network info for offchain blessing. + PluginConfig JSONConfig `toml:"pluginConfig"` +} diff --git a/core/services/job/orm.go b/core/services/job/orm.go index d13decc720..ac3bb65530 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -425,7 +425,34 @@ func (o *orm) CreateJob(ctx context.Context, jb *Job) error { return errors.Wrap(err, "failed to create StandardCapabilities for jobSpec") } jb.StandardCapabilitiesSpecID = &specID - + case CCIP: + sql := `INSERT INTO ccip_specs ( + capability_version, + capability_labelled_name, + ocr_key_bundle_ids, + p2p_key_id, + p2pv2_bootstrappers, + relay_configs, + plugin_config, + created_at, + updated_at + ) VALUES ( + :capability_version, + :capability_labelled_name, + :ocr_key_bundle_ids, + :p2p_key_id, + :p2pv2_bootstrappers, + :relay_configs, + :plugin_config, + NOW(), + NOW() + ) + RETURNING id;` + specID, err := tx.prepareQuerySpecID(ctx, sql, jb.CCIPSpec) + if err != nil { + return errors.Wrap(err, "failed to create CCIPSpec for jobSpec") + } + jb.CCIPSpecID = &specID default: o.lggr.Panicf("Unsupported jb.Type: %v", jb.Type) } @@ -643,19 +670,19 @@ func (o *orm) InsertJob(ctx context.Context, job *Job) error { // if job has id, emplace otherwise insert with a new id. if job.ID == 0 { query = `INSERT INTO jobs (name, stream_id, schema_version, type, max_task_duration, ocr_oracle_spec_id, ocr2_oracle_spec_id, direct_request_spec_id, flux_monitor_spec_id, - keeper_spec_id, cron_spec_id, vrf_spec_id, webhook_spec_id, blockhash_store_spec_id, bootstrap_spec_id, block_header_feeder_spec_id, gateway_spec_id, - legacy_gas_station_server_spec_id, legacy_gas_station_sidecar_spec_id, workflow_spec_id, standard_capabilities_spec_id, external_job_id, gas_limit, forwarding_allowed, created_at) + keeper_spec_id, cron_spec_id, vrf_spec_id, webhook_spec_id, blockhash_store_spec_id, bootstrap_spec_id, block_header_feeder_spec_id, gateway_spec_id, + legacy_gas_station_server_spec_id, legacy_gas_station_sidecar_spec_id, workflow_spec_id, standard_capabilities_spec_id, ccip_spec_id, external_job_id, gas_limit, forwarding_allowed, created_at) VALUES (:name, :stream_id, :schema_version, :type, :max_task_duration, :ocr_oracle_spec_id, :ocr2_oracle_spec_id, :direct_request_spec_id, :flux_monitor_spec_id, - :keeper_spec_id, :cron_spec_id, :vrf_spec_id, :webhook_spec_id, :blockhash_store_spec_id, :bootstrap_spec_id, :block_header_feeder_spec_id, :gateway_spec_id, - :legacy_gas_station_server_spec_id, :legacy_gas_station_sidecar_spec_id, :workflow_spec_id, :standard_capabilities_spec_id, :external_job_id, :gas_limit, :forwarding_allowed, NOW()) + :keeper_spec_id, :cron_spec_id, :vrf_spec_id, :webhook_spec_id, :blockhash_store_spec_id, :bootstrap_spec_id, :block_header_feeder_spec_id, :gateway_spec_id, + :legacy_gas_station_server_spec_id, :legacy_gas_station_sidecar_spec_id, :workflow_spec_id, :standard_capabilities_spec_id, :ccip_spec_id, :external_job_id, :gas_limit, :forwarding_allowed, NOW()) RETURNING *;` } else { query = `INSERT INTO jobs (id, name, stream_id, schema_version, type, max_task_duration, ocr_oracle_spec_id, ocr2_oracle_spec_id, direct_request_spec_id, flux_monitor_spec_id, - keeper_spec_id, cron_spec_id, vrf_spec_id, webhook_spec_id, blockhash_store_spec_id, bootstrap_spec_id, block_header_feeder_spec_id, gateway_spec_id, - legacy_gas_station_server_spec_id, legacy_gas_station_sidecar_spec_id, workflow_spec_id, standard_capabilities_spec_id, external_job_id, gas_limit, forwarding_allowed, created_at) + keeper_spec_id, cron_spec_id, vrf_spec_id, webhook_spec_id, blockhash_store_spec_id, bootstrap_spec_id, block_header_feeder_spec_id, gateway_spec_id, + legacy_gas_station_server_spec_id, legacy_gas_station_sidecar_spec_id, workflow_spec_id, standard_capabilities_spec_id, ccip_spec_id, external_job_id, gas_limit, forwarding_allowed, created_at) VALUES (:id, :name, :stream_id, :schema_version, :type, :max_task_duration, :ocr_oracle_spec_id, :ocr2_oracle_spec_id, :direct_request_spec_id, :flux_monitor_spec_id, - :keeper_spec_id, :cron_spec_id, :vrf_spec_id, :webhook_spec_id, :blockhash_store_spec_id, :bootstrap_spec_id, :block_header_feeder_spec_id, :gateway_spec_id, - :legacy_gas_station_server_spec_id, :legacy_gas_station_sidecar_spec_id, :workflow_spec_id, :standard_capabilities_spec_id, :external_job_id, :gas_limit, :forwarding_allowed, NOW()) + :keeper_spec_id, :cron_spec_id, :vrf_spec_id, :webhook_spec_id, :blockhash_store_spec_id, :bootstrap_spec_id, :block_header_feeder_spec_id, :gateway_spec_id, + :legacy_gas_station_server_spec_id, :legacy_gas_station_sidecar_spec_id, :workflow_spec_id, :standard_capabilities_spec_id, :ccip_spec_id, :external_job_id, :gas_limit, :forwarding_allowed, NOW()) RETURNING *;` } query, args, err := tx.ds.BindNamed(query, job) @@ -699,7 +726,8 @@ func (o *orm) DeleteJob(ctx context.Context, id int32) error { block_header_feeder_spec_id, gateway_spec_id, workflow_spec_id, - standard_capabilities_spec_id + standard_capabilities_spec_id, + ccip_spec_id ), deleted_oracle_specs AS ( DELETE FROM ocr_oracle_specs WHERE id IN (SELECT ocr_oracle_spec_id FROM deleted_jobs) @@ -742,7 +770,10 @@ func (o *orm) DeleteJob(ctx context.Context, id int32) error { ), deleted_standardcapabilities_specs AS ( DELETE FROM standardcapabilities_specs WHERE id in (SELECT standard_capabilities_spec_id FROM deleted_jobs) - ), + ), + deleted_ccip_specs AS ( + DELETE FROM ccip_specs WHERE id in (SELECT ccip_spec_id FROM deleted_jobs) + ), deleted_job_pipeline_specs AS ( DELETE FROM job_pipeline_specs WHERE job_id IN (SELECT id FROM deleted_jobs) RETURNING pipeline_spec_id ) @@ -816,7 +847,7 @@ func (o *orm) FindJobs(ctx context.Context, offset, limit int) (jobs []Job, coun return fmt.Errorf("failed to query jobs count: %w", err) } - sql = `SELECT jobs.*, job_pipeline_specs.pipeline_spec_id as pipeline_spec_id + sql = `SELECT jobs.*, job_pipeline_specs.pipeline_spec_id as pipeline_spec_id FROM jobs JOIN job_pipeline_specs ON (jobs.id = job_pipeline_specs.job_id) ORDER BY jobs.created_at DESC, jobs.id DESC OFFSET $1 LIMIT $2;` @@ -1030,8 +1061,8 @@ func (o *orm) findJob(ctx context.Context, jb *Job, col string, arg interface{}) } func (o *orm) FindJobIDsWithBridge(ctx context.Context, name string) (jids []int32, err error) { - query := `SELECT - jobs.id, pipeline_specs.dot_dag_source + query := `SELECT + jobs.id, pipeline_specs.dot_dag_source FROM jobs JOIN job_pipeline_specs ON job_pipeline_specs.job_id = jobs.id JOIN pipeline_specs ON pipeline_specs.id = job_pipeline_specs.pipeline_spec_id @@ -1078,7 +1109,7 @@ func (o *orm) FindJobIDsWithBridge(ctx context.Context, name string) (jids []int func (o *orm) FindJobIDByWorkflow(ctx context.Context, spec WorkflowSpec) (jobID int32, err error) { stmt := ` SELECT jobs.id FROM jobs -INNER JOIN workflow_specs ws on jobs.workflow_spec_id = ws.id AND ws.workflow_owner = $1 AND ws.workflow_name = $2 +INNER JOIN workflow_specs ws on jobs.workflow_spec_id = ws.id AND ws.workflow_owner = $1 AND ws.workflow_name = $2 ` err = o.ds.GetContext(ctx, &jobID, stmt, spec.WorkflowOwner, spec.WorkflowName) if err != nil { @@ -1391,6 +1422,7 @@ func (o *orm) loadAllJobTypes(ctx context.Context, job *Job) error { o.loadJobType(ctx, job, "GatewaySpec", "gateway_specs", job.GatewaySpecID), o.loadJobType(ctx, job, "WorkflowSpec", "workflow_specs", job.WorkflowSpecID), o.loadJobType(ctx, job, "StandardCapabilitiesSpec", "standardcapabilities_specs", job.StandardCapabilitiesSpecID), + o.loadJobType(ctx, job, "CCIPSpec", "ccip_specs", job.CCIPSpecID), ) } @@ -1428,7 +1460,7 @@ func (o *orm) loadJobPipelineSpec(ctx context.Context, job *Job, id *int32) erro ctx, pipelineSpecRow, `SELECT pipeline_specs.*, job_pipeline_specs.job_id as job_id - FROM pipeline_specs + FROM pipeline_specs JOIN job_pipeline_specs ON(pipeline_specs.id = job_pipeline_specs.pipeline_spec_id) WHERE job_pipeline_specs.job_id = $1 AND job_pipeline_specs.pipeline_spec_id = $2`, job.ID, *id, diff --git a/core/services/pipeline/common.go b/core/services/pipeline/common.go index 763e50546f..1b36c8a664 100644 --- a/core/services/pipeline/common.go +++ b/core/services/pipeline/common.go @@ -29,6 +29,7 @@ const ( BlockhashStoreJobType string = "blockhashstore" BootstrapJobType string = "bootstrap" CronJobType string = "cron" + CCIPJobType string = "ccip" DirectRequestJobType string = "directrequest" FluxMonitorJobType string = "fluxmonitor" GatewayJobType string = "gateway" diff --git a/core/services/registrysyncer/local_registry.go b/core/services/registrysyncer/local_registry.go index 4e4a632bf8..8a0e471ccd 100644 --- a/core/services/registrysyncer/local_registry.go +++ b/core/services/registrysyncer/local_registry.go @@ -16,7 +16,11 @@ type DonID uint32 type DON struct { capabilities.DON - CapabilityConfigurations map[string]capabilities.CapabilityConfiguration + CapabilityConfigurations map[string]CapabilityConfiguration +} + +type CapabilityConfiguration struct { + Config []byte } type Capability struct { @@ -26,7 +30,7 @@ type Capability struct { type LocalRegistry struct { lggr logger.Logger - peerWrapper p2ptypes.PeerWrapper + getPeerID func() (p2ptypes.PeerID, error) IDsToDONs map[DonID]DON IDsToNodes map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo IDsToCapabilities map[string]Capability @@ -36,12 +40,11 @@ func (l *LocalRegistry) LocalNode(ctx context.Context) (capabilities.Node, error // Load the current nodes PeerWrapper, this gets us the current node's // PeerID, allowing us to contextualize registry information in terms of DON ownership // (eg. get my current DON configuration, etc). - if l.peerWrapper.GetPeer() == nil { + pid, err := l.getPeerID() + if err != nil { return capabilities.Node{}, errors.New("unable to get local node: peerWrapper hasn't started yet") } - pid := l.peerWrapper.GetPeer().ID() - var workflowDON capabilities.DON capabilityDONs := []capabilities.DON{} for _, d := range l.IDsToDONs { @@ -70,15 +73,15 @@ func (l *LocalRegistry) LocalNode(ctx context.Context) (capabilities.Node, error }, nil } -func (l *LocalRegistry) ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error) { +func (l *LocalRegistry) ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (CapabilityConfiguration, error) { d, ok := l.IDsToDONs[DonID(donID)] if !ok { - return capabilities.CapabilityConfiguration{}, fmt.Errorf("could not find don %d", donID) + return CapabilityConfiguration{}, fmt.Errorf("could not find don %d", donID) } cc, ok := d.CapabilityConfigurations[capabilityID] if !ok { - return capabilities.CapabilityConfiguration{}, fmt.Errorf("could not find capability configuration for capability %s and donID %d", capabilityID, donID) + return CapabilityConfiguration{}, fmt.Errorf("could not find capability configuration for capability %s and donID %d", capabilityID, donID) } return cc, nil diff --git a/core/services/registrysyncer/syncer.go b/core/services/registrysyncer/syncer.go index 9675d86dc8..83f77e46d3 100644 --- a/core/services/registrysyncer/syncer.go +++ b/core/services/registrysyncer/syncer.go @@ -7,14 +7,10 @@ import ( "sync" "time" - "google.golang.org/protobuf/proto" - "github.com/smartcontractkit/chainlink-common/pkg/capabilities" - capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" - "github.com/smartcontractkit/chainlink-common/pkg/values" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -39,7 +35,7 @@ type registrySyncer struct { initReader func(ctx context.Context, lggr logger.Logger, relayer contractReaderFactory, registryAddress string) (types.ContractReader, error) relayer contractReaderFactory registryAddress string - peerWrapper p2ptypes.PeerWrapper + getPeerID func() (p2ptypes.PeerID, error) wg sync.WaitGroup lggr logger.Logger @@ -55,7 +51,7 @@ var ( // New instantiates a new RegistrySyncer func New( lggr logger.Logger, - peerWrapper p2ptypes.PeerWrapper, + getPeerID func() (p2ptypes.PeerID, error), relayer contractReaderFactory, registryAddress string, ) (*registrySyncer, error) { @@ -66,7 +62,7 @@ func New( relayer: relayer, registryAddress: registryAddress, initReader: newReader, - peerWrapper: peerWrapper, + getPeerID: getPeerID, }, nil } @@ -158,42 +154,6 @@ func (s *registrySyncer) syncLoop() { } } -func unmarshalCapabilityConfig(data []byte) (capabilities.CapabilityConfiguration, error) { - cconf := &capabilitiespb.CapabilityConfig{} - err := proto.Unmarshal(data, cconf) - if err != nil { - return capabilities.CapabilityConfiguration{}, err - } - - var remoteTriggerConfig *capabilities.RemoteTriggerConfig - var remoteTargetConfig *capabilities.RemoteTargetConfig - - switch cconf.GetRemoteConfig().(type) { - case *capabilitiespb.CapabilityConfig_RemoteTriggerConfig: - prtc := cconf.GetRemoteTriggerConfig() - remoteTriggerConfig = &capabilities.RemoteTriggerConfig{} - remoteTriggerConfig.RegistrationRefresh = prtc.RegistrationRefresh.AsDuration() - remoteTriggerConfig.RegistrationExpiry = prtc.RegistrationExpiry.AsDuration() - remoteTriggerConfig.MinResponsesToAggregate = prtc.MinResponsesToAggregate - remoteTriggerConfig.MessageExpiry = prtc.MessageExpiry.AsDuration() - case *capabilitiespb.CapabilityConfig_RemoteTargetConfig: - prtc := cconf.GetRemoteTargetConfig() - remoteTargetConfig = &capabilities.RemoteTargetConfig{} - remoteTargetConfig.RequestHashExcludedAttributes = prtc.RequestHashExcludedAttributes - } - - dc, err := values.FromMapValueProto(cconf.DefaultConfig) - if err != nil { - return capabilities.CapabilityConfiguration{}, err - } - - return capabilities.CapabilityConfiguration{ - DefaultConfig: dc, - RemoteTriggerConfig: remoteTriggerConfig, - RemoteTargetConfig: remoteTargetConfig, - }, nil -} - func (s *registrySyncer) localRegistry(ctx context.Context) (*LocalRegistry, error) { caps := []kcr.CapabilitiesRegistryCapabilityInfo{} err := s.reader.GetLatestValue(ctx, "CapabilitiesRegistry", "getCapabilities", primitives.Unconfirmed, nil, &caps) @@ -221,19 +181,16 @@ func (s *registrySyncer) localRegistry(ctx context.Context) (*LocalRegistry, err idsToDONs := map[DonID]DON{} for _, d := range dons { - cc := map[string]capabilities.CapabilityConfiguration{} + cc := map[string]CapabilityConfiguration{} for _, dc := range d.CapabilityConfigurations { cid, ok := hashedIDsToCapabilityIDs[dc.CapabilityId] if !ok { return nil, fmt.Errorf("invariant violation: could not find full ID for hashed ID %s", dc.CapabilityId) } - cconf, innerErr := unmarshalCapabilityConfig(dc.Config) - if innerErr != nil { - return nil, innerErr + cc[cid] = CapabilityConfiguration{ + Config: dc.Config, } - - cc[cid] = cconf } idsToDONs[DonID(d.Id)] = DON{ @@ -255,7 +212,7 @@ func (s *registrySyncer) localRegistry(ctx context.Context) (*LocalRegistry, err return &LocalRegistry{ lggr: s.lggr, - peerWrapper: s.peerWrapper, + getPeerID: s.getPeerID, IDsToDONs: idsToDONs, IDsToCapabilities: idsToCapabilities, IDsToNodes: idsToNodes, diff --git a/core/services/registrysyncer/syncer_test.go b/core/services/registrysyncer/syncer_test.go index c13cc90490..cd8776d882 100644 --- a/core/services/registrysyncer/syncer_test.go +++ b/core/services/registrysyncer/syncer_test.go @@ -33,7 +33,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" - "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -237,9 +236,8 @@ func TestReader_Integration(t *testing.T) { require.NoError(t, err) - wrapper := mocks.NewPeerWrapper(t) factory := newContractReaderFactory(t, sim) - syncer, err := New(logger.TestLogger(t), wrapper, factory, regAddress.Hex()) + syncer, err := New(logger.TestLogger(t), func() (p2ptypes.PeerID, error) { return p2ptypes.PeerID{}, nil }, factory, regAddress.Hex()) require.NoError(t, err) l := &launcher{} @@ -257,29 +255,17 @@ func TestReader_Integration(t *testing.T) { }, gotCap) assert.Len(t, s.IDsToDONs, 1) - rtc := &capabilities.RemoteTriggerConfig{ - RegistrationRefresh: 20 * time.Second, - MinResponsesToAggregate: 2, - RegistrationExpiry: 60 * time.Second, - MessageExpiry: 120 * time.Second, - } - expectedDON := DON{ - DON: capabilities.DON{ - ID: 1, - ConfigVersion: 1, - IsPublic: true, - AcceptsWorkflows: true, - F: 1, - Members: toPeerIDs(nodeSet), - }, - CapabilityConfigurations: map[string]capabilities.CapabilityConfiguration{ - cid: { - DefaultConfig: values.EmptyMap(), - RemoteTriggerConfig: rtc, - }, - }, + expectedDON := capabilities.DON{ + ID: 1, + ConfigVersion: 1, + IsPublic: true, + AcceptsWorkflows: true, + F: 1, + Members: toPeerIDs(nodeSet), } - assert.Equal(t, expectedDON, s.IDsToDONs[1]) + gotDon := s.IDsToDONs[1] + assert.Equal(t, expectedDON, gotDon.DON) + assert.Equal(t, configb, gotDon.CapabilityConfigurations[cid].Config) nodesInfo := []kcr.CapabilitiesRegistryNodeInfo{ { @@ -329,10 +315,6 @@ func TestSyncer_LocalNode(t *testing.T) { var pid p2ptypes.PeerID err := pid.UnmarshalText([]byte("12D3KooWBCF1XT5Wi8FzfgNCqRL76Swv8TRU3TiD4QiJm8NMNX7N")) require.NoError(t, err) - peer := mocks.NewPeer(t) - peer.On("ID").Return(pid) - wrapper := mocks.NewPeerWrapper(t) - wrapper.On("GetPeer").Return(peer) workflowDonNodes := []p2ptypes.PeerID{ pid, @@ -346,8 +328,8 @@ func TestSyncer_LocalNode(t *testing.T) { // which exposes the streams-trigger and write_chain capabilities. // We expect receivers to be wired up and both capabilities to be added to the registry. localRegistry := LocalRegistry{ - lggr: lggr, - peerWrapper: wrapper, + lggr: lggr, + getPeerID: func() (p2ptypes.PeerID, error) { return pid, nil }, IDsToDONs: map[DonID]DON{ DonID(dID): { DON: capabilities.DON{ diff --git a/core/services/synchronization/common.go b/core/services/synchronization/common.go index bfb9fba6de..394830a76a 100644 --- a/core/services/synchronization/common.go +++ b/core/services/synchronization/common.go @@ -24,6 +24,10 @@ const ( OCR3Mercury TelemetryType = "ocr3-mercury" AutomationCustom TelemetryType = "automation-custom" OCR3Automation TelemetryType = "ocr3-automation" + OCR3Rebalancer TelemetryType = "ocr3-rebalancer" + OCR3CCIPCommit TelemetryType = "ocr3-ccip-commit" + OCR3CCIPExec TelemetryType = "ocr3-ccip-exec" + OCR3CCIPBootstrap TelemetryType = "ocr3-bootstrap" ) type TelemPayload struct { diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index 3af8728413..0a38bf719b 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -11,8 +11,10 @@ import ( "github.com/shopspring/decimal" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/values" "github.com/smartcontractkit/chainlink-common/pkg/workflows" @@ -22,6 +24,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" + "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" "github.com/smartcontractkit/chainlink/v2/core/services/workflows/store" ) @@ -101,7 +104,7 @@ func newTestDBStore(t *testing.T, clock clockwork.Clock) store.Store { type testConfigProvider struct { localNode func(ctx context.Context) (capabilities.Node, error) - configForCapability func(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error) + configForCapability func(ctx context.Context, capabilityID string, donID uint32) (registrysyncer.CapabilityConfiguration, error) } func (t testConfigProvider) LocalNode(ctx context.Context) (capabilities.Node, error) { @@ -118,12 +121,12 @@ func (t testConfigProvider) LocalNode(ctx context.Context) (capabilities.Node, e }, nil } -func (t testConfigProvider) ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error) { +func (t testConfigProvider) ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (registrysyncer.CapabilityConfiguration, error) { if t.configForCapability != nil { return t.configForCapability(ctx, capabilityID, donID) } - return capabilities.CapabilityConfiguration{}, nil + return registrysyncer.CapabilityConfiguration{}, nil } // newTestEngine creates a new engine with some test defaults. @@ -1028,11 +1031,9 @@ func TestEngine_MergesWorkflowConfigAndCRConfig(t *testing.T) { simpleWorkflow, ) reg.SetLocalRegistry(testConfigProvider{ - configForCapability: func(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error) { + configForCapability: func(ctx context.Context, capabilityID string, donID uint32) (registrysyncer.CapabilityConfiguration, error) { if capabilityID != writeID { - return capabilities.CapabilityConfiguration{ - DefaultConfig: values.EmptyMap(), - }, nil + return registrysyncer.CapabilityConfiguration{}, nil } cm, err := values.WrapMap(map[string]any{ @@ -1040,12 +1041,15 @@ func TestEngine_MergesWorkflowConfigAndCRConfig(t *testing.T) { "schedule": "allAtOnce", }) if err != nil { - return capabilities.CapabilityConfiguration{}, err + return registrysyncer.CapabilityConfiguration{}, err } - return capabilities.CapabilityConfiguration{ - DefaultConfig: cm, - }, nil + cb, err := proto.Marshal(&capabilitiespb.CapabilityConfig{ + DefaultConfig: values.ProtoMap(cm), + }) + return registrysyncer.CapabilityConfiguration{ + Config: cb, + }, err }, }) diff --git a/core/web/presenters/job.go b/core/web/presenters/job.go index ad6bf617a8..bb51865051 100644 --- a/core/web/presenters/job.go +++ b/core/web/presenters/job.go @@ -468,6 +468,26 @@ func NewStandardCapabilitiesSpec(spec *job.StandardCapabilitiesSpec) *StandardCa } } +type CCIPSpec struct { + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + CapabilityVersion string `json:"capabilityVersion"` + CapabilityLabelledName string `json:"capabilityLabelledName"` + OCRKeyBundleIDs map[string]interface{} `json:"ocrKeyBundleIDs"` + P2PKeyID string `json:"p2pKeyID"` +} + +func NewCCIPSpec(spec *job.CCIPSpec) *CCIPSpec { + return &CCIPSpec{ + CreatedAt: spec.CreatedAt, + UpdatedAt: spec.UpdatedAt, + CapabilityVersion: spec.CapabilityVersion, + CapabilityLabelledName: spec.CapabilityLabelledName, + OCRKeyBundleIDs: spec.OCRKeyBundleIDs, + P2PKeyID: spec.P2PKeyID, + } +} + // JobError represents errors on the job type JobError struct { ID int64 `json:"id"` @@ -512,6 +532,7 @@ type JobResource struct { GatewaySpec *GatewaySpec `json:"gatewaySpec"` WorkflowSpec *WorkflowSpec `json:"workflowSpec"` StandardCapabilitiesSpec *StandardCapabilitiesSpec `json:"standardCapabilitiesSpec"` + CCIPSpec *CCIPSpec `json:"ccipSpec"` PipelineSpec PipelineSpec `json:"pipelineSpec"` Errors []JobError `json:"errors"` } @@ -562,6 +583,8 @@ func NewJobResource(j job.Job) *JobResource { resource.WorkflowSpec = NewWorkflowSpec(j.WorkflowSpec) case job.StandardCapabilities: resource.StandardCapabilitiesSpec = NewStandardCapabilitiesSpec(j.StandardCapabilitiesSpec) + case job.CCIP: + resource.CCIPSpec = NewCCIPSpec(j.CCIPSpec) case job.LegacyGasStationServer, job.LegacyGasStationSidecar: // unsupported } diff --git a/core/web/presenters/job_test.go b/core/web/presenters/job_test.go index 5de71f918e..75697c6e06 100644 --- a/core/web/presenters/job_test.go +++ b/core/web/presenters/job_test.go @@ -130,6 +130,7 @@ func TestJob(t *testing.T) { "bootstrapSpec": null, "gatewaySpec": null, "standardCapabilitiesSpec": null, + "ccipSpec": null, "errors": [] } } @@ -208,6 +209,7 @@ func TestJob(t *testing.T) { "bootstrapSpec": null, "gatewaySpec": null, "standardCapabilitiesSpec": null, + "ccipSpec": null, "errors": [] } } @@ -296,6 +298,7 @@ func TestJob(t *testing.T) { "bootstrapSpec": null, "gatewaySpec": null, "standardCapabilitiesSpec": null, + "ccipSpec": null, "errors": [] } } @@ -361,6 +364,7 @@ func TestJob(t *testing.T) { "bootstrapSpec": null, "gatewaySpec": null, "standardCapabilitiesSpec": null, + "ccipSpec": null, "errors": [] } } @@ -423,6 +427,7 @@ func TestJob(t *testing.T) { "bootstrapSpec": null, "gatewaySpec": null, "standardCapabilitiesSpec": null, + "ccipSpec": null, "errors": [] } } @@ -481,6 +486,7 @@ func TestJob(t *testing.T) { "bootstrapSpec": null, "gatewaySpec": null, "standardCapabilitiesSpec": null, + "ccipSpec": null, "errors": [] } } @@ -566,7 +572,9 @@ func TestJob(t *testing.T) { "dotDagSource": "" }, "gatewaySpec": null, - "standardCapabilitiesSpec": null, + "standardCapabilitiesSpec": null, + "standardCapabilitiesSpec": null, + "ccipSpec": null, "errors": [] } } @@ -649,6 +657,7 @@ func TestJob(t *testing.T) { }, "gatewaySpec": null, "standardCapabilitiesSpec": null, + "ccipSpec": null, "errors": [] } } @@ -731,6 +740,7 @@ func TestJob(t *testing.T) { }, "gatewaySpec": null, "standardCapabilitiesSpec": null, + "ccipSpec": null, "errors": [] } } @@ -780,14 +790,14 @@ func TestJob(t *testing.T) { "blockhashStoreSpec": null, "blockHeaderFeederSpec": null, "bootstrapSpec": { - "blockchainTimeout":"0s", - "contractConfigConfirmations":0, - "contractConfigTrackerPollInterval":"0s", - "contractConfigTrackerSubscribeInterval":"0s", - "contractID":"0x16988483b46e695f6c8D58e6e1461DC703e008e1", - "createdAt":"0001-01-01T00:00:00Z", - "relay":"evm", - "relayConfig":{"chainID":1337}, + "blockchainTimeout":"0s", + "contractConfigConfirmations":0, + "contractConfigTrackerPollInterval":"0s", + "contractConfigTrackerSubscribeInterval":"0s", + "contractID":"0x16988483b46e695f6c8D58e6e1461DC703e008e1", + "createdAt":"0001-01-01T00:00:00Z", + "relay":"evm", + "relayConfig":{"chainID":1337}, "updatedAt":"0001-01-01T00:00:00Z" }, "pipelineSpec": { @@ -797,6 +807,7 @@ func TestJob(t *testing.T) { }, "gatewaySpec": null, "standardCapabilitiesSpec": null, + "ccipSpec": null, "errors": [] } } @@ -855,6 +866,7 @@ func TestJob(t *testing.T) { "updatedAt":"0001-01-01T00:00:00Z" }, "standardCapabilitiesSpec": null, + "ccipSpec": null, "pipelineSpec": { "id": 1, "jobID": 0, @@ -919,6 +931,7 @@ func TestJob(t *testing.T) { "bootstrapSpec": null, "gatewaySpec": null, "standardCapabilitiesSpec": null, + "ccipSpec": null, "pipelineSpec": { "id": 1, "jobID": 0, @@ -979,6 +992,72 @@ func TestJob(t *testing.T) { "createdAt":"0001-01-01T00:00:00Z", "updatedAt":"0001-01-01T00:00:00Z" }, + "ccipSpec": null, + "pipelineSpec": { + "id": 1, + "jobID": 0, + "dotDagSource": "" + }, + "errors": [] + } + } + }`, + }, + { + name: "ccip spec", + job: job.Job{ + ID: 1, + CCIPSpec: &job.CCIPSpec{ + ID: 3, + CreatedAt: timestamp, + UpdatedAt: timestamp, + CapabilityVersion: "4.5.9", + CapabilityLabelledName: "ccip", + }, + PipelineSpec: &pipeline.Spec{ + ID: 1, + DotDagSource: "", + }, + ExternalJobID: uuid.MustParse("0eec7e1d-d0d2-476c-a1a8-72dfb6633f46"), + Type: job.CCIP, + SchemaVersion: 1, + Name: null.StringFrom("ccip test"), + }, + want: ` + { + "data": { + "type": "jobs", + "id": "1", + "attributes": { + "name": "ccip test", + "type": "ccip", + "schemaVersion": 1, + "maxTaskDuration": "0s", + "externalJobID": "0eec7e1d-d0d2-476c-a1a8-72dfb6633f46", + "directRequestSpec": null, + "fluxMonitorSpec": null, + "gasLimit": null, + "forwardingAllowed": false, + "cronSpec": null, + "offChainReportingOracleSpec": null, + "offChainReporting2OracleSpec": null, + "keeperSpec": null, + "vrfSpec": null, + "webhookSpec": null, + "workflowSpec": null, + "blockhashStoreSpec": null, + "blockHeaderFeederSpec": null, + "bootstrapSpec": null, + "gatewaySpec": null, + "standardCapabilitiesSpec": null, + "ccipSpec": { + "capabilityVersion":"4.5.9", + "capabilityLabelledName":"ccip", + "ocrKeyBundleIDs": null, + "p2pKeyID": "", + "createdAt":"2000-01-01T00:00:00Z", + "updatedAt":"2000-01-01T00:00:00Z" + }, "pipelineSpec": { "id": 1, "jobID": 0, @@ -1058,6 +1137,7 @@ func TestJob(t *testing.T) { "bootstrapSpec": null, "gatewaySpec": null, "standardCapabilitiesSpec": null, + "ccipSpec": null, "errors": [{ "id": 200, "description": "some error", diff --git a/go.md b/go.md index d9ed0d0a66..697d6b52ce 100644 --- a/go.md +++ b/go.md @@ -28,6 +28,8 @@ flowchart LR click chain-selectors href "https://github.com/smartcontractkit/chain-selectors" chainlink/v2 --> chainlink-automation click chainlink-automation href "https://github.com/smartcontractkit/chainlink-automation" + chainlink/v2 --> chainlink-ccip + click chainlink-ccip href "https://github.com/smartcontractkit/chainlink-ccip" chainlink/v2 --> chainlink-common click chainlink-common href "https://github.com/smartcontractkit/chainlink-common" chainlink/v2 --> chainlink-cosmos @@ -50,6 +52,8 @@ flowchart LR click wsrpc href "https://github.com/smartcontractkit/wsrpc" chainlink-automation --> chainlink-common chainlink-automation --> libocr + chainlink-ccip --> chainlink-common + chainlink-ccip --> libocr chainlink-common --> libocr chainlink-cosmos --> chainlink-common chainlink-cosmos --> libocr diff --git a/go.mod b/go.mod index 2179ffc2d2..f89bfe7def 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/cometbft/cometbft v0.37.2 github.com/cosmos/cosmos-sdk v0.47.4 github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e - github.com/deckarep/golang-set/v2 v2.3.0 + github.com/deckarep/golang-set/v2 v2.6.0 github.com/dominikbraun/graph v0.23.0 github.com/esote/minmaxheap v1.0.0 github.com/ethereum/go-ethereum v1.13.8 @@ -74,6 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.4 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f @@ -102,7 +103,7 @@ require ( go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.25.0 - golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/mod v0.19.0 golang.org/x/net v0.27.0 golang.org/x/sync v0.7.0 diff --git a/go.sum b/go.sum index b953f315e9..9679a2da3a 100644 --- a/go.sum +++ b/go.sum @@ -315,8 +315,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= -github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= @@ -1139,6 +1139,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c h1:3apUsez/6Pkp1ckXzSwIhzPRuWjDGjzMjKapEKi0Fcw= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= @@ -1436,8 +1438,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7 h1:wDLEX9a7YQoKdKNQt88rtydkqDxeGaBUTnIYc3iG/mA= -golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index ff60a8f78b..7be6ea209f 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -143,7 +143,7 @@ require ( github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/deckarep/golang-set/v2 v2.3.0 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dennwc/varint v1.0.0 // indirect github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 // indirect @@ -377,6 +377,7 @@ require ( github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect @@ -448,7 +449,7 @@ require ( go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.19.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 5d15dfd92f..372a5ee014 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -415,8 +415,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= -github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= @@ -1488,6 +1488,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c h1:3apUsez/6Pkp1ckXzSwIhzPRuWjDGjzMjKapEKi0Fcw= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= @@ -1836,8 +1838,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7 h1:wDLEX9a7YQoKdKNQt88rtydkqDxeGaBUTnIYc3iG/mA= -golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index c464231c74..11893540a3 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -39,6 +39,7 @@ require ( github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect k8s.io/apimachinery v0.30.2 // indirect ) @@ -131,7 +132,7 @@ require ( github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/deckarep/golang-set/v2 v2.3.0 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dennwc/varint v1.0.0 // indirect github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 // indirect @@ -445,7 +446,7 @@ require ( go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.19.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index d1d6f3a4d5..97a9dfc8ec 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -405,8 +405,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= -github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= @@ -1470,6 +1470,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c h1:3apUsez/6Pkp1ckXzSwIhzPRuWjDGjzMjKapEKi0Fcw= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= @@ -1818,8 +1820,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7 h1:wDLEX9a7YQoKdKNQt88rtydkqDxeGaBUTnIYc3iG/mA= -golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= From 2ac9d980eb1527a2e1e631fb4515919f3b872333 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Wed, 7 Aug 2024 18:37:27 -0400 Subject: [PATCH 055/432] auto-11214: migrate more tests to foundry (#13934) * auto: migrate more tests to foundry * more tests * tests for migration permission * tests for upkeep and admin configs * tests for upkeep admin * tests for pause / unpause upkeeps * tests for upkeep configs * tests for payees * cancel upkeep tests * update * update * withdraw * update --- .../test/v2_3/AutomationRegistry2_3.t.sol | 784 ++++++++- .../v0.8/automation/test/v2_3/BaseTest.t.sol | 74 +- .../automation/AutomationRegistry2_3.test.ts | 1402 ++--------------- 3 files changed, 980 insertions(+), 1280 deletions(-) diff --git a/contracts/src/v0.8/automation/test/v2_3/AutomationRegistry2_3.t.sol b/contracts/src/v0.8/automation/test/v2_3/AutomationRegistry2_3.t.sol index dbc0c203c0..41aabf1bbe 100644 --- a/contracts/src/v0.8/automation/test/v2_3/AutomationRegistry2_3.t.sol +++ b/contracts/src/v0.8/automation/test/v2_3/AutomationRegistry2_3.t.sol @@ -22,11 +22,11 @@ contract SetUp is BaseTest { AutomationRegistryBase2_3.OnchainConfig internal config; bytes internal constant offchainConfigBytes = abi.encode(1234, ZERO_ADDRESS); - uint256 linkUpkeepID; - uint256 linkUpkeepID2; // 2 upkeeps use the same billing token (LINK) to test migration scenario - uint256 usdUpkeepID18; // 1 upkeep uses ERC20 token with 18 decimals - uint256 usdUpkeepID6; // 1 upkeep uses ERC20 token with 6 decimals - uint256 nativeUpkeepID; + uint256 internal linkUpkeepID; + uint256 internal linkUpkeepID2; // 2 upkeeps use the same billing token (LINK) to test migration scenario + uint256 internal usdUpkeepID18; // 1 upkeep uses ERC20 token with 18 decimals + uint256 internal usdUpkeepID6; // 1 upkeep uses ERC20 token with 6 decimals + uint256 internal nativeUpkeepID; function setUp() public virtual override { super.setUp(); @@ -790,6 +790,7 @@ contract SetConfig is SetUp { } function testSetConfigOnTransmittersAndPayees() public { + registry.setPayees(PAYEES); AutomationRegistryBase2_3.TransmitterPayeeInfo[] memory transmitterPayeeInfos = registry .getTransmittersWithPayees(); assertEq(transmitterPayeeInfos.length, TRANSMITTERS.length); @@ -975,6 +976,7 @@ contract NOPsSettlement is SetUp { function testSettleNOPsOffchainSuccess() public { // deploy and configure a registry with OFF_CHAIN payout (Registry registry, ) = deployAndConfigureRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN); + registry.setPayees(PAYEES); uint256[] memory payments = new uint256[](TRANSMITTERS.length); for (uint256 i = 0; i < TRANSMITTERS.length; i++) { @@ -991,6 +993,7 @@ contract NOPsSettlement is SetUp { function testSettleNOPsOffchainSuccessWithERC20MultiSteps() public { // deploy and configure a registry with OFF_CHAIN payout (Registry registry, ) = deployAndConfigureRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN); + registry.setPayees(PAYEES); // register an upkeep and add funds uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken18), "", "", ""); @@ -1186,6 +1189,7 @@ contract NOPsSettlement is SetUp { function testSinglePerformAndNodesCanWithdrawOnchain() public { // deploy and configure a registry with OFF_CHAIN payout (Registry registry, ) = deployAndConfigureRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN); + registry.setPayees(PAYEES); // register an upkeep and add funds uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken18), "", "", ""); @@ -1224,6 +1228,7 @@ contract NOPsSettlement is SetUp { function testMultiplePerformsAndNodesCanWithdrawOnchain() public { // deploy and configure a registry with OFF_CHAIN payout (Registry registry, ) = deployAndConfigureRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN); + registry.setPayees(PAYEES); // register an upkeep and add funds uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken18), "", "", ""); @@ -1977,3 +1982,772 @@ contract MigrateReceive is SetUp { vm.stopPrank(); } } + +contract Pause is SetUp { + function test_RevertsWhen_CalledByNonOwner() external { + vm.expectRevert(bytes("Only callable by owner")); + vm.prank(STRANGER); + registry.pause(); + } + + function test_CalledByOwner_success() external { + vm.startPrank(registry.owner()); + registry.pause(); + + (IAutomationV21PlusCommon.StateLegacy memory state, , , , ) = registry.getState(); + assertTrue(state.paused); + } + + function test_revertsWhen_transmitInPausedRegistry() external { + vm.startPrank(registry.owner()); + registry.pause(); + + _transmitAndExpectRevert(usdUpkeepID18, registry, Registry.RegistryPaused.selector); + } +} + +contract Unpause is SetUp { + function test_RevertsWhen_CalledByNonOwner() external { + vm.startPrank(registry.owner()); + registry.pause(); + + vm.expectRevert(bytes("Only callable by owner")); + vm.startPrank(STRANGER); + registry.unpause(); + } + + function test_CalledByOwner_success() external { + vm.startPrank(registry.owner()); + registry.pause(); + (IAutomationV21PlusCommon.StateLegacy memory state1, , , , ) = registry.getState(); + assertTrue(state1.paused); + + registry.unpause(); + (IAutomationV21PlusCommon.StateLegacy memory state2, , , , ) = registry.getState(); + assertFalse(state2.paused); + } +} + +contract CancelUpkeep is SetUp { + event UpkeepCanceled(uint256 indexed id, uint64 indexed atBlockHeight); + + function test_RevertsWhen_IdIsInvalid_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + vm.expectRevert(Registry.CannotCancel.selector); + registry.cancelUpkeep(1111111); + } + + function test_RevertsWhen_IdIsInvalid_CalledByOwner() external { + vm.startPrank(registry.owner()); + vm.expectRevert(Registry.CannotCancel.selector); + registry.cancelUpkeep(1111111); + } + + function test_RevertsWhen_NotCalledByOwnerOrAdmin() external { + vm.startPrank(STRANGER); + vm.expectRevert(Registry.OnlyCallableByOwnerOrAdmin.selector); + registry.cancelUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepAlreadyCanceledByAdmin_CalledByOwner() external { + uint256 bn = block.number; + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.startPrank(registry.owner()); + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.cancelUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepAlreadyCanceledByOwner_CalledByAdmin() external { + uint256 bn = block.number; + vm.startPrank(registry.owner()); + registry.cancelUpkeep(linkUpkeepID); + + vm.startPrank(UPKEEP_ADMIN); + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.cancelUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepAlreadyCanceledByAdmin_CalledByAdmin() external { + uint256 bn = block.number; + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.cancelUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepAlreadyCanceledByOwner_CalledByOwner() external { + uint256 bn = block.number; + vm.startPrank(registry.owner()); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.cancelUpkeep(linkUpkeepID); + } + + function test_CancelUpkeep_SetMaxValidBlockNumber_CalledByAdmin() external { + uint256 bn = block.number; + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + uint256 maxValidBlocknumber = uint256(registry.getUpkeep(linkUpkeepID).maxValidBlocknumber); + + // 50 is the cancellation delay + assertEq(bn + 50, maxValidBlocknumber); + } + + function test_CancelUpkeep_SetMaxValidBlockNumber_CalledByOwner() external { + uint256 bn = block.number; + vm.startPrank(registry.owner()); + registry.cancelUpkeep(linkUpkeepID); + + uint256 maxValidBlocknumber = uint256(registry.getUpkeep(linkUpkeepID).maxValidBlocknumber); + + // cancellation by registry owner is immediate and no cancellation delay is applied + assertEq(bn, maxValidBlocknumber); + } + + function test_CancelUpkeep_EmitEvent_CalledByAdmin() external { + uint256 bn = block.number; + vm.startPrank(UPKEEP_ADMIN); + + vm.expectEmit(); + emit UpkeepCanceled(linkUpkeepID, uint64(bn + 50)); + registry.cancelUpkeep(linkUpkeepID); + } + + function test_CancelUpkeep_EmitEvent_CalledByOwner() external { + uint256 bn = block.number; + vm.startPrank(registry.owner()); + + vm.expectEmit(); + emit UpkeepCanceled(linkUpkeepID, uint64(bn)); + registry.cancelUpkeep(linkUpkeepID); + } +} + +contract SetPeerRegistryMigrationPermission is SetUp { + function test_SetPeerRegistryMigrationPermission_CalledByOwner() external { + address peer = randomAddress(); + vm.startPrank(registry.owner()); + + uint8 permission = registry.getPeerRegistryMigrationPermission(peer); + assertEq(0, permission); + + registry.setPeerRegistryMigrationPermission(peer, 1); + permission = registry.getPeerRegistryMigrationPermission(peer); + assertEq(1, permission); + + registry.setPeerRegistryMigrationPermission(peer, 2); + permission = registry.getPeerRegistryMigrationPermission(peer); + assertEq(2, permission); + + registry.setPeerRegistryMigrationPermission(peer, 0); + permission = registry.getPeerRegistryMigrationPermission(peer); + assertEq(0, permission); + } + + function test_RevertsWhen_InvalidPermission_CalledByOwner() external { + address peer = randomAddress(); + vm.startPrank(registry.owner()); + + vm.expectRevert(); + registry.setPeerRegistryMigrationPermission(peer, 100); + } + + function test_RevertsWhen_CalledByNonOwner() external { + address peer = randomAddress(); + vm.startPrank(STRANGER); + + vm.expectRevert(bytes("Only callable by owner")); + registry.setPeerRegistryMigrationPermission(peer, 1); + } +} + +contract SetUpkeepPrivilegeConfig is SetUp { + function test_RevertsWhen_CalledByNonManager() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByUpkeepPrivilegeManager.selector); + registry.setUpkeepPrivilegeConfig(linkUpkeepID, hex"1233"); + } + + function test_UpkeepHasEmptyConfig() external { + bytes memory cfg = registry.getUpkeepPrivilegeConfig(linkUpkeepID); + assertEq(cfg, bytes("")); + } + + function test_SetUpkeepPrivilegeConfig_CalledByManager() external { + vm.startPrank(PRIVILEGE_MANAGER); + + registry.setUpkeepPrivilegeConfig(linkUpkeepID, hex"1233"); + + bytes memory cfg = registry.getUpkeepPrivilegeConfig(linkUpkeepID); + assertEq(cfg, hex"1233"); + } +} + +contract SetAdminPrivilegeConfig is SetUp { + function test_RevertsWhen_CalledByNonManager() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByUpkeepPrivilegeManager.selector); + registry.setAdminPrivilegeConfig(randomAddress(), hex"1233"); + } + + function test_UpkeepHasEmptyConfig() external { + bytes memory cfg = registry.getAdminPrivilegeConfig(randomAddress()); + assertEq(cfg, bytes("")); + } + + function test_SetAdminPrivilegeConfig_CalledByManager() external { + vm.startPrank(PRIVILEGE_MANAGER); + address admin = randomAddress(); + + registry.setAdminPrivilegeConfig(admin, hex"1233"); + + bytes memory cfg = registry.getAdminPrivilegeConfig(admin); + assertEq(cfg, hex"1233"); + } +} + +contract TransferUpkeepAdmin is SetUp { + event UpkeepAdminTransferRequested(uint256 indexed id, address indexed from, address indexed to); + + function test_RevertsWhen_NotCalledByAdmin() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.transferUpkeepAdmin(linkUpkeepID, randomAddress()); + } + + function test_RevertsWhen_TransferToSelf() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.ValueNotChanged.selector); + registry.transferUpkeepAdmin(linkUpkeepID, UPKEEP_ADMIN); + } + + function test_RevertsWhen_UpkeepCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.transferUpkeepAdmin(linkUpkeepID, randomAddress()); + } + + function test_DoesNotChangeUpkeepAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + registry.transferUpkeepAdmin(linkUpkeepID, randomAddress()); + + assertEq(registry.getUpkeep(linkUpkeepID).admin, UPKEEP_ADMIN); + } + + function test_EmitEvent_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + address newAdmin = randomAddress(); + + vm.expectEmit(); + emit UpkeepAdminTransferRequested(linkUpkeepID, UPKEEP_ADMIN, newAdmin); + registry.transferUpkeepAdmin(linkUpkeepID, newAdmin); + + // transferring to the same propose admin won't yield another event + vm.recordLogs(); + registry.transferUpkeepAdmin(linkUpkeepID, newAdmin); + Vm.Log[] memory entries = vm.getRecordedLogs(); + assertEq(0, entries.length); + } + + function test_CancelTransfer_ByTransferToEmptyAddress() external { + vm.startPrank(UPKEEP_ADMIN); + address newAdmin = randomAddress(); + + vm.expectEmit(); + emit UpkeepAdminTransferRequested(linkUpkeepID, UPKEEP_ADMIN, newAdmin); + registry.transferUpkeepAdmin(linkUpkeepID, newAdmin); + + vm.expectEmit(); + emit UpkeepAdminTransferRequested(linkUpkeepID, UPKEEP_ADMIN, address(0)); + registry.transferUpkeepAdmin(linkUpkeepID, address(0)); + } +} + +contract AcceptUpkeepAdmin is SetUp { + event UpkeepAdminTransferred(uint256 indexed id, address indexed from, address indexed to); + + function test_RevertsWhen_NotCalledByProposedAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + address newAdmin = randomAddress(); + registry.transferUpkeepAdmin(linkUpkeepID, newAdmin); + + vm.startPrank(STRANGER); + vm.expectRevert(Registry.OnlyCallableByProposedAdmin.selector); + registry.acceptUpkeepAdmin(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + address newAdmin = randomAddress(); + registry.transferUpkeepAdmin(linkUpkeepID, newAdmin); + + registry.cancelUpkeep(linkUpkeepID); + + vm.startPrank(newAdmin); + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.acceptUpkeepAdmin(linkUpkeepID); + } + + function test_UpkeepAdminChanged() external { + vm.startPrank(UPKEEP_ADMIN); + address newAdmin = randomAddress(); + registry.transferUpkeepAdmin(linkUpkeepID, newAdmin); + + vm.startPrank(newAdmin); + vm.expectEmit(); + emit UpkeepAdminTransferred(linkUpkeepID, UPKEEP_ADMIN, newAdmin); + registry.acceptUpkeepAdmin(linkUpkeepID); + + assertEq(newAdmin, registry.getUpkeep(linkUpkeepID).admin); + } +} + +contract PauseUpkeep is SetUp { + event UpkeepPaused(uint256 indexed id); + + function test_RevertsWhen_NotCalledByUpkeepAdmin() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.pauseUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_InvalidUpkeepId() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.pauseUpkeep(linkUpkeepID + 1); + } + + function test_RevertsWhen_UpkeepAlreadyCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.pauseUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepAlreadyPaused() external { + vm.startPrank(UPKEEP_ADMIN); + registry.pauseUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.OnlyUnpausedUpkeep.selector); + registry.pauseUpkeep(linkUpkeepID); + } + + function test_EmitEvent_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectEmit(); + emit UpkeepPaused(linkUpkeepID); + registry.pauseUpkeep(linkUpkeepID); + } +} + +contract UnpauseUpkeep is SetUp { + event UpkeepUnpaused(uint256 indexed id); + + function test_RevertsWhen_InvalidUpkeepId() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.unpauseUpkeep(linkUpkeepID + 1); + } + + function test_RevertsWhen_UpkeepIsNotPaused() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyPausedUpkeep.selector); + registry.unpauseUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepAlreadyCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + registry.pauseUpkeep(linkUpkeepID); + + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.unpauseUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_NotCalledByUpkeepAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + registry.pauseUpkeep(linkUpkeepID); + + vm.startPrank(STRANGER); + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.unpauseUpkeep(linkUpkeepID); + } + + function test_UnpauseUpkeep_CalledByUpkeepAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + registry.pauseUpkeep(linkUpkeepID); + + uint256[] memory ids1 = registry.getActiveUpkeepIDs(0, 0); + + vm.expectEmit(); + emit UpkeepUnpaused(linkUpkeepID); + registry.unpauseUpkeep(linkUpkeepID); + + uint256[] memory ids2 = registry.getActiveUpkeepIDs(0, 0); + assertEq(ids1.length + 1, ids2.length); + } +} + +contract SetUpkeepCheckData is SetUp { + event UpkeepCheckDataSet(uint256 indexed id, bytes newCheckData); + + function test_RevertsWhen_InvalidUpkeepId() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepCheckData(linkUpkeepID + 1, hex"1234"); + } + + function test_RevertsWhen_UpkeepAlreadyCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.setUpkeepCheckData(linkUpkeepID, hex"1234"); + } + + function test_RevertsWhen_NewCheckDataTooLarge() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.CheckDataExceedsLimit.selector); + registry.setUpkeepCheckData(linkUpkeepID, new bytes(10_000)); + } + + function test_RevertsWhen_NotCalledByAdmin() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepCheckData(linkUpkeepID, hex"1234"); + } + + function test_UpdateOffchainConfig_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectEmit(); + emit UpkeepCheckDataSet(linkUpkeepID, hex"1234"); + registry.setUpkeepCheckData(linkUpkeepID, hex"1234"); + + assertEq(registry.getUpkeep(linkUpkeepID).checkData, hex"1234"); + } + + function test_UpdateOffchainConfigOnPausedUpkeep_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + + registry.pauseUpkeep(linkUpkeepID); + + vm.expectEmit(); + emit UpkeepCheckDataSet(linkUpkeepID, hex"1234"); + registry.setUpkeepCheckData(linkUpkeepID, hex"1234"); + + assertTrue(registry.getUpkeep(linkUpkeepID).paused); + assertEq(registry.getUpkeep(linkUpkeepID).checkData, hex"1234"); + } +} + +contract SetUpkeepGasLimit is SetUp { + event UpkeepGasLimitSet(uint256 indexed id, uint96 gasLimit); + + function test_RevertsWhen_InvalidUpkeepId() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepGasLimit(linkUpkeepID + 1, 1230000); + } + + function test_RevertsWhen_UpkeepAlreadyCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.setUpkeepGasLimit(linkUpkeepID, 1230000); + } + + function test_RevertsWhen_NewGasLimitOutOfRange() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.GasLimitOutsideRange.selector); + registry.setUpkeepGasLimit(linkUpkeepID, 300); + + vm.expectRevert(Registry.GasLimitOutsideRange.selector); + registry.setUpkeepGasLimit(linkUpkeepID, 3000000000); + } + + function test_RevertsWhen_NotCalledByAdmin() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepGasLimit(linkUpkeepID, 1230000); + } + + function test_UpdateGasLimit_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectEmit(); + emit UpkeepGasLimitSet(linkUpkeepID, 1230000); + registry.setUpkeepGasLimit(linkUpkeepID, 1230000); + + assertEq(registry.getUpkeep(linkUpkeepID).performGas, 1230000); + } +} + +contract SetUpkeepOffchainConfig is SetUp { + event UpkeepOffchainConfigSet(uint256 indexed id, bytes offchainConfig); + + function test_RevertsWhen_InvalidUpkeepId() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepOffchainConfig(linkUpkeepID + 1, hex"1233"); + } + + function test_RevertsWhen_UpkeepAlreadyCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.setUpkeepOffchainConfig(linkUpkeepID, hex"1234"); + } + + function test_RevertsWhen_NotCalledByAdmin() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepOffchainConfig(linkUpkeepID, hex"1234"); + } + + function test_UpdateOffchainConfig_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectEmit(); + emit UpkeepOffchainConfigSet(linkUpkeepID, hex"1234"); + registry.setUpkeepOffchainConfig(linkUpkeepID, hex"1234"); + + assertEq(registry.getUpkeep(linkUpkeepID).offchainConfig, hex"1234"); + } +} + +contract SetUpkeepTriggerConfig is SetUp { + event UpkeepTriggerConfigSet(uint256 indexed id, bytes triggerConfig); + + function test_RevertsWhen_InvalidUpkeepId() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepTriggerConfig(linkUpkeepID + 1, hex"1233"); + } + + function test_RevertsWhen_UpkeepAlreadyCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.setUpkeepTriggerConfig(linkUpkeepID, hex"1234"); + } + + function test_RevertsWhen_NotCalledByAdmin() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepTriggerConfig(linkUpkeepID, hex"1234"); + } + + function test_UpdateTriggerConfig_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectEmit(); + emit UpkeepTriggerConfigSet(linkUpkeepID, hex"1234"); + registry.setUpkeepTriggerConfig(linkUpkeepID, hex"1234"); + + assertEq(registry.getUpkeepTriggerConfig(linkUpkeepID), hex"1234"); + } +} + +contract TransferPayeeship is SetUp { + event PayeeshipTransferRequested(address indexed transmitter, address indexed from, address indexed to); + + function test_RevertsWhen_NotCalledByPayee() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByPayee.selector); + registry.transferPayeeship(TRANSMITTERS[0], randomAddress()); + } + + function test_RevertsWhen_TransferToSelf() external { + registry.setPayees(PAYEES); + vm.startPrank(PAYEES[0]); + + vm.expectRevert(Registry.ValueNotChanged.selector); + registry.transferPayeeship(TRANSMITTERS[0], PAYEES[0]); + } + + function test_Transfer_DoesNotChangePayee() external { + registry.setPayees(PAYEES); + + vm.startPrank(PAYEES[0]); + + registry.transferPayeeship(TRANSMITTERS[0], randomAddress()); + + (, , , , address payee) = registry.getTransmitterInfo(TRANSMITTERS[0]); + assertEq(PAYEES[0], payee); + } + + function test_EmitEvent_CalledByPayee() external { + registry.setPayees(PAYEES); + + vm.startPrank(PAYEES[0]); + address newPayee = randomAddress(); + + vm.expectEmit(); + emit PayeeshipTransferRequested(TRANSMITTERS[0], PAYEES[0], newPayee); + registry.transferPayeeship(TRANSMITTERS[0], newPayee); + + // transferring to the same propose payee won't yield another event + vm.recordLogs(); + registry.transferPayeeship(TRANSMITTERS[0], newPayee); + Vm.Log[] memory entries = vm.getRecordedLogs(); + assertEq(0, entries.length); + } +} + +contract AcceptPayeeship is SetUp { + event PayeeshipTransferred(address indexed transmitter, address indexed from, address indexed to); + + function test_RevertsWhen_NotCalledByProposedPayee() external { + registry.setPayees(PAYEES); + + vm.startPrank(PAYEES[0]); + address newPayee = randomAddress(); + registry.transferPayeeship(TRANSMITTERS[0], newPayee); + + vm.startPrank(STRANGER); + vm.expectRevert(Registry.OnlyCallableByProposedPayee.selector); + registry.acceptPayeeship(TRANSMITTERS[0]); + } + + function test_PayeeChanged() external { + registry.setPayees(PAYEES); + + vm.startPrank(PAYEES[0]); + address newPayee = randomAddress(); + registry.transferPayeeship(TRANSMITTERS[0], newPayee); + + vm.startPrank(newPayee); + vm.expectEmit(); + emit PayeeshipTransferred(TRANSMITTERS[0], PAYEES[0], newPayee); + registry.acceptPayeeship(TRANSMITTERS[0]); + + (, , , , address payee) = registry.getTransmitterInfo(TRANSMITTERS[0]); + assertEq(newPayee, payee); + } +} + +contract SetPayees is SetUp { + event PayeesUpdated(address[] transmitters, address[] payees); + + function test_RevertsWhen_NotCalledByOwner() external { + vm.startPrank(STRANGER); + + vm.expectRevert(bytes("Only callable by owner")); + registry.setPayees(NEW_PAYEES); + } + + function test_RevertsWhen_PayeesLengthError() external { + vm.startPrank(registry.owner()); + + address[] memory payees = new address[](5); + vm.expectRevert(Registry.ParameterLengthError.selector); + registry.setPayees(payees); + } + + function test_RevertsWhen_InvalidPayee() external { + vm.startPrank(registry.owner()); + + NEW_PAYEES[0] = address(0); + vm.expectRevert(Registry.InvalidPayee.selector); + registry.setPayees(NEW_PAYEES); + } + + function test_SetPayees_WhenExistingPayeesAreEmpty() external { + (registry, ) = deployAndConfigureRegistryAndRegistrar(AutoBase.PayoutMode.ON_CHAIN); + + for (uint256 i = 0; i < TRANSMITTERS.length; i++) { + (, , , , address payee) = registry.getTransmitterInfo(TRANSMITTERS[i]); + assertEq(address(0), payee); + } + + vm.startPrank(registry.owner()); + + vm.expectEmit(); + emit PayeesUpdated(TRANSMITTERS, PAYEES); + registry.setPayees(PAYEES); + for (uint256 i = 0; i < TRANSMITTERS.length; i++) { + (bool active, , , , address payee) = registry.getTransmitterInfo(TRANSMITTERS[i]); + assertTrue(active); + assertEq(PAYEES[i], payee); + } + } + + function test_DotNotSetPayeesToIgnoredAddress() external { + address IGNORE_ADDRESS = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF; + (registry, ) = deployAndConfigureRegistryAndRegistrar(AutoBase.PayoutMode.ON_CHAIN); + PAYEES[0] = IGNORE_ADDRESS; + + registry.setPayees(PAYEES); + (bool active, , , , address payee) = registry.getTransmitterInfo(TRANSMITTERS[0]); + assertTrue(active); + assertEq(address(0), payee); + + (active, , , , payee) = registry.getTransmitterInfo(TRANSMITTERS[1]); + assertTrue(active); + assertEq(PAYEES[1], payee); + } +} + +contract GetActiveUpkeepIDs is SetUp { + function test_RevertsWhen_IndexOutOfRange() external { + vm.expectRevert(Registry.IndexOutOfRange.selector); + registry.getActiveUpkeepIDs(5, 0); + + vm.expectRevert(Registry.IndexOutOfRange.selector); + registry.getActiveUpkeepIDs(6, 0); + } + + function test_ReturnsAllUpkeeps_WhenMaxCountIsZero() external { + uint256[] memory uids = registry.getActiveUpkeepIDs(0, 0); + assertEq(5, uids.length); + + uids = registry.getActiveUpkeepIDs(2, 0); + assertEq(3, uids.length); + } + + function test_ReturnsAllRemainingUpkeeps_WhenMaxCountIsTooLarge() external { + uint256[] memory uids = registry.getActiveUpkeepIDs(2, 20); + assertEq(3, uids.length); + } + + function test_ReturnsUpkeeps_BoundByMaxCount() external { + uint256[] memory uids = registry.getActiveUpkeepIDs(1, 2); + assertEq(2, uids.length); + assertEq(uids[0], linkUpkeepID2); + assertEq(uids[1], usdUpkeepID18); + } +} diff --git a/contracts/src/v0.8/automation/test/v2_3/BaseTest.t.sol b/contracts/src/v0.8/automation/test/v2_3/BaseTest.t.sol index 9e46e7bb40..e0d15daab6 100644 --- a/contracts/src/v0.8/automation/test/v2_3/BaseTest.t.sol +++ b/contracts/src/v0.8/automation/test/v2_3/BaseTest.t.sol @@ -283,7 +283,6 @@ contract BaseTest is Test { billingTokenAddresses, billingTokenConfigs ); - registry.setPayees(PAYEES); return (registry, registrar); } @@ -356,40 +355,58 @@ contract BaseTest is Test { ); } + // tests single upkeep, expects success function _transmit(uint256 id, Registry registry) internal { uint256[] memory ids = new uint256[](1); ids[0] = id; - _transmit(ids, registry); + _handleTransmit(ids, registry, bytes4(0)); } + // tests multiple upkeeps, expects success function _transmit(uint256[] memory ids, Registry registry) internal { - uint256[] memory upkeepIds = new uint256[](ids.length); - uint256[] memory gasLimits = new uint256[](ids.length); - bytes[] memory performDatas = new bytes[](ids.length); - bytes[] memory triggers = new bytes[](ids.length); - for (uint256 i = 0; i < ids.length; i++) { - upkeepIds[i] = ids[i]; - gasLimits[i] = registry.getUpkeep(ids[i]).performGas; - performDatas[i] = new bytes(0); - uint8 triggerType = registry.getTriggerType(ids[i]); - if (triggerType == 0) { - triggers[i] = _encodeConditionalTrigger( - AutoBase.ConditionalTrigger(uint32(block.number - 1), blockhash(block.number - 1)) - ); - } else { - revert("not implemented"); + _handleTransmit(ids, registry, bytes4(0)); + } + + // tests single upkeep, expects revert + function _transmitAndExpectRevert(uint256 id, Registry registry, bytes4 selector) internal { + uint256[] memory ids = new uint256[](1); + ids[0] = id; + _handleTransmit(ids, registry, selector); + } + + // private function not exposed to actual testing contract + function _handleTransmit(uint256[] memory ids, Registry registry, bytes4 selector) private { + bytes memory reportBytes; + { + uint256[] memory upkeepIds = new uint256[](ids.length); + uint256[] memory gasLimits = new uint256[](ids.length); + bytes[] memory performDatas = new bytes[](ids.length); + bytes[] memory triggers = new bytes[](ids.length); + for (uint256 i = 0; i < ids.length; i++) { + upkeepIds[i] = ids[i]; + gasLimits[i] = registry.getUpkeep(ids[i]).performGas; + performDatas[i] = new bytes(0); + uint8 triggerType = registry.getTriggerType(ids[i]); + if (triggerType == 0) { + triggers[i] = _encodeConditionalTrigger( + AutoBase.ConditionalTrigger(uint32(block.number - 1), blockhash(block.number - 1)) + ); + } else { + revert("not implemented"); + } } - } - AutoBase.Report memory report = AutoBase.Report( - uint256(1000000000), - uint256(2000000000), - upkeepIds, - gasLimits, - triggers, - performDatas - ); - bytes memory reportBytes = _encodeReport(report); + AutoBase.Report memory report = AutoBase.Report( + uint256(1000000000), + uint256(2000000000), + upkeepIds, + gasLimits, + triggers, + performDatas + ); + + reportBytes = _encodeReport(report); + } (, , bytes32 configDigest) = registry.latestConfigDetails(); bytes32[3] memory reportContext = [configDigest, configDigest, configDigest]; uint256[] memory signerPKs = new uint256[](2); @@ -398,6 +415,9 @@ contract BaseTest is Test { (bytes32[] memory rs, bytes32[] memory ss, bytes32 vs) = _signReport(reportBytes, reportContext, signerPKs); vm.startPrank(TRANSMITTERS[0]); + if (selector != bytes4(0)) { + vm.expectRevert(selector); + } registry.transmit(reportContext, reportBytes, rs, ss, vs); vm.stopPrank(); } diff --git a/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts b/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts index f993271fbb..3f28a4410b 100644 --- a/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts +++ b/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts @@ -3106,44 +3106,6 @@ describe('AutomationRegistry2_3', () => { await getTransmitTx(registry, keeper1, [upkeepId2]) }) - it('reverts if called on a non existing ID', async () => { - await evmRevertCustomError( - registry - .connect(admin) - .withdrawFunds(upkeepId.add(1), await payee1.getAddress()), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('reverts if called by anyone but the admin', async () => { - await evmRevertCustomError( - registry - .connect(owner) - .withdrawFunds(upkeepId, await payee1.getAddress()), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('reverts if called on an uncanceled upkeep', async () => { - await evmRevertCustomError( - registry - .connect(admin) - .withdrawFunds(upkeepId, await payee1.getAddress()), - registry, - 'UpkeepNotCanceled', - ) - }) - - it('reverts if called with the 0 address', async () => { - await evmRevertCustomError( - registry.connect(admin).withdrawFunds(upkeepId, zeroAddress), - registry, - 'InvalidRecipient', - ) - }) - describe('after the registration is paused, then cancelled', () => { it('allows the admin to withdraw', async () => { const balance = await registry.getBalance(upkeepId) @@ -3513,46 +3475,6 @@ describe('AutomationRegistry2_3', () => { }) }) - describe('#getActiveUpkeepIDs', () => { - it('reverts if startIndex is out of bounds ', async () => { - await evmRevertCustomError( - registry.getActiveUpkeepIDs(numUpkeeps, 0), - registry, - 'IndexOutOfRange', - ) - await evmRevertCustomError( - registry.getActiveUpkeepIDs(numUpkeeps + 1, 0), - registry, - 'IndexOutOfRange', - ) - }) - - it('returns upkeep IDs bounded by maxCount', async () => { - let upkeepIds = await registry.getActiveUpkeepIDs(0, 1) - assert(upkeepIds.length == 1) - assert(upkeepIds[0].eq(upkeepId)) - upkeepIds = await registry.getActiveUpkeepIDs(1, 3) - assert(upkeepIds.length == 3) - expect(upkeepIds).to.deep.equal([ - afUpkeepId, - logUpkeepId, - streamsLookupUpkeepId, - ]) - }) - - it('returns as many ids as possible if maxCount > num available', async () => { - const upkeepIds = await registry.getActiveUpkeepIDs(1, numUpkeeps + 100) - assert(upkeepIds.length == numUpkeeps - 1) - }) - - it('returns all upkeep IDs if maxCount is 0', async () => { - let upkeepIds = await registry.getActiveUpkeepIDs(0, 0) - assert(upkeepIds.length == numUpkeeps) - upkeepIds = await registry.getActiveUpkeepIDs(2, 0) - assert(upkeepIds.length == numUpkeeps - 2) - }) - }) - describe('#getMaxPaymentForGas', () => { let maxl1CostWeiArbWithoutMultiplier: BigNumber let maxl1CostWeiOptWithoutMultiplier: BigNumber @@ -4224,1140 +4146,180 @@ describe('AutomationRegistry2_3', () => { }) }) - describe('#setPeerRegistryMigrationPermission() / #getPeerRegistryMigrationPermission()', () => { - const peer = randomAddress() - it('allows the owner to set the peer registries', async () => { - let permission = await registry.getPeerRegistryMigrationPermission(peer) - expect(permission).to.equal(0) - await registry.setPeerRegistryMigrationPermission(peer, 1) - permission = await registry.getPeerRegistryMigrationPermission(peer) - expect(permission).to.equal(1) - await registry.setPeerRegistryMigrationPermission(peer, 2) - permission = await registry.getPeerRegistryMigrationPermission(peer) - expect(permission).to.equal(2) - await registry.setPeerRegistryMigrationPermission(peer, 0) - permission = await registry.getPeerRegistryMigrationPermission(peer) - expect(permission).to.equal(0) - }) - it('reverts if passed an unsupported permission', async () => { - await expect( - registry.connect(admin).setPeerRegistryMigrationPermission(peer, 10), - ).to.be.reverted - }) - it('reverts if not called by the owner', async () => { - await expect( - registry.connect(admin).setPeerRegistryMigrationPermission(peer, 1), - ).to.be.revertedWith('Only callable by owner') - }) - }) - - describe('#pauseUpkeep', () => { - it('reverts if the registration does not exist', async () => { - await evmRevertCustomError( - registry.connect(keeper1).pauseUpkeep(upkeepId.add(1)), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('reverts if the upkeep is already canceled', async () => { - await registry.connect(admin).cancelUpkeep(upkeepId) - - await evmRevertCustomError( - registry.connect(admin).pauseUpkeep(upkeepId), - registry, - 'UpkeepCancelled', - ) - }) - - it('reverts if the upkeep is already paused', async () => { - await registry.connect(admin).pauseUpkeep(upkeepId) - - await evmRevertCustomError( - registry.connect(admin).pauseUpkeep(upkeepId), - registry, - 'OnlyUnpausedUpkeep', - ) - }) - - it('reverts if the caller is not the upkeep admin', async () => { - await evmRevertCustomError( - registry.connect(keeper1).pauseUpkeep(upkeepId), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('pauses the upkeep and emits an event', async () => { - const tx = await registry.connect(admin).pauseUpkeep(upkeepId) - await expect(tx).to.emit(registry, 'UpkeepPaused').withArgs(upkeepId) + describe('#cancelUpkeep', () => { + describe('when called by the owner', async () => { + it('immediately prevents upkeep', async () => { + await registry.connect(owner).cancelUpkeep(upkeepId) - const registration = await registry.getUpkeep(upkeepId) - assert.equal(registration.paused, true) + const tx = await getTransmitTx(registry, keeper1, [upkeepId]) + const receipt = await tx.wait() + const cancelledUpkeepReportLogs = + parseCancelledUpkeepReportLogs(receipt) + // exactly 1 CancelledUpkeepReport log should be emitted + assert.equal(cancelledUpkeepReportLogs.length, 1) + }) }) - }) - describe('#unpauseUpkeep', () => { - it('reverts if the registration does not exist', async () => { - await evmRevertCustomError( - registry.connect(keeper1).unpauseUpkeep(upkeepId.add(1)), - registry, - 'OnlyCallableByAdmin', - ) - }) + describe('when called by the admin', async () => { + it('immediately prevents upkeep', async () => { + await linkToken.connect(owner).approve(registry.address, toWei('100')) + await registry.connect(owner).addFunds(upkeepId, toWei('100')) + await registry.connect(admin).cancelUpkeep(upkeepId) - it('reverts if the upkeep is already canceled', async () => { - await registry.connect(owner).cancelUpkeep(upkeepId) + await getTransmitTx(registry, keeper1, [upkeepId]) - await evmRevertCustomError( - registry.connect(admin).unpauseUpkeep(upkeepId), - registry, - 'UpkeepCancelled', - ) - }) + for (let i = 0; i < cancellationDelay; i++) { + await ethers.provider.send('evm_mine', []) + } - it('marks the contract as paused', async () => { - assert.isFalse((await registry.getState()).state.paused) + const tx = await getTransmitTx(registry, keeper1, [upkeepId]) - await registry.connect(owner).pause() + const receipt = await tx.wait() + const cancelledUpkeepReportLogs = + parseCancelledUpkeepReportLogs(receipt) + // exactly 1 CancelledUpkeepReport log should be emitted + assert.equal(cancelledUpkeepReportLogs.length, 1) + }) - assert.isTrue((await registry.getState()).state.paused) - }) + describeMaybe('when an upkeep has been performed', async () => { + beforeEach(async () => { + await linkToken.connect(owner).approve(registry.address, toWei('100')) + await registry.connect(owner).addFunds(upkeepId, toWei('100')) + await getTransmitTx(registry, keeper1, [upkeepId]) + }) - it('reverts if the upkeep is not paused', async () => { - await evmRevertCustomError( - registry.connect(admin).unpauseUpkeep(upkeepId), - registry, - 'OnlyPausedUpkeep', - ) - }) + it('deducts a cancellation fee from the upkeep and adds to reserve', async () => { + const newMinUpkeepSpend = toWei('10') + const financeAdminAddress = await financeAdmin.getAddress() - it('reverts if the caller is not the upkeep admin', async () => { - await registry.connect(admin).pauseUpkeep(upkeepId) + await registry.connect(owner).setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + { + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + fallbackNativePrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, + reorgProtectionEnabled: true, + financeAdmin: financeAdminAddress, + }, + offchainVersion, + offchainBytes, + [linkToken.address], + [ + { + gasFeePPB: paymentPremiumPPB, + flatFeeMilliCents, + priceFeed: linkUSDFeed.address, + fallbackPrice: fallbackLinkPrice, + minSpend: newMinUpkeepSpend, + decimals: 18, + }, + ], + ) - const registration = await registry.getUpkeep(upkeepId) + const payee1Before = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const upkeepBefore = (await registry.getUpkeep(upkeepId)).balance + const ownerBefore = await registry.linkAvailableForPayment() - assert.equal(registration.paused, true) + const amountSpent = toWei('100').sub(upkeepBefore) + const cancellationFee = newMinUpkeepSpend.sub(amountSpent) - await evmRevertCustomError( - registry.connect(keeper1).unpauseUpkeep(upkeepId), - registry, - 'OnlyCallableByAdmin', - ) - }) + await registry.connect(admin).cancelUpkeep(upkeepId) - it('unpauses the upkeep and emits an event', async () => { - const originalCount = (await registry.getActiveUpkeepIDs(0, 0)).length + const payee1After = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const upkeepAfter = (await registry.getUpkeep(upkeepId)).balance + const ownerAfter = await registry.linkAvailableForPayment() - await registry.connect(admin).pauseUpkeep(upkeepId) + // post upkeep balance should be previous balance minus cancellation fee + assert.isTrue(upkeepBefore.sub(cancellationFee).eq(upkeepAfter)) + // payee balance should not change + assert.isTrue(payee1Before.eq(payee1After)) + // owner should receive the cancellation fee + assert.isTrue(ownerAfter.sub(ownerBefore).eq(cancellationFee)) + }) - const tx = await registry.connect(admin).unpauseUpkeep(upkeepId) + it('deducts up to balance as cancellation fee', async () => { + // Very high min spend, should deduct whole balance as cancellation fees + const newMinUpkeepSpend = toWei('1000') + const financeAdminAddress = await financeAdmin.getAddress() - await expect(tx).to.emit(registry, 'UpkeepUnpaused').withArgs(upkeepId) + await registry.connect(owner).setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + { + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + fallbackNativePrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, + reorgProtectionEnabled: true, + financeAdmin: financeAdminAddress, + }, + offchainVersion, + offchainBytes, + [linkToken.address], + [ + { + gasFeePPB: paymentPremiumPPB, + flatFeeMilliCents, + priceFeed: linkUSDFeed.address, + fallbackPrice: fallbackLinkPrice, + minSpend: newMinUpkeepSpend, + decimals: 18, + }, + ], + ) + const payee1Before = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const upkeepBefore = (await registry.getUpkeep(upkeepId)).balance + const ownerBefore = await registry.linkAvailableForPayment() - const registration = await registry.getUpkeep(upkeepId) - assert.equal(registration.paused, false) + await registry.connect(admin).cancelUpkeep(upkeepId) + const payee1After = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const ownerAfter = await registry.linkAvailableForPayment() + const upkeepAfter = (await registry.getUpkeep(upkeepId)).balance - const upkeepIds = await registry.getActiveUpkeepIDs(0, 0) - assert.equal(upkeepIds.length, originalCount) - }) - }) + // all upkeep balance is deducted for cancellation fee + assert.equal(upkeepAfter.toNumber(), 0) + // payee balance should not change + assert.isTrue(payee1After.eq(payee1Before)) + // all upkeep balance is transferred to the owner + assert.isTrue(ownerAfter.sub(ownerBefore).eq(upkeepBefore)) + }) - describe('#setUpkeepCheckData', () => { - it('reverts if the registration does not exist', async () => { - await evmRevertCustomError( - registry - .connect(keeper1) - .setUpkeepCheckData(upkeepId.add(1), randomBytes), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('reverts if the caller is not upkeep admin', async () => { - await evmRevertCustomError( - registry.connect(keeper1).setUpkeepCheckData(upkeepId, randomBytes), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('reverts if the upkeep is cancelled', async () => { - await registry.connect(admin).cancelUpkeep(upkeepId) - - await evmRevertCustomError( - registry.connect(admin).setUpkeepCheckData(upkeepId, randomBytes), - registry, - 'UpkeepCancelled', - ) - }) - - it('is allowed to update on paused upkeep', async () => { - await registry.connect(admin).pauseUpkeep(upkeepId) - await registry.connect(admin).setUpkeepCheckData(upkeepId, randomBytes) - - const registration = await registry.getUpkeep(upkeepId) - assert.equal(randomBytes, registration.checkData) - }) - - it('reverts if new data exceeds limit', async () => { - let longBytes = '0x' - for (let i = 0; i < 10000; i++) { - longBytes += '1' - } - - await evmRevertCustomError( - registry.connect(admin).setUpkeepCheckData(upkeepId, longBytes), - registry, - 'CheckDataExceedsLimit', - ) - }) - - it('updates the upkeep check data and emits an event', async () => { - const tx = await registry - .connect(admin) - .setUpkeepCheckData(upkeepId, randomBytes) - await expect(tx) - .to.emit(registry, 'UpkeepCheckDataSet') - .withArgs(upkeepId, randomBytes) - - const registration = await registry.getUpkeep(upkeepId) - assert.equal(randomBytes, registration.checkData) - }) - }) - - describe('#setUpkeepGasLimit', () => { - const newGasLimit = BigNumber.from('300000') - - it('reverts if the registration does not exist', async () => { - await evmRevertCustomError( - registry.connect(admin).setUpkeepGasLimit(upkeepId.add(1), newGasLimit), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('reverts if the upkeep is canceled', async () => { - await registry.connect(admin).cancelUpkeep(upkeepId) - await evmRevertCustomError( - registry.connect(admin).setUpkeepGasLimit(upkeepId, newGasLimit), - registry, - 'UpkeepCancelled', - ) - }) - - it('reverts if called by anyone but the admin', async () => { - await evmRevertCustomError( - registry.connect(owner).setUpkeepGasLimit(upkeepId, newGasLimit), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('reverts if new gas limit is out of bounds', async () => { - await evmRevertCustomError( - registry - .connect(admin) - .setUpkeepGasLimit(upkeepId, BigNumber.from('100')), - registry, - 'GasLimitOutsideRange', - ) - await evmRevertCustomError( - registry - .connect(admin) - .setUpkeepGasLimit(upkeepId, BigNumber.from('6000000')), - registry, - 'GasLimitOutsideRange', - ) - }) - - it('updates the gas limit successfully', async () => { - const initialGasLimit = (await registry.getUpkeep(upkeepId)).performGas - assert.equal(initialGasLimit, performGas.toNumber()) - await registry.connect(admin).setUpkeepGasLimit(upkeepId, newGasLimit) - const updatedGasLimit = (await registry.getUpkeep(upkeepId)).performGas - assert.equal(updatedGasLimit, newGasLimit.toNumber()) - }) - - it('emits a log', async () => { - const tx = await registry - .connect(admin) - .setUpkeepGasLimit(upkeepId, newGasLimit) - await expect(tx) - .to.emit(registry, 'UpkeepGasLimitSet') - .withArgs(upkeepId, newGasLimit) - }) - }) - - describe('#setUpkeepOffchainConfig', () => { - const newConfig = '0xc0ffeec0ffee' - - it('reverts if the registration does not exist', async () => { - await evmRevertCustomError( - registry - .connect(admin) - .setUpkeepOffchainConfig(upkeepId.add(1), newConfig), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('reverts if the upkeep is canceled', async () => { - await registry.connect(admin).cancelUpkeep(upkeepId) - await evmRevertCustomError( - registry.connect(admin).setUpkeepOffchainConfig(upkeepId, newConfig), - registry, - 'UpkeepCancelled', - ) - }) - - it('reverts if called by anyone but the admin', async () => { - await evmRevertCustomError( - registry.connect(owner).setUpkeepOffchainConfig(upkeepId, newConfig), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('updates the config successfully', async () => { - const initialConfig = (await registry.getUpkeep(upkeepId)).offchainConfig - assert.equal(initialConfig, '0x') - await registry.connect(admin).setUpkeepOffchainConfig(upkeepId, newConfig) - const updatedConfig = (await registry.getUpkeep(upkeepId)).offchainConfig - assert.equal(newConfig, updatedConfig) - }) - - it('emits a log', async () => { - const tx = await registry - .connect(admin) - .setUpkeepOffchainConfig(upkeepId, newConfig) - await expect(tx) - .to.emit(registry, 'UpkeepOffchainConfigSet') - .withArgs(upkeepId, newConfig) - }) - }) - - describe('#setUpkeepTriggerConfig', () => { - const newConfig = '0xdeadbeef' - - it('reverts if the registration does not exist', async () => { - await evmRevertCustomError( - registry - .connect(admin) - .setUpkeepTriggerConfig(upkeepId.add(1), newConfig), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('reverts if the upkeep is canceled', async () => { - await registry.connect(admin).cancelUpkeep(upkeepId) - await evmRevertCustomError( - registry.connect(admin).setUpkeepTriggerConfig(upkeepId, newConfig), - registry, - 'UpkeepCancelled', - ) - }) - - it('reverts if called by anyone but the admin', async () => { - await evmRevertCustomError( - registry.connect(owner).setUpkeepTriggerConfig(upkeepId, newConfig), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('emits a log', async () => { - const tx = await registry - .connect(admin) - .setUpkeepTriggerConfig(upkeepId, newConfig) - await expect(tx) - .to.emit(registry, 'UpkeepTriggerConfigSet') - .withArgs(upkeepId, newConfig) - }) - }) - - describe('#transferUpkeepAdmin', () => { - it('reverts when called by anyone but the current upkeep admin', async () => { - await evmRevertCustomError( - registry - .connect(payee1) - .transferUpkeepAdmin(upkeepId, await payee2.getAddress()), - registry, - 'OnlyCallableByAdmin', - ) - }) - - it('reverts when transferring to self', async () => { - await evmRevertCustomError( - registry - .connect(admin) - .transferUpkeepAdmin(upkeepId, await admin.getAddress()), - registry, - 'ValueNotChanged', - ) - }) - - it('reverts when the upkeep is cancelled', async () => { - await registry.connect(admin).cancelUpkeep(upkeepId) - - await evmRevertCustomError( - registry - .connect(admin) - .transferUpkeepAdmin(upkeepId, await keeper1.getAddress()), - registry, - 'UpkeepCancelled', - ) - }) - - it('allows cancelling transfer by reverting to zero address', async () => { - await registry - .connect(admin) - .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) - const tx = await registry - .connect(admin) - .transferUpkeepAdmin(upkeepId, ethers.constants.AddressZero) - - await expect(tx) - .to.emit(registry, 'UpkeepAdminTransferRequested') - .withArgs( - upkeepId, - await admin.getAddress(), - ethers.constants.AddressZero, - ) - }) - - it('does not change the upkeep admin', async () => { - await registry - .connect(admin) - .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) - - const upkeep = await registry.getUpkeep(upkeepId) - assert.equal(await admin.getAddress(), upkeep.admin) - }) - - it('emits an event announcing the new upkeep admin', async () => { - const tx = await registry - .connect(admin) - .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) - - await expect(tx) - .to.emit(registry, 'UpkeepAdminTransferRequested') - .withArgs(upkeepId, await admin.getAddress(), await payee1.getAddress()) - }) - - it('does not emit an event when called with the same proposed upkeep admin', async () => { - await registry - .connect(admin) - .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) - - const tx = await registry - .connect(admin) - .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) - const receipt = await tx.wait() - assert.equal(receipt.logs.length, 0) - }) - }) - - describe('#acceptUpkeepAdmin', () => { - beforeEach(async () => { - // Start admin transfer to payee1 - await registry - .connect(admin) - .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) - }) - - it('reverts when not called by the proposed upkeep admin', async () => { - await evmRevertCustomError( - registry.connect(payee2).acceptUpkeepAdmin(upkeepId), - registry, - 'OnlyCallableByProposedAdmin', - ) - }) - - it('reverts when the upkeep is cancelled', async () => { - await registry.connect(admin).cancelUpkeep(upkeepId) - - await evmRevertCustomError( - registry.connect(payee1).acceptUpkeepAdmin(upkeepId), - registry, - 'UpkeepCancelled', - ) - }) - - it('does change the admin', async () => { - await registry.connect(payee1).acceptUpkeepAdmin(upkeepId) - - const upkeep = await registry.getUpkeep(upkeepId) - assert.equal(await payee1.getAddress(), upkeep.admin) - }) - - it('emits an event announcing the new upkeep admin', async () => { - const tx = await registry.connect(payee1).acceptUpkeepAdmin(upkeepId) - await expect(tx) - .to.emit(registry, 'UpkeepAdminTransferred') - .withArgs(upkeepId, await admin.getAddress(), await payee1.getAddress()) - }) - }) - - describe('#withdrawOwnerFunds', () => { - it('can only be called by finance admin', async () => { - await evmRevertCustomError( - registry.connect(keeper1).withdrawLink(zeroAddress, 1), - registry, - 'OnlyFinanceAdmin', - ) - }) - - itMaybe('withdraws the collected fees to owner', async () => { - await registry.connect(admin).addFunds(upkeepId, toWei('100')) - const financeAdminAddress = await financeAdmin.getAddress() - // Very high min spend, whole balance as cancellation fees - const newMinUpkeepSpend = toWei('1000') - await registry.connect(owner).setConfigTypeSafe( - signerAddresses, - keeperAddresses, - f, - { - checkGasLimit, - stalenessSeconds, - gasCeilingMultiplier, - maxCheckDataSize, - maxPerformDataSize, - maxRevertDataSize, - maxPerformGas, - fallbackGasPrice, - fallbackLinkPrice, - fallbackNativePrice, - transcoder: transcoder.address, - registrars: [], - upkeepPrivilegeManager: upkeepManager, - chainModule: chainModuleBase.address, - reorgProtectionEnabled: true, - financeAdmin: financeAdminAddress, - }, - offchainVersion, - offchainBytes, - [linkToken.address], - [ - { - gasFeePPB: paymentPremiumPPB, - flatFeeMilliCents, - priceFeed: linkUSDFeed.address, - fallbackPrice: fallbackLinkPrice, - minSpend: newMinUpkeepSpend, - decimals: 18, - }, - ], - ) - const upkeepBalance = (await registry.getUpkeep(upkeepId)).balance - const ownerBefore = await linkToken.balanceOf(await owner.getAddress()) - - await registry.connect(owner).cancelUpkeep(upkeepId) - - // Transfered to owner balance on registry - let ownerRegistryBalance = await registry.linkAvailableForPayment() - assert.isTrue(ownerRegistryBalance.eq(upkeepBalance)) - - // Now withdraw - await registry - .connect(financeAdmin) - .withdrawLink(await owner.getAddress(), ownerRegistryBalance) - - ownerRegistryBalance = await registry.linkAvailableForPayment() - const ownerAfter = await linkToken.balanceOf(await owner.getAddress()) - - // Owner registry balance should be changed to 0 - assert.isTrue(ownerRegistryBalance.eq(BigNumber.from('0'))) - - // Owner should be credited with the balance - assert.isTrue(ownerBefore.add(upkeepBalance).eq(ownerAfter)) - }) - }) - - describe('#transferPayeeship', () => { - it('reverts when called by anyone but the current payee', async () => { - await evmRevertCustomError( - registry - .connect(payee2) - .transferPayeeship( - await keeper1.getAddress(), - await payee2.getAddress(), - ), - registry, - 'OnlyCallableByPayee', - ) - }) - - it('reverts when transferring to self', async () => { - await evmRevertCustomError( - registry - .connect(payee1) - .transferPayeeship( - await keeper1.getAddress(), - await payee1.getAddress(), - ), - registry, - 'ValueNotChanged', - ) - }) - - it('does not change the payee', async () => { - await registry - .connect(payee1) - .transferPayeeship( - await keeper1.getAddress(), - await payee2.getAddress(), - ) - - const info = await registry.getTransmitterInfo(await keeper1.getAddress()) - assert.equal(await payee1.getAddress(), info.payee) - }) - - it('emits an event announcing the new payee', async () => { - const tx = await registry - .connect(payee1) - .transferPayeeship( - await keeper1.getAddress(), - await payee2.getAddress(), - ) - await expect(tx) - .to.emit(registry, 'PayeeshipTransferRequested') - .withArgs( - await keeper1.getAddress(), - await payee1.getAddress(), - await payee2.getAddress(), - ) - }) - - it('does not emit an event when called with the same proposal', async () => { - await registry - .connect(payee1) - .transferPayeeship( - await keeper1.getAddress(), - await payee2.getAddress(), - ) - - const tx = await registry - .connect(payee1) - .transferPayeeship( - await keeper1.getAddress(), - await payee2.getAddress(), - ) - const receipt = await tx.wait() - assert.equal(receipt.logs.length, 0) - }) - }) - - describe('#acceptPayeeship', () => { - beforeEach(async () => { - await registry - .connect(payee1) - .transferPayeeship( - await keeper1.getAddress(), - await payee2.getAddress(), - ) - }) - - it('reverts when called by anyone but the proposed payee', async () => { - await evmRevertCustomError( - registry.connect(payee1).acceptPayeeship(await keeper1.getAddress()), - registry, - 'OnlyCallableByProposedPayee', - ) - }) - - it('emits an event announcing the new payee', async () => { - const tx = await registry - .connect(payee2) - .acceptPayeeship(await keeper1.getAddress()) - await expect(tx) - .to.emit(registry, 'PayeeshipTransferred') - .withArgs( - await keeper1.getAddress(), - await payee1.getAddress(), - await payee2.getAddress(), - ) - }) - - it('does change the payee', async () => { - await registry.connect(payee2).acceptPayeeship(await keeper1.getAddress()) - - const info = await registry.getTransmitterInfo(await keeper1.getAddress()) - assert.equal(await payee2.getAddress(), info.payee) - }) - }) - - describe('#pause', () => { - it('reverts if called by a non-owner', async () => { - await evmRevert( - registry.connect(keeper1).pause(), - 'Only callable by owner', - ) - }) - - it('marks the contract as paused', async () => { - assert.isFalse((await registry.getState()).state.paused) - - await registry.connect(owner).pause() - - assert.isTrue((await registry.getState()).state.paused) - }) - - it('Does not allow transmits when paused', async () => { - await registry.connect(owner).pause() - - await evmRevertCustomError( - getTransmitTx(registry, keeper1, [upkeepId]), - registry, - 'RegistryPaused', - ) - }) - - it('Does not allow creation of new upkeeps when paused', async () => { - await registry.connect(owner).pause() - - await evmRevertCustomError( - registry - .connect(owner) - .registerUpkeep( - mock.address, - performGas, - await admin.getAddress(), - Trigger.CONDITION, - linkToken.address, - '0x', - '0x', - '0x', - ), - registry, - 'RegistryPaused', - ) - }) - }) - - describe('#unpause', () => { - beforeEach(async () => { - await registry.connect(owner).pause() - }) - - it('reverts if called by a non-owner', async () => { - await evmRevert( - registry.connect(keeper1).unpause(), - 'Only callable by owner', - ) - }) - - it('marks the contract as not paused', async () => { - assert.isTrue((await registry.getState()).state.paused) - - await registry.connect(owner).unpause() - - assert.isFalse((await registry.getState()).state.paused) - }) - }) - - describe('#setPayees', () => { - const IGNORE_ADDRESS = '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF' - - it('reverts when not called by the owner', async () => { - await evmRevert( - registry.connect(keeper1).setPayees(payees), - 'Only callable by owner', - ) - }) - - it('reverts with different numbers of payees than transmitters', async () => { - await evmRevertCustomError( - registry.connect(owner).setPayees([...payees, randomAddress()]), - registry, - 'ParameterLengthError', - ) - }) - - it('reverts if the payee is the zero address', async () => { - await blankRegistry.connect(owner).setConfigTypeSafe(...baseConfig) // used to test initial config - - await evmRevertCustomError( - blankRegistry // used to test initial config - .connect(owner) - .setPayees([ethers.constants.AddressZero, ...payees.slice(1)]), - registry, - 'InvalidPayee', - ) - }) - - itMaybe( - 'sets the payees when exisitng payees are zero address', - async () => { - //Initial payees should be zero address - await blankRegistry.connect(owner).setConfigTypeSafe(...baseConfig) // used to test initial config - - for (let i = 0; i < keeperAddresses.length; i++) { - const payee = ( - await blankRegistry.getTransmitterInfo(keeperAddresses[i]) - ).payee // used to test initial config - assert.equal(payee, zeroAddress) - } - - await blankRegistry.connect(owner).setPayees(payees) // used to test initial config - - for (let i = 0; i < keeperAddresses.length; i++) { - const payee = ( - await blankRegistry.getTransmitterInfo(keeperAddresses[i]) - ).payee - assert.equal(payee, payees[i]) - } - }, - ) - - it('does not change the payee if IGNORE_ADDRESS is used as payee', async () => { - const signers = Array.from({ length: 5 }, randomAddress) - const keepers = Array.from({ length: 5 }, randomAddress) - const payees = Array.from({ length: 5 }, randomAddress) - const newTransmitter = randomAddress() - const newPayee = randomAddress() - const ignoreAddresses = new Array(payees.length).fill(IGNORE_ADDRESS) - const newPayees = [...ignoreAddresses, newPayee] - // arbitrum registry - // configure registry with 5 keepers // optimism registry - await blankRegistry // used to test initial configurations - .connect(owner) - .setConfigTypeSafe( - signers, - keepers, - f, - config, - offchainVersion, - offchainBytes, - [], - [], - ) - // arbitrum registry - // set initial payees // optimism registry - await blankRegistry.connect(owner).setPayees(payees) // used to test initial configurations - // arbitrum registry - // add another keeper // optimism registry - await blankRegistry // used to test initial configurations - .connect(owner) - .setConfigTypeSafe( - [...signers, randomAddress()], - [...keepers, newTransmitter], - f, - config, - offchainVersion, - offchainBytes, - [], - [], - ) - // arbitrum registry - // update payee list // optimism registry // arbitrum registry - await blankRegistry.connect(owner).setPayees(newPayees) // used to test initial configurations // optimism registry - const ignored = await blankRegistry.getTransmitterInfo(newTransmitter) // used to test initial configurations - assert.equal(newPayee, ignored.payee) - assert.equal(ignored.active, true) - }) - - it('reverts if payee is non zero and owner tries to change payee', async () => { - const newPayees = [randomAddress(), ...payees.slice(1)] - - await evmRevertCustomError( - registry.connect(owner).setPayees(newPayees), - registry, - 'InvalidPayee', - ) - }) - - it('emits events for every payee added and removed', async () => { - const tx = await registry.connect(owner).setPayees(payees) - await expect(tx) - .to.emit(registry, 'PayeesUpdated') - .withArgs(keeperAddresses, payees) - }) - }) - - describe('#cancelUpkeep', () => { - it('reverts if the ID is not valid', async () => { - await evmRevertCustomError( - registry.connect(owner).cancelUpkeep(upkeepId.add(1)), - registry, - 'CannotCancel', - ) - }) - - it('reverts if called by a non-owner/non-admin', async () => { - await evmRevertCustomError( - registry.connect(keeper1).cancelUpkeep(upkeepId), - registry, - 'OnlyCallableByOwnerOrAdmin', - ) - }) - - describe('when called by the owner', async () => { - it('sets the registration to invalid immediately', async () => { - const tx = await registry.connect(owner).cancelUpkeep(upkeepId) - const receipt = await tx.wait() - const registration = await registry.getUpkeep(upkeepId) - assert.equal( - registration.maxValidBlocknumber.toNumber(), - receipt.blockNumber, - ) - }) - - it('emits an event', async () => { - const tx = await registry.connect(owner).cancelUpkeep(upkeepId) - const receipt = await tx.wait() - await expect(tx) - .to.emit(registry, 'UpkeepCanceled') - .withArgs(upkeepId, BigNumber.from(receipt.blockNumber)) - }) - - it('immediately prevents upkeep', async () => { - await registry.connect(owner).cancelUpkeep(upkeepId) - - const tx = await getTransmitTx(registry, keeper1, [upkeepId]) - const receipt = await tx.wait() - const cancelledUpkeepReportLogs = - parseCancelledUpkeepReportLogs(receipt) - // exactly 1 CancelledUpkeepReport log should be emitted - assert.equal(cancelledUpkeepReportLogs.length, 1) - }) - - it('does not revert if reverts if called multiple times', async () => { - await registry.connect(owner).cancelUpkeep(upkeepId) - await evmRevertCustomError( - registry.connect(owner).cancelUpkeep(upkeepId), - registry, - 'UpkeepCancelled', - ) - }) - - describe('when called by the owner when the admin has just canceled', () => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - // @ts-ignore - let oldExpiration: BigNumber - - beforeEach(async () => { - await registry.connect(admin).cancelUpkeep(upkeepId) - const registration = await registry.getUpkeep(upkeepId) - oldExpiration = registration.maxValidBlocknumber - }) - - it('reverts with proper error', async () => { - await evmRevertCustomError( - registry.connect(owner).cancelUpkeep(upkeepId), - registry, - 'UpkeepCancelled', - ) - }) - }) - }) - - describe('when called by the admin', async () => { - it('reverts if called again by the admin', async () => { - await registry.connect(admin).cancelUpkeep(upkeepId) - - await evmRevertCustomError( - registry.connect(admin).cancelUpkeep(upkeepId), - registry, - 'UpkeepCancelled', - ) - }) - - it('reverts if called by the owner after the timeout', async () => { - await registry.connect(admin).cancelUpkeep(upkeepId) - - for (let i = 0; i < cancellationDelay; i++) { - await ethers.provider.send('evm_mine', []) - } - - await evmRevertCustomError( - registry.connect(owner).cancelUpkeep(upkeepId), - registry, - 'UpkeepCancelled', - ) - }) - - it('sets the registration to invalid in 50 blocks', async () => { - const tx = await registry.connect(admin).cancelUpkeep(upkeepId) - const receipt = await tx.wait() - const registration = await registry.getUpkeep(upkeepId) - assert.equal( - registration.maxValidBlocknumber.toNumber(), - receipt.blockNumber + 50, - ) - }) - - it('emits an event', async () => { - const tx = await registry.connect(admin).cancelUpkeep(upkeepId) - const receipt = await tx.wait() - await expect(tx) - .to.emit(registry, 'UpkeepCanceled') - .withArgs( - upkeepId, - BigNumber.from(receipt.blockNumber + cancellationDelay), - ) - }) - - it('immediately prevents upkeep', async () => { - await linkToken.connect(owner).approve(registry.address, toWei('100')) - await registry.connect(owner).addFunds(upkeepId, toWei('100')) - await registry.connect(admin).cancelUpkeep(upkeepId) - - await getTransmitTx(registry, keeper1, [upkeepId]) - - for (let i = 0; i < cancellationDelay; i++) { - await ethers.provider.send('evm_mine', []) - } - - const tx = await getTransmitTx(registry, keeper1, [upkeepId]) - - const receipt = await tx.wait() - const cancelledUpkeepReportLogs = - parseCancelledUpkeepReportLogs(receipt) - // exactly 1 CancelledUpkeepReport log should be emitted - assert.equal(cancelledUpkeepReportLogs.length, 1) - }) - - describeMaybe('when an upkeep has been performed', async () => { - beforeEach(async () => { - await linkToken.connect(owner).approve(registry.address, toWei('100')) - await registry.connect(owner).addFunds(upkeepId, toWei('100')) - await getTransmitTx(registry, keeper1, [upkeepId]) - }) - - it('deducts a cancellation fee from the upkeep and adds to reserve', async () => { - const newMinUpkeepSpend = toWei('10') - const financeAdminAddress = await financeAdmin.getAddress() - - await registry.connect(owner).setConfigTypeSafe( - signerAddresses, - keeperAddresses, - f, - { - checkGasLimit, - stalenessSeconds, - gasCeilingMultiplier, - maxCheckDataSize, - maxPerformDataSize, - maxRevertDataSize, - maxPerformGas, - fallbackGasPrice, - fallbackLinkPrice, - fallbackNativePrice, - transcoder: transcoder.address, - registrars: [], - upkeepPrivilegeManager: upkeepManager, - chainModule: chainModuleBase.address, - reorgProtectionEnabled: true, - financeAdmin: financeAdminAddress, - }, - offchainVersion, - offchainBytes, - [linkToken.address], - [ - { - gasFeePPB: paymentPremiumPPB, - flatFeeMilliCents, - priceFeed: linkUSDFeed.address, - fallbackPrice: fallbackLinkPrice, - minSpend: newMinUpkeepSpend, - decimals: 18, - }, - ], - ) - - const payee1Before = await linkToken.balanceOf( - await payee1.getAddress(), - ) - const upkeepBefore = (await registry.getUpkeep(upkeepId)).balance - const ownerBefore = await registry.linkAvailableForPayment() - - const amountSpent = toWei('100').sub(upkeepBefore) - const cancellationFee = newMinUpkeepSpend.sub(amountSpent) - - await registry.connect(admin).cancelUpkeep(upkeepId) - - const payee1After = await linkToken.balanceOf( - await payee1.getAddress(), - ) - const upkeepAfter = (await registry.getUpkeep(upkeepId)).balance - const ownerAfter = await registry.linkAvailableForPayment() - - // post upkeep balance should be previous balance minus cancellation fee - assert.isTrue(upkeepBefore.sub(cancellationFee).eq(upkeepAfter)) - // payee balance should not change - assert.isTrue(payee1Before.eq(payee1After)) - // owner should receive the cancellation fee - assert.isTrue(ownerAfter.sub(ownerBefore).eq(cancellationFee)) - }) - - it('deducts up to balance as cancellation fee', async () => { - // Very high min spend, should deduct whole balance as cancellation fees - const newMinUpkeepSpend = toWei('1000') - const financeAdminAddress = await financeAdmin.getAddress() - - await registry.connect(owner).setConfigTypeSafe( - signerAddresses, - keeperAddresses, - f, - { - checkGasLimit, - stalenessSeconds, - gasCeilingMultiplier, - maxCheckDataSize, - maxPerformDataSize, - maxRevertDataSize, - maxPerformGas, - fallbackGasPrice, - fallbackLinkPrice, - fallbackNativePrice, - transcoder: transcoder.address, - registrars: [], - upkeepPrivilegeManager: upkeepManager, - chainModule: chainModuleBase.address, - reorgProtectionEnabled: true, - financeAdmin: financeAdminAddress, - }, - offchainVersion, - offchainBytes, - [linkToken.address], - [ - { - gasFeePPB: paymentPremiumPPB, - flatFeeMilliCents, - priceFeed: linkUSDFeed.address, - fallbackPrice: fallbackLinkPrice, - minSpend: newMinUpkeepSpend, - decimals: 18, - }, - ], - ) - const payee1Before = await linkToken.balanceOf( - await payee1.getAddress(), - ) - const upkeepBefore = (await registry.getUpkeep(upkeepId)).balance - const ownerBefore = await registry.linkAvailableForPayment() - - await registry.connect(admin).cancelUpkeep(upkeepId) - const payee1After = await linkToken.balanceOf( - await payee1.getAddress(), - ) - const ownerAfter = await registry.linkAvailableForPayment() - const upkeepAfter = (await registry.getUpkeep(upkeepId)).balance - - // all upkeep balance is deducted for cancellation fee - assert.equal(upkeepAfter.toNumber(), 0) - // payee balance should not change - assert.isTrue(payee1After.eq(payee1Before)) - // all upkeep balance is transferred to the owner - assert.isTrue(ownerAfter.sub(ownerBefore).eq(upkeepBefore)) - }) - - it('does not deduct cancellation fee if more than minUpkeepSpendDollars is spent', async () => { - // Very low min spend, already spent in one perform upkeep - const newMinUpkeepSpend = BigNumber.from(420) - const financeAdminAddress = await financeAdmin.getAddress() + it('does not deduct cancellation fee if more than minUpkeepSpendDollars is spent', async () => { + // Very low min spend, already spent in one perform upkeep + const newMinUpkeepSpend = BigNumber.from(420) + const financeAdminAddress = await financeAdmin.getAddress() await registry.connect(owner).setConfigTypeSafe( signerAddresses, @@ -5594,62 +4556,6 @@ describe('AutomationRegistry2_3', () => { }) }) - describe('#setUpkeepPrivilegeConfig() / #getUpkeepPrivilegeConfig()', () => { - it('reverts when non manager tries to set privilege config', async () => { - await evmRevertCustomError( - registry.connect(payee3).setUpkeepPrivilegeConfig(upkeepId, '0x1234'), - registry, - 'OnlyCallableByUpkeepPrivilegeManager', - ) - }) - - it('returns empty bytes for upkeep privilege config before setting', async () => { - const cfg = await registry.getUpkeepPrivilegeConfig(upkeepId) - assert.equal(cfg, '0x') - }) - - it('allows upkeep manager to set privilege config', async () => { - const tx = await registry - .connect(personas.Norbert) - .setUpkeepPrivilegeConfig(upkeepId, '0x1234') - await expect(tx) - .to.emit(registry, 'UpkeepPrivilegeConfigSet') - .withArgs(upkeepId, '0x1234') - - const cfg = await registry.getUpkeepPrivilegeConfig(upkeepId) - assert.equal(cfg, '0x1234') - }) - }) - - describe('#setAdminPrivilegeConfig() / #getAdminPrivilegeConfig()', () => { - const admin = randomAddress() - - it('reverts when non manager tries to set privilege config', async () => { - await evmRevertCustomError( - registry.connect(payee3).setAdminPrivilegeConfig(admin, '0x1234'), - registry, - 'OnlyCallableByUpkeepPrivilegeManager', - ) - }) - - it('returns empty bytes for upkeep privilege config before setting', async () => { - const cfg = await registry.getAdminPrivilegeConfig(admin) - assert.equal(cfg, '0x') - }) - - it('allows upkeep manager to set privilege config', async () => { - const tx = await registry - .connect(personas.Norbert) - .setAdminPrivilegeConfig(admin, '0x1234') - await expect(tx) - .to.emit(registry, 'AdminPrivilegeConfigSet') - .withArgs(admin, '0x1234') - - const cfg = await registry.getAdminPrivilegeConfig(admin) - assert.equal(cfg, '0x1234') - }) - }) - describe('transmitterPremiumSplit [ @skip-coverage ]', () => { beforeEach(async () => { await linkToken.connect(owner).approve(registry.address, toWei('100')) From 1257d33913d243c146bccbf4bda67a2bb1c7d5af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Thu, 8 Aug 2024 05:30:17 +0300 Subject: [PATCH 056/432] Allow retrying failed transmissions (#14017) * Hardcoded value for call with exact gas * Record gasProvided in route function * Add a getter for transmission gas limit * Update snapshot * Changeset * Remove unused import * Rename to gas limit * Update gethwrappers * Uncomment test code * Remove copy/pasta comment * Slight rename * Allow retrying transmissions with more gas * Only allow retrying failed transmissions * Update snapshot * Fix state for InvalidReceiver check * Check for initial state * Actually store gas limit provided to receiver * Update gethwrappers * Remove unused struct * Correctly mark invalid receiver when receiver interface unsupported * Create TransmissionInfo struct * Update gethwrappers * Bump gas limit * Bump gas even more * Update KeystoneFeedsConsumer.sol to implement IERC165 * Use getTransmissionInfo * Use TransmissionState to determine if transmission should be created * Fix test * Fix trailing line * Update a mock to the GetLatestValue("getTransmissionInfo") call in a test * Remove TODO + replace panic with err * Remove redundant empty lines * Typo * Remove unused constant * Name mapping values --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .changeset/rich-chairs-hug.md | 5 + contracts/.changeset/polite-masks-jog.md | 5 + contracts/.gas-snapshot | 112 ++++++++++++++++++ contracts/gas-snapshots/keystone.gas-snapshot | 24 ++-- .../v0.8/keystone/KeystoneFeedsConsumer.sol | 9 +- .../src/v0.8/keystone/KeystoneForwarder.sol | 94 +++++++++++---- .../v0.8/keystone/interfaces/IReceiver.sol | 5 + .../src/v0.8/keystone/interfaces/IRouter.sol | 42 ++++++- .../test/KeystoneForwarder_ReportTest.t.sol | 82 +++++++++---- .../test/KeystoneRouter_AccessTest.t.sol | 16 ++- .../src/v0.8/keystone/test/mocks/Receiver.sol | 10 +- core/capabilities/targets/write_target.go | 46 +++++-- .../capabilities/targets/write_target_test.go | 18 ++- .../feeds_consumer/feeds_consumer.go | 28 ++++- .../keystone/generated/forwarder/forwarder.go | 31 +++-- ...rapper-dependency-versions-do-not-edit.txt | 4 +- core/services/relay/evm/write_target.go | 9 +- core/services/relay/evm/write_target_test.go | 69 ++++++++++- 18 files changed, 501 insertions(+), 108 deletions(-) create mode 100644 .changeset/rich-chairs-hug.md create mode 100644 contracts/.changeset/polite-masks-jog.md create mode 100644 contracts/.gas-snapshot diff --git a/.changeset/rich-chairs-hug.md b/.changeset/rich-chairs-hug.md new file mode 100644 index 0000000000..0408383bd0 --- /dev/null +++ b/.changeset/rich-chairs-hug.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal diff --git a/contracts/.changeset/polite-masks-jog.md b/contracts/.changeset/polite-masks-jog.md new file mode 100644 index 0000000000..93fba83b55 --- /dev/null +++ b/contracts/.changeset/polite-masks-jog.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +#internal diff --git a/contracts/.gas-snapshot b/contracts/.gas-snapshot new file mode 100644 index 0000000000..3a0354d539 --- /dev/null +++ b/contracts/.gas-snapshot @@ -0,0 +1,112 @@ +CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_NoConfigurationContract() (gas: 154832) +CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_WithConfiguration() (gas: 178813) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 24723) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CapabilityExists() (gas: 145703) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractDoesNotMatchInterface() (gas: 94606) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractNotDeployed() (gas: 92961) +CapabilitiesRegistry_AddDONTest:test_AddDON() (gas: 372302) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19273) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 169752) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 239789) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 249596) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 116890) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_FaultToleranceIsZero() (gas: 43358) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeAlreadyBelongsToWorkflowDON() (gas: 343924) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 180150) +CapabilitiesRegistry_AddNodeOperatorsTest:test_AddNodeOperators() (gas: 184135) +CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_CalledByNonAdmin() (gas: 17602) +CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_NodeOperatorAdminAddressZero() (gas: 18498) +CapabilitiesRegistry_AddNodesTest:test_AddsNodeParams() (gas: 358448) +CapabilitiesRegistry_AddNodesTest:test_OwnerCanAddNodes() (gas: 358414) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingDuplicateP2PId() (gas: 301229) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 55174) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidNodeOperator() (gas: 24895) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithoutCapabilities() (gas: 27669) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25108) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 27408) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 27047) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressNotUnique() (gas: 309679) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_DeprecatesCapability() (gas: 89807) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_EmitsEvent() (gas: 89935) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 22944) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 16231) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityIsDeprecated() (gas: 91264) +CapabilitiesRegistry_GetCapabilitiesTest:test_ReturnsCapabilities() (gas: 135553) +CapabilitiesRegistry_GetDONsTest:test_CorrectlyFetchesDONs() (gas: 65468) +CapabilitiesRegistry_GetDONsTest:test_DoesNotIncludeRemovedDONs() (gas: 64924) +CapabilitiesRegistry_GetHashedCapabilityTest:test_CorrectlyGeneratesHashedCapabilityId() (gas: 11428) +CapabilitiesRegistry_GetHashedCapabilityTest:test_DoesNotCauseIncorrectClashes() (gas: 13087) +CapabilitiesRegistry_GetNodeOperatorsTest:test_CorrectlyFetchesNodeOperators() (gas: 36407) +CapabilitiesRegistry_GetNodeOperatorsTest:test_DoesNotIncludeRemovedNodeOperators() (gas: 38692) +CapabilitiesRegistry_GetNodesTest:test_CorrectlyFetchesNodes() (gas: 65288) +CapabilitiesRegistry_GetNodesTest:test_DoesNotIncludeRemovedNodes() (gas: 73533) +CapabilitiesRegistry_RemoveDONsTest:test_RemovesDON() (gas: 54761) +CapabilitiesRegistry_RemoveDONsTest:test_RevertWhen_CalledByNonAdmin() (gas: 15647) +CapabilitiesRegistry_RemoveDONsTest:test_RevertWhen_DONDoesNotExist() (gas: 16550) +CapabilitiesRegistry_RemoveNodeOperatorsTest:test_RemovesNodeOperator() (gas: 36122) +CapabilitiesRegistry_RemoveNodeOperatorsTest:test_RevertWhen_CalledByNonOwner() (gas: 15816) +CapabilitiesRegistry_RemoveNodesTest:test_CanAddNodeWithSameSignerAddressAfterRemoving() (gas: 115151) +CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenDONDeleted() (gas: 287716) +CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenNodeNoLongerPartOfDON() (gas: 561023) +CapabilitiesRegistry_RemoveNodesTest:test_OwnerCanRemoveNodes() (gas: 73376) +CapabilitiesRegistry_RemoveNodesTest:test_RemovesNode() (gas: 75211) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25053) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 18418) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodePartOfCapabilitiesDON() (gas: 385369) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 18408) +CapabilitiesRegistry_TypeAndVersionTest:test_TypeAndVersion() (gas: 9796) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19415) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 152914) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DONDoesNotExist() (gas: 17835) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 222996) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 232804) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 107643) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 163357) +CapabilitiesRegistry_UpdateDONTest:test_UpdatesDON() (gas: 371909) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_CalledByNonAdminAndNonOwner() (gas: 20728) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorAdminIsZeroAddress() (gas: 20052) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorDoesNotExist() (gas: 19790) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorIdAndParamLengthsMismatch() (gas: 15430) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_UpdatesNodeOperator() (gas: 37034) +CapabilitiesRegistry_UpdateNodesTest:test_CanUpdateParamsIfNodeSignerAddressNoLongerUsed() (gas: 256371) +CapabilitiesRegistry_UpdateNodesTest:test_OwnerCanUpdateNodes() (gas: 162166) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 35873) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByAnotherNodeOperatorAdmin() (gas: 29200) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 29377) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 29199) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeSignerAlreadyAssignedToAnotherNode() (gas: 31326) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 29165) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByCapabilityDON() (gas: 470910) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByWorkflowDON() (gas: 341191) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 29058) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 27587) +CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162220) +KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 2002057) +KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() (gas: 128934) +KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverNotContract() (gas: 130621) +KeystoneForwarder_ReportTest:test_Report_SuccessfulDelivery() (gas: 359123) +KeystoneForwarder_ReportTest:test_Report_SuccessfulRetryWithMoreGas() (gas: 423982) +KeystoneForwarder_ReportTest:test_RevertWhen_AnySignatureIsInvalid() (gas: 86348) +KeystoneForwarder_ReportTest:test_RevertWhen_AnySignerIsInvalid() (gas: 118486) +KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasDuplicateSignatures() (gas: 94516) +KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasIncorrectDON() (gas: 75930) +KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasInexistentConfigVersion() (gas: 76320) +KeystoneForwarder_ReportTest:test_RevertWhen_ReportIsMalformed() (gas: 45585) +KeystoneForwarder_ReportTest:test_RevertWhen_RetryingInvalidContractTransmission() (gas: 143354) +KeystoneForwarder_ReportTest:test_RevertWhen_RetryingSuccessfulTransmission() (gas: 353272) +KeystoneForwarder_ReportTest:test_RevertWhen_TooFewSignatures() (gas: 55292) +KeystoneForwarder_ReportTest:test_RevertWhen_TooManySignatures() (gas: 56050) +KeystoneForwarder_SetConfigTest:test_RevertWhen_ExcessSigners() (gas: 20184) +KeystoneForwarder_SetConfigTest:test_RevertWhen_FaultToleranceIsZero() (gas: 88057) +KeystoneForwarder_SetConfigTest:test_RevertWhen_InsufficientSigners() (gas: 14533) +KeystoneForwarder_SetConfigTest:test_RevertWhen_NotOwner() (gas: 88766) +KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingDuplicateSigners() (gas: 114570) +KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingZeroAddressSigner() (gas: 114225) +KeystoneForwarder_SetConfigTest:test_SetConfig_FirstTime() (gas: 1540541) +KeystoneForwarder_SetConfigTest:test_SetConfig_WhenSignersAreRemoved() (gas: 1535211) +KeystoneForwarder_TypeAndVersionTest:test_TypeAndVersion() (gas: 9641) +KeystoneRouter_SetConfigTest:test_AddForwarder_RevertWhen_NotOwner() (gas: 10978) +KeystoneRouter_SetConfigTest:test_RemoveForwarder_RevertWhen_NotOwner() (gas: 10923) +KeystoneRouter_SetConfigTest:test_RemoveForwarder_Success() (gas: 17599) +KeystoneRouter_SetConfigTest:test_Route_RevertWhen_UnauthorizedForwarder() (gas: 18552) +KeystoneRouter_SetConfigTest:test_Route_Success() (gas: 76407) \ No newline at end of file diff --git a/contracts/gas-snapshots/keystone.gas-snapshot b/contracts/gas-snapshots/keystone.gas-snapshot index 759e287b01..49b1d4add4 100644 --- a/contracts/gas-snapshots/keystone.gas-snapshot +++ b/contracts/gas-snapshots/keystone.gas-snapshot @@ -81,17 +81,20 @@ CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredB CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 29058) CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 27587) CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162220) -KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 1798375) -KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() (gas: 125910) -KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverNotContract() (gas: 127403) -KeystoneForwarder_ReportTest:test_Report_SuccessfulDelivery() (gas: 155928) -KeystoneForwarder_ReportTest:test_RevertWhen_AlreadyAttempted() (gas: 152358) -KeystoneForwarder_ReportTest:test_RevertWhen_AnySignatureIsInvalid() (gas: 86348) -KeystoneForwarder_ReportTest:test_RevertWhen_AnySignerIsInvalid() (gas: 118486) +KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 2003568) +KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() (gas: 124908) +KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverNotContract() (gas: 126927) +KeystoneForwarder_ReportTest:test_Report_SuccessfulDelivery() (gas: 361243) +KeystoneForwarder_ReportTest:test_Report_SuccessfulRetryWithMoreGas() (gas: 501084) +KeystoneForwarder_ReportTest:test_RevertWhen_AnySignatureIsInvalid() (gas: 86326) +KeystoneForwarder_ReportTest:test_RevertWhen_AnySignerIsInvalid() (gas: 118521) +KeystoneForwarder_ReportTest:test_RevertWhen_AttemptingTransmissionWithInsufficientGas() (gas: 96279) KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasDuplicateSignatures() (gas: 94516) KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasIncorrectDON() (gas: 75930) KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasInexistentConfigVersion() (gas: 76298) -KeystoneForwarder_ReportTest:test_RevertWhen_ReportIsMalformed() (gas: 45585) +KeystoneForwarder_ReportTest:test_RevertWhen_ReportIsMalformed() (gas: 45563) +KeystoneForwarder_ReportTest:test_RevertWhen_RetryingInvalidContractTransmission() (gas: 143591) +KeystoneForwarder_ReportTest:test_RevertWhen_RetryingSuccessfulTransmission() (gas: 354042) KeystoneForwarder_ReportTest:test_RevertWhen_TooFewSignatures() (gas: 55292) KeystoneForwarder_ReportTest:test_RevertWhen_TooManySignatures() (gas: 56050) KeystoneForwarder_SetConfigTest:test_RevertWhen_ExcessSigners() (gas: 20184) @@ -105,5 +108,6 @@ KeystoneForwarder_SetConfigTest:test_SetConfig_WhenSignersAreRemoved() (gas: 153 KeystoneForwarder_TypeAndVersionTest:test_TypeAndVersion() (gas: 9641) KeystoneRouter_SetConfigTest:test_AddForwarder_RevertWhen_NotOwner() (gas: 10978) KeystoneRouter_SetConfigTest:test_RemoveForwarder_RevertWhen_NotOwner() (gas: 10923) -KeystoneRouter_SetConfigTest:test_Route_RevertWhen_UnauthorizedForwarder() (gas: 18553) -KeystoneRouter_SetConfigTest:test_Route_Success() (gas: 75629) \ No newline at end of file +KeystoneRouter_SetConfigTest:test_RemoveForwarder_Success() (gas: 17599) +KeystoneRouter_SetConfigTest:test_Route_RevertWhen_UnauthorizedForwarder() (gas: 18552) +KeystoneRouter_SetConfigTest:test_Route_Success() (gas: 79379) \ No newline at end of file diff --git a/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol b/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol index 9dc6f67560..ba1a7c6a8c 100644 --- a/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol +++ b/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol @@ -1,10 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -import {IReceiver} from "./interfaces/IReceiver.sol"; +import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol"; +import {IReceiver} from "./interfaces/IReceiver.sol"; -contract KeystoneFeedsConsumer is IReceiver, OwnerIsCreator { +contract KeystoneFeedsConsumer is IReceiver, OwnerIsCreator, IERC165 { event FeedReceived(bytes32 indexed feedId, uint224 price, uint32 timestamp); error UnauthorizedSender(address sender); @@ -97,4 +98,8 @@ contract KeystoneFeedsConsumer is IReceiver, OwnerIsCreator { StoredFeedReport memory report = s_feedReports[feedId]; return (report.Price, report.Timestamp); } + + function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { + return interfaceId == this.onReport.selector; + } } diff --git a/contracts/src/v0.8/keystone/KeystoneForwarder.sol b/contracts/src/v0.8/keystone/KeystoneForwarder.sol index b18e381cc6..f92295cab9 100644 --- a/contracts/src/v0.8/keystone/KeystoneForwarder.sol +++ b/contracts/src/v0.8/keystone/KeystoneForwarder.sol @@ -1,12 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -import {IReceiver} from "./interfaces/IReceiver.sol"; -import {IRouter} from "./interfaces/IRouter.sol"; -import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; +import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol"; +import {IReceiver} from "./interfaces/IReceiver.sol"; +import {IRouter} from "./interfaces/IRouter.sol"; + /// @notice This is an entry point for `write_${chain}` Target capability. It /// allows nodes to determine if reports have been processed (successfully or /// not) in a decentralized and product-agnostic way by recording processed @@ -66,7 +68,7 @@ contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { /// @notice Contains the configuration for each DON ID // @param configId (uint64(donId) << 32) | configVersion - mapping(uint64 configId => OracleSet) internal s_configs; + mapping(uint64 configId => OracleSet oracleSet) internal s_configs; event ConfigSet(uint32 indexed donId, uint32 indexed configVersion, uint8 f, address[] signers); @@ -90,12 +92,16 @@ contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { uint256 internal constant FORWARDER_METADATA_LENGTH = 45; uint256 internal constant SIGNATURE_LENGTH = 65; + /// @dev The gas we require to revert in case of a revert in the call to the + /// receiver. This is more than enough and does not attempt to be exact. + uint256 internal constant REQUIRED_GAS_FOR_ROUTING = 40_000; + // ================================================================ // │ Router │ // ================================================================ - mapping(address forwarder => bool) internal s_forwarders; - mapping(bytes32 transmissionId => TransmissionInfo) internal s_transmissions; + mapping(address forwarder => bool isForwarder) internal s_forwarders; + mapping(bytes32 transmissionId => Transmission transmission) internal s_transmissions; function addForwarder(address forwarder) external onlyOwner { s_forwarders[forwarder] = true; @@ -114,19 +120,38 @@ contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { bytes calldata metadata, bytes calldata validatedReport ) public returns (bool) { - if (!s_forwarders[msg.sender]) { - revert UnauthorizedForwarder(); - } + if (!s_forwarders[msg.sender]) revert UnauthorizedForwarder(); + uint256 gasLeft = gasleft(); + if (gasLeft < REQUIRED_GAS_FOR_ROUTING) revert InsufficientGasForRouting(transmissionId); - if (s_transmissions[transmissionId].transmitter != address(0)) revert AlreadyAttempted(transmissionId); + Transmission memory transmission = s_transmissions[transmissionId]; + if (transmission.success || transmission.invalidReceiver) revert AlreadyAttempted(transmissionId); + + uint256 gasLimit = gasLeft - REQUIRED_GAS_FOR_ROUTING; s_transmissions[transmissionId].transmitter = transmitter; + s_transmissions[transmissionId].gasLimit = uint80(gasLimit); + + if (receiver.code.length == 0) { + s_transmissions[transmissionId].invalidReceiver = true; + return false; + } - if (receiver.code.length == 0) return false; + try IERC165(receiver).supportsInterface(type(IReceiver).interfaceId) { + bool success; + bytes memory payload = abi.encodeCall(IReceiver.onReport, (metadata, validatedReport)); - try IReceiver(receiver).onReport(metadata, validatedReport) { - s_transmissions[transmissionId].success = true; - return true; + assembly { + // call and return whether we succeeded. ignore return data + // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) + success := call(gasLimit, receiver, 0, add(payload, 0x20), mload(payload), 0x0, 0x0) + } + + if (success) { + s_transmissions[transmissionId].success = true; + } + return success; } catch { + s_transmissions[transmissionId].invalidReceiver = true; return false; } } @@ -141,26 +166,43 @@ contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { return keccak256(bytes.concat(bytes20(uint160(receiver)), workflowExecutionId, reportId)); } - /// @notice Get transmitter of a given report or 0x0 if it wasn't transmitted yet - function getTransmitter( + function getTransmissionInfo( address receiver, bytes32 workflowExecutionId, bytes2 reportId - ) external view returns (address) { - return s_transmissions[getTransmissionId(receiver, workflowExecutionId, reportId)].transmitter; + ) external view returns (TransmissionInfo memory) { + bytes32 transmissionId = getTransmissionId(receiver, workflowExecutionId, reportId); + + Transmission memory transmission = s_transmissions[transmissionId]; + + TransmissionState state; + + if (transmission.transmitter == address(0)) { + state = IRouter.TransmissionState.NOT_ATTEMPTED; + } else if (transmission.invalidReceiver) { + state = IRouter.TransmissionState.INVALID_RECEIVER; + } else { + state = transmission.success ? IRouter.TransmissionState.SUCCEEDED : IRouter.TransmissionState.FAILED; + } + + return + TransmissionInfo({ + gasLimit: transmission.gasLimit, + invalidReceiver: transmission.invalidReceiver, + state: state, + success: transmission.success, + transmissionId: transmissionId, + transmitter: transmission.transmitter + }); } - /// @notice Get delivery status of a given report - function getTransmissionState( + /// @notice Get transmitter of a given report or 0x0 if it wasn't transmitted yet + function getTransmitter( address receiver, bytes32 workflowExecutionId, bytes2 reportId - ) external view returns (IRouter.TransmissionState) { - bytes32 transmissionId = getTransmissionId(receiver, workflowExecutionId, reportId); - - if (s_transmissions[transmissionId].transmitter == address(0)) return IRouter.TransmissionState.NOT_ATTEMPTED; - return - s_transmissions[transmissionId].success ? IRouter.TransmissionState.SUCCEEDED : IRouter.TransmissionState.FAILED; + ) external view returns (address) { + return s_transmissions[getTransmissionId(receiver, workflowExecutionId, reportId)].transmitter; } function isForwarder(address forwarder) external view returns (bool) { diff --git a/contracts/src/v0.8/keystone/interfaces/IReceiver.sol b/contracts/src/v0.8/keystone/interfaces/IReceiver.sol index 3af340a121..debe58feea 100644 --- a/contracts/src/v0.8/keystone/interfaces/IReceiver.sol +++ b/contracts/src/v0.8/keystone/interfaces/IReceiver.sol @@ -3,5 +3,10 @@ pragma solidity 0.8.24; /// @title IReceiver - receives keystone reports interface IReceiver { + /// @notice Handles incoming keystone reports. + /// @dev If this function call reverts, it can be retried with a higher gas + /// limit. The receiver is responsible for discarding stale reports. + /// @param metadata Report's metadata. + /// @param report Workflow report. function onReport(bytes calldata metadata, bytes calldata report) external; } diff --git a/contracts/src/v0.8/keystone/interfaces/IRouter.sol b/contracts/src/v0.8/keystone/interfaces/IRouter.sol index 95d11b0bb3..e40f331867 100644 --- a/contracts/src/v0.8/keystone/interfaces/IRouter.sol +++ b/contracts/src/v0.8/keystone/interfaces/IRouter.sol @@ -4,6 +4,9 @@ pragma solidity 0.8.24; /// @title IRouter - delivers keystone reports to receiver interface IRouter { error UnauthorizedForwarder(); + /// @dev Thrown when the gas limit is insufficient for handling state after + /// calling the receiver function. + error InsufficientGasForRouting(bytes32 transmissionId); error AlreadyAttempted(bytes32 transmissionId); event ForwarderAdded(address indexed forwarder); @@ -12,12 +15,42 @@ interface IRouter { enum TransmissionState { NOT_ATTEMPTED, SUCCEEDED, + INVALID_RECEIVER, FAILED } + struct Transmission { + address transmitter; + // This is true if the receiver is not a contract or does not implement the + // `IReceiver` interface. + bool invalidReceiver; + // Whether the transmission attempt was successful. If `false`, the + // transmission can be retried with an increased gas limit. + bool success; + // The amount of gas allocated for the `IReceiver.onReport` call. uint80 + // allows storing gas for known EVM block gas limits. + // Ensures that the minimum gas requested by the user is available during + // the transmission attempt. If the transmission fails (indicated by a + // `false` success state), it can be retried with an increased gas limit. + uint80 gasLimit; + } + struct TransmissionInfo { + bytes32 transmissionId; + TransmissionState state; address transmitter; + // This is true if the receiver is not a contract or does not implement the + // `IReceiver` interface. + bool invalidReceiver; + // Whether the transmission attempt was successful. If `false`, the + // transmission can be retried with an increased gas limit. bool success; + // The amount of gas allocated for the `IReceiver.onReport` call. uint80 + // allows storing gas for known EVM block gas limits. + // Ensures that the minimum gas requested by the user is available during + // the transmission attempt. If the transmission fails (indicated by a + // `false` success state), it can be retried with an increased gas limit. + uint80 gasLimit; } function addForwarder(address forwarder) external; @@ -36,15 +69,14 @@ interface IRouter { bytes32 workflowExecutionId, bytes2 reportId ) external pure returns (bytes32); - function getTransmitter( + function getTransmissionInfo( address receiver, bytes32 workflowExecutionId, bytes2 reportId - ) external view returns (address); - function getTransmissionState( + ) external view returns (TransmissionInfo memory); + function getTransmitter( address receiver, bytes32 workflowExecutionId, bytes2 reportId - ) external view returns (TransmissionState); - function isForwarder(address forwarder) external view returns (bool); + ) external view returns (address); } diff --git a/contracts/src/v0.8/keystone/test/KeystoneForwarder_ReportTest.t.sol b/contracts/src/v0.8/keystone/test/KeystoneForwarder_ReportTest.t.sol index 56e421a8c9..5363d87e92 100644 --- a/contracts/src/v0.8/keystone/test/KeystoneForwarder_ReportTest.t.sol +++ b/contracts/src/v0.8/keystone/test/KeystoneForwarder_ReportTest.t.sol @@ -141,15 +141,40 @@ contract KeystoneForwarder_ReportTest is BaseTest { s_forwarder.report(address(s_receiver), report, reportContext, signatures); } - function test_RevertWhen_AlreadyAttempted() public { - s_forwarder.report(address(s_receiver), report, reportContext, signatures); + function test_RevertWhen_RetryingSuccessfulTransmission() public { + s_forwarder.report{gas: 400_000}(address(s_receiver), report, reportContext, signatures); bytes32 transmissionId = s_forwarder.getTransmissionId(address(s_receiver), executionId, reportId); vm.expectRevert(abi.encodeWithSelector(IRouter.AlreadyAttempted.selector, transmissionId)); - s_forwarder.report(address(s_receiver), report, reportContext, signatures); + // Retyring with more gas + s_forwarder.report{gas: 450_000}(address(s_receiver), report, reportContext, signatures); + } + + function test_RevertWhen_RetryingInvalidContractTransmission() public { + // Receiver is not a contract + address receiver = address(404); + s_forwarder.report{gas: 400_000}(receiver, report, reportContext, signatures); + + bytes32 transmissionId = s_forwarder.getTransmissionId(receiver, executionId, reportId); + vm.expectRevert(abi.encodeWithSelector(IRouter.AlreadyAttempted.selector, transmissionId)); + // Retyring with more gas + s_forwarder.report{gas: 450_000}(receiver, report, reportContext, signatures); + } + + function test_RevertWhen_AttemptingTransmissionWithInsufficientGas() public { + bytes32 transmissionId = s_forwarder.getTransmissionId(address(s_receiver), executionId, reportId); + vm.expectRevert(abi.encodeWithSelector(IRouter.InsufficientGasForRouting.selector, transmissionId)); + s_forwarder.report{gas: 50_000}(address(s_receiver), report, reportContext, signatures); } function test_Report_SuccessfulDelivery() public { + IRouter.TransmissionInfo memory transmissionInfo = s_forwarder.getTransmissionInfo( + address(s_receiver), + executionId, + reportId + ); + assertEq(uint8(transmissionInfo.state), uint8(IRouter.TransmissionState.NOT_ATTEMPTED), "state mismatch"); + vm.expectEmit(address(s_receiver)); emit MessageReceived(metadata, mercuryReports); @@ -158,16 +183,31 @@ contract KeystoneForwarder_ReportTest is BaseTest { s_forwarder.report(address(s_receiver), report, reportContext, signatures); - assertEq( - s_forwarder.getTransmitter(address(s_receiver), executionId, reportId), - TRANSMITTER, - "transmitter mismatch" - ); - assertEq( - uint8(s_forwarder.getTransmissionState(address(s_receiver), executionId, reportId)), - uint8(IRouter.TransmissionState.SUCCEEDED), - "TransmissionState mismatch" + transmissionInfo = s_forwarder.getTransmissionInfo(address(s_receiver), executionId, reportId); + + assertEq(transmissionInfo.transmitter, TRANSMITTER, "transmitter mismatch"); + assertEq(uint8(transmissionInfo.state), uint8(IRouter.TransmissionState.SUCCEEDED), "state mismatch"); + assertGt(transmissionInfo.gasLimit, 100_000, "gas limit mismatch"); + } + + function test_Report_SuccessfulRetryWithMoreGas() public { + s_forwarder.report{gas: 200_000}(address(s_receiver), report, reportContext, signatures); + + IRouter.TransmissionInfo memory transmissionInfo = s_forwarder.getTransmissionInfo( + address(s_receiver), + executionId, + reportId ); + // Expect to fail with the receiver running out of gas + assertEq(uint8(transmissionInfo.state), uint8(IRouter.TransmissionState.FAILED), "state mismatch"); + assertGt(transmissionInfo.gasLimit, 100_000, "gas limit mismatch"); + + // Should succeed with more gas + s_forwarder.report{gas: 300_000}(address(s_receiver), report, reportContext, signatures); + + transmissionInfo = s_forwarder.getTransmissionInfo(address(s_receiver), executionId, reportId); + assertEq(uint8(transmissionInfo.state), uint8(IRouter.TransmissionState.SUCCEEDED), "state mismatch"); + assertGt(transmissionInfo.gasLimit, 200_000, "gas limit mismatch"); } function test_Report_FailedDeliveryWhenReceiverNotContract() public { @@ -179,29 +219,21 @@ contract KeystoneForwarder_ReportTest is BaseTest { s_forwarder.report(receiver, report, reportContext, signatures); - assertEq(s_forwarder.getTransmitter(receiver, executionId, reportId), TRANSMITTER, "transmitter mismatch"); - assertEq( - uint8(s_forwarder.getTransmissionState(receiver, executionId, reportId)), - uint8(IRouter.TransmissionState.FAILED), - "TransmissionState mismatch" - ); + IRouter.TransmissionInfo memory transmissionInfo = s_forwarder.getTransmissionInfo(receiver, executionId, reportId); + assertEq(uint8(transmissionInfo.state), uint8(IRouter.TransmissionState.INVALID_RECEIVER), "state mismatch"); } function test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() public { // Receiver is a contract but doesn't implement the required interface address receiver = address(s_forwarder); - vm.expectEmit(address(s_forwarder)); + vm.expectEmit(true, true, true, false); emit ReportProcessed(receiver, executionId, reportId, false); s_forwarder.report(receiver, report, reportContext, signatures); - assertEq(s_forwarder.getTransmitter(receiver, executionId, reportId), TRANSMITTER, "transmitter mismatch"); - assertEq( - uint8(s_forwarder.getTransmissionState(receiver, executionId, reportId)), - uint8(IRouter.TransmissionState.FAILED), - "TransmissionState mismatch" - ); + IRouter.TransmissionInfo memory transmissionInfo = s_forwarder.getTransmissionInfo(receiver, executionId, reportId); + assertEq(uint8(transmissionInfo.state), uint8(IRouter.TransmissionState.INVALID_RECEIVER), "state mismatch"); } function test_Report_ConfigVersion() public { diff --git a/contracts/src/v0.8/keystone/test/KeystoneRouter_AccessTest.t.sol b/contracts/src/v0.8/keystone/test/KeystoneRouter_AccessTest.t.sol index c126f7ce31..0e43b72bdc 100644 --- a/contracts/src/v0.8/keystone/test/KeystoneRouter_AccessTest.t.sol +++ b/contracts/src/v0.8/keystone/test/KeystoneRouter_AccessTest.t.sol @@ -5,6 +5,7 @@ import {Test} from "forge-std/Test.sol"; import {IReceiver} from "../interfaces/IReceiver.sol"; import {IRouter} from "../interfaces/IRouter.sol"; import {KeystoneForwarder} from "../KeystoneForwarder.sol"; +import {Receiver} from "./mocks/Receiver.sol"; contract KeystoneRouter_SetConfigTest is Test { address internal ADMIN = address(1); @@ -18,10 +19,12 @@ contract KeystoneRouter_SetConfigTest is Test { bytes32 internal id = hex"6d795f657865637574696f6e5f69640000000000000000000000000000000000"; KeystoneForwarder internal s_router; + Receiver internal s_receiver; function setUp() public virtual { vm.prank(ADMIN); s_router = new KeystoneForwarder(); + s_receiver = new Receiver(); } function test_AddForwarder_RevertWhen_NotOwner() public { @@ -36,6 +39,13 @@ contract KeystoneRouter_SetConfigTest is Test { s_router.removeForwarder(FORWARDER); } + function test_RemoveForwarder_Success() public { + vm.prank(ADMIN); + vm.expectEmit(true, false, false, false); + emit IRouter.ForwarderRemoved(FORWARDER); + s_router.removeForwarder(FORWARDER); + } + function test_Route_RevertWhen_UnauthorizedForwarder() public { vm.prank(STRANGER); vm.expectRevert(IRouter.UnauthorizedForwarder.selector); @@ -50,8 +60,8 @@ contract KeystoneRouter_SetConfigTest is Test { assertEq(s_router.isForwarder(FORWARDER), true); vm.prank(FORWARDER); - vm.mockCall(RECEIVER, abi.encodeCall(IReceiver.onReport, (metadata, report)), abi.encode()); - vm.expectCall(RECEIVER, abi.encodeCall(IReceiver.onReport, (metadata, report))); - s_router.route(id, TRANSMITTER, RECEIVER, metadata, report); + vm.mockCall(address(s_receiver), abi.encodeCall(IReceiver.onReport, (metadata, report)), abi.encode()); + vm.expectCall(address(s_receiver), abi.encodeCall(IReceiver.onReport, (metadata, report))); + s_router.route(id, TRANSMITTER, address(s_receiver), metadata, report); } } diff --git a/contracts/src/v0.8/keystone/test/mocks/Receiver.sol b/contracts/src/v0.8/keystone/test/mocks/Receiver.sol index 4d6bd2d3ac..3c1f157bc4 100644 --- a/contracts/src/v0.8/keystone/test/mocks/Receiver.sol +++ b/contracts/src/v0.8/keystone/test/mocks/Receiver.sol @@ -1,16 +1,24 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; import {IReceiver} from "../../interfaces/IReceiver.sol"; -contract Receiver is IReceiver { +contract Receiver is IReceiver, IERC165 { event MessageReceived(bytes metadata, bytes[] mercuryReports); + bytes public latestReport; constructor() {} function onReport(bytes calldata metadata, bytes calldata rawReport) external { + latestReport = rawReport; + // parse actual report bytes[] memory mercuryReports = abi.decode(rawReport, (bytes[])); emit MessageReceived(metadata, mercuryReports); } + + function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { + return interfaceId == this.onReport.selector; + } } diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index 330f15872d..cc3a58b482 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -28,6 +28,8 @@ type WriteTarget struct { cr commontypes.ContractReader cw commontypes.ChainWriter forwarderAddress string + // The minimum amount of gas that the receiver contract must get to process the forwarder report + receiverGasMinimum uint64 capabilities.CapabilityInfo lggr logger.Logger @@ -35,7 +37,21 @@ type WriteTarget struct { bound bool } -func NewWriteTarget(lggr logger.Logger, id string, cr commontypes.ContractReader, cw commontypes.ChainWriter, forwarderAddress string) *WriteTarget { +type TransmissionInfo struct { + GasLimit *big.Int + InvalidReceiver bool + State uint8 + Success bool + TransmissionId [32]byte + Transmitter common.Address +} + +// The gas cost of the forwarder contract logic, including state updates and event emission. +// This is a rough estimate and should be updated if the forwarder contract logic changes. +// TODO: Make this part of the on-chain capability configuration +const FORWARDER_CONTRACT_LOGIC_GAS_COST = 100_000 + +func NewWriteTarget(lggr logger.Logger, id string, cr commontypes.ContractReader, cw commontypes.ChainWriter, forwarderAddress string, txGasLimit uint64) *WriteTarget { info := capabilities.MustNewCapabilityInfo( id, capabilities.CapabilityTypeTarget, @@ -48,6 +64,7 @@ func NewWriteTarget(lggr logger.Logger, id string, cr commontypes.ContractReader cr, cw, forwarderAddress, + txGasLimit - FORWARDER_CONTRACT_LOGIC_GAS_COST, info, logger, false, @@ -131,16 +148,31 @@ func (cap *WriteTarget) Execute(ctx context.Context, request capabilities.Capabi WorkflowExecutionID: rawExecutionID, ReportId: inputs.ID, } - var transmitter common.Address - if err = cap.cr.GetLatestValue(ctx, "forwarder", "getTransmitter", primitives.Unconfirmed, queryInputs, &transmitter); err != nil { - return nil, fmt.Errorf("failed to getTransmitter latest value: %w", err) + var transmissionInfo TransmissionInfo + if err = cap.cr.GetLatestValue(ctx, "forwarder", "getTransmissionInfo", primitives.Unconfirmed, queryInputs, &transmissionInfo); err != nil { + return nil, fmt.Errorf("failed to getTransmissionInfo latest value: %w", err) } - if transmitter != common.HexToAddress("0x0") { - cap.lggr.Infow("WriteTarget report already onchain - returning without a tranmission attempt", "executionID", request.Metadata.WorkflowExecutionID) + + switch { + case transmissionInfo.State == 0: // NOT_ATTEMPTED + cap.lggr.Infow("non-empty report - tranasmission not attempted - attempting to push to txmgr", "request", request, "reportLen", len(inputs.Report), "reportContextLen", len(inputs.Context), "nSignatures", len(inputs.Signatures), "executionID", request.Metadata.WorkflowExecutionID) + case transmissionInfo.State == 1: // SUCCEEDED + cap.lggr.Infow("returning without a tranmission attempt - report already onchain ", "executionID", request.Metadata.WorkflowExecutionID) + return success(), nil + case transmissionInfo.State == 2: // INVALID_RECEIVER + cap.lggr.Infow("returning without a tranmission attempt - transmission already attempted, receiver was marked as invalid", "executionID", request.Metadata.WorkflowExecutionID) return success(), nil + case transmissionInfo.State == 3: // FAILED + if transmissionInfo.GasLimit.Uint64() > cap.receiverGasMinimum { + cap.lggr.Infow("returning without a tranmission attempt - transmission already attempted and failed, sufficient gas was provided", "executionID", request.Metadata.WorkflowExecutionID, "receiverGasMinimum", cap.receiverGasMinimum, "transmissionGasLimit", transmissionInfo.GasLimit) + return success(), nil + } else { + cap.lggr.Infow("non-empty report - retrying a failed transmission - attempting to push to txmgr", "request", request, "reportLen", len(inputs.Report), "reportContextLen", len(inputs.Context), "nSignatures", len(inputs.Signatures), "executionID", request.Metadata.WorkflowExecutionID, "receiverGasMinimum", cap.receiverGasMinimum, "transmissionGasLimit", transmissionInfo.GasLimit) + } + default: + return nil, fmt.Errorf("unexpected transmission state: %v", transmissionInfo.State) } - cap.lggr.Infow("WriteTarget non-empty report - attempting to push to txmgr", "request", request, "reportLen", len(inputs.Report), "reportContextLen", len(inputs.Context), "nSignatures", len(inputs.Signatures), "executionID", request.Metadata.WorkflowExecutionID) txID, err := uuid.NewUUID() // NOTE: CW expects us to generate an ID, rather than return one if err != nil { return nil, err diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go index e118433177..13305fe7ef 100644 --- a/core/capabilities/targets/write_target_test.go +++ b/core/capabilities/targets/write_target_test.go @@ -3,6 +3,7 @@ package targets_test import ( "context" "errors" + "math/big" "testing" "github.com/ethereum/go-ethereum/common" @@ -29,7 +30,7 @@ func TestWriteTarget(t *testing.T) { forwarderA := testutils.NewAddress() forwarderAddr := forwarderA.Hex() - writeTarget := targets.NewWriteTarget(lggr, "test-write-target@1.0.0", cr, cw, forwarderAddr) + writeTarget := targets.NewWriteTarget(lggr, "test-write-target@1.0.0", cr, cw, forwarderAddr, 400_000) require.NotNil(t, writeTarget) config, err := values.NewMap(map[string]any{ @@ -52,9 +53,16 @@ func TestWriteTarget(t *testing.T) { }, }).Return(nil) - cr.On("GetLatestValue", mock.Anything, "forwarder", "getTransmitter", mock.Anything, mock.Anything, mock.Anything).Return(nil).Run(func(args mock.Arguments) { - transmitter := args.Get(5).(*common.Address) - *transmitter = common.HexToAddress("0x0") + cr.On("GetLatestValue", mock.Anything, "forwarder", "getTransmissionInfo", mock.Anything, mock.Anything, mock.Anything).Return(nil).Run(func(args mock.Arguments) { + transmissionInfo := args.Get(5).(*targets.TransmissionInfo) + *transmissionInfo = targets.TransmissionInfo{ + GasLimit: big.NewInt(0), + InvalidReceiver: false, + State: 0, + Success: false, + TransmissionId: [32]byte{}, + Transmitter: common.HexToAddress("0x0"), + } }).Once() cw.On("SubmitTransaction", mock.Anything, "forwarder", "report", mock.Anything, mock.Anything, forwarderAddr, mock.Anything, mock.Anything).Return(nil).Once() @@ -105,7 +113,7 @@ func TestWriteTarget(t *testing.T) { Config: config, Inputs: validInputs, } - cr.On("GetLatestValue", mock.Anything, "forwarder", "getTransmitter", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("reader error")) + cr.On("GetLatestValue", mock.Anything, "forwarder", "getTransmissionInfo", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("reader error")) _, err = writeTarget.Execute(ctx, req) require.Error(t, err) diff --git a/core/gethwrappers/keystone/generated/feeds_consumer/feeds_consumer.go b/core/gethwrappers/keystone/generated/feeds_consumer/feeds_consumer.go index f4d52eedb9..2951835c8d 100644 --- a/core/gethwrappers/keystone/generated/feeds_consumer/feeds_consumer.go +++ b/core/gethwrappers/keystone/generated/feeds_consumer/feeds_consumer.go @@ -31,8 +31,8 @@ var ( ) var KeystoneFeedsConsumerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"}],\"name\":\"UnauthorizedWorkflowName\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"}],\"name\":\"UnauthorizedWorkflowOwner\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint224\",\"name\":\"price\",\"type\":\"uint224\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"name\":\"FeedReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"getPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_allowedSendersList\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_allowedWorkflowOwnersList\",\"type\":\"address[]\"},{\"internalType\":\"bytes10[]\",\"name\":\"_allowedWorkflowNamesList\",\"type\":\"bytes10[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6111cf806101576000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c80638da5cb5b116100505780638da5cb5b1461014e578063e340171114610176578063f2fde38b1461018957600080fd5b806331d98b3f1461007757806379ba509714610131578063805f21321461013b575b600080fd5b6100f3610085366004610d64565b6000908152600260209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168084527c010000000000000000000000000000000000000000000000000000000090910463ffffffff169290910182905291565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909316835263ffffffff9091166020830152015b60405180910390f35b61013961019c565b005b610139610149366004610dc6565b61029e565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610128565b610139610184366004610e77565b61061d565b610139610197366004610f11565b610a5d565b60015473ffffffffffffffffffffffffffffffffffffffff163314610222576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3360009081526004602052604090205460ff166102e9576040517f3fcc3f17000000000000000000000000000000000000000000000000000000008152336004820152602401610219565b60008061032b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610a7192505050565b7fffffffffffffffffffff000000000000000000000000000000000000000000008216600090815260086020526040902054919350915060ff166103bf576040517f4b942f800000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffff0000000000000000000000000000000000000000000083166004820152602401610219565b73ffffffffffffffffffffffffffffffffffffffff811660009081526006602052604090205460ff16610436576040517fbf24162300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610219565b600061044484860186610ff5565b905060005b815181101561061357604051806040016040528083838151811061046f5761046f611107565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681526020018383815181106104b0576104b0611107565b60200260200101516040015163ffffffff16815250600260008484815181106104db576104db611107565b602090810291909101810151518252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179055815182908290811061055d5761055d611107565b6020026020010151600001517f2c30f5cb3caf4239d0f994ce539d7ef24817fa550169c388e3a110f02e40197d83838151811061059c5761059c611107565b6020026020010151602001518484815181106105ba576105ba611107565b6020026020010151604001516040516106039291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a2600101610449565b5050505050505050565b610625610a87565b60005b60035463ffffffff821610156106c65760006004600060038463ffffffff168154811061065757610657611107565b60009182526020808320919091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556106bf81611136565b9050610628565b5060005b63ffffffff811686111561076e5760016004600089898563ffffffff168181106106f6576106f6611107565b905060200201602081019061070b9190610f11565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905561076781611136565b90506106ca565b5061077b60038787610bff565b5060005b60055463ffffffff8216101561081d5760006006600060058463ffffffff16815481106107ae576107ae611107565b60009182526020808320919091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905561081681611136565b905061077f565b5060005b63ffffffff81168411156108c55760016006600087878563ffffffff1681811061084d5761084d611107565b90506020020160208101906108629190610f11565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556108be81611136565b9050610821565b506108d260058585610bff565b5060005b60075463ffffffff821610156109935760006008600060078463ffffffff168154811061090557610905611107565b600091825260208083206003808404909101549206600a026101000a90910460b01b7fffffffffffffffffffff00000000000000000000000000000000000000000000168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905561098c81611136565b90506108d6565b5060005b63ffffffff8116821115610a475760016008600085858563ffffffff168181106109c3576109c3611107565b90506020020160208101906109d89190611180565b7fffffffffffffffffffff00000000000000000000000000000000000000000000168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055610a4081611136565b9050610997565b50610a5460078383610c87565b50505050505050565b610a65610a87565b610a6e81610b0a565b50565b6040810151604a90910151909160609190911c90565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610219565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610b89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610219565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610c77579160200282015b82811115610c775781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff843516178255602090920191600190910190610c1f565b50610c83929150610d4f565b5090565b82805482825590600052602060002090600201600390048101928215610c775791602002820160005b83821115610d1057833575ffffffffffffffffffffffffffffffffffffffffffff191683826101000a81548169ffffffffffffffffffff021916908360b01c02179055509260200192600a01602081600901049283019260010302610cb0565b8015610d465782816101000a81549069ffffffffffffffffffff0219169055600a01602081600901049283019260010302610d10565b5050610c839291505b5b80821115610c835760008155600101610d50565b600060208284031215610d7657600080fd5b5035919050565b60008083601f840112610d8f57600080fd5b50813567ffffffffffffffff811115610da757600080fd5b602083019150836020828501011115610dbf57600080fd5b9250929050565b60008060008060408587031215610ddc57600080fd5b843567ffffffffffffffff80821115610df457600080fd5b610e0088838901610d7d565b90965094506020870135915080821115610e1957600080fd5b50610e2687828801610d7d565b95989497509550505050565b60008083601f840112610e4457600080fd5b50813567ffffffffffffffff811115610e5c57600080fd5b6020830191508360208260051b8501011115610dbf57600080fd5b60008060008060008060608789031215610e9057600080fd5b863567ffffffffffffffff80821115610ea857600080fd5b610eb48a838b01610e32565b90985096506020890135915080821115610ecd57600080fd5b610ed98a838b01610e32565b90965094506040890135915080821115610ef257600080fd5b50610eff89828a01610e32565b979a9699509497509295939492505050565b600060208284031215610f2357600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f4757600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715610fa057610fa0610f4e565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610fed57610fed610f4e565b604052919050565b6000602080838503121561100857600080fd5b823567ffffffffffffffff8082111561102057600080fd5b818501915085601f83011261103457600080fd5b81358181111561104657611046610f4e565b611054848260051b01610fa6565b8181528481019250606091820284018501918883111561107357600080fd5b938501935b828510156110fb5780858a0312156110905760008081fd5b611098610f7d565b85358152868601357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146110cb5760008081fd5b8188015260408681013563ffffffff811681146110e85760008081fd5b9082015284529384019392850192611078565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103611176577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6001019392505050565b60006020828403121561119257600080fd5b81357fffffffffffffffffffff0000000000000000000000000000000000000000000081168114610f4757600080fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"}],\"name\":\"UnauthorizedWorkflowName\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"}],\"name\":\"UnauthorizedWorkflowOwner\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint224\",\"name\":\"price\",\"type\":\"uint224\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"name\":\"FeedReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"getPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_allowedSendersList\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_allowedWorkflowOwnersList\",\"type\":\"address[]\"},{\"internalType\":\"bytes10[]\",\"name\":\"_allowedWorkflowNamesList\",\"type\":\"bytes10[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611281806101576000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063805f21321161005b578063805f2132146101ab5780638da5cb5b146101be578063e3401711146101e6578063f2fde38b146101f957600080fd5b806301ffc9a71461008257806331d98b3f146100ec57806379ba5097146101a1575b600080fd5b6100d7610090366004610dd4565b7fffffffff00000000000000000000000000000000000000000000000000000000167f805f2132000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b6101686100fa366004610e1d565b6000908152600260209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168084527c010000000000000000000000000000000000000000000000000000000090910463ffffffff169290910182905291565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909316835263ffffffff9091166020830152016100e3565b6101a961020c565b005b6101a96101b9366004610e7f565b61030e565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e3565b6101a96101f4366004610f30565b61068d565b6101a9610207366004610fca565b610acd565b60015473ffffffffffffffffffffffffffffffffffffffff163314610292576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3360009081526004602052604090205460ff16610359576040517f3fcc3f17000000000000000000000000000000000000000000000000000000008152336004820152602401610289565b60008061039b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ae192505050565b7fffffffffffffffffffff000000000000000000000000000000000000000000008216600090815260086020526040902054919350915060ff1661042f576040517f4b942f800000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffff0000000000000000000000000000000000000000000083166004820152602401610289565b73ffffffffffffffffffffffffffffffffffffffff811660009081526006602052604090205460ff166104a6576040517fbf24162300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610289565b60006104b4848601866110a7565b905060005b81518110156106835760405180604001604052808383815181106104df576104df6111b9565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152602001838381518110610520576105206111b9565b60200260200101516040015163ffffffff168152506002600084848151811061054b5761054b6111b9565b602090810291909101810151518252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117905581518290829081106105cd576105cd6111b9565b6020026020010151600001517f2c30f5cb3caf4239d0f994ce539d7ef24817fa550169c388e3a110f02e40197d83838151811061060c5761060c6111b9565b60200260200101516020015184848151811061062a5761062a6111b9565b6020026020010151604001516040516106739291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a26001016104b9565b5050505050505050565b610695610af7565b60005b60035463ffffffff821610156107365760006004600060038463ffffffff16815481106106c7576106c76111b9565b60009182526020808320919091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905561072f816111e8565b9050610698565b5060005b63ffffffff81168611156107de5760016004600089898563ffffffff16818110610766576107666111b9565b905060200201602081019061077b9190610fca565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556107d7816111e8565b905061073a565b506107eb60038787610c6f565b5060005b60055463ffffffff8216101561088d5760006006600060058463ffffffff168154811061081e5761081e6111b9565b60009182526020808320919091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055610886816111e8565b90506107ef565b5060005b63ffffffff81168411156109355760016006600087878563ffffffff168181106108bd576108bd6111b9565b90506020020160208101906108d29190610fca565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905561092e816111e8565b9050610891565b5061094260058585610c6f565b5060005b60075463ffffffff82161015610a035760006008600060078463ffffffff1681548110610975576109756111b9565b600091825260208083206003808404909101549206600a026101000a90910460b01b7fffffffffffffffffffff00000000000000000000000000000000000000000000168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556109fc816111e8565b9050610946565b5060005b63ffffffff8116821115610ab75760016008600085858563ffffffff16818110610a3357610a336111b9565b9050602002016020810190610a489190611232565b7fffffffffffffffffffff00000000000000000000000000000000000000000000168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055610ab0816111e8565b9050610a07565b50610ac460078383610cf7565b50505050505050565b610ad5610af7565b610ade81610b7a565b50565b6040810151604a90910151909160609190911c90565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610289565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610bf9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610289565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610ce7579160200282015b82811115610ce75781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff843516178255602090920191600190910190610c8f565b50610cf3929150610dbf565b5090565b82805482825590600052602060002090600201600390048101928215610ce75791602002820160005b83821115610d8057833575ffffffffffffffffffffffffffffffffffffffffffff191683826101000a81548169ffffffffffffffffffff021916908360b01c02179055509260200192600a01602081600901049283019260010302610d20565b8015610db65782816101000a81549069ffffffffffffffffffff0219169055600a01602081600901049283019260010302610d80565b5050610cf39291505b5b80821115610cf35760008155600101610dc0565b600060208284031215610de657600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e1657600080fd5b9392505050565b600060208284031215610e2f57600080fd5b5035919050565b60008083601f840112610e4857600080fd5b50813567ffffffffffffffff811115610e6057600080fd5b602083019150836020828501011115610e7857600080fd5b9250929050565b60008060008060408587031215610e9557600080fd5b843567ffffffffffffffff80821115610ead57600080fd5b610eb988838901610e36565b90965094506020870135915080821115610ed257600080fd5b50610edf87828801610e36565b95989497509550505050565b60008083601f840112610efd57600080fd5b50813567ffffffffffffffff811115610f1557600080fd5b6020830191508360208260051b8501011115610e7857600080fd5b60008060008060008060608789031215610f4957600080fd5b863567ffffffffffffffff80821115610f6157600080fd5b610f6d8a838b01610eeb565b90985096506020890135915080821115610f8657600080fd5b610f928a838b01610eeb565b90965094506040890135915080821115610fab57600080fd5b50610fb889828a01610eeb565b979a9699509497509295939492505050565b600060208284031215610fdc57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610e1657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561105257611052611000565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561109f5761109f611000565b604052919050565b600060208083850312156110ba57600080fd5b823567ffffffffffffffff808211156110d257600080fd5b818501915085601f8301126110e657600080fd5b8135818111156110f8576110f8611000565b611106848260051b01611058565b8181528481019250606091820284018501918883111561112557600080fd5b938501935b828510156111ad5780858a0312156111425760008081fd5b61114a61102f565b85358152868601357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461117d5760008081fd5b8188015260408681013563ffffffff8116811461119a5760008081fd5b908201528452938401939285019261112a565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103611228577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6001019392505050565b60006020828403121561124457600080fd5b81357fffffffffffffffffffff0000000000000000000000000000000000000000000081168114610e1657600080fdfea164736f6c6343000818000a", } var KeystoneFeedsConsumerABI = KeystoneFeedsConsumerMetaData.ABI @@ -216,6 +216,28 @@ func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerCallerSession) Owner() (commo return _KeystoneFeedsConsumer.Contract.Owner(&_KeystoneFeedsConsumer.CallOpts) } +func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _KeystoneFeedsConsumer.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _KeystoneFeedsConsumer.Contract.SupportsInterface(&_KeystoneFeedsConsumer.CallOpts, interfaceId) +} + +func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _KeystoneFeedsConsumer.Contract.SupportsInterface(&_KeystoneFeedsConsumer.CallOpts, interfaceId) +} + func (_KeystoneFeedsConsumer *KeystoneFeedsConsumerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { return _KeystoneFeedsConsumer.contract.Transact(opts, "acceptOwnership") } @@ -700,6 +722,8 @@ type KeystoneFeedsConsumerInterface interface { Owner(opts *bind.CallOpts) (common.Address, error) + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) OnReport(opts *bind.TransactOpts, metadata []byte, rawReport []byte) (*types.Transaction, error) diff --git a/core/gethwrappers/keystone/generated/forwarder/forwarder.go b/core/gethwrappers/keystone/generated/forwarder/forwarder.go index 3b6fba5c7c..a7a78ab67f 100644 --- a/core/gethwrappers/keystone/generated/forwarder/forwarder.go +++ b/core/gethwrappers/keystone/generated/forwarder/forwarder.go @@ -30,9 +30,18 @@ var ( _ = abi.ConvertType ) +type IRouterTransmissionInfo struct { + TransmissionId [32]byte + State uint8 + Transmitter common.Address + InvalidReceiver bool + Success bool + GasLimit *big.Int +} + var KeystoneForwarderMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"DuplicateSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"configId\",\"type\":\"uint64\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"received\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedForwarder\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"ForwarderAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"ForwarderRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"result\",\"type\":\"bool\"}],\"name\":\"ReportProcessed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"addForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"}],\"name\":\"clearConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmissionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmissionState\",\"outputs\":[{\"internalType\":\"enumIRouter.TransmissionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmitter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"isForwarder\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"removeForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"reportContext\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"signatures\",\"type\":\"bytes[]\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"validatedReport\",\"type\":\"bytes\"}],\"name\":\"route\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b038481169190911790915581161561009757610097816100b9565b5050306000908152600360205260409020805460ff1916600117905550610162565b336001600160a01b038216036101115760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611b9180620001726000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379ba50971161008c578063abcef55411610066578063abcef5541461023e578063ee59d26c14610277578063ef6e17a01461028a578063f2fde38b1461029d57600080fd5b806379ba5097146101e05780638864b864146101e85780638da5cb5b1461022057600080fd5b8063354bdd66116100c8578063354bdd661461017957806343c164671461019a5780634d93172d146101ba5780635c41d2fe146101cd57600080fd5b806311289565146100ef578063181f5a7714610104578063233fd52d14610156575b600080fd5b6101026100fd3660046114d8565b6102b0565b005b6101406040518060400160405280601a81526020017f466f7277617264657220616e6420526f7574657220312e302e3000000000000081525081565b60405161014d9190611583565b60405180910390f35b6101696101643660046115f0565b61080d565b604051901515815260200161014d565b61018c610187366004611678565b610a00565b60405190815260200161014d565b6101ad6101a8366004611678565b610a84565b60405161014d91906116dd565b6101026101c836600461171e565b610b09565b6101026101db36600461171e565b610b85565b610102610c04565b6101fb6101f6366004611678565b610d01565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014d565b60005473ffffffffffffffffffffffffffffffffffffffff166101fb565b61016961024c36600461171e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b61010261028536600461174d565b610d41565b6101026102983660046117cb565b61111e565b6101026102ab36600461171e565b6111be565b606d8510156102eb576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600061032f89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111d292505050565b67ffffffffffffffff8216600090815260026020526040812080549497509195509193509160ff16908190036103a2576040517fdf3b81ea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b856103ae82600161182d565b60ff1614610400576103c181600161182d565b6040517fd6022e8e00000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101879052604401610399565b60008b8b60405161041292919061184c565b60405190819003812061042b918c908c9060200161185c565b60405160208183030381529060405280519060200120905061044b611365565b60005b888110156106cd573660008b8b8481811061046b5761046b611876565b905060200281019061047d91906118a5565b9092509050604181146104c05781816040517f2adfdc30000000000000000000000000000000000000000000000000000000008152600401610399929190611953565b6000600186848460408181106104d8576104d8611876565b6104ea92013560f81c9050601b61182d565b6104f860206000878961196f565b61050191611999565b61050f60406020888a61196f565b61051891611999565b6040805160008152602081018083529590955260ff909316928401929092526060830152608082015260a0016020604051602081039080840390855afa158015610566573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8116600090815260028c0160205291822054909350915081900361060c576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610399565b600086826020811061062057610620611876565b602002015173ffffffffffffffffffffffffffffffffffffffff161461068a576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610399565b8186826020811061069d5761069d611876565b73ffffffffffffffffffffffffffffffffffffffff909216602092909202015250506001909201915061044e9050565b50505050505060003073ffffffffffffffffffffffffffffffffffffffff1663233fd52d6106fc8c8686610a00565b338d8d8d602d90606d926107129392919061196f565b8f8f606d9080926107259392919061196f565b6040518863ffffffff1660e01b815260040161074797969594939291906119d5565b6020604051808303816000875af1158015610766573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078a9190611a36565b9050817dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916838b73ffffffffffffffffffffffffffffffffffffffff167f3617b009e9785c42daebadb6d3fb553243a4bf586d07ea72d65d80013ce116b5846040516107f9911515815260200190565b60405180910390a450505050505050505050565b3360009081526003602052604081205460ff16610856576040517fd79e123d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008881526004602052604090205473ffffffffffffffffffffffffffffffffffffffff16156108b5576040517fa53dc8ca00000000000000000000000000000000000000000000000000000000815260048101899052602401610399565b600088815260046020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a81169190911790915587163b9003610917575060006109f5565b6040517f805f213200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87169063805f21329061096f908890889088908890600401611a58565b600060405180830381600087803b15801561098957600080fd5b505af192505050801561099a575060015b6109a6575060006109f5565b50600087815260046020526040902080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905560015b979650505050505050565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018390527fffff000000000000000000000000000000000000000000000000000000000000821660548201526000906056016040516020818303038152906040528051906020012090505b9392505050565b600080610a92858585610a00565b60008181526004602052604090205490915073ffffffffffffffffffffffffffffffffffffffff16610ac8576000915050610a7d565b60008181526004602052604090205474010000000000000000000000000000000000000000900460ff16610afd576002610b00565b60015b95945050505050565b610b116111ed565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fb96d15bf9258c7b8df062753a6a262864611fc7b060a5ee2e57e79b85f898d389190a250565b610b8d6111ed565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f0ea0ce2c048ff45a4a95f2947879de3fb94abec2f152190400cab2d1272a68e79190a250565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610399565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600060046000610d12868686610a00565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff16949350505050565b610d496111ed565b8260ff16600003610d86576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f811115610dcb576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101829052601f6024820152604401610399565b610dd6836003611a7f565b60ff168111610e345780610deb846003611a7f565b610df690600161182d565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260ff166024820152604401610399565b67ffffffff00000000602086901b1663ffffffff85161760005b67ffffffffffffffff8216600090815260026020526040902060010154811015610ee45767ffffffffffffffff8216600090815260026020819052604082206001810180549190920192919084908110610eaa57610eaa611876565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812055600101610e4e565b5060005b82811015611060576000848483818110610f0457610f04611876565b9050602002016020810190610f19919061171e565b905073ffffffffffffffffffffffffffffffffffffffff8116610f80576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610399565b67ffffffffffffffff8316600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290920190529020541561100c576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610399565b611017826001611aa2565b67ffffffffffffffff8416600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff90961684529490910190529190912055600101610ee8565b5067ffffffffffffffff81166000908152600260205260409020611088906001018484611384565b5067ffffffffffffffff81166000908152600260205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff87161790555163ffffffff86811691908816907f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a4559061110e90889088908890611ab5565b60405180910390a3505050505050565b6111266111ed565b63ffffffff818116602084811b67ffffffff00000000168217600090815260028252604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558051828152928301905291928516917f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a455916040516111b2929190611b1b565b60405180910390a35050565b6111c66111ed565b6111cf81611270565b50565b60218101516045820151608b90920151909260c09290921c91565b60005473ffffffffffffffffffffffffffffffffffffffff16331461126e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610399565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036112ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610399565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6040518061040001604052806020906020820280368337509192915050565b8280548282559060005260206000209081019282156113fc579160200282015b828111156113fc5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8435161782556020909201916001909101906113a4565b5061140892915061140c565b5090565b5b80821115611408576000815560010161140d565b803573ffffffffffffffffffffffffffffffffffffffff8116811461144557600080fd5b919050565b60008083601f84011261145c57600080fd5b50813567ffffffffffffffff81111561147457600080fd5b60208301915083602082850101111561148c57600080fd5b9250929050565b60008083601f8401126114a557600080fd5b50813567ffffffffffffffff8111156114bd57600080fd5b6020830191508360208260051b850101111561148c57600080fd5b60008060008060008060006080888a0312156114f357600080fd5b6114fc88611421565b9650602088013567ffffffffffffffff8082111561151957600080fd5b6115258b838c0161144a565b909850965060408a013591508082111561153e57600080fd5b61154a8b838c0161144a565b909650945060608a013591508082111561156357600080fd5b506115708a828b01611493565b989b979a50959850939692959293505050565b60006020808352835180602085015260005b818110156115b157858101830151858201604001528201611595565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600080600080600080600060a0888a03121561160b57600080fd5b8735965061161b60208901611421565b955061162960408901611421565b9450606088013567ffffffffffffffff8082111561164657600080fd5b6116528b838c0161144a565b909650945060808a013591508082111561166b57600080fd5b506115708a828b0161144a565b60008060006060848603121561168d57600080fd5b61169684611421565b92506020840135915060408401357fffff000000000000000000000000000000000000000000000000000000000000811681146116d257600080fd5b809150509250925092565b6020810160038310611718577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60006020828403121561173057600080fd5b610a7d82611421565b803563ffffffff8116811461144557600080fd5b60008060008060006080868803121561176557600080fd5b61176e86611739565b945061177c60208701611739565b9350604086013560ff8116811461179257600080fd5b9250606086013567ffffffffffffffff8111156117ae57600080fd5b6117ba88828901611493565b969995985093965092949392505050565b600080604083850312156117de57600080fd5b6117e783611739565b91506117f560208401611739565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff8181168382160190811115611846576118466117fe565b92915050565b8183823760009101908152919050565b838152818360208301376000910160200190815292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126118da57600080fd5b83018035915067ffffffffffffffff8211156118f557600080fd5b60200191503681900382131561148c57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60208152600061196760208301848661190a565b949350505050565b6000808585111561197f57600080fd5b8386111561198c57600080fd5b5050820193919092039150565b80356020831015611846577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525060a06060830152611a1560a08301868861190a565b8281036080840152611a2881858761190a565b9a9950505050505050505050565b600060208284031215611a4857600080fd5b81518015158114610a7d57600080fd5b604081526000611a6c60408301868861190a565b82810360208401526109f581858761190a565b60ff8181168382160290811690818114611a9b57611a9b6117fe565b5092915050565b80820180821115611846576118466117fe565b60ff8416815260406020808301829052908201839052600090849060608401835b86811015611b0f5773ffffffffffffffffffffffffffffffffffffffff611afc85611421565b1682529282019290820190600101611ad6565b50979650505050505050565b60006040820160ff8516835260206040602085015281855180845260608601915060208701935060005b81811015611b7757845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101611b45565b509097965050505050505056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"DuplicateSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"}],\"name\":\"InsufficientGasForRouting\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"configId\",\"type\":\"uint64\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"received\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedForwarder\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"ForwarderAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"ForwarderRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"result\",\"type\":\"bool\"}],\"name\":\"ReportProcessed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"addForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"}],\"name\":\"clearConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmissionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmissionInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"},{\"internalType\":\"enumIRouter.TransmissionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"invalidReceiver\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint80\",\"name\":\"gasLimit\",\"type\":\"uint80\"}],\"internalType\":\"structIRouter.TransmissionInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmitter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"isForwarder\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"removeForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"reportContext\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"signatures\",\"type\":\"bytes[]\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"validatedReport\",\"type\":\"bytes\"}],\"name\":\"route\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000bf565b5050306000908152600360205260409020805460ff19166001179055506200016a565b336001600160a01b03821603620001195760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b612141806200017a6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379ba50971161008c578063abcef55411610066578063abcef5541461035d578063ee59d26c14610396578063ef6e17a0146103a9578063f2fde38b146103bc57600080fd5b806379ba50971461025e5780638864b864146102665780638da5cb5b1461033f57600080fd5b8063272cbd93116100c8578063272cbd9314610179578063354bdd66146101995780634d93172d146102385780635c41d2fe1461024b57600080fd5b806311289565146100ef578063181f5a7714610104578063233fd52d14610156575b600080fd5b6101026100fd3660046119df565b6103cf565b005b6101406040518060400160405280601a81526020017f466f7277617264657220616e6420526f7574657220312e302e3000000000000081525081565b60405161014d9190611a8a565b60405180910390f35b610169610164366004611af7565b610989565b604051901515815260200161014d565b61018c610187366004611b7f565b610e4a565b60405161014d9190611c13565b61022a6101a7366004611b7f565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018390527fffff000000000000000000000000000000000000000000000000000000000000821660548201526000906056016040516020818303038152906040528051906020012090509392505050565b60405190815260200161014d565b610102610246366004611cbb565b611050565b610102610259366004611cbb565b6110cc565b61010261114b565b61031a610274366004611b7f565b6040805160609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660208086019190915260348501939093527fffff000000000000000000000000000000000000000000000000000000000000919091166054840152805160368185030181526056909301815282519282019290922060009081526004909152205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014d565b60005473ffffffffffffffffffffffffffffffffffffffff1661031a565b61016961036b366004611cbb565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6101026103a4366004611cf1565b611248565b6101026103b7366004611d6f565b611625565b6101026103ca366004611cbb565b6116c5565b606d85101561040a576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600061044e89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116d992505050565b67ffffffffffffffff8216600090815260026020526040812080549497509195509193509160ff16908190036104c1576040517fdf3b81ea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b856104cd826001611dd1565b60ff161461051f576104e0816001611dd1565b6040517fd6022e8e00000000000000000000000000000000000000000000000000000000815260ff9091166004820152602481018790526044016104b8565b60008b8b604051610531929190611df0565b60405190819003812061054a918c908c90602001611e00565b60405160208183030381529060405280519060200120905061056a61186c565b60005b888110156107ec573660008b8b8481811061058a5761058a611e1a565b905060200281019061059c9190611e49565b9092509050604181146105df5781816040517f2adfdc300000000000000000000000000000000000000000000000000000000081526004016104b8929190611ef7565b6000600186848460408181106105f7576105f7611e1a565b61060992013560f81c9050601b611dd1565b610617602060008789611f13565b61062091611f3d565b61062e60406020888a611f13565b61063791611f3d565b6040805160008152602081018083529590955260ff909316928401929092526060830152608082015260a0016020604051602081039080840390855afa158015610685573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8116600090815260028c0160205291822054909350915081900361072b576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b600086826020811061073f5761073f611e1a565b602002015173ffffffffffffffffffffffffffffffffffffffff16146107a9576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b818682602081106107bc576107bc611e1a565b73ffffffffffffffffffffffffffffffffffffffff909216602092909202015250506001909201915061056d9050565b50506040805160608f901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602080830191909152603482018990527fffff0000000000000000000000000000000000000000000000000000000000008816605483015282516036818403018152605690920190925280519101206000945030935063233fd52d92509050338d8d8d602d90606d9261088e93929190611f13565b8f8f606d9080926108a193929190611f13565b6040518863ffffffff1660e01b81526004016108c39796959493929190611f79565b6020604051808303816000875af11580156108e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109069190611fda565b9050817dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916838b73ffffffffffffffffffffffffffffffffffffffff167f3617b009e9785c42daebadb6d3fb553243a4bf586d07ea72d65d80013ce116b584604051610975911515815260200190565b60405180910390a450505050505050505050565b3360009081526003602052604081205460ff166109d2576040517fd79e123d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005a9050619c40811015610a16576040517f0bfecd63000000000000000000000000000000000000000000000000000000008152600481018a90526024016104b8565b6000898152600460209081526040918290208251608081018452905473ffffffffffffffffffffffffffffffffffffffff8116825274010000000000000000000000000000000000000000810460ff90811615159383019390935275010000000000000000000000000000000000000000008104909216151592810183905276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660608201529080610ace575080602001515b15610b08576040517fa53dc8ca000000000000000000000000000000000000000000000000000000008152600481018b90526024016104b8565b6000610b16619c4084611ffc565b905089600460008d815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600460008d815260200190815260200160002060000160166101000a81548169ffffffffffffffffffff021916908369ffffffffffffffffffff1602179055508873ffffffffffffffffffffffffffffffffffffffff163b600003610c2257505050600088815260046020526040812080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790559050610e3f565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f805f213200000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8a16906301ffc9a790602401602060405180830381865afa925050508015610ce6575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610ce391810190611fda565b60015b610d3f57505050600088815260046020526040812080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790559050610e3f565b5060008089898989604051602401610d5a949392919061200f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f805f21320000000000000000000000000000000000000000000000000000000017815281519192506000918291828f88f191508115610e335760008d815260046020526040902080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b509350610e3f92505050565b979650505050505050565b6040805160c0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905284519088901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001681830152603481018790527fffff000000000000000000000000000000000000000000000000000000000000861660548201528451603681830301815260568201808752815191840191909120808552600490935285842060d68301909652945473ffffffffffffffffffffffffffffffffffffffff811680875274010000000000000000000000000000000000000000820460ff9081161515607685015275010000000000000000000000000000000000000000008304161515609684015276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660b69092019190915292939092909190610fa857506000610fd0565b816020015115610fba57506002610fd0565b8160400151610fca576003610fcd565b60015b90505b6040518060c00160405280848152602001826003811115610ff357610ff3611be4565b8152602001836000015173ffffffffffffffffffffffffffffffffffffffff168152602001836020015115158152602001836040015115158152602001836060015169ffffffffffffffffffff1681525093505050509392505050565b6110586116f4565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fb96d15bf9258c7b8df062753a6a262864611fc7b060a5ee2e57e79b85f898d389190a250565b6110d46116f4565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f0ea0ce2c048ff45a4a95f2947879de3fb94abec2f152190400cab2d1272a68e79190a250565b60015473ffffffffffffffffffffffffffffffffffffffff1633146111cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016104b8565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6112506116f4565b8260ff1660000361128d576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8111156112d2576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101829052601f60248201526044016104b8565b6112dd836003612036565b60ff16811161133b57806112f2846003612036565b6112fd906001611dd1565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260ff1660248201526044016104b8565b67ffffffff00000000602086901b1663ffffffff85161760005b67ffffffffffffffff82166000908152600260205260409020600101548110156113eb5767ffffffffffffffff82166000908152600260208190526040822060018101805491909201929190849081106113b1576113b1611e1a565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812055600101611355565b5060005b8281101561156757600084848381811061140b5761140b611e1a565b90506020020160208101906114209190611cbb565b905073ffffffffffffffffffffffffffffffffffffffff8116611487576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b67ffffffffffffffff8316600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff86168552909201905290205415611513576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b61151e826001612052565b67ffffffffffffffff8416600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff909616845294909101905291909120556001016113ef565b5067ffffffffffffffff8116600090815260026020526040902061158f90600101848461188b565b5067ffffffffffffffff81166000908152600260205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff87161790555163ffffffff86811691908816907f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a4559061161590889088908890612065565b60405180910390a3505050505050565b61162d6116f4565b63ffffffff818116602084811b67ffffffff00000000168217600090815260028252604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558051828152928301905291928516917f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a455916040516116b99291906120cb565b60405180910390a35050565b6116cd6116f4565b6116d681611777565b50565b60218101516045820151608b90920151909260c09290921c91565b60005473ffffffffffffffffffffffffffffffffffffffff163314611775576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104b8565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036117f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104b8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6040518061040001604052806020906020820280368337509192915050565b828054828255906000526020600020908101928215611903579160200282015b828111156119035781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8435161782556020909201916001909101906118ab565b5061190f929150611913565b5090565b5b8082111561190f5760008155600101611914565b803573ffffffffffffffffffffffffffffffffffffffff8116811461194c57600080fd5b919050565b60008083601f84011261196357600080fd5b50813567ffffffffffffffff81111561197b57600080fd5b60208301915083602082850101111561199357600080fd5b9250929050565b60008083601f8401126119ac57600080fd5b50813567ffffffffffffffff8111156119c457600080fd5b6020830191508360208260051b850101111561199357600080fd5b60008060008060008060006080888a0312156119fa57600080fd5b611a0388611928565b9650602088013567ffffffffffffffff80821115611a2057600080fd5b611a2c8b838c01611951565b909850965060408a0135915080821115611a4557600080fd5b611a518b838c01611951565b909650945060608a0135915080821115611a6a57600080fd5b50611a778a828b0161199a565b989b979a50959850939692959293505050565b60006020808352835180602085015260005b81811015611ab857858101830151858201604001528201611a9c565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600080600080600080600060a0888a031215611b1257600080fd5b87359650611b2260208901611928565b9550611b3060408901611928565b9450606088013567ffffffffffffffff80821115611b4d57600080fd5b611b598b838c01611951565b909650945060808a0135915080821115611b7257600080fd5b50611a778a828b01611951565b600080600060608486031215611b9457600080fd5b611b9d84611928565b92506020840135915060408401357fffff00000000000000000000000000000000000000000000000000000000000081168114611bd957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81518152602082015160c082019060048110611c58577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8060208401525073ffffffffffffffffffffffffffffffffffffffff604084015116604083015260608301511515606083015260808301511515608083015260a0830151611cb460a084018269ffffffffffffffffffff169052565b5092915050565b600060208284031215611ccd57600080fd5b611cd682611928565b9392505050565b803563ffffffff8116811461194c57600080fd5b600080600080600060808688031215611d0957600080fd5b611d1286611cdd565b9450611d2060208701611cdd565b9350604086013560ff81168114611d3657600080fd5b9250606086013567ffffffffffffffff811115611d5257600080fd5b611d5e8882890161199a565b969995985093965092949392505050565b60008060408385031215611d8257600080fd5b611d8b83611cdd565b9150611d9960208401611cdd565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff8181168382160190811115611dea57611dea611da2565b92915050565b8183823760009101908152919050565b838152818360208301376000910160200190815292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611e7e57600080fd5b83018035915067ffffffffffffffff821115611e9957600080fd5b60200191503681900382131561199357600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000611f0b602083018486611eae565b949350505050565b60008085851115611f2357600080fd5b83861115611f3057600080fd5b5050820193919092039150565b80356020831015611dea577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525060a06060830152611fb960a083018688611eae565b8281036080840152611fcc818587611eae565b9a9950505050505050505050565b600060208284031215611fec57600080fd5b81518015158114611cd657600080fd5b81810381811115611dea57611dea611da2565b604081526000612023604083018688611eae565b8281036020840152610e3f818587611eae565b60ff8181168382160290811690818114611cb457611cb4611da2565b80820180821115611dea57611dea611da2565b60ff8416815260406020808301829052908201839052600090849060608401835b868110156120bf5773ffffffffffffffffffffffffffffffffffffffff6120ac85611928565b1682529282019290820190600101612086565b50979650505050505050565b60006040820160ff8516835260206040602085015281855180845260608601915060208701935060005b8181101561212757845173ffffffffffffffffffffffffffffffffffffffff16835293830193918301916001016120f5565b509097965050505050505056fea164736f6c6343000818000a", } var KeystoneForwarderABI = KeystoneForwarderMetaData.ABI @@ -193,26 +202,26 @@ func (_KeystoneForwarder *KeystoneForwarderCallerSession) GetTransmissionId(rece return _KeystoneForwarder.Contract.GetTransmissionId(&_KeystoneForwarder.CallOpts, receiver, workflowExecutionId, reportId) } -func (_KeystoneForwarder *KeystoneForwarderCaller) GetTransmissionState(opts *bind.CallOpts, receiver common.Address, workflowExecutionId [32]byte, reportId [2]byte) (uint8, error) { +func (_KeystoneForwarder *KeystoneForwarderCaller) GetTransmissionInfo(opts *bind.CallOpts, receiver common.Address, workflowExecutionId [32]byte, reportId [2]byte) (IRouterTransmissionInfo, error) { var out []interface{} - err := _KeystoneForwarder.contract.Call(opts, &out, "getTransmissionState", receiver, workflowExecutionId, reportId) + err := _KeystoneForwarder.contract.Call(opts, &out, "getTransmissionInfo", receiver, workflowExecutionId, reportId) if err != nil { - return *new(uint8), err + return *new(IRouterTransmissionInfo), err } - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + out0 := *abi.ConvertType(out[0], new(IRouterTransmissionInfo)).(*IRouterTransmissionInfo) return out0, err } -func (_KeystoneForwarder *KeystoneForwarderSession) GetTransmissionState(receiver common.Address, workflowExecutionId [32]byte, reportId [2]byte) (uint8, error) { - return _KeystoneForwarder.Contract.GetTransmissionState(&_KeystoneForwarder.CallOpts, receiver, workflowExecutionId, reportId) +func (_KeystoneForwarder *KeystoneForwarderSession) GetTransmissionInfo(receiver common.Address, workflowExecutionId [32]byte, reportId [2]byte) (IRouterTransmissionInfo, error) { + return _KeystoneForwarder.Contract.GetTransmissionInfo(&_KeystoneForwarder.CallOpts, receiver, workflowExecutionId, reportId) } -func (_KeystoneForwarder *KeystoneForwarderCallerSession) GetTransmissionState(receiver common.Address, workflowExecutionId [32]byte, reportId [2]byte) (uint8, error) { - return _KeystoneForwarder.Contract.GetTransmissionState(&_KeystoneForwarder.CallOpts, receiver, workflowExecutionId, reportId) +func (_KeystoneForwarder *KeystoneForwarderCallerSession) GetTransmissionInfo(receiver common.Address, workflowExecutionId [32]byte, reportId [2]byte) (IRouterTransmissionInfo, error) { + return _KeystoneForwarder.Contract.GetTransmissionInfo(&_KeystoneForwarder.CallOpts, receiver, workflowExecutionId, reportId) } func (_KeystoneForwarder *KeystoneForwarderCaller) GetTransmitter(opts *bind.CallOpts, receiver common.Address, workflowExecutionId [32]byte, reportId [2]byte) (common.Address, error) { @@ -1260,7 +1269,7 @@ func (_KeystoneForwarder *KeystoneForwarder) Address() common.Address { type KeystoneForwarderInterface interface { GetTransmissionId(opts *bind.CallOpts, receiver common.Address, workflowExecutionId [32]byte, reportId [2]byte) ([32]byte, error) - GetTransmissionState(opts *bind.CallOpts, receiver common.Address, workflowExecutionId [32]byte, reportId [2]byte) (uint8, error) + GetTransmissionInfo(opts *bind.CallOpts, receiver common.Address, workflowExecutionId [32]byte, reportId [2]byte) (IRouterTransmissionInfo, error) GetTransmitter(opts *bind.CallOpts, receiver common.Address, workflowExecutionId [32]byte, reportId [2]byte) (common.Address, error) diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 98d0a4bd02..cae02cda28 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,5 +1,5 @@ GETH_VERSION: 1.13.8 capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin 6d2e3aa3a6f3aed2cf24b613743bb9ae4b9558f48a6864dc03b8b0ebb37235e3 -feeds_consumer: ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin f098e25df6afc100425fcad7f5107aec0844cc98315117e49da139a179d0eead -forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin 21a203d62a69338a5ca260907a31727421114ca25679330ada5d68f0092725bf +feeds_consumer: ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin 8c3a2b18a80be41e7c40d2bc3a4c8d1b5e18d55c1fd20ad5af68cebb66109fc5 +forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin 45d9b866c64b41c1349a90b6764aee42a6d078b454d38f369b5fe02b23b9d16e ocr3_capability: ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.bin 8bf0f53f222efce7143dea6134552eb26ea1eef845407b4475a0d79b7d7ba9f8 diff --git a/core/services/relay/evm/write_target.go b/core/services/relay/evm/write_target.go index fb1c694a2e..6a584413db 100644 --- a/core/services/relay/evm/write_target.go +++ b/core/services/relay/evm/write_target.go @@ -31,8 +31,8 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain "forwarder": { ContractABI: forwarder.KeystoneForwarderABI, Configs: map[string]*relayevmtypes.ChainReaderDefinition{ - "getTransmitter": { - ChainSpecificName: "getTransmitter", + "getTransmissionInfo": { + ChainSpecificName: "getTransmissionInfo", }, }, }, @@ -46,6 +46,7 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain return nil, err } + var gasLimit uint64 = 400_000 chainWriterConfig := relayevmtypes.ChainWriterConfig{ Contracts: map[string]*relayevmtypes.ContractConfig{ "forwarder": { @@ -55,7 +56,7 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain ChainSpecificName: "report", Checker: "simulate", FromAddress: config.FromAddress().Address(), - GasLimit: 200_000, + GasLimit: gasLimit, }, }, }, @@ -73,5 +74,5 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain return nil, err } - return targets.NewWriteTarget(lggr, id, cr, cw, config.ForwarderAddress().String()), nil + return targets.NewWriteTarget(lggr.Named("WriteTarget"), id, cr, cw, config.ForwarderAddress().String(), gasLimit), nil } diff --git a/core/services/relay/evm/write_target_test.go b/core/services/relay/evm/write_target_test.go index f3dcae220e..57a0f80f8d 100644 --- a/core/services/relay/evm/write_target_test.go +++ b/core/services/relay/evm/write_target_test.go @@ -1,7 +1,9 @@ package evm_test import ( + "bytes" "errors" + "fmt" "math/big" "testing" @@ -9,6 +11,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/values" "github.com/smartcontractkit/chainlink/v2/common/headtracker/mocks" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/targets" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" @@ -36,16 +39,72 @@ import ( var forwardABI = types.MustGetABI(forwarder.KeystoneForwarderMetaData.ABI) +func newMockedEncodeTransmissionInfo() ([]byte, error) { + info := targets.TransmissionInfo{ + GasLimit: big.NewInt(0), + InvalidReceiver: false, + State: 0, + Success: false, + TransmissionId: [32]byte{}, + Transmitter: common.HexToAddress("0x0"), + } + + var buffer bytes.Buffer + gasLimitBytes := info.GasLimit.Bytes() + if len(gasLimitBytes) > 80 { + return nil, fmt.Errorf("GasLimit too large") + } + paddedGasLimit := make([]byte, 80-len(gasLimitBytes)) + buffer.Write(paddedGasLimit) + buffer.Write(gasLimitBytes) + + // Encode InvalidReceiver (as uint8) + if info.InvalidReceiver { + buffer.WriteByte(1) + } else { + buffer.WriteByte(0) + } + + // Padding for InvalidReceiver to fit into 32 bytes + padInvalidReceiver := make([]byte, 31) + buffer.Write(padInvalidReceiver) + + // Encode State (as uint8) + buffer.WriteByte(info.State) + + // Padding for State to fit into 32 bytes + padState := make([]byte, 31) + buffer.Write(padState) + + // Encode Success (as uint8) + if info.Success { + buffer.WriteByte(1) + } else { + buffer.WriteByte(0) + } + + // Padding for Success to fit into 32 bytes + padSuccess := make([]byte, 31) + buffer.Write(padSuccess) + + // Encode TransmissionId (as bytes32) + buffer.Write(info.TransmissionId[:]) + + // Encode Transmitter (as address) + buffer.Write(info.Transmitter.Bytes()) + + return buffer.Bytes(), nil +} + func TestEvmWrite(t *testing.T) { chain := evmmocks.NewChain(t) txManager := txmmocks.NewMockEvmTxManager(t) evmClient := evmclimocks.NewClient(t) - // This probably isn't the best way to do this, but couldn't find a simpler way to mock the CallContract response - var mockCall []byte - for i := 0; i < 32; i++ { - mockCall = append(mockCall, byte(0)) - } + // This is a very error-prone way to mock an on-chain response to a GetLatestValue("getTransmissionInfo") call + // It's a bit of a hack, but it's the best way to do it without a lot of refactoring + mockCall, err := newMockedEncodeTransmissionInfo() + require.NoError(t, err) evmClient.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(mockCall, nil).Maybe() evmClient.On("CodeAt", mock.Anything, mock.Anything, mock.Anything).Return([]byte("test"), nil) From 40f4becb1eab96920d8bfd59019cdb9358a94122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Thu, 8 Aug 2024 17:22:15 +0300 Subject: [PATCH 057/432] Fix write target nil dereferences (#14059) * Hardcoded value for call with exact gas * Record gasProvided in route function * Add a getter for transmission gas limit * Update snapshot * Changeset * Remove unused import * Rename to gas limit * Update gethwrappers * Uncomment test code * Remove copy/pasta comment * Slight rename * Allow retrying transmissions with more gas * Only allow retrying failed transmissions * Update snapshot * Fix state for InvalidReceiver check * Check for initial state * Actually store gas limit provided to receiver * Update gethwrappers * Remove unused struct * Correctly mark invalid receiver when receiver interface unsupported * Create TransmissionInfo struct * Update gethwrappers * Bump gas limit * Bump gas even more * Update KeystoneFeedsConsumer.sol to implement IERC165 * Use getTransmissionInfo * Use TransmissionState to determine if transmission should be created * Fix test * Fix trailing line * Update a mock to the GetLatestValue("getTransmissionInfo") call in a test * Remove TODO + replace panic with err * Remove redundant empty lines * Typo * Fix nil pointer dereference in write target implementation * Remove unused constant * Name mapping values * Add changeset --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .changeset/shy-windows-juggle.md | 5 +++ core/capabilities/targets/write_target.go | 8 +++++ .../capabilities/targets/write_target_test.go | 32 ++++++++++++++++--- 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 .changeset/shy-windows-juggle.md diff --git a/.changeset/shy-windows-juggle.md b/.changeset/shy-windows-juggle.md new file mode 100644 index 0000000000..0408383bd0 --- /dev/null +++ b/.changeset/shy-windows-juggle.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index cc3a58b482..4524c4fd44 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -76,6 +76,10 @@ type EvmConfig struct { } func parseConfig(rawConfig *values.Map) (config EvmConfig, err error) { + if rawConfig == nil { + return config, fmt.Errorf("missing config field") + } + if err := rawConfig.UnwrapTo(&config); err != nil { return config, err } @@ -117,6 +121,10 @@ func (cap *WriteTarget) Execute(ctx context.Context, request capabilities.Capabi return nil, err } + if request.Inputs == nil { + return nil, fmt.Errorf("missing inputs field") + } + signedReport, ok := request.Inputs.Underlying[signedReportField] if !ok { return nil, fmt.Errorf("missing required field %s", signedReportField) diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go index 13305fe7ef..0fa750911d 100644 --- a/core/capabilities/targets/write_target_test.go +++ b/core/capabilities/targets/write_target_test.go @@ -134,10 +134,10 @@ func TestWriteTarget(t *testing.T) { }) t.Run("fails with invalid config", func(t *testing.T) { - invalidConfig, err := values.NewMap(map[string]any{ + invalidConfig, err2 := values.NewMap(map[string]any{ "Address": "invalid-address", }) - require.NoError(t, err) + require.NoError(t, err2) req := capabilities.CapabilityRequest{ Metadata: capabilities.RequestMetadata{ @@ -146,7 +146,31 @@ func TestWriteTarget(t *testing.T) { Config: invalidConfig, Inputs: validInputs, } - _, err = writeTarget.Execute(ctx, req) - require.Error(t, err) + _, err2 = writeTarget.Execute(ctx, req) + require.Error(t, err2) + }) + + t.Run("fails with nil config", func(t *testing.T) { + req := capabilities.CapabilityRequest{ + Metadata: capabilities.RequestMetadata{ + WorkflowID: "test-id", + }, + Config: nil, + Inputs: validInputs, + } + _, err2 := writeTarget.Execute(ctx, req) + require.Error(t, err2) + }) + + t.Run("fails with nil inputs", func(t *testing.T) { + req := capabilities.CapabilityRequest{ + Metadata: capabilities.RequestMetadata{ + WorkflowID: "test-id", + }, + Config: config, + Inputs: nil, + } + _, err2 := writeTarget.Execute(ctx, req) + require.Error(t, err2) }) } From 4f0f7802a884e831cd76d9578ee5c4a7134034db Mon Sep 17 00:00:00 2001 From: Dylan Tinianov Date: Thu, 8 Aug 2024 10:33:44 -0400 Subject: [PATCH 058/432] Add Mantle errors (#14053) * Add Mantle errors * Add tests for Mantle errors * changeset * Update seven-kiwis-run.md --- .changeset/seven-kiwis-run.md | 5 +++++ core/chains/evm/client/errors.go | 7 ++++++- core/chains/evm/client/errors_test.go | 3 +++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 .changeset/seven-kiwis-run.md diff --git a/.changeset/seven-kiwis-run.md b/.changeset/seven-kiwis-run.md new file mode 100644 index 0000000000..3b56117c46 --- /dev/null +++ b/.changeset/seven-kiwis-run.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Added custom client error messages for Mantle to capture InsufficientEth and Fatal errors. #added diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index 22fac5f728..5d684d1d17 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -250,6 +250,11 @@ var zkEvm = ClientErrors{ TerminallyStuck: regexp.MustCompile(`(?:: |^)not enough .* counters to continue the execution$`), } +var mantle = ClientErrors{ + InsufficientEth: regexp.MustCompile(`(: |^)'*insufficient funds for gas \* price \+ value`), + Fatal: regexp.MustCompile(`(: |^)'*invalid sender`), +} + const TerminallyStuckMsg = "transaction terminally stuck" // Tx.Error messages that are set internally so they are not chain or client specific @@ -257,7 +262,7 @@ var internal = ClientErrors{ TerminallyStuck: regexp.MustCompile(TerminallyStuckMsg), } -var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm, internal} +var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm, mantle, internal} // ClientErrorRegexes returns a map of compiled regexes for each error type func ClientErrorRegexes(errsRegex config.ClientErrors) *ClientErrors { diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index cca54c2a4a..0d8dddf2a0 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -214,6 +214,7 @@ func Test_Eth_Errors(t *testing.T) { {"insufficient funds for gas + value. balance: 42719769622667482000, fee: 48098250000000, value: 42719769622667482000", true, "celo"}, {"client error insufficient eth", true, "tomlConfig"}, {"transaction would cause overdraft", true, "Geth"}, + {"failed to forward tx to sequencer, please try again. Error message: 'insufficient funds for gas * price + value'", true, "Mantle"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) @@ -379,6 +380,8 @@ func Test_Eth_Errors_Fatal(t *testing.T) { {"Failed to serialize transaction: max priority fee per gas higher than 2^64-1", true, "zkSync"}, {"Failed to serialize transaction: oversized data. max: 1000000; actual: 1000000", true, "zkSync"}, + {"failed to forward tx to sequencer, please try again. Error message: 'invalid sender'", true, "Mantle"}, + {"client error fatal", true, "tomlConfig"}, } From fb2918eb3428594fa819df18dbcd5956a459a39e Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Thu, 8 Aug 2024 17:43:59 +0200 Subject: [PATCH 059/432] [TT-1429] notifying guardian on some failures (#14073) * try with notifying guardian * try notification in reusable workflow * try with env in format * do not add it to reusable * add repository info --- .github/workflows/client-compatibility-tests.yml | 2 +- .github/workflows/integration-tests-publish.yml | 2 +- .github/workflows/integration-tests.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 9c1971abb6..ff776c7906 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -709,7 +709,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "${{ contains(join(needs.*.result, ','), 'failure') && format('Some tests failed, notifying ', secrets.COMPAT_SLACK_NOTIFICATION_HANDLE) || 'All Good!' }}" + "text": "${{ contains(join(needs.*.result, ','), 'failure') && format('Some tests failed, notifying ', secrets.COMPAT_SLACK_NOTIFICATION_HANDLE) || 'All Good!' }}" } }, { diff --git a/.github/workflows/integration-tests-publish.yml b/.github/workflows/integration-tests-publish.yml index 76a86c4323..de551fedce 100644 --- a/.github/workflows/integration-tests-publish.yml +++ b/.github/workflows/integration-tests-publish.yml @@ -54,7 +54,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} with: channel-id: "#team-test-tooling-internal" - slack-message: ":x: :mild-panic-intensifies: Publish Integration Test Image failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}" + slack-message: ":x: :mild-panic-intensifies: Publish Integration Test Image failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}\nRepository: Chainlink\n${{ format('Notifying ', secrets.GUARDIAN_SLACK_NOTIFICATION_HANDLE)}}" build-chainlink-image: environment: integration # Only run this build for workflow_dispatch diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 96a2a7a39f..76f397f046 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -997,7 +997,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} with: channel-id: "#team-test-tooling-internal" - slack-message: ":x: :mild-panic-intensifies: Node Migration Tests Failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}" + slack-message: ":x: :mild-panic-intensifies: Node Migration Tests Failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}\n${{ format('Notifying ', secrets.GUARDIAN_SLACK_NOTIFICATION_HANDLE) }}" ## Solana Section get_solana_sha: From 0f166ad2e101897134ed3a2d75f6f30a4da8089c Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Thu, 8 Aug 2024 08:47:22 -0700 Subject: [PATCH 060/432] [KS-412] Validate called DON membership in TriggerPublisher (#14040) Sender needs to actually belong to the DON on behalf of which it is subscribing trigger events. --- core/capabilities/remote/trigger_publisher.go | 14 ++++++++++++++ core/capabilities/remote/trigger_publisher_test.go | 9 +++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/core/capabilities/remote/trigger_publisher.go b/core/capabilities/remote/trigger_publisher.go index c1f2fb32c5..146b878968 100644 --- a/core/capabilities/remote/trigger_publisher.go +++ b/core/capabilities/remote/trigger_publisher.go @@ -26,6 +26,7 @@ type triggerPublisher struct { capInfo commoncap.CapabilityInfo capDonInfo commoncap.DON workflowDONs map[uint32]commoncap.DON + membersCache map[uint32]map[p2ptypes.PeerID]bool dispatcher types.Dispatcher messageCache *messageCache[registrationKey, p2ptypes.PeerID] registrations map[registrationKey]*pubRegState @@ -54,12 +55,21 @@ func NewTriggerPublisher(config *capabilities.RemoteTriggerConfig, underlying co config = &capabilities.RemoteTriggerConfig{} } config.ApplyDefaults() + membersCache := make(map[uint32]map[p2ptypes.PeerID]bool) + for id, don := range workflowDONs { + cache := make(map[p2ptypes.PeerID]bool) + for _, member := range don.Members { + cache[member] = true + } + membersCache[id] = cache + } return &triggerPublisher{ config: config, underlying: underlying, capInfo: capInfo, capDonInfo: capDonInfo, workflowDONs: workflowDONs, + membersCache: membersCache, dispatcher: dispatcher, messageCache: NewMessageCache[registrationKey, p2ptypes.PeerID](), registrations: make(map[registrationKey]*pubRegState), @@ -88,6 +98,10 @@ func (p *triggerPublisher) Receive(_ context.Context, msg *types.MessageBody) { p.lggr.Errorw("received a message from unsupported workflow DON", "capabilityId", p.capInfo.ID, "callerDonId", msg.CallerDonId) return } + if !p.membersCache[msg.CallerDonId][sender] { + p.lggr.Errorw("sender not a member of its workflow DON", "capabilityId", p.capInfo.ID, "callerDonId", msg.CallerDonId, "sender", sender) + return + } p.lggr.Debugw("received trigger registration", "capabilityId", p.capInfo.ID, "workflowId", req.Metadata.WorkflowID, "sender", sender) key := registrationKey{msg.CallerDonId, req.Metadata.WorkflowID} nowMs := time.Now().UnixMilli() diff --git a/core/capabilities/remote/trigger_publisher_test.go b/core/capabilities/remote/trigger_publisher_test.go index 2c4a851896..32de37a95a 100644 --- a/core/capabilities/remote/trigger_publisher_test.go +++ b/core/capabilities/remote/trigger_publisher_test.go @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-common/pkg/capabilities" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" @@ -42,7 +41,7 @@ func TestTriggerPublisher_Register(t *testing.T) { } dispatcher := remoteMocks.NewDispatcher(t) - config := &capabilities.RemoteTriggerConfig{ + config := &commoncap.RemoteTriggerConfig{ RegistrationRefresh: 100 * time.Millisecond, RegistrationExpiry: 100 * time.Second, MinResponsesToAggregate: 1, @@ -73,6 +72,12 @@ func TestTriggerPublisher_Register(t *testing.T) { Payload: marshaled, } publisher.Receive(ctx, regEvent) + // node p1 is not a member of the workflow DON so registration shoudn't happen + require.Empty(t, underlying.registrationsCh) + + regEvent.Sender = p2[:] + publisher.Receive(ctx, regEvent) + require.NotEmpty(t, underlying.registrationsCh) forwarded := <-underlying.registrationsCh require.Equal(t, capRequest.Metadata.WorkflowID, forwarded.Metadata.WorkflowID) From 375e17b70fe6f17483556a491370e72218896dbc Mon Sep 17 00:00:00 2001 From: Juan Farber Date: Thu, 8 Aug 2024 13:07:13 -0300 Subject: [PATCH 061/432] [BCI-3862][chainlink] - Change DSL Block primitive to string instead of int (#14033) * refactor after modifying block from int to string * bump common version * update avast that was failing * add changeset * fix common references * tidy * update common commit hash * Revert "update common commit hash" This reverts commit 5dbbd031ebced5fc9c1067c69cadce4699b1cf03. * update common commit hash * reference to changes in common * update common ref --- .changeset/thirty-olives-marry.md | 5 +++++ core/chains/evm/logpoller/orm_test.go | 28 ++++++++++++------------ core/chains/evm/logpoller/parser_test.go | 2 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 11 files changed, 32 insertions(+), 27 deletions(-) create mode 100644 .changeset/thirty-olives-marry.md diff --git a/.changeset/thirty-olives-marry.md b/.changeset/thirty-olives-marry.md new file mode 100644 index 0000000000..8be272b935 --- /dev/null +++ b/.changeset/thirty-olives-marry.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Change ChainReader Block primitive field from int to string. #internal diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index ce56c79922..6f431b6db9 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -7,6 +7,7 @@ import ( "fmt" "math" "math/big" + "strconv" "testing" "time" @@ -642,7 +643,7 @@ func TestORM_IndexedLogs(t *testing.T) { require.NoError(t, err) assert.Equal(t, 2, len(lgs)) - blockRangeFilter := func(start, end uint64, topicIdx uint64, topicValues []uint64) query.KeyFilter { + blockRangeFilter := func(start, end string, topicIdx uint64, topicValues []uint64) query.KeyFilter { return query.KeyFilter{ Expressions: []query.Expression{ logpoller.NewAddressFilter(addr), @@ -658,7 +659,7 @@ func TestORM_IndexedLogs(t *testing.T) { require.NoError(t, err) assert.Equal(t, 1, len(lgs)) - lgs, err = o1.FilteredLogs(ctx, blockRangeFilter(1, 1, 1, []uint64{1}), limiter, "") + lgs, err = o1.FilteredLogs(ctx, blockRangeFilter("1", "1", 1, []uint64{1}), limiter, "") require.NoError(t, err) assert.Equal(t, 1, len(lgs)) @@ -666,7 +667,7 @@ func TestORM_IndexedLogs(t *testing.T) { require.NoError(t, err) assert.Equal(t, 1, len(lgs)) - lgs, err = o1.FilteredLogs(ctx, blockRangeFilter(1, 2, 1, []uint64{2}), limiter, "") + lgs, err = o1.FilteredLogs(ctx, blockRangeFilter("1", "2", 1, []uint64{2}), limiter, "") require.NoError(t, err) assert.Equal(t, 1, len(lgs)) @@ -674,7 +675,7 @@ func TestORM_IndexedLogs(t *testing.T) { require.NoError(t, err) assert.Equal(t, 1, len(lgs)) - lgs, err = o1.FilteredLogs(ctx, blockRangeFilter(1, 2, 1, []uint64{1}), limiter, "") + lgs, err = o1.FilteredLogs(ctx, blockRangeFilter("1", "2", 1, []uint64{1}), limiter, "") require.NoError(t, err) assert.Equal(t, 1, len(lgs)) @@ -682,7 +683,7 @@ func TestORM_IndexedLogs(t *testing.T) { require.Error(t, err) assert.Contains(t, err.Error(), "invalid index for topic: 0") - _, err = o1.FilteredLogs(ctx, blockRangeFilter(1, 2, 0, []uint64{1}), limiter, "") + _, err = o1.FilteredLogs(ctx, blockRangeFilter("1", "2", 0, []uint64{1}), limiter, "") require.Error(t, err) assert.Contains(t, err.Error(), "invalid index for topic: 0") @@ -690,7 +691,7 @@ func TestORM_IndexedLogs(t *testing.T) { require.Error(t, err) assert.Contains(t, err.Error(), "invalid index for topic: 4") - _, err = o1.FilteredLogs(ctx, blockRangeFilter(1, 2, 4, []uint64{1}), limiter, "") + _, err = o1.FilteredLogs(ctx, blockRangeFilter("1", "2", 4, []uint64{1}), limiter, "") require.Error(t, err) assert.Contains(t, err.Error(), "invalid index for topic: 4") @@ -1042,7 +1043,7 @@ func TestORM_SelectLogsWithSigsByBlockRangeFilter(t *testing.T) { } require.NoError(t, o1.InsertLogs(ctx, inputLogs)) - filter := func(sigs []common.Hash, startBlock, endBlock int64) query.KeyFilter { + filter := func(sigs []common.Hash, startBlock, endBlock string) query.KeyFilter { filters := []query.Expression{ logpoller.NewAddressFilter(sourceAddr), } @@ -1064,8 +1065,8 @@ func TestORM_SelectLogsWithSigsByBlockRangeFilter(t *testing.T) { filters = append(filters, query.Expression{ BoolExpression: query.BoolExpression{ Expressions: []query.Expression{ - query.Block(uint64(startBlock), primitives.Gte), - query.Block(uint64(endBlock), primitives.Lte), + query.Block(startBlock, primitives.Gte), + query.Block(endBlock, primitives.Lte), }, BoolOperator: query.AND, }, @@ -1097,8 +1098,7 @@ func TestORM_SelectLogsWithSigsByBlockRangeFilter(t *testing.T) { }) assertion(t, logs, err, startBlock, endBlock) - - logs, err = th.ORM.FilteredLogs(ctx, filter([]common.Hash{topic, topic2}, startBlock, endBlock), limiter, "") + logs, err = th.ORM.FilteredLogs(ctx, filter([]common.Hash{topic, topic2}, strconv.Itoa(int(startBlock)), strconv.Itoa(int(endBlock))), limiter, "") assertion(t, logs, err, startBlock, endBlock) } @@ -1160,7 +1160,7 @@ func TestLogPoller_Logs(t *testing.T) { assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000005", lgs[4].BlockHash.String()) assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000005", lgs[5].BlockHash.String()) - logFilter := func(start, end uint64, address common.Address) query.KeyFilter { + logFilter := func(start, end string, address common.Address) query.KeyFilter { return query.KeyFilter{ Expressions: []query.Expression{ logpoller.NewAddressFilter(address), @@ -1181,7 +1181,7 @@ func TestLogPoller_Logs(t *testing.T) { assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000005", lgs[1].BlockHash.String()) assert.Equal(t, address1, lgs[1].Address) - lgs, err = th.ORM.FilteredLogs(ctx, logFilter(1, 3, address1), query.LimitAndSort{ + lgs, err = th.ORM.FilteredLogs(ctx, logFilter("1", "3", address1), query.LimitAndSort{ SortBy: []query.SortBy{query.NewSortBySequence(query.Asc)}, }, "") require.NoError(t, err) @@ -1201,7 +1201,7 @@ func TestLogPoller_Logs(t *testing.T) { assert.Equal(t, address2, lgs[0].Address) assert.Equal(t, event1.Bytes(), lgs[0].Topics[0]) - lgs, err = th.ORM.FilteredLogs(ctx, logFilter(2, 2, address2), query.LimitAndSort{ + lgs, err = th.ORM.FilteredLogs(ctx, logFilter("2", "2", address2), query.LimitAndSort{ SortBy: []query.SortBy{query.NewSortBySequence(query.Asc)}, }, "") require.NoError(t, err) diff --git a/core/chains/evm/logpoller/parser_test.go b/core/chains/evm/logpoller/parser_test.go index 5e99ec7ba8..27af9e8318 100644 --- a/core/chains/evm/logpoller/parser_test.go +++ b/core/chains/evm/logpoller/parser_test.go @@ -141,7 +141,7 @@ func TestDSLParser(t *testing.T) { expressions := []query.Expression{ query.Timestamp(10, primitives.Eq), query.TxHash(common.HexToHash("0x84").String()), - query.Block(99, primitives.Neq), + query.Block("99", primitives.Neq), query.Confidence(primitives.Finalized), } limiter := query.NewLimitAndSort(query.CursorLimit("10-20-0x42", query.CursorPrevious, 20)) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index cd13612743..68b54881fd 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index d8ca90e8b4..c3883a7af6 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1186,8 +1186,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c h1:3apUsez/6Pkp1ckXzSwIhzPRuWjDGjzMjKapEKi0Fcw= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d h1:ATGkySP4ATI2kZ+d9zzNi93iaH0KcDGB8AewI8TJkiI= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/go.mod b/go.mod index f89bfe7def..5c53a04cf2 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index 9679a2da3a..7e91b62afe 100644 --- a/go.sum +++ b/go.sum @@ -1141,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c h1:3apUsez/6Pkp1ckXzSwIhzPRuWjDGjzMjKapEKi0Fcw= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d h1:ATGkySP4ATI2kZ+d9zzNi93iaH0KcDGB8AewI8TJkiI= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 7be6ea209f..1ebda7f521 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -28,7 +28,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d github.com/smartcontractkit/chainlink-testing-framework v1.34.2 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 372a5ee014..a0642a0b92 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1490,8 +1490,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c h1:3apUsez/6Pkp1ckXzSwIhzPRuWjDGjzMjKapEKi0Fcw= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d h1:ATGkySP4ATI2kZ+d9zzNi93iaH0KcDGB8AewI8TJkiI= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 11893540a3..2dec28df99 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.31.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d github.com/smartcontractkit/chainlink-testing-framework v1.34.2 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 97a9dfc8ec..484b5eb248 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1472,8 +1472,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c h1:3apUsez/6Pkp1ckXzSwIhzPRuWjDGjzMjKapEKi0Fcw= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240805160614-501c4f40b98c/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d h1:ATGkySP4ATI2kZ+d9zzNi93iaH0KcDGB8AewI8TJkiI= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= From 98fc8813dd7f46e86a15fc3e838bbb681f835d0b Mon Sep 17 00:00:00 2001 From: Jaden Foldesi Date: Thu, 8 Aug 2024 12:38:20 -0400 Subject: [PATCH 062/432] Add error mapping for Astar (#13990) * add error mapping * add changeset * add tag --------- Co-authored-by: Kodey Thomas --- .changeset/hip-crabs-agree.md | 5 +++++ core/chains/evm/client/errors.go | 6 +++++- core/chains/evm/client/errors_test.go | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .changeset/hip-crabs-agree.md diff --git a/.changeset/hip-crabs-agree.md b/.changeset/hip-crabs-agree.md new file mode 100644 index 0000000000..5085899e3d --- /dev/null +++ b/.changeset/hip-crabs-agree.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added Add Astar TerminallyUnderpriced error mapping diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index 5d684d1d17..da12251474 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -250,6 +250,10 @@ var zkEvm = ClientErrors{ TerminallyStuck: regexp.MustCompile(`(?:: |^)not enough .* counters to continue the execution$`), } +var aStar = ClientErrors{ + TerminallyUnderpriced: regexp.MustCompile(`(?:: |^)(gas price less than block base fee)$`), +} + var mantle = ClientErrors{ InsufficientEth: regexp.MustCompile(`(: |^)'*insufficient funds for gas \* price \+ value`), Fatal: regexp.MustCompile(`(: |^)'*invalid sender`), @@ -262,7 +266,7 @@ var internal = ClientErrors{ TerminallyStuck: regexp.MustCompile(TerminallyStuckMsg), } -var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm, mantle, internal} +var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm, mantle, aStar, internal} // ClientErrorRegexes returns a map of compiled regexes for each error type func ClientErrorRegexes(errsRegex config.ClientErrors) *ClientErrors { diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index 0d8dddf2a0..72fa1347ec 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -166,6 +166,7 @@ func Test_Eth_Errors(t *testing.T) { {"max fee per gas less than block base fee", true, "zkSync"}, {"virtual machine entered unexpected state. please contact developers and provide transaction details that caused this error. Error description: The operator included transaction with an unacceptable gas price", true, "zkSync"}, {"client error terminally underpriced", true, "tomlConfig"}, + {"gas price less than block base fee", true, "aStar"}, } for _, test := range tests { From e0850a6a31843606015d1c49d52b5a6ad8727378 Mon Sep 17 00:00:00 2001 From: Domino Valdano Date: Thu, 8 Aug 2024 10:53:43 -0700 Subject: [PATCH 063/432] BCI-3492 [LogPoller]: Allow withObservedExecAndRowsAffected to report non-zero rows affected (#14057) * Fix withObservedExecAndRowsAffected Also: - Change behavior of DeleteExpiredLogs to delete logs which don't match any filter - Add a test case to ensure the dataset size is published properly during pruning * pnpm changeset * changeset #fix -> #bugfix --- .changeset/sweet-pumas-refuse.md | 5 ++++ core/chains/evm/logpoller/observability.go | 2 +- .../evm/logpoller/observability_test.go | 11 +++++++ core/chains/evm/logpoller/orm.go | 30 ++++++++----------- core/chains/evm/logpoller/orm_test.go | 13 ++++---- 5 files changed, 37 insertions(+), 24 deletions(-) create mode 100644 .changeset/sweet-pumas-refuse.md diff --git a/.changeset/sweet-pumas-refuse.md b/.changeset/sweet-pumas-refuse.md new file mode 100644 index 0000000000..fd642a9c94 --- /dev/null +++ b/.changeset/sweet-pumas-refuse.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#bugfix Addresses 2 minor issues with the pruning of LogPoller's db tables: logs not matching any filter will now be pruned, and rows deleted are now properly reported for observability diff --git a/core/chains/evm/logpoller/observability.go b/core/chains/evm/logpoller/observability.go index 7842a060ec..782307e7d0 100644 --- a/core/chains/evm/logpoller/observability.go +++ b/core/chains/evm/logpoller/observability.go @@ -285,7 +285,7 @@ func withObservedExecAndRowsAffected(o *ObservedORM, queryName string, queryType WithLabelValues(o.chainId, queryName, string(queryType)). Observe(float64(time.Since(queryStarted))) - if err != nil { + if err == nil { o.datasetSize. WithLabelValues(o.chainId, queryName, string(queryType)). Set(float64(rowsAffected)) diff --git a/core/chains/evm/logpoller/observability_test.go b/core/chains/evm/logpoller/observability_test.go index 78c27b4b8f..4ea7adceab 100644 --- a/core/chains/evm/logpoller/observability_test.go +++ b/core/chains/evm/logpoller/observability_test.go @@ -16,6 +16,7 @@ import ( "github.com/prometheus/client_golang/prometheus/testutil" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" @@ -117,6 +118,16 @@ func TestCountersAreProperlyPopulatedForWrites(t *testing.T) { assert.Equal(t, float64(20), testutil.ToFloat64(orm.logsInserted.WithLabelValues("420"))) assert.Equal(t, float64(2), testutil.ToFloat64(orm.blocksInserted.WithLabelValues("420"))) + rowsAffected, err := orm.DeleteExpiredLogs(ctx, 3) + require.NoError(t, err) + require.Equal(t, int64(3), rowsAffected) + assert.Equal(t, 3, counterFromGaugeByLabels(orm.datasetSize, "420", "DeleteExpiredLogs", "delete")) + + rowsAffected, err = orm.DeleteBlocksBefore(ctx, 30, 0) + require.NoError(t, err) + require.Equal(t, int64(2), rowsAffected) + assert.Equal(t, 2, counterFromGaugeByLabels(orm.datasetSize, "420", "DeleteBlocksBefore", "delete")) + // Don't update counters in case of an error require.Error(t, orm.InsertLogsWithBlock(ctx, logs, NewLogPollerBlock(utils.RandomBytes32(), 0, time.Now(), 0))) assert.Equal(t, float64(20), testutil.ToFloat64(orm.logsInserted.WithLabelValues("420"))) diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index 1d24976073..22870efccf 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -313,34 +314,29 @@ type Exp struct { ShouldDelete bool } +// DeleteExpiredLogs removes any logs which either: +// - don't match any currently registered filters, or +// - have a timestamp older than any matching filter's retention, UNLESS there is at +// least one matching filter with retention=0 func (o *DSORM) DeleteExpiredLogs(ctx context.Context, limit int64) (int64, error) { var err error var result sql.Result - if limit > 0 { - result, err = o.ds.ExecContext(ctx, ` - DELETE FROM evm.logs + query := `DELETE FROM evm.logs WHERE (evm_chain_id, address, event_sig, block_number) IN ( SELECT l.evm_chain_id, l.address, l.event_sig, l.block_number FROM evm.logs l - INNER JOIN ( - SELECT address, event, MAX(retention) AS retention + LEFT JOIN ( + SELECT address, event, CASE WHEN MIN(retention) = 0 THEN 0 ELSE MAX(retention) END AS retention FROM evm.log_poller_filters WHERE evm_chain_id = $1 GROUP BY evm_chain_id, address, event - HAVING NOT 0 = ANY(ARRAY_AGG(retention)) ) r ON l.evm_chain_id = $1 AND l.address = r.address AND l.event_sig = r.event - AND l.block_timestamp <= STATEMENT_TIMESTAMP() - (r.retention / 10^9 * interval '1 second') - LIMIT $2 - )`, ubig.New(o.chainID), limit) + WHERE r.retention IS NULL OR (r.retention != 0 AND l.block_timestamp <= STATEMENT_TIMESTAMP() - (r.retention / 10^9 * interval '1 second')) %s)` + + if limit > 0 { + result, err = o.ds.ExecContext(ctx, fmt.Sprintf(query, "LIMIT $2"), ubig.New(o.chainID), limit) } else { - result, err = o.ds.ExecContext(ctx, `WITH r AS - ( SELECT address, event, MAX(retention) AS retention - FROM evm.log_poller_filters WHERE evm_chain_id=$1 - GROUP BY evm_chain_id,address, event HAVING NOT 0 = ANY(ARRAY_AGG(retention)) - ) DELETE FROM evm.logs l USING r - WHERE l.evm_chain_id = $1 AND l.address=r.address AND l.event_sig=r.event - AND l.block_timestamp <= STATEMENT_TIMESTAMP() - (r.retention / 10^9 * interval '1 second')`, // retention is in nanoseconds (time.Duration aka BIGINT) - ubig.New(o.chainID)) + result, err = o.ds.ExecContext(ctx, fmt.Sprintf(query, ""), ubig.New(o.chainID)) } if err != nil { diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index 6f431b6db9..0df34196ff 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -458,20 +458,21 @@ func TestORM(t *testing.T) { time.Sleep(2 * time.Millisecond) // just in case we haven't reached the end of the 1ms retention period deleted, err := o1.DeleteExpiredLogs(ctx, 0) require.NoError(t, err) - assert.Equal(t, int64(1), deleted) + assert.Equal(t, int64(4), deleted) + logs, err = o1.SelectLogsByBlockRange(ctx, 1, latest.BlockNumber) require.NoError(t, err) - // The only log which should be deleted is the one which matches filter1 (ret=1ms) but not filter12 (ret=1 hour) - // Importantly, it shouldn't delete any logs matching only filter0 (ret=0 meaning permanent retention). Anything - // matching filter12 should be kept regardless of what other filters it matches. - assert.Len(t, logs, 7) + // It should have retained the log matching filter0 (due to ret=0 meaning permanent retention) as well as all + // 3 logs matching filter12 (ret=1 hour). It should have deleted 3 logs not matching any filter, as well as 1 + // of the 2 logs matching filter1 (ret=1ms)--the one that doesn't also match filter12. + assert.Len(t, logs, 4) // Delete logs after should delete all logs. err = o1.DeleteLogsAndBlocksAfter(ctx, 1) require.NoError(t, err) logs, err = o1.SelectLogsByBlockRange(ctx, 1, latest.BlockNumber) require.NoError(t, err) - require.Zero(t, len(logs)) + assert.Zero(t, len(logs)) } type PgxLogger struct { From 84630b846894bc3a770e5f8ebf58a6ae7f143669 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 8 Aug 2024 11:05:17 -0700 Subject: [PATCH 064/432] fix: refactor sonarqube scan args (#13875) --- .github/workflows/ci-core.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index aac8e578d1..fc7e6e372d 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -341,37 +341,37 @@ jobs: - name: Download all workflow run artifacts uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - - name: Set SonarQube Report Paths - id: sonarqube_report_paths + - name: Check and Set SonarQube Report Paths shell: bash run: | - echo "sonarqube_tests_report_paths=$(find go_core_tests_logs -name output.txt | paste -sd "," -)" >> $GITHUB_OUTPUT - echo "sonarqube_coverage_report_paths=$(find go_core_tests_logs -name coverage.txt | paste -sd "," -)" >> $GITHUB_OUTPUT - echo "sonarqube_lint_report_paths=$(find golangci-lint-report -name golangci-lint-report.xml | paste -sd "," -)" >> $GITHUB_OUTPUT + sonarqube_tests_report_paths=$(find go_core_tests_logs -name output.txt | paste -sd "," -) + sonarqube_coverage_report_paths=$(find go_core_tests_logs -name coverage.txt | paste -sd "," -) + sonarqube_lint_report_paths=$(find golangci-lint-report -name golangci-lint-report.xml | paste -sd "," -) - - name: Check SonarQube Report Paths - id: check_sonarqube_paths - run: | ARGS="" - if [[ -z "${{ steps.sonarqube_report_paths.outputs.sonarqube_tests_report_paths }}" ]]; then + if [[ -z "$sonarqube_tests_report_paths" ]]; then echo "::warning::No test report paths found, will not pass to sonarqube" else - ARGS="$ARGS -Dsonar.go.tests.reportPaths=${{ steps.sonarqube_report_paths.outputs.sonarqube_tests_report_paths }}" + echo "Found test report paths: $sonarqube_tests_report_paths" + ARGS="$ARGS -Dsonar.go.tests.reportPaths=$sonarqube_tests_report_paths" fi - if [[ -z "${{ steps.sonarqube_report_paths.outputs.sonarqube_coverage_report_paths }}" ]]; then + if [[ -z "$sonarqube_coverage_report_paths" ]]; then echo "::warning::No coverage report paths found, will not pass to sonarqube" else - ARGS="$ARGS -Dsonar.go.coverage.reportPaths=${{ steps.sonarqube_report_paths.outputs.sonarqube_coverage_report_paths }}" + echo "Found coverage report paths: $sonarqube_coverage_report_paths" + ARGS="$ARGS -Dsonar.go.coverage.reportPaths=$sonarqube_coverage_report_paths" fi - if [[ -z "${{ steps.sonarqube_report_paths.outputs.sonarqube_lint_report_paths }}" ]]; then + if [[ -z "$sonarqube_lint_report_paths" ]]; then echo "::warning::No lint report paths found, will not pass to sonarqube" else - ARGS="$ARGS -Dsonar.go.golangci-lint.reportPaths=${{ steps.sonarqube_report_paths.outputs.sonarqube_lint_report_paths }}" + echo "Found lint report paths: $sonarqube_lint_report_paths" + ARGS="$ARGS -Dsonar.go.golangci-lint.reportPaths=$sonarqube_lint_report_paths" fi + echo "Final SONARQUBE_ARGS: $ARGS" echo "SONARQUBE_ARGS=$ARGS" >> $GITHUB_ENV - name: SonarQube Scan From 08638ff2b963b1afe731de9910f73654914a45ff Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Thu, 8 Aug 2024 20:13:25 +0200 Subject: [PATCH 065/432] CRIB CI integration (#13924) * decouple CRIB vars * move CRIB vars to CTF, connect with GAP * bump deps * finalize deps * update go.mod * Spin up a separate GAP for crib and k8s * Change up the ports since 8080 is expected for CRIB connections * Use released version of setup-gap action * increase timeout * less logs * increase timeout * increase timeout even more * try creds for one hour * run without chaos * again * try to spin up CRIB * use GATI * update GATI secrets * use different port * fix working dir * update ref * try fixing working dir * another try * another try * another try * another try * nix develop * Fix nix develop * turn debug logs on * use local-dev-simulated-core-ocr1 profile * add teardown step * uppdate crib actions refs * add ref comments * reduce logging * add a confluence link * pin CI versions * temporary enable a nightly run --------- Co-authored-by: chainchad <96362174+chainchad@users.noreply.github.com> Co-authored-by: Radek Scheibinger --- .github/workflows/crib-integration-test.yml | 183 +++++++++++------- integration-tests/README.md | 6 + .../actions/vrf/common/actions.go | 2 +- integration-tests/client/chainlink.go | 16 +- integration-tests/client/chainlink_k8s.go | 7 +- integration-tests/client/chainlink_models.go | 11 +- integration-tests/crib/README.md | 17 +- integration-tests/crib/connect.go | 87 +++------ integration-tests/crib/ocr_test.go | 39 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- integration-tests/smoke/README.md | 6 - integration-tests/testsetups/ocr.go | 1 - 13 files changed, 199 insertions(+), 182 deletions(-) diff --git a/.github/workflows/crib-integration-test.yml b/.github/workflows/crib-integration-test.yml index 75b2215d2f..248004636b 100644 --- a/.github/workflows/crib-integration-test.yml +++ b/.github/workflows/crib-integration-test.yml @@ -1,74 +1,111 @@ -# this is disabled because of GAP limitations, should be re-enabled when github-actions-controller will be installed +name: CRIB Integration Tests +on: + schedule: + - cron: "0 1 * * *" + workflow_call: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +jobs: + test: + runs-on: ubuntu-latest + environment: integration + permissions: + id-token: write + contents: read + actions: read + steps: + - name: Checkout repository + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 -#name: CRIB Integration Tests -#on: -# push: -# workflow_call: -#concurrency: -# group: ${{ github.workflow }}-${{ github.ref }} -# cancel-in-progress: true -#jobs: -# test: -# runs-on: ubuntu-latest -# environment: integration -# permissions: -# id-token: write -# contents: read -# actions: read -# steps: -# - name: Checkout repository -# uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 -# -# - name: Setup Nix + GATI environment -# uses: smartcontractkit/.github/actions/setup-nix-gati@514fe346780e2eddf7ea8b9f48120c2fba120d94 -# with: -# aws-role-arn: ${{ secrets.AWS_OIDC_CHAINLINK_AUTO_PR_TOKEN_ISSUER_ROLE_ARN }} -# aws-lambda-url: ${{ secrets.AWS_CORE_TOKEN_ISSUER_LAMBDA_URL }} # see https://github.com/smartcontractkit/ infra/blob/a79bcfb48315c4411023c182e98eb80ff9e9cda6/accounts/production/us-west-2/lambda/ github-app-token-issuer-production/teams/releng/config.json#L9 -# aws-region: ${{ secrets.AWS_REGION }} -# aws-role-duration-seconds: ${{ secrets.AWS_ROLE_DURATION_SECONDS }} -# enable-magic-cache: true -# -# - name: Nix Develop Action -# uses: nicknovitski/nix-develop@v1 -# with: -# arguments: "--accept-flake-config" -# - name: setup-gap -# uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 -# with: -# aws-role-arn: ${{ secrets.AWS_OIDC_CRIB_ROLE_ARN_STAGE }} -# api-gateway-host: ${{ secrets.AWS_API_GW_HOST_K8S_STAGE }} -# aws-region: ${{ secrets.AWS_REGION }} -# ecr-private-registry: ${{ secrets.AWS_ACCOUNT_ID_PROD }} -# k8s-cluster-name: ${{ secrets.AWS_K8S_CLUSTER_NAME_STAGE }} -# use-private-ecr-registry: true -# use-k8s: true -# metrics-job-name: "k8s" -# gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} -# gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }} -# gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} -# - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 -# name: Checkout CRIB repository -# with: -# repository: 'smartcontractkit/crib' -# ref: 'main' -# - name: Generate Short UUID -# id: uuid -# run: echo "CRIB_NAMESPACE=$(uuidgen | cut -c1-5)" >> $GITHUB_ENV -# - name: Create a new CRIB environment -# run: |- -# devspace use namespace $CRIB_NAMESPACE -# devspace deploy --profile local-dev-simulated-core-ocr1 -# - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 -# - name: Setup go -# uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 -# with: -# go-version-file: "go.mod" -# - name: Run CRIB integration test -# working-directory: integration-tests/crib -# env: -# K8S_STAGING_INGRESS_SUFFIX: ${{ secrets.K8S_STAGING_INGRESS_SUFFIX }} -# CRIB_NAMESPACE: ${{ env.CRIB_NAMESPACE }} -# CRIB_NETWORK: geth -# CRIB_NODES: 5 -# run: |- -# go test -v -run TestCRIB \ No newline at end of file + - uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27 + with: + nix_path: nixpkgs=channel:nixos-unstable + + - name: setup-gap crib + uses: smartcontractkit/.github/actions/setup-gap@00b58566e0ee2761e56d9db0ea72b783fdb89b8d # setup-gap@0.4.0 + with: + aws-role-duration-seconds: 3600 # 1 hour + aws-role-arn: ${{ secrets.AWS_OIDC_CRIB_ROLE_ARN_STAGE }} + api-gateway-host: ${{ secrets.AWS_API_GW_HOST_CRIB_STAGE }} + aws-region: ${{ secrets.AWS_REGION }} + ecr-private-registry: ${{ secrets.AWS_ACCOUNT_ID_PROD }} + k8s-cluster-name: ${{ secrets.AWS_K8S_CLUSTER_NAME_STAGE }} + gap-name: crib + use-private-ecr-registry: true + use-tls: true + proxy-port: 8080 + metrics-job-name: "test" + gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }} + gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + + - name: setup-gap k8s + uses: smartcontractkit/.github/actions/setup-gap@00b58566e0ee2761e56d9db0ea72b783fdb89b8d # setup-gap@0.4.0 + with: + aws-role-duration-seconds: 3600 # 1 hour + aws-role-arn: ${{ secrets.AWS_OIDC_CRIB_ROLE_ARN_STAGE }} + api-gateway-host: ${{ secrets.AWS_API_GW_HOST_K8S_STAGE }} + aws-region: ${{ secrets.AWS_REGION }} + ecr-private-registry: ${{ secrets.AWS_ACCOUNT_ID_PROD }} + k8s-cluster-name: ${{ secrets.AWS_K8S_CLUSTER_NAME_STAGE }} + gap-name: k8s + use-private-ecr-registry: true + use-k8s: true + proxy-port: 8443 + metrics-job-name: "test" + gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }} + gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + + - name: Setup GitHub token using GATI + id: token + uses: smartcontractkit/.github/actions/setup-github-token@c0b38e6c40d72d01b8d2f24f92623a2538b3dedb # main + with: + aws-role-arn: ${{ secrets.AWS_OIDC_GLOBAL_READ_ONLY_TOKEN_ISSUER_ROLE_ARN }} + aws-lambda-url: ${{ secrets.AWS_INFRA_RELENG_TOKEN_ISSUER_LAMBDA_URL }} + aws-region: ${{ secrets.AWS_REGION }} + aws-role-duration-seconds: "1800" + - name: Debug workspace dir + shell: bash + run: | + echo ${{ github.workspace }} + echo $GITHUB_WORKSPACE + + - name: Deploy and validate CRIB Environment for Core + uses: smartcontractkit/.github/actions/crib-deploy-environment@c0b38e6c40d72d01b8d2f24f92623a2538b3dedb # crib-deploy-environment@0.5.0 + id: deploy-crib + with: + github-token: ${{ steps.token.outputs.access-token }} + api-gateway-host: ${{ secrets.AWS_API_GW_HOST_K8S_STAGE }} + aws-region: ${{ secrets.AWS_REGION }} + aws-role-arn: ${{ secrets.AWS_OIDC_CRIB_ROLE_ARN_STAGE }} + ecr-private-registry-stage: ${{ secrets.AWS_ACCOUNT_ID_STAGE }} + ecr-private-registry: ${{ secrets.AWS_ACCOUNT_ID_PROD }} + ingress-base-domain: ${{ secrets.INGRESS_BASE_DOMAIN_STAGE }} + k8s-cluster-name: ${{ secrets.AWS_K8S_CLUSTER_NAME_STAGE }} + devspace-profiles: "local-dev-simulated-core-ocr1" + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - name: Setup go + uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + with: + go-version-file: "go.mod" + - name: Run CRIB integration test + working-directory: integration-tests/crib + env: + K8S_STAGING_INGRESS_SUFFIX: ${{ secrets.K8S_STAGING_INGRESS_SUFFIX }} + CRIB_NAMESPACE: ${{ steps.deploy-crib.outputs.devspace-namespace }} + CRIB_NETWORK: geth + CRIB_NODES: 5 + GAP_URL: ${{ secrets.GAP_URL }} +# SETH_LOG_LEVEL: debug +# RESTY_DEBUG: true +# TEST_PERSISTENCE: true + run: |- + go test -v -run TestCRIB + - name: Destroy CRIB Environment + id: destroy + if: always() && steps.deploy-crib.outputs.devspace-namespace != '' + uses: smartcontractkit/.github/actions/crib-purge-environment@c0b38e6c40d72d01b8d2f24f92623a2538b3dedb # crib-purge-environment@0.1.0 + with: + namespace: ${{ steps.deploy-crib.outputs.devspace-namespace }} \ No newline at end of file diff --git a/integration-tests/README.md b/integration-tests/README.md index 180021efee..1510c8c91b 100644 --- a/integration-tests/README.md +++ b/integration-tests/README.md @@ -129,3 +129,9 @@ Run soak/ocr_test.go with RPC network chaos by bringing down network to RPC node ```bash make test_soak_ocr_rpc_down_half_cl_nodes ``` + +### Debugging HTTP and RPC clients +```bash +export SETH_LOG_LEVEL=debug +export RESTY_DEBUG=true +``` diff --git a/integration-tests/actions/vrf/common/actions.go b/integration-tests/actions/vrf/common/actions.go index 1300ac8b72..5697a26176 100644 --- a/integration-tests/actions/vrf/common/actions.go +++ b/integration-tests/actions/vrf/common/actions.go @@ -429,7 +429,7 @@ type RPCRawClient struct { } func NewRPCRawClient(url string) *RPCRawClient { - isDebug := os.Getenv("DEBUG_RESTY") == "true" + isDebug := os.Getenv("RESTY_DEBUG") == "true" restyClient := resty.New().SetDebug(isDebug).SetBaseURL(url) return &RPCRawClient{ resty: restyClient, diff --git a/integration-tests/client/chainlink.go b/integration-tests/client/chainlink.go index 08a47101dc..da17dcf0d7 100644 --- a/integration-tests/client/chainlink.go +++ b/integration-tests/client/chainlink.go @@ -2,6 +2,7 @@ package client import ( + "crypto/tls" "fmt" "math/big" "net/http" @@ -45,14 +46,10 @@ type ChainlinkClient struct { // NewChainlinkClient creates a new Chainlink model using a provided config func NewChainlinkClient(c *ChainlinkConfig, logger zerolog.Logger) (*ChainlinkClient, error) { - rc, err := initRestyClient(c.URL, c.Email, c.Password, c.HTTPTimeout) + rc, err := initRestyClient(c.URL, c.Email, c.Password, c.Headers, c.HTTPTimeout) if err != nil { return nil, err } - _, isSet := os.LookupEnv("CL_CLIENT_DEBUG") - if isSet { - rc.SetDebug(true) - } return &ChainlinkClient{ Config: c, APIClient: rc, @@ -61,8 +58,11 @@ func NewChainlinkClient(c *ChainlinkConfig, logger zerolog.Logger) (*ChainlinkCl }, nil } -func initRestyClient(url string, email string, password string, timeout *time.Duration) (*resty.Client, error) { - rc := resty.New().SetBaseURL(url) +func initRestyClient(url string, email string, password string, headers map[string]string, timeout *time.Duration) (*resty.Client, error) { + isDebug := os.Getenv("RESTY_DEBUG") == "true" + // G402 - TODO: certificates + //nolint + rc := resty.New().SetBaseURL(url).SetHeaders(headers).SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).SetDebug(isDebug) if timeout != nil { rc.SetTimeout(*timeout) } @@ -74,7 +74,7 @@ func initRestyClient(url string, email string, password string, timeout *time.Du for i := 0; i < retryCount; i++ { resp, err = rc.R().SetBody(session).Post("/sessions") if err != nil { - log.Debug().Err(err).Str("URL", url).Interface("Session Details", session).Msg("Error connecting to Chainlink node, retrying") + log.Warn().Err(err).Str("URL", url).Interface("Session Details", session).Msg("Error connecting to Chainlink node, retrying") time.Sleep(5 * time.Second) } else { break diff --git a/integration-tests/client/chainlink_k8s.go b/integration-tests/client/chainlink_k8s.go index 794e93f727..077b8f7ca4 100644 --- a/integration-tests/client/chainlink_k8s.go +++ b/integration-tests/client/chainlink_k8s.go @@ -2,7 +2,6 @@ package client import ( - "os" "regexp" "github.com/rs/zerolog/log" @@ -23,14 +22,10 @@ type ChainlinkK8sClient struct { // NewChainlink creates a new Chainlink model using a provided config func NewChainlinkK8sClient(c *ChainlinkConfig, podName, chartName string) (*ChainlinkK8sClient, error) { - rc, err := initRestyClient(c.URL, c.Email, c.Password, c.HTTPTimeout) + rc, err := initRestyClient(c.URL, c.Email, c.Password, c.Headers, c.HTTPTimeout) if err != nil { return nil, err } - _, isSet := os.LookupEnv("CL_CLIENT_DEBUG") - if isSet { - rc.SetDebug(true) - } return &ChainlinkK8sClient{ ChainlinkClient: &ChainlinkClient{ APIClient: rc, diff --git a/integration-tests/client/chainlink_models.go b/integration-tests/client/chainlink_models.go index a0435d5336..86e9f75902 100644 --- a/integration-tests/client/chainlink_models.go +++ b/integration-tests/client/chainlink_models.go @@ -20,11 +20,12 @@ type EIServiceConfig struct { // ChainlinkConfig represents the variables needed to connect to a Chainlink node type ChainlinkConfig struct { - URL string `toml:",omitempty"` - Email string `toml:",omitempty"` - Password string `toml:",omitempty"` - InternalIP string `toml:",omitempty"` - HTTPTimeout *time.Duration `toml:"-"` + URL string `toml:",omitempty"` + Email string `toml:",omitempty"` + Password string `toml:",omitempty"` + InternalIP string `toml:",omitempty"` + Headers map[string]string `toml:",omitempty"` + HTTPTimeout *time.Duration `toml:"-"` } // ResponseSlice is the generic model that can be used for all Chainlink API responses that are an slice diff --git a/integration-tests/crib/README.md b/integration-tests/crib/README.md index ecf393f780..e895cca676 100644 --- a/integration-tests/crib/README.md +++ b/integration-tests/crib/README.md @@ -1,4 +1,4 @@ -### CRIB Health Check Test +### Example e2e product test using CRIB ## Setup CRIB This is a simple smoke + chaos test for CRIB deployment. @@ -12,8 +12,15 @@ devspace deploy --debug --profile local-dev-simulated-core-ocr1 ## Run the tests ```shell -CRIB_NAMESPACE=crib-oh-my-crib -CRIB_NETWORK=geth # only "geth" is supported for now -CRIB_NODES=5 # min 5 nodes +export CRIB_NAMESPACE=crib-oh-my-crib +export CRIB_NETWORK=geth # only "geth" is supported for now +export CRIB_NODES=5 # min 5 nodes +#export SETH_LOG_LEVEL=debug # these two can be enabled to debug connection issues +#export RESTY_DEBUG=true +#export TEST_PERSISTENCE=true # to run the chaos test +export GAP_URL=https://localhost:8080/primary # only applicable in CI, unset the var to connect locally go test -v -run TestCRIB -``` \ No newline at end of file +``` + +## Configuring CI workflow +We are using GAP and GATI to access the infrastructure, please follow [configuration guide](https://smartcontract-it.atlassian.net/wiki/spaces/CRIB/pages/909967436/CRIB+CI+Integration) \ No newline at end of file diff --git a/integration-tests/crib/connect.go b/integration-tests/crib/connect.go index 91d7d8ee1a..c180b2ff2e 100644 --- a/integration-tests/crib/connect.go +++ b/integration-tests/crib/connect.go @@ -1,11 +1,11 @@ package crib import ( - "fmt" - "os" - "strconv" + "net/http" "time" + "github.com/smartcontractkit/chainlink-testing-framework/crib" + "github.com/pkg/errors" "github.com/smartcontractkit/seth" @@ -18,17 +18,7 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/client" ) -const ( - // these are constants for simulated CRIB that should never change - // CRIB: https://github.com/smartcontractkit/crib/tree/main/core - // Core Chart: https://github.com/smartcontractkit/infra-charts/tree/main/chainlink-cluster - mockserverCRIBTemplate = "https://%s-mockserver%s" - internalNodeDNSTemplate = "app-node%d" - ingressNetworkWSURLTemplate = "wss://%s-geth-1337-ws%s" - ingressNetworkHTTPURLTemplate = "https://%s-geth-1337-http%s" -) - -func setSethConfig(cfg tc.TestConfig, netWSURL string, netHTTPURL string) { +func setSethConfig(cfg tc.TestConfig, netWSURL string, netHTTPURL string, headers http.Header) { netName := "CRIB_SIMULATED" cfg.Network.SelectedNetworks = []string{netName} cfg.Network.RpcHttpUrls = map[string][]string{} @@ -36,6 +26,7 @@ func setSethConfig(cfg tc.TestConfig, netWSURL string, netHTTPURL string) { cfg.Network.RpcWsUrls = map[string][]string{} cfg.Network.RpcWsUrls[netName] = []string{netWSURL} cfg.Seth.EphemeralAddrs = ptr.Ptr(int64(0)) + cfg.Seth.RPCHeaders = headers } // ConnectRemote connects to a local environment, see https://github.com/smartcontractkit/crib/tree/main/core @@ -47,52 +38,33 @@ func ConnectRemote() ( []*client.ChainlinkK8sClient, error, ) { - ingressSuffix := os.Getenv("K8S_STAGING_INGRESS_SUFFIX") - if ingressSuffix == "" { - return nil, nil, nil, nil, errors.New("K8S_STAGING_INGRESS_SUFFIX must be set to connect to k8s ingresses") - } - cribNamespace := os.Getenv("CRIB_NAMESPACE") - if cribNamespace == "" { - return nil, nil, nil, nil, errors.New("CRIB_NAMESPACE must be set to connect") - } - cribNetwork := os.Getenv("CRIB_NETWORK") - if cribNetwork == "" { - return nil, nil, nil, nil, errors.New("CRIB_NETWORK must be set to connect, only 'geth' is supported for now") - } - cribNodes := os.Getenv("CRIB_NODES") - nodes, err := strconv.Atoi(cribNodes) + vars, err := crib.CoreDONSimulatedConnection() if err != nil { - return nil, nil, nil, nil, errors.New("CRIB_NODES must be a number, 5-19 nodes") + return nil, nil, nil, nil, err } + // TODO: move all the parts of ConnectRemote() to CTF when Seth config refactor is finalized config, err := tc.GetConfig([]string{"CRIB"}, tc.OCR) if err != nil { return nil, nil, nil, nil, err } - if nodes < 2 { - return nil, nil, nil, nil, fmt.Errorf("not enough chainlink nodes, need at least 2, TOML key: [CRIB.nodes]") - } - mockserverURL := fmt.Sprintf(mockserverCRIBTemplate, cribNamespace, ingressSuffix) var sethClient *seth.Client - switch cribNetwork { + switch vars.Network { case "geth": - netWSURL := fmt.Sprintf(ingressNetworkWSURLTemplate, cribNamespace, ingressSuffix) - netHTTPURL := fmt.Sprintf(ingressNetworkHTTPURLTemplate, cribNamespace, ingressSuffix) - setSethConfig(config, netWSURL, netHTTPURL) + setSethConfig(config, vars.NetworkWSURL, vars.NetworkHTTPURL, vars.BlockchainNodeHeaders) net := blockchain.EVMNetwork{ - Name: cribNetwork, - Simulated: true, - SupportsEIP1559: true, - ClientImplementation: blockchain.EthereumClientImplementation, - ChainID: 1337, - PrivateKeys: []string{ - "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", - }, - URLs: []string{netWSURL}, - HTTPURLs: []string{netHTTPURL}, + Name: vars.Network, + Simulated: true, + SupportsEIP1559: true, + ClientImplementation: blockchain.EthereumClientImplementation, + ChainID: vars.ChainID, + PrivateKeys: vars.PrivateKeys, + URLs: []string{vars.NetworkWSURL}, + HTTPURLs: []string{vars.NetworkHTTPURL}, ChainlinkTransactionLimit: 500000, Timeout: blockchain.StrDuration{Duration: 2 * time.Minute}, MinimumConfirmations: 1, GasEstimationBuffer: 10000, + Headers: vars.BlockchainNodeHeaders, } sethClient, err = seth_utils.GetChainClient(config, net) if err != nil { @@ -104,31 +76,34 @@ func ConnectRemote() ( // bootstrap node clClients := make([]*client.ChainlinkK8sClient, 0) c, err := client.NewChainlinkK8sClient(&client.ChainlinkConfig{ - URL: fmt.Sprintf("https://%s-node%d%s", cribNamespace, 1, ingressSuffix), Email: client.CLNodeTestEmail, - InternalIP: fmt.Sprintf(internalNodeDNSTemplate, 1), Password: client.CLNodeTestPassword, - }, fmt.Sprintf(internalNodeDNSTemplate, 1), cribNamespace) + URL: vars.NodeURLs[0], + InternalIP: vars.NodeInternalDNS[0], + Headers: vars.NodeHeaders[0], + }, vars.NodeInternalDNS[0], vars.Namespace) if err != nil { return nil, nil, nil, nil, err } clClients = append(clClients, c) // all the other nodes, indices of nodes in CRIB starts with 1 - for i := 2; i <= nodes; i++ { + for i := 1; i < vars.Nodes; i++ { cl, err := client.NewChainlinkK8sClient(&client.ChainlinkConfig{ - URL: fmt.Sprintf("https://%s-node%d%s", cribNamespace, i, ingressSuffix), Email: client.CLNodeTestEmail, - InternalIP: fmt.Sprintf(internalNodeDNSTemplate, i), Password: client.CLNodeTestPassword, - }, fmt.Sprintf(internalNodeDNSTemplate, i), cribNamespace) + URL: vars.NodeURLs[i], + InternalIP: vars.NodeInternalDNS[i], + Headers: vars.NodeHeaders[i], + }, vars.NodeInternalDNS[i], vars.Namespace) if err != nil { return nil, nil, nil, nil, err } clClients = append(clClients, cl) } mockServerClient := msClient.NewMockserverClient(&msClient.MockserverConfig{ - LocalURL: mockserverURL, - ClusterURL: mockserverURL, + LocalURL: vars.MockserverURL, + ClusterURL: "http://mockserver:1080", + Headers: vars.MockserverHeaders, }) //nolint:gosec // G602 - false positive https://github.com/securego/gosec/issues/1005 diff --git a/integration-tests/crib/ocr_test.go b/integration-tests/crib/ocr_test.go index b84af02a19..91a7a1d76b 100644 --- a/integration-tests/crib/ocr_test.go +++ b/integration-tests/crib/ocr_test.go @@ -7,6 +7,7 @@ import ( "time" "github.com/smartcontractkit/havoc/k8schaos" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/integration-tests/actions" @@ -33,22 +34,24 @@ func TestCRIB(t *testing.T) { err = actions.WatchNewOCRRound(l, sethClient, 1, contracts.V1OffChainAgrregatorToOffChainAggregatorWithRounds(ocrInstances), 5*time.Minute) require.NoError(t, err, "Error watching for new OCR round") - ch, err := rebootCLNamespace( - 1*time.Second, - os.Getenv("CRIB_NAMESPACE"), - ) - ch.Create(context.Background()) - ch.AddListener(k8schaos.NewChaosLogger(l)) - t.Cleanup(func() { - err := ch.Delete(context.Background()) - require.NoError(t, err) - }) - require.Eventually(t, func() bool { - err = actions.WatchNewOCRRound(l, sethClient, 3, contracts.V1OffChainAgrregatorToOffChainAggregatorWithRounds(ocrInstances), 5*time.Minute) - if err != nil { - l.Info().Err(err).Msg("OCR round is not there yet") - return false - } - return true - }, 3*time.Minute, 5*time.Second) + if os.Getenv("TEST_PERSISTENCE") != "" { + ch, err := rebootCLNamespace( + 1*time.Second, + os.Getenv("CRIB_NAMESPACE"), + ) + ch.Create(context.Background()) + ch.AddListener(k8schaos.NewChaosLogger(l)) + t.Cleanup(func() { + err := ch.Delete(context.Background()) + require.NoError(t, err) + }) + require.Eventually(t, func() bool { + err = actions.WatchNewOCRRound(l, sethClient, 3, contracts.V1OffChainAgrregatorToOffChainAggregatorWithRounds(ocrInstances), 5*time.Minute) + if err != nil { + l.Info().Err(err).Msg("OCR round is not there yet") + return false + } + return true + }, 20*time.Minute, 5*time.Second) + } } diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 2dec28df99..bd47a97f48 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -375,7 +375,7 @@ require ( github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect - github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 // indirect + github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a // indirect github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.7.3 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 484b5eb248..7789b94944 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1486,8 +1486,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202407 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/chainlink-testing-framework v1.34.2 h1:YL3ft7KJB7SAopdmJeyeR4/kv0j4jOdagNihXq8OZ38= github.com/smartcontractkit/chainlink-testing-framework v1.34.2/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a h1:8GtvGJaGyKzx/ar1yX74GxrzIYWTZVTyv4pYB/1ln8w= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= diff --git a/integration-tests/smoke/README.md b/integration-tests/smoke/README.md index 266720c7bc..c4aa2b91a1 100644 --- a/integration-tests/smoke/README.md +++ b/integration-tests/smoke/README.md @@ -75,9 +75,3 @@ Then execute: go test -v -run ${TestName} ``` - - -### Debugging CL client API calls -```bash -export CL_CLIENT_DEBUG=true -``` \ No newline at end of file diff --git a/integration-tests/testsetups/ocr.go b/integration-tests/testsetups/ocr.go index b38c39eebe..084ea5eca1 100644 --- a/integration-tests/testsetups/ocr.go +++ b/integration-tests/testsetups/ocr.go @@ -547,7 +547,6 @@ func (o *OCRSoakTest) LoadState() error { } o.mockServer = ctf_client.ConnectMockServerURL(testState.MockServerURL) - return err } From ebd45cef2a19b14ca5e3e394007d746feee5a852 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Thu, 8 Aug 2024 16:05:16 -0400 Subject: [PATCH 066/432] RE-2859 Make jira ticket linkage obligatory in PRs with solidity changes (#14054) * Split out lib functions into their own file * Create issue enforcement option * Setup solidity-jira workflow * chore: Improve error message for JIRA issue key not found --- .github/scripts/jira/enforce-jira-issue.ts | 77 ++++++++++++++ ...{update-jira-issue.test.ts => lib.test.ts} | 13 ++- .github/scripts/jira/lib.ts | 63 +++++++++++ .github/scripts/jira/package.json | 4 +- .github/scripts/jira/update-jira-issue.ts | 59 +---------- .github/workflows/changeset.yml | 2 +- .github/workflows/solidity-jira.yml | 100 ++++++++++++++++++ 7 files changed, 257 insertions(+), 61 deletions(-) create mode 100644 .github/scripts/jira/enforce-jira-issue.ts rename .github/scripts/jira/{update-jira-issue.test.ts => lib.test.ts} (78%) create mode 100644 .github/scripts/jira/lib.ts create mode 100644 .github/workflows/solidity-jira.yml diff --git a/.github/scripts/jira/enforce-jira-issue.ts b/.github/scripts/jira/enforce-jira-issue.ts new file mode 100644 index 0000000000..e0054b25d0 --- /dev/null +++ b/.github/scripts/jira/enforce-jira-issue.ts @@ -0,0 +1,77 @@ +import * as core from "@actions/core"; +import jira from "jira.js"; +import { createJiraClient, parseIssueNumberFrom } from "./lib"; + +async function doesIssueExist( + client: jira.Version3Client, + issueNumber: string, + dryRun: boolean +) { + const payload = { + issueIdOrKey: issueNumber, + }; + + if (dryRun) { + core.info("Dry run enabled, skipping JIRA issue enforcement"); + return true; + } + + try { + /** + * The issue is identified by its ID or key, however, if the identifier doesn't match an issue, a case-insensitive search and check for moved issues is performed. + * If a matching issue is found its details are returned, a 302 or other redirect is not returned. The issue key returned in the response is the key of the issue found. + */ + const issue = await client.issues.getIssue(payload); + core.debug( + `JIRA issue id:${issue.id} key: ${issue.key} found while querying for ${issueNumber}` + ); + if (issue.key !== issueNumber) { + core.error( + `JIRA issue key ${issueNumber} not found, but found issue key ${issue.key} instead. This can happen if the identifier doesn't match an issue, in which case a case-insensitive search and check for moved issues is performed. Make sure the issue key is correct.` + ); + return false; + } + + return true; + } catch (e) { + core.debug(e as any); + return false; + } +} + +async function main() { + const prTitle = process.env.PR_TITLE; + const commitMessage = process.env.COMMIT_MESSAGE; + const branchName = process.env.BRANCH_NAME; + const dryRun = !!process.env.DRY_RUN; + const client = createJiraClient(); + + // Checks for the Jira issue number and exit if it can't find it + const issueNumber = parseIssueNumberFrom(prTitle, commitMessage, branchName); + if (!issueNumber) { + const msg = + "No JIRA issue number found in PR title, commit message, or branch name. This pull request must be associated with a JIRA issue."; + + core.setFailed(msg); + return; + } + + const exists = await doesIssueExist(client, issueNumber, dryRun); + if (!exists) { + core.setFailed(`JIRA issue ${issueNumber} not found, this pull request must be associated with a JIRA issue.`); + return; + } +} + +async function run() { + try { + await main(); + } catch (error) { + if (error instanceof Error) { + return core.setFailed(error.message); + } + core.setFailed(error as any); + } +} + +run(); diff --git a/.github/scripts/jira/update-jira-issue.test.ts b/.github/scripts/jira/lib.test.ts similarity index 78% rename from .github/scripts/jira/update-jira-issue.test.ts rename to .github/scripts/jira/lib.test.ts index c9efebc92d..9c751e8408 100644 --- a/.github/scripts/jira/update-jira-issue.test.ts +++ b/.github/scripts/jira/lib.test.ts @@ -1,5 +1,5 @@ import { expect, describe, it } from "vitest"; -import { parseIssueNumberFrom, tagsToLabels } from "./update-jira-issue"; +import { parseIssueNumberFrom, tagsToLabels } from "./lib"; describe("parseIssueNumberFrom", () => { it("should return the first JIRA issue number found", () => { @@ -18,6 +18,17 @@ describe("parseIssueNumberFrom", () => { expect(r).to.equal("CORE-123"); }); + it("works with multiline commit bodies", () => { + const r = parseIssueNumberFrom( + `This is a multiline commit body + +CORE-1011`, + "CORE-456", + "CORE-789" + ); + expect(r).to.equal("CORE-1011"); + }); + it("should return undefined if no JIRA issue number is found", () => { const result = parseIssueNumberFrom("No issue number"); expect(result).to.be.undefined; diff --git a/.github/scripts/jira/lib.ts b/.github/scripts/jira/lib.ts new file mode 100644 index 0000000000..72f1d57966 --- /dev/null +++ b/.github/scripts/jira/lib.ts @@ -0,0 +1,63 @@ + +import * as core from '@actions/core' +import * as jira from 'jira.js' + +/** + * Given a list of strings, this function will return the first JIRA issue number it finds. + * + * @example parseIssueNumberFrom("CORE-123", "CORE-456", "CORE-789") => "CORE-123" + * @example parseIssueNumberFrom("2f3df5gf", "chore/test-RE-78-branch", "RE-78 Create new test branches") => "RE-78" + */ +export function parseIssueNumberFrom( + ...inputs: (string | undefined)[] +): string | undefined { + function parse(str?: string) { + const jiraIssueRegex = /[A-Z]{2,}-\d+/; + + return str?.toUpperCase().match(jiraIssueRegex)?.[0]; + } + + core.debug(`Parsing issue number from: ${inputs.join(", ")}`); + const parsed: string[] = inputs.map(parse).filter((x) => x !== undefined); + core.debug(`Found issue number: ${parsed[0]}`); + + return parsed[0]; +} + +/** + * Converts an array of tags to an array of labels. + * + * A label is a string that is formatted as `core-release/{tag}`, with the leading `v` removed from the tag. + * + * @example tagsToLabels(["v1.0.0", "v1.1.0"]) => [{ add: "core-release/1.0.0" }, { add: "core-release/1.1.0" }] + */ +export function tagsToLabels(tags: string[]) { + const labelPrefix = "core-release"; + + return tags.map((t) => ({ + add: `${labelPrefix}/${t.substring(1)}`, + })); +} + +export function createJiraClient() { + const jiraHost = process.env.JIRA_HOST; + const jiraUserName = process.env.JIRA_USERNAME; + const jiraApiToken = process.env.JIRA_API_TOKEN; + + if (!jiraHost || !jiraUserName || !jiraApiToken) { + core.setFailed( + "Error: Missing required environment variables: JIRA_HOST and JIRA_USERNAME and JIRA_API_TOKEN." + ); + process.exit(1); + } + + return new jira.Version3Client({ + host: jiraHost, + authentication: { + basic: { + email: jiraUserName, + apiToken: jiraApiToken, + }, + }, + }); +} diff --git a/.github/scripts/jira/package.json b/.github/scripts/jira/package.json index 9902b489ea..95bfbb1e48 100644 --- a/.github/scripts/jira/package.json +++ b/.github/scripts/jira/package.json @@ -13,7 +13,9 @@ "pnpm": ">=9" }, "scripts": { - "start": "tsx update-jira-issue.ts" + "issue:update": "tsx update-jira-issue.ts", + "issue:enforce": "tsx enforce-jira-issue.ts", + "test": "vitest" }, "dependencies": { "@actions/core": "^1.10.1", diff --git a/.github/scripts/jira/update-jira-issue.ts b/.github/scripts/jira/update-jira-issue.ts index 2659f4e517..6e539c7ffa 100644 --- a/.github/scripts/jira/update-jira-issue.ts +++ b/.github/scripts/jira/update-jira-issue.ts @@ -1,40 +1,6 @@ import * as core from "@actions/core"; import jira from "jira.js"; - -/** - * Given a list of strings, this function will return the first JIRA issue number it finds. - * - * @example parseIssueNumberFrom("CORE-123", "CORE-456", "CORE-789") => "CORE-123" - * @example parseIssueNumberFrom("2f3df5gf", "chore/test-RE-78-branch", "RE-78 Create new test branches") => "RE-78" - */ -export function parseIssueNumberFrom( - ...inputs: (string | undefined)[] -): string | undefined { - function parse(str?: string) { - const jiraIssueRegex = /[A-Z]{2,}-\d+/; - - return str?.toUpperCase().match(jiraIssueRegex)?.[0]; - } - - const parsed: string[] = inputs.map(parse).filter((x) => x !== undefined); - - return parsed[0]; -} - -/** - * Converts an array of tags to an array of labels. - * - * A label is a string that is formatted as `core-release/{tag}`, with the leading `v` removed from the tag. - * - * @example tagsToLabels(["v1.0.0", "v1.1.0"]) => [{ add: "core-release/1.0.0" }, { add: "core-release/1.1.0" }] - */ -export function tagsToLabels(tags: string[]) { - const labelPrefix = "core-release"; - - return tags.map((t) => ({ - add: `${labelPrefix}/${t.substring(1)}`, - })); -} +import { tagsToLabels, createJiraClient, parseIssueNumberFrom } from "./lib"; function updateJiraIssue( client: jira.Version3Client, @@ -64,29 +30,6 @@ function updateJiraIssue( return client.issues.editIssue(payload); } -function createJiraClient() { - const jiraHost = process.env.JIRA_HOST; - const jiraUserName = process.env.JIRA_USERNAME; - const jiraApiToken = process.env.JIRA_API_TOKEN; - - if (!jiraHost || !jiraUserName || !jiraApiToken) { - core.setFailed( - "Error: Missing required environment variables: JIRA_HOST and JIRA_USERNAME and JIRA_API_TOKEN." - ); - process.exit(1); - } - - return new jira.Version3Client({ - host: jiraHost, - authentication: { - basic: { - email: jiraUserName, - apiToken: jiraApiToken, - }, - }, - }); -} - async function main() { const prTitle = process.env.PR_TITLE; const commitMessage = process.env.COMMIT_MESSAGE; diff --git a/.github/workflows/changeset.yml b/.github/workflows/changeset.yml index 01df70a20d..5e16b90c40 100644 --- a/.github/workflows/changeset.yml +++ b/.github/workflows/changeset.yml @@ -94,7 +94,7 @@ jobs: working-directory: ./.github/scripts/jira run: | echo "COMMIT_MESSAGE=$(git log -1 --pretty=format:'%s')" >> $GITHUB_ENV - pnpm install && pnpm start + pnpm install && pnpm issue:update env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} JIRA_HOST: ${{ secrets.JIRA_HOST }} diff --git a/.github/workflows/solidity-jira.yml b/.github/workflows/solidity-jira.yml new file mode 100644 index 0000000000..1054bfa987 --- /dev/null +++ b/.github/workflows/solidity-jira.yml @@ -0,0 +1,100 @@ +# This is its own independent workflow since "solidity.yml" depends on "merge_group" and "push" events. +# But for ensuring that JIRA tickets are always updated, we only care about "pull_request" events. +# +# We still need to add "merge_group" event and noop so that we'll pass required workflow checks. +# +# I didn't add this to the "changeset.yml" workflow because the "changeset" job isnt required, and we'd need to add the "merge_group" event to the "changeset.yml" workflow. +# If we made the change to make it required. +name: Solidity Jira + +on: + merge_group: + pull_request: + +defaults: + run: + shell: bash + +jobs: + skip-enforce-jira-issue: + name: Should Skip + # We want to skip merge_group events, and any release branches + # Since we only want to enforce Jira issues on pull requests related to feature branches + if: ${{ github.event_name != 'merge_group' && !startsWith(github.head_ref, 'release/') }} + outputs: + should-enforce: ${{ steps.changed_files.outputs.only_src_contracts }} + runs-on: ubuntu-latest + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + # We don't use detect-solidity-file-changes here because we need to use the "every" predicate quantifier + - name: Filter paths + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: changed_files + with: + list-files: "csv" + # This is a valid input, see https://github.com/dorny/paths-filter/pull/226 + predicate-quantifier: "every" + filters: | + only_src_contracts: + - contracts/**/*.sol + - '!contracts/**/*.t.sol' + + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 + with: + id: solidity-jira + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Should Skip + continue-on-error: true + + enforce-jira-issue: + name: Enforce Jira Issue + runs-on: ubuntu-latest + # If a needs job is skipped, this job will be skipped and counted as successful + # The job skips on merge_group events, and any release branches + # Since we only want to enforce Jira issues on pull requests related to feature branches + needs: [skip-enforce-jira-issue] + # In addition to the above conditions, we only want to running on solidity related PRs. + # + # Note: A job that is skipped will report its status as "Success". + # It will not prevent a pull request from merging, even if it is a required check. + if: ${{ needs.skip-enforce-jira-issue.outputs.should-enforce == 'true' }} + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Setup NodeJS + uses: ./.github/actions/setup-nodejs + + - name: Setup Jira + working-directory: ./.github/scripts/jira + run: pnpm i + + - name: Enforce Jira Issue + working-directory: ./.github/scripts/jira + run: | + echo "COMMIT_MESSAGE=$(git log -1 --pretty=format:'%s')" >> $GITHUB_ENV + pnpm issue:enforce + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + JIRA_HOST: ${{ secrets.JIRA_HOST }} + JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} + JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} + PR_TITLE: ${{ github.event.pull_request.title }} + BRANCH_NAME: ${{ github.event.pull_request.head.ref }} + + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 + with: + id: solidity-jira + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Enforce Jira Issue + continue-on-error: true From 3015b53082fb62878408cf3a2c72d38225abd718 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 8 Aug 2024 14:42:55 -0700 Subject: [PATCH 067/432] fix: check dir before using find (#14087) --- .github/workflows/ci-core.yml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index fc7e6e372d..bb12304ef9 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -344,12 +344,23 @@ jobs: - name: Check and Set SonarQube Report Paths shell: bash run: | - sonarqube_tests_report_paths=$(find go_core_tests_logs -name output.txt | paste -sd "," -) - sonarqube_coverage_report_paths=$(find go_core_tests_logs -name coverage.txt | paste -sd "," -) - sonarqube_lint_report_paths=$(find golangci-lint-report -name golangci-lint-report.xml | paste -sd "," -) + # Check and assign paths for coverage/test reports + if [ -d "go_core_tests_logs" ]; then + sonarqube_coverage_report_paths=$(find go_core_tests_logs -name coverage.txt | paste -sd "," -) + sonarqube_tests_report_paths=$(find go_core_tests_logs -name output.txt | paste -sd "," -) + else + sonarqube_coverage_report_paths="" + sonarqube_tests_report_paths="" + fi - ARGS="" + # Check and assign paths for lint reports + if [ -d "golangci-lint-report" ]; then + sonarqube_lint_report_paths=$(find golangci-lint-report -name golangci-lint-report.xml | paste -sd "," -) + else + sonarqube_lint_report_paths="" + fi + ARGS="" if [[ -z "$sonarqube_tests_report_paths" ]]; then echo "::warning::No test report paths found, will not pass to sonarqube" else From 98b90543972d37e4c00196f3f00bcf5f380ea04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Fri, 9 Aug 2024 12:17:12 +0300 Subject: [PATCH 068/432] Write Chain Target: Validate that signed report metadata matches request metadata (#14066) * Hardcoded value for call with exact gas * Record gasProvided in route function * Add a getter for transmission gas limit * Update snapshot * Changeset * Remove unused import * Rename to gas limit * Update gethwrappers * Uncomment test code * Remove copy/pasta comment * Slight rename * Allow retrying transmissions with more gas * Only allow retrying failed transmissions * Update snapshot * Fix state for InvalidReceiver check * Check for initial state * Actually store gas limit provided to receiver * Update gethwrappers * Remove unused struct * Correctly mark invalid receiver when receiver interface unsupported * Create TransmissionInfo struct * Update gethwrappers * Bump gas limit * Bump gas even more * Update KeystoneFeedsConsumer.sol to implement IERC165 * Use getTransmissionInfo * Use TransmissionState to determine if transmission should be created * Fix test * Fix trailing line * Update a mock to the GetLatestValue("getTransmissionInfo") call in a test * Remove TODO + replace panic with err * Remove redundant empty lines * Typo * Fix nil pointer dereference in write target implementation * Remove unused constant * Name mapping values * Add changeset * Validate that report metadata matches request metadata * Derive report metadata length from the struct * Bytes() => Encode() * Simplify decoding * Undo redundant change * More simplifications * More cleanup * Remove redundant comment * Changeset * Update tests --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .changeset/tall-poems-swim.md | 5 + core/capabilities/targets/write_target.go | 145 +++++++++++++----- .../capabilities/targets/write_target_test.go | 88 +++++------ core/services/relay/evm/write_target_test.go | 137 ++++++----------- 4 files changed, 198 insertions(+), 177 deletions(-) create mode 100644 .changeset/tall-poems-swim.md diff --git a/.changeset/tall-poems-swim.md b/.changeset/tall-poems-swim.md new file mode 100644 index 0000000000..0408383bd0 --- /dev/null +++ b/.changeset/tall-poems-swim.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index 4524c4fd44..282a4741a6 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -1,7 +1,9 @@ package targets import ( + "bytes" "context" + "encoding/binary" "encoding/hex" "fmt" "math/big" @@ -13,7 +15,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3/types" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" - "github.com/smartcontractkit/chainlink-common/pkg/values" "github.com/smartcontractkit/chainlink/v2/core/logger" ) @@ -21,9 +22,6 @@ var ( _ capabilities.ActionCapability = &WriteTarget{} ) -// required field of target's config in the workflow spec -const signedReportField = "signed_report" - type WriteTarget struct { cr commontypes.ContractReader cw commontypes.ChainWriter @@ -71,22 +69,105 @@ func NewWriteTarget(lggr logger.Logger, id string, cr commontypes.ContractReader } } -type EvmConfig struct { +// Note: This should be a shared type that the OCR3 package validates as well +type ReportV1Metadata struct { + Version uint8 + WorkflowExecutionID [32]byte + Timestamp uint32 + DonID uint32 + DonConfigVersion uint32 + WorkflowCID [32]byte + WorkflowName [10]byte + WorkflowOwner [20]byte + ReportID [2]byte +} + +func (rm ReportV1Metadata) Encode() ([]byte, error) { + buf := new(bytes.Buffer) + err := binary.Write(buf, binary.BigEndian, rm) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func (rm ReportV1Metadata) Length() int { + bytes, err := rm.Encode() + if err != nil { + return 0 + } + return len(bytes) +} + +func decodeReportMetadata(data []byte) (metadata ReportV1Metadata, err error) { + if len(data) < metadata.Length() { + return metadata, fmt.Errorf("data too short: %d bytes", len(data)) + } + return metadata, binary.Read(bytes.NewReader(data[:metadata.Length()]), binary.BigEndian, &metadata) +} + +type Config struct { + // Address of the contract that will get the forwarded report Address string } -func parseConfig(rawConfig *values.Map) (config EvmConfig, err error) { - if rawConfig == nil { - return config, fmt.Errorf("missing config field") +type Inputs struct { + SignedReport types.SignedReport +} + +type Request struct { + Metadata capabilities.RequestMetadata + Config Config + Inputs Inputs +} + +func evaluate(rawRequest capabilities.CapabilityRequest) (r Request, err error) { + r.Metadata = rawRequest.Metadata + + if rawRequest.Config == nil { + return r, fmt.Errorf("missing config field") + } + + if err = rawRequest.Config.UnwrapTo(&r.Config); err != nil { + return r, err + } + + if !common.IsHexAddress(r.Config.Address) { + return r, fmt.Errorf("'%v' is not a valid address", r.Config.Address) } - if err := rawConfig.UnwrapTo(&config); err != nil { - return config, err + if rawRequest.Inputs == nil { + return r, fmt.Errorf("missing inputs field") } - if !common.IsHexAddress(config.Address) { - return config, fmt.Errorf("'%v' is not a valid address", config.Address) + + // required field of target's config in the workflow spec + const signedReportField = "signed_report" + signedReport, ok := rawRequest.Inputs.Underlying[signedReportField] + if !ok { + return r, fmt.Errorf("missing required field %s", signedReportField) + } + + if err = signedReport.UnwrapTo(&r.Inputs.SignedReport); err != nil { + return r, err + } + + reportMetadata, err := decodeReportMetadata(r.Inputs.SignedReport.Report) + if err != nil { + return r, err + } + + if reportMetadata.Version != 1 { + return r, fmt.Errorf("unsupported report version: %d", reportMetadata.Version) } - return config, nil + + if hex.EncodeToString(reportMetadata.WorkflowExecutionID[:]) != rawRequest.Metadata.WorkflowExecutionID || + hex.EncodeToString(reportMetadata.WorkflowOwner[:]) != rawRequest.Metadata.WorkflowOwner || + hex.EncodeToString(reportMetadata.WorkflowName[:]) != rawRequest.Metadata.WorkflowName || + hex.EncodeToString(reportMetadata.WorkflowCID[:]) != rawRequest.Metadata.WorkflowID { + return r, fmt.Errorf("report metadata does not match request metadata. reportMetadata: %+v, requestMetadata: %+v", reportMetadata, rawRequest.Metadata) + } + + return r, nil } func success() <-chan capabilities.CapabilityResponse { @@ -98,7 +179,7 @@ func success() <-chan capabilities.CapabilityResponse { return callback } -func (cap *WriteTarget) Execute(ctx context.Context, request capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) { +func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) { // Bind to the contract address on the write path. // Bind() requires a connection to the node's RPCs and // cannot be run during initialization. @@ -114,47 +195,27 @@ func (cap *WriteTarget) Execute(ctx context.Context, request capabilities.Capabi cap.bound = true } - cap.lggr.Debugw("Execute", "request", request) + cap.lggr.Debugw("Execute", "rawRequest", rawRequest) - reqConfig, err := parseConfig(request.Config) + request, err := evaluate(rawRequest) if err != nil { return nil, err } - if request.Inputs == nil { - return nil, fmt.Errorf("missing inputs field") - } - - signedReport, ok := request.Inputs.Underlying[signedReportField] - if !ok { - return nil, fmt.Errorf("missing required field %s", signedReportField) - } - - inputs := types.SignedReport{} - if err = signedReport.UnwrapTo(&inputs); err != nil { - return nil, err - } - - if len(inputs.Report) == 0 { - // We received any empty report -- this means we should skip transmission. - cap.lggr.Debugw("Skipping empty report", "request", request) - return success(), nil - } - // TODO: validate encoded report is prefixed with workflowID and executionID that match the request meta - rawExecutionID, err := hex.DecodeString(request.Metadata.WorkflowExecutionID) if err != nil { return nil, err } + // Check whether value was already transmitted on chain queryInputs := struct { Receiver string WorkflowExecutionID []byte ReportId []byte }{ - Receiver: reqConfig.Address, + Receiver: request.Config.Address, WorkflowExecutionID: rawExecutionID, - ReportId: inputs.ID, + ReportId: request.Inputs.SignedReport.ID, } var transmissionInfo TransmissionInfo if err = cap.cr.GetLatestValue(ctx, "forwarder", "getTransmissionInfo", primitives.Unconfirmed, queryInputs, &transmissionInfo); err != nil { @@ -163,7 +224,7 @@ func (cap *WriteTarget) Execute(ctx context.Context, request capabilities.Capabi switch { case transmissionInfo.State == 0: // NOT_ATTEMPTED - cap.lggr.Infow("non-empty report - tranasmission not attempted - attempting to push to txmgr", "request", request, "reportLen", len(inputs.Report), "reportContextLen", len(inputs.Context), "nSignatures", len(inputs.Signatures), "executionID", request.Metadata.WorkflowExecutionID) + cap.lggr.Infow("non-empty report - tranasmission not attempted - attempting to push to txmgr", "request", request, "reportLen", len(request.Inputs.SignedReport.Report), "reportContextLen", len(request.Inputs.SignedReport.Context), "nSignatures", len(request.Inputs.SignedReport.Signatures), "executionID", request.Metadata.WorkflowExecutionID) case transmissionInfo.State == 1: // SUCCEEDED cap.lggr.Infow("returning without a tranmission attempt - report already onchain ", "executionID", request.Metadata.WorkflowExecutionID) return success(), nil @@ -175,7 +236,7 @@ func (cap *WriteTarget) Execute(ctx context.Context, request capabilities.Capabi cap.lggr.Infow("returning without a tranmission attempt - transmission already attempted and failed, sufficient gas was provided", "executionID", request.Metadata.WorkflowExecutionID, "receiverGasMinimum", cap.receiverGasMinimum, "transmissionGasLimit", transmissionInfo.GasLimit) return success(), nil } else { - cap.lggr.Infow("non-empty report - retrying a failed transmission - attempting to push to txmgr", "request", request, "reportLen", len(inputs.Report), "reportContextLen", len(inputs.Context), "nSignatures", len(inputs.Signatures), "executionID", request.Metadata.WorkflowExecutionID, "receiverGasMinimum", cap.receiverGasMinimum, "transmissionGasLimit", transmissionInfo.GasLimit) + cap.lggr.Infow("non-empty report - retrying a failed transmission - attempting to push to txmgr", "request", request, "reportLen", len(request.Inputs.SignedReport.Report), "reportContextLen", len(request.Inputs.SignedReport.Context), "nSignatures", len(request.Inputs.SignedReport.Signatures), "executionID", request.Metadata.WorkflowExecutionID, "receiverGasMinimum", cap.receiverGasMinimum, "transmissionGasLimit", transmissionInfo.GasLimit) } default: return nil, fmt.Errorf("unexpected transmission state: %v", transmissionInfo.State) @@ -194,7 +255,7 @@ func (cap *WriteTarget) Execute(ctx context.Context, request capabilities.Capabi RawReport []byte ReportContext []byte Signatures [][]byte - }{reqConfig.Address, inputs.Report, inputs.Context, inputs.Signatures} + }{request.Config.Address, request.Inputs.SignedReport.Report, request.Inputs.SignedReport.Context, request.Inputs.SignedReport.Signatures} if req.RawReport == nil { req.RawReport = make([]byte, 0) diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go index 0fa750911d..522fee3251 100644 --- a/core/capabilities/targets/write_target_test.go +++ b/core/capabilities/targets/write_target_test.go @@ -2,6 +2,7 @@ package targets_test import ( "context" + "encoding/hex" "errors" "math/big" "testing" @@ -38,14 +39,36 @@ func TestWriteTarget(t *testing.T) { }) require.NoError(t, err) + reportMetadata := targets.ReportV1Metadata{ + Version: 1, + WorkflowExecutionID: [32]byte{}, + Timestamp: 0, + DonID: 0, + DonConfigVersion: 0, + WorkflowCID: [32]byte{}, + WorkflowName: [10]byte{}, + WorkflowOwner: [20]byte{}, + ReportID: [2]byte{}, + } + + reportMetadataBytes, err := reportMetadata.Encode() + require.NoError(t, err) + validInputs, err := values.NewMap(map[string]any{ "signed_report": map[string]any{ - "report": []byte{1, 2, 3}, + "report": reportMetadataBytes, "signatures": [][]byte{}, }, }) require.NoError(t, err) + validMetadata := capabilities.RequestMetadata{ + WorkflowID: hex.EncodeToString(reportMetadata.WorkflowCID[:]), + WorkflowOwner: hex.EncodeToString(reportMetadata.WorkflowOwner[:]), + WorkflowName: hex.EncodeToString(reportMetadata.WorkflowName[:]), + WorkflowExecutionID: hex.EncodeToString(reportMetadata.WorkflowExecutionID[:]), + } + cr.On("Bind", mock.Anything, []types.BoundContract{ { Address: forwarderAddr, @@ -69,11 +92,9 @@ func TestWriteTarget(t *testing.T) { t.Run("succeeds with valid report", func(t *testing.T) { req := capabilities.CapabilityRequest{ - Metadata: capabilities.RequestMetadata{ - WorkflowID: "test-id", - }, - Config: config, - Inputs: validInputs, + Metadata: validMetadata, + Config: config, + Inputs: validInputs, } ch, err2 := writeTarget.Execute(ctx, req) @@ -82,36 +103,11 @@ func TestWriteTarget(t *testing.T) { require.NotNil(t, response) }) - t.Run("succeeds with empty report", func(t *testing.T) { - emptyInputs, err2 := values.NewMap(map[string]any{ - "signed_report": map[string]any{ - "report": []byte{}, - }, - "signatures": [][]byte{}, - }) - - require.NoError(t, err2) - req := capabilities.CapabilityRequest{ - Metadata: capabilities.RequestMetadata{ - WorkflowExecutionID: "test-id", - }, - Config: config, - Inputs: emptyInputs, - } - - ch, err2 := writeTarget.Execute(ctx, req) - require.NoError(t, err2) - response := <-ch - require.Nil(t, response.Value) - }) - t.Run("fails when ChainReader's GetLatestValue returns error", func(t *testing.T) { req := capabilities.CapabilityRequest{ - Metadata: capabilities.RequestMetadata{ - WorkflowID: "test-id", - }, - Config: config, - Inputs: validInputs, + Metadata: validMetadata, + Config: config, + Inputs: validInputs, } cr.On("GetLatestValue", mock.Anything, "forwarder", "getTransmissionInfo", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("reader error")) @@ -121,11 +117,9 @@ func TestWriteTarget(t *testing.T) { t.Run("fails when ChainWriter's SubmitTransaction returns error", func(t *testing.T) { req := capabilities.CapabilityRequest{ - Metadata: capabilities.RequestMetadata{ - WorkflowID: "test-id", - }, - Config: config, - Inputs: validInputs, + Metadata: validMetadata, + Config: config, + Inputs: validInputs, } cw.On("SubmitTransaction", mock.Anything, "forwarder", "report", mock.Anything, mock.Anything, forwarderAddr, mock.Anything, mock.Anything).Return(errors.New("writer error")) @@ -152,11 +146,9 @@ func TestWriteTarget(t *testing.T) { t.Run("fails with nil config", func(t *testing.T) { req := capabilities.CapabilityRequest{ - Metadata: capabilities.RequestMetadata{ - WorkflowID: "test-id", - }, - Config: nil, - Inputs: validInputs, + Metadata: validMetadata, + Config: nil, + Inputs: validInputs, } _, err2 := writeTarget.Execute(ctx, req) require.Error(t, err2) @@ -164,11 +156,9 @@ func TestWriteTarget(t *testing.T) { t.Run("fails with nil inputs", func(t *testing.T) { req := capabilities.CapabilityRequest{ - Metadata: capabilities.RequestMetadata{ - WorkflowID: "test-id", - }, - Config: config, - Inputs: nil, + Metadata: validMetadata, + Config: config, + Inputs: nil, } _, err2 := writeTarget.Execute(ctx, req) require.Error(t, err2) diff --git a/core/services/relay/evm/write_target_test.go b/core/services/relay/evm/write_target_test.go index 57a0f80f8d..54e3671422 100644 --- a/core/services/relay/evm/write_target_test.go +++ b/core/services/relay/evm/write_target_test.go @@ -2,6 +2,7 @@ package evm_test import ( "bytes" + "encoding/hex" "errors" "fmt" "math/big" @@ -146,14 +147,53 @@ func TestEvmWrite(t *testing.T) { }) require.NoError(t, err) + reportMetadata := targets.ReportV1Metadata{ + Version: 1, + WorkflowExecutionID: [32]byte{}, + Timestamp: 0, + DonID: 0, + DonConfigVersion: 0, + WorkflowCID: [32]byte{}, + WorkflowName: [10]byte{}, + WorkflowOwner: [20]byte{}, + ReportID: [2]byte{}, + } + + reportMetadataBytes, err := reportMetadata.Encode() + require.NoError(t, err) + + signatures := [][]byte{} + + validInputs, err := values.NewMap(map[string]any{ + "signed_report": map[string]any{ + "report": reportMetadataBytes, + "signatures": signatures, + "context": []byte{4, 5}, + "id": []byte{9, 9}, + }, + }) + require.NoError(t, err) + + validMetadata := capabilities.RequestMetadata{ + WorkflowID: hex.EncodeToString(reportMetadata.WorkflowCID[:]), + WorkflowOwner: hex.EncodeToString(reportMetadata.WorkflowOwner[:]), + WorkflowName: hex.EncodeToString(reportMetadata.WorkflowName[:]), + WorkflowExecutionID: hex.EncodeToString(reportMetadata.WorkflowExecutionID[:]), + } + + validConfig, err := values.NewMap(map[string]any{ + "Address": evmCfg.EVM().Workflow().ForwarderAddress().String(), + }) + require.NoError(t, err) + txManager.On("CreateTransaction", mock.Anything, mock.Anything).Return(txmgr.Tx{}, nil).Run(func(args mock.Arguments) { req := args.Get(1).(txmgr.TxRequest) payload := make(map[string]any) method := forwardABI.Methods["report"] err = method.Inputs.UnpackIntoMap(payload, req.EncodedPayload[4:]) require.NoError(t, err) - require.Equal(t, []byte{0x1, 0x2, 0x3}, payload["rawReport"]) - require.Equal(t, [][]byte{}, payload["signatures"]) + require.Equal(t, reportMetadataBytes, payload["rawReport"]) + require.Equal(t, signatures, payload["signatures"]) }).Once() t.Run("succeeds with valid report", func(t *testing.T) { @@ -161,59 +201,10 @@ func TestEvmWrite(t *testing.T) { capability, err := evm.NewWriteTarget(ctx, relayer, chain, lggr) require.NoError(t, err) - config, err := values.NewMap(map[string]any{ - "Address": evmCfg.EVM().Workflow().ForwarderAddress().String(), - }) - require.NoError(t, err) - - inputs, err := values.NewMap(map[string]any{ - "signed_report": map[string]any{ - "report": []byte{1, 2, 3}, - "signatures": [][]byte{}, - "context": []byte{4, 5}, - "id": []byte{9, 9}, - }, - }) - require.NoError(t, err) - - req := capabilities.CapabilityRequest{ - Metadata: capabilities.RequestMetadata{ - WorkflowID: "test-id", - }, - Config: config, - Inputs: inputs, - } - - ch, err := capability.Execute(ctx, req) - require.NoError(t, err) - - response := <-ch - require.Nil(t, response.Err) - }) - - t.Run("succeeds with empty report", func(t *testing.T) { - ctx := testutils.Context(t) - capability, err := evm.NewWriteTarget(ctx, relayer, chain, logger.TestLogger(t)) - require.NoError(t, err) - - config, err := values.NewMap(map[string]any{ - "Address": evmCfg.EVM().Workflow().ForwarderAddress().String(), - }) - require.NoError(t, err) - - inputs, err := values.NewMap(map[string]any{ - "signed_report": map[string]any{ - "report": nil, - }, - }) - require.NoError(t, err) - req := capabilities.CapabilityRequest{ - Metadata: capabilities.RequestMetadata{ - WorkflowID: "test-id", - }, - Config: config, - Inputs: inputs, + Metadata: validMetadata, + Config: validConfig, + Inputs: validInputs, } ch, err := capability.Execute(ctx, req) @@ -233,19 +224,10 @@ func TestEvmWrite(t *testing.T) { }) require.NoError(t, err) - inputs, err := values.NewMap(map[string]any{ - "signed_report": map[string]any{ - "report": nil, - }, - }) - require.NoError(t, err) - req := capabilities.CapabilityRequest{ - Metadata: capabilities.RequestMetadata{ - WorkflowID: "test-id", - }, - Config: invalidConfig, - Inputs: inputs, + Metadata: validMetadata, + Config: invalidConfig, + Inputs: validInputs, } _, err = capability.Execute(ctx, req) @@ -257,27 +239,10 @@ func TestEvmWrite(t *testing.T) { capability, err := evm.NewWriteTarget(ctx, relayer, chain, logger.TestLogger(t)) require.NoError(t, err) - config, err := values.NewMap(map[string]any{ - "Address": evmCfg.EVM().Workflow().ForwarderAddress().String(), - }) - require.NoError(t, err) - - inputs, err := values.NewMap(map[string]any{ - "signed_report": map[string]any{ - "report": []byte{1, 2, 3}, - "signatures": [][]byte{}, - "context": []byte{4, 5}, - "id": []byte{9, 9}, - }, - }) - require.NoError(t, err) - req := capabilities.CapabilityRequest{ - Metadata: capabilities.RequestMetadata{ - WorkflowID: "test-id", - }, - Config: config, - Inputs: inputs, + Metadata: validMetadata, + Config: validConfig, + Inputs: validInputs, } txManager.On("CreateTransaction", mock.Anything, mock.Anything).Return(txmgr.Tx{}, errors.New("TXM error")) From 4b9169131cd44d6cb4f00dae2b33e49626af5f7d Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Fri, 9 Aug 2024 12:48:22 +0200 Subject: [PATCH 069/432] [TT-1326] Update Solidty Foundry pipeline with Slither (#13986) * More univeral lcov prunning * update Shared code cov * exclude deleted files from Slither * use single source of truth for all Solidity Foundry jobs * fix json * compact output with jq * fix condition for fmt * try to scope tests to changes * move matrix check to step level * fix outputs path * trigger * test with Automation change * try with shared * run fmt also if any sol files were modified * fix job name in collect metrics * trigger pipeline only for localised change + update changes info * add changeset * remove test change * do not run forge fmt if shared contracts have changed * try artifact pipeline by hijacking hardhat * # This is a combination of 2 commits. # This is the 1st commit message: CR changes + test them # This is the commit message #2: use shell array * CR changes + test them use shell array init array CR changes + test them use shell array init array * remove test files * do not run Slither for test files * do not run fmt if test files were modified * remove unused config file * restore old Hardhat pipeline * add missing transmission setup * fix basic info condition, join 2 steps into 1, define higher-level coverage exclusions * define actions for installing Slither and solc-select * run all tests also if package.json changes; run them on all non_src changes * add action for validating whether all Slither reports and UML diagrams were generated * fetch origin in validation action * compare with HEAD in validate action * compare with origin in validation action * handle both csv and shell arrays in the validation action * update artifact pipeline with new actions * fix workflow after tests * fix how validation actions works with commits * treat shared as any other product * small fixes * apply CR changes * remove special handling for deleted files * remove apt-get update * use only dorny/paths * remove unused input * CR changes: use dorny/paths with quantifier, move scope validation to an action, remove whitespaces * fix workflow * fail bash scripts on erors * add set -euo pipefail to bash scripts * define action to detect foundry version * fix select solc version script, better slither report output * checkout repo * add id --- .../action.yml | 26 ++ .github/actions/setup-slither/action.yaml | 10 + .github/actions/setup-solc-select/action.yaml | 30 ++ .../validate-artifact-scope/action.yaml | 103 +++++ .../validate-solidity-artifacts/action.yaml | 115 ++++++ .../workflows/solidity-foundry-artifacts.yml | 371 ++++++++++++++++++ .github/workflows/solidity-foundry.yml | 304 +++++++++++--- .github/workflows/solidity-hardhat.yml | 2 +- contracts/.changeset/itchy-deers-deny.md | 5 + .../slither/.slither.config-artifacts.json | 3 + .../slither/.slither.config-ccip-pr.json | 4 + .../slither/.slither.config-default-pr.json | 4 + contracts/scripts/ccip_lcov_prune | 29 -- .../scripts/ci/generate_slither_report.sh | 87 ++++ contracts/scripts/ci/generate_uml.sh | 121 ++++++ contracts/scripts/ci/modify_remappings.sh | 30 ++ contracts/scripts/ci/select_solc_version.sh | 118 ++++++ contracts/scripts/lcov_prune | 77 ++++ 18 files changed, 1354 insertions(+), 85 deletions(-) create mode 100644 .github/actions/detect-solidity-foundry-version/action.yml create mode 100644 .github/actions/setup-slither/action.yaml create mode 100644 .github/actions/setup-solc-select/action.yaml create mode 100644 .github/actions/validate-artifact-scope/action.yaml create mode 100644 .github/actions/validate-solidity-artifacts/action.yaml create mode 100644 .github/workflows/solidity-foundry-artifacts.yml create mode 100644 contracts/.changeset/itchy-deers-deny.md create mode 100644 contracts/configs/slither/.slither.config-artifacts.json create mode 100644 contracts/configs/slither/.slither.config-ccip-pr.json create mode 100644 contracts/configs/slither/.slither.config-default-pr.json delete mode 100755 contracts/scripts/ccip_lcov_prune create mode 100755 contracts/scripts/ci/generate_slither_report.sh create mode 100755 contracts/scripts/ci/generate_uml.sh create mode 100755 contracts/scripts/ci/modify_remappings.sh create mode 100755 contracts/scripts/ci/select_solc_version.sh create mode 100755 contracts/scripts/lcov_prune diff --git a/.github/actions/detect-solidity-foundry-version/action.yml b/.github/actions/detect-solidity-foundry-version/action.yml new file mode 100644 index 0000000000..b37f1e2509 --- /dev/null +++ b/.github/actions/detect-solidity-foundry-version/action.yml @@ -0,0 +1,26 @@ +name: 'Detect Foundry version in GNUmakefile' +description: 'Detects Foundry version in GNUmakefile' +inputs: + working-directory: + description: 'The GNUmakefile directory' + required: false + default: 'contracts' +outputs: + foundry-version: + description: 'Foundry version found in GNUmakefile' + value: ${{ steps.extract-foundry-version.outputs.foundry-version }} +runs: + using: 'composite' + steps: + - name: Extract Foundry version + id: extract-foundry-version + shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + foundry_version=$(grep -Eo "foundryup --version [^ ]+" GNUmakefile | awk '{print $3}') + if [ -z "$foundry_version" ]; then + echo "::error::Foundry version not found in GNUmakefile" + exit 1 + fi + echo "Foundry version found: $foundry_version" + echo "foundry-version=$foundry_version" >> $GITHUB_OUTPUT diff --git a/.github/actions/setup-slither/action.yaml b/.github/actions/setup-slither/action.yaml new file mode 100644 index 0000000000..b8bef38575 --- /dev/null +++ b/.github/actions/setup-slither/action.yaml @@ -0,0 +1,10 @@ +name: Setup Slither +description: Installs Slither 0.10.3 for contract analysis. Requires Python 3.6 or higher. +runs: + using: composite + steps: + - name: Install Slither + shell: bash + run: | + python -m pip install --upgrade pip + pip install slither-analyzer==0.10.3 diff --git a/.github/actions/setup-solc-select/action.yaml b/.github/actions/setup-solc-select/action.yaml new file mode 100644 index 0000000000..b74ffae018 --- /dev/null +++ b/.github/actions/setup-solc-select/action.yaml @@ -0,0 +1,30 @@ +name: Setup Solc Select +description: Installs Solc Select, required versions and selects the version to use. Requires Python 3.6 or higher. +inputs: + to_install: + description: Comma-separated list of solc versions to install + required: true + to_use: + description: Solc version to use + required: true + +runs: + using: composite + steps: + - name: Install solc-select and solc + shell: bash + run: | + pip3 install solc-select + sudo ln -s /usr/local/bin/solc-select /usr/bin/solc-select + + IFS=',' read -ra versions <<< "${{ inputs.to_install }}" + for version in "${versions[@]}"; do + solc-select install $version + if [ $? -ne 0 ]; then + echo "Failed to install Solc $version" + exit 1 + fi + done + + solc-select install ${{ inputs.to_use }} + solc-select use ${{ inputs.to_use }} diff --git a/.github/actions/validate-artifact-scope/action.yaml b/.github/actions/validate-artifact-scope/action.yaml new file mode 100644 index 0000000000..7440efc63a --- /dev/null +++ b/.github/actions/validate-artifact-scope/action.yaml @@ -0,0 +1,103 @@ +name: Validate Artifact Scope +description: Checks there are any modified Solidity files outside of the specified scope. If so, it prints a warning message, but does not fail the workflow. +inputs: + product: + description: The product for which the artifacts are being generated + required: true + sol_files: + description: Comma-separated (CSV) or space-separated (shell) list of Solidity files to check + required: true + +runs: + using: composite + steps: + - name: Transform input array + id: transform_input_array + shell: bash + run: | + is_csv_format() { + local input="$1" + if [[ "$input" =~ "," ]]; then + return 0 + else + return 1 + fi + } + + is_space_separated_string() { + local input="$1" + if [[ "$input" =~ ^[^[:space:]]+([[:space:]][^[:space:]]+)*$ ]]; then + return 0 + else + return 1 + fi + } + + array="${{ inputs.sol_files }}" + + if is_csv_format "$array"; then + echo "::debug::CSV format detected, nothing to do" + echo "sol_files=$array" >> $GITHUB_OUTPUT + exit 0 + fi + + if is_space_separated_string "$array"; then + echo "::debug::Space-separated format detected, converting to CSV" + csv_array="${array// /,}" + echo "sol_files=$csv_array" >> $GITHUB_OUTPUT + exit 0 + fi + + echo "::error::Invalid input format for sol_files. Please provide a comma-separated (CSV) or space-separated (shell) list of Solidity files" + exit 1 + + - name: Check for changes outside of artifact scope + shell: bash + run: | + echo "::debug::All modified contracts:" + echo "${{ steps.transform_input_array.outputs.sol_files }}" | tr ',' '\n' + if [ "${{ inputs.product }}" = "shared" ]; then + excluded_paths_pattern="!/^contracts\/src\/v0\.8\/interfaces/ && !/^contracts\/src\/v0\.8\/${{ inputs.product }}/ && !/^contracts\/src\/v0\.8\/[^\/]+\.sol$/" + else + excluded_paths_pattern="!/^contracts\/src\/v0\.8\/${{ inputs.product }}/" + fi + echo "::debug::Excluded paths: $excluded_paths_pattern" + unexpected_files=$(echo "${{ steps.transform_input_array.outputs.sol_files }}" | tr ',' '\n' | awk "$excluded_paths_pattern") + missing_files="" + set -e + set -o pipefail + if [[ -n "$unexpected_files" ]]; then + products=() + productsStr="" + IFS=$'\n' read -r -d '' -a files <<< "$unexpected_files" || true + echo "Files: ${files[@]}" + + for file in "${files[@]}"; do + missing_files+="$file," + + product=$(echo "$file" | awk -F'src/v0.8/' '{if ($2 ~ /\//) print substr($2, 1, index($2, "/")-1); else print "shared"}') + if [[ ! " ${products[@]} " =~ " ${product} " ]]; then + products+=("$product") + productsStr+="$product, " + fi + done + productsStr=${productsStr%, } + + set +e + set +o pipefail + + missing_files=$(echo $missing_files | tr ',' '\n') + + echo "Error: Found modified contracts outside of the expected scope: ${{ inputs.product }}" + echo "Files:" + echo "$missing_files" + echo "Action required: If you want to generate artifacts for other products ($productsStr) run this workflow again with updated configuration" + + echo "# Warning!" >> $GITHUB_STEP_SUMMARY + echo "## Reason: Found modified contracts outside of the expected scope: ${{ inputs.product }}" >> $GITHUB_STEP_SUMMARY + echo "### Files:" >> $GITHUB_STEP_SUMMARY + echo "$missing_files" >> $GITHUB_STEP_SUMMARY + echo "## Action required: If you want to generate artifacts for other products ($productsStr) run this workflow again with updated configuration" >> $GITHUB_STEP_SUMMARY + else + echo "No unexpected files found." + fi diff --git a/.github/actions/validate-solidity-artifacts/action.yaml b/.github/actions/validate-solidity-artifacts/action.yaml new file mode 100644 index 0000000000..5357a87f96 --- /dev/null +++ b/.github/actions/validate-solidity-artifacts/action.yaml @@ -0,0 +1,115 @@ +name: Validate Solidity Artifacts +description: Checks whether Slither reports and UML diagrams were generated for all necessary files. If not, a warning is printed in job summary, but the job is not marked as failed. +inputs: + slither_reports_path: + description: Path to the Slither reports directory (without trailing slash) + required: true + uml_diagrams_path: + description: Path to the UML diagrams directory (without trailing slash) + required: true + validate_slither_reports: + description: Whether Slither reports should be validated + required: true + validate_uml_diagrams: + description: Whether UML diagrams should be validated + required: true + sol_files: + description: Comma-separated (CSV) or space-separated (shell) list of Solidity files to check + required: true + +runs: + using: composite + steps: + - name: Transform input array + id: transform_input_array + shell: bash + run: | + is_csv_format() { + local input="$1" + if [[ "$input" =~ "," ]]; then + return 0 + else + return 1 + fi + } + + is_space_separated_string() { + local input="$1" + if [[ "$input" =~ ^[^[:space:]]+([[:space:]][^[:space:]]+)*$ ]]; then + return 0 + else + return 1 + fi + } + + array="${{ inputs.sol_files }}" + + if is_csv_format "$array"; then + echo "::debug::CSV format detected, nothing to do" + echo "sol_files=$array" >> $GITHUB_OUTPUT + exit 0 + fi + + if is_space_separated_string "$array"; then + echo "::debug::Space-separated format detected, converting to CSV" + csv_array="${array// /,}" + echo "sol_files=$csv_array" >> $GITHUB_OUTPUT + exit 0 + fi + + echo "::error::Invalid input format for sol_files. Please provide a comma-separated (CSV) or space-separated (shell) list of Solidity files" + exit 1 + + - name: Validate UML diagrams + if: ${{ inputs.validate_uml_diagrams == 'true' }} + shell: bash + run: | + echo "Validating UML diagrams" + IFS=',' read -r -a modified_files <<< "${{ steps.transform_input_array.outputs.sol_files }}" + missing_svgs=() + for file in "${modified_files[@]}"; do + svg_file="$(basename "${file%.sol}").svg" + if [ ! -f "${{ inputs.uml_diagrams_path }}/$svg_file" ]; then + echo "Error: UML diagram for $file not found" + missing_svgs+=("$file") + fi + done + + if [ ${#missing_svgs[@]} -gt 0 ]; then + echo "Error: Missing UML diagrams for files: ${missing_svgs[@]}" + echo "# Warning!" >> $GITHUB_STEP_SUMMARY + echo "## Reason: Missing UML diagrams for files:" >> $GITHUB_STEP_SUMMARY + for file in "${missing_svgs[@]}"; do + echo " $file" >> $GITHUB_STEP_SUMMARY + done + echo "## Action required: Please try to generate artifacts for them locally or using a different tool" >> $GITHUB_STEP_SUMMARY + else + echo "All UML diagrams generated successfully" + fi + + - name: Validate Slither reports + if: ${{ inputs.validate_slither_reports == 'true' }} + shell: bash + run: | + echo "Validating Slither reports" + IFS=',' read -r -a modified_files <<< "${{ steps.transform_input_array.outputs.sol_files }}" + missing_reports=() + for file in "${modified_files[@]}"; do + report_file="$(basename "${file%.sol}")-slither-report.md" + if [ ! -f "${{ inputs.slither_reports_path }}/$report_file" ]; then + echo "Error: Slither report for $file not found" + missing_reports+=("$file") + fi + done + + if [ ${#missing_reports[@]} -gt 0 ]; then + echo "Error: Missing Slither reports for files: ${missing_reports[@]}" + echo "# Warning!" >> $GITHUB_STEP_SUMMARY + echo "## Reason: Missing Slither reports for files:" >> $GITHUB_STEP_SUMMARY + for file in "${missing_reports[@]}"; do + echo " $file" >> $GITHUB_STEP_SUMMARY + done + echo "## Action required: Please try to generate artifacts for them locally" >> $GITHUB_STEP_SUMMARY + else + echo "All Slither reports generated successfully" + fi diff --git a/.github/workflows/solidity-foundry-artifacts.yml b/.github/workflows/solidity-foundry-artifacts.yml new file mode 100644 index 0000000000..e489033d67 --- /dev/null +++ b/.github/workflows/solidity-foundry-artifacts.yml @@ -0,0 +1,371 @@ +name: Solidity Foundry Artifact Generation +on: + workflow_dispatch: + inputs: + product: + type: choice + description: 'product for which to generate artifacts; should be the same as Foundry profile' + required: true + options: + - "automation" + - "ccip" + - "functions" + - "keystone" + - "l2ep" + - "liquiditymanager" + - "llo-feeds" + - "operatorforwarder" + - "shared" + - "transmission" + - "vrf" + base_ref: + description: 'commit or tag to be used as base reference, when looking for modified Solidity files' + required: true + +env: + FOUNDRY_PROFILE: ci + +jobs: + changes: + name: Detect changes + runs-on: ubuntu-latest + outputs: + changes: ${{ steps.changes.outputs.sol }} + product_changes: ${{ steps.changes-transform.outputs.product_changes }} + product_files: ${{ steps.changes-transform.outputs.product_files }} + changeset_changes: ${{ steps.changes-dorny.outputs.changeset }} + changeset_files: ${{ steps.changes-dorny.outputs.changeset_files }} + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - name: Find modified contracts + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: changes + with: + list-files: 'csv' + base: ${{ inputs.base_ref }} + predicate-quantifier: every + filters: | + ignored: &ignored + - '!contracts/src/v0.8/**/test/**' + - '!contracts/src/v0.8/**/tests/**' + - '!contracts/src/v0.8/**/mock/**' + - '!contracts/src/v0.8/**/mocks/**' + - '!contracts/src/v0.8/**/*.t.sol' + - '!contracts/src/v0.8/*.t.sol' + - '!contracts/src/v0.8/**/testhelpers/**' + - '!contracts/src/v0.8/testhelpers/**' + - '!contracts/src/v0.8/vendor/**' + other_shared: + - modified|added: 'contracts/src/v0.8/(interfaces/**/*.sol|*.sol)' + - *ignored + sol: + - modified|added: 'contracts/src/v0.8/**/*.sol' + - *ignored + product: &product + - modified|added: 'contracts/src/v0.8/${{ inputs.product }}/**/*.sol' + - *ignored + changeset: + - modified|added: 'contracts/.changeset/!(README)*.md' + + # Manual transformation needed, because shared contracts have a different folder structure + - name: Transform modified files + id: changes-transform + shell: bash + run: | + if [ "${{ inputs.product }}" = "shared" ]; then + echo "::debug:: Product is shared, transforming changes" + if [[ "${{ steps.changes.outputs.product }}" == "true" && "${{ steps.changes.outputs.other_shared }}" == "true" ]]; then + echo "::debug:: Changes were found in 'shared' folder and in 'interfaces' and root folders" + echo "product_changes=true" >> $GITHUB_OUTPUT + echo "product_files=${{ steps.changes.outputs.product_files }},${{ steps.changes.outputs.other_shared_files }}" >> $GITHUB_OUTPUT + elif [[ "${{ steps.changes.outputs.product }}" == "false" && "${{ steps.changes.outputs.other_shared }}" == "true" ]]; then + echo "::debug:: Only contracts in' interfaces' and root folders were modified" + echo "product_changes=true" >> $GITHUB_OUTPUT + echo "product_files=${{ steps.changes.outputs.other_shared_files }}" >> $GITHUB_OUTPUT + elif [[ "${{ steps.changes.outputs.product }}" == "true" && "${{ steps.changes.outputs.other_shared }}" == "false" ]]; then + echo "::debug:: Only contracts in 'shared' folder were modified" + echo "product_changes=true" >> $GITHUB_OUTPUT + echo "product_files=${{ steps.changes.outputs.product_files }}" >> $GITHUB_OUTPUT + else + echo "::debug:: No contracts were modified" + echo "product_changes=false" >> $GITHUB_OUTPUT + echo "product_files=" >> $GITHUB_OUTPUT + fi + else + echo "product_changes=${{ steps.changes.outputs.product }}" >> $GITHUB_OUTPUT + echo "product_files=${{ steps.changes.outputs.product_files }}" >> $GITHUB_OUTPUT + fi + + - name: Check for changes outside of artifact scope + uses: ./.github/actions/validate-artifact-scope + if: ${{ steps.changes.outputs.sol == 'true' }} + with: + sol_files: ${{ steps.changes.outputs.sol_files }} + product: ${{ inputs.product }} + + gather-basic-info: + name: Gather basic info + if: ${{ needs.changes.outputs.product_changes == 'true' }} + runs-on: ubuntu-22.04 + needs: [ changes ] + outputs: + foundry_version: ${{ steps.extract-foundry-version.outputs.foundry-version }} + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + fetch-depth: 0 + + - name: Extract Foundry version + uses: ./.github/actions/detect-solidity-foundry-version + with: + working-directory: contracts + + - name: Copy modified changesets + if: ${{ needs.changes.outputs.changeset_changes == 'true' }} + run: | + mkdir -p contracts/changesets + files="${{ needs.changes.outputs.changeset_files }}" + IFS=",' + for changeset in $files; do + echo "::debug:: Copying $changeset" + cp $changeset contracts/changesets + done + + - name: Generate basic info and modified contracts list + shell: bash + run: | + echo "Commit SHA used to generate artifacts: ${{ github.sha }}" > contracts/commit_sha_base_ref.txt + echo "Base reference SHA used to find modified contracts: ${{ inputs.base_ref }}" >> contracts/commit_sha_base_ref.txt + + IFS=',' read -r -a modified_files <<< "${{ needs.changes.outputs.product_files }}" + echo "# Modified contracts:" > contracts/modified_contracts.md + for file in "${modified_files[@]}"; do + echo " - [$file](${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/$file)" >> contracts/modified_contracts.md + echo "$file" >> contracts/modified_contracts.txt + done + + - name: Upload basic info and modified contracts list + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + timeout-minutes: 2 + continue-on-error: true + with: + name: tmp-basic-info + path: | + contracts/modified_contracts.md + contracts/modified_contracts.txt + contracts/commit_sha_base_ref.txt + contracts/changesets + retention-days: 7 + + # some of the artifacts can only be generated on product level, and we cannot scope them to single contracts + # some product-level modifications might also require shared contracts changes, so if these happened we need to generate artifacts for shared contracts as well + coverage-and-book: + if: ${{ needs.changes.outputs.product_changes == 'true' }} + name: Generate Docs and Code Coverage reports + runs-on: ubuntu-22.04 + needs: [changes, gather-basic-info] + steps: + - name: Prepare exclusion list + id: prepare-exclusion-list + run: | + cat < coverage_exclusions.json + ["automation", "functions", "vrf"] + EOF + coverage_exclusions=$(cat coverage_exclusions.json | jq -c .) + echo "coverage_exclusions=$coverage_exclusions" >> $GITHUB_OUTPUT + + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Setup NodeJS + uses: ./.github/actions/setup-nodejs + + - name: Create directories + shell: bash + run: | + mkdir -p contracts/code-coverage + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@8f1998e9878d786675189ef566a2e4bf24869773 # v1.2.0 + with: + version: ${{ needs.gather-basic-info.outputs.foundry_version }} + + # required for code coverage report generation + - name: Setup LCOV + uses: hrishikesh-kadam/setup-lcov@f5da1b26b0dcf5d893077a3c4f29cf78079c841d # v1.0.0 + + - name: Run Forge build for product contracts + if: ${{ needs.changes.outputs.product_changes == 'true' }} + run: | + forge --version + forge build + working-directory: contracts + env: + FOUNDRY_PROFILE: ${{ inputs.product }} + + - name: Run coverage for product contracts + if: ${{ !contains(fromJson(steps.prepare-exclusion-list.outputs.coverage_exclusions), inputs.product) && needs.changes.outputs.product_changes == 'true' }} + working-directory: contracts + run: forge coverage --report lcov --report-file code-coverage/lcov.info + env: + FOUNDRY_PROFILE: ${{ inputs.product }} + + - name: Generate Code Coverage HTML report for product contracts + if: ${{ !contains(fromJson(steps.prepare-exclusion-list.outputs.coverage_exclusions), inputs.product) && needs.changes.outputs.product_changes == 'true' }} + shell: bash + working-directory: contracts + run: genhtml code-coverage/lcov.info --branch-coverage --output-directory code-coverage + + - name: Run Forge doc for product contracts + if: ${{ needs.changes.outputs.product_changes == 'true' }} + run: forge doc --build -o docs + working-directory: contracts + env: + FOUNDRY_PROFILE: ${{ inputs.product }} + + - name: Upload Artifacts for product contracts + if: ${{ needs.changes.outputs.product_changes == 'true' }} + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + timeout-minutes: 2 + continue-on-error: true + with: + name: tmp-${{ inputs.product }}-artifacts + path: | + contracts/docs + contracts/code-coverage/lcov-.info + contracts/code-coverage + retention-days: 7 + + # Generates UML diagrams and Slither reports for modified contracts + uml-static-analysis: + if: ${{ needs.changes.outputs.product_changes == 'true' }} + name: Generate UML and Slither reports for modified contracts + runs-on: ubuntu-22.04 + needs: [changes, gather-basic-info] + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + fetch-depth: 0 + + - name: Setup NodeJS + uses: ./.github/actions/setup-nodejs + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@8f1998e9878d786675189ef566a2e4bf24869773 # v1.2.0 + with: + version: ${{ needs.gather-basic-info.outputs.foundry_version }} + + - name: Install Sol2uml + run: | + npm link sol2uml --only=production + + - name: Set up Python + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f #v5.1.1 + with: + python-version: '3.8' + + - name: Install solc-select and solc + uses: ./.github/actions/setup-solc-select + with: + to_install: '0.8.19' + to_use: '0.8.19' + + - name: Install Slither + uses: ./.github/actions/setup-slither + + - name: Generate UML + shell: bash + run: | + contract_list="${{ needs.changes.outputs.product_files }}" + + # modify remappings so that solc can find dependencies + ./contracts/scripts/ci/modify_remappings.sh contracts contracts/remappings.txt + mv remappings_modified.txt remappings.txt + + ./contracts/scripts/ci/generate_uml.sh "./" "contracts/uml-diagrams" "$contract_list" + + - name: Generate Slither Markdown reports + run: | + contract_list="${{ needs.changes.outputs.product_files }}" + + echo "::debug::Processing contracts: $contract_list" + ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/" contracts/configs/slither/.slither.config-artifacts.json "." "$contract_list" "contracts/slither-reports" "--solc-remaps @=contracts/node_modules/@" + + - name: Upload UMLs and Slither reports + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + timeout-minutes: 10 + continue-on-error: true + with: + name: tmp-contracts-artifacts + path: | + contracts/uml-diagrams + contracts/slither-reports + retention-days: 7 + + - name: Validate if all Slither run for all contracts + uses: ./.github/actions/validate-solidity-artifacts + with: + validate_slither_reports: 'true' + validate_uml_diagrams: 'true' + slither_reports_path: 'contracts/slither-reports' + uml_diagrams_path: 'contracts/uml-diagrams' + sol_files: ${{ needs.changes.outputs.product_files }} + + gather-all-artifacts: + name: Gather all artifacts + if: ${{ needs.changes.outputs.product_changes == 'true' }} + runs-on: ubuntu-latest + needs: [coverage-and-book, uml-static-analysis, gather-basic-info, changes] + steps: + - name: Download all artifacts + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + path: review_artifacts + merge-multiple: true + + - name: Upload all artifacts as single package + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + with: + name: review-artifacts-${{ inputs.product }}-${{ github.sha }} + path: review_artifacts + retention-days: 60 + + - name: Remove temporary artifacts + uses: geekyeggo/delete-artifact@24928e75e6e6590170563b8ddae9fac674508aa1 # v5.0 + with: + name: tmp-* + + - name: Print Artifact URL in job summary + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + ARTIFACTS=$(gh api -X GET repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts) + ARTIFACT_ID=$(echo "$ARTIFACTS" | jq '.artifacts[] | select(.name=="review-artifacts-${{ inputs.product }}-${{ github.sha }}") | .id') + echo "Artifact ID: $ARTIFACT_ID" + + echo "# Solidity Review Artifact Generated" >> $GITHUB_STEP_SUMMARY + echo "Base Ref used: **${{ inputs.base_ref }}**" >> $GITHUB_STEP_SUMMARY + echo "Commit SHA used: **${{ github.sha }}**" >> $GITHUB_STEP_SUMMARY + echo "[Artifact URL](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/$ARTIFACT_ID)" >> $GITHUB_STEP_SUMMARY + + notify-no-changes: + if: ${{ needs.changes.outputs.product_changes == 'false' }} + needs: [changes] + runs-on: ubuntu-latest + steps: + - name: Print warning in job summary + shell: bash + run: | + echo "# Solidity Review Artifact NOT Generated" >> $GITHUB_STEP_SUMMARY + echo "Base Ref used: **${{ inputs.base_ref }}**" >> $GITHUB_STEP_SUMMARY + echo "Commit SHA used: **${{ github.sha }}**" >> $GITHUB_STEP_SUMMARY + echo "## Reason: No modified Solidity files found for ${{ inputs.product }}" >> $GITHUB_STEP_SUMMARY + echo "* no modified Solidity files found between ${{ inputs.base_ref }} and ${{ github.sha }} commits" >> $GITHUB_STEP_SUMMARY + echo "* or they are located outside of ./contracts/src/v0.8 folder" >> $GITHUB_STEP_SUMMARY + echo "* or they were limited to test files" >> $GITHUB_STEP_SUMMARY + exit 1 diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index 4ec9e42447..906cb76ffe 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -3,42 +3,122 @@ on: [pull_request] env: FOUNDRY_PROFILE: ci - # Has to match the `make foundry` version in `contracts/GNUmakefile` - FOUNDRY_VERSION: nightly-de33b6af53005037b463318d2628b5cfcaf39916 + +# Making changes: +# * use the top-level matrix to decide, which checks should run for each product. +# * when enabling code coverage, remember to adjust the minimum code coverage as it's set to 98.5% by default. jobs: + define-matrix: + name: Define test matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.define-matrix.outputs.matrix }} + foundry-version: ${{ steps.extract-foundry-version.outputs.foundry-version }} + steps: + - name: Define test matrix + id: define-matrix + shell: bash + run: | + cat < matrix.json + [ + { "name": "automation", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": false, "run-forge-fmt": false }}, + { "name": "ccip", "setup": { "run-coverage": true, "min-coverage": 98.5, "run-gas-snapshot": true, "run-forge-fmt": true }}, + { "name": "functions", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "keystone", "setup": { "run-coverage": true, "min-coverage": 74.1, "run-gas-snapshot": false, "run-forge-fmt": false }}, + { "name": "l2ep", "setup": { "run-coverage": true, "min-coverage": 65.6, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "liquiditymanager", "setup": { "run-coverage": true, "min-coverage": 46.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "llo-feeds", "setup": { "run-coverage": true, "min-coverage": 49.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "operatorforwarder", "setup": { "run-coverage": true, "min-coverage": 55.7, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "shared", "setup": { "run-coverage": true, "min-coverage": 32.6, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "transmission", "setup": { "run-coverage": true, "min-coverage": 65.6, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "vrf", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": false, "run-forge-fmt": false }} + ] + EOF + + matrix=$(cat matrix.json | jq -c .) + echo "matrix=$matrix" >> $GITHUB_OUTPUT + + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Extract Foundry version + id: extract-foundry-version + uses: ./.github/actions/detect-solidity-foundry-version + with: + working-directory: contracts + changes: name: Detect changes runs-on: ubuntu-latest outputs: - changes: ${{ steps.changes.outputs.src }} + non_src_changes: ${{ steps.changes.outputs.non_src }} + sol_modified: ${{ steps.changes.outputs.sol }} + sol_modified_files: ${{ steps.changes.outputs.sol_files }} + not_test_sol_modified: ${{ steps.changes.outputs.not_test_sol }} + not_test_sol_modified_files: ${{ steps.changes.outputs.not_test_sol_files }} + all_changes: ${{ steps.changes.outputs.changes }} steps: - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 id: changes with: + list-files: 'shell' filters: | - src: - - 'contracts/src/v0.8/**/*' + non_src: - '.github/workflows/solidity-foundry.yml' - 'contracts/foundry.toml' - 'contracts/gas-snapshots/*.gas-snapshot' + - 'contracts/package.json' + sol: + - modified|added: 'contracts/src/v0.8/**/*.sol' + not_test_sol: + - modified|added: 'contracts/src/v0.8/**/!(*.t).sol' + automation: + - 'contracts/src/v0.8/automation/**/*.sol' + ccip: + - 'contracts/src/v0.8/ccip/**/*.sol' + functions: + - 'contracts/src/v0.8/functions/**/*.sol' + keystone: + - 'contracts/src/v0.8/keystone/**/*.sol' + l2ep: + - 'contracts/src/v0.8/l2ep/**/*.sol' + liquiditymanager: + - 'contracts/src/v0.8/liquiditymanager/**/*.sol' + llo-feeds: + - 'contracts/src/v0.8/llo-feeds/**/*.sol' + operatorforwarder: + - 'contracts/src/v0.8/operatorforwarder/**/*.sol' + vrf: + - 'contracts/src/v0.8/vrf/**/*.sol' + shared: + - 'contracts/src/v0.8/shared/**/*.sol' + - 'contracts/src/v0.8/*.sol' + - 'contracts/src/v0.8/mocks/**/*.sol' + - 'contracts/src/v0.8/tests/**/*.sol' + - 'contracts/src/v0.8/vendor/**/*.sol' + transmission: + - 'contracts/src/v0.8/transmission/**/*.sol' tests: + if: ${{ needs.changes.outputs.non_src_changes == 'true' || needs.changes.outputs.sol_modified == 'true' }} strategy: fail-fast: false matrix: - product: [automation, ccip, functions, keystone, l2ep, liquiditymanager, llo-feeds, operatorforwarder, shared, vrf] - needs: [changes] - name: Foundry Tests ${{ matrix.product }} - # See https://github.com/foundry-rs/foundry/issues/3827 + product: ${{fromJson(needs.define-matrix.outputs.matrix)}} + needs: [define-matrix, changes] + name: Foundry Tests ${{ matrix.product.name }} runs-on: ubuntu-22.04 # The if statements for steps after checkout repo is workaround for # passing required check for PRs that don't have filtered changes. steps: - name: Checkout the repo + if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) + || contains(fromJson(needs.changes.outputs.all_changes), 'shared') + || needs.changes.outputs.non_src_changes == 'true' }} uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: submodules: recursive @@ -47,127 +127,241 @@ jobs: # and not native Foundry. This is to make sure the dependencies # stay in sync. - name: Setup NodeJS - if: needs.changes.outputs.changes == 'true' + if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) + || contains(fromJson(needs.changes.outputs.all_changes), 'shared') + || needs.changes.outputs.non_src_changes == 'true' }} uses: ./.github/actions/setup-nodejs - name: Install Foundry - if: needs.changes.outputs.changes == 'true' + if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) + || contains(fromJson(needs.changes.outputs.all_changes), 'shared') + || needs.changes.outputs.non_src_changes == 'true' }} uses: foundry-rs/foundry-toolchain@8f1998e9878d786675189ef566a2e4bf24869773 # v1.2.0 with: - version: ${{ env.FOUNDRY_VERSION }} + version: ${{ needs.define-matrix.outputs.foundry-version }} - name: Run Forge build - if: needs.changes.outputs.changes == 'true' + if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) + || contains(fromJson(needs.changes.outputs.all_changes), 'shared') + || needs.changes.outputs.non_src_changes == 'true' }} run: | forge --version forge build id: build working-directory: contracts env: - FOUNDRY_PROFILE: ${{ matrix.product }} + FOUNDRY_PROFILE: ${{ matrix.product.name }} - name: Run Forge tests - if: needs.changes.outputs.changes == 'true' + if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) + || contains(fromJson(needs.changes.outputs.all_changes), 'shared') + || needs.changes.outputs.non_src_changes == 'true' }} run: | forge test -vvv id: test working-directory: contracts env: - FOUNDRY_PROFILE: ${{ matrix.product }} + FOUNDRY_PROFILE: ${{ matrix.product.name }} - name: Run Forge snapshot - if: ${{ !contains(fromJson('["vrf"]'), matrix.product) && !contains(fromJson('["automation"]'), matrix.product) && !contains(fromJson('["keystone"]'), matrix.product) && needs.changes.outputs.changes == 'true' }} + if: ${{ (contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) + || contains(fromJson(needs.changes.outputs.all_changes), 'shared') + || needs.changes.outputs.non_src_changes == 'true') + && matrix.product.setup.run-gas-snapshot }} run: | - forge snapshot --nmt "test_?Fuzz_\w{1,}?" --check gas-snapshots/${{ matrix.product }}.gas-snapshot + forge snapshot --nmt "test_?Fuzz_\w{1,}?" --check gas-snapshots/${{ matrix.product.name }}.gas-snapshot id: snapshot working-directory: contracts env: - FOUNDRY_PROFILE: ${{ matrix.product }} + FOUNDRY_PROFILE: ${{ matrix.product.name }} - - name: Run coverage - if: ${{ contains(fromJson('["ccip"]'), matrix.product) && needs.changes.outputs.changes == 'true' }} + # required for code coverage report generation + - name: Setup LCOV + if: ${{ (contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) + || contains(fromJson(needs.changes.outputs.all_changes), 'shared') + || needs.changes.outputs.non_src_changes == 'true') + && matrix.product.setup.run-coverage }} + uses: hrishikesh-kadam/setup-lcov@f5da1b26b0dcf5d893077a3c4f29cf78079c841d # v1.0.0 + + - name: Run coverage for ${{ matrix.product.name }} + if: ${{ (contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) + || contains(fromJson(needs.changes.outputs.all_changes), 'shared') + || needs.changes.outputs.non_src_changes == 'true') + && matrix.product.setup.run-coverage }} working-directory: contracts run: forge coverage --report lcov env: - FOUNDRY_PROFILE: ${{ matrix.product }} + FOUNDRY_PROFILE: ${{ matrix.product.name }} - - name: Prune report - if: ${{ contains(fromJson('["ccip"]'), matrix.product) && needs.changes.outputs.changes == 'true' }} + - name: Prune lcov report + if: ${{ (contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) + || contains(fromJson(needs.changes.outputs.all_changes), 'shared') + || needs.changes.outputs.non_src_changes == 'true') + && matrix.product.setup.run-coverage }} run: | sudo apt-get install lcov - ./contracts/scripts/ccip_lcov_prune ./contracts/lcov.info ./lcov.info.pruned + ./contracts/scripts/lcov_prune ${{ matrix.product.name }} ./contracts/lcov.info ./contracts/lcov.info.pruned - - name: Report code coverage - if: ${{ contains(fromJson('["ccip"]'), matrix.product) && needs.changes.outputs.changes == 'true' }} + - name: Report code coverage for ${{ matrix.product.name }} + if: ${{ (contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) + || contains(fromJson(needs.changes.outputs.all_changes), 'shared') + || needs.changes.outputs.non_src_changes == 'true') + && matrix.product.setup.run-coverage }} uses: zgosalvez/github-actions-report-lcov@a546f89a65a0cdcd82a92ae8d65e74d450ff3fbc # v4.1.4 with: - update-comment: true - coverage-files: lcov.info.pruned - minimum-coverage: 98.5 - artifact-name: code-coverage-report + update-comment: false + coverage-files: ./contracts/lcov.info.pruned + minimum-coverage: ${{ matrix.product.min-coverage }} + artifact-name: code-coverage-report-${{ matrix.product.name }} working-directory: ./contracts - github-token: ${{ secrets.GITHUB_TOKEN }} - name: Collect Metrics - if: needs.changes.outputs.changes == 'true' + if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) + || contains(fromJson(needs.changes.outputs.all_changes), 'shared') + || needs.changes.outputs.non_src_changes == 'true' }} id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 with: - id: solidity-foundry + id: ${{ matrix.product.name }}-solidity-foundry + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Foundry Tests ${{ matrix.product.name }} + continue-on-error: true + + analyze: + needs: [ changes, define-matrix ] + name: Run static analysis + if: needs.changes.outputs.not_test_sol_modified == 'true' + runs-on: ubuntu-22.04 + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + submodules: recursive + + - name: Setup NodeJS + uses: ./.github/actions/setup-nodejs + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@8f1998e9878d786675189ef566a2e4bf24869773 # v1.2.0 + with: + version: ${{ needs.define-matrix.outputs.foundry-version }} + + - name: Set up Python + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f #v5.1.1 + with: + python-version: '3.8' + + - name: Install solc-select and solc + uses: ./.github/actions/setup-solc-select + with: + to_install: '0.8.19' + to_use: '0.8.19' + + - name: Install Slither + uses: ./.github/actions/setup-slither + + - name: Run Slither + shell: bash + run: | + # modify remappings so that solc can find dependencies + ./contracts/scripts/ci/modify_remappings.sh contracts contracts/remappings.txt + mv remappings_modified.txt remappings.txt + + FILES="${{ needs.changes.outputs.not_test_sol_modified_files }}" + + for FILE in $FILES; do + PRODUCT=$(echo "$FILE" | awk -F'src/[^/]*/' '{print $2}' | cut -d'/' -f1) + echo "::debug::Running Slither for $FILE in $PRODUCT" + SLITHER_CONFIG="contracts/configs/slither/.slither.config-$PRODUCT-pr.json" + if [ ! -f $SLITHER_CONFIG ]; then + echo "::debug::No Slither config found for $PRODUCT, using default" + SLITHER_CONFIG="contracts/configs/slither/.slither.config-default-pr.json" + fi + ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/" "$SLITHER_CONFIG" "." "$FILE" "contracts/slither-reports" "--solc-remaps @=contracts/node_modules/@" + done + + - name: Print Slither summary + shell: bash + run: | + echo "# Static analysis results " >> $GITHUB_STEP_SUMMARY + for file in "contracts/slither-reports"/*.md; do + if [ -e "$file" ]; then + cat "$file" >> $GITHUB_STEP_SUMMARY + fi + done + + - name: Validate if all Slither run for all contracts + uses: ./.github/actions/validate-solidity-artifacts + with: + validate_slither_reports: 'true' + slither_reports_path: 'contracts/slither-reports' + sol_files: ${{ needs.changes.outputs.not_test_sol_modified_files }} + + - name: Upload Slither report + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + timeout-minutes: 10 + continue-on-error: true + with: + name: slither-reports-${{ github.sha }} + path: | + contracts/slither-reports + retention-days: 7 + + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: solidity-foundry-slither org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Foundry Tests ${{ matrix.product }} + this-job-name: Run static analysis continue-on-error: true solidity-forge-fmt: + name: Forge fmt ${{ matrix.product.name }} + if: ${{ needs.changes.outputs.non_src_changes == 'true' || needs.changes.outputs.not_test_sol_modified == 'true' }} + needs: [define-matrix, changes] strategy: fail-fast: false matrix: - product: [ ccip ] - needs: [ changes ] - name: Forge fmt ${{ matrix.product }} - # See https://github.com/foundry-rs/foundry/issues/3827 + product: ${{fromJson(needs.define-matrix.outputs.matrix)}} runs-on: ubuntu-22.04 - - # The if statements for steps after checkout repo is workaround for - # passing required check for PRs that don't have filtered changes. steps: - name: Checkout the repo + if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) && matrix.product.setup.run-forge-fmt }} uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: submodules: recursive - # Only needed because we use the NPM versions of packages - # and not native Foundry. This is to make sure the dependencies - # stay in sync. - name: Setup NodeJS - if: needs.changes.outputs.changes == 'true' + if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) && matrix.product.setup.run-forge-fmt }} uses: ./.github/actions/setup-nodejs - name: Install Foundry - if: needs.changes.outputs.changes == 'true' + if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) && matrix.product.setup.run-forge-fmt }} uses: foundry-rs/foundry-toolchain@8f1998e9878d786675189ef566a2e4bf24869773 # v1.2.0 with: - version: ${{ env.FOUNDRY_VERSION }} + version: ${{ needs.define-matrix.outputs.foundry-version }} - name: Run Forge fmt - if: needs.changes.outputs.changes == 'true' - run: | - forge fmt --check + if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) && matrix.product.setup.run-forge-fmt }} + run: forge fmt --check id: fmt working-directory: contracts env: - FOUNDRY_PROFILE: ${{ matrix.product }} + FOUNDRY_PROFILE: ${{ matrix.product.name }} - name: Collect Metrics - if: needs.changes.outputs.changes == 'true' + if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) && matrix.product.setup.run-forge-fmt }} id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 with: - id: solidity-forge-fmt + id: solidity-forge-fmt-${{ matrix.product.name }} org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Foundry Tests ${{ matrix.product }} + this-job-name: Forge fmt ${{ matrix.product.name }} continue-on-error: true diff --git a/.github/workflows/solidity-hardhat.yml b/.github/workflows/solidity-hardhat.yml index f28cf49907..705fad3be6 100644 --- a/.github/workflows/solidity-hardhat.yml +++ b/.github/workflows/solidity-hardhat.yml @@ -84,4 +84,4 @@ jobs: basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} this-job-name: Solidity - continue-on-error: true \ No newline at end of file + continue-on-error: true diff --git a/contracts/.changeset/itchy-deers-deny.md b/contracts/.changeset/itchy-deers-deny.md new file mode 100644 index 0000000000..888d58ce31 --- /dev/null +++ b/contracts/.changeset/itchy-deers-deny.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +More comprehensive & product-scoped Solidity Foundry pipeline diff --git a/contracts/configs/slither/.slither.config-artifacts.json b/contracts/configs/slither/.slither.config-artifacts.json new file mode 100644 index 0000000000..75071341f5 --- /dev/null +++ b/contracts/configs/slither/.slither.config-artifacts.json @@ -0,0 +1,3 @@ +{ + "filter_paths": "(openzeppelin|mocks/|test/|tests/|testhelpers)" +} diff --git a/contracts/configs/slither/.slither.config-ccip-pr.json b/contracts/configs/slither/.slither.config-ccip-pr.json new file mode 100644 index 0000000000..84d231ea07 --- /dev/null +++ b/contracts/configs/slither/.slither.config-ccip-pr.json @@ -0,0 +1,4 @@ +{ + "filter_paths": "(openzeppelin|mocks/|test/|tests/|testhelpers)", + "detectors_to_exclude": "pragma,solc-version,naming-convention,assembly,reentrancy-events,timestamp,calls-loop,unused-return" +} diff --git a/contracts/configs/slither/.slither.config-default-pr.json b/contracts/configs/slither/.slither.config-default-pr.json new file mode 100644 index 0000000000..1ef145a795 --- /dev/null +++ b/contracts/configs/slither/.slither.config-default-pr.json @@ -0,0 +1,4 @@ +{ + "filter_paths": "(openzeppelin|mocks/|test/|tests/|testhelpers)", + "detectors_to_exclude": "pragma" +} diff --git a/contracts/scripts/ccip_lcov_prune b/contracts/scripts/ccip_lcov_prune deleted file mode 100755 index 002e5a3f13..0000000000 --- a/contracts/scripts/ccip_lcov_prune +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -set -e - -# src/v0.8/ccip/libraries/Internal.sol -# src/v0.8/ccip/libraries/RateLimiter.sol -# src/v0.8/ccip/libraries/USDPriceWith18Decimals.sol -# src/v0.8/ccip/libraries/MerkleMultiProof.sol -# src/v0.8/ccip/libraries/Pool.sol -# excluded because Foundry doesn't support coverage on library files - -# BurnWithFromMintTokenPool is excluded because Forge doesn't seem to -# register coverage, even though it is 100% covered. - -lcov --remove $1 -o $2 \ - '*/ccip/test/*' \ - '*/vendor/*' \ - '*/shared/*' \ - 'src/v0.8/ccip/ocr/OCR2Abstract.sol' \ - 'src/v0.8/ccip/libraries/Internal.sol' \ - 'src/v0.8/ccip/libraries/RateLimiter.sol' \ - 'src/v0.8/ccip/libraries/USDPriceWith18Decimals.sol' \ - 'src/v0.8/ccip/libraries/MerkleMultiProof.sol' \ - 'src/v0.8/ccip/libraries/Pool.sol' \ - 'src/v0.8/ConfirmedOwnerWithProposal.sol' \ - 'src/v0.8/tests/MockV3Aggregator.sol' \ - 'src/v0.8/ccip/applications/CCIPClientExample.sol' \ - 'src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol' \ - --rc lcov_branch_coverage=1 diff --git a/contracts/scripts/ci/generate_slither_report.sh b/contracts/scripts/ci/generate_slither_report.sh new file mode 100755 index 0000000000..7fe31d40ef --- /dev/null +++ b/contracts/scripts/ci/generate_slither_report.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash + +set -euo pipefail + +function check_chainlink_dir() { + local param_dir="chainlink" + current_dir=$(pwd) + + current_base=$(basename "$current_dir") + + if [[ "$current_base" != "$param_dir" ]]; then + >&2 echo "The script must be run from the root of $param_dir directory" + exit 1 + fi +} + +check_chainlink_dir + +if [ "$#" -lt 5 ]; then + >&2 echo "Generates Markdown Slither reports and saves them to a target directory." + >&2 echo "Usage: $0 [slither extra params]" + exit 1 +fi + +REPO_URL=$1 +CONFIG_FILE=$2 +SOURCE_DIR=$3 +FILES=${4// /} # Remove any spaces from the list of files +TARGET_DIR=$5 +SLITHER_EXTRA_PARAMS=$6 + +run_slither() { + local FILE=$1 + local TARGET_DIR=$2 + + if [[ ! -f "$FILE" ]]; then + >&2 echo "::error:File not found: $FILE" + return 1 + fi + + set +e + source ./contracts/scripts/ci/select_solc_version.sh "$FILE" + if [[ $? -ne 0 ]]; then + >&2 echo "::error::Failed to select Solc version for $FILE" + return 1 + fi + set -e + + SLITHER_OUTPUT_FILE="$TARGET_DIR/$(basename "${FILE%.sol}")-slither-report.md" + + output=$(slither --config-file "$CONFIG_FILE" "$FILE" --checklist --markdown-root "$REPO_URL" --fail-none $SLITHER_EXTRA_PARAMS) + if [ $? -ne 0 ]; then + >&2 echo "::error::Slither failed for $FILE" + exit 1 + fi + output=$(echo "$output" | sed '/\*\*THIS CHECKLIST IS NOT COMPLETE\*\*. Use `--show-ignored-findings` to show all the results./d' | sed '/Summary/d') + + echo "# Summary for $FILE" > "$SLITHER_OUTPUT_FILE" + echo "$output" >> "$SLITHER_OUTPUT_FILE" + + if [[ -z "$output" ]]; then + echo "No issues found." >> "$SLITHER_OUTPUT_FILE" + fi +} + +process_files() { + local SOURCE_DIR=$1 + local TARGET_DIR=$2 + local FILES=(${3//,/ }) # Split the comma-separated list into an array + + mkdir -p "$TARGET_DIR" + + for FILE in "${FILES[@]}"; do + FILE=${FILE//\"/} + run_slither "$SOURCE_DIR/$FILE" "$TARGET_DIR" + done +} + +set +e +process_files "$SOURCE_DIR" "$TARGET_DIR" "${FILES[@]}" + +if [[ $? -ne 0 ]]; then + >&2 echo "::error::Failed to generate Slither reports" + exit 1 +fi + +echo "Slither reports saved in $TARGET_DIR folder" diff --git a/contracts/scripts/ci/generate_uml.sh b/contracts/scripts/ci/generate_uml.sh new file mode 100755 index 0000000000..65745c93bb --- /dev/null +++ b/contracts/scripts/ci/generate_uml.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash + +set -euo pipefail + +function check_chainlink_dir() { + local param_dir="chainlink" + current_dir=$(pwd) + + current_base=$(basename "$current_dir") + + if [[ "$current_base" != "$param_dir" ]]; then + >&2 echo "The script must be run from the root of $param_dir directory" + exit 1 + fi +} + +check_chainlink_dir + +if [ "$#" -lt 2 ]; then + >&2 echo "Generates UML diagrams for all contracts in a directory after flattening them to avoid call stack overflows." + >&2 echo "Usage: $0 [comma-separated list of files]" + exit 1 +fi + +SOURCE_DIR="$1" +TARGET_DIR="$2" +FILES=${3// /} # Remove any spaces from the list of files +FAILED_FILES=() + +flatten_and_generate_uml() { + local FILE=$1 + local TARGET_DIR=$2 + + set +e + FLATTENED_FILE="$TARGET_DIR/flattened_$(basename "$FILE")" + echo "::debug::Flattening $FILE to $FLATTENED_FILE" + forge flatten "$FILE" -o "$FLATTENED_FILE" --root contracts + if [[ $? -ne 0 ]]; then + >&2 echo "::error::Failed to flatten $FILE" + FAILED_FILES+=("$FILE") + return + fi + + OUTPUT_FILE=${FLATTENED_FILE//"flattened_"/""} + OUTPUT_FILE_SVG="${OUTPUT_FILE%.sol}.svg" + echo "::debug::Generating SVG UML for $FLATTENED_FILE to $OUTPUT_FILE_SVG" + sol2uml "$FLATTENED_FILE" -o "$OUTPUT_FILE_SVG" + if [[ $? -ne 0 ]]; then + >&2 echo "::error::Failed to generate UML diagram in SVG format for $FILE" + FAILED_FILES+=("$FILE") + rm "$FLATTENED_FILE" + return + fi + OUTPUT_FILE_DOT="${OUTPUT_FILE%.sol}.dot" + echo "::debug::Generating DOT UML for $FLATTENED_FILE to $OUTPUT_FILE_DOT" + sol2uml "$FLATTENED_FILE" -o "$OUTPUT_FILE_DOT" -f dot + if [[ $? -ne 0 ]]; then + >&2 echo "::error::Failed to generate UML diagram in DOT format for $FILE" + FAILED_FILES+=("$FILE") + rm "$FLATTENED_FILE" + return + fi + + rm "$FLATTENED_FILE" + set -e +} + +process_all_files_in_directory() { + local SOURCE_DIR=$1 + local TARGET_DIR=$2 + + mkdir -p "$TARGET_DIR" + + find "$SOURCE_DIR" -type f -name '*.sol' | while read -r ITEM; do + flatten_and_generate_uml "$ITEM" "$TARGET_DIR" + done +} + +process_selected_files() { + local SOURCE_DIR=$1 + local TARGET_DIR=$2 + local FILES=(${3//,/ }) # Split the comma-separated list into an array + + mkdir -p "$TARGET_DIR" + + for FILE in "${FILES[@]}"; do + FILE=${FILE//\"/} + MATCHES=($(find "$SOURCE_DIR" -type f -path "*/$FILE")) + + if [[ ${#MATCHES[@]} -gt 1 ]]; then + >&2 echo "Error: Multiple matches found for $FILE:" + for MATCH in "${MATCHES[@]}"; do + >&2 echo " $MATCH" + done + exit 1 + elif [[ ${#MATCHES[@]} -eq 1 ]]; then + >&2 echo "::debug::File found: ${MATCHES[0]}" + flatten_and_generate_uml "${MATCHES[0]}" "$TARGET_DIR" + else + >&2 echo "::error::File $FILE does not exist within the source directory $SOURCE_DIR." + exit 1 + fi + done +} + +# if FILES is empty, process all files in the directory, otherwise process only the selected files +if [[ -z "$FILES" ]]; then + process_all_files_in_directory "$SOURCE_DIR" "$TARGET_DIR" +else + process_selected_files "$SOURCE_DIR" "$TARGET_DIR" "$FILES" +fi + +if [[ "${#FAILED_FILES[@]}" -gt 0 ]]; then + >&2 echo ":error::Failed to generate UML diagrams for ${#FAILED_FILES[@]} files:" + for FILE in "${FAILED_FILES[@]}"; do + >&2 echo " $FILE" + echo "$FILE" >> "$TARGET_DIR/uml_generation_failures.txt" + done +fi + +echo "UML diagrams saved in $TARGET_DIR folder" diff --git a/contracts/scripts/ci/modify_remappings.sh b/contracts/scripts/ci/modify_remappings.sh new file mode 100755 index 0000000000..e64ca369b0 --- /dev/null +++ b/contracts/scripts/ci/modify_remappings.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -euo pipefail + +if [ "$#" -ne 2 ]; then + >&2 echo "Usage: $0 " + exit 1 +fi + +DIR_PREFIX=$1 +REMAPPINGS_FILE=$2 + +if [ ! -f "$REMAPPINGS_FILE" ]; then + >&2 echo "::error:: Remappings file '$REMAPPINGS_FILE' not found." + exit 1 +fi + +OUTPUT_FILE="remappings_modified.txt" + +while IFS= read -r line; do + if [[ "$line" =~ ^[^=]+= ]]; then + REMAPPED_PATH="${line#*=}" + MODIFIED_LINE="${line%=*}=${DIR_PREFIX}/${REMAPPED_PATH}" + echo "$MODIFIED_LINE" >> "$OUTPUT_FILE" + else + echo "$line" >> "$OUTPUT_FILE" + fi +done < "$REMAPPINGS_FILE" + +echo "Modified remappings have been saved to: $OUTPUT_FILE" diff --git a/contracts/scripts/ci/select_solc_version.sh b/contracts/scripts/ci/select_solc_version.sh new file mode 100755 index 0000000000..3f7d7864ab --- /dev/null +++ b/contracts/scripts/ci/select_solc_version.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash + +set -euo pipefail + +function check_chainlink_dir() { + local param_dir="chainlink" + current_dir=$(pwd) + + current_base=$(basename "$current_dir") + + if [[ "$current_base" != "$param_dir" ]]; then + >&2 echo "::error::The script must be run from the root of $param_dir directory" + exit 1 + fi +} + +check_chainlink_dir + +FILE="$1" + +if [[ "$#" -lt 1 ]]; then + echo "Detects the Solidity version of a file and selects the appropriate Solc version." + echo "If the version is not installed, it will be installed and selected." + echo "Will prefer to use the version from Foundry profile if it satisfies the version in the file." + echo "Usage: $0 " + exit 1 +fi + +if [[ -z "$FILE" ]]; then + >&2 echo "::error:: File not provided." + exit 1 +fi + +extract_product() { + local path=$1 + + echo "$path" | awk -F'src/[^/]*/' '{print $2}' | cut -d'/' -f1 +} + +extract_pragma() { + local FILE=$1 + + if [[ -f "$FILE" ]]; then + SOLCVER="$(grep --no-filename '^pragma solidity' "$FILE" | cut -d' ' -f3)" + else + >&2 echo ":error::$FILE is not a file or it could not be found. Exiting." + return 1 + fi + SOLCVER="$(echo "$SOLCVER" | sed 's/[^0-9\.^]//g')" + >&2 echo "::debug::Detected Solidity version in pragma: $SOLCVER" + echo "$SOLCVER" +} + +echo "Detecting Solc version for $FILE" + +# Set FOUNDRY_PROFILE to the product name only if it is set; otherwise either already set value will be used or it will be empty +PRODUCT=$(extract_product "$FILE") +if [ -n "$PRODUCT" ]; then + FOUNDRY_PROFILE="$PRODUCT" +fi +SOLC_IN_PROFILE=$(forge config --json --root contracts | jq ".solc") +SOLC_IN_PROFILE=$(echo "$SOLC_IN_PROFILE" | tr -d "'\"") +echo "::debug::Detected Solidity version in profile: $SOLC_IN_PROFILE" + +set +e +SOLCVER=$(extract_pragma "$FILE") + +if [[ $? -ne 0 ]]; then + echo "Error: Failed to extract the Solidity version from $FILE." + return 1 +fi + +set -e + +SOLCVER=$(echo "$SOLCVER" | tr -d "'\"") + +if [[ "$SOLC_IN_PROFILE" != "null" && -n "$SOLCVER" ]]; then + set +e + COMPAT_SOLC_VERSION=$(npx semver "$SOLC_IN_PROFILE" -r "$SOLCVER") + exit_code=$? + set -e + if [[ $exit_code -eq 0 && -n "$COMPAT_SOLC_VERSION" ]]; then + echo "::debug::Version $SOLC_IN_PROFILE satisfies the constraint $SOLCVER" + SOLC_TO_USE="$SOLC_IN_PROFILE" + else + echo "::debug::Version $SOLC_IN_PROFILE does not satisfy the constraint $SOLCVER" + SOLC_TO_USE="$SOLCVER" + fi + elif [[ "$SOLC_IN_PROFILE" != "null" && -z "$SOLCVER" ]]; then + >&2 echo "::error::No version found in the Solidity file. Exiting" + return 1 + elif [[ "$SOLC_IN_PROFILE" == "null" && -n "$SOLCVER" ]]; then + echo "::debug::Using the version from the file: $SOLCVER" + SOLC_TO_USE="$SOLCVER" + else + >&2 echo "::error::No version found in the profile or the Solidity file." + return 1 +fi + +echo "Will use $SOLC_TO_USE" +SOLC_TO_USE=$(echo "$SOLC_TO_USE" | tr -d "'\"") +SOLC_TO_USE="$(echo "$SOLC_TO_USE" | sed 's/[^0-9\.]//g')" + +INSTALLED_VERSIONS=$(solc-select versions) + +if echo "$INSTALLED_VERSIONS" | grep -q "$SOLC_TO_USE"; then + echo "::debug::Version $SOLCVER is already installed." + if echo "$INSTALLED_VERSIONS" | grep "$SOLC_TO_USE" | grep -q "current"; then + echo "::debug::Version $SOLCVER is already selected." + else + echo "::debug::Selecting $SOLC_TO_USE" + solc-select use "$SOLC_TO_USE" + fi +else + echo "::debug::Version $SOLC_TO_USE is not installed." + solc-select install "$SOLC_TO_USE" + solc-select use "$SOLC_TO_USE" +fi diff --git a/contracts/scripts/lcov_prune b/contracts/scripts/lcov_prune new file mode 100755 index 0000000000..0f16715cb2 --- /dev/null +++ b/contracts/scripts/lcov_prune @@ -0,0 +1,77 @@ +#!/bin/bash + +if [ "$#" -ne 3 ]; then + >&2 echo "Usage: $0 " + exit 1 +fi + +set -e + +product_name=$1 +input_coverage_file=$2 +output_coverage_file=$3 + +# src/v0.8/ccip/libraries/Internal.sol +# src/v0.8/ccip/libraries/RateLimiter.sol +# src/v0.8/ccip/libraries/USDPriceWith18Decimals.sol +# src/v0.8/ccip/libraries/MerkleMultiProof.sol +# src/v0.8/ccip/libraries/Pool.sol +# excluded because Foundry doesn't support coverage on library files + +# BurnWithFromMintTokenPool is excluded because Forge doesn't seem to +# register coverage, even though it is 100% covered. +exclusion_list_ccip=( + "src/v0.8/ccip/ocr/OCR2Abstract.sol" + "src/v0.8/ccip/libraries/Internal.sol" + "src/v0.8/ccip/libraries/RateLimiter.sol" + "src/v0.8/ccip/libraries/USDPriceWith18Decimals.sol" + "src/v0.8/ccip/libraries/MerkleMultiProof.sol" + "src/v0.8/ccip/libraries/Pool.sol" + "src/v0.8/ConfirmedOwnerWithProposal.sol" + "src/v0.8/tests/MockV3Aggregator.sol" + "src/v0.8/ccip/applications/CCIPClientExample.sol" + "src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol" +) + +exclusion_list_shared=( + "*/shared/*" +) + +exclusion_list_common=( + "*/$product_name/test/*" + "*/vendor/*" +) + +all_exclusions=() + +case "$product_name" in + "ccip") + all_exclusions+=("${exclusion_list_ccip[@]}") + ;; + "shared") + # No product-specific exclusions for shared + ;; + *) + ;; +esac + +all_exclusions+=("${exclusion_list_common[@]}") + +if [ "$product_name" != "shared" ]; then + all_exclusions+=("${exclusion_list_shared[@]}") +fi + +echo "Excluding the following files for product $product_name:" +for exclusion in "${all_exclusions[@]}"; do + echo "$exclusion" +done + +lcov_command="lcov --remove $input_coverage_file -o $output_coverage_file" + +for exclusion in "${all_exclusions[@]}"; do + lcov_command+=" \"$exclusion\"" +done + +lcov_command+=" --rc lcov_branch_coverage=1" + +eval $lcov_command From 14dabac529833900c8db70ae25536e578822df93 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Fri, 9 Aug 2024 07:49:06 -0400 Subject: [PATCH 070/432] [TT-1421] Adds Dot Graphs to CI Upload (#13946) * Adds dot graphs to CI upload * Fix load imports * Verified graphs properly uploaded * Default save DOT traces * use Seth v1.1.2, render DOT graphs for failed transactions in job summary * try newer action * use newer action * run with debug * use newer action * try one more thing with GIthub_workspace * newer action version * last try with image generation * do not try to render dot graphs anymore * fix imports * remove on-demand failure * trace only reverted * use new method in all smoke tests --------- Co-authored-by: Bartek Tofel --- .github/workflows/integration-tests.yml | 24 +++++++++++------- .gitignore | 3 ++- .../actions/vrf/common/actions.go | 7 +++--- .../docker/test_env/test_env_builder.go | 11 +++++--- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +-- integration-tests/smoke/automation_test.go | 4 +-- integration-tests/smoke/flux_test.go | 5 ++-- integration-tests/smoke/forwarder_ocr_test.go | 4 +-- .../smoke/forwarders_ocr2_test.go | 4 +-- integration-tests/smoke/keeper_test.go | 4 +-- integration-tests/smoke/ocr2_test.go | 4 +-- integration-tests/smoke/ocr_test.go | 5 ++-- integration-tests/smoke/runlog_test.go | 4 +-- integration-tests/smoke/vrf_test.go | 5 ++-- integration-tests/testconfig/default.toml | 6 ++--- .../universal/log_poller/helpers.go | 5 ++-- integration-tests/utils/seth.go | 25 +++++++++++++++++++ 20 files changed, 86 insertions(+), 46 deletions(-) create mode 100644 integration-tests/utils/seth.go diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 76f397f046..fd5784df8c 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -356,10 +356,11 @@ jobs: cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ inputs.evm-ref || github.sha }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: ${{ matrix.product.name }}-test-logs + artifacts_name: ${{ matrix.product.name }}-test-artifacts artifacts_location: | ./integration-tests/smoke/logs/ ./integration-tests/smoke/db_dumps/ + ./integration-tests/smoke/seth_artifacts/ /tmp/gotest.log publish_check_name: ${{ matrix.product.name }} token: ${{ secrets.GITHUB_TOKEN }} @@ -395,7 +396,7 @@ jobs: - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@70ccaef155381025e411cf7cd1fa5ef8f668ed75 # v2.3.25 eth-smoke-tests-matrix-log-poller: if: ${{ !(contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') || github.event_name == 'workflow_dispatch') || inputs.distinct_run_name != '' }} @@ -470,10 +471,11 @@ jobs: cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ inputs.evm-ref || github.sha }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: ${{ matrix.product.name }}-test-logs + artifacts_name: ${{ matrix.product.name }}-test-artifacts artifacts_location: | ./integration-tests/smoke/logs/ ./integration-tests/smoke/db_dumps/ + ./integration-tests/smoke/seth_artifacts/ /tmp/gotest.log publish_check_name: ${{ matrix.product.name }} token: ${{ secrets.GITHUB_TOKEN }} @@ -509,8 +511,7 @@ jobs: - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@70ccaef155381025e411cf7cd1fa5ef8f668ed75 # v2.3.25 eth-smoke-tests-matrix: if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} @@ -708,10 +709,11 @@ jobs: cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ inputs.evm-ref || github.sha }}${{ matrix.product.tag_suffix }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: ${{ matrix.product.name }}${{ matrix.product.tag_suffix }}-test-logs + artifacts_name: ${{ matrix.product.name }}${{ matrix.product.tag_suffix }}-test-artifacts artifacts_location: | ./integration-tests/smoke/logs/ ./integration-tests/smoke/db_dumps/ + ./integration-tests/smoke/seth_artifacts/ /tmp/gotest.log publish_check_name: ${{ matrix.product.name }} token: ${{ secrets.GITHUB_TOKEN }} @@ -778,7 +780,7 @@ jobs: - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@70ccaef155381025e411cf7cd1fa5ef8f668ed75 # v2.3.25 with: test_directories: ./integration-tests/smoke/ @@ -958,9 +960,11 @@ jobs: cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ steps.get_latest_version.outputs.latest_version }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: node-migration-test-logs + artifacts_name: node-migration-test-artifacts artifacts_location: | ./integration-tests/migration/logs + ./integration-tests/migration/db_dumps + ./integration-tests/migration/seth_artifacts /tmp/gotest.log publish_check_name: Node Migration Test Results token: ${{ secrets.GITHUB_TOKEN }} @@ -1283,9 +1287,11 @@ jobs: cache_key_id: core-solana-e2e-${{ env.MOD_CACHE_VERSION }} token: ${{ secrets.GITHUB_TOKEN }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: solana-test-logs + artifacts_name: solana-test-artifacts artifacts_location: | ./integration-tests/smoke/logs + ./integration-tests/smoke/db_dumps + ./integration-tests/smoke/seth_artifacts /tmp/gotest.log QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} diff --git a/.gitignore b/.gitignore index 10636f88d8..07dc8baa13 100644 --- a/.gitignore +++ b/.gitignore @@ -85,6 +85,7 @@ MacOSX* *report.xml *report.json *.out +dot_graphs/ contracts/yarn.lock @@ -101,7 +102,7 @@ tools/flakeytests/coverage.txt # Runtime test configuration that might contain secrets override*.toml -# Pythin venv +# Python venv .venv/ ocr_soak_report.csv diff --git a/integration-tests/actions/vrf/common/actions.go b/integration-tests/actions/vrf/common/actions.go index 5697a26176..e1bda549e7 100644 --- a/integration-tests/actions/vrf/common/actions.go +++ b/integration-tests/actions/vrf/common/actions.go @@ -10,6 +10,8 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/integration-tests/utils" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/go-resty/resty/v2" @@ -19,7 +21,6 @@ import ( ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" @@ -367,7 +368,7 @@ func BuildNewCLEnvForVRF(l zerolog.Logger, t *testing.T, envConfig VRFEnvConfig, if err != nil { return nil, nil, fmt.Errorf("%s, err: %w", "error getting first evm network", err) } - sethClient, err := seth_utils.GetChainClient(envConfig.TestConfig, *evmNetwork) + sethClient, err := utils.TestAwareSethClient(t, envConfig.TestConfig, evmNetwork) if err != nil { return nil, nil, fmt.Errorf("%s, err: %w", "error getting seth client", err) } @@ -403,7 +404,7 @@ func LoadExistingCLEnvForVRF( if err != nil { return nil, nil, err } - sethClient, err := seth_utils.GetChainClient(envConfig.TestConfig, *evmNetwork) + sethClient, err := utils.TestAwareSethClient(t, envConfig.TestConfig, evmNetwork) if err != nil { return nil, nil, err } diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go index fbd4a7e870..1ab577bf54 100644 --- a/integration-tests/docker/test_env/test_env_builder.go +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -11,9 +11,10 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" - "go.uber.org/zap/zapcore" + "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" @@ -21,10 +22,10 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/logstream" "github.com/smartcontractkit/chainlink-testing-framework/networks" "github.com/smartcontractkit/chainlink-testing-framework/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/testsummary" "github.com/smartcontractkit/chainlink-testing-framework/utils/osutil" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" ) type CleanUpType string @@ -347,6 +348,10 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { } b.l.Info().Msg("Finished dumping state of all Postgres DBs used by Chainlink Nodes") } + + if b.testConfig.GetSethConfig() != nil && ((b.t.Failed() && slices.Contains(b.testConfig.GetSethConfig().TraceOutputs, seth.TraceOutput_DOT) && b.testConfig.GetSethConfig().TracingLevel != seth.TracingLevel_None) || (!b.t.Failed() && slices.Contains(b.testConfig.GetSethConfig().TraceOutputs, seth.TraceOutput_DOT) && b.testConfig.GetSethConfig().TracingLevel == seth.TracingLevel_All)) { + _ = testsummary.AddEntry(b.t.Name(), "dot_graphs", "true") + } }) } else { b.l.Warn().Msg("LogStream won't be cleaned up, because either test instance is not set or cleanup type is set to none") diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 1ebda7f521..a7783f7daa 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -34,7 +34,7 @@ require ( github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/smartcontractkit/seth v1.1.1 + github.com/smartcontractkit/seth v1.1.2 github.com/smartcontractkit/wasp v0.4.5 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.9.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index a0642a0b92..411b3ddd46 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1514,8 +1514,8 @@ github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1 github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= -github.com/smartcontractkit/seth v1.1.1 h1:6hvexjJD7ek8ht/CLlEwQcH21K2E/WEYwbSRdKInZmM= -github.com/smartcontractkit/seth v1.1.1/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk= +github.com/smartcontractkit/seth v1.1.2 h1:98v9VUFUpNhU7UofeF/bGyUIVv9jnt+JlIE+I8mhX2c= +github.com/smartcontractkit/seth v1.1.2/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index bd47a97f48..4a15b97abf 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -21,7 +21,7 @@ require ( github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/smartcontractkit/seth v1.1.1 + github.com/smartcontractkit/seth v1.1.2 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 github.com/smartcontractkit/wasp v0.4.7 github.com/stretchr/testify v1.9.0 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 7789b94944..625da73ba0 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1496,8 +1496,8 @@ github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1 github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= -github.com/smartcontractkit/seth v1.1.1 h1:6hvexjJD7ek8ht/CLlEwQcH21K2E/WEYwbSRdKInZmM= -github.com/smartcontractkit/seth v1.1.1/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk= +github.com/smartcontractkit/seth v1.1.2 h1:98v9VUFUpNhU7UofeF/bGyUIVv9jnt+JlIE+I8mhX2c= +github.com/smartcontractkit/seth v1.1.2/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 92b25dfd52..39a9f75492 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -12,7 +12,7 @@ import ( "testing" "time" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -1427,7 +1427,7 @@ func setupAutomationTestDocker( evmNetwork, err := env.GetFirstEvmNetwork() require.NoError(t, err, "Error getting first evm network") - sethClient, err := seth_utils.GetChainClient(automationTestConfig, *evmNetwork) + sethClient, err := utils.TestAwareSethClient(t, automationTestConfig, evmNetwork) require.NoError(t, err, "Error getting seth client") err = actions.FundChainlinkNodesFromRootAddress(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs()), big.NewFloat(*automationTestConfig.GetCommonConfig().ChainlinkNodeFunding)) diff --git a/integration-tests/smoke/flux_test.go b/integration-tests/smoke/flux_test.go index d8773690b2..d66cdbd284 100644 --- a/integration-tests/smoke/flux_test.go +++ b/integration-tests/smoke/flux_test.go @@ -8,12 +8,13 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/integration-tests/utils" + "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-testing-framework/logging" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" @@ -49,7 +50,7 @@ func TestFluxBasic(t *testing.T) { evmNetwork, err := env.GetFirstEvmNetwork() require.NoError(t, err, "Error getting first evm network") - sethClient, err := seth_utils.GetChainClient(config, *evmNetwork) + sethClient, err := utils.TestAwareSethClient(t, config, evmNetwork) require.NoError(t, err, "Error getting seth client") adapterUUID := uuid.NewString() diff --git a/integration-tests/smoke/forwarder_ocr_test.go b/integration-tests/smoke/forwarder_ocr_test.go index a249775dc6..1eff96cb7a 100644 --- a/integration-tests/smoke/forwarder_ocr_test.go +++ b/integration-tests/smoke/forwarder_ocr_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" @@ -49,7 +49,7 @@ func TestForwarderOCRBasic(t *testing.T) { evmNetwork, err := env.GetFirstEvmNetwork() require.NoError(t, err, "Error getting first evm network") - sethClient, err := seth_utils.GetChainClient(config, *evmNetwork) + sethClient, err := utils.TestAwareSethClient(t, config, evmNetwork) require.NoError(t, err, "Error getting seth client") err = actions.FundChainlinkNodesFromRootAddress(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs()), big.NewFloat(*config.Common.ChainlinkNodeFunding)) diff --git a/integration-tests/smoke/forwarders_ocr2_test.go b/integration-tests/smoke/forwarders_ocr2_test.go index 863b36e4ed..e3cced94fd 100644 --- a/integration-tests/smoke/forwarders_ocr2_test.go +++ b/integration-tests/smoke/forwarders_ocr2_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" @@ -50,7 +50,7 @@ func TestForwarderOCR2Basic(t *testing.T) { evmNetwork, err := env.GetFirstEvmNetwork() require.NoError(t, err, "Error getting first evm network") - sethClient, err := seth_utils.GetChainClient(config, *evmNetwork) + sethClient, err := utils.TestAwareSethClient(t, config, evmNetwork) require.NoError(t, err, "Error getting seth client") err = actions.FundChainlinkNodesFromRootAddress(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs()), big.NewFloat(*config.Common.ChainlinkNodeFunding)) diff --git a/integration-tests/smoke/keeper_test.go b/integration-tests/smoke/keeper_test.go index 4ff1c90bd1..b6118025a1 100644 --- a/integration-tests/smoke/keeper_test.go +++ b/integration-tests/smoke/keeper_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/ethereum/go-ethereum/common" "github.com/onsi/gomega" @@ -1243,7 +1243,7 @@ func setupKeeperTest(l zerolog.Logger, t *testing.T, config *tc.TestConfig) ( evmNetwork, err := env.GetFirstEvmNetwork() require.NoError(t, err, "Error getting first evm network") - sethClient, err := seth_utils.GetChainClient(config, *evmNetwork) + sethClient, err := utils.TestAwareSethClient(t, config, evmNetwork) require.NoError(t, err, "Error getting seth client") err = actions.FundChainlinkNodesFromRootAddress(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs()), big.NewFloat(*config.Common.ChainlinkNodeFunding)) diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index 56a95c50bd..90afff94cf 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" @@ -163,7 +163,7 @@ func prepareORCv2SmokeTestEnv(t *testing.T, testData ocr2test, l zerolog.Logger, evmNetwork, err := testEnv.GetFirstEvmNetwork() require.NoError(t, err, "Error getting first evm network") - sethClient, err := seth_utils.GetChainClient(config, *evmNetwork) + sethClient, err := utils.TestAwareSethClient(t, config, evmNetwork) require.NoError(t, err, "Error getting seth client") nodeClients := testEnv.ClCluster.NodeAPIs() diff --git a/integration-tests/smoke/ocr_test.go b/integration-tests/smoke/ocr_test.go index 0b4ac3de30..8d17a02071 100644 --- a/integration-tests/smoke/ocr_test.go +++ b/integration-tests/smoke/ocr_test.go @@ -5,8 +5,6 @@ import ( "testing" "time" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" - "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" "github.com/smartcontractkit/seth" @@ -19,6 +17,7 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/utils" ) const ( @@ -99,7 +98,7 @@ func prepareORCv1SmokeTestEnv(t *testing.T, l zerolog.Logger, firstRoundResult i evmNetwork, err := env.GetFirstEvmNetwork() require.NoError(t, err, "Error getting first evm network") - sethClient, err := seth_utils.GetChainClient(config, *evmNetwork) + sethClient, err := utils.TestAwareSethClient(t, config, evmNetwork) require.NoError(t, err, "Error getting seth client") nodeClients := env.ClCluster.NodeAPIs() diff --git a/integration-tests/smoke/runlog_test.go b/integration-tests/smoke/runlog_test.go index 515d9dea33..1558b44732 100644 --- a/integration-tests/smoke/runlog_test.go +++ b/integration-tests/smoke/runlog_test.go @@ -7,7 +7,7 @@ import ( "strings" "testing" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/google/uuid" "github.com/onsi/gomega" @@ -47,7 +47,7 @@ func TestRunLogBasic(t *testing.T) { evmNetwork, err := env.GetFirstEvmNetwork() require.NoError(t, err, "Error getting first evm network") - sethClient, err := seth_utils.GetChainClient(config, *evmNetwork) + sethClient, err := utils.TestAwareSethClient(t, config, evmNetwork) require.NoError(t, err, "Error getting seth client") err = actions.FundChainlinkNodesFromRootAddress(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs()), big.NewFloat(*config.Common.ChainlinkNodeFunding)) diff --git a/integration-tests/smoke/vrf_test.go b/integration-tests/smoke/vrf_test.go index 04e760796d..53e74ac7ff 100644 --- a/integration-tests/smoke/vrf_test.go +++ b/integration-tests/smoke/vrf_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/integration-tests/utils" + "github.com/google/uuid" "github.com/onsi/gomega" "github.com/rs/zerolog" @@ -13,7 +15,6 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-testing-framework/logging" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" @@ -204,7 +205,7 @@ func prepareVRFtestEnv(t *testing.T, l zerolog.Logger) (*test_env.CLClusterTestE evmNetwork, err := env.GetFirstEvmNetwork() require.NoError(t, err, "Error getting first evm network") - sethClient, err := seth_utils.GetChainClient(config, *evmNetwork) + sethClient, err := utils.TestAwareSethClient(t, config, evmNetwork) require.NoError(t, err, "Error getting seth client") err = actions.FundChainlinkNodesFromRootAddress(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs()), big.NewFloat(*config.Common.ChainlinkNodeFunding)) diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index 0d0bb14da9..9609c6175d 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -134,13 +134,13 @@ FeeCapDefault = '200 gwei' [Seth] # controls which transactions are decoded/traced. Possbile values are: none, all, reverted (default). # if transaction level doesn't match, then calling Decode() does nothing. It's advised to keep it set -# to 'reverted' to limit noise. If you combine it with 'trace_to_json' it will save all possible data -# in JSON files for reverted transactions. +# to 'reverted' to limit noise. tracing_level = "reverted" -# saves each decoding/tracing results to JSON files; what exactly is saved depends on what we +# saves each decoding/tracing results to DOT files; what exactly is saved depends on what we # were able te decode, we try to save maximum information possible. It can either be: # just tx hash, decoded transaction or call trace. Which transactions traces are saved depends # on 'tracing_level'. +trace_outputs = ["dot", "console"] # number of addresses to be generated and runtime, if set to 0, no addresses will be generated # each generated address will receive a proportion of native tokens from root private key's balance diff --git a/integration-tests/universal/log_poller/helpers.go b/integration-tests/universal/log_poller/helpers.go index daa4784ec1..bacb5db6ed 100644 --- a/integration-tests/universal/log_poller/helpers.go +++ b/integration-tests/universal/log_poller/helpers.go @@ -13,6 +13,8 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/integration-tests/utils" + "github.com/jmoiron/sqlx" "github.com/smartcontractkit/seth" "github.com/smartcontractkit/wasp" @@ -30,7 +32,6 @@ import ( ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/networks" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" @@ -1059,7 +1060,7 @@ func SetupLogPollerTestDocker( evmNetwork, err := env.GetFirstEvmNetwork() require.NoError(t, err, "Error getting first evm network") - chainClient, err := seth_utils.GetChainClient(testConfig, *evmNetwork) + chainClient, err := utils.TestAwareSethClient(t, testConfig, evmNetwork) require.NoError(t, err, "Error getting seth client") err = actions.FundChainlinkNodesFromRootAddress(l, chainClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs()), big.NewFloat(chainlinkNodeFunding)) diff --git a/integration-tests/utils/seth.go b/integration-tests/utils/seth.go new file mode 100644 index 0000000000..237be1a508 --- /dev/null +++ b/integration-tests/utils/seth.go @@ -0,0 +1,25 @@ +package utils + +import ( + "fmt" + "testing" + + pkg_seth "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" +) + +// DynamicArtifactDirConfigFn returns a function that sets Seth's artifacts directory to a unique directory for the test +func DynamicArtifactDirConfigFn(t *testing.T) func(*pkg_seth.Config) error { + return func(cfg *pkg_seth.Config) error { + cfg.ArtifactsDir = fmt.Sprintf("seth_artifacts/%s", t.Name()) + return nil + } +} + +// TestAwareSethClient returns a Seth client with the artifacts directory set to a unique directory for the test +func TestAwareSethClient(t *testing.T, sethConfig ctf_config.SethConfig, evmNetwork *blockchain.EVMNetwork) (*pkg_seth.Client, error) { + return seth_utils.GetChainClientWithConfigFunction(sethConfig, *evmNetwork, DynamicArtifactDirConfigFn(t)) +} From 7a561304a4650ee60ee96cf0b601266a1461488d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Fri, 9 Aug 2024 21:27:41 +0900 Subject: [PATCH 071/432] core/scripts/keystone improvements (#14075) * scripts: keystone: Use Hostname() over Host Host can contain host:port which will then result in invalid bootstrap addresses (host:port:port) * scripts: keystone: Add command to deploy workflow spec * scripts: keystone: oracle spec used the wrong provider type * scripts: keystone: Add utility to delete a workflow spec * Simplify the changes to scripts a bit * scripts: keystone: Allow overriding PublicKeys.json/NodeList.txt location --- core/scripts/keystone/.gitignore | 1 + core/scripts/keystone/main.go | 2 + .../keystone/src/01_deploy_contracts_cmd.go | 49 ++++++++---- .../keystone/src/02_deploy_jobspecs_cmd.go | 29 ++++++-- .../src/03_gen_crib_cluster_overrides_cmd.go | 29 ++++++-- .../03_gen_crib_cluster_overrides_cmd_test.go | 2 +- .../keystone/src/04_delete_ocr3_jobs_cmd.go | 30 +++++++- .../keystone/src/06_deploy_workflows_cmd.go | 71 ++++++++++++++++++ .../keystone/src/07_delete_workflows_cmd.go | 74 +++++++++++++++++++ core/scripts/keystone/src/88_gen_jobspecs.go | 4 +- .../keystone/src/88_gen_ocr3_config.go | 4 +- .../keystone/src/88_gen_ocr3_config_test.go | 2 +- core/scripts/keystone/src/99_fetch_keys.go | 11 +-- core/scripts/keystone/src/99_files.go | 4 +- .../__snapshots__/88_gen_jobspecs_test.snap | 8 +- core/scripts/keystone/templates/oracle.toml | 2 +- 16 files changed, 269 insertions(+), 53 deletions(-) create mode 100644 core/scripts/keystone/src/06_deploy_workflows_cmd.go create mode 100644 core/scripts/keystone/src/07_delete_workflows_cmd.go diff --git a/core/scripts/keystone/.gitignore b/core/scripts/keystone/.gitignore index 4af4a42a01..92bf9aabc5 100644 --- a/core/scripts/keystone/.gitignore +++ b/core/scripts/keystone/.gitignore @@ -3,3 +3,4 @@ !*-sample.sh keystone .cache/ +artefacts/ diff --git a/core/scripts/keystone/main.go b/core/scripts/keystone/main.go index 571623578a..3486830ca3 100644 --- a/core/scripts/keystone/main.go +++ b/core/scripts/keystone/main.go @@ -20,6 +20,8 @@ func main() { src.NewGenerateCribClusterOverridesCommand(), src.NewDeleteJobsCommand(), src.NewDeployAndInitializeCapabilitiesRegistryCommand(), + src.NewDeployWorkflowsCommand(), + src.NewDeleteWorkflowsCommand(), } commandsList := func(commands []command) string { diff --git a/core/scripts/keystone/src/01_deploy_contracts_cmd.go b/core/scripts/keystone/src/01_deploy_contracts_cmd.go index 2ca60bdfaf..b304973795 100644 --- a/core/scripts/keystone/src/01_deploy_contracts_cmd.go +++ b/core/scripts/keystone/src/01_deploy_contracts_cmd.go @@ -52,8 +52,12 @@ func (g *deployContracts) Run(args []string) { skipFunding := fs.Bool("skipfunding", false, "skip funding the transmitters") onlySetConfig := fs.Bool("onlysetconfig", false, "set the config on the OCR3 contract without deploying the contracts or funding transmitters") dryRun := fs.Bool("dryrun", false, "dry run, don't actually deploy the contracts and do not fund transmitters") + publicKeys := fs.String("publickeys", "", "Custom public keys json location") + nodeList := fs.String("nodes", "", "Custom node list location") + artefactsDir := fs.String("artefacts", "", "Custom artefacts directory location") err := fs.Parse(args) + if err != nil || *ocrConfigFile == "" || ocrConfigFile == nil || *ethUrl == "" || ethUrl == nil || @@ -63,11 +67,21 @@ func (g *deployContracts) Run(args []string) { os.Exit(1) } + if *artefactsDir == "" { + *artefactsDir = defaultArtefactsDir + } + if *publicKeys == "" { + *publicKeys = defaultPublicKeys + } + if *nodeList == "" { + *nodeList = defaultNodeList + } + os.Setenv("ETH_URL", *ethUrl) os.Setenv("ETH_CHAIN_ID", fmt.Sprintf("%d", *chainID)) os.Setenv("ACCOUNT_KEY", *accountKey) - deploy(*ocrConfigFile, *skipFunding, *dryRun, *onlySetConfig) + deploy(*nodeList, *publicKeys, *ocrConfigFile, *skipFunding, *dryRun, *onlySetConfig, *artefactsDir) } // deploy does the following: @@ -77,16 +91,20 @@ func (g *deployContracts) Run(args []string) { // 4. Writes the deployed contract addresses to a file // 5. Funds the transmitters func deploy( + nodeList string, + publicKeys string, configFile string, skipFunding bool, dryRun bool, onlySetConfig bool, + artefacts string, ) { env := helpers.SetupEnv(false) ocrConfig := generateOCR3Config( + nodeList, configFile, env.ChainID, - ".cache/PublicKeys.json", + publicKeys, ) if dryRun { @@ -96,11 +114,11 @@ func deploy( if onlySetConfig { fmt.Println("Skipping deployment of contracts and skipping funding transmitters, only setting config") - setOCR3Config(env, ocrConfig) + setOCR3Config(env, ocrConfig, artefacts) return } - if ContractsAlreadyDeployed() { + if ContractsAlreadyDeployed(artefacts) { fmt.Println("Contracts already deployed") return } @@ -118,10 +136,10 @@ func deploy( jsonBytes, err := json.Marshal(contracts) PanicErr(err) - err = os.WriteFile(DeployedContractsFilePath(), jsonBytes, 0600) + err = os.WriteFile(DeployedContractsFilePath(artefacts), jsonBytes, 0600) PanicErr(err) - setOCR3Config(env, ocrConfig) + setOCR3Config(env, ocrConfig, artefacts) if skipFunding { fmt.Println("Skipping funding transmitters") @@ -139,8 +157,9 @@ func deploy( func setOCR3Config( env helpers.Environment, ocrConfig orc2drOracleConfig, + artefacts string, ) { - loadedContracts, err := LoadDeployedContracts() + loadedContracts, err := LoadDeployedContracts(artefacts) PanicErr(err) ocrContract, err := ocr3_capability.NewOCR3Capability(loadedContracts.OCRContract, env.Ec) @@ -161,16 +180,16 @@ func setOCR3Config( loadedContracts.SetConfigTxBlock = receipt.BlockNumber.Uint64() jsonBytes, err := json.Marshal(loadedContracts) PanicErr(err) - err = os.WriteFile(DeployedContractsFilePath(), jsonBytes, 0600) + err = os.WriteFile(DeployedContractsFilePath(artefacts), jsonBytes, 0600) PanicErr(err) } -func LoadDeployedContracts() (deployedContracts, error) { - if !ContractsAlreadyDeployed() { +func LoadDeployedContracts(artefacts string) (deployedContracts, error) { + if !ContractsAlreadyDeployed(artefacts) { return deployedContracts{}, fmt.Errorf("no deployed contracts found, run deploy first") } - jsonBytes, err := os.ReadFile(DeployedContractsFilePath()) + jsonBytes, err := os.ReadFile(DeployedContractsFilePath(artefacts)) if err != nil { return deployedContracts{}, err } @@ -180,13 +199,13 @@ func LoadDeployedContracts() (deployedContracts, error) { return contracts, err } -func ContractsAlreadyDeployed() bool { - _, err := os.Stat(DeployedContractsFilePath()) +func ContractsAlreadyDeployed(artefacts string) bool { + _, err := os.Stat(DeployedContractsFilePath(artefacts)) return err == nil } -func DeployedContractsFilePath() string { - return filepath.Join(artefactsDir, deployedContractsJSON) +func DeployedContractsFilePath(artefacts string) string { + return filepath.Join(artefacts, deployedContractsJSON) } func DeployForwarder(e helpers.Environment) *forwarder.KeystoneForwarder { diff --git a/core/scripts/keystone/src/02_deploy_jobspecs_cmd.go b/core/scripts/keystone/src/02_deploy_jobspecs_cmd.go index 5918650cf8..275943d638 100644 --- a/core/scripts/keystone/src/02_deploy_jobspecs_cmd.go +++ b/core/scripts/keystone/src/02_deploy_jobspecs_cmd.go @@ -16,8 +16,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/cmd" ) -type deployJobSpecs struct { -} +type deployJobSpecs struct{} func NewDeployJobSpecsCommand() *deployJobSpecs { return &deployJobSpecs{} @@ -32,6 +31,11 @@ func (g *deployJobSpecs) Run(args []string) { chainID := fs.Int64("chainid", 11155111, "chain id") p2pPort := fs.Int64("p2pport", 6690, "p2p port") onlyReplay := fs.Bool("onlyreplay", false, "only replay the block from the OCR3 contract setConfig transaction") + templatesLocation := fs.String("templates", "", "Custom templates location") + nodeList := fs.String("nodes", "", "Custom node list location") + publicKeys := fs.String("publickeys", "", "Custom public keys json location") + artefactsDir := fs.String("artefacts", "", "Custom artefacts directory location") + err := fs.Parse(args) if err != nil || chainID == nil || *chainID == 0 || p2pPort == nil || *p2pPort == 0 || onlyReplay == nil { fs.Usage() @@ -43,12 +47,27 @@ func (g *deployJobSpecs) Run(args []string) { fmt.Println("Deploying OCR3 job specs") } - nodes := downloadNodeAPICredentialsDefault() - deployedContracts, err := LoadDeployedContracts() + if *artefactsDir == "" { + *artefactsDir = defaultArtefactsDir + } + if *publicKeys == "" { + *publicKeys = defaultPublicKeys + } + if *nodeList == "" { + *nodeList = defaultNodeList + } + if *templatesLocation == "" { + *templatesLocation = "templates" + } + + nodes := downloadNodeAPICredentials(*nodeList) + deployedContracts, err := LoadDeployedContracts(*artefactsDir) PanicErr(err) jobspecs := genSpecs( - ".cache/PublicKeys.json", ".cache/NodeList.txt", "templates", + *publicKeys, + *nodeList, + *templatesLocation, *chainID, *p2pPort, deployedContracts.OCRContract.Hex(), ) flattenedSpecs := []hostSpec{jobspecs.bootstrap} diff --git a/core/scripts/keystone/src/03_gen_crib_cluster_overrides_cmd.go b/core/scripts/keystone/src/03_gen_crib_cluster_overrides_cmd.go index cb3acf903b..6b98951459 100644 --- a/core/scripts/keystone/src/03_gen_crib_cluster_overrides_cmd.go +++ b/core/scripts/keystone/src/03_gen_crib_cluster_overrides_cmd.go @@ -9,8 +9,7 @@ import ( helpers "github.com/smartcontractkit/chainlink/core/scripts/common" ) -type generateCribClusterOverrides struct { -} +type generateCribClusterOverrides struct{} func NewGenerateCribClusterOverridesCommand() *generateCribClusterOverrides { return &generateCribClusterOverrides{} @@ -24,25 +23,39 @@ func (g *generateCribClusterOverrides) Run(args []string) { fs := flag.NewFlagSet(g.Name(), flag.ContinueOnError) chainID := fs.Int64("chainid", 11155111, "chain id") outputPath := fs.String("outpath", "../crib", "the path to output the generated overrides") + publicKeys := fs.String("publickeys", "", "Custom public keys json location") + nodeList := fs.String("nodes", "", "Custom node list location") + artefactsDir := fs.String("artefacts", "", "Custom artefacts directory location") - deployedContracts, err := LoadDeployedContracts() - helpers.PanicErr(err) templatesDir := "templates" - err = fs.Parse(args) + err := fs.Parse(args) if err != nil || outputPath == nil || *outputPath == "" || chainID == nil || *chainID == 0 { fs.Usage() os.Exit(1) } - lines := generateCribConfig(".cache/PublicKeys.json", chainID, templatesDir, deployedContracts.ForwarderContract.Hex()) + if *artefactsDir == "" { + *artefactsDir = defaultArtefactsDir + } + if *publicKeys == "" { + *publicKeys = defaultPublicKeys + } + if *nodeList == "" { + *nodeList = defaultNodeList + } + + deployedContracts, err := LoadDeployedContracts(*artefactsDir) + helpers.PanicErr(err) + + lines := generateCribConfig(*nodeList, *publicKeys, chainID, templatesDir, deployedContracts.ForwarderContract.Hex()) cribOverridesStr := strings.Join(lines, "\n") err = os.WriteFile(filepath.Join(*outputPath, "crib-cluster-overrides.yaml"), []byte(cribOverridesStr), 0600) helpers.PanicErr(err) } -func generateCribConfig(pubKeysPath string, chainID *int64, templatesDir string, forwarderAddress string) []string { - nca := downloadNodePubKeys(*chainID, pubKeysPath) +func generateCribConfig(nodeList string, pubKeysPath string, chainID *int64, templatesDir string, forwarderAddress string) []string { + nca := downloadNodePubKeys(nodeList, *chainID, pubKeysPath) nodeAddresses := []string{} for _, node := range nca[1:] { diff --git a/core/scripts/keystone/src/03_gen_crib_cluster_overrides_cmd_test.go b/core/scripts/keystone/src/03_gen_crib_cluster_overrides_cmd_test.go index 722b01e91c..53d43c2342 100644 --- a/core/scripts/keystone/src/03_gen_crib_cluster_overrides_cmd_test.go +++ b/core/scripts/keystone/src/03_gen_crib_cluster_overrides_cmd_test.go @@ -13,7 +13,7 @@ func TestGenerateCribConfig(t *testing.T) { forwarderAddress := "0x1234567890abcdef" publicKeysPath := "./testdata/PublicKeys.json" - lines := generateCribConfig(publicKeysPath, &chainID, templatesDir, forwarderAddress) + lines := generateCribConfig(defaultNodeList, publicKeysPath, &chainID, templatesDir, forwarderAddress) snaps.MatchSnapshot(t, strings.Join(lines, "\n")) } diff --git a/core/scripts/keystone/src/04_delete_ocr3_jobs_cmd.go b/core/scripts/keystone/src/04_delete_ocr3_jobs_cmd.go index 2ebed000ed..136691962d 100644 --- a/core/scripts/keystone/src/04_delete_ocr3_jobs_cmd.go +++ b/core/scripts/keystone/src/04_delete_ocr3_jobs_cmd.go @@ -5,14 +5,14 @@ import ( "encoding/json" "flag" "fmt" + "os" "github.com/urfave/cli" helpers "github.com/smartcontractkit/chainlink/core/scripts/common" ) -type deleteJobs struct { -} +type deleteJobs struct{} type OCRSpec struct { ContractID string @@ -22,11 +22,16 @@ type BootSpec struct { ContractID string } +type WorkflowSpec struct { + WorkflowID string +} + type JobSpec struct { Id string Name string BootstrapSpec BootSpec OffChainReporting2OracleSpec OCRSpec + WorkflowSpec WorkflowSpec } func NewDeleteJobsCommand() *deleteJobs { @@ -38,9 +43,26 @@ func (g *deleteJobs) Name() string { } func (g *deleteJobs) Run(args []string) { - deployedContracts, err := LoadDeployedContracts() + fs := flag.NewFlagSet(g.Name(), flag.ContinueOnError) + nodeList := fs.String("nodes", "", "Custom node list location") + artefactsDir := fs.String("artefacts", "", "Custom artefacts directory location") + + err := fs.Parse(args) + if err != nil { + fs.Usage() + os.Exit(1) + } + + if *artefactsDir == "" { + *artefactsDir = defaultArtefactsDir + } + if *nodeList == "" { + *nodeList = defaultNodeList + } + + deployedContracts, err := LoadDeployedContracts(*artefactsDir) helpers.PanicErr(err) - nodes := downloadNodeAPICredentialsDefault() + nodes := downloadNodeAPICredentials(*nodeList) for _, node := range nodes { output := &bytes.Buffer{} diff --git a/core/scripts/keystone/src/06_deploy_workflows_cmd.go b/core/scripts/keystone/src/06_deploy_workflows_cmd.go new file mode 100644 index 0000000000..0ca8e5d4a7 --- /dev/null +++ b/core/scripts/keystone/src/06_deploy_workflows_cmd.go @@ -0,0 +1,71 @@ +package src + +import ( + "bytes" + "errors" + "flag" + "fmt" + "os" + + "github.com/urfave/cli" + + helpers "github.com/smartcontractkit/chainlink/core/scripts/common" +) + +type deployWorkflows struct{} + +func NewDeployWorkflowsCommand() *deployWorkflows { + return &deployWorkflows{} +} + +func (g *deployWorkflows) Name() string { + return "deploy-workflows" +} + +func (g *deployWorkflows) Run(args []string) { + fs := flag.NewFlagSet(g.Name(), flag.ContinueOnError) + workflowFile := fs.String("workflow", "workflow.yml", "path to workflow file") + nodeList := fs.String("nodes", "", "Custom node list location") + err := fs.Parse(args) + if err != nil || workflowFile == nil || *workflowFile == "" { + fs.Usage() + os.Exit(1) + } + if *nodeList == "" { + *nodeList = defaultNodeList + } + fmt.Println("Deploying workflows") + + // use a separate list + nodes := downloadNodeAPICredentials(*nodeList) + + if _, err = os.Stat(*workflowFile); err != nil { + PanicErr(errors.New("toml file does not exist")) + } + + for i, n := range nodes { + if i == 0 { + continue // skip bootstrap node + } + output := &bytes.Buffer{} + client, app := newApp(n, output) + fmt.Println("Logging in:", n.url) + loginFs := flag.NewFlagSet("test", flag.ContinueOnError) + loginFs.Bool("bypass-version-check", true, "") + loginCtx := cli.NewContext(app, loginFs, nil) + err := client.RemoteLogin(loginCtx) + helpers.PanicErr(err) + output.Reset() + + fmt.Printf("Deploying workflow\n... \n") + fs := flag.NewFlagSet("test", flag.ExitOnError) + err = fs.Parse([]string{*workflowFile}) + + helpers.PanicErr(err) + err = client.CreateJob(cli.NewContext(app, fs, nil)) + if err != nil { + fmt.Println("Failed to deploy workflow:", "Error:", err) + } + output.Reset() + } +} diff --git a/core/scripts/keystone/src/07_delete_workflows_cmd.go b/core/scripts/keystone/src/07_delete_workflows_cmd.go new file mode 100644 index 0000000000..cccedaf9e7 --- /dev/null +++ b/core/scripts/keystone/src/07_delete_workflows_cmd.go @@ -0,0 +1,74 @@ +package src + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "os" + + "github.com/urfave/cli" + + helpers "github.com/smartcontractkit/chainlink/core/scripts/common" +) + +type deleteWorkflows struct{} + +func NewDeleteWorkflowsCommand() *deleteWorkflows { + return &deleteWorkflows{} +} + +func (g *deleteWorkflows) Name() string { + return "delete-workflows" +} + +func (g *deleteWorkflows) Run(args []string) { + fs := flag.NewFlagSet(g.Name(), flag.ExitOnError) + nodeList := fs.String("nodes", "", "Custom node list location") + + err := fs.Parse(args) + if err != nil { + fs.Usage() + os.Exit(1) + } + + if *nodeList == "" { + *nodeList = defaultNodeList + } + + nodes := downloadNodeAPICredentials(*nodeList) + + for _, node := range nodes { + output := &bytes.Buffer{} + client, app := newApp(node, output) + + fmt.Println("Logging in:", node.url) + loginFs := flag.NewFlagSet("test", flag.ContinueOnError) + loginFs.Bool("bypass-version-check", true, "") + loginCtx := cli.NewContext(app, loginFs, nil) + err := client.RemoteLogin(loginCtx) + helpers.PanicErr(err) + output.Reset() + + fileFs := flag.NewFlagSet("test", flag.ExitOnError) + err = client.ListJobs(cli.NewContext(app, fileFs, nil)) + helpers.PanicErr(err) + + var parsed []JobSpec + err = json.Unmarshal(output.Bytes(), &parsed) + helpers.PanicErr(err) + + for _, jobSpec := range parsed { + if jobSpec.WorkflowSpec.WorkflowID != "" { + fmt.Println("Deleting workflow job ID:", jobSpec.Id, "name:", jobSpec.Name) + set := flag.NewFlagSet("test", flag.ExitOnError) + err = set.Parse([]string{jobSpec.Id}) + helpers.PanicErr(err) + err = client.DeleteJob(cli.NewContext(app, set, nil)) + helpers.PanicErr(err) + } + } + + output.Reset() + } +} diff --git a/core/scripts/keystone/src/88_gen_jobspecs.go b/core/scripts/keystone/src/88_gen_jobspecs.go index 6a9c911a5f..5f0b9097d2 100644 --- a/core/scripts/keystone/src/88_gen_jobspecs.go +++ b/core/scripts/keystone/src/88_gen_jobspecs.go @@ -34,12 +34,12 @@ func genSpecs( ocrConfigContractAddress string, ) donHostSpec { nodes := downloadNodeAPICredentials(nodeListPath) - nca := downloadNodePubKeys(chainID, pubkeysPath) + nca := downloadNodePubKeys(nodeListPath, chainID, pubkeysPath) bootstrapNode := nca[0] bootstrapSpecLines, err := readLines(filepath.Join(templatesDir, bootstrapSpecTemplate)) helpers.PanicErr(err) - bootHost := nodes[0].url.Host + bootHost := nodes[0].url.Hostname() bootstrapSpecLines = replacePlaceholders( bootstrapSpecLines, chainID, p2pPort, diff --git a/core/scripts/keystone/src/88_gen_ocr3_config.go b/core/scripts/keystone/src/88_gen_ocr3_config.go index fe9241a2bd..1107df57ca 100644 --- a/core/scripts/keystone/src/88_gen_ocr3_config.go +++ b/core/scripts/keystone/src/88_gen_ocr3_config.go @@ -96,10 +96,10 @@ func mustReadConfig(fileName string) (output TopLevelConfigSource) { return mustParseJSON[TopLevelConfigSource](fileName) } -func generateOCR3Config(configFile string, chainID int64, pubKeysPath string) orc2drOracleConfig { +func generateOCR3Config(nodeList string, configFile string, chainID int64, pubKeysPath string) orc2drOracleConfig { topLevelCfg := mustReadConfig(configFile) cfg := topLevelCfg.OracleConfig - nca := downloadNodePubKeys(chainID, pubKeysPath) + nca := downloadNodePubKeys(nodeList, chainID, pubKeysPath) onchainPubKeys := []common.Address{} for _, n := range nca { diff --git a/core/scripts/keystone/src/88_gen_ocr3_config_test.go b/core/scripts/keystone/src/88_gen_ocr3_config_test.go index 185354ec2f..10cdc07b20 100644 --- a/core/scripts/keystone/src/88_gen_ocr3_config_test.go +++ b/core/scripts/keystone/src/88_gen_ocr3_config_test.go @@ -10,7 +10,7 @@ import ( func TestGenerateOCR3Config(t *testing.T) { // Generate OCR3 config - config := generateOCR3Config("./testdata/SampleConfig.json", 11155111, "./testdata/PublicKeys.json") + config := generateOCR3Config(".cache/NodeList.txt", "./testdata/SampleConfig.json", 11155111, "./testdata/PublicKeys.json") matchOffchainConfig := match.Custom("OffchainConfig", func(s any) (any, error) { // coerce the value to a string diff --git a/core/scripts/keystone/src/99_fetch_keys.go b/core/scripts/keystone/src/99_fetch_keys.go index 4fcb6f138a..b115a7bb94 100644 --- a/core/scripts/keystone/src/99_fetch_keys.go +++ b/core/scripts/keystone/src/99_fetch_keys.go @@ -17,14 +17,14 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) -func downloadNodePubKeys(chainID int64, pubKeysPath string) []NodeKeys { +func downloadNodePubKeys(nodeList string, chainID int64, pubKeysPath string) []NodeKeys { // Check if file exists already, and if so, return the keys if _, err := os.Stat(pubKeysPath); err == nil { fmt.Println("Loading existing public keys at:", pubKeysPath) return mustParseJSON[[]NodeKeys](pubKeysPath) } - nodes := downloadNodeAPICredentialsDefault() + nodes := downloadNodeAPICredentials(nodeList) nodesKeys := mustFetchNodesKeys(chainID, nodes) marshalledNodeKeys, err := json.MarshalIndent(nodesKeys, "", " ") @@ -40,13 +40,6 @@ func downloadNodePubKeys(chainID int64, pubKeysPath string) []NodeKeys { return nodesKeys } -// downloadNodeAPICredentialsDefault downloads the node API credentials, or loads them from disk if they already exist -// -// The nodes are sorted by URL. In the case of crib, the bootstrap node is the first node in the list. -func downloadNodeAPICredentialsDefault() []*node { - return downloadNodeAPICredentials(".cache/NodeList.txt") -} - // downloadNodeAPICredentials downloads the node API credentials, or loads them from disk if they already exist // // The nodes are sorted by URL. In the case of crib, the bootstrap node is the first node in the list. diff --git a/core/scripts/keystone/src/99_files.go b/core/scripts/keystone/src/99_files.go index d334b0fd56..08ba12e419 100644 --- a/core/scripts/keystone/src/99_files.go +++ b/core/scripts/keystone/src/99_files.go @@ -11,7 +11,9 @@ import ( ) const ( - artefactsDir = "artefacts" + defaultArtefactsDir = "artefacts" + defaultPublicKeys = ".cache/PublicKeys.json" + defaultNodeList = ".cache/NodeList.txt" deployedContractsJSON = "deployed_contracts.json" bootstrapSpecTemplate = "bootstrap.toml" cribOverrideTemplate = "crib-overrides.yaml" diff --git a/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap b/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap index 1ee7f67894..21e28f3801 100755 --- a/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap +++ b/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap @@ -33,7 +33,7 @@ chainID = "11155111" command = "chainlink-ocr3-capability" ocrVersion = 3 pluginName = "ocr-capability" -providerType = "plugin" +providerType = "ocr3-capability" telemetryType = "plugin" [onchainSigningStrategy] @@ -63,7 +63,7 @@ chainID = "11155111" command = "chainlink-ocr3-capability" ocrVersion = 3 pluginName = "ocr-capability" -providerType = "plugin" +providerType = "ocr3-capability" telemetryType = "plugin" [onchainSigningStrategy] @@ -93,7 +93,7 @@ chainID = "11155111" command = "chainlink-ocr3-capability" ocrVersion = 3 pluginName = "ocr-capability" -providerType = "plugin" +providerType = "ocr3-capability" telemetryType = "plugin" [onchainSigningStrategy] @@ -123,7 +123,7 @@ chainID = "11155111" command = "chainlink-ocr3-capability" ocrVersion = 3 pluginName = "ocr-capability" -providerType = "plugin" +providerType = "ocr3-capability" telemetryType = "plugin" [onchainSigningStrategy] diff --git a/core/scripts/keystone/templates/oracle.toml b/core/scripts/keystone/templates/oracle.toml index f2ff87de92..f5d539873f 100644 --- a/core/scripts/keystone/templates/oracle.toml +++ b/core/scripts/keystone/templates/oracle.toml @@ -17,7 +17,7 @@ chainID = "{{ chain_id }}" command = "chainlink-ocr3-capability" ocrVersion = 3 pluginName = "ocr-capability" -providerType = "plugin" +providerType = "ocr3-capability" telemetryType = "plugin" [onchainSigningStrategy] From cefbb09797249309ac18e4ef81147e30f7c24360 Mon Sep 17 00:00:00 2001 From: Christopher Dimitri Sastropranoto Date: Fri, 9 Aug 2024 19:33:37 +0700 Subject: [PATCH 072/432] KS-391: Capabilities registry reentrancy fix (#13970) * prevent malicious a node operator from taking over another node belonging to another node operator * prevent malicious node operator from becoming the admin for another node operator * prevent reentrancy when setting DON config * update wrappers and add changeset * fix solhint --- .changeset/weak-rabbits-sell.md | 5 ++ contracts/.changeset/tender-comics-check.md | 5 ++ .../v0.8/keystone/CapabilitiesRegistry.sol | 9 ++- .../CapabilitiesRegistry_AddDONTest.t.sol | 73 +++++++++++++++++++ .../mocks/MaliciousConfigurationContract.sol | 47 ++++++++++++ .../capabilities_registry.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 7 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 .changeset/weak-rabbits-sell.md create mode 100644 contracts/.changeset/tender-comics-check.md create mode 100644 contracts/src/v0.8/keystone/test/mocks/MaliciousConfigurationContract.sol diff --git a/.changeset/weak-rabbits-sell.md b/.changeset/weak-rabbits-sell.md new file mode 100644 index 0000000000..3f0785d3d5 --- /dev/null +++ b/.changeset/weak-rabbits-sell.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal prevent reentrancy when configuring DON in Capabilities Registry diff --git a/contracts/.changeset/tender-comics-check.md b/contracts/.changeset/tender-comics-check.md new file mode 100644 index 0000000000..6ea48d92e4 --- /dev/null +++ b/contracts/.changeset/tender-comics-check.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +#internal prevent reentrancy when configuring DON in capabilities registry diff --git a/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol b/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol index ba61584d0a..ad6f26e8dc 100644 --- a/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol +++ b/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol @@ -961,6 +961,11 @@ contract CapabilitiesRegistry is OwnerIsCreator, TypeAndVersionInterface { donCapabilityConfig.capabilityIds.push(configuration.capabilityId); donCapabilityConfig.capabilityConfigs[configuration.capabilityId] = configuration.config; + s_dons[donParams.id].isPublic = donParams.isPublic; + s_dons[donParams.id].acceptsWorkflows = donParams.acceptsWorkflows; + s_dons[donParams.id].f = donParams.f; + s_dons[donParams.id].configCount = donParams.configCount; + _setDONCapabilityConfig( donParams.id, donParams.configCount, @@ -969,10 +974,6 @@ contract CapabilitiesRegistry is OwnerIsCreator, TypeAndVersionInterface { configuration.config ); } - s_dons[donParams.id].isPublic = donParams.isPublic; - s_dons[donParams.id].acceptsWorkflows = donParams.acceptsWorkflows; - s_dons[donParams.id].f = donParams.f; - s_dons[donParams.id].configCount = donParams.configCount; emit ConfigSet(donParams.id, donParams.configCount); } diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_AddDONTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_AddDONTest.t.sol index 65c85e4f74..dc0b85bfa3 100644 --- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_AddDONTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_AddDONTest.t.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.24; import {BaseTest} from "./BaseTest.t.sol"; import {ICapabilityConfiguration} from "../interfaces/ICapabilityConfiguration.sol"; import {CapabilitiesRegistry} from "../CapabilitiesRegistry.sol"; +import {MaliciousConfigurationContract} from "./mocks/MaliciousConfigurationContract.sol"; contract CapabilitiesRegistry_AddDONTest is BaseTest { function setUp() public override { @@ -245,3 +246,75 @@ contract CapabilitiesRegistry_AddDONTest is BaseTest { assertEq(donInfo.nodeP2PIds[1], P2P_ID_THREE); } } + +contract CapabilitiesRegistry_AddDONTest_WhenMaliciousCapabilityConfigurationConfigured is BaseTest { + function setUp() public override { + BaseTest.setUp(); + CapabilitiesRegistry.Capability[] memory capabilities = new CapabilitiesRegistry.Capability[](2); + + address maliciousConfigContractAddr = address( + new MaliciousConfigurationContract(s_capabilityWithConfigurationContractId) + ); + s_basicCapability.configurationContract = maliciousConfigContractAddr; + capabilities[0] = s_basicCapability; + capabilities[1] = s_capabilityWithConfigurationContract; + + CapabilitiesRegistry.NodeOperator[] memory nodeOperators = _getNodeOperators(); + nodeOperators[0].admin = maliciousConfigContractAddr; + nodeOperators[1].admin = maliciousConfigContractAddr; + nodeOperators[2].admin = maliciousConfigContractAddr; + + s_CapabilitiesRegistry.addNodeOperators(nodeOperators); + s_CapabilitiesRegistry.addCapabilities(capabilities); + + CapabilitiesRegistry.NodeParams[] memory nodes = new CapabilitiesRegistry.NodeParams[](3); + bytes32[] memory capabilityIds = new bytes32[](1); + capabilityIds[0] = s_basicHashedCapabilityId; + + nodes[0] = CapabilitiesRegistry.NodeParams({ + nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, + p2pId: P2P_ID, + signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, + hashedCapabilityIds: capabilityIds + }); + + bytes32[] memory nodeTwoCapabilityIds = new bytes32[](1); + nodeTwoCapabilityIds[0] = s_basicHashedCapabilityId; + + nodes[1] = CapabilitiesRegistry.NodeParams({ + nodeOperatorId: TEST_NODE_OPERATOR_TWO_ID, + p2pId: P2P_ID_TWO, + signer: NODE_OPERATOR_TWO_SIGNER_ADDRESS, + hashedCapabilityIds: nodeTwoCapabilityIds + }); + + nodes[2] = CapabilitiesRegistry.NodeParams({ + nodeOperatorId: TEST_NODE_OPERATOR_THREE_ID, + p2pId: P2P_ID_THREE, + signer: NODE_OPERATOR_THREE_SIGNER_ADDRESS, + hashedCapabilityIds: capabilityIds + }); + + s_CapabilitiesRegistry.addNodes(nodes); + + changePrank(ADMIN); + } + + function test_RevertWhen_MaliciousCapabilitiesConfigContractTriesToRemoveCapabilitiesFromDONNodes() public { + bytes32[] memory nodes = new bytes32[](2); + nodes[0] = P2P_ID; + nodes[1] = P2P_ID_THREE; + + CapabilitiesRegistry.CapabilityConfiguration[] + memory capabilityConfigs = new CapabilitiesRegistry.CapabilityConfiguration[](1); + capabilityConfigs[0] = CapabilitiesRegistry.CapabilityConfiguration({ + capabilityId: s_basicHashedCapabilityId, + config: BASIC_CAPABILITY_CONFIG + }); + + vm.expectRevert( + abi.encodeWithSelector(CapabilitiesRegistry.CapabilityRequiredByDON.selector, s_basicHashedCapabilityId, DON_ID) + ); + s_CapabilitiesRegistry.addDON(nodes, capabilityConfigs, true, true, F_VALUE); + } +} diff --git a/contracts/src/v0.8/keystone/test/mocks/MaliciousConfigurationContract.sol b/contracts/src/v0.8/keystone/test/mocks/MaliciousConfigurationContract.sol new file mode 100644 index 0000000000..72c2e23efe --- /dev/null +++ b/contracts/src/v0.8/keystone/test/mocks/MaliciousConfigurationContract.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {ICapabilityConfiguration} from "../../interfaces/ICapabilityConfiguration.sol"; +import {CapabilitiesRegistry} from "../../CapabilitiesRegistry.sol"; +import {ERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165.sol"; +import {Constants} from "../Constants.t.sol"; + +contract MaliciousConfigurationContract is ICapabilityConfiguration, ERC165, Constants { + bytes32 internal s_capabilityWithConfigurationContractId; + + constructor(bytes32 capabilityWithConfigContractId) { + s_capabilityWithConfigurationContractId = capabilityWithConfigContractId; + } + + function getCapabilityConfiguration(uint32) external view returns (bytes memory configuration) { + return bytes(""); + } + + function beforeCapabilityConfigSet(bytes32[] calldata, bytes calldata, uint64, uint32) external { + CapabilitiesRegistry.NodeParams[] memory nodes = new CapabilitiesRegistry.NodeParams[](2); + bytes32[] memory hashedCapabilityIds = new bytes32[](1); + + hashedCapabilityIds[0] = s_capabilityWithConfigurationContractId; + + // Set node one's signer to another address + nodes[0] = CapabilitiesRegistry.NodeParams({ + nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, + p2pId: P2P_ID, + signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, + hashedCapabilityIds: hashedCapabilityIds + }); + + nodes[1] = CapabilitiesRegistry.NodeParams({ + nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, + p2pId: P2P_ID_THREE, + signer: NODE_OPERATOR_THREE_SIGNER_ADDRESS, + hashedCapabilityIds: hashedCapabilityIds + }); + + CapabilitiesRegistry(msg.sender).updateNodes(nodes); + } + + function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { + return interfaceId == this.getCapabilityConfiguration.selector ^ this.beforeCapabilityConfigSet.selector; + } +} diff --git a/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go b/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go index c345a86569..2cfbe12064 100644 --- a/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go +++ b/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go @@ -87,7 +87,7 @@ type CapabilitiesRegistryNodeParams struct { var CapabilitiesRegistryMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityIsDeprecated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"CapabilityRequiredByDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"DONDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONNode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"nodeCount\",\"type\":\"uint256\"}],\"name\":\"InvalidFaultTolerance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"InvalidNodeCapabilities\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"InvalidNodeP2PId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotSupportCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfCapabilitiesDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfWorkflowDON\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilitiesRegistry.Capability[]\",\"name\":\"capabilities\",\"type\":\"tuple[]\"}],\"name\":\"addCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"addDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"addNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"deprecateCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityConfigs\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"getDON\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"getHashedCapabilityId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"getNode\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo\",\"name\":\"nodeInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodeOperators\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodes\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"isCapabilityDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"donIds\",\"type\":\"uint32[]\"}],\"name\":\"removeDONs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"removedNodeP2PIds\",\"type\":\"bytes32[]\"}],\"name\":\"removeNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"updateDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"updateNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6080604052600e80546001600160401b0319166401000000011790553480156200002857600080fd5b503380600081620000805760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000b357620000b381620000bc565b50505062000167565b336001600160a01b03821603620001165760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000077565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6150f680620001776000396000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80635e65e309116100ee5780638da5cb5b11610097578063d8bc7b6811610071578063d8bc7b68146103f6578063ddbe4f8214610409578063e29581aa1461041e578063f2fde38b1461043357600080fd5b80638da5cb5b1461039b5780639cb7c5f4146103c3578063d59a79f6146103e357600080fd5b806373ac22b4116100c857806373ac22b41461036d57806379ba50971461038057806386fa42461461038857600080fd5b80635e65e3091461033257806366acaa3314610345578063715f52951461035a57600080fd5b8063235374051161015b578063398f377311610135578063398f3773146102cb5780633f2a13c9146102de57806350c946fe146102ff5780635d83d9671461031f57600080fd5b80632353740514610285578063275459f2146102a55780632c01a1e8146102b857600080fd5b80631d05394c1161018c5780631d05394c1461023b578063214502431461025057806322bdbcbc1461026557600080fd5b80630fe5800a146101b357806312570011146101d9578063181f5a77146101fc575b600080fd5b6101c66101c1366004613e8b565b610446565b6040519081526020015b60405180910390f35b6101ec6101e7366004613eef565b61047a565b60405190151581526020016101d0565b604080518082018252601a81527f4361706162696c6974696573526567697374727920312e302e30000000000000602082015290516101d09190613f76565b61024e610249366004613fce565b610487565b005b61025861069c565b6040516101d09190614150565b6102786102733660046141eb565b6107f9565b6040516101d09190614243565b6102986102933660046141eb565b6108e6565b6040516101d09190614256565b61024e6102b3366004613fce565b61092a565b61024e6102c6366004613fce565b610a01565b61024e6102d9366004613fce565b610c9d565b6102f16102ec366004614269565b610e5c565b6040516101d0929190614293565b61031261030d366004613eef565b611048565b6040516101d09190614358565b61024e61032d366004613fce565b611122565b61024e610340366004613fce565b611217565b61034d61193f565b6040516101d0919061436b565b61024e610368366004613fce565b611b22565b61024e61037b366004613fce565b611bd4565b61024e6120a2565b61024e6103963660046143e0565b61219f565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d0565b6103d66103d1366004613eef565b6124df565b6040516101d0919061452f565b61024e6103f1366004614561565b61271a565b61024e610404366004614616565b6127e3565b6104116128ad565b6040516101d091906146bb565b6104266129a1565b6040516101d09190614730565b61024e6104413660046147c9565b612aaa565b6000828260405160200161045b929190614293565b6040516020818303038152906040528051906020012090505b92915050565b6000610474600583612abe565b61048f612ad9565b60005b818110156106975760008383838181106104ae576104ae6147e4565b90506020020160208101906104c391906141eb565b63ffffffff8181166000908152600d60209081526040808320805464010000000081049095168085526001820190935290832094955093909290916a010000000000000000000090910460ff16905b61051b83612b5c565b8110156105bb57811561057157600c60006105368584612b66565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556105b3565b6105b18663ffffffff16600c60006105928588612b6690919063ffffffff16565b8152602001908152602001600020600401612b7290919063ffffffff16565b505b600101610512565b508354640100000000900463ffffffff16600003610612576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff861660048201526024015b60405180910390fd5b63ffffffff85166000818152600d6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffff00000000000000000000001690558051938452908301919091527ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c1581703651910160405180910390a15050505050806001019050610492565b505050565b600e54606090640100000000900463ffffffff1660006106bd600183614842565b63ffffffff1667ffffffffffffffff8111156106db576106db613d25565b60405190808252806020026020018201604052801561076257816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816106f95790505b509050600060015b8363ffffffff168163ffffffff1610156107d65763ffffffff8082166000908152600d602052604090205416156107ce576107a481612b7e565b8383815181106107b6576107b66147e4565b6020026020010181905250816107cb9061485f565b91505b60010161076a565b506107e2600184614842565b63ffffffff1681146107f2578082525b5092915050565b60408051808201909152600081526060602082015263ffffffff82166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161085d90614897565b80601f016020809104026020016040519081016040528092919081815260200182805461088990614897565b80156108d65780601f106108ab576101008083540402835291602001916108d6565b820191906000526020600020905b8154815290600101906020018083116108b957829003601f168201915b5050505050815250509050919050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c081019190915261047482612b7e565b610932612ad9565b60005b63ffffffff811682111561069757600083838363ffffffff1681811061095d5761095d6147e4565b905060200201602081019061097291906141eb565b63ffffffff81166000908152600b6020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559192506109bd6001830182613cb8565b505060405163ffffffff8216907fa59268ca81d40429e65ccea5385b59cf2d3fc6519371dee92f8eb1dae5107a7a90600090a2506109fa816148ea565b9050610935565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110610a3b57610a3b6147e4565b602090810292909201356000818152600c90935260409092206001810154929350919050610a98576040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260048101839052602401610609565b6000610aa682600401612b5c565b1115610afb57610ab96004820184612b66565b6040517f60a6d89800000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101839052604401610609565b805468010000000000000000900463ffffffff1615610b635780546040517f60b9df730000000000000000000000000000000000000000000000000000000081526801000000000000000090910463ffffffff16600482015260248101839052604401610609565b83158015610b9d5750805463ffffffff166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15610bd6576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6001810154610be790600790612b72565b506002810154610bf990600990612b72565b506000828152600c6020526040812080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815560018101829055600281018290559060048201818181610c4e8282613cf2565b5050505050507f5254e609a97bab37b7cc79fe128f85c097bd6015c6e1624ae0ba392eb975320582604051610c8591815260200190565b60405180910390a15050600101610a1f565b50505050565b610ca5612ad9565b60005b81811015610697576000838383818110610cc457610cc46147e4565b9050602002810190610cd6919061490d565b610cdf9061494b565b805190915073ffffffffffffffffffffffffffffffffffffffff16610d30576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815263ffffffff9095166000818152600b909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251919290916001820190610dbc9082614a05565b5050600e8054909150600090610dd79063ffffffff166148ea565b91906101000a81548163ffffffff021916908363ffffffff160217905550816000015173ffffffffffffffffffffffffffffffffffffffff168163ffffffff167f78e94ca80be2c30abc061b99e7eb8583b1254781734b1e3ce339abb57da2fe8e8460200151604051610e4a9190613f76565b60405180910390a35050600101610ca8565b63ffffffff8083166000908152600d60209081526040808320805464010000000090049094168084526001909401825280832085845260030190915281208054606093849390929091610eae90614897565b80601f0160208091040260200160405190810160405280929190818152602001828054610eda90614897565b8015610f275780601f10610efc57610100808354040283529160200191610f27565b820191906000526020600020905b815481529060010190602001808311610f0a57829003601f168201915b5050506000888152600260208190526040909120015492935060609262010000900473ffffffffffffffffffffffffffffffffffffffff1615915061103a905057600086815260026020819052604091829020015490517f8318ed5d00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526201000090910473ffffffffffffffffffffffffffffffffffffffff1690638318ed5d90602401600060405180830381865afa158015610ff1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110379190810190614b1f565b90505b9093509150505b9250929050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c08101919091526040805160e0810182526000848152600c6020908152838220805463ffffffff8082168652640100000000820481168487018190526801000000000000000090920416858701526001820154606086015260028201546080860152835260030190529190912060a08201906110f790612e49565b815260200161111a600c6000868152602001908152602001600020600401612e49565b905292915050565b61112a612ad9565b60005b81811015610697576000838383818110611149576111496147e4565b905060200201359050611166816003612abe90919063ffffffff16565b61119f576040517fe181733f00000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b6111aa600582612e56565b6111e3576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b60405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a25060010161112d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110611251576112516147e4565b90506020028101906112639190614b8d565b61126c90614bc1565b6040808201516000908152600c6020908152828220805463ffffffff168352600b82528383208451808601909552805473ffffffffffffffffffffffffffffffffffffffff16855260018101805496975091959394939092840191906112d190614897565b80601f01602080910402602001604051908101604052809291908181526020018280546112fd90614897565b801561134a5780601f1061131f5761010080835404028352916020019161134a565b820191906000526020600020905b81548152906001019060200180831161132d57829003601f168201915b50505091909252505050600183015490915061139a5782604001516040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b841580156113bf5750805173ffffffffffffffffffffffffffffffffffffffff163314155b156113f8576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6020830151611433576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001820154602084015181146114b457602084015161145490600790612abe565b1561148b576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084015160018401556114a0600782612b72565b5060208401516114b290600790612e56565b505b606084015180516000036114f657806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c94565b8354600090859060049061151790640100000000900463ffffffff166148ea565b91906101000a81548163ffffffff021916908363ffffffff1602179055905060005b82518110156115fc5761156f838281518110611557576115576147e4565b60200260200101516003612abe90919063ffffffff16565b6115a757826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c94565b6115f38382815181106115bc576115bc6147e4565b60200260200101518760030160008563ffffffff1663ffffffff168152602001908152602001600020612e5690919063ffffffff16565b50600101611539565b50845468010000000000000000900463ffffffff16801561175d5763ffffffff8082166000908152600d60209081526040808320805464010000000090049094168352600190930181528282206002018054845181840281018401909552808552929392909183018282801561169157602002820191906000526020600020905b81548152602001906001019080831161167d575b5050505050905060005b815181101561175a576116f08282815181106116b9576116b96147e4565b60200260200101518960030160008763ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b61175257818181518110611706576117066147e4565b6020026020010151836040517f03dcd86200000000000000000000000000000000000000000000000000000000815260040161060992919091825263ffffffff16602082015260400190565b60010161169b565b50505b600061176b87600401612e49565b905060005b81518163ffffffff1610156118b1576000828263ffffffff1681518110611799576117996147e4565b60209081029190910181015163ffffffff8082166000908152600d8452604080822080546401000000009004909316825260019092018452818120600201805483518187028101870190945280845293955090939192909183018282801561182057602002820191906000526020600020905b81548152602001906001019080831161180c575b5050505050905060005b815181101561189d5761187f828281518110611848576118486147e4565b60200260200101518c60030160008a63ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b61189557818181518110611706576117066147e4565b60010161182a565b505050806118aa906148ea565b9050611770565b50875187547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90911690811788556040808a015160028a018190556020808c01518351928352908201527f4b5b465e22eea0c3d40c30e936643245b80d19b2dcf75788c0699fe8d8db645b910160405180910390a25050505050505050806001019050611235565b600e5460609063ffffffff166000611958600183614842565b63ffffffff1667ffffffffffffffff81111561197657611976613d25565b6040519080825280602002602001820160405280156119bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816119945790505b509050600060015b8363ffffffff168163ffffffff161015611b0c5763ffffffff81166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611b045763ffffffff81166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191611a5890614897565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8490614897565b8015611ad15780601f10611aa657610100808354040283529160200191611ad1565b820191906000526020600020905b815481529060010190602001808311611ab457829003601f168201915b505050505081525050838381518110611aec57611aec6147e4565b602002602001018190525081611b019061485f565b91505b6001016119c4565b50600e546107e29060019063ffffffff16614842565b611b2a612ad9565b60005b81811015610697576000838383818110611b4957611b496147e4565b9050602002810190611b5b9190614cd8565b611b6490614d1b565b90506000611b7a82600001518360200151610446565b9050611b87600382612e56565b611bc0576040517febf5255100000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b611bca8183612e62565b5050600101611b2d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110611c0e57611c0e6147e4565b9050602002810190611c209190614b8d565b611c2990614bc1565b805163ffffffff166000908152600b602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191611c7f90614897565b80601f0160208091040260200160405190810160405280929190818152602001828054611cab90614897565b8015611cf85780601f10611ccd57610100808354040283529160200191611cf8565b820191906000526020600020905b815481529060010190602001808311611cdb57829003601f168201915b50505091909252505081519192505073ffffffffffffffffffffffffffffffffffffffff16611d5e5781516040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff9091166004820152602401610609565b83158015611d835750805173ffffffffffffffffffffffffffffffffffffffff163314155b15611dbc576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6040808301516000908152600c60205220600181015415611e115782604001516040517f5461848300000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b6040830151611e545782604001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b60208301511580611e7157506020830151611e7190600790612abe565b15611ea8576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608301518051600003611eea57806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c94565b81548290600490611f0890640100000000900463ffffffff166148ea565b82546101009290920a63ffffffff818102199093169183160217909155825464010000000090041660005b8251811015611fde57611f51838281518110611557576115576147e4565b611f8957826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c94565b611fd5838281518110611f9e57611f9e6147e4565b60200260200101518560030160008563ffffffff1663ffffffff168152602001908152602001600020612e5690919063ffffffff16565b50600101611f33565b50845183547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff918216178455604086015160028501556020860151600185018190556120349160079190612e5616565b50604085015161204690600990612e56565b50845160408087015160208089015183519283529082015263ffffffff909216917f74becb12a5e8fd0e98077d02dfba8f647c9670c9df177e42c2418cf17a636f05910160405180910390a25050505050806001019050611bf2565b60015473ffffffffffffffffffffffffffffffffffffffff163314612123576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610609565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b8281146121e2576040517fab8b67c60000000000000000000000000000000000000000000000000000000081526004810184905260248101829052604401610609565b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156124d757600086868381811061221a5761221a6147e4565b905060200201602081019061222f91906141eb565b63ffffffff81166000908152600b6020526040902080549192509073ffffffffffffffffffffffffffffffffffffffff1661229e576040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff83166004820152602401610609565b60008686858181106122b2576122b26147e4565b90506020028101906122c4919061490d565b6122cd9061494b565b805190915073ffffffffffffffffffffffffffffffffffffffff1661231e576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815473ffffffffffffffffffffffffffffffffffffffff16331480159061235b57503373ffffffffffffffffffffffffffffffffffffffff861614155b15612394576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b8051825473ffffffffffffffffffffffffffffffffffffffff908116911614158061241057506020808201516040516123cd9201613f76565b60405160208183030381529060405280519060200120826001016040516020016123f79190614dc1565b6040516020818303038152906040528051906020012014155b156124c957805182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020810151600183019061246a9082614a05565b50806000015173ffffffffffffffffffffffffffffffffffffffff168363ffffffff167f86f41145bde5dd7f523305452e4aad3685508c181432ec733d5f345009358a2883602001516040516124c09190613f76565b60405180910390a35b5050508060010190506121fe565b505050505050565b6125206040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b6040805160e0810182528381526000848152600260209081529290208054919283019161254c90614897565b80601f016020809104026020016040519081016040528092919081815260200182805461257890614897565b80156125c55780601f1061259a576101008083540402835291602001916125c5565b820191906000526020600020905b8154815290600101906020018083116125a857829003601f168201915b505050505081526020016002600085815260200190815260200160002060010180546125f090614897565b80601f016020809104026020016040519081016040528092919081815260200182805461261c90614897565b80156126695780601f1061263e57610100808354040283529160200191612669565b820191906000526020600020905b81548152906001019060200180831161264c57829003601f168201915b50505091835250506000848152600260208181526040909220015491019060ff16600381111561269b5761269b61444c565b815260008481526002602081815260409092200154910190610100900460ff1660018111156126cc576126cc61444c565b81526000848152600260208181526040928390209091015462010000900473ffffffffffffffffffffffffffffffffffffffff169083015201612710600585612abe565b1515905292915050565b612722612ad9565b63ffffffff8089166000908152600d6020526040812054640100000000900490911690819003612786576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff8a166004820152602401610609565b6127d8888888886040518060a001604052808f63ffffffff168152602001876127ae906148ea565b97508763ffffffff1681526020018a1515815260200189151581526020018860ff168152506130f6565b505050505050505050565b6127eb612ad9565b600e805460009164010000000090910463ffffffff1690600461280d836148ea565b82546101009290920a63ffffffff81810219909316918316021790915581166000818152600d602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001684179055815160a08101835292835260019083015286151590820152841515606082015260ff841660808201529091506128a39089908990899089906130f6565b5050505050505050565b606060006128bb6003612e49565b90506000815167ffffffffffffffff8111156128d9576128d9613d25565b60405190808252806020026020018201604052801561294b57816020015b6129386040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b8152602001906001900390816128f75790505b50905060005b82518110156107f25761297c83828151811061296f5761296f6147e4565b60200260200101516124df565b82828151811061298e5761298e6147e4565b6020908102919091010152600101612951565b606060006129af6009612e49565b90506000815167ffffffffffffffff8111156129cd576129cd613d25565b604051908082528060200260200182016040528015612a5457816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816129eb5790505b50905060005b82518110156107f257612a85838281518110612a7857612a786147e4565b6020026020010151611048565b828281518110612a9757612a976147e4565b6020908102919091010152600101612a5a565b612ab2612ad9565b612abb8161391a565b50565b600081815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612b5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610609565b565b6000610474825490565b6000612ad28383613a0f565b6000612ad28383613a39565b6040805160e0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840181905260c084015263ffffffff8581168352600d8252848320805464010000000090049091168084526001909101825284832060028101805487518186028101860190985280885295969295919493909190830182828015612c2f57602002820191906000526020600020905b815481526020019060010190808311612c1b575b505050505090506000815167ffffffffffffffff811115612c5257612c52613d25565b604051908082528060200260200182016040528015612c9857816020015b604080518082019091526000815260606020820152815260200190600190039081612c705790505b50905060005b8151811015612db0576040518060400160405280848381518110612cc457612cc46147e4565b60200260200101518152602001856003016000868581518110612ce957612ce96147e4565b602002602001015181526020019081526020016000208054612d0a90614897565b80601f0160208091040260200160405190810160405280929190818152602001828054612d3690614897565b8015612d835780601f10612d5857610100808354040283529160200191612d83565b820191906000526020600020905b815481529060010190602001808311612d6657829003601f168201915b5050505050815250828281518110612d9d57612d9d6147e4565b6020908102919091010152600101612c9e565b506040805160e08101825263ffffffff8089166000818152600d6020818152868320548086168752948b168187015260ff680100000000000000008604811697870197909752690100000000000000000085048716151560608701529290915290526a010000000000000000000090049091161515608082015260a08101612e3785612e49565b81526020019190915295945050505050565b60606000612ad283613b2c565b6000612ad28383613b88565b608081015173ffffffffffffffffffffffffffffffffffffffff1615612fb057608081015173ffffffffffffffffffffffffffffffffffffffff163b1580612f5b575060808101516040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f78bea72100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff909116906301ffc9a790602401602060405180830381865afa158015612f35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f599190614e6f565b155b15612fb05760808101516040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610609565b600082815260026020526040902081518291908190612fcf9082614a05565b5060208201516001820190612fe49082614a05565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660018360038111156130265761302661444c565b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010083600181111561306d5761306d61444c565b0217905550608091909101516002909101805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff90921691909117905560405182907f04f0a9bcf3f3a3b42a4d7ca081119755f82ebe43e0d30c8f7292c4fe0dc4a2ae90600090a25050565b805163ffffffff9081166000908152600d602090815260408083208286015190941683526001909301905220608082015160ff161580613148575060808201518590613143906001614e8c565b60ff16115b156131915760808201516040517f25b4d61800000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101869052604401610609565b6001826020015163ffffffff16111561327957815163ffffffff166000908152600d6020908152604082209084015160019182019183916131d29190614842565b63ffffffff1663ffffffff168152602001908152602001600020905060005b6131fa82612b5c565b81101561327657613229846000015163ffffffff16600c60006105928587600001612b6690919063ffffffff16565b50600c60006132388484612b66565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556001016131f1565b50505b60005b858110156134b3576132a9878783818110613299576132996147e4565b8592602090910201359050612e56565b61330a5782518787838181106132c1576132c16147e4565b6040517f636e405700000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b82606001511561346157825163ffffffff16600c6000898985818110613332576133326147e4565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff16148015906133ac5750600c600088888481811061337d5761337d6147e4565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff1615155b1561340e5782518787838181106133c5576133c56147e4565b6040517f60b9df7300000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8251600c6000898985818110613426576134266147e4565b90506020020135815260200190815260200160002060000160086101000a81548163ffffffff021916908363ffffffff1602179055506134ab565b82516134a99063ffffffff16600c60008a8a86818110613483576134836147e4565b905060200201358152602001908152602001600020600401612e5690919063ffffffff16565b505b60010161327c565b5060005b8381101561378f57368585838181106134d2576134d26147e4565b90506020028101906134e4919061490d565b90506134f260038235612abe565b61352b576040517fe181733f00000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b61353760058235612abe565b15613571576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b803560009081526003840160205260408120805461358e90614897565b905011156135da5783516040517f3927d08000000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015281356024820152604401610609565b60005b878110156136e4576136818235600c60008c8c86818110613600576136006147e4565b9050602002013581526020019081526020016000206003016000600c60008e8e88818110613630576136306147e4565b90506020020135815260200190815260200160002060000160049054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b6136dc57888882818110613697576136976147e4565b6040517fa7e792500000000000000000000000000000000000000000000000000000000081526020909102929092013560048301525082356024820152604401610609565b6001016135dd565b506002830180546001810182556000918252602091829020833591015561370d90820182614ea5565b8235600090815260038601602052604090209161372b919083614f0a565b50835160208086015161378692918435908c908c9061374c90880188614ea5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613bd792505050565b506001016134b7565b50604080830151835163ffffffff9081166000908152600d602090815284822080549415156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff90951694909417909355606086015186518316825284822080549115156a0100000000000000000000027fffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff9092169190911790556080860151865183168252848220805460ff9290921668010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff909216919091179055918501805186518316845292849020805493909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9093169290921790558351905191517ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c15817036519261390a929163ffffffff92831681529116602082015260400190565b60405180910390a1505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613999576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610609565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613a2657613a266147e4565b9060005260206000200154905092915050565b60008181526001830160205260408120548015613b22576000613a5d600183615025565b8554909150600090613a7190600190615025565b9050818114613ad6576000866000018281548110613a9157613a916147e4565b9060005260206000200154905080876000018481548110613ab457613ab46147e4565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613ae757613ae7615038565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610474565b6000915050610474565b606081600001805480602002602001604051908101604052809291908181526020018280548015613b7c57602002820191906000526020600020905b815481526020019060010190808311613b68575b50505050509050919050565b6000818152600183016020526040812054613bcf57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610474565b506000610474565b6000848152600260208190526040909120015462010000900473ffffffffffffffffffffffffffffffffffffffff16156124d757600084815260026020819052604091829020015490517ffba64a7c0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169063fba64a7c90613c7e908690869086908b908d90600401615067565b600060405180830381600087803b158015613c9857600080fd5b505af1158015613cac573d6000803e3d6000fd5b50505050505050505050565b508054613cc490614897565b6000825580601f10613cd4575050565b601f016020900490600052602060002090810190612abb9190613d0c565b5080546000825590600052602060002090810190612abb91905b5b80821115613d215760008155600101613d0d565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613d7757613d77613d25565b60405290565b60405160a0810167ffffffffffffffff81118282101715613d7757613d77613d25565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613de757613de7613d25565b604052919050565b600067ffffffffffffffff821115613e0957613e09613d25565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613e4657600080fd5b8135613e59613e5482613def565b613da0565b818152846020838601011115613e6e57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613e9e57600080fd5b823567ffffffffffffffff80821115613eb657600080fd5b613ec286838701613e35565b93506020850135915080821115613ed857600080fd5b50613ee585828601613e35565b9150509250929050565b600060208284031215613f0157600080fd5b5035919050565b60005b83811015613f23578181015183820152602001613f0b565b50506000910152565b60008151808452613f44816020860160208601613f08565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612ad26020830184613f2c565b60008083601f840112613f9b57600080fd5b50813567ffffffffffffffff811115613fb357600080fd5b6020830191508360208260051b850101111561104157600080fd5b60008060208385031215613fe157600080fd5b823567ffffffffffffffff811115613ff857600080fd5b61400485828601613f89565b90969095509350505050565b60008151808452602080850194506020840160005b8381101561404157815187529582019590820190600101614025565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b848110156140c9578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051845284015160408585018190526140b581860183613f2c565b9a86019a9450505090830190600101614069565b5090979650505050505050565b600063ffffffff8083511684528060208401511660208501525060ff604083015116604084015260608201511515606084015260808201511515608084015260a082015160e060a085015261412e60e0850182614010565b905060c083015184820360c0860152614147828261404c565b95945050505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526141b38583516140d6565b94509285019290850190600101614179565b5092979650505050505050565b803563ffffffff811681146141e657600080fd5b919050565b6000602082840312156141fd57600080fd5b612ad2826141d2565b73ffffffffffffffffffffffffffffffffffffffff8151168252600060208201516040602085015261423b6040850182613f2c565b949350505050565b602081526000612ad26020830184614206565b602081526000612ad260208301846140d6565b6000806040838503121561427c57600080fd5b614285836141d2565b946020939093013593505050565b6040815260006142a66040830185613f2c565b82810360208401526141478185613f2c565b600063ffffffff808351168452602081818501511681860152816040850151166040860152606084015160608601526080840151608086015260a0840151915060e060a086015261430c60e0860183614010565b60c08581015187830391880191909152805180835290830193506000918301905b8083101561434d578451825293830193600192909201919083019061432d565b509695505050505050565b602081526000612ad260208301846142b8565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526143ce858351614206565b94509285019290850190600101614394565b600080600080604085870312156143f657600080fd5b843567ffffffffffffffff8082111561440e57600080fd5b61441a88838901613f89565b9096509450602087013591508082111561443357600080fd5b5061444087828801613f89565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b805182526000602082015160e0602085015261449a60e0850182613f2c565b9050604083015184820360408601526144b38282613f2c565b9150506060830151600481106144cb576144cb61444c565b60608501526080830151600281106144e5576144e561444c565b8060808601525060a083015161451360a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015161452760c086018215159052565b509392505050565b602081526000612ad2602083018461447b565b8015158114612abb57600080fd5b803560ff811681146141e657600080fd5b60008060008060008060008060c0898b03121561457d57600080fd5b614586896141d2565b9750602089013567ffffffffffffffff808211156145a357600080fd5b6145af8c838d01613f89565b909950975060408b01359150808211156145c857600080fd5b506145d58b828c01613f89565b90965094505060608901356145e981614542565b925060808901356145f981614542565b915061460760a08a01614550565b90509295985092959890939650565b600080600080600080600060a0888a03121561463157600080fd5b873567ffffffffffffffff8082111561464957600080fd5b6146558b838c01613f89565b909950975060208a013591508082111561466e57600080fd5b5061467b8a828b01613f89565b909650945050604088013561468f81614542565b9250606088013561469f81614542565b91506146ad60808901614550565b905092959891949750929550565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261471e85835161447b565b945092850192908501906001016146e4565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526147938583516142b8565b94509285019290850190600101614759565b803573ffffffffffffffffffffffffffffffffffffffff811681146141e657600080fd5b6000602082840312156147db57600080fd5b612ad2826147a5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff8281168282160390808211156107f2576107f2614813565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361489057614890614813565b5060010190565b600181811c908216806148ab57607f821691505b6020821081036148e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600063ffffffff80831681810361490357614903614813565b6001019392505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261494157600080fd5b9190910192915050565b60006040823603121561495d57600080fd5b6040516040810167ffffffffffffffff828210818311171561498157614981613d25565b8160405261498e856147a5565b835260208501359150808211156149a457600080fd5b506149b136828601613e35565b60208301525092915050565b601f821115610697576000816000526020600020601f850160051c810160208610156149e65750805b601f850160051c820191505b818110156124d7578281556001016149f2565b815167ffffffffffffffff811115614a1f57614a1f613d25565b614a3381614a2d8454614897565b846149bd565b602080601f831160018114614a865760008415614a505750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556124d7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614ad357888601518255948401946001909101908401614ab4565b5085821015614b0f57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215614b3157600080fd5b815167ffffffffffffffff811115614b4857600080fd5b8201601f81018413614b5957600080fd5b8051614b67613e5482613def565b818152856020838501011115614b7c57600080fd5b614147826020830160208601613f08565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183360301811261494157600080fd5b600060808236031215614bd357600080fd5b614bdb613d54565b614be4836141d2565b81526020808401358183015260408401356040830152606084013567ffffffffffffffff80821115614c1557600080fd5b9085019036601f830112614c2857600080fd5b813581811115614c3a57614c3a613d25565b8060051b9150614c4b848301613da0565b8181529183018401918481019036841115614c6557600080fd5b938501935b83851015614c8357843582529385019390850190614c6a565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614ccc57835183529284019291840191600101614cb0565b50909695505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261494157600080fd5b8035600281106141e657600080fd5b600060a08236031215614d2d57600080fd5b614d35613d7d565b823567ffffffffffffffff80821115614d4d57600080fd5b614d5936838701613e35565b83526020850135915080821115614d6f57600080fd5b50614d7c36828601613e35565b602083015250604083013560048110614d9457600080fd5b6040820152614da560608401614d0c565b6060820152614db6608084016147a5565b608082015292915050565b6000602080835260008454614dd581614897565b8060208701526040600180841660008114614df75760018114614e3157614e61565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550614e61565b89600052602060002060005b85811015614e585781548b8201860152908301908801614e3d565b8a016040019650505b509398975050505050505050565b600060208284031215614e8157600080fd5b8151612ad281614542565b60ff818116838216019081111561047457610474614813565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614eda57600080fd5b83018035915067ffffffffffffffff821115614ef557600080fd5b60200191503681900382131561104157600080fd5b67ffffffffffffffff831115614f2257614f22613d25565b614f3683614f308354614897565b836149bd565b6000601f841160018114614f885760008515614f525750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561501e565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015614fd75786850135825560209485019460019092019101614fb7565b5086821015615012577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8181038181111561047457610474614813565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6080815284608082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8611156150a057600080fd5b8560051b808860a0850137820182810360a090810160208501526150c690820187613f2c565b91505063ffffffff8085166040840152808416606084015250969550505050505056fea164736f6c6343000818000a", + Bin: "0x6080604052600e80546001600160401b0319166401000000011790553480156200002857600080fd5b503380600081620000805760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000b357620000b381620000bc565b50505062000167565b336001600160a01b03821603620001165760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000077565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6150f780620001776000396000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80635e65e309116100ee5780638da5cb5b11610097578063d8bc7b6811610071578063d8bc7b68146103f6578063ddbe4f8214610409578063e29581aa1461041e578063f2fde38b1461043357600080fd5b80638da5cb5b1461039b5780639cb7c5f4146103c3578063d59a79f6146103e357600080fd5b806373ac22b4116100c857806373ac22b41461036d57806379ba50971461038057806386fa42461461038857600080fd5b80635e65e3091461033257806366acaa3314610345578063715f52951461035a57600080fd5b8063235374051161015b578063398f377311610135578063398f3773146102cb5780633f2a13c9146102de57806350c946fe146102ff5780635d83d9671461031f57600080fd5b80632353740514610285578063275459f2146102a55780632c01a1e8146102b857600080fd5b80631d05394c1161018c5780631d05394c1461023b578063214502431461025057806322bdbcbc1461026557600080fd5b80630fe5800a146101b357806312570011146101d9578063181f5a77146101fc575b600080fd5b6101c66101c1366004613e8c565b610446565b6040519081526020015b60405180910390f35b6101ec6101e7366004613ef0565b61047a565b60405190151581526020016101d0565b604080518082018252601a81527f4361706162696c6974696573526567697374727920312e302e30000000000000602082015290516101d09190613f77565b61024e610249366004613fcf565b610487565b005b61025861069c565b6040516101d09190614151565b6102786102733660046141ec565b6107f9565b6040516101d09190614244565b6102986102933660046141ec565b6108e6565b6040516101d09190614257565b61024e6102b3366004613fcf565b61092a565b61024e6102c6366004613fcf565b610a01565b61024e6102d9366004613fcf565b610c9d565b6102f16102ec36600461426a565b610e5c565b6040516101d0929190614294565b61031261030d366004613ef0565b611048565b6040516101d09190614359565b61024e61032d366004613fcf565b611122565b61024e610340366004613fcf565b611217565b61034d61193f565b6040516101d0919061436c565b61024e610368366004613fcf565b611b22565b61024e61037b366004613fcf565b611bd4565b61024e6120a2565b61024e6103963660046143e1565b61219f565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d0565b6103d66103d1366004613ef0565b6124df565b6040516101d09190614530565b61024e6103f1366004614562565b61271a565b61024e610404366004614617565b6127e3565b6104116128ad565b6040516101d091906146bc565b6104266129a1565b6040516101d09190614731565b61024e6104413660046147ca565b612aaa565b6000828260405160200161045b929190614294565b6040516020818303038152906040528051906020012090505b92915050565b6000610474600583612abe565b61048f612ad9565b60005b818110156106975760008383838181106104ae576104ae6147e5565b90506020020160208101906104c391906141ec565b63ffffffff8181166000908152600d60209081526040808320805464010000000081049095168085526001820190935290832094955093909290916a010000000000000000000090910460ff16905b61051b83612b5c565b8110156105bb57811561057157600c60006105368584612b66565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556105b3565b6105b18663ffffffff16600c60006105928588612b6690919063ffffffff16565b8152602001908152602001600020600401612b7290919063ffffffff16565b505b600101610512565b508354640100000000900463ffffffff16600003610612576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff861660048201526024015b60405180910390fd5b63ffffffff85166000818152600d6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffff00000000000000000000001690558051938452908301919091527ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c1581703651910160405180910390a15050505050806001019050610492565b505050565b600e54606090640100000000900463ffffffff1660006106bd600183614843565b63ffffffff1667ffffffffffffffff8111156106db576106db613d26565b60405190808252806020026020018201604052801561076257816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816106f95790505b509050600060015b8363ffffffff168163ffffffff1610156107d65763ffffffff8082166000908152600d602052604090205416156107ce576107a481612b7e565b8383815181106107b6576107b66147e5565b6020026020010181905250816107cb90614860565b91505b60010161076a565b506107e2600184614843565b63ffffffff1681146107f2578082525b5092915050565b60408051808201909152600081526060602082015263ffffffff82166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161085d90614898565b80601f016020809104026020016040519081016040528092919081815260200182805461088990614898565b80156108d65780601f106108ab576101008083540402835291602001916108d6565b820191906000526020600020905b8154815290600101906020018083116108b957829003601f168201915b5050505050815250509050919050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c081019190915261047482612b7e565b610932612ad9565b60005b63ffffffff811682111561069757600083838363ffffffff1681811061095d5761095d6147e5565b905060200201602081019061097291906141ec565b63ffffffff81166000908152600b6020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559192506109bd6001830182613cb9565b505060405163ffffffff8216907fa59268ca81d40429e65ccea5385b59cf2d3fc6519371dee92f8eb1dae5107a7a90600090a2506109fa816148eb565b9050610935565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110610a3b57610a3b6147e5565b602090810292909201356000818152600c90935260409092206001810154929350919050610a98576040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260048101839052602401610609565b6000610aa682600401612b5c565b1115610afb57610ab96004820184612b66565b6040517f60a6d89800000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101839052604401610609565b805468010000000000000000900463ffffffff1615610b635780546040517f60b9df730000000000000000000000000000000000000000000000000000000081526801000000000000000090910463ffffffff16600482015260248101839052604401610609565b83158015610b9d5750805463ffffffff166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15610bd6576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6001810154610be790600790612b72565b506002810154610bf990600990612b72565b506000828152600c6020526040812080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815560018101829055600281018290559060048201818181610c4e8282613cf3565b5050505050507f5254e609a97bab37b7cc79fe128f85c097bd6015c6e1624ae0ba392eb975320582604051610c8591815260200190565b60405180910390a15050600101610a1f565b50505050565b610ca5612ad9565b60005b81811015610697576000838383818110610cc457610cc46147e5565b9050602002810190610cd6919061490e565b610cdf9061494c565b805190915073ffffffffffffffffffffffffffffffffffffffff16610d30576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815263ffffffff9095166000818152600b909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251919290916001820190610dbc9082614a06565b5050600e8054909150600090610dd79063ffffffff166148eb565b91906101000a81548163ffffffff021916908363ffffffff160217905550816000015173ffffffffffffffffffffffffffffffffffffffff168163ffffffff167f78e94ca80be2c30abc061b99e7eb8583b1254781734b1e3ce339abb57da2fe8e8460200151604051610e4a9190613f77565b60405180910390a35050600101610ca8565b63ffffffff8083166000908152600d60209081526040808320805464010000000090049094168084526001909401825280832085845260030190915281208054606093849390929091610eae90614898565b80601f0160208091040260200160405190810160405280929190818152602001828054610eda90614898565b8015610f275780601f10610efc57610100808354040283529160200191610f27565b820191906000526020600020905b815481529060010190602001808311610f0a57829003601f168201915b5050506000888152600260208190526040909120015492935060609262010000900473ffffffffffffffffffffffffffffffffffffffff1615915061103a905057600086815260026020819052604091829020015490517f8318ed5d00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526201000090910473ffffffffffffffffffffffffffffffffffffffff1690638318ed5d90602401600060405180830381865afa158015610ff1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110379190810190614b20565b90505b9093509150505b9250929050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c08101919091526040805160e0810182526000848152600c6020908152838220805463ffffffff8082168652640100000000820481168487018190526801000000000000000090920416858701526001820154606086015260028201546080860152835260030190529190912060a08201906110f790612e49565b815260200161111a600c6000868152602001908152602001600020600401612e49565b905292915050565b61112a612ad9565b60005b81811015610697576000838383818110611149576111496147e5565b905060200201359050611166816003612abe90919063ffffffff16565b61119f576040517fe181733f00000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b6111aa600582612e56565b6111e3576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b60405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a25060010161112d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110611251576112516147e5565b90506020028101906112639190614b8e565b61126c90614bc2565b6040808201516000908152600c6020908152828220805463ffffffff168352600b82528383208451808601909552805473ffffffffffffffffffffffffffffffffffffffff16855260018101805496975091959394939092840191906112d190614898565b80601f01602080910402602001604051908101604052809291908181526020018280546112fd90614898565b801561134a5780601f1061131f5761010080835404028352916020019161134a565b820191906000526020600020905b81548152906001019060200180831161132d57829003601f168201915b50505091909252505050600183015490915061139a5782604001516040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b841580156113bf5750805173ffffffffffffffffffffffffffffffffffffffff163314155b156113f8576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6020830151611433576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001820154602084015181146114b457602084015161145490600790612abe565b1561148b576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084015160018401556114a0600782612b72565b5060208401516114b290600790612e56565b505b606084015180516000036114f657806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c95565b8354600090859060049061151790640100000000900463ffffffff166148eb565b91906101000a81548163ffffffff021916908363ffffffff1602179055905060005b82518110156115fc5761156f838281518110611557576115576147e5565b60200260200101516003612abe90919063ffffffff16565b6115a757826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c95565b6115f38382815181106115bc576115bc6147e5565b60200260200101518760030160008563ffffffff1663ffffffff168152602001908152602001600020612e5690919063ffffffff16565b50600101611539565b50845468010000000000000000900463ffffffff16801561175d5763ffffffff8082166000908152600d60209081526040808320805464010000000090049094168352600190930181528282206002018054845181840281018401909552808552929392909183018282801561169157602002820191906000526020600020905b81548152602001906001019080831161167d575b5050505050905060005b815181101561175a576116f08282815181106116b9576116b96147e5565b60200260200101518960030160008763ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b61175257818181518110611706576117066147e5565b6020026020010151836040517f03dcd86200000000000000000000000000000000000000000000000000000000815260040161060992919091825263ffffffff16602082015260400190565b60010161169b565b50505b600061176b87600401612e49565b905060005b81518163ffffffff1610156118b1576000828263ffffffff1681518110611799576117996147e5565b60209081029190910181015163ffffffff8082166000908152600d8452604080822080546401000000009004909316825260019092018452818120600201805483518187028101870190945280845293955090939192909183018282801561182057602002820191906000526020600020905b81548152602001906001019080831161180c575b5050505050905060005b815181101561189d5761187f828281518110611848576118486147e5565b60200260200101518c60030160008a63ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b61189557818181518110611706576117066147e5565b60010161182a565b505050806118aa906148eb565b9050611770565b50875187547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90911690811788556040808a015160028a018190556020808c01518351928352908201527f4b5b465e22eea0c3d40c30e936643245b80d19b2dcf75788c0699fe8d8db645b910160405180910390a25050505050505050806001019050611235565b600e5460609063ffffffff166000611958600183614843565b63ffffffff1667ffffffffffffffff81111561197657611976613d26565b6040519080825280602002602001820160405280156119bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816119945790505b509050600060015b8363ffffffff168163ffffffff161015611b0c5763ffffffff81166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611b045763ffffffff81166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191611a5890614898565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8490614898565b8015611ad15780601f10611aa657610100808354040283529160200191611ad1565b820191906000526020600020905b815481529060010190602001808311611ab457829003601f168201915b505050505081525050838381518110611aec57611aec6147e5565b602002602001018190525081611b0190614860565b91505b6001016119c4565b50600e546107e29060019063ffffffff16614843565b611b2a612ad9565b60005b81811015610697576000838383818110611b4957611b496147e5565b9050602002810190611b5b9190614cd9565b611b6490614d1c565b90506000611b7a82600001518360200151610446565b9050611b87600382612e56565b611bc0576040517febf5255100000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b611bca8183612e62565b5050600101611b2d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110611c0e57611c0e6147e5565b9050602002810190611c209190614b8e565b611c2990614bc2565b805163ffffffff166000908152600b602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191611c7f90614898565b80601f0160208091040260200160405190810160405280929190818152602001828054611cab90614898565b8015611cf85780601f10611ccd57610100808354040283529160200191611cf8565b820191906000526020600020905b815481529060010190602001808311611cdb57829003601f168201915b50505091909252505081519192505073ffffffffffffffffffffffffffffffffffffffff16611d5e5781516040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff9091166004820152602401610609565b83158015611d835750805173ffffffffffffffffffffffffffffffffffffffff163314155b15611dbc576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6040808301516000908152600c60205220600181015415611e115782604001516040517f5461848300000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b6040830151611e545782604001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b60208301511580611e7157506020830151611e7190600790612abe565b15611ea8576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608301518051600003611eea57806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c95565b81548290600490611f0890640100000000900463ffffffff166148eb565b82546101009290920a63ffffffff818102199093169183160217909155825464010000000090041660005b8251811015611fde57611f51838281518110611557576115576147e5565b611f8957826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c95565b611fd5838281518110611f9e57611f9e6147e5565b60200260200101518560030160008563ffffffff1663ffffffff168152602001908152602001600020612e5690919063ffffffff16565b50600101611f33565b50845183547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff918216178455604086015160028501556020860151600185018190556120349160079190612e5616565b50604085015161204690600990612e56565b50845160408087015160208089015183519283529082015263ffffffff909216917f74becb12a5e8fd0e98077d02dfba8f647c9670c9df177e42c2418cf17a636f05910160405180910390a25050505050806001019050611bf2565b60015473ffffffffffffffffffffffffffffffffffffffff163314612123576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610609565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b8281146121e2576040517fab8b67c60000000000000000000000000000000000000000000000000000000081526004810184905260248101829052604401610609565b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156124d757600086868381811061221a5761221a6147e5565b905060200201602081019061222f91906141ec565b63ffffffff81166000908152600b6020526040902080549192509073ffffffffffffffffffffffffffffffffffffffff1661229e576040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff83166004820152602401610609565b60008686858181106122b2576122b26147e5565b90506020028101906122c4919061490e565b6122cd9061494c565b805190915073ffffffffffffffffffffffffffffffffffffffff1661231e576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815473ffffffffffffffffffffffffffffffffffffffff16331480159061235b57503373ffffffffffffffffffffffffffffffffffffffff861614155b15612394576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b8051825473ffffffffffffffffffffffffffffffffffffffff908116911614158061241057506020808201516040516123cd9201613f77565b60405160208183030381529060405280519060200120826001016040516020016123f79190614dc2565b6040516020818303038152906040528051906020012014155b156124c957805182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020810151600183019061246a9082614a06565b50806000015173ffffffffffffffffffffffffffffffffffffffff168363ffffffff167f86f41145bde5dd7f523305452e4aad3685508c181432ec733d5f345009358a2883602001516040516124c09190613f77565b60405180910390a35b5050508060010190506121fe565b505050505050565b6125206040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b6040805160e0810182528381526000848152600260209081529290208054919283019161254c90614898565b80601f016020809104026020016040519081016040528092919081815260200182805461257890614898565b80156125c55780601f1061259a576101008083540402835291602001916125c5565b820191906000526020600020905b8154815290600101906020018083116125a857829003601f168201915b505050505081526020016002600085815260200190815260200160002060010180546125f090614898565b80601f016020809104026020016040519081016040528092919081815260200182805461261c90614898565b80156126695780601f1061263e57610100808354040283529160200191612669565b820191906000526020600020905b81548152906001019060200180831161264c57829003601f168201915b50505091835250506000848152600260208181526040909220015491019060ff16600381111561269b5761269b61444d565b815260008481526002602081815260409092200154910190610100900460ff1660018111156126cc576126cc61444d565b81526000848152600260208181526040928390209091015462010000900473ffffffffffffffffffffffffffffffffffffffff169083015201612710600585612abe565b1515905292915050565b612722612ad9565b63ffffffff8089166000908152600d6020526040812054640100000000900490911690819003612786576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff8a166004820152602401610609565b6127d8888888886040518060a001604052808f63ffffffff168152602001876127ae906148eb565b97508763ffffffff1681526020018a1515815260200189151581526020018860ff168152506130f6565b505050505050505050565b6127eb612ad9565b600e805460009164010000000090910463ffffffff1690600461280d836148eb565b82546101009290920a63ffffffff81810219909316918316021790915581166000818152600d602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001684179055815160a08101835292835260019083015286151590820152841515606082015260ff841660808201529091506128a39089908990899089906130f6565b5050505050505050565b606060006128bb6003612e49565b90506000815167ffffffffffffffff8111156128d9576128d9613d26565b60405190808252806020026020018201604052801561294b57816020015b6129386040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b8152602001906001900390816128f75790505b50905060005b82518110156107f25761297c83828151811061296f5761296f6147e5565b60200260200101516124df565b82828151811061298e5761298e6147e5565b6020908102919091010152600101612951565b606060006129af6009612e49565b90506000815167ffffffffffffffff8111156129cd576129cd613d26565b604051908082528060200260200182016040528015612a5457816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816129eb5790505b50905060005b82518110156107f257612a85838281518110612a7857612a786147e5565b6020026020010151611048565b828281518110612a9757612a976147e5565b6020908102919091010152600101612a5a565b612ab2612ad9565b612abb8161391b565b50565b600081815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612b5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610609565b565b6000610474825490565b6000612ad28383613a10565b6000612ad28383613a3a565b6040805160e0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840181905260c084015263ffffffff8581168352600d8252848320805464010000000090049091168084526001909101825284832060028101805487518186028101860190985280885295969295919493909190830182828015612c2f57602002820191906000526020600020905b815481526020019060010190808311612c1b575b505050505090506000815167ffffffffffffffff811115612c5257612c52613d26565b604051908082528060200260200182016040528015612c9857816020015b604080518082019091526000815260606020820152815260200190600190039081612c705790505b50905060005b8151811015612db0576040518060400160405280848381518110612cc457612cc46147e5565b60200260200101518152602001856003016000868581518110612ce957612ce96147e5565b602002602001015181526020019081526020016000208054612d0a90614898565b80601f0160208091040260200160405190810160405280929190818152602001828054612d3690614898565b8015612d835780601f10612d5857610100808354040283529160200191612d83565b820191906000526020600020905b815481529060010190602001808311612d6657829003601f168201915b5050505050815250828281518110612d9d57612d9d6147e5565b6020908102919091010152600101612c9e565b506040805160e08101825263ffffffff8089166000818152600d6020818152868320548086168752948b168187015260ff680100000000000000008604811697870197909752690100000000000000000085048716151560608701529290915290526a010000000000000000000090049091161515608082015260a08101612e3785612e49565b81526020019190915295945050505050565b60606000612ad283613b2d565b6000612ad28383613b89565b608081015173ffffffffffffffffffffffffffffffffffffffff1615612fb057608081015173ffffffffffffffffffffffffffffffffffffffff163b1580612f5b575060808101516040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f78bea72100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff909116906301ffc9a790602401602060405180830381865afa158015612f35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f599190614e70565b155b15612fb05760808101516040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610609565b600082815260026020526040902081518291908190612fcf9082614a06565b5060208201516001820190612fe49082614a06565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660018360038111156130265761302661444d565b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010083600181111561306d5761306d61444d565b0217905550608091909101516002909101805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff90921691909117905560405182907f04f0a9bcf3f3a3b42a4d7ca081119755f82ebe43e0d30c8f7292c4fe0dc4a2ae90600090a25050565b805163ffffffff9081166000908152600d602090815260408083208286015190941683526001909301905220608082015160ff161580613148575060808201518590613143906001614e8d565b60ff16115b156131915760808201516040517f25b4d61800000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101869052604401610609565b6001826020015163ffffffff16111561327957815163ffffffff166000908152600d6020908152604082209084015160019182019183916131d29190614843565b63ffffffff1663ffffffff168152602001908152602001600020905060005b6131fa82612b5c565b81101561327657613229846000015163ffffffff16600c60006105928587600001612b6690919063ffffffff16565b50600c60006132388484612b66565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556001016131f1565b50505b60005b858110156134b3576132a9878783818110613299576132996147e5565b8592602090910201359050612e56565b61330a5782518787838181106132c1576132c16147e5565b6040517f636e405700000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b82606001511561346157825163ffffffff16600c6000898985818110613332576133326147e5565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff16148015906133ac5750600c600088888481811061337d5761337d6147e5565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff1615155b1561340e5782518787838181106133c5576133c56147e5565b6040517f60b9df7300000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8251600c6000898985818110613426576134266147e5565b90506020020135815260200190815260200160002060000160086101000a81548163ffffffff021916908363ffffffff1602179055506134ab565b82516134a99063ffffffff16600c60008a8a86818110613483576134836147e5565b905060200201358152602001908152602001600020600401612e5690919063ffffffff16565b505b60010161327c565b5060005b838110156138c157368585838181106134d2576134d26147e5565b90506020028101906134e4919061490e565b90506134f260038235612abe565b61352b576040517fe181733f00000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b61353760058235612abe565b15613571576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b803560009081526003840160205260408120805461358e90614898565b905011156135da5783516040517f3927d08000000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015281356024820152604401610609565b60005b878110156136e4576136818235600c60008c8c86818110613600576136006147e5565b9050602002013581526020019081526020016000206003016000600c60008e8e88818110613630576136306147e5565b90506020020135815260200190815260200160002060000160049054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b6136dc57888882818110613697576136976147e5565b6040517fa7e792500000000000000000000000000000000000000000000000000000000081526020909102929092013560048301525082356024820152604401610609565b6001016135dd565b506002830180546001810182556000918252602091829020833591015561370d90820182614ea6565b8235600090815260038601602052604090209161372b919083614f0b565b50604080850151855163ffffffff9081166000908152600d602090815284822080549415156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff90951694909417909355606088015188518316825284822080549115156a0100000000000000000000027fffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff9092169190911790556080880151885183168252848220805460ff9290921668010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff909216919091179055828801805189518416835294909120805494909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff909416939093179055855191516138b892918435908c908c9061387e90880188614ea6565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613bd892505050565b506001016134b7565b50815160208301516040517ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c15817036519261390b92909163ffffffff92831681529116602082015260400190565b60405180910390a1505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361399a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610609565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613a2757613a276147e5565b9060005260206000200154905092915050565b60008181526001830160205260408120548015613b23576000613a5e600183615026565b8554909150600090613a7290600190615026565b9050818114613ad7576000866000018281548110613a9257613a926147e5565b9060005260206000200154905080876000018481548110613ab557613ab56147e5565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613ae857613ae8615039565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610474565b6000915050610474565b606081600001805480602002602001604051908101604052809291908181526020018280548015613b7d57602002820191906000526020600020905b815481526020019060010190808311613b69575b50505050509050919050565b6000818152600183016020526040812054613bd057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610474565b506000610474565b6000848152600260208190526040909120015462010000900473ffffffffffffffffffffffffffffffffffffffff16156124d757600084815260026020819052604091829020015490517ffba64a7c0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169063fba64a7c90613c7f908690869086908b908d90600401615068565b600060405180830381600087803b158015613c9957600080fd5b505af1158015613cad573d6000803e3d6000fd5b50505050505050505050565b508054613cc590614898565b6000825580601f10613cd5575050565b601f016020900490600052602060002090810190612abb9190613d0d565b5080546000825590600052602060002090810190612abb91905b5b80821115613d225760008155600101613d0e565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613d7857613d78613d26565b60405290565b60405160a0810167ffffffffffffffff81118282101715613d7857613d78613d26565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613de857613de8613d26565b604052919050565b600067ffffffffffffffff821115613e0a57613e0a613d26565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613e4757600080fd5b8135613e5a613e5582613df0565b613da1565b818152846020838601011115613e6f57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613e9f57600080fd5b823567ffffffffffffffff80821115613eb757600080fd5b613ec386838701613e36565b93506020850135915080821115613ed957600080fd5b50613ee685828601613e36565b9150509250929050565b600060208284031215613f0257600080fd5b5035919050565b60005b83811015613f24578181015183820152602001613f0c565b50506000910152565b60008151808452613f45816020860160208601613f09565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612ad26020830184613f2d565b60008083601f840112613f9c57600080fd5b50813567ffffffffffffffff811115613fb457600080fd5b6020830191508360208260051b850101111561104157600080fd5b60008060208385031215613fe257600080fd5b823567ffffffffffffffff811115613ff957600080fd5b61400585828601613f8a565b90969095509350505050565b60008151808452602080850194506020840160005b8381101561404257815187529582019590820190600101614026565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b848110156140ca578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051845284015160408585018190526140b681860183613f2d565b9a86019a945050509083019060010161406a565b5090979650505050505050565b600063ffffffff8083511684528060208401511660208501525060ff604083015116604084015260608201511515606084015260808201511515608084015260a082015160e060a085015261412f60e0850182614011565b905060c083015184820360c0860152614148828261404d565b95945050505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526141b48583516140d7565b9450928501929085019060010161417a565b5092979650505050505050565b803563ffffffff811681146141e757600080fd5b919050565b6000602082840312156141fe57600080fd5b612ad2826141d3565b73ffffffffffffffffffffffffffffffffffffffff8151168252600060208201516040602085015261423c6040850182613f2d565b949350505050565b602081526000612ad26020830184614207565b602081526000612ad260208301846140d7565b6000806040838503121561427d57600080fd5b614286836141d3565b946020939093013593505050565b6040815260006142a76040830185613f2d565b82810360208401526141488185613f2d565b600063ffffffff808351168452602081818501511681860152816040850151166040860152606084015160608601526080840151608086015260a0840151915060e060a086015261430d60e0860183614011565b60c08581015187830391880191909152805180835290830193506000918301905b8083101561434e578451825293830193600192909201919083019061432e565b509695505050505050565b602081526000612ad260208301846142b9565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526143cf858351614207565b94509285019290850190600101614395565b600080600080604085870312156143f757600080fd5b843567ffffffffffffffff8082111561440f57600080fd5b61441b88838901613f8a565b9096509450602087013591508082111561443457600080fd5b5061444187828801613f8a565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b805182526000602082015160e0602085015261449b60e0850182613f2d565b9050604083015184820360408601526144b48282613f2d565b9150506060830151600481106144cc576144cc61444d565b60608501526080830151600281106144e6576144e661444d565b8060808601525060a083015161451460a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015161452860c086018215159052565b509392505050565b602081526000612ad2602083018461447c565b8015158114612abb57600080fd5b803560ff811681146141e757600080fd5b60008060008060008060008060c0898b03121561457e57600080fd5b614587896141d3565b9750602089013567ffffffffffffffff808211156145a457600080fd5b6145b08c838d01613f8a565b909950975060408b01359150808211156145c957600080fd5b506145d68b828c01613f8a565b90965094505060608901356145ea81614543565b925060808901356145fa81614543565b915061460860a08a01614551565b90509295985092959890939650565b600080600080600080600060a0888a03121561463257600080fd5b873567ffffffffffffffff8082111561464a57600080fd5b6146568b838c01613f8a565b909950975060208a013591508082111561466f57600080fd5b5061467c8a828b01613f8a565b909650945050604088013561469081614543565b925060608801356146a081614543565b91506146ae60808901614551565b905092959891949750929550565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261471f85835161447c565b945092850192908501906001016146e5565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526147948583516142b9565b9450928501929085019060010161475a565b803573ffffffffffffffffffffffffffffffffffffffff811681146141e757600080fd5b6000602082840312156147dc57600080fd5b612ad2826147a6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff8281168282160390808211156107f2576107f2614814565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361489157614891614814565b5060010190565b600181811c908216806148ac57607f821691505b6020821081036148e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600063ffffffff80831681810361490457614904614814565b6001019392505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261494257600080fd5b9190910192915050565b60006040823603121561495e57600080fd5b6040516040810167ffffffffffffffff828210818311171561498257614982613d26565b8160405261498f856147a6565b835260208501359150808211156149a557600080fd5b506149b236828601613e36565b60208301525092915050565b601f821115610697576000816000526020600020601f850160051c810160208610156149e75750805b601f850160051c820191505b818110156124d7578281556001016149f3565b815167ffffffffffffffff811115614a2057614a20613d26565b614a3481614a2e8454614898565b846149be565b602080601f831160018114614a875760008415614a515750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556124d7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614ad457888601518255948401946001909101908401614ab5565b5085821015614b1057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215614b3257600080fd5b815167ffffffffffffffff811115614b4957600080fd5b8201601f81018413614b5a57600080fd5b8051614b68613e5582613df0565b818152856020838501011115614b7d57600080fd5b614148826020830160208601613f09565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183360301811261494257600080fd5b600060808236031215614bd457600080fd5b614bdc613d55565b614be5836141d3565b81526020808401358183015260408401356040830152606084013567ffffffffffffffff80821115614c1657600080fd5b9085019036601f830112614c2957600080fd5b813581811115614c3b57614c3b613d26565b8060051b9150614c4c848301613da1565b8181529183018401918481019036841115614c6657600080fd5b938501935b83851015614c8457843582529385019390850190614c6b565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614ccd57835183529284019291840191600101614cb1565b50909695505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261494257600080fd5b8035600281106141e757600080fd5b600060a08236031215614d2e57600080fd5b614d36613d7e565b823567ffffffffffffffff80821115614d4e57600080fd5b614d5a36838701613e36565b83526020850135915080821115614d7057600080fd5b50614d7d36828601613e36565b602083015250604083013560048110614d9557600080fd5b6040820152614da660608401614d0d565b6060820152614db7608084016147a6565b608082015292915050565b6000602080835260008454614dd681614898565b8060208701526040600180841660008114614df85760018114614e3257614e62565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550614e62565b89600052602060002060005b85811015614e595781548b8201860152908301908801614e3e565b8a016040019650505b509398975050505050505050565b600060208284031215614e8257600080fd5b8151612ad281614543565b60ff818116838216019081111561047457610474614814565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614edb57600080fd5b83018035915067ffffffffffffffff821115614ef657600080fd5b60200191503681900382131561104157600080fd5b67ffffffffffffffff831115614f2357614f23613d26565b614f3783614f318354614898565b836149be565b6000601f841160018114614f895760008515614f535750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561501f565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015614fd85786850135825560209485019460019092019101614fb8565b5086821015615013577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8181038181111561047457610474614814565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6080815284608082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8611156150a157600080fd5b8560051b808860a0850137820182810360a090810160208501526150c790820187613f2d565b91505063ffffffff8085166040840152808416606084015250969550505050505056fea164736f6c6343000818000a", } var CapabilitiesRegistryABI = CapabilitiesRegistryMetaData.ABI diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index cae02cda28..5b2288e4fa 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,5 +1,5 @@ GETH_VERSION: 1.13.8 -capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin 6d2e3aa3a6f3aed2cf24b613743bb9ae4b9558f48a6864dc03b8b0ebb37235e3 +capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin bb794cc0042784b060d1d63090e2086670b88ba3685067cd436305f36054c82b feeds_consumer: ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin 8c3a2b18a80be41e7c40d2bc3a4c8d1b5e18d55c1fd20ad5af68cebb66109fc5 forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin 45d9b866c64b41c1349a90b6764aee42a6d078b454d38f369b5fe02b23b9d16e ocr3_capability: ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.bin 8bf0f53f222efce7143dea6134552eb26ea1eef845407b4475a0d79b7d7ba9f8 From 288257a4f0a0ab714630f266c32953a2b0619c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Fri, 9 Aug 2024 22:07:17 +0900 Subject: [PATCH 073/432] multi-chain fixes (#14077) * ocr2: Shouldn't require "publicKey" under the multi-chain codepath * ocr2: Use parent ocrKeyBundleID for publicKey when using multi-chain --- .../__snapshots__/88_gen_jobspecs_test.snap | 4 -- core/scripts/keystone/templates/oracle.toml | 1 - core/services/ocr2/delegate.go | 2 +- core/services/ocr2/validate/validate.go | 19 ------ core/services/ocr2/validate/validate_test.go | 60 ------------------- core/services/ocrcommon/adapters.go | 5 +- core/services/ocrcommon/adapters_test.go | 4 +- 7 files changed, 5 insertions(+), 90 deletions(-) diff --git a/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap b/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap index 21e28f3801..a4b4e6e302 100755 --- a/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap +++ b/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap @@ -39,7 +39,6 @@ telemetryType = "plugin" [onchainSigningStrategy] strategyName = 'single-chain' [onchainSigningStrategy.config] -publicKey = '8fa807463ad73f9ee855cfd60ba406dcf98a2855b3dd8af613107b0f6890a707' -------------------------------- Oracle 1: @@ -69,7 +68,6 @@ telemetryType = "plugin" [onchainSigningStrategy] strategyName = 'single-chain' [onchainSigningStrategy.config] -publicKey = '8fa807463ad73f9ee855cfd60ba406dcf98a2855b3dd8af613107b0f6890a707' -------------------------------- Oracle 2: @@ -99,7 +97,6 @@ telemetryType = "plugin" [onchainSigningStrategy] strategyName = 'single-chain' [onchainSigningStrategy.config] -publicKey = '8fa807463ad73f9ee855cfd60ba406dcf98a2855b3dd8af613107b0f6890a707' -------------------------------- Oracle 3: @@ -129,7 +126,6 @@ telemetryType = "plugin" [onchainSigningStrategy] strategyName = 'single-chain' [onchainSigningStrategy.config] -publicKey = '8fa807463ad73f9ee855cfd60ba406dcf98a2855b3dd8af613107b0f6890a707' --- diff --git a/core/scripts/keystone/templates/oracle.toml b/core/scripts/keystone/templates/oracle.toml index f5d539873f..6049ad925d 100644 --- a/core/scripts/keystone/templates/oracle.toml +++ b/core/scripts/keystone/templates/oracle.toml @@ -23,4 +23,3 @@ telemetryType = "plugin" [onchainSigningStrategy] strategyName = 'single-chain' [onchainSigningStrategy.config] -publicKey = '8fa807463ad73f9ee855cfd60ba406dcf98a2855b3dd8af613107b0f6890a707' diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 5c44825ca2..f53ceaefa1 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -772,7 +772,7 @@ func (d *Delegate) newServicesGenericPlugin( } keyBundles[name] = os } - onchainKeyringAdapter, err = ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(keyBundles, lggr) + onchainKeyringAdapter, err = ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(keyBundles, kb.PublicKey(), lggr) if err != nil { return nil, err } diff --git a/core/services/ocr2/validate/validate.go b/core/services/ocr2/validate/validate.go index 8d98a28267..a224249e1e 100644 --- a/core/services/ocr2/validate/validate.go +++ b/core/services/ocr2/validate/validate.go @@ -197,18 +197,6 @@ func (o *OCR2OnchainSigningStrategy) IsMultiChain() bool { return o.StrategyName == "multi-chain" } -func (o *OCR2OnchainSigningStrategy) PublicKey() (string, error) { - pk, ok := o.Config["publicKey"] - if !ok { - return "", nil - } - pkString, ok := pk.(string) - if !ok { - return "", fmt.Errorf("expected string publicKey value, but got: %T", pk) - } - return pkString, nil -} - func (o *OCR2OnchainSigningStrategy) ConfigCopy() job.JSONConfig { copiedConfig := make(job.JSONConfig) for k, v := range o.Config { @@ -251,13 +239,6 @@ func validateGenericPluginSpec(ctx context.Context, spec *job.OCR2OracleSpec, rc if err != nil { return err } - pk, ossErr := onchainSigningStrategy.PublicKey() - if ossErr != nil { - return ossErr - } - if pk == "" { - return errors.New("generic config invalid: must provide public key for the onchain signing strategy") - } } plugEnv := env.NewPlugin(p.PluginName) diff --git a/core/services/ocr2/validate/validate_test.go b/core/services/ocr2/validate/validate_test.go index b92752c647..1356e0db62 100644 --- a/core/services/ocr2/validate/validate_test.go +++ b/core/services/ocr2/validate/validate_test.go @@ -49,7 +49,6 @@ chainID = 1337 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] juelsPerFeeCoinSource = """ ds1 [type=bridge name=voter_turnout]; @@ -105,7 +104,6 @@ chainID = 1337 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] juelsPerFeeCoinSource = """ ds1 [type=bridge name=voter_turnout]; @@ -150,7 +148,6 @@ chainID = 1337 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -174,7 +171,6 @@ chainID = 1337 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -200,7 +196,6 @@ chainID = 1337 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -226,7 +221,6 @@ chainID = 1337 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -253,7 +247,6 @@ chainID = 1337 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -279,7 +272,6 @@ chainID = 1337 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -303,7 +295,6 @@ chainID = 1337 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -344,7 +335,6 @@ answer1 [type=median index=0]; strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] juelsPerFeeCoinSource = """ ds1 [type=bridge name=voter_turnout]; @@ -383,7 +373,6 @@ answer1 [type=median index=0]; strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] juelsPerFeeCoinSource = """ -> @@ -415,7 +404,6 @@ answer1 [type=median index=0]; strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] juelsPerFeeCoinSource = """ ds1 [type=bridge name=voter_turnout]; @@ -429,46 +417,6 @@ chainID = 1337 require.Contains(t, err.Error(), "no such relay blerg supported") }, }, - { - name: "Generic public onchain signing strategy with no public key", - toml: ` -type = "offchainreporting2" -pluginType = "plugin" -schemaVersion = 1 -relay = "evm" -contractID = "0x613a38AC1659769640aaE063C651F48E0250454C" -p2pPeerID = "12D3KooWHfYFQ8hGttAYbMCevQVESEQhzJAqFZokMVtom8bNxwGq" -p2pv2Bootstrappers = [ -"12D3KooWHfYFQ8hGttAYbMCevQVESEQhzJAqFZokMVtom8bNxwGq@127.0.0.1:5001", -] -ocrKeyBundleID = "73e8966a78ca09bb912e9565cfb79fbe8a6048fab1f0cf49b18047c3895e0447" -monitoringEndpoint = "chain.link:4321" -transmitterID = "0xF67D0290337bca0847005C7ffD1BC75BA9AAE6e4" -observationTimeout = "10s" -observationSource = """ -ds1 [type=bridge name=voter_turnout]; -ds1_parse [type=jsonparse path="one,two"]; -ds1_multiply [type=multiply times=1.23]; -ds1 -> ds1_parse -> ds1_multiply -> answer1; -answer1 [type=median index=0]; -""" -[relayConfig] -chainID = 1337 -[onchainSigningStrategy] -strategyName = "single-chain" -[onchainSigningStrategy.config] -evm = "" -publicKey = "" -[pluginConfig] -pluginName = "median" -telemetryType = "median" -OCRVersion=2 -`, - assertion: func(t *testing.T, os job.Job, err error) { - require.Error(t, err) - require.Contains(t, err.Error(), "must provide public key for the onchain signing strategy") - }, - }, { name: "Generic plugin config validation - nothing provided", toml: ` @@ -493,7 +441,6 @@ chainID = 4 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, @@ -525,7 +472,6 @@ chainID = 4 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] PluginName="some random name" @@ -559,7 +505,6 @@ chainID = 4 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] PluginName="some random name" @@ -594,7 +539,6 @@ chainID = 4 strategyName = "single-chain" [onchainSigningStrategy.config] evm = "" -publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] PluginName="some random name" @@ -712,7 +656,6 @@ func TestOCR2OnchainSigningStrategy_Unmarshal(t *testing.T) { strategyName = "single-chain" [onchainSigningStrategy.config] evm = "08d14c6eed757414d72055d28de6caf06535806c6a14e450f3a2f1c854420e17" -publicKey = "0x1234567890123456789012345678901234567890" ` oss := &envelope2{} tree, err := toml.Load(payload) @@ -725,12 +668,9 @@ publicKey = "0x1234567890123456789012345678901234567890" err = json.Unmarshal(b, oss) require.NoError(t, err) - pk, err := oss.OnchainSigningStrategy.PublicKey() - require.NoError(t, err) kbID, err := oss.OnchainSigningStrategy.KeyBundleID("evm") require.NoError(t, err) assert.False(t, oss.OnchainSigningStrategy.IsMultiChain()) - assert.Equal(t, "0x1234567890123456789012345678901234567890", pk) assert.Equal(t, "08d14c6eed757414d72055d28de6caf06535806c6a14e450f3a2f1c854420e17", kbID) } diff --git a/core/services/ocrcommon/adapters.go b/core/services/ocrcommon/adapters.go index 372d9e37f1..53e62be9a0 100644 --- a/core/services/ocrcommon/adapters.go +++ b/core/services/ocrcommon/adapters.go @@ -87,12 +87,11 @@ type OCR3OnchainKeyringMultiChainAdapter struct { lggr logger.Logger } -func NewOCR3OnchainKeyringMultiChainAdapter(ost map[string]ocr2key.KeyBundle, lggr logger.Logger) (*OCR3OnchainKeyringMultiChainAdapter, error) { +func NewOCR3OnchainKeyringMultiChainAdapter(ost map[string]ocr2key.KeyBundle, publicKey ocrtypes.OnchainPublicKey, lggr logger.Logger) (*OCR3OnchainKeyringMultiChainAdapter, error) { if len(ost) == 0 { return nil, errors.New("no key bundles provided") } - // We don't need to check for the existence of `publicKey` in the keyBundles map because it is required on validation on `validate/validate.go` - return &OCR3OnchainKeyringMultiChainAdapter{ost, ost["publicKey"].PublicKey(), lggr}, nil + return &OCR3OnchainKeyringMultiChainAdapter{ost, publicKey, lggr}, nil } func (a *OCR3OnchainKeyringMultiChainAdapter) PublicKey() ocrtypes.OnchainPublicKey { diff --git a/core/services/ocrcommon/adapters_test.go b/core/services/ocrcommon/adapters_test.go index fed854b0b3..e7d4562729 100644 --- a/core/services/ocrcommon/adapters_test.go +++ b/core/services/ocrcommon/adapters_test.go @@ -162,9 +162,9 @@ publicKey = "pub-key" keyBundles[name] = os } - adapter, err := ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(keyBundles, logger.TestLogger(t)) + adapter, err := ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(keyBundles, pk, logger.TestLogger(t)) require.NoError(t, err) - _, err = ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(map[string]ocr2key.KeyBundle{}, logger.TestLogger(t)) + _, err = ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(map[string]ocr2key.KeyBundle{}, pk, logger.TestLogger(t)) require.Error(t, err, "no key bundles provided") sig, err := adapter.Sign(configDigest, seqNr, reportInfo) From 349778bbc6048bbea7e6ac0ae711126922bfe1f5 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Fri, 9 Aug 2024 16:16:24 +0200 Subject: [PATCH 074/432] add missing step id to action (#14088) * add missing step id * do not fail if Slither fails * try with not failing generation --- .github/workflows/solidity-foundry-artifacts.yml | 1 + contracts/scripts/ci/generate_slither_report.sh | 14 ++++++-------- contracts/scripts/ci/generate_uml.sh | 2 +- contracts/scripts/ci/select_solc_version.sh | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/solidity-foundry-artifacts.yml b/.github/workflows/solidity-foundry-artifacts.yml index e489033d67..50a77e2846 100644 --- a/.github/workflows/solidity-foundry-artifacts.yml +++ b/.github/workflows/solidity-foundry-artifacts.yml @@ -118,6 +118,7 @@ jobs: fetch-depth: 0 - name: Extract Foundry version + id: extract-foundry-version uses: ./.github/actions/detect-solidity-foundry-version with: working-directory: contracts diff --git a/contracts/scripts/ci/generate_slither_report.sh b/contracts/scripts/ci/generate_slither_report.sh index 7fe31d40ef..bc876ae118 100755 --- a/contracts/scripts/ci/generate_slither_report.sh +++ b/contracts/scripts/ci/generate_slither_report.sh @@ -44,15 +44,13 @@ run_slither() { >&2 echo "::error::Failed to select Solc version for $FILE" return 1 fi - set -e SLITHER_OUTPUT_FILE="$TARGET_DIR/$(basename "${FILE%.sol}")-slither-report.md" - - output=$(slither --config-file "$CONFIG_FILE" "$FILE" --checklist --markdown-root "$REPO_URL" --fail-none $SLITHER_EXTRA_PARAMS) - if [ $? -ne 0 ]; then - >&2 echo "::error::Slither failed for $FILE" - exit 1 + if ! output=$(slither --config-file "$CONFIG_FILE" "$FILE" --checklist --markdown-root "$REPO_URL" --fail-none $SLITHER_EXTRA_PARAMS); then + >&2 echo "::warning::Slither failed for $FILE" + return 0 fi + set -e output=$(echo "$output" | sed '/\*\*THIS CHECKLIST IS NOT COMPLETE\*\*. Use `--show-ignored-findings` to show all the results./d' | sed '/Summary/d') echo "# Summary for $FILE" > "$SLITHER_OUTPUT_FILE" @@ -80,8 +78,8 @@ set +e process_files "$SOURCE_DIR" "$TARGET_DIR" "${FILES[@]}" if [[ $? -ne 0 ]]; then - >&2 echo "::error::Failed to generate Slither reports" - exit 1 + >&2 echo "::warning::Failed to generate some Slither reports" + exit 0 fi echo "Slither reports saved in $TARGET_DIR folder" diff --git a/contracts/scripts/ci/generate_uml.sh b/contracts/scripts/ci/generate_uml.sh index 65745c93bb..c71d0a1ac7 100755 --- a/contracts/scripts/ci/generate_uml.sh +++ b/contracts/scripts/ci/generate_uml.sh @@ -88,7 +88,7 @@ process_selected_files() { MATCHES=($(find "$SOURCE_DIR" -type f -path "*/$FILE")) if [[ ${#MATCHES[@]} -gt 1 ]]; then - >&2 echo "Error: Multiple matches found for $FILE:" + >&2 echo "::error:: Multiple matches found for $FILE:" for MATCH in "${MATCHES[@]}"; do >&2 echo " $MATCH" done diff --git a/contracts/scripts/ci/select_solc_version.sh b/contracts/scripts/ci/select_solc_version.sh index 3f7d7864ab..cfa13de0f6 100755 --- a/contracts/scripts/ci/select_solc_version.sh +++ b/contracts/scripts/ci/select_solc_version.sh @@ -66,7 +66,7 @@ set +e SOLCVER=$(extract_pragma "$FILE") if [[ $? -ne 0 ]]; then - echo "Error: Failed to extract the Solidity version from $FILE." + >&2 echo "::error:: Failed to extract the Solidity version from $FILE." return 1 fi From 95cb692500218a337f5ba05771d240abd9c01c62 Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Fri, 9 Aug 2024 07:54:01 -0700 Subject: [PATCH 075/432] [KS-421] Improve logging from remote capabilities (#14058) Add validations and sanitizing --- core/capabilities/remote/dispatcher.go | 2 +- core/capabilities/remote/target/client.go | 11 +++-- .../capabilities/remote/target/client_test.go | 14 ++++-- .../remote/target/endtoend_test.go | 4 +- .../remote/target/request/client_request.go | 2 +- .../target/request/client_request_test.go | 9 +++- .../remote/target/request/server_request.go | 2 +- core/capabilities/remote/target/server.go | 25 ++++++++--- .../capabilities/remote/target/server_test.go | 16 +++---- core/capabilities/remote/trigger_publisher.go | 6 ++- .../capabilities/remote/trigger_subscriber.go | 4 +- .../remote/trigger_subscriber_test.go | 5 +-- core/capabilities/remote/utils.go | 43 +++++++++++++++++++ core/capabilities/remote/utils_test.go | 23 ++++++++++ 14 files changed, 132 insertions(+), 34 deletions(-) diff --git a/core/capabilities/remote/dispatcher.go b/core/capabilities/remote/dispatcher.go index c1ee5db294..dab4f6c98b 100644 --- a/core/capabilities/remote/dispatcher.go +++ b/core/capabilities/remote/dispatcher.go @@ -180,7 +180,7 @@ func (d *dispatcher) receive() { receiver, ok := d.receivers[k] d.mu.RUnlock() if !ok { - d.lggr.Debugw("received message for unregistered capability", "capabilityId", k.capId, "donId", k.donId) + d.lggr.Debugw("received message for unregistered capability", "capabilityId", SanitizeLogString(k.capId), "donId", k.donId) d.tryRespondWithError(msg.Sender, body, types.Error_CAPABILITY_NOT_FOUND) continue } diff --git a/core/capabilities/remote/target/client.go b/core/capabilities/remote/target/client.go index 5b65bf63e4..4273169d23 100644 --- a/core/capabilities/remote/target/client.go +++ b/core/capabilities/remote/target/client.go @@ -9,6 +9,7 @@ import ( commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/target/request" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -151,7 +152,11 @@ func (c *client) Receive(ctx context.Context, msg *types.MessageBody) { c.mutex.Lock() defer c.mutex.Unlock() - messageID := GetMessageID(msg) + messageID, err := GetMessageID(msg) + if err != nil { + c.lggr.Errorw("invalid message ID", "err", err, "id", remote.SanitizeLogString(string(msg.MessageId))) + return + } c.lggr.Debugw("Remote client target receiving message", "messageID", messageID) @@ -167,8 +172,8 @@ func (c *client) Receive(ctx context.Context, msg *types.MessageBody) { } func GetMessageIDForRequest(req commoncap.CapabilityRequest) (string, error) { - if req.Metadata.WorkflowID == "" || req.Metadata.WorkflowExecutionID == "" { - return "", errors.New("workflow ID and workflow execution ID must be set in request metadata") + if !remote.IsValidWorkflowOrExecutionID(req.Metadata.WorkflowID) || !remote.IsValidWorkflowOrExecutionID(req.Metadata.WorkflowExecutionID) { + return "", errors.New("workflow ID and workflow execution ID in request metadata are invalid") } return req.Metadata.WorkflowID + req.Metadata.WorkflowExecutionID, nil diff --git a/core/capabilities/remote/target/client_test.go b/core/capabilities/remote/target/client_test.go index 6d26b51b8a..2198636a7a 100644 --- a/core/capabilities/remote/target/client_test.go +++ b/core/capabilities/remote/target/client_test.go @@ -21,6 +21,11 @@ import ( p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) +const ( + workflowID1 = "15c631d295ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0" + workflowExecutionID1 = "95ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0abbadeed" +) + func Test_Client_DonTopologies(t *testing.T) { ctx := testutils.Context(t) @@ -192,8 +197,8 @@ func testClient(ctx context.Context, t *testing.T, numWorkflowPeers int, workflo responseCh, err := caller.Execute(ctx, commoncap.CapabilityRequest{ Metadata: commoncap.RequestMetadata{ - WorkflowID: "workflowID", - WorkflowExecutionID: "workflowExecutionID", + WorkflowID: workflowID1, + WorkflowExecutionID: workflowExecutionID1, }, Config: transmissionSchedule, Inputs: executeInputs, @@ -234,7 +239,10 @@ func (t *clientTestServer) Receive(_ context.Context, msg *remotetypes.MessageBo defer t.mux.Unlock() sender := toPeerID(msg.Sender) - messageID := target.GetMessageID(msg) + messageID, err := target.GetMessageID(msg) + if err != nil { + panic(err) + } if t.messageIDToSenders[messageID] == nil { t.messageIDToSenders[messageID] = make(map[p2ptypes.PeerID]bool) diff --git a/core/capabilities/remote/target/endtoend_test.go b/core/capabilities/remote/target/endtoend_test.go index cfab50f0fe..31bdc83e26 100644 --- a/core/capabilities/remote/target/endtoend_test.go +++ b/core/capabilities/remote/target/endtoend_test.go @@ -261,8 +261,8 @@ func testRemoteTarget(ctx context.Context, t *testing.T, underlying commoncap.Ta responseCh, err := caller.Execute(ctx, commoncap.CapabilityRequest{ Metadata: commoncap.RequestMetadata{ - WorkflowID: "workflowID", - WorkflowExecutionID: "workflowExecutionID", + WorkflowID: workflowID1, + WorkflowExecutionID: workflowExecutionID1, }, Config: transmissionSchedule, Inputs: executeInputs, diff --git a/core/capabilities/remote/target/request/client_request.go b/core/capabilities/remote/target/request/client_request.go index 50a742c218..0370fd229c 100644 --- a/core/capabilities/remote/target/request/client_request.go +++ b/core/capabilities/remote/target/request/client_request.go @@ -170,7 +170,7 @@ func (c *ClientRequest) OnMessage(_ context.Context, msg *types.MessageBody) err } } } else { - c.lggr.Warnw("received error response", "error", msg.ErrorMsg) + c.lggr.Warnw("received error response", "error", remote.SanitizeLogString(msg.ErrorMsg)) c.errorCount[msg.ErrorMsg]++ if c.errorCount[msg.ErrorMsg] == c.requiredIdenticalResponses { c.sendResponse(commoncap.CapabilityResponse{Err: errors.New(msg.ErrorMsg)}) diff --git a/core/capabilities/remote/target/request/client_request_test.go b/core/capabilities/remote/target/request/client_request_test.go index 07f43dbc71..7edb2f5e53 100644 --- a/core/capabilities/remote/target/request/client_request_test.go +++ b/core/capabilities/remote/target/request/client_request_test.go @@ -20,6 +20,11 @@ import ( p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) +const ( + workflowID1 = "15c631d295ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0" + workflowExecutionID1 = "95ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0abbadeed" +) + func Test_ClientRequest_MessageValidation(t *testing.T) { lggr := logger.TestLogger(t) @@ -68,8 +73,8 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { capabilityRequest := commoncap.CapabilityRequest{ Metadata: commoncap.RequestMetadata{ - WorkflowID: "workflowID", - WorkflowExecutionID: "workflowExecutionID", + WorkflowID: workflowID1, + WorkflowExecutionID: workflowExecutionID1, }, Inputs: executeInputs, Config: transmissionSchedule, diff --git a/core/capabilities/remote/target/request/server_request.go b/core/capabilities/remote/target/request/server_request.go index b8ae05bc31..16e90a034b 100644 --- a/core/capabilities/remote/target/request/server_request.go +++ b/core/capabilities/remote/target/request/server_request.go @@ -134,7 +134,7 @@ func (e *ServerRequest) executeRequest(ctx context.Context, payload []byte) erro return fmt.Errorf("failed to marshal capability response: %w", err) } - e.lggr.Debugw("received execution results", "metadata", capabilityRequest.Metadata, "error", capResponse.Err) + e.lggr.Debugw("received execution results", "workflowExecutionID", capabilityRequest.Metadata.WorkflowExecutionID, "error", capResponse.Err) e.setResult(responsePayload) return nil } diff --git a/core/capabilities/remote/target/server.go b/core/capabilities/remote/target/server.go index 39023ffb3f..56cad3739b 100644 --- a/core/capabilities/remote/target/server.go +++ b/core/capabilities/remote/target/server.go @@ -11,6 +11,7 @@ import ( commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/target/request" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" @@ -129,9 +130,14 @@ func (r *server) Receive(ctx context.Context, msg *types.MessageBody) { r.receiveLock.Lock() defer r.receiveLock.Unlock() - r.lggr.Debugw("received request for msg", "msgId", msg.MessageId) if msg.Method != types.MethodExecute { - r.lggr.Errorw("received request for unsupported method type", "method", msg.Method) + r.lggr.Errorw("received request for unsupported method type", "method", remote.SanitizeLogString(msg.Method)) + return + } + + messageId, err := GetMessageID(msg) + if err != nil { + r.lggr.Errorw("invalid message id", "err", err, "id", remote.SanitizeLogString(string(msg.MessageId))) return } @@ -143,9 +149,10 @@ func (r *server) Receive(ctx context.Context, msg *types.MessageBody) { // A request is uniquely identified by the message id and the hash of the payload to prevent a malicious // actor from sending a different payload with the same message id - messageId := GetMessageID(msg) requestID := messageId + hex.EncodeToString(msgHash[:]) + r.lggr.Debugw("received request", "msgId", msg.MessageId, "requestID", requestID) + if requestIDs, ok := r.messageIDToRequestIDsCount[messageId]; ok { requestIDs[requestID] = requestIDs[requestID] + 1 } else { @@ -156,7 +163,7 @@ func (r *server) Receive(ctx context.Context, msg *types.MessageBody) { if len(requestIDs) > 1 { // This is a potential attack vector as well as a situation that will occur if the client is sending non-deterministic payloads // so a warning is logged - r.lggr.Warnw("received messages with the same id and different payloads", "messageID", messageId, "requestIDToCount", requestIDs) + r.lggr.Warnw("received messages with the same id and different payloads", "messageID", messageId, "lenRequestIDs", len(requestIDs)) } if _, ok := r.requestIDToRequest[requestID]; !ok { @@ -177,7 +184,7 @@ func (r *server) Receive(ctx context.Context, msg *types.MessageBody) { err = reqAndMsgID.request.OnMessage(ctx, msg) if err != nil { - r.lggr.Errorw("request failed to OnMessage new message", "request", reqAndMsgID, "err", err) + r.lggr.Errorw("request failed to OnMessage new message", "messageID", reqAndMsgID.messageID, "err", err) } } @@ -201,8 +208,12 @@ func (r *server) getMessageHash(msg *types.MessageBody) ([32]byte, error) { return hash, nil } -func GetMessageID(msg *types.MessageBody) string { - return string(msg.MessageId) +func GetMessageID(msg *types.MessageBody) (string, error) { + idStr := string(msg.MessageId) + if !remote.IsValidID(idStr) { + return "", fmt.Errorf("invalid message id") + } + return idStr, nil } func (r *server) Ready() error { diff --git a/core/capabilities/remote/target/server_test.go b/core/capabilities/remote/target/server_test.go index 2460a2dd0f..505a2dcce5 100644 --- a/core/capabilities/remote/target/server_test.go +++ b/core/capabilities/remote/target/server_test.go @@ -39,8 +39,8 @@ func Test_Server_ExcludesNonDeterministicInputAttributes(t *testing.T) { _, err = caller.Execute(context.Background(), commoncap.CapabilityRequest{ Metadata: commoncap.RequestMetadata{ - WorkflowID: "workflowID", - WorkflowExecutionID: "workflowExecutionID", + WorkflowID: workflowID1, + WorkflowExecutionID: workflowExecutionID1, }, Inputs: inputs, }) @@ -67,8 +67,8 @@ func Test_Server_RespondsAfterSufficientRequests(t *testing.T) { _, err := caller.Execute(context.Background(), commoncap.CapabilityRequest{ Metadata: commoncap.RequestMetadata{ - WorkflowID: "workflowID", - WorkflowExecutionID: "workflowExecutionID", + WorkflowID: workflowID1, + WorkflowExecutionID: workflowExecutionID1, }, }) require.NoError(t, err) @@ -94,8 +94,8 @@ func Test_Server_InsufficientCallers(t *testing.T) { _, err := caller.Execute(context.Background(), commoncap.CapabilityRequest{ Metadata: commoncap.RequestMetadata{ - WorkflowID: "workflowID", - WorkflowExecutionID: "workflowExecutionID", + WorkflowID: workflowID1, + WorkflowExecutionID: workflowExecutionID1, }, }) require.NoError(t, err) @@ -121,8 +121,8 @@ func Test_Server_CapabilityError(t *testing.T) { _, err := caller.Execute(context.Background(), commoncap.CapabilityRequest{ Metadata: commoncap.RequestMetadata{ - WorkflowID: "workflowID", - WorkflowExecutionID: "workflowExecutionID", + WorkflowID: workflowID1, + WorkflowExecutionID: workflowExecutionID1, }, }) require.NoError(t, err) diff --git a/core/capabilities/remote/trigger_publisher.go b/core/capabilities/remote/trigger_publisher.go index 146b878968..b4d749754d 100644 --- a/core/capabilities/remote/trigger_publisher.go +++ b/core/capabilities/remote/trigger_publisher.go @@ -102,6 +102,10 @@ func (p *triggerPublisher) Receive(_ context.Context, msg *types.MessageBody) { p.lggr.Errorw("sender not a member of its workflow DON", "capabilityId", p.capInfo.ID, "callerDonId", msg.CallerDonId, "sender", sender) return } + if !IsValidWorkflowOrExecutionID(req.Metadata.WorkflowID) { + p.lggr.Errorw("received trigger request with invalid workflow ID", "capabilityId", p.capInfo.ID, "workflowId", SanitizeLogString(req.Metadata.WorkflowID)) + return + } p.lggr.Debugw("received trigger registration", "capabilityId", p.capInfo.ID, "workflowId", req.Metadata.WorkflowID, "sender", sender) key := registrationKey{msg.CallerDonId, req.Metadata.WorkflowID} nowMs := time.Now().UnixMilli() @@ -145,7 +149,7 @@ func (p *triggerPublisher) Receive(_ context.Context, msg *types.MessageBody) { p.lggr.Errorw("failed to register trigger", "capabilityId", p.capInfo.ID, "workflowId", req.Metadata.WorkflowID, "err", err) } } else { - p.lggr.Errorw("received trigger request with unknown method", "method", msg.Method, "sender", sender) + p.lggr.Errorw("received trigger request with unknown method", "method", SanitizeLogString(msg.Method), "sender", sender) } } diff --git a/core/capabilities/remote/trigger_subscriber.go b/core/capabilities/remote/trigger_subscriber.go index 2d038e45c0..d957614886 100644 --- a/core/capabilities/remote/trigger_subscriber.go +++ b/core/capabilities/remote/trigger_subscriber.go @@ -189,7 +189,7 @@ func (s *triggerSubscriber) Receive(_ context.Context, msg *types.MessageBody) { registration, found := s.registeredWorkflows[workflowId] s.mu.RUnlock() if !found { - s.lggr.Errorw("received message for unregistered workflow", "capabilityId", s.capInfo.ID, "workflowID", workflowId, "sender", sender) + s.lggr.Errorw("received message for unregistered workflow", "capabilityId", s.capInfo.ID, "workflowID", SanitizeLogString(workflowId), "sender", sender) continue } key := triggerEventKey{ @@ -217,7 +217,7 @@ func (s *triggerSubscriber) Receive(_ context.Context, msg *types.MessageBody) { } } } else { - s.lggr.Errorw("received trigger event with unknown method", "method", msg.Method, "sender", sender) + s.lggr.Errorw("received trigger event with unknown method", "method", SanitizeLogString(msg.Method), "sender", sender) } } diff --git a/core/capabilities/remote/trigger_subscriber_test.go b/core/capabilities/remote/trigger_subscriber_test.go index 2e34b03ec5..c834a271d5 100644 --- a/core/capabilities/remote/trigger_subscriber_test.go +++ b/core/capabilities/remote/trigger_subscriber_test.go @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-common/pkg/capabilities" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/values" @@ -22,7 +21,7 @@ import ( const ( peerID1 = "12D3KooWF3dVeJ6YoT5HFnYhmwQWWMoEwVFzJQ5kKCMX3ZityxMC" peerID2 = "12D3KooWQsmok6aD8PZqt3RnJhQRrNzKHLficq7zYFRp7kZ1hHP8" - workflowID1 = "workflowID1" + workflowID1 = "15c631d295ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0" ) var ( @@ -63,7 +62,7 @@ func TestTriggerSubscriber_RegisterAndReceive(t *testing.T) { }) // register trigger - config := &capabilities.RemoteTriggerConfig{ + config := &commoncap.RemoteTriggerConfig{ RegistrationRefresh: 100 * time.Millisecond, RegistrationExpiry: 100 * time.Second, MinResponsesToAggregate: 1, diff --git a/core/capabilities/remote/utils.go b/core/capabilities/remote/utils.go index dba24b843c..10e4e3082c 100644 --- a/core/capabilities/remote/utils.go +++ b/core/capabilities/remote/utils.go @@ -7,6 +7,7 @@ import ( "encoding/hex" "errors" "fmt" + "unicode" "google.golang.org/protobuf/proto" @@ -16,6 +17,12 @@ import ( p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) +const ( + maxLoggedStringLen = 256 + validWorkflowIDLen = 64 + maxIDLen = 128 +) + func ValidateMessage(msg p2ptypes.Message, expectedReceiver p2ptypes.PeerID) (*remotetypes.MessageBody, error) { var topLevelMessage remotetypes.Message err := proto.Unmarshal(msg.Payload, &topLevelMessage) @@ -93,3 +100,39 @@ func AggregateModeRaw(elemList [][]byte, minIdenticalResponses uint32) ([]byte, } return found, nil } + +func SanitizeLogString(s string) string { + tooLongSuffix := "" + if len(s) > maxLoggedStringLen { + s = s[:maxLoggedStringLen] + tooLongSuffix = " [TRUNCATED]" + } + for i := 0; i < len(s); i++ { + if !unicode.IsPrint(rune(s[i])) { + return "[UNPRINTABLE] " + hex.EncodeToString([]byte(s)) + tooLongSuffix + } + } + return s + tooLongSuffix +} + +// Workflow IDs and Execution IDs are 32-byte hex-encoded strings +func IsValidWorkflowOrExecutionID(id string) bool { + if len(id) != validWorkflowIDLen { + return false + } + _, err := hex.DecodeString(id) + return err == nil +} + +// Trigger event IDs and message IDs can only contain printable characters and must be non-empty +func IsValidID(id string) bool { + if len(id) == 0 || len(id) > maxIDLen { + return false + } + for i := 0; i < len(id); i++ { + if !unicode.IsPrint(rune(id[i])) { + return false + } + } + return true +} diff --git a/core/capabilities/remote/utils_test.go b/core/capabilities/remote/utils_test.go index 8bebf71fb6..177ab5a7d1 100644 --- a/core/capabilities/remote/utils_test.go +++ b/core/capabilities/remote/utils_test.go @@ -118,3 +118,26 @@ func TestDefaultModeAggregator_Aggregate(t *testing.T) { require.NoError(t, err) require.Equal(t, res, capResponse1) } + +func TestSanitizeLogString(t *testing.T) { + require.Equal(t, "hello", remote.SanitizeLogString("hello")) + require.Equal(t, "[UNPRINTABLE] 0a", remote.SanitizeLogString("\n")) + + longString := "" + for i := 0; i < 100; i++ { + longString += "aa-aa-aa-" + } + require.Equal(t, longString[:256]+" [TRUNCATED]", remote.SanitizeLogString(longString)) +} + +func TestIsValidWorkflowID(t *testing.T) { + require.False(t, remote.IsValidWorkflowOrExecutionID("too_short")) + require.False(t, remote.IsValidWorkflowOrExecutionID("nothex--95ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0")) + require.True(t, remote.IsValidWorkflowOrExecutionID("15c631d295ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0")) +} + +func TestIsValidTriggerEventID(t *testing.T) { + require.False(t, remote.IsValidID("")) + require.False(t, remote.IsValidID("\n\n")) + require.True(t, remote.IsValidID("id_id_2")) +} From bd648bd73df2a1de91a463a988f4c5b61e74b240 Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:05:10 +0200 Subject: [PATCH 076/432] Custom Astar finality (#14021) * Custom Astar finality * fix merge artifact * fix lint issue * simplify isRequestingFinalizedBlock * avoid iterating through the whole batch again * fix errors wrapping --- .changeset/warm-houses-build.md | 5 + core/chains/evm/client/chain_client.go | 4 + core/chains/evm/client/chain_client_test.go | 4 +- core/chains/evm/client/evm_client.go | 4 +- core/chains/evm/client/helpers_test.go | 4 +- core/chains/evm/client/rpc_client.go | 170 +++++++++++++++--- core/chains/evm/client/rpc_client_test.go | 115 +++++++++++- core/chains/evm/config/chaintype/chaintype.go | 6 +- core/chains/evm/testutils/client.go | 8 +- core/services/chainlink/config_test.go | 4 +- core/services/ocr/contract_tracker.go | 2 +- 11 files changed, 277 insertions(+), 49 deletions(-) create mode 100644 .changeset/warm-houses-build.md diff --git a/.changeset/warm-houses-build.md b/.changeset/warm-houses-build.md new file mode 100644 index 0000000000..6ce6215a88 --- /dev/null +++ b/.changeset/warm-houses-build.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Added custom finality calculation for Astar #internal diff --git a/core/chains/evm/client/chain_client.go b/core/chains/evm/client/chain_client.go index c39214471c..c27d294ebf 100644 --- a/core/chains/evm/client/chain_client.go +++ b/core/chains/evm/client/chain_client.go @@ -160,9 +160,13 @@ func (c *chainClient) BalanceAt(ctx context.Context, account common.Address, blo return c.multiNode.BalanceAt(ctx, account, blockNumber) } +// BatchCallContext - sends all given requests as a single batch. // Request specific errors for batch calls are returned to the individual BatchElem. // Ensure the same BatchElem slice provided by the caller is passed through the call stack // to ensure the caller has access to the errors. +// Note: some chains (e.g Astar) have custom finality requests, so even when FinalityTagEnabled=true, finality tag +// might not be properly handled and returned results might have weaker finality guarantees. It's highly recommended +// to use HeadTracker to identify latest finalized block. func (c *chainClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { return c.multiNode.BatchCallContext(ctx, b) } diff --git a/core/chains/evm/client/chain_client_test.go b/core/chains/evm/client/chain_client_test.go index a0b89cabbc..47041e40e9 100644 --- a/core/chains/evm/client/chain_client_test.go +++ b/core/chains/evm/client/chain_client_test.go @@ -328,7 +328,7 @@ func TestEthClient_HeaderByNumber(t *testing.T) { `{"difficulty":"0xf3a00","extraData":"0xd883010503846765746887676f312e372e318664617277696e","gasLimit":"0xffc001","gasUsed":"0x0","hash":"0x41800b5c3f1717687d85fc9018faac0a6e90b39deaa0b99e7fe4fe796ddeb26a","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0xd1aeb42885a43b72b518182ef893125814811048","mixHash":"0x0f98b15f1a4901a7e9204f3c500a7bd527b3fb2c3340e12176a44b83e414a69e","nonce":"0x0ece08ea8c49dfd9","number":"0x1","parentHash":"0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x218","stateRoot":"0xc7b01007a10da045eacb90385887dd0c38fcb5db7393006bdde24b93873c334b","timestamp":"0x58318da2","totalDifficulty":"0x1f3a00","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]}`}, {"happy parity", expectedBlockNum, expectedBlockNum.Int64(), nil, `{"author":"0xd1aeb42885a43b72b518182ef893125814811048","difficulty":"0xf3a00","extraData":"0xd883010503846765746887676f312e372e318664617277696e","gasLimit":"0xffc001","gasUsed":"0x0","hash":"0x41800b5c3f1717687d85fc9018faac0a6e90b39deaa0b99e7fe4fe796ddeb26a","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0xd1aeb42885a43b72b518182ef893125814811048","mixHash":"0x0f98b15f1a4901a7e9204f3c500a7bd527b3fb2c3340e12176a44b83e414a69e","nonce":"0x0ece08ea8c49dfd9","number":"0x1","parentHash":"0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sealFields":["0xa00f98b15f1a4901a7e9204f3c500a7bd527b3fb2c3340e12176a44b83e414a69e","0x880ece08ea8c49dfd9"],"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x218","stateRoot":"0xc7b01007a10da045eacb90385887dd0c38fcb5db7393006bdde24b93873c334b","timestamp":"0x58318da2","totalDifficulty":"0x1f3a00","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]}`}, - {"missing header", expectedBlockNum, 0, fmt.Errorf("no live nodes available for chain %s", testutils.FixtureChainID.String()), + {"missing header", expectedBlockNum, 0, fmt.Errorf("RPCClient returned error (eth-primary-rpc-0): not found"), `null`}, } @@ -366,7 +366,7 @@ func TestEthClient_HeaderByNumber(t *testing.T) { ctx, cancel := context.WithTimeout(tests.Context(t), 5*time.Second) result, err := ethClient.HeadByNumber(ctx, expectedBlockNum) if test.error != nil { - require.Error(t, err, test.error) + require.EqualError(t, err, test.error.Error()) } else { require.NoError(t, err) require.Equal(t, expectedBlockHash, result.Hash.Hex()) diff --git a/core/chains/evm/client/evm_client.go b/core/chains/evm/client/evm_client.go index 3676808683..1fd533d6aa 100644 --- a/core/chains/evm/client/evm_client.go +++ b/core/chains/evm/client/evm_client.go @@ -22,13 +22,13 @@ func NewEvmClient(cfg evmconfig.NodePool, chainCfg commonclient.ChainConfig, cli for i, node := range nodes { if node.SendOnly != nil && *node.SendOnly { rpc := NewRPCClient(lggr, empty, (*url.URL)(node.HTTPURL), *node.Name, int32(i), chainID, - commonclient.Secondary, cfg.FinalizedBlockPollInterval(), largePayloadRPCTimeout, defaultRPCTimeout) + commonclient.Secondary, cfg.FinalizedBlockPollInterval(), largePayloadRPCTimeout, defaultRPCTimeout, chainType) sendonly := commonclient.NewSendOnlyNode(lggr, (url.URL)(*node.HTTPURL), *node.Name, chainID, rpc) sendonlys = append(sendonlys, sendonly) } else { rpc := NewRPCClient(lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), *node.Name, int32(i), - chainID, commonclient.Primary, cfg.FinalizedBlockPollInterval(), largePayloadRPCTimeout, defaultRPCTimeout) + chainID, commonclient.Primary, cfg.FinalizedBlockPollInterval(), largePayloadRPCTimeout, defaultRPCTimeout, chainType) primaryNode := commonclient.NewNode(cfg, chainCfg, lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), *node.Name, int32(i), chainID, *node.Order, rpc, "EVM") diff --git a/core/chains/evm/client/helpers_test.go b/core/chains/evm/client/helpers_test.go index 8caacb4190..e996ccc5e4 100644 --- a/core/chains/evm/client/helpers_test.go +++ b/core/chains/evm/client/helpers_test.go @@ -140,7 +140,7 @@ func NewChainClientWithTestNode( } lggr := logger.Test(t) - rpc := NewRPCClient(lggr, *parsed, rpcHTTPURL, "eth-primary-rpc-0", id, chainID, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) + rpc := NewRPCClient(lggr, *parsed, rpcHTTPURL, "eth-primary-rpc-0", id, chainID, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") n := commonclient.NewNode[*big.Int, *evmtypes.Head, RPCClient]( nodeCfg, clientMocks.ChainConfig{NoNewHeadsThresholdVal: noNewHeadsThreshold}, lggr, *parsed, rpcHTTPURL, "eth-primary-node-0", id, chainID, 1, rpc, "EVM") @@ -152,7 +152,7 @@ func NewChainClientWithTestNode( return nil, pkgerrors.Errorf("sendonly ethereum rpc url scheme must be http(s): %s", u.String()) } var empty url.URL - rpc := NewRPCClient(lggr, empty, &sendonlyRPCURLs[i], fmt.Sprintf("eth-sendonly-rpc-%d", i), id, chainID, commonclient.Secondary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) + rpc := NewRPCClient(lggr, empty, &sendonlyRPCURLs[i], fmt.Sprintf("eth-sendonly-rpc-%d", i), id, chainID, commonclient.Secondary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") s := commonclient.NewSendOnlyNode[*big.Int, RPCClient]( lggr, u, fmt.Sprintf("eth-sendonly-%d", i), chainID, rpc) sendonlys = append(sendonlys, s) diff --git a/core/chains/evm/client/rpc_client.go b/core/chains/evm/client/rpc_client.go index 200703dd42..07aa86fc45 100644 --- a/core/chains/evm/client/rpc_client.go +++ b/core/chains/evm/client/rpc_client.go @@ -2,6 +2,7 @@ package client import ( "context" + "encoding/json" "errors" "fmt" "math/big" @@ -28,6 +29,7 @@ import ( commonclient "github.com/smartcontractkit/chainlink/v2/common/client" commontypes "github.com/smartcontractkit/chainlink/v2/common/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" @@ -120,6 +122,7 @@ type rpcClient struct { largePayloadRpcTimeout time.Duration rpcTimeout time.Duration finalizedBlockPollInterval time.Duration + chainType chaintype.ChainType ws rawclient http *rawclient @@ -156,10 +159,12 @@ func NewRPCClient( finalizedBlockPollInterval time.Duration, largePayloadRpcTimeout time.Duration, rpcTimeout time.Duration, + chainType chaintype.ChainType, ) RPCClient { r := &rpcClient{ largePayloadRpcTimeout: largePayloadRpcTimeout, rpcTimeout: rpcTimeout, + chainType: chainType, } r.name = name r.id = id @@ -396,8 +401,28 @@ func (r *rpcClient) CallContext(ctx context.Context, result interface{}, method return err } -func (r *rpcClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { - ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.largePayloadRpcTimeout) +func (r *rpcClient) BatchCallContext(rootCtx context.Context, b []rpc.BatchElem) error { + // Astar's finality tags provide weaker finality guarantees than we require. + // Fetch latest finalized block using Astar's custom requests and populate it after batch request completes + var astarRawLatestFinalizedBlock json.RawMessage + var requestedFinalizedBlock bool + if r.chainType == chaintype.ChainAstar { + for _, el := range b { + if !isRequestingFinalizedBlock(el) { + continue + } + + requestedFinalizedBlock = true + err := r.astarLatestFinalizedBlock(rootCtx, &astarRawLatestFinalizedBlock) + if err != nil { + return fmt.Errorf("failed to get astar latest finalized block: %w", err) + } + + break + } + } + + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(rootCtx, r.largePayloadRpcTimeout) defer cancel() lggr := r.newRqLggr().With("nBatchElems", len(b), "batchElems", b) @@ -412,8 +437,46 @@ func (r *rpcClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) err duration := time.Since(start) r.logResult(lggr, err, duration, r.getRPCDomain(), "BatchCallContext") + if err != nil { + return err + } - return err + if r.chainType == chaintype.ChainAstar && requestedFinalizedBlock { + // populate requested finalized block with correct value + for _, el := range b { + if !isRequestingFinalizedBlock(el) { + continue + } + + el.Error = nil + err = json.Unmarshal(astarRawLatestFinalizedBlock, el.Result) + if err != nil { + el.Error = fmt.Errorf("failed to unmarshal astar finalized block into provided struct: %w", err) + } + } + } + + return nil +} + +func isRequestingFinalizedBlock(el rpc.BatchElem) bool { + isGetBlock := el.Method == "eth_getBlockByNumber" && len(el.Args) > 0 + if !isGetBlock { + return false + } + + if el.Args[0] == rpc.FinalizedBlockNumber { + return true + } + + switch arg := el.Args[0].(type) { + case string: + return arg == rpc.FinalizedBlockNumber.String() + case fmt.Stringer: + return arg.String() == rpc.FinalizedBlockNumber.String() + default: + return false + } } // TODO: Full transition from SubscribeNewHead to SubscribeToHeads is done in BCI-2875 @@ -601,17 +664,84 @@ func (r *rpcClient) HeaderByHash(ctx context.Context, hash common.Hash) (header return } -func (r *rpcClient) LatestFinalizedBlock(ctx context.Context) (*evmtypes.Head, error) { - return r.blockByNumber(ctx, rpc.FinalizedBlockNumber.String()) +func (r *rpcClient) LatestFinalizedBlock(ctx context.Context) (head *evmtypes.Head, err error) { + // capture chStopInFlight to ensure we are not updating chainInfo with observations related to previous life cycle + ctx, cancel, chStopInFlight, _, _ := r.acquireQueryCtx(ctx, r.rpcTimeout) + defer cancel() + if r.chainType == chaintype.ChainAstar { + // astar's finality tags provide weaker guarantee. Use their custom request to request latest finalized block + err = r.astarLatestFinalizedBlock(ctx, &head) + } else { + err = r.ethGetBlockByNumber(ctx, rpc.FinalizedBlockNumber.String(), &head) + } + + if err != nil { + return + } + + if head == nil { + err = r.wrapRPCClientError(ethereum.NotFound) + return + } + + head.EVMChainID = ubig.New(r.chainID) + + r.onNewFinalizedHead(ctx, chStopInFlight, head) + return +} + +func (r *rpcClient) astarLatestFinalizedBlock(ctx context.Context, result interface{}) (err error) { + var hashResult string + err = r.CallContext(ctx, &hashResult, "chain_getFinalizedHead") + if err != nil { + return fmt.Errorf("failed to get astar latest finalized hash: %w", err) + } + + var astarHead struct { + Number *hexutil.Big `json:"number"` + } + err = r.CallContext(ctx, &astarHead, "chain_getHeader", hashResult, false) + if err != nil { + return fmt.Errorf("failed to get astar head by hash: %w", err) + } + + if astarHead.Number == nil { + return r.wrapRPCClientError(fmt.Errorf("expected non empty head number of finalized block")) + } + + err = r.ethGetBlockByNumber(ctx, astarHead.Number.String(), result) + if err != nil { + return fmt.Errorf("failed to get astar finalized block: %w", err) + } + + return nil } func (r *rpcClient) BlockByNumber(ctx context.Context, number *big.Int) (head *evmtypes.Head, err error) { - hex := ToBlockNumArg(number) - return r.blockByNumber(ctx, hex) + ctx, cancel, chStopInFlight, _, _ := r.acquireQueryCtx(ctx, r.rpcTimeout) + defer cancel() + hexNumber := ToBlockNumArg(number) + err = r.ethGetBlockByNumber(ctx, hexNumber, &head) + if err != nil { + return + } + + if head == nil { + err = r.wrapRPCClientError(ethereum.NotFound) + return + } + + head.EVMChainID = ubig.New(r.chainID) + + if hexNumber == rpc.LatestBlockNumber.String() { + r.onNewHead(ctx, chStopInFlight, head) + } + + return } -func (r *rpcClient) blockByNumber(ctx context.Context, number string) (head *evmtypes.Head, err error) { - ctx, cancel, chStopInFlight, ws, http := r.acquireQueryCtx(ctx, r.rpcTimeout) +func (r *rpcClient) ethGetBlockByNumber(ctx context.Context, number string, result interface{}) (err error) { + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() const method = "eth_getBlockByNumber" args := []interface{}{number, false} @@ -623,30 +753,14 @@ func (r *rpcClient) blockByNumber(ctx context.Context, number string) (head *evm lggr.Debug("RPC call: evmclient.Client#CallContext") start := time.Now() if http != nil { - err = r.wrapHTTP(http.rpc.CallContext(ctx, &head, method, args...)) + err = r.wrapHTTP(http.rpc.CallContext(ctx, result, method, args...)) } else { - err = r.wrapWS(ws.rpc.CallContext(ctx, &head, method, args...)) + err = r.wrapWS(ws.rpc.CallContext(ctx, result, method, args...)) } duration := time.Since(start) r.logResult(lggr, err, duration, r.getRPCDomain(), "CallContext") - if err != nil { - return nil, err - } - if head == nil { - err = r.wrapRPCClientError(ethereum.NotFound) - return - } - head.EVMChainID = ubig.New(r.chainID) - - switch number { - case rpc.FinalizedBlockNumber.String(): - r.onNewFinalizedHead(ctx, chStopInFlight, head) - case rpc.LatestBlockNumber.String(): - r.onNewHead(ctx, chStopInFlight, head) - } - - return + return err } func (r *rpcClient) BlockByHash(ctx context.Context, hash common.Hash) (head *evmtypes.Head, err error) { diff --git a/core/chains/evm/client/rpc_client_test.go b/core/chains/evm/client/rpc_client_test.go index d6a11e0d01..1282188099 100644 --- a/core/chains/evm/client/rpc_client_test.go +++ b/core/chains/evm/client/rpc_client_test.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tidwall/gjson" @@ -23,6 +24,7 @@ import ( commonclient "github.com/smartcontractkit/chainlink/v2/common/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/testutils" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) @@ -58,7 +60,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) // set to default values @@ -108,7 +110,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) ch := make(chan *evmtypes.Head) @@ -131,7 +133,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { t.Run("Block's chain ID matched configured", func(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) ch := make(chan *evmtypes.Head) @@ -148,7 +150,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { }) wsURL := server.WSURL() observedLggr, observed := logger.TestObserved(t, zap.DebugLevel) - rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) + rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") require.NoError(t, rpc.Dial(ctx)) server.Close() _, err := rpc.SubscribeNewHead(ctx, make(chan *evmtypes.Head)) @@ -158,7 +160,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { t.Run("Subscription error is properly wrapper", func(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) sub, err := rpc.SubscribeNewHead(ctx, make(chan *evmtypes.Head)) @@ -186,7 +188,7 @@ func TestRPCClient_SubscribeFilterLogs(t *testing.T) { }) wsURL := server.WSURL() observedLggr, observed := logger.TestObserved(t, zap.DebugLevel) - rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) + rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") require.NoError(t, rpc.Dial(ctx)) server.Close() _, err := rpc.SubscribeFilterLogs(ctx, ethereum.FilterQuery{}, make(chan types.Log)) @@ -203,7 +205,7 @@ func TestRPCClient_SubscribeFilterLogs(t *testing.T) { return resp }) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) sub, err := rpc.SubscribeFilterLogs(ctx, ethereum.FilterQuery{}, make(chan types.Log)) @@ -252,7 +254,7 @@ func TestRPCClient_LatestFinalizedBlock(t *testing.T) { } server := createRPCServer() - rpc := client.NewRPCClient(lggr, *server.URL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout) + rpc := client.NewRPCClient(lggr, *server.URL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") require.NoError(t, rpc.Dial(ctx)) defer rpc.Close() server.Head = &evmtypes.Head{Number: 128} @@ -362,7 +364,7 @@ func TestRpcClientLargePayloadTimeout(t *testing.T) { // use something unreasonably large for RPC timeout to ensure that we use largePayloadRPCTimeout const rpcTimeout = time.Hour const largePayloadRPCTimeout = tests.TestInterval - rpc := client.NewRPCClient(logger.Test(t), *rpcURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, largePayloadRPCTimeout, rpcTimeout) + rpc := client.NewRPCClient(logger.Test(t), *rpcURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, largePayloadRPCTimeout, rpcTimeout, "") require.NoError(t, rpc.Dial(ctx)) defer rpc.Close() err := testCase.Fn(ctx, rpc) @@ -370,3 +372,98 @@ func TestRpcClientLargePayloadTimeout(t *testing.T) { }) } } + +func TestAstarCustomFinality(t *testing.T) { + t.Parallel() + + chainId := big.NewInt(123456) + // create new server that returns 4 block for Astar custom finality and 8 block for finality tag. + wsURL := testutils.NewWSServer(t, chainId, func(method string, params gjson.Result) (resp testutils.JSONRPCResponse) { + switch method { + case "chain_getFinalizedHead": + resp.Result = `"0xf14c499253fd7bbcba142e5dd77dad8b5ad598c1dc414a66bacdd8dae14a6759"` + case "chain_getHeader": + if assert.True(t, params.IsArray()) && assert.Equal(t, "0xf14c499253fd7bbcba142e5dd77dad8b5ad598c1dc414a66bacdd8dae14a6759", params.Array()[0].String()) { + resp.Result = `{"parentHash":"0x1311773bc6b4efc8f438ed1f094524b2a1233baf8a35396f641fcc42a378fc62","number":"0x4","stateRoot":"0x0e4920dc5516b587e1f74a0b65963134523a12cc11478bb314e52895758fbfa2","extrinsicsRoot":"0x5b02446dcab0659eb07d4a38f28f181c1b78a71b2aba207bb0ea1f0f3468e6bd","digest":{"logs":["0x066175726120ad678e0800000000","0x04525053529023158dc8e8fd0180bf26d88233a3d94eed2f4e43480395f0809f28791965e4d34e9b3905","0x0466726f6e88017441e97acf83f555e0deefef86db636bc8a37eb84747603412884e4df4d2280400","0x056175726101018a0a57edf70cc5474323114a47ee1e7f645b8beea5a1560a996416458e89f42bdf4955e24d32b5da54e1bf628aaa7ce4b8c0fa2b95c175a139d88786af12a88c"]}}` + } + case "eth_getBlockByNumber": + assert.True(t, params.IsArray()) + switch params.Array()[0].String() { + case "0x4": + resp.Result = `{"author":"0x5accb3bf9194a5f81b2087d4bd6ac47c62775d49","baseFeePerGas":"0xb576270823","difficulty":"0x0","extraData":"0x","gasLimit":"0xe4e1c0","gasUsed":"0x0","hash":"0x7441e97acf83f555e0deefef86db636bc8a37eb84747603412884e4df4d22804","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x5accb3bf9194a5f81b2087d4bd6ac47c62775d49","nonce":"0x0000000000000000","number":"0x4","parentHash":"0x6ba069c318b692bf2cc0bd7ea070a9382a20c2f52413c10554b57c2e381bf2bb","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x201","stateRoot":"0x17c46d359b9af773312c747f1d20032c67658d9a2923799f00533b73789cf49b","timestamp":"0x66acdc22","totalDifficulty":"0x0","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]}` + case "finalized": + resp.Result = `{"author":"0x1687736326c9fea17e25fc5287613693c912909c","baseFeePerGas":"0x3b9aca00","difficulty":"0x0","extraData":"0x","gasLimit":"0xe4e1c0","gasUsed":"0x0","hash":"0x62f03413681948b06882e7d9f91c4949bc39ded98d36336ab03faea038ec8e3d","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x1687736326c9fea17e25fc5287613693c912909c","nonce":"0x0000000000000000","number":"0x8","parentHash":"0x43f504afdc639cbb8daf5fd5328a37762164b73f9c70ed54e1928c1fca6d8f23","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x200","stateRoot":"0x0cb938d51ad83bdf401e3f5f7f989e60df64fdea620d394af41a3e72629f7495","timestamp":"0x61bd8d1a","totalDifficulty":"0x0","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]}` + default: + assert.Fail(t, fmt.Sprintf("unexpected eth_getBlockByNumber param: %v", params.Array())) + } + default: + assert.Fail(t, fmt.Sprintf("unexpected method: %s", method)) + } + return + }).WSURL() + + const expectedFinalizedBlockNumber = int64(4) + const expectedFinalizedBlockHash = "0x7441e97acf83f555e0deefef86db636bc8a37eb84747603412884e4df4d22804" + rpcClient := client.NewRPCClient(logger.Test(t), *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, chaintype.ChainAstar) + defer rpcClient.Close() + err := rpcClient.Dial(tests.Context(t)) + require.NoError(t, err) + + testCases := []struct { + Name string + GetLatestFinalized func(ctx context.Context) (*evmtypes.Head, error) + }{ + { + Name: "Direct LatestFinalized call", + GetLatestFinalized: func(ctx context.Context) (*evmtypes.Head, error) { + return rpcClient.LatestFinalizedBlock(ctx) + }, + }, + { + Name: "BatchCallContext with Finalized tag as string", + GetLatestFinalized: func(ctx context.Context) (*evmtypes.Head, error) { + result := &evmtypes.Head{} + req := rpc.BatchElem{ + Method: "eth_getBlockByNumber", + Args: []interface{}{rpc.FinalizedBlockNumber.String(), false}, + Result: result, + } + err := rpcClient.BatchCallContext(ctx, []rpc.BatchElem{ + req, + }) + if err != nil { + return nil, err + } + + return result, req.Error + }, + }, + { + Name: "BatchCallContext with Finalized tag as BlockNumber", + GetLatestFinalized: func(ctx context.Context) (*evmtypes.Head, error) { + result := &evmtypes.Head{} + req := rpc.BatchElem{ + Method: "eth_getBlockByNumber", + Args: []interface{}{rpc.FinalizedBlockNumber, false}, + Result: result, + } + err := rpcClient.BatchCallContext(ctx, []rpc.BatchElem{req}) + if err != nil { + return nil, err + } + + return result, req.Error + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.Name, func(t *testing.T) { + lf, err := testCase.GetLatestFinalized(tests.Context(t)) + require.NoError(t, err) + require.NotNil(t, lf) + assert.Equal(t, expectedFinalizedBlockHash, lf.Hash.String()) + assert.Equal(t, expectedFinalizedBlockNumber, lf.Number) + }) + } +} diff --git a/core/chains/evm/config/chaintype/chaintype.go b/core/chains/evm/config/chaintype/chaintype.go index 623a80f54f..07ea620624 100644 --- a/core/chains/evm/config/chaintype/chaintype.go +++ b/core/chains/evm/config/chaintype/chaintype.go @@ -9,6 +9,7 @@ type ChainType string const ( ChainArbitrum ChainType = "arbitrum" + ChainAstar ChainType = "astar" ChainCelo ChainType = "celo" ChainGnosis ChainType = "gnosis" ChainHedera ChainType = "hedera" @@ -36,7 +37,7 @@ func (c ChainType) IsL2() bool { func (c ChainType) IsValid() bool { switch c { - case "", ChainArbitrum, ChainCelo, ChainGnosis, ChainHedera, ChainKroma, ChainMetis, ChainOptimismBedrock, ChainScroll, ChainWeMix, ChainXLayer, ChainZkEvm, ChainZkSync: + case "", ChainArbitrum, ChainAstar, ChainCelo, ChainGnosis, ChainHedera, ChainKroma, ChainMetis, ChainOptimismBedrock, ChainScroll, ChainWeMix, ChainXLayer, ChainZkEvm, ChainZkSync: return true } return false @@ -46,6 +47,8 @@ func ChainTypeFromSlug(slug string) ChainType { switch slug { case "arbitrum": return ChainArbitrum + case "astar": + return ChainAstar case "celo": return ChainCelo case "gnosis": @@ -121,6 +124,7 @@ func (c *ChainTypeConfig) String() string { var ErrInvalidChainType = fmt.Errorf("must be one of %s or omitted", strings.Join([]string{ string(ChainArbitrum), + string(ChainAstar), string(ChainCelo), string(ChainGnosis), string(ChainHedera), diff --git a/core/chains/evm/testutils/client.go b/core/chains/evm/testutils/client.go index 89c97b01e6..1e5523fbff 100644 --- a/core/chains/evm/testutils/client.go +++ b/core/chains/evm/testutils/client.go @@ -148,8 +148,12 @@ func (ts *testWSServer) newWSHandler(chainID *big.Int, callback JSONRPCHandler) ts.t.Log("Received message", string(data)) req := gjson.ParseBytes(data) if !req.IsObject() { - ts.t.Logf("Request must be object: %v", req.Type) - return + if isSingleObjectArray := req.IsArray() && len(req.Array()) == 1; !isSingleObjectArray { + ts.t.Logf("Request must be object: %v", req.Type) + return + } + + req = req.Array()[0] } if e := req.Get("error"); e.Exists() { ts.t.Logf("Received jsonrpc error: %v", e) diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 0038be8a97..f5a9d33592 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -1304,7 +1304,7 @@ func TestConfig_Validate(t *testing.T) { - 1: 10 errors: - ChainType: invalid value (Foo): must not be set with this chain id - Nodes: missing: must have at least one node - - ChainType: invalid value (Foo): must be one of arbitrum, celo, gnosis, hedera, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync or omitted + - ChainType: invalid value (Foo): must be one of arbitrum, astar, celo, gnosis, hedera, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync or omitted - HeadTracker.HistoryDepth: invalid value (30): must be greater than or equal to FinalizedBlockOffset - GasEstimator.BumpThreshold: invalid value (0): cannot be 0 if auto-purge feature is enabled for Foo - Transactions.AutoPurge.Threshold: missing: needs to be set if auto-purge feature is enabled for Foo @@ -1317,7 +1317,7 @@ func TestConfig_Validate(t *testing.T) { - 2: 5 errors: - ChainType: invalid value (Arbitrum): only "optimismBedrock" can be used with this chain id - Nodes: missing: must have at least one node - - ChainType: invalid value (Arbitrum): must be one of arbitrum, celo, gnosis, hedera, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync or omitted + - ChainType: invalid value (Arbitrum): must be one of arbitrum, astar, celo, gnosis, hedera, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync or omitted - FinalityDepth: invalid value (0): must be greater than or equal to 1 - MinIncomingConfirmations: invalid value (0): must be greater than or equal to 1 - 3.Nodes: 5 errors: diff --git a/core/services/ocr/contract_tracker.go b/core/services/ocr/contract_tracker.go index 6651e4b65d..d7199874a9 100644 --- a/core/services/ocr/contract_tracker.go +++ b/core/services/ocr/contract_tracker.go @@ -399,7 +399,7 @@ func (t *OCRContractTracker) LatestBlockHeight(ctx context.Context) (blockheight // care about the block height; we have no way of getting the L1 block // height anyway return 0, nil - case "", chaintype.ChainArbitrum, chaintype.ChainCelo, chaintype.ChainGnosis, chaintype.ChainHedera, chaintype.ChainKroma, chaintype.ChainOptimismBedrock, chaintype.ChainScroll, chaintype.ChainWeMix, chaintype.ChainXLayer, chaintype.ChainZkEvm, chaintype.ChainZkSync: + case "", chaintype.ChainArbitrum, chaintype.ChainAstar, chaintype.ChainCelo, chaintype.ChainGnosis, chaintype.ChainHedera, chaintype.ChainKroma, chaintype.ChainOptimismBedrock, chaintype.ChainScroll, chaintype.ChainWeMix, chaintype.ChainXLayer, chaintype.ChainZkEvm, chaintype.ChainZkSync: // continue } latestBlockHeight := t.getLatestBlockHeight() From c330defde2211aa4a0d8392f867400a829220b2f Mon Sep 17 00:00:00 2001 From: Juan Farber Date: Fri, 9 Aug 2024 14:47:24 -0300 Subject: [PATCH 077/432] [BCI-3573] - Remove dependence on FinalityDepth in EVM TXM code (#13794) * removing finality within common/txmgr * remove finality from common/txmgr comment * latestFinalizedBlockNum support within evm/txmgr txstore * refactor tests after evm/txmgr txstore changes * mocks for both common and core/evm * remove comments that are still referencing to finalityDepth within evm/txmgr * add changeset * error if no LatestFinalizedHead was found * fix mocks version * fix mocks version * mock versioning * mock version * mock version * mock version * mock version * inject head tracker trimmed API * fix tests * mocks * remove unnecesary tests as finalized head is guaranteed * ht in shell local * remove evm dep from confirmer and use generics instead * make markOldTxesMissingReceiptAsErrored condition inclusive * use already initialized head tracker within shell local * fix mocking, fix unit test * fix a potential bug * fix bug * refactor * address comments * fix lint * rename * have log back * update comments * remove nil check * minor * fix test * grammar * rephrase --------- Co-authored-by: Joe Huang --- .changeset/chatty-spiders-double.md | 5 + common/txmgr/confirmer.go | 66 ++++++--- common/txmgr/types/mocks/tx_store.go | 22 +-- common/txmgr/types/tx_store.go | 2 +- core/chains/evm/txmgr/builder.go | 13 +- core/chains/evm/txmgr/confirmer_test.go | 144 ++++++++++++-------- core/chains/evm/txmgr/evm_tx_store.go | 27 ++-- core/chains/evm/txmgr/evm_tx_store_test.go | 7 +- core/chains/evm/txmgr/mocks/evm_tx_store.go | 22 +-- core/chains/evm/txmgr/txmgr_test.go | 1 + core/cmd/shell_local.go | 2 +- core/cmd/shell_local_test.go | 3 +- core/internal/cltest/mocks.go | 1 + 13 files changed, 191 insertions(+), 124 deletions(-) create mode 100644 .changeset/chatty-spiders-double.md diff --git a/.changeset/chatty-spiders-double.md b/.changeset/chatty-spiders-double.md new file mode 100644 index 0000000000..750a11628f --- /dev/null +++ b/.changeset/chatty-spiders-double.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +remove dependency on FinalityDepth in EVM TXM code. #internal diff --git a/common/txmgr/confirmer.go b/common/txmgr/confirmer.go index 1e3922fdbf..3b42119178 100644 --- a/common/txmgr/confirmer.go +++ b/common/txmgr/confirmer.go @@ -102,6 +102,10 @@ var ( }, []string{"chainID"}) ) +type confirmerHeadTracker[HEAD types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] interface { + LatestAndFinalizedBlock(ctx context.Context) (latest, finalized HEAD, err error) +} + // Confirmer is a broad service which performs four different tasks in sequence on every new longest chain // Step 1: Mark that all currently pending transaction attempts were broadcast before this block // Step 2: Check pending transactions for receipts @@ -133,14 +137,15 @@ type Confirmer[ ks txmgrtypes.KeyStore[ADDR, CHAIN_ID, SEQ] enabledAddresses []ADDR - mb *mailbox.Mailbox[HEAD] - stopCh services.StopChan - wg sync.WaitGroup - initSync sync.Mutex - isStarted bool - + mb *mailbox.Mailbox[HEAD] + stopCh services.StopChan + wg sync.WaitGroup + initSync sync.Mutex + isStarted bool nConsecutiveBlocksChainTooShort int isReceiptNil func(R) bool + + headTracker confirmerHeadTracker[HEAD, BLOCK_HASH] } func NewConfirmer[ @@ -164,6 +169,7 @@ func NewConfirmer[ lggr logger.Logger, isReceiptNil func(R) bool, stuckTxDetector txmgrtypes.StuckTxDetector[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], + headTracker confirmerHeadTracker[HEAD, BLOCK_HASH], ) *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { lggr = logger.Named(lggr, "Confirmer") return &Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]{ @@ -181,6 +187,7 @@ func NewConfirmer[ mb: mailbox.NewSingle[HEAD](), isReceiptNil: isReceiptNil, stuckTxDetector: stuckTxDetector, + headTracker: headTracker, } } @@ -297,7 +304,20 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) pro return fmt.Errorf("CheckConfirmedMissingReceipt failed: %w", err) } - if err := ec.CheckForReceipts(ctx, head.BlockNumber()); err != nil { + _, latestFinalizedHead, err := ec.headTracker.LatestAndFinalizedBlock(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve latest finalized head: %w", err) + } + + if !latestFinalizedHead.IsValid() { + return fmt.Errorf("latest finalized head is not valid") + } + + if latestFinalizedHead.BlockNumber() > head.BlockNumber() { + ec.lggr.Debugw("processHead received old block", "latestFinalizedHead", latestFinalizedHead.BlockNumber(), "headNum", head.BlockNumber(), "time", time.Since(mark), "id", "confirmer") + } + + if err := ec.CheckForReceipts(ctx, head.BlockNumber(), latestFinalizedHead.BlockNumber()); err != nil { return fmt.Errorf("CheckForReceipts failed: %w", err) } @@ -318,7 +338,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) pro ec.lggr.Debugw("Finished RebroadcastWhereNecessary", "headNum", head.BlockNumber(), "time", time.Since(mark), "id", "confirmer") mark = time.Now() - if err := ec.EnsureConfirmedTransactionsInLongestChain(ctx, head); err != nil { + if err := ec.EnsureConfirmedTransactionsInLongestChain(ctx, head, latestFinalizedHead.BlockNumber()); err != nil { return fmt.Errorf("EnsureConfirmedTransactionsInLongestChain failed: %w", err) } @@ -395,8 +415,8 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Che return } -// CheckForReceipts finds attempts that are still pending and checks to see if a receipt is present for the given block number -func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) CheckForReceipts(ctx context.Context, blockNum int64) error { +// CheckForReceipts finds attempts that are still pending and checks to see if a receipt is present for the given block number. +func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) CheckForReceipts(ctx context.Context, blockNum int64, latestFinalizedBlockNum int64) error { attempts, err := ec.txStore.FindTxAttemptsRequiringReceiptFetch(ctx, ec.chainID) if err != nil { return fmt.Errorf("FindTxAttemptsRequiringReceiptFetch failed: %w", err) @@ -443,7 +463,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Che return fmt.Errorf("unable to mark txes as 'confirmed_missing_receipt': %w", err) } - if err := ec.txStore.MarkOldTxesMissingReceiptAsErrored(ctx, blockNum, ec.chainConfig.FinalityDepth(), ec.chainID); err != nil { + if err := ec.txStore.MarkOldTxesMissingReceiptAsErrored(ctx, blockNum, latestFinalizedBlockNum, ec.chainID); err != nil { return fmt.Errorf("unable to confirm buried unconfirmed txes': %w", err) } return nil @@ -1004,22 +1024,30 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) han } } -// EnsureConfirmedTransactionsInLongestChain finds all confirmed txes up to the depth +// EnsureConfirmedTransactionsInLongestChain finds all confirmed txes up to the earliest head // of the given chain and ensures that every one has a receipt with a block hash that is // in the given chain. // // If any of the confirmed transactions does not have a receipt in the chain, it has been // re-org'd out and will be rebroadcast. -func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) EnsureConfirmedTransactionsInLongestChain(ctx context.Context, head types.Head[BLOCK_HASH]) error { - if head.ChainLength() < ec.chainConfig.FinalityDepth() { - logArgs := []interface{}{ - "chainLength", head.ChainLength(), "finalityDepth", ec.chainConfig.FinalityDepth(), - } +func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) EnsureConfirmedTransactionsInLongestChain(ctx context.Context, head types.Head[BLOCK_HASH], latestFinalizedHeadNumber int64) error { + logArgs := []interface{}{ + "chainLength", head.ChainLength(), "latestFinalizedHead number", latestFinalizedHeadNumber, + } + + if head.BlockNumber() < latestFinalizedHeadNumber { + errMsg := "current head is shorter than latest finalized head" + ec.lggr.Errorw(errMsg, append(logArgs, "head block number", head.BlockNumber())...) + return errors.New(errMsg) + } + + calculatedFinalityDepth := uint32(head.BlockNumber() - latestFinalizedHeadNumber) + if head.ChainLength() < calculatedFinalityDepth { if ec.nConsecutiveBlocksChainTooShort > logAfterNConsecutiveBlocksChainTooShort { - warnMsg := "Chain length supplied for re-org detection was shorter than FinalityDepth. Re-org protection is not working properly. This could indicate a problem with the remote RPC endpoint, a compatibility issue with a particular blockchain, a bug with this particular blockchain, heads table being truncated too early, remote node out of sync, or something else. If this happens a lot please raise a bug with the Chainlink team including a log output sample and details of the chain and RPC endpoint you are using." + warnMsg := "Chain length supplied for re-org detection was shorter than the depth from the latest head to the finalized head. Re-org protection is not working properly. This could indicate a problem with the remote RPC endpoint, a compatibility issue with a particular blockchain, a bug with this particular blockchain, heads table being truncated too early, remote node out of sync, or something else. If this happens a lot please raise a bug with the Chainlink team including a log output sample and details of the chain and RPC endpoint you are using." ec.lggr.Warnw(warnMsg, append(logArgs, "nConsecutiveBlocksChainTooShort", ec.nConsecutiveBlocksChainTooShort)...) } else { - logMsg := "Chain length supplied for re-org detection was shorter than FinalityDepth" + logMsg := "Chain length supplied for re-org detection was shorter than the depth from the latest head to the finalized head" ec.lggr.Debugw(logMsg, append(logArgs, "nConsecutiveBlocksChainTooShort", ec.nConsecutiveBlocksChainTooShort)...) } ec.nConsecutiveBlocksChainTooShort++ diff --git a/common/txmgr/types/mocks/tx_store.go b/common/txmgr/types/mocks/tx_store.go index 0b9c711066..4467729e16 100644 --- a/common/txmgr/types/mocks/tx_store.go +++ b/common/txmgr/types/mocks/tx_store.go @@ -1854,17 +1854,17 @@ func (_c *TxStore_MarkAllConfirmedMissingReceipt_Call[ADDR, CHAIN_ID, TX_HASH, B return _c } -// MarkOldTxesMissingReceiptAsErrored provides a mock function with given fields: ctx, blockNum, finalityDepth, chainID -func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) MarkOldTxesMissingReceiptAsErrored(ctx context.Context, blockNum int64, finalityDepth uint32, chainID CHAIN_ID) error { - ret := _m.Called(ctx, blockNum, finalityDepth, chainID) +// MarkOldTxesMissingReceiptAsErrored provides a mock function with given fields: ctx, blockNum, latestFinalizedBlockNum, chainID +func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) MarkOldTxesMissingReceiptAsErrored(ctx context.Context, blockNum int64, latestFinalizedBlockNum int64, chainID CHAIN_ID) error { + ret := _m.Called(ctx, blockNum, latestFinalizedBlockNum, chainID) if len(ret) == 0 { panic("no return value specified for MarkOldTxesMissingReceiptAsErrored") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, int64, uint32, CHAIN_ID) error); ok { - r0 = rf(ctx, blockNum, finalityDepth, chainID) + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, CHAIN_ID) error); ok { + r0 = rf(ctx, blockNum, latestFinalizedBlockNum, chainID) } else { r0 = ret.Error(0) } @@ -1880,15 +1880,15 @@ type TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR types.Hashable, CHAIN_ // MarkOldTxesMissingReceiptAsErrored is a helper method to define mock.On call // - ctx context.Context // - blockNum int64 -// - finalityDepth uint32 +// - latestFinalizedBlockNum int64 // - chainID CHAIN_ID -func (_e *TxStore_Expecter[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) MarkOldTxesMissingReceiptAsErrored(ctx interface{}, blockNum interface{}, finalityDepth interface{}, chainID interface{}) *TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { - return &TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]{Call: _e.mock.On("MarkOldTxesMissingReceiptAsErrored", ctx, blockNum, finalityDepth, chainID)} +func (_e *TxStore_Expecter[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) MarkOldTxesMissingReceiptAsErrored(ctx interface{}, blockNum interface{}, latestFinalizedBlockNum interface{}, chainID interface{}) *TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { + return &TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]{Call: _e.mock.On("MarkOldTxesMissingReceiptAsErrored", ctx, blockNum, latestFinalizedBlockNum, chainID)} } -func (_c *TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Run(run func(ctx context.Context, blockNum int64, finalityDepth uint32, chainID CHAIN_ID)) *TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { +func (_c *TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Run(run func(ctx context.Context, blockNum int64, latestFinalizedBlockNum int64, chainID CHAIN_ID)) *TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(int64), args[2].(uint32), args[3].(CHAIN_ID)) + run(args[0].(context.Context), args[1].(int64), args[2].(int64), args[3].(CHAIN_ID)) }) return _c } @@ -1898,7 +1898,7 @@ func (_c *TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HAS return _c } -func (_c *TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) RunAndReturn(run func(context.Context, int64, uint32, CHAIN_ID) error) *TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { +func (_c *TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) RunAndReturn(run func(context.Context, int64, int64, CHAIN_ID) error) *TxStore_MarkOldTxesMissingReceiptAsErrored_Call[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] { _c.Call.Return(run) return _c } diff --git a/common/txmgr/types/tx_store.go b/common/txmgr/types/tx_store.go index 63b56dd169..5489a57e63 100644 --- a/common/txmgr/types/tx_store.go +++ b/common/txmgr/types/tx_store.go @@ -89,7 +89,7 @@ type TransactionStore[ HasInProgressTransaction(ctx context.Context, account ADDR, chainID CHAIN_ID) (exists bool, err error) LoadTxAttempts(ctx context.Context, etx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) error MarkAllConfirmedMissingReceipt(ctx context.Context, chainID CHAIN_ID) (err error) - MarkOldTxesMissingReceiptAsErrored(ctx context.Context, blockNum int64, finalityDepth uint32, chainID CHAIN_ID) error + MarkOldTxesMissingReceiptAsErrored(ctx context.Context, blockNum int64, latestFinalizedBlockNum int64, chainID CHAIN_ID) error PreloadTxes(ctx context.Context, attempts []TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) error SaveConfirmedMissingReceiptAttempt(ctx context.Context, timeout time.Duration, attempt *TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], broadcastAt time.Time) error SaveInProgressAttempt(ctx context.Context, attempt *TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) error diff --git a/core/chains/evm/txmgr/builder.go b/core/chains/evm/txmgr/builder.go index d85d6acdc8..cbfb8775cf 100644 --- a/core/chains/evm/txmgr/builder.go +++ b/core/chains/evm/txmgr/builder.go @@ -1,6 +1,7 @@ package txmgr import ( + "context" "math/big" "time" @@ -13,12 +14,15 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/forwarders" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" - httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/keystore" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) +type latestAndFinalizedBlockHeadTracker interface { + LatestAndFinalizedBlock(ctx context.Context) (latest, finalized *evmtypes.Head, err error) +} + // NewTxm constructs the necessary dependencies for the EvmTxm (broadcaster, confirmer, etc) and returns a new EvmTxManager func NewTxm( ds sqlutil.DataSource, @@ -33,7 +37,7 @@ func NewTxm( logPoller logpoller.LogPoller, keyStore keystore.Eth, estimator gas.EvmFeeEstimator, - headTracker httypes.HeadTracker, + headTracker latestAndFinalizedBlockHeadTracker, ) (txm TxManager, err error, ) { @@ -55,7 +59,7 @@ func NewTxm( evmBroadcaster := NewEvmBroadcaster(txStore, txmClient, txmCfg, feeCfg, txConfig, listenerConfig, keyStore, txAttemptBuilder, lggr, checker, chainConfig.NonceAutoSync(), chainConfig.ChainType()) evmTracker := NewEvmTracker(txStore, keyStore, chainID, lggr) stuckTxDetector := NewStuckTxDetector(lggr, client.ConfiguredChainID(), chainConfig.ChainType(), fCfg.PriceMax(), txConfig.AutoPurge(), estimator, txStore, client) - evmConfirmer := NewEvmConfirmer(txStore, txmClient, txmCfg, feeCfg, txConfig, dbConfig, keyStore, txAttemptBuilder, lggr, stuckTxDetector) + evmConfirmer := NewEvmConfirmer(txStore, txmClient, txmCfg, feeCfg, txConfig, dbConfig, keyStore, txAttemptBuilder, lggr, stuckTxDetector, headTracker) evmFinalizer := NewEvmFinalizer(lggr, client.ConfiguredChainID(), chainConfig.RPCDefaultBatchSize(), txStore, client, headTracker) var evmResender *Resender if txConfig.ResendAfterThreshold() > 0 { @@ -116,8 +120,9 @@ func NewEvmConfirmer( txAttemptBuilder TxAttemptBuilder, lggr logger.Logger, stuckTxDetector StuckTxDetector, + headTracker latestAndFinalizedBlockHeadTracker, ) *Confirmer { - return txmgr.NewConfirmer(txStore, client, chainConfig, feeConfig, txConfig, dbConfig, keystore, txAttemptBuilder, lggr, func(r *evmtypes.Receipt) bool { return r == nil }, stuckTxDetector) + return txmgr.NewConfirmer(txStore, client, chainConfig, feeConfig, txConfig, dbConfig, keystore, txAttemptBuilder, lggr, func(r *evmtypes.Receipt) bool { return r == nil }, stuckTxDetector, headTracker) } // NewEvmTracker instantiates a new EVM tracker for abandoned transactions diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index 6b107b222a..cce6dc8fc6 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -34,6 +34,7 @@ import ( evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" gasmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/keystore" ksmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/keystore/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/testutils" @@ -131,7 +132,8 @@ func TestEthConfirmer_Lifecycle(t *testing.T) { feeEstimator := gas.NewEvmFeeEstimator(lggr, newEst, ge.EIP1559DynamicFees(), ge) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ethKeyStore, feeEstimator) stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), config.EVM().Transactions().AutoPurge(), feeEstimator, txStore, ethClient) - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), gconfig.Database(), ethKeyStore, txBuilder, lggr, stuckTxDetector) + ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), gconfig.Database(), ethKeyStore, txBuilder, lggr, stuckTxDetector, ht) ctx := tests.Context(t) // Can't close unstarted instance @@ -145,19 +147,27 @@ func TestEthConfirmer_Lifecycle(t *testing.T) { // Can't start an already started instance err = ec.Start(ctx) require.Error(t, err) + + latestFinalizedHead := evmtypes.Head{ + Number: 8, + Hash: testutils.NewHash(), + Parent: nil, + IsFinalized: true, // We are guaranteed to receive a latestFinalizedHead. + } + head := evmtypes.Head{ Hash: testutils.NewHash(), Number: 10, Parent: &evmtypes.Head{ Hash: testutils.NewHash(), Number: 9, - Parent: &evmtypes.Head{ - Number: 8, - Hash: testutils.NewHash(), - Parent: nil, - }, + Parent: &latestFinalizedHead, }, } + + ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(&head, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&latestFinalizedHead, nil).Once() + err = ec.ProcessHead(ctx, &head) require.NoError(t, err) // Can successfully close once @@ -199,6 +209,7 @@ func TestEthConfirmer_CheckForReceipts(t *testing.T) { nonce := int64(0) ctx := tests.Context(t) blockNum := int64(0) + latestFinalizedBlockNum := int64(0) t.Run("only finds eth_txes in unconfirmed state with at least one broadcast attempt", func(t *testing.T) { mustInsertFatalErrorEthTx(t, txStore, fromAddress) @@ -211,7 +222,7 @@ func TestEthConfirmer_CheckForReceipts(t *testing.T) { mustCreateUnstartedGeneratedTx(t, txStore, fromAddress, config.EVM().ChainID()) // Do the thing - require.NoError(t, ec.CheckForReceipts(ctx, blockNum)) + require.NoError(t, ec.CheckForReceipts(ctx, blockNum, latestFinalizedBlockNum)) }) etx1 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress) @@ -232,7 +243,7 @@ func TestEthConfirmer_CheckForReceipts(t *testing.T) { }).Once() // Do the thing - require.NoError(t, ec.CheckForReceipts(ctx, blockNum)) + require.NoError(t, ec.CheckForReceipts(ctx, blockNum, latestFinalizedBlockNum)) var err error etx1, err = txStore.FindTxWithAttempts(ctx, etx1.ID) @@ -261,7 +272,7 @@ func TestEthConfirmer_CheckForReceipts(t *testing.T) { }).Once() // No error because it is merely logged - require.NoError(t, ec.CheckForReceipts(ctx, blockNum)) + require.NoError(t, ec.CheckForReceipts(ctx, blockNum, latestFinalizedBlockNum)) etx, err := txStore.FindTxWithAttempts(ctx, etx1.ID) require.NoError(t, err) @@ -289,7 +300,7 @@ func TestEthConfirmer_CheckForReceipts(t *testing.T) { }).Once() // No error because it is merely logged - require.NoError(t, ec.CheckForReceipts(ctx, blockNum)) + require.NoError(t, ec.CheckForReceipts(ctx, blockNum, latestFinalizedBlockNum)) etx, err := txStore.FindTxWithAttempts(ctx, etx1.ID) require.NoError(t, err) @@ -326,7 +337,7 @@ func TestEthConfirmer_CheckForReceipts(t *testing.T) { }).Once() // Do the thing - require.NoError(t, ec.CheckForReceipts(ctx, blockNum)) + require.NoError(t, ec.CheckForReceipts(ctx, blockNum, latestFinalizedBlockNum)) // Check that the receipt was saved etx, err := txStore.FindTxWithAttempts(ctx, etx1.ID) @@ -388,7 +399,7 @@ func TestEthConfirmer_CheckForReceipts(t *testing.T) { }).Once() // Do the thing - require.NoError(t, ec.CheckForReceipts(ctx, blockNum)) + require.NoError(t, ec.CheckForReceipts(ctx, blockNum, latestFinalizedBlockNum)) // Check that the state was updated etx, err := txStore.FindTxWithAttempts(ctx, etx2.ID) @@ -416,7 +427,7 @@ func TestEthConfirmer_CheckForReceipts(t *testing.T) { }).Once() // Do the thing - require.NoError(t, ec.CheckForReceipts(ctx, blockNum)) + require.NoError(t, ec.CheckForReceipts(ctx, blockNum, latestFinalizedBlockNum)) // No receipt, but no error either etx, err := txStore.FindTxWithAttempts(ctx, etx3.ID) @@ -443,7 +454,7 @@ func TestEthConfirmer_CheckForReceipts(t *testing.T) { }).Once() // Do the thing - require.NoError(t, ec.CheckForReceipts(ctx, blockNum)) + require.NoError(t, ec.CheckForReceipts(ctx, blockNum, latestFinalizedBlockNum)) // No receipt, but no error either etx, err := txStore.FindTxWithAttempts(ctx, etx3.ID) @@ -472,7 +483,7 @@ func TestEthConfirmer_CheckForReceipts(t *testing.T) { }).Once() // Do the thing - require.NoError(t, ec.CheckForReceipts(ctx, blockNum)) + require.NoError(t, ec.CheckForReceipts(ctx, blockNum, latestFinalizedBlockNum)) // Check that the receipt was unchanged etx, err := txStore.FindTxWithAttempts(ctx, etx3.ID) @@ -523,7 +534,7 @@ func TestEthConfirmer_CheckForReceipts(t *testing.T) { }).Once() // Do the thing - require.NoError(t, ec.CheckForReceipts(ctx, blockNum)) + require.NoError(t, ec.CheckForReceipts(ctx, blockNum, latestFinalizedBlockNum)) // Check that the state was updated var err error @@ -576,7 +587,7 @@ func TestEthConfirmer_CheckForReceipts(t *testing.T) { }).Once() // Do the thing - require.NoError(t, ec.CheckForReceipts(ctx, blockNum)) + require.NoError(t, ec.CheckForReceipts(ctx, blockNum, latestFinalizedBlockNum)) // Check that the state was updated etx5, err = txStore.FindTxWithAttempts(ctx, etx5.ID) @@ -614,6 +625,7 @@ func TestEthConfirmer_CheckForReceipts_batching(t *testing.T) { etx := cltest.MustInsertUnconfirmedEthTx(t, txStore, 0, fromAddress) var attempts []txmgr.TxAttempt + latestFinalizedBlockNum := int64(0) // Total of 5 attempts should lead to 3 batched fetches (2, 2, 1) for i := 0; i < 5; i++ { @@ -650,7 +662,7 @@ func TestEthConfirmer_CheckForReceipts_batching(t *testing.T) { elems[0].Result = &evmtypes.Receipt{} }).Once() - require.NoError(t, ec.CheckForReceipts(ctx, 42)) + require.NoError(t, ec.CheckForReceipts(ctx, 42, latestFinalizedBlockNum)) } func TestEthConfirmer_CheckForReceipts_HandlesNonFwdTxsWithForwardingEnabled(t *testing.T) { @@ -671,6 +683,8 @@ func TestEthConfirmer_CheckForReceipts_HandlesNonFwdTxsWithForwardingEnabled(t * _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) ctx := tests.Context(t) + latestFinalizedBlockNum := int64(0) + // tx is not forwarded and doesn't have meta set. EthConfirmer should handle nil meta values etx := cltest.MustInsertUnconfirmedEthTx(t, txStore, 0, fromAddress) attempt := newBroadcastLegacyEthTxAttempt(t, etx.ID, 2) @@ -697,7 +711,7 @@ func TestEthConfirmer_CheckForReceipts_HandlesNonFwdTxsWithForwardingEnabled(t * *(elems[0].Result.(*evmtypes.Receipt)) = txmReceipt // confirmed }).Once() - require.NoError(t, ec.CheckForReceipts(ctx, 42)) + require.NoError(t, ec.CheckForReceipts(ctx, 42, latestFinalizedBlockNum)) // Check receipt is inserted correctly. dbtx, err = txStore.FindTxWithAttempts(ctx, etx.ID) @@ -724,6 +738,7 @@ func TestEthConfirmer_CheckForReceipts_only_likely_confirmed(t *testing.T) { ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) ctx := tests.Context(t) + latestFinalizedBlockNum := int64(0) var attempts []txmgr.TxAttempt // inserting in DESC nonce order to test DB ASC ordering @@ -755,7 +770,7 @@ func TestEthConfirmer_CheckForReceipts_only_likely_confirmed(t *testing.T) { elems[3].Result = &evmtypes.Receipt{} }).Once() - require.NoError(t, ec.CheckForReceipts(ctx, 42)) + require.NoError(t, ec.CheckForReceipts(ctx, 42, latestFinalizedBlockNum)) cltest.BatchElemMustMatchParams(t, captured[0], attempts[0].Hash, "eth_getTransactionReceipt") cltest.BatchElemMustMatchParams(t, captured[1], attempts[1].Hash, "eth_getTransactionReceipt") @@ -778,6 +793,7 @@ func TestEthConfirmer_CheckForReceipts_should_not_check_for_likely_unconfirmed(t ec := newEthConfirmer(t, txStore, ethClient, gconfig, config, ethKeyStore, nil) ctx := tests.Context(t) + latestFinalizedBlockNum := int64(0) etx := cltest.MustInsertUnconfirmedEthTx(t, txStore, 1, fromAddress) for i := 0; i < 4; i++ { @@ -788,7 +804,7 @@ func TestEthConfirmer_CheckForReceipts_should_not_check_for_likely_unconfirmed(t // latest nonce is lower that all attempts' nonces ethClient.On("SequenceAt", mock.Anything, mock.Anything, mock.Anything).Return(evmtypes.Nonce(0), nil) - require.NoError(t, ec.CheckForReceipts(ctx, 42)) + require.NoError(t, ec.CheckForReceipts(ctx, 42, latestFinalizedBlockNum)) } func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt_scoped_to_key(t *testing.T) { @@ -809,6 +825,7 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt_scoped_to_key(t ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) ctx := tests.Context(t) + latestFinalizedBlockNum := int64(0) // STATE // key 1, tx with nonce 0 is unconfirmed @@ -832,7 +849,7 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt_scoped_to_key(t *(elems[0].Result.(*evmtypes.Receipt)) = txmReceipt2_9 }).Once() - require.NoError(t, ec.CheckForReceipts(ctx, 10)) + require.NoError(t, ec.CheckForReceipts(ctx, 10, latestFinalizedBlockNum)) mustTxBeInState(t, txStore, etx1_0, txmgrcommon.TxUnconfirmed) mustTxBeInState(t, txStore, etx1_1, txmgrcommon.TxUnconfirmed) @@ -850,7 +867,7 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt_scoped_to_key(t *(elems[0].Result.(*evmtypes.Receipt)) = txmReceipt1_1 }).Once() - require.NoError(t, ec.CheckForReceipts(ctx, 11)) + require.NoError(t, ec.CheckForReceipts(ctx, 11, latestFinalizedBlockNum)) mustTxBeInState(t, txStore, etx1_0, txmgrcommon.TxConfirmedMissingReceipt) mustTxBeInState(t, txStore, etx1_1, txmgrcommon.TxConfirmed) @@ -861,9 +878,7 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].FinalityDepth = ptr[uint32](50) - }) + cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {}) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() @@ -876,6 +891,7 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt(t *testing.T) { ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) ctx := tests.Context(t) + latestFinalizedBlockNum := int64(0) // STATE // eth_txes with nonce 0 has two attempts (broadcast before block 21 and 41) the first of which will get a receipt @@ -949,7 +965,7 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt(t *testing.T) { // PERFORM // Block num of 43 is one higher than the receipt (as would generally be expected) - require.NoError(t, ec.CheckForReceipts(ctx, 43)) + require.NoError(t, ec.CheckForReceipts(ctx, 43, latestFinalizedBlockNum)) // Expected state is that the "top" eth_tx is now confirmed, with the // two below it "confirmed_missing_receipt" and the "bottom" eth_tx also confirmed @@ -1009,7 +1025,7 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt(t *testing.T) { // PERFORM // Block num of 44 is one higher than the receipt (as would generally be expected) - require.NoError(t, ec.CheckForReceipts(ctx, 44)) + require.NoError(t, ec.CheckForReceipts(ctx, 44, latestFinalizedBlockNum)) // Expected state is that the "top" two eth_txes are now confirmed, with the // one below it still "confirmed_missing_receipt" and the bottom one remains confirmed @@ -1038,7 +1054,7 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt(t *testing.T) { // eth_txes with nonce 2 is confirmed // eth_txes with nonce 3 is confirmed - t.Run("continues to leave eth_txes with state 'confirmed_missing_receipt' unchanged if at least one attempt is above EVM.FinalityDepth", func(t *testing.T) { + t.Run("continues to leave eth_txes with state 'confirmed_missing_receipt' unchanged if at least one attempt is above LatestFinalizedBlockNum", func(t *testing.T) { ethClient.On("SequenceAt", mock.Anything, mock.Anything, mock.Anything).Return(evmtypes.Nonce(10), nil) ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 2 && @@ -1051,9 +1067,11 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt(t *testing.T) { elems[1].Result = &evmtypes.Receipt{} }).Once() + latestFinalizedBlockNum = 30 + // PERFORM // Block num of 80 puts the first attempt (21) below threshold but second attempt (41) still above - require.NoError(t, ec.CheckForReceipts(ctx, 80)) + require.NoError(t, ec.CheckForReceipts(ctx, 80, latestFinalizedBlockNum)) // Expected state is that the "top" two eth_txes are now confirmed, with the // one below it still "confirmed_missing_receipt" and the bottom one remains confirmed @@ -1078,7 +1096,7 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt(t *testing.T) { // eth_txes with nonce 2 is confirmed // eth_txes with nonce 3 is confirmed - t.Run("marks eth_Txes with state 'confirmed_missing_receipt' as 'errored' if a receipt fails to show up and all attempts are buried deeper than EVM.FinalityDepth", func(t *testing.T) { + t.Run("marks eth_Txes with state 'confirmed_missing_receipt' as 'errored' if a receipt fails to show up and all attempts are buried deeper than LatestFinalizedBlockNum", func(t *testing.T) { ethClient.On("SequenceAt", mock.Anything, mock.Anything, mock.Anything).Return(evmtypes.Nonce(10), nil) ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 2 && @@ -1091,9 +1109,11 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt(t *testing.T) { elems[1].Result = &evmtypes.Receipt{} }).Once() + latestFinalizedBlockNum = 50 + // PERFORM // Block num of 100 puts the first attempt (21) and second attempt (41) below threshold - require.NoError(t, ec.CheckForReceipts(ctx, 100)) + require.NoError(t, ec.CheckForReceipts(ctx, 100, latestFinalizedBlockNum)) // Expected state is that the "top" two eth_txes are now confirmed, with the // one below it marked as "fatal_error" and the bottom one remains confirmed @@ -1117,9 +1137,7 @@ func TestEthConfirmer_CheckConfirmedMissingReceipt(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].FinalityDepth = ptr[uint32](50) - }) + cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {}) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() @@ -1197,9 +1215,7 @@ func TestEthConfirmer_CheckConfirmedMissingReceipt_batchSendTransactions_fails(t t.Parallel() db := pgtest.NewSqlxDB(t) - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].FinalityDepth = ptr[uint32](50) - }) + cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {}) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() @@ -1262,7 +1278,6 @@ func TestEthConfirmer_CheckConfirmedMissingReceipt_smallEvmRPCBatchSize_middleBa db := pgtest.NewSqlxDB(t) cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].FinalityDepth = ptr[uint32](50) c.EVM[0].RPCDefaultBatchSize = ptr[uint32](1) }) txStore := cltest.NewTestTxStore(t, db) @@ -1651,8 +1666,9 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing addresses := []gethCommon.Address{fromAddress} kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Maybe() stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), ccfg.EVM().Transactions().AutoPurge(), feeEstimator, txStore, ethClient) + ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) // Create confirmer with necessary state - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), ccfg.EVM(), txmgr.NewEvmTxmFeeConfig(ccfg.EVM().GasEstimator()), ccfg.EVM().Transactions(), cfg.Database(), kst, txBuilder, lggr, stuckTxDetector) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), ccfg.EVM(), txmgr.NewEvmTxmFeeConfig(ccfg.EVM().GasEstimator()), ccfg.EVM().Transactions(), cfg.Database(), kst, txBuilder, lggr, stuckTxDetector, ht) servicetest.Run(t, ec) currentHead := int64(30) oldEnough := int64(15) @@ -1700,7 +1716,8 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing addresses := []gethCommon.Address{fromAddress} kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Maybe() stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), ccfg.EVM().Transactions().AutoPurge(), feeEstimator, txStore, ethClient) - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), ccfg.EVM(), txmgr.NewEvmTxmFeeConfig(ccfg.EVM().GasEstimator()), ccfg.EVM().Transactions(), cfg.Database(), kst, txBuilder, lggr, stuckTxDetector) + ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), ccfg.EVM(), txmgr.NewEvmTxmFeeConfig(ccfg.EVM().GasEstimator()), ccfg.EVM().Transactions(), cfg.Database(), kst, txBuilder, lggr, stuckTxDetector, ht) servicetest.Run(t, ec) currentHead := int64(30) oldEnough := int64(15) @@ -2672,6 +2689,13 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { gconfig, config := newTestChainScopedConfig(t) ec := newEthConfirmer(t, txStore, ethClient, gconfig, config, ethKeyStore, nil) + latestFinalizedHead := evmtypes.Head{ + Number: 8, + Hash: testutils.NewHash(), + Parent: nil, + IsFinalized: false, // We are guaranteed to receive a latestFinalizedHead. + } + head := evmtypes.Head{ Hash: testutils.NewHash(), Number: 10, @@ -2685,16 +2709,15 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { }, }, } - t.Run("does nothing if there aren't any transactions", func(t *testing.T) { - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head)) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) }) t.Run("does nothing to unconfirmed transactions", func(t *testing.T) { etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress) // Do the thing - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head)) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -2706,7 +2729,7 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { mustInsertEthReceipt(t, txStore, head.Number, head.Hash, etx.TxAttempts[0].Hash) // Do the thing - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head)) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -2719,7 +2742,7 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { mustInsertEthReceipt(t, txStore, head.Parent.Parent.Number-1, testutils.NewHash(), etx.TxAttempts[0].Hash) // Do the thing - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head)) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -2740,7 +2763,7 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { }), fromAddress).Return(commonclient.Successful, nil).Once() // Do the thing - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head)) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -2763,7 +2786,7 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { commonclient.Successful, nil).Once() // Do the thing - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head)) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -2798,7 +2821,7 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { }), fromAddress).Return(commonclient.Successful, nil).Once() // Do the thing - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head)) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -2818,7 +2841,7 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { // Add receipt that is higher than head mustInsertEthReceipt(t, txStore, head.Number+1, testutils.NewHash(), attempt.Hash) - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head)) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -3158,7 +3181,8 @@ func TestEthConfirmer_ProcessStuckTransactions(t *testing.T) { ge := evmcfg.EVM().GasEstimator() txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ethKeyStore, feeEstimator) stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), evmcfg.EVM().Transactions().AutoPurge(), feeEstimator, txStore, ethClient) - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(ge), evmcfg.EVM().Transactions(), cfg.Database(), ethKeyStore, txBuilder, lggr, stuckTxDetector) + ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(ge), evmcfg.EVM().Transactions(), cfg.Database(), ethKeyStore, txBuilder, lggr, stuckTxDetector, ht) servicetest.Run(t, ec) ctx := tests.Context(t) @@ -3172,9 +3196,13 @@ func TestEthConfirmer_ProcessStuckTransactions(t *testing.T) { tx := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, nonce, fromAddress, autoPurgeMinAttempts, blockNum-int64(autoPurgeThreshold), marketGasPrice.Add(oneGwei)) head := evmtypes.Head{ - Hash: testutils.NewHash(), - Number: blockNum, + Hash: testutils.NewHash(), + Number: blockNum, + IsFinalized: true, } + + ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(&head, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&head, nil).Once() ethClient.On("SequenceAt", mock.Anything, mock.Anything, mock.Anything).Return(evmtypes.Nonce(0), nil).Once() ethClient.On("BatchCallContext", mock.Anything, mock.Anything).Return(nil).Once() @@ -3196,9 +3224,12 @@ func TestEthConfirmer_ProcessStuckTransactions(t *testing.T) { require.Equal(t, bumpedFee.Legacy, latestAttempt.TxFee.Legacy) head = evmtypes.Head{ - Hash: testutils.NewHash(), - Number: blockNum + 1, + Hash: testutils.NewHash(), + Number: blockNum + 1, + IsFinalized: true, } + ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(&head, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&head, nil).Once() ethClient.On("SequenceAt", mock.Anything, mock.Anything, mock.Anything).Return(evmtypes.Nonce(1), nil) ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 4 && cltest.BatchElemMatchesParams(b[0], latestAttempt.Hash, "eth_getTransactionReceipt") @@ -3237,7 +3268,8 @@ func newEthConfirmer(t testing.TB, txStore txmgr.EvmTxStore, ethClient client.Cl }, ge.EIP1559DynamicFees(), ge) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ks, estimator) stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), config.EVM().Transactions().AutoPurge(), estimator, txStore, ethClient) - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), gconfig.Database(), ks, txBuilder, lggr, stuckTxDetector) + ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), gconfig.Database(), ks, txBuilder, lggr, stuckTxDetector, ht) ec.SetResumeCallback(fn) servicetest.Run(t, ec) return ec diff --git a/core/chains/evm/txmgr/evm_tx_store.go b/core/chains/evm/txmgr/evm_tx_store.go index 45de437e44..4bdf191376 100644 --- a/core/chains/evm/txmgr/evm_tx_store.go +++ b/core/chains/evm/txmgr/evm_tx_store.go @@ -34,8 +34,8 @@ import ( var ( ErrKeyNotUpdated = errors.New("evmTxStore: Key not updated") - // ErrCouldNotGetReceipt is the error string we save if we reach our finality depth for a confirmed transaction without ever getting a receipt - // This most likely happened because an external wallet used the account for this nonce + // ErrCouldNotGetReceipt is the error string we save if we reach our LatestFinalizedBlockNum for a confirmed transaction + // without ever getting a receipt. This most likely happened because an external wallet used the account for this nonce ErrCouldNotGetReceipt = "could not get receipt" ) @@ -959,11 +959,11 @@ func (o *evmTxStore) SaveFetchedReceipts(ctx context.Context, r []*evmtypes.Rece // NOTE: We continue to attempt to resend evm.txes in this state on // every head to guard against the extremely rare scenario of nonce gap due to // reorg that excludes the transaction (from another wallet) that had this -// nonce (until finality depth is reached, after which we make the explicit +// nonce (until LatestFinalizedBlockNum is reached, after which we make the explicit // decision to give up). This is done in the EthResender. // // We will continue to try to fetch a receipt for these attempts until all -// attempts are below the finality depth from current head. +// attempts are equal to or below the LatestFinalizedBlockNum from current head. func (o *evmTxStore) MarkAllConfirmedMissingReceipt(ctx context.Context, chainID *big.Int) (err error) { var cancel context.CancelFunc ctx, cancel = o.stopCh.Ctx(ctx) @@ -1430,23 +1430,18 @@ ORDER BY nonce ASC // markOldTxesMissingReceiptAsErrored // -// Once eth_tx has all of its attempts broadcast before some cutoff threshold +// Once eth_tx has all of its attempts broadcast equal to or before latestFinalizedBlockNum // without receiving any receipts, we mark it as fatally errored (never sent). // // The job run will also be marked as errored in this case since we never got a // receipt and thus cannot pass on any transaction hash -func (o *evmTxStore) MarkOldTxesMissingReceiptAsErrored(ctx context.Context, blockNum int64, finalityDepth uint32, chainID *big.Int) error { +func (o *evmTxStore) MarkOldTxesMissingReceiptAsErrored(ctx context.Context, blockNum int64, latestFinalizedBlockNum int64, chainID *big.Int) error { var cancel context.CancelFunc ctx, cancel = o.stopCh.Ctx(ctx) defer cancel() - // cutoffBlockNum is a block height - // Any 'confirmed_missing_receipt' eth_tx with all attempts older than this block height will be marked as errored - // We will not try to query for receipts for this transaction any more - cutoff := blockNum - int64(finalityDepth) - if cutoff <= 0 { - return nil - } - if cutoff <= 0 { + // Any 'confirmed_missing_receipt' eth_tx with all attempts equal to or older than latestFinalizedBlockNum will be marked as errored + // We will not try to query for receipts for this transaction anymore + if latestFinalizedBlockNum <= 0 { return nil } // note: if QOpt passes in a sql.Tx this will reuse it @@ -1466,12 +1461,12 @@ FROM ( WHERE e2.state = 'confirmed_missing_receipt' AND e2.evm_chain_id = $3 GROUP BY e2.id - HAVING max(evm.tx_attempts.broadcast_before_block_num) < $2 + HAVING max(evm.tx_attempts.broadcast_before_block_num) <= $2 ) FOR UPDATE OF e1 ) e0 WHERE e0.id = evm.txes.id -RETURNING e0.id, e0.nonce`, ErrCouldNotGetReceipt, cutoff, chainID.String()) +RETURNING e0.id, e0.nonce`, ErrCouldNotGetReceipt, latestFinalizedBlockNum, chainID.String()) if err != nil { return pkgerrors.Wrap(err, "markOldTxesMissingReceiptAsErrored failed to query") diff --git a/core/chains/evm/txmgr/evm_tx_store_test.go b/core/chains/evm/txmgr/evm_tx_store_test.go index 191a0a5fed..992bd1f434 100644 --- a/core/chains/evm/txmgr/evm_tx_store_test.go +++ b/core/chains/evm/txmgr/evm_tx_store_test.go @@ -1117,13 +1117,14 @@ func TestORM_MarkOldTxesMissingReceiptAsErrored(t *testing.T) { ethKeyStore := cltest.NewKeyStore(t, db).Eth() ethClient := evmtest.NewEthClientMockWithDefaultChain(t) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) + latestFinalizedBlockNum := int64(8) // tx state should be confirmed missing receipt - // attempt should be broadcast before cutoff time + // attempt should be before latestFinalizedBlockNum t.Run("successfully mark errored transactions", func(t *testing.T) { etx := mustInsertConfirmedMissingReceiptEthTxWithLegacyAttempt(t, txStore, 1, 7, time.Now(), fromAddress) - err := txStore.MarkOldTxesMissingReceiptAsErrored(tests.Context(t), 10, 2, ethClient.ConfiguredChainID()) + err := txStore.MarkOldTxesMissingReceiptAsErrored(tests.Context(t), 10, latestFinalizedBlockNum, ethClient.ConfiguredChainID()) require.NoError(t, err) etx, err = txStore.FindTxWithAttempts(ctx, etx.ID) @@ -1133,7 +1134,7 @@ func TestORM_MarkOldTxesMissingReceiptAsErrored(t *testing.T) { t.Run("successfully mark errored transactions w/ qopt passing in sql.Tx", func(t *testing.T) { etx := mustInsertConfirmedMissingReceiptEthTxWithLegacyAttempt(t, txStore, 1, 7, time.Now(), fromAddress) - err := txStore.MarkOldTxesMissingReceiptAsErrored(tests.Context(t), 10, 2, ethClient.ConfiguredChainID()) + err := txStore.MarkOldTxesMissingReceiptAsErrored(tests.Context(t), 10, latestFinalizedBlockNum, ethClient.ConfiguredChainID()) require.NoError(t, err) // must run other query outside of postgres transaction so changes are committed diff --git a/core/chains/evm/txmgr/mocks/evm_tx_store.go b/core/chains/evm/txmgr/mocks/evm_tx_store.go index b40c0ca837..a9a175e3d9 100644 --- a/core/chains/evm/txmgr/mocks/evm_tx_store.go +++ b/core/chains/evm/txmgr/mocks/evm_tx_store.go @@ -2214,17 +2214,17 @@ func (_c *EvmTxStore_MarkAllConfirmedMissingReceipt_Call) RunAndReturn(run func( return _c } -// MarkOldTxesMissingReceiptAsErrored provides a mock function with given fields: ctx, blockNum, finalityDepth, chainID -func (_m *EvmTxStore) MarkOldTxesMissingReceiptAsErrored(ctx context.Context, blockNum int64, finalityDepth uint32, chainID *big.Int) error { - ret := _m.Called(ctx, blockNum, finalityDepth, chainID) +// MarkOldTxesMissingReceiptAsErrored provides a mock function with given fields: ctx, blockNum, latestFinalizedBlockNum, chainID +func (_m *EvmTxStore) MarkOldTxesMissingReceiptAsErrored(ctx context.Context, blockNum int64, latestFinalizedBlockNum int64, chainID *big.Int) error { + ret := _m.Called(ctx, blockNum, latestFinalizedBlockNum, chainID) if len(ret) == 0 { panic("no return value specified for MarkOldTxesMissingReceiptAsErrored") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, int64, uint32, *big.Int) error); ok { - r0 = rf(ctx, blockNum, finalityDepth, chainID) + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, *big.Int) error); ok { + r0 = rf(ctx, blockNum, latestFinalizedBlockNum, chainID) } else { r0 = ret.Error(0) } @@ -2240,15 +2240,15 @@ type EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call struct { // MarkOldTxesMissingReceiptAsErrored is a helper method to define mock.On call // - ctx context.Context // - blockNum int64 -// - finalityDepth uint32 +// - latestFinalizedBlockNum int64 // - chainID *big.Int -func (_e *EvmTxStore_Expecter) MarkOldTxesMissingReceiptAsErrored(ctx interface{}, blockNum interface{}, finalityDepth interface{}, chainID interface{}) *EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call { - return &EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call{Call: _e.mock.On("MarkOldTxesMissingReceiptAsErrored", ctx, blockNum, finalityDepth, chainID)} +func (_e *EvmTxStore_Expecter) MarkOldTxesMissingReceiptAsErrored(ctx interface{}, blockNum interface{}, latestFinalizedBlockNum interface{}, chainID interface{}) *EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call { + return &EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call{Call: _e.mock.On("MarkOldTxesMissingReceiptAsErrored", ctx, blockNum, latestFinalizedBlockNum, chainID)} } -func (_c *EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call) Run(run func(ctx context.Context, blockNum int64, finalityDepth uint32, chainID *big.Int)) *EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call { +func (_c *EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call) Run(run func(ctx context.Context, blockNum int64, latestFinalizedBlockNum int64, chainID *big.Int)) *EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(int64), args[2].(uint32), args[3].(*big.Int)) + run(args[0].(context.Context), args[1].(int64), args[2].(int64), args[3].(*big.Int)) }) return _c } @@ -2258,7 +2258,7 @@ func (_c *EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call) Return(_a0 error) return _c } -func (_c *EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call) RunAndReturn(run func(context.Context, int64, uint32, *big.Int) error) *EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call { +func (_c *EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call) RunAndReturn(run func(context.Context, int64, int64, *big.Int) error) *EvmTxStore_MarkOldTxesMissingReceiptAsErrored_Call { _c.Call.Return(run) return _c } diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index 5f932db872..3d52e6eb4f 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -627,6 +627,7 @@ func TestTxm_GetTransactionStatus(t *testing.T) { ethClient.On("PendingNonceAt", mock.Anything, mock.Anything).Return(uint64(0), nil).Maybe() ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head.Parent, nil).Once() + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil) feeEstimator := gasmocks.NewEvmFeeEstimator(t) feeEstimator.On("Start", mock.Anything).Return(nil).Once() feeEstimator.On("Close", mock.Anything).Return(nil).Once() diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index e19cc485d8..ed8b653c05 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -669,7 +669,7 @@ func (s *Shell) RebroadcastTransactions(c *cli.Context) (err error) { feeCfg := txmgr.NewEvmTxmFeeConfig(chain.Config().EVM().GasEstimator()) stuckTxDetector := txmgr.NewStuckTxDetector(lggr, ethClient.ConfiguredChainID(), "", assets.NewWei(assets.NewEth(100).ToInt()), chain.Config().EVM().Transactions().AutoPurge(), nil, orm, ethClient) ec := txmgr.NewEvmConfirmer(orm, txmgr.NewEvmTxmClient(ethClient, chain.Config().EVM().NodePool().Errors()), - cfg, feeCfg, chain.Config().EVM().Transactions(), app.GetConfig().Database(), keyStore.Eth(), txBuilder, chain.Logger(), stuckTxDetector) + cfg, feeCfg, chain.Config().EVM().Transactions(), app.GetConfig().Database(), keyStore.Eth(), txBuilder, chain.Logger(), stuckTxDetector, chain.HeadTracker()) totalNonces := endingNonce - beginningNonce + 1 nonces := make([]evmtypes.Nonce, totalNonces) for i := int64(0); i < totalNonces; i++ { diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go index 60545269e2..8ed48dcaa2 100644 --- a/core/cmd/shell_local_test.go +++ b/core/cmd/shell_local_test.go @@ -11,9 +11,8 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - "github.com/smartcontractkit/chainlink/v2/core/capabilities" - "github.com/smartcontractkit/chainlink/v2/common/client" + "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/cmd" cmdMocks "github.com/smartcontractkit/chainlink/v2/core/cmd/mocks" diff --git a/core/internal/cltest/mocks.go b/core/internal/cltest/mocks.go index 9e0ee2f3f2..fd01f72c13 100644 --- a/core/internal/cltest/mocks.go +++ b/core/internal/cltest/mocks.go @@ -392,6 +392,7 @@ func NewLegacyChainsWithMockChain(t testing.TB, ethClient evmclient.Client, cfg scopedCfg := evmtest.NewChainScopedConfig(t, cfg) ch.On("ID").Return(scopedCfg.EVM().ChainID()) ch.On("Config").Return(scopedCfg) + ch.On("HeadTracker").Return(nil) return NewLegacyChainsWithChain(ch, cfg) } From 1fcfd80af03e12828b18a4fded88a2cca0f77e65 Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Sun, 11 Aug 2024 23:25:22 -0700 Subject: [PATCH 078/432] [Keystone] Minor fixes (#14091) A bundle of minor fixes in several components: 1. Launcher: adjust defaultStreamConfig values to a resonable max capacity (250 MB per channel) 2. Trigger shims: change some incorrect read-locks to rw-locks 3. Trigger shims: enforce max possible number of bundled worklflow IDs in an event 4. Mode Aggregator: avoid unnecessary early exit 5. Message Cache: avoid unnecessary early exit while collecting ready messages --- core/capabilities/launcher.go | 12 +++++----- core/capabilities/remote/message_cache.go | 8 +++---- core/capabilities/remote/trigger_publisher.go | 4 ++-- .../capabilities/remote/trigger_subscriber.go | 24 ++++++++++++------- core/capabilities/remote/utils.go | 3 ++- 5 files changed, 29 insertions(+), 22 deletions(-) diff --git a/core/capabilities/launcher.go b/core/capabilities/launcher.go index 3fc321087b..3182b192b7 100644 --- a/core/capabilities/launcher.go +++ b/core/capabilities/launcher.go @@ -28,16 +28,16 @@ import ( ) var defaultStreamConfig = p2ptypes.StreamConfig{ - IncomingMessageBufferSize: 1000000, - OutgoingMessageBufferSize: 1000000, - MaxMessageLenBytes: 100000, + IncomingMessageBufferSize: 500, + OutgoingMessageBufferSize: 500, + MaxMessageLenBytes: 500000, // 500 KB; max capacity = 500 * 500000 = 250 MB MessageRateLimiter: ragep2p.TokenBucketParams{ Rate: 100.0, - Capacity: 1000, + Capacity: 500, }, BytesRateLimiter: ragep2p.TokenBucketParams{ - Rate: 100000.0, - Capacity: 1000000, + Rate: 5000000.0, // 5 MB/s + Capacity: 10000000, // 10 MB }, } diff --git a/core/capabilities/remote/message_cache.go b/core/capabilities/remote/message_cache.go index 27f909c516..f3a3a79b2c 100644 --- a/core/capabilities/remote/message_cache.go +++ b/core/capabilities/remote/message_cache.go @@ -60,12 +60,12 @@ func (c *messageCache[EventID, PeerID]) Ready(eventID EventID, minCount uint32, if msg.timestamp >= minTimestamp { countAboveMinTimestamp++ accPayloads = append(accPayloads, msg.payload) - if countAboveMinTimestamp >= minCount { - ev.wasReady = true - return true, accPayloads - } } } + if countAboveMinTimestamp >= minCount { + ev.wasReady = true + return true, accPayloads + } return false, nil } diff --git a/core/capabilities/remote/trigger_publisher.go b/core/capabilities/remote/trigger_publisher.go index b4d749754d..23b778f601 100644 --- a/core/capabilities/remote/trigger_publisher.go +++ b/core/capabilities/remote/trigger_publisher.go @@ -163,7 +163,7 @@ func (p *triggerPublisher) registrationCleanupLoop() { return case <-ticker.C: now := time.Now().UnixMilli() - p.mu.RLock() + p.mu.Lock() for key, req := range p.registrations { callerDon := p.workflowDONs[key.callerDonId] ready, _ := p.messageCache.Ready(key, uint32(2*callerDon.F+1), now-p.config.RegistrationExpiry.Milliseconds(), false) @@ -178,7 +178,7 @@ func (p *triggerPublisher) registrationCleanupLoop() { p.messageCache.Delete(key) } } - p.mu.RUnlock() + p.mu.Unlock() } } } diff --git a/core/capabilities/remote/trigger_subscriber.go b/core/capabilities/remote/trigger_subscriber.go index d957614886..c932dc68e3 100644 --- a/core/capabilities/remote/trigger_subscriber.go +++ b/core/capabilities/remote/trigger_subscriber.go @@ -6,7 +6,6 @@ import ( sync "sync" "time" - "github.com/smartcontractkit/chainlink-common/pkg/capabilities" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/services" @@ -23,11 +22,11 @@ import ( // // TriggerSubscriber communicates with corresponding TriggerReceivers on remote nodes. type triggerSubscriber struct { - config *capabilities.RemoteTriggerConfig + config *commoncap.RemoteTriggerConfig capInfo commoncap.CapabilityInfo - capDonInfo capabilities.DON + capDonInfo commoncap.DON capDonMembers map[p2ptypes.PeerID]struct{} - localDonInfo capabilities.DON + localDonInfo commoncap.DON dispatcher types.Dispatcher aggregator types.Aggregator messageCache *messageCache[triggerEventKey, p2ptypes.PeerID] @@ -53,16 +52,19 @@ var _ types.Receiver = &triggerSubscriber{} var _ services.Service = &triggerSubscriber{} // TODO makes this configurable with a default -const defaultSendChannelBufferSize = 1000 +const ( + defaultSendChannelBufferSize = 1000 + maxBatchedWorkflowIDs = 1000 +) -func NewTriggerSubscriber(config *capabilities.RemoteTriggerConfig, capInfo commoncap.CapabilityInfo, capDonInfo capabilities.DON, localDonInfo capabilities.DON, dispatcher types.Dispatcher, aggregator types.Aggregator, lggr logger.Logger) *triggerSubscriber { +func NewTriggerSubscriber(config *commoncap.RemoteTriggerConfig, capInfo commoncap.CapabilityInfo, capDonInfo commoncap.DON, localDonInfo commoncap.DON, dispatcher types.Dispatcher, aggregator types.Aggregator, lggr logger.Logger) *triggerSubscriber { if aggregator == nil { lggr.Warnw("no aggregator provided, using default MODE aggregator", "capabilityId", capInfo.ID) aggregator = NewDefaultModeAggregator(uint32(capDonInfo.F + 1)) } if config == nil { lggr.Info("no config provided, using default values") - config = &capabilities.RemoteTriggerConfig{} + config = &commoncap.RemoteTriggerConfig{} } config.ApplyDefaults() capDonMembers := make(map[p2ptypes.PeerID]struct{}) @@ -184,6 +186,10 @@ func (s *triggerSubscriber) Receive(_ context.Context, msg *types.MessageBody) { s.lggr.Errorw("received message with invalid trigger metadata", "capabilityId", s.capInfo.ID, "sender", sender) return } + if len(meta.WorkflowIds) > maxBatchedWorkflowIDs { + s.lggr.Errorw("received message with too many workflow IDs - truncating", "capabilityId", s.capInfo.ID, "nWorkflows", len(meta.WorkflowIds), "sender", sender) + meta.WorkflowIds = meta.WorkflowIds[:maxBatchedWorkflowIDs] + } for _, workflowId := range meta.WorkflowIds { s.mu.RLock() registration, found := s.registeredWorkflows[workflowId] @@ -197,10 +203,10 @@ func (s *triggerSubscriber) Receive(_ context.Context, msg *types.MessageBody) { workflowId: workflowId, } nowMs := time.Now().UnixMilli() - s.mu.RLock() + s.mu.Lock() creationTs := s.messageCache.Insert(key, sender, nowMs, msg.Payload) ready, payloads := s.messageCache.Ready(key, s.config.MinResponsesToAggregate, nowMs-s.config.MessageExpiry.Milliseconds(), true) - s.mu.RUnlock() + s.mu.Unlock() if nowMs-creationTs > s.config.RegistrationExpiry.Milliseconds() { s.lggr.Warnw("received trigger event for an expired ID", "triggerEventID", meta.TriggerEventId, "capabilityId", s.capInfo.ID, "workflowId", workflowId, "sender", sender) continue diff --git a/core/capabilities/remote/utils.go b/core/capabilities/remote/utils.go index 10e4e3082c..7e303eefc8 100644 --- a/core/capabilities/remote/utils.go +++ b/core/capabilities/remote/utils.go @@ -92,7 +92,8 @@ func AggregateModeRaw(elemList [][]byte, minIdenticalResponses uint32) ([]byte, hashToCount[sha]++ if hashToCount[sha] >= minIdenticalResponses { found = elem - break + // update in case we find another elem with an even higher count + minIdenticalResponses = hashToCount[sha] } } if found == nil { From 518cc281b14727c26cd7fcb9db882b45837d443a Mon Sep 17 00:00:00 2001 From: kanth <70688600+defistar@users.noreply.github.com> Date: Mon, 12 Aug 2024 17:26:04 +0530 Subject: [PATCH 079/432] feat: CCIP-2465 enumerableMap for addressToBytes Mapping (#14012) * feat: CCIP-2465 enumerableMap for addressToBytes Mapping * fix: CCIP-2465 prettier write for new library contracts * fix: CCIP-2465 gas-snapshot updated and changeset added for new library * fix: CCIP-2465 gassnapshot corrections for EnumerableAddresses --- contracts/.changeset/nice-planets-share.md | 5 + contracts/gas-snapshots/shared.gas-snapshot | 28 ++-- .../enumerable/EnumerableMapAddresses.sol | 89 +++++++++++- .../enumerable/EnumerableMapBytes32.sol | 136 ++++++++++++++++++ .../enumerable/EnumerableMapAddresses.t.sol | 111 +++++++++++--- 5 files changed, 338 insertions(+), 31 deletions(-) create mode 100644 contracts/.changeset/nice-planets-share.md create mode 100644 contracts/src/v0.8/shared/enumerable/EnumerableMapBytes32.sol diff --git a/contracts/.changeset/nice-planets-share.md b/contracts/.changeset/nice-planets-share.md new file mode 100644 index 0000000000..a8af56ac61 --- /dev/null +++ b/contracts/.changeset/nice-planets-share.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': minor +--- + +EnumerableMap Library for an Address to Bytes mapping diff --git a/contracts/gas-snapshots/shared.gas-snapshot b/contracts/gas-snapshots/shared.gas-snapshot index 0419c42a6a..3cc143ecc0 100644 --- a/contracts/gas-snapshots/shared.gas-snapshot +++ b/contracts/gas-snapshots/shared.gas-snapshot @@ -51,21 +51,29 @@ CallWithExactGas__callWithExactGasSafeReturnData:test_NoContractReverts() (gas: CallWithExactGas__callWithExactGasSafeReturnData:test_NoGasForCallExactCheckReverts() (gas: 16139) CallWithExactGas__callWithExactGasSafeReturnData:test_NotEnoughGasForCallReverts() (gas: 16547) CallWithExactGas__callWithExactGasSafeReturnData:test_callWithExactGasSafeReturnData_ThrowOOGError_Revert() (gas: 36752) -EnumerableMapAddresses_at:testAtSuccess() (gas: 95001) -EnumerableMapAddresses_at:testBytes32AtSuccess() (gas: 94770) +EnumerableMapAddresses_at:testAtSuccess() (gas: 95086) +EnumerableMapAddresses_at:testBytes32AtSuccess() (gas: 94877) EnumerableMapAddresses_contains:testBytes32ContainsSuccess() (gas: 93518) EnumerableMapAddresses_contains:testContainsSuccess() (gas: 93696) -EnumerableMapAddresses_get:testBytes32GetSuccess() (gas: 94249) -EnumerableMapAddresses_get:testGetSuccess() (gas: 94436) -EnumerableMapAddresses_get_errorMessage:testGetErrorMessageSuccess() (gas: 94477) -EnumerableMapAddresses_length:testBytes32LengthSuccess() (gas: 72404) -EnumerableMapAddresses_length:testLengthSuccess() (gas: 72582) -EnumerableMapAddresses_remove:testBytes32RemoveSuccess() (gas: 73408) +EnumerableMapAddresses_get:testBytes32GetSuccess() (gas: 94278) +EnumerableMapAddresses_get:testGetSuccess() (gas: 94453) +EnumerableMapAddresses_get_errorMessage:testGetErrorMessageSuccess() (gas: 94489) +EnumerableMapAddresses_length:testBytes32LengthSuccess() (gas: 72445) +EnumerableMapAddresses_length:testLengthSuccess() (gas: 72640) +EnumerableMapAddresses_remove:testBytes32RemoveSuccess() (gas: 73462) EnumerableMapAddresses_remove:testRemoveSuccess() (gas: 73686) EnumerableMapAddresses_set:testBytes32SetSuccess() (gas: 94496) EnumerableMapAddresses_set:testSetSuccess() (gas: 94685) -EnumerableMapAddresses_tryGet:testBytes32TryGetSuccess() (gas: 94604) -EnumerableMapAddresses_tryGet:testTryGetSuccess() (gas: 94864) +EnumerableMapAddresses_tryGet:testBytes32TryGetSuccess() (gas: 94622) +EnumerableMapAddresses_tryGet:testTryGetSuccess() (gas: 94893) +EnumerableMapAddresses_at:testBytesAtSuccess() (gas: 96564) +EnumerableMapAddresses_contains:testBytesContainsSuccess() (gas: 94012) +EnumerableMapAddresses_get:testBytesGetSuccess() (gas: 95879) +EnumerableMapAddresses_get_errorMessage:testBytesGetErrorMessageSuccess() (gas: 95878) +EnumerableMapAddresses_length:testBytesLengthSuccess() (gas: 73011) +EnumerableMapAddresses_remove:testBytesRemoveSuccess() (gas: 74249) +EnumerableMapAddresses_set:testBytesSetSuccess() (gas: 95428) +EnumerableMapAddresses_tryGet:testBytesTryGetSuccess() (gas: 96279) OpStackBurnMintERC677_constructor:testConstructorSuccess() (gas: 1743649) OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 298649) OpStackBurnMintERC677_interfaceCompatibility:testMintCompatibility() (gas: 137957) diff --git a/contracts/src/v0.8/shared/enumerable/EnumerableMapAddresses.sol b/contracts/src/v0.8/shared/enumerable/EnumerableMapAddresses.sol index 6fbd37c60d..c14a03b444 100644 --- a/contracts/src/v0.8/shared/enumerable/EnumerableMapAddresses.sol +++ b/contracts/src/v0.8/shared/enumerable/EnumerableMapAddresses.sol @@ -1,12 +1,15 @@ // SPDX-License-Identifier: MIT +/* solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore */ pragma solidity ^0.8.0; import {EnumerableMap} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableMap.sol"; +import {EnumerableMapBytes32} from "./EnumerableMapBytes32.sol"; // TODO: the lib can be replaced with OZ v5.1 post-upgrade, which has AddressToAddressMap and AddressToBytes32Map library EnumerableMapAddresses { using EnumerableMap for EnumerableMap.UintToAddressMap; using EnumerableMap for EnumerableMap.Bytes32ToBytes32Map; + using EnumerableMapBytes32 for EnumerableMapBytes32.Bytes32ToBytesMap; struct AddressToAddressMap { EnumerableMap.UintToAddressMap _inner; @@ -57,8 +60,6 @@ library EnumerableMapAddresses { return map._inner.get(uint256(uint160(key)), errorMessage); } - // AddressToBytes32Map - struct AddressToBytes32Map { EnumerableMap.Bytes32ToBytes32Map _inner; } @@ -137,4 +138,88 @@ library EnumerableMapAddresses { function get(AddressToBytes32Map storage map, address key) internal view returns (bytes32) { return map._inner.get(bytes32(uint256(uint160(key)))); } + + struct AddressToBytesMap { + EnumerableMapBytes32.Bytes32ToBytesMap _inner; + } + + /** + * @dev Sets the value for `key` in the map. Returns true if the key was added to the map, that is if it was not already present. + * @param map The map where the value will be set + * @param key The key to set the value for + * @param value The value to set for the key + * @return bool indicating whether the key was added to the map + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function set(AddressToBytesMap storage map, address key, bytes memory value) internal returns (bool) { + return map._inner.set(bytes32(uint256(uint160(key))), value); + } + + /** + * @dev Removes the value for `key` in the map. Returns true if the key was removed from the map, that is if it was present. + * @param map The map where the value will be removed + * @param key The key to remove the value for + * @return bool indicating whether the key was removed from the map + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function remove(AddressToBytesMap storage map, address key) internal returns (bool) { + return map._inner.remove(bytes32(uint256(uint160(key)))); + } + + /** + * @dev Checks if the map contains the `key`. Returns true if the key is in the map. + * @param map The map to check for the presence of the key + * @param key The key to check for presence in the map + * @return bool indicating whether the key is in the map + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function contains(AddressToBytesMap storage map, address key) internal view returns (bool) { + return map._inner.contains(bytes32(uint256(uint160(key)))); + } + + /** + * @dev Returns the number of elements in the map. + * @param map The map to check the length of + * @return uint256 indicating the number of elements in the map + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function length(AddressToBytesMap storage map) internal view returns (uint256) { + return map._inner.length(); + } + + /** + * @dev Returns the element stored at position `index` in the map. Note that there are no guarantees on the ordering of values inside the array, and it may change when more values are added or removed. + * @param map The map to retrieve the element from + * @param index The index to retrieve the element at + * @return address The key of the element at the specified index + * @return bytes The value of the element at the specified index + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function at(AddressToBytesMap storage map, uint256 index) internal view returns (address, bytes memory) { + (bytes32 key, bytes memory value) = map._inner.at(index); + return (address(uint160(uint256(key))), value); + } + + /** + * @dev Tries to return the value associated with `key`. Does not revert if `key` is not in the map. + * @param map The map to retrieve the value from + * @param key The key to retrieve the value for + * @return bool indicating whether the key was in the map + * @return bytes The value associated with the key + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function tryGet(AddressToBytesMap storage map, address key) internal view returns (bool, bytes memory) { + return map._inner.tryGet(bytes32(uint256(uint160(key)))); + } + + /** + * @dev Returns the value associated with `key`. + * @param map The map to retrieve the value from + * @param key The key to retrieve the value for + * @return bytes The value associated with the key + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function get(AddressToBytesMap storage map, address key) internal view returns (bytes memory) { + return map._inner.get(bytes32(uint256(uint160(key)))); + } } diff --git a/contracts/src/v0.8/shared/enumerable/EnumerableMapBytes32.sol b/contracts/src/v0.8/shared/enumerable/EnumerableMapBytes32.sol new file mode 100644 index 0000000000..2ec9098f85 --- /dev/null +++ b/contracts/src/v0.8/shared/enumerable/EnumerableMapBytes32.sol @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT +/* solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore */ +pragma solidity ^0.8.0; + +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +/** + * @dev Library for managing an enumerable variant of Solidity's + * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] + * type. + * + * Maps have the following properties: + * + * - Entries are added, removed, and checked for existence in constant time + * (O(1)). + * - Entries are enumerated in O(n). No guarantees are made on the ordering. + * + * ``` + * contract Example { + * // Add the library methods + * using EnumerableMapBytes32 for EnumerableMapBytes32.Bytes32ToBytesMap; + * + * // Declare a set state variable + * EnumerableMapBytes32.Bytes32ToBytesMap private myMap; + * } + * ``` + * + * The following map types are supported: + * + * - `bytes32 -> bytes` (`Bytes32ToBytes`) + * + * [WARNING] + * ==== + * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure + * unusable. + * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. + * + * In order to clean up an EnumerableMapBytes32, you should remove all elements one by one. + * ==== + */ +library EnumerableMapBytes32 { + using EnumerableSet for EnumerableSet.Bytes32Set; + + error NonexistentKeyError(); + + struct Bytes32ToBytesMap { + EnumerableSet.Bytes32Set _keys; + mapping(bytes32 => bytes) _values; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function set(Bytes32ToBytesMap storage map, bytes32 key, bytes memory value) internal returns (bool) { + map._values[key] = value; + return map._keys.add(key); + } + + /** + * @dev Removes a key-value pair from a map. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function remove(Bytes32ToBytesMap storage map, bytes32 key) internal returns (bool) { + delete map._values[key]; + return map._keys.remove(key); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function contains(Bytes32ToBytesMap storage map, bytes32 key) internal view returns (bool) { + return map._keys.contains(key); + } + + /** + * @dev Returns the number of key-value pairs in the map. O(1). + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function length(Bytes32ToBytesMap storage map) internal view returns (uint256) { + return map._keys.length(); + } + + /** + * @dev Returns the key-value pair stored at position `index` in the map. O(1). + * + * Note that there are no guarantees on the ordering of entries inside the + * array, and it may change when more entries are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function at(Bytes32ToBytesMap storage map, uint256 index) internal view returns (bytes32, bytes memory) { + bytes32 key = map._keys.at(index); + return (key, map._values[key]); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function tryGet(Bytes32ToBytesMap storage map, bytes32 key) internal view returns (bool, bytes memory) { + bytes memory value = map._values[key]; + if (value.length == 0) { + return (contains(map, key), bytes("")); + } else { + return (true, value); + } + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore + function get(Bytes32ToBytesMap storage map, bytes32 key) internal view returns (bytes memory) { + bytes memory value = map._values[key]; + if (value.length == 0 && !contains(map, key)) { + revert NonexistentKeyError(); + } + return value; + } +} diff --git a/contracts/src/v0.8/shared/test/enumerable/EnumerableMapAddresses.t.sol b/contracts/src/v0.8/shared/test/enumerable/EnumerableMapAddresses.t.sol index 900c546f66..097e79e372 100644 --- a/contracts/src/v0.8/shared/test/enumerable/EnumerableMapAddresses.t.sol +++ b/contracts/src/v0.8/shared/test/enumerable/EnumerableMapAddresses.t.sol @@ -7,11 +7,14 @@ import {EnumerableMapAddresses} from "../../enumerable/EnumerableMapAddresses.so contract EnumerableMapAddressesTest is BaseTest { using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytesMap; EnumerableMapAddresses.AddressToAddressMap internal s_addressToAddressMap; EnumerableMapAddresses.AddressToBytes32Map internal s_addressToBytes32Map; + EnumerableMapAddresses.AddressToBytesMap internal s_addressToBytesMap; bytes32 internal constant MOCK_BYTES32_VALUE = bytes32(uint256(42)); + bytes internal constant MOCK_BYTES_VALUE = "0x123456789abcdef"; function setUp() public virtual override { BaseTest.setUp(); @@ -21,6 +24,7 @@ contract EnumerableMapAddressesTest is BaseTest { contract EnumerableMapAddresses_set is EnumerableMapAddressesTest { using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytesMap; function testSetSuccess() public { assertTrue(!s_addressToAddressMap.contains(address(this))); @@ -35,11 +39,19 @@ contract EnumerableMapAddresses_set is EnumerableMapAddressesTest { assertTrue(s_addressToBytes32Map.contains(address(this))); assertTrue(!s_addressToBytes32Map.set(address(this), MOCK_BYTES32_VALUE)); } + + function testBytesSetSuccess() public { + assertTrue(!s_addressToBytesMap.contains(address(this))); + assertTrue(s_addressToBytesMap.set(address(this), MOCK_BYTES_VALUE)); + assertTrue(s_addressToBytesMap.contains(address(this))); + assertTrue(!s_addressToBytesMap.set(address(this), MOCK_BYTES_VALUE)); + } } contract EnumerableMapAddresses_remove is EnumerableMapAddressesTest { using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytesMap; function testRemoveSuccess() public { assertTrue(!s_addressToAddressMap.contains(address(this))); @@ -58,11 +70,21 @@ contract EnumerableMapAddresses_remove is EnumerableMapAddressesTest { assertTrue(!s_addressToBytes32Map.contains(address(this))); assertTrue(!s_addressToBytes32Map.remove(address(this))); } + + function testBytesRemoveSuccess() public { + assertTrue(!s_addressToBytesMap.contains(address(this))); + assertTrue(s_addressToBytesMap.set(address(this), MOCK_BYTES_VALUE)); + assertTrue(s_addressToBytesMap.contains(address(this))); + assertTrue(s_addressToBytesMap.remove(address(this))); + assertTrue(!s_addressToBytesMap.contains(address(this))); + assertTrue(!s_addressToBytesMap.remove(address(this))); + } } contract EnumerableMapAddresses_contains is EnumerableMapAddressesTest { using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytesMap; function testContainsSuccess() public { assertTrue(!s_addressToAddressMap.contains(address(this))); @@ -75,55 +97,81 @@ contract EnumerableMapAddresses_contains is EnumerableMapAddressesTest { assertTrue(s_addressToBytes32Map.set(address(this), MOCK_BYTES32_VALUE)); assertTrue(s_addressToBytes32Map.contains(address(this))); } + + function testBytesContainsSuccess() public { + assertTrue(!s_addressToBytesMap.contains(address(this))); + assertTrue(s_addressToBytesMap.set(address(this), MOCK_BYTES_VALUE)); + assertTrue(s_addressToBytesMap.contains(address(this))); + } } contract EnumerableMapAddresses_length is EnumerableMapAddressesTest { using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytesMap; function testLengthSuccess() public { - assertTrue(s_addressToAddressMap.length() == 0); + assertEq(s_addressToAddressMap.length(), 0); assertTrue(s_addressToAddressMap.set(address(this), address(this))); - assertTrue(s_addressToAddressMap.length() == 1); + assertEq(s_addressToAddressMap.length(), 1); assertTrue(s_addressToAddressMap.remove(address(this))); - assertTrue(s_addressToAddressMap.length() == 0); + assertEq(s_addressToAddressMap.length(), 0); } function testBytes32LengthSuccess() public { - assertTrue(s_addressToBytes32Map.length() == 0); + assertEq(s_addressToBytes32Map.length(), 0); assertTrue(s_addressToBytes32Map.set(address(this), MOCK_BYTES32_VALUE)); - assertTrue(s_addressToBytes32Map.length() == 1); + assertEq(s_addressToBytes32Map.length(), 1); assertTrue(s_addressToBytes32Map.remove(address(this))); - assertTrue(s_addressToBytes32Map.length() == 0); + assertEq(s_addressToBytes32Map.length(), 0); + } + + function testBytesLengthSuccess() public { + assertEq(s_addressToBytesMap.length(), 0); + assertTrue(s_addressToBytesMap.set(address(this), MOCK_BYTES_VALUE)); + assertEq(s_addressToBytesMap.length(), 1); + assertTrue(s_addressToBytesMap.remove(address(this))); + assertEq(s_addressToBytesMap.length(), 0); } } contract EnumerableMapAddresses_at is EnumerableMapAddressesTest { using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytesMap; function testAtSuccess() public { - assertTrue(s_addressToAddressMap.length() == 0); + assertEq(s_addressToAddressMap.length(), 0); assertTrue(s_addressToAddressMap.set(address(this), address(this))); - assertTrue(s_addressToAddressMap.length() == 1); + assertEq(s_addressToAddressMap.length(), 1); (address key, address value) = s_addressToAddressMap.at(0); - assertTrue(key == address(this)); - assertTrue(value == address(this)); + assertEq(key, address(this)); + assertEq(value, address(this)); } function testBytes32AtSuccess() public { - assertTrue(s_addressToBytes32Map.length() == 0); + assertEq(s_addressToBytes32Map.length(), 0); assertTrue(s_addressToBytes32Map.set(address(this), MOCK_BYTES32_VALUE)); - assertTrue(s_addressToBytes32Map.length() == 1); + assertEq(s_addressToBytes32Map.length(), 1); (address key, bytes32 value) = s_addressToBytes32Map.at(0); - assertTrue(key == address(this)); - assertTrue(value == MOCK_BYTES32_VALUE); + assertEq(key, address(this)); + assertEq(value, MOCK_BYTES32_VALUE); + } + + function testBytesAtSuccess() public { + assertEq(s_addressToBytesMap.length(), 0); + assertTrue(s_addressToBytesMap.set(address(this), MOCK_BYTES_VALUE)); + assertEq(s_addressToBytesMap.length(), 1); + (address key, bytes memory value) = s_addressToBytesMap.at(0); + assertEq(key, address(this)); + assertEq(value, MOCK_BYTES_VALUE); } } contract EnumerableMapAddresses_tryGet is EnumerableMapAddressesTest { using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytesMap; function testTryGetSuccess() public { assertTrue(!s_addressToAddressMap.contains(address(this))); @@ -131,7 +179,7 @@ contract EnumerableMapAddresses_tryGet is EnumerableMapAddressesTest { assertTrue(s_addressToAddressMap.contains(address(this))); (bool success, address value) = s_addressToAddressMap.tryGet(address(this)); assertTrue(success); - assertTrue(value == address(this)); + assertEq(value, address(this)); } function testBytes32TryGetSuccess() public { @@ -140,37 +188,62 @@ contract EnumerableMapAddresses_tryGet is EnumerableMapAddressesTest { assertTrue(s_addressToBytes32Map.contains(address(this))); (bool success, bytes32 value) = s_addressToBytes32Map.tryGet(address(this)); assertTrue(success); - assertTrue(value == MOCK_BYTES32_VALUE); + assertEq(value, MOCK_BYTES32_VALUE); + } + + function testBytesTryGetSuccess() public { + assertTrue(!s_addressToBytesMap.contains(address(this))); + assertTrue(s_addressToBytesMap.set(address(this), MOCK_BYTES_VALUE)); + assertTrue(s_addressToBytesMap.contains(address(this))); + (bool success, bytes memory value) = s_addressToBytesMap.tryGet(address(this)); + assertTrue(success); + assertEq(value, MOCK_BYTES_VALUE); } } contract EnumerableMapAddresses_get is EnumerableMapAddressesTest { using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytesMap; function testGetSuccess() public { assertTrue(!s_addressToAddressMap.contains(address(this))); assertTrue(s_addressToAddressMap.set(address(this), address(this))); assertTrue(s_addressToAddressMap.contains(address(this))); - assertTrue(s_addressToAddressMap.get(address(this)) == address(this)); + assertEq(s_addressToAddressMap.get(address(this)), address(this)); } function testBytes32GetSuccess() public { assertTrue(!s_addressToBytes32Map.contains(address(this))); assertTrue(s_addressToBytes32Map.set(address(this), MOCK_BYTES32_VALUE)); assertTrue(s_addressToBytes32Map.contains(address(this))); - assertTrue(s_addressToBytes32Map.get(address(this)) == MOCK_BYTES32_VALUE); + assertEq(s_addressToBytes32Map.get(address(this)), MOCK_BYTES32_VALUE); + } + + function testBytesGetSuccess() public { + assertTrue(!s_addressToBytesMap.contains(address(this))); + assertTrue(s_addressToBytesMap.set(address(this), MOCK_BYTES_VALUE)); + assertTrue(s_addressToBytesMap.contains(address(this))); + assertEq(s_addressToBytesMap.get(address(this)), MOCK_BYTES_VALUE); } } contract EnumerableMapAddresses_get_errorMessage is EnumerableMapAddressesTest { using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytesMap; function testGetErrorMessageSuccess() public { assertTrue(!s_addressToAddressMap.contains(address(this))); assertTrue(s_addressToAddressMap.set(address(this), address(this))); assertTrue(s_addressToAddressMap.contains(address(this))); - assertTrue(s_addressToAddressMap.get(address(this), "EnumerableMapAddresses: nonexistent key") == address(this)); + assertEq(s_addressToAddressMap.get(address(this), "EnumerableMapAddresses: nonexistent key"), address(this)); + } + + function testBytesGetErrorMessageSuccess() public { + assertTrue(!s_addressToBytesMap.contains(address(this))); + assertTrue(s_addressToBytesMap.set(address(this), MOCK_BYTES_VALUE)); + assertTrue(s_addressToBytesMap.contains(address(this))); + assertEq(s_addressToBytesMap.get(address(this)), MOCK_BYTES_VALUE); } } From 2b86088670596de517b35d652c85a031f0fb6faf Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Mon, 12 Aug 2024 17:54:53 +0400 Subject: [PATCH 080/432] refactor + support v2.3 benchmark test (#14052) * update feeds used in automation tests * comment unused vars * support v2.3 in benchmark test --- .../actions/automation_ocr_helpers.go | 2 +- .../actions/automationv2/actions.go | 67 +++++++++---- integration-tests/actions/keeper_helpers.go | 6 +- integration-tests/benchmark/keeper_test.go | 95 +++++++------------ .../contracts/contract_models.go | 2 +- .../contracts/ethereum_contracts.go | 20 ++-- .../contracts/ethereum_keeper_contracts.go | 1 + .../testconfig/keeper/keeper.toml | 67 ++++++++++++- .../testsetups/keeper_benchmark.go | 28 +++--- 9 files changed, 178 insertions(+), 110 deletions(-) diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index 05c4501fbe..3e552371f9 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -438,7 +438,7 @@ func deployRegistry( wethToken contracts.WETHToken, ethUSDFeed contracts.MockETHUSDFeed, ) contracts.KeeperRegistry { - ef, err := contracts.DeployMockETHLINKFeed(client, big.NewInt(2e18)) + ef, err := contracts.DeployMockLINKETHFeed(client, big.NewInt(2e18)) require.NoError(t, err, "Deploying mock ETH-Link feed shouldn't fail") gf, err := contracts.DeployMockGASFeed(client, big.NewInt(2e11)) require.NoError(t, err, "Deploying mock gas feed shouldn't fail") diff --git a/integration-tests/actions/automationv2/actions.go b/integration-tests/actions/automationv2/actions.go index 40caf15917..9075b863b6 100644 --- a/integration-tests/actions/automationv2/actions.go +++ b/integration-tests/actions/automationv2/actions.go @@ -62,8 +62,9 @@ type AutomationTest struct { LinkToken contracts.LinkToken Transcoder contracts.UpkeepTranscoder - EthLinkFeed contracts.MockETHLINKFeed - EthUSDFeed contracts.MockETHUSDFeed + LINKETHFeed contracts.MockLINKETHFeed + ETHUSDFeed contracts.MockETHUSDFeed + LINKUSDFeed contracts.MockETHUSDFeed WETHToken contracts.WETHToken GasFeed contracts.MockGasFeed Registry contracts.KeeperRegistry @@ -192,31 +193,30 @@ func (a *AutomationTest) LoadTranscoder(address string) error { return nil } -func (a *AutomationTest) DeployEthLinkFeed() error { - ethLinkFeed, err := contracts.DeployMockETHLINKFeed(a.ChainClient, a.RegistrySettings.FallbackLinkPrice) +func (a *AutomationTest) DeployLinkEthFeed() error { + ethLinkFeed, err := contracts.DeployMockLINKETHFeed(a.ChainClient, a.RegistrySettings.FallbackLinkPrice) if err != nil { return err } - a.EthLinkFeed = ethLinkFeed + a.LINKETHFeed = ethLinkFeed return nil } -func (a *AutomationTest) LoadEthLinkFeed(address string) error { - ethLinkFeed, err := contracts.LoadMockETHLINKFeed(a.ChainClient, common.HexToAddress(address)) +func (a *AutomationTest) LoadLinkEthFeed(address string) error { + ethLinkFeed, err := contracts.LoadMockLINKETHFeed(a.ChainClient, common.HexToAddress(address)) if err != nil { return err } - a.EthLinkFeed = ethLinkFeed + a.LINKETHFeed = ethLinkFeed return nil } func (a *AutomationTest) DeployEthUSDFeed() error { - // FallbackLinkPrice and FallbackETHPrice are the same ethUSDFeed, err := contracts.DeployMockETHUSDFeed(a.ChainClient, a.RegistrySettings.FallbackLinkPrice) if err != nil { return err } - a.EthUSDFeed = ethUSDFeed + a.ETHUSDFeed = ethUSDFeed return nil } @@ -225,7 +225,25 @@ func (a *AutomationTest) LoadEthUSDFeed(address string) error { if err != nil { return err } - a.EthUSDFeed = ethUSDFeed + a.ETHUSDFeed = ethUSDFeed + return nil +} + +func (a *AutomationTest) DeployLinkUSDFeed() error { + linkUSDFeed, err := contracts.DeployMockETHUSDFeed(a.ChainClient, a.RegistrySettings.FallbackLinkPrice) + if err != nil { + return err + } + a.LINKUSDFeed = linkUSDFeed + return nil +} + +func (a *AutomationTest) LoadLinkUSDFeed(address string) error { + linkUSDFeed, err := contracts.LoadMockETHUSDFeed(a.ChainClient, common.HexToAddress(address)) + if err != nil { + return err + } + a.LINKUSDFeed = linkUSDFeed return nil } @@ -269,13 +287,13 @@ func (a *AutomationTest) DeployRegistry() error { registryOpts := &contracts.KeeperRegistryOpts{ RegistryVersion: a.RegistrySettings.RegistryVersion, LinkAddr: a.LinkToken.Address(), - ETHFeedAddr: a.EthLinkFeed.Address(), + ETHFeedAddr: a.LINKETHFeed.Address(), GasFeedAddr: a.GasFeed.Address(), TranscoderAddr: a.Transcoder.Address(), RegistrarAddr: utils.ZeroAddress.Hex(), Settings: a.RegistrySettings, - LinkUSDFeedAddr: a.EthUSDFeed.Address(), - NativeUSDFeedAddr: a.EthUSDFeed.Address(), + LinkUSDFeedAddr: a.ETHUSDFeed.Address(), + NativeUSDFeedAddr: a.LINKUSDFeed.Address(), WrappedNativeAddr: a.WETHToken.Address(), } registry, err := contracts.DeployKeeperRegistry(a.ChainClient, registryOpts) @@ -563,7 +581,7 @@ func (a *AutomationTest) SetConfigOnRegistry() error { { GasFeePPB: 100, FlatFeeMilliCents: big.NewInt(500), - PriceFeed: common.HexToAddress(a.EthUSDFeed.Address()), // ETH/USD feed and LINK/USD feed are the same + PriceFeed: common.HexToAddress(a.ETHUSDFeed.Address()), Decimals: 18, FallbackPrice: big.NewInt(1000), MinSpend: big.NewInt(200), @@ -571,7 +589,7 @@ func (a *AutomationTest) SetConfigOnRegistry() error { { GasFeePPB: 100, FlatFeeMilliCents: big.NewInt(500), - PriceFeed: common.HexToAddress(a.EthUSDFeed.Address()), // ETH/USD feed and LINK/USD feed are the same + PriceFeed: common.HexToAddress(a.LINKUSDFeed.Address()), Decimals: 18, FallbackPrice: big.NewInt(1000), MinSpend: big.NewInt(200), @@ -853,14 +871,17 @@ func (a *AutomationTest) SetupAutomationDeployment(t *testing.T) { err = a.DeployWETH() require.NoError(t, err, "Error deploying weth token contract") - err = a.DeployEthLinkFeed() - require.NoError(t, err, "Error deploying eth link feed contract") + err = a.DeployLinkEthFeed() + require.NoError(t, err, "Error deploying link eth feed contract") err = a.DeployGasFeed() require.NoError(t, err, "Error deploying gas feed contract") err = a.DeployEthUSDFeed() require.NoError(t, err, "Error deploying eth usd feed contract") + err = a.DeployLinkUSDFeed() + require.NoError(t, err, "Error deploying link usd feed contract") + err = a.DeployTranscoder() require.NoError(t, err, "Error deploying transcoder contract") @@ -873,7 +894,7 @@ func (a *AutomationTest) SetupAutomationDeployment(t *testing.T) { } func (a *AutomationTest) LoadAutomationDeployment(t *testing.T, linkTokenAddress, - ethLinkFeedAddress, gasFeedAddress, transcoderAddress, registryAddress, registrarAddress string) { + linkEthFeedAddress, linkUsdFeedAddress, EthUsdFeedAddress, gasFeedAddress, transcoderAddress, registryAddress, registrarAddress string) { l := logging.GetTestLogger(t) err := a.CollectNodeDetails() require.NoError(t, err, "Error collecting node details") @@ -883,10 +904,14 @@ func (a *AutomationTest) LoadAutomationDeployment(t *testing.T, linkTokenAddress err = a.LoadLINK(linkTokenAddress) require.NoError(t, err, "Error loading link token contract") - err = a.LoadEthLinkFeed(ethLinkFeedAddress) - require.NoError(t, err, "Error loading eth link feed contract") + err = a.LoadLinkEthFeed(linkEthFeedAddress) + require.NoError(t, err, "Error loading link eth feed contract") err = a.LoadEthGasFeed(gasFeedAddress) require.NoError(t, err, "Error loading gas feed contract") + err = a.LoadEthUSDFeed(EthUsdFeedAddress) + require.NoError(t, err, "Error loading eth usd feed contract") + err = a.LoadLinkUSDFeed(linkUsdFeedAddress) + require.NoError(t, err, "Error loading link usd feed contract") err = a.LoadTranscoder(transcoderAddress) require.NoError(t, err, "Error loading transcoder contract") err = a.LoadRegistry(registryAddress) diff --git a/integration-tests/actions/keeper_helpers.go b/integration-tests/actions/keeper_helpers.go index ee1662cc18..618ca96933 100644 --- a/integration-tests/actions/keeper_helpers.go +++ b/integration-tests/actions/keeper_helpers.go @@ -81,7 +81,7 @@ func DeployKeeperContracts( client *seth.Client, linkFundsForEachUpkeep *big.Int, ) (contracts.KeeperRegistry, contracts.KeeperRegistrar, []contracts.KeeperConsumer, []*big.Int) { - ef, err := contracts.DeployMockETHLINKFeed(client, big.NewInt(2e18)) + ef, err := contracts.DeployMockLINKETHFeed(client, big.NewInt(2e18)) require.NoError(t, err, "Deploying mock ETH-Link feed shouldn't fail") gf, err := contracts.DeployMockGASFeed(client, big.NewInt(2e11)) require.NoError(t, err, "Deploying mock gas feed shouldn't fail") @@ -136,7 +136,7 @@ func DeployPerformanceKeeperContracts( checkGasToBurn, // How much gas should be burned on checkUpkeep() calls performGasToBurn int64, // How much gas should be burned on performUpkeep() calls ) (contracts.KeeperRegistry, contracts.KeeperRegistrar, []contracts.KeeperConsumerPerformance, []*big.Int) { - ef, err := contracts.DeployMockETHLINKFeed(chainClient, big.NewInt(2e18)) + ef, err := contracts.DeployMockLINKETHFeed(chainClient, big.NewInt(2e18)) require.NoError(t, err, "Deploying mock ETH-Link feed shouldn't fail") gf, err := contracts.DeployMockGASFeed(chainClient, big.NewInt(2e11)) require.NoError(t, err, "Deploying mock gas feed shouldn't fail") @@ -196,7 +196,7 @@ func DeployPerformDataCheckerContracts( linkFundsForEachUpkeep *big.Int, expectedData []byte, ) (contracts.KeeperRegistry, contracts.KeeperRegistrar, []contracts.KeeperPerformDataChecker, []*big.Int) { - ef, err := contracts.DeployMockETHLINKFeed(chainClient, big.NewInt(2e18)) + ef, err := contracts.DeployMockLINKETHFeed(chainClient, big.NewInt(2e18)) require.NoError(t, err, "Deploying mock ETH-Link feed shouldn't fail") gf, err := contracts.DeployMockGASFeed(chainClient, big.NewInt(2e11)) require.NoError(t, err, "Deploying mock gas feed shouldn't fail") diff --git a/integration-tests/benchmark/keeper_test.go b/integration-tests/benchmark/keeper_test.go index 177b352101..fde550bbdf 100644 --- a/integration-tests/benchmark/keeper_test.go +++ b/integration-tests/benchmark/keeper_test.go @@ -10,26 +10,26 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - env_client "github.com/smartcontractkit/chainlink-testing-framework/k8s/client" + ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/config" + envclient "github.com/smartcontractkit/chainlink-testing-framework/k8s/client" "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/chainlink" "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/ethereum" "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/reorg" "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/networks" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + sethutils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" - eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + ethcontracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" "github.com/smartcontractkit/chainlink/integration-tests/types" ) var ( - performanceChainlinkResources = map[string]interface{}{ + chainlinkResources = map[string]interface{}{ "resources": map[string]interface{}{ "requests": map[string]interface{}{ "cpu": "1000m", @@ -41,7 +41,7 @@ var ( }, }, } - performanceDbResources = map[string]interface{}{ + dbResources = map[string]interface{}{ "resources": map[string]interface{}{ "requests": map[string]interface{}{ "cpu": "1000m", @@ -55,33 +55,6 @@ var ( "stateful": true, "capacity": "10Gi", } - - soakChainlinkResources = map[string]interface{}{ - "resources": map[string]interface{}{ - "requests": map[string]interface{}{ - "cpu": "350m", - "memory": "1Gi", - }, - "limits": map[string]interface{}{ - "cpu": "350m", - "memory": "1Gi", - }, - }, - } - soakDbResources = map[string]interface{}{ - "resources": map[string]interface{}{ - "requests": map[string]interface{}{ - "cpu": "250m", - "memory": "256Mi", - }, - "limits": map[string]interface{}{ - "cpu": "250m", - "memory": "256Mi", - }, - }, - "stateful": true, - "capacity": "10Gi", - } ) type NetworkConfig struct { @@ -115,9 +88,9 @@ func TestAutomationBenchmark(t *testing.T) { benchmarkTestNetwork := getNetworkConfig(&config) l.Info().Str("Namespace", testEnvironment.Cfg.Namespace).Msg("Connected to Keepers Benchmark Environment") - testNetwork := seth_utils.MustReplaceSimulatedNetworkUrlWithK8(l, benchmarkNetwork, *testEnvironment) + testNetwork := sethutils.MustReplaceSimulatedNetworkUrlWithK8(l, benchmarkNetwork, *testEnvironment) - chainClient, err := seth_utils.GetChainClientWithConfigFunction(&config, testNetwork, seth_utils.OneEphemeralKeysLiveTestnetAutoFixFn) + chainClient, err := sethutils.GetChainClientWithConfigFunction(&config, testNetwork, sethutils.OneEphemeralKeysLiveTestnetAutoFixFn) require.NoError(t, err, "Error getting Seth client") registryVersions := addRegistry(&config) @@ -173,40 +146,42 @@ func TestAutomationBenchmark(t *testing.T) { keeperBenchmarkTest.Run() } -func addRegistry(config *tc.TestConfig) []eth_contracts.KeeperRegistryVersion { +func addRegistry(config *tc.TestConfig) []ethcontracts.KeeperRegistryVersion { switch *config.Keeper.Common.RegistryToTest { case "1_1": - return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_1_1} + return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_1_1} case "1_2": - return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_1_2} + return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_1_2} case "1_3": - return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_1_3} + return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_1_3} case "2_0": - return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_0} + return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_0} case "2_1": - return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_1} + return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_1} case "2_2": - return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_2} + return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_2} + case "2_3": + return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_3} case "2_0-1_3": - return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_0, eth_contracts.RegistryVersion_1_3} + return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_0, ethcontracts.RegistryVersion_1_3} case "2_1-2_0-1_3": - return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_1, - eth_contracts.RegistryVersion_2_0, eth_contracts.RegistryVersion_1_3} + return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_1, + ethcontracts.RegistryVersion_2_0, ethcontracts.RegistryVersion_1_3} case "2_2-2_1": - return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_2, eth_contracts.RegistryVersion_2_1} + return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_2, ethcontracts.RegistryVersion_2_1} case "2_0-Multiple": - return repeatRegistries(eth_contracts.RegistryVersion_2_0, *config.Keeper.Common.NumberOfRegistries) + return repeatRegistries(ethcontracts.RegistryVersion_2_0, *config.Keeper.Common.NumberOfRegistries) case "2_1-Multiple": - return repeatRegistries(eth_contracts.RegistryVersion_2_1, *config.Keeper.Common.NumberOfRegistries) + return repeatRegistries(ethcontracts.RegistryVersion_2_1, *config.Keeper.Common.NumberOfRegistries) case "2_2-Multiple": - return repeatRegistries(eth_contracts.RegistryVersion_2_2, *config.Keeper.Common.NumberOfRegistries) + return repeatRegistries(ethcontracts.RegistryVersion_2_2, *config.Keeper.Common.NumberOfRegistries) default: - return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_0} + return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_0} } } -func repeatRegistries(registryVersion eth_contracts.KeeperRegistryVersion, numberOfRegistries int) []eth_contracts.KeeperRegistryVersion { - repeatedRegistries := make([]eth_contracts.KeeperRegistryVersion, 0) +func repeatRegistries(registryVersion ethcontracts.KeeperRegistryVersion, numberOfRegistries int) []ethcontracts.KeeperRegistryVersion { + repeatedRegistries := make([]ethcontracts.KeeperRegistryVersion, 0) for i := 0; i < numberOfRegistries; i++ { repeatedRegistries = append(repeatedRegistries, registryVersion) } @@ -316,12 +291,8 @@ func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.KeeperBenc PreventPodEviction: true, }) - dbResources := performanceDbResources - chainlinkResources := performanceChainlinkResources - if strings.Contains(strings.ToLower(strings.Join(keeperTestConfig.GetConfigurationNames(), ",")), "soak") { - chainlinkResources = soakChainlinkResources - dbResources = soakDbResources - } + dbResources := dbResources + chainlinkResources := chainlinkResources // Test can run on simulated, simulated-non-dev, testnets if testNetwork.Name == networks.SimulatedEVMNonDev.Name { @@ -389,10 +360,10 @@ func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.KeeperBenc // for simulated-nod-dev each CL node gets its own RPC node if testNetwork.Name == networks.SimulatedEVMNonDev.Name { podName := fmt.Sprintf("%s-ethereum-geth:%d", testNetwork.Name, i) - txNodeInternalWs, err := testEnvironment.Fwd.FindPort(podName, "geth", "ws-rpc").As(env_client.RemoteConnection, env_client.WS) + txNodeInternalWs, err := testEnvironment.Fwd.FindPort(podName, "geth", "ws-rpc").As(envclient.RemoteConnection, envclient.WS) require.NoError(t, err, "Error finding WS ports") internalWsURLs = append(internalWsURLs, txNodeInternalWs) - txNodeInternalHttp, err := testEnvironment.Fwd.FindPort(podName, "geth", "http-rpc").As(env_client.RemoteConnection, env_client.HTTP) + txNodeInternalHttp, err := testEnvironment.Fwd.FindPort(podName, "geth", "http-rpc").As(envclient.RemoteConnection, envclient.HTTP) require.NoError(t, err, "Error finding HTTP ports") internalHttpURLs = append(internalHttpURLs, txNodeInternalHttp) // for testnets with more than 1 RPC nodes @@ -412,8 +383,8 @@ func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.KeeperBenc testNetwork.URLs = []string{internalWsURLs[i]} var overrideFn = func(_ interface{}, target interface{}) { - ctf_config.MustConfigOverrideChainlinkVersion(keeperTestConfig.GetChainlinkImageConfig(), target) - ctf_config.MightConfigOverridePyroscopeKey(keeperTestConfig.GetPyroscopeConfig(), target) + ctfconfig.MustConfigOverrideChainlinkVersion(keeperTestConfig.GetChainlinkImageConfig(), target) + ctfconfig.MightConfigOverridePyroscopeKey(keeperTestConfig.GetPyroscopeConfig(), target) } tomlConfig, err := actions.BuildTOMLNodeConfigForK8s(keeperTestConfig, testNetwork) diff --git a/integration-tests/contracts/contract_models.go b/integration-tests/contracts/contract_models.go index 5983f95c9f..ea63f1aa4d 100644 --- a/integration-tests/contracts/contract_models.go +++ b/integration-tests/contracts/contract_models.go @@ -224,7 +224,7 @@ type JobByInstance struct { Instance string } -type MockETHLINKFeed interface { +type MockLINKETHFeed interface { Address() string LatestRoundData() (*big.Int, error) LatestRoundDataUpdatedAt() (*big.Int, error) diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index 5b08c9a9fb..0d493dff45 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -1195,19 +1195,19 @@ func (v *EthereumMockETHLINKFeed) LatestRoundDataUpdatedAt() (*big.Int, error) { return data.UpdatedAt, nil } -func DeployMockETHLINKFeed(client *seth.Client, answer *big.Int) (MockETHLINKFeed, error) { +func DeployMockLINKETHFeed(client *seth.Client, answer *big.Int) (MockLINKETHFeed, error) { abi, err := mock_ethlink_aggregator_wrapper.MockETHLINKAggregatorMetaData.GetAbi() if err != nil { - return &EthereumMockETHLINKFeed{}, fmt.Errorf("failed to get MockETHLINKFeed ABI: %w", err) + return &EthereumMockETHLINKFeed{}, fmt.Errorf("failed to get MockLINKETHFeed ABI: %w", err) } - data, err := client.DeployContract(client.NewTXOpts(), "MockETHLINKFeed", *abi, common.FromHex(mock_ethlink_aggregator_wrapper.MockETHLINKAggregatorMetaData.Bin), answer) + data, err := client.DeployContract(client.NewTXOpts(), "MockLINKETHFeed", *abi, common.FromHex(mock_ethlink_aggregator_wrapper.MockETHLINKAggregatorMetaData.Bin), answer) if err != nil { - return &EthereumMockETHLINKFeed{}, fmt.Errorf("MockETHLINKFeed instance deployment have failed: %w", err) + return &EthereumMockETHLINKFeed{}, fmt.Errorf("MockLINKETHFeed instance deployment have failed: %w", err) } instance, err := mock_ethlink_aggregator_wrapper.NewMockETHLINKAggregator(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) if err != nil { - return &EthereumMockETHLINKFeed{}, fmt.Errorf("failed to instantiate MockETHLINKFeed instance: %w", err) + return &EthereumMockETHLINKFeed{}, fmt.Errorf("failed to instantiate MockLINKETHFeed instance: %w", err) } return &EthereumMockETHLINKFeed{ @@ -1217,17 +1217,17 @@ func DeployMockETHLINKFeed(client *seth.Client, answer *big.Int) (MockETHLINKFee }, nil } -func LoadMockETHLINKFeed(client *seth.Client, address common.Address) (MockETHLINKFeed, error) { +func LoadMockLINKETHFeed(client *seth.Client, address common.Address) (MockLINKETHFeed, error) { abi, err := mock_ethlink_aggregator_wrapper.MockETHLINKAggregatorMetaData.GetAbi() if err != nil { - return &EthereumMockETHLINKFeed{}, fmt.Errorf("failed to get MockETHLINKFeed ABI: %w", err) + return &EthereumMockETHLINKFeed{}, fmt.Errorf("failed to get MockLINKETHFeed ABI: %w", err) } - client.ContractStore.AddABI("MockETHLINKFeed", *abi) - client.ContractStore.AddBIN("MockETHLINKFeed", common.FromHex(mock_ethlink_aggregator_wrapper.MockETHLINKAggregatorMetaData.Bin)) + client.ContractStore.AddABI("MockLINKETHFeed", *abi) + client.ContractStore.AddBIN("MockLINKETHFeed", common.FromHex(mock_ethlink_aggregator_wrapper.MockETHLINKAggregatorMetaData.Bin)) instance, err := mock_ethlink_aggregator_wrapper.NewMockETHLINKAggregator(address, wrappers.MustNewWrappedContractBackend(nil, client)) if err != nil { - return &EthereumMockETHLINKFeed{}, fmt.Errorf("failed to instantiate MockETHLINKFeed instance: %w", err) + return &EthereumMockETHLINKFeed{}, fmt.Errorf("failed to instantiate MockLINKETHFeed instance: %w", err) } return &EthereumMockETHLINKFeed{ diff --git a/integration-tests/contracts/ethereum_keeper_contracts.go b/integration-tests/contracts/ethereum_keeper_contracts.go index 28fdd15b13..38aa5c58f0 100644 --- a/integration-tests/contracts/ethereum_keeper_contracts.go +++ b/integration-tests/contracts/ethereum_keeper_contracts.go @@ -150,6 +150,7 @@ type KeeperRegistrySettings struct { MaxPerformGas uint32 // max gas allowed for an upkeep within perform FallbackGasPrice *big.Int // gas price used if the gas price feed is stale FallbackLinkPrice *big.Int // LINK price used if the LINK price feed is stale + FallbackNativePrice *big.Int // Native price used if the Native price feed is stale MaxCheckDataSize uint32 MaxPerformDataSize uint32 MaxRevertDataSize uint32 diff --git a/integration-tests/testconfig/keeper/keeper.toml b/integration-tests/testconfig/keeper/keeper.toml index b4a6a3b2c0..39eae1ea53 100644 --- a/integration-tests/testconfig/keeper/keeper.toml +++ b/integration-tests/testconfig/keeper/keeper.toml @@ -57,7 +57,21 @@ contract_call_interval = "4s" [Seth] # keeper benchmark running on simulated network requires 100k per node -root_key_funds_buffer = 700_000 +root_key_funds_buffer = 1_000_000 + +[Benchmark.Keeper.Common] +registry_to_test = "2_1" +number_of_registries = 1 +number_of_nodes = 6 +number_of_upkeeps = 1000 +upkeep_gas_limit = 1500000 +check_gas_to_burn = 10000 +perform_gas_to_burn = 1000 +max_perform_gas = 5000000 +block_range = 3600 +block_interval = 60 +forces_single_tx_key = false +delete_jobs_on_end = true [Benchmark.NodeConfig] BaseConfigTOML = """ @@ -95,3 +109,54 @@ HistoryDepth = 100 Mode = 'FixedPrice' LimitDefault = 5_000_000 """ + +[Soak.Keeper.Common] +registry_to_test = "2_1" +number_of_registries = 1 +number_of_nodes = 6 +number_of_upkeeps = 50 +upkeep_gas_limit = 1500000 +check_gas_to_burn = 10000 +perform_gas_to_burn = 1000 +max_perform_gas = 5000000 +block_range = 28800 +block_interval = 300 +forces_single_tx_key = false +delete_jobs_on_end = true + +[Soak.NodeConfig] +BaseConfigTOML = """ +[Feature] +LogPoller = true + +[OCR2] +Enabled = true + +[P2P] +[P2P.V2] +Enabled = true +AnnounceAddresses = ["0.0.0.0:6690"] +ListenAddresses = ["0.0.0.0:6690"] +[Keeper] +TurnLookBack = 0 +[WebServer] +HTTPWriteTimeout = '1h' +""" + +CommonChainConfigTOML = """ +""" + +[Soak.NodeConfig.ChainConfigTOMLByChainID] +# applicable for simulated chain +1337 = """ +FinalityDepth = 50 +LogPollInterval = '1s' +MinIncomingConfirmations = 1 + +[HeadTracker] +HistoryDepth = 100 + +[GasEstimator] +Mode = 'FixedPrice' +LimitDefault = 5_000_000 +""" diff --git a/integration-tests/testsetups/keeper_benchmark.go b/integration-tests/testsetups/keeper_benchmark.go index 4803a5249f..a3d6c426e4 100644 --- a/integration-tests/testsetups/keeper_benchmark.go +++ b/integration-tests/testsetups/keeper_benchmark.go @@ -62,9 +62,11 @@ type KeeperBenchmarkTest struct { chainClient *seth.Client testConfig tt.KeeperBenchmarkTestConfig - linkToken contracts.LinkToken - ethFeed contracts.MockETHLINKFeed - gasFeed contracts.MockGasFeed + linkToken contracts.LinkToken + linkethFeed contracts.MockLINKETHFeed + gasFeed contracts.MockGasFeed + ethusdFeed contracts.MockETHUSDFeed + wrappedNative contracts.WETHToken } // UpkeepConfig dictates details of how the test's upkeep contracts should be called and configured @@ -163,10 +165,10 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Keep } if common.IsHexAddress(c.EthFeedAddress) { - _, err = contracts.LoadMockETHLINKFeed(k.chainClient, common.HexToAddress(c.EthFeedAddress)) + _, err = contracts.LoadMockLINKETHFeed(k.chainClient, common.HexToAddress(c.EthFeedAddress)) require.NoError(k.t, err, "Loading ETH-Link feed Contract shouldn't fail") } else { - k.ethFeed, err = contracts.DeployMockETHLINKFeed(k.chainClient, big.NewInt(2e18)) + k.linkethFeed, err = contracts.DeployMockLINKETHFeed(k.chainClient, big.NewInt(2e18)) require.NoError(k.t, err, "Deploying mock ETH-Link feed shouldn't fail") } @@ -178,6 +180,11 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Keep require.NoError(k.t, err, "Deploying mock gas feed shouldn't fail") } + k.ethusdFeed, err = contracts.DeployMockETHUSDFeed(k.chainClient, big.NewInt(200000000000)) + require.NoError(k.t, err, "Deploying mock ETH-USD feed shouldn't fail") + k.wrappedNative, err = contracts.DeployWETHTokenContract(k.log, k.chainClient) + require.NoError(k.t, err, "Deploying WETH Token Contract shouldn't fail") + for index := range inputs.RegistryVersions { k.log.Info().Int("Index", index).Msg("Starting Test Setup") k.DeployBenchmarkKeeperContracts(index) @@ -240,15 +247,14 @@ func (k *KeeperBenchmarkTest) Run() { txKeyId = 0 } kr := k.keeperRegistries[rIndex] - // TODO: need to add the LINK, WETH and WETH/USD feed to support v23 ocrConfig, err := actions.BuildAutoOCR2ConfigVarsWithKeyIndex( - k.t, nodesWithoutBootstrap, *inputs.KeeperRegistrySettings, kr.Address(), k.Inputs.DeltaStage, txKeyId, common.Address{}, kr.ChainModuleAddress(), kr.ReorgProtectionEnabled(), nil, nil, nil, + k.t, nodesWithoutBootstrap, *inputs.KeeperRegistrySettings, kr.Address(), k.Inputs.DeltaStage, txKeyId, common.Address{}, kr.ChainModuleAddress(), kr.ReorgProtectionEnabled(), k.linkToken, k.wrappedNative, k.ethusdFeed, ) require.NoError(k.t, err, "Building OCR config shouldn't fail") rv := inputs.RegistryVersions[rIndex] // Send keeper jobs to registry and chainlink nodes - if rv == ethereum.RegistryVersion_2_0 || rv == ethereum.RegistryVersion_2_1 || rv == ethereum.RegistryVersion_2_2 { + if rv >= ethereum.RegistryVersion_2_0 { actions.CreateOCRKeeperJobs(k.t, k.chainlinkNodes, kr.Address(), k.chainClient.ChainID, txKeyId, rv) if rv == ethereum.RegistryVersion_2_0 { err = kr.SetConfig(*inputs.KeeperRegistrySettings, ocrConfig) @@ -708,7 +714,7 @@ func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int) { registry, err = contracts.DeployKeeperRegistry(k.chainClient, &contracts.KeeperRegistryOpts{ RegistryVersion: registryVersion, LinkAddr: k.linkToken.Address(), - ETHFeedAddr: k.ethFeed.Address(), + ETHFeedAddr: k.linkethFeed.Address(), GasFeedAddr: k.gasFeed.Address(), TranscoderAddr: actions.ZeroAddress.Hex(), RegistrarAddr: actions.ZeroAddress.Hex(), @@ -731,13 +737,13 @@ func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int) { require.NoError(k.t, err, "Funding keeper registrar contract shouldn't fail") } else { // OCR automation - v2.X registry, registrar = actions.DeployAutoOCRRegistryAndRegistrar( - k.t, k.chainClient, registryVersion, *k.Inputs.KeeperRegistrySettings, k.linkToken, nil, nil, + k.t, k.chainClient, registryVersion, *k.Inputs.KeeperRegistrySettings, k.linkToken, k.wrappedNative, k.ethusdFeed, ) // Fund the registry with LINK err := k.linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(k.Inputs.Upkeeps.NumberOfUpkeeps)))) require.NoError(k.t, err, "Funding keeper registry contract shouldn't fail") - ocrConfig, err := actions.BuildAutoOCR2ConfigVars(k.t, k.chainlinkNodes[1:], *k.Inputs.KeeperRegistrySettings, registrar.Address(), k.Inputs.DeltaStage, registry.ChainModuleAddress(), registry.ReorgProtectionEnabled(), nil, nil, nil) + ocrConfig, err := actions.BuildAutoOCR2ConfigVars(k.t, k.chainlinkNodes[1:], *k.Inputs.KeeperRegistrySettings, registrar.Address(), k.Inputs.DeltaStage, registry.ChainModuleAddress(), registry.ReorgProtectionEnabled(), k.linkToken, k.wrappedNative, k.ethusdFeed) require.NoError(k.t, err, "Building OCR config shouldn't fail") k.log.Debug().Interface("KeeperRegistrySettings", *k.Inputs.KeeperRegistrySettings).Interface("OCRConfig", ocrConfig).Msg("Config") require.NoError(k.t, err, "Error building OCR config vars") From 5d4d996ed275b78eda8d189ad9fac3ddc3055fe2 Mon Sep 17 00:00:00 2001 From: Cedric Date: Mon, 12 Aug 2024 21:10:52 +0100 Subject: [PATCH 081/432] [fix] Don't initialize the remote dispatcher (#14097) --- core/services/chainlink/application.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 6a381b1ffa..17c217b1c9 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -214,8 +214,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) { signer := externalPeer externalPeerWrapper = externalPeer remoteDispatcher := remote.NewDispatcher(externalPeerWrapper, signer, opts.CapabilitiesRegistry, globalLogger) - srvcs = append(srvcs, remoteDispatcher) - dispatcher = remoteDispatcher } else { dispatcher = opts.CapabilitiesDispatcher From 220ca2a88aa8c3666da6d45dbf5d5a30e9f584ce Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Tue, 13 Aug 2024 10:49:15 +0200 Subject: [PATCH 082/432] Turn CRIB persistence test by default (#14101) * try run chaos test for CRIB * less logs * finalize --- .github/workflows/crib-integration-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/crib-integration-test.yml b/.github/workflows/crib-integration-test.yml index 248004636b..a67ac641bf 100644 --- a/.github/workflows/crib-integration-test.yml +++ b/.github/workflows/crib-integration-test.yml @@ -98,9 +98,9 @@ jobs: CRIB_NETWORK: geth CRIB_NODES: 5 GAP_URL: ${{ secrets.GAP_URL }} -# SETH_LOG_LEVEL: debug + SETH_LOG_LEVEL: info # RESTY_DEBUG: true -# TEST_PERSISTENCE: true + TEST_PERSISTENCE: true run: |- go test -v -run TestCRIB - name: Destroy CRIB Environment From eb31cf7970bef1615b10b5a734c16879b448f30a Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Tue, 13 Aug 2024 15:17:00 +0100 Subject: [PATCH 083/432] speedup keystone e2e tests (#14105) --- .changeset/ninety-ways-run.md | 5 +++++ .../integration_tests/keystone_contracts_setup.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/ninety-ways-run.md diff --git a/.changeset/ninety-ways-run.md b/.changeset/ninety-ways-run.md new file mode 100644 index 0000000000..0b4508bdd2 --- /dev/null +++ b/.changeset/ninety-ways-run.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal speed up keystone e2e tests diff --git a/core/capabilities/integration_tests/keystone_contracts_setup.go b/core/capabilities/integration_tests/keystone_contracts_setup.go index 004a4c32a3..38925cb0a3 100644 --- a/core/capabilities/integration_tests/keystone_contracts_setup.go +++ b/core/capabilities/integration_tests/keystone_contracts_setup.go @@ -209,7 +209,7 @@ func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workfl triggerCapabilityConfig := newCapabilityConfig() triggerCapabilityConfig.RemoteConfig = &pb.CapabilityConfig_RemoteTriggerConfig{ RemoteTriggerConfig: &pb.RemoteTriggerConfig{ - RegistrationRefresh: durationpb.New(60000 * time.Millisecond), + RegistrationRefresh: durationpb.New(1000 * time.Millisecond), RegistrationExpiry: durationpb.New(60000 * time.Millisecond), // F + 1 MinResponsesToAggregate: uint32(triggerDon.F) + 1, From 1d1af81c51d78a7e1406d3e182b8740a2ae43c9c Mon Sep 17 00:00:00 2001 From: Joe Huang Date: Tue, 13 Aug 2024 13:06:12 -0500 Subject: [PATCH 084/432] fix unhandled already seen tx error for gnosis chiado (#14099) * add case for gnosis * add changeset * fix typo * typo --------- Co-authored-by: Prashant Yadav <34992934+prashantkumar1982@users.noreply.github.com> --- .changeset/chilly-cars-attend.md | 5 +++++ core/chains/evm/client/errors.go | 6 +++++- core/chains/evm/client/errors_test.go | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .changeset/chilly-cars-attend.md diff --git a/.changeset/chilly-cars-attend.md b/.changeset/chilly-cars-attend.md new file mode 100644 index 0000000000..2cb8323ab3 --- /dev/null +++ b/.changeset/chilly-cars-attend.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +add error handle for gnosis chiado for seen tx #added diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index da12251474..1e4a7caefe 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -259,6 +259,10 @@ var mantle = ClientErrors{ Fatal: regexp.MustCompile(`(: |^)'*invalid sender`), } +var gnosis = ClientErrors{ + TransactionAlreadyInMempool: regexp.MustCompile(`(: |^)(alreadyknown)`), +} + const TerminallyStuckMsg = "transaction terminally stuck" // Tx.Error messages that are set internally so they are not chain or client specific @@ -266,7 +270,7 @@ var internal = ClientErrors{ TerminallyStuck: regexp.MustCompile(TerminallyStuckMsg), } -var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm, mantle, aStar, internal} +var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm, mantle, aStar, gnosis, internal} // ClientErrorRegexes returns a map of compiled regexes for each error type func ClientErrorRegexes(errsRegex config.ClientErrors) *ClientErrors { diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index 72fa1347ec..a75d37f2af 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -136,6 +136,7 @@ func Test_Eth_Errors(t *testing.T) { // This seems to be an erroneous message from the zkSync client, we'll have to match it anyway {"ErrorObject { code: ServerError(3), message: \\\"known transaction. transaction with hash 0xf016…ad63 is already in the system\\\", data: Some(RawValue(\\\"0x\\\")) }", true, "zkSync"}, {"client error transaction already in mempool", true, "tomlConfig"}, + {"alreadyknown", true, "Gnosis"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) From 6a9528db29dadd231ec592f10d655e5367301d8f Mon Sep 17 00:00:00 2001 From: Joe Huang Date: Tue, 13 Aug 2024 14:44:43 -0500 Subject: [PATCH 085/432] classify arbitrum sequencer inaccessible error as retryable (#14100) * add error handling for service unavailable for arbitrum * add changeset * update error message --------- Co-authored-by: Prashant Yadav <34992934+prashantkumar1982@users.noreply.github.com> --- .changeset/calm-badgers-jump.md | 5 +++++ core/chains/evm/client/errors.go | 2 +- core/chains/evm/client/errors_test.go | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 .changeset/calm-badgers-jump.md diff --git a/.changeset/calm-badgers-jump.md b/.changeset/calm-badgers-jump.md new file mode 100644 index 0000000000..76f6e5d312 --- /dev/null +++ b/.changeset/calm-badgers-jump.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +add error handling when arbitrum sequencer is not accessible #added diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index 1e4a7caefe..83c2d9566f 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -158,7 +158,7 @@ var arbitrum = ClientErrors{ Fatal: arbitrumFatal, L2FeeTooLow: regexp.MustCompile(`(: |^)max fee per gas less than block base fee(:|$)`), L2Full: regexp.MustCompile(`(: |^)(queue full|sequencer pending tx pool full, please try again)(:|$)`), - ServiceUnavailable: regexp.MustCompile(`(: |^)502 Bad Gateway: [\s\S]*$`), + ServiceUnavailable: regexp.MustCompile(`(: |^)502 Bad Gateway: [\s\S]*$|network is unreachable|i/o timeout`), } var celo = ClientErrors{ diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index a75d37f2af..00bc1a9a5b 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -230,6 +230,8 @@ func Test_Eth_Errors(t *testing.T) { tests := []errorCase{ {"call failed: 503 Service Unavailable: \r\n503 Service Temporarily Unavailable\r\n\r\n

    503 Service Temporarily Unavailable

    \r\n\r\n\r\n", true, "Nethermind"}, {"call failed: 502 Bad Gateway: \r\n502 Bad Gateway\r\n\r\n

    502 Bad Gateway

    \r\n
    ", true, "Arbitrum"}, + {"i/o timeout", true, "Arbitrum"}, + {"network is unreachable", true, "Arbitrum"}, {"client error service unavailable", true, "tomlConfig"}, } for _, test := range tests { From 3399dd6d7fee12bd8d099b74397edcc4dc56c11d Mon Sep 17 00:00:00 2001 From: Christopher Dimitri Sastropranoto Date: Wed, 14 Aug 2024 08:38:16 +0700 Subject: [PATCH 086/432] prevent editing DON accepts workflows field (#14092) Co-authored-by: Bolek <1416262+bolekk@users.noreply.github.com> --- .changeset/new-eagles-marry.md | 5 +++++ contracts/.changeset/slimy-pens-listen.md | 5 +++++ .../v0.8/keystone/CapabilitiesRegistry.sol | 20 ++++++++++++++----- ...CapabilitiesRegistry_RemoveNodesTest.t.sol | 2 +- .../CapabilitiesRegistry_UpdateDONTest.t.sol | 16 +++++++-------- .../capabilities_registry.go | 18 ++++++++--------- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 7 files changed, 44 insertions(+), 24 deletions(-) create mode 100644 .changeset/new-eagles-marry.md create mode 100644 contracts/.changeset/slimy-pens-listen.md diff --git a/.changeset/new-eagles-marry.md b/.changeset/new-eagles-marry.md new file mode 100644 index 0000000000..9577c2bbe0 --- /dev/null +++ b/.changeset/new-eagles-marry.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal prevent editing whether or not a DON accepts workflows diff --git a/contracts/.changeset/slimy-pens-listen.md b/contracts/.changeset/slimy-pens-listen.md new file mode 100644 index 0000000000..ff81d22237 --- /dev/null +++ b/contracts/.changeset/slimy-pens-listen.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +#internal prevent editing whether or not a DON accepts workflows diff --git a/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol b/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol index ad6f26e8dc..2b8a82a285 100644 --- a/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol +++ b/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol @@ -775,7 +775,9 @@ contract CapabilitiesRegistry is OwnerIsCreator, TypeAndVersionInterface { /// @param nodes The nodes making up the DON /// @param capabilityConfigurations The list of configurations for the /// capabilities supported by the DON - /// @param isPublic True if the DON is public + /// @param isPublic True if the DON is can accept external capability requests + /// @param acceptsWorkflows True if the DON can accept workflows + /// @param f The maximum number of faulty nodes the DON can tolerate function addDON( bytes32[] calldata nodes, CapabilityConfiguration[] calldata capabilityConfigurations, @@ -797,24 +799,32 @@ contract CapabilitiesRegistry is OwnerIsCreator, TypeAndVersionInterface { /// the admin to reconfigure the list of capabilities supported /// by the DON, the list of nodes that make up the DON as well /// as whether or not the DON can accept external workflows + /// @param donId The ID of the DON to update /// @param nodes The nodes making up the DON /// @param capabilityConfigurations The list of configurations for the /// capabilities supported by the DON - /// @param isPublic True if the DON is can accept external workflows + /// @param isPublic True if the DON is can accept external capability requests + /// @param f The maximum number of nodes that can fail function updateDON( uint32 donId, bytes32[] calldata nodes, CapabilityConfiguration[] calldata capabilityConfigurations, bool isPublic, - bool acceptsWorkflows, uint8 f ) external onlyOwner { - uint32 configCount = s_dons[donId].configCount; + DON storage don = s_dons[donId]; + uint32 configCount = don.configCount; if (configCount == 0) revert DONDoesNotExist(donId); _setDONConfig( nodes, capabilityConfigurations, - DONParams({id: donId, configCount: ++configCount, isPublic: isPublic, acceptsWorkflows: acceptsWorkflows, f: f}) + DONParams({ + id: donId, + configCount: ++configCount, + isPublic: isPublic, + acceptsWorkflows: don.acceptsWorkflows, + f: f + }) ); } diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_RemoveNodesTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_RemoveNodesTest.t.sol index 9622c23876..08646600a6 100644 --- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_RemoveNodesTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_RemoveNodesTest.t.sol @@ -158,7 +158,7 @@ contract CapabilitiesRegistry_RemoveNodesTest is BaseTest { bytes32[] memory updatedNodes = new bytes32[](2); updatedNodes[0] = P2P_ID; updatedNodes[1] = P2P_ID_THREE; - s_CapabilitiesRegistry.updateDON(DON_ID, updatedNodes, capabilityConfigs, true, true, F_VALUE); + s_CapabilitiesRegistry.updateDON(DON_ID, updatedNodes, capabilityConfigs, true, F_VALUE); // Remove node s_CapabilitiesRegistry.removeNodes(removedNodes); diff --git a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateDONTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateDONTest.t.sol index 8b21b29506..825524ebe8 100644 --- a/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateDONTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilitiesRegistry_UpdateDONTest.t.sol @@ -71,7 +71,7 @@ contract CapabilitiesRegistry_UpdateDONTest is BaseTest { capabilityId: s_basicHashedCapabilityId, config: BASIC_CAPABILITY_CONFIG }); - s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, true, true, F_VALUE); + s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, true, F_VALUE); } function test_RevertWhen_NodeDoesNotSupportCapability() public { @@ -91,7 +91,7 @@ contract CapabilitiesRegistry_UpdateDONTest is BaseTest { s_capabilityWithConfigurationContractId ) ); - s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, true, true, F_VALUE); + s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, true, F_VALUE); } function test_RevertWhen_DONDoesNotExist() public { @@ -106,7 +106,7 @@ contract CapabilitiesRegistry_UpdateDONTest is BaseTest { config: BASIC_CAPABILITY_CONFIG }); vm.expectRevert(abi.encodeWithSelector(CapabilitiesRegistry.DONDoesNotExist.selector, nonExistentDONId)); - s_CapabilitiesRegistry.updateDON(nonExistentDONId, nodes, capabilityConfigs, true, true, F_VALUE); + s_CapabilitiesRegistry.updateDON(nonExistentDONId, nodes, capabilityConfigs, true, F_VALUE); } function test_RevertWhen_CapabilityDoesNotExist() public { @@ -122,7 +122,7 @@ contract CapabilitiesRegistry_UpdateDONTest is BaseTest { vm.expectRevert( abi.encodeWithSelector(CapabilitiesRegistry.CapabilityDoesNotExist.selector, s_nonExistentHashedCapabilityId) ); - s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, true, true, F_VALUE); + s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, true, F_VALUE); } function test_RevertWhen_DuplicateCapabilityAdded() public { @@ -144,7 +144,7 @@ contract CapabilitiesRegistry_UpdateDONTest is BaseTest { vm.expectRevert( abi.encodeWithSelector(CapabilitiesRegistry.DuplicateDONCapability.selector, 1, s_basicHashedCapabilityId) ); - s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, true, true, F_VALUE); + s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, true, F_VALUE); } function test_RevertWhen_DeprecatedCapabilityAdded() public { @@ -165,7 +165,7 @@ contract CapabilitiesRegistry_UpdateDONTest is BaseTest { }); vm.expectRevert(abi.encodeWithSelector(CapabilitiesRegistry.CapabilityIsDeprecated.selector, capabilityId)); - s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, true, true, F_VALUE); + s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, true, F_VALUE); } function test_RevertWhen_DuplicateNodeAdded() public { @@ -180,7 +180,7 @@ contract CapabilitiesRegistry_UpdateDONTest is BaseTest { config: BASIC_CAPABILITY_CONFIG }); vm.expectRevert(abi.encodeWithSelector(CapabilitiesRegistry.DuplicateDONNode.selector, 1, P2P_ID)); - s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, true, true, F_VALUE); + s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, true, F_VALUE); } function test_UpdatesDON() public { @@ -217,7 +217,7 @@ contract CapabilitiesRegistry_UpdateDONTest is BaseTest { ), 1 ); - s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, expectedDONIsPublic, true, F_VALUE); + s_CapabilitiesRegistry.updateDON(DON_ID, nodes, capabilityConfigs, expectedDONIsPublic, F_VALUE); CapabilitiesRegistry.DONInfo memory donInfo = s_CapabilitiesRegistry.getDON(DON_ID); assertEq(donInfo.id, DON_ID); diff --git a/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go b/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go index 2cfbe12064..9245f2c738 100644 --- a/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go +++ b/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go @@ -86,8 +86,8 @@ type CapabilitiesRegistryNodeParams struct { } var CapabilitiesRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityIsDeprecated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"CapabilityRequiredByDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"DONDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONNode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"nodeCount\",\"type\":\"uint256\"}],\"name\":\"InvalidFaultTolerance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"InvalidNodeCapabilities\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"InvalidNodeP2PId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotSupportCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfCapabilitiesDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfWorkflowDON\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilitiesRegistry.Capability[]\",\"name\":\"capabilities\",\"type\":\"tuple[]\"}],\"name\":\"addCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"addDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"addNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"deprecateCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityConfigs\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"getDON\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"getHashedCapabilityId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"getNode\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo\",\"name\":\"nodeInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodeOperators\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodes\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"isCapabilityDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"donIds\",\"type\":\"uint32[]\"}],\"name\":\"removeDONs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"removedNodeP2PIds\",\"type\":\"bytes32[]\"}],\"name\":\"removeNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"updateDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"updateNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6080604052600e80546001600160401b0319166401000000011790553480156200002857600080fd5b503380600081620000805760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000b357620000b381620000bc565b50505062000167565b336001600160a01b03821603620001165760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000077565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6150f780620001776000396000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80635e65e309116100ee5780638da5cb5b11610097578063d8bc7b6811610071578063d8bc7b68146103f6578063ddbe4f8214610409578063e29581aa1461041e578063f2fde38b1461043357600080fd5b80638da5cb5b1461039b5780639cb7c5f4146103c3578063d59a79f6146103e357600080fd5b806373ac22b4116100c857806373ac22b41461036d57806379ba50971461038057806386fa42461461038857600080fd5b80635e65e3091461033257806366acaa3314610345578063715f52951461035a57600080fd5b8063235374051161015b578063398f377311610135578063398f3773146102cb5780633f2a13c9146102de57806350c946fe146102ff5780635d83d9671461031f57600080fd5b80632353740514610285578063275459f2146102a55780632c01a1e8146102b857600080fd5b80631d05394c1161018c5780631d05394c1461023b578063214502431461025057806322bdbcbc1461026557600080fd5b80630fe5800a146101b357806312570011146101d9578063181f5a77146101fc575b600080fd5b6101c66101c1366004613e8c565b610446565b6040519081526020015b60405180910390f35b6101ec6101e7366004613ef0565b61047a565b60405190151581526020016101d0565b604080518082018252601a81527f4361706162696c6974696573526567697374727920312e302e30000000000000602082015290516101d09190613f77565b61024e610249366004613fcf565b610487565b005b61025861069c565b6040516101d09190614151565b6102786102733660046141ec565b6107f9565b6040516101d09190614244565b6102986102933660046141ec565b6108e6565b6040516101d09190614257565b61024e6102b3366004613fcf565b61092a565b61024e6102c6366004613fcf565b610a01565b61024e6102d9366004613fcf565b610c9d565b6102f16102ec36600461426a565b610e5c565b6040516101d0929190614294565b61031261030d366004613ef0565b611048565b6040516101d09190614359565b61024e61032d366004613fcf565b611122565b61024e610340366004613fcf565b611217565b61034d61193f565b6040516101d0919061436c565b61024e610368366004613fcf565b611b22565b61024e61037b366004613fcf565b611bd4565b61024e6120a2565b61024e6103963660046143e1565b61219f565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d0565b6103d66103d1366004613ef0565b6124df565b6040516101d09190614530565b61024e6103f1366004614562565b61271a565b61024e610404366004614617565b6127e3565b6104116128ad565b6040516101d091906146bc565b6104266129a1565b6040516101d09190614731565b61024e6104413660046147ca565b612aaa565b6000828260405160200161045b929190614294565b6040516020818303038152906040528051906020012090505b92915050565b6000610474600583612abe565b61048f612ad9565b60005b818110156106975760008383838181106104ae576104ae6147e5565b90506020020160208101906104c391906141ec565b63ffffffff8181166000908152600d60209081526040808320805464010000000081049095168085526001820190935290832094955093909290916a010000000000000000000090910460ff16905b61051b83612b5c565b8110156105bb57811561057157600c60006105368584612b66565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556105b3565b6105b18663ffffffff16600c60006105928588612b6690919063ffffffff16565b8152602001908152602001600020600401612b7290919063ffffffff16565b505b600101610512565b508354640100000000900463ffffffff16600003610612576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff861660048201526024015b60405180910390fd5b63ffffffff85166000818152600d6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffff00000000000000000000001690558051938452908301919091527ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c1581703651910160405180910390a15050505050806001019050610492565b505050565b600e54606090640100000000900463ffffffff1660006106bd600183614843565b63ffffffff1667ffffffffffffffff8111156106db576106db613d26565b60405190808252806020026020018201604052801561076257816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816106f95790505b509050600060015b8363ffffffff168163ffffffff1610156107d65763ffffffff8082166000908152600d602052604090205416156107ce576107a481612b7e565b8383815181106107b6576107b66147e5565b6020026020010181905250816107cb90614860565b91505b60010161076a565b506107e2600184614843565b63ffffffff1681146107f2578082525b5092915050565b60408051808201909152600081526060602082015263ffffffff82166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161085d90614898565b80601f016020809104026020016040519081016040528092919081815260200182805461088990614898565b80156108d65780601f106108ab576101008083540402835291602001916108d6565b820191906000526020600020905b8154815290600101906020018083116108b957829003601f168201915b5050505050815250509050919050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c081019190915261047482612b7e565b610932612ad9565b60005b63ffffffff811682111561069757600083838363ffffffff1681811061095d5761095d6147e5565b905060200201602081019061097291906141ec565b63ffffffff81166000908152600b6020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559192506109bd6001830182613cb9565b505060405163ffffffff8216907fa59268ca81d40429e65ccea5385b59cf2d3fc6519371dee92f8eb1dae5107a7a90600090a2506109fa816148eb565b9050610935565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110610a3b57610a3b6147e5565b602090810292909201356000818152600c90935260409092206001810154929350919050610a98576040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260048101839052602401610609565b6000610aa682600401612b5c565b1115610afb57610ab96004820184612b66565b6040517f60a6d89800000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101839052604401610609565b805468010000000000000000900463ffffffff1615610b635780546040517f60b9df730000000000000000000000000000000000000000000000000000000081526801000000000000000090910463ffffffff16600482015260248101839052604401610609565b83158015610b9d5750805463ffffffff166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15610bd6576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6001810154610be790600790612b72565b506002810154610bf990600990612b72565b506000828152600c6020526040812080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815560018101829055600281018290559060048201818181610c4e8282613cf3565b5050505050507f5254e609a97bab37b7cc79fe128f85c097bd6015c6e1624ae0ba392eb975320582604051610c8591815260200190565b60405180910390a15050600101610a1f565b50505050565b610ca5612ad9565b60005b81811015610697576000838383818110610cc457610cc46147e5565b9050602002810190610cd6919061490e565b610cdf9061494c565b805190915073ffffffffffffffffffffffffffffffffffffffff16610d30576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815263ffffffff9095166000818152600b909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251919290916001820190610dbc9082614a06565b5050600e8054909150600090610dd79063ffffffff166148eb565b91906101000a81548163ffffffff021916908363ffffffff160217905550816000015173ffffffffffffffffffffffffffffffffffffffff168163ffffffff167f78e94ca80be2c30abc061b99e7eb8583b1254781734b1e3ce339abb57da2fe8e8460200151604051610e4a9190613f77565b60405180910390a35050600101610ca8565b63ffffffff8083166000908152600d60209081526040808320805464010000000090049094168084526001909401825280832085845260030190915281208054606093849390929091610eae90614898565b80601f0160208091040260200160405190810160405280929190818152602001828054610eda90614898565b8015610f275780601f10610efc57610100808354040283529160200191610f27565b820191906000526020600020905b815481529060010190602001808311610f0a57829003601f168201915b5050506000888152600260208190526040909120015492935060609262010000900473ffffffffffffffffffffffffffffffffffffffff1615915061103a905057600086815260026020819052604091829020015490517f8318ed5d00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526201000090910473ffffffffffffffffffffffffffffffffffffffff1690638318ed5d90602401600060405180830381865afa158015610ff1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110379190810190614b20565b90505b9093509150505b9250929050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c08101919091526040805160e0810182526000848152600c6020908152838220805463ffffffff8082168652640100000000820481168487018190526801000000000000000090920416858701526001820154606086015260028201546080860152835260030190529190912060a08201906110f790612e49565b815260200161111a600c6000868152602001908152602001600020600401612e49565b905292915050565b61112a612ad9565b60005b81811015610697576000838383818110611149576111496147e5565b905060200201359050611166816003612abe90919063ffffffff16565b61119f576040517fe181733f00000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b6111aa600582612e56565b6111e3576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b60405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a25060010161112d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110611251576112516147e5565b90506020028101906112639190614b8e565b61126c90614bc2565b6040808201516000908152600c6020908152828220805463ffffffff168352600b82528383208451808601909552805473ffffffffffffffffffffffffffffffffffffffff16855260018101805496975091959394939092840191906112d190614898565b80601f01602080910402602001604051908101604052809291908181526020018280546112fd90614898565b801561134a5780601f1061131f5761010080835404028352916020019161134a565b820191906000526020600020905b81548152906001019060200180831161132d57829003601f168201915b50505091909252505050600183015490915061139a5782604001516040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b841580156113bf5750805173ffffffffffffffffffffffffffffffffffffffff163314155b156113f8576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6020830151611433576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001820154602084015181146114b457602084015161145490600790612abe565b1561148b576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084015160018401556114a0600782612b72565b5060208401516114b290600790612e56565b505b606084015180516000036114f657806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c95565b8354600090859060049061151790640100000000900463ffffffff166148eb565b91906101000a81548163ffffffff021916908363ffffffff1602179055905060005b82518110156115fc5761156f838281518110611557576115576147e5565b60200260200101516003612abe90919063ffffffff16565b6115a757826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c95565b6115f38382815181106115bc576115bc6147e5565b60200260200101518760030160008563ffffffff1663ffffffff168152602001908152602001600020612e5690919063ffffffff16565b50600101611539565b50845468010000000000000000900463ffffffff16801561175d5763ffffffff8082166000908152600d60209081526040808320805464010000000090049094168352600190930181528282206002018054845181840281018401909552808552929392909183018282801561169157602002820191906000526020600020905b81548152602001906001019080831161167d575b5050505050905060005b815181101561175a576116f08282815181106116b9576116b96147e5565b60200260200101518960030160008763ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b61175257818181518110611706576117066147e5565b6020026020010151836040517f03dcd86200000000000000000000000000000000000000000000000000000000815260040161060992919091825263ffffffff16602082015260400190565b60010161169b565b50505b600061176b87600401612e49565b905060005b81518163ffffffff1610156118b1576000828263ffffffff1681518110611799576117996147e5565b60209081029190910181015163ffffffff8082166000908152600d8452604080822080546401000000009004909316825260019092018452818120600201805483518187028101870190945280845293955090939192909183018282801561182057602002820191906000526020600020905b81548152602001906001019080831161180c575b5050505050905060005b815181101561189d5761187f828281518110611848576118486147e5565b60200260200101518c60030160008a63ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b61189557818181518110611706576117066147e5565b60010161182a565b505050806118aa906148eb565b9050611770565b50875187547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90911690811788556040808a015160028a018190556020808c01518351928352908201527f4b5b465e22eea0c3d40c30e936643245b80d19b2dcf75788c0699fe8d8db645b910160405180910390a25050505050505050806001019050611235565b600e5460609063ffffffff166000611958600183614843565b63ffffffff1667ffffffffffffffff81111561197657611976613d26565b6040519080825280602002602001820160405280156119bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816119945790505b509050600060015b8363ffffffff168163ffffffff161015611b0c5763ffffffff81166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611b045763ffffffff81166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191611a5890614898565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8490614898565b8015611ad15780601f10611aa657610100808354040283529160200191611ad1565b820191906000526020600020905b815481529060010190602001808311611ab457829003601f168201915b505050505081525050838381518110611aec57611aec6147e5565b602002602001018190525081611b0190614860565b91505b6001016119c4565b50600e546107e29060019063ffffffff16614843565b611b2a612ad9565b60005b81811015610697576000838383818110611b4957611b496147e5565b9050602002810190611b5b9190614cd9565b611b6490614d1c565b90506000611b7a82600001518360200151610446565b9050611b87600382612e56565b611bc0576040517febf5255100000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b611bca8183612e62565b5050600101611b2d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610c97576000848483818110611c0e57611c0e6147e5565b9050602002810190611c209190614b8e565b611c2990614bc2565b805163ffffffff166000908152600b602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191611c7f90614898565b80601f0160208091040260200160405190810160405280929190818152602001828054611cab90614898565b8015611cf85780601f10611ccd57610100808354040283529160200191611cf8565b820191906000526020600020905b815481529060010190602001808311611cdb57829003601f168201915b50505091909252505081519192505073ffffffffffffffffffffffffffffffffffffffff16611d5e5781516040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff9091166004820152602401610609565b83158015611d835750805173ffffffffffffffffffffffffffffffffffffffff163314155b15611dbc576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6040808301516000908152600c60205220600181015415611e115782604001516040517f5461848300000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b6040830151611e545782604001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b60208301511580611e7157506020830151611e7190600790612abe565b15611ea8576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608301518051600003611eea57806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c95565b81548290600490611f0890640100000000900463ffffffff166148eb565b82546101009290920a63ffffffff818102199093169183160217909155825464010000000090041660005b8251811015611fde57611f51838281518110611557576115576147e5565b611f8957826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c95565b611fd5838281518110611f9e57611f9e6147e5565b60200260200101518560030160008563ffffffff1663ffffffff168152602001908152602001600020612e5690919063ffffffff16565b50600101611f33565b50845183547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff918216178455604086015160028501556020860151600185018190556120349160079190612e5616565b50604085015161204690600990612e56565b50845160408087015160208089015183519283529082015263ffffffff909216917f74becb12a5e8fd0e98077d02dfba8f647c9670c9df177e42c2418cf17a636f05910160405180910390a25050505050806001019050611bf2565b60015473ffffffffffffffffffffffffffffffffffffffff163314612123576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610609565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b8281146121e2576040517fab8b67c60000000000000000000000000000000000000000000000000000000081526004810184905260248101829052604401610609565b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156124d757600086868381811061221a5761221a6147e5565b905060200201602081019061222f91906141ec565b63ffffffff81166000908152600b6020526040902080549192509073ffffffffffffffffffffffffffffffffffffffff1661229e576040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff83166004820152602401610609565b60008686858181106122b2576122b26147e5565b90506020028101906122c4919061490e565b6122cd9061494c565b805190915073ffffffffffffffffffffffffffffffffffffffff1661231e576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815473ffffffffffffffffffffffffffffffffffffffff16331480159061235b57503373ffffffffffffffffffffffffffffffffffffffff861614155b15612394576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b8051825473ffffffffffffffffffffffffffffffffffffffff908116911614158061241057506020808201516040516123cd9201613f77565b60405160208183030381529060405280519060200120826001016040516020016123f79190614dc2565b6040516020818303038152906040528051906020012014155b156124c957805182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020810151600183019061246a9082614a06565b50806000015173ffffffffffffffffffffffffffffffffffffffff168363ffffffff167f86f41145bde5dd7f523305452e4aad3685508c181432ec733d5f345009358a2883602001516040516124c09190613f77565b60405180910390a35b5050508060010190506121fe565b505050505050565b6125206040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b6040805160e0810182528381526000848152600260209081529290208054919283019161254c90614898565b80601f016020809104026020016040519081016040528092919081815260200182805461257890614898565b80156125c55780601f1061259a576101008083540402835291602001916125c5565b820191906000526020600020905b8154815290600101906020018083116125a857829003601f168201915b505050505081526020016002600085815260200190815260200160002060010180546125f090614898565b80601f016020809104026020016040519081016040528092919081815260200182805461261c90614898565b80156126695780601f1061263e57610100808354040283529160200191612669565b820191906000526020600020905b81548152906001019060200180831161264c57829003601f168201915b50505091835250506000848152600260208181526040909220015491019060ff16600381111561269b5761269b61444d565b815260008481526002602081815260409092200154910190610100900460ff1660018111156126cc576126cc61444d565b81526000848152600260208181526040928390209091015462010000900473ffffffffffffffffffffffffffffffffffffffff169083015201612710600585612abe565b1515905292915050565b612722612ad9565b63ffffffff8089166000908152600d6020526040812054640100000000900490911690819003612786576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff8a166004820152602401610609565b6127d8888888886040518060a001604052808f63ffffffff168152602001876127ae906148eb565b97508763ffffffff1681526020018a1515815260200189151581526020018860ff168152506130f6565b505050505050505050565b6127eb612ad9565b600e805460009164010000000090910463ffffffff1690600461280d836148eb565b82546101009290920a63ffffffff81810219909316918316021790915581166000818152600d602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001684179055815160a08101835292835260019083015286151590820152841515606082015260ff841660808201529091506128a39089908990899089906130f6565b5050505050505050565b606060006128bb6003612e49565b90506000815167ffffffffffffffff8111156128d9576128d9613d26565b60405190808252806020026020018201604052801561294b57816020015b6129386040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b8152602001906001900390816128f75790505b50905060005b82518110156107f25761297c83828151811061296f5761296f6147e5565b60200260200101516124df565b82828151811061298e5761298e6147e5565b6020908102919091010152600101612951565b606060006129af6009612e49565b90506000815167ffffffffffffffff8111156129cd576129cd613d26565b604051908082528060200260200182016040528015612a5457816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816129eb5790505b50905060005b82518110156107f257612a85838281518110612a7857612a786147e5565b6020026020010151611048565b828281518110612a9757612a976147e5565b6020908102919091010152600101612a5a565b612ab2612ad9565b612abb8161391b565b50565b600081815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612b5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610609565b565b6000610474825490565b6000612ad28383613a10565b6000612ad28383613a3a565b6040805160e0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840181905260c084015263ffffffff8581168352600d8252848320805464010000000090049091168084526001909101825284832060028101805487518186028101860190985280885295969295919493909190830182828015612c2f57602002820191906000526020600020905b815481526020019060010190808311612c1b575b505050505090506000815167ffffffffffffffff811115612c5257612c52613d26565b604051908082528060200260200182016040528015612c9857816020015b604080518082019091526000815260606020820152815260200190600190039081612c705790505b50905060005b8151811015612db0576040518060400160405280848381518110612cc457612cc46147e5565b60200260200101518152602001856003016000868581518110612ce957612ce96147e5565b602002602001015181526020019081526020016000208054612d0a90614898565b80601f0160208091040260200160405190810160405280929190818152602001828054612d3690614898565b8015612d835780601f10612d5857610100808354040283529160200191612d83565b820191906000526020600020905b815481529060010190602001808311612d6657829003601f168201915b5050505050815250828281518110612d9d57612d9d6147e5565b6020908102919091010152600101612c9e565b506040805160e08101825263ffffffff8089166000818152600d6020818152868320548086168752948b168187015260ff680100000000000000008604811697870197909752690100000000000000000085048716151560608701529290915290526a010000000000000000000090049091161515608082015260a08101612e3785612e49565b81526020019190915295945050505050565b60606000612ad283613b2d565b6000612ad28383613b89565b608081015173ffffffffffffffffffffffffffffffffffffffff1615612fb057608081015173ffffffffffffffffffffffffffffffffffffffff163b1580612f5b575060808101516040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f78bea72100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff909116906301ffc9a790602401602060405180830381865afa158015612f35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f599190614e70565b155b15612fb05760808101516040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610609565b600082815260026020526040902081518291908190612fcf9082614a06565b5060208201516001820190612fe49082614a06565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660018360038111156130265761302661444d565b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010083600181111561306d5761306d61444d565b0217905550608091909101516002909101805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff90921691909117905560405182907f04f0a9bcf3f3a3b42a4d7ca081119755f82ebe43e0d30c8f7292c4fe0dc4a2ae90600090a25050565b805163ffffffff9081166000908152600d602090815260408083208286015190941683526001909301905220608082015160ff161580613148575060808201518590613143906001614e8d565b60ff16115b156131915760808201516040517f25b4d61800000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101869052604401610609565b6001826020015163ffffffff16111561327957815163ffffffff166000908152600d6020908152604082209084015160019182019183916131d29190614843565b63ffffffff1663ffffffff168152602001908152602001600020905060005b6131fa82612b5c565b81101561327657613229846000015163ffffffff16600c60006105928587600001612b6690919063ffffffff16565b50600c60006132388484612b66565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556001016131f1565b50505b60005b858110156134b3576132a9878783818110613299576132996147e5565b8592602090910201359050612e56565b61330a5782518787838181106132c1576132c16147e5565b6040517f636e405700000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b82606001511561346157825163ffffffff16600c6000898985818110613332576133326147e5565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff16148015906133ac5750600c600088888481811061337d5761337d6147e5565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff1615155b1561340e5782518787838181106133c5576133c56147e5565b6040517f60b9df7300000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8251600c6000898985818110613426576134266147e5565b90506020020135815260200190815260200160002060000160086101000a81548163ffffffff021916908363ffffffff1602179055506134ab565b82516134a99063ffffffff16600c60008a8a86818110613483576134836147e5565b905060200201358152602001908152602001600020600401612e5690919063ffffffff16565b505b60010161327c565b5060005b838110156138c157368585838181106134d2576134d26147e5565b90506020028101906134e4919061490e565b90506134f260038235612abe565b61352b576040517fe181733f00000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b61353760058235612abe565b15613571576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b803560009081526003840160205260408120805461358e90614898565b905011156135da5783516040517f3927d08000000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015281356024820152604401610609565b60005b878110156136e4576136818235600c60008c8c86818110613600576136006147e5565b9050602002013581526020019081526020016000206003016000600c60008e8e88818110613630576136306147e5565b90506020020135815260200190815260200160002060000160049054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020612abe90919063ffffffff16565b6136dc57888882818110613697576136976147e5565b6040517fa7e792500000000000000000000000000000000000000000000000000000000081526020909102929092013560048301525082356024820152604401610609565b6001016135dd565b506002830180546001810182556000918252602091829020833591015561370d90820182614ea6565b8235600090815260038601602052604090209161372b919083614f0b565b50604080850151855163ffffffff9081166000908152600d602090815284822080549415156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff90951694909417909355606088015188518316825284822080549115156a0100000000000000000000027fffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff9092169190911790556080880151885183168252848220805460ff9290921668010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff909216919091179055828801805189518416835294909120805494909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff909416939093179055855191516138b892918435908c908c9061387e90880188614ea6565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613bd892505050565b506001016134b7565b50815160208301516040517ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c15817036519261390b92909163ffffffff92831681529116602082015260400190565b60405180910390a1505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361399a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610609565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613a2757613a276147e5565b9060005260206000200154905092915050565b60008181526001830160205260408120548015613b23576000613a5e600183615026565b8554909150600090613a7290600190615026565b9050818114613ad7576000866000018281548110613a9257613a926147e5565b9060005260206000200154905080876000018481548110613ab557613ab56147e5565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613ae857613ae8615039565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610474565b6000915050610474565b606081600001805480602002602001604051908101604052809291908181526020018280548015613b7d57602002820191906000526020600020905b815481526020019060010190808311613b69575b50505050509050919050565b6000818152600183016020526040812054613bd057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610474565b506000610474565b6000848152600260208190526040909120015462010000900473ffffffffffffffffffffffffffffffffffffffff16156124d757600084815260026020819052604091829020015490517ffba64a7c0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169063fba64a7c90613c7f908690869086908b908d90600401615068565b600060405180830381600087803b158015613c9957600080fd5b505af1158015613cad573d6000803e3d6000fd5b50505050505050505050565b508054613cc590614898565b6000825580601f10613cd5575050565b601f016020900490600052602060002090810190612abb9190613d0d565b5080546000825590600052602060002090810190612abb91905b5b80821115613d225760008155600101613d0e565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613d7857613d78613d26565b60405290565b60405160a0810167ffffffffffffffff81118282101715613d7857613d78613d26565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613de857613de8613d26565b604052919050565b600067ffffffffffffffff821115613e0a57613e0a613d26565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613e4757600080fd5b8135613e5a613e5582613df0565b613da1565b818152846020838601011115613e6f57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613e9f57600080fd5b823567ffffffffffffffff80821115613eb757600080fd5b613ec386838701613e36565b93506020850135915080821115613ed957600080fd5b50613ee685828601613e36565b9150509250929050565b600060208284031215613f0257600080fd5b5035919050565b60005b83811015613f24578181015183820152602001613f0c565b50506000910152565b60008151808452613f45816020860160208601613f09565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612ad26020830184613f2d565b60008083601f840112613f9c57600080fd5b50813567ffffffffffffffff811115613fb457600080fd5b6020830191508360208260051b850101111561104157600080fd5b60008060208385031215613fe257600080fd5b823567ffffffffffffffff811115613ff957600080fd5b61400585828601613f8a565b90969095509350505050565b60008151808452602080850194506020840160005b8381101561404257815187529582019590820190600101614026565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b848110156140ca578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051845284015160408585018190526140b681860183613f2d565b9a86019a945050509083019060010161406a565b5090979650505050505050565b600063ffffffff8083511684528060208401511660208501525060ff604083015116604084015260608201511515606084015260808201511515608084015260a082015160e060a085015261412f60e0850182614011565b905060c083015184820360c0860152614148828261404d565b95945050505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526141b48583516140d7565b9450928501929085019060010161417a565b5092979650505050505050565b803563ffffffff811681146141e757600080fd5b919050565b6000602082840312156141fe57600080fd5b612ad2826141d3565b73ffffffffffffffffffffffffffffffffffffffff8151168252600060208201516040602085015261423c6040850182613f2d565b949350505050565b602081526000612ad26020830184614207565b602081526000612ad260208301846140d7565b6000806040838503121561427d57600080fd5b614286836141d3565b946020939093013593505050565b6040815260006142a76040830185613f2d565b82810360208401526141488185613f2d565b600063ffffffff808351168452602081818501511681860152816040850151166040860152606084015160608601526080840151608086015260a0840151915060e060a086015261430d60e0860183614011565b60c08581015187830391880191909152805180835290830193506000918301905b8083101561434e578451825293830193600192909201919083019061432e565b509695505050505050565b602081526000612ad260208301846142b9565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526143cf858351614207565b94509285019290850190600101614395565b600080600080604085870312156143f757600080fd5b843567ffffffffffffffff8082111561440f57600080fd5b61441b88838901613f8a565b9096509450602087013591508082111561443457600080fd5b5061444187828801613f8a565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b805182526000602082015160e0602085015261449b60e0850182613f2d565b9050604083015184820360408601526144b48282613f2d565b9150506060830151600481106144cc576144cc61444d565b60608501526080830151600281106144e6576144e661444d565b8060808601525060a083015161451460a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015161452860c086018215159052565b509392505050565b602081526000612ad2602083018461447c565b8015158114612abb57600080fd5b803560ff811681146141e757600080fd5b60008060008060008060008060c0898b03121561457e57600080fd5b614587896141d3565b9750602089013567ffffffffffffffff808211156145a457600080fd5b6145b08c838d01613f8a565b909950975060408b01359150808211156145c957600080fd5b506145d68b828c01613f8a565b90965094505060608901356145ea81614543565b925060808901356145fa81614543565b915061460860a08a01614551565b90509295985092959890939650565b600080600080600080600060a0888a03121561463257600080fd5b873567ffffffffffffffff8082111561464a57600080fd5b6146568b838c01613f8a565b909950975060208a013591508082111561466f57600080fd5b5061467c8a828b01613f8a565b909650945050604088013561469081614543565b925060608801356146a081614543565b91506146ae60808901614551565b905092959891949750929550565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261471f85835161447c565b945092850192908501906001016146e5565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141c6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526147948583516142b9565b9450928501929085019060010161475a565b803573ffffffffffffffffffffffffffffffffffffffff811681146141e757600080fd5b6000602082840312156147dc57600080fd5b612ad2826147a6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff8281168282160390808211156107f2576107f2614814565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361489157614891614814565b5060010190565b600181811c908216806148ac57607f821691505b6020821081036148e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600063ffffffff80831681810361490457614904614814565b6001019392505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261494257600080fd5b9190910192915050565b60006040823603121561495e57600080fd5b6040516040810167ffffffffffffffff828210818311171561498257614982613d26565b8160405261498f856147a6565b835260208501359150808211156149a557600080fd5b506149b236828601613e36565b60208301525092915050565b601f821115610697576000816000526020600020601f850160051c810160208610156149e75750805b601f850160051c820191505b818110156124d7578281556001016149f3565b815167ffffffffffffffff811115614a2057614a20613d26565b614a3481614a2e8454614898565b846149be565b602080601f831160018114614a875760008415614a515750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556124d7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614ad457888601518255948401946001909101908401614ab5565b5085821015614b1057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215614b3257600080fd5b815167ffffffffffffffff811115614b4957600080fd5b8201601f81018413614b5a57600080fd5b8051614b68613e5582613df0565b818152856020838501011115614b7d57600080fd5b614148826020830160208601613f09565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183360301811261494257600080fd5b600060808236031215614bd457600080fd5b614bdc613d55565b614be5836141d3565b81526020808401358183015260408401356040830152606084013567ffffffffffffffff80821115614c1657600080fd5b9085019036601f830112614c2957600080fd5b813581811115614c3b57614c3b613d26565b8060051b9150614c4c848301613da1565b8181529183018401918481019036841115614c6657600080fd5b938501935b83851015614c8457843582529385019390850190614c6b565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614ccd57835183529284019291840191600101614cb1565b50909695505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261494257600080fd5b8035600281106141e757600080fd5b600060a08236031215614d2e57600080fd5b614d36613d7e565b823567ffffffffffffffff80821115614d4e57600080fd5b614d5a36838701613e36565b83526020850135915080821115614d7057600080fd5b50614d7d36828601613e36565b602083015250604083013560048110614d9557600080fd5b6040820152614da660608401614d0d565b6060820152614db7608084016147a6565b608082015292915050565b6000602080835260008454614dd681614898565b8060208701526040600180841660008114614df85760018114614e3257614e62565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550614e62565b89600052602060002060005b85811015614e595781548b8201860152908301908801614e3e565b8a016040019650505b509398975050505050505050565b600060208284031215614e8257600080fd5b8151612ad281614543565b60ff818116838216019081111561047457610474614814565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614edb57600080fd5b83018035915067ffffffffffffffff821115614ef657600080fd5b60200191503681900382131561104157600080fd5b67ffffffffffffffff831115614f2357614f23613d26565b614f3783614f318354614898565b836149be565b6000601f841160018114614f895760008515614f535750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561501f565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015614fd85786850135825560209485019460019092019101614fb8565b5086821015615013577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8181038181111561047457610474614814565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6080815284608082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8611156150a157600080fd5b8560051b808860a0850137820182810360a090810160208501526150c790820187613f2d565b91505063ffffffff8085166040840152808416606084015250969550505050505056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityIsDeprecated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"CapabilityRequiredByDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"DONDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONNode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"nodeCount\",\"type\":\"uint256\"}],\"name\":\"InvalidFaultTolerance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"InvalidNodeCapabilities\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"InvalidNodeP2PId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotSupportCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfCapabilitiesDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfWorkflowDON\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilitiesRegistry.Capability[]\",\"name\":\"capabilities\",\"type\":\"tuple[]\"}],\"name\":\"addCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"addDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"addNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"deprecateCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityConfigs\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"getDON\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"getHashedCapabilityId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"getNode\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo\",\"name\":\"nodeInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodeOperators\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodes\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"isCapabilityDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"donIds\",\"type\":\"uint32[]\"}],\"name\":\"removeDONs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"removedNodeP2PIds\",\"type\":\"bytes32[]\"}],\"name\":\"removeNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"updateDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"updateNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6080604052600e80546001600160401b0319166401000000011790553480156200002857600080fd5b503380600081620000805760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000b357620000b381620000bc565b50505062000167565b336001600160a01b03821603620001165760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000077565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6150e080620001776000396000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80635d83d967116100ee57806386fa424611610097578063d8bc7b6811610071578063d8bc7b68146103f6578063ddbe4f8214610409578063e29581aa1461041e578063f2fde38b1461043357600080fd5b806386fa42461461039b5780638da5cb5b146103ae5780639cb7c5f4146103d657600080fd5b8063715f5295116100c8578063715f52951461036d57806373ac22b41461038057806379ba50971461039357600080fd5b80635d83d967146103325780635e65e3091461034557806366acaa331461035857600080fd5b8063235374051161015b5780632c01a1e8116101355780632c01a1e8146102cb578063398f3773146102de5780633f2a13c9146102f157806350c946fe1461031257600080fd5b80632353740514610285578063275459f2146102a55780632a852933146102b857600080fd5b80631d05394c1161018c5780631d05394c1461023b578063214502431461025057806322bdbcbc1461026557600080fd5b80630fe5800a146101b357806312570011146101d9578063181f5a77146101fc575b600080fd5b6101c66101c1366004613ea3565b610446565b6040519081526020015b60405180910390f35b6101ec6101e7366004613f07565b61047a565b60405190151581526020016101d0565b604080518082018252601a81527f4361706162696c6974696573526567697374727920312e302e30000000000000602082015290516101d09190613f8e565b61024e610249366004613fe6565b610487565b005b61025861069c565b6040516101d09190614168565b610278610273366004614203565b6107f9565b6040516101d0919061425b565b610298610293366004614203565b6108e6565b6040516101d0919061426e565b61024e6102b3366004613fe6565b61092a565b61024e6102c63660046142a0565b610a01565b61024e6102d9366004613fe6565b610ae1565b61024e6102ec366004613fe6565b610d7d565b6103046102ff366004614343565b610f3c565b6040516101d092919061436d565b610325610320366004613f07565b611128565b6040516101d09190614432565b61024e610340366004613fe6565b611202565b61024e610353366004613fe6565b6112f7565b610360611a1f565b6040516101d09190614445565b61024e61037b366004613fe6565b611c02565b61024e61038e366004613fe6565b611cb4565b61024e612182565b61024e6103a93660046144ba565b61227f565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d0565b6103e96103e4366004613f07565b6125bf565b6040516101d09190614609565b61024e61040436600461461c565b6127fa565b6104116128c4565b6040516101d091906146a5565b6104266129b8565b6040516101d0919061471a565b61024e6104413660046147b3565b612ac1565b6000828260405160200161045b92919061436d565b6040516020818303038152906040528051906020012090505b92915050565b6000610474600583612ad5565b61048f612af0565b60005b818110156106975760008383838181106104ae576104ae6147ce565b90506020020160208101906104c39190614203565b63ffffffff8181166000908152600d60209081526040808320805464010000000081049095168085526001820190935290832094955093909290916a010000000000000000000090910460ff16905b61051b83612b73565b8110156105bb57811561057157600c60006105368584612b7d565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556105b3565b6105b18663ffffffff16600c60006105928588612b7d90919063ffffffff16565b8152602001908152602001600020600401612b8990919063ffffffff16565b505b600101610512565b508354640100000000900463ffffffff16600003610612576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff861660048201526024015b60405180910390fd5b63ffffffff85166000818152600d6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffff00000000000000000000001690558051938452908301919091527ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c1581703651910160405180910390a15050505050806001019050610492565b505050565b600e54606090640100000000900463ffffffff1660006106bd60018361482c565b63ffffffff1667ffffffffffffffff8111156106db576106db613d3d565b60405190808252806020026020018201604052801561076257816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816106f95790505b509050600060015b8363ffffffff168163ffffffff1610156107d65763ffffffff8082166000908152600d602052604090205416156107ce576107a481612b95565b8383815181106107b6576107b66147ce565b6020026020010181905250816107cb90614849565b91505b60010161076a565b506107e260018461482c565b63ffffffff1681146107f2578082525b5092915050565b60408051808201909152600081526060602082015263ffffffff82166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161085d90614881565b80601f016020809104026020016040519081016040528092919081815260200182805461088990614881565b80156108d65780601f106108ab576101008083540402835291602001916108d6565b820191906000526020600020905b8154815290600101906020018083116108b957829003601f168201915b5050505050815250509050919050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c081019190915261047482612b95565b610932612af0565b60005b63ffffffff811682111561069757600083838363ffffffff1681811061095d5761095d6147ce565b90506020020160208101906109729190614203565b63ffffffff81166000908152600b6020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559192506109bd6001830182613cd0565b505060405163ffffffff8216907fa59268ca81d40429e65ccea5385b59cf2d3fc6519371dee92f8eb1dae5107a7a90600090a2506109fa816148d4565b9050610935565b610a09612af0565b63ffffffff8088166000908152600d60205260408120805490926401000000009091041690819003610a6f576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff8a166004820152602401610609565b610ad6888888886040518060a001604052808f63ffffffff16815260200187610a97906148d4565b63ffffffff811682528b15156020830152895460ff6a01000000000000000000009091048116151560408401528b166060909201919091529650612e60565b505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d77576000848483818110610b1b57610b1b6147ce565b602090810292909201356000818152600c90935260409092206001810154929350919050610b78576040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260048101839052602401610609565b6000610b8682600401612b73565b1115610bdb57610b996004820184612b7d565b6040517f60a6d89800000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101839052604401610609565b805468010000000000000000900463ffffffff1615610c435780546040517f60b9df730000000000000000000000000000000000000000000000000000000081526801000000000000000090910463ffffffff16600482015260248101839052604401610609565b83158015610c7d5750805463ffffffff166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15610cb6576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6001810154610cc790600790612b89565b506002810154610cd990600990612b89565b506000828152600c6020526040812080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815560018101829055600281018290559060048201818181610d2e8282613d0a565b5050505050507f5254e609a97bab37b7cc79fe128f85c097bd6015c6e1624ae0ba392eb975320582604051610d6591815260200190565b60405180910390a15050600101610aff565b50505050565b610d85612af0565b60005b81811015610697576000838383818110610da457610da46147ce565b9050602002810190610db691906148f7565b610dbf90614935565b805190915073ffffffffffffffffffffffffffffffffffffffff16610e10576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815263ffffffff9095166000818152600b909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251919290916001820190610e9c90826149ef565b5050600e8054909150600090610eb79063ffffffff166148d4565b91906101000a81548163ffffffff021916908363ffffffff160217905550816000015173ffffffffffffffffffffffffffffffffffffffff168163ffffffff167f78e94ca80be2c30abc061b99e7eb8583b1254781734b1e3ce339abb57da2fe8e8460200151604051610f2a9190613f8e565b60405180910390a35050600101610d88565b63ffffffff8083166000908152600d60209081526040808320805464010000000090049094168084526001909401825280832085845260030190915281208054606093849390929091610f8e90614881565b80601f0160208091040260200160405190810160405280929190818152602001828054610fba90614881565b80156110075780601f10610fdc57610100808354040283529160200191611007565b820191906000526020600020905b815481529060010190602001808311610fea57829003601f168201915b5050506000888152600260208190526040909120015492935060609262010000900473ffffffffffffffffffffffffffffffffffffffff1615915061111a905057600086815260026020819052604091829020015490517f8318ed5d00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526201000090910473ffffffffffffffffffffffffffffffffffffffff1690638318ed5d90602401600060405180830381865afa1580156110d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111179190810190614b09565b90505b9093509150505b9250929050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c08101919091526040805160e0810182526000848152600c6020908152838220805463ffffffff8082168652640100000000820481168487018190526801000000000000000090920416858701526001820154606086015260028201546080860152835260030190529190912060a08201906111d790613685565b81526020016111fa600c6000868152602001908152602001600020600401613685565b905292915050565b61120a612af0565b60005b81811015610697576000838383818110611229576112296147ce565b905060200201359050611246816003612ad590919063ffffffff16565b61127f576040517fe181733f00000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b61128a600582613692565b6112c3576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b60405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a25060010161120d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d77576000848483818110611331576113316147ce565b90506020028101906113439190614b77565b61134c90614bab565b6040808201516000908152600c6020908152828220805463ffffffff168352600b82528383208451808601909552805473ffffffffffffffffffffffffffffffffffffffff16855260018101805496975091959394939092840191906113b190614881565b80601f01602080910402602001604051908101604052809291908181526020018280546113dd90614881565b801561142a5780601f106113ff5761010080835404028352916020019161142a565b820191906000526020600020905b81548152906001019060200180831161140d57829003601f168201915b50505091909252505050600183015490915061147a5782604001516040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b8415801561149f5750805173ffffffffffffffffffffffffffffffffffffffff163314155b156114d8576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6020830151611513576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018201546020840151811461159457602084015161153490600790612ad5565b1561156b576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208401516001840155611580600782612b89565b50602084015161159290600790613692565b505b606084015180516000036115d657806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c7e565b835460009085906004906115f790640100000000900463ffffffff166148d4565b91906101000a81548163ffffffff021916908363ffffffff1602179055905060005b82518110156116dc5761164f838281518110611637576116376147ce565b60200260200101516003612ad590919063ffffffff16565b61168757826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c7e565b6116d383828151811061169c5761169c6147ce565b60200260200101518760030160008563ffffffff1663ffffffff16815260200190815260200160002061369290919063ffffffff16565b50600101611619565b50845468010000000000000000900463ffffffff16801561183d5763ffffffff8082166000908152600d60209081526040808320805464010000000090049094168352600190930181528282206002018054845181840281018401909552808552929392909183018282801561177157602002820191906000526020600020905b81548152602001906001019080831161175d575b5050505050905060005b815181101561183a576117d0828281518110611799576117996147ce565b60200260200101518960030160008763ffffffff1663ffffffff168152602001908152602001600020612ad590919063ffffffff16565b611832578181815181106117e6576117e66147ce565b6020026020010151836040517f03dcd86200000000000000000000000000000000000000000000000000000000815260040161060992919091825263ffffffff16602082015260400190565b60010161177b565b50505b600061184b87600401613685565b905060005b81518163ffffffff161015611991576000828263ffffffff1681518110611879576118796147ce565b60209081029190910181015163ffffffff8082166000908152600d8452604080822080546401000000009004909316825260019092018452818120600201805483518187028101870190945280845293955090939192909183018282801561190057602002820191906000526020600020905b8154815260200190600101908083116118ec575b5050505050905060005b815181101561197d5761195f828281518110611928576119286147ce565b60200260200101518c60030160008a63ffffffff1663ffffffff168152602001908152602001600020612ad590919063ffffffff16565b611975578181815181106117e6576117e66147ce565b60010161190a565b5050508061198a906148d4565b9050611850565b50875187547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90911690811788556040808a015160028a018190556020808c01518351928352908201527f4b5b465e22eea0c3d40c30e936643245b80d19b2dcf75788c0699fe8d8db645b910160405180910390a25050505050505050806001019050611315565b600e5460609063ffffffff166000611a3860018361482c565b63ffffffff1667ffffffffffffffff811115611a5657611a56613d3d565b604051908082528060200260200182016040528015611a9c57816020015b604080518082019091526000815260606020820152815260200190600190039081611a745790505b509050600060015b8363ffffffff168163ffffffff161015611bec5763ffffffff81166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611be45763ffffffff81166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191611b3890614881565b80601f0160208091040260200160405190810160405280929190818152602001828054611b6490614881565b8015611bb15780601f10611b8657610100808354040283529160200191611bb1565b820191906000526020600020905b815481529060010190602001808311611b9457829003601f168201915b505050505081525050838381518110611bcc57611bcc6147ce565b602002602001018190525081611be190614849565b91505b600101611aa4565b50600e546107e29060019063ffffffff1661482c565b611c0a612af0565b60005b81811015610697576000838383818110611c2957611c296147ce565b9050602002810190611c3b9190614cc2565b611c4490614d05565b90506000611c5a82600001518360200151610446565b9050611c67600382613692565b611ca0576040517febf5255100000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b611caa818361369e565b5050600101611c0d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d77576000848483818110611cee57611cee6147ce565b9050602002810190611d009190614b77565b611d0990614bab565b805163ffffffff166000908152600b602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191611d5f90614881565b80601f0160208091040260200160405190810160405280929190818152602001828054611d8b90614881565b8015611dd85780601f10611dad57610100808354040283529160200191611dd8565b820191906000526020600020905b815481529060010190602001808311611dbb57829003601f168201915b50505091909252505081519192505073ffffffffffffffffffffffffffffffffffffffff16611e3e5781516040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff9091166004820152602401610609565b83158015611e635750805173ffffffffffffffffffffffffffffffffffffffff163314155b15611e9c576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6040808301516000908152600c60205220600181015415611ef15782604001516040517f5461848300000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b6040830151611f345782604001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b60208301511580611f5157506020830151611f5190600790612ad5565b15611f88576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608301518051600003611fca57806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c7e565b81548290600490611fe890640100000000900463ffffffff166148d4565b82546101009290920a63ffffffff818102199093169183160217909155825464010000000090041660005b82518110156120be57612031838281518110611637576116376147ce565b61206957826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c7e565b6120b583828151811061207e5761207e6147ce565b60200260200101518560030160008563ffffffff1663ffffffff16815260200190815260200160002061369290919063ffffffff16565b50600101612013565b50845183547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff91821617845560408601516002850155602086015160018501819055612114916007919061369216565b50604085015161212690600990613692565b50845160408087015160208089015183519283529082015263ffffffff909216917f74becb12a5e8fd0e98077d02dfba8f647c9670c9df177e42c2418cf17a636f05910160405180910390a25050505050806001019050611cd2565b60015473ffffffffffffffffffffffffffffffffffffffff163314612203576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610609565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b8281146122c2576040517fab8b67c60000000000000000000000000000000000000000000000000000000081526004810184905260248101829052604401610609565b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156125b75760008686838181106122fa576122fa6147ce565b905060200201602081019061230f9190614203565b63ffffffff81166000908152600b6020526040902080549192509073ffffffffffffffffffffffffffffffffffffffff1661237e576040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff83166004820152602401610609565b6000868685818110612392576123926147ce565b90506020028101906123a491906148f7565b6123ad90614935565b805190915073ffffffffffffffffffffffffffffffffffffffff166123fe576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815473ffffffffffffffffffffffffffffffffffffffff16331480159061243b57503373ffffffffffffffffffffffffffffffffffffffff861614155b15612474576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b8051825473ffffffffffffffffffffffffffffffffffffffff90811691161415806124f057506020808201516040516124ad9201613f8e565b60405160208183030381529060405280519060200120826001016040516020016124d79190614dab565b6040516020818303038152906040528051906020012014155b156125a957805182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020810151600183019061254a90826149ef565b50806000015173ffffffffffffffffffffffffffffffffffffffff168363ffffffff167f86f41145bde5dd7f523305452e4aad3685508c181432ec733d5f345009358a2883602001516040516125a09190613f8e565b60405180910390a35b5050508060010190506122de565b505050505050565b6126006040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b6040805160e0810182528381526000848152600260209081529290208054919283019161262c90614881565b80601f016020809104026020016040519081016040528092919081815260200182805461265890614881565b80156126a55780601f1061267a576101008083540402835291602001916126a5565b820191906000526020600020905b81548152906001019060200180831161268857829003601f168201915b505050505081526020016002600085815260200190815260200160002060010180546126d090614881565b80601f01602080910402602001604051908101604052809291908181526020018280546126fc90614881565b80156127495780601f1061271e57610100808354040283529160200191612749565b820191906000526020600020905b81548152906001019060200180831161272c57829003601f168201915b50505091835250506000848152600260208181526040909220015491019060ff16600381111561277b5761277b614526565b815260008481526002602081815260409092200154910190610100900460ff1660018111156127ac576127ac614526565b81526000848152600260208181526040928390209091015462010000900473ffffffffffffffffffffffffffffffffffffffff1690830152016127f0600585612ad5565b1515905292915050565b612802612af0565b600e805460009164010000000090910463ffffffff16906004612824836148d4565b82546101009290920a63ffffffff81810219909316918316021790915581166000818152600d602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001684179055815160a08101835292835260019083015286151590820152841515606082015260ff841660808201529091506128ba908990899089908990612e60565b5050505050505050565b606060006128d26003613685565b90506000815167ffffffffffffffff8111156128f0576128f0613d3d565b60405190808252806020026020018201604052801561296257816020015b61294f6040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b81526020019060019003908161290e5790505b50905060005b82518110156107f257612993838281518110612986576129866147ce565b60200260200101516125bf565b8282815181106129a5576129a56147ce565b6020908102919091010152600101612968565b606060006129c66009613685565b90506000815167ffffffffffffffff8111156129e4576129e4613d3d565b604051908082528060200260200182016040528015612a6b57816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181612a025790505b50905060005b82518110156107f257612a9c838281518110612a8f57612a8f6147ce565b6020026020010151611128565b828281518110612aae57612aae6147ce565b6020908102919091010152600101612a71565b612ac9612af0565b612ad281613932565b50565b600081815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612b71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610609565b565b6000610474825490565b6000612ae98383613a27565b6000612ae98383613a51565b6040805160e0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840181905260c084015263ffffffff8581168352600d8252848320805464010000000090049091168084526001909101825284832060028101805487518186028101860190985280885295969295919493909190830182828015612c4657602002820191906000526020600020905b815481526020019060010190808311612c32575b505050505090506000815167ffffffffffffffff811115612c6957612c69613d3d565b604051908082528060200260200182016040528015612caf57816020015b604080518082019091526000815260606020820152815260200190600190039081612c875790505b50905060005b8151811015612dc7576040518060400160405280848381518110612cdb57612cdb6147ce565b60200260200101518152602001856003016000868581518110612d0057612d006147ce565b602002602001015181526020019081526020016000208054612d2190614881565b80601f0160208091040260200160405190810160405280929190818152602001828054612d4d90614881565b8015612d9a5780601f10612d6f57610100808354040283529160200191612d9a565b820191906000526020600020905b815481529060010190602001808311612d7d57829003601f168201915b5050505050815250828281518110612db457612db46147ce565b6020908102919091010152600101612cb5565b506040805160e08101825263ffffffff8089166000818152600d6020818152868320548086168752948b168187015260ff680100000000000000008604811697870197909752690100000000000000000085048716151560608701529290915290526a010000000000000000000090049091161515608082015260a08101612e4e85613685565b81526020019190915295945050505050565b805163ffffffff9081166000908152600d602090815260408083208286015190941683526001909301905220608082015160ff161580612eb2575060808201518590612ead906001614e59565b60ff16115b15612efb5760808201516040517f25b4d61800000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101869052604401610609565b6001826020015163ffffffff161115612fe357815163ffffffff166000908152600d602090815260408220908401516001918201918391612f3c919061482c565b63ffffffff1663ffffffff168152602001908152602001600020905060005b612f6482612b73565b811015612fe057612f93846000015163ffffffff16600c60006105928587600001612b7d90919063ffffffff16565b50600c6000612fa28484612b7d565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff169055600101612f5b565b50505b60005b8581101561321d57613013878783818110613003576130036147ce565b8592602090910201359050613692565b61307457825187878381811061302b5761302b6147ce565b6040517f636e405700000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8260600151156131cb57825163ffffffff16600c600089898581811061309c5761309c6147ce565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff16148015906131165750600c60008888848181106130e7576130e76147ce565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff1615155b1561317857825187878381811061312f5761312f6147ce565b6040517f60b9df7300000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8251600c6000898985818110613190576131906147ce565b90506020020135815260200190815260200160002060000160086101000a81548163ffffffff021916908363ffffffff160217905550613215565b82516132139063ffffffff16600c60008a8a868181106131ed576131ed6147ce565b90506020020135815260200190815260200160002060040161369290919063ffffffff16565b505b600101612fe6565b5060005b8381101561362b573685858381811061323c5761323c6147ce565b905060200281019061324e91906148f7565b905061325c60038235612ad5565b613295576040517fe181733f00000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b6132a160058235612ad5565b156132db576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b80356000908152600384016020526040812080546132f890614881565b905011156133445783516040517f3927d08000000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015281356024820152604401610609565b60005b8781101561344e576133eb8235600c60008c8c8681811061336a5761336a6147ce565b9050602002013581526020019081526020016000206003016000600c60008e8e8881811061339a5761339a6147ce565b90506020020135815260200190815260200160002060000160049054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020612ad590919063ffffffff16565b61344657888882818110613401576134016147ce565b6040517fa7e792500000000000000000000000000000000000000000000000000000000081526020909102929092013560048301525082356024820152604401610609565b600101613347565b506002830180546001810182556000918252602091829020833591015561347790820182614e72565b82356000908152600386016020526040902091613495919083614ed7565b50604080850151855163ffffffff9081166000908152600d602090815284822080549415156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff90951694909417909355606088015188518316825284822080549115156a0100000000000000000000027fffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff9092169190911790556080880151885183168252848220805460ff9290921668010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff909216919091179055828801805189518416835294909120805494909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9094169390931790558551915161362292918435908c908c906135e890880188614e72565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613b4492505050565b50600101613221565b50815160208301516040517ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c15817036519261367592909163ffffffff92831681529116602082015260400190565b60405180910390a1505050505050565b60606000612ae983613c25565b6000612ae98383613c81565b608081015173ffffffffffffffffffffffffffffffffffffffff16156137ec57608081015173ffffffffffffffffffffffffffffffffffffffff163b1580613797575060808101516040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f78bea72100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff909116906301ffc9a790602401602060405180830381865afa158015613771573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137959190614ff2565b155b156137ec5760808101516040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610609565b60008281526002602052604090208151829190819061380b90826149ef565b506020820151600182019061382090826149ef565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600381111561386257613862614526565b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156138a9576138a9614526565b0217905550608091909101516002909101805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff90921691909117905560405182907f04f0a9bcf3f3a3b42a4d7ca081119755f82ebe43e0d30c8f7292c4fe0dc4a2ae90600090a25050565b3373ffffffffffffffffffffffffffffffffffffffff8216036139b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610609565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613a3e57613a3e6147ce565b9060005260206000200154905092915050565b60008181526001830160205260408120548015613b3a576000613a7560018361500f565b8554909150600090613a899060019061500f565b9050818114613aee576000866000018281548110613aa957613aa96147ce565b9060005260206000200154905080876000018481548110613acc57613acc6147ce565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613aff57613aff615022565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610474565b6000915050610474565b6000848152600260208190526040909120015462010000900473ffffffffffffffffffffffffffffffffffffffff16156125b757600084815260026020819052604091829020015490517ffba64a7c0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169063fba64a7c90613beb908690869086908b908d90600401615051565b600060405180830381600087803b158015613c0557600080fd5b505af1158015613c19573d6000803e3d6000fd5b50505050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015613c7557602002820191906000526020600020905b815481526020019060010190808311613c61575b50505050509050919050565b6000818152600183016020526040812054613cc857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610474565b506000610474565b508054613cdc90614881565b6000825580601f10613cec575050565b601f016020900490600052602060002090810190612ad29190613d24565b5080546000825590600052602060002090810190612ad291905b5b80821115613d395760008155600101613d25565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613d8f57613d8f613d3d565b60405290565b60405160a0810167ffffffffffffffff81118282101715613d8f57613d8f613d3d565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613dff57613dff613d3d565b604052919050565b600067ffffffffffffffff821115613e2157613e21613d3d565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613e5e57600080fd5b8135613e71613e6c82613e07565b613db8565b818152846020838601011115613e8657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613eb657600080fd5b823567ffffffffffffffff80821115613ece57600080fd5b613eda86838701613e4d565b93506020850135915080821115613ef057600080fd5b50613efd85828601613e4d565b9150509250929050565b600060208284031215613f1957600080fd5b5035919050565b60005b83811015613f3b578181015183820152602001613f23565b50506000910152565b60008151808452613f5c816020860160208601613f20565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612ae96020830184613f44565b60008083601f840112613fb357600080fd5b50813567ffffffffffffffff811115613fcb57600080fd5b6020830191508360208260051b850101111561112157600080fd5b60008060208385031215613ff957600080fd5b823567ffffffffffffffff81111561401057600080fd5b61401c85828601613fa1565b90969095509350505050565b60008151808452602080850194506020840160005b838110156140595781518752958201959082019060010161403d565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b848110156140e1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051845284015160408585018190526140cd81860183613f44565b9a86019a9450505090830190600101614081565b5090979650505050505050565b600063ffffffff8083511684528060208401511660208501525060ff604083015116604084015260608201511515606084015260808201511515608084015260a082015160e060a085015261414660e0850182614028565b905060c083015184820360c086015261415f8282614064565b95945050505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526141cb8583516140ee565b94509285019290850190600101614191565b5092979650505050505050565b803563ffffffff811681146141fe57600080fd5b919050565b60006020828403121561421557600080fd5b612ae9826141ea565b73ffffffffffffffffffffffffffffffffffffffff815116825260006020820151604060208501526142536040850182613f44565b949350505050565b602081526000612ae9602083018461421e565b602081526000612ae960208301846140ee565b8015158114612ad257600080fd5b803560ff811681146141fe57600080fd5b600080600080600080600060a0888a0312156142bb57600080fd5b6142c4886141ea565b9650602088013567ffffffffffffffff808211156142e157600080fd5b6142ed8b838c01613fa1565b909850965060408a013591508082111561430657600080fd5b506143138a828b01613fa1565b909550935050606088013561432781614281565b91506143356080890161428f565b905092959891949750929550565b6000806040838503121561435657600080fd5b61435f836141ea565b946020939093013593505050565b6040815260006143806040830185613f44565b828103602084015261415f8185613f44565b600063ffffffff808351168452602081818501511681860152816040850151166040860152606084015160608601526080840151608086015260a0840151915060e060a08601526143e660e0860183614028565b60c08581015187830391880191909152805180835290830193506000918301905b808310156144275784518252938301936001929092019190830190614407565b509695505050505050565b602081526000612ae96020830184614392565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526144a885835161421e565b9450928501929085019060010161446e565b600080600080604085870312156144d057600080fd5b843567ffffffffffffffff808211156144e857600080fd5b6144f488838901613fa1565b9096509450602087013591508082111561450d57600080fd5b5061451a87828801613fa1565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b805182526000602082015160e0602085015261457460e0850182613f44565b90506040830151848203604086015261458d8282613f44565b9150506060830151600481106145a5576145a5614526565b60608501526080830151600281106145bf576145bf614526565b8060808601525060a08301516145ed60a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015161460160c086018215159052565b509392505050565b602081526000612ae96020830184614555565b600080600080600080600060a0888a03121561463757600080fd5b873567ffffffffffffffff8082111561464f57600080fd5b61465b8b838c01613fa1565b909950975060208a013591508082111561467457600080fd5b506146818a828b01613fa1565b909650945050604088013561469581614281565b9250606088013561432781614281565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452614708858351614555565b945092850192908501906001016146ce565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261477d858351614392565b94509285019290850190600101614743565b803573ffffffffffffffffffffffffffffffffffffffff811681146141fe57600080fd5b6000602082840312156147c557600080fd5b612ae98261478f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff8281168282160390808211156107f2576107f26147fd565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361487a5761487a6147fd565b5060010190565b600181811c9082168061489557607f821691505b6020821081036148ce577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600063ffffffff8083168181036148ed576148ed6147fd565b6001019392505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261492b57600080fd5b9190910192915050565b60006040823603121561494757600080fd5b6040516040810167ffffffffffffffff828210818311171561496b5761496b613d3d565b816040526149788561478f565b8352602085013591508082111561498e57600080fd5b5061499b36828601613e4d565b60208301525092915050565b601f821115610697576000816000526020600020601f850160051c810160208610156149d05750805b601f850160051c820191505b818110156125b7578281556001016149dc565b815167ffffffffffffffff811115614a0957614a09613d3d565b614a1d81614a178454614881565b846149a7565b602080601f831160018114614a705760008415614a3a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556125b7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614abd57888601518255948401946001909101908401614a9e565b5085821015614af957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215614b1b57600080fd5b815167ffffffffffffffff811115614b3257600080fd5b8201601f81018413614b4357600080fd5b8051614b51613e6c82613e07565b818152856020838501011115614b6657600080fd5b61415f826020830160208601613f20565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183360301811261492b57600080fd5b600060808236031215614bbd57600080fd5b614bc5613d6c565b614bce836141ea565b81526020808401358183015260408401356040830152606084013567ffffffffffffffff80821115614bff57600080fd5b9085019036601f830112614c1257600080fd5b813581811115614c2457614c24613d3d565b8060051b9150614c35848301613db8565b8181529183018401918481019036841115614c4f57600080fd5b938501935b83851015614c6d57843582529385019390850190614c54565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614cb657835183529284019291840191600101614c9a565b50909695505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261492b57600080fd5b8035600281106141fe57600080fd5b600060a08236031215614d1757600080fd5b614d1f613d95565b823567ffffffffffffffff80821115614d3757600080fd5b614d4336838701613e4d565b83526020850135915080821115614d5957600080fd5b50614d6636828601613e4d565b602083015250604083013560048110614d7e57600080fd5b6040820152614d8f60608401614cf6565b6060820152614da06080840161478f565b608082015292915050565b6000602080835260008454614dbf81614881565b8060208701526040600180841660008114614de15760018114614e1b57614e4b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550614e4b565b89600052602060002060005b85811015614e425781548b8201860152908301908801614e27565b8a016040019650505b509398975050505050505050565b60ff8181168382160190811115610474576104746147fd565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614ea757600080fd5b83018035915067ffffffffffffffff821115614ec257600080fd5b60200191503681900382131561112157600080fd5b67ffffffffffffffff831115614eef57614eef613d3d565b614f0383614efd8354614881565b836149a7565b6000601f841160018114614f555760008515614f1f5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614feb565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015614fa45786850135825560209485019460019092019101614f84565b5086821015614fdf577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60006020828403121561500457600080fd5b8151612ae981614281565b81810381811115610474576104746147fd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6080815284608082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86111561508a57600080fd5b8560051b808860a0850137820182810360a090810160208501526150b090820187613f44565b91505063ffffffff8085166040840152808416606084015250969550505050505056fea164736f6c6343000818000a", } var CapabilitiesRegistryABI = CapabilitiesRegistryMetaData.ABI @@ -633,16 +633,16 @@ func (_CapabilitiesRegistry *CapabilitiesRegistryTransactorSession) TransferOwne return _CapabilitiesRegistry.Contract.TransferOwnership(&_CapabilitiesRegistry.TransactOpts, to) } -func (_CapabilitiesRegistry *CapabilitiesRegistryTransactor) UpdateDON(opts *bind.TransactOpts, donId uint32, nodes [][32]byte, capabilityConfigurations []CapabilitiesRegistryCapabilityConfiguration, isPublic bool, acceptsWorkflows bool, f uint8) (*types.Transaction, error) { - return _CapabilitiesRegistry.contract.Transact(opts, "updateDON", donId, nodes, capabilityConfigurations, isPublic, acceptsWorkflows, f) +func (_CapabilitiesRegistry *CapabilitiesRegistryTransactor) UpdateDON(opts *bind.TransactOpts, donId uint32, nodes [][32]byte, capabilityConfigurations []CapabilitiesRegistryCapabilityConfiguration, isPublic bool, f uint8) (*types.Transaction, error) { + return _CapabilitiesRegistry.contract.Transact(opts, "updateDON", donId, nodes, capabilityConfigurations, isPublic, f) } -func (_CapabilitiesRegistry *CapabilitiesRegistrySession) UpdateDON(donId uint32, nodes [][32]byte, capabilityConfigurations []CapabilitiesRegistryCapabilityConfiguration, isPublic bool, acceptsWorkflows bool, f uint8) (*types.Transaction, error) { - return _CapabilitiesRegistry.Contract.UpdateDON(&_CapabilitiesRegistry.TransactOpts, donId, nodes, capabilityConfigurations, isPublic, acceptsWorkflows, f) +func (_CapabilitiesRegistry *CapabilitiesRegistrySession) UpdateDON(donId uint32, nodes [][32]byte, capabilityConfigurations []CapabilitiesRegistryCapabilityConfiguration, isPublic bool, f uint8) (*types.Transaction, error) { + return _CapabilitiesRegistry.Contract.UpdateDON(&_CapabilitiesRegistry.TransactOpts, donId, nodes, capabilityConfigurations, isPublic, f) } -func (_CapabilitiesRegistry *CapabilitiesRegistryTransactorSession) UpdateDON(donId uint32, nodes [][32]byte, capabilityConfigurations []CapabilitiesRegistryCapabilityConfiguration, isPublic bool, acceptsWorkflows bool, f uint8) (*types.Transaction, error) { - return _CapabilitiesRegistry.Contract.UpdateDON(&_CapabilitiesRegistry.TransactOpts, donId, nodes, capabilityConfigurations, isPublic, acceptsWorkflows, f) +func (_CapabilitiesRegistry *CapabilitiesRegistryTransactorSession) UpdateDON(donId uint32, nodes [][32]byte, capabilityConfigurations []CapabilitiesRegistryCapabilityConfiguration, isPublic bool, f uint8) (*types.Transaction, error) { + return _CapabilitiesRegistry.Contract.UpdateDON(&_CapabilitiesRegistry.TransactOpts, donId, nodes, capabilityConfigurations, isPublic, f) } func (_CapabilitiesRegistry *CapabilitiesRegistryTransactor) UpdateNodeOperators(opts *bind.TransactOpts, nodeOperatorIds []uint32, nodeOperators []CapabilitiesRegistryNodeOperator) (*types.Transaction, error) { @@ -2214,7 +2214,7 @@ type CapabilitiesRegistryInterface interface { TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - UpdateDON(opts *bind.TransactOpts, donId uint32, nodes [][32]byte, capabilityConfigurations []CapabilitiesRegistryCapabilityConfiguration, isPublic bool, acceptsWorkflows bool, f uint8) (*types.Transaction, error) + UpdateDON(opts *bind.TransactOpts, donId uint32, nodes [][32]byte, capabilityConfigurations []CapabilitiesRegistryCapabilityConfiguration, isPublic bool, f uint8) (*types.Transaction, error) UpdateNodeOperators(opts *bind.TransactOpts, nodeOperatorIds []uint32, nodeOperators []CapabilitiesRegistryNodeOperator) (*types.Transaction, error) diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 5b2288e4fa..30396c12e7 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,5 +1,5 @@ GETH_VERSION: 1.13.8 -capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin bb794cc0042784b060d1d63090e2086670b88ba3685067cd436305f36054c82b +capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin 7e95d72f24940f08ada0ee3b85d894d6bfccfd6c8a3e0ceeff65bae52c899d54 feeds_consumer: ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin 8c3a2b18a80be41e7c40d2bc3a4c8d1b5e18d55c1fd20ad5af68cebb66109fc5 forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin 45d9b866c64b41c1349a90b6764aee42a6d078b454d38f369b5fe02b23b9d16e ocr3_capability: ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.bin 8bf0f53f222efce7143dea6134552eb26ea1eef845407b4475a0d79b7d7ba9f8 From 8d332fde7d3a5abe36c5e2c38d144018a5987786 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Wed, 14 Aug 2024 10:30:40 -0400 Subject: [PATCH 087/432] [CCIP-2944] Merge CCIP E2E Tests and CI into Core Repo (#14102) * [CCIP-2937] Copy ccip-tests and CI to Core (#14069) * gitignore * Fix gitignore * Adds CCIP Tests Dir * Adds CCIP CI * [CCIP-2937] Fixes Conflicts and Run Issues with CCIP E2E Tests Merge (#14070) * Fixes CI conflicts * Fixes config path * Separate CCIP smoke tests * Change repo for compatibility tests * Remove references to separate CCIP repo * Callout needed updates * Remove CCIP Upgrade Test --------- Co-authored-by: asoliman * Fixes * Go mod * Ports over fixes for CCIP network tests --------- Co-authored-by: asoliman --- .../action.yml | 187 + .github/workflows/ccip-chaos-tests.yml | 253 + .../ccip-client-compatibility-tests.yml | 743 +++ .github/workflows/ccip-live-network-tests.yml | 312 ++ .github/workflows/ccip-load-tests.yml | 289 ++ .github/workflows/chain-selectors-check.yml | 39 + .github/workflows/integration-tests.yml | 379 +- .gitignore | 2 + integration-tests/ccip-tests/Makefile | 70 + integration-tests/ccip-tests/README.md | 138 + .../ccip-tests/actions/ccip_helpers.go | 4380 +++++++++++++++++ .../ccip-tests/actions/ccip_helpers_test.go | 105 + .../ccip-tests/chaos/ccip_test.go | 153 + .../ccip-tests/contracts/contract_deployer.go | 1586 ++++++ .../ccip-tests/contracts/contract_models.go | 2247 +++++++++ .../contracts/laneconfig/contracts-1.2.json | 634 +++ .../contracts/laneconfig/contracts.json | 243 + .../contracts/laneconfig/parse_contracts.go | 227 + .../ccip-tests/contracts/multicall.go | 280 ++ .../ccip-tests/load/ccip_loadgen.go | 363 ++ .../ccip-tests/load/ccip_multicall_loadgen.go | 271 + .../ccip-tests/load/ccip_test.go | 331 ++ integration-tests/ccip-tests/load/helper.go | 483 ++ .../ccip-tests/smoke/ccip_test.go | 1008 ++++ .../ccip-tests/testconfig/README.md | 700 +++ .../ccip-tests/testconfig/ccip.go | 416 ++ .../examples/network_config.toml.example | 168 + .../testconfig/examples/override.toml.example | 119 + .../testconfig/examples/secrets.toml.example | 52 + .../ccip-tests/testconfig/global.go | 457 ++ .../override/mainnet-secondary.toml | 712 +++ .../testconfig/override/mainnet.toml | 767 +++ .../testconfig/tomls/ccip-crib.toml | 96 + .../testconfig/tomls/ccip-default.toml | 440 ++ .../tomls/ccip1.4-stress/baseline.toml | 189 + .../tomls/ccip1.4-stress/prod-testnet.toml | 964 ++++ .../ccip1.4-stress/sample-scalability.toml | 129 + .../tomls/ccip1.4-stress/tier-a.toml | 240 + .../tomls/ccip1.4-stress/tier-b.toml | 0 .../testconfig/tomls/contract-version1.4.toml | 13 + .../testconfig/tomls/db-compatibility.toml | 34 + .../testconfig/tomls/leader-lane.toml | 4 + .../tomls/load-with-arm-curse-uncurse.toml | 20 + .../node-post-upgrade-compatibility.toml | 45 + .../tomls/node-pre-upgrade-compatibility.toml | 13 + .../tomls/usdc_mock_deployment.toml | 10 + .../tomls/varied-block-time-sample.toml | 47 + .../ccip-tests/testreporters/ccip.go | 476 ++ .../ccip-tests/testsetups/ccip.go | 1436 ++++++ .../ccip-tests/testsetups/test_env.go | 594 +++ .../ccip-tests/types/config/node/core.go | 67 + integration-tests/ccip-tests/utils/common.go | 32 + .../ccip-tests/utils/fileutil.go | 63 + integration-tests/go.mod | 18 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 57 files changed, 23038 insertions(+), 16 deletions(-) create mode 100644 .github/actions/setup-create-base64-config-ccip/action.yml create mode 100644 .github/workflows/ccip-chaos-tests.yml create mode 100644 .github/workflows/ccip-client-compatibility-tests.yml create mode 100644 .github/workflows/ccip-live-network-tests.yml create mode 100644 .github/workflows/ccip-load-tests.yml create mode 100644 .github/workflows/chain-selectors-check.yml create mode 100644 integration-tests/ccip-tests/Makefile create mode 100644 integration-tests/ccip-tests/README.md create mode 100644 integration-tests/ccip-tests/actions/ccip_helpers.go create mode 100644 integration-tests/ccip-tests/actions/ccip_helpers_test.go create mode 100644 integration-tests/ccip-tests/chaos/ccip_test.go create mode 100644 integration-tests/ccip-tests/contracts/contract_deployer.go create mode 100644 integration-tests/ccip-tests/contracts/contract_models.go create mode 100644 integration-tests/ccip-tests/contracts/laneconfig/contracts-1.2.json create mode 100644 integration-tests/ccip-tests/contracts/laneconfig/contracts.json create mode 100644 integration-tests/ccip-tests/contracts/laneconfig/parse_contracts.go create mode 100644 integration-tests/ccip-tests/contracts/multicall.go create mode 100644 integration-tests/ccip-tests/load/ccip_loadgen.go create mode 100644 integration-tests/ccip-tests/load/ccip_multicall_loadgen.go create mode 100644 integration-tests/ccip-tests/load/ccip_test.go create mode 100644 integration-tests/ccip-tests/load/helper.go create mode 100644 integration-tests/ccip-tests/smoke/ccip_test.go create mode 100644 integration-tests/ccip-tests/testconfig/README.md create mode 100644 integration-tests/ccip-tests/testconfig/ccip.go create mode 100644 integration-tests/ccip-tests/testconfig/examples/network_config.toml.example create mode 100644 integration-tests/ccip-tests/testconfig/examples/override.toml.example create mode 100644 integration-tests/ccip-tests/testconfig/examples/secrets.toml.example create mode 100644 integration-tests/ccip-tests/testconfig/global.go create mode 100644 integration-tests/ccip-tests/testconfig/override/mainnet-secondary.toml create mode 100644 integration-tests/ccip-tests/testconfig/override/mainnet.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/ccip-crib.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/baseline.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/prod-testnet.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/sample-scalability.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/tier-a.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/tier-b.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/contract-version1.4.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/db-compatibility.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/leader-lane.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/load-with-arm-curse-uncurse.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/node-post-upgrade-compatibility.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/node-pre-upgrade-compatibility.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/usdc_mock_deployment.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/varied-block-time-sample.toml create mode 100644 integration-tests/ccip-tests/testreporters/ccip.go create mode 100644 integration-tests/ccip-tests/testsetups/ccip.go create mode 100644 integration-tests/ccip-tests/testsetups/test_env.go create mode 100644 integration-tests/ccip-tests/types/config/node/core.go create mode 100644 integration-tests/ccip-tests/utils/common.go create mode 100644 integration-tests/ccip-tests/utils/fileutil.go diff --git a/.github/actions/setup-create-base64-config-ccip/action.yml b/.github/actions/setup-create-base64-config-ccip/action.yml new file mode 100644 index 0000000000..88d9fe8078 --- /dev/null +++ b/.github/actions/setup-create-base64-config-ccip/action.yml @@ -0,0 +1,187 @@ +name: Create Base64 Config for CCIP Tests +description: A composite action that creates a base64-encoded config to be used by ccip integration tests + +inputs: + runId: + description: The run id + existingNamespace: + description: If test needs to run against already deployed namespace + testLogCollect: + description: Whether to always collect logs, even for passing tests + default: "false" + selectedNetworks: + description: The networks to run tests against + chainlinkImage: + description: The chainlink image to use + default: "public.ecr.aws/chainlink/chainlink" + chainlinkVersion: + description: The git commit sha to use for the image tag + upgradeImage: + description: The chainlink image to upgrade to + default: "" + upgradeVersion: + description: The git commit sha to use for the image tag + lokiEndpoint: + description: Loki push endpoint + lokiTenantId: + description: Loki tenant id + lokiBasicAuth: + description: Loki basic auth + logstreamLogTargets: + description: Where to send logs (e.g. file, loki) + grafanaUrl: + description: Grafana URL + grafanaDashboardUrl: + description: Grafana dashboard URL + grafanaBearerToken: + description: Grafana bearer token + customEvmNodes: + description: Custom EVM nodes to use in key=value format, where key is chain id and value is docker image to use. If they are provided the number of networksSelected must be equal to the number of customEvmNodes + evmNodeLogLevel: + description: Log level for the custom EVM nodes + default: "info" + +runs: + using: composite + steps: + - name: Prepare Base64 TOML override + shell: bash + id: base64-config-override + env: + RUN_ID: ${{ inputs.runId }} + SELECTED_NETWORKS: ${{ inputs.selectedNetworks }} + EXISTING_NAMESPACE: ${{ inputs.existingNamespace }} + TEST_LOG_COLLECT: ${{ inputs.testLogCollect }} + CHAINLINK_IMAGE: ${{ inputs.chainlinkImage }} + CHAINLINK_VERSION: ${{ inputs.chainlinkVersion }} + UPGRADE_IMAGE: ${{ inputs.upgradeImage }} + UPGRADE_VERSION: ${{ inputs.upgradeVersion }} + LOKI_ENDPOINT: ${{ inputs.lokiEndpoint }} + LOKI_TENANT_ID: ${{ inputs.lokiTenantId }} + LOKI_BASIC_AUTH: ${{ inputs.lokiBasicAuth }} + LOGSTREAM_LOG_TARGETS: ${{ inputs.logstreamLogTargets }} + GRAFANA_URL: ${{ inputs.grafanaUrl }} + GRAFANA_DASHBOARD_URL: ${{ inputs.grafanaDashboardUrl }} + GRAFANA_BEARER_TOKEN: ${{ inputs.grafanaBearerToken }} + CUSTOM_EVM_NODES: ${{ inputs.customEvmNodes }} + EVM_NODE_LOG_LEVEL: ${{ inputs.evmNodeLogLevel }} + run: | + echo ::add-mask::$CHAINLINK_IMAGE + function convert_to_toml_array() { + local IFS=',' + local input_array=($1) + local toml_array_format="[" + + for element in "${input_array[@]}"; do + toml_array_format+="\"$element\"," + done + + toml_array_format="${toml_array_format%,}]" + echo "$toml_array_format" + } + + selected_networks=$(convert_to_toml_array "$SELECTED_NETWORKS") + log_targets=$(convert_to_toml_array "$LOGSTREAM_LOG_TARGETS") + + if [ -n "$TEST_LOG_COLLECT" ]; then + test_log_collect=true + else + test_log_collect=false + fi + + # make sure the number of networks and nodes match + IFS=',' read -r -a networks_array <<< "$SELECTED_NETWORKS" + IFS=',' read -r -a nodes_array <<< "$CUSTOM_EVM_NODES" + + networks_count=${#networks_array[@]} + nodes_count=${#nodes_array[@]} + + # Initialize or clear CONFIG_TOML environment variable + custom_nodes_toml="" + + # Check if the number of CUSTOM_EVM_NODES is zero + if [ $nodes_count -eq 0 ]; then + echo "The number of CUSTOM_EVM_NODES is zero, won't output any custom private Ethereum network configurations." + else + if [ $networks_count -ne $nodes_count ]; then + echo "The number of elements in SELECTED_NETWORKS (${networks_count}) and CUSTOM_EVM_NODES does not match (${nodes_count})." + exit 1 + else + for i in "${!networks_array[@]}"; do + IFS='=' read -r chain_id docker_image <<< "${nodes_array[i]}" + custom_nodes_toml+=" + [CCIP.Env.PrivateEthereumNetworks.${networks_array[i]}] + ethereum_version=\"\" + execution_layer=\"\" + + [CCIP.Env.PrivateEthereumNetworks.${networks_array[i]}.EthereumChainConfig] + seconds_per_slot=3 + slots_per_epoch=2 + genesis_delay=15 + validator_count=4 + chain_id=${chain_id} + addresses_to_fund=[\"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266\", \"0x70997970C51812dc3A010C7d01b50e0d17dc79C8\"] + node_log_level=\"${EVM_NODES_LOG_LEVEL}\" + + [CCIP.Env.PrivateEthereumNetworks.${networks_array[i]}.EthereumChainConfig.HardForkEpochs] + Deneb=500 + + [CCIP.Env.PrivateEthereumNetworks.${networks_array[i]}.CustomDockerImages] + execution_layer=\"${docker_image}\" + " + done + fi + fi + + grafana_bearer_token="" + if [ -n "$GRAFANA_BEARER_TOKEN" ]; then + grafana_bearer_token="bearer_token_secret=\"$GRAFANA_BEARER_TOKEN\"" + fi + + cat << EOF > config.toml + [CCIP] + [CCIP.Env] + EnvToConnect="$EXISTING_NAMESPACE" + [CCIP.Env.Network] + selected_networks = $selected_networks + [CCIP.Env.NewCLCluster] + [CCIP.Env.NewCLCluster.Common] + [CCIP.Env.NewCLCluster.Common.ChainlinkImage] + image="$CHAINLINK_IMAGE" + version="$CHAINLINK_VERSION" + + [CCIP.Env.NewCLCluster.Common.ChainlinkUpgradeImage] + image="$UPGRADE_IMAGE" + version="$UPGRADE_VERSION" + + $custom_nodes_toml + + [CCIP.Env.Logging] + test_log_collect=$test_log_collect + run_id="$RUN_ID" + + [CCIP.Env.Logging.LogStream] + log_targets=$log_targets + + [CCIP.Env.Logging.Loki] + tenant_id="$LOKI_TENANT_ID" + endpoint="$LOKI_ENDPOINT" + basic_auth_secret="$LOKI_BASIC_AUTH" + + [CCIP.Env.Logging.Grafana] + base_url="$GRAFANA_URL" + dashboard_url="$GRAFANA_DASHBOARD_URL" + $grafana_bearer_token + + [CCIP.Groups.load] + TestRunName = '$EXISTING_NAMESPACE' + + [CCIP.Groups.smoke] + TestRunName = '$EXISTING_NAMESPACE' + + EOF + + BASE64_CCIP_SECRETS_CONFIG=$(cat config.toml | base64 -w 0) + echo ::add-mask::$BASE64_CCIP_SECRETS_CONFIG + echo "BASE64_CCIP_SECRETS_CONFIG=$BASE64_CCIP_SECRETS_CONFIG" >> $GITHUB_ENV + echo "TEST_BASE64_CCIP_SECRETS_CONFIG=$BASE64_CCIP_SECRETS_CONFIG" >> $GITHUB_ENV diff --git a/.github/workflows/ccip-chaos-tests.yml b/.github/workflows/ccip-chaos-tests.yml new file mode 100644 index 0000000000..493322ae42 --- /dev/null +++ b/.github/workflows/ccip-chaos-tests.yml @@ -0,0 +1,253 @@ +name: CCIP Chaos Tests +on: + workflow_run: + workflows: [ CCIP Load Test ] + types: [ completed ] + branches: [ develop ] + workflow_dispatch: + + + +# Only run 1 of this workflow at a time per PR +concurrency: + group: chaos-ccip-tests-chainlink-${{ github.ref }} + cancel-in-progress: true + +env: + # TODO: TT-1470 - Update image names as we solidify new realease strategy + CL_ECR: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests:${{ github.sha }} + MOD_CACHE_VERSION: 1 + +jobs: + build-chainlink: + environment: integration + permissions: + id-token: write + contents: read + name: Build Chainlink Image + runs-on: ubuntu20.04-16cores-64GB + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - name: Check if image exists + id: check-image + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 + with: + repository: chainlink + tag: ${{ github.sha }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + - name: Build Image + if: steps.check-image.outputs.exists == 'false' + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 + env: + GH_TOKEN: ${{ github.token }} + with: + cl_repo: smartcontractkit/chainlink + cl_ref: ${{ github.sha }} + push_tag: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:${{ github.sha }} + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + - name: Collect Metrics + if: always() + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: ccip-chaos-tests-build-chainlink-image + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Build Chainlink Image + continue-on-error: true + + build-test-image: + environment: integration + permissions: + id-token: write + contents: read + name: Build Test Image + runs-on: ubuntu20.04-16cores-64GB + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: ccip-chaos-tests-build-test-image + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Build Test Image + continue-on-error: true + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - name: Build Test Image + uses: ./.github/actions/build-test-image + with: + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + + ccip-chaos-tests: + environment: integration + permissions: + issues: read + checks: write + pull-requests: write + id-token: write + contents: read + name: CCIP Chaos Tests + runs-on: ubuntu-latest + needs: [ build-chainlink, build-test-image ] + env: + TEST_SUITE: chaos + TEST_ARGS: -test.timeout 30m + CHAINLINK_COMMIT_SHA: ${{ github.sha }} + CHAINLINK_ENV_USER: ${{ github.actor }} + TEST_TRIGGERED_BY: ccip-cron-chaos-eth + TEST_LOG_LEVEL: debug + DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable + GH_TOKEN: ${{ github.token }} + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: ccip-chaos-tests + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: CCIP Chaos Tests + test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' + continue-on-error: true + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - name: Prepare Base64 TOML override for CCIP secrets + uses: ./.github/actions/setup-create-base64-config-ccip + with: + runId: ${{ github.run_id }} + testLogCollect: ${{ vars.TEST_LOG_COLLECT }} + chainlinkImage: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + chainlinkVersion: ${{ github.sha }} + lokiEndpoint: ${{ secrets.LOKI_URL }} + lokiTenantId: ${{ vars.LOKI_TENANT_ID }} + logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + grafanaUrl: ${{ vars.GRAFANA_URL }} + grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + - name: Run Chaos Tests + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 + with: + test_command_to_run: cd ./integration-tests && go test -timeout 1h -count=1 -json -test.parallel 11 -run 'TestChaosCCIP' ./chaos 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci + test_download_vendor_packages_command: make gomod + cl_repo: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + cl_image_tag: ${{ github.sha }} + artifacts_location: ./integration-tests/chaos/logs + publish_check_name: CCIP Chaos Test Results + publish_report_paths: ./tests-chaos-report.xml + triggered_by: ${{ env.TEST_TRIGGERED_BY }} + token: ${{ secrets.GITHUB_TOKEN }} + go_mod_path: ./integration-tests/go.mod + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + CGO_ENABLED: "1" + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + cache_key_id: ccip-load-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: "true" + ## Notify in slack if the job fails + - name: Notify Slack + if: failure() && github.event_name != 'workflow_dispatch' + uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 + env: + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + with: + channel-id: "#ccip-testing" + slack-message: ":x: :mild-panic-intensifies: CCIP chaos tests failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}" + ## Run Cleanup if the job succeeds + - name: cleanup + if: always() + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/cleanup@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 + with: + triggered_by: ${{ env.TEST_TRIGGERED_BY }} + + ccip-chaos-with-load-tests: + environment: integration + permissions: + issues: read + checks: write + pull-requests: write + id-token: write + contents: read + name: CCIP Load With Chaos Tests + if: false # Disabled until CCIP-2555 is resolved + runs-on: ubuntu-latest + needs: [ build-chainlink, build-test-image ] + env: + TEST_SUITE: load + TEST_ARGS: -test.timeout 1h + CHAINLINK_COMMIT_SHA: ${{ github.sha }} + CHAINLINK_ENV_USER: ${{ github.actor }} + TEST_TRIGGERED_BY: ccip-cron-chaos-and-load-eth + TEST_LOG_LEVEL: debug + DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable + GH_TOKEN: ${{ github.token }} + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: ccip-chaos-tests-with-load-test + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: CCIP load with chaos test + continue-on-error: true + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - name: Prepare Base64 TOML override for CCIP secrests + uses: ./.github/actions/setup-create-base64-config-ccip + with: + runId: ${{ github.run_id }} + testLogCollect: ${{ vars.TEST_LOG_COLLECT }} + chainlinkImage: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + chainlinkVersion: ${{ github.sha }} + lokiEndpoint: ${{ secrets.LOKI_URL }} + lokiTenantId: ${{ vars.LOKI_TENANT_ID }} + logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + grafanaUrl: ${{ vars.GRAFANA_URL }} + grafanaDashboardUrl: "/d/6vjVx-1V8/ccip-long-running-tests" + - name: Run Load With Chaos Tests + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 + with: + test_command_to_run: cd ./integration-tests/ccip-tests && go test -timeout 2h -count=1 -json -test.parallel 4 -run '^TestLoadCCIPStableWithPodChaosDiffCommitAndExec' ./load 2>&1 | tee /tmp/gotest.log | gotestfmt + test_download_vendor_packages_command: make gomod + cl_repo: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + cl_image_tag: ${{ github.sha }} + artifacts_location: ./integration-tests/load/logs + publish_check_name: CCIP Chaos With Load Test Results + publish_report_paths: ./tests-chaos-with-load-report.xml + triggered_by: ${{ env.TEST_TRIGGERED_BY }} + token: ${{ secrets.GITHUB_TOKEN }} + go_mod_path: ./integration-tests/go.mod + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + CGO_ENABLED: "1" + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + cache_key_id: ccip-load-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: "true" + ## Notify in slack if the job fails + - name: Notify Slack + if: failure() && github.event_name != 'workflow_dispatch' + uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 + env: + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + with: + channel-id: "#ccip-testing" + slack-message: ":x: :mild-panic-intensifies: CCIP chaos with load tests failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}" + ## Run Cleanup if the job succeeds + - name: cleanup + if: always() + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/cleanup@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 + with: + triggered_by: ${{ env.TEST_TRIGGERED_BY }} diff --git a/.github/workflows/ccip-client-compatibility-tests.yml b/.github/workflows/ccip-client-compatibility-tests.yml new file mode 100644 index 0000000000..ff0e4be25c --- /dev/null +++ b/.github/workflows/ccip-client-compatibility-tests.yml @@ -0,0 +1,743 @@ +name: CCIP Client Compatibility Tests +on: + schedule: + - cron: "30 5 * * TUE,FRI" # Run every Tuesday and Friday at midnight + 30min EST + push: + tags: + - "*" + merge_group: + pull_request: + workflow_dispatch: + inputs: + chainlinkVersion: + description: commit SHA or tag of the Chainlink version to test + required: true + type: string + evmImplementations: + description: comma separated list of EVM implementations to test (ignored if base64TestList is used) + required: true + type: string + default: "geth,besu,nethermind,erigon" + latestVersionsNumber: + description: how many of latest images of EVM implementations to test with (ignored if base64TestList is used) + required: true + type: number + default: 3 + base64TestList: + description: base64 encoded list of tests to run (same as base64-ed output of testlistgenerator tool) + required: false + type: string + +env: + # TODO: TT-1470 - Update image names as we solidify new realease strategy + CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/ccip + INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com + MOD_CACHE_VERSION: 2 + +jobs: + # Build Test Dependencies + + check-dependency-bump: + name: Check for go-ethereum dependency bump + if: github.event_name == 'pull_request' || github.event_name == 'merge_queue' + runs-on: ubuntu-latest + outputs: + dependency_changed: ${{ steps.changes.outputs.dependency_changed }} + steps: + - name: Checkout code + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + repository: smartcontractkit/chainlink + fetch-depth: 0 + - name: Check for go.mod changes + id: changes + run: | + git fetch origin ${{ github.base_ref }} + # if no match is found then grep exits with code 1, but if there is a match it exits with code 0 + # this will return a match if there are any changes on that corresponding line, for example if spacing was changed + DEPENDENCY_CHANGED=$(git diff -U0 origin/${{ github.base_ref }}...HEAD -- go.mod | grep -q 'github.com/ethereum/go-ethereum'; echo $?) + PR_VERSION=$(grep 'github.com/ethereum/go-ethereum' go.mod | awk '{print $2}') + + # here 0 means a match was found, 1 means no match was found + if [ "$DEPENDENCY_CHANGED" -eq 0 ]; then + # Dependency was changed in the PR, now compare with the base branch + git fetch origin ${{ github.base_ref }} + BASE_VERSION=$(git show origin/${{ github.base_ref }}:go.mod | grep 'github.com/ethereum/go-ethereum' | awk '{print $2}') + + echo "Base branch version: $BASE_VERSION" + echo "PR branch version: $PR_VERSION" + + echo "Dependency version changed in the PR compared to the base branch." + echo "dependency_changed=true" >> $GITHUB_OUTPUT + else + echo "No changes to ethereum/go-ethereum dependency in the PR." + echo "PR branch version: $PR_VERSION" + echo "dependency_changed=false" >> $GITHUB_OUTPUT + fi + + should-run: + if: always() + name: Check if the job should run + needs: check-dependency-bump + runs-on: ubuntu-latest + outputs: + should_run: ${{ steps.should-run.outputs.should_run }} + eth_implementations : ${{ steps.should-run.outputs.eth_implementations }} + env: + GITHUB_REF_TYPE: ${{ github.ref_type }} + steps: + - name: Check if the job should run + id: should-run + run: | + if [ "${{ needs.check-dependency-bump.outputs.dependency_changed }}" == "true" ]; then + echo "Will run tests, because go-ethereum dependency was bumped" + echo "should_run=true" >> $GITHUB_OUTPUT + elif [ "$GITHUB_EVENT_NAME" = "schedule" ]; then + echo "Will run tests, because trigger event was $GITHUB_EVENT_NAME" + echo "should_run=true" >> $GITHUB_OUTPUT + elif [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then + echo "Will run tests, because trigger event was $GITHUB_EVENT_NAME" + echo "should_run=true" >> $GITHUB_OUTPUT + elif [ "$GITHUB_REF_TYPE" = "tag" ]; then + echo "Will run tests, because new tag was created" + echo "should_run=true" >> $GITHUB_OUTPUT + else + echo "Will not run tests" + echo "should_run=false" >> $GITHUB_OUTPUT + fi + + select-versions: + if: always() && needs.should-run.outputs.should_run == 'true' + name: Select Versions + needs: should-run + runs-on: ubuntu-latest + env: + RELEASED_DAYS_AGO: 4 + GITHUB_REF_TYPE: ${{ github.ref_type }} + outputs: + evm_implementations : ${{ steps.select-implementations.outputs.evm_implementations }} + chainlink_version: ${{ steps.select-chainlink-version.outputs.chainlink_version }} + latest_image_count: ${{ steps.get-image-count.outputs.image_count }} + steps: + # ghlatestreleasechecker is a tool to check if new release is available for a given repo + - name: Set Up ghlatestreleasechecker + shell: bash + run: | + go install github.com/smartcontractkit/chainlink-testing-framework/tools/ghlatestreleasechecker@v1.0.0 + - name: Select EVM implementations to test + id: select-implementations + run: | + PATH=$PATH:$(go env GOPATH)/bin + export PATH + + if [ "$GITHUB_EVENT_NAME" = "schedule" ]; then + echo "Checking for new releases" + implementations_arr=() + new_geth=$(ghlatestreleasechecker "ethereum/go-ethereum" $RELEASED_DAYS_AGO) + if [ "$new_geth" != "none" ]; then + echo "New geth release found: $new_geth" + implementations_arr+=("geth") + fi + new_besu=$(ghlatestreleasechecker "hyperledger/besu" $RELEASED_DAYS_AGO) + if [ "new_besu" != "none" ]; then + echo "New besu release found: $new_besu" + implementations_arr+=("besu") + fi + new_erigon=$(ghlatestreleasechecker "ledgerwatch/erigon" $RELEASED_DAYS_AGO) + if [ "new_erigon" != "none" ]; then + echo "New erigon release found: $new_erigon" + implementations_arr+=("erigon") + fi + new_nethermind=$(ghlatestreleasechecker "nethermindEth/nethermind" $RELEASED_DAYS_AGO) + if [ "new_nethermind" != "none" ]; then + echo "New nethermind release found: $new_nethermind" + implementations_arr+=("nethermind") + fi + IFS=',' + eth_implementations="${implementations_arr[*]}" + echo "Found new releases for: $eth_implementations" + echo "evm_implementations=$eth_implementations" >> $GITHUB_OUTPUT + elif [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then + if [ -n "${{ github.event.inputs.base64TestList }}" ]; then + echo "Base64-ed Test Input provided, ignoring EVM implementations" + else + echo "Will test following EVM implementations: ${{ github.event.inputs.evmImplementations }}" + echo "evm_implementations=${{ github.event.inputs.evmImplementations }}" >> $GITHUB_OUTPUT + fi + else + echo "Will test all EVM implementations" + echo "evm_implementations=geth,besu,nethermind,erigon" >> $GITHUB_OUTPUT + fi + - name: Select Chainlink CCIP version + id: select-chainlink-version + run: | + PATH=$PATH:$(go env GOPATH)/bin + export PATH + + if [ "$GITHUB_EVENT_NAME" = "schedule" ]; then + echo "Fetching latest Chainlink CCIP stable version" + implementations_arr=() + # we use 100 days since we really want the latest one, and it's highly improbable there won't be a release in last 100 days + chainlink_version=$(ghlatestreleasechecker "smartcontractkit/ccip" 100) + echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT + elif [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then + echo "Fetching Chainlink version from input" + if [ -n "${{ github.event.inputs.chainlinkVersion }}" ]; then + echo "Chainlink version provided in input" + chainlink_version="${{ github.event.inputs.chainlinkVersion }}" + else + echo "Chainlink version not provided in input. Using latest commit SHA." + chainlink_version=${{ github.sha }} + fi + echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT + elif [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then + echo "Fetching Chainlink version from PR's head commit" + chainlink_version="${{ github.event.pull_request.head.sha }}" + echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT + elif [ "$GITHUB_EVENT_NAME" = "merge_queue" ]; then + echo "Fetching Chainlink version from merge queue's head commit" + chainlink_version="${{ github.event.merge_group.head_sha }}" + echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT + elif [ "$GITHUB_REF_TYPE" = "tag" ]; then + echo "Fetching Chainlink version from tag" + chainlink_version="${{ github.ref_name }}" + echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT + else + echo "Unsupported trigger event. It's probably an issue with the pipeline definition. Please reach out to the Test Tooling team." + exit 1 + fi + echo "Will use following Chainlink version: $chainlink_version" + - name: Get image count + id: get-image-count + run: | + if [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then + echo "Fetching latest image count from input" + if [ -n "${{ github.event.inputs.base64TestList }}" ]; then + echo "Base64-ed Test Input provided, ignoring latest image count" + else + image_count="${{ github.event.inputs.latestVersionsNumber }}" + echo "image_count=$image_count" >> $GITHUB_OUTPUT + fi + else + echo "Fetching default latest image count" + image_count=3 + echo "image_count=$image_count" >> $GITHUB_OUTPUT + fi + echo "Will use following latest image count: $image_count" + + check-ecr-images-exist: + name: Check images used as test dependencies exist in ECR + if: always() && needs.should-run.outputs.should_run == 'true' + environment: integration + permissions: + id-token: write + contents: read + needs: [should-run] + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + mirror: + - name: ethereum/client-go + expression: '^(alltools-v|v)[0-9]\.[0-9]+\.[0-9]+$' + - name: hyperledger/besu + expression: '^[0-9]+\.[0-9]+(\.[0-9]+)?$' + page_size: 300 + - name: thorax/erigon + expression: '^v[0-9]+\.[0-9]+\.[0-9]+$' + - name: nethermind/nethermind + expression: '^[0-9]+\.[0-9]+\.[0-9]+$' + - name: tofelb/ethereum-genesis-generator + expression: '^[0-9]+\.[0-9]+\.[0-9]+(\-slots\-per\-epoch)?' + steps: + - name: Update internal ECR if the latest Ethereum client image does not exist + uses: smartcontractkit/chainlink-testing-framework/.github/actions/update-internal-mirrors@5eea86ee4f7742b4e944561a570a6b268e712d9e # v1.30.3 + with: + aws_region: ${{ secrets.QA_AWS_REGION }} + role_to_assume: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + aws_account_number: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + image_name: ${{matrix.mirror.name}} + expression: ${{matrix.mirror.expression}} + page_size: ${{matrix.mirror.page_size}} + + build-chainlink: + if: always() && needs.should-run.outputs.should_run == 'true' + environment: integration + permissions: + id-token: write + contents: read + name: Build Chainlink Image + needs: [should-run, select-versions] + runs-on: ubuntu-latest + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: client-compatablility-build-chainlink + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Build Chainlink Image + continue-on-error: true + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + repository: smartcontractkit/chainlink + ref: ${{ needs.select-versions.outputs.chainlink_version }} + - name: Build Chainlink Image + uses: ./.github/actions/build-chainlink-image + with: + tag_suffix: "" + dockerfile: core/chainlink.Dockerfile + git_commit_sha: ${{ needs.select-versions.outputs.chainlink_version }} + check_image_exists: 'true' + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + + get-latest-available-images: + name: Get Latest EVM Implementation's Images + if: always() && needs.should-run.outputs.should_run == 'true' + environment: integration + runs-on: ubuntu-latest + needs: [check-ecr-images-exist, should-run, select-versions] + permissions: + id-token: write + contents: read + env: + LATEST_IMAGE_COUNT: ${{ needs.select-versions.outputs.latest_image_count }} + outputs: + geth_images: ${{ env.GETH_IMAGES }} + nethermind_images: ${{ env.NETHERMIND_IMAGES }} + besu_images: ${{ env.BESU_IMAGES }} + erigon_images: ${{ env.ERIGON_IMAGES }} + steps: + # Setup AWS creds + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + with: + aws-region: ${{ secrets.QA_AWS_REGION }} + role-to-assume: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + role-duration-seconds: 3600 + # Login to ECR + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@062b18b96a7aff071d4dc91bc00c4c1a7945b076 # v2.0.1 + with: + mask-password: "true" + env: + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + # ecrimagefetcher is a tool to get latest images from ECR + - name: Set Up ecrimagefetcher + shell: bash + run: | + go install github.com/smartcontractkit/chainlink-testing-framework/tools/ecrimagefetcher@v1.0.1 + - name: Get latest docker images from ECR + if: ${{ github.event.inputs.base64TestList == '' }} + env: + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + ETH_IMPLEMENTATIONS: ${{ needs.select-versions.outputs.evm_implementations }} + run: | + PATH=$PATH:$(go env GOPATH)/bin + export PATH + if [[ "$ETH_IMPLEMENTATIONS" == *"geth"* ]]; then + geth_images=$(ecrimagefetcher 'ethereum/client-go' '^v[0-9]+\.[0-9]+\.[0-9]+$' ${{ env.LATEST_IMAGE_COUNT }}) + echo "GETH_IMAGES=$geth_images" >> $GITHUB_ENV + echo "Geth latest images: $geth_images" + fi + + if [[ "$ETH_IMPLEMENTATIONS" == *"nethermind"* ]]; then + nethermind_images=$(ecrimagefetcher 'nethermind/nethermind' '^[0-9]+\.[0-9]+\.[0-9]+$' ${{ env.LATEST_IMAGE_COUNT }}) + echo "NETHERMIND_IMAGES=$nethermind_images" >> $GITHUB_ENV + echo "Nethermind latest images: $nethermind_images" + fi + + if [[ "$ETH_IMPLEMENTATIONS" == *"besu"* ]]; then + # 24.3.3 is ignored as it doesn't support data & input fields in eth_call + besu_images=$(ecrimagefetcher 'hyperledger/besu' '^[0-9]+\.[0-9]+(\.[0-9]+)?$' ${{ env.LATEST_IMAGE_COUNT }} ">=24.5.1") + echo "BESU_IMAGES=$besu_images" >> $GITHUB_ENV + echo "Besu latest images: $besu_images" + fi + + if [[ "$ETH_IMPLEMENTATIONS" == *"erigon"* ]]; then + # 2.60.0 and 2.60.1 are ignored as they stopped working with CL node + erigon_images=$(ecrimagefetcher 'thorax/erigon' '^v[0-9]+\.[0-9]+\.[0-9]+$' ${{ env.LATEST_IMAGE_COUNT }} "> $GITHUB_ENV + echo "Erigon latest images: $erigon_images" + fi + + # End Build Test Dependencies + + prepare-compatibility-matrix: + name: Prepare Compatibility Matrix + if: always() && needs.should-run.outputs.should_run == 'true' + environment: integration + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + needs: [get-latest-available-images,should-run,select-versions] + runs-on: ubuntu-latest + env: + ETH_IMPLEMENTATIONS: ${{ needs.select-versions.outputs.evm_implementations }} + BASE64_TEST_LIST: ${{ github.event.inputs.base64TestList }} + outputs: + matrix: ${{ env.JOB_MATRIX_JSON }} + steps: + - name: Decode Base64 Test List Input if Set + if: env.BASE64_TEST_LIST != '' + run: | + echo "Decoding base64 tests list from the input" + DECODED_BASE64_TEST_LIST=$(echo $BASE64_TEST_LIST | base64 -d) + echo "Decoded input:" + echo "$DECODED_BASE64_TEST_LIST" + is_valid=$(echo "$DECODED_BASE64_TEST_LIST" | jq . > /dev/null 2>&1; echo $?) + if [ "$is_valid" -ne 0 ]; then + echo "Invalid base64 input. Please provide a valid base64 encoded JSON list of tests." + echo "Here is an example of valid JSON:" + cat <> $GITHUB_ENV + # testlistgenerator is a tool that builds a matrix of tests to run + - name: Set Up testlistgenerator + if: env.BASE64_TEST_LIST == '' + shell: bash + run: | + go install github.com/smartcontractkit/chainlink-testing-framework/tools/testlistgenerator@v1.1.0 + - name: Prepare matrix input + if: env.BASE64_TEST_LIST == '' + run: | + PATH=$PATH:$(go env GOPATH)/bin + export PATH + + if [[ "$ETH_IMPLEMENTATIONS" == *"geth"* ]]; then + echo "Will test compatibility with geth" + testlistgenerator -o compatibility_test_list.json -p ccip -r TestSmokeCCIPForBidirectionalLane -f './ccip-tests/smoke/ccip_test.go' -e geth -d "${{ needs.get-latest-available-images.outputs.geth_images }}" -t "ccip-geth-compatibility-test" -w "SIMULATED_1,SIMULATED_2" -c 1337,2337 -n ubuntu-latest + else + echo "Will not test compatibility with geth" + fi + + if [[ "$ETH_IMPLEMENTATIONS" == *"besu"* ]]; then + echo "Will test compatibility with besu" + testlistgenerator -o compatibility_test_list.json -p ccip -r TestSmokeCCIPForBidirectionalLane -f './ccip-tests/smoke/ccip_test.go' -e besu -d "${{ needs.get-latest-available-images.outputs.besu_images }}" -t "ccip-besu-compatibility-test" -w "SIMULATED_BESU_NONDEV_1,SIMULATED_BESU_NONDEV_2" -c 1337,2337 -n ubuntu-latest + else + echo "Will not test compatibility with besu" + fi + + # TODO: Waiting for CCIP-2255 to be resolved + if [[ "$ETH_IMPLEMENTATIONS" == *"erigon"* ]]; then + echo "Will test compatibility with erigon" + testlistgenerator -o compatibility_test_list.json -p ccip -r TestSmokeCCIPForBidirectionalLane -f './ccip-tests/smoke/ccip_test.go' -e erigon -d "${{ needs.get-latest-available-images.outputs.erigon_images }}" -t "ccip-erigon-compatibility-test" -w "SIMULATED_1,SIMULATED_2" -c 1337,2337 -n ubuntu-latest + else + echo "Will not test compatibility with erigon" + fi + + # TODO: uncomment when nethermind flake reason is addressed + if [[ "$ETH_IMPLEMENTATIONS" == *"nethermind"* ]]; then + echo "Will not test compatibility with nethermind due to flakiness" + # echo "Will test compatibility with nethermind" + # testlistgenerator -o compatibility_test_list.json -p ccip -r TestSmokeCCIPForBidirectionalLane -f './ccip-tests/smoke/ccip_test.go' -e nethermind -d "${{ needs.get-latest-available-images.outputs.nethermind_images }}" -t "ccip-nethermind-compatibility-test" -w "SIMULATED_1,SIMULATED_2" -c 1337,2337 -n ubuntu-latest + else + echo "Will not test compatibility with nethermind" + fi + + jq . compatibility_test_list.json + echo "Adding human-readable name" + jq 'map(. + {visible_name: (.docker_image | split(",")[0] | split("=")[1])})' compatibility_test_list.json > compatibility_test_list_modified.json + jq . compatibility_test_list_modified.json + JOB_MATRIX_JSON=$(jq -c . compatibility_test_list_modified.json) + echo "JOB_MATRIX_JSON=${JOB_MATRIX_JSON}" >> $GITHUB_ENV + + run-client-compatibility-matrix: + name: CCIP Compatibility with ${{ matrix.evm_node.visible_name }} + if: always() && needs.should-run.outputs.should_run == 'true' + environment: integration + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + needs: [build-chainlink, prepare-compatibility-matrix, should-run, select-versions] + env: + CHAINLINK_COMMIT_SHA: ${{ needs.select-versions.outputs.chainlink_version }} + CHAINLINK_ENV_USER: ${{ github.actor }} + TEST_LOG_LEVEL: debug + strategy: + fail-fast: false + matrix: + evm_node: ${{fromJson(needs.prepare-compatibility-matrix.outputs.matrix)}} + runs-on: ubuntu-latest + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + repository: smartcontractkit/chainlink + ref: ${{ needs.select-versions.outputs.chainlink_version }} + - name: Prepare Base64 TOML override + uses: ./.github/actions/setup-create-base64-config + with: + runId: ${{ github.run_id }} + testLogCollect: ${{ vars.TEST_LOG_COLLECT }} + selectedNetworks: ${{ matrix.evm_node.networks }} + chainlinkImage: ${{ env.CHAINLINK_IMAGE }} + chainlinkVersion: ${{ needs.select-versions.outputs.chainlink_version }} + pyroscopeServer: ${{ !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 + pyroscopeEnvironment: ci-ccip-bidirectional-lane-${{ matrix.evm_node.name }} + pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} + lokiEndpoint: ${{ secrets.LOKI_URL_CI }} + lokiTenantId: ${{ vars.LOKI_TENANT_ID }} + lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} + logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + grafanaUrl: ${{ vars.GRAFANA_URL }} + grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + - name: Prepare Base64 TOML override for CCIP secrets + uses: ./.github/actions/setup-create-base64-config-ccip + with: + runId: ${{ github.run_id }} + testLogCollect: ${{ vars.TEST_LOG_COLLECT }} + selectedNetworks: ${{ matrix.evm_node.networks }} + chainlinkImage: ${{ env.CHAINLINK_IMAGE }} + chainlinkVersion: ${{ needs.select-versions.outputs.chainlink_version }} + lokiEndpoint: ${{ secrets.LOKI_URL_CI }} + lokiTenantId: ${{ vars.LOKI_TENANT_ID }} + lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} + logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + grafanaUrl: ${{ vars.GRAFANA_URL }} + grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + customEvmNodes: ${{ matrix.evm_node.docker_image }} + evmNodeLogLevel: "trace" + - name: Prepare test log name + run: | + replace_special_chars() { + if [ -z "$1" ]; then + echo "Please provide a string as an argument." + return 1 + fi + + local input_string="$1" + + # Replace '/' with '-' + local modified_string="${input_string//\//-}" + + # Replace ':' with '-' + modified_string="${modified_string//:/-}" + + # Replace '.' with '-' + modified_string="${modified_string//./-}" + + echo "$modified_string" + } + echo "TEST_LOG_NAME=$(replace_special_chars "ccip-${{ matrix.evm_node.name }}-test-logs")" >> $GITHUB_ENV + - name: Print Test details - ${{ matrix.evm_node.docker_image }} + run: | + echo "EVM Implementation Docker Image: ${{ matrix.evm_node.docker_image }}" + echo "EVM Implementation Networks: ${{ matrix.evm_node.networks }}" + echo "Test identifier: ${{ matrix.evm_node.name }}" + - name: Run Tests + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@fc3e0df622521019f50d772726d6bf8dc919dd38 # v2.3.19 + with: + test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=2 ${{ matrix.evm_node.run }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci + test_download_vendor_packages_command: cd ./integration-tests && go mod download + cl_repo: ${{ env.CHAINLINK_IMAGE }} + cl_image_tag: ${{ needs.select-versions.outputs.chainlink_version }} + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + artifacts_name: ${{ env.TEST_LOG_NAME }} + artifacts_location: | + ./integration-tests/smoke/logs/ + ./integration-tests/ccip-tests/smoke/logs/* + /tmp/gotest.log + publish_check_name: ${{ matrix.evm_node.name }} + token: ${{ secrets.GITHUB_TOKEN }} + go_mod_path: ./integration-tests/go.mod + cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: "true" + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: "" + should_tidy: "false" + - name: Print failed test summary + if: always() + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@1587f59bfd626b668d303abbc90fee41b12397e6 # v2.3.23 + with: + test_directories: ./integration-tests/smoke/,./integration-tests/ccip-tests/smoke/ + + start-slack-thread: + name: Start Slack Thread + if: ${{ always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' && needs.should-run.outputs.should_run == 'true' }} + environment: integration + outputs: + thread_ts: ${{ steps.slack.outputs.thread_ts }} + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + runs-on: ubuntu-latest + needs: [run-client-compatibility-matrix,should-run,select-versions] + steps: + - name: Debug Result + run: echo ${{ join(needs.*.result, ',') }} + - name: Main Slack Notification + uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 + id: slack + with: + channel-id: ${{ secrets.QA_CCIP_SLACK_CHANNEL }} + payload: | + { + "attachments": [ + { + "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || '#2E7D32' }}", + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "CCIP Compatibility Test Results ${{ contains(join(needs.*.result, ','), 'failure') && ':x:' || ':white_check_mark:'}}", + "emoji": true + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "${{ contains(join(needs.*.result, ','), 'failure') && 'Some tests failed! Notifying ' || 'All Good!' }}" + } + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "<${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}> | <${{ github.server_url }}/${{ github.repository }}/commit/${{ needs.select-versions.outputs.chainlink_version }}|${{ needs.select-versions.outputs.chainlink_version }}> | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Run>" + } + } + ] + } + ] + } + env: + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + + parse-test-results: + name: Parse Test Results + if: always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' && needs.should-run.outputs.should_run == 'true' + environment: integration + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + runs-on: ubuntu-latest + needs: [run-client-compatibility-matrix,should-run] + outputs: + base64_parsed_results: ${{ steps.get-test-results.outputs.base64_parsed_results }} + steps: + # workflowresultparser is a tool to get job results from a workflow run + - name: Set Up workflowresultparser + shell: bash + run: | + go install github.com/smartcontractkit/chainlink-testing-framework/tools/workflowresultparser@v1.0.0 + - name: Get and parse Test Results + shell: bash + id: get-test-results + run: | + PATH=$PATH:$(go env GOPATH)/bin + export PATH + + workflowresultparser -workflowRunID ${{ github.run_id }} -githubToken ${{ github.token }} -githubRepo "${{ github.repository }}" -jobNameRegex "^CCIP Compatibility with (.*)$" -namedKey="CCIP" -outputFile=output.json + + echo "base64_parsed_results=$(base64 -w 0 output.json)" >> $GITHUB_OUTPUT + + display-test-results: + name: Aggregated test results + if: always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' && needs.should-run.outputs.should_run == 'true' && needs.parse-test-results.result == 'success' + environment: integration + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + runs-on: ubuntu-latest + needs: [start-slack-thread, should-run, select-versions, parse-test-results] + steps: + # asciitable is a tool that prints results in a nice ASCII table + - name: Set Up asciitable + shell: bash + run: | + go install github.com/smartcontractkit/chainlink-testing-framework/tools/asciitable@v1.0.2 + - name: Print aggregated test results + shell: bash + run: | + PATH=$PATH:$(go env GOPATH)/bin + export PATH + + raw_results="$(echo ${{ needs.parse-test-results.outputs.base64_parsed_results }} | base64 -d)" + echo $raw_results > input.json + asciitable --firstColumn "EVM Implementation" --secondColumn Result --jsonfile input.json --outputFile output.txt --section "CCIP" --namedKey "CCIP" + + echo + echo "AGGREGATED RESULTS" + cat output.txt + + echo "## Aggregated EVM Implementations compatibility results summary" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + cat output.txt >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + + post-test-results-to-slack: + name: Post Test Results + if: ${{ always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' && needs.should-run.outputs.should_run == 'true' }} + environment: integration + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + runs-on: ubuntu-latest + needs: [start-slack-thread,should-run,select-versions] + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + ref: ${{ needs.select-versions.outputs.chainlink_version }} + - name: Get test results for CCIP + id: get-product-results + shell: bash + run: | + raw_results="$(echo ${{ needs.parse-test-results.outputs.base64_parsed_results }} | base64 -d)" + product_result=$(echo "$raw_results" | jq -c "select(has(\"CCIP\")) | .CCIP[]") + if [ -n "$product_result" ]; then + base64_result=$(echo $product_result | base64 -w 0) + echo "base64_result=$base64_result" >> $GITHUB_OUTPUT + else + echo "No results found for CCIP" + echo "base64_result=" >> $GITHUB_OUTPUT + fi + - name: Post Test Results to Slack + uses: ./.github/actions/notify-slack-jobs-result + with: + github_token: ${{ github.token }} + github_repository: ${{ github.repository }} + workflow_run_id: ${{ github.run_id }} + github_job_name_regex: ^CCIP Compatibility with (.*?)$ + message_title: CCIP Compatibility Test Results + slack_channel_id: ${{ secrets.QA_CCIP_SLACK_CHANNEL }} + slack_bot_token: ${{ secrets.QA_SLACK_API_KEY }} + slack_thread_ts: ${{ needs.start-slack-thread.outputs.thread_ts }} + base64_parsed_results: ${{ steps.get-product-results.outputs.base64_result }} diff --git a/.github/workflows/ccip-live-network-tests.yml b/.github/workflows/ccip-live-network-tests.yml new file mode 100644 index 0000000000..fa24614c8e --- /dev/null +++ b/.github/workflows/ccip-live-network-tests.yml @@ -0,0 +1,312 @@ +name: CCIP Live Network Tests +on: + schedule: + - cron: '0 */6 * * *' + workflow_dispatch: + inputs: + base64_test_input : # base64 encoded toml for test input + description: 'Base64 encoded toml test input' + required: false + slackMemberID: + description: 'Slack member ID to notify' + required: false + test_type: + description: 'Type of test to run' + required: false + type: choice + options: + - 'load' + - 'smoke' + +# Only run 1 of this workflow at a time per PR +concurrency: + group: live-testnet-tests + cancel-in-progress: true + +env: + # TODO: TT-1470 - Update image names as we solidify new realease strategy + CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + CHAINLINK_VERSION: ${{ github.sha}} + CHAINLINK_TEST_VERSION: ${{ github.sha}} + ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests:${{ github.sha }} + INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com + AWS_ECR_REPO_PUBLIC_REGISTRY: public.ecr.aws + +jobs: + build-chainlink: + environment: integration + permissions: + id-token: write + contents: read + name: Build Chainlink Image + runs-on: ubuntu20.04-16cores-64GB + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - name: Check if image exists + id: check-image + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 + with: + repository: chainlink + tag: ${{ env.CHAINLINK_VERSION }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + - name: Build Image + if: steps.check-image.outputs.exists == 'false' + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 + env: + GH_TOKEN: ${{ github.token }} + with: + cl_repo: smartcontractkit/chainlink-ccip + cl_ref: ${{ env.CHAINLINK_VERSION }} + push_tag: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:${{ env.CHAINLINK_VERSION }} + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + - name: Collect Metrics + if: always() + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: ccip-on-demand-live-testnet-tests-build-chainlink-image + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Build Chainlink Image + continue-on-error: true + + build-test-image: + environment: integration + permissions: + id-token: write + contents: read + name: Build Test Image + runs-on: ubuntu20.04-16cores-64GB + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: ccip-on-demand-live-testnet-tests-build-test-image + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Build Test Image + continue-on-error: true + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - name: Build Test Image + uses: ./.github/actions/build-test-image + with: + tag: ${{ env.CHAINLINK_TEST_VERSION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + + ccip-load-test: + name: CCIP Load Test + environment: integration + runs-on: ubuntu-latest + strategy: + matrix: + config: [mainnet.toml] + needs: [ build-chainlink, build-test-image ] + # if the event is a scheduled event or the test type is load and no previous job failed + if: ${{ (github.event_name == 'schedule' || inputs.test_type == 'load') && !contains(needs.*.result, 'failure') }} + permissions: + issues: read + checks: write + pull-requests: write + id-token: write + contents: read + env: + CHAINLINK_ENV_USER: ${{ github.actor }} + SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} + SLACK_CHANNEL: ${{ secrets.QA_SLACK_CHANNEL }} + TEST_LOG_LEVEL: info + REF_NAME: ${{ github.head_ref || github.ref_name }} + ENV_JOB_IMAGE_BASE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests + BASE64_NETWORK_CONFIG: ${{ secrets.BASE64_NETWORK_CONFIG }} + + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: ccip-on-demand-live-testnet-tests-load-tests + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: CCIP Load Test + continue-on-error: true + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + ref: ${{ env.REF_NAME }} + - name: Prepare Base64 TOML override + shell: bash + run: | + # this key secrets.QA_SHARED_803C_KEY has a story behind it. To know more, see CCIP-2875 and SECHD-16575 tickets. + BASE64_NETWORK_CONFIG=$(echo $BASE64_NETWORK_CONFIG | base64 -w 0 -d | sed -e 's/evm_key/${{ secrets.QA_SHARED_803C_KEY }}/g' | base64 -w 0) + echo ::add-mask::$BASE64_NETWORK_CONFIG + echo "BASE64_NETWORK_CONFIG=$BASE64_NETWORK_CONFIG" >> "$GITHUB_ENV" + SLACK_USER=$(jq -r '.inputs.slackMemberID' $GITHUB_EVENT_PATH) + echo ::add-mask::$SLACK_USER + echo "SLACK_USER=$SLACK_USER" >> "$GITHUB_ENV" + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + BASE64_CCIP_CONFIG_OVERRIDE=$(jq -r '.inputs.base64_test_input' $GITHUB_EVENT_PATH) + echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE + echo "BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV + echo "TEST_BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV + fi + if [[ "${{ github.event_name }}" == "schedule" ]]; then + BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -w 0 -i ./integration-tests/ccip-tests/testconfig/override/${{ matrix.config }}) + echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE + echo "BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV + echo "TEST_BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV + echo "SLACK_USER=${{ secrets.QA_SLACK_USER }}" >> $GITHUB_ENV + fi + - name: step summary + shell: bash + run: | + echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY + echo "\`${{ env.CHAINLINK_VERSION }}\`" >> $GITHUB_STEP_SUMMARY + echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY + echo "\`${{ env.CHAINLINK_TEST_VERSION }}\`" >> $GITHUB_STEP_SUMMARY + - name: Prepare Base64 TOML override for CCIP secrets + uses: ./.github/actions/setup-create-base64-config-ccip + with: + runId: ${{ github.run_id }} + testLogCollect: ${{ vars.TEST_LOG_COLLECT }} + chainlinkImage: ${{ env.CHAINLINK_IMAGE }} + chainlinkVersion: ${{ github.sha }} + lokiEndpoint: ${{ secrets.LOKI_URL }} + lokiTenantId: ${{ vars.LOKI_TENANT_ID }} + lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} + logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + grafanaUrl: ${{ vars.GRAFANA_URL }} + grafanaDashboardUrl: "/d/6vjVx-1V8/ccip-long-running-tests" + - name: Run Tests + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 + env: + TEST_SUITE: load + TEST_ARGS: -test.timeout 900h + DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable + RR_MEM: 8Gi + RR_CPU: 4 + DETACH_RUNNER: true + TEST_TRIGGERED_BY: ccip-load-test-ci + with: + test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 70m -count=1 -json -run ^TestLoadCCIPStableRPS$ ./load 2>&1 | tee /tmp/gotest.log | gotestfmt + test_download_vendor_packages_command: cd ./integration-tests && go mod download + cl_repo: ${{ env.CHAINLINK_IMAGE }} + cl_image_tag: ${{ env.CHAINLINK_VERSION }} + token: ${{ secrets.GITHUB_TOKEN }} + go_mod_path: ./integration-tests/go.mod + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + triggered_by: ${{ env.TEST_TRIGGERED_BY }} + artifacts_location: ./integration-tests/load/logs/payload_ccip.json + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + cache_key_id: ccip-load-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: "true" + should_cleanup: false + + ccip-smoke-test: + name: CCIP smoke Test + environment: integration + runs-on: ubuntu-latest + needs: [ build-chainlink, build-test-image ] + # if the event is a scheduled event or the test type is load and no previous job failed + if: ${{ github.event_name == 'workflow_dispatch' && inputs.test_type == 'smoke' && !contains(needs.*.result, 'failure') }} + permissions: + issues: read + checks: write + pull-requests: write + id-token: write + contents: read + env: + CHAINLINK_ENV_USER: ${{ github.actor }} + SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} + SLACK_CHANNEL: ${{ secrets.QA_SLACK_CHANNEL }} + TEST_LOG_LEVEL: info + REF_NAME: ${{ github.head_ref || github.ref_name }} + ENV_JOB_IMAGE_BASE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests + BASE64_NETWORK_CONFIG: ${{ secrets.BASE64_NETWORK_CONFIG }} + + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: ccip-on-demand-live-testnet-tests-smoke-test + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: CCIP Smoke Test + continue-on-error: true + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + ref: ${{ env.REF_NAME }} + - name: Prepare Base64 TOML override + shell: bash + run: | + BASE64_NETWORK_CONFIG=$(echo $BASE64_NETWORK_CONFIG | base64 -w 0 -d | sed -e 's/evm_key/${{ secrets.QA_SHARED_803C_KEY }}/g' | base64 -w 0) + echo ::add-mask::$BASE64_NETWORK_CONFIG + echo "BASE64_NETWORK_CONFIG=$BASE64_NETWORK_CONFIG" >> "$GITHUB_ENV" + SLACK_USER=$(jq -r '.inputs.slackMemberID' $GITHUB_EVENT_PATH) + echo ::add-mask::$SLACK_USER + echo "SLACK_USER=$SLACK_USER" >> "$GITHUB_ENV" + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + BASE64_CCIP_CONFIG_OVERRIDE=$(jq -r '.inputs.base64_test_input' $GITHUB_EVENT_PATH) + echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE + echo "BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV + echo "TEST_BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV + fi + - name: step summary + shell: bash + run: | + echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY + echo "\`${{ env.CHAINLINK_VERSION }}\`" >> $GITHUB_STEP_SUMMARY + echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY + echo "\`${{ env.CHAINLINK_TEST_VERSION }}\`" >> $GITHUB_STEP_SUMMARY + - name: Prepare Base64 TOML override for CCIP secrets + uses: ./.github/actions/setup-create-base64-config-ccip + with: + runId: ${{ github.run_id }} + testLogCollect: ${{ vars.TEST_LOG_COLLECT }} + chainlinkImage: ${{ env.CHAINLINK_IMAGE }} + chainlinkVersion: ${{ github.sha }} + lokiEndpoint: ${{ secrets.LOKI_URL }} + lokiTenantId: ${{ vars.LOKI_TENANT_ID }} + lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} + logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + grafanaUrl: ${{ vars.GRAFANA_URL }} + grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + - name: Run Tests + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 + env: + TEST_SUITE: smoke + TEST_ARGS: -test.timeout 900h + DETACH_RUNNER: true + DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable + RR_MEM: 8Gi + RR_CPU: 4 + TEST_TRIGGERED_BY: ccip-smoke-test-ci + with: + test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 70m -count=1 -p 30 -json -run ^TestSmokeCCIPForBidirectionalLane$ ./smoke 2>&1 | tee /tmp/gotest.log | gotestfmt + test_download_vendor_packages_command: cd ./integration-tests && go mod download + cl_repo: ${{ env.CHAINLINK_IMAGE }} + cl_image_tag: ${{ env.CHAINLINK_VERSION }} + token: ${{ secrets.GITHUB_TOKEN }} + go_mod_path: ./integration-tests/go.mod + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + triggered_by: ${{ env.TEST_TRIGGERED_BY }} + artifacts_location: ./integration-tests/smoke/logs/payload_ccip.json + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + cache_key_id: ccip-smoke-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: "true" + should_cleanup: false \ No newline at end of file diff --git a/.github/workflows/ccip-load-tests.yml b/.github/workflows/ccip-load-tests.yml new file mode 100644 index 0000000000..8ddaba1199 --- /dev/null +++ b/.github/workflows/ccip-load-tests.yml @@ -0,0 +1,289 @@ +name: CCIP Load Test +on: + push: + branches: + - develop + tags: + - '*' + workflow_dispatch: + inputs: + base64_test_input: # base64 encoded toml for test input + description: 'Base64 encoded toml test input' + required: false + +# Only run 1 of this workflow at a time per PR +concurrency: + group: load-ccip-tests-chainlink-${{ github.ref }} + cancel-in-progress: true + +env: + # TODO: TT-1470 - Update image names as we solidify new realease strategy + CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + CHAINLINK_VERSION: ${{ github.sha}} + INPUT_CHAINLINK_TEST_VERSION: ${{ github.sha}} + ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests:${{ github.sha }} + INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com + AWS_ECR_REPO_PUBLIC_REGISTRY: public.ecr.aws + MOD_CACHE_VERSION: 1 + +jobs: + build-chainlink: + environment: integration + permissions: + id-token: write + contents: read + name: Build Chainlink Image + runs-on: ubuntu20.04-16cores-64GB + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - name: Check if image exists + id: check-image + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 + with: + repository: chainlink + tag: ${{ env.CHAINLINK_VERSION }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + - name: Build Image + if: steps.check-image.outputs.exists == 'false' + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 + env: + GH_TOKEN: ${{ github.token }} + with: + cl_repo: smartcontractkit/chainlink + cl_ref: ${{ env.CHAINLINK_VERSION }} + push_tag: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:${{ env.CHAINLINK_VERSION }} + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + - name: Collect Metrics + if: always() + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: ccip-load-test-build-chainlink-image + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Build Chainlink Image + continue-on-error: true + + build-test-image: + environment: integration + permissions: + id-token: write + contents: read + name: Build Test Image + runs-on: ubuntu20.04-16cores-64GB + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: ccip-load-test-build-test-image + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Build Test Image + continue-on-error: true + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - name: Build Test Image + uses: ./.github/actions/build-test-image + with: + tag: ${{ env.INPUT_CHAINLINK_TEST_VERSION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + + ccip-load-test: + environment: integration + needs: [ build-chainlink, build-test-image ] + if: ${{ always() && !contains(needs.*.result, 'failure') }} + permissions: + issues: read + checks: write + pull-requests: write + id-token: write + contents: read + env: + CHAINLINK_ENV_USER: ${{ github.actor }} + SLACK_USER: ${{ inputs.slackMemberID }} + SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} + SLACK_CHANNEL: ${{ secrets.QA_SLACK_CHANNEL }} + TEST_LOG_LEVEL: info + REF_NAME: ${{ github.head_ref || github.ref_name }} + BASE64_NETWORK_CONFIG: ${{ secrets.BASE64_NETWORK_CONFIG }} + strategy: + fail-fast: false + matrix: + type: + - name: stable-load + run: ^TestLoadCCIPStableRPS$ + os: ubuntu-latest + - name: load-with-arm-curse-uncurse + run: ^TestLoadCCIPStableRPSAfterARMCurseAndUncurse$ + config_path: ./integration-tests/ccip-tests/testconfig/tomls/load-with-arm-curse-uncurse.toml + os: ubuntu-latest + runs-on: ${{ matrix.type.os }} + name: CCIP ${{ matrix.type.name }} + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: ccip-load-test-${{ matrix.type.name }} + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: CCIP ${{ matrix.type.name }} + test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' + continue-on-error: true + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + ref: ${{ env.REF_NAME }} + - name: Sets env vars + shell: bash + run: | + # if the matrix.type.config_path is set, use it as the override config + if [ -n "${{ matrix.type.config_path }}" ]; then + echo "BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -w 0 -i ${{ matrix.type.config_path }})" >> $GITHUB_ENV + echo "TEST_BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -w 0 -i ${{ matrix.type.config_path }})" >> $GITHUB_ENV + fi + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + BASE64_CCIP_CONFIG_OVERRIDE=$(jq -r '.inputs.base64_test_input' $GITHUB_EVENT_PATH) + echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE + if [ -n "${BASE64_CCIP_CONFIG_OVERRIDE}" && "$BASE64_CCIP_CONFIG_OVERRIDE" != "null"]; then + echo "BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV + echo "TEST_BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV + fi + fi + - name: step summary + shell: bash + run: | + echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY + echo "\`${{ env.CHAINLINK_VERSION }}\`" >> $GITHUB_STEP_SUMMARY + echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY + echo "\`${{ env.INPUT_CHAINLINK_TEST_VERSION }}\`" >> $GITHUB_STEP_SUMMARY + - name: Prepare Base64 TOML override for CCIP secrets + uses: ./.github/actions/setup-create-base64-config-ccip + with: + runId: ${{ github.run_id }} + testLogCollect: ${{ vars.TEST_LOG_COLLECT }} + chainlinkImage: ${{ env.CHAINLINK_IMAGE }} + chainlinkVersion: ${{ github.sha }} + lokiEndpoint: ${{ secrets.LOKI_URL }} + lokiTenantId: ${{ vars.LOKI_TENANT_ID }} + logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + grafanaUrl: ${{ vars.GRAFANA_URL }} + grafanaDashboardUrl: "/d/6vjVx-1V8/ccip-long-running-tests" + - name: Run Tests + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 + env: + TEST_SUITE: load + TEST_ARGS: -test.timeout 900h + DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable + RR_MEM: 8Gi + RR_CPU: 4 + TEST_TRIGGERED_BY: ccip-load-test-ci-${{ matrix.type.name }} + with: + test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 70m -count=1 -json -run ${{ matrix.type.run }} ./load 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci + test_download_vendor_packages_command: cd ./integration-tests && go mod download + cl_repo: ${{ env.CHAINLINK_IMAGE }} + cl_image_tag: ${{ env.CHAINLINK_VERSION }} + token: ${{ secrets.GITHUB_TOKEN }} + go_mod_path: ./integration-tests/go.mod + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + triggered_by: ${{ env.TEST_TRIGGERED_BY }} + publish_check_name: ${{ matrix.type.name }} + artifacts_location: ./integration-tests/load/logs/payload_ccip.json + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + cache_key_id: ccip-load-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: "true" + should_cleanup: "true" + + # Reporting Jobs + start-slack-thread: + name: Start Slack Thread + if: ${{ failure() && needs.ccip-load-test.result != 'skipped' && needs.ccip-load-test.result != 'cancelled' }} + environment: integration + outputs: + thread_ts: ${{ steps.slack.outputs.thread_ts }} + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + runs-on: ubuntu-latest + needs: [ccip-load-test] + steps: + - name: Debug Result + run: echo ${{ join(needs.*.result, ',') }} + - name: Main Slack Notification + uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 + id: slack + with: + channel-id: "#ccip-testing" + payload: | + { + "attachments": [ + { + "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || '#2E7D32' }}", + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "CCIP load tests results ${{ contains(join(needs.*.result, ','), 'failure') && ':x:' || ':white_check_mark:'}}", + "emoji": true + } + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "<${{ github.server_url }}/${{ github.repository }}/${{contains(github.ref_name, 'release') && 'releases/tag' || 'tree'}}/${{ github.ref_name }}|${{ github.ref_name }}> | <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}> | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Run>" + } + } + ] + } + ] + } + env: + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + + post-test-results-to-slack: + name: Post Test Results + if: ${{ failure() && needs.start-slack-thread.result != 'skipped' && needs.start-slack-thread.result != 'cancelled' }} + environment: integration + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + runs-on: ubuntu-latest + needs: start-slack-thread + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} + - name: Post Test Results + uses: ./.github/actions/notify-slack-jobs-result + with: + github_token: ${{ github.token }} + github_repository: ${{ github.repository }} + workflow_run_id: ${{ github.run_id }} + github_job_name_regex: ^CCIP (.*)$ + message_title: CCIP Jobs + slack_channel_id: "#ccip-testing" + slack_bot_token: ${{ secrets.QA_SLACK_API_KEY }} + slack_thread_ts: ${{ needs.start-slack-thread.outputs.thread_ts }} + + # End Reporting Jobs diff --git a/.github/workflows/chain-selectors-check.yml b/.github/workflows/chain-selectors-check.yml new file mode 100644 index 0000000000..c2b58e68d4 --- /dev/null +++ b/.github/workflows/chain-selectors-check.yml @@ -0,0 +1,39 @@ +name: Chain Selectors Version Check + +on: + push: + branches: + - develop + - release/* + tags: + - v* + pull_request: + branches: + - release/* + + +jobs: + verify-version: + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Setup Go + uses: ./.github/actions/setup-go + with: + only-modules: true + go-version-file: "go.mod" + + - name: Get chain-selectors version + id: get-chain-selectors-version + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + current_chain_selector_version=$(go list -m -f '{{.Version}}' github.com/smartcontractkit/chain-selectors) + latest_chain_selector_version=$(gh release view -R smartcontractkit/chain-selectors --json tagName --jq '.tagName') + if [[ "$current_chain_selector_version" != "$latest_chain_selector_version" ]]; then + echo "::error:: Chain Selectors version mismatch. Current version: $current_chain_selector_version, Latest version: $latest_chain_selector_version" + exit 1 + fi diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index fd5784df8c..d821b20a30 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -511,7 +511,323 @@ jobs: - name: Print failed test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@70ccaef155381025e411cf7cd1fa5ef8f668ed75 # v2.3.25 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 + + eth-smoke-tests-matrix-ccip: + if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} + environment: integration + permissions: + actions: read + checks: write + pull-requests: write + id-token: write + contents: read + needs: [build-chainlink, changes, build-lint-integration-tests] + env: + SELECTED_NETWORKS: SIMULATED + CHAINLINK_COMMIT_SHA: ${{ inputs.evm-ref || github.sha }} + CHAINLINK_ENV_USER: ${{ github.actor }} + TEST_LOG_LEVEL: debug + strategy: + fail-fast: false + matrix: + product: + - name: ccip-smoke + nodes: 1 + os: ubuntu-latest + file: ccip + dir: ccip-tests/smoke + run: -run ^TestSmokeCCIPForBidirectionalLane$ + - name: ccip-smoke-1.4-pools + nodes: 1 + os: ubuntu-latest + file: ccip + dir: ccip-tests/smoke + run: -run ^TestSmokeCCIPForBidirectionalLane$ + config_path: ./integration-tests/ccip-tests/testconfig/tomls/contract-version1.4.toml + - name: ccip-smoke-usdc + nodes: 1 + os: ubuntu-latest + file: ccip + dir: ccip-tests/smoke + run: -run ^TestSmokeCCIPForBidirectionalLane$ + config_path: ./integration-tests/ccip-tests/testconfig/tomls/usdc_mock_deployment.toml + - name: ccip-smoke-db-compatibility + nodes: 1 + os: ubuntu-latest + file: ccip + dir: ccip-tests/smoke + run: -run ^TestSmokeCCIPForBidirectionalLane$ + config_path: ./integration-tests/ccip-tests/testconfig/tomls/db-compatibility.toml + - name: ccip-smoke-rate-limit + nodes: 1 + dir: ccip-tests/smoke + os: ubuntu-latest + file: ccip + run: -run ^TestSmokeCCIPRateLimit$ + - name: ccip-smoke-rate-limit + nodes: 1 + dir: ccip-tests/smoke + os: ubuntu-latest + file: ccip + run: -run ^TestSmokeCCIPTokenPoolRateLimits$ + - name: ccip-smoke-multicall + nodes: 1 + dir: ccip-tests/smoke + os: ubuntu-latest + file: ccip + run: -run ^TestSmokeCCIPMulticall$ + - name: ccip-smoke-manual-exec + nodes: 1 + dir: ccip-tests/smoke + os: ubuntu-latest + file: ccip + run: -run ^TestSmokeCCIPManuallyExecuteAfterExecutionFailingDueToInsufficientGas$ + - name: ccip-smoke-on-ramp-limits + nodes: 1 + dir: ccip-tests/smoke + os: ubuntu-latest + file: ccip + run: -run ^TestSmokeCCIPOnRampLimits$ + - name: ccip-smoke-off-ramp-capacity + nodes: 1 + dir: ccip-tests/smoke + os: ubuntu-latest + file: ccip + run: -run ^TestSmokeCCIPOffRampCapacityLimit$ + - name: ccip-smoke-off-ramp-agg-rate-limit + nodes: 1 + dir: ccip-tests/smoke + os: ubuntu-latest + file: ccip + run: -run ^TestSmokeCCIPOffRampAggRateLimit$ + - name: ccip-smoke-leader-lane + nodes: 15 + dir: ccip-tests/smoke + os: ubuntu-latest + file: ccip + run: -run ^TestSmokeCCIPForBidirectionalLane$ + config_path: ./integration-tests/ccip-tests/testconfig/tomls/leader-lane.toml + runs-on: ${{ matrix.product.os }} + name: ETH Smoke Tests ${{ matrix.product.name }}${{ matrix.product.tag_suffix }} + steps: + # Handy for debugging resource usage + # - name: Collect Workflow Telemetry + # uses: catchpoint/workflow-telemetry-action@v2 + - name: Collect Metrics + if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 + with: + id: ${{ env.COLLECTION_ID }}-matrix-${{ matrix.product.id }} + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: ETH Smoke Tests ${{ matrix.product.name }}${{ matrix.product.tag_suffix }} + test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' + continue-on-error: true + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + repository: smartcontractkit/chainlink + ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} + - name: Build Go Test Command + id: build-go-test-command + run: | + # if dir is provided use it, otherwise use the smoke dir + if [ "${{ matrix.product.dir }}" != "" ]; then + dir=${{ matrix.product.dir }} + else + dir=smoke + fi + # if the matrix.product.run is set, use it for a different command + if [ "${{ matrix.product.run }}" != "" ]; then + echo "run_command=${{ matrix.product.run }} ./${dir}/${{ matrix.product.file }}_test.go" >> "$GITHUB_OUTPUT" + else + echo "run_command=./${dir}/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT" + fi + - name: Check for "enable tracing" label + id: check-label + run: | + label=$(jq -r '.pull_request.labels[]?.name // empty' "$GITHUB_EVENT_PATH") + + if [[ -n "$label" ]]; then + if [[ "$label" == "enable tracing" ]]; then + echo "Enable tracing label found." + echo "trace=true" >> $GITHUB_OUTPUT + else + echo "Enable tracing label not found." + echo "trace=false" >> $GITHUB_OUTPUT + fi + else + echo "No labels present or labels are null." + echo "trace=false" >> $GITHUB_OUTPUT + fi + + - name: Setup Grafana and OpenTelemetry + id: docker-setup + if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' + run: | + # Create network + docker network create --driver bridge tracing + + # Make trace directory + cd integration-tests/smoke/ + mkdir ./traces + chmod -R 777 ./traces + + # Switch directory + cd ../../.github/tracing + + # Create a Docker volume for traces + # docker volume create otel-traces + + # Start OpenTelemetry Collector + # Note the user must be set to the same user as the runner for the trace data to be accessible + docker run -d --network=tracing --name=otel-collector \ + -v $PWD/otel-collector-ci.yaml:/etc/otel-collector.yaml \ + -v $PWD/../../integration-tests/smoke/traces:/tracing \ + --user "$(id -u):$(id -g)" \ + -p 4317:4317 otel/opentelemetry-collector:0.88.0 --config=/etc/otel-collector.yaml + + - name: Locate Docker Volume + id: locate-volume + if: false + run: | + echo "VOLUME_PATH=$(docker volume inspect --format '{{ .Mountpoint }}' otel-traces)" >> $GITHUB_OUTPUT + + - name: Show Otel-Collector Logs + if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' + run: | + docker logs otel-collector + + - name: Set Override Config + id: set_override_config + run: | + # if the matrix.product.config_path is set, use it as the override config + if [ "${{ matrix.product.config_path }}" != "" ]; then + echo "base_64_override=$(base64 -w 0 -i ${{ matrix.product.config_path }})" >> "$GITHUB_OUTPUT" + fi + + - name: Setup GAP for Grafana + uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 + id: setup-gap + with: + # aws inputs + aws-region: ${{ secrets.AWS_REGION }} + aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + # other inputs + duplicate-authorization-header: "true" + + - name: Prepare Base64 CCIP TOML secrets + uses: ./.github/actions/setup-create-base64-config-ccip + with: + runId: ${{ github.run_id }} + pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 + pyroscopeEnvironment: ${{ matrix.product.pyroscope_env }} + pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} + testLogCollect: ${{ vars.TEST_LOG_COLLECT }} + selectedNetworks: SIMULATED_1,SIMULATED_2 + chainlinkImage: ${{ env.CHAINLINK_IMAGE }} + chainlinkVersion: ${{ github.sha }} + lokiEndpoint: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + lokiTenantId: ${{ vars.LOKI_TENANT_ID }} + lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} + logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + grafanaUrl: "http://localhost:8080/primary" + grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + + ## Run this step when changes that require tests to be run are made + - name: Run Tests + if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 + with: + test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs + test_download_vendor_packages_command: cd ./integration-tests && go mod download + test_config_chainlink_version: ${{ inputs.evm-ref || github.sha }} + test_config_selected_networks: ${{ env.SELECTED_NETWORKS }} + test_config_logging_run_id: ${{ github.run_id }} + test_config_logstream_log_targets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + test_config_test_log_collect: ${{ vars.TEST_LOG_COLLECT }} + cl_repo: ${{ env.CHAINLINK_IMAGE }} + cl_image_tag: ${{ inputs.evm-ref || github.sha }}${{ matrix.product.tag_suffix }} + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + artifacts_name: ${{ matrix.product.name }}${{ matrix.product.tag_suffix }}-test-logs + artifacts_location: | + ./integration-tests/smoke/logs/ + ./integration-tests/smoke/db_dumps/ + /tmp/gotest.log + publish_check_name: ${{ matrix.product.name }} + token: ${{ secrets.GITHUB_TOKEN }} + go_mod_path: ./integration-tests/go.mod + cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: "true" + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: "" + should_tidy: "false" + go_coverage_src_dir: /var/tmp/go-coverage + go_coverage_dest_dir: ${{ github.workspace }}/.covdata + DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} + DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" + DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + DEFAULT_PYROSCOPE_SERVER_URL: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 + DEFAULT_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + DEFAULT_PYROSCOPE_ENVIRONMENT: ${{ matrix.product.pyroscope_env }} + DEFAULT_PYROSCOPE_ENABLED: ${{ matrix.product.pyroscope_env == '' || !startsWith(github.ref, 'refs/tags/') && 'false' || 'true' }} + + - name: Upload Coverage Data + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + timeout-minutes: 2 + continue-on-error: true + with: + name: cl-node-coverage-data-${{ matrix.product.name }}-${{ matrix.product.tag_suffix }} + path: .covdata + retention-days: 1 + + # Run this step when changes that do not need the test to run are made + - name: Run Setup + if: needs.changes.outputs.src == 'false' + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 + with: + test_download_vendor_packages_command: cd ./integration-tests && go mod download + go_mod_path: ./integration-tests/go.mod + cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: "true" + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: "" + should_tidy: "false" + + - name: Show Otel-Collector Logs + if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' + run: | + docker logs otel-collector + + - name: Permissions on traces + if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' + run: | + ls -l ./integration-tests/smoke/traces + + - name: Upload Trace Data + if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + with: + name: trace-data + path: ./integration-tests/smoke/traces/trace-data.json + + - name: Print failed test summary + if: always() + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 + with: + test_directories: ./integration-tests/smoke/ + eth-smoke-tests-matrix: if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} @@ -622,11 +938,17 @@ jobs: - name: Build Go Test Command id: build-go-test-command run: | + # if dir is provided use it, otherwise use the smoke dir + if [ "${{ matrix.product.dir }}" != "" ]; then + dir=${{ matrix.product.dir }} + else + dir=smoke + fi # if the matrix.product.run is set, use it for a different command if [ "${{ matrix.product.run }}" != "" ]; then - echo "run_command=${{ matrix.product.run }} ./smoke/${{ matrix.product.file }}_test.go" >> "$GITHUB_OUTPUT" + echo "run_command=${{ matrix.product.run }} ./${dir}/${{ matrix.product.file }}_test.go" >> "$GITHUB_OUTPUT" else - echo "run_command=./smoke/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT" + echo "run_command=./${dir}/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT" fi - name: Check for "enable tracing" label id: check-label @@ -682,6 +1004,14 @@ jobs: if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' run: | docker logs otel-collector + + - name: Set Override Config + id: set_override_config + run: | + # if the matrix.product.config_path is set, use it as the override config + if [ "${{ matrix.product.config_path }}" != "" ]; then + echo "base_64_override=$(base64 -w 0 -i ${{ matrix.product.config_path }})" >> "$GITHUB_OUTPUT" + fi - name: Setup GAP for Grafana uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 @@ -694,6 +1024,25 @@ jobs: # other inputs duplicate-authorization-header: "true" + - name: Prepare Base64 CCIP TOML secrets + uses: ./.github/actions/setup-create-base64-config-ccip + with: + runId: ${{ github.run_id }} + pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 + pyroscopeEnvironment: ${{ matrix.product.pyroscope_env }} + pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} + testLogCollect: ${{ vars.TEST_LOG_COLLECT }} + selectedNetworks: SIMULATED_1,SIMULATED_2 + chainlinkImage: ${{ env.CHAINLINK_IMAGE }} + chainlinkVersion: ${{ github.sha }} + lokiEndpoint: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + lokiTenantId: ${{ vars.LOKI_TENANT_ID }} + lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} + logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + grafanaUrl: "http://localhost:8080/primary" + grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' @@ -811,6 +1160,30 @@ jobs: matrix-aggregator-status: ${{ needs.eth-smoke-tests-matrix.result }} continue-on-error: true + eth-smoke-tests-ccip: + if: always() + runs-on: ubuntu-latest + name: ETH Smoke Tests CCIP + needs: eth-smoke-tests-matrix-ccip + steps: + - name: Check smoke test matrix status + if: needs.eth-smoke-tests-matrix-ccip.result != 'success' + run: | + echo "ETH Smoke Tests CCIP: ${{ needs.eth-smoke-tests-matrix-ccip.result }}" + exit 1 + - name: Collect Metrics + if: always() + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 + with: + id: ${{ env.COLLECTION_ID }}-matrix-results-ccip + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: ETH Smoke Tests CCIP + matrix-aggregator-status: ${{ needs.eth-smoke-tests-matrix-ccip.result }} + continue-on-error: true + cleanup: name: Clean up integration environment deployments if: always() diff --git a/.gitignore b/.gitignore index 07dc8baa13..00962a94a3 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,8 @@ integration-tests/**/traces/ benchmark_report.csv benchmark_summary.json integration-tests/citool/output.csv +secrets.toml +tmp_laneconfig/ # goreleaser builds cosign.* diff --git a/integration-tests/ccip-tests/Makefile b/integration-tests/ccip-tests/Makefile new file mode 100644 index 0000000000..5a40f7ca0f --- /dev/null +++ b/integration-tests/ccip-tests/Makefile @@ -0,0 +1,70 @@ +## To Override the default config, and secret config: +# example usage: make set_config override_toml=../config/config.toml secret_toml=../config/secret.toml network_config_toml=../config/network.toml +.PHONY: set_config +set_config: + if [ -s "$(override_toml)" ]; then \ + echo "Overriding config with $(override_toml)"; \ + echo "export BASE64_CCIP_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" > ./testconfig/override/.env; \ + echo "export TEST_BASE64_CCIP_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" >> ./testconfig/override/.env; \ + else \ + echo "No override config found, using default config"; \ + echo > ./testconfig/override/.env; \ + fi + if [ -s "$(network_config_toml)" ]; then \ + echo "Overriding network config with $(network_config_toml)"; \ + echo "export BASE64_NETWORK_CONFIG=$$(base64 -i $(network_config_toml))" >> ./testconfig/override/.env; \ + fi + + @echo "setting secret config with $(secret_toml)" + @echo "export BASE64_CCIP_SECRETS_CONFIG=$$(base64 -i $(secret_toml))" >> ./testconfig/override/.env + @echo "export TEST_BASE64_CCIP_SECRETS_CONFIG=$$(base64 -i $(secret_toml))" >> ./testconfig/override/.env + @echo "BASE64_CCIP_SECRETS_CONFIG=$$(base64 -i $(secret_toml))" > ./testconfig/override/debug.env + @echo "TEST_BASE64_CCIP_SECRETS_CONFIG=$$(base64 -i $(secret_toml))" >> ./testconfig/override/debug.env + + +# example usage: make test_load_ccip testimage=chainlink-ccip-tests:latest testname=TestLoadCCIPStableRPS override_toml=./testconfig/override/config.toml secret_toml=./testconfig/tomls/secrets.toml network_config_toml=../config/network.toml +.PHONY: test_load_ccip +test_load_ccip: set_config + source ./testconfig/override/.env && \ + DATABASE_URL=postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable \ + ENV_JOB_IMAGE=$(testimage) \ + TEST_SUITE=load \ + TEST_ARGS="-test.timeout 900h" \ + DETACH_RUNNER=true \ + RR_MEM=16Gi \ + RR_CPU=4 \ + go test -timeout 24h -count=1 -v -run ^$(testname)$$ ./load + + +# example usage: make test_smoke_ccip testimage=chainlink-ccip-tests:latest testname=TestSmokeCCIPForBidirectionalLane override_toml=../testconfig/override/config.toml secret_toml=./testconfig/tomls/secrets.toml network_config_toml=../config/network.toml +.PHONY: test_smoke_ccip +test_smoke_ccip: set_config + source ./testconfig/override/.env && \ + DATABASE_URL=postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable \ + ENV_JOB_IMAGE=$(testimage) \ + TEST_SUITE=smoke \ + TEST_ARGS="-test.timeout 900h" \ + DETACH_RUNNER=true \ + go test -timeout 24h -count=1 -v -run ^$(testname)$$ ./smoke + +# run ccip smoke tests with default config; explicitly sets the override config to empty +# example usage: make test_smoke_ccip_default testname=TestSmokeCCIPForBidirectionalLane secret_toml=./testconfig/tomls/secrets.toml +.PHONY: test_smoke_ccip_default +test_smoke_ccip_default: set_config + source ./testconfig/override/.env && \ + DATABASE_URL=postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable \ + BASE64_CCIP_CONFIG_OVERRIDE="" \ + TEST_BASE64_CCIP_CONFIG_OVERRIDE="" \ + ENV_JOB_IMAGE="" \ + TEST_SUITE=smoke \ + TEST_ARGS="-test.timeout 900h" \ + DETACH_RUNNER=true \ + go test -timeout 24h -count=1 -v -run ^$(testname)$$ ./smoke + + +# image: the name for the chainlink image being built, example: image=chainlink +# tag: the tag for the chainlink image being built, example: tag=latest +# example usage: make build_ccip_image image=chainlink-ccip tag=latest +.PHONY: build_ccip_image +build_ccip_image: + docker build -f ../../core/chainlink.Dockerfile --build-arg COMMIT_SHA=$(git rev-parse HEAD) --build-arg CHAINLINK_USER=chainlink -t $(image):$(tag) ../../ diff --git a/integration-tests/ccip-tests/README.md b/integration-tests/ccip-tests/README.md new file mode 100644 index 0000000000..0e000561fa --- /dev/null +++ b/integration-tests/ccip-tests/README.md @@ -0,0 +1,138 @@ +# CCIP Tests + +Here lives the integration tests for ccip, utilizing our [chainlink-testing-framework](https://github.com/smartcontractkit/chainlink-testing-framework) and [integration-tests](https://github.com/smartcontractkit/ccip/tree/ccip-develop/integration-tests) + +## Setup the Tests + +CCIP tests are designed to be highly configurable. Instead of writing many tests to check specific scenarios, the philosophy is to write a few unique tests and make them adjustable through the use of test inputs and configurations. There are a few different ways to set this configuration: + +1. Default test input - set via TOML - If no specific input is set; the tests will run with default inputs mentioned in [default.toml](./testconfig/tomls/ccip-default.toml). +Please refer to the [testconfig README](../testconfig/README.md) for a more detailed look at how testconfig works. +2. If you want to run your test with a different config, you can override the default inputs. You can either write an [overrides.toml](../testconfig/README.md#configuration-and-overrides) file, or set the env var `BASE64_CCIP_CONFIG_OVERRIDE` containing the base64 encoded TOML file content with updated test input parameters. +For example, if you want to override the `Network` input in test and want to run your test on `avalanche testnet` and `arbitrum goerli` network, you need to: + 1. Create a TOML file with the following content: + + ```toml + [CCIP] + [CCIP.Env] + [CCIP.Env.Network] + selected_networks= ['AVALANCHE_FUJI', 'ARBITRUM_GOERLI'] + ``` + + 2. Encode it using the `base64` command + 3. Set the env var `BASE64_CCIP_CONFIG_OVERRIDE` with the encoded content. + + ```bash + export BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -i ) + ``` + + [mainnet.toml](./testconfig/override/mainnet.toml), [override.toml](./testconfig/examples/override.toml.example) are some of the sample override TOML files. + + For example - In order to run the smoke test (TestSmokeCCIPForBidirectionalLane) on mainnet, run the test with following env var set: + + ```bash + export BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -i ./testconfig/override/mainnet.toml) + ``` + +3. Secrets - You also need to set some secrets. This is a mandatory step needed to run the tests. Please refer to [sample-secrets.toml](./testconfig/examples/secrets.toml.example) for the list of secrets that are mandatory to run the tests. + - The chainlink image and tag are required secrets for all the tests. + - If you are running tests in live networks like testnet and mainnet, you need to set the secrets (rpc urls and private keys) for the respective networks. + - If you are running tests in simulated networks no network specific secrets are required. + here is a sample secrets.toml file, for running the tests in simulated networks, with the chainlink image and tag set as secrets: + + ```toml + [CCIP] + [CCIP.Env] + # ChainlinkImage is mandatory for all tests. + [CCIP.Env.NewCLCluster] + [CCIP.Env.NewCLCluster.Common] + [CCIP.Env.NewCLCluster.Common.ChainlinkImage] + image = "chainlink-ccip" + version = "latest" + ``` + + We consider secrets similar to test input overrides and encode them using `base64` command. + Once you have the secrets.toml file, you can encode it using `base64` command (similar to step 2) and set the env var `BASE64_CCIP_SECRETS_CONFIG` with the encoded content. + + ```bash + export BASE64_CCIP_SECRETS_CONFIG=$(base64 -i ./testconfig/tomls/secrets.toml) + ``` + +**Please note that the secrets should NOT be checked in to the repo and should be kept locally.** + +We recommend against changing the content of [sample-secrets.toml](./testconfig/examples/secrets.toml.example). Please create a new file and set it as the secrets file. +You can run the command to ignore the changes to the file. + +```bash +git update-index --skip-worktree +``` + +## Running the Tests + +There are two ways to run the tests: + +1. Using local docker containers +2. Using a remote kubernetes cluster + +### Using Local Docker Containers + +In order to run the tests locally, you need to have docker installed and running on your machine. +You can use a specific chainlink image and tag (if you already have one) for the tests. Otherwise, you can build the image using the following command: + +```bash +make build_ccip_image image=chainlink-ccip tag=latest-dev # please choose the image and tag name as per your choice +``` + +For a local run, tests creates two private geth networks and runs the tests on them. Running tests on testnet and mainnet is not supported yet for local docker tests and must be run in a kubernetes environment. + +1. [Setting the test inputs](#setup-the-tests) + 1. If required, create an `override.toml` with the required test inputs. If you want to run the tests with default parameters, you can skip this step. + 2. Create a TOML file with the secrets. +2. Run the following command to run the smoke tests with your custom override toml and secrets. + +```bash +# mark the testimage as empty for running the tests in local docker containers +make test_smoke_ccip testimage="" testname=TestSmokeCCIPForBidirectionalLane override_toml="" secret_toml="" +``` + +If you don't want to bother with any overrides, you can run with the default TOML settings with the below command. + +```bash +make test_smoke_ccip_default testname=TestSmokeCCIPForBidirectionalLane secret_toml="" +``` + +```mermaid +--- +title: Basic Docker Test Environment +--- +flowchart + subgraph SD[DON] + CL1[Node 1] + CL2[Node 2] + CL3[Node 3] + CL4[Node 4] + CL5[Node 5] + CL6[Node 6] + CL1---CL2 + CL2---CL3 + CL3---CL4 + CL4---CL5 + CL5---CL6 + end + subgraph Chains + SC1[[Private Chain 1]] + SC2[[Private Chain 2]] + end + SC1<-->SD + SC2<-->SD + MS([Mock Server]) + MS-->SD + TC[/Test Code\] + TC<-->MS + TC<-->Chains + TC<-->SD +``` + +### Using Remote Kubernetes Cluster + +For running more complex and intensive tests (like load and chaos tests) you need to connect the test to a Kubernetes cluster. These tests have more complex setup and running instructions. We endeavor to make these easier to run and configure, but for the time being please seek a member of the QA/Test Tooling team if you want to run these. diff --git a/integration-tests/ccip-tests/actions/ccip_helpers.go b/integration-tests/ccip-tests/actions/ccip_helpers.go new file mode 100644 index 0000000000..7594a9dc44 --- /dev/null +++ b/integration-tests/ccip-tests/actions/ccip_helpers.go @@ -0,0 +1,4380 @@ +package actions + +import ( + "context" + crypto_rand "crypto/rand" + "encoding/base64" + "encoding/json" + "fmt" + "math/big" + "net/http" + "runtime" + "strings" + "sync" + "testing" + "time" + + "dario.cat/mergo" + "github.com/AlekSi/pointer" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/pkg/errors" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/atomic" + "golang.org/x/exp/rand" + "golang.org/x/sync/errgroup" + + "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + + chainselectors "github.com/smartcontractkit/chain-selectors" + + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" + ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/foundry" + "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/mockserver" + "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/reorg" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts/laneconfig" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testreporters" + testutils "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/utils" + "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_pool" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" + integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/integration" + bigmath "github.com/smartcontractkit/chainlink/v2/core/utils/big_math" +) + +const ( + ChaosGroupExecution = "ExecutionNodesAll" // all execution nodes + ChaosGroupCommit = "CommitNodesAll" // all commit nodes + ChaosGroupCommitFaultyPlus = "CommitMajority" // >f number of nodes + ChaosGroupCommitFaulty = "CommitMinority" // f number of nodes + ChaosGroupExecutionFaultyPlus = "ExecutionNodesMajority" // > f number of nodes + ChaosGroupExecutionFaulty = "ExecutionNodesMinority" // f number of nodes + + ChaosGroupCommitAndExecFaulty = "CommitAndExecutionNodesMinority" // f number of nodes + ChaosGroupCommitAndExecFaultyPlus = "CommitAndExecutionNodesMajority" // >f number of nodes + ChaosGroupCCIPGeth = "CCIPGeth" // both source and destination simulated geth networks + ChaosGroupNetworkACCIPGeth = "CCIPNetworkAGeth" + ChaosGroupNetworkBCCIPGeth = "CCIPNetworkBGeth" + + defaultUSDCDestBytesOverhead = 640 + defaultUSDCDestGasOverhead = 150_000 + DefaultDestinationGasLimit = 600_000 + // DefaultResubscriptionTimeout denotes the max backoff duration for resubscription for various watch events + // if the subscription keeps failing even after this duration, the test will fail + DefaultResubscriptionTimeout = 2 * time.Hour +) + +// TODO: These should be refactored along with the default CCIP test setup to use optional config functions +var ( + // DefaultPermissionlessExecThreshold denotes how long the DON will retry a transaction before giving up, + // otherwise known as the "Smart Execution Time Window". If a transaction fails to execute within this time window, + // the DON will give up and the transaction will need Manual Execution as detailed here: https://docs.chain.link/ccip/concepts/manual-execution#manual-execution + // For performance tests: the higher the load/throughput, the higher value we might need here to guarantee that nonces are not blocked + // 1 day should be enough for most of the cases + DefaultPermissionlessExecThreshold = time.Hour * 8 + DefaultMaxNoOfTokensInMsg uint16 = 50 +) + +type CCIPTOMLEnv struct { + Networks []blockchain.EVMNetwork +} + +var ( + NetworkChart = reorg.TXNodesAppLabel + NetworkName = func(name string) string { + return strings.ReplaceAll(strings.ToLower(name), " ", "-") + } + InflightExpiryExec = 3 * time.Minute + InflightExpiryCommit = 3 * time.Minute + BatchGasLimit = uint32(7_000_000) + + MaxDataBytes = uint32(50_000) + + RootSnoozeTime = 3 * time.Minute + GethLabel = func(name string) string { + name = NetworkName(name) + switch NetworkChart { + case reorg.TXNodesAppLabel: + return fmt.Sprintf("%s-ethereum-geth", name) + case foundry.ChartName: + return name + } + return "" + } + // ApprovedAmountToRouter is the default amount which gets approved for router so that it can transfer token and use the fee token for fee payment + ApprovedAmountToRouter = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1)) + ApprovedFeeAmountToRouter = new(big.Int).Mul(big.NewInt(int64(GasFeeMultiplier)), big.NewInt(1e5)) + GasFeeMultiplier uint64 = 12e17 + LinkToUSD = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(20)) + WrappedNativeToUSD = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1.7e3)) +) + +func GetUSDCDomain(networkName string, simulated bool) (uint32, error) { + if simulated { + // generate a random domain for simulated networks + return rand.Uint32(), nil + } + lookup := map[string]uint32{ + networks.AvalancheFuji.Name: 1, + networks.OptimismGoerli.Name: 2, + networks.ArbitrumGoerli.Name: 3, + networks.BaseGoerli.Name: 6, + networks.PolygonMumbai.Name: 7, + } + if val, ok := lookup[networkName]; ok { + return val, nil + } + return 0, fmt.Errorf("USDC domain not found for chain %s", networkName) +} + +type CCIPCommon struct { + Logger *zerolog.Logger + ChainClient blockchain.EVMClient + // Deployer deploys all CCIP contracts + Deployer *contracts.CCIPContractsDeployer + // tokenDeployer is used exclusively for deploying self-serve tokens and their pools + tokenDeployer *contracts.CCIPContractsDeployer + FeeToken *contracts.LinkToken + BridgeTokens []*contracts.ERC20Token + PriceAggregators map[common.Address]*contracts.MockAggregator + NoOfTokensNeedingDynamicPrice int + BridgeTokenPools []*contracts.TokenPool + RateLimiterConfig contracts.RateLimiterConfig + ARMContract *common.Address + ARM *contracts.ARM // populate only if the ARM contracts is not a mock and can be used to verify various ARM events; keep this nil for mock ARM + Router *contracts.Router + PriceRegistry *contracts.PriceRegistry + TokenAdminRegistry *contracts.TokenAdminRegistry + WrappedNative common.Address + MulticallEnabled bool + MulticallContract common.Address + ExistingDeployment bool + USDCMockDeployment *bool + TokenMessenger *common.Address + TokenTransmitter *contracts.TokenTransmitter + IsConnectionRestoredRecently *atomic.Bool + + poolFunds *big.Int + tokenPriceUpdateWatcherMu *sync.Mutex + tokenPriceUpdateWatcher map[common.Address]*big.Int // key - token; value - timestamp of update + gasUpdateWatcherMu *sync.Mutex + gasUpdateWatcher map[uint64]*big.Int // key - destchain id; value - timestamp of update + GasUpdateEvents []contracts.GasUpdateEvent +} + +// FreeUpUnusedSpace sets nil to various elements of ccipModule which are only used +// during lane set up and not used for rest of the test duration +// this is called mainly by load test to keep the memory usage minimum for high number of lanes +func (ccipModule *CCIPCommon) FreeUpUnusedSpace() { + ccipModule.PriceAggregators = nil + ccipModule.BridgeTokenPools = nil + ccipModule.TokenMessenger = nil + ccipModule.TokenTransmitter = nil + runtime.GC() +} + +func (ccipModule *CCIPCommon) UnvoteToCurseARM() error { + if ccipModule.ARM != nil { + return fmt.Errorf("real ARM deployed. cannot curse through test") + } + if ccipModule.ARMContract == nil { + return fmt.Errorf("no ARM contract is set") + } + arm, err := mock_arm_contract.NewMockARMContract(*ccipModule.ARMContract, ccipModule.ChainClient.Backend()) + if err != nil { + return fmt.Errorf("error instantiating arm %w", err) + } + opts, err := ccipModule.ChainClient.TransactionOpts(ccipModule.ChainClient.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("error getting owners for ARM OwnerUnvoteToCurse %w", err) + } + tx, err := arm.OwnerUnvoteToCurse0(opts, []mock_arm_contract.RMNUnvoteToCurseRecord{}) + if err != nil { + return fmt.Errorf("error in calling OwnerUnvoteToCurse %w", err) + } + err = ccipModule.ChainClient.ProcessTransaction(tx) + if err != nil { + return err + } + log.Info(). + Str("ARM", arm.Address().Hex()). + Msg("ARM is uncursed") + return ccipModule.ChainClient.WaitForEvents() +} + +func (ccipModule *CCIPCommon) IsCursed() (bool, error) { + if ccipModule.ARM != nil { + return false, fmt.Errorf("real ARM deployed. cannot validate cursing") + } + if ccipModule.ARMContract == nil { + return false, fmt.Errorf("no ARM contract is set") + } + arm, err := mock_arm_contract.NewMockARMContract(*ccipModule.ARMContract, ccipModule.ChainClient.Backend()) + if err != nil { + return false, fmt.Errorf("error instantiating arm %w", err) + } + return arm.IsCursed0(nil) +} + +func (ccipModule *CCIPCommon) CurseARM() (*types.Transaction, error) { + if ccipModule.ARM != nil { + return nil, fmt.Errorf("real ARM deployed. cannot curse through test") + } + if ccipModule.ARMContract == nil { + return nil, fmt.Errorf("no ARM contract is set") + } + arm, err := mock_arm_contract.NewMockARMContract(*ccipModule.ARMContract, ccipModule.ChainClient.Backend()) + if err != nil { + return nil, fmt.Errorf("error instantiating arm %w", err) + } + opts, err := ccipModule.ChainClient.TransactionOpts(ccipModule.ChainClient.GetDefaultWallet()) + if err != nil { + return nil, fmt.Errorf("error getting owners for ARM VoteToCurse %w", err) + } + tx, err := arm.VoteToCurse(opts, [32]byte{}) + if err != nil { + return nil, fmt.Errorf("error in calling VoteToCurse %w", err) + } + err = ccipModule.ChainClient.ProcessTransaction(tx) + if err != nil { + return tx, err + } + log.Info(). + Str("ARM", arm.Address().Hex()). + Str("Network", ccipModule.ChainClient.GetNetworkName()). + Msg("ARM is cursed") + return tx, ccipModule.ChainClient.WaitForEvents() +} + +func (ccipModule *CCIPCommon) LoadContractAddresses(conf *laneconfig.LaneConfig, noOfTokens *int) { + if conf != nil { + if common.IsHexAddress(conf.FeeToken) { + ccipModule.FeeToken = &contracts.LinkToken{ + EthAddress: common.HexToAddress(conf.FeeToken), + } + } + if conf.IsNativeFeeToken { + ccipModule.FeeToken = &contracts.LinkToken{ + EthAddress: common.HexToAddress("0x0"), + } + } + + if common.IsHexAddress(conf.Router) { + ccipModule.Router = &contracts.Router{ + EthAddress: common.HexToAddress(conf.Router), + } + } + if common.IsHexAddress(conf.ARM) { + addr := common.HexToAddress(conf.ARM) + ccipModule.ARMContract = &addr + if !conf.IsMockARM { + ccipModule.ARM = &contracts.ARM{ + EthAddress: addr, + } + } + } + if common.IsHexAddress(conf.PriceRegistry) { + ccipModule.PriceRegistry = &contracts.PriceRegistry{ + EthAddress: common.HexToAddress(conf.PriceRegistry), + } + } + if common.IsHexAddress(conf.WrappedNative) { + ccipModule.WrappedNative = common.HexToAddress(conf.WrappedNative) + } + if common.IsHexAddress(conf.Multicall) { + ccipModule.MulticallContract = common.HexToAddress(conf.Multicall) + } + if common.IsHexAddress(conf.TokenMessenger) { + addr := common.HexToAddress(conf.TokenMessenger) + ccipModule.TokenMessenger = &addr + } + if common.IsHexAddress(conf.TokenTransmitter) { + ccipModule.TokenTransmitter = &contracts.TokenTransmitter{ + ContractAddress: common.HexToAddress(conf.TokenTransmitter), + } + } + if len(conf.BridgeTokens) > 0 { + // if noOfTokens is set, then only take that many tokens from the list + // the lane config can have more tokens than required for the test + if noOfTokens != nil { + if len(conf.BridgeTokens) > *noOfTokens { + conf.BridgeTokens = conf.BridgeTokens[:*noOfTokens] + } + } + var tokens []*contracts.ERC20Token + for _, token := range conf.BridgeTokens { + if common.IsHexAddress(token) { + tokens = append(tokens, &contracts.ERC20Token{ + ContractAddress: common.HexToAddress(token), + }) + } + } + ccipModule.BridgeTokens = tokens + } + if len(conf.BridgeTokenPools) > 0 { + // if noOfTokens is set, then only take that many tokenpools from the list + // the lane config can have more tokenpools than required for the test + if noOfTokens != nil { + if len(conf.BridgeTokenPools) > *noOfTokens { + conf.BridgeTokenPools = conf.BridgeTokenPools[:*noOfTokens] + } + } + var pools []*contracts.TokenPool + for _, pool := range conf.BridgeTokenPools { + if common.IsHexAddress(pool) { + pools = append(pools, &contracts.TokenPool{ + EthAddress: common.HexToAddress(pool), + }) + } + } + ccipModule.BridgeTokenPools = pools + } + if len(conf.PriceAggregators) > 0 { + priceAggrs := make(map[common.Address]*contracts.MockAggregator) + for token, aggr := range conf.PriceAggregators { + if common.IsHexAddress(aggr) { + priceAggrs[common.HexToAddress(token)] = &contracts.MockAggregator{ + ContractAddress: common.HexToAddress(aggr), + } + } + } + ccipModule.PriceAggregators = priceAggrs + } + if common.IsHexAddress(conf.TokenAdminRegistry) { + ccipModule.TokenAdminRegistry = &contracts.TokenAdminRegistry{ + EthAddress: common.HexToAddress(conf.TokenAdminRegistry), + } + } + } +} + +// ApproveTokens approves tokens for the router to send usually a massive amount of tokens enough to cover all the ccip transfers +// to be triggered by the test. +// Also, if the test is using self-serve tokens and pools deployed by a separate `tokenDeployer` address, this sends some of those tokens +// to the default `ccipOwner` address to be used for the test. +func (ccipModule *CCIPCommon) ApproveTokens() error { + isApproved := false + for _, token := range ccipModule.BridgeTokens { + // TODO: We send half of token funds back to the CCIP Deployer account, which isn't particularly realistic. + // See CCIP-2477 + if token.OwnerWallet.Address() != ccipModule.ChainClient.GetDefaultWallet().Address() && + !ccipModule.ExistingDeployment { + tokenBalance, err := token.BalanceOf(context.Background(), token.OwnerWallet.Address()) + if err != nil { + return fmt.Errorf("failed to get balance of token %s: %w", token.ContractAddress.Hex(), err) + } + tokenBalance.Div(tokenBalance, big.NewInt(2)) // Send half of the balance to the default wallet + err = token.Transfer(token.OwnerWallet, ccipModule.ChainClient.GetDefaultWallet().Address(), tokenBalance) + if err != nil { + return fmt.Errorf("failed to transfer token from '%s' to '%s' %s: %w", + token.ContractAddress.Hex(), token.OwnerAddress.Hex(), ccipModule.ChainClient.GetDefaultWallet().Address(), err, + ) + } + } + + err := token.Approve(ccipModule.ChainClient.GetDefaultWallet(), ccipModule.Router.Address(), ApprovedAmountToRouter) + if err != nil { + return fmt.Errorf("failed to approve token %s: %w", token.ContractAddress.Hex(), err) + } + if token.ContractAddress == ccipModule.FeeToken.EthAddress { + isApproved = true + } + } + if ccipModule.FeeToken.EthAddress != common.HexToAddress("0x0") { + amount := ApprovedFeeAmountToRouter + if isApproved { + amount = new(big.Int).Add(ApprovedAmountToRouter, ApprovedFeeAmountToRouter) + } + allowance, err := ccipModule.FeeToken.Allowance(ccipModule.ChainClient.GetDefaultWallet().Address(), ccipModule.Router.Address()) + if err != nil { + return fmt.Errorf("failed to get allowance for token %s: %w", ccipModule.FeeToken.Address(), err) + } + if allowance.Cmp(amount) < 0 { + err := ccipModule.FeeToken.Approve(ccipModule.Router.Address(), amount) + if err != nil { + return fmt.Errorf("failed to approve fee token %s: %w", ccipModule.FeeToken.EthAddress.String(), err) + } + } + } + ccipModule.Logger.Info().Msg("Tokens approved") + + return nil +} + +func (ccipModule *CCIPCommon) CleanUp() error { + if !ccipModule.ExistingDeployment { + for i, pool := range ccipModule.BridgeTokenPools { + if !pool.IsLockRelease() { + continue + } + bal, err := ccipModule.BridgeTokens[i].BalanceOf(context.Background(), pool.Address()) + if err != nil { + return fmt.Errorf("error in getting pool balance %w", err) + } + if bal.Cmp(big.NewInt(0)) == 0 { + continue + } + err = pool.RemoveLiquidity(bal) + if err != nil { + return fmt.Errorf("error in removing liquidity %w", err) + } + } + err := ccipModule.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("error in waiting for events %wfmt.Sprintf(\"Setting mockserver response\")", err) + } + } + return nil +} + +func (ccipModule *CCIPCommon) WaitForPriceUpdates( + ctx context.Context, + lggr *zerolog.Logger, + timeout time.Duration, + destChainId uint64, + allTokens []common.Address, +) error { + destChainSelector, err := chainselectors.SelectorFromChainId(destChainId) + if err != nil { + return err + } + // check if price is already updated + price, err := ccipModule.PriceRegistry.Instance.GetDestinationChainGasPrice(nil, destChainSelector) + if err != nil { + return err + } + + if price.Timestamp > 0 && price.Value.Cmp(big.NewInt(0)) > 0 { + lggr.Info(). + Str("Price Registry", ccipModule.PriceRegistry.Address()). + Uint64("dest chain", destChainId). + Str("source chain", ccipModule.ChainClient.GetNetworkName()). + Msg("Price already updated") + return nil + } + // if not, wait for price update + lggr.Info().Msgf("Waiting for UsdPerUnitGas and UsdPerTokenUpdated for dest chain %d Price Registry %s", destChainId, ccipModule.PriceRegistry.Address()) + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + localCtx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + var tokensMissingForUpdate common.Address + for { + select { + case <-ticker.C: + ccipModule.gasUpdateWatcherMu.Lock() + timestampOfUpdate, ok := ccipModule.gasUpdateWatcher[destChainId] + ccipModule.gasUpdateWatcherMu.Unlock() + tokenPricesUpdated := false + if len(allTokens) > 0 { + ccipModule.tokenPriceUpdateWatcherMu.Lock() + for _, token := range allTokens { + timestampOfTokenUpdate, okToken := ccipModule.tokenPriceUpdateWatcher[token] + // we consider token prices updated only if all tokens have been updated + // if any token is missing, we retry + if !okToken || timestampOfTokenUpdate.Cmp(big.NewInt(0)) < 1 { + tokenPricesUpdated = false + tokensMissingForUpdate = token + break + } + tokenPricesUpdated = true + } + ccipModule.tokenPriceUpdateWatcherMu.Unlock() + } + + if tokenPricesUpdated && ok && timestampOfUpdate.Cmp(big.NewInt(0)) == 1 { + lggr.Info(). + Str("Price Registry", ccipModule.PriceRegistry.Address()). + Uint64("dest chain", destChainId). + Str("source chain", ccipModule.ChainClient.GetNetworkName()). + Msg("Price updated") + return nil + } + case <-localCtx.Done(): + if tokensMissingForUpdate != (common.Address{}) { + return fmt.Errorf("price Updates not found for token %s", tokensMissingForUpdate.Hex()) + } + return fmt.Errorf("price Updates not found for chain %d", destChainId) + } + } +} + +// WatchForPriceUpdates helps to ensure the price updates are happening in price registry by subscribing to a couple +// of price update events and add the event details to watchers. It subscribes to 'UsdPerUnitGasUpdated' +// and 'UsdPerTokenUpdated' event. +func (ccipModule *CCIPCommon) WatchForPriceUpdates(ctx context.Context, lggr *zerolog.Logger) error { + gasUpdateEventLatest := make(chan *price_registry.PriceRegistryUsdPerUnitGasUpdated) + tokenUpdateEvent := make(chan *price_registry.PriceRegistryUsdPerTokenUpdated) + sub := event.Resubscribe(DefaultResubscriptionTimeout, func(_ context.Context) (event.Subscription, error) { + lggr.Info().Msg("Subscribing to UsdPerUnitGasUpdated event") + eventSub, err := ccipModule.PriceRegistry.WatchUsdPerUnitGasUpdated(nil, gasUpdateEventLatest, nil) + if err != nil { + log.Error().Err(err).Msg("error in subscribing to UsdPerUnitGasUpdated event") + } + return eventSub, err + }) + if sub == nil { + return fmt.Errorf("no event subscription found") + } + tokenUpdateSub := event.Resubscribe(DefaultResubscriptionTimeout, func(_ context.Context) (event.Subscription, error) { + lggr.Info().Msg("Subscribing to UsdPerTokenUpdated event") + eventSub, err := ccipModule.PriceRegistry.WatchUsdPerTokenUpdated(nil, tokenUpdateEvent) + if err != nil { + log.Error().Err(err).Msg("error in subscribing to UsdPerTokenUpdated event") + } + return eventSub, err + }) + if tokenUpdateSub == nil { + return fmt.Errorf("no event subscription found") + } + processEvent := func(value, timestamp *big.Int, destChainSelector uint64, raw types.Log) error { + destChain, err := chainselectors.ChainIdFromSelector(destChainSelector) + if err != nil { + return err + } + ccipModule.gasUpdateWatcherMu.Lock() + ccipModule.gasUpdateWatcher[destChain] = timestamp + + ccipModule.GasUpdateEvents = append(ccipModule.GasUpdateEvents, contracts.GasUpdateEvent{ + Sender: raw.Address.Hex(), + Tx: raw.TxHash.Hex(), + Value: value, + DestChain: destChain, + Source: ccipModule.ChainClient.GetNetworkName(), + }) + ccipModule.gasUpdateWatcherMu.Unlock() + lggr.Info(). + Uint64("chainSelector", destChainSelector). + Uint64("dest_chain", destChain). + Str("price_registry", ccipModule.PriceRegistry.Address()). + Str("tx hash", raw.TxHash.Hex()). + Msgf("UsdPerUnitGasUpdated event received for dest chain: %d, source chain: %s", + destChain, ccipModule.ChainClient.GetNetworkName()) + return nil + } + go func() { + defer func() { + sub.Unsubscribe() + tokenUpdateSub.Unsubscribe() + ccipModule.gasUpdateWatcher = nil + ccipModule.gasUpdateWatcherMu = nil + ccipModule.GasUpdateEvents = nil + ccipModule.tokenPriceUpdateWatcher = nil + ccipModule.tokenPriceUpdateWatcherMu = nil + }() + for { + select { + case e := <-gasUpdateEventLatest: + err := processEvent(e.Value, e.Timestamp, e.DestChain, e.Raw) + if err != nil { + continue + } + case tk := <-tokenUpdateEvent: + ccipModule.tokenPriceUpdateWatcherMu.Lock() + ccipModule.tokenPriceUpdateWatcher[tk.Token] = tk.Timestamp + ccipModule.tokenPriceUpdateWatcherMu.Unlock() + lggr.Info(). + Str("token", tk.Token.Hex()). + Str("chain", ccipModule.ChainClient.GetNetworkName()). + Str("price_registry", ccipModule.PriceRegistry.Address()). + Msg("UsdPerTokenUpdated event received") + case <-ctx.Done(): + return + } + } + }() + + return nil +} + +// UpdateTokenPricesAtRegularInterval updates aggregator contract with updated answer at regular interval. +// At each iteration of ticker it chooses one of the aggregator contracts and updates its round answer. +func (ccipModule *CCIPCommon) UpdateTokenPricesAtRegularInterval(ctx context.Context, lggr *zerolog.Logger, interval time.Duration, conf *laneconfig.LaneConfig) error { + if ccipModule.ExistingDeployment { + return nil + } + var aggregators []*contracts.MockAggregator + for _, aggregatorContract := range conf.PriceAggregators { + contract, err := ccipModule.Deployer.NewMockAggregator(common.HexToAddress(aggregatorContract)) + if err != nil { + return err + } + aggregators = append(aggregators, contract) + } + go func(aggregators []*contracts.MockAggregator) { + rand.NewSource(uint64(time.Now().UnixNano())) + ticker := time.NewTicker(interval) + for { + select { + case <-ticker.C: + // randomly choose an aggregator contract from slice of aggregators + randomIndex := rand.Intn(len(aggregators)) + err := aggregators[randomIndex].UpdateRoundData(nil, ptr.Ptr(-5), ptr.Ptr(2)) + if err != nil { + lggr.Error().Err(err).Msg("error in updating round data") + continue + } + case <-ctx.Done(): + return + } + } + }(aggregators) + return nil +} + +// SyncUSDCDomain makes domain updates to Source usdc pool domain with - +// 1. USDC domain from destination chain's token transmitter contract +// 2. Destination pool address as allowed caller +func (ccipModule *CCIPCommon) SyncUSDCDomain(destTransmitter *contracts.TokenTransmitter, destPools []*contracts.TokenPool, destChainID uint64) error { + // if not USDC new deployment, return + // if existing deployment, consider that no syncing is required and return + if ccipModule.ExistingDeployment || !ccipModule.IsUSDCDeployment() { + return nil + } + if destTransmitter == nil { + return fmt.Errorf("invalid address") + } + destChainSelector, err := chainselectors.SelectorFromChainId(destChainID) + if err != nil { + return fmt.Errorf("invalid chain id %w", err) + } + + // sync USDC domain + for i, pool := range ccipModule.BridgeTokenPools { + if !pool.IsUSDC() { + continue + } + if destPools[i] == nil { + return fmt.Errorf("invalid pool address") + } + if !destPools[i].IsUSDC() { + return fmt.Errorf("corresponding dest pool is not USDC pool") + } + err = pool.SyncUSDCDomain(destTransmitter, destPools[i].EthAddress, destChainSelector) + if err != nil { + return err + } + err = destPools[i].MintUSDCToUSDCPool() + if err != nil { + return err + } + } + + return ccipModule.ChainClient.WaitForEvents() +} + +func (ccipModule *CCIPCommon) PollRPCConnection(ctx context.Context, lggr *zerolog.Logger) { + for { + select { + case reconnectTime := <-ccipModule.ChainClient.ConnectionRestored(): + if ccipModule.IsConnectionRestoredRecently == nil { + ccipModule.IsConnectionRestoredRecently = atomic.NewBool(true) + } else { + ccipModule.IsConnectionRestoredRecently.Store(true) + } + lggr.Info().Time("Restored At", reconnectTime).Str("Network", ccipModule.ChainClient.GetNetworkName()).Msg("Connection Restored") + case issueTime := <-ccipModule.ChainClient.ConnectionIssue(): + if ccipModule.IsConnectionRestoredRecently == nil { + ccipModule.IsConnectionRestoredRecently = atomic.NewBool(false) + } else { + ccipModule.IsConnectionRestoredRecently.Store(false) + } + lggr.Info().Time("Started At", issueTime).Str("Network", ccipModule.ChainClient.GetNetworkName()).Msg("RPC Disconnected") + case <-ctx.Done(): + return + } + } +} + +func (ccipModule *CCIPCommon) IsUSDCDeployment() bool { + return pointer.GetBool(ccipModule.USDCMockDeployment) +} + +func (ccipModule *CCIPCommon) WriteLaneConfig(conf *laneconfig.LaneConfig) { + var btAddresses, btpAddresses []string + priceAggrs := make(map[string]string) + for i, bt := range ccipModule.BridgeTokens { + btAddresses = append(btAddresses, bt.Address()) + btpAddresses = append(btpAddresses, ccipModule.BridgeTokenPools[i].Address()) + } + for k, v := range ccipModule.PriceAggregators { + priceAggrs[k.Hex()] = v.ContractAddress.Hex() + } + conf.CommonContracts = laneconfig.CommonContracts{ + FeeToken: ccipModule.FeeToken.Address(), + BridgeTokens: btAddresses, + BridgeTokenPools: btpAddresses, + ARM: ccipModule.ARMContract.Hex(), + Router: ccipModule.Router.Address(), + PriceRegistry: ccipModule.PriceRegistry.Address(), + PriceAggregators: priceAggrs, + WrappedNative: ccipModule.WrappedNative.Hex(), + Multicall: ccipModule.MulticallContract.Hex(), + } + if ccipModule.TokenAdminRegistry != nil { + conf.CommonContracts.TokenAdminRegistry = ccipModule.TokenAdminRegistry.Address() + } + if ccipModule.TokenTransmitter != nil { + conf.CommonContracts.TokenTransmitter = ccipModule.TokenTransmitter.ContractAddress.Hex() + } + if ccipModule.TokenMessenger != nil { + conf.CommonContracts.TokenMessenger = ccipModule.TokenMessenger.Hex() + } + if ccipModule.ARM == nil { + conf.CommonContracts.IsMockARM = true + } +} + +func (ccipModule *CCIPCommon) AddPriceAggregatorToken(token common.Address, initialAns *big.Int) error { + // check if dynamic price update is enabled + if ccipModule.NoOfTokensNeedingDynamicPrice <= 0 { + return nil + } + var err error + if aggregator, ok := ccipModule.PriceAggregators[token]; !ok { + ccipModule.PriceAggregators[token], err = ccipModule.Deployer.DeployMockAggregator(18, initialAns) + if err != nil { + return fmt.Errorf("deploying mock aggregator contract shouldn't fail %w", err) + } + } else { + ccipModule.PriceAggregators[token], err = ccipModule.Deployer.NewMockAggregator(aggregator.ContractAddress) + if err != nil { + return fmt.Errorf("error instantiating price aggregator for token %s", token.Hex()) + } + } + ccipModule.NoOfTokensNeedingDynamicPrice-- + return nil +} + +// DeployContracts deploys the contracts which are necessary in both source and dest chain +// This reuses common contracts for bidirectional lanes +func (ccipModule *CCIPCommon) DeployContracts( + noOfTokens int, + tokenDeployerFns []blockchain.ContractDeployer, + conf *laneconfig.LaneConfig, +) error { + var err error + cd := ccipModule.Deployer + + ccipModule.LoadContractAddresses(conf, &noOfTokens) + if ccipModule.ARM != nil { + arm, err := cd.NewARMContract(ccipModule.ARM.EthAddress) + if err != nil { + return fmt.Errorf("getting new ARM contract shouldn't fail %w", err) + } + ccipModule.ARM = arm + } else { + // deploy a mock ARM contract + if ccipModule.ARMContract == nil { + if ccipModule.ExistingDeployment { + return fmt.Errorf("ARM contract address is not provided in lane config") + } + ccipModule.ARMContract, err = cd.DeployMockARMContract() + if err != nil { + return fmt.Errorf("deploying mock ARM contract shouldn't fail %w", err) + } + err = ccipModule.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("error in waiting for mock ARM deployment %w", err) + } + } + } + if ccipModule.WrappedNative == common.HexToAddress("0x0") { + if ccipModule.ExistingDeployment { + return fmt.Errorf("wrapped native contract address is not provided in lane config") + } + weth9addr, err := cd.DeployWrappedNative() + if err != nil { + return fmt.Errorf("deploying wrapped native shouldn't fail %w", err) + } + err = ccipModule.AddPriceAggregatorToken(*weth9addr, WrappedNativeToUSD) + if err != nil { + return fmt.Errorf("deploying mock aggregator contract shouldn't fail %w", err) + } + err = ccipModule.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("waiting for deploying wrapped native shouldn't fail %w", err) + } + ccipModule.WrappedNative = *weth9addr + } + + if ccipModule.Router == nil { + if ccipModule.ExistingDeployment { + return fmt.Errorf("router contract address is not provided in lane config") + } + ccipModule.Router, err = cd.DeployRouter(ccipModule.WrappedNative, *ccipModule.ARMContract) + if err != nil { + return fmt.Errorf("deploying router shouldn't fail %w", err) + } + err = ccipModule.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("error in waiting for router deployment %w", err) + } + } else { + r, err := cd.NewRouter(ccipModule.Router.EthAddress) + if err != nil { + return fmt.Errorf("getting new router contract shouldn't fail %w", err) + } + ccipModule.Router = r + } + if ccipModule.FeeToken == nil { + if ccipModule.ExistingDeployment { + return fmt.Errorf("FeeToken contract address is not provided in lane config") + } + // deploy link token + token, err := cd.DeployLinkTokenContract() + if err != nil { + return fmt.Errorf("deploying fee token contract shouldn't fail %w", err) + } + + ccipModule.FeeToken = token + err = ccipModule.AddPriceAggregatorToken(ccipModule.FeeToken.EthAddress, LinkToUSD) + if err != nil { + return fmt.Errorf("deploying mock aggregator contract shouldn't fail %w", err) + } + err = ccipModule.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("error in waiting for feetoken deployment %w", err) + } + } else { + token, err := cd.NewLinkTokenContract(common.HexToAddress(ccipModule.FeeToken.Address())) + if err != nil { + return fmt.Errorf("getting fee token contract shouldn't fail %w", err) + } + ccipModule.FeeToken = token + } + + // If the number of deployed bridge tokens does not match noOfTokens, deploy rest of the tokens in case ExistingDeployment is false + // In case of ExistingDeployment as true use whatever is provided in laneconfig + if len(ccipModule.BridgeTokens) < noOfTokens && !ccipModule.ExistingDeployment { + // deploy bridge token. + for i := len(ccipModule.BridgeTokens); i < noOfTokens; i++ { + var token *contracts.ERC20Token + + if len(tokenDeployerFns) != noOfTokens { + if ccipModule.IsUSDCDeployment() && i == 0 { + // if it's USDC deployment, we deploy the burn mint token 677 with decimal 6 and cast it to ERC20Token + usdcToken, err := ccipModule.tokenDeployer.DeployBurnMintERC677(new(big.Int).Mul(big.NewInt(1e6), big.NewInt(1e18))) + if err != nil { + return fmt.Errorf("deploying bridge usdc token contract shouldn't fail %w", err) + } + token, err = ccipModule.tokenDeployer.NewERC20TokenContract(usdcToken.ContractAddress) + if err != nil { + return fmt.Errorf("getting new bridge usdc token contract shouldn't fail %w", err) + } + if ccipModule.TokenTransmitter == nil { + domain, err := GetUSDCDomain(ccipModule.ChainClient.GetNetworkName(), ccipModule.ChainClient.NetworkSimulated()) + if err != nil { + return fmt.Errorf("error in getting USDC domain %w", err) + } + + ccipModule.TokenTransmitter, err = ccipModule.tokenDeployer.DeployTokenTransmitter(domain, usdcToken.ContractAddress) + if err != nil { + return fmt.Errorf("deploying token transmitter shouldn't fail %w", err) + } + } + if ccipModule.TokenMessenger == nil { + if ccipModule.TokenTransmitter == nil { + return fmt.Errorf("TokenTransmitter contract address is not provided") + } + ccipModule.TokenMessenger, err = ccipModule.tokenDeployer.DeployTokenMessenger(ccipModule.TokenTransmitter.ContractAddress) + if err != nil { + return fmt.Errorf("deploying token messenger shouldn't fail %w", err) + } + err = ccipModule.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("error in waiting for mock TokenMessenger and Transmitter deployment %w", err) + } + } + + // grant minter role to token messenger + err = usdcToken.GrantMintAndBurn(*ccipModule.TokenMessenger) + if err != nil { + return fmt.Errorf("granting minter role to token messenger shouldn't fail %w", err) + } + err = usdcToken.GrantMintAndBurn(ccipModule.TokenTransmitter.ContractAddress) + if err != nil { + return fmt.Errorf("granting minter role to token transmitter shouldn't fail %w", err) + } + } else { + // otherwise we deploy link token and cast it to ERC20Token + linkToken, err := ccipModule.tokenDeployer.DeployLinkTokenContract() + if err != nil { + return fmt.Errorf("deploying bridge token contract shouldn't fail %w", err) + } + token, err = ccipModule.tokenDeployer.NewERC20TokenContract(common.HexToAddress(linkToken.Address())) + if err != nil { + return fmt.Errorf("getting new bridge token contract shouldn't fail %w", err) + } + err = ccipModule.AddPriceAggregatorToken(linkToken.EthAddress, LinkToUSD) + if err != nil { + return fmt.Errorf("deploying mock aggregator contract shouldn't fail %w", err) + } + } + } else { + token, err = ccipModule.tokenDeployer.DeployERC20TokenContract(tokenDeployerFns[i]) + if err != nil { + return fmt.Errorf("deploying bridge token contract shouldn't fail %w", err) + } + err = ccipModule.AddPriceAggregatorToken(token.ContractAddress, LinkToUSD) + if err != nil { + return fmt.Errorf("deploying mock aggregator contract shouldn't fail %w", err) + } + } + ccipModule.BridgeTokens = append(ccipModule.BridgeTokens, token) + + } + if err = ccipModule.ChainClient.WaitForEvents(); err != nil { + return fmt.Errorf("error in waiting for bridge token deployment %w", err) + } + } + + var tokens []*contracts.ERC20Token + for _, token := range ccipModule.BridgeTokens { + newToken, err := ccipModule.tokenDeployer.NewERC20TokenContract(common.HexToAddress(token.Address())) + if err != nil { + return fmt.Errorf("getting new bridge token contract shouldn't fail %w", err) + } + tokens = append(tokens, newToken) + } + ccipModule.BridgeTokens = tokens + if len(ccipModule.BridgeTokenPools) != len(ccipModule.BridgeTokens) { + if ccipModule.ExistingDeployment { + return fmt.Errorf("bridge token pool contract address is not provided in lane config") + } + // deploy native token pool + for i := len(ccipModule.BridgeTokenPools); i < len(ccipModule.BridgeTokens); i++ { + token := ccipModule.BridgeTokens[i] + // usdc pool need to be the first one in the slice + if ccipModule.IsUSDCDeployment() && i == 0 { + // deploy usdc token pool in case of usdc deployment + if ccipModule.TokenMessenger == nil { + return fmt.Errorf("TokenMessenger contract address is not provided") + } + if ccipModule.TokenTransmitter == nil { + return fmt.Errorf("TokenTransmitter contract address is not provided") + } + usdcPool, err := ccipModule.tokenDeployer.DeployUSDCTokenPoolContract(token.Address(), *ccipModule.TokenMessenger, *ccipModule.ARMContract, ccipModule.Router.Instance.Address()) + if err != nil { + return fmt.Errorf("deploying bridge Token pool(usdc) shouldn't fail %w", err) + } + + ccipModule.BridgeTokenPools = append(ccipModule.BridgeTokenPools, usdcPool) + } else { + // deploy lock release token pool in case of non-usdc deployment + btp, err := ccipModule.tokenDeployer.DeployLockReleaseTokenPoolContract(token.Address(), *ccipModule.ARMContract, ccipModule.Router.Instance.Address()) + if err != nil { + return fmt.Errorf("deploying bridge Token pool(lock&release) shouldn't fail %w", err) + } + ccipModule.BridgeTokenPools = append(ccipModule.BridgeTokenPools, btp) + + err = btp.AddLiquidity(token, token.OwnerWallet, ccipModule.poolFunds) + if err != nil { + return fmt.Errorf("adding liquidity token to dest pool shouldn't fail %w", err) + } + } + } + } else { + var pools []*contracts.TokenPool + for _, pool := range ccipModule.BridgeTokenPools { + newPool, err := ccipModule.tokenDeployer.NewLockReleaseTokenPoolContract(pool.EthAddress) + if err != nil { + return fmt.Errorf("getting new bridge token pool contract shouldn't fail %w", err) + } + pools = append(pools, newPool) + } + ccipModule.BridgeTokenPools = pools + } + + // no need to have price registry for existing deployment, we consider that it's already deployed + if !ccipModule.ExistingDeployment { + if ccipModule.PriceRegistry == nil { + // we will update the price updates later based on source and dest PriceUpdates + ccipModule.PriceRegistry, err = cd.DeployPriceRegistry( + []common.Address{ + common.HexToAddress(ccipModule.FeeToken.Address()), + common.HexToAddress(ccipModule.WrappedNative.Hex()), + }) + if err != nil { + return fmt.Errorf("deploying PriceRegistry shouldn't fail %w", err) + } + err = ccipModule.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("error in waiting for PriceRegistry deployment %w", err) + } + } else { + ccipModule.PriceRegistry, err = cd.NewPriceRegistry(ccipModule.PriceRegistry.EthAddress) + if err != nil { + return fmt.Errorf("getting new PriceRegistry contract shouldn't fail %w", err) + } + } + } + if ccipModule.MulticallContract == (common.Address{}) && ccipModule.MulticallEnabled { + ccipModule.MulticallContract, err = cd.DeployMultiCallContract() + if err != nil { + return fmt.Errorf("deploying multicall contract shouldn't fail %w", err) + } + } + + // if the version is after 1.4.0, we need to deploy TokenAdminRegistry + // no need to have token admin registry for existing deployment, we consider that it's already deployed + if contracts.NeedTokenAdminRegistry() && !ccipModule.ExistingDeployment { + if ccipModule.TokenAdminRegistry == nil { + // deploy token admin registry + ccipModule.TokenAdminRegistry, err = cd.DeployTokenAdminRegistry() + if err != nil { + return fmt.Errorf("deploying token admin registry shouldn't fail %w", err) + } + err = ccipModule.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("error in waiting for token admin registry deployment %w", err) + } + + if len(ccipModule.BridgeTokens) != len(ccipModule.BridgeTokenPools) { + return fmt.Errorf("tokens number %d and pools number %d do not match", len(ccipModule.BridgeTokens), len(ccipModule.BridgeTokenPools)) + } + // add all pools to registry + for i, pool := range ccipModule.BridgeTokenPools { + token := ccipModule.BridgeTokens[i] + err := ccipModule.TokenAdminRegistry.SetAdminAndRegisterPool(token.ContractAddress, pool.EthAddress) + if err != nil { + return fmt.Errorf("error setting up token %s and pool %s on TokenAdminRegistry : %w", token.Address(), pool.Address(), err) + } + } + err = ccipModule.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("error in waiting for token admin registry set up with tokens and pools %w", err) + } + } else { + ccipModule.TokenAdminRegistry, err = cd.NewTokenAdminRegistry(ccipModule.TokenAdminRegistry.EthAddress) + if err != nil { + return fmt.Errorf("getting new token admin registry contract shouldn't fail %w", err) + } + } + } + ccipModule.Logger.Info().Msg("Finished deploying common contracts") + // approve router to spend fee token + return ccipModule.ApproveTokens() +} + +func (ccipModule *CCIPCommon) AvgBlockTime(ctx context.Context) (time.Duration, error) { + return ccipModule.ChainClient.AvgBlockTime(ctx) +} + +// DynamicPriceGetterConfig specifies the configuration for the price getter in price pipeline. +// This should match pricegetter.DynamicPriceGetterConfig in core/services/ocr2/plugins/ccip/internal/pricegetter +type DynamicPriceGetterConfig struct { + AggregatorPrices map[common.Address]AggregatorPriceConfig `json:"aggregatorPrices"` + StaticPrices map[common.Address]StaticPriceConfig `json:"staticPrices"` +} + +func (d *DynamicPriceGetterConfig) AddPriceConfig( + tokenAddr string, + aggregatorMap map[common.Address]*contracts.MockAggregator, + price *big.Int, + chainID uint64, +) error { + aggregatorContract, ok := aggregatorMap[common.HexToAddress(tokenAddr)] + if !ok || aggregatorContract == nil { + return d.AddStaticPriceConfig(tokenAddr, chainID, price) + } + return d.AddAggregatorPriceConfig(tokenAddr, aggregatorMap, price) +} + +func (d *DynamicPriceGetterConfig) AddAggregatorPriceConfig( + tokenAddr string, + aggregatorMap map[common.Address]*contracts.MockAggregator, + price *big.Int, +) error { + aggregatorContract, ok := aggregatorMap[common.HexToAddress(tokenAddr)] + if !ok || aggregatorContract == nil { + return fmt.Errorf("aggregator contract not found for token %s", tokenAddr) + } + // update round Data + err := aggregatorContract.UpdateRoundData(price, nil, nil) + if err != nil { + return fmt.Errorf("error in updating round data %w", err) + } + + d.AggregatorPrices[common.HexToAddress(tokenAddr)] = AggregatorPriceConfig{ + ChainID: aggregatorContract.ChainID(), + AggregatorContractAddress: aggregatorContract.ContractAddress, + } + return nil +} + +func (d *DynamicPriceGetterConfig) AddStaticPriceConfig(tokenAddr string, chainID uint64, price *big.Int) error { + d.StaticPrices[common.HexToAddress(tokenAddr)] = StaticPriceConfig{ + ChainID: chainID, + Price: price, + } + return nil +} + +func (d *DynamicPriceGetterConfig) String() (string, error) { + tokenPricesConfigBytes, err := json.MarshalIndent(d, "", " ") + if err != nil { + return "", fmt.Errorf("error in marshalling token prices config %w", err) + } + return string(tokenPricesConfigBytes), nil +} + +// AggregatorPriceConfig specifies a price retrieved from an aggregator contract. +// This should match pricegetter.AggregatorPriceConfig in core/services/ocr2/plugins/ccip/internal/pricegetter +type AggregatorPriceConfig struct { + ChainID uint64 `json:"chainID,string"` + AggregatorContractAddress common.Address `json:"contractAddress"` +} + +// StaticPriceConfig specifies a price defined statically. +// This should match pricegetter.StaticPriceConfig in core/services/ocr2/plugins/ccip/internal/pricegetter +type StaticPriceConfig struct { + ChainID uint64 `json:"chainID,string"` + Price *big.Int `json:"price"` +} + +func NewCCIPCommonFromConfig( + logger *zerolog.Logger, + testGroupConf *testconfig.CCIPTestGroupConfig, + chainClient blockchain.EVMClient, + laneConfig *laneconfig.LaneConfig, +) (*CCIPCommon, error) { + newCCIPModule, err := DefaultCCIPModule(logger, testGroupConf, chainClient) + if err != nil { + return nil, err + } + newCD := newCCIPModule.Deployer + newCCIPModule.LoadContractAddresses(laneConfig, testGroupConf.TokenConfig.NoOfTokensPerChain) + if newCCIPModule.TokenAdminRegistry != nil { + newCCIPModule.TokenAdminRegistry, err = newCD.NewTokenAdminRegistry(common.HexToAddress(newCCIPModule.TokenAdminRegistry.Address())) + if err != nil { + return nil, err + } + } + var arm *contracts.ARM + if newCCIPModule.ARM != nil { + arm, err = newCD.NewARMContract(*newCCIPModule.ARMContract) + if err != nil { + return nil, err + } + newCCIPModule.ARM = arm + } + var pools []*contracts.TokenPool + for i := range newCCIPModule.BridgeTokenPools { + // if there is usdc token, the corresponding pool will always be added as first one in the slice + if newCCIPModule.IsUSDCDeployment() && i == 0 { + pool, err := newCCIPModule.tokenDeployer.NewUSDCTokenPoolContract(common.HexToAddress(newCCIPModule.BridgeTokenPools[i].Address())) + if err != nil { + return nil, err + } + pools = append(pools, pool) + } else { + pool, err := newCCIPModule.tokenDeployer.NewLockReleaseTokenPoolContract(common.HexToAddress(newCCIPModule.BridgeTokenPools[i].Address())) + if err != nil { + return nil, err + } + pools = append(pools, pool) + } + } + newCCIPModule.BridgeTokenPools = pools + var tokens []*contracts.ERC20Token + for i := range newCCIPModule.BridgeTokens { + token, err := newCCIPModule.tokenDeployer.NewERC20TokenContract(common.HexToAddress(newCCIPModule.BridgeTokens[i].Address())) + if err != nil { + return nil, err + } + tokens = append(tokens, token) + } + newCCIPModule.BridgeTokens = tokens + priceAggregators := make(map[common.Address]*contracts.MockAggregator) + for k, v := range newCCIPModule.PriceAggregators { + aggregator, err := newCD.NewMockAggregator(v.ContractAddress) + if err != nil { + return nil, err + } + priceAggregators[k] = aggregator + } + newCCIPModule.PriceAggregators = priceAggregators + newCCIPModule.FeeToken, err = newCCIPModule.Deployer.NewLinkTokenContract(common.HexToAddress(newCCIPModule.FeeToken.Address())) + if err != nil { + return nil, err + } + if newCCIPModule.PriceRegistry != nil { + newCCIPModule.PriceRegistry, err = newCCIPModule.Deployer.NewPriceRegistry(common.HexToAddress(newCCIPModule.PriceRegistry.Address())) + if err != nil { + return nil, err + } + } + newCCIPModule.Router, err = newCCIPModule.Deployer.NewRouter(common.HexToAddress(newCCIPModule.Router.Address())) + if err != nil { + return nil, err + } + if newCCIPModule.TokenTransmitter != nil { + newCCIPModule.TokenTransmitter, err = newCCIPModule.Deployer.NewTokenTransmitter(newCCIPModule.TokenTransmitter.ContractAddress) + if err != nil { + return nil, err + } + } + return newCCIPModule, nil +} + +func DefaultCCIPModule( + logger *zerolog.Logger, + testGroupConf *testconfig.CCIPTestGroupConfig, + chainClient blockchain.EVMClient, +) (*CCIPCommon, error) { + networkCfg := chainClient.GetNetworkConfig() + tokenDeployerChainClient, err := blockchain.ConcurrentEVMClient(*networkCfg, nil, chainClient, *logger) + if err != nil { + return nil, errors.WithStack(fmt.Errorf("failed to create token deployment chain client for %s: %w", networkCfg.Name, err)) + } + // If we want to deploy tokens as a non CCIP owner, we need to set the default wallet to something other than the first one. The first wallet is used as default CCIP owner for all other ccip contract deployment. + // This is not needed for existing deployment as the tokens and pools are already deployed. + if contracts.NeedTokenAdminRegistry() && + !pointer.GetBool(testGroupConf.TokenConfig.CCIPOwnerTokens) && + !pointer.GetBool(testGroupConf.ExistingDeployment) && + len(tokenDeployerChainClient.GetWallets()) > 1 { + if err = tokenDeployerChainClient.SetDefaultWallet(1); err != nil { + return nil, errors.WithStack(fmt.Errorf("failed to set default wallet for token deployment client %s: %w", networkCfg.Name, err)) + } + } + cd, err := contracts.NewCCIPContractsDeployer(logger, chainClient) + if err != nil { + return nil, err + } + tokenCD, err := contracts.NewCCIPContractsDeployer(logger, tokenDeployerChainClient) + if err != nil { + return nil, err + } + return &CCIPCommon{ + Logger: logger, + ChainClient: chainClient, + Deployer: cd, + tokenDeployer: tokenCD, + RateLimiterConfig: contracts.RateLimiterConfig{ + Rate: contracts.FiftyCoins, + Capacity: contracts.HundredCoins, + }, + ExistingDeployment: pointer.GetBool(testGroupConf.ExistingDeployment), + MulticallEnabled: pointer.GetBool(testGroupConf.MulticallInOneTx), + USDCMockDeployment: testGroupConf.USDCMockDeployment, + NoOfTokensNeedingDynamicPrice: pointer.GetInt(testGroupConf.TokenConfig.NoOfTokensWithDynamicPrice), + poolFunds: testhelpers.Link(5), + gasUpdateWatcherMu: &sync.Mutex{}, + gasUpdateWatcher: make(map[uint64]*big.Int), + tokenPriceUpdateWatcherMu: &sync.Mutex{}, + tokenPriceUpdateWatcher: make(map[common.Address]*big.Int), + PriceAggregators: make(map[common.Address]*contracts.MockAggregator), + }, nil +} + +type SourceCCIPModule struct { + Common *CCIPCommon + Sender common.Address + TransferAmount []*big.Int + MsgDataLength int64 + DestinationChainId uint64 + DestChainSelector uint64 + DestNetworkName string + OnRamp *contracts.OnRamp + SrcStartBlock uint64 + CCIPSendRequestedWatcher *sync.Map // map[string]*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested + NewFinalizedBlockNum atomic.Uint64 + NewFinalizedBlockTimestamp atomic.Time +} + +func (sourceCCIP *SourceCCIPModule) PayCCIPFeeToOwnerAddress() error { + isNativeFee := sourceCCIP.Common.FeeToken.EthAddress == common.HexToAddress("0x0") + if isNativeFee { + err := sourceCCIP.OnRamp.WithdrawNonLinkFees(sourceCCIP.Common.WrappedNative) + if err != nil { + return err + } + } else { + err := sourceCCIP.OnRamp.SetNops() + if err != nil { + return err + } + err = sourceCCIP.OnRamp.PayNops() + if err != nil { + return err + } + } + return nil +} + +func (sourceCCIP *SourceCCIPModule) LoadContracts(conf *laneconfig.LaneConfig) { + if conf != nil { + cfg, ok := conf.SrcContracts[sourceCCIP.DestNetworkName] + if ok { + if common.IsHexAddress(cfg.OnRamp) { + sourceCCIP.OnRamp = &contracts.OnRamp{ + EthAddress: common.HexToAddress(cfg.OnRamp), + } + } + if cfg.DeployedAt > 0 { + sourceCCIP.SrcStartBlock = cfg.DeployedAt + } + } + } +} + +// SetAllTokenTransferFeeConfigs sets a default transfer fee config for all BridgeTokens on the CCIP source chain. +// enableAggregateRateLimit is used to enable/disable aggregate rate limit for all BridgeTokens. +func (sourceCCIP *SourceCCIPModule) SetAllTokenTransferFeeConfigs(enableAggregateRateLimit bool) error { + var tokenTransferFeeConfig []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs + var tokens, pools []common.Address + if len(sourceCCIP.Common.BridgeTokens) != len(sourceCCIP.Common.BridgeTokenPools) { + return fmt.Errorf("tokens number %d and pools number %d do not match", len(sourceCCIP.Common.BridgeTokens), len(sourceCCIP.Common.BridgeTokenPools)) + } + for i, token := range sourceCCIP.Common.BridgeTokens { + tokens = append(tokens, token.ContractAddress) + pools = append(pools, sourceCCIP.Common.BridgeTokenPools[i].EthAddress) + conf := evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + Token: token.ContractAddress, + MinFeeUSDCents: 50, // $0.5 + MaxFeeUSDCents: 1_000_000_00, // $ 1 million + DeciBps: 5_0, // 5 bps + AggregateRateLimitEnabled: enableAggregateRateLimit, + } + if sourceCCIP.Common.BridgeTokenPools[i].IsUSDC() { + conf.DestBytesOverhead = defaultUSDCDestBytesOverhead + conf.DestGasOverhead = defaultUSDCDestGasOverhead + } + tokenTransferFeeConfig = append(tokenTransferFeeConfig, conf) + } + err := sourceCCIP.OnRamp.SetTokenTransferFeeConfig(tokenTransferFeeConfig) + if err != nil { + return fmt.Errorf("setting token transfer fee config shouldn't fail %w", err) + } + // this is required for v1.2.0 ramps + err = sourceCCIP.OnRamp.ApplyPoolUpdates(tokens, pools) + if err != nil { + return fmt.Errorf("applying pool updates shouldn't fail %w", err) + } + return nil +} + +// DeployContracts deploys all CCIP contracts specific to the source chain +func (sourceCCIP *SourceCCIPModule) DeployContracts(lane *laneconfig.LaneConfig) error { + var err error + contractDeployer := sourceCCIP.Common.Deployer + log.Info().Msg("Deploying source chain specific contracts") + + sourceCCIP.LoadContracts(lane) + sourceChainSelector, err := chainselectors.SelectorFromChainId(sourceCCIP.Common.ChainClient.GetChainID().Uint64()) + if err != nil { + return fmt.Errorf("getting chain selector shouldn't fail %w", err) + } + + if sourceCCIP.OnRamp == nil { + if sourceCCIP.Common.ExistingDeployment { + return fmt.Errorf("existing deployment is set to true but no onramp address is provided") + } + var tokensAndPools []evm_2_evm_onramp_1_2_0.InternalPoolUpdate + var tokenTransferFeeConfig []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs + + sourceCCIP.SrcStartBlock, err = sourceCCIP.Common.ChainClient.LatestBlockNumber(context.Background()) + if err != nil { + return fmt.Errorf("getting latest block number shouldn't fail %w", err) + } + var tokenAdminReg common.Address + if contracts.NeedTokenAdminRegistry() { + if sourceCCIP.Common.TokenAdminRegistry == nil { + return fmt.Errorf("token admin registry contract address is not provided in lane config") + } + tokenAdminReg = sourceCCIP.Common.TokenAdminRegistry.EthAddress + } + sourceCCIP.OnRamp, err = contractDeployer.DeployOnRamp( + sourceChainSelector, + sourceCCIP.DestChainSelector, + tokensAndPools, + *sourceCCIP.Common.ARMContract, + sourceCCIP.Common.Router.EthAddress, + sourceCCIP.Common.PriceRegistry.EthAddress, + tokenAdminReg, + sourceCCIP.Common.RateLimiterConfig, + []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ + { + Token: common.HexToAddress(sourceCCIP.Common.FeeToken.Address()), + NetworkFeeUSDCents: 1_00, + GasMultiplierWeiPerEth: GasFeeMultiplier, + PremiumMultiplierWeiPerEth: 1e18, + Enabled: true, + }, + { + Token: sourceCCIP.Common.WrappedNative, + NetworkFeeUSDCents: 1_00, + GasMultiplierWeiPerEth: GasFeeMultiplier, + PremiumMultiplierWeiPerEth: 1e18, + Enabled: true, + }, + }, tokenTransferFeeConfig, sourceCCIP.Common.FeeToken.EthAddress) + + if err != nil { + return fmt.Errorf("onRamp deployment shouldn't fail %w", err) + } + + err = sourceCCIP.Common.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("waiting for onRamp deployment shouldn't fail %w", err) + } + + // update source Router with OnRamp address + err = sourceCCIP.Common.Router.SetOnRamp(sourceCCIP.DestChainSelector, sourceCCIP.OnRamp.EthAddress) + if err != nil { + return fmt.Errorf("setting onramp on the router shouldn't fail %w", err) + } + // now sync the pools and tokens + err := sourceCCIP.SetAllTokenTransferFeeConfigs(true) + if err != nil { + return err + } + } else { + sourceCCIP.OnRamp, err = contractDeployer.NewOnRamp(sourceCCIP.OnRamp.EthAddress) + if err != nil { + return fmt.Errorf("getting new onramp contractshouldn't fail %w", err) + } + } + return nil +} + +func (sourceCCIP *SourceCCIPModule) CollectBalanceRequirements() []testhelpers.BalanceReq { + var balancesReq []testhelpers.BalanceReq + for _, token := range sourceCCIP.Common.BridgeTokens { + balancesReq = append(balancesReq, testhelpers.BalanceReq{ + Name: fmt.Sprintf("BridgeToken-%s-Address-%s", token.Address(), sourceCCIP.Sender.Hex()), + Addr: sourceCCIP.Sender, + Getter: GetterForLinkToken(token.BalanceOf, sourceCCIP.Sender.Hex()), + }) + } + for i, pool := range sourceCCIP.Common.BridgeTokenPools { + balancesReq = append(balancesReq, testhelpers.BalanceReq{ + Name: fmt.Sprintf("BridgeToken-%s-TokenPool-%s", sourceCCIP.Common.BridgeTokens[i].Address(), pool.Address()), + Addr: pool.EthAddress, + Getter: GetterForLinkToken(sourceCCIP.Common.BridgeTokens[i].BalanceOf, pool.Address()), + }) + } + + if sourceCCIP.Common.FeeToken.Address() != common.HexToAddress("0x0").String() { + balancesReq = append(balancesReq, testhelpers.BalanceReq{ + Name: fmt.Sprintf("FeeToken-%s-Address-%s", sourceCCIP.Common.FeeToken.Address(), sourceCCIP.Sender.Hex()), + Addr: sourceCCIP.Sender, + Getter: GetterForLinkToken(sourceCCIP.Common.FeeToken.BalanceOf, sourceCCIP.Sender.Hex()), + }) + balancesReq = append(balancesReq, testhelpers.BalanceReq{ + Name: fmt.Sprintf("FeeToken-%s-Router-%s", sourceCCIP.Common.FeeToken.Address(), sourceCCIP.Common.Router.Address()), + Addr: sourceCCIP.Common.Router.EthAddress, + Getter: GetterForLinkToken(sourceCCIP.Common.FeeToken.BalanceOf, sourceCCIP.Common.Router.Address()), + }) + balancesReq = append(balancesReq, testhelpers.BalanceReq{ + Name: fmt.Sprintf("FeeToken-%s-OnRamp-%s", sourceCCIP.Common.FeeToken.Address(), sourceCCIP.OnRamp.Address()), + Addr: sourceCCIP.OnRamp.EthAddress, + Getter: GetterForLinkToken(sourceCCIP.Common.FeeToken.BalanceOf, sourceCCIP.OnRamp.Address()), + }) + balancesReq = append(balancesReq, testhelpers.BalanceReq{ + Name: fmt.Sprintf("FeeToken-%s-Prices-%s", sourceCCIP.Common.FeeToken.Address(), sourceCCIP.Common.PriceRegistry.Address()), + Addr: sourceCCIP.Common.PriceRegistry.EthAddress, + Getter: GetterForLinkToken(sourceCCIP.Common.FeeToken.BalanceOf, sourceCCIP.Common.PriceRegistry.Address()), + }) + } + return balancesReq +} + +func (sourceCCIP *SourceCCIPModule) UpdateBalance( + noOfReq int64, + totalFee *big.Int, + balances *BalanceSheet, +) { + if len(sourceCCIP.TransferAmount) > 0 { + for i := range sourceCCIP.TransferAmount { + if sourceCCIP.TransferAmount[i] == nil { // nil transfer amount means no transfer for this token + continue + } + // if length of sourceCCIP.TransferAmount is more than available bridge token use first bridge token + token := sourceCCIP.Common.BridgeTokens[0] + if i < len(sourceCCIP.Common.BridgeTokens) { + token = sourceCCIP.Common.BridgeTokens[i] + } + name := fmt.Sprintf("BridgeToken-%s-Address-%s", token.Address(), sourceCCIP.Sender.Hex()) + balances.Update(name, BalanceItem{ + Address: sourceCCIP.Sender, + Getter: GetterForLinkToken(token.BalanceOf, sourceCCIP.Sender.Hex()), + AmtToSub: bigmath.Mul(big.NewInt(noOfReq), sourceCCIP.TransferAmount[i]), + }) + } + for i := range sourceCCIP.TransferAmount { + // if length of sourceCCIP.TransferAmount is more than available bridge token use first bridge token + pool := sourceCCIP.Common.BridgeTokenPools[0] + index := 0 + if i < len(sourceCCIP.Common.BridgeTokenPools) { + pool = sourceCCIP.Common.BridgeTokenPools[i] + index = i + } + + name := fmt.Sprintf("BridgeToken-%s-TokenPool-%s", sourceCCIP.Common.BridgeTokens[index].Address(), pool.Address()) + balances.Update(name, BalanceItem{ + Address: pool.EthAddress, + Getter: GetterForLinkToken(sourceCCIP.Common.BridgeTokens[index].BalanceOf, pool.Address()), + AmtToAdd: bigmath.Mul(big.NewInt(noOfReq), sourceCCIP.TransferAmount[i]), + }) + } + } + if sourceCCIP.Common.FeeToken.Address() != common.HexToAddress("0x0").String() { + name := fmt.Sprintf("FeeToken-%s-Address-%s", sourceCCIP.Common.FeeToken.Address(), sourceCCIP.Sender.Hex()) + balances.Update(name, BalanceItem{ + Address: sourceCCIP.Sender, + Getter: GetterForLinkToken(sourceCCIP.Common.FeeToken.BalanceOf, sourceCCIP.Sender.Hex()), + AmtToSub: totalFee, + }) + name = fmt.Sprintf("FeeToken-%s-Prices-%s", sourceCCIP.Common.FeeToken.Address(), sourceCCIP.Common.PriceRegistry.Address()) + balances.Update(name, BalanceItem{ + Address: sourceCCIP.Common.PriceRegistry.EthAddress, + Getter: GetterForLinkToken(sourceCCIP.Common.FeeToken.BalanceOf, sourceCCIP.Common.PriceRegistry.Address()), + }) + name = fmt.Sprintf("FeeToken-%s-Router-%s", sourceCCIP.Common.FeeToken.Address(), sourceCCIP.Common.Router.Address()) + balances.Update(name, BalanceItem{ + Address: sourceCCIP.Common.Router.EthAddress, + Getter: GetterForLinkToken(sourceCCIP.Common.FeeToken.BalanceOf, sourceCCIP.Common.Router.Address()), + }) + name = fmt.Sprintf("FeeToken-%s-OnRamp-%s", sourceCCIP.Common.FeeToken.Address(), sourceCCIP.OnRamp.Address()) + balances.Update(name, BalanceItem{ + Address: sourceCCIP.OnRamp.EthAddress, + Getter: GetterForLinkToken(sourceCCIP.Common.FeeToken.BalanceOf, sourceCCIP.OnRamp.Address()), + AmtToAdd: totalFee, + }) + } +} + +func (sourceCCIP *SourceCCIPModule) AssertSendRequestedLogFinalized( + lggr *zerolog.Logger, + txHash common.Hash, + sendReqData []*contracts.SendReqEventData, + prevEventAt time.Time, + reqStats []*testreporters.RequestStat, +) (time.Time, uint64, error) { + if len(sendReqData) != len(reqStats) { + return time.Time{}, 0, fmt.Errorf("sendReqData and reqStats length mismatch") + } + var gasUsed uint64 + receipt, err := sourceCCIP.Common.ChainClient.GetTxReceipt(txHash) + if err == nil { + gasUsed = receipt.GasUsed + } + lggr.Info().Msg("Waiting for CCIPSendRequested event log to be finalized") + finalizedBlockNum, finalizedAt, err := sourceCCIP.Common.ChainClient.WaitForFinalizedTx(txHash) + if err != nil || finalizedBlockNum == nil { + for i, stat := range reqStats { + stat.UpdateState(lggr, stat.SeqNum, testreporters.SourceLogFinalized, time.Since(prevEventAt), testreporters.Failure, &testreporters.TransactionStats{ + MsgID: fmt.Sprintf("0x%x", sendReqData[i].MessageId[:]), + Fee: sendReqData[i].Fee.String(), + NoOfTokensSent: sendReqData[i].NoOfTokens, + MessageBytesLength: int64(sendReqData[i].DataLength), + TxHash: txHash.Hex(), + }) + } + return time.Time{}, 0, fmt.Errorf("error waiting for CCIPSendRequested event log to be finalized - %w", err) + } + for i, stat := range reqStats { + stat.UpdateState(lggr, stat.SeqNum, testreporters.SourceLogFinalized, finalizedAt.Sub(prevEventAt), testreporters.Success, + &testreporters.TransactionStats{ + MsgID: fmt.Sprintf("0x%x", sendReqData[i].MessageId[:]), + Fee: sendReqData[i].Fee.String(), + GasUsed: gasUsed, + NoOfTokensSent: sendReqData[i].NoOfTokens, + MessageBytesLength: int64(sendReqData[i].DataLength), + TxHash: txHash.Hex(), + FinalizedByBlock: finalizedBlockNum.String(), + FinalizedAt: finalizedAt.String(), + }) + } + return finalizedAt, finalizedBlockNum.Uint64(), nil +} + +func (sourceCCIP *SourceCCIPModule) IsRequestTriggeredWithinTimeframe(timeframe *commonconfig.Duration) *time.Time { + if timeframe == nil { + return nil + } + var foundAt *time.Time + lastSeenTimestamp := time.Now().UTC().Add(-timeframe.Duration()) + sourceCCIP.CCIPSendRequestedWatcher.Range(func(_, value any) bool { + if sendRequestedEvents, exists := value.([]*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested); exists { + for _, sendRequestedEvent := range sendRequestedEvents { + raw := sendRequestedEvent.Raw + hdr, err := sourceCCIP.Common.ChainClient.HeaderByNumber(context.Background(), big.NewInt(int64(raw.BlockNumber))) + if err == nil { + if hdr.Timestamp.After(lastSeenTimestamp) { + foundAt = pointer.ToTime(hdr.Timestamp) + return false + } + } + } + } + return true + }) + return foundAt +} + +func (sourceCCIP *SourceCCIPModule) AssertEventCCIPSendRequested( + lggr *zerolog.Logger, + txHash string, + timeout time.Duration, + prevEventAt time.Time, + reqStat []*testreporters.RequestStat, +) ([]*contracts.SendReqEventData, time.Time, error) { + lggr.Info().Str("Timeout", timeout.String()).Msg("Waiting for CCIPSendRequested event") + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + timer := time.NewTimer(timeout) + defer timer.Stop() + resetTimer := 0 + for { + select { + case <-ticker.C: + value, ok := sourceCCIP.CCIPSendRequestedWatcher.Load(txHash) + if ok { + // if sendrequested events are found, check if the number of events are same as the number of requests + if sendRequestedEvents, exists := value.([]*contracts.SendReqEventData); exists && len(sendRequestedEvents) == len(reqStat) { + // if the value is processed, delete it from the map + sourceCCIP.CCIPSendRequestedWatcher.Delete(txHash) + for i, sendRequestedEvent := range sendRequestedEvents { + seqNum := sendRequestedEvent.SequenceNumber + lggr = ptr.Ptr(lggr.With(). + Uint64("SequenceNumber", seqNum). + Str("MsgID", fmt.Sprintf("0x%x", sendRequestedEvent.MessageId[:])). + Logger()) + // prevEventAt is the time when the message was successful, this should be same as the time when the event was emitted + reqStat[i].UpdateState(lggr, seqNum, testreporters.CCIPSendRe, 0, testreporters.Success, nil) + } + var err error + if len(sendRequestedEvents) == 0 { + err = fmt.Errorf("message logs not found, no CCIPSendRequested event found for tx %s", txHash) + } + return sendRequestedEvents, prevEventAt, err + } + } + case <-timer.C: + // if there is connection issue reset the timer : + if sourceCCIP.Common.IsConnectionRestoredRecently != nil && !sourceCCIP.Common.IsConnectionRestoredRecently.Load() { + if resetTimer > 2 { + for _, stat := range reqStat { + stat.UpdateState(lggr, 0, testreporters.CCIPSendRe, time.Since(prevEventAt), testreporters.Failure, + &testreporters.TransactionStats{ + TxHash: txHash, + }) + } + return nil, time.Now(), fmt.Errorf("possible RPC issue - CCIPSendRequested event is not found for tx %s", txHash) + } + resetTimer++ + timer.Reset(timeout) + lggr.Info().Int("count of reset", resetTimer).Msg("Resetting timer to validate CCIPSendRequested event") + continue + } + for _, stat := range reqStat { + stat.UpdateState(lggr, 0, testreporters.CCIPSendRe, time.Since(prevEventAt), testreporters.Failure, + &testreporters.TransactionStats{ + TxHash: txHash, + }) + } + return nil, time.Now(), fmt.Errorf("CCIPSendRequested event is not found for tx %s", txHash) + } + } +} + +// CCIPMsg constructs the message for a CCIP request +func (sourceCCIP *SourceCCIPModule) CCIPMsg( + receiver common.Address, + gasLimit *big.Int, +) (router.ClientEVM2AnyMessage, error) { + length := sourceCCIP.MsgDataLength + var data string + if length > 0 { + b := make([]byte, length) + _, err := crypto_rand.Read(b) + if err != nil { + return router.ClientEVM2AnyMessage{}, fmt.Errorf("failed generating random string: %w", err) + } + randomString := base64.URLEncoding.EncodeToString(b) + data = randomString[:length] + } + + tokenAndAmounts := []router.ClientEVMTokenAmount{} + for i, amount := range sourceCCIP.TransferAmount { + if amount == nil { // make nil transfer amount 0 to avoid panics + sourceCCIP.TransferAmount[i] = big.NewInt(0) + } + token := sourceCCIP.Common.BridgeTokens[0] + // if length of sourceCCIP.TransferAmount is more than available bridge token use first bridge token + if i < len(sourceCCIP.Common.BridgeTokens) { + token = sourceCCIP.Common.BridgeTokens[i] + } + if amount == nil || amount.Cmp(big.NewInt(0)) == 0 { + log.Warn(). + Str("Token Address", token.Address()). + Int("Token Index", i). + Msg("Not sending a request for token transfer as the amount is 0 or nil") + continue + } + tokenAndAmounts = append(tokenAndAmounts, router.ClientEVMTokenAmount{ + Token: common.HexToAddress(token.Address()), Amount: amount, + }) + } + + receiverAddr, err := utils.ABIEncode(`[{"type":"address"}]`, receiver) + if err != nil { + return router.ClientEVM2AnyMessage{}, fmt.Errorf("failed encoding the receiver address: %w", err) + } + + extraArgsV1, err := testhelpers.GetEVMExtraArgsV1(gasLimit, false) + if err != nil { + return router.ClientEVM2AnyMessage{}, fmt.Errorf("failed encoding the options field: %w", err) + } + // form the message for transfer + return router.ClientEVM2AnyMessage{ + Receiver: receiverAddr, + Data: []byte(data), + TokenAmounts: tokenAndAmounts, + FeeToken: common.HexToAddress(sourceCCIP.Common.FeeToken.Address()), + ExtraArgs: extraArgsV1, + }, nil +} + +// SendRequest sends a CCIP request to the source chain's router contract +func (sourceCCIP *SourceCCIPModule) SendRequest( + receiver common.Address, + gasLimit *big.Int, +) (common.Hash, time.Duration, *big.Int, error) { + var d time.Duration + destChainSelector, err := chainselectors.SelectorFromChainId(sourceCCIP.DestinationChainId) + if err != nil { + return common.Hash{}, d, nil, fmt.Errorf("failed getting the chain selector: %w", err) + } + // form the message for transfer + msg, err := sourceCCIP.CCIPMsg(receiver, gasLimit) + if err != nil { + return common.Hash{}, d, nil, fmt.Errorf("failed forming the ccip msg: %w", err) + } + + fee, err := sourceCCIP.Common.Router.GetFee(destChainSelector, msg) + if err != nil { + log.Info().Interface("Msg", msg).Msg("CCIP msg") + reason, _ := blockchain.RPCErrorFromError(err) + if reason != "" { + return common.Hash{}, d, nil, fmt.Errorf("failed getting the fee: %s", reason) + } + return common.Hash{}, d, nil, fmt.Errorf("failed getting the fee: %w", err) + } + log.Info().Str("Fee", fee.String()).Msg("Calculated fee") + + var sendTx *types.Transaction + timeNow := time.Now() + feeToken := common.HexToAddress(sourceCCIP.Common.FeeToken.Address()) + // initiate the transfer + // if the fee token address is 0x0 it will use Native as fee token and the fee amount should be mentioned in bind.TransactOpts's value + if feeToken != (common.Address{}) { + sendTx, err = sourceCCIP.Common.Router.CCIPSendAndProcessTx(destChainSelector, msg, nil) + if err != nil { + txHash := common.Hash{} + if sendTx != nil { + txHash = sendTx.Hash() + } + return txHash, time.Since(timeNow), nil, fmt.Errorf("failed initiating the transfer ccip-send: %w", err) + } + } else { + sendTx, err = sourceCCIP.Common.Router.CCIPSendAndProcessTx(destChainSelector, msg, fee) + if err != nil { + txHash := common.Hash{} + if sendTx != nil { + txHash = sendTx.Hash() + } + return txHash, time.Since(timeNow), nil, fmt.Errorf("failed initiating the transfer ccip-send: %w", err) + } + } + + log.Info(). + Str("Network", sourceCCIP.Common.ChainClient.GetNetworkName()). + Str("Send token transaction", sendTx.Hash().String()). + Str("lane", fmt.Sprintf("%s-->%s", sourceCCIP.Common.ChainClient.GetNetworkName(), sourceCCIP.DestNetworkName)). + Msg("Sending token") + return sendTx.Hash(), time.Since(timeNow), fee, nil +} + +func DefaultSourceCCIPModule( + logger *zerolog.Logger, + testConf *testconfig.CCIPTestGroupConfig, + chainClient blockchain.EVMClient, + destChainId uint64, + destChain string, + laneConf *laneconfig.LaneConfig, +) (*SourceCCIPModule, error) { + cmn, err := NewCCIPCommonFromConfig( + logger, testConf, chainClient, laneConf, + ) + if err != nil { + return nil, err + } + + destChainSelector, err := chainselectors.SelectorFromChainId(destChainId) + if err != nil { + return nil, fmt.Errorf("failed getting the chain selector: %w", err) + } + source := &SourceCCIPModule{ + Common: cmn, + TransferAmount: testConf.MsgDetails.TransferAmounts(), + MsgDataLength: pointer.GetInt64(testConf.MsgDetails.DataLength), + DestinationChainId: destChainId, + DestChainSelector: destChainSelector, + DestNetworkName: destChain, + Sender: common.HexToAddress(chainClient.GetDefaultWallet().Address()), + CCIPSendRequestedWatcher: &sync.Map{}, + } + + return source, nil +} + +type DestCCIPModule struct { + Common *CCIPCommon + SourceChainId uint64 + SourceChainSelector uint64 + SourceNetworkName string + CommitStore *contracts.CommitStore + ReceiverDapp *contracts.ReceiverDapp + OffRamp *contracts.OffRamp + ReportAcceptedWatcher *sync.Map + ExecStateChangedWatcher *sync.Map + ReportBlessedWatcher *sync.Map + ReportBlessedBySeqNum *sync.Map + NextSeqNumToCommit *atomic.Uint64 + DestStartBlock uint64 +} + +func (destCCIP *DestCCIPModule) LoadContracts(conf *laneconfig.LaneConfig) { + if conf != nil { + cfg, ok := conf.DestContracts[destCCIP.SourceNetworkName] + if ok { + if common.IsHexAddress(cfg.OffRamp) { + destCCIP.OffRamp = &contracts.OffRamp{ + EthAddress: common.HexToAddress(cfg.OffRamp), + } + } + if common.IsHexAddress(cfg.CommitStore) { + destCCIP.CommitStore = &contracts.CommitStore{ + EthAddress: common.HexToAddress(cfg.CommitStore), + } + } + if common.IsHexAddress(cfg.ReceiverDapp) { + destCCIP.ReceiverDapp = &contracts.ReceiverDapp{ + EthAddress: common.HexToAddress(cfg.ReceiverDapp), + } + } + } + } +} + +func (destCCIP *DestCCIPModule) SyncTokensAndPools(srcTokens []*contracts.ERC20Token) error { + if destCCIP.OffRamp.Instance.V1_2_0 == nil { + return nil + } + var sourceTokens, pools []common.Address + + for _, token := range srcTokens { + sourceTokens = append(sourceTokens, common.HexToAddress(token.Address())) + } + + for i := range destCCIP.Common.BridgeTokenPools { + pools = append(pools, destCCIP.Common.BridgeTokenPools[i].EthAddress) + } + if len(sourceTokens) != len(pools) { + return fmt.Errorf("source token and destination pool length mismatch") + } + // if number of tokens are more than 10, then we need to split the tokens in batch of 10 and call sync + // otherwise the tx gets too large and we will get out of gas error + if len(sourceTokens) > 10 { + for i := 0; i < len(sourceTokens); i += 10 { + end := i + 10 + if end > len(sourceTokens) { + end = len(sourceTokens) + } + err := destCCIP.OffRamp.SyncTokensAndPools(sourceTokens[i:end], pools[i:end]) + if err != nil { + return err + } + } + return nil + } + return destCCIP.OffRamp.SyncTokensAndPools(sourceTokens, pools) +} + +// AddRateLimitTokens adds token pairs to the OffRamp's rate limiting +func (destCCIP *DestCCIPModule) AddRateLimitTokens(srcTokens, destTokens []*contracts.ERC20Token) error { + if destCCIP.OffRamp.Instance.Latest == nil { + return nil + } + if srcTokens == nil || destTokens == nil { + return fmt.Errorf("source or destination tokens are nil") + } + + if len(srcTokens) != len(destTokens) { + return fmt.Errorf("source and destination token length mismatch") + } + + var sourceTokenAddresses, destTokenAddresses []common.Address + + for i, token := range srcTokens { + sourceTokenAddresses = append(sourceTokenAddresses, common.HexToAddress(token.Address())) + destTokenAddresses = append(destTokenAddresses, common.HexToAddress(destTokens[i].Address())) + } + + // if number of tokens are more than 10, then we need to split the tokens in batch of 10 and update the rate limit + // otherwise the tx gets too large and we will get out of gas error + if len(sourceTokenAddresses) > 10 { + for i := 0; i < len(sourceTokenAddresses); i += 10 { + end := i + 10 + if end > len(sourceTokenAddresses) { + end = len(sourceTokenAddresses) + } + err := destCCIP.OffRamp.AddRateLimitTokens(sourceTokenAddresses[i:end], destTokenAddresses[i:end]) + if err != nil { + return err + } + } + return nil + } + + return destCCIP.OffRamp.AddRateLimitTokens(sourceTokenAddresses, destTokenAddresses) +} + +// RemoveRateLimitTokens removes token pairs from the OffRamp's rate limiting. +// If you ask to remove a token pair that doesn't exist, it will return an error. +func (destCCIP *DestCCIPModule) RemoveRateLimitTokens(ctx context.Context, srcTokens, destTokens []*contracts.ERC20Token) error { + if srcTokens == nil || destTokens == nil { + return fmt.Errorf("source or destination tokens are nil") + } + + if len(srcTokens) != len(destTokens) { + return fmt.Errorf("source and destination token length mismatch") + } + + var sourceTokenAddresses, destTokenAddresses []common.Address + + for i, token := range srcTokens { + sourceTokenAddresses = append(sourceTokenAddresses, common.HexToAddress(token.Address())) + destTokenAddresses = append(destTokenAddresses, common.HexToAddress(destTokens[i].Address())) + } + + return destCCIP.OffRamp.RemoveRateLimitTokens(ctx, sourceTokenAddresses, destTokenAddresses) +} + +// RemoveAllRateLimitTokens removes all token pairs from the OffRamp's rate limiting. +func (destCCIP *DestCCIPModule) RemoveAllRateLimitTokens(ctx context.Context) error { + return destCCIP.OffRamp.RemoveAllRateLimitTokens(ctx) +} + +// DeployContracts deploys all CCIP contracts specific to the destination chain +func (destCCIP *DestCCIPModule) DeployContracts( + sourceCCIP SourceCCIPModule, + lane *laneconfig.LaneConfig, +) error { + var err error + contractDeployer := destCCIP.Common.Deployer + log.Info().Msg("Deploying destination chain specific contracts") + destCCIP.LoadContracts(lane) + destChainSelector, err := chainselectors.SelectorFromChainId(destCCIP.Common.ChainClient.GetChainID().Uint64()) + if err != nil { + return fmt.Errorf("failed to get chain selector for destination chain id %d: %w", destCCIP.Common.ChainClient.GetChainID().Uint64(), err) + } + destCCIP.DestStartBlock, err = destCCIP.Common.ChainClient.LatestBlockNumber(context.Background()) + if err != nil { + return fmt.Errorf("getting latest block number shouldn't fail %w", err) + } + if !destCCIP.Common.ExistingDeployment && len(sourceCCIP.Common.BridgeTokenPools) != len(destCCIP.Common.BridgeTokenPools) { + return fmt.Errorf("source and destination token pool number does not match") + } + + if destCCIP.CommitStore == nil { + if destCCIP.Common.ExistingDeployment { + return fmt.Errorf("commit store address not provided in lane config") + } + // commitStore responsible for validating the transfer message + destCCIP.CommitStore, err = contractDeployer.DeployCommitStore( + destCCIP.SourceChainSelector, + destChainSelector, + sourceCCIP.OnRamp.EthAddress, + *destCCIP.Common.ARMContract, + ) + if err != nil { + return fmt.Errorf("deploying commitstore shouldn't fail %w", err) + } + err = destCCIP.Common.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("waiting for commitstore deployment shouldn't fail %w", err) + } + + // CommitStore can update + err = destCCIP.Common.PriceRegistry.AddPriceUpdater(destCCIP.CommitStore.EthAddress) + if err != nil { + return fmt.Errorf("setting commitstore as fee updater shouldn't fail %w", err) + } + err = destCCIP.Common.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("waiting for setting commitstore as fee updater shouldn't fail %w", err) + } + } else { + destCCIP.CommitStore, err = contractDeployer.NewCommitStore(destCCIP.CommitStore.EthAddress) + if err != nil { + return fmt.Errorf("getting new commitstore shouldn't fail %w", err) + } + } + + if destCCIP.OffRamp == nil { + if destCCIP.Common.ExistingDeployment { + return fmt.Errorf("offramp address not provided in lane config") + } + var tokenAdminReg common.Address + if contracts.NeedTokenAdminRegistry() { + if destCCIP.Common.TokenAdminRegistry == nil { + return fmt.Errorf("token admin registry contract address is not provided in lane config") + } + tokenAdminReg = destCCIP.Common.TokenAdminRegistry.EthAddress + } + destCCIP.OffRamp, err = contractDeployer.DeployOffRamp( + destCCIP.SourceChainSelector, + destChainSelector, + destCCIP.CommitStore.EthAddress, + sourceCCIP.OnRamp.EthAddress, + destCCIP.Common.RateLimiterConfig, + []common.Address{}, + []common.Address{}, + *destCCIP.Common.ARMContract, + tokenAdminReg, + ) + if err != nil { + return fmt.Errorf("deploying offramp shouldn't fail %w", err) + } + err = destCCIP.Common.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("waiting for offramp deployment shouldn't fail %w", err) + } + + // apply offramp updates + _, err = destCCIP.Common.Router.AddOffRamp(destCCIP.OffRamp.EthAddress, destCCIP.SourceChainSelector) + if err != nil { + return fmt.Errorf("setting offramp as fee updater shouldn't fail %w", err) + } + + err = destCCIP.AddRateLimitTokens(sourceCCIP.Common.BridgeTokens, destCCIP.Common.BridgeTokens) + if err != nil { + return fmt.Errorf("setting rate limited tokens shouldn't fail %w", err) + } + err = destCCIP.SyncTokensAndPools(sourceCCIP.Common.BridgeTokens) + if err != nil { + return fmt.Errorf("syncing tokens and pools shouldn't fail %w", err) + } + err = destCCIP.Common.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("waiting for events on destination contract shouldn't fail %w", err) + } + } else { + destCCIP.OffRamp, err = contractDeployer.NewOffRamp(destCCIP.OffRamp.EthAddress) + if err != nil { + return fmt.Errorf("getting new offramp shouldn't fail %w", err) + } + } + if destCCIP.ReceiverDapp == nil { + // ReceiverDapp + destCCIP.ReceiverDapp, err = contractDeployer.DeployReceiverDapp(false) + if err != nil { + return fmt.Errorf("receiverDapp contract should be deployed successfully %w", err) + } + err = destCCIP.Common.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("waiting for events on destination contract deployments %w", err) + } + } else { + destCCIP.ReceiverDapp, err = contractDeployer.NewReceiverDapp(destCCIP.ReceiverDapp.EthAddress) + if err != nil { + return fmt.Errorf("getting new receiverDapp shouldn't fail %w", err) + } + } + return nil +} + +func (destCCIP *DestCCIPModule) CollectBalanceRequirements() []testhelpers.BalanceReq { + var destBalancesReq []testhelpers.BalanceReq + for _, token := range destCCIP.Common.BridgeTokens { + destBalancesReq = append(destBalancesReq, testhelpers.BalanceReq{ + Name: fmt.Sprintf("BridgeToken-%s-Address-%s", token.Address(), destCCIP.ReceiverDapp.Address()), + Addr: destCCIP.ReceiverDapp.EthAddress, + Getter: GetterForLinkToken(token.BalanceOf, destCCIP.ReceiverDapp.Address()), + }) + } + for i, pool := range destCCIP.Common.BridgeTokenPools { + destBalancesReq = append(destBalancesReq, testhelpers.BalanceReq{ + Name: fmt.Sprintf("BridgeToken-%s-TokenPool-%s", destCCIP.Common.BridgeTokens[i].Address(), pool.Address()), + Addr: pool.EthAddress, + Getter: GetterForLinkToken(destCCIP.Common.BridgeTokens[i].BalanceOf, pool.Address()), + }) + } + if destCCIP.Common.FeeToken.Address() != common.HexToAddress("0x0").String() { + destBalancesReq = append(destBalancesReq, testhelpers.BalanceReq{ + Name: fmt.Sprintf("FeeToken-%s-Address-%s", destCCIP.Common.FeeToken.Address(), destCCIP.ReceiverDapp.Address()), + Addr: destCCIP.ReceiverDapp.EthAddress, + Getter: GetterForLinkToken(destCCIP.Common.FeeToken.BalanceOf, destCCIP.ReceiverDapp.Address()), + }) + destBalancesReq = append(destBalancesReq, testhelpers.BalanceReq{ + Name: fmt.Sprintf("FeeToken-%s-OffRamp-%s", destCCIP.Common.FeeToken.Address(), destCCIP.OffRamp.Address()), + Addr: destCCIP.OffRamp.EthAddress, + Getter: GetterForLinkToken(destCCIP.Common.FeeToken.BalanceOf, destCCIP.OffRamp.Address()), + }) + } + return destBalancesReq +} + +func (destCCIP *DestCCIPModule) UpdateBalance( + transferAmount []*big.Int, + noOfReq int64, + balance *BalanceSheet, +) { + if len(transferAmount) > 0 { + for i := range transferAmount { + token := destCCIP.Common.BridgeTokens[0] + if i < len(destCCIP.Common.BridgeTokens) { + token = destCCIP.Common.BridgeTokens[i] + } + name := fmt.Sprintf("BridgeToken-%s-Address-%s", token.Address(), destCCIP.ReceiverDapp.Address()) + balance.Update(name, BalanceItem{ + Address: destCCIP.ReceiverDapp.EthAddress, + Getter: GetterForLinkToken(token.BalanceOf, destCCIP.ReceiverDapp.Address()), + AmtToAdd: bigmath.Mul(big.NewInt(noOfReq), transferAmount[i]), + }) + } + for i := range transferAmount { + pool := destCCIP.Common.BridgeTokenPools[0] + index := 0 + if i < len(destCCIP.Common.BridgeTokenPools) { + pool = destCCIP.Common.BridgeTokenPools[i] + index = i + } + name := fmt.Sprintf("BridgeToken-%s-TokenPool-%s", destCCIP.Common.BridgeTokens[index].Address(), pool.Address()) + balance.Update(name, BalanceItem{ + Address: pool.EthAddress, + Getter: GetterForLinkToken(destCCIP.Common.BridgeTokens[index].BalanceOf, pool.Address()), + AmtToSub: bigmath.Mul(big.NewInt(noOfReq), transferAmount[i]), + }) + } + } + if destCCIP.Common.FeeToken.Address() != common.HexToAddress("0x0").String() { + name := fmt.Sprintf("FeeToken-%s-OffRamp-%s", destCCIP.Common.FeeToken.Address(), destCCIP.OffRamp.Address()) + balance.Update(name, BalanceItem{ + Address: destCCIP.OffRamp.EthAddress, + Getter: GetterForLinkToken(destCCIP.Common.FeeToken.BalanceOf, destCCIP.OffRamp.Address()), + }) + + name = fmt.Sprintf("FeeToken-%s-Address-%s", destCCIP.Common.FeeToken.Address(), destCCIP.ReceiverDapp.Address()) + balance.Update(name, BalanceItem{ + Address: destCCIP.ReceiverDapp.EthAddress, + Getter: GetterForLinkToken(destCCIP.Common.FeeToken.BalanceOf, destCCIP.ReceiverDapp.Address()), + }) + } +} + +// AssertNoReportAcceptedEventReceived validates that no ExecutionStateChangedEvent is emitted for mentioned timeRange after lastSeenTimestamp +func (destCCIP *DestCCIPModule) AssertNoReportAcceptedEventReceived(lggr *zerolog.Logger, timeRange time.Duration, lastSeenTimestamp time.Time) error { + ctx, cancel := context.WithTimeout(context.Background(), timeRange) + defer cancel() + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + for { + select { + case <-ticker.C: + var eventFoundAfterCursing *time.Time + // verify if CommitReportAccepted is received, it's not generated after provided lastSeenTimestamp + destCCIP.ReportAcceptedWatcher.Range(func(_, value any) bool { + e, exists := value.(*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged) + if exists { + vLogs := e.Raw + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(ctx, big.NewInt(int64(vLogs.BlockNumber))) + if err != nil { + return true + } + if hdr.Timestamp.After(lastSeenTimestamp) { + eventFoundAfterCursing = pointer.ToTime(hdr.Timestamp) + return false + } + } + return true + }) + if eventFoundAfterCursing != nil { + return fmt.Errorf("CommitReportAccepted Event detected at %s after %s", lastSeenTimestamp, eventFoundAfterCursing.String()) + } + case <-ctx.Done(): + lggr.Info().Msgf("successfully validated that no CommitReportAccepted detected after %s for %s", lastSeenTimestamp, timeRange) + return nil + } + } +} + +// AssertNoExecutionStateChangedEventReceived validates that no ExecutionStateChangedEvent is emitted for mentioned timeRange after lastSeenTimestamp +func (destCCIP *DestCCIPModule) AssertNoExecutionStateChangedEventReceived( + lggr *zerolog.Logger, + timeRange time.Duration, + lastSeenTimestamp time.Time, +) error { + ctx, cancel := context.WithTimeout(context.Background(), timeRange) + defer cancel() + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + lggr.Info().Str("Wait Time", timeRange.String()).Time("Since", lastSeenTimestamp).Msg("Waiting to ensure no ExecutionStateChanged event") + for { + select { + case <-ticker.C: + var eventFoundAfterCursing *time.Time + // verify if ExecutionStateChanged is received, it's not generated after provided lastSeenTimestamp + destCCIP.ExecStateChangedWatcher.Range(func(_, value any) bool { + e, exists := value.(*contracts.EVM2EVMOffRampExecutionStateChanged) + if exists { + vLogs := e.LogInfo + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(ctx, big.NewInt(int64(vLogs.BlockNumber))) + if err != nil { + return true + } + if hdr.Timestamp.After(lastSeenTimestamp) { + eventFoundAfterCursing = pointer.ToTime(hdr.Timestamp) + return false + } + } + return true + }) + if eventFoundAfterCursing != nil { + return fmt.Errorf("ExecutionStateChanged Event detected at %s after %s", lastSeenTimestamp, eventFoundAfterCursing.String()) + } + case <-ctx.Done(): + lggr.Info().Msgf("Successfully validated that no ExecutionStateChanged detected after %s for %s", lastSeenTimestamp, timeRange) + return nil + } + } +} + +func (destCCIP *DestCCIPModule) AssertEventExecutionStateChanged( + lggr *zerolog.Logger, + seqNum uint64, + timeout time.Duration, + timeNow time.Time, + reqStat *testreporters.RequestStat, + execState testhelpers.MessageExecutionState, +) (uint8, error) { + lggr.Info().Int64("seqNum", int64(seqNum)).Str("Timeout", timeout.String()).Msg("Waiting for ExecutionStateChanged event") + timer := time.NewTimer(timeout) + defer timer.Stop() + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + resetTimer := 0 + for { + select { + case <-ticker.C: + value, ok := destCCIP.ExecStateChangedWatcher.Load(seqNum) + if ok && value != nil { + e, exists := value.(*contracts.EVM2EVMOffRampExecutionStateChanged) + // find the type of the value + if exists { + // if the value is processed, delete it from the map + destCCIP.ExecStateChangedWatcher.Delete(seqNum) + vLogs := e.LogInfo + receivedAt := time.Now().UTC() + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(context.Background(), big.NewInt(int64(vLogs.BlockNumber))) + if err == nil { + receivedAt = hdr.Timestamp + } + receipt, err := destCCIP.Common.ChainClient.GetTxReceipt(vLogs.TxHash) + if err != nil { + lggr.Warn().Msg("Failed to get receipt for ExecStateChanged event") + } + var gasUsed uint64 + if receipt != nil { + gasUsed = receipt.GasUsed + } + if testhelpers.MessageExecutionState(e.State) == execState { + lggr.Info().Int64("seqNum", int64(seqNum)).Uint8("ExecutionState", e.State).Msg("ExecutionStateChanged event received") + reqStat.UpdateState(lggr, seqNum, testreporters.ExecStateChanged, receivedAt.Sub(timeNow), + testreporters.Success, + &testreporters.TransactionStats{ + TxHash: vLogs.TxHash.Hex(), + MsgID: fmt.Sprintf("0x%x", e.MessageId[:]), + GasUsed: gasUsed, + }, + ) + return e.State, nil + } + reqStat.UpdateState(lggr, seqNum, testreporters.ExecStateChanged, time.Since(timeNow), testreporters.Failure, nil) + return e.State, fmt.Errorf("ExecutionStateChanged event state - expected %d actual - %d with data %x for seq num %v for lane %d-->%d", + execState, testhelpers.MessageExecutionState(e.State), e.ReturnData, seqNum, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) + } + } + case <-timer.C: + // if there is connection issue reset the context : + if destCCIP.Common.IsConnectionRestoredRecently != nil && !destCCIP.Common.IsConnectionRestoredRecently.Load() { + // if timer already has been reset 2 times we fail with warning + if resetTimer > 2 { + reqStat.UpdateState(lggr, seqNum, testreporters.ExecStateChanged, time.Since(timeNow), testreporters.Failure, nil) + return 0, fmt.Errorf("possible RPC issues - ExecutionStateChanged event not found for seq num %d for lane %d-->%d", + seqNum, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) + } + timer.Reset(timeout) + resetTimer++ + lggr.Info().Int("count of reset", resetTimer).Msg("Resetting timer to validate ExecutionStateChanged event") + continue + } + reqStat.UpdateState(lggr, seqNum, testreporters.ExecStateChanged, time.Since(timeNow), testreporters.Failure, nil) + return 0, fmt.Errorf("ExecutionStateChanged event not found for seq num %d for lane %d-->%d", + seqNum, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) + } + } +} + +func (destCCIP *DestCCIPModule) AssertEventReportAccepted( + lggr *zerolog.Logger, + seqNum uint64, + timeout time.Duration, + prevEventAt time.Time, + reqStat *testreporters.RequestStat, +) (*contracts.CommitStoreReportAccepted, time.Time, error) { + lggr.Info().Int64("seqNum", int64(seqNum)).Str("Timeout", timeout.String()).Msg("Waiting for ReportAccepted event") + timer := time.NewTimer(timeout) + defer timer.Stop() + resetTimerCount := 0 + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + for { + select { + case <-ticker.C: + value, ok := destCCIP.ReportAcceptedWatcher.Load(seqNum) + if ok && value != nil { + reportAccepted, exists := value.(*contracts.CommitStoreReportAccepted) + if exists { + // if the value is processed, delete it from the map + destCCIP.ReportAcceptedWatcher.Delete(seqNum) + receivedAt := time.Now().UTC() + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(context.Background(), big.NewInt(int64(reportAccepted.LogInfo.BlockNumber))) + if err == nil { + receivedAt = hdr.Timestamp + } + + totalTime := receivedAt.Sub(prevEventAt) + // we cannot calculate the exact time at which block was finalized + // as a result sometimes we get a time which is slightly after the block was marked as finalized + // in such cases we get a negative time difference between finalized and report accepted if the commit + // has happened almost immediately after block being finalized + // in such cases we set the time difference to 1 second + if totalTime < 0 { + lggr.Warn(). + Uint64("seqNum", seqNum). + Time("finalized at", prevEventAt). + Time("ReportAccepted at", receivedAt). + Msg("ReportAccepted event received before finalized timestamp") + totalTime = time.Second + } + receipt, err := destCCIP.Common.ChainClient.GetTxReceipt(reportAccepted.LogInfo.TxHash) + if err != nil { + lggr.Warn().Msg("Failed to get receipt for ReportAccepted event") + } + var gasUsed uint64 + if receipt != nil { + gasUsed = receipt.GasUsed + } + reqStat.UpdateState(lggr, seqNum, testreporters.Commit, totalTime, testreporters.Success, + &testreporters.TransactionStats{ + GasUsed: gasUsed, + TxHash: reportAccepted.LogInfo.TxHash.Hex(), + CommitRoot: fmt.Sprintf("%x", reportAccepted.MerkleRoot), + }) + return reportAccepted, receivedAt, nil + } + } + case <-timer.C: + // if there is connection issue reset the context : + if destCCIP.Common.IsConnectionRestoredRecently != nil && !destCCIP.Common.IsConnectionRestoredRecently.Load() { + if resetTimerCount > 2 { + reqStat.UpdateState(lggr, seqNum, testreporters.Commit, time.Since(prevEventAt), testreporters.Failure, nil) + return nil, time.Now().UTC(), fmt.Errorf("possible RPC issue - ReportAccepted is not found for seq num %d lane %d-->%d", + seqNum, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) + } + timer.Reset(timeout) + resetTimerCount++ + lggr.Info().Int("count of reset", resetTimerCount).Msg("Resetting timer to validate ReportAccepted event") + continue + } + reqStat.UpdateState(lggr, seqNum, testreporters.Commit, time.Since(prevEventAt), testreporters.Failure, nil) + return nil, time.Now().UTC(), fmt.Errorf("ReportAccepted is not found for seq num %d lane %d-->%d", + seqNum, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) + } + } +} + +func (destCCIP *DestCCIPModule) AssertReportBlessed( + lggr *zerolog.Logger, + seqNum uint64, + timeout time.Duration, + CommitReport contracts.CommitStoreReportAccepted, + prevEventAt time.Time, + reqStat *testreporters.RequestStat, +) (time.Time, error) { + if destCCIP.Common.ARM == nil { + lggr.Info(). + Uint64("commit store interval Min", CommitReport.Min). + Uint64("commit store interval Max", CommitReport.Max). + Hex("Root", CommitReport.MerkleRoot[:]). + Msg("Skipping ReportBlessed check for mock ARM") + return prevEventAt, nil + } + lggr.Info(). + Str("Timeout", timeout.String()). + Uint64("commit store interval Min", CommitReport.Min). + Uint64("commit store interval Max", CommitReport.Max). + Msg("Waiting for Report To be blessed") + timer := time.NewTimer(timeout) + defer timer.Stop() + resetTimerCount := 0 + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + for { + select { + case <-ticker.C: + var value any + var foundAsRoot, ok bool + value, foundAsRoot = destCCIP.ReportBlessedWatcher.Load(CommitReport.MerkleRoot) + receivedAt := time.Now().UTC() + ok = foundAsRoot + if !foundAsRoot { + // if the value is not found as root, check if it is found as sequence number + value, ok = destCCIP.ReportBlessedBySeqNum.Load(seqNum) + } + if ok && value != nil { + vLogs, exists := value.(*contracts.LogInfo) + if exists { + // if the root is found, set the value for all the sequence numbers in the interval and delete the root from the map + if foundAsRoot { + // set the value for all the sequence numbers in the interval + for i := CommitReport.Min; i <= CommitReport.Max; i++ { + destCCIP.ReportBlessedBySeqNum.Store(i, vLogs) + } + // if the value is processed, delete it from the map + destCCIP.ReportBlessedWatcher.Delete(CommitReport.MerkleRoot) + } else { + // if the value is processed, delete it from the map + destCCIP.ReportBlessedBySeqNum.Delete(seqNum) + } + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(context.Background(), big.NewInt(int64(vLogs.BlockNumber))) + if err == nil { + receivedAt = hdr.Timestamp + } + receipt, err := destCCIP.Common.ChainClient.GetTxReceipt(vLogs.TxHash) + if err != nil { + lggr.Warn().Err(err).Msg("Failed to get receipt for ReportBlessed event") + } + var gasUsed uint64 + if receipt != nil { + gasUsed = receipt.GasUsed + } + reqStat.UpdateState(lggr, seqNum, testreporters.ReportBlessed, receivedAt.Sub(prevEventAt), testreporters.Success, + &testreporters.TransactionStats{ + GasUsed: gasUsed, + TxHash: vLogs.TxHash.String(), + CommitRoot: fmt.Sprintf("%x", CommitReport.MerkleRoot), + }) + return receivedAt, nil + } + } + case <-timer.C: + // if there is connection issue reset the context : + if destCCIP.Common.IsConnectionRestoredRecently != nil && !destCCIP.Common.IsConnectionRestoredRecently.Load() { + if resetTimerCount > 2 { + reqStat.UpdateState(lggr, seqNum, testreporters.ReportBlessed, time.Since(prevEventAt), testreporters.Failure, nil) + return time.Now().UTC(), fmt.Errorf("possible RPC issue - ReportBlessed is not found for interval min - %d max - %d lane %d-->%d", + CommitReport.Min, CommitReport.Max, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) + } + timer.Reset(timeout) + resetTimerCount++ + lggr.Info().Int("count of reset", resetTimerCount).Msg("Resetting timer to validate ReportBlessed event") + continue + } + reqStat.UpdateState(lggr, seqNum, testreporters.ReportBlessed, time.Since(prevEventAt), testreporters.Failure, nil) + return time.Now().UTC(), fmt.Errorf("ReportBlessed is not found for interval min - %d max - %d lane %d-->%d", + CommitReport.Min, CommitReport.Max, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) + } + } +} + +func (destCCIP *DestCCIPModule) AssertSeqNumberExecuted( + lggr *zerolog.Logger, + seqNumberBefore uint64, + timeout time.Duration, + timeNow time.Time, + reqStat *testreporters.RequestStat, +) error { + lggr.Info().Int64("seqNum", int64(seqNumberBefore)).Str("Timeout", timeout.String()).Msg("Waiting to be processed by commit store") + timer := time.NewTimer(timeout) + defer timer.Stop() + resetTimerCount := 0 + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + for { + select { + case <-ticker.C: + if destCCIP.NextSeqNumToCommit.Load() > seqNumberBefore { + return nil + } + seqNumberAfter, err := destCCIP.CommitStore.Instance.GetExpectedNextSequenceNumber(nil) + if err != nil { + // if we get error instead of returning error we continue, in case it's a temporary RPC failure . + continue + } + if seqNumberAfter > seqNumberBefore { + destCCIP.NextSeqNumToCommit.Store(seqNumberAfter) + return nil + } + case <-timer.C: + // if there is connection issue reset the context : + if destCCIP.Common.IsConnectionRestoredRecently != nil && !destCCIP.Common.IsConnectionRestoredRecently.Load() { + if resetTimerCount > 2 { + reqStat.UpdateState(lggr, seqNumberBefore, testreporters.Commit, time.Since(timeNow), testreporters.Failure, nil) + return fmt.Errorf("possible RPC issue - sequence number is not increased for seq num %d lane %d-->%d", + seqNumberBefore, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) + } + timer.Reset(timeout) + resetTimerCount++ + lggr.Info().Int("count of reset", resetTimerCount).Msg("Resetting timer to validate seqnumber increase in commit store") + continue + } + reqStat.UpdateState(lggr, seqNumberBefore, testreporters.Commit, time.Since(timeNow), testreporters.Failure, nil) + return fmt.Errorf("sequence number is not increased for seq num %d lane %d-->%d", + seqNumberBefore, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) + } + } +} + +func DefaultDestinationCCIPModule( + logger *zerolog.Logger, + testConf *testconfig.CCIPTestGroupConfig, + chainClient blockchain.EVMClient, + sourceChainId uint64, + sourceChain string, + laneConf *laneconfig.LaneConfig, +) (*DestCCIPModule, error) { + cmn, err := NewCCIPCommonFromConfig( + logger, testConf, chainClient, laneConf, + ) + if err != nil { + return nil, err + } + + sourceChainSelector, err := chainselectors.SelectorFromChainId(sourceChainId) + if err != nil { + return nil, fmt.Errorf("failed to get chain selector for source chain id %d: %w", sourceChainId, err) + } + return &DestCCIPModule{ + Common: cmn, + SourceChainId: sourceChainId, + SourceChainSelector: sourceChainSelector, + SourceNetworkName: sourceChain, + NextSeqNumToCommit: atomic.NewUint64(1), + ReportBlessedWatcher: &sync.Map{}, + ReportBlessedBySeqNum: &sync.Map{}, + ExecStateChangedWatcher: &sync.Map{}, + ReportAcceptedWatcher: &sync.Map{}, + }, nil +} + +type CCIPRequest struct { + ReqNo int64 + txHash string + txConfirmationTimestamp time.Time + RequestStat *testreporters.RequestStat +} + +func CCIPRequestFromTxHash(txHash common.Hash, chainClient blockchain.EVMClient) (CCIPRequest, *types.Receipt, error) { + rcpt, err := chainClient.GetTxReceipt(txHash) + if err != nil { + return CCIPRequest{}, nil, err + } + + hdr, err := chainClient.HeaderByNumber(context.Background(), rcpt.BlockNumber) + if err != nil { + return CCIPRequest{}, nil, err + } + txConfirmationTimestamp := hdr.Timestamp + + return CCIPRequest{ + txHash: txHash.Hex(), + txConfirmationTimestamp: txConfirmationTimestamp, + }, rcpt, nil +} + +type CCIPLane struct { + Test *testing.T + Logger *zerolog.Logger + SourceNetworkName string + DestNetworkName string + SourceChain blockchain.EVMClient + DestChain blockchain.EVMClient + Source *SourceCCIPModule + Dest *DestCCIPModule + NumberOfReq int + Reports *testreporters.CCIPLaneStats + Balance *BalanceSheet + SentReqs map[common.Hash][]CCIPRequest + TotalFee *big.Int // total fee for all the requests. Used for balance validation. + ValidationTimeout time.Duration + Context context.Context + SrcNetworkLaneCfg *laneconfig.LaneConfig + DstNetworkLaneCfg *laneconfig.LaneConfig + PriceReportingDisabled bool +} + +func (lane *CCIPLane) TokenPricesConfig() (string, error) { + d := &DynamicPriceGetterConfig{ + AggregatorPrices: make(map[common.Address]AggregatorPriceConfig), + StaticPrices: make(map[common.Address]StaticPriceConfig), + } + // for each token if there is a price aggregator, add it to the aggregator prices + // else add it to the static prices + for _, token := range lane.Dest.Common.BridgeTokens { + err := d.AddPriceConfig(token.Address(), lane.Dest.Common.PriceAggregators, LinkToUSD, lane.DestChain.GetChainID().Uint64()) + if err != nil { + return "", fmt.Errorf("error in adding PriceConfig for source bridge token %s: %w", token.Address(), err) + } + } + err := d.AddPriceConfig(lane.Dest.Common.FeeToken.Address(), lane.Dest.Common.PriceAggregators, LinkToUSD, lane.DestChain.GetChainID().Uint64()) + if err != nil { + return "", fmt.Errorf("error adding PriceConfig for dest Fee token %s: %w", lane.Dest.Common.FeeToken.Address(), err) + } + err = d.AddPriceConfig(lane.Dest.Common.WrappedNative.Hex(), lane.Dest.Common.PriceAggregators, WrappedNativeToUSD, lane.DestChain.GetChainID().Uint64()) + if err != nil { + return "", fmt.Errorf("error in adding PriceConfig for dest WrappedNative token %s: %w", lane.Dest.Common.WrappedNative.Hex(), err) + } + err = d.AddPriceConfig(lane.Source.Common.WrappedNative.Hex(), lane.Source.Common.PriceAggregators, WrappedNativeToUSD, lane.SourceChain.GetChainID().Uint64()) + if err != nil { + return "", fmt.Errorf("error in adding PriceConfig for source WrappedNative token %s: %w", lane.Source.Common.WrappedNative.Hex(), err) + } + return d.String() +} + +func (lane *CCIPLane) SetRemoteChainsOnPool() error { + if lane.Source.Common.ExistingDeployment { + return nil + } + if len(lane.Source.Common.BridgeTokenPools) != len(lane.Dest.Common.BridgeTokenPools) { + return fmt.Errorf("source (%d) and dest (%d) bridge token pools length should be same", + len(lane.Source.Common.BridgeTokenPools), len(lane.Dest.Common.BridgeTokenPools), + ) + } + for i, srcPool := range lane.Source.Common.BridgeTokenPools { + sourceToken := lane.Source.Common.BridgeTokens[i] + destToken := lane.Dest.Common.BridgeTokens[i] + dstPool := lane.Dest.Common.BridgeTokenPools[i] + + err := srcPool.SetRemoteChainOnPool(lane.Source.DestChainSelector, dstPool.EthAddress, destToken.ContractAddress) + if err != nil { + return err + } + err = dstPool.SetRemoteChainOnPool(lane.Dest.SourceChainSelector, srcPool.EthAddress, sourceToken.ContractAddress) + if err != nil { + return err + } + } + return nil +} + +// OptimizeStorage sets nil to various elements of CCIPLane which are only used +// during lane set up and not used for rest of the test duration +// this is called mainly by load test to keep the memory usage minimum for high number of lanes +func (lane *CCIPLane) OptimizeStorage() { + lane.Source.Common.FreeUpUnusedSpace() + lane.Dest.Common.FreeUpUnusedSpace() + lane.DstNetworkLaneCfg = nil + lane.SrcNetworkLaneCfg = nil + // close all header subscriptions for dest chains + queuedEvents := lane.Dest.Common.ChainClient.GetHeaderSubscriptions() + for subName := range queuedEvents { + lane.Dest.Common.ChainClient.DeleteHeaderEventSubscription(subName) + } + // close all header subscriptions for source chains except for finalized header + queuedEvents = lane.Source.Common.ChainClient.GetHeaderSubscriptions() + for subName := range queuedEvents { + if subName == blockchain.FinalizedHeaderKey { + continue + } + lane.Source.Common.ChainClient.DeleteHeaderEventSubscription(subName) + } +} + +func (lane *CCIPLane) UpdateLaneConfig() { + lane.Source.Common.WriteLaneConfig(lane.SrcNetworkLaneCfg) + lane.SrcNetworkLaneCfg.SrcContractsMu.Lock() + lane.SrcNetworkLaneCfg.SrcContracts[lane.Source.DestNetworkName] = laneconfig.SourceContracts{ + OnRamp: lane.Source.OnRamp.Address(), + DeployedAt: lane.Source.SrcStartBlock, + } + lane.SrcNetworkLaneCfg.SrcContractsMu.Unlock() + lane.Dest.Common.WriteLaneConfig(lane.DstNetworkLaneCfg) + lane.DstNetworkLaneCfg.DestContractsMu.Lock() + lane.DstNetworkLaneCfg.DestContracts[lane.Dest.SourceNetworkName] = laneconfig.DestContracts{ + OffRamp: lane.Dest.OffRamp.Address(), + CommitStore: lane.Dest.CommitStore.Address(), + ReceiverDapp: lane.Dest.ReceiverDapp.Address(), + } + lane.DstNetworkLaneCfg.DestContractsMu.Unlock() +} + +func (lane *CCIPLane) RecordStateBeforeTransfer() { + // collect the balance assert.ment to verify balances after transfer + bal, err := testhelpers.GetBalances(lane.Test, lane.Source.CollectBalanceRequirements()) + require.NoError(lane.Test, err, "fetching source balance") + lane.Balance.RecordBalance(bal) + + bal, err = testhelpers.GetBalances(lane.Test, lane.Dest.CollectBalanceRequirements()) + require.NoError(lane.Test, err, "fetching dest balance") + lane.Balance.RecordBalance(bal) + + // save the current block numbers to use in various filter log requests + lane.TotalFee = big.NewInt(0) + lane.NumberOfReq = 0 + lane.SentReqs = make(map[common.Hash][]CCIPRequest) +} + +func (lane *CCIPLane) AddToSentReqs(txHash common.Hash, reqStats []*testreporters.RequestStat) (*types.Receipt, error) { + request, rcpt, err := CCIPRequestFromTxHash(txHash, lane.Source.Common.ChainClient) + if err != nil { + for _, stat := range reqStats { + stat.UpdateState(lane.Logger, 0, testreporters.TX, 0, testreporters.Failure, nil) + } + return rcpt, fmt.Errorf("could not get request from tx hash %s: %w", txHash.Hex(), err) + } + var allRequests []CCIPRequest + for _, stat := range reqStats { + allRequests = append(allRequests, CCIPRequest{ + ReqNo: stat.ReqNo, + txHash: rcpt.TxHash.Hex(), + txConfirmationTimestamp: request.txConfirmationTimestamp, + RequestStat: stat, + }) + lane.NumberOfReq++ + } + lane.SentReqs[rcpt.TxHash] = allRequests + return rcpt, nil +} + +// Multicall sends multiple ccip-send requests in a single transaction +// It will create one transaction for all the requests and will wait for the confirmation +func (lane *CCIPLane) Multicall(noOfRequests int, multiSendAddr common.Address) error { + var ccipMultipleMsg []contracts.CCIPMsgData + feeToken := common.HexToAddress(lane.Source.Common.FeeToken.Address()) + genericMsg, err := lane.Source.CCIPMsg(lane.Dest.ReceiverDapp.EthAddress, big.NewInt(DefaultDestinationGasLimit)) + if err != nil { + return fmt.Errorf("failed to form the ccip message: %w", err) + } + destChainSelector, err := chainselectors.SelectorFromChainId(lane.Source.DestinationChainId) + if err != nil { + return fmt.Errorf("failed getting the chain selector: %w", err) + } + var reqStats []*testreporters.RequestStat + var txstats []*testreporters.TransactionStats + for i := 1; i <= noOfRequests; i++ { + // form the message for transfer + msg := genericMsg + msg.Data = []byte(fmt.Sprintf("msg %d", i)) + sendData := contracts.CCIPMsgData{ + Msg: msg, + RouterAddr: lane.Source.Common.Router.EthAddress, + ChainSelector: destChainSelector, + } + + fee, err := lane.Source.Common.Router.GetFee(destChainSelector, msg) + if err != nil { + reason, _ := blockchain.RPCErrorFromError(err) + if reason != "" { + return fmt.Errorf("failed getting the fee: %s", reason) + } + return fmt.Errorf("failed getting the fee: %w", err) + } + log.Info().Str("fee", fee.String()).Msg("calculated fee") + sendData.Fee = fee + lane.TotalFee = new(big.Int).Add(lane.TotalFee, fee) + ccipMultipleMsg = append(ccipMultipleMsg, sendData) + // if token transfer is required, transfer the token amount to multisend + for j, amount := range lane.Source.TransferAmount { + // if length of sourceCCIP.TransferAmount is more than available bridge token use first bridge token + token := lane.Source.Common.BridgeTokens[0] + if j < len(lane.Source.Common.BridgeTokens) { + token = lane.Source.Common.BridgeTokens[j] + } + err = token.Transfer(lane.SourceChain.GetDefaultWallet(), multiSendAddr.Hex(), amount) + if err != nil { + return err + } + } + stat := testreporters.NewCCIPRequestStats(int64(lane.NumberOfReq+i), lane.SourceNetworkName, lane.DestNetworkName) + txstats = append(txstats, &testreporters.TransactionStats{ + Fee: fee.String(), + NoOfTokensSent: len(msg.TokenAmounts), + MessageBytesLength: int64(len(msg.Data)), + }) + reqStats = append(reqStats, stat) + } + isNative := true + // transfer the fee amount to multisend + if feeToken != (common.Address{}) { + isNative = false + err = lane.Source.Common.FeeToken.Transfer(multiSendAddr.Hex(), lane.TotalFee) + if err != nil { + return err + } + } + + tx, err := contracts.MultiCallCCIP(lane.Source.Common.ChainClient, multiSendAddr.Hex(), ccipMultipleMsg, isNative) + if err != nil { + // update the stats as failure for all the requests in the multicall tx + for _, stat := range reqStats { + stat.UpdateState(lane.Logger, 0, testreporters.TX, 0, testreporters.Failure, nil) + } + return fmt.Errorf("failed to send the multicall: %w", err) + } + rcpt, err := lane.AddToSentReqs(tx.Hash(), reqStats) + if err != nil { + return err + } + var gasUsed uint64 + if rcpt != nil { + gasUsed = rcpt.GasUsed + } + // update the stats for all the requests in the multicall tx + for i, stat := range reqStats { + txstats[i].GasUsed = gasUsed + txstats[i].TxHash = tx.Hash().Hex() + stat.UpdateState(lane.Logger, 0, testreporters.TX, 0, testreporters.Success, txstats[i]) + } + return nil +} + +// SendRequests sends individual ccip-send requests in different transactions +// It will create noOfRequests transactions +func (lane *CCIPLane) SendRequests(noOfRequests int, gasLimit *big.Int) error { + for i := 1; i <= noOfRequests; i++ { + stat := testreporters.NewCCIPRequestStats(int64(lane.NumberOfReq+i), lane.SourceNetworkName, lane.DestNetworkName) + txHash, txConfirmationDur, fee, err := lane.Source.SendRequest( + lane.Dest.ReceiverDapp.EthAddress, + gasLimit, + ) + if err != nil { + stat.UpdateState(lane.Logger, 0, testreporters.TX, txConfirmationDur, testreporters.Failure, nil) + return fmt.Errorf("could not send request: %w", err) + } + err = lane.Source.Common.ChainClient.WaitForEvents() + if err != nil { + stat.UpdateState(lane.Logger, 0, testreporters.TX, txConfirmationDur, testreporters.Failure, nil) + return fmt.Errorf("could not send request: %w", err) + } + + noOfTokens := 0 + for _, tokenAmount := range lane.Source.TransferAmount { // Only count tokens that are actually sent + if tokenAmount != nil && tokenAmount.Cmp(big.NewInt(0)) > 0 { + noOfTokens++ + } + } + _, err = lane.AddToSentReqs(txHash, []*testreporters.RequestStat{stat}) + if err != nil { + return err + } + stat.UpdateState(lane.Logger, 0, testreporters.TX, txConfirmationDur, testreporters.Success, nil) + lane.TotalFee = bigmath.Add(lane.TotalFee, fee) + } + + return nil +} + +// manualExecutionOpts modify how ExecuteManually behaves +type manualExecutionOpts struct { + timeout time.Duration +} + +// ManualExecutionOption is a function that modifies ExecuteManually behavior +type ManualExecutionOption func(*manualExecutionOpts) + +// WithConfirmationTimeout sets a custom timeout for waiting for the confirmation of the manual execution +func WithConfirmationTimeout(timeout time.Duration) ManualExecutionOption { + return func(opts *manualExecutionOpts) { + opts.timeout = timeout + } +} + +// ExecuteManually attempts to execute pending CCIP transactions manually. +// This is necessary in situations where Smart Execution window for that message is over and Offchain plugin +// will not attempt to execute the message.In such situation any further message from same sender will not be executed until +// the blocking message is executed by the OffRamp. +// More info: https://docs.chain.link/ccip/concepts/manual-execution#manual-execution +func (lane *CCIPLane) ExecuteManually(options ...ManualExecutionOption) error { + var opts manualExecutionOpts + for _, opt := range options { + if opt != nil { + opt(&opts) + } + } + if opts.timeout == 0 { + opts.timeout = lane.ValidationTimeout + } + + onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp.EVM2EVMOnRampABI)) + if err != nil { + return err + } + sendReqTopic := onRampABI.Events["CCIPSendRequested"].ID + for txHash, req := range lane.SentReqs { + for _, ccipReq := range req { + lane.Logger.Info().Str("ccip-send", txHash.Hex()).Msg("Executing request manually") + seqNum := ccipReq.RequestStat.SeqNum + sendReqReceipt, err := lane.Source.Common.ChainClient.GetTxReceipt(txHash) + if err != nil { + return err + } + if sendReqReceipt == nil { + return fmt.Errorf("could not find the receipt for tx %s", txHash.Hex()) + } + commitStat, ok := ccipReq.RequestStat.StatusByPhase[testreporters.Commit] + if !ok { + return fmt.Errorf("could not find the commit phase in the request stats, reqNo %d", ccipReq.RequestStat.ReqNo) + } + commitTx := commitStat.SendTransactionStats.TxHash + commitReceipt, err := lane.DestChain.GetTxReceipt(common.HexToHash(commitTx)) + if err != nil { + return err + } + var logIndex uint + // find the send request log index sendReqReceipt + for _, sendReqLog := range sendReqReceipt.Logs { + if sendReqLog.Topics[0] == sendReqTopic { + logSeqNum, err := lane.Source.OnRamp.Instance.ParseCCIPSendRequested(*sendReqLog) + if err != nil { + return err + } + if logSeqNum == seqNum { + logIndex = sendReqLog.Index + } + } + } + destChainSelector, err := chainselectors.SelectorFromChainId(lane.DestChain.GetChainID().Uint64()) + if err != nil { + return err + } + sourceChainSelector, err := chainselectors.SelectorFromChainId(lane.SourceChain.GetChainID().Uint64()) + if err != nil { + return err + } + // Calling `TransactionOpts` will automatically increase the nonce, so if this fails, any other destination transactions will time out + destUser, err := lane.DestChain.TransactionOpts(lane.DestChain.GetDefaultWallet()) + if err != nil { + return err + } + args := testhelpers.ManualExecArgs{ + SourceChainID: sourceChainSelector, + DestChainID: destChainSelector, + DestUser: destUser, + SourceChain: lane.SourceChain.Backend(), + DestChain: lane.DestChain.Backend(), + SourceStartBlock: sendReqReceipt.BlockNumber, + DestStartBlock: commitReceipt.BlockNumber.Uint64(), + SendReqTxHash: txHash.Hex(), + CommitStore: lane.Dest.CommitStore.Address(), + OnRamp: lane.Source.OnRamp.Address(), + OffRamp: lane.Dest.OffRamp.Address(), + SendReqLogIndex: logIndex, + GasLimit: big.NewInt(DefaultDestinationGasLimit), + } + timeNow := time.Now().UTC() + tx, err := args.ExecuteManually() + if err != nil { + return fmt.Errorf("could not execute manually: %w seqNum %d", err, seqNum) + } + + ctx, cancel := context.WithTimeout(context.Background(), opts.timeout) + rec, err := bind.WaitMined(ctx, lane.DestChain.DeployBackend(), tx) + if err != nil { + cancel() + return fmt.Errorf("could not get receipt: %w seqNum %d", err, seqNum) + } + cancel() + if rec.Status != 1 { + return fmt.Errorf( + "manual execution failed for seqNum %d with receipt status %d, use the revert-reason script on this transaction hash '%s' and this sender address '%s'", + seqNum, rec.Status, tx.Hash().Hex(), destUser.From.Hex(), + ) + } + lane.Logger.Info().Uint64("seqNum", seqNum).Msg("Manual Execution completed") + _, err = lane.Dest.AssertEventExecutionStateChanged(lane.Logger, seqNum, opts.timeout, + timeNow, ccipReq.RequestStat, testhelpers.ExecutionStateSuccess, + ) + if err != nil { + return fmt.Errorf("could not validate ExecutionStateChanged event: %w", err) + } + } + } + return nil +} + +// validationOptions are used in the ValidateRequests function to specify which phase is expected to fail and how +type validationOptions struct { + phaseExpectedToFail testreporters.Phase // the phase expected to fail + expectedErrorMessage string // if provided, we're looking for a specific error message + timeout time.Duration // timeout for the validation +} + +// ValidationOptionFunc is a function that can be passed to ValidateRequests to specify which phase is expected to fail +type ValidationOptionFunc func(opts *validationOptions) + +// PhaseSpecificValidationOptionFunc can specify how exactly you want a phase to fail +type PhaseSpecificValidationOptionFunc func(*validationOptions) + +// WithErrorMessage specifies the expected error message for the phase that is expected to fail. +func WithErrorMessage(expectedErrorMessage string) PhaseSpecificValidationOptionFunc { + return func(opts *validationOptions) { + opts.expectedErrorMessage = expectedErrorMessage + } +} + +// WithTimeout specifies a custom timeout for validating that the phase failed. +func WithTimeout(timeout time.Duration) PhaseSpecificValidationOptionFunc { + return func(opts *validationOptions) { + opts.timeout = timeout + } +} + +// ExpectPhaseToFail specifies that a specific phase is expected to fail. +// You can optionally provide an expected error message, if you don't have one in mind, just pass an empty string. +// shouldExist is used to specify whether the phase should exist or not, which is only applicable to the `ExecStateChanged` phase. +// If you expect the `ExecStateChanged` events to be there, but in a "failed" state, set this to true. +// It will otherwise be ignored. +func ExpectPhaseToFail(phase testreporters.Phase, phaseSpecificOptions ...PhaseSpecificValidationOptionFunc) ValidationOptionFunc { + return func(opts *validationOptions) { + opts.phaseExpectedToFail = phase + for _, f := range phaseSpecificOptions { + if f != nil { + f(opts) + } + } + } +} + +// ValidateRequests validates all sent request events. +// If you expect a specific phase to fail, you can pass a validationOptionFunc to specify exactly which one. +// If not, just pass in nil. +func (lane *CCIPLane) ValidateRequests(validationOptionFuncs ...ValidationOptionFunc) { + var opts validationOptions + for _, f := range validationOptionFuncs { + if f != nil { + f(&opts) + } + } + for txHash, ccipReqs := range lane.SentReqs { + require.Greater(lane.Test, len(ccipReqs), 0, "no ccip requests found for tx hash") + require.NoError(lane.Test, lane.ValidateRequestByTxHash(txHash, opts), "validating request events by tx hash") + } + if len(validationOptionFuncs) > 0 { + return + } + // Asserting balances reliably work only for simulated private chains. The testnet contract balances might get updated by other transactions + // verify the fee amount is deducted from sender, added to receiver token balances and + if len(lane.Source.TransferAmount) > 0 && len(lane.Source.Common.BridgeTokens) > 0 { + lane.Source.UpdateBalance(int64(lane.NumberOfReq), lane.TotalFee, lane.Balance) + lane.Dest.UpdateBalance(lane.Source.TransferAmount, int64(lane.NumberOfReq), lane.Balance) + } +} + +// ValidateRequestByTxHash validates the request events by tx hash. +// If a phaseExpectedToFail is provided, it will return no error if that phase fails, but will error if it succeeds. +func (lane *CCIPLane) ValidateRequestByTxHash(txHash common.Hash, opts validationOptions) error { + var ( + reqStats []*testreporters.RequestStat + timeout = lane.ValidationTimeout + ccipRequests = lane.SentReqs[txHash] + txConfirmation = ccipRequests[0].txConfirmationTimestamp + ) + require.Greater(lane.Test, len(ccipRequests), 0, "no ccip requests found for tx hash") + + defer func() { + for _, req := range ccipRequests { + lane.Reports.UpdatePhaseStatsForReq(req.RequestStat) + } + }() + for _, req := range ccipRequests { + reqStats = append(reqStats, req.RequestStat) + } + + if opts.phaseExpectedToFail == testreporters.CCIPSendRe && opts.timeout != 0 { + timeout = opts.timeout + } + msgLogs, ccipSendReqGenAt, err := lane.Source.AssertEventCCIPSendRequested( + lane.Logger, txHash.Hex(), timeout, txConfirmation, reqStats, + ) + if shouldReturn, phaseErr := isPhaseValid(lane.Logger, testreporters.CCIPSendRe, opts, err); shouldReturn { + return phaseErr + } + + sourceLogFinalizedAt, _, err := lane.Source.AssertSendRequestedLogFinalized(lane.Logger, txHash, msgLogs, ccipSendReqGenAt, reqStats) + if shouldReturn, phaseErr := isPhaseValid(lane.Logger, testreporters.SourceLogFinalized, opts, err); shouldReturn { + return phaseErr + } + for _, msgLog := range msgLogs { + seqNumber := msgLog.SequenceNumber + lane.Logger = ptr.Ptr(lane.Logger.With().Str("msgId", fmt.Sprintf("0x%x", msgLog.MessageId[:])).Logger()) + var reqStat *testreporters.RequestStat + for _, stat := range reqStats { + if stat.SeqNum == seqNumber { + reqStat = stat + break + } + } + if reqStat == nil { + return fmt.Errorf("could not find request stat for seq number %d", seqNumber) + } + + if opts.phaseExpectedToFail == testreporters.Commit && opts.timeout != 0 { + timeout = opts.timeout + } + err = lane.Dest.AssertSeqNumberExecuted(lane.Logger, seqNumber, timeout, sourceLogFinalizedAt, reqStat) + if shouldReturn, phaseErr := isPhaseValid(lane.Logger, testreporters.Commit, opts, err); shouldReturn { + return phaseErr + } + + // Verify whether commitStore has accepted the report + commitReport, reportAcceptedAt, err := lane.Dest.AssertEventReportAccepted( + lane.Logger, seqNumber, timeout, sourceLogFinalizedAt, reqStat, + ) + if shouldReturn, phaseErr := isPhaseValid(lane.Logger, testreporters.Commit, opts, err); shouldReturn { + return phaseErr + } + + if opts.phaseExpectedToFail == testreporters.ReportBlessed && opts.timeout != 0 { + timeout = opts.timeout + } + reportBlessedAt, err := lane.Dest.AssertReportBlessed(lane.Logger, seqNumber, timeout, *commitReport, reportAcceptedAt, reqStat) + if shouldReturn, phaseErr := isPhaseValid(lane.Logger, testreporters.ReportBlessed, opts, err); shouldReturn { + return phaseErr + } + + if opts.phaseExpectedToFail == testreporters.ExecStateChanged && opts.timeout != 0 { + timeout = opts.timeout + } + // Verify whether the execution state is changed and the transfer is successful + _, err = lane.Dest.AssertEventExecutionStateChanged( + lane.Logger, seqNumber, + timeout, + reportBlessedAt, + reqStat, + testhelpers.ExecutionStateSuccess, + ) + if shouldReturn, phaseErr := isPhaseValid(lane.Logger, testreporters.ExecStateChanged, opts, err); shouldReturn { + return phaseErr + } + } + return nil +} + +// isPhaseValid checks if the phase is in a valid state or not given expectations. +// If `shouldComplete` is true, it means that the phase validation is meant to end and we should return from the calling function. +func isPhaseValid( + logger *zerolog.Logger, + currentPhase testreporters.Phase, + opts validationOptions, + err error, +) (shouldComplete bool, validationError error) { + // If no phase is expected to fail or the current phase is not the one expected to fail, we just return what we were given + if opts.phaseExpectedToFail == "" || currentPhase != opts.phaseExpectedToFail { + return err != nil, err + } + if err == nil && currentPhase == opts.phaseExpectedToFail { + return true, fmt.Errorf("expected phase '%s' to fail, but it passed", opts.phaseExpectedToFail) + } + logmsg := logger.Info().Str("Failed with Error", err.Error()).Str("Phase", string(currentPhase)) + if opts.expectedErrorMessage != "" { + if !strings.Contains(err.Error(), opts.expectedErrorMessage) { + return true, fmt.Errorf("expected phase '%s' to fail with error message '%s' but got error '%s'", currentPhase, opts.expectedErrorMessage, err.Error()) + } + logmsg.Str("Expected Error Message", opts.expectedErrorMessage) + } + logmsg.Msg("Expected phase to fail and it did") + return true, nil +} + +// DisableAllRateLimiting disables all rate limiting for the lane, including ARL and token pool rate limits +func (lane *CCIPLane) DisableAllRateLimiting() error { + src := lane.Source + dest := lane.Dest + + // Tell OnRamp to not include any tokens in ARL + err := src.SetAllTokenTransferFeeConfigs(false) + if err != nil { + return fmt.Errorf("error disabling token transfer fee config for OnRamp: %w", err) + } + err = dest.RemoveAllRateLimitTokens(context.Background()) + if err != nil { + return fmt.Errorf("error removing rate limited tokens for OffRamp: %w", err) + } + // Disable ARL for OnRamp and OffRamp + err = src.OnRamp.SetRateLimit(evm_2_evm_onramp.RateLimiterConfig{ + IsEnabled: false, + Capacity: big.NewInt(0), + Rate: big.NewInt(0), + }) + if err != nil { + return fmt.Errorf("error disabling rate limit for source onramp: %w", err) + } + err = dest.OffRamp.SetRateLimit(contracts.RateLimiterConfig{ + IsEnabled: false, + Capacity: big.NewInt(0), + Rate: big.NewInt(0), + }) + if err != nil { + return fmt.Errorf("error disabling rate limit for destination offramp: %w", err) + } + // Disable individual token pool rate limits + for i, tokenPool := range src.Common.BridgeTokenPools { + err = tokenPool.SetRemoteChainRateLimits(src.DestChainSelector, token_pool.RateLimiterConfig{ + IsEnabled: false, + Capacity: big.NewInt(0), + Rate: big.NewInt(0), + }) + if err != nil { + return fmt.Errorf("error disabling rate limit for token pool %d: %w", i, err) + } + } + for i, tokenPool := range dest.Common.BridgeTokenPools { + err = tokenPool.SetRemoteChainRateLimits(dest.SourceChainSelector, token_pool.RateLimiterConfig{ + IsEnabled: false, + Capacity: big.NewInt(0), + Rate: big.NewInt(0), + }) + if err != nil { + return fmt.Errorf("error disabling rate limit for token pool %d: %w", i, err) + } + } + err = src.Common.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("error waiting for source chain events: %w", err) + } + err = dest.Common.ChainClient.WaitForEvents() + if err != nil { + return fmt.Errorf("error waiting for destination chain events: %w", err) + } + lane.Logger.Info().Msg("Disabled all rate limiting") + return nil +} + +func (lane *CCIPLane) StartEventWatchers() error { + lane.Logger.Info().Msg("Starting event watchers") + if lane.Source.Common.ChainClient.GetNetworkConfig().FinalityDepth == 0 { + err := lane.Source.Common.ChainClient.PollFinality() + if err != nil { + return err + } + } + + go lane.Source.Common.PollRPCConnection(lane.Context, lane.Logger) + go lane.Dest.Common.PollRPCConnection(lane.Context, lane.Logger) + + sendReqEventLatest := make(chan *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested) + senReqSub := event.Resubscribe(DefaultResubscriptionTimeout, func(_ context.Context) (event.Subscription, error) { + sub, err := lane.Source.OnRamp.WatchCCIPSendRequested(nil, sendReqEventLatest) + if err != nil { + log.Error().Err(err).Msg("error in subscribing to CCIPSendRequested event") + } + return sub, err + }) + if senReqSub == nil { + return fmt.Errorf("failed to subscribe to CCIPSendRequested event") + } + go func(sub event.Subscription) { + defer sub.Unsubscribe() + for { + select { + case e := <-sendReqEventLatest: + lane.Logger.Info().Msgf("CCIPSendRequested event received for seq number %d", e.Message.SequenceNumber) + eventsForTx, ok := lane.Source.CCIPSendRequestedWatcher.Load(e.Raw.TxHash.Hex()) + if ok { + lane.Source.CCIPSendRequestedWatcher.Store(e.Raw.TxHash.Hex(), append(eventsForTx.([]*contracts.SendReqEventData), + &contracts.SendReqEventData{ + MessageId: e.Message.MessageId, + SequenceNumber: e.Message.SequenceNumber, + DataLength: len(e.Message.Data), + NoOfTokens: len(e.Message.TokenAmounts), + LogInfo: contracts.LogInfo{ + BlockNumber: e.Raw.BlockNumber, + TxHash: e.Raw.TxHash, + }, + Fee: e.Message.FeeTokenAmount, + })) + } else { + lane.Source.CCIPSendRequestedWatcher.Store(e.Raw.TxHash.Hex(), []*contracts.SendReqEventData{ + { + MessageId: e.Message.MessageId, + SequenceNumber: e.Message.SequenceNumber, + DataLength: len(e.Message.Data), + NoOfTokens: len(e.Message.TokenAmounts), + LogInfo: contracts.LogInfo{ + BlockNumber: e.Raw.BlockNumber, + TxHash: e.Raw.TxHash, + }, + Fee: e.Message.FeeTokenAmount, + }, + }) + } + + lane.Source.CCIPSendRequestedWatcher = testutils.DeleteNilEntriesFromMap(lane.Source.CCIPSendRequestedWatcher) + case <-lane.Context.Done(): + return + } + } + }(senReqSub) + + reportAcceptedEvent := make(chan *commit_store.CommitStoreReportAccepted) + reportAccSub := event.Resubscribe(DefaultResubscriptionTimeout, func(_ context.Context) (event.Subscription, error) { + sub, err := lane.Dest.CommitStore.WatchReportAccepted(nil, reportAcceptedEvent) + if err != nil { + log.Error().Err(err).Msg("error in subscribing to ReportAccepted event") + } + return sub, err + }) + if reportAccSub == nil { + return fmt.Errorf("failed to subscribe to ReportAccepted event") + } + go func(sub event.Subscription) { + defer sub.Unsubscribe() + for { + select { + case e := <-reportAcceptedEvent: + lane.Logger.Info().Interface("Interval", e.Report.Interval).Msgf("ReportAccepted event received") + for i := e.Report.Interval.Min; i <= e.Report.Interval.Max; i++ { + lane.Dest.ReportAcceptedWatcher.Store(i, &contracts.CommitStoreReportAccepted{ + Min: e.Report.Interval.Min, + Max: e.Report.Interval.Max, + MerkleRoot: e.Report.MerkleRoot, + LogInfo: contracts.LogInfo{ + BlockNumber: e.Raw.BlockNumber, + TxHash: e.Raw.TxHash, + }, + }) + } + lane.Dest.ReportAcceptedWatcher = testutils.DeleteNilEntriesFromMap(lane.Dest.ReportAcceptedWatcher) + case <-lane.Context.Done(): + return + } + } + }(reportAccSub) + + if lane.Dest.Common.ARM != nil { + reportBlessedEvent := make(chan *arm_contract.ARMContractTaggedRootBlessed) + blessedSub := event.Resubscribe(DefaultResubscriptionTimeout, func(_ context.Context) (event.Subscription, error) { + sub, err := lane.Dest.Common.ARM.Instance.WatchTaggedRootBlessed(nil, reportBlessedEvent, nil) + if err != nil { + log.Error().Err(err).Msg("error in subscribing to TaggedRootBlessed event") + } + return sub, err + }) + if blessedSub == nil { + return fmt.Errorf("failed to subscribe to TaggedRootBlessed event") + } + go func(sub event.Subscription) { + defer sub.Unsubscribe() + for { + select { + case e := <-reportBlessedEvent: + lane.Logger.Info().Msgf("TaggedRootBlessed event received for root %x", e.TaggedRoot.Root) + if e.TaggedRoot.CommitStore == lane.Dest.CommitStore.EthAddress { + lane.Dest.ReportBlessedWatcher.Store(e.TaggedRoot.Root, &contracts.LogInfo{ + BlockNumber: e.Raw.BlockNumber, + TxHash: e.Raw.TxHash, + }) + } + lane.Dest.ReportBlessedWatcher = testutils.DeleteNilEntriesFromMap(lane.Dest.ReportBlessedWatcher) + case <-lane.Context.Done(): + return + } + } + }(blessedSub) + } + + execStateChangedEventLatest := make(chan *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged) + execSub := event.Resubscribe(DefaultResubscriptionTimeout, func(_ context.Context) (event.Subscription, error) { + sub, err := lane.Dest.OffRamp.WatchExecutionStateChanged(nil, execStateChangedEventLatest, nil, nil) + if err != nil { + log.Error().Err(err).Msg("error in subscribing to ExecutionStateChanged event") + } + return sub, err + }) + if execSub == nil { + return fmt.Errorf("failed to subscribe to ExecutionStateChanged event") + } + go func(sub event.Subscription) { + defer sub.Unsubscribe() + for { + select { + case e := <-execStateChangedEventLatest: + lane.Logger.Info().Msgf("Execution state changed event received for seq number %d", e.SequenceNumber) + lane.Dest.ExecStateChangedWatcher.Store(e.SequenceNumber, &contracts.EVM2EVMOffRampExecutionStateChanged{ + SequenceNumber: e.SequenceNumber, + MessageId: e.MessageId, + State: e.State, + ReturnData: e.ReturnData, + LogInfo: contracts.LogInfo{ + BlockNumber: e.Raw.BlockNumber, + TxHash: e.Raw.TxHash, + }, + }) + lane.Dest.ExecStateChangedWatcher = testutils.DeleteNilEntriesFromMap(lane.Dest.ExecStateChangedWatcher) + case <-lane.Context.Done(): + return + } + } + }(execSub) + return nil +} + +func (lane *CCIPLane) CleanUp(clearFees bool) error { + lane.Logger.Info().Msg("Cleaning up lane") + if lane.Source.Common.ChainClient.GetNetworkConfig().FinalityDepth == 0 { + lane.Source.Common.ChainClient.CancelFinalityPolling() + } + // recover fees from onRamp contract + if clearFees && !lane.Source.Common.ChainClient.NetworkSimulated() { + err := lane.Source.PayCCIPFeeToOwnerAddress() + if err != nil { + return err + } + } + err := lane.Dest.Common.ChainClient.Close() + if err != nil { + return err + } + return lane.Source.Common.ChainClient.Close() +} + +// DeployNewCCIPLane sets up a lane and initiates lane.Source and lane.Destination +// If configureCLNodes is true it sets up jobs and contract config for the lane +func (lane *CCIPLane) DeployNewCCIPLane( + setUpCtx context.Context, + env *CCIPTestEnv, + testConf *testconfig.CCIPTestGroupConfig, + bootstrapAdded *atomic.Bool, + jobErrGroup *errgroup.Group, +) error { + var ( + err error + sourceChainClient = lane.SourceChain + destChainClient = lane.DestChain + srcConf = lane.SrcNetworkLaneCfg + destConf = lane.DstNetworkLaneCfg + commitAndExecOnSameDON = pointer.GetBool(testConf.CommitAndExecuteOnSameDON) + withPipeline = pointer.GetBool(testConf.TokenConfig.WithPipeline) + configureCLNodes = !pointer.GetBool(testConf.ExistingDeployment) + ) + + lane.Source, err = DefaultSourceCCIPModule( + lane.Logger, + testConf, + sourceChainClient, destChainClient.GetChainID().Uint64(), + destChainClient.GetNetworkName(), + srcConf, + ) + if err != nil { + return fmt.Errorf("failed to create source module: %w", err) + } + lane.Dest, err = DefaultDestinationCCIPModule( + lane.Logger, testConf, + destChainClient, sourceChainClient.GetChainID().Uint64(), + sourceChainClient.GetNetworkName(), destConf, + ) + if err != nil { + return fmt.Errorf("failed to create destination module: %w", err) + } + + // deploy all source contracts + err = lane.Source.DeployContracts(srcConf) + if err != nil { + return fmt.Errorf("failed to deploy source contracts: %w", err) + } + // deploy all destination contracts + err = lane.Dest.DeployContracts(*lane.Source, destConf) + if err != nil { + return fmt.Errorf("failed to deploy destination contracts: %w", err) + } + // if it's a new USDC deployment, sync the USDC domain + err = lane.Source.Common.SyncUSDCDomain(lane.Dest.Common.TokenTransmitter, lane.Dest.Common.BridgeTokenPools, lane.Source.DestinationChainId) + if err != nil { + return fmt.Errorf("failed to sync USDC domain: %w", err) + } + + lane.UpdateLaneConfig() + + // if lane is being set up for already configured CL nodes and contracts + // no further action is necessary + if !configureCLNodes { + return nil + } + err = lane.Source.Common.WatchForPriceUpdates(setUpCtx, lane.Logger) + if err != nil { + return fmt.Errorf("error in starting price update watch %w", err) + } + if env == nil { + return fmt.Errorf("test environment not set") + } + // wait for the CL nodes to be ready before moving ahead with job creation + err = env.CLNodeWithKeyReady.Wait() + if err != nil { + return fmt.Errorf("failed to wait for CL nodes to be ready: %w", err) + } + clNodesWithKeys := env.CLNodesWithKeys + // set up ocr2 jobs + clNodes, exists := clNodesWithKeys[lane.Dest.Common.ChainClient.GetChainID().String()] + if !exists { + return fmt.Errorf("could not find CL nodes for %s", lane.Dest.Common.ChainClient.GetChainID().String()) + } + bootstrapCommit := clNodes[0] + var bootstrapExec *client.CLNodesWithKeys + commitNodes := clNodes[env.CommitNodeStartIndex : env.CommitNodeStartIndex+env.NumOfCommitNodes] + execNodes := clNodes[env.ExecNodeStartIndex : env.ExecNodeStartIndex+env.NumOfExecNodes] + if !commitAndExecOnSameDON { + if len(clNodes) < 11 { + return fmt.Errorf("not enough CL nodes for separate commit and execution nodes") + } + bootstrapExec = clNodes[1] // for a set-up of different commit and execution nodes second node is the bootstrapper for execution nodes + } + + // save the current block numbers. If there is a delay between job start up and ocr config set up, the jobs will + // replay the log polling from these mentioned block number. The dest block number should ideally be the block number on which + // contract config is set and the source block number should be the one on which the ccip send request is performed. + // Here for simplicity we are just taking the current block number just before the job is created. + currentBlockOnDest, err := destChainClient.LatestBlockNumber(context.Background()) + if err != nil { + return fmt.Errorf("getting current block should be successful in destination chain %w", err) + } + + var killgrave *ctftestenv.Killgrave + if env.LocalCluster != nil { + killgrave = env.LocalCluster.MockAdapter + } + var tokenAddresses []string + for _, token := range lane.Dest.Common.BridgeTokens { + tokenAddresses = append(tokenAddresses, token.Address()) + } + tokenAddresses = append(tokenAddresses, lane.Dest.Common.FeeToken.Address(), lane.Source.Common.WrappedNative.Hex(), lane.Dest.Common.WrappedNative.Hex()) + + // Only one off pipeline or price getter to be set. + tokenPricesUSDPipeline := "" + tokenPricesConfigJson := "" + if withPipeline { + tokensUSDUrl := TokenPricePipelineURLs(tokenAddresses, killgrave, env.MockServer) + tokenPricesUSDPipeline = TokenFeeForMultipleTokenAddr(tokensUSDUrl) + } else { + tokenPricesConfigJson, err = lane.TokenPricesConfig() + if err != nil { + return fmt.Errorf("error getting token prices config %w", err) + } + lane.Logger.Info().Str("tokenPricesConfigJson", tokenPricesConfigJson).Msg("Price getter config") + } + + jobParams := integrationtesthelpers.CCIPJobSpecParams{ + OffRamp: lane.Dest.OffRamp.EthAddress, + CommitStore: lane.Dest.CommitStore.EthAddress, + SourceChainName: sourceChainClient.GetNetworkName(), + DestChainName: destChainClient.GetNetworkName(), + DestEvmChainId: destChainClient.GetChainID().Uint64(), + SourceStartBlock: lane.Source.SrcStartBlock, + TokenPricesUSDPipeline: tokenPricesUSDPipeline, + PriceGetterConfig: tokenPricesConfigJson, + DestStartBlock: currentBlockOnDest, + } + if !lane.Source.Common.ExistingDeployment && lane.Source.Common.IsUSDCDeployment() { + api := "" + if killgrave != nil { + api = killgrave.InternalEndpoint + } + if env.MockServer != nil { + api = env.MockServer.Config.ClusterURL + } + if lane.Source.Common.TokenTransmitter == nil { + return fmt.Errorf("token transmitter address not set") + } + // Only one USDC allowed per chain + jobParams.USDCConfig = &config.USDCConfig{ + SourceTokenAddress: common.HexToAddress(lane.Source.Common.BridgeTokens[0].Address()), + SourceMessageTransmitterAddress: lane.Source.Common.TokenTransmitter.ContractAddress, + AttestationAPI: api, + AttestationAPITimeoutSeconds: 5, + } + } + if !bootstrapAdded.Load() { + bootstrapAdded.Store(true) + err := CreateBootstrapJob(jobParams, bootstrapCommit, bootstrapExec) + if err != nil { + return fmt.Errorf("failed to create bootstrap job: %w", err) + } + } + + bootstrapCommitP2PId := bootstrapCommit.KeysBundle.P2PKeys.Data[0].Attributes.PeerID + var p2pBootstrappersExec, p2pBootstrappersCommit *client.P2PData + if bootstrapExec != nil { + p2pBootstrappersExec = &client.P2PData{ + InternalIP: bootstrapExec.Node.InternalIP(), + PeerID: bootstrapExec.KeysBundle.P2PKeys.Data[0].Attributes.PeerID, + } + } + + p2pBootstrappersCommit = &client.P2PData{ + InternalIP: bootstrapCommit.Node.InternalIP(), + PeerID: bootstrapCommitP2PId, + } + + jobParams.P2PV2Bootstrappers = []string{p2pBootstrappersCommit.P2PV2Bootstrapper()} + + err = SetOCR2Config(lane.Context, lane.Logger, *testConf, commitNodes, execNodes, *lane.Dest, lane.PriceReportingDisabled) + if err != nil { + return fmt.Errorf("failed to set ocr2 config: %w", err) + } + + err = CreateOCR2CCIPCommitJobs(lane.Logger, jobParams, commitNodes, env.nodeMutexes, jobErrGroup) + if err != nil { + return fmt.Errorf("failed to create ocr2 commit jobs: %w", err) + } + if p2pBootstrappersExec != nil { + jobParams.P2PV2Bootstrappers = []string{p2pBootstrappersExec.P2PV2Bootstrapper()} + } + + err = CreateOCR2CCIPExecutionJobs(lane.Logger, jobParams, execNodes, env.nodeMutexes, jobErrGroup) + if err != nil { + return fmt.Errorf("failed to create ocr2 execution jobs: %w", err) + } + + if err := lane.Source.Common.ChainClient.WaitForEvents(); err != nil { + return fmt.Errorf("failed to wait for events: %w", err) + } + if err := lane.Dest.Common.ChainClient.WaitForEvents(); err != nil { + return fmt.Errorf("failed to wait for events: %w", err) + } + lane.Dest.Common.ChainClient.ParallelTransactions(false) + lane.Source.Common.ChainClient.ParallelTransactions(false) + + return nil +} + +// SetOCR2Config sets the oracle config in ocr2 contracts. If execNodes is nil, commit and execution jobs are set up in same DON +func SetOCR2Config( + ctx context.Context, + lggr *zerolog.Logger, + testConf testconfig.CCIPTestGroupConfig, + commitNodes, + execNodes []*client.CLNodesWithKeys, + destCCIP DestCCIPModule, + priceReportingDisabled bool, +) error { + inflightExpiryExec := commonconfig.MustNewDuration(InflightExpiryExec) + inflightExpiryCommit := commonconfig.MustNewDuration(InflightExpiryCommit) + blockTime, err := destCCIP.Common.AvgBlockTime(ctx) + if err != nil { + return fmt.Errorf("failed to get avg block time: %w", err) + } + + OCR2ParamsForCommit := contracts.OCR2ParamsForCommit(blockTime) + OCR2ParamsForExec := contracts.OCR2ParamsForExec(blockTime) + // if test config has custom ocr2 params, merge them with default params to replace default with custom ocr2 params provided in config + // for commit and exec + if testConf.CommitOCRParams != nil { + err := mergo.Merge(&OCR2ParamsForCommit, testConf.CommitOCRParams, mergo.WithOverride) + if err != nil { + return err + } + } + if testConf.ExecOCRParams != nil { + err := mergo.Merge(&OCR2ParamsForExec, testConf.ExecOCRParams, mergo.WithOverride) + if err != nil { + return err + } + } + lggr.Info(). + Dur("AvgBlockTimeOnDest", blockTime). + Interface("OCRParmsForCommit", OCR2ParamsForCommit). + Interface("OCRParmsForExec", OCR2ParamsForExec). + Msg("Setting OCR2 config") + commitOffchainCfg, err := contracts.NewCommitOffchainConfig( + *commonconfig.MustNewDuration(5 * time.Second), + 1e6, + 1e6, + *commonconfig.MustNewDuration(5 * time.Second), + 1e6, + *inflightExpiryCommit, + priceReportingDisabled, + ) + if err != nil { + return fmt.Errorf("failed to create commit offchain config: %w", err) + } + + commitOnchainCfg, err := contracts.NewCommitOnchainConfig( + destCCIP.Common.PriceRegistry.EthAddress, + ) + if err != nil { + return fmt.Errorf("failed to create commit onchain config: %w", err) + } + signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, err := contracts.NewOffChainAggregatorV2ConfigForCCIPPlugin( + commitNodes, commitOffchainCfg, commitOnchainCfg, OCR2ParamsForCommit, 3*time.Minute) + if err != nil { + return fmt.Errorf("failed to create ocr2 config params for commit: %w", err) + } + + err = destCCIP.CommitStore.SetOCR2Config(signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + if err != nil { + return fmt.Errorf("failed to set ocr2 config for commit: %w", err) + } + + nodes := commitNodes + // if commit and exec job is set up in different DON + if len(execNodes) > 0 { + nodes = execNodes + } + if destCCIP.OffRamp != nil { + execOffchainCfg, err := contracts.NewExecOffchainConfig( + 1, + BatchGasLimit, + 0.7, + *inflightExpiryExec, + *commonconfig.MustNewDuration(RootSnoozeTime), + ) + if err != nil { + return fmt.Errorf("failed to create exec offchain config: %w", err) + } + execOnchainCfg, err := contracts.NewExecOnchainConfig( + uint32(DefaultPermissionlessExecThreshold.Seconds()), + destCCIP.Common.Router.EthAddress, + destCCIP.Common.PriceRegistry.EthAddress, + DefaultMaxNoOfTokensInMsg, + MaxDataBytes, + 200_000, + ) + if err != nil { + return fmt.Errorf("failed to create exec onchain config: %w", err) + } + signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, err = contracts.NewOffChainAggregatorV2ConfigForCCIPPlugin( + nodes, + execOffchainCfg, + execOnchainCfg, + OCR2ParamsForExec, + 3*time.Minute, + ) + if err != nil { + return fmt.Errorf("failed to create ocr2 config params for exec: %w", err) + } + err = destCCIP.OffRamp.SetOCR2Config(signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + if err != nil { + return fmt.Errorf("failed to set ocr2 config for exec: %w", err) + } + } + return destCCIP.Common.ChainClient.WaitForEvents() +} + +func CreateBootstrapJob( + jobParams integrationtesthelpers.CCIPJobSpecParams, + bootstrapCommit *client.CLNodesWithKeys, + bootstrapExec *client.CLNodesWithKeys, +) error { + _, err := bootstrapCommit.Node.MustCreateJob(jobParams.BootstrapJob(jobParams.CommitStore.Hex())) + if err != nil { + return fmt.Errorf("shouldn't fail creating bootstrap job on bootstrap node %w", err) + } + if bootstrapExec != nil { + _, err := bootstrapExec.Node.MustCreateJob(jobParams.BootstrapJob(jobParams.OffRamp.Hex())) + if err != nil { + return fmt.Errorf("shouldn't fail creating bootstrap job on bootstrap node %w", err) + } + } + return nil +} + +func CreateOCR2CCIPCommitJobs( + lggr *zerolog.Logger, + jobParams integrationtesthelpers.CCIPJobSpecParams, + commitNodes []*client.CLNodesWithKeys, + mutexes []*sync.Mutex, + group *errgroup.Group, +) error { + ocr2SpecCommit, err := jobParams.CommitJobSpec() + if err != nil { + return fmt.Errorf("failed to create ocr2 commit job spec: %w", err) + } + createJob := func(index int, node *client.CLNodesWithKeys, ocr2SpecCommit client.OCR2TaskJobSpec, mu *sync.Mutex) error { + mu.Lock() + defer mu.Unlock() + ocr2SpecCommit.OCR2OracleSpec.OCRKeyBundleID.SetValid(node.KeysBundle.OCR2Key.Data.ID) + ocr2SpecCommit.OCR2OracleSpec.TransmitterID.SetValid(node.KeysBundle.EthAddress) + lggr.Info().Msgf("Creating CCIP-Commit job on OCR node %d job name %s", index+1, ocr2SpecCommit.Name) + _, err = node.Node.MustCreateJob(&ocr2SpecCommit) + if err != nil { + return fmt.Errorf("shouldn't fail creating CCIP-Commit job on OCR node %d job name %s - %w", index+1, ocr2SpecCommit.Name, err) + } + return nil + } + + testSpec := client.OCR2TaskJobSpec{ + Name: ocr2SpecCommit.Name, + JobType: ocr2SpecCommit.JobType, + OCR2OracleSpec: ocr2SpecCommit.OCR2OracleSpec, + } + for i, node := range commitNodes { + node := node + i := i + group.Go(func() error { + return createJob(i, node, testSpec, mutexes[i]) + }) + } + return nil +} + +func CreateOCR2CCIPExecutionJobs( + lggr *zerolog.Logger, + jobParams integrationtesthelpers.CCIPJobSpecParams, + execNodes []*client.CLNodesWithKeys, + mutexes []*sync.Mutex, + group *errgroup.Group, +) error { + ocr2SpecExec, err := jobParams.ExecutionJobSpec() + if err != nil { + return fmt.Errorf("failed to create ocr2 execution job spec: %w", err) + } + createJob := func(index int, node *client.CLNodesWithKeys, ocr2SpecExec client.OCR2TaskJobSpec, mu *sync.Mutex) error { + mu.Lock() + defer mu.Unlock() + ocr2SpecExec.OCR2OracleSpec.OCRKeyBundleID.SetValid(node.KeysBundle.OCR2Key.Data.ID) + ocr2SpecExec.OCR2OracleSpec.TransmitterID.SetValid(node.KeysBundle.EthAddress) + lggr.Info().Msgf("Creating CCIP-Exec job on OCR node %d job name %s", index+1, ocr2SpecExec.Name) + _, err = node.Node.MustCreateJob(&ocr2SpecExec) + if err != nil { + return fmt.Errorf("shouldn't fail creating CCIP-Exec job on OCR node %d job name %s - %w", index+1, + ocr2SpecExec.Name, err) + } + return nil + } + if ocr2SpecExec != nil { + for i, node := range execNodes { + node := node + i := i + group.Go(func() error { + return createJob(i, node, client.OCR2TaskJobSpec{ + Name: ocr2SpecExec.Name, + JobType: ocr2SpecExec.JobType, + MaxTaskDuration: ocr2SpecExec.MaxTaskDuration, + ForwardingAllowed: ocr2SpecExec.ForwardingAllowed, + OCR2OracleSpec: ocr2SpecExec.OCR2OracleSpec, + ObservationSource: ocr2SpecExec.ObservationSource, + }, mutexes[i]) + }) + } + } + return nil +} + +func TokenFeeForMultipleTokenAddr(tokenAddrToURL map[string]string) string { + source := "" + right := "" + i := 1 + for addr, url := range tokenAddrToURL { + source = source + fmt.Sprintf(` +token%d [type=http method=GET url="%s"]; +token%d_parse [type=jsonparse path="data,result"]; +token%d->token%d_parse;`, i, url, i, i, i) + right = right + fmt.Sprintf(` \\\"%s\\\":$(token%d_parse),`, addr, i) + i++ + } + right = right[:len(right)-1] + source = fmt.Sprintf(`%s +merge [type=merge left="{}" right="{%s}"];`, source, right) + + return source +} + +type CCIPTestEnv struct { + MockServer *ctfClient.MockserverClient + LocalCluster *test_env.CLClusterTestEnv + CLNodesWithKeys map[string][]*client.CLNodesWithKeys // key - network chain-id + CLNodes []*client.ChainlinkK8sClient + nodeMutexes []*sync.Mutex + ExecNodeStartIndex int + CommitNodeStartIndex int + NumOfAllowedFaultyCommit int + NumOfAllowedFaultyExec int + NumOfCommitNodes int + NumOfExecNodes int + K8Env *environment.Environment + CLNodeWithKeyReady *errgroup.Group // denotes if keys are created in chainlink node and ready to be used for job creation +} + +func (c *CCIPTestEnv) ChaosLabelForGeth(t *testing.T, srcChain, destChain string) { + err := c.K8Env.Client.LabelChaosGroupByLabels(c.K8Env.Cfg.Namespace, map[string]string{ + "app": GethLabel(srcChain), + }, ChaosGroupNetworkACCIPGeth) + require.NoError(t, err) + + err = c.K8Env.Client.LabelChaosGroupByLabels(c.K8Env.Cfg.Namespace, map[string]string{ + "app": GethLabel(destChain), + }, ChaosGroupNetworkBCCIPGeth) + require.NoError(t, err) + gethNetworksLabels := []string{GethLabel(srcChain), GethLabel(destChain)} + c.ChaosLabelForAllGeth(t, gethNetworksLabels) + +} + +func (c *CCIPTestEnv) ChaosLabelForAllGeth(t *testing.T, gethNetworksLabels []string) { + for _, gethNetworkLabel := range gethNetworksLabels { + err := c.K8Env.Client.AddLabel(c.K8Env.Cfg.Namespace, + fmt.Sprintf("app=%s", gethNetworkLabel), + fmt.Sprintf("geth=%s", ChaosGroupCCIPGeth)) + require.NoError(t, err) + } +} + +func (c *CCIPTestEnv) ChaosLabelForCLNodes(t *testing.T) { + allowedFaulty := c.NumOfAllowedFaultyCommit + commitStartInstance := c.CommitNodeStartIndex + 1 + execStartInstance := c.ExecNodeStartIndex + 1 + for i := commitStartInstance; i < len(c.CLNodes); i++ { + labelSelector := map[string]string{ + "app": "chainlink-0", + "instance": fmt.Sprintf("node-%d", i), + } + if i >= commitStartInstance && i < commitStartInstance+allowedFaulty+1 { + err := c.K8Env.Client.LabelChaosGroupByLabels(c.K8Env.Cfg.Namespace, labelSelector, ChaosGroupCommitAndExecFaultyPlus) + require.NoError(t, err) + } + if i >= commitStartInstance && i < commitStartInstance+allowedFaulty { + err := c.K8Env.Client.LabelChaosGroupByLabels(c.K8Env.Cfg.Namespace, labelSelector, ChaosGroupCommitAndExecFaulty) + require.NoError(t, err) + } + + // commit node starts from index 2 + if i >= commitStartInstance && i < commitStartInstance+c.NumOfCommitNodes { + err := c.K8Env.Client.LabelChaosGroupByLabels(c.K8Env.Cfg.Namespace, labelSelector, ChaosGroupCommit) + require.NoError(t, err) + } + if i >= commitStartInstance && i < commitStartInstance+c.NumOfAllowedFaultyCommit+1 { + err := c.K8Env.Client.LabelChaosGroupByLabels(c.K8Env.Cfg.Namespace, labelSelector, ChaosGroupCommitFaultyPlus) + require.NoError(t, err) + } + if i >= commitStartInstance && i < commitStartInstance+c.NumOfAllowedFaultyCommit { + err := c.K8Env.Client.LabelChaosGroupByLabels(c.K8Env.Cfg.Namespace, labelSelector, ChaosGroupCommitFaulty) + require.NoError(t, err) + } + if i >= execStartInstance && i < execStartInstance+c.NumOfExecNodes { + err := c.K8Env.Client.LabelChaosGroupByLabels(c.K8Env.Cfg.Namespace, labelSelector, ChaosGroupExecution) + require.NoError(t, err) + } + if i >= execStartInstance && i < execStartInstance+c.NumOfAllowedFaultyExec+1 { + err := c.K8Env.Client.LabelChaosGroupByLabels(c.K8Env.Cfg.Namespace, labelSelector, ChaosGroupExecutionFaultyPlus) + require.NoError(t, err) + } + if i >= execStartInstance && i < execStartInstance+c.NumOfAllowedFaultyExec { + err := c.K8Env.Client.LabelChaosGroupByLabels(c.K8Env.Cfg.Namespace, labelSelector, ChaosGroupExecutionFaulty) + require.NoError(t, err) + } + } +} + +func (c *CCIPTestEnv) ConnectToExistingNodes(envConfig *testconfig.Common) error { + if envConfig.ExistingCLCluster == nil { + return fmt.Errorf("existing cluster is nil") + } + noOfNodes := pointer.GetInt(envConfig.ExistingCLCluster.NoOfNodes) + namespace := pointer.GetString(envConfig.ExistingCLCluster.Name) + + for i := 0; i < noOfNodes; i++ { + cfg := envConfig.ExistingCLCluster.NodeConfigs[i] + if cfg == nil { + return fmt.Errorf("node %d config is nil", i+1) + } + clClient, err := client.NewChainlinkK8sClient(cfg, cfg.InternalIP, namespace) + if err != nil { + return fmt.Errorf("failed to create chainlink client: %w for node %d config %v", err, i+1, cfg) + } + c.CLNodes = append(c.CLNodes, clClient) + c.nodeMutexes = append(c.nodeMutexes, &sync.Mutex{}) + } + + return nil +} + +func (c *CCIPTestEnv) ConnectToDeployedNodes() error { + if c.LocalCluster != nil { + // for local cluster, fetch the values from the local cluster + for _, chainlinkNode := range c.LocalCluster.ClCluster.Nodes { + c.nodeMutexes = append(c.nodeMutexes, &sync.Mutex{}) + c.CLNodes = append(c.CLNodes, &client.ChainlinkK8sClient{ + ChainlinkClient: chainlinkNode.API, + }) + } + } else { + // in case of k8s, we need to connect to the chainlink nodes + log.Info().Msg("Connecting to launched resources") + chainlinkK8sNodes, err := client.ConnectChainlinkNodes(c.K8Env) + if err != nil { + return fmt.Errorf("failed to connect to chainlink nodes: %w", err) + } + if len(chainlinkK8sNodes) == 0 { + return fmt.Errorf("no CL node found") + } + + for range chainlinkK8sNodes { + c.nodeMutexes = append(c.nodeMutexes, &sync.Mutex{}) + } + c.CLNodes = chainlinkK8sNodes + if _, exists := c.K8Env.URLs[mockserver.InternalURLsKey]; exists { + c.MockServer = ctfClient.ConnectMockServer(c.K8Env) + } + } + return nil +} + +// SetUpNodeKeysAndFund creates node keys and funds the nodes +func (c *CCIPTestEnv) SetUpNodeKeysAndFund( + logger *zerolog.Logger, + nodeFund *big.Float, + chains []blockchain.EVMClient, +) error { + if c.CLNodes == nil || len(c.CLNodes) == 0 { + return fmt.Errorf("no chainlink nodes to setup") + } + var chainlinkNodes []*client.ChainlinkClient + for _, node := range c.CLNodes { + chainlinkNodes = append(chainlinkNodes, node.ChainlinkClient) + } + nodesWithKeys := make(map[string][]*client.CLNodesWithKeys) + + populateKeys := func(chain blockchain.EVMClient) error { + log.Info().Str("chain id", chain.GetChainID().String()).Msg("creating node keys for chain") + _, clNodes, err := client.CreateNodeKeysBundle(chainlinkNodes, "evm", chain.GetChainID().String()) + if err != nil { + return fmt.Errorf("failed to create node keys for chain %s: %w", chain.GetChainID().String(), err) + } + if len(clNodes) == 0 { + return fmt.Errorf("no CL node with keys found for chain %s", chain.GetNetworkName()) + } + + nodesWithKeys[chain.GetChainID().String()] = clNodes + return nil + } + + fund := func(ec blockchain.EVMClient) error { + cfg := ec.GetNetworkConfig() + if cfg == nil { + return fmt.Errorf("blank network config") + } + c1, err := blockchain.ConcurrentEVMClient(*cfg, c.K8Env, ec, *logger) + if err != nil { + return fmt.Errorf("getting concurrent evmclient chain %s %w", ec.GetNetworkName(), err) + } + defer func() { + if c1 != nil { + c1.Close() + } + }() + log.Info().Str("chain id", c1.GetChainID().String()).Msg("Funding Chainlink nodes for chain") + for i := 1; i < len(chainlinkNodes); i++ { + cl := chainlinkNodes[i] + m := c.nodeMutexes[i] + toAddress, err := cl.EthAddressesForChain(c1.GetChainID().String()) + if err != nil { + return err + } + for _, addr := range toAddress { + toAddr := common.HexToAddress(addr) + gasEstimates, err := c1.EstimateGas(ethereum.CallMsg{ + To: &toAddr, + }) + if err != nil { + return err + } + m.Lock() + err = c1.Fund(addr, nodeFund, gasEstimates) + m.Unlock() + if err != nil { + return err + } + } + } + return c1.WaitForEvents() + } + grp, _ := errgroup.WithContext(context.Background()) + for _, chain := range chains { + err := populateKeys(chain) + if err != nil { + return err + } + } + for _, chain := range chains { + chain := chain + grp.Go(func() error { + return fund(chain) + }) + } + err := grp.Wait() + if err != nil { + return fmt.Errorf("error funding nodes %w", err) + } + c.CLNodesWithKeys = nodesWithKeys + + return nil +} + +func AssertBalances(t *testing.T, bas []testhelpers.BalanceAssertion) { + logEvent := log.Info() + for _, b := range bas { + actual := b.Getter(t, b.Address) + assert.NotNil(t, actual, "%v getter return nil", b.Name) + if b.Within == "" { + assert.Equal(t, b.Expected, actual.String(), "wrong balance for %s got %s want %s", b.Name, actual, b.Expected) + logEvent.Interface(b.Name, struct { + Exp string + Actual string + }{ + Exp: b.Expected, + Actual: actual.String(), + }) + } else { + bi, _ := big.NewInt(0).SetString(b.Expected, 10) + withinI, _ := big.NewInt(0).SetString(b.Within, 10) + high := big.NewInt(0).Add(bi, withinI) + low := big.NewInt(0).Sub(bi, withinI) + assert.Equal(t, -1, actual.Cmp(high), + "wrong balance for %s got %s outside expected range [%s, %s]", b.Name, actual, low, high) + assert.Equal(t, 1, actual.Cmp(low), + "wrong balance for %s got %s outside expected range [%s, %s]", b.Name, actual, low, high) + logEvent.Interface(b.Name, struct { + ExpRange string + Actual string + }{ + ExpRange: fmt.Sprintf("[%s, %s]", low, high), + Actual: actual.String(), + }) + } + } + logEvent.Msg("balance assertions succeeded") +} + +type BalFunc func(ctx context.Context, addr string) (*big.Int, error) + +func GetterForLinkToken(getBalance BalFunc, addr string) func(t *testing.T, _ common.Address) *big.Int { + return func(t *testing.T, _ common.Address) *big.Int { + balance, err := getBalance(context.Background(), addr) + assert.NoError(t, err) + return balance + } +} + +type BalanceItem struct { + Address common.Address + Getter func(t *testing.T, addr common.Address) *big.Int + PreviousBalance *big.Int + AmtToAdd *big.Int + AmtToSub *big.Int +} + +type BalanceSheet struct { + mu *sync.Mutex + Items map[string]BalanceItem + PrevBalance map[string]*big.Int +} + +func (b *BalanceSheet) Update(key string, item BalanceItem) { + b.mu.Lock() + defer b.mu.Unlock() + prev, ok := b.Items[key] + if !ok { + b.Items[key] = item + return + } + amtToAdd, amtToSub := big.NewInt(0), big.NewInt(0) + if prev.AmtToAdd != nil { + amtToAdd = prev.AmtToAdd + } + if prev.AmtToSub != nil { + amtToSub = prev.AmtToSub + } + if item.AmtToAdd != nil { + amtToAdd = new(big.Int).Add(amtToAdd, item.AmtToAdd) + } + if item.AmtToSub != nil { + amtToSub = new(big.Int).Add(amtToSub, item.AmtToSub) + } + + b.Items[key] = BalanceItem{ + Address: item.Address, + Getter: item.Getter, + AmtToAdd: amtToAdd, + AmtToSub: amtToSub, + } +} + +func (b *BalanceSheet) RecordBalance(bal map[string]*big.Int) { + b.mu.Lock() + defer b.mu.Unlock() + for key, value := range bal { + if _, ok := b.PrevBalance[key]; !ok { + b.PrevBalance[key] = value + } + } +} + +func (b *BalanceSheet) Verify(t *testing.T) { + var balAssertions []testhelpers.BalanceAssertion + for key, item := range b.Items { + prevBalance, ok := b.PrevBalance[key] + require.Truef(t, ok, "previous balance is not captured for %s", key) + exp := prevBalance + if item.AmtToAdd != nil { + exp = new(big.Int).Add(exp, item.AmtToAdd) + } + if item.AmtToSub != nil { + exp = new(big.Int).Sub(exp, item.AmtToSub) + } + balAssertions = append(balAssertions, testhelpers.BalanceAssertion{ + Name: key, + Address: item.Address, + Getter: item.Getter, + Expected: exp.String(), + }) + } + AssertBalances(t, balAssertions) +} + +func NewBalanceSheet() *BalanceSheet { + return &BalanceSheet{ + mu: &sync.Mutex{}, + Items: make(map[string]BalanceItem), + PrevBalance: make(map[string]*big.Int), + } +} + +// SetMockServerWithUSDCAttestation responds with a mock attestation for any msgHash +// The path is set with regex to match any path that starts with /v1/attestations +func SetMockServerWithUSDCAttestation( + killGrave *ctftestenv.Killgrave, + mockserver *ctfClient.MockserverClient, +) error { + path := "/v1/attestations" + response := struct { + Status string `json:"status"` + Attestation string `json:"attestation"` + Error string `json:"error"` + }{ + Status: "complete", + Attestation: "0x9049623e91719ef2aa63c55f357be2529b0e7122ae552c18aff8db58b4633c4d3920ff03d3a6d1ddf11f06bf64d7fd60d45447ac81f527ba628877dc5ca759651b08ffae25a6d3b1411749765244f0a1c131cbfe04430d687a2e12fd9d2e6dc08e118ad95d94ad832332cf3c4f7a4f3da0baa803b7be024b02db81951c0f0714de1b", + } + if killGrave == nil && mockserver == nil { + return fmt.Errorf("both killgrave and mockserver are nil") + } + log.Info().Str("path", path).Msg("setting attestation-api response for any msgHash") + if killGrave != nil { + err := killGrave.SetAnyValueResponse(fmt.Sprintf("%s/{_hash:.*}", path), []string{http.MethodGet}, response) + if err != nil { + return fmt.Errorf("failed to set killgrave server value: %w", err) + } + } + if mockserver != nil { + err := mockserver.SetAnyValueResponse(fmt.Sprintf("%s/.*", path), response) + if err != nil { + return fmt.Errorf("failed to set mockserver value: %w URL = %s", err, fmt.Sprintf("%s/%s/.*", mockserver.LocalURL(), path)) + } + } + return nil +} + +// SetMockserverWithTokenPriceValue sets the mock responses in mockserver that are read by chainlink nodes +// to simulate different price feed value. +// it keeps updating the response every 15 seconds to simulate price feed updates +func SetMockserverWithTokenPriceValue( + killGrave *ctftestenv.Killgrave, + mockserver *ctfClient.MockserverClient, +) { + wg := &sync.WaitGroup{} + path := "token_contract_" + wg.Add(1) + go func() { + set := true + // keep updating token value every 15 second + for { + if killGrave == nil && mockserver == nil { + log.Fatal().Msg("both killgrave and mockserver are nil") + return + } + tokenValue := big.NewInt(time.Now().UnixNano()).String() + if killGrave != nil { + err := killGrave.SetAdapterBasedAnyValuePath(fmt.Sprintf("%s{.*}", path), []string{http.MethodGet}, tokenValue) + if err != nil { + log.Fatal().Err(err).Msg("failed to set killgrave server value") + return + } + } + if mockserver != nil { + err := mockserver.SetAnyValuePath(fmt.Sprintf("/%s.*", path), tokenValue) + if err != nil { + log.Fatal().Err(err).Str("URL", fmt.Sprintf("%s/%s/.*", mockserver.LocalURL(), path)).Msg("failed to set mockserver value") + return + } + } + if set { + set = false + wg.Done() + } + time.Sleep(15 * time.Second) + } + }() + // wait for the first value to be set + wg.Wait() +} + +// TokenPricePipelineURLs returns the mockserver urls for the token price pipeline +func TokenPricePipelineURLs( + tokenAddresses []string, + killGrave *ctftestenv.Killgrave, + mockserver *ctfClient.MockserverClient, +) map[string]string { + mapTokenURL := make(map[string]string) + + for _, tokenAddr := range tokenAddresses { + path := fmt.Sprintf("token_contract_%s", tokenAddr[2:12]) + if mockserver != nil { + mapTokenURL[tokenAddr] = fmt.Sprintf("%s/%s", mockserver.Config.ClusterURL, path) + } + if killGrave != nil { + mapTokenURL[tokenAddr] = fmt.Sprintf("%s/%s", killGrave.InternalEndpoint, path) + } + } + + return mapTokenURL +} diff --git a/integration-tests/ccip-tests/actions/ccip_helpers_test.go b/integration-tests/ccip-tests/actions/ccip_helpers_test.go new file mode 100644 index 0000000000..4ca1061d6f --- /dev/null +++ b/integration-tests/ccip-tests/actions/ccip_helpers_test.go @@ -0,0 +1,105 @@ +package actions + +import ( + "errors" + "testing" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testreporters" +) + +func TestIsPhaseValid(t *testing.T) { + // isPhaseValid has some complex logic that could lead to false negatives + t.Parallel() + logger := zerolog.New(zerolog.Nop()) + + testCases := []struct { + name string + currentPhase testreporters.Phase + opts validationOptions + phaseErr error + + expectedShouldReturn bool + expectedErr error + }{ + { + name: "should return error immediately if phase error is present and no phase is expected to fail", + currentPhase: testreporters.CCIPSendRe, + opts: validationOptions{}, + phaseErr: errors.New("some error"), + + expectedShouldReturn: true, + expectedErr: errors.New("some error"), + }, + { + name: "should return with no error if phase is expected to fail and phase error present", + currentPhase: testreporters.CCIPSendRe, + opts: validationOptions{ + phaseExpectedToFail: testreporters.CCIPSendRe, + }, + phaseErr: errors.New("some error"), + + expectedShouldReturn: true, + expectedErr: nil, + }, + { + name: "should return with error if phase is expected to fail and no phase error present", + currentPhase: testreporters.CCIPSendRe, + opts: validationOptions{ + phaseExpectedToFail: testreporters.CCIPSendRe, + }, + phaseErr: nil, + + expectedShouldReturn: true, + expectedErr: errors.New("expected phase 'CCIPSendRequested' to fail, but it passed"), + }, + { + name: "should not return if phase is not expected to fail and no phase error present", + currentPhase: testreporters.CCIPSendRe, + opts: validationOptions{ + phaseExpectedToFail: testreporters.ExecStateChanged, + }, + phaseErr: nil, + + expectedShouldReturn: false, + expectedErr: nil, + }, + { + name: "should return with no error if phase is expected to fail with specific error message and that error message is present", + currentPhase: testreporters.CCIPSendRe, + opts: validationOptions{ + phaseExpectedToFail: testreporters.CCIPSendRe, + expectedErrorMessage: "some error", + }, + phaseErr: errors.New("some error"), + + expectedShouldReturn: true, + expectedErr: nil, + }, + { + name: "should return with error if phase is expected to fail with specific error message and that error message is not present", + currentPhase: testreporters.CCIPSendRe, + opts: validationOptions{ + phaseExpectedToFail: testreporters.CCIPSendRe, + expectedErrorMessage: "some error", + }, + phaseErr: errors.New("some other error"), + + expectedShouldReturn: true, + expectedErr: errors.New("expected phase 'CCIPSendRequested' to fail with error message 'some error' but got error 'some other error'"), + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + shouldReturn, err := isPhaseValid(&logger, tc.currentPhase, tc.opts, tc.phaseErr) + require.Equal(t, tc.expectedShouldReturn, shouldReturn, "shouldReturn not as expected") + require.Equal(t, tc.expectedErr, err, "err not as expected") + }) + } +} diff --git a/integration-tests/ccip-tests/chaos/ccip_test.go b/integration-tests/ccip-tests/chaos/ccip_test.go new file mode 100644 index 0000000000..4b1dda7a91 --- /dev/null +++ b/integration-tests/ccip-tests/chaos/ccip_test.go @@ -0,0 +1,153 @@ +package chaos_test + +import ( + "math/big" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-testing-framework/k8s/chaos" + "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" +) + +/* @network-chaos and @pod-chaos are split intentionally into 2 parallel groups +we can't use chaos.NewNetworkPartition and chaos.NewFailPods in parallel +because of jsii runtime bug, see Makefile and please use those targets to run tests +In .github/workflows/ccip-chaos-tests.yml we use these tags to run these tests separately +*/ + +func TestChaosCCIP(t *testing.T) { + inputs := []struct { + testName string + chaosFunc chaos.ManifestFunc + chaosProps *chaos.Props + waitForChaosRecovery bool + }{ + { + testName: "CCIP works after rpc is down for NetworkA @network-chaos", + chaosFunc: chaos.NewNetworkPartition, + chaosProps: &chaos.Props{ + FromLabels: &map[string]*string{actions.ChaosGroupNetworkACCIPGeth: ptr.Ptr("1")}, + // chainlink-0 is default label set for all cll nodes + ToLabels: &map[string]*string{"app": ptr.Ptr("chainlink-0")}, + DurationStr: "1m", + }, + waitForChaosRecovery: true, + }, + { + testName: "CCIP works after rpc is down for NetworkB @network-chaos", + chaosFunc: chaos.NewNetworkPartition, + chaosProps: &chaos.Props{ + FromLabels: &map[string]*string{actions.ChaosGroupNetworkBCCIPGeth: ptr.Ptr("1")}, + ToLabels: &map[string]*string{"app": ptr.Ptr("chainlink-0")}, + DurationStr: "1m", + }, + waitForChaosRecovery: true, + }, + { + testName: "CCIP works after 2 rpc's are down for all cll nodes @network-chaos", + chaosFunc: chaos.NewNetworkPartition, + chaosProps: &chaos.Props{ + FromLabels: &map[string]*string{"geth": ptr.Ptr(actions.ChaosGroupCCIPGeth)}, + ToLabels: &map[string]*string{"app": ptr.Ptr("chainlink-0")}, + DurationStr: "1m", + }, + waitForChaosRecovery: true, + }, + { + testName: "CCIP Commit works after majority of CL nodes are recovered from pod failure @pod-chaos", + chaosFunc: chaos.NewFailPods, + chaosProps: &chaos.Props{ + LabelsSelector: &map[string]*string{actions.ChaosGroupCommitFaultyPlus: ptr.Ptr("1")}, + DurationStr: "1m", + }, + waitForChaosRecovery: true, + }, + { + testName: "CCIP Execution works after majority of CL nodes are recovered from pod failure @pod-chaos", + chaosFunc: chaos.NewFailPods, + chaosProps: &chaos.Props{ + LabelsSelector: &map[string]*string{actions.ChaosGroupExecutionFaultyPlus: ptr.Ptr("1")}, + DurationStr: "1m", + }, + waitForChaosRecovery: true, + }, + { + testName: "CCIP Commit works while minority of CL nodes are in failed state for pod failure @pod-chaos", + chaosFunc: chaos.NewFailPods, + chaosProps: &chaos.Props{ + LabelsSelector: &map[string]*string{actions.ChaosGroupCommitFaulty: ptr.Ptr("1")}, + DurationStr: "90s", + }, + waitForChaosRecovery: false, + }, + { + testName: "CCIP Execution works while minority of CL nodes are in failed state for pod failure @pod-chaos", + chaosFunc: chaos.NewFailPods, + chaosProps: &chaos.Props{ + LabelsSelector: &map[string]*string{actions.ChaosGroupExecutionFaulty: ptr.Ptr("1")}, + DurationStr: "90s", + }, + waitForChaosRecovery: false, + }, + } + + for _, in := range inputs { + in := in + t.Run(in.testName, func(t *testing.T) { + t.Parallel() + l := logging.GetTestLogger(t) + testCfg := testsetups.NewCCIPTestConfig(t, l, testconfig.Chaos) + var numOfRequests = 3 + + setUpArgs := testsetups.CCIPDefaultTestSetUp( + t, &l, "chaos-ccip", nil, testCfg) + + if len(setUpArgs.Lanes) == 0 { + return + } + + lane := setUpArgs.Lanes[0].ForwardLane + + tearDown := setUpArgs.TearDown + testEnvironment := setUpArgs.Env.K8Env + testSetup := setUpArgs.Env + + testSetup.ChaosLabelForGeth(t, lane.SourceChain.GetNetworkName(), lane.DestChain.GetNetworkName()) + testSetup.ChaosLabelForCLNodes(t) + + lane.RecordStateBeforeTransfer() + // Send the ccip-request and verify ocr2 is running + err := lane.SendRequests(1, big.NewInt(actions.DefaultDestinationGasLimit)) + require.NoError(t, err) + lane.ValidateRequests(nil) + + // apply chaos + chaosId, err := testEnvironment.Chaos.Run(in.chaosFunc(testEnvironment.Cfg.Namespace, in.chaosProps)) + require.NoError(t, err) + t.Cleanup(func() { + if chaosId != "" { + require.NoError(t, testEnvironment.Chaos.Stop(chaosId)) + } + require.NoError(t, tearDown()) + }) + lane.RecordStateBeforeTransfer() + // Now send the ccip-request while the chaos is at play + err = lane.SendRequests(numOfRequests, big.NewInt(actions.DefaultDestinationGasLimit)) + require.NoError(t, err) + if in.waitForChaosRecovery { + // wait for chaos to be recovered before further validation + require.NoError(t, testEnvironment.Chaos.WaitForAllRecovered(chaosId, 1*time.Minute)) + } else { + l.Info().Msg("proceeding without waiting for chaos recovery") + } + lane.ValidateRequests(nil) + }) + } +} diff --git a/integration-tests/ccip-tests/contracts/contract_deployer.go b/integration-tests/ccip-tests/contracts/contract_deployer.go new file mode 100644 index 0000000000..8656656e0b --- /dev/null +++ b/integration-tests/ccip-tests/contracts/contract_deployer.go @@ -0,0 +1,1586 @@ +package contracts + +import ( + "context" + "crypto/ed25519" + "encoding/hex" + "fmt" + "math/big" + "strings" + "time" + + "github.com/Masterminds/semver/v3" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "golang.org/x/crypto/curve25519" + + ocrconfighelper2 "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" + ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2/types" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + + "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/wrappers" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_messenger" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_v3_aggregator_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_pool_1_4_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/usdc_token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/usdc_token_pool_1_4_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + type_and_version "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/type_and_version_interface_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/erc20" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" +) + +// MatchContractVersionsOrAbove checks if the current contract versions for the test match or exceed the provided contract versions +func MatchContractVersionsOrAbove(requiredContractVersions map[Name]Version) error { + for contractName, r := range requiredContractVersions { + required := r + if contractVersion, ok := VersionMap[contractName]; !ok { + return fmt.Errorf("contract %s not found in version map", contractName) + } else if contractVersion.Compare(&required.Version) < 0 { + return fmt.Errorf("contract %s version %s is less than required version %s", contractName, contractVersion, required.Version) + } + } + return nil +} + +// NeedTokenAdminRegistry checks if token admin registry is needed for the current version of ccip +// if the version is less than 1.5.0-dev, then token admin registry is not needed +func NeedTokenAdminRegistry() bool { + return MatchContractVersionsOrAbove(map[Name]Version{ + TokenPoolContract: V1_5_0_dev, + }) == nil +} + +// CCIPContractsDeployer provides the implementations for deploying CCIP ETH contracts +type CCIPContractsDeployer struct { + evmClient blockchain.EVMClient + logger *zerolog.Logger +} + +// NewCCIPContractsDeployer returns an instance of a contract deployer for CCIP +func NewCCIPContractsDeployer(logger *zerolog.Logger, bcClient blockchain.EVMClient) (*CCIPContractsDeployer, error) { + return &CCIPContractsDeployer{ + evmClient: bcClient, + logger: logger, + }, nil +} + +func (e *CCIPContractsDeployer) Client() blockchain.EVMClient { + return e.evmClient +} + +func (e *CCIPContractsDeployer) DeployMultiCallContract() (common.Address, error) { + multiCallABI, err := abi.JSON(strings.NewReader(MultiCallABI)) + if err != nil { + return common.Address{}, err + } + address, tx, _, err := e.evmClient.DeployContract("MultiCall Contract", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + address, tx, contract, err := bind.DeployContract(auth, multiCallABI, common.FromHex(MultiCallBIN), wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, contract, err + }) + if err != nil { + return common.Address{}, err + } + r, err := bind.WaitMined(context.Background(), e.evmClient.DeployBackend(), tx) + if err != nil { + return common.Address{}, err + } + if r.Status != types.ReceiptStatusSuccessful { + return common.Address{}, fmt.Errorf("deploy multicall failed") + } + return *address, nil +} + +func (e *CCIPContractsDeployer) DeployTokenMessenger(tokenTransmitter common.Address) (*common.Address, error) { + address, _, _, err := e.evmClient.DeployContract("Mock Token Messenger", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + address, tx, contract, err := mock_usdc_token_messenger.DeployMockE2EUSDCTokenMessenger(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil), 0, tokenTransmitter) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, contract, err + }) + + return address, err +} + +func (e *CCIPContractsDeployer) NewTokenTransmitter(addr common.Address) (*TokenTransmitter, error) { + transmitter, err := mock_usdc_token_transmitter.NewMockE2EUSDCTransmitter(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + + if err != nil { + return nil, err + } + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "Mock USDC Token Transmitter"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + return &TokenTransmitter{ + client: e.evmClient, + instance: transmitter, + ContractAddress: addr, + }, err +} + +func (e *CCIPContractsDeployer) DeployTokenTransmitter(domain uint32, usdcToken common.Address) (*TokenTransmitter, error) { + address, _, instance, err := e.evmClient.DeployContract("Mock Token Transmitter", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + address, tx, contract, err := mock_usdc_token_transmitter.DeployMockE2EUSDCTransmitter(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil), 0, domain, usdcToken) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, contract, err + }) + + if err != nil { + return nil, fmt.Errorf("error in deploying usdc token transmitter: %w", err) + } + + return &TokenTransmitter{ + client: e.evmClient, + instance: instance.(*mock_usdc_token_transmitter.MockE2EUSDCTransmitter), + ContractAddress: *address, + }, err +} + +func (e *CCIPContractsDeployer) DeployLinkTokenContract() (*LinkToken, error) { + address, _, instance, err := e.evmClient.DeployContract("Link Token", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return link_token_interface.DeployLinkToken(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + }) + + if err != nil { + return nil, err + } + return &LinkToken{ + client: e.evmClient, + logger: e.logger, + instance: instance.(*link_token_interface.LinkToken), + EthAddress: *address, + }, err +} + +// DeployBurnMintERC677 deploys a BurnMintERC677 contract, mints given amount ( if provided) to the owner address and returns the ERC20Token wrapper instance +func (e *CCIPContractsDeployer) DeployBurnMintERC677(ownerMintingAmount *big.Int) (*ERC677Token, error) { + address, _, instance, err := e.evmClient.DeployContract("Burn Mint ERC 677", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return burn_mint_erc677.DeployBurnMintERC677(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil), "Test Token ERC677", "TERC677", 6, new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e9))) + }) + if err != nil { + return nil, err + } + + token := &ERC677Token{ + client: e.evmClient, + logger: e.logger, + ContractAddress: *address, + instance: instance.(*burn_mint_erc677.BurnMintERC677), + OwnerAddress: common.HexToAddress(e.evmClient.GetDefaultWallet().Address()), + OwnerWallet: e.evmClient.GetDefaultWallet(), + } + if ownerMintingAmount != nil { + // grant minter role to owner and mint tokens + err = token.GrantMintRole(common.HexToAddress(e.evmClient.GetDefaultWallet().Address())) + if err != nil { + return token, fmt.Errorf("granting minter role to owner shouldn't fail %w", err) + } + err = e.evmClient.WaitForEvents() + if err != nil { + return token, fmt.Errorf("error in waiting for granting mint role %w", err) + } + err = token.Mint(common.HexToAddress(e.evmClient.GetDefaultWallet().Address()), ownerMintingAmount) + if err != nil { + return token, fmt.Errorf("minting tokens shouldn't fail %w", err) + } + } + return token, err +} + +func (e *CCIPContractsDeployer) DeployERC20TokenContract(deployerFn blockchain.ContractDeployer) (*ERC20Token, error) { + address, _, _, err := e.evmClient.DeployContract("Custom ERC20 Token", deployerFn) + if err != nil { + return nil, err + } + err = e.evmClient.WaitForEvents() + if err != nil { + return nil, err + } + return e.NewERC20TokenContract(*address) +} + +func (e *CCIPContractsDeployer) NewLinkTokenContract(addr common.Address) (*LinkToken, error) { + token, err := link_token_interface.NewLinkToken(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + + if err != nil { + return nil, err + } + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "Link Token"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + return &LinkToken{ + client: e.evmClient, + logger: e.logger, + instance: token, + EthAddress: addr, + }, err +} + +func (e *CCIPContractsDeployer) NewERC20TokenContract(addr common.Address) (*ERC20Token, error) { + token, err := erc20.NewERC20(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + + if err != nil { + return nil, err + } + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "ERC20 Token"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + return &ERC20Token{ + client: e.evmClient, + logger: e.logger, + instance: token, + ContractAddress: addr, + OwnerAddress: common.HexToAddress(e.evmClient.GetDefaultWallet().Address()), + OwnerWallet: e.evmClient.GetDefaultWallet(), + }, err +} + +func (e *CCIPContractsDeployer) NewLockReleaseTokenPoolContract(addr common.Address) ( + *TokenPool, + error, +) { + version := VersionMap[TokenPoolContract] + e.logger.Info().Str("Version", version.String()).Msg("New LockRelease Token Pool") + switch version { + case Latest: + pool, err := lock_release_token_pool.NewLockReleaseTokenPool(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + + if err != nil { + return nil, err + } + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "Native Token Pool"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + poolInstance, err := token_pool.NewTokenPool(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, err + } + return &TokenPool{ + client: e.evmClient, + logger: e.logger, + Instance: &TokenPoolWrapper{ + Latest: &LatestPool{ + PoolInterface: poolInstance, + LockReleasePool: pool, + }, + }, + EthAddress: addr, + OwnerAddress: common.HexToAddress(e.evmClient.GetDefaultWallet().Address()), + OwnerWallet: e.evmClient.GetDefaultWallet(), + }, err + case V1_4_0: + pool, err := lock_release_token_pool_1_4_0.NewLockReleaseTokenPool(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, err + } + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "Native Token Pool"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + poolInstance, err := token_pool_1_4_0.NewTokenPool(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, err + } + return &TokenPool{ + client: e.evmClient, + logger: e.logger, + Instance: &TokenPoolWrapper{ + V1_4_0: &V1_4_0Pool{ + PoolInterface: poolInstance, + LockReleasePool: pool, + }, + }, + EthAddress: addr, + OwnerAddress: common.HexToAddress(e.evmClient.GetDefaultWallet().Address()), + OwnerWallet: e.evmClient.GetDefaultWallet(), + }, err + default: + return nil, fmt.Errorf("version not supported: %s", version) + } +} + +func (e *CCIPContractsDeployer) NewUSDCTokenPoolContract(addr common.Address) ( + *TokenPool, + error, +) { + version := VersionMap[TokenPoolContract] + e.logger.Info().Str("Version", version.String()).Msg("New USDC Token Pool") + switch version { + case Latest: + pool, err := usdc_token_pool.NewUSDCTokenPool(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + + if err != nil { + return nil, err + } + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "USDC Token Pool"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + poolInterface, err := token_pool.NewTokenPool(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, err + } + return &TokenPool{ + client: e.evmClient, + logger: e.logger, + Instance: &TokenPoolWrapper{ + Latest: &LatestPool{ + PoolInterface: poolInterface, + USDCPool: pool, + }, + }, + EthAddress: addr, + OwnerAddress: common.HexToAddress(e.evmClient.GetDefaultWallet().Address()), + OwnerWallet: e.evmClient.GetDefaultWallet(), + }, err + case V1_4_0: + pool, err := usdc_token_pool_1_4_0.NewUSDCTokenPool(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + + if err != nil { + return nil, err + } + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "USDC Token Pool"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + poolInterface, err := token_pool_1_4_0.NewTokenPool(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, err + } + return &TokenPool{ + client: e.evmClient, + logger: e.logger, + Instance: &TokenPoolWrapper{ + V1_4_0: &V1_4_0Pool{ + PoolInterface: poolInterface, + USDCPool: pool, + }, + }, + EthAddress: addr, + OwnerAddress: common.HexToAddress(e.evmClient.GetDefaultWallet().Address()), + OwnerWallet: e.evmClient.GetDefaultWallet(), + }, err + default: + return nil, fmt.Errorf("version not supported: %s", version) + } + +} + +func (e *CCIPContractsDeployer) DeployUSDCTokenPoolContract(tokenAddr string, tokenMessenger, rmnProxy common.Address, router common.Address) ( + *TokenPool, + error, +) { + version := VersionMap[TokenPoolContract] + e.logger.Debug().Str("Token", tokenAddr).Msg("Deploying USDC token pool") + token := common.HexToAddress(tokenAddr) + switch version { + case Latest: + address, _, _, err := e.evmClient.DeployContract("USDC Token Pool", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return usdc_token_pool.DeployUSDCTokenPool( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + tokenMessenger, + token, + []common.Address{}, + rmnProxy, + router, + ) + }) + + if err != nil { + return nil, err + } + return e.NewUSDCTokenPoolContract(*address) + case V1_4_0: + address, _, _, err := e.evmClient.DeployContract("USDC Token Pool", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return usdc_token_pool_1_4_0.DeployUSDCTokenPool( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + tokenMessenger, + token, + []common.Address{}, + rmnProxy, + router, + ) + }) + + if err != nil { + return nil, err + } + return e.NewUSDCTokenPoolContract(*address) + default: + return nil, fmt.Errorf("version not supported: %s", version) + } +} + +func (e *CCIPContractsDeployer) DeployLockReleaseTokenPoolContract(tokenAddr string, rmnProxy common.Address, router common.Address) ( + *TokenPool, + error, +) { + version := VersionMap[TokenPoolContract] + e.logger.Info().Str("Version", version.String()).Msg("Deploying LockRelease Token Pool") + token := common.HexToAddress(tokenAddr) + switch version { + case Latest: + address, _, _, err := e.evmClient.DeployContract("LockRelease Token Pool", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return lock_release_token_pool.DeployLockReleaseTokenPool( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + token, + []common.Address{}, + rmnProxy, + true, + router, + ) + }) + + if err != nil { + return nil, err + } + return e.NewLockReleaseTokenPoolContract(*address) + case V1_4_0: + address, _, _, err := e.evmClient.DeployContract("LockRelease Token Pool", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return lock_release_token_pool_1_4_0.DeployLockReleaseTokenPool( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + token, + []common.Address{}, + rmnProxy, + true, + router, + ) + }) + + if err != nil { + return nil, err + } + return e.NewLockReleaseTokenPoolContract(*address) + default: + return nil, fmt.Errorf("version not supported: %s", version) + } +} + +func (e *CCIPContractsDeployer) DeployMockARMContract() (*common.Address, error) { + address, _, _, err := e.evmClient.DeployContract("Mock ARM Contract", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return mock_arm_contract.DeployMockARMContract(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + }) + return address, err +} + +func (e *CCIPContractsDeployer) NewARMContract(addr common.Address) (*ARM, error) { + arm, err := arm_contract.NewARMContract(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, err + } + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "Mock ARM Contract"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + + return &ARM{ + client: e.evmClient, + Instance: arm, + EthAddress: addr, + }, err +} + +func (e *CCIPContractsDeployer) NewCommitStore(addr common.Address) ( + *CommitStore, + error, +) { + version := VersionMap[CommitStoreContract] + e.logger.Info().Str("Version", version.String()).Msg("New CommitStore") + switch version { + case Latest: + ins, err := commit_store.NewCommitStore(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "CommitStore"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + return &CommitStore{ + client: e.evmClient, + logger: e.logger, + Instance: &CommitStoreWrapper{ + Latest: ins, + }, + EthAddress: addr, + }, err + case V1_2_0: + ins, err := commit_store_1_2_0.NewCommitStore(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "CommitStore"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + return &CommitStore{ + client: e.evmClient, + logger: e.logger, + Instance: &CommitStoreWrapper{ + V1_2_0: ins, + }, + EthAddress: addr, + }, err + default: + return nil, fmt.Errorf("version not supported: %s", version) + } +} + +func (e *CCIPContractsDeployer) DeployCommitStore(sourceChainSelector, destChainSelector uint64, onRamp common.Address, armProxy common.Address) (*CommitStore, error) { + version, ok := VersionMap[CommitStoreContract] + if !ok { + return nil, fmt.Errorf("versioning not supported: %s", version) + } + e.logger.Info().Str("Version", version.String()).Msg("Deploying CommitStore") + switch version { + case Latest: + address, _, instance, err := e.evmClient.DeployContract("CommitStore Contract", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return commit_store.DeployCommitStore( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + commit_store.CommitStoreStaticConfig{ + ChainSelector: destChainSelector, + SourceChainSelector: sourceChainSelector, + OnRamp: onRamp, + RmnProxy: armProxy, + }, + ) + }) + if err != nil { + return nil, err + } + return &CommitStore{ + client: e.evmClient, + logger: e.logger, + Instance: &CommitStoreWrapper{ + Latest: instance.(*commit_store.CommitStore), + }, + EthAddress: *address, + }, err + case V1_2_0: + address, _, instance, err := e.evmClient.DeployContract("CommitStore Contract", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return commit_store_1_2_0.DeployCommitStore( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + commit_store_1_2_0.CommitStoreStaticConfig{ + ChainSelector: destChainSelector, + SourceChainSelector: sourceChainSelector, + OnRamp: onRamp, + ArmProxy: armProxy, + }, + ) + }) + if err != nil { + return nil, err + } + return &CommitStore{ + client: e.evmClient, + logger: e.logger, + Instance: &CommitStoreWrapper{ + V1_2_0: instance.(*commit_store_1_2_0.CommitStore), + }, + EthAddress: *address, + }, err + default: + return nil, fmt.Errorf("version not supported: %s", version) + } +} + +func (e *CCIPContractsDeployer) DeployReceiverDapp(revert bool) ( + *ReceiverDapp, + error, +) { + address, _, instance, err := e.evmClient.DeployContract("ReceiverDapp", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil), revert) + }) + if err != nil { + return nil, err + } + return &ReceiverDapp{ + client: e.evmClient, + logger: e.logger, + instance: instance.(*maybe_revert_message_receiver.MaybeRevertMessageReceiver), + EthAddress: *address, + }, err +} + +func (e *CCIPContractsDeployer) NewReceiverDapp(addr common.Address) ( + *ReceiverDapp, + error, +) { + ins, err := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "ReceiverDapp"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + return &ReceiverDapp{ + client: e.evmClient, + logger: e.logger, + instance: ins, + EthAddress: addr, + }, err +} + +func (e *CCIPContractsDeployer) DeployRouter(wrappedNative common.Address, armAddress common.Address) ( + *Router, + error, +) { + address, _, instance, err := e.evmClient.DeployContract("Router", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return router.DeployRouter(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil), wrappedNative, armAddress) + }) + if err != nil { + return nil, err + } + return &Router{ + client: e.evmClient, + logger: e.logger, + Instance: instance.(*router.Router), + EthAddress: *address, + }, err +} + +func (e *CCIPContractsDeployer) NewRouter(addr common.Address) ( + *Router, + error, +) { + r, err := router.NewRouter(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "Router"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + if err != nil { + return nil, err + } + return &Router{ + client: e.evmClient, + logger: e.logger, + Instance: r, + EthAddress: addr, + }, err +} + +func (e *CCIPContractsDeployer) NewPriceRegistry(addr common.Address) ( + *PriceRegistry, + error, +) { + var wrapper *PriceRegistryWrapper + version := VersionMap[PriceRegistryContract] + e.logger.Info().Str("Version", version.String()).Msg("New PriceRegistry") + switch version { + case Latest: + ins, err := price_registry_1_2_0.NewPriceRegistry(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, fmt.Errorf("error in creating price registry instance: %w", err) + } + wrapper = &PriceRegistryWrapper{ + V1_2_0: ins, + } + case V1_2_0: + ins, err := price_registry_1_2_0.NewPriceRegistry(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, fmt.Errorf("error in creating price registry instance: %w", err) + } + wrapper = &PriceRegistryWrapper{ + V1_2_0: ins, + } + default: + return nil, fmt.Errorf("version not supported: %s", version) + } + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "PriceRegistry"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + return &PriceRegistry{ + client: e.evmClient, + logger: e.logger, + Instance: wrapper, + EthAddress: addr, + }, nil +} + +func (e *CCIPContractsDeployer) DeployPriceRegistry(tokens []common.Address) (*PriceRegistry, error) { + var address *common.Address + var wrapper *PriceRegistryWrapper + var err error + var instance interface{} + version := VersionMap[PriceRegistryContract] + e.logger.Info().Str("Version", version.String()).Msg("Deploying PriceRegistry") + switch version { + case Latest: + address, _, instance, err = e.evmClient.DeployContract("PriceRegistry", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return price_registry_1_2_0.DeployPriceRegistry(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil), nil, tokens, 60*60*24*14) + }) + if err != nil { + return nil, err + } + wrapper = &PriceRegistryWrapper{ + V1_2_0: instance.(*price_registry_1_2_0.PriceRegistry), + } + case V1_2_0: + address, _, instance, err = e.evmClient.DeployContract("PriceRegistry", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return price_registry_1_2_0.DeployPriceRegistry(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil), nil, tokens, 60*60*24*14) + }) + if err != nil { + return nil, err + } + wrapper = &PriceRegistryWrapper{ + V1_2_0: instance.(*price_registry_1_2_0.PriceRegistry), + } + default: + return nil, fmt.Errorf("version not supported: %s", version) + } + reg := &PriceRegistry{ + client: e.evmClient, + logger: e.logger, + EthAddress: *address, + Instance: wrapper, + } + return reg, err +} + +func (e *CCIPContractsDeployer) DeployTokenAdminRegistry() (*TokenAdminRegistry, error) { + address, _, instance, err := e.evmClient.DeployContract("TokenAdminRegistry", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return token_admin_registry.DeployTokenAdminRegistry(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + }) + if err != nil { + return nil, err + } + return &TokenAdminRegistry{ + client: e.evmClient, + logger: e.logger, + Instance: instance.(*token_admin_registry.TokenAdminRegistry), + EthAddress: *address, + }, err +} + +func (e *CCIPContractsDeployer) NewTokenAdminRegistry(addr common.Address) ( + *TokenAdminRegistry, + error, +) { + ins, err := token_admin_registry.NewTokenAdminRegistry(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "TokenAdminRegistry"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + return &TokenAdminRegistry{ + client: e.evmClient, + logger: e.logger, + Instance: ins, + EthAddress: addr, + }, err +} + +func (e *CCIPContractsDeployer) NewOnRamp(addr common.Address) ( + *OnRamp, + error, +) { + version := VersionMap[OnRampContract] + e.logger.Info().Str("Version", version.String()).Msg("New OnRamp") + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "OnRamp"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + switch version { + case V1_2_0: + ins, err := evm_2_evm_onramp_1_2_0.NewEVM2EVMOnRamp(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, err + } + return &OnRamp{ + client: e.evmClient, + logger: e.logger, + Instance: &OnRampWrapper{V1_2_0: ins}, + EthAddress: addr, + }, err + case Latest: + ins, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, err + } + return &OnRamp{ + client: e.evmClient, + logger: e.logger, + Instance: &OnRampWrapper{Latest: ins}, + EthAddress: addr, + }, nil + default: + return nil, fmt.Errorf("version not supported: %s", version) + } +} + +func (e *CCIPContractsDeployer) DeployOnRamp( + sourceChainSelector, destChainSelector uint64, + tokensAndPools []evm_2_evm_onramp_1_2_0.InternalPoolUpdate, + rmn, + router, + priceRegistry, + tokenAdminRegistry common.Address, + opts RateLimiterConfig, + feeTokenConfig []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs, + tokenTransferFeeConfig []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs, + linkTokenAddress common.Address, +) (*OnRamp, error) { + version := VersionMap[OnRampContract] + e.logger.Info().Str("Version", version.String()).Msg("Deploying OnRamp") + switch version { + case V1_2_0: + feeTokenConfigV1_2_0 := make([]evm_2_evm_onramp_1_2_0.EVM2EVMOnRampFeeTokenConfigArgs, len(feeTokenConfig)) + for i, f := range feeTokenConfig { + feeTokenConfigV1_2_0[i] = evm_2_evm_onramp_1_2_0.EVM2EVMOnRampFeeTokenConfigArgs{ + Token: f.Token, + NetworkFeeUSDCents: f.NetworkFeeUSDCents, + GasMultiplierWeiPerEth: f.GasMultiplierWeiPerEth, + PremiumMultiplierWeiPerEth: f.PremiumMultiplierWeiPerEth, + Enabled: f.Enabled, + } + } + tokenTransferFeeConfigV1_2_0 := make([]evm_2_evm_onramp_1_2_0.EVM2EVMOnRampTokenTransferFeeConfigArgs, len(tokenTransferFeeConfig)) + for i, f := range tokenTransferFeeConfig { + tokenTransferFeeConfigV1_2_0[i] = evm_2_evm_onramp_1_2_0.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + Token: f.Token, + MinFeeUSDCents: f.MinFeeUSDCents, + MaxFeeUSDCents: f.MaxFeeUSDCents, + DeciBps: f.DeciBps, + DestGasOverhead: f.DestGasOverhead, + DestBytesOverhead: f.DestBytesOverhead, + } + } + address, _, instance, err := e.evmClient.DeployContract("OnRamp", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return evm_2_evm_onramp_1_2_0.DeployEVM2EVMOnRamp( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + evm_2_evm_onramp_1_2_0.EVM2EVMOnRampStaticConfig{ + LinkToken: linkTokenAddress, + ChainSelector: sourceChainSelector, // source chain id + DestChainSelector: destChainSelector, // destinationChainSelector + DefaultTxGasLimit: 200_000, + MaxNopFeesJuels: big.NewInt(0).Mul(big.NewInt(100_000_000), big.NewInt(1e18)), + PrevOnRamp: common.HexToAddress(""), + ArmProxy: rmn, + }, + evm_2_evm_onramp_1_2_0.EVM2EVMOnRampDynamicConfig{ + Router: router, + MaxNumberOfTokensPerMsg: 50, + DestGasOverhead: 350_000, + DestGasPerPayloadByte: 16, + DestDataAvailabilityOverheadGas: 33_596, + DestGasPerDataAvailabilityByte: 16, + DestDataAvailabilityMultiplierBps: 6840, // 0.684 + PriceRegistry: priceRegistry, + MaxDataBytes: 50000, + MaxPerMsgGasLimit: 4_000_000, + }, + tokensAndPools, + evm_2_evm_onramp_1_2_0.RateLimiterConfig{ + Capacity: opts.Capacity, + Rate: opts.Rate, + }, + feeTokenConfigV1_2_0, + tokenTransferFeeConfigV1_2_0, + []evm_2_evm_onramp_1_2_0.EVM2EVMOnRampNopAndWeight{}, + ) + }) + if err != nil { + return nil, err + } + return &OnRamp{ + client: e.evmClient, + logger: e.logger, + Instance: &OnRampWrapper{ + V1_2_0: instance.(*evm_2_evm_onramp_1_2_0.EVM2EVMOnRamp), + }, + EthAddress: *address, + }, nil + case Latest: + address, _, instance, err := e.evmClient.DeployContract("OnRamp", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return evm_2_evm_onramp.DeployEVM2EVMOnRamp( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ + LinkToken: linkTokenAddress, + ChainSelector: sourceChainSelector, // source chain id + DestChainSelector: destChainSelector, // destinationChainSelector + DefaultTxGasLimit: 200_000, + MaxNopFeesJuels: big.NewInt(0).Mul(big.NewInt(100_000_000), big.NewInt(1e18)), + PrevOnRamp: common.HexToAddress(""), + RmnProxy: rmn, + TokenAdminRegistry: tokenAdminRegistry, + }, + evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ + Router: router, + MaxNumberOfTokensPerMsg: 50, + DestGasOverhead: 350_000, + DestGasPerPayloadByte: 16, + DestDataAvailabilityOverheadGas: 33_596, + DestGasPerDataAvailabilityByte: 16, + DestDataAvailabilityMultiplierBps: 6840, // 0.684 + PriceRegistry: priceRegistry, + MaxDataBytes: 50000, + MaxPerMsgGasLimit: 4_000_000, + DefaultTokenFeeUSDCents: 50, + DefaultTokenDestGasOverhead: 125_000, + DefaultTokenDestBytesOverhead: 500, + }, + evm_2_evm_onramp.RateLimiterConfig{ + Capacity: opts.Capacity, + Rate: opts.Rate, + }, + feeTokenConfig, + tokenTransferFeeConfig, + []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{}, + ) + }) + if err != nil { + return nil, err + } + return &OnRamp{ + client: e.evmClient, + logger: e.logger, + Instance: &OnRampWrapper{ + Latest: instance.(*evm_2_evm_onramp.EVM2EVMOnRamp), + }, + EthAddress: *address, + }, err + default: + return nil, fmt.Errorf("version not supported: %s", version) + } +} + +func (e *CCIPContractsDeployer) NewOffRamp(addr common.Address) ( + *OffRamp, + error, +) { + version := VersionMap[OffRampContract] + e.logger.Info().Str("Version", version.String()).Msg("New OffRamp") + switch version { + case V1_2_0: + ins, err := evm_2_evm_offramp_1_2_0.NewEVM2EVMOffRamp(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, err + } + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "OffRamp"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + return &OffRamp{ + client: e.evmClient, + logger: e.logger, + Instance: &OffRampWrapper{V1_2_0: ins}, + EthAddress: addr, + }, err + case Latest: + ins, err := evm_2_evm_offramp.NewEVM2EVMOffRamp(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, err + } + e.logger.Info(). + Str("Contract Address", addr.Hex()). + Str("Contract Name", "OffRamp"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + return &OffRamp{ + client: e.evmClient, + logger: e.logger, + Instance: &OffRampWrapper{Latest: ins}, + EthAddress: addr, + }, err + default: + return nil, fmt.Errorf("version not supported: %s", version) + } +} + +func (e *CCIPContractsDeployer) DeployOffRamp( + sourceChainSelector, destChainSelector uint64, + commitStore, onRamp common.Address, + opts RateLimiterConfig, + sourceTokens, pools []common.Address, + rmnProxy common.Address, + tokenAdminRegistry common.Address, +) (*OffRamp, error) { + version := VersionMap[OffRampContract] + e.logger.Info().Str("Version", version.String()).Msg("Deploying OffRamp") + switch version { + case V1_2_0: + address, _, instance, err := e.evmClient.DeployContract("OffRamp Contract", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return evm_2_evm_offramp_1_2_0.DeployEVM2EVMOffRamp( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + evm_2_evm_offramp_1_2_0.EVM2EVMOffRampStaticConfig{ + CommitStore: commitStore, + ChainSelector: destChainSelector, + SourceChainSelector: sourceChainSelector, + OnRamp: onRamp, + PrevOffRamp: common.Address{}, + ArmProxy: rmnProxy, + }, + sourceTokens, + pools, + evm_2_evm_offramp_1_2_0.RateLimiterConfig{ + IsEnabled: true, + Capacity: opts.Capacity, + Rate: opts.Rate, + }, + ) + }) + if err != nil { + return nil, err + } + return &OffRamp{ + client: e.evmClient, + logger: e.logger, + Instance: &OffRampWrapper{ + V1_2_0: instance.(*evm_2_evm_offramp_1_2_0.EVM2EVMOffRamp), + }, + EthAddress: *address, + }, err + case Latest: + staticConfig := evm_2_evm_offramp.EVM2EVMOffRampStaticConfig{ + CommitStore: commitStore, + ChainSelector: destChainSelector, + SourceChainSelector: sourceChainSelector, + OnRamp: onRamp, + PrevOffRamp: common.Address{}, + RmnProxy: rmnProxy, + TokenAdminRegistry: tokenAdminRegistry, + } + address, _, instance, err := e.evmClient.DeployContract("OffRamp Contract", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return evm_2_evm_offramp.DeployEVM2EVMOffRamp( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + staticConfig, + evm_2_evm_offramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: opts.Capacity, + Rate: opts.Rate, + }, + ) + }) + e.logger.Info().Msg(fmt.Sprintf("deploying offramp with static config: %+v", staticConfig)) + + if err != nil { + return nil, err + } + return &OffRamp{ + client: e.evmClient, + logger: e.logger, + Instance: &OffRampWrapper{ + Latest: instance.(*evm_2_evm_offramp.EVM2EVMOffRamp), + }, + EthAddress: *address, + }, err + default: + return nil, fmt.Errorf("version not supported: %s", version) + } +} + +func (e *CCIPContractsDeployer) DeployWrappedNative() (*common.Address, error) { + address, _, _, err := e.evmClient.DeployContract("WrappedNative", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return weth9.DeployWETH9(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + }) + if err != nil { + return nil, err + } + return address, err +} + +func (e *CCIPContractsDeployer) DeployMockAggregator(decimals uint8, initialAns *big.Int) (*MockAggregator, error) { + address, _, instance, err := e.evmClient.DeployContract("MockAggregator", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return mock_v3_aggregator_contract.DeployMockV3Aggregator(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil), decimals, initialAns) + }) + if err != nil { + return nil, fmt.Errorf("deploying mock aggregator: %w", err) + } + e.logger.Info(). + Str("Contract Address", address.Hex()). + Str("Contract Name", "MockAggregator"). + Str("From", e.evmClient.GetDefaultWallet().Address()). + Str("Network Name", e.evmClient.GetNetworkConfig().Name). + Msg("New contract") + return &MockAggregator{ + client: e.evmClient, + logger: e.logger, + Instance: instance.(*mock_v3_aggregator_contract.MockV3Aggregator), + ContractAddress: *address, + }, nil +} + +func (e *CCIPContractsDeployer) NewMockAggregator(addr common.Address) (*MockAggregator, error) { + ins, err := mock_v3_aggregator_contract.NewMockV3Aggregator(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return nil, fmt.Errorf("creating mock aggregator: %w", err) + } + return &MockAggregator{ + client: e.evmClient, + logger: e.logger, + Instance: ins, + ContractAddress: addr, + }, nil +} + +func (e *CCIPContractsDeployer) TypeAndVersion(addr common.Address) (string, error) { + tv, err := type_and_version.NewTypeAndVersionInterface(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + if err != nil { + return "", err + } + tvStr, err := tv.TypeAndVersion(nil) + if err != nil { + return "", fmt.Errorf("error calling typeAndVersion on addr: %s %w", addr.Hex(), err) + } + e.logger.Info(). + Str("TypeAndVersion", tvStr). + Str("Contract Address", addr.Hex()). + Msg("TypeAndVersion") + + _, versionStr, err := ccipconfig.ParseTypeAndVersion(tvStr) + if err != nil { + return versionStr, err + } + v, err := semver.NewVersion(versionStr) + if err != nil { + return "", fmt.Errorf("failed parsing version %s: %w", versionStr, err) + } + return v.String(), nil +} + +// OCR2ParamsForCommit and OCR2ParamsForExec - +// These functions return the default OCR2 parameters for Commit and Exec respectively. +// Refer to CommitOCRParams and ExecOCRParams in CCIPTestConfig located in testconfig/ccip.go to override these values with custom param values. +func OCR2ParamsForCommit(blockTime time.Duration) contracts.OffChainAggregatorV2Config { + // slow blocktime chains like Ethereum + if blockTime >= 10*time.Second { + return contracts.OffChainAggregatorV2Config{ + DeltaProgress: 2 * time.Minute, + DeltaResend: 5 * time.Second, + DeltaRound: 90 * time.Second, + DeltaGrace: 5 * time.Second, + DeltaStage: 60 * time.Second, + MaxDurationQuery: 100 * time.Millisecond, + MaxDurationObservation: 35 * time.Second, + MaxDurationReport: 10 * time.Second, + MaxDurationShouldAcceptFinalizedReport: 5 * time.Second, + MaxDurationShouldTransmitAcceptedReport: 10 * time.Second, + } + } + // fast blocktime chains like Avalanche + return contracts.OffChainAggregatorV2Config{ + DeltaProgress: 2 * time.Minute, + DeltaResend: 5 * time.Second, + DeltaRound: 60 * time.Second, + DeltaGrace: 5 * time.Second, + DeltaStage: 25 * time.Second, + MaxDurationQuery: 100 * time.Millisecond, + MaxDurationObservation: 35 * time.Second, + MaxDurationReport: 10 * time.Second, + MaxDurationShouldAcceptFinalizedReport: 5 * time.Second, + MaxDurationShouldTransmitAcceptedReport: 10 * time.Second, + } +} + +func OCR2ParamsForExec(blockTime time.Duration) contracts.OffChainAggregatorV2Config { + // slow blocktime chains like Ethereum + if blockTime >= 10*time.Second { + return contracts.OffChainAggregatorV2Config{ + DeltaProgress: 2 * time.Minute, + DeltaResend: 5 * time.Second, + DeltaRound: 90 * time.Second, + DeltaGrace: 5 * time.Second, + DeltaStage: 60 * time.Second, + MaxDurationQuery: 100 * time.Millisecond, + MaxDurationObservation: 35 * time.Second, + MaxDurationReport: 10 * time.Second, + MaxDurationShouldAcceptFinalizedReport: 5 * time.Second, + MaxDurationShouldTransmitAcceptedReport: 10 * time.Second, + } + } + // fast blocktime chains like Avalanche + return contracts.OffChainAggregatorV2Config{ + DeltaProgress: 120 * time.Second, + DeltaResend: 5 * time.Second, + DeltaRound: 30 * time.Second, + DeltaGrace: 5 * time.Second, + DeltaStage: 10 * time.Second, + MaxDurationQuery: 100 * time.Millisecond, + MaxDurationObservation: 35 * time.Second, + MaxDurationReport: 10 * time.Second, + MaxDurationShouldAcceptFinalizedReport: 5 * time.Second, + MaxDurationShouldTransmitAcceptedReport: 10 * time.Second, + } +} + +func OffChainAggregatorV2ConfigWithNodes(numberNodes int, inflightExpiry time.Duration, cfg contracts.OffChainAggregatorV2Config) contracts.OffChainAggregatorV2Config { + if numberNodes <= 4 { + log.Err(fmt.Errorf("insufficient number of nodes (%d) supplied for OCR, need at least 5", numberNodes)). + Int("Number Chainlink Nodes", numberNodes). + Msg("You likely need more chainlink nodes to properly configure OCR, try 5 or more.") + } + s := make([]int, 0) + for i := 0; i < numberNodes; i++ { + s = append(s, 1) + } + faultyNodes := 0 + if numberNodes > 1 { + faultyNodes = (numberNodes - 1) / 3 + } + if faultyNodes == 0 { + faultyNodes = 1 + } + if cfg.DeltaStage == 0 { + cfg.DeltaStage = inflightExpiry + } + return contracts.OffChainAggregatorV2Config{ + DeltaProgress: cfg.DeltaProgress, + DeltaResend: cfg.DeltaResend, + DeltaRound: cfg.DeltaRound, + DeltaGrace: cfg.DeltaGrace, + DeltaStage: cfg.DeltaStage, + RMax: 3, + S: s, + F: faultyNodes, + Oracles: []ocrconfighelper2.OracleIdentityExtra{}, + MaxDurationQuery: cfg.MaxDurationQuery, + MaxDurationObservation: cfg.MaxDurationObservation, + MaxDurationReport: cfg.MaxDurationReport, + MaxDurationShouldAcceptFinalizedReport: cfg.MaxDurationShouldAcceptFinalizedReport, + MaxDurationShouldTransmitAcceptedReport: cfg.MaxDurationShouldTransmitAcceptedReport, + OnchainConfig: []byte{}, + } +} + +func stripKeyPrefix(key string) string { + chunks := strings.Split(key, "_") + if len(chunks) == 3 { + return chunks[2] + } + return key +} + +func NewCommitOffchainConfig( + GasPriceHeartBeat config.Duration, + DAGasPriceDeviationPPB uint32, + ExecGasPriceDeviationPPB uint32, + TokenPriceHeartBeat config.Duration, + TokenPriceDeviationPPB uint32, + InflightCacheExpiry config.Duration, + _ bool, // TODO: priceReportingDisabled added after this merge +) (ccipconfig.OffchainConfig, error) { + switch VersionMap[CommitStoreContract] { + case Latest: + return testhelpers.NewCommitOffchainConfig( + GasPriceHeartBeat, + DAGasPriceDeviationPPB, + ExecGasPriceDeviationPPB, + TokenPriceHeartBeat, + TokenPriceDeviationPPB, + InflightCacheExpiry, + ), nil + case V1_2_0: + return testhelpers_1_4_0.NewCommitOffchainConfig( + GasPriceHeartBeat, + DAGasPriceDeviationPPB, + ExecGasPriceDeviationPPB, + TokenPriceHeartBeat, + TokenPriceDeviationPPB, + InflightCacheExpiry, + ), nil + default: + return nil, fmt.Errorf("version not supported: %s", VersionMap[CommitStoreContract]) + } +} + +func NewCommitOnchainConfig( + PriceRegistry common.Address, +) (abihelpers.AbiDefined, error) { + switch VersionMap[CommitStoreContract] { + case Latest: + return testhelpers.NewCommitOnchainConfig(PriceRegistry), nil + case V1_2_0: + return testhelpers_1_4_0.NewCommitOnchainConfig(PriceRegistry), nil + default: + return nil, fmt.Errorf("version not supported: %s", VersionMap[CommitStoreContract]) + } +} + +func NewExecOnchainConfig( + PermissionLessExecutionThresholdSeconds uint32, + Router common.Address, + PriceRegistry common.Address, + MaxNumberOfTokensPerMsg uint16, + MaxDataBytes uint32, + MaxPoolReleaseOrMintGas uint32, +) (abihelpers.AbiDefined, error) { + switch VersionMap[OffRampContract] { + case Latest: + return testhelpers.NewExecOnchainConfig( + PermissionLessExecutionThresholdSeconds, + Router, + PriceRegistry, + MaxNumberOfTokensPerMsg, + MaxDataBytes, + MaxPoolReleaseOrMintGas, // TODO: obsolete soon after this merge + 50_000, // TODO: MaxTokenTransferGas, obsolete soon after this merge + ), nil + case V1_2_0: + return testhelpers_1_4_0.NewExecOnchainConfig( + PermissionLessExecutionThresholdSeconds, + Router, + PriceRegistry, + MaxNumberOfTokensPerMsg, + MaxDataBytes, + MaxPoolReleaseOrMintGas, + ), nil + default: + return nil, fmt.Errorf("version not supported: %s", VersionMap[OffRampContract]) + } +} + +func NewExecOffchainConfig( + destOptimisticConfirmations uint32, + batchGasLimit uint32, + relativeBoostPerWaitHour float64, + inflightCacheExpiry config.Duration, + rootSnoozeTime config.Duration, +) (ccipconfig.OffchainConfig, error) { + switch VersionMap[OffRampContract] { + case Latest: + return testhelpers.NewExecOffchainConfig( + destOptimisticConfirmations, + batchGasLimit, + relativeBoostPerWaitHour, + inflightCacheExpiry, + rootSnoozeTime, + ), nil + case V1_2_0: + return testhelpers_1_4_0.NewExecOffchainConfig( + destOptimisticConfirmations, + batchGasLimit, + relativeBoostPerWaitHour, + inflightCacheExpiry, + rootSnoozeTime, + ), nil + default: + return nil, fmt.Errorf("version not supported: %s", VersionMap[OffRampContract]) + } +} + +func NewOffChainAggregatorV2ConfigForCCIPPlugin[T ccipconfig.OffchainConfig]( + nodes []*client.CLNodesWithKeys, + offchainCfg T, + onchainCfg abihelpers.AbiDefined, + ocr2Params contracts.OffChainAggregatorV2Config, + inflightExpiry time.Duration, +) ( + signers []common.Address, + transmitters []common.Address, + f_ uint8, + onchainConfig_ []byte, + offchainConfigVersion uint64, + offchainConfig []byte, + err error, +) { + oracleIdentities := make([]ocrconfighelper2.OracleIdentityExtra, 0) + ocrConfig := OffChainAggregatorV2ConfigWithNodes(len(nodes), inflightExpiry, ocr2Params) + var onChainKeys []ocrtypes2.OnchainPublicKey + for i, nodeWithKeys := range nodes { + ocr2Key := nodeWithKeys.KeysBundle.OCR2Key.Data + offChainPubKeyTemp, err := hex.DecodeString(stripKeyPrefix(ocr2Key.Attributes.OffChainPublicKey)) + if err != nil { + return nil, nil, 0, nil, 0, nil, err + } + formattedOnChainPubKey := stripKeyPrefix(ocr2Key.Attributes.OnChainPublicKey) + cfgPubKeyTemp, err := hex.DecodeString(stripKeyPrefix(ocr2Key.Attributes.ConfigPublicKey)) + if err != nil { + return nil, nil, 0, nil, 0, nil, err + } + cfgPubKeyBytes := [ed25519.PublicKeySize]byte{} + copy(cfgPubKeyBytes[:], cfgPubKeyTemp) + offChainPubKey := [curve25519.PointSize]byte{} + copy(offChainPubKey[:], offChainPubKeyTemp) + ethAddress := nodeWithKeys.KeysBundle.EthAddress + p2pKeys := nodeWithKeys.KeysBundle.P2PKeys + peerID := p2pKeys.Data[0].Attributes.PeerID + oracleIdentities = append(oracleIdentities, ocrconfighelper2.OracleIdentityExtra{ + OracleIdentity: ocrconfighelper2.OracleIdentity{ + OffchainPublicKey: offChainPubKey, + OnchainPublicKey: common.HexToAddress(formattedOnChainPubKey).Bytes(), + PeerID: peerID, + TransmitAccount: ocrtypes2.Account(ethAddress), + }, + ConfigEncryptionPublicKey: cfgPubKeyBytes, + }) + onChainKeys = append(onChainKeys, oracleIdentities[i].OnchainPublicKey) + transmitters = append(transmitters, common.HexToAddress(ethAddress)) + } + signers, err = evm.OnchainPublicKeyToAddress(onChainKeys) + if err != nil { + return nil, nil, 0, nil, 0, nil, err + } + ocrConfig.Oracles = oracleIdentities + ocrConfig.ReportingPluginConfig, err = ccipconfig.EncodeOffchainConfig(offchainCfg) + if err != nil { + return nil, nil, 0, nil, 0, nil, err + } + ocrConfig.OnchainConfig, err = abihelpers.EncodeAbiStruct(onchainCfg) + if err != nil { + return nil, nil, 0, nil, 0, nil, err + } + + _, _, f_, onchainConfig_, offchainConfigVersion, offchainConfig, err = ocrconfighelper2.ContractSetConfigArgsForTests( + ocrConfig.DeltaProgress, + ocrConfig.DeltaResend, + ocrConfig.DeltaRound, + ocrConfig.DeltaGrace, + ocrConfig.DeltaStage, + ocrConfig.RMax, + ocrConfig.S, + ocrConfig.Oracles, + ocrConfig.ReportingPluginConfig, + ocrConfig.MaxDurationQuery, + ocrConfig.MaxDurationObservation, + ocrConfig.MaxDurationReport, + ocrConfig.MaxDurationShouldAcceptFinalizedReport, + ocrConfig.MaxDurationShouldTransmitAcceptedReport, + ocrConfig.F, + ocrConfig.OnchainConfig, + ) + return +} diff --git a/integration-tests/ccip-tests/contracts/contract_models.go b/integration-tests/ccip-tests/contracts/contract_models.go new file mode 100644 index 0000000000..7008d51b62 --- /dev/null +++ b/integration-tests/ccip-tests/contracts/contract_models.go @@ -0,0 +1,2247 @@ +package contracts + +import ( + "context" + "fmt" + "math/big" + "strconv" + "strings" + "time" + + "github.com/AlekSi/pointer" + "github.com/Masterminds/semver/v3" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/rs/zerolog" + "golang.org/x/exp/rand" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + + "github.com/smartcontractkit/chainlink/integration-tests/wrappers" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_v3_aggregator_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_pool_1_4_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/usdc_token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/usdc_token_pool_1_4_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/erc20" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" +) + +type LogInfo struct { + BlockNumber uint64 + TxHash common.Hash +} + +// Name denotes a contract name +type Name string + +// Version wraps a semver.Version object to provide some custom unmarshalling +type Version struct { + semver.Version +} + +// GasUpdateEvent holds the event details of Gas price update +type GasUpdateEvent struct { + Sender string + Tx string + Value *big.Int + DestChain uint64 + Source string +} + +// MustVersion creates a new Version object from a semver string and panics if it fails +func MustVersion(version string) Version { + v := semver.MustParse(version) + return Version{Version: *v} +} + +// UnmarshalTOML unmarshals TOML data into a Version object +func (v *Version) UnmarshalText(data []byte) error { + str := strings.Trim(string(data), `"`) + str = strings.Trim(str, `'`) + if strings.ToLower(str) == "latest" { + *v = Latest + return nil + } + ver, err := semver.NewVersion(str) + if err != nil { + return fmt.Errorf("failed to parse version from '%s': %w", str, err) + } + v.Version = *ver + return nil +} + +// Latest returns true if the version is the latest version +func (v *Version) Latest() bool { + return v.Version.Equal(&Latest.Version) +} + +const ( + Network = "Network Name" + PriceRegistryContract Name = "PriceRegistry" + OffRampContract Name = "OffRamp" + OnRampContract Name = "OnRamp" + TokenPoolContract Name = "TokenPool" + CommitStoreContract Name = "CommitStore" + + defaultDestByteOverhead = uint32(32) + defaultDestGasOverhead = uint32(125_000) +) + +var ( + V1_2_0 = MustVersion("1.2.0") + V1_4_0 = MustVersion("1.4.0") + V1_5_0_dev = MustVersion("1.5.0-dev") + LatestPoolVersion = V1_5_0_dev + Latest = V1_5_0_dev + VersionMap = map[Name]Version{ + PriceRegistryContract: V1_2_0, + OffRampContract: Latest, + OnRampContract: Latest, + CommitStoreContract: Latest, + TokenPoolContract: Latest, + } + SupportedContracts = map[Name]map[string]bool{ + PriceRegistryContract: { + Latest.String(): true, + V1_2_0.String(): true, + }, + OffRampContract: { + Latest.String(): true, + V1_2_0.String(): true, + }, + OnRampContract: { + Latest.String(): true, + V1_2_0.String(): true, + }, + CommitStoreContract: { + Latest.String(): true, + V1_2_0.String(): true, + }, + TokenPoolContract: { + Latest.String(): true, + V1_4_0.String(): true, + }, + } + + FiftyCoins = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(50)) + HundredCoins = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(100)) +) + +// CheckVersionSupported checks if a given version is supported for a given contract +func CheckVersionSupported(name Name, version Version) error { + if contract, ok := SupportedContracts[name]; ok { + if isSupported, ok := contract[version.String()]; ok { + if isSupported { + return nil + } + return fmt.Errorf("version %s is not supported for contract %s", version.String(), name) + } + return fmt.Errorf("version %s is not supported for contract %s", version.String(), name) + } + return fmt.Errorf("contract %s is not supported", name) +} + +type RateLimiterConfig struct { + IsEnabled bool + Rate *big.Int + Capacity *big.Int + Tokens *big.Int +} + +type ARMConfig struct { + ARMWeightsByParticipants map[string]*big.Int // mapping : ARM participant address => weight + ThresholdForBlessing *big.Int + ThresholdForBadSignal *big.Int +} + +type TokenTransmitter struct { + client blockchain.EVMClient + instance *mock_usdc_token_transmitter.MockE2EUSDCTransmitter + ContractAddress common.Address +} + +type ERC677Token struct { + client blockchain.EVMClient + logger *zerolog.Logger + instance *burn_mint_erc677.BurnMintERC677 + ContractAddress common.Address + OwnerAddress common.Address + OwnerWallet *blockchain.EthereumWallet +} + +func (token *ERC677Token) GrantMintAndBurn(burnAndMinter common.Address) error { + opts, err := token.client.TransactionOpts(token.OwnerWallet) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + token.logger.Info(). + Str(Network, token.client.GetNetworkName()). + Str("BurnAndMinter", burnAndMinter.Hex()). + Str("Token", token.ContractAddress.Hex()). + Msg("Granting mint and burn roles") + tx, err := token.instance.GrantMintAndBurnRoles(opts, burnAndMinter) + if err != nil { + return fmt.Errorf("failed to grant mint and burn roles: %w", err) + } + return token.client.ProcessTransaction(tx) +} + +func (token *ERC677Token) GrantMintRole(minter common.Address) error { + opts, err := token.client.TransactionOpts(token.OwnerWallet) + if err != nil { + return err + } + token.logger.Info(). + Str(Network, token.client.GetNetworkName()). + Str("Minter", minter.Hex()). + Str("Token", token.ContractAddress.Hex()). + Msg("Granting mint roles") + tx, err := token.instance.GrantMintRole(opts, minter) + if err != nil { + return fmt.Errorf("failed to grant mint role: %w", err) + } + return token.client.ProcessTransaction(tx) +} + +func (token *ERC677Token) Mint(to common.Address, amount *big.Int) error { + opts, err := token.client.TransactionOpts(token.OwnerWallet) + if err != nil { + return err + } + token.logger.Info(). + Str(Network, token.client.GetNetworkName()). + Str("To", to.Hex()). + Str("Token", token.ContractAddress.Hex()). + Str("Amount", amount.String()). + Msg("Minting tokens") + tx, err := token.instance.Mint(opts, to, amount) + if err != nil { + return fmt.Errorf("failed to mint tokens: %w", err) + } + return token.client.ProcessTransaction(tx) +} + +type ERC20Token struct { + client blockchain.EVMClient + logger *zerolog.Logger + instance *erc20.ERC20 + ContractAddress common.Address + OwnerAddress common.Address + OwnerWallet *blockchain.EthereumWallet +} + +func (token *ERC20Token) Address() string { + return token.ContractAddress.Hex() +} + +func (token *ERC20Token) BalanceOf(ctx context.Context, addr string) (*big.Int, error) { + opts := &bind.CallOpts{ + From: common.HexToAddress(token.client.GetDefaultWallet().Address()), + Context: ctx, + } + balance, err := token.instance.BalanceOf(opts, common.HexToAddress(addr)) + if err != nil { + return nil, fmt.Errorf("failed to get balance: %w", err) + } + return balance, nil +} + +// Allowance returns the amount which spender is still allowed to withdraw from owner +// https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20-allowance-address-address- +func (token *ERC20Token) Allowance(owner, spender string) (*big.Int, error) { + allowance, err := token.instance.Allowance(nil, common.HexToAddress(owner), common.HexToAddress(spender)) + if err != nil { + return nil, err + } + return allowance, nil +} + +// Approve approves the spender to spend the given amount of tokens on behalf of another account +// https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20-approve-address-uint256- +func (token *ERC20Token) Approve(onBehalf *blockchain.EthereumWallet, spender string, amount *big.Int) error { + onBehalfBalance, err := token.BalanceOf(context.Background(), onBehalf.Address()) + if err != nil { + return fmt.Errorf("failed to get balance of onBehalf: %w", err) + } + currentAllowance, err := token.Allowance(onBehalf.Address(), spender) + if err != nil { + return fmt.Errorf("failed to get current allowance for '%s' on behalf of '%s': %w", spender, onBehalf.Address(), err) + } + opts, err := token.client.TransactionOpts(onBehalf) + if err != nil { + return fmt.Errorf("failed to get transaction options: %w", err) + } + log := token.logger.Info(). + Str("On Behalf Of", onBehalf.Address()). + Str("On Behalf Of Balance", onBehalfBalance.String()). + Str("Spender", spender). + Str("Spender Current Allowance", currentAllowance.String()). + Str("Token", token.Address()). + Str("Amount", amount.String()). + Uint64("Nonce", opts.Nonce.Uint64()). + Str(Network, token.client.GetNetworkConfig().Name) + tx, err := token.instance.Approve(opts, common.HexToAddress(spender), amount) + if err != nil { + log.Err(err).Msg("Error Approving ERC20 Transfer") + return fmt.Errorf("failed to approve ERC20: %w", err) + } + log.Str("Hash", tx.Hash().Hex()).Msg("Approving ERC20 Transfer") + return token.client.ProcessTransaction(tx) +} + +func (token *ERC20Token) Transfer(from *blockchain.EthereumWallet, to string, amount *big.Int) error { + opts, err := token.client.TransactionOpts(from) + if err != nil { + return fmt.Errorf("failed to get transaction options: %w", err) + } + token.logger.Info(). + Str("From", from.Address()). + Str("To", to). + Str("Amount", amount.String()). + Uint64("Nonce", opts.Nonce.Uint64()). + Str(Network, token.client.GetNetworkConfig().Name). + Msg("Transferring ERC20") + tx, err := token.instance.Transfer(opts, common.HexToAddress(to), amount) + if err != nil { + return fmt.Errorf("failed to transfer ERC20: %w", err) + } + return token.client.ProcessTransaction(tx) +} + +type LinkToken struct { + client blockchain.EVMClient + logger *zerolog.Logger + instance *link_token_interface.LinkToken + EthAddress common.Address +} + +func (l *LinkToken) Address() string { + return l.EthAddress.Hex() +} + +func (l *LinkToken) BalanceOf(ctx context.Context, addr string) (*big.Int, error) { + opts := &bind.CallOpts{ + From: common.HexToAddress(l.client.GetDefaultWallet().Address()), + Context: ctx, + } + balance, err := l.instance.BalanceOf(opts, common.HexToAddress(addr)) + if err != nil { + return nil, fmt.Errorf("failed to get LINK balance: %w", err) + } + return balance, nil +} + +func (l *LinkToken) Allowance(owner, spender string) (*big.Int, error) { + allowance, err := l.instance.Allowance(nil, common.HexToAddress(owner), common.HexToAddress(spender)) + if err != nil { + return nil, err + } + return allowance, nil +} + +func (l *LinkToken) Approve(to string, amount *big.Int) error { + opts, err := l.client.TransactionOpts(l.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + l.logger.Info(). + Str("From", l.client.GetDefaultWallet().Address()). + Str("To", to). + Str("Token", l.Address()). + Str("Amount", amount.String()). + Uint64("Nonce", opts.Nonce.Uint64()). + Str(Network, l.client.GetNetworkConfig().Name). + Msg("Approving LINK Transfer") + tx, err := l.instance.Approve(opts, common.HexToAddress(to), amount) + if err != nil { + return fmt.Errorf("failed to approve LINK transfer: %w", err) + } + return l.client.ProcessTransaction(tx) +} + +func (l *LinkToken) Transfer(to string, amount *big.Int) error { + opts, err := l.client.TransactionOpts(l.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + l.logger.Info(). + Str("From", l.client.GetDefaultWallet().Address()). + Str("To", to). + Str("Amount", amount.String()). + Uint64("Nonce", opts.Nonce.Uint64()). + Str(Network, l.client.GetNetworkConfig().Name). + Msg("Transferring LINK") + tx, err := l.instance.Transfer(opts, common.HexToAddress(to), amount) + if err != nil { + return fmt.Errorf("failed to transfer LINK: %w", err) + } + return l.client.ProcessTransaction(tx) +} + +type LatestPool struct { + PoolInterface *token_pool.TokenPool + LockReleasePool *lock_release_token_pool.LockReleaseTokenPool + USDCPool *usdc_token_pool.USDCTokenPool +} + +type V1_4_0Pool struct { + PoolInterface *token_pool_1_4_0.TokenPool + LockReleasePool *lock_release_token_pool_1_4_0.LockReleaseTokenPool + USDCPool *usdc_token_pool_1_4_0.USDCTokenPool +} + +type TokenPoolWrapper struct { + Latest *LatestPool + V1_4_0 *V1_4_0Pool +} + +func (w TokenPoolWrapper) SetRebalancer(opts *bind.TransactOpts, from common.Address) (*types.Transaction, error) { + if w.Latest != nil && w.Latest.LockReleasePool != nil { + return w.Latest.LockReleasePool.SetRebalancer(opts, from) + } + if w.V1_4_0 != nil && w.V1_4_0.LockReleasePool != nil { + return w.V1_4_0.LockReleasePool.SetRebalancer(opts, from) + } + return nil, fmt.Errorf("no pool found to set rebalancer") +} + +func (w TokenPoolWrapper) SetUSDCDomains(opts *bind.TransactOpts, updates []usdc_token_pool.USDCTokenPoolDomainUpdate) (*types.Transaction, error) { + if w.Latest != nil && w.Latest.USDCPool != nil { + return w.Latest.USDCPool.SetDomains(opts, updates) + } + if w.V1_4_0 != nil && w.V1_4_0.USDCPool != nil { + V1_4_0Updates := make([]usdc_token_pool_1_4_0.USDCTokenPoolDomainUpdate, len(updates)) + for i, update := range updates { + V1_4_0Updates[i] = usdc_token_pool_1_4_0.USDCTokenPoolDomainUpdate{ + AllowedCaller: update.AllowedCaller, + DomainIdentifier: update.DomainIdentifier, + DestChainSelector: update.DestChainSelector, + Enabled: update.Enabled, + } + } + return w.V1_4_0.USDCPool.SetDomains(opts, V1_4_0Updates) + } + return nil, fmt.Errorf("no pool found to set USDC domains") +} + +func (w TokenPoolWrapper) WithdrawLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + if w.Latest != nil && w.Latest.LockReleasePool != nil { + return w.Latest.LockReleasePool.WithdrawLiquidity(opts, amount) + } + if w.V1_4_0 != nil && w.V1_4_0.LockReleasePool != nil { + return w.V1_4_0.LockReleasePool.WithdrawLiquidity(opts, amount) + } + return nil, fmt.Errorf("no pool found to withdraw liquidity") +} + +func (w TokenPoolWrapper) ProvideLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + if w.Latest != nil && w.Latest.LockReleasePool != nil { + return w.Latest.LockReleasePool.ProvideLiquidity(opts, amount) + } + if w.V1_4_0 != nil && w.V1_4_0.LockReleasePool != nil { + return w.V1_4_0.LockReleasePool.ProvideLiquidity(opts, amount) + } + return nil, fmt.Errorf("no pool found to provide liquidity") +} + +func (w TokenPoolWrapper) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + if w.Latest != nil && w.Latest.PoolInterface != nil { + return w.Latest.PoolInterface.IsSupportedChain(opts, remoteChainSelector) + } + if w.V1_4_0 != nil && w.V1_4_0.PoolInterface != nil { + return w.V1_4_0.PoolInterface.IsSupportedChain(opts, remoteChainSelector) + } + return false, fmt.Errorf("no pool found to check if chain is supported") +} + +func (w TokenPoolWrapper) ApplyChainUpdates(opts *bind.TransactOpts, update []token_pool.TokenPoolChainUpdate) (*types.Transaction, error) { + if w.Latest != nil && w.Latest.PoolInterface != nil { + return w.Latest.PoolInterface.ApplyChainUpdates(opts, update) + } + if w.V1_4_0 != nil && w.V1_4_0.PoolInterface != nil { + V1_4_0Updates := make([]token_pool_1_4_0.TokenPoolChainUpdate, len(update)) + for i, u := range update { + V1_4_0Updates[i] = token_pool_1_4_0.TokenPoolChainUpdate{ + RemoteChainSelector: u.RemoteChainSelector, + Allowed: u.Allowed, + InboundRateLimiterConfig: token_pool_1_4_0.RateLimiterConfig{ + IsEnabled: u.InboundRateLimiterConfig.IsEnabled, + Capacity: u.InboundRateLimiterConfig.Capacity, + Rate: u.InboundRateLimiterConfig.Rate, + }, + OutboundRateLimiterConfig: token_pool_1_4_0.RateLimiterConfig{ + IsEnabled: u.OutboundRateLimiterConfig.IsEnabled, + Capacity: u.OutboundRateLimiterConfig.Capacity, + Rate: u.OutboundRateLimiterConfig.Rate, + }, + } + } + return w.V1_4_0.PoolInterface.ApplyChainUpdates(opts, V1_4_0Updates) + } + return nil, fmt.Errorf("no pool found to apply chain updates") +} + +func (w TokenPoolWrapper) SetChainRateLimiterConfig(opts *bind.TransactOpts, selector uint64, out token_pool.RateLimiterConfig, in token_pool.RateLimiterConfig) (*types.Transaction, error) { + if w.Latest != nil && w.Latest.PoolInterface != nil { + return w.Latest.PoolInterface.SetChainRateLimiterConfig(opts, selector, out, in) + } + if w.V1_4_0 != nil && w.V1_4_0.PoolInterface != nil { + return w.V1_4_0.PoolInterface.SetChainRateLimiterConfig(opts, selector, + token_pool_1_4_0.RateLimiterConfig{ + IsEnabled: out.IsEnabled, + Capacity: out.Capacity, + Rate: out.Rate, + }, token_pool_1_4_0.RateLimiterConfig{ + IsEnabled: in.IsEnabled, + Capacity: in.Capacity, + Rate: in.Rate, + }) + } + return nil, fmt.Errorf("no pool found to set chain rate limiter config") +} + +func (w TokenPoolWrapper) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, selector uint64) (*RateLimiterConfig, error) { + if w.Latest != nil && w.Latest.PoolInterface != nil { + rl, err := w.Latest.PoolInterface.GetCurrentOutboundRateLimiterState(opts, selector) + if err != nil { + return nil, err + } + return &RateLimiterConfig{ + IsEnabled: rl.IsEnabled, + Capacity: rl.Capacity, + Rate: rl.Rate, + Tokens: rl.Tokens, + }, nil + } + if w.V1_4_0 != nil && w.V1_4_0.PoolInterface != nil { + rl, err := w.V1_4_0.PoolInterface.GetCurrentOutboundRateLimiterState(opts, selector) + if err != nil { + return nil, err + } + return &RateLimiterConfig{ + IsEnabled: rl.IsEnabled, + Capacity: rl.Capacity, + Rate: rl.Rate, + Tokens: rl.Tokens, + }, nil + } + return nil, fmt.Errorf("no pool found to get current outbound rate limiter state") +} + +func (w TokenPoolWrapper) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, selector uint64) (*RateLimiterConfig, error) { + if w.Latest != nil && w.Latest.PoolInterface != nil { + rl, err := w.Latest.PoolInterface.GetCurrentInboundRateLimiterState(opts, selector) + if err != nil { + return nil, err + } + return &RateLimiterConfig{ + IsEnabled: rl.IsEnabled, + Capacity: rl.Capacity, + Rate: rl.Rate, + Tokens: rl.Tokens, + }, nil + } + if w.V1_4_0 != nil && w.V1_4_0.PoolInterface != nil { + rl, err := w.V1_4_0.PoolInterface.GetCurrentInboundRateLimiterState(opts, selector) + if err != nil { + return nil, err + } + return &RateLimiterConfig{ + IsEnabled: rl.IsEnabled, + Capacity: rl.Capacity, + Rate: rl.Rate, + Tokens: rl.Tokens, + }, nil + } + return nil, fmt.Errorf("no pool found to get current outbound rate limiter state") +} + +func (w TokenPoolWrapper) SetRouter(opts *bind.TransactOpts, routerAddr common.Address) (*types.Transaction, error) { + if w.Latest != nil && w.Latest.PoolInterface != nil { + return w.Latest.PoolInterface.SetRouter(opts, routerAddr) + } + if w.V1_4_0 != nil && w.V1_4_0.PoolInterface != nil { + return w.V1_4_0.PoolInterface.SetRouter(opts, routerAddr) + } + return nil, fmt.Errorf("no pool found to set router") +} + +func (w TokenPoolWrapper) GetRouter(opts *bind.CallOpts) (common.Address, error) { + if w.Latest != nil && w.Latest.PoolInterface != nil { + addr, err := w.Latest.PoolInterface.GetRouter(opts) + if err != nil { + return common.Address{}, err + } + return addr, nil + } + if w.V1_4_0 != nil && w.V1_4_0.PoolInterface != nil { + addr, err := w.V1_4_0.PoolInterface.GetRouter(opts) + if err != nil { + return common.Address{}, err + } + return addr, nil + } + return common.Address{}, fmt.Errorf("no pool found to get router") +} + +func (w TokenPoolWrapper) GetRebalancer(opts *bind.CallOpts) (common.Address, error) { + if w.Latest != nil && w.Latest.LockReleasePool != nil { + addr, err := w.Latest.LockReleasePool.GetRebalancer(opts) + if err != nil { + return common.Address{}, err + } + return addr, nil + } + if w.V1_4_0 != nil && w.V1_4_0.LockReleasePool != nil { + addr, err := w.V1_4_0.LockReleasePool.GetRebalancer(opts) + if err != nil { + return common.Address{}, err + } + return addr, nil + } + return common.Address{}, fmt.Errorf("no pool found to get rebalancer") +} + +// TokenPool represents a TokenPool address +type TokenPool struct { + client blockchain.EVMClient + logger *zerolog.Logger + Instance *TokenPoolWrapper + EthAddress common.Address + OwnerAddress common.Address + OwnerWallet *blockchain.EthereumWallet +} + +func (pool *TokenPool) Address() string { + return pool.EthAddress.Hex() +} + +func (pool *TokenPool) IsUSDC() bool { + if pool.Instance.Latest != nil && pool.Instance.Latest.USDCPool != nil { + return true + } + if pool.Instance.V1_4_0 != nil && pool.Instance.V1_4_0.USDCPool != nil { + return true + } + return false +} + +func (pool *TokenPool) IsLockRelease() bool { + if pool.Instance.Latest != nil && pool.Instance.Latest.LockReleasePool != nil { + return true + } + if pool.Instance.V1_4_0 != nil && pool.Instance.V1_4_0.LockReleasePool != nil { + return true + } + return false +} + +func (pool *TokenPool) SyncUSDCDomain(destTokenTransmitter *TokenTransmitter, destPoolAddr common.Address, destChainSelector uint64) error { + if !pool.IsUSDC() { + return fmt.Errorf("pool is not a USDC pool, cannot sync domain") + } + + var allowedCallerBytes [32]byte + copy(allowedCallerBytes[12:], destPoolAddr.Bytes()) + destTokenTransmitterIns, err := mock_usdc_token_transmitter.NewMockE2EUSDCTransmitter( + destTokenTransmitter.ContractAddress, destTokenTransmitter.client.Backend(), + ) + if err != nil { + return fmt.Errorf("failed to create mock USDC token transmitter: %w", err) + } + domain, err := destTokenTransmitterIns.LocalDomain(nil) + if err != nil { + return fmt.Errorf("failed to get local domain: %w", err) + } + opts, err := pool.client.TransactionOpts(pool.OwnerWallet) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Str("From", pool.OwnerAddress.Hex()). + Str(Network, pool.client.GetNetworkName()). + Uint32("Domain", domain). + Str("Allowed Caller", destPoolAddr.Hex()). + Str("Dest Chain Selector", fmt.Sprintf("%d", destChainSelector)). + Msg("Syncing USDC Domain") + tx, err := pool.Instance.SetUSDCDomains(opts, []usdc_token_pool.USDCTokenPoolDomainUpdate{ + { + AllowedCaller: allowedCallerBytes, + DomainIdentifier: domain, + DestChainSelector: destChainSelector, + Enabled: true, + }, + }) + if err != nil { + return fmt.Errorf("failed to set domain: %w", err) + } + return pool.client.ProcessTransaction(tx) +} + +// MintUSDCToUSDCPool mints 100 USDC tokens to the pool if it is a USDC pool. +// This helps provide liquidity to the pool which is necessary for USDC tests to function properly. +func (pool *TokenPool) MintUSDCToUSDCPool() error { + if !pool.IsUSDC() { + return fmt.Errorf("pool is not a USDC pool, cannot send USDC") + } + usdcToken, err := pool.GetToken() + if err != nil { + return fmt.Errorf("failed to get dest usdc token: %w", err) + } + usdcInstance, err := burn_mint_erc677.NewBurnMintERC677(usdcToken, pool.client.Backend()) + if err != nil { + return fmt.Errorf("failed to get dest usdc token instance: %w", err) + } + + opts, err := pool.client.TransactionOpts(pool.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + + tx, err := usdcInstance.Mint(opts, pool.EthAddress, HundredCoins) + if err != nil { + return fmt.Errorf("failed to mint usdc tokens to destPool: %w", err) + } + return pool.client.ProcessTransaction(tx) +} + +func (pool *TokenPool) RemoveLiquidity(amount *big.Int) error { + if !pool.IsLockRelease() { + return fmt.Errorf("pool is not a lock release pool, cannot remove liquidity") + } + opts, err := pool.client.TransactionOpts(pool.OwnerWallet) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Str("Amount", amount.String()). + Msg("Initiating removing funds from pool") + tx, err := pool.Instance.WithdrawLiquidity(opts, amount) + if err != nil { + return fmt.Errorf("failed to withdraw liquidity: %w", err) + } + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Str("Amount", amount.String()). + Str(Network, pool.client.GetNetworkConfig().Name). + Msg("Liquidity removed") + return pool.client.ProcessTransaction(tx) +} + +// AddLiquidity approves the token pool to spend the given amount of tokens from the given wallet +func (pool *TokenPool) AddLiquidity(token *ERC20Token, fromWallet *blockchain.EthereumWallet, amount *big.Int) error { + if !pool.IsLockRelease() { + return fmt.Errorf("pool is not a lock release pool, cannot add liquidity") + } + pool.logger.Info(). + Str("Token", token.Address()). + Str("Token Pool", pool.Address()). + Msg("Initiating adding liquidity to token pool") + err := token.Approve(fromWallet, pool.Address(), amount) + if err != nil { + return fmt.Errorf("failed to approve token transfer: %w", err) + } + err = pool.client.WaitForEvents() + if err != nil { + return fmt.Errorf("failed to wait for events: %w", err) + } + opts, err := pool.client.TransactionOpts(pool.OwnerWallet) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + _, err = pool.Instance.SetRebalancer(opts, opts.From) + if err != nil { + return fmt.Errorf("failed to set rebalancer: %w", err) + } + opts, err = pool.client.TransactionOpts(pool.OwnerWallet) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Msg("Initiating adding Tokens in pool") + tx, err := pool.Instance.ProvideLiquidity(opts, amount) + if err != nil { + return fmt.Errorf("failed to provide liquidity: %w", err) + } + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Str("Token", token.Address()). + Str(Network, pool.client.GetNetworkConfig().Name). + Msg("Liquidity added") + return pool.client.ProcessTransaction(tx) +} + +func (pool *TokenPool) SetRemoteChainOnPool(remoteChainSelector uint64, remotePoolAddresses common.Address, remoteTokenAddress common.Address) error { + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Msg("Setting remote chain on pool") + var selectorsToUpdate []token_pool.TokenPoolChainUpdate + + isSupported, err := pool.Instance.IsSupportedChain(nil, remoteChainSelector) + if err != nil { + return fmt.Errorf("failed to get if chain is supported: %w", err) + } + // Check if remote chain is already supported, if yes return + if isSupported { + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Str(Network, pool.client.GetNetworkName()). + Uint64("Remote Chain Selector", remoteChainSelector). + Msg("Remote chain is already supported") + return nil + } + // if not, add it + encodedPoolAddress, err := abihelpers.EncodeAddress(remotePoolAddresses) + if err != nil { + return fmt.Errorf("failed to encode address: %w", err) + } + + encodedTokenAddress, err := abihelpers.EncodeAddress(remoteTokenAddress) + if err != nil { + return fmt.Errorf("failed to encode token address: %w", err) + } + + selectorsToUpdate = append(selectorsToUpdate, token_pool.TokenPoolChainUpdate{ + RemoteChainSelector: remoteChainSelector, + RemotePoolAddress: encodedPoolAddress, + RemoteTokenAddress: encodedTokenAddress, + Allowed: true, + InboundRateLimiterConfig: token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e9)), + Rate: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e5)), + }, + OutboundRateLimiterConfig: token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e9)), + Rate: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e5)), + }, + }) + opts, err := pool.client.TransactionOpts(pool.OwnerWallet) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + tx, err := pool.Instance.ApplyChainUpdates(opts, selectorsToUpdate) + if err != nil { + return fmt.Errorf("failed to set chain updates on token pool: %w", err) + } + + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Uint64("Chain selector", remoteChainSelector). + Str(Network, pool.client.GetNetworkConfig().Name). + Msg("Remote chains set on token pool") + return pool.client.ProcessTransaction(tx) +} + +// SetRemoteChainRateLimits sets the rate limits for the token pool on the remote chain +func (pool *TokenPool) SetRemoteChainRateLimits(remoteChainSelector uint64, rl token_pool.RateLimiterConfig) error { + opts, err := pool.client.TransactionOpts(pool.OwnerWallet) + if err != nil { + return fmt.Errorf("error getting transaction opts: %w", err) + } + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Str("Remote chain selector", strconv.FormatUint(remoteChainSelector, 10)). + Interface("RateLimiterConfig", rl). + Msg("Setting Rate Limit on token pool") + tx, err := pool.Instance.SetChainRateLimiterConfig(opts, remoteChainSelector, rl, rl) + + if err != nil { + return fmt.Errorf("error setting rate limit token pool: %w", err) + } + + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Str("Remote chain selector", strconv.FormatUint(remoteChainSelector, 10)). + Interface("RateLimiterConfig", rl). + Msg("Rate Limit on token pool is set") + return pool.client.ProcessTransaction(tx) +} + +func (pool *TokenPool) SetRouter(routerAddr common.Address) error { + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Msg("Setting router on pool") + opts, err := pool.client.TransactionOpts(pool.OwnerWallet) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + tx, err := pool.Instance.SetRouter(opts, routerAddr) + if err != nil { + return fmt.Errorf("failed to set router: %w", err) + + } + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Str("Router", routerAddr.String()). + Msg("Router set on pool") + return pool.client.ProcessTransaction(tx) +} + +func (pool *TokenPool) GetRouter() (common.Address, error) { + return pool.Instance.GetRouter(nil) +} + +func (pool *TokenPool) GetToken() (common.Address, error) { + if pool.Instance.V1_4_0 != nil && pool.Instance.V1_4_0.PoolInterface != nil { + return pool.Instance.V1_4_0.PoolInterface.GetToken(nil) + } + if pool.Instance.Latest != nil && pool.Instance.Latest.PoolInterface != nil { + return pool.Instance.Latest.PoolInterface.GetToken(nil) + } + return common.Address{}, fmt.Errorf("no pool found to get token") +} + +func (pool *TokenPool) SetRebalancer(rebalancerAddress common.Address) error { + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Msg("Setting rebalancer on pool") + opts, err := pool.client.TransactionOpts(pool.OwnerWallet) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + tx, err := pool.Instance.SetRebalancer(opts, rebalancerAddress) + if err != nil { + return fmt.Errorf("failed to set router: %w", err) + + } + pool.logger.Info(). + Str("Token Pool", pool.Address()). + Str("Rebalancer", rebalancerAddress.String()). + Msg("Rebalancer set on pool") + return pool.client.ProcessTransaction(tx) +} + +func (pool *TokenPool) GetRebalancer() (common.Address, error) { + return pool.Instance.GetRebalancer(nil) +} + +type ARM struct { + client blockchain.EVMClient + Instance *arm_contract.ARMContract + EthAddress common.Address +} + +func (arm *ARM) Address() string { + return arm.EthAddress.Hex() +} + +type MockARM struct { + client blockchain.EVMClient + Instance *mock_arm_contract.MockARMContract + EthAddress common.Address +} + +func (arm *MockARM) SetClient(client blockchain.EVMClient) { + arm.client = client +} +func (arm *MockARM) Address() string { + return arm.EthAddress.Hex() +} + +type CommitStoreReportAccepted struct { + Min uint64 + Max uint64 + MerkleRoot [32]byte + LogInfo LogInfo +} + +type CommitStoreWrapper struct { + Latest *commit_store.CommitStore + V1_2_0 *commit_store_1_2_0.CommitStore +} + +func (w CommitStoreWrapper) SetOCR2Config(opts *bind.TransactOpts, + signers []common.Address, + transmitters []common.Address, + f uint8, + onchainConfig []byte, + offchainConfigVersion uint64, + offchainConfig []byte, +) (*types.Transaction, error) { + if w.Latest != nil { + return w.Latest.SetOCR2Config(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } + if w.V1_2_0 != nil { + return w.V1_2_0.SetOCR2Config(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + } + return nil, fmt.Errorf("no instance found to set OCR2 config") +} + +func (w CommitStoreWrapper) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + if w.Latest != nil { + return w.Latest.GetExpectedNextSequenceNumber(opts) + } + if w.V1_2_0 != nil { + return w.V1_2_0.GetExpectedNextSequenceNumber(opts) + } + return 0, fmt.Errorf("no instance found to get expected next sequence number") +} + +type CommitStore struct { + client blockchain.EVMClient + logger *zerolog.Logger + Instance *CommitStoreWrapper + EthAddress common.Address +} + +func (b *CommitStore) Address() string { + return b.EthAddress.Hex() +} + +// SetOCR2Config sets the offchain reporting protocol configuration +func (b *CommitStore) SetOCR2Config( + signers []common.Address, + transmitters []common.Address, + f uint8, + onchainConfig []byte, + offchainConfigVersion uint64, + offchainConfig []byte, +) error { + b.logger.Info().Str("Contract Address", b.Address()).Msg("Configuring OCR config for CommitStore Contract") + // Set Config + opts, err := b.client.TransactionOpts(b.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("error getting transaction opts: %w", err) + } + tx, err := b.Instance.SetOCR2Config( + opts, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + ) + b.logger.Debug(). + Interface("signerAddresses", signers). + Interface("transmitterAddresses", transmitters). + Str(Network, b.client.GetNetworkConfig().Name). + Str("Tx", tx.Hash().Hex()). + Msg("Configuring CommitStore") + + if err != nil { + return fmt.Errorf("error setting OCR2 config: %w", err) + } + return b.client.ProcessTransaction(tx) +} + +// WatchReportAccepted watches for report accepted events +// There is no need to differentiate between the two versions of the contract as the event signature is the same +// we can cast the contract to the latest version +func (b *CommitStore) WatchReportAccepted(opts *bind.WatchOpts, acceptedEvent chan *commit_store.CommitStoreReportAccepted) (event.Subscription, error) { + if b.Instance.Latest != nil { + return b.Instance.Latest.WatchReportAccepted(opts, acceptedEvent) + } + if b.Instance.V1_2_0 != nil { + newCommitStore, err := commit_store.NewCommitStore(b.EthAddress, wrappers.MustNewWrappedContractBackend(b.client, nil)) + if err != nil { + return nil, fmt.Errorf("failed to create new CommitStore contract: %w", err) + } + return newCommitStore.WatchReportAccepted(opts, acceptedEvent) + } + return nil, fmt.Errorf("no instance found to watch for report accepted") +} + +type ReceiverDapp struct { + client blockchain.EVMClient + logger *zerolog.Logger + instance *maybe_revert_message_receiver.MaybeRevertMessageReceiver + EthAddress common.Address +} + +func (rDapp *ReceiverDapp) Address() string { + return rDapp.EthAddress.Hex() +} + +func (rDapp *ReceiverDapp) ToggleRevert(revert bool) error { + opts, err := rDapp.client.TransactionOpts(rDapp.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("error getting transaction opts: %w", err) + } + tx, err := rDapp.instance.SetRevert(opts, revert) + if err != nil { + return fmt.Errorf("error setting revert: %w", err) + } + rDapp.logger.Info(). + Bool("revert", revert). + Str("tx", tx.Hash().String()). + Str("ReceiverDapp", rDapp.Address()). + Str(Network, rDapp.client.GetNetworkConfig().Name). + Msg("ReceiverDapp revert set") + return rDapp.client.ProcessTransaction(tx) +} + +type InternalTimestampedPackedUint224 struct { + Value *big.Int + Timestamp uint32 +} + +type PriceRegistryUsdPerUnitGasUpdated struct { + DestChain uint64 + Value *big.Int + Timestamp *big.Int + Raw types.Log +} + +type PriceRegistryWrapper struct { + Latest *price_registry.PriceRegistry + V1_2_0 *price_registry_1_2_0.PriceRegistry +} + +func (p *PriceRegistryWrapper) GetTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) { + if p.Latest != nil { + price, err := p.Latest.GetTokenPrice(opts, token) + if err != nil { + return nil, err + } + return price.Value, nil + } + if p.V1_2_0 != nil { + p, err := p.V1_2_0.GetTokenPrice(opts, token) + if err != nil { + return nil, err + } + return p.Value, nil + } + return nil, fmt.Errorf("no instance found to get token price") +} + +func (p *PriceRegistryWrapper) AddPriceUpdater(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + if p.Latest != nil { + return p.Latest.ApplyAuthorizedCallerUpdates( + opts, + price_registry.AuthorizedCallersAuthorizedCallerArgs{ + AddedCallers: []common.Address{addr}, + RemovedCallers: []common.Address{}, + }, + ) + } + if p.V1_2_0 != nil { + return p.V1_2_0.ApplyPriceUpdatersUpdates(opts, []common.Address{addr}, []common.Address{}) + } + return nil, fmt.Errorf("no instance found to add price updater") +} + +func (p *PriceRegistryWrapper) AddFeeToken(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + if p.Latest != nil { + return p.Latest.ApplyFeeTokensUpdates(opts, []common.Address{addr}, []common.Address{}) + } + if p.V1_2_0 != nil { + return p.V1_2_0.ApplyFeeTokensUpdates(opts, []common.Address{addr}, []common.Address{}) + } + return nil, fmt.Errorf("no instance found to add fee token") +} + +func (p *PriceRegistryWrapper) GetDestinationChainGasPrice(opts *bind.CallOpts, chainselector uint64) (InternalTimestampedPackedUint224, error) { + if p.Latest != nil { + price, err := p.Latest.GetDestinationChainGasPrice(opts, chainselector) + if err != nil { + return InternalTimestampedPackedUint224{}, err + } + return InternalTimestampedPackedUint224{ + Value: price.Value, + Timestamp: price.Timestamp, + }, nil + } + if p.V1_2_0 != nil { + price, err := p.V1_2_0.GetDestinationChainGasPrice(opts, chainselector) + if err != nil { + return InternalTimestampedPackedUint224{}, err + } + return InternalTimestampedPackedUint224{ + Value: price.Value, + Timestamp: price.Timestamp, + }, nil + } + return InternalTimestampedPackedUint224{}, fmt.Errorf("no instance found to add fee token") +} + +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +type PriceRegistry struct { + client blockchain.EVMClient + Instance *PriceRegistryWrapper + logger *zerolog.Logger + EthAddress common.Address +} + +func (c *PriceRegistry) Address() string { + return c.EthAddress.Hex() +} + +func (c *PriceRegistry) AddPriceUpdater(addr common.Address) error { + opts, err := c.client.TransactionOpts(c.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("error getting transaction opts: %w", err) + } + tx, err := c.Instance.AddPriceUpdater(opts, addr) + if err != nil { + return fmt.Errorf("error adding price updater: %w", err) + } + c.logger.Info(). + Str("updaters", addr.Hex()). + Str(Network, c.client.GetNetworkConfig().Name). + Msg("PriceRegistry updater added") + return c.client.ProcessTransaction(tx) +} + +func (c *PriceRegistry) AddFeeToken(addr common.Address) error { + opts, err := c.client.TransactionOpts(c.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("error getting transaction opts: %w", err) + } + tx, err := c.Instance.AddFeeToken(opts, addr) + if err != nil { + return fmt.Errorf("error adding fee token: %w", err) + } + c.logger.Info(). + Str("feeTokens", addr.Hex()). + Str(Network, c.client.GetNetworkConfig().Name). + Msg("PriceRegistry feeToken set") + return c.client.ProcessTransaction(tx) +} + +func (c *PriceRegistry) UpdatePrices(tokenUpdates []InternalTokenPriceUpdate, gasUpdates []InternalGasPriceUpdate) error { + opts, err := c.client.TransactionOpts(c.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("error getting transaction opts: %w", err) + } + var tx *types.Transaction + if c.Instance.Latest != nil { + var tokenUpdatesLatest []price_registry.InternalTokenPriceUpdate + var gasUpdatesLatest []price_registry.InternalGasPriceUpdate + for _, update := range tokenUpdates { + tokenUpdatesLatest = append(tokenUpdatesLatest, price_registry.InternalTokenPriceUpdate{ + SourceToken: update.SourceToken, + UsdPerToken: update.UsdPerToken, + }) + } + for _, update := range gasUpdates { + gasUpdatesLatest = append(gasUpdatesLatest, price_registry.InternalGasPriceUpdate{ + DestChainSelector: update.DestChainSelector, + UsdPerUnitGas: update.UsdPerUnitGas, + }) + } + tx, err = c.Instance.Latest.UpdatePrices(opts, price_registry.InternalPriceUpdates{ + TokenPriceUpdates: tokenUpdatesLatest, + GasPriceUpdates: gasUpdatesLatest, + }) + if err != nil { + return fmt.Errorf("error updating prices: %w", err) + } + } + if c.Instance.V1_2_0 != nil { + var tokenUpdates_1_2_0 []price_registry_1_2_0.InternalTokenPriceUpdate + var gasUpdates_1_2_0 []price_registry_1_2_0.InternalGasPriceUpdate + for _, update := range tokenUpdates { + tokenUpdates_1_2_0 = append(tokenUpdates_1_2_0, price_registry_1_2_0.InternalTokenPriceUpdate{ + SourceToken: update.SourceToken, + UsdPerToken: update.UsdPerToken, + }) + } + for _, update := range gasUpdates { + gasUpdates_1_2_0 = append(gasUpdates_1_2_0, price_registry_1_2_0.InternalGasPriceUpdate{ + DestChainSelector: update.DestChainSelector, + UsdPerUnitGas: update.UsdPerUnitGas, + }) + } + tx, err = c.Instance.V1_2_0.UpdatePrices(opts, price_registry_1_2_0.InternalPriceUpdates{ + TokenPriceUpdates: tokenUpdates_1_2_0, + GasPriceUpdates: gasUpdates_1_2_0, + }) + if err != nil { + return fmt.Errorf("error updating prices: %w", err) + } + } + if tx == nil { + return fmt.Errorf("no instance found to update prices") + } + c.logger.Info(). + Str(Network, c.client.GetNetworkConfig().Name). + Interface("tokenUpdates", tokenUpdates). + Interface("gasUpdates", gasUpdates). + Msg("Prices updated") + return c.client.ProcessTransaction(tx) +} + +func (c *PriceRegistry) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, latest chan *price_registry.PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) { + if c.Instance.Latest != nil { + return c.Instance.Latest.WatchUsdPerUnitGasUpdated(opts, latest, destChain) + } + if c.Instance.V1_2_0 != nil { + newP, err := price_registry.NewPriceRegistry(c.Instance.V1_2_0.Address(), wrappers.MustNewWrappedContractBackend(c.client, nil)) + if err != nil { + return nil, fmt.Errorf("failed to create new PriceRegistry contract: %w", err) + } + return newP.WatchUsdPerUnitGasUpdated(opts, latest, destChain) + } + return nil, fmt.Errorf("no instance found to watch for price updates for gas") +} + +func (c *PriceRegistry) WatchUsdPerTokenUpdated(opts *bind.WatchOpts, latest chan *price_registry.PriceRegistryUsdPerTokenUpdated) (event.Subscription, error) { + if c.Instance.Latest != nil { + return c.Instance.Latest.WatchUsdPerTokenUpdated(opts, latest, nil) + } + if c.Instance.V1_2_0 != nil { + newP, err := price_registry.NewPriceRegistry(c.Instance.V1_2_0.Address(), wrappers.MustNewWrappedContractBackend(c.client, nil)) + if err != nil { + return nil, fmt.Errorf("failed to create new PriceRegistry contract: %w", err) + } + return newP.WatchUsdPerTokenUpdated(opts, latest, nil) + } + return nil, fmt.Errorf("no instance found to watch for price updates for tokens") +} + +type TokenAdminRegistry struct { + client blockchain.EVMClient + logger *zerolog.Logger + Instance *token_admin_registry.TokenAdminRegistry + EthAddress common.Address +} + +func (r *TokenAdminRegistry) Address() string { + return r.EthAddress.Hex() +} + +func (r *TokenAdminRegistry) SetAdminAndRegisterPool(tokenAddr, poolAddr common.Address) error { + opts, err := r.client.TransactionOpts(r.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("error getting transaction opts: %w", err) + } + tx, err := r.Instance.ProposeAdministrator(opts, tokenAddr, opts.From) + if err != nil { + return fmt.Errorf("error setting admin for token %s : %w", tokenAddr.Hex(), err) + } + err = r.client.ProcessTransaction(tx) + if err != nil { + return fmt.Errorf("error processing tx for setting admin on token %w", err) + } + r.logger.Info(). + Str("Admin", opts.From.Hex()). + Str("Token", tokenAddr.Hex()). + Str("TokenAdminRegistry", r.Address()). + Msg("Admin is set for token on TokenAdminRegistry") + err = r.client.WaitForEvents() + if err != nil { + return fmt.Errorf("error waiting for tx for setting admin on pool %w", err) + } + opts, err = r.client.TransactionOpts(r.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("error getting transaction opts: %w", err) + } + tx, err = r.Instance.AcceptAdminRole(opts, tokenAddr) + if err != nil { + return fmt.Errorf("error accepting admin role for token %s : %w", tokenAddr.Hex(), err) + } + err = r.client.ProcessTransaction(tx) + if err != nil { + return fmt.Errorf("error processing tx for accepting admin role for token %w", err) + } + r.logger.Info(). + Str("Token", tokenAddr.Hex()). + Str("TokenAdminRegistry", r.Address()). + Msg("Admin role is accepted for token on TokenAdminRegistry") + err = r.client.WaitForEvents() + if err != nil { + return fmt.Errorf("error waiting for tx for accepting admin role for token %w", err) + } + opts, err = r.client.TransactionOpts(r.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("error getting transaction opts: %w", err) + } + tx, err = r.Instance.SetPool(opts, tokenAddr, poolAddr) + if err != nil { + return fmt.Errorf("error setting token %s and pool %s : %w", tokenAddr.Hex(), poolAddr.Hex(), err) + } + r.logger.Info(). + Str("Token", tokenAddr.Hex()). + Str("Pool", poolAddr.Hex()). + Str("TokenAdminRegistry", r.Address()). + Msg("token and pool are set on TokenAdminRegistry") + err = r.client.ProcessTransaction(tx) + if err != nil { + return fmt.Errorf("error processing tx for setting token %s and pool %s : %w", tokenAddr.Hex(), poolAddr.Hex(), err) + } + return nil +} + +type Router struct { + client blockchain.EVMClient + logger *zerolog.Logger + Instance *router.Router + EthAddress common.Address +} + +func (r *Router) Address() string { + return r.EthAddress.Hex() +} + +func (r *Router) SetOnRamp(chainSelector uint64, onRamp common.Address) error { + opts, err := r.client.TransactionOpts(r.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("error getting transaction opts: %w", err) + } + r.logger.Info(). + Str("Router", r.Address()). + Str("OnRamp", onRamp.Hex()). + Str(Network, r.client.GetNetworkName()). + Str("ChainSelector", strconv.FormatUint(chainSelector, 10)). + Msg("Setting on ramp for r") + + tx, err := r.Instance.ApplyRampUpdates(opts, []router.RouterOnRamp{{DestChainSelector: chainSelector, OnRamp: onRamp}}, nil, nil) + if err != nil { + return fmt.Errorf("error applying ramp updates: %w", err) + } + r.logger.Info(). + Str("onRamp", onRamp.Hex()). + Str("Network Name", r.client.GetNetworkConfig().Name). + Msg("Router is configured") + return r.client.ProcessTransaction(tx) +} + +func (r *Router) CCIPSend(destChainSelector uint64, msg router.ClientEVM2AnyMessage, valueForNative *big.Int) (*types.Transaction, error) { + opts, err := r.client.TransactionOpts(r.client.GetDefaultWallet()) + if err != nil { + return nil, fmt.Errorf("error getting transaction opts: %w", err) + } + if valueForNative != nil { + opts.Value = valueForNative + } + + r.logger.Info(). + Str(Network, r.client.GetNetworkName()). + Str("Router", r.Address()). + Interface("TokensAndAmounts", msg.TokenAmounts). + Str("FeeToken", msg.FeeToken.Hex()). + Str("ExtraArgs", fmt.Sprintf("0x%x", msg.ExtraArgs[:])). + Str("Receiver", fmt.Sprintf("0x%x", msg.Receiver[:])). + Msg("Sending msg") + return r.Instance.CcipSend(opts, destChainSelector, msg) +} + +func (r *Router) CCIPSendAndProcessTx(destChainSelector uint64, msg router.ClientEVM2AnyMessage, valueForNative *big.Int) (*types.Transaction, error) { + tx, err := r.CCIPSend(destChainSelector, msg, valueForNative) + if err != nil { + return nil, fmt.Errorf("failed to send msg: %w", err) + } + r.logger.Info(). + Str("Router", r.Address()). + Str("txHash", tx.Hash().Hex()). + Str(Network, r.client.GetNetworkConfig().Name). + Str("Chain Selector", strconv.FormatUint(destChainSelector, 10)). + Msg("Message Sent") + return tx, r.client.ProcessTransaction(tx) +} + +func (r *Router) AddOffRamp(offRamp common.Address, sourceChainId uint64) (*types.Transaction, error) { + opts, err := r.client.TransactionOpts(r.client.GetDefaultWallet()) + if err != nil { + return nil, fmt.Errorf("failed to get transaction opts: %w", err) + } + tx, err := r.Instance.ApplyRampUpdates(opts, nil, nil, []router.RouterOffRamp{{SourceChainSelector: sourceChainId, OffRamp: offRamp}}) + if err != nil { + return nil, fmt.Errorf("failed to add offRamp: %w", err) + } + r.logger.Info(). + Str("offRamp", offRamp.Hex()). + Str(Network, r.client.GetNetworkConfig().Name). + Msg("offRamp is added to Router") + return tx, r.client.ProcessTransaction(tx) +} + +func (r *Router) SetWrappedNative(wNative common.Address) (*types.Transaction, error) { + opts, err := r.client.TransactionOpts(r.client.GetDefaultWallet()) + if err != nil { + return nil, fmt.Errorf("failed to get transaction opts: %w", err) + } + tx, err := r.Instance.SetWrappedNative(opts, wNative) + if err != nil { + return nil, fmt.Errorf("failed to set wrapped native: %w", err) + } + r.logger.Info(). + Str("wrapped native", wNative.Hex()). + Str("router", r.Address()). + Str(Network, r.client.GetNetworkConfig().Name). + Msg("wrapped native is added for Router") + return tx, r.client.ProcessTransaction(tx) +} + +func (r *Router) GetFee(destChainSelector uint64, message router.ClientEVM2AnyMessage) (*big.Int, error) { + return r.Instance.GetFee(nil, destChainSelector, message) +} + +type SendReqEventData struct { + MessageId [32]byte + SequenceNumber uint64 + DataLength int + NoOfTokens int + LogInfo LogInfo + Fee *big.Int +} + +type OnRampWrapper struct { + Latest *evm_2_evm_onramp.EVM2EVMOnRamp + V1_2_0 *evm_2_evm_onramp_1_2_0.EVM2EVMOnRamp +} + +func (w OnRampWrapper) SetNops(opts *bind.TransactOpts, owner common.Address) (*types.Transaction, error) { + if w.Latest != nil { + return w.Latest.SetNops(opts, []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{ + { + Nop: owner, + Weight: 1, + }, + }) + } + if w.V1_2_0 != nil { + return w.V1_2_0.SetNops(opts, []evm_2_evm_onramp_1_2_0.EVM2EVMOnRampNopAndWeight{ + { + Nop: owner, + Weight: 1, + }, + }) + } + return nil, fmt.Errorf("no instance found to set nops") +} + +func (w OnRampWrapper) SetTokenTransferFeeConfig( + opts *bind.TransactOpts, + config []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs, + addresses []common.Address, +) (*types.Transaction, error) { + if w.Latest != nil { + return w.Latest.SetTokenTransferFeeConfig(opts, config, addresses) + } + if w.V1_2_0 != nil { + var configV12 []evm_2_evm_onramp_1_2_0.EVM2EVMOnRampTokenTransferFeeConfigArgs + for _, c := range config { + configV12 = append(configV12, evm_2_evm_onramp_1_2_0.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + Token: c.Token, + MinFeeUSDCents: c.MinFeeUSDCents, + MaxFeeUSDCents: c.MaxFeeUSDCents, + DeciBps: c.DeciBps, + DestGasOverhead: c.DestGasOverhead, + DestBytesOverhead: c.DestBytesOverhead, + }) + } + return w.V1_2_0.SetTokenTransferFeeConfig(opts, configV12) + } + return nil, fmt.Errorf("no instance found to set token transfer fee config") +} + +func (w OnRampWrapper) PayNops(opts *bind.TransactOpts) (*types.Transaction, error) { + if w.Latest != nil { + return w.Latest.PayNops(opts) + } + if w.V1_2_0 != nil { + return w.V1_2_0.PayNops(opts) + } + return nil, fmt.Errorf("no instance found to pay nops") +} + +func (w OnRampWrapper) WithdrawNonLinkFees(opts *bind.TransactOpts, native common.Address, owner common.Address) (*types.Transaction, error) { + if w.Latest != nil { + return w.Latest.WithdrawNonLinkFees(opts, native, owner) + } + if w.V1_2_0 != nil { + return w.V1_2_0.WithdrawNonLinkFees(opts, native, owner) + } + return nil, fmt.Errorf("no instance found to withdraw non link fees") +} + +func (w OnRampWrapper) SetRateLimiterConfig(opts *bind.TransactOpts, config evm_2_evm_onramp.RateLimiterConfig) (*types.Transaction, error) { + if w.Latest != nil { + return w.Latest.SetRateLimiterConfig(opts, config) + } + if w.V1_2_0 != nil { + return w.V1_2_0.SetRateLimiterConfig(opts, evm_2_evm_onramp_1_2_0.RateLimiterConfig{ + IsEnabled: config.IsEnabled, + Capacity: config.Capacity, + Rate: config.Rate, + }) + } + return nil, fmt.Errorf("no instance found to set rate limiter config") +} + +func (w OnRampWrapper) ParseCCIPSendRequested(l types.Log) (uint64, error) { + if w.Latest != nil { + sendReq, err := w.Latest.ParseCCIPSendRequested(l) + if err != nil { + return 0, err + } + return sendReq.Message.SequenceNumber, nil + } + if w.V1_2_0 != nil { + sendReq, err := w.V1_2_0.ParseCCIPSendRequested(l) + if err != nil { + return 0, err + } + return sendReq.Message.SequenceNumber, nil + } + return 0, fmt.Errorf("no instance found to parse CCIPSendRequested") +} + +func (w OnRampWrapper) GetDynamicConfig(opts *bind.CallOpts) (uint32, error) { + if w.Latest != nil { + cfg, err := w.Latest.GetDynamicConfig(opts) + if err != nil { + return 0, err + } + return cfg.MaxDataBytes, nil + } + if w.V1_2_0 != nil { + cfg, err := w.V1_2_0.GetDynamicConfig(opts) + if err != nil { + return 0, err + } + return cfg.MaxDataBytes, nil + } + return 0, fmt.Errorf("no instance found to get dynamic config") +} + +func (w OnRampWrapper) ApplyPoolUpdates(opts *bind.TransactOpts, tokens []common.Address, pools []common.Address) (*types.Transaction, error) { + if w.Latest != nil { + return nil, fmt.Errorf("latest version does not support ApplyPoolUpdates") + } + if w.V1_2_0 != nil { + var poolUpdates []evm_2_evm_onramp_1_2_0.InternalPoolUpdate + if len(tokens) != len(pools) { + return nil, fmt.Errorf("tokens and pools length mismatch") + } + for i, token := range tokens { + poolUpdates = append(poolUpdates, evm_2_evm_onramp_1_2_0.InternalPoolUpdate{ + Token: token, + Pool: pools[i], + }) + } + return w.V1_2_0.ApplyPoolUpdates(opts, []evm_2_evm_onramp_1_2_0.InternalPoolUpdate{}, poolUpdates) + } + return nil, fmt.Errorf("no instance found to apply pool updates") +} + +// CurrentRateLimiterState returns the current state of the rate limiter +func (w OnRampWrapper) CurrentRateLimiterState(opts *bind.CallOpts) (*RateLimiterConfig, error) { + if w.Latest != nil { + rlConfig, err := w.Latest.CurrentRateLimiterState(opts) + if err != nil { + return nil, err + } + return &RateLimiterConfig{ + IsEnabled: rlConfig.IsEnabled, + Rate: rlConfig.Rate, + Capacity: rlConfig.Capacity, + Tokens: rlConfig.Tokens, + }, err + } + if w.V1_2_0 != nil { + rlConfig, err := w.V1_2_0.CurrentRateLimiterState(opts) + if err != nil { + return nil, err + } + return &RateLimiterConfig{ + IsEnabled: rlConfig.IsEnabled, + Rate: rlConfig.Rate, + Capacity: rlConfig.Capacity, + Tokens: rlConfig.Tokens, + }, err + } + return nil, fmt.Errorf("no instance found to get current rate limiter state") +} + +type OnRamp struct { + client blockchain.EVMClient + logger *zerolog.Logger + Instance *OnRampWrapper + EthAddress common.Address +} + +// WatchCCIPSendRequested returns a subscription to watch for CCIPSendRequested events +// there is no difference in the event between the two versions +// so we can use the latest version to watch for events +func (onRamp *OnRamp) WatchCCIPSendRequested(opts *bind.WatchOpts, sendReqEvent chan *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested) (event.Subscription, error) { + if onRamp.Instance.Latest != nil { + return onRamp.Instance.Latest.WatchCCIPSendRequested(opts, sendReqEvent) + } + // cast the contract to the latest version so that we can watch for events with latest wrapper + if onRamp.Instance.V1_2_0 != nil { + newRamp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(onRamp.EthAddress, wrappers.MustNewWrappedContractBackend(onRamp.client, nil)) + if err != nil { + return nil, fmt.Errorf("failed to cast to latest version: %w", err) + } + return newRamp.WatchCCIPSendRequested(opts, sendReqEvent) + } + // should never reach here + return nil, fmt.Errorf("no instance found to watch for CCIPSendRequested") +} + +func (onRamp *OnRamp) Address() string { + return onRamp.EthAddress.Hex() +} + +func (onRamp *OnRamp) SetNops() error { + opts, err := onRamp.client.TransactionOpts(onRamp.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + owner := common.HexToAddress(onRamp.client.GetDefaultWallet().Address()) + // set the payee to the default wallet + tx, err := onRamp.Instance.SetNops(opts, owner) + if err != nil { + return fmt.Errorf("failed to set nops: %w", err) + } + return onRamp.client.ProcessTransaction(tx) +} + +// SetTokenTransferFeeConfig sets the token transfer fee configuration for the OnRamp +func (onRamp *OnRamp) SetTokenTransferFeeConfig(tokenTransferFeeConfig []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs) error { + opts, err := onRamp.client.TransactionOpts(onRamp.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + for i := range tokenTransferFeeConfig { + if tokenTransferFeeConfig[i].DestBytesOverhead == 0 { + tokenTransferFeeConfig[i].DestBytesOverhead = defaultDestByteOverhead + } + if tokenTransferFeeConfig[i].DestGasOverhead == 0 { + tokenTransferFeeConfig[i].DestGasOverhead = defaultDestGasOverhead + } + } + tx, err := onRamp.Instance.SetTokenTransferFeeConfig(opts, tokenTransferFeeConfig, []common.Address{}) + if err != nil { + return fmt.Errorf("failed to set token transfer fee config: %w", err) + } + onRamp.logger.Info(). + Interface("tokenTransferFeeConfig", tokenTransferFeeConfig). + Str("onRamp", onRamp.Address()). + Str(Network, onRamp.client.GetNetworkConfig().Name). + Msg("TokenTransferFeeConfig set in OnRamp") + return onRamp.client.ProcessTransaction(tx) +} + +func (onRamp *OnRamp) PayNops() error { + opts, err := onRamp.client.TransactionOpts(onRamp.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + tx, err := onRamp.Instance.PayNops(opts) + if err != nil { + return fmt.Errorf("failed to pay nops: %w", err) + } + return onRamp.client.ProcessTransaction(tx) +} + +func (onRamp *OnRamp) WithdrawNonLinkFees(wrappedNative common.Address) error { + opts, err := onRamp.client.TransactionOpts(onRamp.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + owner := common.HexToAddress(onRamp.client.GetDefaultWallet().Address()) + tx, err := onRamp.Instance.WithdrawNonLinkFees(opts, wrappedNative, owner) + if err != nil { + return fmt.Errorf("failed to withdraw non link fees: %w", err) + } + return onRamp.client.ProcessTransaction(tx) +} + +// SetRateLimit sets the Aggregate Rate Limit (ARL) values for the OnRamp +func (onRamp *OnRamp) SetRateLimit(rlConfig evm_2_evm_onramp.RateLimiterConfig) error { + opts, err := onRamp.client.TransactionOpts(onRamp.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := onRamp.Instance.SetRateLimiterConfig(opts, rlConfig) + if err != nil { + return fmt.Errorf("failed to set rate limit: %w", err) + } + onRamp.logger.Info(). + Bool("Enabled", rlConfig.IsEnabled). + Str("capacity", rlConfig.Capacity.String()). + Str("rate", rlConfig.Rate.String()). + Str("onRamp", onRamp.Address()). + Str(Network, onRamp.client.GetNetworkConfig().Name). + Msg("Setting Rate limit in OnRamp") + return onRamp.client.ProcessTransaction(tx) +} + +func (onRamp *OnRamp) ApplyPoolUpdates(tokens []common.Address, pools []common.Address) error { + // if the latest version is used, no need to apply pool updates + if onRamp.Instance.Latest != nil { + return nil + } + opts, err := onRamp.client.TransactionOpts(onRamp.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + tx, err := onRamp.Instance.ApplyPoolUpdates(opts, tokens, pools) + if err != nil { + return fmt.Errorf("failed to apply pool updates: %w", err) + } + onRamp.logger.Info(). + Interface("tokens", tokens). + Interface("pools", pools). + Str("onRamp", onRamp.Address()). + Str(Network, onRamp.client.GetNetworkConfig().Name). + Msg("poolUpdates set in OnRamp") + return onRamp.client.ProcessTransaction(tx) +} + +// OffRamp represents the OffRamp CCIP contract on the destination chain +type OffRamp struct { + client blockchain.EVMClient + logger *zerolog.Logger + Instance *OffRampWrapper + EthAddress common.Address +} + +func (offRamp *OffRamp) Address() string { + return offRamp.EthAddress.Hex() +} + +// WatchExecutionStateChanged returns a subscription to watch for ExecutionStateChanged events +// there is no difference in the event between the two versions +// so we can use the latest version to watch for events +func (offRamp *OffRamp) WatchExecutionStateChanged( + opts *bind.WatchOpts, + execEvent chan *evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged, + sequenceNumber []uint64, + messageId [][32]byte, +) (event.Subscription, error) { + if offRamp.Instance.Latest != nil { + return offRamp.Instance.Latest.WatchExecutionStateChanged(opts, execEvent, sequenceNumber, messageId) + } + if offRamp.Instance.V1_2_0 != nil { + newOffRamp, err := evm_2_evm_offramp.NewEVM2EVMOffRamp(offRamp.EthAddress, wrappers.MustNewWrappedContractBackend(offRamp.client, nil)) + if err != nil { + return nil, fmt.Errorf("failed to cast to latest version of OffRamp from v1_2_0: %w", err) + } + return newOffRamp.WatchExecutionStateChanged(opts, execEvent, sequenceNumber, messageId) + } + return nil, fmt.Errorf("no instance found to watch for ExecutionStateChanged") +} + +// SetOCR2Config sets the offchain reporting protocol configuration +func (offRamp *OffRamp) SetOCR2Config( + signers []common.Address, + transmitters []common.Address, + f uint8, + onchainConfig []byte, + offchainConfigVersion uint64, + offchainConfig []byte, +) error { + offRamp.logger.Info().Str("Contract Address", offRamp.Address()).Msg("Configuring OffRamp Contract") + // Set Config + opts, err := offRamp.client.TransactionOpts(offRamp.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction options: %w", err) + } + offRamp.logger.Debug(). + Interface("SignerAddresses", signers). + Interface("TransmitterAddresses", transmitters). + Str(Network, offRamp.client.GetNetworkConfig().Name). + Msg("Configuring OffRamp") + if offRamp.Instance.Latest != nil { + tx, err := offRamp.Instance.Latest.SetOCR2Config( + opts, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + ) + if err != nil { + return fmt.Errorf("failed to set latest OCR2 config: %w", err) + } + return offRamp.client.ProcessTransaction(tx) + } + if offRamp.Instance.V1_2_0 != nil { + tx, err := offRamp.Instance.V1_2_0.SetOCR2Config( + opts, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + ) + if err != nil { + return fmt.Errorf("failed to set 1.2 OCR2 config: %w", err) + } + return offRamp.client.ProcessTransaction(tx) + } + return fmt.Errorf("no instance found to set OCR2 config") +} + +// AddRateLimitTokens adds token pairs to the OffRamp's rate limit +func (offRamp *OffRamp) AddRateLimitTokens(sourceTokens, destTokens []common.Address) error { + if offRamp.Instance.V1_2_0 != nil { + return nil + } + + if len(sourceTokens) != len(destTokens) { + return fmt.Errorf("source and dest tokens must be of the same length") + } + opts, err := offRamp.client.TransactionOpts(offRamp.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + + if offRamp.Instance.Latest != nil { + rateLimitTokens := make([]evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken, len(sourceTokens)) + for i, sourceToken := range sourceTokens { + rateLimitTokens[i] = evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken{ + SourceToken: sourceToken, + DestToken: destTokens[i], + } + } + + tx, err := offRamp.Instance.Latest.UpdateRateLimitTokens(opts, []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken{}, rateLimitTokens) + if err != nil { + return fmt.Errorf("failed to apply rate limit tokens updates: %w", err) + } + offRamp.logger.Info(). + Interface("rateLimitToken adds", rateLimitTokens). + Str("offRamp", offRamp.Address()). + Str(Network, offRamp.client.GetNetworkConfig().Name). + Msg("rateLimitTokens set in OffRamp") + return offRamp.client.ProcessTransaction(tx) + } + return fmt.Errorf("no supported OffRamp version instance found") +} + +// RemoveRateLimitTokens removes token pairs to the OffRamp's rate limit. +// If you ask to remove a token pair that doesn't exist, it will return an error. +func (offRamp *OffRamp) RemoveRateLimitTokens(ctx context.Context, sourceTokens, destTokens []common.Address) error { + callOpts := &bind.CallOpts{ + From: common.HexToAddress(offRamp.client.GetDefaultWallet().Address()), + Context: ctx, + } + + switch { + case offRamp.Instance.Latest != nil: + existingRateLimitTokens, err := offRamp.Instance.Latest.GetAllRateLimitTokens(callOpts) + if err != nil { + return fmt.Errorf("failed to get all rate limit tokens: %w", err) + } + + rateLimitTokens := make([]evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken, len(sourceTokens)) + for i, sourceToken := range sourceTokens { + destToken := destTokens[i] + // Check if the source rate limit token exists + foundIndex := -1 + for j, existingSourceToken := range existingRateLimitTokens.SourceTokens { + if existingSourceToken == sourceToken { + foundIndex = j + break + } + } + if foundIndex == -1 { + return fmt.Errorf("source rate limit token not found for pair: %s -> %s", sourceTokens[i].Hex(), destTokens[i].Hex()) + } + // Check if the matching dest rate limit token exists + if existingRateLimitTokens.DestTokens[foundIndex] != destToken { + return fmt.Errorf("dest rate limit token not found for pair: %s -> %s", sourceTokens[i].Hex(), destTokens[i].Hex()) + } + // Update the existing rate limit tokens to remove the pair for visibility + existingRateLimitTokens.SourceTokens = append(existingRateLimitTokens.SourceTokens[:foundIndex], existingRateLimitTokens.SourceTokens[foundIndex+1:]...) + existingRateLimitTokens.DestTokens = append(existingRateLimitTokens.DestTokens[:foundIndex], existingRateLimitTokens.DestTokens[foundIndex+1:]...) + + rateLimitTokens[i] = evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken{ + SourceToken: sourceToken, + DestToken: destToken, + } + } + + opts, err := offRamp.client.TransactionOpts(offRamp.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + tx, err := offRamp.Instance.Latest.UpdateRateLimitTokens(opts, rateLimitTokens, []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken{}) + if err != nil { + return fmt.Errorf("failed to remove rate limit tokens: %w", err) + } + offRamp.logger.Info(). + Interface("RateLimitTokens Remaining", existingRateLimitTokens). + Interface("RateLimitTokens Removed", rateLimitTokens). + Str("OffRamp", offRamp.Address()). + Str(Network, offRamp.client.GetNetworkConfig().Name). + Msg("RateLimitTokens Removed from OffRamp") + return offRamp.client.ProcessTransaction(tx) + case offRamp.Instance.V1_2_0 != nil: + return nil + } + return fmt.Errorf("no supported OffRamp version instance found") +} + +// RemoveAllRateLimitTokens removes all token pairs from the OffRamp's rate limit. +func (offRamp *OffRamp) RemoveAllRateLimitTokens(ctx context.Context) error { + callOpts := &bind.CallOpts{ + From: common.HexToAddress(offRamp.client.GetDefaultWallet().Address()), + Context: ctx, + } + + switch { + case offRamp.Instance.Latest != nil: + allRateLimitTokens, err := offRamp.Instance.Latest.GetAllRateLimitTokens(callOpts) + if err != nil { + return fmt.Errorf("failed to get all rate limit tokens: %w", err) + } + + rateLimitTokens := make([]evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken, len(allRateLimitTokens.SourceTokens)) + for i, sourceToken := range allRateLimitTokens.SourceTokens { + rateLimitTokens[i] = evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken{ + SourceToken: sourceToken, + DestToken: allRateLimitTokens.DestTokens[i], + } + } + + opts, err := offRamp.client.TransactionOpts(offRamp.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + tx, err := offRamp.Instance.Latest.UpdateRateLimitTokens(opts, rateLimitTokens, []evm_2_evm_offramp.EVM2EVMOffRampRateLimitToken{}) + if err != nil { + return fmt.Errorf("failed to remove rate limit tokens: %w", err) + } + offRamp.logger.Info(). + Interface("RateLimitTokens Removed", rateLimitTokens). + Str("OffRamp", offRamp.Address()). + Str(Network, offRamp.client.GetNetworkConfig().Name). + Msg("Removed all RateLimitTokens from OffRamp") + return offRamp.client.ProcessTransaction(tx) + case offRamp.Instance.V1_2_0 != nil: + return nil + } + return fmt.Errorf("no supported OffRamp version instance found") +} + +// SetRateLimit sets the Aggregate Rate Limit (ARL) values for the OffRamp +func (offRamp *OffRamp) SetRateLimit(rlConfig RateLimiterConfig) error { + opts, err := offRamp.client.TransactionOpts(offRamp.client.GetDefaultWallet()) + if err != nil { + return err + } + offRamp.logger.Info(). + Bool("Enabled", rlConfig.IsEnabled). + Str("Capacity", rlConfig.Capacity.String()). + Str("Rate", rlConfig.Rate.String()). + Str("OffRamp", offRamp.Address()). + Str(Network, offRamp.client.GetNetworkConfig().Name). + Msg("Setting Rate limit on OffRamp") + + switch { + case offRamp.Instance.Latest != nil: + tx, err := offRamp.Instance.Latest.SetRateLimiterConfig(opts, evm_2_evm_offramp.RateLimiterConfig{ + IsEnabled: rlConfig.IsEnabled, + Capacity: rlConfig.Capacity, + Rate: rlConfig.Rate, + }) + if err != nil { + return fmt.Errorf("failed to set rate limit: %w", err) + } + return offRamp.client.ProcessTransaction(tx) + case offRamp.Instance.V1_2_0 != nil: + tx, err := offRamp.Instance.V1_2_0.SetRateLimiterConfig(opts, evm_2_evm_offramp_1_2_0.RateLimiterConfig{ + IsEnabled: rlConfig.IsEnabled, + Capacity: rlConfig.Capacity, + Rate: rlConfig.Rate, + }) + if err != nil { + return fmt.Errorf("failed to set rate limit: %w", err) + } + return offRamp.client.ProcessTransaction(tx) + } + return fmt.Errorf("no supported OffRamp version instance found") +} + +func (offRamp *OffRamp) SyncTokensAndPools(sourceTokens, pools []common.Address) error { + if offRamp.Instance.Latest != nil { + return nil + } + opts, err := offRamp.client.TransactionOpts(offRamp.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + if offRamp.Instance.V1_2_0 != nil { + var tokenUpdates []evm_2_evm_offramp_1_2_0.InternalPoolUpdate + for i, srcToken := range sourceTokens { + tokenUpdates = append(tokenUpdates, evm_2_evm_offramp_1_2_0.InternalPoolUpdate{ + Token: srcToken, + Pool: pools[i], + }) + } + tx, err := offRamp.Instance.V1_2_0.ApplyPoolUpdates(opts, []evm_2_evm_offramp_1_2_0.InternalPoolUpdate{}, tokenUpdates) + if err != nil { + return fmt.Errorf("failed to apply pool updates: %w", err) + } + offRamp.logger.Info(). + Interface("tokenUpdates", tokenUpdates). + Str("offRamp", offRamp.Address()). + Str(Network, offRamp.client.GetNetworkConfig().Name). + Msg("tokenUpdates set in OffRamp") + return offRamp.client.ProcessTransaction(tx) + } + return fmt.Errorf("no instance found to sync tokens and pools") +} + +// OffRampWrapper wraps multiple versions of the OffRamp contract as we support multiple at once. +// If you are using any of the functions in this struct, be sure to follow best practices: +// 1. If the function does not make sense for a specific version, +// (e.g. crucial functionality that changes state, but doesn't exist yet) return an error. +// 2. If the function does not make sense for a specific version, but calling it doesn't change how execution would work +// (e.g. functionality that wouldn't change state), you can return a nil or default value, treating it as a no-op. +// 3. If no valid versions are available, return an error. +// +// See CurrentRateLimiterState, WatchExecutionStateChanged, and AddRateLimitTokens for examples. +type OffRampWrapper struct { + Latest *evm_2_evm_offramp.EVM2EVMOffRamp + V1_2_0 *evm_2_evm_offramp_1_2_0.EVM2EVMOffRamp +} + +// CurrentRateLimiterState retrieves the current rate limiter state for the OffRamp contract +func (offRamp *OffRampWrapper) CurrentRateLimiterState(opts *bind.CallOpts) (RateLimiterConfig, error) { + if offRamp.Latest != nil { + rlConfig, err := offRamp.Latest.CurrentRateLimiterState(opts) + if err != nil { + return RateLimiterConfig{}, err + } + return RateLimiterConfig{ + IsEnabled: rlConfig.IsEnabled, + Capacity: rlConfig.Capacity, + Rate: rlConfig.Rate, + }, nil + } + if offRamp.V1_2_0 != nil { + rlConfig, err := offRamp.V1_2_0.CurrentRateLimiterState(opts) + if err != nil { + return RateLimiterConfig{}, err + } + return RateLimiterConfig{ + IsEnabled: rlConfig.IsEnabled, + Capacity: rlConfig.Capacity, + Rate: rlConfig.Rate, + }, nil + } + return RateLimiterConfig{}, fmt.Errorf("no instance found to get rate limiter state") +} + +type EVM2EVMOffRampExecutionStateChanged struct { + SequenceNumber uint64 + MessageId [32]byte + State uint8 + ReturnData []byte + LogInfo LogInfo +} + +type MockAggregator struct { + client blockchain.EVMClient + logger *zerolog.Logger + Instance *mock_v3_aggregator_contract.MockV3Aggregator + ContractAddress common.Address + RoundId *big.Int + Answer *big.Int +} + +func (a *MockAggregator) ChainID() uint64 { + return a.client.GetChainID().Uint64() +} + +// UpdateRoundData updates the round data in the aggregator contract +// if answer is nil, it will set next round data by adding random percentage( within provided range) to the previous round data +func (a *MockAggregator) UpdateRoundData(answer *big.Int, minP, maxP *int) error { + if answer == nil && (minP == nil || maxP == nil) { + return fmt.Errorf("minP and maxP are required to update round data with random percentage if answer is nil") + } + // if round id is nil, set it to 1 + if a.RoundId == nil { + a.RoundId = big.NewInt(1) + } + // if there is no answer provided and last saved answer is nil + // we fetch the last round data from chain + // and set the answer to the aggregator's latest answer and round id to the aggregator's latest round id + if answer == nil && a.Answer == nil { + roundData, err := a.Instance.LatestRoundData(nil) + if err != nil || roundData.RoundId == nil || roundData.Answer == nil { + return fmt.Errorf("unable to get latest round data: %w", err) + } + a.Answer = roundData.Answer + a.RoundId = roundData.RoundId + } + + // if answer is nil, we calculate the answer with random percentage (within the provided range) of latest answer + if answer == nil { + rand.Seed(uint64(time.Now().UnixNano())) + randomNumber := rand.Intn(pointer.GetInt(maxP)-pointer.GetInt(minP)+1) + pointer.GetInt(minP) + // answer = previous round answer + (previous round answer * random percentage) + answer = new(big.Int).Add(a.Answer, new(big.Int).Div(new(big.Int).Mul(a.Answer, big.NewInt(int64(randomNumber))), big.NewInt(100))) + } + // increment the round id + round := new(big.Int).Add(a.RoundId, big.NewInt(1)) + // save the round data as the latest round data + a.RoundId = round + a.Answer = answer + opts, err := a.client.TransactionOpts(a.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("unable to get transaction opts: %w", err) + } + a.logger.Info(). + Str("Contract Address", a.ContractAddress.Hex()). + Str("Network Name", a.client.GetNetworkConfig().Name). + Msg("Updating Round Data") + tx, err := a.Instance.UpdateRoundData(opts, round, answer, big.NewInt(time.Now().UTC().UnixNano()), big.NewInt(time.Now().UTC().UnixNano())) + if err != nil { + return fmt.Errorf("unable to update round data: %w", err) + } + a.logger.Info(). + Str("Contract Address", a.ContractAddress.Hex()). + Str("Network Name", a.client.GetNetworkConfig().Name). + Str("Round", round.String()). + Str("Answer", answer.String()). + Msg("Updated Round Data") + ctx, cancel := context.WithTimeout(context.Background(), a.client.GetNetworkConfig().Timeout.Duration) + defer cancel() + rec, err := bind.WaitMined(ctx, a.client.DeployBackend(), tx) + if err != nil { + return fmt.Errorf("error waiting for tx %s to be mined", tx.Hash().Hex()) + } + if rec.Status != types.ReceiptStatusSuccessful { + return fmt.Errorf("tx %s failed while updating round data", tx.Hash().Hex()) + } + + return a.client.MarkTxAsSentOnL2(tx) +} diff --git a/integration-tests/ccip-tests/contracts/laneconfig/contracts-1.2.json b/integration-tests/ccip-tests/contracts/laneconfig/contracts-1.2.json new file mode 100644 index 0000000000..4de4d1e504 --- /dev/null +++ b/integration-tests/ccip-tests/contracts/laneconfig/contracts-1.2.json @@ -0,0 +1,634 @@ +{ + "lane_configs": { + "Arbitrum Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0xe06b0e8c4bd455153e8794ad7Ea8Ff5A14B64E4b", + "router": "0x141fa059441E0ca23ce184B6A78bafD2A517DdE8", + "price_registry": "0x13015e4E6f839E1Aa1016DF521ea458ecA20438c", + "wrapped_native": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "src_contracts": { + "Avalanche Mainnet": { + "on_ramp": "0x05B723f3db92430FbE4395fD03E40Cc7e9D17988", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x77b60F85b25fD501E3ddED6C1fe7bF565C08A22A", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0x79f3ABeCe5A3AFFf32D47F4CFe45e7b65c9a2D91", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0xCe11020D56e5FDbfE46D9FC3021641FfbBB5AdEE", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0xC09b72E8128620C40D89649019d995Cc79f030C3", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x122F05F49e90508F089eE8D0d868d1a4f3E5a809", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x66a0046ac9FA104eB38B04cfF391CcD0122E6FbC", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Avalanche Mainnet": { + "off_ramp": "0xe0109912157d5B75ea8b3181123Cf32c73bc9920", + "commit_store": "0xDaa61b8Cd85977820f92d1e749E1D9F55Da6CCEA", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0xdB19F77F87661f9be0F557cf9a1ebeCf7D8F206c", + "commit_store": "0x6e37f4c82d9A31cc42B445874dd3c3De97AB553f", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "BSC Mainnet": { + "off_ramp": "0xB1b705c2315fced1B38baE463BE7DDef531e47fA", + "commit_store": "0x310cECbFf14Ad0307EfF762F461a487C1abb90bf", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x542ba1902044069330e8c5b36A84EC503863722f", + "commit_store": "0x060331fEdA35691e54876D957B4F9e3b8Cb47d20", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Optimism Mainnet": { + "off_ramp": "0xeeed4D86F3E0e6d32A6Ad29d8De6A0Dc91963A5f", + "commit_store": "0xbbB563c4d98020b9c0f3Cc34c2C0Ef9676806E35", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x9bDA7c8DCda4E39aFeB483cc0B7E3C1f6E0D5AB1", + "commit_store": "0x63a0AeaadAe851b990bBD9dc41f5C1B08b32026d", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0xEEf5Fb4c4953F9cA9ab1f25cE590776AfFc2c455", + "commit_store": "0xD268286A277095a9C3C90205110831a84505881c", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Avalanche Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x5947BB275c521040051D82396192181b413227A3", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0xdFD6C0dc67666DE3bB36b31eec5c7B1542A82C1E", + "router": "0xF4c7E640EdA248ef95972845a62bdC74237805dB", + "price_registry": "0xfA4edD04eaAcDB07c8D73621bc1790eC50D8c489", + "wrapped_native": "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x98f51B041e493fc4d72B8BD33218480bA0c66DDF", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x268fb4311D2c6CB2bbA01CCA9AC073Fb3bfd1C7c", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0x8eaae6462816CB4957184c48B86afA7642D8Bf2B", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0xD0701FcC7818c31935331B02Eb21e91eC71a1704", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x8629008887E073260c5434D6CaCFc83C3001d211", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x97500490d9126f34cf9aA0126d64623E170319Ef", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x9b1ed9De069Be4d50957464b359f98eD0Bf34dd5", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x770b1375F86E7a9bf30DBe3F97bea67193dC9135", + "commit_store": "0x23E2b34Ce8e12c53f8a39AD4b3FFCa845f8E617C", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Base Mainnet": { + "off_ramp": "0x4d6A796Bc85dcDF41ce9AaEB50B094C6b589748f", + "commit_store": "0xc4C4358FA01a04D6c6FE3b96a351946d4c2715C2", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "BSC Mainnet": { + "off_ramp": "0x83F53Fc798FEbfFbdF84830AD403b9989187a06C", + "commit_store": "0xD8ceCE2D7794385E00Ce3EF94550E732b0A0B959", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Ethereum Mainnet": { + "off_ramp": "0x5B833BD6456c604Eb396C0fBa477aD49e82B1A2a", + "commit_store": "0x23E23958D220B774680f91c2c91a6f2B2f610d7e", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Optimism Mainnet": { + "off_ramp": "0xb68A3EE8bD0A09eE221cf1859Dd5a4d5765188Fe", + "commit_store": "0x83DCeeCf822981F9F8552925eEfd88CAc1905dEA", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Polygon Mainnet": { + "off_ramp": "0x19250aBE66B88F214d02B6f3BF80F4118290C619", + "commit_store": "0x87A0935cE6254dB1252bBac90d1D07D04846aDCA", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "WeMix Mainnet": { + "off_ramp": "0x317dE8bc5c3292E494b6496586696d4966A922B0", + "commit_store": "0x97Fbf3d6DEac16adC721aE9187CeEa1e610aC7Af", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "Base Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x38660c8CC222c0192b635c2ac09687B4F25cCE5F", + "router": "0x881e3A65B4d4a04dD529061dd0071cf975F58bCD", + "price_registry": "0x6337a58D4BD7Ba691B66341779e8f87d4679923a", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x1E5Ca70d1e7A1B26061125738a880BBeA42FeB21", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0xBE5a9E336D9614024B4Fa10D8112671fc9A42d96", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0xdd4Fb402d41Beb0eEeF6CfB1bf445f50bDC8c981", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0xDEA286dc0E01Cb4755650A6CF8d1076b454eA1cb", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0xd952FEAcDd5919Cc5E9454b53bF45d4E73dD6457", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x3DB8Bea142e41cA3633890d0e5640F99a895D6A5", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x8531E63aE9279a1f0D09eba566CD1b092b95f3D5", + "commit_store": "0x327E13f54c7871a2416006B33B4822eAAD357916", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Avalanche Mainnet": { + "off_ramp": "0x8345F2fF67e5A65e85dc955DE1414832608E00aD", + "commit_store": "0xd0b13be4c53A6262b47C5DDd36F0257aa714F562", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "BSC Mainnet": { + "off_ramp": "0x48a51f5D38BE630Ddd6417Ea2D9052B8efc91a18", + "commit_store": "0xF97127e77252284EC9D4bc13C247c9D1A99F72B0", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Ethereum Mainnet": { + "off_ramp": "0xEC0cFe335a4d53dBA70CB650Ab56eEc32788F0BB", + "commit_store": "0x0ae3c2c7FB789bd05A450CD3075D11f6c2Ca4F77", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Optimism Mainnet": { + "off_ramp": "0xf50c0d2a8B6Db60f1D93E60f03d0413D56153E4F", + "commit_store": "0x16f72C15165f7C9d74c12fDF188E399d4d3724e4", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Polygon Mainnet": { + "off_ramp": "0x75F29f058b31106F99caFdc17c9b26ADfcC7b5D7", + "commit_store": "0xb719616E732581B570232DfB13Ca49D27667Af9f", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "BSC Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x404460C6A5EdE2D891e8297795264fDe62ADBB75", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x3DB43b96B2625F4232e9Df900d464dd2c64C0021", + "router": "0x34B03Cb9086d7D758AC55af71584F81A598759FE", + "price_registry": "0xd64aAbD70A71d9f0A00B99F6EFc1626aA2dD43C7", + "wrapped_native": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "src_contracts": { + "Avalanche Mainnet": { + "on_ramp": "0x6aa72a998859eF93356c6521B72155D355D0Cfd2", + "deployed_at": 11111111 + }, + "Arbitrum Mainnet": { + "on_ramp": "0x2788b46BAcFF49BD89562e6bA5c5FBbbE5Fa92F7", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x70bC7f7a6D936b289bBF5c0E19ECE35B437E2e36", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0x0Bf40b034872D0b364f3DCec04C7434a4Da1C8d9", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x4FEB11A454C9E8038A8d0aDF599Fe7612ce114bA", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x6bD4754D86fc87FE5b463D368f26a3587a08347c", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x1467fF8f249f5bc604119Af26a47035886f856BE", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Avalanche Mainnet": { + "off_ramp": "0x37a6fa55fe61061Ae97bF7314Ae270eCF71c5ED3", + "commit_store": "0x1f558F6dcf0224Ef1F78A24814FED548B9602c80", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Arbitrum Mainnet": { + "off_ramp": "0x3DA330fd8Ef10d93cFB7D4f8ecE7BC1F10811feC", + "commit_store": "0x86D55Ff492cfBBAf0c0D42D4EE615144E78b3D02", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0x574c697deab06B805D8780898B3F136a1F4892Dc", + "commit_store": "0x002B164b1dcf4E92F352DC625A01Be0E890EdEea", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Ethereum Mainnet": { + "off_ramp": "0x181Bb1E97b0bDD1D85E741ad0943552D3682cc35", + "commit_store": "0x3fF27A34fF0FA77921C3438e67f58da1a83e9Ce1", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Optimism Mainnet": { + "off_ramp": "0xE7E080C8d62d595a223C577C7C8d1f75d9A5E664", + "commit_store": "0xF4d53346bDb6d393C74B0B72Aa7D6689a3eAad79", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Polygon Mainnet": { + "off_ramp": "0x26af2046Da85d7f6712D5edCa81B9E3b2e7A60Ab", + "commit_store": "0x4C1dA405a789AC2853A69D8290B8B9b47a0374F8", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "WeMix Mainnet": { + "off_ramp": "0xC027C5AEb230008c243Be463A73571e581F94c13", + "commit_store": "0x2EB426C8C54D740d1FC856eB3Ff96feA03957978", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "Ethereum Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x514910771AF9Ca656af840dff83E8264EcF986CA", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x8B63b3DE93431C0f756A493644d128134291fA1b", + "router": "0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D", + "price_registry": "0x8c9b2Efb7c64C394119270bfecE7f54763b958Ad", + "wrapped_native": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x925228D7B82d883Dde340A55Fe8e6dA56244A22C", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0x3df8dAe2d123081c4D5E946E655F7c109B9Dd630", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0xe2c2AB221AA0b957805f229d2AA57fBE2f4dADf7", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0x91D25A56Db77aD5147437d8B83Eb563D46eBFa69", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x86B47d8411006874eEf8E4584BdFD7be8e5549d1", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x35F0ca9Be776E4B38659944c257bDd0ba75F1B8B", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0xCbE7e5DA76dC99Ac317adF6d99137005FDA4E2C4", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0xeFC4a18af59398FF23bfe7325F2401aD44286F4d", + "commit_store": "0x9B2EEd6A1e16cB50Ed4c876D2dD69468B21b7749", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Avalanche Mainnet": { + "off_ramp": "0x569940e02D4425eac61A7601632eC00d69f75c17", + "commit_store": "0x2aa101BF99CaeF7fc1355D4c493a1fe187A007cE", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Base Mainnet": { + "off_ramp": "0xdf85c8381954694E74abD07488f452b4c2Cddfb3", + "commit_store": "0x8DC27D621c41a32140e22E2a4dAf1259639BAe04", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "BSC Mainnet": { + "off_ramp": "0x7Afe7088aff57173565F4b034167643AA8b9171c", + "commit_store": "0x87c55D48DF6EF7B08153Ab079e76bFEcbb793D75", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Optimism Mainnet": { + "off_ramp": "0xB095900fB91db00E6abD247A5A5AD1cee3F20BF7", + "commit_store": "0x4af4B497c998007eF83ad130318eB2b925a79dc8", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Polygon Mainnet": { + "off_ramp": "0x0af338F0E314c7551bcE0EF516d46d855b0Ee395", + "commit_store": "0xD37a60E8C36E802D2E1a6321832Ee85556Beeb76", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "WeMix Mainnet": { + "off_ramp": "0x3a129e6C18b23d18BA9E6Aa14Dc2e79d1f91c6c5", + "commit_store": "0x31f6ab382DDeb9A316Ab61C3945a5292a50a89AB", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "Kroma Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xC1F6f7622ad37C3f46cDF6F8AA0344ADE80BF450", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0xB59779d3364BC6d71168245f9ebb96469E5a5a98", + "router": "0xE93E8B0d1b1CEB44350C8758ed1E2799CCee31aB", + "price_registry": "0x8155B4710e7bbC90924E957104F94Afd4f95Eca2", + "wrapped_native": "0x4200000000000000000000000000000000000001", + "src_contracts": { + "WeMix Mainnet": { + "on_ramp": "0x3C5Ab46fA1dB1dECD854224654313a69bf9fcAD3", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "WeMix Mainnet": { + "off_ramp": "0x2B555774B3D1dcbcd76efb7751F3c5FbCFABC5C4", + "commit_store": "0x213124614aAf31eBCE7c612A12aac5f8aAD77DE4", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "Optimism Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x8C7C2C3362a42308BB5c368677Ad321D11693b81", + "router": "0x3206695CaE29952f4b0c22a169725a865bc8Ce0f", + "price_registry": "0xb52545aECE8C73A97E52a146757EC15b90Ed8488", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x0C9BE7Cfd12c735E5aaE047C1dCB845d54E518C3", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0xD0D3E757bFBce7ae1881DDD7F6d798DDcE588445", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x0b1760A8112183303c5526C6b24569fd3A274f3B", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0xa3c9544B82846C45BE37593d5d9ACffbE61BF3A6", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0x55183Db1d2aE0b63e4c92A64bEF2CBfc2032B127", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x6B57145e322c877E7D91Ed8E31266eB5c02F7EfC", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x82e9f4C5ec4a84E310d60D462a12042E5cbA0954", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x0C9BE7Cfd12c735E5aaE047C1dCB845d54E518C3", + "commit_store": "0x55028780918330FD00a34a61D9a7Efd3f43ca845", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Mainnet": { + "off_ramp": "0x8dc6490A6204dF846BaBE809cB695ba17Df1F9B1", + "commit_store": "0xA190660787B6B183Dd82B243eA10e609327c7308", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Base Mainnet": { + "off_ramp": "0xBAE6560eCa9B77Cb047158C783e36F7735C86037", + "commit_store": "0x6168aDF58e1Ad446BaD45c6275Bef60Ef4FFBAb8", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "BSC Mainnet": { + "off_ramp": "0xE14501F2838F2fA1Ceb52E78ABdA289EcE1705EA", + "commit_store": "0xa8DD25B29787527Df283211C24Ac72B17150A696", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Ethereum Mainnet": { + "off_ramp": "0xd2D98Be6a1C241e86C807e51cED6ABb51d044203", + "commit_store": "0x4d75A5cE454b264b187BeE9e189aF1564a68408D", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Polygon Mainnet": { + "off_ramp": "0x7c6221880A1D62506b1A08Dab3Bf695A49AcDD22", + "commit_store": "0x0684076EE3595221861C50cDb9Cb66402Ec11Cb9", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "WeMix Mainnet": { + "off_ramp": "0x3e5B3b7559D39563a74434157b31781322dA712D", + "commit_store": "0x7954372FF6f80908e5A2dC2a19d796A1005f91D2", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "Polygon Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xb0897686c545045aFc77CF20eC7A532E3120E0F1", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0xD7AcF65dA1E1f34b663aB199a474F209bF2b0523", + "router": "0x849c5ED5a80F5B408Dd4969b78c2C8fdf0565Bfe", + "price_registry": "0x30D873664Ba766C983984C7AF9A921ccE36D34e1", + "wrapped_native": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0xD16D025330Edb91259EEA8ed499daCd39087c295", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0x5FA30697e90eB30954895c45b028F7C0dDD39b12", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x20B028A2e0F6CCe3A11f3CE5F2B8986F932e89b4", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0xF5b5A2fC11BF46B1669C3B19d98B19C79109Dca9", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0xFd77c53AA4eF0E3C01f5Ac012BF7Cc7A3ECf5168", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x3111cfbF5e84B5D9BD952dd8e957f4Ca75f728Cf", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x5060eF647a1F66BE6eE27FAe3046faf8D53CeB2d", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0xa8a9eDa2867c2E0CE0d5ECe273961F1EcC3CC25B", + "commit_store": "0xbD4480658dca8496a65046dfD1BDD44EF897Bdb5", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Avalanche Mainnet": { + "off_ramp": "0xB9e3680639c9F0C4e0b02FD81C445094426244Ae", + "commit_store": "0x8c63d4e67f7c4af6FEd2f56A34fB4e01CB807CFF", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Base Mainnet": { + "off_ramp": "0xD0FA7DE2D18A0c59D3fD7dfC7aB4e913C6Aa7b68", + "commit_store": "0xF88053B9DAC8Dd3039a4eFa8639159aaa3F2D4Cb", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "BSC Mainnet": { + "off_ramp": "0x592773924741F0Da889a0dfdab71171Dd11E054C", + "commit_store": "0xEC4d35E1A85f770f4D93BA43a462c9d87Ef7017e", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Ethereum Mainnet": { + "off_ramp": "0x45320085fF051361D301eC1044318213A5387A15", + "commit_store": "0x4Dc771B5ef21ef60c33e2987E092345f2b63aE08", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Optimism Mainnet": { + "off_ramp": "0xBa754ecd3CFA7E9093F688EAc3860cf9D07Fc0AC", + "commit_store": "0x04C0D5302E3D8Ca0A0019141a52a23B59cdb70e4", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "WeMix Mainnet": { + "off_ramp": "0xd7c877ea02310Cce9278D9A048Aa1Bb9aF72F00d", + "commit_store": "0x92A1C927E8E10Ab6A40E5A5154e2300D278d1a67", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "WeMix Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x80f1FcdC96B55e459BF52b998aBBE2c364935d69", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x07aaC8B69A62dB5bd3d244091916EbF2fac17b76", + "router": "0x7798b795Fde864f4Cd1b124a38Ba9619B7F8A442", + "price_registry": "0x252863688762aD86868D3d3076233Eacd80c7055", + "wrapped_native": "0x7D72b22a74A216Af4a002a1095C8C707d6eC1C5f", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x9aBfd6f4C865610692AB6fb1Be862575809fFabf", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0xbE0Cfae74677F8dd16a246a3a5c8cbB1973118f4", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0x56657ec4D15C71f7F3C17ba2b21C853A24Dc5381", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x70f3b0FD7e6a4B9B623e9AB859604A9EE03e48BD", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x777058C1e1dcE4eB8001F38631a1cd9450816e5a", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0x190bcE84CF2d500B878966F4Cf98a50d78f2675E", + "deployed_at": 11111111 + }, + "Kroma Mainnet": { + "on_ramp": "0x47E9AE0A815C94836202E696748A5d5476aD8735", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x2ba68a395B72a6E3498D312efeD755ed2f3CF223", + "commit_store": "0xdAeC234DA83F68707Bb8AcB2ee6a01a5FD4c2391", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Avalanche Mainnet": { + "off_ramp": "0xFac907F9a1087B846Faa75A14C5d34A8639233d8", + "commit_store": "0xF2812063446c7deD2CA306c67A68364BdDcbEfc5", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "BSC Mainnet": { + "off_ramp": "0x6ec9ca4Cba62cA17c55F05ad2000B46192f02035", + "commit_store": "0x84534BE763366a69710E119c100832955795B34B", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Optimism Mainnet": { + "off_ramp": "0x87220D01DF0fF27149B47227897074653788fd23", + "commit_store": "0xF8dD2be2C6FA43e48A17146380CbEBBB4291807b", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Polygon Mainnet": { + "off_ramp": "0x8f0229804513A9Bc00c1308414AB279Dbc718ae1", + "commit_store": "0x3A85D1b8641d83a87957C6ECF1b62151213e0842", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Ethereum Mainnet": { + "off_ramp": "0xF92Fa796F5307b029c65CA26f322a6D86f211194", + "commit_store": "0xbeC110FF43D52be2066B06525304A9924E16b73b", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Kroma Mainnet": { + "off_ramp": "0xF886d8DC64E544af4835cbf91e5678A54D95B80e", + "commit_store": "0x8794C9534658fdCC44f2FF6645Bf31cf9F6d2d5D", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + } + } +} \ No newline at end of file diff --git a/integration-tests/ccip-tests/contracts/laneconfig/contracts.json b/integration-tests/ccip-tests/contracts/laneconfig/contracts.json new file mode 100644 index 0000000000..4d20e2a4d5 --- /dev/null +++ b/integration-tests/ccip-tests/contracts/laneconfig/contracts.json @@ -0,0 +1,243 @@ +{ + "lane_configs": { + "Arbitrum Mainnet": { + "fee_token": "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4", + "bridge_tokens": [ + "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4" + ], + "bridge_tokens_pools": [ + "" + ], + "arm": "0xe06b0e8c4bd455153e8794ad7Ea8Ff5A14B64E4b", + "router": "0xE92634289A1841A979C11C2f618B33D376e4Ba85", + "price_registry": "0xeBec5Cb8651FCD0Fd86Bd1BBb8562f5028D5102E", + "wrapped_native": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "src_contracts": { + "Ethereum Mainnet": { + "on_ramp": "0x98dd9E9b8AE458225119Ab5B8c947A9d1cd0B648", + "deployed_at": 126471491 + } + }, + "dest_contracts": { + "Ethereum Mainnet": { + "off_ramp": "0x7b1f908ceBf41d5829D0134c7dfD6aa0f163C97d", + "commit_store": "0x8E2adA223f8514C2E6E6Fb0877a19018B67256fF", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "Avalanche Mainnet": { + "fee_token": "0x5947BB275c521040051D82396192181b413227A3", + "bridge_tokens": [ + "0x5947BB275c521040051D82396192181b413227A3" + ], + "bridge_tokens_pools": [ + "0x8A3e8D8614189d7ad0CF3f1a0D787Da79eBCEc17" + ], + "arm": "0xdFD6C0dc67666DE3bB36b31eec5c7B1542A82C1E", + "router": "0x27F39D0af3303703750D4001fCc1844c6491563c", + "price_registry": "0x2d3b38E0a4DFFDad2A613f7760bE1683F272eA18", + "wrapped_native": "0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7", + "src_contracts": { + "Ethereum Mainnet": { + "on_ramp": "0x3D3817270db2b89e9F68bA27297fb4672082f942", + "deployed_at": 32263102 + }, + "Polygon Mainnet": { + "on_ramp": "0x2d306510FE83Cdb33Ff1658c71C181e9567F0009", + "deployed_at": 32562460 + } + }, + "dest_contracts": { + "Ethereum Mainnet": { + "off_ramp": "0x2BF2611a07e2cA880b814d53325e9b2ee0BbfD2f", + "commit_store": "0x5eBE880c4d340892dA1b0F32798a7A28e17e6E65", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Polygon Mainnet": { + "off_ramp": "0xC65F15b8178c2Fd653183130C6E003d196C39eC2", + "commit_store": "0xa9DC27fAc318fdDCa08E215ca157Fa5C7A832d80", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "Base Mainnet": { + "fee_token": "0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196", + "arm": "0x38660c8CC222c0192b635c2ac09687B4F25cCE5F", + "router": "0x673AA85efd75080031d44fcA061575d1dA427A28", + "price_registry": "0x1bA15c57c8b74cD32443D7583E7f6d7c638aCf46", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Ethereum Mainnet": { + "on_ramp": "0xD44371bFDe87f2db3eA6Df242091351A06c2e181", + "deployed_at": 3316617 + } + }, + "dest_contracts": { + "Ethereum Mainnet": { + "off_ramp": "0x391B9B016C3bBA61F02e7ddd345130415908B9c7", + "commit_store": "0x398d2164a3F61353B4619814A31cC74A7741612E", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "BSC Mainnet": { + "fee_token": "0x404460C6A5EdE2D891e8297795264fDe62ADBB75", + "bridge_tokens": [ + "0x404460C6A5EdE2D891e8297795264fDe62ADBB75" + ], + "bridge_tokens_pools": [ + "" + ], + "arm": "0x3DB43b96B2625F4232e9Df900d464dd2c64C0021", + "router": "0x536d7E53D0aDeB1F20E7c81fea45d02eC9dBD698", + "price_registry": "0x18C3D917D55Bc1784a3d4729AA3e2C1ecd662fFd", + "wrapped_native": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "src_contracts": { + "Ethereum Mainnet": { + "on_ramp": "0x1f17D464652f5Bd74a03446FeA20590CCfB3332D", + "deployed_at": 31312405 + } + }, + "dest_contracts": { + "Ethereum Mainnet": { + "off_ramp": "0xEcaa7473b57956647C8Cff5a909520e7A0A4a5f6", + "commit_store": "0x9C68a868db2C27E9A7Ce43b73272A5d7ecFB5865", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "Ethereum Mainnet": { + "fee_token": "0x514910771AF9Ca656af840dff83E8264EcF986CA", + "bridge_tokens": [ + "0x514910771AF9Ca656af840dff83E8264EcF986CA" + ], + "bridge_tokens_pools": [ + "0xC2291992A08eBFDfedfE248F2CCD34Da63570DF4" + ], + "arm": "0x8B63b3DE93431C0f756A493644d128134291fA1b", + "router": "0xE561d5E02207fb5eB32cca20a699E0d8919a1476", + "price_registry": "0x020082A7a9c2510e1921116001152DEE4da81985", + "wrapped_native": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x333f976915195ba9044fD0cd603cEcE936f6264e", + "deployed_at": 18029393 + }, + "Avalanche Mainnet": { + "on_ramp": "0xd0B5Fc9790a6085b048b8Aa1ED26ca2b3b282CF2", + "deployed_at": 17636709 + }, + "BSC Mainnet": { + "on_ramp": "0xdF1d7FD22aC3aB5171E275796f123224039f3b24", + "deployed_at": 18029385 + }, + "Base Mainnet": { + "on_ramp": "0xe2Eb229e88F56691e96bb98256707Bc62160FE73", + "deployed_at": 18029431 + }, + "Optimism Mainnet": { + "on_ramp": "0xCC19bC4D43d17eB6859F0d22BA300967C97780b0", + "deployed_at": 17636647 + }, + "Polygon Mainnet": { + "on_ramp": "0x0f27c8532457b66D6037141DEB0ed479Dad04B3c", + "deployed_at": 17636734 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x61135E701a2214C170c5F596D0067798FEfbaaE4", + "commit_store": "0x3d3467e1036Ee25F6F4aa15e3Abf77443A23144C", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Avalanche Mainnet": { + "off_ramp": "0x1C207dabc46902dF9028b27D6d301c3849b2D12c", + "commit_store": "0x40c558575093eC1099CC21B020d9b8D13c74417F", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "BSC Mainnet": { + "off_ramp": "0xC7176620daf49A39a17FF9A6C2DE1eAA6033EE94", + "commit_store": "0x7986C9892389854cAAbAC785ff18123B0070a5Fd", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Base Mainnet": { + "off_ramp": "0xfF51C00546AA3d9051a4B96Ae81346E14709CD24", + "commit_store": "0x2D1708ff2a15adbE313eA8C6035aA24d0FBA1c77", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Optimism Mainnet": { + "off_ramp": "0x41627a90f2c6238f2BADAB72D5aB050B857fdAb5", + "commit_store": "0x8bEFCa744c6f2b567b1863dcF055C593afdC11A0", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Polygon Mainnet": { + "off_ramp": "0xBDd822f3bC2EAB6818CfA3053107831D4E93fE72", + "commit_store": "0x20718EfbC25Dba60FD51c2c81362b83f7C411A6D", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "Optimism Mainnet": { + "fee_token": "0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6", + "bridge_tokens": [ + "0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6" + ], + "bridge_tokens_pools": [ + "0x841b32B5309ba30cFbf4534667fC3D99EdF05B7A" + ], + "arm": "0x8C7C2C3362a42308BB5c368677Ad321D11693b81", + "router": "0x261c05167db67B2b619f9d312e0753f3721ad6E8", + "price_registry": "0x9270AAA75F4B9038f4c25fEc665B02a150a90361", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Ethereum Mainnet": { + "on_ramp": "0xad1b1F2A6DD55627e3893B771A00Cd43F69DcE35", + "deployed_at": 106535110 + } + }, + "dest_contracts": { + "Ethereum Mainnet": { + "off_ramp": "0x032F957BfbB8C535a1b2048f8b4FA27E1F2018Fd", + "commit_store": "0xa4D34ca38244F6c8AB640315d7257221408B6596", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + }, + "Polygon Mainnet": { + "fee_token": "0xb0897686c545045aFc77CF20eC7A532E3120E0F1", + "bridge_tokens": [ + "0xb0897686c545045aFc77CF20eC7A532E3120E0F1" + ], + "bridge_tokens_pools": [ + "0x086892015567fb8764d02c6845C85C25C8FcA389" + ], + "arm": "0xD7AcF65dA1E1f34b663aB199a474F209bF2b0523", + "router": "0x3C3D92629A02a8D95D5CB9650fe49C3544f69B43", + "price_registry": "0x68590799942eed65f9f1fB2277B9F6584A5957B8", + "wrapped_native": "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270", + "src_contracts": { + "Avalanche Mainnet": { + "on_ramp": "0x47D945f7bbb814B65775a89c71F5D2229BE96CE9", + "deployed_at": 45041759 + }, + "Ethereum Mainnet": { + "on_ramp": "0xAE0e486Fa6577188d586A8e4c12360FB82E2a386", + "deployed_at": 44762064 + } + }, + "dest_contracts": { + "Avalanche Mainnet": { + "off_ramp": "0xd59A3770c3e05479152b8581Ae0839f51b315E6A", + "commit_store": "0xC2870bF94E24657f7f5E75cF458e391D23CD84B5", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + }, + "Ethereum Mainnet": { + "off_ramp": "0xa73bf37F78CD1629ff11Fa2B397CED39F49F6efe", + "commit_store": "0x779cA414cAC21c76AbE9213861b1bE9187d495F9", + "receiver_dapp": "0xAFa2c441a83bBCEDc2E8c5c6f66248aFD8b9af3d" + } + } + } + } +} diff --git a/integration-tests/ccip-tests/contracts/laneconfig/parse_contracts.go b/integration-tests/ccip-tests/contracts/laneconfig/parse_contracts.go new file mode 100644 index 0000000000..332bd48ab3 --- /dev/null +++ b/integration-tests/ccip-tests/contracts/laneconfig/parse_contracts.go @@ -0,0 +1,227 @@ +package laneconfig + +import ( + _ "embed" + "encoding/json" + "errors" + "fmt" + "os" + "path/filepath" + "sync" + + "github.com/ethereum/go-ethereum/common" + "go.uber.org/multierr" +) + +var ( + //go:embed contracts.json + ExistingContracts []byte + laneMu = &sync.Mutex{} +) + +type CommonContracts struct { + IsNativeFeeToken bool `json:"is_native_fee_token,omitempty"` + IsMockARM bool `json:"is_mock_arm,omitempty"` + FeeToken string `json:"fee_token"` + BridgeTokens []string `json:"bridge_tokens,omitempty"` + BridgeTokenPools []string `json:"bridge_tokens_pools,omitempty"` + PriceAggregators map[string]string `json:"price_aggregators,omitempty"` + ARM string `json:"arm"` + Router string `json:"router"` + PriceRegistry string `json:"price_registry,omitempty"` + WrappedNative string `json:"wrapped_native"` + Multicall string `json:"multicall,omitempty"` + TokenTransmitter string `json:"token_transmitter,omitempty"` + TokenMessenger string `json:"token_messenger,omitempty"` + TokenAdminRegistry string `json:"token_admin_registry,omitempty"` +} + +type SourceContracts struct { + OnRamp string `json:"on_ramp"` + DeployedAt uint64 `json:"deployed_at"` +} + +type DestContracts struct { + OffRamp string `json:"off_ramp"` + CommitStore string `json:"commit_store"` + ReceiverDapp string `json:"receiver_dapp"` +} + +type LaneConfig struct { + CommonContracts + SrcContractsMu *sync.Mutex `json:"-"` + SrcContracts map[string]SourceContracts `json:"src_contracts"` // key destination chain id + DestContractsMu *sync.Mutex `json:"-"` + DestContracts map[string]DestContracts `json:"dest_contracts"` // key source chain id +} + +func (l *LaneConfig) Validate() error { + var laneConfigError error + + if l.ARM == "" || !common.IsHexAddress(l.ARM) { + laneConfigError = multierr.Append(laneConfigError, errors.New("must set proper address for arm")) + } + + if l.FeeToken != "" && !common.IsHexAddress(l.FeeToken) { + laneConfigError = multierr.Append(laneConfigError, errors.New("must set proper address for fee_token")) + } + + for _, token := range l.BridgeTokens { + if token != "" && !common.IsHexAddress(token) { + laneConfigError = multierr.Append(laneConfigError, errors.New("must set proper address for bridge_tokens")) + } + } + + for _, pool := range l.BridgeTokenPools { + if pool != "" && !common.IsHexAddress(pool) { + laneConfigError = multierr.Append(laneConfigError, errors.New("must set proper address for bridge_tokens_pools")) + } + } + if l.Router == "" || !common.IsHexAddress(l.Router) { + laneConfigError = multierr.Append(laneConfigError, errors.New("must set proper address for router")) + } + if l.PriceRegistry == "" || !common.IsHexAddress(l.PriceRegistry) { + laneConfigError = multierr.Append(laneConfigError, errors.New("must set proper address for price_registry")) + } + if l.WrappedNative == "" || !common.IsHexAddress(l.WrappedNative) { + laneConfigError = multierr.Append(laneConfigError, errors.New("must set proper address for wrapped_native")) + } + if l.Multicall == "" || !common.IsHexAddress(l.Multicall) { + laneConfigError = multierr.Append(laneConfigError, errors.New("must set proper address for multicall")) + } + return laneConfigError +} + +type Lanes struct { + LaneConfigs map[string]*LaneConfig `json:"lane_configs"` +} + +func (l *Lanes) ReadLaneConfig(networkA string) *LaneConfig { + laneMu.Lock() + defer laneMu.Unlock() + cfg, ok := l.LaneConfigs[networkA] + if !ok { + l.LaneConfigs[networkA] = &LaneConfig{ + SrcContracts: make(map[string]SourceContracts), + DestContracts: make(map[string]DestContracts), + SrcContractsMu: &sync.Mutex{}, + DestContractsMu: &sync.Mutex{}, + } + return l.LaneConfigs[networkA] + } + if cfg.SrcContractsMu == nil { + l.LaneConfigs[networkA].SrcContractsMu = &sync.Mutex{} + } + if cfg.DestContractsMu == nil { + l.LaneConfigs[networkA].DestContractsMu = &sync.Mutex{} + } + return l.LaneConfigs[networkA] +} + +// CopyCommonContracts copies network config for common contracts from fromNetwork to toNetwork +// if the toNetwork already exists, it does nothing +// If reuse is set to false, it only retains the token contracts +func (l *Lanes) CopyCommonContracts(fromNetwork, toNetwork string, reuse, isTokenTransfer bool) { + laneMu.Lock() + defer laneMu.Unlock() + // if the toNetwork already exists, return + if _, ok := l.LaneConfigs[toNetwork]; ok { + return + } + existing, ok := l.LaneConfigs[fromNetwork] + if !ok { + l.LaneConfigs[toNetwork] = &LaneConfig{ + SrcContracts: make(map[string]SourceContracts), + DestContracts: make(map[string]DestContracts), + SrcContractsMu: &sync.Mutex{}, + DestContractsMu: &sync.Mutex{}, + } + return + } + cfg := &LaneConfig{ + SrcContracts: make(map[string]SourceContracts), + SrcContractsMu: &sync.Mutex{}, + DestContractsMu: &sync.Mutex{}, + DestContracts: make(map[string]DestContracts), + CommonContracts: CommonContracts{ + WrappedNative: existing.WrappedNative, + Multicall: existing.Multicall, + }, + } + // if reuse is set to true, it copies all the common contracts except the router + if reuse { + cfg.CommonContracts.FeeToken = existing.FeeToken + cfg.CommonContracts.PriceRegistry = existing.PriceRegistry + cfg.CommonContracts.TokenAdminRegistry = existing.TokenAdminRegistry + cfg.CommonContracts.PriceAggregators = existing.PriceAggregators + cfg.CommonContracts.ARM = existing.ARM + cfg.CommonContracts.IsMockARM = existing.IsMockARM + cfg.CommonContracts.Multicall = existing.Multicall + } + // if it is a token transfer, it copies the bridge token contracts + if isTokenTransfer { + cfg.CommonContracts.BridgeTokens = existing.BridgeTokens + if reuse { + cfg.CommonContracts.BridgeTokenPools = existing.BridgeTokenPools + } + } + l.LaneConfigs[toNetwork] = cfg +} + +func (l *Lanes) WriteLaneConfig(networkA string, cfg *LaneConfig) error { + laneMu.Lock() + defer laneMu.Unlock() + if l.LaneConfigs == nil { + l.LaneConfigs = make(map[string]*LaneConfig) + } + err := cfg.Validate() + if err != nil { + return err + } + l.LaneConfigs[networkA] = cfg + return nil +} + +func ReadLanesFromExistingDeployment(contracts []byte) (*Lanes, error) { + // if contracts is empty, use the existing contracts from contracts.json + if len(contracts) == 0 { + contracts = ExistingContracts + } + var lanes Lanes + if err := json.Unmarshal(contracts, &lanes); err != nil { + return nil, err + } + return &lanes, nil +} + +func CreateDeploymentJSON(path string) (*Lanes, error) { + existingLanes := Lanes{ + LaneConfigs: make(map[string]*LaneConfig), + } + err := WriteLanesToJSON(path, &existingLanes) + return &existingLanes, err +} + +func WriteLanesToJSON(path string, lanes *Lanes) error { + b, err := json.MarshalIndent(lanes, "", " ") + if err != nil { + return err + } + // Get the directory part of the file path. + dir := filepath.Dir(path) + // Check if the directory exists. + if _, err := os.Stat(dir); os.IsNotExist(err) { + // The directory does not exist, create it. + if err := os.MkdirAll(dir, 0755); err != nil { + return fmt.Errorf("failed to create directory: %w", err) + } + } + + f, err := os.Create(path) + if err != nil { + return err + } + defer f.Close() + _, err = f.Write(b) + return err +} diff --git a/integration-tests/ccip-tests/contracts/multicall.go b/integration-tests/ccip-tests/contracts/multicall.go new file mode 100644 index 0000000000..7db7f37519 --- /dev/null +++ b/integration-tests/ccip-tests/contracts/multicall.go @@ -0,0 +1,280 @@ +package contracts + +import ( + "context" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/erc20" +) + +const ( + MultiCallABI = "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"returnData\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call3[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call3Value[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3Value\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"blockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBasefee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"basefee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockCoinbase\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"coinbase\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockDifficulty\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"difficulty\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockGasLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gaslimit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getEthBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryAggregate\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryBlockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]" + MultiCallBIN = "0x608060405234801561001057600080fd5b50610ee0806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033" +) + +type CallWithValue struct { + Target common.Address + AllowFailure bool + Value *big.Int + CallData []byte +} + +type Call struct { + Target common.Address + AllowFailure bool + CallData []byte +} + +type Result struct { + Success bool + ReturnData []byte +} +type CCIPMsgData struct { + RouterAddr common.Address + ChainSelector uint64 + Msg router.ClientEVM2AnyMessage + Fee *big.Int +} + +func TransferTokenCallData(to common.Address, amount *big.Int) ([]byte, error) { + erc20ABI, err := abi.JSON(strings.NewReader(erc20.ERC20ABI)) + if err != nil { + return nil, err + } + transferToken := erc20ABI.Methods["transfer"] + inputs, err := transferToken.Inputs.Pack(to, amount) + if err != nil { + return nil, err + } + inputs = append(transferToken.ID[:], inputs...) + return inputs, nil +} + +// ApproveTokenCallData returns the call data for approving a token with approve function of erc20 contract +func ApproveTokenCallData(to common.Address, amount *big.Int) ([]byte, error) { + erc20ABI, err := abi.JSON(strings.NewReader(erc20.ERC20ABI)) + if err != nil { + return nil, err + } + approveToken := erc20ABI.Methods["approve"] + inputs, err := approveToken.Inputs.Pack(to, amount) + if err != nil { + return nil, err + } + inputs = append(approveToken.ID[:], inputs...) + return inputs, nil +} + +// CCIPSendCallData returns the call data for sending a CCIP message with ccipSend function of router contract +func CCIPSendCallData(msg CCIPMsgData) ([]byte, error) { + routerABI, err := abi.JSON(strings.NewReader(router.RouterABI)) + if err != nil { + return nil, err + } + ccipSend := routerABI.Methods["ccipSend"] + sendID := ccipSend.ID + inputs, err := ccipSend.Inputs.Pack( + msg.ChainSelector, + msg.Msg, + ) + if err != nil { + return nil, err + } + inputs = append(sendID[:], inputs...) + return inputs, nil +} + +func WaitForSuccessfulTxMined(evmClient blockchain.EVMClient, tx *types.Transaction) error { + log.Info().Str("tx", tx.Hash().Hex()).Msg("waiting for tx to be mined") + receipt, err := bind.WaitMined(context.Background(), evmClient.DeployBackend(), tx) + if err != nil { + return err + } + if receipt.Status != types.ReceiptStatusSuccessful { + // TODO: Add error reason from receipt/tx + return fmt.Errorf("tx failed %s", tx.Hash().Hex()) + } + log.Info().Str("tx", tx.Hash().Hex()).Str("Network", evmClient.GetNetworkName()).Msg("tx mined successfully") + return nil +} + +// MultiCallCCIP sends multiple CCIP messages in a single transaction +// if native is true, it will send msg with native as fee. In this case the msg should be sent with a +// msg.value equivalent to the total fee with the help of aggregate3Value +// +// if native is false, it will send msg with fee in specific feetoken. In this case the msg should be sent without value with the help of aggregate3. +// In both cases, if there are any bridge tokens included in ccip transfer, the amount for corresponding token should be approved to the router contract as spender. +// The approval should be done by calling approval function as part of the call data of aggregate3 or aggregate3Value +// If feetoken is used as fee, the amount for feetoken should be approved to the router contract as spender and should be done as part of the call data of aggregate3 +// In case of native as fee, there is no need for fee amount approval +func MultiCallCCIP( + evmClient blockchain.EVMClient, + address string, + msgData []CCIPMsgData, + native bool, +) (*types.Transaction, error) { + contractAddress := common.HexToAddress(address) + multiCallABI, err := abi.JSON(strings.NewReader(MultiCallABI)) + if err != nil { + return nil, err + } + boundContract := bind.NewBoundContract(contractAddress, multiCallABI, evmClient.Backend(), evmClient.Backend(), evmClient.Backend()) + + // if native, use aggregate3Value to send msg with value + if native { + var callData []CallWithValue + allValue := big.NewInt(0) + // create call data for each msg + for _, msg := range msgData { + if msg.Msg.FeeToken != (common.Address{}) { + return nil, fmt.Errorf("fee token should be %s for native as fee", common.HexToAddress("0x0").Hex()) + } + // approve bridge token + for _, tokenAndAmount := range msg.Msg.TokenAmounts { + inputs, err := ApproveTokenCallData(msg.RouterAddr, tokenAndAmount.Amount) + if err != nil { + return nil, err + } + data := CallWithValue{Target: tokenAndAmount.Token, AllowFailure: false, Value: big.NewInt(0), CallData: inputs} + callData = append(callData, data) + } + inputs, err := CCIPSendCallData(msg) + if err != nil { + return nil, err + } + data := CallWithValue{Target: msg.RouterAddr, AllowFailure: false, Value: msg.Fee, CallData: inputs} + callData = append(callData, data) + allValue.Add(allValue, msg.Fee) + } + + opts, err := evmClient.TransactionOpts(evmClient.GetDefaultWallet()) + if err != nil { + return nil, err + } + // the value of transactionOpts is the sum of the value of all msg, which is the total fee of all ccip-sends + opts.Value = allValue + + // call aggregate3Value to group all msg call data and send them in a single transaction + tx, err := boundContract.Transact(opts, "aggregate3Value", callData) + if err != nil { + return nil, err + } + err = evmClient.MarkTxAsSentOnL2(tx) + if err != nil { + return nil, err + } + err = WaitForSuccessfulTxMined(evmClient, tx) + if err != nil { + return nil, errors.Wrapf(err, "multicall failed for ccip-send; multicall %s", contractAddress.Hex()) + } + return tx, nil + } + // if with feetoken, use aggregate3 to send msg without value + var callData []Call + // create call data for each msg + for _, msg := range msgData { + isFeeTokenAndBridgeTokenSame := false + // approve bridge token + for _, tokenAndAmount := range msg.Msg.TokenAmounts { + var inputs []byte + // if feetoken is same as bridge token, approve total amount including transfer amount + fee amount + if tokenAndAmount.Token == msg.Msg.FeeToken { + isFeeTokenAndBridgeTokenSame = true + inputs, err = ApproveTokenCallData(msg.RouterAddr, new(big.Int).Add(msg.Fee, tokenAndAmount.Amount)) + if err != nil { + return nil, err + } + } else { + inputs, err = ApproveTokenCallData(msg.RouterAddr, tokenAndAmount.Amount) + if err != nil { + return nil, err + } + } + + callData = append(callData, Call{Target: tokenAndAmount.Token, AllowFailure: false, CallData: inputs}) + } + // approve fee token if not already approved + if msg.Fee != nil && msg.Fee.Cmp(big.NewInt(0)) > 0 && !isFeeTokenAndBridgeTokenSame { + inputs, err := ApproveTokenCallData(msg.RouterAddr, msg.Fee) + if err != nil { + return nil, err + } + callData = append(callData, Call{Target: msg.Msg.FeeToken, AllowFailure: false, CallData: inputs}) + } + + inputs, err := CCIPSendCallData(msg) + if err != nil { + return nil, err + } + callData = append(callData, Call{Target: msg.RouterAddr, AllowFailure: false, CallData: inputs}) + } + opts, err := evmClient.TransactionOpts(evmClient.GetDefaultWallet()) + if err != nil { + return nil, err + } + + // call aggregate3 to group all msg call data and send them in a single transaction + tx, err := boundContract.Transact(opts, "aggregate3", callData) + if err != nil { + return nil, err + } + err = WaitForSuccessfulTxMined(evmClient, tx) + if err != nil { + return tx, errors.Wrapf(err, "multicall failed for ccip-send; router %s", contractAddress.Hex()) + } + return tx, nil +} + +func TransferTokens( + evmClient blockchain.EVMClient, + contractAddress common.Address, + tokens []*ERC20Token, +) error { + multiCallABI, err := abi.JSON(strings.NewReader(MultiCallABI)) + if err != nil { + return err + } + var callData []Call + boundContract := bind.NewBoundContract(contractAddress, multiCallABI, evmClient.Backend(), evmClient.Backend(), evmClient.Backend()) + for _, token := range tokens { + var inputs []byte + balance, err := token.BalanceOf(context.Background(), contractAddress.Hex()) + if err != nil { + return err + } + inputs, err = TransferTokenCallData(common.HexToAddress(evmClient.GetDefaultWallet().Address()), balance) + if err != nil { + return err + } + data := Call{Target: token.ContractAddress, AllowFailure: false, CallData: inputs} + callData = append(callData, data) + } + + opts, err := evmClient.TransactionOpts(evmClient.GetDefaultWallet()) + if err != nil { + return err + } + + // call aggregate3 to group all msg call data and send them in a single transaction + tx, err := boundContract.Transact(opts, "aggregate3", callData) + if err != nil { + return err + } + err = WaitForSuccessfulTxMined(evmClient, tx) + if err != nil { + return errors.Wrapf(err, "token transfer failed for token; router %s", contractAddress.Hex()) + } + return nil +} diff --git a/integration-tests/ccip-tests/load/ccip_loadgen.go b/integration-tests/ccip-tests/load/ccip_loadgen.go new file mode 100644 index 0000000000..4ed54a45fd --- /dev/null +++ b/integration-tests/ccip-tests/load/ccip_loadgen.go @@ -0,0 +1,363 @@ +package load + +import ( + "context" + crypto_rand "crypto/rand" + "encoding/base64" + "fmt" + "math/big" + "strconv" + "testing" + "time" + + "github.com/AlekSi/pointer" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/rs/zerolog" + chain_selectors "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/wasp" + "github.com/stretchr/testify/require" + "go.uber.org/atomic" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" + + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testreporters" +) + +// CCIPLaneOptimized is a light-weight version of CCIPLane, It only contains elements which are used during load triggering and validation +type CCIPLaneOptimized struct { + Logger *zerolog.Logger + SourceNetworkName string + DestNetworkName string + Source *actions.SourceCCIPModule + Dest *actions.DestCCIPModule + Reports *testreporters.CCIPLaneStats +} + +type CCIPE2ELoad struct { + t *testing.T + Lane *CCIPLaneOptimized + NoOfReq int64 // approx no of Request fired + CurrentMsgSerialNo *atomic.Int64 // current msg serial number in the load sequence + CallTimeOut time.Duration // max time to wait for various on-chain events + msg router.ClientEVM2AnyMessage + MaxDataBytes uint32 + SendMaxDataIntermittentlyInMsgCount int64 + SkipRequestIfAnotherRequestTriggeredWithin *config.Duration + LastFinalizedTxBlock atomic.Uint64 + LastFinalizedTimestamp atomic.Time + MsgProfiles *testconfig.MsgProfile + EOAReceiver []byte +} + +func NewCCIPLoad( + t *testing.T, + lane *actions.CCIPLane, + timeout time.Duration, + noOfReq int64, + m *testconfig.MsgProfile, + sendMaxDataIntermittentlyInEveryMsgCount int64, + SkipRequestIfAnotherRequestTriggeredWithin *config.Duration, +) *CCIPE2ELoad { + // to avoid holding extra data + loadLane := &CCIPLaneOptimized{ + Logger: lane.Logger, + SourceNetworkName: lane.SourceNetworkName, + DestNetworkName: lane.DestNetworkName, + Source: lane.Source, + Dest: lane.Dest, + Reports: lane.Reports, + } + + return &CCIPE2ELoad{ + t: t, + Lane: loadLane, + CurrentMsgSerialNo: atomic.NewInt64(1), + CallTimeOut: timeout, + NoOfReq: noOfReq, + SendMaxDataIntermittentlyInMsgCount: sendMaxDataIntermittentlyInEveryMsgCount, + SkipRequestIfAnotherRequestTriggeredWithin: SkipRequestIfAnotherRequestTriggeredWithin, + MsgProfiles: m, + } +} + +// BeforeAllCall funds subscription, approves the token transfer amount. +// Needs to be called before load sequence is started. +// Needs to approve and fund for the entire sequence. +func (c *CCIPE2ELoad) BeforeAllCall() { + sourceCCIP := c.Lane.Source + destCCIP := c.Lane.Dest + + receiver, err := utils.ABIEncode(`[{"type":"address"}]`, destCCIP.ReceiverDapp.EthAddress) + require.NoError(c.t, err, "Failed encoding the receiver address") + c.msg = router.ClientEVM2AnyMessage{ + Receiver: receiver, + FeeToken: common.HexToAddress(sourceCCIP.Common.FeeToken.Address()), + Data: []byte("message with Id 1"), + } + var tokenAndAmounts []router.ClientEVMTokenAmount + if len(c.Lane.Source.Common.BridgeTokens) > 0 { + for i := range c.Lane.Source.TransferAmount { + // if length of sourceCCIP.TransferAmount is more than available bridge token use first bridge token + token := sourceCCIP.Common.BridgeTokens[0] + if i < len(sourceCCIP.Common.BridgeTokens) { + token = sourceCCIP.Common.BridgeTokens[i] + } + tokenAndAmounts = append(tokenAndAmounts, router.ClientEVMTokenAmount{ + Token: common.HexToAddress(token.Address()), Amount: c.Lane.Source.TransferAmount[i], + }) + } + c.msg.TokenAmounts = tokenAndAmounts + } + // we might need to change the receiver to the default wallet of destination based on the gaslimit of msg + // Get the receiver's bytecode to check if it's a contract or EOA + bytecode, err := c.Lane.Dest.Common.ChainClient.Backend().CodeAt(context.Background(), c.Lane.Dest.ReceiverDapp.EthAddress, nil) + require.NoError(c.t, err, "Failed to get bytecode of the receiver contract") + // if the bytecode is empty, it's an EOA, + // In that case save the receiver address as EOA to be used in the message + // Otherwise save destination's default wallet address as EOA + // so that it can be used later for msgs with gaslimit 0 + if len(bytecode) > 0 { + receiver, err := utils.ABIEncode(`[{"type":"address"}]`, common.HexToAddress(c.Lane.Dest.Common.ChainClient.GetDefaultWallet().Address())) + require.NoError(c.t, err, "Failed encoding the receiver address") + c.EOAReceiver = receiver + } else { + c.EOAReceiver = c.msg.Receiver + } + if c.SendMaxDataIntermittentlyInMsgCount > 0 { + c.MaxDataBytes, err = sourceCCIP.OnRamp.Instance.GetDynamicConfig(nil) + require.NoError(c.t, err, "failed to fetch dynamic config") + } + // if the msg is sent via multicall, transfer the token transfer amount to multicall contract + if sourceCCIP.Common.MulticallEnabled && + sourceCCIP.Common.MulticallContract != (common.Address{}) && + len(c.Lane.Source.Common.BridgeTokens) > 0 { + for i, amount := range sourceCCIP.TransferAmount { + // if length of sourceCCIP.TransferAmount is more than available bridge token use first bridge token + token := sourceCCIP.Common.BridgeTokens[0] + if i < len(sourceCCIP.Common.BridgeTokens) { + token = sourceCCIP.Common.BridgeTokens[i] + } + amountToApprove := new(big.Int).Mul(amount, big.NewInt(c.NoOfReq)) + bal, err := token.BalanceOf(context.Background(), sourceCCIP.Common.MulticallContract.Hex()) + require.NoError(c.t, err, "Failed to get token balance") + if bal.Cmp(amountToApprove) < 0 { + err := token.Transfer(token.OwnerWallet, sourceCCIP.Common.MulticallContract.Hex(), amountToApprove) + require.NoError(c.t, err, "Failed to approve token transfer amount") + } + } + } + + c.LastFinalizedTxBlock.Store(c.Lane.Source.NewFinalizedBlockNum.Load()) + c.LastFinalizedTimestamp.Store(c.Lane.Source.NewFinalizedBlockTimestamp.Load()) + + sourceCCIP.Common.ChainClient.ParallelTransactions(false) + destCCIP.Common.ChainClient.ParallelTransactions(false) +} + +func (c *CCIPE2ELoad) CCIPMsg() (router.ClientEVM2AnyMessage, *testreporters.RequestStat, error) { + msgSerialNo := c.CurrentMsgSerialNo.Load() + c.CurrentMsgSerialNo.Inc() + msgDetails := c.MsgProfiles.MsgDetailsForIteration(msgSerialNo) + stats := testreporters.NewCCIPRequestStats(msgSerialNo, c.Lane.SourceNetworkName, c.Lane.DestNetworkName) + // form the message for transfer + msgLength := pointer.GetInt64(msgDetails.DataLength) + gasLimit := pointer.GetInt64(msgDetails.DestGasLimit) + msg := c.msg + if msgLength > 0 && msgDetails.IsDataTransfer() { + if c.SendMaxDataIntermittentlyInMsgCount > 0 { + // every SendMaxDataIntermittentlyInMsgCount message will have extra data with almost MaxDataBytes + if msgSerialNo%c.SendMaxDataIntermittentlyInMsgCount == 0 { + msgLength = int64(c.MaxDataBytes - 1) + } + } + b := make([]byte, msgLength) + _, err := crypto_rand.Read(b) + if err != nil { + return router.ClientEVM2AnyMessage{}, stats, fmt.Errorf("failed to generate random string %w", err) + } + randomString := base64.URLEncoding.EncodeToString(b) + msg.Data = []byte(randomString[:msgLength]) + } + if !msgDetails.IsTokenTransfer() { + msg.TokenAmounts = []router.ClientEVMTokenAmount{} + } + extraArgsV1, err := testhelpers.GetEVMExtraArgsV1(big.NewInt(gasLimit), false) + if err != nil { + return router.ClientEVM2AnyMessage{}, stats, err + } + msg.ExtraArgs = extraArgsV1 + // if gaslimit is 0, set the receiver to EOA + if gasLimit == 0 { + msg.Receiver = c.EOAReceiver + } + return msg, stats, nil +} + +func (c *CCIPE2ELoad) Call(_ *wasp.Generator) *wasp.Response { + res := &wasp.Response{} + sourceCCIP := c.Lane.Source + recentRequestFoundAt := sourceCCIP.IsRequestTriggeredWithinTimeframe(c.SkipRequestIfAnotherRequestTriggeredWithin) + if recentRequestFoundAt != nil { + c.Lane.Logger. + Info(). + Str("Found At=", recentRequestFoundAt.String()). + Msgf("Skipping ...Another Request found within given timeframe %s", c.SkipRequestIfAnotherRequestTriggeredWithin.String()) + return res + } + // if there is an connection error , we will skip sending the request + // this is to avoid sending the request when the connection is not restored yet + if sourceCCIP.Common.IsConnectionRestoredRecently != nil { + if !sourceCCIP.Common.IsConnectionRestoredRecently.Load() { + c.Lane.Logger.Info().Msg("RPC Connection Error.. skipping this request") + res.Failed = true + res.Error = "RPC Connection error .. this request was skipped" + return res + } + c.Lane.Logger.Info().Msg("Connection is restored, Resuming load") + } + msg, stats, err := c.CCIPMsg() + if err != nil { + res.Error = err.Error() + res.Failed = true + return res + } + msgSerialNo := stats.ReqNo + // create a sub-logger for the request + lggr := c.Lane.Logger.With().Int64("msg Number", stats.ReqNo).Logger() + + feeToken := sourceCCIP.Common.FeeToken.EthAddress + // initiate the transfer + lggr.Debug().Str("triggeredAt", time.Now().GoString()).Msg("triggering transfer") + var sendTx *types.Transaction + + destChainSelector, err := chain_selectors.SelectorFromChainId(sourceCCIP.DestinationChainId) + if err != nil { + res.Error = fmt.Sprintf("reqNo %d err %s - while getting selector from chainid", msgSerialNo, err.Error()) + res.Failed = true + return res + } + + // initiate the transfer + // if the token address is 0x0 it will use Native as fee token and the fee amount should be mentioned in bind.TransactOpts's value + fee, err := sourceCCIP.Common.Router.GetFee(destChainSelector, msg) + if err != nil { + res.Error = fmt.Sprintf("reqNo %d err %s - while getting fee from router", msgSerialNo, err.Error()) + res.Failed = true + return res + } + startTime := time.Now().UTC() + if feeToken != common.HexToAddress("0x0") { + sendTx, err = sourceCCIP.Common.Router.CCIPSendAndProcessTx(destChainSelector, msg, nil) + } else { + // add a bit buffer to fee + sendTx, err = sourceCCIP.Common.Router.CCIPSendAndProcessTx(destChainSelector, msg, new(big.Int).Add(big.NewInt(1e5), fee)) + } + if err != nil { + stats.UpdateState(&lggr, 0, testreporters.TX, time.Since(startTime), testreporters.Failure, nil) + res.Error = fmt.Sprintf("ccip-send tx error %s for reqNo %d", err.Error(), msgSerialNo) + res.Data = stats.StatusByPhase + res.Failed = true + return res + } + + // the msg is no longer needed, so we can clear it to avoid holding extra data during load + // nolint:ineffassign,staticcheck + msg = router.ClientEVM2AnyMessage{} + + txConfirmationTime := time.Now().UTC() + lggr = lggr.With().Str("Msg Tx", sendTx.Hash().String()).Logger() + + stats.UpdateState(&lggr, 0, testreporters.TX, txConfirmationTime.Sub(startTime), testreporters.Success, nil) + err = c.Validate(lggr, sendTx, txConfirmationTime, []*testreporters.RequestStat{stats}) + if err != nil { + res.Error = err.Error() + res.Failed = true + res.Data = stats.StatusByPhase + return res + } + res.Data = stats.StatusByPhase + return res +} + +func (c *CCIPE2ELoad) Validate(lggr zerolog.Logger, sendTx *types.Transaction, txConfirmationTime time.Time, stats []*testreporters.RequestStat) error { + // wait for + // - CCIPSendRequested Event log to be generated, + msgLogs, sourceLogTime, err := c.Lane.Source.AssertEventCCIPSendRequested(&lggr, sendTx.Hash().Hex(), c.CallTimeOut, txConfirmationTime, stats) + if err != nil { + return err + } + + lstFinalizedBlock := c.LastFinalizedTxBlock.Load() + var sourceLogFinalizedAt time.Time + // if the finality tag is enabled and the last finalized block is greater than the block number of the message + // consider the message finalized + if c.Lane.Source.Common.ChainClient.GetNetworkConfig().FinalityDepth == 0 && + lstFinalizedBlock != 0 && lstFinalizedBlock > msgLogs[0].LogInfo.BlockNumber { + sourceLogFinalizedAt = c.LastFinalizedTimestamp.Load() + for i, stat := range stats { + stat.UpdateState(&lggr, stat.SeqNum, testreporters.SourceLogFinalized, + sourceLogFinalizedAt.Sub(sourceLogTime), testreporters.Success, + &testreporters.TransactionStats{ + TxHash: msgLogs[i].LogInfo.TxHash.Hex(), + FinalizedByBlock: strconv.FormatUint(lstFinalizedBlock, 10), + FinalizedAt: sourceLogFinalizedAt.String(), + Fee: msgLogs[i].Fee.String(), + NoOfTokensSent: msgLogs[i].NoOfTokens, + MessageBytesLength: int64(msgLogs[i].DataLength), + MsgID: fmt.Sprintf("0x%x", msgLogs[i].MessageId[:]), + }) + } + } else { + var finalizingBlock uint64 + sourceLogFinalizedAt, finalizingBlock, err = c.Lane.Source.AssertSendRequestedLogFinalized( + &lggr, msgLogs[0].LogInfo.TxHash, msgLogs, sourceLogTime, stats) + if err != nil { + return err + } + c.LastFinalizedTxBlock.Store(finalizingBlock) + c.LastFinalizedTimestamp.Store(sourceLogFinalizedAt) + } + + for _, msgLog := range msgLogs { + seqNum := msgLog.SequenceNumber + var reqStat *testreporters.RequestStat + lggr = lggr.With().Str("MsgID", fmt.Sprintf("0x%x", msgLog.MessageId[:])).Logger() + for _, stat := range stats { + if stat.SeqNum == seqNum { + reqStat = stat + break + } + } + if reqStat == nil { + return fmt.Errorf("could not find request stat for seq number %d", seqNum) + } + // wait for + // - CommitStore to increase the seq number, + err = c.Lane.Dest.AssertSeqNumberExecuted(&lggr, seqNum, c.CallTimeOut, sourceLogFinalizedAt, reqStat) + if err != nil { + return err + } + // wait for ReportAccepted event + commitReport, reportAcceptedAt, err := c.Lane.Dest.AssertEventReportAccepted(&lggr, seqNum, c.CallTimeOut, sourceLogFinalizedAt, reqStat) + if err != nil || commitReport == nil { + return err + } + blessedAt, err := c.Lane.Dest.AssertReportBlessed(&lggr, seqNum, c.CallTimeOut, *commitReport, reportAcceptedAt, reqStat) + if err != nil { + return err + } + _, err = c.Lane.Dest.AssertEventExecutionStateChanged(&lggr, seqNum, c.CallTimeOut, blessedAt, reqStat, testhelpers.ExecutionStateSuccess) + if err != nil { + return err + } + } + + return nil +} diff --git a/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go b/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go new file mode 100644 index 0000000000..ad3960dee2 --- /dev/null +++ b/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go @@ -0,0 +1,271 @@ +package load + +import ( + "fmt" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/prometheus/common/model" + "github.com/rs/zerolog" + "golang.org/x/sync/errgroup" + + chain_selectors "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/logging" + + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testreporters" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" +) + +// CCIPMultiCallLoadGenerator represents a load generator for the CCIP lanes originating from same network +// The purpose of this load generator is to group ccip-send calls for the CCIP lanes originating from same network +// This is to avoid the scenario of hitting rpc rate limit for the same network if the load generator is sending +// too many ccip-send calls to the same network hitting the rpc rate limit +type CCIPMultiCallLoadGenerator struct { + t *testing.T + logger zerolog.Logger + client blockchain.EVMClient + E2ELoads map[string]*CCIPE2ELoad + MultiCall string + NoOfRequestsPerUnitTime int64 + labels model.LabelSet + loki *wasp.LokiClient + responses chan map[string]MultiCallReturnValues + Done chan struct{} +} + +type MultiCallReturnValues struct { + Msgs []contracts.CCIPMsgData + Stats []*testreporters.RequestStat +} + +func NewMultiCallLoadGenerator(testCfg *testsetups.CCIPTestConfig, lanes []*actions.CCIPLane, noOfRequestsPerUnitTime int64, labels map[string]string) (*CCIPMultiCallLoadGenerator, error) { + // check if all lanes are from same network + source := lanes[0].Source.Common.ChainClient.GetChainID() + multiCall := lanes[0].Source.Common.MulticallContract.Hex() + if multiCall == "" { + return nil, fmt.Errorf("multicall address cannot be empty") + } + for i := 1; i < len(lanes); i++ { + if source.String() != lanes[i].Source.Common.ChainClient.GetChainID().String() { + return nil, fmt.Errorf("all lanes should be from same network; expected %s, got %s", source, lanes[i].Source.Common.ChainClient.GetChainID()) + } + if lanes[i].Source.Common.MulticallContract.Hex() != multiCall { + return nil, fmt.Errorf("multicall address should be same for all lanes") + } + } + client := lanes[0].Source.Common.ChainClient + lggr := logging.GetTestLogger(testCfg.Test).With().Str("Source Network", client.GetNetworkName()).Logger() + ls := wasp.LabelsMapToModel(labels) + if err := ls.Validate(); err != nil { + return nil, err + } + lokiConfig := testCfg.EnvInput.Logging.Loki + loki, err := wasp.NewLokiClient(wasp.NewLokiConfig(lokiConfig.Endpoint, lokiConfig.TenantId, nil, nil)) + if err != nil { + return nil, err + } + m := &CCIPMultiCallLoadGenerator{ + t: testCfg.Test, + client: client, + MultiCall: multiCall, + logger: lggr, + NoOfRequestsPerUnitTime: noOfRequestsPerUnitTime, + E2ELoads: make(map[string]*CCIPE2ELoad), + labels: ls, + loki: loki, + responses: make(chan map[string]MultiCallReturnValues), + Done: make(chan struct{}), + } + for _, lane := range lanes { + // for multicall load generator, we don't want to send max data intermittently, it might + // cause oversized data for multicall + ccipLoad := NewCCIPLoad( + testCfg.Test, lane, testCfg.TestGroupInput.PhaseTimeout.Duration(), + 100000, + testCfg.TestGroupInput.LoadProfile.MsgProfile, 0, + testCfg.TestGroupInput.LoadProfile.SkipRequestIfAnotherRequestTriggeredWithin, + ) + ccipLoad.BeforeAllCall() + m.E2ELoads[fmt.Sprintf("%s-%s", lane.SourceNetworkName, lane.DestNetworkName)] = ccipLoad + } + + m.StartLokiStream() + return m, nil +} + +func (m *CCIPMultiCallLoadGenerator) Stop() error { + m.Done <- struct{}{} + tokenMap := make(map[string]struct{}) + var tokens []*contracts.ERC20Token + for _, e2eLoad := range m.E2ELoads { + for i := range e2eLoad.Lane.Source.TransferAmount { + // if length of sourceCCIP.TransferAmount is more than available bridge token use first bridge token + token := e2eLoad.Lane.Source.Common.BridgeTokens[0] + if i < len(e2eLoad.Lane.Source.Common.BridgeTokens) { + token = e2eLoad.Lane.Source.Common.BridgeTokens[i] + } + if _, ok := tokenMap[token.Address()]; !ok { + tokens = append(tokens, e2eLoad.Lane.Source.Common.BridgeTokens[i]) + } + } + } + if len(tokens) > 0 { + return contracts.TransferTokens(m.client, common.HexToAddress(m.MultiCall), tokens) + } + return nil +} + +func (m *CCIPMultiCallLoadGenerator) StartLokiStream() { + go func() { + for { + select { + case <-m.Done: + m.logger.Info().Msg("stopping loki client from multi call load generator") + m.loki.Stop() + return + case rValues := <-m.responses: + m.HandleLokiLogs(rValues) + } + } + }() +} + +func (m *CCIPMultiCallLoadGenerator) HandleLokiLogs(rValues map[string]MultiCallReturnValues) { + for dest, rValue := range rValues { + labels := m.labels.Merge(model.LabelSet{ + "dest_chain": model.LabelValue(dest), + "test_data_type": "responses", + "go_test_name": model.LabelValue(m.t.Name()), + }) + for _, stat := range rValue.Stats { + err := m.loki.HandleStruct(labels, time.Now().UTC(), stat.StatusByPhase) + if err != nil { + m.logger.Error().Err(err).Msg("error while handling loki logs") + } + } + } +} + +func (m *CCIPMultiCallLoadGenerator) Call(_ *wasp.Generator) *wasp.Response { + res := &wasp.Response{} + msgs, returnValuesByDest, err := m.MergeCalls() + if err != nil { + res.Error = err.Error() + res.Failed = true + return res + } + defer func() { + m.responses <- returnValuesByDest + }() + m.logger.Info().Interface("msgs", msgs).Msgf("Sending %d ccip-send calls", len(msgs)) + startTime := time.Now().UTC() + // for now we are using all ccip-sends with native + sendTx, err := contracts.MultiCallCCIP(m.client, m.MultiCall, msgs, true) + if err != nil { + res.Error = err.Error() + res.Failed = true + return res + } + + lggr := m.logger.With().Str("Msg Tx", sendTx.Hash().String()).Logger() + txConfirmationTime := time.Now().UTC() + for _, rValues := range returnValuesByDest { + if len(rValues.Stats) != len(rValues.Msgs) { + res.Error = fmt.Sprintf("number of stats %d and msgs %d should be same", len(rValues.Stats), len(rValues.Msgs)) + res.Failed = true + return res + } + for _, stat := range rValues.Stats { + stat.UpdateState(&lggr, 0, testreporters.TX, startTime.Sub(txConfirmationTime), testreporters.Success, nil) + } + } + + validateGrp := errgroup.Group{} + // wait for + // - CCIPSendRequested Event log to be generated, + for _, rValues := range returnValuesByDest { + key := fmt.Sprintf("%s-%s", rValues.Stats[0].SourceNetwork, rValues.Stats[0].DestNetwork) + c, ok := m.E2ELoads[key] + if !ok { + res.Error = fmt.Sprintf("load for %s not found", key) + res.Failed = true + return res + } + + lggr = lggr.With().Str("Source Network", c.Lane.Source.Common.ChainClient.GetNetworkName()).Str("Dest Network", c.Lane.Dest.Common.ChainClient.GetNetworkName()).Logger() + stats := rValues.Stats + txConfirmationTime := txConfirmationTime + sendTx := sendTx + lggr := lggr + validateGrp.Go(func() error { + return c.Validate(lggr, sendTx, txConfirmationTime, stats) + }) + } + err = validateGrp.Wait() + if err != nil { + res.Error = err.Error() + res.Failed = true + return res + } + + return res +} + +func (m *CCIPMultiCallLoadGenerator) MergeCalls() ([]contracts.CCIPMsgData, map[string]MultiCallReturnValues, error) { + var ccipMsgs []contracts.CCIPMsgData + statDetails := make(map[string]MultiCallReturnValues) + + for _, e2eLoad := range m.E2ELoads { + destChainSelector, err := chain_selectors.SelectorFromChainId(e2eLoad.Lane.Source.DestinationChainId) + if err != nil { + return ccipMsgs, statDetails, err + } + + allFee := big.NewInt(0) + var allStatsForDest []*testreporters.RequestStat + var allMsgsForDest []contracts.CCIPMsgData + for i := int64(0); i < m.NoOfRequestsPerUnitTime; i++ { + msg, stats, err := e2eLoad.CCIPMsg() + if err != nil { + return ccipMsgs, statDetails, err + } + msg.FeeToken = common.Address{} + fee, err := e2eLoad.Lane.Source.Common.Router.GetFee(destChainSelector, msg) + if err != nil { + return ccipMsgs, statDetails, err + } + // transfer fee to the multicall address + if msg.FeeToken != (common.Address{}) { + allFee = new(big.Int).Add(allFee, fee) + } + msgData := contracts.CCIPMsgData{ + RouterAddr: e2eLoad.Lane.Source.Common.Router.EthAddress, + ChainSelector: destChainSelector, + Msg: msg, + Fee: fee, + } + ccipMsgs = append(ccipMsgs, msgData) + + allStatsForDest = append(allStatsForDest, stats) + allMsgsForDest = append(allMsgsForDest, msgData) + } + statDetails[e2eLoad.Lane.DestNetworkName] = MultiCallReturnValues{ + Stats: allStatsForDest, + Msgs: allMsgsForDest, + } + // transfer fee to the multicall address + if allFee.Cmp(big.NewInt(0)) > 0 { + if err := e2eLoad.Lane.Source.Common.FeeToken.Transfer(e2eLoad.Lane.Source.Common.MulticallContract.Hex(), allFee); err != nil { + return ccipMsgs, statDetails, err + } + } + } + return ccipMsgs, statDetails, nil +} diff --git a/integration-tests/ccip-tests/load/ccip_test.go b/integration-tests/ccip-tests/load/ccip_test.go new file mode 100644 index 0000000000..0d14549ec9 --- /dev/null +++ b/integration-tests/ccip-tests/load/ccip_test.go @@ -0,0 +1,331 @@ +package load + +import ( + "testing" + "time" + + "github.com/rs/zerolog/log" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-testing-framework/k8s/chaos" + "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" +) + +func TestLoadCCIPStableRPS(t *testing.T) { + t.Parallel() + lggr := logging.GetTestLogger(t) + testArgs := NewLoadArgs(t, lggr) + testArgs.Setup() + // if the test runs on remote runner + if len(testArgs.TestSetupArgs.Lanes) == 0 { + return + } + t.Cleanup(func() { + log.Info().Msg("Tearing down the environment") + require.NoError(t, testArgs.TestSetupArgs.TearDown()) + }) + testArgs.TriggerLoadByLane() + testArgs.Wait() +} + +// TestLoadCCIPWithUpgradeNodeVersion starts all nodes with a specific version, triggers load and then upgrades the node version as the load is running +func TestLoadCCIPWithUpgradeNodeVersion(t *testing.T) { + t.Parallel() + lggr := logging.GetTestLogger(t) + testArgs := NewLoadArgs(t, lggr) + testArgs.Setup() + // if the test runs on remote runner + if len(testArgs.TestSetupArgs.Lanes) == 0 { + return + } + t.Cleanup(func() { + log.Info().Msg("Tearing down the environment") + require.NoError(t, testArgs.TestSetupArgs.TearDown()) + }) + testArgs.TriggerLoadByLane() + testArgs.lggr.Info().Msg("Waiting for load to start on all lanes") + // wait for load runner to start + testArgs.LoadStarterWg.Wait() + // sleep for 30s to let load run for a while + time.Sleep(30 * time.Second) + // upgrade node version for few nodes + err := testsetups.UpgradeNodes(testArgs.t, testArgs.lggr, testArgs.TestCfg, testArgs.TestSetupArgs.Env) + require.NoError(t, err) + // after upgrade send a request to all lanes as a sanity check + testArgs.SanityCheck() + // now wait for the load to finish + testArgs.Wait() +} + +func TestLoadCCIPStableRPSTriggerBySource(t *testing.T) { + t.Parallel() + lggr := logging.GetTestLogger(t) + testArgs := NewLoadArgs(t, lggr) + testArgs.TestCfg.TestGroupInput.MulticallInOneTx = ptr.Ptr(true) + testArgs.Setup() + // if the test runs on remote runner + if len(testArgs.TestSetupArgs.Lanes) == 0 { + return + } + t.Cleanup(func() { + log.Info().Msg("Tearing down the environment") + testArgs.TearDown() + }) + testArgs.TriggerLoadBySource() + testArgs.Wait() +} + +func TestLoadCCIPStableRequestTriggeringWithNetworkChaos(t *testing.T) { + t.Parallel() + lggr := logging.GetTestLogger(t) + testArgs := NewLoadArgs(t, lggr) + testArgs.Setup() + // if the test runs on remote runner + if len(testArgs.TestSetupArgs.Lanes) == 0 { + return + } + t.Cleanup(func() { + log.Info().Msg("Tearing down the environment") + require.NoError(t, testArgs.TestSetupArgs.TearDown()) + }) + testEnv := testArgs.TestSetupArgs.Env + require.NotNil(t, testEnv) + require.NotNil(t, testEnv.K8Env) + + // apply network chaos so that chainlink's RPC calls are affected by some network delay for the duration of the test + var gethNetworksLabels []string + for _, net := range testArgs.TestCfg.SelectedNetworks { + gethNetworksLabels = append(gethNetworksLabels, actions.GethLabel(net.Name)) + } + testEnv.ChaosLabelForAllGeth(t, gethNetworksLabels) + if testArgs.TestCfg.TestGroupInput.LoadProfile.NetworkChaosDelay == nil { + testArgs.TestCfg.TestGroupInput.LoadProfile.NetworkChaosDelay = config.MustNewDuration(200 * time.Millisecond) + } + chaosId, err := testEnv.K8Env.Chaos.Run( + chaos.NewNetworkLatency( + testEnv.K8Env.Cfg.Namespace, &chaos.Props{ + FromLabels: &map[string]*string{"geth": ptr.Ptr(actions.ChaosGroupCCIPGeth)}, + ToLabels: &map[string]*string{"app": ptr.Ptr("chainlink-0")}, + DurationStr: testArgs.TestCfg.TestGroupInput.LoadProfile.TestDuration.String(), + Delay: testArgs.TestCfg.TestGroupInput.LoadProfile.NetworkChaosDelay.Duration().String(), + })) + require.NoError(t, err) + + t.Cleanup(func() { + if chaosId != "" { + require.NoError(t, testEnv.K8Env.Chaos.Stop(chaosId)) + } + }) + + // now trigger the load + testArgs.TriggerLoadByLane() + testArgs.Wait() +} + +// This test applies pod chaos to the CL nodes asynchronously and sequentially while the load is running +// the pod chaos is applied at a regular interval throughout the test duration +// this test needs to be run for a longer duration to see the effects of pod chaos +// in this test commit and execution are set up to be on the same node +func TestLoadCCIPStableWithMajorityNodeFailure(t *testing.T) { + t.Parallel() + + inputs := []ChaosConfig{ + { + ChaosName: "CCIP works after majority of CL nodes are recovered from pod failure @pod-chaos", + ChaosFunc: chaos.NewFailPods, + ChaosProps: &chaos.Props{ + LabelsSelector: &map[string]*string{actions.ChaosGroupCommitFaultyPlus: ptr.Ptr("1")}, + DurationStr: "2m", + }, + }, + } + + lggr := logging.GetTestLogger(t) + testArgs := NewLoadArgs(t, lggr, inputs...) + + var allChaosDur time.Duration + // to override the default duration of chaos with test input + for i := range inputs { + inputs[i].ChaosProps.DurationStr = testArgs.TestCfg.TestGroupInput.ChaosDuration.String() + allChaosDur += testArgs.TestCfg.TestGroupInput.ChaosDuration.Duration() + inputs[i].WaitBetweenChaos = testArgs.TestCfg.TestGroupInput.LoadProfile.WaitBetweenChaosDuringLoad.Duration() + allChaosDur += inputs[i].WaitBetweenChaos + } + + // the duration of load test should be greater than the duration of chaos + if testArgs.TestCfg.TestGroupInput.LoadProfile.TestDuration.Duration() < allChaosDur+2*time.Minute { + t.Fatalf("Skipping the test as the test duration is less than the chaos duration") + } + + testArgs.Setup() + // if the test runs on remote runner + if len(testArgs.TestSetupArgs.Lanes) == 0 { + return + } + t.Cleanup(func() { + log.Info().Msg("Tearing down the environment") + require.NoError(t, testArgs.TestSetupArgs.TearDown()) + }) + + testEnv := testArgs.TestSetupArgs.Env + require.NotNil(t, testEnv) + require.NotNil(t, testEnv.K8Env) + + testArgs.TriggerLoadByLane() + testArgs.ApplyChaos() + testArgs.Wait() +} + +// This test applies pod chaos to the CL nodes asynchronously and sequentially while the load is running +// the pod chaos is applied at a regular interval throughout the test duration +// this test needs to be run for a longer duration to see the effects of pod chaos +// in this test commit and execution are set up to be on the same node +func TestLoadCCIPStableWithMinorityNodeFailure(t *testing.T) { + t.Parallel() + + inputs := []ChaosConfig{ + { + ChaosName: "CCIP works while minority of CL nodes are in failed state for pod failure @pod-chaos", + ChaosFunc: chaos.NewFailPods, + ChaosProps: &chaos.Props{ + LabelsSelector: &map[string]*string{actions.ChaosGroupCommitFaulty: ptr.Ptr("1")}, + DurationStr: "4m", + }, + }, + } + + lggr := logging.GetTestLogger(t) + testArgs := NewLoadArgs(t, lggr, inputs...) + + var allChaosDur time.Duration + // to override the default duration of chaos with test input + for i := range inputs { + inputs[i].ChaosProps.DurationStr = testArgs.TestCfg.TestGroupInput.ChaosDuration.String() + allChaosDur += testArgs.TestCfg.TestGroupInput.ChaosDuration.Duration() + inputs[i].WaitBetweenChaos = testArgs.TestCfg.TestGroupInput.LoadProfile.WaitBetweenChaosDuringLoad.Duration() + allChaosDur += inputs[i].WaitBetweenChaos + } + + // the duration of load test should be greater than the duration of chaos + if testArgs.TestCfg.TestGroupInput.LoadProfile.TestDuration.Duration() < allChaosDur+2*time.Minute { + t.Fatalf("Skipping the test as the test duration is less than the chaos duration") + } + + testArgs.Setup() + // if the test runs on remote runner + if len(testArgs.TestSetupArgs.Lanes) == 0 { + return + } + t.Cleanup(func() { + log.Info().Msg("Tearing down the environment") + require.NoError(t, testArgs.TestSetupArgs.TearDown()) + }) + + testEnv := testArgs.TestSetupArgs.Env + require.NotNil(t, testEnv) + require.NotNil(t, testEnv.K8Env) + + testArgs.TriggerLoadByLane() + testArgs.ApplyChaos() + testArgs.Wait() +} + +// This test applies pod chaos to the CL nodes asynchronously and sequentially while the load is running +// the pod chaos is applied at a regular interval throughout the test duration +// in this test commit and execution are set up to be on different node +func TestLoadCCIPStableWithPodChaosDiffCommitAndExec(t *testing.T) { + t.Parallel() + inputs := []ChaosConfig{ + { + ChaosName: "CCIP Commit works after majority of CL nodes are recovered from pod failure @pod-chaos", + ChaosFunc: chaos.NewFailPods, + ChaosProps: &chaos.Props{ + LabelsSelector: &map[string]*string{actions.ChaosGroupCommitFaultyPlus: ptr.Ptr("1")}, + DurationStr: "2m", + }, + }, + { + ChaosName: "CCIP Execution works after majority of CL nodes are recovered from pod failure @pod-chaos", + ChaosFunc: chaos.NewFailPods, + ChaosProps: &chaos.Props{ + LabelsSelector: &map[string]*string{actions.ChaosGroupExecutionFaultyPlus: ptr.Ptr("1")}, + DurationStr: "2m", + }, + }, + { + ChaosName: "CCIP Commit works while minority of CL nodes are in failed state for pod failure @pod-chaos", + ChaosFunc: chaos.NewFailPods, + ChaosProps: &chaos.Props{ + LabelsSelector: &map[string]*string{actions.ChaosGroupCommitFaulty: ptr.Ptr("1")}, + DurationStr: "4m", + }, + }, + { + ChaosName: "CCIP Execution works while minority of CL nodes are in failed state for pod failure @pod-chaos", + ChaosFunc: chaos.NewFailPods, + ChaosProps: &chaos.Props{ + LabelsSelector: &map[string]*string{actions.ChaosGroupExecutionFaulty: ptr.Ptr("1")}, + DurationStr: "4m", + }, + }, + } + for _, in := range inputs { + in := in + t.Run(in.ChaosName, func(t *testing.T) { + t.Parallel() + lggr := logging.GetTestLogger(t) + testArgs := NewLoadArgs(t, lggr, in) + testArgs.TestCfg.TestGroupInput.LoadProfile.TestDuration = config.MustNewDuration(5 * time.Minute) + testArgs.TestCfg.TestGroupInput.LoadProfile.TimeUnit = config.MustNewDuration(1 * time.Second) + testArgs.TestCfg.TestGroupInput.LoadProfile.RequestPerUnitTime = []int64{2} + testArgs.TestCfg.TestGroupInput.PhaseTimeout = config.MustNewDuration(15 * time.Minute) + + testArgs.Setup() + // if the test runs on remote runner + if len(testArgs.TestSetupArgs.Lanes) == 0 { + return + } + t.Cleanup(func() { + log.Info().Msg("Tearing down the environment") + require.NoError(t, testArgs.TestSetupArgs.TearDown()) + }) + testArgs.SanityCheck() + testArgs.TriggerLoadByLane() + testArgs.ApplyChaos() + testArgs.Wait() + }) + } +} + +// TestLoadCCIPStableRPSAfterARMCurseAndUncurse validates that after ARM curse is lifted +// all pending requests get delivered. +// The test pauses loadgen while ARM is cursed and resumes it when curse is lifted. +// There is a known limitation of this test - if the test is run on remote-runner with high frequency +// the remote-runner pod gets evicted after the loadgen is resumed. +// The recommended frequency for this test 2req/min +func TestLoadCCIPStableRPSAfterARMCurseAndUncurse(t *testing.T) { + t.Skipf("need to be enabled as part of CCIP-2277") + t.Parallel() + lggr := logging.GetTestLogger(t) + testArgs := NewLoadArgs(t, lggr) + testArgs.Setup() + // if the test runs on remote runner + if len(testArgs.TestSetupArgs.Lanes) == 0 { + return + } + t.Cleanup(func() { + log.Info().Msg("Tearing down the environment") + require.NoError(t, testArgs.TestSetupArgs.TearDown()) + }) + testArgs.TriggerLoadByLane() + // wait for certain time so that few messages are sent + time.Sleep(2 * time.Minute) + // now validate the curse + testArgs.ValidateCurseFollowedByUncurse() + testArgs.Wait() +} diff --git a/integration-tests/ccip-tests/load/helper.go b/integration-tests/ccip-tests/load/helper.go new file mode 100644 index 0000000000..9522a6c346 --- /dev/null +++ b/integration-tests/ccip-tests/load/helper.go @@ -0,0 +1,483 @@ +package load + +import ( + "context" + "fmt" + "math" + "math/big" + "strings" + "sync" + "testing" + "time" + + "github.com/AlekSi/pointer" + "github.com/rs/zerolog" + "github.com/smartcontractkit/wasp" + "github.com/stretchr/testify/require" + "go.uber.org/atomic" + "golang.org/x/sync/errgroup" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + + "github.com/smartcontractkit/chainlink-testing-framework/k8s/chaos" + "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" +) + +type ChaosConfig struct { + ChaosName string + ChaosFunc chaos.ManifestFunc + ChaosProps *chaos.Props + WaitBetweenChaos time.Duration +} + +// WaspSchedule calculates the load schedule based on the provided request per unit time and duration +// if multiple step durations are provided, it will calculate the schedule based on the step duration and +// corresponding request per unit time by matching the index of the request per unit time and step duration slice +func WaspSchedule(rps []int64, duration *config.Duration, steps []*config.Duration) []*wasp.Segment { + var segments []*wasp.Segment + var segmentDuration time.Duration + + if len(rps) > 1 { + for i, req := range rps { + duration := steps[i].Duration() + segmentDuration += duration + segments = append(segments, wasp.Plain(req, duration)...) + } + totalDuration := duration.Duration() + repeatTimes := totalDuration.Seconds() / segmentDuration.Seconds() + return wasp.CombineAndRepeat(int(math.Round(repeatTimes)), segments) + } + return wasp.Plain(rps[0], duration.Duration()) +} + +type LoadArgs struct { + t *testing.T + Ctx context.Context + lggr *zerolog.Logger + RunnerWg *errgroup.Group // to wait on individual load generators run + LoadStarterWg *sync.WaitGroup // waits for all the runners to start + TestCfg *testsetups.CCIPTestConfig + TestSetupArgs *testsetups.CCIPTestSetUpOutputs + ChaosExps []ChaosConfig + LoadgenTearDowns []func() + Labels map[string]string + pauseLoad *atomic.Bool +} + +func (l *LoadArgs) SetReportParams() { + var qParams []string + for k, v := range l.Labels { + qParams = append(qParams, fmt.Sprintf("var-%s=%s", k, v)) + } + // add one of the source and destination network to the grafana query params + if len(l.TestSetupArgs.Lanes) > 0 { + qParams = append(qParams, fmt.Sprintf("var-source_chain=%s", l.TestSetupArgs.Lanes[0].ForwardLane.SourceNetworkName)) + qParams = append(qParams, fmt.Sprintf("var-dest_chain=%s", l.TestSetupArgs.Lanes[0].ForwardLane.DestNetworkName)) + } + err := l.TestSetupArgs.Reporter.AddToGrafanaDashboardQueryParams(qParams...) + require.NoError(l.t, err, "failed to set grafana query params") +} + +func (l *LoadArgs) Setup() { + lggr := l.lggr + existing := pointer.GetBool(l.TestCfg.TestGroupInput.ExistingDeployment) + envName := "load-ccip" + if existing { + envName = "ccip-runner" + } + l.TestSetupArgs = testsetups.CCIPDefaultTestSetUp(l.TestCfg.Test, lggr, envName, nil, l.TestCfg) + namespace := l.TestCfg.TestGroupInput.LoadProfile.TestRunName + if l.TestSetupArgs.Env != nil && l.TestSetupArgs.Env.K8Env != nil && l.TestSetupArgs.Env.K8Env.Cfg != nil { + namespace = l.TestSetupArgs.Env.K8Env.Cfg.Namespace + } + l.Labels = map[string]string{ + "test_group": "load", + "test_id": "ccip", + "namespace": namespace, + } + l.TestSetupArgs.Reporter.SetGrafanaURLProvider(l.TestCfg.EnvInput) + l.SetReportParams() +} + +func (l *LoadArgs) scheduleForDest(destNetworkName string) []*wasp.Segment { + require.Greater(l.t, len(l.TestCfg.TestGroupInput.LoadProfile.RequestPerUnitTime), 0, "RequestPerUnitTime must be set") + // try to locate if there is a frequency provided for the destination network + // to locate the frequency, we check if the destination network name contains the network name in the frequency map + // if found, use that frequency for the destination network + // otherwise, use the default frequency + if l.TestCfg.TestGroupInput.LoadProfile.FrequencyByDestination != nil { + for networkName, freq := range l.TestCfg.TestGroupInput.LoadProfile.FrequencyByDestination { + if strings.Contains(destNetworkName, networkName) { + return WaspSchedule( + freq.RequestPerUnitTime, + l.TestCfg.TestGroupInput.LoadProfile.TestDuration, + freq.StepDuration) + } + } + } + + return WaspSchedule( + l.TestCfg.TestGroupInput.LoadProfile.RequestPerUnitTime, + l.TestCfg.TestGroupInput.LoadProfile.TestDuration, + l.TestCfg.TestGroupInput.LoadProfile.StepDuration) +} + +func (l *LoadArgs) SanityCheck() { + var allLanes []*actions.CCIPLane + for _, lane := range l.TestSetupArgs.Lanes { + allLanes = append(allLanes, lane.ForwardLane) + if lane.ReverseLane != nil { + allLanes = append(allLanes, lane.ReverseLane) + } + } + for _, lane := range allLanes { + ccipLoad := NewCCIPLoad( + l.TestCfg.Test, lane, + l.TestCfg.TestGroupInput.PhaseTimeout.Duration(), + 1, l.TestCfg.TestGroupInput.LoadProfile.MsgProfile, + 0, nil, + ) + ccipLoad.BeforeAllCall() + resp := ccipLoad.Call(nil) + require.False(l.t, resp.Failed, "request failed in sanity check") + } +} + +// ValidateCurseFollowedByUncurse assumes the lanes under test are bi-directional. +// It assumes requests in both direction are in flight when this is called. +// It assumes the ARM is not already cursed, it will fail the test if it is in cursed state. +// It curses source ARM for forward lanes so that destination curse is also validated for reverse lanes. +// It waits for 2 minutes for curse to be seen by ccip plugins and contracts. +// It captures the curse timestamp to verify no execution state changed event is emitted after the cure is applied. +// It uncurses the source ARM at the end so that it can be verified that rest of the requests are processed as expected. +// Validates that even after uncursing the lane should not function for 30 more minutes. +func (l *LoadArgs) ValidateCurseFollowedByUncurse() { + var lanes []*actions.CCIPLane + for _, lane := range l.TestSetupArgs.Lanes { + lanes = append(lanes, lane.ForwardLane) + } + // check if source is already cursed + for _, lane := range lanes { + cursed, err := lane.Source.Common.IsCursed() + require.NoError(l.t, err, "cannot get cursed state") + if cursed { + require.Fail(l.t, "test will not work if ARM is already cursed") + } + } + // before cursing set pause + l.pauseLoad.Store(true) + // wait for some time for pause to be active in wasp + l.lggr.Info().Msg("Waiting for 1 minute after applying pause on load") + time.Sleep(1 * time.Minute) + curseTimeStamps := make(map[string]time.Time) + for _, lane := range lanes { + if _, exists := curseTimeStamps[lane.SourceNetworkName]; exists { + continue + } + curseTx, err := lane.Source.Common.CurseARM() + require.NoError(l.t, err, "error in cursing arm") + require.NotNil(l.t, curseTx, "invalid cursetx") + receipt, err := lane.Source.Common.ChainClient.GetTxReceipt(curseTx.Hash()) + require.NoError(l.t, err) + hdr, err := lane.Source.Common.ChainClient.HeaderByNumber(context.Background(), receipt.BlockNumber) + require.NoError(l.t, err) + curseTimeStamps[lane.SourceNetworkName] = hdr.Timestamp + l.lggr.Info().Str("Source", lane.SourceNetworkName).Msg("Curse is applied on source") + l.lggr.Info().Str("Destination", lane.SourceNetworkName).Msg("Curse is applied on destination") + } + + l.lggr.Info().Msg("Curse is applied on all lanes. Waiting for 2 minutes") + time.Sleep(2 * time.Minute) + + for _, lane := range lanes { + // try to send requests on lanes on which curse is applied on source RMN and the request should revert + // data-only transfer is sufficient + lane.Source.TransferAmount = []*big.Int{} + failedTx, _, _, err := lane.Source.SendRequest( + lane.Dest.ReceiverDapp.EthAddress, + big.NewInt(actions.DefaultDestinationGasLimit), // gas limit + ) + if lane.Source.Common.ChainClient.GetNetworkConfig().MinimumConfirmations > 0 { + require.Error(l.t, err) + } else { + require.NoError(l.t, err) + } + errReason, v, err := lane.Source.Common.ChainClient.RevertReasonFromTx(failedTx, router.RouterABI) + require.NoError(l.t, err) + require.Equal(l.t, "BadARMSignal", errReason) + lane.Logger.Info(). + Str("Revert Reason", errReason). + Interface("Args", v). + Str("FailedTx", failedTx.Hex()). + Msg("Msg sent while source ARM is cursed") + } + + // now uncurse all + for _, lane := range lanes { + require.NoError(l.t, lane.Source.Common.UnvoteToCurseARM(), "error to unvote in cursing arm") + } + l.lggr.Info().Msg("Curse is lifted on all lanes") + // lift the pause on load test + l.pauseLoad.Store(false) + + // now add the reverse lanes so that destination curse is also verified + // we add the reverse lanes now to verify absence of commit and execution for the reverse lanes + for _, lane := range l.TestSetupArgs.Lanes { + lanes = append(lanes, lane.ReverseLane) + } + + // verify that even after uncursing the lane should not function for 30 more minutes, + // i.e no execution state changed or commit report accepted event is generated + errGrp := &errgroup.Group{} + for _, lane := range lanes { + lane := lane + curseTimeStamp, exists := curseTimeStamps[lane.SourceNetworkName] + // if curse timestamp does not exist for source, it will exist for destination + if !exists { + curseTimeStamp, exists = curseTimeStamps[lane.DestNetworkName] + require.Truef(l.t, exists, "did not find curse time stamp for lane %s->%s", lane.SourceNetworkName, lane.DestNetworkName) + } + errGrp.Go(func() error { + lane.Logger.Info().Msg("Validating no CommitReportAccepted event is received for 29 minutes") + // we allow additional 1 minute after curse timestamp for curse to be visible by plugin + return lane.Dest.AssertNoReportAcceptedEventReceived(lane.Logger, 25*time.Minute, curseTimeStamp.Add(1*time.Minute)) + }) + errGrp.Go(func() error { + lane.Logger.Info().Msg("Validating no ExecutionStateChanged event is received for 25 minutes") + // we allow additional 1 minute after curse timestamp for curse to be visible by plugin + return lane.Dest.AssertNoExecutionStateChangedEventReceived(lane.Logger, 25*time.Minute, curseTimeStamp.Add(1*time.Minute)) + }) + } + l.lggr.Info().Msg("waiting for no commit/execution validation") + err := errGrp.Wait() + require.NoError(l.t, err, "error received to validate no commit/execution is generated after lane is cursed") +} + +func (l *LoadArgs) TriggerLoadByLane() { + l.TestSetupArgs.Reporter.SetDuration(l.TestCfg.TestGroupInput.LoadProfile.TestDuration.Duration()) + + // start load for a lane + startLoad := func(lane *actions.CCIPLane) { + lane.Logger.Info(). + Str("Source Network", lane.SourceNetworkName). + Str("Destination Network", lane.DestNetworkName). + Msg("Starting load for lane") + sendMaxData := pointer.GetInt64(l.TestCfg.TestGroupInput.LoadProfile.SendMaxDataInEveryMsgCount) + ccipLoad := NewCCIPLoad( + l.TestCfg.Test, lane, l.TestCfg.TestGroupInput.PhaseTimeout.Duration(), + 100000, l.TestCfg.TestGroupInput.LoadProfile.MsgProfile, sendMaxData, + l.TestCfg.TestGroupInput.LoadProfile.SkipRequestIfAnotherRequestTriggeredWithin, + ) + ccipLoad.BeforeAllCall() + // if it's not multicall set the tokens to nil to free up some space, + // we have already formed the msg to be sent in load, there is no need to store the bridge tokens anymore + // In case of multicall we still need the BridgeTokens to transfer amount from mutlicall to owner + if !lane.Source.Common.MulticallEnabled { + lane.Source.Common.BridgeTokens = nil + lane.Dest.Common.BridgeTokens = nil + } + // no need for price registry in load + lane.Source.Common.PriceRegistry = nil + lane.Dest.Common.PriceRegistry = nil + lokiConfig := l.TestCfg.EnvInput.Logging.Loki + labels := make(map[string]string) + for k, v := range l.Labels { + labels[k] = v + } + labels["source_chain"] = lane.SourceNetworkName + labels["dest_chain"] = lane.DestNetworkName + waspCfg := &wasp.Config{ + T: l.TestCfg.Test, + GenName: fmt.Sprintf("lane %s-> %s", lane.SourceNetworkName, lane.DestNetworkName), + Schedule: l.scheduleForDest(lane.DestNetworkName), + LoadType: wasp.RPS, + RateLimitUnitDuration: l.TestCfg.TestGroupInput.LoadProfile.TimeUnit.Duration(), + CallResultBufLen: 10, // we keep the last 10 call results for each generator, as the detailed report is generated at the end of the test + CallTimeout: (l.TestCfg.TestGroupInput.PhaseTimeout.Duration()) * 5, + Gun: ccipLoad, + Logger: *ccipLoad.Lane.Logger, + LokiConfig: wasp.NewLokiConfig(lokiConfig.Endpoint, lokiConfig.TenantId, nil, nil), + Labels: labels, + FailOnErr: pointer.GetBool(l.TestCfg.TestGroupInput.LoadProfile.FailOnFirstErrorInLoad), + } + waspCfg.LokiConfig.Timeout = time.Minute + loadRunner, err := wasp.NewGenerator(waspCfg) + require.NoError(l.TestCfg.Test, err, "initiating loadgen for lane %s --> %s", + lane.SourceNetworkName, lane.DestNetworkName) + loadRunner.Run(false) + l.AddToRunnerGroup(loadRunner) + } + + for _, lane := range l.TestSetupArgs.Lanes { + lane := lane + l.LoadStarterWg.Add(1) + go func() { + defer l.LoadStarterWg.Done() + startLoad(lane.ForwardLane) + }() + if pointer.GetBool(l.TestSetupArgs.Cfg.TestGroupInput.BiDirectionalLane) { + l.LoadStarterWg.Add(1) + go func() { + defer l.LoadStarterWg.Done() + startLoad(lane.ReverseLane) + }() + } + } +} + +func (l *LoadArgs) AddToRunnerGroup(gen *wasp.Generator) { + // watch for pause signal + go func(gen *wasp.Generator) { + ticker := time.NewTicker(time.Second) + pausedOnce := false + resumedAlready := false + for { + select { + case <-ticker.C: + if l.pauseLoad.Load() && !pausedOnce { + gen.Pause() + pausedOnce = true + continue + } + if pausedOnce && !resumedAlready && !l.pauseLoad.Load() { + gen.Resume() + resumedAlready = true + } + case <-l.Ctx.Done(): + return + } + } + }(gen) + l.RunnerWg.Go(func() error { + _, failed := gen.Wait() + if failed { + return fmt.Errorf("load run is failed") + } + if len(gen.Errors()) > 0 { + return fmt.Errorf("error in load sequence call %v", gen.Errors()) + } + return nil + }) +} + +func (l *LoadArgs) Wait() { + l.lggr.Info().Msg("Waiting for load to start on all lanes") + // wait for load runner to start + l.LoadStarterWg.Wait() + l.lggr.Info().Msg("Waiting for load to finish on all lanes") + // wait for load runner to finish + err := l.RunnerWg.Wait() + require.NoError(l.t, err, "load run is failed") + l.lggr.Info().Msg("Load finished on all lanes") +} + +func (l *LoadArgs) ApplyChaos() { + testEnv := l.TestSetupArgs.Env + if testEnv == nil || testEnv.K8Env == nil { + l.lggr.Warn().Msg("test environment is nil, skipping chaos") + return + } + testEnv.ChaosLabelForCLNodes(l.TestCfg.Test) + + for _, exp := range l.ChaosExps { + if exp.WaitBetweenChaos > 0 { + l.lggr.Info().Msgf("sleeping for %s after chaos %s", exp.WaitBetweenChaos, exp.ChaosName) + time.Sleep(exp.WaitBetweenChaos) + } + l.lggr.Info().Msgf("Starting to apply chaos %s at %s", exp.ChaosName, time.Now().UTC()) + // apply chaos + chaosId, err := testEnv.K8Env.Chaos.Run(exp.ChaosFunc(testEnv.K8Env.Cfg.Namespace, exp.ChaosProps)) + require.NoError(l.t, err) + if chaosId != "" { + chaosDur, err := time.ParseDuration(exp.ChaosProps.DurationStr) + require.NoError(l.t, err) + err = testEnv.K8Env.Chaos.WaitForAllRecovered(chaosId, chaosDur+1*time.Minute) + require.NoError(l.t, err) + l.lggr.Info().Msgf("chaos %s is recovered at %s", exp.ChaosName, time.Now().UTC()) + err = testEnv.K8Env.Chaos.Stop(chaosId) + require.NoError(l.t, err) + l.lggr.Info().Msgf("stopped chaos %s at %s", exp.ChaosName, time.Now().UTC()) + } + } +} + +func (l *LoadArgs) TearDown() { + for _, tearDn := range l.LoadgenTearDowns { + tearDn() + } + if l.TestSetupArgs.TearDown != nil { + require.NoError(l.t, l.TestSetupArgs.TearDown()) + } +} + +func (l *LoadArgs) TriggerLoadBySource() { + require.NotNil(l.t, l.TestCfg.TestGroupInput.LoadProfile.TestDuration, "test duration input is nil") + require.GreaterOrEqual(l.t, 1, len(l.TestCfg.TestGroupInput.LoadProfile.RequestPerUnitTime), "time unit input must be specified") + l.TestSetupArgs.Reporter.SetDuration(l.TestCfg.TestGroupInput.LoadProfile.TestDuration.Duration()) + var laneBySource = make(map[string][]*actions.CCIPLane) + for _, lane := range l.TestSetupArgs.Lanes { + laneBySource[lane.ForwardLane.SourceNetworkName] = append(laneBySource[lane.ForwardLane.SourceNetworkName], lane.ForwardLane) + if lane.ReverseLane != nil { + laneBySource[lane.ReverseLane.SourceNetworkName] = append(laneBySource[lane.ReverseLane.SourceNetworkName], lane.ReverseLane) + } + } + for source, lanes := range laneBySource { + source := source + lanes := lanes + l.LoadStarterWg.Add(1) + go func() { + defer l.LoadStarterWg.Done() + l.lggr.Info(). + Str("Source Network", source). + Msg("Starting load for source") + allLabels := make(map[string]string) + for k, v := range l.Labels { + allLabels[k] = v + } + allLabels["source_chain"] = source + multiCallGen, err := NewMultiCallLoadGenerator(l.TestCfg, lanes, l.TestCfg.TestGroupInput.LoadProfile.RequestPerUnitTime[0], allLabels) + require.NoError(l.t, err) + lokiConfig := l.TestCfg.EnvInput.Logging.Loki + loadRunner, err := wasp.NewGenerator(&wasp.Config{ + T: l.TestCfg.Test, + GenName: fmt.Sprintf("Source %s", source), + Schedule: wasp.Plain(1, l.TestCfg.TestGroupInput.LoadProfile.TestDuration.Duration()), // hardcoded request per unit time to 1 as we are using multiCallGen + LoadType: wasp.RPS, + RateLimitUnitDuration: l.TestCfg.TestGroupInput.LoadProfile.TimeUnit.Duration(), + CallResultBufLen: 10, // we keep the last 10 call results for each generator, as the detailed report is generated at the end of the test + CallTimeout: (l.TestCfg.TestGroupInput.PhaseTimeout.Duration()) * 5, + Gun: multiCallGen, + Logger: multiCallGen.logger, + LokiConfig: wasp.NewLokiConfig(lokiConfig.Endpoint, lokiConfig.TenantId, nil, nil), + Labels: allLabels, + FailOnErr: pointer.GetBool(l.TestCfg.TestGroupInput.LoadProfile.FailOnFirstErrorInLoad), + }) + require.NoError(l.TestCfg.Test, err, "initiating loadgen for source %s", source) + loadRunner.Run(false) + l.AddToRunnerGroup(loadRunner) + l.LoadgenTearDowns = append(l.LoadgenTearDowns, func() { + require.NoError(l.t, multiCallGen.Stop()) + }) + }() + } +} + +func NewLoadArgs(t *testing.T, lggr zerolog.Logger, chaosExps ...ChaosConfig) *LoadArgs { + wg, _ := errgroup.WithContext(testcontext.Get(t)) + ctx := testcontext.Get(t) + return &LoadArgs{ + t: t, + Ctx: ctx, + lggr: &lggr, + RunnerWg: wg, + TestCfg: testsetups.NewCCIPTestConfig(t, lggr, testconfig.Load), + ChaosExps: chaosExps, + LoadStarterWg: &sync.WaitGroup{}, + pauseLoad: atomic.NewBool(false), + } +} diff --git a/integration-tests/ccip-tests/smoke/ccip_test.go b/integration-tests/ccip-tests/smoke/ccip_test.go new file mode 100644 index 0000000000..9a34044a5d --- /dev/null +++ b/integration-tests/ccip-tests/smoke/ccip_test.go @@ -0,0 +1,1008 @@ +package smoke + +import ( + "fmt" + "math/big" + "testing" + "time" + + "github.com/AlekSi/pointer" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_pool" + + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testreporters" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" +) + +type testDefinition struct { + testName string + lane *actions.CCIPLane +} + +func TestSmokeCCIPForBidirectionalLane(t *testing.T) { + t.Parallel() + log := logging.GetTestLogger(t) + TestCfg := testsetups.NewCCIPTestConfig(t, log, testconfig.Smoke) + require.NotNil(t, TestCfg.TestGroupInput.MsgDetails.DestGasLimit) + gasLimit := big.NewInt(*TestCfg.TestGroupInput.MsgDetails.DestGasLimit) + setUpOutput := testsetups.CCIPDefaultTestSetUp(t, &log, "smoke-ccip", nil, TestCfg) + if len(setUpOutput.Lanes) == 0 { + log.Info().Msg("No lanes found") + return + } + + t.Cleanup(func() { + // If we are running a test that is a token transfer, we need to verify the balance. + // skip the balance check for existing deployment, there can be multiple external requests in progress for existing deployments + // other than token transfer initiated by the test, which can affect the balance check + // therefore we check the balance only for the ccip environment created by the test + if TestCfg.TestGroupInput.MsgDetails.IsTokenTransfer() && + !pointer.GetBool(TestCfg.TestGroupInput.USDCMockDeployment) && + !pointer.GetBool(TestCfg.TestGroupInput.ExistingDeployment) { + setUpOutput.Balance.Verify(t) + } + require.NoError(t, setUpOutput.TearDown()) + }) + + // Create test definitions for each lane. + var tests []testDefinition + for _, lane := range setUpOutput.Lanes { + tests = append(tests, testDefinition{ + testName: fmt.Sprintf("CCIP message transfer from network %s to network %s", + lane.ForwardLane.SourceNetworkName, lane.ForwardLane.DestNetworkName), + lane: lane.ForwardLane, + }) + if lane.ReverseLane != nil { + tests = append(tests, testDefinition{ + testName: fmt.Sprintf("CCIP message transfer from network %s to network %s", + lane.ReverseLane.SourceNetworkName, lane.ReverseLane.DestNetworkName), + lane: lane.ReverseLane, + }) + } + } + + // Execute tests. + log.Info().Int("Total Lanes", len(tests)).Msg("Starting CCIP test") + for _, test := range tests { + tc := test + t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + tc.lane.Test = t + log.Info(). + Str("Source", tc.lane.SourceNetworkName). + Str("Destination", tc.lane.DestNetworkName). + Msgf("Starting lane %s -> %s", tc.lane.SourceNetworkName, tc.lane.DestNetworkName) + + tc.lane.RecordStateBeforeTransfer() + err := tc.lane.SendRequests(1, gasLimit) + require.NoError(t, err) + tc.lane.ValidateRequests() + }) + } +} + +func TestSmokeCCIPRateLimit(t *testing.T) { + t.Parallel() + log := logging.GetTestLogger(t) + TestCfg := testsetups.NewCCIPTestConfig(t, log, testconfig.Smoke) + require.True(t, TestCfg.TestGroupInput.MsgDetails.IsTokenTransfer(), "Test config should have token transfer message type") + setUpOutput := testsetups.CCIPDefaultTestSetUp(t, &log, "smoke-ccip", nil, TestCfg) + if len(setUpOutput.Lanes) == 0 { + return + } + t.Cleanup(func() { + require.NoError(t, setUpOutput.TearDown()) + }) + + var tests []testDefinition + for _, lane := range setUpOutput.Lanes { + tests = append(tests, testDefinition{ + testName: fmt.Sprintf("Network %s to network %s", + lane.ForwardLane.SourceNetworkName, lane.ForwardLane.DestNetworkName), + lane: lane.ForwardLane, + }) + } + + // if we are running in simulated or in testnet mode, we can set the rate limit to test friendly values + // For mainnet, we need to set this as false to avoid changing the deployed contract config + setRateLimit := true + AggregatedRateLimitCapacity := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(30)) + AggregatedRateLimitRate := big.NewInt(1e17) + + TokenPoolRateLimitCapacity := new(big.Int).Mul(big.NewInt(1e17), big.NewInt(1)) + TokenPoolRateLimitRate := big.NewInt(1e14) + + for _, test := range tests { + tc := test + t.Run(fmt.Sprintf("%s - Rate Limit", tc.testName), func(t *testing.T) { + tc.lane.Test = t + src := tc.lane.Source + // add liquidity to pools on both networks + if !pointer.GetBool(TestCfg.TestGroupInput.ExistingDeployment) { + addLiquidity(t, src.Common, new(big.Int).Mul(AggregatedRateLimitCapacity, big.NewInt(20))) + addLiquidity(t, tc.lane.Dest.Common, new(big.Int).Mul(AggregatedRateLimitCapacity, big.NewInt(20))) + } + log.Info(). + Str("Source", tc.lane.SourceNetworkName). + Str("Destination", tc.lane.DestNetworkName). + Msgf("Starting lane %s -> %s", tc.lane.SourceNetworkName, tc.lane.DestNetworkName) + + // capture the rate limit config before we change it + prevRLOnRamp, err := src.OnRamp.Instance.CurrentRateLimiterState(nil) + require.NoError(t, err) + tc.lane.Logger.Info().Interface("rate limit", prevRLOnRamp).Msg("Initial OnRamp rate limiter state") + + prevOnRampRLTokenPool, err := src.Common.BridgeTokenPools[0].Instance.GetCurrentOutboundRateLimiterState( + nil, tc.lane.Source.DestChainSelector, + ) // TODO RENS maybe? + require.NoError(t, err) + tc.lane.Logger.Info(). + Interface("rate limit", prevOnRampRLTokenPool). + Str("pool", src.Common.BridgeTokenPools[0].Address()). + Str("onRamp", src.OnRamp.Address()). + Msg("Initial Token Pool rate limiter state") + + // some sanity checks + rlOffRamp, err := tc.lane.Dest.OffRamp.Instance.CurrentRateLimiterState(nil) + require.NoError(t, err) + tc.lane.Logger.Info().Interface("rate limit", rlOffRamp).Msg("Initial OffRamp rate limiter state") + if rlOffRamp.IsEnabled { + require.GreaterOrEqual(t, rlOffRamp.Capacity.Cmp(prevRLOnRamp.Capacity), 0, + "OffRamp Aggregated capacity should be greater than or equal to OnRamp Aggregated capacity", + ) + } + + prevOffRampRLTokenPool, err := tc.lane.Dest.Common.BridgeTokenPools[0].Instance.GetCurrentInboundRateLimiterState( + nil, tc.lane.Dest.SourceChainSelector, + ) // TODO RENS maybe? + require.NoError(t, err) + tc.lane.Logger.Info(). + Interface("rate limit", prevOffRampRLTokenPool). + Str("pool", tc.lane.Dest.Common.BridgeTokenPools[0].Address()). + Str("offRamp", tc.lane.Dest.OffRamp.Address()). + Msg("Initial Token Pool rate limiter state") + if prevOffRampRLTokenPool.IsEnabled { + require.GreaterOrEqual(t, prevOffRampRLTokenPool.Capacity.Cmp(prevOnRampRLTokenPool.Capacity), 0, + "OffRamp Token Pool capacity should be greater than or equal to OnRamp Token Pool capacity", + ) + } + + AggregatedRateLimitChanged := false + TokenPoolRateLimitChanged := false + + // reset the rate limit config to what it was before the tc + t.Cleanup(func() { + if AggregatedRateLimitChanged { + require.NoError(t, src.OnRamp.SetRateLimit(evm_2_evm_onramp.RateLimiterConfig{ + IsEnabled: prevRLOnRamp.IsEnabled, + Capacity: prevRLOnRamp.Capacity, + Rate: prevRLOnRamp.Rate, + }), "setting rate limit") + require.NoError(t, src.Common.ChainClient.WaitForEvents(), "waiting for events") + } + if TokenPoolRateLimitChanged { + require.NoError(t, src.Common.BridgeTokenPools[0].SetRemoteChainRateLimits(src.DestChainSelector, + token_pool.RateLimiterConfig{ + Capacity: prevOnRampRLTokenPool.Capacity, + IsEnabled: prevOnRampRLTokenPool.IsEnabled, + Rate: prevOnRampRLTokenPool.Rate, + })) + require.NoError(t, src.Common.ChainClient.WaitForEvents(), "waiting for events") + } + }) + + if setRateLimit { + if prevRLOnRamp.Capacity.Cmp(AggregatedRateLimitCapacity) != 0 || + prevRLOnRamp.Rate.Cmp(AggregatedRateLimitRate) != 0 || + !prevRLOnRamp.IsEnabled { + require.NoError(t, src.OnRamp.SetRateLimit(evm_2_evm_onramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: AggregatedRateLimitCapacity, + Rate: AggregatedRateLimitRate, + }), "setting rate limit on onramp") + require.NoError(t, src.Common.ChainClient.WaitForEvents(), "waiting for events") + AggregatedRateLimitChanged = true + } + } else { + AggregatedRateLimitCapacity = prevRLOnRamp.Capacity + AggregatedRateLimitRate = prevRLOnRamp.Rate + } + + rlOnRamp, err := src.OnRamp.Instance.CurrentRateLimiterState(nil) + require.NoError(t, err) + tc.lane.Logger.Info().Interface("rate limit", rlOnRamp).Msg("OnRamp rate limiter state") + require.True(t, rlOnRamp.IsEnabled, "OnRamp rate limiter should be enabled") + + tokenPrice, err := src.Common.PriceRegistry.Instance.GetTokenPrice(nil, src.Common.BridgeTokens[0].ContractAddress) + require.NoError(t, err) + tc.lane.Logger.Info().Str("tokenPrice.Value", tokenPrice.String()).Msg("Price Registry Token Price") + + totalTokensForOnRampCapacity := new(big.Int).Mul( + big.NewInt(1e18), + new(big.Int).Div(rlOnRamp.Capacity, tokenPrice), + ) + + tc.lane.Source.Common.ChainClient.ParallelTransactions(true) + + // current tokens are equal to the full capacity - should fail + src.TransferAmount[0] = rlOnRamp.Tokens + tc.lane.Logger.Info().Str("tokensToSend", rlOnRamp.Tokens.String()).Msg("Aggregated Capacity") + // approve the tokens + require.NoError(t, src.Common.BridgeTokens[0].Approve( + tc.lane.Source.Common.ChainClient.GetDefaultWallet(), src.Common.Router.Address(), src.TransferAmount[0]), + ) + require.NoError(t, tc.lane.Source.Common.ChainClient.WaitForEvents()) + failedTx, _, _, err := tc.lane.Source.SendRequest( + tc.lane.Dest.ReceiverDapp.EthAddress, + big.NewInt(actions.DefaultDestinationGasLimit), // gas limit + ) + require.NoError(t, err) + require.Error(t, tc.lane.Source.Common.ChainClient.WaitForEvents()) + errReason, v, err := tc.lane.Source.Common.ChainClient.RevertReasonFromTx(failedTx, evm_2_evm_onramp.EVM2EVMOnRampABI) + require.NoError(t, err) + tc.lane.Logger.Info(). + Str("Revert Reason", errReason). + Interface("Args", v). + Str("TokensSent", src.TransferAmount[0].String()). + Str("Token", tc.lane.Source.Common.BridgeTokens[0].Address()). + Str("FailedTx", failedTx.Hex()). + Msg("Msg sent with tokens more than AggregateValueMaxCapacity") + require.Equal(t, "AggregateValueMaxCapacityExceeded", errReason) + + // 99% of the aggregated capacity - should succeed + tokensToSend := new(big.Int).Div(new(big.Int).Mul(totalTokensForOnRampCapacity, big.NewInt(99)), big.NewInt(100)) + tc.lane.Logger.Info().Str("tokensToSend", tokensToSend.String()).Msg("99% of Aggregated Capacity") + tc.lane.RecordStateBeforeTransfer() + src.TransferAmount[0] = tokensToSend + err = tc.lane.SendRequests(1, big.NewInt(actions.DefaultDestinationGasLimit)) + require.NoError(t, err) + + // try to send again with amount more than the amount refilled by rate and + // this should fail, as the refill rate is not enough to refill the capacity + src.TransferAmount[0] = new(big.Int).Mul(AggregatedRateLimitRate, big.NewInt(10)) + failedTx, _, _, err = tc.lane.Source.SendRequest( + tc.lane.Dest.ReceiverDapp.EthAddress, + big.NewInt(actions.DefaultDestinationGasLimit), // gas limit + ) + tc.lane.Logger.Info().Str("tokensToSend", src.TransferAmount[0].String()).Msg("More than Aggregated Rate") + require.NoError(t, err) + require.Error(t, tc.lane.Source.Common.ChainClient.WaitForEvents()) + errReason, v, err = tc.lane.Source.Common.ChainClient.RevertReasonFromTx(failedTx, evm_2_evm_onramp.EVM2EVMOnRampABI) + require.NoError(t, err) + tc.lane.Logger.Info(). + Str("Revert Reason", errReason). + Interface("Args", v). + Str("TokensSent", src.TransferAmount[0].String()). + Str("Token", tc.lane.Source.Common.BridgeTokens[0].Address()). + Str("FailedTx", failedTx.Hex()). + Msg("Msg sent with tokens more than AggregateValueRate") + require.Equal(t, "AggregateValueRateLimitReached", errReason) + + // validate the successful request was delivered to the destination + tc.lane.ValidateRequests() + + // now set the token pool rate limit + if setRateLimit { + if prevOnRampRLTokenPool.Capacity.Cmp(TokenPoolRateLimitCapacity) != 0 || + prevOnRampRLTokenPool.Rate.Cmp(TokenPoolRateLimitRate) != 0 || + !prevOnRampRLTokenPool.IsEnabled { + require.NoError(t, src.Common.BridgeTokenPools[0].SetRemoteChainRateLimits( + src.DestChainSelector, + token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: TokenPoolRateLimitCapacity, + Rate: TokenPoolRateLimitRate, + }), "error setting rate limit on token pool") + require.NoError(t, src.Common.ChainClient.WaitForEvents(), "waiting for events") + TokenPoolRateLimitChanged = true + } + } else { + TokenPoolRateLimitCapacity = prevOnRampRLTokenPool.Capacity + TokenPoolRateLimitRate = prevOnRampRLTokenPool.Rate + } + + rlOnPool, err := src.Common.BridgeTokenPools[0].Instance.GetCurrentOutboundRateLimiterState(nil, src.DestChainSelector) + require.NoError(t, err) + require.True(t, rlOnPool.IsEnabled, "Token Pool rate limiter should be enabled") + + // try to send more than token pool capacity - should fail + tokensToSend = new(big.Int).Add(TokenPoolRateLimitCapacity, big.NewInt(2)) + + // wait for the AggregateCapacity to be refilled + onRampState, err := src.OnRamp.Instance.CurrentRateLimiterState(nil) + if err != nil { + return + } + if AggregatedRateLimitCapacity.Cmp(onRampState.Capacity) > 0 { + capacityToBeFilled := new(big.Int).Sub(AggregatedRateLimitCapacity, onRampState.Capacity) + durationToFill := time.Duration(new(big.Int).Div(capacityToBeFilled, AggregatedRateLimitRate).Int64()) + tc.lane.Logger.Info(). + Dur("wait duration", durationToFill). + Str("current capacity", onRampState.Capacity.String()). + Str("tokensToSend", tokensToSend.String()). + Msg("Waiting for aggregated capacity to be available") + time.Sleep(durationToFill * time.Second) + } + + src.TransferAmount[0] = tokensToSend + tc.lane.Logger.Info().Str("tokensToSend", tokensToSend.String()).Msg("More than Token Pool Capacity") + + failedTx, _, _, err = tc.lane.Source.SendRequest( + tc.lane.Dest.ReceiverDapp.EthAddress, + big.NewInt(actions.DefaultDestinationGasLimit), // gas limit + ) + require.NoError(t, err) + require.Error(t, tc.lane.Source.Common.ChainClient.WaitForEvents()) + errReason, v, err = tc.lane.Source.Common.ChainClient.RevertReasonFromTx(failedTx, lock_release_token_pool.LockReleaseTokenPoolABI) + require.NoError(t, err) + tc.lane.Logger.Info(). + Str("Revert Reason", errReason). + Interface("Args", v). + Str("TokensSent", src.TransferAmount[0].String()). + Str("Token", tc.lane.Source.Common.BridgeTokens[0].Address()). + Str("FailedTx", failedTx.Hex()). + Msg("Msg sent with tokens more than token pool capacity") + require.Equal(t, "TokenMaxCapacityExceeded", errReason) + + // try to send 99% of token pool capacity - should succeed + tokensToSend = new(big.Int).Div(new(big.Int).Mul(TokenPoolRateLimitCapacity, big.NewInt(99)), big.NewInt(100)) + src.TransferAmount[0] = tokensToSend + tc.lane.Logger.Info().Str("tokensToSend", tokensToSend.String()).Msg("99% of Token Pool Capacity") + tc.lane.RecordStateBeforeTransfer() + err = tc.lane.SendRequests(1, big.NewInt(actions.DefaultDestinationGasLimit)) + require.NoError(t, err) + + // try to send again with amount more than the amount refilled by token pool rate and + // this should fail, as the refill rate is not enough to refill the capacity + tokensToSend = new(big.Int).Mul(TokenPoolRateLimitRate, big.NewInt(20)) + tc.lane.Logger.Info().Str("tokensToSend", tokensToSend.String()).Msg("More than TokenPool Rate") + src.TransferAmount[0] = tokensToSend + // approve the tokens + require.NoError(t, src.Common.BridgeTokens[0].Approve( + src.Common.ChainClient.GetDefaultWallet(), src.Common.Router.Address(), src.TransferAmount[0]), + ) + require.NoError(t, tc.lane.Source.Common.ChainClient.WaitForEvents()) + failedTx, _, _, err = tc.lane.Source.SendRequest( + tc.lane.Dest.ReceiverDapp.EthAddress, + big.NewInt(actions.DefaultDestinationGasLimit), + ) + require.NoError(t, err) + require.Error(t, tc.lane.Source.Common.ChainClient.WaitForEvents()) + errReason, v, err = tc.lane.Source.Common.ChainClient.RevertReasonFromTx(failedTx, lock_release_token_pool.LockReleaseTokenPoolABI) + require.NoError(t, err) + tc.lane.Logger.Info(). + Str("Revert Reason", errReason). + Interface("Args", v). + Str("TokensSent", src.TransferAmount[0].String()). + Str("Token", tc.lane.Source.Common.BridgeTokens[0].Address()). + Str("FailedTx", failedTx.Hex()). + Msg("Msg sent with tokens more than TokenPool Rate") + require.Equal(t, "TokenRateLimitReached", errReason) + + // validate that the successful transfers are reflected in destination + tc.lane.ValidateRequests() + }) + } +} + +func TestSmokeCCIPOnRampLimits(t *testing.T) { + t.Parallel() + + log := logging.GetTestLogger(t) + TestCfg := testsetups.NewCCIPTestConfig(t, log, testconfig.Smoke, testsetups.WithNoTokensPerMessage(4), testsetups.WithTokensPerChain(4)) + require.False(t, pointer.GetBool(TestCfg.TestGroupInput.ExistingDeployment), + "This test modifies contract state. Before running it, ensure you are willing and able to do so.", + ) + err := contracts.MatchContractVersionsOrAbove(map[contracts.Name]contracts.Version{ + contracts.OffRampContract: contracts.V1_5_0_dev, + contracts.OnRampContract: contracts.V1_5_0_dev, + }) + require.NoError(t, err, "Required contract versions not met") + + setUpOutput := testsetups.CCIPDefaultTestSetUp(t, &log, "smoke-ccip", nil, TestCfg) + if len(setUpOutput.Lanes) == 0 { + return + } + t.Cleanup(func() { + require.NoError(t, setUpOutput.TearDown()) + }) + + var tests []testDefinition + for _, lane := range setUpOutput.Lanes { + tests = append(tests, testDefinition{ + testName: fmt.Sprintf("Network %s to network %s", + lane.ForwardLane.SourceNetworkName, lane.ForwardLane.DestNetworkName), + lane: lane.ForwardLane, + }) + } + + var ( + capacityLimit = big.NewInt(1e16) + overCapacityAmount = new(big.Int).Add(capacityLimit, big.NewInt(1)) + + // token without any transfer config + freeTokenIndex = 0 + // token with bps non-zero, no agg rate limit + bpsTokenIndex = 1 + // token with bps zero, with agg rate limit on + aggRateTokenIndex = 2 + // token with both bps and agg rate limit + bpsAndAggTokenIndex = 3 + ) + + for _, tc := range tests { + t.Run(fmt.Sprintf("%s - OnRamp Limits", tc.testName), func(t *testing.T) { + tc.lane.Test = t + src := tc.lane.Source + dest := tc.lane.Dest + require.GreaterOrEqual(t, len(src.Common.BridgeTokens), 2, "At least two bridge tokens needed for test") + require.GreaterOrEqual(t, len(src.Common.BridgeTokenPools), 2, "At least two bridge token pools needed for test") + require.GreaterOrEqual(t, len(dest.Common.BridgeTokens), 2, "At least two bridge tokens needed for test") + require.GreaterOrEqual(t, len(dest.Common.BridgeTokenPools), 2, "At least two bridge token pools needed for test") + addLiquidity(t, src.Common, new(big.Int).Mul(capacityLimit, big.NewInt(20))) + addLiquidity(t, dest.Common, new(big.Int).Mul(capacityLimit, big.NewInt(20))) + + var ( + freeToken = src.Common.BridgeTokens[freeTokenIndex] + bpsToken = src.Common.BridgeTokens[bpsTokenIndex] + aggRateToken = src.Common.BridgeTokens[aggRateTokenIndex] + bpsAndAggToken = src.Common.BridgeTokens[bpsAndAggTokenIndex] + ) + tc.lane.Logger.Info(). + Str("Free Token", freeToken.ContractAddress.Hex()). + Str("BPS Token", bpsToken.ContractAddress.Hex()). + Str("Agg Rate Token", aggRateToken.ContractAddress.Hex()). + Str("BPS and Agg Rate Token", bpsAndAggToken.ContractAddress.Hex()). + Msg("Tokens for rate limit testing") + err := tc.lane.DisableAllRateLimiting() + require.NoError(t, err, "Error disabling rate limits") + + // Set reasonable rate limits for the tokens + err = src.OnRamp.SetTokenTransferFeeConfig([]evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ + { + Token: bpsToken.ContractAddress, + AggregateRateLimitEnabled: false, + DeciBps: 10, + }, + { + Token: aggRateToken.ContractAddress, + AggregateRateLimitEnabled: true, + }, + { + Token: bpsAndAggToken.ContractAddress, + AggregateRateLimitEnabled: true, + DeciBps: 10, + }, + }) + require.NoError(t, err, "Error setting OnRamp transfer fee config") + err = src.OnRamp.SetRateLimit(evm_2_evm_onramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: capacityLimit, + Rate: new(big.Int).Mul(capacityLimit, big.NewInt(500)), // Set a high rate to avoid it getting in the way + }) + require.NoError(t, err, "Error setting OnRamp rate limits") + err = src.Common.ChainClient.WaitForEvents() + require.NoError(t, err, "Error waiting for events") + + // Send all tokens under their limits and ensure they succeed + src.TransferAmount[freeTokenIndex] = overCapacityAmount + src.TransferAmount[bpsTokenIndex] = overCapacityAmount + src.TransferAmount[aggRateTokenIndex] = big.NewInt(1) + src.TransferAmount[bpsAndAggTokenIndex] = big.NewInt(1) + tc.lane.RecordStateBeforeTransfer() + err = tc.lane.SendRequests(1, big.NewInt(actions.DefaultDestinationGasLimit)) + require.NoError(t, err) + tc.lane.ValidateRequests() + + // Check that capacity limits are enforced + src.TransferAmount[freeTokenIndex] = big.NewInt(0) + src.TransferAmount[bpsTokenIndex] = big.NewInt(0) + src.TransferAmount[aggRateTokenIndex] = overCapacityAmount + src.TransferAmount[bpsAndAggTokenIndex] = big.NewInt(0) + failedTx, _, _, err := tc.lane.Source.SendRequest(tc.lane.Dest.ReceiverDapp.EthAddress, big.NewInt(actions.DefaultDestinationGasLimit)) + require.Error(t, err, "Limited token transfer should immediately revert") + errReason, _, err := src.Common.ChainClient.RevertReasonFromTx(failedTx, evm_2_evm_onramp.EVM2EVMOnRampABI) + require.NoError(t, err) + require.Equal(t, "AggregateValueMaxCapacityExceeded", errReason, "Expected capacity limit reached error") + tc.lane.Logger. + Info(). + Str("Token", aggRateToken.ContractAddress.Hex()). + Msg("Limited token transfer failed on source chain (a good thing in this context)") + + src.TransferAmount[aggRateTokenIndex] = big.NewInt(0) + src.TransferAmount[bpsAndAggTokenIndex] = overCapacityAmount + failedTx, _, _, err = tc.lane.Source.SendRequest(tc.lane.Dest.ReceiverDapp.EthAddress, big.NewInt(actions.DefaultDestinationGasLimit)) + require.Error(t, err, "Limited token transfer should immediately revert") + errReason, _, err = src.Common.ChainClient.RevertReasonFromTx(failedTx, evm_2_evm_onramp.EVM2EVMOnRampABI) + require.NoError(t, err) + require.Equal(t, "AggregateValueMaxCapacityExceeded", errReason, "Expected capacity limit reached error") + tc.lane.Logger. + Info(). + Str("Token", aggRateToken.ContractAddress.Hex()). + Msg("Limited token transfer failed on source chain (a good thing in this context)") + + // Set a high price for the tokens to more easily trigger aggregate rate limits + // Aggregate rate limits are based on USD price of the tokens + err = src.Common.PriceRegistry.UpdatePrices([]contracts.InternalTokenPriceUpdate{ + { + SourceToken: aggRateToken.ContractAddress, + UsdPerToken: big.NewInt(100), + }, + { + SourceToken: bpsAndAggToken.ContractAddress, + UsdPerToken: big.NewInt(100), + }, + }, []contracts.InternalGasPriceUpdate{}) + require.NoError(t, err, "Error updating prices") + // Enable aggregate rate limiting for the limited tokens + err = src.OnRamp.SetRateLimit(evm_2_evm_onramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: new(big.Int).Mul(capacityLimit, big.NewInt(5000)), // Set a high capacity to avoid it getting in the way + Rate: big.NewInt(1), + }) + require.NoError(t, err, "Error setting OnRamp rate limits") + err = src.Common.ChainClient.WaitForEvents() + require.NoError(t, err, "Error waiting for events") + + // Send aggregate unlimited tokens and ensure they succeed + src.TransferAmount[freeTokenIndex] = overCapacityAmount + src.TransferAmount[bpsTokenIndex] = overCapacityAmount + src.TransferAmount[aggRateTokenIndex] = big.NewInt(0) + src.TransferAmount[bpsAndAggTokenIndex] = big.NewInt(0) + tc.lane.RecordStateBeforeTransfer() + err = tc.lane.SendRequests(1, big.NewInt(actions.DefaultDestinationGasLimit)) + require.NoError(t, err) + tc.lane.ValidateRequests() + + // Check that aggregate rate limits are enforced on limited tokens + src.TransferAmount[freeTokenIndex] = big.NewInt(0) + src.TransferAmount[bpsTokenIndex] = big.NewInt(0) + src.TransferAmount[aggRateTokenIndex] = capacityLimit + src.TransferAmount[bpsAndAggTokenIndex] = big.NewInt(0) + failedTx, _, _, err = tc.lane.Source.SendRequest(tc.lane.Dest.ReceiverDapp.EthAddress, big.NewInt(actions.DefaultDestinationGasLimit)) + require.Error(t, err, "Aggregate rate limited token transfer should immediately revert") + errReason, _, err = src.Common.ChainClient.RevertReasonFromTx(failedTx, evm_2_evm_onramp.EVM2EVMOnRampABI) + require.NoError(t, err) + require.Equal(t, "AggregateValueRateLimitReached", errReason, "Expected aggregate rate limit reached error") + tc.lane.Logger. + Info(). + Str("Token", aggRateToken.ContractAddress.Hex()). + Msg("Limited token transfer failed on source chain (a good thing in this context)") + + src.TransferAmount[aggRateTokenIndex] = big.NewInt(0) + src.TransferAmount[bpsAndAggTokenIndex] = capacityLimit + failedTx, _, _, err = tc.lane.Source.SendRequest(tc.lane.Dest.ReceiverDapp.EthAddress, big.NewInt(actions.DefaultDestinationGasLimit)) + require.Error(t, err, "Aggregate rate limited token transfer should immediately revert") + errReason, _, err = src.Common.ChainClient.RevertReasonFromTx(failedTx, evm_2_evm_onramp.EVM2EVMOnRampABI) + require.NoError(t, err) + require.Equal(t, "AggregateValueRateLimitReached", errReason, "Expected aggregate rate limit reached error") + tc.lane.Logger. + Info(). + Str("Token", aggRateToken.ContractAddress.Hex()). + Msg("Limited token transfer failed on source chain (a good thing in this context)") + }) + } +} + +func TestSmokeCCIPOffRampCapacityLimit(t *testing.T) { + t.Parallel() + + capacityLimited := contracts.RateLimiterConfig{ + IsEnabled: true, + Capacity: big.NewInt(1e16), + Rate: new(big.Int).Mul(big.NewInt(1e16), big.NewInt(10)), // Set a high rate limit to avoid it getting in the way + } + testOffRampRateLimits(t, capacityLimited) +} + +func TestSmokeCCIPOffRampAggRateLimit(t *testing.T) { + t.Parallel() + + aggRateLimited := contracts.RateLimiterConfig{ + IsEnabled: true, + Capacity: new(big.Int).Mul(big.NewInt(1e16), big.NewInt(10)), // Set a high capacity limit to avoid it getting in the way + Rate: big.NewInt(1), + } + testOffRampRateLimits(t, aggRateLimited) +} + +func TestSmokeCCIPTokenPoolRateLimits(t *testing.T) { + t.Parallel() + + log := logging.GetTestLogger(t) + TestCfg := testsetups.NewCCIPTestConfig(t, log, testconfig.Smoke, testsetups.WithNoTokensPerMessage(4), testsetups.WithTokensPerChain(4)) + require.False(t, pointer.GetBool(TestCfg.TestGroupInput.ExistingDeployment), + "This test modifies contract state. Before running it, ensure you are willing and able to do so.", + ) + err := contracts.MatchContractVersionsOrAbove(map[contracts.Name]contracts.Version{ + contracts.OffRampContract: contracts.V1_5_0_dev, + contracts.OnRampContract: contracts.V1_5_0_dev, + }) + require.NoError(t, err, "Required contract versions not met") + + setUpOutput := testsetups.CCIPDefaultTestSetUp(t, &log, "smoke-ccip", nil, TestCfg) + if len(setUpOutput.Lanes) == 0 { + return + } + t.Cleanup(func() { + require.NoError(t, setUpOutput.TearDown()) + }) + + var tests []testDefinition + for _, lane := range setUpOutput.Lanes { + tests = append(tests, testDefinition{ + testName: fmt.Sprintf("Network %s to network %s", + lane.ForwardLane.SourceNetworkName, lane.ForwardLane.DestNetworkName), + lane: lane.ForwardLane, + }) + } + + var ( + capacityLimit = big.NewInt(1e16) + overCapacityAmount = new(big.Int).Add(capacityLimit, big.NewInt(1)) + + // token without any limits + freeTokenIndex = 0 + // token with rate limits + limitedTokenIndex = 1 + ) + + for _, tc := range tests { + t.Run(fmt.Sprintf("%s - Token Pool Rate Limits", tc.testName), func(t *testing.T) { + tc.lane.Test = t + src := tc.lane.Source + dest := tc.lane.Dest + require.GreaterOrEqual(t, len(src.Common.BridgeTokens), 2, "At least two bridge tokens needed for test") + require.GreaterOrEqual(t, len(src.Common.BridgeTokenPools), 2, "At least two bridge token pools needed for test") + require.GreaterOrEqual(t, len(dest.Common.BridgeTokens), 2, "At least two bridge tokens needed for test") + require.GreaterOrEqual(t, len(dest.Common.BridgeTokenPools), 2, "At least two bridge token pools needed for test") + addLiquidity(t, src.Common, new(big.Int).Mul(capacityLimit, big.NewInt(20))) + addLiquidity(t, dest.Common, new(big.Int).Mul(capacityLimit, big.NewInt(20))) + + var ( + freeToken = src.Common.BridgeTokens[freeTokenIndex] + limitedToken = src.Common.BridgeTokens[limitedTokenIndex] + limitedTokenPool = src.Common.BridgeTokenPools[limitedTokenIndex] + ) + tc.lane.Logger.Info(). + Str("Free Token", freeToken.ContractAddress.Hex()). + Str("Limited Token", limitedToken.ContractAddress.Hex()). + Msg("Tokens for rate limit testing") + err := tc.lane.DisableAllRateLimiting() // Make sure this is pure + require.NoError(t, err, "Error disabling rate limits") + + // Check capacity limits + err = limitedTokenPool.SetRemoteChainRateLimits(src.DestChainSelector, token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: capacityLimit, + Rate: new(big.Int).Sub(capacityLimit, big.NewInt(1)), // Set as high rate as possible to avoid it getting in the way + }) + require.NoError(t, err, "Error setting token pool rate limit") + err = src.Common.ChainClient.WaitForEvents() + require.NoError(t, err, "Error waiting for events") + + // Send all tokens under their limits and ensure they succeed + src.TransferAmount[freeTokenIndex] = overCapacityAmount + src.TransferAmount[limitedTokenIndex] = big.NewInt(1) + tc.lane.RecordStateBeforeTransfer() + err = tc.lane.SendRequests(1, big.NewInt(actions.DefaultDestinationGasLimit)) + require.NoError(t, err) + tc.lane.ValidateRequests() + + // Send limited token over capacity and ensure it fails + src.TransferAmount[freeTokenIndex] = big.NewInt(0) + src.TransferAmount[limitedTokenIndex] = overCapacityAmount + failedTx, _, _, err := tc.lane.Source.SendRequest(tc.lane.Dest.ReceiverDapp.EthAddress, big.NewInt(actions.DefaultDestinationGasLimit)) + require.Error(t, err, "Limited token transfer should immediately revert") + errReason, _, err := src.Common.ChainClient.RevertReasonFromTx(failedTx, lock_release_token_pool.LockReleaseTokenPoolABI) + require.NoError(t, err) + require.Equal(t, "TokenMaxCapacityExceeded", errReason, "Expected token capacity error") + tc.lane.Logger. + Info(). + Str("Token", limitedToken.ContractAddress.Hex()). + Msg("Limited token transfer failed on source chain (a good thing in this context)") + + // Check rate limit + err = limitedTokenPool.SetRemoteChainRateLimits(src.DestChainSelector, token_pool.RateLimiterConfig{ + IsEnabled: true, + Capacity: new(big.Int).Mul(capacityLimit, big.NewInt(2)), // Set a high capacity to avoid it getting in the way + Rate: big.NewInt(1), + }) + require.NoError(t, err, "Error setting token pool rate limit") + err = src.Common.ChainClient.WaitForEvents() + require.NoError(t, err, "Error waiting for events") + + // Send all tokens under their limits and ensure they succeed + src.TransferAmount[freeTokenIndex] = overCapacityAmount + src.TransferAmount[limitedTokenIndex] = capacityLimit + tc.lane.RecordStateBeforeTransfer() + err = tc.lane.SendRequests(1, big.NewInt(actions.DefaultDestinationGasLimit)) + require.NoError(t, err) + tc.lane.ValidateRequests() + + // Send limited token over rate limit and ensure it fails + src.TransferAmount[freeTokenIndex] = big.NewInt(0) + src.TransferAmount[limitedTokenIndex] = capacityLimit + failedTx, _, _, err = tc.lane.Source.SendRequest(tc.lane.Dest.ReceiverDapp.EthAddress, big.NewInt(actions.DefaultDestinationGasLimit)) + require.Error(t, err, "Limited token transfer should immediately revert") + errReason, _, err = src.Common.ChainClient.RevertReasonFromTx(failedTx, lock_release_token_pool.LockReleaseTokenPoolABI) + require.NoError(t, err) + require.Equal(t, "TokenRateLimitReached", errReason, "Expected rate limit reached error") + tc.lane.Logger. + Info(). + Str("Token", limitedToken.ContractAddress.Hex()). + Msg("Limited token transfer failed on source chain (a good thing in this context)") + }) + } +} + +func TestSmokeCCIPMulticall(t *testing.T) { + t.Parallel() + log := logging.GetTestLogger(t) + TestCfg := testsetups.NewCCIPTestConfig(t, log, testconfig.Smoke) + // enable multicall in one tx for this test + TestCfg.TestGroupInput.MulticallInOneTx = ptr.Ptr(true) + setUpOutput := testsetups.CCIPDefaultTestSetUp(t, &log, "smoke-ccip", nil, TestCfg) + if len(setUpOutput.Lanes) == 0 { + return + } + t.Cleanup(func() { + require.NoError(t, setUpOutput.TearDown()) + }) + + var tests []testDefinition + for _, lane := range setUpOutput.Lanes { + tests = append(tests, testDefinition{ + testName: fmt.Sprintf("CCIP message transfer from network %s to network %s", + lane.ForwardLane.SourceNetworkName, lane.ForwardLane.DestNetworkName), + lane: lane.ForwardLane, + }) + if lane.ReverseLane != nil { + tests = append(tests, testDefinition{ + testName: fmt.Sprintf("CCIP message transfer from network %s to network %s", + lane.ReverseLane.SourceNetworkName, lane.ReverseLane.DestNetworkName), + lane: lane.ReverseLane, + }) + } + } + + log.Info().Int("Total Lanes", len(tests)).Msg("Starting CCIP test") + for _, test := range tests { + tc := test + t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + tc.lane.Test = t + log.Info(). + Str("Source", tc.lane.SourceNetworkName). + Str("Destination", tc.lane.DestNetworkName). + Msgf("Starting lane %s -> %s", tc.lane.SourceNetworkName, tc.lane.DestNetworkName) + + tc.lane.RecordStateBeforeTransfer() + err := tc.lane.Multicall(TestCfg.TestGroupInput.NoOfSendsInMulticall, tc.lane.Source.Common.MulticallContract) + require.NoError(t, err) + tc.lane.ValidateRequests() + }) + } +} + +func TestSmokeCCIPManuallyExecuteAfterExecutionFailingDueToInsufficientGas(t *testing.T) { + t.Parallel() + log := logging.GetTestLogger(t) + TestCfg := testsetups.NewCCIPTestConfig(t, log, testconfig.Smoke) + setUpOutput := testsetups.CCIPDefaultTestSetUp(t, &log, "smoke-ccip", nil, TestCfg) + if len(setUpOutput.Lanes) == 0 { + return + } + t.Cleanup(func() { + if TestCfg.TestGroupInput.MsgDetails.IsTokenTransfer() { + setUpOutput.Balance.Verify(t) + } + require.NoError(t, setUpOutput.TearDown()) + }) + + var tests []testDefinition + for _, lane := range setUpOutput.Lanes { + tests = append(tests, testDefinition{ + testName: fmt.Sprintf("CCIP message transfer from network %s to network %s", + lane.ForwardLane.SourceNetworkName, lane.ForwardLane.DestNetworkName), + lane: lane.ForwardLane, + }) + if lane.ReverseLane != nil { + tests = append(tests, testDefinition{ + testName: fmt.Sprintf("CCIP message transfer from network %s to network %s", + lane.ReverseLane.SourceNetworkName, lane.ReverseLane.DestNetworkName), + lane: lane.ReverseLane, + }) + } + } + + log.Info().Int("Total Lanes", len(tests)).Msg("Starting CCIP test") + for _, test := range tests { + tc := test + t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + tc.lane.Test = t + log.Info(). + Str("Source", tc.lane.SourceNetworkName). + Str("Destination", tc.lane.DestNetworkName). + Msgf("Starting lane %s -> %s", tc.lane.SourceNetworkName, tc.lane.DestNetworkName) + + tc.lane.RecordStateBeforeTransfer() + // send with insufficient gas for ccip-receive to fail + err := tc.lane.SendRequests(1, big.NewInt(0)) + require.NoError(t, err) + tc.lane.ValidateRequests(actions.ExpectPhaseToFail(testreporters.ExecStateChanged)) + // wait for events + err = tc.lane.Dest.Common.ChainClient.WaitForEvents() + require.NoError(t, err) + // execute all failed ccip requests manually + err = tc.lane.ExecuteManually() + require.NoError(t, err) + if len(tc.lane.Source.TransferAmount) > 0 { + tc.lane.Source.UpdateBalance(int64(tc.lane.NumberOfReq), tc.lane.TotalFee, tc.lane.Balance) + tc.lane.Dest.UpdateBalance(tc.lane.Source.TransferAmount, int64(tc.lane.NumberOfReq), tc.lane.Balance) + } + }) + } +} + +// add liquidity to pools on both networks +func addLiquidity(t *testing.T, ccipCommon *actions.CCIPCommon, amount *big.Int) { + t.Helper() + + for i, btp := range ccipCommon.BridgeTokenPools { + token := ccipCommon.BridgeTokens[i] + err := btp.AddLiquidity( + token, token.OwnerWallet, amount, + ) + require.NoError(t, err) + } +} + +// testOffRampRateLimits tests the rate limiting functionality of the OffRamp contract +// it's broken into a helper to help parallelize and keep the tests DRY +func testOffRampRateLimits(t *testing.T, rateLimiterConfig contracts.RateLimiterConfig) { + t.Helper() + + log := logging.GetTestLogger(t) + TestCfg := testsetups.NewCCIPTestConfig(t, log, testconfig.Smoke) + require.False(t, pointer.GetBool(TestCfg.TestGroupInput.ExistingDeployment), + "This test modifies contract state. Before running it, ensure you are willing and able to do so.", + ) + err := contracts.MatchContractVersionsOrAbove(map[contracts.Name]contracts.Version{ + contracts.OffRampContract: contracts.V1_5_0_dev, + }) + require.NoError(t, err, "Required contract versions not met") + require.False(t, pointer.GetBool(TestCfg.TestGroupInput.ExistingDeployment), "This test modifies contract state and cannot be run on existing deployments") + + // Set the default permissionless exec threshold lower so that we can manually execute the transactions faster + // Tuning this too low stops any transactions from being realistically executed + actions.DefaultPermissionlessExecThreshold = 1 * time.Minute + + setUpOutput := testsetups.CCIPDefaultTestSetUp(t, &log, "smoke-ccip", nil, TestCfg) + if len(setUpOutput.Lanes) == 0 { + return + } + t.Cleanup(func() { + require.NoError(t, setUpOutput.TearDown()) + }) + + var tests []testDefinition + for _, lane := range setUpOutput.Lanes { + tests = append(tests, testDefinition{ + testName: fmt.Sprintf("Network %s to network %s", + lane.ForwardLane.SourceNetworkName, lane.ForwardLane.DestNetworkName), + lane: lane.ForwardLane, + }) + } + + var ( + freeTokenIndex = 0 + limitedTokenIndex = 1 + ) + + for _, tc := range tests { + t.Run(fmt.Sprintf("%s - OffRamp Limits", tc.testName), func(t *testing.T) { + tc.lane.Test = t + src := tc.lane.Source + dest := tc.lane.Dest + var ( + capacityLimit = rateLimiterConfig.Capacity + overLimitAmount = new(big.Int).Add(capacityLimit, big.NewInt(1)) + ) + require.GreaterOrEqual(t, len(src.Common.BridgeTokens), 2, "At least two bridge tokens needed for test") + require.GreaterOrEqual(t, len(src.Common.BridgeTokenPools), 2, "At least two bridge token pools needed for test") + require.GreaterOrEqual(t, len(dest.Common.BridgeTokens), 2, "At least two bridge tokens needed for test") + require.GreaterOrEqual(t, len(dest.Common.BridgeTokenPools), 2, "At least two bridge token pools needed for test") + addLiquidity(t, src.Common, new(big.Int).Mul(capacityLimit, big.NewInt(20))) + addLiquidity(t, dest.Common, new(big.Int).Mul(capacityLimit, big.NewInt(20))) + + var ( + freeSrcToken = src.Common.BridgeTokens[freeTokenIndex] + freeDestToken = dest.Common.BridgeTokens[freeTokenIndex] + limitedSrcToken = src.Common.BridgeTokens[limitedTokenIndex] + limitedDestToken = dest.Common.BridgeTokens[limitedTokenIndex] + ) + tc.lane.Logger.Info(). + Str("Free Source Token", freeSrcToken.Address()). + Str("Free Dest Token", freeDestToken.Address()). + Str("Limited Source Token", limitedSrcToken.Address()). + Str("Limited Dest Token", limitedDestToken.Address()). + Msg("Tokens for rate limit testing") + + err := tc.lane.DisableAllRateLimiting() + require.NoError(t, err, "Error disabling rate limits") + + // Send both tokens with no rate limits and ensure they succeed + src.TransferAmount[freeTokenIndex] = overLimitAmount + src.TransferAmount[limitedTokenIndex] = overLimitAmount + tc.lane.RecordStateBeforeTransfer() + err = tc.lane.SendRequests(1, big.NewInt(actions.DefaultDestinationGasLimit)) + require.NoError(t, err) + tc.lane.ValidateRequests() + + // Enable capacity limiting on the destination chain for the limited token + err = dest.AddRateLimitTokens([]*contracts.ERC20Token{limitedSrcToken}, []*contracts.ERC20Token{limitedDestToken}) + require.NoError(t, err, "Error setting destination rate limits") + err = dest.OffRamp.SetRateLimit(rateLimiterConfig) + require.NoError(t, err, "Error setting destination rate limits") + err = dest.Common.ChainClient.WaitForEvents() + require.NoError(t, err, "Error waiting for events") + tc.lane.Logger.Debug().Str("Token", limitedSrcToken.ContractAddress.Hex()).Msg("Enabled capacity limit on destination chain") + + // Send free token that should not have a rate limit and should succeed + src.TransferAmount[freeTokenIndex] = overLimitAmount + src.TransferAmount[limitedTokenIndex] = big.NewInt(0) + tc.lane.RecordStateBeforeTransfer() + err = tc.lane.SendRequests(1, big.NewInt(actions.DefaultDestinationGasLimit)) + require.NoError(t, err, "Free token transfer failed") + tc.lane.ValidateRequests() + tc.lane.Logger.Info().Str("Token", freeSrcToken.ContractAddress.Hex()).Msg("Free token transfer succeeded") + + // Send limited token with rate limit that should fail on the destination chain + src.TransferAmount[freeTokenIndex] = big.NewInt(0) + src.TransferAmount[limitedTokenIndex] = overLimitAmount + tc.lane.RecordStateBeforeTransfer() + err = tc.lane.SendRequests(1, big.NewInt(actions.DefaultDestinationGasLimit)) + require.NoError(t, err, "Failed to send rate limited token transfer") + + // We should see the ExecStateChanged phase fail on the OffRamp + tc.lane.ValidateRequests(actions.ExpectPhaseToFail(testreporters.ExecStateChanged)) + tc.lane.Logger.Info(). + Str("Token", limitedSrcToken.ContractAddress.Hex()). + Msg("Limited token transfer failed on destination chain (a good thing in this context)") + + // Manually execute the rate limited token transfer and expect a similar error + tc.lane.Logger.Info().Str("Wait Time", actions.DefaultPermissionlessExecThreshold.String()).Msg("Waiting for Exec Threshold to Expire") + time.Sleep(actions.DefaultPermissionlessExecThreshold) // Give time to exit the window + // See above comment on timeout + err = tc.lane.ExecuteManually(actions.WithConfirmationTimeout(time.Minute)) + require.Error(t, err, "There should be errors executing manually at this point") + tc.lane.Logger.Debug().Str("Error", err.Error()).Msg("Manually executed rate limited token transfer failed as expected") + + // Change limits to make it viable + err = dest.OffRamp.SetRateLimit(contracts.RateLimiterConfig{ + IsEnabled: true, + Capacity: new(big.Int).Mul(capacityLimit, big.NewInt(100)), + Rate: new(big.Int).Mul(capacityLimit, big.NewInt(100)), + }) + require.NoError(t, err, "Error setting destination rate limits") + err = dest.Common.ChainClient.WaitForEvents() + require.NoError(t, err, "Error waiting for events") + + // Execute again manually and expect a pass + err = tc.lane.ExecuteManually() + require.NoError(t, err, "Error manually executing transaction after rate limit is lifted") + }) + } + +} diff --git a/integration-tests/ccip-tests/testconfig/README.md b/integration-tests/ccip-tests/testconfig/README.md new file mode 100644 index 0000000000..c32aee3d91 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/README.md @@ -0,0 +1,700 @@ +# CCIP Configuration + +The CCIP configuration is used to specify the test configuration for running the CCIP integration tests. +The configuration is specified in a TOML file. The configuration is used to specify the test environment, test type, test parameters, and other necessary details for running the tests. +The test config is read in following order: +- The test reads the default configuration from [ccip-default.toml](./tomls/ccip-default.toml). +- The default can be overridden by specifying the test config in a separate file. + - The file content needs to be encoded in base64 format and set in `BASE64_CCIP_CONFIG_OVERRIDE` environment variable. + - The config mentioned in this file will override the default config. + - Example override file - [override.toml.example](./examples/override.toml.example) +- If there are sensitive details like private keys, credentials in test config, they can be specified in a separate secret file. + - The file content needs to be encoded in base64 format and set in `BASE64_CCIP_SECRETS_CONFIG` environment variable. + - The config mentioned in this file will override the default and override config. + - Example secret file - [secrets.toml.example](./examples/secrets.toml.example) + +## CCIP.ContractVersions +Specifies contract versions of different contracts to be referred by test. +Supported versions are: +- **PriceRegistry**: '1.2.0', 'Latest' +- **OffRamp**: '1.2.0', 'Latest' +- **OnRamp**: '1.2.0', 'Latest' +- **TokenPool**: '1.4.0', 'Latest' +- **CommitStore**: '1.2.0', 'Latest' + +Example Usage: +```toml +[CCIP.ContractVersions] +PriceRegistry = "1.2.0" +OffRamp = "1.2.0" +OnRamp = "1.2.0" +TokenPool = "1.4.0" +CommitStore = "1.2.0" +``` + +## CCIP.Deployments +CCIP Deployment contains all necessary contract addresses for various networks. This is mandatory if the test are to be run for [existing deployments](#ccipgroupstestgroupexistingdeployment) +The deployment data can be specified - + - Under `CCIP.Deployments.Data` field with value as stringify format of json. + - Under `CCIP.Deployments.DataFile` field with value as the path of the file containing the deployment data in json format. + +The json schema is specified in https://github.com/smartcontractkit/ccip/blob/ccip-develop/integration-tests/ccip-tests/contracts/laneconfig/parse_contracts.go#L96 + +Example Usage: +```toml +[CCIP.Deployments] +Data = """ +{ + "lane_configs": { + "Arbitrum Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4", + "bridge_tokens": ["0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"], + "bridge_tokens_pools": ["0x82aF49947D8a07e3bd95BD0d56f35241523fBab1"], + "arm": "0xe06b0e8c4bd455153e8794ad7Ea8Ff5A14B64E4b", + "router": "0x141fa059441E0ca23ce184B6A78bafD2A517DdE8", + "price_registry": "0x13015e4E6f839E1Aa1016DF521ea458ecA20438c", + "wrapped_native": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "src_contracts": { + "Ethereum Mainnet": { + "on_ramp": "0xCe11020D56e5FDbfE46D9FC3021641FfbBB5AdEE", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Ethereum Mainnet": { + "off_ramp": "0x542ba1902044069330e8c5b36A84EC503863722f", + "commit_store": "0x060331fEdA35691e54876D957B4F9e3b8Cb47d20", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Ethereum Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x514910771AF9Ca656af840dff83E8264EcF986CA", + "bridge_tokens": ["0x8B63b3DE93431C0f756A493644d128134291fA1b"], + "bridge_tokens_pools": ["0x8B63b3DE93431C0f756A493644d128134291fA1b"], + "arm": "0x8B63b3DE93431C0f756A493644d128134291fA1b", + "router": "0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D", + "price_registry": "0x8c9b2Efb7c64C394119270bfecE7f54763b958Ad", + "wrapped_native": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x925228D7B82d883Dde340A55Fe8e6dA56244A22C", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0xeFC4a18af59398FF23bfe7325F2401aD44286F4d", + "commit_store": "0x9B2EEd6A1e16cB50Ed4c876D2dD69468B21b7749", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + } + } +} +""" +``` +Or +```toml +[CCIP.Deployments] +DataFile = '' +``` + +## CCIP.Env +Specifies the environment details for the test to be run on. +Mandatory fields are: +- **Networks**: [CCIP.Env.Networks](#ccipenvnetworks) +- **NewCLCluster**: [CCIP.Env.NewCLCluster](#ccipenvnewclcluster) - This is mandatory if the test needs to deploy Chainlink nodes. +- **ExistingCLCluster**: [CCIP.Env.ExistingCLCluster](#ccipenvexistingclcluster) - This is mandatory if the test needs to run on existing Chainlink nodes to deploy ccip jobs. + +Test needs network/chain details to be set through configuration. This configuration is mandatory for running the tests. +you have option to set the network details in two ways: +1. Using [CCIP.Env.Networks](#ccipenvnetworks) +2. Using a separate network config file - + * refer to the example - [network_config.toml.example](./examples/network_config.toml.example) + * once all necessary values are set, encode the toml file content in base64 format, + * set the base64'ed string content in `BASE64_NETWORK_CONFIG` environment variable. + +### CCIP.Env.Networks +Specifies the network details for the test to be run. +The NetworkConfig is imported from https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/network.go#L39 + +#### CCIP.Env.Networks.selected_networks +It denotes the network names in which tests will be run. These networks are used to deploy ccip contracts and set up lanes between them. +If more than 2 networks are specified, then lanes will be set up between all possible pairs of networks. + +For example , if `selected_networks = ['SIMULATED_1', 'SIMULATED_2', 'SIMULATED_3']`, it denotes that lanes will be set up between SIMULATED_1 and SIMULATED_2, SIMULATED_1 and SIMULATED_3, SIMULATED_2 and SIMULATED_3 +This behaviour can be varied based on [NoOfNetworks](#ccipgroupstestgroupnoofnetworks), [NetworkPairs](#ccipgroupstestgroupnetworkpairs), [MaxNoOfLanes](#ccipgroupstestgroupmaxnooflanes) fields in test config. + +The name of the networks are taken from [known_networks](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/networks/known_networks.go#L884) in chainlink-testing-framework +If the network is not present in known_networks, then the network details can be specified in the config file itself under the following `EVMNetworks` key. + +#### CCIP.Env.Network.EVMNetworks +Specifies the network config to be used while creating blockchain EVMClient for test. +It is a map of network name to EVMNetworks where key is network name specified under `CCIP.Env.Networks.selected_networks` and value is `EVMNetwork`. +The EVMNetwork is imported from [EVMNetwork](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/blockchain/config.go#L43) in chainlink-testing-framework. + +If `CCIP.Env.Network.EVMNetworks` config is not set for a network name specified under `CCIP.Env.Networks.selected_networks`, test will try to find the corresponding network config from defined networks in `MappedNetworks` under [known_networks.go](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/networks/known_networks.go) + +#### CCIP.Env.Network.AnvilConfigs +If the test needs to run on chains created using Anvil, then the AnvilConfigs can be specified. +It is a map of network name to `AnvilConfig` where key is network name specified under `CCIP.Env.Networks.selected_networks` and value is `AnvilConfig`. +The AnvilConfig is imported from [AnvilConfig](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/network.go#L20) in chainlink-testing-framework. + + +**The following network configs are required for tests running on live networks. It can be ignored if the tests are running on simulated networks.** +Refer to [secrets.toml.example](./examples/secrets.toml.example) for details. + +#### CCIP.ENV.Network.RpcHttpUrls +RpcHttpUrls is the RPC HTTP endpoints for each network, key is the network name as declared in selected_networks slice. + +#### CCIP.ENV.Network.RpcWsUrls +RpcWsUrls is the RPC WS endpoints for each network, key is the network name as declared in selected_networks slice. + +#### CCIP.ENV.Network.WalletKeys +WalletKeys is the private keys for each network, key is the network name as declared in selected_networks slice. + +Example Usage of Network Config: + +```toml +[CCIP.Env.Network] +selected_networks= ['PRIVATE-CHAIN-1', 'PRIVATE-CHAIN-2'] + +[CCIP.Env.Network.EVMNetworks.PRIVATE-CHAIN-1] +evm_name = 'private-chain-1' +evm_chain_id = 2337 +evm_urls = ['wss://ignore-this-url.com'] +evm_http_urls = ['https://ignore-this-url.com'] +evm_keys = ['59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 400 + +[CCIP.Env.Network.EVMNetworks.PRIVATE-CHAIN-2] +evm_name = 'private-chain-2' +evm_chain_id = 1337 +evm_urls = ['wss://ignore-this-url.com'] +evm_http_urls = ['https://ignore-this-url.com'] +evm_keys = ['ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 400 + +[CCIP.Env.Network.AnvilConfigs.PRIVATE-CHAIN-1] +block_time = 1 + +[CCIP.Env.Network.AnvilConfigs.PRIVATE-CHAIN-2] +block_time = 1 +``` + +### CCIP.Env.NewCLCluster +The NewCLCluster config holds the overall deployment configuration for Chainlink nodes. + +#### CCIP.Env.NewCLCluster.NoOfNodes +Specifies the number of Chainlink nodes to be deployed. + +#### CCIP.Env.NewCLCluster.Common +Specifies the common configuration for all Chainlink nodes if they share the same configuration. +##### Name: +Name of the node. +##### NeedsUpgrade: +Indicates if the node needs an upgrade during test. +##### ChainlinkImage: +Configuration for the Chainlink image. + +##### ChainlinkUpgradeImage: +Configuration for the Chainlink upgrade image. It is used when the node needs an upgrade. + +##### BaseConfigTOML: +String containing the base configuration toml content for the Chainlink node config. + +##### CommonChainConfigTOML: +String containing the common chain configuration toml content for all EVMNodes in chainlink node config. + +##### ChainConfigTOMLByChain: +String containing the chain-specific configuration toml content for individual EVMNodes in chainlink node config. This is keyed by chain ID. + +##### DBImage: +Database image for the Chainlink node. + +##### DBTag: +Database tag/version for the Chainlink node. + +#### CCIP.Env.NewCLCluster.Nodes +Specifies the configuration for individual nodes if they differ from the common configuration. The fields are the same as the common configuration. + +#### CCIP.Env.NewCLCluster.NodeMemory +Specifies the memory to be allocated for each Chainlink node. This is valid only if the deployment is on Kubernetes. + +#### CCIP.Env.NewCLCluster.NodeCPU +Specifies the CPU to be allocated for each Chainlink node. This is valid only if the deployment is on Kubernetes. + +#### CCIP.Env.NewCLCluster.DBMemory +Specifies the memory to be allocated for the database. This is valid only if the deployment is on Kubernetes. + +#### CCIP.Env.NewCLCluster.DBCPU +Specifies the CPU to be allocated for the database. This is valid only if the deployment is on Kubernetes. + +#### CCIP.Env.NewCLCluster.IsStateful +Specifies whether the deployment is StatefulSet on Kubernetes. + +#### CCIP.Env.NewCLCluster.DBStorageClass +Specifies the storage class for the database. This is valid only if the deployment is StatefulSet on Kubernetes. + +#### CCIP.Env.NewCLCluster.DBCapacity +Specifies the capacity of the database. This is valid only if the deployment is StatefulSet on Kubernetes. + +#### CCIP.Env.NewCLCluster.PromPgExporter +Specifies whether to enable Prometheus PostgreSQL exporter. This is valid only if the deployment is on Kubernetes. + +#### CCIP.Env.NewCLCluster.DBArgs +Specifies the arguments to be passed to the database. This is valid only if the deployment is on Kubernetes. + +Example Usage: +```toml +[CCIP.Env.NewCLCluster] +NoOfNodes = 17 +NodeMemory = '12Gi' +NodeCPU = '6' +DBMemory = '10Gi' +DBCPU = '2' +DBStorageClass = 'gp3' +PromPgExporter = true +DBCapacity = '50Gi' +IsStateful = true +DBArgs = ['shared_buffers=2048MB', 'effective_cache_size=4096MB', 'work_mem=64MB'] + +[CCIP.Env.NewCLCluster.Common] +Name = 'node1' +DBImage = 'postgres' +DBTag = '13.12' +CommonChainConfigTOML = """ +[HeadTracker] +HistoryDepth = 400 + +[GasEstimator] +PriceMax = '200 gwei' +LimitDefault = 6000000 +FeeCapDefault = '200 gwei' +""" +``` + +### CCIP.Env.ExistingCLCluster +The ExistingCLCluster config holds the overall connection configuration for existing Chainlink nodes. +It is needed when the tests are to be run on Chainlink nodes already deployed on some environment. +If this is specified, test will not need to connect to k8 namespace using [CCIP.Env.EnvToConnect](#ccipenvenvtoconnect) . +Test can directly connect to the existing Chainlink nodes using node credentials without knowing the k8 namespace details. + +#### CCIP.Env.ExistingCLCluster.Name +Specifies the name of the existing Chainlink cluster. This is used to identify the cluster in the test. + +#### CCIP.Env.ExistingCLCluster.NoOfNodes +Specifies the number of Chainlink nodes in the existing cluster. + +#### CCIP.Env.ExistingCLCluster.NodeConfigs +Specifies the configuration for individual nodes in the existing cluster. Each node config contains the following fields to connect to the Chainlink node: +##### CCIP.Env.ExistingCLCluster.NodeConfigs.URL +The URL of the Chainlink node. +##### CCIP.Env.ExistingCLCluster.NodeConfigs.Email +The username/email of the Chainlink node credential. +##### CCIP.Env.ExistingCLCluster.NodeConfigs.Password +The password of the Chainlink node credential. +##### CCIP.Env.ExistingCLCluster.NodeConfigs.InternalIP +The internal IP of the Chainlink node. + +Example Usage: +```toml +[CCIP.Env.ExistingCLCluster] +Name = 'crib-sample' +NoOfNodes = 5 + +[[CCIP.Env.ExistingCLCluster.NodeConfigs]] +URL = 'https://crib-sample-demo-node1.main.stage.cldev.sh/' +Email = 'notreal@fakeemail.ch' +Password = 'fj293fbBnlQ!f9vNs' +InternalIP = 'app-node-1' + + +[[CCIP.Env.ExistingCLCluster.NodeConfigs]] +URL = 'https://crib-sample-demo-node2.main.stage.cldev.sh/' +Email = 'notreal@fakeemail.ch' +Password = 'fj293fbBnlQ!f9vNs' +InternalIP = 'app-node-2' + +[[CCIP.Env.ExistingCLCluster.NodeConfigs]] +URL = 'https://crib-sample-demo-node3.main.stage.cldev.sh/' +Email = 'notreal@fakeemail.ch' +Password = 'fj293fbBnlQ!f9vNs' +InternalIP = 'app-node-3' + +[[CCIP.Env.ExistingCLCluster.NodeConfigs]] +URL = 'https://crib-ani-demo-node4.main.stage.cldev.sh/' +Email = 'notreal@fakeemail.ch' +Password = 'fj293fbBnlQ!f9vNs' +InternalIP = 'app-node-4' + +[[CCIP.Env.ExistingCLCluster.NodeConfigs]] +URL = 'https://crib-sample-demo-node5.main.stage.cldev.sh/' +Email = 'notreal@fakeemail.ch' +Password = 'fj293fbBnlQ!f9vNs' +InternalIP = 'app-node-5' +``` + +### CCIP.Env.EnvToConnect +This is specified when the test needs to connect to already existing k8s namespace. User needs to have access to the k8 namespace to run the tests through specific kubeconfig file. +Example usage: +```toml +[CCIP.Env] +EnvToConnect="load-ccip-c8972" +``` +### CCIP.ENV.TTL +Specifies the time to live for the k8 namespace. This is used to terminate the namespace after the tests are run. This is only valid if the tests are run on k8s. +Example usage: +```toml +[CCIP.Env] +TTL = "11h" +``` + +### CCIP.Env.Logging +Specifies the logging configuration for the test. Imported from [LoggingConfig](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/logging.go#L11) in chainlink-testing-framework. +Example usage: +```toml +[CCIP.Env.Logging] +test_log_collect = false # if set to true will save logs even if test did not fail + +[CCIP.Env.Logging.LogStream] +# supported targets: file, loki, in-memory. if empty no logs will be persistet +log_targets = ["file"] +# context timeout for starting log producer and also time-frame for requesting logs +log_producer_timeout = "10s" +# number of retries before log producer gives up and stops listening to logs +log_producer_retry_limit = 10 + +[CCIP.Env.Logging.Loki] +tenant_id = "..." +endpoint = "https://loki...." + +[CCIP.Env.Logging.Grafana] +base_url = "https://grafana..../" +dashboard_url = "/d/6vjVx-1V8/ccip-long-running-tests" +``` + +### CCIP.Env.Lane.LeaderLaneEnabled +Specifies whether to enable the leader lane feature. This setting is only applicable for new deployments. + +## CCIP.Groups +Specifies the test config specific to each test type. Available test types are: +- **CCIP.Groups.load** +- **CCIP.Groups.smoke** +- **CCIP.Groups.chaos** + +### CCIP.Groups.[testgroup].KeepEnvAlive +Specifies whether to keep the k8 namespace alive after the test is run. This is only valid if the tests are run on k8s. + +### CCIP.Groups.[testgroup].BiDirectionalLane +Specifies whether to set up bi-directional lanes between networks. + +### CCIP.Groups.[testgroup].CommitAndExecuteOnSameDON +Specifies whether commit and execution jobs are to be run on the same Chainlink node. + +### CCIP.Groups.[testgroup].NoOfCommitNodes +Specifies the number of nodes on which commit jobs are to be run. This needs to be lesser than the total number of nodes mentioned in [CCIP.Env.NewCLCluster.NoOfNodes](#ccipenvnewclclusternoofnodes) or [CCIP.Env.ExistingCLCluster.NoOfNodes](#ccipenvexistingclclusternoofnodes). +If the value of total nodes is `n`, then the max value of NoOfCommitNodes should be less than `n-1`. As the first node is used for bootstrap job. +If the NoOfCommitNodes is lesser than `n-1`, then the remaining nodes are used for execution jobs if `CCIP.Groups.[testgroup].CommitAndExecuteOnSameDON` is set to false. + +### CCIP.Groups.[testgroup].TokenConfig +Specifies the token configuration for the test. The token configuration is used to set up tokens and token pools for all chains. + +#### CCIP.Groups.[testgroup].TokenConfig.NoOfTokensPerChain +Specifies the number of tokens to be set up for each chain. + +#### CCIP.Groups.[testgroup].TokenConfig.WithPipeline +Specifies whether to set up token pipelines in commit jobspec. If set to false, the token prices will be set with DynamicPriceGetterConfig. + +#### CCIP.Groups.[testgroup].TokenConfig.TimeoutForPriceUpdate +Specifies the timeout to wait for token and gas price updates to be available in price registry for each chain. + +#### CCIP.Groups.[testgroup].TokenConfig.NoOfTokensWithDynamicPrice +Specifies the number of tokens to be set up with dynamic price update. The rest of the tokens will be set up with static price. This is only valid if [WithPipeline](#ccipgroupstestgrouptokenconfigwithpipeline) is set to false. + +#### CCIP.Groups.[testgroup].TokenConfig.DynamicPriceUpdateInterval +Specifies the interval for dynamic price update for tokens. This is only valid if [NoOfTokensWithDynamicPrice](#ccipgroupstestgrouptokenconfignooftokenswithdynamicprice) is set to value greater tha zero. + +#### CCIP.Groups.[testgroup].TokenConfig.CCIPOwnerTokens +Specifies the tokens to be owned by the CCIP owner. If this is false, the tokens and pools will be owned by an address other than rest of CCIP contract admin addresses. +This is applicable only if the contract versions are '1.5' or higher. + +Example Usage: +```toml + +[CCIP.Groups.load.TokenConfig] +TimeoutForPriceUpdate = '15m' +NoOfTokensPerChain = 60 +NoOfTokensWithDynamicPrice = 15 +DynamicPriceUpdateInterval ='15s' +CCIPOwnerTokens = true +``` + +### CCIP.Groups.[testgroup].MsgDetails +Specifies the ccip message details to be sent by the test. +#### CCIP.Groups.[testgroup].MsgDetails.MsgType +Specifies the type of message to be sent. The supported message types are: +- **Token** +- **Data** +- **DataWithToken** + +#### CCIP.Groups.[testgroup].MsgDetails.DestGasLimit +Specifies the gas limit for the destination chain. This is used to in `ExtraArgs` field of CCIPMessage. Change this to 0, if you are doing ccip-send to an EOA in the destination chain. + +#### CCIP.Groups.[testgroup].MsgDetails.DataLength +Specifies the length of data to be sent in the message. This is only valid if [MsgType](#ccipgroupstestgroupmsgdetailsmsgtype) is set to 'Data' or 'DataWithToken'. + +#### CCIP.Groups.[testgroup].MsgDetails.NoOfTokens +Specifies the number of tokens to be sent in the message. This is only valid if [MsgType](#ccipgroupstestgroupmsgdetailsmsgtype) is set to 'Token' or 'DataWithToken'. +It needs to be less than or equal to [NoOfTokensPerChain](#ccipgroupstestgrouptokenconfignooftokensperchain) specified in the test config. + +#### CCIP.Groups.[testgroup].MsgDetails.TokenAmount +Specifies the amount for each token to be sent in the message. This is only valid if [MsgType](#ccipgroupstestgroupmsgdetailsmsgtype) is set to 'Token' or 'DataWithToken'. + +Example Usage: +```toml +[CCIP.Groups.smoke.MsgDetails] +MsgType = 'DataWithToken' +DestGasLimit = 100000 +DataLength = 1000 +NoOfTokens = 2 +AmountPerToken = 1 +``` + +### CCIP.Groups.[testgroup].MulticallInOneTx +Specifies whether to send multiple ccip messages in a single transaction. + +### CCIP.Groups.[testgroup].NoOfSendsInMulticall +Specifies the number of ccip messages to be sent in a single transaction. This is only valid if [MulticallInOneTx](#ccipgroupstestgroupmulticallinonetx) is set to true. + +### CCIP.Groups.[testgroup].PhaseTimeout +The test validates various events in a ccip request lifecycle, like commit, execute, etc. This field specifies the timeout for each phase in the lifecycle. +The timeout is calculated from the time the previous phase event is received. +The following contract events are validated: +- **CCIPSendRequested on OnRamp** +- **CCIPSendRequested event log to be Finalized** +- **ReportAccepted on CommitStore** +- **TaggedRootBlessed on ARM/RMN** +- **ExecutionStateChanged on OffRamp** + +### CCIP.Groups.[testgroup].LocalCluster +Specifies whether the test is to be run on a local docker. If set to true, the test environment will be set up on a local docker. + +### CCIP.Groups.[testgroup].ExistingDeployment +Specifies whether the test is to be run on existing deployments. If set to true, the test will use the deployment data specified in [CCIP.Deployments](#ccipdeployments) for interacting with the ccip contracts. +If the deployment data does not contain the required contract addresses, the test will fail. + +### CCIP.Groups.[testgroup].ReuseContracts +Test loads contract/lane config from [contracts.json](../contracts/laneconfig/contracts.json) if no lane config is specified in [CCIP.Deployments](#ccipdeployments) +If a certain contract is present in the contracts.json, the test will use the contract address from the contracts.json. +This field specifies whether to reuse the contracts from [contracts.json](../contracts/laneconfig/contracts.json) +For example if the contracts.json contains the contract address for PriceRegistry for `Arbitrum Mainnet`, the test by default will use the contract address from contracts.json instead of redeploying the contract. +If `ReuseContracts` is set to false, the test will redeploy the contract instead of using the contract address from contracts.json. + +### CCIP.Groups.[testgroup].NodeFunding +Specified the native token funding for each Chainlink node. It assumes that the native token decimals is 18. +The funding is done by the private key specified in [CCIP.Env.Networks](#ccipenvnetworks) for each network. +The funding is done only if the test is run on local docker or k8s. This is not applicable for [existing deployments](#ccipgroupstestgroupexistingdeployment) is set to true. + +### CCIP.Groups.[testgroup].NetworkPairs +Specifies the network pairs for which the test is to be run. The test will set up lanes only between the specified network pairs. +If the network pairs are not specified, the test will set up lanes between all possible pairs of networks mentioned in selected_networks in [CCIP.Env.Networks](#ccipenvnetworksselectednetworks) + +### CCIP.Groups.[testgroup].NoOfNetworks +Specifies the number of networks to be used for the test. +If the number of networks is greater than the total number of networks specified in [CCIP.Env.Networks.selected_networks](#ccipenvnetworksselectednetworks) : +- the test will fail if the networks are live networks. +- the test will create equal number of replicas of the first network with a new chain id if the networks are simulated networks. + For example, if the `selected_networks` is ['SIMULATED_1','SIMULATED_2'] and `NoOfNetworks` is 3, the test will create 1 more network config by copying the network config of `SIMULATED_1` with a different chain id and use that as 3rd network. + +### CCIP.Groups.[testgroup].NoOfRoutersPerPair +Specifies the number of routers to be set up for each network. + +### CCIP.Groups.[testgroup].MaxNoOfLanes +Specifies the maximum number of lanes to be set up between networks. If this values is not set, the test will set up lanes between all possible pairs of networks mentioned in `selected_networks` in [CCIP.Env.Networks](#ccipenvnetworksselectednetworks). +For example, if `selected_networks = ['SIMULATED_1', 'SIMULATED_2', 'SIMULATED_3']`, and `MaxNoOfLanes` is set to 2, it denotes that the test will randomly select the 2 lanes between all possible pairs `SIMULATED_1`, `SIMULATED_2`, and `SIMULATED_3` for the test run. + +### CCIP.Groups.[testgroup].DenselyConnectedNetworkChainIds +This is applicable only if [MaxNoOfLanes](#ccipgroupstestgroupmaxnooflanes) is specified. +Specifies the chain ids for networks to be densely connected. If this is provided the test will include all possible pairs of networks mentioned in `DenselyConnectedNetworkChainIds`. +The rest of the networks will be connected randomly based on the value of `MaxNoOfLanes`. + +### CCIP.Groups.[testgroup].ChaosDuration +Specifies the duration for which the chaos experiment is to be run. This is only valid if the test type is 'chaos'. + +### CCIP.Groups.[testgroup].USDCMockDeployment +Specifies whether to deploy USDC mock contract for the test. This is only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). + +The following fields are used for various parameters in OCR2 commit and execution jobspecs. All of these are only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). +### CCIP.Groups.[testgroup].CommitOCRParams +Specifies the OCR parameters for the commit job. This is only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). + +### CCIP.Groups.[testgroup].ExecuteOCRParams +Specifies the OCR parameters for the execute job. This is only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). + +### CCIP.Groups.[testgroup].CommitInflightExpiry +Specifies the value for the `InflightExpiry` in commit job's offchain config. This is only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). + +### CCIP.Groups.[testgroup].OffRampConfig +Specifies the offramp configuration for the execution job. This is only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). +This is used to set values for following fields in execution jobspec's offchain and onchain config: +- **OffRampConfig.MaxDataBytes** +- **OffRampConfig.BatchGasLimit** +- **OffRampConfig.InflightExpiry** +- **OffRampConfig.RootSnooze** + +Example Usage: +```toml +[CCIP.Groups.load] +CommitInflightExpiry = '5m' + +[CCIP.Groups.load.CommitOCRParams] +DeltaProgress = '2m' +DeltaResend = '5s' +DeltaRound = '75s' +DeltaGrace = '5s' +MaxDurationQuery = '100ms' +MaxDurationObservation = '35s' +MaxDurationReport = '10s' +MaxDurationShouldAcceptFinalizedReport = '5s' +MaxDurationShouldTransmitAcceptedReport = '10s' + +[CCIP.Groups.load.ExecOCRParams] +DeltaProgress = '2m' +DeltaResend = '5s' +DeltaRound = '75s' +DeltaGrace = '5s' +MaxDurationQuery = '100ms' +MaxDurationObservation = '35s' +MaxDurationReport = '10s' +MaxDurationShouldAcceptFinalizedReport = '5s' +MaxDurationShouldTransmitAcceptedReport = '10s' + +[CCIP.Groups.load.OffRampConfig] +BatchGasLimit = 11000000 +MaxDataBytes = 1000 +InflightExpiry = '5m' +RootSnooze = '5m' + +``` + +### CCIP.Groups.[testgroup].StoreLaneConfig +This is only valid if the tests are run on remote runners in k8s. If set to true, the test will store the lane config in the remote runner. + +### CCIP.Groups.[testgroup].LoadProfile +Specifies the load profile for the test. Only valid if the testgroup is 'load'. + +### CCIP.Groups.[testgroup].LoadProfile.LoadFrequency.[DestNetworkName] + +#### CCIP.Groups.[testgroup].LoadProfile.RequestPerUnitTime +Specifies the number of requests to be sent per unit time. This is applicable to all networks if [LoadFrequency](#ccipgroupstestgrouploadprofileloadfrequencydestnetworkname) is not specified for a destination network. + +#### CCIP.Groups.[testgroup].LoadProfile.TimeUnit +Specifies the unit of time for the load profile. This is applicable to all networks if [LoadFrequency](#ccipgroupstestgrouploadprofileloadfrequencydestnetworkname) is not specified for a destination network. + +#### CCIP.Groups.[testgroup].LoadProfile.StepDuration +Specifies the duration for each step in the load profile. This is applicable to all networks if [LoadFrequency](#ccipgroupstestgrouploadprofileloadfrequencydestnetworkname) is not specified for a destination network. + +#### CCIP.Groups.[testgroup].LoadProfile.TestDuration +Specifies the total duration for the load test. + +#### CCIP.Groups.[testgroup].LoadProfile.NetworkChaosDelay +Specifies the duration network delay used for `NetworkChaos` experiment. This is only valid if the test is run on k8s and not on [existing deployments](#ccipgroupstestgroupexistingdeployment). + +#### CCIP.Groups.[testgroup].LoadProfile.WaitBetweenChaosDuringLoad +If there are multiple chaos experiments, this specifies the duration to wait between each chaos experiment. This is only valid if the test is run on k8s and not on [existing deployments](#ccipgroupstestgroupexistingdeployment). + +#### CCIP.Groups.[testgroup].LoadProfile.SkipRequestIfAnotherRequestTriggeredWithin +If a request is triggered within this duration, the test will skip sending another request during load run. For Example, if `SkipRequestIfAnotherRequestTriggeredWithin` is set to `40m`, and a request is triggered at 0th second, the test will skip sending another request for another 40m. +This particular field is used to avoid sending multiple requests in a short duration during load run. + +#### CCIP.Groups.[testgroup].LoadProfile.OptimizeSpace +This is used internally to optimize memory usage during load run. If set to true, after the initial lane set up is over the test will discard the lane config to save memory. +The test will only store contract addresses strictly necessary to trigger/validate ccip-send requests. +Except for following contracts all other contract addresses will be discarded after the initial lane set up - +- Router +- ARM +- CommitStore +- OffRamp +- OnRamp + +#### CCIP.Groups.[testgroup].LoadProfile.FailOnFirstErrorInLoad +If set to true, the test will fail on the first error encountered during load run. If set to false, the test will continue to run even if there are errors during load run. + +#### CCIP.Groups.[testgroup].LoadProfile.SendMaxDataInEveryMsgCount +Specifies the number of requests to send with maximum data in every mentioned count iteration. +For example, if `SendMaxDataInEveryMsgCount` is set to 5, the test will send ccip message with max allowable data length(as set in onRamp config) in every 5th request. + +#### CCIP.Groups.[testgroup].LoadProfile.TestRunName +Specifies the name of the test run. This is used to identify the test run in CCIP test dashboard or logs. If multiple tests are run with same `TestRunName`, the test results will be aggregated under the same test run in grafana dashboard. +This is used when multiple iterations of tests are run against same release version to aggregate the results under same dashboard view. + +#### CCIP.Groups.[testgroup].LoadProfile.MsgProfile +Specifies the message profile for the test. The message profile is used to set up multiple ccip message details during load test. + +##### CCIP.Groups.[testgroup].LoadProfile.MsgProfile.Frequencies +Specifies the frequency of each message profile. +For example, if `Frequencies` is set to [1, 2, 3], the test will send 1st message profile 1 time, 2nd message profile 2 times, and 3rd message profile 3 times in each iteration. Each iteration will be defined by (1+2+3) = 6 requests. +Example Breakdown: +- Frequencies = [4, 12, 3, 1] +- Total Sum of Frequencies = 4 + 12 + 3 + 1 = 20 +- Percentages: + - Message Type 1: (4 / 20) * 100% = 20% + - Message Type 2: (12 / 20) * 100% = 60% + - Message Type 3: (3 / 20) * 100% = 15% + - Message Type 4: (1 / 20) * 100% = 5% + These percentages reflect how often each message type should appear in the total set of messages. + Please note - if the total set of messages is not equal to the multiple of sum of frequencies, the percentages will not be accurate. + +##### CCIP.Groups.[testgroup].LoadProfile.MsgProfile.MsgDetails +Specifies the message details for each message profile. The fields are the same as [CCIP.Groups.[testgroup].MsgDetails](#ccipgroupstestgroupmsgdetails). + +example usage: +```toml +# to represent 20%, 60%, 15%, 5% of the total messages +[CCIP.Groups.load.LoadProfile.MsgProfile] +Frequencies = [4,12,3,1] + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Token' +DestGasLimit = 0 +DataLength = 0 +NoOfTokens = 5 +AmountPerToken = 1 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'DataWithToken' +DestGasLimit = 500000 +DataLength = 5000 +NoOfTokens = 5 +AmountPerToken = 1 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 800000 +DataLength = 10000 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 2500000 +DataLength = 10000 +``` \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/ccip.go b/integration-tests/ccip-tests/testconfig/ccip.go new file mode 100644 index 0000000000..60d7055cb3 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/ccip.go @@ -0,0 +1,416 @@ +package testconfig + +import ( + "fmt" + "math/big" + "os" + + "github.com/AlekSi/pointer" + "github.com/pelletier/go-toml/v2" + "github.com/rs/zerolog" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/config" + ctfK8config "github.com/smartcontractkit/chainlink-testing-framework/k8s/config" + + ccipcontracts "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts" + testutils "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/utils" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" +) + +const ( + CONTRACTS_OVERRIDE_CONFIG string = "BASE64_CCIP_CONFIG_OVERRIDE_CONTRACTS" + TokenOnlyTransfer string = "Token" + DataOnlyTransfer string = "Data" + DataAndTokenTransfer string = "DataWithToken" +) + +type OffRampConfig struct { + MaxDataBytes *uint32 `toml:",omitempty"` + BatchGasLimit *uint32 `toml:",omitempty"` + InflightExpiry *config.Duration `toml:",omitempty"` + RootSnooze *config.Duration `toml:",omitempty"` +} + +type MsgDetails struct { + MsgType *string `toml:",omitempty"` + DestGasLimit *int64 `toml:",omitempty"` + DataLength *int64 `toml:",omitempty"` + NoOfTokens *int `toml:",omitempty"` + AmountPerToken *int64 `toml:",omitempty"` +} + +func (m *MsgDetails) IsTokenTransfer() bool { + return pointer.GetString(m.MsgType) == "Token" || pointer.GetString(m.MsgType) == "DataWithToken" +} + +func (m *MsgDetails) IsDataTransfer() bool { + return pointer.GetString(m.MsgType) == "Data" || pointer.GetString(m.MsgType) == "DataWithToken" +} + +func (m *MsgDetails) TransferAmounts() []*big.Int { + var transferAmounts []*big.Int + if m.IsTokenTransfer() { + for i := 0; i < pointer.GetInt(m.NoOfTokens); i++ { + transferAmounts = append(transferAmounts, big.NewInt(pointer.GetInt64(m.AmountPerToken))) + } + } + return transferAmounts +} + +func (m *MsgDetails) Validate() error { + if m == nil { + return fmt.Errorf("msg details should be set") + } + if m.MsgType == nil { + return fmt.Errorf("msg type should be set") + } + if m.IsDataTransfer() { + if m.DataLength == nil || *m.DataLength == 0 { + return fmt.Errorf("data length should be set and greater than 0") + } + } + if m.DestGasLimit == nil { + return fmt.Errorf("destination gas limit should be set") + } + if pointer.GetString(m.MsgType) != DataOnlyTransfer && + pointer.GetString(m.MsgType) != TokenOnlyTransfer && + pointer.GetString(m.MsgType) != DataAndTokenTransfer { + return fmt.Errorf("msg type should be - %s/%s/%s", DataOnlyTransfer, TokenOnlyTransfer, DataAndTokenTransfer) + } + + if m.IsTokenTransfer() { + if pointer.GetInt64(m.AmountPerToken) == 0 { + return fmt.Errorf("token amount should be greater than 0") + } + + if pointer.GetInt(m.NoOfTokens) == 0 { + return fmt.Errorf("number of tokens in msg should be greater than 0") + } + } + + return nil +} + +// TokenConfig defines the configuration for tokens in a CCIP test group +type TokenConfig struct { + NoOfTokensPerChain *int `toml:",omitempty"` + WithPipeline *bool `toml:",omitempty"` + TimeoutForPriceUpdate *config.Duration `toml:",omitempty"` + NoOfTokensWithDynamicPrice *int `toml:",omitempty"` + DynamicPriceUpdateInterval *config.Duration `toml:",omitempty"` + // CCIPOwnerTokens dictates if tokens are deployed and controlled by the default CCIP owner account + // By default, all tokens are deployed and owned by a separate address + CCIPOwnerTokens *bool `toml:",omitempty"` +} + +func (tc *TokenConfig) IsDynamicPriceUpdate() bool { + return tc.NoOfTokensWithDynamicPrice != nil && *tc.NoOfTokensWithDynamicPrice > 0 +} + +func (tc *TokenConfig) IsPipelineSpec() bool { + return pointer.GetBool(tc.WithPipeline) +} + +func (tc *TokenConfig) Validate() error { + if tc == nil { + return fmt.Errorf("token config should be set") + } + if tc.TimeoutForPriceUpdate == nil || tc.TimeoutForPriceUpdate.Duration().Minutes() == 0 { + return fmt.Errorf("timeout for price update should be set") + } + if tc.NoOfTokensWithDynamicPrice != nil && *tc.NoOfTokensWithDynamicPrice > 0 { + if tc.DynamicPriceUpdateInterval == nil || tc.DynamicPriceUpdateInterval.Duration().Minutes() == 0 { + return fmt.Errorf("dynamic price update interval should be set if NoOfTokensWithDynamicPrice is greater than 0") + } + } + return nil +} + +type MsgProfile struct { + MsgDetails *[]*MsgDetails `toml:",omitempty"` + Frequencies []int `toml:",omitempty"` + matrixByFreq []int + mapMsgDetails map[int]*MsgDetails +} + +// msgDetailsIndexMatrixByFrequency creates a matrix of msg details index based on their frequency +// This matrix is used to select a msg detail based on the iteration number +// For example, if we have 3 msg details (msg1,msg2,msg3) with frequencies 2, 3, 5 respectively, +// the matrixByFreq will be [0,0,1,1,1,2,2,2,2,2] +// and mapMsgDetails will be {0:msg1, 1:msg2, 2:msg3} +// So, for iteration 0, msg1 will be selected, for iteration 1, msg1 will be selected, for iteration 2, msg2 will be selected and so on +// This is useful to select a msg detail based on the iteration number +func (m *MsgProfile) msgDetailsIndexMatrixByFrequency() { + m.mapMsgDetails = make(map[int]*MsgDetails) + for i, msg := range *m.MsgDetails { + m.mapMsgDetails[i] = msg + } + m.matrixByFreq = make([]int, 0) + for i, freq := range m.Frequencies { + for j := 0; j < freq; j++ { + m.matrixByFreq = append(m.matrixByFreq, i) + } + } + // we do not need frequencies and msg details after creating the matrix + m.Frequencies = nil + m.MsgDetails = nil +} + +// MsgDetailsForIteration returns the msg details for the given iteration +// The iteration is used to select the msg details based on their frequency +// Refer to msgDetailsIndexMatrixByFrequency for more details +// If the iteration is greater than the number of matrixByFreq, it will loop back to the first msg detail +// if the final iteration in a load run is lesser than the number of matrixByFreq, there is a chance that some of the msg details might not be selected +func (m *MsgProfile) MsgDetailsForIteration(it int64) *MsgDetails { + index := (it - 1) % int64(len(m.matrixByFreq)) + return m.mapMsgDetails[m.matrixByFreq[index]] +} + +// MsgDetailWithMaxToken returns the msg details with the max no of tokens in the msg profile +func (m *MsgProfile) MsgDetailWithMaxToken() *MsgDetails { + allDetails := *m.MsgDetails + msgDetails := allDetails[0] + for _, msg := range allDetails { + if msg.NoOfTokens != nil && pointer.GetInt(msg.NoOfTokens) > pointer.GetInt(msgDetails.NoOfTokens) { + msgDetails = msg + } + } + return msgDetails +} + +func (m *MsgProfile) Validate() error { + if m == nil { + return fmt.Errorf("msg profile should be set") + } + if m.MsgDetails == nil { + return fmt.Errorf("msg details should be set") + } + allDetails := *m.MsgDetails + if len(allDetails) == 0 { + return fmt.Errorf("msg details should be set") + } + if len(m.Frequencies) == 0 { + return fmt.Errorf("frequencies should be set") + } + if len(allDetails) != len(m.Frequencies) { + return fmt.Errorf("number of msg details %d and frequencies %d should be same", len(allDetails), len(m.Frequencies)) + } + for _, msg := range allDetails { + if err := msg.Validate(); err != nil { + return err + } + } + return nil +} + +type LoadFrequency struct { + RequestPerUnitTime []int64 `toml:",omitempty"` + TimeUnit *config.Duration `toml:",omitempty"` + StepDuration []*config.Duration `toml:",omitempty"` +} + +type LoadProfile struct { + MsgProfile *MsgProfile `toml:",omitempty"` + FrequencyByDestination map[string]*LoadFrequency `toml:",omitempty"` + RequestPerUnitTime []int64 `toml:",omitempty"` + TimeUnit *config.Duration `toml:",omitempty"` + StepDuration []*config.Duration `toml:",omitempty"` + TestDuration *config.Duration `toml:",omitempty"` + NetworkChaosDelay *config.Duration `toml:",omitempty"` + WaitBetweenChaosDuringLoad *config.Duration `toml:",omitempty"` + SkipRequestIfAnotherRequestTriggeredWithin *config.Duration `toml:",omitempty"` + OptimizeSpace *bool `toml:",omitempty"` + FailOnFirstErrorInLoad *bool `toml:",omitempty"` + SendMaxDataInEveryMsgCount *int64 `toml:",omitempty"` + TestRunName string `toml:",omitempty"` +} + +func (l *LoadProfile) Validate() error { + if l == nil { + return fmt.Errorf("load profile should be set") + } + if err := l.MsgProfile.Validate(); err != nil { + return err + } + if len(l.RequestPerUnitTime) == 0 { + return fmt.Errorf("request per unit time should be set") + } + if l.TimeUnit == nil || l.TimeUnit.Duration().Minutes() == 0 { + return fmt.Errorf("time unit should be set") + } + if l.TestDuration == nil || l.TestDuration.Duration().Minutes() == 0 { + return fmt.Errorf("test duration should be set") + } + return nil +} + +func (l *LoadProfile) SetTestRunName(name string) { + if l.TestRunName == "" && name != "" { + l.TestRunName = name + } +} + +// CCIPTestGroupConfig defines configuration input to change how a particular CCIP test group should run +type CCIPTestGroupConfig struct { + Type string `toml:",omitempty"` + KeepEnvAlive *bool `toml:",omitempty"` + BiDirectionalLane *bool `toml:",omitempty"` + CommitAndExecuteOnSameDON *bool `toml:",omitempty"` + NoOfCommitNodes int `toml:",omitempty"` + MsgDetails *MsgDetails `toml:",omitempty"` + TokenConfig *TokenConfig `toml:",omitempty"` + MulticallInOneTx *bool `toml:",omitempty"` + NoOfSendsInMulticall int `toml:",omitempty"` + PhaseTimeout *config.Duration `toml:",omitempty"` + LocalCluster *bool `toml:",omitempty"` + ExistingDeployment *bool `toml:",omitempty"` + ReuseContracts *bool `toml:",omitempty"` + NodeFunding float64 `toml:",omitempty"` + NetworkPairs []string `toml:",omitempty"` + DenselyConnectedNetworkChainIds []string `toml:",omitempty"` + NoOfNetworks int `toml:",omitempty"` + NoOfRoutersPerPair int `toml:",omitempty"` + MaxNoOfLanes int `toml:",omitempty"` + ChaosDuration *config.Duration `toml:",omitempty"` + USDCMockDeployment *bool `toml:",omitempty"` + CommitOCRParams *contracts.OffChainAggregatorV2Config `toml:",omitempty"` + ExecOCRParams *contracts.OffChainAggregatorV2Config `toml:",omitempty"` + OffRampConfig *OffRampConfig `toml:",omitempty"` + CommitInflightExpiry *config.Duration `toml:",omitempty"` + StoreLaneConfig *bool `toml:",omitempty"` + LoadProfile *LoadProfile `toml:",omitempty"` +} + +func (c *CCIPTestGroupConfig) Validate() error { + if c.Type == Load { + if err := c.LoadProfile.Validate(); err != nil { + return err + } + if c.MsgDetails == nil { + c.MsgDetails = c.LoadProfile.MsgProfile.MsgDetailWithMaxToken() + } + c.LoadProfile.MsgProfile.msgDetailsIndexMatrixByFrequency() + if c.ExistingDeployment != nil && *c.ExistingDeployment { + if c.LoadProfile.TestRunName == "" && os.Getenv(ctfK8config.EnvVarJobImage) != "" { + return fmt.Errorf("test run name should be set if existing deployment is true and test is running in k8s") + } + } + } + err := c.MsgDetails.Validate() + if err != nil { + return err + } + if c.PhaseTimeout != nil && (c.PhaseTimeout.Duration().Minutes() < 1 || c.PhaseTimeout.Duration().Minutes() > 50) { + return fmt.Errorf("phase timeout should be between 1 and 50 minutes") + } + + if c.NoOfCommitNodes < 4 { + return fmt.Errorf("insuffcient number of commit nodes provided") + } + if err := c.TokenConfig.Validate(); err != nil { + return err + } + + if c.MsgDetails.IsTokenTransfer() { + if pointer.GetInt(c.TokenConfig.NoOfTokensPerChain) == 0 { + return fmt.Errorf("number of tokens per chain should be greater than 0") + } + } + if c.MulticallInOneTx != nil { + if c.NoOfSendsInMulticall == 0 { + return fmt.Errorf("number of sends in multisend should be greater than 0 if multisend is true") + } + } + + return nil +} + +type CCIPContractConfig struct { + DataFile *string `toml:",omitempty"` + Data string `toml:",omitempty"` +} + +func (c *CCIPContractConfig) DataFilePath() string { + return pointer.GetString(c.DataFile) +} + +// ContractsData reads the contract config passed in TOML +// CCIPContractConfig can accept contract config in string mentioned in Data field +// It also accepts DataFile. Data takes precedence over DataFile +// If you are providing contract config in DataFile, this will read the content of the file +// and set it to CONTRACTS_OVERRIDE_CONFIG env var in base 64 encoded format. +// This comes handy while running tests in remote runner. It ensures that you won't have to deal with copying the +// DataFile to remote runner pod. Instead, you can pass the base64ed content of the file with the help of +// an env var. +func (c *CCIPContractConfig) ContractsData() ([]byte, error) { + // check if CONTRACTS_OVERRIDE_CONFIG is provided + // load config from env var if specified for contracts + rawConfig := os.Getenv(CONTRACTS_OVERRIDE_CONFIG) + if rawConfig != "" { + err := DecodeConfig(rawConfig, &c) + if err != nil { + return nil, err + } + } + if c == nil { + return nil, nil + } + if c.Data != "" { + return []byte(c.Data), nil + } + // if DataFilePath is given, update c.Data with the content of file so that we can set CONTRACTS_OVERRIDE_CONFIG + // to pass the file content to remote runner with override config var + if c.DataFilePath() != "" { + // if there is regex provided in filepath, reformat the filepath with actual filepath matching the regex + filePath, err := testutils.FirstFileFromMatchingPath(c.DataFilePath()) + if err != nil { + return nil, fmt.Errorf("error finding contract config file %s: %w", c.DataFilePath(), err) + } + dataContent, err := os.ReadFile(filePath) + if err != nil { + return dataContent, fmt.Errorf("error reading contract config file %s : %w", filePath, err) + } + c.Data = string(dataContent) + // encode it to base64 and set to CONTRACTS_OVERRIDE_CONFIG so that the same content can be passed to remote runner + // we add TEST_ prefix to CONTRACTS_OVERRIDE_CONFIG to ensure the env var is ported to remote runner. + _, err = EncodeConfigAndSetEnv(c, fmt.Sprintf("TEST_%s", CONTRACTS_OVERRIDE_CONFIG)) + return dataContent, err + } + return nil, nil +} + +type CCIP struct { + Env *Common `toml:",omitempty"` + ContractVersions map[ccipcontracts.Name]ccipcontracts.Version `toml:",omitempty"` + Deployments *CCIPContractConfig `toml:",omitempty"` + Groups map[string]*CCIPTestGroupConfig `toml:",omitempty"` +} + +func (c *CCIP) Validate() error { + if c.Env != nil { + err := c.Env.Validate() + if err != nil { + return err + } + } + + for name, grp := range c.Groups { + grp.Type = name + if err := grp.Validate(); err != nil { + return err + } + } + return nil +} + +func (c *CCIP) ApplyOverrides(fromCfg *CCIP) error { + if fromCfg == nil { + return nil + } + logBytes, err := toml.Marshal(fromCfg) + if err != nil { + return err + } + return ctfconfig.BytesToAnyTomlStruct(zerolog.Logger{}, "", "", c, logBytes) +} diff --git a/integration-tests/ccip-tests/testconfig/examples/network_config.toml.example b/integration-tests/ccip-tests/testconfig/examples/network_config.toml.example new file mode 100644 index 0000000000..ffed99a771 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/examples/network_config.toml.example @@ -0,0 +1,168 @@ +[RpcHttpUrls] +ETHEREUM_MAINNET = [ + 'https:....', + 'https:......', +] +AVALANCHE_MAINNET = [ + 'https:....', + 'https:......', +] +BASE_MAINNET = [ + 'https:....', + 'https:......', +] +ARBITRUM_MAINNET = [ + 'https:....', + 'https:......', +] +BSC_MAINNET = [ + 'https:....', + 'https:......', +] +OPTIMISM_MAINNET = [ + 'https:....', + 'https:......', +] +POLYGON_MAINNET = [ + 'https:....', + 'https:......', +] +WEMIX_MAINNET = [ + 'https:....', + 'https:......', +] +KROMA_MAINNET = [ + 'https:....', + 'https:......', +] + +OPTIMISM_SEPOLIA = [ + 'https:....', + 'https:......', +] +SEPOLIA = [ + 'https:....', + 'https:......', +] +AVALANCHE_FUJI = [ + 'https:....', + 'https:......', +] +ARBITRUM_SEPOLIA = [ + 'https:....', + 'https:......', +] +POLYGON_MUMBAI = [ + 'https:....', + 'https:......', +] +BASE_SEPOLIA = [ + 'https:....', + 'https:......', +] +BSC_TESTNET = [ + 'https:....', + 'https:......', +] +KROMA_SEPOLIA = [ + 'https:....', + 'https:......', +] +WEMIX_TESTNET = [ + 'https:....', + 'https:......', +] + +[RpcWsUrls] +ETHEREUM_MAINNET = [ + 'wss://......', + 'wss://.........' +] +AVALANCHE_MAINNET = [ + 'wss://......', + 'wss://.........' +] +BASE_MAINNET = [ + 'wss://......', + 'wss://.........' +] +ARBITRUM_MAINNET = [ + 'wss://......', + 'wss://.........' +] +BSC_MAINNET = [ + 'wss://......', + 'wss://.........' +] +POLYGON_MAINNET = [ + 'wss://......', + 'wss://.........' +] +OPTIMISM_MAINNET = [ + 'wss://......', + 'wss://.........' +] +WEMIX_MAINNET = [ + 'wss://......', + 'wss://.........' +] +KROMA_MAINNET = [ + 'wss://......', + 'wss://.........' +] +OPTIMISM_SEPOLIA = [ + 'wss://......', + 'wss://.........' +] +SEPOLIA = [ + 'wss://......', + 'wss://.........' +] +AVALANCHE_FUJI = [ + 'wss://......', + 'wss://.........' +] +ARBITRUM_SEPOLIA = [ + 'wss://......', + 'wss://.........' +] +POLYGON_MUMBAI = [ + 'wss://......', + 'wss://.........' +] +BASE_SEPOLIA = [ + 'wss://......', + 'wss://.........' +] +BSC_TESTNET = [ + 'wss://......', + 'wss://.........' +] +KROMA_SEPOLIA = [ + 'wss://......', + 'wss://.........' +] +WEMIX_TESTNET = [ + 'wss://......', + 'wss://.........' +] + +[WalletKeys] +ETHEREUM_MAINNET = [''] +AVALANCHE_MAINNET = [''] +BASE_MAINNET = [''] +ARBITRUM_MAINNET = [''] +BSC_MAINNET = [''] +POLYGON_MAINNET = [''] +OPTIMISM_MAINNET = [''] +WEMIX_MAINNET = [''] +KROMA_MAINNET = [''] +OPTIMISM_SEPOLIA = [''] +SEPOLIA = [''] +AVALANCHE_FUJI = [''] +ARBITRUM_SEPOLIA = [''] +POLYGON_MUMBAI = [''] +BASE_SEPOLIA = [''] +BSC_TESTNET = [''] +KROMA_SEPOLIA = [''] +WEMIX_TESTNET = [''] \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/examples/override.toml.example b/integration-tests/ccip-tests/testconfig/examples/override.toml.example new file mode 100644 index 0000000000..281a4e8963 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/examples/override.toml.example @@ -0,0 +1,119 @@ + +[CCIP] +[CCIP.Deployments] +Data = """ +{ + "lane_configs": { + "geth_1337": { + "is_mock_arm": true, + "fee_token": "0x42699A7612A82f1d9C36148af9C77354759b210b", + "bridge_tokens": [ + "0x42699A7612A82f1d9C36148af9C77354759b210b" + ], + "bridge_tokens_pools": [ + "0xecb550de5c73e6690ab4521c03ec9d476617167e" + ], + "arm": "0x99c6a236913907dce5714cfa4a179d4f2c0b93d9", + "router": "0x96c1f5d31c4c627d6e84a046d4790cac4f17d3ed", + "price_registry": "0x625c70baf2dfb2cf06cf6673e6bbad1672427605", + "wrapped_native": "0x9B8397f1B0FEcD3a1a40CdD5E8221Fa461898517", + "src_contracts": { + "geth_2337": { + "on_ramp": "0xe62b93777e666224cc8029c21a31311554e2f10e", + "deployed_at": 71207 + } + }, + "dest_contracts": { + "geth_2337": { + "off_ramp": "0xba1a4f08001416a630e19e34abd260f039874e92", + "commit_store": "0x297e29cd7be020c211495f98a3d794a8ae000165", + "receiver_dapp": "" + } + } + }, + "geth_2337": { + "is_mock_arm": true, + "fee_token": "0x42699A7612A82f1d9C36148af9C77354759b210b", + "bridge_tokens": [ + "0x42699A7612A82f1d9C36148af9C77354759b210b" + ], + "bridge_tokens_pools": [ + "0xc7555581de61f6db45ea28547d6d5e0722ed6fbe" + ], + "arm": "0x2b33e63e99cbb1847a2735e08c61d9034b13a171", + "router": "0x27a107a95b36c4510ea926f0f886ff7772248e66", + "price_registry": "0x4a6ea541263c363478da333239e38e96e2cc8653", + "wrapped_native": "0x9B8397f1B0FEcD3a1a40CdD5E8221Fa461898517", + "src_contracts": { + "geth_1337": { + "on_ramp": "0x96c1f5d31c4c627d6e84a046d4790cac4f17d3ed", + "deployed_at": 71209 + } + }, + "dest_contracts": { + "geth_1337": { + "off_ramp": "0xe62b93777e666224cc8029c21a31311554e2f10e", + "commit_store": "0xa1dc9167b1a8f201d15b48bdd5d77f8360845ced", + "receiver_dapp": "" + } + } + } + } +} +""" + +[CCIP.Env] +EnvUser = 'crib-deployment' +Mockserver = 'http://mockserver:1080' + +[CCIP.Env.Network] +selected_networks = ['geth_1337', 'geth_2337'] + +[CCIP.Env.Network.EVMNetworks.geth_1337] +evm_name = 'geth_1337' +evm_chain_id = 1337 +evm_urls = ['wss://chain-alpha-rpc.nodeops.sand.cldev.sh/ws/'] +evm_http_urls = ['https://chain-alpha-rpc.nodeops.sand.cldev.sh/'] +evm_keys = ['8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 500000 +evm_transaction_timeout = '2m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 10000 +evm_supports_eip1559 = false +evm_default_gas_limit = 6000000 +evm_finality_depth = 1 + +[CCIP.Env.Network.EVMNetworks.geth_2337] +evm_name = 'geth_2337' +evm_chain_id = 2337 +evm_urls = ['wss://chain-beta-rpc.nodeops.sand.cldev.sh/ws/'] +evm_http_urls = ['https://chain-beta-rpc.nodeops.sand.cldev.sh/'] +evm_keys = ['8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 500000 +evm_transaction_timeout = '2m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 10000 +evm_supports_eip1559 = false +evm_default_gas_limit = 6000000 +evm_finality_depth = 1 + +[CCIP.Env.ExistingCLCluster] +Name = 'crib-mono-repo-test' + +[CCIP.Groups] +[CCIP.Groups.smoke] +LocalCluster = false +ExistingDeployment = true + + +[CCIP.Groups.smoke.MsgDetails] +MsgType = 'DataWithToken' +DestGasLimit = 100000 +DataLength = 1000 +NoOfTokens = 1 +AmountPerToken = 1 + diff --git a/integration-tests/ccip-tests/testconfig/examples/secrets.toml.example b/integration-tests/ccip-tests/testconfig/examples/secrets.toml.example new file mode 100644 index 0000000000..3045f51759 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/examples/secrets.toml.example @@ -0,0 +1,52 @@ +# This file contains all secret parameters for ccip tests. +# DO NOT UPDATE THIS FILE WITH ANY SECRET VALUES. +# Use this file as a template for the actual secret file and update all the parameter values accordingly. +# DO NOT COMMIT THE ACTUAL SECRET FILE TO THE REPOSITORY. +[CCIP] +[CCIP.Env] + +# ChainlinkImage is mandatory for all tests. +[CCIP.Env.NewCLCluster] +[CCIP.Env.NewCLCluster.Common] +[CCIP.Env.NewCLCluster.Common.ChainlinkImage] +image = "chainlink-ccip" +version = "latest" + +# Chainlink upgrade image is used only for upgrade tests +#[CCIP.Env.NewCLCluster.Common.ChainlinkUpgradeImage] +#image = "***.dkr.ecr.***.amazonaws.com/chainlink-ccip" +#version = "****" + + +# Networks configuration with rpc urls and wallet keys are mandatory only for tests running on live networks +# The following example is for 3 networks: Ethereum, Base and Arbitrum +# Network configuration can be ignored for tests running on simulated/private networks +[CCIP.Env.Network] +selected_networks= [ + 'ETHEREUM_MAINNET','BASE_MAINNET', 'ARBITRUM_MAINNET', +] + +[CCIP.Env.Network.RpcHttpUrls] +ETHEREUM_MAINNET = ['', ''] +BASE_MAINNET = ['', ''] +ARBITRUM_MAINNET = ['', ''] + +[CCIP.Env.Network.RpcWsUrls] +ETHEREUM_MAINNET = ['', ''] +BASE_MAINNET = ['', ''] +ARBITRUM_MAINNET = ['', ''] + +[CCIP.Env.Network.WalletKeys] +ETHEREUM_MAINNET = [''] +BASE_MAINNET = [''] +ARBITRUM_MAINNET = [''] + +# Used for tests using 1. loki logging for test results. +# Mandatory for load tests +[CCIP.Env.Logging.Loki] +tenant_id="" +endpoint="" + +[CCIP.Env.Logging.Grafana] +base_url="" +dashboard_url="/d/6vjVx-1V8/ccip-long-running-tests" diff --git a/integration-tests/ccip-tests/testconfig/global.go b/integration-tests/ccip-tests/testconfig/global.go new file mode 100644 index 0000000000..331737c5fb --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/global.go @@ -0,0 +1,457 @@ +package testconfig + +import ( + "bytes" + _ "embed" + "encoding/base64" + "fmt" + "os" + "strings" + + "github.com/AlekSi/pointer" + "github.com/pelletier/go-toml/v2" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/utils/osutil" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/config" + + "github.com/smartcontractkit/chainlink/integration-tests/client" +) + +const ( + OVERIDECONFIG = "BASE64_CCIP_CONFIG_OVERRIDE" + + SECRETSCONFIG = "BASE64_CCIP_SECRETS_CONFIG" + ErrReadConfig = "failed to read TOML config" + ErrUnmarshalConfig = "failed to unmarshal TOML config" + Load string = "load" + Chaos string = "chaos" + Smoke string = "smoke" + ProductCCIP = "CCIP" +) + +var ( + //go:embed tomls/ccip-default.toml + DefaultConfig []byte +) + +func GlobalTestConfig() *Config { + var err error + cfg, err := NewConfig() + if err != nil { + log.Fatal().Err(err).Msg("Failed to load config") + } + return cfg +} + +// GenericConfig is an interface for all product based config types to implement +type GenericConfig interface { + Validate() error + ApplyOverrides(from interface{}) error +} + +// Config is the top level config struct. It contains config for all product based tests. +type Config struct { + CCIP *CCIP `toml:",omitempty"` +} + +func (c *Config) Validate() error { + return c.CCIP.Validate() +} + +func (c *Config) TOMLString() string { + buf := new(bytes.Buffer) + err := toml.NewEncoder(buf).Encode(c) + if err != nil { + log.Fatal().Err(err).Msg("Failed to encode config to TOML") + } + return buf.String() +} + +func DecodeConfig(rawConfig string, c any) error { + d, err := base64.StdEncoding.DecodeString(rawConfig) + if err != nil { + return errors.Wrap(err, ErrReadConfig) + } + err = toml.Unmarshal(d, c) + if err != nil { + return errors.Wrap(err, ErrUnmarshalConfig) + } + return nil +} + +// EncodeConfigAndSetEnv encodes the given struct to base64 +// and sets env var ( if not empty) with the encoded base64 string +func EncodeConfigAndSetEnv(c any, envVar string) (string, error) { + srcBytes, err := toml.Marshal(c) + if err != nil { + return "", err + } + encodedStr := base64.StdEncoding.EncodeToString(srcBytes) + if envVar == "" { + return encodedStr, nil + } + return encodedStr, os.Setenv(envVar, encodedStr) +} + +func NewConfig() (*Config, error) { + cfg := &Config{} + var override *Config + var secrets *Config + // load config from default file + err := config.DecodeTOML(bytes.NewReader(DefaultConfig), cfg) + if err != nil { + return nil, errors.Wrap(err, ErrReadConfig) + } + + // load config from env var if specified + rawConfig, _ := osutil.GetEnv(OVERIDECONFIG) + if rawConfig != "" { + err = DecodeConfig(rawConfig, &override) + if err != nil { + return nil, fmt.Errorf("failed to decode override config: %w", err) + } + } + if override != nil { + // apply overrides for all products + if override.CCIP != nil { + if cfg.CCIP == nil { + cfg.CCIP = override.CCIP + } else { + err = cfg.CCIP.ApplyOverrides(override.CCIP) + if err != nil { + return nil, err + } + } + } + } + // read secrets for all products + if cfg.CCIP != nil { + // load config from env var if specified for secrets + secretRawConfig, _ := osutil.GetEnv(SECRETSCONFIG) + if secretRawConfig != "" { + err = DecodeConfig(secretRawConfig, &secrets) + if err != nil { + return nil, fmt.Errorf("failed to decode secrets config: %w", err) + } + if secrets != nil { + // apply secrets for all products + if secrets.CCIP != nil { + err = cfg.CCIP.ApplyOverrides(secrets.CCIP) + if err != nil { + return nil, fmt.Errorf("failed to apply secrets: %w", err) + } + } + } + } + // validate all products + err = cfg.CCIP.Validate() + if err != nil { + return nil, err + } + } + + return cfg, nil +} + +// Common is the generic config struct which can be used with product specific configs. +// It contains generic DON and networks config which can be applied to all product based tests. +type Common struct { + EnvUser string `toml:",omitempty"` + EnvToConnect *string `toml:",omitempty"` + TTL *config.Duration `toml:",omitempty"` + ExistingCLCluster *CLCluster `toml:",omitempty"` // ExistingCLCluster is the existing chainlink cluster to use, if specified it will be used instead of creating a new one + Mockserver *string `toml:",omitempty"` + NewCLCluster *ChainlinkDeployment `toml:",omitempty"` // NewCLCluster is the new chainlink cluster to create, if specified along with ExistingCLCluster this will be ignored + Network *ctfconfig.NetworkConfig `toml:",omitempty"` + PrivateEthereumNetworks map[string]*ctfconfig.EthereumNetworkConfig `toml:",omitempty"` + Logging *ctfconfig.LoggingConfig `toml:",omitempty"` +} + +func (p *Common) GetNodeConfig() *ctfconfig.NodeConfig { + return &ctfconfig.NodeConfig{ + BaseConfigTOML: p.NewCLCluster.Common.BaseConfigTOML, + CommonChainConfigTOML: p.NewCLCluster.Common.CommonChainConfigTOML, + ChainConfigTOMLByChainID: p.NewCLCluster.Common.ChainConfigTOMLByChain, + } +} + +func (p *Common) GetSethConfig() *seth.Config { + return nil +} + +func (p *Common) Validate() error { + if err := p.Logging.Validate(); err != nil { + return fmt.Errorf("error validating logging config %w", err) + } + if p.Network == nil { + return errors.New("no networks specified") + } + // read the default network config, if specified + p.Network.UpperCaseNetworkNames() + p.Network.OverrideURLsAndKeysFromEVMNetwork() + err := p.Network.Default() + if err != nil { + return fmt.Errorf("error reading default network config %w", err) + } + if err := p.Network.Validate(); err != nil { + return fmt.Errorf("error validating networks config %w", err) + } + if p.NewCLCluster == nil && p.ExistingCLCluster == nil { + return errors.New("no chainlink or existing cluster specified") + } + + for k, v := range p.PrivateEthereumNetworks { + // this is the only value we need to generate dynamically before starting a new simulated chain + if v.EthereumChainConfig != nil { + p.PrivateEthereumNetworks[k].EthereumChainConfig.GenerateGenesisTimestamp() + } + + builder := test_env.NewEthereumNetworkBuilder() + ethNetwork, err := builder.WithExistingConfig(*v).Build() + if err != nil { + return fmt.Errorf("error building private ethereum network ethNetworks %w", err) + } + + p.PrivateEthereumNetworks[k] = ðNetwork.EthereumNetworkConfig + } + + if p.ExistingCLCluster != nil { + if err := p.ExistingCLCluster.Validate(); err != nil { + return fmt.Errorf("error validating existing chainlink cluster config %w", err) + } + if p.Mockserver == nil { + return errors.New("no mockserver specified for existing chainlink cluster") + } + log.Warn().Msg("Using existing chainlink cluster, overriding new chainlink cluster config if specified") + p.NewCLCluster = nil + } else { + if p.NewCLCluster != nil { + if err := p.NewCLCluster.Validate(); err != nil { + return fmt.Errorf("error validating chainlink config %w", err) + } + } + } + return nil +} + +func (p *Common) EVMNetworks() ([]blockchain.EVMNetwork, []string, error) { + evmNetworks := networks.MustGetSelectedNetworkConfig(p.Network) + if len(p.Network.SelectedNetworks) != len(evmNetworks) { + return nil, p.Network.SelectedNetworks, fmt.Errorf("selected networks %v do not match evm networks %v", p.Network.SelectedNetworks, evmNetworks) + } + return evmNetworks, p.Network.SelectedNetworks, nil +} + +func (p *Common) GetLoggingConfig() *ctfconfig.LoggingConfig { + return p.Logging +} + +func (p *Common) GetChainlinkImageConfig() *ctfconfig.ChainlinkImageConfig { + return p.NewCLCluster.Common.ChainlinkImage +} + +func (p *Common) GetPyroscopeConfig() *ctfconfig.PyroscopeConfig { + return nil +} + +func (p *Common) GetPrivateEthereumNetworkConfig() *ctfconfig.EthereumNetworkConfig { + return nil +} + +func (p *Common) GetNetworkConfig() *ctfconfig.NetworkConfig { + return p.Network +} + +// Returns Grafana URL from Logging config +func (p *Common) GetGrafanaBaseURL() (string, error) { + if p.Logging.Grafana == nil || p.Logging.Grafana.BaseUrl == nil { + return "", errors.New("grafana base url not set") + } + + return strings.TrimSuffix(*p.Logging.Grafana.BaseUrl, "/"), nil +} + +// Returns Grafana Dashboard URL from Logging config +func (p *Common) GetGrafanaDashboardURL() (string, error) { + if p.Logging.Grafana == nil || p.Logging.Grafana.DashboardUrl == nil { + return "", errors.New("grafana dashboard url not set") + } + + url := *p.Logging.Grafana.DashboardUrl + if !strings.HasPrefix(url, "/") { + url = "/" + url + } + + return url, nil +} + +type CLCluster struct { + Name *string `toml:",omitempty"` + NoOfNodes *int `toml:",omitempty"` + NodeConfigs []*client.ChainlinkConfig `toml:",omitempty"` +} + +func (c *CLCluster) Validate() error { + if c.NoOfNodes == nil || len(c.NodeConfigs) == 0 { + return fmt.Errorf("no chainlink nodes specified") + } + if *c.NoOfNodes != len(c.NodeConfigs) { + return fmt.Errorf("number of nodes %d does not match number of node configs %d", *c.NoOfNodes, len(c.NodeConfigs)) + } + for i, nodeConfig := range c.NodeConfigs { + if nodeConfig.URL == "" { + return fmt.Errorf("node %d url not specified", i+1) + } + if nodeConfig.Password == "" { + return fmt.Errorf("node %d password not specified", i+1) + } + if nodeConfig.Email == "" { + return fmt.Errorf("node %d email not specified", i+1) + } + if nodeConfig.InternalIP == "" { + return fmt.Errorf("node %d internal ip not specified", i+1) + } + } + + return nil +} + +type ChainlinkDeployment struct { + Common *Node `toml:",omitempty"` + NodeMemory string `toml:",omitempty"` + NodeCPU string `toml:",omitempty"` + DBMemory string `toml:",omitempty"` + DBCPU string `toml:",omitempty"` + DBCapacity string `toml:",omitempty"` + DBStorageClass *string `toml:",omitempty"` + PromPgExporter *bool `toml:",omitempty"` + IsStateful *bool `toml:",omitempty"` + DBArgs []string `toml:",omitempty"` + NoOfNodes *int `toml:",omitempty"` + Nodes []*Node `toml:",omitempty"` // to be mentioned only if diff nodes follow diff configs; not required if all nodes follow CommonConfig +} + +func (c *ChainlinkDeployment) Validate() error { + if c.Common == nil { + return errors.New("common config can't be empty") + } + if c.Common.ChainlinkImage == nil { + return errors.New("chainlink image can't be empty") + } + if err := c.Common.ChainlinkImage.Validate(); err != nil { + return err + } + if c.Common.DBImage == "" || c.Common.DBTag == "" { + return errors.New("must provide db image and tag") + } + if c.NoOfNodes == nil { + return errors.New("chainlink config is invalid, NoOfNodes should be specified") + } + if c.Nodes != nil && len(c.Nodes) > 0 { + noOfNodes := pointer.GetInt(c.NoOfNodes) + if noOfNodes != len(c.Nodes) { + return errors.New("chainlink config is invalid, NoOfNodes and Nodes length mismatch") + } + for i := range c.Nodes { + // merge common config with node specific config + c.Nodes[i].Merge(c.Common) + node := c.Nodes[i] + if node.ChainlinkImage == nil { + return fmt.Errorf("node %s: chainlink image can't be empty", node.Name) + } + if err := node.ChainlinkImage.Validate(); err != nil { + return fmt.Errorf("node %s: %w", node.Name, err) + } + if node.DBImage == "" || node.DBTag == "" { + return fmt.Errorf("node %s: must provide db image and tag", node.Name) + } + } + } + return nil +} + +type Node struct { + Name string `toml:",omitempty"` + NeedsUpgrade *bool `toml:",omitempty"` + ChainlinkImage *ctfconfig.ChainlinkImageConfig `toml:"ChainlinkImage"` + ChainlinkUpgradeImage *ctfconfig.ChainlinkImageConfig `toml:"ChainlinkUpgradeImage"` + BaseConfigTOML string `toml:",omitempty"` + CommonChainConfigTOML string `toml:",omitempty"` + ChainConfigTOMLByChain map[string]string `toml:",omitempty"` // key is chainID + DBImage string `toml:",omitempty"` + DBTag string `toml:",omitempty"` +} + +// Merge merges non-empty values +func (n *Node) Merge(from *Node) { + if from == nil || n == nil { + return + } + if n.Name == "" { + n.Name = from.Name + } + if n.ChainlinkImage == nil { + if from.ChainlinkImage != nil { + n.ChainlinkImage = &ctfconfig.ChainlinkImageConfig{ + Image: from.ChainlinkImage.Image, + Version: from.ChainlinkImage.Version, + } + } + } else { + if n.ChainlinkImage.Image == nil && from.ChainlinkImage != nil { + n.ChainlinkImage.Image = from.ChainlinkImage.Image + } + if n.ChainlinkImage.Version == nil && from.ChainlinkImage != nil { + n.ChainlinkImage.Version = from.ChainlinkImage.Version + } + } + // merge upgrade image only if the nodes is marked as NeedsUpgrade to true + if pointer.GetBool(n.NeedsUpgrade) { + if n.ChainlinkUpgradeImage == nil { + if from.ChainlinkUpgradeImage != nil { + n.ChainlinkUpgradeImage = &ctfconfig.ChainlinkImageConfig{ + Image: from.ChainlinkUpgradeImage.Image, + Version: from.ChainlinkUpgradeImage.Version, + } + } + } else { + if n.ChainlinkUpgradeImage.Image == nil && from.ChainlinkUpgradeImage != nil { + n.ChainlinkUpgradeImage.Image = from.ChainlinkUpgradeImage.Image + } + if n.ChainlinkUpgradeImage.Version == nil && from.ChainlinkUpgradeImage != nil { + n.ChainlinkUpgradeImage.Version = from.ChainlinkUpgradeImage.Version + } + } + } + + if n.DBImage == "" { + n.DBImage = from.DBImage + } + if n.DBTag == "" { + n.DBTag = from.DBTag + } + if n.BaseConfigTOML == "" { + n.BaseConfigTOML = from.BaseConfigTOML + } + if n.CommonChainConfigTOML == "" { + n.CommonChainConfigTOML = from.CommonChainConfigTOML + } + if n.ChainConfigTOMLByChain == nil { + n.ChainConfigTOMLByChain = from.ChainConfigTOMLByChain + } else { + for k, v := range from.ChainConfigTOMLByChain { + if _, ok := n.ChainConfigTOMLByChain[k]; !ok { + n.ChainConfigTOMLByChain[k] = v + } + } + } +} diff --git a/integration-tests/ccip-tests/testconfig/override/mainnet-secondary.toml b/integration-tests/ccip-tests/testconfig/override/mainnet-secondary.toml new file mode 100644 index 0000000000..7d457774b0 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/override/mainnet-secondary.toml @@ -0,0 +1,712 @@ +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = '1.2.0' +OffRamp = '1.2.0' +OnRamp = '1.2.0' +TokenPool = '1.4.0' +CommitStore = '1.2.0' + +[CCIP.Deployments] +Data = """ +{ + "lane_configs": { + "Arbitrum Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4", + "bridge_tokens": ["0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"], + "bridge_tokens_pools": ["0x34700F5faE61Ba628c4269BdCbA12DA53bbfa726"], + "arm": "0xe06b0e8c4bd455153e8794ad7Ea8Ff5A14B64E4b", + "router": "0x141fa059441E0ca23ce184B6A78bafD2A517DdE8", + "price_registry": "0x13015e4E6f839E1Aa1016DF521ea458ecA20438c", + "wrapped_native": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "version" : "1.4.0", + "src_contracts": { + "Avalanche Mainnet": { + "on_ramp": "0x05B723f3db92430FbE4395fD03E40Cc7e9D17988", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x77b60F85b25fD501E3ddED6C1fe7bF565C08A22A", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0x79f3ABeCe5A3AFFf32D47F4CFe45e7b65c9a2D91", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0xCe11020D56e5FDbfE46D9FC3021641FfbBB5AdEE", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0xC09b72E8128620C40D89649019d995Cc79f030C3", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x122F05F49e90508F089eE8D0d868d1a4f3E5a809", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x66a0046ac9FA104eB38B04cfF391CcD0122E6FbC", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Avalanche Mainnet": { + "off_ramp": "0xe0109912157d5B75ea8b3181123Cf32c73bc9920", + "commit_store": "0xDaa61b8Cd85977820f92d1e749E1D9F55Da6CCEA", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0xdB19F77F87661f9be0F557cf9a1ebeCf7D8F206c", + "commit_store": "0x6e37f4c82d9A31cc42B445874dd3c3De97AB553f", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0xB1b705c2315fced1B38baE463BE7DDef531e47fA", + "commit_store": "0x310cECbFf14Ad0307EfF762F461a487C1abb90bf", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x542ba1902044069330e8c5b36A84EC503863722f", + "commit_store": "0x060331fEdA35691e54876D957B4F9e3b8Cb47d20", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0xeeed4D86F3E0e6d32A6Ad29d8De6A0Dc91963A5f", + "commit_store": "0xbbB563c4d98020b9c0f3Cc34c2C0Ef9676806E35", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x9bDA7c8DCda4E39aFeB483cc0B7E3C1f6E0D5AB1", + "commit_store": "0x63a0AeaadAe851b990bBD9dc41f5C1B08b32026d", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0xEEf5Fb4c4953F9cA9ab1f25cE590776AfFc2c455", + "commit_store": "0xD268286A277095a9C3C90205110831a84505881c", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Avalanche Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x5947BB275c521040051D82396192181b413227A3", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0xdFD6C0dc67666DE3bB36b31eec5c7B1542A82C1E", + "router": "0xF4c7E640EdA248ef95972845a62bdC74237805dB", + "price_registry": "0xfA4edD04eaAcDB07c8D73621bc1790eC50D8c489", + "wrapped_native": "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x98f51B041e493fc4d72B8BD33218480bA0c66DDF", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x268fb4311D2c6CB2bbA01CCA9AC073Fb3bfd1C7c", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0x8eaae6462816CB4957184c48B86afA7642D8Bf2B", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0xD0701FcC7818c31935331B02Eb21e91eC71a1704", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x8629008887E073260c5434D6CaCFc83C3001d211", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x97500490d9126f34cf9aA0126d64623E170319Ef", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x9b1ed9De069Be4d50957464b359f98eD0Bf34dd5", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x770b1375F86E7a9bf30DBe3F97bea67193dC9135", + "commit_store": "0x23E2b34Ce8e12c53f8a39AD4b3FFCa845f8E617C", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0x4d6A796Bc85dcDF41ce9AaEB50B094C6b589748f", + "commit_store": "0xc4C4358FA01a04D6c6FE3b96a351946d4c2715C2", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0x83F53Fc798FEbfFbdF84830AD403b9989187a06C", + "commit_store": "0xD8ceCE2D7794385E00Ce3EF94550E732b0A0B959", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x5B833BD6456c604Eb396C0fBa477aD49e82B1A2a", + "commit_store": "0x23E23958D220B774680f91c2c91a6f2B2f610d7e", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0xb68A3EE8bD0A09eE221cf1859Dd5a4d5765188Fe", + "commit_store": "0x83DCeeCf822981F9F8552925eEfd88CAc1905dEA", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x19250aBE66B88F214d02B6f3BF80F4118290C619", + "commit_store": "0x87A0935cE6254dB1252bBac90d1D07D04846aDCA", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0x317dE8bc5c3292E494b6496586696d4966A922B0", + "commit_store": "0x97Fbf3d6DEac16adC721aE9187CeEa1e610aC7Af", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Base Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x38660c8CC222c0192b635c2ac09687B4F25cCE5F", + "router": "0x881e3A65B4d4a04dD529061dd0071cf975F58bCD", + "price_registry": "0x6337a58D4BD7Ba691B66341779e8f87d4679923a", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x1E5Ca70d1e7A1B26061125738a880BBeA42FeB21", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0xBE5a9E336D9614024B4Fa10D8112671fc9A42d96", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0xdd4Fb402d41Beb0eEeF6CfB1bf445f50bDC8c981", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0xDEA286dc0E01Cb4755650A6CF8d1076b454eA1cb", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0xd952FEAcDd5919Cc5E9454b53bF45d4E73dD6457", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x3DB8Bea142e41cA3633890d0e5640F99a895D6A5", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x8531E63aE9279a1f0D09eba566CD1b092b95f3D5", + "commit_store": "0x327E13f54c7871a2416006B33B4822eAAD357916", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Mainnet": { + "off_ramp": "0x8345F2fF67e5A65e85dc955DE1414832608E00aD", + "commit_store": "0xd0b13be4c53A6262b47C5DDd36F0257aa714F562", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0x48a51f5D38BE630Ddd6417Ea2D9052B8efc91a18", + "commit_store": "0xF97127e77252284EC9D4bc13C247c9D1A99F72B0", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0xEC0cFe335a4d53dBA70CB650Ab56eEc32788F0BB", + "commit_store": "0x0ae3c2c7FB789bd05A450CD3075D11f6c2Ca4F77", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0xf50c0d2a8B6Db60f1D93E60f03d0413D56153E4F", + "commit_store": "0x16f72C15165f7C9d74c12fDF188E399d4d3724e4", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x75F29f058b31106F99caFdc17c9b26ADfcC7b5D7", + "commit_store": "0xb719616E732581B570232DfB13Ca49D27667Af9f", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "BSC Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x404460C6A5EdE2D891e8297795264fDe62ADBB75", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x3DB43b96B2625F4232e9Df900d464dd2c64C0021", + "router": "0x34B03Cb9086d7D758AC55af71584F81A598759FE", + "price_registry": "0xd64aAbD70A71d9f0A00B99F6EFc1626aA2dD43C7", + "wrapped_native": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "src_contracts": { + "Avalanche Mainnet": { + "on_ramp": "0x6aa72a998859eF93356c6521B72155D355D0Cfd2", + "deployed_at": 11111111 + }, + "Arbitrum Mainnet": { + "on_ramp": "0x2788b46BAcFF49BD89562e6bA5c5FBbbE5Fa92F7", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x70bC7f7a6D936b289bBF5c0E19ECE35B437E2e36", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0x0Bf40b034872D0b364f3DCec04C7434a4Da1C8d9", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x4FEB11A454C9E8038A8d0aDF599Fe7612ce114bA", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x6bD4754D86fc87FE5b463D368f26a3587a08347c", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x1467fF8f249f5bc604119Af26a47035886f856BE", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Avalanche Mainnet": { + "off_ramp": "0x37a6fa55fe61061Ae97bF7314Ae270eCF71c5ED3", + "commit_store": "0x1f558F6dcf0224Ef1F78A24814FED548B9602c80", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Arbitrum Mainnet": { + "off_ramp": "0x3DA330fd8Ef10d93cFB7D4f8ecE7BC1F10811feC", + "commit_store": "0x86D55Ff492cfBBAf0c0D42D4EE615144E78b3D02", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0x574c697deab06B805D8780898B3F136a1F4892Dc", + "commit_store": "0x002B164b1dcf4E92F352DC625A01Be0E890EdEea", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x181Bb1E97b0bDD1D85E741ad0943552D3682cc35", + "commit_store": "0x3fF27A34fF0FA77921C3438e67f58da1a83e9Ce1", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0xE7E080C8d62d595a223C577C7C8d1f75d9A5E664", + "commit_store": "0xF4d53346bDb6d393C74B0B72Aa7D6689a3eAad79", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x26af2046Da85d7f6712D5edCa81B9E3b2e7A60Ab", + "commit_store": "0x4C1dA405a789AC2853A69D8290B8B9b47a0374F8", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0xC027C5AEb230008c243Be463A73571e581F94c13", + "commit_store": "0x2EB426C8C54D740d1FC856eB3Ff96feA03957978", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Ethereum Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x514910771AF9Ca656af840dff83E8264EcF986CA", + "bridge_tokens": ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"], + "bridge_tokens_pools": ["0x69c24c970B65e22Ac26864aF10b2295B7d78f93A"], + "arm": "0x8B63b3DE93431C0f756A493644d128134291fA1b", + "router": "0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D", + "price_registry": "0x8c9b2Efb7c64C394119270bfecE7f54763b958Ad", + "wrapped_native": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x925228D7B82d883Dde340A55Fe8e6dA56244A22C", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0x3df8dAe2d123081c4D5E946E655F7c109B9Dd630", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0xe2c2AB221AA0b957805f229d2AA57fBE2f4dADf7", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0x91D25A56Db77aD5147437d8B83Eb563D46eBFa69", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x86B47d8411006874eEf8E4584BdFD7be8e5549d1", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x35F0ca9Be776E4B38659944c257bDd0ba75F1B8B", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0xCbE7e5DA76dC99Ac317adF6d99137005FDA4E2C4", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0xeFC4a18af59398FF23bfe7325F2401aD44286F4d", + "commit_store": "0x9B2EEd6A1e16cB50Ed4c876D2dD69468B21b7749", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Mainnet": { + "off_ramp": "0x569940e02D4425eac61A7601632eC00d69f75c17", + "commit_store": "0x2aa101BF99CaeF7fc1355D4c493a1fe187A007cE", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0xdf85c8381954694E74abD07488f452b4c2Cddfb3", + "commit_store": "0x8DC27D621c41a32140e22E2a4dAf1259639BAe04", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0x7Afe7088aff57173565F4b034167643AA8b9171c", + "commit_store": "0x87c55D48DF6EF7B08153Ab079e76bFEcbb793D75", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0xB095900fB91db00E6abD247A5A5AD1cee3F20BF7", + "commit_store": "0x4af4B497c998007eF83ad130318eB2b925a79dc8", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x0af338F0E314c7551bcE0EF516d46d855b0Ee395", + "commit_store": "0xD37a60E8C36E802D2E1a6321832Ee85556Beeb76", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0x3a129e6C18b23d18BA9E6Aa14Dc2e79d1f91c6c5", + "commit_store": "0x31f6ab382DDeb9A316Ab61C3945a5292a50a89AB", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Kroma Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xC1F6f7622ad37C3f46cDF6F8AA0344ADE80BF450", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0xB59779d3364BC6d71168245f9ebb96469E5a5a98", + "router": "0xE93E8B0d1b1CEB44350C8758ed1E2799CCee31aB", + "price_registry": "0x8155B4710e7bbC90924E957104F94Afd4f95Eca2", + "wrapped_native": "0x4200000000000000000000000000000000000001", + "src_contracts": { + "WeMix Mainnet": { + "on_ramp": "0x3C5Ab46fA1dB1dECD854224654313a69bf9fcAD3", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "WeMix Mainnet": { + "off_ramp": "0x2B555774B3D1dcbcd76efb7751F3c5FbCFABC5C4", + "commit_store": "0x213124614aAf31eBCE7c612A12aac5f8aAD77DE4", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Optimism Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6", + "bridge_tokens": ["0x4200000000000000000000000000000000000006"], + "bridge_tokens_pools": ["0x86E715415D8C8435903d1e8204fA1e9784Aa7305"], + "arm": "0x8C7C2C3362a42308BB5c368677Ad321D11693b81", + "router": "0x3206695CaE29952f4b0c22a169725a865bc8Ce0f", + "price_registry": "0xb52545aECE8C73A97E52a146757EC15b90Ed8488", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x0C9BE7Cfd12c735E5aaE047C1dCB845d54E518C3", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0xD0D3E757bFBce7ae1881DDD7F6d798DDcE588445", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x0b1760A8112183303c5526C6b24569fd3A274f3B", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0xa3c9544B82846C45BE37593d5d9ACffbE61BF3A6", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0x55183Db1d2aE0b63e4c92A64bEF2CBfc2032B127", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x6B57145e322c877E7D91Ed8E31266eB5c02F7EfC", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x82e9f4C5ec4a84E310d60D462a12042E5cbA0954", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x0C9BE7Cfd12c735E5aaE047C1dCB845d54E518C3", + "commit_store": "0x55028780918330FD00a34a61D9a7Efd3f43ca845", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Mainnet": { + "off_ramp": "0x8dc6490A6204dF846BaBE809cB695ba17Df1F9B1", + "commit_store": "0xA190660787B6B183Dd82B243eA10e609327c7308", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0xBAE6560eCa9B77Cb047158C783e36F7735C86037", + "commit_store": "0x6168aDF58e1Ad446BaD45c6275Bef60Ef4FFBAb8", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0xE14501F2838F2fA1Ceb52E78ABdA289EcE1705EA", + "commit_store": "0xa8DD25B29787527Df283211C24Ac72B17150A696", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0xd2D98Be6a1C241e86C807e51cED6ABb51d044203", + "commit_store": "0x4d75A5cE454b264b187BeE9e189aF1564a68408D", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x7c6221880A1D62506b1A08Dab3Bf695A49AcDD22", + "commit_store": "0x0684076EE3595221861C50cDb9Cb66402Ec11Cb9", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0x3e5B3b7559D39563a74434157b31781322dA712D", + "commit_store": "0x7954372FF6f80908e5A2dC2a19d796A1005f91D2", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Polygon Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xb0897686c545045aFc77CF20eC7A532E3120E0F1", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0xD7AcF65dA1E1f34b663aB199a474F209bF2b0523", + "router": "0x849c5ED5a80F5B408Dd4969b78c2C8fdf0565Bfe", + "price_registry": "0x30D873664Ba766C983984C7AF9A921ccE36D34e1", + "wrapped_native": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0xD16D025330Edb91259EEA8ed499daCd39087c295", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0x5FA30697e90eB30954895c45b028F7C0dDD39b12", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x20B028A2e0F6CCe3A11f3CE5F2B8986F932e89b4", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0xF5b5A2fC11BF46B1669C3B19d98B19C79109Dca9", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0xFd77c53AA4eF0E3C01f5Ac012BF7Cc7A3ECf5168", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x3111cfbF5e84B5D9BD952dd8e957f4Ca75f728Cf", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x5060eF647a1F66BE6eE27FAe3046faf8D53CeB2d", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0xa8a9eDa2867c2E0CE0d5ECe273961F1EcC3CC25B", + "commit_store": "0xbD4480658dca8496a65046dfD1BDD44EF897Bdb5", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Mainnet": { + "off_ramp": "0xB9e3680639c9F0C4e0b02FD81C445094426244Ae", + "commit_store": "0x8c63d4e67f7c4af6FEd2f56A34fB4e01CB807CFF", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0xD0FA7DE2D18A0c59D3fD7dfC7aB4e913C6Aa7b68", + "commit_store": "0xF88053B9DAC8Dd3039a4eFa8639159aaa3F2D4Cb", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0x592773924741F0Da889a0dfdab71171Dd11E054C", + "commit_store": "0xEC4d35E1A85f770f4D93BA43a462c9d87Ef7017e", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x45320085fF051361D301eC1044318213A5387A15", + "commit_store": "0x4Dc771B5ef21ef60c33e2987E092345f2b63aE08", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0xBa754ecd3CFA7E9093F688EAc3860cf9D07Fc0AC", + "commit_store": "0x04C0D5302E3D8Ca0A0019141a52a23B59cdb70e4", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0xd7c877ea02310Cce9278D9A048Aa1Bb9aF72F00d", + "commit_store": "0x92A1C927E8E10Ab6A40E5A5154e2300D278d1a67", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "WeMix Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x80f1FcdC96B55e459BF52b998aBBE2c364935d69", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x07aaC8B69A62dB5bd3d244091916EbF2fac17b76", + "router": "0x7798b795Fde864f4Cd1b124a38Ba9619B7F8A442", + "price_registry": "0x252863688762aD86868D3d3076233Eacd80c7055", + "wrapped_native": "0x7D72b22a74A216Af4a002a1095C8C707d6eC1C5f", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x9aBfd6f4C865610692AB6fb1Be862575809fFabf", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0xbE0Cfae74677F8dd16a246a3a5c8cbB1973118f4", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0x56657ec4D15C71f7F3C17ba2b21C853A24Dc5381", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x70f3b0FD7e6a4B9B623e9AB859604A9EE03e48BD", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x777058C1e1dcE4eB8001F38631a1cd9450816e5a", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0x190bcE84CF2d500B878966F4Cf98a50d78f2675E", + "deployed_at": 11111111 + }, + "Kroma Mainnet": { + "on_ramp": "0x47E9AE0A815C94836202E696748A5d5476aD8735", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x2ba68a395B72a6E3498D312efeD755ed2f3CF223", + "commit_store": "0xdAeC234DA83F68707Bb8AcB2ee6a01a5FD4c2391", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Mainnet": { + "off_ramp": "0xFac907F9a1087B846Faa75A14C5d34A8639233d8", + "commit_store": "0xF2812063446c7deD2CA306c67A68364BdDcbEfc5", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0x6ec9ca4Cba62cA17c55F05ad2000B46192f02035", + "commit_store": "0x84534BE763366a69710E119c100832955795B34B", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0x87220D01DF0fF27149B47227897074653788fd23", + "commit_store": "0xF8dD2be2C6FA43e48A17146380CbEBBB4291807b", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x8f0229804513A9Bc00c1308414AB279Dbc718ae1", + "commit_store": "0x3A85D1b8641d83a87957C6ECF1b62151213e0842", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0xF92Fa796F5307b029c65CA26f322a6D86f211194", + "commit_store": "0xbeC110FF43D52be2066B06525304A9924E16b73b", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Kroma Mainnet": { + "off_ramp": "0xF886d8DC64E544af4835cbf91e5678A54D95B80e", + "commit_store": "0x8794C9534658fdCC44f2FF6645Bf31cf9F6d2d5D", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + } + } +} +""" + +[CCIP.Env] +TTL = '8h' + +[CCIP.Env.Network] +selected_networks = [ + 'ETHEREUM_MAINNET', + 'ARBITRUM_MAINNET', + 'OPTIMISM_MAINNET' + ] + +[CCIP.Groups.load] +NetworkPairs = [ + 'ETHEREUM_MAINNET,OPTIMISM_MAINNET', + 'ETHEREUM_MAINNET,ARBITRUM_MAINNET', + 'ARBITRUM_MAINNET,OPTIMISM_MAINNET' # added as batch 1 +] + +BiDirectionalLane = true +PhaseTimeout = '40m' +ExistingDeployment = true + +[CCIP.Groups.load.TokenConfig] +NoOfTokensPerChain = 1 +CCIPOwnerTokens = true + +[CCIP.Groups.load.LoadProfile] +RequestPerUnitTime = [1] +TimeUnit = '3h' +TestDuration = '24h' +TestRunName = 'mainnet-2.7-ccip1.2' +FailOnFirstErrorInLoad = true +SkipRequestIfAnotherRequestTriggeredWithin = '40m' + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 0 +DataLength = 100 +NoOfTokens = 1 +AmountPerToken = 1 + +[CCIP.Groups.smoke] +# these are all the valid network pairs +NetworkPairs = [ + 'ETHEREUM_MAINNET,OPTIMISM_MAINNET', + 'ETHEREUM_MAINNET,ARBITRUM_MAINNET', + 'ARBITRUM_MAINNET,OPTIMISM_MAINNET' +] + +BiDirectionalLane = true +DestGasLimit = 0 +PhaseTimeout = '20m' +LocalCluster = false +ExistingDeployment = true +ReuseContracts = true + +[CCIP.Groups.smoke.TokenConfig] +NoOfTokensPerChain = 1 +CCIPOwnerTokens = true + +[CCIP.Groups.smoke.MsgDetails] +MsgType = 'Data' +DestGasLimit = 0 +DataLength = 100 +NoOfTokens = 1 +AmountPerToken = 1 \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/override/mainnet.toml b/integration-tests/ccip-tests/testconfig/override/mainnet.toml new file mode 100644 index 0000000000..72695ba754 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/override/mainnet.toml @@ -0,0 +1,767 @@ +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = '1.2.0' +OffRamp = '1.2.0' +OnRamp = '1.2.0' +TokenPool = '1.4.0' +CommitStore = '1.2.0' + +[CCIP.Deployments] +Data = """ +{ + "lane_configs": { + "Arbitrum Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0xe06b0e8c4bd455153e8794ad7Ea8Ff5A14B64E4b", + "router": "0x141fa059441E0ca23ce184B6A78bafD2A517DdE8", + "price_registry": "0x13015e4E6f839E1Aa1016DF521ea458ecA20438c", + "wrapped_native": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "version" : "1.4.0", + "src_contracts": { + "Avalanche Mainnet": { + "on_ramp": "0x05B723f3db92430FbE4395fD03E40Cc7e9D17988", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x77b60F85b25fD501E3ddED6C1fe7bF565C08A22A", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0x79f3ABeCe5A3AFFf32D47F4CFe45e7b65c9a2D91", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0xCe11020D56e5FDbfE46D9FC3021641FfbBB5AdEE", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0xC09b72E8128620C40D89649019d995Cc79f030C3", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x122F05F49e90508F089eE8D0d868d1a4f3E5a809", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x66a0046ac9FA104eB38B04cfF391CcD0122E6FbC", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Avalanche Mainnet": { + "off_ramp": "0xe0109912157d5B75ea8b3181123Cf32c73bc9920", + "commit_store": "0xDaa61b8Cd85977820f92d1e749E1D9F55Da6CCEA", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0xdB19F77F87661f9be0F557cf9a1ebeCf7D8F206c", + "commit_store": "0x6e37f4c82d9A31cc42B445874dd3c3De97AB553f", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0xB1b705c2315fced1B38baE463BE7DDef531e47fA", + "commit_store": "0x310cECbFf14Ad0307EfF762F461a487C1abb90bf", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x542ba1902044069330e8c5b36A84EC503863722f", + "commit_store": "0x060331fEdA35691e54876D957B4F9e3b8Cb47d20", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0xeeed4D86F3E0e6d32A6Ad29d8De6A0Dc91963A5f", + "commit_store": "0xbbB563c4d98020b9c0f3Cc34c2C0Ef9676806E35", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x9bDA7c8DCda4E39aFeB483cc0B7E3C1f6E0D5AB1", + "commit_store": "0x63a0AeaadAe851b990bBD9dc41f5C1B08b32026d", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0xEEf5Fb4c4953F9cA9ab1f25cE590776AfFc2c455", + "commit_store": "0xD268286A277095a9C3C90205110831a84505881c", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Avalanche Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x5947BB275c521040051D82396192181b413227A3", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0xdFD6C0dc67666DE3bB36b31eec5c7B1542A82C1E", + "router": "0xF4c7E640EdA248ef95972845a62bdC74237805dB", + "price_registry": "0xfA4edD04eaAcDB07c8D73621bc1790eC50D8c489", + "wrapped_native": "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x98f51B041e493fc4d72B8BD33218480bA0c66DDF", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x268fb4311D2c6CB2bbA01CCA9AC073Fb3bfd1C7c", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0x8eaae6462816CB4957184c48B86afA7642D8Bf2B", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0xD0701FcC7818c31935331B02Eb21e91eC71a1704", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x8629008887E073260c5434D6CaCFc83C3001d211", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x97500490d9126f34cf9aA0126d64623E170319Ef", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x9b1ed9De069Be4d50957464b359f98eD0Bf34dd5", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x770b1375F86E7a9bf30DBe3F97bea67193dC9135", + "commit_store": "0x23E2b34Ce8e12c53f8a39AD4b3FFCa845f8E617C", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0x4d6A796Bc85dcDF41ce9AaEB50B094C6b589748f", + "commit_store": "0xc4C4358FA01a04D6c6FE3b96a351946d4c2715C2", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0x83F53Fc798FEbfFbdF84830AD403b9989187a06C", + "commit_store": "0xD8ceCE2D7794385E00Ce3EF94550E732b0A0B959", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x5B833BD6456c604Eb396C0fBa477aD49e82B1A2a", + "commit_store": "0x23E23958D220B774680f91c2c91a6f2B2f610d7e", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0xb68A3EE8bD0A09eE221cf1859Dd5a4d5765188Fe", + "commit_store": "0x83DCeeCf822981F9F8552925eEfd88CAc1905dEA", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x19250aBE66B88F214d02B6f3BF80F4118290C619", + "commit_store": "0x87A0935cE6254dB1252bBac90d1D07D04846aDCA", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0x317dE8bc5c3292E494b6496586696d4966A922B0", + "commit_store": "0x97Fbf3d6DEac16adC721aE9187CeEa1e610aC7Af", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Base Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x38660c8CC222c0192b635c2ac09687B4F25cCE5F", + "router": "0x881e3A65B4d4a04dD529061dd0071cf975F58bCD", + "price_registry": "0x6337a58D4BD7Ba691B66341779e8f87d4679923a", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x1E5Ca70d1e7A1B26061125738a880BBeA42FeB21", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0xBE5a9E336D9614024B4Fa10D8112671fc9A42d96", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0xdd4Fb402d41Beb0eEeF6CfB1bf445f50bDC8c981", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0xDEA286dc0E01Cb4755650A6CF8d1076b454eA1cb", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0xd952FEAcDd5919Cc5E9454b53bF45d4E73dD6457", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x3DB8Bea142e41cA3633890d0e5640F99a895D6A5", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x8531E63aE9279a1f0D09eba566CD1b092b95f3D5", + "commit_store": "0x327E13f54c7871a2416006B33B4822eAAD357916", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Mainnet": { + "off_ramp": "0x8345F2fF67e5A65e85dc955DE1414832608E00aD", + "commit_store": "0xd0b13be4c53A6262b47C5DDd36F0257aa714F562", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0x48a51f5D38BE630Ddd6417Ea2D9052B8efc91a18", + "commit_store": "0xF97127e77252284EC9D4bc13C247c9D1A99F72B0", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0xEC0cFe335a4d53dBA70CB650Ab56eEc32788F0BB", + "commit_store": "0x0ae3c2c7FB789bd05A450CD3075D11f6c2Ca4F77", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0xf50c0d2a8B6Db60f1D93E60f03d0413D56153E4F", + "commit_store": "0x16f72C15165f7C9d74c12fDF188E399d4d3724e4", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x75F29f058b31106F99caFdc17c9b26ADfcC7b5D7", + "commit_store": "0xb719616E732581B570232DfB13Ca49D27667Af9f", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "BSC Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x404460C6A5EdE2D891e8297795264fDe62ADBB75", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x3DB43b96B2625F4232e9Df900d464dd2c64C0021", + "router": "0x34B03Cb9086d7D758AC55af71584F81A598759FE", + "price_registry": "0xd64aAbD70A71d9f0A00B99F6EFc1626aA2dD43C7", + "wrapped_native": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "src_contracts": { + "Avalanche Mainnet": { + "on_ramp": "0x6aa72a998859eF93356c6521B72155D355D0Cfd2", + "deployed_at": 11111111 + }, + "Arbitrum Mainnet": { + "on_ramp": "0x2788b46BAcFF49BD89562e6bA5c5FBbbE5Fa92F7", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x70bC7f7a6D936b289bBF5c0E19ECE35B437E2e36", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0x0Bf40b034872D0b364f3DCec04C7434a4Da1C8d9", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x4FEB11A454C9E8038A8d0aDF599Fe7612ce114bA", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x6bD4754D86fc87FE5b463D368f26a3587a08347c", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x1467fF8f249f5bc604119Af26a47035886f856BE", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Avalanche Mainnet": { + "off_ramp": "0x37a6fa55fe61061Ae97bF7314Ae270eCF71c5ED3", + "commit_store": "0x1f558F6dcf0224Ef1F78A24814FED548B9602c80", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Arbitrum Mainnet": { + "off_ramp": "0x3DA330fd8Ef10d93cFB7D4f8ecE7BC1F10811feC", + "commit_store": "0x86D55Ff492cfBBAf0c0D42D4EE615144E78b3D02", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0x574c697deab06B805D8780898B3F136a1F4892Dc", + "commit_store": "0x002B164b1dcf4E92F352DC625A01Be0E890EdEea", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x181Bb1E97b0bDD1D85E741ad0943552D3682cc35", + "commit_store": "0x3fF27A34fF0FA77921C3438e67f58da1a83e9Ce1", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0xE7E080C8d62d595a223C577C7C8d1f75d9A5E664", + "commit_store": "0xF4d53346bDb6d393C74B0B72Aa7D6689a3eAad79", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x26af2046Da85d7f6712D5edCa81B9E3b2e7A60Ab", + "commit_store": "0x4C1dA405a789AC2853A69D8290B8B9b47a0374F8", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0xC027C5AEb230008c243Be463A73571e581F94c13", + "commit_store": "0x2EB426C8C54D740d1FC856eB3Ff96feA03957978", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Ethereum Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x514910771AF9Ca656af840dff83E8264EcF986CA", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x8B63b3DE93431C0f756A493644d128134291fA1b", + "router": "0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D", + "price_registry": "0x8c9b2Efb7c64C394119270bfecE7f54763b958Ad", + "wrapped_native": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x925228D7B82d883Dde340A55Fe8e6dA56244A22C", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0x3df8dAe2d123081c4D5E946E655F7c109B9Dd630", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0xe2c2AB221AA0b957805f229d2AA57fBE2f4dADf7", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0x91D25A56Db77aD5147437d8B83Eb563D46eBFa69", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x86B47d8411006874eEf8E4584BdFD7be8e5549d1", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x35F0ca9Be776E4B38659944c257bDd0ba75F1B8B", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0xCbE7e5DA76dC99Ac317adF6d99137005FDA4E2C4", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0xeFC4a18af59398FF23bfe7325F2401aD44286F4d", + "commit_store": "0x9B2EEd6A1e16cB50Ed4c876D2dD69468B21b7749", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Mainnet": { + "off_ramp": "0x569940e02D4425eac61A7601632eC00d69f75c17", + "commit_store": "0x2aa101BF99CaeF7fc1355D4c493a1fe187A007cE", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0xdf85c8381954694E74abD07488f452b4c2Cddfb3", + "commit_store": "0x8DC27D621c41a32140e22E2a4dAf1259639BAe04", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0x7Afe7088aff57173565F4b034167643AA8b9171c", + "commit_store": "0x87c55D48DF6EF7B08153Ab079e76bFEcbb793D75", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0xB095900fB91db00E6abD247A5A5AD1cee3F20BF7", + "commit_store": "0x4af4B497c998007eF83ad130318eB2b925a79dc8", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x0af338F0E314c7551bcE0EF516d46d855b0Ee395", + "commit_store": "0xD37a60E8C36E802D2E1a6321832Ee85556Beeb76", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0x3a129e6C18b23d18BA9E6Aa14Dc2e79d1f91c6c5", + "commit_store": "0x31f6ab382DDeb9A316Ab61C3945a5292a50a89AB", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Kroma Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xC1F6f7622ad37C3f46cDF6F8AA0344ADE80BF450", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0xB59779d3364BC6d71168245f9ebb96469E5a5a98", + "router": "0xE93E8B0d1b1CEB44350C8758ed1E2799CCee31aB", + "price_registry": "0x8155B4710e7bbC90924E957104F94Afd4f95Eca2", + "wrapped_native": "0x4200000000000000000000000000000000000001", + "src_contracts": { + "WeMix Mainnet": { + "on_ramp": "0x3C5Ab46fA1dB1dECD854224654313a69bf9fcAD3", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "WeMix Mainnet": { + "off_ramp": "0x2B555774B3D1dcbcd76efb7751F3c5FbCFABC5C4", + "commit_store": "0x213124614aAf31eBCE7c612A12aac5f8aAD77DE4", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Optimism Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x8C7C2C3362a42308BB5c368677Ad321D11693b81", + "router": "0x3206695CaE29952f4b0c22a169725a865bc8Ce0f", + "price_registry": "0xb52545aECE8C73A97E52a146757EC15b90Ed8488", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x0C9BE7Cfd12c735E5aaE047C1dCB845d54E518C3", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0xD0D3E757bFBce7ae1881DDD7F6d798DDcE588445", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x0b1760A8112183303c5526C6b24569fd3A274f3B", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0xa3c9544B82846C45BE37593d5d9ACffbE61BF3A6", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0x55183Db1d2aE0b63e4c92A64bEF2CBfc2032B127", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x6B57145e322c877E7D91Ed8E31266eB5c02F7EfC", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x82e9f4C5ec4a84E310d60D462a12042E5cbA0954", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x0C9BE7Cfd12c735E5aaE047C1dCB845d54E518C3", + "commit_store": "0x55028780918330FD00a34a61D9a7Efd3f43ca845", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Mainnet": { + "off_ramp": "0x8dc6490A6204dF846BaBE809cB695ba17Df1F9B1", + "commit_store": "0xA190660787B6B183Dd82B243eA10e609327c7308", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0xBAE6560eCa9B77Cb047158C783e36F7735C86037", + "commit_store": "0x6168aDF58e1Ad446BaD45c6275Bef60Ef4FFBAb8", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0xE14501F2838F2fA1Ceb52E78ABdA289EcE1705EA", + "commit_store": "0xa8DD25B29787527Df283211C24Ac72B17150A696", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0xd2D98Be6a1C241e86C807e51cED6ABb51d044203", + "commit_store": "0x4d75A5cE454b264b187BeE9e189aF1564a68408D", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x7c6221880A1D62506b1A08Dab3Bf695A49AcDD22", + "commit_store": "0x0684076EE3595221861C50cDb9Cb66402Ec11Cb9", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0x3e5B3b7559D39563a74434157b31781322dA712D", + "commit_store": "0x7954372FF6f80908e5A2dC2a19d796A1005f91D2", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Polygon Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xb0897686c545045aFc77CF20eC7A532E3120E0F1", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0xD7AcF65dA1E1f34b663aB199a474F209bF2b0523", + "router": "0x849c5ED5a80F5B408Dd4969b78c2C8fdf0565Bfe", + "price_registry": "0x30D873664Ba766C983984C7AF9A921ccE36D34e1", + "wrapped_native": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0xD16D025330Edb91259EEA8ed499daCd39087c295", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0x5FA30697e90eB30954895c45b028F7C0dDD39b12", + "deployed_at": 11111111 + }, + "Base Mainnet": { + "on_ramp": "0x20B028A2e0F6CCe3A11f3CE5F2B8986F932e89b4", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0xF5b5A2fC11BF46B1669C3B19d98B19C79109Dca9", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0xFd77c53AA4eF0E3C01f5Ac012BF7Cc7A3ECf5168", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x3111cfbF5e84B5D9BD952dd8e957f4Ca75f728Cf", + "deployed_at": 11111111 + }, + "WeMix Mainnet": { + "on_ramp": "0x5060eF647a1F66BE6eE27FAe3046faf8D53CeB2d", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0xa8a9eDa2867c2E0CE0d5ECe273961F1EcC3CC25B", + "commit_store": "0xbD4480658dca8496a65046dfD1BDD44EF897Bdb5", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Mainnet": { + "off_ramp": "0xB9e3680639c9F0C4e0b02FD81C445094426244Ae", + "commit_store": "0x8c63d4e67f7c4af6FEd2f56A34fB4e01CB807CFF", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Mainnet": { + "off_ramp": "0xD0FA7DE2D18A0c59D3fD7dfC7aB4e913C6Aa7b68", + "commit_store": "0xF88053B9DAC8Dd3039a4eFa8639159aaa3F2D4Cb", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0x592773924741F0Da889a0dfdab71171Dd11E054C", + "commit_store": "0xEC4d35E1A85f770f4D93BA43a462c9d87Ef7017e", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x45320085fF051361D301eC1044318213A5387A15", + "commit_store": "0x4Dc771B5ef21ef60c33e2987E092345f2b63aE08", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0xBa754ecd3CFA7E9093F688EAc3860cf9D07Fc0AC", + "commit_store": "0x04C0D5302E3D8Ca0A0019141a52a23B59cdb70e4", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Mainnet": { + "off_ramp": "0xd7c877ea02310Cce9278D9A048Aa1Bb9aF72F00d", + "commit_store": "0x92A1C927E8E10Ab6A40E5A5154e2300D278d1a67", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "WeMix Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x80f1FcdC96B55e459BF52b998aBBE2c364935d69", + "bridge_tokens": [], + "bridge_tokens_pools": [], + "arm": "0x07aaC8B69A62dB5bd3d244091916EbF2fac17b76", + "router": "0x7798b795Fde864f4Cd1b124a38Ba9619B7F8A442", + "price_registry": "0x252863688762aD86868D3d3076233Eacd80c7055", + "wrapped_native": "0x7D72b22a74A216Af4a002a1095C8C707d6eC1C5f", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x9aBfd6f4C865610692AB6fb1Be862575809fFabf", + "deployed_at": 11111111 + }, + "Avalanche Mainnet": { + "on_ramp": "0xbE0Cfae74677F8dd16a246a3a5c8cbB1973118f4", + "deployed_at": 11111111 + }, + "BSC Mainnet": { + "on_ramp": "0x56657ec4D15C71f7F3C17ba2b21C853A24Dc5381", + "deployed_at": 11111111 + }, + "Optimism Mainnet": { + "on_ramp": "0x70f3b0FD7e6a4B9B623e9AB859604A9EE03e48BD", + "deployed_at": 11111111 + }, + "Polygon Mainnet": { + "on_ramp": "0x777058C1e1dcE4eB8001F38631a1cd9450816e5a", + "deployed_at": 11111111 + }, + "Ethereum Mainnet": { + "on_ramp": "0x190bcE84CF2d500B878966F4Cf98a50d78f2675E", + "deployed_at": 11111111 + }, + "Kroma Mainnet": { + "on_ramp": "0x47E9AE0A815C94836202E696748A5d5476aD8735", + "deployed_at": 11111111 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x2ba68a395B72a6E3498D312efeD755ed2f3CF223", + "commit_store": "0xdAeC234DA83F68707Bb8AcB2ee6a01a5FD4c2391", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Mainnet": { + "off_ramp": "0xFac907F9a1087B846Faa75A14C5d34A8639233d8", + "commit_store": "0xF2812063446c7deD2CA306c67A68364BdDcbEfc5", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Mainnet": { + "off_ramp": "0x6ec9ca4Cba62cA17c55F05ad2000B46192f02035", + "commit_store": "0x84534BE763366a69710E119c100832955795B34B", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Mainnet": { + "off_ramp": "0x87220D01DF0fF27149B47227897074653788fd23", + "commit_store": "0xF8dD2be2C6FA43e48A17146380CbEBBB4291807b", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Mainnet": { + "off_ramp": "0x8f0229804513A9Bc00c1308414AB279Dbc718ae1", + "commit_store": "0x3A85D1b8641d83a87957C6ECF1b62151213e0842", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Ethereum Mainnet": { + "off_ramp": "0xF92Fa796F5307b029c65CA26f322a6D86f211194", + "commit_store": "0xbeC110FF43D52be2066B06525304A9924E16b73b", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Kroma Mainnet": { + "off_ramp": "0xF886d8DC64E544af4835cbf91e5678A54D95B80e", + "commit_store": "0x8794C9534658fdCC44f2FF6645Bf31cf9F6d2d5D", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + } + } +} +""" + +[CCIP.Env] +TTL = '8h' + +[CCIP.Env.Network] +selected_networks = [ + 'ETHEREUM_MAINNET', + 'ARBITRUM_MAINNET', + 'BASE_MAINNET', + 'WEMIX_MAINNET', + 'OPTIMISM_MAINNET', + 'POLYGON_MAINNET', + 'AVALANCHE_MAINNET', + 'BSC_MAINNET', + 'KROMA_MAINNET' + ] + +[CCIP.Groups.load] +NetworkPairs = [ + 'ETHEREUM_MAINNET,OPTIMISM_MAINNET', + 'ETHEREUM_MAINNET,AVALANCHE_MAINNET', + 'ETHEREUM_MAINNET,POLYGON_MAINNET', + 'ETHEREUM_MAINNET,BSC_MAINNET', + 'ETHEREUM_MAINNET,ARBITRUM_MAINNET', + 'ETHEREUM_MAINNET,BASE_MAINNET', + 'ETHEREUM_MAINNET,WEMIX_MAINNET', + 'AVALANCHE_MAINNET,POLYGON_MAINNET', + 'BASE_MAINNET,OPTIMISM_MAINNET', + 'BASE_MAINNET,ARBITRUM_MAINNET', + 'AVALANCHE_MAINNET,BSC_MAINNET', + 'BSC_MAINNET,POLYGON_MAINNET', + 'OPTIMISM_MAINNET,POLYGON_MAINNET', + 'BASE_MAINNET,BSC_MAINNET', + 'POLYGON_MAINNET,ARBITRUM_MAINNET', # added as batch 1 + 'ARBITRUM_MAINNET,BSC_MAINNET', # added as batch 1 + 'ARBITRUM_MAINNET,OPTIMISM_MAINNET', # added as batch 1 + 'AVALANCHE_MAINNET,OPTIMISM_MAINNET', # added as batch 2 + 'AVALANCHE_MAINNET,ARBITRUM_MAINNET', # added as batch 2 + 'BASE_MAINNET,POLYGON_MAINNET', # added as batch 2 + 'BSC_MAINNET,OPTIMISM_MAINNET', # added as batch 2 + 'AVALANCHE_MAINNET,BASE_MAINNET', # added as batch 2 + 'WEMIX_MAINNET,KROMA_MAINNET', + 'BSC_MAINNET,WEMIX_MAINNET', # added as batch 2 + 'AVALANCHE_MAINNET,WEMIX_MAINNET', # added as batch 2 + 'POLYGON_MAINNET,WEMIX_MAINNET', # added as batch 2 + 'WEMIX_MAINNET,ARBITRUM_MAINNET', # added as batch 2 + 'OPTIMISM_MAINNET,WEMIX_MAINNET' # added as batch 2 +] + +BiDirectionalLane = true +PhaseTimeout = '20m' +ExistingDeployment = true + +[CCIP.Groups.load.TokenConfig] +NoOfTokensPerChain = 1 + +[CCIP.Groups.load.LoadProfile] +RequestPerUnitTime = [1] +TimeUnit = '1h' +TestDuration = '5h' +TestRunName = 'mainnet-2.7-ccip1.2' +FailOnFirstErrorInLoad = true +SkipRequestIfAnotherRequestTriggeredWithin = '40m' + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 0 +DataLength = 100 +NoOfTokens = 1 +AmountPerToken = 1 + +[CCIP.Groups.smoke] +# these are all the valid network pairs +NetworkPairs = [ + 'ETHEREUM_MAINNET,OPTIMISM_MAINNET', + 'ETHEREUM_MAINNET,AVALANCHE_MAINNET', + 'ETHEREUM_MAINNET,POLYGON_MAINNET', + 'ETHEREUM_MAINNET,BSC_MAINNET', + 'ETHEREUM_MAINNET,ARBITRUM_MAINNET', + 'ETHEREUM_MAINNET,BASE_MAINNET', + 'ETHEREUM_MAINNET,WEMIX_MAINNET', + 'AVALANCHE_MAINNET,POLYGON_MAINNET', + 'BASE_MAINNET,OPTIMISM_MAINNET', + 'BASE_MAINNET,ARBITRUM_MAINNET', + 'AVALANCHE_MAINNET,BSC_MAINNET', + 'BSC_MAINNET,POLYGON_MAINNET', + 'OPTIMISM_MAINNET,POLYGON_MAINNET', + 'BASE_MAINNET,BSC_MAINNET', + 'POLYGON_MAINNET,ARBITRUM_MAINNET', # added as batch 1 + 'ARBITRUM_MAINNET,BSC_MAINNET', # added as batch 1 + 'ARBITRUM_MAINNET,OPTIMISM_MAINNET', # added as batch 1 + 'AVALANCHE_MAINNET,OPTIMISM_MAINNET', # added as batch 2 + 'AVALANCHE_MAINNET,ARBITRUM_MAINNET', # added as batch 2 + 'BASE_MAINNET,POLYGON_MAINNET', # added as batch 2 + 'BSC_MAINNET,OPTIMISM_MAINNET', # added as batch 2 + 'AVALANCHE_MAINNET,BASE_MAINNET', # added as batch 2 + 'WEMIX_MAINNET,KROMA_MAINNET', + 'BSC_MAINNET,WEMIX_MAINNET', # added as batch 2 + 'AVALANCHE_MAINNET,WEMIX_MAINNET', # added as batch 2 + 'POLYGON_MAINNET,WEMIX_MAINNET', # added as batch 2 + 'WEMIX_MAINNET,ARBITRUM_MAINNET', # added as batch 2 + 'OPTIMISM_MAINNET,WEMIX_MAINNET' # added as batch 2 +] + +BiDirectionalLane = true +PhaseTimeout = '20m' +LocalCluster = false +ExistingDeployment = true +ReuseContracts = true + + +[CCIP.Groups.smoke.TokenConfig] +NoOfTokensPerChain = 1 +CCIPOwnerTokens = true + +[CCIP.Groups.smoke.MsgDetails] +MsgType = 'Data' +DestGasLimit = 0 +DataLength = 100 +NoOfTokens = 1 +AmountPerToken = 1 \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip-crib.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip-crib.toml new file mode 100644 index 0000000000..12afcea791 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/ccip-crib.toml @@ -0,0 +1,96 @@ +[CCIP] +[CCIP.Env] +Mockserver = 'http://mockserver:1080' + +[CCIP.Env.Network] +selected_networks = ['AVALANCHE_FUJI', 'BSC_TESTNET'] + +[CCIP.Env.Network.EVMNetworks.AVALANCHE_FUJI] +evm_name = 'Avalanche Fuji' +evm_chain_id = 43113 +evm_urls = ['wss://...'] +evm_http_urls = ['https://...'] +evm_keys = [''] +evm_simulated = false +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 50000 +evm_transaction_timeout = '2m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_tag = true + +[CCIP.Env.Network.EVMNetworks.BSC_TESTNET] +evm_name = 'BSC Testnet' +evm_chain_id = 97 +evm_urls = ['wss://...'] +evm_http_urls = ['https://...'] +evm_keys = [''] +evm_simulated = false +client_implementation = 'BSC' +evm_chainlink_transaction_limit = 50000 +evm_transaction_timeout = '2m' +evm_minimum_confirmations = 3 +evm_gas_estimation_buffer = 0 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_tag = true + +[CCIP.Env.ExistingCLCluster] +Name = 'crib-ani' +NoOfNodes = 6 + +[[CCIP.Env.ExistingCLCluster.NodeConfigs]] +URL = 'https://crib-ani-demo-node1.main.stage.cldev.sh/' +Email = 'notreal@fakeemail.ch' +Password = 'fj293fbBnlQ!f9vNs' +InternalIP = 'app-node-1' + + +[[CCIP.Env.ExistingCLCluster.NodeConfigs]] +URL = 'https://crib-ani-demo-node2.main.stage.cldev.sh/' +Email = 'notreal@fakeemail.ch' +Password = 'fj293fbBnlQ!f9vNs' +InternalIP = 'app-node-2' + +[[CCIP.Env.ExistingCLCluster.NodeConfigs]] +URL = 'https://crib-ani-demo-node3.main.stage.cldev.sh/' +Email = 'notreal@fakeemail.ch' +Password = 'fj293fbBnlQ!f9vNs' +InternalIP = 'app-node-3' + +[[CCIP.Env.ExistingCLCluster.NodeConfigs]] +URL = 'https://crib-ani-demo-node4.main.stage.cldev.sh/' +Email = 'notreal@fakeemail.ch' +Password = 'fj293fbBnlQ!f9vNs' +InternalIP = 'app-node-4' + +[[CCIP.Env.ExistingCLCluster.NodeConfigs]] +URL = 'https://crib-ani-demo-node5.main.stage.cldev.sh/' +Email = 'notreal@fakeemail.ch' +Password = 'fj293fbBnlQ!f9vNs' +InternalIP = 'app-node-5' + +[[CCIP.Env.ExistingCLCluster.NodeConfigs]] +URL = 'https://crib-ani-demo-node6.main.stage.cldev.sh/' +Email = 'notreal@fakeemail.ch' +Password = 'fj293fbBnlQ!f9vNs' +InternalIP = 'app-node-6' + +[CCIP.Groups] +[CCIP.Groups.smoke] +LocalCluster = false +TestRunName = 'crib-ani-demo' +NodeFunding = 1000.0 + + +[CCIP.Groups.load] +LocalCluster = false + +[CCIP.Groups.load.LoadProfile] +TestRunName = 'crib-ani-demo' +TimeUnit = '1s' +TestDuration = '15m' +RequestPerUnitTime = [1] +NodeFunding = 1000.0 diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml new file mode 100644 index 0000000000..0157ac24fb --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml @@ -0,0 +1,440 @@ +# this file contains the deafult configuration for the test +# all secrets must be stored in .env file and sourced before running the test +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = 'latest' +OffRamp = 'latest' +OnRamp = 'latest' +CommitStore = 'latest' +TokenPool = 'latest' + +# all variables to set up the test environment +[CCIP.Env] +TTL = '5h' +# networks between which lanes will be set up and the messages will be sent +# if more than 2 networks are specified, then lanes will be set up between all possible pairs of networks +# for example , if Networks = ['SIMULATED_1', 'SIMULATED_2', 'SIMULATED_3'], +# then lanes will be set up between SIMULATED_1 and SIMULATED_2, SIMULATED_1 and SIMULATED_3, SIMULATED_2 and SIMULATED_3 +# default value is ['SIMULATED_1', 'SIMULATED_2'] which means that test will create two private geth networks from scratch and set up lanes between them +[CCIP.Env.Network] +selected_networks = ['SIMULATED_1', 'SIMULATED_2'] + +# PrivateEthereumNetworks.NETWORK_NAME contains the configuration of private ethereum network that includes ethereum version, evm node client, chain id, +# certain chain configurations, addresses to fund or custom docker images to be used. These are non-dev networks, but they all run just a single node. +[CCIP.Env.PrivateEthereumNetworks.SIMULATED_1] +# either eth1 or eth2 (for post-Merge); for eth2 Prysm is used for consensus layer. +ethereum_version = "eth1" +# geth, besu, erigon or nethermind +execution_layer = "geth" +# eth2-only, if set to true environment startup will wait until at least 1 epoch has been finalised +wait_for_finalization=false + +[CCIP.Env.PrivateEthereumNetworks.SIMULATED_1.EthereumChainConfig] +# eth2-only, the lower the value the faster the block production (3 is minimum) +seconds_per_slot = 3 +# eth2-only, the lower the value the faster the epoch finalisation (2 is minimum) +slots_per_epoch = 2 +# eht2-only, the lower tha value the faster the chain starts (10 is minimum) +genesis_delay = 15 +# eth2-only, number of validators +validator_count = 4 +chain_id = 1337 +# address that should be founded in genesis wih ETH +addresses_to_fund = [ + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", +] + +[CCIP.Env.PrivateEthereumNetworks.SIMULATED_1.EthereumChainConfig.HardForkEpochs] +# eth2-only, epoch at which chain will upgrade do Dencun or Deneb/Cancun (1 is minimum) +Deneb = 500 + +#[CCIP.Env.PrivateEthereumNetworks.SIMULATED_1.CustomDockerImages] +# custom docker image that will be used for execution layer client. It has to be one of: hyperledger/besu, nethermind/nethermind, thorax/erigon or ethereum/client-go. +# instead of using a specific tag you can also use "latest_available" to use latest published tag in Github or "latest_stable" to use latest stable release from Github +# (if corresponding Docker image on Docker Hub has not been published environment creation will fail). +#execution_layer="hyperledger/besu:latest_stable" + +[CCIP.Env.PrivateEthereumNetworks.SIMULATED_2] +ethereum_version = "eth1" +execution_layer = "geth" + +[CCIP.Env.PrivateEthereumNetworks.SIMULATED_2.EthereumChainConfig] +seconds_per_slot = 3 +slots_per_epoch = 2 +genesis_delay = 15 +validator_count = 4 +chain_id = 2337 +addresses_to_fund = [ + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", +] + +[CCIP.Env.PrivateEthereumNetworks.SIMULATED_2.EthereumChainConfig.HardForkEpochs] +Deneb = 500 + +[CCIP.Env.Logging] +test_log_collect = false # if set to true will save logs even if test did not fail + +[CCIP.Env.Logging.LogStream] +# supported targets: file, loki, in-memory. if empty no logs will be persistet +log_targets = ["file"] +# context timeout for starting log producer and also time-frame for requesting logs +log_producer_timeout = "10s" +# number of retries before log producer gives up and stops listening to logs +log_producer_retry_limit = 10 + +# these values will be used to set up chainlink DON +# along with these values, the secrets needs to be specified as part of .env variables +# +[CCIP.Env.NewCLCluster] +NoOfNodes = 6 # number of chainlink nodes to be set up in DON, including one bootstrap node +# if tests are run in k8s, then the following values will be used to set up chainlink nodes and postgresql database, +# in case of local deployment through docker container, these values will be ignored +# for k8s deployment, helm charts are used from https://github.com/smartcontractkit/chainlink-testing-framework/tree/main/charts/chainlink/templates +NodeMemory = '4Gi' # memory to be allocated to each chainlink node; only used if tests are in k8s +NodeCPU = '2' # cpu to be allocated to each chainlink node ; only used if tests are in k8s +DBMemory = '4Gi' # memory to be allocated to postgresql database ; only used if tests are in k8s +DBCPU = '2' # cpu to be allocated to postgresql database ; only used if tests are in k8s +DBCapacity = '10Gi' # disk space to be allocated to postgresql database ; only used if tests are in k8s in stateful deployment +IsStateful = true # if true, chainlink nodes and postgresql database will be deployed as stateful set in k8s +DBArgs = [ + 'shared_buffers=1536MB', + 'effective_cache_size=4096MB', + 'work_mem=64MB', +] # postgresql database arguments ; only used if tests are in k8s + +# these values will be used to set up chainlink DON, if all the chainlink nodes are deployed with same configuration +[CCIP.Env.NewCLCluster.Common] +Name = 'node1' # name of the chainlink node, used as prefix for all the chainlink node names , used for k8s deployment +DBImage = 'postgres' # postgresql database image to be used for k8s deployment +DBTag = '13.12' # postgresql database image tag to be used for k8s deployment +# override config toml file for chainlink nodes +BaseConfigTOML = """ +[Feature] +LogPoller = true +CCIP = true + +[Log] +Level = 'debug' +JSONConsole = true + +[Log.File] +MaxSize = '0b' + +[WebServer] +AllowOrigins = '*' +HTTPPort = 6688 +SecureCookies = false +HTTPWriteTimeout = '1m' + +[WebServer.RateLimit] +Authenticated = 2000 +Unauthenticated = 1000 + +[WebServer.TLS] +HTTPSPort = 0 + +[Database] +MaxIdleConns = 10 +MaxOpenConns = 20 +MigrateOnStartup = true + +[OCR2] +Enabled = true +DefaultTransactionQueueDepth = 0 + +[OCR] +Enabled = false +DefaultTransactionQueueDepth = 0 + +[P2P] +[P2P.V2] +Enabled = true +ListenAddresses = ['0.0.0.0:6690'] +AnnounceAddresses = ['0.0.0.0:6690'] +DeltaDial = '500ms' +DeltaReconcile = '5s' +""" + +# override config toml related to EVMNode configs for chainlink nodes; applicable to all EVM node configs in chainlink toml +CommonChainConfigTOML = """ +[GasEstimator] +PriceMax = '200 gwei' +LimitDefault = 6000000 +FeeCapDefault = '200 gwei' +""" + +# chainlink override config toml for EVMNode config specific to EVM chains with chain id as mentioned in the key +[CCIP.Env.NewCLCluster.Common.ChainConfigTOMLByChain] +# applicable for arbitrum-goerli chain +421613 = """ +[GasEstimator] +PriceMax = '400 gwei' +LimitDefault = 100000000 +FeeCapDefault = '200 gwei' +BumpThreshold = 60 +BumpPercent = 20 +BumpMin = '100 gwei' +""" + +# applicable for optimism-goerli chain +420 = """ +[GasEstimator] +PriceMax = '150 gwei' +LimitDefault = 6000000 +FeeCapDefault = '150 gwei' +BumpThreshold = 60 +BumpPercent = 20 +BumpMin = '100 gwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 200 +EIP1559FeeCapBufferBlocks = 0 +""" + +# applicable for base-goerli chain +84531 = """ +[GasEstimator] +PriceMax = '150 gwei' +LimitDefault = 6000000 +FeeCapDefault = '150 gwei' +BumpThreshold = 60 +BumpPercent = 20 +BumpMin = '100 gwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 200 +EIP1559FeeCapBufferBlocks = 0 +""" + +# applicable for avalanche-fuji chain +43113 = """ +[GasEstimator] +PriceMax = '200 gwei' +LimitDefault = 6000000 +FeeCapDefault = '200 gwei' +BumpThreshold = 60 +""" + +# applicable for sepolia chain +11155111 = """ +[GasEstimator] +PriceMax = '200 gwei' +LimitDefault = 6000000 +FeeCapDefault = '200 gwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 200 +EIP1559FeeCapBufferBlocks = 0 +""" + +# the following configs are specific to each test type, smoke, load , chaos, etc... +[CCIP.Groups] +[CCIP.Groups.smoke] +# uncomment the following with specific values of lane combinations to be tested, if you want to run your tests to run only on these specific network pairs +# if specific network pairs are not mentioned, then all the network pairs will be tested based on values in CCIP.Env.NetworkPairs and CCIP.Groups..NoOfNetworks +# if specified, CCIP.Groups..NetworkPairs takes precedence over CCIP.Env.NetworkPairs and CCIP.Groups..NoOfNetworks +#NetworkPairs = ['SEPOLIA,OPTIMISM_GOERLI','SEPOLIA,POLYGON_MUMBAI','AVALANCHE_FUJI,SEPOLIA','SEPOLIA,BASE_GOERLI','SEPOLIA,BSC_TESTNET','SEPOLIA,WEMIX_TESTNET','AVALANCHE_FUJI,OPTIMISM_GOERLI','AVALANCHE_FUJI,POLYGON_MUMBAI','AVALANCHE_FUJI,BSC_TESTNET','AVALANCHE_FUJI,BASE_GOERLI','OPTIMISM_GOERLI,BASE_GOERLI','OPTIMISM_GOERLI,POLYGON_MUMBAI','BSC_TESTNET,POLYGON_MUMBAI','BSC_TESTNET,BASE_GOERLI','WEMIX_TESTNET,KROMA_SEPOLIA'] + +KeepEnvAlive = false # if true, the test will not tear down the test environment after the test is finished +CommitAndExecuteOnSameDON = true # if true, and the test is building the env from scratch, same chainlink nodes will be used for Commit and Execution jobs. +# Otherwise Commit and execution jobs will be set up in different nodes based on the number of nodes specified in NoOfCommitNodes and CCIP.Env.NewCLCluster.NoOfNodes +BiDirectionalLane = true # True uses both the lanes. If bidirectional is false only one way lane is set up. +NoOfCommitNodes = 5 # no of chainlink nodes with Commit job +PhaseTimeout = '10m' # Duration to wait for the each phase validation(SendRequested, Commit, RMN Blessing, Execution) to time-out. +LocalCluster = true # if true, the test will use the local docker container, otherwise it will use the k8s cluster +ExistingDeployment = false # true if the tests are run on existing environment with already set-up jobs, smart contracts, etc... +# In this case the test will only be used to send and verify ccip requests considering that lanes are already functioning. +# In case of ExistingDeployment = false, the test will deploy it's own contracts and spin up new chainlink nodes with ccip jobs. It will then use +# the newly deployed contracts to send and verify ccip requests. + +ReuseContracts = true # Whether to reuse the contracts deployed in the previous run. Default value is true unless specified +NodeFunding = 1.0 # Amount of native currency to fund the chainlink node with for each network. Default value is 1 for smoke and 20 for load unless specified +NoOfRoutersPerPair = 1 # denotes the number of routers to be deployed per network. mostly required for scalability tests. +MulticallInOneTx = false # if set to true, multiple ccip-send is grouped under one blockchain transaction +NoOfSendsInMulticall = 5 # if MulticallInOneTx=true , this denotes the number of ccip-sends to group in one transaction + +NoOfNetworks = 2 # this is used with Networks in `CCIP.Env`, `NoOfNetworks < len(CCIP.Env.Networks)` test only uses first NoOfNetworks from` CCIP.Env.Networks`. +# This value is ignored if CCIP.Groups..NetworkPairs is provided + + +[CCIP.Groups.smoke.MsgDetails] +MsgType = 'DataWithToken' # type of message to be sent, either 'Token' or 'DataWithToken' Or 'Data' +DestGasLimit = 100000 # change this to 0 gas limit if you are doing ccip-send to an EOA +DataLength = 1000 # length of the data to be sent in ccip message if MsgType = 'Data'/'DataWithToken' +NoOfTokens = 2 # number of bridge tokens to be sent in ccip message if MsgType = 'Token'/'DataWithToken' +AmountPerToken = 1 # amount to be sent for each bridge token in ccip message if MsgType = 'Token'/'DataWithToken' + +[CCIP.Groups.smoke.TokenConfig] +TimeoutForPriceUpdate = '15m' # Duration to wait for the price update to time-out. +# Now testing only with dynamic price getter (no pipeline). +# Could be removed once the pipeline is completely removed. +WithPipeline = false +NoOfTokensPerChain = 2 # number of bridge tokens to be deployed per network; if MsgType = 'Token'/'DataWithToken' +CCIPOwnerTokens = false # if true, the test will use deploy the tokens by the CCIPOwner, otherwise the tokens will be deployed by a non-owner account, only applicable for 1.5 pools and onwards + +#NoOfTokensWithDynamicPrice = 15 # number of tokens with dynamic price to be deployed +#DynamicPriceUpdateInterval ='15s' # Periodic interval to update the price of tokens, if there are tokens with dynamic price + +# uncomment the following if you want to run your tests with specific number of lanes; +# in this case out of all the possible lane combinations, only the ones with the specified number of lanes will be considered +# for example, if you have provided CCIP.Env.Networks = ['SIMULATED_1', 'SIMULATED_2', 'SIMULATED_3'] and CCIP.Groups..MaxNoOfLanes = 2, +# then only random combinations of 2 lanes from the following will be considered for the test : +# ['SIMULATED_1', 'SIMULATED_2'], ['SIMULATED_1', 'SIMULATED_3'], ['SIMULATED_2', 'SIMULATED_3'] +#MaxNoOfLanes = # maximum number of lanes to be added in the test; mainly used for scalability tests + + +[CCIP.Groups.load] +# uncomment the following with specific values of lane combinations to be tested, if you want to run your tests to run only on these specific network pairs +# if specific network pairs are not mentioned, then all the network pairs will be tested based on values in CCIP.Env.NetworkPairs and CCIP.Groups..NoOfNetworks +# if specified, CCIP.Groups..NetworkPairs takes precedence over CCIP.Env.NetworkPairs and CCIP.Groups..NoOfNetworks +#NetworkPairs = ['SEPOLIA,OPTIMISM_GOERLI','SEPOLIA,POLYGON_MUMBAI','AVALANCHE_FUJI,SEPOLIA','SEPOLIA,BASE_GOERLI','SEPOLIA,BSC_TESTNET','SEPOLIA,WEMIX_TESTNET','AVALANCHE_FUJI,OPTIMISM_GOERLI','AVALANCHE_FUJI,POLYGON_MUMBAI','AVALANCHE_FUJI,BSC_TESTNET','AVALANCHE_FUJI,BASE_GOERLI','OPTIMISM_GOERLI,BASE_GOERLI','OPTIMISM_GOERLI,POLYGON_MUMBAI','BSC_TESTNET,POLYGON_MUMBAI','BSC_TESTNET,BASE_GOERLI','WEMIX_TESTNET,KROMA_SEPOLIA'] + +KeepEnvAlive = false # same as above +CommitAndExecuteOnSameDON = true # same as above +BiDirectionalLane = true # same as above +NoOfCommitNodes = 5 # same as above +PhaseTimeout = '10m' # same as above +LocalCluster = false # same as above +ExistingDeployment = false # same as above +ReuseContracts = true # same as above +NodeFunding = 20.0 # same as above +NoOfRoutersPerPair = 1 # same as above +MulticallInOneTx = false # same as above +NoOfSendsInMulticall = 5 # same as above +NoOfNetworks = 2 # same as above + +[CCIP.Groups.load.OffRampConfig] +BatchGasLimit = 11000000 + +[CCIP.Groups.load.LoadProfile] +RequestPerUnitTime = [1] # number of ccip requests to be sent per unit time +TimeUnit = '10s' # unit of time for RequestPerUnitTime +TestDuration = '10m' # load test duration, not used for smoke tests +WaitBetweenChaosDuringLoad = '2m' # Duration to wait between each chaos injection during load test; only valid for chaos tests +NetworkChaosDelay = '100ms' # Duration for network chaos delay; only valid for chaos tests using network chaos + +# uncomment the following if you want your test results to be reflected under CCIP test grafana dashboard with namespace label same as the value of the following variable +# TestRunName = __ i.e prod-testnet-2.7.1-ccip1.2.1-beta +# Message Frequency Distribution Example + +# The 'Frequencies' array configures the relative frequency of different message types. +# Each value in the array represents the relative frequency of a message type, +# determining how often each type appears relative to the others. +#[CCIP.Groups.load.LoadProfile.MsgProfile] +#Frequencies = [4, 12, 3, 1] + +# Example Breakdown: +# - Frequencies = [4, 12, 3, 1] +# - Total Sum of Frequencies = 4 + 12 + 3 + 1 = 20 +# - Percentages: +# - Message Type 1: (4 / 20) * 100% = 20% +# - Message Type 2: (12 / 20) * 100% = 60% +# - Message Type 3: (3 / 20) * 100% = 15% +# - Message Type 4: (1 / 20) * 100% = 5% +# These percentages reflect how often each message type should appear in the total set of messages. +# Please note - if the total set of messages is not equal to the multiple of sum of frequencies, the percentages will not be accurate. +[CCIP.Groups.load.LoadProfile.MsgProfile] +Frequencies = [1] # frequency of each message type in the MsgDetails + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'DataWithToken' # type of message to be sent, either 'Token' or 'DataWithToken' Or 'Data' +DestGasLimit = 100000 # change this to 0 gas limit if you are doing ccip-send to an EOA +DataLength = 1000 # length of the data to be sent in ccip message if MsgType = 'Data'/'DataWithToken' +NoOfTokens = 2 # number of bridge tokens to be sent in ccip message if MsgType = 'Token'/'DataWithToken' +AmountPerToken = 1 # amount to be sent for each bridge token in ccip message if MsgType = 'Token'/'DataWithToken' + + +[CCIP.Groups.load.TokenConfig] +TimeoutForPriceUpdate = '15m' # Duration to wait for the price update to time-out. +# Now testing only with dynamic price getter (no pipeline). +# Could be removed once the pipeline is completely removed. +WithPipeline = false +NoOfTokensPerChain = 2 # number of bridge tokens to be deployed per network; if MsgType = 'Token'/'DataWithToken' +CCIPOwnerTokens = false # if true, the test will use deploy the tokens by the CCIPOwner, otherwise the tokens and pools will be deployed by a non-owner account, +# only applicable for 1.5 pools and onwards, if you are running with pre-1.5 pools, then set this to true to deploy token pools by CCIPOwner, otherwise +# the test will fail + +#NoOfTokensWithDynamicPrice = 15 # number of tokens with dynamic price to be deployed +#DynamicPriceUpdateInterval ='15s' # Periodic interval to update the price of tokens, if there are tokens with dynamic price + +# uncomment the following if you want to run your tests with specific number of lanes; +# in this case out of all the possible lane combinations, only the ones with the specified number of lanes will be considered +# for example, if you have provided CCIP.Env.Networks = ['SIMULATED_1', 'SIMULATED_2', 'SIMULATED_3'] and CCIP.Groups..MaxNoOfLanes = 2, +# then only random combinations of 2 lanes from the following will be considered for the test : +# ['SIMULATED_1', 'SIMULATED_2'], ['SIMULATED_1', 'SIMULATED_3'], ['SIMULATED_2', 'SIMULATED_3'] +#MaxNoOfLanes = # maximum number of lanes to be added in the test; mainly used for scalability tests +# + +# Uncomment the following if you want to run your tests with updated OCR params +# otherwise test will use default OCR params from - +# https://github.com/smartcontractkit/chainlink/blob/develop/integration-tests/ccip-tests/contracts/contract_deployer.go#L729-L751 +## OCR Params +#CommitInflightExpiry = '2m' +#ExecInflightExpiry = '2m' +# +#[CCIP.Groups.load.CommitOCRParams] +#DeltaProgress = '2m' +#DeltaResend = '5s' +#DeltaRound = '75s' +#DeltaGrace = '5s' +#MaxDurationQuery = '100ms' +#MaxDurationObservation = '35s' +#MaxDurationReport = '10s' +#MaxDurationShouldAcceptFinalizedReport = '5s' +#MaxDurationShouldTransmitAcceptedReport = '10s' +# +#[CCIP.Groups.load.ExecOCRParams] +#DeltaProgress = '100s' +#DeltaResend = '5s' +#DeltaRound = '40s' +#DeltaGrace = '5s' +#MaxDurationQuery = '100ms' +#MaxDurationObservation = '20s' +#MaxDurationReport = '8s' +#MaxDurationShouldAcceptFinalizedReport = '5s' +#MaxDurationShouldTransmitAcceptedReport = '8s' + +[CCIP.Groups.chaos] +# uncomment the following with specific values of lane combinations to be tested, if you want to run your tests to run only on these specific network pairs +# if specific network pairs are not mentioned, then all the network pairs will be tested based on values in CCIP.Env.NetworkPairs and CCIP.Groups..NoOfNetworks +# if specified, CCIP.Groups..NetworkPairs takes precedence over CCIP.Env.NetworkPairs and CCIP.Groups..NoOfNetworks +#NetworkPairs = ['SEPOLIA,OPTIMISM_GOERLI','SEPOLIA,POLYGON_MUMBAI','AVALANCHE_FUJI,SEPOLIA','SEPOLIA,BASE_GOERLI','SEPOLIA,BSC_TESTNET','SEPOLIA,WEMIX_TESTNET','AVALANCHE_FUJI,OPTIMISM_GOERLI','AVALANCHE_FUJI,POLYGON_MUMBAI','AVALANCHE_FUJI,BSC_TESTNET','AVALANCHE_FUJI,BASE_GOERLI','OPTIMISM_GOERLI,BASE_GOERLI','OPTIMISM_GOERLI,POLYGON_MUMBAI','BSC_TESTNET,POLYGON_MUMBAI','BSC_TESTNET,BASE_GOERLI','WEMIX_TESTNET,KROMA_SEPOLIA'] +KeepEnvAlive = false +CommitAndExecuteOnSameDON = false +BiDirectionalLane = true +NoOfCommitNodes = 5 +PhaseTimeout = '50m' +LocalCluster = false +ExistingDeployment = false +ReuseContracts = true +NodeFunding = 20.0 +NoOfRoutersPerPair = 1 +MulticallInOneTx = false +NoOfSendsInMulticall = 5 +NoOfNetworks = 2 +# chaos test settings +ChaosDuration = '10m' # Duration for whichever chaos will be injected; only valid for chaos tests + + +[CCIP.Groups.chaos.MsgDetails] +MsgType = 'DataWithToken' # type of message to be sent, either 'Token' or 'DataWithToken' Or 'Data' +DestGasLimit = 100000 # change this to 0 gas limit if you are doing ccip-send to an EOA +DataLength = 1000 # length of the data to be sent in ccip message if MsgType = 'Data'/'DataWithToken' +NoOfTokens = 2 # number of bridge tokens to be sent in ccip message if MsgType = 'Token'/'DataWithToken' +AmountPerToken = 1 # amount to be sent for each bridge token in ccip message if MsgType = 'Token'/'DataWithToken' + +[CCIP.Groups.chaos.TokenConfig] +TimeoutForPriceUpdate = '15m' # Duration to wait for the price update to time-out. +# Now testing only with dynamic price getter (no pipeline). +# Could be removed once the pipeline is completely removed. +WithPipeline = false +NoOfTokensPerChain = 2 # number of bridge tokens to be deployed per network; if MsgType = 'Token'/'DataWithToken' + +# uncomment the following if you want to run your tests with specific number of lanes; +# in this case out of all the possible lane combinations, only the ones with the specified number of lanes will be considered +# for example, if you have provided CCIP.Env.Networks = ['SIMULATED_1', 'SIMULATED_2', 'SIMULATED_3'] and CCIP.Groups..MaxNoOfLanes = 2, +# then only random combinations of 2 lanes from the following will be considered for the test : +# ['SIMULATED_1', 'SIMULATED_2'], ['SIMULATED_1', 'SIMULATED_3'], ['SIMULATED_2', 'SIMULATED_3'] +#MaxNoOfLanes = # maximum number of lanes to be added in the test; mainly used for scalability tests diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/baseline.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/baseline.toml new file mode 100644 index 0000000000..d48c0b0f79 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/baseline.toml @@ -0,0 +1,189 @@ +## Baseline performance test on simulated environment (with chaos) +## 40 chains / 400 lanes +## historyDepth 200 / finalityDepth 200 +## block_time = 1s +## throughput 1msg / 5s +## 20% Token, 60% DataWithToken, 15% Regular size msgs, 5% Large msgs +## +## make test_load_ccip testimage=.dkr.ecr..amazonaws.com/chainlink-ccip-tests:ccip-develop \ +## testname=TestLoadCCIPStableRequestTriggeringWithNetworkChaos \ +## override_toml=./testconfig/tomls/ccip-1.4-stress/baseline.toml \ +## secret_toml=./testconfig/tomls/secrets.toml + +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = '1.2.0' +OffRamp = '1.2.0' +OnRamp = '1.2.0' +TokenPool = '1.4.0' +CommitStore = '1.2.0' + +[CCIP.Env] +TTL = '8h' + +[CCIP.Env.Network] +selected_networks= ['PRIVATE-CHAIN-1', 'PRIVATE-CHAIN-2'] + +[CCIP.Env.Network.EVMNetworks.PRIVATE-CHAIN-1] +evm_name = 'private-chain-1' +evm_chain_id = 2337 +evm_urls = ['wss://ignore-this-url.com'] +evm_http_urls = ['https://ignore-this-url.com'] +evm_keys = ['59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 200 + +[CCIP.Env.Network.EVMNetworks.PRIVATE-CHAIN-2] +evm_name = 'private-chain-2' +evm_chain_id = 1337 +evm_urls = ['wss://ignore-this-url.com'] +evm_http_urls = ['https://ignore-this-url.com'] +evm_keys = ['ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 200 + +[CCIP.Env.Network.AnvilConfigs.PRIVATE-CHAIN-1] +block_time = 1 + +# +[CCIP.Env.Network.AnvilConfigs.PRIVATE-CHAIN-2] +block_time = 1 + +[CCIP.Env.NewCLCluster] +NoOfNodes = 17 +NodeMemory = '10Gi' +NodeCPU = '6' +DBMemory = '16Gi' +DBCPU = '4' +DBStorageClass = 'gp3' +PromPgExporter = true +DBCapacity = '50Gi' +IsStateful = true +DBArgs = ['shared_buffers=4096MB', 'effective_cache_size=8192MB', 'work_mem=128MB'] + +[CCIP.Env.NewCLCluster.Common] +BaseConfigTOML = """ +[Feature] +LogPoller = true +CCIP = true + +[Log] +Level = 'debug' +JSONConsole = true + +[Log.File] +MaxSize = '0b' + +[WebServer] +AllowOrigins = '*' +HTTPPort = 6688 +SecureCookies = false +HTTPWriteTimeout = '1m' + +[WebServer.RateLimit] +Authenticated = 2000 +Unauthenticated = 1000 + +[WebServer.TLS] +HTTPSPort = 0 + +[Database] +MaxIdleConns = 20 +MaxOpenConns = 30 +MigrateOnStartup = true + +[OCR2] +Enabled = true +DefaultTransactionQueueDepth = 0 + +[OCR] +Enabled = false +DefaultTransactionQueueDepth = 0 + +[P2P] +[P2P.V2] +Enabled = true +ListenAddresses = ['0.0.0.0:6690'] +AnnounceAddresses = ['0.0.0.0:6690'] +DeltaDial = '500ms' +DeltaReconcile = '5s' +""" + +CommonChainConfigTOML = """ +[HeadTracker] +HistoryDepth = 200 + +[GasEstimator] +PriceMax = '200 gwei' +LimitDefault = 6000000 +FeeCapDefault = '200 gwei' +""" + +[CCIP.Groups] +[CCIP.Groups.load] +KeepEnvAlive = true +NoOfCommitNodes = 16 +PhaseTimeout = '40m' +NodeFunding = 1000.0 +NoOfRoutersPerPair = 2 +NoOfNetworks = 40 +MaxNoOfLanes = 400 + +[CCIP.Groups.load.OffRampConfig] +BatchGasLimit = 11000000 + +[CCIP.Groups.load.TokenConfig] +TimeoutForPriceUpdate = '15m' +NoOfTokensPerChain = 10 +NoOfTokensWithDynamicPrice = 10 +DynamicPriceUpdateInterval ='15s' +CCIPOwnerTokens = true + +[CCIP.Groups.load.LoadProfile] +TestDuration = '4h' +TimeUnit = '5s' +RequestPerUnitTime = [1] +OptimizeSpace = true +NetworkChaosDelay = '100ms' + +# to represent 20%, 60%, 15%, 5% of the total messages +[CCIP.Groups.load.LoadProfile.MsgProfile] +Frequencies = [4,12,3,1] + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Token' +DestGasLimit = 0 +DataLength = 0 +NoOfTokens = 1 +AmountPerToken = 1 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'DataWithToken' +DestGasLimit = 500000 +DataLength = 5000 +NoOfTokens = 1 +AmountPerToken = 1 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 800000 +DataLength = 10000 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 2500000 +DataLength = 10000 diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/prod-testnet.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/prod-testnet.toml new file mode 100644 index 0000000000..f8321584c8 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/prod-testnet.toml @@ -0,0 +1,964 @@ +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = '1.2.0' +OffRamp = '1.2.0' +OnRamp = '1.2.0' +TokenPool = '1.4.0' +CommitStore = '1.2.0' + + +[CCIP.Deployments] +Data = """ +{ + "lane_configs": { + "Arbitrum Sepolia": { + "is_native_fee_token": true, + "fee_token": "0xb1D4538B4571d411F07960EF2838Ce337FE1E80E", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0x5EF7a726Fd21Fd9D77D34E3C56cfDD8691F7F0ac", + "router": "0x2a9C5afB0d0e4BAb2BCdaE109EC4b0c4Be15a165", + "price_registry": "0x89D5b13908b9063abCC6791dc724bF7B7c93634C", + "wrapped_native": "0xE591bf0A0CF924A0674d7792db046B23CEbF5f34", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0x1Cb56374296ED19E86F68fA437ee679FD7798DaA", + "deployed_at": 33999325 + }, + "Base Sepolia": { + "on_ramp": "0x7854E73C73e7F9bb5b0D5B4861E997f4C6E8dcC6", + "deployed_at": 9199926 + }, + "Gnosis Chiado": { + "on_ramp": "0x973CbE752258D32AE82b60CD1CB656Eebb588dF0", + "deployed_at": 42809650 + }, + "Optimism Sepolia": { + "on_ramp": "0x701Fe16916dd21EFE2f535CA59611D818B017877", + "deployed_at": 35180131 + }, + "Sepolia Testnet": { + "on_ramp": "0x4205E1Ca0202A248A5D42F5975A8FE56F3E302e9", + "deployed_at": 35180131 + }, + "WeMix Testnet": { + "on_ramp": "0xBD4106fBE4699FE212A34Cc21b10BFf22b02d959", + "deployed_at": 18816676 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0xcab0EF91Bee323d1A617c0a027eE753aFd6997E4", + "commit_store": "0x0d90b9b96cBFa0D01635ce12982ccE1b70827c7a", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Sepolia": { + "off_ramp": "0xc1982985720B959E66c19b64F783361Eb9B60F26", + "commit_store": "0x28F66bB336f6db713d6ad2a3bd1B7a531282A159", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Gnosis Chiado": { + "off_ramp": "0x935C26F9a9122E5F9a27f2d3803e74c75B94f5a3", + "commit_store": "0xEdb963Ec5c2E5AbdFdCF137eF44A445a7fa4787A", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Sepolia": { + "off_ramp": "0xfD404A89e1d195F0c65be1A9042C77745197659e", + "commit_store": "0x84B7B012c95f8A152B44Ab3e952f2dEE424fA8e1", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Sepolia Testnet": { + "off_ramp": "0x1c71f141b4630EBE52d6aF4894812960abE207eB", + "commit_store": "0xaB0c8Ba51E7Fa3E5693a4Fbb39473520FD85d173", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Testnet": { + "off_ramp": "0x262e16C8D42aa07bE13e58F81e7D9F62F6DE2830", + "commit_store": "0xc132eFAf929299E5ee704Fa6D9796CFa23Bb8b2C", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Avalanche Fuji": { + "fee_token": "0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0x0ea0D7B2b78DD3A926fC76d6875a287F0AEB158F", + "router": "0xF694E193200268f9a4868e4Aa017A0118C9a8177", + "price_registry": "0x19e157E5fb1DAec1aE4BaB113fdf077F980704AA", + "wrapped_native": "0xd00ae08403B9bbb9124bB305C09058E32C39A48c", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x8bB16BEDbFd62D1f905ACe8DBBF2954c8EEB4f66", + "deployed_at": 31888860 + }, + "BSC Testnet": { + "on_ramp": "0xF25ECF1Aad9B2E43EDc2960cF66f325783245535", + "deployed_at": 33214865 + }, + "Base Sepolia": { + "on_ramp": "0x1A674645f3EB4147543FCA7d40C5719cbd997362", + "deployed_at": 31235262 + }, + "Gnosis Chiado": { + "on_ramp": "0x1532e5b204ee2b2244170c78E743CB9c168F4DF9", + "deployed_at": 32817266 + }, + "Optimism Sepolia": { + "on_ramp": "0xC334DE5b020e056d0fE766dE46e8d9f306Ffa1E2", + "deployed_at": 30396804 + }, + "Polygon Amoy": { + "on_ramp": "0x610F76A35E17DA4542518D85FfEa12645eF111Fc", + "deployed_at": 31982368 + }, + "Sepolia Testnet": { + "on_ramp": "0x5724B4Cc39a9690135F7273b44Dfd3BA6c0c69aD", + "deployed_at": 33214865 + }, + "WeMix Testnet": { + "on_ramp": "0x677B5ab5C8522d929166c064d5700F147b15fa33", + "deployed_at": 30436465 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x90A74072e7B0c2d59e13aB4d8f93c8198c413194", + "commit_store": "0xf3458CFd2fdf4a6CF0Ce296d520DD21eB194828b", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Testnet": { + "off_ramp": "0x10b28009E5D776F1f5AAA73941CE8953B8f42d26", + "commit_store": "0xacDD582F271eCF22FAd6764cCDe1c4a534b732A8", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Sepolia": { + "off_ramp": "0xdBdE8510226d1E060A3bf982b67705C67f5697e2", + "commit_store": "0x8Ee73BC9492b4182D289E5C1e66e40CD876CC00F", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Gnosis Chiado": { + "off_ramp": "0x56dF55aF5F0A4689f3364230587a68eD6A314fAd", + "commit_store": "0xabA7ff98094c4cc7A075812EefF2CD21f6400235", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Sepolia": { + "off_ramp": "0x3d7CbC95DCC33257F14D6Eb780c88Bd56C6335BB", + "commit_store": "0x1fcDC02edDfb405f378ba53cF9E6104feBcB7542", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Amoy": { + "off_ramp": "0x3e33290B90fD0FF30a3FA138934DF028E4eCA348", + "commit_store": "0xCFe3556Aa42d40be09BD23aa80448a19443BE5B1", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Sepolia Testnet": { + "off_ramp": "0x9e5e4324F8608D54A50a317832d456a392E4F8C2", + "commit_store": "0x92A51eD3F041B39EbD1e464C1f7cb1e8f8A8c63f", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Testnet": { + "off_ramp": "0xD0D338318bC6837b091FC7AB5F2a94B7783507d5", + "commit_store": "0xd9D479208235c7355848ff4aF26eB5aacfDC30c6", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "BSC Testnet": { + "is_native_fee_token": true, + "fee_token": "0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0xF9a21B587111e7E8745Fb8b13750014f19DB0014", + "router": "0xE1053aE1857476f36A3C62580FF9b016E8EE8F6f", + "price_registry": "0xCCDf022c9d31DC26Ebab4FB92432724a5b79809a", + "wrapped_native": "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0xa2515683E99F50ADbE177519A46bb20FfdBaA5de", + "deployed_at": 40500000 + }, + "Base Sepolia": { + "on_ramp": "0x3E807220Ca84b997c0d1928162227b46C618e0c5", + "deployed_at": 37115558 + }, + "Gnosis Chiado": { + "on_ramp": "0x8735f991d41eA9cA9D2CC75cD201e4B7C866E63e", + "deployed_at": 40228352 + }, + "Polygon Amoy": { + "on_ramp": "0xf37CcbfC04adc1B56a46B36F811D52C744a1AF78", + "deployed_at": 39572254 + }, + "Sepolia Testnet": { + "on_ramp": "0xB1DE44B04C00eaFe9915a3C07a0CaeA4410537dF", + "deployed_at": 38150066 + }, + "WeMix Testnet": { + "on_ramp": "0x89268Afc1BEA0782a27ba84124E3F42b196af927", + "deployed_at": 38184995 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0x6e6fFCb6B4BED91ff0CC8C2e57EC029dA7DB80C2", + "commit_store": "0x38Bc38Bd824b6eE87571f9D3CFbe6D6E28E3Dc62", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Sepolia": { + "off_ramp": "0x2C61FD7E93Dc79422861282145c59B56dFbc3a8c", + "commit_store": "0x42fAe5B3605804CF6d08632d7A25864e24F792Ae", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Gnosis Chiado": { + "off_ramp": "0x71a44a60832B0F8B63232C9516e7E6aEc3A373Dc", + "commit_store": "0xAC24299a91b72d1Cb5B31147e3CF54964D896974", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Amoy": { + "off_ramp": "0x63440C7747d37bc6154b5538AE32b54FE0965AfA", + "commit_store": "0xAD22fA198CECfC534927aE1D480c460d5bB3460F", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Sepolia Testnet": { + "off_ramp": "0xf1c128Fe52Ea78CcAAB407509292E61ce38C1523", + "commit_store": "0x59dFD870dC4bd76A7B879A4f705Fdcd2595f85f9", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Testnet": { + "off_ramp": "0xfd9B19c3725da5B517aA705B848ff3f21F98280e", + "commit_store": "0x3c1F1412563188aBc8FE3fd53E8F1Cb601CaB4f9", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Base Sepolia": { + "is_native_fee_token": true, + "fee_token": "0xE4aB69C077896252FAFBD49EFD26B5D171A32410", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0x5aA82cA372782d6CC33AA4C830Df2a91017A7e1b", + "router": "0xD3b06cEbF099CE7DA4AcCf578aaebFDBd6e88a93", + "price_registry": "0x4D20536e60832bE579Cd38E89Dc03d11E1741FbA", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x58622a80c6DdDc072F2b527a99BE1D0934eb2b50", + "deployed_at": 5146539 + }, + "Avalanche Fuji": { + "on_ramp": "0xAbA09a1b7b9f13E05A6241292a66793Ec7d43357", + "deployed_at": 7810235 + }, + "BSC Testnet": { + "on_ramp": "0xD806966beAB5A3C75E5B90CDA4a6922C6A9F0c9d", + "deployed_at": 5144127 + }, + "Gnosis Chiado": { + "on_ramp": "0x2Eff2d1BF5C557d6289D208a7a43608f5E3FeCc2", + "deployed_at": 9817141 + }, + "Optimism Sepolia": { + "on_ramp": "0x3b39Cd9599137f892Ad57A4f54158198D445D147", + "deployed_at": 5147649 + }, + "Sepolia Testnet": { + "on_ramp": "0x6486906bB2d85A6c0cCEf2A2831C11A2059ebfea", + "deployed_at": 7810235 + }, + "ethereum-testnet-sepolia-mode-1": { + "on_ramp": "0x3d0115386C01436870a2c47e6297962284E70BA6", + "deployed_at": 10409731 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xd364C06ac99a82a00d3eFF9F2F78E4Abe4b9baAA", + "commit_store": "0xdE8d0f47a71eA3fDFBD3162271652f2847939097", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Fuji": { + "off_ramp": "0xAd91214efFee446500940c764DF77AF18427294F", + "commit_store": "0x1242b6c5e0e349b8d4BCf0938f961C4B4f7EA3Fa", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Testnet": { + "off_ramp": "0xd5E9508921434e8758f4540D55c1c066b7cc1598", + "commit_store": "0x1a86b29364D1B3fA3386329A361aA98A104b2742", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Gnosis Chiado": { + "off_ramp": "0x9Bb7e398ef9Acfe9cA584C39B1E233Cba62BB9f7", + "commit_store": "0x1F4B82cDebaC5e3a0Dd53183D47e51808B4a64cB", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Sepolia": { + "off_ramp": "0x86a3910908eCaAA31Fcd9F0fC8841D8E98f1511d", + "commit_store": "0xE99a87C9b5ed4D2b6060195DEea5106ffF655736", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Sepolia Testnet": { + "off_ramp": "0x189F61D9B886Dd2975D5Abc893c8Cf5f5effda71", + "commit_store": "0xEE7e27346DCD1e711348D0F7f7ECB53a9a3a08a7", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "ethereum-testnet-sepolia-mode-1": { + "off_ramp": "0xB26647A23e8b4284375e5C74b77c9557aE709D03", + "commit_store": "0x4b4fEB401d3E613e1D6242E155C83A80BF9ac2C9", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Gnosis Chiado": { + "is_native_fee_token": true, + "fee_token": "0xDCA67FD8324990792C0bfaE95903B8A64097754F", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0xb6f1Fe2CDE891eFd5Efd2A563C4C2F2549163718", + "router": "0x19b1bac554111517831ACadc0FD119D23Bb14391", + "price_registry": "0x2F4ACd1f8986c6B1788159C4c9a5fC3fceCCE363", + "wrapped_native": "0x18c8a7ec7897177E4529065a7E7B0878358B3BfF", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x473b49fb592B54a4BfCD55d40E048431982879C9", + "deployed_at": 9718588 + }, + "Avalanche Fuji": { + "on_ramp": "0x610F76A35E17DA4542518D85FfEa12645eF111Fc", + "deployed_at": 9718676 + }, + "BSC Testnet": { + "on_ramp": "0xE48E6AA1fc7D0411acEA95F8C6CaD972A37721D4", + "deployed_at": 9718302 + }, + "Base Sepolia": { + "on_ramp": "0x41b4A51cAfb699D9504E89d19D71F92E886028a8", + "deployed_at": 9718513 + }, + "Optimism Sepolia": { + "on_ramp": "0xAae733212981e06D9C978Eb5148F8af03F54b6EF", + "deployed_at": 9718420 + }, + "Polygon Amoy": { + "on_ramp": "0x01800fCDd892e37f7829937271840A6F041bE62E", + "deployed_at": 9718194 + }, + "Sepolia Testnet": { + "on_ramp": "0x4ac7FBEc2A7298AbDf0E0F4fDC45015836C4bAFe", + "deployed_at": 8487681 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x9aA82DBB53bf02096B771D40e9432A323a78fB26", + "commit_store": "0x5CdbA91aBC0cD81FC56bc10Ad1835C9E5fB38e5F", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Fuji": { + "off_ramp": "0x3e33290B90fD0FF30a3FA138934DF028E4eCA348", + "commit_store": "0xCFe3556Aa42d40be09BD23aa80448a19443BE5B1", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Testnet": { + "off_ramp": "0xbc4AD54e91b213D4279af92c0C5518c0b96cf62D", + "commit_store": "0xff84e8Dd4Fd17eaBb23b6AeA6e1981830e54389C", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Sepolia": { + "off_ramp": "0x4117953A5ceeF12f5B8C1E973b470ab83a8CebA6", + "commit_store": "0x94ad41296186E81f31e1ed0B1BcF5fa9e1721C27", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Sepolia": { + "off_ramp": "0x33d2898F8fb7714FD1661791766f40754982a343", + "commit_store": "0x55d6Df194472f02CD481e506A277c4A29D0D1bCc", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Amoy": { + "off_ramp": "0x450543b1d85ca79885851D7b74dc982981b78229", + "commit_store": "0x23B79d940A769FE31b4C867A8BAE80117f24Ca81", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Sepolia Testnet": { + "off_ramp": "0xbf9036529123DE264bFA0FC7362fE25B650D4B16", + "commit_store": "0x5f7F1abD5c5EdaF2636D58B980e85355AF0Ef80d", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Kroma Sepolia": { + "is_native_fee_token": true, + "fee_token": "0xa75cCA5b404ec6F4BB6EC4853D177FE7057085c8", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0x1E4e4e0d6f6631A45C616F71a1A5cF208DB9eCDe", + "router": "0xA8C0c11bf64AF62CDCA6f93D3769B88BdD7cb93D", + "price_registry": "0xa1ed3A3aA29166C9c8448654A8cA6b7916BC8379", + "wrapped_native": "0x4200000000000000000000000000000000000001", + "src_contracts": { + "WeMix Testnet": { + "on_ramp": "0x6ea155Fc77566D9dcE01B8aa5D7968665dc4f0C5", + "deployed_at": 10290904 + } + }, + "dest_contracts": { + "WeMix Testnet": { + "off_ramp": "0xB602B6E5Caf08ac0C920EAE585aed100a8cF6f3B", + "commit_store": "0x89D5b13908b9063abCC6791dc724bF7B7c93634C", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Optimism Sepolia": { + "is_native_fee_token": true, + "fee_token": "0xE4aB69C077896252FAFBD49EFD26B5D171A32410", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0xf06Ff5D2084295909119ca541E93635E7D582FFc", + "router": "0x114A20A10b43D4115e5aeef7345a1A71d2a60C57", + "price_registry": "0x782a7Ba95215f2F7c3dD4C153cbB2Ae3Ec2d3215", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x1a86b29364D1B3fA3386329A361aA98A104b2742", + "deployed_at": 10841494 + }, + "Avalanche Fuji": { + "on_ramp": "0x6b38CC6Fa938D5AB09Bdf0CFe580E226fDD793cE", + "deployed_at": 8677537 + }, + "Base Sepolia": { + "on_ramp": "0xe284D2315a28c4d62C419e8474dC457b219DB969", + "deployed_at": 7130524 + }, + "Gnosis Chiado": { + "on_ramp": "0x835a5b8e6CA17c2bB5A336c93a4E22478E6F1C8A", + "deployed_at": 11799783 + }, + "Polygon Amoy": { + "on_ramp": "0x2Cf26fb01E9ccDb831414B766287c0A9e4551089", + "deployed_at": 10813146 + }, + "Sepolia Testnet": { + "on_ramp": "0xC8b93b46BF682c39B3F65Aa1c135bC8A95A5E43a", + "deployed_at": 12165583 + }, + "WeMix Testnet": { + "on_ramp": "0xc7E53f6aB982af7A7C3e470c8cCa283d3399BDAd", + "deployed_at": 8733017 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xDc2c7A3d8068C6F09F0F3648d24C84e372F6014d", + "commit_store": "0xb1aFb5cbE3c29b5Db71F21442BA9EfD450BC23C3", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Fuji": { + "off_ramp": "0x1F350718e015EB20E5065C09F4A7a3f66888aEeD", + "commit_store": "0x98650A8EB59f75D93563aB34FcF603b1A30e4CBF", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Sepolia": { + "off_ramp": "0x0a750ca77369e03613d7640548F4b2b1c695c3Bb", + "commit_store": "0x8fEBC74C26129C8d7E60288C6dCCc75eb494aA3C", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Gnosis Chiado": { + "off_ramp": "0xCE2CE7F940B7c839384e5D7e079A6aE80e8AD6dB", + "commit_store": "0x1b9D78Ec1CEEC439F0b7eA6C428A1a607D9FA7e4", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Amoy": { + "off_ramp": "0xD667b5706592D0b040C78fEe5EE17D243b7dCB41", + "commit_store": "0x96101BA5250EE9295c193693C1e08A55bC593664", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Sepolia Testnet": { + "off_ramp": "0x260AF9b83e0d2Bb6C9015fC9f0BfF8858A0CCE68", + "commit_store": "0x7a0bB92Bc8663abe6296d0162A9b41a2Cb2E0358", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Testnet": { + "off_ramp": "0x9C08B7712af0344188aa5087D9e6aD0f47191037", + "commit_store": "0x4BE6DB0B884169a6A207fe5cad01eB4C025a13dB", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Polygon Amoy": { + "is_native_fee_token": true, + "fee_token": "0x0Fd9e8d3aF1aaee056EB9e802c3A762a667b1904", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0x50b023c5b33AEe5Adef15C2E95C2fEC690a52fa1", + "router": "0x9C32fCB86BF0f4a1A8921a9Fe46de3198bb884B2", + "price_registry": "0xfb2f2A207dC428da81fbAFfDDe121761f8Be1194", + "wrapped_native": "0x360ad4f9a9A8EFe9A8DCB5f461c4Cc1047E1Dcf9", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0x8Fb98b3837578aceEA32b454f3221FE18D7Ce903", + "deployed_at": 6004551 + }, + "BSC Testnet": { + "on_ramp": "0xC6683ac4a0F62803Bec89a5355B36495ddF2C38b", + "deployed_at": 6005330 + }, + "Gnosis Chiado": { + "on_ramp": "0x2331F6D614C9Fd613Ff59a1aB727f1EDf6c37A68", + "deployed_at": 6897885 + }, + "Optimism Sepolia": { + "on_ramp": "0xA52cDAeb43803A80B3c0C2296f5cFe57e695BE11", + "deployed_at": 6004902 + }, + "Sepolia Testnet": { + "on_ramp": "0x35347A2fC1f2a4c5Eae03339040d0b83b09e6FDA", + "deployed_at": 6004056 + }, + "WeMix Testnet": { + "on_ramp": "0x26546096F64B5eF9A1DcDAe70Df6F4f8c2E10C61", + "deployed_at": 6005611 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0xa733ce82a84335b2E9D864312225B0F3D5d80600", + "commit_store": "0x09B0F93fC2111aE439e853884173AC5b2F809885", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Testnet": { + "off_ramp": "0x948dfaa4842fc23e0e362Fe8D4396AaE4E6DF7EA", + "commit_store": "0x7F4e739D40E58BBd59dAD388171d18e37B26326f", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Gnosis Chiado": { + "off_ramp": "0x17c542a28e08AEF5697251601C7b2B621d153D42", + "commit_store": "0x811250c20fAB9a1b7ca245453aC214ba637fBEB5", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Sepolia": { + "off_ramp": "0xfFdE9E8c34A27BEBeaCcAcB7b3044A0A364455C9", + "commit_store": "0x74ED442ad211050e9C05Dc9A267E037E3d74A03B", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Sepolia Testnet": { + "off_ramp": "0xFb04129aD1EEDB741CC705ebC1978a7aB63e51f6", + "commit_store": "0x63f875240149d29136053C954Ca164a9BfA81F77", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Testnet": { + "off_ramp": "0xdE8451E952Eb43350614839cCAA84f7C8701a09C", + "commit_store": "0xaCdaBa07ECad81dc634458b98673931DD9d3Bc14", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "Sepolia Testnet": { + "is_native_fee_token": true, + "fee_token": "0x779877A7B0D9E8603169DdbD7836e478b4624789", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0xB4d360459F32Dd641Ef5A6985fFbAC5c4e5521aA", + "router": "0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59", + "price_registry": "0x9EF7D57a4ea30b9e37794E55b0C75F2A70275dCc", + "wrapped_native": "0x097D90c9d3E0B50Ca60e1ae45F6A81010f9FB534", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0xe4Dd3B16E09c016402585a8aDFdB4A18f772a07e", + "deployed_at": 5737506 + }, + "Avalanche Fuji": { + "on_ramp": "0x0477cA0a35eE05D3f9f424d88bC0977ceCf339D4", + "deployed_at": 5944649 + }, + "BSC Testnet": { + "on_ramp": "0xD990f8aFA5BCB02f95eEd88ecB7C68f5998bD618", + "deployed_at": 5383500 + }, + "Base Sepolia": { + "on_ramp": "0x2B70a05320cB069e0fB55084D402343F832556E7", + "deployed_at": 5619657 + }, + "Gnosis Chiado": { + "on_ramp": "0x3E842E3A79A00AFdd03B52390B1caC6306Ea257E", + "deployed_at": 5386355 + }, + "Optimism Sepolia": { + "on_ramp": "0x69CaB5A0a08a12BaFD8f5B195989D709E396Ed4d", + "deployed_at": 5937506 + }, + "Polygon Amoy": { + "on_ramp": "0x9f656e0361Fb5Df2ac446102c8aB31855B591692", + "deployed_at": 5723315 + }, + "WeMix Testnet": { + "on_ramp": "0xedFc22336Eb0B9B11Ff37C07777db27BCcDe3C65", + "deployed_at": 5393931 + }, + "celo-testnet-alfajores": { + "on_ramp": "0x3C86d16F52C10B2ff6696a0e1b8E0BcfCC085948", + "deployed_at": 5704643 + }, + "ethereum-testnet-sepolia-blast-1": { + "on_ramp": "0xDB75E9D9ca7577CcBd7232741be954cf26194a66", + "deployed_at": 6040848 + }, + "ethereum-testnet-sepolia-metis-1": { + "on_ramp": "0x1C4640914cd57c5f02a68048A0fbb0E12d904223", + "deployed_at": 6002793 + }, + "ethereum-testnet-sepolia-mode-1": { + "on_ramp": "0xc630fbD4D0F6AEB00aD0793FB827b54fBB78e981", + "deployed_at": 5970819 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xF18896AB20a09A29e64fdEbA99FDb8EC328f43b1", + "commit_store": "0x93Ff9Dd39Dc01eac1fc4d2c9211D95Ee458CAB94", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Fuji": { + "off_ramp": "0x000b26f604eAadC3D874a4404bde6D64a97d95ca", + "commit_store": "0x2dD9273F8208B8393350508131270A6574A69784", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Testnet": { + "off_ramp": "0xdE2d8E126e08d675fCD7fFa5a6CE49925f3Dc692", + "commit_store": "0x0050ac355a82caB31194507f94174297bf0655A7", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Base Sepolia": { + "off_ramp": "0x31c0B81832B333419f0DfD36A69F502cF9094aed", + "commit_store": "0xDFcde9d698a2B32DB2537DC9B752Cadd1D846a52", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Gnosis Chiado": { + "off_ramp": "0x7db0115A0b3AAb01d30bf81123c5DD7B0C41Add5", + "commit_store": "0x6640723Ea801178c4383FA016b9781e7ef1016EF", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Sepolia": { + "off_ramp": "0xD50590D4438411EDe47029b0FD7901A7145E5Df6", + "commit_store": "0xe85EEE9Fd434A7b8a586Ee086E828abF41839479", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Amoy": { + "off_ramp": "0x5032cbC0C4aEeD25bb6E45D8B3fAF05DB0688C5d", + "commit_store": "0xe6201C9996Cc7B6E828E10CbE937E693d577D318", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "WeMix Testnet": { + "off_ramp": "0x46b639a3C1a4CBfD326b94a2dB7415c27157282f", + "commit_store": "0x7b74554678816b045c1e7409327E086bD436aa46", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "celo-testnet-alfajores": { + "off_ramp": "0xB435E0f73c18C5a12C324CA1d02F81F2C3e6e761", + "commit_store": "0xbc5d74957F171e75F92c8F0E1C317A25a56a416D", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "ethereum-testnet-sepolia-blast-1": { + "off_ramp": "0x4e897e5cF3aC307F0541B2151A88bCD781c153a3", + "commit_store": "0xB656652841F347178e193951C4663652aCe36B74", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "ethereum-testnet-sepolia-metis-1": { + "off_ramp": "0x4DB693A93E9d5196ECD42EC56CDEAe99dFC652ED", + "commit_store": "0xBfACd78F1412B6f93Ac23409bf456aFec1ABd845", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "ethereum-testnet-sepolia-mode-1": { + "off_ramp": "0xbEfd8D65F6643De54F0b1268A3bf4618ff85dcB4", + "commit_store": "0x0C161D3470b45Cc677661654C30ce4AdE6aCD288", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "WeMix Testnet": { + "is_native_fee_token": true, + "fee_token": "0x3580c7A817cCD41f7e02143BFa411D4EeAE78093", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0x46fF31494651593973D9b38a872ED5B06f45A693", + "router": "0xA8C0c11bf64AF62CDCA6f93D3769B88BdD7cb93D", + "price_registry": "0x89D17571DB7C9540eeB36760E3c749C8fb984569", + "wrapped_native": "0xbE3686643c05f00eC46e73da594c78098F7a9Ae7", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0xA9DE3F7A617D67bC50c56baaCb9E0373C15EbfC6", + "deployed_at": 51216113 + }, + "Avalanche Fuji": { + "on_ramp": "0xC4aC84da458ba8e40210D2dF94C76E9a41f70069", + "deployed_at": 51214769 + }, + "BSC Testnet": { + "on_ramp": "0x5AD6eed6Be0ffaDCA4105050CF0E584D87E0c2F1", + "deployed_at": 51213771 + }, + "Kroma Sepolia": { + "on_ramp": "0x428C4dc89b6Bf908B82d77C9CBceA786ea8cc7D0", + "deployed_at": 51239062 + }, + "Optimism Sepolia": { + "on_ramp": "0x1961a7De751451F410391c251D4D4F98D71B767D", + "deployed_at": 51216748 + }, + "Polygon Amoy": { + "on_ramp": "0xd55148e841e76265B484d399eC71b7076ecB1216", + "deployed_at": 55378685 + }, + "Sepolia Testnet": { + "on_ramp": "0x4d57C6d8037C65fa66D6231844785a428310a735", + "deployed_at": 51239309 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xeB1dFaB2464Bf0574D43e764E0c758f92e7ecAFb", + "commit_store": "0xcEaCa2B7890065c485f3E58657358a185Ad33791", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Avalanche Fuji": { + "off_ramp": "0x98e811Df9D2512f1aaf58D534607F583D6c54A4F", + "commit_store": "0x8e538351F6E5B2daF3c90C565C3738bca69a2716", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "BSC Testnet": { + "off_ramp": "0xB0e7f0fCcD3c961C473E7c44D939C1cDb4Cec1cB", + "commit_store": "0x4B56D8d53f1A6e0117B09700067De99581aA5542", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Kroma Sepolia": { + "off_ramp": "0xD685D2d224dd6D0Db2D56497db6270D77D9a7966", + "commit_store": "0x7e062D6880779a0347e7742058C1b1Ee4AA0B137", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Optimism Sepolia": { + "off_ramp": "0xA5f97Bc69Bf06e7C37B93265c5457420A92c5F4b", + "commit_store": "0xd48b9213583074f518D8f4336FDf35370D450132", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Polygon Amoy": { + "off_ramp": "0x6c8f5999B06FDE17B11E4e3C1062b761766F960f", + "commit_store": "0x957c3c2056192e58A8485eF31165fC490d474239", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Sepolia Testnet": { + "off_ramp": "0x8AB103843ED9D28D2C5DAf5FdB9c3e1CE2B6c876", + "commit_store": "0x7d5297c5506ee2A7Ef121Da9bE02b6a6AD30b392", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "celo-testnet-alfajores": { + "is_native_fee_token": true, + "fee_token": "0x32E08557B14FaD8908025619797221281D439071", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0xbE8FD4b84ca8CC2cFAeeEf8dc1388E44860eeEeb", + "router": "0xb00E95b773528E2Ea724DB06B75113F239D15Dca", + "price_registry": "0x8F048206D11B2c69b8963E2EBd5968D141e022f4", + "wrapped_native": "0x99604d0e2EfE7ABFb58BdE565b5330Bb46Ab3Dca", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x16a020c4bbdE363FaB8481262D30516AdbcfcFc8", + "deployed_at": 23561364 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0xa1b97F92D806BA040daf419AFC2765DC723683a4", + "commit_store": "0xcd92C0599Ac515e7588865cC45Eee21A74816aFc", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "ethereum-testnet-sepolia-blast-1": { + "is_native_fee_token": true, + "fee_token": "0x02c359ebf98fc8BF793F970F9B8302bb373BdF32", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0x9C32fCB86BF0f4a1A8921a9Fe46de3198bb884B2", + "router": "0xfb2f2A207dC428da81fbAFfDDe121761f8Be1194", + "price_registry": "0xc8acE9dF450FaD007755C6C9AB4f0e9c8626E29C", + "wrapped_native": "0x4200000000000000000000000000000000000023", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x85Ef19FC4C63c70744995DC38CAAEC185E0c619f", + "deployed_at": 6429339 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0x92cD24C278D34C726f377703E50875d8f9535dC2", + "commit_store": "0xcE1b4D50CeD56850182Bd58Ace91171cB249B873", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "ethereum-testnet-sepolia-metis-1": { + "is_native_fee_token": true, + "fee_token": "0x9870D6a0e05F867EAAe696e106741843F7fD116D", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0x26546096F64B5eF9A1DcDAe70Df6F4f8c2E10C61", + "router": "0xaCdaBa07ECad81dc634458b98673931DD9d3Bc14", + "price_registry": "0x5DCE866b3ae6E0Ed153f0e149D7203A1B266cdF5", + "wrapped_native": "0x5c48e07062aC4E2Cf4b9A768a711Aef18e8fbdA0", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x2Eff2d1BF5C557d6289D208a7a43608f5E3FeCc2", + "deployed_at": 858864 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0x9Bb7e398ef9Acfe9cA584C39B1E233Cba62BB9f7", + "commit_store": "0x1F4B82cDebaC5e3a0Dd53183D47e51808B4a64cB", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + }, + "ethereum-testnet-sepolia-mode-1": { + "is_native_fee_token": true, + "fee_token": "0x925a4bfE64AE2bFAC8a02b35F78e60C29743755d", + "bridge_tokens": [ + ], + "bridge_tokens_pools": [ + ], + "price_aggregators": null, + "arm": "0x11545812A8d64e4A3A0Ec36b6F70D87b42Ce4a01", + "router": "0xc49ec0eB4beb48B8Da4cceC51AA9A5bD0D0A4c43", + "price_registry": "0xa733ce82a84335b2E9D864312225B0F3D5d80600", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Base Sepolia": { + "on_ramp": "0x73f7E074bd7291706a0C5412f51DB46441B1aDCB", + "deployed_at": 14359909 + }, + "Sepolia Testnet": { + "on_ramp": "0xfFdE9E8c34A27BEBeaCcAcB7b3044A0A364455C9", + "deployed_at": 14359680 + } + }, + "dest_contracts": { + "Base Sepolia": { + "off_ramp": "0x137a38c6b1Ad20101F93516aB2159Df525309168", + "commit_store": "0x8F43d867969F14619895d71E0A5b89E0bb20bF70", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + }, + "Sepolia Testnet": { + "off_ramp": "0xcD44cec849B6a8eBd5551D6DFeEcA452257Dfe4d", + "commit_store": "0xbA66f08733E6715D33edDfb5a5947676bb45d0e0", + "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" + } + } + } + } +} +""" + +[CCIP.Env] +TTL = '8h' + +[CCIP.Env.Network] +selected_networks = [ + 'ARBITRUM_SEPOLIA', + 'AVALANCHE_FUJI', + 'OPTIMISM_SEPOLIA', + 'BASE_SEPOLIA', + 'BSC_TESTNET', + 'WEMIX_TESTNET', + 'SEPOLIA', + 'POLYGON_AMOY', + 'KROMA_SEPOLIA', + 'BLAST_SEPOLIA' +] + +[CCIP.Groups.load] +NetworkPairs = [ + 'AVALANCHE_FUJI,SEPOLIA', + 'OPTIMISM_SEPOLIA,BASE_SEPOLIA' +] + +BiDirectionalLane = true +PhaseTimeout = '45m' +ExistingDeployment = true + +NoOfTokensPerChain = 1 + +[CCIP.Groups.load.LoadProfile] +RequestPerUnitTime = [1] +TimeUnit = '5s' +TestDuration = '1h' +TestRunName = 'v2.12.0-ccip1.4.16-load' + +# to represent 20%, 60%, 15%, 5% of the total messages +[CCIP.Groups.load.LoadProfile.MsgProfile] +Frequencies = [4,12,3,1] + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Token' +DestGasLimit = 0 +DataLength = 0 +NoOfTokens = 5 +AmountPerToken = 1 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'DataWithToken' +DestGasLimit = 500000 +DataLength = 5000 +NoOfTokens = 5 +AmountPerToken = 1 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 800000 +DataLength = 10000 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 2500000 +DataLength = 10000 \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/sample-scalability.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/sample-scalability.toml new file mode 100644 index 0000000000..872a6ae565 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/sample-scalability.toml @@ -0,0 +1,129 @@ +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = '1.2.0' +OffRamp = '1.2.0' +OnRamp = '1.2.0' +TokenPool = '1.4.0' +CommitStore = '1.2.0' + +[CCIP.Env] +TTL = '15h' + +[CCIP.Env.Network] +selected_networks= ['PRIVATE-CHAIN-1', 'PRIVATE-CHAIN-2'] + +[CCIP.Env.Network.EVMNetworks.PRIVATE-CHAIN-1] +evm_name = 'private-chain-1' +evm_chain_id = 2337 +evm_urls = ['wss://ignore-this-url.com'] +evm_http_urls = ['https://ignore-this-url.com'] +evm_keys = ['59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 1 + +[CCIP.Env.Network.EVMNetworks.PRIVATE-CHAIN-2] +evm_name = 'private-chain-2' +evm_chain_id = 1337 +evm_urls = ['wss://ignore-this-url.com'] +evm_http_urls = ['https://ignore-this-url.com'] +evm_keys = ['ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 1 + +[CCIP.Env.Network.AnvilConfigs.PRIVATE-CHAIN-1] +block_time = 1 +# +[CCIP.Env.Network.AnvilConfigs.PRIVATE-CHAIN-2] +block_time = 1 + +[CCIP.Env.NewCLCluster] +NoOfNodes = 17 +NodeMemory = '12Gi' +NodeCPU = '6' +DBMemory = '10Gi' +DBCPU = '2' +DBStorageClass = 'gp3' +PromPgExporter = true +DBCapacity = '50Gi' +IsStateful = true +DBArgs = ['shared_buffers=2048MB', 'effective_cache_size=4096MB', 'work_mem=64MB'] + +#[CCIP.Env.NewCLCluster.Common] +#CommonChainConfigTOML = """ +#[HeadTracker] +#HistoryDepth = 3000 +# +#[GasEstimator] +#PriceMax = '200 gwei' +#LimitDefault = 6000000 +#FeeCapDefault = '200 gwei' +#""" + +[CCIP.Groups] +[CCIP.Groups.load] +KeepEnvAlive = true +NoOfCommitNodes = 16 +PhaseTimeout = '40m' +NodeFunding = 1000.0 +NoOfRoutersPerPair = 2 +NoOfNetworks = 40 +MaxNoOfLanes = 200 + +[CCIP.Groups.load.OffRampConfig] +BatchGasLimit = 11000000 + +[CCIP.Groups.load.TokenConfig] +TimeoutForPriceUpdate = '15m' +NoOfTokensPerChain = 60 +NoOfTokensWithDynamicPrice = 15 +DynamicPriceUpdateInterval ='15s' +CCIPOwnerTokens = true + +[CCIP.Groups.load.LoadProfile] +TestDuration = '4h' +TimeUnit = '5s' +RequestPerUnitTime = [1] +OptimizeSpace = true +NetworkChaosDelay = '100ms' + +# to represent 20%, 60%, 15%, 5% of the total messages +[CCIP.Groups.load.LoadProfile.MsgProfile] +Frequencies = [4,12,3,1] + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Token' +DestGasLimit = 0 +DataLength = 0 +NoOfTokens = 5 +AmountPerToken = 1 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'DataWithToken' +DestGasLimit = 500000 +DataLength = 5000 +NoOfTokens = 5 +AmountPerToken = 1 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 800000 +DataLength = 10000 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 2500000 +DataLength = 10000 \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/tier-a.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/tier-a.toml new file mode 100644 index 0000000000..5270de7f6d --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/tier-a.toml @@ -0,0 +1,240 @@ +## Baseline performance test on simulated environment (with chaos) +## 40 chains / 400 lanes +## historyDepth 200 / finalityDepth 200 +## block_time = 1s +## throughput 1msg / 5s +## 20% Token, 60% DataWithToken, 15% Regular size msgs, 5% Large msgs +## +## make test_load_ccip testimage=.dkr.ecr..amazonaws.com/chainlink-ccip-tests:ccip-develop \ +## testname=TestLoadCCIPStableRequestTriggeringWithNetworkChaos \ +## override_toml=./testconfig/tomls/ccip1.4-stress/tier-a.toml \ +## secret_toml=./testconfig/tomls/secrets.toml + +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = '1.2.0' +OffRamp = '1.2.0' +OnRamp = '1.2.0' +TokenPool = '1.4.0' +CommitStore = '1.2.0' + +[CCIP.Env] +TTL = '8h' + +[CCIP.Env.Network] +selected_networks= ['PRIVATE-CHAIN-1', 'SLOW-CHAIN-1', 'SLOW-CHAIN-2', 'SLOW-CHAIN-3'] + +[CCIP.Env.Network.EVMNetworks.PRIVATE-CHAIN-1] +evm_name = 'private-chain-1' +evm_chain_id = 2337 +evm_urls = ['wss://ignore-this-url.com'] +evm_http_urls = ['https://ignore-this-url.com'] +evm_keys = ['59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 1 + +[CCIP.Env.Network.EVMNetworks.SLOW-CHAIN-1] +evm_name = 'slow-chain-1' +evm_chain_id = 90000001 +evm_urls = ['wss://ignore-this-url.com'] +evm_http_urls = ['https://ignore-this-url.com'] +evm_keys = ['ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 1 + +[CCIP.Env.Network.EVMNetworks.SLOW-CHAIN-2] +evm_name = 'slow-chain-2' +evm_chain_id = 90000002 +evm_urls = ['wss://ignore-this-url.com'] +evm_http_urls = ['https://ignore-this-url.com'] +evm_keys = ['ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 1 + +[CCIP.Env.Network.EVMNetworks.SLOW-CHAIN-3] +evm_name = 'slow-chain-3' +evm_chain_id = 1337 +evm_urls = ['wss://ignore-this-url.com'] +evm_http_urls = ['https://ignore-this-url.com'] +evm_keys = ['ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 1 + +[CCIP.Env.Network.AnvilConfigs.PRIVATE-CHAIN-1] +block_time = 2 + +# +[CCIP.Env.Network.AnvilConfigs.SLOW-CHAIN-1] +block_time = 12 + +[CCIP.Env.Network.AnvilConfigs.SLOW-CHAIN-2] +block_time = 12 + +[CCIP.Env.Network.AnvilConfigs.SLOW-CHAIN-3] +block_time = 12 + +[CCIP.Env.NewCLCluster] +NoOfNodes = 17 +NodeMemory = '10Gi' +NodeCPU = '6' +DBMemory = '16Gi' +DBCPU = '4' +DBStorageClass = 'gp3' +PromPgExporter = true +DBCapacity = '50Gi' +IsStateful = true +DBArgs = ['shared_buffers=4096MB', 'effective_cache_size=8192MB', 'work_mem=128MB'] + +[CCIP.Env.NewCLCluster.Common] +BaseConfigTOML = """ +[Feature] +LogPoller = true +CCIP = true + +[Log] +Level = 'debug' +JSONConsole = true + +[Log.File] +MaxSize = '0b' + +[WebServer] +AllowOrigins = '*' +HTTPPort = 6688 +SecureCookies = false +HTTPWriteTimeout = '1m' + +[WebServer.RateLimit] +Authenticated = 2000 +Unauthenticated = 1000 + +[WebServer.TLS] +HTTPSPort = 0 + +[Database] +MaxIdleConns = 20 +MaxOpenConns = 30 +MigrateOnStartup = true + +[OCR2] +Enabled = true +DefaultTransactionQueueDepth = 0 + +[OCR] +Enabled = false +DefaultTransactionQueueDepth = 0 + +[P2P] +[P2P.V2] +Enabled = true +ListenAddresses = ['0.0.0.0:6690'] +AnnounceAddresses = ['0.0.0.0:6690'] +DeltaDial = '500ms' +DeltaReconcile = '5s' +""" + +#CommonChainConfigTOML = """ +#[HeadTracker] +#HistoryDepth = 200 +# +#[GasEstimator] +#PriceMax = '200 gwei' +#LimitDefault = 6000000 +#FeeCapDefault = '200 gwei' +#""" + +[CCIP.Groups] +[CCIP.Groups.load] +DenselyConnectedNetworkChainIds = ['90000001', '90000002', '1337'] +KeepEnvAlive = true +NoOfCommitNodes = 16 +PhaseTimeout = '40m' +NodeFunding = 1000.0 +NoOfRoutersPerPair = 2 +NoOfNetworks = 40 +MaxNoOfLanes = 400 + +[CCIP.Groups.load.OffRampConfig] +BatchGasLimit = 11000000 + +[CCIP.Groups.load.TokenConfig] +TimeoutForPriceUpdate = '15m' +NoOfTokensPerChain = 60 +NoOfTokensWithDynamicPrice = 15 +DynamicPriceUpdateInterval ='5m' +CCIPOwnerTokens = true + +[CCIP.Groups.load.LoadProfile] +TestDuration = '4h' +OptimizeSpace = true +NetworkChaosDelay = '100ms' +TimeUnit = '5s' +RequestPerUnitTime = [1] + +[CCIP.Groups.load.LoadProfile.LoadFrequency.slow-chain-1] +TimeUnit = '10s' +RequestPerUnitTime = [1] + +[CCIP.Groups.load.LoadProfile.LoadFrequency.slow-chain-2] +TimeUnit = '10s' +RequestPerUnitTime = [1] + +[CCIP.Groups.load.LoadProfile.LoadFrequency.slow-chain-3] +TimeUnit = '10s' +RequestPerUnitTime = [1] + +# to represent 20%, 60%, 15%, 5% of the total messages +[CCIP.Groups.load.LoadProfile.MsgProfile] +Frequencies = [4,12,3,1] + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Token' +DestGasLimit = 0 +DataLength = 0 +NoOfTokens = 5 +AmountPerToken = 1 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'DataWithToken' +DestGasLimit = 500000 +DataLength = 5000 +NoOfTokens = 5 +AmountPerToken = 1 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 800000 +DataLength = 10000 + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 2500000 +DataLength = 10000 \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/tier-b.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/tier-b.toml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/integration-tests/ccip-tests/testconfig/tomls/contract-version1.4.toml b/integration-tests/ccip-tests/testconfig/tomls/contract-version1.4.toml new file mode 100644 index 0000000000..392b058e5c --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/contract-version1.4.toml @@ -0,0 +1,13 @@ +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = '1.2.0' +OffRamp = '1.2.0' +OnRamp = '1.2.0' +TokenPool = '1.4.0' +CommitStore = '1.2.0' + +[CCIP.Groups.smoke.TokenConfig] +CCIPOwnerTokens = true + +[CCIP.Groups.load.TokenConfig] +CCIPOwnerTokens = true \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/db-compatibility.toml b/integration-tests/ccip-tests/testconfig/tomls/db-compatibility.toml new file mode 100644 index 0000000000..9de5925cb1 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/db-compatibility.toml @@ -0,0 +1,34 @@ +[CCIP] +[CCIP.Env] +[CCIP.Env.NewCLCluster] +NoOfNodes = 6 + +[[CCIP.Env.NewCLCluster.Nodes]] +Name = 'node1' +DBImage = 'postgres' +DBTag = '13.14' + +[[CCIP.Env.NewCLCluster.Nodes]] +Name = 'node2' +DBImage = 'postgres' +DBTag = '12.18' + +[[CCIP.Env.NewCLCluster.Nodes]] +Name = 'node3' +DBImage = 'postgres' +DBTag = '14.11' + +[[CCIP.Env.NewCLCluster.Nodes]] +Name = 'node4' +DBImage = 'postgres' +DBTag = '14.8' + +[[CCIP.Env.NewCLCluster.Nodes]] +Name = 'node5' +DBImage = 'postgres' +DBTag = '15.6' + +[[CCIP.Env.NewCLCluster.Nodes]] +Name = 'node6' +DBImage = 'postgres' +DBTag = '15.6' diff --git a/integration-tests/ccip-tests/testconfig/tomls/leader-lane.toml b/integration-tests/ccip-tests/testconfig/tomls/leader-lane.toml new file mode 100644 index 0000000000..76b97ad97b --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/leader-lane.toml @@ -0,0 +1,4 @@ +[CCIP] +[CCIP.Groups.smoke] +NoOfNetworks = 4 +NoOfRoutersPerPair = 2 \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/load-with-arm-curse-uncurse.toml b/integration-tests/ccip-tests/testconfig/tomls/load-with-arm-curse-uncurse.toml new file mode 100644 index 0000000000..e49f1184af --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/load-with-arm-curse-uncurse.toml @@ -0,0 +1,20 @@ +[CCIP] +[CCIP.Env] +TTL = '15h' + +[CCIP.Groups] +[CCIP.Groups.load] +KeepEnvAlive = true +PhaseTimeout = '50m' +NodeFunding = 1000.0 + + +[CCIP.Groups.load.LoadProfile] +RequestPerUnitTime = [1] +TimeUnit = '1m' +TestDuration = '30m' +SendMaxDataInEveryMsgCount = 0 + + + + diff --git a/integration-tests/ccip-tests/testconfig/tomls/node-post-upgrade-compatibility.toml b/integration-tests/ccip-tests/testconfig/tomls/node-post-upgrade-compatibility.toml new file mode 100644 index 0000000000..c1c6c65144 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/node-post-upgrade-compatibility.toml @@ -0,0 +1,45 @@ +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = '1.2.0' +OffRamp = '1.2.0' +OnRamp = '1.2.0' +TokenPool = '1.4.0' +CommitStore = '1.2.0' + +[CCIP.Deployments] +DataFile = 'lane-config/.*.json' + +[CCIP.Env] +[CCIP.Env.NewCLCluster] +NoOfNodes = 6 + +[[CCIP.Env.NewCLCluster.Nodes]] +Name = 'node-1' + +[[CCIP.Env.NewCLCluster.Nodes]] +Name = 'node-2' +NeedsUpgrade = true + +[[CCIP.Env.NewCLCluster.Nodes]] +Name = 'node-3' +NeedsUpgrade = true + +[[CCIP.Env.NewCLCluster.Nodes]] +Name = 'node-4' +NeedsUpgrade = true + +[[CCIP.Env.NewCLCluster.Nodes]] +Name = 'node-5' +NeedsUpgrade = true + +[[CCIP.Env.NewCLCluster.Nodes]] +Name = 'node-6' +NeedsUpgrade = true + +[CCIP.Groups] +[CCIP.Groups.load] +LocalCluster = false +ExistingDeployment = true + +[CCIP.Groups.load.LoadProfile] +TestRunName = 'upgrade-test' \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/node-pre-upgrade-compatibility.toml b/integration-tests/ccip-tests/testconfig/tomls/node-pre-upgrade-compatibility.toml new file mode 100644 index 0000000000..36ada83419 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/node-pre-upgrade-compatibility.toml @@ -0,0 +1,13 @@ +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = '1.2.0' +OffRamp = '1.2.0' +OnRamp = '1.2.0' +TokenPool = '1.4.0' +CommitStore = '1.2.0' + +[CCIP.Groups] +[CCIP.Groups.smoke] +LocalCluster = false +KeepEnvAlive = true +StoreLaneConfig = true \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/usdc_mock_deployment.toml b/integration-tests/ccip-tests/testconfig/tomls/usdc_mock_deployment.toml new file mode 100644 index 0000000000..82a3d49216 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/usdc_mock_deployment.toml @@ -0,0 +1,10 @@ +[CCIP] +[CCIP.Groups] +[CCIP.Groups.smoke] +USDCMockDeployment = true + +[CCIP.Groups.smoke.TokenConfig] +NoOfTokensPerChain = 2 + +[CCIP.Groups.smoke.MsgDetails] +NoOfTokens = 3 \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/varied-block-time-sample.toml b/integration-tests/ccip-tests/testconfig/tomls/varied-block-time-sample.toml new file mode 100644 index 0000000000..dfe947af11 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/varied-block-time-sample.toml @@ -0,0 +1,47 @@ +[CCIP] +[CCIP.Env] +[CCIP.Env.Network] +selected_networks= ['PRIVATE-CHAIN-1', 'PRIVATE-CHAIN-2'] + +[CCIP.Env.Network.EVMNetworks.PRIVATE-CHAIN-1] +evm_name = 'private-chain-1' +evm_chain_id = 2337 +evm_urls = ['wss://ignore-this-url.com'] +evm_http_urls = ['https://ignore-this-url.com'] +evm_keys = ['59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 100 # with 50 blocks of finality, and 12s block time, we have 20 minutes of finality + +[CCIP.Env.Network.EVMNetworks.PRIVATE-CHAIN-2] +evm_name = 'private-chain-2' +evm_chain_id = 1337 +evm_urls = ['wss://ignore-this-url.com'] +evm_http_urls = ['https://ignore-this-url.com'] +evm_keys = ['ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 1 # with 1 block of finality, and 1s block time, we have instant finality + + +[CCIP.Env.Network.AnvilConfigs.PRIVATE-CHAIN-1] +block_time = 12 + +[CCIP.Env.Network.AnvilConfigs.PRIVATE-CHAIN-2] +block_time = 1 + +[CCIP.Groups] +[CCIP.Groups.smoke] +LocalCluster = false \ No newline at end of file diff --git a/integration-tests/ccip-tests/testreporters/ccip.go b/integration-tests/ccip-tests/testreporters/ccip.go new file mode 100644 index 0000000000..b567f6a629 --- /dev/null +++ b/integration-tests/ccip-tests/testreporters/ccip.go @@ -0,0 +1,476 @@ +package testreporters + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "strings" + "sync" + "testing" + "time" + + "github.com/rs/zerolog" + "github.com/slack-go/slack" + + "github.com/smartcontractkit/chainlink-testing-framework/k8s/config" + "github.com/smartcontractkit/chainlink-testing-framework/testreporters" +) + +type Phase string +type Status string + +const ( + // These are the different phases of a CCIP transaction lifecycle + // You can see an illustration of the flow here: https://docs.chain.link/images/ccip/ccip-diagram-04_v04.webp + TX Phase = "CCIP-Send Transaction" // The initial transaction is sent from the client to the OnRamp + CCIPSendRe Phase = "CCIPSendRequested" // The OnRamp emits the CCIPSendRequested event which acknowledges the transaction requesting a CCIP transfer + SourceLogFinalized Phase = "SourceLogFinalizedTentatively" // The source chain finalizes the transaction where the CCIPSendRequested event was emitted + Commit Phase = "Commit-ReportAccepted" // The destination chain commits to the transaction and emits the ReportAccepted event + ReportBlessed Phase = "ReportBlessedByARM" // The destination chain emits the ReportBlessed event. This is triggered by the RMN, for tests we usually mock it. + E2E Phase = "CommitAndExecute" // This is effectively an alias for the below phase, but it's used to represent the end-to-end flow + ExecStateChanged Phase = "ExecutionStateChanged" // The destination chain emits the ExecutionStateChanged event. This indicates that the transaction has been executed + + Success Status = "✅" + Failure Status = "❌" + Unsure = "⚠️" + slackFile string = "payload_ccip.json" +) + +type AggregatorMetrics struct { + Min float64 `json:"min_duration_for_successful_requests(s),omitempty"` + Max float64 `json:"max_duration_for_successful_requests(s),omitempty"` + Avg float64 `json:"avg_duration_for_successful_requests(s),omitempty"` + sum float64 + count int +} +type TransactionStats struct { + Fee string `json:"fee,omitempty"` + MsgID string `json:"msg_id,omitempty"` + GasUsed uint64 `json:"gas_used,omitempty"` + TxHash string `json:"tx_hash,omitempty"` + NoOfTokensSent int `json:"no_of_tokens_sent,omitempty"` + MessageBytesLength int64 `json:"message_bytes_length,omitempty"` + FinalizedByBlock string `json:"finalized_block_num,omitempty"` + FinalizedAt string `json:"finalized_at,omitempty"` + CommitRoot string `json:"commit_root,omitempty"` +} + +type PhaseStat struct { + SeqNum uint64 `json:"seq_num,omitempty"` + Duration float64 `json:"duration,omitempty"` + Status Status `json:"success"` + SendTransactionStats *TransactionStats `json:"ccip_send_data,omitempty"` +} + +type RequestStat struct { + ReqNo int64 + SeqNum uint64 + SourceNetwork string + DestNetwork string + StatusByPhase map[Phase]PhaseStat `json:"status_by_phase,omitempty"` +} + +func (stat *RequestStat) UpdateState( + lggr *zerolog.Logger, + seqNum uint64, + step Phase, + duration time.Duration, + state Status, + sendTransactionStats *TransactionStats, +) { + durationInSec := duration.Seconds() + stat.SeqNum = seqNum + phaseDetails := PhaseStat{ + SeqNum: seqNum, + Duration: durationInSec, + Status: state, + SendTransactionStats: sendTransactionStats, + } + + event := lggr.Info() + if seqNum != 0 { + event.Uint64("seq num", seqNum) + } + // if any of the phase fails mark the E2E as failed + if state == Failure || state == Unsure { + stat.StatusByPhase[E2E] = PhaseStat{ + SeqNum: seqNum, + Status: state, + } + stat.StatusByPhase[step] = phaseDetails + lggr.Info(). + Str(fmt.Sprint(E2E), string(state)). + Msgf("reqNo %d", stat.ReqNo) + event.Str(string(step), string(state)).Msgf("reqNo %d", stat.ReqNo) + } else { + event.Str(string(step), string(Success)).Msgf("reqNo %d", stat.ReqNo) + // we don't want to save phase details for TX and CCIPSendRe to avoid redundancy if these phases are successful + if step != TX && step != CCIPSendRe { + stat.StatusByPhase[step] = phaseDetails + } + if step == Commit || step == ReportBlessed || step == ExecStateChanged { + stat.StatusByPhase[E2E] = PhaseStat{ + SeqNum: seqNum, + Status: state, + Duration: stat.StatusByPhase[step].Duration + stat.StatusByPhase[E2E].Duration, + } + if step == ExecStateChanged { + lggr.Info(). + Str(fmt.Sprint(E2E), string(Success)). + Msgf("reqNo %d", stat.ReqNo) + } + } + } +} + +func NewCCIPRequestStats(reqNo int64, source, dest string) *RequestStat { + return &RequestStat{ + ReqNo: reqNo, + StatusByPhase: make(map[Phase]PhaseStat), + SourceNetwork: source, + DestNetwork: dest, + } +} + +type CCIPLaneStats struct { + lane string + lggr *zerolog.Logger + TotalRequests int64 `json:"total_requests,omitempty"` // TotalRequests is the total number of requests made + SuccessCountsByPhase map[Phase]int64 `json:"success_counts_by_phase,omitempty"` // SuccessCountsByPhase is the number of requests that succeeded in each phase + FailedCountsByPhase map[Phase]int64 `json:"failed_counts_by_phase,omitempty"` // FailedCountsByPhase is the number of requests that failed in each phase + DurationStatByPhase map[Phase]AggregatorMetrics `json:"duration_stat_by_phase,omitempty"` // DurationStatByPhase is the duration statistics for each phase + statusByPhaseByRequests sync.Map +} + +func (testStats *CCIPLaneStats) UpdatePhaseStatsForReq(stat *RequestStat) { + testStats.statusByPhaseByRequests.Store(stat.ReqNo, stat.StatusByPhase) +} + +func (testStats *CCIPLaneStats) Aggregate(phase Phase, durationInSec float64) { + if prevDur, ok := testStats.DurationStatByPhase[phase]; !ok { + testStats.DurationStatByPhase[phase] = AggregatorMetrics{ + Min: durationInSec, + Max: durationInSec, + sum: durationInSec, + count: 1, + } + } else { + if prevDur.Min > durationInSec { + prevDur.Min = durationInSec + } + if prevDur.Max < durationInSec { + prevDur.Max = durationInSec + } + prevDur.sum = prevDur.sum + durationInSec + prevDur.count++ + testStats.DurationStatByPhase[phase] = prevDur + } +} + +func (testStats *CCIPLaneStats) Finalize(lane string) { + phases := []Phase{E2E, TX, CCIPSendRe, SourceLogFinalized, Commit, ReportBlessed, ExecStateChanged} + events := make(map[Phase]*zerolog.Event) + testStats.statusByPhaseByRequests.Range(func(key, value interface{}) bool { + if reqNo, ok := key.(int64); ok { + if stat, ok := value.(map[Phase]PhaseStat); ok { + for phase, phaseStat := range stat { + if phaseStat.Status == Success { + testStats.SuccessCountsByPhase[phase]++ + testStats.Aggregate(phase, phaseStat.Duration) + } else { + testStats.FailedCountsByPhase[phase]++ + } + } + } + if reqNo > testStats.TotalRequests { + testStats.TotalRequests = reqNo + } + } + return true + }) + // if no phase stats are found return + if testStats.TotalRequests <= 0 { + return + } + testStats.lggr.Info().Int64("Total Requests Triggerred", testStats.TotalRequests).Msg("Test Run Completed") + for _, phase := range phases { + events[phase] = testStats.lggr.Info().Str("Phase", string(phase)) + if phaseStat, ok := testStats.DurationStatByPhase[phase]; ok { + testStats.DurationStatByPhase[phase] = AggregatorMetrics{ + Min: phaseStat.Min, + Max: phaseStat.Max, + Avg: phaseStat.sum / float64(phaseStat.count), + } + events[phase]. + Str("Min Duration for Successful Requests", fmt.Sprintf("%.02f", testStats.DurationStatByPhase[phase].Min)). + Str("Max Duration for Successful Requests", fmt.Sprintf("%.02f", testStats.DurationStatByPhase[phase].Max)). + Str("Average Duration for Successful Requests", fmt.Sprintf("%.02f", testStats.DurationStatByPhase[phase].Avg)) + } + if failed, ok := testStats.FailedCountsByPhase[phase]; ok { + events[phase].Int64("Failed Count", failed) + } + if s, ok := testStats.SuccessCountsByPhase[phase]; ok { + events[phase].Int64("Successful Count", s) + } + events[phase].Msgf("Phase Stats for Lane %s", lane) + } +} + +type CCIPTestReporter struct { + t *testing.T + logger *zerolog.Logger + startTime int64 + endTime int64 + grafanaURLProvider testreporters.GrafanaURLProvider + grafanaURL string + grafanaQueryParams []string + namespace string + reportFilePath string + duration time.Duration // duration is the duration of the test + FailedLanes map[string]Phase `json:"failed_lanes_and_phases,omitempty"` // FailedLanes is the list of lanes that failed and the phase at which it failed + LaneStats map[string]*CCIPLaneStats `json:"lane_stats"` // LaneStats is the statistics for each lane + mu *sync.Mutex + sendSlackReport bool +} + +func (r *CCIPTestReporter) SetSendSlackReport(sendSlackReport bool) { + r.sendSlackReport = sendSlackReport +} + +func (r *CCIPTestReporter) CompleteGrafanaDashboardURL() error { + if r.grafanaURLProvider == nil { + return fmt.Errorf("grafana URL provider is not set") + } + grafanaUrl, err := r.grafanaURLProvider.GetGrafanaBaseURL() + if err != nil { + return err + } + + dashboardUrl, err := r.grafanaURLProvider.GetGrafanaDashboardURL() + if err != nil { + return err + } + r.grafanaURL = fmt.Sprintf("%s%s", grafanaUrl, dashboardUrl) + err = r.AddToGrafanaDashboardQueryParams( + fmt.Sprintf("from=%d", r.startTime), + fmt.Sprintf("to=%d", r.endTime), + fmt.Sprintf("var-remote_runner=%s", r.namespace)) + if err != nil { + return err + } + + err = r.FormatGrafanaURLWithQueryParameters() + if err != nil { + return fmt.Errorf("error formatting grafana URL: %w", err) + } + r.logger.Info().Str("Dashboard", r.grafanaURL).Msg("Dashboard URL") + return nil +} + +// FormatGrafanaURLWithQueryParameters adds query params to the grafana URL +// The query params are added in the format ?key=value if the grafana URL does not have any query params +// If the grafana URL already has query params, the query params are added in the format &key=value +// The function parameter qParam should be in the format key=value +// If the function parameter qParam does not contain an =, an error is returned +func (r *CCIPTestReporter) FormatGrafanaURLWithQueryParameters() error { + for _, v := range r.grafanaQueryParams { + if !strings.Contains(v, "=") { + return fmt.Errorf("invalid query param %s", v) + } + if strings.Contains(r.grafanaURL, "?") { + r.grafanaURL = fmt.Sprintf("%s&%s", r.grafanaURL, v) + continue + } + r.grafanaURL = fmt.Sprintf("%s?%s", r.grafanaURL, v) + } + return nil +} + +// AddToGrafanaDashboardQueryParams adds query params to the QueryParams slice +// The function parameter qParam should be in the format key=value +// If the function parameter qParam does not contain an =, an error is returned +func (r *CCIPTestReporter) AddToGrafanaDashboardQueryParams(qParams ...string) error { + for _, qParam := range qParams { + if !strings.Contains(qParam, "=") { + return fmt.Errorf("invalid query param %s", qParam) + } + r.grafanaQueryParams = append(r.grafanaQueryParams, qParam) + } + return nil +} + +// SendSlackNotification sends a slack notification to the specified channel set in the environment variable "SLACK_CHANNEL" +// notifying the user set in the environment variable "SLACK_USER" +// The function returns an error if the slack notification fails +func (r *CCIPTestReporter) SendSlackNotification(t *testing.T, slackClient *slack.Client, _ testreporters.GrafanaURLProvider) error { + if r.sendSlackReport { + r.logger.Info().Msg("Sending Slack notification") + } else { + r.logger.Info().Msg("Slack notification not enabled") + return nil + } + if testreporters.SlackAPIKey == "" || testreporters.SlackChannel == "" || testreporters.SlackUserID == "" { + r.logger.Warn().Msg("Slack API Key, Channel or User ID not set. Skipping Slack notification") + return nil + } + if slackClient == nil { + slackClient = slack.New(testreporters.SlackAPIKey) + } + + var msgTexts []string + headerText := ":white_check_mark: CCIP Test PASSED :white_check_mark:" + if t.Failed() { + headerText = ":x: CCIP Test FAILED :x:" + } + // If grafanaURLProvider is not set, form the message notifying about the failed lanes with the report file path + if r.grafanaURLProvider == nil { + for name, lane := range r.LaneStats { + if lane.FailedCountsByPhase[E2E] > 0 { + msgTexts = append(msgTexts, + fmt.Sprintf("lane %s :x:", name), + fmt.Sprintf( + "\nNumber of ccip-send= %d"+ + "\nNo of failed requests = %d", lane.TotalRequests, lane.FailedCountsByPhase[E2E])) + } + } + + msgTexts = append(msgTexts, fmt.Sprintf( + "\nTest Run Summary created on _remote-test-runner_ at _%s_\nNotifying <@%s>", + r.reportFilePath, testreporters.SlackUserID)) + } else { + // If grafanaURLProvider is set, form the message with the grafana dashboard link + err := r.CompleteGrafanaDashboardURL() + if err != nil { + return fmt.Errorf("error formatting grafana dashboard URL: %w", err) + } + msgTexts = append(msgTexts, fmt.Sprintf( + "\nTest Run Completed \nNotifying <@%s>\n<%s|CCIP Long Running Tests Dashboard>", + testreporters.SlackUserID, r.grafanaURL)) + } + + messageBlocks := testreporters.SlackNotifyBlocks(headerText, r.namespace, msgTexts) + ts, err := testreporters.SendSlackMessage(slackClient, slack.MsgOptionBlocks(messageBlocks...)) + if err != nil { + fmt.Println(messageBlocks) + return fmt.Errorf("failed to send slack message: %w", err) + } + // if grafanaURLProvider is set, we don't want to write the report in a file + // the report will be shared in terms of grafana dashboard link + if r.grafanaURLProvider == nil { + return testreporters.UploadSlackFile(slackClient, slack.FileUploadParameters{ + Title: fmt.Sprintf("CCIP Test Report %s", r.namespace), + Filetype: "json", + Filename: fmt.Sprintf("ccip_report_%s.csv", r.namespace), + File: r.reportFilePath, + InitialComment: fmt.Sprintf("CCIP Test Report %s.", r.namespace), + Channels: []string{testreporters.SlackChannel}, + ThreadTimestamp: ts, + }) + } + return nil +} + +func (r *CCIPTestReporter) WriteReport(folderPath string) error { + l := r.logger + for k := range r.LaneStats { + r.LaneStats[k].Finalize(k) + // if E2E for the lane has failed + if _, ok := r.LaneStats[k].FailedCountsByPhase[E2E]; ok { + // find the phase at which it failed + for phase, count := range r.LaneStats[k].FailedCountsByPhase { + if count > 0 && phase != E2E { + r.FailedLanes[k] = phase + break + } + } + } + } + if len(r.FailedLanes) > 0 { + r.logger.Info().Interface("List of Failed Lanes", r.FailedLanes).Msg("Failed Lanes") + } + + // if grafanaURLProvider is set, we don't want to write the report in a file + // the report will be shared in terms of grafana dashboard link + if r.grafanaURLProvider != nil { + return nil + } + l.Debug().Str("Folder Path", folderPath).Msg("Writing CCIP Test Report") + if err := testreporters.MkdirIfNotExists(folderPath); err != nil { + return err + } + reportLocation := filepath.Join(folderPath, slackFile) + r.reportFilePath = reportLocation + slackFile, err := os.Create(reportLocation) + defer func() { + err = slackFile.Close() + if err != nil { + l.Error().Err(err).Msg("Error closing slack file") + } + }() + if err != nil { + return err + } + stats, err := json.MarshalIndent(r, "", " ") + if err != nil { + return err + } + _, err = slackFile.Write(stats) + if err != nil { + return err + } + return nil +} + +// SetNamespace sets the namespace of the report for clean reports +func (r *CCIPTestReporter) SetNamespace(namespace string) { + // if the test is run in remote runner, the namespace will be set to the remote runner's namespace + if value, set := os.LookupEnv(config.EnvVarNamespace); set && value != "" { + r.namespace = value + return + } + // if the namespace is not set, set it to the namespace provided + r.namespace = namespace +} + +// SetDuration sets the duration of the test +func (r *CCIPTestReporter) SetDuration(d time.Duration) { + r.duration = d +} + +func (r *CCIPTestReporter) SetGrafanaURLProvider(provider testreporters.GrafanaURLProvider) { + r.grafanaURLProvider = provider +} + +func (r *CCIPTestReporter) AddNewLane(name string, lggr *zerolog.Logger) *CCIPLaneStats { + r.mu.Lock() + defer r.mu.Unlock() + i := &CCIPLaneStats{ + lane: name, + lggr: lggr, + FailedCountsByPhase: make(map[Phase]int64), + SuccessCountsByPhase: make(map[Phase]int64), + DurationStatByPhase: make(map[Phase]AggregatorMetrics), + } + r.LaneStats[name] = i + return i +} + +func (r *CCIPTestReporter) SendReport(t *testing.T, namespace string, slackSend bool) error { + logsPath := filepath.Join("logs", fmt.Sprintf("%s-%s-%d", t.Name(), namespace, time.Now().Unix())) + r.SetNamespace(namespace) + r.endTime = time.Now().UTC().UnixMilli() + r.SetSendSlackReport(r.namespace != "" && slackSend) + return testreporters.SendReport(t, namespace, logsPath, r, nil) +} + +func NewCCIPTestReporter(t *testing.T, lggr *zerolog.Logger) *CCIPTestReporter { + return &CCIPTestReporter{ + LaneStats: make(map[string]*CCIPLaneStats), + startTime: time.Now().UTC().UnixMilli(), + logger: lggr, + t: t, + mu: &sync.Mutex{}, + FailedLanes: make(map[string]Phase), + } +} diff --git a/integration-tests/ccip-tests/testsetups/ccip.go b/integration-tests/ccip-tests/testsetups/ccip.go new file mode 100644 index 0000000000..207773aace --- /dev/null +++ b/integration-tests/ccip-tests/testsetups/ccip.go @@ -0,0 +1,1436 @@ +package testsetups + +import ( + "context" + "fmt" + "math/big" + "math/rand" + "os" + "regexp" + "strconv" + "strings" + "sync" + "testing" + "time" + + "github.com/AlekSi/pointer" + "github.com/ethereum/go-ethereum/common" + "github.com/google/uuid" + "github.com/pkg/errors" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "github.com/stretchr/testify/require" + "go.uber.org/atomic" + "go.uber.org/multierr" + "go.uber.org/zap/zapcore" + "golang.org/x/sync/errgroup" + + chainselectors "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" + ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/config/types" + ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/k8s/config" + "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + + integrationactions "github.com/smartcontractkit/chainlink/integration-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts/laneconfig" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" + ccipconfig "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testreporters" + testutils "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/utils" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" +) + +var ( + GethResourceProfile = map[string]interface{}{ + "requests": map[string]interface{}{ + "cpu": "4", + "memory": "6Gi", + }, + "limits": map[string]interface{}{ + "cpu": "4", + "memory": "6Gi", + }, + } + // to set default values through test config use sync.once + setContractVersion sync.Once + setOCRParams sync.Once + setConfigOverrides sync.Once +) + +type NetworkPair struct { + NetworkA blockchain.EVMNetwork + NetworkB blockchain.EVMNetwork + ChainClientA blockchain.EVMClient + ChainClientB blockchain.EVMClient +} + +// LeaderLane is to hold the details of leader lane source and destination network +type LeaderLane struct { + source string + dest string +} + +type CCIPTestConfig struct { + Test *testing.T + EnvInput *testconfig.Common + TestGroupInput *testconfig.CCIPTestGroupConfig + VersionInput map[contracts.Name]contracts.Version + ContractsInput *testconfig.CCIPContractConfig + AllNetworks map[string]blockchain.EVMNetwork + SelectedNetworks []blockchain.EVMNetwork + NetworkPairs []NetworkPair + LeaderLanes []LeaderLane + GethResourceProfile map[string]interface{} +} + +func (c *CCIPTestConfig) useExistingDeployment() bool { + return pointer.GetBool(c.TestGroupInput.ExistingDeployment) +} + +func (c *CCIPTestConfig) useSeparateTokenDeployer() bool { + return contracts.NeedTokenAdminRegistry() && + !pointer.GetBool(c.TestGroupInput.TokenConfig.CCIPOwnerTokens) && + !c.useExistingDeployment() +} + +func (c *CCIPTestConfig) MultiCallEnabled() bool { + return pointer.GetBool(c.TestGroupInput.MulticallInOneTx) +} + +func (c *CCIPTestConfig) localCluster() bool { + return pointer.GetBool(c.TestGroupInput.LocalCluster) +} + +func (c *CCIPTestConfig) ExistingCLCluster() bool { + return c.EnvInput.ExistingCLCluster != nil +} + +func (c *CCIPTestConfig) CLClusterNeedsUpgrade() bool { + if c.EnvInput.NewCLCluster == nil { + return false + } + if c.EnvInput.NewCLCluster.Common != nil && c.EnvInput.NewCLCluster.Common.ChainlinkUpgradeImage != nil { + return true + } + for _, node := range c.EnvInput.NewCLCluster.Nodes { + if node.ChainlinkUpgradeImage != nil { + return true + } + } + return false +} + +func (c *CCIPTestConfig) AddPairToNetworkList(networkA, networkB blockchain.EVMNetwork) { + if c.AllNetworks == nil { + c.AllNetworks = make(map[string]blockchain.EVMNetwork) + } + firstOfPairs := []blockchain.EVMNetwork{networkA} + secondOfPairs := []blockchain.EVMNetwork{networkB} + // if no of lanes per pair is greater than 1, copy common contracts from the same network + // if no of lanes per pair is more than 1, the networks are added into the inputs.AllNetworks with a suffix of - + // for example, if no of lanes per pair is 2, and the network pairs are called "testnetA", "testnetB", + // the network will be added as "testnetA-1", testnetA-2","testnetB-1", testnetB-2" + // to deploy 4 lanes between same network pair "testnetA", "testnetB". + // lanes - testnetA-1<->testnetB-1, testnetA-1<-->testnetB-2 , testnetA-2<--> testnetB-1, testnetA-2<--> testnetB-2 + if c.TestGroupInput.NoOfRoutersPerPair > 1 { + firstOfPairs[0].Name = fmt.Sprintf("%s-%d", firstOfPairs[0].Name, 1) + secondOfPairs[0].Name = fmt.Sprintf("%s-%d", secondOfPairs[0].Name, 1) + for i := 1; i < c.TestGroupInput.NoOfRoutersPerPair; i++ { + netsA := networkA + netsA.Name = fmt.Sprintf("%s-%d", netsA.Name, i+1) + netsB := networkB + netsB.Name = fmt.Sprintf("%s-%d", netsB.Name, i+1) + firstOfPairs = append(firstOfPairs, netsA) + secondOfPairs = append(secondOfPairs, netsB) + } + } + + for i := range firstOfPairs { + c.AllNetworks[firstOfPairs[i].Name] = firstOfPairs[i] + c.AllNetworks[secondOfPairs[i].Name] = secondOfPairs[i] + c.NetworkPairs = append(c.NetworkPairs, NetworkPair{ + NetworkA: firstOfPairs[i], + NetworkB: secondOfPairs[i], + }) + } +} + +func (c *CCIPTestConfig) SetNetworkPairs(lggr zerolog.Logger) error { + var allError error + var err error + var inputNetworks []string + c.SelectedNetworks, inputNetworks, err = c.EnvInput.EVMNetworks() + if err != nil { + allError = multierr.Append(allError, fmt.Errorf("failed to get networks: %w", err)) + return allError + } + + networkByChainName := make(map[string]blockchain.EVMNetwork) + for i, net := range c.SelectedNetworks { + networkByChainName[inputNetworks[i]] = net + } + // if network pairs are provided, then use them + if c.TestGroupInput.NetworkPairs != nil { + networkPairs := c.TestGroupInput.NetworkPairs + + for _, pair := range networkPairs { + networkNames := strings.Split(pair, ",") + if len(networkNames) != 2 { + allError = multierr.Append(allError, fmt.Errorf("invalid network pair")) + } + // check if the network names are valid + network1, ok := networkByChainName[networkNames[0]] + if !ok { + allError = multierr.Append(allError, fmt.Errorf("network %s not found in network config", networkNames[0])) + } + network2, ok := networkByChainName[networkNames[1]] + if !ok { + allError = multierr.Append(allError, fmt.Errorf("network %s not found in network config", networkNames[1])) + } + c.AddPairToNetworkList(network1, network2) + } + lggr.Info().Int("Pairs", len(c.NetworkPairs)).Msg("No Of Lanes") + return allError + } + + if c.TestGroupInput.NoOfNetworks == 0 { + c.TestGroupInput.NoOfNetworks = len(c.SelectedNetworks) + } + // TODO remove this when CTF network timeout is fixed + for i := range c.SelectedNetworks { + c.SelectedNetworks[i].Timeout = blockchain.StrDuration{ + Duration: 3 * time.Minute, + } + } + simulated := c.SelectedNetworks[0].Simulated + for i := 1; i < len(c.SelectedNetworks); i++ { + if c.SelectedNetworks[i].Simulated != simulated { + lggr.Fatal().Msg("networks must be of the same type either simulated or real") + } + } + + // if the networks are not simulated use the first p.NoOfNetworks networks from the selected networks + if !simulated && len(c.SelectedNetworks) != c.TestGroupInput.NoOfNetworks { + if len(c.SelectedNetworks) < c.TestGroupInput.NoOfNetworks { + allError = multierr.Append(allError, fmt.Errorf("not enough networks provided")) + } else { + c.SelectedNetworks = c.SelectedNetworks[:c.TestGroupInput.NoOfNetworks] + } + } + // If provided networks is lesser than the required number of networks + // and the provided networks are simulated network, create replicas of the provided networks with + // different chain ids + if simulated && len(c.SelectedNetworks) < c.TestGroupInput.NoOfNetworks { + actualNoOfNetworks := len(c.SelectedNetworks) + n := c.SelectedNetworks[0] + var chainIDs []int64 + existingChainIDs := make(map[uint64]struct{}) + for _, net := range c.SelectedNetworks { + existingChainIDs[uint64(net.ChainID)] = struct{}{} + } + for _, id := range chainselectors.TestChainIds() { + // if the chain id already exists in the already provided selected networks, skip it + if _, exists := existingChainIDs[id]; exists { + continue + } + chainIDs = append(chainIDs, int64(id)) + } + for i := 0; i < c.TestGroupInput.NoOfNetworks-actualNoOfNetworks; i++ { + chainID := chainIDs[i] + // if i is greater than the number of simulated pvt keys, rotate the keys + if i > len(networks.AdditionalSimulatedPvtKeys)-1 { + networks.AdditionalSimulatedPvtKeys = append(networks.AdditionalSimulatedPvtKeys, networks.AdditionalSimulatedPvtKeys...) + } + name := fmt.Sprintf("private-chain-%d", len(c.SelectedNetworks)+1) + c.SelectedNetworks = append(c.SelectedNetworks, blockchain.EVMNetwork{ + Name: name, + ChainID: chainID, + Simulated: true, + PrivateKeys: []string{ + networks.AdditionalSimulatedPvtKeys[i], + "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", // second key for token deployments + }, + ChainlinkTransactionLimit: n.ChainlinkTransactionLimit, + Timeout: n.Timeout, + MinimumConfirmations: n.MinimumConfirmations, + GasEstimationBuffer: n.GasEstimationBuffer + 1000, + ClientImplementation: n.ClientImplementation, + DefaultGasLimit: n.DefaultGasLimit, + FinalityDepth: n.FinalityDepth, + SupportsEIP1559: true, + }) + if existing, ok := c.EnvInput.Network.AnvilConfigs[strings.ToUpper(n.Name)]; c.EnvInput.Network.AnvilConfigs != nil && ok { + c.EnvInput.Network.AnvilConfigs[strings.ToUpper(name)] = existing + } + + chainConfig := &ctf_config.EthereumChainConfig{} + err := chainConfig.Default() + if err != nil { + allError = multierr.Append(allError, fmt.Errorf("failed to get default chain config: %w", err)) + } else { + chainConfig.ChainID = int(chainID) + eth1 := ctf_config_types.EthereumVersion_Eth1 + geth := ctf_config_types.ExecutionLayer_Geth + + c.EnvInput.PrivateEthereumNetworks[fmt.Sprint(chainID)] = &ctf_config.EthereumNetworkConfig{ + EthereumVersion: ð1, + ExecutionLayer: &geth, + EthereumChainConfig: chainConfig, + } + } + } + } + + if c.TestGroupInput.NoOfNetworks > 2 { + c.FormNetworkPairCombinations() + } else { + c.AddPairToNetworkList(c.SelectedNetworks[0], c.SelectedNetworks[1]) + } + + // if the number of lanes is lesser than the number of network pairs, choose first c.TestGroupInput.MaxNoOfLanes pairs + if c.TestGroupInput.MaxNoOfLanes > 0 && c.TestGroupInput.MaxNoOfLanes < len(c.NetworkPairs) { + var newNetworkPairs []NetworkPair + denselyConnectedNetworks := make(map[string]struct{}) + // if densely connected networks are provided, choose all the network pairs containing the networks mentioned in the list for DenselyConnectedNetworkChainIds + if c.TestGroupInput.DenselyConnectedNetworkChainIds != nil && len(c.TestGroupInput.DenselyConnectedNetworkChainIds) > 0 { + for _, n := range c.TestGroupInput.DenselyConnectedNetworkChainIds { + denselyConnectedNetworks[n] = struct{}{} + } + for _, pair := range c.NetworkPairs { + if _, exists := denselyConnectedNetworks[strconv.FormatInt(pair.NetworkA.ChainID, 10)]; exists { + newNetworkPairs = append(newNetworkPairs, pair) + } + } + } + // shuffle the network pairs, we want to randomly distribute the network pairs among all available networks + rand.Shuffle(len(c.NetworkPairs), func(i, j int) { + c.NetworkPairs[i], c.NetworkPairs[j] = c.NetworkPairs[j], c.NetworkPairs[i] + }) + // now add the remaining network pairs by skipping the already covered networks + // and adding the remaining pair from the shuffled list + i := len(newNetworkPairs) + j := 0 + for i < c.TestGroupInput.MaxNoOfLanes { + pair := c.NetworkPairs[j] + // if the network is already covered, skip it + if _, exists := denselyConnectedNetworks[strconv.FormatInt(pair.NetworkA.ChainID, 10)]; !exists { + newNetworkPairs = append(newNetworkPairs, pair) + i++ + } + j++ + } + c.NetworkPairs = newNetworkPairs + } + + // setting leader lane details to network pairs if it is enabled and only in simulated environments + if !pointer.GetBool(c.TestGroupInput.ExistingDeployment) { + c.defineLeaderLanes(lggr) + } + for _, n := range c.NetworkPairs { + lggr.Info(). + Str("NetworkA", fmt.Sprintf("%s-%d", n.NetworkA.Name, n.NetworkA.ChainID)). + Str("NetworkB", fmt.Sprintf("%s-%d", n.NetworkB.Name, n.NetworkB.ChainID)). + Msg("Network Pairs") + } + for _, lane := range c.LeaderLanes { + lggr.Info(). + Str("Source", lane.source). + Str("Destination", lane.dest). + Msg("Leader Lane: ") + } + lggr.Info().Int("Pairs", len(c.NetworkPairs)).Msg("No Of Lanes") + + return allError +} + +// defineLeaderLanes goes over the available network pairs and define one leader lane per destination +func (c *CCIPTestConfig) defineLeaderLanes(lggr zerolog.Logger) { + if !isLeaderLaneFeatureEnabled(&lggr) { + return + } + // the way we are defining leader lane is simply by tagging the destination as key along with the first source network + // as value to the map. + leaderLanes := make(map[string]string) + for _, n := range c.NetworkPairs { + if _, ok := leaderLanes[n.NetworkB.Name]; !ok { + leaderLanes[n.NetworkB.Name] = n.NetworkA.Name + } + if pointer.GetBool(c.TestGroupInput.BiDirectionalLane) { + if _, ok := leaderLanes[n.NetworkA.Name]; !ok { + leaderLanes[n.NetworkA.Name] = n.NetworkB.Name + } + } + } + for k, v := range leaderLanes { + c.LeaderLanes = append(c.LeaderLanes, LeaderLane{ + source: v, + dest: k, + }) + } +} + +// isPriceReportingDisabled checks the given lane is leader lane and return boolean accordingly +func (c *CCIPTestConfig) isPriceReportingDisabled(lggr *zerolog.Logger, source, dest string) bool { + for _, leader := range c.LeaderLanes { + if leader.source == source && leader.dest == dest { + lggr.Debug(). + Str("Source", source). + Str("Destination", dest). + Msg("Non-leader lane") + return true + } + } + return false +} + +func isLeaderLaneFeatureEnabled(lggr *zerolog.Logger) bool { + if err := contracts.MatchContractVersionsOrAbove(map[contracts.Name]contracts.Version{ + contracts.OffRampContract: contracts.V1_2_0, + contracts.OnRampContract: contracts.V1_2_0, + }); err != nil { + lggr.Info().Str("Required contract version", contracts.V1_2_0.String()).Msg("Leader lane feature is not enabled") + return false + } + return true +} + +func (c *CCIPTestConfig) FormNetworkPairCombinations() { + for i := 0; i < c.TestGroupInput.NoOfNetworks; i++ { + for j := i + 1; j < c.TestGroupInput.NoOfNetworks; j++ { + c.AddPairToNetworkList(c.SelectedNetworks[i], c.SelectedNetworks[j]) + } + } +} + +func (c *CCIPTestConfig) SetContractVersion() error { + if c.VersionInput == nil { + return nil + } + for contractName, version := range c.VersionInput { + err := contracts.CheckVersionSupported(contractName, version) + if err != nil { + return err + } + contracts.VersionMap[contractName] = version + } + return nil +} + +func (c *CCIPTestConfig) SetOCRParams() error { + if c.TestGroupInput.OffRampConfig != nil { + if c.TestGroupInput.OffRampConfig.InflightExpiry != nil && + c.TestGroupInput.OffRampConfig.InflightExpiry.Duration() > 0 { + actions.InflightExpiryExec = c.TestGroupInput.OffRampConfig.InflightExpiry.Duration() + } + if pointer.GetUint32(c.TestGroupInput.OffRampConfig.BatchGasLimit) > 0 { + actions.BatchGasLimit = pointer.GetUint32(c.TestGroupInput.OffRampConfig.BatchGasLimit) + } + if pointer.GetUint32(c.TestGroupInput.OffRampConfig.MaxDataBytes) > 0 { + actions.MaxDataBytes = pointer.GetUint32(c.TestGroupInput.OffRampConfig.MaxDataBytes) + } + if c.TestGroupInput.OffRampConfig.RootSnooze != nil && + c.TestGroupInput.OffRampConfig.RootSnooze.Duration() > 0 { + actions.RootSnoozeTime = c.TestGroupInput.OffRampConfig.RootSnooze.Duration() + } + } + if c.TestGroupInput.CommitInflightExpiry != nil && c.TestGroupInput.CommitInflightExpiry.Duration() > 0 { + actions.InflightExpiryCommit = c.TestGroupInput.CommitInflightExpiry.Duration() + } + return nil +} + +// TestConfigOverrideOption is a function that modifies the test config and overrides any values passed in by test files +// This is useful for setting up test specific configurations. +// The return should be a short, explanatory string that describes the change made by the override. +// This is logged at the beginning of the test run. +type TestConfigOverrideOption func(*CCIPTestConfig) string + +// UseCCIPOwnerTokens defines whether all tokens are deployed by the same address as the CCIP owner +func UseCCIPOwnerTokens(yes bool) TestConfigOverrideOption { + return func(c *CCIPTestConfig) string { + c.TestGroupInput.TokenConfig.CCIPOwnerTokens = pointer.ToBool(yes) + return fmt.Sprintf("CCIPOwnerTokens set to %t", yes) + } +} + +// WithTokensPerChain sets the number of tokens to deploy on each chain +func WithTokensPerChain(count int) TestConfigOverrideOption { + return func(c *CCIPTestConfig) string { + c.TestGroupInput.TokenConfig.NoOfTokensPerChain = pointer.ToInt(count) + return fmt.Sprintf("NoOfTokensPerChain set to %d", count) + } +} + +// WithMsgDetails sets the message details for the test +func WithMsgDetails(details *testconfig.MsgDetails) TestConfigOverrideOption { + return func(c *CCIPTestConfig) string { + c.TestGroupInput.MsgDetails = details + return "Message set" + } +} + +// WithNoTokensPerMessage sets how many tokens can be sent in a single message +func WithNoTokensPerMessage(noOfTokens int) TestConfigOverrideOption { + return func(c *CCIPTestConfig) string { + c.TestGroupInput.MsgDetails.NoOfTokens = pointer.ToInt(noOfTokens) + return fmt.Sprintf("MsgDetails.NoOfTokens set to %d", noOfTokens) + } +} + +// NewCCIPTestConfig reads the CCIP test config from TOML files, applies any overrides, and configures the test environment +func NewCCIPTestConfig(t *testing.T, lggr zerolog.Logger, tType string, overrides ...TestConfigOverrideOption) *CCIPTestConfig { + testCfg := ccipconfig.GlobalTestConfig() + groupCfg, exists := testCfg.CCIP.Groups[tType] + if !exists { + t.Fatalf("group config for %s does not exist", tType) + } + if tType == ccipconfig.Load { + if testCfg.CCIP.Env.Logging == nil || testCfg.CCIP.Env.Logging.Loki == nil { + t.Fatal("loki config is required to be set for load test") + } + if testCfg.CCIP.Env.Logging == nil || testCfg.CCIP.Env.Logging.Grafana == nil { + t.Fatal("grafana config is required for load test") + } + } + if pointer.GetBool(groupCfg.KeepEnvAlive) { + err := os.Setenv(config.EnvVarKeepEnvironments, "ALWAYS") + if err != nil { + t.Fatal(err) + } + } + ccipTestConfig := &CCIPTestConfig{ + Test: t, + EnvInput: testCfg.CCIP.Env, + ContractsInput: testCfg.CCIP.Deployments, + VersionInput: testCfg.CCIP.ContractVersions, + TestGroupInput: groupCfg, + GethResourceProfile: GethResourceProfile, + } + setContractVersion.Do(func() { + err := ccipTestConfig.SetContractVersion() + if err != nil { + t.Fatal(err) + } + }) + setOCRParams.Do(func() { + err := ccipTestConfig.SetOCRParams() + if err != nil { + t.Fatal(err) + } + }) + setConfigOverrides.Do(func() { + overrideMessages := []string{} + for _, override := range overrides { + if override != nil { + overrideMessages = append(overrideMessages, override(ccipTestConfig)) + } + } + if len(overrideMessages) > 0 { + lggr.Debug().Int("Overrides", len(overrideMessages)).Msg("Test Specific Config Overrides Applied") + for _, msg := range overrideMessages { + lggr.Debug().Msg(msg) + } + } + }) + err := ccipTestConfig.SetNetworkPairs(lggr) + if err != nil { + t.Fatal(err) + } + + return ccipTestConfig +} + +type BiDirectionalLaneConfig struct { + NetworkA blockchain.EVMNetwork + NetworkB blockchain.EVMNetwork + ForwardLane *actions.CCIPLane + ReverseLane *actions.CCIPLane +} + +type CCIPTestSetUpOutputs struct { + SetUpContext context.Context + Cfg *CCIPTestConfig + LaneContractsByNetwork *sync.Map + laneMutex *sync.Mutex + Lanes []*BiDirectionalLaneConfig + Reporter *testreporters.CCIPTestReporter + LaneConfigFile string + LaneConfig *laneconfig.Lanes + TearDown func() error + Env *actions.CCIPTestEnv + Balance *actions.BalanceSheet + BootstrapAdded *atomic.Bool + JobAddGrp *errgroup.Group +} + +func (o *CCIPTestSetUpOutputs) AddToLanes(lane *BiDirectionalLaneConfig) { + o.laneMutex.Lock() + defer o.laneMutex.Unlock() + o.Lanes = append(o.Lanes, lane) +} + +func (o *CCIPTestSetUpOutputs) ReadLanes() []*BiDirectionalLaneConfig { + o.laneMutex.Lock() + defer o.laneMutex.Unlock() + return o.Lanes +} + +func (o *CCIPTestSetUpOutputs) DeployChainContracts( + lggr *zerolog.Logger, + chainClient blockchain.EVMClient, + networkCfg blockchain.EVMNetwork, + noOfTokens int, + tokenDeployerFns []blockchain.ContractDeployer, +) error { + var k8Env *environment.Environment + ccipEnv := o.Env + if ccipEnv != nil { + k8Env = ccipEnv.K8Env + } + if k8Env != nil && chainClient.NetworkSimulated() { + networkCfg.URLs = k8Env.URLs[chainClient.GetNetworkConfig().Name] + } + + mainChainClient, err := blockchain.ConcurrentEVMClient(networkCfg, k8Env, chainClient, *lggr) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create chain client for %s: %w", networkCfg.Name, err)) + } + + mainChainClient.ParallelTransactions(true) + defer mainChainClient.Close() + ccipCommon, err := actions.DefaultCCIPModule( + lggr, o.Cfg.TestGroupInput, mainChainClient, + ) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create ccip common module for %s: %w", networkCfg.Name, err)) + } + + cfg := o.LaneConfig.ReadLaneConfig(networkCfg.Name) + + err = ccipCommon.DeployContracts(noOfTokens, tokenDeployerFns, cfg) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy common ccip contracts for %s: %w", networkCfg.Name, err)) + } + ccipCommon.WriteLaneConfig(cfg) + o.LaneContractsByNetwork.Store(networkCfg.Name, cfg) + + return nil +} + +func (o *CCIPTestSetUpOutputs) SetupDynamicTokenPriceUpdates() error { + interval := o.Cfg.TestGroupInput.TokenConfig.DynamicPriceUpdateInterval.Duration() + covered := make(map[string]struct{}) + for _, lanes := range o.ReadLanes() { + lane := lanes.ForwardLane + if _, exists := covered[lane.SourceNetworkName]; !exists { + covered[lane.SourceNetworkName] = struct{}{} + err := lane.Source.Common.UpdateTokenPricesAtRegularInterval(lane.Context, lane.Logger, interval, o.LaneConfig.ReadLaneConfig(lane.SourceNetworkName)) + if err != nil { + return err + } + } + if _, exists := covered[lane.DestNetworkName]; !exists { + covered[lane.DestNetworkName] = struct{}{} + err := lane.Dest.Common.UpdateTokenPricesAtRegularInterval(lane.Context, lane.Logger, interval, o.LaneConfig.ReadLaneConfig(lane.DestNetworkName)) + if err != nil { + return err + } + } + } + return nil +} + +func (o *CCIPTestSetUpOutputs) AddLanesForNetworkPair( + lggr *zerolog.Logger, + networkA, networkB blockchain.EVMNetwork, + chainClientA, chainClientB blockchain.EVMClient, +) error { + var ( + t = o.Cfg.Test + allErrors atomic.Error + k8Env *environment.Environment + ccipEnv = o.Env + namespace = "" + ) + + if o.Cfg.TestGroupInput.LoadProfile != nil { + namespace = o.Cfg.TestGroupInput.LoadProfile.TestRunName + } + bidirectional := pointer.GetBool(o.Cfg.TestGroupInput.BiDirectionalLane) + if ccipEnv != nil { + k8Env = ccipEnv.K8Env + if k8Env != nil { + namespace = k8Env.Cfg.Namespace + } + } + + setUpFuncs, ctx := errgroup.WithContext(testcontext.Get(t)) + + // Use new set of clients(sourceChainClient,destChainClient) + // with new header subscriptions(otherwise transactions + // on one lane will keep on waiting for transactions on other lane for the same network) + // Currently for simulated network clients(from same network) created with NewEVMClient does not sync nonce + // ConcurrentEVMClient is a work-around for that. + sourceChainClientA2B, err := blockchain.ConcurrentEVMClient(networkA, k8Env, chainClientA, *lggr) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create chain client for %s: %w", networkA.Name, err)) + } + + sourceChainClientA2B.ParallelTransactions(true) + + destChainClientA2B, err := blockchain.ConcurrentEVMClient(networkB, k8Env, chainClientB, *lggr) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create chain client for %s: %w", networkB.Name, err)) + } + destChainClientA2B.ParallelTransactions(true) + + ccipLaneA2B := &actions.CCIPLane{ + Test: t, + SourceChain: sourceChainClientA2B, + DestChain: destChainClientA2B, + SourceNetworkName: actions.NetworkName(networkA.Name), + DestNetworkName: actions.NetworkName(networkB.Name), + ValidationTimeout: o.Cfg.TestGroupInput.PhaseTimeout.Duration(), + SentReqs: make(map[common.Hash][]actions.CCIPRequest), + TotalFee: big.NewInt(0), + Balance: o.Balance, + Context: testcontext.Get(t), + } + // if it non leader lane, disable the price reporting + ccipLaneA2B.PriceReportingDisabled = len(o.Cfg.LeaderLanes) > 0 && + !o.Cfg.isPriceReportingDisabled(lggr, ccipLaneA2B.SourceNetworkName, ccipLaneA2B.DestNetworkName) + + contractsA, ok := o.LaneContractsByNetwork.Load(networkA.Name) + if !ok { + return errors.WithStack(fmt.Errorf("failed to load lane contracts for %s", networkA.Name)) + } + srcCfg := contractsA.(*laneconfig.LaneConfig) + ccipLaneA2B.SrcNetworkLaneCfg = srcCfg + contractsB, ok := o.LaneContractsByNetwork.Load(networkB.Name) + if !ok { + return errors.WithStack(fmt.Errorf("failed to load lane contracts for %s", networkB.Name)) + } + destCfg := contractsB.(*laneconfig.LaneConfig) + ccipLaneA2B.DstNetworkLaneCfg = destCfg + + a2blogger := lggr.With().Str("env", namespace).Str("Lane", + fmt.Sprintf("%s-->%s", ccipLaneA2B.SourceNetworkName, ccipLaneA2B.DestNetworkName)).Logger() + ccipLaneA2B.Logger = &a2blogger + ccipLaneA2B.Reports = o.Reporter.AddNewLane(fmt.Sprintf("%s To %s", + networkA.Name, networkB.Name), ccipLaneA2B.Logger) + + bidirectionalLane := &BiDirectionalLaneConfig{ + NetworkA: networkA, + NetworkB: networkB, + ForwardLane: ccipLaneA2B, + } + + var ccipLaneB2A *actions.CCIPLane + + if bidirectional { + sourceChainClientB2A, err := blockchain.ConcurrentEVMClient(networkB, k8Env, chainClientB, *lggr) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create chain client for %s: %w", networkB.Name, err)) + } + sourceChainClientB2A.ParallelTransactions(true) + + destChainClientB2A, err := blockchain.ConcurrentEVMClient(networkA, k8Env, chainClientA, *lggr) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create chain client for %s: %w", networkA.Name, err)) + } + destChainClientB2A.ParallelTransactions(true) + + ccipLaneB2A = &actions.CCIPLane{ + Test: t, + SourceNetworkName: actions.NetworkName(networkB.Name), + DestNetworkName: actions.NetworkName(networkA.Name), + SourceChain: sourceChainClientB2A, + DestChain: destChainClientB2A, + ValidationTimeout: o.Cfg.TestGroupInput.PhaseTimeout.Duration(), + Balance: o.Balance, + SentReqs: make(map[common.Hash][]actions.CCIPRequest), + TotalFee: big.NewInt(0), + Context: testcontext.Get(t), + SrcNetworkLaneCfg: ccipLaneA2B.DstNetworkLaneCfg, + DstNetworkLaneCfg: ccipLaneA2B.SrcNetworkLaneCfg, + } + // if it non leader lane, disable the price reporting + ccipLaneB2A.PriceReportingDisabled = len(o.Cfg.LeaderLanes) > 0 && + !o.Cfg.isPriceReportingDisabled(lggr, ccipLaneB2A.SourceNetworkName, ccipLaneB2A.DestNetworkName) + b2aLogger := lggr.With().Str("env", namespace).Str("Lane", + fmt.Sprintf("%s-->%s", ccipLaneB2A.SourceNetworkName, ccipLaneB2A.DestNetworkName)).Logger() + ccipLaneB2A.Logger = &b2aLogger + ccipLaneB2A.Reports = o.Reporter.AddNewLane( + fmt.Sprintf("%s To %s", networkB.Name, networkA.Name), ccipLaneB2A.Logger) + bidirectionalLane.ReverseLane = ccipLaneB2A + } + o.AddToLanes(bidirectionalLane) + + setUpFuncs.Go(func() error { + lggr.Info().Msgf("Setting up lane %s to %s", networkA.Name, networkB.Name) + err := ccipLaneA2B.DeployNewCCIPLane( + o.SetUpContext, o.Env, + o.Cfg.TestGroupInput, o.BootstrapAdded, o.JobAddGrp, + ) + if err != nil { + allErrors.Store(multierr.Append(allErrors.Load(), fmt.Errorf("deploying lane %s to %s; err - %w", networkA.Name, networkB.Name, errors.WithStack(err)))) + return err + } + err = o.LaneConfig.WriteLaneConfig(networkA.Name, ccipLaneA2B.SrcNetworkLaneCfg) + if err != nil { + lggr.Error().Err(err).Msgf("error deploying lane %s to %s", networkA.Name, networkB.Name) + allErrors.Store(multierr.Append(allErrors.Load(), fmt.Errorf("writing lane config for %s; err - %w", networkA.Name, errors.WithStack(err)))) + return err + } + err = o.LaneConfig.WriteLaneConfig(networkB.Name, ccipLaneA2B.DstNetworkLaneCfg) + if err != nil { + allErrors.Store(multierr.Append(allErrors.Load(), fmt.Errorf("writing lane config for %s; err - %w", networkB.Name, errors.WithStack(err)))) + return err + } + + // we need to set the remote chains on the pool after the lane is deployed + // it's sufficient to do this only for the forward lane, as the destination pools will also be updated with source pool updates + // The reverse lane will have the same pools as the forward lane but in reverse order of source and destination + err = ccipLaneA2B.SetRemoteChainsOnPool() + if err != nil { + allErrors.Store(multierr.Append(allErrors.Load(), fmt.Errorf("error setting remote chains; err - %w", errors.WithStack(err)))) + return err + } + lggr.Info().Msgf("done setting up lane %s to %s", networkA.Name, networkB.Name) + if o.Cfg.TestGroupInput.LoadProfile != nil && pointer.GetBool(o.Cfg.TestGroupInput.LoadProfile.OptimizeSpace) { + // This is to optimize memory space for load tests with high number of networks, lanes, tokens + ccipLaneA2B.OptimizeStorage() + } + return nil + }) + + setUpFuncs.Go(func() error { + if bidirectional { + lggr.Info().Msgf("Setting up lane %s to %s", networkB.Name, networkA.Name) + err := ccipLaneB2A.DeployNewCCIPLane( + o.SetUpContext, o.Env, + o.Cfg.TestGroupInput, o.BootstrapAdded, o.JobAddGrp, + ) + if err != nil { + lggr.Error().Err(err).Msgf("error deploying lane %s to %s", networkB.Name, networkA.Name) + allErrors.Store(multierr.Append(allErrors.Load(), fmt.Errorf("deploying lane %s to %s; err - %w", networkB.Name, networkA.Name, errors.WithStack(err)))) + return err + } + + err = o.LaneConfig.WriteLaneConfig(networkB.Name, ccipLaneB2A.SrcNetworkLaneCfg) + if err != nil { + allErrors.Store(multierr.Append(allErrors.Load(), fmt.Errorf("writing lane config for %s; err - %w", networkA.Name, errors.WithStack(err)))) + return err + } + err = o.LaneConfig.WriteLaneConfig(networkA.Name, ccipLaneB2A.DstNetworkLaneCfg) + if err != nil { + allErrors.Store( + multierr.Append( + allErrors.Load(), + fmt.Errorf("writing lane config for %s; err - %w", networkB.Name, errors.WithStack(err)), + ), + ) + return err + } + lggr.Info().Msgf("done setting up lane %s to %s", networkB.Name, networkA.Name) + if o.Cfg.TestGroupInput.LoadProfile != nil && pointer.GetBool(o.Cfg.TestGroupInput.LoadProfile.OptimizeSpace) { + // This is to optimize memory space for load tests with high number of networks, lanes, tokens + ccipLaneB2A.OptimizeStorage() + } + return nil + } + return nil + }) + + errs := make(chan error, 1) + go func() { + errs <- setUpFuncs.Wait() + }() + + // wait for either context to get cancelled or all the error-groups to finish execution + for { + select { + case err := <-errs: + // check if there has been any error while waiting for the error groups + // to finish execution + return err + case <-ctx.Done(): + lggr.Print(ctx.Err()) + return allErrors.Load() + } + } +} + +func (o *CCIPTestSetUpOutputs) StartEventWatchers() { + for _, lane := range o.ReadLanes() { + err := lane.ForwardLane.StartEventWatchers() + require.NoError(o.Cfg.Test, err) + if lane.ReverseLane != nil { + err = lane.ReverseLane.StartEventWatchers() + require.NoError(o.Cfg.Test, err) + } + } +} + +func (o *CCIPTestSetUpOutputs) WaitForPriceUpdates() { + t := o.Cfg.Test + priceUpdateGrp, _ := errgroup.WithContext(o.SetUpContext) + for _, lanes := range o.ReadLanes() { + lanes := lanes + forwardLane := lanes.ForwardLane + reverseLane := lanes.ReverseLane + waitForUpdate := func(lane *actions.CCIPLane) error { + defer func() { + lane.Logger.Info(). + Str("source_chain", lane.Source.Common.ChainClient.GetNetworkName()). + Uint64("dest_chain", lane.Source.DestinationChainId). + Str("price_registry", lane.Source.Common.PriceRegistry.Address()). + Msg("Stopping price update watch") + + }() + var allTokens []common.Address + for _, token := range lane.Source.Common.BridgeTokens { + allTokens = append(allTokens, token.ContractAddress) + } + allTokens = append(allTokens, lane.Source.Common.FeeToken.EthAddress) + lane.Logger.Info(). + Str("source_chain", lane.Source.Common.ChainClient.GetNetworkName()). + Uint64("dest_chain", lane.Source.DestinationChainId). + Str("price_registry", lane.Source.Common.PriceRegistry.Address()). + Msgf("Waiting for price update") + err := lane.Source.Common.WaitForPriceUpdates( + o.SetUpContext, lane.Logger, + o.Cfg.TestGroupInput.TokenConfig.TimeoutForPriceUpdate.Duration(), + lane.Source.DestinationChainId, + allTokens, + ) + if err != nil { + return errors.Wrapf(err, "waiting for price update failed on lane %s-->%s", lane.SourceNetworkName, lane.DestNetworkName) + } + return nil + } + + priceUpdateGrp.Go(func() error { + return waitForUpdate(forwardLane) + }) + if lanes.ReverseLane != nil { + priceUpdateGrp.Go(func() error { + return waitForUpdate(reverseLane) + }) + } + } + + require.NoError(t, priceUpdateGrp.Wait()) +} + +// CheckGasUpdateTransaction checks the gas update transactions count +func (o *CCIPTestSetUpOutputs) CheckGasUpdateTransaction(lggr *zerolog.Logger) error { + transactionsBySource := make(map[string]string) + destToSourcesList := make(map[string][]string) + // create a map to hold the unique destination with list of sources + for _, n := range o.Cfg.NetworkPairs { + destToSourcesList[n.NetworkB.Name] = append(destToSourcesList[n.NetworkB.Name], n.NetworkA.Name) + if pointer.GetBool(o.Cfg.TestGroupInput.BiDirectionalLane) { + destToSourcesList[n.NetworkA.Name] = append(destToSourcesList[n.NetworkA.Name], n.NetworkB.Name) + } + } + lggr.Debug().Interface("list", destToSourcesList).Msg("Dest to Source") + // a function to read the gas update events and create a map with unique source and store the tx hash + filterGasUpdateEventTxBySource := func(lane *actions.CCIPLane) error { + for _, g := range lane.Source.Common.GasUpdateEvents { + if g.Value == nil { + return fmt.Errorf("gas update value should not be nil in tx %s", g.Tx) + } + if _, ok := transactionsBySource[g.Source]; !ok { + transactionsBySource[g.Source] = g.Tx + } + } + return nil + } + + for _, lane := range o.ReadLanes() { + if err := filterGasUpdateEventTxBySource(lane.ForwardLane); err != nil { + return fmt.Errorf("error in filtering gas update transactions in the lane source: %s and destination: %s, error: %w", + lane.ForwardLane.SourceNetworkName, lane.ForwardLane.DestNetworkName, err) + } + if lane.ReverseLane != nil { + if err := filterGasUpdateEventTxBySource(lane.ReverseLane); err != nil { + return fmt.Errorf("error in filtering gas update transactions in the lane source: %s and destination: %s, error: %w", + lane.ReverseLane.SourceNetworkName, lane.ReverseLane.DestNetworkName, err) + } + } + } + + lggr.Debug().Interface("Tx hashes by source", transactionsBySource).Msg("Checked Gas Update Transactions by Source") + // when leader lane setup is enabled, number of unique transaction from the source + // should match the number of leader lanes defined. + if len(transactionsBySource) != len(o.Cfg.LeaderLanes) { + lggr.Error(). + Int("Tx hashes expected", len(o.Cfg.LeaderLanes)). + Int("Tx hashes received", len(transactionsBySource)). + Int("Leader lanes count", len(o.Cfg.LeaderLanes)). + Msg("Checked Gas Update transactions count doesn't match") + return fmt.Errorf("checked Gas Update transactions count doesn't match") + } + lggr.Debug(). + Int("Tx hashes by source", len(transactionsBySource)). + Int("Leader lanes count", len(o.Cfg.LeaderLanes)). + Msg("Checked Gas Update transactions count matches") + + return nil +} + +// CCIPDefaultTestSetUp sets up the environment for CCIP tests +// if configureCLNode is set as false, it assumes: +// 1. contracts are already deployed on live networks +// 2. CL nodes are set up and configured with existing contracts +// 3. No k8 env deployment is needed +// It reuses already deployed contracts from the addresses provided in ../contracts/ccip/laneconfig/contracts.json +// +// If bidirectional is true it sets up two-way lanes between NetworkA and NetworkB. Same CL nodes are used for both the lanes. +// If bidirectional is false only one way lane is set up. +// +// Returns - +// 1. CCIPLane for NetworkA --> NetworkB +// 2. If bidirectional is true, CCIPLane for NetworkB --> NetworkA +// 3. If configureCLNode is true, the tearDown func to call when environment needs to be destroyed +func CCIPDefaultTestSetUp( + t *testing.T, + lggr *zerolog.Logger, + envName string, + tokenDeployerFns []blockchain.ContractDeployer, + testConfig *CCIPTestConfig, +) *CCIPTestSetUpOutputs { + var err error + reportPath := "tmp_laneconfig" + filepath := fmt.Sprintf("./%s/tmp_%s.json", reportPath, strings.ReplaceAll(t.Name(), "/", "_")) + reportFile := testutils.FileNameFromPath(filepath) + parent, cancel := context.WithCancel(context.Background()) + defer cancel() + setUpArgs := &CCIPTestSetUpOutputs{ + SetUpContext: parent, + Cfg: testConfig, + Reporter: testreporters.NewCCIPTestReporter(t, lggr), + LaneConfigFile: filepath, + LaneContractsByNetwork: &sync.Map{}, + Balance: actions.NewBalanceSheet(), + BootstrapAdded: atomic.NewBool(false), + JobAddGrp: &errgroup.Group{}, + laneMutex: &sync.Mutex{}, + } + + contractsData, err := setUpArgs.Cfg.ContractsInput.ContractsData() + require.NoError(t, err, "error reading existing lane config") + + chainClientByChainID := setUpArgs.CreateEnvironment(lggr, envName, reportPath) + // if test is run in remote runner, register a clean-up to copy the laneconfig file + if value, set := os.LookupEnv(config.EnvVarJobImage); set && value != "" && + (setUpArgs.Env != nil && setUpArgs.Env.K8Env != nil) && + pointer.GetBool(setUpArgs.Cfg.TestGroupInput.StoreLaneConfig) { + t.Cleanup(func() { + path := fmt.Sprintf("reports/%s/%s", reportPath, reportFile) + dir, err := os.Getwd() + require.NoError(t, err) + destPath := fmt.Sprintf("%s/%s", dir, reportFile) + lggr.Info().Str("srcPath", path).Str("dstPath", destPath).Msg("copying lane config") + err = setUpArgs.Env.K8Env.CopyFromPod("app=runner-data", + "remote-test-runner-data-files", path, destPath) + require.NoError(t, err, "error getting lane config") + }) + } + if setUpArgs.Env != nil { + ccipEnv := setUpArgs.Env + if ccipEnv.K8Env != nil && ccipEnv.K8Env.WillUseRemoteRunner() { + return setUpArgs + } + } + + setUpArgs.LaneConfig, err = laneconfig.ReadLanesFromExistingDeployment(contractsData) + require.NoError(t, err) + + if setUpArgs.LaneConfig == nil { + setUpArgs.LaneConfig = &laneconfig.Lanes{LaneConfigs: make(map[string]*laneconfig.LaneConfig)} + } + laneCfgFile, err := os.Stat(setUpArgs.LaneConfigFile) + if err == nil && laneCfgFile.Size() > 0 { + // remove the existing lane config file + err = os.Remove(setUpArgs.LaneConfigFile) + require.NoError(t, err, "error while removing existing lane config file - %s", setUpArgs.LaneConfigFile) + } + + configureCLNode := !testConfig.useExistingDeployment() + + // if no of lanes per pair is greater than 1, copy common contracts from the same network + // if no of lanes per pair is more than 1, the networks are added into the testConfig.AllNetworks with a suffix of - + // for example, if no of lanes per pair is 2, and the network pairs are called "testnetA", "testnetB", + // the network will be added as "testnetA-1", testnetA-2","testnetB-1", testnetB-2" + // to deploy 2 lanes between same network pair "testnetA", "testnetB". + // In the following the common contracts will be copied from "testnetA" to "testnetA-1" and "testnetA-2" and + // from "testnetB" to "testnetB-1" and "testnetB-2" + for n := range testConfig.AllNetworks { + if setUpArgs.Cfg.TestGroupInput.NoOfRoutersPerPair > 1 { + regex := regexp.MustCompile(`-(\d+)$`) + networkNameToReadCfg := regex.ReplaceAllString(n, "") + reuse := pointer.GetBool(testConfig.TestGroupInput.ReuseContracts) + // if reuse contracts is true, copy common contracts from the same network except the router contract + setUpArgs.LaneConfig.CopyCommonContracts( + networkNameToReadCfg, n, + reuse, testConfig.TestGroupInput.MsgDetails.IsTokenTransfer(), + ) + } + } + + // deploy all chain specific common contracts + chainAddGrp, _ := errgroup.WithContext(setUpArgs.SetUpContext) + lggr.Info().Msg("Deploying common contracts") + + // If we have a token admin registry, we need to use a separate to deploy our test tokens from so that the tokens + // are not owned by the same account that owns the other CCIP contracts. This emulates self-serve token setups where + // the token owner is different from the CCIP contract owner. + if testConfig.useSeparateTokenDeployer() { + for _, net := range testConfig.AllNetworks { + chainClient := chainClientByChainID[net.ChainID] + require.NotNil(t, chainClient, "Chain client not found for chainID %d", net.ChainID) + require.GreaterOrEqual(t, len(chainClient.GetWallets()), 2, "The test is using a TokenAdminRegistry, and has CCIPOwnerTokens set to 'false'. The test needs a second wallet to deploy token contracts from. Please add a second wallet to the 'evm_clients' config option.") + tokenDeployerWallet := chainClient.GetWallets()[1] + // TODO: This is a total guess at how much funds we need to deploy the tokens. This could be way off, especially on live chains. + // There aren't a lot of good ways to estimate this though. See CCIP-2471. + recommendedTokenBalance := new(big.Int).Mul(big.NewInt(5e18), big.NewInt(int64(pointer.GetInt(testConfig.TestGroupInput.TokenConfig.NoOfTokensPerChain)))) + currentTokenBalance, err := chainClient.BalanceAt(context.Background(), common.HexToAddress(tokenDeployerWallet.Address())) + require.NoError(t, err) + if currentTokenBalance.Cmp(recommendedTokenBalance) < 0 { + lggr.Warn(). + Str("Token Deployer Address", tokenDeployerWallet.Address()). + Uint64("Current Balance", currentTokenBalance.Uint64()). + Uint64("Recommended Balance", recommendedTokenBalance.Uint64()). + Msg("Token Deployer wallet may be underfunded. Please ensure it has enough funds to deploy the tokens.") + } + } + } + + for _, net := range testConfig.AllNetworks { + chainClient := chainClientByChainID[net.ChainID] + net := net + net.HTTPURLs = chainClient.GetNetworkConfig().HTTPURLs + net.URLs = chainClient.GetNetworkConfig().URLs + chainAddGrp.Go(func() error { + return setUpArgs.DeployChainContracts( + lggr, chainClient, net, + pointer.GetInt(testConfig.TestGroupInput.TokenConfig.NoOfTokensPerChain), + tokenDeployerFns, + ) + }) + } + require.NoError(t, chainAddGrp.Wait(), "Deploying common contracts shouldn't fail") + + // set up mock server for price pipeline and usdc attestation if not using existing deployment + if !pointer.GetBool(setUpArgs.Cfg.TestGroupInput.ExistingDeployment) { + var killgrave *ctftestenv.Killgrave + if setUpArgs.Env.LocalCluster != nil { + killgrave = setUpArgs.Env.LocalCluster.MockAdapter + } + if setUpArgs.Cfg.TestGroupInput.TokenConfig.IsPipelineSpec() { + // set up mock server for price pipeline. need to set it once for all the lanes as the price pipeline path uses + // regex to match the path for all tokens across all lanes + actions.SetMockserverWithTokenPriceValue(killgrave, setUpArgs.Env.MockServer) + } + if pointer.GetBool(setUpArgs.Cfg.TestGroupInput.USDCMockDeployment) { + // if it's a new USDC deployment, set up mock server for attestation, + // we need to set it only once for all the lanes as the attestation path uses regex to match the path for + // all messages across all lanes + err = actions.SetMockServerWithUSDCAttestation(killgrave, setUpArgs.Env.MockServer) + require.NoError(t, err, "failed to set up mock server for attestation") + } + } + // deploy all lane specific contracts + lggr.Info().Msg("Deploying lane specific contracts") + laneAddGrp, _ := errgroup.WithContext(setUpArgs.SetUpContext) + // for memory management set a batch size for active lane deployment group + laneAddGrp.SetLimit(200) + for _, networkPair := range testConfig.NetworkPairs { + n := networkPair + var ok bool + n.ChainClientA, ok = chainClientByChainID[n.NetworkA.ChainID] + require.True(t, ok, "Chain client for chainID %d not found", n.NetworkA.ChainID) + n.ChainClientB, ok = chainClientByChainID[n.NetworkB.ChainID] + require.True(t, ok, "Chain client for chainID %d not found", n.NetworkB.ChainID) + + n.NetworkA.HTTPURLs = n.ChainClientA.GetNetworkConfig().HTTPURLs + n.NetworkA.URLs = n.ChainClientA.GetNetworkConfig().URLs + n.NetworkB.HTTPURLs = n.ChainClientB.GetNetworkConfig().HTTPURLs + n.NetworkB.URLs = n.ChainClientB.GetNetworkConfig().URLs + + laneAddGrp.Go(func() error { + return setUpArgs.AddLanesForNetworkPair( + lggr, n.NetworkA, n.NetworkB, + chainClientByChainID[n.NetworkA.ChainID], chainClientByChainID[n.NetworkB.ChainID], + ) + }) + } + require.NoError(t, laneAddGrp.Wait()) + err = laneconfig.WriteLanesToJSON(setUpArgs.LaneConfigFile, setUpArgs.LaneConfig) + require.NoError(t, err) + + require.Equal(t, len(setUpArgs.Lanes), len(testConfig.NetworkPairs), + "Number of bi-directional lanes should be equal to number of network pairs") + // only required for env set up + setUpArgs.LaneContractsByNetwork = nil + + if configureCLNode { + // wait for all jobs to get created + lggr.Info().Msg("Waiting for jobs to be created") + require.NoError(t, setUpArgs.JobAddGrp.Wait(), "Creating jobs shouldn't fail") + // wait for price updates to be available + setUpArgs.WaitForPriceUpdates() + if isLeaderLaneFeatureEnabled(lggr) && !pointer.GetBool(setUpArgs.Cfg.TestGroupInput.ExistingDeployment) { + require.NoError(t, setUpArgs.CheckGasUpdateTransaction(lggr), "gas update transaction check shouldn't fail") + } + // if dynamic price update is required + if setUpArgs.Cfg.TestGroupInput.TokenConfig.IsDynamicPriceUpdate() { + require.NoError(t, setUpArgs.SetupDynamicTokenPriceUpdates(), "setting up dynamic price update should not fail") + } + } + + // start event watchers for all lanes + setUpArgs.StartEventWatchers() + // now that lane configs are already dumped to file, we can clean up the lane config map + setUpArgs.LaneConfig = nil + setUpArgs.TearDown = func() error { + var errs error + for _, lanes := range setUpArgs.Lanes { + // if existing deployment is true, don't attempt to pay ccip fees + err := lanes.ForwardLane.CleanUp(configureCLNode) + if err != nil { + errs = multierr.Append(errs, err) + } + if lanes.ReverseLane != nil { + // if existing deployment is true, don't attempt to pay ccip fees + err := lanes.ReverseLane.CleanUp(configureCLNode) + if err != nil { + errs = multierr.Append(errs, err) + } + } + } + return errs + } + lggr.Info().Msg("Test setup completed") + return setUpArgs +} + +// CreateEnvironment creates the environment for the test and registers the test clean-up function to tear down the set-up environment +// It returns the map of chainID to EVMClient +func (o *CCIPTestSetUpOutputs) CreateEnvironment( + lggr *zerolog.Logger, + envName string, + reportPath string, +) map[int64]blockchain.EVMClient { + var ( + testConfig = o.Cfg + t = o.Cfg.Test + + ccipEnv *actions.CCIPTestEnv + k8Env *environment.Environment + err error + chains []blockchain.EVMClient + local *test_env.CLClusterTestEnv + deployCL func() error + ) + + envConfig := createEnvironmentConfig(t, envName, testConfig, reportPath) + + configureCLNode := !testConfig.useExistingDeployment() || pointer.GetString(testConfig.EnvInput.EnvToConnect) != "" + namespace := "" + if testConfig.TestGroupInput.LoadProfile != nil { + namespace = testConfig.TestGroupInput.LoadProfile.TestRunName + } + require.False(t, testConfig.localCluster() && testConfig.ExistingCLCluster(), + "local cluster and existing cluster cannot be true at the same time") + // if it's a new deployment, deploy the env + // Or if EnvToConnect is given connect to that k8 environment + if configureCLNode { + if !testConfig.ExistingCLCluster() { + // if it's a local cluster, deploy the local cluster in docker + if testConfig.localCluster() { + local, deployCL = DeployLocalCluster(t, testConfig) + ccipEnv = &actions.CCIPTestEnv{ + LocalCluster: local, + } + namespace = "local-docker-deployment" + } else { + // Otherwise, deploy the k8s env + lggr.Info().Msg("Deploying test environment") + // deploy the env if configureCLNode is true + k8Env = DeployEnvironments(t, envConfig, testConfig) + ccipEnv = &actions.CCIPTestEnv{K8Env: k8Env} + namespace = ccipEnv.K8Env.Cfg.Namespace + } + } else { + // if there is already a cluster, use the existing cluster to connect to the nodes + ccipEnv = &actions.CCIPTestEnv{} + mockserverURL := pointer.GetString(testConfig.EnvInput.Mockserver) + require.NotEmpty(t, mockserverURL, "mockserver URL cannot be nil") + ccipEnv.MockServer = ctfClient.NewMockserverClient(&ctfClient.MockserverConfig{ + LocalURL: mockserverURL, + ClusterURL: mockserverURL, + }) + } + ccipEnv.CLNodeWithKeyReady, _ = errgroup.WithContext(o.SetUpContext) + o.Env = ccipEnv + if ccipEnv.K8Env != nil && ccipEnv.K8Env.WillUseRemoteRunner() { + return nil + } + } else { + // if configureCLNode is false it means we don't need to deploy any additional pods, + // use a placeholder env to create just the remote runner in it. + if value, set := os.LookupEnv(config.EnvVarJobImage); set && value != "" { + k8Env = environment.New(envConfig) + err = k8Env.Run() + require.NoErrorf(t, err, "error creating environment remote runner") + o.Env = &actions.CCIPTestEnv{K8Env: k8Env} + if k8Env.WillUseRemoteRunner() { + return nil + } + } + } + if o.Cfg.TestGroupInput.LoadProfile != nil { + o.Cfg.TestGroupInput.LoadProfile.SetTestRunName(namespace) + } + chainByChainID := make(map[int64]blockchain.EVMClient) + if pointer.GetBool(testConfig.TestGroupInput.LocalCluster) { + require.NotNil(t, ccipEnv.LocalCluster, "Local cluster shouldn't be nil") + for _, n := range ccipEnv.LocalCluster.EVMNetworks { + if evmClient, err := blockchain.NewEVMClientFromNetwork(*n, *lggr); err == nil { + chainByChainID[evmClient.GetChainID().Int64()] = evmClient + chains = append(chains, evmClient) + } else { + lggr.Error().Err(err).Msgf("EVMClient for chainID %d not found", n.ChainID) + } + } + } else { + for _, n := range testConfig.SelectedNetworks { + if _, ok := chainByChainID[n.ChainID]; ok { + continue + } + var ec blockchain.EVMClient + if k8Env == nil { + ec, err = blockchain.ConnectEVMClient(n, *lggr) + } else { + log.Info().Interface("urls", k8Env.URLs).Msg("URLs") + ec, err = blockchain.NewEVMClient(n, k8Env, *lggr) + } + require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail") + chains = append(chains, ec) + chainByChainID[n.ChainID] = ec + } + } + if configureCLNode { + ccipEnv.CLNodeWithKeyReady.Go(func() error { + var totalNodes int + if !o.Cfg.ExistingCLCluster() { + if ccipEnv.LocalCluster != nil { + err = deployCL() + if err != nil { + return err + } + } + err = ccipEnv.ConnectToDeployedNodes() + if err != nil { + return fmt.Errorf("error connecting to chainlink nodes: %w", err) + } + totalNodes = pointer.GetInt(testConfig.EnvInput.NewCLCluster.NoOfNodes) + } else { + totalNodes = pointer.GetInt(testConfig.EnvInput.ExistingCLCluster.NoOfNodes) + err = ccipEnv.ConnectToExistingNodes(o.Cfg.EnvInput) + if err != nil { + return fmt.Errorf("error deploying and connecting to chainlink nodes: %w", err) + } + } + err = ccipEnv.SetUpNodeKeysAndFund(lggr, big.NewFloat(testConfig.TestGroupInput.NodeFunding), chains) + if err != nil { + return fmt.Errorf("error setting up nodes and keys %w", err) + } + // first node is the bootstrapper + ccipEnv.CommitNodeStartIndex = 1 + ccipEnv.ExecNodeStartIndex = 1 + ccipEnv.NumOfCommitNodes = testConfig.TestGroupInput.NoOfCommitNodes + ccipEnv.NumOfExecNodes = ccipEnv.NumOfCommitNodes + if !pointer.GetBool(testConfig.TestGroupInput.CommitAndExecuteOnSameDON) { + if len(ccipEnv.CLNodesWithKeys) < 11 { + return fmt.Errorf("not enough CL nodes for separate commit and execution nodes") + } + if testConfig.TestGroupInput.NoOfCommitNodes >= totalNodes { + return fmt.Errorf("number of commit nodes can not be greater than total number of nodes in DON") + } + // first two nodes are reserved for bootstrap commit and bootstrap exec + ccipEnv.CommitNodeStartIndex = 2 + ccipEnv.ExecNodeStartIndex = 2 + testConfig.TestGroupInput.NoOfCommitNodes + ccipEnv.NumOfExecNodes = totalNodes - (2 + testConfig.TestGroupInput.NoOfCommitNodes) + if ccipEnv.NumOfExecNodes < 4 { + return fmt.Errorf("insufficient number of exec nodes") + } + } + ccipEnv.NumOfAllowedFaultyExec = (ccipEnv.NumOfExecNodes - 1) / 3 + ccipEnv.NumOfAllowedFaultyCommit = (ccipEnv.NumOfCommitNodes - 1) / 3 + return nil + }) + } + + t.Cleanup(func() { + if configureCLNode { + if ccipEnv.LocalCluster != nil { + err := ccipEnv.LocalCluster.Terminate() + require.NoError(t, err, "Local cluster termination shouldn't fail") + require.NoError(t, o.Reporter.SendReport(t, namespace, false), "Aggregating and sending report shouldn't fail") + return + } + if pointer.GetBool(testConfig.TestGroupInput.KeepEnvAlive) || testConfig.ExistingCLCluster() { + require.NoError(t, o.Reporter.SendReport(t, namespace, true), "Aggregating and sending report shouldn't fail") + return + } + lggr.Info().Msg("Tearing down the environment") + err = integrationactions.TeardownSuite(t, nil, ccipEnv.K8Env, ccipEnv.CLNodes, o.Reporter, zapcore.DPanicLevel, o.Cfg.EnvInput) + require.NoError(t, err, "Environment teardown shouldn't fail") + } else { + //just send the report + require.NoError(t, o.Reporter.SendReport(t, namespace, true), "Aggregating and sending report shouldn't fail") + } + }) + return chainByChainID +} + +func createEnvironmentConfig(t *testing.T, envName string, testConfig *CCIPTestConfig, reportPath string) *environment.Config { + envConfig := &environment.Config{ + NamespacePrefix: envName, + Test: t, + // PreventPodEviction: true, //TODO: enable this once we have a way to handle pod eviction + } + if pointer.GetBool(testConfig.TestGroupInput.StoreLaneConfig) { + envConfig.ReportPath = reportPath + } + // if there is already existing namespace, no need to update any manifest there, we just connect to it + existingEnv := pointer.GetString(testConfig.EnvInput.EnvToConnect) + if existingEnv != "" { + envConfig.Namespace = existingEnv + envConfig.NamespacePrefix = "" + envConfig.SkipManifestUpdate = true + envConfig.RunnerName = fmt.Sprintf("%s-%s", environment.REMOTE_RUNNER_NAME, uuid.NewString()[0:5]) + } + if testConfig.EnvInput.TTL != nil { + envConfig.TTL = testConfig.EnvInput.TTL.Duration() + } + if testConfig.TestGroupInput.LoadProfile != nil && testConfig.TestGroupInput.LoadProfile.TestDuration != nil { + approxDur := testConfig.TestGroupInput.LoadProfile.TestDuration.Duration() + 3*time.Hour + if envConfig.TTL < approxDur { + envConfig.TTL = approxDur + } + } + return envConfig +} diff --git a/integration-tests/ccip-tests/testsetups/test_env.go b/integration-tests/ccip-tests/testsetups/test_env.go new file mode 100644 index 0000000000..63018c9fe4 --- /dev/null +++ b/integration-tests/ccip-tests/testsetups/test_env.go @@ -0,0 +1,594 @@ +package testsetups + +import ( + "bytes" + "fmt" + "os" + "strconv" + "strings" + "testing" + + "github.com/AlekSi/pointer" + "github.com/pkg/errors" + "github.com/rs/zerolog" + "github.com/stretchr/testify/require" + + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" + ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/config/types" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" + + "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/foundry" + + "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/mockserver" + mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/mockserver-cfg" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/chainlink" + "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/reorg" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + k8config "github.com/smartcontractkit/chainlink-testing-framework/k8s/config" + + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/types/config/node" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + integrationnodes "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" + evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + corechainlink "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" +) + +func SetResourceProfile(cpu, mem string) map[string]interface{} { + return map[string]interface{}{ + "requests": map[string]interface{}{ + "cpu": cpu, + "memory": mem, + }, + "limits": map[string]interface{}{ + "cpu": cpu, + "memory": mem, + }, + } +} + +func setNodeConfig(nets []blockchain.EVMNetwork, nodeConfig, commonChain string, configByChain map[string]string) (*corechainlink.Config, string, error) { + var tomlCfg *corechainlink.Config + var err error + var commonChainConfig *evmcfg.Chain + if commonChain != "" { + err = config.DecodeTOML(bytes.NewReader([]byte(commonChain)), &commonChainConfig) + if err != nil { + return nil, "", err + } + } + configByChainMap := make(map[int64]evmcfg.Chain) + for k, v := range configByChain { + var chain evmcfg.Chain + err = config.DecodeTOML(bytes.NewReader([]byte(v)), &chain) + if err != nil { + return nil, "", err + } + chainId, err := strconv.ParseInt(k, 10, 64) + if err != nil { + return nil, "", err + } + configByChainMap[chainId] = chain + } + if nodeConfig == "" { + tomlCfg = integrationnodes.NewConfig( + integrationnodes.NewBaseConfig(), + node.WithPrivateEVMs(nets, commonChainConfig, configByChainMap)) + } else { + tomlCfg, err = node.NewConfigFromToml([]byte(nodeConfig), node.WithPrivateEVMs(nets, commonChainConfig, configByChainMap)) + if err != nil { + return nil, "", err + } + } + tomlStr, err := tomlCfg.TOMLString() + return tomlCfg, tomlStr, err +} + +func ChainlinkPropsForUpdate( + t *testing.T, + testInputs *CCIPTestConfig, +) (map[string]any, int) { + updateProps := make(map[string]any) + upgradeImage := pointer.GetString(testInputs.EnvInput.NewCLCluster.Common.ChainlinkUpgradeImage.Image) + upgradeTag := pointer.GetString(testInputs.EnvInput.NewCLCluster.Common.ChainlinkUpgradeImage.Version) + noOfNodesToUpgrade := 0 + if len(testInputs.EnvInput.NewCLCluster.Nodes) > 0 { + var nodesMap []map[string]any + for _, clNode := range testInputs.EnvInput.NewCLCluster.Nodes { + if !pointer.GetBool(clNode.NeedsUpgrade) { + continue + } + upgradeImage = pointer.GetString(clNode.ChainlinkUpgradeImage.Image) + upgradeTag = pointer.GetString(clNode.ChainlinkUpgradeImage.Version) + if upgradeImage == "" || upgradeTag == "" { + continue + } + nodeConfig := clNode.BaseConfigTOML + commonChainConfig := clNode.CommonChainConfigTOML + chainConfigByChain := clNode.ChainConfigTOMLByChain + if nodeConfig == "" { + nodeConfig = testInputs.EnvInput.NewCLCluster.Common.BaseConfigTOML + } + if commonChainConfig == "" { + commonChainConfig = testInputs.EnvInput.NewCLCluster.Common.CommonChainConfigTOML + } + if chainConfigByChain == nil { + chainConfigByChain = testInputs.EnvInput.NewCLCluster.Common.ChainConfigTOMLByChain + } + + _, tomlStr, err := setNodeConfig( + testInputs.SelectedNetworks, + nodeConfig, commonChainConfig, chainConfigByChain, + ) + require.NoError(t, err) + nodesMap = append(nodesMap, map[string]any{ + "name": clNode.Name, + "chainlink": map[string]any{ + "image": map[string]any{ + "image": upgradeImage, + "version": upgradeTag, + }, + }, + "toml": tomlStr, + }) + noOfNodesToUpgrade++ + } + updateProps["nodes"] = nodesMap + } else { + if upgradeImage == "" || upgradeTag == "" { + return nil, 0 + } + updateProps["chainlink"] = map[string]interface{}{ + "image": map[string]interface{}{ + "image": upgradeImage, + "version": upgradeTag, + }, + } + _, tomlStr, err := setNodeConfig( + testInputs.SelectedNetworks, + testInputs.EnvInput.NewCLCluster.Common.BaseConfigTOML, + testInputs.EnvInput.NewCLCluster.Common.CommonChainConfigTOML, + testInputs.EnvInput.NewCLCluster.Common.ChainConfigTOMLByChain, + ) + require.NoError(t, err) + updateProps["toml"] = tomlStr + noOfNodesToUpgrade = pointer.GetInt(testInputs.EnvInput.NewCLCluster.NoOfNodes) + } + return updateProps, noOfNodesToUpgrade +} + +func ChainlinkChart( + t *testing.T, + testInputs *CCIPTestConfig, + nets []blockchain.EVMNetwork, +) environment.ConnectedChart { + require.NotNil(t, testInputs.EnvInput.NewCLCluster.Common, "Chainlink Common config is not specified") + clProps := make(map[string]interface{}) + clProps["prometheus"] = true + var formattedArgs []string + if len(testInputs.EnvInput.NewCLCluster.DBArgs) > 0 { + for _, arg := range testInputs.EnvInput.NewCLCluster.DBArgs { + formattedArgs = append(formattedArgs, "-c") + formattedArgs = append(formattedArgs, arg) + } + } + clProps["db"] = map[string]interface{}{ + "resources": SetResourceProfile(testInputs.EnvInput.NewCLCluster.DBCPU, testInputs.EnvInput.NewCLCluster.DBMemory), + "additionalArgs": formattedArgs, + "stateful": pointer.GetBool(testInputs.EnvInput.NewCLCluster.IsStateful), + "capacity": testInputs.EnvInput.NewCLCluster.DBCapacity, + "storageClassName": pointer.GetString(testInputs.EnvInput.NewCLCluster.DBStorageClass), + "enablePrometheusPostgresExporter": pointer.GetBool(testInputs.EnvInput.NewCLCluster.PromPgExporter), + "image": map[string]any{ + "image": testInputs.EnvInput.NewCLCluster.Common.DBImage, + "version": testInputs.EnvInput.NewCLCluster.Common.DBTag, + }, + } + clProps["chainlink"] = map[string]interface{}{ + "resources": SetResourceProfile(testInputs.EnvInput.NewCLCluster.NodeCPU, testInputs.EnvInput.NewCLCluster.NodeMemory), + "image": map[string]any{ + "image": pointer.GetString(testInputs.EnvInput.NewCLCluster.Common.ChainlinkImage.Image), + "version": pointer.GetString(testInputs.EnvInput.NewCLCluster.Common.ChainlinkImage.Version), + }, + } + + require.NotNil(t, testInputs.EnvInput, "no env test input specified") + + if len(testInputs.EnvInput.NewCLCluster.Nodes) > 0 { + var nodesMap []map[string]any + for _, clNode := range testInputs.EnvInput.NewCLCluster.Nodes { + nodeConfig := clNode.BaseConfigTOML + commonChainConfig := clNode.CommonChainConfigTOML + chainConfigByChain := clNode.ChainConfigTOMLByChain + if nodeConfig == "" { + nodeConfig = testInputs.EnvInput.NewCLCluster.Common.BaseConfigTOML + } + if commonChainConfig == "" { + commonChainConfig = testInputs.EnvInput.NewCLCluster.Common.CommonChainConfigTOML + } + if chainConfigByChain == nil { + chainConfigByChain = testInputs.EnvInput.NewCLCluster.Common.ChainConfigTOMLByChain + } + + _, tomlStr, err := setNodeConfig(nets, nodeConfig, commonChainConfig, chainConfigByChain) + require.NoError(t, err) + nodesMap = append(nodesMap, map[string]any{ + "name": clNode.Name, + "chainlink": map[string]any{ + "image": map[string]any{ + "image": pointer.GetString(clNode.ChainlinkImage.Image), + "version": pointer.GetString(clNode.ChainlinkImage.Version), + }, + }, + "db": map[string]any{ + "image": map[string]any{ + "image": clNode.DBImage, + "version": clNode.DBTag, + }, + "storageClassName": "gp3", + }, + "toml": tomlStr, + }) + } + clProps["nodes"] = nodesMap + return chainlink.New(0, clProps) + } + clProps["replicas"] = pointer.GetInt(testInputs.EnvInput.NewCLCluster.NoOfNodes) + _, tomlStr, err := setNodeConfig( + nets, + testInputs.EnvInput.NewCLCluster.Common.BaseConfigTOML, + testInputs.EnvInput.NewCLCluster.Common.CommonChainConfigTOML, + testInputs.EnvInput.NewCLCluster.Common.ChainConfigTOMLByChain, + ) + require.NoError(t, err) + clProps["toml"] = tomlStr + return chainlink.New(0, clProps) +} + +func DeployLocalCluster( + t *testing.T, + testInputs *CCIPTestConfig, +) (*test_env.CLClusterTestEnv, func() error) { + selectedNetworks := testInputs.SelectedNetworks + + privateEthereumNetworks := []*ctf_config.EthereumNetworkConfig{} + for _, network := range testInputs.EnvInput.PrivateEthereumNetworks { + privateEthereumNetworks = append(privateEthereumNetworks, network) + + for _, networkCfg := range networks.MustGetSelectedNetworkConfig(testInputs.EnvInput.Network) { + for _, key := range networkCfg.PrivateKeys { + address, err := conversions.PrivateKeyHexToAddress(key) + require.NoError(t, err, "failed to convert private key to address: %w", err) + network.EthereumChainConfig.AddressesToFund = append( + network.EthereumChainConfig.AddressesToFund, address.Hex(), + ) + } + } + } + + if len(selectedNetworks) > len(privateEthereumNetworks) { + seen := make(map[int64]bool) + missing := []blockchain.EVMNetwork{} + + for _, network := range privateEthereumNetworks { + seen[int64(network.EthereumChainConfig.ChainID)] = true + } + + for _, network := range selectedNetworks { + if !seen[network.ChainID] { + missing = append(missing, network) + } + } + + for _, network := range missing { + chainConfig := &ctf_config.EthereumChainConfig{} + err := chainConfig.Default() + if err != nil { + require.NoError(t, err, "failed to get default chain config: %w", err) + } else { + chainConfig.ChainID = int(network.ChainID) + eth1 := ctf_config_types.EthereumVersion_Eth1 + geth := ctf_config_types.ExecutionLayer_Geth + + privateEthereumNetworks = append(privateEthereumNetworks, &ctf_config.EthereumNetworkConfig{ + EthereumVersion: ð1, + ExecutionLayer: &geth, + EthereumChainConfig: chainConfig, + }) + } + } + + require.Equal(t, len(selectedNetworks), len(privateEthereumNetworks), "failed to create undefined selected networks. Maybe some of them had the same chain ids?") + } + + env, err := test_env.NewCLTestEnvBuilder(). + WithTestConfig(testInputs.EnvInput). + WithTestInstance(t). + WithPrivateEthereumNetworks(privateEthereumNetworks). + WithMockAdapter(). + WithoutCleanup(). + Build() + require.NoError(t, err) + // the builder builds network with a static network config, we don't want that. + env.EVMNetworks = []*blockchain.EVMNetwork{} + for i, networkCfg := range selectedNetworks { + rpcProvider, err := env.GetRpcProvider(networkCfg.ChainID) + require.NoError(t, err, "Error getting rpc provider") + selectedNetworks[i].URLs = rpcProvider.PrivateWsUrsl() + selectedNetworks[i].HTTPURLs = rpcProvider.PrivateHttpUrls() + newNetwork := networkCfg + newNetwork.URLs = rpcProvider.PublicWsUrls() + newNetwork.HTTPURLs = rpcProvider.PublicHttpUrls() + env.EVMNetworks = append(env.EVMNetworks, &newNetwork) + } + testInputs.SelectedNetworks = selectedNetworks + + // a func to start the CL nodes asynchronously + deployCL := func() error { + noOfNodes := pointer.GetInt(testInputs.EnvInput.NewCLCluster.NoOfNodes) + // if individual nodes are specified, then deploy them with specified configs + if len(testInputs.EnvInput.NewCLCluster.Nodes) > 0 { + for _, clNode := range testInputs.EnvInput.NewCLCluster.Nodes { + toml, _, err := setNodeConfig( + selectedNetworks, + clNode.BaseConfigTOML, + clNode.CommonChainConfigTOML, + clNode.ChainConfigTOMLByChain, + ) + if err != nil { + return err + } + ccipNode, err := test_env.NewClNode( + []string{env.DockerNetwork.Name}, + pointer.GetString(clNode.ChainlinkImage.Image), + pointer.GetString(clNode.ChainlinkImage.Version), + toml, + env.LogStream, + test_env.WithPgDBOptions( + ctftestenv.WithPostgresImageName(clNode.DBImage), + ctftestenv.WithPostgresImageVersion(clNode.DBTag), + ), + ) + if err != nil { + return err + } + ccipNode.SetTestLogger(t) + env.ClCluster.Nodes = append(env.ClCluster.Nodes, ccipNode) + } + } else { + // if no individual nodes are specified, then deploy the number of nodes specified in the env input with common config + for i := 0; i < noOfNodes; i++ { + toml, _, err := setNodeConfig( + selectedNetworks, + testInputs.EnvInput.NewCLCluster.Common.BaseConfigTOML, + testInputs.EnvInput.NewCLCluster.Common.CommonChainConfigTOML, + testInputs.EnvInput.NewCLCluster.Common.ChainConfigTOMLByChain, + ) + if err != nil { + return err + } + ccipNode, err := test_env.NewClNode( + []string{env.DockerNetwork.Name}, + pointer.GetString(testInputs.EnvInput.NewCLCluster.Common.ChainlinkImage.Image), + pointer.GetString(testInputs.EnvInput.NewCLCluster.Common.ChainlinkImage.Version), + toml, + env.LogStream, + test_env.WithPgDBOptions( + ctftestenv.WithPostgresImageName(testInputs.EnvInput.NewCLCluster.Common.DBImage), + ctftestenv.WithPostgresImageVersion(testInputs.EnvInput.NewCLCluster.Common.DBTag), + ), + ) + if err != nil { + return err + } + ccipNode.SetTestLogger(t) + env.ClCluster.Nodes = append(env.ClCluster.Nodes, ccipNode) + } + } + return env.ClCluster.Start() + } + return env, deployCL +} + +// UpgradeNodes restarts chainlink nodes in the given range with upgrade image +// startIndex and endIndex are inclusive +func UpgradeNodes( + t *testing.T, + lggr *zerolog.Logger, + testInputs *CCIPTestConfig, + ccipEnv *actions.CCIPTestEnv, +) error { + lggr.Info(). + Msg("Upgrading node version") + // if the test is running on local docker + if pointer.GetBool(testInputs.TestGroupInput.LocalCluster) { + env := ccipEnv.LocalCluster + for i, clNode := range env.ClCluster.Nodes { + upgradeImage := pointer.GetString(testInputs.EnvInput.NewCLCluster.Common.ChainlinkUpgradeImage.Image) + upgradeTag := pointer.GetString(testInputs.EnvInput.NewCLCluster.Common.ChainlinkUpgradeImage.Version) + // if individual node upgrade image is provided, use that + if len(testInputs.EnvInput.NewCLCluster.Nodes) > 0 { + if i < len(testInputs.EnvInput.NewCLCluster.Nodes) { + upgradeImage = pointer.GetString(testInputs.EnvInput.NewCLCluster.Nodes[i].ChainlinkUpgradeImage.Image) + upgradeTag = pointer.GetString(testInputs.EnvInput.NewCLCluster.Nodes[i].ChainlinkUpgradeImage.Version) + } + } + if upgradeImage == "" || upgradeTag == "" { + continue + } + err := clNode.UpgradeVersion(upgradeImage, upgradeTag) + if err != nil { + return err + } + } + } else { + // if the test is running on k8s + k8Env := ccipEnv.K8Env + if k8Env == nil { + return errors.New("k8s environment is nil, cannot restart nodes") + } + props, noOfNodesToUpgrade := ChainlinkPropsForUpdate(t, testInputs) + chartName := ccipEnv.CLNodes[0].ChartName + // explicitly set the env var into false to allow manifest update + // if tests are run in remote runner, it might be set to true to disable manifest update + err := os.Setenv(k8config.EnvVarSkipManifestUpdate, "false") + if err != nil { + return err + } + k8Env.Cfg.SkipManifestUpdate = false + lggr.Info(). + Str("Chart Name", chartName). + Interface("Upgrade Details", props). + Msg("Upgrading Chainlink Node") + k8Env, err = k8Env.UpdateHelm(chartName, props) + if err != nil { + return err + } + err = k8Env.RunUpdated(noOfNodesToUpgrade) + // Run the new environment and wait for changes to show + if err != nil { + return err + } + } + return nil +} + +// DeployEnvironments deploys K8 env for CCIP tests. For tests running on simulated geth it deploys - +// 1. two simulated geth network in non-dev mode +// 2. mockserver ( to set mock price feed details) +// 3. chainlink nodes +func DeployEnvironments( + t *testing.T, + envconfig *environment.Config, + testInputs *CCIPTestConfig, +) *environment.Environment { + selectedNetworks := testInputs.SelectedNetworks + testEnvironment := environment.New(envconfig) + numOfTxNodes := 1 + var charts []string + for i, network := range selectedNetworks { + if testInputs.EnvInput.Network.AnvilConfigs != nil { + // if anvilconfig is specified for a network addhelm for anvil + if anvilConfig, exists := testInputs.EnvInput.Network.AnvilConfigs[strings.ToUpper(network.Name)]; exists { + charts = append(charts, foundry.ChartName) + if anvilConfig.BaseFee == nil { + anvilConfig.BaseFee = pointer.ToInt64(1000000) + } + if anvilConfig.BlockGaslimit == nil { + anvilConfig.BlockGaslimit = pointer.ToInt64(100000000) + } + testEnvironment. + AddHelm(foundry.NewVersioned("0.2.1", &foundry.Props{ + NetworkName: network.Name, + Values: map[string]interface{}{ + "fullnameOverride": actions.NetworkName(network.Name), + "image": map[string]interface{}{ + "repository": "ghcr.io/foundry-rs/foundry", + "tag": "nightly-5ac78a9cd4b94dc53d1fe5e0f42372b28b5a7559", + // "tag": "nightly-ea2eff95b5c17edd3ffbdfc6daab5ce5cc80afc0", + }, + "anvil": map[string]interface{}{ + "chainId": fmt.Sprintf("%d", network.ChainID), + "blockTime": anvilConfig.BlockTime, + "forkURL": anvilConfig.URL, + "forkBlockNumber": anvilConfig.BlockNumber, + "forkRetries": anvilConfig.Retries, + "forkTimeout": anvilConfig.Timeout, + "forkComputeUnitsPerSecond": anvilConfig.ComputePerSecond, + "forkNoRateLimit": anvilConfig.RateLimitDisabled, + "blocksToKeepInMemory": anvilConfig.BlocksToKeepInMem, + "blockGasLimit": fmt.Sprintf("%d", pointer.GetInt64(anvilConfig.BlockGaslimit)), + "baseFee": fmt.Sprintf("%d", pointer.GetInt64(anvilConfig.BaseFee)), + }, + "resources": GethResourceProfile, + "cache": map[string]interface{}{ + "capacity": "150Gi", + }, + }, + })) + selectedNetworks[i].Simulated = true + actions.NetworkChart = foundry.ChartName + continue + } + } + + if !network.Simulated { + charts = append(charts, "") + continue + } + charts = append(charts, strings.ReplaceAll(strings.ToLower(network.Name), " ", "-")) + testEnvironment. + AddHelm(reorg.New(&reorg.Props{ + NetworkName: network.Name, + NetworkType: "simulated-geth-non-dev", + Values: map[string]interface{}{ + "geth": map[string]interface{}{ + "genesis": map[string]interface{}{ + "networkId": fmt.Sprint(network.ChainID), + }, + "tx": map[string]interface{}{ + "replicas": strconv.Itoa(numOfTxNodes), + "resources": testInputs.GethResourceProfile, + }, + "miner": map[string]interface{}{ + "replicas": "0", + "resources": testInputs.GethResourceProfile, + }, + }, + "bootnode": map[string]interface{}{ + "replicas": "1", + }, + }, + })) + } + if pointer.GetBool(testInputs.TestGroupInput.USDCMockDeployment) || + pointer.GetBool(testInputs.TestGroupInput.TokenConfig.WithPipeline) { + testEnvironment. + AddHelm(mockservercfg.New(nil)). + AddHelm(mockserver.New(nil)) + } + err := testEnvironment.Run() + require.NoError(t, err) + + if testEnvironment.WillUseRemoteRunner() { + return testEnvironment + } + urlFinder := func(network blockchain.EVMNetwork, chart string) ([]string, []string) { + if !network.Simulated { + return network.URLs, network.HTTPURLs + } + networkName := actions.NetworkName(network.Name) + var internalWsURLs, internalHttpURLs []string + switch chart { + case foundry.ChartName: + internalWsURLs = append(internalWsURLs, fmt.Sprintf("ws://%s:8545", networkName)) + internalHttpURLs = append(internalHttpURLs, fmt.Sprintf("http://%s:8545", networkName)) + case networkName: + for i := 0; i < numOfTxNodes; i++ { + internalWsURLs = append(internalWsURLs, fmt.Sprintf("ws://%s-ethereum-geth:8546", networkName)) + internalHttpURLs = append(internalHttpURLs, fmt.Sprintf("http://%s-ethereum-geth:8544", networkName)) + } + default: + return network.URLs, network.HTTPURLs + } + + return internalWsURLs, internalHttpURLs + } + var nets []blockchain.EVMNetwork + for i := range selectedNetworks { + nets = append(nets, selectedNetworks[i]) + nets[i].URLs, nets[i].HTTPURLs = urlFinder(selectedNetworks[i], charts[i]) + } + + err = testEnvironment. + AddHelm(ChainlinkChart(t, testInputs, nets)). + Run() + require.NoError(t, err) + return testEnvironment +} diff --git a/integration-tests/ccip-tests/types/config/node/core.go b/integration-tests/ccip-tests/types/config/node/core.go new file mode 100644 index 0000000000..eb12598f94 --- /dev/null +++ b/integration-tests/ccip-tests/types/config/node/core.go @@ -0,0 +1,67 @@ +package node + +import ( + "bytes" + "fmt" + "math/big" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + + "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" + itutils "github.com/smartcontractkit/chainlink/integration-tests/utils" + evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" +) + +func NewConfigFromToml(tomlConfig []byte, opts ...node.NodeConfigOpt) (*chainlink.Config, error) { + var cfg chainlink.Config + err := config.DecodeTOML(bytes.NewReader(tomlConfig), &cfg) + if err != nil { + return nil, err + } + for _, opt := range opts { + opt(&cfg) + } + return &cfg, nil +} + +func WithPrivateEVMs(networks []blockchain.EVMNetwork, commonChainConfig *evmcfg.Chain, chainSpecificConfig map[int64]evmcfg.Chain) node.NodeConfigOpt { + var evmConfigs []*evmcfg.EVMConfig + for _, network := range networks { + var evmNodes []*evmcfg.Node + for i := range network.URLs { + evmNodes = append(evmNodes, &evmcfg.Node{ + Name: ptr.Ptr(fmt.Sprintf("%s-%d", network.Name, i)), + WSURL: itutils.MustURL(network.URLs[i]), + HTTPURL: itutils.MustURL(network.HTTPURLs[i]), + }) + } + evmConfig := &evmcfg.EVMConfig{ + ChainID: ubig.New(big.NewInt(network.ChainID)), + Nodes: evmNodes, + Chain: evmcfg.Chain{}, + } + if commonChainConfig != nil { + evmConfig.Chain = *commonChainConfig + } + if chainSpecificConfig == nil { + if overriddenChainCfg, ok := chainSpecificConfig[network.ChainID]; ok { + evmConfig.Chain = overriddenChainCfg + } + } + if evmConfig.Chain.FinalityDepth == nil && network.FinalityDepth > 0 { + evmConfig.Chain.FinalityDepth = ptr.Ptr(uint32(network.FinalityDepth)) + } + if evmConfig.Chain.FinalityTagEnabled == nil && network.FinalityTag { + evmConfig.Chain.FinalityTagEnabled = ptr.Ptr(network.FinalityTag) + } + evmConfigs = append(evmConfigs, evmConfig) + } + return func(c *chainlink.Config) { + c.EVM = evmConfigs + } +} diff --git a/integration-tests/ccip-tests/utils/common.go b/integration-tests/ccip-tests/utils/common.go new file mode 100644 index 0000000000..afa8158e45 --- /dev/null +++ b/integration-tests/ccip-tests/utils/common.go @@ -0,0 +1,32 @@ +package utils + +import ( + "path/filepath" + "runtime" + "sync" +) + +func ProjectRoot() string { + _, b, _, _ := runtime.Caller(0) + return filepath.Join(filepath.Dir(b), "/..") +} + +// DeleteNilEntriesFromMap checks for nil entry in map, store all not-nil entries to another map and deallocates previous map +// Deleting keys from a map actually does not delete the key, It just sets the corresponding value to nil. +func DeleteNilEntriesFromMap(inputMap *sync.Map) *sync.Map { + newMap := &sync.Map{} + foundNil := false + inputMap.Range(func(key, value any) bool { + if value != nil { + newMap.Store(key, value) + } + if value == nil { + foundNil = true + } + return true + }) + if foundNil { + runtime.GC() + } + return newMap +} diff --git a/integration-tests/ccip-tests/utils/fileutil.go b/integration-tests/ccip-tests/utils/fileutil.go new file mode 100644 index 0000000000..43e048e1f6 --- /dev/null +++ b/integration-tests/ccip-tests/utils/fileutil.go @@ -0,0 +1,63 @@ +package utils + +import ( + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/rs/zerolog/log" +) + +// FilesWithRegex returns all filepaths under root folder matching with regex pattern +func FilesWithRegex(root, pattern string) ([]string, error) { + r, err := regexp.Compile(pattern) + if err != nil { + return nil, err + } + var filenames []string + err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + // Check if the file matches the regex pattern + if !info.IsDir() && r.MatchString(info.Name()) { + filenames = append(filenames, path) + } + + return nil + }) + return filenames, err +} + +func FileNameFromPath(path string) string { + if !strings.Contains(path, "/") { + return path + } + return strings.Split(path, "/")[len(strings.Split(path, "/"))-1] +} + +// FirstFileFromMatchingPath formats the given filepathWithPattern with actual file path +// if filepathWithPattern is provided with a regex expression it returns the first filepath +// matching with the regex. +// if there is no regex provided in filepathWithPattern it just returns the provided filepath +func FirstFileFromMatchingPath(filepathWithPattern string) (string, error) { + filename := FileNameFromPath(filepathWithPattern) + if strings.Contains(filepathWithPattern, "/") { + rootFolder := strings.Split(filepathWithPattern, filename)[0] + allFiles, err := FilesWithRegex(rootFolder, filename) + if err != nil { + return "", fmt.Errorf("error trying to find file %s:%w", filepathWithPattern, err) + } + if len(allFiles) == 0 { + return "", fmt.Errorf("error trying to find file %s", filepathWithPattern) + } + if len(allFiles) > 1 { + log.Warn().Str("path", filepathWithPattern).Msg("more than one contract config files found in location, using the first one") + } + return allFiles[0], nil + } + return filepathWithPattern, nil +} diff --git a/integration-tests/go.mod b/integration-tests/go.mod index a7783f7daa..16482effa4 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -6,6 +6,9 @@ go 1.22.5 replace github.com/smartcontractkit/chainlink/v2 => ../ require ( + dario.cat/mergo v1.0.0 + github.com/AlekSi/pointer v1.1.0 + github.com/Masterminds/semver/v3 v3.2.1 github.com/avast/retry-go/v4 v4.6.0 github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f @@ -22,11 +25,13 @@ require ( github.com/onsi/gomega v1.33.1 github.com/pelletier/go-toml/v2 v2.2.2 github.com/pkg/errors v0.9.1 + github.com/prometheus/common v0.55.0 github.com/rs/zerolog v1.31.0 github.com/scylladb/go-reflectx v1.0.1 github.com/segmentio/ksuid v1.0.4 github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 + github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d github.com/smartcontractkit/chainlink-testing-framework v1.34.2 @@ -41,7 +46,11 @@ require ( github.com/test-go/testify v1.1.4 github.com/testcontainers/testcontainers-go v0.28.0 github.com/umbracle/ethgo v0.1.3 + go.uber.org/atomic v1.11.0 + go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 + golang.org/x/crypto v0.25.0 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/sync v0.7.0 golang.org/x/text v0.16.0 gopkg.in/guregu/null.v4 v4.0.0 @@ -60,7 +69,6 @@ require ( cosmossdk.io/depinject v1.0.0-alpha.3 // indirect cosmossdk.io/errors v1.0.0 // indirect cosmossdk.io/math v1.0.1 // indirect - dario.cat/mergo v1.0.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect @@ -78,7 +86,6 @@ require ( github.com/K-Phoen/sdk v0.12.4 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.11.4 // indirect @@ -270,6 +277,7 @@ require ( github.com/hashicorp/serf v0.10.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect + github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.4 // indirect github.com/huandu/skiplist v1.2.0 // indirect @@ -358,7 +366,6 @@ require ( github.com/prometheus/alertmanager v0.26.0 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 // indirect github.com/prometheus/procfs v0.15.1 // indirect @@ -376,7 +383,6 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect @@ -442,14 +448,10 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect - go.uber.org/atomic v1.11.0 // indirect go.uber.org/goleak v1.3.0 // indirect - go.uber.org/multierr v1.11.0 // indirect go.uber.org/ratelimit v0.3.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.19.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 411b3ddd46..99de85d877 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1484,8 +1484,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCqR1LNS7aI3jT0V+xGrg= -github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= +github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1WonwhVOPtOStpqTmLC4E= +github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 4a15b97abf..0a65245f43 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -370,7 +370,7 @@ require ( github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chain-selectors v1.0.10 // indirect + github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 625da73ba0..22286e5933 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1466,8 +1466,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCqR1LNS7aI3jT0V+xGrg= -github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= +github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1WonwhVOPtOStpqTmLC4E= +github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= From 83e576f6bf222296a47f359fe620840833d626c0 Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:11:28 -0400 Subject: [PATCH 088/432] Add slack alerts for failing crib integrations (#14122) * Add slack alerts for failing crib integrations * Bump version to action with fix --- .github/workflows/crib-integration-test.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/crib-integration-test.yml b/.github/workflows/crib-integration-test.yml index a67ac641bf..0dda07f285 100644 --- a/.github/workflows/crib-integration-test.yml +++ b/.github/workflows/crib-integration-test.yml @@ -73,7 +73,7 @@ jobs: echo $GITHUB_WORKSPACE - name: Deploy and validate CRIB Environment for Core - uses: smartcontractkit/.github/actions/crib-deploy-environment@c0b38e6c40d72d01b8d2f24f92623a2538b3dedb # crib-deploy-environment@0.5.0 + uses: smartcontractkit/.github/actions/crib-deploy-environment@9a4954089045a765eca4bac68f396b2df5a5ea25 # crib-deploy-environment@0.7.1 id: deploy-crib with: github-token: ${{ steps.token.outputs.access-token }} @@ -85,6 +85,7 @@ jobs: ingress-base-domain: ${{ secrets.INGRESS_BASE_DOMAIN_STAGE }} k8s-cluster-name: ${{ secrets.AWS_K8S_CLUSTER_NAME_STAGE }} devspace-profiles: "local-dev-simulated-core-ocr1" + crib-alert-slack-webhook: ${{ secrets.CRIB_ALERT_SLACK_WEBHOOK }} - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Setup go uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 @@ -99,7 +100,7 @@ jobs: CRIB_NODES: 5 GAP_URL: ${{ secrets.GAP_URL }} SETH_LOG_LEVEL: info -# RESTY_DEBUG: true + # RESTY_DEBUG: true TEST_PERSISTENCE: true run: |- go test -v -run TestCRIB @@ -108,4 +109,4 @@ jobs: if: always() && steps.deploy-crib.outputs.devspace-namespace != '' uses: smartcontractkit/.github/actions/crib-purge-environment@c0b38e6c40d72d01b8d2f24f92623a2538b3dedb # crib-purge-environment@0.1.0 with: - namespace: ${{ steps.deploy-crib.outputs.devspace-namespace }} \ No newline at end of file + namespace: ${{ steps.deploy-crib.outputs.devspace-namespace }} From 3f0fad643d554d2445273a67f58974cb6a785ec4 Mon Sep 17 00:00:00 2001 From: Juan Farber Date: Wed, 14 Aug 2024 16:52:49 -0300 Subject: [PATCH 089/432] [BCI-3863] - Use filtered logs in eventBinding GetLatestValue instead of manual filtering (#14096) * Use filtered logs in eventBinding GetLatestValue instead of manual filtering * handle one filter simple expression case for topic filters * and instead of or for matching all topic filters conditions * add changeset * nit comment to reduce createTopicFilters func * add address to query name in GetLatestValue and QueryKey * key not necessary as we are using logpoller filters --- .changeset/early-glasses-rhyme.md | 5 ++ core/services/relay/evm/event_binding.go | 67 ++++++++++-------------- 2 files changed, 32 insertions(+), 40 deletions(-) create mode 100644 .changeset/early-glasses-rhyme.md diff --git a/.changeset/early-glasses-rhyme.md b/.changeset/early-glasses-rhyme.md new file mode 100644 index 0000000000..aa35bf897e --- /dev/null +++ b/.changeset/early-glasses-rhyme.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +use FilteredLogs in EventBinding GetLatestValue instead of manual filtering. #internal diff --git a/core/services/relay/evm/event_binding.go b/core/services/relay/evm/event_binding.go index 97ddc99a10..7b62d862b3 100644 --- a/core/services/relay/evm/event_binding.go +++ b/core/services/relay/evm/event_binding.go @@ -169,7 +169,7 @@ func (e *eventBinding) QueryKey(ctx context.Context, filter query.KeyFilter, lim } remapped.Expressions = append(defaultExpressions, remapped.Expressions...) - logs, err := e.lp.FilteredLogs(ctx, remapped, limitAndSort, e.contractName+"-"+e.eventName) + logs, err := e.lp.FilteredLogs(ctx, remapped, limitAndSort, e.contractName+"-"+e.address.String()+"-"+e.eventName) if err != nil { return nil, err } @@ -227,32 +227,41 @@ func (e *eventBinding) getLatestValueWithFilters( return err } - fai := filtersAndIndices[0] - remainingFilters := filtersAndIndices[1:] - - logs, err := e.lp.IndexedLogs(ctx, e.hash, e.address, 1, []common.Hash{fai}, confs) + // Create limiter and filter for the query. + limiter := query.NewLimitAndSort(query.CountLimit(1), query.NewSortBySequence(query.Desc)) + filter, err := query.Where( + "", + logpoller.NewAddressFilter(e.address), + logpoller.NewEventSigFilter(e.hash), + logpoller.NewConfirmationsFilter(confs), + createTopicFilters(filtersAndIndices), + ) if err != nil { return wrapInternalErr(err) } - // TODO Use filtered logs here BCF-3316 - // TODO: there should be a better way to ask log poller to filter these - // First, you should be able to ask for as many topics to match - // Second, you should be able to get the latest only - var logToUse *logpoller.Log - for _, log := range logs { - tmp := log - if compareLogs(&tmp, logToUse) > 0 && matchesRemainingFilters(&tmp, remainingFilters) { - // copy so that it's not pointing to the changing variable - logToUse = &tmp - } + // Gets the latest log that matches the filter and limiter. + logs, err := e.lp.FilteredLogs(ctx, filter, limiter, e.contractName+"-"+e.address.String()+"-"+e.eventName) + if err != nil { + return wrapInternalErr(err) } - if logToUse == nil { + if len(logs) == 0 { return fmt.Errorf("%w: no events found", commontypes.ErrNotFound) } - return e.decodeLog(ctx, logToUse, into) + return e.decodeLog(ctx, &logs[0], into) +} + +func createTopicFilters(filtersAndIndices []common.Hash) query.Expression { + var expressions []query.Expression + for topicID, fai := range filtersAndIndices { + // first topic index is 1-based, so we add 1. + expressions = append(expressions, logpoller.NewEventByTopicFilter( + uint64(topicID+1), []primitives.ValueComparator{{Value: fai.Hex(), Operator: primitives.Eq}}, + )) + } + return query.And(expressions...) } // convertToOffChainType creates a struct based on contract abi with applied codec modifiers. @@ -270,28 +279,6 @@ func (e *eventBinding) convertToOffChainType(params any) (any, error) { return offChain, nil } -func compareLogs(log, use *logpoller.Log) int64 { - if use == nil { - return 1 - } - - if log.BlockNumber != use.BlockNumber { - return log.BlockNumber - use.BlockNumber - } - - return log.LogIndex - use.LogIndex -} - -func matchesRemainingFilters(log *logpoller.Log, filters []common.Hash) bool { - for i, rfai := range filters { - if !reflect.DeepEqual(rfai[:], log.Topics[i+2]) { - return false - } - } - - return true -} - // encodeParams accepts nativeParams and encodes them to match onchain topics. func (e *eventBinding) encodeParams(nativeParams reflect.Value) ([]common.Hash, error) { for nativeParams.Kind() == reflect.Pointer { From aa4e981c8f51692ae19f57569260171736a3e4d9 Mon Sep 17 00:00:00 2001 From: Cedric Date: Wed, 14 Aug 2024 22:22:28 +0100 Subject: [PATCH 090/432] [KS-426] Remove panic from CapabilityType type (#14095) * [chore] Remove panic from CapabilityType type * Update common * Update common * Add enum for CapabilityType --------- Co-authored-by: Vyzaldy Sanchez --- .changeset/fast-insects-shout.md | 5 +++++ .../keystone_contracts_setup.go | 19 +++++++++++++------ core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- core/services/registrysyncer/syncer.go | 3 +-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 11 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 .changeset/fast-insects-shout.md diff --git a/.changeset/fast-insects-shout.md b/.changeset/fast-insects-shout.md new file mode 100644 index 0000000000..847fc8d057 --- /dev/null +++ b/.changeset/fast-insects-shout.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#internal Change CapabilityType to string; remove possiblity of a panic diff --git a/core/capabilities/integration_tests/keystone_contracts_setup.go b/core/capabilities/integration_tests/keystone_contracts_setup.go index 38925cb0a3..b138b8f812 100644 --- a/core/capabilities/integration_tests/keystone_contracts_setup.go +++ b/core/capabilities/integration_tests/keystone_contracts_setup.go @@ -26,7 +26,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/values" - "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" @@ -40,6 +39,13 @@ import ( kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) +const ( + CapabilityTypeTrigger = 0 + CapabilityTypeAction = 1 + CapabilityTypeConsensus = 2 + CapabilityTypeTarget = 3 +) + type peer struct { PeerID string Signer string @@ -102,15 +108,16 @@ func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workfl streamsTrigger := kcr.CapabilitiesRegistryCapability{ LabelledName: "streams-trigger", Version: "1.0.0", - CapabilityType: uint8(capabilities.CapabilityTypeTrigger), + CapabilityType: CapabilityTypeTrigger, } sid, err := reg.GetHashedCapabilityId(&bind.CallOpts{}, streamsTrigger.LabelledName, streamsTrigger.Version) require.NoError(t, err) writeChain := kcr.CapabilitiesRegistryCapability{ - LabelledName: "write_geth-testnet", - Version: "1.0.0", - CapabilityType: uint8(capabilities.CapabilityTypeTarget), + LabelledName: "write_geth-testnet", + Version: "1.0.0", + + CapabilityType: CapabilityTypeTarget, } wid, err := reg.GetHashedCapabilityId(&bind.CallOpts{}, writeChain.LabelledName, writeChain.Version) if err != nil { @@ -120,7 +127,7 @@ func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workfl ocr := kcr.CapabilitiesRegistryCapability{ LabelledName: "offchain_reporting", Version: "1.0.0", - CapabilityType: uint8(capabilities.CapabilityTypeConsensus), + CapabilityType: CapabilityTypeConsensus, } ocrid, err := reg.GetHashedCapabilityId(&bind.CallOpts{}, ocr.LabelledName, ocr.Version) require.NoError(t, err) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 68b54881fd..31b07472c5 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index c3883a7af6..ccb508b82e 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1186,8 +1186,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d h1:ATGkySP4ATI2kZ+d9zzNi93iaH0KcDGB8AewI8TJkiI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad h1:QmXA8j7f1gNK52dRuW78ZAbzTRlv62fRZQdp0aYFJmc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/core/services/registrysyncer/syncer.go b/core/services/registrysyncer/syncer.go index 83f77e46d3..a83e0102af 100644 --- a/core/services/registrysyncer/syncer.go +++ b/core/services/registrysyncer/syncer.go @@ -262,8 +262,7 @@ func toCapabilityType(capabilityType uint8) capabilities.CapabilityType { case 3: return capabilities.CapabilityTypeTarget default: - // Not found - return capabilities.CapabilityType(-1) + return capabilities.CapabilityTypeUnknown } } diff --git a/go.mod b/go.mod index 5c53a04cf2..66bf6ad606 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index 7e91b62afe..f5650b82b3 100644 --- a/go.sum +++ b/go.sum @@ -1141,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d h1:ATGkySP4ATI2kZ+d9zzNi93iaH0KcDGB8AewI8TJkiI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad h1:QmXA8j7f1gNK52dRuW78ZAbzTRlv62fRZQdp0aYFJmc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 16482effa4..bf826c136f 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -33,7 +33,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad github.com/smartcontractkit/chainlink-testing-framework v1.34.2 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 99de85d877..3c48904828 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1490,8 +1490,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d h1:ATGkySP4ATI2kZ+d9zzNi93iaH0KcDGB8AewI8TJkiI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad h1:QmXA8j7f1gNK52dRuW78ZAbzTRlv62fRZQdp0aYFJmc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 0a65245f43..ebb17f3031 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.31.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad github.com/smartcontractkit/chainlink-testing-framework v1.34.2 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 22286e5933..ae966241ad 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1472,8 +1472,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d h1:ATGkySP4ATI2kZ+d9zzNi93iaH0KcDGB8AewI8TJkiI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240808143317-6b16fc28887d/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad h1:QmXA8j7f1gNK52dRuW78ZAbzTRlv62fRZQdp0aYFJmc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= From 5e99bdb764171f584df1fc6e10495c8ec0a3bb63 Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Wed, 14 Aug 2024 19:40:40 -0500 Subject: [PATCH 091/432] Handle terminally stuck transactions on send (#14127) * Added error classification on send for terminally stuck transactions * Added changeset * Addressed feedback and fixed linting * Restructured broadcaster code for fatal and terminally stuck case * Reduced log levels for terminally stuck transactions --- .changeset/yellow-cougars-act.md | 5 +++ common/txmgr/broadcaster.go | 14 +++--- common/txmgr/confirmer.go | 17 +++++++- core/chains/evm/client/errors.go | 5 +++ core/chains/evm/client/errors_test.go | 22 +++++++++- core/chains/evm/txmgr/broadcaster_test.go | 19 +++++++++ core/chains/evm/txmgr/confirmer_test.go | 52 +++++++++++++++++++++++ core/chains/evm/txmgr/txmgr_test.go | 22 ++++++++++ 8 files changed, 146 insertions(+), 10 deletions(-) create mode 100644 .changeset/yellow-cougars-act.md diff --git a/.changeset/yellow-cougars-act.md b/.changeset/yellow-cougars-act.md new file mode 100644 index 0000000000..61ed62607a --- /dev/null +++ b/.changeset/yellow-cougars-act.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Added client error classification for terminally stuck transactions in the TXM #internal diff --git a/common/txmgr/broadcaster.go b/common/txmgr/broadcaster.go index b2fb1dabff..be3d3ca2f6 100644 --- a/common/txmgr/broadcaster.go +++ b/common/txmgr/broadcaster.go @@ -493,16 +493,16 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand errType, err = eb.validateOnChainSequence(ctx, lgr, errType, err, etx, retryCount) } - if errType != client.Fatal { - etx.InitialBroadcastAt = &initialBroadcastAt - etx.BroadcastAt = &initialBroadcastAt - } - - switch errType { - case client.Fatal: + if errType == client.Fatal || errType == client.TerminallyStuck { eb.SvcErrBuffer.Append(err) etx.Error = null.StringFrom(err.Error()) return eb.saveFatallyErroredTransaction(lgr, &etx), true + } + + etx.InitialBroadcastAt = &initialBroadcastAt + etx.BroadcastAt = &initialBroadcastAt + + switch errType { case client.TransactionAlreadyKnown: fallthrough case client.Successful: diff --git a/common/txmgr/confirmer.go b/common/txmgr/confirmer.go index 3b42119178..d67bd45122 100644 --- a/common/txmgr/confirmer.go +++ b/common/txmgr/confirmer.go @@ -491,7 +491,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Pro go func(tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) { defer wg.Done() lggr := tx.GetLogger(ec.lggr) - // Create an purge attempt for tx + // Create a purge attempt for tx purgeAttempt, err := ec.TxAttemptBuilder.NewPurgeTxAttempt(ctx, tx, lggr) if err != nil { errMu.Lock() @@ -999,6 +999,21 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) han ec.SvcErrBuffer.Append(sendError) // This will loop continuously on every new head so it must be handled manually by the node operator! return ec.txStore.DeleteInProgressAttempt(ctx, attempt) + case client.TerminallyStuck: + // A transaction could broadcast successfully but then be considered terminally stuck on another attempt + // Even though the transaction can succeed under different circumstances, we want to purge this transaction as soon as we get this error + lggr.Warnw("terminally stuck transaction detected", "err", sendError.Error()) + ec.SvcErrBuffer.Append(sendError) + // Create a purge attempt for tx + purgeAttempt, err := ec.TxAttemptBuilder.NewPurgeTxAttempt(ctx, etx, lggr) + if err != nil { + return fmt.Errorf("NewPurgeTxAttempt failed: %w", err) + } + // Replace the in progress attempt with the purge attempt + if err := ec.txStore.SaveReplacementInProgressAttempt(ctx, attempt, &purgeAttempt); err != nil { + return fmt.Errorf("saveReplacementInProgressAttempt failed: %w", err) + } + return ec.handleInProgressAttempt(ctx, lggr, etx, purgeAttempt, blockHeight) case client.TransactionAlreadyKnown: // Sequence too low indicated that a transaction at this sequence was confirmed already. // Mark confirmed_missing_receipt and wait for the next cycle to try to get a receipt diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index 83c2d9566f..e7fff8d0db 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -596,6 +596,11 @@ func ClassifySendError(err error, clientErrors config.ClientErrors, lggr logger. ) return commonclient.ExceedsMaxFee } + if sendError.IsTerminallyStuckConfigError(configErrors) { + lggr.Warnw("Transaction that would have been terminally stuck in the mempool detected on send. Marking as fatal error.", "err", sendError, "etx", tx) + // Attempt is thrown away in this case; we don't need it since it never got accepted by a node + return commonclient.TerminallyStuck + } lggr.Criticalw("Unknown error encountered when sending transaction", "err", err, "etx", tx) return commonclient.Unknown } diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index 00bc1a9a5b..32a1ba2bf3 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -290,7 +290,7 @@ func Test_Eth_Errors(t *testing.T) { }) t.Run("Metis gas price errors", func(t *testing.T) { - err := evmclient.NewSendErrorS("primary websocket (wss://ws-mainnet.metis.io) call failed: gas price too low: 18000000000 wei, use at least tx.gasPrice = 19500000000 wei") + err = evmclient.NewSendErrorS("primary websocket (wss://ws-mainnet.metis.io) call failed: gas price too low: 18000000000 wei, use at least tx.gasPrice = 19500000000 wei") assert.True(t, err.L2FeeTooLow(clientErrors)) err = newSendErrorWrapped("primary websocket (wss://ws-mainnet.metis.io) call failed: gas price too low: 18000000000 wei, use at least tx.gasPrice = 19500000000 wei") assert.True(t, err.L2FeeTooLow(clientErrors)) @@ -302,7 +302,7 @@ func Test_Eth_Errors(t *testing.T) { }) t.Run("moonriver errors", func(t *testing.T) { - err := evmclient.NewSendErrorS("primary http (http://***REDACTED***:9933) call failed: submit transaction to pool failed: Pool(Stale)") + err = evmclient.NewSendErrorS("primary http (http://***REDACTED***:9933) call failed: submit transaction to pool failed: Pool(Stale)") assert.True(t, err.IsNonceTooLowError(clientErrors)) assert.False(t, err.IsTransactionAlreadyInMempool(clientErrors)) assert.False(t, err.Fatal(clientErrors)) @@ -311,6 +311,24 @@ func Test_Eth_Errors(t *testing.T) { assert.False(t, err.IsNonceTooLowError(clientErrors)) assert.False(t, err.Fatal(clientErrors)) }) + + t.Run("IsTerminallyStuck", func(t *testing.T) { + tests := []errorCase{ + {"failed to add tx to the pool: not enough step counters to continue the execution", true, "zkEVM"}, + {"failed to add tx to the pool: not enough step counters to continue the execution", true, "Xlayer"}, + {"failed to add tx to the pool: not enough keccak counters to continue the execution", true, "zkEVM"}, + {"failed to add tx to the pool: not enough keccak counters to continue the execution", true, "Xlayer"}, + } + + for _, test := range tests { + t.Run(test.network, func(t *testing.T) { + err = evmclient.NewSendErrorS(test.message) + assert.Equal(t, err.IsTerminallyStuckConfigError(clientErrors), test.expect) + err = newSendErrorWrapped(test.message) + assert.Equal(t, err.IsTerminallyStuckConfigError(clientErrors), test.expect) + }) + } + }) } func Test_Eth_Errors_Fatal(t *testing.T) { diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 537875a647..c6c342973b 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -521,6 +521,25 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { assert.True(t, ethTx.Error.Valid) assert.Equal(t, "transaction reverted during simulation: json-rpc error { Code = 42, Message = 'oh no, it reverted', Data = 'KqYi' }", ethTx.Error.String) }) + + t.Run("terminally stuck transaction is marked as fatal", func(t *testing.T) { + terminallyStuckError := "failed to add tx to the pool: not enough step counters to continue the execution" + etx := mustCreateUnstartedTx(t, txStore, fromAddress, toAddress, []byte{42, 42, 0}, gasLimit, big.Int(assets.NewEthValue(243)), testutils.FixtureChainID) + ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { + return tx.Nonce() == uint64(346) && tx.Value().Cmp(big.NewInt(243)) == 0 + }), fromAddress).Return(commonclient.Fatal, errors.New(terminallyStuckError)).Once() + + // Start processing unstarted transactions + retryable, err := eb.ProcessUnstartedTxs(tests.Context(t), fromAddress) + assert.NoError(t, err) + assert.False(t, retryable) + + dbTx, err := txStore.FindTxWithAttempts(ctx, etx.ID) + require.NoError(t, err) + assert.Equal(t, txmgrcommon.TxFatalError, dbTx.State) + assert.True(t, dbTx.Error.Valid) + assert.Equal(t, terminallyStuckError, dbTx.Error.String) + }) }) } diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index cce6dc8fc6..eaf79b6aba 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -2673,6 +2673,58 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WhenOutOfEth(t *testing.T) { }) } +func TestEthConfirmer_RebroadcastWhereNecessary_TerminallyStuckError(t *testing.T) { + t.Parallel() + + db := pgtest.NewSqlxDB(t) + cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.EVM[0].GasEstimator.PriceMax = assets.GWei(500) + }) + txStore := cltest.NewTestTxStore(t, db) + ctx := tests.Context(t) + + ethClient := testutils.NewEthClientMockWithDefaultChain(t) + ethKeyStore := cltest.NewKeyStore(t, db).Eth() + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + + evmcfg := evmtest.NewChainScopedConfig(t, cfg) + + // Use a mock keystore for this test + ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + currentHead := int64(30) + oldEnough := int64(19) + nonce := int64(0) + terminallyStuckError := "failed to add tx to the pool: not enough step counters to continue the execution" + + t.Run("terminally stuck transaction replaced with purge attempt", func(t *testing.T) { + originalBroadcastAt := time.Unix(1616509100, 0) + etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress, originalBroadcastAt) + nonce++ + attempt1_1 := etx.TxAttempts[0] + var dbAttempt txmgr.DbEthTxAttempt + require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1_1.ID)) + + // Return terminally stuck error on first rebroadcast + ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { + return tx.Nonce() == uint64(*etx.Sequence) + }), fromAddress).Return(commonclient.TerminallyStuck, errors.New(terminallyStuckError)).Once() + // Return successful for purge attempt + ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { + return tx.Nonce() == uint64(*etx.Sequence) + }), fromAddress).Return(commonclient.Successful, nil).Once() + + // Start processing transactions for rebroadcast + require.NoError(t, ec.RebroadcastWhereNecessary(tests.Context(t), currentHead)) + var err error + etx, err = txStore.FindTxWithAttempts(ctx, etx.ID) + require.NoError(t, err) + + require.Len(t, etx.TxAttempts, 2) + purgeAttempt := etx.TxAttempts[0] + require.True(t, purgeAttempt.IsPurgeAttempt) + }) +} + func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { t.Parallel() diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index 3d52e6eb4f..86bf5fcc4b 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -786,6 +786,7 @@ func TestTxm_GetTransactionStatus(t *testing.T) { t.Run("returns fatal for fatal error state with terminally stuck error", func(t *testing.T) { idempotencyKey := uuid.New().String() _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + // Test the internal terminally stuck error returns Fatal nonce := evmtypes.Nonce(0) broadcast := time.Now() tx := &txmgr.Tx{ @@ -804,6 +805,27 @@ func TestTxm_GetTransactionStatus(t *testing.T) { state, err := txm.GetTransactionStatus(ctx, idempotencyKey) require.Equal(t, commontypes.Fatal, state) require.Error(t, err, evmclient.TerminallyStuckMsg) + + // Test a terminally stuck client error returns Fatal + nonce = evmtypes.Nonce(1) + idempotencyKey = uuid.New().String() + terminallyStuckClientError := "failed to add tx to the pool: not enough step counters to continue the execution" + tx = &txmgr.Tx{ + Sequence: &nonce, + IdempotencyKey: &idempotencyKey, + FromAddress: fromAddress, + EncodedPayload: []byte{1, 2, 3}, + FeeLimit: feeLimit, + State: txmgrcommon.TxFatalError, + Error: null.NewString(terminallyStuckClientError, true), + BroadcastAt: &broadcast, + InitialBroadcastAt: &broadcast, + } + err = txStore.InsertTx(ctx, tx) + require.NoError(t, err) + state, err = txm.GetTransactionStatus(ctx, idempotencyKey) + require.Equal(t, commontypes.Fatal, state) + require.Error(t, err, evmclient.TerminallyStuckMsg) }) t.Run("returns failed for fatal error state with other error", func(t *testing.T) { From e2a884152293040ab1fb6d5312232b64286afa64 Mon Sep 17 00:00:00 2001 From: frank zhu Date: Wed, 14 Aug 2024 23:55:32 -0500 Subject: [PATCH 092/432] refactor: use only goreleaser to build unsigned chainlink images in one workflow (#14034) * refactor: use only goreleaser to build unsigned chainlink images in one workflow * fix: use branches-ignore filter instead * rename and switch runner * temp switch back name because of env protection rule * back to use the refactored name * update goreleaser yaml * add new docker inputs, rename IMAGE_NAME, add goreleaser build-sign-publish workflow * add output image name and digest to github summary * refactor gha workflow names and add output image name and digest to build-develop * remove unnecessary outputs * add a git_ref validation job * temp delete workflows for easier testing * add if conditional to validate step * fix metric name and add debug log * update docker registry * no goreleaser output since we don't use the goreleaser/action * remove debug log and use bash shell * fix formatting * remove root images from goreleaser yaml * use custom setup-go * fix typo * use tee instead * add back setup-go and refactor output summary step * update with new filename and workflow trigger * fix docker registry input * remove role-duration input * change conditional * revert temp gha workflow delete commit * sync with origin develop * refactor trigger based on push and pr label * fix install remote plugins bug include * add new docker builds for plugins and update dockerfile * add goreleaser --split to gha and refactor action_utils script * fix add shell * fix metrics job name and publish docker manifest files * fix image_templates goreleaser * fix check artifacts.json and metrics name * fix if not end * ls -al dist * add --single-target flag and split checksum * remove split in checksum * remove --single-target and update output artifact.json path * cat artifacts.json * use ubuntu-latest runner * update build-publish workflow output summary step * build on every pr - conditional publish | add workflow_dispatch trigger * add workflow_dispatch conditional build-publish * fix typo * fix typo * use ubuntu-20.04 runner * fix conditional * add comment --- .../goreleaser-build-sign-publish/action.yml | 41 ++++-- .../action_utils | 32 +++-- .../workflows/build-publish-develop-pr.yml | 119 ++++++++++++++++++ .github/workflows/build-publish-develop.yml | 69 ---------- .github/workflows/build-publish-pr.yml | 66 ---------- .github/workflows/build-publish.yml | 65 +++++++++- .github/workflows/build.yml | 51 -------- .../goreleaser-build-publish-develop.yml | 52 -------- .goreleaser.develop.yaml | 65 ++++++---- core/chainlink.goreleaser.Dockerfile | 5 +- tools/bin/goreleaser_utils | 8 +- 11 files changed, 283 insertions(+), 290 deletions(-) create mode 100644 .github/workflows/build-publish-develop-pr.yml delete mode 100644 .github/workflows/build-publish-develop.yml delete mode 100644 .github/workflows/build-publish-pr.yml delete mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/goreleaser-build-publish-develop.yml diff --git a/.github/actions/goreleaser-build-sign-publish/action.yml b/.github/actions/goreleaser-build-sign-publish/action.yml index f4b2111bea..c279c2f929 100644 --- a/.github/actions/goreleaser-build-sign-publish/action.yml +++ b/.github/actions/goreleaser-build-sign-publish/action.yml @@ -29,10 +29,13 @@ inputs: description: The docker registry default: localhost:5001 required: false - # snapshot inputs - enable-goreleaser-snapshot: - description: Enable goreleaser build / release snapshot - default: "false" + docker-image-name: + description: The docker image name + default: chainlink + required: false + docker-image-tag: + description: The docker image tag + default: develop required: false # goreleaser inputs goreleaser-exec: @@ -43,6 +46,17 @@ inputs: description: "The goreleaser configuration yaml" default: ".goreleaser.yaml" required: false + enable-goreleaser-snapshot: + description: Enable goreleaser build / release snapshot + default: "false" + required: false + enable-goreleaser-split: + description: Enable goreleaser split and merge builds + default: "false" + required: false + goreleaser-split-arch: + description: The architecture to split the goreleaser build + required: false # signing inputs enable-cosign: description: Enable signing of docker images @@ -57,13 +71,6 @@ inputs: cosign-password: description: The password to decrypt the cosign private key needed to sign the image required: false -outputs: - goreleaser-metadata: - description: "Build result metadata" - value: ${{ steps.goreleaser.outputs.metadata }} - goreleaser-artifacts: - description: "Build result artifacts" - value: ${{ steps.goreleaser.outputs.artifacts }} runs: using: composite steps: @@ -97,14 +104,22 @@ runs: uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 with: registry: ${{ inputs.docker-registry }} - - name: Goreleaser release - id: goreleaser + - name: Set goreleaser split env + if: inputs.enable-goreleaser-split == 'true' + shell: bash + run: | + echo "GOOS=linux" | tee -a $GITHUB_ENV + echo "GOARCH=${{ inputs.goreleaser-split-arch }}" | tee -a $GITHUB_ENV + - name: Run goreleaser release shell: bash env: ENABLE_COSIGN: ${{ inputs.enable-cosign }} ENABLE_GORELEASER_SNAPSHOT: ${{ inputs.enable-goreleaser-snapshot }} + ENABLE_GORELEASER_SPLIT: ${{ inputs.enable-goreleaser-split }} ENABLE_DOCKER_PUBLISH: ${{ inputs.enable-docker-publish }} IMAGE_PREFIX: ${{ inputs.docker-registry }} + IMAGE_NAME: ${{ inputs.docker-image-name }} + IMAGE_TAG: ${{ inputs.docker-image-tag }} GORELEASER_EXEC: ${{ inputs.goreleaser-exec }} GORELEASER_CONFIG: ${{ inputs.goreleaser-config }} COSIGN_PASSWORD: ${{ inputs.cosign-password }} diff --git a/.github/actions/goreleaser-build-sign-publish/action_utils b/.github/actions/goreleaser-build-sign-publish/action_utils index 4aac78d6fc..051e0763fb 100755 --- a/.github/actions/goreleaser-build-sign-publish/action_utils +++ b/.github/actions/goreleaser-build-sign-publish/action_utils @@ -4,6 +4,7 @@ set -euo pipefail ENABLE_COSIGN=${ENABLE_COSIGN:-false} ENABLE_GORELEASER_SNAPSHOT=${ENABLE_GORELEASER_SNAPSHOT:-false} +ENABLE_GORELEASER_SPLIT=${ENABLE_GORELEASER_SPLIT:-false} ENABLE_DOCKER_PUBLISH=${ENABLE_DOCKER_PUBLISH:-false} COSIGN_PASSWORD=${COSIGN_PASSWORD:-""} GORELEASER_EXEC=${GORELEASER_EXEC:-goreleaser} @@ -27,8 +28,12 @@ _publish_snapshot_manifests() { local docker_manifest_extra_args=$DOCKER_MANIFEST_EXTRA_ARGS local full_sha=$(git rev-parse HEAD) local images=$(docker images --filter "label=org.opencontainers.image.revision=$full_sha" --format "{{.Repository}}:{{.Tag}}" | sort) - local arches=(amd64 arm64) local raw_manifest_lists="" + if [[ $ENABLE_GORELEASER_SPLIT == "true" ]]; then + local arches=(${GOARCH:-""}) + else + local arches=(amd64 arm64) + fi for image in $images; do for arch in "${arches[@]}"; do image=${image%"-$arch"} @@ -51,22 +56,35 @@ _publish_snapshot_manifests() { # wrapper function to invoke goreleaser release goreleaser_release() { + goreleaser_flags=() + + # set goreleaser flags + if [[ $ENABLE_GORELEASER_SNAPSHOT == "true" ]]; then + goreleaser_flags+=("--snapshot") + goreleaser_flags+=("--clean") + fi + if [[ $ENABLE_GORELEASER_SPLIT == "true" ]]; then + goreleaser_flags+=("--split") + fi + flags=$(printf "%s " "${goreleaser_flags[@]}") + flags=$(echo "$flags" | sed 's/ *$//') + if [[ $ENABLE_COSIGN == "true" ]]; then echo "$COSIGN_PUBLIC_KEY" > cosign.pub echo "$COSIGN_PRIVATE_KEY" > cosign.key fi + if [[ -n $MACOS_SDK_DIR ]]; then MACOS_SDK_DIR=$(echo "$(cd "$(dirname "$MACOS_SDK_DIR")" || exit; pwd)/$(basename "$MACOS_SDK_DIR")") fi - if [[ $ENABLE_GORELEASER_SNAPSHOT == "true" ]]; then - $GORELEASER_EXEC release --snapshot --clean --config "$GORELEASER_CONFIG" "$@" - if [[ $ENABLE_DOCKER_PUBLISH == "true" ]]; then + + $GORELEASER_EXEC release ${flags} --config "$GORELEASER_CONFIG" "$@" + + if [[ $ENABLE_DOCKER_PUBLISH == "true" ]]; then _publish_snapshot_images _publish_snapshot_manifests - fi - else - $GORELEASER_EXEC release --clean --config "$GORELEASER_CONFIG" "$@" fi + if [[ $ENABLE_COSIGN == "true" ]]; then rm -rf cosign.pub rm -rf cosign.key diff --git a/.github/workflows/build-publish-develop-pr.yml b/.github/workflows/build-publish-develop-pr.yml new file mode 100644 index 0000000000..c0c3a17824 --- /dev/null +++ b/.github/workflows/build-publish-develop-pr.yml @@ -0,0 +1,119 @@ +name: "Build and Publish Chainlink" + +on: + pull_request: + push: + branches: + - develop + - "release/**" + workflow_dispatch: + inputs: + git_ref: + description: "The git ref to check out" + required: true + build-publish: + description: "Whether to build and publish - defaults to just build" + required: false + default: "false" + +env: + GIT_REF: ${{ github.event.inputs.git_ref || github.ref }} + +jobs: + goreleaser-build-publish-chainlink: + runs-on: ubuntu-20.04 + permissions: + id-token: write + contents: read + strategy: + matrix: + goarch: [amd64, arm64] + steps: + - name: Checkout repository + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + ref: ${{ env.GIT_REF }} + + # This gets the image tag and whether to publish the image based on the event type + # PR builds: pr-- (if label 'build-publish' is present publishes the image) + # develop builds: develop- + # release builds: release- + # manual builds: (if build-publish is true publishes the image) + - name: Get image tag + id: get-image-tag + run: | + short_sha=$(git rev-parse --short HEAD) + echo "build-publish=false" | tee -a $GITHUB_OUTPUT + if [[ ${{ github.event_name }} == 'push' ]]; then + if [[ ${{ github.ref_name }} == 'release/'* ]]; then + echo "image-tag=release-${short_sha}" | tee -a $GITHUB_OUTPUT + echo "build-publish=true" | tee -a $GITHUB_OUTPUT + else + echo "image-tag=develop-${short_sha}" | tee -a $GITHUB_OUTPUT + echo "build-publish=true" | tee -a $GITHUB_OUTPUT + fi + elif [[ ${{ github.event_name }} == 'workflow_dispatch' ]]; then + echo "image-tag=${short_sha}" | tee -a $GITHUB_OUTPUT + echo "build-publish=${{ github.event.inputs.build-publish }}" | tee -a $GITHUB_OUTPUT + else + if [[ ${{ github.event_name }} == "pull_request" ]]; then + echo "image-tag=pr-${{ github.event.number }}-${short_sha}" | tee -a $GITHUB_OUTPUT + if [[ ${{ contains(github.event.pull_request.labels.*.name, 'build-publish') }} == "true" ]]; then + echo "build-publish=true" | tee -a $GITHUB_OUTPUT + fi + fi + fi + + - name: Configure aws credentials + if: steps.get-image-tag.outputs.build-publish == 'true' + uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + with: + role-to-assume: ${{ secrets.AWS_OIDC_IAM_ROLE_BUILD_PUBLISH_DEVELOP_PR }} + aws-region: ${{ secrets.AWS_REGION }} + mask-aws-account-id: true + role-session-name: goreleaser-build-publish-chainlink + + - name: Build and publish images + uses: ./.github/actions/goreleaser-build-sign-publish + with: + enable-docker-publish: ${{ steps.get-image-tag.outputs.build-publish }} + docker-registry: ${{ secrets.AWS_SDLC_ECR_HOSTNAME }} + docker-image-name: chainlink + docker-image-tag: ${{ steps.get-image-tag.outputs.image-tag }} + enable-goreleaser-snapshot: "true" + enable-goreleaser-split: "true" + goreleaser-split-arch: ${{ matrix.goarch }} + goreleaser-exec: ./tools/bin/goreleaser_wrapper + goreleaser-config: .goreleaser.develop.yaml + goreleaser-key: ${{ secrets.GORELEASER_KEY }} + zig-version: 0.11.0 + + - name: Output image name and digest + if: steps.get-image-tag.outputs.build-publish == 'true' + shell: bash + run: | + # need to check if artifacts.json exists because goreleaser splits the build + if [[ -f dist/artifacts.json ]]; then + artifact_path="dist/artifacts.json" + else + artifact_path="dist/linux_${{ matrix.goarch }}/artifacts.json" + cat dist/linux_${{ matrix.goarch }}/artifacts.json + fi + echo "### Docker Images" | tee -a "$GITHUB_STEP_SUMMARY" + jq -r '.[] | select(.type == "Docker Image") | "`\(.goarch)-image`: \(.name)"' ${artifact_path} >> output.txt + jq -r '.[] | select(.type == "Archive") | "`\(.goarch)-digest`: \(.extra.Checksum)"' ${artifact_path} >> output.txt + while read -r line; do + echo "$line" | tee -a "$GITHUB_STEP_SUMMARY" + done < output.txt + + - name: Collect Metrics + if: always() + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 + with: + id: goreleaser-build-publish + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: goreleaser-build-publish-chainlink (${{ matrix.goarch }}) + continue-on-error: true \ No newline at end of file diff --git a/.github/workflows/build-publish-develop.yml b/.github/workflows/build-publish-develop.yml deleted file mode 100644 index 8c6e5e76ac..0000000000 --- a/.github/workflows/build-publish-develop.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: "Push develop to private ECR" - -on: - push: - branches: - - develop - workflow_dispatch: - inputs: - git_ref: - description: "Git ref (commit SHA, branch name, tag name, etc.) to checkout" - required: true -env: - GIT_REF: ${{ github.event.inputs.git_ref || github.ref }} - -jobs: - push-chainlink-develop: - runs-on: ubuntu-20.04 - environment: build-develop - permissions: - id-token: write - contents: read - strategy: - matrix: - image: - - name: "" - dockerfile: core/chainlink.Dockerfile - tag-suffix: "" - - name: (plugins) - dockerfile: plugins/chainlink.Dockerfile - tag-suffix: -plugins - name: push-chainlink-develop ${{ matrix.image.name }} - steps: - - name: Checkout repository - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ env.GIT_REF }} - # When this is ran from manual workflow_dispatch, the github.sha may be - # different than the checked out commit sha. The core build uses this - # commit sha as build metadata, so we need to make sure it's correct. - - name: Get checked out git ref - if: github.event.inputs.git_ref - id: git-ref - run: echo "checked-out=$(git rev-parse HEAD)" | tee -a "${GITHUB_OUTPUT}" - - name: Build, sign and publish chainlink image - uses: ./.github/actions/build-sign-publish-chainlink - with: - publish: true - aws-role-to-assume: ${{ secrets.AWS_OIDC_IAM_ROLE_ARN }} - aws-role-duration-seconds: ${{ secrets.AWS_ROLE_DURATION_SECONDS }} - aws-region: ${{ secrets.AWS_REGION }} - ecr-hostname: ${{ secrets.AWS_DEVELOP_ECR_HOSTNAME }} - ecr-image-name: chainlink - ecr-tag-suffix: ${{ matrix.image.tag-suffix }} - dockerfile: ${{ matrix.image.dockerfile }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - git-commit-sha: ${{ steps.git-ref.outputs.checked-out || github.sha }} - - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: build-chainlink-develop - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: push-chainlink-develop ${{ matrix.image.name }} - continue-on-error: true diff --git a/.github/workflows/build-publish-pr.yml b/.github/workflows/build-publish-pr.yml deleted file mode 100644 index 36eac61cab..0000000000 --- a/.github/workflows/build-publish-pr.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: "Build and Publish from PR" - -## -# This workflow builds and publishes a Docker image for Chainlink from a PR. -# It has its own special IAM role, does not sign the image, and publishes to -# a special ECR repo. -## - -on: - pull_request: - -jobs: - build-publish-untrusted: - if: ${{ ! startsWith(github.ref_name, 'release/') || (! startsWith(github.head_ref, 'release/') && ! startsWith(github.ref_name, 'chore/'))}} - runs-on: ubuntu-20.04 - environment: sdlc - permissions: - id-token: write - contents: read - env: - ECR_IMAGE_NAME: crib-chainlink-untrusted - steps: - - name: Checkout repository - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - - name: Git Short SHA - shell: bash - env: - GIT_PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} - run: | - echo "GIT_SHORT_SHA=${GIT_PR_HEAD_SHA:0:7}" | tee -a "$GITHUB_ENV" - - - name: Check if image exists - id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - repository: ${{ env.ECR_IMAGE_NAME}} - tag: sha-${{ env.GIT_SHORT_SHA }} - AWS_REGION: ${{ secrets.AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.AWS_OIDC_IAM_ROLE_PUBLISH_PR_ARN }} - - - name: Build and publish chainlink image - if: steps.check-image.outputs.exists == 'false' - uses: ./.github/actions/build-sign-publish-chainlink - with: - publish: true - aws-role-to-assume: ${{ secrets.AWS_OIDC_IAM_ROLE_PUBLISH_PR_ARN }} - aws-role-duration-seconds: ${{ secrets.AWS_ROLE_DURATION_SECONDS_DEFAULT }} - aws-region: ${{ secrets.AWS_REGION }} - sign-images: false - ecr-hostname: ${{ secrets.AWS_SDLC_ECR_HOSTNAME }} - ecr-image-name: ${{ env.ECR_IMAGE_NAME }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: build-chainlink-pr - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: build-publish-untrusted - continue-on-error: true diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index 1a3c6546a6..0941455a16 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -1,4 +1,4 @@ -name: "Build Chainlink and Publish" +name: "Build, Sign and Publish Chainlink" on: # Mimics old circleci behaviour @@ -59,6 +59,7 @@ jobs: dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} verify-signature: true + - name: Collect Metrics if: always() id: collect-gha-metrics @@ -71,6 +72,68 @@ jobs: this-job-name: build-sign-publish-chainlink continue-on-error: true + goreleaser-build-sign-publish-chainlink: + needs: [checks] + if: ${{ ! startsWith(github.ref_name, 'release/') }} + runs-on: ubuntu-20.04 + environment: build-publish + permissions: + id-token: write + contents: read + steps: + - name: Checkout repository + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Configure aws credentials + uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + with: + role-to-assume: ${{ secrets.AWS_OIDC_IAM_ROLE_ARN }} + role-duration-seconds: ${{ secrets.AWS_ROLE_DURATION_SECONDS }} + aws-region: ${{ secrets.AWS_REGION }} + mask-aws-account-id: true + role-session-name: goreleaser-build-sign-publish-chainlink + + - name: Build, sign, and publish image + id: goreleaser-build-sign-publish + uses: ./.github/actions/goreleaser-build-sign-publish + with: + enable-docker-publish: "true" + docker-registry: ${{ env.ECR_HOSTNAME}} + docker-image-name: ${{ env.ECR_IMAGE_NAME }} + docker-image-tag: ${{ github.ref_name }} + goreleaser-exec: ./tools/bin/goreleaser_wrapper + goreleaser-config: .goreleaser.develop.yaml + goreleaser-key: ${{ secrets.GORELEASER_KEY }} + zig-version: 0.11.0 + enable-cosign: "true" + cosign-version: 3.4.0 + cosign-password: ${{ secrets.COSIGN_PASSWORD }} + cosign-public-key: ${{ secrets.COSIGN_PUBLIC_KEY }} + cosign-private-key: ${{ secrets.COSIGN_PRIVATE_KEY }} + + - name: Output image name and digest + shell: sh + run: | + artifact_path="dist/artifacts.json" + echo "### Docker Images" | tee -a "$GITHUB_STEP_SUMMARY" + jq -r '.[] | select(.type == "Docker Image") | "`\(.goarch)-image`: \(.name)"' ${artifact_path} >> output.txt + jq -r '.[] | select(.type == "Archive") | "`\(.goarch)-digest`: \(.extra.Checksum)"' ${artifact_path} >> output.txt + while read -r line; do + echo "$line" | tee -a "$GITHUB_STEP_SUMMARY" + done < output.txt + + - name: Collect Metrics + if: always() + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 + with: + id: goreleaser-build-chainlink-publish + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: goreleaser-build-sign-publish-chainlink + continue-on-error: true + # Notify Slack channel for new git tags. slack-notify: if: github.ref_type == 'tag' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index f52b9a5974..0000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: "Build Chainlink" - -on: - pull_request: - -jobs: - build-chainlink: - runs-on: ubuntu-20.04 - if: ${{ ! startsWith(github.head_ref, 'release/') && ! startsWith(github.ref_name, 'chore/') }} - steps: - - name: Checkout repository - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 - id: change - with: - predicate-quantifier: every - filters: | - changelog-only: - - 'CHANGELOG.md' - - '!common/**' - - '!contracts/**' - - '!core/**' - - '!dashboard-lib/**' - - '!fuzz/**' - - '!integration-tests/**' - - '!internal/**' - - '!operator_ui/**' - - '!plugins/**' - - '!tools/**' - - - name: Build chainlink image - if: ${{ steps.change.outputs.changelog-only == 'false' }} - uses: ./.github/actions/build-sign-publish-chainlink - with: - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - publish: false - sign-images: false - - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: build-chainlink - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: build-chainlink - continue-on-error: true diff --git a/.github/workflows/goreleaser-build-publish-develop.yml b/.github/workflows/goreleaser-build-publish-develop.yml deleted file mode 100644 index 835d650f18..0000000000 --- a/.github/workflows/goreleaser-build-publish-develop.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: "Build publish Chainlink develop on private ECR" - -on: - push: - branches: - - develop - -jobs: - push-chainlink-develop-goreleaser: - runs-on: - labels: ubuntu22.04-16cores-64GB - outputs: - goreleaser-metadata: ${{ steps.build-sign-publish.outputs.goreleaser-metadata }} - goreleaser-artifacts: ${{ steps.build-sign-publish.outputs.goreleaser-artifacts }} - environment: build-develop - permissions: - id-token: write - contents: read - steps: - - name: Checkout repository - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Configure aws credentials - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 - with: - role-to-assume: ${{ secrets.AWS_OIDC_IAM_ROLE_ARN }} - role-duration-seconds: ${{ secrets.AWS_ROLE_DURATION_SECONDS }} - aws-region: ${{ secrets.AWS_REGION }} - mask-aws-account-id: true - role-session-name: goreleaser-build-publish-chainlink.push-develop - - name: Build, sign, and publish image - id: build-sign-publish - uses: ./.github/actions/goreleaser-build-sign-publish - with: - enable-docker-publish: "true" - docker-registry: ${{ secrets.AWS_DEVELOP_ECR_HOSTNAME }} - enable-goreleaser-snapshot: "true" - goreleaser-exec: ./tools/bin/goreleaser_wrapper - goreleaser-config: .goreleaser.develop.yaml - goreleaser-key: ${{ secrets.GORELEASER_KEY }} - zig-version: 0.11.0 - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: goreleaser-build-publish - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: push-chainlink-develop-goreleaser - continue-on-error: true - \ No newline at end of file diff --git a/.goreleaser.develop.yaml b/.goreleaser.develop.yaml index 7fbd2aa667..b1f65217b8 100644 --- a/.goreleaser.develop.yaml +++ b/.goreleaser.develop.yaml @@ -4,6 +4,8 @@ project_name: chainlink env: - ZIG_EXEC={{ if index .Env "ZIG_EXEC" }}{{ .Env.ZIG_EXEC }}{{ else }}zig{{ end }} - IMAGE_PREFIX={{ if index .Env "IMAGE_PREFIX" }}{{ .Env.IMAGE_PREFIX }}{{ else }}localhost:5001{{ end }} + - IMAGE_NAME={{ if index .Env "IMAGE_NAME" }}{{ .Env.IMAGE_NAME }}{{ else }}chainlink{{ end }} + - IMAGE_TAG={{ if index .Env "IMAGE_TAG" }}{{ .Env.IMAGE_TAG }}{{ else }}develop{{ end }} - IMAGE_LABEL_DESCRIPTION="node of the decentralized oracle network, bridging on and off-chain computation" - IMAGE_LABEL_LICENSES="MIT" - IMAGE_LABEL_SOURCE="https://github.com/smartcontractkit/{{ .ProjectName }}" @@ -56,18 +58,18 @@ builds: # See https://goreleaser.com/customization/docker/ dockers: - - id: root-linux-amd64 + - id: linux-amd64 dockerfile: core/chainlink.goreleaser.Dockerfile use: buildx goos: linux goarch: amd64 extra_files: - tmp/linux_amd64/libs - - tmp/linux_amd64/plugins - tools/bin/ldd_fix build_flag_templates: - "--platform=linux/amd64" - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" - "--build-arg=COMMIT_SHA={{ .FullCommit }}" - "--label=org.opencontainers.image.created={{ .Date }}" - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" @@ -78,20 +80,20 @@ dockers: - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" image_templates: - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop-root-amd64" - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}-root-amd64" - - id: root-linux-arm64 + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-amd64" + - id: linux-arm64 dockerfile: core/chainlink.goreleaser.Dockerfile use: buildx goos: linux goarch: arm64 extra_files: - tmp/linux_arm64/libs - - tmp/linux_arm64/plugins - tools/bin/ldd_fix build_flag_templates: - "--platform=linux/arm64" - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" - "--build-arg=COMMIT_SHA={{ .FullCommit }}" - "--label=org.opencontainers.image.created={{ .Date }}" - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" @@ -102,9 +104,9 @@ dockers: - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" image_templates: - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop-root-arm64" - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}-root-arm64" - - id: linux-amd64 + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-arm64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-arm64" + - id: linux-amd64-plugins dockerfile: core/chainlink.goreleaser.Dockerfile use: buildx goos: linux @@ -118,6 +120,10 @@ dockers: - "--pull" - "--build-arg=CHAINLINK_USER=chainlink" - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--build-arg=CL_MEDIAN_CMD=chainlink-feeds" + - "--build-arg=CL_MERCURY_CMD=chainlink-mercury" + - "--build-arg=CL_SOLANA_CMD=chainlink-solana" + - "--build-arg=CL_STARKNET_CMD=chainlink-starknet" - "--label=org.opencontainers.image.created={{ .Date }}" - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" @@ -127,9 +133,9 @@ dockers: - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" image_templates: - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop-amd64" - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}-amd64" - - id: linux-arm64 + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-amd64" + - id: linux-arm64-plugins dockerfile: core/chainlink.goreleaser.Dockerfile use: buildx goos: linux @@ -143,6 +149,10 @@ dockers: - "--pull" - "--build-arg=CHAINLINK_USER=chainlink" - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--build-arg=CL_MEDIAN_CMD=chainlink-feeds" + - "--build-arg=CL_MERCURY_CMD=chainlink-mercury" + - "--build-arg=CL_SOLANA_CMD=chainlink-solana" + - "--build-arg=CL_STARKNET_CMD=chainlink-starknet" - "--label=org.opencontainers.image.created={{ .Date }}" - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" @@ -152,27 +162,27 @@ dockers: - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" image_templates: - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop-arm64" - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}-arm64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-arm64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-arm64" # See https://goreleaser.com/customization/docker_manifest/ docker_manifests: - - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop-root" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}" image_templates: - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop-root-amd64" - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop-root-arm64" - - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}-root" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-arm64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}" image_templates: - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}-root-amd64" - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}-root-arm64" - - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-arm64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins" image_templates: - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop-amd64" - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop-arm64" - - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-arm64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins" image_templates: - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}-amd64" - - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}-arm64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-arm64" # See https://goreleaser.com/customization/docker_sign/ docker_signs: @@ -185,6 +195,9 @@ checksum: snapshot: name_template: "{{ .Env.CHAINLINK_VERSION }}-{{ .ShortCommit }}" +partial: + by: target + changelog: sort: asc filters: diff --git a/core/chainlink.goreleaser.Dockerfile b/core/chainlink.goreleaser.Dockerfile index 5d172fd77e..c35fe015cb 100644 --- a/core/chainlink.goreleaser.Dockerfile +++ b/core/chainlink.goreleaser.Dockerfile @@ -20,8 +20,9 @@ COPY ./chainlink /usr/local/bin/ # Copy native libs if cgo is enabled COPY ./tmp/linux_${TARGETARCH}/libs /usr/local/bin/libs -# Copy plugins and enable them -COPY ./tmp/linux_${TARGETARCH}/plugins/* /usr/local/bin/ +# Copy plugins if exist and enable them +# https://stackoverflow.com/questions/70096208/dockerfile-copy-folder-if-it-exists-conditional-copy/70096420#70096420 +COPY ./tmp/linux_${TARGETARCH}/plugin[s] /usr/local/bin/ # Allow individual plugins to be enabled by supplying their path ARG CL_MEDIAN_CMD ARG CL_MERCURY_CMD diff --git a/tools/bin/goreleaser_utils b/tools/bin/goreleaser_utils index 4e1b3ffc4d..fa9553274c 100755 --- a/tools/bin/goreleaser_utils +++ b/tools/bin/goreleaser_utils @@ -68,11 +68,13 @@ before_hook() { install_remote_plugins "linux" "amd64" "$gobin"/linux_amd64/ mkdir -p "$lib_path/linux_amd64/plugins" cp "$gobin"/linux_amd64/chainlink* "$lib_path/linux_amd64/plugins" + cp "$gobin"/chainlink* "$lib_path/linux_amd64/plugins" install_local_plugins "linux" "arm64" "$gobin"/linux_arm64/ install_remote_plugins "linux" "arm64" "$gobin"/linux_arm64/ mkdir -p "$lib_path/linux_arm64/plugins" cp "$gobin"/linux_arm64/chainlink* "$lib_path/linux_arm64/plugins" + cp "$gobin"/chainlink* "$lib_path/linux_arm64/plugins" } install_local_plugins() { @@ -94,10 +96,10 @@ get_remote_plugin_paths() { ) for plugin in "${plugins[@]}"; do - plugin_dep_name=$(echo "$plugin" | cut -d"|" -f1) - plugin_main=$(echo "$plugin" | cut -d"|" -f2) + plugin_dep_name=$(echo "$plugin" | cut -d"|" -f1) + plugin_main=$(echo "$plugin" | cut -d"|" -f2) - full_plugin_path=$(go list -m -f "{{.Dir}}" "$plugin_dep_name")"$plugin_main" + full_plugin_path=$(go list -m -f "{{.Dir}}" "$plugin_dep_name")"$plugin_main" echo "$full_plugin_path" done } From 8fa8c3a07512bb8358abdabc3fdcc8ae310c6c1c Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata <96521086+bukata-sa@users.noreply.github.com> Date: Thu, 15 Aug 2024 12:50:11 +0100 Subject: [PATCH 093/432] fix: deadlock in balance shutdown (#14125) * fix: deadlock in balance shutdown * bump dependency --- .changeset/tasty-windows-own.md | 5 +++++ core/chains/evm/monitor/balance.go | 8 ++------ core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 10 files changed, 19 insertions(+), 18 deletions(-) create mode 100644 .changeset/tasty-windows-own.md diff --git a/.changeset/tasty-windows-own.md b/.changeset/tasty-windows-own.md new file mode 100644 index 0000000000..bd81338cb4 --- /dev/null +++ b/.changeset/tasty-windows-own.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#bugfix balance shutdown deadlock diff --git a/core/chains/evm/monitor/balance.go b/core/chains/evm/monitor/balance.go index 3e28d5c436..1f5275c13f 100644 --- a/core/chains/evm/monitor/balance.go +++ b/core/chains/evm/monitor/balance.go @@ -82,17 +82,13 @@ func (bm *balanceMonitor) close() error { // OnNewLongestChain checks the balance for each key func (bm *balanceMonitor) OnNewLongestChain(_ context.Context, _ *evmtypes.Head) { - ok := bm.sleeperTask.IfStarted(bm.checkBalances) + bm.eng.Debugw("BalanceMonitor: signalling balance worker") + ok := bm.sleeperTask.WakeUpIfStarted() if !ok { bm.eng.Debugw("BalanceMonitor: ignoring OnNewLongestChain call, balance monitor is not started", "state", bm.sleeperTask.State()) } } -func (bm *balanceMonitor) checkBalances() { - bm.eng.Debugw("BalanceMonitor: signalling balance worker") - bm.sleeperTask.WakeUp() -} - func (bm *balanceMonitor) updateBalance(ethBal assets.Eth, address gethCommon.Address) { bm.promUpdateEthBalance(ðBal, address) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 31b07472c5..43dd930fd5 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index ccb508b82e..4efc20bbd5 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1186,8 +1186,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad h1:QmXA8j7f1gNK52dRuW78ZAbzTRlv62fRZQdp0aYFJmc= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 h1:5x4kknDjui1m1E5Ad6oXc/sFi6nPN2cQqUfSIdwr5iQ= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/go.mod b/go.mod index 66bf6ad606..23e6d7efec 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index f5650b82b3..1a4d97d32a 100644 --- a/go.sum +++ b/go.sum @@ -1141,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad h1:QmXA8j7f1gNK52dRuW78ZAbzTRlv62fRZQdp0aYFJmc= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 h1:5x4kknDjui1m1E5Ad6oXc/sFi6nPN2cQqUfSIdwr5iQ= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index bf826c136f..ff246ad79a 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -33,7 +33,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 github.com/smartcontractkit/chainlink-testing-framework v1.34.2 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 3c48904828..df5b1603e3 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1490,8 +1490,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad h1:QmXA8j7f1gNK52dRuW78ZAbzTRlv62fRZQdp0aYFJmc= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 h1:5x4kknDjui1m1E5Ad6oXc/sFi6nPN2cQqUfSIdwr5iQ= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index ebb17f3031..a5c61b4005 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.31.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 github.com/smartcontractkit/chainlink-testing-framework v1.34.2 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index ae966241ad..91aec9d710 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1472,8 +1472,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad h1:QmXA8j7f1gNK52dRuW78ZAbzTRlv62fRZQdp0aYFJmc= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240814082155-8b06c222c7ad/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 h1:5x4kknDjui1m1E5Ad6oXc/sFi6nPN2cQqUfSIdwr5iQ= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= From 48c084664a2f4a8d6b32bcdd9f9af172a6776319 Mon Sep 17 00:00:00 2001 From: joaoluisam Date: Thu, 15 Aug 2024 15:01:31 +0100 Subject: [PATCH 094/432] [SHIP-2816] Add scroll sepolia network config (#14126) * Add scroll sepolia network config * disable reorg protection on v2_3 scroll, zkevm * fix node funding * fix reorg protection logic --------- Co-authored-by: anirudhwarrier <12178754+anirudhwarrier@users.noreply.github.com> --- integration-tests/benchmark/keeper_test.go | 5 +++++ integration-tests/contracts/ethereum_contracts_automation.go | 2 +- integration-tests/testsetups/keeper_benchmark.go | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/integration-tests/benchmark/keeper_test.go b/integration-tests/benchmark/keeper_test.go index fde550bbdf..af0d52ae23 100644 --- a/integration-tests/benchmark/keeper_test.go +++ b/integration-tests/benchmark/keeper_test.go @@ -263,6 +263,11 @@ var networkConfig = map[string]NetworkConfig{ blockTime: time.Second, deltaStage: 20 * time.Second, }, + networks.ScrollSepolia.Name: { + upkeepSLA: int64(120), + blockTime: 3 * time.Second, + deltaStage: 20 * time.Second, + }, } func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.KeeperBenchmarkTestConfig) (*environment.Environment, blockchain.EVMNetwork) { diff --git a/integration-tests/contracts/ethereum_contracts_automation.go b/integration-tests/contracts/ethereum_contracts_automation.go index bd0e1aafc8..9c01511ff1 100644 --- a/integration-tests/contracts/ethereum_contracts_automation.go +++ b/integration-tests/contracts/ethereum_contracts_automation.go @@ -147,7 +147,7 @@ type EthereumKeeperRegistry struct { func (v *EthereumKeeperRegistry) ReorgProtectionEnabled() bool { chainId := v.client.ChainID // reorg protection is disabled in polygon zkEVM and Scroll bc currently there is no way to get the block hash onchain - return v.version != ethereum.RegistryVersion_2_2 || (chainId != 1101 && chainId != 1442 && chainId != 2442 && chainId != 534352 && chainId != 534351) + return v.version < ethereum.RegistryVersion_2_2 || (chainId != 1101 && chainId != 1442 && chainId != 2442 && chainId != 534352 && chainId != 534351) } func (v *EthereumKeeperRegistry) ChainModuleAddress() common.Address { diff --git a/integration-tests/testsetups/keeper_benchmark.go b/integration-tests/testsetups/keeper_benchmark.go index a3d6c426e4..5ea3fb8a3c 100644 --- a/integration-tests/testsetups/keeper_benchmark.go +++ b/integration-tests/testsetups/keeper_benchmark.go @@ -198,7 +198,7 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Keep for index := range keysToFund { // Fund chainlink nodes nodesToFund := k.chainlinkNodes - if inputs.RegistryVersions[index] == ethereum.RegistryVersion_2_0 || inputs.RegistryVersions[index] == ethereum.RegistryVersion_2_1 || inputs.RegistryVersions[index] == ethereum.RegistryVersion_2_2 { + if inputs.RegistryVersions[index] >= ethereum.RegistryVersion_2_0 { nodesToFund = k.chainlinkNodes[1:] } err = actions.FundChainlinkNodesAtKeyIndexFromRootAddress(k.log, k.chainClient, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(nodesToFund), k.Inputs.ChainlinkNodeFunding, index) From a41b353a20d73aa2d3fe3e8e979a0bcacc46fafe Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata <96521086+bukata-sa@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:14:02 +0100 Subject: [PATCH 095/432] [CCIP-2611] Report new heads to atlas' OTI (#13647) * feat(oti-head-report): Report new heads to atlas' OTI * tests tests review fixes ci fixes ci fixes telemetry reporter test fix chain in proto fix chain in proto fix ci changeset fix config test review fix fix config test fix docs test fix config testscript fix config testscript fix test * move to relayer move to relayer move service to evm * go generate * move config * simplify * review * Revert moving to relayer * review * review * head telemetry enabled by default * review * rebase * review * drop config * rebase * review * regenerate * cl node timeout * review fix * rebase --------- Co-authored-by: Jordan Krage --- .changeset/proud-jokes-exercise.md | 5 + .mockery.yaml | 22 +- common/types/mocks/monitoring_endpoint.go | 65 +++++ core/internal/mocks/prometheus_backend.go | 204 -------------- core/services/chainlink/application.go | 14 +- core/services/headreporter/head_reporter.go | 110 ++++++++ .../headreporter/head_reporter_mock.go | 130 +++++++++ .../headreporter/head_reporter_test.go | 45 ++++ core/services/headreporter/helper_test.go | 5 + .../headreporter/prometheus_backend_mock.go | 204 ++++++++++++++ .../prometheus_reporter.go} | 168 +++--------- .../prometheus_reporter_test.go} | 174 ++++++------ .../headreporter/telemetry_reporter.go | 65 +++++ .../headreporter/telemetry_reporter_test.go | 105 ++++++++ core/services/synchronization/common.go | 1 + .../telem/telem_head_report.pb.go | 255 ++++++++++++++++++ .../telem/telem_head_report.proto | 17 ++ .../monitoring_endpoint_generator_mock.go | 88 ++++++ core/web/testdata/body/health.html | 6 +- core/web/testdata/body/health.json | 18 +- core/web/testdata/body/health.txt | 2 +- .../testconfig/vrfv2plus/vrfv2plus.toml | 1 + testdata/scripts/health/default.txtar | 20 +- testdata/scripts/health/multi-chain.txtar | 20 +- 24 files changed, 1280 insertions(+), 464 deletions(-) create mode 100644 .changeset/proud-jokes-exercise.md create mode 100644 common/types/mocks/monitoring_endpoint.go delete mode 100644 core/internal/mocks/prometheus_backend.go create mode 100644 core/services/headreporter/head_reporter.go create mode 100644 core/services/headreporter/head_reporter_mock.go create mode 100644 core/services/headreporter/head_reporter_test.go create mode 100644 core/services/headreporter/helper_test.go create mode 100644 core/services/headreporter/prometheus_backend_mock.go rename core/services/{promreporter/prom_reporter.go => headreporter/prometheus_reporter.go} (63%) rename core/services/{promreporter/prom_reporter_test.go => headreporter/prometheus_reporter_test.go} (64%) create mode 100644 core/services/headreporter/telemetry_reporter.go create mode 100644 core/services/headreporter/telemetry_reporter_test.go create mode 100644 core/services/synchronization/telem/telem_head_report.pb.go create mode 100644 core/services/synchronization/telem/telem_head_report.proto create mode 100644 core/services/telemetry/monitoring_endpoint_generator_mock.go diff --git a/.changeset/proud-jokes-exercise.md b/.changeset/proud-jokes-exercise.md new file mode 100644 index 0000000000..4e36d139de --- /dev/null +++ b/.changeset/proud-jokes-exercise.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#added Report new heads as a telemetry to OTI diff --git a/.mockery.yaml b/.mockery.yaml index abb3105b13..37cbff58b1 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -262,11 +262,20 @@ packages: ORM: Runner: PipelineParamUnmarshaler: - github.com/smartcontractkit/chainlink/v2/core/services/promreporter: + github.com/smartcontractkit/chainlink/v2/core/services/headreporter: config: - dir: core/internal/mocks + dir: "{{ .InterfaceDir }}" + filename: "{{ .InterfaceName | snakecase }}_mock.go" + inpackage: true + mockname: "Mock{{ .InterfaceName | camelcase }}" interfaces: + HeadReporter: PrometheusBackend: + github.com/smartcontractkit/libocr/commontypes: + config: + dir: "common/types/mocks" + interfaces: + MonitoringEndpoint: github.com/smartcontractkit/chainlink/v2/core/services/relay/evm: interfaces: BatchCaller: @@ -301,6 +310,15 @@ packages: interfaces: Config: FeeConfig: + github.com/smartcontractkit/chainlink/v2/core/services/telemetry: + config: + dir: "{{ .InterfaceDir }}" + filename: "{{ .InterfaceName | snakecase }}_mock.go" + inpackage: true + mockname: "Mock{{ .InterfaceName | camelcase }}" + interfaces: + MonitoringEndpointGenerator: + IngressAgent: github.com/smartcontractkit/chainlink/v2/core/services/webhook: interfaces: ExternalInitiatorManager: diff --git a/common/types/mocks/monitoring_endpoint.go b/common/types/mocks/monitoring_endpoint.go new file mode 100644 index 0000000000..5afc04c909 --- /dev/null +++ b/common/types/mocks/monitoring_endpoint.go @@ -0,0 +1,65 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import mock "github.com/stretchr/testify/mock" + +// MonitoringEndpoint is an autogenerated mock type for the MonitoringEndpoint type +type MonitoringEndpoint struct { + mock.Mock +} + +type MonitoringEndpoint_Expecter struct { + mock *mock.Mock +} + +func (_m *MonitoringEndpoint) EXPECT() *MonitoringEndpoint_Expecter { + return &MonitoringEndpoint_Expecter{mock: &_m.Mock} +} + +// SendLog provides a mock function with given fields: log +func (_m *MonitoringEndpoint) SendLog(log []byte) { + _m.Called(log) +} + +// MonitoringEndpoint_SendLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendLog' +type MonitoringEndpoint_SendLog_Call struct { + *mock.Call +} + +// SendLog is a helper method to define mock.On call +// - log []byte +func (_e *MonitoringEndpoint_Expecter) SendLog(log interface{}) *MonitoringEndpoint_SendLog_Call { + return &MonitoringEndpoint_SendLog_Call{Call: _e.mock.On("SendLog", log)} +} + +func (_c *MonitoringEndpoint_SendLog_Call) Run(run func(log []byte)) *MonitoringEndpoint_SendLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte)) + }) + return _c +} + +func (_c *MonitoringEndpoint_SendLog_Call) Return() *MonitoringEndpoint_SendLog_Call { + _c.Call.Return() + return _c +} + +func (_c *MonitoringEndpoint_SendLog_Call) RunAndReturn(run func([]byte)) *MonitoringEndpoint_SendLog_Call { + _c.Call.Return(run) + return _c +} + +// NewMonitoringEndpoint creates a new instance of MonitoringEndpoint. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMonitoringEndpoint(t interface { + mock.TestingT + Cleanup(func()) +}) *MonitoringEndpoint { + mock := &MonitoringEndpoint{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/internal/mocks/prometheus_backend.go b/core/internal/mocks/prometheus_backend.go deleted file mode 100644 index d02f7062cb..0000000000 --- a/core/internal/mocks/prometheus_backend.go +++ /dev/null @@ -1,204 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package mocks - -import ( - big "math/big" - - mock "github.com/stretchr/testify/mock" -) - -// PrometheusBackend is an autogenerated mock type for the PrometheusBackend type -type PrometheusBackend struct { - mock.Mock -} - -type PrometheusBackend_Expecter struct { - mock *mock.Mock -} - -func (_m *PrometheusBackend) EXPECT() *PrometheusBackend_Expecter { - return &PrometheusBackend_Expecter{mock: &_m.Mock} -} - -// SetMaxUnconfirmedAge provides a mock function with given fields: _a0, _a1 -func (_m *PrometheusBackend) SetMaxUnconfirmedAge(_a0 *big.Int, _a1 float64) { - _m.Called(_a0, _a1) -} - -// PrometheusBackend_SetMaxUnconfirmedAge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedAge' -type PrometheusBackend_SetMaxUnconfirmedAge_Call struct { - *mock.Call -} - -// SetMaxUnconfirmedAge is a helper method to define mock.On call -// - _a0 *big.Int -// - _a1 float64 -func (_e *PrometheusBackend_Expecter) SetMaxUnconfirmedAge(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetMaxUnconfirmedAge_Call { - return &PrometheusBackend_SetMaxUnconfirmedAge_Call{Call: _e.mock.On("SetMaxUnconfirmedAge", _a0, _a1)} -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) Run(run func(_a0 *big.Int, _a1 float64)) *PrometheusBackend_SetMaxUnconfirmedAge_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*big.Int), args[1].(float64)) - }) - return _c -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) Return() *PrometheusBackend_SetMaxUnconfirmedAge_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) RunAndReturn(run func(*big.Int, float64)) *PrometheusBackend_SetMaxUnconfirmedAge_Call { - _c.Call.Return(run) - return _c -} - -// SetMaxUnconfirmedBlocks provides a mock function with given fields: _a0, _a1 -func (_m *PrometheusBackend) SetMaxUnconfirmedBlocks(_a0 *big.Int, _a1 int64) { - _m.Called(_a0, _a1) -} - -// PrometheusBackend_SetMaxUnconfirmedBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedBlocks' -type PrometheusBackend_SetMaxUnconfirmedBlocks_Call struct { - *mock.Call -} - -// SetMaxUnconfirmedBlocks is a helper method to define mock.On call -// - _a0 *big.Int -// - _a1 int64 -func (_e *PrometheusBackend_Expecter) SetMaxUnconfirmedBlocks(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { - return &PrometheusBackend_SetMaxUnconfirmedBlocks_Call{Call: _e.mock.On("SetMaxUnconfirmedBlocks", _a0, _a1)} -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) Run(run func(_a0 *big.Int, _a1 int64)) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*big.Int), args[1].(int64)) - }) - return _c -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) Return() *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) RunAndReturn(run func(*big.Int, int64)) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { - _c.Call.Return(run) - return _c -} - -// SetPipelineRunsQueued provides a mock function with given fields: n -func (_m *PrometheusBackend) SetPipelineRunsQueued(n int) { - _m.Called(n) -} - -// PrometheusBackend_SetPipelineRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineRunsQueued' -type PrometheusBackend_SetPipelineRunsQueued_Call struct { - *mock.Call -} - -// SetPipelineRunsQueued is a helper method to define mock.On call -// - n int -func (_e *PrometheusBackend_Expecter) SetPipelineRunsQueued(n interface{}) *PrometheusBackend_SetPipelineRunsQueued_Call { - return &PrometheusBackend_SetPipelineRunsQueued_Call{Call: _e.mock.On("SetPipelineRunsQueued", n)} -} - -func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) Run(run func(n int)) *PrometheusBackend_SetPipelineRunsQueued_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int)) - }) - return _c -} - -func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) Return() *PrometheusBackend_SetPipelineRunsQueued_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) RunAndReturn(run func(int)) *PrometheusBackend_SetPipelineRunsQueued_Call { - _c.Call.Return(run) - return _c -} - -// SetPipelineTaskRunsQueued provides a mock function with given fields: n -func (_m *PrometheusBackend) SetPipelineTaskRunsQueued(n int) { - _m.Called(n) -} - -// PrometheusBackend_SetPipelineTaskRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineTaskRunsQueued' -type PrometheusBackend_SetPipelineTaskRunsQueued_Call struct { - *mock.Call -} - -// SetPipelineTaskRunsQueued is a helper method to define mock.On call -// - n int -func (_e *PrometheusBackend_Expecter) SetPipelineTaskRunsQueued(n interface{}) *PrometheusBackend_SetPipelineTaskRunsQueued_Call { - return &PrometheusBackend_SetPipelineTaskRunsQueued_Call{Call: _e.mock.On("SetPipelineTaskRunsQueued", n)} -} - -func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) Run(run func(n int)) *PrometheusBackend_SetPipelineTaskRunsQueued_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int)) - }) - return _c -} - -func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) Return() *PrometheusBackend_SetPipelineTaskRunsQueued_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) RunAndReturn(run func(int)) *PrometheusBackend_SetPipelineTaskRunsQueued_Call { - _c.Call.Return(run) - return _c -} - -// SetUnconfirmedTransactions provides a mock function with given fields: _a0, _a1 -func (_m *PrometheusBackend) SetUnconfirmedTransactions(_a0 *big.Int, _a1 int64) { - _m.Called(_a0, _a1) -} - -// PrometheusBackend_SetUnconfirmedTransactions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetUnconfirmedTransactions' -type PrometheusBackend_SetUnconfirmedTransactions_Call struct { - *mock.Call -} - -// SetUnconfirmedTransactions is a helper method to define mock.On call -// - _a0 *big.Int -// - _a1 int64 -func (_e *PrometheusBackend_Expecter) SetUnconfirmedTransactions(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetUnconfirmedTransactions_Call { - return &PrometheusBackend_SetUnconfirmedTransactions_Call{Call: _e.mock.On("SetUnconfirmedTransactions", _a0, _a1)} -} - -func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) Run(run func(_a0 *big.Int, _a1 int64)) *PrometheusBackend_SetUnconfirmedTransactions_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*big.Int), args[1].(int64)) - }) - return _c -} - -func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) Return() *PrometheusBackend_SetUnconfirmedTransactions_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) RunAndReturn(run func(*big.Int, int64)) *PrometheusBackend_SetUnconfirmedTransactions_Call { - _c.Call.Return(run) - return _c -} - -// NewPrometheusBackend creates a new instance of PrometheusBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewPrometheusBackend(t interface { - mock.TestingT - Cleanup(func()) -}) *PrometheusBackend { - mock := &PrometheusBackend{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 17c217b1c9..98067821f9 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -45,6 +45,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/feeds" "github.com/smartcontractkit/chainlink/v2/core/services/fluxmonitorv2" "github.com/smartcontractkit/chainlink/v2/core/services/gateway" + "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keeper" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" @@ -56,7 +57,6 @@ import ( externalp2p "github.com/smartcontractkit/chainlink/v2/core/services/p2p/wrapper" "github.com/smartcontractkit/chainlink/v2/core/services/periodicbackup" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/promreporter" "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" @@ -323,8 +323,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) { srvcs = append(srvcs, mailMon) srvcs = append(srvcs, relayerChainInterops.Services()...) - promReporter := promreporter.NewPromReporter(opts.DS, legacyEVMChains, globalLogger) - srvcs = append(srvcs, promReporter) // Initialize Local Users ORM and Authentication Provider specified in config // BasicAdminUsersORM is initialized and required regardless of separate Authentication Provider @@ -364,8 +362,16 @@ func NewApplication(opts ApplicationOpts) (Application, error) { workflowORM = workflowstore.NewDBStore(opts.DS, globalLogger, clockwork.NewRealClock()) ) + promReporter := headreporter.NewPrometheusReporter(opts.DS, legacyEVMChains) + chainIDs := make([]*big.Int, legacyEVMChains.Len()) + for i, chain := range legacyEVMChains.Slice() { + chainIDs[i] = chain.ID() + } + telemReporter := headreporter.NewTelemetryReporter(telemetryManager, chainIDs...) + headReporter := headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter, telemReporter) + srvcs = append(srvcs, headReporter) for _, chain := range legacyEVMChains.Slice() { - chain.HeadBroadcaster().Subscribe(promReporter) + chain.HeadBroadcaster().Subscribe(headReporter) chain.TxManager().RegisterResumeCallback(pipelineRunner.ResumeRun) } diff --git a/core/services/headreporter/head_reporter.go b/core/services/headreporter/head_reporter.go new file mode 100644 index 0000000000..f81a6acf91 --- /dev/null +++ b/core/services/headreporter/head_reporter.go @@ -0,0 +1,110 @@ +package headreporter + +import ( + "context" + "sync" + "time" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +type ( + HeadReporter interface { + ReportNewHead(ctx context.Context, head *evmtypes.Head) error + ReportPeriodic(ctx context.Context) error + } + + HeadReporterService struct { + services.StateMachine + ds sqlutil.DataSource + lggr logger.Logger + newHeads *mailbox.Mailbox[*evmtypes.Head] + chStop services.StopChan + wgDone sync.WaitGroup + reportPeriod time.Duration + reporters []HeadReporter + unsubscribeFns []func() + } +) + +func NewHeadReporterService(ds sqlutil.DataSource, lggr logger.Logger, reporters ...HeadReporter) *HeadReporterService { + return &HeadReporterService{ + ds: ds, + lggr: lggr.Named("HeadReporter"), + newHeads: mailbox.NewSingle[*evmtypes.Head](), + chStop: make(chan struct{}), + reporters: reporters, + } +} + +func (hrd *HeadReporterService) Subscribe(subFn func(types.HeadTrackable) (evmtypes.Head, func())) { + _, unsubscribe := subFn(hrd) + hrd.unsubscribeFns = append(hrd.unsubscribeFns, unsubscribe) +} + +func (hrd *HeadReporterService) Start(context.Context) error { + return hrd.StartOnce(hrd.Name(), func() error { + hrd.wgDone.Add(1) + go hrd.eventLoop() + return nil + }) +} + +func (hrd *HeadReporterService) Close() error { + return hrd.StopOnce(hrd.Name(), func() error { + close(hrd.chStop) + hrd.wgDone.Wait() + return nil + }) +} + +func (hrd *HeadReporterService) Name() string { + return hrd.lggr.Name() +} + +func (hrd *HeadReporterService) HealthReport() map[string]error { + return map[string]error{hrd.Name(): hrd.Healthy()} +} + +func (hrd *HeadReporterService) OnNewLongestChain(ctx context.Context, head *evmtypes.Head) { + hrd.newHeads.Deliver(head) +} + +func (hrd *HeadReporterService) eventLoop() { + hrd.lggr.Debug("Starting event loop") + defer hrd.wgDone.Done() + ctx, cancel := hrd.chStop.NewCtx() + defer cancel() + after := time.After(hrd.reportPeriod) + for { + select { + case <-hrd.newHeads.Notify(): + head, exists := hrd.newHeads.Retrieve() + if !exists { + continue + } + for _, reporter := range hrd.reporters { + err := reporter.ReportNewHead(ctx, head) + if err != nil && ctx.Err() == nil { + hrd.lggr.Errorw("Error reporting new head", "err", err) + } + } + case <-after: + for _, reporter := range hrd.reporters { + err := reporter.ReportPeriodic(ctx) + if err != nil && ctx.Err() == nil { + hrd.lggr.Errorw("Error in periodic report", "err", err) + } + } + after = time.After(hrd.reportPeriod) + case <-hrd.chStop: + return + } + } +} diff --git a/core/services/headreporter/head_reporter_mock.go b/core/services/headreporter/head_reporter_mock.go new file mode 100644 index 0000000000..21978abb86 --- /dev/null +++ b/core/services/headreporter/head_reporter_mock.go @@ -0,0 +1,130 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package headreporter + +import ( + context "context" + + types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + mock "github.com/stretchr/testify/mock" +) + +// MockHeadReporter is an autogenerated mock type for the HeadReporter type +type MockHeadReporter struct { + mock.Mock +} + +type MockHeadReporter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockHeadReporter) EXPECT() *MockHeadReporter_Expecter { + return &MockHeadReporter_Expecter{mock: &_m.Mock} +} + +// ReportNewHead provides a mock function with given fields: ctx, head +func (_m *MockHeadReporter) ReportNewHead(ctx context.Context, head *types.Head) error { + ret := _m.Called(ctx, head) + + if len(ret) == 0 { + panic("no return value specified for ReportNewHead") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *types.Head) error); ok { + r0 = rf(ctx, head) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockHeadReporter_ReportNewHead_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportNewHead' +type MockHeadReporter_ReportNewHead_Call struct { + *mock.Call +} + +// ReportNewHead is a helper method to define mock.On call +// - ctx context.Context +// - head *types.Head +func (_e *MockHeadReporter_Expecter) ReportNewHead(ctx interface{}, head interface{}) *MockHeadReporter_ReportNewHead_Call { + return &MockHeadReporter_ReportNewHead_Call{Call: _e.mock.On("ReportNewHead", ctx, head)} +} + +func (_c *MockHeadReporter_ReportNewHead_Call) Run(run func(ctx context.Context, head *types.Head)) *MockHeadReporter_ReportNewHead_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*types.Head)) + }) + return _c +} + +func (_c *MockHeadReporter_ReportNewHead_Call) Return(_a0 error) *MockHeadReporter_ReportNewHead_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockHeadReporter_ReportNewHead_Call) RunAndReturn(run func(context.Context, *types.Head) error) *MockHeadReporter_ReportNewHead_Call { + _c.Call.Return(run) + return _c +} + +// ReportPeriodic provides a mock function with given fields: ctx +func (_m *MockHeadReporter) ReportPeriodic(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ReportPeriodic") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockHeadReporter_ReportPeriodic_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportPeriodic' +type MockHeadReporter_ReportPeriodic_Call struct { + *mock.Call +} + +// ReportPeriodic is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockHeadReporter_Expecter) ReportPeriodic(ctx interface{}) *MockHeadReporter_ReportPeriodic_Call { + return &MockHeadReporter_ReportPeriodic_Call{Call: _e.mock.On("ReportPeriodic", ctx)} +} + +func (_c *MockHeadReporter_ReportPeriodic_Call) Run(run func(ctx context.Context)) *MockHeadReporter_ReportPeriodic_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockHeadReporter_ReportPeriodic_Call) Return(_a0 error) *MockHeadReporter_ReportPeriodic_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockHeadReporter_ReportPeriodic_Call) RunAndReturn(run func(context.Context) error) *MockHeadReporter_ReportPeriodic_Call { + _c.Call.Return(run) + return _c +} + +// NewMockHeadReporter creates a new instance of MockHeadReporter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockHeadReporter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockHeadReporter { + mock := &MockHeadReporter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/headreporter/head_reporter_test.go b/core/services/headreporter/head_reporter_test.go new file mode 100644 index 0000000000..ded7e1fb61 --- /dev/null +++ b/core/services/headreporter/head_reporter_test.go @@ -0,0 +1,45 @@ +package headreporter + +import ( + "sync/atomic" + "testing" + "time" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func NewHead() evmtypes.Head { + return evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(0)} +} + +func Test_HeadReporterService(t *testing.T) { + t.Run("report everything", func(t *testing.T) { + db := pgtest.NewSqlxDB(t) + + headReporter := NewMockHeadReporter(t) + service := NewHeadReporterService(db, logger.TestLogger(t), headReporter) + service.reportPeriod = time.Second + err := service.Start(testutils.Context(t)) + require.NoError(t, err) + + var reportCalls atomic.Int32 + head := NewHead() + headReporter.On("ReportNewHead", mock.Anything, &head).Run(func(args mock.Arguments) { + reportCalls.Add(1) + }).Return(nil) + headReporter.On("ReportPeriodic", mock.Anything).Run(func(args mock.Arguments) { + reportCalls.Add(1) + }).Return(nil) + service.OnNewLongestChain(testutils.Context(t), &head) + + require.Eventually(t, func() bool { return reportCalls.Load() == 2 }, 5*time.Second, 100*time.Millisecond) + }) +} diff --git a/core/services/headreporter/helper_test.go b/core/services/headreporter/helper_test.go new file mode 100644 index 0000000000..fa05182a85 --- /dev/null +++ b/core/services/headreporter/helper_test.go @@ -0,0 +1,5 @@ +package headreporter + +func (p *prometheusReporter) SetBackend(b PrometheusBackend) { + p.backend = b +} diff --git a/core/services/headreporter/prometheus_backend_mock.go b/core/services/headreporter/prometheus_backend_mock.go new file mode 100644 index 0000000000..ca83f6c4fb --- /dev/null +++ b/core/services/headreporter/prometheus_backend_mock.go @@ -0,0 +1,204 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package headreporter + +import ( + big "math/big" + + mock "github.com/stretchr/testify/mock" +) + +// MockPrometheusBackend is an autogenerated mock type for the PrometheusBackend type +type MockPrometheusBackend struct { + mock.Mock +} + +type MockPrometheusBackend_Expecter struct { + mock *mock.Mock +} + +func (_m *MockPrometheusBackend) EXPECT() *MockPrometheusBackend_Expecter { + return &MockPrometheusBackend_Expecter{mock: &_m.Mock} +} + +// SetMaxUnconfirmedAge provides a mock function with given fields: _a0, _a1 +func (_m *MockPrometheusBackend) SetMaxUnconfirmedAge(_a0 *big.Int, _a1 float64) { + _m.Called(_a0, _a1) +} + +// MockPrometheusBackend_SetMaxUnconfirmedAge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedAge' +type MockPrometheusBackend_SetMaxUnconfirmedAge_Call struct { + *mock.Call +} + +// SetMaxUnconfirmedAge is a helper method to define mock.On call +// - _a0 *big.Int +// - _a1 float64 +func (_e *MockPrometheusBackend_Expecter) SetMaxUnconfirmedAge(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { + return &MockPrometheusBackend_SetMaxUnconfirmedAge_Call{Call: _e.mock.On("SetMaxUnconfirmedAge", _a0, _a1)} +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) Run(run func(_a0 *big.Int, _a1 float64)) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(float64)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) Return() *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) RunAndReturn(run func(*big.Int, float64)) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { + _c.Call.Return(run) + return _c +} + +// SetMaxUnconfirmedBlocks provides a mock function with given fields: _a0, _a1 +func (_m *MockPrometheusBackend) SetMaxUnconfirmedBlocks(_a0 *big.Int, _a1 int64) { + _m.Called(_a0, _a1) +} + +// MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedBlocks' +type MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call struct { + *mock.Call +} + +// SetMaxUnconfirmedBlocks is a helper method to define mock.On call +// - _a0 *big.Int +// - _a1 int64 +func (_e *MockPrometheusBackend_Expecter) SetMaxUnconfirmedBlocks(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { + return &MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call{Call: _e.mock.On("SetMaxUnconfirmedBlocks", _a0, _a1)} +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) Run(run func(_a0 *big.Int, _a1 int64)) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(int64)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) Return() *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) RunAndReturn(run func(*big.Int, int64)) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { + _c.Call.Return(run) + return _c +} + +// SetPipelineRunsQueued provides a mock function with given fields: n +func (_m *MockPrometheusBackend) SetPipelineRunsQueued(n int) { + _m.Called(n) +} + +// MockPrometheusBackend_SetPipelineRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineRunsQueued' +type MockPrometheusBackend_SetPipelineRunsQueued_Call struct { + *mock.Call +} + +// SetPipelineRunsQueued is a helper method to define mock.On call +// - n int +func (_e *MockPrometheusBackend_Expecter) SetPipelineRunsQueued(n interface{}) *MockPrometheusBackend_SetPipelineRunsQueued_Call { + return &MockPrometheusBackend_SetPipelineRunsQueued_Call{Call: _e.mock.On("SetPipelineRunsQueued", n)} +} + +func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) Run(run func(n int)) *MockPrometheusBackend_SetPipelineRunsQueued_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(int)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) Return() *MockPrometheusBackend_SetPipelineRunsQueued_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) RunAndReturn(run func(int)) *MockPrometheusBackend_SetPipelineRunsQueued_Call { + _c.Call.Return(run) + return _c +} + +// SetPipelineTaskRunsQueued provides a mock function with given fields: n +func (_m *MockPrometheusBackend) SetPipelineTaskRunsQueued(n int) { + _m.Called(n) +} + +// MockPrometheusBackend_SetPipelineTaskRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineTaskRunsQueued' +type MockPrometheusBackend_SetPipelineTaskRunsQueued_Call struct { + *mock.Call +} + +// SetPipelineTaskRunsQueued is a helper method to define mock.On call +// - n int +func (_e *MockPrometheusBackend_Expecter) SetPipelineTaskRunsQueued(n interface{}) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { + return &MockPrometheusBackend_SetPipelineTaskRunsQueued_Call{Call: _e.mock.On("SetPipelineTaskRunsQueued", n)} +} + +func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) Run(run func(n int)) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(int)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) Return() *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) RunAndReturn(run func(int)) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { + _c.Call.Return(run) + return _c +} + +// SetUnconfirmedTransactions provides a mock function with given fields: _a0, _a1 +func (_m *MockPrometheusBackend) SetUnconfirmedTransactions(_a0 *big.Int, _a1 int64) { + _m.Called(_a0, _a1) +} + +// MockPrometheusBackend_SetUnconfirmedTransactions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetUnconfirmedTransactions' +type MockPrometheusBackend_SetUnconfirmedTransactions_Call struct { + *mock.Call +} + +// SetUnconfirmedTransactions is a helper method to define mock.On call +// - _a0 *big.Int +// - _a1 int64 +func (_e *MockPrometheusBackend_Expecter) SetUnconfirmedTransactions(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetUnconfirmedTransactions_Call { + return &MockPrometheusBackend_SetUnconfirmedTransactions_Call{Call: _e.mock.On("SetUnconfirmedTransactions", _a0, _a1)} +} + +func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) Run(run func(_a0 *big.Int, _a1 int64)) *MockPrometheusBackend_SetUnconfirmedTransactions_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(int64)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) Return() *MockPrometheusBackend_SetUnconfirmedTransactions_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) RunAndReturn(run func(*big.Int, int64)) *MockPrometheusBackend_SetUnconfirmedTransactions_Call { + _c.Call.Return(run) + return _c +} + +// NewMockPrometheusBackend creates a new instance of MockPrometheusBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockPrometheusBackend(t interface { + mock.TestingT + Cleanup(func()) +}) *MockPrometheusBackend { + mock := &MockPrometheusBackend{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/promreporter/prom_reporter.go b/core/services/headreporter/prometheus_reporter.go similarity index 63% rename from core/services/promreporter/prom_reporter.go rename to core/services/headreporter/prometheus_reporter.go index 31d5f1129e..3e39c7aca4 100644 --- a/core/services/promreporter/prom_reporter.go +++ b/core/services/headreporter/prometheus_reporter.go @@ -1,40 +1,28 @@ -package promreporter +package headreporter import ( "context" "fmt" "math/big" - "sync" "time" - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "go.uber.org/multierr" - "github.com/smartcontractkit/chainlink-common/pkg/services" - "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) type ( - promReporter struct { - services.StateMachine - ds sqlutil.DataSource - chains legacyevm.LegacyChainContainer - lggr logger.Logger - backend PrometheusBackend - newHeads *mailbox.Mailbox[*evmtypes.Head] - chStop services.StopChan - wgDone sync.WaitGroup - reportPeriod time.Duration + prometheusReporter struct { + ds sqlutil.DataSource + chains legacyevm.LegacyChainContainer + backend PrometheusBackend } PrometheusBackend interface { @@ -71,103 +59,15 @@ var ( }) ) -func (defaultBackend) SetUnconfirmedTransactions(evmChainID *big.Int, n int64) { - promUnconfirmedTransactions.WithLabelValues(evmChainID.String()).Set(float64(n)) -} - -func (defaultBackend) SetMaxUnconfirmedAge(evmChainID *big.Int, s float64) { - promMaxUnconfirmedAge.WithLabelValues(evmChainID.String()).Set(s) -} - -func (defaultBackend) SetMaxUnconfirmedBlocks(evmChainID *big.Int, n int64) { - promMaxUnconfirmedBlocks.WithLabelValues(evmChainID.String()).Set(float64(n)) -} - -func (defaultBackend) SetPipelineRunsQueued(n int) { - promPipelineTaskRunsQueued.Set(float64(n)) -} - -func (defaultBackend) SetPipelineTaskRunsQueued(n int) { - promPipelineRunsQueued.Set(float64(n)) -} - -func NewPromReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) *promReporter { - var backend PrometheusBackend = defaultBackend{} - period := 15 * time.Second - for _, opt := range opts { - switch v := opt.(type) { - case time.Duration: - period = v - case PrometheusBackend: - backend = v - } - } - - chStop := make(chan struct{}) - return &promReporter{ - ds: ds, - chains: chainContainer, - lggr: lggr.Named("PromReporter"), - backend: backend, - newHeads: mailbox.NewSingle[*evmtypes.Head](), - chStop: chStop, - reportPeriod: period, +func NewPrometheusReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer) *prometheusReporter { + return &prometheusReporter{ + ds: ds, + chains: chainContainer, + backend: defaultBackend{}, } } -// Start starts PromReporter. -func (pr *promReporter) Start(context.Context) error { - return pr.StartOnce("PromReporter", func() error { - pr.wgDone.Add(1) - go pr.eventLoop() - return nil - }) -} - -func (pr *promReporter) Close() error { - return pr.StopOnce("PromReporter", func() error { - close(pr.chStop) - pr.wgDone.Wait() - return nil - }) -} -func (pr *promReporter) Name() string { - return pr.lggr.Name() -} - -func (pr *promReporter) HealthReport() map[string]error { - return map[string]error{pr.Name(): pr.Healthy()} -} - -func (pr *promReporter) OnNewLongestChain(ctx context.Context, head *evmtypes.Head) { - pr.newHeads.Deliver(head) -} - -func (pr *promReporter) eventLoop() { - pr.lggr.Debug("Starting event loop") - defer pr.wgDone.Done() - ctx, cancel := pr.chStop.NewCtx() - defer cancel() - for { - select { - case <-pr.newHeads.Notify(): - head, exists := pr.newHeads.Retrieve() - if !exists { - continue - } - pr.reportHeadMetrics(ctx, head) - case <-time.After(pr.reportPeriod): - if err := errors.Wrap(pr.reportPipelineRunStats(ctx), "reportPipelineRunStats failed"); err != nil { - pr.lggr.Errorw("Error reporting prometheus metrics", "err", err) - } - - case <-pr.chStop: - return - } - } -} - -func (pr *promReporter) getTxm(evmChainID *big.Int) (txmgr.TxManager, error) { +func (pr *prometheusReporter) getTxm(evmChainID *big.Int) (txmgr.TxManager, error) { chain, err := pr.chains.Get(evmChainID.String()) if err != nil { return nil, fmt.Errorf("failed to get chain: %w", err) @@ -175,20 +75,16 @@ func (pr *promReporter) getTxm(evmChainID *big.Int) (txmgr.TxManager, error) { return chain.TxManager(), nil } -func (pr *promReporter) reportHeadMetrics(ctx context.Context, head *evmtypes.Head) { +func (pr *prometheusReporter) ReportNewHead(ctx context.Context, head *evmtypes.Head) error { evmChainID := head.EVMChainID.ToInt() - err := multierr.Combine( + return multierr.Combine( errors.Wrap(pr.reportPendingEthTxes(ctx, evmChainID), "reportPendingEthTxes failed"), errors.Wrap(pr.reportMaxUnconfirmedAge(ctx, evmChainID), "reportMaxUnconfirmedAge failed"), errors.Wrap(pr.reportMaxUnconfirmedBlocks(ctx, head), "reportMaxUnconfirmedBlocks failed"), ) - - if err != nil && ctx.Err() == nil { - pr.lggr.Errorw("Error reporting prometheus metrics", "err", err) - } } -func (pr *promReporter) reportPendingEthTxes(ctx context.Context, evmChainID *big.Int) (err error) { +func (pr *prometheusReporter) reportPendingEthTxes(ctx context.Context, evmChainID *big.Int) (err error) { txm, err := pr.getTxm(evmChainID) if err != nil { return fmt.Errorf("failed to get txm: %w", err) @@ -202,7 +98,7 @@ func (pr *promReporter) reportPendingEthTxes(ctx context.Context, evmChainID *bi return nil } -func (pr *promReporter) reportMaxUnconfirmedAge(ctx context.Context, evmChainID *big.Int) (err error) { +func (pr *prometheusReporter) reportMaxUnconfirmedAge(ctx context.Context, evmChainID *big.Int) (err error) { txm, err := pr.getTxm(evmChainID) if err != nil { return fmt.Errorf("failed to get txm: %w", err) @@ -221,7 +117,7 @@ func (pr *promReporter) reportMaxUnconfirmedAge(ctx context.Context, evmChainID return nil } -func (pr *promReporter) reportMaxUnconfirmedBlocks(ctx context.Context, head *evmtypes.Head) (err error) { +func (pr *prometheusReporter) reportMaxUnconfirmedBlocks(ctx context.Context, head *evmtypes.Head) (err error) { txm, err := pr.getTxm(head.EVMChainID.ToInt()) if err != nil { return fmt.Errorf("failed to get txm: %w", err) @@ -240,7 +136,11 @@ func (pr *promReporter) reportMaxUnconfirmedBlocks(ctx context.Context, head *ev return nil } -func (pr *promReporter) reportPipelineRunStats(ctx context.Context) (err error) { +func (pr *prometheusReporter) ReportPeriodic(ctx context.Context) error { + return errors.Wrap(pr.reportPipelineRunStats(ctx), "reportPipelineRunStats failed") +} + +func (pr *prometheusReporter) reportPipelineRunStats(ctx context.Context) (err error) { rows, err := pr.ds.QueryContext(ctx, ` SELECT pipeline_run_id FROM pipeline_task_runs WHERE finished_at IS NULL `) @@ -271,3 +171,23 @@ SELECT pipeline_run_id FROM pipeline_task_runs WHERE finished_at IS NULL return nil } + +func (defaultBackend) SetUnconfirmedTransactions(evmChainID *big.Int, n int64) { + promUnconfirmedTransactions.WithLabelValues(evmChainID.String()).Set(float64(n)) +} + +func (defaultBackend) SetMaxUnconfirmedAge(evmChainID *big.Int, s float64) { + promMaxUnconfirmedAge.WithLabelValues(evmChainID.String()).Set(s) +} + +func (defaultBackend) SetMaxUnconfirmedBlocks(evmChainID *big.Int, n int64) { + promMaxUnconfirmedBlocks.WithLabelValues(evmChainID.String()).Set(float64(n)) +} + +func (defaultBackend) SetPipelineRunsQueued(n int) { + promPipelineTaskRunsQueued.Set(float64(n)) +} + +func (defaultBackend) SetPipelineTaskRunsQueued(n int) { + promPipelineRunsQueued.Set(float64(n)) +} diff --git a/core/services/promreporter/prom_reporter_test.go b/core/services/headreporter/prometheus_reporter_test.go similarity index 64% rename from core/services/promreporter/prom_reporter_test.go rename to core/services/headreporter/prometheus_reporter_test.go index a0a4a247c2..d96e617fd7 100644 --- a/core/services/promreporter/prom_reporter_test.go +++ b/core/services/headreporter/prometheus_reporter_test.go @@ -1,8 +1,7 @@ -package promreporter_test +package headreporter_test import ( "math/big" - "sync/atomic" "testing" "time" @@ -10,91 +9,40 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" - evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/promreporter" + "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" ) -func newHead() evmtypes.Head { - return evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(0)} -} - -func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainContainer { - config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) - keyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator()) - require.NoError(t, err) - lggr := logger.TestLogger(t) - lpOpts := logpoller.Opts{ - PollPeriod: 100 * time.Millisecond, - FinalityDepth: 2, - BackfillBatchSize: 3, - RpcBatchSize: 2, - KeepFinalizedBlocksDepth: 1000, - } - ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, ht, lpOpts) - - txm, err := txmgr.NewTxm( - db, - evmConfig, - evmConfig.GasEstimator(), - evmConfig.Transactions(), - nil, - dbConfig, - dbConfig.Listener(), - ethClient, - lggr, - lp, - keyStore, - estimator, - ht) - require.NoError(t, err) - - cfg := configtest.NewGeneralConfig(t, nil) - return cltest.NewLegacyChainsWithMockChainAndTxManager(t, ethClient, cfg, txm) -} - -func Test_PromReporter_OnNewLongestChain(t *testing.T) { +func Test_PrometheusReporter(t *testing.T) { t.Run("with nothing in the database", func(t *testing.T) { db := pgtest.NewSqlxDB(t) - backend := mocks.NewPrometheusBackend(t) - reporter := promreporter.NewPromReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) - - var subscribeCalls atomic.Int32 - + backend := headreporter.NewMockPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() - backend.On("SetPipelineTaskRunsQueued", 0).Return() - backend.On("SetPipelineRunsQueued", 0). - Run(func(args mock.Arguments) { - subscribeCalls.Add(1) - }). - Return() - servicetest.Run(t, reporter) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db)) + reporter.SetBackend(backend) - head := newHead() - reporter.OnNewLongestChain(testutils.Context(t), &head) + head := headreporter.NewHead() + err := reporter.ReportNewHead(testutils.Context(t), &head) + require.NoError(t, err) - require.Eventually(t, func() bool { return subscribeCalls.Load() >= 1 }, 12*time.Second, 100*time.Millisecond) + backend.On("SetPipelineTaskRunsQueued", 0).Return() + backend.On("SetPipelineRunsQueued", 0).Return() + err = reporter.ReportPeriodic(testutils.Context(t)) + require.NoError(t, err) }) t.Run("with unconfirmed evm.txes", func(t *testing.T) { @@ -103,61 +51,93 @@ func Test_PromReporter_OnNewLongestChain(t *testing.T) { ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) - var subscribeCalls atomic.Int32 + etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress) + cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, fromAddress) + cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress) + require.NoError(t, txStore.UpdateTxAttemptBroadcastBeforeBlockNum(testutils.Context(t), etx.ID, 7)) - backend := mocks.NewPrometheusBackend(t) + backend := headreporter.NewMockPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(3)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), mock.MatchedBy(func(s float64) bool { return s > 0 })).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(35)).Return() - backend.On("SetPipelineTaskRunsQueued", 0).Return() - backend.On("SetPipelineRunsQueued", 0). - Run(func(args mock.Arguments) { - subscribeCalls.Add(1) - }). - Return() - reporter := promreporter.NewPromReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) - servicetest.Run(t, reporter) - etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress) - cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, fromAddress) - cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress) - require.NoError(t, txStore.UpdateTxAttemptBroadcastBeforeBlockNum(testutils.Context(t), etx.ID, 7)) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db)) + reporter.SetBackend(backend) - head := newHead() - reporter.OnNewLongestChain(testutils.Context(t), &head) + head := headreporter.NewHead() + err := reporter.ReportNewHead(testutils.Context(t), &head) + require.NoError(t, err) - require.Eventually(t, func() bool { return subscribeCalls.Load() >= 1 }, 12*time.Second, 100*time.Millisecond) + backend.On("SetPipelineTaskRunsQueued", 0).Return() + backend.On("SetPipelineRunsQueued", 0).Return() + + err = reporter.ReportPeriodic(testutils.Context(t)) + require.NoError(t, err) }) t.Run("with unfinished pipeline task runs", func(t *testing.T) { db := pgtest.NewSqlxDB(t) pgtest.MustExec(t, db, `SET CONSTRAINTS pipeline_task_runs_pipeline_run_id_fkey DEFERRED`) - backend := mocks.NewPrometheusBackend(t) - reporter := promreporter.NewPromReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) - cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 2) - var subscribeCalls atomic.Int32 - + backend := headreporter.NewMockPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() - backend.On("SetPipelineTaskRunsQueued", 3).Return() - backend.On("SetPipelineRunsQueued", 2). - Run(func(args mock.Arguments) { - subscribeCalls.Add(1) - }). - Return() - servicetest.Run(t, reporter) - head := newHead() - reporter.OnNewLongestChain(testutils.Context(t), &head) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db)) + reporter.SetBackend(backend) + + head := headreporter.NewHead() + err := reporter.ReportNewHead(testutils.Context(t), &head) + require.NoError(t, err) - require.Eventually(t, func() bool { return subscribeCalls.Load() >= 1 }, 12*time.Second, 100*time.Millisecond) + backend.On("SetPipelineTaskRunsQueued", 3).Return() + backend.On("SetPipelineRunsQueued", 2).Return() + + err = reporter.ReportPeriodic(testutils.Context(t)) + require.NoError(t, err) }) } + +func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainContainer { + config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) + keyStore := cltest.NewKeyStore(t, db).Eth() + ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator()) + require.NoError(t, err) + lggr := logger.TestLogger(t) + lpOpts := logpoller.Opts{ + PollPeriod: 100 * time.Millisecond, + FinalityDepth: 2, + BackfillBatchSize: 3, + RpcBatchSize: 2, + KeepFinalizedBlocksDepth: 1000, + } + ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, ht, lpOpts) + + txm, err := txmgr.NewTxm( + db, + evmConfig, + evmConfig.GasEstimator(), + evmConfig.Transactions(), + nil, + dbConfig, + dbConfig.Listener(), + ethClient, + lggr, + lp, + keyStore, + estimator, + ht) + require.NoError(t, err) + + cfg := configtest.NewGeneralConfig(t, nil) + return cltest.NewLegacyChainsWithMockChainAndTxManager(t, ethClient, cfg, txm) +} diff --git a/core/services/headreporter/telemetry_reporter.go b/core/services/headreporter/telemetry_reporter.go new file mode 100644 index 0000000000..d76ce8a604 --- /dev/null +++ b/core/services/headreporter/telemetry_reporter.go @@ -0,0 +1,65 @@ +package headreporter + +import ( + "context" + "math/big" + + "github.com/pkg/errors" + + "github.com/smartcontractkit/libocr/commontypes" + "google.golang.org/protobuf/proto" + + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" +) + +type telemetryReporter struct { + endpoints map[uint64]commontypes.MonitoringEndpoint +} + +func NewTelemetryReporter(monitoringEndpointGen telemetry.MonitoringEndpointGenerator, chainIDs ...*big.Int) HeadReporter { + endpoints := make(map[uint64]commontypes.MonitoringEndpoint) + for _, chainID := range chainIDs { + endpoints[chainID.Uint64()] = monitoringEndpointGen.GenMonitoringEndpoint("EVM", chainID.String(), "", synchronization.HeadReport) + } + return &telemetryReporter{endpoints: endpoints} +} + +func (t *telemetryReporter) ReportNewHead(ctx context.Context, head *evmtypes.Head) error { + monitoringEndpoint := t.endpoints[head.EVMChainID.ToInt().Uint64()] + if monitoringEndpoint == nil { + return errors.Errorf("No monitoring endpoint provided chain_id=%d", head.EVMChainID.Int64()) + } + var finalized *telem.Block + latestFinalizedHead := head.LatestFinalizedHead() + if latestFinalizedHead != nil { + finalized = &telem.Block{ + Timestamp: uint64(latestFinalizedHead.GetTimestamp().UTC().Unix()), + Number: uint64(latestFinalizedHead.BlockNumber()), + Hash: latestFinalizedHead.BlockHash().Hex(), + } + } + request := &telem.HeadReportRequest{ + Latest: &telem.Block{ + Timestamp: uint64(head.Timestamp.UTC().Unix()), + Number: uint64(head.Number), + Hash: head.Hash.Hex(), + }, + Finalized: finalized, + } + bytes, err := proto.Marshal(request) + if err != nil { + return errors.WithMessage(err, "telem.HeadReportRequest marshal error") + } + monitoringEndpoint.SendLog(bytes) + if finalized == nil { + return errors.Errorf("No finalized block was found for chain_id=%d", head.EVMChainID.Int64()) + } + return nil +} + +func (t *telemetryReporter) ReportPeriodic(ctx context.Context) error { + return nil +} diff --git a/core/services/headreporter/telemetry_reporter_test.go b/core/services/headreporter/telemetry_reporter_test.go new file mode 100644 index 0000000000..c33edab0bc --- /dev/null +++ b/core/services/headreporter/telemetry_reporter_test.go @@ -0,0 +1,105 @@ +package headreporter_test + +import ( + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/proto" + + mocks2 "github.com/smartcontractkit/chainlink/v2/common/types/mocks" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" +) + +func Test_TelemetryReporter_NewHead(t *testing.T) { + head := evmtypes.Head{ + Number: 42, + EVMChainID: ubig.NewI(100), + Hash: common.HexToHash("0x1010"), + Timestamp: time.UnixMilli(1000), + IsFinalized: false, + Parent: &evmtypes.Head{ + Number: 41, + Hash: common.HexToHash("0x1009"), + Timestamp: time.UnixMilli(999), + IsFinalized: true, + }, + } + requestBytes, err := proto.Marshal(&telem.HeadReportRequest{ + Latest: &telem.Block{ + Timestamp: uint64(head.Timestamp.UTC().Unix()), + Number: 42, + Hash: head.Hash.Hex(), + }, + Finalized: &telem.Block{ + Timestamp: uint64(head.Parent.Timestamp.UTC().Unix()), + Number: 41, + Hash: head.Parent.Hash.Hex(), + }, + }) + assert.NoError(t, err) + + monitoringEndpoint := mocks2.NewMonitoringEndpoint(t) + monitoringEndpoint.On("SendLog", requestBytes).Return() + + monitoringEndpointGen := telemetry.NewMockMonitoringEndpointGenerator(t) + monitoringEndpointGen. + On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). + Return(monitoringEndpoint) + reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, big.NewInt(100)) + + err = reporter.ReportNewHead(testutils.Context(t), &head) + assert.NoError(t, err) +} + +func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { + head := evmtypes.Head{ + Number: 42, + EVMChainID: ubig.NewI(100), + Hash: common.HexToHash("0x1010"), + Timestamp: time.UnixMilli(1000), + IsFinalized: false, + } + requestBytes, err := proto.Marshal(&telem.HeadReportRequest{ + Latest: &telem.Block{ + Timestamp: uint64(head.Timestamp.UTC().Unix()), + Number: 42, + Hash: head.Hash.Hex(), + }, + }) + assert.NoError(t, err) + + monitoringEndpoint := mocks2.NewMonitoringEndpoint(t) + monitoringEndpoint.On("SendLog", requestBytes).Return() + + monitoringEndpointGen := telemetry.NewMockMonitoringEndpointGenerator(t) + monitoringEndpointGen. + On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). + Return(monitoringEndpoint) + reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, big.NewInt(100)) + + err = reporter.ReportNewHead(testutils.Context(t), &head) + assert.Errorf(t, err, "No finalized block was found for chain_id=100") +} + +func Test_TelemetryReporter_NewHead_MissingEndpoint(t *testing.T) { + monitoringEndpointGen := telemetry.NewMockMonitoringEndpointGenerator(t) + monitoringEndpointGen. + On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). + Return(nil) + + reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, big.NewInt(100)) + + head := evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(100)} + + err := reporter.ReportNewHead(testutils.Context(t), &head) + assert.Errorf(t, err, "No monitoring endpoint provided chain_id=100") +} diff --git a/core/services/synchronization/common.go b/core/services/synchronization/common.go index 394830a76a..a6c0191e3a 100644 --- a/core/services/synchronization/common.go +++ b/core/services/synchronization/common.go @@ -28,6 +28,7 @@ const ( OCR3CCIPCommit TelemetryType = "ocr3-ccip-commit" OCR3CCIPExec TelemetryType = "ocr3-ccip-exec" OCR3CCIPBootstrap TelemetryType = "ocr3-bootstrap" + HeadReport TelemetryType = "head-report" ) type TelemPayload struct { diff --git a/core/services/synchronization/telem/telem_head_report.pb.go b/core/services/synchronization/telem/telem_head_report.pb.go new file mode 100644 index 0000000000..18e4532472 --- /dev/null +++ b/core/services/synchronization/telem/telem_head_report.pb.go @@ -0,0 +1,255 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc v4.25.1 +// source: core/services/synchronization/telem/telem_head_report.proto + +package telem + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type HeadReportRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Chain string `protobuf:"bytes,1,opt,name=chain,proto3" json:"chain,omitempty"` + Latest *Block `protobuf:"bytes,2,opt,name=latest,proto3" json:"latest,omitempty"` + Finalized *Block `protobuf:"bytes,3,opt,name=finalized,proto3,oneof" json:"finalized,omitempty"` +} + +func (x *HeadReportRequest) Reset() { + *x = HeadReportRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HeadReportRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HeadReportRequest) ProtoMessage() {} + +func (x *HeadReportRequest) ProtoReflect() protoreflect.Message { + mi := &file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HeadReportRequest.ProtoReflect.Descriptor instead. +func (*HeadReportRequest) Descriptor() ([]byte, []int) { + return file_core_services_synchronization_telem_telem_head_report_proto_rawDescGZIP(), []int{0} +} + +func (x *HeadReportRequest) GetChain() string { + if x != nil { + return x.Chain + } + return "" +} + +func (x *HeadReportRequest) GetLatest() *Block { + if x != nil { + return x.Latest + } + return nil +} + +func (x *HeadReportRequest) GetFinalized() *Block { + if x != nil { + return x.Finalized + } + return nil +} + +type Block struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Timestamp uint64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Number uint64 `protobuf:"varint,2,opt,name=number,proto3" json:"number,omitempty"` + Hash string `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty"` +} + +func (x *Block) Reset() { + *x = Block{} + if protoimpl.UnsafeEnabled { + mi := &file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Block) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Block) ProtoMessage() {} + +func (x *Block) ProtoReflect() protoreflect.Message { + mi := &file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Block.ProtoReflect.Descriptor instead. +func (*Block) Descriptor() ([]byte, []int) { + return file_core_services_synchronization_telem_telem_head_report_proto_rawDescGZIP(), []int{1} +} + +func (x *Block) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *Block) GetNumber() uint64 { + if x != nil { + return x.Number + } + return 0 +} + +func (x *Block) GetHash() string { + if x != nil { + return x.Hash + } + return "" +} + +var File_core_services_synchronization_telem_telem_head_report_proto protoreflect.FileDescriptor + +var file_core_services_synchronization_telem_telem_head_report_proto_rawDesc = []byte{ + 0x0a, 0x3b, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, + 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, + 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x5f, 0x68, 0x65, 0x61, 0x64, + 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x74, + 0x65, 0x6c, 0x65, 0x6d, 0x22, 0x8e, 0x01, 0x0a, 0x11, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x12, 0x24, 0x0a, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x06, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x66, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x51, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1c, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x42, 0x4e, 0x5a, 0x4c, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x69, 0x6e, + 0x6b, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_core_services_synchronization_telem_telem_head_report_proto_rawDescOnce sync.Once + file_core_services_synchronization_telem_telem_head_report_proto_rawDescData = file_core_services_synchronization_telem_telem_head_report_proto_rawDesc +) + +func file_core_services_synchronization_telem_telem_head_report_proto_rawDescGZIP() []byte { + file_core_services_synchronization_telem_telem_head_report_proto_rawDescOnce.Do(func() { + file_core_services_synchronization_telem_telem_head_report_proto_rawDescData = protoimpl.X.CompressGZIP(file_core_services_synchronization_telem_telem_head_report_proto_rawDescData) + }) + return file_core_services_synchronization_telem_telem_head_report_proto_rawDescData +} + +var file_core_services_synchronization_telem_telem_head_report_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_core_services_synchronization_telem_telem_head_report_proto_goTypes = []interface{}{ + (*HeadReportRequest)(nil), // 0: telem.HeadReportRequest + (*Block)(nil), // 1: telem.Block +} +var file_core_services_synchronization_telem_telem_head_report_proto_depIdxs = []int32{ + 1, // 0: telem.HeadReportRequest.latest:type_name -> telem.Block + 1, // 1: telem.HeadReportRequest.finalized:type_name -> telem.Block + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_core_services_synchronization_telem_telem_head_report_proto_init() } +func file_core_services_synchronization_telem_telem_head_report_proto_init() { + if File_core_services_synchronization_telem_telem_head_report_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HeadReportRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Block); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[0].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_core_services_synchronization_telem_telem_head_report_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_core_services_synchronization_telem_telem_head_report_proto_goTypes, + DependencyIndexes: file_core_services_synchronization_telem_telem_head_report_proto_depIdxs, + MessageInfos: file_core_services_synchronization_telem_telem_head_report_proto_msgTypes, + }.Build() + File_core_services_synchronization_telem_telem_head_report_proto = out.File + file_core_services_synchronization_telem_telem_head_report_proto_rawDesc = nil + file_core_services_synchronization_telem_telem_head_report_proto_goTypes = nil + file_core_services_synchronization_telem_telem_head_report_proto_depIdxs = nil +} diff --git a/core/services/synchronization/telem/telem_head_report.proto b/core/services/synchronization/telem/telem_head_report.proto new file mode 100644 index 0000000000..6f4cf2ddae --- /dev/null +++ b/core/services/synchronization/telem/telem_head_report.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +option go_package = "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem"; + +package telem; + +message HeadReportRequest { + string chainID = 1; + Block latest = 2; + optional Block finalized = 3; +} + +message Block { + uint64 timestamp = 1; + uint64 number = 2; + string hash = 3; +} diff --git a/core/services/telemetry/monitoring_endpoint_generator_mock.go b/core/services/telemetry/monitoring_endpoint_generator_mock.go new file mode 100644 index 0000000000..a0fc503ecc --- /dev/null +++ b/core/services/telemetry/monitoring_endpoint_generator_mock.go @@ -0,0 +1,88 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package telemetry + +import ( + commontypes "github.com/smartcontractkit/libocr/commontypes" + mock "github.com/stretchr/testify/mock" + + synchronization "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" +) + +// MockMonitoringEndpointGenerator is an autogenerated mock type for the MonitoringEndpointGenerator type +type MockMonitoringEndpointGenerator struct { + mock.Mock +} + +type MockMonitoringEndpointGenerator_Expecter struct { + mock *mock.Mock +} + +func (_m *MockMonitoringEndpointGenerator) EXPECT() *MockMonitoringEndpointGenerator_Expecter { + return &MockMonitoringEndpointGenerator_Expecter{mock: &_m.Mock} +} + +// GenMonitoringEndpoint provides a mock function with given fields: network, chainID, contractID, telemType +func (_m *MockMonitoringEndpointGenerator) GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) commontypes.MonitoringEndpoint { + ret := _m.Called(network, chainID, contractID, telemType) + + if len(ret) == 0 { + panic("no return value specified for GenMonitoringEndpoint") + } + + var r0 commontypes.MonitoringEndpoint + if rf, ok := ret.Get(0).(func(string, string, string, synchronization.TelemetryType) commontypes.MonitoringEndpoint); ok { + r0 = rf(network, chainID, contractID, telemType) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(commontypes.MonitoringEndpoint) + } + } + + return r0 +} + +// MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GenMonitoringEndpoint' +type MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call struct { + *mock.Call +} + +// GenMonitoringEndpoint is a helper method to define mock.On call +// - network string +// - chainID string +// - contractID string +// - telemType synchronization.TelemetryType +func (_e *MockMonitoringEndpointGenerator_Expecter) GenMonitoringEndpoint(network interface{}, chainID interface{}, contractID interface{}, telemType interface{}) *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call { + return &MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call{Call: _e.mock.On("GenMonitoringEndpoint", network, chainID, contractID, telemType)} +} + +func (_c *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call) Run(run func(network string, chainID string, contractID string, telemType synchronization.TelemetryType)) *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string), args[2].(string), args[3].(synchronization.TelemetryType)) + }) + return _c +} + +func (_c *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call) Return(_a0 commontypes.MonitoringEndpoint) *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call) RunAndReturn(run func(string, string, string, synchronization.TelemetryType) commontypes.MonitoringEndpoint) *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call { + _c.Call.Return(run) + return _c +} + +// NewMockMonitoringEndpointGenerator creates a new instance of MockMonitoringEndpointGenerator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockMonitoringEndpointGenerator(t interface { + mock.TestingT + Cleanup(func()) +}) *MockMonitoringEndpointGenerator { + mock := &MockMonitoringEndpointGenerator{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/web/testdata/body/health.html b/core/web/testdata/body/health.html index 90d301bc8b..d2b6db906b 100644 --- a/core/web/testdata/body/health.html +++ b/core/web/testdata/body/health.html @@ -72,6 +72,9 @@

    +
    + HeadReporter +
    JobSpawner
    @@ -99,9 +102,6 @@ BridgeCache -
    - PromReporter -
    TelemetryManager
    diff --git a/core/web/testdata/body/health.json b/core/web/testdata/body/health.json index 839428a510..81ed7ff6d1 100644 --- a/core/web/testdata/body/health.json +++ b/core/web/testdata/body/health.json @@ -108,6 +108,15 @@ "output": "" } }, + { + "type": "checks", + "id": "HeadReporter", + "attributes": { + "name": "HeadReporter", + "status": "passing", + "output": "" + } + }, { "type": "checks", "id": "JobSpawner", @@ -171,15 +180,6 @@ "output": "" } }, - { - "type": "checks", - "id": "PromReporter", - "attributes": { - "name": "PromReporter", - "status": "passing", - "output": "" - } - }, { "type": "checks", "id": "TelemetryManager", diff --git a/core/web/testdata/body/health.txt b/core/web/testdata/body/health.txt index 3709b4e15f..6b165d26d9 100644 --- a/core/web/testdata/body/health.txt +++ b/core/web/testdata/body/health.txt @@ -11,6 +11,7 @@ ok EVM.0.Txm.Broadcaster ok EVM.0.Txm.Confirmer ok EVM.0.Txm.Finalizer ok EVM.0.Txm.WrappedEvmEstimator +ok HeadReporter ok JobSpawner ok Mailbox.Monitor ok Mercury.WSRPCPool @@ -18,5 +19,4 @@ ok Mercury.WSRPCPool.CacheSet ok PipelineORM ok PipelineRunner ok PipelineRunner.BridgeCache -ok PromReporter ok TelemetryManager diff --git a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml index 88ca12975f..860c0c158b 100644 --- a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml +++ b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml @@ -19,6 +19,7 @@ MaxSize = '0b' [WebServer] AllowOrigins = '*' HTTPPort = 6688 +HTTPWriteTimeout = '1m0s' SecureCookies = false [WebServer.RateLimit] diff --git a/testdata/scripts/health/default.txtar b/testdata/scripts/health/default.txtar index 1dbf6b8eb9..777d3e5e12 100644 --- a/testdata/scripts/health/default.txtar +++ b/testdata/scripts/health/default.txtar @@ -31,6 +31,7 @@ fj293fbBnlQ!f9vNs HTTPPort = $PORT -- out.txt -- +ok HeadReporter ok JobSpawner ok Mailbox.Monitor ok Mercury.WSRPCPool @@ -38,12 +39,20 @@ ok Mercury.WSRPCPool.CacheSet ok PipelineORM ok PipelineRunner ok PipelineRunner.BridgeCache -ok PromReporter ok TelemetryManager -- out.json -- { "data": [ + { + "type": "checks", + "id": "HeadReporter", + "attributes": { + "name": "HeadReporter", + "status": "passing", + "output": "" + } + }, { "type": "checks", "id": "JobSpawner", @@ -107,15 +116,6 @@ ok TelemetryManager "output": "" } }, - { - "type": "checks", - "id": "PromReporter", - "attributes": { - "name": "PromReporter", - "status": "passing", - "output": "" - } - }, { "type": "checks", "id": "TelemetryManager", diff --git a/testdata/scripts/health/multi-chain.txtar b/testdata/scripts/health/multi-chain.txtar index 76937329cb..bba3b3e111 100644 --- a/testdata/scripts/health/multi-chain.txtar +++ b/testdata/scripts/health/multi-chain.txtar @@ -84,6 +84,7 @@ ok EVM.1.Txm.Broadcaster ok EVM.1.Txm.Confirmer ok EVM.1.Txm.Finalizer ok EVM.1.Txm.WrappedEvmEstimator +ok HeadReporter ok JobSpawner ok Mailbox.Monitor ok Mercury.WSRPCPool @@ -91,7 +92,6 @@ ok Mercury.WSRPCPool.CacheSet ok PipelineORM ok PipelineRunner ok PipelineRunner.BridgeCache -ok PromReporter ok Solana.Bar ok StarkNet.Baz ok TelemetryManager @@ -238,6 +238,15 @@ ok TelemetryManager "output": "" } }, + { + "type": "checks", + "id": "HeadReporter", + "attributes": { + "name": "HeadReporter", + "status": "passing", + "output": "" + } + }, { "type": "checks", "id": "JobSpawner", @@ -301,15 +310,6 @@ ok TelemetryManager "output": "" } }, - { - "type": "checks", - "id": "PromReporter", - "attributes": { - "name": "PromReporter", - "status": "passing", - "output": "" - } - }, { "type": "checks", "id": "Solana.Bar", From c92a7212ee77b08c40d62925216e5081278a4e3f Mon Sep 17 00:00:00 2001 From: Vyzaldy Sanchez Date: Thu, 15 Aug 2024 10:22:27 -0400 Subject: [PATCH 096/432] Add Db syncing for registry syncer (#13756) * Adds migration for syncer state data * Implements syncer ORM * Implements syncing with local registry and properly updating it * Fixes db sync channel * Connects DB to syncer constructor * Adds changeset * Fixes changeset * Uses custom marshal JSON call on DB store call * Fixes errors from merge conflicts * Fixes existing tests * Prevents tests from hanging * Fixes lint issue * Fixes setup on `New()` call * Implements marshal/unnmarshal mechanics on syncer state * Fixes migration name * Fixes lint * Keeps the latest 10 records on `registry_syncer_states` * Adds ORM tests * Prevents possible flake * Fixes errors from conflict * Fixes syncer tests * Fixes syncer ORM tests * Fixes linter * Fixes tests * Fixes tests * Review changes * Fixes tests * Fixes lint * Improves implementation * Removes unused `to32Byte` func * fixes errors on `Close()` * Adds more custom types to avoid data races * Update tests * fixes lint * Removes unnecessary comments * Sends deep copy of local registry to launchers * Fixes linter * Uses interface for syncer ORM * Mocks the ORM for tests * Improves `syncer.Close()` mechanism * Fixes merge conflicts * Fixes test * Fixes linter * Fixes race condition with `syncer.reader` * Fixes race condition in test * Fixes race condition in test * Fixes test --------- Co-authored-by: Bolek <1416262+bolekk@users.noreply.github.com> --- .changeset/many-knives-play.md | 5 + .mockery.yaml | 5 +- core/capabilities/ccip/delegate.go | 2 + .../ccip/launcher/integration_test.go | 3 + core/services/chainlink/application.go | 1 + .../services/registrysyncer/local_registry.go | 16 ++ core/services/registrysyncer/mocks/orm.go | 142 ++++++++++++ core/services/registrysyncer/orm.go | 167 ++++++++++++++ core/services/registrysyncer/orm_test.go | 145 ++++++++++++ core/services/registrysyncer/syncer.go | 170 +++++++++++++-- core/services/registrysyncer/syncer_test.go | 206 ++++++++++++++++-- .../migrations/0249_registry_syncer_state.sql | 11 + 12 files changed, 837 insertions(+), 36 deletions(-) create mode 100644 .changeset/many-knives-play.md create mode 100644 core/services/registrysyncer/mocks/orm.go create mode 100644 core/services/registrysyncer/orm.go create mode 100644 core/services/registrysyncer/orm_test.go create mode 100644 core/store/migrate/migrations/0249_registry_syncer_state.sql diff --git a/.changeset/many-knives-play.md b/.changeset/many-knives-play.md new file mode 100644 index 0000000000..8c1f5da1a4 --- /dev/null +++ b/.changeset/many-knives-play.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#updated Adds DB syncing for registry syncer diff --git a/.mockery.yaml b/.mockery.yaml index 37cbff58b1..87c27cd46a 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -570,4 +570,7 @@ packages: interfaces: Reader: config: - mockname: "Mock{{ .InterfaceName }}" \ No newline at end of file + mockname: "Mock{{ .InterfaceName }}" + github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer: + interfaces: + ORM: \ No newline at end of file diff --git a/core/capabilities/ccip/delegate.go b/core/capabilities/ccip/delegate.go index c9974d62e9..187ae0c581 100644 --- a/core/capabilities/ccip/delegate.go +++ b/core/capabilities/ccip/delegate.go @@ -6,6 +6,7 @@ import ( "time" "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/common" configsevm "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/configs/evm" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/launcher" @@ -119,6 +120,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services }, relayer, cfg.ExternalRegistry().Address(), + registrysyncer.NewORM(d.ds, d.lggr), ) if err != nil { return nil, fmt.Errorf("could not configure syncer: %w", err) diff --git a/core/capabilities/ccip/launcher/integration_test.go b/core/capabilities/ccip/launcher/integration_test.go index db3daf4d9b..7973316b31 100644 --- a/core/capabilities/ccip/launcher/integration_test.go +++ b/core/capabilities/ccip/launcher/integration_test.go @@ -6,6 +6,7 @@ import ( it "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccip_integration_tests/integrationhelpers" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" "github.com/onsi/gomega" @@ -30,12 +31,14 @@ func TestIntegration_Launcher(t *testing.T) { p2pIDs := it.P2pIDsFromInts(arr) uni.AddCapability(p2pIDs) + db := pgtest.NewSqlxDB(t) regSyncer, err := registrysyncer.New(lggr, func() (p2ptypes.PeerID, error) { return p2pIDs[0], nil }, uni, uni.CapReg.Address().String(), + registrysyncer.NewORM(db, lggr), ) require.NoError(t, err) diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 98067821f9..a3f46fc8a9 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -241,6 +241,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { }, relayer, registryAddress, + registrysyncer.NewORM(opts.DS, globalLogger), ) if err != nil { return nil, fmt.Errorf("could not configure syncer: %w", err) diff --git a/core/services/registrysyncer/local_registry.go b/core/services/registrysyncer/local_registry.go index 8a0e471ccd..d4bf4a49f5 100644 --- a/core/services/registrysyncer/local_registry.go +++ b/core/services/registrysyncer/local_registry.go @@ -36,6 +36,22 @@ type LocalRegistry struct { IDsToCapabilities map[string]Capability } +func NewLocalRegistry( + lggr logger.Logger, + getPeerID func() (p2ptypes.PeerID, error), + IDsToDONs map[DonID]DON, + IDsToNodes map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo, + IDsToCapabilities map[string]Capability, +) LocalRegistry { + return LocalRegistry{ + lggr: lggr.Named("LocalRegistry"), + getPeerID: getPeerID, + IDsToDONs: IDsToDONs, + IDsToNodes: IDsToNodes, + IDsToCapabilities: IDsToCapabilities, + } +} + func (l *LocalRegistry) LocalNode(ctx context.Context) (capabilities.Node, error) { // Load the current nodes PeerWrapper, this gets us the current node's // PeerID, allowing us to contextualize registry information in terms of DON ownership diff --git a/core/services/registrysyncer/mocks/orm.go b/core/services/registrysyncer/mocks/orm.go new file mode 100644 index 0000000000..d7777ecb6e --- /dev/null +++ b/core/services/registrysyncer/mocks/orm.go @@ -0,0 +1,142 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + registrysyncer "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" + mock "github.com/stretchr/testify/mock" +) + +// ORM is an autogenerated mock type for the ORM type +type ORM struct { + mock.Mock +} + +type ORM_Expecter struct { + mock *mock.Mock +} + +func (_m *ORM) EXPECT() *ORM_Expecter { + return &ORM_Expecter{mock: &_m.Mock} +} + +// AddLocalRegistry provides a mock function with given fields: ctx, localRegistry +func (_m *ORM) AddLocalRegistry(ctx context.Context, localRegistry registrysyncer.LocalRegistry) error { + ret := _m.Called(ctx, localRegistry) + + if len(ret) == 0 { + panic("no return value specified for AddLocalRegistry") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, registrysyncer.LocalRegistry) error); ok { + r0 = rf(ctx, localRegistry) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ORM_AddLocalRegistry_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddLocalRegistry' +type ORM_AddLocalRegistry_Call struct { + *mock.Call +} + +// AddLocalRegistry is a helper method to define mock.On call +// - ctx context.Context +// - localRegistry registrysyncer.LocalRegistry +func (_e *ORM_Expecter) AddLocalRegistry(ctx interface{}, localRegistry interface{}) *ORM_AddLocalRegistry_Call { + return &ORM_AddLocalRegistry_Call{Call: _e.mock.On("AddLocalRegistry", ctx, localRegistry)} +} + +func (_c *ORM_AddLocalRegistry_Call) Run(run func(ctx context.Context, localRegistry registrysyncer.LocalRegistry)) *ORM_AddLocalRegistry_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(registrysyncer.LocalRegistry)) + }) + return _c +} + +func (_c *ORM_AddLocalRegistry_Call) Return(_a0 error) *ORM_AddLocalRegistry_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ORM_AddLocalRegistry_Call) RunAndReturn(run func(context.Context, registrysyncer.LocalRegistry) error) *ORM_AddLocalRegistry_Call { + _c.Call.Return(run) + return _c +} + +// LatestLocalRegistry provides a mock function with given fields: ctx +func (_m *ORM) LatestLocalRegistry(ctx context.Context) (*registrysyncer.LocalRegistry, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for LatestLocalRegistry") + } + + var r0 *registrysyncer.LocalRegistry + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*registrysyncer.LocalRegistry, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *registrysyncer.LocalRegistry); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*registrysyncer.LocalRegistry) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ORM_LatestLocalRegistry_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestLocalRegistry' +type ORM_LatestLocalRegistry_Call struct { + *mock.Call +} + +// LatestLocalRegistry is a helper method to define mock.On call +// - ctx context.Context +func (_e *ORM_Expecter) LatestLocalRegistry(ctx interface{}) *ORM_LatestLocalRegistry_Call { + return &ORM_LatestLocalRegistry_Call{Call: _e.mock.On("LatestLocalRegistry", ctx)} +} + +func (_c *ORM_LatestLocalRegistry_Call) Run(run func(ctx context.Context)) *ORM_LatestLocalRegistry_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *ORM_LatestLocalRegistry_Call) Return(_a0 *registrysyncer.LocalRegistry, _a1 error) *ORM_LatestLocalRegistry_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ORM_LatestLocalRegistry_Call) RunAndReturn(run func(context.Context) (*registrysyncer.LocalRegistry, error)) *ORM_LatestLocalRegistry_Call { + _c.Call.Return(run) + return _c +} + +// NewORM creates a new instance of ORM. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewORM(t interface { + mock.TestingT + Cleanup(func()) +}) *ORM { + mock := &ORM{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/registrysyncer/orm.go b/core/services/registrysyncer/orm.go new file mode 100644 index 0000000000..cb08eaafea --- /dev/null +++ b/core/services/registrysyncer/orm.go @@ -0,0 +1,167 @@ +package registrysyncer + +import ( + "context" + "crypto/sha256" + "encoding/json" + "fmt" + "math/big" + + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/logger" + p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" +) + +type capabilitiesRegistryNodeInfo struct { + NodeOperatorId uint32 `json:"nodeOperatorId"` + ConfigCount uint32 `json:"configCount"` + WorkflowDONId uint32 `json:"workflowDONId"` + Signer p2ptypes.PeerID `json:"signer"` + P2pId p2ptypes.PeerID `json:"p2pId"` + HashedCapabilityIds []p2ptypes.PeerID `json:"hashedCapabilityIds"` + CapabilitiesDONIds []string `json:"capabilitiesDONIds"` +} + +func (l *LocalRegistry) MarshalJSON() ([]byte, error) { + idsToNodes := make(map[p2ptypes.PeerID]capabilitiesRegistryNodeInfo) + for k, v := range l.IDsToNodes { + hashedCapabilityIds := make([]p2ptypes.PeerID, len(v.HashedCapabilityIds)) + for i, id := range v.HashedCapabilityIds { + hashedCapabilityIds[i] = p2ptypes.PeerID(id[:]) + } + capabilitiesDONIds := make([]string, len(v.CapabilitiesDONIds)) + for i, id := range v.CapabilitiesDONIds { + capabilitiesDONIds[i] = id.String() + } + idsToNodes[k] = capabilitiesRegistryNodeInfo{ + NodeOperatorId: v.NodeOperatorId, + ConfigCount: v.ConfigCount, + WorkflowDONId: v.WorkflowDONId, + Signer: p2ptypes.PeerID(v.Signer[:]), + P2pId: p2ptypes.PeerID(v.P2pId[:]), + HashedCapabilityIds: hashedCapabilityIds, + CapabilitiesDONIds: capabilitiesDONIds, + } + } + + b, err := json.Marshal(&struct { + IDsToDONs map[DonID]DON + IDsToNodes map[p2ptypes.PeerID]capabilitiesRegistryNodeInfo + IDsToCapabilities map[string]Capability + }{ + IDsToDONs: l.IDsToDONs, + IDsToNodes: idsToNodes, + IDsToCapabilities: l.IDsToCapabilities, + }) + if err != nil { + return []byte{}, err + } + return b, nil +} + +func (l *LocalRegistry) UnmarshalJSON(data []byte) error { + temp := struct { + IDsToDONs map[DonID]DON + IDsToNodes map[p2ptypes.PeerID]capabilitiesRegistryNodeInfo + IDsToCapabilities map[string]Capability + }{ + IDsToDONs: make(map[DonID]DON), + IDsToNodes: make(map[p2ptypes.PeerID]capabilitiesRegistryNodeInfo), + IDsToCapabilities: make(map[string]Capability), + } + + if err := json.Unmarshal(data, &temp); err != nil { + return fmt.Errorf("failed to unmarshal state: %w", err) + } + + l.IDsToDONs = temp.IDsToDONs + + l.IDsToNodes = make(map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo) + for peerID, v := range temp.IDsToNodes { + hashedCapabilityIds := make([][32]byte, len(v.HashedCapabilityIds)) + for i, id := range v.HashedCapabilityIds { + copy(hashedCapabilityIds[i][:], id[:]) + } + + capabilitiesDONIds := make([]*big.Int, len(v.CapabilitiesDONIds)) + for i, id := range v.CapabilitiesDONIds { + bigInt := new(big.Int) + bigInt.SetString(id, 10) + capabilitiesDONIds[i] = bigInt + } + l.IDsToNodes[peerID] = kcr.CapabilitiesRegistryNodeInfo{ + NodeOperatorId: v.NodeOperatorId, + ConfigCount: v.ConfigCount, + WorkflowDONId: v.WorkflowDONId, + Signer: v.Signer, + P2pId: v.P2pId, + HashedCapabilityIds: hashedCapabilityIds, + CapabilitiesDONIds: capabilitiesDONIds, + } + } + + l.IDsToCapabilities = temp.IDsToCapabilities + + return nil +} + +type ORM interface { + AddLocalRegistry(ctx context.Context, localRegistry LocalRegistry) error + LatestLocalRegistry(ctx context.Context) (*LocalRegistry, error) +} + +type orm struct { + ds sqlutil.DataSource + lggr logger.Logger +} + +var _ ORM = (*orm)(nil) + +func NewORM(ds sqlutil.DataSource, lggr logger.Logger) orm { + namedLogger := lggr.Named("RegistrySyncerORM") + return orm{ + ds: ds, + lggr: namedLogger, + } +} + +func (orm orm) AddLocalRegistry(ctx context.Context, localRegistry LocalRegistry) error { + return sqlutil.TransactDataSource(ctx, orm.ds, nil, func(tx sqlutil.DataSource) error { + localRegistryJSON, err := localRegistry.MarshalJSON() + if err != nil { + return err + } + hash := sha256.Sum256(localRegistryJSON) + _, err = tx.ExecContext( + ctx, + `INSERT INTO registry_syncer_states (data, data_hash) VALUES ($1, $2) ON CONFLICT (data_hash) DO NOTHING`, + localRegistryJSON, fmt.Sprintf("%x", hash[:]), + ) + if err != nil { + return err + } + _, err = tx.ExecContext(ctx, `DELETE FROM registry_syncer_states +WHERE data_hash NOT IN ( + SELECT data_hash FROM registry_syncer_states + ORDER BY id DESC + LIMIT 10 +);`) + return err + }) +} + +func (orm orm) LatestLocalRegistry(ctx context.Context) (*LocalRegistry, error) { + var localRegistry LocalRegistry + var localRegistryJSON string + err := orm.ds.GetContext(ctx, &localRegistryJSON, `SELECT data FROM registry_syncer_states ORDER BY id DESC LIMIT 1`) + if err != nil { + return nil, err + } + err = localRegistry.UnmarshalJSON([]byte(localRegistryJSON)) + if err != nil { + return nil, err + } + return &localRegistry, nil +} diff --git a/core/services/registrysyncer/orm_test.go b/core/services/registrysyncer/orm_test.go new file mode 100644 index 0000000000..03772ea22b --- /dev/null +++ b/core/services/registrysyncer/orm_test.go @@ -0,0 +1,145 @@ +package registrysyncer_test + +import ( + "encoding/hex" + "math/big" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/durationpb" + + ragetypes "github.com/smartcontractkit/libocr/ragep2p/types" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" + "github.com/smartcontractkit/chainlink-common/pkg/values" + + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" + "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" +) + +func TestRegistrySyncerORM_InsertAndRetrieval(t *testing.T) { + db := pgtest.NewSqlxDB(t) + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + orm := registrysyncer.NewORM(db, lggr) + + var states []registrysyncer.LocalRegistry + for i := 0; i < 11; i++ { + state := generateState(t) + err := orm.AddLocalRegistry(ctx, state) + require.NoError(t, err) + states = append(states, state) + } + + var count int + err := db.Get(&count, `SELECT count(*) FROM registry_syncer_states`) + require.NoError(t, err) + assert.Equal(t, 10, count) + + state, err := orm.LatestLocalRegistry(ctx) + require.NoError(t, err) + assert.Equal(t, states[10], *state) +} + +func generateState(t *testing.T) registrysyncer.LocalRegistry { + dID := uint32(1) + var pid ragetypes.PeerID + err := pid.UnmarshalText([]byte("12D3KooWBCF1XT5Wi8FzfgNCqRL76Swv8TRU3TiD4QiJm8NMNX7N")) + require.NoError(t, err) + nodes := [][32]byte{ + pid, + randomWord(), + randomWord(), + randomWord(), + } + capabilityID := randomWord() + capabilityID2 := randomWord() + capabilityIDStr := hex.EncodeToString(capabilityID[:]) + capabilityID2Str := hex.EncodeToString(capabilityID2[:]) + + config := &capabilitiespb.CapabilityConfig{ + DefaultConfig: values.Proto(values.EmptyMap()).GetMapValue(), + RemoteConfig: &capabilitiespb.CapabilityConfig_RemoteTriggerConfig{ + RemoteTriggerConfig: &capabilitiespb.RemoteTriggerConfig{ + RegistrationRefresh: durationpb.New(20 * time.Second), + RegistrationExpiry: durationpb.New(60 * time.Second), + // F + 1 + MinResponsesToAggregate: uint32(1) + 1, + MessageExpiry: durationpb.New(120 * time.Second), + }, + }, + } + configb, err := proto.Marshal(config) + require.NoError(t, err) + + return registrysyncer.LocalRegistry{ + IDsToDONs: map[registrysyncer.DonID]registrysyncer.DON{ + registrysyncer.DonID(dID): { + DON: capabilities.DON{ + ID: dID, + ConfigVersion: uint32(0), + F: uint8(1), + IsPublic: true, + AcceptsWorkflows: true, + Members: toPeerIDs(nodes), + }, + CapabilityConfigurations: map[string]registrysyncer.CapabilityConfiguration{ + capabilityIDStr: { + Config: configb, + }, + capabilityID2Str: { + Config: configb, + }, + }, + }, + }, + IDsToCapabilities: map[string]registrysyncer.Capability{ + capabilityIDStr: { + ID: capabilityIDStr, + CapabilityType: capabilities.CapabilityTypeAction, + }, + capabilityID2Str: { + ID: capabilityID2Str, + CapabilityType: capabilities.CapabilityTypeConsensus, + }, + }, + IDsToNodes: map[types.PeerID]kcr.CapabilitiesRegistryNodeInfo{ + nodes[0]: { + NodeOperatorId: 1, + Signer: randomWord(), + P2pId: nodes[0], + HashedCapabilityIds: [][32]byte{capabilityID, capabilityID2}, + CapabilitiesDONIds: []*big.Int{}, + }, + nodes[1]: { + NodeOperatorId: 1, + Signer: randomWord(), + P2pId: nodes[1], + HashedCapabilityIds: [][32]byte{capabilityID, capabilityID2}, + CapabilitiesDONIds: []*big.Int{}, + }, + nodes[2]: { + NodeOperatorId: 1, + Signer: randomWord(), + P2pId: nodes[2], + HashedCapabilityIds: [][32]byte{capabilityID, capabilityID2}, + CapabilitiesDONIds: []*big.Int{}, + }, + nodes[3]: { + NodeOperatorId: 1, + Signer: randomWord(), + P2pId: nodes[3], + HashedCapabilityIds: [][32]byte{capabilityID, capabilityID2}, + CapabilitiesDONIds: []*big.Int{}, + }, + }, + } +} diff --git a/core/services/registrysyncer/syncer.go b/core/services/registrysyncer/syncer.go index a83e0102af..ab50c448b5 100644 --- a/core/services/registrysyncer/syncer.go +++ b/core/services/registrysyncer/syncer.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "math/big" "sync" "time" @@ -27,16 +28,34 @@ type Syncer interface { AddLauncher(h ...Launcher) } +type ContractReaderFactory interface { + NewContractReader(context.Context, []byte) (types.ContractReader, error) +} + +type RegistrySyncer interface { + Sync(ctx context.Context, isInitialSync bool) error + AddLauncher(launchers ...Launcher) + Start(ctx context.Context) error + Close() error + Ready() error + HealthReport() map[string]error + Name() string +} + type registrySyncer struct { services.StateMachine stopCh services.StopChan launchers []Launcher reader types.ContractReader - initReader func(ctx context.Context, lggr logger.Logger, relayer contractReaderFactory, registryAddress string) (types.ContractReader, error) - relayer contractReaderFactory + initReader func(ctx context.Context, lggr logger.Logger, relayer ContractReaderFactory, registryAddress string) (types.ContractReader, error) + relayer ContractReaderFactory registryAddress string getPeerID func() (p2ptypes.PeerID, error) + orm ORM + + updateChan chan *LocalRegistry + wg sync.WaitGroup lggr logger.Logger mu sync.RWMutex @@ -52,28 +71,26 @@ var ( func New( lggr logger.Logger, getPeerID func() (p2ptypes.PeerID, error), - relayer contractReaderFactory, + relayer ContractReaderFactory, registryAddress string, -) (*registrySyncer, error) { - stopCh := make(services.StopChan) + orm ORM, +) (RegistrySyncer, error) { return ®istrySyncer{ - stopCh: stopCh, + stopCh: make(services.StopChan), + updateChan: make(chan *LocalRegistry), lggr: lggr.Named("RegistrySyncer"), relayer: relayer, registryAddress: registryAddress, initReader: newReader, + orm: orm, getPeerID: getPeerID, }, nil } -type contractReaderFactory interface { - NewContractReader(context.Context, []byte) (types.ContractReader, error) -} - // NOTE: this can't be called while initializing the syncer and needs to be called in the sync loop. // This is because Bind() makes an onchain call to verify that the contract address exists, and if // called during initialization, this results in a "no live nodes" error. -func newReader(ctx context.Context, lggr logger.Logger, relayer contractReaderFactory, remoteRegistryAddress string) (types.ContractReader, error) { +func newReader(ctx context.Context, lggr logger.Logger, relayer ContractReaderFactory, remoteRegistryAddress string) (types.ContractReader, error) { contractReaderConfig := evmrelaytypes.ChainReaderConfig{ Contracts: map[string]evmrelaytypes.ChainContractReader{ "CapabilitiesRegistry": { @@ -120,6 +137,11 @@ func (s *registrySyncer) Start(ctx context.Context) error { defer s.wg.Done() s.syncLoop() }() + s.wg.Add(1) + go func() { + defer s.wg.Done() + s.updateStateLoop() + }() return nil }) } @@ -135,7 +157,7 @@ func (s *registrySyncer) syncLoop() { // sync immediately once spinning up syncLoop, as by default a ticker will // fire for the first time at T+N, where N is the interval. s.lggr.Debug("starting initial sync with remote registry") - err := s.sync(ctx) + err := s.Sync(ctx, true) if err != nil { s.lggr.Errorw("failed to sync with remote registry", "error", err) } @@ -146,7 +168,7 @@ func (s *registrySyncer) syncLoop() { return case <-ticker.C: s.lggr.Debug("starting regular sync with the remote registry") - err := s.sync(ctx) + err := s.Sync(ctx, false) if err != nil { s.lggr.Errorw("failed to sync with remote registry", "error", err) } @@ -154,8 +176,28 @@ func (s *registrySyncer) syncLoop() { } } +func (s *registrySyncer) updateStateLoop() { + ctx, cancel := s.stopCh.NewCtx() + defer cancel() + + for { + select { + case <-s.stopCh: + return + case localRegistry, ok := <-s.updateChan: + if !ok { + // channel has been closed, terminating. + return + } + if err := s.orm.AddLocalRegistry(ctx, *localRegistry); err != nil { + s.lggr.Errorw("failed to save state to local registry", "error", err) + } + } + } +} + func (s *registrySyncer) localRegistry(ctx context.Context) (*LocalRegistry, error) { - caps := []kcr.CapabilitiesRegistryCapabilityInfo{} + var caps []kcr.CapabilitiesRegistryCapabilityInfo err := s.reader.GetLatestValue(ctx, "CapabilitiesRegistry", "getCapabilities", primitives.Unconfirmed, nil, &caps) if err != nil { return nil, err @@ -173,7 +215,7 @@ func (s *registrySyncer) localRegistry(ctx context.Context) (*LocalRegistry, err hashedIDsToCapabilityIDs[c.HashedId] = cid } - dons := []kcr.CapabilitiesRegistryDONInfo{} + var dons []kcr.CapabilitiesRegistryDONInfo err = s.reader.GetLatestValue(ctx, "CapabilitiesRegistry", "getDONs", primitives.Unconfirmed, nil, &dons) if err != nil { return nil, err @@ -199,7 +241,7 @@ func (s *registrySyncer) localRegistry(ctx context.Context) (*LocalRegistry, err } } - nodes := []kcr.CapabilitiesRegistryNodeInfo{} + var nodes []kcr.CapabilitiesRegistryNodeInfo err = s.reader.GetLatestValue(ctx, "CapabilitiesRegistry", "getNodes", primitives.Unconfirmed, nil, &nodes) if err != nil { return nil, err @@ -219,7 +261,7 @@ func (s *registrySyncer) localRegistry(ctx context.Context) (*LocalRegistry, err }, nil } -func (s *registrySyncer) sync(ctx context.Context) error { +func (s *registrySyncer) Sync(ctx context.Context, isInitialSync bool) error { s.mu.RLock() defer s.mu.RUnlock() @@ -237,13 +279,44 @@ func (s *registrySyncer) sync(ctx context.Context) error { s.reader = reader } - lr, err := s.localRegistry(ctx) - if err != nil { - return fmt.Errorf("failed to sync with remote registry: %w", err) + var lr *LocalRegistry + var err error + + if isInitialSync { + s.lggr.Debug("syncing with local registry") + lr, err = s.orm.LatestLocalRegistry(ctx) + if err != nil { + s.lggr.Warnw("failed to sync with local registry, using remote registry instead", "error", err) + } else { + lr.lggr = s.lggr + lr.getPeerID = s.getPeerID + } + } + + if lr == nil { + s.lggr.Debug("syncing with remote registry") + localRegistry, err := s.localRegistry(ctx) + if err != nil { + return fmt.Errorf("failed to sync with remote registry: %w", err) + } + lr = localRegistry + // Attempt to send local registry to the update channel without blocking + // This is to prevent the tests from hanging if they are not calling `Start()` on the syncer + select { + case <-s.stopCh: + s.lggr.Debug("sync cancelled, stopping") + case s.updateChan <- lr: + // Successfully sent state + s.lggr.Debug("remote registry update triggered successfully") + default: + // No one is ready to receive the state, handle accordingly + s.lggr.Debug("no listeners on update channel, remote registry update skipped") + } } for _, h := range s.launchers { - if err := h.Launch(ctx, lr); err != nil { + lrCopy := deepCopyLocalRegistry(lr) + if err := h.Launch(ctx, &lrCopy); err != nil { s.lggr.Errorf("error calling launcher: %s", err) } } @@ -251,6 +324,58 @@ func (s *registrySyncer) sync(ctx context.Context) error { return nil } +func deepCopyLocalRegistry(lr *LocalRegistry) LocalRegistry { + var lrCopy LocalRegistry + lrCopy.lggr = lr.lggr + lrCopy.getPeerID = lr.getPeerID + lrCopy.IDsToDONs = make(map[DonID]DON, len(lr.IDsToDONs)) + for id, don := range lr.IDsToDONs { + d := capabilities.DON{ + ID: don.ID, + ConfigVersion: don.ConfigVersion, + Members: make([]p2ptypes.PeerID, len(don.Members)), + F: don.F, + IsPublic: don.IsPublic, + AcceptsWorkflows: don.AcceptsWorkflows, + } + copy(d.Members, don.Members) + capCfgs := make(map[string]CapabilityConfiguration, len(don.CapabilityConfigurations)) + for capID, capCfg := range don.CapabilityConfigurations { + capCfgs[capID] = CapabilityConfiguration{ + Config: capCfg.Config[:], + } + } + lrCopy.IDsToDONs[id] = DON{ + DON: d, + CapabilityConfigurations: capCfgs, + } + } + + lrCopy.IDsToCapabilities = make(map[string]Capability, len(lr.IDsToCapabilities)) + for id, capability := range lr.IDsToCapabilities { + cp := capability + lrCopy.IDsToCapabilities[id] = cp + } + + lrCopy.IDsToNodes = make(map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo, len(lr.IDsToNodes)) + for id, node := range lr.IDsToNodes { + nodeInfo := kcr.CapabilitiesRegistryNodeInfo{ + NodeOperatorId: node.NodeOperatorId, + ConfigCount: node.ConfigCount, + WorkflowDONId: node.WorkflowDONId, + Signer: node.Signer, + P2pId: node.P2pId, + HashedCapabilityIds: make([][32]byte, len(node.HashedCapabilityIds)), + CapabilitiesDONIds: make([]*big.Int, len(node.CapabilitiesDONIds)), + } + copy(nodeInfo.HashedCapabilityIds, node.HashedCapabilityIds) + copy(nodeInfo.CapabilitiesDONIds, node.CapabilitiesDONIds) + lrCopy.IDsToNodes[id] = nodeInfo + } + + return lrCopy +} + func toCapabilityType(capabilityType uint8) capabilities.CapabilityType { switch capabilityType { case 0: @@ -291,6 +416,9 @@ func (s *registrySyncer) AddLauncher(launchers ...Launcher) { func (s *registrySyncer) Close() error { return s.StopOnce("RegistrySyncer", func() error { close(s.stopCh) + s.mu.Lock() + defer s.mu.Unlock() + close(s.updateChan) s.wg.Wait() return nil }) diff --git a/core/services/registrysyncer/syncer_test.go b/core/services/registrysyncer/syncer_test.go index cd8776d882..2c08a1cdde 100644 --- a/core/services/registrysyncer/syncer_test.go +++ b/core/services/registrysyncer/syncer_test.go @@ -1,4 +1,4 @@ -package registrysyncer +package registrysyncer_test import ( "context" @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "math/big" + "sync" "testing" "time" @@ -15,6 +16,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/durationpb" @@ -25,6 +27,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/values" capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" + evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -33,6 +36,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" + "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" + syncerMocks "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -126,16 +131,51 @@ func randomWord() [32]byte { } type launcher struct { - localRegistry *LocalRegistry + localRegistry *registrysyncer.LocalRegistry + mu sync.RWMutex } -func (l *launcher) Launch(ctx context.Context, localRegistry *LocalRegistry) error { +func (l *launcher) Launch(ctx context.Context, localRegistry *registrysyncer.LocalRegistry) error { + l.mu.Lock() + defer l.mu.Unlock() l.localRegistry = localRegistry return nil } +type orm struct { + ormMock *syncerMocks.ORM + latestLocalRegistryCh chan struct{} + addLocalRegistryCh chan struct{} +} + +func newORM(t *testing.T) *orm { + t.Helper() + + return &orm{ + ormMock: syncerMocks.NewORM(t), + latestLocalRegistryCh: make(chan struct{}, 1), + addLocalRegistryCh: make(chan struct{}, 1), + } +} + +func (o *orm) Cleanup() { + close(o.latestLocalRegistryCh) + close(o.addLocalRegistryCh) +} + +func (o *orm) AddLocalRegistry(ctx context.Context, localRegistry registrysyncer.LocalRegistry) error { + o.addLocalRegistryCh <- struct{}{} + err := o.ormMock.AddLocalRegistry(ctx, localRegistry) + return err +} + +func (o *orm) LatestLocalRegistry(ctx context.Context) (*registrysyncer.LocalRegistry, error) { + o.latestLocalRegistryCh <- struct{}{} + return o.ormMock.LatestLocalRegistry(ctx) +} + func toPeerIDs(ids [][32]byte) []p2ptypes.PeerID { - pids := []p2ptypes.PeerID{} + var pids []p2ptypes.PeerID for _, id := range ids { pids = append(pids, id) } @@ -236,20 +276,22 @@ func TestReader_Integration(t *testing.T) { require.NoError(t, err) + db := pgtest.NewSqlxDB(t) factory := newContractReaderFactory(t, sim) - syncer, err := New(logger.TestLogger(t), func() (p2ptypes.PeerID, error) { return p2ptypes.PeerID{}, nil }, factory, regAddress.Hex()) + syncerORM := registrysyncer.NewORM(db, logger.TestLogger(t)) + syncer, err := registrysyncer.New(logger.TestLogger(t), func() (p2ptypes.PeerID, error) { return p2ptypes.PeerID{}, nil }, factory, regAddress.Hex(), syncerORM) require.NoError(t, err) l := &launcher{} syncer.AddLauncher(l) - err = syncer.sync(ctx) + err = syncer.Sync(ctx, false) // not looking to load from the DB in this specific test. s := l.localRegistry require.NoError(t, err) assert.Len(t, s.IDsToCapabilities, 1) gotCap := s.IDsToCapabilities[cid] - assert.Equal(t, Capability{ + assert.Equal(t, registrysyncer.Capability{ CapabilityType: capabilities.CapabilityTypeTarget, ID: "write-chain@1.0.1", }, gotCap) @@ -308,6 +350,127 @@ func TestReader_Integration(t *testing.T) { }, s.IDsToNodes) } +func TestSyncer_DBIntegration(t *testing.T) { + ctx := testutils.Context(t) + reg, regAddress, owner, sim := startNewChainWithRegistry(t) + + _, err := reg.AddCapabilities(owner, []kcr.CapabilitiesRegistryCapability{writeChainCapability}) + require.NoError(t, err, "AddCapability failed for %s", writeChainCapability.LabelledName) + sim.Commit() + + cid, err := reg.GetHashedCapabilityId(&bind.CallOpts{}, writeChainCapability.LabelledName, writeChainCapability.Version) + require.NoError(t, err) + + _, err = reg.AddNodeOperators(owner, []kcr.CapabilitiesRegistryNodeOperator{ + { + Admin: owner.From, + Name: "TEST_NOP", + }, + }) + require.NoError(t, err) + + nodeSet := [][32]byte{ + randomWord(), + randomWord(), + randomWord(), + } + + signersSet := [][32]byte{ + randomWord(), + randomWord(), + randomWord(), + } + + nodes := []kcr.CapabilitiesRegistryNodeParams{ + { + // The first NodeOperatorId has id 1 since the id is auto-incrementing. + NodeOperatorId: uint32(1), + Signer: signersSet[0], + P2pId: nodeSet[0], + HashedCapabilityIds: [][32]byte{cid}, + }, + { + // The first NodeOperatorId has id 1 since the id is auto-incrementing. + NodeOperatorId: uint32(1), + Signer: signersSet[1], + P2pId: nodeSet[1], + HashedCapabilityIds: [][32]byte{cid}, + }, + { + // The first NodeOperatorId has id 1 since the id is auto-incrementing. + NodeOperatorId: uint32(1), + Signer: signersSet[2], + P2pId: nodeSet[2], + HashedCapabilityIds: [][32]byte{cid}, + }, + } + _, err = reg.AddNodes(owner, nodes) + require.NoError(t, err) + + config := &capabilitiespb.CapabilityConfig{ + DefaultConfig: values.Proto(values.EmptyMap()).GetMapValue(), + RemoteConfig: &capabilitiespb.CapabilityConfig_RemoteTriggerConfig{ + RemoteTriggerConfig: &capabilitiespb.RemoteTriggerConfig{ + RegistrationRefresh: durationpb.New(20 * time.Second), + RegistrationExpiry: durationpb.New(60 * time.Second), + // F + 1 + MinResponsesToAggregate: uint32(1) + 1, + }, + }, + } + configb, err := proto.Marshal(config) + require.NoError(t, err) + + cfgs := []kcr.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: cid, + Config: configb, + }, + } + _, err = reg.AddDON( + owner, + nodeSet, + cfgs, + true, + true, + 1, + ) + sim.Commit() + + require.NoError(t, err) + + factory := newContractReaderFactory(t, sim) + syncerORM := newORM(t) + syncerORM.ormMock.On("LatestLocalRegistry", mock.Anything).Return(nil, fmt.Errorf("no state found")) + syncerORM.ormMock.On("AddLocalRegistry", mock.Anything, mock.Anything).Return(nil) + syncer, err := newTestSyncer(logger.TestLogger(t), func() (p2ptypes.PeerID, error) { return p2ptypes.PeerID{}, nil }, factory, regAddress.Hex(), syncerORM) + require.NoError(t, err) + require.NoError(t, syncer.Start(ctx)) + t.Cleanup(func() { + syncerORM.Cleanup() + require.NoError(t, syncer.Close()) + }) + + l := &launcher{} + syncer.AddLauncher(l) + + var latestLocalRegistryCalled, addLocalRegistryCalled bool + timeout := time.After(500 * time.Millisecond) + + for !latestLocalRegistryCalled || !addLocalRegistryCalled { + select { + case val := <-syncerORM.latestLocalRegistryCh: + assert.Equal(t, struct{}{}, val) + latestLocalRegistryCalled = true + case val := <-syncerORM.addLocalRegistryCh: + assert.Equal(t, struct{}{}, val) + addLocalRegistryCalled = true + case <-timeout: + t.Fatal("test timed out; channels did not received data") + } + } +} + func TestSyncer_LocalNode(t *testing.T) { ctx := tests.Context(t) lggr := logger.TestLogger(t) @@ -327,11 +490,11 @@ func TestSyncer_LocalNode(t *testing.T) { // The below state describes a Workflow DON (AcceptsWorkflows = true), // which exposes the streams-trigger and write_chain capabilities. // We expect receivers to be wired up and both capabilities to be added to the registry. - localRegistry := LocalRegistry{ - lggr: lggr, - getPeerID: func() (p2ptypes.PeerID, error) { return pid, nil }, - IDsToDONs: map[DonID]DON{ - DonID(dID): { + localRegistry := registrysyncer.NewLocalRegistry( + lggr, + func() (p2ptypes.PeerID, error) { return pid, nil }, + map[registrysyncer.DonID]registrysyncer.DON{ + registrysyncer.DonID(dID): { DON: capabilities.DON{ ID: dID, ConfigVersion: uint32(2), @@ -342,7 +505,7 @@ func TestSyncer_LocalNode(t *testing.T) { }, }, }, - IDsToNodes: map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo{ + map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo{ workflowDonNodes[0]: { NodeOperatorId: 1, Signer: randomWord(), @@ -364,7 +527,8 @@ func TestSyncer_LocalNode(t *testing.T) { P2pId: workflowDonNodes[3], }, }, - } + map[string]registrysyncer.Capability{}, + ) node, err := localRegistry.LocalNode(ctx) require.NoError(t, err) @@ -384,3 +548,17 @@ func TestSyncer_LocalNode(t *testing.T) { } assert.Equal(t, expectedNode, node) } + +func newTestSyncer( + lggr logger.Logger, + getPeerID func() (p2ptypes.PeerID, error), + relayer registrysyncer.ContractReaderFactory, + registryAddress string, + orm *orm, +) (registrysyncer.RegistrySyncer, error) { + rs, err := registrysyncer.New(lggr, getPeerID, relayer, registryAddress, orm) + if err != nil { + return nil, err + } + return rs, nil +} diff --git a/core/store/migrate/migrations/0249_registry_syncer_state.sql b/core/store/migrate/migrations/0249_registry_syncer_state.sql new file mode 100644 index 0000000000..e34a3790a3 --- /dev/null +++ b/core/store/migrate/migrations/0249_registry_syncer_state.sql @@ -0,0 +1,11 @@ +-- +goose Up +CREATE TABLE registry_syncer_states ( + id SERIAL PRIMARY KEY, + data JSONB NOT NULL, + data_hash TEXT NOT NULL UNIQUE, + created_at TIMESTAMPTZ NOT NULL DEFAULT now() +); +-- +goose Down +-- +goose StatementBegin +DROP TABLE registry_syncer_states; +-- +goose StatementEnd From 1b584366d6bedc114946d0c8e202e95d031d5d37 Mon Sep 17 00:00:00 2001 From: Giorgio Gambino <151543+giogam@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:52:29 +0200 Subject: [PATCH 097/432] Updates feeds-manager noderpc proto (#14112) * update feeds-manager noderpc proto * add changesets * re-generate feeds-manager proto --- .changeset/flat-mirrors-confess.md | 5 + core/services/feeds/proto/feeds_manager.pb.go | 118 +++++++++--------- .../feeds/proto/feeds_manager_wsrpc.pb.go | 3 +- 3 files changed, 65 insertions(+), 61 deletions(-) create mode 100644 .changeset/flat-mirrors-confess.md diff --git a/.changeset/flat-mirrors-confess.md b/.changeset/flat-mirrors-confess.md new file mode 100644 index 0000000000..7c0a6a92a3 --- /dev/null +++ b/.changeset/flat-mirrors-confess.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#updated Sync feeds-manager wsrpc proto diff --git a/core/services/feeds/proto/feeds_manager.pb.go b/core/services/feeds/proto/feeds_manager.pb.go index 89f351a427..ee5bcef393 100644 --- a/core/services/feeds/proto/feeds_manager.pb.go +++ b/core/services/feeds/proto/feeds_manager.pb.go @@ -79,8 +79,7 @@ const ( ChainType_CHAIN_TYPE_UNSPECIFIED ChainType = 0 ChainType_CHAIN_TYPE_EVM ChainType = 1 ChainType_CHAIN_TYPE_SOLANA ChainType = 2 - ChainType_CHAIN_TYPE_ZKSYNC ChainType = 3 - ChainType_CHAIN_TYPE_STARKNET ChainType = 4 + ChainType_CHAIN_TYPE_STARKNET ChainType = 3 ) // Enum value maps for ChainType. @@ -89,15 +88,13 @@ var ( 0: "CHAIN_TYPE_UNSPECIFIED", 1: "CHAIN_TYPE_EVM", 2: "CHAIN_TYPE_SOLANA", - 3: "CHAIN_TYPE_ZKSYNC", - 4: "CHAIN_TYPE_STARKNET", + 3: "CHAIN_TYPE_STARKNET", } ChainType_value = map[string]int32{ "CHAIN_TYPE_UNSPECIFIED": 0, "CHAIN_TYPE_EVM": 1, "CHAIN_TYPE_SOLANA": 2, - "CHAIN_TYPE_ZKSYNC": 3, - "CHAIN_TYPE_STARKNET": 4, + "CHAIN_TYPE_STARKNET": 3, } ) @@ -476,13 +473,17 @@ type ChainConfig struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Chain *Chain `protobuf:"bytes,1,opt,name=chain,proto3" json:"chain,omitempty"` - AccountAddress string `protobuf:"bytes,2,opt,name=account_address,json=accountAddress,proto3" json:"account_address,omitempty"` - AdminAddress string `protobuf:"bytes,3,opt,name=admin_address,json=adminAddress,proto3" json:"admin_address,omitempty"` - FluxMonitorConfig *FluxMonitorConfig `protobuf:"bytes,4,opt,name=flux_monitor_config,json=fluxMonitorConfig,proto3" json:"flux_monitor_config,omitempty"` - Ocr1Config *OCR1Config `protobuf:"bytes,5,opt,name=ocr1_config,json=ocr1Config,proto3" json:"ocr1_config,omitempty"` - Ocr2Config *OCR2Config `protobuf:"bytes,6,opt,name=ocr2_config,json=ocr2Config,proto3" json:"ocr2_config,omitempty"` - AccountAddressPublicKey *string `protobuf:"bytes,7,opt,name=account_address_public_key,json=accountAddressPublicKey,proto3,oneof" json:"account_address_public_key,omitempty"` + Chain *Chain `protobuf:"bytes,1,opt,name=chain,proto3" json:"chain,omitempty"` + AccountAddress string `protobuf:"bytes,2,opt,name=account_address,json=accountAddress,proto3" json:"account_address,omitempty"` + AdminAddress string `protobuf:"bytes,3,opt,name=admin_address,json=adminAddress,proto3" json:"admin_address,omitempty"` + FluxMonitorConfig *FluxMonitorConfig `protobuf:"bytes,4,opt,name=flux_monitor_config,json=fluxMonitorConfig,proto3" json:"flux_monitor_config,omitempty"` + Ocr1Config *OCR1Config `protobuf:"bytes,5,opt,name=ocr1_config,json=ocr1Config,proto3" json:"ocr1_config,omitempty"` + Ocr2Config *OCR2Config `protobuf:"bytes,6,opt,name=ocr2_config,json=ocr2Config,proto3" json:"ocr2_config,omitempty"` + // For EVM chains, we do not need this value and it is kept in the node's + // keystore. For starknet, because the wallet address needs to be deployed + // using this value and this pub key needs to be passed into the starknet + // relayer, we request the node to send this directly to CLO. + AccountAddressPublicKey *string `protobuf:"bytes,7,opt,name=account_address_public_key,json=accountAddressPublicKey,proto3,oneof" json:"account_address_public_key,omitempty"` } func (x *ChainConfig) Reset() { @@ -1912,53 +1913,52 @@ var file_pkg_noderpc_proto_feeds_manager_proto_rawDesc = []byte{ 0x5f, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4a, 0x4f, 0x42, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x43, 0x52, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4a, 0x4f, 0x42, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x43, 0x52, 0x32, 0x10, 0x03, 0x2a, - 0x82, 0x01, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, - 0x16, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, - 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x56, 0x4d, 0x10, 0x01, 0x12, 0x15, 0x0a, - 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4f, 0x4c, 0x41, - 0x4e, 0x41, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x5a, 0x4b, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x03, 0x12, 0x17, 0x0a, 0x13, 0x43, - 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x4b, 0x4e, - 0x45, 0x54, 0x10, 0x04, 0x32, 0xd8, 0x02, 0x0a, 0x0c, 0x46, 0x65, 0x65, 0x64, 0x73, 0x4d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, - 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, - 0x76, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, - 0x63, 0x66, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x18, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0a, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x52, 0x65, 0x6a, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x52, 0x65, - 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x18, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4a, - 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x43, 0x61, - 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x18, 0x2e, 0x63, 0x66, 0x6d, - 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, - 0x6c, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, - 0xc4, 0x01, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x3d, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x16, 0x2e, + 0x6b, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, + 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, + 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x56, 0x4d, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, + 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4f, 0x4c, 0x41, 0x4e, + 0x41, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x4b, 0x4e, 0x45, 0x54, 0x10, 0x03, 0x32, 0xd8, 0x02, 0x0a, + 0x0c, 0x46, 0x65, 0x65, 0x64, 0x73, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x40, 0x0a, + 0x0b, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x17, 0x2e, 0x63, + 0x66, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x72, + 0x6f, 0x76, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x40, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x17, + 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3d, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, + 0x16, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x40, 0x0a, 0x0b, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, + 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4a, 0x6f, + 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x52, + 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x4a, + 0x6f, 0x62, 0x12, 0x18, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, + 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, + 0x66, 0x6d, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xc4, 0x01, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3d, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x70, 0x6f, + 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x16, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x50, 0x72, 0x6f, 0x70, + 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x50, 0x72, 0x6f, 0x70, - 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, - 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x2e, 0x63, 0x66, - 0x6d, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, - 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x52, 0x65, - 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x52, 0x65, - 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, - 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x73, 0x2d, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x72, 0x70, 0x63, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x63, 0x66, 0x6d, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x12, + 0x15, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x52, 0x65, 0x76, + 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3d, + 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, + 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x66, 0x65, + 0x65, 0x64, 0x73, 0x2d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, + 0x6e, 0x6f, 0x64, 0x65, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/core/services/feeds/proto/feeds_manager_wsrpc.pb.go b/core/services/feeds/proto/feeds_manager_wsrpc.pb.go index a002257e5c..17fe100b4f 100644 --- a/core/services/feeds/proto/feeds_manager_wsrpc.pb.go +++ b/core/services/feeds/proto/feeds_manager_wsrpc.pb.go @@ -1,13 +1,12 @@ // Code generated by protoc-gen-go-wsrpc. DO NOT EDIT. // versions: // - protoc-gen-go-wsrpc v0.0.1 -// - protoc v3.21.7 +// - protoc v4.25.3 package proto import ( context "context" - wsrpc "github.com/smartcontractkit/wsrpc" ) From c3b1f90dbc9d986fd2a61efc364363dfe612c683 Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Thu, 15 Aug 2024 09:32:20 -0700 Subject: [PATCH 098/432] [Keystone] Return an error from Launcher on invariant validation (#14128) Co-authored-by: Vyzaldy Sanchez --- core/capabilities/launcher.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/capabilities/launcher.go b/core/capabilities/launcher.go index 3182b192b7..fbf4d918a5 100644 --- a/core/capabilities/launcher.go +++ b/core/capabilities/launcher.go @@ -204,7 +204,7 @@ func (w *launcher) Launch(ctx context.Context, state *registrysyncer.LocalRegist // NOTE: this is enforced on-chain and so should never happen. if len(myWorkflowDONs) > 1 { - w.lggr.Error("invariant violation: node is part of more than one workflowDON: this shouldn't happen.") + return errors.New("invariant violation: node is part of more than one workflowDON") } for _, rcd := range remoteCapabilityDONs { From c0c7649f3b4d83ad6d6cf02055f497be7dd8cf5a Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Thu, 15 Aug 2024 13:15:07 -0400 Subject: [PATCH 099/432] Gates CCIP CI to run only when CCIP files change (#14131) --- .github/workflows/ccip-live-network-tests.yml | 5 +++-- .github/workflows/ccip-load-tests.yml | 3 +++ .github/workflows/integration-tests.yml | 5 ++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ccip-live-network-tests.yml b/.github/workflows/ccip-live-network-tests.yml index fa24614c8e..6649a881b9 100644 --- a/.github/workflows/ccip-live-network-tests.yml +++ b/.github/workflows/ccip-live-network-tests.yml @@ -1,7 +1,8 @@ name: CCIP Live Network Tests on: - schedule: - - cron: '0 */6 * * *' + # TODO: TT-1470 - Turn back on as we solidify new realease and image strategy + # schedule: + # - cron: '0 */6 * * *' workflow_dispatch: inputs: base64_test_input : # base64 encoded toml for test input diff --git a/.github/workflows/ccip-load-tests.yml b/.github/workflows/ccip-load-tests.yml index 8ddaba1199..0d53d803d1 100644 --- a/.github/workflows/ccip-load-tests.yml +++ b/.github/workflows/ccip-load-tests.yml @@ -1,6 +1,9 @@ name: CCIP Load Test on: push: + paths: + - '**/*ccip*' + - '**/*ccip*/**' branches: - develop tags: diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index d821b20a30..2b7a3b728d 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -101,6 +101,9 @@ jobs: - 'core/**/migrations/*.sql' - 'core/**/config/**/*.toml' - 'integration-tests/**/*.toml' + ccip-changes: + - '**/*ccip*' + - '**/*ccip*/**' - name: Ignore Filter On Workflow Dispatch if: ${{ github.event_name == 'workflow_dispatch' }} id: ignore-filter @@ -514,7 +517,7 @@ jobs: uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 eth-smoke-tests-matrix-ccip: - if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} + if: steps.changes.outputs.ccip-changes == 'true' && ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} environment: integration permissions: actions: read From 08194beb46355135dedde89d37838f5da36f2cef Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Fri, 16 Aug 2024 06:57:59 -0400 Subject: [PATCH 100/432] DEVSVCS-147: link balance monitor updates (#14108) * DEVSVCS-147: link balance monitor updates * changeset --- contracts/.changeset/nasty-llamas-prove.md | 5 +++++ .../upkeeps/LinkAvailableBalanceMonitor.sol | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 contracts/.changeset/nasty-llamas-prove.md diff --git a/contracts/.changeset/nasty-llamas-prove.md b/contracts/.changeset/nasty-llamas-prove.md new file mode 100644 index 0000000000..c3b26c9be3 --- /dev/null +++ b/contracts/.changeset/nasty-llamas-prove.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +DEVSVCS-147: add a reentrancy guard for balance monitor diff --git a/contracts/src/v0.8/automation/upkeeps/LinkAvailableBalanceMonitor.sol b/contracts/src/v0.8/automation/upkeeps/LinkAvailableBalanceMonitor.sol index 5d8a8d58c8..824bce711b 100644 --- a/contracts/src/v0.8/automation/upkeeps/LinkAvailableBalanceMonitor.sol +++ b/contracts/src/v0.8/automation/upkeeps/LinkAvailableBalanceMonitor.sol @@ -61,6 +61,7 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter error InvalidWatchList(); error InvalidChainSelector(); error DuplicateAddress(address duplicate); + error ReentrantCall(); struct MonitoredAddress { uint96 minBalance; @@ -94,6 +95,8 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter /// whenever a new one is deployed with the same dstChainSelector. EnumerableMap.UintToAddressMap private s_onRampAddresses; + bool private reentrancyGuard; + /// @param admin is the administrator address of this contract /// @param linkToken the LINK token address /// @param minWaitPeriodSeconds represents the amount of time that has to wait a contract to be funded @@ -116,6 +119,7 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter setMaxPerform(maxPerform); setMaxCheck(maxCheck); setUpkeepInterval(upkeepInterval); + reentrancyGuard = false; } /// @notice Sets the list of subscriptions to watch and their funding parameters @@ -259,7 +263,7 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter /// @notice tries to fund an array of target addresses, checking if they're underfunded in the process /// @param targetAddresses is an array of contract addresses to be funded in case they're underfunded - function topUp(address[] memory targetAddresses) public whenNotPaused { + function topUp(address[] memory targetAddresses) public whenNotPaused nonReentrant { MonitoredAddress memory contractToFund; uint256 minWaitPeriod = s_minWaitPeriodSeconds; uint256 localBalance = i_linkToken.balanceOf(address(this)); @@ -457,6 +461,13 @@ contract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInter _; } + modifier nonReentrant() { + if (reentrancyGuard) revert ReentrantCall(); + reentrancyGuard = true; + _; + reentrancyGuard = false; + } + /// @notice Pause the contract, which prevents executing performUpkeep function pause() external onlyRole(ADMIN_ROLE) { _pause(); From 69a00908e0eeaa936c5c588c9fc4287f4a8ca117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Fri, 16 Aug 2024 13:09:53 +0200 Subject: [PATCH 101/432] Aptos LOOP setup (#14076) * Wire up init necessary for an Aptos LOOP * Fix typings, make sure SetFrom doesn't blank out RawConfig * Add missing initialization code for Aptos * keystore: Aptos should use blake2b since blake2s is unavailable Blake2b costs about a third of SHA2/SHA3/keccak256 https://aptos.dev/en/build/smart-contracts/cryptography * keystore: Fix aptoskey public key encoding * keystore: Remove aptoskey/account.go, completely unused * aptoskey: Add support for address derivation * keystore: aptos: Test implementation against vectors generated by the CLI * keystore: aptos: Remove 0x prefix from public key * keystore: cosmos: Remove duplicate nil check * operator_ui: Increase install timeout Really painful on slower internet connections * keystore: aptos: Update report hashing format --- core/cmd/shell.go | 7 + core/cmd/shell_local.go | 9 ++ core/internal/cltest/cltest.go | 7 + core/services/chainlink/config.go | 24 ++- core/services/chainlink/config_general.go | 4 + core/services/chainlink/config_test.go | 2 +- .../chainlink/mocks/general_config.go | 49 ++++++ .../chainlink/relayer_chain_interoperators.go | 17 +++ core/services/chainlink/relayer_factory.go | 70 ++++++++- core/services/chainlink/types.go | 1 + .../keystore/keys/aptoskey/account.go | 72 --------- .../keystore/keys/aptoskey/account_test.go | 141 ------------------ core/services/keystore/keys/aptoskey/key.go | 13 +- .../keystore/keys/aptoskey/key_test.go | 17 +++ core/services/keystore/keys/cosmoskey/key.go | 3 - .../keystore/keys/ocr2key/aptos_keyring.go | 11 +- core/web/presenters/aptos_key.go | 8 +- operator_ui/install.go | 2 +- 18 files changed, 219 insertions(+), 238 deletions(-) delete mode 100644 core/services/keystore/keys/aptoskey/account.go delete mode 100644 core/services/keystore/keys/aptoskey/account_test.go create mode 100644 core/services/keystore/keys/aptoskey/key_test.go diff --git a/core/cmd/shell.go b/core/cmd/shell.go index 3d055bb03a..5c864b82cd 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -208,6 +208,13 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G } initOps = append(initOps, chainlink.InitStarknet(ctx, relayerFactory, starkCfg)) } + if cfg.AptosEnabled() { + aptosCfg := chainlink.AptosFactoryConfig{ + Keystore: keyStore.Aptos(), + TOMLConfigs: cfg.AptosConfigs(), + } + initOps = append(initOps, chainlink.InitAptos(ctx, relayerFactory, aptosCfg)) + } relayChainInterops, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) if err != nil { diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index ed8b653c05..604daf7568 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -435,6 +435,9 @@ func (s *Shell) runNode(c *cli.Context) error { if s.Config.StarkNetEnabled() { enabledChains = append(enabledChains, chaintype.StarkNet) } + if s.Config.AptosEnabled() { + enabledChains = append(enabledChains, chaintype.Aptos) + } err2 := app.GetKeyStore().OCR2().EnsureKeys(rootCtx, enabledChains...) if err2 != nil { return errors.Wrap(err2, "failed to ensure ocr key") @@ -464,6 +467,12 @@ func (s *Shell) runNode(c *cli.Context) error { return errors.Wrap(err2, "failed to ensure starknet key") } } + if s.Config.AptosEnabled() { + err2 := app.GetKeyStore().Aptos().EnsureKey(rootCtx) + if err2 != nil { + return errors.Wrap(err2, "failed to ensure aptos key") + } + } err2 := app.GetKeyStore().CSA().EnsureKey(rootCtx) if err2 != nil { diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 12491300bf..7447d1385f 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -439,6 +439,13 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn } initOps = append(initOps, chainlink.InitStarknet(testCtx, relayerFactory, starkCfg)) } + if cfg.AptosEnabled() { + aptosCfg := chainlink.AptosFactoryConfig{ + Keystore: keyStore.Aptos(), + TOMLConfigs: cfg.AptosConfigs(), + } + initOps = append(initOps, chainlink.InitAptos(testCtx, relayerFactory, aptosCfg)) + } relayChainInterops, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) if err != nil { diff --git a/core/services/chainlink/config.go b/core/services/chainlink/config.go index dc301c0967..476e758ccb 100644 --- a/core/services/chainlink/config.go +++ b/core/services/chainlink/config.go @@ -55,8 +55,13 @@ type RawConfig map[string]any // ValidateConfig returns an error if the Config is not valid for use, as-is. func (c *RawConfig) ValidateConfig() (err error) { if v, ok := (*c)["Enabled"]; ok { - if _, ok := v.(*bool); !ok { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "Enabled", Value: v, Msg: "expected *bool"}) + if _, ok := v.(bool); !ok { + err = multierr.Append(err, commonconfig.ErrInvalid{Name: "Enabled", Value: v, Msg: "expected bool"}) + } + } + if v, ok := (*c)["ChainID"]; ok { + if _, ok := v.(string); !ok { + err = multierr.Append(err, commonconfig.ErrInvalid{Name: "ChainID", Value: v, Msg: "expected string"}) } } return err @@ -67,7 +72,17 @@ func (c *RawConfig) IsEnabled() bool { return false } - return (*c)["Enabled"] == nil || *(*c)["Enabled"].(*bool) + enabled, ok := (*c)["Enabled"].(bool) + return ok && enabled +} + +func (c *RawConfig) ChainID() string { + if c == nil { + return "" + } + + chainID, _ := (*c)["ChainID"].(string) + return chainID } // TOMLString returns a TOML encoded string. @@ -170,6 +185,9 @@ func (c *Config) SetFrom(f *Config) (err error) { err = multierr.Append(err, commonconfig.NamedMultiErrorList(err4, "Starknet")) } + // the plugin should handle it's own defaults and merging + c.Aptos = f.Aptos + _, err = commonconfig.MultiErrorList(err) return err diff --git a/core/services/chainlink/config_general.go b/core/services/chainlink/config_general.go index 5b6b839fb5..79c92f8214 100644 --- a/core/services/chainlink/config_general.go +++ b/core/services/chainlink/config_general.go @@ -209,6 +209,10 @@ func (g *generalConfig) StarknetConfigs() starknet.TOMLConfigs { return g.c.Starknet } +func (g *generalConfig) AptosConfigs() RawConfigs { + return g.c.Aptos +} + func (g *generalConfig) Validate() error { return g.validate(g.secrets.Validate) } diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index f5a9d33592..5fc9babe77 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -1365,7 +1365,7 @@ func TestConfig_Validate(t *testing.T) { - 1: 2 errors: - ChainID: missing: required for all chains - Nodes: missing: must have at least one node - - Aptos.0.Enabled: invalid value (1): expected *bool`}, + - Aptos.0.Enabled: invalid value (1): expected bool`}, } { t.Run(tt.name, func(t *testing.T) { var c Config diff --git a/core/services/chainlink/mocks/general_config.go b/core/services/chainlink/mocks/general_config.go index c42ed5c701..f4594a4322 100644 --- a/core/services/chainlink/mocks/general_config.go +++ b/core/services/chainlink/mocks/general_config.go @@ -4,6 +4,8 @@ package mocks import ( chainlinkconfig "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config" + chainlink "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + config "github.com/smartcontractkit/chainlink/v2/core/config" cosmosconfig "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config" @@ -81,6 +83,53 @@ func (_c *GeneralConfig_AppID_Call) RunAndReturn(run func() uuid.UUID) *GeneralC return _c } +// AptosConfigs provides a mock function with given fields: +func (_m *GeneralConfig) AptosConfigs() chainlink.RawConfigs { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for AptosConfigs") + } + + var r0 chainlink.RawConfigs + if rf, ok := ret.Get(0).(func() chainlink.RawConfigs); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(chainlink.RawConfigs) + } + } + + return r0 +} + +// GeneralConfig_AptosConfigs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AptosConfigs' +type GeneralConfig_AptosConfigs_Call struct { + *mock.Call +} + +// AptosConfigs is a helper method to define mock.On call +func (_e *GeneralConfig_Expecter) AptosConfigs() *GeneralConfig_AptosConfigs_Call { + return &GeneralConfig_AptosConfigs_Call{Call: _e.mock.On("AptosConfigs")} +} + +func (_c *GeneralConfig_AptosConfigs_Call) Run(run func()) *GeneralConfig_AptosConfigs_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *GeneralConfig_AptosConfigs_Call) Return(_a0 chainlink.RawConfigs) *GeneralConfig_AptosConfigs_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GeneralConfig_AptosConfigs_Call) RunAndReturn(run func() chainlink.RawConfigs) *GeneralConfig_AptosConfigs_Call { + _c.Call.Return(run) + return _c +} + // AptosEnabled provides a mock function with given fields: func (_m *GeneralConfig) AptosEnabled() bool { ret := _m.Called() diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index 60381c0d47..ffcfc67b87 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -186,6 +186,23 @@ func InitStarknet(ctx context.Context, factory RelayerFactory, config StarkNetFa } } +// InitAptos is a option for instantiating Aptos relayers +func InitAptos(ctx context.Context, factory RelayerFactory, config AptosFactoryConfig) CoreRelayerChainInitFunc { + return func(op *CoreRelayerChainInteroperators) (err error) { + relayers, err := factory.NewAptos(config.Keystore, config.TOMLConfigs) + if err != nil { + return fmt.Errorf("failed to setup aptos relayer: %w", err) + } + + for id, relayer := range relayers { + op.srvs = append(op.srvs, relayer) + op.loopRelayers[id] = relayer + } + + return nil + } +} + // Get a [loop.Relayer] by id func (rs *CoreRelayerChainInteroperators) Get(id types.RelayID) (loop.Relayer, error) { rs.mu.Lock() diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index 849964f9be..3ddfe27047 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -18,7 +18,7 @@ import ( solcfg "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" pkgstarknet "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink" starkchain "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/chain" - "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config" + starkcfg "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" coreconfig "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/config/env" @@ -171,12 +171,12 @@ func (r *RelayerFactory) NewSolana(ks keystore.Solana, chainCfgs solcfg.TOMLConf type StarkNetFactoryConfig struct { Keystore keystore.StarkNet - config.TOMLConfigs + starkcfg.TOMLConfigs } // TODO BCF-2606 consider consolidating the driving logic with that of NewSolana above via generics // perhaps when we implement a Cosmos LOOP -func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs config.TOMLConfigs) (map[types.RelayID]loop.Relayer, error) { +func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs starkcfg.TOMLConfigs) (map[types.RelayID]loop.Relayer, error) { starknetRelayers := make(map[types.RelayID]loop.Relayer) var ( @@ -205,7 +205,7 @@ func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs config.TOML if cmdName := env.StarknetPlugin.Cmd.Get(); cmdName != "" { // setup the starknet relayer to be a LOOP cfgTOML, err := toml.Marshal(struct { - Starknet config.TOMLConfig + Starknet starkcfg.TOMLConfig }{Starknet: *chainCfg}) if err != nil { return nil, fmt.Errorf("failed to marshal StarkNet configs: %w", err) @@ -301,3 +301,65 @@ func (r *RelayerFactory) NewCosmos(config CosmosFactoryConfig) (map[types.RelayI } return relayers, nil } + +type AptosFactoryConfig struct { + Keystore keystore.Aptos + TOMLConfigs RawConfigs +} + +func (r *RelayerFactory) NewAptos(ks keystore.Aptos, chainCfgs RawConfigs) (map[types.RelayID]loop.Relayer, error) { + plugin := env.NewPlugin("aptos") + loopKs := &keystore.AptosLooppSigner{Aptos: ks} + return r.NewLOOPRelayer("Aptos", corerelay.NetworkAptos, plugin, loopKs, chainCfgs) +} + +func (r *RelayerFactory) NewLOOPRelayer(name string, network string, plugin env.Plugin, ks coretypes.Keystore, chainCfgs RawConfigs) (map[types.RelayID]loop.Relayer, error) { + relayers := make(map[types.RelayID]loop.Relayer) + lggr := r.Logger.Named(name) + + unique := make(map[string]struct{}) + // create one relayer per chain id + for _, chainCfg := range chainCfgs { + relayID := types.RelayID{Network: network, ChainID: chainCfg.ChainID()} + if _, alreadyExists := unique[relayID.Name()]; alreadyExists { + return nil, fmt.Errorf("duplicate chain definitions for %s", relayID.Name()) + } + unique[relayID.Name()] = struct{}{} + + // skip disabled chains from further processing + if !chainCfg.IsEnabled() { + lggr.Warnw("Skipping disabled chain", "id", relayID.ChainID) + continue + } + + lggr2 := lggr.Named(relayID.ChainID) + + cmdName := plugin.Cmd.Get() + if cmdName == "" { + return nil, fmt.Errorf("plugin not defined: %s", "") + } + + // setup the relayer as a LOOP + cfgTOML, err := toml.Marshal(chainCfg) + if err != nil { + return nil, fmt.Errorf("failed to marshal configs: %w", err) + } + + envVars, err := plugins.ParseEnvFile(plugin.Env.Get()) + if err != nil { + return nil, fmt.Errorf("failed to parse env file: %w", err) + } + cmdFn, err := plugins.NewCmdFactory(r.Register, plugins.CmdConfig{ + ID: relayID.Name(), + Cmd: cmdName, + Env: envVars, + }) + if err != nil { + return nil, fmt.Errorf("failed to create LOOP command: %w", err) + } + // the relayer service has a delicate keystore dependency. the value that is passed to NewRelayerService must + // be compatible with instantiating a starknet transaction manager KeystoreAdapter within the LOOPp executable. + relayers[relayID] = loop.NewRelayerService(lggr2, r.GRPCOpts, cmdFn, string(cfgTOML), ks, r.CapabilitiesRegistry) + } + return relayers, nil +} diff --git a/core/services/chainlink/types.go b/core/services/chainlink/types.go index 4aa3782549..74ffc5dc66 100644 --- a/core/services/chainlink/types.go +++ b/core/services/chainlink/types.go @@ -15,6 +15,7 @@ type GeneralConfig interface { CosmosConfigs() coscfg.TOMLConfigs SolanaConfigs() solcfg.TOMLConfigs StarknetConfigs() stkcfg.TOMLConfigs + AptosConfigs() RawConfigs // ConfigTOML returns both the user provided and effective configuration as TOML. ConfigTOML() (user, effective string) } diff --git a/core/services/keystore/keys/aptoskey/account.go b/core/services/keystore/keys/aptoskey/account.go deleted file mode 100644 index 89f62d3301..0000000000 --- a/core/services/keystore/keys/aptoskey/account.go +++ /dev/null @@ -1,72 +0,0 @@ -package aptoskey - -import ( - "encoding/hex" - "errors" - "fmt" - "strings" -) - -// AccountAddress is a 32 byte address on the Aptos blockchain -// It can represent an Object, an Account, and much more. -// -// AccountAddress is copied from the aptos sdk because: -// 1. There are still breaking changes in sdk and we don't want the dependency. -// 2. AccountAddress is just a wrapper and can be easily extracted out. -// -// https://github.com/aptos-labs/aptos-go-sdk/blob/main/internal/types/account.go -type AccountAddress [32]byte - -// IsSpecial Returns whether the address is a "special" address. Addresses are considered -// special if the first 63 characters of the hex string are zero. In other words, -// an address is special if the first 31 bytes are zero and the last byte is -// smaller than `0b10000` (16). In other words, special is defined as an address -// that matches the following regex: `^0x0{63}[0-9a-f]$`. In short form this means -// the addresses in the range from `0x0` to `0xf` (inclusive) are special. -// For more details see the v1 address standard defined as part of AIP-40: -// https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-40.md -func (aa *AccountAddress) IsSpecial() bool { - for _, b := range aa[:31] { - if b != 0 { - return false - } - } - return aa[31] < 0x10 -} - -// String Returns the canonical string representation of the AccountAddress -func (aa *AccountAddress) String() string { - if aa.IsSpecial() { - return fmt.Sprintf("0x%x", aa[31]) - } - return BytesToHex(aa[:]) -} - -// ParseStringRelaxed parses a string into an AccountAddress -func (aa *AccountAddress) ParseStringRelaxed(x string) error { - x = strings.TrimPrefix(x, "0x") - if len(x) < 1 { - return ErrAddressTooShort - } - if len(x) > 64 { - return ErrAddressTooLong - } - if len(x)%2 != 0 { - x = "0" + x - } - bytes, err := hex.DecodeString(x) - if err != nil { - return err - } - // zero-prefix/right-align what bytes we got - copy((*aa)[32-len(bytes):], bytes) - - return nil -} - -var ErrAddressTooShort = errors.New("AccountAddress too short") -var ErrAddressTooLong = errors.New("AccountAddress too long") - -func BytesToHex(bytes []byte) string { - return "0x" + hex.EncodeToString(bytes) -} diff --git a/core/services/keystore/keys/aptoskey/account_test.go b/core/services/keystore/keys/aptoskey/account_test.go deleted file mode 100644 index b9ed4ea04a..0000000000 --- a/core/services/keystore/keys/aptoskey/account_test.go +++ /dev/null @@ -1,141 +0,0 @@ -package aptoskey - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -// Tests extracted from -// https://github.com/aptos-labs/aptos-go-sdk/blob/5ee5ac308e5881b508c0a5124f5e0b8df27a4d40/internal/types/account_test.go - -func TestStringOutput(t *testing.T) { - inputs := [][]byte{ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F}, - {0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, - {0x02, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, - {0x00, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, - {0x00, 0x04, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, - {0x00, 0x00, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, - } - expected := []string{ - "0x0", - "0x1", - "0xf", - "0x1234123412341234123412341234123412341234123412340123456789abcdef", - "0x0234123412341234123412341234123412341234123412340123456789abcdef", - "0x0034123412341234123412341234123412341234123412340123456789abcdef", - "0x0004123412341234123412341234123412341234123412340123456789abcdef", - "0x0000123412341234123412341234123412341234123412340123456789abcdef", - } - - for i := 0; i < len(inputs); i++ { - addr := AccountAddress(inputs[i]) - assert.Equal(t, expected[i], addr.String()) - } -} - -func TestAccountAddress_ParseStringRelaxed_Error(t *testing.T) { - var owner AccountAddress - err := owner.ParseStringRelaxed("0x") - assert.Error(t, err) - err = owner.ParseStringRelaxed("0xF1234567812345678123456781234567812345678123456781234567812345678") - assert.Error(t, err) - err = owner.ParseStringRelaxed("NotHex") - assert.Error(t, err) -} - -func TestAccountAddress_String(t *testing.T) { - testCases := []struct { - name string - address AccountAddress - expected string - }{ - { - name: "Special address", - address: AccountAddress{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - expected: "0x1", - }, - { - name: "Non-special address", - address: AccountAddress{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}, - expected: "0x123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - assert.Equal(t, tc.expected, tc.address.String()) - }) - } -} - -func TestAccountAddress_IsSpecial(t *testing.T) { - testCases := []struct { - name string - address AccountAddress - expected bool - }{ - { - name: "Special address", - address: AccountAddress{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - expected: true, - }, - { - name: "Non-special address", - address: AccountAddress{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}, - expected: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - assert.Equal(t, tc.expected, tc.address.IsSpecial()) - }) - } -} - -func TestBytesToHex(t *testing.T) { - testCases := []struct { - name string - bytes []byte - expected string - }{ - { - name: "Empty bytes", - bytes: []byte{}, - expected: "0x", - }, - { - name: "Non-empty bytes", - bytes: []byte{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}, - expected: "0x123456789abcdef0", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - assert.Equal(t, tc.expected, BytesToHex(tc.bytes)) - }) - } -} - -func TestAccountSpecialString(t *testing.T) { - var aa AccountAddress - aa[31] = 3 - aas := aa.String() - if aas != "0x3" { - t.Errorf("wanted 0x3 got %s", aas) - } - - var aa2 AccountAddress - err := aa2.ParseStringRelaxed("0x3") - if err != nil { - t.Errorf("unexpected err %s", err) - } - if aa2 != aa { - t.Errorf("aa2 != aa") - } -} diff --git a/core/services/keystore/keys/aptoskey/key.go b/core/services/keystore/keys/aptoskey/key.go index ec9b27a359..fa8925454e 100644 --- a/core/services/keystore/keys/aptoskey/key.go +++ b/core/services/keystore/keys/aptoskey/key.go @@ -7,7 +7,7 @@ import ( "fmt" "io" - "github.com/mr-tron/base58" + "golang.org/x/crypto/sha3" ) // Raw represents the Aptos private key @@ -37,6 +37,7 @@ var _ fmt.GoStringer = &Key{} // Key represents Aptos key type Key struct { + // TODO: store initial Account() derivation to support key rotation privkey ed25519.PrivateKey pubKey ed25519.PublicKey } @@ -72,14 +73,20 @@ func (key Key) ID() string { return key.PublicKeyStr() } +// https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-40.md#long +func (key Key) Account() string { + authKey := sha3.Sum256(append([]byte(key.pubKey), 0x00)) + return fmt.Sprintf("%064x", authKey) +} + // GetPublic get Key's public key func (key Key) GetPublic() ed25519.PublicKey { return key.pubKey } -// PublicKeyStr return base58 encoded public key +// PublicKeyStr returns hex encoded public key func (key Key) PublicKeyStr() string { - return base58.Encode(key.pubKey) + return fmt.Sprintf("%064x", key.pubKey) } // Raw returns the seed from private key diff --git a/core/services/keystore/keys/aptoskey/key_test.go b/core/services/keystore/keys/aptoskey/key_test.go new file mode 100644 index 0000000000..277a30eb9f --- /dev/null +++ b/core/services/keystore/keys/aptoskey/key_test.go @@ -0,0 +1,17 @@ +package aptoskey + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestAptosKey(t *testing.T) { + bytes, err := hex.DecodeString("f0d07ab448018b2754475f9a3b580218b0675a1456aad96ad607c7bbd7d9237b") + require.NoError(t, err) + k := Raw(bytes).Key() + assert.Equal(t, k.PublicKeyStr(), "2acd605efc181e2af8a0b8c0686a5e12578efa1253d15a235fa5e5ad970c4b29") + assert.Equal(t, k.Account(), "69d8b07f5945185873c622ea66873b0e1fb921de7b94d904d3ef9be80770682e") +} diff --git a/core/services/keystore/keys/cosmoskey/key.go b/core/services/keystore/keys/cosmoskey/key.go index 3e516a21ab..b5ea255f23 100644 --- a/core/services/keystore/keys/cosmoskey/key.go +++ b/core/services/keystore/keys/cosmoskey/key.go @@ -59,9 +59,6 @@ func newFrom(reader io.Reader) Key { panic(err) } privKey := secpSigningAlgo.Generate()(rawKey.D.Bytes()) - if err != nil { - panic(err) - } return Key{ d: rawKey.D, diff --git a/core/services/keystore/keys/ocr2key/aptos_keyring.go b/core/services/keystore/keys/ocr2key/aptos_keyring.go index 51e6c3a9c8..cdc5afa792 100644 --- a/core/services/keystore/keys/ocr2key/aptos_keyring.go +++ b/core/services/keystore/keys/ocr2key/aptos_keyring.go @@ -2,12 +2,11 @@ package ocr2key import ( "crypto/ed25519" - "encoding/binary" "io" "github.com/hdevalence/ed25519consensus" "github.com/pkg/errors" - "golang.org/x/crypto/blake2s" + "golang.org/x/crypto/blake2b" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -37,17 +36,15 @@ func (akr *aptosKeyring) PublicKey() ocrtypes.OnchainPublicKey { func (akr *aptosKeyring) reportToSigData(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) ([]byte, error) { rawReportContext := evmutil.RawReportContext(reportCtx) - h, err := blake2s.New256(nil) + h, err := blake2b.New256(nil) if err != nil { return nil, err } - reportLen := make([]byte, 4) - binary.BigEndian.PutUint32(reportLen[0:], uint32(len(report))) - h.Write(reportLen[:]) - h.Write(report) + // blake2b_256(report_context | report) h.Write(rawReportContext[0][:]) h.Write(rawReportContext[1][:]) h.Write(rawReportContext[2][:]) + h.Write(report) return h.Sum(nil), nil } diff --git a/core/web/presenters/aptos_key.go b/core/web/presenters/aptos_key.go index 6460c325f9..8c0c09ed10 100644 --- a/core/web/presenters/aptos_key.go +++ b/core/web/presenters/aptos_key.go @@ -5,7 +5,8 @@ import "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/apt // AptosKeyResource represents a Aptos key JSONAPI resource. type AptosKeyResource struct { JAID - PubKey string `json:"publicKey"` + Account string `json:"account"` + PubKey string `json:"publicKey"` } // GetName implements the api2go EntityNamer interface @@ -15,8 +16,9 @@ func (AptosKeyResource) GetName() string { func NewAptosKeyResource(key aptoskey.Key) *AptosKeyResource { r := &AptosKeyResource{ - JAID: JAID{ID: key.ID()}, - PubKey: key.PublicKeyStr(), + JAID: JAID{ID: key.ID()}, + Account: key.Account(), + PubKey: key.PublicKeyStr(), } return r diff --git a/operator_ui/install.go b/operator_ui/install.go index 1e09783db6..14d920ddd4 100644 --- a/operator_ui/install.go +++ b/operator_ui/install.go @@ -22,7 +22,7 @@ func main() { fullRepo = owner + "/" + repo tagPath = "operator_ui/TAG" unpackDir = "core/web/assets" - downloadTimeoutSeconds = 10 + downloadTimeoutSeconds = 30 ) // Grab first argument as root directory if len(os.Args) < 2 { From 2e314cddf0f4dbd29cad4a43926dc1a5390cc70f Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Fri, 16 Aug 2024 16:02:35 -0500 Subject: [PATCH 102/432] Update ZK overflow detection logic (#14132) * Updated ZK overflow detection to skip tx with non-broadcast attempts and delayed detection for zkEVM * Added changeset * Added assumption violation log * Updated XLayer to use the same detection logic as zkEVM * Fixed test --- .changeset/big-dots-report.md | 5 ++ core/chains/evm/config/toml/config.go | 12 +++- core/chains/evm/txmgr/stuck_tx_detector.go | 53 +++++++++++++++--- .../evm/txmgr/stuck_tx_detector_test.go | 56 ++++++++++++++++++- core/chains/evm/txmgr/txmgr_test.go | 6 +- 5 files changed, 118 insertions(+), 14 deletions(-) create mode 100644 .changeset/big-dots-report.md diff --git a/.changeset/big-dots-report.md b/.changeset/big-dots-report.md new file mode 100644 index 0000000000..01475010f0 --- /dev/null +++ b/.changeset/big-dots-report.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Updated ZK overflow detection to skip transactions with non-broadcasted attempts. Delayed detection for zkEVM using the MinAttempts config. Updated XLayer to use the same detection logic as zkEVM. #internal diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 2cb29d9769..ac7841ac49 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -412,8 +412,16 @@ func (c *Chain) ValidateConfig() (err error) { err = multierr.Append(err, commonconfig.ErrInvalid{Name: "Transactions.AutoPurge.DetectionApiUrl", Value: c.Transactions.AutoPurge.DetectionApiUrl.Scheme, Msg: "must be http or https"}) } } - case chaintype.ChainZkEvm: - // No other configs are needed + case chaintype.ChainZkEvm, chaintype.ChainXLayer: + // MinAttempts is an optional config that can be used to delay the stuck tx detection for zkEVM or XLayer + // If MinAttempts is set, BumpThreshold cannot be 0 + if c.Transactions.AutoPurge.MinAttempts != nil && *c.Transactions.AutoPurge.MinAttempts != 0 { + if c.GasEstimator.BumpThreshold == nil { + err = multierr.Append(err, commonconfig.ErrMissing{Name: "GasEstimator.BumpThreshold", Msg: fmt.Sprintf("must be set if Transactions.AutoPurge.MinAttempts is set for %s", chainType)}) + } else if *c.GasEstimator.BumpThreshold == 0 { + err = multierr.Append(err, commonconfig.ErrInvalid{Name: "GasEstimator.BumpThreshold", Value: 0, Msg: fmt.Sprintf("cannot be 0 if Transactions.AutoPurge.MinAttempts is set for %s", chainType)}) + } + } default: // Bump Threshold is required because the stuck tx heuristic relies on a minimum number of bump attempts to exist if c.GasEstimator.BumpThreshold == nil { diff --git a/core/chains/evm/txmgr/stuck_tx_detector.go b/core/chains/evm/txmgr/stuck_tx_detector.go index 5901be0b02..5d621dc0b2 100644 --- a/core/chains/evm/txmgr/stuck_tx_detector.go +++ b/core/chains/evm/txmgr/stuck_tx_detector.go @@ -44,7 +44,7 @@ type stuckTxDetectorConfig interface { } type stuckTxDetector struct { - lggr logger.Logger + lggr logger.SugaredLogger chainID *big.Int chainType chaintype.ChainType maxPrice *assets.Wei @@ -64,7 +64,7 @@ func NewStuckTxDetector(lggr logger.Logger, chainID *big.Int, chainType chaintyp t.DisableCompression = true httpClient := &http.Client{Transport: t} return &stuckTxDetector{ - lggr: lggr, + lggr: logger.Sugared(lggr), chainID: chainID, chainType: chainType, maxPrice: maxPrice, @@ -128,7 +128,7 @@ func (d *stuckTxDetector) DetectStuckTransactions(ctx context.Context, enabledAd switch d.chainType { case chaintype.ChainScroll: return d.detectStuckTransactionsScroll(ctx, txs) - case chaintype.ChainZkEvm: + case chaintype.ChainZkEvm, chaintype.ChainXLayer: return d.detectStuckTransactionsZkEVM(ctx, txs) default: return d.detectStuckTransactionsHeuristic(ctx, txs, blockNum) @@ -153,11 +153,28 @@ func (d *stuckTxDetector) FindUnconfirmedTxWithLowestNonce(ctx context.Context, } } - // Build list of potentially stuck tx but exclude any that are already marked for purge + // Build list of potentially stuck tx but exclude any that are already marked for purge or have non-broadcasted attempts var stuckTxs []Tx for _, tx := range lowestNonceTxMap { - // Attempts are loaded newest to oldest so one marked for purge will always be first - if len(tx.TxAttempts) > 0 && !tx.TxAttempts[0].IsPurgeAttempt { + if len(tx.TxAttempts) == 0 { + d.lggr.AssumptionViolationw("encountered an unconfirmed transaction without an attempt", "tx", tx) + continue + } + // Check the transaction's attempts in case any are already marked for purge or if any are not broadcasted + // We can only have one non-broadcasted attempt for a transaction at a time + // Skip purge detection until all attempts are broadcasted to avoid conflicts with the purge attempt + var foundPurgeAttempt, foundNonBroadcastAttempt bool + for _, attempt := range tx.TxAttempts { + if attempt.IsPurgeAttempt { + foundPurgeAttempt = true + break + } + if attempt.State != types.TxAttemptBroadcast { + foundNonBroadcastAttempt = true + break + } + } + if !foundPurgeAttempt && !foundNonBroadcastAttempt { stuckTxs = append(stuckTxs, tx) } } @@ -322,14 +339,32 @@ func (d *stuckTxDetector) detectStuckTransactionsScroll(ctx context.Context, txs // Uses eth_getTransactionByHash to detect that a transaction has been discarded due to overflow // Currently only used by zkEVM but if other chains follow the same behavior in the future func (d *stuckTxDetector) detectStuckTransactionsZkEVM(ctx context.Context, txs []Tx) ([]Tx, error) { - txReqs := make([]rpc.BatchElem, len(txs)) + minAttempts := 0 + if d.cfg.MinAttempts() != nil { + minAttempts = int(*d.cfg.MinAttempts()) + } + // Check transactions have MinAttempts to ensure it has enough time to return results for getTransactionByHash + // zkEVM has a significant delay between broadcasting a transaction and getting a proper result from the RPC + var filteredTx []Tx + for _, tx := range txs { + if len(tx.TxAttempts) >= minAttempts { + filteredTx = append(filteredTx, tx) + } + } + + // No transactions to process + if len(filteredTx) == 0 { + return filteredTx, nil + } + + txReqs := make([]rpc.BatchElem, len(filteredTx)) txHashMap := make(map[common.Hash]Tx) - txRes := make([]*map[string]interface{}, len(txs)) + txRes := make([]*map[string]interface{}, len(filteredTx)) // Build batch request elems to perform // Does not need to be separated out into smaller batches // Max number of transactions to check is equal to the number of enabled addresses which is a relatively small amount - for i, tx := range txs { + for i, tx := range filteredTx { latestAttemptHash := tx.TxAttempts[0].Hash var result map[string]interface{} txReqs[i] = rpc.BatchElem{ diff --git a/core/chains/evm/txmgr/stuck_tx_detector_test.go b/core/chains/evm/txmgr/stuck_tx_detector_test.go index 5f0d73be18..def49f8e11 100644 --- a/core/chains/evm/txmgr/stuck_tx_detector_test.go +++ b/core/chains/evm/txmgr/stuck_tx_detector_test.go @@ -155,6 +155,30 @@ func TestStuckTxDetector_FindPotentialStuckTxs(t *testing.T) { require.NoError(t, err) require.Len(t, stuckTxs, 0) }) + + t.Run("excludes transactions with a in-progress attempt", func(t *testing.T) { + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress) + attempt := cltest.NewLegacyEthTxAttempt(t, etx.ID) + attempt.TxFee.Legacy = assets.NewWeiI(2) + attempt.State = txmgrtypes.TxAttemptInProgress + require.NoError(t, txStore.InsertTxAttempt(ctx, &attempt)) + stuckTxs, err := stuckTxDetector.FindUnconfirmedTxWithLowestNonce(ctx, []common.Address{fromAddress}) + require.NoError(t, err) + require.Len(t, stuckTxs, 0) + }) + + t.Run("excludes transactions with an insufficient funds attempt", func(t *testing.T) { + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress) + attempt := cltest.NewLegacyEthTxAttempt(t, etx.ID) + attempt.TxFee.Legacy = assets.NewWeiI(2) + attempt.State = txmgrtypes.TxAttemptInsufficientFunds + require.NoError(t, txStore.InsertTxAttempt(ctx, &attempt)) + stuckTxs, err := stuckTxDetector.FindUnconfirmedTxWithLowestNonce(ctx, []common.Address{fromAddress}) + require.NoError(t, err) + require.Len(t, stuckTxs, 0) + }) } func TestStuckTxDetector_DetectStuckTransactionsHeuristic(t *testing.T) { @@ -271,8 +295,9 @@ func TestStuckTxDetector_DetectStuckTransactionsZkEVM(t *testing.T) { enabled: true, } blockNum := int64(100) - stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, chaintype.ChainZkEvm, assets.NewWei(assets.NewEth(100).ToInt()), autoPurgeCfg, feeEstimator, txStore, ethClient) + t.Run("returns empty list if no stuck transactions identified", func(t *testing.T) { + stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, chaintype.ChainZkEvm, assets.NewWei(assets.NewEth(100).ToInt()), autoPurgeCfg, feeEstimator, txStore, ethClient) _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) tx := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress, 1, blockNum, tenGwei) attempts := tx.TxAttempts[0] @@ -292,6 +317,7 @@ func TestStuckTxDetector_DetectStuckTransactionsZkEVM(t *testing.T) { }) t.Run("returns stuck transactions discarded by chain", func(t *testing.T) { + stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, chaintype.ChainZkEvm, assets.NewWei(assets.NewEth(100).ToInt()), autoPurgeCfg, feeEstimator, txStore, ethClient) // Insert tx that will be mocked as stuck _, fromAddress1 := cltest.MustInsertRandomKey(t, ethKeyStore) mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress1, 1, blockNum, tenGwei) @@ -316,6 +342,34 @@ func TestStuckTxDetector_DetectStuckTransactionsZkEVM(t *testing.T) { // Expect only 1 tx to return as stuck due to nil eth_getTransactionByHash response require.Len(t, txs, 1) }) + + t.Run("skips stuck tx detection for transactions that do not have enough attempts", func(t *testing.T) { + autoPurgeCfg.minAttempts = ptr(uint32(2)) + stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, chaintype.ChainZkEvm, assets.NewWei(assets.NewEth(100).ToInt()), autoPurgeCfg, feeEstimator, txStore, ethClient) + // Insert tx with enough attempts for detection + _, fromAddress1 := cltest.MustInsertRandomKey(t, ethKeyStore) + etx1 := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress1, 1, blockNum, tenGwei) + attempt := cltest.NewLegacyEthTxAttempt(t, etx1.ID) + attempt.TxFee.Legacy = assets.NewWeiI(2) + attempt.State = txmgrtypes.TxAttemptBroadcast + require.NoError(t, txStore.InsertTxAttempt(ctx, &attempt)) + + // Insert tx that will be skipped for too few attempts + _, fromAddress2 := cltest.MustInsertRandomKey(t, ethKeyStore) + mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress2, 1, blockNum, tenGwei) + + // Return nil response for a tx and a normal response for the other + ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { + return len(b) == 1 + })).Return(nil).Run(func(args mock.Arguments) { + elems := args.Get(1).([]rpc.BatchElem) + elems[0].Result = nil // Return nil to signal discarded tx + }).Once() + + txs, err := stuckTxDetector.DetectStuckTransactions(ctx, []common.Address{fromAddress1, fromAddress2}, blockNum) + require.NoError(t, err) + require.Len(t, txs, 1) + }) } func TestStuckTxDetector_DetectStuckTransactionsScroll(t *testing.T) { diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index 86bf5fcc4b..4d85c26087 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -804,7 +804,8 @@ func TestTxm_GetTransactionStatus(t *testing.T) { require.NoError(t, err) state, err := txm.GetTransactionStatus(ctx, idempotencyKey) require.Equal(t, commontypes.Fatal, state) - require.Error(t, err, evmclient.TerminallyStuckMsg) + require.Error(t, err) + require.Equal(t, evmclient.TerminallyStuckMsg, err.Error()) // Test a terminally stuck client error returns Fatal nonce = evmtypes.Nonce(1) @@ -825,7 +826,8 @@ func TestTxm_GetTransactionStatus(t *testing.T) { require.NoError(t, err) state, err = txm.GetTransactionStatus(ctx, idempotencyKey) require.Equal(t, commontypes.Fatal, state) - require.Error(t, err, evmclient.TerminallyStuckMsg) + require.Error(t, err) + require.Equal(t, terminallyStuckClientError, err.Error()) }) t.Run("returns failed for fatal error state with other error", func(t *testing.T) { From 69335dc6b0837ba9726a2772bf1dc98174c03310 Mon Sep 17 00:00:00 2001 From: Silas Lenihan <32529249+silaslenihan@users.noreply.github.com> Date: Fri, 16 Aug 2024 19:34:16 -0400 Subject: [PATCH 103/432] Expose Confirmed state to ChainWriter (#14138) * Expose Confirmed state to ChainWriter * update comment * Update common/txmgr/txmgr.go Co-authored-by: amit-momin <108959691+amit-momin@users.noreply.github.com> --------- Co-authored-by: amit-momin <108959691+amit-momin@users.noreply.github.com> --- .changeset/afraid-buckets-yell.md | 5 +++++ common/txmgr/txmgr.go | 4 ++-- core/chains/evm/txmgr/txmgr_test.go | 8 ++++---- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- core/services/relay/evm/chain_writer_test.go | 1 + go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 12 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 .changeset/afraid-buckets-yell.md diff --git a/.changeset/afraid-buckets-yell.md b/.changeset/afraid-buckets-yell.md new file mode 100644 index 0000000000..88e9469208 --- /dev/null +++ b/.changeset/afraid-buckets-yell.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#internal Exposed Confirmed state to ChainWriter GetTransactionStatus method diff --git a/common/txmgr/txmgr.go b/common/txmgr/txmgr.go index 49ac8a89b7..28d505e5e0 100644 --- a/common/txmgr/txmgr.go +++ b/common/txmgr/txmgr.go @@ -654,8 +654,8 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) GetTransac } switch tx.State { case TxUnconfirmed, TxConfirmedMissingReceipt: - // Return unconfirmed for ConfirmedMissingReceipt since a receipt is required to determine if it is finalized - return commontypes.Unconfirmed, nil + // Return pending for ConfirmedMissingReceipt since a receipt is required to consider it as unconfirmed + return commontypes.Pending, nil case TxConfirmed: // Return unconfirmed for confirmed transactions because they are not yet finalized return commontypes.Unconfirmed, nil diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index 4d85c26087..d4bfbffd12 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -681,7 +681,7 @@ func TestTxm_GetTransactionStatus(t *testing.T) { require.Equal(t, commontypes.Unknown, state) }) - t.Run("returns unconfirmed for unconfirmed state", func(t *testing.T) { + t.Run("returns pending for unconfirmed state", func(t *testing.T) { idempotencyKey := uuid.New().String() _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) nonce := evmtypes.Nonce(0) @@ -700,7 +700,7 @@ func TestTxm_GetTransactionStatus(t *testing.T) { require.NoError(t, err) state, err := txm.GetTransactionStatus(ctx, idempotencyKey) require.NoError(t, err) - require.Equal(t, commontypes.Unconfirmed, state) + require.Equal(t, commontypes.Pending, state) }) t.Run("returns unconfirmed for confirmed state", func(t *testing.T) { @@ -761,7 +761,7 @@ func TestTxm_GetTransactionStatus(t *testing.T) { require.Equal(t, commontypes.Finalized, state) }) - t.Run("returns unconfirmed for confirmed missing receipt state", func(t *testing.T) { + t.Run("returns pending for confirmed missing receipt state", func(t *testing.T) { idempotencyKey := uuid.New().String() _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) nonce := evmtypes.Nonce(0) @@ -780,7 +780,7 @@ func TestTxm_GetTransactionStatus(t *testing.T) { require.NoError(t, err) state, err := txm.GetTransactionStatus(ctx, idempotencyKey) require.NoError(t, err) - require.Equal(t, commontypes.Unconfirmed, state) + require.Equal(t, commontypes.Pending, state) }) t.Run("returns fatal for fatal error state with terminally stuck error", func(t *testing.T) { diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 43dd930fd5..9f1844693c 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 4efc20bbd5..35226b0de3 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1186,8 +1186,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 h1:5x4kknDjui1m1E5Ad6oXc/sFi6nPN2cQqUfSIdwr5iQ= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 h1:iT9xlcy7Q98F9QheClGBiU0Ig1A+0UhtFkEdKFHvX/0= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/core/services/relay/evm/chain_writer_test.go b/core/services/relay/evm/chain_writer_test.go index 66c85bfc2c..ab8b6f0e36 100644 --- a/core/services/relay/evm/chain_writer_test.go +++ b/core/services/relay/evm/chain_writer_test.go @@ -67,6 +67,7 @@ func TestChainWriter(t *testing.T) { status commontypes.TransactionStatus }{ {uuid.NewString(), commontypes.Unknown}, + {uuid.NewString(), commontypes.Pending}, {uuid.NewString(), commontypes.Unconfirmed}, {uuid.NewString(), commontypes.Finalized}, {uuid.NewString(), commontypes.Failed}, diff --git a/go.mod b/go.mod index 23e6d7efec..7976cbcd44 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index 1a4d97d32a..704b9507c6 100644 --- a/go.sum +++ b/go.sum @@ -1141,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 h1:5x4kknDjui1m1E5Ad6oXc/sFi6nPN2cQqUfSIdwr5iQ= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 h1:iT9xlcy7Q98F9QheClGBiU0Ig1A+0UhtFkEdKFHvX/0= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index ff246ad79a..86a03cec17 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -33,7 +33,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 github.com/smartcontractkit/chainlink-testing-framework v1.34.2 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index df5b1603e3..8af6705473 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1490,8 +1490,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 h1:5x4kknDjui1m1E5Ad6oXc/sFi6nPN2cQqUfSIdwr5iQ= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 h1:iT9xlcy7Q98F9QheClGBiU0Ig1A+0UhtFkEdKFHvX/0= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index a5c61b4005..6e33eb7e39 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.31.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 github.com/smartcontractkit/chainlink-testing-framework v1.34.2 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 91aec9d710..16b3525476 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1472,8 +1472,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4 h1:5x4kknDjui1m1E5Ad6oXc/sFi6nPN2cQqUfSIdwr5iQ= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240815090511-4586e672b8e4/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 h1:iT9xlcy7Q98F9QheClGBiU0Ig1A+0UhtFkEdKFHvX/0= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= From 6ef1d6eb449ee1dc1d7d10d50990de7da55561ee Mon Sep 17 00:00:00 2001 From: amaechiokolobi <168412367+amaechiokolobi@users.noreply.github.com> Date: Sat, 17 Aug 2024 01:09:27 +0100 Subject: [PATCH 104/432] (SHIP-2626) added custom error handling for Treasure (#13981) * added custom error handling for Treasure * added changeset * fix * fixed test * moved Treasure error to Fatal * added treasure fatal * fixed changeset * add changeset * removed extra changeset * added fatal error case test * changeset fix * removed unsed fatal errors --- .changeset/strong-dogs-smash.md | 5 +++++ core/chains/evm/client/errors.go | 8 +++++++- core/chains/evm/client/errors_test.go | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 .changeset/strong-dogs-smash.md diff --git a/.changeset/strong-dogs-smash.md b/.changeset/strong-dogs-smash.md new file mode 100644 index 0000000000..a34a418e65 --- /dev/null +++ b/.changeset/strong-dogs-smash.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +error handling for Treasure #added \ No newline at end of file diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index e7fff8d0db..5980b0dd96 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -161,6 +161,12 @@ var arbitrum = ClientErrors{ ServiceUnavailable: regexp.MustCompile(`(: |^)502 Bad Gateway: [\s\S]*$|network is unreachable|i/o timeout`), } +// Treasure +var treasureFatal = regexp.MustCompile(`(: |^)invalid chain id for signer(:|$)`) +var treasure = ClientErrors{ + Fatal: treasureFatal, +} + var celo = ClientErrors{ TxFeeExceedsCap: regexp.MustCompile(`(: |^)tx fee \([0-9\.]+ of currency celo\) exceeds the configured cap \([0-9\.]+ [a-zA-Z]+\)$`), TerminallyUnderpriced: regexp.MustCompile(`(: |^)gasprice is less than gas price minimum floor`), @@ -270,7 +276,7 @@ var internal = ClientErrors{ TerminallyStuck: regexp.MustCompile(TerminallyStuckMsg), } -var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm, mantle, aStar, gnosis, internal} +var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm, treasure, mantle, aStar, gnosis, internal} // ClientErrorRegexes returns a map of compiled regexes for each error type func ClientErrorRegexes(errsRegex config.ClientErrors) *ClientErrors { diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index 32a1ba2bf3..095e291f5e 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -405,6 +405,7 @@ func Test_Eth_Errors_Fatal(t *testing.T) { {"failed to forward tx to sequencer, please try again. Error message: 'invalid sender'", true, "Mantle"}, {"client error fatal", true, "tomlConfig"}, + {"invalid chain id for signer", true, "Treasure"}, } for _, test := range tests { From 326c1d43a8d12a5b0f5c811612d68e8c4cc3b36b Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Mon, 19 Aug 2024 07:21:19 -0400 Subject: [PATCH 105/432] [TT-1396] [CCIP-2804] Migrates CCIP To testsecrets (#14135) * Ports Over testsecrets * Fixes CCIP Config * Use chain-selectors v1.0.21 * Remove old keys in workflow * Fix go mods --------- Co-authored-by: lukaszcl <120112546+lukaszcl@users.noreply.github.com> --- .../action.yml | 70 +- .github/workflows/ccip-chaos-tests.yml | 45 +- .../ccip-client-compatibility-tests.yml | 743 ------------------ .github/workflows/ccip-live-network-tests.yml | 313 -------- .github/workflows/ccip-load-tests.yml | 41 +- .github/workflows/integration-tests.yml | 35 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- integration-tests/ccip-tests/Makefile | 23 +- integration-tests/ccip-tests/README.md | 25 +- .../ccip-tests/testconfig/README.md | 235 ++++-- .../ccip-tests/testconfig/ccip.go | 12 + .../testconfig/examples/.testsecrets.example | 39 + .../testconfig/examples/secrets.toml.example | 52 -- .../ccip-tests/testconfig/global.go | 214 ++++- 17 files changed, 504 insertions(+), 1355 deletions(-) delete mode 100644 .github/workflows/ccip-client-compatibility-tests.yml delete mode 100644 .github/workflows/ccip-live-network-tests.yml create mode 100644 integration-tests/ccip-tests/testconfig/examples/.testsecrets.example delete mode 100644 integration-tests/ccip-tests/testconfig/examples/secrets.toml.example diff --git a/.github/actions/setup-create-base64-config-ccip/action.yml b/.github/actions/setup-create-base64-config-ccip/action.yml index 88d9fe8078..cb20c886e3 100644 --- a/.github/actions/setup-create-base64-config-ccip/action.yml +++ b/.github/actions/setup-create-base64-config-ccip/action.yml @@ -11,62 +11,39 @@ inputs: default: "false" selectedNetworks: description: The networks to run tests against - chainlinkImage: - description: The chainlink image to use - default: "public.ecr.aws/chainlink/chainlink" chainlinkVersion: description: The git commit sha to use for the image tag - upgradeImage: - description: The chainlink image to upgrade to - default: "" upgradeVersion: - description: The git commit sha to use for the image tag - lokiEndpoint: - description: Loki push endpoint - lokiTenantId: - description: Loki tenant id - lokiBasicAuth: - description: Loki basic auth + description: The git commit sha to use for the image tag logstreamLogTargets: description: Where to send logs (e.g. file, loki) - grafanaUrl: - description: Grafana URL - grafanaDashboardUrl: - description: Grafana dashboard URL - grafanaBearerToken: - description: Grafana bearer token customEvmNodes: description: Custom EVM nodes to use in key=value format, where key is chain id and value is docker image to use. If they are provided the number of networksSelected must be equal to the number of customEvmNodes evmNodeLogLevel: description: Log level for the custom EVM nodes default: "info" +outputs: + base64_config: + description: The base64-encoded config + value: ${{ steps.base64_config_override.outputs.base64_config }} runs: using: composite steps: - name: Prepare Base64 TOML override shell: bash - id: base64-config-override + id: base64_config_override env: RUN_ID: ${{ inputs.runId }} SELECTED_NETWORKS: ${{ inputs.selectedNetworks }} EXISTING_NAMESPACE: ${{ inputs.existingNamespace }} TEST_LOG_COLLECT: ${{ inputs.testLogCollect }} - CHAINLINK_IMAGE: ${{ inputs.chainlinkImage }} CHAINLINK_VERSION: ${{ inputs.chainlinkVersion }} - UPGRADE_IMAGE: ${{ inputs.upgradeImage }} UPGRADE_VERSION: ${{ inputs.upgradeVersion }} - LOKI_ENDPOINT: ${{ inputs.lokiEndpoint }} - LOKI_TENANT_ID: ${{ inputs.lokiTenantId }} - LOKI_BASIC_AUTH: ${{ inputs.lokiBasicAuth }} LOGSTREAM_LOG_TARGETS: ${{ inputs.logstreamLogTargets }} - GRAFANA_URL: ${{ inputs.grafanaUrl }} - GRAFANA_DASHBOARD_URL: ${{ inputs.grafanaDashboardUrl }} - GRAFANA_BEARER_TOKEN: ${{ inputs.grafanaBearerToken }} CUSTOM_EVM_NODES: ${{ inputs.customEvmNodes }} EVM_NODE_LOG_LEVEL: ${{ inputs.evmNodeLogLevel }} run: | - echo ::add-mask::$CHAINLINK_IMAGE function convert_to_toml_array() { local IFS=',' local input_array=($1) @@ -133,11 +110,6 @@ runs: fi fi - grafana_bearer_token="" - if [ -n "$GRAFANA_BEARER_TOKEN" ]; then - grafana_bearer_token="bearer_token_secret=\"$GRAFANA_BEARER_TOKEN\"" - fi - cat << EOF > config.toml [CCIP] [CCIP.Env] @@ -147,13 +119,8 @@ runs: [CCIP.Env.NewCLCluster] [CCIP.Env.NewCLCluster.Common] [CCIP.Env.NewCLCluster.Common.ChainlinkImage] - image="$CHAINLINK_IMAGE" version="$CHAINLINK_VERSION" - [CCIP.Env.NewCLCluster.Common.ChainlinkUpgradeImage] - image="$UPGRADE_IMAGE" - version="$UPGRADE_VERSION" - $custom_nodes_toml [CCIP.Env.Logging] @@ -163,16 +130,6 @@ runs: [CCIP.Env.Logging.LogStream] log_targets=$log_targets - [CCIP.Env.Logging.Loki] - tenant_id="$LOKI_TENANT_ID" - endpoint="$LOKI_ENDPOINT" - basic_auth_secret="$LOKI_BASIC_AUTH" - - [CCIP.Env.Logging.Grafana] - base_url="$GRAFANA_URL" - dashboard_url="$GRAFANA_DASHBOARD_URL" - $grafana_bearer_token - [CCIP.Groups.load] TestRunName = '$EXISTING_NAMESPACE' @@ -181,7 +138,14 @@ runs: EOF - BASE64_CCIP_SECRETS_CONFIG=$(cat config.toml | base64 -w 0) - echo ::add-mask::$BASE64_CCIP_SECRETS_CONFIG - echo "BASE64_CCIP_SECRETS_CONFIG=$BASE64_CCIP_SECRETS_CONFIG" >> $GITHUB_ENV - echo "TEST_BASE64_CCIP_SECRETS_CONFIG=$BASE64_CCIP_SECRETS_CONFIG" >> $GITHUB_ENV + # Check if UPGRADE_VERSION is not empty and append to config.toml + if [ -n "$UPGRADE_VERSION" ]; then + cat << EOF >> config.toml + [CCIP.Env.NewCLCluster.Common.ChainlinkUpgradeImage] + version="$UPGRADE_VERSION" + EOF + fi + + BASE64_CONFIG=$(cat config.toml | base64 -w 0) + echo ::add-mask::$BASE64_CONFIG + echo "base64_config=$BASE64_CONFIG" >> $GITHUB_OUTPUT \ No newline at end of file diff --git a/.github/workflows/ccip-chaos-tests.yml b/.github/workflows/ccip-chaos-tests.yml index 493322ae42..03f809b44c 100644 --- a/.github/workflows/ccip-chaos-tests.yml +++ b/.github/workflows/ccip-chaos-tests.yml @@ -6,8 +6,6 @@ on: branches: [ develop ] workflow_dispatch: - - # Only run 1 of this workflow at a time per PR concurrency: group: chaos-ccip-tests-chainlink-${{ github.ref }} @@ -16,7 +14,7 @@ concurrency: env: # TODO: TT-1470 - Update image names as we solidify new realease strategy CL_ECR: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests:${{ github.sha }} + ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ github.sha }} MOD_CACHE_VERSION: 1 jobs: @@ -124,23 +122,20 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Prepare Base64 TOML override for CCIP secrets uses: ./.github/actions/setup-create-base64-config-ccip + id: setup_create_base64_config_ccip with: runId: ${{ github.run_id }} testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink chainlinkVersion: ${{ github.sha }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: ${{ vars.GRAFANA_URL }} - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - name: Run Chaos Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d38226be720c5ccc1ff4d3cee40608ebf264cd59 # v2.3.26 + env: + BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} + TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} with: test_command_to_run: cd ./integration-tests && go test -timeout 1h -count=1 -json -test.parallel 11 -run 'TestChaosCCIP' ./chaos 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci test_download_vendor_packages_command: make gomod - cl_repo: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - cl_image_tag: ${{ github.sha }} artifacts_location: ./integration-tests/chaos/logs publish_check_name: CCIP Chaos Test Results publish_report_paths: ./tests-chaos-report.xml @@ -154,6 +149,13 @@ jobs: aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} cache_key_id: ccip-load-${{ env.MOD_CACHE_VERSION }} cache_restore_only: "true" + DEFAULT_LOKI_TENANT_ID: ${{ vars.LOKI_TENANT_ID }} + DEFAULT_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} + DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + DEFAULT_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + DEFAULT_GRAFANA_BASE_URL: ${{ vars.GRAFANA_URL }} + DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + ## Notify in slack if the job fails - name: Notify Slack if: failure() && github.event_name != 'workflow_dispatch' @@ -206,23 +208,20 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Prepare Base64 TOML override for CCIP secrests uses: ./.github/actions/setup-create-base64-config-ccip + id: setup_create_base64_config_ccip with: runId: ${{ github.run_id }} testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink chainlinkVersion: ${{ github.sha }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: ${{ vars.GRAFANA_URL }} - grafanaDashboardUrl: "/d/6vjVx-1V8/ccip-long-running-tests" - name: Run Load With Chaos Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d38226be720c5ccc1ff4d3cee40608ebf264cd59 # v2.3.26 + env: + BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} + TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} with: test_command_to_run: cd ./integration-tests/ccip-tests && go test -timeout 2h -count=1 -json -test.parallel 4 -run '^TestLoadCCIPStableWithPodChaosDiffCommitAndExec' ./load 2>&1 | tee /tmp/gotest.log | gotestfmt test_download_vendor_packages_command: make gomod - cl_repo: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - cl_image_tag: ${{ github.sha }} artifacts_location: ./integration-tests/load/logs publish_check_name: CCIP Chaos With Load Test Results publish_report_paths: ./tests-chaos-with-load-report.xml @@ -236,6 +235,12 @@ jobs: aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} cache_key_id: ccip-load-${{ env.MOD_CACHE_VERSION }} cache_restore_only: "true" + DEFAULT_LOKI_TENANT_ID: ${{ vars.LOKI_TENANT_ID }} + DEFAULT_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} + DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + DEFAULT_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + DEFAULT_GRAFANA_BASE_URL: ${{ vars.GRAFANA_URL }} + DEFAULT_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" ## Notify in slack if the job fails - name: Notify Slack if: failure() && github.event_name != 'workflow_dispatch' @@ -250,4 +255,4 @@ jobs: if: always() uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/cleanup@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 with: - triggered_by: ${{ env.TEST_TRIGGERED_BY }} + triggered_by: ${{ env.TEST_TRIGGERED_BY }} \ No newline at end of file diff --git a/.github/workflows/ccip-client-compatibility-tests.yml b/.github/workflows/ccip-client-compatibility-tests.yml deleted file mode 100644 index ff0e4be25c..0000000000 --- a/.github/workflows/ccip-client-compatibility-tests.yml +++ /dev/null @@ -1,743 +0,0 @@ -name: CCIP Client Compatibility Tests -on: - schedule: - - cron: "30 5 * * TUE,FRI" # Run every Tuesday and Friday at midnight + 30min EST - push: - tags: - - "*" - merge_group: - pull_request: - workflow_dispatch: - inputs: - chainlinkVersion: - description: commit SHA or tag of the Chainlink version to test - required: true - type: string - evmImplementations: - description: comma separated list of EVM implementations to test (ignored if base64TestList is used) - required: true - type: string - default: "geth,besu,nethermind,erigon" - latestVersionsNumber: - description: how many of latest images of EVM implementations to test with (ignored if base64TestList is used) - required: true - type: number - default: 3 - base64TestList: - description: base64 encoded list of tests to run (same as base64-ed output of testlistgenerator tool) - required: false - type: string - -env: - # TODO: TT-1470 - Update image names as we solidify new realease strategy - CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/ccip - INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com - MOD_CACHE_VERSION: 2 - -jobs: - # Build Test Dependencies - - check-dependency-bump: - name: Check for go-ethereum dependency bump - if: github.event_name == 'pull_request' || github.event_name == 'merge_queue' - runs-on: ubuntu-latest - outputs: - dependency_changed: ${{ steps.changes.outputs.dependency_changed }} - steps: - - name: Checkout code - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - fetch-depth: 0 - - name: Check for go.mod changes - id: changes - run: | - git fetch origin ${{ github.base_ref }} - # if no match is found then grep exits with code 1, but if there is a match it exits with code 0 - # this will return a match if there are any changes on that corresponding line, for example if spacing was changed - DEPENDENCY_CHANGED=$(git diff -U0 origin/${{ github.base_ref }}...HEAD -- go.mod | grep -q 'github.com/ethereum/go-ethereum'; echo $?) - PR_VERSION=$(grep 'github.com/ethereum/go-ethereum' go.mod | awk '{print $2}') - - # here 0 means a match was found, 1 means no match was found - if [ "$DEPENDENCY_CHANGED" -eq 0 ]; then - # Dependency was changed in the PR, now compare with the base branch - git fetch origin ${{ github.base_ref }} - BASE_VERSION=$(git show origin/${{ github.base_ref }}:go.mod | grep 'github.com/ethereum/go-ethereum' | awk '{print $2}') - - echo "Base branch version: $BASE_VERSION" - echo "PR branch version: $PR_VERSION" - - echo "Dependency version changed in the PR compared to the base branch." - echo "dependency_changed=true" >> $GITHUB_OUTPUT - else - echo "No changes to ethereum/go-ethereum dependency in the PR." - echo "PR branch version: $PR_VERSION" - echo "dependency_changed=false" >> $GITHUB_OUTPUT - fi - - should-run: - if: always() - name: Check if the job should run - needs: check-dependency-bump - runs-on: ubuntu-latest - outputs: - should_run: ${{ steps.should-run.outputs.should_run }} - eth_implementations : ${{ steps.should-run.outputs.eth_implementations }} - env: - GITHUB_REF_TYPE: ${{ github.ref_type }} - steps: - - name: Check if the job should run - id: should-run - run: | - if [ "${{ needs.check-dependency-bump.outputs.dependency_changed }}" == "true" ]; then - echo "Will run tests, because go-ethereum dependency was bumped" - echo "should_run=true" >> $GITHUB_OUTPUT - elif [ "$GITHUB_EVENT_NAME" = "schedule" ]; then - echo "Will run tests, because trigger event was $GITHUB_EVENT_NAME" - echo "should_run=true" >> $GITHUB_OUTPUT - elif [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then - echo "Will run tests, because trigger event was $GITHUB_EVENT_NAME" - echo "should_run=true" >> $GITHUB_OUTPUT - elif [ "$GITHUB_REF_TYPE" = "tag" ]; then - echo "Will run tests, because new tag was created" - echo "should_run=true" >> $GITHUB_OUTPUT - else - echo "Will not run tests" - echo "should_run=false" >> $GITHUB_OUTPUT - fi - - select-versions: - if: always() && needs.should-run.outputs.should_run == 'true' - name: Select Versions - needs: should-run - runs-on: ubuntu-latest - env: - RELEASED_DAYS_AGO: 4 - GITHUB_REF_TYPE: ${{ github.ref_type }} - outputs: - evm_implementations : ${{ steps.select-implementations.outputs.evm_implementations }} - chainlink_version: ${{ steps.select-chainlink-version.outputs.chainlink_version }} - latest_image_count: ${{ steps.get-image-count.outputs.image_count }} - steps: - # ghlatestreleasechecker is a tool to check if new release is available for a given repo - - name: Set Up ghlatestreleasechecker - shell: bash - run: | - go install github.com/smartcontractkit/chainlink-testing-framework/tools/ghlatestreleasechecker@v1.0.0 - - name: Select EVM implementations to test - id: select-implementations - run: | - PATH=$PATH:$(go env GOPATH)/bin - export PATH - - if [ "$GITHUB_EVENT_NAME" = "schedule" ]; then - echo "Checking for new releases" - implementations_arr=() - new_geth=$(ghlatestreleasechecker "ethereum/go-ethereum" $RELEASED_DAYS_AGO) - if [ "$new_geth" != "none" ]; then - echo "New geth release found: $new_geth" - implementations_arr+=("geth") - fi - new_besu=$(ghlatestreleasechecker "hyperledger/besu" $RELEASED_DAYS_AGO) - if [ "new_besu" != "none" ]; then - echo "New besu release found: $new_besu" - implementations_arr+=("besu") - fi - new_erigon=$(ghlatestreleasechecker "ledgerwatch/erigon" $RELEASED_DAYS_AGO) - if [ "new_erigon" != "none" ]; then - echo "New erigon release found: $new_erigon" - implementations_arr+=("erigon") - fi - new_nethermind=$(ghlatestreleasechecker "nethermindEth/nethermind" $RELEASED_DAYS_AGO) - if [ "new_nethermind" != "none" ]; then - echo "New nethermind release found: $new_nethermind" - implementations_arr+=("nethermind") - fi - IFS=',' - eth_implementations="${implementations_arr[*]}" - echo "Found new releases for: $eth_implementations" - echo "evm_implementations=$eth_implementations" >> $GITHUB_OUTPUT - elif [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then - if [ -n "${{ github.event.inputs.base64TestList }}" ]; then - echo "Base64-ed Test Input provided, ignoring EVM implementations" - else - echo "Will test following EVM implementations: ${{ github.event.inputs.evmImplementations }}" - echo "evm_implementations=${{ github.event.inputs.evmImplementations }}" >> $GITHUB_OUTPUT - fi - else - echo "Will test all EVM implementations" - echo "evm_implementations=geth,besu,nethermind,erigon" >> $GITHUB_OUTPUT - fi - - name: Select Chainlink CCIP version - id: select-chainlink-version - run: | - PATH=$PATH:$(go env GOPATH)/bin - export PATH - - if [ "$GITHUB_EVENT_NAME" = "schedule" ]; then - echo "Fetching latest Chainlink CCIP stable version" - implementations_arr=() - # we use 100 days since we really want the latest one, and it's highly improbable there won't be a release in last 100 days - chainlink_version=$(ghlatestreleasechecker "smartcontractkit/ccip" 100) - echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT - elif [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then - echo "Fetching Chainlink version from input" - if [ -n "${{ github.event.inputs.chainlinkVersion }}" ]; then - echo "Chainlink version provided in input" - chainlink_version="${{ github.event.inputs.chainlinkVersion }}" - else - echo "Chainlink version not provided in input. Using latest commit SHA." - chainlink_version=${{ github.sha }} - fi - echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT - elif [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then - echo "Fetching Chainlink version from PR's head commit" - chainlink_version="${{ github.event.pull_request.head.sha }}" - echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT - elif [ "$GITHUB_EVENT_NAME" = "merge_queue" ]; then - echo "Fetching Chainlink version from merge queue's head commit" - chainlink_version="${{ github.event.merge_group.head_sha }}" - echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT - elif [ "$GITHUB_REF_TYPE" = "tag" ]; then - echo "Fetching Chainlink version from tag" - chainlink_version="${{ github.ref_name }}" - echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT - else - echo "Unsupported trigger event. It's probably an issue with the pipeline definition. Please reach out to the Test Tooling team." - exit 1 - fi - echo "Will use following Chainlink version: $chainlink_version" - - name: Get image count - id: get-image-count - run: | - if [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then - echo "Fetching latest image count from input" - if [ -n "${{ github.event.inputs.base64TestList }}" ]; then - echo "Base64-ed Test Input provided, ignoring latest image count" - else - image_count="${{ github.event.inputs.latestVersionsNumber }}" - echo "image_count=$image_count" >> $GITHUB_OUTPUT - fi - else - echo "Fetching default latest image count" - image_count=3 - echo "image_count=$image_count" >> $GITHUB_OUTPUT - fi - echo "Will use following latest image count: $image_count" - - check-ecr-images-exist: - name: Check images used as test dependencies exist in ECR - if: always() && needs.should-run.outputs.should_run == 'true' - environment: integration - permissions: - id-token: write - contents: read - needs: [should-run] - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - mirror: - - name: ethereum/client-go - expression: '^(alltools-v|v)[0-9]\.[0-9]+\.[0-9]+$' - - name: hyperledger/besu - expression: '^[0-9]+\.[0-9]+(\.[0-9]+)?$' - page_size: 300 - - name: thorax/erigon - expression: '^v[0-9]+\.[0-9]+\.[0-9]+$' - - name: nethermind/nethermind - expression: '^[0-9]+\.[0-9]+\.[0-9]+$' - - name: tofelb/ethereum-genesis-generator - expression: '^[0-9]+\.[0-9]+\.[0-9]+(\-slots\-per\-epoch)?' - steps: - - name: Update internal ECR if the latest Ethereum client image does not exist - uses: smartcontractkit/chainlink-testing-framework/.github/actions/update-internal-mirrors@5eea86ee4f7742b4e944561a570a6b268e712d9e # v1.30.3 - with: - aws_region: ${{ secrets.QA_AWS_REGION }} - role_to_assume: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - aws_account_number: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - image_name: ${{matrix.mirror.name}} - expression: ${{matrix.mirror.expression}} - page_size: ${{matrix.mirror.page_size}} - - build-chainlink: - if: always() && needs.should-run.outputs.should_run == 'true' - environment: integration - permissions: - id-token: write - contents: read - name: Build Chainlink Image - needs: [should-run, select-versions] - runs-on: ubuntu-latest - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: client-compatablility-build-chainlink - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Chainlink Image - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ needs.select-versions.outputs.chainlink_version }} - - name: Build Chainlink Image - uses: ./.github/actions/build-chainlink-image - with: - tag_suffix: "" - dockerfile: core/chainlink.Dockerfile - git_commit_sha: ${{ needs.select-versions.outputs.chainlink_version }} - check_image_exists: 'true' - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - get-latest-available-images: - name: Get Latest EVM Implementation's Images - if: always() && needs.should-run.outputs.should_run == 'true' - environment: integration - runs-on: ubuntu-latest - needs: [check-ecr-images-exist, should-run, select-versions] - permissions: - id-token: write - contents: read - env: - LATEST_IMAGE_COUNT: ${{ needs.select-versions.outputs.latest_image_count }} - outputs: - geth_images: ${{ env.GETH_IMAGES }} - nethermind_images: ${{ env.NETHERMIND_IMAGES }} - besu_images: ${{ env.BESU_IMAGES }} - erigon_images: ${{ env.ERIGON_IMAGES }} - steps: - # Setup AWS creds - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 - with: - aws-region: ${{ secrets.QA_AWS_REGION }} - role-to-assume: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - role-duration-seconds: 3600 - # Login to ECR - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@062b18b96a7aff071d4dc91bc00c4c1a7945b076 # v2.0.1 - with: - mask-password: "true" - env: - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - # ecrimagefetcher is a tool to get latest images from ECR - - name: Set Up ecrimagefetcher - shell: bash - run: | - go install github.com/smartcontractkit/chainlink-testing-framework/tools/ecrimagefetcher@v1.0.1 - - name: Get latest docker images from ECR - if: ${{ github.event.inputs.base64TestList == '' }} - env: - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - ETH_IMPLEMENTATIONS: ${{ needs.select-versions.outputs.evm_implementations }} - run: | - PATH=$PATH:$(go env GOPATH)/bin - export PATH - if [[ "$ETH_IMPLEMENTATIONS" == *"geth"* ]]; then - geth_images=$(ecrimagefetcher 'ethereum/client-go' '^v[0-9]+\.[0-9]+\.[0-9]+$' ${{ env.LATEST_IMAGE_COUNT }}) - echo "GETH_IMAGES=$geth_images" >> $GITHUB_ENV - echo "Geth latest images: $geth_images" - fi - - if [[ "$ETH_IMPLEMENTATIONS" == *"nethermind"* ]]; then - nethermind_images=$(ecrimagefetcher 'nethermind/nethermind' '^[0-9]+\.[0-9]+\.[0-9]+$' ${{ env.LATEST_IMAGE_COUNT }}) - echo "NETHERMIND_IMAGES=$nethermind_images" >> $GITHUB_ENV - echo "Nethermind latest images: $nethermind_images" - fi - - if [[ "$ETH_IMPLEMENTATIONS" == *"besu"* ]]; then - # 24.3.3 is ignored as it doesn't support data & input fields in eth_call - besu_images=$(ecrimagefetcher 'hyperledger/besu' '^[0-9]+\.[0-9]+(\.[0-9]+)?$' ${{ env.LATEST_IMAGE_COUNT }} ">=24.5.1") - echo "BESU_IMAGES=$besu_images" >> $GITHUB_ENV - echo "Besu latest images: $besu_images" - fi - - if [[ "$ETH_IMPLEMENTATIONS" == *"erigon"* ]]; then - # 2.60.0 and 2.60.1 are ignored as they stopped working with CL node - erigon_images=$(ecrimagefetcher 'thorax/erigon' '^v[0-9]+\.[0-9]+\.[0-9]+$' ${{ env.LATEST_IMAGE_COUNT }} "> $GITHUB_ENV - echo "Erigon latest images: $erigon_images" - fi - - # End Build Test Dependencies - - prepare-compatibility-matrix: - name: Prepare Compatibility Matrix - if: always() && needs.should-run.outputs.should_run == 'true' - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [get-latest-available-images,should-run,select-versions] - runs-on: ubuntu-latest - env: - ETH_IMPLEMENTATIONS: ${{ needs.select-versions.outputs.evm_implementations }} - BASE64_TEST_LIST: ${{ github.event.inputs.base64TestList }} - outputs: - matrix: ${{ env.JOB_MATRIX_JSON }} - steps: - - name: Decode Base64 Test List Input if Set - if: env.BASE64_TEST_LIST != '' - run: | - echo "Decoding base64 tests list from the input" - DECODED_BASE64_TEST_LIST=$(echo $BASE64_TEST_LIST | base64 -d) - echo "Decoded input:" - echo "$DECODED_BASE64_TEST_LIST" - is_valid=$(echo "$DECODED_BASE64_TEST_LIST" | jq . > /dev/null 2>&1; echo $?) - if [ "$is_valid" -ne 0 ]; then - echo "Invalid base64 input. Please provide a valid base64 encoded JSON list of tests." - echo "Here is an example of valid JSON:" - cat <> $GITHUB_ENV - # testlistgenerator is a tool that builds a matrix of tests to run - - name: Set Up testlistgenerator - if: env.BASE64_TEST_LIST == '' - shell: bash - run: | - go install github.com/smartcontractkit/chainlink-testing-framework/tools/testlistgenerator@v1.1.0 - - name: Prepare matrix input - if: env.BASE64_TEST_LIST == '' - run: | - PATH=$PATH:$(go env GOPATH)/bin - export PATH - - if [[ "$ETH_IMPLEMENTATIONS" == *"geth"* ]]; then - echo "Will test compatibility with geth" - testlistgenerator -o compatibility_test_list.json -p ccip -r TestSmokeCCIPForBidirectionalLane -f './ccip-tests/smoke/ccip_test.go' -e geth -d "${{ needs.get-latest-available-images.outputs.geth_images }}" -t "ccip-geth-compatibility-test" -w "SIMULATED_1,SIMULATED_2" -c 1337,2337 -n ubuntu-latest - else - echo "Will not test compatibility with geth" - fi - - if [[ "$ETH_IMPLEMENTATIONS" == *"besu"* ]]; then - echo "Will test compatibility with besu" - testlistgenerator -o compatibility_test_list.json -p ccip -r TestSmokeCCIPForBidirectionalLane -f './ccip-tests/smoke/ccip_test.go' -e besu -d "${{ needs.get-latest-available-images.outputs.besu_images }}" -t "ccip-besu-compatibility-test" -w "SIMULATED_BESU_NONDEV_1,SIMULATED_BESU_NONDEV_2" -c 1337,2337 -n ubuntu-latest - else - echo "Will not test compatibility with besu" - fi - - # TODO: Waiting for CCIP-2255 to be resolved - if [[ "$ETH_IMPLEMENTATIONS" == *"erigon"* ]]; then - echo "Will test compatibility with erigon" - testlistgenerator -o compatibility_test_list.json -p ccip -r TestSmokeCCIPForBidirectionalLane -f './ccip-tests/smoke/ccip_test.go' -e erigon -d "${{ needs.get-latest-available-images.outputs.erigon_images }}" -t "ccip-erigon-compatibility-test" -w "SIMULATED_1,SIMULATED_2" -c 1337,2337 -n ubuntu-latest - else - echo "Will not test compatibility with erigon" - fi - - # TODO: uncomment when nethermind flake reason is addressed - if [[ "$ETH_IMPLEMENTATIONS" == *"nethermind"* ]]; then - echo "Will not test compatibility with nethermind due to flakiness" - # echo "Will test compatibility with nethermind" - # testlistgenerator -o compatibility_test_list.json -p ccip -r TestSmokeCCIPForBidirectionalLane -f './ccip-tests/smoke/ccip_test.go' -e nethermind -d "${{ needs.get-latest-available-images.outputs.nethermind_images }}" -t "ccip-nethermind-compatibility-test" -w "SIMULATED_1,SIMULATED_2" -c 1337,2337 -n ubuntu-latest - else - echo "Will not test compatibility with nethermind" - fi - - jq . compatibility_test_list.json - echo "Adding human-readable name" - jq 'map(. + {visible_name: (.docker_image | split(",")[0] | split("=")[1])})' compatibility_test_list.json > compatibility_test_list_modified.json - jq . compatibility_test_list_modified.json - JOB_MATRIX_JSON=$(jq -c . compatibility_test_list_modified.json) - echo "JOB_MATRIX_JSON=${JOB_MATRIX_JSON}" >> $GITHUB_ENV - - run-client-compatibility-matrix: - name: CCIP Compatibility with ${{ matrix.evm_node.visible_name }} - if: always() && needs.should-run.outputs.should_run == 'true' - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, prepare-compatibility-matrix, should-run, select-versions] - env: - CHAINLINK_COMMIT_SHA: ${{ needs.select-versions.outputs.chainlink_version }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: debug - strategy: - fail-fast: false - matrix: - evm_node: ${{fromJson(needs.prepare-compatibility-matrix.outputs.matrix)}} - runs-on: ubuntu-latest - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ needs.select-versions.outputs.chainlink_version }} - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - selectedNetworks: ${{ matrix.evm_node.networks }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ needs.select-versions.outputs.chainlink_version }} - pyroscopeServer: ${{ !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ci-ccip-bidirectional-lane-${{ matrix.evm_node.name }} - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - lokiEndpoint: ${{ secrets.LOKI_URL_CI }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: ${{ vars.GRAFANA_URL }} - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - - name: Prepare Base64 TOML override for CCIP secrets - uses: ./.github/actions/setup-create-base64-config-ccip - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - selectedNetworks: ${{ matrix.evm_node.networks }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ needs.select-versions.outputs.chainlink_version }} - lokiEndpoint: ${{ secrets.LOKI_URL_CI }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: ${{ vars.GRAFANA_URL }} - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - customEvmNodes: ${{ matrix.evm_node.docker_image }} - evmNodeLogLevel: "trace" - - name: Prepare test log name - run: | - replace_special_chars() { - if [ -z "$1" ]; then - echo "Please provide a string as an argument." - return 1 - fi - - local input_string="$1" - - # Replace '/' with '-' - local modified_string="${input_string//\//-}" - - # Replace ':' with '-' - modified_string="${modified_string//:/-}" - - # Replace '.' with '-' - modified_string="${modified_string//./-}" - - echo "$modified_string" - } - echo "TEST_LOG_NAME=$(replace_special_chars "ccip-${{ matrix.evm_node.name }}-test-logs")" >> $GITHUB_ENV - - name: Print Test details - ${{ matrix.evm_node.docker_image }} - run: | - echo "EVM Implementation Docker Image: ${{ matrix.evm_node.docker_image }}" - echo "EVM Implementation Networks: ${{ matrix.evm_node.networks }}" - echo "Test identifier: ${{ matrix.evm_node.name }}" - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@fc3e0df622521019f50d772726d6bf8dc919dd38 # v2.3.19 - with: - test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=2 ${{ matrix.evm_node.run }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci - test_download_vendor_packages_command: cd ./integration-tests && go mod download - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ needs.select-versions.outputs.chainlink_version }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: ${{ env.TEST_LOG_NAME }} - artifacts_location: | - ./integration-tests/smoke/logs/ - ./integration-tests/ccip-tests/smoke/logs/* - /tmp/gotest.log - publish_check_name: ${{ matrix.evm_node.name }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: "" - should_tidy: "false" - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@1587f59bfd626b668d303abbc90fee41b12397e6 # v2.3.23 - with: - test_directories: ./integration-tests/smoke/,./integration-tests/ccip-tests/smoke/ - - start-slack-thread: - name: Start Slack Thread - if: ${{ always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' && needs.should-run.outputs.should_run == 'true' }} - environment: integration - outputs: - thread_ts: ${{ steps.slack.outputs.thread_ts }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - runs-on: ubuntu-latest - needs: [run-client-compatibility-matrix,should-run,select-versions] - steps: - - name: Debug Result - run: echo ${{ join(needs.*.result, ',') }} - - name: Main Slack Notification - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - id: slack - with: - channel-id: ${{ secrets.QA_CCIP_SLACK_CHANNEL }} - payload: | - { - "attachments": [ - { - "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || '#2E7D32' }}", - "blocks": [ - { - "type": "header", - "text": { - "type": "plain_text", - "text": "CCIP Compatibility Test Results ${{ contains(join(needs.*.result, ','), 'failure') && ':x:' || ':white_check_mark:'}}", - "emoji": true - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "${{ contains(join(needs.*.result, ','), 'failure') && 'Some tests failed! Notifying ' || 'All Good!' }}" - } - }, - { - "type": "divider" - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "<${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}> | <${{ github.server_url }}/${{ github.repository }}/commit/${{ needs.select-versions.outputs.chainlink_version }}|${{ needs.select-versions.outputs.chainlink_version }}> | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Run>" - } - } - ] - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - - parse-test-results: - name: Parse Test Results - if: always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' && needs.should-run.outputs.should_run == 'true' - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - runs-on: ubuntu-latest - needs: [run-client-compatibility-matrix,should-run] - outputs: - base64_parsed_results: ${{ steps.get-test-results.outputs.base64_parsed_results }} - steps: - # workflowresultparser is a tool to get job results from a workflow run - - name: Set Up workflowresultparser - shell: bash - run: | - go install github.com/smartcontractkit/chainlink-testing-framework/tools/workflowresultparser@v1.0.0 - - name: Get and parse Test Results - shell: bash - id: get-test-results - run: | - PATH=$PATH:$(go env GOPATH)/bin - export PATH - - workflowresultparser -workflowRunID ${{ github.run_id }} -githubToken ${{ github.token }} -githubRepo "${{ github.repository }}" -jobNameRegex "^CCIP Compatibility with (.*)$" -namedKey="CCIP" -outputFile=output.json - - echo "base64_parsed_results=$(base64 -w 0 output.json)" >> $GITHUB_OUTPUT - - display-test-results: - name: Aggregated test results - if: always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' && needs.should-run.outputs.should_run == 'true' && needs.parse-test-results.result == 'success' - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - runs-on: ubuntu-latest - needs: [start-slack-thread, should-run, select-versions, parse-test-results] - steps: - # asciitable is a tool that prints results in a nice ASCII table - - name: Set Up asciitable - shell: bash - run: | - go install github.com/smartcontractkit/chainlink-testing-framework/tools/asciitable@v1.0.2 - - name: Print aggregated test results - shell: bash - run: | - PATH=$PATH:$(go env GOPATH)/bin - export PATH - - raw_results="$(echo ${{ needs.parse-test-results.outputs.base64_parsed_results }} | base64 -d)" - echo $raw_results > input.json - asciitable --firstColumn "EVM Implementation" --secondColumn Result --jsonfile input.json --outputFile output.txt --section "CCIP" --namedKey "CCIP" - - echo - echo "AGGREGATED RESULTS" - cat output.txt - - echo "## Aggregated EVM Implementations compatibility results summary" >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - cat output.txt >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - - post-test-results-to-slack: - name: Post Test Results - if: ${{ always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' && needs.should-run.outputs.should_run == 'true' }} - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - runs-on: ubuntu-latest - needs: [start-slack-thread,should-run,select-versions] - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ needs.select-versions.outputs.chainlink_version }} - - name: Get test results for CCIP - id: get-product-results - shell: bash - run: | - raw_results="$(echo ${{ needs.parse-test-results.outputs.base64_parsed_results }} | base64 -d)" - product_result=$(echo "$raw_results" | jq -c "select(has(\"CCIP\")) | .CCIP[]") - if [ -n "$product_result" ]; then - base64_result=$(echo $product_result | base64 -w 0) - echo "base64_result=$base64_result" >> $GITHUB_OUTPUT - else - echo "No results found for CCIP" - echo "base64_result=" >> $GITHUB_OUTPUT - fi - - name: Post Test Results to Slack - uses: ./.github/actions/notify-slack-jobs-result - with: - github_token: ${{ github.token }} - github_repository: ${{ github.repository }} - workflow_run_id: ${{ github.run_id }} - github_job_name_regex: ^CCIP Compatibility with (.*?)$ - message_title: CCIP Compatibility Test Results - slack_channel_id: ${{ secrets.QA_CCIP_SLACK_CHANNEL }} - slack_bot_token: ${{ secrets.QA_SLACK_API_KEY }} - slack_thread_ts: ${{ needs.start-slack-thread.outputs.thread_ts }} - base64_parsed_results: ${{ steps.get-product-results.outputs.base64_result }} diff --git a/.github/workflows/ccip-live-network-tests.yml b/.github/workflows/ccip-live-network-tests.yml deleted file mode 100644 index 6649a881b9..0000000000 --- a/.github/workflows/ccip-live-network-tests.yml +++ /dev/null @@ -1,313 +0,0 @@ -name: CCIP Live Network Tests -on: - # TODO: TT-1470 - Turn back on as we solidify new realease and image strategy - # schedule: - # - cron: '0 */6 * * *' - workflow_dispatch: - inputs: - base64_test_input : # base64 encoded toml for test input - description: 'Base64 encoded toml test input' - required: false - slackMemberID: - description: 'Slack member ID to notify' - required: false - test_type: - description: 'Type of test to run' - required: false - type: choice - options: - - 'load' - - 'smoke' - -# Only run 1 of this workflow at a time per PR -concurrency: - group: live-testnet-tests - cancel-in-progress: true - -env: - # TODO: TT-1470 - Update image names as we solidify new realease strategy - CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - CHAINLINK_VERSION: ${{ github.sha}} - CHAINLINK_TEST_VERSION: ${{ github.sha}} - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests:${{ github.sha }} - INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com - AWS_ECR_REPO_PUBLIC_REGISTRY: public.ecr.aws - -jobs: - build-chainlink: - environment: integration - permissions: - id-token: write - contents: read - name: Build Chainlink Image - runs-on: ubuntu20.04-16cores-64GB - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Check if image exists - id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 - with: - repository: chainlink - tag: ${{ env.CHAINLINK_VERSION }} - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - name: Build Image - if: steps.check-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 - env: - GH_TOKEN: ${{ github.token }} - with: - cl_repo: smartcontractkit/chainlink-ccip - cl_ref: ${{ env.CHAINLINK_VERSION }} - push_tag: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:${{ env.CHAINLINK_VERSION }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: ccip-on-demand-live-testnet-tests-build-chainlink-image - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Chainlink Image - continue-on-error: true - - build-test-image: - environment: integration - permissions: - id-token: write - contents: read - name: Build Test Image - runs-on: ubuntu20.04-16cores-64GB - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: ccip-on-demand-live-testnet-tests-build-test-image - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Test Image - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Build Test Image - uses: ./.github/actions/build-test-image - with: - tag: ${{ env.CHAINLINK_TEST_VERSION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - - ccip-load-test: - name: CCIP Load Test - environment: integration - runs-on: ubuntu-latest - strategy: - matrix: - config: [mainnet.toml] - needs: [ build-chainlink, build-test-image ] - # if the event is a scheduled event or the test type is load and no previous job failed - if: ${{ (github.event_name == 'schedule' || inputs.test_type == 'load') && !contains(needs.*.result, 'failure') }} - permissions: - issues: read - checks: write - pull-requests: write - id-token: write - contents: read - env: - CHAINLINK_ENV_USER: ${{ github.actor }} - SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} - SLACK_CHANNEL: ${{ secrets.QA_SLACK_CHANNEL }} - TEST_LOG_LEVEL: info - REF_NAME: ${{ github.head_ref || github.ref_name }} - ENV_JOB_IMAGE_BASE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests - BASE64_NETWORK_CONFIG: ${{ secrets.BASE64_NETWORK_CONFIG }} - - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: ccip-on-demand-live-testnet-tests-load-tests - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: CCIP Load Test - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ env.REF_NAME }} - - name: Prepare Base64 TOML override - shell: bash - run: | - # this key secrets.QA_SHARED_803C_KEY has a story behind it. To know more, see CCIP-2875 and SECHD-16575 tickets. - BASE64_NETWORK_CONFIG=$(echo $BASE64_NETWORK_CONFIG | base64 -w 0 -d | sed -e 's/evm_key/${{ secrets.QA_SHARED_803C_KEY }}/g' | base64 -w 0) - echo ::add-mask::$BASE64_NETWORK_CONFIG - echo "BASE64_NETWORK_CONFIG=$BASE64_NETWORK_CONFIG" >> "$GITHUB_ENV" - SLACK_USER=$(jq -r '.inputs.slackMemberID' $GITHUB_EVENT_PATH) - echo ::add-mask::$SLACK_USER - echo "SLACK_USER=$SLACK_USER" >> "$GITHUB_ENV" - if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then - BASE64_CCIP_CONFIG_OVERRIDE=$(jq -r '.inputs.base64_test_input' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE - echo "BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV - echo "TEST_BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV - fi - if [[ "${{ github.event_name }}" == "schedule" ]]; then - BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -w 0 -i ./integration-tests/ccip-tests/testconfig/override/${{ matrix.config }}) - echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE - echo "BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV - echo "TEST_BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV - echo "SLACK_USER=${{ secrets.QA_SLACK_USER }}" >> $GITHUB_ENV - fi - - name: step summary - shell: bash - run: | - echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_VERSION }}\`" >> $GITHUB_STEP_SUMMARY - echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_TEST_VERSION }}\`" >> $GITHUB_STEP_SUMMARY - - name: Prepare Base64 TOML override for CCIP secrets - uses: ./.github/actions/setup-create-base64-config-ccip - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: ${{ vars.GRAFANA_URL }} - grafanaDashboardUrl: "/d/6vjVx-1V8/ccip-long-running-tests" - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 - env: - TEST_SUITE: load - TEST_ARGS: -test.timeout 900h - DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable - RR_MEM: 8Gi - RR_CPU: 4 - DETACH_RUNNER: true - TEST_TRIGGERED_BY: ccip-load-test-ci - with: - test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 70m -count=1 -json -run ^TestLoadCCIPStableRPS$ ./load 2>&1 | tee /tmp/gotest.log | gotestfmt - test_download_vendor_packages_command: cd ./integration-tests && go mod download - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ env.CHAINLINK_VERSION }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - triggered_by: ${{ env.TEST_TRIGGERED_BY }} - artifacts_location: ./integration-tests/load/logs/payload_ccip.json - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - cache_key_id: ccip-load-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - should_cleanup: false - - ccip-smoke-test: - name: CCIP smoke Test - environment: integration - runs-on: ubuntu-latest - needs: [ build-chainlink, build-test-image ] - # if the event is a scheduled event or the test type is load and no previous job failed - if: ${{ github.event_name == 'workflow_dispatch' && inputs.test_type == 'smoke' && !contains(needs.*.result, 'failure') }} - permissions: - issues: read - checks: write - pull-requests: write - id-token: write - contents: read - env: - CHAINLINK_ENV_USER: ${{ github.actor }} - SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} - SLACK_CHANNEL: ${{ secrets.QA_SLACK_CHANNEL }} - TEST_LOG_LEVEL: info - REF_NAME: ${{ github.head_ref || github.ref_name }} - ENV_JOB_IMAGE_BASE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests - BASE64_NETWORK_CONFIG: ${{ secrets.BASE64_NETWORK_CONFIG }} - - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: ccip-on-demand-live-testnet-tests-smoke-test - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: CCIP Smoke Test - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ env.REF_NAME }} - - name: Prepare Base64 TOML override - shell: bash - run: | - BASE64_NETWORK_CONFIG=$(echo $BASE64_NETWORK_CONFIG | base64 -w 0 -d | sed -e 's/evm_key/${{ secrets.QA_SHARED_803C_KEY }}/g' | base64 -w 0) - echo ::add-mask::$BASE64_NETWORK_CONFIG - echo "BASE64_NETWORK_CONFIG=$BASE64_NETWORK_CONFIG" >> "$GITHUB_ENV" - SLACK_USER=$(jq -r '.inputs.slackMemberID' $GITHUB_EVENT_PATH) - echo ::add-mask::$SLACK_USER - echo "SLACK_USER=$SLACK_USER" >> "$GITHUB_ENV" - if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then - BASE64_CCIP_CONFIG_OVERRIDE=$(jq -r '.inputs.base64_test_input' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE - echo "BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV - echo "TEST_BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV - fi - - name: step summary - shell: bash - run: | - echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_VERSION }}\`" >> $GITHUB_STEP_SUMMARY - echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_TEST_VERSION }}\`" >> $GITHUB_STEP_SUMMARY - - name: Prepare Base64 TOML override for CCIP secrets - uses: ./.github/actions/setup-create-base64-config-ccip - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: ${{ vars.GRAFANA_URL }} - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 - env: - TEST_SUITE: smoke - TEST_ARGS: -test.timeout 900h - DETACH_RUNNER: true - DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable - RR_MEM: 8Gi - RR_CPU: 4 - TEST_TRIGGERED_BY: ccip-smoke-test-ci - with: - test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 70m -count=1 -p 30 -json -run ^TestSmokeCCIPForBidirectionalLane$ ./smoke 2>&1 | tee /tmp/gotest.log | gotestfmt - test_download_vendor_packages_command: cd ./integration-tests && go mod download - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ env.CHAINLINK_VERSION }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - triggered_by: ${{ env.TEST_TRIGGERED_BY }} - artifacts_location: ./integration-tests/smoke/logs/payload_ccip.json - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - cache_key_id: ccip-smoke-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - should_cleanup: false \ No newline at end of file diff --git a/.github/workflows/ccip-load-tests.yml b/.github/workflows/ccip-load-tests.yml index 0d53d803d1..a6d073715d 100644 --- a/.github/workflows/ccip-load-tests.yml +++ b/.github/workflows/ccip-load-tests.yml @@ -13,6 +13,10 @@ on: base64_test_input: # base64 encoded toml for test input description: 'Base64 encoded toml test input' required: false + test_secrets_override_key: + description: 'Key to run tests with custom test secrets' + required: false + type: string # Only run 1 of this workflow at a time per PR concurrency: @@ -24,7 +28,7 @@ env: CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink CHAINLINK_VERSION: ${{ github.sha}} INPUT_CHAINLINK_TEST_VERSION: ${{ github.sha}} - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-ccip-tests:${{ github.sha }} + ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ github.sha }} INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com AWS_ECR_REPO_PUBLIC_REGISTRY: public.ecr.aws MOD_CACHE_VERSION: 1 @@ -56,7 +60,7 @@ jobs: with: cl_repo: smartcontractkit/chainlink cl_ref: ${{ env.CHAINLINK_VERSION }} - push_tag: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:${{ env.CHAINLINK_VERSION }} + push_tag: ${{ env.CHAINLINK_IMAGE }}:${{ env.CHAINLINK_VERSION }} QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - name: Collect Metrics @@ -111,7 +115,6 @@ jobs: contents: read env: CHAINLINK_ENV_USER: ${{ github.actor }} - SLACK_USER: ${{ inputs.slackMemberID }} SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} SLACK_CHANNEL: ${{ secrets.QA_SLACK_CHANNEL }} TEST_LOG_LEVEL: info @@ -147,20 +150,19 @@ jobs: with: ref: ${{ env.REF_NAME }} - name: Sets env vars + id: set_override_config shell: bash run: | # if the matrix.type.config_path is set, use it as the override config if [ -n "${{ matrix.type.config_path }}" ]; then - echo "BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -w 0 -i ${{ matrix.type.config_path }})" >> $GITHUB_ENV - echo "TEST_BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -w 0 -i ${{ matrix.type.config_path }})" >> $GITHUB_ENV + BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -w 0 -i ${{ matrix.type.config_path }}) + echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE + echo "base_64_override=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_OUTPUT fi if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then BASE64_CCIP_CONFIG_OVERRIDE=$(jq -r '.inputs.base64_test_input' $GITHUB_EVENT_PATH) echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE - if [ -n "${BASE64_CCIP_CONFIG_OVERRIDE}" && "$BASE64_CCIP_CONFIG_OVERRIDE" != "null"]; then - echo "BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV - echo "TEST_BASE64_CCIP_CONFIG_OVERRIDE=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_ENV - fi + echo "base_64_override=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_OUTPUT fi - name: step summary shell: bash @@ -171,18 +173,14 @@ jobs: echo "\`${{ env.INPUT_CHAINLINK_TEST_VERSION }}\`" >> $GITHUB_STEP_SUMMARY - name: Prepare Base64 TOML override for CCIP secrets uses: ./.github/actions/setup-create-base64-config-ccip + id: setup_create_base64_config_ccip with: runId: ${{ github.run_id }} testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} chainlinkVersion: ${{ github.sha }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: ${{ vars.GRAFANA_URL }} - grafanaDashboardUrl: "/d/6vjVx-1V8/ccip-long-running-tests" - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d38226be720c5ccc1ff4d3cee40608ebf264cd59 # v2.3.26 env: TEST_SUITE: load TEST_ARGS: -test.timeout 900h @@ -190,11 +188,12 @@ jobs: RR_MEM: 8Gi RR_CPU: 4 TEST_TRIGGERED_BY: ccip-load-test-ci-${{ matrix.type.name }} + BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} + TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} with: test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 70m -count=1 -json -run ${{ matrix.type.run }} ./load 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci test_download_vendor_packages_command: cd ./integration-tests && go mod download - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ env.CHAINLINK_VERSION }} + test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} token: ${{ secrets.GITHUB_TOKEN }} go_mod_path: ./integration-tests/go.mod QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} @@ -207,6 +206,12 @@ jobs: cache_key_id: ccip-load-${{ env.MOD_CACHE_VERSION }} cache_restore_only: "true" should_cleanup: "true" + DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} + DEFAULT_LOKI_TENANT_ID: ${{ vars.LOKI_TENANT_ID }} + DEFAULT_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} + DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + DEFAULT_GRAFANA_BASE_URL: ${{ vars.GRAFANA_URL }} + DEFAULT_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" # Reporting Jobs start-slack-thread: @@ -289,4 +294,4 @@ jobs: slack_bot_token: ${{ secrets.QA_SLACK_API_KEY }} slack_thread_ts: ${{ needs.start-slack-thread.outputs.thread_ts }} - # End Reporting Jobs + # End Reporting Jobs \ No newline at end of file diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 2b7a3b728d..46aa53e9c1 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -725,26 +725,20 @@ jobs: - name: Prepare Base64 CCIP TOML secrets uses: ./.github/actions/setup-create-base64-config-ccip + id: setup_create_base64_config_ccip with: runId: ${{ github.run_id }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ${{ matrix.product.pyroscope_env }} - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} testLogCollect: ${{ vars.TEST_LOG_COLLECT }} selectedNetworks: SIMULATED_1,SIMULATED_2 - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - lokiEndpoint: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} + chainlinkVersion: ${{ inputs.evm-ref || github.sha }} logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' + env: + BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} + TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs @@ -1027,25 +1021,6 @@ jobs: # other inputs duplicate-authorization-header: "true" - - name: Prepare Base64 CCIP TOML secrets - uses: ./.github/actions/setup-create-base64-config-ccip - with: - runId: ${{ github.run_id }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ${{ matrix.product.pyroscope_env }} - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - selectedNetworks: SIMULATED_1,SIMULATED_2 - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - lokiEndpoint: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 9f1844693c..0a9b4f7a34 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -269,7 +269,7 @@ require ( github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect - github.com/smartcontractkit/chain-selectors v1.0.10 // indirect + github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 35226b0de3..c228e65415 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1180,8 +1180,8 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCqR1LNS7aI3jT0V+xGrg= -github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= +github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1WonwhVOPtOStpqTmLC4E= +github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= diff --git a/go.mod b/go.mod index 7976cbcd44..e6fd4f9e23 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,7 @@ require ( github.com/scylladb/go-reflectx v1.0.1 github.com/shirou/gopsutil/v3 v3.24.3 github.com/shopspring/decimal v1.4.0 - github.com/smartcontractkit/chain-selectors v1.0.10 + github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 diff --git a/go.sum b/go.sum index 704b9507c6..e484324866 100644 --- a/go.sum +++ b/go.sum @@ -1135,8 +1135,8 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCqR1LNS7aI3jT0V+xGrg= -github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= +github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1WonwhVOPtOStpqTmLC4E= +github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= diff --git a/integration-tests/ccip-tests/Makefile b/integration-tests/ccip-tests/Makefile index 5a40f7ca0f..d33d956915 100644 --- a/integration-tests/ccip-tests/Makefile +++ b/integration-tests/ccip-tests/Makefile @@ -1,11 +1,13 @@ -## To Override the default config, and secret config: -# example usage: make set_config override_toml=../config/config.toml secret_toml=../config/secret.toml network_config_toml=../config/network.toml +## To Override the default config: +# example usage: make set_config override_toml=../config/config.toml network_config_toml=../config/network.toml .PHONY: set_config set_config: if [ -s "$(override_toml)" ]; then \ echo "Overriding config with $(override_toml)"; \ echo "export BASE64_CCIP_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" > ./testconfig/override/.env; \ echo "export TEST_BASE64_CCIP_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" >> ./testconfig/override/.env; \ + echo "BASE64_CCIP_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" > ./testconfig/override/debug.env; \ + echo "TEST_BASE64_CCIP_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" >> ./testconfig/override/debug.env; \ else \ echo "No override config found, using default config"; \ echo > ./testconfig/override/.env; \ @@ -15,14 +17,15 @@ set_config: echo "export BASE64_NETWORK_CONFIG=$$(base64 -i $(network_config_toml))" >> ./testconfig/override/.env; \ fi - @echo "setting secret config with $(secret_toml)" - @echo "export BASE64_CCIP_SECRETS_CONFIG=$$(base64 -i $(secret_toml))" >> ./testconfig/override/.env - @echo "export TEST_BASE64_CCIP_SECRETS_CONFIG=$$(base64 -i $(secret_toml))" >> ./testconfig/override/.env - @echo "BASE64_CCIP_SECRETS_CONFIG=$$(base64 -i $(secret_toml))" > ./testconfig/override/debug.env - @echo "TEST_BASE64_CCIP_SECRETS_CONFIG=$$(base64 -i $(secret_toml))" >> ./testconfig/override/debug.env + @echo "Checking for test secrets file in ~/.testsecrets..."; + @if [ ! -f ~/.testsecrets ]; then \ + echo "WARNING: ~/.testsecrets file not found. No test secrets will be set. To set test secrets, refer to ./testconfig/examples/.testsecrets.example for the list of secrets and instruction how to set them up."; \ + else \ + echo "Test secrets will be loaded from ~/.testsecrets file."; \ + fi -# example usage: make test_load_ccip testimage=chainlink-ccip-tests:latest testname=TestLoadCCIPStableRPS override_toml=./testconfig/override/config.toml secret_toml=./testconfig/tomls/secrets.toml network_config_toml=../config/network.toml +# example usage: make test_load_ccip testimage=chainlink-ccip-tests:latest testname=TestLoadCCIPStableRPS override_toml=./testconfig/override/config.toml network_config_toml=../config/network.toml .PHONY: test_load_ccip test_load_ccip: set_config source ./testconfig/override/.env && \ @@ -36,7 +39,7 @@ test_load_ccip: set_config go test -timeout 24h -count=1 -v -run ^$(testname)$$ ./load -# example usage: make test_smoke_ccip testimage=chainlink-ccip-tests:latest testname=TestSmokeCCIPForBidirectionalLane override_toml=../testconfig/override/config.toml secret_toml=./testconfig/tomls/secrets.toml network_config_toml=../config/network.toml +# example usage: make test_smoke_ccip testimage=chainlink-ccip-tests:latest testname=TestSmokeCCIPForBidirectionalLane override_toml=../testconfig/override/config.toml network_config_toml=../config/network.toml .PHONY: test_smoke_ccip test_smoke_ccip: set_config source ./testconfig/override/.env && \ @@ -48,7 +51,7 @@ test_smoke_ccip: set_config go test -timeout 24h -count=1 -v -run ^$(testname)$$ ./smoke # run ccip smoke tests with default config; explicitly sets the override config to empty -# example usage: make test_smoke_ccip_default testname=TestSmokeCCIPForBidirectionalLane secret_toml=./testconfig/tomls/secrets.toml +# example usage: make test_smoke_ccip_default testname=TestSmokeCCIPForBidirectionalLane .PHONY: test_smoke_ccip_default test_smoke_ccip_default: set_config source ./testconfig/override/.env && \ diff --git a/integration-tests/ccip-tests/README.md b/integration-tests/ccip-tests/README.md index 0e000561fa..f7182338f7 100644 --- a/integration-tests/ccip-tests/README.md +++ b/integration-tests/ccip-tests/README.md @@ -34,34 +34,17 @@ For example, if you want to override the `Network` input in test and want to run export BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -i ./testconfig/override/mainnet.toml) ``` -3. Secrets - You also need to set some secrets. This is a mandatory step needed to run the tests. Please refer to [sample-secrets.toml](./testconfig/examples/secrets.toml.example) for the list of secrets that are mandatory to run the tests. +3. Secrets - You also need to set some secrets. This is a mandatory step needed to run the tests. Please refer to [.testsecrets.example](./examples/.testsecrets.example) for the list of secrets and instruction how to set them up. - The chainlink image and tag are required secrets for all the tests. - If you are running tests in live networks like testnet and mainnet, you need to set the secrets (rpc urls and private keys) for the respective networks. - If you are running tests in simulated networks no network specific secrets are required. here is a sample secrets.toml file, for running the tests in simulated networks, with the chainlink image and tag set as secrets: - ```toml - [CCIP] - [CCIP.Env] - # ChainlinkImage is mandatory for all tests. - [CCIP.Env.NewCLCluster] - [CCIP.Env.NewCLCluster.Common] - [CCIP.Env.NewCLCluster.Common.ChainlinkImage] - image = "chainlink-ccip" - version = "latest" - ``` - - We consider secrets similar to test input overrides and encode them using `base64` command. - Once you have the secrets.toml file, you can encode it using `base64` command (similar to step 2) and set the env var `BASE64_CCIP_SECRETS_CONFIG` with the encoded content. - - ```bash - export BASE64_CCIP_SECRETS_CONFIG=$(base64 -i ./testconfig/tomls/secrets.toml) - ``` - **Please note that the secrets should NOT be checked in to the repo and should be kept locally.** -We recommend against changing the content of [sample-secrets.toml](./testconfig/examples/secrets.toml.example). Please create a new file and set it as the secrets file. -You can run the command to ignore the changes to the file. +We recommend against changing the content of [secrets.toml.example](./testconfig/examples/secrets.toml.example). Please create a new file and set it as the secrets file. + +You can run this command to ignore any changes to the file. ```bash git update-index --skip-worktree diff --git a/integration-tests/ccip-tests/testconfig/README.md b/integration-tests/ccip-tests/testconfig/README.md index c32aee3d91..51009e49a2 100644 --- a/integration-tests/ccip-tests/testconfig/README.md +++ b/integration-tests/ccip-tests/testconfig/README.md @@ -1,21 +1,23 @@ # CCIP Configuration -The CCIP configuration is used to specify the test configuration for running the CCIP integration tests. +The CCIP configuration is used to specify the test configuration for running the CCIP integration tests. The configuration is specified in a TOML file. The configuration is used to specify the test environment, test type, test parameters, and other necessary details for running the tests. The test config is read in following order: -- The test reads the default configuration from [ccip-default.toml](./tomls/ccip-default.toml). -- The default can be overridden by specifying the test config in a separate file. - - The file content needs to be encoded in base64 format and set in `BASE64_CCIP_CONFIG_OVERRIDE` environment variable. + +- The test reads the default configuration from [ccip-default.toml](./tomls/ccip-default.toml). +- The default can be overridden by specifying the test config in a separate file. + - The file content needs to be encoded in base64 format and set in `BASE64_CCIP_CONFIG_OVERRIDE` environment variable. - The config mentioned in this file will override the default config. - Example override file - [override.toml.example](./examples/override.toml.example) -- If there are sensitive details like private keys, credentials in test config, they can be specified in a separate secret file. - - The file content needs to be encoded in base64 format and set in `BASE64_CCIP_SECRETS_CONFIG` environment variable. - - The config mentioned in this file will override the default and override config. - - Example secret file - [secrets.toml.example](./examples/secrets.toml.example) +- If there are sensitive details like private keys, credentials in test config, they can be specified in a separate dotenv file as env vars + - The `~/.testsecrets` file in home directory is automatically loaded and should have all test secrets as env vars + - Example secret file - [.testsecrets.example](./examples/.testsecrets.example) ## CCIP.ContractVersions + Specifies contract versions of different contracts to be referred by test. Supported versions are: + - **PriceRegistry**: '1.2.0', 'Latest' - **OffRamp**: '1.2.0', 'Latest' - **OnRamp**: '1.2.0', 'Latest' @@ -23,6 +25,7 @@ Supported versions are: - **CommitStore**: '1.2.0', 'Latest' Example Usage: + ```toml [CCIP.ContractVersions] PriceRegistry = "1.2.0" @@ -33,14 +36,17 @@ CommitStore = "1.2.0" ``` ## CCIP.Deployments -CCIP Deployment contains all necessary contract addresses for various networks. This is mandatory if the test are to be run for [existing deployments](#ccipgroupstestgroupexistingdeployment) + +CCIP Deployment contains all necessary contract addresses for various networks. This is mandatory if the test are to be run for [existing deployments](#ccipgroupstestgroupexistingdeployment) The deployment data can be specified - - - Under `CCIP.Deployments.Data` field with value as stringify format of json. - - Under `CCIP.Deployments.DataFile` field with value as the path of the file containing the deployment data in json format. + +- Under `CCIP.Deployments.Data` field with value as stringify format of json. +- Under `CCIP.Deployments.DataFile` field with value as the path of the file containing the deployment data in json format. The json schema is specified in https://github.com/smartcontractkit/ccip/blob/ccip-develop/integration-tests/ccip-tests/contracts/laneconfig/parse_contracts.go#L96 Example Usage: + ```toml [CCIP.Deployments] Data = """ @@ -96,32 +102,39 @@ Data = """ } """ ``` -Or + +Or, + ```toml [CCIP.Deployments] DataFile = '' ``` -## CCIP.Env +## CCIP.Env + Specifies the environment details for the test to be run on. Mandatory fields are: + - **Networks**: [CCIP.Env.Networks](#ccipenvnetworks) - **NewCLCluster**: [CCIP.Env.NewCLCluster](#ccipenvnewclcluster) - This is mandatory if the test needs to deploy Chainlink nodes. - **ExistingCLCluster**: [CCIP.Env.ExistingCLCluster](#ccipenvexistingclcluster) - This is mandatory if the test needs to run on existing Chainlink nodes to deploy ccip jobs. Test needs network/chain details to be set through configuration. This configuration is mandatory for running the tests. you have option to set the network details in two ways: -1. Using [CCIP.Env.Networks](#ccipenvnetworks) + +1. Using [CCIP.Env.Networks](#ccipenvnetworks) 2. Using a separate network config file - - * refer to the example - [network_config.toml.example](./examples/network_config.toml.example) - * once all necessary values are set, encode the toml file content in base64 format, - * set the base64'ed string content in `BASE64_NETWORK_CONFIG` environment variable. + - refer to the example - [network_config.toml.example](./examples/network_config.toml.example) + - once all necessary values are set, encode the toml file content in base64 format, + - set the base64'ed string content in `BASE64_NETWORK_CONFIG` environment variable. ### CCIP.Env.Networks + Specifies the network details for the test to be run. The NetworkConfig is imported from https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/network.go#L39 #### CCIP.Env.Networks.selected_networks + It denotes the network names in which tests will be run. These networks are used to deploy ccip contracts and set up lanes between them. If more than 2 networks are specified, then lanes will be set up between all possible pairs of networks. @@ -132,28 +145,32 @@ The name of the networks are taken from [known_networks](https://github.com/smar If the network is not present in known_networks, then the network details can be specified in the config file itself under the following `EVMNetworks` key. #### CCIP.Env.Network.EVMNetworks -Specifies the network config to be used while creating blockchain EVMClient for test. + +Specifies the network config to be used while creating blockchain EVMClient for test. It is a map of network name to EVMNetworks where key is network name specified under `CCIP.Env.Networks.selected_networks` and value is `EVMNetwork`. The EVMNetwork is imported from [EVMNetwork](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/blockchain/config.go#L43) in chainlink-testing-framework. If `CCIP.Env.Network.EVMNetworks` config is not set for a network name specified under `CCIP.Env.Networks.selected_networks`, test will try to find the corresponding network config from defined networks in `MappedNetworks` under [known_networks.go](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/networks/known_networks.go) #### CCIP.Env.Network.AnvilConfigs -If the test needs to run on chains created using Anvil, then the AnvilConfigs can be specified. -It is a map of network name to `AnvilConfig` where key is network name specified under `CCIP.Env.Networks.selected_networks` and value is `AnvilConfig`. -The AnvilConfig is imported from [AnvilConfig](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/network.go#L20) in chainlink-testing-framework. +If the test needs to run on chains created using Anvil, then the AnvilConfigs can be specified. +It is a map of network name to `AnvilConfig` where key is network name specified under `CCIP.Env.Networks.selected_networks` and value is `AnvilConfig`. +The AnvilConfig is imported from [AnvilConfig](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/network.go#L20) in chainlink-testing-framework. **The following network configs are required for tests running on live networks. It can be ignored if the tests are running on simulated networks.** Refer to [secrets.toml.example](./examples/secrets.toml.example) for details. #### CCIP.ENV.Network.RpcHttpUrls + RpcHttpUrls is the RPC HTTP endpoints for each network, key is the network name as declared in selected_networks slice. #### CCIP.ENV.Network.RpcWsUrls + RpcWsUrls is the RPC WS endpoints for each network, key is the network name as declared in selected_networks slice. #### CCIP.ENV.Network.WalletKeys + WalletKeys is the private keys for each network, key is the network name as declared in selected_networks slice. Example Usage of Network Config: @@ -202,69 +219,95 @@ block_time = 1 ``` ### CCIP.Env.NewCLCluster -The NewCLCluster config holds the overall deployment configuration for Chainlink nodes. + +The NewCLCluster config holds the overall deployment configuration for Chainlink nodes. #### CCIP.Env.NewCLCluster.NoOfNodes + Specifies the number of Chainlink nodes to be deployed. #### CCIP.Env.NewCLCluster.Common + Specifies the common configuration for all Chainlink nodes if they share the same configuration. -##### Name: + +##### Name + Name of the node. -##### NeedsUpgrade: + +##### NeedsUpgrade + Indicates if the node needs an upgrade during test. -##### ChainlinkImage: + +##### ChainlinkImage + Configuration for the Chainlink image. -##### ChainlinkUpgradeImage: +##### ChainlinkUpgradeImage + Configuration for the Chainlink upgrade image. It is used when the node needs an upgrade. -##### BaseConfigTOML: +##### BaseConfigTOML + String containing the base configuration toml content for the Chainlink node config. -##### CommonChainConfigTOML: +##### CommonChainConfigTOML + String containing the common chain configuration toml content for all EVMNodes in chainlink node config. -##### ChainConfigTOMLByChain: +##### ChainConfigTOMLByChain + String containing the chain-specific configuration toml content for individual EVMNodes in chainlink node config. This is keyed by chain ID. -##### DBImage: +##### DBImage + Database image for the Chainlink node. -##### DBTag: +##### DBTag + Database tag/version for the Chainlink node. #### CCIP.Env.NewCLCluster.Nodes + Specifies the configuration for individual nodes if they differ from the common configuration. The fields are the same as the common configuration. #### CCIP.Env.NewCLCluster.NodeMemory + Specifies the memory to be allocated for each Chainlink node. This is valid only if the deployment is on Kubernetes. #### CCIP.Env.NewCLCluster.NodeCPU + Specifies the CPU to be allocated for each Chainlink node. This is valid only if the deployment is on Kubernetes. #### CCIP.Env.NewCLCluster.DBMemory + Specifies the memory to be allocated for the database. This is valid only if the deployment is on Kubernetes. #### CCIP.Env.NewCLCluster.DBCPU + Specifies the CPU to be allocated for the database. This is valid only if the deployment is on Kubernetes. #### CCIP.Env.NewCLCluster.IsStateful + Specifies whether the deployment is StatefulSet on Kubernetes. #### CCIP.Env.NewCLCluster.DBStorageClass + Specifies the storage class for the database. This is valid only if the deployment is StatefulSet on Kubernetes. #### CCIP.Env.NewCLCluster.DBCapacity + Specifies the capacity of the database. This is valid only if the deployment is StatefulSet on Kubernetes. #### CCIP.Env.NewCLCluster.PromPgExporter + Specifies whether to enable Prometheus PostgreSQL exporter. This is valid only if the deployment is on Kubernetes. #### CCIP.Env.NewCLCluster.DBArgs + Specifies the arguments to be passed to the database. This is valid only if the deployment is on Kubernetes. Example Usage: + ```toml [CCIP.Env.NewCLCluster] NoOfNodes = 17 @@ -294,29 +337,42 @@ FeeCapDefault = '200 gwei' ``` ### CCIP.Env.ExistingCLCluster -The ExistingCLCluster config holds the overall connection configuration for existing Chainlink nodes. -It is needed when the tests are to be run on Chainlink nodes already deployed on some environment. -If this is specified, test will not need to connect to k8 namespace using [CCIP.Env.EnvToConnect](#ccipenvenvtoconnect) . + +The ExistingCLCluster config holds the overall connection configuration for existing Chainlink nodes. +It is needed when the tests are to be run on Chainlink nodes already deployed on some environment. +If this is specified, test will not need to connect to k8 namespace using [CCIP.Env.EnvToConnect](#ccipenvenvtoconnect). Test can directly connect to the existing Chainlink nodes using node credentials without knowing the k8 namespace details. #### CCIP.Env.ExistingCLCluster.Name + Specifies the name of the existing Chainlink cluster. This is used to identify the cluster in the test. #### CCIP.Env.ExistingCLCluster.NoOfNodes + Specifies the number of Chainlink nodes in the existing cluster. #### CCIP.Env.ExistingCLCluster.NodeConfigs + Specifies the configuration for individual nodes in the existing cluster. Each node config contains the following fields to connect to the Chainlink node: + ##### CCIP.Env.ExistingCLCluster.NodeConfigs.URL + The URL of the Chainlink node. -##### CCIP.Env.ExistingCLCluster.NodeConfigs.Email + +##### CCIP.Env.ExistingCLCluster.NodeConfigs.Email + The username/email of the Chainlink node credential. + ##### CCIP.Env.ExistingCLCluster.NodeConfigs.Password + The password of the Chainlink node credential. + ##### CCIP.Env.ExistingCLCluster.NodeConfigs.InternalIP + The internal IP of the Chainlink node. Example Usage: + ```toml [CCIP.Env.ExistingCLCluster] Name = 'crib-sample' @@ -355,23 +411,30 @@ InternalIP = 'app-node-5' ``` ### CCIP.Env.EnvToConnect + This is specified when the test needs to connect to already existing k8s namespace. User needs to have access to the k8 namespace to run the tests through specific kubeconfig file. Example usage: + ```toml [CCIP.Env] EnvToConnect="load-ccip-c8972" ``` + ### CCIP.ENV.TTL + Specifies the time to live for the k8 namespace. This is used to terminate the namespace after the tests are run. This is only valid if the tests are run on k8s. Example usage: + ```toml [CCIP.Env] TTL = "11h" ``` ### CCIP.Env.Logging + Specifies the logging configuration for the test. Imported from [LoggingConfig](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/logging.go#L11) in chainlink-testing-framework. Example usage: + ```toml [CCIP.Env.Logging] test_log_collect = false # if set to true will save logs even if test did not fail @@ -394,53 +457,67 @@ dashboard_url = "/d/6vjVx-1V8/ccip-long-running-tests" ``` ### CCIP.Env.Lane.LeaderLaneEnabled + Specifies whether to enable the leader lane feature. This setting is only applicable for new deployments. ## CCIP.Groups + Specifies the test config specific to each test type. Available test types are: + - **CCIP.Groups.load** - **CCIP.Groups.smoke** - **CCIP.Groups.chaos** ### CCIP.Groups.[testgroup].KeepEnvAlive + Specifies whether to keep the k8 namespace alive after the test is run. This is only valid if the tests are run on k8s. ### CCIP.Groups.[testgroup].BiDirectionalLane -Specifies whether to set up bi-directional lanes between networks. + +Specifies whether to set up bi-directional lanes between networks. ### CCIP.Groups.[testgroup].CommitAndExecuteOnSameDON + Specifies whether commit and execution jobs are to be run on the same Chainlink node. ### CCIP.Groups.[testgroup].NoOfCommitNodes + Specifies the number of nodes on which commit jobs are to be run. This needs to be lesser than the total number of nodes mentioned in [CCIP.Env.NewCLCluster.NoOfNodes](#ccipenvnewclclusternoofnodes) or [CCIP.Env.ExistingCLCluster.NoOfNodes](#ccipenvexistingclclusternoofnodes). If the value of total nodes is `n`, then the max value of NoOfCommitNodes should be less than `n-1`. As the first node is used for bootstrap job. If the NoOfCommitNodes is lesser than `n-1`, then the remaining nodes are used for execution jobs if `CCIP.Groups.[testgroup].CommitAndExecuteOnSameDON` is set to false. ### CCIP.Groups.[testgroup].TokenConfig + Specifies the token configuration for the test. The token configuration is used to set up tokens and token pools for all chains. #### CCIP.Groups.[testgroup].TokenConfig.NoOfTokensPerChain + Specifies the number of tokens to be set up for each chain. #### CCIP.Groups.[testgroup].TokenConfig.WithPipeline -Specifies whether to set up token pipelines in commit jobspec. If set to false, the token prices will be set with DynamicPriceGetterConfig. + +Specifies whether to set up token pipelines in commit jobspec. If set to false, the token prices will be set with DynamicPriceGetterConfig. #### CCIP.Groups.[testgroup].TokenConfig.TimeoutForPriceUpdate -Specifies the timeout to wait for token and gas price updates to be available in price registry for each chain. + +Specifies the timeout to wait for token and gas price updates to be available in price registry for each chain. #### CCIP.Groups.[testgroup].TokenConfig.NoOfTokensWithDynamicPrice + Specifies the number of tokens to be set up with dynamic price update. The rest of the tokens will be set up with static price. This is only valid if [WithPipeline](#ccipgroupstestgrouptokenconfigwithpipeline) is set to false. #### CCIP.Groups.[testgroup].TokenConfig.DynamicPriceUpdateInterval + Specifies the interval for dynamic price update for tokens. This is only valid if [NoOfTokensWithDynamicPrice](#ccipgroupstestgrouptokenconfignooftokenswithdynamicprice) is set to value greater tha zero. #### CCIP.Groups.[testgroup].TokenConfig.CCIPOwnerTokens + Specifies the tokens to be owned by the CCIP owner. If this is false, the tokens and pools will be owned by an address other than rest of CCIP contract admin addresses. This is applicable only if the contract versions are '1.5' or higher. Example Usage: -```toml +```toml [CCIP.Groups.load.TokenConfig] TimeoutForPriceUpdate = '15m' NoOfTokensPerChain = 60 @@ -450,27 +527,36 @@ CCIPOwnerTokens = true ``` ### CCIP.Groups.[testgroup].MsgDetails -Specifies the ccip message details to be sent by the test. + +Specifies the ccip message details to be sent by the test. + #### CCIP.Groups.[testgroup].MsgDetails.MsgType + Specifies the type of message to be sent. The supported message types are: + - **Token** - **Data** - **DataWithToken** #### CCIP.Groups.[testgroup].MsgDetails.DestGasLimit + Specifies the gas limit for the destination chain. This is used to in `ExtraArgs` field of CCIPMessage. Change this to 0, if you are doing ccip-send to an EOA in the destination chain. #### CCIP.Groups.[testgroup].MsgDetails.DataLength + Specifies the length of data to be sent in the message. This is only valid if [MsgType](#ccipgroupstestgroupmsgdetailsmsgtype) is set to 'Data' or 'DataWithToken'. #### CCIP.Groups.[testgroup].MsgDetails.NoOfTokens + Specifies the number of tokens to be sent in the message. This is only valid if [MsgType](#ccipgroupstestgroupmsgdetailsmsgtype) is set to 'Token' or 'DataWithToken'. It needs to be less than or equal to [NoOfTokensPerChain](#ccipgroupstestgrouptokenconfignooftokensperchain) specified in the test config. #### CCIP.Groups.[testgroup].MsgDetails.TokenAmount + Specifies the amount for each token to be sent in the message. This is only valid if [MsgType](#ccipgroupstestgroupmsgdetailsmsgtype) is set to 'Token' or 'DataWithToken'. Example Usage: + ```toml [CCIP.Groups.smoke.MsgDetails] MsgType = 'DataWithToken' @@ -481,15 +567,19 @@ AmountPerToken = 1 ``` ### CCIP.Groups.[testgroup].MulticallInOneTx + Specifies whether to send multiple ccip messages in a single transaction. ### CCIP.Groups.[testgroup].NoOfSendsInMulticall + Specifies the number of ccip messages to be sent in a single transaction. This is only valid if [MulticallInOneTx](#ccipgroupstestgroupmulticallinonetx) is set to true. ### CCIP.Groups.[testgroup].PhaseTimeout + The test validates various events in a ccip request lifecycle, like commit, execute, etc. This field specifies the timeout for each phase in the lifecycle. The timeout is calculated from the time the previous phase event is received. The following contract events are validated: + - **CCIPSendRequested on OnRamp** - **CCIPSendRequested event log to be Finalized** - **ReportAccepted on CommitStore** @@ -497,13 +587,16 @@ The following contract events are validated: - **ExecutionStateChanged on OffRamp** ### CCIP.Groups.[testgroup].LocalCluster + Specifies whether the test is to be run on a local docker. If set to true, the test environment will be set up on a local docker. ### CCIP.Groups.[testgroup].ExistingDeployment + Specifies whether the test is to be run on existing deployments. If set to true, the test will use the deployment data specified in [CCIP.Deployments](#ccipdeployments) for interacting with the ccip contracts. If the deployment data does not contain the required contract addresses, the test will fail. ### CCIP.Groups.[testgroup].ReuseContracts + Test loads contract/lane config from [contracts.json](../contracts/laneconfig/contracts.json) if no lane config is specified in [CCIP.Deployments](#ccipdeployments) If a certain contract is present in the contracts.json, the test will use the contract address from the contracts.json. This field specifies whether to reuse the contracts from [contracts.json](../contracts/laneconfig/contracts.json) @@ -511,58 +604,74 @@ For example if the contracts.json contains the contract address for PriceRegistr If `ReuseContracts` is set to false, the test will redeploy the contract instead of using the contract address from contracts.json. ### CCIP.Groups.[testgroup].NodeFunding + Specified the native token funding for each Chainlink node. It assumes that the native token decimals is 18. The funding is done by the private key specified in [CCIP.Env.Networks](#ccipenvnetworks) for each network. The funding is done only if the test is run on local docker or k8s. This is not applicable for [existing deployments](#ccipgroupstestgroupexistingdeployment) is set to true. ### CCIP.Groups.[testgroup].NetworkPairs -Specifies the network pairs for which the test is to be run. The test will set up lanes only between the specified network pairs. + +Specifies the network pairs for which the test is to be run. The test will set up lanes only between the specified network pairs. If the network pairs are not specified, the test will set up lanes between all possible pairs of networks mentioned in selected_networks in [CCIP.Env.Networks](#ccipenvnetworksselectednetworks) ### CCIP.Groups.[testgroup].NoOfNetworks -Specifies the number of networks to be used for the test. -If the number of networks is greater than the total number of networks specified in [CCIP.Env.Networks.selected_networks](#ccipenvnetworksselectednetworks) : + +Specifies the number of networks to be used for the test. +If the number of networks is greater than the total number of networks specified in [CCIP.Env.Networks.selected_networks](#ccipenvnetworksselectednetworks): + - the test will fail if the networks are live networks. - the test will create equal number of replicas of the first network with a new chain id if the networks are simulated networks. For example, if the `selected_networks` is ['SIMULATED_1','SIMULATED_2'] and `NoOfNetworks` is 3, the test will create 1 more network config by copying the network config of `SIMULATED_1` with a different chain id and use that as 3rd network. ### CCIP.Groups.[testgroup].NoOfRoutersPerPair + Specifies the number of routers to be set up for each network. ### CCIP.Groups.[testgroup].MaxNoOfLanes + Specifies the maximum number of lanes to be set up between networks. If this values is not set, the test will set up lanes between all possible pairs of networks mentioned in `selected_networks` in [CCIP.Env.Networks](#ccipenvnetworksselectednetworks). For example, if `selected_networks = ['SIMULATED_1', 'SIMULATED_2', 'SIMULATED_3']`, and `MaxNoOfLanes` is set to 2, it denotes that the test will randomly select the 2 lanes between all possible pairs `SIMULATED_1`, `SIMULATED_2`, and `SIMULATED_3` for the test run. ### CCIP.Groups.[testgroup].DenselyConnectedNetworkChainIds -This is applicable only if [MaxNoOfLanes](#ccipgroupstestgroupmaxnooflanes) is specified. + +This is applicable only if [MaxNoOfLanes](#ccipgroupstestgroupmaxnooflanes) is specified. Specifies the chain ids for networks to be densely connected. If this is provided the test will include all possible pairs of networks mentioned in `DenselyConnectedNetworkChainIds`. The rest of the networks will be connected randomly based on the value of `MaxNoOfLanes`. ### CCIP.Groups.[testgroup].ChaosDuration + Specifies the duration for which the chaos experiment is to be run. This is only valid if the test type is 'chaos'. ### CCIP.Groups.[testgroup].USDCMockDeployment + Specifies whether to deploy USDC mock contract for the test. This is only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). The following fields are used for various parameters in OCR2 commit and execution jobspecs. All of these are only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). + ### CCIP.Groups.[testgroup].CommitOCRParams + Specifies the OCR parameters for the commit job. This is only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). ### CCIP.Groups.[testgroup].ExecuteOCRParams + Specifies the OCR parameters for the execute job. This is only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). ### CCIP.Groups.[testgroup].CommitInflightExpiry + Specifies the value for the `InflightExpiry` in commit job's offchain config. This is only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). ### CCIP.Groups.[testgroup].OffRampConfig + Specifies the offramp configuration for the execution job. This is only valid if the test is not run on [existing deployments](#ccipgroupstestgroupexistingdeployment). This is used to set values for following fields in execution jobspec's offchain and onchain config: + - **OffRampConfig.MaxDataBytes** - **OffRampConfig.BatchGasLimit** - **OffRampConfig.InflightExpiry** - **OffRampConfig.RootSnooze** Example Usage: + ```toml [CCIP.Groups.load] CommitInflightExpiry = '5m' @@ -594,43 +703,53 @@ BatchGasLimit = 11000000 MaxDataBytes = 1000 InflightExpiry = '5m' RootSnooze = '5m' - ``` ### CCIP.Groups.[testgroup].StoreLaneConfig + This is only valid if the tests are run on remote runners in k8s. If set to true, the test will store the lane config in the remote runner. ### CCIP.Groups.[testgroup].LoadProfile -Specifies the load profile for the test. Only valid if the testgroup is 'load'. + +Specifies the load profile for the test. Only valid if the testgroup is 'load'. ### CCIP.Groups.[testgroup].LoadProfile.LoadFrequency.[DestNetworkName] #### CCIP.Groups.[testgroup].LoadProfile.RequestPerUnitTime + Specifies the number of requests to be sent per unit time. This is applicable to all networks if [LoadFrequency](#ccipgroupstestgrouploadprofileloadfrequencydestnetworkname) is not specified for a destination network. #### CCIP.Groups.[testgroup].LoadProfile.TimeUnit + Specifies the unit of time for the load profile. This is applicable to all networks if [LoadFrequency](#ccipgroupstestgrouploadprofileloadfrequencydestnetworkname) is not specified for a destination network. #### CCIP.Groups.[testgroup].LoadProfile.StepDuration + Specifies the duration for each step in the load profile. This is applicable to all networks if [LoadFrequency](#ccipgroupstestgrouploadprofileloadfrequencydestnetworkname) is not specified for a destination network. #### CCIP.Groups.[testgroup].LoadProfile.TestDuration + Specifies the total duration for the load test. #### CCIP.Groups.[testgroup].LoadProfile.NetworkChaosDelay + Specifies the duration network delay used for `NetworkChaos` experiment. This is only valid if the test is run on k8s and not on [existing deployments](#ccipgroupstestgroupexistingdeployment). #### CCIP.Groups.[testgroup].LoadProfile.WaitBetweenChaosDuringLoad + If there are multiple chaos experiments, this specifies the duration to wait between each chaos experiment. This is only valid if the test is run on k8s and not on [existing deployments](#ccipgroupstestgroupexistingdeployment). #### CCIP.Groups.[testgroup].LoadProfile.SkipRequestIfAnotherRequestTriggeredWithin + If a request is triggered within this duration, the test will skip sending another request during load run. For Example, if `SkipRequestIfAnotherRequestTriggeredWithin` is set to `40m`, and a request is triggered at 0th second, the test will skip sending another request for another 40m. This particular field is used to avoid sending multiple requests in a short duration during load run. #### CCIP.Groups.[testgroup].LoadProfile.OptimizeSpace -This is used internally to optimize memory usage during load run. If set to true, after the initial lane set up is over the test will discard the lane config to save memory. -The test will only store contract addresses strictly necessary to trigger/validate ccip-send requests. + +This is used internally to optimize memory usage during load run. If set to true, after the initial lane set up is over the test will discard the lane config to save memory. +The test will only store contract addresses strictly necessary to trigger/validate ccip-send requests. Except for following contracts all other contract addresses will be discarded after the initial lane set up - + - Router - ARM - CommitStore @@ -638,37 +757,45 @@ Except for following contracts all other contract addresses will be discarded af - OnRamp #### CCIP.Groups.[testgroup].LoadProfile.FailOnFirstErrorInLoad + If set to true, the test will fail on the first error encountered during load run. If set to false, the test will continue to run even if there are errors during load run. #### CCIP.Groups.[testgroup].LoadProfile.SendMaxDataInEveryMsgCount -Specifies the number of requests to send with maximum data in every mentioned count iteration. + +Specifies the number of requests to send with maximum data in every mentioned count iteration. For example, if `SendMaxDataInEveryMsgCount` is set to 5, the test will send ccip message with max allowable data length(as set in onRamp config) in every 5th request. #### CCIP.Groups.[testgroup].LoadProfile.TestRunName + Specifies the name of the test run. This is used to identify the test run in CCIP test dashboard or logs. If multiple tests are run with same `TestRunName`, the test results will be aggregated under the same test run in grafana dashboard. This is used when multiple iterations of tests are run against same release version to aggregate the results under same dashboard view. #### CCIP.Groups.[testgroup].LoadProfile.MsgProfile + Specifies the message profile for the test. The message profile is used to set up multiple ccip message details during load test. ##### CCIP.Groups.[testgroup].LoadProfile.MsgProfile.Frequencies -Specifies the frequency of each message profile. + +Specifies the frequency of each message profile. For example, if `Frequencies` is set to [1, 2, 3], the test will send 1st message profile 1 time, 2nd message profile 2 times, and 3rd message profile 3 times in each iteration. Each iteration will be defined by (1+2+3) = 6 requests. Example Breakdown: + - Frequencies = [4, 12, 3, 1] - Total Sum of Frequencies = 4 + 12 + 3 + 1 = 20 - Percentages: - - Message Type 1: (4 / 20) * 100% = 20% - - Message Type 2: (12 / 20) * 100% = 60% - - Message Type 3: (3 / 20) * 100% = 15% - - Message Type 4: (1 / 20) * 100% = 5% + - Message Type 1: (4 / 20) * 100% = 20% + - Message Type 2: (12 / 20) * 100% = 60% + - Message Type 3: (3 / 20) * 100% = 15% + - Message Type 4: (1 / 20) * 100% = 5% These percentages reflect how often each message type should appear in the total set of messages. Please note - if the total set of messages is not equal to the multiple of sum of frequencies, the percentages will not be accurate. ##### CCIP.Groups.[testgroup].LoadProfile.MsgProfile.MsgDetails + Specifies the message details for each message profile. The fields are the same as [CCIP.Groups.[testgroup].MsgDetails](#ccipgroupstestgroupmsgdetails). example usage: + ```toml # to represent 20%, 60%, 15%, 5% of the total messages [CCIP.Groups.load.LoadProfile.MsgProfile] diff --git a/integration-tests/ccip-tests/testconfig/ccip.go b/integration-tests/ccip-tests/testconfig/ccip.go index 60d7055cb3..7d9419828e 100644 --- a/integration-tests/ccip-tests/testconfig/ccip.go +++ b/integration-tests/ccip-tests/testconfig/ccip.go @@ -387,6 +387,18 @@ type CCIP struct { Groups map[string]*CCIPTestGroupConfig `toml:",omitempty"` } +// LoadFromEnv loads selected env vars into the CCIP config +func (c *CCIP) LoadFromEnv() error { + if c.Env == nil { + c.Env = &Common{} + } + err := c.Env.ReadFromEnvVar() + if err != nil { + return err + } + return nil +} + func (c *CCIP) Validate() error { if c.Env != nil { err := c.Env.Validate() diff --git a/integration-tests/ccip-tests/testconfig/examples/.testsecrets.example b/integration-tests/ccip-tests/testconfig/examples/.testsecrets.example new file mode 100644 index 0000000000..52afa77015 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/examples/.testsecrets.example @@ -0,0 +1,39 @@ +# DO NOT UPDATE THIS FILE WITH ANY SECRET VALUES. +# This file serves as a template for the actual ~/.testsecrets file. Follow these steps to use it: +# 1. Create a copy of this template in your home directory under ~/.testsecrets +# 2. Update ~/.testsecrets with actual secret values required for your tests. The file will be automatically loaded by the test framework +# 3. Only include secrets necessary for the tests you are running. For example, if you are only running tests on Ethereum Mainnet, you do not need secrets for Base Mainnet. Comment other env vars. +# DO NOT COMMIT THE ACTUAL SECRETS FILE TO THE REPOSITORY. + +# Chainlink image used for NewCLCluster +E2E_TEST_CHAINLINK_IMAGE="***.dkr.ecr.***.amazonaws.com/chainlink-ccip" + +# Chainlink upgrade image for NewCLCluster. Used only for upgrade tests +E2E_TEST_CHAINLINK_UPGRADE_IMAGE="***.dkr.ecr.***.amazonaws.com/chainlink-ccip" + +# Ethereum network secrets +E2E_TEST_ETHEREUM_MAINNET_WALLET_KEY="" +E2E_TEST_ETHEREUM_MAINNET_RPC_HTTP_URL="" +E2E_TEST_ETHEREUM_MAINNET_RPC_HTTP_URL_1="" +E2E_TEST_ETHEREUM_MAINNET_RPC_WS_URL="" +E2E_TEST_ETHEREUM_MAINNET_RPC_WS_URL_1="" + +# Base network secrets +E2E_TEST_BASE_MAINNET_WALLET_KEY="" +E2E_TEST_BASE_MAINNET_RPC_HTTP_URL="" +E2E_TEST_BASE_MAINNET_RPC_HTTP_URL_1="" +E2E_TEST_BASE_MAINNET_RPC_WS_URL="" +E2E_TEST_BASE_MAINNET_RPC_WS_URL_1="" + +# Other networks secrets (pattern for envs) +# E2E_TEST_(.+)_WALLET_KEY_(\d+)="" +# E2E_TEST_(.+)_RPC_HTTP_URL_(\d+)="" +# E2E_TEST_(.+)_RPC_WS_URL_(\d+)="" + +# Loki secrets +E2E_TEST_LOKI_TENANT_ID="" +E2E_TEST_LOKI_ENDPOINT="" + +# Grafana secrets +E2E_TEST_GRAFANA_BASE_URL="" +E2E_TEST_GRAFANA_DASHBOARD_URL="/d/6vjVx-1V8/ccip-long-running-tests" \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/examples/secrets.toml.example b/integration-tests/ccip-tests/testconfig/examples/secrets.toml.example deleted file mode 100644 index 3045f51759..0000000000 --- a/integration-tests/ccip-tests/testconfig/examples/secrets.toml.example +++ /dev/null @@ -1,52 +0,0 @@ -# This file contains all secret parameters for ccip tests. -# DO NOT UPDATE THIS FILE WITH ANY SECRET VALUES. -# Use this file as a template for the actual secret file and update all the parameter values accordingly. -# DO NOT COMMIT THE ACTUAL SECRET FILE TO THE REPOSITORY. -[CCIP] -[CCIP.Env] - -# ChainlinkImage is mandatory for all tests. -[CCIP.Env.NewCLCluster] -[CCIP.Env.NewCLCluster.Common] -[CCIP.Env.NewCLCluster.Common.ChainlinkImage] -image = "chainlink-ccip" -version = "latest" - -# Chainlink upgrade image is used only for upgrade tests -#[CCIP.Env.NewCLCluster.Common.ChainlinkUpgradeImage] -#image = "***.dkr.ecr.***.amazonaws.com/chainlink-ccip" -#version = "****" - - -# Networks configuration with rpc urls and wallet keys are mandatory only for tests running on live networks -# The following example is for 3 networks: Ethereum, Base and Arbitrum -# Network configuration can be ignored for tests running on simulated/private networks -[CCIP.Env.Network] -selected_networks= [ - 'ETHEREUM_MAINNET','BASE_MAINNET', 'ARBITRUM_MAINNET', -] - -[CCIP.Env.Network.RpcHttpUrls] -ETHEREUM_MAINNET = ['', ''] -BASE_MAINNET = ['', ''] -ARBITRUM_MAINNET = ['', ''] - -[CCIP.Env.Network.RpcWsUrls] -ETHEREUM_MAINNET = ['', ''] -BASE_MAINNET = ['', ''] -ARBITRUM_MAINNET = ['', ''] - -[CCIP.Env.Network.WalletKeys] -ETHEREUM_MAINNET = [''] -BASE_MAINNET = [''] -ARBITRUM_MAINNET = [''] - -# Used for tests using 1. loki logging for test results. -# Mandatory for load tests -[CCIP.Env.Logging.Loki] -tenant_id="" -endpoint="" - -[CCIP.Env.Logging.Grafana] -base_url="" -dashboard_url="/d/6vjVx-1V8/ccip-long-running-tests" diff --git a/integration-tests/ccip-tests/testconfig/global.go b/integration-tests/ccip-tests/testconfig/global.go index 331737c5fb..a1658a4841 100644 --- a/integration-tests/ccip-tests/testconfig/global.go +++ b/integration-tests/ccip-tests/testconfig/global.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/seth" "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/networks" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" @@ -29,7 +30,6 @@ import ( const ( OVERIDECONFIG = "BASE64_CCIP_CONFIG_OVERRIDE" - SECRETSCONFIG = "BASE64_CCIP_SECRETS_CONFIG" ErrReadConfig = "failed to read TOML config" ErrUnmarshalConfig = "failed to unmarshal TOML config" Load string = "load" @@ -105,52 +105,46 @@ func EncodeConfigAndSetEnv(c any, envVar string) (string, error) { func NewConfig() (*Config, error) { cfg := &Config{} var override *Config - var secrets *Config + // var secrets *Config // load config from default file err := config.DecodeTOML(bytes.NewReader(DefaultConfig), cfg) if err != nil { return nil, errors.Wrap(err, ErrReadConfig) } - // load config from env var if specified - rawConfig, _ := osutil.GetEnv(OVERIDECONFIG) - if rawConfig != "" { - err = DecodeConfig(rawConfig, &override) - if err != nil { - return nil, fmt.Errorf("failed to decode override config: %w", err) - } - } - if override != nil { - // apply overrides for all products - if override.CCIP != nil { - if cfg.CCIP == nil { - cfg.CCIP = override.CCIP - } else { - err = cfg.CCIP.ApplyOverrides(override.CCIP) - if err != nil { - return nil, err + // load config overrides from env var if specified + // there can be multiple overrides separated by comma + rawConfigs, _ := osutil.GetEnv(OVERIDECONFIG) + if rawConfigs != "" { + for _, rawConfig := range strings.Split(rawConfigs, ",") { + err = DecodeConfig(rawConfig, &override) + if err != nil { + return nil, fmt.Errorf("failed to decode override config: %w", err) + } + if override != nil { + // apply overrides for all products + if override.CCIP != nil { + if cfg.CCIP == nil { + cfg.CCIP = override.CCIP + } else { + err = cfg.CCIP.ApplyOverrides(override.CCIP) + if err != nil { + return nil, err + } + } } } } } // read secrets for all products if cfg.CCIP != nil { - // load config from env var if specified for secrets - secretRawConfig, _ := osutil.GetEnv(SECRETSCONFIG) - if secretRawConfig != "" { - err = DecodeConfig(secretRawConfig, &secrets) - if err != nil { - return nil, fmt.Errorf("failed to decode secrets config: %w", err) - } - if secrets != nil { - // apply secrets for all products - if secrets.CCIP != nil { - err = cfg.CCIP.ApplyOverrides(secrets.CCIP) - if err != nil { - return nil, fmt.Errorf("failed to apply secrets: %w", err) - } - } - } + err := ctfconfig.LoadSecretEnvsFromFiles() + if err != nil { + return nil, errors.Wrap(err, "error loading testsecrets files") + } + err = cfg.CCIP.LoadFromEnv() + if err != nil { + return nil, errors.Wrap(err, "error loading env vars into CCIP config") } // validate all products err = cfg.CCIP.Validate() @@ -176,6 +170,156 @@ type Common struct { Logging *ctfconfig.LoggingConfig `toml:",omitempty"` } +// ReadFromEnvVar loads selected env vars into the config +func (p *Common) ReadFromEnvVar() error { + logger := logging.GetTestLogger(nil) + + lokiTenantID := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_LOKI_TENANT_ID_ENV) + if lokiTenantID != "" { + if p.Logging == nil { + p.Logging = &ctfconfig.LoggingConfig{} + } + if p.Logging.Loki == nil { + p.Logging.Loki = &ctfconfig.LokiConfig{} + } + logger.Debug().Msgf("Using %s env var to override Logging.Loki.TenantId", ctfconfig.E2E_TEST_LOKI_TENANT_ID_ENV) + p.Logging.Loki.TenantId = &lokiTenantID + } + + lokiEndpoint := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_LOKI_ENDPOINT_ENV) + if lokiEndpoint != "" { + if p.Logging == nil { + p.Logging = &ctfconfig.LoggingConfig{} + } + if p.Logging.Loki == nil { + p.Logging.Loki = &ctfconfig.LokiConfig{} + } + logger.Debug().Msgf("Using %s env var to override Logging.Loki.Endpoint", ctfconfig.E2E_TEST_LOKI_ENDPOINT_ENV) + p.Logging.Loki.Endpoint = &lokiEndpoint + } + + lokiBasicAuth := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_LOKI_BASIC_AUTH_ENV) + if lokiBasicAuth != "" { + if p.Logging == nil { + p.Logging = &ctfconfig.LoggingConfig{} + } + if p.Logging.Loki == nil { + p.Logging.Loki = &ctfconfig.LokiConfig{} + } + logger.Debug().Msgf("Using %s env var to override Logging.Loki.BasicAuth", ctfconfig.E2E_TEST_LOKI_BASIC_AUTH_ENV) + p.Logging.Loki.BasicAuth = &lokiBasicAuth + } + + lokiBearerToken := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_LOKI_BEARER_TOKEN_ENV) + if lokiBearerToken != "" { + if p.Logging == nil { + p.Logging = &ctfconfig.LoggingConfig{} + } + if p.Logging.Loki == nil { + p.Logging.Loki = &ctfconfig.LokiConfig{} + } + logger.Debug().Msgf("Using %s env var to override Logging.Loki.BearerToken", ctfconfig.E2E_TEST_LOKI_BEARER_TOKEN_ENV) + p.Logging.Loki.BearerToken = &lokiBearerToken + } + + grafanaBaseUrl := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_GRAFANA_BASE_URL_ENV) + if grafanaBaseUrl != "" { + if p.Logging == nil { + p.Logging = &ctfconfig.LoggingConfig{} + } + if p.Logging.Grafana == nil { + p.Logging.Grafana = &ctfconfig.GrafanaConfig{} + } + logger.Debug().Msgf("Using %s env var to override Logging.Grafana.BaseUrl", ctfconfig.E2E_TEST_GRAFANA_BASE_URL_ENV) + p.Logging.Grafana.BaseUrl = &grafanaBaseUrl + } + + grafanaDashboardUrl := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_GRAFANA_DASHBOARD_URL_ENV) + if grafanaDashboardUrl != "" { + if p.Logging == nil { + p.Logging = &ctfconfig.LoggingConfig{} + } + if p.Logging.Grafana == nil { + p.Logging.Grafana = &ctfconfig.GrafanaConfig{} + } + logger.Debug().Msgf("Using %s env var to override Logging.Grafana.DashboardUrl", ctfconfig.E2E_TEST_GRAFANA_DASHBOARD_URL_ENV) + p.Logging.Grafana.DashboardUrl = &grafanaDashboardUrl + } + + grafanaBearerToken := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_GRAFANA_BEARER_TOKEN_ENV) + if grafanaBearerToken != "" { + if p.Logging == nil { + p.Logging = &ctfconfig.LoggingConfig{} + } + if p.Logging.Grafana == nil { + p.Logging.Grafana = &ctfconfig.GrafanaConfig{} + } + logger.Debug().Msgf("Using %s env var to override Logging.Grafana.BearerToken", ctfconfig.E2E_TEST_GRAFANA_BEARER_TOKEN_ENV) + p.Logging.Grafana.BearerToken = &grafanaBearerToken + } + + walletKeys := ctfconfig.ReadEnvVarGroupedMap(ctfconfig.E2E_TEST_WALLET_KEY_ENV, ctfconfig.E2E_TEST_WALLET_KEYS_ENV) + if len(walletKeys) > 0 { + if p.Network == nil { + p.Network = &ctfconfig.NetworkConfig{} + } + logger.Debug().Msgf("Using %s and/or %s env vars to override Network.WalletKeys", ctfconfig.E2E_TEST_WALLET_KEY_ENV, ctfconfig.E2E_TEST_WALLET_KEYS_ENV) + p.Network.WalletKeys = walletKeys + } + + rpcHttpUrls := ctfconfig.ReadEnvVarGroupedMap(ctfconfig.E2E_TEST_RPC_HTTP_URL_ENV, ctfconfig.E2E_TEST_RPC_HTTP_URLS_ENV) + if len(rpcHttpUrls) > 0 { + if p.Network == nil { + p.Network = &ctfconfig.NetworkConfig{} + } + logger.Debug().Msgf("Using %s and/or %s env vars to override Network.RpcHttpUrls", ctfconfig.E2E_TEST_RPC_HTTP_URL_ENV, ctfconfig.E2E_TEST_RPC_HTTP_URLS_ENV) + p.Network.RpcHttpUrls = rpcHttpUrls + } + + rpcWsUrls := ctfconfig.ReadEnvVarGroupedMap(ctfconfig.E2E_TEST_RPC_WS_URL_ENV, ctfconfig.E2E_TEST_RPC_WS_URLS_ENV) + if len(rpcWsUrls) > 0 { + if p.Network == nil { + p.Network = &ctfconfig.NetworkConfig{} + } + logger.Debug().Msgf("Using %s and/or %s env vars to override Network.RpcWsUrls", ctfconfig.E2E_TEST_RPC_WS_URL_ENV, ctfconfig.E2E_TEST_RPC_WS_URLS_ENV) + p.Network.RpcWsUrls = rpcWsUrls + } + + chainlinkImage := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_CHAINLINK_IMAGE_ENV) + if chainlinkImage != "" { + if p.NewCLCluster == nil { + p.NewCLCluster = &ChainlinkDeployment{} + } + if p.NewCLCluster.Common == nil { + p.NewCLCluster.Common = &Node{} + } + if p.NewCLCluster.Common.ChainlinkImage == nil { + p.NewCLCluster.Common.ChainlinkImage = &ctfconfig.ChainlinkImageConfig{} + } + + logger.Debug().Msgf("Using %s env var to override NewCLCluster.Common.ChainlinkImage.Image", ctfconfig.E2E_TEST_CHAINLINK_IMAGE_ENV) + p.NewCLCluster.Common.ChainlinkImage.Image = &chainlinkImage + } + + chainlinkUpgradeImage := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_CHAINLINK_UPGRADE_IMAGE_ENV) + if chainlinkUpgradeImage != "" { + if p.NewCLCluster == nil { + p.NewCLCluster = &ChainlinkDeployment{} + } + if p.NewCLCluster.Common == nil { + p.NewCLCluster.Common = &Node{} + } + if p.NewCLCluster.Common.ChainlinkUpgradeImage == nil { + p.NewCLCluster.Common.ChainlinkUpgradeImage = &ctfconfig.ChainlinkImageConfig{} + } + + logger.Debug().Msgf("Using %s env var to override NewCLCluster.Common.ChainlinkUpgradeImage.Image", ctfconfig.E2E_TEST_CHAINLINK_UPGRADE_IMAGE_ENV) + p.NewCLCluster.Common.ChainlinkUpgradeImage.Image = &chainlinkUpgradeImage + } + + return nil +} + func (p *Common) GetNodeConfig() *ctfconfig.NodeConfig { return &ctfconfig.NodeConfig{ BaseConfigTOML: p.NewCLCluster.Common.BaseConfigTOML, From 0ceb9b5fc67199b850d16b6a5ab1848327e91a5b Mon Sep 17 00:00:00 2001 From: Vyzaldy Sanchez Date: Mon, 19 Aug 2024 14:34:36 -0400 Subject: [PATCH 106/432] Fix test flake on registry syncer (#14148) * Fixes test flake * Adds changeset * Fixes readme --- .changeset/big-students-rush.md | 5 +++++ core/services/registrysyncer/syncer_test.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/big-students-rush.md diff --git a/.changeset/big-students-rush.md b/.changeset/big-students-rush.md new file mode 100644 index 0000000000..914205cdf7 --- /dev/null +++ b/.changeset/big-students-rush.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#bugfix Fixes test flake diff --git a/core/services/registrysyncer/syncer_test.go b/core/services/registrysyncer/syncer_test.go index 2c08a1cdde..9e51b7498f 100644 --- a/core/services/registrysyncer/syncer_test.go +++ b/core/services/registrysyncer/syncer_test.go @@ -455,7 +455,7 @@ func TestSyncer_DBIntegration(t *testing.T) { syncer.AddLauncher(l) var latestLocalRegistryCalled, addLocalRegistryCalled bool - timeout := time.After(500 * time.Millisecond) + timeout := time.After(testutils.WaitTimeout(t)) for !latestLocalRegistryCalled || !addLocalRegistryCalled { select { From c72afe72e890a2a363bd54eb823c4ba54dd42fcb Mon Sep 17 00:00:00 2001 From: Patrick Date: Mon, 19 Aug 2024 18:45:40 -0400 Subject: [PATCH 107/432] bumping common to a commit on main (#14152) * bumping common to a commit on main * gomodtidy --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 0a9b4f7a34..4045c3b5e8 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index c228e65415..bbaf5271d4 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1186,8 +1186,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 h1:iT9xlcy7Q98F9QheClGBiU0Ig1A+0UhtFkEdKFHvX/0= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 h1:bNsry/El6yigB00BBU3iIOhZHiPm5MgCrDkJEFNXL1U= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/go.mod b/go.mod index e6fd4f9e23..7b5de72594 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index e484324866..6574c9c0d8 100644 --- a/go.sum +++ b/go.sum @@ -1141,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 h1:iT9xlcy7Q98F9QheClGBiU0Ig1A+0UhtFkEdKFHvX/0= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 h1:bNsry/El6yigB00BBU3iIOhZHiPm5MgCrDkJEFNXL1U= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 86a03cec17..7b0760de4d 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -33,7 +33,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 github.com/smartcontractkit/chainlink-testing-framework v1.34.2 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 8af6705473..324064296d 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1490,8 +1490,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 h1:iT9xlcy7Q98F9QheClGBiU0Ig1A+0UhtFkEdKFHvX/0= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 h1:bNsry/El6yigB00BBU3iIOhZHiPm5MgCrDkJEFNXL1U= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 6e33eb7e39..e960e12c63 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.31.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 github.com/smartcontractkit/chainlink-testing-framework v1.34.2 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 16b3525476..cac0f64d24 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1472,8 +1472,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82 h1:iT9xlcy7Q98F9QheClGBiU0Ig1A+0UhtFkEdKFHvX/0= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816202716-6930d109fd82/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 h1:bNsry/El6yigB00BBU3iIOhZHiPm5MgCrDkJEFNXL1U= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= From a937d5c577d8ba13dc7542a757359339442ae33f Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Tue, 20 Aug 2024 11:43:01 +0200 Subject: [PATCH 108/432] Separate token price reporting schedule (#14154) * Separate token price reporting schedule (#1278) ## Motivation Static price removal job rollout will be delayed to after 1.5 release. To unblock db load concerns in 1.4.21 which writes prices to db, we want to reduce number of token-price related insertions in db. ## Solution Separate gas price and token price insertion frequency, insert every 10 minutes for token price. 10-min resolution for token price is accurate enough for our use case. * Changeset --------- Co-authored-by: Chunkai Yang --- .changeset/late-stingrays-promise.md | 5 + .../ccip/internal/ccipdb/price_service.go | 249 ++++++++------ .../internal/ccipdb/price_service_test.go | 320 ++++++++++++------ 3 files changed, 363 insertions(+), 211 deletions(-) create mode 100644 .changeset/late-stingrays-promise.md diff --git a/.changeset/late-stingrays-promise.md b/.changeset/late-stingrays-promise.md new file mode 100644 index 0000000000..39ca570f58 --- /dev/null +++ b/.changeset/late-stingrays-promise.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Separate price updates schedule for token prices in CCIP #updated diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go index 7d7d5bda3a..2118d5832d 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go @@ -42,23 +42,28 @@ type PriceService interface { var _ PriceService = (*priceService)(nil) const ( - // Prices should expire after 10 minutes in DB. Prices should be fresh in the Commit plugin. - // 10 min provides sufficient buffer for the Commit plugin to withstand transient price update outages, while + // Gas prices are refreshed every 1 minute, they are sufficiently accurate, and consistent with Commit OCR round time. + gasPriceUpdateInterval = 1 * time.Minute + // Token prices are refreshed every 10 minutes, we only report prices for blue chip tokens, DS&A simulation show + // their prices are stable, 10-minute resolution is accurate enough. + tokenPriceUpdateInterval = 10 * time.Minute + + // Prices should expire after 25 minutes in DB. Prices should be fresh in the Commit plugin. + // 25 min provides sufficient buffer for the Commit plugin to withstand transient price update outages, while // surfacing price update outages quickly enough. - priceExpireSec = 600 - // Cleanups are called every 10 minutes. For a given job, on average we may expect 3 token prices and 1 gas price. - // 10 minutes should result in 40 rows being cleaned up per job, it is not a heavy load on DB, so there is no need - // to run cleanup more frequently. We shouldn't clean up less frequently than `priceExpireSec`. - priceCleanupInterval = 600 * time.Second + priceExpireThreshold = 25 * time.Minute - // Prices are refreshed every 1 minute, they are sufficiently accurate, and consistent with Commit OCR round time. - priceUpdateInterval = 60 * time.Second + // Cleanups are called every 10 minutes. For a given job, on average we may expect 3 token prices and 1 gas price. + // 10 minutes should result in ~13 rows being cleaned up per job, it is not a heavy load on DB, so there is no need + // to run cleanup more frequently. We shouldn't clean up less frequently than `priceExpireThreshold`. + priceCleanupInterval = 10 * time.Minute ) type priceService struct { - priceExpireSec int - cleanupInterval time.Duration - updateInterval time.Duration + priceExpireThreshold time.Duration + cleanupInterval time.Duration + gasUpdateInterval time.Duration + tokenUpdateInterval time.Duration lggr logger.Logger orm cciporm.ORM @@ -93,9 +98,10 @@ func NewPriceService( ctx, cancel := context.WithCancel(context.Background()) pw := &priceService{ - priceExpireSec: priceExpireSec, - cleanupInterval: utils.WithJitter(priceCleanupInterval), // use WithJitter to avoid multiple services impacting DB at same time - updateInterval: utils.WithJitter(priceUpdateInterval), + priceExpireThreshold: priceExpireThreshold, + cleanupInterval: utils.WithJitter(priceCleanupInterval), // use WithJitter to avoid multiple services impacting DB at same time + gasUpdateInterval: utils.WithJitter(gasPriceUpdateInterval), + tokenUpdateInterval: utils.WithJitter(tokenPriceUpdateInterval), lggr: lggr, orm: orm, @@ -135,10 +141,14 @@ func (p *priceService) Close() error { func (p *priceService) run() { cleanupTicker := time.NewTicker(p.cleanupInterval) - updateTicker := time.NewTicker(p.updateInterval) + gasUpdateTicker := time.NewTicker(p.gasUpdateInterval) + tokenUpdateTicker := time.NewTicker(p.tokenUpdateInterval) go func() { defer p.wg.Done() + defer cleanupTicker.Stop() + defer gasUpdateTicker.Stop() + defer tokenUpdateTicker.Stop() for { select { @@ -149,10 +159,15 @@ func (p *priceService) run() { if err != nil { p.lggr.Errorw("Error when cleaning up in-db prices in the background", "err", err) } - case <-updateTicker.C: - err := p.runUpdate(p.backgroundCtx) + case <-gasUpdateTicker.C: + err := p.runGasPriceUpdate(p.backgroundCtx) if err != nil { - p.lggr.Errorw("Error when updating prices in the background", "err", err) + p.lggr.Errorw("Error when updating gas prices in the background", "err", err) + } + case <-tokenUpdateTicker.C: + err := p.runTokenPriceUpdate(p.backgroundCtx) + if err != nil { + p.lggr.Errorw("Error when updating token prices in the background", "err", err) } } } @@ -167,8 +182,11 @@ func (p *priceService) UpdateDynamicConfig(ctx context.Context, gasPriceEstimato // Config update may substantially change the prices, refresh the prices immediately, this also makes testing easier // for not having to wait to the full update interval. - if err := p.runUpdate(ctx); err != nil { - p.lggr.Errorw("Error when updating prices after dynamic config update", "err", err) + if err := p.runGasPriceUpdate(ctx); err != nil { + p.lggr.Errorw("Error when updating gas prices after dynamic config update", "err", err) + } + if err := p.runTokenPriceUpdate(ctx); err != nil { + p.lggr.Errorw("Error when updating token prices after dynamic config update", "err", err) } return nil @@ -224,7 +242,7 @@ func (p *priceService) runCleanup(ctx context.Context) error { eg := new(errgroup.Group) eg.Go(func() error { - err := p.orm.ClearGasPricesByDestChain(ctx, p.destChainSelector, p.priceExpireSec) + err := p.orm.ClearGasPricesByDestChain(ctx, p.destChainSelector, int(p.priceExpireThreshold.Seconds())) if err != nil { return fmt.Errorf("error clearing gas prices: %w", err) } @@ -232,7 +250,7 @@ func (p *priceService) runCleanup(ctx context.Context) error { }) eg.Go(func() error { - err := p.orm.ClearTokenPricesByDestChain(ctx, p.destChainSelector, p.priceExpireSec) + err := p.orm.ClearTokenPricesByDestChain(ctx, p.destChainSelector, int(p.priceExpireThreshold.Seconds())) if err != nil { return fmt.Errorf("error clearing token prices: %w", err) } @@ -242,84 +260,134 @@ func (p *priceService) runCleanup(ctx context.Context) error { return eg.Wait() } -func (p *priceService) runUpdate(ctx context.Context) error { +func (p *priceService) runGasPriceUpdate(ctx context.Context) error { // Protect against concurrent updates of `gasPriceEstimator` and `destPriceRegistryReader` - // Price updates happen infrequently - once every `priceUpdateInterval` seconds. + // Price updates happen infrequently - once every `gasPriceUpdateInterval` seconds. // It does not happen on any code path that is performance sensitive. // We can afford to have non-performant unlocks here that is simple and safe. p.dynamicConfigMu.RLock() defer p.dynamicConfigMu.RUnlock() // There may be a period of time between service is started and dynamic config is updated - if p.gasPriceEstimator == nil || p.destPriceRegistryReader == nil { - p.lggr.Info("Skipping price update due to gasPriceEstimator and/or destPriceRegistry not ready") + if p.gasPriceEstimator == nil { + p.lggr.Info("Skipping gas price update due to gasPriceEstimator not ready") + return nil + } + + sourceGasPriceUSD, err := p.observeGasPriceUpdates(ctx, p.lggr) + if err != nil { + return fmt.Errorf("failed to observe gas price updates: %w", err) + } + + err = p.writeGasPricesToDB(ctx, sourceGasPriceUSD) + if err != nil { + return fmt.Errorf("failed to write gas prices to db: %w", err) + } + + return nil +} + +func (p *priceService) runTokenPriceUpdate(ctx context.Context) error { + // Protect against concurrent updates of `tokenPriceEstimator` and `destPriceRegistryReader` + // Price updates happen infrequently - once every `tokenPriceUpdateInterval` seconds. + p.dynamicConfigMu.RLock() + defer p.dynamicConfigMu.RUnlock() + + // There may be a period of time between service is started and dynamic config is updated + if p.destPriceRegistryReader == nil { + p.lggr.Info("Skipping token price update due to destPriceRegistry not ready") return nil } - sourceGasPriceUSD, tokenPricesUSD, err := p.observePriceUpdates(ctx, p.lggr) + tokenPricesUSD, err := p.observeTokenPriceUpdates(ctx, p.lggr) if err != nil { - return fmt.Errorf("failed to observe price updates: %w", err) + return fmt.Errorf("failed to observe token price updates: %w", err) } - err = p.writePricesToDB(ctx, sourceGasPriceUSD, tokenPricesUSD) + err = p.writeTokenPricesToDB(ctx, tokenPricesUSD) if err != nil { - return fmt.Errorf("failed to write prices to db: %w", err) + return fmt.Errorf("failed to write token prices to db: %w", err) } return nil } -func (p *priceService) observePriceUpdates( +func (p *priceService) observeGasPriceUpdates( ctx context.Context, lggr logger.Logger, -) (sourceGasPriceUSD *big.Int, tokenPricesUSD map[cciptypes.Address]*big.Int, err error) { - if p.gasPriceEstimator == nil || p.destPriceRegistryReader == nil { - return nil, nil, fmt.Errorf("gasPriceEstimator and/or destPriceRegistry is not set yet") +) (sourceGasPriceUSD *big.Int, err error) { + if p.gasPriceEstimator == nil { + return nil, fmt.Errorf("gasPriceEstimator is not set yet") } - sortedLaneTokens, filteredLaneTokens, err := ccipcommon.GetFilteredSortedLaneTokens(ctx, p.offRampReader, p.destPriceRegistryReader, p.priceGetter) + // Include wrapped native to identify the source native USD price, notice USD is in 1e18 scale, i.e. $1 = 1e18 + rawTokenPricesUSD, err := p.priceGetter.TokenPricesUSD(ctx, []cciptypes.Address{p.sourceNative}) + if err != nil { + return nil, fmt.Errorf("failed to fetch source native price (%s): %w", p.sourceNative, err) + } - lggr.Debugw("Filtered bridgeable tokens with no configured price getter", "filteredLaneTokens", filteredLaneTokens) + sourceNativePriceUSD, exists := rawTokenPricesUSD[p.sourceNative] + if !exists { + return nil, fmt.Errorf("missing source native (%s) price", p.sourceNative) + } + sourceGasPrice, err := p.gasPriceEstimator.GetGasPrice(ctx) + if err != nil { + return nil, err + } + if sourceGasPrice == nil { + return nil, fmt.Errorf("missing gas price") + } + sourceGasPriceUSD, err = p.gasPriceEstimator.DenoteInUSD(sourceGasPrice, sourceNativePriceUSD) if err != nil { - return nil, nil, fmt.Errorf("get destination tokens: %w", err) + return nil, err } - return p.generatePriceUpdates(ctx, lggr, sortedLaneTokens) + lggr.Infow("PriceService observed latest gas price", + "sourceChainSelector", p.sourceChainSelector, + "destChainSelector", p.destChainSelector, + "sourceNative", p.sourceNative, + "gasPriceWei", sourceGasPrice, + "sourceNativePriceUSD", sourceNativePriceUSD, + "sourceGasPriceUSD", sourceGasPriceUSD, + ) + return sourceGasPriceUSD, nil } // All prices are USD ($1=1e18) denominated. All prices must be not nil. // Return token prices should contain the exact same tokens as in tokenDecimals. -func (p *priceService) generatePriceUpdates( +func (p *priceService) observeTokenPriceUpdates( ctx context.Context, lggr logger.Logger, - sortedLaneTokens []cciptypes.Address, -) (sourceGasPriceUSD *big.Int, tokenPricesUSD map[cciptypes.Address]*big.Int, err error) { - // Include wrapped native in our token query as way to identify the source native USD price. - // notice USD is in 1e18 scale, i.e. $1 = 1e18 - queryTokens := ccipcommon.FlattenUniqueSlice([]cciptypes.Address{p.sourceNative}, sortedLaneTokens) +) (tokenPricesUSD map[cciptypes.Address]*big.Int, err error) { + if p.destPriceRegistryReader == nil { + return nil, fmt.Errorf("destPriceRegistry is not set yet") + } + + sortedLaneTokens, filteredLaneTokens, err := ccipcommon.GetFilteredSortedLaneTokens(ctx, p.offRampReader, p.destPriceRegistryReader, p.priceGetter) + if err != nil { + return nil, fmt.Errorf("get destination tokens: %w", err) + } + lggr.Debugw("Filtered bridgeable tokens with no configured price getter", "filteredLaneTokens", filteredLaneTokens) + + queryTokens := ccipcommon.FlattenUniqueSlice(sortedLaneTokens) rawTokenPricesUSD, err := p.priceGetter.TokenPricesUSD(ctx, queryTokens) if err != nil { - return nil, nil, err + return nil, fmt.Errorf("failed to fetch token prices (%v): %w", queryTokens, err) } lggr.Infow("Raw token prices", "rawTokenPrices", rawTokenPricesUSD) // make sure that we got prices for all the tokens of our query for _, token := range queryTokens { if rawTokenPricesUSD[token] == nil { - return nil, nil, fmt.Errorf("missing token price: %+v", token) + return nil, fmt.Errorf("missing token price: %+v", token) } } - sourceNativePriceUSD, exists := rawTokenPricesUSD[p.sourceNative] - if !exists { - return nil, nil, fmt.Errorf("missing source native (%s) price", p.sourceNative) - } - destTokensDecimals, err := p.destPriceRegistryReader.GetTokensDecimals(ctx, sortedLaneTokens) if err != nil { - return nil, nil, fmt.Errorf("get tokens decimals: %w", err) + return nil, fmt.Errorf("get tokens decimals: %w", err) } tokenPricesUSD = make(map[cciptypes.Address]*big.Int, len(rawTokenPricesUSD)) @@ -327,68 +395,47 @@ func (p *priceService) generatePriceUpdates( tokenPricesUSD[token] = calculateUsdPer1e18TokenAmount(rawTokenPricesUSD[token], destTokensDecimals[i]) } - sourceGasPrice, err := p.gasPriceEstimator.GetGasPrice(ctx) - if err != nil { - return nil, nil, err - } - if sourceGasPrice == nil { - return nil, nil, fmt.Errorf("missing gas price") - } - sourceGasPriceUSD, err = p.gasPriceEstimator.DenoteInUSD(sourceGasPrice, sourceNativePriceUSD) - if err != nil { - return nil, nil, err - } - - lggr.Infow("PriceService observed latest price", + lggr.Infow("PriceService observed latest token prices", "sourceChainSelector", p.sourceChainSelector, "destChainSelector", p.destChainSelector, - "gasPriceWei", sourceGasPrice, - "sourceNativePriceUSD", sourceNativePriceUSD, - "sourceGasPriceUSD", sourceGasPriceUSD, "tokenPricesUSD", tokenPricesUSD, ) - return sourceGasPriceUSD, tokenPricesUSD, nil + return tokenPricesUSD, nil } -func (p *priceService) writePricesToDB( - ctx context.Context, - sourceGasPriceUSD *big.Int, - tokenPricesUSD map[cciptypes.Address]*big.Int, -) (err error) { - eg := new(errgroup.Group) - - if sourceGasPriceUSD != nil { - eg.Go(func() error { - return p.orm.InsertGasPricesForDestChain(ctx, p.destChainSelector, p.jobId, []cciporm.GasPriceUpdate{ - { - SourceChainSelector: p.sourceChainSelector, - GasPrice: assets.NewWei(sourceGasPriceUSD), - }, - }) - }) +func (p *priceService) writeGasPricesToDB(ctx context.Context, sourceGasPriceUSD *big.Int) (err error) { + if sourceGasPriceUSD == nil { + return nil } - if tokenPricesUSD != nil { - var tokenPrices []cciporm.TokenPriceUpdate + return p.orm.InsertGasPricesForDestChain(ctx, p.destChainSelector, p.jobId, []cciporm.GasPriceUpdate{ + { + SourceChainSelector: p.sourceChainSelector, + GasPrice: assets.NewWei(sourceGasPriceUSD), + }, + }) +} - for token, price := range tokenPricesUSD { - tokenPrices = append(tokenPrices, cciporm.TokenPriceUpdate{ - TokenAddr: string(token), - TokenPrice: assets.NewWei(price), - }) - } +func (p *priceService) writeTokenPricesToDB(ctx context.Context, tokenPricesUSD map[cciptypes.Address]*big.Int) (err error) { + if tokenPricesUSD == nil { + return nil + } - // Sort token by addr to make price updates ordering deterministic, easier to testing and debugging - sort.Slice(tokenPrices, func(i, j int) bool { - return tokenPrices[i].TokenAddr < tokenPrices[j].TokenAddr - }) + var tokenPrices []cciporm.TokenPriceUpdate - eg.Go(func() error { - return p.orm.InsertTokenPricesForDestChain(ctx, p.destChainSelector, p.jobId, tokenPrices) + for token, price := range tokenPricesUSD { + tokenPrices = append(tokenPrices, cciporm.TokenPriceUpdate{ + TokenAddr: string(token), + TokenPrice: assets.NewWei(price), }) } - return eg.Wait() + // Sort token by addr to make price updates ordering deterministic, easier for testing and debugging + sort.Slice(tokenPrices, func(i, j int) bool { + return tokenPrices[i].TokenAddr < tokenPrices[j].TokenAddr + }) + + return p.orm.InsertTokenPricesForDestChain(ctx, p.destChainSelector, p.jobId, tokenPrices) } // Input price is USD per full token, with 18 decimal precision diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go index 0bea8af9a1..26721bdf8e 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go @@ -82,8 +82,8 @@ func TestPriceService_priceCleanup(t *testing.T) { } mockOrm := ccipmocks.NewORM(t) - mockOrm.On("ClearGasPricesByDestChain", ctx, destChainSelector, priceExpireSec).Return(gasPricesError).Once() - mockOrm.On("ClearTokenPricesByDestChain", ctx, destChainSelector, priceExpireSec).Return(tokenPricesError).Once() + mockOrm.On("ClearGasPricesByDestChain", ctx, destChainSelector, int(priceExpireThreshold.Seconds())).Return(gasPricesError).Once() + mockOrm.On("ClearTokenPricesByDestChain", ctx, destChainSelector, int(priceExpireThreshold.Seconds())).Return(tokenPricesError).Once() priceService := NewPriceService( lggr, @@ -105,17 +105,13 @@ func TestPriceService_priceCleanup(t *testing.T) { } } -func TestPriceService_priceWrite(t *testing.T) { +func TestPriceService_writeGasPrices(t *testing.T) { lggr := logger.TestLogger(t) jobId := int32(1) destChainSelector := uint64(12345) sourceChainSelector := uint64(67890) gasPrice := big.NewInt(1e18) - tokenPrices := map[cciptypes.Address]*big.Int{ - "0x123": big.NewInt(2e18), - "0x234": big.NewInt(3e18), - } expectedGasPriceUpdate := []cciporm.GasPriceUpdate{ { @@ -123,6 +119,67 @@ func TestPriceService_priceWrite(t *testing.T) { GasPrice: assets.NewWei(gasPrice), }, } + + testCases := []struct { + name string + gasPriceError bool + expectedErr bool + }{ + { + name: "ORM called successfully", + gasPriceError: false, + expectedErr: false, + }, + { + name: "gasPrice clear failed", + gasPriceError: true, + expectedErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctx := tests.Context(t) + + var gasPricesError error + if tc.gasPriceError { + gasPricesError = fmt.Errorf("gas prices error") + } + + mockOrm := ccipmocks.NewORM(t) + mockOrm.On("InsertGasPricesForDestChain", ctx, destChainSelector, jobId, expectedGasPriceUpdate).Return(gasPricesError).Once() + + priceService := NewPriceService( + lggr, + mockOrm, + jobId, + destChainSelector, + sourceChainSelector, + "", + nil, + nil, + ).(*priceService) + err := priceService.writeGasPricesToDB(ctx, gasPrice) + if tc.expectedErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPriceService_writeTokenPrices(t *testing.T) { + lggr := logger.TestLogger(t) + jobId := int32(1) + destChainSelector := uint64(12345) + sourceChainSelector := uint64(67890) + + tokenPrices := map[cciptypes.Address]*big.Int{ + "0x123": big.NewInt(2e18), + "0x234": big.NewInt(3e18), + } + expectedTokenPriceUpdate := []cciporm.TokenPriceUpdate{ { TokenAddr: "0x123", @@ -136,31 +193,16 @@ func TestPriceService_priceWrite(t *testing.T) { testCases := []struct { name string - gasPriceError bool tokenPriceError bool expectedErr bool }{ { name: "ORM called successfully", - gasPriceError: false, tokenPriceError: false, expectedErr: false, }, - { - name: "gasPrice clear failed", - gasPriceError: true, - tokenPriceError: false, - expectedErr: true, - }, { name: "tokenPrice clear failed", - gasPriceError: false, - tokenPriceError: true, - expectedErr: true, - }, - { - name: "both ORM calls failed", - gasPriceError: true, tokenPriceError: true, expectedErr: true, }, @@ -170,17 +212,12 @@ func TestPriceService_priceWrite(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := tests.Context(t) - var gasPricesError error var tokenPricesError error - if tc.gasPriceError { - gasPricesError = fmt.Errorf("gas prices error") - } if tc.tokenPriceError { tokenPricesError = fmt.Errorf("token prices error") } mockOrm := ccipmocks.NewORM(t) - mockOrm.On("InsertGasPricesForDestChain", ctx, destChainSelector, jobId, expectedGasPriceUpdate).Return(gasPricesError).Once() mockOrm.On("InsertTokenPricesForDestChain", ctx, destChainSelector, jobId, expectedTokenPriceUpdate).Return(tokenPricesError).Once() priceService := NewPriceService( @@ -193,7 +230,7 @@ func TestPriceService_priceWrite(t *testing.T) { nil, nil, ).(*priceService) - err := priceService.writePricesToDB(ctx, gasPrice, tokenPrices) + err := priceService.writeTokenPricesToDB(ctx, tokenPrices) if tc.expectedErr { assert.Error(t, err) } else { @@ -203,22 +240,15 @@ func TestPriceService_priceWrite(t *testing.T) { } } -func TestPriceService_generatePriceUpdates(t *testing.T) { +func TestPriceService_observeGasPriceUpdates(t *testing.T) { lggr := logger.TestLogger(t) jobId := int32(1) destChainSelector := uint64(12345) sourceChainSelector := uint64(67890) - - const nTokens = 10 - tokens := make([]cciptypes.Address, nTokens) - for i := range tokens { - tokens[i] = cciptypes.Address(utils.RandomAddress().String()) - } - sort.Slice(tokens, func(i, j int) bool { return tokens[i] < tokens[j] }) + sourceNativeToken := cciptypes.Address(utils.RandomAddress().String()) testCases := []struct { name string - tokenDecimals map[cciptypes.Address]uint8 sourceNativeToken cciptypes.Address priceGetterRespData map[cciptypes.Address]*big.Int priceGetterRespErr error @@ -226,108 +256,179 @@ func TestPriceService_generatePriceUpdates(t *testing.T) { feeEstimatorRespErr error maxGasPrice uint64 expSourceGasPriceUSD *big.Int - expTokenPricesUSD map[cciptypes.Address]*big.Int expErr bool }{ { - name: "base", - tokenDecimals: map[cciptypes.Address]uint8{ - tokens[0]: 18, - tokens[1]: 12, - }, - sourceNativeToken: tokens[0], + name: "base", + sourceNativeToken: sourceNativeToken, priceGetterRespData: map[cciptypes.Address]*big.Int{ - tokens[0]: val1e18(100), - tokens[1]: val1e18(200), - tokens[2]: val1e18(300), // price getter returned a price for this token even though we didn't request it (should be skipped) + sourceNativeToken: val1e18(100), }, priceGetterRespErr: nil, feeEstimatorRespFee: big.NewInt(10), feeEstimatorRespErr: nil, maxGasPrice: 1e18, expSourceGasPriceUSD: big.NewInt(1000), - expTokenPricesUSD: map[cciptypes.Address]*big.Int{ - tokens[0]: val1e18(100), - tokens[1]: val1e18(200 * 1e6), - }, - expErr: false, + expErr: false, }, { - name: "price getter returned an error", - tokenDecimals: map[cciptypes.Address]uint8{ - tokens[0]: 18, - tokens[1]: 18, - }, - sourceNativeToken: tokens[0], + name: "price getter returned an error", + sourceNativeToken: sourceNativeToken, priceGetterRespData: nil, priceGetterRespErr: fmt.Errorf("some random network error"), expErr: true, }, { - name: "price getter skipped a requested price", - tokenDecimals: map[cciptypes.Address]uint8{ - tokens[0]: 18, - tokens[1]: 18, - }, - sourceNativeToken: tokens[0], + name: "price getter did not return source native gas price", + sourceNativeToken: sourceNativeToken, priceGetterRespData: map[cciptypes.Address]*big.Int{ - tokens[0]: val1e18(100), + "0x1": val1e18(100), }, priceGetterRespErr: nil, expErr: true, }, { - name: "price getter skipped source native price", - tokenDecimals: map[cciptypes.Address]uint8{ - tokens[0]: 18, - tokens[1]: 18, + name: "dynamic fee cap overrides legacy", + sourceNativeToken: sourceNativeToken, + priceGetterRespData: map[cciptypes.Address]*big.Int{ + sourceNativeToken: val1e18(100), }, - sourceNativeToken: tokens[2], + priceGetterRespErr: nil, + feeEstimatorRespFee: big.NewInt(20), + feeEstimatorRespErr: nil, + maxGasPrice: 1e18, + expSourceGasPriceUSD: big.NewInt(2000), + expErr: false, + }, + { + name: "nil gas price", + sourceNativeToken: sourceNativeToken, priceGetterRespData: map[cciptypes.Address]*big.Int{ - tokens[0]: val1e18(100), - tokens[1]: val1e18(200), + sourceNativeToken: val1e18(100), }, - priceGetterRespErr: nil, - expErr: true, + feeEstimatorRespFee: nil, + maxGasPrice: 1e18, + expErr: true, }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + priceGetter := pricegetter.NewMockPriceGetter(t) + defer priceGetter.AssertExpectations(t) + + gasPriceEstimator := prices.NewMockGasPriceEstimatorCommit(t) + defer gasPriceEstimator.AssertExpectations(t) + + priceGetter.On("TokenPricesUSD", mock.Anything, []cciptypes.Address{tc.sourceNativeToken}).Return(tc.priceGetterRespData, tc.priceGetterRespErr) + + if tc.maxGasPrice > 0 { + gasPriceEstimator.On("GetGasPrice", mock.Anything).Return(tc.feeEstimatorRespFee, tc.feeEstimatorRespErr) + if tc.feeEstimatorRespFee != nil { + pUSD := ccipcalc.CalculateUsdPerUnitGas(tc.feeEstimatorRespFee, tc.priceGetterRespData[tc.sourceNativeToken]) + gasPriceEstimator.On("DenoteInUSD", mock.Anything, mock.Anything).Return(pUSD, nil) + } + } + + priceService := NewPriceService( + lggr, + nil, + jobId, + destChainSelector, + sourceChainSelector, + tc.sourceNativeToken, + priceGetter, + nil, + ).(*priceService) + priceService.gasPriceEstimator = gasPriceEstimator + + sourceGasPriceUSD, err := priceService.observeGasPriceUpdates(context.Background(), lggr) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.True(t, tc.expSourceGasPriceUSD.Cmp(sourceGasPriceUSD) == 0) + }) + } +} + +func TestPriceService_observeTokenPriceUpdates(t *testing.T) { + lggr := logger.TestLogger(t) + jobId := int32(1) + destChainSelector := uint64(12345) + sourceChainSelector := uint64(67890) + + const nTokens = 10 + tokens := make([]cciptypes.Address, nTokens) + for i := range tokens { + tokens[i] = cciptypes.Address(utils.RandomAddress().String()) + } + sort.Slice(tokens, func(i, j int) bool { return tokens[i] < tokens[j] }) + + testCases := []struct { + name string + tokenDecimals map[cciptypes.Address]uint8 + filterOutTokens []cciptypes.Address + priceGetterRespData map[cciptypes.Address]*big.Int + priceGetterRespErr error + expTokenPricesUSD map[cciptypes.Address]*big.Int + expErr bool + }{ { - name: "dynamic fee cap overrides legacy", + name: "base", tokenDecimals: map[cciptypes.Address]uint8{ tokens[0]: 18, - tokens[1]: 18, + tokens[1]: 12, }, - sourceNativeToken: tokens[0], + filterOutTokens: []cciptypes.Address{tokens[2]}, priceGetterRespData: map[cciptypes.Address]*big.Int{ tokens[0]: val1e18(100), tokens[1]: val1e18(200), tokens[2]: val1e18(300), // price getter returned a price for this token even though we didn't request it (should be skipped) }, - priceGetterRespErr: nil, - feeEstimatorRespFee: big.NewInt(20), - feeEstimatorRespErr: nil, - maxGasPrice: 1e18, - expSourceGasPriceUSD: big.NewInt(2000), + priceGetterRespErr: nil, expTokenPricesUSD: map[cciptypes.Address]*big.Int{ tokens[0]: val1e18(100), - tokens[1]: val1e18(200), + tokens[1]: val1e18(200 * 1e6), }, expErr: false, }, { - name: "nil gas price", + name: "price getter returned an error", + tokenDecimals: map[cciptypes.Address]uint8{ + tokens[0]: 18, + tokens[1]: 18, + }, + priceGetterRespData: nil, + priceGetterRespErr: fmt.Errorf("some random network error"), + expErr: true, + }, + { + name: "price getter skipped a requested price", tokenDecimals: map[cciptypes.Address]uint8{ tokens[0]: 18, tokens[1]: 18, }, - sourceNativeToken: tokens[0], priceGetterRespData: map[cciptypes.Address]*big.Int{ tokens[0]: val1e18(100), + }, + priceGetterRespErr: nil, + expErr: true, + }, + { + name: "nil token price", + tokenDecimals: map[cciptypes.Address]uint8{ + tokens[0]: 18, + tokens[1]: 18, + }, + filterOutTokens: []cciptypes.Address{tokens[2]}, + priceGetterRespData: map[cciptypes.Address]*big.Int{ + tokens[0]: nil, tokens[1]: val1e18(200), - tokens[2]: val1e18(300), // price getter returned a price for this token even though we didn't request it (should be skipped) + tokens[2]: val1e18(300), }, - feeEstimatorRespFee: nil, - maxGasPrice: 1e18, - expErr: true, + expErr: true, }, } @@ -336,9 +437,6 @@ func TestPriceService_generatePriceUpdates(t *testing.T) { priceGetter := pricegetter.NewMockPriceGetter(t) defer priceGetter.AssertExpectations(t) - gasPriceEstimator := prices.NewMockGasPriceEstimatorCommit(t) - defer gasPriceEstimator.AssertExpectations(t) - var destTokens []cciptypes.Address for tk := range tc.tokenDecimals { destTokens = append(destTokens, tk) @@ -351,22 +449,21 @@ func TestPriceService_generatePriceUpdates(t *testing.T) { destDecimals = append(destDecimals, tc.tokenDecimals[token]) } - queryTokens := ccipcommon.FlattenUniqueSlice([]cciptypes.Address{tc.sourceNativeToken}, destTokens) + queryTokens := ccipcommon.FlattenUniqueSlice(destTokens) if len(queryTokens) > 0 { priceGetter.On("TokenPricesUSD", mock.Anything, queryTokens).Return(tc.priceGetterRespData, tc.priceGetterRespErr) + priceGetter.On("FilterConfiguredTokens", mock.Anything, mock.Anything).Return(destTokens, tc.filterOutTokens, nil) } - if tc.maxGasPrice > 0 { - gasPriceEstimator.On("GetGasPrice", mock.Anything).Return(tc.feeEstimatorRespFee, tc.feeEstimatorRespErr) - if tc.feeEstimatorRespFee != nil { - pUSD := ccipcalc.CalculateUsdPerUnitGas(tc.feeEstimatorRespFee, tc.expTokenPricesUSD[tc.sourceNativeToken]) - gasPriceEstimator.On("DenoteInUSD", mock.Anything, mock.Anything).Return(pUSD, nil) - } - } + offRampReader := ccipdatamocks.NewOffRampReader(t) + offRampReader.On("GetTokens", mock.Anything).Return(cciptypes.OffRampTokens{ + DestinationTokens: destTokens, + }, nil).Maybe() destPriceReg := ccipdatamocks.NewPriceRegistryReader(t) destPriceReg.On("GetTokensDecimals", mock.Anything, destTokens).Return(destDecimals, nil).Maybe() + destPriceReg.On("GetFeeTokens", mock.Anything).Return([]cciptypes.Address{destTokens[0]}, nil).Maybe() priceService := NewPriceService( lggr, @@ -374,20 +471,18 @@ func TestPriceService_generatePriceUpdates(t *testing.T) { jobId, destChainSelector, sourceChainSelector, - tc.sourceNativeToken, + "0x123", priceGetter, - nil, + offRampReader, ).(*priceService) - priceService.gasPriceEstimator = gasPriceEstimator priceService.destPriceRegistryReader = destPriceReg - sourceGasPriceUSD, tokenPricesUSD, err := priceService.generatePriceUpdates(context.Background(), lggr, destTokens) + tokenPricesUSD, err := priceService.observeTokenPriceUpdates(context.Background(), lggr) if tc.expErr { assert.Error(t, err) return } assert.NoError(t, err) - assert.True(t, tc.expSourceGasPriceUSD.Cmp(sourceGasPriceUSD) == 0) assert.True(t, reflect.DeepEqual(tc.expTokenPricesUSD, tokenPricesUSD)) }) } @@ -680,8 +775,10 @@ func TestPriceService_priceWriteAndCleanupInBackground(t *testing.T) { gasPriceEstimator := prices.NewMockGasPriceEstimatorCommit(t) defer gasPriceEstimator.AssertExpectations(t) - priceGetter.On("TokenPricesUSD", mock.Anything, tokens).Return(map[cciptypes.Address]*big.Int{ + priceGetter.On("TokenPricesUSD", mock.Anything, tokens[:1]).Return(map[cciptypes.Address]*big.Int{ tokens[0]: val1e18(tokenPrices[0]), + }, nil) + priceGetter.On("TokenPricesUSD", mock.Anything, tokens[1:]).Return(map[cciptypes.Address]*big.Int{ tokens[1]: val1e18(tokenPrices[1]), tokens[2]: val1e18(tokenPrices[2]), }, nil) @@ -711,15 +808,18 @@ func TestPriceService_priceWriteAndCleanupInBackground(t *testing.T) { offRampReader, ).(*priceService) - updateInterval := 2000 * time.Millisecond + gasUpdateInterval := 2000 * time.Millisecond + tokenUpdateInterval := 5000 * time.Millisecond cleanupInterval := 3000 * time.Millisecond - // run write task every 2 second - priceService.updateInterval = updateInterval + // run gas price task every 2 second + priceService.gasUpdateInterval = gasUpdateInterval + // run token price task every 5 second + priceService.tokenUpdateInterval = tokenUpdateInterval // run cleanup every 3 seconds priceService.cleanupInterval = cleanupInterval // expire all prices during every cleanup - priceService.priceExpireSec = 0 + priceService.priceExpireThreshold = time.Duration(0) // initially, db is empty assert.NoError(t, checkResultLen(t, priceService, destChainSelector, 0, 0)) From 4f5374be052313a5d57f6cebbb8ebf88278b4832 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 20 Aug 2024 12:35:23 +0200 Subject: [PATCH 109/432] string v prefix from docker tag (#14147) --- .github/workflows/client-compatibility-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index ff776c7906..49ff2d9af7 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -225,6 +225,7 @@ jobs: elif [ "$GITHUB_REF_TYPE" = "tag" ]; then echo "Fetching Chainlink version from tag" chainlink_version="${{ github.ref_name }}" + chainlink_version=${chainlink_version#v} cl_ref_path="releases" else echo "Unsupported trigger event. It's probably an issue with the pipeline definition. Please reach out to the Test Tooling team." From 667bde4275b86f2721dad905e46383645b35c25b Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Tue, 20 Aug 2024 12:39:55 +0200 Subject: [PATCH 110/432] Update run-tests action for running E2E tests (#14156) --- .github/workflows/automation-ondemand-tests.yml | 2 +- .github/workflows/client-compatibility-tests.yml | 2 +- .github/workflows/integration-tests.yml | 12 ++++++------ .github/workflows/on-demand-keeper-smoke-tests.yml | 2 +- .../workflows/run-e2e-tests-reusable-workflow.yml | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml index 7514743fa8..83da3c3d52 100644 --- a/.github/workflows/automation-ondemand-tests.yml +++ b/.github/workflows/automation-ondemand-tests.yml @@ -260,7 +260,7 @@ jobs: duplicate-authorization-header: "true" - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 if: ${{ matrix.tests.enabled == true }} with: test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 49ff2d9af7..ea0b911936 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -625,7 +625,7 @@ jobs: # comment_on_pr: false # theme: 'dark' - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 with: test_command_to_run: cd ./integration-tests && touch .root_dir && go test -timeout 30m -count=1 -json ${{ matrix.evm_node.run }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 46aa53e9c1..ab6308f034 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -347,7 +347,7 @@ jobs: ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -462,7 +462,7 @@ jobs: ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -739,7 +739,7 @@ jobs: env: BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -1024,7 +1024,7 @@ jobs: ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -1303,7 +1303,7 @@ jobs: testLogCollect: ${{ vars.TEST_LOG_COLLECT }} logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - name: Run Migration Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 with: test_command_to_run: cd ./integration-tests && go test -timeout 20m -count=1 -json ./migration 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -1627,7 +1627,7 @@ jobs: echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - name: Run Tests if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 with: test_command_to_run: export ENV_JOB_IMAGE=${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-solana-tests:${{ needs.get_solana_sha.outputs.sha }} && make test_smoke test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} diff --git a/.github/workflows/on-demand-keeper-smoke-tests.yml b/.github/workflows/on-demand-keeper-smoke-tests.yml index 626daf0057..23626c2c98 100644 --- a/.github/workflows/on-demand-keeper-smoke-tests.yml +++ b/.github/workflows/on-demand-keeper-smoke-tests.yml @@ -134,7 +134,7 @@ jobs: ## Run this step when changes that require tests to be run are made - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index 4c177f9a13..edfd1a13d6 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -410,7 +410,7 @@ jobs: duplicate-authorization-header: "true" - name: Run tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 env: DETACH_RUNNER: true with: @@ -543,7 +543,7 @@ jobs: echo "Remote Runner Version: ${{ needs.prepare-remote-runner-test-image.outputs.remote-runner-version }}" - name: Run tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@aa8eea635029ab8d95abd3c206f56dae1e22e623 # v2.3.28 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 env: DETACH_RUNNER: true RR_MEM: ${{ matrix.tests.remote_runner_memory }} From 5c2da36855b9e56335fa079ae67ec88d96d15fe0 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 20 Aug 2024 12:56:41 +0200 Subject: [PATCH 111/432] allow to select commit SHA used for artifact generation (#14158) --- .../workflows/solidity-foundry-artifacts.yml | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/.github/workflows/solidity-foundry-artifacts.yml b/.github/workflows/solidity-foundry-artifacts.yml index 50a77e2846..7a96c81277 100644 --- a/.github/workflows/solidity-foundry-artifacts.yml +++ b/.github/workflows/solidity-foundry-artifacts.yml @@ -18,8 +18,12 @@ on: - "shared" - "transmission" - "vrf" + commit_to_use: + type: string + description: 'commit SHA to use for artifact generation; if empty HEAD will be used' + required: false base_ref: - description: 'commit or tag to be used as base reference, when looking for modified Solidity files' + description: 'commit or tag to use as base reference, when looking for modified Solidity files' required: true env: @@ -38,6 +42,8 @@ jobs: steps: - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + ref: ${{ inputs.commit_to_use || github.sha }} - name: Find modified contracts uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 id: changes @@ -137,13 +143,13 @@ jobs: - name: Generate basic info and modified contracts list shell: bash run: | - echo "Commit SHA used to generate artifacts: ${{ github.sha }}" > contracts/commit_sha_base_ref.txt + echo "Commit SHA used to generate artifacts: ${{ inputs.commit_to_use || github.sha }}" > contracts/commit_sha_base_ref.txt echo "Base reference SHA used to find modified contracts: ${{ inputs.base_ref }}" >> contracts/commit_sha_base_ref.txt IFS=',' read -r -a modified_files <<< "${{ needs.changes.outputs.product_files }}" echo "# Modified contracts:" > contracts/modified_contracts.md for file in "${modified_files[@]}"; do - echo " - [$file](${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/$file)" >> contracts/modified_contracts.md + echo " - [$file](${{ github.server_url }}/${{ github.repository }}/blob/${{ inputs.commit_to_use || github.sha }}/$file)" >> contracts/modified_contracts.md echo "$file" >> contracts/modified_contracts.txt done @@ -179,6 +185,8 @@ jobs: - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + ref: ${{ inputs.commit_to_use || github.sha }} - name: Setup NodeJS uses: ./.github/actions/setup-nodejs @@ -252,6 +260,7 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: fetch-depth: 0 + ref: ${{ inputs.commit_to_use || github.sha }} - name: Setup NodeJS uses: ./.github/actions/setup-nodejs @@ -295,7 +304,7 @@ jobs: contract_list="${{ needs.changes.outputs.product_files }}" echo "::debug::Processing contracts: $contract_list" - ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/" contracts/configs/slither/.slither.config-artifacts.json "." "$contract_list" "contracts/slither-reports" "--solc-remaps @=contracts/node_modules/@" + ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ inputs.commit_to_use || github.sha }}/" contracts/configs/slither/.slither.config-artifacts.json "." "$contract_list" "contracts/slither-reports" "--solc-remaps @=contracts/node_modules/@" - name: Upload UMLs and Slither reports uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 @@ -332,7 +341,7 @@ jobs: - name: Upload all artifacts as single package uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: - name: review-artifacts-${{ inputs.product }}-${{ github.sha }} + name: review-artifacts-${{ inputs.product }}-${{ inputs.commit_to_use || github.sha }} path: review_artifacts retention-days: 60 @@ -346,12 +355,12 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | ARTIFACTS=$(gh api -X GET repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts) - ARTIFACT_ID=$(echo "$ARTIFACTS" | jq '.artifacts[] | select(.name=="review-artifacts-${{ inputs.product }}-${{ github.sha }}") | .id') + ARTIFACT_ID=$(echo "$ARTIFACTS" | jq '.artifacts[] | select(.name=="review-artifacts-${{ inputs.product }}-${{ inputs.commit_to_use || github.sha }}") | .id') echo "Artifact ID: $ARTIFACT_ID" echo "# Solidity Review Artifact Generated" >> $GITHUB_STEP_SUMMARY echo "Base Ref used: **${{ inputs.base_ref }}**" >> $GITHUB_STEP_SUMMARY - echo "Commit SHA used: **${{ github.sha }}**" >> $GITHUB_STEP_SUMMARY + echo "Commit SHA used: **${{ inputs.commit_to_use || github.sha }}**" >> $GITHUB_STEP_SUMMARY echo "[Artifact URL](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/$ARTIFACT_ID)" >> $GITHUB_STEP_SUMMARY notify-no-changes: @@ -364,9 +373,9 @@ jobs: run: | echo "# Solidity Review Artifact NOT Generated" >> $GITHUB_STEP_SUMMARY echo "Base Ref used: **${{ inputs.base_ref }}**" >> $GITHUB_STEP_SUMMARY - echo "Commit SHA used: **${{ github.sha }}**" >> $GITHUB_STEP_SUMMARY + echo "Commit SHA used: **${{ inputs.commit_to_use || github.sha }}**" >> $GITHUB_STEP_SUMMARY echo "## Reason: No modified Solidity files found for ${{ inputs.product }}" >> $GITHUB_STEP_SUMMARY - echo "* no modified Solidity files found between ${{ inputs.base_ref }} and ${{ github.sha }} commits" >> $GITHUB_STEP_SUMMARY + echo "* no modified Solidity files found between ${{ inputs.base_ref }} and ${{ inputs.commit_to_use || github.sha }} commits" >> $GITHUB_STEP_SUMMARY echo "* or they are located outside of ./contracts/src/v0.8 folder" >> $GITHUB_STEP_SUMMARY echo "* or they were limited to test files" >> $GITHUB_STEP_SUMMARY exit 1 From 6d072dd415c5b5ed0a247b9fd53873b6790e5a02 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 20 Aug 2024 14:10:54 +0200 Subject: [PATCH 112/432] [TT-1435] use chatgpt to find new issues in modified Solidity files (#14104) * use chatgpt to find new issues in modified Solidity files * update prompts * CR changes * use exit instead of return * add product name to solidity artifact summary * prune lcov report in artifact pipeline * pin llm versions --- .../workflows/solidity-foundry-artifacts.yml | 13 +- .github/workflows/solidity-foundry.yml | 174 +++++++++++++++++- .../scripts/ci/find_slither_report_diff.sh | 94 ++++++++++ contracts/scripts/ci/prompt-difference.md | 21 +++ contracts/scripts/ci/prompt-validation.md | 33 ++++ 5 files changed, 323 insertions(+), 12 deletions(-) create mode 100755 contracts/scripts/ci/find_slither_report_diff.sh create mode 100644 contracts/scripts/ci/prompt-difference.md create mode 100644 contracts/scripts/ci/prompt-validation.md diff --git a/.github/workflows/solidity-foundry-artifacts.yml b/.github/workflows/solidity-foundry-artifacts.yml index 7a96c81277..9bba72b2e4 100644 --- a/.github/workflows/solidity-foundry-artifacts.yml +++ b/.github/workflows/solidity-foundry-artifacts.yml @@ -143,7 +143,8 @@ jobs: - name: Generate basic info and modified contracts list shell: bash run: | - echo "Commit SHA used to generate artifacts: ${{ inputs.commit_to_use || github.sha }}" > contracts/commit_sha_base_ref.txt + echo "Product: ${{ inputs.product }}" > contracts/commit_sha_base_ref.txt + echo "Commit SHA used to generate artifacts: ${{ inputs.commit_to_use || github.sha }}" >> contracts/commit_sha_base_ref.txt echo "Base reference SHA used to find modified contracts: ${{ inputs.base_ref }}" >> contracts/commit_sha_base_ref.txt IFS=',' read -r -a modified_files <<< "${{ needs.changes.outputs.product_files }}" @@ -221,11 +222,18 @@ jobs: env: FOUNDRY_PROFILE: ${{ inputs.product }} + - name: Prune lcov report + if: ${{ !contains(fromJson(steps.prepare-exclusion-list.outputs.coverage_exclusions), inputs.product) && needs.changes.outputs.product_changes == 'true' }} + shell: bash + working-directory: contracts + run: | + ./scripts/lcov_prune ${{ inputs.product }} ./code-coverage/lcov.info ./code-coverage/lcov.info.pruned + - name: Generate Code Coverage HTML report for product contracts if: ${{ !contains(fromJson(steps.prepare-exclusion-list.outputs.coverage_exclusions), inputs.product) && needs.changes.outputs.product_changes == 'true' }} shell: bash working-directory: contracts - run: genhtml code-coverage/lcov.info --branch-coverage --output-directory code-coverage + run: genhtml code-coverage/lcov.info.pruned --branch-coverage --output-directory code-coverage - name: Run Forge doc for product contracts if: ${{ needs.changes.outputs.product_changes == 'true' }} @@ -359,6 +367,7 @@ jobs: echo "Artifact ID: $ARTIFACT_ID" echo "# Solidity Review Artifact Generated" >> $GITHUB_STEP_SUMMARY + echo "Product: **${{ inputs.product }}**" >> $GITHUB_STEP_SUMMARY echo "Base Ref used: **${{ inputs.base_ref }}**" >> $GITHUB_STEP_SUMMARY echo "Commit SHA used: **${{ inputs.commit_to_use || github.sha }}**" >> $GITHUB_STEP_SUMMARY echo "[Artifact URL](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/$ARTIFACT_ID)" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index 906cb76ffe..c1da33dc6f 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -8,6 +8,11 @@ env: # * use the top-level matrix to decide, which checks should run for each product. # * when enabling code coverage, remember to adjust the minimum code coverage as it's set to 98.5% by default. +# This pipeline will run product tests only if product-specific contracts were modified or if broad-impact changes were made (e.g. changes to this pipeline, Foundry configuration, etc.) +# For modified contracts we use a LLM to extract new issues introduced by the changes. For new contracts full report is delivered. +# Slither has a default configuration, but also supports per-product configuration. If a product-specific configuration is not found, the default one is used. +# Changes to test files do not trigger static analysis or formatting checks. + jobs: define-matrix: name: Define test matrix @@ -53,8 +58,10 @@ jobs: runs-on: ubuntu-latest outputs: non_src_changes: ${{ steps.changes.outputs.non_src }} - sol_modified: ${{ steps.changes.outputs.sol }} - sol_modified_files: ${{ steps.changes.outputs.sol_files }} + sol_modified_added: ${{ steps.changes.outputs.sol }} + sol_modified_added_files: ${{ steps.changes.outputs.sol_files }} + sol_mod_only: ${{ steps.changes.outputs.sol_mod_only }} + sol_mod_only_files: ${{ steps.changes.outputs.sol_mod_only_files }} not_test_sol_modified: ${{ steps.changes.outputs.not_test_sol }} not_test_sol_modified_files: ${{ steps.changes.outputs.not_test_sol_files }} all_changes: ${{ steps.changes.outputs.changes }} @@ -73,6 +80,8 @@ jobs: - 'contracts/package.json' sol: - modified|added: 'contracts/src/v0.8/**/*.sol' + sol_mod_only: + - modified: 'contracts/src/v0.8/**/!(*.t).sol' not_test_sol: - modified|added: 'contracts/src/v0.8/**/!(*.t).sol' automation: @@ -199,7 +208,6 @@ jobs: || needs.changes.outputs.non_src_changes == 'true') && matrix.product.setup.run-coverage }} run: | - sudo apt-get install lcov ./contracts/scripts/lcov_prune ${{ matrix.product.name }} ./contracts/lcov.info ./contracts/lcov.info.pruned - name: Report code coverage for ${{ matrix.product.name }} @@ -229,6 +237,7 @@ jobs: this-job-name: Foundry Tests ${{ matrix.product.name }} continue-on-error: true + # runs only if non-test contracts were modified; scoped only to modified or added contracts analyze: needs: [ changes, define-matrix ] name: Run static analysis @@ -268,25 +277,165 @@ jobs: # modify remappings so that solc can find dependencies ./contracts/scripts/ci/modify_remappings.sh contracts contracts/remappings.txt mv remappings_modified.txt remappings.txt + + # without it Slither sometimes fails to use remappings correctly + cp contracts/foundry.toml foundry.toml + + FILES="${{ needs.changes.outputs.not_test_sol_modified_files }}" + + for FILE in $FILES; do + PRODUCT=$(echo "$FILE" | awk -F'src/[^/]*/' '{print $2}' | cut -d'/' -f1) + echo "::debug::Running Slither for $FILE in $PRODUCT" + SLITHER_CONFIG="contracts/configs/slither/.slither.config-$PRODUCT-pr.json" + if [[ ! -f $SLITHER_CONFIG ]]; then + echo "::debug::No Slither config found for $PRODUCT, using default" + SLITHER_CONFIG="contracts/configs/slither/.slither.config-default-pr.json" + fi + ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/" "$SLITHER_CONFIG" "." "$FILE" "contracts/slither-reports-current" "--solc-remaps @=contracts/node_modules/@" + done + + # all the actions below, up to printing results, run only if any existing contracts were modified + # in that case we extract new issues introduced by the changes by using an LLM model + - name: Upload Slither results for current branch + if: needs.changes.outputs.sol_mod_only == 'true' + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + timeout-minutes: 2 + continue-on-error: true + with: + name: slither-reports-current-${{ github.sha }} + path: contracts/slither-reports-current + retention-days: 7 + + # we need to upload scripts and configuration in case base_ref doesn't have the scripts, or they are in different version + - name: Upload Slither scripts + if: needs.changes.outputs.sol_mod_only == 'true' + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + timeout-minutes: 2 + continue-on-error: true + with: + name: tmp-slither-scripts-${{ github.sha }} + path: contracts/scripts/ci + retention-days: 7 + + - name: Upload configs + if: needs.changes.outputs.sol_mod_only == 'true' + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + timeout-minutes: 2 + continue-on-error: true + with: + name: tmp-configs-${{ github.sha }} + path: contracts/configs + retention-days: 7 + + - name: Checkout the repo + if: needs.changes.outputs.sol_mod_only == 'true' + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + ref: ${{ github.base_ref }} + + - name: Download Slither scripts + if: needs.changes.outputs.sol_mod_only == 'true' + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + name: tmp-slither-scripts-${{ github.sha }} + path: contracts/scripts/ci - FILES="${{ needs.changes.outputs.not_test_sol_modified_files }}" + - name: Download configs + if: needs.changes.outputs.sol_mod_only == 'true' + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + name: tmp-configs-${{ github.sha }} + path: contracts/configs + + # since we have just checked out the repository again, we lose NPM dependencies installs previously, we need to install them again to compile contracts + - name: Setup NodeJS + if: needs.changes.outputs.sol_mod_only == 'true' + uses: ./.github/actions/setup-nodejs + + - name: Run Slither for base reference + if: needs.changes.outputs.sol_mod_only == 'true' + shell: bash + run: | + # we need to set file permission again since they are lost during download + for file in contracts/scripts/ci/*.sh; do + chmod +x "$file" + done + + # modify remappings so that solc can find dependencies + ./contracts/scripts/ci/modify_remappings.sh contracts contracts/remappings.txt + mv remappings_modified.txt remappings.txt + + # without it Slither sometimes fails to use remappings correctly + cp contracts/foundry.toml foundry.toml + + FILES="${{ needs.changes.outputs.sol_mod_only_files }}" for FILE in $FILES; do PRODUCT=$(echo "$FILE" | awk -F'src/[^/]*/' '{print $2}' | cut -d'/' -f1) echo "::debug::Running Slither for $FILE in $PRODUCT" SLITHER_CONFIG="contracts/configs/slither/.slither.config-$PRODUCT-pr.json" - if [ ! -f $SLITHER_CONFIG ]; then + if [[ ! -f $SLITHER_CONFIG ]]; then echo "::debug::No Slither config found for $PRODUCT, using default" SLITHER_CONFIG="contracts/configs/slither/.slither.config-default-pr.json" fi - ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/" "$SLITHER_CONFIG" "." "$FILE" "contracts/slither-reports" "--solc-remaps @=contracts/node_modules/@" + ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/" "$SLITHER_CONFIG" "." "$FILE" "contracts/slither-reports-base-ref" "--solc-remaps @=contracts/node_modules/@" + done + + - name: Upload Slither report + if: needs.changes.outputs.sol_mod_only == 'true' + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + timeout-minutes: 10 + continue-on-error: true + with: + name: slither-reports-base-${{ github.sha }} + path: | + contracts/slither-reports-base-ref + retention-days: 7 + + - name: Download Slither results for current branch + if: needs.changes.outputs.sol_mod_only == 'true' + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + name: slither-reports-current-${{ github.sha }} + path: contracts/slither-reports-current + + - name: Generate diff of Slither reports for modified files + if: needs.changes.outputs.sol_mod_only == 'true' + env: + OPEN_API_KEY: ${{ secrets.OPEN_AI_SLITHER_API_KEY }} + shell: bash + run: | + set -euo pipefail + for base_report in contracts/slither-reports-base-ref/*.md; do + filename=$(basename "$base_report") + current_report="contracts/slither-reports-current/$filename" + new_issues_report="contracts/slither-reports-current/${filename%.md}_new_issues.md" + if [ -f "$current_report" ]; then + if ./contracts/scripts/ci/find_slither_report_diff.sh "$base_report" "$current_report" "$new_issues_report" "contracts/scripts/ci/prompt-difference.md" "contracts/scripts/ci/prompt-validation.md"; then + if [[ -s $new_issues_report ]]; then + awk 'NR==2{print "*This new issues report has been automatically generated by LLM model using two Slither reports. One based on `${{ github.base_ref}}` and another on `${{ github.sha }}` commits.*"}1' $new_issues_report > tmp.md && mv tmp.md $new_issues_report + echo "Replacing full Slither report with diff for $current_report" + rm $current_report && mv $new_issues_report $current_report + else + echo "No difference detected between $base_report and $current_report reports. Won't include any of them." + rm $current_report + fi + else + echo "::warning::Failed to generate a diff report with new issues for $base_report using an LLM model, will use full report." + fi + + else + echo "::error::Failed to find current commit's equivalent of $base_report (file $current_file doesn't exist, but should have been generated). Please check Slither logs." + exit 1 + fi done + # actions that execute only if any existing contracts were modified end here - name: Print Slither summary shell: bash run: | echo "# Static analysis results " >> $GITHUB_STEP_SUMMARY - for file in "contracts/slither-reports"/*.md; do + for file in "contracts/slither-reports-current"/*.md; do if [ -e "$file" ]; then cat "$file" >> $GITHUB_STEP_SUMMARY fi @@ -296,17 +445,17 @@ jobs: uses: ./.github/actions/validate-solidity-artifacts with: validate_slither_reports: 'true' - slither_reports_path: 'contracts/slither-reports' + slither_reports_path: 'contracts/slither-reports-current' sol_files: ${{ needs.changes.outputs.not_test_sol_modified_files }} - - name: Upload Slither report + - name: Upload Slither reports uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 timeout-minutes: 10 continue-on-error: true with: name: slither-reports-${{ github.sha }} path: | - contracts/slither-reports + contracts/slither-reports-current retention-days: 7 - name: Collect Metrics @@ -320,6 +469,11 @@ jobs: this-job-name: Run static analysis continue-on-error: true + - name: Remove temp artifacts + uses: geekyeggo/delete-artifact@24928e75e6e6590170563b8ddae9fac674508aa1 # v5.0 + with: + name: tmp-* + solidity-forge-fmt: name: Forge fmt ${{ matrix.product.name }} if: ${{ needs.changes.outputs.non_src_changes == 'true' || needs.changes.outputs.not_test_sol_modified == 'true' }} diff --git a/contracts/scripts/ci/find_slither_report_diff.sh b/contracts/scripts/ci/find_slither_report_diff.sh new file mode 100755 index 0000000000..d0b5238a1a --- /dev/null +++ b/contracts/scripts/ci/find_slither_report_diff.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash + +set -euo pipefail + +if [[ "$#" -lt 4 ]]; then + >&2 echo "Generates a markdown file with diff in new issues detected by ChatGPT between two Slither reports." + >&2 echo "Usage: $0 [path-to-validation-prompt]" + exit 1 +fi + +if [[ -z "${OPEN_API_KEY+x}" ]]; then + >&2 echo "OPEN_API_KEY is not set." + exit 1 +fi + +first_report_path=$1 +second_report_path=$2 +new_issues_report_path=$3 +report_prompt_path=$4 +if [[ "$#" -eq 5 ]]; then + validation_prompt_path=$5 +else + validation_prompt_path="" +fi + +first_report_content=$(cat "$first_report_path" | sed 's/"//g' | sed -E 's/\\+$//g' | sed -E 's/\\+ //g') +second_report_content=$(cat "$second_report_path" | sed 's/"//g' | sed -E 's/\\+$//g' | sed -E 's/\\+ //g') +openai_prompt=$(cat "$report_prompt_path" | sed 's/"/\\"/g' | sed -E 's/\\+$//g' | sed -E 's/\\+ //g') +openai_model="gpt-4o-2024-05-13" +openai_result=$(echo '{ + "model": "'$openai_model'", + "temperature": 0.01, + "messages": [ + { + "role": "system", + "content": "'$openai_prompt' \nreport1:\n```'$first_report_content'```\nreport2:\n```'$second_report_content'```" + } + ] +}' | envsubst | curl https://api.openai.com/v1/chat/completions \ + -w "%{http_code}" \ + -o prompt_response.json \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $OPEN_API_KEY" \ + -d @- +) + +# throw error openai_result when is not 200 +if [ "$openai_result" != '200' ]; then + echo "::error::OpenAI API call failed with status $openai_result: $(cat prompt_response.json)" + exit 1 +fi + +# replace lines starting with ' -' (1space) with ' -' (2spaces) +response_content=$(cat prompt_response.json | jq -r '.choices[0].message.content') +new_issues_report_content=$(echo "$response_content" | sed -e 's/^ -/ -/g') +echo "$new_issues_report_content" > "$new_issues_report_path" + +if [[ -n "$validation_prompt_path" ]]; then + echo "::debug::Validating the diff report using the validation prompt" + openai_model="gpt-4-turbo-2024-04-09" + report_input=$(echo "$new_issues_report_content" | sed 's/"//g' | sed -E 's/\\+$//g' | sed -E 's/\\+ //g') + validation_prompt_content=$(cat "$validation_prompt_path" | sed 's/"/\\"/g' | sed -E 's/\\+$//g' | sed -E 's/\\+ //g') + validation_result=$(echo '{ + "model": "'$openai_model'", + "temperature": 0.01, + "messages": [ + { + "role": "system", + "content": "'$validation_prompt_content' \nreport1:\n```'$first_report_content'```\nreport2:\n```'$second_report_content'```\nnew_issues:\n```'$report_input'```" + } + ] + }' | envsubst | curl https://api.openai.com/v1/chat/completions \ + -w "%{http_code}" \ + -o prompt_validation_response.json \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $OPEN_API_KEY" \ + -d @- + ) + + # throw error openai_result when is not 200 + if [ "$validation_result" != '200' ]; then + echo "::error::OpenAI API call failed with status $validation_result: $(cat prompt_validation_response.json)" + exit 1 + fi + + # replace lines starting with ' -' (1space) with ' -' (2spaces) + response_content=$(cat prompt_validation_response.json | jq -r '.choices[0].message.content') + + echo "$response_content" | sed -e 's/^ -/ -/g' >> "$new_issues_report_path" + echo "" >> "$new_issues_report_path" + echo "*Confidence rating presented above is an automatic validation (self-check) of the differences between two reports generated by ChatGPT ${openai_model} model. It has a scale of 1 to 5, where 1 means that all new issues are missing and 5 that all new issues are present*." >> "$new_issues_report_path" + echo "" >> "$new_issues_report_path" + echo "*If confidence rating is low it's advised to look for differences manually by downloading Slither reports for base reference and current commit from job's artifacts*." >> "$new_issues_report_path" +fi diff --git a/contracts/scripts/ci/prompt-difference.md b/contracts/scripts/ci/prompt-difference.md new file mode 100644 index 0000000000..b7603c9748 --- /dev/null +++ b/contracts/scripts/ci/prompt-difference.md @@ -0,0 +1,21 @@ +You are a helpful expert data engineer with expertise in Blockchain and Decentralized Oracle Networks. + +Given two reports generated by Slither - a Solidity static analysis tool - provided at the bottom of the reply, your task is to help create a report for your peers with new issues introduced in the second report in order to decrease noise resulting from irrelevant changes to the report, by focusing on a single topic: **New Issues**. + +First report is provided under Heading 2 (##) called `report1` and is surrounded by triple backticks (```) to indicate the beginning and end of the report. +Second report is provided under Heading 2 (##) called `report2` and is surrounded by triple backticks (```) to indicate the beginning and end of the report. + +First report is report generated by Slither using default branch of the code repository. Second report is report generated by Slither using a feature branch of the code repository. You want to help your peers understand the impact of changes they introduced in the pull request on the codebase and whether they introduced any new issues. + +**New Issues** + +Provide a bullet point summary of new issues that were introduced in the second report. If a given issue is not present in first report, but is present in the second one, it is considered a new issue. If the count for given issue type is higher in the second report than in the first one, it is considered a new issue. +For each issue include original description text from the report together with severity level, issue ID, line number and a link to problematic line in the code. +Group the issues by their type, which is defined as Heading 2 (##). + +Output your response starting from**New Issues** in escaped, markdown text that can be sent as http body to API. Do not wrap output in code blocks. +Extract the name of the file from the first line of the report and title the new report with it in a following way: "# Slither's new issues in: " + +Remember that it might be possible that second report does not introduce any new issues. In such case, provide an empty report. + +Format **New Issues** as Heading 2 using double sharp characters (##). Otherwise, do not include any another preamble and postamble to your answer. diff --git a/contracts/scripts/ci/prompt-validation.md b/contracts/scripts/ci/prompt-validation.md new file mode 100644 index 0000000000..5fcf08e146 --- /dev/null +++ b/contracts/scripts/ci/prompt-validation.md @@ -0,0 +1,33 @@ +You are a helpful expert data engineer with expertise in Blockchain and Decentralized Oracle Networks. + +At the bottom of the reply you will find two reports generated by Slither - a Solidity static analysis tool - and another report that contains new issues found in the second report. +Your task is to evaluate how well that new issues report shows all new issues mentioned in the second Slither report and assert its completeness. +Rate your confidence in the completeness of the new issues report on a scale from 1 to 5, where 1 means it's missing all new issues and 5 means that all new issues are present. + +First report is provided under Heading 2 (##) called `report1` and is surrounded by triple backticks (```) to indicate the beginning and end of the report. +Second report is provided under Heading 2 (##) called `report2` and is surrounded by triple backticks (```) to indicate the beginning and end of the report. +New issues report is provided under Heading 2 (##) called `new_issues` and is surrounded by triple backticks (```) to indicate the beginning and end of the report. + +Use the following steps to evaluate the new issues report: +* each report begins with a summary with types of issues found and number of issues found for each type, called "# Summary for " +* group issues by type and count for each report and calculate the expected difference in number of issues for each type for each report +* exclude all issue types, for which the count for is higher in the first report than in the second one +* for each remaining issue type, compare the number of issues found in the new issues report with the expected difference +* evaluate if the new issues report captures all new issues introduced in the second report + +Do not focus on: +* the quality of the Slither reports themselves, but rather on whether all new issues from the second report are present in the new issues report +* how well the new issues report is structured or written and how well it presents new issues + +It is crucial that you ignore all differences in the reports that are not related to new issues, such as resolved issues or issues, which count has decreased. + +If a given issue is not present in first report, but is present in the second one, it is considered a new issue. Similar behaviour is expected from the new issues report. +If the count for given issue type is higher in the second report than in the first one, it is considered a new issue. + +Your report should include only a single section titled "Confidence level". +Your evaluation of the completeness of the new issues report should be displayed as a Heading 3 using triple sharp characters (###). In a new line a brief explanation of the scale used, with minimum and maximum possible values. + +Remember that it might be possible that second report does not introduce any new issues. In such case, confidence rating should be 5. + +Output your response as escaped, markdown text that can be sent as http body to API. Do not wrap output in code blocks. Do not include any partial results or statistics regarding the number of new and resolved issues in any of the reports. +Format **Confidence level** as Heading 2 using double sharp characters (##). Otherwise, do not include any another preamble and postamble to your answer. From 0fd7480f9634cc1a41e69612e4f67f3d57a120f3 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 20 Aug 2024 15:25:10 +0200 Subject: [PATCH 113/432] golangci-lint: enable only-new-issues for PRs (#14136) --- .github/actions/golangci-lint/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/golangci-lint/action.yml b/.github/actions/golangci-lint/action.yml index f3697ed719..ffcfeea3d0 100644 --- a/.github/actions/golangci-lint/action.yml +++ b/.github/actions/golangci-lint/action.yml @@ -58,7 +58,7 @@ runs: skip-pkg-cache: true skip-build-cache: true # only-new-issues is only applicable to PRs, otherwise it is always set to false - only-new-issues: false # disabled for PRs due to unreliability + only-new-issues: true args: --out-format colored-line-number,checkstyle:golangci-lint-report.xml working-directory: ${{ inputs.go-directory }} - name: Print lint report artifact From 7fdc0c8e95c4157dd9e3ce3f9a4efe370554a19c Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Tue, 20 Aug 2024 15:06:46 +0100 Subject: [PATCH 114/432] ks-404 validate ids used in transmission schedule (#14116) --- .changeset/slimy-cars-sparkle.md | 5 +++ .../ccip/launcher/test_helpers.go | 2 +- core/capabilities/remote/dispatcher.go | 1 - core/capabilities/remote/target/client.go | 9 ++++- core/capabilities/remote/target/server.go | 3 +- core/capabilities/remote/trigger_publisher.go | 5 ++- core/capabilities/remote/utils.go | 24 ------------ core/capabilities/remote/utils_test.go | 12 ------ .../local_target_capability_test.go | 16 ++++---- .../capabilities/transmission/transmission.go | 12 ++++-- .../transmission/transmission_test.go | 22 ++++++----- core/capabilities/validation/validation.go | 38 +++++++++++++++++++ .../validation/validation_test.go | 19 ++++++++++ 13 files changed, 103 insertions(+), 65 deletions(-) create mode 100644 .changeset/slimy-cars-sparkle.md create mode 100644 core/capabilities/validation/validation.go create mode 100644 core/capabilities/validation/validation_test.go diff --git a/.changeset/slimy-cars-sparkle.md b/.changeset/slimy-cars-sparkle.md new file mode 100644 index 0000000000..aa7658ae90 --- /dev/null +++ b/.changeset/slimy-cars-sparkle.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal ks-404 validate ids before using as seed of transmission schedule diff --git a/core/capabilities/ccip/launcher/test_helpers.go b/core/capabilities/ccip/launcher/test_helpers.go index a2ebf3fdba..e1b47fa352 100644 --- a/core/capabilities/ccip/launcher/test_helpers.go +++ b/core/capabilities/ccip/launcher/test_helpers.go @@ -24,7 +24,7 @@ var ( p2pID1 = getP2PID(1) p2pID2 = getP2PID(2) defaultCapCfgs = map[string]registrysyncer.CapabilityConfiguration{ - defaultCapability.ID: registrysyncer.CapabilityConfiguration{}, + defaultCapability.ID: {}, } defaultRegistryDon = registrysyncer.DON{ DON: getDON(1, []ragep2ptypes.PeerID{p2pID1}, 0), diff --git a/core/capabilities/remote/dispatcher.go b/core/capabilities/remote/dispatcher.go index dab4f6c98b..bed485c286 100644 --- a/core/capabilities/remote/dispatcher.go +++ b/core/capabilities/remote/dispatcher.go @@ -13,7 +13,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types/core" - "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" "github.com/smartcontractkit/chainlink/v2/core/logger" diff --git a/core/capabilities/remote/target/client.go b/core/capabilities/remote/target/client.go index 4273169d23..8572efed15 100644 --- a/core/capabilities/remote/target/client.go +++ b/core/capabilities/remote/target/client.go @@ -12,6 +12,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/target/request" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/validation" "github.com/smartcontractkit/chainlink/v2/core/logger" ) @@ -172,8 +173,12 @@ func (c *client) Receive(ctx context.Context, msg *types.MessageBody) { } func GetMessageIDForRequest(req commoncap.CapabilityRequest) (string, error) { - if !remote.IsValidWorkflowOrExecutionID(req.Metadata.WorkflowID) || !remote.IsValidWorkflowOrExecutionID(req.Metadata.WorkflowExecutionID) { - return "", errors.New("workflow ID and workflow execution ID in request metadata are invalid") + if err := validation.ValidateWorkflowOrExecutionID(req.Metadata.WorkflowID); err != nil { + return "", fmt.Errorf("workflow ID is invalid: %w", err) + } + + if err := validation.ValidateWorkflowOrExecutionID(req.Metadata.WorkflowExecutionID); err != nil { + return "", fmt.Errorf("workflow execution ID is invalid: %w", err) } return req.Metadata.WorkflowID + req.Metadata.WorkflowExecutionID, nil diff --git a/core/capabilities/remote/target/server.go b/core/capabilities/remote/target/server.go index 56cad3739b..5324475b19 100644 --- a/core/capabilities/remote/target/server.go +++ b/core/capabilities/remote/target/server.go @@ -14,6 +14,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/target/request" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/validation" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -210,7 +211,7 @@ func (r *server) getMessageHash(msg *types.MessageBody) ([32]byte, error) { func GetMessageID(msg *types.MessageBody) (string, error) { idStr := string(msg.MessageId) - if !remote.IsValidID(idStr) { + if !validation.IsValidID(idStr) { return "", fmt.Errorf("invalid message id") } return idStr, nil diff --git a/core/capabilities/remote/trigger_publisher.go b/core/capabilities/remote/trigger_publisher.go index 23b778f601..4aac821bc1 100644 --- a/core/capabilities/remote/trigger_publisher.go +++ b/core/capabilities/remote/trigger_publisher.go @@ -10,6 +10,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/validation" "github.com/smartcontractkit/chainlink/v2/core/logger" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) @@ -102,8 +103,8 @@ func (p *triggerPublisher) Receive(_ context.Context, msg *types.MessageBody) { p.lggr.Errorw("sender not a member of its workflow DON", "capabilityId", p.capInfo.ID, "callerDonId", msg.CallerDonId, "sender", sender) return } - if !IsValidWorkflowOrExecutionID(req.Metadata.WorkflowID) { - p.lggr.Errorw("received trigger request with invalid workflow ID", "capabilityId", p.capInfo.ID, "workflowId", SanitizeLogString(req.Metadata.WorkflowID)) + if err = validation.ValidateWorkflowOrExecutionID(req.Metadata.WorkflowID); err != nil { + p.lggr.Errorw("received trigger request with invalid workflow ID", "capabilityId", p.capInfo.ID, "workflowId", SanitizeLogString(req.Metadata.WorkflowID), "err", err) return } p.lggr.Debugw("received trigger registration", "capabilityId", p.capInfo.ID, "workflowId", req.Metadata.WorkflowID, "sender", sender) diff --git a/core/capabilities/remote/utils.go b/core/capabilities/remote/utils.go index 7e303eefc8..c77ef67916 100644 --- a/core/capabilities/remote/utils.go +++ b/core/capabilities/remote/utils.go @@ -19,8 +19,6 @@ import ( const ( maxLoggedStringLen = 256 - validWorkflowIDLen = 64 - maxIDLen = 128 ) func ValidateMessage(msg p2ptypes.Message, expectedReceiver p2ptypes.PeerID) (*remotetypes.MessageBody, error) { @@ -115,25 +113,3 @@ func SanitizeLogString(s string) string { } return s + tooLongSuffix } - -// Workflow IDs and Execution IDs are 32-byte hex-encoded strings -func IsValidWorkflowOrExecutionID(id string) bool { - if len(id) != validWorkflowIDLen { - return false - } - _, err := hex.DecodeString(id) - return err == nil -} - -// Trigger event IDs and message IDs can only contain printable characters and must be non-empty -func IsValidID(id string) bool { - if len(id) == 0 || len(id) > maxIDLen { - return false - } - for i := 0; i < len(id); i++ { - if !unicode.IsPrint(rune(id[i])) { - return false - } - } - return true -} diff --git a/core/capabilities/remote/utils_test.go b/core/capabilities/remote/utils_test.go index 177ab5a7d1..1213507336 100644 --- a/core/capabilities/remote/utils_test.go +++ b/core/capabilities/remote/utils_test.go @@ -129,15 +129,3 @@ func TestSanitizeLogString(t *testing.T) { } require.Equal(t, longString[:256]+" [TRUNCATED]", remote.SanitizeLogString(longString)) } - -func TestIsValidWorkflowID(t *testing.T) { - require.False(t, remote.IsValidWorkflowOrExecutionID("too_short")) - require.False(t, remote.IsValidWorkflowOrExecutionID("nothex--95ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0")) - require.True(t, remote.IsValidWorkflowOrExecutionID("15c631d295ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0")) -} - -func TestIsValidTriggerEventID(t *testing.T) { - require.False(t, remote.IsValidID("")) - require.False(t, remote.IsValidID("\n\n")) - require.True(t, remote.IsValidID("id_id_2")) -} diff --git a/core/capabilities/transmission/local_target_capability_test.go b/core/capabilities/transmission/local_target_capability_test.go index 93bf708cce..cdca854986 100644 --- a/core/capabilities/transmission/local_target_capability_test.go +++ b/core/capabilities/transmission/local_target_capability_test.go @@ -54,8 +54,8 @@ func TestScheduledExecutionStrategy_LocalDON(t *testing.T) { name: "position 0; oneAtATime", position: 0, schedule: "oneAtATime", - low: 300 * time.Millisecond, - high: 400 * time.Millisecond, + low: 200 * time.Millisecond, + high: 300 * time.Millisecond, }, { name: "position 1; oneAtATime", @@ -68,15 +68,15 @@ func TestScheduledExecutionStrategy_LocalDON(t *testing.T) { name: "position 2; oneAtATime", position: 2, schedule: "oneAtATime", - low: 0 * time.Millisecond, - high: 100 * time.Millisecond, + low: 300 * time.Millisecond, + high: 400 * time.Millisecond, }, { name: "position 3; oneAtATime", position: 3, schedule: "oneAtATime", - low: 100 * time.Millisecond, - high: 300 * time.Millisecond, + low: 0 * time.Millisecond, + high: 100 * time.Millisecond, }, { name: "position 0; allAtOnce", @@ -121,8 +121,8 @@ func TestScheduledExecutionStrategy_LocalDON(t *testing.T) { req := capabilities.CapabilityRequest{ Config: m, Metadata: capabilities.RequestMetadata{ - WorkflowID: "mock-workflow-id", - WorkflowExecutionID: "mock-execution-id-1", + WorkflowID: "15c631d295ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0", + WorkflowExecutionID: "32c631d295ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce1", }, } diff --git a/core/capabilities/transmission/transmission.go b/core/capabilities/transmission/transmission.go index b41be5bcaa..88ce0fa3ed 100644 --- a/core/capabilities/transmission/transmission.go +++ b/core/capabilities/transmission/transmission.go @@ -4,10 +4,10 @@ import ( "fmt" "time" - "github.com/pkg/errors" - "github.com/smartcontractkit/libocr/permutation" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/validation" + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/values" "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" @@ -56,8 +56,12 @@ func GetPeerIDToTransmissionDelay(donPeerIDs []types.PeerID, req capabilities.Ca return nil, fmt.Errorf("failed to extract transmission config from request: %w", err) } - if req.Metadata.WorkflowID == "" || req.Metadata.WorkflowExecutionID == "" { - return nil, errors.New("workflow ID and workflow execution ID must be set in request metadata") + if err = validation.ValidateWorkflowOrExecutionID(req.Metadata.WorkflowID); err != nil { + return nil, fmt.Errorf("workflow ID is invalid: %w", err) + } + + if err = validation.ValidateWorkflowOrExecutionID(req.Metadata.WorkflowExecutionID); err != nil { + return nil, fmt.Errorf("workflow execution ID is invalid: %w", err) } transmissionID := req.Metadata.WorkflowID + req.Metadata.WorkflowExecutionID diff --git a/core/capabilities/transmission/transmission_test.go b/core/capabilities/transmission/transmission_test.go index fba233eadb..aaa367e78c 100644 --- a/core/capabilities/transmission/transmission_test.go +++ b/core/capabilities/transmission/transmission_test.go @@ -36,20 +36,21 @@ func Test_GetPeerIDToTransmissionDelay(t *testing.T) { "one", "oneAtATime", "100ms", - "mock-execution-id", + "15c631d295ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0", map[string]time.Duration{ "one": 300 * time.Millisecond, - "two": 100 * time.Millisecond, - "three": 0 * time.Millisecond, + "two": 0 * time.Millisecond, + "three": 100 * time.Millisecond, "four": 200 * time.Millisecond, }, }, + { "TestAllAtOnce", "one", "allAtOnce", "100ms", - "mock-execution-id", + "15c631d295ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0", map[string]time.Duration{ "one": 0 * time.Millisecond, "two": 0 * time.Millisecond, @@ -57,17 +58,18 @@ func Test_GetPeerIDToTransmissionDelay(t *testing.T) { "four": 0 * time.Millisecond, }, }, + { "TestOneAtATimeWithDifferentExecutionID", "one", "oneAtATime", "100ms", - "mock-execution-id2", + "16c631d295ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce1", map[string]time.Duration{ - "one": 0 * time.Millisecond, - "two": 200 * time.Millisecond, - "three": 100 * time.Millisecond, - "four": 300 * time.Millisecond, + "one": 300 * time.Millisecond, + "two": 100 * time.Millisecond, + "three": 200 * time.Millisecond, + "four": 0 * time.Millisecond, }, }, } @@ -83,7 +85,7 @@ func Test_GetPeerIDToTransmissionDelay(t *testing.T) { capabilityRequest := capabilities.CapabilityRequest{ Config: transmissionCfg, Metadata: capabilities.RequestMetadata{ - WorkflowID: "mock-workflow-id", + WorkflowID: "17c631d295ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0", WorkflowExecutionID: tc.workflowExecutionID, }, } diff --git a/core/capabilities/validation/validation.go b/core/capabilities/validation/validation.go new file mode 100644 index 0000000000..67ee3a504c --- /dev/null +++ b/core/capabilities/validation/validation.go @@ -0,0 +1,38 @@ +package validation + +import ( + "encoding/hex" + "errors" + "unicode" +) + +const ( + validWorkflowIDLen = 64 + maxIDLen = 128 +) + +// Workflow IDs and Execution IDs are 32-byte hex-encoded strings +func ValidateWorkflowOrExecutionID(id string) error { + if len(id) != validWorkflowIDLen { + return errors.New("must be 32 bytes long") + } + _, err := hex.DecodeString(id) + if err != nil { + return errors.New("must be a hex-encoded string") + } + + return nil +} + +// Trigger event IDs and message IDs can only contain printable characters and must be non-empty +func IsValidID(id string) bool { + if len(id) == 0 || len(id) > maxIDLen { + return false + } + for i := 0; i < len(id); i++ { + if !unicode.IsPrint(rune(id[i])) { + return false + } + } + return true +} diff --git a/core/capabilities/validation/validation_test.go b/core/capabilities/validation/validation_test.go new file mode 100644 index 0000000000..205898652f --- /dev/null +++ b/core/capabilities/validation/validation_test.go @@ -0,0 +1,19 @@ +package validation + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestIsValidWorkflowID(t *testing.T) { + require.NotNil(t, ValidateWorkflowOrExecutionID("too_short")) + require.NotNil(t, ValidateWorkflowOrExecutionID("nothex--95ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0")) + require.NoError(t, ValidateWorkflowOrExecutionID("15c631d295ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0")) +} + +func TestIsValidTriggerEventID(t *testing.T) { + require.False(t, IsValidID("")) + require.False(t, IsValidID("\n\n")) + require.True(t, IsValidID("id_id_2")) +} From 80c60c4a4fd9815757efb96fd2cffbdbd801928a Mon Sep 17 00:00:00 2001 From: David Cauchi <13139524+davidcauchi@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:15:27 +0200 Subject: [PATCH 115/432] Adds seth chain defaults (#14162) --- integration-tests/testconfig/default.toml | 116 ++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index 9609c6175d..b10c7280b3 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -602,3 +602,119 @@ evm_gas_estimation_buffer = 10000 evm_supports_eip1559 = true evm_default_gas_limit = 6000000 evm_chain_id = 5668 + +[[Seth.networks]] +name = "LINEA_SEPOLIA" +chain_id = "59141" +transaction_timeout = "10m" +transfer_gas_fee = 21_000 +gas_price = 200_000_000_000_000 +eip_1559_dynamic_fees = false +gas_fee_cap = 109_694_825_437 +gas_tip_cap = 30_000_000_000 +gas_price_estimation_enabled = true +gas_price_estimation_blocks = 1000 +gas_price_estimation_tx_priority = "standard" + +[[Seth.networks]] +name = "LINEA_MAINNET" +chain_id = "59144" +transaction_timeout = "10m" +transfer_gas_fee = 21_000 +gas_price = 200_000_000_000_000 +eip_1559_dynamic_fees = false +gas_fee_cap = 109_694_825_437 +gas_tip_cap = 30_000_000_000 +gas_price_estimation_enabled = true +gas_price_estimation_blocks = 1000 +gas_price_estimation_tx_priority = "standard" + +[[Seth.networks]] +name = "ZKSYNC_SEPOLIA" +chain_id = "300" +transaction_timeout = "3m" +transfer_gas_fee = 21_000 +gas_price = 200_000_000_000 +eip_1559_dynamic_fees = true +gas_fee_cap = 109_694_825_437 +gas_tip_cap = 30_000_000_000 +gas_price_estimation_enabled = true +gas_price_estimation_blocks = 1000 +gas_price_estimation_tx_priority = "standard" + +[[Seth.networks]] +name = "ZKSYNC_MAINNET" +chain_id = "324" +transaction_timeout = "3m" +transfer_gas_fee = 21_000 +gas_price = 200_000_000_000 +eip_1559_dynamic_fees = true +gas_fee_cap = 109_694_825_437 +gas_tip_cap = 30_000_000_000 +gas_price_estimation_enabled = true +gas_price_estimation_blocks = 1000 +gas_price_estimation_tx_priority = "standard" + +[[Seth.networks]] +name = "POLYGON_ZKEVM_CARDONA" +transaction_timeout = "3m" +transfer_gas_fee = 21_000 +gas_price = 743_000_000 +eip_1559_dynamic_fees = false +gas_fee_cap = 1_725_800_000 +gas_tip_cap = 822_800_000 +gas_price_estimation_enabled = true +gas_price_estimation_blocks = 1000 +gas_price_estimation_tx_priority = "standard" + +[[Seth.networks]] +name = "HEDERA_TESTNET" +transaction_timeout = "3m" +transfer_gas_fee = 800_000 +gas_limit = 2_000_000 +gas_price = 2_500_000_000_000 +eip_1559_dynamic_fees = false +gas_fee_cap = 109_694_825_437 +gas_tip_cap = 30_000_000_000 +gas_price_estimation_enabled = true +gas_price_estimation_blocks = 1000 +gas_price_estimation_tx_priority = "standard" + +[[Seth.networks]] +name = "TREASURE_RUBY" +chain_id = "978657" +transaction_timeout = "10m" +transfer_gas_fee = 21_000 +gas_price = 100_000_000 +eip_1559_dynamic_fees = true +gas_fee_cap = 200_000_000 +gas_tip_cap = 100_000_000 +gas_price_estimation_enabled = true +gas_price_estimation_blocks = 1000 +gas_price_estimation_tx_priority = "standard" + +[[Seth.networks]] +name = "XLAYER_MAINNET" +chain_id = "196" +transaction_timeout = "10m" +transfer_gas_fee = 21_000 +gas_price = 13_400_000_000 +eip_1559_dynamic_fees = false +gas_fee_cap = 109_694_825_437 +gas_tip_cap = 30_000_000_000 +gas_price_estimation_enabled = true +gas_price_estimation_blocks = 500 +gas_price_estimation_tx_priority = "standard" + +[[Seth.networks]] +name = "XLAYER_SEPOLIA" +chain_id = "195" +transaction_timeout = "10m" +transfer_gas_fee = 21_000 +gas_price = 200_000_000_000 +eip_1559_dynamic_fees = false +gas_fee_cap = 109_694_825_437 +gas_tip_cap = 30_000_000_000 +gas_price_estimation_enabled = true +gas_price_estimation_blocks = 500 +gas_price_estimation_tx_priority = "standard" From 910dd8db057410b103a3b407d1d5008121ba53c0 Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Tue, 20 Aug 2024 07:51:06 -0700 Subject: [PATCH 116/432] [KS-427] Launcher: process DONs in a deterministic order (#14153) Sort by IDs to avoid iterating over a map, which could yield different results on different nodes. --- core/capabilities/launcher.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/core/capabilities/launcher.go b/core/capabilities/launcher.go index fbf4d918a5..03a1dd54f0 100644 --- a/core/capabilities/launcher.go +++ b/core/capabilities/launcher.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "slices" "strings" "time" @@ -130,6 +131,12 @@ func (w *launcher) Name() string { func (w *launcher) Launch(ctx context.Context, state *registrysyncer.LocalRegistry) error { w.registry.SetLocalRegistry(state) + allDONIDs := []registrysyncer.DonID{} + for id := range state.IDsToDONs { + allDONIDs = append(allDONIDs, id) + } + slices.Sort(allDONIDs) // ensure deterministic order + // Let's start by updating the list of Peers // We do this by creating a new entry for each node belonging // to a public DON. @@ -137,7 +144,8 @@ func (w *launcher) Launch(ctx context.Context, state *registrysyncer.LocalRegist allPeers := make(map[ragetypes.PeerID]p2ptypes.StreamConfig) publicDONs := []registrysyncer.DON{} - for _, d := range state.IDsToDONs { + for _, id := range allDONIDs { + d := state.IDsToDONs[id] if !d.DON.IsPublic { continue } @@ -167,7 +175,8 @@ func (w *launcher) Launch(ctx context.Context, state *registrysyncer.LocalRegist myWorkflowDONs := []registrysyncer.DON{} remoteWorkflowDONs := []registrysyncer.DON{} myDONs := map[uint32]bool{} - for _, d := range state.IDsToDONs { + for _, id := range allDONIDs { + d := state.IDsToDONs[id] for _, peerID := range d.Members { if peerID == myID { myDONs[d.ID] = true From aec9d9f4e95efc1aa3b22cc314c10be7a6422437 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Tue, 20 Aug 2024 11:19:02 -0400 Subject: [PATCH 117/432] Fixes CCIP Change Detection (#14164) --- .github/workflows/integration-tests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index ab6308f034..500966c6a2 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -102,6 +102,9 @@ jobs: - 'core/**/config/**/*.toml' - 'integration-tests/**/*.toml' ccip-changes: + - '.github/workflows/integration-tests.yml' + - 'integration-tests/**/*.toml' + - '**/*Dockerfile' - '**/*ccip*' - '**/*ccip*/**' - name: Ignore Filter On Workflow Dispatch @@ -121,6 +124,7 @@ jobs: continue-on-error: true outputs: src: ${{ steps.ignore-filter.outputs.changes || steps.changes.outputs.changes }} + ccip-changes: ${{ steps.ignore-filter.outputs.changes || steps.changes.outputs.ccip-changes }} build-lint-integration-tests: name: Build and Lint ${{ matrix.project.name }} From f0d72f739a5657059f0ae05763bd8c804c0bc1b0 Mon Sep 17 00:00:00 2001 From: frank zhu Date: Tue, 20 Aug 2024 13:15:06 -0500 Subject: [PATCH 118/432] chore: update goreleaser develop tag mutable (#14167) --- .github/workflows/build-publish-develop-pr.yml | 2 +- .goreleaser.develop.yaml | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-publish-develop-pr.yml b/.github/workflows/build-publish-develop-pr.yml index c0c3a17824..b1b9db67c6 100644 --- a/.github/workflows/build-publish-develop-pr.yml +++ b/.github/workflows/build-publish-develop-pr.yml @@ -49,7 +49,7 @@ jobs: echo "image-tag=release-${short_sha}" | tee -a $GITHUB_OUTPUT echo "build-publish=true" | tee -a $GITHUB_OUTPUT else - echo "image-tag=develop-${short_sha}" | tee -a $GITHUB_OUTPUT + echo "image-tag=develop" | tee -a $GITHUB_OUTPUT echo "build-publish=true" | tee -a $GITHUB_OUTPUT fi elif [[ ${{ github.event_name }} == 'workflow_dispatch' ]]; then diff --git a/.goreleaser.develop.yaml b/.goreleaser.develop.yaml index b1f65217b8..c3126b30f6 100644 --- a/.goreleaser.develop.yaml +++ b/.goreleaser.develop.yaml @@ -1,4 +1,3 @@ -## goreleaser <1.14.0 project_name: chainlink env: @@ -80,6 +79,7 @@ dockers: - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}" - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-amd64" - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-amd64" - id: linux-arm64 @@ -133,6 +133,7 @@ dockers: - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins" - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-amd64" - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-amd64" - id: linux-arm64-plugins @@ -169,6 +170,7 @@ dockers: docker_manifests: - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}" image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}" - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-amd64" - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-arm64" - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}" @@ -177,6 +179,7 @@ docker_manifests: - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-arm64" - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins" image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins" - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-amd64" - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-arm64" - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins" From 32a743b3540de498f2213ee3e4c45453f4d921e9 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 20 Aug 2024 23:25:49 +0200 Subject: [PATCH 119/432] golangci-lint: revive: exported, var-naming, range-val-address, early-return (#11747) * golangci-lint: revive: exported, var-naming, range-val-address, early-return * core/scripts: only lint PRs and scheduled --- .github/workflows/ci-core.yml | 3 ++- .github/workflows/ci-scripts.yml | 2 ++ .golangci.yml | 5 +++-- GNUmakefile | 3 +-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index bb12304ef9..74369493eb 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -431,7 +431,8 @@ jobs: run: curl https://github.com/smartcontractkit/wsrpc/raw/main/cmd/protoc-gen-go-wsrpc/protoc-gen-go-wsrpc --output $HOME/go/bin/protoc-gen-go-wsrpc && chmod +x $HOME/go/bin/protoc-gen-go-wsrpc - name: Setup NodeJS uses: ./.github/actions/setup-nodejs - - run: | + - name: make generate + run: | make rm-mocked make generate - name: Ensure clean after generate diff --git a/.github/workflows/ci-scripts.yml b/.github/workflows/ci-scripts.yml index 2c1024310f..73e72eced5 100644 --- a/.github/workflows/ci-scripts.yml +++ b/.github/workflows/ci-scripts.yml @@ -6,6 +6,8 @@ on: jobs: lint-scripts: + # We don't directly merge dependabot PRs, so let's not waste the resources + if: ${{ (github.event_name == 'pull_request' || github.event_name == 'schedule') && github.actor != 'dependabot[bot]' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 diff --git a/.golangci.yml b/.golangci.yml index 7155cff2d5..72f52bd452 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -71,9 +71,10 @@ linters-settings: - name: error-return - name: error-strings - name: error-naming + - name: exported - name: if-return - name: increment-decrement - # - name: var-naming + - name: var-naming - name: var-declaration - name: package-comments - name: range @@ -92,7 +93,7 @@ linters-settings: - name: struct-tag # - name: string-format - name: string-of-int - # - name: range-val-address + - name: range-val-address - name: range-val-in-closure - name: modifies-value-receiver - name: modifies-parameter diff --git a/GNUmakefile b/GNUmakefile index 3b781a665d..775d204269 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -160,8 +160,7 @@ config-docs: ## Generate core node configuration documentation .PHONY: golangci-lint golangci-lint: ## Run golangci-lint for all issues. [ -d "./golangci-lint" ] || mkdir ./golangci-lint && \ - docker run --rm -v $(shell pwd):/app -w /app golangci/golangci-lint:v1.59.1 golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 > ./golangci-lint/$(shell date +%Y-%m-%d_%H:%M:%S).txt - + docker run --rm -v $(shell pwd):/app -w /app golangci/golangci-lint:v1.59.1 golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 | tee ./golangci-lint/$(shell date +%Y-%m-%d_%H:%M:%S).txt GORELEASER_CONFIG ?= .goreleaser.yaml From c6d1d4562dfe71e6a8737d86f93d27d35ea7e254 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 21 Aug 2024 01:24:11 +0200 Subject: [PATCH 120/432] use services.Config.NewService/Engine (part 2) (#14117) --- core/capabilities/targets/write_target.go | 6 +- core/services/llo/bm/dummy_transmitter.go | 7 +- .../llo/channel_definition_cache_factory.go | 2 +- .../llo/onchain_channel_definition_cache.go | 4 +- .../llo/static_channel_definitions_cache.go | 4 +- core/services/llo/transmitter.go | 2 +- .../ocr2/plugins/ccip/exportinternal.go | 3 +- .../batchreader/token_pool_batch_reader.go | 2 +- .../token_pool_batch_reader_test.go | 4 +- .../ccipdata/ccipdataprovider/provider.go | 3 +- .../ccipdata/commit_store_reader_test.go | 7 +- .../internal/ccipdata/factory/commit_store.go | 2 +- .../ccipdata/factory/commit_store_test.go | 4 +- .../ccip/internal/ccipdata/factory/offramp.go | 2 +- .../internal/ccipdata/factory/offramp_test.go | 4 +- .../ccip/internal/ccipdata/factory/onramp.go | 2 +- .../internal/ccipdata/factory/onramp_test.go | 4 +- .../ccipdata/factory/price_registry.go | 2 +- .../ccipdata/factory/price_registry_test.go | 4 +- .../internal/ccipdata/offramp_reader_test.go | 6 +- .../internal/ccipdata/onramp_reader_test.go | 8 +- .../ccipdata/price_registry_reader_test.go | 6 +- .../plugins/ccip/internal/ccipdata/reader.go | 3 +- .../ccip/internal/ccipdata/reader_test.go | 7 +- .../ccip/internal/ccipdata/usdc_reader.go | 3 +- .../ccipdata/usdc_reader_internal_test.go | 7 +- .../internal/ccipdata/v1_0_0/commit_store.go | 2 +- .../ccipdata/v1_0_0/commit_store_test.go | 4 +- .../ccip/internal/ccipdata/v1_0_0/offramp.go | 11 +- .../ccipdata/v1_0_0/offramp_reader_test.go | 5 +- .../v1_0_0/offramp_reader_unit_test.go | 11 +- .../internal/ccipdata/v1_0_0/offramp_test.go | 9 +- .../ccip/internal/ccipdata/v1_0_0/onramp.go | 3 +- .../ccipdata/v1_0_0/price_registry.go | 5 +- .../ccip/internal/ccipdata/v1_1_0/onramp.go | 2 +- .../internal/ccipdata/v1_2_0/commit_store.go | 2 +- .../ccipdata/v1_2_0/commit_store_test.go | 5 +- .../ccip/internal/ccipdata/v1_2_0/offramp.go | 3 +- .../ccipdata/v1_2_0/offramp_reader_test.go | 5 +- .../ccip/internal/ccipdata/v1_2_0/onramp.go | 3 +- .../internal/ccipdata/v1_2_0/onramp_test.go | 5 +- .../ccipdata/v1_2_0/price_registry.go | 3 +- .../internal/ccipdata/v1_5_0/commit_store.go | 2 +- .../ccip/internal/ccipdata/v1_5_0/offramp.go | 2 +- .../ccip/internal/ccipdata/v1_5_0/onramp.go | 2 +- .../internal/ccipdata/v1_5_0/onramp_test.go | 8 +- .../ocr2/plugins/ccip/internal/rpclib/evm.go | 2 +- .../ocr2/plugins/ccip/tokendata/usdc/usdc.go | 2 +- .../evmregistry/v21/block_subscriber.go | 7 +- .../evmregistry/v21/gasprice/gasprice.go | 3 +- .../evmregistry/v21/logprovider/buffer_v1.go | 7 +- .../v21/logprovider/buffer_v1_test.go | 4 +- .../evmregistry/v21/logprovider/factory.go | 3 +- .../evmregistry/v21/logprovider/provider.go | 13 +-- .../v21/logprovider/provider_life_cycle.go | 4 +- .../evmregistry/v21/logprovider/recoverer.go | 13 +-- .../v21/mercury/streams/streams.go | 4 +- .../evmregistry/v21/mercury/v02/request.go | 8 +- .../evmregistry/v21/mercury/v03/request.go | 8 +- .../evmregistry/v21/payload_builder.go | 6 +- .../ocr2keeper/evmregistry/v21/registry.go | 17 ++- .../v21/registry_check_pipeline_test.go | 25 ++-- .../evmregistry/v21/registry_test.go | 10 +- .../v21/transmit/event_provider.go | 7 +- .../evmregistry/v21/upkeepstate/scanner.go | 5 +- .../evmregistry/v21/upkeepstate/store.go | 7 +- .../ocrcommon/arbitrum_block_translator.go | 5 +- core/services/ocrcommon/block_translator.go | 3 +- core/services/relay/evm/batch_caller.go | 3 +- core/services/relay/evm/ccip.go | 10 +- core/services/relay/evm/chain_reader.go | 4 +- core/services/relay/evm/chain_writer.go | 2 +- core/services/relay/evm/commit_provider.go | 2 +- core/services/relay/evm/config_poller.go | 2 +- .../relay/evm/contract_transmitter.go | 6 +- core/services/relay/evm/evm.go | 107 ++++++++---------- core/services/relay/evm/exec_provider.go | 2 +- core/services/relay/evm/functions.go | 54 ++++----- .../relay/evm/functions/config_poller.go | 5 +- .../evm/functions/contract_transmitter.go | 6 +- .../relay/evm/functions/logpoller_wrapper.go | 2 +- .../services/relay/evm/llo_config_provider.go | 3 +- core/services/relay/evm/llo_provider.go | 4 +- core/services/relay/evm/median.go | 5 +- core/services/relay/evm/median_test.go | 6 +- .../relay/evm/mercury/config_poller.go | 3 +- .../relay/evm/mercury/persistence_manager.go | 5 +- core/services/relay/evm/mercury/queue.go | 6 +- .../services/relay/evm/mercury/transmitter.go | 13 ++- .../mercury/v1/reportcodec/report_codec.go | 3 +- .../mercury/v2/reportcodec/report_codec.go | 2 +- .../mercury/v3/reportcodec/report_codec.go | 2 +- .../mercury/v4/reportcodec/report_codec.go | 3 +- .../relay/evm/mercury_config_provider.go | 4 +- core/services/relay/evm/mercury_provider.go | 4 +- core/services/relay/evm/method_binding.go | 6 +- core/services/relay/evm/ocr2keeper.go | 4 +- core/services/relay/evm/plugin_provider.go | 3 +- core/services/relay/evm/request_round_db.go | 2 +- .../relay/evm/request_round_tracker.go | 2 +- .../relay/evm/standard_config_provider.go | 3 +- core/services/relay/evm/write_target.go | 5 +- 102 files changed, 319 insertions(+), 337 deletions(-) diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index 282a4741a6..da9841948d 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -13,9 +13,9 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) var ( @@ -56,15 +56,13 @@ func NewWriteTarget(lggr logger.Logger, id string, cr commontypes.ContractReader "Write target.", ) - logger := lggr.Named("WriteTarget") - return &WriteTarget{ cr, cw, forwarderAddress, txGasLimit - FORWARDER_CONTRACT_LOGIC_GAS_COST, info, - logger, + logger.Named(lggr, "WriteTarget"), false, } } diff --git a/core/services/llo/bm/dummy_transmitter.go b/core/services/llo/bm/dummy_transmitter.go index c349c9e0ee..aa29938545 100644 --- a/core/services/llo/bm/dummy_transmitter.go +++ b/core/services/llo/bm/dummy_transmitter.go @@ -12,10 +12,9 @@ import ( "github.com/smartcontractkit/chainlink-data-streams/llo" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" - - "github.com/smartcontractkit/chainlink/v2/core/logger" ) // A dummy transmitter useful for benchmarking and testing @@ -39,7 +38,7 @@ type transmitter struct { func NewTransmitter(lggr logger.Logger, fromAccount string) Transmitter { return &transmitter{ - lggr.Named("DummyTransmitter"), + logger.Named(lggr, "DummyTransmitter"), fromAccount, } } @@ -66,7 +65,7 @@ func (t *transmitter) Transmit( if err != nil { lggr.Debugw("Failed to decode JSON report", "err", err) } - lggr = lggr.With( + lggr = logger.With(lggr, "report.Report.ConfigDigest", r.ConfigDigest, "report.Report.SeqNr", r.SeqNr, "report.Report.ChannelID", r.ChannelID, diff --git a/core/services/llo/channel_definition_cache_factory.go b/core/services/llo/channel_definition_cache_factory.go index 51906e0ff1..4aa358d64a 100644 --- a/core/services/llo/channel_definition_cache_factory.go +++ b/core/services/llo/channel_definition_cache_factory.go @@ -6,10 +6,10 @@ import ( "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-common/pkg/logger" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/logger" lloconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/llo/config" ) diff --git a/core/services/llo/onchain_channel_definition_cache.go b/core/services/llo/onchain_channel_definition_cache.go index 4d3fb0e825..3362aa9b9d 100644 --- a/core/services/llo/onchain_channel_definition_cache.go +++ b/core/services/llo/onchain_channel_definition_cache.go @@ -13,12 +13,12 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_config_store" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) type ChannelDefinitionCacheORM interface { @@ -75,7 +75,7 @@ func NewChannelDefinitionCache(lggr logger.Logger, orm ChannelDefinitionCacheORM lp, 0, addr, - lggr.Named("ChannelDefinitionCache").With("addr", addr, "fromBlock", fromBlock), + logger.Sugared(lggr).Named("ChannelDefinitionCache").With("addr", addr, "fromBlock", fromBlock), sync.RWMutex{}, nil, fromBlock, diff --git a/core/services/llo/static_channel_definitions_cache.go b/core/services/llo/static_channel_definitions_cache.go index 98ef3642cb..980625bd59 100644 --- a/core/services/llo/static_channel_definitions_cache.go +++ b/core/services/llo/static_channel_definitions_cache.go @@ -7,7 +7,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/services" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink-common/pkg/logger" ) // A CDC that loads a static JSON of channel definitions; useful for @@ -27,7 +27,7 @@ func NewStaticChannelDefinitionCache(lggr logger.Logger, dfnstr string) (llotype if err := json.Unmarshal([]byte(dfnstr), &definitions); err != nil { return nil, err } - return &staticCDC{services.StateMachine{}, lggr.Named("StaticChannelDefinitionCache"), definitions}, nil + return &staticCDC{services.StateMachine{}, logger.Named(lggr, "StaticChannelDefinitionCache"), definitions}, nil } func (s *staticCDC) Start(context.Context) error { diff --git a/core/services/llo/transmitter.go b/core/services/llo/transmitter.go index b8cfb86de3..f876128481 100644 --- a/core/services/llo/transmitter.go +++ b/core/services/llo/transmitter.go @@ -11,10 +11,10 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" ) diff --git a/core/services/ocr2/plugins/ccip/exportinternal.go b/core/services/ocr2/plugins/ccip/exportinternal.go index 2a5767ac85..aecf1a0b16 100644 --- a/core/services/ocr2/plugins/ccip/exportinternal.go +++ b/core/services/ocr2/plugins/ccip/exportinternal.go @@ -7,11 +7,12 @@ import ( "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader.go index 57e8df1bde..32ec1b24ac 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader.go @@ -12,8 +12,8 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/logger" type_and_version "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/type_and_version_interface_wrapper" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader_test.go index c67c3c1527..ceafdf2272 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/batchreader/token_pool_batch_reader_test.go @@ -13,15 +13,15 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" ) func TestTokenPoolFactory(t *testing.T) { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) offRamp := utils.RandomAddress() ctx := context.Background() remoteChainSelector := uint64(2000) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/provider.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/provider.go index d1666d548a..971b507e82 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/provider.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/ccipdataprovider/provider.go @@ -3,10 +3,11 @@ package ccipdataprovider import ( "context" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/observability" ) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go index 4e134b1f17..3ba106f280 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -13,9 +13,9 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/config" - cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" evmclientmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" @@ -32,7 +32,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" @@ -142,7 +141,7 @@ func TestCommitOnchainConfig(t *testing.T) { func TestCommitStoreReaders(t *testing.T) { user, ec := newSim(t) ctx := testutils.Context(t) - lggr := logger.TestLogger(t) + lggr := logger.Test(t) lpOpts := logpoller.Opts{ PollPeriod: 100 * time.Millisecond, FinalityDepth: 2, @@ -412,7 +411,7 @@ func TestNewCommitStoreReader(t *testing.T) { if tc.expectedErr == "" { lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil) } - _, err = factory.NewCommitStoreReader(logger.TestLogger(t), factory.NewEvmVersionFinder(), addr, c, lp) + _, err = factory.NewCommitStoreReader(logger.Test(t), factory.NewEvmVersionFinder(), addr, c, lp) if tc.expectedErr != "" { require.EqualError(t, err, tc.expectedErr) } else { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store.go index d431d2863a..6ab9b52fc5 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store.go @@ -4,6 +4,7 @@ import ( "github.com/Masterminds/semver/v3" "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" @@ -11,7 +12,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_0_0" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store_test.go index e1b8ff929c..ae6b997794 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/commit_store_test.go @@ -9,10 +9,10 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" mocks2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/logger" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" @@ -20,7 +20,7 @@ import ( func TestCommitStore(t *testing.T) { for _, versionStr := range []string{ccipdata.V1_0_0, ccipdata.V1_2_0} { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) addr := cciptypes.Address(utils.RandomAddress().String()) lp := mocks2.NewLogPoller(t) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp.go index c6fa63ee82..3c8d7182d4 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp.go @@ -10,13 +10,13 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp_test.go index 4b9e57ecfb..145d00bc13 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/offramp_test.go @@ -9,10 +9,10 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" mocks2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/logger" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" @@ -20,7 +20,7 @@ import ( func TestOffRamp(t *testing.T) { for _, versionStr := range []string{ccipdata.V1_0_0, ccipdata.V1_2_0} { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) addr := cciptypes.Address(utils.RandomAddress().String()) lp := mocks2.NewLogPoller(t) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp.go index e82584ac7c..cb9e0015ca 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp.go @@ -5,9 +5,9 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/logger" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp_test.go index 8cf47ddc7b..e3013e3629 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp_test.go @@ -9,17 +9,17 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" mocks2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/logger" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" ) func TestOnRamp(t *testing.T) { for _, versionStr := range []string{ccipdata.V1_0_0, ccipdata.V1_1_0, ccipdata.V1_2_0, ccipdata.V1_5_0} { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) addr := cciptypes.Address(utils.RandomAddress().String()) lp := mocks2.NewLogPoller(t) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry.go index f1fa7c4e81..7f08b04d48 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry.go @@ -5,11 +5,11 @@ import ( "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/logger" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry_test.go index b4a9d30714..f388c5cb9a 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/price_registry_test.go @@ -9,11 +9,11 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" mocks2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" ) @@ -22,7 +22,7 @@ func TestPriceRegistry(t *testing.T) { ctx := testutils.Context(t) for _, versionStr := range []string{ccipdata.V1_0_0, ccipdata.V1_2_0} { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) addr := cciptypes.Address(utils.RandomAddress().String()) lp := mocks2.NewLogPoller(t) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go index 6f14fb8559..7a13e20cba 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" @@ -27,7 +28,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" @@ -158,7 +158,7 @@ func TestOffRampReaderInit(t *testing.T) { func setupOffRampReaderTH(t *testing.T, version string) offRampReaderTH { ctx := testutils.Context(t) user, bc := ccipdata.NewSimulation(t) - log := logger.TestLogger(t) + log := logger.Test(t) orm := logpoller.NewORM(testutils.SimulatedChainID, pgtest.NewSqlxDB(t), log) lpOpts := logpoller.Opts{ PollPeriod: 100 * time.Millisecond, @@ -405,7 +405,7 @@ func TestNewOffRampReader(t *testing.T) { addr := ccipcalc.EvmAddrToGeneric(utils.RandomAddress()) lp := lpmocks.NewLogPoller(t) lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil).Maybe() - _, err = factory.NewOffRampReader(logger.TestLogger(t), factory.NewEvmVersionFinder(), addr, c, lp, nil, nil, true) + _, err = factory.NewOffRampReader(logger.Test(t), factory.NewEvmVersionFinder(), addr, c, lp, nil, nil, true) if tc.expectedErr != "" { assert.EqualError(t, err, tc.expectedErr) } else { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_test.go index 9cfe3f628c..2f0ccbc246 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_test.go @@ -14,6 +14,7 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmclientmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" @@ -26,7 +27,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" @@ -40,7 +40,7 @@ type onRampReaderTH struct { func TestNewOnRampReader_noContractAtAddress(t *testing.T) { _, bc := ccipdata.NewSimulation(t) addr := ccipcalc.EvmAddrToGeneric(utils.RandomAddress()) - _, err := factory.NewOnRampReader(logger.TestLogger(t), factory.NewEvmVersionFinder(), testutils.SimulatedChainID.Uint64(), testutils.SimulatedChainID.Uint64(), addr, lpmocks.NewLogPoller(t), bc) + _, err := factory.NewOnRampReader(logger.Test(t), factory.NewEvmVersionFinder(), testutils.SimulatedChainID.Uint64(), testutils.SimulatedChainID.Uint64(), addr, lpmocks.NewLogPoller(t), bc) assert.EqualError(t, err, fmt.Sprintf("unable to read type and version: error calling typeAndVersion on addr: %s no contract code at given address", addr)) } @@ -77,7 +77,7 @@ func TestOnRampReaderInit(t *testing.T) { func setupOnRampReaderTH(t *testing.T, version string) onRampReaderTH { user, bc := ccipdata.NewSimulation(t) - log := logger.TestLogger(t) + log := logger.Test(t) orm := logpoller.NewORM(testutils.SimulatedChainID, pgtest.NewSqlxDB(t), log) lpOpts := logpoller.Opts{ PollPeriod: 100 * time.Millisecond, @@ -468,7 +468,7 @@ func TestNewOnRampReader(t *testing.T) { addr := ccipcalc.EvmAddrToGeneric(utils.RandomAddress()) lp := lpmocks.NewLogPoller(t) lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil).Maybe() - _, err = factory.NewOnRampReader(logger.TestLogger(t), factory.NewEvmVersionFinder(), 1, 2, addr, lp, c) + _, err = factory.NewOnRampReader(logger.Test(t), factory.NewEvmVersionFinder(), 1, 2, addr, lp, c) if tc.expectedErr != "" { require.EqualError(t, err, tc.expectedErr) } else { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go index e17b885cff..9ace6ea481 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go @@ -17,6 +17,7 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmclientmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" @@ -27,7 +28,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/factory" @@ -71,7 +71,7 @@ func newSim(t *testing.T) (*bind.TransactOpts, *client.SimulatedBackendClient) { // with a snapshot of data so reader tests can do multi-version assertions. func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { user, ec := newSim(t) - lggr := logger.TestLogger(t) + lggr := logger.Test(t) lpOpts := logpoller.Opts{ PollPeriod: 100 * time.Millisecond, FinalityDepth: 2, @@ -285,7 +285,7 @@ func TestNewPriceRegistryReader(t *testing.T) { addr := ccipcalc.EvmAddrToGeneric(utils.RandomAddress()) lp := lpmocks.NewLogPoller(t) lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil).Maybe() - _, err = factory.NewPriceRegistryReader(ctx, logger.TestLogger(t), factory.NewEvmVersionFinder(), addr, lp, c) + _, err = factory.NewPriceRegistryReader(ctx, logger.Test(t), factory.NewEvmVersionFinder(), addr, lp, c) if tc.expectedErr != "" { require.EqualError(t, err, tc.expectedErr) } else { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go index a9a07f0879..25471d0d65 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go @@ -6,10 +6,11 @@ import ( "github.com/ethereum/go-ethereum/core/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) const ( diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader_test.go index 06766be81e..0df7687391 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader_test.go @@ -10,8 +10,9 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func Test_parseLogs(t *testing.T) { @@ -27,7 +28,7 @@ func Test_parseLogs(t *testing.T) { return &log.Index, nil } - parsedEvents, err := ParseLogs[uint](logs, logger.TestLogger(t), parseFn) + parsedEvents, err := ParseLogs[uint](logs, logger.Test(t), parseFn) require.NoError(t, err) assert.Len(t, parsedEvents, 100) @@ -55,7 +56,7 @@ func Test_parseLogs_withErrors(t *testing.T) { return &log.Index, nil } - log, observed := logger.TestLoggerObserved(t, zapcore.DebugLevel) + log, observed := logger.TestObserved(t, zapcore.DebugLevel) parsedEvents, err := ParseLogs[uint](logs, log, parseFn) assert.ErrorContains(t, err, fmt.Sprintf("%d logs were not parsed", len(logs)/2)) assert.Nil(t, parsedEvents, "No events are returned if there was an error.") diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go index 51ce0db7c0..cd8fd3150a 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go @@ -10,9 +10,10 @@ import ( "github.com/patrickmn/go-cache" "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_internal_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_internal_test.go index a5f0a1ffd0..953da52713 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_internal_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_internal_test.go @@ -14,6 +14,8 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -21,7 +23,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestLogPollerClient_GetUSDCMessagePriorToLogIndexInTx(t *testing.T) { @@ -31,7 +32,7 @@ func TestLogPollerClient_GetUSDCMessagePriorToLogIndexInTx(t *testing.T) { expectedData := "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000" expectedPostParse := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" - lggr := logger.TestLogger(t) + lggr := logger.Test(t) t.Run("multiple found - selected last", func(t *testing.T) { lp := lpmocks.NewLogPoller(t) @@ -136,7 +137,7 @@ func TestParse(t *testing.T) { func TestFilters(t *testing.T) { t.Run("filters of different jobs should be distinct", func(t *testing.T) { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) chainID := testutils.NewRandomEVMChainID() db := pgtest.NewSqlxDB(t) o := logpoller.NewORM(chainID, db, lggr) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go index 3e58143a28..d0559b800e 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go @@ -14,6 +14,7 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" @@ -23,7 +24,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_0_0" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store_test.go index 31bcaf8a18..b10e3ec889 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store_test.go @@ -8,12 +8,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestCommitReportEncoding(t *testing.T) { @@ -35,7 +35,7 @@ func TestCommitReportEncoding(t *testing.T) { Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}, } - c, err := NewCommitStore(logger.TestLogger(t), utils.RandomAddress(), nil, mocks.NewLogPoller(t)) + c, err := NewCommitStore(logger.Test(t), utils.RandomAddress(), nil, mocks.NewLogPoller(t)) assert.NoError(t, err) encodedReport, err := c.EncodeCommitReport(ctx, report) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp.go index 137cbaf451..c8b7c504ff 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp.go @@ -7,8 +7,6 @@ import ( "sync" "time" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" - mapset "github.com/deckarep/golang-set/v2" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -17,23 +15,22 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-common/pkg/config" - + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" ) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_test.go index d834b792ce..67d40df2bf 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_test.go @@ -6,11 +6,12 @@ import ( "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" ) @@ -25,7 +26,7 @@ func TestExecutionReportEncodingV100(t *testing.T) { ProofFlagBits: big.NewInt(133), } - offRamp, err := v1_0_0.NewOffRamp(logger.TestLogger(t), utils.RandomAddress(), nil, lpmocks.NewLogPoller(t), nil, nil) + offRamp, err := v1_0_0.NewOffRamp(logger.Test(t), utils.RandomAddress(), nil, lpmocks.NewLogPoller(t), nil, nil) require.NoError(t, err) ctx := testutils.Context(t) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_unit_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_unit_test.go index f8b1dc4e61..f1cd2a4f84 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_unit_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_reader_unit_test.go @@ -6,14 +6,12 @@ import ( "slices" "testing" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib/rpclibmocks" - "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" @@ -24,9 +22,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0" mock_contracts "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/mocks/v1_0_0" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib/rpclibmocks" ) func TestOffRampGetDestinationTokensFromSourceTokens(t *testing.T) { @@ -115,7 +114,7 @@ func TestCachedOffRampTokens(t *testing.T) { offRamp := OffRamp{ offRampV100: mockOffRamp, lp: lp, - Logger: logger.TestLogger(t), + Logger: logger.Test(t), Client: evmclimocks.NewClient(t), evmBatchCaller: rpclibmocks.NewEvmBatchCaller(t), cachedOffRampTokens: cache.NewLogpollerEventsBased[cciptypes.OffRampTokens]( @@ -196,7 +195,7 @@ func Test_LogsAreProperlyMarkedAsFinalized(t *testing.T) { lp.On("IndexedLogsTopicRange", mock.Anything, ExecutionStateChangedEvent, offrampAddress, 1, logpoller.EvmWord(minSeqNr), logpoller.EvmWord(maxSeqNr), evmtypes.Confirmations(0)). Return(inputLogs, nil) - offRamp, err := NewOffRamp(logger.TestLogger(t), offrampAddress, evmclimocks.NewClient(t), lp, nil, nil) + offRamp, err := NewOffRamp(logger.Test(t), offrampAddress, evmclimocks.NewClient(t), lp, nil, nil) require.NoError(t, err) logs, err := offRamp.GetExecutionStateChangesBetweenSeqNums(testutils.Context(t), minSeqNr, maxSeqNr, 0) require.NoError(t, err) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_test.go index 44fb6ca063..234490a72c 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/offramp_test.go @@ -5,20 +5,19 @@ import ( "testing" "time" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib/rpclibmocks" - "github.com/pkg/errors" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib/rpclibmocks" ) func TestExecOffchainConfig100_Encoding(t *testing.T) { @@ -218,7 +217,7 @@ func Test_GetSendersNonce(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - offramp := OffRamp{evmBatchCaller: test.batchCaller, Logger: logger.TestLogger(t)} + offramp := OffRamp{evmBatchCaller: test.batchCaller, Logger: logger.Test(t)} nonce, err := offramp.ListSenderNonces(testutils.Context(t), test.addresses) if test.expectedError { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go index 29cb357223..969b1fa48f 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go @@ -10,12 +10,13 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/price_registry.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/price_registry.go index d2104f985b..2ed9015a98 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/price_registry.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/price_registry.go @@ -7,12 +7,11 @@ import ( "sync" "time" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" @@ -20,12 +19,12 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_0_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/erc20" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/rpclib" ) var ( diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_1_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_1_0/onramp.go index d4d73219fc..52d7985f7e 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_1_0/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_1_0/onramp.go @@ -6,12 +6,12 @@ import ( "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_1_0" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" ) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go index 7612e54419..2b87a7913a 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go @@ -14,6 +14,7 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" @@ -23,7 +24,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go index 8b29309633..e0771f33cb 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store_test.go @@ -10,13 +10,12 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/config" - + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" ) @@ -48,7 +47,7 @@ func TestCommitReportEncoding(t *testing.T) { Interval: cciptypes.CommitStoreInterval{Min: 1, Max: 10}, } - c, err := NewCommitStore(logger.TestLogger(t), utils.RandomAddress(), nil, mocks.NewLogPoller(t)) + c, err := NewCommitStore(logger.Test(t), utils.RandomAddress(), nil, mocks.NewLogPoller(t)) assert.NoError(t, err) encodedReport, err := c.EncodeCommitReport(ctx, report) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp.go index fa00894b38..1f40439743 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp.go @@ -12,7 +12,7 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-common/pkg/config" - + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" @@ -20,7 +20,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_test.go index f87fc8842f..630b92f67f 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/offramp_reader_test.go @@ -6,11 +6,12 @@ import ( "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" ) @@ -25,7 +26,7 @@ func TestExecutionReportEncodingV120(t *testing.T) { ProofFlagBits: big.NewInt(133), } - offRamp, err := v1_2_0.NewOffRamp(logger.TestLogger(t), utils.RandomAddress(), nil, lpmocks.NewLogPoller(t), nil, nil) + offRamp, err := v1_2_0.NewOffRamp(logger.Test(t), utils.RandomAddress(), nil, lpmocks.NewLogPoller(t), nil, nil) require.NoError(t, err) ctx := testutils.Context(t) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go index f727d7fd5f..9579286470 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go @@ -11,12 +11,13 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp_test.go index ec912667ac..bbdf52e23a 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp_test.go @@ -8,11 +8,12 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ) @@ -20,7 +21,7 @@ func TestLogPollerClient_GetSendRequestsBetweenSeqNumsV1_2_0(t *testing.T) { onRampAddr := utils.RandomAddress() seqNum := uint64(100) limit := uint64(10) - lggr := logger.TestLogger(t) + lggr := logger.Test(t) tests := []struct { name string diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/price_registry.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/price_registry.go index 9aac30e612..df95823377 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/price_registry.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/price_registry.go @@ -7,11 +7,12 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/commit_store.go index 3bb582f3a2..fd768d4235 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/commit_store.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/commit_store.go @@ -8,10 +8,10 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" ) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp.go index cac61c6787..2db9498de9 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp.go @@ -9,13 +9,13 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go index 481933f89a..d07fa7bb61 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go @@ -13,11 +13,11 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/hashutil" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go index 3ca360c8ff..f072fc2b38 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" @@ -19,7 +20,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" @@ -29,7 +29,7 @@ func TestLogPollerClient_GetSendRequestsBetweenSeqNums1_4_0(t *testing.T) { onRampAddr := utils.RandomAddress() seqNum := uint64(100) limit := uint64(10) - lggr := logger.TestLogger(t) + lggr := logger.Test(t) tests := []struct { name string @@ -72,7 +72,7 @@ func Test_ProperlyRecognizesPerLaneCurses(t *testing.T) { sourceChainSelector := uint64(200) onRampAddress, mockRMN, mockRMNAddress := setupOnRampV1_5_0(t, user, bc) - onRamp, err := NewOnRamp(logger.TestLogger(t), 1, destChainSelector, onRampAddress, mocks.NewLogPoller(t), bc) + onRamp, err := NewOnRamp(logger.Test(t), 1, destChainSelector, onRampAddress, mocks.NewLogPoller(t), bc) require.NoError(t, err) onRamp.cachedStaticConfig = func(ctx context.Context) (evm_2_evm_onramp.EVM2EVMOnRampStaticConfig, error) { @@ -121,7 +121,7 @@ func BenchmarkIsSourceCursedWithCache(b *testing.B) { destChainSelector := uint64(100) onRampAddress, _, _ := setupOnRampV1_5_0(b, user, bc) - onRamp, err := NewOnRamp(logger.TestLogger(b), 1, destChainSelector, onRampAddress, mocks.NewLogPoller(b), bc) + onRamp, err := NewOnRamp(logger.Test(b), 1, destChainSelector, onRampAddress, mocks.NewLogPoller(b), bc) require.NoError(b, err) for i := 0; i < b.N; i++ { diff --git a/core/services/ocr2/plugins/ccip/internal/rpclib/evm.go b/core/services/ocr2/plugins/ccip/internal/rpclib/evm.go index 71357029dd..6c4aabb435 100644 --- a/core/services/ocr2/plugins/ccip/internal/rpclib/evm.go +++ b/core/services/ocr2/plugins/ccip/internal/rpclib/evm.go @@ -13,7 +13,7 @@ import ( "github.com/pkg/errors" "golang.org/x/sync/errgroup" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink-common/pkg/logger" ) var ErrEmptyOutput = errors.New("rpc call output is empty (make sure that the contract method exists and rpc is healthy)") diff --git a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go index fe3a86d2af..aaa6086fbc 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go +++ b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go @@ -17,10 +17,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber.go index d07af8a8de..a5a0054217 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber.go @@ -9,14 +9,13 @@ import ( "github.com/ethereum/go-ethereum/common" - ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation" - + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" + ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation" httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -74,7 +73,7 @@ func NewBlockSubscriber(hb httypes.HeadBroadcaster, lp logpoller.LogPoller, fina blockSize: lookbackDepth, finalityDepth: finalityDepth, latestBlock: atomic.Pointer[ocr2keepers.BlockKey]{}, - lggr: lggr.Named("BlockSubscriber"), + lggr: logger.Named(lggr, "BlockSubscriber"), } } diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice.go index f84a48c1ff..34d7fb7945 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice.go @@ -6,10 +6,11 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/cbor" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" ) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer_v1.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer_v1.go index e58d5ad9c9..00a56496a0 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer_v1.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer_v1.go @@ -6,8 +6,9 @@ import ( "sync" "sync/atomic" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics" ) @@ -79,7 +80,7 @@ type logBuffer struct { func NewLogBuffer(lggr logger.Logger, lookback, blockRate, logLimit uint32) LogBuffer { return &logBuffer{ - lggr: lggr.Named("KeepersRegistry.LogEventBufferV1"), + lggr: logger.Sugared(lggr).Named("KeepersRegistry").Named("LogEventBufferV1"), opts: newLogBufferOptions(lookback, blockRate, logLimit), lastBlockSeen: new(atomic.Int64), queueIDs: []string{}, @@ -313,7 +314,7 @@ type upkeepLogQueue struct { func newUpkeepLogQueue(lggr logger.Logger, id *big.Int, opts *logBufferOptions) *upkeepLogQueue { return &upkeepLogQueue{ - lggr: lggr.With("upkeepID", id.String()), + lggr: logger.With(lggr, "upkeepID", id.String()), id: id, opts: opts, logs: map[int64][]logpoller.Log{}, diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer_v1_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer_v1_test.go index f742d39689..4c46b9b3fe 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer_v1_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/buffer_v1_test.go @@ -54,8 +54,6 @@ func TestLogEventBufferV1_SyncFilters(t *testing.T) { type readableLogger struct { logger.Logger DebugwFn func(msg string, keysAndValues ...interface{}) - NamedFn func(name string) logger.Logger - WithFn func(args ...interface{}) logger.Logger } func (l *readableLogger) Debugw(msg string, keysAndValues ...interface{}) { @@ -74,6 +72,7 @@ func TestLogEventBufferV1_EnqueueViolations(t *testing.T) { t.Run("enqueuing logs for a block older than latest seen logs a message", func(t *testing.T) { logReceived := false readableLogger := &readableLogger{ + Logger: logger.TestLogger(t), DebugwFn: func(msg string, keysAndValues ...interface{}) { if msg == "enqueuing logs from a block older than latest seen block" { logReceived = true @@ -103,6 +102,7 @@ func TestLogEventBufferV1_EnqueueViolations(t *testing.T) { t.Run("enqueuing logs for the same block over multiple calls logs a message", func(t *testing.T) { logReceived := false readableLogger := &readableLogger{ + Logger: logger.TestLogger(t), DebugwFn: func(msg string, keysAndValues ...interface{}) { if msg == "enqueuing logs again for a previously seen block" { logReceived = true diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/factory.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/factory.go index 25cc5e939b..57b48841a2 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/factory.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/factory.go @@ -4,9 +4,10 @@ import ( "math/big" "time" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" ) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go index f1de1ef512..50b2ebc0d0 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go @@ -16,13 +16,12 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation" - + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" + ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" ac "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_compatible_utils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -111,7 +110,7 @@ type logEventProvider struct { func NewLogProvider(lggr logger.Logger, poller logpoller.LogPoller, chainID *big.Int, packer LogDataPacker, filterStore UpkeepFilterStore, opts LogTriggersOptions) *logEventProvider { return &logEventProvider{ threadCtrl: utils.NewThreadControl(), - lggr: lggr.Named("KeepersRegistry.LogEventProvider"), + lggr: logger.Named(lggr, "KeepersRegistry.LogEventProvider"), packer: packer, buffer: NewLogBuffer(lggr, uint32(opts.LookbackBlocks), opts.BlockRate, opts.LogLimit), poller: poller, @@ -135,7 +134,7 @@ func (p *logEventProvider) SetConfig(cfg ocr2keepers.LogEventProviderConfig) { logLimit = p.opts.defaultLogLimit() } - p.lggr.With("where", "setConfig").Infow("setting config ", "bockRate", blockRate, "logLimit", logLimit) + p.lggr.Infow("setting config", "where", "setConfig", "bockRate", blockRate, "logLimit", logLimit) atomic.StoreUint32(&p.opts.BlockRate, blockRate) atomic.StoreUint32(&p.opts.LogLimit, logLimit) @@ -156,7 +155,7 @@ func (p *logEventProvider) Start(context.Context) error { } p.threadCtrl.Go(func(ctx context.Context) { - lggr := p.lggr.With("where", "scheduler") + lggr := logger.With(p.lggr, "where", "scheduler") p.scheduleReadJobs(ctx, func(ids []*big.Int) { select { @@ -369,7 +368,7 @@ func (p *logEventProvider) startReader(pctx context.Context, readQ <-chan []*big ctx, cancel := context.WithCancel(pctx) defer cancel() - lggr := p.lggr.With("where", "reader") + lggr := logger.With(p.lggr, "where", "reader") for { select { diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider_life_cycle.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider_life_cycle.go index db47ac2ecd..cbd493bf2e 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider_life_cycle.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider_life_cycle.go @@ -10,6 +10,8 @@ import ( "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" ) @@ -106,7 +108,7 @@ func (p *logEventProvider) register(ctx context.Context, lpFilter logpoller.Filt if err != nil { return fmt.Errorf("failed to get latest block while registering filter: %w", err) } - lggr := p.lggr.With("upkeepID", ufilter.upkeepID.String()) + lggr := logger.With(p.lggr, "upkeepID", ufilter.upkeepID.String()) logPollerHasFilter := p.poller.HasFilter(lpFilter.Name) filterStoreHasFilter := p.filterStore.Has(ufilter.upkeepID) if filterStoreHasFilter { diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer.go index 9e41008ed8..984856bf3c 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer.go @@ -14,18 +14,17 @@ import ( "sync/atomic" "time" - "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" - "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/chainlink-automation/pkg/v3/random" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation" - "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-automation/pkg/v3/random" + "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -71,7 +70,7 @@ type logRecoverer struct { services.StateMachine threadCtrl utils.ThreadControl - lggr logger.Logger + lggr logger.SugaredLogger lookbackBlocks *atomic.Int64 blockTime *atomic.Int64 @@ -96,7 +95,7 @@ var _ LogRecoverer = &logRecoverer{} func NewLogRecoverer(lggr logger.Logger, poller logpoller.LogPoller, client client.Client, stateStore core.UpkeepStateReader, packer LogDataPacker, filterStore UpkeepFilterStore, opts LogTriggersOptions) *logRecoverer { rec := &logRecoverer{ - lggr: lggr.Named(LogRecovererServiceName), + lggr: logger.Sugared(lggr).Named(LogRecovererServiceName), threadCtrl: utils.NewThreadControl(), diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams.go index 5a4b701f61..1700593921 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams.go @@ -15,11 +15,11 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/patrickmn/go-cache" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation" autov2common "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_v21_plus_common" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury" @@ -119,7 +119,7 @@ func (s *streams) Lookup(ctx context.Context, checkResults []ocr2keepers.CheckRe // buildResult checks if the upkeep is allowed by Mercury and builds a streams lookup request from the check result func (s *streams) buildResult(ctx context.Context, i int, checkResult ocr2keepers.CheckResult, checkResults []ocr2keepers.CheckResult, lookups map[int]*mercury.StreamsLookup) { - lookupLggr := s.lggr.With("where", "StreamsLookup") + lookupLggr := logger.Sugared(s.lggr).With("where", "StreamsLookup") if checkResult.IneligibilityReason != uint8(encoding.UpkeepFailureReasonTargetCheckReverted) { // Streams Lookup only works when upkeep target check reverts prommetrics.AutomationStreamsLookupError.WithLabelValues(prommetrics.StreamsLookupErrorReasonNotReverted).Inc() diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v02/request.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v02/request.go index 5e954475a8..c02b7c10de 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v02/request.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v02/request.go @@ -11,14 +11,14 @@ import ( "strconv" "time" - automationTypes "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" + "github.com/avast/retry-go/v4" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" - "github.com/avast/retry-go/v4" - "github.com/ethereum/go-ethereum/common/hexutil" + automationTypes "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics" diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v03/request.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v03/request.go index 39a26b6b5d..c2ffb2172b 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v03/request.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v03/request.go @@ -10,14 +10,14 @@ import ( "strings" "time" - automationTypes "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" + "github.com/avast/retry-go/v4" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" - "github.com/avast/retry-go/v4" - "github.com/ethereum/go-ethereum/common/hexutil" + automationTypes "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/prommetrics" diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/payload_builder.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/payload_builder.go index 7f29cb3b7a..c6262899a3 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/payload_builder.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/payload_builder.go @@ -3,11 +3,11 @@ package evm import ( "context" - "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" - + "github.com/smartcontractkit/chainlink-common/pkg/logger" ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider" ) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry.go index 16b8627cf7..25bd7a445e 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry.go @@ -10,10 +10,6 @@ import ( "sync" "time" - types2 "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" - - "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -22,19 +18,20 @@ import ( "github.com/pkg/errors" "go.uber.org/multierr" - evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" - + "github.com/smartcontractkit/chainlink-common/pkg/types" ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation" + types2 "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" ac "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_v21_plus_common" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider" @@ -98,7 +95,7 @@ func NewEvmRegistry( return &EvmRegistry{ stopCh: make(chan struct{}), threadCtrl: utils.NewThreadControl(), - lggr: lggr.Named(RegistryServiceName), + lggr: logger.Sugared(lggr).Named(RegistryServiceName), poller: client.LogPoller(), addr: addr, client: client.Client(), @@ -175,7 +172,7 @@ func (c *MercuryConfig) SetPluginRetry(k string, v interface{}, d time.Duration) type EvmRegistry struct { services.StateMachine threadCtrl utils.ThreadControl - lggr logger.Logger + lggr logger.SugaredLogger poller logpoller.LogPoller addr common.Address client client.Client diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_check_pipeline_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_check_pipeline_test.go index 6f8785fda7..cb014e1d3e 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_check_pipeline_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_check_pipeline_test.go @@ -8,10 +8,6 @@ import ( "sync/atomic" "testing" - types3 "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" - - types2 "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rpc" @@ -20,8 +16,12 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + types2 "github.com/smartcontractkit/chainlink-common/pkg/types" ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation" + types3 "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" + evmClientMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" gasMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -30,7 +30,6 @@ import ( ac "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_v21_plus_common" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/streams_lookup_compatible_interface" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mocks" @@ -82,7 +81,7 @@ func TestRegistry_GetBlockAndUpkeepId(t *testing.T) { } func TestRegistry_VerifyCheckBlock(t *testing.T) { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) upkeepId := ocr2keepers.UpkeepIdentifier{} upkeepId.FromBigInt(big.NewInt(12345)) tests := []struct { @@ -197,7 +196,7 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { } bs.latestBlock.Store(tc.latestBlock) e := &EvmRegistry{ - lggr: lggr, + lggr: logger.Sugared(lggr), bs: bs, poller: tc.poller, } @@ -229,7 +228,7 @@ func (p *mockLogPoller) IndexedLogs(ctx context.Context, eventSig common.Hash, a } func TestRegistry_VerifyLogExists(t *testing.T) { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) upkeepId := ocr2keepers.UpkeepIdentifier{} upkeepId.FromBigInt(big.NewInt(12345)) @@ -351,7 +350,7 @@ func TestRegistry_VerifyLogExists(t *testing.T) { blocks: tc.blocks, } e := &EvmRegistry{ - lggr: lggr, + lggr: logger.Sugared(lggr), bs: bs, } @@ -379,7 +378,7 @@ func TestRegistry_VerifyLogExists(t *testing.T) { } func TestRegistry_CheckUpkeeps(t *testing.T) { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) uid0 := core.GenUpkeepID(types3.UpkeepType(0), "p0") uid1 := core.GenUpkeepID(types3.UpkeepType(1), "p1") uid2 := core.GenUpkeepID(types3.UpkeepType(1), "p2") @@ -509,7 +508,7 @@ func TestRegistry_CheckUpkeeps(t *testing.T) { } bs.latestBlock.Store(tc.latestBlock) e := &EvmRegistry{ - lggr: lggr, + lggr: logger.Sugared(lggr), bs: bs, poller: tc.poller, } @@ -669,7 +668,7 @@ func TestRegistry_SimulatePerformUpkeeps(t *testing.T) { // setups up an evm registry for tests. func setupEVMRegistry(t *testing.T) *EvmRegistry { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) addr := common.HexToAddress("0x6cA639822c6C241Fa9A7A6b5032F6F7F1C513CAD") keeperRegistryABI, err := abi.JSON(strings.NewReader(ac.IAutomationV21PlusCommonABI)) require.Nil(t, err, "need registry abi") @@ -682,7 +681,7 @@ func setupEVMRegistry(t *testing.T) *EvmRegistry { ge := gasMocks.NewEvmFeeEstimator(t) r := &EvmRegistry{ - lggr: lggr, + lggr: logger.Sugared(lggr), poller: logPoller, addr: addr, client: client, diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_test.go index ab530f877a..1a3f103dd1 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_test.go @@ -15,19 +15,19 @@ import ( "github.com/stretchr/testify/mock" types2 "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" types3 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" ac "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_compatible_utils" autov2common "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_v21_plus_common" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider" @@ -546,7 +546,7 @@ func TestRegistry_refreshLogTriggerUpkeeps(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { ctx := tests.Context(t) - lggr := logger.TestLogger(t) + lggr := logger.Test(t) var hb types3.HeadBroadcaster var lp logpoller.LogPoller @@ -560,7 +560,7 @@ func TestRegistry_refreshLogTriggerUpkeeps(t *testing.T) { bs: bs, registry: tc.registry, packer: tc.packer, - lggr: lggr, + lggr: logger.Sugared(lggr), } err := registry.refreshLogTriggerUpkeeps(ctx, tc.ids) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/transmit/event_provider.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/transmit/event_provider.go index f1a6468804..697f56c866 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/transmit/event_provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/transmit/event_provider.go @@ -6,18 +6,17 @@ import ( "fmt" "sync" - "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" - "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation" - "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-automation/pkg/v3/types" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" ac "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_v21_plus_common" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" ) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/scanner.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/scanner.go index d11970864a..27a35ddff1 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/scanner.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/scanner.go @@ -8,10 +8,11 @@ import ( "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ac "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_v21_plus_common" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider" ) @@ -43,7 +44,7 @@ func NewPerformedEventsScanner( finalityDepth uint32, ) *performedEventsScanner { return &performedEventsScanner{ - lggr: lggr.Named("EventsScanner"), + lggr: logger.Named(lggr, "EventsScanner"), poller: poller, registryAddress: registryAddress, finalityDepth: finalityDepth, diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/store.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/store.go index e6486ca56a..27cac24a9f 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/store.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/store.go @@ -8,13 +8,12 @@ import ( "sync" "time" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation" - "github.com/smartcontractkit/chainlink-common/pkg/services" - ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -84,7 +83,7 @@ type upkeepStateStore struct { func NewUpkeepStateStore(orm ORM, lggr logger.Logger, scanner PerformedLogsScanner) *upkeepStateStore { return &upkeepStateStore{ orm: orm, - lggr: lggr.Named(UpkeepStateStoreServiceName), + lggr: logger.Named(lggr, UpkeepStateStoreServiceName), cache: map[string]*upkeepStateRecord{}, scanner: scanner, retention: CacheExpiration, diff --git a/core/services/ocrcommon/arbitrum_block_translator.go b/core/services/ocrcommon/arbitrum_block_translator.go index 1b7c371238..9179fe3227 100644 --- a/core/services/ocrcommon/arbitrum_block_translator.go +++ b/core/services/ocrcommon/arbitrum_block_translator.go @@ -10,9 +10,10 @@ import ( "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -33,7 +34,7 @@ type ArbitrumBlockTranslator struct { func NewArbitrumBlockTranslator(ethClient evmclient.Client, lggr logger.Logger) *ArbitrumBlockTranslator { return &ArbitrumBlockTranslator{ ethClient, - lggr.Named("ArbitrumBlockTranslator"), + logger.Named(lggr, "ArbitrumBlockTranslator"), make(map[int64]int64), sync.RWMutex{}, utils.KeyedMutex{}, diff --git a/core/services/ocrcommon/block_translator.go b/core/services/ocrcommon/block_translator.go index d7ceffc5ea..fa44d79c2d 100644 --- a/core/services/ocrcommon/block_translator.go +++ b/core/services/ocrcommon/block_translator.go @@ -4,10 +4,11 @@ import ( "context" "math/big" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) // BlockTranslator converts emitted block numbers (from block.number) into a diff --git a/core/services/relay/evm/batch_caller.go b/core/services/relay/evm/batch_caller.go index 3ee4525827..53edc49eaa 100644 --- a/core/services/relay/evm/batch_caller.go +++ b/core/services/relay/evm/batch_caller.go @@ -11,9 +11,10 @@ import ( "github.com/pkg/errors" "golang.org/x/sync/errgroup" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) var errEmptyOutput = errors.New("rpc call output is empty (make sure that the contract method exists and rpc is healthy)") diff --git a/core/services/relay/evm/ccip.go b/core/services/relay/evm/ccip.go index 34a732e145..3eefb7bec7 100644 --- a/core/services/relay/evm/ccip.go +++ b/core/services/relay/evm/ccip.go @@ -6,18 +6,16 @@ import ( "math/big" "time" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" - - cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" ) var _ cciptypes.CommitStoreReader = (*IncompleteSourceCommitStoreReader)(nil) diff --git a/core/services/relay/evm/chain_reader.go b/core/services/relay/evm/chain_reader.go index 205fcbbcf0..0f1f6e72dd 100644 --- a/core/services/relay/evm/chain_reader.go +++ b/core/services/relay/evm/chain_reader.go @@ -13,6 +13,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/smartcontractkit/chainlink-common/pkg/codec" + "github.com/smartcontractkit/chainlink-common/pkg/logger" commonservices "github.com/smartcontractkit/chainlink-common/pkg/services" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query" @@ -21,7 +22,6 @@ import ( evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -49,7 +49,7 @@ var _ commontypes.ContractTypeProvider = &chainReader{} // Note that the ChainReaderService returned does not support anonymous events. func NewChainReaderService(ctx context.Context, lggr logger.Logger, lp logpoller.LogPoller, ht logpoller.HeadTracker, client evmclient.Client, config types.ChainReaderConfig) (ChainReaderService, error) { cr := &chainReader{ - lggr: lggr.Named("ChainReader"), + lggr: logger.Named(lggr, "ChainReader"), ht: ht, lp: lp, client: client, diff --git a/core/services/relay/evm/chain_writer.go b/core/services/relay/evm/chain_writer.go index f188ffeced..895d276e6b 100644 --- a/core/services/relay/evm/chain_writer.go +++ b/core/services/relay/evm/chain_writer.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-common/pkg/logger" commonservices "github.com/smartcontractkit/chainlink-common/pkg/services" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" @@ -18,7 +19,6 @@ import ( evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" evmtxmgr "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) diff --git a/core/services/relay/evm/commit_provider.go b/core/services/relay/evm/commit_provider.go index fe3e327c7f..f41df16a4f 100644 --- a/core/services/relay/evm/commit_provider.go +++ b/core/services/relay/evm/commit_provider.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" @@ -17,7 +18,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" ) diff --git a/core/services/relay/evm/config_poller.go b/core/services/relay/evm/config_poller.go index 2280d60d7e..a00b04b078 100644 --- a/core/services/relay/evm/config_poller.go +++ b/core/services/relay/evm/config_poller.go @@ -15,11 +15,11 @@ import ( "github.com/smartcontractkit/libocr/gethwrappers2/ocrconfigurationstoreevmsimple" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/logger" evmRelayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) diff --git a/core/services/relay/evm/contract_transmitter.go b/core/services/relay/evm/contract_transmitter.go index d594dfb921..e2065bc60f 100644 --- a/core/services/relay/evm/contract_transmitter.go +++ b/core/services/relay/evm/contract_transmitter.go @@ -12,13 +12,15 @@ import ( "github.com/ethereum/go-ethereum/common" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" ) @@ -102,7 +104,7 @@ func NewOCRContractTransmitter( transmittedEventSig: transmitted.ID, lp: lp, contractReader: caller, - lggr: lggr.Named("OCRContractTransmitter"), + lggr: logger.Named(lggr, "OCRContractTransmitter"), reportToEvmTxMeta: reportToEvmTxMetaNoop, excludeSigs: false, retention: 0, diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index e310464a55..9596ab29d0 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -9,15 +9,6 @@ import ( "fmt" "math/big" "strings" - "sync" - - cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/ccipcommit" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/ccipexec" - ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" - cciptransmitter "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/transmitter" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -32,20 +23,25 @@ import ( ocr3capability "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/triggers" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core" - reportcodecv4 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v4/reportcodec" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" txm "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/llo" "github.com/smartcontractkit/chainlink/v2/core/services/llo/bm" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/ccipcommit" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/ccipexec" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + cciptransmitter "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/transmitter" lloconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/llo/config" mercuryconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" @@ -55,6 +51,7 @@ import ( reportcodecv1 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1/reportcodec" reportcodecv2 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/reportcodec" reportcodecv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" + reportcodecv4 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v4/reportcodec" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -137,7 +134,7 @@ func (u UnimplementedContractTransmitter) LatestConfigDigestAndEpoch(ctx context type Relayer struct { ds sqlutil.DataSource chain legacyevm.Chain - lggr logger.Logger + lggr logger.SugaredLogger ks CSAETHKeystore mercuryPool wsrpc.Pool chainReader commontypes.ContractReader @@ -189,15 +186,15 @@ func NewRelayer(lggr logger.Logger, chain legacyevm.Chain, opts RelayerOpts) (*R if err != nil { return nil, fmt.Errorf("cannot create evm relayer: %w", err) } - lggr = lggr.Named("Relayer") + sugared := logger.Sugared(lggr).Named("Relayer") mercuryORM := mercury.NewORM(opts.DS) lloORM := llo.NewORM(opts.DS, chain.ID()) - cdcFactory := llo.NewChannelDefinitionCacheFactory(lggr, lloORM, chain.LogPoller()) + cdcFactory := llo.NewChannelDefinitionCacheFactory(sugared, lloORM, chain.LogPoller()) relayer := &Relayer{ ds: opts.DS, chain: chain, - lggr: lggr, + lggr: sugared, ks: opts.CSAETHKeystore, mercuryPool: opts.MercuryPool, cdcFactory: cdcFactory, @@ -271,7 +268,7 @@ func (r *Relayer) NewPluginProvider(rargs commontypes.RelayArgs, pargs commontyp // TODO https://smartcontract-it.atlassian.net/browse/BCF-2887 ctx := context.Background() - lggr := r.lggr.Named("PluginProvider").Named(rargs.ExternalJobID.String()) + lggr := logger.Sugared(r.lggr).Named("PluginProvider").Named(rargs.ExternalJobID.String()) configWatcher, err := newStandardConfigProvider(ctx, r.lggr, r.chain, types.NewRelayOpts(rargs)) if err != nil { @@ -295,7 +292,7 @@ func (r *Relayer) NewPluginProvider(rargs commontypes.RelayArgs, pargs commontyp func (r *Relayer) NewMercuryProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.MercuryProvider, error) { // TODO https://smartcontract-it.atlassian.net/browse/BCF-2887 ctx := context.Background() - lggr := r.lggr.Named("MercuryProvider").Named(rargs.ExternalJobID.String()) + lggr := logger.Sugared(r.lggr).Named("MercuryProvider").Named(rargs.ExternalJobID.String()) relayOpts := types.NewRelayOpts(rargs) relayConfig, err := relayOpts.RelayConfig() if err != nil { @@ -511,16 +508,15 @@ func FilterNamesFromRelayArgs(args commontypes.RelayArgs) (filterNames []string, } type configWatcher struct { - services.StateMachine - lggr logger.Logger + services.Service + eng *services.Engine + contractAddress common.Address offchainDigester ocrtypes.OffchainConfigDigester configPoller types.ConfigPoller chain legacyevm.Chain runReplay bool fromBlock uint64 - stopCh services.StopChan - wg sync.WaitGroup } func newConfigWatcher(lggr logger.Logger, @@ -531,54 +527,41 @@ func newConfigWatcher(lggr logger.Logger, fromBlock uint64, runReplay bool, ) *configWatcher { - return &configWatcher{ - lggr: lggr.Named("ConfigWatcher").Named(contractAddress.String()), + cw := &configWatcher{ contractAddress: contractAddress, offchainDigester: offchainDigester, configPoller: configPoller, chain: chain, runReplay: runReplay, fromBlock: fromBlock, - stopCh: make(chan struct{}), } + cw.Service, cw.eng = services.Config{ + Name: fmt.Sprintf("ConfigWatcher.%s", contractAddress), + NewSubServices: nil, + Start: cw.start, + Close: cw.close, + }.NewServiceEngine(lggr) + return cw +} + +func (c *configWatcher) start(ctx context.Context) error { + if c.runReplay && c.fromBlock != 0 { + // Only replay if it's a brand runReplay job. + c.eng.Go(func(ctx context.Context) { + c.eng.Infow("starting replay for config", "fromBlock", c.fromBlock) + if err := c.configPoller.Replay(ctx, int64(c.fromBlock)); err != nil { + c.eng.Errorw("error replaying for config", "err", err) + } else { + c.eng.Infow("completed replaying for config", "fromBlock", c.fromBlock) + } + }) + } + c.configPoller.Start() + return nil } -func (c *configWatcher) Name() string { - return c.lggr.Name() -} - -func (c *configWatcher) Start(ctx context.Context) error { - return c.StartOnce(fmt.Sprintf("configWatcher %x", c.contractAddress), func() error { - if c.runReplay && c.fromBlock != 0 { - // Only replay if it's a brand runReplay job. - c.wg.Add(1) - go func() { - defer c.wg.Done() - ctx, cancel := c.stopCh.NewCtx() - defer cancel() - c.lggr.Infow("starting replay for config", "fromBlock", c.fromBlock) - if err := c.configPoller.Replay(ctx, int64(c.fromBlock)); err != nil { - c.lggr.Errorw("error replaying for config", "err", err) - } else { - c.lggr.Infow("completed replaying for config", "fromBlock", c.fromBlock) - } - }() - } - c.configPoller.Start() - return nil - }) -} - -func (c *configWatcher) Close() error { - return c.StopOnce(fmt.Sprintf("configWatcher %x", c.contractAddress), func() error { - close(c.stopCh) - c.wg.Wait() - return c.configPoller.Close() - }) -} - -func (c *configWatcher) HealthReport() map[string]error { - return map[string]error{c.Name(): c.Healthy()} +func (c *configWatcher) close() error { + return c.configPoller.Close() } func (c *configWatcher) OffchainConfigDigester() ocrtypes.OffchainConfigDigester { @@ -732,7 +715,7 @@ func (r *Relayer) NewMedianProvider(rargs commontypes.RelayArgs, pargs commontyp // TODO https://smartcontract-it.atlassian.net/browse/BCF-2887 ctx := context.Background() - lggr := r.lggr.Named("MedianProvider").Named(rargs.ExternalJobID.String()) + lggr := logger.Sugared(r.lggr).Named("MedianProvider").Named(rargs.ExternalJobID.String()) relayOpts := types.NewRelayOpts(rargs) relayConfig, err := relayOpts.RelayConfig() if err != nil { @@ -801,7 +784,7 @@ func (r *Relayer) NewMedianProvider(rargs commontypes.RelayArgs, pargs commontyp } func (r *Relayer) NewAutomationProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.AutomationProvider, error) { - lggr := r.lggr.Named("AutomationProvider").Named(rargs.ExternalJobID.String()) + lggr := logger.Sugared(r.lggr).Named("AutomationProvider").Named(rargs.ExternalJobID.String()) ocr2keeperRelayer := NewOCR2KeeperRelayer(r.ds, r.chain, lggr.Named("OCR2KeeperRelayer"), r.ks.Eth()) return ocr2keeperRelayer.NewOCR2KeeperProvider(rargs, pargs) diff --git a/core/services/relay/evm/exec_provider.go b/core/services/relay/evm/exec_provider.go index ae3ce56532..db10f31f35 100644 --- a/core/services/relay/evm/exec_provider.go +++ b/core/services/relay/evm/exec_provider.go @@ -13,6 +13,7 @@ import ( "github.com/ethereum/go-ethereum/common" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/types" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" @@ -22,7 +23,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata/usdc" ) diff --git a/core/services/relay/evm/functions.go b/core/services/relay/evm/functions.go index a04a991e37..1f1554eb11 100644 --- a/core/services/relay/evm/functions.go +++ b/core/services/relay/evm/functions.go @@ -8,17 +8,15 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - "go.uber.org/multierr" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" txm "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config" functionsRelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/functions" @@ -26,12 +24,29 @@ import ( ) type functionsProvider struct { - services.StateMachine + services.Service + eng *services.Engine + configWatcher *configWatcher contractTransmitter ContractTransmitter logPollerWrapper evmRelayTypes.LogPollerWrapper } +func newFunctionsProvider(lggr logger.Logger, cw *configWatcher, ct ContractTransmitter, lpw evmRelayTypes.LogPollerWrapper) *functionsProvider { + p := &functionsProvider{ + configWatcher: cw, + contractTransmitter: ct, + logPollerWrapper: lpw, + } + p.Service, p.eng = services.Config{ + Name: "FunctionsProvider", + NewSubServices: func(lggr logger.Logger) []services.Service { + return []services.Service{p.configWatcher, p.logPollerWrapper} + }, + }.NewServiceEngine(lggr) + return p +} + var _ evmRelayTypes.FunctionsProvider = (*functionsProvider)(nil) func (p *functionsProvider) ContractTransmitter() ocrtypes.ContractTransmitter { @@ -47,23 +62,6 @@ func (p *functionsProvider) FunctionsEvents() commontypes.FunctionsEvents { return nil } -func (p *functionsProvider) Start(ctx context.Context) error { - return p.StartOnce("FunctionsProvider", func() error { - if err := p.configWatcher.Start(ctx); err != nil { - return err - } - return p.logPollerWrapper.Start(ctx) - }) -} - -func (p *functionsProvider) Close() error { - return p.StopOnce("FunctionsProvider", func() (err error) { - err = multierr.Combine(err, p.logPollerWrapper.Close()) - err = multierr.Combine(err, p.configWatcher.Close()) - return - }) -} - // Forward all calls to the underlying configWatcher func (p *functionsProvider) OffchainConfigDigester() ocrtypes.OffchainConfigDigester { return p.configWatcher.OffchainConfigDigester() @@ -73,14 +71,6 @@ func (p *functionsProvider) ContractConfigTracker() ocrtypes.ContractConfigTrack return p.configWatcher.ContractConfigTracker() } -func (p *functionsProvider) HealthReport() map[string]error { - return p.configWatcher.HealthReport() -} - -func (p *functionsProvider) Name() string { - return p.configWatcher.Name() -} - func (p *functionsProvider) ChainReader() commontypes.ContractReader { return nil } @@ -127,11 +117,7 @@ func NewFunctionsProvider(ctx context.Context, chain legacyevm.Chain, rargs comm } else { lggr.Warn("no sending keys configured for functions plugin, not starting contract transmitter") } - return &functionsProvider{ - configWatcher: configWatcher, - contractTransmitter: contractTransmitter, - logPollerWrapper: logPollerWrapper, - }, nil + return newFunctionsProvider(lggr, configWatcher, contractTransmitter, logPollerWrapper), nil } func newFunctionsConfigProvider(ctx context.Context, pluginType functionsRelay.FunctionsPluginType, chain legacyevm.Chain, args commontypes.RelayArgs, fromBlock uint64, logPollerWrapper evmRelayTypes.LogPollerWrapper, lggr logger.Logger) (*configWatcher, error) { diff --git a/core/services/relay/evm/functions/config_poller.go b/core/services/relay/evm/functions/config_poller.go index 71616f2e84..2cb21738b9 100644 --- a/core/services/relay/evm/functions/config_poller.go +++ b/core/services/relay/evm/functions/config_poller.go @@ -9,12 +9,13 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" + "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) diff --git a/core/services/relay/evm/functions/contract_transmitter.go b/core/services/relay/evm/functions/contract_transmitter.go index 23143ed3ef..f588a02390 100644 --- a/core/services/relay/evm/functions/contract_transmitter.go +++ b/core/services/relay/evm/functions/contract_transmitter.go @@ -13,14 +13,16 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/encoding" evmRelayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" @@ -105,7 +107,7 @@ func NewFunctionsContractTransmitter( transmittedEventSig: transmitted.ID, lp: lp, contractReader: caller, - lggr: lggr.Named("OCRFunctionsContractTransmitter"), + lggr: logger.Named(lggr, "OCRFunctionsContractTransmitter"), contractVersion: contractVersion, reportCodec: codec, txm: txm, diff --git a/core/services/relay/evm/functions/logpoller_wrapper.go b/core/services/relay/evm/functions/logpoller_wrapper.go index b0d04b1187..260c366eb8 100644 --- a/core/services/relay/evm/functions/logpoller_wrapper.go +++ b/core/services/relay/evm/functions/logpoller_wrapper.go @@ -10,13 +10,13 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_coordinator" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config" evmRelayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) diff --git a/core/services/relay/evm/llo_config_provider.go b/core/services/relay/evm/llo_config_provider.go index 6efd0ccada..71b6a39be2 100644 --- a/core/services/relay/evm/llo_config_provider.go +++ b/core/services/relay/evm/llo_config_provider.go @@ -6,8 +6,9 @@ import ( "github.com/ethereum/go-ethereum/common" pkgerrors "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/llo" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) diff --git a/core/services/relay/evm/llo_provider.go b/core/services/relay/evm/llo_provider.go index b685565e6e..caedf0e771 100644 --- a/core/services/relay/evm/llo_provider.go +++ b/core/services/relay/evm/llo_provider.go @@ -6,12 +6,12 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" relaytypes "github.com/smartcontractkit/chainlink-common/pkg/types" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/llo" ) @@ -35,7 +35,7 @@ func NewLLOProvider( return &lloProvider{ cp, transmitter, - lggr.Named("LLOProvider"), + logger.Named(lggr, "LLOProvider"), channelDefinitionCache, services.MultiStart{}, } diff --git a/core/services/relay/evm/median.go b/core/services/relay/evm/median.go index 2407cff714..60a63994bd 100644 --- a/core/services/relay/evm/median.go +++ b/core/services/relay/evm/median.go @@ -8,16 +8,17 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" + "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" offchain_aggregator_wrapper "github.com/smartcontractkit/chainlink/v2/core/internal/gethwrappers2/generated/offchainaggregator" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) var _ median.MedianContract = &medianContract{} @@ -31,7 +32,7 @@ type medianContract struct { } func newMedianContract(configTracker types.ContractConfigTracker, contractAddress common.Address, chain legacyevm.Chain, specID int32, ds sqlutil.DataSource, lggr logger.Logger) (*medianContract, error) { - lggr = lggr.Named("MedianContract") + lggr = logger.Named(lggr, "MedianContract") contract, err := offchain_aggregator_wrapper.NewOffchainAggregator(contractAddress, chain.Client()) if err != nil { return nil, errors.Wrap(err, "could not instantiate NewOffchainAggregator") diff --git a/core/services/relay/evm/median_test.go b/core/services/relay/evm/median_test.go index 9c474006aa..a1578737b6 100644 --- a/core/services/relay/evm/median_test.go +++ b/core/services/relay/evm/median_test.go @@ -7,23 +7,23 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) func TestNewMedianProvider(t *testing.T) { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) chain := mocks.NewChain(t) chainID := testutils.NewRandomEVMChainID() chain.On("ID").Return(chainID) contractID := testutils.NewAddress() - relayer := Relayer{lggr: lggr, chain: chain} + relayer := Relayer{lggr: logger.Sugared(lggr), chain: chain} pargs := commontypes.PluginArgs{} diff --git a/core/services/relay/evm/mercury/config_poller.go b/core/services/relay/evm/mercury/config_poller.go index 2da541a8e4..e93ad339ce 100644 --- a/core/services/relay/evm/mercury/config_poller.go +++ b/core/services/relay/evm/mercury/config_poller.go @@ -11,9 +11,10 @@ import ( "github.com/pkg/errors" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" ) diff --git a/core/services/relay/evm/mercury/persistence_manager.go b/core/services/relay/evm/mercury/persistence_manager.go index d7f3d8eaa0..dfe75e7c3c 100644 --- a/core/services/relay/evm/mercury/persistence_manager.go +++ b/core/services/relay/evm/mercury/persistence_manager.go @@ -7,9 +7,10 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" ) @@ -39,7 +40,7 @@ type PersistenceManager struct { func NewPersistenceManager(lggr logger.Logger, serverURL string, orm ORM, jobID int32, maxTransmitQueueSize int, flushDeletesFrequency, pruneFrequency time.Duration) *PersistenceManager { return &PersistenceManager{ - lggr: lggr.Named("MercuryPersistenceManager").With("serverURL", serverURL), + lggr: logger.Sugared(lggr).Named("MercuryPersistenceManager").With("serverURL", serverURL), orm: orm, serverURL: serverURL, stopCh: make(services.StopChan), diff --git a/core/services/relay/evm/mercury/queue.go b/core/services/relay/evm/mercury/queue.go index 8b39be72a6..a450d21af6 100644 --- a/core/services/relay/evm/mercury/queue.go +++ b/core/services/relay/evm/mercury/queue.go @@ -13,9 +13,9 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" ) @@ -42,7 +42,7 @@ type transmitQueue struct { services.StateMachine cond sync.Cond - lggr logger.Logger + lggr logger.SugaredLogger asyncDeleter asyncDeleter mu *sync.RWMutex @@ -76,7 +76,7 @@ func NewTransmitQueue(lggr logger.Logger, serverURL, feedID string, maxlen int, return &transmitQueue{ services.StateMachine{}, sync.Cond{L: mu}, - lggr.Named("TransmitQueue"), + logger.Sugared(lggr).Named("TransmitQueue"), asyncDeleter, mu, nil, // pq needs to be initialized by calling tq.Init before use diff --git a/core/services/relay/evm/mercury/transmitter.go b/core/services/relay/evm/mercury/transmitter.go index f1434bf20f..b914e67b45 100644 --- a/core/services/relay/evm/mercury/transmitter.go +++ b/core/services/relay/evm/mercury/transmitter.go @@ -27,10 +27,10 @@ import ( capStreams "github.com/smartcontractkit/chainlink-common/pkg/capabilities/datastreams" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/triggers" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" - "github.com/smartcontractkit/chainlink/v2/core/logger" mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" @@ -110,7 +110,7 @@ type TransmitterConfig interface { type mercuryTransmitter struct { services.StateMachine - lggr logger.Logger + lggr logger.SugaredLogger cfg TransmitterConfig orm ORM @@ -147,7 +147,7 @@ func getPayloadTypes() abi.Arguments { } type server struct { - lggr logger.Logger + lggr logger.SugaredLogger transmitTimeout time.Duration @@ -285,7 +285,7 @@ func (s *server) runQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup, feed func newServer(lggr logger.Logger, cfg TransmitterConfig, client wsrpc.Client, pm *PersistenceManager, serverURL, feedIDHex string) *server { return &server{ - lggr, + logger.Sugared(lggr), cfg.TransmitTimeout().Duration(), client, pm, @@ -302,16 +302,17 @@ func newServer(lggr logger.Logger, cfg TransmitterConfig, client wsrpc.Client, p } func NewTransmitter(lggr logger.Logger, cfg TransmitterConfig, clients map[string]wsrpc.Client, fromAccount ed25519.PublicKey, jobID int32, feedID [32]byte, orm ORM, codec TransmitterReportDecoder, triggerCapability *triggers.MercuryTriggerService) *mercuryTransmitter { + sugared := logger.Sugared(lggr) feedIDHex := fmt.Sprintf("0x%x", feedID[:]) servers := make(map[string]*server, len(clients)) for serverURL, client := range clients { - cLggr := lggr.Named(serverURL).With("serverURL", serverURL) + cLggr := sugared.Named(serverURL).With("serverURL", serverURL) pm := NewPersistenceManager(cLggr, serverURL, orm, jobID, int(cfg.TransmitQueueMaxSize()), flushDeletesFrequency, pruneFrequency) servers[serverURL] = newServer(cLggr, cfg, client, pm, serverURL, feedIDHex) } return &mercuryTransmitter{ services.StateMachine{}, - lggr.Named("MercuryTransmitter").With("feedID", feedIDHex), + sugared.Named("MercuryTransmitter").With("feedID", feedIDHex), cfg, orm, servers, diff --git a/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go index f4c6af32b8..fb332dcc8f 100644 --- a/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go +++ b/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go @@ -11,8 +11,9 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" v1 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" reporttypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1/types" ) diff --git a/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go index 33c5fa9a32..ebbdfac66c 100644 --- a/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go +++ b/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go @@ -9,9 +9,9 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" v2 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" reporttypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/types" ) diff --git a/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go index 601431838d..1bf750fbf9 100644 --- a/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go +++ b/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go @@ -9,9 +9,9 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" v3 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" reporttypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/types" ) diff --git a/core/services/relay/evm/mercury/v4/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v4/reportcodec/report_codec.go index 12f3d88e73..9c4cb0e509 100644 --- a/core/services/relay/evm/mercury/v4/reportcodec/report_codec.go +++ b/core/services/relay/evm/mercury/v4/reportcodec/report_codec.go @@ -8,8 +8,9 @@ import ( pkgerrors "github.com/pkg/errors" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" v4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" reporttypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v4/types" ) diff --git a/core/services/relay/evm/mercury_config_provider.go b/core/services/relay/evm/mercury_config_provider.go index bd0749e5ae..349650c0fc 100644 --- a/core/services/relay/evm/mercury_config_provider.go +++ b/core/services/relay/evm/mercury_config_provider.go @@ -7,10 +7,10 @@ import ( "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-common/pkg/logger" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -31,7 +31,7 @@ func newMercuryConfigProvider(ctx context.Context, lggr logger.Logger, chain leg } cp, err := mercury.NewConfigPoller( ctx, - lggr.Named(relayConfig.FeedID.String()), + logger.Named(lggr, relayConfig.FeedID.String()), chain.LogPoller(), aggregatorAddress, *relayConfig.FeedID, diff --git a/core/services/relay/evm/mercury_provider.go b/core/services/relay/evm/mercury_provider.go index 9393f66b0d..58806e3dd7 100644 --- a/core/services/relay/evm/mercury_provider.go +++ b/core/services/relay/evm/mercury_provider.go @@ -6,6 +6,7 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" @@ -13,9 +14,10 @@ import ( v2 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" v3 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" v4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" + "github.com/smartcontractkit/chainlink-data-streams/mercury" + httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" - "github.com/smartcontractkit/chainlink/v2/core/logger" evmmercury "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" ) diff --git a/core/services/relay/evm/method_binding.go b/core/services/relay/evm/method_binding.go index 448f1b9fbf..9ff57fd934 100644 --- a/core/services/relay/evm/method_binding.go +++ b/core/services/relay/evm/method_binding.go @@ -8,14 +8,14 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-common/pkg/logger" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/logger" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) type NoContractExistsError struct { diff --git a/core/services/relay/evm/ocr2keeper.go b/core/services/relay/evm/ocr2keeper.go index b2d19c1170..2300f54b6e 100644 --- a/core/services/relay/evm/ocr2keeper.go +++ b/core/services/relay/evm/ocr2keeper.go @@ -13,6 +13,7 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink-automation/pkg/v3/plugin" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/automation" @@ -20,7 +21,6 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" ac "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_v21_plus_common" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" evm "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" @@ -218,7 +218,7 @@ func newOCR2KeeperConfigProvider(ctx context.Context, lggr logger.Logger, chain configPoller, err := NewConfigPoller( ctx, - lggr.With("contractID", rargs.ContractID), + logger.With(lggr, "contractID", rargs.ContractID), CPConfig{ chain.Client(), chain.LogPoller(), diff --git a/core/services/relay/evm/plugin_provider.go b/core/services/relay/evm/plugin_provider.go index ffcea48db2..58bfc1e525 100644 --- a/core/services/relay/evm/plugin_provider.go +++ b/core/services/relay/evm/plugin_provider.go @@ -5,10 +5,9 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" - - "github.com/smartcontractkit/chainlink/v2/core/logger" ) type pluginProvider struct { diff --git a/core/services/relay/evm/request_round_db.go b/core/services/relay/evm/request_round_db.go index 1aa3dfd747..07a2d1cbc3 100644 --- a/core/services/relay/evm/request_round_db.go +++ b/core/services/relay/evm/request_round_db.go @@ -8,8 +8,8 @@ import ( "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) // RequestRoundDB stores requested rounds for querying by the median plugin. diff --git a/core/services/relay/evm/request_round_tracker.go b/core/services/relay/evm/request_round_tracker.go index 7cf1377569..b9200fff75 100644 --- a/core/services/relay/evm/request_round_tracker.go +++ b/core/services/relay/evm/request_round_tracker.go @@ -12,13 +12,13 @@ import ( "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" offchain_aggregator_wrapper "github.com/smartcontractkit/chainlink/v2/core/internal/gethwrappers2/generated/offchainaggregator" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" ) diff --git a/core/services/relay/evm/standard_config_provider.go b/core/services/relay/evm/standard_config_provider.go index 59f91c52f4..91ca25413f 100644 --- a/core/services/relay/evm/standard_config_provider.go +++ b/core/services/relay/evm/standard_config_provider.go @@ -10,8 +10,9 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) diff --git a/core/services/relay/evm/write_target.go b/core/services/relay/evm/write_target.go index 6a584413db..699c5013ea 100644 --- a/core/services/relay/evm/write_target.go +++ b/core/services/relay/evm/write_target.go @@ -7,10 +7,11 @@ import ( chainselectors "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/targets" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/forwarder" - "github.com/smartcontractkit/chainlink/v2/core/logger" relayevmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -74,5 +75,5 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain return nil, err } - return targets.NewWriteTarget(lggr.Named("WriteTarget"), id, cr, cw, config.ForwarderAddress().String(), gasLimit), nil + return targets.NewWriteTarget(logger.Named(lggr, "WriteTarget"), id, cr, cw, config.ForwarderAddress().String(), gasLimit), nil } From b3887127e8549db9fdab773f9b5c9a5beb72b24e Mon Sep 17 00:00:00 2001 From: Lee Yik Jiun Date: Wed, 21 Aug 2024 16:36:54 +0800 Subject: [PATCH 121/432] vrf: fix vrfv2 test loading consumer address as coordinator (#14172) --- integration-tests/actions/vrf/vrfv2/setup_steps.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/actions/vrf/vrfv2/setup_steps.go b/integration-tests/actions/vrf/vrfv2/setup_steps.go index b5852f8281..c025a56304 100644 --- a/integration-tests/actions/vrf/vrfv2/setup_steps.go +++ b/integration-tests/actions/vrf/vrfv2/setup_steps.go @@ -378,7 +378,7 @@ func SetupVRFV2ForExistingEnv(t *testing.T, envConfig vrfcommon.VRFEnvConfig, l if err != nil { return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error loading existing CL env", err) } - coordinator, err := contracts.LoadVRFCoordinatorV2(sethClient, *commonExistingEnvConfig.ConsumerAddress) + coordinator, err := contracts.LoadVRFCoordinatorV2(sethClient, *commonExistingEnvConfig.CoordinatorAddress) if err != nil { return nil, nil, nil, nil, fmt.Errorf("%s, err: %w", "error loading VRFCoordinator2", err) } From 1852353bbf6ae4726287cb376bc7a323f657c92a Mon Sep 17 00:00:00 2001 From: Dimitris Grigoriou Date: Wed, 21 Aug 2024 12:29:15 +0300 Subject: [PATCH 122/432] Fix datarace (#14157) * Fix datarace * Add changeset --- .changeset/beige-eels-teach.md | 5 +++++ core/chains/evm/gas/block_history_estimator.go | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 .changeset/beige-eels-teach.md diff --git a/.changeset/beige-eels-teach.md b/.changeset/beige-eels-teach.md new file mode 100644 index 0000000000..3a3c59ec26 --- /dev/null +++ b/.changeset/beige-eels-teach.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Fix bhe datarace #internal diff --git a/core/chains/evm/gas/block_history_estimator.go b/core/chains/evm/gas/block_history_estimator.go index 4075b46f90..b933ea2382 100644 --- a/core/chains/evm/gas/block_history_estimator.go +++ b/core/chains/evm/gas/block_history_estimator.go @@ -276,6 +276,8 @@ func (b *BlockHistoryEstimator) setMaxPercentileGasPrice(gasPrice *assets.Wei) { } func (b *BlockHistoryEstimator) getBlockHistoryNumbers() (numsInHistory []int64) { + b.blocksMu.RLock() + defer b.blocksMu.RUnlock() for _, b := range b.blocks { numsInHistory = append(numsInHistory, b.Number) } From 4d50117e8d14b35cce5c94c418ff1157476742d5 Mon Sep 17 00:00:00 2001 From: Gheorghe Strimtu Date: Wed, 21 Aug 2024 15:44:04 +0300 Subject: [PATCH 123/432] crib-317 update ctf version (#14176) * crib-317 update crf version * load tests go module update * new ctf release --- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 7b0760de4d..8589f12840 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -34,7 +34,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 - github.com/smartcontractkit/chainlink-testing-framework v1.34.2 + github.com/smartcontractkit/chainlink-testing-framework v1.34.5 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 324064296d..53c0c5645f 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1502,8 +1502,8 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f9856 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.2 h1:YL3ft7KJB7SAopdmJeyeR4/kv0j4jOdagNihXq8OZ38= -github.com/smartcontractkit/chainlink-testing-framework v1.34.2/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= +github.com/smartcontractkit/chainlink-testing-framework v1.34.5 h1:6itLSDW4NHDDNR+Y+Z8YDzxxCN9SjdKb6SmLCl0vTFM= +github.com/smartcontractkit/chainlink-testing-framework v1.34.5/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index e960e12c63..abecf67074 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,7 +17,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 - github.com/smartcontractkit/chainlink-testing-framework v1.34.2 + github.com/smartcontractkit/chainlink-testing-framework v1.34.5 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index cac0f64d24..791b999a6c 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1484,8 +1484,8 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f9856 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.2 h1:YL3ft7KJB7SAopdmJeyeR4/kv0j4jOdagNihXq8OZ38= -github.com/smartcontractkit/chainlink-testing-framework v1.34.2/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= +github.com/smartcontractkit/chainlink-testing-framework v1.34.5 h1:6itLSDW4NHDDNR+Y+Z8YDzxxCN9SjdKb6SmLCl0vTFM= +github.com/smartcontractkit/chainlink-testing-framework v1.34.5/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a h1:8GtvGJaGyKzx/ar1yX74GxrzIYWTZVTyv4pYB/1ln8w= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= From d204c463db699b66475eb2ef22bd1fdd935a92d8 Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs <5300706+iljapavlovs@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:01:23 +0300 Subject: [PATCH 124/432] CTF tests - increase gas_tip_cap for Polygon Amoy chain (#14178) * CTF tests - increase gas_tip_cap for Polygon Amoy chain * CTF tests - enable gas_price_estimation_enabled * CTF tests - add sleep to wait for txs to be mined --- integration-tests/load/vrfv2/vrfv2_test.go | 2 ++ integration-tests/load/vrfv2plus/vrfv2plus_test.go | 2 ++ integration-tests/testconfig/default.toml | 8 ++++---- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/integration-tests/load/vrfv2/vrfv2_test.go b/integration-tests/load/vrfv2/vrfv2_test.go index 0075300c7d..7913d26904 100644 --- a/integration-tests/load/vrfv2/vrfv2_test.go +++ b/integration-tests/load/vrfv2/vrfv2_test.go @@ -82,6 +82,8 @@ func TestVRFV2Performance(t *testing.T) { Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") } else { if *vrfv2Config.General.CancelSubsAfterTestRun { + // wait for all txs to be mined in order to avoid nonce issues + time.Sleep(10 * time.Second) //cancel subs and return funds to sub owner vrfv2.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) } diff --git a/integration-tests/load/vrfv2plus/vrfv2plus_test.go b/integration-tests/load/vrfv2plus/vrfv2plus_test.go index e8e1d7779c..a1e5deabcb 100644 --- a/integration-tests/load/vrfv2plus/vrfv2plus_test.go +++ b/integration-tests/load/vrfv2plus/vrfv2plus_test.go @@ -81,6 +81,8 @@ func TestVRFV2PlusPerformance(t *testing.T) { Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") } else { if *testConfig.VRFv2Plus.General.CancelSubsAfterTestRun { + // wait for all txs to be mined in order to avoid nonce issues + time.Sleep(10 * time.Second) //cancel subs and return funds to sub owner vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) } diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index b10c7280b3..2bb73f42ad 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -323,11 +323,11 @@ eip_1559_dynamic_fees = true # automated gas estimation for live networks # if set to true we will dynamically estimate gas for every transaction (based on suggested values, priority and congestion rate for last X blocks) -# gas_price_estimation_enabled = true + gas_price_estimation_enabled = true # number of blocks to use for congestion rate estimation (it will determine buffer added on top of suggested values) -# gas_price_estimation_blocks = 100 + gas_price_estimation_blocks = 100 # transaction priority, which determines adjustment factor multiplier applied to suggested values (fast - 1.2x, standard - 1x, slow - 0.8x) -# gas_price_estimation_tx_priority = "standard" + gas_price_estimation_tx_priority = "standard" # URLs # if set they will overwrite URLs from EVMNetwork that Seth uses, can be either WS(S) or HTTP(S) @@ -346,7 +346,7 @@ gas_price = 200_000_000_000 # EIP-1559 transactions gas_fee_cap = 200_000_000_000 -gas_tip_cap = 2_000_000_000 +gas_tip_cap = 25_000_000_000 [[Seth.networks]] name = "Polygon zkEVM Goerli" From d7645dd91c6d644cdebcd3590a5fd4da6cb260bc Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Wed, 21 Aug 2024 17:32:51 +0200 Subject: [PATCH 125/432] CCIP-3008 CCIP versioning which is semver compatible (#14177) * CCIP versioning which is semver compatible * Drop suffixes to avoid misleading people * Update core/services/versioning/orm_test.go Co-authored-by: Ryan Stout --------- Co-authored-by: Ryan Stout --- core/services/versioning/orm_test.go | 81 ++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/core/services/versioning/orm_test.go b/core/services/versioning/orm_test.go index 3504c2bc77..e2f05e3903 100644 --- a/core/services/versioning/orm_test.go +++ b/core/services/versioning/orm_test.go @@ -97,6 +97,87 @@ func Test_Version_CheckVersion(t *testing.T) { assert.Equal(t, "9.9.8", dbv.String()) } +func TestORM_CheckVersion_CCIP(t *testing.T) { + ctx := testutils.Context(t) + db := pgtest.NewSqlxDB(t) + + lggr := logger.TestLogger(t) + + orm := NewORM(db, lggr) + + tests := []struct { + name string + currentVersion string + newVersion string + expectedError bool + }{ + { + name: "ccip patch version bump from 0 -> 2", + currentVersion: "2.5.0-ccip1.4.0", + newVersion: "2.5.0-ccip1.4.2", + expectedError: false, + }, + { + name: "ccip patch downgrade errors", + currentVersion: "2.5.0-ccip1.4.2", + newVersion: "2.5.0-ccip1.4.1", + expectedError: true, + }, + { + name: "ccip patch version bump from 2 -> 10", + currentVersion: "2.5.0-ccip1.4.2", + newVersion: "2.5.0-ccip1.4.10", + expectedError: false, + }, + { + name: "ccip patch version bump from 9 -> 101", + currentVersion: "2.5.0-ccip1.4.9", + newVersion: "2.5.0-ccip1.4.101", + expectedError: false, + }, + { + name: "upgrading only core version", + currentVersion: "2.5.0-ccip1.4.10", + newVersion: "2.6.0-ccip1.4.10", + expectedError: false, + }, + { + name: "downgrading only core version errors", + currentVersion: "2.6.0-ccip1.4.10", + newVersion: "2.5.0-ccip1.4.10", + expectedError: true, + }, + { + name: "upgrading both core and ccip version", + currentVersion: "2.5.0-ccip1.4.10", + newVersion: "2.6.0-ccip1.4.11", + expectedError: false, + }, + { + name: "upgrading both core and ccip version but minor version", + currentVersion: "2.5.0-ccip1.4.10", + newVersion: "2.6.0-ccip1.5.0", + expectedError: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + _, err := db.ExecContext(ctx, `TRUNCATE node_versions;`) + require.NoError(t, err) + + require.NoError(t, orm.UpsertNodeVersion(ctx, NewNodeVersion(test.currentVersion))) + _, _, err = CheckVersion(ctx, db, lggr, test.newVersion) + if test.expectedError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + + } +} + func TestORM_NodeVersion_FindLatestNodeVersion(t *testing.T) { ctx := testutils.Context(t) db := pgtest.NewSqlxDB(t) From 0cbad1b0c8aadd2a8daebdfe63b3c735d473e2b6 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Wed, 21 Aug 2024 18:40:52 +0200 Subject: [PATCH 126/432] TT-1473 Refactor integration-tests.yml workflow to use run-e2e-tests-reusable-workflow.yml (#14134) * wip * fix secrets and test log level * comment eth-smoke-tests-matrix-automation and use reusable workflow instead * comment eth-smoke-tests-matrix-log-poller and use reusable workflow instead * Fix * migrate node upgrade tests * fix test_config_chainlink_upgrade_version * use default workflow name * bump run-tests * comment compare-tests * add name to reusable workflow * Add chainlink-testing-framework/show-test-summary to reusable workflow and run collect metrics step for aggregated result * Move Upload CL Node Coverage Data Artifacts to reusable workflow * Fix * Update cl node coverage artifact prefix * Update reusable workflow to have test results as output * Fix * fix * test * fix * remove old node migration tests * migrate otel traces steps to reusable workflow * uncomment eth-smoke-go-mod-cache * rename some steps and jobs * Use citool from CTF * Fix * Fix * Add cache for citool * Update setup-go GHA * Cache ctf builds * Bump * Fix * Bump * Remove eth-smoke-go-mod-cache as cache is saved in run-tests * Bump * Remove duplicated step * Bump * Bump * trigger build * Clean up after_tests job * Run all PR tests * Fix record test result step * Remove duplicated tests from e2e-tests.yml * Bump GHA * Run ccip tests in reusable workflow * fix go mod * Fix * Update test_env names * Install citool bin intead of checking out ctf repo * Add more ccip tests * chore: Update Go setup in reusable workflow * Update test names * Use ctf from branch * Run all PR tests * fix plugins test * Run core and ccip tests based on changes * Fix * Bump citool * Bump run-tests * Fix collect metrics * Bump ctf * Simplify test ids * uncomment tags * fix * Fix TEST_TYPE * Fix test env vars * Update check-e2e-test-results * Fix check results * test * fix * test * fix * Do not build integration-tests, run only lint * fix test_result artifact * Fix cache * Fix unique workflow id * Fix e2e-tests and skip one test * test when ccip tests skipped * fix --- .github/e2e-tests.yml | 640 +++++---- .github/workflows/integration-tests.yml | 1218 ++--------------- .../run-automation-ondemand-e2e-tests.yml | 68 +- .../run-e2e-tests-reusable-workflow.yml | 305 +++-- .gitignore | 1 - .../ccip-tests/testconfig/global.go | 87 ++ .../citool/cmd/check_tests_cmd.go | 166 --- .../citool/cmd/check_tests_cmd_test.go | 47 - .../citool/cmd/create_test_config_cmd.go | 179 --- .../citool/cmd/csv_export_cmd.go | 96 -- integration-tests/citool/cmd/filter_cmd.go | 165 --- .../citool/cmd/filter_cmd_test.go | 64 - integration-tests/citool/cmd/root_cmd.go | 32 - .../citool/cmd/test_config_cmd.go | 123 -- .../citool/cmd/test_config_cmd_test.go | 75 - integration-tests/citool/cmd/types.go | 26 - integration-tests/citool/main.go | 9 - integration-tests/go.mod | 4 +- 18 files changed, 838 insertions(+), 2467 deletions(-) delete mode 100644 integration-tests/citool/cmd/check_tests_cmd.go delete mode 100644 integration-tests/citool/cmd/check_tests_cmd_test.go delete mode 100644 integration-tests/citool/cmd/create_test_config_cmd.go delete mode 100644 integration-tests/citool/cmd/csv_export_cmd.go delete mode 100644 integration-tests/citool/cmd/filter_cmd.go delete mode 100644 integration-tests/citool/cmd/filter_cmd_test.go delete mode 100644 integration-tests/citool/cmd/root_cmd.go delete mode 100644 integration-tests/citool/cmd/test_config_cmd.go delete mode 100644 integration-tests/citool/cmd/test_config_cmd_test.go delete mode 100644 integration-tests/citool/cmd/types.go delete mode 100644 integration-tests/citool/main.go diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index b2c9f12fca..6a46e76f01 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -3,493 +3,472 @@ # Each entry in this file includes the following: # - The GitHub runner (runs_on field) that will execute tests. # - The tests that will be run by the runner. -# - The workflows (e.g., Run PR E2E Tests, Run Nightly E2E Tests) that should trigger these tests. +# - The workflows (e.g., Run PR E2E Tests, Nightly E2E Tests) that should trigger these tests. # runner-test-matrix: # START: OCR tests # Example of 1 runner for all tests in integration-tests/smoke/ocr_test.go - - id: integration-tests/smoke/ocr_test.go:* + - id: smoke/ocr_test.go:* path: integration-tests/smoke/ocr_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/ocr_test.go -timeout 30m -count=1 -test.parallel=2 -json pyroscope_env: ci-smoke-ocr-evm-simulated - # Example of 2 separate runners for the same test file but different tests. Can be used if tests if are too heavy to run on the same runner - - id: integration-tests/smoke/ocr2_test.go:^TestOCRv2Request$ - path: integration-tests/smoke/ocr2_test.go - test_env_type: docker - runs_on: ubuntu-latest - workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests - test_cmd: cd integration-tests/ && go test smoke/ocr2_test.go -test.run ^TestOCRv2Request$ -test.parallel=1 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-ocr2-evm-simulated-nightly - - - id: integration-tests/smoke/ocr2_test.go:^TestOCRv2Basic$ - path: integration-tests/smoke/ocr2_test.go - test_env_type: docker - runs_on: ubuntu-latest - workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests - test_cmd: cd integration-tests/ && go test smoke/ocr2_test.go -test.run ^TestOCRv2Basic$ -test.parallel=1 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-ocr2-evm-simulated-nightly - # Example of a configuration for running a single soak test in Kubernetes Remote Runner - - id: integration-tests/soak/ocr_test.go:^TestOCRv1Soak$ + - id: soak/ocr_test.go:^TestOCRv1Soak$ path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRv1Soak$ -test.parallel=1 -timeout 30m -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_suite: soak + test_env_vars: + TEST_SUITE: soak - - id: integration-tests/soak/ocr_test.go:^TestOCRv2Soak$ + - id: soak/ocr_test.go:^TestOCRv2Soak$ path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRv2Soak$ -test.parallel=1 -timeout 30m -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_suite: soak + test_env_vars: + TEST_SUITE: soak - - id: integration-tests/soak/ocr_test.go:^TestForwarderOCRv1Soak$ + - id: soak/ocr_test.go:^TestForwarderOCRv1Soak$ path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestForwarderOCRv1Soak$ -test.parallel=1 -timeout 30m -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_suite: soak + test_env_vars: + TEST_SUITE: soak - - id: integration-tests/soak/ocr_test.go:^TestForwarderOCRv2Soak$ + - id: soak/ocr_test.go:^TestForwarderOCRv2Soak$ path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestForwarderOCRv2Soak$ -test.parallel=1 -timeout 30m -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_suite: soak + test_env_vars: + TEST_SUITE: soak - - id: integration-tests/soak/ocr_test.go:^TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled$ + - id: soak/ocr_test.go:^TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled$ path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled$ -test.parallel=1 -timeout 30m -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_suite: soak + test_env_vars: + TEST_SUITE: soak - - id: integration-tests/soak/ocr_test.go:^TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled$ + - id: soak/ocr_test.go:^TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled$ path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled$ -test.parallel=1 -timeout 30m -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_suite: soak + test_env_vars: + TEST_SUITE: soak - - id: integration-tests/soak/ocr_test.go:^TestOCRSoak_GasSpike$ + - id: soak/ocr_test.go:^TestOCRSoak_GasSpike$ path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_GasSpike$ -test.parallel=1 -timeout 30m -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_suite: soak + test_env_vars: + TEST_SUITE: soak - - id: integration-tests/soak/ocr_test.go:^TestOCRSoak_ChangeBlockGasLimit$ + - id: soak/ocr_test.go:^TestOCRSoak_ChangeBlockGasLimit$ path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_ChangeBlockGasLimit$ -test.parallel=1 -timeout 30m -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_suite: soak + test_env_vars: + TEST_SUITE: soak - - id: integration-tests/soak/ocr_test.go:^TestOCRSoak_RPCDownForAllCLNodes$ + - id: soak/ocr_test.go:^TestOCRSoak_RPCDownForAllCLNodes$ path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_RPCDownForAllCLNodes$ -test.parallel=1 -timeout 30m -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_suite: soak + test_env_vars: + TEST_SUITE: soak - - id: integration-tests/soak/ocr_test.go:^TestOCRSoak_RPCDownForHalfCLNodes$ + - id: soak/ocr_test.go:^TestOCRSoak_RPCDownForHalfCLNodes$ path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_RPCDownForHalfCLNodes$ -test.parallel=1 -timeout 30m -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_suite: soak + test_env_vars: + TEST_SUITE: soak - - id: integration-tests/smoke/forwarder_ocr_test.go:* + - id: smoke/forwarder_ocr_test.go:* path: integration-tests/smoke/forwarder_ocr_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/forwarder_ocr_test.go -timeout 30m -count=1 -test.parallel=2 -json pyroscope_env: ci-smoke-forwarder-ocr-evm-simulated - - id: integration-tests/smoke/forwarders_ocr2_test.go:* + - id: smoke/forwarders_ocr2_test.go:* path: integration-tests/smoke/forwarders_ocr2_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/forwarders_ocr2_test.go -timeout 30m -count=1 -test.parallel=2 -json pyroscope_env: ci-smoke-forwarder-ocr-evm-simulated - - id: integration-tests/smoke/ocr2_test.go:* + - id: smoke/ocr2_test.go:* path: integration-tests/smoke/ocr2_test.go test_env_type: docker runs_on: ubuntu22.04-16cores-64GB workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/ocr2_test.go -timeout 30m -count=1 -test.parallel=6 -json pyroscope_env: ci-smoke-ocr2-evm-simulated - - id: integration-tests/smoke/ocr2_test.go:*-plugins + - id: smoke/ocr2_test.go:*-plugins path: integration-tests/smoke/ocr2_test.go test_env_type: docker runs_on: ubuntu22.04-16cores-64GB workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/ocr2_test.go -timeout 30m -count=1 -test.parallel=6 -json pyroscope_env: ci-smoke-ocr2-plugins-evm-simulated - test_inputs: - # chainlink_version: '{{ env.GITHUB_SHA_PLUGINS }}' # This is the chainlink version that has the plugins - chainlink_version: develop-plugins + test_env_vars: + E2E_TEST_CHAINLINK_VERSION: '{{ env.GITHUB_SHA_PLUGINS }}' # This is the chainlink version that has the plugins + ENABLE_OTEL_TRACES: true # END: OCR tests # START: Automation tests - - id: integration-tests/smoke/automation_test.go:^TestAutomationBasic/registry_2_0|TestAutomationBasic/registry_2_1_conditional|TestAutomationBasic/registry_2_1_logtrigger$ + - id: smoke/automation_test.go:^TestAutomationBasic/registry_2_0|TestAutomationBasic/registry_2_1_conditional|TestAutomationBasic/registry_2_1_logtrigger$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_0|TestAutomationBasic/registry_2_1_conditional|TestAutomationBasic/registry_2_1_logtrigger$" -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationBasic/registry_2_1_with_mercury_v02|TestAutomationBasic/registry_2_1_with_mercury_v03|TestAutomationBasic/registry_2_1_with_logtrigger_and_mercury_v02$ + - id: smoke/automation_test.go:^TestAutomationBasic/registry_2_1_with_mercury_v02|TestAutomationBasic/registry_2_1_with_mercury_v03|TestAutomationBasic/registry_2_1_with_logtrigger_and_mercury_v02$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_1_with_mercury_v02|TestAutomationBasic/registry_2_1_with_mercury_v03|TestAutomationBasic/registry_2_1_with_logtrigger_and_mercury_v02$" -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationBasic/registry_2_2_conditional|TestAutomationBasic/registry_2_2_logtrigger|TestAutomationBasic/registry_2_2_with_mercury_v02$ + - id: smoke/automation_test.go:^TestAutomationBasic/registry_2_2_conditional|TestAutomationBasic/registry_2_2_logtrigger|TestAutomationBasic/registry_2_2_with_mercury_v02$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_2_conditional|TestAutomationBasic/registry_2_2_logtrigger|TestAutomationBasic/registry_2_2_with_mercury_v02$" -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationBasic/registry_2_2_with_mercury_v03|TestAutomationBasic/registry_2_2_with_logtrigger_and_mercury_v02$ + - id: smoke/automation_test.go:^TestAutomationBasic/registry_2_2_with_mercury_v03|TestAutomationBasic/registry_2_2_with_logtrigger_and_mercury_v02$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_2_with_mercury_v03|TestAutomationBasic/registry_2_2_with_logtrigger_and_mercury_v02$" -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationBasic/registry_2_3_conditional_native|TestAutomationBasic/registry_2_3_conditional_link$ + - id: smoke/automation_test.go:^TestAutomationBasic/registry_2_3_conditional_native|TestAutomationBasic/registry_2_3_conditional_link$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_3_conditional_native|TestAutomationBasic/registry_2_3_conditional_link$" -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationBasic/registry_2_3_logtrigger_native|TestAutomationBasic/registry_2_3_logtrigger_link$ + - id: smoke/automation_test.go:^TestAutomationBasic/registry_2_3_logtrigger_native|TestAutomationBasic/registry_2_3_logtrigger_link$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_3_logtrigger_native|TestAutomationBasic/registry_2_3_logtrigger_link$" -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationBasic/registry_2_3_with_mercury_v03_link|TestAutomationBasic/registry_2_3_with_logtrigger_and_mercury_v02_link$ + - id: smoke/automation_test.go:^TestAutomationBasic/registry_2_3_with_mercury_v03_link|TestAutomationBasic/registry_2_3_with_logtrigger_and_mercury_v02_link$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_3_with_mercury_v03_link|TestAutomationBasic/registry_2_3_with_logtrigger_and_mercury_v02_link$" -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestSetUpkeepTriggerConfig$ + - id: smoke/automation_test.go:^TestSetUpkeepTriggerConfig$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestSetUpkeepTriggerConfig$ -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationAddFunds$ + - id: smoke/automation_test.go:^TestAutomationAddFunds$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationAddFunds$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationPauseUnPause$ + - id: smoke/automation_test.go:^TestAutomationPauseUnPause$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationPauseUnPause$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationRegisterUpkeep$ + - id: smoke/automation_test.go:^TestAutomationRegisterUpkeep$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationRegisterUpkeep$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationPauseRegistry$ + - id: smoke/automation_test.go:^TestAutomationPauseRegistry$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationPauseRegistry$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationKeeperNodesDown$ + - id: smoke/automation_test.go:^TestAutomationKeeperNodesDown$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationKeeperNodesDown$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationPerformSimulation$ + - id: smoke/automation_test.go:^TestAutomationPerformSimulation$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationPerformSimulation$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestAutomationCheckPerformGasLimit$ + - id: smoke/automation_test.go:^TestAutomationCheckPerformGasLimit$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationCheckPerformGasLimit$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestUpdateCheckData$ + - id: smoke/automation_test.go:^TestUpdateCheckData$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestUpdateCheckData$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/automation_test.go:^TestSetOffchainConfigWithMaxGasPrice$ + - id: smoke/automation_test.go:^TestSetOffchainConfigWithMaxGasPrice$ path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestSetOffchainConfigWithMaxGasPrice$ -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperBasicSmoke$ + - id: smoke/keeper_test.go:^TestKeeperBasicSmoke$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperBasicSmoke$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperBlockCountPerTurn$ + - id: smoke/keeper_test.go:^TestKeeperBlockCountPerTurn$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperBlockCountPerTurn$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperSimulation$ + - id: smoke/keeper_test.go:^TestKeeperSimulation$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperSimulation$ -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperCheckPerformGasLimit$ + - id: smoke/keeper_test.go:^TestKeeperCheckPerformGasLimit$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperCheckPerformGasLimit$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperRegisterUpkeep$ + - id: smoke/keeper_test.go:^TestKeeperRegisterUpkeep$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperRegisterUpkeep$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperAddFunds$ + - id: smoke/keeper_test.go:^TestKeeperAddFunds$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperAddFunds$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperRemove$ + - id: smoke/keeper_test.go:^TestKeeperRemove$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperRemove$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperPauseRegistry$ + - id: smoke/keeper_test.go:^TestKeeperPauseRegistry$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperPauseRegistry$ -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperMigrateRegistry$ + - id: smoke/keeper_test.go:^TestKeeperMigrateRegistry$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperMigrateRegistry$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperNodeDown$ + - id: smoke/keeper_test.go:^TestKeeperNodeDown$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperNodeDown$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperPauseUnPauseUpkeep$ + - id: smoke/keeper_test.go:^TestKeeperPauseUnPauseUpkeep$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperPauseUnPauseUpkeep$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperUpdateCheckData$ + - id: smoke/keeper_test.go:^TestKeeperUpdateCheckData$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperUpdateCheckData$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/smoke/keeper_test.go:^TestKeeperJobReplacement$ + - id: smoke/keeper_test.go:^TestKeeperJobReplacement$ path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperJobReplacement$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - - id: integration-tests/load/automationv2_1/automationv2_1_test.go:TestLogTrigger + - id: load/automationv2_1/automationv2_1_test.go:TestLogTrigger path: integration-tests/load/automationv2_1/automationv2_1_test.go runs_on: ubuntu-latest test_env_type: k8s-remote-runner @@ -497,88 +476,88 @@ runner-test-matrix: remote_runner_memory: 4Gi test_config_override_required: true test_secrets_required: true - test_inputs: - test_suite: automationv2_1 + test_env_vars: + TEST_SUITE: automationv2_1 workflows: - Automation Load Test pyroscope_env: automation-load-test - - id: integration-tests/smoke/automation_upgrade_test.go:^TestAutomationNodeUpgrade/registry_2_0 + - id: smoke/automation_upgrade_test.go:^TestAutomationNodeUpgrade/registry_2_0 path: integration-tests/smoke/automation_upgrade_test.go test_env_type: docker runs_on: ubuntu22.04-8cores-32GB workflows: - Run Automation Product Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationNodeUpgrade/registry_2_0 -test.parallel=1 -timeout 60m -count=1 -json - test_inputs: - chainlink_image: public.ecr.aws/chainlink/chainlink - chainlink_version: latest - chainlink_upgrade_image: '{{ env.QA_CHAINLINK_IMAGE }}' - chainlink_upgrade_version: develop + test_env_vars: + E2E_TEST_CHAINLINK_IMAGE: public.ecr.aws/chainlink/chainlink + E2E_TEST_CHAINLINK_VERSION: latest + E2E_TEST_CHAINLINK_UPGRADE_IMAGE: '{{ env.QA_CHAINLINK_IMAGE }}' + E2E_TEST_CHAINLINK_UPGRADE_VERSION: develop pyroscope_env: ci-smoke-automation-upgrade-tests - - id: integration-tests/smoke/automation_upgrade_test.go:^TestAutomationNodeUpgrade/registry_2_1 + - id: smoke/automation_upgrade_test.go:^TestAutomationNodeUpgrade/registry_2_1 path: integration-tests/smoke/automation_upgrade_test.go test_env_type: docker runs_on: ubuntu22.04-8cores-32GB workflows: - Run Automation Product Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationNodeUpgrade/registry_2_1 -test.parallel=5 -timeout 60m -count=1 -json - test_inputs: - chainlink_image: public.ecr.aws/chainlink/chainlink - chainlink_version: latest - chainlink_upgrade_image: '{{ env.QA_CHAINLINK_IMAGE }}' - chainlink_upgrade_version: develop + test_env_vars: + E2E_TEST_CHAINLINK_IMAGE: public.ecr.aws/chainlink/chainlink + E2E_TEST_CHAINLINK_VERSION: latest + E2E_TEST_CHAINLINK_UPGRADE_IMAGE: '{{ env.QA_CHAINLINK_IMAGE }}' + E2E_TEST_CHAINLINK_UPGRADE_VERSION: develop pyroscope_env: ci-smoke-automation-upgrade-tests - - id: integration-tests/smoke/automation_upgrade_test.go:^TestAutomationNodeUpgrade/registry_2_2 + - id: smoke/automation_upgrade_test.go:^TestAutomationNodeUpgrade/registry_2_2 path: integration-tests/smoke/automation_upgrade_test.go test_env_type: docker runs_on: ubuntu22.04-8cores-32GB workflows: - Run Automation Product Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationNodeUpgrade/registry_2_2 -test.parallel=5 -timeout 60m -count=1 -json - test_inputs: - chainlink_image: public.ecr.aws/chainlink/chainlink - chainlink_version: latest - chainlink_upgrade_image: '{{ env.QA_CHAINLINK_IMAGE }}' - chainlink_upgrade_version: develop + test_env_vars: + E2E_TEST_CHAINLINK_IMAGE: public.ecr.aws/chainlink/chainlink + E2E_TEST_CHAINLINK_VERSION: latest + E2E_TEST_CHAINLINK_UPGRADE_IMAGE: '{{ env.QA_CHAINLINK_IMAGE }}' + E2E_TEST_CHAINLINK_UPGRADE_VERSION: develop pyroscope_env: ci-smoke-automation-upgrade-tests - - id: integration-tests/reorg/automation_reorg_test.go^TestAutomationReorg/registry_2_0 + - id: reorg/automation_reorg_test.go^TestAutomationReorg/registry_2_0 path: integration-tests/reorg/automation_reorg_test.go runs_on: ubuntu-latest test_env_type: docker - test_inputs: - test_suite: reorg + test_env_vars: + TEST_SUITE: reorg workflows: - Run Automation On Demand Tests (TEST WORKFLOW) test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_0 -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg - - id: integration-tests/reorg/automation_reorg_test.go^TestAutomationReorg/registry_2_1 + - id: reorg/automation_reorg_test.go^TestAutomationReorg/registry_2_1 path: integration-tests/reorg/automation_reorg_test.go runs_on: ubuntu-latest test_env_type: docker - test_inputs: - test_suite: reorg + test_env_vars: + TEST_SUITE: reorg workflows: - Run Automation On Demand Tests (TEST WORKFLOW) test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_1 -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg - - id: integration-tests/reorg/automation_reorg_test.go^TestAutomationReorg/registry_2_2 + - id: reorg/automation_reorg_test.go^TestAutomationReorg/registry_2_2 path: integration-tests/reorg/automation_reorg_test.go runs_on: ubuntu-latest test_env_type: docker - test_inputs: - test_suite: reorg + test_env_vars: + TEST_SUITE: reorg workflows: - Run Automation On Demand Tests (TEST WORKFLOW) test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_2 -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg - - id: integration-tests/chaos/automation_chaos_test.go + - id: chaos/automation_chaos_test.go path: integration-tests/chaos/automation_chaos_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest @@ -586,26 +565,27 @@ runner-test-matrix: - Run Automation On Demand Tests (TEST WORKFLOW) test_cmd: cd integration-tests/chaos && DETACH_RUNNER=false go test -v -test.run ^TestAutomationChaos$ -test.parallel=20 -timeout 60m -count=1 -json pyroscope_env: ci-automation-on-demand-chaos - test_inputs: - test_suite: chaos + test_env_vars: + TEST_SUITE: chaos - - id: integration-tests/benchmark/keeper_test.go:^TestAutomationBenchmark$ + - id: benchmark/keeper_test.go:^TestAutomationBenchmark$ path: integration-tests/benchmark/keeper_test.go test_env_type: k8s-remote-runner remote_runner_memory: 4Gi runs_on: ubuntu-latest # workflows: - # - Run Nightly E2E Tests + # - Nightly E2E Tests test_cmd: cd integration-tests/benchmark && go test -v -test.run ^TestAutomationBenchmark$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-benchmark-automation-nightly - test_inputs: - test_suite: benchmark + test_env_vars: + TEST_SUITE: benchmark + TEST_TYPE: benchmark # END: Automation tests # START: VRF tests - - id: integration-tests/smoke/vrfv2_test.go:TestVRFv2Basic + - id: smoke/vrfv2_test.go:TestVRFv2Basic path: integration-tests/smoke/vrfv2_test.go runs_on: ubuntu22.04-8cores-32GB test_env_type: docker @@ -615,55 +595,55 @@ runner-test-matrix: workflows: - On Demand VRFV2 Smoke Test (Ethereum clients) - - id: integration-tests/load/vrfv2plus/vrfv2plus_test.go:^TestVRFV2PlusPerformance$Smoke + - id: load/vrfv2plus/vrfv2plus_test.go:^TestVRFV2PlusPerformance$Smoke path: integration-tests/load/vrfv2plus/vrfv2plus_test.go runs_on: ubuntu22.04-8cores-32GB test_env_type: docker test_cmd: cd integration-tests/load/vrfv2plus && go test -v -test.run ^TestVRFV2PlusPerformance$ -test.parallel=1 -timeout 24h -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_type: Smoke + test_env_vars: + TEST_TYPE: Smoke workflows: - On Demand VRFV2 Plus Performance Test - - id: integration-tests/load/vrfv2plus/vrfv2plus_test.go:^TestVRFV2PlusBHSPerformance$Smoke + - id: load/vrfv2plus/vrfv2plus_test.go:^TestVRFV2PlusBHSPerformance$Smoke path: integration-tests/load/vrfv2plus/vrfv2plus_test.go runs_on: ubuntu22.04-8cores-32GB test_env_type: docker test_cmd: cd integration-tests/load/vrfv2plus && go test -v -test.run ^TestVRFV2PlusBHSPerformance$ -test.parallel=1 -timeout 24h -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_type: Smoke + test_env_vars: + TEST_TYPE: Smoke workflows: - On Demand VRFV2 Plus Performance Test - - id: integration-tests/load/vrfv2/vrfv2_test.go:^TestVRFV2Performance$Smoke + - id: load/vrfv2/vrfv2_test.go:^TestVRFV2Performance$Smoke path: integration-tests/load/vrfv2/vrfv2_test.go runs_on: ubuntu22.04-8cores-32GB test_env_type: docker test_cmd: cd integration-tests/load/vrfv2 && go test -v -test.run ^TestVRFV2Performance$ -test.parallel=1 -timeout 24h -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_type: Smoke + test_env_vars: + TEST_TYPE: Smoke workflows: - On Demand VRFV2 Performance Test - - id: integration-tests/load/vrfv2/vrfv2_test.go:^TestVRFV2PlusBHSPerformance$Smoke + - id: load/vrfv2/vrfv2_test.go:^TestVRFV2PlusBHSPerformance$Smoke path: integration-tests/load/vrfv2/vrfv2_test.go runs_on: ubuntu22.04-8cores-32GB test_env_type: docker test_cmd: cd integration-tests/load/vrfv2 && go test -v -test.run ^TestVRFV2PlusBHSPerformance$ -test.parallel=1 -timeout 24h -count=1 -json test_config_override_required: true test_secrets_required: true - test_inputs: - test_type: Smoke + test_env_vars: + TEST_TYPE: Smoke workflows: - On Demand VRFV2 Performance Test - - id: integration-tests/smoke/vrfv2plus_test.go:^TestVRFv2Plus$/^Link_Billing$ + - id: smoke/vrfv2plus_test.go:^TestVRFv2Plus$/^Link_Billing$ path: integration-tests/smoke/vrfv2plus_test.go runs_on: ubuntu22.04-8cores-32GB test_env_type: docker @@ -673,33 +653,33 @@ runner-test-matrix: workflows: - On Demand VRFV2Plus Smoke Test (Ethereum clients) - - id: integration-tests/smoke/vrf_test.go:* + - id: smoke/vrf_test.go:* path: integration-tests/smoke/vrf_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/vrf_test.go -timeout 30m -count=1 -test.parallel=2 -json pyroscope_env: ci-smoke-vrf-evm-simulated - - id: integration-tests/smoke/vrfv2_test.go:* + - id: smoke/vrfv2_test.go:* path: integration-tests/smoke/vrfv2_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/vrfv2_test.go -timeout 30m -count=1 -test.parallel=6 -json pyroscope_env: ci-smoke-vrf2-evm-simulated - - id: integration-tests/smoke/vrfv2plus_test.go:* + - id: smoke/vrfv2plus_test.go:* path: integration-tests/smoke/vrfv2plus_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/vrfv2plus_test.go -timeout 30m -count=1 -test.parallel=9 -json pyroscope_env: ci-smoke-vrf2plus-evm-simulated @@ -707,83 +687,83 @@ runner-test-matrix: # START: LogPoller tests - - id: integration-tests/smoke/log_poller_test.go:^TestLogPollerFewFiltersFixedDepth$ + - id: smoke/log_poller_test.go:^TestLogPollerFewFiltersFixedDepth$ path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerFewFiltersFixedDepth$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated - - id: integration-tests/smoke/log_poller_test.go:^TestLogPollerFewFiltersFinalityTag$ + - id: smoke/log_poller_test.go:^TestLogPollerFewFiltersFinalityTag$ path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerFewFiltersFinalityTag$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated - - id: integration-tests/smoke/log_poller_test.go:^TestLogPollerWithChaosFixedDepth$ + - id: smoke/log_poller_test.go:^TestLogPollerWithChaosFixedDepth$ path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerWithChaosFixedDepth$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated - - id: integration-tests/smoke/log_poller_test.go:^TestLogPollerWithChaosFinalityTag$ + - id: smoke/log_poller_test.go:^TestLogPollerWithChaosFinalityTag$ path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerWithChaosFinalityTag$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated - - id: integration-tests/smoke/log_poller_test.go:^TestLogPollerWithChaosPostgresFinalityTag$ + - id: smoke/log_poller_test.go:^TestLogPollerWithChaosPostgresFinalityTag$ path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerWithChaosPostgresFinalityTag$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated - - id: integration-tests/smoke/log_poller_test.go:^TestLogPollerWithChaosPostgresFixedDepth$ + - id: smoke/log_poller_test.go:^TestLogPollerWithChaosPostgresFixedDepth$ path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerWithChaosPostgresFixedDepth$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated - - id: integration-tests/smoke/log_poller_test.go:^TestLogPollerReplayFixedDepth$ + - id: smoke/log_poller_test.go:^TestLogPollerReplayFixedDepth$ path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerReplayFixedDepth$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated - - id: integration-tests/smoke/log_poller_test.go:^TestLogPollerReplayFinalityTag$ + - id: smoke/log_poller_test.go:^TestLogPollerReplayFinalityTag$ path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerReplayFinalityTag$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated @@ -791,58 +771,188 @@ runner-test-matrix: # START: Other tests - - id: integration-tests/smoke/runlog_test.go:* + - id: smoke/runlog_test.go:* path: integration-tests/smoke/runlog_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests - test_cmd: cd integration-tests/ && go test smoke/runlog_test.go -timeout 30m -count=1 -json + - PR E2E Core Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ && go test smoke/runlog_test.go -timeout 30m -test.parallel=2 -count=1 -json pyroscope_env: ci-smoke-runlog-evm-simulated - - id: integration-tests/smoke/cron_test.go:* + - id: smoke/cron_test.go:* path: integration-tests/smoke/cron_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/cron_test.go -timeout 30m -count=1 -json pyroscope_env: ci-smoke-cron-evm-simulated - - id: integration-tests/smoke/flux_test.go:* + - id: smoke/flux_test.go:* path: integration-tests/smoke/flux_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/flux_test.go -timeout 30m -count=1 -json pyroscope_env: ci-smoke-flux-evm-simulated - - id: integration-tests/smoke/reorg_above_finality_test.go:* + - id: smoke/reorg_above_finality_test.go:* path: integration-tests/smoke/reorg_above_finality_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/reorg_above_finality_test.go -timeout 30m -count=1 -json pyroscope_env: ci-smoke-reorg-above-finality-evm-simulated - - id: integration-tests/migration/upgrade_version_test.go:* + - id: migration/upgrade_version_test.go:* path: integration-tests/migration/upgrade_version_test.go test_env_type: docker runs_on: ubuntu-latest workflows: - - Run PR E2E Tests - - Run Nightly E2E Tests + - PR E2E Core Tests + - Nightly E2E Tests test_cmd: cd integration-tests/migration && go test upgrade_version_test.go -timeout 30m -count=1 -test.parallel=2 -json - test_inputs: - chainlink_image: public.ecr.aws/chainlink/chainlink - chainlink_version: '{{ env.LATEST_CHAINLINK_RELEASE_VERSION }}' - chainlink_upgrade_image: '{{ env.QA_CHAINLINK_IMAGE }}' - chainlink_upgrade_version: develop + test_env_vars: + E2E_TEST_CHAINLINK_IMAGE: public.ecr.aws/chainlink/chainlink + E2E_TEST_CHAINLINK_VERSION: '{{ env.LATEST_CHAINLINK_RELEASE_VERSION }}' + E2E_TEST_CHAINLINK_UPGRADE_IMAGE: '{{ env.QA_CHAINLINK_IMAGE }}' + E2E_TEST_CHAINLINK_UPGRADE_VERSION: '{{ env.GITHUB_SHA }}' # END: Other tests + + # START: CCIP tests + + - id: ccip-smoke + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + + - id: ccip-smoke-1.4-pools + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/contract-version1.4.toml + + - id: ccip-smoke-usdc + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/usdc_mock_deployment.toml + + - id: ccip-smoke-db-compatibility + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/db-compatibility.toml + + - id: ccip-smoke-leader-lane + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + # Leader lane test is flakey in Core repo - Need to fix CCIP-3074 to enable it. + workflows: + # - PR E2E CCIP Tests + # - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/leader-lane.toml + + - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPTokenPoolRateLimits$ + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPTokenPoolRateLimits$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + + - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPMulticall$ + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPMulticall$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + + - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPManuallyExecuteAfterExecutionFailingDueToInsufficientGas$ + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPManuallyExecuteAfterExecutionFailingDueToInsufficientGas$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + + - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPOnRampLimits$ + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPOnRampLimits$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + + - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPOffRampCapacityLimit$ + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPOffRampCapacityLimit$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + + - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPOffRampAggRateLimit$ + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPOffRampAggRateLimit$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + + # END: CCIP tests \ No newline at end of file diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 500966c6a2..8a96a66a68 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -92,7 +92,7 @@ jobs: id: changes with: filters: | - changes: + core_changes: - '**/*.go' - '**/*go.sum' - '**/*go.mod' @@ -101,12 +101,9 @@ jobs: - 'core/**/migrations/*.sql' - 'core/**/config/**/*.toml' - 'integration-tests/**/*.toml' - ccip-changes: - - '.github/workflows/integration-tests.yml' - - 'integration-tests/**/*.toml' - - '**/*Dockerfile' + ccip_changes: - '**/*ccip*' - - '**/*ccip*/**' + - '**/*ccip*/**' - name: Ignore Filter On Workflow Dispatch if: ${{ github.event_name == 'workflow_dispatch' }} id: ignore-filter @@ -123,11 +120,11 @@ jobs: this-job-name: Check Paths That Require Tests To Run continue-on-error: true outputs: - src: ${{ steps.ignore-filter.outputs.changes || steps.changes.outputs.changes }} - ccip-changes: ${{ steps.ignore-filter.outputs.changes || steps.changes.outputs.ccip-changes }} + core_changes: ${{ steps.ignore-filter.outputs.changes || steps.changes.outputs.core_changes }} + ccip_changes: ${{ steps.ignore-filter.outputs.changes || steps.changes.outputs.ccip_changes }} - build-lint-integration-tests: - name: Build and Lint ${{ matrix.project.name }} + lint-integration-tests: + name: Lint ${{ matrix.project.name }} runs-on: ubuntu22.04-8cores-32GB # We don't directly merge dependabot PRs, so let's not waste the resources if: github.actor != 'dependabot[bot]' @@ -135,13 +132,13 @@ jobs: matrix: project: - name: integration-tests - id: e2e + id: e2e-tests path: ./integration-tests - cache-id: e2e + cache_id: e2e-tests - name: load id: load path: ./integration-tests/load - cache-id: load + cache_id: load steps: - name: Collect Metrics id: collect-gha-metrics @@ -151,7 +148,7 @@ jobs: org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build and Lint ${{ matrix.project.name }} + this-job-name: Lint ${{ matrix.project.name }} continue-on-error: true - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 @@ -159,17 +156,12 @@ jobs: repository: smartcontractkit/chainlink ref: ${{ inputs.cl_ref }} - name: Setup Go - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@0ce1e67b254a4f041e03cc6f0e3afc987b47c7bd # v2.3.30 with: test_download_vendor_packages_command: cd ${{ matrix.project.path }} && go mod download go_mod_path: ${{ matrix.project.path }}/go.mod - cache_key_id: core-${{ matrix.project.cache-id }}-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - - name: Build Go - run: | - cd ${{ matrix.project.path }} - go build ./... - go test -run=^# ./... + cache_key_id: ${{ matrix.project.cache_id }} + cache_restore_only: "true" - name: Lint Go uses: golangci/golangci-lint-action@3cfe3a4abbb849e10058ce4af15d205b6da42804 # v4.0.0 with: @@ -201,7 +193,7 @@ jobs: needs: [changes, enforce-ctf-version] steps: - name: Collect Metrics - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' + if: needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch' id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 with: @@ -226,7 +218,7 @@ jobs: aws-region: ${{ secrets.AWS_REGION }} set-git-config: "true" - name: Build Chainlink Image - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' + if: needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch' uses: ./.github/actions/build-chainlink-image with: tag_suffix: ${{ matrix.image.tag-suffix }} @@ -236,940 +228,126 @@ jobs: AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} dep_evm_sha: ${{ inputs.evm-ref }} - compare-tests: - needs: [changes] - runs-on: ubuntu-latest - name: Compare/Build Automation Test List - outputs: - automation-matrix: ${{ env.AUTOMATION_JOB_MATRIX_JSON }} - lp-matrix: ${{ env.LP_JOB_MATRIX_JSON }} - steps: - - name: Check for Skip Tests Label - if: contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') - run: | - echo "## \`skip-smoke-tests\` label is active, skipping E2E smoke tests" >>$GITHUB_STEP_SUMMARY - exit 0 - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref }} - - name: Compare Test Lists - run: | - cd ./integration-tests - ./scripts/compareTestList.sh ./smoke/automation_test.go - ./scripts/compareTestList.sh ./smoke/keeper_test.go - ./scripts/compareTestList.sh ./smoke/log_poller_test.go - - name: Build Test Matrix Lists - id: build-test-matrix-list - run: | - cd ./integration-tests - MATRIX_JSON_AUTOMATION=$(./scripts/buildTestMatrixList.sh ./smoke/automation_test.go automation ubuntu-latest 1) - MATRIX_JSON_KEEPER=$(./scripts/buildTestMatrixList.sh ./smoke/keeper_test.go keeper ubuntu-latest 1) - COMBINED_ARRAY=$(jq -c -n "$MATRIX_JSON_AUTOMATION + $MATRIX_JSON_KEEPER") - echo "combined array = ${COMBINED_ARRAY}" - echo "event name = $GITHUB_EVENT_NAME" - - LOG_POLLER_MATRIX_JSON=$(./scripts/buildTestMatrixList.sh ./smoke/log_poller_test.go log_poller ubuntu-latest 1) - echo "LP_JOB_MATRIX_JSON=${LOG_POLLER_MATRIX_JSON}" >> $GITHUB_ENV - - # if we running a PR against the develop branch we should only run the automation tests unless we are in the merge group event - if [[ "$GITHUB_EVENT_NAME" == "merge_group" ]]; then - echo "We are in a merge_group event, run both automation and keepers tests" - echo "AUTOMATION_JOB_MATRIX_JSON=${COMBINED_ARRAY}" >> $GITHUB_ENV - else - echo "we are not in a merge_group event, if this is a PR to develop run only automation tests, otherwise run everything because we could be running against a release branch" - target_branch=$(cat $GITHUB_EVENT_PATH | jq -r .pull_request.base.ref) - if [[ "$target_branch" == "develop" ]]; then - echo "only run automation tests" - echo "AUTOMATION_JOB_MATRIX_JSON=${MATRIX_JSON_AUTOMATION}" >> $GITHUB_ENV - else - echo "run both automation and keepers tests" - echo "AUTOMATION_JOB_MATRIX_JSON=${COMBINED_ARRAY}" >> $GITHUB_ENV - fi - fi - - eth-smoke-tests-matrix-automation: - if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: - [build-chainlink, changes, compare-tests, build-lint-integration-tests] - env: - SELECTED_NETWORKS: SIMULATED,SIMULATED_1,SIMULATED_2 - CHAINLINK_COMMIT_SHA: ${{ inputs.evm-ref || github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: debug - strategy: - fail-fast: false - matrix: - product: ${{fromJson(needs.compare-tests.outputs.automation-matrix)}} - runs-on: ${{ matrix.product.os }} - name: ETH Smoke Tests ${{ matrix.product.name }} - steps: - - name: Collect Metrics - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: ${{ env.COLLECTION_ID }}-matrix-${{ matrix.product.name }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - this-job-name: ETH Smoke Tests ${{ matrix.product.name }} - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Build Go Test Command - id: build-go-test-command - run: | - # if the matrix.product.run is set, use it for a different command - if [ "${{ matrix.product.run }}" != "" ]; then - echo "run_command=${{ matrix.product.run }} ./smoke/${{ matrix.product.file }}_test.go" >> "$GITHUB_OUTPUT" - else - echo "run_command=./smoke/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT" - fi - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - id: setup-gap - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - ## Run this step when changes that require tests to be run are made - - name: Run Tests - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 - with: - test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_config_chainlink_version: ${{ inputs.evm-ref || github.sha }} - test_config_selected_networks: ${{ env.SELECTED_NETWORKS }} - test_config_logging_run_id: ${{ github.run_id }} - test_config_logstream_log_targets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - test_config_test_log_collect: ${{ vars.TEST_LOG_COLLECT }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ inputs.evm-ref || github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: ${{ matrix.product.name }}-test-artifacts - artifacts_location: | - ./integration-tests/smoke/logs/ - ./integration-tests/smoke/db_dumps/ - ./integration-tests/smoke/seth_artifacts/ - /tmp/gotest.log - publish_check_name: ${{ matrix.product.name }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: "" - should_tidy: "false" - go_coverage_src_dir: /var/tmp/go-coverage - go_coverage_dest_dir: ${{ github.workspace }}/.covdata - DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - DEFAULT_PYROSCOPE_SERVER_URL: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - DEFAULT_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - DEFAULT_PYROSCOPE_ENVIRONMENT: ${{ matrix.product.pyroscope_env }} - DEFAULT_PYROSCOPE_ENABLED: ${{ matrix.product.pyroscope_env == '' || !startsWith(github.ref, 'refs/tags/') && 'false' || 'true' }} - - - name: Upload Coverage Data - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - timeout-minutes: 2 - continue-on-error: true - with: - name: cl-node-coverage-data-${{ matrix.product.name }} - path: .covdata - retention-days: 1 - - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@70ccaef155381025e411cf7cd1fa5ef8f668ed75 # v2.3.25 - - eth-smoke-tests-matrix-log-poller: - if: ${{ !(contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') || github.event_name == 'workflow_dispatch') || inputs.distinct_run_name != '' }} - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: - [build-chainlink, changes, compare-tests, build-lint-integration-tests] - env: - SELECTED_NETWORKS: SIMULATED,SIMULATED_1,SIMULATED_2 - CHAINLINK_COMMIT_SHA: ${{ inputs.evm-ref || github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: debug - strategy: - fail-fast: false - matrix: - product: ${{fromJson(needs.compare-tests.outputs.lp-matrix)}} - runs-on: ${{ matrix.product.os }} - name: ETH Smoke Tests ${{ matrix.product.name }} - steps: - - name: Collect Metrics - if: needs.changes.outputs.src == 'true' - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: ${{ env.COLLECTION_ID }}-matrix-${{ matrix.product.name }} - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ETH Smoke Tests ${{ matrix.product.name }} - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Build Go Test Command - id: build-go-test-command - run: | - # if the matrix.product.run is set, use it for a different command - if [ "${{ matrix.product.run }}" != "" ]; then - echo "run_command=${{ matrix.product.run }} ./smoke/${{ matrix.product.file }}_test.go" >> "$GITHUB_OUTPUT" - else - echo "run_command=./smoke/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT" - fi - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - id: setup-gap - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - ## Run this step when changes that require tests to be run are made - - name: Run Tests - if: needs.changes.outputs.src == 'true' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 - with: - test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_config_chainlink_version: ${{ inputs.evm-ref || github.sha }} - test_config_selected_networks: ${{ env.SELECTED_NETWORKS }} - test_config_logging_run_id: ${{ github.run_id }} - test_config_logstream_log_targets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - test_config_test_log_collect: ${{ vars.TEST_LOG_COLLECT }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ inputs.evm-ref || github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: ${{ matrix.product.name }}-test-artifacts - artifacts_location: | - ./integration-tests/smoke/logs/ - ./integration-tests/smoke/db_dumps/ - ./integration-tests/smoke/seth_artifacts/ - /tmp/gotest.log - publish_check_name: ${{ matrix.product.name }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: "" - should_tidy: "false" - go_coverage_src_dir: /var/tmp/go-coverage - go_coverage_dest_dir: ${{ github.workspace }}/.covdata - DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - DEFAULT_PYROSCOPE_SERVER_URL: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - DEFAULT_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - DEFAULT_PYROSCOPE_ENVIRONMENT: ${{ matrix.product.pyroscope_env }} - DEFAULT_PYROSCOPE_ENABLED: ${{ matrix.product.pyroscope_env == '' || !startsWith(github.ref, 'refs/tags/') && 'false' || 'true' }} - - - name: Upload Coverage Data - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - timeout-minutes: 2 - continue-on-error: true - with: - name: cl-node-coverage-data-${{ matrix.product.name }} - path: .covdata - retention-days: 1 - - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - - eth-smoke-tests-matrix-ccip: - if: steps.changes.outputs.ccip-changes == 'true' && ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} - environment: integration + run-core-e2e-tests-workflow: + name: Run Core E2E Tests permissions: actions: read checks: write pull-requests: write id-token: write contents: read - needs: [build-chainlink, changes, build-lint-integration-tests] - env: - SELECTED_NETWORKS: SIMULATED - CHAINLINK_COMMIT_SHA: ${{ inputs.evm-ref || github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: debug - strategy: - fail-fast: false - matrix: - product: - - name: ccip-smoke - nodes: 1 - os: ubuntu-latest - file: ccip - dir: ccip-tests/smoke - run: -run ^TestSmokeCCIPForBidirectionalLane$ - - name: ccip-smoke-1.4-pools - nodes: 1 - os: ubuntu-latest - file: ccip - dir: ccip-tests/smoke - run: -run ^TestSmokeCCIPForBidirectionalLane$ - config_path: ./integration-tests/ccip-tests/testconfig/tomls/contract-version1.4.toml - - name: ccip-smoke-usdc - nodes: 1 - os: ubuntu-latest - file: ccip - dir: ccip-tests/smoke - run: -run ^TestSmokeCCIPForBidirectionalLane$ - config_path: ./integration-tests/ccip-tests/testconfig/tomls/usdc_mock_deployment.toml - - name: ccip-smoke-db-compatibility - nodes: 1 - os: ubuntu-latest - file: ccip - dir: ccip-tests/smoke - run: -run ^TestSmokeCCIPForBidirectionalLane$ - config_path: ./integration-tests/ccip-tests/testconfig/tomls/db-compatibility.toml - - name: ccip-smoke-rate-limit - nodes: 1 - dir: ccip-tests/smoke - os: ubuntu-latest - file: ccip - run: -run ^TestSmokeCCIPRateLimit$ - - name: ccip-smoke-rate-limit - nodes: 1 - dir: ccip-tests/smoke - os: ubuntu-latest - file: ccip - run: -run ^TestSmokeCCIPTokenPoolRateLimits$ - - name: ccip-smoke-multicall - nodes: 1 - dir: ccip-tests/smoke - os: ubuntu-latest - file: ccip - run: -run ^TestSmokeCCIPMulticall$ - - name: ccip-smoke-manual-exec - nodes: 1 - dir: ccip-tests/smoke - os: ubuntu-latest - file: ccip - run: -run ^TestSmokeCCIPManuallyExecuteAfterExecutionFailingDueToInsufficientGas$ - - name: ccip-smoke-on-ramp-limits - nodes: 1 - dir: ccip-tests/smoke - os: ubuntu-latest - file: ccip - run: -run ^TestSmokeCCIPOnRampLimits$ - - name: ccip-smoke-off-ramp-capacity - nodes: 1 - dir: ccip-tests/smoke - os: ubuntu-latest - file: ccip - run: -run ^TestSmokeCCIPOffRampCapacityLimit$ - - name: ccip-smoke-off-ramp-agg-rate-limit - nodes: 1 - dir: ccip-tests/smoke - os: ubuntu-latest - file: ccip - run: -run ^TestSmokeCCIPOffRampAggRateLimit$ - - name: ccip-smoke-leader-lane - nodes: 15 - dir: ccip-tests/smoke - os: ubuntu-latest - file: ccip - run: -run ^TestSmokeCCIPForBidirectionalLane$ - config_path: ./integration-tests/ccip-tests/testconfig/tomls/leader-lane.toml - runs-on: ${{ matrix.product.os }} - name: ETH Smoke Tests ${{ matrix.product.name }}${{ matrix.product.tag_suffix }} - steps: - # Handy for debugging resource usage - # - name: Collect Workflow Telemetry - # uses: catchpoint/workflow-telemetry-action@v2 - - name: Collect Metrics - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: ${{ env.COLLECTION_ID }}-matrix-${{ matrix.product.id }} - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ETH Smoke Tests ${{ matrix.product.name }}${{ matrix.product.tag_suffix }} - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Build Go Test Command - id: build-go-test-command - run: | - # if dir is provided use it, otherwise use the smoke dir - if [ "${{ matrix.product.dir }}" != "" ]; then - dir=${{ matrix.product.dir }} - else - dir=smoke - fi - # if the matrix.product.run is set, use it for a different command - if [ "${{ matrix.product.run }}" != "" ]; then - echo "run_command=${{ matrix.product.run }} ./${dir}/${{ matrix.product.file }}_test.go" >> "$GITHUB_OUTPUT" - else - echo "run_command=./${dir}/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT" - fi - - name: Check for "enable tracing" label - id: check-label - run: | - label=$(jq -r '.pull_request.labels[]?.name // empty' "$GITHUB_EVENT_PATH") - - if [[ -n "$label" ]]; then - if [[ "$label" == "enable tracing" ]]; then - echo "Enable tracing label found." - echo "trace=true" >> $GITHUB_OUTPUT - else - echo "Enable tracing label not found." - echo "trace=false" >> $GITHUB_OUTPUT - fi - else - echo "No labels present or labels are null." - echo "trace=false" >> $GITHUB_OUTPUT - fi - - - name: Setup Grafana and OpenTelemetry - id: docker-setup - if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' - run: | - # Create network - docker network create --driver bridge tracing - - # Make trace directory - cd integration-tests/smoke/ - mkdir ./traces - chmod -R 777 ./traces - - # Switch directory - cd ../../.github/tracing - - # Create a Docker volume for traces - # docker volume create otel-traces - - # Start OpenTelemetry Collector - # Note the user must be set to the same user as the runner for the trace data to be accessible - docker run -d --network=tracing --name=otel-collector \ - -v $PWD/otel-collector-ci.yaml:/etc/otel-collector.yaml \ - -v $PWD/../../integration-tests/smoke/traces:/tracing \ - --user "$(id -u):$(id -g)" \ - -p 4317:4317 otel/opentelemetry-collector:0.88.0 --config=/etc/otel-collector.yaml - - - name: Locate Docker Volume - id: locate-volume - if: false - run: | - echo "VOLUME_PATH=$(docker volume inspect --format '{{ .Mountpoint }}' otel-traces)" >> $GITHUB_OUTPUT - - - name: Show Otel-Collector Logs - if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' - run: | - docker logs otel-collector - - - name: Set Override Config - id: set_override_config - run: | - # if the matrix.product.config_path is set, use it as the override config - if [ "${{ matrix.product.config_path }}" != "" ]; then - echo "base_64_override=$(base64 -w 0 -i ${{ matrix.product.config_path }})" >> "$GITHUB_OUTPUT" - fi - - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - id: setup-gap - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - - name: Prepare Base64 CCIP TOML secrets - uses: ./.github/actions/setup-create-base64-config-ccip - id: setup_create_base64_config_ccip - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - selectedNetworks: SIMULATED_1,SIMULATED_2 - chainlinkVersion: ${{ inputs.evm-ref || github.sha }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - - ## Run this step when changes that require tests to be run are made - - name: Run Tests - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - env: - BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} - TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 - with: - test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_config_chainlink_version: ${{ inputs.evm-ref || github.sha }} - test_config_selected_networks: ${{ env.SELECTED_NETWORKS }} - test_config_logging_run_id: ${{ github.run_id }} - test_config_logstream_log_targets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - test_config_test_log_collect: ${{ vars.TEST_LOG_COLLECT }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ inputs.evm-ref || github.sha }}${{ matrix.product.tag_suffix }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: ${{ matrix.product.name }}${{ matrix.product.tag_suffix }}-test-logs - artifacts_location: | - ./integration-tests/smoke/logs/ - ./integration-tests/smoke/db_dumps/ - /tmp/gotest.log - publish_check_name: ${{ matrix.product.name }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: "" - should_tidy: "false" - go_coverage_src_dir: /var/tmp/go-coverage - go_coverage_dest_dir: ${{ github.workspace }}/.covdata - DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - DEFAULT_PYROSCOPE_SERVER_URL: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - DEFAULT_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - DEFAULT_PYROSCOPE_ENVIRONMENT: ${{ matrix.product.pyroscope_env }} - DEFAULT_PYROSCOPE_ENABLED: ${{ matrix.product.pyroscope_env == '' || !startsWith(github.ref, 'refs/tags/') && 'false' || 'true' }} - - - name: Upload Coverage Data - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - timeout-minutes: 2 - continue-on-error: true - with: - name: cl-node-coverage-data-${{ matrix.product.name }}-${{ matrix.product.tag_suffix }} - path: .covdata - retention-days: 1 - - # Run this step when changes that do not need the test to run are made - - name: Run Setup - if: needs.changes.outputs.src == 'false' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_download_vendor_packages_command: cd ./integration-tests && go mod download - go_mod_path: ./integration-tests/go.mod - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: "" - should_tidy: "false" - - - name: Show Otel-Collector Logs - if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' - run: | - docker logs otel-collector - - - name: Permissions on traces - if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' - run: | - ls -l ./integration-tests/smoke/traces - - - name: Upload Trace Data - if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 - with: - name: trace-data - path: ./integration-tests/smoke/traces/trace-data.json - - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directories: ./integration-tests/smoke/ - - - eth-smoke-tests-matrix: - if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} - environment: integration + needs: [build-chainlink, changes] + if: needs.changes.outputs.core_changes == 'true' + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + workflow_name: Run Core E2E Tests + chainlink_version: ${{ inputs.evm-ref || github.sha }} + chainlink_upgrade_version: ${{ github.sha }} + test_workflow: PR E2E Core Tests + upload_cl_node_coverage_artifact: true + upload_cl_node_coverage_artifact_prefix: cl_node_coverage_data_ + enable_otel_traces_for_ocr2_plugins: ${{ contains(join(github.event.pull_request.labels.*.name, ' '), 'enable tracing') }} + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + + run-ccip-e2e-tests-workflow: + name: Run CCIP E2E Tests permissions: actions: read checks: write pull-requests: write id-token: write contents: read - needs: [build-chainlink, changes, build-lint-integration-tests] - env: - SELECTED_NETWORKS: SIMULATED - CHAINLINK_COMMIT_SHA: ${{ inputs.evm-ref || github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: debug - strategy: - fail-fast: false - matrix: - product: - - name: runlog - id: runlog - nodes: 2 - os: ubuntu-latest - pyroscope_env: "ci-smoke-runlog-evm-simulated" - - name: cron - id: cron - nodes: 2 - os: ubuntu-latest - pyroscope_env: "ci-smoke-cron-evm-simulated" - - name: flux - id: flux - nodes: 1 - os: ubuntu-latest - pyroscope_env: "ci-smoke-flux-evm-simulated" - - name: ocr - id: ocr - nodes: 2 - os: ubuntu-latest - file: ocr - pyroscope_env: ci-smoke-ocr-evm-simulated - - name: reorg_above_finality - id: reorg_above_finality - nodes: 1 - os: ubuntu-latest - file: reorg_above_finality - pyroscope_env: ci-smoke-reorg-above-finality-evm-simulated - - name: ocr2 - id: ocr2 - nodes: 6 - os: ubuntu22.04-16cores-64GB - file: ocr2 - pyroscope_env: ci-smoke-ocr2-evm-simulated - - name: ocr2 - id: ocr2-plugins - nodes: 6 - os: ubuntu22.04-16cores-64GB - pyroscope_env: ci-smoke-ocr2-plugins-evm-simulated - tag_suffix: "-plugins" - - name: vrf - id: vrf - nodes: 2 - os: ubuntu-latest - pyroscope_env: ci-smoke-vrf-evm-simulated - - name: vrfv2 - id: vrfv2 - nodes: 6 - os: ubuntu-latest - pyroscope_env: ci-smoke-vrf2-evm-simulated - - name: vrfv2plus - id: vrfv2plus - nodes: 9 - os: ubuntu-latest - pyroscope_env: ci-smoke-vrf2plus-evm-simulated - - name: forwarder_ocr - id: forwarder_ocr - nodes: 2 - os: ubuntu-latest - pyroscope_env: ci-smoke-forwarder-ocr-evm-simulated - - name: forwarders_ocr2 - id: forwarders_ocr2 - nodes: 2 - os: ubuntu-latest - pyroscope_env: ci-smoke-forwarder-ocr-evm-simulated - runs-on: ${{ matrix.product.os }} - name: ETH Smoke Tests ${{ matrix.product.name }}${{ matrix.product.tag_suffix }} + needs: [build-chainlink, changes] + if: needs.changes.outputs.ccip_changes == 'true' + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + workflow_name: Run CCIP E2E Tests + chainlink_version: ${{ inputs.evm-ref || github.sha }} + chainlink_upgrade_version: ${{ github.sha }} + test_workflow: PR E2E CCIP Tests + upload_cl_node_coverage_artifact: true + upload_cl_node_coverage_artifact_prefix: cl_node_coverage_data_ + enable_otel_traces_for_ocr2_plugins: ${{ contains(join(github.event.pull_request.labels.*.name, ' '), 'enable tracing') }} + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + + check-e2e-test-results: + if: always() + name: ETH Smoke Tests + runs-on: ubuntu-latest + needs: [run-core-e2e-tests-workflow, run-ccip-e2e-tests-workflow] steps: - # Handy for debugging resource usage - # - name: Collect Workflow Telemetry - # uses: catchpoint/workflow-telemetry-action@v2 - - name: Collect Metrics - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: ${{ env.COLLECTION_ID }}-matrix-${{ matrix.product.id }} - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ETH Smoke Tests ${{ matrix.product.name }}${{ matrix.product.tag_suffix }} - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Build Go Test Command - id: build-go-test-command + - name: Check Core test results + id: check_core_results run: | - # if dir is provided use it, otherwise use the smoke dir - if [ "${{ matrix.product.dir }}" != "" ]; then - dir=${{ matrix.product.dir }} - else - dir=smoke - fi - # if the matrix.product.run is set, use it for a different command - if [ "${{ matrix.product.run }}" != "" ]; then - echo "run_command=${{ matrix.product.run }} ./${dir}/${{ matrix.product.file }}_test.go" >> "$GITHUB_OUTPUT" - else - echo "run_command=./${dir}/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT" - fi - - name: Check for "enable tracing" label - id: check-label + results='${{ needs.run-core-e2e-tests-workflow.outputs.test_results }}' + echo "Core test results:" + echo "$results" | jq . + + node_migration_tests_failed=$(echo $results | jq '[.[] | select(.id == "integration-tests/migration/upgrade_version_test.go:*" ) | select(.result != "success")] | length > 0') + echo "node_migration_tests_failed=$node_migration_tests_failed" >> $GITHUB_OUTPUT + + - name: Check CCIP test results + id: check_ccip_results run: | - label=$(jq -r '.pull_request.labels[]?.name // empty' "$GITHUB_EVENT_PATH") - - if [[ -n "$label" ]]; then - if [[ "$label" == "enable tracing" ]]; then - echo "Enable tracing label found." - echo "trace=true" >> $GITHUB_OUTPUT - else - echo "Enable tracing label not found." - echo "trace=false" >> $GITHUB_OUTPUT - fi + if [[ '${{ needs.run-ccip-e2e-tests-workflow.result }}' != 'skipped' ]]; then + results='${{ needs.run-ccip-e2e-tests-workflow.outputs.test_results }}' + echo "CCIP test results:" + echo "$results" | jq . else - echo "No labels present or labels are null." - echo "trace=false" >> $GITHUB_OUTPUT + echo "CCIP tests were skipped." fi - - name: Setup Grafana and OpenTelemetry - id: docker-setup - if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' - run: | - # Create network - docker network create --driver bridge tracing - - # Make trace directory - cd integration-tests/smoke/ - mkdir ./traces - chmod -R 777 ./traces - - # Switch directory - cd ../../.github/tracing - - # Create a Docker volume for traces - # docker volume create otel-traces - - # Start OpenTelemetry Collector - # Note the user must be set to the same user as the runner for the trace data to be accessible - docker run -d --network=tracing --name=otel-collector \ - -v $PWD/otel-collector-ci.yaml:/etc/otel-collector.yaml \ - -v $PWD/../../integration-tests/smoke/traces:/tracing \ - --user "$(id -u):$(id -g)" \ - -p 4317:4317 otel/opentelemetry-collector:0.88.0 --config=/etc/otel-collector.yaml - - - name: Locate Docker Volume - id: locate-volume - if: false - run: | - echo "VOLUME_PATH=$(docker volume inspect --format '{{ .Mountpoint }}' otel-traces)" >> $GITHUB_OUTPUT - - - name: Show Otel-Collector Logs - if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' - run: | - docker logs otel-collector - - - name: Set Override Config - id: set_override_config - run: | - # if the matrix.product.config_path is set, use it as the override config - if [ "${{ matrix.product.config_path }}" != "" ]; then - echo "base_64_override=$(base64 -w 0 -i ${{ matrix.product.config_path }})" >> "$GITHUB_OUTPUT" - fi - - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - id: setup-gap - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - ## Run this step when changes that require tests to be run are made - - name: Run Tests - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 - with: - test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_config_chainlink_version: ${{ inputs.evm-ref || github.sha }} - test_config_selected_networks: ${{ env.SELECTED_NETWORKS }} - test_config_logging_run_id: ${{ github.run_id }} - test_config_logstream_log_targets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - test_config_test_log_collect: ${{ vars.TEST_LOG_COLLECT }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ inputs.evm-ref || github.sha }}${{ matrix.product.tag_suffix }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: ${{ matrix.product.name }}${{ matrix.product.tag_suffix }}-test-artifacts - artifacts_location: | - ./integration-tests/smoke/logs/ - ./integration-tests/smoke/db_dumps/ - ./integration-tests/smoke/seth_artifacts/ - /tmp/gotest.log - publish_check_name: ${{ matrix.product.name }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: "" - should_tidy: "false" - go_coverage_src_dir: /var/tmp/go-coverage - go_coverage_dest_dir: ${{ github.workspace }}/.covdata - DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - DEFAULT_PYROSCOPE_SERVER_URL: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - DEFAULT_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - DEFAULT_PYROSCOPE_ENVIRONMENT: ${{ matrix.product.pyroscope_env }} - DEFAULT_PYROSCOPE_ENABLED: ${{ matrix.product.pyroscope_env == '' || !startsWith(github.ref, 'refs/tags/') && 'false' || 'true' }} - - - name: Upload Coverage Data - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - timeout-minutes: 2 - continue-on-error: true - with: - name: cl-node-coverage-data-${{ matrix.product.name }}-${{ matrix.product.tag_suffix }} - path: .covdata - retention-days: 1 - - # Run this step when changes that do not need the test to run are made - - name: Run Setup - if: needs.changes.outputs.src == 'false' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_download_vendor_packages_command: cd ./integration-tests && go mod download - go_mod_path: ./integration-tests/go.mod - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: "" - should_tidy: "false" - - - name: Show Otel-Collector Logs - if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' - run: | - docker logs otel-collector - - - name: Permissions on traces - if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' - run: | - ls -l ./integration-tests/smoke/traces - - - name: Upload Trace Data - if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 - with: - name: trace-data - path: ./integration-tests/smoke/traces/trace-data.json - - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@70ccaef155381025e411cf7cd1fa5ef8f668ed75 # v2.3.25 - with: - test_directories: ./integration-tests/smoke/ - - ### Used to check the required checks box when the matrix completes - eth-smoke-tests: - if: always() - runs-on: ubuntu-latest - name: ETH Smoke Tests - needs: [eth-smoke-tests-matrix, eth-smoke-tests-matrix-automation, eth-smoke-tests-matrix-log-poller] - steps: - - name: Check smoke test matrix status - if: needs.eth-smoke-tests-matrix.result != 'success' || needs.eth-smoke-tests-matrix-automation.result != 'success' || needs.eth-smoke-tests-matrix-log-poller.result != 'success' - run: | - echo "ETH Smoke Tests: ${{ needs.eth-smoke-tests-matrix.result }}" - echo "Automation: ${{ needs.eth-smoke-tests-matrix-automation.result }}" - echo "Log Poller: ${{ needs.eth-smoke-tests-matrix-log-poller.result }}" - exit 1 - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 + - name: Send slack notification for failed migration tests + if: steps.check_core_results.outputs.node_migration_tests_failed == 'true' && github.event_name != 'workflow_dispatch' + uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 + env: + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} with: - id: ${{ env.COLLECTION_ID }}-matrix-results - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ETH Smoke Tests - matrix-aggregator-status: ${{ needs.eth-smoke-tests-matrix.result }} - continue-on-error: true + channel-id: "#team-test-tooling-internal" + slack-message: ":x: :mild-panic-intensifies: Node Migration Tests Failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}\n${{ format('Notifying ', secrets.GUARDIAN_SLACK_NOTIFICATION_HANDLE) }}" - eth-smoke-tests-ccip: - if: always() - runs-on: ubuntu-latest - name: ETH Smoke Tests CCIP - needs: eth-smoke-tests-matrix-ccip - steps: - - name: Check smoke test matrix status - if: needs.eth-smoke-tests-matrix-ccip.result != 'success' + - name: Fail the job if Core tests failed + if: always() && needs.run-core-e2e-tests-workflow.result == 'failure' run: | - echo "ETH Smoke Tests CCIP: ${{ needs.eth-smoke-tests-matrix-ccip.result }}" + echo "Core E2E tests failed" + echo "Job status:" + echo ${{ needs.run-core-e2e-tests-workflow.result }} exit 1 - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: ${{ env.COLLECTION_ID }}-matrix-results-ccip - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ETH Smoke Tests CCIP - matrix-aggregator-status: ${{ needs.eth-smoke-tests-matrix-ccip.result }} - continue-on-error: true cleanup: name: Clean up integration environment deployments if: always() - needs: [eth-smoke-tests] + needs: [run-core-e2e-tests-workflow, run-ccip-e2e-tests-workflow] runs-on: ubuntu-latest steps: - name: Checkout repo @@ -1198,10 +376,10 @@ jobs: this-job-name: Clean up integration environment deployments continue-on-error: true - show-coverage: + show-chainlink-node-coverage: name: Show Chainlink Node Go Coverage if: always() - needs: [cleanup] + needs: [run-core-e2e-tests-workflow, run-ccip-e2e-tests-workflow] runs-on: ubuntu-latest steps: - name: Checkout the repo @@ -1212,151 +390,11 @@ jobs: - name: Download All Artifacts uses: actions/download-artifact@9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395 # v4.1.6 with: - path: cl-node-coverage-data - pattern: cl-node-coverage-data-* + path: cl_node_coverage_data + pattern: cl_node_coverage_data_* merge-multiple: true - name: Show Coverage - run: go run ./integration-tests/scripts/show_coverage.go "${{ github.workspace }}/cl-node-coverage-data/*/merged" - - # Run the setup if the matrix finishes but this time save the cache if we have a cache hit miss - # this will also only run if both of the matrix jobs pass - eth-smoke-go-mod-cache: - environment: integration - needs: [eth-smoke-tests] - runs-on: ubuntu-latest - name: ETH Smoke Tests Go Mod Cache - continue-on-error: true - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Run Setup - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_download_vendor_packages_command: | - cd ./integration-tests - go mod download - # force download of test dependencies - go test -run=NonExistentTest ./smoke/... || echo "ignore expected test failure" - go_mod_path: ./integration-tests/go.mod - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "false" - - ### Migration tests - node-migration-tests: - name: Version Migration Tests - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - runs-on: ubuntu-latest - needs: [build-chainlink, changes] - # Only run migration tests on new tags - if: startsWith(github.ref, 'refs/tags/') - env: - SELECTED_NETWORKS: SIMULATED,SIMULATED_1,SIMULATED_2 - CHAINLINK_COMMIT_SHA: ${{ inputs.evm-ref || github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - CHAINLINK_IMAGE: public.ecr.aws/chainlink/chainlink - UPGRADE_VERSION: ${{ inputs.evm-ref || github.sha }} - UPGRADE_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - TEST_LOG_LEVEL: debug - TEST_SUITE: migration - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: ${{ env.COLLECTION_ID }}-migration-tests - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Version Migration Tests - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Get Latest Version - id: get_latest_version - run: | - untrimmed_ver=$(curl --header "Authorization: token ${{ secrets.GITHUB_TOKEN }}" --request GET https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r .name) - latest_version="${untrimmed_ver:1}" - # Check if latest_version is empty - if [ -z "$latest_version" ]; then - echo "Error: The latest_version is empty. The migration tests need a verison to run." - exit 1 - fi - echo "latest_version=${latest_version}" >> "$GITHUB_OUTPUT" - - name: Name Versions - run: | - echo "Running migration tests from version '${{ steps.get_latest_version.outputs.latest_version }}' to: '${{ inputs.evm-ref || github.sha }}'" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-upgrade-config - with: - selectedNetworks: ${{ env.SELECTED_NETWORKS }} - chainlinkVersion: ${{ steps.get_latest_version.outputs.latest_version }} - upgradeVersion: ${{ env.UPGRADE_VERSION }} - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - - name: Run Migration Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 - with: - test_command_to_run: cd ./integration-tests && go test -timeout 20m -count=1 -json ./migration 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ steps.get_latest_version.outputs.latest_version }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: node-migration-test-artifacts - artifacts_location: | - ./integration-tests/migration/logs - ./integration-tests/migration/db_dumps - ./integration-tests/migration/seth_artifacts - /tmp/gotest.log - publish_check_name: Node Migration Test Results - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: "" - go_coverage_src_dir: /var/tmp/go-coverage - go_coverage_dest_dir: ${{ github.workspace }}/.covdata - should_tidy: "false" - DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - DEFAULT_CHAINLINK_UPGRADE_IMAGE: ${{ env.UPGRADE_IMAGE }} - DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - - - name: Upload Coverage Data - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - timeout-minutes: 2 - continue-on-error: true - with: - name: cl-node-coverage-data-migration-tests - path: .covdata - retention-days: 1 - - name: Notify Slack - if: failure() && github.event_name != 'workflow_dispatch' - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - env: - SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - with: - channel-id: "#team-test-tooling-internal" - slack-message: ":x: :mild-panic-intensifies: Node Migration Tests Failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}\n${{ format('Notifying ', secrets.GUARDIAN_SLACK_NOTIFICATION_HANDLE) }}" + run: go run ./integration-tests/scripts/show_coverage.go "${{ github.workspace }}/cl_node_coverage_data/*/merged" ## Solana Section get_solana_sha: @@ -1439,7 +477,7 @@ jobs: steps: - name: Check if image exists id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@0ce1e67b254a4f041e03cc6f0e3afc987b47c7bd # v2.3.30 with: repository: chainlink-solana-tests tag: ${{ needs.get_solana_sha.outputs.sha }} @@ -1464,7 +502,7 @@ jobs: ] steps: - name: Collect Metrics - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' + if: needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch' id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 with: @@ -1480,7 +518,7 @@ jobs: repository: smartcontractkit/chainlink-solana ref: ${{ needs.get_solana_sha.outputs.sha }} - name: Build contracts - if: (needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch') && needs.solana-test-image-exists.outputs.exists == 'false' + if: (needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch') && needs.solana-test-image-exists.outputs.exists == 'false' uses: smartcontractkit/chainlink-solana/.github/actions/build_contract_artifacts@46b1311a5a83f33d08ffa8e1e0ab04f9ad51665d # node20 update on may 10, 2024 with: ref: ${{ needs.get_solana_sha.outputs.sha }} @@ -1507,7 +545,7 @@ jobs: CONTRACT_ARTIFACTS_PATH: contracts/target/deploy steps: - name: Collect Metrics - if: (needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch') && needs.solana-test-image-exists.outputs.exists == 'false' + if: (needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch') && needs.solana-test-image-exists.outputs.exists == 'false' id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 with: @@ -1518,13 +556,13 @@ jobs: this-job-name: Solana Build Test Image continue-on-error: true - name: Checkout the repo - if: (needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch') && needs.solana-test-image-exists.outputs.exists == 'false' + if: (needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch') && needs.solana-test-image-exists.outputs.exists == 'false' uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: repository: smartcontractkit/chainlink-solana ref: ${{ needs.get_solana_sha.outputs.sha }} - name: Build Test Image - if: (needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch') && needs.solana-test-image-exists.outputs.exists == 'false' + if: (needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch') && needs.solana-test-image-exists.outputs.exists == 'false' uses: ./.github/actions/build-test-image with: tag: ${{ needs.get_solana_sha.outputs.sha }} @@ -1533,7 +571,7 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - run: echo "this exists so we don't have to run anything else if the build is skipped" - if: needs.changes.outputs.src == 'false' || needs.solana-test-image-exists.outputs.exists == 'true' + if: needs.changes.outputs.core_changes == 'false' || needs.solana-test-image-exists.outputs.exists == 'true' solana-smoke-tests: if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} @@ -1560,7 +598,7 @@ jobs: CONTRACT_ARTIFACTS_PATH: contracts/target/deploy steps: - name: Collect Metrics - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' + if: needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch' id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 with: @@ -1577,8 +615,8 @@ jobs: repository: smartcontractkit/chainlink-solana ref: ${{ needs.get_solana_sha.outputs.sha }} - name: Run Setup - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 + if: needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch' + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@0ce1e67b254a4f041e03cc6f0e3afc987b47c7bd # v2.3.30 with: go_mod_path: ./integration-tests/go.mod cache_restore_only: true @@ -1590,7 +628,7 @@ jobs: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Pull Artifacts - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' + if: needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch' run: | IMAGE_NAME=${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-solana-tests:${{ needs.get_solana_sha.outputs.sha }} # Pull the Docker image @@ -1630,7 +668,7 @@ jobs: # shellcheck disable=SC2086 echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - name: Run Tests - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' + if: needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch' uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 with: test_command_to_run: export ENV_JOB_IMAGE=${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-solana-tests:${{ needs.get_solana_sha.outputs.sha }} && make test_smoke @@ -1660,7 +698,7 @@ jobs: timeout-minutes: 2 continue-on-error: true with: - name: cl-node-coverage-data-solana-tests + name: cl_node_coverage_data_solana_tests path: .covdata retention-days: 1 diff --git a/.github/workflows/run-automation-ondemand-e2e-tests.yml b/.github/workflows/run-automation-ondemand-e2e-tests.yml index 8dac3c5699..9e62b1557a 100644 --- a/.github/workflows/run-automation-ondemand-e2e-tests.yml +++ b/.github/workflows/run-automation-ondemand-e2e-tests.yml @@ -91,53 +91,53 @@ jobs: # Always run upgrade tests cat > test_list.yaml <> test_list.yaml <> test_list.yaml <> $GITHUB_OUTPUT - name: Generate K8s Tests Matrix id: set-k8s-runner-matrix run: | - cd integration-tests/citool - MATRIX_JSON=$(go run main.go filter --file ${{ github.workspace }}/.github/e2e-tests.yml --test-env-type 'k8s-remote-runner' --test-list '${{ inputs.test_list }}' --test-ids '${{ inputs.test_ids }}' --workflow '${{ inputs.test_workflow }}') + MATRIX_JSON=$(citool filter --file ${{ github.workspace }}/.github/e2e-tests.yml --test-env-type 'k8s-remote-runner' --test-list '${{ inputs.test_list }}' --test-ids '${{ inputs.test_ids }}' --workflow '${{ inputs.test_workflow }}') echo "K8s tests:" echo "$MATRIX_JSON" | jq echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT @@ -301,6 +343,11 @@ jobs: echo "No tests require secrets. Proceeding without additional secret setup." fi + - name: Generate random workflow id + id: gen_id + run: echo "workflow_id=$(uuidgen)" >> $GITHUB_OUTPUT + + # Build Chainlink images required for the tests require-chainlink-image-versions-in-qa-ecr: name: Build Chainlink image @@ -388,7 +435,7 @@ jobs: org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Run E2E Tests / Run ${{ matrix.tests.id }} + this-job-name: ${{ inputs.workflow_name }} / Run ${{ matrix.tests.id }} test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' continue-on-error: true @@ -398,8 +445,7 @@ jobs: run: sudo apt-get install -y jq - name: Show test configuration run: echo '${{ toJson(matrix.tests) }}' | jq . - - name: Setup Go - uses: ./.github/actions/setup-go + - name: Setup GAP for Grafana uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 id: setup-gap @@ -409,24 +455,65 @@ jobs: api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} duplicate-authorization-header: "true" + - name: Setup Grafana and OpenTelemetry + id: docker-setup + if: inputs.enable_otel_traces_for_ocr2_plugins && matrix.tests.test_env_vars.ENABLE_OTEL_TRACES == 'true' + run: | + # Create network + docker network create --driver bridge tracing + + # Make trace directory + cd integration-tests/smoke/ + mkdir ./traces + chmod -R 777 ./traces + + # Switch directory + cd ../../.github/tracing + + # Create a Docker volume for traces + # docker volume create otel-traces + + # Start OpenTelemetry Collector + # Note the user must be set to the same user as the runner for the trace data to be accessible + docker run -d --network=tracing --name=otel-collector \ + -v $PWD/otel-collector-ci.yaml:/etc/otel-collector.yaml \ + -v $PWD/../../integration-tests/smoke/traces:/tracing \ + --user "$(id -u):$(id -g)" \ + -p 4317:4317 otel/opentelemetry-collector:0.88.0 --config=/etc/otel-collector.yaml + - name: Run tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 + id: run_tests + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c164251be2a7c5b2b23a6e5f7014982f232c14 # v2.3.32 env: DETACH_RUNNER: true + E2E_TEST_CHAINLINK_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || inputs.chainlink_version || github.sha }} + E2E_TEST_CHAINLINK_UPGRADE_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_VERSION }} + E2E_TEST_CHAINLINK_POSTGRES_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_POSTGRES_VERSION }} + E2E_TEST_SELECTED_NETWORK: ${{ matrix.tests.test_env_vars.E2E_TEST_SELECTED_NETWORK || env.SELECTED_NETWORKS }} + E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} + E2E_TEST_LOG_STREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} + E2E_TEST_LOG_COLLECT: ${{ vars.TEST_LOG_COLLECT }} + E2E_TEST_CHAINLINK_IMAGE: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_IMAGE || env.CHAINLINK_IMAGE }} + E2E_TEST_CHAINLINK_UPGRADE_IMAGE: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_IMAGE }} + E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" + E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + E2E_TEST_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} + E2E_TEST_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} + E2E_TEST_PYROSCOPE_KEY: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_KEY || '' }} + E2E_TEST_PYROSCOPE_ENABLED: ${{ matrix.tests.pyroscope_env != '' && 'true' || '' }} with: test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs - test_download_vendor_packages_command: cd ./integration-tests && go mod download + test_download_vendor_packages_command: cd $(dirname ${{ matrix.tests.path }}) && go mod download test_secrets_override_base64: ${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }} + test_config_override_path: ${{ matrix.tests.test_config_override_path }} # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 # test_config_override_base64: ${{ inputs.test_config_override_base64 }} - test_config_chainlink_version: ${{ matrix.tests.test_inputs.chainlink_version || inputs.chainlink_version || github.sha }} - test_config_chainlink_upgrade_version: ${{ matrix.tests.test_inputs.chainlink_upgrade_version }} - test_config_chainlink_postgres_version: ${{ matrix.tests.test_inputs.chainlink_postgres_version }} - test_config_selected_networks: ${{ matrix.tests.test_inputs.selected_networks || env.SELECTED_NETWORKS}} - test_config_logging_run_id: ${{ github.run_id }} - test_config_logstream_log_targets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - test_type: ${{ matrix.tests.test_inputs.test_type }} - test_suite: ${{ matrix.tests.test_inputs.test_suite }} + test_type: ${{ matrix.tests.test_env_vars.TEST_TYPE }} + test_suite: ${{ matrix.tests.test_env_vars.TEST_SUITE }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_name: ${{ matrix.tests.id_sanitized }}-test-logs artifacts_location: | @@ -435,7 +522,7 @@ jobs: /tmp/gotest.log publish_check_name: ${{ matrix.tests.id_sanitized }} token: ${{ secrets.GH_TOKEN }} - no_cache: true # Do not restore cache since go was already configured in the previous step + cache_key_id: e2e-tests go_mod_path: ./integration-tests/go.mod QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} @@ -443,19 +530,24 @@ jobs: should_tidy: "false" go_coverage_src_dir: /var/tmp/go-coverage go_coverage_dest_dir: ${{ github.workspace }}/.covdata - DEFAULT_CHAINLINK_IMAGE: ${{ matrix.tests.test_inputs.chainlink_image || env.CHAINLINK_IMAGE }} - DEFAULT_CHAINLINK_UPGRADE_IMAGE: ${{ matrix.tests.test_inputs.chainlink_upgrade_image }} - DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - DEFAULT_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} - DEFAULT_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} - DEFAULT_PYROSCOPE_KEY: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_KEY || '' }} - DEFAULT_PYROSCOPE_ENABLED: ${{ matrix.tests.pyroscope_env != '' && 'true' || '' }} + - name: Show Otel-Collector logs + if: inputs.enable_otel_traces_for_ocr2_plugins && matrix.tests.test_env_vars.ENABLE_OTEL_TRACES == 'true' + run: | + docker logs otel-collector + + - name: Permissions on traces + if: inputs.enable_otel_traces_for_ocr2_plugins && matrix.tests.test_env_vars.ENABLE_OTEL_TRACES == 'true' + run: | + ls -l ./integration-tests/smoke/traces + + - name: Upload trace data as Github artifact + if: inputs.enable_otel_traces_for_ocr2_plugins && matrix.tests.test_env_vars.ENABLE_OTEL_TRACES == 'true' + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + with: + name: trace-data + path: ./integration-tests/smoke/traces/trace-data.json + - name: Upload test log as Github artifact uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 if: inputs.test_log_upload_on_failure && failure() @@ -464,6 +556,35 @@ jobs: path: /tmp/gotest.log retention-days: ${{ inputs.test_log_upload_retention_days }} continue-on-error: true + + - name: Upload cl node coverage data as Github artifact + if: inputs.upload_cl_node_coverage_artifact + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + timeout-minutes: 2 + continue-on-error: true + with: + name: ${{ inputs.upload_cl_node_coverage_artifact_prefix }}${{ matrix.tests.id_sanitized }} + path: .covdata + retention-days: 1 + + - name: Record test result + if: ${{ always() }} + run: | + id="${{ matrix.tests.id }}" + result="${{ steps.run_tests.outcome }}" + echo "{\"id\": \"$id\", \"result\": \"$result\"}" > test_result.json + + - name: Upload test result as artifact + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: test_result_${{ needs.load-test-configurations.outputs.workflow_id }}_${{ matrix.tests.id_sanitized }} + path: test_result.json + retention-days: 1 + + - name: Print failed test summary + if: always() + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@70ccaef155381025e411cf7cd1fa5ef8f668ed75 # v2.3.25 + # Run K8s tests using old remote runner @@ -529,7 +650,7 @@ jobs: org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Run E2E Tests / Run ${{ matrix.tests.id }} + this-job-name: ${{ inputs.workflow_name }} / Run ${{ matrix.tests.id }} continue-on-error: true - name: Checkout repository @@ -543,7 +664,8 @@ jobs: echo "Remote Runner Version: ${{ needs.prepare-remote-runner-test-image.outputs.remote-runner-version }}" - name: Run tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 + id: run_tests + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c164251be2a7c5b2b23a6e5f7014982f232c14 # v2.3.32 env: DETACH_RUNNER: true RR_MEM: ${{ matrix.tests.remote_runner_memory }} @@ -553,44 +675,42 @@ jobs: # We can comment these out when we have a stable soak test and aren't worried about resource consumption TEST_UPLOAD_CPU_PROFILE: true TEST_UPLOAD_MEM_PROFILE: true - TEST_LOG_LEVEL: debug REF_NAME: ${{ github.head_ref || github.ref_name }} + E2E_TEST_CHAINLINK_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || inputs.chainlink_version || github.sha }} + E2E_TEST_CHAINLINK_UPGRADE_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_VERSION }} + E2E_TEST_CHAINLINK_POSTGRES_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_POSTGRES_VERSION }} + E2E_TEST_SELECTED_NETWORK: ${{ matrix.tests.test_env_vars.E2E_TEST_SELECTED_NETWORK || env.SELECTED_NETWORKS }} + E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} + E2E_TEST_LOG_STREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} + E2E_TEST_LOG_COLLECT: ${{ vars.TEST_LOG_COLLECT }} + E2E_TEST_CHAINLINK_IMAGE: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_IMAGE || env.CHAINLINK_IMAGE }} + E2E_TEST_CHAINLINK_UPGRADE_IMAGE: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_IMAGE }} + E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" + E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + E2E_TEST_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} + E2E_TEST_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} + E2E_TEST_PYROSCOPE_KEY: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_KEY || '' }} + E2E_TEST_PYROSCOPE_ENABLED: ${{ matrix.tests.pyroscope_env != '' && 'true' || '' }} with: test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: make gomod test_secrets_override_base64: ${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }} - # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 - # test_config_override_base64: ${{ inputs.test_config_override_base64 }} - test_config_chainlink_version: ${{ matrix.tests.test_inputs.chainlink_version || inputs.chainlink_version || github.sha }} - test_config_chainlink_upgrade_version: ${{ matrix.tests.test_inputs.chainlink_upgrade_version }} - test_config_chainlink_postgres_version: ${{ matrix.tests.test_inputs.chainlink_postgres_version }} - test_config_selected_networks: ${{ matrix.tests.test_inputs.selected_networks || env.SELECTED_NETWORKS}} - test_config_logging_run_id: ${{ github.run_id }} - test_config_logstream_log_targets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - test_type: ${{ matrix.tests.test_inputs.test_type }} - test_suite: ${{ matrix.tests.test_inputs.test_suite }} + test_type: ${{ matrix.tests.test_env_vars.TEST_TYPE }} + test_suite: ${{ matrix.tests.test_env_vars.TEST_SUITE }} token: ${{ secrets.GH_TOKEN }} should_cleanup: false - no_cache: true # Do not restore cache since go was already configured in the previous step + cache_key_id: e2e-tests go_mod_path: ./integration-tests/go.mod QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - DEFAULT_CHAINLINK_IMAGE: ${{ matrix.tests.test_inputs.chainlink_image || env.CHAINLINK_IMAGE }} - DEFAULT_CHAINLINK_UPGRADE_IMAGE: ${{ matrix.tests.test_inputs.chainlink_upgrade_image }} - DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - DEFAULT_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} - DEFAULT_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} - DEFAULT_PYROSCOPE_KEY: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_KEY || '' }} - DEFAULT_PYROSCOPE_ENABLED: ${{ matrix.tests.pyroscope_env != '' && 'true' || '' }} - name: Upload test log as Github artifact - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 if: inputs.test_log_upload_on_failure && failure() with: name: test_log_${{ matrix.tests.id_sanitized }} @@ -598,41 +718,40 @@ jobs: retention-days: ${{ inputs.test_log_upload_retention_days }} continue-on-error: true + # TODO: move to run-tests GHA + - name: Print failed test summary + if: always() + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@70ccaef155381025e411cf7cd1fa5ef8f668ed75 # v2.3.25 + after_tests: - needs: [run-docker-tests, run-k8s-runner-tests] + needs: [load-test-configurations, run-docker-tests, run-k8s-runner-tests] if: always() - name: After tests notifications + name: After tests runs-on: ubuntu-latest + outputs: + test_results: ${{ steps.set_test_results.outputs.results }} steps: - - name: Determine combined test results - id: combine_results + - name: Download all test result artifacts + uses: actions/download-artifact@9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395 # v4.1.6 + with: + path: test_results + pattern: test_result_${{ needs.load-test-configurations.outputs.workflow_id }}_* + + - name: Set detailed test results + id: set_test_results run: | - docker_result="${{ needs.run-docker-tests.result }}" - k8s_result="${{ needs.run-k8s-runner-tests.result }}" - - function map_outcome { - case "$1" in - success|skipped) - echo "success" - ;; - cancelled) - echo "cancelled" - ;; - *) - echo "failure" - ;; - esac - } - - combined_docker_result=$(map_outcome $docker_result) - combined_k8s_result=$(map_outcome $k8s_result) - - if [[ $combined_docker_result == "failure" || $combined_k8s_result == "failure" ]]; then - echo "result=failure" >> $GITHUB_OUTPUT - elif [[ $combined_docker_result == "cancelled" || $combined_k8s_result == "cancelled" ]]; then - echo "result=cancelled" >> $GITHUB_OUTPUT + if [ -d "test_results" ]; then + cd test_results + ls -R . + # Combine JSON files into one + find . -name '*.json' -exec cat {} + | jq -s '.' > test_results.json + # Display the combined JSON + jq . test_results.json + # Set the combined results as an output + echo "results=$(jq -c . test_results.json)" >> $GITHUB_OUTPUT else - echo "result=success" >> $GITHUB_OUTPUT + echo "No test results directory found." + echo "results=[]" >> $GITHUB_OUTPUT fi - name: Send Slack notification diff --git a/.gitignore b/.gitignore index 00962a94a3..bd7a6b72cd 100644 --- a/.gitignore +++ b/.gitignore @@ -74,7 +74,6 @@ db_dumps/ integration-tests/**/traces/ benchmark_report.csv benchmark_summary.json -integration-tests/citool/output.csv secrets.toml tmp_laneconfig/ diff --git a/integration-tests/ccip-tests/testconfig/global.go b/integration-tests/ccip-tests/testconfig/global.go index a1658a4841..25e87bac2a 100644 --- a/integration-tests/ccip-tests/testconfig/global.go +++ b/integration-tests/ccip-tests/testconfig/global.go @@ -174,6 +174,36 @@ type Common struct { func (p *Common) ReadFromEnvVar() error { logger := logging.GetTestLogger(nil) + testLogCollect := ctfconfig.MustReadEnvVar_Boolean(ctfconfig.E2E_TEST_LOG_COLLECT_ENV) + if testLogCollect != nil { + if p.Logging == nil { + p.Logging = &ctfconfig.LoggingConfig{} + } + logger.Debug().Msgf("Using %s env var to override Logging.TestLogCollect", ctfconfig.E2E_TEST_LOG_COLLECT_ENV) + p.Logging.TestLogCollect = testLogCollect + } + + loggingRunID := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_LOGGING_RUN_ID_ENV) + if loggingRunID != "" { + if p.Logging == nil { + p.Logging = &ctfconfig.LoggingConfig{} + } + logger.Debug().Msgf("Using %s env var to override Logging.RunID", ctfconfig.E2E_TEST_LOGGING_RUN_ID_ENV) + p.Logging.RunId = &loggingRunID + } + + logstreamLogTargets := ctfconfig.MustReadEnvVar_Strings(ctfconfig.E2E_TEST_LOG_STREAM_LOG_TARGETS_ENV, ",") + if len(logstreamLogTargets) > 0 { + if p.Logging == nil { + p.Logging = &ctfconfig.LoggingConfig{} + } + if p.Logging.LogStream == nil { + p.Logging.LogStream = &ctfconfig.LogStreamConfig{} + } + logger.Debug().Msgf("Using %s env var to override Logging.LogStream.LogTargets", ctfconfig.E2E_TEST_LOG_STREAM_LOG_TARGETS_ENV) + p.Logging.LogStream.LogTargets = logstreamLogTargets + } + lokiTenantID := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_LOKI_TENANT_ID_ENV) if lokiTenantID != "" { if p.Logging == nil { @@ -258,6 +288,15 @@ func (p *Common) ReadFromEnvVar() error { p.Logging.Grafana.BearerToken = &grafanaBearerToken } + selectedNetworks := ctfconfig.MustReadEnvVar_Strings(ctfconfig.E2E_TEST_SELECTED_NETWORK_ENV, ",") + if len(selectedNetworks) > 0 { + if p.Network == nil { + p.Network = &ctfconfig.NetworkConfig{} + } + logger.Debug().Msgf("Using %s env var to override Network.SelectedNetworks", ctfconfig.E2E_TEST_SELECTED_NETWORK_ENV) + p.Network.SelectedNetworks = selectedNetworks + } + walletKeys := ctfconfig.ReadEnvVarGroupedMap(ctfconfig.E2E_TEST_WALLET_KEY_ENV, ctfconfig.E2E_TEST_WALLET_KEYS_ENV) if len(walletKeys) > 0 { if p.Network == nil { @@ -301,6 +340,38 @@ func (p *Common) ReadFromEnvVar() error { p.NewCLCluster.Common.ChainlinkImage.Image = &chainlinkImage } + chainlinkVersion := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_CHAINLINK_VERSION_ENV) + if chainlinkVersion != "" { + if p.NewCLCluster == nil { + p.NewCLCluster = &ChainlinkDeployment{} + } + if p.NewCLCluster.Common == nil { + p.NewCLCluster.Common = &Node{} + } + if p.NewCLCluster.Common.ChainlinkImage == nil { + p.NewCLCluster.Common.ChainlinkImage = &ctfconfig.ChainlinkImageConfig{} + } + + logger.Debug().Msgf("Using %s env var to override NewCLCluster.Common.ChainlinkImage.Version", ctfconfig.E2E_TEST_CHAINLINK_VERSION_ENV) + p.NewCLCluster.Common.ChainlinkImage.Version = &chainlinkVersion + } + + chainlinkPostgresVersion := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_CHAINLINK_POSTGRES_VERSION_ENV) + if chainlinkPostgresVersion != "" { + if p.NewCLCluster == nil { + p.NewCLCluster = &ChainlinkDeployment{} + } + if p.NewCLCluster.Common == nil { + p.NewCLCluster.Common = &Node{} + } + if p.NewCLCluster.Common.ChainlinkImage == nil { + p.NewCLCluster.Common.ChainlinkImage = &ctfconfig.ChainlinkImageConfig{} + } + + logger.Debug().Msgf("Using %s env var to override NewCLCluster.Common.ChainlinkImage.PostgresVersion", ctfconfig.E2E_TEST_CHAINLINK_POSTGRES_VERSION_ENV) + p.NewCLCluster.Common.ChainlinkImage.PostgresVersion = &chainlinkPostgresVersion + } + chainlinkUpgradeImage := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_CHAINLINK_UPGRADE_IMAGE_ENV) if chainlinkUpgradeImage != "" { if p.NewCLCluster == nil { @@ -317,6 +388,22 @@ func (p *Common) ReadFromEnvVar() error { p.NewCLCluster.Common.ChainlinkUpgradeImage.Image = &chainlinkUpgradeImage } + chainlinkUpgradeVersion := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_CHAINLINK_UPGRADE_VERSION_ENV) + if chainlinkUpgradeVersion != "" { + if p.NewCLCluster == nil { + p.NewCLCluster = &ChainlinkDeployment{} + } + if p.NewCLCluster.Common == nil { + p.NewCLCluster.Common = &Node{} + } + if p.NewCLCluster.Common.ChainlinkImage == nil { + p.NewCLCluster.Common.ChainlinkImage = &ctfconfig.ChainlinkImageConfig{} + } + + logger.Debug().Msgf("Using %s env var to override NewCLCluster.Common.ChainlinkUpgradeImage.Version", ctfconfig.E2E_TEST_CHAINLINK_UPGRADE_VERSION_ENV) + p.NewCLCluster.Common.ChainlinkUpgradeImage.Version = &chainlinkUpgradeVersion + } + return nil } diff --git a/integration-tests/citool/cmd/check_tests_cmd.go b/integration-tests/citool/cmd/check_tests_cmd.go deleted file mode 100644 index 3ef3712a57..0000000000 --- a/integration-tests/citool/cmd/check_tests_cmd.go +++ /dev/null @@ -1,166 +0,0 @@ -package cmd - -import ( - "fmt" - "os" - "path/filepath" - "regexp" - "strings" - - "github.com/spf13/cobra" - "gopkg.in/yaml.v3" -) - -type JobConfig struct { - Jobs map[string]struct { - Strategy struct { - Matrix struct { - Test []struct { - Path string `yaml:"path"` - TestOpts string `yaml:"testOpts"` - } `yaml:"test"` - } `yaml:"matrix"` - } `yaml:"strategy"` - } `yaml:"jobs"` -} - -var checkTestsCmd = &cobra.Command{ - Use: "check-tests [directory] [yaml file]", - Short: "Check if all tests in a directory are included in the test configurations YAML file", - Args: cobra.ExactArgs(2), - Run: func(_ *cobra.Command, args []string) { - directory := args[0] - yamlFile := args[1] - excludedDirs := []string{"../../citool"} - tests, err := extractTests(directory, excludedDirs) - if err != nil { - fmt.Println("Error extracting tests:", err) - os.Exit(1) - } - - checkTestsInPipeline(yamlFile, tests) - }, -} - -// extractTests scans the given directory and subdirectories (except the excluded ones) -// for Go test files, extracts test function names, and returns a slice of Test. -func extractTests(dir string, excludeDirs []string) ([]Test, error) { - var tests []Test - - // Resolve to absolute path - absDir, err := filepath.Abs(dir) - if err != nil { - return nil, err - } - - // filepath.WalkDir provides more control and is more efficient for skipping directories - err = filepath.WalkDir(absDir, func(path string, d os.DirEntry, err error) error { - if err != nil { - return err - } - - // Check if the current path is one of the excluded directories - for _, exclude := range excludeDirs { - absExclude, _ := filepath.Abs(exclude) - if strings.HasPrefix(path, absExclude) { - if d.IsDir() { - return filepath.SkipDir // Skip this directory - } - return nil // Skip this file - } - } - - if !d.IsDir() && strings.HasSuffix(d.Name(), "_test.go") { - content, err := os.ReadFile(path) - if err != nil { - return err - } - re := regexp.MustCompile(`func (Test\w+)`) - matches := re.FindAllSubmatch(content, -1) - for _, match := range matches { - funcName := string(match[1]) - if funcName == "TestMain" { // Skip "TestMain" - continue - } - tests = append(tests, Test{ - Name: funcName, - Path: mustExtractSubpath(path, "integration-tests"), - }) - } - } - return nil - }) - - return tests, err -} - -// ExtractSubpath extracts a specific subpath from a given full path. -// If the subpath is not found, it returns an error. -func mustExtractSubpath(fullPath, subPath string) string { - index := strings.Index(fullPath, subPath) - if index == -1 { - panic("subpath not found in the provided full path") - } - return fullPath[index:] -} - -func checkTestsInPipeline(yamlFile string, tests []Test) { - data, err := os.ReadFile(yamlFile) - if err != nil { - fmt.Printf("Error reading YAML file: %s\n", err) - return - } - - var config Config - err = yaml.Unmarshal(data, &config) - if err != nil { - fmt.Printf("Error parsing YAML: %s\n", err) - return - } - - missingTests := []string{} // Track missing tests - - for _, test := range tests { - found := false - for _, item := range config.Tests { - if item.Path == test.Path { - if strings.Contains(item.TestCmd, "-test.run") { - if matchTestNameInCmd(item.TestCmd, test.Name) { - found = true - break - } - } else { - found = true - break - } - } - } - if !found { - missingTests = append(missingTests, fmt.Sprintf("ERROR: Test '%s' in file '%s' does not have CI configuration in '%s'", test.Name, test.Path, yamlFile)) - } - } - - if len(missingTests) > 0 { - for _, missing := range missingTests { - fmt.Println(missing) - } - os.Exit(1) // Exit with a failure status - } -} - -// matchTestNameInCmd checks if the given test name matches the -test.run pattern in the command string. -func matchTestNameInCmd(cmd string, testName string) bool { - testRunRegex := regexp.MustCompile(`-test\.run ([^\s]+)`) - matches := testRunRegex.FindStringSubmatch(cmd) - if len(matches) > 1 { - // Extract the regex pattern used in the -test.run command - pattern := matches[1] - - // Escape regex metacharacters in the testName before matching - escapedTestName := regexp.QuoteMeta(testName) - - // Check if the escaped test name matches the extracted pattern - return regexp.MustCompile(pattern).MatchString(escapedTestName) - } - return false -} diff --git a/integration-tests/citool/cmd/check_tests_cmd_test.go b/integration-tests/citool/cmd/check_tests_cmd_test.go deleted file mode 100644 index 4b7f50e7f0..0000000000 --- a/integration-tests/citool/cmd/check_tests_cmd_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package cmd - -import ( - "testing" -) - -func TestMatchTestNameInCmd(t *testing.T) { - tests := []struct { - cmd string - testName string - expected bool - }{ - {"go test -test.run ^TestExample$", "TestExample", true}, - {"go test -test.run ^TestExample$", "TestAnother", false}, - {"go test -test.run ^TestExample$ -v", "TestExample", true}, - {"go test -test.run ^TestExamplePart$", "TestExample", false}, - {"go test -test.run ^TestWithNumbers123$", "TestWithNumbers123", true}, - {"go test -test.run ^Test_With_Underscores$", "Test_With_Underscores", true}, - {"go test -test.run ^Test-With-Dash$", "Test-With-Dash", true}, - {"go test -test.run ^TestWithSpace Space$", "TestWithSpace Space", true}, - {"go test -test.run ^TestWithNewline\nNewline$", "TestWithNewline\nNewline", true}, - {"go test -test.run ^TestOne$|^TestTwo$", "TestOne", true}, - {"go test -test.run ^TestOne$|^TestTwo$", "TestTwo", true}, - {"go test -test.run ^TestOne$|^TestTwo$", "TestThree", false}, - {"go test -test.run TestOne|TestTwo", "TestTwo", true}, - {"go test -test.run TestOne|TestTwo", "TestOne", true}, - {"go test -test.run TestOne|TestTwo|TestThree", "TestFour", false}, - {"go test -test.run ^TestOne$|TestTwo$", "TestTwo", true}, - {"go test -test.run ^TestOne$|TestTwo|TestThree$", "TestThree", true}, - {"go test -test.run TestOne|TestTwo|TestThree", "TestOne", true}, - {"go test -test.run TestOne|TestTwo|TestThree", "TestThree", true}, - {"go test -test.run ^TestA$|^TestB$|^TestC$", "TestA", true}, - {"go test -test.run ^TestA$|^TestB$|^TestC$", "TestB", true}, - {"go test -test.run ^TestA$|^TestB$|^TestC$", "TestD", false}, - {"go test -test.run TestA|^TestB$|TestC", "TestB", true}, - {"go test -test.run ^TestA|^TestB|TestC$", "TestA", true}, - {"go test -test.run ^TestA|^TestB|TestC$", "TestC", true}, - {"go test -test.run ^TestA|^TestB|TestC$", "TestD", false}, - } - - for _, tt := range tests { - result := matchTestNameInCmd(tt.cmd, tt.testName) - if result != tt.expected { - t.Errorf("matchTestNameInCmd(%s, %s) = %t; expected %t", tt.cmd, tt.testName, result, tt.expected) - } - } -} diff --git a/integration-tests/citool/cmd/create_test_config_cmd.go b/integration-tests/citool/cmd/create_test_config_cmd.go deleted file mode 100644 index c0cd91b05f..0000000000 --- a/integration-tests/citool/cmd/create_test_config_cmd.go +++ /dev/null @@ -1,179 +0,0 @@ -package cmd - -import ( - "fmt" - "os" - - "github.com/pelletier/go-toml/v2" - "github.com/spf13/cobra" - - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/config/types" -) - -var createTestConfigCmd = &cobra.Command{ - Use: "create", - Short: "Create a test config from the provided flags", - Run: func(cmd *cobra.Command, _ []string) { - var tc ctf_config.TestConfig - - var version, postgresVersion *string - if cmd.Flags().Changed(ChainlinkVersionFlag) { - version = &oc.ChainlinkVersion - } - if cmd.Flags().Changed(ChainlinkPostgresVersionFlag) { - version = &oc.ChainlinkPostgresVersion - } - if version != nil || postgresVersion != nil { - tc.ChainlinkImage = &ctf_config.ChainlinkImageConfig{ - Version: version, - PostgresVersion: postgresVersion, - } - } - - var upgradeVersion *string - if cmd.Flags().Changed(ChainlinkUpgradeVersionFlag) { - upgradeVersion = &oc.ChainlinkUpgradeVersion - } - if upgradeVersion != nil { - tc.ChainlinkUpgradeImage = &ctf_config.ChainlinkImageConfig{ - Version: upgradeVersion, - } - } - - var selectedNetworks *[]string - if cmd.Flags().Changed(SelectedNetworksFlag) { - selectedNetworks = &oc.SelectedNetworks - } - if selectedNetworks != nil { - tc.Network = &ctf_config.NetworkConfig{ - SelectedNetworks: oc.SelectedNetworks, - } - } - - var peryscopeEnabled *bool - var pyroscopeServerURL, pyroscopeEnvironment, pyroscopeKey *string - if cmd.Flags().Changed(PyroscopeEnabledFlag) { - peryscopeEnabled = &oc.PyroscopeEnabled - } - if cmd.Flags().Changed(PyroscopeServerURLFlag) { - pyroscopeServerURL = &oc.PyroscopeServerURL - } - if cmd.Flags().Changed(PyroscopeKeyFlag) { - pyroscopeKey = &oc.PyroscopeKey - } - if cmd.Flags().Changed(PyroscopeEnvironmentFlag) { - pyroscopeEnvironment = &oc.PyroscopeEnvironment - } - if peryscopeEnabled != nil { - tc.Pyroscope = &ctf_config.PyroscopeConfig{ - Enabled: peryscopeEnabled, - ServerUrl: pyroscopeServerURL, - Environment: pyroscopeEnvironment, - Key: pyroscopeKey, - } - } - - var testLogCollect *bool - if cmd.Flags().Changed(LoggingTestLogCollectFlag) { - testLogCollect = &oc.LoggingTestLogCollect - } - var loggingRunID *string - if cmd.Flags().Changed(LoggingRunIDFlag) { - loggingRunID = &oc.LoggingRunID - } - var loggingLogTargets []string - if cmd.Flags().Changed(LoggingLogTargetsFlag) { - loggingLogTargets = oc.LoggingLogTargets - } - var loggingLokiTenantID *string - if cmd.Flags().Changed(LoggingLokiTenantIDFlag) { - loggingLokiTenantID = &oc.LoggingLokiTenantID - } - var loggingLokiBasicAuth *string - if cmd.Flags().Changed(LoggingLokiBasicAuthFlag) { - loggingLokiBasicAuth = &oc.LoggingLokiBasicAuth - } - var loggingLokiEndpoint *string - if cmd.Flags().Changed(LoggingLokiEndpointFlag) { - loggingLokiEndpoint = &oc.LoggingLokiEndpoint - } - var loggingGrafanaBaseURL *string - if cmd.Flags().Changed(LoggingGrafanaBaseURLFlag) { - loggingGrafanaBaseURL = &oc.LoggingGrafanaBaseURL - } - var loggingGrafanaDashboardURL *string - if cmd.Flags().Changed(LoggingGrafanaDashboardURLFlag) { - loggingGrafanaDashboardURL = &oc.LoggingGrafanaDashboardURL - } - var loggingGrafanaBearerToken *string - if cmd.Flags().Changed(LoggingGrafanaBearerTokenFlag) { - loggingGrafanaBearerToken = &oc.LoggingGrafanaBearerToken - } - - if testLogCollect != nil || loggingRunID != nil || loggingLogTargets != nil || loggingLokiEndpoint != nil || loggingLokiTenantID != nil || loggingLokiBasicAuth != nil || loggingGrafanaBaseURL != nil || loggingGrafanaDashboardURL != nil || loggingGrafanaBearerToken != nil { - tc.Logging = &ctf_config.LoggingConfig{} - tc.Logging.TestLogCollect = testLogCollect - tc.Logging.RunId = loggingRunID - if loggingLogTargets != nil { - tc.Logging.LogStream = &ctf_config.LogStreamConfig{ - LogTargets: loggingLogTargets, - } - } - if loggingLokiTenantID != nil || loggingLokiBasicAuth != nil || loggingLokiEndpoint != nil { - tc.Logging.Loki = &ctf_config.LokiConfig{ - TenantId: loggingLokiTenantID, - BasicAuth: loggingLokiBasicAuth, - Endpoint: loggingLokiEndpoint, - } - } - if loggingGrafanaBaseURL != nil || loggingGrafanaDashboardURL != nil || loggingGrafanaBearerToken != nil { - tc.Logging.Grafana = &ctf_config.GrafanaConfig{ - BaseUrl: loggingGrafanaBaseURL, - DashboardUrl: loggingGrafanaDashboardURL, - BearerToken: loggingGrafanaBearerToken, - } - } - } - - var privateEthereumNetworkExecutionLayer *string - if cmd.Flags().Changed(PrivateEthereumNetworkExecutionLayerFlag) { - privateEthereumNetworkExecutionLayer = &oc.PrivateEthereumNetworkExecutionLayer - } - var privateEthereumNetworkEthereumVersion *string - if cmd.Flags().Changed(PrivateEthereumNetworkEthereumVersionFlag) { - privateEthereumNetworkEthereumVersion = &oc.PrivateEthereumNetworkEthereumVersion - } - var privateEthereumNetworkCustomDockerImage *string - if cmd.Flags().Changed(PrivateEthereumNetworkCustomDockerImageFlag) { - privateEthereumNetworkCustomDockerImage = &oc.PrivateEthereumNetworkCustomDockerImages - } - if privateEthereumNetworkExecutionLayer != nil || privateEthereumNetworkEthereumVersion != nil || privateEthereumNetworkCustomDockerImage != nil { - var el ctf_config_types.ExecutionLayer - if privateEthereumNetworkExecutionLayer != nil { - el = ctf_config_types.ExecutionLayer(*privateEthereumNetworkExecutionLayer) - } - var ev ctf_config_types.EthereumVersion - if privateEthereumNetworkEthereumVersion != nil { - ev = ctf_config_types.EthereumVersion(*privateEthereumNetworkEthereumVersion) - } - var customImages map[ctf_config.ContainerType]string - if privateEthereumNetworkCustomDockerImage != nil { - customImages = map[ctf_config.ContainerType]string{"execution_layer": *privateEthereumNetworkCustomDockerImage} - } - tc.PrivateEthereumNetwork = &ctf_config.EthereumNetworkConfig{ - ExecutionLayer: &el, - EthereumVersion: &ev, - CustomDockerImages: customImages, - } - } - - configToml, err := toml.Marshal(tc) - if err != nil { - fmt.Fprintf(os.Stderr, "Error marshalling TestConfig to TOML: %v\n", err) - os.Exit(1) - } - - fmt.Fprintln(cmd.OutOrStdout(), string(configToml)) - }, -} diff --git a/integration-tests/citool/cmd/csv_export_cmd.go b/integration-tests/citool/cmd/csv_export_cmd.go deleted file mode 100644 index 8fe13440c8..0000000000 --- a/integration-tests/citool/cmd/csv_export_cmd.go +++ /dev/null @@ -1,96 +0,0 @@ -package cmd - -import ( - "encoding/csv" - "fmt" - "os" - "strings" - - "github.com/spf13/cobra" - "gopkg.in/yaml.v3" -) - -var csvExportCmd = &cobra.Command{ - Use: "csvexport", - Short: "Export tests to CSV format", - Run: func(cmd *cobra.Command, _ []string) { - configFile, _ := cmd.Flags().GetString("file") - if err := exportConfigToCSV(configFile); err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(1) - } - }, -} - -func init() { - csvExportCmd.Flags().StringP("file", "f", "", "Path to YML file") - err := csvExportCmd.MarkFlagRequired("file") - if err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(1) - } -} - -func exportConfigToCSV(configFile string) error { - // Read the YAML file - bytes, err := os.ReadFile(configFile) - if err != nil { - return err - } - - // Unmarshal the YAML into the Config struct - var config Config - if err := yaml.Unmarshal(bytes, &config); err != nil { - return err - } - - // Create a CSV file - file, err := os.Create("output.csv") - if err != nil { - return err - } - defer file.Close() - - writer := csv.NewWriter(file) - defer writer.Flush() - - // Write CSV headers - headers := []string{"ID", "Test Path", "Test Env Type", "Runs On", "Test Cmd", "Test Config Override Required", "Test Secrets Required", "Remote Runner Memory", "Pyroscope Env", "Workflows", "Test Inputs"} - if err := writer.Write(headers); err != nil { - return err - } - - // Iterate over Tests and write data to CSV - for _, test := range config.Tests { - workflows := strings.Join(test.Workflows, ", ") // Combine workflows into a single CSV field - // Serialize TestInputs - testInputs := serializeMap(test.TestInputs) - - record := []string{ - test.ID, - test.Path, - test.TestEnvType, - test.RunsOn, - test.TestCmd, - fmt.Sprintf("%t", test.TestConfigOverrideRequired), - fmt.Sprintf("%t", test.TestSecretsRequired), - test.RemoteRunnerMemory, - test.PyroscopeEnv, - workflows, - testInputs, - } - if err := writer.Write(record); err != nil { - return err - } - } - - return nil -} - -func serializeMap(inputs map[string]string) string { - pairs := make([]string, 0, len(inputs)) - for key, value := range inputs { - pairs = append(pairs, fmt.Sprintf("%s=%s", key, value)) - } - return strings.Join(pairs, ", ") -} diff --git a/integration-tests/citool/cmd/filter_cmd.go b/integration-tests/citool/cmd/filter_cmd.go deleted file mode 100644 index c1d5f22357..0000000000 --- a/integration-tests/citool/cmd/filter_cmd.go +++ /dev/null @@ -1,165 +0,0 @@ -package cmd - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "log" - "os" - "regexp" - "strings" - - "github.com/spf13/cobra" - "gopkg.in/yaml.v2" - - "github.com/smartcontractkit/chainlink-testing-framework/utils" -) - -// Filter tests based on workflow, test type, and test IDs. -func filterTests(allTests []CITestConf, workflow, testType, ids string, envresolve bool) []CITestConf { - workflowFilter := workflow - typeFilter := testType - idFilter := strings.Split(ids, ",") - - var filteredTests []CITestConf - - for _, test := range allTests { - workflowMatch := workflow == "" || contains(test.Workflows, workflowFilter) - typeMatch := testType == "" || test.TestEnvType == typeFilter - idMatch := ids == "*" || ids == "" || contains(idFilter, test.ID) - - if workflowMatch && typeMatch && idMatch { - test.IDSanitized = sanitizeTestID(test.ID) - filteredTests = append(filteredTests, test) - } - if envresolve { - for k, v := range test.TestInputs { - test.TestInputs[k] = utils.MustResolveEnvPlaceholder(v) - } - } - } - - return filteredTests -} - -func filterAndMergeTests(allTests []CITestConf, workflow, testType, base64Tests string, envresolve bool) ([]CITestConf, error) { - decodedBytes, err := base64.StdEncoding.DecodeString(base64Tests) - if err != nil { - return nil, err - } - var decodedTests []CITestConf - err = yaml.Unmarshal(decodedBytes, &decodedTests) - if err != nil { - return nil, err - } - - idFilter := make(map[string]CITestConf) - for _, dt := range decodedTests { - idFilter[dt.ID] = dt - } - - var filteredTests []CITestConf - for _, test := range allTests { - workflowMatch := workflow == "" || contains(test.Workflows, workflow) - typeMatch := testType == "" || test.TestEnvType == testType - - if decodedTest, exists := idFilter[test.ID]; exists && workflowMatch && typeMatch { - // Override test inputs from the base64 encoded tests - for k, v := range decodedTest.TestInputs { - if test.TestInputs == nil { - test.TestInputs = make(map[string]string) - } - test.TestInputs[k] = v - } - test.IDSanitized = sanitizeTestID(test.ID) - filteredTests = append(filteredTests, test) - } - if envresolve { - for k, v := range test.TestInputs { - test.TestInputs[k] = utils.MustResolveEnvPlaceholder(v) - } - } - } - - return filteredTests, nil -} - -func sanitizeTestID(id string) string { - // Define a regular expression that matches any character not a letter, digit, hyphen - re := regexp.MustCompile(`[^a-zA-Z0-9-_]+`) - // Replace all occurrences of disallowed characters with "_" - return re.ReplaceAllString(id, "_") -} - -// Utility function to check if a slice contains a string. -func contains(slice []string, element string) bool { - for _, s := range slice { - if s == element { - return true - } - } - return false -} - -// filterCmd represents the filter command -var filterCmd = &cobra.Command{ - Use: "filter", - Short: "Filter test configurations based on specified criteria", - Long: `Filters tests from a YAML configuration based on name, workflow, test type, and test IDs. -Example usage: -./e2e_tests_tool filter --file .github/e2e-tests.yml --workflow "Run Nightly E2E Tests" --test-env-type "docker" --test-ids "test1,test2"`, - Run: func(cmd *cobra.Command, _ []string) { - yamlFile, _ := cmd.Flags().GetString("file") - workflow, _ := cmd.Flags().GetString("workflow") - testType, _ := cmd.Flags().GetString("test-env-type") - testIDs, _ := cmd.Flags().GetString("test-ids") - testMap, _ := cmd.Flags().GetString("test-list") - envresolve, _ := cmd.Flags().GetBool("envresolve") - - data, err := os.ReadFile(yamlFile) - if err != nil { - fmt.Fprintf(os.Stderr, "Error reading YAML file: %v\n", err) - os.Exit(1) - } - - var config Config - err = yaml.Unmarshal(data, &config) - if err != nil { - fmt.Fprintf(os.Stderr, "Error parsing YAML file %s data: %v\n", yamlFile, err) - os.Exit(1) - } - - var filteredTests []CITestConf - if testMap == "" { - filteredTests = filterTests(config.Tests, workflow, testType, testIDs, envresolve) - } else { - filteredTests, err = filterAndMergeTests(config.Tests, workflow, testType, testMap, envresolve) - if err != nil { - log.Fatalf("Error filtering and merging tests: %v", err) - } - } - matrix := map[string][]CITestConf{"tests": filteredTests} - matrixJSON, err := json.Marshal(matrix) - if err != nil { - fmt.Fprintf(os.Stderr, "Error marshaling matrix to JSON: %v\n", err) - os.Exit(1) - } - - fmt.Printf("%s", matrixJSON) - }, -} - -func init() { - filterCmd.Flags().StringP("file", "f", "", "Path to the YAML file") - filterCmd.Flags().String("test-list", "", "Base64 encoded list of tests (YML objects) to filter by. Can include test_inputs for each test.") - filterCmd.Flags().StringP("test-ids", "i", "*", "Comma-separated list of test IDs to filter by") - filterCmd.Flags().StringP("test-env-type", "y", "", "Type of test to filter by") - filterCmd.Flags().StringP("workflow", "t", "", "Workflow filter") - filterCmd.Flags().Bool("envresolve", false, "Resolve environment variables in test inputs") - - err := filterCmd.MarkFlagRequired("file") - if err != nil { - fmt.Fprintf(os.Stderr, "Error marking flag as required: %v\n", err) - os.Exit(1) - } -} diff --git a/integration-tests/citool/cmd/filter_cmd_test.go b/integration-tests/citool/cmd/filter_cmd_test.go deleted file mode 100644 index ff6e9c981d..0000000000 --- a/integration-tests/citool/cmd/filter_cmd_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package cmd - -import ( - "testing" -) - -func TestFilterTestsByID(t *testing.T) { - tests := []CITestConf{ - {ID: "run_all_in_ocr_tests_go", TestEnvType: "docker"}, - {ID: "run_all_in_ocr2_tests_go", TestEnvType: "docker"}, - {ID: "run_all_in_ocr3_tests_go", TestEnvType: "k8s_remote_runner"}, - } - - cases := []struct { - description string - inputIDs string - expectedLen int - }{ - {"Filter by single ID", "run_all_in_ocr_tests_go", 1}, - {"Filter by multiple IDs", "run_all_in_ocr_tests_go,run_all_in_ocr2_tests_go", 2}, - {"Wildcard to include all", "*", 3}, - {"Empty ID string to include all", "", 3}, - } - - for _, c := range cases { - t.Run(c.description, func(t *testing.T) { - filtered := filterTests(tests, "", "", c.inputIDs, false) - if len(filtered) != c.expectedLen { - t.Errorf("FilterTests(%s) returned %d tests, expected %d", c.description, len(filtered), c.expectedLen) - } - }) - } -} - -func TestFilterTestsIntegration(t *testing.T) { - tests := []CITestConf{ - {ID: "run_all_in_ocr_tests_go", TestEnvType: "docker", Workflows: []string{"Run Nightly E2E Tests"}}, - {ID: "run_all_in_ocr2_tests_go", TestEnvType: "docker", Workflows: []string{"Run PR E2E Tests"}}, - {ID: "run_all_in_ocr3_tests_go", TestEnvType: "k8s_remote_runner", Workflows: []string{"Run PR E2E Tests"}}, - } - - cases := []struct { - description string - inputNames string - inputWorkflow string - inputTestType string - inputIDs string - expectedLen int - }{ - {"Filter by test type and ID", "", "", "docker", "run_all_in_ocr2_tests_go", 1}, - {"Filter by trigger and test type", "", "Run PR E2E Tests", "docker", "*", 1}, - {"No filters applied", "", "", "", "*", 3}, - {"Filter mismatching all criteria", "", "Run Nightly E2E Tests", "", "", 1}, - } - - for _, c := range cases { - t.Run(c.description, func(t *testing.T) { - filtered := filterTests(tests, c.inputWorkflow, c.inputTestType, c.inputIDs, false) - if len(filtered) != c.expectedLen { - t.Errorf("FilterTests(%s) returned %d tests, expected %d", c.description, len(filtered), c.expectedLen) - } - }) - } -} diff --git a/integration-tests/citool/cmd/root_cmd.go b/integration-tests/citool/cmd/root_cmd.go deleted file mode 100644 index fdb4efd572..0000000000 --- a/integration-tests/citool/cmd/root_cmd.go +++ /dev/null @@ -1,32 +0,0 @@ -package cmd - -import ( - "os" - - "github.com/spf13/cobra" -) - -// rootCmd represents the base command when called without any subcommands -var rootCmd = &cobra.Command{ - Use: "citool", - Short: "A tool to manage E2E tests on Github CI", -} - -// Execute adds all child commands to the root command and sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the rootCmd. -func Execute() { - err := rootCmd.Execute() - if err != nil { - os.Exit(1) - } -} - -func init() { - rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") - - rootCmd.AddCommand(checkTestsCmd) - rootCmd.AddCommand(filterCmd) - rootCmd.AddCommand(csvExportCmd) - rootCmd.AddCommand(testConfigCmd) - testConfigCmd.AddCommand(createTestConfigCmd) -} diff --git a/integration-tests/citool/cmd/test_config_cmd.go b/integration-tests/citool/cmd/test_config_cmd.go deleted file mode 100644 index 0c0e272353..0000000000 --- a/integration-tests/citool/cmd/test_config_cmd.go +++ /dev/null @@ -1,123 +0,0 @@ -package cmd - -import ( - "strings" - - "github.com/spf13/cobra" - - "github.com/smartcontractkit/chainlink-testing-framework/utils" -) - -var testConfigCmd = &cobra.Command{ - Use: "test-config", - Short: "Manage test config", -} - -// OverrideConfig holds the configuration data for overrides -type OverrideConfig struct { - ChainlinkImage string - ChainlinkVersion string - ChainlinkUpgradeImage string - ChainlinkUpgradeVersion string - ChainlinkPostgresVersion string - SelectedNetworks []string - PyroscopeEnabled bool - PyroscopeServerURL string - PyroscopeEnvironment string - PyroscopeKey string - LoggingTestLogCollect bool - LoggingRunID string - LoggingLogTargets []string - LoggingLokiTenantID string - LoggingLokiEndpoint string - LoggingLokiBasicAuth string - LoggingGrafanaBaseURL string - LoggingGrafanaDashboardURL string - LoggingGrafanaBearerToken string - PrivateEthereumNetworkExecutionLayer string - PrivateEthereumNetworkEthereumVersion string - PrivateEthereumNetworkCustomDockerImages string -} - -const ( - ChainlinkVersionFlag = "chainlink-version" - ChainlinkUpgradeVersionFlag = "chainlink-upgrade-version" - ChainlinkPostgresVersionFlag = "chainlink-postgres-version" - SelectedNetworksFlag = "selected-networks" - FromBase64ConfigFlag = "from-base64-config" - LoggingLokiBasicAuthFlag = "logging-loki-basic-auth" - LoggingLokiEndpointFlag = "logging-loki-endpoint" - LoggingRunIDFlag = "logging-run-id" - LoggingLokiTenantIDFlag = "logging-loki-tenant-id" - LoggingGrafanaBaseURLFlag = "logging-grafana-base-url" - LoggingGrafanaDashboardURLFlag = "logging-grafana-dashboard-url" - LoggingGrafanaBearerTokenFlag = "logging-grafana-bearer-token" - LoggingLogTargetsFlag = "logging-log-targets" - LoggingTestLogCollectFlag = "logging-test-log-collect" - PyroscopeEnabledFlag = "pyroscope-enabled" - PyroscopeServerURLFlag = "pyroscope-server-url" - PyroscopeKeyFlag = "pyroscope-key" - PyroscopeEnvironmentFlag = "pyroscope-environment" - PrivateEthereumNetworkExecutionLayerFlag = "private-ethereum-network-execution-layer" - PrivateEthereumNetworkEthereumVersionFlag = "private-ethereum-network-ethereum-version" - PrivateEthereumNetworkCustomDockerImageFlag = "private-ethereum-network-custom-docker-image" -) - -var oc OverrideConfig - -func init() { - cmds := []*cobra.Command{createTestConfigCmd} - for _, c := range cmds { - c.Flags().StringArrayVar(&oc.SelectedNetworks, SelectedNetworksFlag, nil, "Selected networks") - c.Flags().StringVar(&oc.ChainlinkVersion, ChainlinkVersionFlag, "", "Chainlink version") - c.Flags().StringVar(&oc.ChainlinkUpgradeVersion, ChainlinkUpgradeVersionFlag, "", "Chainlink upgrade version") - c.Flags().StringVar(&oc.ChainlinkPostgresVersion, ChainlinkPostgresVersionFlag, "", "Chainlink Postgres version") - c.Flags().BoolVar(&oc.PyroscopeEnabled, PyroscopeEnabledFlag, false, "Pyroscope enabled") - c.Flags().StringVar(&oc.PyroscopeServerURL, PyroscopeServerURLFlag, "", "Pyroscope server URL") - c.Flags().StringVar(&oc.PyroscopeKey, PyroscopeKeyFlag, "", "Pyroscope key") - c.Flags().StringVar(&oc.PyroscopeEnvironment, PyroscopeEnvironmentFlag, "", "Pyroscope environment") - c.Flags().BoolVar(&oc.LoggingTestLogCollect, LoggingTestLogCollectFlag, false, "Test log collect") - c.Flags().StringVar(&oc.LoggingRunID, LoggingRunIDFlag, "", "Run ID") - c.Flags().StringArrayVar(&oc.LoggingLogTargets, LoggingLogTargetsFlag, nil, "Logging.LogStream.LogTargets") - c.Flags().StringVar(&oc.LoggingLokiEndpoint, LoggingLokiEndpointFlag, "", "") - c.Flags().StringVar(&oc.LoggingLokiTenantID, LoggingLokiTenantIDFlag, "", "") - c.Flags().StringVar(&oc.LoggingLokiBasicAuth, LoggingLokiBasicAuthFlag, "", "") - c.Flags().StringVar(&oc.LoggingGrafanaBaseURL, LoggingGrafanaBaseURLFlag, "", "") - c.Flags().StringVar(&oc.LoggingGrafanaDashboardURL, LoggingGrafanaDashboardURLFlag, "", "") - c.Flags().StringVar(&oc.LoggingGrafanaBearerToken, LoggingGrafanaBearerTokenFlag, "", "") - c.Flags().StringVar(&oc.PrivateEthereumNetworkExecutionLayer, PrivateEthereumNetworkExecutionLayerFlag, "", "") - c.Flags().StringVar(&oc.PrivateEthereumNetworkEthereumVersion, PrivateEthereumNetworkEthereumVersionFlag, "", "") - c.Flags().StringVar(&oc.PrivateEthereumNetworkCustomDockerImages, PrivateEthereumNetworkCustomDockerImageFlag, "", "") - - c.PreRun = func(_ *cobra.Command, _ []string) { - // Resolve selected networks environment variable if set - if len(oc.SelectedNetworks) > 0 { - _, hasEnvVar := utils.LookupEnvVarName(oc.SelectedNetworks[0]) - if hasEnvVar { - selectedNetworks := utils.MustResolveEnvPlaceholder(oc.SelectedNetworks[0]) - oc.SelectedNetworks = strings.Split(selectedNetworks, ",") - } - } - - // Resolve all other environment variables - oc.ChainlinkImage = utils.MustResolveEnvPlaceholder(oc.ChainlinkImage) - oc.ChainlinkVersion = utils.MustResolveEnvPlaceholder(oc.ChainlinkVersion) - oc.ChainlinkUpgradeImage = utils.MustResolveEnvPlaceholder(oc.ChainlinkUpgradeImage) - oc.ChainlinkUpgradeVersion = utils.MustResolveEnvPlaceholder(oc.ChainlinkUpgradeVersion) - oc.ChainlinkPostgresVersion = utils.MustResolveEnvPlaceholder(oc.ChainlinkPostgresVersion) - oc.PyroscopeServerURL = utils.MustResolveEnvPlaceholder(oc.PyroscopeServerURL) - oc.PyroscopeKey = utils.MustResolveEnvPlaceholder(oc.PyroscopeKey) - oc.PyroscopeEnvironment = utils.MustResolveEnvPlaceholder(oc.PyroscopeEnvironment) - oc.LoggingRunID = utils.MustResolveEnvPlaceholder(oc.LoggingRunID) - oc.LoggingLokiTenantID = utils.MustResolveEnvPlaceholder(oc.LoggingLokiTenantID) - oc.LoggingLokiEndpoint = utils.MustResolveEnvPlaceholder(oc.LoggingLokiEndpoint) - oc.LoggingLokiBasicAuth = utils.MustResolveEnvPlaceholder(oc.LoggingLokiBasicAuth) - oc.LoggingGrafanaBaseURL = utils.MustResolveEnvPlaceholder(oc.LoggingGrafanaBaseURL) - oc.LoggingGrafanaDashboardURL = utils.MustResolveEnvPlaceholder(oc.LoggingGrafanaDashboardURL) - oc.LoggingGrafanaBearerToken = utils.MustResolveEnvPlaceholder(oc.LoggingGrafanaBearerToken) - oc.PrivateEthereumNetworkExecutionLayer = utils.MustResolveEnvPlaceholder(oc.PrivateEthereumNetworkExecutionLayer) - oc.PrivateEthereumNetworkEthereumVersion = utils.MustResolveEnvPlaceholder(oc.PrivateEthereumNetworkEthereumVersion) - oc.PrivateEthereumNetworkCustomDockerImages = utils.MustResolveEnvPlaceholder(oc.PrivateEthereumNetworkCustomDockerImages) - } - } -} diff --git a/integration-tests/citool/cmd/test_config_cmd_test.go b/integration-tests/citool/cmd/test_config_cmd_test.go deleted file mode 100644 index 79185e6082..0000000000 --- a/integration-tests/citool/cmd/test_config_cmd_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package cmd - -import ( - "bytes" - "testing" - - "github.com/pelletier/go-toml/v2" - "github.com/spf13/cobra" - "github.com/stretchr/testify/assert" - - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/config/types" -) - -func TestCreateTestConfigCmd(t *testing.T) { - tests := []struct { - name string - args []string - want interface{} - check func(t *testing.T, tc *ctf_config.TestConfig) - wantErr bool - }{ - { - name: "LoggingLogTargets", - args: []string{"create", "--logging-log-targets=target1", "--logging-log-targets=target2"}, - check: func(t *testing.T, tc *ctf_config.TestConfig) { - assert.NotNil(t, tc.Logging) - assert.NotNil(t, tc.Logging.LogStream) - assert.Equal(t, []string{"target1", "target2"}, tc.Logging.LogStream.LogTargets) - }, - }, - { - name: "PrivateEthereumNetworkExecutionLayerFlag", - args: []string{"create", "--private-ethereum-network-execution-layer=geth", "--private-ethereum-network-ethereum-version=1.10.0"}, - check: func(t *testing.T, tc *ctf_config.TestConfig) { - assert.NotNil(t, tc.PrivateEthereumNetwork) - assert.NotNil(t, tc.PrivateEthereumNetwork.ExecutionLayer) - assert.Equal(t, ctf_config_types.ExecutionLayer("geth"), *tc.PrivateEthereumNetwork.ExecutionLayer) - assert.Equal(t, ctf_config_types.EthereumVersion("1.10.0"), *tc.PrivateEthereumNetwork.EthereumVersion) - }, - }, - { - name: "PrivateEthereumNetworkCustomDockerImageFlag", - args: []string{"create", "--private-ethereum-network-execution-layer=geth", "--private-ethereum-network-ethereum-version=1.10.0", "--private-ethereum-network-custom-docker-image=custom-image:v1.0"}, - check: func(t *testing.T, tc *ctf_config.TestConfig) { - assert.NotNil(t, tc.PrivateEthereumNetwork) - assert.NotNil(t, tc.PrivateEthereumNetwork.ExecutionLayer) - assert.Equal(t, map[ctf_config.ContainerType]string{"execution_layer": "custom-image:v1.0"}, tc.PrivateEthereumNetwork.CustomDockerImages) - }, - }, - } - - rootCmd := &cobra.Command{} - rootCmd.AddCommand(createTestConfigCmd) - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - rootCmd.SetArgs(tt.args) - var out bytes.Buffer - rootCmd.SetOutput(&out) - err := rootCmd.Execute() - if (err != nil) != tt.wantErr { - t.Fatalf("Execute() error = %v, wantErr %v", err, tt.wantErr) - } - var tc ctf_config.TestConfig - err = toml.Unmarshal(out.Bytes(), &tc) - if err != nil { - t.Fatalf("Failed to unmarshal output: %v", err) - } - if tt.check != nil { - tt.check(t, &tc) - } - }) - } -} diff --git a/integration-tests/citool/cmd/types.go b/integration-tests/citool/cmd/types.go deleted file mode 100644 index 3c347e9406..0000000000 --- a/integration-tests/citool/cmd/types.go +++ /dev/null @@ -1,26 +0,0 @@ -package cmd - -type Test struct { - Name string - Path string -} - -// CITestConf defines the configuration for running a test in a CI environment, specifying details like test ID, path, type, runner settings, command, and associated workflows. -type CITestConf struct { - ID string `yaml:"id" json:"id"` - IDSanitized string `json:"id_sanitized"` - Path string `yaml:"path" json:"path"` - TestEnvType string `yaml:"test_env_type" json:"test_env_type"` - RunsOn string `yaml:"runs_on" json:"runs_on"` - TestCmd string `yaml:"test_cmd" json:"test_cmd"` - TestConfigOverrideRequired bool `yaml:"test_config_override_required" json:"testConfigOverrideRequired"` - TestSecretsRequired bool `yaml:"test_secrets_required" json:"testSecretsRequired"` - TestInputs map[string]string `yaml:"test_inputs" json:"test_inputs"` - RemoteRunnerMemory string `yaml:"remote_runner_memory" json:"remoteRunnerMemory"` - PyroscopeEnv string `yaml:"pyroscope_env" json:"pyroscopeEnv"` - Workflows []string `yaml:"workflows" json:"workflows"` -} - -type Config struct { - Tests []CITestConf `yaml:"runner-test-matrix"` -} diff --git a/integration-tests/citool/main.go b/integration-tests/citool/main.go deleted file mode 100644 index 4fa6cac56e..0000000000 --- a/integration-tests/citool/main.go +++ /dev/null @@ -1,9 +0,0 @@ -package main - -import ( - "github.com/smartcontractkit/chainlink/integration-tests/citool/cmd" -) - -func main() { - cmd.Execute() -} diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 8589f12840..b4c1839c74 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -54,8 +54,6 @@ require ( golang.org/x/sync v0.7.0 golang.org/x/text v0.16.0 gopkg.in/guregu/null.v4 v4.0.0 - gopkg.in/yaml.v2 v2.4.0 - gopkg.in/yaml.v3 v3.0.1 k8s.io/apimachinery v0.28.2 ) @@ -469,6 +467,8 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.28.2 // indirect k8s.io/apiextensions-apiserver v0.28.2 // indirect k8s.io/cli-runtime v0.28.2 // indirect From ec183b5edec990146c984f904ec46da61549c4e9 Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Wed, 21 Aug 2024 21:29:24 +0400 Subject: [PATCH 127/432] Soak Tests - Remove Namespace if fund return is successful (#14155) --- integration-tests/benchmark/keeper_test.go | 5 +++++ integration-tests/soak/forwarder_ocr_test.go | 5 +++++ integration-tests/soak/ocr_test.go | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/integration-tests/benchmark/keeper_test.go b/integration-tests/benchmark/keeper_test.go index af0d52ae23..ab54885b28 100644 --- a/integration-tests/benchmark/keeper_test.go +++ b/integration-tests/benchmark/keeper_test.go @@ -140,6 +140,11 @@ func TestAutomationBenchmark(t *testing.T) { t.Cleanup(func() { if err = actions.TeardownRemoteSuite(keeperBenchmarkTest.TearDownVals(t)); err != nil { l.Error().Err(err).Msg("Error when tearing down remote suite") + } else { + err := testEnvironment.Client.RemoveNamespace(testEnvironment.Cfg.Namespace) + if err != nil { + l.Error().Err(err).Msg("Error removing namespace") + } } }) keeperBenchmarkTest.Setup(testEnvironment, &config) diff --git a/integration-tests/soak/forwarder_ocr_test.go b/integration-tests/soak/forwarder_ocr_test.go index dd7eb10217..9b12978366 100644 --- a/integration-tests/soak/forwarder_ocr_test.go +++ b/integration-tests/soak/forwarder_ocr_test.go @@ -42,6 +42,11 @@ func executeForwarderOCRSoakTest(t *testing.T, config *tc.TestConfig) { t.Cleanup(func() { if err := actions.TeardownRemoteSuite(ocrSoakTest.TearDownVals(t)); err != nil { l.Error().Err(err).Msg("Error tearing down environment") + } else { + err := ocrSoakTest.Environment().Client.RemoveNamespace(ocrSoakTest.Environment().Cfg.Namespace) + if err != nil { + l.Error().Err(err).Msg("Error removing namespace") + } } }) ocrSoakTest.Setup(config) diff --git a/integration-tests/soak/ocr_test.go b/integration-tests/soak/ocr_test.go index 1f437e565e..d1440b7c3a 100644 --- a/integration-tests/soak/ocr_test.go +++ b/integration-tests/soak/ocr_test.go @@ -160,6 +160,11 @@ func executeOCRSoakTest(t *testing.T, test *testsetups.OCRSoakTest, config *tc.T t.Cleanup(func() { if err := actions.TeardownRemoteSuite(test.TearDownVals(t)); err != nil { l.Error().Err(err).Msg("Error tearing down environment") + } else { + err := test.Environment().Client.RemoveNamespace(test.Environment().Cfg.Namespace) + if err != nil { + l.Error().Err(err).Msg("Error removing namespace") + } } }) if test.Interrupted() { From 831d006050c389caf2e0b1e5f938aff6e81dbfaa Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Wed, 21 Aug 2024 14:56:12 -0400 Subject: [PATCH 128/432] devsvcs-168: fix chain module l1 fee calculation (#14150) * devsvcs-168: fix chain module l1 fee calculation * Update gethwrappers * go gen --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .../v0.8/automation/chains/ArbitrumModule.sol | 2 +- .../automation/chains/ChainModuleBase.sol | 2 +- .../v0.8/automation/chains/OptimismModule.sol | 10 +- .../v0.8/automation/chains/ScrollModule.sol | 28 +- .../automation/interfaces/IChainModule.sol | 2 +- .../automation/v2_2/AutomationRegistry2_2.sol | 2 +- .../automation/v2_3/AutomationRegistry2_3.sol | 2 +- .../v2_3/AutomationRegistryBase2_3.sol | 2 +- .../ZKSyncAutomationRegistry2_3.sol | 2 +- .../arbitrum_module/arbitrum_module.go | 18 +- ...automation_registry_logic_b_wrapper_2_3.go | 2 +- ...automation_registry_logic_c_wrapper_2_3.go | 2 +- .../automation_registry_wrapper_2_2.go | 2 +- .../automation_registry_wrapper_2_3.go | 2 +- .../chain_module_base/chain_module_base.go | 18 +- .../i_chain_module/i_chain_module.go | 16 +- .../optimism_module/optimism_module.go | 18 +- .../generated/scroll_module/scroll_module.go | 545 +++++++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 18 +- 19 files changed, 624 insertions(+), 69 deletions(-) diff --git a/contracts/src/v0.8/automation/chains/ArbitrumModule.sol b/contracts/src/v0.8/automation/chains/ArbitrumModule.sol index e27a0809b7..2ad6fdddc8 100644 --- a/contracts/src/v0.8/automation/chains/ArbitrumModule.sol +++ b/contracts/src/v0.8/automation/chains/ArbitrumModule.sol @@ -31,7 +31,7 @@ contract ArbitrumModule is ChainModuleBase { return ARB_SYS.arbBlockNumber(); } - function getCurrentL1Fee() external view override returns (uint256) { + function getCurrentL1Fee(uint256) external view override returns (uint256) { return ARB_GAS.getCurrentTxL1GasFees(); } diff --git a/contracts/src/v0.8/automation/chains/ChainModuleBase.sol b/contracts/src/v0.8/automation/chains/ChainModuleBase.sol index e9b082063b..52829d43e5 100644 --- a/contracts/src/v0.8/automation/chains/ChainModuleBase.sol +++ b/contracts/src/v0.8/automation/chains/ChainModuleBase.sol @@ -18,7 +18,7 @@ contract ChainModuleBase is IChainModule { return blockhash(n); } - function getCurrentL1Fee() external view virtual returns (uint256) { + function getCurrentL1Fee(uint256) external view virtual returns (uint256) { return 0; } diff --git a/contracts/src/v0.8/automation/chains/OptimismModule.sol b/contracts/src/v0.8/automation/chains/OptimismModule.sol index 91c1c0ed96..c108bed008 100644 --- a/contracts/src/v0.8/automation/chains/OptimismModule.sol +++ b/contracts/src/v0.8/automation/chains/OptimismModule.sol @@ -16,13 +16,19 @@ contract OptimismModule is ChainModuleBase { uint256 private constant FIXED_GAS_OVERHEAD = 60_000; uint256 private constant PER_CALLDATA_BYTE_GAS_OVERHEAD = 270; - function getCurrentL1Fee() external view override returns (uint256) { - return OVM_GASPRICEORACLE.getL1Fee(bytes.concat(msg.data, OP_L1_DATA_FEE_PADDING)); + // @dev This will be updated to use the new function introduced by OP team + function getCurrentL1Fee(uint256 dataSize) external view override returns (uint256) { + return _getL1Fee(dataSize); } function getMaxL1Fee(uint256 dataSize) external view override returns (uint256) { + return _getL1Fee(dataSize); + } + + function _getL1Fee(uint256 dataSize) internal view returns (uint256) { // fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have all non zero-bytes. // Instead of setting bytes to non-zero, we initialize 'new bytes' of length 4*dataSize to cover for zero bytes. + // this is the same as OP. bytes memory txCallData = new bytes(4 * dataSize); return OVM_GASPRICEORACLE.getL1Fee(bytes.concat(txCallData, OP_L1_DATA_FEE_PADDING)); } diff --git a/contracts/src/v0.8/automation/chains/ScrollModule.sol b/contracts/src/v0.8/automation/chains/ScrollModule.sol index 1e41ed3805..5a1373b372 100644 --- a/contracts/src/v0.8/automation/chains/ScrollModule.sol +++ b/contracts/src/v0.8/automation/chains/ScrollModule.sol @@ -3,8 +3,12 @@ pragma solidity 0.8.19; import {IScrollL1GasPriceOracle} from "../../vendor/@scroll-tech/contracts/src/L2/predeploys/IScrollL1GasPriceOracle.sol"; import {ChainModuleBase} from "./ChainModuleBase.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; + +contract ScrollModule is ChainModuleBase, ConfirmedOwner { + error InvalidL1FeeCoefficient(uint8 coefficient); + event L1FeeCoefficientSet(uint8 coefficient); -contract ScrollModule is ChainModuleBase { /// @dev SCROLL_L1_FEE_DATA_PADDING includes 140 bytes for L1 data padding for Scroll /// @dev according to testing, this padding allows automation registry to properly estimates L1 data fee with 3-5% buffer /// @dev this MAY NOT work for a different product and this may get out of date if transmit function is changed @@ -15,14 +19,22 @@ contract ScrollModule is ChainModuleBase { address private constant SCROLL_ORACLE_ADDR = 0x5300000000000000000000000000000000000002; IScrollL1GasPriceOracle private constant SCROLL_ORACLE = IScrollL1GasPriceOracle(SCROLL_ORACLE_ADDR); + /// @dev L1 fee coefficient can be applied to reduce possibly inflated gas cost + uint8 public s_l1FeeCoefficient = 100; uint256 private constant FIXED_GAS_OVERHEAD = 45_000; uint256 private constant PER_CALLDATA_BYTE_GAS_OVERHEAD = 170; - function getCurrentL1Fee() external view override returns (uint256) { - return SCROLL_ORACLE.getL1Fee(bytes.concat(msg.data, SCROLL_L1_FEE_DATA_PADDING)); + constructor() ConfirmedOwner(msg.sender) {} + + function getCurrentL1Fee(uint256 dataSize) external view override returns (uint256) { + return (s_l1FeeCoefficient * _getL1Fee(dataSize)) / 100; } function getMaxL1Fee(uint256 dataSize) external view override returns (uint256) { + return _getL1Fee(dataSize); + } + + function _getL1Fee(uint256 dataSize) internal view returns (uint256) { // fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have all non zero-bytes. // Instead of setting bytes to non-zero, we initialize 'new bytes' of length 4*dataSize to cover for zero bytes. // this is the same as OP. @@ -38,4 +50,14 @@ contract ScrollModule is ChainModuleBase { { return (FIXED_GAS_OVERHEAD, PER_CALLDATA_BYTE_GAS_OVERHEAD); } + + function setL1FeeCalculation(uint8 coefficient) external onlyOwner { + if (coefficient > 100) { + revert InvalidL1FeeCoefficient(coefficient); + } + + s_l1FeeCoefficient = coefficient; + + emit L1FeeCoefficientSet(coefficient); + } } diff --git a/contracts/src/v0.8/automation/interfaces/IChainModule.sol b/contracts/src/v0.8/automation/interfaces/IChainModule.sol index e3a4b32c9b..47d5b25111 100644 --- a/contracts/src/v0.8/automation/interfaces/IChainModule.sol +++ b/contracts/src/v0.8/automation/interfaces/IChainModule.sol @@ -11,7 +11,7 @@ interface IChainModule { // retrieve the L1 data fee for a L2 transaction. it should return 0 for L1 chains and // L2 chains which don't have L1 fee component. it uses msg.data to estimate L1 data so // it must be used with a transaction. Return value in wei. - function getCurrentL1Fee() external view returns (uint256); + function getCurrentL1Fee(uint256 dataSize) external view returns (uint256); // retrieve the L1 data fee for a L2 simulation. it should return 0 for L1 chains and // L2 chains which don't have L1 fee component. Return value in wei. diff --git a/contracts/src/v0.8/automation/v2_2/AutomationRegistry2_2.sol b/contracts/src/v0.8/automation/v2_2/AutomationRegistry2_2.sol index f0c703679c..464e874639 100644 --- a/contracts/src/v0.8/automation/v2_2/AutomationRegistry2_2.sol +++ b/contracts/src/v0.8/automation/v2_2/AutomationRegistry2_2.sol @@ -115,7 +115,7 @@ contract AutomationRegistry2_2 is AutomationRegistryBase2_2, OCR2Abstract, Chain }); uint256 blocknumber = hotVars.chainModule.blockNumber(); - uint256 l1Fee = hotVars.chainModule.getCurrentL1Fee(); + uint256 l1Fee = hotVars.chainModule.getCurrentL1Fee(msg.data.length); for (uint256 i = 0; i < report.upkeepIds.length; i++) { upkeepTransmitInfo[i].upkeep = s_upkeep[report.upkeepIds[i]]; diff --git a/contracts/src/v0.8/automation/v2_3/AutomationRegistry2_3.sol b/contracts/src/v0.8/automation/v2_3/AutomationRegistry2_3.sol index 6113cbf9fd..031d7b5dfb 100644 --- a/contracts/src/v0.8/automation/v2_3/AutomationRegistry2_3.sol +++ b/contracts/src/v0.8/automation/v2_3/AutomationRegistry2_3.sol @@ -136,7 +136,7 @@ contract AutomationRegistry2_3 is AutomationRegistryBase2_3, OCR2Abstract, Chain }); uint256 blocknumber = hotVars.chainModule.blockNumber(); - uint256 l1Fee = hotVars.chainModule.getCurrentL1Fee(); + uint256 l1Fee = hotVars.chainModule.getCurrentL1Fee(msg.data.length); for (uint256 i = 0; i < report.upkeepIds.length; i++) { upkeepTransmitInfo[i].upkeep = s_upkeep[report.upkeepIds[i]]; diff --git a/contracts/src/v0.8/automation/v2_3/AutomationRegistryBase2_3.sol b/contracts/src/v0.8/automation/v2_3/AutomationRegistryBase2_3.sol index fa8f06ffc0..354a6a9b47 100644 --- a/contracts/src/v0.8/automation/v2_3/AutomationRegistryBase2_3.sol +++ b/contracts/src/v0.8/automation/v2_3/AutomationRegistryBase2_3.sol @@ -45,7 +45,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { // These values are calibrated using hardhat tests which simulate various cases and verify that // the variables result in accurate estimation uint256 internal constant REGISTRY_CONDITIONAL_OVERHEAD = 98_200; // Fixed gas overhead for conditional upkeeps - uint256 internal constant REGISTRY_LOG_OVERHEAD = 122_500; // Fixed gas overhead for log upkeeps + uint256 internal constant REGISTRY_LOG_OVERHEAD = 123_500; // Fixed gas overhead for log upkeeps uint256 internal constant REGISTRY_PER_SIGNER_GAS_OVERHEAD = 5_600; // Value scales with f uint256 internal constant REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD = 24; // Per perform data byte overhead diff --git a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol index 027fe59aca..00858085e3 100644 --- a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol +++ b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol @@ -136,7 +136,7 @@ contract ZKSyncAutomationRegistry2_3 is ZKSyncAutomationRegistryBase2_3, OCR2Abs }); uint256 blocknumber = hotVars.chainModule.blockNumber(); - uint256 l1Fee = hotVars.chainModule.getCurrentL1Fee(); + uint256 l1Fee = hotVars.chainModule.getCurrentL1Fee(msg.data.length); // this will be updated for (uint256 i = 0; i < report.upkeepIds.length; i++) { upkeepTransmitInfo[i].upkeep = s_upkeep[report.upkeepIds[i]]; diff --git a/core/gethwrappers/generated/arbitrum_module/arbitrum_module.go b/core/gethwrappers/generated/arbitrum_module/arbitrum_module.go index 537fbe2154..ca9b77d563 100644 --- a/core/gethwrappers/generated/arbitrum_module/arbitrum_module.go +++ b/core/gethwrappers/generated/arbitrum_module/arbitrum_module.go @@ -29,8 +29,8 @@ var ( ) var ArbitrumModuleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061041b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806357e871e71161005057806357e871e71461009a57806385df51fd146100a2578063de9ee35e146100b557600080fd5b8063125441401461006c57806318b8f61314610092575b600080fd5b61007f61007a366004610333565b6100cb565b6040519081526020015b60405180910390f35b61007f610158565b61007f6101cf565b61007f6100b0366004610333565b61021d565b6040805161138881526000602082015201610089565b600080606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa15801561011a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061013e919061034c565b50505050915050828161015191906103c5565b9392505050565b6000606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101ca91906103e2565b905090565b6000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a6573d6000803e3d6000fd5b600080606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561026c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029091906103e2565b905080831015806102ab57506101006102a984836103fb565b115b156102b95750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa15801561030f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061015191906103e2565b60006020828403121561034557600080fd5b5035919050565b60008060008060008060c0878903121561036557600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176103dc576103dc610396565b92915050565b6000602082840312156103f457600080fd5b5051919050565b818103818111156103dc576103dc61039656fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061044a806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80637810d12a116100505780637810d12a1461009a57806385df51fd146100ad578063de9ee35e146100c057600080fd5b8063125441401461006c57806357e871e714610092575b600080fd5b61007f61007a366004610368565b6100d6565b6040519081526020015b60405180910390f35b61007f610163565b61007f6100a8366004610368565b6101da565b61007f6100bb366004610368565b610252565b6040805161138881526000602082015201610089565b600080606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa158015610125573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101499190610381565b50505050915050828161015c91906103fa565b9392505050565b6000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d59190610411565b905090565b6000606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024c9190610411565b92915050565b600080606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c59190610411565b905080831015806102e057506101006102de848361042a565b115b156102ee5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa158015610344573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061015c9190610411565b60006020828403121561037a57600080fd5b5035919050565b60008060008060008060c0878903121561039a57600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761024c5761024c6103cb565b60006020828403121561042357600080fd5b5051919050565b8181038181111561024c5761024c6103cb56fea164736f6c6343000813000a", } var ArbitrumModuleABI = ArbitrumModuleMetaData.ABI @@ -213,9 +213,9 @@ func (_ArbitrumModule *ArbitrumModuleCallerSession) BlockNumber() (*big.Int, err return _ArbitrumModule.Contract.BlockNumber(&_ArbitrumModule.CallOpts) } -func (_ArbitrumModule *ArbitrumModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) { +func (_ArbitrumModule *ArbitrumModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { var out []interface{} - err := _ArbitrumModule.contract.Call(opts, &out, "getCurrentL1Fee") + err := _ArbitrumModule.contract.Call(opts, &out, "getCurrentL1Fee", arg0) if err != nil { return *new(*big.Int), err @@ -227,12 +227,12 @@ func (_ArbitrumModule *ArbitrumModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts } -func (_ArbitrumModule *ArbitrumModuleSession) GetCurrentL1Fee() (*big.Int, error) { - return _ArbitrumModule.Contract.GetCurrentL1Fee(&_ArbitrumModule.CallOpts) +func (_ArbitrumModule *ArbitrumModuleSession) GetCurrentL1Fee(arg0 *big.Int) (*big.Int, error) { + return _ArbitrumModule.Contract.GetCurrentL1Fee(&_ArbitrumModule.CallOpts, arg0) } -func (_ArbitrumModule *ArbitrumModuleCallerSession) GetCurrentL1Fee() (*big.Int, error) { - return _ArbitrumModule.Contract.GetCurrentL1Fee(&_ArbitrumModule.CallOpts) +func (_ArbitrumModule *ArbitrumModuleCallerSession) GetCurrentL1Fee(arg0 *big.Int) (*big.Int, error) { + return _ArbitrumModule.Contract.GetCurrentL1Fee(&_ArbitrumModule.CallOpts, arg0) } func (_ArbitrumModule *ArbitrumModuleCaller) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, @@ -301,7 +301,7 @@ type ArbitrumModuleInterface interface { BlockNumber(opts *bind.CallOpts) (*big.Int, error) - GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) + GetCurrentL1Fee(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, diff --git a/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3/automation_registry_logic_b_wrapper_2_3.go b/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3/automation_registry_logic_b_wrapper_2_3.go index acbf11155d..c2a808d554 100644 --- a/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3/automation_registry_logic_b_wrapper_2_3.go +++ b/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3/automation_registry_logic_b_wrapper_2_3.go @@ -57,7 +57,7 @@ type AutomationRegistryBase23PaymentReceipt struct { var AutomationRegistryLogicBMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicC2_3\",\"name\":\"logicC\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractIERC20Metadata\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint96\",\"name\":\"gasChargeInBillingToken\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"premiumInBillingToken\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"gasReimbursementInJuels\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"premiumInJuels\",\"type\":\"uint96\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"linkUSD\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeUSD\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"billingUSD\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.PaymentReceipt\",\"name\":\"receipt\",\"type\":\"tuple\"}],\"name\":\"UpkeepCharged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"removeBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"billingOverrides\",\"type\":\"tuple\"}],\"name\":\"setBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20Metadata\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20Fees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101806040523480156200001257600080fd5b5060405162005d2238038062005d2283398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e051610100516101205161014051610160516155e86200073a60003960008181610182015261022f0152600081816120e7015261228d01526000612bb30152600050506000612ee901526000613c5d01526000612fc3015260008181610c4701528181610d0801528181610dd30152612c7401526155e86000f3fe6080604052600436106101805760003560e01c80638765ecbe116100d6578063aed2e9291161007f578063ce7dc5b411610059578063ce7dc5b4146104b1578063f2fde38b146104d1578063f7d334ba146104f157610180565b8063aed2e9291461043a578063b148ab6b14610471578063cd7f71b51461049157610180565b8063948108f7116100b0578063948108f7146103e7578063a72aa27e146103fa578063a86e17811461041a57610180565b80638765ecbe1461037c5780638da5cb5b1461039c5780638dcf0fe7146103c757610180565b806354b7faae1161013857806371fae17f1161011257806371fae17f14610327578063744bfe611461034757806379ba50971461036757610180565b806354b7faae146102b457806368d369d8146102d457806371791aa0146102f457610180565b8063349e8cca11610169578063349e8cca146102205780634ee88d35146102745780635165f2f51461029457610180565b80631a2af011146101c757806329c5efad146101e7575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156101c0573d6000f35b3d6000fd5b005b3480156101d357600080fd5b506101c56101e2366004614490565b610511565b3480156101f357600080fd5b50610207610202366004614604565b610617565b6040516102179493929190614723565b60405180910390f35b34801561022c57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610217565b34801561028057600080fd5b506101c561028f3660046147a5565b6108f5565b3480156102a057600080fd5b506101c56102af3660046147f1565b610957565b3480156102c057600080fd5b506101c56102cf36600461480a565b610b09565b3480156102e057600080fd5b506101c56102ef366004614836565b610d7c565b34801561030057600080fd5b5061031461030f366004614604565b61102a565b6040516102179796959493929190614877565b34801561033357600080fd5b506101c56103423660046147f1565b61178e565b34801561035357600080fd5b506101c5610362366004614490565b611824565b34801561037357600080fd5b506101c5611c9c565b34801561038857600080fd5b506101c56103973660046147f1565b611d99565b3480156103a857600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661024f565b3480156103d357600080fd5b506101c56103e23660046147a5565b611f4e565b6101c56103f53660046148c5565b611fa3565b34801561040657600080fd5b506101c561041536600461490d565b612365565b34801561042657600080fd5b506101c5610435366004614932565b612464565b34801561044657600080fd5b5061045a6104553660046147a5565b612545565b604080519215158352602083019190915201610217565b34801561047d57600080fd5b506101c561048c3660046147f1565b6126f0565b34801561049d57600080fd5b506101c56104ac3660046147a5565b61291d565b3480156104bd57600080fd5b506102076104cc3660046149ac565b6129d4565b3480156104dd57600080fd5b506101c56104ec366004614a8e565b612a96565b3480156104fd57600080fd5b5061031461050c3660046147f1565b612aaa565b61051a82612ae6565b3373ffffffffffffffffffffffffffffffffffffffff821603610569576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116146106135760008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917fb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b3591a45b5050565b60006060600080610626612b9b565b600086815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615159483019490945263ffffffff620100008204811695830195909552660100000000000081048516606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490941660e0820152600290910154909216908201525a9150600080826080015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561077c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a09190614abb565b73ffffffffffffffffffffffffffffffffffffffff16601660000160149054906101000a900463ffffffff1663ffffffff16896040516107e09190614ad8565b60006040518083038160008787f1925050503d806000811461081e576040519150601f19603f3d011682016040523d82523d6000602084013e610823565b606091505b50915091505a6108339085614b23565b93508161085c5760006040518060200160405280600081525060079650965096505050506108ec565b808060200190518101906108709190614b8b565b90975095508661089c5760006040518060200160405280600081525060049650965096505050506108ec565b60185486517401000000000000000000000000000000000000000090910463ffffffff1610156108e85760006040518060200160405280600081525060059650965096505050506108ec565b5050505b92959194509250565b6108fe83612ae6565b6000838152601d60205260409020610917828483614c70565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664838360405161094a929190614dd4565b60405180910390a2505050565b61096081612ae6565b600081815260046020908152604091829020825161012081018452815460ff808216151580845261010080840490921615159584019590955262010000820463ffffffff9081169684019690965266010000000000008204861660608401526a010000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff908116608084015260018401546fffffffffffffffffffffffffffffffff811660a085015270010000000000000000000000000000000081046bffffffffffffffffffffffff1660c08501527c0100000000000000000000000000000000000000000000000000000000900490951660e083015260029092015490931690830152610a9a576040517f1b88a78400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610ad9600283612c0c565b5060405182907f7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a4745690600090a25050565b610b11612c21565b73ffffffffffffffffffffffffffffffffffffffff8216610b5e576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b68612c72565b90506000811215610bb4576040517fcf47918100000000000000000000000000000000000000000000000000000000815260006004820152602481018390526044015b60405180910390fd5b80821115610bf8576040517fcf4791810000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610bab565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490526000917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015610c92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb69190614de8565b905080610cef576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f5e110f8bc8a20b65dcc87f224bdf1cc039346e267118bae2739847f07321ffa885604051610d6e91815260200190565b60405180910390a350505050565b610d84612c21565b73ffffffffffffffffffffffffffffffffffffffff8216610dd1576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610e56576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610e60612c72565b128015610e835750600060255460ff166001811115610e8157610e816146b9565b145b15610eba576040517f981bb6a000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000818152602160205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152919290916370a0823190602401602060405180830381865afa158015610f36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5a9190614e03565b610f649190614b23565b905080821115610faa576040517fcf4791810000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610bab565b610fcb73ffffffffffffffffffffffffffffffffffffffff85168484612d41565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f5e110f8bc8a20b65dcc87f224bdf1cc039346e267118bae2739847f07321ffa884604051610d6e91815260200190565b60006060600080600080600061103e612b9b565b60006110498a612e1a565b905060006014604051806101200160405290816000820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160139054906101000a900461ffff1661ffff1661ffff1681526020016000820160159054906101000a900460ff1660ff1660ff1681526020016000820160169054906101000a900460ff161515151581526020016000820160179054906101000a900460ff161515151581526020016000820160189054906101000a900460ff161515151581526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000600460008d8152602001908152602001600020604051806101200160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900460ff161515151581526020016000820160029054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160069054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160008201600a9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201601c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000808360a001511561140c5750506040805160208101825260008082529290910151919a5098506009975089965063ffffffff169450859350839250611782915050565b606083015163ffffffff908116146114565750506040805160208101825260008082529290910151919a5098506001975089965063ffffffff169450859350839250611782915050565b8251156114955750506040805160208101825260008082529290910151919a5098506002975089965063ffffffff169450859350839250611782915050565b61149e84612ec5565b8094508198508299505050506114c38e858786604001518b8b888a61010001516130b7565b9050806bffffffffffffffffffffffff168360c001516bffffffffffffffffffffffff1610156115255750506040805160208101825260008082529290910151919a5098506006975089965063ffffffff169450859350839250611782915050565b505060006115348d858e613427565b90505a9750600080836080015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561158b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115af9190614abb565b73ffffffffffffffffffffffffffffffffffffffff16601660000160149054906101000a900463ffffffff1663ffffffff16846040516115ef9190614ad8565b60006040518083038160008787f1925050503d806000811461162d576040519150601f19603f3d011682016040523d82523d6000602084013e611632565b606091505b50915091505a611642908b614b23565b9950816116c8576018548151780100000000000000000000000000000000000000000000000090910463ffffffff1610156116a75750506040805160208101825260008082529390910151929b509950600898505063ffffffff169450611782915050565b604090930151929a50600399505063ffffffff909116955061178292505050565b808060200190518101906116dc9190614b8b565b909d509b508c6117165750506040805160208101825260008082529390910151929b509950600498505063ffffffff169450611782915050565b6018548c517401000000000000000000000000000000000000000090910463ffffffff1610156117705750506040805160208101825260008082529390910151929b509950600598505063ffffffff169450611782915050565b5050506040015163ffffffff16945050505b92959891949750929550565b611796613607565b600081815260046020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055602390915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000001690555182917f97d0ef3f46a56168af653f547bdb6f77ec2b1d7d9bc6ba0193c2b340ec68064a91a250565b60145477010000000000000000000000000000000000000000000000900460ff161561187c576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff167701000000000000000000000000000000000000000000000017905573ffffffffffffffffffffffffffffffffffffffff811661190b576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600460209081526040808320815161012081018352815460ff8082161515835261010080830490911615158387015263ffffffff620100008304811684870152660100000000000083048116606085015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009093048316608085015260018501546fffffffffffffffffffffffffffffffff811660a08601526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08601527c010000000000000000000000000000000000000000000000000000000090041660e084015260029093015481169282019290925286855260059093529220549091163314611a4b576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601554604080517f57e871e7000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216916357e871e7916004808201926020929091908290030181865afa158015611abb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611adf9190614e03565b816060015163ffffffff161115611b22576040517fff84e5dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526004602090815260408083206001015461010085015173ffffffffffffffffffffffffffffffffffffffff1684526021909252909120547001000000000000000000000000000000009091046bffffffffffffffffffffffff1690611b8d908290614b23565b6101008301805173ffffffffffffffffffffffffffffffffffffffff908116600090815260216020908152604080832095909555888252600490529290922060010180547fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff16905551611c109116846bffffffffffffffffffffffff8416612d41565b604080516bffffffffffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff8516602082015285917ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318910160405180910390a25050601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611d1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610bab565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611da281612ae6565b600081815260046020908152604091829020825161012081018452815460ff808216158015845261010080840490921615159584019590955262010000820463ffffffff9081169684019690965266010000000000008204861660608401526a010000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff908116608084015260018401546fffffffffffffffffffffffffffffffff811660a085015270010000000000000000000000000000000081046bffffffffffffffffffffffff1660c08501527c0100000000000000000000000000000000000000000000000000000000900490951660e083015260029092015490931690830152611edc576040517f514b6c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611f1e600283613658565b5060405182907f8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f90600090a25050565b611f5783612ae6565b6000838152601e60205260409020611f70828483614c70565b50827f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf4850838360405161094a929190614dd4565b600082815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615159483019490945263ffffffff6201000082048116958301959095526601000000000000810485166060830181905273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009092048216608084015260018401546fffffffffffffffffffffffffffffffff811660a08501526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08501527c01000000000000000000000000000000000000000000000000000000009004861660e084015260029093015416928101929092529091146120df576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b341561217b577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681610100015173ffffffffffffffffffffffffffffffffffffffff161461216f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61217834613664565b91505b818160c0015161218b9190614e1c565b600084815260046020908152604080832060010180547fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000006bffffffffffffffffffffffff9687160217905561010085015173ffffffffffffffffffffffffffffffffffffffff168352602190915290205461221b91841690614e41565b61010082015173ffffffffffffffffffffffffffffffffffffffff1660009081526021602052604081209190915534900361228b576101008101516122869073ffffffffffffffffffffffffffffffffffffffff1633306bffffffffffffffffffffffff8616613706565b61231b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836bffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016000604051808303818588803b15801561230157600080fd5b505af1158015612315573d6000803e3d6000fd5b50505050505b6040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b6108fc8163ffffffff1610806123a2575060165463ffffffff78010000000000000000000000000000000000000000000000009091048116908216115b156123d9576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e282612ae6565b60008281526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffff166201000063ffffffff861690810291909117909155915191825283917fc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c91015b60405180910390a25050565b61246c613607565b6000828152600460205260409020546601000000000000900463ffffffff908116146124c4576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790556023909152902081906125128282614e65565b905050817fd8a6d79d170a55968079d3a89b960d86b4442aef6aac1d01e644c32b9e38b340826040516124589190614eec565b600080612550612b9b565b601454760100000000000000000000000000000000000000000000900460ff16156125a7576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615158386015262010000820463ffffffff90811684880181905266010000000000008404821660608601526a010000000000000000000090930473ffffffffffffffffffffffffffffffffffffffff9081166080860181905260018701546fffffffffffffffffffffffffffffffff811660a088015270010000000000000000000000000000000081046bffffffffffffffffffffffff1660c08801527c0100000000000000000000000000000000000000000000000000000000900490921660e0860152600290950154909416908301528451601f890185900485028101850190955287855290936126e393899089908190840183828082843760009201919091525061376a92505050565b9097909650945050505050565b600081815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615159483019490945263ffffffff6201000082048116958301959095526601000000000000810485166060830181905273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009092048216608084015260018401546fffffffffffffffffffffffffffffffff811660a08501526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08501527c01000000000000000000000000000000000000000000000000000000009004861660e0840152600290930154169281019290925290911461282c576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff163314612889576040517f6352a85300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260408083208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821790935560069094528285208054909216909155905173ffffffffffffffffffffffffffffffffffffffff90911692839186917f5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c91a4505050565b61292683612ae6565b6017547c0100000000000000000000000000000000000000000000000000000000900463ffffffff16811115612988576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526007602052604090206129a1828483614c70565b50827fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d838360405161094a929190614dd4565b600060606000806000634b56a42e60e01b8888886040516024016129fa93929190614f23565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050612a838982610617565b929c919b50995090975095505050505050565b612a9e613985565b612aa781613a06565b50565b600060606000806000806000612acf886040518060200160405280600081525061102a565b959e949d50929b5090995097509550909350915050565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314612b43576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020546601000000000000900463ffffffff90811614612aa7576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614612c0a576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612c188383613afb565b90505b92915050565b60185473ffffffffffffffffffffffffffffffffffffffff163314612c0a576040517fb6dfb7a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166000818152602160205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152919290916370a0823190602401602060405180830381865afa158015612d0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d329190614e03565b612d3c9190614fb9565b905090565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612e159084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613b4a565b505050565b6000818160045b600f811015612ea7577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612e5f57612e5f614fd9565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612e9557506000949350505050565b80612e9f81615008565b915050612e21565b5081600f1a6001811115612ebd57612ebd6146b9565b949350505050565b600080600080846040015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612f52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f76919061505a565b5094509092505050600081131580612f8d57508142105b80612fae5750828015612fae5750612fa58242614b23565b8463ffffffff16105b15612fbd576019549650612fc1565b8096505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561302c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613050919061505a565b509450909250505060008113158061306757508142105b806130885750828015613088575061307f8242614b23565b8463ffffffff16105b1561309757601a54955061309b565b8095505b86866130a68a613c56565b965096509650505050509193909250565b60008080808960018111156130ce576130ce6146b9565b036130dd575062017f98613132565b60018960018111156130f1576130f16146b9565b0361310057506201de84613132565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008a60800151600161314591906150aa565b6131539060ff1660406150c3565b601854613181906103a49074010000000000000000000000000000000000000000900463ffffffff16614e41565b61318b9190614e41565b601554604080517fde9ee35e0000000000000000000000000000000000000000000000000000000081528151939450600093849373ffffffffffffffffffffffffffffffffffffffff169263de9ee35e92600480820193918290030181865afa1580156131fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061322091906150da565b90925090508183613232836018614e41565b61323c91906150c3565b60808f015161324c9060016150aa565b61325b9060ff166115e06150c3565b6132659190614e41565b61326f9190614e41565b6132799085614e41565b6101008e01516040517f125441400000000000000000000000000000000000000000000000000000000081526004810186905291955073ffffffffffffffffffffffffffffffffffffffff1690631254414090602401602060405180830381865afa1580156132ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133109190614e03565b8d6060015161ffff1661332391906150c3565b945050505060006133348b86613d47565b60008d815260046020526040902054909150610100900460ff16156133995760008c81526023602090815260409182902082518084018452905463ffffffff811680835264010000000090910462ffffff908116928401928352928501525116908201525b60006134038c6040518061012001604052808d63ffffffff1681526020018681526020018781526020018c81526020018b81526020018a81526020018973ffffffffffffffffffffffffffffffffffffffff16815260200185815260200160001515815250613ec3565b6020810151815191925061341691614e1c565b9d9c50505050505050505050505050565b6060600083600181111561343d5761343d6146b9565b03613506576000848152600760205260409081902090517f6e04ff0d000000000000000000000000000000000000000000000000000000009161348291602401615199565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050613600565b600183600181111561351a5761351a6146b9565b03613100576000828060200190518101906135359190615212565b6000868152600760205260409081902090519192507f40691db4000000000000000000000000000000000000000000000000000000009161357a918491602401615322565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915291506136009050565b9392505050565b60175473ffffffffffffffffffffffffffffffffffffffff163314612c0a576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612c18838361420a565b60006bffffffffffffffffffffffff821115613702576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610bab565b5090565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526137649085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612d93565b50505050565b601454600090819077010000000000000000000000000000000000000000000000900460ff16156137c7576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000001790556040517f4585e33b000000000000000000000000000000000000000000000000000000009061383c9085906024016153ed565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d169061390f9087908790600401615400565b60408051808303816000875af115801561392d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139519190615419565b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612c0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610bab565b3373ffffffffffffffffffffffffffffffffffffffff821603613a85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610bab565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054613b4257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612c1b565b506000612c1b565b6000613bac826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166142fd9092919063ffffffff16565b805190915015612e155780806020019051810190613bca9190614de8565b612e15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610bab565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613cc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cea919061505a565b50935050925050600082131580613d0057508042105b80613d3057506000846040015162ffffff16118015613d305750613d248142614b23565b846040015162ffffff16105b15613d40575050601b5492915050565b5092915050565b60408051608081018252600080825260208083018281528385018381526060850184905273ffffffffffffffffffffffffffffffffffffffff878116855260229093528584208054640100000000810462ffffff1690925263ffffffff82169092527b01000000000000000000000000000000000000000000000000000000810460ff16855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495919484936701000000000000009092049091169163feaf968c9160048083019260a09291908290030181865afa158015613e34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e58919061505a565b50935050925050600082131580613e6e57508042105b80613e9e57506000866040015162ffffff16118015613e9e5750613e928142614b23565b866040015162ffffff16105b15613eb25760018301546060850152613eba565b606084018290525b50505092915050565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915260008260e001516000015160ff1690506000846060015161ffff168460600151613f2e91906150c3565b90508361010001518015613f415750803a105b15613f4957503a5b600060128311613f5a576001613f70565b613f65601284614b23565b613f7090600a615565565b9050600060128410613f83576001613f99565b613f8e846012614b23565b613f9990600a615565565b905060008660a00151876040015188602001518960000151613fbb9190614e41565b613fc590876150c3565b613fcf9190614e41565b613fd991906150c3565b9050614035828860e0015160600151613ff291906150c3565b6001848a60e001516060015161400891906150c3565b6140129190614b23565b61401c86856150c3565b6140269190614e41565b6140309190615571565b613664565b6bffffffffffffffffffffffff1686526080870151614058906140309083615571565b6bffffffffffffffffffffffff1660408088019190915260e088015101516000906140919062ffffff16683635c9adc5dea000006150c3565b9050600081633b9aca008a60a001518b60e001516020015163ffffffff168c604001518d600001518b6140c491906150c3565b6140ce9190614e41565b6140d891906150c3565b6140e291906150c3565b6140ec9190615571565b6140f69190614e41565b9050614139848a60e001516060015161410f91906150c3565b6001868c60e001516060015161412591906150c3565b61412f9190614b23565b61401c88856150c3565b6bffffffffffffffffffffffff166020890152608089015161415f906140309083615571565b6bffffffffffffffffffffffff16606089015260c089015173ffffffffffffffffffffffffffffffffffffffff166080808a01919091528901516141a290613664565b6bffffffffffffffffffffffff1660a0808a01919091528901516141c590613664565b6bffffffffffffffffffffffff1660c089015260e0890151606001516141ea90613664565b6bffffffffffffffffffffffff1660e08901525050505050505092915050565b600081815260018301602052604081205480156142f357600061422e600183614b23565b855490915060009061424290600190614b23565b90508181146142a757600086600001828154811061426257614262614fd9565b906000526020600020015490508087600001848154811061428557614285614fd9565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806142b8576142b86155ac565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612c1b565b6000915050612c1b565b6060612ebd8484600085856000808673ffffffffffffffffffffffffffffffffffffffff1685876040516143319190614ad8565b60006040518083038185875af1925050503d806000811461436e576040519150601f19603f3d011682016040523d82523d6000602084013e614373565b606091505b50915091506143848783838761438f565b979650505050505050565b6060831561442557825160000361441e5773ffffffffffffffffffffffffffffffffffffffff85163b61441e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610bab565b5081612ebd565b612ebd838381511561443a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bab91906153ed565b73ffffffffffffffffffffffffffffffffffffffff81168114612aa757600080fd5b600080604083850312156144a357600080fd5b8235915060208301356144b58161446e565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715614513576145136144c0565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614560576145606144c0565b604052919050565b600067ffffffffffffffff821115614582576145826144c0565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126145bf57600080fd5b81356145d26145cd82614568565b614519565b8181528460208386010111156145e757600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561461757600080fd5b82359150602083013567ffffffffffffffff81111561463557600080fd5b614641858286016145ae565b9150509250929050565b60005b8381101561466657818101518382015260200161464e565b50506000910152565b6000815180845261468781602086016020860161464b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a811061471f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b841515815260806020820152600061473e608083018661466f565b905061474d60408301856146e8565b82606083015295945050505050565b60008083601f84011261476e57600080fd5b50813567ffffffffffffffff81111561478657600080fd5b60208301915083602082850101111561479e57600080fd5b9250929050565b6000806000604084860312156147ba57600080fd5b83359250602084013567ffffffffffffffff8111156147d857600080fd5b6147e48682870161475c565b9497909650939450505050565b60006020828403121561480357600080fd5b5035919050565b6000806040838503121561481d57600080fd5b82356148288161446e565b946020939093013593505050565b60008060006060848603121561484b57600080fd5b83356148568161446e565b925060208401356148668161446e565b929592945050506040919091013590565b871515815260e06020820152600061489260e083018961466f565b90506148a160408301886146e8565b8560608301528460808301528360a08301528260c083015298975050505050505050565b600080604083850312156148d857600080fd5b8235915060208301356bffffffffffffffffffffffff811681146144b557600080fd5b63ffffffff81168114612aa757600080fd5b6000806040838503121561492057600080fd5b8235915060208301356144b5816148fb565b600080828403606081121561494657600080fd5b8335925060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561497a57600080fd5b506020830190509250929050565b600067ffffffffffffffff8211156149a2576149a26144c0565b5060051b60200190565b600080600080606085870312156149c257600080fd5b8435935060208086013567ffffffffffffffff808211156149e257600080fd5b818801915088601f8301126149f657600080fd5b8135614a046145cd82614988565b81815260059190911b8301840190848101908b831115614a2357600080fd5b8585015b83811015614a5b57803585811115614a3f5760008081fd5b614a4d8e89838a01016145ae565b845250918601918601614a27565b50975050506040880135925080831115614a7457600080fd5b5050614a828782880161475c565b95989497509550505050565b600060208284031215614aa057600080fd5b81356136008161446e565b8051614ab68161446e565b919050565b600060208284031215614acd57600080fd5b81516136008161446e565b60008251614aea81846020870161464b565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115612c1b57612c1b614af4565b80518015158114614ab657600080fd5b600082601f830112614b5757600080fd5b8151614b656145cd82614568565b818152846020838601011115614b7a57600080fd5b612ebd82602083016020870161464b565b60008060408385031215614b9e57600080fd5b614ba783614b36565b9150602083015167ffffffffffffffff811115614bc357600080fd5b61464185828601614b46565b600181811c90821680614be357607f821691505b602082108103614c1c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115612e1557600081815260208120601f850160051c81016020861015614c495750805b601f850160051c820191505b81811015614c6857828155600101614c55565b505050505050565b67ffffffffffffffff831115614c8857614c886144c0565b614c9c83614c968354614bcf565b83614c22565b6000601f841160018114614cee5760008515614cb85750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614d84565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015614d3d5786850135825560209485019460019092019101614d1d565b5086821015614d78577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000612ebd602083018486614d8b565b600060208284031215614dfa57600080fd5b612c1882614b36565b600060208284031215614e1557600080fd5b5051919050565b6bffffffffffffffffffffffff818116838216019080821115613d4057613d40614af4565b80820180821115612c1b57612c1b614af4565b62ffffff81168114612aa757600080fd5b8135614e70816148fb565b63ffffffff811690508154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000082161783556020840135614eb081614e54565b66ffffff000000008160201b16837fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000008416171784555050505050565b604081018235614efb816148fb565b63ffffffff1682526020830135614f1181614e54565b62ffffff811660208401525092915050565b6000604082016040835280865180835260608501915060608160051b8601019250602080890160005b83811015614f98577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552614f8686835161466f565b95509382019390820190600101614f4c565b505085840381870152505050614faf818587614d8b565b9695505050505050565b8181036000831280158383131683831282161715613d4057613d40614af4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361503957615039614af4565b5060010190565b805169ffffffffffffffffffff81168114614ab657600080fd5b600080600080600060a0868803121561507257600080fd5b61507b86615040565b945060208601519350604086015192506060860151915061509e60808701615040565b90509295509295909350565b60ff8181168382160190811115612c1b57612c1b614af4565b8082028115828204841417612c1b57612c1b614af4565b600080604083850312156150ed57600080fd5b505080516020909101519092909150565b6000815461510b81614bcf565b80855260206001838116801561512857600181146151605761518e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955061518e565b866000528260002060005b858110156151865781548a820186015290830190840161516b565b890184019650505b505050505092915050565b602081526000612c1860208301846150fe565b600082601f8301126151bd57600080fd5b815160206151cd6145cd83614988565b82815260059290921b840181019181810190868411156151ec57600080fd5b8286015b8481101561520757805183529183019183016151f0565b509695505050505050565b60006020828403121561522457600080fd5b815167ffffffffffffffff8082111561523c57600080fd5b90830190610100828603121561525157600080fd5b6152596144ef565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015261529160a08401614aab565b60a082015260c0830151828111156152a857600080fd5b6152b4878286016151ac565b60c08301525060e0830151828111156152cc57600080fd5b6152d887828601614b46565b60e08301525095945050505050565b600081518084526020808501945080840160005b83811015615317578151875295820195908201906001016152fb565b509495945050505050565b60408152825160408201526020830151606082015260408301516080820152606083015160a0820152608083015160c082015273ffffffffffffffffffffffffffffffffffffffff60a08401511660e0820152600060c08401516101008081850152506153936101408401826152e7565b905060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0848303016101208501526153cf828261466f565b91505082810360208401526153e481856150fe565b95945050505050565b602081526000612c18602083018461466f565b828152604060208201526000612ebd604083018461466f565b6000806040838503121561542c57600080fd5b61543583614b36565b9150602083015190509250929050565b600181815b8085111561549e57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561548457615484614af4565b8085161561549157918102915b93841c939080029061544a565b509250929050565b6000826154b557506001612c1b565b816154c257506000612c1b565b81600181146154d857600281146154e2576154fe565b6001915050612c1b565b60ff8411156154f3576154f3614af4565b50506001821b612c1b565b5060208310610133831016604e8410600b8410161715615521575081810a612c1b565b61552b8383615445565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561555d5761555d614af4565b029392505050565b6000612c1883836154a6565b6000826155a7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", + Bin: "0x6101806040523480156200001257600080fd5b5060405162005d2238038062005d2283398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e051610100516101205161014051610160516155e86200073a60003960008181610182015261022f0152600081816120e7015261228d01526000612bb30152600050506000612ee901526000613c5d01526000612fc3015260008181610c4701528181610d0801528181610dd30152612c7401526155e86000f3fe6080604052600436106101805760003560e01c80638765ecbe116100d6578063aed2e9291161007f578063ce7dc5b411610059578063ce7dc5b4146104b1578063f2fde38b146104d1578063f7d334ba146104f157610180565b8063aed2e9291461043a578063b148ab6b14610471578063cd7f71b51461049157610180565b8063948108f7116100b0578063948108f7146103e7578063a72aa27e146103fa578063a86e17811461041a57610180565b80638765ecbe1461037c5780638da5cb5b1461039c5780638dcf0fe7146103c757610180565b806354b7faae1161013857806371fae17f1161011257806371fae17f14610327578063744bfe611461034757806379ba50971461036757610180565b806354b7faae146102b457806368d369d8146102d457806371791aa0146102f457610180565b8063349e8cca11610169578063349e8cca146102205780634ee88d35146102745780635165f2f51461029457610180565b80631a2af011146101c757806329c5efad146101e7575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156101c0573d6000f35b3d6000fd5b005b3480156101d357600080fd5b506101c56101e2366004614490565b610511565b3480156101f357600080fd5b50610207610202366004614604565b610617565b6040516102179493929190614723565b60405180910390f35b34801561022c57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610217565b34801561028057600080fd5b506101c561028f3660046147a5565b6108f5565b3480156102a057600080fd5b506101c56102af3660046147f1565b610957565b3480156102c057600080fd5b506101c56102cf36600461480a565b610b09565b3480156102e057600080fd5b506101c56102ef366004614836565b610d7c565b34801561030057600080fd5b5061031461030f366004614604565b61102a565b6040516102179796959493929190614877565b34801561033357600080fd5b506101c56103423660046147f1565b61178e565b34801561035357600080fd5b506101c5610362366004614490565b611824565b34801561037357600080fd5b506101c5611c9c565b34801561038857600080fd5b506101c56103973660046147f1565b611d99565b3480156103a857600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661024f565b3480156103d357600080fd5b506101c56103e23660046147a5565b611f4e565b6101c56103f53660046148c5565b611fa3565b34801561040657600080fd5b506101c561041536600461490d565b612365565b34801561042657600080fd5b506101c5610435366004614932565b612464565b34801561044657600080fd5b5061045a6104553660046147a5565b612545565b604080519215158352602083019190915201610217565b34801561047d57600080fd5b506101c561048c3660046147f1565b6126f0565b34801561049d57600080fd5b506101c56104ac3660046147a5565b61291d565b3480156104bd57600080fd5b506102076104cc3660046149ac565b6129d4565b3480156104dd57600080fd5b506101c56104ec366004614a8e565b612a96565b3480156104fd57600080fd5b5061031461050c3660046147f1565b612aaa565b61051a82612ae6565b3373ffffffffffffffffffffffffffffffffffffffff821603610569576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116146106135760008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917fb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b3591a45b5050565b60006060600080610626612b9b565b600086815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615159483019490945263ffffffff620100008204811695830195909552660100000000000081048516606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490941660e0820152600290910154909216908201525a9150600080826080015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561077c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a09190614abb565b73ffffffffffffffffffffffffffffffffffffffff16601660000160149054906101000a900463ffffffff1663ffffffff16896040516107e09190614ad8565b60006040518083038160008787f1925050503d806000811461081e576040519150601f19603f3d011682016040523d82523d6000602084013e610823565b606091505b50915091505a6108339085614b23565b93508161085c5760006040518060200160405280600081525060079650965096505050506108ec565b808060200190518101906108709190614b8b565b90975095508661089c5760006040518060200160405280600081525060049650965096505050506108ec565b60185486517401000000000000000000000000000000000000000090910463ffffffff1610156108e85760006040518060200160405280600081525060059650965096505050506108ec565b5050505b92959194509250565b6108fe83612ae6565b6000838152601d60205260409020610917828483614c70565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664838360405161094a929190614dd4565b60405180910390a2505050565b61096081612ae6565b600081815260046020908152604091829020825161012081018452815460ff808216151580845261010080840490921615159584019590955262010000820463ffffffff9081169684019690965266010000000000008204861660608401526a010000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff908116608084015260018401546fffffffffffffffffffffffffffffffff811660a085015270010000000000000000000000000000000081046bffffffffffffffffffffffff1660c08501527c0100000000000000000000000000000000000000000000000000000000900490951660e083015260029092015490931690830152610a9a576040517f1b88a78400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610ad9600283612c0c565b5060405182907f7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a4745690600090a25050565b610b11612c21565b73ffffffffffffffffffffffffffffffffffffffff8216610b5e576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b68612c72565b90506000811215610bb4576040517fcf47918100000000000000000000000000000000000000000000000000000000815260006004820152602481018390526044015b60405180910390fd5b80821115610bf8576040517fcf4791810000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610bab565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490526000917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015610c92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb69190614de8565b905080610cef576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f5e110f8bc8a20b65dcc87f224bdf1cc039346e267118bae2739847f07321ffa885604051610d6e91815260200190565b60405180910390a350505050565b610d84612c21565b73ffffffffffffffffffffffffffffffffffffffff8216610dd1576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610e56576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610e60612c72565b128015610e835750600060255460ff166001811115610e8157610e816146b9565b145b15610eba576040517f981bb6a000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000818152602160205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152919290916370a0823190602401602060405180830381865afa158015610f36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5a9190614e03565b610f649190614b23565b905080821115610faa576040517fcf4791810000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610bab565b610fcb73ffffffffffffffffffffffffffffffffffffffff85168484612d41565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f5e110f8bc8a20b65dcc87f224bdf1cc039346e267118bae2739847f07321ffa884604051610d6e91815260200190565b60006060600080600080600061103e612b9b565b60006110498a612e1a565b905060006014604051806101200160405290816000820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160139054906101000a900461ffff1661ffff1661ffff1681526020016000820160159054906101000a900460ff1660ff1660ff1681526020016000820160169054906101000a900460ff161515151581526020016000820160179054906101000a900460ff161515151581526020016000820160189054906101000a900460ff161515151581526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000600460008d8152602001908152602001600020604051806101200160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900460ff161515151581526020016000820160029054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160069054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160008201600a9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201601c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000808360a001511561140c5750506040805160208101825260008082529290910151919a5098506009975089965063ffffffff169450859350839250611782915050565b606083015163ffffffff908116146114565750506040805160208101825260008082529290910151919a5098506001975089965063ffffffff169450859350839250611782915050565b8251156114955750506040805160208101825260008082529290910151919a5098506002975089965063ffffffff169450859350839250611782915050565b61149e84612ec5565b8094508198508299505050506114c38e858786604001518b8b888a61010001516130b7565b9050806bffffffffffffffffffffffff168360c001516bffffffffffffffffffffffff1610156115255750506040805160208101825260008082529290910151919a5098506006975089965063ffffffff169450859350839250611782915050565b505060006115348d858e613427565b90505a9750600080836080015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561158b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115af9190614abb565b73ffffffffffffffffffffffffffffffffffffffff16601660000160149054906101000a900463ffffffff1663ffffffff16846040516115ef9190614ad8565b60006040518083038160008787f1925050503d806000811461162d576040519150601f19603f3d011682016040523d82523d6000602084013e611632565b606091505b50915091505a611642908b614b23565b9950816116c8576018548151780100000000000000000000000000000000000000000000000090910463ffffffff1610156116a75750506040805160208101825260008082529390910151929b509950600898505063ffffffff169450611782915050565b604090930151929a50600399505063ffffffff909116955061178292505050565b808060200190518101906116dc9190614b8b565b909d509b508c6117165750506040805160208101825260008082529390910151929b509950600498505063ffffffff169450611782915050565b6018548c517401000000000000000000000000000000000000000090910463ffffffff1610156117705750506040805160208101825260008082529390910151929b509950600598505063ffffffff169450611782915050565b5050506040015163ffffffff16945050505b92959891949750929550565b611796613607565b600081815260046020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055602390915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000001690555182917f97d0ef3f46a56168af653f547bdb6f77ec2b1d7d9bc6ba0193c2b340ec68064a91a250565b60145477010000000000000000000000000000000000000000000000900460ff161561187c576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff167701000000000000000000000000000000000000000000000017905573ffffffffffffffffffffffffffffffffffffffff811661190b576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600460209081526040808320815161012081018352815460ff8082161515835261010080830490911615158387015263ffffffff620100008304811684870152660100000000000083048116606085015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009093048316608085015260018501546fffffffffffffffffffffffffffffffff811660a08601526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08601527c010000000000000000000000000000000000000000000000000000000090041660e084015260029093015481169282019290925286855260059093529220549091163314611a4b576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601554604080517f57e871e7000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216916357e871e7916004808201926020929091908290030181865afa158015611abb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611adf9190614e03565b816060015163ffffffff161115611b22576040517fff84e5dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526004602090815260408083206001015461010085015173ffffffffffffffffffffffffffffffffffffffff1684526021909252909120547001000000000000000000000000000000009091046bffffffffffffffffffffffff1690611b8d908290614b23565b6101008301805173ffffffffffffffffffffffffffffffffffffffff908116600090815260216020908152604080832095909555888252600490529290922060010180547fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff16905551611c109116846bffffffffffffffffffffffff8416612d41565b604080516bffffffffffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff8516602082015285917ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318910160405180910390a25050601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611d1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610bab565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611da281612ae6565b600081815260046020908152604091829020825161012081018452815460ff808216158015845261010080840490921615159584019590955262010000820463ffffffff9081169684019690965266010000000000008204861660608401526a010000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff908116608084015260018401546fffffffffffffffffffffffffffffffff811660a085015270010000000000000000000000000000000081046bffffffffffffffffffffffff1660c08501527c0100000000000000000000000000000000000000000000000000000000900490951660e083015260029092015490931690830152611edc576040517f514b6c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611f1e600283613658565b5060405182907f8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f90600090a25050565b611f5783612ae6565b6000838152601e60205260409020611f70828483614c70565b50827f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf4850838360405161094a929190614dd4565b600082815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615159483019490945263ffffffff6201000082048116958301959095526601000000000000810485166060830181905273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009092048216608084015260018401546fffffffffffffffffffffffffffffffff811660a08501526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08501527c01000000000000000000000000000000000000000000000000000000009004861660e084015260029093015416928101929092529091146120df576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b341561217b577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681610100015173ffffffffffffffffffffffffffffffffffffffff161461216f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61217834613664565b91505b818160c0015161218b9190614e1c565b600084815260046020908152604080832060010180547fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000006bffffffffffffffffffffffff9687160217905561010085015173ffffffffffffffffffffffffffffffffffffffff168352602190915290205461221b91841690614e41565b61010082015173ffffffffffffffffffffffffffffffffffffffff1660009081526021602052604081209190915534900361228b576101008101516122869073ffffffffffffffffffffffffffffffffffffffff1633306bffffffffffffffffffffffff8616613706565b61231b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836bffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016000604051808303818588803b15801561230157600080fd5b505af1158015612315573d6000803e3d6000fd5b50505050505b6040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b6108fc8163ffffffff1610806123a2575060165463ffffffff78010000000000000000000000000000000000000000000000009091048116908216115b156123d9576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e282612ae6565b60008281526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffff166201000063ffffffff861690810291909117909155915191825283917fc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c91015b60405180910390a25050565b61246c613607565b6000828152600460205260409020546601000000000000900463ffffffff908116146124c4576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790556023909152902081906125128282614e65565b905050817fd8a6d79d170a55968079d3a89b960d86b4442aef6aac1d01e644c32b9e38b340826040516124589190614eec565b600080612550612b9b565b601454760100000000000000000000000000000000000000000000900460ff16156125a7576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615158386015262010000820463ffffffff90811684880181905266010000000000008404821660608601526a010000000000000000000090930473ffffffffffffffffffffffffffffffffffffffff9081166080860181905260018701546fffffffffffffffffffffffffffffffff811660a088015270010000000000000000000000000000000081046bffffffffffffffffffffffff1660c08801527c0100000000000000000000000000000000000000000000000000000000900490921660e0860152600290950154909416908301528451601f890185900485028101850190955287855290936126e393899089908190840183828082843760009201919091525061376a92505050565b9097909650945050505050565b600081815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615159483019490945263ffffffff6201000082048116958301959095526601000000000000810485166060830181905273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009092048216608084015260018401546fffffffffffffffffffffffffffffffff811660a08501526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08501527c01000000000000000000000000000000000000000000000000000000009004861660e0840152600290930154169281019290925290911461282c576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff163314612889576040517f6352a85300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260408083208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821790935560069094528285208054909216909155905173ffffffffffffffffffffffffffffffffffffffff90911692839186917f5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c91a4505050565b61292683612ae6565b6017547c0100000000000000000000000000000000000000000000000000000000900463ffffffff16811115612988576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526007602052604090206129a1828483614c70565b50827fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d838360405161094a929190614dd4565b600060606000806000634b56a42e60e01b8888886040516024016129fa93929190614f23565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050612a838982610617565b929c919b50995090975095505050505050565b612a9e613985565b612aa781613a06565b50565b600060606000806000806000612acf886040518060200160405280600081525061102a565b959e949d50929b5090995097509550909350915050565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314612b43576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020546601000000000000900463ffffffff90811614612aa7576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614612c0a576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612c188383613afb565b90505b92915050565b60185473ffffffffffffffffffffffffffffffffffffffff163314612c0a576040517fb6dfb7a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166000818152602160205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152919290916370a0823190602401602060405180830381865afa158015612d0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d329190614e03565b612d3c9190614fb9565b905090565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612e159084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613b4a565b505050565b6000818160045b600f811015612ea7577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612e5f57612e5f614fd9565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612e9557506000949350505050565b80612e9f81615008565b915050612e21565b5081600f1a6001811115612ebd57612ebd6146b9565b949350505050565b600080600080846040015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612f52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f76919061505a565b5094509092505050600081131580612f8d57508142105b80612fae5750828015612fae5750612fa58242614b23565b8463ffffffff16105b15612fbd576019549650612fc1565b8096505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561302c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613050919061505a565b509450909250505060008113158061306757508142105b806130885750828015613088575061307f8242614b23565b8463ffffffff16105b1561309757601a54955061309b565b8095505b86866130a68a613c56565b965096509650505050509193909250565b60008080808960018111156130ce576130ce6146b9565b036130dd575062017f98613132565b60018960018111156130f1576130f16146b9565b0361310057506201e26c613132565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008a60800151600161314591906150aa565b6131539060ff1660406150c3565b601854613181906103a49074010000000000000000000000000000000000000000900463ffffffff16614e41565b61318b9190614e41565b601554604080517fde9ee35e0000000000000000000000000000000000000000000000000000000081528151939450600093849373ffffffffffffffffffffffffffffffffffffffff169263de9ee35e92600480820193918290030181865afa1580156131fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061322091906150da565b90925090508183613232836018614e41565b61323c91906150c3565b60808f015161324c9060016150aa565b61325b9060ff166115e06150c3565b6132659190614e41565b61326f9190614e41565b6132799085614e41565b6101008e01516040517f125441400000000000000000000000000000000000000000000000000000000081526004810186905291955073ffffffffffffffffffffffffffffffffffffffff1690631254414090602401602060405180830381865afa1580156132ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133109190614e03565b8d6060015161ffff1661332391906150c3565b945050505060006133348b86613d47565b60008d815260046020526040902054909150610100900460ff16156133995760008c81526023602090815260409182902082518084018452905463ffffffff811680835264010000000090910462ffffff908116928401928352928501525116908201525b60006134038c6040518061012001604052808d63ffffffff1681526020018681526020018781526020018c81526020018b81526020018a81526020018973ffffffffffffffffffffffffffffffffffffffff16815260200185815260200160001515815250613ec3565b6020810151815191925061341691614e1c565b9d9c50505050505050505050505050565b6060600083600181111561343d5761343d6146b9565b03613506576000848152600760205260409081902090517f6e04ff0d000000000000000000000000000000000000000000000000000000009161348291602401615199565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050613600565b600183600181111561351a5761351a6146b9565b03613100576000828060200190518101906135359190615212565b6000868152600760205260409081902090519192507f40691db4000000000000000000000000000000000000000000000000000000009161357a918491602401615322565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915291506136009050565b9392505050565b60175473ffffffffffffffffffffffffffffffffffffffff163314612c0a576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612c18838361420a565b60006bffffffffffffffffffffffff821115613702576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610bab565b5090565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526137649085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612d93565b50505050565b601454600090819077010000000000000000000000000000000000000000000000900460ff16156137c7576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000001790556040517f4585e33b000000000000000000000000000000000000000000000000000000009061383c9085906024016153ed565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d169061390f9087908790600401615400565b60408051808303816000875af115801561392d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139519190615419565b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612c0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610bab565b3373ffffffffffffffffffffffffffffffffffffffff821603613a85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610bab565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054613b4257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612c1b565b506000612c1b565b6000613bac826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166142fd9092919063ffffffff16565b805190915015612e155780806020019051810190613bca9190614de8565b612e15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610bab565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613cc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cea919061505a565b50935050925050600082131580613d0057508042105b80613d3057506000846040015162ffffff16118015613d305750613d248142614b23565b846040015162ffffff16105b15613d40575050601b5492915050565b5092915050565b60408051608081018252600080825260208083018281528385018381526060850184905273ffffffffffffffffffffffffffffffffffffffff878116855260229093528584208054640100000000810462ffffff1690925263ffffffff82169092527b01000000000000000000000000000000000000000000000000000000810460ff16855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495919484936701000000000000009092049091169163feaf968c9160048083019260a09291908290030181865afa158015613e34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e58919061505a565b50935050925050600082131580613e6e57508042105b80613e9e57506000866040015162ffffff16118015613e9e5750613e928142614b23565b866040015162ffffff16105b15613eb25760018301546060850152613eba565b606084018290525b50505092915050565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915260008260e001516000015160ff1690506000846060015161ffff168460600151613f2e91906150c3565b90508361010001518015613f415750803a105b15613f4957503a5b600060128311613f5a576001613f70565b613f65601284614b23565b613f7090600a615565565b9050600060128410613f83576001613f99565b613f8e846012614b23565b613f9990600a615565565b905060008660a00151876040015188602001518960000151613fbb9190614e41565b613fc590876150c3565b613fcf9190614e41565b613fd991906150c3565b9050614035828860e0015160600151613ff291906150c3565b6001848a60e001516060015161400891906150c3565b6140129190614b23565b61401c86856150c3565b6140269190614e41565b6140309190615571565b613664565b6bffffffffffffffffffffffff1686526080870151614058906140309083615571565b6bffffffffffffffffffffffff1660408088019190915260e088015101516000906140919062ffffff16683635c9adc5dea000006150c3565b9050600081633b9aca008a60a001518b60e001516020015163ffffffff168c604001518d600001518b6140c491906150c3565b6140ce9190614e41565b6140d891906150c3565b6140e291906150c3565b6140ec9190615571565b6140f69190614e41565b9050614139848a60e001516060015161410f91906150c3565b6001868c60e001516060015161412591906150c3565b61412f9190614b23565b61401c88856150c3565b6bffffffffffffffffffffffff166020890152608089015161415f906140309083615571565b6bffffffffffffffffffffffff16606089015260c089015173ffffffffffffffffffffffffffffffffffffffff166080808a01919091528901516141a290613664565b6bffffffffffffffffffffffff1660a0808a01919091528901516141c590613664565b6bffffffffffffffffffffffff1660c089015260e0890151606001516141ea90613664565b6bffffffffffffffffffffffff1660e08901525050505050505092915050565b600081815260018301602052604081205480156142f357600061422e600183614b23565b855490915060009061424290600190614b23565b90508181146142a757600086600001828154811061426257614262614fd9565b906000526020600020015490508087600001848154811061428557614285614fd9565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806142b8576142b86155ac565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612c1b565b6000915050612c1b565b6060612ebd8484600085856000808673ffffffffffffffffffffffffffffffffffffffff1685876040516143319190614ad8565b60006040518083038185875af1925050503d806000811461436e576040519150601f19603f3d011682016040523d82523d6000602084013e614373565b606091505b50915091506143848783838761438f565b979650505050505050565b6060831561442557825160000361441e5773ffffffffffffffffffffffffffffffffffffffff85163b61441e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610bab565b5081612ebd565b612ebd838381511561443a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bab91906153ed565b73ffffffffffffffffffffffffffffffffffffffff81168114612aa757600080fd5b600080604083850312156144a357600080fd5b8235915060208301356144b58161446e565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715614513576145136144c0565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614560576145606144c0565b604052919050565b600067ffffffffffffffff821115614582576145826144c0565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126145bf57600080fd5b81356145d26145cd82614568565b614519565b8181528460208386010111156145e757600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561461757600080fd5b82359150602083013567ffffffffffffffff81111561463557600080fd5b614641858286016145ae565b9150509250929050565b60005b8381101561466657818101518382015260200161464e565b50506000910152565b6000815180845261468781602086016020860161464b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a811061471f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b841515815260806020820152600061473e608083018661466f565b905061474d60408301856146e8565b82606083015295945050505050565b60008083601f84011261476e57600080fd5b50813567ffffffffffffffff81111561478657600080fd5b60208301915083602082850101111561479e57600080fd5b9250929050565b6000806000604084860312156147ba57600080fd5b83359250602084013567ffffffffffffffff8111156147d857600080fd5b6147e48682870161475c565b9497909650939450505050565b60006020828403121561480357600080fd5b5035919050565b6000806040838503121561481d57600080fd5b82356148288161446e565b946020939093013593505050565b60008060006060848603121561484b57600080fd5b83356148568161446e565b925060208401356148668161446e565b929592945050506040919091013590565b871515815260e06020820152600061489260e083018961466f565b90506148a160408301886146e8565b8560608301528460808301528360a08301528260c083015298975050505050505050565b600080604083850312156148d857600080fd5b8235915060208301356bffffffffffffffffffffffff811681146144b557600080fd5b63ffffffff81168114612aa757600080fd5b6000806040838503121561492057600080fd5b8235915060208301356144b5816148fb565b600080828403606081121561494657600080fd5b8335925060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561497a57600080fd5b506020830190509250929050565b600067ffffffffffffffff8211156149a2576149a26144c0565b5060051b60200190565b600080600080606085870312156149c257600080fd5b8435935060208086013567ffffffffffffffff808211156149e257600080fd5b818801915088601f8301126149f657600080fd5b8135614a046145cd82614988565b81815260059190911b8301840190848101908b831115614a2357600080fd5b8585015b83811015614a5b57803585811115614a3f5760008081fd5b614a4d8e89838a01016145ae565b845250918601918601614a27565b50975050506040880135925080831115614a7457600080fd5b5050614a828782880161475c565b95989497509550505050565b600060208284031215614aa057600080fd5b81356136008161446e565b8051614ab68161446e565b919050565b600060208284031215614acd57600080fd5b81516136008161446e565b60008251614aea81846020870161464b565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115612c1b57612c1b614af4565b80518015158114614ab657600080fd5b600082601f830112614b5757600080fd5b8151614b656145cd82614568565b818152846020838601011115614b7a57600080fd5b612ebd82602083016020870161464b565b60008060408385031215614b9e57600080fd5b614ba783614b36565b9150602083015167ffffffffffffffff811115614bc357600080fd5b61464185828601614b46565b600181811c90821680614be357607f821691505b602082108103614c1c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115612e1557600081815260208120601f850160051c81016020861015614c495750805b601f850160051c820191505b81811015614c6857828155600101614c55565b505050505050565b67ffffffffffffffff831115614c8857614c886144c0565b614c9c83614c968354614bcf565b83614c22565b6000601f841160018114614cee5760008515614cb85750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614d84565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015614d3d5786850135825560209485019460019092019101614d1d565b5086821015614d78577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000612ebd602083018486614d8b565b600060208284031215614dfa57600080fd5b612c1882614b36565b600060208284031215614e1557600080fd5b5051919050565b6bffffffffffffffffffffffff818116838216019080821115613d4057613d40614af4565b80820180821115612c1b57612c1b614af4565b62ffffff81168114612aa757600080fd5b8135614e70816148fb565b63ffffffff811690508154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000082161783556020840135614eb081614e54565b66ffffff000000008160201b16837fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000008416171784555050505050565b604081018235614efb816148fb565b63ffffffff1682526020830135614f1181614e54565b62ffffff811660208401525092915050565b6000604082016040835280865180835260608501915060608160051b8601019250602080890160005b83811015614f98577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552614f8686835161466f565b95509382019390820190600101614f4c565b505085840381870152505050614faf818587614d8b565b9695505050505050565b8181036000831280158383131683831282161715613d4057613d40614af4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361503957615039614af4565b5060010190565b805169ffffffffffffffffffff81168114614ab657600080fd5b600080600080600060a0868803121561507257600080fd5b61507b86615040565b945060208601519350604086015192506060860151915061509e60808701615040565b90509295509295909350565b60ff8181168382160190811115612c1b57612c1b614af4565b8082028115828204841417612c1b57612c1b614af4565b600080604083850312156150ed57600080fd5b505080516020909101519092909150565b6000815461510b81614bcf565b80855260206001838116801561512857600181146151605761518e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955061518e565b866000528260002060005b858110156151865781548a820186015290830190840161516b565b890184019650505b505050505092915050565b602081526000612c1860208301846150fe565b600082601f8301126151bd57600080fd5b815160206151cd6145cd83614988565b82815260059290921b840181019181810190868411156151ec57600080fd5b8286015b8481101561520757805183529183019183016151f0565b509695505050505050565b60006020828403121561522457600080fd5b815167ffffffffffffffff8082111561523c57600080fd5b90830190610100828603121561525157600080fd5b6152596144ef565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015261529160a08401614aab565b60a082015260c0830151828111156152a857600080fd5b6152b4878286016151ac565b60c08301525060e0830151828111156152cc57600080fd5b6152d887828601614b46565b60e08301525095945050505050565b600081518084526020808501945080840160005b83811015615317578151875295820195908201906001016152fb565b509495945050505050565b60408152825160408201526020830151606082015260408301516080820152606083015160a0820152608083015160c082015273ffffffffffffffffffffffffffffffffffffffff60a08401511660e0820152600060c08401516101008081850152506153936101408401826152e7565b905060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0848303016101208501526153cf828261466f565b91505082810360208401526153e481856150fe565b95945050505050565b602081526000612c18602083018461466f565b828152604060208201526000612ebd604083018461466f565b6000806040838503121561542c57600080fd5b61543583614b36565b9150602083015190509250929050565b600181815b8085111561549e57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561548457615484614af4565b8085161561549157918102915b93841c939080029061544a565b509250929050565b6000826154b557506001612c1b565b816154c257506000612c1b565b81600181146154d857600281146154e2576154fe565b6001915050612c1b565b60ff8411156154f3576154f3614af4565b50506001821b612c1b565b5060208310610133831016604e8410600b8410161715615521575081810a612c1b565b61552b8383615445565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561555d5761555d614af4565b029392505050565b6000612c1883836154a6565b6000826155a7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", } var AutomationRegistryLogicBABI = AutomationRegistryLogicBMetaData.ABI diff --git a/core/gethwrappers/generated/automation_registry_logic_c_wrapper_2_3/automation_registry_logic_c_wrapper_2_3.go b/core/gethwrappers/generated/automation_registry_logic_c_wrapper_2_3/automation_registry_logic_c_wrapper_2_3.go index e32d6890dd..d5e6d9d64f 100644 --- a/core/gethwrappers/generated/automation_registry_logic_c_wrapper_2_3/automation_registry_logic_c_wrapper_2_3.go +++ b/core/gethwrappers/generated/automation_registry_logic_c_wrapper_2_3/automation_registry_logic_c_wrapper_2_3.go @@ -151,7 +151,7 @@ type IAutomationV21PlusCommonUpkeepInfoLegacy struct { var AutomationRegistryLogicCMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkUSDFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nativeUSDFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fastGasFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"automationForwarderLogic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowedReadOnlyAddress\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_3.PayoutMode\",\"name\":\"payoutMode\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"wrappedNativeTokenAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractIERC20Metadata\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint96\",\"name\":\"gasChargeInBillingToken\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"premiumInBillingToken\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"gasReimbursementInJuels\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"premiumInJuels\",\"type\":\"uint96\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"linkUSD\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeUSD\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"billingUSD\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.PaymentReceipt\",\"name\":\"receipt\",\"type\":\"tuple\"}],\"name\":\"UpkeepCharged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disableOffchainPayments\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getAvailableERC20ForPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getBillingConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getBillingOverrides\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getBillingOverridesEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getBillingToken\",\"outputs\":[{\"internalType\":\"contractIERC20Metadata\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20Metadata\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getBillingTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBillingTokens\",\"outputs\":[{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFallbackNativePrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"contractIAutomationForwarder\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getHotVars\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reentrancyGuard\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.HotVars\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkUSDFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enumAutomationRegistryBase2_3.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNativeUSDFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNumUpkeeps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPayoutMode\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_3.PayoutMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_3.MigrationPermission\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getReserveAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structIAutomationV21PlusCommon.StateLegacy\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structIAutomationV21PlusCommon.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistryBase2_3.Storage\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataFixedBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataPerSignerBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmittersWithPayees\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"transmitterAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"payeeAddress\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.TransmitterPayeeInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_3.Trigger\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structIAutomationV21PlusCommon.UpkeepInfoLegacy\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWrappedNativeTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_3.MigrationPermission\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settleNOPsOffchain\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20Metadata\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"supportsBillingToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101606040523480156200001257600080fd5b5060405162005c8738038062005c87833981016040819052620000359162000309565b87878787878787873380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000241565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff191660018381811115620001185762000118620003b6565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000179573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200019f9190620003cc565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002099190620003cc565b60ff16146200022b576040516301f86e1760e41b815260040160405180910390fd5b50505050505050505050505050505050620003f8565b336001600160a01b038216036200029b5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200030457600080fd5b919050565b600080600080600080600080610100898b0312156200032757600080fd5b6200033289620002ec565b97506200034260208a01620002ec565b96506200035260408a01620002ec565b95506200036260608a01620002ec565b94506200037260808a01620002ec565b93506200038260a08a01620002ec565b925060c0890151600281106200039757600080fd5b9150620003a760e08a01620002ec565b90509295985092959890939650565b634e487b7160e01b600052602160045260246000fd5b600060208284031215620003df57600080fd5b815160ff81168114620003f157600080fd5b9392505050565b60805160a05160c05160e051610100516101205161014051615803620004846000396000610b7001526000610ad2015260006107be0152600081816109a001526135b60152600081816109540152613e3201526000818161051d0152613690015260008181610c1801528181611df00152818161256b015281816125c80152613af601526158036000f3fe608060405234801561001057600080fd5b50600436106103d05760003560e01c80638ed02bab116101ff578063c3f909d41161011a578063eb5dcd6c116100ad578063f5a418461161007c578063f5a4184614610eb4578063f777ff0614610f35578063faa3e99614610f3c578063ffd242bd14610f8257600080fd5b8063eb5dcd6c14610de5578063ec4de4ba14610df8578063ed56b3e114610e2e578063f2fde38b14610ea157600080fd5b8063d09dc339116100e9578063d09dc33914610c3c578063d763264814610c44578063d85aa07c14610c57578063e80a3d4414610c5f57600080fd5b8063c3f909d414610bd6578063c5b964e014610beb578063c7c3a19a14610bf6578063ca30e60314610c1657600080fd5b8063aab9edd611610192578063b3596c2311610161578063b3596c23146107e2578063b6511a2a14610ba7578063b657bc9c14610bae578063ba87666814610bc157600080fd5b8063aab9edd614610b57578063abc76ae014610b66578063ac4dc59a14610b6e578063b121e14714610b9457600080fd5b8063a08714c0116101ce578063a08714c014610ad0578063a538b2eb14610af6578063a710b22114610b3c578063a87f45fe14610b4f57600080fd5b80638ed02bab14610a5c5780639089daa414610a7a57806393f6ebcf14610a8f5780639e0a99ed14610ac857600080fd5b806343cc055c116102ef5780636209e1e91161028257806379ba50971161025157806379ba5097146109ea57806379ea9943146109f25780638456cb5914610a365780638da5cb5b14610a3e57600080fd5b80636209e1e91461098b5780636709d0e51461099e578063671d36ed146109c45780636eec02a2146109d757600080fd5b80635425d8ac116102be5780635425d8ac146107bc57806357359584146107e2578063614486af146109525780636181d82d1461097857600080fd5b806343cc055c1461074957806344cb70b8146107705780634ca16c52146107935780635147cd591461079c57600080fd5b8063207b6516116103675780633b9cce59116103365780633b9cce59146106c05780633f4ba83a146106d3578063421d183b146106db57806343b46e5f1461074157600080fd5b8063207b651614610508578063226cf83c1461051b578063232c1cc5146105625780633408f73a1461056957600080fd5b8063187256e8116103a3578063187256e81461043b57806319d97a941461044e5780631e0104391461046e5780631efcf646146104d057600080fd5b8063050ee65d146103d557806306e3b632146103ed5780630b7d33e61461040d5780631865c57d14610422575b600080fd5b6201de845b6040519081526020015b60405180910390f35b6104006103fb36600461447a565b610f8a565b6040516103e491906144d7565b61042061041b366004614533565b6110a7565b005b61042a611108565b6040516103e495949392919061472b565b61042061044936600461486c565b611508565b61046161045c3660046148a9565b611579565b6040516103e49190614926565b6104b361047c3660046148a9565b60009081526004602052604090206001015470010000000000000000000000000000000090046bffffffffffffffffffffffff1690565b6040516bffffffffffffffffffffffff90911681526020016103e4565b6104f86104de3660046148a9565b600090815260046020526040902054610100900460ff1690565b60405190151581526020016103e4565b6104616105163660046148a9565b61161b565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103e4565b60186103da565b6106b36040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915250604080516101608101825260165473ffffffffffffffffffffffffffffffffffffffff808216835263ffffffff740100000000000000000000000000000000000000008084048216602086015278010000000000000000000000000000000000000000000000008085048316968601969096527c010000000000000000000000000000000000000000000000000000000093849004821660608601526017548084166080870152818104831660a0870152868104831660c087015293909304811660e085015260185491821661010085015291810482166101208401529290920490911661014082015290565b6040516103e49190614939565b6104206106ce366004614a63565b611638565b61042061188e565b6106ee6106e9366004614ad8565b6118f4565b60408051951515865260ff90941660208601526bffffffffffffffffffffffff9283169385019390935216606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a0016103e4565b610420611a13565b6014547801000000000000000000000000000000000000000000000000900460ff166104f8565b6104f861077e3660046148a9565b60009081526008602052604090205460ff1690565b62017f986103da565b6107af6107aa3660046148a9565b611eaa565b6040516103e49190614b34565b7f000000000000000000000000000000000000000000000000000000000000000061053d565b6108d46107f0366004614ad8565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525073ffffffffffffffffffffffffffffffffffffffff908116600090815260226020908152604091829020825160c081018452815463ffffffff81168252640100000000810462ffffff16938201939093526701000000000000008304909416928401929092527b01000000000000000000000000000000000000000000000000000000900460ff16606083015260018101546080830152600201546bffffffffffffffffffffffff1660a082015290565b6040516103e49190600060c08201905063ffffffff835116825262ffffff602084015116602083015273ffffffffffffffffffffffffffffffffffffffff604084015116604083015260ff6060840151166060830152608083015160808301526bffffffffffffffffffffffff60a08401511660a083015292915050565b7f000000000000000000000000000000000000000000000000000000000000000061053d565b6104b3610986366004614b47565b611eb5565b610461610999366004614ad8565b612010565b7f000000000000000000000000000000000000000000000000000000000000000061053d565b6104206109d2366004614ba7565b612043565b6103da6109e5366004614ad8565b6120c3565b61042061216d565b61053d610a003660046148a9565b6000908152600460205260409020546a0100000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b61042061226f565b60005473ffffffffffffffffffffffffffffffffffffffff1661053d565b60155473ffffffffffffffffffffffffffffffffffffffff1661053d565b610a826122e8565b6040516103e49190614be3565b61053d610a9d3660046148a9565b60009081526004602052604090206002015473ffffffffffffffffffffffffffffffffffffffff1690565b6103a46103da565b7f000000000000000000000000000000000000000000000000000000000000000061053d565b6104f8610b04366004614ad8565b73ffffffffffffffffffffffffffffffffffffffff908116600090815260226020526040902054670100000000000000900416151590565b610420610b4a366004614c4c565b6123fa565b610420612728565b604051600481526020016103e4565b6115e06103da565b7f000000000000000000000000000000000000000000000000000000000000000061053d565b610420610ba2366004614ad8565b61275a565b60326103da565b6104b3610bbc3660046148a9565b612852565b610bc9612979565b6040516103e49190614c7a565b610bde6129e8565b6040516103e49190614cd4565b60255460ff166107af565b610c09610c043660046148a9565b612bd0565b6040516103e49190614e5b565b7f000000000000000000000000000000000000000000000000000000000000000061053d565b6103da612fe0565b6104b3610c523660046148a9565b612fef565b601b546103da565b610dd86040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101919091525060408051610120810182526014546bffffffffffffffffffffffff8116825263ffffffff6c01000000000000000000000000820416602083015262ffffff7001000000000000000000000000000000008204169282019290925261ffff730100000000000000000000000000000000000000830416606082015260ff750100000000000000000000000000000000000000000083048116608083015276010000000000000000000000000000000000000000000083048116151560a08301527701000000000000000000000000000000000000000000000083048116151560c08301527801000000000000000000000000000000000000000000000000909204909116151560e082015260155473ffffffffffffffffffffffffffffffffffffffff1661010082015290565b6040516103e49190614f92565b610420610df3366004614c4c565b612ffa565b6103da610e06366004614ad8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526021602052604090205490565b610e88610e3c366004614ad8565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602090815260409182902082518084019093525460ff8082161515808552610100909204169290910182905291565b60408051921515835260ff9091166020830152016103e4565b610420610eaf366004614ad8565b613159565b610f0f610ec23660046148a9565b60408051808201909152600080825260208201525060009081526023602090815260409182902082518084019093525463ffffffff81168352640100000000900462ffffff169082015290565b60408051825163ffffffff16815260209283015162ffffff1692810192909252016103e4565b60406103da565b610f75610f4a366004614ad8565b73ffffffffffffffffffffffffffffffffffffffff166000908152601c602052604090205460ff1690565b6040516103e49190615062565b6103da61316d565b60606000610f986002613175565b9050808410610fd3576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610fdf84866150a5565b905081811180610fed575083155b610ff75780610ff9565b815b9050600061100786836150b8565b67ffffffffffffffff81111561101f5761101f6150cb565b604051908082528060200260200182016040528015611048578160200160208202803683370190505b50905060005b815181101561109b5761106c61106488836150a5565b60029061317f565b82828151811061107e5761107e6150fa565b60209081029190910101528061109381615129565b91505061104e565b50925050505b92915050565b6110af61318b565b6000838152601f602052604090206110c8828483615203565b50827f2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae776983836040516110fb92919061531e565b60405180910390a2505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152604080516101e08101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a08201526101c081019190915260408051610140810182526016547c0100000000000000000000000000000000000000000000000000000000900463ffffffff1681526000602082018190529181018290526014546bffffffffffffffffffffffff16606080830191909152918291608081016112416002613175565b81526017547401000000000000000000000000000000000000000080820463ffffffff908116602080860191909152780100000000000000000000000000000000000000000000000080850483166040808801919091526013546060808901919091526014546c01000000000000000000000000810486166080808b0191909152760100000000000000000000000000000000000000000000820460ff16151560a09a8b015283516101e0810185526000808252968101879052601654898104891695820195909552700100000000000000000000000000000000830462ffffff169381019390935273010000000000000000000000000000000000000090910461ffff169082015296870192909252808204831660c08701527c0100000000000000000000000000000000000000000000000000000000909404821660e086015260185492830482166101008601529290910416610120830152601954610140830152601a5461016083015273ffffffffffffffffffffffffffffffffffffffff166101808201529095506101a081016113dc60096131de565b815260175473ffffffffffffffffffffffffffffffffffffffff16602091820152601454600d80546040805182860281018601909152818152949850899489949293600e93750100000000000000000000000000000000000000000090910460ff1692859183018282801561148757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161145c575b50505050509250818054806020026020016040519081016040528092919081815260200182805480156114f057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116114c5575b50505050509150945094509450945094509091929394565b6115106131eb565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601c6020526040902080548291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600381111561157057611570614af5565b02179055505050565b6000818152601f6020526040902080546060919061159690615161565b80601f01602080910402602001604051908101604052809291908181526020018280546115c290615161565b801561160f5780601f106115e45761010080835404028352916020019161160f565b820191906000526020600020905b8154815290600101906020018083116115f257829003601f168201915b50505050509050919050565b6000818152601d6020526040902080546060919061159690615161565b6116406131eb565b600e54811461167b576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b600e5481101561184d576000600e828154811061169d5761169d6150fa565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff9081168084526011909252604083205491935016908585858181106116e7576116e76150fa565b90506020020160208101906116fc9190614ad8565b905073ffffffffffffffffffffffffffffffffffffffff8116158061178f575073ffffffffffffffffffffffffffffffffffffffff82161580159061176d57508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561178f575073ffffffffffffffffffffffffffffffffffffffff81811614155b156117c6576040517fb387a23800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff818116146118375773ffffffffffffffffffffffffffffffffffffffff838116600090815260116020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169183169190911790555b505050808061184590615129565b91505061167e565b507fa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725600e83836040516118829392919061536b565b60405180910390a15050565b6118966131eb565b601480547fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015282918291829182919082906119ba5760608201516014546000916119a6916bffffffffffffffffffffffff1661541d565b600e549091506119b69082615471565b9150505b8151602083015160408401516119d190849061549c565b6060949094015173ffffffffffffffffffffffffffffffffffffffff9a8b16600090815260116020526040902054929b919a9499509750921694509092505050565b611a1b61326c565b600060255460ff166001811115611a3457611a34614af5565b03611a6b576040517fe0262d7400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601454600e546bffffffffffffffffffffffff909116906000611a8e600f613175565b90506000611a9c82846150a5565b905060008167ffffffffffffffff811115611ab957611ab96150cb565b604051908082528060200260200182016040528015611ae2578160200160208202803683370190505b50905060008267ffffffffffffffff811115611b0057611b006150cb565b604051908082528060200260200182016040528015611b29578160200160208202803683370190505b50905060005b85811015611c5b576000600e8281548110611b4c57611b4c6150fa565b600091825260208220015473ffffffffffffffffffffffffffffffffffffffff169150611b7a828a8a6132bd565b9050806bffffffffffffffffffffffff16858481518110611b9d57611b9d6150fa565b60209081029190910181019190915273ffffffffffffffffffffffffffffffffffffffff808416600090815260119092526040909120548551911690859085908110611beb57611beb6150fa565b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920181019190915292166000908152600b909252506040902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff16905580611c5381615129565b915050611b2f565b5060005b84811015611dd8576000611c74600f8361317f565b73ffffffffffffffffffffffffffffffffffffffff8082166000818152600b602090815260408083208151608081018352905460ff80821615158352610100820416828501526bffffffffffffffffffffffff6201000082048116838501526e0100000000000000000000000000009091041660608201529383526011909152902054929350911684611d078a866150a5565b81518110611d1757611d176150fa565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015260408101516bffffffffffffffffffffffff1685611d5a8a866150a5565b81518110611d6a57611d6a6150fa565b60209081029190910181019190915273ffffffffffffffffffffffffffffffffffffffff9092166000908152600b909252506040902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff16905580611dd081615129565b915050611c5f565b5073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166000908152602160205260408120819055611e2b600f613175565b90505b8015611e6857611e55611e4d611e456001846150b8565b600f9061317f565b600f906134c5565b5080611e60816154c1565b915050611e2e565b507f5af23b715253628d12b660b27a4f3fc626562ea8a55040aa99ab3dc178989fad8183604051611e9a9291906154f6565b60405180910390a1505050505050565b60006110a1826134e7565b60408051610120810182526014546bffffffffffffffffffffffff8116825263ffffffff6c01000000000000000000000000820416602083015262ffffff7001000000000000000000000000000000008204169282019290925261ffff730100000000000000000000000000000000000000830416606082015260ff750100000000000000000000000000000000000000000083048116608083015276010000000000000000000000000000000000000000000083048116151560a08301527701000000000000000000000000000000000000000000000083048116151560c08301527801000000000000000000000000000000000000000000000000909204909116151560e082015260155473ffffffffffffffffffffffffffffffffffffffff16610100820152600090818080611fed84613592565b92509250925061200389858a8a8787878d613784565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602080526040902080546060919061159690615161565b61204b61318b565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602080526040902061207a828483615203565b508273ffffffffffffffffffffffffffffffffffffffff167f7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d283836040516110fb92919061531e565b73ffffffffffffffffffffffffffffffffffffffff81166000818152602160205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152919290916370a0823190602401602060405180830381865afa15801561213f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121639190615524565b6110a191906150b8565b60015473ffffffffffffffffffffffffffffffffffffffff1633146121f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6122776131eb565b601480547fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff167601000000000000000000000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020016118ea565b600e5460609060008167ffffffffffffffff811115612309576123096150cb565b60405190808252806020026020018201604052801561234e57816020015b60408051808201909152600080825260208201528152602001906001900390816123275790505b50905060005b828110156123f3576000600e8281548110612371576123716150fa565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff9081168084526011835260409384902054845180860190955281855290911691830182905285519093509091908590859081106123d3576123d36150fa565b6020026020010181905250505080806123eb90615129565b915050612354565b5092915050565b73ffffffffffffffffffffffffffffffffffffffff8116612447576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160255460ff16600181111561246057612460614af5565b03612497576040517f4a3578fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152601160205260409020541633146124f7576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601454600e5460009161251a9185916bffffffffffffffffffffffff16906132bd565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600b6020908152604080832080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff1690557f000000000000000000000000000000000000000000000000000000000000000090931682526021905220549091506125b1906bffffffffffffffffffffffff8316906150b8565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166000818152602160205260408082209490945592517fa9059cbb00000000000000000000000000000000000000000000000000000000815291851660048301526bffffffffffffffffffffffff841660248301529063a9059cbb906044016020604051808303816000875af1158015612666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268a919061553d565b9050806126c3576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405133815273ffffffffffffffffffffffffffffffffffffffff808516916bffffffffffffffffffffffff8516918716907f9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f406989060200160405180910390a450505050565b6127306131eb565b602580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601260205260409020541633146127ba576040517f6752e7aa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81811660008181526011602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556012909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b6000818152600460209081526040808320815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e08201526002909101549091169181019190915261297283612962816134e7565b8360400151846101000151611eb5565b9392505050565b606060248054806020026020016040519081016040528092919081815260200182805480156129de57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116129b3575b5050505050905090565b604080516102008101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a082018390526101c08201526101e0810191909152604080516102008101825260165463ffffffff74010000000000000000000000000000000000000000808304821684527801000000000000000000000000000000000000000000000000808404831660208601526017547c0100000000000000000000000000000000000000000000000000000000810484169686019690965273ffffffffffffffffffffffffffffffffffffffff938416606086015260145460ff828204161515608087015262ffffff70010000000000000000000000000000000082041660a0870152601854928304841660c087015290820490921660e085015293821661010084015261ffff7301000000000000000000000000000000000000009091041661012083015291909116610140820152601954610160820152601a54610180820152601b546101a08201526101c08101612baa60096131de565b815260155473ffffffffffffffffffffffffffffffffffffffff16602090910152919050565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526000828152600460209081526040808320815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a010000000000000000000090910481166080830181905260018401546fffffffffffffffffffffffffffffffff811660a08501526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08501527c0100000000000000000000000000000000000000000000000000000000900490941660e08301526002909201549091169281019290925290919015612da557816080015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da0919061555f565b612da8565b60005b90506040518061014001604052808273ffffffffffffffffffffffffffffffffffffffff168152602001836040015163ffffffff168152602001600760008781526020019081526020016000208054612e0090615161565b80601f0160208091040260200160405190810160405280929190818152602001828054612e2c90615161565b8015612e795780601f10612e4e57610100808354040283529160200191612e79565b820191906000526020600020905b815481529060010190602001808311612e5c57829003601f168201915b505050505081526020018360c001516bffffffffffffffffffffffff1681526020016005600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001836060015163ffffffff1667ffffffffffffffff1681526020018360e0015163ffffffff1681526020018360a001516bffffffffffffffffffffffff168152602001836000015115158152602001601e60008781526020019081526020016000208054612f5690615161565b80601f0160208091040260200160405190810160405280929190818152602001828054612f8290615161565b8015612fcf5780601f10612fa457610100808354040283529160200191612fcf565b820191906000526020600020905b815481529060010190602001808311612fb257829003601f168201915b505050505081525092505050919050565b6000612fea613af4565b905090565b60006110a182612852565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526011602052604090205416331461305a576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff8216036130a9576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152601260205260409020548116908216146131555773ffffffffffffffffffffffffffffffffffffffff82811660008181526012602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055513392917f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836791a45b5050565b6131616131eb565b61316a81613bbe565b50565b6000612fea60025b60006110a1825490565b60006129728383613cb3565b60175473ffffffffffffffffffffffffffffffffffffffff1633146131dc576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6060600061297283613cdd565b60005473ffffffffffffffffffffffffffffffffffffffff1633146131dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016121ea565b60185473ffffffffffffffffffffffffffffffffffffffff1633146131dc576040517fb6dfb7a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906134b9576000816060015185613355919061541d565b905060006133638583615471565b90508083604001818151613377919061549c565b6bffffffffffffffffffffffff16905250613392858261557c565b836060018181516133a3919061549c565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b60006129728373ffffffffffffffffffffffffffffffffffffffff8416613d38565b6000818160045b600f811015613574577fff00000000000000000000000000000000000000000000000000000000000000821683826020811061352c5761352c6150fa565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461356257506000949350505050565b8061356c81615129565b9150506134ee565b5081600f1a600181111561358a5761358a614af5565b949350505050565b600080600080846040015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561361f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061364391906155c3565b509450909250505060008113158061365a57508142105b8061367b575082801561367b575061367282426150b8565b8463ffffffff16105b1561368a57601954965061368e565b8096505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156136f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371d91906155c3565b509450909250505060008113158061373457508142105b806137555750828015613755575061374c82426150b8565b8463ffffffff16105b1561376457601a549550613768565b8095505b86866137738a613e2b565b965096509650505050509193909250565b600080808089600181111561379b5761379b614af5565b036137aa575062017f986137ff565b60018960018111156137be576137be614af5565b036137cd57506201de846137ff565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008a6080015160016138129190615613565b6138209060ff16604061562c565b60185461384e906103a49074010000000000000000000000000000000000000000900463ffffffff166150a5565b61385891906150a5565b601554604080517fde9ee35e0000000000000000000000000000000000000000000000000000000081528151939450600093849373ffffffffffffffffffffffffffffffffffffffff169263de9ee35e92600480820193918290030181865afa1580156138c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ed9190615643565b909250905081836138ff8360186150a5565b613909919061562c565b60808f0151613919906001615613565b6139289060ff166115e061562c565b61393291906150a5565b61393c91906150a5565b61394690856150a5565b6101008e01516040517f125441400000000000000000000000000000000000000000000000000000000081526004810186905291955073ffffffffffffffffffffffffffffffffffffffff1690631254414090602401602060405180830381865afa1580156139b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139dd9190615524565b8d6060015161ffff166139f0919061562c565b94505050506000613a018b86613f15565b60008d815260046020526040902054909150610100900460ff1615613a665760008c81526023602090815260409182902082518084018452905463ffffffff811680835264010000000090910462ffffff908116928401928352928501525116908201525b6000613ad08c6040518061012001604052808d63ffffffff1681526020018681526020018781526020018c81526020018b81526020018a81526020018973ffffffffffffffffffffffffffffffffffffffff16815260200185815260200160001515815250614091565b60208101518151919250613ae39161549c565b9d9c50505050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166000818152602160205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152919290916370a0823190602401602060405180830381865afa158015613b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb49190615524565b612fea9190615667565b3373ffffffffffffffffffffffffffffffffffffffff821603613c3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016121ea565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613cca57613cca6150fa565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561160f57602002820191906000526020600020905b815481526020019060010190808311613d195750505050509050919050565b60008181526001830160205260408120548015613e21576000613d5c6001836150b8565b8554909150600090613d70906001906150b8565b9050818114613dd5576000866000018281548110613d9057613d906150fa565b9060005260206000200154905080876000018481548110613db357613db36150fa565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613de657613de6615687565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506110a1565b60009150506110a1565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613e9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ebf91906155c3565b50935050925050600082131580613ed557508042105b80613f0557506000846040015162ffffff16118015613f055750613ef981426150b8565b846040015162ffffff16105b156123f3575050601b5492915050565b60408051608081018252600080825260208083018281528385018381526060850184905273ffffffffffffffffffffffffffffffffffffffff878116855260229093528584208054640100000000810462ffffff1690925263ffffffff82169092527b01000000000000000000000000000000000000000000000000000000810460ff16855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495919484936701000000000000009092049091169163feaf968c9160048083019260a09291908290030181865afa158015614002573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061402691906155c3565b5093505092505060008213158061403c57508042105b8061406c57506000866040015162ffffff1611801561406c575061406081426150b8565b866040015162ffffff16105b156140805760018301546060850152614088565b606084018290525b50505092915050565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915260008260e001516000015160ff1690506000846060015161ffff1684606001516140fc919061562c565b9050836101000151801561410f5750803a105b1561411757503a5b60006012831161412857600161413e565b6141336012846150b8565b61413e90600a6157d6565b9050600060128410614151576001614167565b61415c8460126150b8565b61416790600a6157d6565b905060008660a0015187604001518860200151896000015161418991906150a5565b614193908761562c565b61419d91906150a5565b6141a7919061562c565b9050614203828860e00151606001516141c0919061562c565b6001848a60e00151606001516141d6919061562c565b6141e091906150b8565b6141ea868561562c565b6141f491906150a5565b6141fe91906157e2565b6143d8565b6bffffffffffffffffffffffff1686526080870151614226906141fe90836157e2565b6bffffffffffffffffffffffff1660408088019190915260e0880151015160009061425f9062ffffff16683635c9adc5dea0000061562c565b9050600081633b9aca008a60a001518b60e001516020015163ffffffff168c604001518d600001518b614292919061562c565b61429c91906150a5565b6142a6919061562c565b6142b0919061562c565b6142ba91906157e2565b6142c491906150a5565b9050614307848a60e00151606001516142dd919061562c565b6001868c60e00151606001516142f3919061562c565b6142fd91906150b8565b6141ea888561562c565b6bffffffffffffffffffffffff166020890152608089015161432d906141fe90836157e2565b6bffffffffffffffffffffffff16606089015260c089015173ffffffffffffffffffffffffffffffffffffffff166080808a0191909152890151614370906143d8565b6bffffffffffffffffffffffff1660a0808a0191909152890151614393906143d8565b6bffffffffffffffffffffffff1660c089015260e0890151606001516143b8906143d8565b6bffffffffffffffffffffffff1660e08901525050505050505092915050565b60006bffffffffffffffffffffffff821115614476576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016121ea565b5090565b6000806040838503121561448d57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b838110156144cc578151875295820195908201906001016144b0565b509495945050505050565b602081526000612972602083018461449c565b60008083601f8401126144fc57600080fd5b50813567ffffffffffffffff81111561451457600080fd5b60208301915083602082850101111561452c57600080fd5b9250929050565b60008060006040848603121561454857600080fd5b83359250602084013567ffffffffffffffff81111561456657600080fd5b614572868287016144ea565b9497909650939450505050565b600081518084526020808501945080840160005b838110156144cc57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614593565b805163ffffffff16825260006101e060208301516145eb602086018263ffffffff169052565b506040830151614603604086018263ffffffff169052565b50606083015161461a606086018262ffffff169052565b506080830151614630608086018261ffff169052565b5060a083015161465060a08601826bffffffffffffffffffffffff169052565b5060c083015161466860c086018263ffffffff169052565b5060e083015161468060e086018263ffffffff169052565b506101008381015163ffffffff908116918601919091526101208085015190911690850152610140808401519085015261016080840151908501526101808084015173ffffffffffffffffffffffffffffffffffffffff16908501526101a0808401518186018390526146f58387018261457f565b925050506101c0808401516147218287018273ffffffffffffffffffffffffffffffffffffffff169052565b5090949350505050565b855163ffffffff16815260006101c0602088015161475960208501826bffffffffffffffffffffffff169052565b5060408801516040840152606088015161478360608501826bffffffffffffffffffffffff169052565b506080880151608084015260a08801516147a560a085018263ffffffff169052565b5060c08801516147bd60c085018263ffffffff169052565b5060e088015160e0840152610100808901516147e08286018263ffffffff169052565b5050610120888101511515908401526101408301819052614803818401886145c5565b9050828103610160840152614818818761457f565b905082810361018084015261482d818661457f565b9150506148406101a083018460ff169052565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461316a57600080fd5b6000806040838503121561487f57600080fd5b823561488a8161484a565b915060208301356004811061489e57600080fd5b809150509250929050565b6000602082840312156148bb57600080fd5b5035919050565b6000815180845260005b818110156148e8576020818501810151868301820152016148cc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061297260208301846148c2565b815173ffffffffffffffffffffffffffffffffffffffff1681526101608101602083015161496f602084018263ffffffff169052565b506040830151614987604084018263ffffffff169052565b50606083015161499f606084018263ffffffff169052565b5060808301516149c7608084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a08301516149df60a084018263ffffffff169052565b5060c08301516149f760c084018263ffffffff169052565b5060e0830151614a0f60e084018263ffffffff169052565b506101008381015173ffffffffffffffffffffffffffffffffffffffff81168483015250506101208381015163ffffffff81168483015250506101408381015163ffffffff8116848301525b505092915050565b60008060208385031215614a7657600080fd5b823567ffffffffffffffff80821115614a8e57600080fd5b818501915085601f830112614aa257600080fd5b813581811115614ab157600080fd5b8660208260051b8501011115614ac657600080fd5b60209290920196919550909350505050565b600060208284031215614aea57600080fd5b81356129728161484a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6002811061316a5761316a614af5565b60208101614b4183614b24565b91905290565b60008060008060808587031215614b5d57600080fd5b84359350602085013560028110614b7357600080fd5b9250604085013563ffffffff81168114614b8c57600080fd5b91506060850135614b9c8161484a565b939692955090935050565b600080600060408486031215614bbc57600080fd5b8335614bc78161484a565b9250602084013567ffffffffffffffff81111561456657600080fd5b602080825282518282018190526000919060409081850190868401855b82811015614c3f578151805173ffffffffffffffffffffffffffffffffffffffff90811686529087015116868501529284019290850190600101614c00565b5091979650505050505050565b60008060408385031215614c5f57600080fd5b8235614c6a8161484a565b9150602083013561489e8161484a565b6020808252825182820181905260009190848201906040850190845b81811015614cc857835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614c96565b50909695505050505050565b60208152614ceb60208201835163ffffffff169052565b60006020830151614d04604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015180151560a08401525060a083015162ffffff811660c08401525060c083015163ffffffff811660e08401525060e0830151610100614d838185018363ffffffff169052565b8401519050610120614dac8482018373ffffffffffffffffffffffffffffffffffffffff169052565b8401519050610140614dc38482018361ffff169052565b8401519050610160614dec8482018373ffffffffffffffffffffffffffffffffffffffff169052565b840151610180848101919091528401516101a0808501919091528401516101c0808501919091528401516102006101e080860182905291925090614e3461022086018461457f565b9086015173ffffffffffffffffffffffffffffffffffffffff811683870152909250614721565b60208152614e8260208201835173ffffffffffffffffffffffffffffffffffffffff169052565b60006020830151614e9b604084018263ffffffff169052565b506040830151610140806060850152614eb86101608501836148c2565b91506060850151614ed960808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e0850151610100614f45818701836bffffffffffffffffffffffff169052565b8601519050610120614f5a8682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183870152905061484083826148c2565b6000610120820190506bffffffffffffffffffffffff835116825263ffffffff60208401511660208301526040830151614fd3604084018262ffffff169052565b506060830151614fe9606084018261ffff169052565b506080830151614ffe608084018260ff169052565b5060a083015161501260a084018215159052565b5060c083015161502660c084018215159052565b5060e083015161503a60e084018215159052565b506101008381015173ffffffffffffffffffffffffffffffffffffffff811684830152614a5b565b6020810160048310614b4157614b41614af5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156110a1576110a1615076565b818103818111156110a1576110a1615076565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361515a5761515a615076565b5060010190565b600181811c9082168061517557607f821691505b6020821081036151ae577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156151fe57600081815260208120601f850160051c810160208610156151db5750805b601f850160051c820191505b818110156151fa578281556001016151e7565b5050505b505050565b67ffffffffffffffff83111561521b5761521b6150cb565b61522f836152298354615161565b836151b4565b6000601f841160018114615281576000851561524b5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355615317565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156152d057868501358255602094850194600190920191016152b0565b508682101561530b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000604082016040835280865480835260608501915087600052602092508260002060005b828110156153c257815473ffffffffffffffffffffffffffffffffffffffff1684529284019260019182019101615390565b505050838103828501528481528590820160005b868110156154115782356153e98161484a565b73ffffffffffffffffffffffffffffffffffffffff16825291830191908301906001016153d6565b50979650505050505050565b6bffffffffffffffffffffffff8281168282160390808211156123f3576123f3615076565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006bffffffffffffffffffffffff8084168061549057615490615442565b92169190910492915050565b6bffffffffffffffffffffffff8181168382160190808211156123f3576123f3615076565b6000816154d0576154d0615076565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b604081526000615509604083018561457f565b828103602084015261551b818561449c565b95945050505050565b60006020828403121561553657600080fd5b5051919050565b60006020828403121561554f57600080fd5b8151801515811461297257600080fd5b60006020828403121561557157600080fd5b81516129728161484a565b6bffffffffffffffffffffffff818116838216028082169190828114614a5b57614a5b615076565b805169ffffffffffffffffffff811681146155be57600080fd5b919050565b600080600080600060a086880312156155db57600080fd5b6155e4866155a4565b9450602086015193506040860151925060608601519150615607608087016155a4565b90509295509295909350565b60ff81811683821601908111156110a1576110a1615076565b80820281158282048414176110a1576110a1615076565b6000806040838503121561565657600080fd5b505080516020909101519092909150565b81810360008312801583831316838312821617156123f3576123f3615076565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600181815b8085111561570f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156156f5576156f5615076565b8085161561570257918102915b93841c93908002906156bb565b509250929050565b600082615726575060016110a1565b81615733575060006110a1565b816001811461574957600281146157535761576f565b60019150506110a1565b60ff84111561576457615764615076565b50506001821b6110a1565b5060208310610133831016604e8410600b8410161715615792575081810a6110a1565b61579c83836156b6565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156157ce576157ce615076565b029392505050565b60006129728383615717565b6000826157f1576157f1615442565b50049056fea164736f6c6343000813000a", + Bin: "0x6101606040523480156200001257600080fd5b5060405162005c8738038062005c87833981016040819052620000359162000309565b87878787878787873380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000241565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff191660018381811115620001185762000118620003b6565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000179573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200019f9190620003cc565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002099190620003cc565b60ff16146200022b576040516301f86e1760e41b815260040160405180910390fd5b50505050505050505050505050505050620003f8565b336001600160a01b038216036200029b5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200030457600080fd5b919050565b600080600080600080600080610100898b0312156200032757600080fd5b6200033289620002ec565b97506200034260208a01620002ec565b96506200035260408a01620002ec565b95506200036260608a01620002ec565b94506200037260808a01620002ec565b93506200038260a08a01620002ec565b925060c0890151600281106200039757600080fd5b9150620003a760e08a01620002ec565b90509295985092959890939650565b634e487b7160e01b600052602160045260246000fd5b600060208284031215620003df57600080fd5b815160ff81168114620003f157600080fd5b9392505050565b60805160a05160c05160e051610100516101205161014051615803620004846000396000610b7001526000610ad2015260006107be0152600081816109a001526135b60152600081816109540152613e3201526000818161051d0152613690015260008181610c1801528181611df00152818161256b015281816125c80152613af601526158036000f3fe608060405234801561001057600080fd5b50600436106103d05760003560e01c80638ed02bab116101ff578063c3f909d41161011a578063eb5dcd6c116100ad578063f5a418461161007c578063f5a4184614610eb4578063f777ff0614610f35578063faa3e99614610f3c578063ffd242bd14610f8257600080fd5b8063eb5dcd6c14610de5578063ec4de4ba14610df8578063ed56b3e114610e2e578063f2fde38b14610ea157600080fd5b8063d09dc339116100e9578063d09dc33914610c3c578063d763264814610c44578063d85aa07c14610c57578063e80a3d4414610c5f57600080fd5b8063c3f909d414610bd6578063c5b964e014610beb578063c7c3a19a14610bf6578063ca30e60314610c1657600080fd5b8063aab9edd611610192578063b3596c2311610161578063b3596c23146107e2578063b6511a2a14610ba7578063b657bc9c14610bae578063ba87666814610bc157600080fd5b8063aab9edd614610b57578063abc76ae014610b66578063ac4dc59a14610b6e578063b121e14714610b9457600080fd5b8063a08714c0116101ce578063a08714c014610ad0578063a538b2eb14610af6578063a710b22114610b3c578063a87f45fe14610b4f57600080fd5b80638ed02bab14610a5c5780639089daa414610a7a57806393f6ebcf14610a8f5780639e0a99ed14610ac857600080fd5b806343cc055c116102ef5780636209e1e91161028257806379ba50971161025157806379ba5097146109ea57806379ea9943146109f25780638456cb5914610a365780638da5cb5b14610a3e57600080fd5b80636209e1e91461098b5780636709d0e51461099e578063671d36ed146109c45780636eec02a2146109d757600080fd5b80635425d8ac116102be5780635425d8ac146107bc57806357359584146107e2578063614486af146109525780636181d82d1461097857600080fd5b806343cc055c1461074957806344cb70b8146107705780634ca16c52146107935780635147cd591461079c57600080fd5b8063207b6516116103675780633b9cce59116103365780633b9cce59146106c05780633f4ba83a146106d3578063421d183b146106db57806343b46e5f1461074157600080fd5b8063207b651614610508578063226cf83c1461051b578063232c1cc5146105625780633408f73a1461056957600080fd5b8063187256e8116103a3578063187256e81461043b57806319d97a941461044e5780631e0104391461046e5780631efcf646146104d057600080fd5b8063050ee65d146103d557806306e3b632146103ed5780630b7d33e61461040d5780631865c57d14610422575b600080fd5b6201e26c5b6040519081526020015b60405180910390f35b6104006103fb36600461447a565b610f8a565b6040516103e491906144d7565b61042061041b366004614533565b6110a7565b005b61042a611108565b6040516103e495949392919061472b565b61042061044936600461486c565b611508565b61046161045c3660046148a9565b611579565b6040516103e49190614926565b6104b361047c3660046148a9565b60009081526004602052604090206001015470010000000000000000000000000000000090046bffffffffffffffffffffffff1690565b6040516bffffffffffffffffffffffff90911681526020016103e4565b6104f86104de3660046148a9565b600090815260046020526040902054610100900460ff1690565b60405190151581526020016103e4565b6104616105163660046148a9565b61161b565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103e4565b60186103da565b6106b36040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915250604080516101608101825260165473ffffffffffffffffffffffffffffffffffffffff808216835263ffffffff740100000000000000000000000000000000000000008084048216602086015278010000000000000000000000000000000000000000000000008085048316968601969096527c010000000000000000000000000000000000000000000000000000000093849004821660608601526017548084166080870152818104831660a0870152868104831660c087015293909304811660e085015260185491821661010085015291810482166101208401529290920490911661014082015290565b6040516103e49190614939565b6104206106ce366004614a63565b611638565b61042061188e565b6106ee6106e9366004614ad8565b6118f4565b60408051951515865260ff90941660208601526bffffffffffffffffffffffff9283169385019390935216606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a0016103e4565b610420611a13565b6014547801000000000000000000000000000000000000000000000000900460ff166104f8565b6104f861077e3660046148a9565b60009081526008602052604090205460ff1690565b62017f986103da565b6107af6107aa3660046148a9565b611eaa565b6040516103e49190614b34565b7f000000000000000000000000000000000000000000000000000000000000000061053d565b6108d46107f0366004614ad8565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525073ffffffffffffffffffffffffffffffffffffffff908116600090815260226020908152604091829020825160c081018452815463ffffffff81168252640100000000810462ffffff16938201939093526701000000000000008304909416928401929092527b01000000000000000000000000000000000000000000000000000000900460ff16606083015260018101546080830152600201546bffffffffffffffffffffffff1660a082015290565b6040516103e49190600060c08201905063ffffffff835116825262ffffff602084015116602083015273ffffffffffffffffffffffffffffffffffffffff604084015116604083015260ff6060840151166060830152608083015160808301526bffffffffffffffffffffffff60a08401511660a083015292915050565b7f000000000000000000000000000000000000000000000000000000000000000061053d565b6104b3610986366004614b47565b611eb5565b610461610999366004614ad8565b612010565b7f000000000000000000000000000000000000000000000000000000000000000061053d565b6104206109d2366004614ba7565b612043565b6103da6109e5366004614ad8565b6120c3565b61042061216d565b61053d610a003660046148a9565b6000908152600460205260409020546a0100000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b61042061226f565b60005473ffffffffffffffffffffffffffffffffffffffff1661053d565b60155473ffffffffffffffffffffffffffffffffffffffff1661053d565b610a826122e8565b6040516103e49190614be3565b61053d610a9d3660046148a9565b60009081526004602052604090206002015473ffffffffffffffffffffffffffffffffffffffff1690565b6103a46103da565b7f000000000000000000000000000000000000000000000000000000000000000061053d565b6104f8610b04366004614ad8565b73ffffffffffffffffffffffffffffffffffffffff908116600090815260226020526040902054670100000000000000900416151590565b610420610b4a366004614c4c565b6123fa565b610420612728565b604051600481526020016103e4565b6115e06103da565b7f000000000000000000000000000000000000000000000000000000000000000061053d565b610420610ba2366004614ad8565b61275a565b60326103da565b6104b3610bbc3660046148a9565b612852565b610bc9612979565b6040516103e49190614c7a565b610bde6129e8565b6040516103e49190614cd4565b60255460ff166107af565b610c09610c043660046148a9565b612bd0565b6040516103e49190614e5b565b7f000000000000000000000000000000000000000000000000000000000000000061053d565b6103da612fe0565b6104b3610c523660046148a9565b612fef565b601b546103da565b610dd86040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101919091525060408051610120810182526014546bffffffffffffffffffffffff8116825263ffffffff6c01000000000000000000000000820416602083015262ffffff7001000000000000000000000000000000008204169282019290925261ffff730100000000000000000000000000000000000000830416606082015260ff750100000000000000000000000000000000000000000083048116608083015276010000000000000000000000000000000000000000000083048116151560a08301527701000000000000000000000000000000000000000000000083048116151560c08301527801000000000000000000000000000000000000000000000000909204909116151560e082015260155473ffffffffffffffffffffffffffffffffffffffff1661010082015290565b6040516103e49190614f92565b610420610df3366004614c4c565b612ffa565b6103da610e06366004614ad8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526021602052604090205490565b610e88610e3c366004614ad8565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602090815260409182902082518084019093525460ff8082161515808552610100909204169290910182905291565b60408051921515835260ff9091166020830152016103e4565b610420610eaf366004614ad8565b613159565b610f0f610ec23660046148a9565b60408051808201909152600080825260208201525060009081526023602090815260409182902082518084019093525463ffffffff81168352640100000000900462ffffff169082015290565b60408051825163ffffffff16815260209283015162ffffff1692810192909252016103e4565b60406103da565b610f75610f4a366004614ad8565b73ffffffffffffffffffffffffffffffffffffffff166000908152601c602052604090205460ff1690565b6040516103e49190615062565b6103da61316d565b60606000610f986002613175565b9050808410610fd3576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610fdf84866150a5565b905081811180610fed575083155b610ff75780610ff9565b815b9050600061100786836150b8565b67ffffffffffffffff81111561101f5761101f6150cb565b604051908082528060200260200182016040528015611048578160200160208202803683370190505b50905060005b815181101561109b5761106c61106488836150a5565b60029061317f565b82828151811061107e5761107e6150fa565b60209081029190910101528061109381615129565b91505061104e565b50925050505b92915050565b6110af61318b565b6000838152601f602052604090206110c8828483615203565b50827f2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae776983836040516110fb92919061531e565b60405180910390a2505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152604080516101e08101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a08201526101c081019190915260408051610140810182526016547c0100000000000000000000000000000000000000000000000000000000900463ffffffff1681526000602082018190529181018290526014546bffffffffffffffffffffffff16606080830191909152918291608081016112416002613175565b81526017547401000000000000000000000000000000000000000080820463ffffffff908116602080860191909152780100000000000000000000000000000000000000000000000080850483166040808801919091526013546060808901919091526014546c01000000000000000000000000810486166080808b0191909152760100000000000000000000000000000000000000000000820460ff16151560a09a8b015283516101e0810185526000808252968101879052601654898104891695820195909552700100000000000000000000000000000000830462ffffff169381019390935273010000000000000000000000000000000000000090910461ffff169082015296870192909252808204831660c08701527c0100000000000000000000000000000000000000000000000000000000909404821660e086015260185492830482166101008601529290910416610120830152601954610140830152601a5461016083015273ffffffffffffffffffffffffffffffffffffffff166101808201529095506101a081016113dc60096131de565b815260175473ffffffffffffffffffffffffffffffffffffffff16602091820152601454600d80546040805182860281018601909152818152949850899489949293600e93750100000000000000000000000000000000000000000090910460ff1692859183018282801561148757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161145c575b50505050509250818054806020026020016040519081016040528092919081815260200182805480156114f057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116114c5575b50505050509150945094509450945094509091929394565b6115106131eb565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601c6020526040902080548291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600381111561157057611570614af5565b02179055505050565b6000818152601f6020526040902080546060919061159690615161565b80601f01602080910402602001604051908101604052809291908181526020018280546115c290615161565b801561160f5780601f106115e45761010080835404028352916020019161160f565b820191906000526020600020905b8154815290600101906020018083116115f257829003601f168201915b50505050509050919050565b6000818152601d6020526040902080546060919061159690615161565b6116406131eb565b600e54811461167b576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b600e5481101561184d576000600e828154811061169d5761169d6150fa565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff9081168084526011909252604083205491935016908585858181106116e7576116e76150fa565b90506020020160208101906116fc9190614ad8565b905073ffffffffffffffffffffffffffffffffffffffff8116158061178f575073ffffffffffffffffffffffffffffffffffffffff82161580159061176d57508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561178f575073ffffffffffffffffffffffffffffffffffffffff81811614155b156117c6576040517fb387a23800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff818116146118375773ffffffffffffffffffffffffffffffffffffffff838116600090815260116020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169183169190911790555b505050808061184590615129565b91505061167e565b507fa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725600e83836040516118829392919061536b565b60405180910390a15050565b6118966131eb565b601480547fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015282918291829182919082906119ba5760608201516014546000916119a6916bffffffffffffffffffffffff1661541d565b600e549091506119b69082615471565b9150505b8151602083015160408401516119d190849061549c565b6060949094015173ffffffffffffffffffffffffffffffffffffffff9a8b16600090815260116020526040902054929b919a9499509750921694509092505050565b611a1b61326c565b600060255460ff166001811115611a3457611a34614af5565b03611a6b576040517fe0262d7400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601454600e546bffffffffffffffffffffffff909116906000611a8e600f613175565b90506000611a9c82846150a5565b905060008167ffffffffffffffff811115611ab957611ab96150cb565b604051908082528060200260200182016040528015611ae2578160200160208202803683370190505b50905060008267ffffffffffffffff811115611b0057611b006150cb565b604051908082528060200260200182016040528015611b29578160200160208202803683370190505b50905060005b85811015611c5b576000600e8281548110611b4c57611b4c6150fa565b600091825260208220015473ffffffffffffffffffffffffffffffffffffffff169150611b7a828a8a6132bd565b9050806bffffffffffffffffffffffff16858481518110611b9d57611b9d6150fa565b60209081029190910181019190915273ffffffffffffffffffffffffffffffffffffffff808416600090815260119092526040909120548551911690859085908110611beb57611beb6150fa565b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920181019190915292166000908152600b909252506040902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff16905580611c5381615129565b915050611b2f565b5060005b84811015611dd8576000611c74600f8361317f565b73ffffffffffffffffffffffffffffffffffffffff8082166000818152600b602090815260408083208151608081018352905460ff80821615158352610100820416828501526bffffffffffffffffffffffff6201000082048116838501526e0100000000000000000000000000009091041660608201529383526011909152902054929350911684611d078a866150a5565b81518110611d1757611d176150fa565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015260408101516bffffffffffffffffffffffff1685611d5a8a866150a5565b81518110611d6a57611d6a6150fa565b60209081029190910181019190915273ffffffffffffffffffffffffffffffffffffffff9092166000908152600b909252506040902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff16905580611dd081615129565b915050611c5f565b5073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166000908152602160205260408120819055611e2b600f613175565b90505b8015611e6857611e55611e4d611e456001846150b8565b600f9061317f565b600f906134c5565b5080611e60816154c1565b915050611e2e565b507f5af23b715253628d12b660b27a4f3fc626562ea8a55040aa99ab3dc178989fad8183604051611e9a9291906154f6565b60405180910390a1505050505050565b60006110a1826134e7565b60408051610120810182526014546bffffffffffffffffffffffff8116825263ffffffff6c01000000000000000000000000820416602083015262ffffff7001000000000000000000000000000000008204169282019290925261ffff730100000000000000000000000000000000000000830416606082015260ff750100000000000000000000000000000000000000000083048116608083015276010000000000000000000000000000000000000000000083048116151560a08301527701000000000000000000000000000000000000000000000083048116151560c08301527801000000000000000000000000000000000000000000000000909204909116151560e082015260155473ffffffffffffffffffffffffffffffffffffffff16610100820152600090818080611fed84613592565b92509250925061200389858a8a8787878d613784565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602080526040902080546060919061159690615161565b61204b61318b565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602080526040902061207a828483615203565b508273ffffffffffffffffffffffffffffffffffffffff167f7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d283836040516110fb92919061531e565b73ffffffffffffffffffffffffffffffffffffffff81166000818152602160205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152919290916370a0823190602401602060405180830381865afa15801561213f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121639190615524565b6110a191906150b8565b60015473ffffffffffffffffffffffffffffffffffffffff1633146121f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6122776131eb565b601480547fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff167601000000000000000000000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020016118ea565b600e5460609060008167ffffffffffffffff811115612309576123096150cb565b60405190808252806020026020018201604052801561234e57816020015b60408051808201909152600080825260208201528152602001906001900390816123275790505b50905060005b828110156123f3576000600e8281548110612371576123716150fa565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff9081168084526011835260409384902054845180860190955281855290911691830182905285519093509091908590859081106123d3576123d36150fa565b6020026020010181905250505080806123eb90615129565b915050612354565b5092915050565b73ffffffffffffffffffffffffffffffffffffffff8116612447576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160255460ff16600181111561246057612460614af5565b03612497576040517f4a3578fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152601160205260409020541633146124f7576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601454600e5460009161251a9185916bffffffffffffffffffffffff16906132bd565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600b6020908152604080832080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff1690557f000000000000000000000000000000000000000000000000000000000000000090931682526021905220549091506125b1906bffffffffffffffffffffffff8316906150b8565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166000818152602160205260408082209490945592517fa9059cbb00000000000000000000000000000000000000000000000000000000815291851660048301526bffffffffffffffffffffffff841660248301529063a9059cbb906044016020604051808303816000875af1158015612666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268a919061553d565b9050806126c3576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405133815273ffffffffffffffffffffffffffffffffffffffff808516916bffffffffffffffffffffffff8516918716907f9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f406989060200160405180910390a450505050565b6127306131eb565b602580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601260205260409020541633146127ba576040517f6752e7aa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81811660008181526011602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556012909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b6000818152600460209081526040808320815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e08201526002909101549091169181019190915261297283612962816134e7565b8360400151846101000151611eb5565b9392505050565b606060248054806020026020016040519081016040528092919081815260200182805480156129de57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116129b3575b5050505050905090565b604080516102008101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a082018390526101c08201526101e0810191909152604080516102008101825260165463ffffffff74010000000000000000000000000000000000000000808304821684527801000000000000000000000000000000000000000000000000808404831660208601526017547c0100000000000000000000000000000000000000000000000000000000810484169686019690965273ffffffffffffffffffffffffffffffffffffffff938416606086015260145460ff828204161515608087015262ffffff70010000000000000000000000000000000082041660a0870152601854928304841660c087015290820490921660e085015293821661010084015261ffff7301000000000000000000000000000000000000009091041661012083015291909116610140820152601954610160820152601a54610180820152601b546101a08201526101c08101612baa60096131de565b815260155473ffffffffffffffffffffffffffffffffffffffff16602090910152919050565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526000828152600460209081526040808320815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a010000000000000000000090910481166080830181905260018401546fffffffffffffffffffffffffffffffff811660a08501526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08501527c0100000000000000000000000000000000000000000000000000000000900490941660e08301526002909201549091169281019290925290919015612da557816080015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da0919061555f565b612da8565b60005b90506040518061014001604052808273ffffffffffffffffffffffffffffffffffffffff168152602001836040015163ffffffff168152602001600760008781526020019081526020016000208054612e0090615161565b80601f0160208091040260200160405190810160405280929190818152602001828054612e2c90615161565b8015612e795780601f10612e4e57610100808354040283529160200191612e79565b820191906000526020600020905b815481529060010190602001808311612e5c57829003601f168201915b505050505081526020018360c001516bffffffffffffffffffffffff1681526020016005600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001836060015163ffffffff1667ffffffffffffffff1681526020018360e0015163ffffffff1681526020018360a001516bffffffffffffffffffffffff168152602001836000015115158152602001601e60008781526020019081526020016000208054612f5690615161565b80601f0160208091040260200160405190810160405280929190818152602001828054612f8290615161565b8015612fcf5780601f10612fa457610100808354040283529160200191612fcf565b820191906000526020600020905b815481529060010190602001808311612fb257829003601f168201915b505050505081525092505050919050565b6000612fea613af4565b905090565b60006110a182612852565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526011602052604090205416331461305a576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff8216036130a9576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152601260205260409020548116908216146131555773ffffffffffffffffffffffffffffffffffffffff82811660008181526012602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055513392917f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836791a45b5050565b6131616131eb565b61316a81613bbe565b50565b6000612fea60025b60006110a1825490565b60006129728383613cb3565b60175473ffffffffffffffffffffffffffffffffffffffff1633146131dc576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6060600061297283613cdd565b60005473ffffffffffffffffffffffffffffffffffffffff1633146131dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016121ea565b60185473ffffffffffffffffffffffffffffffffffffffff1633146131dc576040517fb6dfb7a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906134b9576000816060015185613355919061541d565b905060006133638583615471565b90508083604001818151613377919061549c565b6bffffffffffffffffffffffff16905250613392858261557c565b836060018181516133a3919061549c565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b60006129728373ffffffffffffffffffffffffffffffffffffffff8416613d38565b6000818160045b600f811015613574577fff00000000000000000000000000000000000000000000000000000000000000821683826020811061352c5761352c6150fa565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461356257506000949350505050565b8061356c81615129565b9150506134ee565b5081600f1a600181111561358a5761358a614af5565b949350505050565b600080600080846040015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561361f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061364391906155c3565b509450909250505060008113158061365a57508142105b8061367b575082801561367b575061367282426150b8565b8463ffffffff16105b1561368a57601954965061368e565b8096505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156136f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371d91906155c3565b509450909250505060008113158061373457508142105b806137555750828015613755575061374c82426150b8565b8463ffffffff16105b1561376457601a549550613768565b8095505b86866137738a613e2b565b965096509650505050509193909250565b600080808089600181111561379b5761379b614af5565b036137aa575062017f986137ff565b60018960018111156137be576137be614af5565b036137cd57506201e26c6137ff565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008a6080015160016138129190615613565b6138209060ff16604061562c565b60185461384e906103a49074010000000000000000000000000000000000000000900463ffffffff166150a5565b61385891906150a5565b601554604080517fde9ee35e0000000000000000000000000000000000000000000000000000000081528151939450600093849373ffffffffffffffffffffffffffffffffffffffff169263de9ee35e92600480820193918290030181865afa1580156138c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ed9190615643565b909250905081836138ff8360186150a5565b613909919061562c565b60808f0151613919906001615613565b6139289060ff166115e061562c565b61393291906150a5565b61393c91906150a5565b61394690856150a5565b6101008e01516040517f125441400000000000000000000000000000000000000000000000000000000081526004810186905291955073ffffffffffffffffffffffffffffffffffffffff1690631254414090602401602060405180830381865afa1580156139b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139dd9190615524565b8d6060015161ffff166139f0919061562c565b94505050506000613a018b86613f15565b60008d815260046020526040902054909150610100900460ff1615613a665760008c81526023602090815260409182902082518084018452905463ffffffff811680835264010000000090910462ffffff908116928401928352928501525116908201525b6000613ad08c6040518061012001604052808d63ffffffff1681526020018681526020018781526020018c81526020018b81526020018a81526020018973ffffffffffffffffffffffffffffffffffffffff16815260200185815260200160001515815250614091565b60208101518151919250613ae39161549c565b9d9c50505050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166000818152602160205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152919290916370a0823190602401602060405180830381865afa158015613b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb49190615524565b612fea9190615667565b3373ffffffffffffffffffffffffffffffffffffffff821603613c3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016121ea565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613cca57613cca6150fa565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561160f57602002820191906000526020600020905b815481526020019060010190808311613d195750505050509050919050565b60008181526001830160205260408120548015613e21576000613d5c6001836150b8565b8554909150600090613d70906001906150b8565b9050818114613dd5576000866000018281548110613d9057613d906150fa565b9060005260206000200154905080876000018481548110613db357613db36150fa565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613de657613de6615687565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506110a1565b60009150506110a1565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613e9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ebf91906155c3565b50935050925050600082131580613ed557508042105b80613f0557506000846040015162ffffff16118015613f055750613ef981426150b8565b846040015162ffffff16105b156123f3575050601b5492915050565b60408051608081018252600080825260208083018281528385018381526060850184905273ffffffffffffffffffffffffffffffffffffffff878116855260229093528584208054640100000000810462ffffff1690925263ffffffff82169092527b01000000000000000000000000000000000000000000000000000000810460ff16855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495919484936701000000000000009092049091169163feaf968c9160048083019260a09291908290030181865afa158015614002573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061402691906155c3565b5093505092505060008213158061403c57508042105b8061406c57506000866040015162ffffff1611801561406c575061406081426150b8565b866040015162ffffff16105b156140805760018301546060850152614088565b606084018290525b50505092915050565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915260008260e001516000015160ff1690506000846060015161ffff1684606001516140fc919061562c565b9050836101000151801561410f5750803a105b1561411757503a5b60006012831161412857600161413e565b6141336012846150b8565b61413e90600a6157d6565b9050600060128410614151576001614167565b61415c8460126150b8565b61416790600a6157d6565b905060008660a0015187604001518860200151896000015161418991906150a5565b614193908761562c565b61419d91906150a5565b6141a7919061562c565b9050614203828860e00151606001516141c0919061562c565b6001848a60e00151606001516141d6919061562c565b6141e091906150b8565b6141ea868561562c565b6141f491906150a5565b6141fe91906157e2565b6143d8565b6bffffffffffffffffffffffff1686526080870151614226906141fe90836157e2565b6bffffffffffffffffffffffff1660408088019190915260e0880151015160009061425f9062ffffff16683635c9adc5dea0000061562c565b9050600081633b9aca008a60a001518b60e001516020015163ffffffff168c604001518d600001518b614292919061562c565b61429c91906150a5565b6142a6919061562c565b6142b0919061562c565b6142ba91906157e2565b6142c491906150a5565b9050614307848a60e00151606001516142dd919061562c565b6001868c60e00151606001516142f3919061562c565b6142fd91906150b8565b6141ea888561562c565b6bffffffffffffffffffffffff166020890152608089015161432d906141fe90836157e2565b6bffffffffffffffffffffffff16606089015260c089015173ffffffffffffffffffffffffffffffffffffffff166080808a0191909152890151614370906143d8565b6bffffffffffffffffffffffff1660a0808a0191909152890151614393906143d8565b6bffffffffffffffffffffffff1660c089015260e0890151606001516143b8906143d8565b6bffffffffffffffffffffffff1660e08901525050505050505092915050565b60006bffffffffffffffffffffffff821115614476576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016121ea565b5090565b6000806040838503121561448d57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b838110156144cc578151875295820195908201906001016144b0565b509495945050505050565b602081526000612972602083018461449c565b60008083601f8401126144fc57600080fd5b50813567ffffffffffffffff81111561451457600080fd5b60208301915083602082850101111561452c57600080fd5b9250929050565b60008060006040848603121561454857600080fd5b83359250602084013567ffffffffffffffff81111561456657600080fd5b614572868287016144ea565b9497909650939450505050565b600081518084526020808501945080840160005b838110156144cc57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614593565b805163ffffffff16825260006101e060208301516145eb602086018263ffffffff169052565b506040830151614603604086018263ffffffff169052565b50606083015161461a606086018262ffffff169052565b506080830151614630608086018261ffff169052565b5060a083015161465060a08601826bffffffffffffffffffffffff169052565b5060c083015161466860c086018263ffffffff169052565b5060e083015161468060e086018263ffffffff169052565b506101008381015163ffffffff908116918601919091526101208085015190911690850152610140808401519085015261016080840151908501526101808084015173ffffffffffffffffffffffffffffffffffffffff16908501526101a0808401518186018390526146f58387018261457f565b925050506101c0808401516147218287018273ffffffffffffffffffffffffffffffffffffffff169052565b5090949350505050565b855163ffffffff16815260006101c0602088015161475960208501826bffffffffffffffffffffffff169052565b5060408801516040840152606088015161478360608501826bffffffffffffffffffffffff169052565b506080880151608084015260a08801516147a560a085018263ffffffff169052565b5060c08801516147bd60c085018263ffffffff169052565b5060e088015160e0840152610100808901516147e08286018263ffffffff169052565b5050610120888101511515908401526101408301819052614803818401886145c5565b9050828103610160840152614818818761457f565b905082810361018084015261482d818661457f565b9150506148406101a083018460ff169052565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461316a57600080fd5b6000806040838503121561487f57600080fd5b823561488a8161484a565b915060208301356004811061489e57600080fd5b809150509250929050565b6000602082840312156148bb57600080fd5b5035919050565b6000815180845260005b818110156148e8576020818501810151868301820152016148cc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061297260208301846148c2565b815173ffffffffffffffffffffffffffffffffffffffff1681526101608101602083015161496f602084018263ffffffff169052565b506040830151614987604084018263ffffffff169052565b50606083015161499f606084018263ffffffff169052565b5060808301516149c7608084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a08301516149df60a084018263ffffffff169052565b5060c08301516149f760c084018263ffffffff169052565b5060e0830151614a0f60e084018263ffffffff169052565b506101008381015173ffffffffffffffffffffffffffffffffffffffff81168483015250506101208381015163ffffffff81168483015250506101408381015163ffffffff8116848301525b505092915050565b60008060208385031215614a7657600080fd5b823567ffffffffffffffff80821115614a8e57600080fd5b818501915085601f830112614aa257600080fd5b813581811115614ab157600080fd5b8660208260051b8501011115614ac657600080fd5b60209290920196919550909350505050565b600060208284031215614aea57600080fd5b81356129728161484a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6002811061316a5761316a614af5565b60208101614b4183614b24565b91905290565b60008060008060808587031215614b5d57600080fd5b84359350602085013560028110614b7357600080fd5b9250604085013563ffffffff81168114614b8c57600080fd5b91506060850135614b9c8161484a565b939692955090935050565b600080600060408486031215614bbc57600080fd5b8335614bc78161484a565b9250602084013567ffffffffffffffff81111561456657600080fd5b602080825282518282018190526000919060409081850190868401855b82811015614c3f578151805173ffffffffffffffffffffffffffffffffffffffff90811686529087015116868501529284019290850190600101614c00565b5091979650505050505050565b60008060408385031215614c5f57600080fd5b8235614c6a8161484a565b9150602083013561489e8161484a565b6020808252825182820181905260009190848201906040850190845b81811015614cc857835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614c96565b50909695505050505050565b60208152614ceb60208201835163ffffffff169052565b60006020830151614d04604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015180151560a08401525060a083015162ffffff811660c08401525060c083015163ffffffff811660e08401525060e0830151610100614d838185018363ffffffff169052565b8401519050610120614dac8482018373ffffffffffffffffffffffffffffffffffffffff169052565b8401519050610140614dc38482018361ffff169052565b8401519050610160614dec8482018373ffffffffffffffffffffffffffffffffffffffff169052565b840151610180848101919091528401516101a0808501919091528401516101c0808501919091528401516102006101e080860182905291925090614e3461022086018461457f565b9086015173ffffffffffffffffffffffffffffffffffffffff811683870152909250614721565b60208152614e8260208201835173ffffffffffffffffffffffffffffffffffffffff169052565b60006020830151614e9b604084018263ffffffff169052565b506040830151610140806060850152614eb86101608501836148c2565b91506060850151614ed960808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e0850151610100614f45818701836bffffffffffffffffffffffff169052565b8601519050610120614f5a8682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183870152905061484083826148c2565b6000610120820190506bffffffffffffffffffffffff835116825263ffffffff60208401511660208301526040830151614fd3604084018262ffffff169052565b506060830151614fe9606084018261ffff169052565b506080830151614ffe608084018260ff169052565b5060a083015161501260a084018215159052565b5060c083015161502660c084018215159052565b5060e083015161503a60e084018215159052565b506101008381015173ffffffffffffffffffffffffffffffffffffffff811684830152614a5b565b6020810160048310614b4157614b41614af5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156110a1576110a1615076565b818103818111156110a1576110a1615076565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361515a5761515a615076565b5060010190565b600181811c9082168061517557607f821691505b6020821081036151ae577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156151fe57600081815260208120601f850160051c810160208610156151db5750805b601f850160051c820191505b818110156151fa578281556001016151e7565b5050505b505050565b67ffffffffffffffff83111561521b5761521b6150cb565b61522f836152298354615161565b836151b4565b6000601f841160018114615281576000851561524b5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355615317565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156152d057868501358255602094850194600190920191016152b0565b508682101561530b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000604082016040835280865480835260608501915087600052602092508260002060005b828110156153c257815473ffffffffffffffffffffffffffffffffffffffff1684529284019260019182019101615390565b505050838103828501528481528590820160005b868110156154115782356153e98161484a565b73ffffffffffffffffffffffffffffffffffffffff16825291830191908301906001016153d6565b50979650505050505050565b6bffffffffffffffffffffffff8281168282160390808211156123f3576123f3615076565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006bffffffffffffffffffffffff8084168061549057615490615442565b92169190910492915050565b6bffffffffffffffffffffffff8181168382160190808211156123f3576123f3615076565b6000816154d0576154d0615076565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b604081526000615509604083018561457f565b828103602084015261551b818561449c565b95945050505050565b60006020828403121561553657600080fd5b5051919050565b60006020828403121561554f57600080fd5b8151801515811461297257600080fd5b60006020828403121561557157600080fd5b81516129728161484a565b6bffffffffffffffffffffffff818116838216028082169190828114614a5b57614a5b615076565b805169ffffffffffffffffffff811681146155be57600080fd5b919050565b600080600080600060a086880312156155db57600080fd5b6155e4866155a4565b9450602086015193506040860151925060608601519150615607608087016155a4565b90509295509295909350565b60ff81811683821601908111156110a1576110a1615076565b80820281158282048414176110a1576110a1615076565b6000806040838503121561565657600080fd5b505080516020909101519092909150565b81810360008312801583831316838312821617156123f3576123f3615076565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600181815b8085111561570f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156156f5576156f5615076565b8085161561570257918102915b93841c93908002906156bb565b509250929050565b600082615726575060016110a1565b81615733575060006110a1565b816001811461574957600281146157535761576f565b60019150506110a1565b60ff84111561576457615764615076565b50506001821b6110a1565b5060208310610133831016604e8410600b8410161715615792575081810a6110a1565b61579c83836156b6565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156157ce576157ce615076565b029392505050565b60006129728383615717565b6000826157f1576157f1615442565b50049056fea164736f6c6343000813000a", } var AutomationRegistryLogicCABI = AutomationRegistryLogicCMetaData.ABI diff --git a/core/gethwrappers/generated/automation_registry_wrapper_2_2/automation_registry_wrapper_2_2.go b/core/gethwrappers/generated/automation_registry_wrapper_2_2/automation_registry_wrapper_2_2.go index eb385cf7b0..a7fcf430b3 100644 --- a/core/gethwrappers/generated/automation_registry_wrapper_2_2/automation_registry_wrapper_2_2.go +++ b/core/gethwrappers/generated/automation_registry_wrapper_2_2/automation_registry_wrapper_2_2.go @@ -52,7 +52,7 @@ type AutomationRegistryBase22OnchainConfig struct { var AutomationRegistryMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_2\",\"name\":\"logicA\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_2.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b506040516200524a3803806200524a8339810160408190526200003591620003b1565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b9190620003b1565b826001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003b1565b836001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003b1565b846001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003b1565b856001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003b1565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b981620002ed565b5050506001600160a01b0394851660805292841660a05290831660c052821660e052811661010052166101205250620003d8565b336001600160a01b03821603620003475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003ae57600080fd5b50565b600060208284031215620003c457600080fd5b8151620003d18162000398565b9392505050565b60805160a05160c05160e0516101005161012051614e25620004256000396000818160c9015261017c01526000611bb8015260005050600050506000505060006104c20152614e256000f3fe6080604052600436106100c75760003560e01c8063aed2e92911610074578063e3d0e7121161004e578063e3d0e71214610348578063f2fde38b14610368578063f75f6b1114610388576100c7565b8063aed2e929146102a3578063afcb95d7146102da578063b1dc65a414610328576100c7565b806381ff7048116100a557806381ff7048146101d65780638da5cb5b14610258578063a4c0ed3614610283576100c7565b8063181f5a771461010e578063349e8cca1461016d57806379ba5097146101c1575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610107573d6000f35b3d6000fd5b005b34801561011a57600080fd5b506101576040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e322e30000000000000000081525081565b6040516101649190613b21565b60405180910390f35b34801561017957600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b3480156101cd57600080fd5b5061010c6103a8565b3480156101e257600080fd5b5061023560155460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b34801561026457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661019c565b34801561028f57600080fd5b5061010c61029e366004613baf565b6104aa565b3480156102af57600080fd5b506102c36102be366004613c0b565b6106c6565b604080519215158352602083019190915201610164565b3480156102e657600080fd5b50601154601254604080516000815260208101939093527401000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b34801561033457600080fd5b5061010c610343366004613c9c565b61083c565b34801561035457600080fd5b5061010c610363366004613f6d565b610b77565b34801561037457600080fd5b5061010c61038336600461403a565b610ba0565b34801561039457600080fd5b5061010c6103a336600461423e565b610bb4565b60015473ffffffffffffffffffffffffffffffffffffffff16331461042e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610519576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114610553576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610561828401846142cd565b60008181526004602052604090205490915065010000000000900463ffffffff908116146105bb576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020600101546105f69085906c0100000000000000000000000090046bffffffffffffffffffffffff16614315565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff90921691909117905560195461066190859061433a565b6019556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b6000806106d1611ba0565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff1615610730576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff908116838601819052650100000000008304821684880152690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606084018190526001909401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a0850152780100000000000000000000000000000000000000000000000090041660c08301528451601f8901859004850281018501909552878552909361082f938990899081908401838280828437600092019190915250611c1192505050565b9097909650945050505050565b60005a60408051610160810182526012546bffffffffffffffffffffffff8116825263ffffffff6c010000000000000000000000008204811660208401527001000000000000000000000000000000008204811693830193909352740100000000000000000000000000000000000000008104909216606082015262ffffff7801000000000000000000000000000000000000000000000000830416608082015261ffff7b0100000000000000000000000000000000000000000000000000000083041660a082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660c08301527e010000000000000000000000000000000000000000000000000000000000008304811615801560e08401527f01000000000000000000000000000000000000000000000000000000000000009093048116151561010080840191909152601354918216151561012084015273ffffffffffffffffffffffffffffffffffffffff9104166101408201529192506109f2576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff16610a3b576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a3514610a77576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c0810151610a8790600161437c565b60ff1686141580610a985750858414155b15610acf576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610adf8a8a8a8a8a8a8a8a611e3a565b6000610aeb8a8a6120a3565b905060208b0135600881901c63ffffffff16610b0884848761215e565b836060015163ffffffff168163ffffffff161115610b6857601280547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8416021790555b50505050505050505050505050565b610b9886868686806020019051810190610b91919061443b565b8686610bb4565b505050505050565b610ba8612add565b610bb181612b5e565b50565b610bbc612add565b601f86511115610bf8576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff16600003610c35576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518651141580610c545750610c4c8460036145bd565b60ff16865111155b15610c8b576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e546bffffffffffffffffffffffff9091169060005b816bffffffffffffffffffffffff16811015610d0d57610cfa600e8281548110610cd157610cd161434d565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484612c53565b5080610d05816145d9565b915050610ca5565b5060008060005b836bffffffffffffffffffffffff16811015610e1657600d8181548110610d3d57610d3d61434d565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff90921694509082908110610d7857610d7861434d565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055915080610e0e816145d9565b915050610d14565b50610e23600d6000613a00565b610e2f600e6000613a00565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c5181101561129857600c60008e8381518110610e7457610e7461434d565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615610edf576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168d8281518110610f0957610f0961434d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610f5e576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f8481518110610f8f57610f8f61434d565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c90829081106110375761103761434d565b60200260200101519150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036110a7576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e01000000000000000000000000000090049092166060830152909350611162576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169490941717919091169290921791909117905580611290816145d9565b915050610e55565b50508a516112ae9150600d9060208d0190613a1e565b5088516112c290600e9060208c0190613a1e565b50604051806101600160405280856bffffffffffffffffffffffff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001600063ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020018960ff1681526020016012600001601e9054906101000a900460ff16151581526020016012600001601f9054906101000a900460ff161515815260200188610200015115158152602001886101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601260008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060808201518160000160186101000a81548162ffffff021916908362ffffff16021790555060a082015181600001601b6101000a81548161ffff021916908361ffff16021790555060c082015181600001601d6101000a81548160ff021916908360ff16021790555060e082015181600001601e6101000a81548160ff02191690831515021790555061010082015181600001601f6101000a81548160ff0219169083151502179055506101208201518160010160006101000a81548160ff0219169083151502179055506101408201518160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601460010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601460010160149054906101000a900463ffffffff1663ffffffff168152602001601460010160189054906101000a900463ffffffff1663ffffffff1681526020016014600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160178190555086610160015160188190555060006014600101601c9054906101000a900463ffffffff169050876101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611963573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119879190614611565b601580547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601891611a02918591780100000000000000000000000000000000000000000000000090041661462a565b92506101000a81548163ffffffff021916908363ffffffff160217905550600088604051602001611a339190614698565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601554909150611a9c90469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612e5b565b60115560005b611aac6009612f05565b811015611adc57611ac9611ac1600983612f0f565b600990612f22565b5080611ad4816145d9565b915050611aa2565b5060005b896101a0015151811015611b3357611b208a6101a001518281518110611b0857611b0861434d565b60200260200101516009612f4490919063ffffffff16565b5080611b2b816145d9565b915050611ae0565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601460010160189054906101000a900463ffffffff168f8f8f878f8f604051611b8a9998979695949392919061483c565b60405180910390a1505050505050505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611c0f576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60125460009081907f0100000000000000000000000000000000000000000000000000000000000000900460ff1615611c76576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790556040517f4585e33b0000000000000000000000000000000000000000000000000000000090611cf2908590602401613b21565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d1690611dc590879087906004016148d2565b60408051808303816000875af1158015611de3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0791906148eb565b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b60008787604051611e4c929190614919565b604051908190038120611e63918b90602001614929565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b8881101561203a57600185878360208110611ecf57611ecf61434d565b611edc91901a601b61437c565b8c8c85818110611eee57611eee61434d565b905060200201358b8b86818110611f0757611f0761434d565b9050602002013560405160008152602001604052604051611f44949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611f66573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612014576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b840193508080612032906145d9565b915050611eb2565b50827e01010101010101010101010101010101010101010101010101010101010101841614612095576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b6120dc6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b60006120ea83850185614a1a565b604081015151606082015151919250908114158061210d57508082608001515114155b8061211d5750808260a001515114155b15612154576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090505b92915050565b600082604001515167ffffffffffffffff81111561217e5761217e613d53565b60405190808252806020026020018201604052801561223a57816020015b604080516101c081018252600060e08201818152610100830182905261012083018290526101408301829052610160830182905261018083018290526101a0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161219c5790505b50905060006040518060800160405280600061ffff1681526020016000815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152509050600085610140015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122fc9190614611565b9050600086610140015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa158015612350573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123749190614611565b905060005b8660400151518110156127c35760046000886040015183815181106123a0576123a061434d565b6020908102919091018101518252818101929092526040908101600020815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c082015285518690839081106124855761248561434d565b6020026020010151600001819052506124ba876040015182815181106124ad576124ad61434d565b6020026020010151612f66565b8582815181106124cc576124cc61434d565b60200260200101516060019060018111156124e9576124e9614b07565b908160018111156124fc576124fc614b07565b81525050612560876040015182815181106125195761251961434d565b602002602001015184896080015184815181106125385761253861434d565b60200260200101518885815181106125525761255261434d565b60200260200101518c613011565b8683815181106125725761257261434d565b602002602001015160200187848151811061258f5761258f61434d565b602002602001015160c00182815250821515151581525050508481815181106125ba576125ba61434d565b602002602001015160200151156125ea576001846000018181516125de9190614b36565b61ffff169052506125ef565b6127b1565b6126558582815181106126045761260461434d565b602002602001015160000151606001518860600151838151811061262a5761262a61434d565b60200260200101518960a0015184815181106126485761264861434d565b6020026020010151611c11565b8683815181106126675761266761434d565b60200260200101516040018784815181106126845761268461434d565b602090810291909101015160800191909152901515905260c08801516126ab90600161437c565b6126b99060ff166040614b51565b6103a48860a0015183815181106126d2576126d261434d565b6020026020010151516126e5919061433a565b6126ef919061433a565b8582815181106127015761270161434d565b602002602001015160a00181815250508481815181106127235761272361434d565b602002602001015160a0015184602001818151612740919061433a565b90525084518590829081106127575761275761434d565b6020026020010151608001518661276e9190614b68565b95506127b1876040015182815181106127895761278961434d565b6020026020010151848784815181106127a4576127a461434d565b6020026020010151613130565b806127bb816145d9565b915050612379565b50825161ffff166000036127da5750505050505050565b6155f06127e8366010614b51565b5a6127f39088614b68565b6127fd919061433a565b612807919061433a565b8351909550611b589061281e9061ffff1687614baa565b612828919061433a565b945060008060005b886040015151811015612a0c5786818151811061284f5761284f61434d565b602002602001015160200151156129fa576128e88a8a60400151838151811061287a5761287a61434d565b60200260200101518984815181106128945761289461434d565b6020026020010151608001518c600001518d602001518d8c602001518e89815181106128c2576128c261434d565b602002602001015160a001518c6128d99190614b51565b6128e39190614baa565b613235565b6060880180519295509093508391612901908390614315565b6bffffffffffffffffffffffff16905250604086018051849190612926908390614315565b6bffffffffffffffffffffffff16905250865187908290811061294b5761294b61434d565b60200260200101516040015115158960400151828151811061296f5761296f61434d565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b84866129a49190614315565b8a85815181106129b6576129b661434d565b6020026020010151608001518c8e6080015187815181106129d9576129d961434d565b60200260200101516040516129f19493929190614bbe565b60405180910390a35b80612a04816145d9565b915050612830565b505050604083810151336000908152600b602052919091208054600290612a489084906201000090046bffffffffffffffffffffffff16614315565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260600151601260000160008282829054906101000a90046bffffffffffffffffffffffff16612aa69190614315565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611c0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610425565b3373ffffffffffffffffffffffffffffffffffffffff821603612bdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610425565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015290612e4f576000816060015185612ceb9190614bfb565b90506000612cf98583614c20565b90508083604001818151612d0d9190614315565b6bffffffffffffffffffffffff16905250612d288582614c4b565b83606001818151612d399190614315565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b6000808a8a8a8a8a8a8a8a8a604051602001612e7f99989796959493929190614c7b565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b6000612158825490565b6000612f1b83836133b8565b9392505050565b6000612f1b8373ffffffffffffffffffffffffffffffffffffffff84166133e2565b6000612f1b8373ffffffffffffffffffffffffffffffffffffffff84166134dc565b6000818160045b600f811015612ff3577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612fab57612fab61434d565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612fe157506000949350505050565b80612feb816145d9565b915050612f6d565b5081600f1a600181111561300957613009614b07565b949350505050565b60008080808560600151600181111561302c5761302c614b07565b036130525761303e888888888861352b565b61304d57600092509050613126565b6130ca565b60018560600151600181111561306a5761306a614b07565b0361309857600061307d898989886136b6565b92509050806130925750600092509050613126565b506130ca565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516040015163ffffffff16871061311f57877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd56368760405161310c9190613b21565b60405180910390a2600092509050613126565b6001925090505b9550959350505050565b60008160600151600181111561314857613148614b07565b036131ac57600083815260046020526040902060010180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff851602179055505050565b6001816060015160018111156131c4576131c4614b07565b036132305760c08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b600080613248898886868a8a60016138c4565b60008a8152600460205260408120600101549294509092506c010000000000000000000000009091046bffffffffffffffffffffffff169061328a8385614315565b9050836bffffffffffffffffffffffff16826bffffffffffffffffffffffff1610156132be575091506000905081806132f1565b806bffffffffffffffffffffffff16826bffffffffffffffffffffffff1610156132f15750806132ee8482614bfb565b92505b60008a81526004602052604090206001018054829190600c906133339084906c0100000000000000000000000090046bffffffffffffffffffffffff16614bfb565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008c81526004602052604081206001018054859450909261337c91859116614315565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505097509795505050505050565b60008260000182815481106133cf576133cf61434d565b9060005260206000200154905092915050565b600081815260018301602052604081205480156134cb576000613406600183614b68565b855490915060009061341a90600190614b68565b905081811461347f57600086600001828154811061343a5761343a61434d565b906000526020600020015490508087600001848154811061345d5761345d61434d565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061349057613490614d10565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612158565b6000915050612158565b5092915050565b600081815260018301602052604081205461352357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612158565b506000612158565b600080848060200190518101906135429190614d3f565b845160c00151815191925063ffffffff9081169116101561359f57867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e88660405161358d9190613b21565b60405180910390a260009150506136ad565b826101200151801561366057506020810151158015906136605750602081015161014084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015613639573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061365d9190614611565b14155b806136725750805163ffffffff168611155b156136a757867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc3018660405161358d9190613b21565b60019150505b95945050505050565b6000806000848060200190518101906136cf9190614d97565b905060008782600001518360200151846040015160405160200161373194939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b604051602081830303815290604052805190602001209050846101200151801561380d575060808201511580159061380d5750608082015161014086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa1580156137e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380a9190614611565b14155b80613822575086826060015163ffffffff1610155b1561386c57877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301876040516138579190613b21565b60405180910390a26000935091506138bb9050565b60008181526008602052604090205460ff16156138b357877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8876040516138579190613b21565b600193509150505b94509492505050565b60008060008960a0015161ffff16866138dd9190614b51565b90508380156138eb5750803a105b156138f357503a5b600085886139018b8d61433a565b61390b9085614b51565b613915919061433a565b61392790670de0b6b3a7640000614b51565b6139319190614baa565b905060008b6040015163ffffffff1664e8d4a510006139509190614b51565b60208d0151889063ffffffff168b6139688f88614b51565b613972919061433a565b61398090633b9aca00614b51565b61398a9190614b51565b6139949190614baa565b61399e919061433a565b90506b033b2e3c9fd0803ce80000006139b7828461433a565b11156139ef576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909b909a5098505050505050505050565b5080546000825590600052602060002090810190610bb19190613aa8565b828054828255906000526020600020908101928215613a98579160200282015b82811115613a9857825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613a3e565b50613aa4929150613aa8565b5090565b5b80821115613aa45760008155600101613aa9565b6000815180845260005b81811015613ae357602081850181015186830182015201613ac7565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000612f1b6020830184613abd565b73ffffffffffffffffffffffffffffffffffffffff81168114610bb157600080fd5b8035613b6181613b34565b919050565b60008083601f840112613b7857600080fd5b50813567ffffffffffffffff811115613b9057600080fd5b602083019150836020828501011115613ba857600080fd5b9250929050565b60008060008060608587031215613bc557600080fd5b8435613bd081613b34565b935060208501359250604085013567ffffffffffffffff811115613bf357600080fd5b613bff87828801613b66565b95989497509550505050565b600080600060408486031215613c2057600080fd5b83359250602084013567ffffffffffffffff811115613c3e57600080fd5b613c4a86828701613b66565b9497909650939450505050565b60008083601f840112613c6957600080fd5b50813567ffffffffffffffff811115613c8157600080fd5b6020830191508360208260051b8501011115613ba857600080fd5b60008060008060008060008060e0898b031215613cb857600080fd5b606089018a811115613cc957600080fd5b8998503567ffffffffffffffff80821115613ce357600080fd5b613cef8c838d01613b66565b909950975060808b0135915080821115613d0857600080fd5b613d148c838d01613c57565b909750955060a08b0135915080821115613d2d57600080fd5b50613d3a8b828c01613c57565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610220810167ffffffffffffffff81118282101715613da657613da6613d53565b60405290565b60405160c0810167ffffffffffffffff81118282101715613da657613da6613d53565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613e1657613e16613d53565b604052919050565b600067ffffffffffffffff821115613e3857613e38613d53565b5060051b60200190565b600082601f830112613e5357600080fd5b81356020613e68613e6383613e1e565b613dcf565b82815260059290921b84018101918181019086841115613e8757600080fd5b8286015b84811015613eab578035613e9e81613b34565b8352918301918301613e8b565b509695505050505050565b803560ff81168114613b6157600080fd5b600082601f830112613ed857600080fd5b813567ffffffffffffffff811115613ef257613ef2613d53565b613f2360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613dcf565b818152846020838601011115613f3857600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff81168114613b6157600080fd5b60008060008060008060c08789031215613f8657600080fd5b863567ffffffffffffffff80821115613f9e57600080fd5b613faa8a838b01613e42565b97506020890135915080821115613fc057600080fd5b613fcc8a838b01613e42565b9650613fda60408a01613eb6565b95506060890135915080821115613ff057600080fd5b613ffc8a838b01613ec7565b945061400a60808a01613f55565b935060a089013591508082111561402057600080fd5b5061402d89828a01613ec7565b9150509295509295509295565b60006020828403121561404c57600080fd5b8135612f1b81613b34565b63ffffffff81168114610bb157600080fd5b8035613b6181614057565b62ffffff81168114610bb157600080fd5b8035613b6181614074565b61ffff81168114610bb157600080fd5b8035613b6181614090565b6bffffffffffffffffffffffff81168114610bb157600080fd5b8035613b61816140ab565b8015158114610bb157600080fd5b8035613b61816140d0565b600061022082840312156140fc57600080fd5b614104613d82565b905061410f82614069565b815261411d60208301614069565b602082015261412e60408301614069565b604082015261413f60608301614085565b6060820152614150608083016140a0565b608082015261416160a083016140c5565b60a082015261417260c08301614069565b60c082015261418360e08301614069565b60e0820152610100614196818401614069565b908201526101206141a8838201614069565b90820152610140828101359082015261016080830135908201526101806141d0818401613b56565b908201526101a08281013567ffffffffffffffff8111156141f057600080fd5b6141fc85828601613e42565b8284015250506101c0614210818401613b56565b908201526101e0614222838201613b56565b908201526102006142348382016140de565b9082015292915050565b60008060008060008060c0878903121561425757600080fd5b863567ffffffffffffffff8082111561426f57600080fd5b61427b8a838b01613e42565b9750602089013591508082111561429157600080fd5b61429d8a838b01613e42565b96506142ab60408a01613eb6565b955060608901359150808211156142c157600080fd5b613ffc8a838b016140e9565b6000602082840312156142df57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8181168382160190808211156134d5576134d56142e6565b80820180821115612158576121586142e6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60ff8181168382160190811115612158576121586142e6565b8051613b6181614057565b8051613b6181614074565b8051613b6181614090565b8051613b61816140ab565b8051613b6181613b34565b600082601f8301126143dd57600080fd5b815160206143ed613e6383613e1e565b82815260059290921b8401810191818101908684111561440c57600080fd5b8286015b84811015613eab57805161442381613b34565b8352918301918301614410565b8051613b61816140d0565b60006020828403121561444d57600080fd5b815167ffffffffffffffff8082111561446557600080fd5b90830190610220828603121561447a57600080fd5b614482613d82565b61448b83614395565b815261449960208401614395565b60208201526144aa60408401614395565b60408201526144bb606084016143a0565b60608201526144cc608084016143ab565b60808201526144dd60a084016143b6565b60a08201526144ee60c08401614395565b60c08201526144ff60e08401614395565b60e0820152610100614512818501614395565b90820152610120614524848201614395565b908201526101408381015190820152610160808401519082015261018061454c8185016143c1565b908201526101a0838101518381111561456457600080fd5b614570888287016143cc565b8284015250506101c091506145868284016143c1565b828201526101e0915061459a8284016143c1565b8282015261020091506145ae828401614430565b91810191909152949350505050565b60ff81811683821602908116908181146134d5576134d56142e6565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361460a5761460a6142e6565b5060010190565b60006020828403121561462357600080fd5b5051919050565b63ffffffff8181168382160190808211156134d5576134d56142e6565b600081518084526020808501945080840160005b8381101561468d57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161465b565b509495945050505050565b602081526146af60208201835163ffffffff169052565b600060208301516146c8604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006147418185018363ffffffff169052565b840151905061012061475a8482018363ffffffff169052565b84015190506101406147738482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06147b68185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506102206101c081818601526147d6610240860184614647565b908601519092506101e06148018682018373ffffffffffffffffffffffffffffffffffffffff169052565b860151905061020061482a8682018373ffffffffffffffffffffffffffffffffffffffff169052565b90950151151593019290925250919050565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261486c8184018a614647565b905082810360808401526148808189614647565b905060ff871660a084015282810360c084015261489d8187613abd565b905067ffffffffffffffff851660e08401528281036101008401526148c28185613abd565b9c9b505050505050505050505050565b8281526040602082015260006130096040830184613abd565b600080604083850312156148fe57600080fd5b8251614909816140d0565b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f83011261495057600080fd5b81356020614960613e6383613e1e565b82815260059290921b8401810191818101908684111561497f57600080fd5b8286015b84811015613eab5780358352918301918301614983565b600082601f8301126149ab57600080fd5b813560206149bb613e6383613e1e565b82815260059290921b840181019181810190868411156149da57600080fd5b8286015b84811015613eab57803567ffffffffffffffff8111156149fe5760008081fd5b614a0c8986838b0101613ec7565b8452509183019183016149de565b600060208284031215614a2c57600080fd5b813567ffffffffffffffff80821115614a4457600080fd5b9083019060c08286031215614a5857600080fd5b614a60613dac565b8235815260208301356020820152604083013582811115614a8057600080fd5b614a8c8782860161493f565b604083015250606083013582811115614aa457600080fd5b614ab08782860161493f565b606083015250608083013582811115614ac857600080fd5b614ad48782860161499a565b60808301525060a083013582811115614aec57600080fd5b614af88782860161499a565b60a08301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61ffff8181168382160190808211156134d5576134d56142e6565b8082028115828204841417612158576121586142e6565b81810381811115612158576121586142e6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614bb957614bb9614b7b565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000614bf16080830184613abd565b9695505050505050565b6bffffffffffffffffffffffff8281168282160390808211156134d5576134d56142e6565b60006bffffffffffffffffffffffff80841680614c3f57614c3f614b7b565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114614c7357614c736142e6565b505092915050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614cc28285018b614647565b91508382036080850152614cd6828a614647565b915060ff881660a085015283820360c0850152614cf38288613abd565b90861660e085015283810361010085015290506148c28185613abd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060408284031215614d5157600080fd5b6040516040810181811067ffffffffffffffff82111715614d7457614d74613d53565b6040528251614d8281614057565b81526020928301519281019290925250919050565b600060a08284031215614da957600080fd5b60405160a0810181811067ffffffffffffffff82111715614dcc57614dcc613d53565b806040525082518152602083015160208201526040830151614ded81614057565b60408201526060830151614e0081614057565b6060820152608092830151928101929092525091905056fea164736f6c6343000813000a", + Bin: "0x6101406040523480156200001257600080fd5b506040516200526d3803806200526d8339810160408190526200003591620003b1565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b9190620003b1565b826001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003b1565b836001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003b1565b846001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003b1565b856001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003b1565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b981620002ed565b5050506001600160a01b0394851660805292841660a05290831660c052821660e052811661010052166101205250620003d8565b336001600160a01b03821603620003475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003ae57600080fd5b50565b600060208284031215620003c457600080fd5b8151620003d18162000398565b9392505050565b60805160a05160c05160e0516101005161012051614e48620004256000396000818160c9015261017c01526000611bb8015260005050600050506000505060006104c20152614e486000f3fe6080604052600436106100c75760003560e01c8063aed2e92911610074578063e3d0e7121161004e578063e3d0e71214610348578063f2fde38b14610368578063f75f6b1114610388576100c7565b8063aed2e929146102a3578063afcb95d7146102da578063b1dc65a414610328576100c7565b806381ff7048116100a557806381ff7048146101d65780638da5cb5b14610258578063a4c0ed3614610283576100c7565b8063181f5a771461010e578063349e8cca1461016d57806379ba5097146101c1575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610107573d6000f35b3d6000fd5b005b34801561011a57600080fd5b506101576040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e322e30000000000000000081525081565b6040516101649190613b44565b60405180910390f35b34801561017957600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b3480156101cd57600080fd5b5061010c6103a8565b3480156101e257600080fd5b5061023560155460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b34801561026457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661019c565b34801561028f57600080fd5b5061010c61029e366004613bd2565b6104aa565b3480156102af57600080fd5b506102c36102be366004613c2e565b6106c6565b604080519215158352602083019190915201610164565b3480156102e657600080fd5b50601154601254604080516000815260208101939093527401000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b34801561033457600080fd5b5061010c610343366004613cbf565b61083c565b34801561035457600080fd5b5061010c610363366004613f90565b610b77565b34801561037457600080fd5b5061010c61038336600461405d565b610ba0565b34801561039457600080fd5b5061010c6103a3366004614261565b610bb4565b60015473ffffffffffffffffffffffffffffffffffffffff16331461042e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610519576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114610553576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610561828401846142f0565b60008181526004602052604090205490915065010000000000900463ffffffff908116146105bb576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020600101546105f69085906c0100000000000000000000000090046bffffffffffffffffffffffff16614338565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff90921691909117905560195461066190859061435d565b6019556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b6000806106d1611ba0565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff1615610730576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff908116838601819052650100000000008304821684880152690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606084018190526001909401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a0850152780100000000000000000000000000000000000000000000000090041660c08301528451601f8901859004850281018501909552878552909361082f938990899081908401838280828437600092019190915250611c1192505050565b9097909650945050505050565b60005a60408051610160810182526012546bffffffffffffffffffffffff8116825263ffffffff6c010000000000000000000000008204811660208401527001000000000000000000000000000000008204811693830193909352740100000000000000000000000000000000000000008104909216606082015262ffffff7801000000000000000000000000000000000000000000000000830416608082015261ffff7b0100000000000000000000000000000000000000000000000000000083041660a082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660c08301527e010000000000000000000000000000000000000000000000000000000000008304811615801560e08401527f01000000000000000000000000000000000000000000000000000000000000009093048116151561010080840191909152601354918216151561012084015273ffffffffffffffffffffffffffffffffffffffff9104166101408201529192506109f2576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff16610a3b576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a3514610a77576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c0810151610a8790600161439f565b60ff1686141580610a985750858414155b15610acf576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610adf8a8a8a8a8a8a8a8a611e3a565b6000610aeb8a8a6120a3565b905060208b0135600881901c63ffffffff16610b0884848761215e565b836060015163ffffffff168163ffffffff161115610b6857601280547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8416021790555b50505050505050505050505050565b610b9886868686806020019051810190610b91919061445e565b8686610bb4565b505050505050565b610ba8612b00565b610bb181612b81565b50565b610bbc612b00565b601f86511115610bf8576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff16600003610c35576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518651141580610c545750610c4c8460036145e0565b60ff16865111155b15610c8b576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e546bffffffffffffffffffffffff9091169060005b816bffffffffffffffffffffffff16811015610d0d57610cfa600e8281548110610cd157610cd1614370565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484612c76565b5080610d05816145fc565b915050610ca5565b5060008060005b836bffffffffffffffffffffffff16811015610e1657600d8181548110610d3d57610d3d614370565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff90921694509082908110610d7857610d78614370565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055915080610e0e816145fc565b915050610d14565b50610e23600d6000613a23565b610e2f600e6000613a23565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c5181101561129857600c60008e8381518110610e7457610e74614370565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615610edf576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168d8281518110610f0957610f09614370565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610f5e576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f8481518110610f8f57610f8f614370565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c908290811061103757611037614370565b60200260200101519150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036110a7576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e01000000000000000000000000000090049092166060830152909350611162576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169490941717919091169290921791909117905580611290816145fc565b915050610e55565b50508a516112ae9150600d9060208d0190613a41565b5088516112c290600e9060208c0190613a41565b50604051806101600160405280856bffffffffffffffffffffffff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001600063ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020018960ff1681526020016012600001601e9054906101000a900460ff16151581526020016012600001601f9054906101000a900460ff161515815260200188610200015115158152602001886101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601260008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060808201518160000160186101000a81548162ffffff021916908362ffffff16021790555060a082015181600001601b6101000a81548161ffff021916908361ffff16021790555060c082015181600001601d6101000a81548160ff021916908360ff16021790555060e082015181600001601e6101000a81548160ff02191690831515021790555061010082015181600001601f6101000a81548160ff0219169083151502179055506101208201518160010160006101000a81548160ff0219169083151502179055506101408201518160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601460010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601460010160149054906101000a900463ffffffff1663ffffffff168152602001601460010160189054906101000a900463ffffffff1663ffffffff1681526020016014600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160178190555086610160015160188190555060006014600101601c9054906101000a900463ffffffff169050876101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611963573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119879190614634565b601580547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601891611a02918591780100000000000000000000000000000000000000000000000090041661464d565b92506101000a81548163ffffffff021916908363ffffffff160217905550600088604051602001611a3391906146bb565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601554909150611a9c90469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612e7e565b60115560005b611aac6009612f28565b811015611adc57611ac9611ac1600983612f32565b600990612f45565b5080611ad4816145fc565b915050611aa2565b5060005b896101a0015151811015611b3357611b208a6101a001518281518110611b0857611b08614370565b60200260200101516009612f6790919063ffffffff16565b5080611b2b816145fc565b915050611ae0565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601460010160189054906101000a900463ffffffff168f8f8f878f8f604051611b8a9998979695949392919061485f565b60405180910390a1505050505050505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611c0f576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60125460009081907f0100000000000000000000000000000000000000000000000000000000000000900460ff1615611c76576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790556040517f4585e33b0000000000000000000000000000000000000000000000000000000090611cf2908590602401613b44565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d1690611dc590879087906004016148f5565b60408051808303816000875af1158015611de3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e07919061490e565b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b60008787604051611e4c92919061493c565b604051908190038120611e63918b9060200161494c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b8881101561203a57600185878360208110611ecf57611ecf614370565b611edc91901a601b61439f565b8c8c85818110611eee57611eee614370565b905060200201358b8b86818110611f0757611f07614370565b9050602002013560405160008152602001604052604051611f44949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611f66573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612014576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b840193508080612032906145fc565b915050611eb2565b50827e01010101010101010101010101010101010101010101010101010101010101841614612095576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b6120dc6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b60006120ea83850185614a3d565b604081015151606082015151919250908114158061210d57508082608001515114155b8061211d5750808260a001515114155b15612154576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090505b92915050565b600082604001515167ffffffffffffffff81111561217e5761217e613d76565b60405190808252806020026020018201604052801561223a57816020015b604080516101c081018252600060e08201818152610100830182905261012083018290526101408301829052610160830182905261018083018290526101a0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161219c5790505b50905060006040518060800160405280600061ffff1681526020016000815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152509050600085610140015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122fc9190614634565b6101408701516040517f7810d12a00000000000000000000000000000000000000000000000000000000815236600482015291925060009173ffffffffffffffffffffffffffffffffffffffff90911690637810d12a90602401602060405180830381865afa158015612373573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123979190614634565b905060005b8660400151518110156127e65760046000886040015183815181106123c3576123c3614370565b6020908102919091018101518252818101929092526040908101600020815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c082015285518690839081106124a8576124a8614370565b6020026020010151600001819052506124dd876040015182815181106124d0576124d0614370565b6020026020010151612f89565b8582815181106124ef576124ef614370565b602002602001015160600190600181111561250c5761250c614b2a565b9081600181111561251f5761251f614b2a565b815250506125838760400151828151811061253c5761253c614370565b6020026020010151848960800151848151811061255b5761255b614370565b602002602001015188858151811061257557612575614370565b60200260200101518c613034565b86838151811061259557612595614370565b60200260200101516020018784815181106125b2576125b2614370565b602002602001015160c00182815250821515151581525050508481815181106125dd576125dd614370565b6020026020010151602001511561260d576001846000018181516126019190614b59565b61ffff16905250612612565b6127d4565b61267885828151811061262757612627614370565b602002602001015160000151606001518860600151838151811061264d5761264d614370565b60200260200101518960a00151848151811061266b5761266b614370565b6020026020010151611c11565b86838151811061268a5761268a614370565b60200260200101516040018784815181106126a7576126a7614370565b602090810291909101015160800191909152901515905260c08801516126ce90600161439f565b6126dc9060ff166040614b74565b6103a48860a0015183815181106126f5576126f5614370565b602002602001015151612708919061435d565b612712919061435d565b85828151811061272457612724614370565b602002602001015160a001818152505084818151811061274657612746614370565b602002602001015160a0015184602001818151612763919061435d565b905250845185908290811061277a5761277a614370565b602002602001015160800151866127919190614b8b565b95506127d4876040015182815181106127ac576127ac614370565b6020026020010151848784815181106127c7576127c7614370565b6020026020010151613153565b806127de816145fc565b91505061239c565b50825161ffff166000036127fd5750505050505050565b6155f061280b366010614b74565b5a6128169088614b8b565b612820919061435d565b61282a919061435d565b8351909550611b58906128419061ffff1687614bcd565b61284b919061435d565b945060008060005b886040015151811015612a2f5786818151811061287257612872614370565b60200260200101516020015115612a1d5761290b8a8a60400151838151811061289d5761289d614370565b60200260200101518984815181106128b7576128b7614370565b6020026020010151608001518c600001518d602001518d8c602001518e89815181106128e5576128e5614370565b602002602001015160a001518c6128fc9190614b74565b6129069190614bcd565b613258565b6060880180519295509093508391612924908390614338565b6bffffffffffffffffffffffff16905250604086018051849190612949908390614338565b6bffffffffffffffffffffffff16905250865187908290811061296e5761296e614370565b60200260200101516040015115158960400151828151811061299257612992614370565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b84866129c79190614338565b8a85815181106129d9576129d9614370565b6020026020010151608001518c8e6080015187815181106129fc576129fc614370565b6020026020010151604051612a149493929190614be1565b60405180910390a35b80612a27816145fc565b915050612853565b505050604083810151336000908152600b602052919091208054600290612a6b9084906201000090046bffffffffffffffffffffffff16614338565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260600151601260000160008282829054906101000a90046bffffffffffffffffffffffff16612ac99190614338565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611c0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610425565b3373ffffffffffffffffffffffffffffffffffffffff821603612c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610425565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015290612e72576000816060015185612d0e9190614c1e565b90506000612d1c8583614c43565b90508083604001818151612d309190614338565b6bffffffffffffffffffffffff16905250612d4b8582614c6e565b83606001818151612d5c9190614338565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b6000808a8a8a8a8a8a8a8a8a604051602001612ea299989796959493929190614c9e565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b6000612158825490565b6000612f3e83836133db565b9392505050565b6000612f3e8373ffffffffffffffffffffffffffffffffffffffff8416613405565b6000612f3e8373ffffffffffffffffffffffffffffffffffffffff84166134ff565b6000818160045b600f811015613016577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612fce57612fce614370565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461300457506000949350505050565b8061300e816145fc565b915050612f90565b5081600f1a600181111561302c5761302c614b2a565b949350505050565b60008080808560600151600181111561304f5761304f614b2a565b0361307557613061888888888861354e565b61307057600092509050613149565b6130ed565b60018560600151600181111561308d5761308d614b2a565b036130bb5760006130a0898989886136d9565b92509050806130b55750600092509050613149565b506130ed565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516040015163ffffffff16871061314257877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd56368760405161312f9190613b44565b60405180910390a2600092509050613149565b6001925090505b9550959350505050565b60008160600151600181111561316b5761316b614b2a565b036131cf57600083815260046020526040902060010180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff851602179055505050565b6001816060015160018111156131e7576131e7614b2a565b036132535760c08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b60008061326b898886868a8a60016138e7565b60008a8152600460205260408120600101549294509092506c010000000000000000000000009091046bffffffffffffffffffffffff16906132ad8385614338565b9050836bffffffffffffffffffffffff16826bffffffffffffffffffffffff1610156132e157509150600090508180613314565b806bffffffffffffffffffffffff16826bffffffffffffffffffffffff1610156133145750806133118482614c1e565b92505b60008a81526004602052604090206001018054829190600c906133569084906c0100000000000000000000000090046bffffffffffffffffffffffff16614c1e565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008c81526004602052604081206001018054859450909261339f91859116614338565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505097509795505050505050565b60008260000182815481106133f2576133f2614370565b9060005260206000200154905092915050565b600081815260018301602052604081205480156134ee576000613429600183614b8b565b855490915060009061343d90600190614b8b565b90508181146134a257600086600001828154811061345d5761345d614370565b906000526020600020015490508087600001848154811061348057613480614370565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806134b3576134b3614d33565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612158565b6000915050612158565b5092915050565b600081815260018301602052604081205461354657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612158565b506000612158565b600080848060200190518101906135659190614d62565b845160c00151815191925063ffffffff908116911610156135c257867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8866040516135b09190613b44565b60405180910390a260009150506136d0565b826101200151801561368357506020810151158015906136835750602081015161014084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa15801561365c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136809190614634565b14155b806136955750805163ffffffff168611155b156136ca57867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301866040516135b09190613b44565b60019150505b95945050505050565b6000806000848060200190518101906136f29190614dba565b905060008782600001518360200151846040015160405160200161375494939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b604051602081830303815290604052805190602001209050846101200151801561383057506080820151158015906138305750608082015161014086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015613809573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061382d9190614634565b14155b80613845575086826060015163ffffffff1610155b1561388f57877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc3018760405161387a9190613b44565b60405180910390a26000935091506138de9050565b60008181526008602052604090205460ff16156138d657877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e88760405161387a9190613b44565b600193509150505b94509492505050565b60008060008960a0015161ffff16866139009190614b74565b905083801561390e5750803a105b1561391657503a5b600085886139248b8d61435d565b61392e9085614b74565b613938919061435d565b61394a90670de0b6b3a7640000614b74565b6139549190614bcd565b905060008b6040015163ffffffff1664e8d4a510006139739190614b74565b60208d0151889063ffffffff168b61398b8f88614b74565b613995919061435d565b6139a390633b9aca00614b74565b6139ad9190614b74565b6139b79190614bcd565b6139c1919061435d565b90506b033b2e3c9fd0803ce80000006139da828461435d565b1115613a12576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909b909a5098505050505050505050565b5080546000825590600052602060002090810190610bb19190613acb565b828054828255906000526020600020908101928215613abb579160200282015b82811115613abb57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613a61565b50613ac7929150613acb565b5090565b5b80821115613ac75760008155600101613acc565b6000815180845260005b81811015613b0657602081850181015186830182015201613aea565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000612f3e6020830184613ae0565b73ffffffffffffffffffffffffffffffffffffffff81168114610bb157600080fd5b8035613b8481613b57565b919050565b60008083601f840112613b9b57600080fd5b50813567ffffffffffffffff811115613bb357600080fd5b602083019150836020828501011115613bcb57600080fd5b9250929050565b60008060008060608587031215613be857600080fd5b8435613bf381613b57565b935060208501359250604085013567ffffffffffffffff811115613c1657600080fd5b613c2287828801613b89565b95989497509550505050565b600080600060408486031215613c4357600080fd5b83359250602084013567ffffffffffffffff811115613c6157600080fd5b613c6d86828701613b89565b9497909650939450505050565b60008083601f840112613c8c57600080fd5b50813567ffffffffffffffff811115613ca457600080fd5b6020830191508360208260051b8501011115613bcb57600080fd5b60008060008060008060008060e0898b031215613cdb57600080fd5b606089018a811115613cec57600080fd5b8998503567ffffffffffffffff80821115613d0657600080fd5b613d128c838d01613b89565b909950975060808b0135915080821115613d2b57600080fd5b613d378c838d01613c7a565b909750955060a08b0135915080821115613d5057600080fd5b50613d5d8b828c01613c7a565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610220810167ffffffffffffffff81118282101715613dc957613dc9613d76565b60405290565b60405160c0810167ffffffffffffffff81118282101715613dc957613dc9613d76565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613e3957613e39613d76565b604052919050565b600067ffffffffffffffff821115613e5b57613e5b613d76565b5060051b60200190565b600082601f830112613e7657600080fd5b81356020613e8b613e8683613e41565b613df2565b82815260059290921b84018101918181019086841115613eaa57600080fd5b8286015b84811015613ece578035613ec181613b57565b8352918301918301613eae565b509695505050505050565b803560ff81168114613b8457600080fd5b600082601f830112613efb57600080fd5b813567ffffffffffffffff811115613f1557613f15613d76565b613f4660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613df2565b818152846020838601011115613f5b57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff81168114613b8457600080fd5b60008060008060008060c08789031215613fa957600080fd5b863567ffffffffffffffff80821115613fc157600080fd5b613fcd8a838b01613e65565b97506020890135915080821115613fe357600080fd5b613fef8a838b01613e65565b9650613ffd60408a01613ed9565b9550606089013591508082111561401357600080fd5b61401f8a838b01613eea565b945061402d60808a01613f78565b935060a089013591508082111561404357600080fd5b5061405089828a01613eea565b9150509295509295509295565b60006020828403121561406f57600080fd5b8135612f3e81613b57565b63ffffffff81168114610bb157600080fd5b8035613b848161407a565b62ffffff81168114610bb157600080fd5b8035613b8481614097565b61ffff81168114610bb157600080fd5b8035613b84816140b3565b6bffffffffffffffffffffffff81168114610bb157600080fd5b8035613b84816140ce565b8015158114610bb157600080fd5b8035613b84816140f3565b6000610220828403121561411f57600080fd5b614127613da5565b90506141328261408c565b81526141406020830161408c565b60208201526141516040830161408c565b6040820152614162606083016140a8565b6060820152614173608083016140c3565b608082015261418460a083016140e8565b60a082015261419560c0830161408c565b60c08201526141a660e0830161408c565b60e08201526101006141b981840161408c565b908201526101206141cb83820161408c565b90820152610140828101359082015261016080830135908201526101806141f3818401613b79565b908201526101a08281013567ffffffffffffffff81111561421357600080fd5b61421f85828601613e65565b8284015250506101c0614233818401613b79565b908201526101e0614245838201613b79565b90820152610200614257838201614101565b9082015292915050565b60008060008060008060c0878903121561427a57600080fd5b863567ffffffffffffffff8082111561429257600080fd5b61429e8a838b01613e65565b975060208901359150808211156142b457600080fd5b6142c08a838b01613e65565b96506142ce60408a01613ed9565b955060608901359150808211156142e457600080fd5b61401f8a838b0161410c565b60006020828403121561430257600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8181168382160190808211156134f8576134f8614309565b8082018082111561215857612158614309565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60ff818116838216019081111561215857612158614309565b8051613b848161407a565b8051613b8481614097565b8051613b84816140b3565b8051613b84816140ce565b8051613b8481613b57565b600082601f83011261440057600080fd5b81516020614410613e8683613e41565b82815260059290921b8401810191818101908684111561442f57600080fd5b8286015b84811015613ece57805161444681613b57565b8352918301918301614433565b8051613b84816140f3565b60006020828403121561447057600080fd5b815167ffffffffffffffff8082111561448857600080fd5b90830190610220828603121561449d57600080fd5b6144a5613da5565b6144ae836143b8565b81526144bc602084016143b8565b60208201526144cd604084016143b8565b60408201526144de606084016143c3565b60608201526144ef608084016143ce565b608082015261450060a084016143d9565b60a082015261451160c084016143b8565b60c082015261452260e084016143b8565b60e08201526101006145358185016143b8565b908201526101206145478482016143b8565b908201526101408381015190820152610160808401519082015261018061456f8185016143e4565b908201526101a0838101518381111561458757600080fd5b614593888287016143ef565b8284015250506101c091506145a98284016143e4565b828201526101e091506145bd8284016143e4565b8282015261020091506145d1828401614453565b91810191909152949350505050565b60ff81811683821602908116908181146134f8576134f8614309565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361462d5761462d614309565b5060010190565b60006020828403121561464657600080fd5b5051919050565b63ffffffff8181168382160190808211156134f8576134f8614309565b600081518084526020808501945080840160005b838110156146b057815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161467e565b509495945050505050565b602081526146d260208201835163ffffffff169052565b600060208301516146eb604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006147648185018363ffffffff169052565b840151905061012061477d8482018363ffffffff169052565b84015190506101406147968482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06147d98185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506102206101c081818601526147f961024086018461466a565b908601519092506101e06148248682018373ffffffffffffffffffffffffffffffffffffffff169052565b860151905061020061484d8682018373ffffffffffffffffffffffffffffffffffffffff169052565b90950151151593019290925250919050565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261488f8184018a61466a565b905082810360808401526148a3818961466a565b905060ff871660a084015282810360c08401526148c08187613ae0565b905067ffffffffffffffff851660e08401528281036101008401526148e58185613ae0565b9c9b505050505050505050505050565b82815260406020820152600061302c6040830184613ae0565b6000806040838503121561492157600080fd5b825161492c816140f3565b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f83011261497357600080fd5b81356020614983613e8683613e41565b82815260059290921b840181019181810190868411156149a257600080fd5b8286015b84811015613ece57803583529183019183016149a6565b600082601f8301126149ce57600080fd5b813560206149de613e8683613e41565b82815260059290921b840181019181810190868411156149fd57600080fd5b8286015b84811015613ece57803567ffffffffffffffff811115614a215760008081fd5b614a2f8986838b0101613eea565b845250918301918301614a01565b600060208284031215614a4f57600080fd5b813567ffffffffffffffff80821115614a6757600080fd5b9083019060c08286031215614a7b57600080fd5b614a83613dcf565b8235815260208301356020820152604083013582811115614aa357600080fd5b614aaf87828601614962565b604083015250606083013582811115614ac757600080fd5b614ad387828601614962565b606083015250608083013582811115614aeb57600080fd5b614af7878286016149bd565b60808301525060a083013582811115614b0f57600080fd5b614b1b878286016149bd565b60a08301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61ffff8181168382160190808211156134f8576134f8614309565b808202811582820484141761215857612158614309565b8181038181111561215857612158614309565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614bdc57614bdc614b9e565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000614c146080830184613ae0565b9695505050505050565b6bffffffffffffffffffffffff8281168282160390808211156134f8576134f8614309565b60006bffffffffffffffffffffffff80841680614c6257614c62614b9e565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114614c9657614c96614309565b505092915050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614ce58285018b61466a565b91508382036080850152614cf9828a61466a565b915060ff881660a085015283820360c0850152614d168288613ae0565b90861660e085015283810361010085015290506148e58185613ae0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060408284031215614d7457600080fd5b6040516040810181811067ffffffffffffffff82111715614d9757614d97613d76565b6040528251614da58161407a565b81526020928301519281019290925250919050565b600060a08284031215614dcc57600080fd5b60405160a0810181811067ffffffffffffffff82111715614def57614def613d76565b806040525082518152602083015160208201526040830151614e108161407a565b60408201526060830151614e238161407a565b6060820152608092830151928101929092525091905056fea164736f6c6343000813000a", } var AutomationRegistryABI = AutomationRegistryMetaData.ABI diff --git a/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go b/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go index 1d460036fa..97f0cfb113 100644 --- a/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go +++ b/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go @@ -76,7 +76,7 @@ type AutomationRegistryBase23PaymentReceipt struct { var AutomationRegistryMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicA2_3\",\"name\":\"logicA\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractIERC20Metadata\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint96\",\"name\":\"gasChargeInBillingToken\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"premiumInBillingToken\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"gasReimbursementInJuels\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"premiumInJuels\",\"type\":\"uint96\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"linkUSD\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeUSD\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"billingUSD\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.PaymentReceipt\",\"name\":\"receipt\",\"type\":\"tuple\"}],\"name\":\"UpkeepCharged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig[]\",\"name\":\"billingConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101806040523480156200001257600080fd5b506040516200651f3803806200651f83398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e05161010051610120516101405161016051615e07620007186000396000818160b30152610186015260005050600050506000505060005050600061379a015260005050600081816113710152612dc30152615e076000f3fe6080604052600436106100b15760003560e01c80638da5cb5b11610069578063b1dc65a41161004e578063b1dc65a4146102cb578063e3d0e712146102eb578063f2fde38b1461030b576100b1565b80638da5cb5b1461025a578063afcb95d714610285576100b1565b8063349e8cca1161009a578063349e8cca1461017757806379ba5097146101cb57806381ff7048146101e0576100b1565b80630870d3a1146100f8578063181f5a7714610118575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156100f1573d6000f35b3d6000fd5b005b34801561010457600080fd5b506100f6610113366004614b7b565b61032b565b34801561012457600080fd5b506101616040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e332e30000000000000000081525081565b60405161016e9190614cf7565b60405180910390f35b34801561018357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161016e565b3480156101d757600080fd5b506100f6610c0f565b3480156101ec57600080fd5b5061023760175460135463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff94851681529390921660208401529082015260600161016e565b34801561026657600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166101a6565b34801561029157600080fd5b50601354601454604080516000815260208101939093526c0100000000000000000000000090910463ffffffff169082015260600161016e565b3480156102d757600080fd5b506100f66102e6366004614d56565b610d11565b3480156102f757600080fd5b506100f6610306366004614e3b565b611051565b34801561031757600080fd5b506100f6610326366004614f08565b61108b565b61033361109f565b601f8851111561036f576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560ff166000036103ac576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b865188511415806103cb57506103c3866003614f54565b60ff16885111155b15610402576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805182511461043d576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104478282611122565b610451888861175a565b604051806101200160405280601460000160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001600063ffffffff1681526020018660a0015162ffffff16815260200186610120015161ffff1681526020018760ff168152602001601460000160169054906101000a900460ff1615158152602001601460000160179054906101000a900460ff1615158152602001866080015115158152602001866101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548162ffffff021916908362ffffff16021790555060608201518160000160136101000a81548161ffff021916908361ffff16021790555060808201518160000160156101000a81548160ff021916908360ff16021790555060a08201518160000160166101000a81548160ff02191690831515021790555060c08201518160000160176101000a81548160ff02191690831515021790555060e08201518160000160186101000a81548160ff0219169083151502179055506101008201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050506000601660010160189054906101000a900463ffffffff1690506000866101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610701573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107259190614f70565b6017549091506000906107579074010000000000000000000000000000000000000000900463ffffffff166001614f89565b9050604051806101600160405280896060015173ffffffffffffffffffffffffffffffffffffffff168152602001896000015163ffffffff168152602001896020015163ffffffff1681526020016016600001601c9054906101000a900463ffffffff1663ffffffff16815260200189610100015173ffffffffffffffffffffffffffffffffffffffff1681526020018263ffffffff1681526020018363ffffffff168152602001896040015163ffffffff16815260200189610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015163ffffffff1681526020018960e0015163ffffffff16815250601660008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160020160146101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160186101000a81548163ffffffff021916908363ffffffff160217905550905050876101600151601981905550876101800151601a81905550876101a00151601b81905550600088604051602001610a9a9190614ff7565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601754909150610aff904690309074010000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f611e19565b6013556000610b0e6009611ec3565b90505b8015610b4b57610b38610b30610b2860018461517d565b600990611ed3565b600990611ee6565b5080610b4381615190565b915050610b11565b5060005b896101c0015151811015610ba257610b8f8a6101c001518281518110610b7757610b776151c5565b60200260200101516009611f0890919063ffffffff16565b5080610b9a816151f4565b915050610b4f565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0584601354601660010160149054906101000a900463ffffffff168f8f8f878f8f604051610bf99998979695949392919061522c565b60405180910390a1505050505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005a90506000610d238660406152c2565b610d2f896101446152d9565b610d3991906152d9565b9050368114610d74576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051610120810182526014546bffffffffffffffffffffffff8116825263ffffffff6c01000000000000000000000000820416602083015262ffffff7001000000000000000000000000000000008204169282019290925261ffff730100000000000000000000000000000000000000830416606082015260ff75010000000000000000000000000000000000000000008304811660808301527601000000000000000000000000000000000000000000008304811615801560a08401527701000000000000000000000000000000000000000000000084048216151560c0840152780100000000000000000000000000000000000000000000000090930416151560e082015260155473ffffffffffffffffffffffffffffffffffffffff1661010082015290610ed3576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff16610f1c576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6013548b3514610f58576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080810151610f689060016152ec565b60ff1687141580610f795750868514155b15610fb0576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610fc08b8b8b8b8b8b8b8b611f2a565b6000610fcc8b8b612193565b905060208c0135600881901c63ffffffff16610fe984848861224c565b836020015163ffffffff168163ffffffff16111561104157601480547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790555b5050505050505050505050505050565b60008060008580602001905181019061106a9190615472565b925092509250611080898989868989888861032b565b505050505050505050565b61109361109f565b61109c81612e39565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c8c565b565b60005b6024548110156111e0576022600060248381548110611146576111466151c5565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffff00000000000000000000000000000000000000000000000000000000168155600181019190915560020180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169055806111d8816151f4565b915050611125565b506111ed602460006145cf565b60255460ff1660005b8351811015611754576000848281518110611213576112136151c5565b602002602001015190506000848381518110611231576112316151c5565b602002602001015190508173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611286573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112aa919061561d565b60ff16816060015160ff161415806113385750806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561130c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611330919061561d565b60ff16600814155b1561136f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480156113db575060018460018111156113d9576113d961563a565b145b15611412576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216158061144d5750604081015173ffffffffffffffffffffffffffffffffffffffff16155b15611484576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff828116600090815260226020526040902054670100000000000000900416156114ee576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024805460018181019092557f7cd332d19b93bcabe3cce7ca0c18a052f57e5fd03b4758a09f30f5ddc4b22ec401805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216821790925560008181526022602090815260409182902086518154928801518489015160608a015160ff167b01000000000000000000000000000000000000000000000000000000027fffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff9190981667010000000000000002167fffffffff000000000000000000000000000000000000000000ffffffffffffff62ffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000090951663ffffffff9093169290921793909317929092169190911793909317835560808501519383019390935560a0840151600290920180546bffffffffffffffffffffffff9093167fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009093169290921790915590517fca93cbe727c73163ec538f71be6c0a64877d7f1f6dd35d5ca7cbaef3a3e34ba390611737908490600060c08201905063ffffffff835116825262ffffff602084015116602083015273ffffffffffffffffffffffffffffffffffffffff604084015116604083015260ff6060840151166060830152608083015160808301526bffffffffffffffffffffffff60a08401511660a083015292915050565b60405180910390a25050808061174c906151f4565b9150506111f6565b50505050565b600e546014546bffffffffffffffffffffffff1660005b600e548110156117cd576117ba600e8281548110611791576117916151c5565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168385612f2e565b50806117c5816151f4565b915050611771565b5060255460009060ff16815b600e5481101561193e57600e81815481106117f6576117f66151c5565b6000918252602082200154600d805473ffffffffffffffffffffffffffffffffffffffff9092169550600c929184908110611833576118336151c5565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff9081168452838201949094526040928301822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559286168152600b909252902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905560018260018111156118d5576118d561563a565b14801561191a575073ffffffffffffffffffffffffffffffffffffffff83166000908152600b60205260409020546201000090046bffffffffffffffffffffffff1615155b1561192c5761192a600f84611f08565b505b80611936816151f4565b9150506117d9565b5061194b600d60006145cf565b611957600e60006145cf565b6040805160808101825260008082526020820181905291810182905260608101829052905b8751811015611de757600c600089838151811061199b5761199b6151c5565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611a06576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16888281518110611a3057611a306151c5565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611a85576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008a8481518110611ab657611ab66151c5565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558651879082908110611b5e57611b5e6151c5565b60200260200101519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611bce576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e01000000000000000000000000000090049092166060830152909250611c89576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180835260ff80831660208086019182526014546bffffffffffffffffffffffff9081166060880190815273ffffffffffffffffffffffffffffffffffffffff8a166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090951694909417179190911692909217919091179055836001811115611dc357611dc361563a565b03611dd557611dd3600f85611ee6565b505b80611ddf816151f4565b91505061197c565b508651611dfb90600d9060208a01906145ed565b508551611e0f90600e9060208901906145ed565b5050505050505050565b6000808a8a8a8a8a8a8a8a8a604051602001611e3d99989796959493929190615669565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b6000611ecd825490565b92915050565b6000611edf8383613136565b9392505050565b6000611edf8373ffffffffffffffffffffffffffffffffffffffff8416613160565b6000611edf8373ffffffffffffffffffffffffffffffffffffffff841661325a565b60008787604051611f3c9291906156fe565b604051908190038120611f53918b9060200161570e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b8881101561212a57600185878360208110611fbf57611fbf6151c5565b611fcc91901a601b6152ec565b8c8c85818110611fde57611fde6151c5565b905060200201358b8b86818110611ff757611ff76151c5565b9050602002013560405160008152602001604052604051612034949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612056573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612104576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b840193508080612122906151f4565b915050611fa2565b50827e01010101010101010101010101010101010101010101010101010101010101841614612185576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b6121cc6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b60006121da838501856157ff565b60408101515160608201515191925090811415806121fd57508082608001515114155b8061220d5750808260a001515114155b15612244576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b600082604001515167ffffffffffffffff81111561226c5761226c614684565b60405190808252806020026020018201604052801561233857816020015b6040805161020081018252600060e08201818152610100830182905261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c083018290526101e0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161228a5790505b50905060006040518060800160405280600061ffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160008152509050600085610100015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123fa9190614f70565b9050600086610100015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa15801561244e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124729190614f70565b905060005b86604001515181101561290257600460008860400151838151811061249e5761249e6151c5565b6020908102919091018101518252818101929092526040908101600020815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e08201526002909101549091169181019190915285518690839081106125c1576125c16151c5565b6020026020010151600001819052506125f6876040015182815181106125e9576125e96151c5565b60200260200101516132a9565b858281518110612608576126086151c5565b60200260200101516060019060018111156126255761262561563a565b908160018111156126385761263861563a565b8152505061269c87604001518281518110612655576126556151c5565b60200260200101518489608001518481518110612674576126746151c5565b602002602001015188858151811061268e5761268e6151c5565b60200260200101518c613354565b8683815181106126ae576126ae6151c5565b60200260200101516020018784815181106126cb576126cb6151c5565b602002602001015160c00182815250821515151581525050508481815181106126f6576126f66151c5565b602002602001015160200151156127265760018460000181815161271a91906158ec565b61ffff1690525061272b565b6128f0565b612791858281518110612740576127406151c5565b6020026020010151600001516080015188606001518381518110612766576127666151c5565b60200260200101518960a001518481518110612784576127846151c5565b6020026020010151613473565b8683815181106127a3576127a36151c5565b60200260200101516040018784815181106127c0576127c06151c5565b60200260200101516080018281525082151515158152505050876080015160016127ea91906152ec565b6127f89060ff1660406152c2565b6103a48860a001518381518110612811576128116151c5565b60200260200101515161282491906152d9565b61282e91906152d9565b858281518110612840576128406151c5565b602002602001015160a0018181525050848181518110612862576128626151c5565b602002602001015160a001518460600181815161287f91906152d9565b9052508451859082908110612896576128966151c5565b602002602001015160800151866128ad919061517d565b95506128f0876040015182815181106128c8576128c86151c5565b6020026020010151848784815181106128e3576128e36151c5565b602002602001015161368e565b806128fa816151f4565b915050612477565b50825161ffff166000036129195750505050505050565b61c8006129273660106152c2565b5a612932908861517d565b61293c91906152d9565b61294691906152d9565b83519095506137789061295d9061ffff1687615936565b61296791906152d9565b604080516080810182526000808252602082018190529181018290526060810182905291965061299689613793565b905060005b886040015151811015612cd2578681815181106129ba576129ba6151c5565b60200260200101516020015115612cc057801580612a525750866129df60018361517d565b815181106129ef576129ef6151c5565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff16878281518110612a2857612a286151c5565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff1614155b15612a8657612a838a888381518110612a6d57612a6d6151c5565b602002602001015160000151610100015161387d565b92505b6000612ba48b6040518061012001604052808b8681518110612aaa57612aaa6151c5565b60200260200101516080015181526020018c81526020018a606001518c8781518110612ad857612ad86151c5565b602002602001015160a001518a612aef91906152c2565b612af99190615936565b81526020018d6000015181526020018d6020015181526020018681526020018b8681518110612b2a57612b2a6151c5565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff168152602001878152602001600115158152508c604001518581518110612b7957612b796151c5565b60200260200101518b8681518110612b9357612b936151c5565b6020026020010151600001516139f9565b9050806060015187604001818151612bbc919061594a565b6bffffffffffffffffffffffff169052506040810151602088018051612be390839061594a565b6bffffffffffffffffffffffff169052508751889083908110612c0857612c086151c5565b60200260200101516040015115158a604001518381518110612c2c57612c2c6151c5565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b83602001518460000151612c69919061594a565b8b8681518110612c7b57612c7b6151c5565b6020026020010151608001518d8f608001518881518110612c9e57612c9e6151c5565b6020026020010151604051612cb6949392919061596f565b60405180910390a3505b80612cca816151f4565b91505061299b565b505050602083810151336000908152600b90925260409091208054600290612d0f9084906201000090046bffffffffffffffffffffffff1661594a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260400151601460000160008282829054906101000a90046bffffffffffffffffffffffff16612d6d919061594a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555082604001518360200151612daf919061594a565b6bffffffffffffffffffffffff16602160007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612e2b91906152d9565b909155505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603612eb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c8c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e010000000000000000000000000000900490911660608201529061312a576000816060015185612fc691906159ac565b90506000612fd485836159d1565b90508083604001818151612fe8919061594a565b6bffffffffffffffffffffffff1690525061300385826159fc565b83606001818151613014919061594a565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b600082600001828154811061314d5761314d6151c5565b9060005260206000200154905092915050565b6000818152600183016020526040812054801561324957600061318460018361517d565b85549091506000906131989060019061517d565b90508181146131fd5760008660000182815481106131b8576131b86151c5565b90600052602060002001549050808760000184815481106131db576131db6151c5565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061320e5761320e615a2c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611ecd565b6000915050611ecd565b5092915050565b60008181526001830160205260408120546132a157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611ecd565b506000611ecd565b6000818160045b600f811015613336577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106132ee576132ee6151c5565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461332457506000949350505050565b8061332e816151f4565b9150506132b0565b5081600f1a600181111561334c5761334c61563a565b949350505050565b60008080808560600151600181111561336f5761336f61563a565b03613395576133818888888888613e68565b61339057600092509050613469565b61340d565b6001856060015160018111156133ad576133ad61563a565b036133db5760006133c089898988613ff2565b92509050806133d55750600092509050613469565b5061340d565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516060015163ffffffff16871061346257877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd56368760405161344f9190614cf7565b60405180910390a2600092509050613469565b6001925090505b9550959350505050565b601454600090819077010000000000000000000000000000000000000000000000900460ff16156134d0576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000001790556040517f4585e33b0000000000000000000000000000000000000000000000000000000090613545908590602401614cf7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906136189087908790600401615a5b565b60408051808303816000875af1158015613636573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061365a9190615a74565b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b6000816060015160018111156136a6576136a661563a565b0361370a57600083815260046020526040902060010180547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff851602179055505050565b6001816060015160018111156137225761372261563a565b0361378e5760c08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613803573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138279190615abc565b5093505092505060008213158061383d57508042105b8061386d57506000846040015162ffffff1611801561386d5750613861814261517d565b846040015162ffffff16105b15613253575050601b5492915050565b60408051608081018252600080825260208083018281528385018381526060850184905273ffffffffffffffffffffffffffffffffffffffff878116855260229093528584208054640100000000810462ffffff1690925263ffffffff82169092527b01000000000000000000000000000000000000000000000000000000810460ff16855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495919484936701000000000000009092049091169163feaf968c9160048083019260a09291908290030181865afa15801561396a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061398e9190615abc565b509350509250506000821315806139a457508042105b806139d457506000866040015162ffffff161180156139d457506139c8814261517d565b866040015162ffffff16105b156139e857600183015460608501526139f0565b606084018290525b50505092915050565b604080516101008101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201529082015115613a8f5760008381526023602090815260409182902082518084018452905463ffffffff811680835262ffffff640100000000909204821692840192835260e089018051909401529051915191169101525b6000613a9b86866141ff565b60c0840151602082015182519293509091600091613ab89161594a565b60e08801515190915060ff16600060128210613ad5576001613aeb565b613ae082601261517d565b613aeb90600a615c2c565b9050600060128311613afe576001613b14565b613b0960128461517d565b613b1490600a615c2c565b905085600001516bffffffffffffffffffffffff16856bffffffffffffffffffffffff161015613bbc57849350613b90818b60800151613b5491906152c2565b838c60e0015160600151886bffffffffffffffffffffffff16613b7791906152c2565b613b8191906152c2565b613b8b9190615936565b61452d565b6bffffffffffffffffffffffff9081166040880152600060608801819052602088015285168652613ce2565b836bffffffffffffffffffffffff16856bffffffffffffffffffffffff161015613ce257849350613c4a86604001516bffffffffffffffffffffffff16828c60800151613c0991906152c2565b848d60e0015160600151896bffffffffffffffffffffffff16613c2c91906152c2565b613c3691906152c2565b613c409190615936565b613b8b919061517d565b6bffffffffffffffffffffffff1660608088019190915260e08b01510151613cce90613c779084906152c2565b6001848d60e0015160600151613c8d91906152c2565b613c97919061517d565b838d608001518a606001516bffffffffffffffffffffffff16613cba91906152c2565b613cc491906152c2565b613b8191906152d9565b6bffffffffffffffffffffffff1660208701525b60008981526004602052604090206001018054859190601090613d2890849070010000000000000000000000000000000090046bffffffffffffffffffffffff166159ac565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008b81526004602052604081206001018054928816935091613d839084906fffffffffffffffffffffffffffffffff16615c38565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550836bffffffffffffffffffffffff16602160008c60c0015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254613e1a919061517d565b92505081905550887f801ba6ed51146ffe3e99d1dbd9dd0f4de6292e78a9a34c39c0183de17b3f40fc87604051613e519190615c61565b60405180910390a250939998505050505050505050565b60008084806020019051810190613e7f9190615d21565b845160e00151815191925063ffffffff90811691161015613edc57867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e886604051613eca9190614cf7565b60405180910390a26000915050613fe9565b8260e001518015613f9c5750602081015115801590613f9c5750602081015161010084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015613f75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f999190614f70565b14155b80613fae5750805163ffffffff168611155b15613fe357867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc30186604051613eca9190614cf7565b60019150505b95945050505050565b60008060008480602001905181019061400b9190615d79565b905060008782600001518360200151846040015160405160200161406d94939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b6040516020818303038152906040528051906020012090508460e00151801561414857506080820151158015906141485750608082015161010086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015614121573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141459190614f70565b14155b8061415d575086826060015163ffffffff1610155b156141a757877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301876040516141929190614cf7565b60405180910390a26000935091506141f69050565b60008181526008602052604090205460ff16156141ee57877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8876040516141929190614cf7565b600193509150505b94509492505050565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915260008260e001516000015160ff1690506000846060015161ffff16846060015161426a91906152c2565b9050836101000151801561427d5750803a105b1561428557503a5b6000601283116142965760016142ac565b6142a160128461517d565b6142ac90600a615c2c565b90506000601284106142bf5760016142d5565b6142ca84601261517d565b6142d590600a615c2c565b905060008660a001518760400151886020015189600001516142f791906152d9565b61430190876152c2565b61430b91906152d9565b61431591906152c2565b9050614358828860e001516060015161432e91906152c2565b6001848a60e001516060015161434491906152c2565b61434e919061517d565b613cc486856152c2565b6bffffffffffffffffffffffff168652608087015161437b90613b8b9083615936565b6bffffffffffffffffffffffff1660408088019190915260e088015101516000906143b49062ffffff16683635c9adc5dea000006152c2565b9050600081633b9aca008a60a001518b60e001516020015163ffffffff168c604001518d600001518b6143e791906152c2565b6143f191906152d9565b6143fb91906152c2565b61440591906152c2565b61440f9190615936565b61441991906152d9565b905061445c848a60e001516060015161443291906152c2565b6001868c60e001516060015161444891906152c2565b614452919061517d565b613cc488856152c2565b6bffffffffffffffffffffffff166020890152608089015161448290613b8b9083615936565b6bffffffffffffffffffffffff16606089015260c089015173ffffffffffffffffffffffffffffffffffffffff166080808a01919091528901516144c59061452d565b6bffffffffffffffffffffffff1660a0808a01919091528901516144e89061452d565b6bffffffffffffffffffffffff1660c089015260e08901516060015161450d9061452d565b6bffffffffffffffffffffffff1660e08901525050505050505092915050565b60006bffffffffffffffffffffffff8211156145cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610c8c565b5090565b508054600082559060005260206000209081019061109c919061466f565b828054828255906000526020600020908101928215614667579160200282015b8281111561466757825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061460d565b506145cb9291505b5b808211156145cb5760008155600101614670565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610200810167ffffffffffffffff811182821017156146d7576146d7614684565b60405290565b60405160c0810167ffffffffffffffff811182821017156146d7576146d7614684565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561474757614747614684565b604052919050565b600067ffffffffffffffff82111561476957614769614684565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461109c57600080fd5b80356147a081614773565b919050565b600082601f8301126147b657600080fd5b813560206147cb6147c68361474f565b614700565b82815260059290921b840181019181810190868411156147ea57600080fd5b8286015b8481101561480e57803561480181614773565b83529183019183016147ee565b509695505050505050565b60ff8116811461109c57600080fd5b80356147a081614819565b63ffffffff8116811461109c57600080fd5b80356147a081614833565b801515811461109c57600080fd5b80356147a081614850565b62ffffff8116811461109c57600080fd5b80356147a081614869565b61ffff8116811461109c57600080fd5b80356147a081614885565b600061020082840312156148b357600080fd5b6148bb6146b3565b90506148c682614845565b81526148d460208301614845565b60208201526148e560408301614845565b60408201526148f660608301614795565b60608201526149076080830161485e565b608082015261491860a0830161487a565b60a082015261492960c08301614845565b60c082015261493a60e08301614845565b60e082015261010061494d818401614795565b9082015261012061495f838201614895565b90820152610140614971838201614795565b90820152610160828101359082015261018080830135908201526101a080830135908201526101c08083013567ffffffffffffffff8111156149b257600080fd5b6149be858286016147a5565b8284015250506101e06149d2818401614795565b9082015292915050565b803567ffffffffffffffff811681146147a057600080fd5b600082601f830112614a0557600080fd5b813567ffffffffffffffff811115614a1f57614a1f614684565b614a5060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614700565b818152846020838601011115614a6557600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461109c57600080fd5b600082601f830112614aad57600080fd5b81356020614abd6147c68361474f565b82815260c09283028501820192828201919087851115614adc57600080fd5b8387015b85811015614b6e5781818a031215614af85760008081fd5b614b006146dd565b8135614b0b81614833565b815281860135614b1a81614869565b81870152604082810135614b2d81614773565b90820152606082810135614b4081614819565b908201526080828101359082015260a080830135614b5d81614a82565b908201528452928401928101614ae0565b5090979650505050505050565b600080600080600080600080610100898b031215614b9857600080fd5b883567ffffffffffffffff80821115614bb057600080fd5b614bbc8c838d016147a5565b995060208b0135915080821115614bd257600080fd5b614bde8c838d016147a5565b9850614bec60408c01614828565b975060608b0135915080821115614c0257600080fd5b614c0e8c838d016148a0565b9650614c1c60808c016149dc565b955060a08b0135915080821115614c3257600080fd5b614c3e8c838d016149f4565b945060c08b0135915080821115614c5457600080fd5b614c608c838d016147a5565b935060e08b0135915080821115614c7657600080fd5b50614c838b828c01614a9c565b9150509295985092959890939650565b6000815180845260005b81811015614cb957602081850181015186830182015201614c9d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611edf6020830184614c93565b60008083601f840112614d1c57600080fd5b50813567ffffffffffffffff811115614d3457600080fd5b6020830191508360208260051b8501011115614d4f57600080fd5b9250929050565b60008060008060008060008060e0898b031215614d7257600080fd5b606089018a811115614d8357600080fd5b8998503567ffffffffffffffff80821115614d9d57600080fd5b818b0191508b601f830112614db157600080fd5b813581811115614dc057600080fd5b8c6020828501011115614dd257600080fd5b6020830199508098505060808b0135915080821115614df057600080fd5b614dfc8c838d01614d0a565b909750955060a08b0135915080821115614e1557600080fd5b50614e228b828c01614d0a565b999c989b50969995989497949560c00135949350505050565b60008060008060008060c08789031215614e5457600080fd5b863567ffffffffffffffff80821115614e6c57600080fd5b614e788a838b016147a5565b97506020890135915080821115614e8e57600080fd5b614e9a8a838b016147a5565b9650614ea860408a01614828565b95506060890135915080821115614ebe57600080fd5b614eca8a838b016149f4565b9450614ed860808a016149dc565b935060a0890135915080821115614eee57600080fd5b50614efb89828a016149f4565b9150509295509295509295565b600060208284031215614f1a57600080fd5b8135611edf81614773565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff818116838216029081169081811461325357613253614f25565b600060208284031215614f8257600080fd5b5051919050565b63ffffffff81811683821601908082111561325357613253614f25565b600081518084526020808501945080840160005b83811015614fec57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614fba565b509495945050505050565b6020815261500e60208201835163ffffffff169052565b60006020830151615027604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015180151560a08401525060a083015162ffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006150a68185018363ffffffff169052565b84015190506101206150cf8482018373ffffffffffffffffffffffffffffffffffffffff169052565b84015190506101406150e68482018361ffff169052565b840151905061016061510f8482018373ffffffffffffffffffffffffffffffffffffffff169052565b840151610180848101919091528401516101a0808501919091528401516101c0808501919091528401516102006101e080860182905291925090615157610220860184614fa6565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b81810381811115611ecd57611ecd614f25565b60008161519f5761519f614f25565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361522557615225614f25565b5060010190565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261525c8184018a614fa6565b905082810360808401526152708189614fa6565b905060ff871660a084015282810360c084015261528d8187614c93565b905067ffffffffffffffff851660e08401528281036101008401526152b28185614c93565b9c9b505050505050505050505050565b8082028115828204841417611ecd57611ecd614f25565b80820180821115611ecd57611ecd614f25565b60ff8181168382160190811115611ecd57611ecd614f25565b80516147a081614833565b80516147a081614773565b80516147a081614850565b80516147a081614869565b80516147a081614885565b600082601f83011261534d57600080fd5b8151602061535d6147c68361474f565b82815260059290921b8401810191818101908684111561537c57600080fd5b8286015b8481101561480e57805161539381614773565b8352918301918301615380565b600082601f8301126153b157600080fd5b815160206153c16147c68361474f565b82815260c092830285018201928282019190878511156153e057600080fd5b8387015b85811015614b6e5781818a0312156153fc5760008081fd5b6154046146dd565b815161540f81614833565b81528186015161541e81614869565b8187015260408281015161543181614773565b9082015260608281015161544481614819565b908201526080828101519082015260a08083015161546181614a82565b9082015284529284019281016153e4565b60008060006060848603121561548757600080fd5b835167ffffffffffffffff8082111561549f57600080fd5b9085019061020082880312156154b457600080fd5b6154bc6146b3565b6154c583615305565b81526154d360208401615305565b60208201526154e460408401615305565b60408201526154f560608401615310565b60608201526155066080840161531b565b608082015261551760a08401615326565b60a082015261552860c08401615305565b60c082015261553960e08401615305565b60e082015261010061554c818501615310565b9082015261012061555e848201615331565b90820152610140615570848201615310565b90820152610160838101519082015261018080840151908201526101a080840151908201526101c080840151838111156155a957600080fd5b6155b58a82870161533c565b8284015250506101e06155c9818501615310565b9082015260208701519095509150808211156155e457600080fd5b6155f08783880161533c565b9350604086015191508082111561560657600080fd5b50615613868287016153a0565b9150509250925092565b60006020828403121561562f57600080fd5b8151611edf81614819565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526156b08285018b614fa6565b915083820360808501526156c4828a614fa6565b915060ff881660a085015283820360c08501526156e18288614c93565b90861660e085015283810361010085015290506152b28185614c93565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f83011261573557600080fd5b813560206157456147c68361474f565b82815260059290921b8401810191818101908684111561576457600080fd5b8286015b8481101561480e5780358352918301918301615768565b600082601f83011261579057600080fd5b813560206157a06147c68361474f565b82815260059290921b840181019181810190868411156157bf57600080fd5b8286015b8481101561480e57803567ffffffffffffffff8111156157e35760008081fd5b6157f18986838b01016149f4565b8452509183019183016157c3565b60006020828403121561581157600080fd5b813567ffffffffffffffff8082111561582957600080fd5b9083019060c0828603121561583d57600080fd5b6158456146dd565b823581526020830135602082015260408301358281111561586557600080fd5b61587187828601615724565b60408301525060608301358281111561588957600080fd5b61589587828601615724565b6060830152506080830135828111156158ad57600080fd5b6158b98782860161577f565b60808301525060a0830135828111156158d157600080fd5b6158dd8782860161577f565b60a08301525095945050505050565b61ffff81811683821601908082111561325357613253614f25565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261594557615945615907565b500490565b6bffffffffffffffffffffffff81811683821601908082111561325357613253614f25565b6bffffffffffffffffffffffff851681528360208201528260408201526080606082015260006159a26080830184614c93565b9695505050505050565b6bffffffffffffffffffffffff82811682821603908082111561325357613253614f25565b60006bffffffffffffffffffffffff808416806159f0576159f0615907565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114615a2457615a24614f25565b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b82815260406020820152600061334c6040830184614c93565b60008060408385031215615a8757600080fd5b8251615a9281614850565b6020939093015192949293505050565b805169ffffffffffffffffffff811681146147a057600080fd5b600080600080600060a08688031215615ad457600080fd5b615add86615aa2565b9450602086015193506040860151925060608601519150615b0060808701615aa2565b90509295509295909350565b600181815b80851115615b6557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615b4b57615b4b614f25565b80851615615b5857918102915b93841c9390800290615b11565b509250929050565b600082615b7c57506001611ecd565b81615b8957506000611ecd565b8160018114615b9f5760028114615ba957615bc5565b6001915050611ecd565b60ff841115615bba57615bba614f25565b50506001821b611ecd565b5060208310610133831016604e8410600b8410161715615be8575081810a611ecd565b615bf28383615b0c565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615c2457615c24614f25565b029392505050565b6000611edf8383615b6d565b6fffffffffffffffffffffffffffffffff81811683821601908082111561325357613253614f25565b6000610100820190506bffffffffffffffffffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401525073ffffffffffffffffffffffffffffffffffffffff608084015116608083015260a0830151615ce160a08401826bffffffffffffffffffffffff169052565b5060c0830151615d0160c08401826bffffffffffffffffffffffff169052565b5060e083015161325360e08401826bffffffffffffffffffffffff169052565b600060408284031215615d3357600080fd5b6040516040810181811067ffffffffffffffff82111715615d5657615d56614684565b6040528251615d6481614833565b81526020928301519281019290925250919050565b600060a08284031215615d8b57600080fd5b60405160a0810181811067ffffffffffffffff82111715615dae57615dae614684565b806040525082518152602083015160208201526040830151615dcf81614833565b60408201526060830151615de281614833565b6060820152608092830151928101929092525091905056fea164736f6c6343000813000a", + Bin: "0x6101806040523480156200001257600080fd5b50604051620065423803806200654283398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e05161010051610120516101405161016051615e2a620007186000396000818160b3015261018601526000505060005050600050506000505060006137bd015260005050600081816113710152612de60152615e2a6000f3fe6080604052600436106100b15760003560e01c80638da5cb5b11610069578063b1dc65a41161004e578063b1dc65a4146102cb578063e3d0e712146102eb578063f2fde38b1461030b576100b1565b80638da5cb5b1461025a578063afcb95d714610285576100b1565b8063349e8cca1161009a578063349e8cca1461017757806379ba5097146101cb57806381ff7048146101e0576100b1565b80630870d3a1146100f8578063181f5a7714610118575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156100f1573d6000f35b3d6000fd5b005b34801561010457600080fd5b506100f6610113366004614b9e565b61032b565b34801561012457600080fd5b506101616040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e332e30000000000000000081525081565b60405161016e9190614d1a565b60405180910390f35b34801561018357600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161016e565b3480156101d757600080fd5b506100f6610c0f565b3480156101ec57600080fd5b5061023760175460135463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff94851681529390921660208401529082015260600161016e565b34801561026657600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166101a6565b34801561029157600080fd5b50601354601454604080516000815260208101939093526c0100000000000000000000000090910463ffffffff169082015260600161016e565b3480156102d757600080fd5b506100f66102e6366004614d79565b610d11565b3480156102f757600080fd5b506100f6610306366004614e5e565b611051565b34801561031757600080fd5b506100f6610326366004614f2b565b61108b565b61033361109f565b601f8851111561036f576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560ff166000036103ac576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b865188511415806103cb57506103c3866003614f77565b60ff16885111155b15610402576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805182511461043d576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104478282611122565b610451888861175a565b604051806101200160405280601460000160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001600063ffffffff1681526020018660a0015162ffffff16815260200186610120015161ffff1681526020018760ff168152602001601460000160169054906101000a900460ff1615158152602001601460000160179054906101000a900460ff1615158152602001866080015115158152602001866101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548162ffffff021916908362ffffff16021790555060608201518160000160136101000a81548161ffff021916908361ffff16021790555060808201518160000160156101000a81548160ff021916908360ff16021790555060a08201518160000160166101000a81548160ff02191690831515021790555060c08201518160000160176101000a81548160ff02191690831515021790555060e08201518160000160186101000a81548160ff0219169083151502179055506101008201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050506000601660010160189054906101000a900463ffffffff1690506000866101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610701573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107259190614f93565b6017549091506000906107579074010000000000000000000000000000000000000000900463ffffffff166001614fac565b9050604051806101600160405280896060015173ffffffffffffffffffffffffffffffffffffffff168152602001896000015163ffffffff168152602001896020015163ffffffff1681526020016016600001601c9054906101000a900463ffffffff1663ffffffff16815260200189610100015173ffffffffffffffffffffffffffffffffffffffff1681526020018263ffffffff1681526020018363ffffffff168152602001896040015163ffffffff16815260200189610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015163ffffffff1681526020018960e0015163ffffffff16815250601660008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160020160146101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160186101000a81548163ffffffff021916908363ffffffff160217905550905050876101600151601981905550876101800151601a81905550876101a00151601b81905550600088604051602001610a9a919061501a565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601754909150610aff904690309074010000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f611e19565b6013556000610b0e6009611ec3565b90505b8015610b4b57610b38610b30610b286001846151a0565b600990611ed3565b600990611ee6565b5080610b43816151b3565b915050610b11565b5060005b896101c0015151811015610ba257610b8f8a6101c001518281518110610b7757610b776151e8565b60200260200101516009611f0890919063ffffffff16565b5080610b9a81615217565b915050610b4f565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0584601354601660010160149054906101000a900463ffffffff168f8f8f878f8f604051610bf99998979695949392919061524f565b60405180910390a1505050505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005a90506000610d238660406152e5565b610d2f896101446152fc565b610d3991906152fc565b9050368114610d74576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051610120810182526014546bffffffffffffffffffffffff8116825263ffffffff6c01000000000000000000000000820416602083015262ffffff7001000000000000000000000000000000008204169282019290925261ffff730100000000000000000000000000000000000000830416606082015260ff75010000000000000000000000000000000000000000008304811660808301527601000000000000000000000000000000000000000000008304811615801560a08401527701000000000000000000000000000000000000000000000084048216151560c0840152780100000000000000000000000000000000000000000000000090930416151560e082015260155473ffffffffffffffffffffffffffffffffffffffff1661010082015290610ed3576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff16610f1c576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6013548b3514610f58576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080810151610f6890600161530f565b60ff1687141580610f795750868514155b15610fb0576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610fc08b8b8b8b8b8b8b8b611f2a565b6000610fcc8b8b612193565b905060208c0135600881901c63ffffffff16610fe984848861224c565b836020015163ffffffff168163ffffffff16111561104157601480547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790555b5050505050505050505050505050565b60008060008580602001905181019061106a9190615495565b925092509250611080898989868989888861032b565b505050505050505050565b61109361109f565b61109c81612e5c565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c8c565b565b60005b6024548110156111e0576022600060248381548110611146576111466151e8565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffff00000000000000000000000000000000000000000000000000000000168155600181019190915560020180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169055806111d881615217565b915050611125565b506111ed602460006145f2565b60255460ff1660005b8351811015611754576000848281518110611213576112136151e8565b602002602001015190506000848381518110611231576112316151e8565b602002602001015190508173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611286573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112aa9190615640565b60ff16816060015160ff161415806113385750806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561130c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113309190615640565b60ff16600814155b1561136f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480156113db575060018460018111156113d9576113d961565d565b145b15611412576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216158061144d5750604081015173ffffffffffffffffffffffffffffffffffffffff16155b15611484576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff828116600090815260226020526040902054670100000000000000900416156114ee576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024805460018181019092557f7cd332d19b93bcabe3cce7ca0c18a052f57e5fd03b4758a09f30f5ddc4b22ec401805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216821790925560008181526022602090815260409182902086518154928801518489015160608a015160ff167b01000000000000000000000000000000000000000000000000000000027fffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff9190981667010000000000000002167fffffffff000000000000000000000000000000000000000000ffffffffffffff62ffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000090951663ffffffff9093169290921793909317929092169190911793909317835560808501519383019390935560a0840151600290920180546bffffffffffffffffffffffff9093167fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009093169290921790915590517fca93cbe727c73163ec538f71be6c0a64877d7f1f6dd35d5ca7cbaef3a3e34ba390611737908490600060c08201905063ffffffff835116825262ffffff602084015116602083015273ffffffffffffffffffffffffffffffffffffffff604084015116604083015260ff6060840151166060830152608083015160808301526bffffffffffffffffffffffff60a08401511660a083015292915050565b60405180910390a25050808061174c90615217565b9150506111f6565b50505050565b600e546014546bffffffffffffffffffffffff1660005b600e548110156117cd576117ba600e8281548110611791576117916151e8565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168385612f51565b50806117c581615217565b915050611771565b5060255460009060ff16815b600e5481101561193e57600e81815481106117f6576117f66151e8565b6000918252602082200154600d805473ffffffffffffffffffffffffffffffffffffffff9092169550600c929184908110611833576118336151e8565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff9081168452838201949094526040928301822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559286168152600b909252902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905560018260018111156118d5576118d561565d565b14801561191a575073ffffffffffffffffffffffffffffffffffffffff83166000908152600b60205260409020546201000090046bffffffffffffffffffffffff1615155b1561192c5761192a600f84611f08565b505b8061193681615217565b9150506117d9565b5061194b600d60006145f2565b611957600e60006145f2565b6040805160808101825260008082526020820181905291810182905260608101829052905b8751811015611de757600c600089838151811061199b5761199b6151e8565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611a06576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16888281518110611a3057611a306151e8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611a85576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008a8481518110611ab657611ab66151e8565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558651879082908110611b5e57611b5e6151e8565b60200260200101519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611bce576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e01000000000000000000000000000090049092166060830152909250611c89576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180835260ff80831660208086019182526014546bffffffffffffffffffffffff9081166060880190815273ffffffffffffffffffffffffffffffffffffffff8a166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090951694909417179190911692909217919091179055836001811115611dc357611dc361565d565b03611dd557611dd3600f85611ee6565b505b80611ddf81615217565b91505061197c565b508651611dfb90600d9060208a0190614610565b508551611e0f90600e906020890190614610565b5050505050505050565b6000808a8a8a8a8a8a8a8a8a604051602001611e3d9998979695949392919061568c565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b6000611ecd825490565b92915050565b6000611edf8383613159565b9392505050565b6000611edf8373ffffffffffffffffffffffffffffffffffffffff8416613183565b6000611edf8373ffffffffffffffffffffffffffffffffffffffff841661327d565b60008787604051611f3c929190615721565b604051908190038120611f53918b90602001615731565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b8881101561212a57600185878360208110611fbf57611fbf6151e8565b611fcc91901a601b61530f565b8c8c85818110611fde57611fde6151e8565b905060200201358b8b86818110611ff757611ff76151e8565b9050602002013560405160008152602001604052604051612034949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612056573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612104576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b84019350808061212290615217565b915050611fa2565b50827e01010101010101010101010101010101010101010101010101010101010101841614612185576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b6121cc6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b60006121da83850185615822565b60408101515160608201515191925090811415806121fd57508082608001515114155b8061220d5750808260a001515114155b15612244576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b600082604001515167ffffffffffffffff81111561226c5761226c6146a7565b60405190808252806020026020018201604052801561233857816020015b6040805161020081018252600060e08201818152610100830182905261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c083018290526101e0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161228a5790505b50905060006040518060800160405280600061ffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160008152509050600085610100015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123fa9190614f93565b6101008701516040517f7810d12a00000000000000000000000000000000000000000000000000000000815236600482015291925060009173ffffffffffffffffffffffffffffffffffffffff90911690637810d12a90602401602060405180830381865afa158015612471573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124959190614f93565b905060005b8660400151518110156129255760046000886040015183815181106124c1576124c16151e8565b6020908102919091018101518252818101929092526040908101600020815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e08201526002909101549091169181019190915285518690839081106125e4576125e46151e8565b6020026020010151600001819052506126198760400151828151811061260c5761260c6151e8565b60200260200101516132cc565b85828151811061262b5761262b6151e8565b60200260200101516060019060018111156126485761264861565d565b9081600181111561265b5761265b61565d565b815250506126bf87604001518281518110612678576126786151e8565b60200260200101518489608001518481518110612697576126976151e8565b60200260200101518885815181106126b1576126b16151e8565b60200260200101518c613377565b8683815181106126d1576126d16151e8565b60200260200101516020018784815181106126ee576126ee6151e8565b602002602001015160c0018281525082151515158152505050848181518110612719576127196151e8565b602002602001015160200151156127495760018460000181815161273d919061590f565b61ffff1690525061274e565b612913565b6127b4858281518110612763576127636151e8565b6020026020010151600001516080015188606001518381518110612789576127896151e8565b60200260200101518960a0015184815181106127a7576127a76151e8565b6020026020010151613496565b8683815181106127c6576127c66151e8565b60200260200101516040018784815181106127e3576127e36151e8565b602002602001015160800182815250821515151581525050508760800151600161280d919061530f565b61281b9060ff1660406152e5565b6103a48860a001518381518110612834576128346151e8565b60200260200101515161284791906152fc565b61285191906152fc565b858281518110612863576128636151e8565b602002602001015160a0018181525050848181518110612885576128856151e8565b602002602001015160a00151846060018181516128a291906152fc565b90525084518590829081106128b9576128b96151e8565b602002602001015160800151866128d091906151a0565b9550612913876040015182815181106128eb576128eb6151e8565b602002602001015184878481518110612906576129066151e8565b60200260200101516136b1565b8061291d81615217565b91505061249a565b50825161ffff1660000361293c5750505050505050565b61c80061294a3660106152e5565b5a61295590886151a0565b61295f91906152fc565b61296991906152fc565b8351909550613778906129809061ffff1687615959565b61298a91906152fc565b60408051608081018252600080825260208201819052918101829052606081018290529196506129b9896137b6565b905060005b886040015151811015612cf5578681815181106129dd576129dd6151e8565b60200260200101516020015115612ce357801580612a75575086612a026001836151a0565b81518110612a1257612a126151e8565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff16878281518110612a4b57612a4b6151e8565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff1614155b15612aa957612aa68a888381518110612a9057612a906151e8565b60200260200101516000015161010001516138a0565b92505b6000612bc78b6040518061012001604052808b8681518110612acd57612acd6151e8565b60200260200101516080015181526020018c81526020018a606001518c8781518110612afb57612afb6151e8565b602002602001015160a001518a612b1291906152e5565b612b1c9190615959565b81526020018d6000015181526020018d6020015181526020018681526020018b8681518110612b4d57612b4d6151e8565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff168152602001878152602001600115158152508c604001518581518110612b9c57612b9c6151e8565b60200260200101518b8681518110612bb657612bb66151e8565b602002602001015160000151613a1c565b9050806060015187604001818151612bdf919061596d565b6bffffffffffffffffffffffff169052506040810151602088018051612c0690839061596d565b6bffffffffffffffffffffffff169052508751889083908110612c2b57612c2b6151e8565b60200260200101516040015115158a604001518381518110612c4f57612c4f6151e8565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b83602001518460000151612c8c919061596d565b8b8681518110612c9e57612c9e6151e8565b6020026020010151608001518d8f608001518881518110612cc157612cc16151e8565b6020026020010151604051612cd99493929190615992565b60405180910390a3505b80612ced81615217565b9150506129be565b505050602083810151336000908152600b90925260409091208054600290612d329084906201000090046bffffffffffffffffffffffff1661596d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260400151601460000160008282829054906101000a90046bffffffffffffffffffffffff16612d90919061596d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555082604001518360200151612dd2919061596d565b6bffffffffffffffffffffffff16602160007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612e4e91906152fc565b909155505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603612edb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c8c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e010000000000000000000000000000900490911660608201529061314d576000816060015185612fe991906159cf565b90506000612ff785836159f4565b9050808360400181815161300b919061596d565b6bffffffffffffffffffffffff169052506130268582615a1f565b83606001818151613037919061596d565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b6000826000018281548110613170576131706151e8565b9060005260206000200154905092915050565b6000818152600183016020526040812054801561326c5760006131a76001836151a0565b85549091506000906131bb906001906151a0565b90508181146132205760008660000182815481106131db576131db6151e8565b90600052602060002001549050808760000184815481106131fe576131fe6151e8565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061323157613231615a4f565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611ecd565b6000915050611ecd565b5092915050565b60008181526001830160205260408120546132c457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611ecd565b506000611ecd565b6000818160045b600f811015613359577fff000000000000000000000000000000000000000000000000000000000000008216838260208110613311576133116151e8565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461334757506000949350505050565b8061335181615217565b9150506132d3565b5081600f1a600181111561336f5761336f61565d565b949350505050565b6000808080856060015160018111156133925761339261565d565b036133b8576133a48888888888613e8b565b6133b35760009250905061348c565b613430565b6001856060015160018111156133d0576133d061565d565b036133fe5760006133e389898988614015565b92509050806133f8575060009250905061348c565b50613430565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516060015163ffffffff16871061348557877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636876040516134729190614d1a565b60405180910390a260009250905061348c565b6001925090505b9550959350505050565b601454600090819077010000000000000000000000000000000000000000000000900460ff16156134f3576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000001790556040517f4585e33b0000000000000000000000000000000000000000000000000000000090613568908590602401614d1a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d169061363b9087908790600401615a7e565b60408051808303816000875af1158015613659573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061367d9190615a97565b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b6000816060015160018111156136c9576136c961565d565b0361372d57600083815260046020526040902060010180547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff851602179055505050565b6001816060015160018111156137455761374561565d565b036137b15760c08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613826573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061384a9190615adf565b5093505092505060008213158061386057508042105b8061389057506000846040015162ffffff16118015613890575061388481426151a0565b846040015162ffffff16105b15613276575050601b5492915050565b60408051608081018252600080825260208083018281528385018381526060850184905273ffffffffffffffffffffffffffffffffffffffff878116855260229093528584208054640100000000810462ffffff1690925263ffffffff82169092527b01000000000000000000000000000000000000000000000000000000810460ff16855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495919484936701000000000000009092049091169163feaf968c9160048083019260a09291908290030181865afa15801561398d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139b19190615adf565b509350509250506000821315806139c757508042105b806139f757506000866040015162ffffff161180156139f757506139eb81426151a0565b866040015162ffffff16105b15613a0b5760018301546060850152613a13565b606084018290525b50505092915050565b604080516101008101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201529082015115613ab25760008381526023602090815260409182902082518084018452905463ffffffff811680835262ffffff640100000000909204821692840192835260e089018051909401529051915191169101525b6000613abe8686614222565b60c0840151602082015182519293509091600091613adb9161596d565b60e08801515190915060ff16600060128210613af8576001613b0e565b613b038260126151a0565b613b0e90600a615c4f565b9050600060128311613b21576001613b37565b613b2c6012846151a0565b613b3790600a615c4f565b905085600001516bffffffffffffffffffffffff16856bffffffffffffffffffffffff161015613bdf57849350613bb3818b60800151613b7791906152e5565b838c60e0015160600151886bffffffffffffffffffffffff16613b9a91906152e5565b613ba491906152e5565b613bae9190615959565b614550565b6bffffffffffffffffffffffff9081166040880152600060608801819052602088015285168652613d05565b836bffffffffffffffffffffffff16856bffffffffffffffffffffffff161015613d0557849350613c6d86604001516bffffffffffffffffffffffff16828c60800151613c2c91906152e5565b848d60e0015160600151896bffffffffffffffffffffffff16613c4f91906152e5565b613c5991906152e5565b613c639190615959565b613bae91906151a0565b6bffffffffffffffffffffffff1660608088019190915260e08b01510151613cf190613c9a9084906152e5565b6001848d60e0015160600151613cb091906152e5565b613cba91906151a0565b838d608001518a606001516bffffffffffffffffffffffff16613cdd91906152e5565b613ce791906152e5565b613ba491906152fc565b6bffffffffffffffffffffffff1660208701525b60008981526004602052604090206001018054859190601090613d4b90849070010000000000000000000000000000000090046bffffffffffffffffffffffff166159cf565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008b81526004602052604081206001018054928816935091613da69084906fffffffffffffffffffffffffffffffff16615c5b565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550836bffffffffffffffffffffffff16602160008c60c0015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254613e3d91906151a0565b92505081905550887f801ba6ed51146ffe3e99d1dbd9dd0f4de6292e78a9a34c39c0183de17b3f40fc87604051613e749190615c84565b60405180910390a250939998505050505050505050565b60008084806020019051810190613ea29190615d44565b845160e00151815191925063ffffffff90811691161015613eff57867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e886604051613eed9190614d1a565b60405180910390a2600091505061400c565b8260e001518015613fbf5750602081015115801590613fbf5750602081015161010084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015613f98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fbc9190614f93565b14155b80613fd15750805163ffffffff168611155b1561400657867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc30186604051613eed9190614d1a565b60019150505b95945050505050565b60008060008480602001905181019061402e9190615d9c565b905060008782600001518360200151846040015160405160200161409094939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b6040516020818303038152906040528051906020012090508460e00151801561416b575060808201511580159061416b5750608082015161010086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015614144573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141689190614f93565b14155b80614180575086826060015163ffffffff1610155b156141ca57877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301876040516141b59190614d1a565b60405180910390a26000935091506142199050565b60008181526008602052604090205460ff161561421157877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8876040516141b59190614d1a565b600193509150505b94509492505050565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915260008260e001516000015160ff1690506000846060015161ffff16846060015161428d91906152e5565b905083610100015180156142a05750803a105b156142a857503a5b6000601283116142b95760016142cf565b6142c46012846151a0565b6142cf90600a615c4f565b90506000601284106142e25760016142f8565b6142ed8460126151a0565b6142f890600a615c4f565b905060008660a0015187604001518860200151896000015161431a91906152fc565b61432490876152e5565b61432e91906152fc565b61433891906152e5565b905061437b828860e001516060015161435191906152e5565b6001848a60e001516060015161436791906152e5565b61437191906151a0565b613ce786856152e5565b6bffffffffffffffffffffffff168652608087015161439e90613bae9083615959565b6bffffffffffffffffffffffff1660408088019190915260e088015101516000906143d79062ffffff16683635c9adc5dea000006152e5565b9050600081633b9aca008a60a001518b60e001516020015163ffffffff168c604001518d600001518b61440a91906152e5565b61441491906152fc565b61441e91906152e5565b61442891906152e5565b6144329190615959565b61443c91906152fc565b905061447f848a60e001516060015161445591906152e5565b6001868c60e001516060015161446b91906152e5565b61447591906151a0565b613ce788856152e5565b6bffffffffffffffffffffffff16602089015260808901516144a590613bae9083615959565b6bffffffffffffffffffffffff16606089015260c089015173ffffffffffffffffffffffffffffffffffffffff166080808a01919091528901516144e890614550565b6bffffffffffffffffffffffff1660a0808a019190915289015161450b90614550565b6bffffffffffffffffffffffff1660c089015260e08901516060015161453090614550565b6bffffffffffffffffffffffff1660e08901525050505050505092915050565b60006bffffffffffffffffffffffff8211156145ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610c8c565b5090565b508054600082559060005260206000209081019061109c9190614692565b82805482825590600052602060002090810192821561468a579160200282015b8281111561468a57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614630565b506145ee9291505b5b808211156145ee5760008155600101614693565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610200810167ffffffffffffffff811182821017156146fa576146fa6146a7565b60405290565b60405160c0810167ffffffffffffffff811182821017156146fa576146fa6146a7565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561476a5761476a6146a7565b604052919050565b600067ffffffffffffffff82111561478c5761478c6146a7565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461109c57600080fd5b80356147c381614796565b919050565b600082601f8301126147d957600080fd5b813560206147ee6147e983614772565b614723565b82815260059290921b8401810191818101908684111561480d57600080fd5b8286015b8481101561483157803561482481614796565b8352918301918301614811565b509695505050505050565b60ff8116811461109c57600080fd5b80356147c38161483c565b63ffffffff8116811461109c57600080fd5b80356147c381614856565b801515811461109c57600080fd5b80356147c381614873565b62ffffff8116811461109c57600080fd5b80356147c38161488c565b61ffff8116811461109c57600080fd5b80356147c3816148a8565b600061020082840312156148d657600080fd5b6148de6146d6565b90506148e982614868565b81526148f760208301614868565b602082015261490860408301614868565b6040820152614919606083016147b8565b606082015261492a60808301614881565b608082015261493b60a0830161489d565b60a082015261494c60c08301614868565b60c082015261495d60e08301614868565b60e08201526101006149708184016147b8565b908201526101206149828382016148b8565b908201526101406149948382016147b8565b90820152610160828101359082015261018080830135908201526101a080830135908201526101c08083013567ffffffffffffffff8111156149d557600080fd5b6149e1858286016147c8565b8284015250506101e06149f58184016147b8565b9082015292915050565b803567ffffffffffffffff811681146147c357600080fd5b600082601f830112614a2857600080fd5b813567ffffffffffffffff811115614a4257614a426146a7565b614a7360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614723565b818152846020838601011115614a8857600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461109c57600080fd5b600082601f830112614ad057600080fd5b81356020614ae06147e983614772565b82815260c09283028501820192828201919087851115614aff57600080fd5b8387015b85811015614b915781818a031215614b1b5760008081fd5b614b23614700565b8135614b2e81614856565b815281860135614b3d8161488c565b81870152604082810135614b5081614796565b90820152606082810135614b638161483c565b908201526080828101359082015260a080830135614b8081614aa5565b908201528452928401928101614b03565b5090979650505050505050565b600080600080600080600080610100898b031215614bbb57600080fd5b883567ffffffffffffffff80821115614bd357600080fd5b614bdf8c838d016147c8565b995060208b0135915080821115614bf557600080fd5b614c018c838d016147c8565b9850614c0f60408c0161484b565b975060608b0135915080821115614c2557600080fd5b614c318c838d016148c3565b9650614c3f60808c016149ff565b955060a08b0135915080821115614c5557600080fd5b614c618c838d01614a17565b945060c08b0135915080821115614c7757600080fd5b614c838c838d016147c8565b935060e08b0135915080821115614c9957600080fd5b50614ca68b828c01614abf565b9150509295985092959890939650565b6000815180845260005b81811015614cdc57602081850181015186830182015201614cc0565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611edf6020830184614cb6565b60008083601f840112614d3f57600080fd5b50813567ffffffffffffffff811115614d5757600080fd5b6020830191508360208260051b8501011115614d7257600080fd5b9250929050565b60008060008060008060008060e0898b031215614d9557600080fd5b606089018a811115614da657600080fd5b8998503567ffffffffffffffff80821115614dc057600080fd5b818b0191508b601f830112614dd457600080fd5b813581811115614de357600080fd5b8c6020828501011115614df557600080fd5b6020830199508098505060808b0135915080821115614e1357600080fd5b614e1f8c838d01614d2d565b909750955060a08b0135915080821115614e3857600080fd5b50614e458b828c01614d2d565b999c989b50969995989497949560c00135949350505050565b60008060008060008060c08789031215614e7757600080fd5b863567ffffffffffffffff80821115614e8f57600080fd5b614e9b8a838b016147c8565b97506020890135915080821115614eb157600080fd5b614ebd8a838b016147c8565b9650614ecb60408a0161484b565b95506060890135915080821115614ee157600080fd5b614eed8a838b01614a17565b9450614efb60808a016149ff565b935060a0890135915080821115614f1157600080fd5b50614f1e89828a01614a17565b9150509295509295509295565b600060208284031215614f3d57600080fd5b8135611edf81614796565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff818116838216029081169081811461327657613276614f48565b600060208284031215614fa557600080fd5b5051919050565b63ffffffff81811683821601908082111561327657613276614f48565b600081518084526020808501945080840160005b8381101561500f57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614fdd565b509495945050505050565b6020815261503160208201835163ffffffff169052565b6000602083015161504a604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015180151560a08401525060a083015162ffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006150c98185018363ffffffff169052565b84015190506101206150f28482018373ffffffffffffffffffffffffffffffffffffffff169052565b84015190506101406151098482018361ffff169052565b84015190506101606151328482018373ffffffffffffffffffffffffffffffffffffffff169052565b840151610180848101919091528401516101a0808501919091528401516101c0808501919091528401516102006101e08086018290529192509061517a610220860184614fc9565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b81810381811115611ecd57611ecd614f48565b6000816151c2576151c2614f48565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361524857615248614f48565b5060010190565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261527f8184018a614fc9565b905082810360808401526152938189614fc9565b905060ff871660a084015282810360c08401526152b08187614cb6565b905067ffffffffffffffff851660e08401528281036101008401526152d58185614cb6565b9c9b505050505050505050505050565b8082028115828204841417611ecd57611ecd614f48565b80820180821115611ecd57611ecd614f48565b60ff8181168382160190811115611ecd57611ecd614f48565b80516147c381614856565b80516147c381614796565b80516147c381614873565b80516147c38161488c565b80516147c3816148a8565b600082601f83011261537057600080fd5b815160206153806147e983614772565b82815260059290921b8401810191818101908684111561539f57600080fd5b8286015b848110156148315780516153b681614796565b83529183019183016153a3565b600082601f8301126153d457600080fd5b815160206153e46147e983614772565b82815260c0928302850182019282820191908785111561540357600080fd5b8387015b85811015614b915781818a03121561541f5760008081fd5b615427614700565b815161543281614856565b8152818601516154418161488c565b8187015260408281015161545481614796565b908201526060828101516154678161483c565b908201526080828101519082015260a08083015161548481614aa5565b908201528452928401928101615407565b6000806000606084860312156154aa57600080fd5b835167ffffffffffffffff808211156154c257600080fd5b9085019061020082880312156154d757600080fd5b6154df6146d6565b6154e883615328565b81526154f660208401615328565b602082015261550760408401615328565b604082015261551860608401615333565b60608201526155296080840161533e565b608082015261553a60a08401615349565b60a082015261554b60c08401615328565b60c082015261555c60e08401615328565b60e082015261010061556f818501615333565b90820152610120615581848201615354565b90820152610140615593848201615333565b90820152610160838101519082015261018080840151908201526101a080840151908201526101c080840151838111156155cc57600080fd5b6155d88a82870161535f565b8284015250506101e06155ec818501615333565b90820152602087015190955091508082111561560757600080fd5b6156138783880161535f565b9350604086015191508082111561562957600080fd5b50615636868287016153c3565b9150509250925092565b60006020828403121561565257600080fd5b8151611edf8161483c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526156d38285018b614fc9565b915083820360808501526156e7828a614fc9565b915060ff881660a085015283820360c08501526157048288614cb6565b90861660e085015283810361010085015290506152d58185614cb6565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f83011261575857600080fd5b813560206157686147e983614772565b82815260059290921b8401810191818101908684111561578757600080fd5b8286015b84811015614831578035835291830191830161578b565b600082601f8301126157b357600080fd5b813560206157c36147e983614772565b82815260059290921b840181019181810190868411156157e257600080fd5b8286015b8481101561483157803567ffffffffffffffff8111156158065760008081fd5b6158148986838b0101614a17565b8452509183019183016157e6565b60006020828403121561583457600080fd5b813567ffffffffffffffff8082111561584c57600080fd5b9083019060c0828603121561586057600080fd5b615868614700565b823581526020830135602082015260408301358281111561588857600080fd5b61589487828601615747565b6040830152506060830135828111156158ac57600080fd5b6158b887828601615747565b6060830152506080830135828111156158d057600080fd5b6158dc878286016157a2565b60808301525060a0830135828111156158f457600080fd5b615900878286016157a2565b60a08301525095945050505050565b61ffff81811683821601908082111561327657613276614f48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159685761596861592a565b500490565b6bffffffffffffffffffffffff81811683821601908082111561327657613276614f48565b6bffffffffffffffffffffffff851681528360208201528260408201526080606082015260006159c56080830184614cb6565b9695505050505050565b6bffffffffffffffffffffffff82811682821603908082111561327657613276614f48565b60006bffffffffffffffffffffffff80841680615a1357615a1361592a565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114615a4757615a47614f48565b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b82815260406020820152600061336f6040830184614cb6565b60008060408385031215615aaa57600080fd5b8251615ab581614873565b6020939093015192949293505050565b805169ffffffffffffffffffff811681146147c357600080fd5b600080600080600060a08688031215615af757600080fd5b615b0086615ac5565b9450602086015193506040860151925060608601519150615b2360808701615ac5565b90509295509295909350565b600181815b80851115615b8857817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615b6e57615b6e614f48565b80851615615b7b57918102915b93841c9390800290615b34565b509250929050565b600082615b9f57506001611ecd565b81615bac57506000611ecd565b8160018114615bc25760028114615bcc57615be8565b6001915050611ecd565b60ff841115615bdd57615bdd614f48565b50506001821b611ecd565b5060208310610133831016604e8410600b8410161715615c0b575081810a611ecd565b615c158383615b2f565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615c4757615c47614f48565b029392505050565b6000611edf8383615b90565b6fffffffffffffffffffffffffffffffff81811683821601908082111561327657613276614f48565b6000610100820190506bffffffffffffffffffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401525073ffffffffffffffffffffffffffffffffffffffff608084015116608083015260a0830151615d0460a08401826bffffffffffffffffffffffff169052565b5060c0830151615d2460c08401826bffffffffffffffffffffffff169052565b5060e083015161327660e08401826bffffffffffffffffffffffff169052565b600060408284031215615d5657600080fd5b6040516040810181811067ffffffffffffffff82111715615d7957615d796146a7565b6040528251615d8781614856565b81526020928301519281019290925250919050565b600060a08284031215615dae57600080fd5b60405160a0810181811067ffffffffffffffff82111715615dd157615dd16146a7565b806040525082518152602083015160208201526040830151615df281614856565b60408201526060830151615e0581614856565b6060820152608092830151928101929092525091905056fea164736f6c6343000813000a", } var AutomationRegistryABI = AutomationRegistryMetaData.ABI diff --git a/core/gethwrappers/generated/chain_module_base/chain_module_base.go b/core/gethwrappers/generated/chain_module_base/chain_module_base.go index bf98608aab..7f8a0b4c49 100644 --- a/core/gethwrappers/generated/chain_module_base/chain_module_base.go +++ b/core/gethwrappers/generated/chain_module_base/chain_module_base.go @@ -29,8 +29,8 @@ var ( ) var ChainModuleBaseMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061015c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806357e871e71161005057806357e871e71461009a57806385df51fd146100a0578063de9ee35e146100b357600080fd5b8063125441401461006c57806318b8f61314610093575b600080fd5b61008061007a3660046100f6565b50600090565b6040519081526020015b60405180910390f35b6000610080565b43610080565b6100806100ae3660046100f6565b6100c9565b6040805161012c8152600060208201520161008a565b600043821015806100e457506101006100e2834361010f565b115b156100f157506000919050565b504090565b60006020828403121561010857600080fd5b5035919050565b81810381811115610149577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610155806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80637810d12a116100505780637810d12a1461006c57806385df51fd14610099578063de9ee35e146100ac57600080fd5b8063125441401461006c57806357e871e714610093575b600080fd5b61008061007a3660046100ef565b50600090565b6040519081526020015b60405180910390f35b43610080565b6100806100a73660046100ef565b6100c2565b6040805161012c8152600060208201520161008a565b600043821015806100dd57506101006100db8343610108565b115b156100ea57506000919050565b504090565b60006020828403121561010157600080fd5b5035919050565b81810381811115610142577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000a", } var ChainModuleBaseABI = ChainModuleBaseMetaData.ABI @@ -213,9 +213,9 @@ func (_ChainModuleBase *ChainModuleBaseCallerSession) BlockNumber() (*big.Int, e return _ChainModuleBase.Contract.BlockNumber(&_ChainModuleBase.CallOpts) } -func (_ChainModuleBase *ChainModuleBaseCaller) GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) { +func (_ChainModuleBase *ChainModuleBaseCaller) GetCurrentL1Fee(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { var out []interface{} - err := _ChainModuleBase.contract.Call(opts, &out, "getCurrentL1Fee") + err := _ChainModuleBase.contract.Call(opts, &out, "getCurrentL1Fee", arg0) if err != nil { return *new(*big.Int), err @@ -227,12 +227,12 @@ func (_ChainModuleBase *ChainModuleBaseCaller) GetCurrentL1Fee(opts *bind.CallOp } -func (_ChainModuleBase *ChainModuleBaseSession) GetCurrentL1Fee() (*big.Int, error) { - return _ChainModuleBase.Contract.GetCurrentL1Fee(&_ChainModuleBase.CallOpts) +func (_ChainModuleBase *ChainModuleBaseSession) GetCurrentL1Fee(arg0 *big.Int) (*big.Int, error) { + return _ChainModuleBase.Contract.GetCurrentL1Fee(&_ChainModuleBase.CallOpts, arg0) } -func (_ChainModuleBase *ChainModuleBaseCallerSession) GetCurrentL1Fee() (*big.Int, error) { - return _ChainModuleBase.Contract.GetCurrentL1Fee(&_ChainModuleBase.CallOpts) +func (_ChainModuleBase *ChainModuleBaseCallerSession) GetCurrentL1Fee(arg0 *big.Int) (*big.Int, error) { + return _ChainModuleBase.Contract.GetCurrentL1Fee(&_ChainModuleBase.CallOpts, arg0) } func (_ChainModuleBase *ChainModuleBaseCaller) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, @@ -301,7 +301,7 @@ type ChainModuleBaseInterface interface { BlockNumber(opts *bind.CallOpts) (*big.Int, error) - GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) + GetCurrentL1Fee(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, diff --git a/core/gethwrappers/generated/i_chain_module/i_chain_module.go b/core/gethwrappers/generated/i_chain_module/i_chain_module.go index 23cec8fb9c..947a18c319 100644 --- a/core/gethwrappers/generated/i_chain_module/i_chain_module.go +++ b/core/gethwrappers/generated/i_chain_module/i_chain_module.go @@ -29,7 +29,7 @@ var ( ) var IChainModuleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", } var IChainModuleABI = IChainModuleMetaData.ABI @@ -194,9 +194,9 @@ func (_IChainModule *IChainModuleCallerSession) BlockNumber() (*big.Int, error) return _IChainModule.Contract.BlockNumber(&_IChainModule.CallOpts) } -func (_IChainModule *IChainModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) { +func (_IChainModule *IChainModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) { var out []interface{} - err := _IChainModule.contract.Call(opts, &out, "getCurrentL1Fee") + err := _IChainModule.contract.Call(opts, &out, "getCurrentL1Fee", dataSize) if err != nil { return *new(*big.Int), err @@ -208,12 +208,12 @@ func (_IChainModule *IChainModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts) (* } -func (_IChainModule *IChainModuleSession) GetCurrentL1Fee() (*big.Int, error) { - return _IChainModule.Contract.GetCurrentL1Fee(&_IChainModule.CallOpts) +func (_IChainModule *IChainModuleSession) GetCurrentL1Fee(dataSize *big.Int) (*big.Int, error) { + return _IChainModule.Contract.GetCurrentL1Fee(&_IChainModule.CallOpts, dataSize) } -func (_IChainModule *IChainModuleCallerSession) GetCurrentL1Fee() (*big.Int, error) { - return _IChainModule.Contract.GetCurrentL1Fee(&_IChainModule.CallOpts) +func (_IChainModule *IChainModuleCallerSession) GetCurrentL1Fee(dataSize *big.Int) (*big.Int, error) { + return _IChainModule.Contract.GetCurrentL1Fee(&_IChainModule.CallOpts, dataSize) } func (_IChainModule *IChainModuleCaller) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, @@ -282,7 +282,7 @@ type IChainModuleInterface interface { BlockNumber(opts *bind.CallOpts) (*big.Int, error) - GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) + GetCurrentL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, diff --git a/core/gethwrappers/generated/optimism_module/optimism_module.go b/core/gethwrappers/generated/optimism_module/optimism_module.go index 009ab6d8cf..89b6a758fc 100644 --- a/core/gethwrappers/generated/optimism_module/optimism_module.go +++ b/core/gethwrappers/generated/optimism_module/optimism_module.go @@ -29,8 +29,8 @@ var ( ) var OptimismModuleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b506104d1806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806357e871e71161005057806357e871e71461009a57806385df51fd146100a0578063de9ee35e146100b357600080fd5b8063125441401461006c57806318b8f61314610092575b600080fd5b61007f61007a3660046102e9565b6100ca565b6040519081526020015b60405180910390f35b61007f6101eb565b4361007f565b61007f6100ae3660046102e9565b6102bc565b6040805161ea60815261010e602082015201610089565b6000806100d8836004610331565b67ffffffffffffffff8111156100f0576100f061034e565b6040519080825280601f01601f19166020018201604052801561011a576020820181803683370190505b50905073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff166349948e0e82604051806080016040528060508152602001610475605091396040516020016101789291906103a1565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016101a391906103d0565b602060405180830381865afa1580156101c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e49190610421565b9392505050565b600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff166349948e0e6000366040518060800160405280605081526020016104756050913960405160200161024b9392919061043a565b6040516020818303038152906040526040518263ffffffff1660e01b815260040161027691906103d0565b602060405180830381865afa158015610293573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b79190610421565b905090565b600043821015806102d757506101006102d58343610461565b115b156102e457506000919050565b504090565b6000602082840312156102fb57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761034857610348610302565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b83811015610398578181015183820152602001610380565b50506000910152565b600083516103b381846020880161037d565b8351908301906103c781836020880161037d565b01949350505050565b60208152600082518060208401526103ef81604085016020870161037d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60006020828403121561043357600080fd5b5051919050565b82848237600083820160008152835161045781836020880161037d565b0195945050505050565b818103818111156103485761034861030256feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506103dc806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80637810d12a116100505780637810d12a1461006c57806385df51fd14610098578063de9ee35e146100ab57600080fd5b8063125441401461006c57806357e871e714610092575b600080fd5b61007f61007a366004610221565b6100c2565b6040519081526020015b60405180910390f35b4361007f565b61007f6100a6366004610221565b6100d3565b6040805161ea60815261010e602082015201610089565b60006100cd82610100565b92915050565b600043821015806100ee57506101006100ec8343610269565b115b156100fb57506000919050565b504090565b60008061010e83600461027c565b67ffffffffffffffff81111561012657610126610293565b6040519080825280601f01601f191660200182016040528015610150576020820181803683370190505b50905073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff166349948e0e82604051806080016040528060508152602001610380605091396040516020016101ae9291906102e6565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016101d99190610315565b602060405180830381865afa1580156101f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061021a9190610366565b9392505050565b60006020828403121561023357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156100cd576100cd61023a565b80820281158282048414176100cd576100cd61023a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b838110156102dd5781810151838201526020016102c5565b50506000910152565b600083516102f88184602088016102c2565b83519083019061030c8183602088016102c2565b01949350505050565b60208152600082518060208401526103348160408501602087016102c2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60006020828403121561037857600080fd5b505191905056feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa164736f6c6343000813000a", } var OptimismModuleABI = OptimismModuleMetaData.ABI @@ -213,9 +213,9 @@ func (_OptimismModule *OptimismModuleCallerSession) BlockNumber() (*big.Int, err return _OptimismModule.Contract.BlockNumber(&_OptimismModule.CallOpts) } -func (_OptimismModule *OptimismModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) { +func (_OptimismModule *OptimismModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) { var out []interface{} - err := _OptimismModule.contract.Call(opts, &out, "getCurrentL1Fee") + err := _OptimismModule.contract.Call(opts, &out, "getCurrentL1Fee", dataSize) if err != nil { return *new(*big.Int), err @@ -227,12 +227,12 @@ func (_OptimismModule *OptimismModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts } -func (_OptimismModule *OptimismModuleSession) GetCurrentL1Fee() (*big.Int, error) { - return _OptimismModule.Contract.GetCurrentL1Fee(&_OptimismModule.CallOpts) +func (_OptimismModule *OptimismModuleSession) GetCurrentL1Fee(dataSize *big.Int) (*big.Int, error) { + return _OptimismModule.Contract.GetCurrentL1Fee(&_OptimismModule.CallOpts, dataSize) } -func (_OptimismModule *OptimismModuleCallerSession) GetCurrentL1Fee() (*big.Int, error) { - return _OptimismModule.Contract.GetCurrentL1Fee(&_OptimismModule.CallOpts) +func (_OptimismModule *OptimismModuleCallerSession) GetCurrentL1Fee(dataSize *big.Int) (*big.Int, error) { + return _OptimismModule.Contract.GetCurrentL1Fee(&_OptimismModule.CallOpts, dataSize) } func (_OptimismModule *OptimismModuleCaller) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, @@ -301,7 +301,7 @@ type OptimismModuleInterface interface { BlockNumber(opts *bind.CallOpts) (*big.Int, error) - GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) + GetCurrentL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, diff --git a/core/gethwrappers/generated/scroll_module/scroll_module.go b/core/gethwrappers/generated/scroll_module/scroll_module.go index 702cc39a7a..0a580546d1 100644 --- a/core/gethwrappers/generated/scroll_module/scroll_module.go +++ b/core/gethwrappers/generated/scroll_module/scroll_module.go @@ -5,6 +5,7 @@ package scroll_module import ( "errors" + "fmt" "math/big" "strings" @@ -14,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" ) var ( @@ -29,8 +31,8 @@ var ( ) var ScrollModuleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061050c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806357e871e71161005057806357e871e71461009a57806385df51fd146100a0578063de9ee35e146100b357600080fd5b8063125441401461006c57806318b8f61314610092575b600080fd5b61007f61007a3660046102e8565b6100c9565b6040519081526020015b60405180910390f35b61007f6101ea565b4361007f565b61007f6100ae3660046102e8565b6102bb565b6040805161afc8815260aa602082015201610089565b6000806100d7836004610330565b67ffffffffffffffff8111156100ef576100ef61034d565b6040519080825280601f01601f191660200182016040528015610119576020820181803683370190505b50905073530000000000000000000000000000000000000273ffffffffffffffffffffffffffffffffffffffff166349948e0e826040518060c00160405280608c8152602001610474608c91396040516020016101779291906103a0565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016101a291906103cf565b602060405180830381865afa1580156101bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e39190610420565b9392505050565b600073530000000000000000000000000000000000000273ffffffffffffffffffffffffffffffffffffffff166349948e0e6000366040518060c00160405280608c8152602001610474608c913960405160200161024a93929190610439565b6040516020818303038152906040526040518263ffffffff1660e01b815260040161027591906103cf565b602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b69190610420565b905090565b600043821015806102d657506101006102d48343610460565b115b156102e357506000919050565b504090565b6000602082840312156102fa57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761034757610347610301565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b8381101561039757818101518382015260200161037f565b50506000910152565b600083516103b281846020880161037c565b8351908301906103c681836020880161037c565b01949350505050565b60208152600082518060208401526103ee81604085016020870161037c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60006020828403121561043257600080fd5b5051919050565b82848237600083820160008152835161045681836020880161037c565b0195945050505050565b818103818111156103475761034761030156feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"coefficient\",\"type\":\"uint8\"}],\"name\":\"InvalidL1FeeCoefficient\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"coefficient\",\"type\":\"uint8\"}],\"name\":\"L1FeeCoefficientSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_l1FeeCoefficient\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"coefficient\",\"type\":\"uint8\"}],\"name\":\"setL1FeeCalculation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040526001805460ff60a01b1916601960a21b17905534801561002357600080fd5b50338060008161007a5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100aa576100aa816100b2565b50505061015b565b336001600160a01b0382160361010a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610071565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61093c8061016a6000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80638da5cb5b11610076578063de9ee35e1161005b578063de9ee35e1461017e578063f22559a014610194578063f2fde38b146101a757600080fd5b80638da5cb5b1461011f57806390bd5c741461014757600080fd5b80637810d12a116100a75780637810d12a146100ef57806379ba50971461010257806385df51fd1461010c57600080fd5b806312544140146100c357806357e871e7146100e9575b600080fd5b6100d66100d13660046106b1565b6101ba565b6040519081526020015b60405180910390f35b436100d6565b6100d66100fd3660046106b1565b6101cb565b61010a61020a565b005b6100d661011a3660046106b1565b61030c565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e0565b60015461016c9074010000000000000000000000000000000000000000900460ff1681565b60405160ff90911681526020016100e0565b6040805161afc8815260aa6020820152016100e0565b61010a6101a23660046106ca565b610339565b61010a6101b53660046106ed565b610404565b60006101c582610418565b92915050565b600060646101d883610418565b600154610200919074010000000000000000000000000000000000000000900460ff16610752565b6101c59190610769565b60015473ffffffffffffffffffffffffffffffffffffffff163314610290576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60004382101580610327575061010061032583436107a4565b115b1561033457506000919050565b504090565b610341610539565b60648160ff161115610384576040517f1a8a06a000000000000000000000000000000000000000000000000000000000815260ff82166004820152602401610287565b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000060ff8416908102919091179091556040519081527f29ec9e31de0d3fe0208a7ccb792bbc26a854f123146110daa3a77219cb74a5549060200160405180910390a150565b61040c610539565b610415816105bc565b50565b600080610426836004610752565b67ffffffffffffffff81111561043e5761043e6107b7565b6040519080825280601f01601f191660200182016040528015610468576020820181803683370190505b50905073530000000000000000000000000000000000000273ffffffffffffffffffffffffffffffffffffffff166349948e0e826040518060c00160405280608c81526020016108a4608c91396040516020016104c692919061080a565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016104f19190610839565b602060405180830381865afa15801561050e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610532919061088a565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610287565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361063b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610287565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156106c357600080fd5b5035919050565b6000602082840312156106dc57600080fd5b813560ff8116811461053257600080fd5b6000602082840312156106ff57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461053257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176101c5576101c5610723565b60008261079f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b818103818111156101c5576101c5610723565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b838110156108015781810151838201526020016107e9565b50506000910152565b6000835161081c8184602088016107e6565b8351908301906108308183602088016107e6565b01949350505050565b60208152600082518060208401526108588160408501602087016107e6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60006020828403121561089c57600080fd5b505191905056feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa164736f6c6343000813000a", } var ScrollModuleABI = ScrollModuleMetaData.ABI @@ -213,9 +215,9 @@ func (_ScrollModule *ScrollModuleCallerSession) BlockNumber() (*big.Int, error) return _ScrollModule.Contract.BlockNumber(&_ScrollModule.CallOpts) } -func (_ScrollModule *ScrollModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) { +func (_ScrollModule *ScrollModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) { var out []interface{} - err := _ScrollModule.contract.Call(opts, &out, "getCurrentL1Fee") + err := _ScrollModule.contract.Call(opts, &out, "getCurrentL1Fee", dataSize) if err != nil { return *new(*big.Int), err @@ -227,12 +229,12 @@ func (_ScrollModule *ScrollModuleCaller) GetCurrentL1Fee(opts *bind.CallOpts) (* } -func (_ScrollModule *ScrollModuleSession) GetCurrentL1Fee() (*big.Int, error) { - return _ScrollModule.Contract.GetCurrentL1Fee(&_ScrollModule.CallOpts) +func (_ScrollModule *ScrollModuleSession) GetCurrentL1Fee(dataSize *big.Int) (*big.Int, error) { + return _ScrollModule.Contract.GetCurrentL1Fee(&_ScrollModule.CallOpts, dataSize) } -func (_ScrollModule *ScrollModuleCallerSession) GetCurrentL1Fee() (*big.Int, error) { - return _ScrollModule.Contract.GetCurrentL1Fee(&_ScrollModule.CallOpts) +func (_ScrollModule *ScrollModuleCallerSession) GetCurrentL1Fee(dataSize *big.Int) (*big.Int, error) { + return _ScrollModule.Contract.GetCurrentL1Fee(&_ScrollModule.CallOpts, dataSize) } func (_ScrollModule *ScrollModuleCaller) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, @@ -287,11 +289,506 @@ func (_ScrollModule *ScrollModuleCallerSession) GetMaxL1Fee(dataSize *big.Int) ( return _ScrollModule.Contract.GetMaxL1Fee(&_ScrollModule.CallOpts, dataSize) } +func (_ScrollModule *ScrollModuleCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ScrollModule.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_ScrollModule *ScrollModuleSession) Owner() (common.Address, error) { + return _ScrollModule.Contract.Owner(&_ScrollModule.CallOpts) +} + +func (_ScrollModule *ScrollModuleCallerSession) Owner() (common.Address, error) { + return _ScrollModule.Contract.Owner(&_ScrollModule.CallOpts) +} + +func (_ScrollModule *ScrollModuleCaller) SL1FeeCoefficient(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ScrollModule.contract.Call(opts, &out, "s_l1FeeCoefficient") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_ScrollModule *ScrollModuleSession) SL1FeeCoefficient() (uint8, error) { + return _ScrollModule.Contract.SL1FeeCoefficient(&_ScrollModule.CallOpts) +} + +func (_ScrollModule *ScrollModuleCallerSession) SL1FeeCoefficient() (uint8, error) { + return _ScrollModule.Contract.SL1FeeCoefficient(&_ScrollModule.CallOpts) +} + +func (_ScrollModule *ScrollModuleTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ScrollModule.contract.Transact(opts, "acceptOwnership") +} + +func (_ScrollModule *ScrollModuleSession) AcceptOwnership() (*types.Transaction, error) { + return _ScrollModule.Contract.AcceptOwnership(&_ScrollModule.TransactOpts) +} + +func (_ScrollModule *ScrollModuleTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _ScrollModule.Contract.AcceptOwnership(&_ScrollModule.TransactOpts) +} + +func (_ScrollModule *ScrollModuleTransactor) SetL1FeeCalculation(opts *bind.TransactOpts, coefficient uint8) (*types.Transaction, error) { + return _ScrollModule.contract.Transact(opts, "setL1FeeCalculation", coefficient) +} + +func (_ScrollModule *ScrollModuleSession) SetL1FeeCalculation(coefficient uint8) (*types.Transaction, error) { + return _ScrollModule.Contract.SetL1FeeCalculation(&_ScrollModule.TransactOpts, coefficient) +} + +func (_ScrollModule *ScrollModuleTransactorSession) SetL1FeeCalculation(coefficient uint8) (*types.Transaction, error) { + return _ScrollModule.Contract.SetL1FeeCalculation(&_ScrollModule.TransactOpts, coefficient) +} + +func (_ScrollModule *ScrollModuleTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _ScrollModule.contract.Transact(opts, "transferOwnership", to) +} + +func (_ScrollModule *ScrollModuleSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _ScrollModule.Contract.TransferOwnership(&_ScrollModule.TransactOpts, to) +} + +func (_ScrollModule *ScrollModuleTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _ScrollModule.Contract.TransferOwnership(&_ScrollModule.TransactOpts, to) +} + +type ScrollModuleL1FeeCoefficientSetIterator struct { + Event *ScrollModuleL1FeeCoefficientSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ScrollModuleL1FeeCoefficientSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ScrollModuleL1FeeCoefficientSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ScrollModuleL1FeeCoefficientSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ScrollModuleL1FeeCoefficientSetIterator) Error() error { + return it.fail +} + +func (it *ScrollModuleL1FeeCoefficientSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ScrollModuleL1FeeCoefficientSet struct { + Coefficient uint8 + Raw types.Log +} + +func (_ScrollModule *ScrollModuleFilterer) FilterL1FeeCoefficientSet(opts *bind.FilterOpts) (*ScrollModuleL1FeeCoefficientSetIterator, error) { + + logs, sub, err := _ScrollModule.contract.FilterLogs(opts, "L1FeeCoefficientSet") + if err != nil { + return nil, err + } + return &ScrollModuleL1FeeCoefficientSetIterator{contract: _ScrollModule.contract, event: "L1FeeCoefficientSet", logs: logs, sub: sub}, nil +} + +func (_ScrollModule *ScrollModuleFilterer) WatchL1FeeCoefficientSet(opts *bind.WatchOpts, sink chan<- *ScrollModuleL1FeeCoefficientSet) (event.Subscription, error) { + + logs, sub, err := _ScrollModule.contract.WatchLogs(opts, "L1FeeCoefficientSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ScrollModuleL1FeeCoefficientSet) + if err := _ScrollModule.contract.UnpackLog(event, "L1FeeCoefficientSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ScrollModule *ScrollModuleFilterer) ParseL1FeeCoefficientSet(log types.Log) (*ScrollModuleL1FeeCoefficientSet, error) { + event := new(ScrollModuleL1FeeCoefficientSet) + if err := _ScrollModule.contract.UnpackLog(event, "L1FeeCoefficientSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ScrollModuleOwnershipTransferRequestedIterator struct { + Event *ScrollModuleOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ScrollModuleOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ScrollModuleOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ScrollModuleOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ScrollModuleOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *ScrollModuleOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ScrollModuleOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_ScrollModule *ScrollModuleFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ScrollModuleOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ScrollModule.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &ScrollModuleOwnershipTransferRequestedIterator{contract: _ScrollModule.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_ScrollModule *ScrollModuleFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ScrollModuleOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ScrollModule.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ScrollModuleOwnershipTransferRequested) + if err := _ScrollModule.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ScrollModule *ScrollModuleFilterer) ParseOwnershipTransferRequested(log types.Log) (*ScrollModuleOwnershipTransferRequested, error) { + event := new(ScrollModuleOwnershipTransferRequested) + if err := _ScrollModule.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ScrollModuleOwnershipTransferredIterator struct { + Event *ScrollModuleOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ScrollModuleOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ScrollModuleOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ScrollModuleOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ScrollModuleOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *ScrollModuleOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ScrollModuleOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_ScrollModule *ScrollModuleFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ScrollModuleOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ScrollModule.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &ScrollModuleOwnershipTransferredIterator{contract: _ScrollModule.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_ScrollModule *ScrollModuleFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ScrollModuleOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ScrollModule.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ScrollModuleOwnershipTransferred) + if err := _ScrollModule.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_ScrollModule *ScrollModuleFilterer) ParseOwnershipTransferred(log types.Log) (*ScrollModuleOwnershipTransferred, error) { + event := new(ScrollModuleOwnershipTransferred) + if err := _ScrollModule.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type GetGasOverhead struct { ChainModuleFixedOverhead *big.Int ChainModulePerByteOverhead *big.Int } +func (_ScrollModule *ScrollModule) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _ScrollModule.abi.Events["L1FeeCoefficientSet"].ID: + return _ScrollModule.ParseL1FeeCoefficientSet(log) + case _ScrollModule.abi.Events["OwnershipTransferRequested"].ID: + return _ScrollModule.ParseOwnershipTransferRequested(log) + case _ScrollModule.abi.Events["OwnershipTransferred"].ID: + return _ScrollModule.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (ScrollModuleL1FeeCoefficientSet) Topic() common.Hash { + return common.HexToHash("0x29ec9e31de0d3fe0208a7ccb792bbc26a854f123146110daa3a77219cb74a554") +} + +func (ScrollModuleOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (ScrollModuleOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + func (_ScrollModule *ScrollModule) Address() common.Address { return _ScrollModule.address } @@ -301,7 +798,7 @@ type ScrollModuleInterface interface { BlockNumber(opts *bind.CallOpts) (*big.Int, error) - GetCurrentL1Fee(opts *bind.CallOpts) (*big.Int, error) + GetCurrentL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, @@ -309,5 +806,35 @@ type ScrollModuleInterface interface { GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) + Owner(opts *bind.CallOpts) (common.Address, error) + + SL1FeeCoefficient(opts *bind.CallOpts) (uint8, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + SetL1FeeCalculation(opts *bind.TransactOpts, coefficient uint8) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterL1FeeCoefficientSet(opts *bind.FilterOpts) (*ScrollModuleL1FeeCoefficientSetIterator, error) + + WatchL1FeeCoefficientSet(opts *bind.WatchOpts, sink chan<- *ScrollModuleL1FeeCoefficientSet) (event.Subscription, error) + + ParseL1FeeCoefficientSet(log types.Log) (*ScrollModuleL1FeeCoefficientSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ScrollModuleOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ScrollModuleOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*ScrollModuleOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ScrollModuleOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ScrollModuleOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*ScrollModuleOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + Address() common.Address } diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 3299989c58..ee2ad5867c 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,7 +1,7 @@ GETH_VERSION: 1.13.8 aggregator_v2v3_interface: ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV2V3Interface.abi ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV2V3Interface.bin 95e8814b408bb05bf21742ef580d98698b7db6a9bac6a35c3de12b23aec4ee28 aggregator_v3_interface: ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV3Interface.abi ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV3Interface.bin 351b55d3b0f04af67db6dfb5c92f1c64479400ca1fec77afc20bc0ce65cb49ab -arbitrum_module: ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.abi ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.bin b76cf77e3e8200c5f292e93af3f620f68f207f83634aacaaee43d682701dfea3 +arbitrum_module: ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.abi ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.bin 12a7bad1f887d832d101a73ae279a91a90c93fd72befea9983e85eff493f62f4 authorized_forwarder: ../../contracts/solc/v0.8.19/AuthorizedForwarder/AuthorizedForwarder.abi ../../contracts/solc/v0.8.19/AuthorizedForwarder/AuthorizedForwarder.bin 8ea76c883d460f8353a45a493f2aebeb5a2d9a7b4619d1bc4fff5fb590bb3e10 authorized_receiver: ../../contracts/solc/v0.8.19/AuthorizedReceiver/AuthorizedReceiver.abi ../../contracts/solc/v0.8.19/AuthorizedReceiver/AuthorizedReceiver.bin 18e8969ba3234b027e1b16c11a783aca58d0ea5c2361010ec597f134b7bf1c4f automation_compatible_utils: ../../contracts/solc/v0.8.19/AutomationCompatibleUtils/AutomationCompatibleUtils.abi ../../contracts/solc/v0.8.19/AutomationCompatibleUtils/AutomationCompatibleUtils.bin dfe88f4f40d124b8cb5f36a7e9f9328008ca57f7ec5d07a28d949d569d5f2834 @@ -12,10 +12,10 @@ automation_registrar_wrapper2_3: ../../contracts/solc/v0.8.19/AutomationRegistra automation_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 2f267fb8467a15c587ce4586ac56069f7229344ad3936430d7c7624c0528a171 automation_registry_logic_a_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.bin 73b5cc3ece642abbf6f2a4c9188335b71404f4dd0ad10b761390b6397af6f1c8 automation_registry_logic_b_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin a6d33dfbbfb0ff253eb59a51f4f6d6d4c22ea5ec95aae52d25d49a312b37a22f -automation_registry_logic_b_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.bin fbf6f6cf4e6858855ff5da847c3baa4859dd997cfae51f2fa0651e4fa15b92c9 -automation_registry_logic_c_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicC2_3/AutomationRegistryLogicC2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicC2_3/AutomationRegistryLogicC2_3.bin 6bfe0f54fa7a587a83b6981ffdef28b3cb5e24cae1c95becdf59eed21147d289 -automation_registry_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin de60f69878e9b32a291a001c91fc8636544c2cfbd9b507c8c1a4873b602bfb62 -automation_registry_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.bin f8f920a225fdb1e36948dd95bae3aa46ecc2b01fd113480e111960b5e5f95624 +automation_registry_logic_b_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.bin e628b4ba1ca8bf45c2b08c6b80f0b14efbd2dff13b85e5a9ebf643df32335ed2 +automation_registry_logic_c_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicC2_3/AutomationRegistryLogicC2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicC2_3/AutomationRegistryLogicC2_3.bin 19d59318e42f28777756eff60d5c5e52563a2fffb8e3f0f0b07b6d36d82b2c55 +automation_registry_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin 7072ba90159d84572f427ec816e78aa032cf907b39bf228185e0c446842f7c11 +automation_registry_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.bin b6163402434b84e3b66bc078f6efac121c1e1240dca0e8ea89c43db46b4e308b automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.bin 815b17b63f15d26a0274b962eefad98cdee4ec897ead58688bbb8e2470e585f5 automation_utils_2_2: ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.abi ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.bin 8743f6231aaefa3f2a0b2d484258070d506e2d0860690e66890dccc3949edb2e automation_utils_2_3: ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.abi ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.bin 11e2b481dc9a4d936e3443345d45d2cc571164459d214917b42a8054b295393b @@ -23,7 +23,7 @@ batch_blockhash_store: ../../contracts/solc/v0.8.19/BatchBlockhashStore/BatchBlo batch_vrf_coordinator_v2: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/BatchVRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/BatchVRFCoordinatorV2.bin 4512f4313bc5c078215c9241a69045a2a3cfecd6adfcef2f13037183a2d71483 batch_vrf_coordinator_v2plus: ../../contracts/solc/v0.8.19/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.19/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.bin f13715b38b5b9084b08bffa571fb1c8ef686001535902e1255052f074b31ad4e blockhash_store: ../../contracts/solc/v0.8.19/BlockhashStore/BlockhashStore.abi ../../contracts/solc/v0.8.19/BlockhashStore/BlockhashStore.bin 31b118f9577240c8834c35f8b5a1440e82a6ca8aea702970de2601824b6ab0e1 -chain_module_base: ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.abi ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.bin 39dfce79330e921e5c169051b11c6e5ea15cd4db5a7b09c06aabbe9658148915 +chain_module_base: ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.abi ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.bin c318d55aae33f370881fec220987a401a06ef7a0da834cea90a68749f85ac96f chain_reader_tester: ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.abi ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.bin b207f9e6bf71e445a2664a602677011b87b80bf95c6352fd7869f1a9ddb08a5b chain_specific_util_helper: ../../contracts/solc/v0.8.6/ChainSpecificUtilHelper/ChainSpecificUtilHelper.abi ../../contracts/solc/v0.8.6/ChainSpecificUtilHelper/ChainSpecificUtilHelper.bin 66eb30b0717fefe05672df5ec863c0b9a5a654623c4757307a2726d8f31e26b1 counter: ../../contracts/solc/v0.8.6/Counter/Counter.abi ../../contracts/solc/v0.8.6/Counter/Counter.bin 6ca06e000e8423573ffa0bdfda749d88236ab3da2a4cbb4a868c706da90488c9 @@ -35,7 +35,7 @@ gas_wrapper_mock: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageW i_automation_registry_master_wrapper_2_2: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin 9ff7087179f89f9b05964ebc3e71332fce11f1b8e85058f7b16b3bc0dd6fb96b i_automation_registry_master_wrapper_2_3: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.bin 06cc87c122452f63fbe84f65329978f30281613be0caa261e53503d94763e921 i_automation_v21_plus_common: ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.abi ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.bin e8a601ec382c0a2e83c49759de13b0622b5e04e6b95901e96a1e9504329e594c -i_chain_module: ../../contracts/solc/v0.8.19/IChainModule/IChainModule.abi ../../contracts/solc/v0.8.19/IChainModule/IChainModule.bin 383611981c86c70522f41b8750719faacc7d7933a22849d5004799ebef3371fa +i_chain_module: ../../contracts/solc/v0.8.19/IChainModule/IChainModule.abi ../../contracts/solc/v0.8.19/IChainModule/IChainModule.bin 17ed358d5635be8959c7dcdccc08d40b1fb1aa40a4d7624455dfb725d79ca7d9 i_keeper_registry_master_wrapper_2_1: ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.bin ee0f150b3afbab2df3d24ff3f4c87851efa635da30db04cd1f70cb4e185a1781 i_log_automation: ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.bin 296beccb6af655d6fc3a6e676b244831cce2da6688d3afc4f21f8738ae59e03e keeper_consumer_performance_wrapper: ../../contracts/solc/v0.8.16/KeeperConsumerPerformance/KeeperConsumerPerformance.abi ../../contracts/solc/v0.8.16/KeeperConsumerPerformance/KeeperConsumerPerformance.bin eeda39f5d3e1c8ffa0fb6cd1803731b98a4bc262d41833458e3fe8b40933ae90 @@ -60,9 +60,9 @@ mock_ethusd_aggregator_wrapper: ../../contracts/solc/v0.8.19/MockETHUSDAggregato offchain_aggregator_wrapper: OffchainAggregator/OffchainAggregator.abi - 5c8d6562e94166d4790f1ee6e4321d359d9f7262e6c5452a712b1f1c896f45cf operator_factory: ../../contracts/solc/v0.8.19/OperatorFactory/OperatorFactory.abi ../../contracts/solc/v0.8.19/OperatorFactory/OperatorFactory.bin 88e6baa5d9b255eea02616fbcb2cbe21a25ab46adeb6395f6289d169dec949ae operator_wrapper: ../../contracts/solc/v0.8.19/Operator/Operator.abi ../../contracts/solc/v0.8.19/Operator/Operator.bin 23c3888eaa7259e6adf2153d09abae8f4b1987dc44200363faab1e65483f32d5 -optimism_module: ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.abi ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.bin a1f8ee97e12b1b2311db03b94dc52b91f3c2e9a2f8d554031a9c7b41e4432280 +optimism_module: ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.abi ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.bin fb34a04d32c6f4ccc860962b740bfde91e5bdfd88cbac0711b41f25f6fd23a85 perform_data_checker_wrapper: ../../contracts/solc/v0.8.16/PerformDataChecker/PerformDataChecker.abi ../../contracts/solc/v0.8.16/PerformDataChecker/PerformDataChecker.bin 48d8309c2117c29a24e1155917ab0b780956b2cd6a8a39ef06ae66a7f6d94f73 -scroll_module: ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.abi ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.bin 8de157cb7e5bc78146548212803d60926c8483aca7e912d802b7c66dc5d2ab11 +scroll_module: ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.abi ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.bin ddd46b32aa5eb8dc252b10391f6c3345a4c80445c6c058257ceb16eccc074268 simple_log_upkeep_counter_wrapper: ../../contracts/solc/v0.8.6/SimpleLogUpkeepCounter/SimpleLogUpkeepCounter.abi ../../contracts/solc/v0.8.6/SimpleLogUpkeepCounter/SimpleLogUpkeepCounter.bin 7557d117a066cd8cf35f635bc085ee11795442073c18f8610ede9037b74fd814 solidity_vrf_consumer_interface_v08: ../../contracts/solc/v0.8.6/VRFConsumer/VRFConsumer.abi ../../contracts/solc/v0.8.6/VRFConsumer/VRFConsumer.bin b14f9136b15e3dc9d6154d5700f3ed4cf88ddc4f70f20c3bb57fc46050904c8f solidity_vrf_request_id_v08: ../../contracts/solc/v0.8.6/VRFRequestIDBaseTestHelper/VRFRequestIDBaseTestHelper.abi ../../contracts/solc/v0.8.6/VRFRequestIDBaseTestHelper/VRFRequestIDBaseTestHelper.bin f2559015d6f3e5d285c57b011be9b2300632e93dd6c4524e58202d6200f09edc From e76463cfa9a0fbe6e35a74cbb3f7d63c85efcd88 Mon Sep 17 00:00:00 2001 From: Silas Lenihan <32529249+silaslenihan@users.noreply.github.com> Date: Wed, 21 Aug 2024 15:14:18 -0400 Subject: [PATCH 129/432] Fix: Add hexutil Bytes encoding to batchcall data (#14165) --- .changeset/odd-eagles-shave.md | 5 +++++ core/services/relay/evm/batch_caller.go | 2 +- core/services/relay/evm/batch_caller_test.go | 8 +++----- 3 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 .changeset/odd-eagles-shave.md diff --git a/.changeset/odd-eagles-shave.md b/.changeset/odd-eagles-shave.md new file mode 100644 index 0000000000..0c68bc1573 --- /dev/null +++ b/.changeset/odd-eagles-shave.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#internal Add hexutil Bytes encoding to batchcall data diff --git a/core/services/relay/evm/batch_caller.go b/core/services/relay/evm/batch_caller.go index 53edc49eaa..ce5a2bd722 100644 --- a/core/services/relay/evm/batch_caller.go +++ b/core/services/relay/evm/batch_caller.go @@ -149,7 +149,7 @@ func (c *defaultEvmBatchCaller) batchCall(ctx context.Context, blockNumber uint6 map[string]interface{}{ "from": common.Address{}, "to": call.ContractAddress, - "data": data, + "data": hexutil.Bytes(data), }, blockNumStr, }, diff --git a/core/services/relay/evm/batch_caller_test.go b/core/services/relay/evm/batch_caller_test.go index 995e47618c..048df90dab 100644 --- a/core/services/relay/evm/batch_caller_test.go +++ b/core/services/relay/evm/batch_caller_test.go @@ -1,12 +1,12 @@ package evm_test import ( - "encoding/hex" "fmt" "math/big" "testing" "github.com/cometbft/cometbft/libs/rand" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rpc" "github.com/pkg/errors" "github.com/stretchr/testify/assert" @@ -152,12 +152,10 @@ func TestDefaultEvmBatchCaller_batchCallLimit(t *testing.T) { Run(func(args mock.Arguments) { evmCalls := args.Get(1).([]rpc.BatchElem) for i := range evmCalls { - arg := evmCalls[i].Args[0].(map[string]interface{})["data"].([]uint8) - bytes, err := hex.DecodeString(fmt.Sprintf("%x", arg)) - require.NoError(t, err) + arg := evmCalls[i].Args[0].(map[string]interface{})["data"].(hexutil.Bytes) str, isOk := evmCalls[i].Result.(*string) require.True(t, isOk) - *str = fmt.Sprintf("0x%064x", new(big.Int).SetBytes(bytes[24:]).Uint64()) + *str = fmt.Sprintf("0x%064x", new(big.Int).SetBytes(arg[24:]).Uint64()) } }).Return(nil) From fdf9d10ebc6ae1f8f5d0446060ffa830d8f202f3 Mon Sep 17 00:00:00 2001 From: momentmaker Date: Wed, 21 Aug 2024 14:24:03 -0500 Subject: [PATCH 130/432] refactor: build-publish-develop-pr workflow to not split (#14187) * refactor: build-publish-develop-pr workflow to not split * fix metrics job name --------- Co-authored-by: Lukasz <120112546+lukaszcl@users.noreply.github.com> --- .github/workflows/build-publish-develop-pr.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-publish-develop-pr.yml b/.github/workflows/build-publish-develop-pr.yml index b1b9db67c6..0b75b6c477 100644 --- a/.github/workflows/build-publish-develop-pr.yml +++ b/.github/workflows/build-publish-develop-pr.yml @@ -25,9 +25,6 @@ jobs: permissions: id-token: write contents: read - strategy: - matrix: - goarch: [amd64, arm64] steps: - name: Checkout repository uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 @@ -36,7 +33,7 @@ jobs: # This gets the image tag and whether to publish the image based on the event type # PR builds: pr-- (if label 'build-publish' is present publishes the image) - # develop builds: develop- + # develop builds: develop- and develop (only amd64) # release builds: release- # manual builds: (if build-publish is true publishes the image) - name: Get image tag @@ -81,8 +78,6 @@ jobs: docker-image-name: chainlink docker-image-tag: ${{ steps.get-image-tag.outputs.image-tag }} enable-goreleaser-snapshot: "true" - enable-goreleaser-split: "true" - goreleaser-split-arch: ${{ matrix.goarch }} goreleaser-exec: ./tools/bin/goreleaser_wrapper goreleaser-config: .goreleaser.develop.yaml goreleaser-key: ${{ secrets.GORELEASER_KEY }} @@ -92,7 +87,7 @@ jobs: if: steps.get-image-tag.outputs.build-publish == 'true' shell: bash run: | - # need to check if artifacts.json exists because goreleaser splits the build + # need to check if artifacts.json exists because goreleaser could split the build if [[ -f dist/artifacts.json ]]; then artifact_path="dist/artifacts.json" else @@ -115,5 +110,5 @@ jobs: org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: goreleaser-build-publish-chainlink (${{ matrix.goarch }}) + this-job-name: goreleaser-build-publish-chainlink continue-on-error: true \ No newline at end of file From ee57b4f940b8a9d9d7bba41a74e4757874755f5f Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Wed, 21 Aug 2024 20:41:08 +0100 Subject: [PATCH 131/432] item 4 - topeerid should validate []byte length (#14181) Co-authored-by: Bolek <1416262+bolekk@users.noreply.github.com> --- .changeset/tender-wombats-juggle.md | 5 +++++ core/capabilities/remote/target/request/client_request.go | 5 ++++- core/capabilities/remote/target/request/server_request.go | 6 +++++- core/capabilities/remote/trigger_publisher.go | 7 ++++++- core/capabilities/remote/trigger_subscriber.go | 7 ++++++- core/capabilities/remote/utils.go | 8 ++++++-- core/capabilities/remote/utils_test.go | 3 ++- 7 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 .changeset/tender-wombats-juggle.md diff --git a/.changeset/tender-wombats-juggle.md b/.changeset/tender-wombats-juggle.md new file mode 100644 index 0000000000..08f256f4be --- /dev/null +++ b/.changeset/tender-wombats-juggle.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal topeerid should validate []byte length diff --git a/core/capabilities/remote/target/request/client_request.go b/core/capabilities/remote/target/request/client_request.go index 0370fd229c..c9f76fb25a 100644 --- a/core/capabilities/remote/target/request/client_request.go +++ b/core/capabilities/remote/target/request/client_request.go @@ -140,7 +140,10 @@ func (c *ClientRequest) OnMessage(_ context.Context, msg *types.MessageBody) err c.lggr.Debugw("OnMessage called for client request", "messageID", msg.MessageId) - sender := remote.ToPeerID(msg.Sender) + sender, err := remote.ToPeerID(msg.Sender) + if err != nil { + return fmt.Errorf("failed to convert message sender to PeerID: %w", err) + } received, expected := c.responseReceived[sender] if !expected { diff --git a/core/capabilities/remote/target/request/server_request.go b/core/capabilities/remote/target/request/server_request.go index 16e90a034b..4aaee11854 100644 --- a/core/capabilities/remote/target/request/server_request.go +++ b/core/capabilities/remote/target/request/server_request.go @@ -74,7 +74,11 @@ func (e *ServerRequest) OnMessage(ctx context.Context, msg *types.MessageBody) e return fmt.Errorf("sender missing from message") } - requester := remote.ToPeerID(msg.Sender) + requester, err := remote.ToPeerID(msg.Sender) + if err != nil { + return fmt.Errorf("failed to convert message sender to PeerID: %w", err) + } + if err := e.addRequester(requester); err != nil { return fmt.Errorf("failed to add requester to request: %w", err) } diff --git a/core/capabilities/remote/trigger_publisher.go b/core/capabilities/remote/trigger_publisher.go index 4aac821bc1..ad0b9b27c6 100644 --- a/core/capabilities/remote/trigger_publisher.go +++ b/core/capabilities/remote/trigger_publisher.go @@ -87,7 +87,12 @@ func (p *triggerPublisher) Start(ctx context.Context) error { } func (p *triggerPublisher) Receive(_ context.Context, msg *types.MessageBody) { - sender := ToPeerID(msg.Sender) + sender, err := ToPeerID(msg.Sender) + if err != nil { + p.lggr.Errorw("failed to convert message sender to PeerID", "err", err) + return + } + if msg.Method == types.MethodRegisterTrigger { req, err := pb.UnmarshalCapabilityRequest(msg.Payload) if err != nil { diff --git a/core/capabilities/remote/trigger_subscriber.go b/core/capabilities/remote/trigger_subscriber.go index c932dc68e3..f880735f4f 100644 --- a/core/capabilities/remote/trigger_subscriber.go +++ b/core/capabilities/remote/trigger_subscriber.go @@ -175,7 +175,12 @@ func (s *triggerSubscriber) UnregisterTrigger(ctx context.Context, request commo } func (s *triggerSubscriber) Receive(_ context.Context, msg *types.MessageBody) { - sender := ToPeerID(msg.Sender) + sender, err := ToPeerID(msg.Sender) + if err != nil { + s.lggr.Errorw("failed to convert message sender to PeerID", "err", err) + return + } + if _, found := s.capDonMembers[sender]; !found { s.lggr.Errorw("received message from unexpected node", "capabilityId", s.capInfo.ID, "sender", sender) return diff --git a/core/capabilities/remote/utils.go b/core/capabilities/remote/utils.go index c77ef67916..a1fe4dcb84 100644 --- a/core/capabilities/remote/utils.go +++ b/core/capabilities/remote/utils.go @@ -48,10 +48,14 @@ func ValidateMessage(msg p2ptypes.Message, expectedReceiver p2ptypes.PeerID) (*r return &body, nil } -func ToPeerID(peerID []byte) p2ptypes.PeerID { +func ToPeerID(peerID []byte) (p2ptypes.PeerID, error) { + if len(peerID) != p2ptypes.PeerIDLength { + return p2ptypes.PeerID{}, fmt.Errorf("invalid peer ID length: %d", len(peerID)) + } + var id p2ptypes.PeerID copy(id[:], peerID) - return id + return id, nil } // Default MODE Aggregator needs a configurable number of identical responses for aggregation to succeed diff --git a/core/capabilities/remote/utils_test.go b/core/capabilities/remote/utils_test.go index 1213507336..4a38a226e5 100644 --- a/core/capabilities/remote/utils_test.go +++ b/core/capabilities/remote/utils_test.go @@ -84,7 +84,8 @@ func encodeAndSign(t *testing.T, senderPrivKey ed25519.PrivateKey, senderId p2pt } func TestToPeerID(t *testing.T) { - id := remote.ToPeerID([]byte("12345678901234567890123456789012")) + id, err := remote.ToPeerID([]byte("12345678901234567890123456789012")) + require.NoError(t, err) require.Equal(t, "12D3KooWD8QYTQVYjB6oog4Ej8PcPpqTrPRnxLQap8yY8KUQRVvq", id.String()) } From 5b9d92d39f9882bcd1823b25776828eb7f2d9cc6 Mon Sep 17 00:00:00 2001 From: Balamurali Gopalswami <167726375+b-gopalswami@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:40:22 -0400 Subject: [PATCH 132/432] Fix flakey ccipreader_test as per CCIP pr 1337 (#14189) --- .../ccipreader/ccipreader_test.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go index 66c47f4741..e0de0b801d 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go @@ -3,6 +3,7 @@ package ccipreader import ( "context" "math/big" + "sort" "testing" "time" @@ -110,7 +111,7 @@ func TestCCIPReader_CommitReportsGTETimestamp(t *testing.T) { ) require.NoError(t, err) return len(reports) == numReports-1 - }, testutils.WaitTimeout(t), 50*time.Millisecond) + }, 10*time.Second, 50*time.Millisecond) assert.Len(t, reports[0].Report.MerkleRoots, 1) assert.Equal(t, chainS1, reports[0].Report.MerkleRoots[0].ChainSel) @@ -250,6 +251,10 @@ func TestCCIPReader_MsgsBetweenSeqNums(t *testing.T) { s.sb.Commit() + // Need to replay as sometimes the logs are not picked up by the log poller (?) + // Maybe another situation where chain reader doesn't register filters as expected. + require.NoError(t, s.lp.Replay(ctx, 1)) + var msgs []cciptypes.Message require.Eventually(t, func() bool { msgs, err = s.reader.MsgsBetweenSeqNums( @@ -262,6 +267,10 @@ func TestCCIPReader_MsgsBetweenSeqNums(t *testing.T) { }, 10*time.Second, 100*time.Millisecond) require.Len(t, msgs, 2) + // sort to ensure ascending order of sequence numbers. + sort.Slice(msgs, func(i, j int) bool { + return msgs[i].Header.SequenceNumber < msgs[j].Header.SequenceNumber + }) require.Equal(t, cciptypes.SeqNum(10), msgs[0].Header.SequenceNumber) require.Equal(t, cciptypes.SeqNum(15), msgs[1].Header.SequenceNumber) for _, msg := range msgs { From c098805f82f1ce385254d0743325b3d330caf6ac Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Wed, 21 Aug 2024 17:14:43 -0400 Subject: [PATCH 133/432] =?UTF-8?q?devsvcs-130:=20add=20an=20optimism=20mo?= =?UTF-8?q?dule=20v2=20to=20reduce=20gas=20cost=20to=20estimate=E2=80=A6?= =?UTF-8?q?=20(#14151)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * devsvcs-168: fix chain module l1 fee calculation * Update gethwrappers * devsvcs-130: add an optimism module v2 to reduce gas cost to estimate l1 fee * Update gethwrappers * fix version * go gen * update * update * update * remove op module abi --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .../native_solc_compile_all_automation | 2 +- .../automation/chains/ChainModuleBase.sol | 4 +- .../v0.8/automation/chains/OptimismModule.sol | 11 +- .../automation/chains/OptimismModuleV2.sol | 78 ++ .../v0.8/automation/chains/ScrollModule.sol | 19 +- .../automation/interfaces/IChainModule.sol | 45 +- .../src/v0.8/tests/MockOVMGasPriceOracle.sol | 7 +- .../automation/AutomationRegistry2_2.test.ts | 13 +- .../automation/AutomationRegistry2_3.test.ts | 10 +- .../chain_module_base/chain_module_base.go | 2 +- .../i_chain_module/i_chain_module.go | 16 +- .../optimism_module_v2/optimism_module_v2.go | 840 ++++++++++++++++++ .../generated/scroll_module/scroll_module.go | 52 +- ...rapper-dependency-versions-do-not-edit.txt | 8 +- core/gethwrappers/go_generate.go | 2 +- 15 files changed, 1035 insertions(+), 74 deletions(-) create mode 100644 contracts/src/v0.8/automation/chains/OptimismModuleV2.sol create mode 100644 core/gethwrappers/generated/optimism_module_v2/optimism_module_v2.go diff --git a/contracts/scripts/native_solc_compile_all_automation b/contracts/scripts/native_solc_compile_all_automation index 29326a15c0..e189e78cb0 100755 --- a/contracts/scripts/native_solc_compile_all_automation +++ b/contracts/scripts/native_solc_compile_all_automation @@ -93,7 +93,7 @@ compileContract automation/v2_2/AutomationUtils2_2.sol compileContract automation/interfaces/v2_2/IAutomationRegistryMaster.sol compileContract automation/chains/ArbitrumModule.sol compileContract automation/chains/ChainModuleBase.sol -compileContract automation/chains/OptimismModule.sol +compileContract automation/chains/OptimismModuleV2.sol compileContract automation/chains/ScrollModule.sol compileContract automation/interfaces/IChainModule.sol compileContract automation/interfaces/IAutomationV21PlusCommon.sol diff --git a/contracts/src/v0.8/automation/chains/ChainModuleBase.sol b/contracts/src/v0.8/automation/chains/ChainModuleBase.sol index 52829d43e5..c595dbd640 100644 --- a/contracts/src/v0.8/automation/chains/ChainModuleBase.sol +++ b/contracts/src/v0.8/automation/chains/ChainModuleBase.sol @@ -18,11 +18,11 @@ contract ChainModuleBase is IChainModule { return blockhash(n); } - function getCurrentL1Fee(uint256) external view virtual returns (uint256) { + function getCurrentL1Fee(uint256) external view virtual returns (uint256 l1Fee) { return 0; } - function getMaxL1Fee(uint256) external view virtual returns (uint256) { + function getMaxL1Fee(uint256) external view virtual returns (uint256 maxL1Fee) { return 0; } diff --git a/contracts/src/v0.8/automation/chains/OptimismModule.sol b/contracts/src/v0.8/automation/chains/OptimismModule.sol index c108bed008..7a46429496 100644 --- a/contracts/src/v0.8/automation/chains/OptimismModule.sol +++ b/contracts/src/v0.8/automation/chains/OptimismModule.sol @@ -4,6 +4,10 @@ pragma solidity 0.8.19; import {OVM_GasPriceOracle} from "../../vendor/@eth-optimism/contracts/v0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; import {ChainModuleBase} from "./ChainModuleBase.sol"; +/** + * @notice This contract is deprecated. Please use OptimismModuleV2 which utilizes the most recent offerings from OP + * and can estimate L1 fee with much lower cost. + */ contract OptimismModule is ChainModuleBase { /// @dev OP_L1_DATA_FEE_PADDING includes 80 bytes for L1 data padding for Optimism and BASE bytes private constant OP_L1_DATA_FEE_PADDING = @@ -25,10 +29,15 @@ contract OptimismModule is ChainModuleBase { return _getL1Fee(dataSize); } + /* @notice this function provides an estimation for L1 fee incurred by calldata of a certain size + * @dev this function uses the getL1Fee function in OP gas price oracle. it estimates the exact L1 fee but it costs + * a lot of gas to call. + * @param dataSize the size of calldata + * @return l1Fee the L1 fee + */ function _getL1Fee(uint256 dataSize) internal view returns (uint256) { // fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have all non zero-bytes. // Instead of setting bytes to non-zero, we initialize 'new bytes' of length 4*dataSize to cover for zero bytes. - // this is the same as OP. bytes memory txCallData = new bytes(4 * dataSize); return OVM_GASPRICEORACLE.getL1Fee(bytes.concat(txCallData, OP_L1_DATA_FEE_PADDING)); } diff --git a/contracts/src/v0.8/automation/chains/OptimismModuleV2.sol b/contracts/src/v0.8/automation/chains/OptimismModuleV2.sol new file mode 100644 index 0000000000..772b66cdf9 --- /dev/null +++ b/contracts/src/v0.8/automation/chains/OptimismModuleV2.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {GasPriceOracle as OVM_GasPriceOracle} from "../../vendor/@eth-optimism/contracts-bedrock/v0.17.3/src/L2/GasPriceOracle.sol"; +import {ChainModuleBase} from "./ChainModuleBase.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; + +/** + * @notice OptimismModuleV2 provides a cost-efficient way to get L1 fee on OP stack. + * After EIP-4844 is implemented in OP stack, the new OP upgrade includes a new function getL1FeeUpperBound to estimate + * the upper bound of current transaction's L1 fee. + */ +contract OptimismModuleV2 is ChainModuleBase, ConfirmedOwner { + error InvalidL1FeeCoefficient(uint8 coefficient); + event L1FeeCoefficientSet(uint8 coefficient); + + /// @dev OVM_GASPRICEORACLE_ADDR is the address of the OVM_GasPriceOracle precompile on Optimism. + /// @dev reference: https://community.optimism.io/docs/developers/build/transaction-fees/#estimating-the-l1-data-fee + address private constant OVM_GASPRICEORACLE_ADDR = address(0x420000000000000000000000000000000000000F); + OVM_GasPriceOracle private constant OVM_GASPRICEORACLE = OVM_GasPriceOracle(OVM_GASPRICEORACLE_ADDR); + + /// @dev L1 fee coefficient is used to account for the impact of data compression on the l1 fee + /// getL1FeeUpperBound returns the upper bound of l1 fee so this configurable coefficient will help + /// charge a predefined percentage of the upper bound. + uint8 private s_l1FeeCoefficient = 100; + uint256 private constant FIXED_GAS_OVERHEAD = 28_000; + uint256 private constant PER_CALLDATA_BYTE_GAS_OVERHEAD = 0; + + constructor() ConfirmedOwner(msg.sender) {} + + function getCurrentL1Fee(uint256 dataSize) external view override returns (uint256) { + return (s_l1FeeCoefficient * _getL1Fee(dataSize)) / 100; + } + + function getMaxL1Fee(uint256 dataSize) external view override returns (uint256) { + return _getL1Fee(dataSize); + } + + /* @notice this function provides an estimation for L1 fee incurred by calldata of a certain size + * @dev this function uses the newly provided getL1FeeUpperBound function in OP gas price oracle. this helps + * estimate L1 fee with much lower cost + * @param dataSize the size of calldata + * @return l1Fee the L1 fee + */ + function _getL1Fee(uint256 dataSize) internal view returns (uint256) { + return OVM_GASPRICEORACLE.getL1FeeUpperBound(dataSize); + } + + function getGasOverhead() + external + pure + override + returns (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead) + { + return (FIXED_GAS_OVERHEAD, PER_CALLDATA_BYTE_GAS_OVERHEAD); + } + + /* @notice this function sets a new coefficient for L1 fee estimation. + * @dev this function can only be invoked by contract owner + * @param coefficient the new coefficient + */ + function setL1FeeCalculation(uint8 coefficient) external onlyOwner { + if (coefficient > 100) { + revert InvalidL1FeeCoefficient(coefficient); + } + + s_l1FeeCoefficient = coefficient; + + emit L1FeeCoefficientSet(coefficient); + } + + /* @notice this function returns the s_l1FeeCoefficient + * @return coefficient the current s_l1FeeCoefficient in effect + */ + function getL1FeeCoefficient() public view returns (uint256 coefficient) { + return s_l1FeeCoefficient; + } +} diff --git a/contracts/src/v0.8/automation/chains/ScrollModule.sol b/contracts/src/v0.8/automation/chains/ScrollModule.sol index 5a1373b372..30fdc908d4 100644 --- a/contracts/src/v0.8/automation/chains/ScrollModule.sol +++ b/contracts/src/v0.8/automation/chains/ScrollModule.sol @@ -20,7 +20,7 @@ contract ScrollModule is ChainModuleBase, ConfirmedOwner { IScrollL1GasPriceOracle private constant SCROLL_ORACLE = IScrollL1GasPriceOracle(SCROLL_ORACLE_ADDR); /// @dev L1 fee coefficient can be applied to reduce possibly inflated gas cost - uint8 public s_l1FeeCoefficient = 100; + uint8 private s_l1FeeCoefficient = 100; uint256 private constant FIXED_GAS_OVERHEAD = 45_000; uint256 private constant PER_CALLDATA_BYTE_GAS_OVERHEAD = 170; @@ -34,7 +34,11 @@ contract ScrollModule is ChainModuleBase, ConfirmedOwner { return _getL1Fee(dataSize); } - function _getL1Fee(uint256 dataSize) internal view returns (uint256) { + /* @notice this function provides an estimation for L1 fee incurred by calldata of a certain size + * @param dataSize the size of calldata + * @return l1Fee the L1 fee + */ + function _getL1Fee(uint256 dataSize) internal view returns (uint256 l1Fee) { // fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have all non zero-bytes. // Instead of setting bytes to non-zero, we initialize 'new bytes' of length 4*dataSize to cover for zero bytes. // this is the same as OP. @@ -51,6 +55,10 @@ contract ScrollModule is ChainModuleBase, ConfirmedOwner { return (FIXED_GAS_OVERHEAD, PER_CALLDATA_BYTE_GAS_OVERHEAD); } + /* @notice this function sets a new coefficient for L1 fee estimation. + * @dev this function can only be invoked by contract owner + * @param coefficient the new coefficient + */ function setL1FeeCalculation(uint8 coefficient) external onlyOwner { if (coefficient > 100) { revert InvalidL1FeeCoefficient(coefficient); @@ -60,4 +68,11 @@ contract ScrollModule is ChainModuleBase, ConfirmedOwner { emit L1FeeCoefficientSet(coefficient); } + + /* @notice this function returns the s_l1FeeCoefficient + * @return coefficient the current s_l1FeeCoefficient in effect + */ + function getL1FeeCoefficient() public view returns (uint256 coefficient) { + return s_l1FeeCoefficient; + } } diff --git a/contracts/src/v0.8/automation/interfaces/IChainModule.sol b/contracts/src/v0.8/automation/interfaces/IChainModule.sol index 47d5b25111..15e84f7984 100644 --- a/contracts/src/v0.8/automation/interfaces/IChainModule.sol +++ b/contracts/src/v0.8/automation/interfaces/IChainModule.sol @@ -2,26 +2,39 @@ pragma solidity ^0.8.0; interface IChainModule { - // retrieve the native block number of a chain. e.g. L2 block number on Arbitrum - function blockNumber() external view returns (uint256); + /* @notice this function provides the block number of current chain. + * @dev certain chains have its own function to retrieve block number, e.g. Arbitrum + * @return blockNumber the block number of the current chain. + */ + function blockNumber() external view returns (uint256 blockNumber); - // retrieve the native block hash of a chain. - function blockHash(uint256) external view returns (bytes32); + /* @notice this function provides the block hash of a block number. + * @dev this function can usually look back 256 blocks at most, unless otherwise specified + * @param blockNumber the block number + * @return blockHash the block hash of the input block number + */ + function blockHash(uint256 blockNumber) external view returns (bytes32 blockHash); - // retrieve the L1 data fee for a L2 transaction. it should return 0 for L1 chains and - // L2 chains which don't have L1 fee component. it uses msg.data to estimate L1 data so - // it must be used with a transaction. Return value in wei. - function getCurrentL1Fee(uint256 dataSize) external view returns (uint256); + /* @notice this function provides the L1 fee of current transaction. + * @dev retrieve the L1 data fee for a L2 transaction. it should return 0 for L1 chains. it should + * return 0 for L2 chains if they don't have L1 fee component. + * @param dataSize the calldata size of the current transaction + * @return l1Fee the L1 fee in wei incurred by calldata of this data size + */ + function getCurrentL1Fee(uint256 dataSize) external view returns (uint256 l1Fee); - // retrieve the L1 data fee for a L2 simulation. it should return 0 for L1 chains and - // L2 chains which don't have L1 fee component. Return value in wei. - function getMaxL1Fee(uint256 dataSize) external view returns (uint256); + /* @notice this function provides the max possible L1 fee of current transaction. + * @dev retrieve the max possible L1 data fee for a L2 transaction. it should return 0 for L1 chains. it should + * return 0 for L2 chains if they don't have L1 fee component. + * @param dataSize the calldata size of the current transaction + * @return maxL1Fee the max possible L1 fee in wei incurred by calldata of this data size + */ + function getMaxL1Fee(uint256 dataSize) external view returns (uint256 maxL1Fee); - // Returns an upper bound on execution gas cost for one invocation of blockNumber(), - // one invocation of blockHash() and one invocation of getCurrentL1Fee(). - // Returns two values, first value indicates a fixed cost and the second value is - // the cost per msg.data byte (As some chain module's getCurrentL1Fee execution cost - // scales with calldata size) + /* @notice this function provides the overheads of calling this chain module. + * @return chainModuleFixedOverhead the fixed overhead incurred by calling this chain module + * @return chainModulePerByteOverhead the fixed overhead per byte incurred by calling this chain module with calldata + */ function getGasOverhead() external view diff --git a/contracts/src/v0.8/tests/MockOVMGasPriceOracle.sol b/contracts/src/v0.8/tests/MockOVMGasPriceOracle.sol index 29790b0e15..6bb0dae645 100644 --- a/contracts/src/v0.8/tests/MockOVMGasPriceOracle.sol +++ b/contracts/src/v0.8/tests/MockOVMGasPriceOracle.sol @@ -1,7 +1,12 @@ +// SPDX-License-Identifier: MIT pragma solidity 0.8.6; contract MockOVMGasPriceOracle { - function getL1Fee(bytes memory _data) public view returns (uint256) { + function getL1Fee(bytes memory) public pure returns (uint256) { + return 2000000; + } + + function getL1FeeUpperBound(uint256) public pure returns (uint256) { return 2000000; } } diff --git a/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts b/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts index 62733bcad4..6b220f2f7c 100644 --- a/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts +++ b/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts @@ -23,7 +23,7 @@ import { MockArbGasInfo__factory as MockArbGasInfoFactory } from '../../../typec import { MockOVMGasPriceOracle__factory as MockOVMGasPriceOracleFactory } from '../../../typechain/factories/MockOVMGasPriceOracle__factory' import { ChainModuleBase__factory as ChainModuleBaseFactory } from '../../../typechain/factories/ChainModuleBase__factory' import { ArbitrumModule__factory as ArbitrumModuleFactory } from '../../../typechain/factories/ArbitrumModule__factory' -import { OptimismModule__factory as OptimismModuleFactory } from '../../../typechain/factories/OptimismModule__factory' +import { OptimismModuleV2__factory as OptimismModuleV2Factory } from '../../../typechain/factories/OptimismModuleV2__factory' import { ILogAutomation__factory as ILogAutomationactory } from '../../../typechain/factories/ILogAutomation__factory' import { IAutomationForwarder__factory as IAutomationForwarderFactory } from '../../../typechain/factories/IAutomationForwarder__factory' import { MockArbSys__factory as MockArbSysFactory } from '../../../typechain/factories/MockArbSys__factory' @@ -35,7 +35,7 @@ import { MockV3Aggregator } from '../../../typechain/MockV3Aggregator' import { UpkeepMock } from '../../../typechain/UpkeepMock' import { ChainModuleBase } from '../../../typechain/ChainModuleBase' import { ArbitrumModule } from '../../../typechain/ArbitrumModule' -import { OptimismModule } from '../../../typechain/OptimismModule' +import { OptimismModuleV2 } from '../../../typechain/OptimismModuleV2' import { UpkeepTranscoder } from '../../../typechain/UpkeepTranscoder' import { IChainModule, UpkeepAutoFunder } from '../../../typechain' import { @@ -148,7 +148,7 @@ let upkeepMockFactory: UpkeepMockFactory let upkeepAutoFunderFactory: UpkeepAutoFunderFactory let chainModuleBaseFactory: ChainModuleBaseFactory let arbitrumModuleFactory: ArbitrumModuleFactory -let optimismModuleFactory: OptimismModuleFactory +let optimismModuleV2Factory: OptimismModuleV2Factory let streamsLookupUpkeepFactory: StreamsLookupUpkeepFactory let personas: Personas @@ -169,7 +169,7 @@ let ltUpkeep: MockContract let transcoder: UpkeepTranscoder let chainModuleBase: ChainModuleBase let arbitrumModule: ArbitrumModule -let optimismModule: OptimismModule +let optimismModule: OptimismModuleV2 let streamsLookupUpkeep: StreamsLookupUpkeep let automationUtils: AutomationCompatibleUtils @@ -430,7 +430,8 @@ describe('AutomationRegistry2_2', () => { await ethers.getContractFactory('UpkeepAutoFunder') chainModuleBaseFactory = await ethers.getContractFactory('ChainModuleBase') arbitrumModuleFactory = await ethers.getContractFactory('ArbitrumModule') - optimismModuleFactory = await ethers.getContractFactory('OptimismModule') + optimismModuleV2Factory = + await ethers.getContractFactory('OptimismModuleV2') streamsLookupUpkeepFactory = await ethers.getContractFactory( 'StreamsLookupUpkeep', ) @@ -844,7 +845,7 @@ describe('AutomationRegistry2_2', () => { .deploy() chainModuleBase = await chainModuleBaseFactory.connect(owner).deploy() arbitrumModule = await arbitrumModuleFactory.connect(owner).deploy() - optimismModule = await optimismModuleFactory.connect(owner).deploy() + optimismModule = await optimismModuleV2Factory.connect(owner).deploy() streamsLookupUpkeep = await streamsLookupUpkeepFactory .connect(owner) .deploy( diff --git a/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts b/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts index 3f28a4410b..f3c2d9bb98 100644 --- a/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts +++ b/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts @@ -23,7 +23,7 @@ import { MockArbGasInfo__factory as MockArbGasInfoFactory } from '../../../typec import { MockOVMGasPriceOracle__factory as MockOVMGasPriceOracleFactory } from '../../../typechain/factories/MockOVMGasPriceOracle__factory' import { ChainModuleBase__factory as ChainModuleBaseFactory } from '../../../typechain/factories/ChainModuleBase__factory' import { ArbitrumModule__factory as ArbitrumModuleFactory } from '../../../typechain/factories/ArbitrumModule__factory' -import { OptimismModule__factory as OptimismModuleFactory } from '../../../typechain/factories/OptimismModule__factory' +import { OptimismModuleV2__factory as OptimismModuleV2Factory } from '../../../typechain/factories/OptimismModuleV2__factory' import { ILogAutomation__factory as ILogAutomationactory } from '../../../typechain/factories/ILogAutomation__factory' import { MockArbSys__factory as MockArbSysFactory } from '../../../typechain/factories/MockArbSys__factory' import { AutomationCompatibleUtils } from '../../../typechain/AutomationCompatibleUtils' @@ -34,7 +34,7 @@ import { MockV3Aggregator } from '../../../typechain/MockV3Aggregator' import { UpkeepMock } from '../../../typechain/UpkeepMock' import { ChainModuleBase } from '../../../typechain/ChainModuleBase' import { ArbitrumModule } from '../../../typechain/ArbitrumModule' -import { OptimismModule } from '../../../typechain/OptimismModule' +import { OptimismModuleV2 } from '../../../typechain/OptimismModuleV2' import { UpkeepTranscoder } from '../../../typechain/UpkeepTranscoder' import { IChainModule, UpkeepAutoFunder } from '../../../typechain' import { @@ -152,7 +152,7 @@ let upkeepMockFactory: UpkeepMockFactory let upkeepAutoFunderFactory: UpkeepAutoFunderFactory let chainModuleBaseFactory: ChainModuleBaseFactory let arbitrumModuleFactory: ArbitrumModuleFactory -let optimismModuleFactory: OptimismModuleFactory +let optimismModuleFactory: OptimismModuleV2Factory let streamsLookupUpkeepFactory: StreamsLookupUpkeepFactory let personas: Personas @@ -174,7 +174,7 @@ let ltUpkeep: MockContract let transcoder: UpkeepTranscoder let chainModuleBase: ChainModuleBase let arbitrumModule: ArbitrumModule -let optimismModule: OptimismModule +let optimismModule: OptimismModuleV2 let streamsLookupUpkeep: StreamsLookupUpkeep let automationUtils: AutomationCompatibleUtils let automationUtils2_3: AutomationUtils2_3 @@ -442,7 +442,7 @@ describe('AutomationRegistry2_3', () => { await ethers.getContractFactory('UpkeepAutoFunder') chainModuleBaseFactory = await ethers.getContractFactory('ChainModuleBase') arbitrumModuleFactory = await ethers.getContractFactory('ArbitrumModule') - optimismModuleFactory = await ethers.getContractFactory('OptimismModule') + optimismModuleFactory = await ethers.getContractFactory('OptimismModuleV2') streamsLookupUpkeepFactory = await ethers.getContractFactory( 'StreamsLookupUpkeep', ) diff --git a/core/gethwrappers/generated/chain_module_base/chain_module_base.go b/core/gethwrappers/generated/chain_module_base/chain_module_base.go index 7f8a0b4c49..19bc49298f 100644 --- a/core/gethwrappers/generated/chain_module_base/chain_module_base.go +++ b/core/gethwrappers/generated/chain_module_base/chain_module_base.go @@ -29,7 +29,7 @@ var ( ) var ChainModuleBaseMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"l1Fee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"maxL1Fee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", Bin: "0x608060405234801561001057600080fd5b50610155806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80637810d12a116100505780637810d12a1461006c57806385df51fd14610099578063de9ee35e146100ac57600080fd5b8063125441401461006c57806357e871e714610093575b600080fd5b61008061007a3660046100ef565b50600090565b6040519081526020015b60405180910390f35b43610080565b6100806100a73660046100ef565b6100c2565b6040805161012c8152600060208201520161008a565b600043821015806100dd57506101006100db8343610108565b115b156100ea57506000919050565b504090565b60006020828403121561010157600080fd5b5035919050565b81810381811115610142577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000a", } diff --git a/core/gethwrappers/generated/i_chain_module/i_chain_module.go b/core/gethwrappers/generated/i_chain_module/i_chain_module.go index 947a18c319..e432d912cc 100644 --- a/core/gethwrappers/generated/i_chain_module/i_chain_module.go +++ b/core/gethwrappers/generated/i_chain_module/i_chain_module.go @@ -29,7 +29,7 @@ var ( ) var IChainModuleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"l1Fee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"maxL1Fee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", } var IChainModuleABI = IChainModuleMetaData.ABI @@ -150,9 +150,9 @@ func (_IChainModule *IChainModuleTransactorRaw) Transact(opts *bind.TransactOpts return _IChainModule.Contract.contract.Transact(opts, method, params...) } -func (_IChainModule *IChainModuleCaller) BlockHash(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { +func (_IChainModule *IChainModuleCaller) BlockHash(opts *bind.CallOpts, blockNumber *big.Int) ([32]byte, error) { var out []interface{} - err := _IChainModule.contract.Call(opts, &out, "blockHash", arg0) + err := _IChainModule.contract.Call(opts, &out, "blockHash", blockNumber) if err != nil { return *new([32]byte), err @@ -164,12 +164,12 @@ func (_IChainModule *IChainModuleCaller) BlockHash(opts *bind.CallOpts, arg0 *bi } -func (_IChainModule *IChainModuleSession) BlockHash(arg0 *big.Int) ([32]byte, error) { - return _IChainModule.Contract.BlockHash(&_IChainModule.CallOpts, arg0) +func (_IChainModule *IChainModuleSession) BlockHash(blockNumber *big.Int) ([32]byte, error) { + return _IChainModule.Contract.BlockHash(&_IChainModule.CallOpts, blockNumber) } -func (_IChainModule *IChainModuleCallerSession) BlockHash(arg0 *big.Int) ([32]byte, error) { - return _IChainModule.Contract.BlockHash(&_IChainModule.CallOpts, arg0) +func (_IChainModule *IChainModuleCallerSession) BlockHash(blockNumber *big.Int) ([32]byte, error) { + return _IChainModule.Contract.BlockHash(&_IChainModule.CallOpts, blockNumber) } func (_IChainModule *IChainModuleCaller) BlockNumber(opts *bind.CallOpts) (*big.Int, error) { @@ -278,7 +278,7 @@ func (_IChainModule *IChainModule) Address() common.Address { } type IChainModuleInterface interface { - BlockHash(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) + BlockHash(opts *bind.CallOpts, blockNumber *big.Int) ([32]byte, error) BlockNumber(opts *bind.CallOpts) (*big.Int, error) diff --git a/core/gethwrappers/generated/optimism_module_v2/optimism_module_v2.go b/core/gethwrappers/generated/optimism_module_v2/optimism_module_v2.go new file mode 100644 index 0000000000..abad079caa --- /dev/null +++ b/core/gethwrappers/generated/optimism_module_v2/optimism_module_v2.go @@ -0,0 +1,840 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package optimism_module_v2 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var OptimismModuleV2MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"coefficient\",\"type\":\"uint8\"}],\"name\":\"InvalidL1FeeCoefficient\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"coefficient\",\"type\":\"uint8\"}],\"name\":\"L1FeeCoefficientSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getL1FeeCoefficient\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"coefficient\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"coefficient\",\"type\":\"uint8\"}],\"name\":\"setL1FeeCalculation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040526001805460ff60a01b1916601960a21b17905534801561002357600080fd5b50338060008161007a5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100aa576100aa816100b2565b50505061015b565b336001600160a01b0382160361010a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610071565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61073f8061016a6000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80638da5cb5b11610076578063de9ee35e1161005b578063de9ee35e1461016a578063f22559a014610180578063f2fde38b1461019357600080fd5b80638da5cb5b1461011f578063d10a944e1461014757600080fd5b80637810d12a116100a75780637810d12a146100ef57806379ba50971461010257806385df51fd1461010c57600080fd5b806312544140146100c357806357e871e7146100e9575b600080fd5b6100d66100d136600461060c565b6101a6565b6040519081526020015b60405180910390f35b436100d6565b6100d66100fd36600461060c565b6101b7565b61010a6101f6565b005b6100d661011a36600461060c565b6102f8565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e0565b60015474010000000000000000000000000000000000000000900460ff166100d6565b60408051616d60815260006020820152016100e0565b61010a61018e366004610625565b610325565b61010a6101a136600461064f565b6103f0565b60006101b182610404565b92915050565b600060646101c483610404565b6001546101ec919074010000000000000000000000000000000000000000900460ff166106b4565b6101b191906106cb565b60015473ffffffffffffffffffffffffffffffffffffffff16331461027c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000438210158061031357506101006103118343610706565b115b1561032057506000919050565b504090565b61032d610494565b60648160ff161115610370576040517f1a8a06a000000000000000000000000000000000000000000000000000000000815260ff82166004820152602401610273565b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000060ff8416908102919091179091556040519081527f29ec9e31de0d3fe0208a7ccb792bbc26a854f123146110daa3a77219cb74a5549060200160405180910390a150565b6103f8610494565b61040181610517565b50565b6040517ff1c7a58b0000000000000000000000000000000000000000000000000000000081526004810182905260009073420000000000000000000000000000000000000f9063f1c7a58b90602401602060405180830381865afa158015610470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b19190610719565b60005473ffffffffffffffffffffffffffffffffffffffff163314610515576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610273565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610596576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610273565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561061e57600080fd5b5035919050565b60006020828403121561063757600080fd5b813560ff8116811461064857600080fd5b9392505050565b60006020828403121561066157600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064857600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176101b1576101b1610685565b600082610701577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b818103818111156101b1576101b1610685565b60006020828403121561072b57600080fd5b505191905056fea164736f6c6343000813000a", +} + +var OptimismModuleV2ABI = OptimismModuleV2MetaData.ABI + +var OptimismModuleV2Bin = OptimismModuleV2MetaData.Bin + +func DeployOptimismModuleV2(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *OptimismModuleV2, error) { + parsed, err := OptimismModuleV2MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(OptimismModuleV2Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &OptimismModuleV2{address: address, abi: *parsed, OptimismModuleV2Caller: OptimismModuleV2Caller{contract: contract}, OptimismModuleV2Transactor: OptimismModuleV2Transactor{contract: contract}, OptimismModuleV2Filterer: OptimismModuleV2Filterer{contract: contract}}, nil +} + +type OptimismModuleV2 struct { + address common.Address + abi abi.ABI + OptimismModuleV2Caller + OptimismModuleV2Transactor + OptimismModuleV2Filterer +} + +type OptimismModuleV2Caller struct { + contract *bind.BoundContract +} + +type OptimismModuleV2Transactor struct { + contract *bind.BoundContract +} + +type OptimismModuleV2Filterer struct { + contract *bind.BoundContract +} + +type OptimismModuleV2Session struct { + Contract *OptimismModuleV2 + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OptimismModuleV2CallerSession struct { + Contract *OptimismModuleV2Caller + CallOpts bind.CallOpts +} + +type OptimismModuleV2TransactorSession struct { + Contract *OptimismModuleV2Transactor + TransactOpts bind.TransactOpts +} + +type OptimismModuleV2Raw struct { + Contract *OptimismModuleV2 +} + +type OptimismModuleV2CallerRaw struct { + Contract *OptimismModuleV2Caller +} + +type OptimismModuleV2TransactorRaw struct { + Contract *OptimismModuleV2Transactor +} + +func NewOptimismModuleV2(address common.Address, backend bind.ContractBackend) (*OptimismModuleV2, error) { + abi, err := abi.JSON(strings.NewReader(OptimismModuleV2ABI)) + if err != nil { + return nil, err + } + contract, err := bindOptimismModuleV2(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismModuleV2{address: address, abi: abi, OptimismModuleV2Caller: OptimismModuleV2Caller{contract: contract}, OptimismModuleV2Transactor: OptimismModuleV2Transactor{contract: contract}, OptimismModuleV2Filterer: OptimismModuleV2Filterer{contract: contract}}, nil +} + +func NewOptimismModuleV2Caller(address common.Address, caller bind.ContractCaller) (*OptimismModuleV2Caller, error) { + contract, err := bindOptimismModuleV2(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismModuleV2Caller{contract: contract}, nil +} + +func NewOptimismModuleV2Transactor(address common.Address, transactor bind.ContractTransactor) (*OptimismModuleV2Transactor, error) { + contract, err := bindOptimismModuleV2(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismModuleV2Transactor{contract: contract}, nil +} + +func NewOptimismModuleV2Filterer(address common.Address, filterer bind.ContractFilterer) (*OptimismModuleV2Filterer, error) { + contract, err := bindOptimismModuleV2(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismModuleV2Filterer{contract: contract}, nil +} + +func bindOptimismModuleV2(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OptimismModuleV2MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OptimismModuleV2 *OptimismModuleV2Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismModuleV2.Contract.OptimismModuleV2Caller.contract.Call(opts, result, method, params...) +} + +func (_OptimismModuleV2 *OptimismModuleV2Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismModuleV2.Contract.OptimismModuleV2Transactor.contract.Transfer(opts) +} + +func (_OptimismModuleV2 *OptimismModuleV2Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismModuleV2.Contract.OptimismModuleV2Transactor.contract.Transact(opts, method, params...) +} + +func (_OptimismModuleV2 *OptimismModuleV2CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismModuleV2.Contract.contract.Call(opts, result, method, params...) +} + +func (_OptimismModuleV2 *OptimismModuleV2TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismModuleV2.Contract.contract.Transfer(opts) +} + +func (_OptimismModuleV2 *OptimismModuleV2TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismModuleV2.Contract.contract.Transact(opts, method, params...) +} + +func (_OptimismModuleV2 *OptimismModuleV2Caller) BlockHash(opts *bind.CallOpts, n *big.Int) ([32]byte, error) { + var out []interface{} + err := _OptimismModuleV2.contract.Call(opts, &out, "blockHash", n) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_OptimismModuleV2 *OptimismModuleV2Session) BlockHash(n *big.Int) ([32]byte, error) { + return _OptimismModuleV2.Contract.BlockHash(&_OptimismModuleV2.CallOpts, n) +} + +func (_OptimismModuleV2 *OptimismModuleV2CallerSession) BlockHash(n *big.Int) ([32]byte, error) { + return _OptimismModuleV2.Contract.BlockHash(&_OptimismModuleV2.CallOpts, n) +} + +func (_OptimismModuleV2 *OptimismModuleV2Caller) BlockNumber(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _OptimismModuleV2.contract.Call(opts, &out, "blockNumber") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_OptimismModuleV2 *OptimismModuleV2Session) BlockNumber() (*big.Int, error) { + return _OptimismModuleV2.Contract.BlockNumber(&_OptimismModuleV2.CallOpts) +} + +func (_OptimismModuleV2 *OptimismModuleV2CallerSession) BlockNumber() (*big.Int, error) { + return _OptimismModuleV2.Contract.BlockNumber(&_OptimismModuleV2.CallOpts) +} + +func (_OptimismModuleV2 *OptimismModuleV2Caller) GetCurrentL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) { + var out []interface{} + err := _OptimismModuleV2.contract.Call(opts, &out, "getCurrentL1Fee", dataSize) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_OptimismModuleV2 *OptimismModuleV2Session) GetCurrentL1Fee(dataSize *big.Int) (*big.Int, error) { + return _OptimismModuleV2.Contract.GetCurrentL1Fee(&_OptimismModuleV2.CallOpts, dataSize) +} + +func (_OptimismModuleV2 *OptimismModuleV2CallerSession) GetCurrentL1Fee(dataSize *big.Int) (*big.Int, error) { + return _OptimismModuleV2.Contract.GetCurrentL1Fee(&_OptimismModuleV2.CallOpts, dataSize) +} + +func (_OptimismModuleV2 *OptimismModuleV2Caller) GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, + + error) { + var out []interface{} + err := _OptimismModuleV2.contract.Call(opts, &out, "getGasOverhead") + + outstruct := new(GetGasOverhead) + if err != nil { + return *outstruct, err + } + + outstruct.ChainModuleFixedOverhead = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.ChainModulePerByteOverhead = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_OptimismModuleV2 *OptimismModuleV2Session) GetGasOverhead() (GetGasOverhead, + + error) { + return _OptimismModuleV2.Contract.GetGasOverhead(&_OptimismModuleV2.CallOpts) +} + +func (_OptimismModuleV2 *OptimismModuleV2CallerSession) GetGasOverhead() (GetGasOverhead, + + error) { + return _OptimismModuleV2.Contract.GetGasOverhead(&_OptimismModuleV2.CallOpts) +} + +func (_OptimismModuleV2 *OptimismModuleV2Caller) GetL1FeeCoefficient(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _OptimismModuleV2.contract.Call(opts, &out, "getL1FeeCoefficient") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_OptimismModuleV2 *OptimismModuleV2Session) GetL1FeeCoefficient() (*big.Int, error) { + return _OptimismModuleV2.Contract.GetL1FeeCoefficient(&_OptimismModuleV2.CallOpts) +} + +func (_OptimismModuleV2 *OptimismModuleV2CallerSession) GetL1FeeCoefficient() (*big.Int, error) { + return _OptimismModuleV2.Contract.GetL1FeeCoefficient(&_OptimismModuleV2.CallOpts) +} + +func (_OptimismModuleV2 *OptimismModuleV2Caller) GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) { + var out []interface{} + err := _OptimismModuleV2.contract.Call(opts, &out, "getMaxL1Fee", dataSize) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_OptimismModuleV2 *OptimismModuleV2Session) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { + return _OptimismModuleV2.Contract.GetMaxL1Fee(&_OptimismModuleV2.CallOpts, dataSize) +} + +func (_OptimismModuleV2 *OptimismModuleV2CallerSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { + return _OptimismModuleV2.Contract.GetMaxL1Fee(&_OptimismModuleV2.CallOpts, dataSize) +} + +func (_OptimismModuleV2 *OptimismModuleV2Caller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismModuleV2.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_OptimismModuleV2 *OptimismModuleV2Session) Owner() (common.Address, error) { + return _OptimismModuleV2.Contract.Owner(&_OptimismModuleV2.CallOpts) +} + +func (_OptimismModuleV2 *OptimismModuleV2CallerSession) Owner() (common.Address, error) { + return _OptimismModuleV2.Contract.Owner(&_OptimismModuleV2.CallOpts) +} + +func (_OptimismModuleV2 *OptimismModuleV2Transactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismModuleV2.contract.Transact(opts, "acceptOwnership") +} + +func (_OptimismModuleV2 *OptimismModuleV2Session) AcceptOwnership() (*types.Transaction, error) { + return _OptimismModuleV2.Contract.AcceptOwnership(&_OptimismModuleV2.TransactOpts) +} + +func (_OptimismModuleV2 *OptimismModuleV2TransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _OptimismModuleV2.Contract.AcceptOwnership(&_OptimismModuleV2.TransactOpts) +} + +func (_OptimismModuleV2 *OptimismModuleV2Transactor) SetL1FeeCalculation(opts *bind.TransactOpts, coefficient uint8) (*types.Transaction, error) { + return _OptimismModuleV2.contract.Transact(opts, "setL1FeeCalculation", coefficient) +} + +func (_OptimismModuleV2 *OptimismModuleV2Session) SetL1FeeCalculation(coefficient uint8) (*types.Transaction, error) { + return _OptimismModuleV2.Contract.SetL1FeeCalculation(&_OptimismModuleV2.TransactOpts, coefficient) +} + +func (_OptimismModuleV2 *OptimismModuleV2TransactorSession) SetL1FeeCalculation(coefficient uint8) (*types.Transaction, error) { + return _OptimismModuleV2.Contract.SetL1FeeCalculation(&_OptimismModuleV2.TransactOpts, coefficient) +} + +func (_OptimismModuleV2 *OptimismModuleV2Transactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _OptimismModuleV2.contract.Transact(opts, "transferOwnership", to) +} + +func (_OptimismModuleV2 *OptimismModuleV2Session) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _OptimismModuleV2.Contract.TransferOwnership(&_OptimismModuleV2.TransactOpts, to) +} + +func (_OptimismModuleV2 *OptimismModuleV2TransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _OptimismModuleV2.Contract.TransferOwnership(&_OptimismModuleV2.TransactOpts, to) +} + +type OptimismModuleV2L1FeeCoefficientSetIterator struct { + Event *OptimismModuleV2L1FeeCoefficientSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OptimismModuleV2L1FeeCoefficientSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OptimismModuleV2L1FeeCoefficientSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(OptimismModuleV2L1FeeCoefficientSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *OptimismModuleV2L1FeeCoefficientSetIterator) Error() error { + return it.fail +} + +func (it *OptimismModuleV2L1FeeCoefficientSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OptimismModuleV2L1FeeCoefficientSet struct { + Coefficient uint8 + Raw types.Log +} + +func (_OptimismModuleV2 *OptimismModuleV2Filterer) FilterL1FeeCoefficientSet(opts *bind.FilterOpts) (*OptimismModuleV2L1FeeCoefficientSetIterator, error) { + + logs, sub, err := _OptimismModuleV2.contract.FilterLogs(opts, "L1FeeCoefficientSet") + if err != nil { + return nil, err + } + return &OptimismModuleV2L1FeeCoefficientSetIterator{contract: _OptimismModuleV2.contract, event: "L1FeeCoefficientSet", logs: logs, sub: sub}, nil +} + +func (_OptimismModuleV2 *OptimismModuleV2Filterer) WatchL1FeeCoefficientSet(opts *bind.WatchOpts, sink chan<- *OptimismModuleV2L1FeeCoefficientSet) (event.Subscription, error) { + + logs, sub, err := _OptimismModuleV2.contract.WatchLogs(opts, "L1FeeCoefficientSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OptimismModuleV2L1FeeCoefficientSet) + if err := _OptimismModuleV2.contract.UnpackLog(event, "L1FeeCoefficientSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_OptimismModuleV2 *OptimismModuleV2Filterer) ParseL1FeeCoefficientSet(log types.Log) (*OptimismModuleV2L1FeeCoefficientSet, error) { + event := new(OptimismModuleV2L1FeeCoefficientSet) + if err := _OptimismModuleV2.contract.UnpackLog(event, "L1FeeCoefficientSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OptimismModuleV2OwnershipTransferRequestedIterator struct { + Event *OptimismModuleV2OwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OptimismModuleV2OwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OptimismModuleV2OwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(OptimismModuleV2OwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *OptimismModuleV2OwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *OptimismModuleV2OwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OptimismModuleV2OwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_OptimismModuleV2 *OptimismModuleV2Filterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OptimismModuleV2OwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _OptimismModuleV2.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &OptimismModuleV2OwnershipTransferRequestedIterator{contract: _OptimismModuleV2.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_OptimismModuleV2 *OptimismModuleV2Filterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *OptimismModuleV2OwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _OptimismModuleV2.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OptimismModuleV2OwnershipTransferRequested) + if err := _OptimismModuleV2.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_OptimismModuleV2 *OptimismModuleV2Filterer) ParseOwnershipTransferRequested(log types.Log) (*OptimismModuleV2OwnershipTransferRequested, error) { + event := new(OptimismModuleV2OwnershipTransferRequested) + if err := _OptimismModuleV2.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OptimismModuleV2OwnershipTransferredIterator struct { + Event *OptimismModuleV2OwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OptimismModuleV2OwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OptimismModuleV2OwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(OptimismModuleV2OwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *OptimismModuleV2OwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *OptimismModuleV2OwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OptimismModuleV2OwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_OptimismModuleV2 *OptimismModuleV2Filterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OptimismModuleV2OwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _OptimismModuleV2.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &OptimismModuleV2OwnershipTransferredIterator{contract: _OptimismModuleV2.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_OptimismModuleV2 *OptimismModuleV2Filterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OptimismModuleV2OwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _OptimismModuleV2.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OptimismModuleV2OwnershipTransferred) + if err := _OptimismModuleV2.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_OptimismModuleV2 *OptimismModuleV2Filterer) ParseOwnershipTransferred(log types.Log) (*OptimismModuleV2OwnershipTransferred, error) { + event := new(OptimismModuleV2OwnershipTransferred) + if err := _OptimismModuleV2.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetGasOverhead struct { + ChainModuleFixedOverhead *big.Int + ChainModulePerByteOverhead *big.Int +} + +func (_OptimismModuleV2 *OptimismModuleV2) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _OptimismModuleV2.abi.Events["L1FeeCoefficientSet"].ID: + return _OptimismModuleV2.ParseL1FeeCoefficientSet(log) + case _OptimismModuleV2.abi.Events["OwnershipTransferRequested"].ID: + return _OptimismModuleV2.ParseOwnershipTransferRequested(log) + case _OptimismModuleV2.abi.Events["OwnershipTransferred"].ID: + return _OptimismModuleV2.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (OptimismModuleV2L1FeeCoefficientSet) Topic() common.Hash { + return common.HexToHash("0x29ec9e31de0d3fe0208a7ccb792bbc26a854f123146110daa3a77219cb74a554") +} + +func (OptimismModuleV2OwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (OptimismModuleV2OwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_OptimismModuleV2 *OptimismModuleV2) Address() common.Address { + return _OptimismModuleV2.address +} + +type OptimismModuleV2Interface interface { + BlockHash(opts *bind.CallOpts, n *big.Int) ([32]byte, error) + + BlockNumber(opts *bind.CallOpts) (*big.Int, error) + + GetCurrentL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) + + GetGasOverhead(opts *bind.CallOpts) (GetGasOverhead, + + error) + + GetL1FeeCoefficient(opts *bind.CallOpts) (*big.Int, error) + + GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + SetL1FeeCalculation(opts *bind.TransactOpts, coefficient uint8) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterL1FeeCoefficientSet(opts *bind.FilterOpts) (*OptimismModuleV2L1FeeCoefficientSetIterator, error) + + WatchL1FeeCoefficientSet(opts *bind.WatchOpts, sink chan<- *OptimismModuleV2L1FeeCoefficientSet) (event.Subscription, error) + + ParseL1FeeCoefficientSet(log types.Log) (*OptimismModuleV2L1FeeCoefficientSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OptimismModuleV2OwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *OptimismModuleV2OwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*OptimismModuleV2OwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OptimismModuleV2OwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OptimismModuleV2OwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*OptimismModuleV2OwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/scroll_module/scroll_module.go b/core/gethwrappers/generated/scroll_module/scroll_module.go index 0a580546d1..e8f48da0d0 100644 --- a/core/gethwrappers/generated/scroll_module/scroll_module.go +++ b/core/gethwrappers/generated/scroll_module/scroll_module.go @@ -31,8 +31,8 @@ var ( ) var ScrollModuleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"coefficient\",\"type\":\"uint8\"}],\"name\":\"InvalidL1FeeCoefficient\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"coefficient\",\"type\":\"uint8\"}],\"name\":\"L1FeeCoefficientSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_l1FeeCoefficient\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"coefficient\",\"type\":\"uint8\"}],\"name\":\"setL1FeeCalculation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040526001805460ff60a01b1916601960a21b17905534801561002357600080fd5b50338060008161007a5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100aa576100aa816100b2565b50505061015b565b336001600160a01b0382160361010a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610071565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61093c8061016a6000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80638da5cb5b11610076578063de9ee35e1161005b578063de9ee35e1461017e578063f22559a014610194578063f2fde38b146101a757600080fd5b80638da5cb5b1461011f57806390bd5c741461014757600080fd5b80637810d12a116100a75780637810d12a146100ef57806379ba50971461010257806385df51fd1461010c57600080fd5b806312544140146100c357806357e871e7146100e9575b600080fd5b6100d66100d13660046106b1565b6101ba565b6040519081526020015b60405180910390f35b436100d6565b6100d66100fd3660046106b1565b6101cb565b61010a61020a565b005b6100d661011a3660046106b1565b61030c565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e0565b60015461016c9074010000000000000000000000000000000000000000900460ff1681565b60405160ff90911681526020016100e0565b6040805161afc8815260aa6020820152016100e0565b61010a6101a23660046106ca565b610339565b61010a6101b53660046106ed565b610404565b60006101c582610418565b92915050565b600060646101d883610418565b600154610200919074010000000000000000000000000000000000000000900460ff16610752565b6101c59190610769565b60015473ffffffffffffffffffffffffffffffffffffffff163314610290576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60004382101580610327575061010061032583436107a4565b115b1561033457506000919050565b504090565b610341610539565b60648160ff161115610384576040517f1a8a06a000000000000000000000000000000000000000000000000000000000815260ff82166004820152602401610287565b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000060ff8416908102919091179091556040519081527f29ec9e31de0d3fe0208a7ccb792bbc26a854f123146110daa3a77219cb74a5549060200160405180910390a150565b61040c610539565b610415816105bc565b50565b600080610426836004610752565b67ffffffffffffffff81111561043e5761043e6107b7565b6040519080825280601f01601f191660200182016040528015610468576020820181803683370190505b50905073530000000000000000000000000000000000000273ffffffffffffffffffffffffffffffffffffffff166349948e0e826040518060c00160405280608c81526020016108a4608c91396040516020016104c692919061080a565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016104f19190610839565b602060405180830381865afa15801561050e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610532919061088a565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610287565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361063b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610287565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156106c357600080fd5b5035919050565b6000602082840312156106dc57600080fd5b813560ff8116811461053257600080fd5b6000602082840312156106ff57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461053257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176101c5576101c5610723565b60008261079f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b818103818111156101c5576101c5610723565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b838110156108015781810151838201526020016107e9565b50506000910152565b6000835161081c8184602088016107e6565b8351908301906108308183602088016107e6565b01949350505050565b60208152600082518060208401526108588160408501602087016107e6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60006020828403121561089c57600080fd5b505191905056feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"coefficient\",\"type\":\"uint8\"}],\"name\":\"InvalidL1FeeCoefficient\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"coefficient\",\"type\":\"uint8\"}],\"name\":\"L1FeeCoefficientSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getL1FeeCoefficient\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"coefficient\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"coefficient\",\"type\":\"uint8\"}],\"name\":\"setL1FeeCalculation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040526001805460ff60a01b1916601960a21b17905534801561002357600080fd5b50338060008161007a5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100aa576100aa816100b2565b50505061015b565b336001600160a01b0382160361010a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610071565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6109288061016a6000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80638da5cb5b11610076578063de9ee35e1161005b578063de9ee35e1461016a578063f22559a014610180578063f2fde38b1461019357600080fd5b80638da5cb5b1461011f578063d10a944e1461014757600080fd5b80637810d12a116100a75780637810d12a146100ef57806379ba50971461010257806385df51fd1461010c57600080fd5b806312544140146100c357806357e871e7146100e9575b600080fd5b6100d66100d136600461069d565b6101a6565b6040519081526020015b60405180910390f35b436100d6565b6100d66100fd36600461069d565b6101b7565b61010a6101f6565b005b6100d661011a36600461069d565b6102f8565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e0565b60015474010000000000000000000000000000000000000000900460ff166100d6565b6040805161afc8815260aa6020820152016100e0565b61010a61018e3660046106b6565b610325565b61010a6101a13660046106d9565b6103f0565b60006101b182610404565b92915050565b600060646101c483610404565b6001546101ec919074010000000000000000000000000000000000000000900460ff1661073e565b6101b19190610755565b60015473ffffffffffffffffffffffffffffffffffffffff16331461027c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000438210158061031357506101006103118343610790565b115b1561032057506000919050565b504090565b61032d610525565b60648160ff161115610370576040517f1a8a06a000000000000000000000000000000000000000000000000000000000815260ff82166004820152602401610273565b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000060ff8416908102919091179091556040519081527f29ec9e31de0d3fe0208a7ccb792bbc26a854f123146110daa3a77219cb74a5549060200160405180910390a150565b6103f8610525565b610401816105a8565b50565b60008061041283600461073e565b67ffffffffffffffff81111561042a5761042a6107a3565b6040519080825280601f01601f191660200182016040528015610454576020820181803683370190505b50905073530000000000000000000000000000000000000273ffffffffffffffffffffffffffffffffffffffff166349948e0e826040518060c00160405280608c8152602001610890608c91396040516020016104b29291906107f6565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016104dd9190610825565b602060405180830381865afa1580156104fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051e9190610876565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610273565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610627576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610273565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156106af57600080fd5b5035919050565b6000602082840312156106c857600080fd5b813560ff8116811461051e57600080fd5b6000602082840312156106eb57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461051e57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176101b1576101b161070f565b60008261078b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b818103818111156101b1576101b161070f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b838110156107ed5781810151838201526020016107d5565b50506000910152565b600083516108088184602088016107d2565b83519083019061081c8183602088016107d2565b01949350505050565b60208152600082518060208401526108448160408501602087016107d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60006020828403121561088857600080fd5b505191905056feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa164736f6c6343000813000a", } var ScrollModuleABI = ScrollModuleMetaData.ABI @@ -267,9 +267,9 @@ func (_ScrollModule *ScrollModuleCallerSession) GetGasOverhead() (GetGasOverhead return _ScrollModule.Contract.GetGasOverhead(&_ScrollModule.CallOpts) } -func (_ScrollModule *ScrollModuleCaller) GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) { +func (_ScrollModule *ScrollModuleCaller) GetL1FeeCoefficient(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _ScrollModule.contract.Call(opts, &out, "getMaxL1Fee", dataSize) + err := _ScrollModule.contract.Call(opts, &out, "getL1FeeCoefficient") if err != nil { return *new(*big.Int), err @@ -281,56 +281,56 @@ func (_ScrollModule *ScrollModuleCaller) GetMaxL1Fee(opts *bind.CallOpts, dataSi } -func (_ScrollModule *ScrollModuleSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { - return _ScrollModule.Contract.GetMaxL1Fee(&_ScrollModule.CallOpts, dataSize) +func (_ScrollModule *ScrollModuleSession) GetL1FeeCoefficient() (*big.Int, error) { + return _ScrollModule.Contract.GetL1FeeCoefficient(&_ScrollModule.CallOpts) } -func (_ScrollModule *ScrollModuleCallerSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { - return _ScrollModule.Contract.GetMaxL1Fee(&_ScrollModule.CallOpts, dataSize) +func (_ScrollModule *ScrollModuleCallerSession) GetL1FeeCoefficient() (*big.Int, error) { + return _ScrollModule.Contract.GetL1FeeCoefficient(&_ScrollModule.CallOpts) } -func (_ScrollModule *ScrollModuleCaller) Owner(opts *bind.CallOpts) (common.Address, error) { +func (_ScrollModule *ScrollModuleCaller) GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) { var out []interface{} - err := _ScrollModule.contract.Call(opts, &out, "owner") + err := _ScrollModule.contract.Call(opts, &out, "getMaxL1Fee", dataSize) if err != nil { - return *new(common.Address), err + return *new(*big.Int), err } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) return out0, err } -func (_ScrollModule *ScrollModuleSession) Owner() (common.Address, error) { - return _ScrollModule.Contract.Owner(&_ScrollModule.CallOpts) +func (_ScrollModule *ScrollModuleSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { + return _ScrollModule.Contract.GetMaxL1Fee(&_ScrollModule.CallOpts, dataSize) } -func (_ScrollModule *ScrollModuleCallerSession) Owner() (common.Address, error) { - return _ScrollModule.Contract.Owner(&_ScrollModule.CallOpts) +func (_ScrollModule *ScrollModuleCallerSession) GetMaxL1Fee(dataSize *big.Int) (*big.Int, error) { + return _ScrollModule.Contract.GetMaxL1Fee(&_ScrollModule.CallOpts, dataSize) } -func (_ScrollModule *ScrollModuleCaller) SL1FeeCoefficient(opts *bind.CallOpts) (uint8, error) { +func (_ScrollModule *ScrollModuleCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _ScrollModule.contract.Call(opts, &out, "s_l1FeeCoefficient") + err := _ScrollModule.contract.Call(opts, &out, "owner") if err != nil { - return *new(uint8), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -func (_ScrollModule *ScrollModuleSession) SL1FeeCoefficient() (uint8, error) { - return _ScrollModule.Contract.SL1FeeCoefficient(&_ScrollModule.CallOpts) +func (_ScrollModule *ScrollModuleSession) Owner() (common.Address, error) { + return _ScrollModule.Contract.Owner(&_ScrollModule.CallOpts) } -func (_ScrollModule *ScrollModuleCallerSession) SL1FeeCoefficient() (uint8, error) { - return _ScrollModule.Contract.SL1FeeCoefficient(&_ScrollModule.CallOpts) +func (_ScrollModule *ScrollModuleCallerSession) Owner() (common.Address, error) { + return _ScrollModule.Contract.Owner(&_ScrollModule.CallOpts) } func (_ScrollModule *ScrollModuleTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { @@ -804,12 +804,12 @@ type ScrollModuleInterface interface { error) + GetL1FeeCoefficient(opts *bind.CallOpts) (*big.Int, error) + GetMaxL1Fee(opts *bind.CallOpts, dataSize *big.Int) (*big.Int, error) Owner(opts *bind.CallOpts) (common.Address, error) - SL1FeeCoefficient(opts *bind.CallOpts) (uint8, error) - AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) SetL1FeeCalculation(opts *bind.TransactOpts, coefficient uint8) (*types.Transaction, error) diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index ee2ad5867c..8862fef8c8 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -23,7 +23,7 @@ batch_blockhash_store: ../../contracts/solc/v0.8.19/BatchBlockhashStore/BatchBlo batch_vrf_coordinator_v2: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/BatchVRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/BatchVRFCoordinatorV2.bin 4512f4313bc5c078215c9241a69045a2a3cfecd6adfcef2f13037183a2d71483 batch_vrf_coordinator_v2plus: ../../contracts/solc/v0.8.19/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.19/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.bin f13715b38b5b9084b08bffa571fb1c8ef686001535902e1255052f074b31ad4e blockhash_store: ../../contracts/solc/v0.8.19/BlockhashStore/BlockhashStore.abi ../../contracts/solc/v0.8.19/BlockhashStore/BlockhashStore.bin 31b118f9577240c8834c35f8b5a1440e82a6ca8aea702970de2601824b6ab0e1 -chain_module_base: ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.abi ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.bin c318d55aae33f370881fec220987a401a06ef7a0da834cea90a68749f85ac96f +chain_module_base: ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.abi ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.bin 7a82cc28014761090185c2650239ad01a0901181f1b2b899b42ca293bcda3741 chain_reader_tester: ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.abi ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.bin b207f9e6bf71e445a2664a602677011b87b80bf95c6352fd7869f1a9ddb08a5b chain_specific_util_helper: ../../contracts/solc/v0.8.6/ChainSpecificUtilHelper/ChainSpecificUtilHelper.abi ../../contracts/solc/v0.8.6/ChainSpecificUtilHelper/ChainSpecificUtilHelper.bin 66eb30b0717fefe05672df5ec863c0b9a5a654623c4757307a2726d8f31e26b1 counter: ../../contracts/solc/v0.8.6/Counter/Counter.abi ../../contracts/solc/v0.8.6/Counter/Counter.bin 6ca06e000e8423573ffa0bdfda749d88236ab3da2a4cbb4a868c706da90488c9 @@ -35,7 +35,7 @@ gas_wrapper_mock: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageW i_automation_registry_master_wrapper_2_2: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin 9ff7087179f89f9b05964ebc3e71332fce11f1b8e85058f7b16b3bc0dd6fb96b i_automation_registry_master_wrapper_2_3: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.bin 06cc87c122452f63fbe84f65329978f30281613be0caa261e53503d94763e921 i_automation_v21_plus_common: ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.abi ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.bin e8a601ec382c0a2e83c49759de13b0622b5e04e6b95901e96a1e9504329e594c -i_chain_module: ../../contracts/solc/v0.8.19/IChainModule/IChainModule.abi ../../contracts/solc/v0.8.19/IChainModule/IChainModule.bin 17ed358d5635be8959c7dcdccc08d40b1fb1aa40a4d7624455dfb725d79ca7d9 +i_chain_module: ../../contracts/solc/v0.8.19/IChainModule/IChainModule.abi ../../contracts/solc/v0.8.19/IChainModule/IChainModule.bin 8ccb8fcfd1ae331a46b4469e1567c380e2a6d2bf21a9976d6c4c655a716aaa42 i_keeper_registry_master_wrapper_2_1: ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.bin ee0f150b3afbab2df3d24ff3f4c87851efa635da30db04cd1f70cb4e185a1781 i_log_automation: ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.bin 296beccb6af655d6fc3a6e676b244831cce2da6688d3afc4f21f8738ae59e03e keeper_consumer_performance_wrapper: ../../contracts/solc/v0.8.16/KeeperConsumerPerformance/KeeperConsumerPerformance.abi ../../contracts/solc/v0.8.16/KeeperConsumerPerformance/KeeperConsumerPerformance.bin eeda39f5d3e1c8ffa0fb6cd1803731b98a4bc262d41833458e3fe8b40933ae90 @@ -60,9 +60,9 @@ mock_ethusd_aggregator_wrapper: ../../contracts/solc/v0.8.19/MockETHUSDAggregato offchain_aggregator_wrapper: OffchainAggregator/OffchainAggregator.abi - 5c8d6562e94166d4790f1ee6e4321d359d9f7262e6c5452a712b1f1c896f45cf operator_factory: ../../contracts/solc/v0.8.19/OperatorFactory/OperatorFactory.abi ../../contracts/solc/v0.8.19/OperatorFactory/OperatorFactory.bin 88e6baa5d9b255eea02616fbcb2cbe21a25ab46adeb6395f6289d169dec949ae operator_wrapper: ../../contracts/solc/v0.8.19/Operator/Operator.abi ../../contracts/solc/v0.8.19/Operator/Operator.bin 23c3888eaa7259e6adf2153d09abae8f4b1987dc44200363faab1e65483f32d5 -optimism_module: ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.abi ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.bin fb34a04d32c6f4ccc860962b740bfde91e5bdfd88cbac0711b41f25f6fd23a85 +optimism_module_v2: ../../contracts/solc/v0.8.19/OptimismModuleV2/OptimismModuleV2.abi ../../contracts/solc/v0.8.19/OptimismModuleV2/OptimismModuleV2.bin 6bc8f93d3a49b3fdecc169214565e6fe5690427860ca4f674818c611dd719502 perform_data_checker_wrapper: ../../contracts/solc/v0.8.16/PerformDataChecker/PerformDataChecker.abi ../../contracts/solc/v0.8.16/PerformDataChecker/PerformDataChecker.bin 48d8309c2117c29a24e1155917ab0b780956b2cd6a8a39ef06ae66a7f6d94f73 -scroll_module: ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.abi ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.bin ddd46b32aa5eb8dc252b10391f6c3345a4c80445c6c058257ceb16eccc074268 +scroll_module: ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.abi ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.bin 0b99b89ff0c8d95a2ab273c93355e572b9e052ce2a9507498a06e0915b541a86 simple_log_upkeep_counter_wrapper: ../../contracts/solc/v0.8.6/SimpleLogUpkeepCounter/SimpleLogUpkeepCounter.abi ../../contracts/solc/v0.8.6/SimpleLogUpkeepCounter/SimpleLogUpkeepCounter.bin 7557d117a066cd8cf35f635bc085ee11795442073c18f8610ede9037b74fd814 solidity_vrf_consumer_interface_v08: ../../contracts/solc/v0.8.6/VRFConsumer/VRFConsumer.abi ../../contracts/solc/v0.8.6/VRFConsumer/VRFConsumer.bin b14f9136b15e3dc9d6154d5700f3ed4cf88ddc4f70f20c3bb57fc46050904c8f solidity_vrf_request_id_v08: ../../contracts/solc/v0.8.6/VRFRequestIDBaseTestHelper/VRFRequestIDBaseTestHelper.abi ../../contracts/solc/v0.8.6/VRFRequestIDBaseTestHelper/VRFRequestIDBaseTestHelper.bin f2559015d6f3e5d285c57b011be9b2300632e93dd6c4524e58202d6200f09edc diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index 95485faf4b..d877c7a8db 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -53,7 +53,7 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.abi ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.bin AutomationUtils automation_utils_2_3 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.abi ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.bin ArbitrumModule arbitrum_module //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.abi ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.bin ChainModuleBase chain_module_base -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.abi ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.bin OptimismModule optimism_module +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/OptimismModuleV2/OptimismModuleV2.abi ../../contracts/solc/v0.8.19/OptimismModuleV2/OptimismModuleV2.bin OptimismModuleV2 optimism_module_v2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.abi ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.bin ScrollModule scroll_module //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/IChainModule/IChainModule.abi ../../contracts/solc/v0.8.19/IChainModule/IChainModule.bin IChainModule i_chain_module //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.abi ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.bin IAutomationV21PlusCommon i_automation_v21_plus_common From 633eb41a4467f91506e05e7fda6873c7b34f4731 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata <96521086+bukata-sa@users.noreply.github.com> Date: Wed, 21 Aug 2024 22:15:25 +0100 Subject: [PATCH 134/432] [CCIP-3072] Info log on missing finalized block (#14179) * [CCIP-3072] Info log on broken chain * sort imports --------- Co-authored-by: Lukasz <120112546+lukaszcl@users.noreply.github.com> --- .changeset/hot-laws-deny.md | 5 +++++ core/services/chainlink/application.go | 2 +- core/services/headreporter/telemetry_reporter.go | 9 ++++++--- core/services/headreporter/telemetry_reporter_test.go | 9 +++++---- 4 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 .changeset/hot-laws-deny.md diff --git a/.changeset/hot-laws-deny.md b/.changeset/hot-laws-deny.md new file mode 100644 index 0000000000..d71783d1b7 --- /dev/null +++ b/.changeset/hot-laws-deny.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal log info on missed finalized head instead of returning an error diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index a3f46fc8a9..3418ac11b3 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -368,7 +368,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { for i, chain := range legacyEVMChains.Slice() { chainIDs[i] = chain.ID() } - telemReporter := headreporter.NewTelemetryReporter(telemetryManager, chainIDs...) + telemReporter := headreporter.NewTelemetryReporter(telemetryManager, globalLogger, chainIDs...) headReporter := headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter, telemReporter) srvcs = append(srvcs, headReporter) for _, chain := range legacyEVMChains.Slice() { diff --git a/core/services/headreporter/telemetry_reporter.go b/core/services/headreporter/telemetry_reporter.go index d76ce8a604..93852f44c0 100644 --- a/core/services/headreporter/telemetry_reporter.go +++ b/core/services/headreporter/telemetry_reporter.go @@ -10,21 +10,23 @@ import ( "google.golang.org/protobuf/proto" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" ) type telemetryReporter struct { + lggr logger.Logger endpoints map[uint64]commontypes.MonitoringEndpoint } -func NewTelemetryReporter(monitoringEndpointGen telemetry.MonitoringEndpointGenerator, chainIDs ...*big.Int) HeadReporter { +func NewTelemetryReporter(monitoringEndpointGen telemetry.MonitoringEndpointGenerator, lggr logger.Logger, chainIDs ...*big.Int) HeadReporter { endpoints := make(map[uint64]commontypes.MonitoringEndpoint) for _, chainID := range chainIDs { endpoints[chainID.Uint64()] = monitoringEndpointGen.GenMonitoringEndpoint("EVM", chainID.String(), "", synchronization.HeadReport) } - return &telemetryReporter{endpoints: endpoints} + return &telemetryReporter{lggr: lggr.Named("TelemetryReporter"), endpoints: endpoints} } func (t *telemetryReporter) ReportNewHead(ctx context.Context, head *evmtypes.Head) error { @@ -55,7 +57,8 @@ func (t *telemetryReporter) ReportNewHead(ctx context.Context, head *evmtypes.He } monitoringEndpoint.SendLog(bytes) if finalized == nil { - return errors.Errorf("No finalized block was found for chain_id=%d", head.EVMChainID.Int64()) + t.lggr.Infow("No finalized block was found", "chainID", head.EVMChainID.Int64(), + "head.number", head.Number, "chainLength", head.ChainLength()) } return nil } diff --git a/core/services/headreporter/telemetry_reporter_test.go b/core/services/headreporter/telemetry_reporter_test.go index c33edab0bc..58c0935490 100644 --- a/core/services/headreporter/telemetry_reporter_test.go +++ b/core/services/headreporter/telemetry_reporter_test.go @@ -13,6 +13,7 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" @@ -54,7 +55,7 @@ func Test_TelemetryReporter_NewHead(t *testing.T) { monitoringEndpointGen. On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(monitoringEndpoint) - reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, big.NewInt(100)) + reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, logger.TestLogger(t), big.NewInt(100)) err = reporter.ReportNewHead(testutils.Context(t), &head) assert.NoError(t, err) @@ -84,10 +85,10 @@ func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { monitoringEndpointGen. On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(monitoringEndpoint) - reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, big.NewInt(100)) + reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, logger.TestLogger(t), big.NewInt(100)) err = reporter.ReportNewHead(testutils.Context(t), &head) - assert.Errorf(t, err, "No finalized block was found for chain_id=100") + assert.NoError(t, err) } func Test_TelemetryReporter_NewHead_MissingEndpoint(t *testing.T) { @@ -96,7 +97,7 @@ func Test_TelemetryReporter_NewHead_MissingEndpoint(t *testing.T) { On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(nil) - reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, big.NewInt(100)) + reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, logger.TestLogger(t), big.NewInt(100)) head := evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(100)} From d884838a6fcbb94288aacbf6ae494160a905dc91 Mon Sep 17 00:00:00 2001 From: Aaron Lu <50029043+aalu1418@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:24:53 -0600 Subject: [PATCH 135/432] bump solana (#14188) --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 4045c3b5e8..d17b8c89e8 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -274,7 +274,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index bbaf5271d4..1680dc0e87 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1194,8 +1194,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 h1:8ZzsGNhqYxmQ/QMO1fuXO7u9Vpl9YUvPJK+td/ZaBJA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= diff --git a/go.mod b/go.mod index 7b5de72594..35fa108f45 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 diff --git a/go.sum b/go.sum index 6574c9c0d8..5123739709 100644 --- a/go.sum +++ b/go.sum @@ -1149,8 +1149,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 h1:8ZzsGNhqYxmQ/QMO1fuXO7u9Vpl9YUvPJK+td/ZaBJA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index b4c1839c74..c1fb3a7d92 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -385,7 +385,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 53c0c5645f..98c4928c2d 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1498,8 +1498,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 h1:8ZzsGNhqYxmQ/QMO1fuXO7u9Vpl9YUvPJK+td/ZaBJA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/chainlink-testing-framework v1.34.5 h1:6itLSDW4NHDDNR+Y+Z8YDzxxCN9SjdKb6SmLCl0vTFM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index abecf67074..da7bf46a92 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -373,7 +373,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a // indirect github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 791b999a6c..8e2d18aaf4 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1480,8 +1480,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564 h1:8ZzsGNhqYxmQ/QMO1fuXO7u9Vpl9YUvPJK+td/ZaBJA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240806154405-8e5684f98564/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/chainlink-testing-framework v1.34.5 h1:6itLSDW4NHDDNR+Y+Z8YDzxxCN9SjdKb6SmLCl0vTFM= From 8322953569e708f16b9aabce2bc1c4fb8bf95727 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Thu, 22 Aug 2024 08:04:01 +0200 Subject: [PATCH 136/432] use explicit block number when checking LINK contract balance (#14186) Co-authored-by: Lukasz <120112546+lukaszcl@users.noreply.github.com> --- integration-tests/actions/actions.go | 49 +++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index 8487e3a264..b274b59416 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -27,6 +27,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" ethContracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + "github.com/smartcontractkit/chainlink/integration-tests/wrappers" "github.com/ethereum/go-ethereum/accounts/abi" @@ -1024,18 +1025,42 @@ func SendLinkFundsToDeploymentAddresses( toTransferToMultiCallContract := big.NewInt(0).Mul(linkAmountPerUpkeep, big.NewInt(int64(totalUpkeeps+concurrency))) toTransferPerClient := big.NewInt(0).Mul(linkAmountPerUpkeep, big.NewInt(int64(operationsPerAddress+1))) - err := linkToken.Transfer(multicallAddress.Hex(), toTransferToMultiCallContract) + + // As a hack we use the geth wrapper directly, because we need to access receipt to get block number, which we will use to query the balance + // This is needed as querying with 'latest' block number very rarely, but still, return stale balance. That's happening even though we wait for + // the transaction to be mined. + linkInstance, err := link_token_interface.NewLinkToken(common.HexToAddress(linkToken.Address()), wrappers.MustNewWrappedContractBackend(nil, chainClient)) if err != nil { - return errors.Wrapf(err, "Error transferring LINK to multicall contract") + return err } - balance, err := linkToken.BalanceOf(context.Background(), multicallAddress.Hex()) + tx, err := chainClient.Decode(linkInstance.Transfer(chainClient.NewTXOpts(), multicallAddress, toTransferToMultiCallContract)) + if err != nil { + return err + } + + if tx.Receipt == nil { + return fmt.Errorf("transaction receipt for LINK transfer to multicall contract is nil") + } + + multiBalance, err := linkInstance.BalanceOf(&bind.CallOpts{From: chainClient.Addresses[0], BlockNumber: tx.Receipt.BlockNumber}, multicallAddress) if err != nil { return errors.Wrapf(err, "Error getting LINK balance of multicall contract") } - if balance.Cmp(toTransferToMultiCallContract) < 0 { - return fmt.Errorf("Incorrect LINK balance of multicall contract. Expected at least: %s. Got: %s", toTransferToMultiCallContract.String(), balance.String()) + // Old code that's querying latest block + //err := linkToken.Transfer(multicallAddress.Hex(), toTransferToMultiCallContract) + //if err != nil { + // return errors.Wrapf(err, "Error transferring LINK to multicall contract") + //} + // + //balance, err := linkToken.BalanceOf(context.Background(), multicallAddress.Hex()) + //if err != nil { + // return errors.Wrapf(err, "Error getting LINK balance of multicall contract") + //} + + if multiBalance.Cmp(toTransferToMultiCallContract) < 0 { + return fmt.Errorf("Incorrect LINK balance of multicall contract. Expected at least: %s. Got: %s", toTransferToMultiCallContract.String(), multiBalance.String()) } // Transfer LINK to ephemeral keys @@ -1060,18 +1085,24 @@ func SendLinkFundsToDeploymentAddresses( } boundContract := bind.NewBoundContract(multicallAddress, multiCallABI, chainClient.Client, chainClient.Client, chainClient.Client) // call aggregate3 to group all msg call data and send them in a single transaction - _, err = chainClient.Decode(boundContract.Transact(chainClient.NewTXOpts(), "aggregate3", call)) + ephemeralTx, err := chainClient.Decode(boundContract.Transact(chainClient.NewTXOpts(), "aggregate3", call)) if err != nil { return errors.Wrapf(err, "Error calling Multicall contract") } + if ephemeralTx.Receipt == nil { + return fmt.Errorf("transaction receipt for LINK transfer to ephemeral keys is nil") + } + for i := 1; i <= concurrency; i++ { - balance, err := linkToken.BalanceOf(context.Background(), chainClient.Addresses[i].Hex()) + ephemeralBalance, err := linkInstance.BalanceOf(&bind.CallOpts{From: chainClient.Addresses[0], BlockNumber: ephemeralTx.Receipt.BlockNumber}, chainClient.Addresses[i]) + // Old code that's querying latest block, for now we prefer to use block number from the transaction receipt + //balance, err := linkToken.BalanceOf(context.Background(), chainClient.Addresses[i].Hex()) if err != nil { return errors.Wrapf(err, "Error getting LINK balance of ephemeral key %d", i) } - if balance.Cmp(toTransferPerClient) < 0 { - return fmt.Errorf("Incorrect LINK balance after transfer. Ephemeral key %d. Expected: %s. Got: %s", i, toTransferPerClient.String(), balance.String()) + if ephemeralBalance.Cmp(toTransferPerClient) < 0 { + return fmt.Errorf("Incorrect LINK balance after transfer. Ephemeral key %d. Expected: %s. Got: %s", i, toTransferPerClient.String(), ephemeralBalance.String()) } } From b563d77dd30ad96253ae6586c06fd34a66d61936 Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Thu, 22 Aug 2024 08:59:21 +0200 Subject: [PATCH 137/432] Report all prices from Jobspec (#14185) * Report all prices from Jobspec (#1275) Fetch all the token prices in the jobspec for dest tokens * Missing changeset --------- Co-authored-by: nogo <110664798+0xnogo@users.noreply.github.com> --- .changeset/lucky-boats-run.md | 5 + .mockery.yaml | 5 + .../plugins/ccip/ccipcommit/initializers.go | 2 +- .../plugins/ccip/clo_ccip_integration_test.go | 26 +- .../plugins/ccip/integration_legacy_test.go | 11 - .../ocr2/plugins/ccip/integration_test.go | 11 - .../ccip/internal/ccipcommon/shortcuts.go | 19 +- .../internal/ccipcommon/shortcuts_test.go | 96 ++-- .../ccip/internal/ccipdb/price_service.go | 75 ++- .../internal/ccipdb/price_service_test.go | 170 +++++-- .../pricegetter/all_price_getter_mock.go | 269 +++++++++++ .../plugins/ccip/internal/pricegetter/evm.go | 17 + .../ccip/internal/pricegetter/evm_test.go | 440 +++++++++++++----- .../ccip/internal/pricegetter/pipeline.go | 68 ++- .../internal/pricegetter/pipeline_test.go | 18 +- .../ccip/internal/pricegetter/pricegetter.go | 13 +- .../ccip/testhelpers/integration/chainlink.go | 43 ++ 17 files changed, 973 insertions(+), 315 deletions(-) create mode 100644 .changeset/lucky-boats-run.md create mode 100644 core/services/ocr2/plugins/ccip/internal/pricegetter/all_price_getter_mock.go diff --git a/.changeset/lucky-boats-run.md b/.changeset/lucky-boats-run.md new file mode 100644 index 0000000000..c5864a6e37 --- /dev/null +++ b/.changeset/lucky-boats-run.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Reporting all the token prices from the job spec for CCIP #updated diff --git a/.mockery.yaml b/.mockery.yaml index 87c27cd46a..5cba66f3da 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -529,6 +529,11 @@ packages: PriceGetter: config: mockname: "Mock{{ .InterfaceName }}" + filename: mock.go + AllTokensPriceGetter: + config: + mockname: "Mock{{ .InterfaceName }}" + filename: all_price_getter_mock.go github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/statuschecker: interfaces: CCIPTransactionStatusChecker: diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go b/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go index e964896ab9..5fb9733cc6 100644 --- a/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go +++ b/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go @@ -69,7 +69,7 @@ func NewCommitServices(ctx context.Context, ds sqlutil.DataSource, srcProvider c commitStoreReader = ccip.NewProviderProxyCommitStoreReader(srcCommitStore, dstCommitStore) commitLggr := lggr.Named("CCIPCommit").With("sourceChain", sourceChainID, "destChain", destChainID) - var priceGetter pricegetter.PriceGetter + var priceGetter pricegetter.AllTokensPriceGetter withPipeline := strings.Trim(pluginConfig.TokenPricesUSDPipeline, "\n\t ") != "" if withPipeline { priceGetter, err = pricegetter.NewPipelineGetter(pluginConfig.TokenPricesUSDPipeline, pr, jb.ID, jb.ExternalJobID, jb.Name.ValueOrZero(), lggr) diff --git a/core/services/ocr2/plugins/ccip/clo_ccip_integration_test.go b/core/services/ocr2/plugins/ccip/clo_ccip_integration_test.go index 142ba006be..2fddd58ac8 100644 --- a/core/services/ocr2/plugins/ccip/clo_ccip_integration_test.go +++ b/core/services/ocr2/plugins/ccip/clo_ccip_integration_test.go @@ -1,6 +1,7 @@ package ccip_test import ( + "context" "encoding/json" "math/big" "testing" @@ -32,7 +33,6 @@ func Test_CLOSpecApprovalFlow_dynamicPriceGetter(t *testing.T) { ccipTH := integrationtesthelpers.SetupCCIPIntegrationTH(t, testhelpers.SourceChainID, testhelpers.SourceChainSelector, testhelpers.DestChainID, testhelpers.DestChainSelector) //Set up the aggregators here to avoid modifying ccipTH. - srcLinkAddr := ccipTH.Source.LinkToken.Address() dstLinkAddr := ccipTH.Dest.LinkToken.Address() srcNativeAddr, err := ccipTH.Source.Router.GetWrappedNative(nil) require.NoError(t, err) @@ -44,13 +44,6 @@ func Test_CLOSpecApprovalFlow_dynamicPriceGetter(t *testing.T) { require.NoError(t, err) ccipTH.Source.Chain.Commit() - aggSrcLnkAddr, _, aggSrcLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Source.User, ccipTH.Source.Chain, 18, big.NewInt(3e18)) - require.NoError(t, err) - ccipTH.Dest.Chain.Commit() - _, err = aggSrcLnk.UpdateRoundData(ccipTH.Source.User, big.NewInt(50), big.NewInt(8000000), big.NewInt(1000), big.NewInt(1000)) - require.NoError(t, err) - ccipTH.Source.Chain.Commit() - aggDstLnkAddr, _, aggDstLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Dest.User, ccipTH.Dest.Chain, 18, big.NewInt(3e18)) require.NoError(t, err) ccipTH.Dest.Chain.Commit() @@ -74,10 +67,6 @@ func Test_CLOSpecApprovalFlow_dynamicPriceGetter(t *testing.T) { priceGetterConfig := config.DynamicPriceGetterConfig{ AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ - srcLinkAddr: { - ChainID: ccipTH.Source.ChainID, - AggregatorContractAddress: aggSrcLnkAddr, - }, srcNativeAddr: { ChainID: ccipTH.Source.ChainID, AggregatorContractAddress: aggSrcNatAddr, @@ -125,11 +114,22 @@ func test_CLOSpecApprovalFlow(t *testing.T, ccipTH integrationtesthelpers.CCIPIn _, err = ccipTH.Source.LinkToken.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), new(big.Int).Set(fee)) require.NoError(t, err) - ccipTH.Source.Chain.Commit() + blockHash := ccipTH.Dest.Chain.Commit() + // get the block number + block, err := ccipTH.Dest.Chain.BlockByHash(context.Background(), blockHash) + require.NoError(t, err) + blockNumber := block.Number().Uint64() + 1 // +1 as a block will be mined for the request from EventuallyReportCommitted ccipTH.SendRequest(t, msg) ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum) ccipTH.EventuallyReportCommitted(t, currentSeqNum) + ccipTH.EventuallyPriceRegistryUpdated( + t, + blockNumber, + ccipTH.Source.ChainSelector, + []common.Address{ccipTH.Dest.LinkToken.Address(), ccipTH.Dest.WrappedNative.Address()}, + ccipTH.Source.WrappedNative.Address(), + ) executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum) assert.Len(t, executionLogs, 1) diff --git a/core/services/ocr2/plugins/ccip/integration_legacy_test.go b/core/services/ocr2/plugins/ccip/integration_legacy_test.go index 9bc94b5fe4..d89c50b407 100644 --- a/core/services/ocr2/plugins/ccip/integration_legacy_test.go +++ b/core/services/ocr2/plugins/ccip/integration_legacy_test.go @@ -63,13 +63,6 @@ func TestIntegration_legacy_CCIP(t *testing.T) { require.NoError(t, err) ccipTH.Source.Chain.Commit() - aggSrcLnkAddr, _, aggSrcLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Source.User, ccipTH.Source.Chain, 18, big.NewInt(3e18)) - require.NoError(t, err) - ccipTH.Dest.Chain.Commit() - _, err = aggSrcLnk.UpdateRoundData(ccipTH.Source.User, big.NewInt(50), big.NewInt(8000000), big.NewInt(1000), big.NewInt(1000)) - require.NoError(t, err) - ccipTH.Source.Chain.Commit() - aggDstLnkAddr, _, aggDstLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Dest.User, ccipTH.Dest.Chain, 18, big.NewInt(3e18)) require.NoError(t, err) ccipTH.Dest.Chain.Commit() @@ -79,10 +72,6 @@ func TestIntegration_legacy_CCIP(t *testing.T) { priceGetterConfig := config.DynamicPriceGetterConfig{ AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ - ccipTH.Source.LinkToken.Address(): { - ChainID: ccipTH.Source.ChainID, - AggregatorContractAddress: aggSrcLnkAddr, - }, ccipTH.Source.WrappedNative.Address(): { ChainID: ccipTH.Source.ChainID, AggregatorContractAddress: aggSrcNatAddr, diff --git a/core/services/ocr2/plugins/ccip/integration_test.go b/core/services/ocr2/plugins/ccip/integration_test.go index 202d2ef230..bbf785efa8 100644 --- a/core/services/ocr2/plugins/ccip/integration_test.go +++ b/core/services/ocr2/plugins/ccip/integration_test.go @@ -66,13 +66,6 @@ func TestIntegration_CCIP(t *testing.T) { require.NoError(t, err) ccipTH.Source.Chain.Commit() - aggSrcLnkAddr, _, aggSrcLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Source.User, ccipTH.Source.Chain, 18, big.NewInt(3e18)) - require.NoError(t, err) - ccipTH.Dest.Chain.Commit() - _, err = aggSrcLnk.UpdateRoundData(ccipTH.Source.User, big.NewInt(50), big.NewInt(8000000), big.NewInt(1000), big.NewInt(1000)) - require.NoError(t, err) - ccipTH.Source.Chain.Commit() - aggDstLnkAddr, _, aggDstLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Dest.User, ccipTH.Dest.Chain, 18, big.NewInt(3e18)) require.NoError(t, err) ccipTH.Dest.Chain.Commit() @@ -82,10 +75,6 @@ func TestIntegration_CCIP(t *testing.T) { priceGetterConfig := config.DynamicPriceGetterConfig{ AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ - ccipTH.Source.LinkToken.Address(): { - ChainID: ccipTH.Source.ChainID, - AggregatorContractAddress: aggSrcLnkAddr, - }, ccipTH.Source.WrappedNative.Address(): { ChainID: ccipTH.Source.ChainID, AggregatorContractAddress: aggSrcNatAddr, diff --git a/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts.go b/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts.go index 4f5ba6cfae..8372ae4748 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts.go @@ -32,24 +32,7 @@ type BackfillArgs struct { SourceStartBlock, DestStartBlock uint64 } -// GetFilteredSortedLaneTokens returns union of tokens supported on this lane, including fee tokens from the provided price registry -// and the bridgeable tokens from offRamp. Bridgeable tokens are only included if they are configured on the pricegetter -// Fee tokens are not filtered as they must always be priced -func GetFilteredSortedLaneTokens(ctx context.Context, offRamp ccipdata.OffRampReader, priceRegistry cciptypes.PriceRegistryReader, priceGetter cciptypes.PriceGetter) (laneTokens []cciptypes.Address, excludedTokens []cciptypes.Address, err error) { - destFeeTokens, destBridgeableTokens, err := GetDestinationTokens(ctx, offRamp, priceRegistry) - if err != nil { - return nil, nil, fmt.Errorf("get tokens with batch limit: %w", err) - } - - destTokensWithPrice, destTokensWithoutPrice, err := priceGetter.FilterConfiguredTokens(ctx, destBridgeableTokens) - if err != nil { - return nil, nil, fmt.Errorf("filter for priced tokens: %w", err) - } - - return flattenedAndSortedTokens(destFeeTokens, destTokensWithPrice), destTokensWithoutPrice, nil -} - -func flattenedAndSortedTokens(slices ...[]cciptypes.Address) (tokens []cciptypes.Address) { +func FlattenedAndSortedTokens(slices ...[]cciptypes.Address) (tokens []cciptypes.Address) { // fee token can overlap with bridgeable tokens, we need to dedup them to arrive at lane token set tokens = FlattenUniqueSlice(slices...) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts_test.go b/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts_test.go index 73a3b83495..6f1cdb4a6a 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipcommon/shortcuts_test.go @@ -3,22 +3,14 @@ package ccipcommon import ( "fmt" "math/rand" - "sort" "strconv" "testing" "time" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" - ccipdatamocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" ) func TestGetMessageIDsAsHexString(t *testing.T) { @@ -70,77 +62,47 @@ func TestFlattenUniqueSlice(t *testing.T) { } } -func TestGetFilteredChainTokens(t *testing.T) { - const numTokens = 6 - var tokens []cciptypes.Address - for i := 0; i < numTokens; i++ { - tokens = append(tokens, ccipcalc.EvmAddrToGeneric(utils.RandomAddress())) - } - +func TestFlattenedAndSortedTokens(t *testing.T) { testCases := []struct { - name string - feeTokens []cciptypes.Address - destTokens []cciptypes.Address - expectedChainTokens []cciptypes.Address - expectedFilteredTokens []cciptypes.Address + name string + inputSlices [][]cciptypes.Address + expectedOutput []cciptypes.Address }{ + {name: "empty", inputSlices: nil, expectedOutput: []cciptypes.Address{}}, + {name: "empty 2", inputSlices: [][]cciptypes.Address{}, expectedOutput: []cciptypes.Address{}}, { - name: "empty", - feeTokens: []cciptypes.Address{}, - destTokens: []cciptypes.Address{}, - expectedChainTokens: []cciptypes.Address{}, - expectedFilteredTokens: []cciptypes.Address{}, + name: "single", + inputSlices: [][]cciptypes.Address{{"0x1", "0x2", "0x3"}}, + expectedOutput: []cciptypes.Address{"0x1", "0x2", "0x3"}, }, { - name: "unique tokens", - feeTokens: []cciptypes.Address{tokens[0]}, - destTokens: []cciptypes.Address{tokens[1], tokens[2], tokens[3]}, - expectedChainTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3]}, - expectedFilteredTokens: []cciptypes.Address{tokens[4], tokens[5]}, + name: "simple", + inputSlices: [][]cciptypes.Address{{"0x1", "0x2", "0x3"}, {"0x2", "0x3", "0x4"}}, + expectedOutput: []cciptypes.Address{"0x1", "0x2", "0x3", "0x4"}, }, { - name: "all tokens", - feeTokens: []cciptypes.Address{tokens[0]}, - destTokens: []cciptypes.Address{tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]}, - expectedChainTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]}, - expectedFilteredTokens: []cciptypes.Address{}, - }, - { - name: "overlapping tokens", - feeTokens: []cciptypes.Address{tokens[0]}, - destTokens: []cciptypes.Address{tokens[1], tokens[2], tokens[5], tokens[3], tokens[0], tokens[2], tokens[3], tokens[4], tokens[5], tokens[5]}, - expectedChainTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]}, - expectedFilteredTokens: []cciptypes.Address{}, - }, - { - name: "unconfigured tokens", - feeTokens: []cciptypes.Address{tokens[0]}, - destTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3], tokens[0], tokens[2], tokens[3], tokens[4], tokens[5], tokens[5]}, - expectedChainTokens: []cciptypes.Address{tokens[0], tokens[1], tokens[2], tokens[3], tokens[4]}, - expectedFilteredTokens: []cciptypes.Address{tokens[5]}, + name: "more complex case", + inputSlices: [][]cciptypes.Address{ + {"0x1", "0x3"}, + {"0x2", "0x4", "0x3"}, + {"0x5", "0x2", "0x7", "0xa"}, + }, + expectedOutput: []cciptypes.Address{ + "0x1", + "0x2", + "0x3", + "0x4", + "0x5", + "0x7", + "0xa", + }, }, } - ctx := testutils.Context(t) for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - priceRegistry := ccipdatamocks.NewPriceRegistryReader(t) - priceRegistry.On("GetFeeTokens", ctx).Return(tc.feeTokens, nil).Once() - - priceGet := pricegetter.NewMockPriceGetter(t) - priceGet.On("FilterConfiguredTokens", mock.Anything, mock.Anything).Return(tc.expectedChainTokens, tc.expectedFilteredTokens, nil) - - offRamp := ccipdatamocks.NewOffRampReader(t) - offRamp.On("GetTokens", ctx).Return(cciptypes.OffRampTokens{DestinationTokens: tc.destTokens}, nil).Once() - - chainTokens, filteredTokens, err := GetFilteredSortedLaneTokens(ctx, offRamp, priceRegistry, priceGet) - assert.NoError(t, err) - - sort.Slice(tc.expectedChainTokens, func(i, j int) bool { - return tc.expectedChainTokens[i] < tc.expectedChainTokens[j] - }) - assert.Equal(t, tc.expectedChainTokens, chainTokens) - assert.Equal(t, tc.expectedFilteredTokens, filteredTokens) + res := FlattenedAndSortedTokens(tc.inputSlices...) + assert.Equal(t, tc.expectedOutput, res) }) } } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go index 2118d5832d..ad44555477 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math/big" + "slices" "sort" "sync" "time" @@ -18,6 +19,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" cciporm "github.com/smartcontractkit/chainlink/v2/core/services/ccip" "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" @@ -72,7 +74,7 @@ type priceService struct { sourceChainSelector uint64 sourceNative cciptypes.Address - priceGetter pricegetter.PriceGetter + priceGetter pricegetter.AllTokensPriceGetter offRampReader ccipdata.OffRampReader gasPriceEstimator prices.GasPriceEstimatorCommit destPriceRegistryReader ccipdata.PriceRegistryReader @@ -92,7 +94,7 @@ func NewPriceService( sourceChainSelector uint64, sourceNative cciptypes.Address, - priceGetter pricegetter.PriceGetter, + priceGetter pricegetter.AllTokensPriceGetter, offRampReader ccipdata.OffRampReader, ) PriceService { ctx, cancel := context.WithCancel(context.Background()) @@ -322,6 +324,7 @@ func (p *priceService) observeGasPriceUpdates( // Include wrapped native to identify the source native USD price, notice USD is in 1e18 scale, i.e. $1 = 1e18 rawTokenPricesUSD, err := p.priceGetter.TokenPricesUSD(ctx, []cciptypes.Address{p.sourceNative}) + if err != nil { return nil, fmt.Errorf("failed to fetch source native price (%s): %w", p.sourceNative, err) } @@ -355,6 +358,9 @@ func (p *priceService) observeGasPriceUpdates( } // All prices are USD ($1=1e18) denominated. All prices must be not nil. +// Jobspec should have the destination tokens (Aggregate Rate Limit, Bps) and 1 source token (source native). +// Not respecting this will error out as we need to fetch the token decimals for all tokens expect sourceNative. +// destTokens is only used to check if sourceNative has the same address as one of the dest tokens. // Return token prices should contain the exact same tokens as in tokenDecimals. func (p *priceService) observeTokenPriceUpdates( ctx context.Context, @@ -363,35 +369,72 @@ func (p *priceService) observeTokenPriceUpdates( if p.destPriceRegistryReader == nil { return nil, fmt.Errorf("destPriceRegistry is not set yet") } - - sortedLaneTokens, filteredLaneTokens, err := ccipcommon.GetFilteredSortedLaneTokens(ctx, p.offRampReader, p.destPriceRegistryReader, p.priceGetter) + rawTokenPricesUSD, err := p.priceGetter.GetJobSpecTokenPricesUSD(ctx) if err != nil { - return nil, fmt.Errorf("get destination tokens: %w", err) + return nil, fmt.Errorf("failed to fetch token prices: %w", err) + } + + // Verify no price returned by price getter is nil + for token, price := range rawTokenPricesUSD { + if price == nil { + return nil, fmt.Errorf("Token price is nil for token %s", token) + } } - lggr.Debugw("Filtered bridgeable tokens with no configured price getter", "filteredLaneTokens", filteredLaneTokens) + lggr.Infow("Raw token prices", "rawTokenPrices", rawTokenPricesUSD) - queryTokens := ccipcommon.FlattenUniqueSlice(sortedLaneTokens) - rawTokenPricesUSD, err := p.priceGetter.TokenPricesUSD(ctx, queryTokens) + sourceNativeEvmAddr, err := ccipcalc.GenericAddrToEvm(p.sourceNative) if err != nil { - return nil, fmt.Errorf("failed to fetch token prices (%v): %w", queryTokens, err) + return nil, fmt.Errorf("failed to convert source native to EVM address: %w", err) } - lggr.Infow("Raw token prices", "rawTokenPrices", rawTokenPricesUSD) - // make sure that we got prices for all the tokens of our query - for _, token := range queryTokens { - if rawTokenPricesUSD[token] == nil { - return nil, fmt.Errorf("missing token price: %+v", token) + // Filter out source native token only if source native not in dest tokens + var finalDestTokens []cciptypes.Address + for token := range rawTokenPricesUSD { + tokenEvmAddr, err2 := ccipcalc.GenericAddrToEvm(token) + if err2 != nil { + return nil, fmt.Errorf("failed to convert token to EVM address: %w", err) + } + + if tokenEvmAddr != sourceNativeEvmAddr { + finalDestTokens = append(finalDestTokens, token) } } - destTokensDecimals, err := p.destPriceRegistryReader.GetTokensDecimals(ctx, sortedLaneTokens) + fee, bridged, err := ccipcommon.GetDestinationTokens(ctx, p.offRampReader, p.destPriceRegistryReader) + if err != nil { + return nil, fmt.Errorf("get destination tokens: %w", err) + } + onchainDestTokens := ccipcommon.FlattenedAndSortedTokens(fee, bridged) + lggr.Debugw("Destination tokens", "destTokens", onchainDestTokens) + + onchainTokensEvmAddr, err := ccipcalc.GenericAddrsToEvm(onchainDestTokens...) + if err != nil { + return nil, fmt.Errorf("failed to convert sorted lane tokens to EVM addresses: %w", err) + } + // Check for case where sourceNative has same address as one of the dest tokens (example: WETH in Base and Optimism) + hasSameDestAddress := slices.Contains(onchainTokensEvmAddr, sourceNativeEvmAddr) + + if hasSameDestAddress { + finalDestTokens = append(finalDestTokens, p.sourceNative) + } + + // Sort tokens to make the order deterministic, easier for testing and debugging + sort.Slice(finalDestTokens, func(i, j int) bool { + return finalDestTokens[i] < finalDestTokens[j] + }) + + destTokensDecimals, err := p.destPriceRegistryReader.GetTokensDecimals(ctx, finalDestTokens) if err != nil { return nil, fmt.Errorf("get tokens decimals: %w", err) } + if len(destTokensDecimals) != len(finalDestTokens) { + return nil, fmt.Errorf("mismatched token decimals and tokens") + } + tokenPricesUSD = make(map[cciptypes.Address]*big.Int, len(rawTokenPricesUSD)) - for i, token := range sortedLaneTokens { + for i, token := range finalDestTokens { tokenPricesUSD[token] = calculateUsdPer1e18TokenAmount(rawTokenPricesUSD[token], destTokensDecimals[i]) } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go index 26721bdf8e..0468c3addb 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go @@ -5,6 +5,7 @@ import ( "fmt" "math/big" "reflect" + "slices" "sort" "testing" "time" @@ -24,7 +25,6 @@ import ( cciporm "github.com/smartcontractkit/chainlink/v2/core/services/ccip" ccipmocks "github.com/smartcontractkit/chainlink/v2/core/services/ccip/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" ccipdatamocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" @@ -314,7 +314,7 @@ func TestPriceService_observeGasPriceUpdates(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - priceGetter := pricegetter.NewMockPriceGetter(t) + priceGetter := pricegetter.NewMockAllTokensPriceGetter(t) defer priceGetter.AssertExpectations(t) gasPriceEstimator := prices.NewMockGasPriceEstimatorCommit(t) @@ -358,6 +358,7 @@ func TestPriceService_observeTokenPriceUpdates(t *testing.T) { jobId := int32(1) destChainSelector := uint64(12345) sourceChainSelector := uint64(67890) + sourceNativeToken := cciptypes.Address(utils.RandomAddress().String()) const nTokens = 10 tokens := make([]cciptypes.Address, nTokens) @@ -368,29 +369,50 @@ func TestPriceService_observeTokenPriceUpdates(t *testing.T) { testCases := []struct { name string + destTokens []cciptypes.Address tokenDecimals map[cciptypes.Address]uint8 + sourceNativeToken cciptypes.Address filterOutTokens []cciptypes.Address priceGetterRespData map[cciptypes.Address]*big.Int priceGetterRespErr error expTokenPricesUSD map[cciptypes.Address]*big.Int expErr bool + expDecimalErr bool }{ { - name: "base", + name: "base case with src native token not equals to dest token", + tokenDecimals: map[cciptypes.Address]uint8{ // only destination tokens + tokens[1]: 18, + tokens[2]: 12, + }, + sourceNativeToken: sourceNativeToken, + priceGetterRespData: map[cciptypes.Address]*big.Int{ // should return all tokens (including source native token) + sourceNativeToken: val1e18(100), + tokens[1]: val1e18(200), + tokens[2]: val1e18(300), + }, + priceGetterRespErr: nil, + expTokenPricesUSD: map[cciptypes.Address]*big.Int{ // should only return the tokens in destination chain + tokens[1]: val1e18(200), + tokens[2]: val1e18(300 * 1e6), + }, + expErr: false, + }, + { + name: "base case with src native token equals to dest token", tokenDecimals: map[cciptypes.Address]uint8{ - tokens[0]: 18, - tokens[1]: 12, + sourceNativeToken: 18, + tokens[1]: 12, }, - filterOutTokens: []cciptypes.Address{tokens[2]}, + sourceNativeToken: sourceNativeToken, priceGetterRespData: map[cciptypes.Address]*big.Int{ - tokens[0]: val1e18(100), - tokens[1]: val1e18(200), - tokens[2]: val1e18(300), // price getter returned a price for this token even though we didn't request it (should be skipped) + sourceNativeToken: val1e18(100), + tokens[1]: val1e18(200), }, priceGetterRespErr: nil, expTokenPricesUSD: map[cciptypes.Address]*big.Int{ - tokens[0]: val1e18(100), - tokens[1]: val1e18(200 * 1e6), + sourceNativeToken: val1e18(100), + tokens[1]: val1e18(200 * 1e6), }, expErr: false, }, @@ -400,29 +422,73 @@ func TestPriceService_observeTokenPriceUpdates(t *testing.T) { tokens[0]: 18, tokens[1]: 18, }, + sourceNativeToken: tokens[0], priceGetterRespData: nil, priceGetterRespErr: fmt.Errorf("some random network error"), expErr: true, }, + { + name: "price getter returns more prices than destTokens", + destTokens: []cciptypes.Address{tokens[1]}, + tokenDecimals: map[cciptypes.Address]uint8{ + tokens[1]: 18, + tokens[2]: 12, + tokens[3]: 18, + }, + sourceNativeToken: sourceNativeToken, + priceGetterRespData: map[cciptypes.Address]*big.Int{ + sourceNativeToken: val1e18(100), + tokens[1]: val1e18(200), + tokens[2]: val1e18(300), + tokens[3]: val1e18(400), + }, + expTokenPricesUSD: map[cciptypes.Address]*big.Int{ + tokens[1]: val1e18(200), + tokens[2]: val1e18(300 * 1e6), + tokens[3]: val1e18(400), + }, + }, + { + name: "price getter returns more prices with missing decimals", + tokenDecimals: map[cciptypes.Address]uint8{ + tokens[1]: 18, + tokens[2]: 12, + }, + sourceNativeToken: sourceNativeToken, + priceGetterRespData: map[cciptypes.Address]*big.Int{ + sourceNativeToken: val1e18(100), + tokens[1]: val1e18(200), + tokens[2]: val1e18(300), + tokens[3]: val1e18(400), + }, + priceGetterRespErr: nil, + expErr: true, + expDecimalErr: true, + }, { name: "price getter skipped a requested price", tokenDecimals: map[cciptypes.Address]uint8{ tokens[0]: 18, - tokens[1]: 18, }, + sourceNativeToken: tokens[0], priceGetterRespData: map[cciptypes.Address]*big.Int{ tokens[0]: val1e18(100), }, priceGetterRespErr: nil, - expErr: true, + expTokenPricesUSD: map[cciptypes.Address]*big.Int{ + tokens[0]: val1e18(100), + }, + expErr: false, }, { name: "nil token price", tokenDecimals: map[cciptypes.Address]uint8{ tokens[0]: 18, tokens[1]: 18, + tokens[2]: 18, }, - filterOutTokens: []cciptypes.Address{tokens[2]}, + sourceNativeToken: tokens[0], + filterOutTokens: []cciptypes.Address{tokens[2]}, priceGetterRespData: map[cciptypes.Address]*big.Int{ tokens[0]: nil, tokens[1]: val1e18(200), @@ -434,27 +500,34 @@ func TestPriceService_observeTokenPriceUpdates(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - priceGetter := pricegetter.NewMockPriceGetter(t) + priceGetter := pricegetter.NewMockAllTokensPriceGetter(t) defer priceGetter.AssertExpectations(t) var destTokens []cciptypes.Address - for tk := range tc.tokenDecimals { - destTokens = append(destTokens, tk) + if len(tc.destTokens) == 0 { + for tk := range tc.tokenDecimals { + destTokens = append(destTokens, tk) + } + } else { + destTokens = tc.destTokens + } + + finalDestTokens := make([]cciptypes.Address, 0, len(destTokens)) + for addr := range tc.priceGetterRespData { + if (tc.sourceNativeToken != addr) || (slices.Contains(destTokens, addr)) { + finalDestTokens = append(finalDestTokens, addr) + } } - sort.Slice(destTokens, func(i, j int) bool { - return destTokens[i] < destTokens[j] + sort.Slice(finalDestTokens, func(i, j int) bool { + return finalDestTokens[i] < finalDestTokens[j] }) + var destDecimals []uint8 - for _, token := range destTokens { + for _, token := range finalDestTokens { destDecimals = append(destDecimals, tc.tokenDecimals[token]) } - queryTokens := ccipcommon.FlattenUniqueSlice(destTokens) - - if len(queryTokens) > 0 { - priceGetter.On("TokenPricesUSD", mock.Anything, queryTokens).Return(tc.priceGetterRespData, tc.priceGetterRespErr) - priceGetter.On("FilterConfiguredTokens", mock.Anything, mock.Anything).Return(destTokens, tc.filterOutTokens, nil) - } + priceGetter.On("GetJobSpecTokenPricesUSD", mock.Anything).Return(tc.priceGetterRespData, tc.priceGetterRespErr) offRampReader := ccipdatamocks.NewOffRampReader(t) offRampReader.On("GetTokens", mock.Anything).Return(cciptypes.OffRampTokens{ @@ -462,7 +535,11 @@ func TestPriceService_observeTokenPriceUpdates(t *testing.T) { }, nil).Maybe() destPriceReg := ccipdatamocks.NewPriceRegistryReader(t) - destPriceReg.On("GetTokensDecimals", mock.Anything, destTokens).Return(destDecimals, nil).Maybe() + if tc.expDecimalErr { + destPriceReg.On("GetTokensDecimals", mock.Anything, finalDestTokens).Return([]uint8{}, fmt.Errorf("Token not found")).Maybe() + } else { + destPriceReg.On("GetTokensDecimals", mock.Anything, finalDestTokens).Return(destDecimals, nil).Maybe() + } destPriceReg.On("GetFeeTokens", mock.Anything).Return([]cciptypes.Address{destTokens[0]}, nil).Maybe() priceService := NewPriceService( @@ -471,7 +548,7 @@ func TestPriceService_observeTokenPriceUpdates(t *testing.T) { jobId, destChainSelector, sourceChainSelector, - "0x123", + tc.sourceNativeToken, priceGetter, offRampReader, ).(*priceService) @@ -754,39 +831,48 @@ func TestPriceService_priceWriteAndCleanupInBackground(t *testing.T) { sourceChainSelector := uint64(67890) ctx := tests.Context(t) - sourceNative := cciptypes.Address("0x123") - feeTokens := []cciptypes.Address{"0x234"} - rampTokens := []cciptypes.Address{"0x345", "0x456"} - rampFilteredTokens := []cciptypes.Address{"0x345"} - rampFilterOutTokens := []cciptypes.Address{"0x456"} + sourceNative := cciptypes.Address(utils.RandomAddress().String()) + feeToken := cciptypes.Address(utils.RandomAddress().String()) + destToken1 := cciptypes.Address(utils.RandomAddress().String()) + destToken2 := cciptypes.Address(utils.RandomAddress().String()) - laneTokens := []cciptypes.Address{"0x234", "0x345"} - laneTokenDecimals := []uint8{18, 18} + feeTokens := []cciptypes.Address{feeToken} + rampTokens := []cciptypes.Address{destToken1, destToken2} - tokens := []cciptypes.Address{sourceNative, "0x234", "0x345"} - tokenPrices := []int64{2, 3, 4} + laneTokens := []cciptypes.Address{sourceNative, feeToken, destToken1, destToken2} + // sort laneTokens + sort.Slice(laneTokens, func(i, j int) bool { + return laneTokens[i] < laneTokens[j] + }) + laneTokenDecimals := []uint8{18, 18, 18, 18} + + tokens := []cciptypes.Address{sourceNative, feeToken, destToken1, destToken2} + tokenPrices := []int64{2, 3, 4, 5} gasPrice := big.NewInt(10) orm := setupORM(t) - priceGetter := pricegetter.NewMockPriceGetter(t) + priceGetter := pricegetter.NewMockAllTokensPriceGetter(t) defer priceGetter.AssertExpectations(t) gasPriceEstimator := prices.NewMockGasPriceEstimatorCommit(t) defer gasPriceEstimator.AssertExpectations(t) - priceGetter.On("TokenPricesUSD", mock.Anything, tokens[:1]).Return(map[cciptypes.Address]*big.Int{ + priceGetter.On("TokenPricesUSD", mock.Anything, []cciptypes.Address{sourceNative}).Return(map[cciptypes.Address]*big.Int{ tokens[0]: val1e18(tokenPrices[0]), }, nil) - priceGetter.On("TokenPricesUSD", mock.Anything, tokens[1:]).Return(map[cciptypes.Address]*big.Int{ + + priceGetter.On("GetJobSpecTokenPricesUSD", mock.Anything).Return(map[cciptypes.Address]*big.Int{ + tokens[0]: val1e18(tokenPrices[0]), tokens[1]: val1e18(tokenPrices[1]), tokens[2]: val1e18(tokenPrices[2]), + tokens[3]: val1e18(tokenPrices[3]), }, nil) - priceGetter.On("FilterConfiguredTokens", mock.Anything, rampTokens).Return(rampFilteredTokens, rampFilterOutTokens, nil) + destTokens := append(rampTokens, sourceNative) offRampReader := ccipdatamocks.NewOffRampReader(t) offRampReader.On("GetTokens", mock.Anything).Return(cciptypes.OffRampTokens{ - DestinationTokens: rampTokens, + DestinationTokens: destTokens, }, nil).Maybe() gasPriceEstimator.On("GetGasPrice", mock.Anything).Return(gasPrice, nil) diff --git a/core/services/ocr2/plugins/ccip/internal/pricegetter/all_price_getter_mock.go b/core/services/ocr2/plugins/ccip/internal/pricegetter/all_price_getter_mock.go new file mode 100644 index 0000000000..010c955c76 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/pricegetter/all_price_getter_mock.go @@ -0,0 +1,269 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package pricegetter + +import ( + context "context" + big "math/big" + + ccip "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + + mock "github.com/stretchr/testify/mock" +) + +// MockAllTokensPriceGetter is an autogenerated mock type for the AllTokensPriceGetter type +type MockAllTokensPriceGetter struct { + mock.Mock +} + +type MockAllTokensPriceGetter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockAllTokensPriceGetter) EXPECT() *MockAllTokensPriceGetter_Expecter { + return &MockAllTokensPriceGetter_Expecter{mock: &_m.Mock} +} + +// Close provides a mock function with given fields: +func (_m *MockAllTokensPriceGetter) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAllTokensPriceGetter_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type MockAllTokensPriceGetter_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *MockAllTokensPriceGetter_Expecter) Close() *MockAllTokensPriceGetter_Close_Call { + return &MockAllTokensPriceGetter_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *MockAllTokensPriceGetter_Close_Call) Run(run func()) *MockAllTokensPriceGetter_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAllTokensPriceGetter_Close_Call) Return(_a0 error) *MockAllTokensPriceGetter_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAllTokensPriceGetter_Close_Call) RunAndReturn(run func() error) *MockAllTokensPriceGetter_Close_Call { + _c.Call.Return(run) + return _c +} + +// FilterConfiguredTokens provides a mock function with given fields: ctx, tokens +func (_m *MockAllTokensPriceGetter) FilterConfiguredTokens(ctx context.Context, tokens []ccip.Address) ([]ccip.Address, []ccip.Address, error) { + ret := _m.Called(ctx, tokens) + + if len(ret) == 0 { + panic("no return value specified for FilterConfiguredTokens") + } + + var r0 []ccip.Address + var r1 []ccip.Address + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) ([]ccip.Address, []ccip.Address, error)); ok { + return rf(ctx, tokens) + } + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) []ccip.Address); ok { + r0 = rf(ctx, tokens) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]ccip.Address) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []ccip.Address) []ccip.Address); ok { + r1 = rf(ctx, tokens) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).([]ccip.Address) + } + } + + if rf, ok := ret.Get(2).(func(context.Context, []ccip.Address) error); ok { + r2 = rf(ctx, tokens) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockAllTokensPriceGetter_FilterConfiguredTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterConfiguredTokens' +type MockAllTokensPriceGetter_FilterConfiguredTokens_Call struct { + *mock.Call +} + +// FilterConfiguredTokens is a helper method to define mock.On call +// - ctx context.Context +// - tokens []ccip.Address +func (_e *MockAllTokensPriceGetter_Expecter) FilterConfiguredTokens(ctx interface{}, tokens interface{}) *MockAllTokensPriceGetter_FilterConfiguredTokens_Call { + return &MockAllTokensPriceGetter_FilterConfiguredTokens_Call{Call: _e.mock.On("FilterConfiguredTokens", ctx, tokens)} +} + +func (_c *MockAllTokensPriceGetter_FilterConfiguredTokens_Call) Run(run func(ctx context.Context, tokens []ccip.Address)) *MockAllTokensPriceGetter_FilterConfiguredTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]ccip.Address)) + }) + return _c +} + +func (_c *MockAllTokensPriceGetter_FilterConfiguredTokens_Call) Return(configured []ccip.Address, unconfigured []ccip.Address, err error) *MockAllTokensPriceGetter_FilterConfiguredTokens_Call { + _c.Call.Return(configured, unconfigured, err) + return _c +} + +func (_c *MockAllTokensPriceGetter_FilterConfiguredTokens_Call) RunAndReturn(run func(context.Context, []ccip.Address) ([]ccip.Address, []ccip.Address, error)) *MockAllTokensPriceGetter_FilterConfiguredTokens_Call { + _c.Call.Return(run) + return _c +} + +// GetJobSpecTokenPricesUSD provides a mock function with given fields: ctx +func (_m *MockAllTokensPriceGetter) GetJobSpecTokenPricesUSD(ctx context.Context) (map[ccip.Address]*big.Int, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetJobSpecTokenPricesUSD") + } + + var r0 map[ccip.Address]*big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (map[ccip.Address]*big.Int, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) map[ccip.Address]*big.Int); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[ccip.Address]*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockAllTokensPriceGetter_GetJobSpecTokenPricesUSD_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetJobSpecTokenPricesUSD' +type MockAllTokensPriceGetter_GetJobSpecTokenPricesUSD_Call struct { + *mock.Call +} + +// GetJobSpecTokenPricesUSD is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockAllTokensPriceGetter_Expecter) GetJobSpecTokenPricesUSD(ctx interface{}) *MockAllTokensPriceGetter_GetJobSpecTokenPricesUSD_Call { + return &MockAllTokensPriceGetter_GetJobSpecTokenPricesUSD_Call{Call: _e.mock.On("GetJobSpecTokenPricesUSD", ctx)} +} + +func (_c *MockAllTokensPriceGetter_GetJobSpecTokenPricesUSD_Call) Run(run func(ctx context.Context)) *MockAllTokensPriceGetter_GetJobSpecTokenPricesUSD_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockAllTokensPriceGetter_GetJobSpecTokenPricesUSD_Call) Return(_a0 map[ccip.Address]*big.Int, _a1 error) *MockAllTokensPriceGetter_GetJobSpecTokenPricesUSD_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockAllTokensPriceGetter_GetJobSpecTokenPricesUSD_Call) RunAndReturn(run func(context.Context) (map[ccip.Address]*big.Int, error)) *MockAllTokensPriceGetter_GetJobSpecTokenPricesUSD_Call { + _c.Call.Return(run) + return _c +} + +// TokenPricesUSD provides a mock function with given fields: ctx, tokens +func (_m *MockAllTokensPriceGetter) TokenPricesUSD(ctx context.Context, tokens []ccip.Address) (map[ccip.Address]*big.Int, error) { + ret := _m.Called(ctx, tokens) + + if len(ret) == 0 { + panic("no return value specified for TokenPricesUSD") + } + + var r0 map[ccip.Address]*big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) (map[ccip.Address]*big.Int, error)); ok { + return rf(ctx, tokens) + } + if rf, ok := ret.Get(0).(func(context.Context, []ccip.Address) map[ccip.Address]*big.Int); ok { + r0 = rf(ctx, tokens) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[ccip.Address]*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []ccip.Address) error); ok { + r1 = rf(ctx, tokens) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockAllTokensPriceGetter_TokenPricesUSD_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TokenPricesUSD' +type MockAllTokensPriceGetter_TokenPricesUSD_Call struct { + *mock.Call +} + +// TokenPricesUSD is a helper method to define mock.On call +// - ctx context.Context +// - tokens []ccip.Address +func (_e *MockAllTokensPriceGetter_Expecter) TokenPricesUSD(ctx interface{}, tokens interface{}) *MockAllTokensPriceGetter_TokenPricesUSD_Call { + return &MockAllTokensPriceGetter_TokenPricesUSD_Call{Call: _e.mock.On("TokenPricesUSD", ctx, tokens)} +} + +func (_c *MockAllTokensPriceGetter_TokenPricesUSD_Call) Run(run func(ctx context.Context, tokens []ccip.Address)) *MockAllTokensPriceGetter_TokenPricesUSD_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]ccip.Address)) + }) + return _c +} + +func (_c *MockAllTokensPriceGetter_TokenPricesUSD_Call) Return(_a0 map[ccip.Address]*big.Int, _a1 error) *MockAllTokensPriceGetter_TokenPricesUSD_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockAllTokensPriceGetter_TokenPricesUSD_Call) RunAndReturn(run func(context.Context, []ccip.Address) (map[ccip.Address]*big.Int, error)) *MockAllTokensPriceGetter_TokenPricesUSD_Call { + _c.Call.Return(run) + return _c +} + +// NewMockAllTokensPriceGetter creates a new instance of MockAllTokensPriceGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockAllTokensPriceGetter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockAllTokensPriceGetter { + mock := &MockAllTokensPriceGetter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/pricegetter/evm.go b/core/services/ocr2/plugins/ccip/internal/pricegetter/evm.go index ed54428bd9..ac4002f53f 100644 --- a/core/services/ocr2/plugins/ccip/internal/pricegetter/evm.go +++ b/core/services/ocr2/plugins/ccip/internal/pricegetter/evm.go @@ -103,6 +103,11 @@ func (d *DynamicPriceGetter) FilterConfiguredTokens(ctx context.Context, tokens return configured, unconfigured, nil } +// It returns the prices of all tokens defined in the price getter. +func (d *DynamicPriceGetter) GetJobSpecTokenPricesUSD(ctx context.Context) (map[cciptypes.Address]*big.Int, error) { + return d.TokenPricesUSD(ctx, d.getAllTokensDefined()) +} + // TokenPricesUSD implements the PriceGetter interface. // It returns static prices stored in the price getter, and batch calls aggregators (one per chain) to retrieve aggregator-based prices. func (d *DynamicPriceGetter) TokenPricesUSD(ctx context.Context, tokens []cciptypes.Address) (map[cciptypes.Address]*big.Int, error) { @@ -116,6 +121,18 @@ func (d *DynamicPriceGetter) TokenPricesUSD(ctx context.Context, tokens []ccipty return prices, nil } +func (d *DynamicPriceGetter) getAllTokensDefined() []cciptypes.Address { + tokens := make([]cciptypes.Address, 0) + + for addr := range d.cfg.AggregatorPrices { + tokens = append(tokens, ccipcalc.EvmAddrToGeneric(addr)) + } + for addr := range d.cfg.StaticPrices { + tokens = append(tokens, ccipcalc.EvmAddrToGeneric(addr)) + } + return tokens +} + // performBatchCalls performs batch calls on all chains to retrieve token prices. func (d *DynamicPriceGetter) performBatchCalls(ctx context.Context, batchCallsPerChain map[uint64]*batchCallsForChain, prices map[cciptypes.Address]*big.Int) error { for chainID, batchCalls := range batchCallsPerChain { diff --git a/core/services/ocr2/plugins/ccip/internal/pricegetter/evm_test.go b/core/services/ocr2/plugins/ccip/internal/pricegetter/evm_test.go index 673b9776c7..78de269968 100644 --- a/core/services/ocr2/plugins/ccip/internal/pricegetter/evm_test.go +++ b/core/services/ocr2/plugins/ccip/internal/pricegetter/evm_test.go @@ -25,12 +25,27 @@ type testParameters struct { evmClients map[uint64]DynamicPriceGetterClient tokens []common.Address expectedTokenPrices map[common.Address]big.Int + expectedTokenPricesForAll map[common.Address]big.Int evmCallErr bool invalidConfigErrorExpected bool priceResolutionErrorExpected bool } -func TestDynamicPriceGetter(t *testing.T) { +var ( + TK1 common.Address + TK2 common.Address + TK3 common.Address + TK4 common.Address +) + +func init() { + TK1 = utils.RandomAddress() + TK2 = utils.RandomAddress() + TK3 = utils.RandomAddress() + TK4 = utils.RandomAddress() +} + +func TestDynamicPriceGetterWithEmptyInput(t *testing.T) { tests := []struct { name string param testParameters @@ -63,6 +78,22 @@ func TestDynamicPriceGetter(t *testing.T) { name: "batchCall_returns_err", param: testParamBatchCallReturnsErr(t), }, + { + name: "less_inputs_than_defined_prices", + param: testLessInputsThanDefinedPrices(t), + }, + { + name: "get_all_tokens_aggregator_and_static", + param: testGetAllTokensAggregatorAndStatic(t), + }, + { + name: "get_all_tokens_aggregator_only", + param: testGetAllTokensAggregatorOnly(t), + }, + { + name: "get_all_tokens_static_only", + param: testGetAllTokensStaticOnly(), + }, } for _, test := range tests { @@ -74,34 +105,31 @@ func TestDynamicPriceGetter(t *testing.T) { } require.NoError(t, err) ctx := testutils.Context(t) - // Check configured token - unconfiguredTk := cciptypes.Address(utils.RandomAddress().String()) - cfgTokens, uncfgTokens, err := pg.FilterConfiguredTokens(ctx, []cciptypes.Address{unconfiguredTk}) - require.NoError(t, err) - assert.Equal(t, []cciptypes.Address{}, cfgTokens) - assert.Equal(t, []cciptypes.Address{unconfiguredTk}, uncfgTokens) - // Build list of tokens to query. - tokens := make([]cciptypes.Address, 0, len(test.param.tokens)) - for _, tk := range test.param.tokens { - tokenAddr := ccipcalc.EvmAddrToGeneric(tk) - tokens = append(tokens, tokenAddr) - } - prices, err := pg.TokenPricesUSD(ctx, tokens) - if test.param.evmCallErr { - require.Error(t, err) - return - } + var prices map[cciptypes.Address]*big.Int + var expectedTokens map[common.Address]big.Int + if len(test.param.expectedTokenPricesForAll) == 0 { + prices, err = pg.TokenPricesUSD(ctx, ccipcalc.EvmAddrsToGeneric(test.param.tokens...)) + if test.param.evmCallErr { + require.Error(t, err) + return + } - if test.param.priceResolutionErrorExpected { - require.Error(t, err) - return + if test.param.priceResolutionErrorExpected { + require.Error(t, err) + return + } + expectedTokens = test.param.expectedTokenPrices + } else { + prices, err = pg.GetJobSpecTokenPricesUSD(ctx) + expectedTokens = test.param.expectedTokenPricesForAll } + require.NoError(t, err) - // we expect prices for at least all queried tokens (it is possible that additional tokens are returned). - assert.True(t, len(prices) >= len(test.param.expectedTokenPrices)) + // Ensure all expected prices are present. + assert.True(t, len(prices) == len(expectedTokens)) // Check prices are matching expected result. - for tk, expectedPrice := range test.param.expectedTokenPrices { + for tk, expectedPrice := range expectedTokens { if prices[cciptypes.Address(tk.String())] == nil { assert.Fail(t, "Token price not found") } @@ -113,25 +141,21 @@ func TestDynamicPriceGetter(t *testing.T) { } func testParamAggregatorOnly(t *testing.T) testParameters { - tk1 := utils.RandomAddress() - tk2 := utils.RandomAddress() - tk3 := utils.RandomAddress() - tk4 := utils.RandomAddress() cfg := config.DynamicPriceGetterConfig{ AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ - tk1: { + TK1: { ChainID: 101, AggregatorContractAddress: utils.RandomAddress(), }, - tk2: { + TK2: { ChainID: 102, AggregatorContractAddress: utils.RandomAddress(), }, - tk3: { + TK3: { ChainID: 103, AggregatorContractAddress: utils.RandomAddress(), }, - tk4: { + TK4: { ChainID: 104, AggregatorContractAddress: utils.RandomAddress(), }, @@ -177,15 +201,15 @@ func testParamAggregatorOnly(t *testing.T) testParameters { uint64(104): mockClient(t, []uint8{20}, []aggregator_v3_interface.LatestRoundData{round4}), } expectedTokenPrices := map[common.Address]big.Int{ - tk1: *multExp(round1.Answer, 10), // expected in 1e18 format. - tk2: *multExp(round2.Answer, 10), // expected in 1e18 format. - tk3: *round3.Answer, // already in 1e18 format (contract decimals==18). - tk4: *multExp(big.NewInt(1234567890), 8), // expected in 1e18 format. + TK1: *multExp(round1.Answer, 10), // expected in 1e18 format. + TK2: *multExp(round2.Answer, 10), // expected in 1e18 format. + TK3: *round3.Answer, // already in 1e18 format (contract decimals==18). + TK4: *multExp(big.NewInt(1234567890), 8), // expected in 1e18 format. } return testParameters{ cfg: cfg, evmClients: evmClients, - tokens: []common.Address{tk1, tk2, tk3, tk4}, + tokens: []common.Address{TK1, TK2, TK3, TK4}, expectedTokenPrices: expectedTokenPrices, invalidConfigErrorExpected: false, } @@ -193,20 +217,17 @@ func testParamAggregatorOnly(t *testing.T) testParameters { // testParamAggregatorOnlyMulti test with several tokens on chain 102. func testParamAggregatorOnlyMulti(t *testing.T) testParameters { - tk1 := utils.RandomAddress() - tk2 := utils.RandomAddress() - tk3 := utils.RandomAddress() cfg := config.DynamicPriceGetterConfig{ AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ - tk1: { + TK1: { ChainID: 101, AggregatorContractAddress: utils.RandomAddress(), }, - tk2: { + TK2: { ChainID: 102, AggregatorContractAddress: utils.RandomAddress(), }, - tk3: { + TK3: { ChainID: 102, AggregatorContractAddress: utils.RandomAddress(), }, @@ -241,35 +262,32 @@ func testParamAggregatorOnlyMulti(t *testing.T) testParameters { uint64(102): mockClient(t, []uint8{8, 8}, []aggregator_v3_interface.LatestRoundData{round2, round3}), } expectedTokenPrices := map[common.Address]big.Int{ - tk1: *multExp(round1.Answer, 10), - tk2: *multExp(round2.Answer, 10), - tk3: *multExp(round3.Answer, 10), + TK1: *multExp(round1.Answer, 10), + TK2: *multExp(round2.Answer, 10), + TK3: *multExp(round3.Answer, 10), } return testParameters{ cfg: cfg, evmClients: evmClients, invalidConfigErrorExpected: false, - tokens: []common.Address{tk1, tk2, tk3}, + tokens: []common.Address{TK1, TK2, TK3}, expectedTokenPrices: expectedTokenPrices, } } func testParamStaticOnly() testParameters { - tk1 := utils.RandomAddress() - tk2 := utils.RandomAddress() - tk3 := utils.RandomAddress() cfg := config.DynamicPriceGetterConfig{ AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{}, StaticPrices: map[common.Address]config.StaticPriceConfig{ - tk1: { + TK1: { ChainID: 101, Price: big.NewInt(1_234_000), }, - tk2: { + TK2: { ChainID: 102, Price: big.NewInt(2_234_000), }, - tk3: { + TK3: { ChainID: 103, Price: big.NewInt(3_234_000), }, @@ -278,35 +296,86 @@ func testParamStaticOnly() testParameters { // Real LINK/USD example from OP. evmClients := map[uint64]DynamicPriceGetterClient{} expectedTokenPrices := map[common.Address]big.Int{ - tk1: *cfg.StaticPrices[tk1].Price, - tk2: *cfg.StaticPrices[tk2].Price, - tk3: *cfg.StaticPrices[tk3].Price, + TK1: *cfg.StaticPrices[TK1].Price, + TK2: *cfg.StaticPrices[TK2].Price, + TK3: *cfg.StaticPrices[TK3].Price, } return testParameters{ cfg: cfg, evmClients: evmClients, - tokens: []common.Address{tk1, tk2, tk3}, + tokens: []common.Address{TK1, TK2, TK3}, expectedTokenPrices: expectedTokenPrices, } } +func testParamNoAggregatorForToken(t *testing.T) testParameters { + cfg := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ + TK1: { + ChainID: 101, + AggregatorContractAddress: utils.RandomAddress(), + }, + TK2: { + ChainID: 102, + AggregatorContractAddress: utils.RandomAddress(), + }, + }, + StaticPrices: map[common.Address]config.StaticPriceConfig{ + TK3: { + ChainID: 103, + Price: big.NewInt(1_234_000), + }, + }, + } + // Real LINK/USD example from OP. + round1 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(1000), + Answer: big.NewInt(1396818990), + StartedAt: big.NewInt(1704896575), + UpdatedAt: big.NewInt(1704896575), + AnsweredInRound: big.NewInt(1000), + } + // Real ETH/USD example from OP. + round2 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(2000), + Answer: big.NewInt(238879815123), + StartedAt: big.NewInt(1704897197), + UpdatedAt: big.NewInt(1704897197), + AnsweredInRound: big.NewInt(2000), + } + evmClients := map[uint64]DynamicPriceGetterClient{ + uint64(101): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round1}), + uint64(102): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round2}), + } + expectedTokenPrices := map[common.Address]big.Int{ + TK1: *round1.Answer, + TK2: *round2.Answer, + TK3: *cfg.StaticPrices[TK3].Price, + TK4: *big.NewInt(0), + } + return testParameters{ + cfg: cfg, + evmClients: evmClients, + tokens: []common.Address{TK1, TK2, TK3, TK4}, + expectedTokenPrices: expectedTokenPrices, + priceResolutionErrorExpected: true, + } +} + func testParamAggregatorAndStaticValid(t *testing.T) testParameters { - tk1 := utils.RandomAddress() - tk2 := utils.RandomAddress() - tk3 := utils.RandomAddress() cfg := config.DynamicPriceGetterConfig{ AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ - tk1: { + TK1: { ChainID: 101, AggregatorContractAddress: utils.RandomAddress(), }, - tk2: { + TK2: { ChainID: 102, AggregatorContractAddress: utils.RandomAddress(), }, }, StaticPrices: map[common.Address]config.StaticPriceConfig{ - tk3: { + TK3: { ChainID: 103, Price: big.NewInt(1_234_000), }, @@ -333,39 +402,36 @@ func testParamAggregatorAndStaticValid(t *testing.T) testParameters { uint64(102): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round2}), } expectedTokenPrices := map[common.Address]big.Int{ - tk1: *multExp(round1.Answer, 10), - tk2: *multExp(round2.Answer, 10), - tk3: *cfg.StaticPrices[tk3].Price, + TK1: *multExp(round1.Answer, 10), + TK2: *multExp(round2.Answer, 10), + TK3: *cfg.StaticPrices[TK3].Price, } return testParameters{ cfg: cfg, evmClients: evmClients, - tokens: []common.Address{tk1, tk2, tk3}, + tokens: []common.Address{TK1, TK2, TK3}, expectedTokenPrices: expectedTokenPrices, } } func testParamAggregatorAndStaticTokenCollision(t *testing.T) testParameters { - tk1 := utils.RandomAddress() - tk2 := utils.RandomAddress() - tk3 := utils.RandomAddress() cfg := config.DynamicPriceGetterConfig{ AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ - tk1: { + TK1: { ChainID: 101, AggregatorContractAddress: utils.RandomAddress(), }, - tk2: { + TK2: { ChainID: 102, AggregatorContractAddress: utils.RandomAddress(), }, - tk3: { + TK3: { ChainID: 103, AggregatorContractAddress: utils.RandomAddress(), }, }, StaticPrices: map[common.Address]config.StaticPriceConfig{ - tk3: { + TK3: { ChainID: 103, Price: big.NewInt(1_234_000), }, @@ -402,29 +468,25 @@ func testParamAggregatorAndStaticTokenCollision(t *testing.T) testParameters { return testParameters{ cfg: cfg, evmClients: evmClients, - tokens: []common.Address{tk1, tk2, tk3}, + tokens: []common.Address{TK1, TK2, TK3}, invalidConfigErrorExpected: true, } } -func testParamNoAggregatorForToken(t *testing.T) testParameters { - tk1 := utils.RandomAddress() - tk2 := utils.RandomAddress() - tk3 := utils.RandomAddress() - tk4 := utils.RandomAddress() +func testParamBatchCallReturnsErr(t *testing.T) testParameters { cfg := config.DynamicPriceGetterConfig{ AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ - tk1: { + TK1: { ChainID: 101, AggregatorContractAddress: utils.RandomAddress(), }, - tk2: { + TK2: { ChainID: 102, AggregatorContractAddress: utils.RandomAddress(), }, }, StaticPrices: map[common.Address]config.StaticPriceConfig{ - tk3: { + TK3: { ChainID: 103, Price: big.NewInt(1_234_000), }, @@ -438,6 +500,51 @@ func testParamNoAggregatorForToken(t *testing.T) testParameters { UpdatedAt: big.NewInt(1704896575), AnsweredInRound: big.NewInt(1000), } + evmClients := map[uint64]DynamicPriceGetterClient{ + uint64(101): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round1}), + uint64(102): { + BatchCaller: mockErrCaller(t), + }, + } + return testParameters{ + cfg: cfg, + evmClients: evmClients, + tokens: []common.Address{TK1, TK2, TK3}, + evmCallErr: true, + } +} + +func testLessInputsThanDefinedPrices(t *testing.T) testParameters { + cfg := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ + TK1: { + ChainID: 101, + AggregatorContractAddress: utils.RandomAddress(), + }, + TK2: { + ChainID: 102, + AggregatorContractAddress: utils.RandomAddress(), + }, + TK3: { + ChainID: 103, + AggregatorContractAddress: utils.RandomAddress(), + }, + }, + StaticPrices: map[common.Address]config.StaticPriceConfig{ + TK4: { + ChainID: 104, + Price: big.NewInt(1_234_000), + }, + }, + } + // Real LINK/USD example from OP. + round1 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(1000), + Answer: big.NewInt(3749350456), + StartedAt: big.NewInt(1704896575), + UpdatedAt: big.NewInt(1704896575), + AnsweredInRound: big.NewInt(1000), + } // Real ETH/USD example from OP. round2 := aggregator_v3_interface.LatestRoundData{ RoundId: big.NewInt(2000), @@ -446,43 +553,51 @@ func testParamNoAggregatorForToken(t *testing.T) testParameters { UpdatedAt: big.NewInt(1704897197), AnsweredInRound: big.NewInt(2000), } + // Real LINK/ETH example from OP. + round3 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(3000), + Answer: big.NewInt(4468862777874802), + StartedAt: big.NewInt(1715743907), + UpdatedAt: big.NewInt(1715743907), + AnsweredInRound: big.NewInt(3000), + } evmClients := map[uint64]DynamicPriceGetterClient{ uint64(101): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round1}), uint64(102): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round2}), + uint64(103): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round3}), } expectedTokenPrices := map[common.Address]big.Int{ - tk1: *round1.Answer, - tk2: *round2.Answer, - tk3: *cfg.StaticPrices[tk3].Price, - tk4: *big.NewInt(0), + TK1: *multExp(round1.Answer, 10), + TK2: *multExp(round2.Answer, 10), + TK3: *multExp(round3.Answer, 10), } return testParameters{ - cfg: cfg, - evmClients: evmClients, - tokens: []common.Address{tk1, tk2, tk3, tk4}, - expectedTokenPrices: expectedTokenPrices, - priceResolutionErrorExpected: true, + cfg: cfg, + evmClients: evmClients, + tokens: []common.Address{TK1, TK2, TK3}, + expectedTokenPrices: expectedTokenPrices, } } -func testParamBatchCallReturnsErr(t *testing.T) testParameters { - tk1 := utils.RandomAddress() - tk2 := utils.RandomAddress() - tk3 := utils.RandomAddress() +func testGetAllTokensAggregatorAndStatic(t *testing.T) testParameters { cfg := config.DynamicPriceGetterConfig{ AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ - tk1: { + TK1: { ChainID: 101, AggregatorContractAddress: utils.RandomAddress(), }, - tk2: { + TK2: { ChainID: 102, AggregatorContractAddress: utils.RandomAddress(), }, + TK3: { + ChainID: 103, + AggregatorContractAddress: utils.RandomAddress(), + }, }, StaticPrices: map[common.Address]config.StaticPriceConfig{ - tk3: { - ChainID: 103, + TK4: { + ChainID: 104, Price: big.NewInt(1_234_000), }, }, @@ -490,22 +605,133 @@ func testParamBatchCallReturnsErr(t *testing.T) testParameters { // Real LINK/USD example from OP. round1 := aggregator_v3_interface.LatestRoundData{ RoundId: big.NewInt(1000), - Answer: big.NewInt(1396818990), + Answer: big.NewInt(3749350456), StartedAt: big.NewInt(1704896575), UpdatedAt: big.NewInt(1704896575), AnsweredInRound: big.NewInt(1000), } + // Real ETH/USD example from OP. + round2 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(2000), + Answer: big.NewInt(238879815123), + StartedAt: big.NewInt(1704897197), + UpdatedAt: big.NewInt(1704897197), + AnsweredInRound: big.NewInt(2000), + } + // Real LINK/ETH example from OP. + round3 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(3000), + Answer: big.NewInt(4468862777874802), + StartedAt: big.NewInt(1715743907), + UpdatedAt: big.NewInt(1715743907), + AnsweredInRound: big.NewInt(3000), + } evmClients := map[uint64]DynamicPriceGetterClient{ uint64(101): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round1}), - uint64(102): { - BatchCaller: mockErrCaller(t), + uint64(102): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round2}), + uint64(103): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round3}), + } + expectedTokenPricesForAll := map[common.Address]big.Int{ + TK1: *multExp(round1.Answer, 10), + TK2: *multExp(round2.Answer, 10), + TK3: *multExp(round3.Answer, 10), + TK4: *cfg.StaticPrices[TK4].Price, + } + return testParameters{ + cfg: cfg, + evmClients: evmClients, + expectedTokenPricesForAll: expectedTokenPricesForAll, + } +} + +func testGetAllTokensAggregatorOnly(t *testing.T) testParameters { + cfg := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ + TK1: { + ChainID: 101, + AggregatorContractAddress: utils.RandomAddress(), + }, + TK2: { + ChainID: 102, + AggregatorContractAddress: utils.RandomAddress(), + }, + TK3: { + ChainID: 103, + AggregatorContractAddress: utils.RandomAddress(), + }, }, + StaticPrices: map[common.Address]config.StaticPriceConfig{}, + } + // Real LINK/USD example from OP. + round1 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(1000), + Answer: big.NewInt(3749350456), + StartedAt: big.NewInt(1704896575), + UpdatedAt: big.NewInt(1704896575), + AnsweredInRound: big.NewInt(1000), + } + // Real ETH/USD example from OP. + round2 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(2000), + Answer: big.NewInt(238879815123), + StartedAt: big.NewInt(1704897197), + UpdatedAt: big.NewInt(1704897197), + AnsweredInRound: big.NewInt(2000), + } + // Real LINK/ETH example from OP. + round3 := aggregator_v3_interface.LatestRoundData{ + RoundId: big.NewInt(3000), + Answer: big.NewInt(4468862777874802), + StartedAt: big.NewInt(1715743907), + UpdatedAt: big.NewInt(1715743907), + AnsweredInRound: big.NewInt(3000), + } + evmClients := map[uint64]DynamicPriceGetterClient{ + uint64(101): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round1}), + uint64(102): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round2}), + uint64(103): mockClient(t, []uint8{8}, []aggregator_v3_interface.LatestRoundData{round3}), + } + expectedTokenPricesForAll := map[common.Address]big.Int{ + TK1: *multExp(round1.Answer, 10), + TK2: *multExp(round2.Answer, 10), + TK3: *multExp(round3.Answer, 10), } return testParameters{ - cfg: cfg, - evmClients: evmClients, - tokens: []common.Address{tk1, tk2, tk3}, - evmCallErr: true, + cfg: cfg, + evmClients: evmClients, + expectedTokenPricesForAll: expectedTokenPricesForAll, + } +} + +func testGetAllTokensStaticOnly() testParameters { + cfg := config.DynamicPriceGetterConfig{ + AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{}, + StaticPrices: map[common.Address]config.StaticPriceConfig{ + TK1: { + ChainID: 101, + Price: big.NewInt(1_234_000), + }, + TK2: { + ChainID: 102, + Price: big.NewInt(2_234_000), + }, + TK3: { + ChainID: 103, + Price: big.NewInt(3_234_000), + }, + }, + } + + evmClients := map[uint64]DynamicPriceGetterClient{} + expectedTokenPricesForAll := map[common.Address]big.Int{ + TK1: *cfg.StaticPrices[TK1].Price, + TK2: *cfg.StaticPrices[TK2].Price, + TK3: *cfg.StaticPrices[TK3].Price, + } + return testParameters{ + cfg: cfg, + evmClients: evmClients, + expectedTokenPricesForAll: expectedTokenPricesForAll, } } diff --git a/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline.go b/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline.go index ae9a10deb6..34977eda9f 100644 --- a/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline.go +++ b/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline.go @@ -11,7 +11,6 @@ import ( "github.com/pkg/errors" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/parseutil" @@ -60,28 +59,30 @@ func (d *PipelineGetter) FilterConfiguredTokens(ctx context.Context, tokens []cc return configured, unconfigured, nil } -func (d *PipelineGetter) TokenPricesUSD(ctx context.Context, tokens []cciptypes.Address) (map[cciptypes.Address]*big.Int, error) { - _, trrs, err := d.runner.ExecuteRun(ctx, pipeline.Spec{ - ID: d.jobID, - DotDagSource: d.source, - CreatedAt: time.Now(), - JobID: d.jobID, - JobName: d.name, - JobType: "", - }, pipeline.NewVarsFrom(map[string]interface{}{})) +func (d *PipelineGetter) GetJobSpecTokenPricesUSD(ctx context.Context) (map[cciptypes.Address]*big.Int, error) { + prices, err := d.getPricesFromRunner(ctx) if err != nil { return nil, err } - finalResult := trrs.FinalResult() - if finalResult.HasErrors() { - return nil, errors.Errorf("error getting prices %v", finalResult.AllErrors) - } - if len(finalResult.Values) != 1 { - return nil, errors.Errorf("invalid number of price results, expected 1 got %v", len(finalResult.Values)) + + tokenPrices := make(map[cciptypes.Address]*big.Int) + for tokenAddressStr, rawPrice := range prices { + tokenAddressStr := ccipcalc.HexToAddress(tokenAddressStr) + castedPrice, err := parseutil.ParseBigIntFromAny(rawPrice) + if err != nil { + return nil, err + } + + tokenPrices[tokenAddressStr] = castedPrice } - prices, ok := finalResult.Values[0].(map[string]interface{}) - if !ok { - return nil, errors.Errorf("expected map output of price pipeline, got %T", finalResult.Values[0]) + + return tokenPrices, nil +} + +func (d *PipelineGetter) TokenPricesUSD(ctx context.Context, tokens []cciptypes.Address) (map[cciptypes.Address]*big.Int, error) { + prices, err := d.getPricesFromRunner(ctx) + if err != nil { + return nil, err } providedTokensSet := mapset.NewSet(tokens...) @@ -101,7 +102,7 @@ func (d *PipelineGetter) TokenPricesUSD(ctx context.Context, tokens []cciptypes. // The mapping of token address to source of token price has to live offchain. // Best we can do is sanity check that the token price spec covers all our desired execution token prices. for _, token := range tokens { - if _, ok = tokenPrices[token]; !ok { + if _, ok := tokenPrices[token]; !ok { return nil, errors.Errorf("missing token %s from tokensForFeeCoin spec, got %v", token, prices) } } @@ -109,6 +110,33 @@ func (d *PipelineGetter) TokenPricesUSD(ctx context.Context, tokens []cciptypes. return tokenPrices, nil } +func (d *PipelineGetter) getPricesFromRunner(ctx context.Context) (map[string]interface{}, error) { + _, trrs, err := d.runner.ExecuteRun(ctx, pipeline.Spec{ + ID: d.jobID, + DotDagSource: d.source, + CreatedAt: time.Now(), + JobID: d.jobID, + JobName: d.name, + JobType: "", + }, pipeline.NewVarsFrom(map[string]interface{}{})) + if err != nil { + return nil, err + } + finalResult := trrs.FinalResult() + if finalResult.HasErrors() { + return nil, errors.Errorf("error getting prices %v", finalResult.AllErrors) + } + if len(finalResult.Values) != 1 { + return nil, errors.Errorf("invalid number of price results, expected 1 got %v", len(finalResult.Values)) + } + prices, ok := finalResult.Values[0].(map[string]interface{}) + if !ok { + return nil, errors.Errorf("expected map output of price pipeline, got %T", finalResult.Values[0]) + } + + return prices, nil +} + func (d *PipelineGetter) Close() error { return d.runner.Close() } diff --git a/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline_test.go b/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline_test.go index 3797075073..8aeeff96b5 100644 --- a/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline_test.go +++ b/core/services/ocr2/plugins/ccip/internal/pricegetter/pipeline_test.go @@ -57,19 +57,21 @@ func TestDataSource(t *testing.T) { priceGetter := newTestPipelineGetter(t, source) - // USDC & LINK are configured - confTokens, _, err := priceGetter.FilterConfiguredTokens(context.Background(), []cciptypes.Address{linkTokenAddress, usdcTokenAddress}) + // Ask for all prices present in spec. + prices, err := priceGetter.GetJobSpecTokenPricesUSD(context.Background()) require.NoError(t, err) - assert.Equal(t, linkTokenAddress, confTokens[0]) - assert.Equal(t, usdcTokenAddress, confTokens[1]) + assert.Equal(t, prices, map[cciptypes.Address]*big.Int{ + linkTokenAddress: big.NewInt(0).Mul(big.NewInt(200), big.NewInt(1000000000000000000)), + usdcTokenAddress: big.NewInt(0).Mul(big.NewInt(1000), big.NewInt(1000000000000000000)), + }) - // Ask for all prices present in spec. - prices, err := priceGetter.TokenPricesUSD(context.Background(), []cciptypes.Address{ + // Specifically ask for all prices + pricesWithInput, errWithInput := priceGetter.TokenPricesUSD(context.Background(), []cciptypes.Address{ linkTokenAddress, usdcTokenAddress, }) - require.NoError(t, err) - assert.Equal(t, prices, map[cciptypes.Address]*big.Int{ + require.NoError(t, errWithInput) + assert.Equal(t, pricesWithInput, map[cciptypes.Address]*big.Int{ linkTokenAddress: big.NewInt(0).Mul(big.NewInt(200), big.NewInt(1000000000000000000)), usdcTokenAddress: big.NewInt(0).Mul(big.NewInt(1000), big.NewInt(1000000000000000000)), }) diff --git a/core/services/ocr2/plugins/ccip/internal/pricegetter/pricegetter.go b/core/services/ocr2/plugins/ccip/internal/pricegetter/pricegetter.go index 9ee0e8f3d0..d4bcfc57b6 100644 --- a/core/services/ocr2/plugins/ccip/internal/pricegetter/pricegetter.go +++ b/core/services/ocr2/plugins/ccip/internal/pricegetter/pricegetter.go @@ -1,7 +1,18 @@ package pricegetter -import cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" +import ( + "context" + "math/big" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" +) type PriceGetter interface { cciptypes.PriceGetter } + +type AllTokensPriceGetter interface { + PriceGetter + // GetJobSpecTokenPricesUSD returns all token prices defined in the jobspec. + GetJobSpecTokenPricesUSD(ctx context.Context) (map[cciptypes.Address]*big.Int, error) +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go index 177ccf323b..fe9021e4c1 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go @@ -7,6 +7,7 @@ import ( "math/big" "net/http" "net/http/httptest" + "slices" "strconv" "strings" "testing" @@ -49,6 +50,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" @@ -762,6 +764,47 @@ func (c *CCIPIntegrationTestHarness) NoNodesHaveExecutedSeqNum(t *testing.T, seq return log } +func (c *CCIPIntegrationTestHarness) EventuallyPriceRegistryUpdated(t *testing.T, block uint64, srcSelector uint64, tokens []common.Address, sourceNative common.Address, priceRegistryOpts ...common.Address) { + var priceRegistry *price_registry_1_2_0.PriceRegistry + var err error + if len(priceRegistryOpts) > 0 { + priceRegistry, err = price_registry_1_2_0.NewPriceRegistry(priceRegistryOpts[0], c.Dest.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Dest.PriceRegistry, "no priceRegistry configured") + priceRegistry = c.Dest.PriceRegistry + } + + g := gomega.NewGomegaWithT(t) + g.Eventually(func() bool { + it, err := priceRegistry.FilterUsdPerTokenUpdated(&bind.FilterOpts{Start: block}, tokens) + g.Expect(err).NotTo(gomega.HaveOccurred(), "Error filtering UsdPerTokenUpdated event") + + tokensFetched := make([]common.Address, 0, len(tokens)) + for it.Next() { + tokenFetched := it.Event.Token + tokensFetched = append(tokensFetched, tokenFetched) + t.Log("Token price updated", tokenFetched.String(), it.Event.Value.String(), it.Event.Timestamp.String()) + } + + for _, token := range tokens { + if !slices.Contains(tokensFetched, token) { + return false + } + } + + return true + }, testutils.WaitTimeout(t), 10*time.Second).Should(gomega.BeTrue(), "Tokens prices has not been updated") + + g.Eventually(func() bool { + it, err := priceRegistry.FilterUsdPerUnitGasUpdated(&bind.FilterOpts{Start: block}, []uint64{srcSelector}) + g.Expect(err).NotTo(gomega.HaveOccurred(), "Error filtering UsdPerUnitGasUpdated event") + g.Expect(it.Next()).To(gomega.BeTrue(), "No UsdPerUnitGasUpdated event found") + + return true + }, testutils.WaitTimeout(t), 10*time.Second).Should(gomega.BeTrue(), "source gas price has not been updated") +} + func (c *CCIPIntegrationTestHarness) EventuallyCommitReportAccepted(t *testing.T, currentBlock uint64, commitStoreOpts ...common.Address) commit_store.CommitStoreCommitReport { var commitStore *commit_store.CommitStore var err error From a865709ea18bfc792db758b60de6f03e953f141f Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Thu, 22 Aug 2024 10:57:33 +0200 Subject: [PATCH 138/432] CCIP-2971 Optimize token/gas prices database interactions (#14074) * Simplify codebase and improve performance by switching to upsert * Update core/services/ccip/orm.go Co-authored-by: Abdelrahman Soliman (Boda) <2677789+asoliman92@users.noreply.github.com> * Post review fixes --------- Co-authored-by: Abdelrahman Soliman (Boda) <2677789+asoliman92@users.noreply.github.com> --- .changeset/thick-mails-applaud.md | 5 + core/services/ccip/mocks/orm.go | 201 ++++++------------ core/services/ccip/observability.go | 115 ++++++++++ core/services/ccip/observability_test.go | 94 ++++++++ core/services/ccip/orm.go | 173 +++++++++------ core/services/ccip/orm_test.go | 168 +++++++++------ .../plugins/ccip/ccipcommit/initializers.go | 2 +- .../ccip/internal/ccipdb/price_service.go | 71 ++----- .../internal/ccipdb/price_service_test.go | 113 +--------- .../migrations/0250_ccip_token_prices_fix.sql | 49 +++++ 10 files changed, 559 insertions(+), 432 deletions(-) create mode 100644 .changeset/thick-mails-applaud.md create mode 100644 core/services/ccip/observability.go create mode 100644 core/services/ccip/observability_test.go create mode 100644 core/store/migrate/migrations/0250_ccip_token_prices_fix.sql diff --git a/.changeset/thick-mails-applaud.md b/.changeset/thick-mails-applaud.md new file mode 100644 index 0000000000..ceec9e64fd --- /dev/null +++ b/.changeset/thick-mails-applaud.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Simplify how token and gas prices are stored in the database - user upsert instead of insert/delete flow #db_update diff --git a/core/services/ccip/mocks/orm.go b/core/services/ccip/mocks/orm.go index 8a987c2160..0c9086def7 100644 --- a/core/services/ccip/mocks/orm.go +++ b/core/services/ccip/mocks/orm.go @@ -8,6 +8,8 @@ import ( ccip "github.com/smartcontractkit/chainlink/v2/core/services/ccip" mock "github.com/stretchr/testify/mock" + + time "time" ) // ORM is an autogenerated mock type for the ORM type @@ -23,102 +25,6 @@ func (_m *ORM) EXPECT() *ORM_Expecter { return &ORM_Expecter{mock: &_m.Mock} } -// ClearGasPricesByDestChain provides a mock function with given fields: ctx, destChainSelector, expireSec -func (_m *ORM) ClearGasPricesByDestChain(ctx context.Context, destChainSelector uint64, expireSec int) error { - ret := _m.Called(ctx, destChainSelector, expireSec) - - if len(ret) == 0 { - panic("no return value specified for ClearGasPricesByDestChain") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, int) error); ok { - r0 = rf(ctx, destChainSelector, expireSec) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ORM_ClearGasPricesByDestChain_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ClearGasPricesByDestChain' -type ORM_ClearGasPricesByDestChain_Call struct { - *mock.Call -} - -// ClearGasPricesByDestChain is a helper method to define mock.On call -// - ctx context.Context -// - destChainSelector uint64 -// - expireSec int -func (_e *ORM_Expecter) ClearGasPricesByDestChain(ctx interface{}, destChainSelector interface{}, expireSec interface{}) *ORM_ClearGasPricesByDestChain_Call { - return &ORM_ClearGasPricesByDestChain_Call{Call: _e.mock.On("ClearGasPricesByDestChain", ctx, destChainSelector, expireSec)} -} - -func (_c *ORM_ClearGasPricesByDestChain_Call) Run(run func(ctx context.Context, destChainSelector uint64, expireSec int)) *ORM_ClearGasPricesByDestChain_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(uint64), args[2].(int)) - }) - return _c -} - -func (_c *ORM_ClearGasPricesByDestChain_Call) Return(_a0 error) *ORM_ClearGasPricesByDestChain_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ORM_ClearGasPricesByDestChain_Call) RunAndReturn(run func(context.Context, uint64, int) error) *ORM_ClearGasPricesByDestChain_Call { - _c.Call.Return(run) - return _c -} - -// ClearTokenPricesByDestChain provides a mock function with given fields: ctx, destChainSelector, expireSec -func (_m *ORM) ClearTokenPricesByDestChain(ctx context.Context, destChainSelector uint64, expireSec int) error { - ret := _m.Called(ctx, destChainSelector, expireSec) - - if len(ret) == 0 { - panic("no return value specified for ClearTokenPricesByDestChain") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, int) error); ok { - r0 = rf(ctx, destChainSelector, expireSec) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ORM_ClearTokenPricesByDestChain_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ClearTokenPricesByDestChain' -type ORM_ClearTokenPricesByDestChain_Call struct { - *mock.Call -} - -// ClearTokenPricesByDestChain is a helper method to define mock.On call -// - ctx context.Context -// - destChainSelector uint64 -// - expireSec int -func (_e *ORM_Expecter) ClearTokenPricesByDestChain(ctx interface{}, destChainSelector interface{}, expireSec interface{}) *ORM_ClearTokenPricesByDestChain_Call { - return &ORM_ClearTokenPricesByDestChain_Call{Call: _e.mock.On("ClearTokenPricesByDestChain", ctx, destChainSelector, expireSec)} -} - -func (_c *ORM_ClearTokenPricesByDestChain_Call) Run(run func(ctx context.Context, destChainSelector uint64, expireSec int)) *ORM_ClearTokenPricesByDestChain_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(uint64), args[2].(int)) - }) - return _c -} - -func (_c *ORM_ClearTokenPricesByDestChain_Call) Return(_a0 error) *ORM_ClearTokenPricesByDestChain_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ORM_ClearTokenPricesByDestChain_Call) RunAndReturn(run func(context.Context, uint64, int) error) *ORM_ClearTokenPricesByDestChain_Call { - _c.Call.Return(run) - return _c -} - // GetGasPricesByDestChain provides a mock function with given fields: ctx, destChainSelector func (_m *ORM) GetGasPricesByDestChain(ctx context.Context, destChainSelector uint64) ([]ccip.GasPrice, error) { ret := _m.Called(ctx, destChainSelector) @@ -237,100 +143,119 @@ func (_c *ORM_GetTokenPricesByDestChain_Call) RunAndReturn(run func(context.Cont return _c } -// InsertGasPricesForDestChain provides a mock function with given fields: ctx, destChainSelector, jobId, gasPrices -func (_m *ORM) InsertGasPricesForDestChain(ctx context.Context, destChainSelector uint64, jobId int32, gasPrices []ccip.GasPriceUpdate) error { - ret := _m.Called(ctx, destChainSelector, jobId, gasPrices) +// UpsertGasPricesForDestChain provides a mock function with given fields: ctx, destChainSelector, gasPrices +func (_m *ORM) UpsertGasPricesForDestChain(ctx context.Context, destChainSelector uint64, gasPrices []ccip.GasPrice) (int64, error) { + ret := _m.Called(ctx, destChainSelector, gasPrices) if len(ret) == 0 { - panic("no return value specified for InsertGasPricesForDestChain") + panic("no return value specified for UpsertGasPricesForDestChain") } - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, int32, []ccip.GasPriceUpdate) error); ok { - r0 = rf(ctx, destChainSelector, jobId, gasPrices) + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, []ccip.GasPrice) (int64, error)); ok { + return rf(ctx, destChainSelector, gasPrices) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, []ccip.GasPrice) int64); ok { + r0 = rf(ctx, destChainSelector, gasPrices) } else { - r0 = ret.Error(0) + r0 = ret.Get(0).(int64) } - return r0 + if rf, ok := ret.Get(1).(func(context.Context, uint64, []ccip.GasPrice) error); ok { + r1 = rf(ctx, destChainSelector, gasPrices) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// ORM_InsertGasPricesForDestChain_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'InsertGasPricesForDestChain' -type ORM_InsertGasPricesForDestChain_Call struct { +// ORM_UpsertGasPricesForDestChain_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpsertGasPricesForDestChain' +type ORM_UpsertGasPricesForDestChain_Call struct { *mock.Call } -// InsertGasPricesForDestChain is a helper method to define mock.On call +// UpsertGasPricesForDestChain is a helper method to define mock.On call // - ctx context.Context // - destChainSelector uint64 -// - jobId int32 -// - gasPrices []ccip.GasPriceUpdate -func (_e *ORM_Expecter) InsertGasPricesForDestChain(ctx interface{}, destChainSelector interface{}, jobId interface{}, gasPrices interface{}) *ORM_InsertGasPricesForDestChain_Call { - return &ORM_InsertGasPricesForDestChain_Call{Call: _e.mock.On("InsertGasPricesForDestChain", ctx, destChainSelector, jobId, gasPrices)} +// - gasPrices []ccip.GasPrice +func (_e *ORM_Expecter) UpsertGasPricesForDestChain(ctx interface{}, destChainSelector interface{}, gasPrices interface{}) *ORM_UpsertGasPricesForDestChain_Call { + return &ORM_UpsertGasPricesForDestChain_Call{Call: _e.mock.On("UpsertGasPricesForDestChain", ctx, destChainSelector, gasPrices)} } -func (_c *ORM_InsertGasPricesForDestChain_Call) Run(run func(ctx context.Context, destChainSelector uint64, jobId int32, gasPrices []ccip.GasPriceUpdate)) *ORM_InsertGasPricesForDestChain_Call { +func (_c *ORM_UpsertGasPricesForDestChain_Call) Run(run func(ctx context.Context, destChainSelector uint64, gasPrices []ccip.GasPrice)) *ORM_UpsertGasPricesForDestChain_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(uint64), args[2].(int32), args[3].([]ccip.GasPriceUpdate)) + run(args[0].(context.Context), args[1].(uint64), args[2].([]ccip.GasPrice)) }) return _c } -func (_c *ORM_InsertGasPricesForDestChain_Call) Return(_a0 error) *ORM_InsertGasPricesForDestChain_Call { - _c.Call.Return(_a0) +func (_c *ORM_UpsertGasPricesForDestChain_Call) Return(_a0 int64, _a1 error) *ORM_UpsertGasPricesForDestChain_Call { + _c.Call.Return(_a0, _a1) return _c } -func (_c *ORM_InsertGasPricesForDestChain_Call) RunAndReturn(run func(context.Context, uint64, int32, []ccip.GasPriceUpdate) error) *ORM_InsertGasPricesForDestChain_Call { +func (_c *ORM_UpsertGasPricesForDestChain_Call) RunAndReturn(run func(context.Context, uint64, []ccip.GasPrice) (int64, error)) *ORM_UpsertGasPricesForDestChain_Call { _c.Call.Return(run) return _c } -// InsertTokenPricesForDestChain provides a mock function with given fields: ctx, destChainSelector, jobId, tokenPrices -func (_m *ORM) InsertTokenPricesForDestChain(ctx context.Context, destChainSelector uint64, jobId int32, tokenPrices []ccip.TokenPriceUpdate) error { - ret := _m.Called(ctx, destChainSelector, jobId, tokenPrices) +// UpsertTokenPricesForDestChain provides a mock function with given fields: ctx, destChainSelector, tokenPrices, interval +func (_m *ORM) UpsertTokenPricesForDestChain(ctx context.Context, destChainSelector uint64, tokenPrices []ccip.TokenPrice, interval time.Duration) (int64, error) { + ret := _m.Called(ctx, destChainSelector, tokenPrices, interval) if len(ret) == 0 { - panic("no return value specified for InsertTokenPricesForDestChain") + panic("no return value specified for UpsertTokenPricesForDestChain") } - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, int32, []ccip.TokenPriceUpdate) error); ok { - r0 = rf(ctx, destChainSelector, jobId, tokenPrices) + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, []ccip.TokenPrice, time.Duration) (int64, error)); ok { + return rf(ctx, destChainSelector, tokenPrices, interval) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, []ccip.TokenPrice, time.Duration) int64); ok { + r0 = rf(ctx, destChainSelector, tokenPrices, interval) } else { - r0 = ret.Error(0) + r0 = ret.Get(0).(int64) } - return r0 + if rf, ok := ret.Get(1).(func(context.Context, uint64, []ccip.TokenPrice, time.Duration) error); ok { + r1 = rf(ctx, destChainSelector, tokenPrices, interval) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// ORM_InsertTokenPricesForDestChain_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'InsertTokenPricesForDestChain' -type ORM_InsertTokenPricesForDestChain_Call struct { +// ORM_UpsertTokenPricesForDestChain_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpsertTokenPricesForDestChain' +type ORM_UpsertTokenPricesForDestChain_Call struct { *mock.Call } -// InsertTokenPricesForDestChain is a helper method to define mock.On call +// UpsertTokenPricesForDestChain is a helper method to define mock.On call // - ctx context.Context // - destChainSelector uint64 -// - jobId int32 -// - tokenPrices []ccip.TokenPriceUpdate -func (_e *ORM_Expecter) InsertTokenPricesForDestChain(ctx interface{}, destChainSelector interface{}, jobId interface{}, tokenPrices interface{}) *ORM_InsertTokenPricesForDestChain_Call { - return &ORM_InsertTokenPricesForDestChain_Call{Call: _e.mock.On("InsertTokenPricesForDestChain", ctx, destChainSelector, jobId, tokenPrices)} +// - tokenPrices []ccip.TokenPrice +// - interval time.Duration +func (_e *ORM_Expecter) UpsertTokenPricesForDestChain(ctx interface{}, destChainSelector interface{}, tokenPrices interface{}, interval interface{}) *ORM_UpsertTokenPricesForDestChain_Call { + return &ORM_UpsertTokenPricesForDestChain_Call{Call: _e.mock.On("UpsertTokenPricesForDestChain", ctx, destChainSelector, tokenPrices, interval)} } -func (_c *ORM_InsertTokenPricesForDestChain_Call) Run(run func(ctx context.Context, destChainSelector uint64, jobId int32, tokenPrices []ccip.TokenPriceUpdate)) *ORM_InsertTokenPricesForDestChain_Call { +func (_c *ORM_UpsertTokenPricesForDestChain_Call) Run(run func(ctx context.Context, destChainSelector uint64, tokenPrices []ccip.TokenPrice, interval time.Duration)) *ORM_UpsertTokenPricesForDestChain_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(uint64), args[2].(int32), args[3].([]ccip.TokenPriceUpdate)) + run(args[0].(context.Context), args[1].(uint64), args[2].([]ccip.TokenPrice), args[3].(time.Duration)) }) return _c } -func (_c *ORM_InsertTokenPricesForDestChain_Call) Return(_a0 error) *ORM_InsertTokenPricesForDestChain_Call { - _c.Call.Return(_a0) +func (_c *ORM_UpsertTokenPricesForDestChain_Call) Return(_a0 int64, _a1 error) *ORM_UpsertTokenPricesForDestChain_Call { + _c.Call.Return(_a0, _a1) return _c } -func (_c *ORM_InsertTokenPricesForDestChain_Call) RunAndReturn(run func(context.Context, uint64, int32, []ccip.TokenPriceUpdate) error) *ORM_InsertTokenPricesForDestChain_Call { +func (_c *ORM_UpsertTokenPricesForDestChain_Call) RunAndReturn(run func(context.Context, uint64, []ccip.TokenPrice, time.Duration) (int64, error)) *ORM_UpsertTokenPricesForDestChain_Call { _c.Call.Return(run) return _c } diff --git a/core/services/ccip/observability.go b/core/services/ccip/observability.go new file mode 100644 index 0000000000..8a061893ce --- /dev/null +++ b/core/services/ccip/observability.go @@ -0,0 +1,115 @@ +package ccip + +import ( + "context" + "strconv" + "time" + + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +var ( + sqlLatencyBuckets = []float64{ + float64(10 * time.Millisecond), + float64(20 * time.Millisecond), + float64(30 * time.Millisecond), + float64(40 * time.Millisecond), + float64(50 * time.Millisecond), + float64(70 * time.Millisecond), + float64(90 * time.Millisecond), + float64(100 * time.Millisecond), + float64(200 * time.Millisecond), + float64(300 * time.Millisecond), + float64(400 * time.Millisecond), + float64(500 * time.Millisecond), + float64(750 * time.Millisecond), + float64(1 * time.Second), + } + ccipQueryDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "ccip_orm_query_duration", + Buckets: sqlLatencyBuckets, + }, []string{"query", "destChainSelector"}) + ccipQueryDatasets = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "ccip_orm_dataset_size", + }, []string{"query", "destChainSelector"}) +) + +type observedORM struct { + ORM + queryDuration *prometheus.HistogramVec + datasetSize *prometheus.GaugeVec +} + +var _ ORM = (*observedORM)(nil) + +func NewObservedORM(ds sqlutil.DataSource, lggr logger.Logger) (*observedORM, error) { + delegate, err := NewORM(ds, lggr) + if err != nil { + return nil, err + } + + return &observedORM{ + ORM: delegate, + queryDuration: ccipQueryDuration, + datasetSize: ccipQueryDatasets, + }, nil +} + +func (o *observedORM) GetGasPricesByDestChain(ctx context.Context, destChainSelector uint64) ([]GasPrice, error) { + return withObservedQueryAndResults(o, "GetGasPricesByDestChain", destChainSelector, func() ([]GasPrice, error) { + return o.ORM.GetGasPricesByDestChain(ctx, destChainSelector) + }) +} + +func (o *observedORM) GetTokenPricesByDestChain(ctx context.Context, destChainSelector uint64) ([]TokenPrice, error) { + return withObservedQueryAndResults(o, "GetTokenPricesByDestChain", destChainSelector, func() ([]TokenPrice, error) { + return o.ORM.GetTokenPricesByDestChain(ctx, destChainSelector) + }) +} + +func (o *observedORM) UpsertGasPricesForDestChain(ctx context.Context, destChainSelector uint64, gasPrices []GasPrice) (int64, error) { + return withObservedQueryAndRowsAffected(o, "UpsertGasPricesForDestChain", destChainSelector, func() (int64, error) { + return o.ORM.UpsertGasPricesForDestChain(ctx, destChainSelector, gasPrices) + }) +} + +func (o *observedORM) UpsertTokenPricesForDestChain(ctx context.Context, destChainSelector uint64, tokenPrices []TokenPrice, interval time.Duration) (int64, error) { + return withObservedQueryAndRowsAffected(o, "UpsertTokenPricesForDestChain", destChainSelector, func() (int64, error) { + return o.ORM.UpsertTokenPricesForDestChain(ctx, destChainSelector, tokenPrices, interval) + }) +} + +func withObservedQueryAndRowsAffected(o *observedORM, queryName string, chainSelector uint64, query func() (int64, error)) (int64, error) { + rowsAffected, err := withObservedQuery(o, queryName, chainSelector, query) + if err == nil { + o.datasetSize. + WithLabelValues(queryName, strconv.FormatUint(chainSelector, 10)). + Set(float64(rowsAffected)) + } + return rowsAffected, err +} + +func withObservedQueryAndResults[T any](o *observedORM, queryName string, chainSelector uint64, query func() ([]T, error)) ([]T, error) { + results, err := withObservedQuery(o, queryName, chainSelector, query) + if err == nil { + o.datasetSize. + WithLabelValues(queryName, strconv.FormatUint(chainSelector, 10)). + Set(float64(len(results))) + } + return results, err +} + +func withObservedQuery[T any](o *observedORM, queryName string, chainSelector uint64, query func() (T, error)) (T, error) { + queryStarted := time.Now() + defer func() { + o.queryDuration. + WithLabelValues(queryName, strconv.FormatUint(chainSelector, 10)). + Observe(float64(time.Since(queryStarted))) + }() + return query() +} diff --git a/core/services/ccip/observability_test.go b/core/services/ccip/observability_test.go new file mode 100644 index 0000000000..24bfb4a9ec --- /dev/null +++ b/core/services/ccip/observability_test.go @@ -0,0 +1,94 @@ +package ccip + +import ( + "math/big" + "testing" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/testutil" + io_prometheus_client "github.com/prometheus/client_model/go" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func Test_MetricsAreTrackedForAllMethods(t *testing.T) { + ctx := testutils.Context(t) + db := pgtest.NewSqlxDB(t) + ccipORM, err := NewObservedORM(db, logger.TestLogger(t)) + require.NoError(t, err) + + tokenPrices := []TokenPrice{ + { + TokenAddr: "0xA", + TokenPrice: assets.NewWei(big.NewInt(1e18)), + }, + { + TokenAddr: "0xB", + TokenPrice: assets.NewWei(big.NewInt(1e18)), + }, + } + tokensUpserted, err := ccipORM.UpsertTokenPricesForDestChain(ctx, 100, tokenPrices, time.Second) + require.NoError(t, err) + assert.Equal(t, len(tokenPrices), int(tokensUpserted)) + assert.Equal(t, len(tokenPrices), counterFromGaugeByLabels(ccipORM.datasetSize, "UpsertTokenPricesForDestChain", "100")) + assert.Equal(t, 0, counterFromGaugeByLabels(ccipORM.datasetSize, "UpsertTokenPricesForDestChain", "200")) + + tokens, err := ccipORM.GetTokenPricesByDestChain(ctx, 100) + require.NoError(t, err) + assert.Equal(t, len(tokenPrices), len(tokens)) + assert.Equal(t, len(tokenPrices), counterFromGaugeByLabels(ccipORM.datasetSize, "GetTokenPricesByDestChain", "100")) + assert.Equal(t, 1, counterFromHistogramByLabels(t, ccipORM.queryDuration, "GetTokenPricesByDestChain", "100")) + + gasPrices := []GasPrice{ + { + SourceChainSelector: 200, + GasPrice: assets.NewWei(big.NewInt(1e18)), + }, + { + SourceChainSelector: 201, + GasPrice: assets.NewWei(big.NewInt(1e18)), + }, + { + SourceChainSelector: 202, + GasPrice: assets.NewWei(big.NewInt(1e18)), + }, + } + gasUpserted, err := ccipORM.UpsertGasPricesForDestChain(ctx, 100, gasPrices) + require.NoError(t, err) + assert.Equal(t, len(gasPrices), int(gasUpserted)) + assert.Equal(t, len(gasPrices), counterFromGaugeByLabels(ccipORM.datasetSize, "UpsertGasPricesForDestChain", "100")) + assert.Equal(t, 0, counterFromGaugeByLabels(ccipORM.datasetSize, "UpsertGasPricesForDestChain", "200")) + + gas, err := ccipORM.GetGasPricesByDestChain(ctx, 100) + require.NoError(t, err) + assert.Equal(t, len(gasPrices), len(gas)) + assert.Equal(t, len(gasPrices), counterFromGaugeByLabels(ccipORM.datasetSize, "GetGasPricesByDestChain", "100")) + assert.Equal(t, 1, counterFromHistogramByLabels(t, ccipORM.queryDuration, "GetGasPricesByDestChain", "100")) +} + +func counterFromHistogramByLabels(t *testing.T, histogramVec *prometheus.HistogramVec, labels ...string) int { + observer, err := histogramVec.GetMetricWithLabelValues(labels...) + require.NoError(t, err) + + metricCh := make(chan prometheus.Metric, 1) + observer.(prometheus.Histogram).Collect(metricCh) + close(metricCh) + + metric := <-metricCh + pb := &io_prometheus_client.Metric{} + err = metric.Write(pb) + require.NoError(t, err) + + return int(pb.GetHistogram().GetSampleCount()) +} + +func counterFromGaugeByLabels(gaugeVec *prometheus.GaugeVec, labels ...string) int { + value := testutil.ToFloat64(gaugeVec.WithLabelValues(labels...)) + return int(value) +} diff --git a/core/services/ccip/orm.go b/core/services/ccip/orm.go index d074ea7473..1942c68fef 100644 --- a/core/services/ccip/orm.go +++ b/core/services/ccip/orm.go @@ -8,65 +8,51 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/logger" ) type GasPrice struct { SourceChainSelector uint64 GasPrice *assets.Wei - CreatedAt time.Time -} - -type GasPriceUpdate struct { - SourceChainSelector uint64 - GasPrice *assets.Wei } type TokenPrice struct { TokenAddr string TokenPrice *assets.Wei - CreatedAt time.Time -} - -type TokenPriceUpdate struct { - TokenAddr string - TokenPrice *assets.Wei } type ORM interface { GetGasPricesByDestChain(ctx context.Context, destChainSelector uint64) ([]GasPrice, error) GetTokenPricesByDestChain(ctx context.Context, destChainSelector uint64) ([]TokenPrice, error) - InsertGasPricesForDestChain(ctx context.Context, destChainSelector uint64, jobId int32, gasPrices []GasPriceUpdate) error - InsertTokenPricesForDestChain(ctx context.Context, destChainSelector uint64, jobId int32, tokenPrices []TokenPriceUpdate) error - - ClearGasPricesByDestChain(ctx context.Context, destChainSelector uint64, expireSec int) error - ClearTokenPricesByDestChain(ctx context.Context, destChainSelector uint64, expireSec int) error + UpsertGasPricesForDestChain(ctx context.Context, destChainSelector uint64, gasPrices []GasPrice) (int64, error) + UpsertTokenPricesForDestChain(ctx context.Context, destChainSelector uint64, tokenPrices []TokenPrice, interval time.Duration) (int64, error) } type orm struct { - ds sqlutil.DataSource + ds sqlutil.DataSource + lggr logger.Logger } var _ ORM = (*orm)(nil) -func NewORM(ds sqlutil.DataSource) (ORM, error) { +func NewORM(ds sqlutil.DataSource, lggr logger.Logger) (ORM, error) { if ds == nil { return nil, fmt.Errorf("datasource to CCIP NewORM cannot be nil") } return &orm{ - ds: ds, + ds: ds, + lggr: lggr, }, nil } func (o *orm) GetGasPricesByDestChain(ctx context.Context, destChainSelector uint64) ([]GasPrice, error) { var gasPrices []GasPrice stmt := ` - SELECT DISTINCT ON (source_chain_selector) - source_chain_selector, gas_price, created_at + SELECT source_chain_selector, gas_price FROM ccip.observed_gas_prices - WHERE chain_selector = $1 - ORDER BY source_chain_selector, created_at DESC; + WHERE chain_selector = $1; ` err := o.ds.SelectContext(ctx, &gasPrices, stmt, destChainSelector) if err != nil { @@ -79,82 +65,147 @@ func (o *orm) GetGasPricesByDestChain(ctx context.Context, destChainSelector uin func (o *orm) GetTokenPricesByDestChain(ctx context.Context, destChainSelector uint64) ([]TokenPrice, error) { var tokenPrices []TokenPrice stmt := ` - SELECT DISTINCT ON (token_addr) - token_addr, token_price, created_at + SELECT token_addr, token_price FROM ccip.observed_token_prices - WHERE chain_selector = $1 - ORDER BY token_addr, created_at DESC; + WHERE chain_selector = $1; ` err := o.ds.SelectContext(ctx, &tokenPrices, stmt, destChainSelector) if err != nil { return nil, err } - return tokenPrices, nil } -func (o *orm) InsertGasPricesForDestChain(ctx context.Context, destChainSelector uint64, jobId int32, gasPrices []GasPriceUpdate) error { +func (o *orm) UpsertGasPricesForDestChain(ctx context.Context, destChainSelector uint64, gasPrices []GasPrice) (int64, error) { if len(gasPrices) == 0 { - return nil + return 0, nil + } + + uniqueGasUpdates := make(map[string]GasPrice) + for _, gasPrice := range gasPrices { + key := fmt.Sprintf("%d-%d", gasPrice.SourceChainSelector, destChainSelector) + uniqueGasUpdates[key] = gasPrice } - insertData := make([]map[string]interface{}, 0, len(gasPrices)) - for _, price := range gasPrices { + insertData := make([]map[string]interface{}, 0, len(uniqueGasUpdates)) + for _, price := range uniqueGasUpdates { insertData = append(insertData, map[string]interface{}{ "chain_selector": destChainSelector, - "job_id": jobId, "source_chain_selector": price.SourceChainSelector, "gas_price": price.GasPrice, }) } - // using statement_timestamp() to make testing easier - stmt := `INSERT INTO ccip.observed_gas_prices (chain_selector, job_id, source_chain_selector, gas_price, created_at) - VALUES (:chain_selector, :job_id, :source_chain_selector, :gas_price, statement_timestamp());` - _, err := o.ds.NamedExecContext(ctx, stmt, insertData) + stmt := `INSERT INTO ccip.observed_gas_prices (chain_selector, source_chain_selector, gas_price, updated_at) + VALUES (:chain_selector, :source_chain_selector, :gas_price, statement_timestamp()) + ON CONFLICT (source_chain_selector, chain_selector) + DO UPDATE SET gas_price = EXCLUDED.gas_price, updated_at = EXCLUDED.updated_at;` + + result, err := o.ds.NamedExecContext(ctx, stmt, insertData) if err != nil { - err = fmt.Errorf("error inserting gas prices for job %d: %w", jobId, err) + return 0, fmt.Errorf("error inserting gas prices %w", err) } - - return err + return result.RowsAffected() } -func (o *orm) InsertTokenPricesForDestChain(ctx context.Context, destChainSelector uint64, jobId int32, tokenPrices []TokenPriceUpdate) error { +// UpsertTokenPricesForDestChain inserts or updates only relevant token prices. +// In order to reduce locking an unnecessary writes to the table, we start with fetching current prices. +// If price for a token doesn't change or was updated recently we don't include that token to the upsert query. +// We don't run in TX intentionally, because we don't want to lock the table and conflicts are resolved on the insert level +func (o *orm) UpsertTokenPricesForDestChain(ctx context.Context, destChainSelector uint64, tokenPrices []TokenPrice, interval time.Duration) (int64, error) { if len(tokenPrices) == 0 { - return nil + return 0, nil } - insertData := make([]map[string]interface{}, 0, len(tokenPrices)) - for _, price := range tokenPrices { + tokensToUpdate, err := o.pickOnlyRelevantTokensForUpdate(ctx, destChainSelector, tokenPrices, interval) + if err != nil || len(tokensToUpdate) == 0 { + return 0, err + } + + insertData := make([]map[string]interface{}, 0, len(tokensToUpdate)) + for _, price := range tokensToUpdate { insertData = append(insertData, map[string]interface{}{ "chain_selector": destChainSelector, - "job_id": jobId, "token_addr": price.TokenAddr, "token_price": price.TokenPrice, }) } - // using statement_timestamp() to make testing easier - stmt := `INSERT INTO ccip.observed_token_prices (chain_selector, job_id, token_addr, token_price, created_at) - VALUES (:chain_selector, :job_id, :token_addr, :token_price, statement_timestamp());` - _, err := o.ds.NamedExecContext(ctx, stmt, insertData) + stmt := `INSERT INTO ccip.observed_token_prices (chain_selector, token_addr, token_price, updated_at) + VALUES (:chain_selector, :token_addr, :token_price, statement_timestamp()) + ON CONFLICT (token_addr, chain_selector) + DO UPDATE SET token_price = EXCLUDED.token_price, updated_at = EXCLUDED.updated_at;` + result, err := o.ds.NamedExecContext(ctx, stmt, insertData) if err != nil { - err = fmt.Errorf("error inserting token prices for job %d: %w", jobId, err) + return 0, fmt.Errorf("error inserting token prices %w", err) } - - return err + return result.RowsAffected() } -func (o *orm) ClearGasPricesByDestChain(ctx context.Context, destChainSelector uint64, expireSec int) error { - stmt := `DELETE FROM ccip.observed_gas_prices WHERE chain_selector = $1 AND created_at < (statement_timestamp() - $2 * interval '1 second')` +// pickOnlyRelevantTokensForUpdate returns only tokens that need to be updated. Multiple jobs can be updating the same tokens, +// in order to reduce table locking and redundant upserts we start with reading the table and checking which tokens are eligible for update. +// A token is eligible for update when time since last update is greater than the interval. +func (o *orm) pickOnlyRelevantTokensForUpdate( + ctx context.Context, + destChainSelector uint64, + tokenPrices []TokenPrice, + interval time.Duration, +) ([]TokenPrice, error) { + tokenPricesByAddress := toTokensByAddress(tokenPrices) + + // Picks only tokens which were recently updated and can be ignored, + // we will filter out these tokens from the upsert query. + stmt := ` + SELECT + token_addr + FROM ccip.observed_token_prices + WHERE + chain_selector = $1 + and token_addr = any($2) + and updated_at >= statement_timestamp() - $3::interval + ` + + pgInterval := fmt.Sprintf("%d milliseconds", interval.Milliseconds()) + args := []interface{}{destChainSelector, tokenAddrsToBytes(tokenPricesByAddress), pgInterval} + var dbTokensToIgnore []string + if err := o.ds.SelectContext(ctx, &dbTokensToIgnore, stmt, args...); err != nil { + return nil, err + } + + tokensToIgnore := make(map[string]struct{}, len(dbTokensToIgnore)) + for _, tk := range dbTokensToIgnore { + tokensToIgnore[tk] = struct{}{} + } - _, err := o.ds.ExecContext(ctx, stmt, destChainSelector, expireSec) - return err + tokenPricesToUpdate := make([]TokenPrice, 0, len(tokenPrices)) + for tokenAddr, tokenPrice := range tokenPricesByAddress { + eligibleForUpdate := false + if _, ok := tokensToIgnore[tokenAddr]; !ok { + eligibleForUpdate = true + tokenPricesToUpdate = append(tokenPricesToUpdate, TokenPrice{TokenAddr: tokenAddr, TokenPrice: tokenPrice}) + } + o.lggr.Debugw( + "Token price eligibility for database update", + "eligibleForUpdate", eligibleForUpdate, + "token", tokenAddr, + "price", tokenPrice, + ) + } + return tokenPricesToUpdate, nil } -func (o *orm) ClearTokenPricesByDestChain(ctx context.Context, destChainSelector uint64, expireSec int) error { - stmt := `DELETE FROM ccip.observed_token_prices WHERE chain_selector = $1 AND created_at < (statement_timestamp() - $2 * interval '1 second')` +func toTokensByAddress(tokens []TokenPrice) map[string]*assets.Wei { + tokensByAddr := make(map[string]*assets.Wei, len(tokens)) + for _, tk := range tokens { + tokensByAddr[tk.TokenAddr] = tk.TokenPrice + } + return tokensByAddr +} - _, err := o.ds.ExecContext(ctx, stmt, destChainSelector, expireSec) - return err +func tokenAddrsToBytes(tokens map[string]*assets.Wei) [][]byte { + addrs := make([][]byte, 0, len(tokens)) + for tkAddr := range tokens { + addrs = append(addrs, []byte(tkAddr)) + } + return addrs } diff --git a/core/services/ccip/orm_test.go b/core/services/ccip/orm_test.go index 7b7b8d8271..e778ddf6ce 100644 --- a/core/services/ccip/orm_test.go +++ b/core/services/ccip/orm_test.go @@ -15,13 +15,18 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +var ( + r = rand.New(rand.NewSource(time.Now().UnixNano())) ) func setupORM(t *testing.T) (ORM, sqlutil.DataSource) { t.Helper() db := pgtest.NewSqlxDB(t) - orm, err := NewORM(db) + orm, err := NewORM(db, logger.TestLogger(t)) require.NoError(t, err) @@ -37,12 +42,12 @@ func generateChainSelectors(n int) []uint64 { return selectors } -func generateGasPriceUpdates(chainSelector uint64, n int) []GasPriceUpdate { - updates := make([]GasPriceUpdate, n) +func generateGasPrices(chainSelector uint64, n int) []GasPrice { + updates := make([]GasPrice, n) for i := 0; i < n; i++ { // gas prices can take up whole range of uint256 uint256Max := new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(256), nil), big.NewInt(1)) - row := GasPriceUpdate{ + row := GasPrice{ SourceChainSelector: chainSelector, GasPrice: assets.NewWei(new(big.Int).Sub(uint256Max, big.NewInt(int64(i)))), } @@ -61,10 +66,21 @@ func generateTokenAddresses(n int) []string { return addrs } -func generateTokenPriceUpdates(tokenAddr string, n int) []TokenPriceUpdate { - updates := make([]TokenPriceUpdate, n) +func generateRandomTokenPrices(tokenAddrs []string) []TokenPrice { + updates := make([]TokenPrice, 0, len(tokenAddrs)) + for _, addr := range tokenAddrs { + updates = append(updates, TokenPrice{ + TokenAddr: addr, + TokenPrice: assets.NewWei(new(big.Int).Rand(r, big.NewInt(1e18))), + }) + } + return updates +} + +func generateTokenPrices(tokenAddr string, n int) []TokenPrice { + updates := make([]TokenPrice, n) for i := 0; i < n; i++ { - row := TokenPriceUpdate{ + row := TokenPrice{ TokenAddr: tokenAddr, TokenPrice: assets.NewWei(new(big.Int).Mul(big.NewInt(1e18), big.NewInt(int64(i)))), } @@ -134,20 +150,20 @@ func TestORM_InsertAndGetGasPrices(t *testing.T) { sourceSelectors := generateChainSelectors(numSourceChainSelectors) - updates := make(map[uint64][]GasPriceUpdate) + updates := make(map[uint64][]GasPrice) for _, selector := range sourceSelectors { - updates[selector] = generateGasPriceUpdates(selector, numUpdatesPerSourceSelector) + updates[selector] = generateGasPrices(selector, numUpdatesPerSourceSelector) } // 5 jobs, each inserting prices for 10 chains, with 20 updates per chain. - expectedPrices := make(map[uint64]GasPriceUpdate) + expectedPrices := make(map[uint64]GasPrice) for i := 0; i < numJobs; i++ { for selector, updatesPerSelector := range updates { lastIndex := len(updatesPerSelector) - 1 - err := orm.InsertGasPricesForDestChain(ctx, destSelector, int32(i), updatesPerSelector[:lastIndex]) + _, err := orm.UpsertGasPricesForDestChain(ctx, destSelector, updatesPerSelector[:lastIndex]) assert.NoError(t, err) - err = orm.InsertGasPricesForDestChain(ctx, destSelector, int32(i), updatesPerSelector[lastIndex:]) + _, err = orm.UpsertGasPricesForDestChain(ctx, destSelector, updatesPerSelector[lastIndex:]) assert.NoError(t, err) expectedPrices[selector] = updatesPerSelector[lastIndex] @@ -156,7 +172,7 @@ func TestORM_InsertAndGetGasPrices(t *testing.T) { // verify number of rows inserted numRows := getGasTableRowCount(t, db) - assert.Equal(t, numJobs*numSourceChainSelectors*numUpdatesPerSourceSelector, numRows) + assert.Equal(t, numSourceChainSelectors, numRows) prices, err := orm.GetGasPricesByDestChain(ctx, destSelector) assert.NoError(t, err) @@ -170,15 +186,15 @@ func TestORM_InsertAndGetGasPrices(t *testing.T) { } // after the initial inserts, insert new round of prices, 1 price per selector this time - var combinedUpdates []GasPriceUpdate + var combinedUpdates []GasPrice for selector, updatesPerSelector := range updates { combinedUpdates = append(combinedUpdates, updatesPerSelector[0]) expectedPrices[selector] = updatesPerSelector[0] } - err = orm.InsertGasPricesForDestChain(ctx, destSelector, 1, combinedUpdates) + _, err = orm.UpsertGasPricesForDestChain(ctx, destSelector, combinedUpdates) assert.NoError(t, err) - assert.Equal(t, numJobs*numSourceChainSelectors*numUpdatesPerSourceSelector+numSourceChainSelectors, getGasTableRowCount(t, db)) + assert.Equal(t, numSourceChainSelectors, getGasTableRowCount(t, db)) prices, err = orm.GetGasPricesByDestChain(ctx, destSelector) assert.NoError(t, err) @@ -190,7 +206,7 @@ func TestORM_InsertAndGetGasPrices(t *testing.T) { } } -func TestORM_InsertAndDeleteGasPrices(t *testing.T) { +func TestORM_UpsertGasPrices(t *testing.T) { t.Parallel() ctx := testutils.Context(t) @@ -202,13 +218,13 @@ func TestORM_InsertAndDeleteGasPrices(t *testing.T) { sourceSelectors := generateChainSelectors(numSourceChainSelectors) - updates := make(map[uint64][]GasPriceUpdate) + updates := make(map[uint64][]GasPrice) for _, selector := range sourceSelectors { - updates[selector] = generateGasPriceUpdates(selector, numUpdatesPerSourceSelector) + updates[selector] = generateGasPrices(selector, numUpdatesPerSourceSelector) } for _, updatesPerSelector := range updates { - err := orm.InsertGasPricesForDestChain(ctx, destSelector, 1, updatesPerSelector) + _, err := orm.UpsertGasPricesForDestChain(ctx, destSelector, updatesPerSelector) assert.NoError(t, err) } @@ -217,21 +233,11 @@ func TestORM_InsertAndDeleteGasPrices(t *testing.T) { // insert for the 2nd time after interimTimeStamp for _, updatesPerSelector := range updates { - err := orm.InsertGasPricesForDestChain(ctx, destSelector, 1, updatesPerSelector) + _, err := orm.UpsertGasPricesForDestChain(ctx, destSelector, updatesPerSelector) assert.NoError(t, err) } - assert.Equal(t, 2*numSourceChainSelectors*numUpdatesPerSourceSelector, getGasTableRowCount(t, db)) - - // clear by sleepSec should delete rows inserted before it - err := orm.ClearGasPricesByDestChain(ctx, destSelector, sleepSec) - assert.NoError(t, err) - assert.Equal(t, numSourceChainSelectors*numUpdatesPerSourceSelector, getGasTableRowCount(t, db)) - - // clear by 0 expiration seconds should delete all rows - err = orm.ClearGasPricesByDestChain(ctx, destSelector, 0) - assert.NoError(t, err) - assert.Equal(t, 0, getGasTableRowCount(t, db)) + assert.Equal(t, numSourceChainSelectors, getGasTableRowCount(t, db)) } func TestORM_InsertAndGetTokenPrices(t *testing.T) { @@ -247,20 +253,20 @@ func TestORM_InsertAndGetTokenPrices(t *testing.T) { addrs := generateTokenAddresses(numAddresses) - updates := make(map[string][]TokenPriceUpdate) + updates := make(map[string][]TokenPrice) for _, addr := range addrs { - updates[addr] = generateTokenPriceUpdates(addr, numUpdatesPerAddress) + updates[addr] = generateTokenPrices(addr, numUpdatesPerAddress) } // 5 jobs, each inserting prices for 10 chains, with 20 updates per chain. - expectedPrices := make(map[string]TokenPriceUpdate) + expectedPrices := make(map[string]TokenPrice) for i := 0; i < numJobs; i++ { for addr, updatesPerAddr := range updates { lastIndex := len(updatesPerAddr) - 1 - err := orm.InsertTokenPricesForDestChain(ctx, destSelector, int32(i), updatesPerAddr[:lastIndex]) + _, err := orm.UpsertTokenPricesForDestChain(ctx, destSelector, updatesPerAddr[:lastIndex], 0) assert.NoError(t, err) - err = orm.InsertTokenPricesForDestChain(ctx, destSelector, int32(i), updatesPerAddr[lastIndex:]) + _, err = orm.UpsertTokenPricesForDestChain(ctx, destSelector, updatesPerAddr[lastIndex:], 0) assert.NoError(t, err) expectedPrices[addr] = updatesPerAddr[lastIndex] @@ -269,7 +275,7 @@ func TestORM_InsertAndGetTokenPrices(t *testing.T) { // verify number of rows inserted numRows := getTokenTableRowCount(t, db) - assert.Equal(t, numJobs*numAddresses*numUpdatesPerAddress, numRows) + assert.Equal(t, numAddresses, numRows) prices, err := orm.GetTokenPricesByDestChain(ctx, destSelector) assert.NoError(t, err) @@ -283,15 +289,15 @@ func TestORM_InsertAndGetTokenPrices(t *testing.T) { } // after the initial inserts, insert new round of prices, 1 price per selector this time - var combinedUpdates []TokenPriceUpdate + var combinedUpdates []TokenPrice for addr, updatesPerAddr := range updates { combinedUpdates = append(combinedUpdates, updatesPerAddr[0]) expectedPrices[addr] = updatesPerAddr[0] } - err = orm.InsertTokenPricesForDestChain(ctx, destSelector, 1, combinedUpdates) + _, err = orm.UpsertTokenPricesForDestChain(ctx, destSelector, combinedUpdates, 0) assert.NoError(t, err) - assert.Equal(t, numJobs*numAddresses*numUpdatesPerAddress+numAddresses, getTokenTableRowCount(t, db)) + assert.Equal(t, numAddresses, getTokenTableRowCount(t, db)) prices, err = orm.GetTokenPricesByDestChain(ctx, destSelector) assert.NoError(t, err) @@ -303,46 +309,68 @@ func TestORM_InsertAndGetTokenPrices(t *testing.T) { } } -func TestORM_InsertAndDeleteTokenPrices(t *testing.T) { +func TestORM_InsertTokenPricesWhenExpired(t *testing.T) { t.Parallel() ctx := testutils.Context(t) - - orm, db := setupORM(t) + orm, _ := setupORM(t) numAddresses := 10 - numUpdatesPerAddress := 20 - destSelector := uint64(1) - + destSelector := rand.Uint64() addrs := generateTokenAddresses(numAddresses) + initTokenUpdates := generateRandomTokenPrices(addrs) - updates := make(map[string][]TokenPriceUpdate) - for _, addr := range addrs { - updates[addr] = generateTokenPriceUpdates(addr, numUpdatesPerAddress) - } + // Insert the first time, table is initialized + rowsUpdated, err := orm.UpsertTokenPricesForDestChain(ctx, destSelector, initTokenUpdates, time.Minute) + require.NoError(t, err) + assert.Equal(t, int64(numAddresses), rowsUpdated) - for _, updatesPerAddr := range updates { - err := orm.InsertTokenPricesForDestChain(ctx, destSelector, 1, updatesPerAddr) - assert.NoError(t, err) - } + //time.Sleep(100 * time.Millisecond) - sleepSec := 2 - time.Sleep(time.Duration(sleepSec) * time.Second) + // Insert the second time, no updates, because prices haven't changed + rowsUpdated, err = orm.UpsertTokenPricesForDestChain(ctx, destSelector, initTokenUpdates, time.Minute) + require.NoError(t, err) + assert.Equal(t, int64(0), rowsUpdated) - // insert for the 2nd time after interimTimeStamp - for _, updatesPerAddr := range updates { - err := orm.InsertTokenPricesForDestChain(ctx, destSelector, 1, updatesPerAddr) - assert.NoError(t, err) + // There are new prices, but we still haven't reached interval + newPrices := generateRandomTokenPrices(addrs) + rowsUpdated, err = orm.UpsertTokenPricesForDestChain(ctx, destSelector, newPrices, time.Minute) + require.NoError(t, err) + assert.Equal(t, int64(0), rowsUpdated) + + time.Sleep(100 * time.Millisecond) + + // Again with the same new prices, but this time interval is reached + rowsUpdated, err = orm.UpsertTokenPricesForDestChain(ctx, destSelector, newPrices, time.Millisecond) + require.NoError(t, err) + assert.Equal(t, int64(numAddresses), rowsUpdated) + + dbTokenPrices, err := orm.GetTokenPricesByDestChain(ctx, destSelector) + require.NoError(t, err) + assert.Len(t, dbTokenPrices, numAddresses) + + dbTokenPricesByAddr := toTokensByAddress(dbTokenPrices) + for _, tkPrice := range newPrices { + dbToken, ok := dbTokenPricesByAddr[tkPrice.TokenAddr] + assert.True(t, ok) + assert.Equal(t, dbToken, tkPrice.TokenPrice) } +} - assert.Equal(t, 2*numAddresses*numUpdatesPerAddress, getTokenTableRowCount(t, db)) +func Benchmark_UpsertsTheSameTokenPrices(b *testing.B) { + db := pgtest.NewSqlxDB(b) + orm, err := NewORM(db, logger.NullLogger) + require.NoError(b, err) - // clear by sleepSec should delete rows inserted before it - err := orm.ClearTokenPricesByDestChain(ctx, destSelector, sleepSec) - assert.NoError(t, err) - assert.Equal(t, numAddresses*numUpdatesPerAddress, getTokenTableRowCount(t, db)) + ctx := testutils.Context(b) + numAddresses := 50 + destSelector := rand.Uint64() + addrs := generateTokenAddresses(numAddresses) + tokenUpdates := generateRandomTokenPrices(addrs) - // clear by 0 expiration seconds should delete all rows - err = orm.ClearTokenPricesByDestChain(ctx, destSelector, 0) - assert.NoError(t, err) - assert.Equal(t, 0, getTokenTableRowCount(t, db)) + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, err1 := orm.UpsertTokenPricesForDestChain(ctx, destSelector, tokenUpdates, time.Second) + require.NoError(b, err1) + } } diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go b/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go index 5fb9733cc6..771fdd322f 100644 --- a/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go +++ b/core/services/ocr2/plugins/ccip/ccipcommit/initializers.go @@ -156,7 +156,7 @@ func NewCommitServices(ctx context.Context, ds sqlutil.DataSource, srcProvider c onRampAddress, ) - orm, err := cciporm.NewORM(ds) + orm, err := cciporm.NewObservedORM(ds, lggr) if err != nil { return nil, err } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go index ad44555477..2806c26e22 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service.go @@ -14,7 +14,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" cciporm "github.com/smartcontractkit/chainlink/v2/core/services/ccip" @@ -24,6 +23,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) // PriceService manages DB access for gas and token price data. @@ -49,23 +49,11 @@ const ( // Token prices are refreshed every 10 minutes, we only report prices for blue chip tokens, DS&A simulation show // their prices are stable, 10-minute resolution is accurate enough. tokenPriceUpdateInterval = 10 * time.Minute - - // Prices should expire after 25 minutes in DB. Prices should be fresh in the Commit plugin. - // 25 min provides sufficient buffer for the Commit plugin to withstand transient price update outages, while - // surfacing price update outages quickly enough. - priceExpireThreshold = 25 * time.Minute - - // Cleanups are called every 10 minutes. For a given job, on average we may expect 3 token prices and 1 gas price. - // 10 minutes should result in ~13 rows being cleaned up per job, it is not a heavy load on DB, so there is no need - // to run cleanup more frequently. We shouldn't clean up less frequently than `priceExpireThreshold`. - priceCleanupInterval = 10 * time.Minute ) type priceService struct { - priceExpireThreshold time.Duration - cleanupInterval time.Duration - gasUpdateInterval time.Duration - tokenUpdateInterval time.Duration + gasUpdateInterval time.Duration + tokenUpdateInterval time.Duration lggr logger.Logger orm cciporm.ORM @@ -100,10 +88,8 @@ func NewPriceService( ctx, cancel := context.WithCancel(context.Background()) pw := &priceService{ - priceExpireThreshold: priceExpireThreshold, - cleanupInterval: utils.WithJitter(priceCleanupInterval), // use WithJitter to avoid multiple services impacting DB at same time - gasUpdateInterval: utils.WithJitter(gasPriceUpdateInterval), - tokenUpdateInterval: utils.WithJitter(tokenPriceUpdateInterval), + gasUpdateInterval: gasPriceUpdateInterval, + tokenUpdateInterval: tokenPriceUpdateInterval, lggr: lggr, orm: orm, @@ -142,13 +128,11 @@ func (p *priceService) Close() error { } func (p *priceService) run() { - cleanupTicker := time.NewTicker(p.cleanupInterval) - gasUpdateTicker := time.NewTicker(p.gasUpdateInterval) - tokenUpdateTicker := time.NewTicker(p.tokenUpdateInterval) + gasUpdateTicker := time.NewTicker(utils.WithJitter(p.gasUpdateInterval)) + tokenUpdateTicker := time.NewTicker(utils.WithJitter(p.tokenUpdateInterval)) go func() { defer p.wg.Done() - defer cleanupTicker.Stop() defer gasUpdateTicker.Stop() defer tokenUpdateTicker.Stop() @@ -156,11 +140,6 @@ func (p *priceService) run() { select { case <-p.backgroundCtx.Done(): return - case <-cleanupTicker.C: - err := p.runCleanup(p.backgroundCtx) - if err != nil { - p.lggr.Errorw("Error when cleaning up in-db prices in the background", "err", err) - } case <-gasUpdateTicker.C: err := p.runGasPriceUpdate(p.backgroundCtx) if err != nil { @@ -240,28 +219,6 @@ func (p *priceService) GetGasAndTokenPrices(ctx context.Context, destChainSelect return gasPrices, tokenPrices, nil } -func (p *priceService) runCleanup(ctx context.Context) error { - eg := new(errgroup.Group) - - eg.Go(func() error { - err := p.orm.ClearGasPricesByDestChain(ctx, p.destChainSelector, int(p.priceExpireThreshold.Seconds())) - if err != nil { - return fmt.Errorf("error clearing gas prices: %w", err) - } - return nil - }) - - eg.Go(func() error { - err := p.orm.ClearTokenPricesByDestChain(ctx, p.destChainSelector, int(p.priceExpireThreshold.Seconds())) - if err != nil { - return fmt.Errorf("error clearing token prices: %w", err) - } - return nil - }) - - return eg.Wait() -} - func (p *priceService) runGasPriceUpdate(ctx context.Context) error { // Protect against concurrent updates of `gasPriceEstimator` and `destPriceRegistryReader` // Price updates happen infrequently - once every `gasPriceUpdateInterval` seconds. @@ -446,28 +403,29 @@ func (p *priceService) observeTokenPriceUpdates( return tokenPricesUSD, nil } -func (p *priceService) writeGasPricesToDB(ctx context.Context, sourceGasPriceUSD *big.Int) (err error) { +func (p *priceService) writeGasPricesToDB(ctx context.Context, sourceGasPriceUSD *big.Int) error { if sourceGasPriceUSD == nil { return nil } - return p.orm.InsertGasPricesForDestChain(ctx, p.destChainSelector, p.jobId, []cciporm.GasPriceUpdate{ + _, err := p.orm.UpsertGasPricesForDestChain(ctx, p.destChainSelector, []cciporm.GasPrice{ { SourceChainSelector: p.sourceChainSelector, GasPrice: assets.NewWei(sourceGasPriceUSD), }, }) + return err } -func (p *priceService) writeTokenPricesToDB(ctx context.Context, tokenPricesUSD map[cciptypes.Address]*big.Int) (err error) { +func (p *priceService) writeTokenPricesToDB(ctx context.Context, tokenPricesUSD map[cciptypes.Address]*big.Int) error { if tokenPricesUSD == nil { return nil } - var tokenPrices []cciporm.TokenPriceUpdate + var tokenPrices []cciporm.TokenPrice for token, price := range tokenPricesUSD { - tokenPrices = append(tokenPrices, cciporm.TokenPriceUpdate{ + tokenPrices = append(tokenPrices, cciporm.TokenPrice{ TokenAddr: string(token), TokenPrice: assets.NewWei(price), }) @@ -478,7 +436,8 @@ func (p *priceService) writeTokenPricesToDB(ctx context.Context, tokenPricesUSD return tokenPrices[i].TokenAddr < tokenPrices[j].TokenAddr }) - return p.orm.InsertTokenPricesForDestChain(ctx, p.destChainSelector, p.jobId, tokenPrices) + _, err := p.orm.UpsertTokenPricesForDestChain(ctx, p.destChainSelector, tokenPrices, p.tokenUpdateInterval) + return err } // Input price is USD per full token, with 18 decimal precision diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go index 0468c3addb..a25c5d3c47 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdb/price_service_test.go @@ -19,7 +19,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" cciporm "github.com/smartcontractkit/chainlink/v2/core/services/ccip" @@ -30,81 +29,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" ) -func TestPriceService_priceCleanup(t *testing.T) { - lggr := logger.TestLogger(t) - jobId := int32(1) - destChainSelector := uint64(12345) - sourceChainSelector := uint64(67890) - - testCases := []struct { - name string - gasPriceError bool - tokenPriceError bool - expectedErr bool - }{ - { - name: "ORM called successfully", - gasPriceError: false, - tokenPriceError: false, - expectedErr: false, - }, - { - name: "gasPrice clear failed", - gasPriceError: true, - tokenPriceError: false, - expectedErr: true, - }, - { - name: "tokenPrice clear failed", - gasPriceError: false, - tokenPriceError: true, - expectedErr: true, - }, - { - name: "both ORM calls failed", - gasPriceError: true, - tokenPriceError: true, - expectedErr: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx := tests.Context(t) - - var gasPricesError error - var tokenPricesError error - if tc.gasPriceError { - gasPricesError = fmt.Errorf("gas prices error") - } - if tc.tokenPriceError { - tokenPricesError = fmt.Errorf("token prices error") - } - - mockOrm := ccipmocks.NewORM(t) - mockOrm.On("ClearGasPricesByDestChain", ctx, destChainSelector, int(priceExpireThreshold.Seconds())).Return(gasPricesError).Once() - mockOrm.On("ClearTokenPricesByDestChain", ctx, destChainSelector, int(priceExpireThreshold.Seconds())).Return(tokenPricesError).Once() - - priceService := NewPriceService( - lggr, - mockOrm, - jobId, - destChainSelector, - sourceChainSelector, - "", - nil, - nil, - ).(*priceService) - err := priceService.runCleanup(ctx) - if tc.expectedErr { - assert.Error(t, err) - } else { - assert.NoError(t, err) - } - }) - } -} - func TestPriceService_writeGasPrices(t *testing.T) { lggr := logger.TestLogger(t) jobId := int32(1) @@ -113,7 +37,7 @@ func TestPriceService_writeGasPrices(t *testing.T) { gasPrice := big.NewInt(1e18) - expectedGasPriceUpdate := []cciporm.GasPriceUpdate{ + expectedGasPriceUpdate := []cciporm.GasPrice{ { SourceChainSelector: sourceChainSelector, GasPrice: assets.NewWei(gasPrice), @@ -147,7 +71,7 @@ func TestPriceService_writeGasPrices(t *testing.T) { } mockOrm := ccipmocks.NewORM(t) - mockOrm.On("InsertGasPricesForDestChain", ctx, destChainSelector, jobId, expectedGasPriceUpdate).Return(gasPricesError).Once() + mockOrm.On("UpsertGasPricesForDestChain", ctx, destChainSelector, expectedGasPriceUpdate).Return(int64(0), gasPricesError).Once() priceService := NewPriceService( lggr, @@ -180,7 +104,7 @@ func TestPriceService_writeTokenPrices(t *testing.T) { "0x234": big.NewInt(3e18), } - expectedTokenPriceUpdate := []cciporm.TokenPriceUpdate{ + expectedTokenPriceUpdate := []cciporm.TokenPrice{ { TokenAddr: "0x123", TokenPrice: assets.NewWei(big.NewInt(2e18)), @@ -218,7 +142,8 @@ func TestPriceService_writeTokenPrices(t *testing.T) { } mockOrm := ccipmocks.NewORM(t) - mockOrm.On("InsertTokenPricesForDestChain", ctx, destChainSelector, jobId, expectedTokenPriceUpdate).Return(tokenPricesError).Once() + mockOrm.On("UpsertTokenPricesForDestChain", ctx, destChainSelector, expectedTokenPriceUpdate, tokenPriceUpdateInterval). + Return(int64(len(expectedTokenPriceUpdate)), tokenPricesError).Once() priceService := NewPriceService( lggr, @@ -802,7 +727,7 @@ func setupORM(t *testing.T) cciporm.ORM { t.Helper() db := pgtest.NewSqlxDB(t) - orm, err := cciporm.NewORM(db) + orm, err := cciporm.NewORM(db, logger.TestLogger(t)) require.NoError(t, err) @@ -824,7 +749,7 @@ func checkResultLen(t *testing.T, priceService PriceService, destChainSelector u return nil } -func TestPriceService_priceWriteAndCleanupInBackground(t *testing.T) { +func TestPriceService_priceWriteInBackground(t *testing.T) { lggr := logger.TestLogger(t) jobId := int32(1) destChainSelector := uint64(12345) @@ -896,16 +821,11 @@ func TestPriceService_priceWriteAndCleanupInBackground(t *testing.T) { gasUpdateInterval := 2000 * time.Millisecond tokenUpdateInterval := 5000 * time.Millisecond - cleanupInterval := 3000 * time.Millisecond // run gas price task every 2 second priceService.gasUpdateInterval = gasUpdateInterval // run token price task every 5 second priceService.tokenUpdateInterval = tokenUpdateInterval - // run cleanup every 3 seconds - priceService.cleanupInterval = cleanupInterval - // expire all prices during every cleanup - priceService.priceExpireThreshold = time.Duration(0) // initially, db is empty assert.NoError(t, checkResultLen(t, priceService, destChainSelector, 0, 0)) @@ -918,24 +838,5 @@ func TestPriceService_priceWriteAndCleanupInBackground(t *testing.T) { assert.NoError(t, err) assert.NoError(t, checkResultLen(t, priceService, destChainSelector, 1, len(laneTokens))) - // eventually prices will be cleaned - assert.Eventually(t, func() bool { - err := checkResultLen(t, priceService, destChainSelector, 0, 0) - return err == nil - }, testutils.WaitTimeout(t), testutils.TestInterval) - - // then prices will be updated again - assert.Eventually(t, func() bool { - err := checkResultLen(t, priceService, destChainSelector, 1, len(laneTokens)) - return err == nil - }, testutils.WaitTimeout(t), testutils.TestInterval) - assert.NoError(t, priceService.Close()) - assert.NoError(t, priceService.runCleanup(ctx)) - - // after stopping PriceService and runCleanup, no more updates are inserted - for i := 0; i < 5; i++ { - time.Sleep(time.Second) - assert.NoError(t, checkResultLen(t, priceService, destChainSelector, 0, 0)) - } } diff --git a/core/store/migrate/migrations/0250_ccip_token_prices_fix.sql b/core/store/migrate/migrations/0250_ccip_token_prices_fix.sql new file mode 100644 index 0000000000..6c6cf02b43 --- /dev/null +++ b/core/store/migrate/migrations/0250_ccip_token_prices_fix.sql @@ -0,0 +1,49 @@ +-- +goose Up + +-- We need to re-create tables from scratch because of the unique constraint on tokens and chains selectors +DROP TABLE ccip.observed_token_prices; +DROP TABLE ccip.observed_gas_prices; + +CREATE TABLE ccip.observed_token_prices +( + chain_selector NUMERIC(20, 0) NOT NULL, + token_addr BYTEA NOT NULL, + token_price NUMERIC(78, 0) NOT NULL, + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + PRIMARY KEY (chain_selector, token_addr) +); + +CREATE TABLE ccip.observed_gas_prices +( + chain_selector NUMERIC(20, 0) NOT NULL, + source_chain_selector NUMERIC(20, 0) NOT NULL, + gas_price NUMERIC(78, 0) NOT NULL, + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + PRIMARY KEY (chain_selector, source_chain_selector) +); + +-- +goose Down +DROP TABLE ccip.observed_token_prices; +DROP TABLE ccip.observed_gas_prices; + +-- Restore state from migration 0236_ccip_prices_cache.sql +CREATE TABLE ccip.observed_gas_prices +( + chain_selector NUMERIC(20, 0) NOT NULL, + job_id INTEGER NOT NULL, + source_chain_selector NUMERIC(20, 0) NOT NULL, + gas_price NUMERIC(78, 0) NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE TABLE ccip.observed_token_prices +( + chain_selector NUMERIC(20, 0) NOT NULL, + job_id INTEGER NOT NULL, + token_addr BYTEA NOT NULL, + token_price NUMERIC(78, 0) NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE INDEX idx_ccip_gas_prices_chain_gas_price_timestamp ON ccip.observed_gas_prices (chain_selector, source_chain_selector, created_at DESC); +CREATE INDEX idx_ccip_token_prices_token_price_timestamp ON ccip.observed_token_prices (chain_selector, token_addr, created_at DESC); From b9a433bff513223378b8b29c6f694446d00c345b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Thu, 22 Aug 2024 12:47:59 +0300 Subject: [PATCH 139/432] Create an empty registry if external registry is not connected (#14174) * Create an empty registry if external registry is not connected * Add changeset * Run go mod tidy * Update changeset to include a tag * Run make gomodstidy * Use the fixed version of chainlink-common * Bump chainlink-testing-framework --- .changeset/blue-roses-brush.md | 5 ++++ core/capabilities/registry.go | 28 ++++++++++++++++++ core/scripts/go.mod | 20 ++++++------- core/scripts/go.sum | 40 +++++++++++++------------- core/services/chainlink/application.go | 3 ++ go.mod | 20 ++++++------- go.sum | 40 +++++++++++++------------- integration-tests/go.mod | 20 ++++++------- integration-tests/go.sum | 40 +++++++++++++------------- integration-tests/load/go.mod | 20 ++++++------- integration-tests/load/go.sum | 40 +++++++++++++------------- 11 files changed, 156 insertions(+), 120 deletions(-) create mode 100644 .changeset/blue-roses-brush.md diff --git a/.changeset/blue-roses-brush.md b/.changeset/blue-roses-brush.md new file mode 100644 index 0000000000..57dc796c03 --- /dev/null +++ b/.changeset/blue-roses-brush.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added Allow workflows to run without external registry configured diff --git a/core/capabilities/registry.go b/core/capabilities/registry.go index 4da51a27b6..4728550580 100644 --- a/core/capabilities/registry.go +++ b/core/capabilities/registry.go @@ -8,6 +8,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink/v2/core/logger" + p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" ) @@ -199,3 +200,30 @@ func NewRegistry(lggr logger.Logger) *Registry { lggr: lggr.Named("CapabilitiesRegistry"), } } + +// TestMetadataRegistry is a test implementation of the metadataRegistry +// interface. It is used when ExternalCapabilitiesRegistry is not available. +type TestMetadataRegistry struct{} + +func (t *TestMetadataRegistry) LocalNode(ctx context.Context) (capabilities.Node, error) { + peerID := p2ptypes.PeerID{} + workflowDON := capabilities.DON{ + ID: 1, + ConfigVersion: 1, + Members: []p2ptypes.PeerID{ + peerID, + }, + F: 0, + IsPublic: false, + AcceptsWorkflows: true, + } + return capabilities.Node{ + PeerID: &peerID, + WorkflowDON: workflowDON, + CapabilityDONs: []capabilities.DON{}, + }, nil +} + +func (t *TestMetadataRegistry) ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (registrysyncer.CapabilityConfiguration, error) { + return registrysyncer.CapabilityConfiguration{}, nil +} diff --git a/core/scripts/go.mod b/core/scripts/go.mod index d17b8c89e8..f891dc3e14 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 @@ -330,17 +330,17 @@ require ( go.uber.org/ratelimit v0.3.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/tools v0.24.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 1680dc0e87..d1c8c65a5e 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1186,8 +1186,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 h1:bNsry/El6yigB00BBU3iIOhZHiPm5MgCrDkJEFNXL1U= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 h1:88WOOrXy7t8IxS+91AKItN/HTzIHvEgFNetZDOhosKc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097/go.mod h1:HqdnbHS9j9EKPidpSUI9S37zl0blbVjB+NP4ztdYta8= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= @@ -1474,8 +1474,8 @@ golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1486,8 +1486,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1515,8 +1515,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1573,8 +1573,8 @@ golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1599,8 +1599,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1686,8 +1686,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1695,8 +1695,8 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1709,8 +1709,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1782,8 +1782,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 3418ac11b3..3efc92c227 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -257,6 +257,9 @@ func NewApplication(opts ApplicationOpts) (Application, error) { srvcs = append(srvcs, wfLauncher, registrySyncer) } + } else { + globalLogger.Debug("External registry not configured, skipping registry syncer and starting with an empty registry") + opts.CapabilitiesRegistry.SetLocalRegistry(&capabilities.TestMetadataRegistry{}) } // LOOPs can be created as options, in the case of LOOP relayers, or diff --git a/go.mod b/go.mod index 35fa108f45..39517d4340 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 @@ -102,15 +102,15 @@ require ( go.opentelemetry.io/otel v1.28.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.25.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - golang.org/x/mod v0.19.0 - golang.org/x/net v0.27.0 - golang.org/x/sync v0.7.0 - golang.org/x/term v0.22.0 - golang.org/x/text v0.16.0 + golang.org/x/crypto v0.26.0 + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa + golang.org/x/mod v0.20.0 + golang.org/x/net v0.28.0 + golang.org/x/sync v0.8.0 + golang.org/x/term v0.23.0 + golang.org/x/text v0.17.0 golang.org/x/time v0.5.0 - golang.org/x/tools v0.23.0 + golang.org/x/tools v0.24.0 gonum.org/v1/gonum v0.15.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 @@ -336,7 +336,7 @@ require ( go.uber.org/ratelimit v0.3.0 // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sys v0.22.0 // indirect + golang.org/x/sys v0.23.0 // indirect google.golang.org/api v0.188.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect diff --git a/go.sum b/go.sum index 5123739709..c6ade4ce55 100644 --- a/go.sum +++ b/go.sum @@ -1141,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 h1:bNsry/El6yigB00BBU3iIOhZHiPm5MgCrDkJEFNXL1U= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 h1:88WOOrXy7t8IxS+91AKItN/HTzIHvEgFNetZDOhosKc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097/go.mod h1:HqdnbHS9j9EKPidpSUI9S37zl0blbVjB+NP4ztdYta8= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= @@ -1426,8 +1426,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1438,8 +1438,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1467,8 +1467,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1524,8 +1524,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1550,8 +1550,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1636,8 +1636,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1646,8 +1646,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1661,8 +1661,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1734,8 +1734,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index c1fb3a7d92..260e9bef1d 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -33,7 +33,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 github.com/smartcontractkit/chainlink-testing-framework v1.34.5 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 @@ -49,10 +49,10 @@ require ( go.uber.org/atomic v1.11.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.25.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - golang.org/x/sync v0.7.0 - golang.org/x/text v0.16.0 + golang.org/x/crypto v0.26.0 + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa + golang.org/x/sync v0.8.0 + golang.org/x/text v0.17.0 gopkg.in/guregu/null.v4 v4.0.0 k8s.io/apimachinery v0.28.2 ) @@ -450,13 +450,13 @@ require ( go.uber.org/ratelimit v0.3.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/term v0.23.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/tools v0.24.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 98c4928c2d..be87459a24 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1490,8 +1490,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 h1:bNsry/El6yigB00BBU3iIOhZHiPm5MgCrDkJEFNXL1U= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 h1:88WOOrXy7t8IxS+91AKItN/HTzIHvEgFNetZDOhosKc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097/go.mod h1:HqdnbHS9j9EKPidpSUI9S37zl0blbVjB+NP4ztdYta8= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= @@ -1826,8 +1826,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1838,8 +1838,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1867,8 +1867,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1930,8 +1930,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1960,8 +1960,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2058,8 +2058,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2071,8 +2071,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2086,8 +2086,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2165,8 +2165,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index da7bf46a92..8908d3f473 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.31.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 github.com/smartcontractkit/chainlink-testing-framework v1.34.5 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 @@ -445,17 +445,17 @@ require ( go.uber.org/zap v1.27.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/tools v0.24.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 8e2d18aaf4..bf36247e5e 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1472,8 +1472,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33 h1:bNsry/El6yigB00BBU3iIOhZHiPm5MgCrDkJEFNXL1U= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240816204408-654165b6ee33/go.mod h1:Jg1sCTsbxg76YByI8ifpFby3FvVqISStHT8ypy9ocmY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 h1:88WOOrXy7t8IxS+91AKItN/HTzIHvEgFNetZDOhosKc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097/go.mod h1:HqdnbHS9j9EKPidpSUI9S37zl0blbVjB+NP4ztdYta8= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= @@ -1808,8 +1808,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1820,8 +1820,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1849,8 +1849,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1912,8 +1912,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1942,8 +1942,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2038,8 +2038,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2051,8 +2051,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2066,8 +2066,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2145,8 +2145,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 8d58c697c30cb56f476a0d9e789afa24120cca06 Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:29:58 +0400 Subject: [PATCH 140/432] update test parallel count for automation tests (#14199) --- .github/e2e-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 6a46e76f01..679477e54b 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -215,7 +215,7 @@ runner-test-matrix: workflows: - PR E2E Core Tests - Nightly E2E Tests - test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_3_conditional_native|TestAutomationBasic/registry_2_3_conditional_link$" -test.parallel=3 -timeout 30m -count=1 -json + test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_3_conditional_native|TestAutomationBasic/registry_2_3_conditional_link$" -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated - id: smoke/automation_test.go:^TestAutomationBasic/registry_2_3_logtrigger_native|TestAutomationBasic/registry_2_3_logtrigger_link$ @@ -375,7 +375,7 @@ runner-test-matrix: workflows: - PR E2E Core Tests - Nightly E2E Tests - test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperCheckPerformGasLimit$ -test.parallel=3 -timeout 30m -count=1 -json + test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperCheckPerformGasLimit$ -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated - id: smoke/keeper_test.go:^TestKeeperRegisterUpkeep$ From e452ee1ddb520b86f827ac75cccdb0719e9f5335 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Thu, 22 Aug 2024 14:02:56 +0200 Subject: [PATCH 141/432] [TT-1492] add step to publish comment with Slither report job summary (#14198) * add step to publish comment with Slither report job summary * Update gethwrappers * add step to publish comment with Slither report job summary * try with failing Slither * try with good and bad * remove test files * add link to artifact url in the comment * trigger slither * Update gethwrappers * remove test file * try using pusher.username instead of actor * try with modified * remove test files --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .github/workflows/solidity-foundry.yml | 59 ++++++++++++++++++---- contracts/.changeset/eighty-ways-vanish.md | 5 ++ 2 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 contracts/.changeset/eighty-ways-vanish.md diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index c1da33dc6f..ef643e32e8 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -74,16 +74,16 @@ jobs: list-files: 'shell' filters: | non_src: - - '.github/workflows/solidity-foundry.yml' + - '.github/workflows/solidity-foundry.yml' - 'contracts/foundry.toml' - 'contracts/gas-snapshots/*.gas-snapshot' - 'contracts/package.json' sol: - modified|added: 'contracts/src/v0.8/**/*.sol' sol_mod_only: - - modified: 'contracts/src/v0.8/**/!(*.t).sol' + - modified: 'contracts/src/v0.8/**/!(tests|mocks)/!(*.t).sol' not_test_sol: - - modified|added: 'contracts/src/v0.8/**/!(*.t).sol' + - modified|added: 'contracts/src/v0.8/**/!(tests|mocks)/!(*.t).sol' automation: - 'contracts/src/v0.8/automation/**/*.sol' ccip: @@ -112,7 +112,7 @@ jobs: - 'contracts/src/v0.8/transmission/**/*.sol' tests: - if: ${{ needs.changes.outputs.non_src_changes == 'true' || needs.changes.outputs.sol_modified == 'true' }} + if: ${{ needs.changes.outputs.non_src_changes == 'true' || needs.changes.outputs.sol_modified_added == 'true' }} strategy: fail-fast: false matrix: @@ -425,8 +425,7 @@ jobs: fi else - echo "::error::Failed to find current commit's equivalent of $base_report (file $current_file doesn't exist, but should have been generated). Please check Slither logs." - exit 1 + echo "::warning::Failed to find current commit's equivalent of $base_report (file $current_report doesn't exist, but should have been generated). Please check Slither logs." fi done @@ -458,6 +457,49 @@ jobs: contracts/slither-reports-current retention-days: 7 + - name: Find Slither comment in the PR + uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3.0.0 + id: find-comment + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: 'Static analysis results' + + - name: Extract job summary URL + id: job-summary-url + uses: pl-strflt/job-summary-url-action@df2d22c5351f73e0a187d20879854b8d98e6e001 # v1.0.0 + with: + job: 'Run static analysis' + + - name: Build Slither reports artifacts URL + id: build-slither-artifact-url + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + ARTIFACTS=$(gh api -X GET repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts) + ARTIFACT_ID=$(echo "$ARTIFACTS" | jq '.artifacts[] | select(.name=="slither-reports-${{ github.sha }}") | .id') + echo "Artifact ID: $ARTIFACT_ID" + + slither_artifact_url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/$ARTIFACT_ID" + echo "slither_artifact_url=$slither_artifact_url" >> $GITHUB_OUTPUT + + - name: Create or update Slither comment in the PR + uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0 + with: + comment-id: ${{ steps.find-comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body: | + ## Static analysis results are available + Hey @${{ github.event.push && github.event.push.pusher && github.event.push.pusher.username || github.actor }}, you can view Slither reports in the job summary [here](${{ steps.job-summary-url.outputs.job_summary_url }}) or download them as artifact [here](${{ steps.build-slither-artifact-url.outputs.slither_artifact_url }}). + + Please check them before merging and make sure you have addressed all issues. + edit-mode: replace + + - name: Remove temp artifacts + uses: geekyeggo/delete-artifact@24928e75e6e6590170563b8ddae9fac674508aa1 # v5.0 + with: + name: tmp-* + - name: Collect Metrics id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 @@ -469,11 +511,6 @@ jobs: this-job-name: Run static analysis continue-on-error: true - - name: Remove temp artifacts - uses: geekyeggo/delete-artifact@24928e75e6e6590170563b8ddae9fac674508aa1 # v5.0 - with: - name: tmp-* - solidity-forge-fmt: name: Forge fmt ${{ matrix.product.name }} if: ${{ needs.changes.outputs.non_src_changes == 'true' || needs.changes.outputs.not_test_sol_modified == 'true' }} diff --git a/contracts/.changeset/eighty-ways-vanish.md b/contracts/.changeset/eighty-ways-vanish.md new file mode 100644 index 0000000000..3a48ca4e71 --- /dev/null +++ b/contracts/.changeset/eighty-ways-vanish.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +Publish a comment in PR mentioning the actor and informing her about avilability of Slither reports. From 2900a1eb26e7408141d1162f2312799016a0b9fc Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:25:26 +0200 Subject: [PATCH 142/432] Fix for E2E tests nightly workflow (#14200) * Fix slack notification in e2e reusable workflow Fix notification when no tests were executed. Then load-test-configurations fails and failed notification will be send * Fix nightly workflow * Fix * Run tests on workflow or test list changes * Update job names --- .github/e2e-tests.yml | 4 ++-- .github/workflows/integration-tests.yml | 16 ++++++++++------ .../run-e2e-tests-reusable-workflow.yml | 18 +++++++++--------- .github/workflows/run-nightly-e2e-tests.yml | 2 +- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 679477e54b..7b4a2b97eb 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -161,7 +161,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ && go test smoke/ocr2_test.go -timeout 30m -count=1 -test.parallel=6 -json pyroscope_env: ci-smoke-ocr2-plugins-evm-simulated test_env_vars: - E2E_TEST_CHAINLINK_VERSION: '{{ env.GITHUB_SHA_PLUGINS }}' # This is the chainlink version that has the plugins + E2E_TEST_CHAINLINK_VERSION: '{{ env.DEFAULT_CHAINLINK_PLUGINS_VERSION }}' # This is the chainlink version that has the plugins ENABLE_OTEL_TRACES: true # END: OCR tests @@ -823,7 +823,7 @@ runner-test-matrix: E2E_TEST_CHAINLINK_IMAGE: public.ecr.aws/chainlink/chainlink E2E_TEST_CHAINLINK_VERSION: '{{ env.LATEST_CHAINLINK_RELEASE_VERSION }}' E2E_TEST_CHAINLINK_UPGRADE_IMAGE: '{{ env.QA_CHAINLINK_IMAGE }}' - E2E_TEST_CHAINLINK_UPGRADE_VERSION: '{{ env.GITHUB_SHA }}' + E2E_TEST_CHAINLINK_UPGRADE_VERSION: '{{ env.DEFAULT_CHAINLINK_VERSION }}' # END: Other tests diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 8a96a66a68..972228bc8e 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -92,18 +92,21 @@ jobs: id: changes with: filters: | + github_ci_changes: + - '.github/workflows/integration-tests.yml' + - '.github/workflows/run-e2e-tests-reusable-workflow.yml' + - '.github/e2e-tests.yml' core_changes: - '**/*.go' - '**/*go.sum' - '**/*go.mod' - - '.github/workflows/integration-tests.yml' - '**/*Dockerfile' - 'core/**/migrations/*.sql' - 'core/**/config/**/*.toml' - 'integration-tests/**/*.toml' ccip_changes: - '**/*ccip*' - - '**/*ccip*/**' + - '**/*ccip*/**' - name: Ignore Filter On Workflow Dispatch if: ${{ github.event_name == 'workflow_dispatch' }} id: ignore-filter @@ -120,6 +123,7 @@ jobs: this-job-name: Check Paths That Require Tests To Run continue-on-error: true outputs: + github_ci_changes: ${{ steps.ignore-filter.outputs.changes || steps.changes.outputs.github_ci_changes }} core_changes: ${{ steps.ignore-filter.outputs.changes || steps.changes.outputs.core_changes }} ccip_changes: ${{ steps.ignore-filter.outputs.changes || steps.changes.outputs.ccip_changes }} @@ -193,7 +197,7 @@ jobs: needs: [changes, enforce-ctf-version] steps: - name: Collect Metrics - if: needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch' + if: needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true' || github.event_name == 'workflow_dispatch' id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 with: @@ -218,7 +222,7 @@ jobs: aws-region: ${{ secrets.AWS_REGION }} set-git-config: "true" - name: Build Chainlink Image - if: needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch' + if: needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true' || github.event_name == 'workflow_dispatch' uses: ./.github/actions/build-chainlink-image with: tag_suffix: ${{ matrix.image.tag-suffix }} @@ -237,7 +241,7 @@ jobs: id-token: write contents: read needs: [build-chainlink, changes] - if: needs.changes.outputs.core_changes == 'true' + if: needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true' uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml with: workflow_name: Run Core E2E Tests @@ -273,7 +277,7 @@ jobs: id-token: write contents: read needs: [build-chainlink, changes] - if: needs.changes.outputs.ccip_changes == 'true' + if: needs.changes.outputs.ccip_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true' uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml with: workflow_name: Run CCIP E2E Tests diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index 92bc780f43..182e0f31d5 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -10,11 +10,11 @@ on: type: string default: 'Run E2E Tests' chainlink_version: - description: 'Enter Chainlink version to use for the tests. Example: "v2.10.0" or sha' + description: 'Enter Chainlink version to use for the tests. Example: v2.10.0, develop or commit sha' required: false type: string chainlink_upgrade_version: - description: 'Enter Chainlink version to upgrade to for upgrade tests. Example: "v2.10.0" or sha' + description: 'Enter Chainlink version to use for the upgrade tests. Example: v2.10.0, develop or commit sha' required: false type: string test_ids: @@ -134,8 +134,8 @@ on: env: CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink QA_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - GITHUB_SHA: ${{ github.sha }} - GITHUB_SHA_PLUGINS: ${{ github.sha }}-plugins + DEFAULT_CHAINLINK_VERSION: ${{ inputs.chainlink_version || github.sha }} + DEFAULT_CHAINLINK_PLUGINS_VERSION: ${{ inputs.chainlink_version != '' && format('{0}-plugins', inputs.chainlink_version) || format('{0}-plugins', github.sha) }} CHAINLINK_ENV_USER: ${{ github.actor }} CHAINLINK_COMMIT_SHA: ${{ inputs.evm-ref || github.sha }} SELECTED_NETWORKS: SIMULATED @@ -408,7 +408,7 @@ jobs: # Run Docker tests run-docker-tests: - name: Run ${{ matrix.tests.id }} + name: ${{ matrix.tests.id }} needs: [load-test-configurations, require-chainlink-image-versions-in-qa-ecr, require-chainlink-plugin-versions-in-qa-ecr, get_latest_chainlink_release_version] # Run when none of the needed jobs fail or are cancelled (skipped or successful jobs are ok) if: ${{ needs.load-test-configurations.outputs.run-docker-tests == 'true' && always() && !failure() && !cancelled() }} @@ -435,7 +435,7 @@ jobs: org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ${{ inputs.workflow_name }} / Run ${{ matrix.tests.id }} + this-job-name: ${{ inputs.workflow_name }} / ${{ matrix.tests.id }} test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' continue-on-error: true @@ -626,7 +626,7 @@ jobs: run-k8s-runner-tests: needs: [load-test-configurations, prepare-remote-runner-test-image, require-chainlink-image-versions-in-qa-ecr, require-chainlink-plugin-versions-in-qa-ecr, get_latest_chainlink_release_version] if: ${{ needs.load-test-configurations.outputs.run-k8s-tests == 'true' && always() && !failure() && !cancelled() }} - name: Run ${{ matrix.tests.id }} + name: ${{ matrix.tests.id }} runs-on: ${{ matrix.tests.runs_on }} strategy: fail-fast: false @@ -650,7 +650,7 @@ jobs: org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ${{ inputs.workflow_name }} / Run ${{ matrix.tests.id }} + this-job-name: ${{ inputs.workflow_name }} / ${{ matrix.tests.id }} continue-on-error: true - name: Checkout repository @@ -769,7 +769,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "${{ inputs.slack_notification_after_tests_name }} - ${{ steps.combine_results.outputs.result == 'failure' && 'Failed :x:' || steps.combine_results.outputs.result == 'cancelled' && 'Cancelled :warning:' || 'Passed :white_check_mark:' }}" + "text": "${{ inputs.slack_notification_after_tests_name }} - ${{ contains(join(needs.*.result, ','), 'failure') && 'Failed :x:' || contains(join(needs.*.result, ','), 'cancelled') && 'Cancelled :warning:' || 'Passed :white_check_mark:' }}" } }, { diff --git a/.github/workflows/run-nightly-e2e-tests.yml b/.github/workflows/run-nightly-e2e-tests.yml index ab12b36555..6d7056ed04 100644 --- a/.github/workflows/run-nightly-e2e-tests.yml +++ b/.github/workflows/run-nightly-e2e-tests.yml @@ -12,7 +12,7 @@ jobs: uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml with: chainlink_version: develop - test_workflow: Run Nightly E2E Tests + test_workflow: Nightly E2E Tests slack_notification_after_tests: true slack_notification_after_tests_channel_id: "#team-test-tooling-internal" slack_notification_after_tests_name: Nightly E2E Tests From 35f68c806b10cc0fe4a565293e32e2f5581bfeb5 Mon Sep 17 00:00:00 2001 From: Graham Goh Date: Fri, 23 Aug 2024 00:06:02 +1000 Subject: [PATCH 143/432] fix(RegisterManager): handle error correctly (#14183) Currently, when something goes wrong in `tx.CreateManager` such as invalid sql, the error returned is ignored. We should handle the error and return accordingly. Co-authored-by: Ivaylo Novakov --- .changeset/smart-pumas-collect.md | 5 ++++ core/services/feeds/service.go | 5 +++- core/services/feeds/service_test.go | 46 +++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 .changeset/smart-pumas-collect.md diff --git a/.changeset/smart-pumas-collect.md b/.changeset/smart-pumas-collect.md new file mode 100644 index 0000000000..0748f170b9 --- /dev/null +++ b/.changeset/smart-pumas-collect.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#bugfix Fix incorrect error handling when registering a new feed manager diff --git a/core/services/feeds/service.go b/core/services/feeds/service.go index 1733d4a758..5e8e743109 100644 --- a/core/services/feeds/service.go +++ b/core/services/feeds/service.go @@ -209,7 +209,7 @@ func (s *service) RegisterManager(ctx context.Context, params RegisterManagerPar var txerr error id, txerr = tx.CreateManager(ctx, &mgr) - if err != nil { + if txerr != nil { return txerr } @@ -219,6 +219,9 @@ func (s *service) RegisterManager(ctx context.Context, params RegisterManagerPar return nil }) + if err != nil { + return 0, err + } privkey, err := s.getCSAPrivateKey() if err != nil { diff --git a/core/services/feeds/service_test.go b/core/services/feeds/service_test.go index 3ee7adc0d7..e98ae984fb 100644 --- a/core/services/feeds/service_test.go +++ b/core/services/feeds/service_test.go @@ -265,6 +265,52 @@ func Test_Service_RegisterManager(t *testing.T) { assert.Equal(t, actual, id) } +func Test_Service_RegisterManager_InvalidCreateManager(t *testing.T) { + t.Parallel() + + var ( + id = int64(1) + pubKeyHex = "0f17c3bf72de8beef6e2d17a14c0a972f5d7e0e66e70722373f12b88382d40f9" + ) + + var pubKey crypto.PublicKey + _, err := hex.Decode([]byte(pubKeyHex), pubKey) + require.NoError(t, err) + + var ( + mgr = feeds.FeedsManager{ + Name: "FMS", + URI: "localhost:8080", + PublicKey: pubKey, + } + params = feeds.RegisterManagerParams{ + Name: "FMS", + URI: "localhost:8080", + PublicKey: pubKey, + } + ) + + svc := setupTestService(t) + + svc.orm.On("CountManagers", mock.Anything).Return(int64(0), nil) + svc.orm.On("CreateManager", mock.Anything, &mgr, mock.Anything). + Return(id, errors.New("orm error")) + // ListManagers runs in a goroutine so it might be called. + svc.orm.On("ListManagers", testutils.Context(t)).Return([]feeds.FeedsManager{mgr}, nil).Maybe() + + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) + _, err = svc.RegisterManager(testutils.Context(t), params) + // We need to stop the service because the manager will attempt to make a + // connection + svc.Close() + require.Error(t, err) + assert.Equal(t, "orm error", err.Error()) +} + func Test_Service_ListManagers(t *testing.T) { t.Parallel() ctx := testutils.Context(t) From d50feb0d8c5b2eee8112246d5c782e86ad2832bb Mon Sep 17 00:00:00 2001 From: momentmaker Date: Thu, 22 Aug 2024 10:52:44 -0500 Subject: [PATCH 144/432] migrate goreleaser to use ~> v2 as default version to use (#14190) * migrate goreleaser to use ~> v2 as default version to use * add version and fix deprecated keys in goreleaser yaml --- .../actions/goreleaser-build-sign-publish/README.md | 10 +++++++--- .../actions/goreleaser-build-sign-publish/action.yml | 4 ++-- .goreleaser.develop.yaml | 4 +++- .goreleaser.devspace.yaml | 5 +++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.github/actions/goreleaser-build-sign-publish/README.md b/.github/actions/goreleaser-build-sign-publish/README.md index d6bf7e6fd4..189578391f 100644 --- a/.github/actions/goreleaser-build-sign-publish/README.md +++ b/.github/actions/goreleaser-build-sign-publish/README.md @@ -97,13 +97,17 @@ Following inputs can be used as `step.with` keys | Name | Type | Default | Description | | ---------------------------- | ------ | ------------------ | ----------------------------------------------------------------------- | -| `goreleaser-version` | String | `1.13.1` | `goreleaser` version | -| `zig-version` | String | `0.10.0` | `zig` version | -| `cosign-version` | String | `v1.13.1` | `cosign` version | +| `goreleaser-version` | String | `~> v2` | `goreleaser` version | +| `zig-version` | String | `0.10.1` | `zig` version | +| `cosign-version` | String | `v2.2.2` | `cosign` version | | `macos-sdk-dir` | String | `MacOSX12.3.sdk` | MacOSX sdk directory | | `enable-docker-publish` | Bool | `true` | Enable publishing of Docker images / manifests | | `docker-registry` | String | `localhost:5001` | Docker registry | +| `docker-image-name` | String | `chainlink` | Docker image name | +| `docker-image-tag` | String | `develop` | Docker image tag | | `enable-goreleaser-snapshot` | Bool | `false` | Enable goreleaser build / release snapshot | +| `enable-goreleaser-split` | Bool | `false` | Enable goreleaser build using split and merge | +| `goreleaser-split-arch` | String | `""` | The arch to build the image with - amd64, arm64 | | `goreleaser-exec` | String | `goreleaser` | The goreleaser executable, can invoke wrapper script | | `goreleaser-config` | String | `.goreleaser.yaml` | The goreleaser configuration yaml | | `enable-cosign` | Bool | `false` | Enable signing of Docker images | diff --git a/.github/actions/goreleaser-build-sign-publish/action.yml b/.github/actions/goreleaser-build-sign-publish/action.yml index c279c2f929..cf9da323de 100644 --- a/.github/actions/goreleaser-build-sign-publish/action.yml +++ b/.github/actions/goreleaser-build-sign-publish/action.yml @@ -3,7 +3,7 @@ description: A composite action that allows building and publishing signed chain inputs: goreleaser-version: description: The goreleaser version - default: 1.23.0 + default: "~> v2" required: false goreleaser-key: description: The goreleaser key @@ -83,7 +83,7 @@ runs: with: go-version-file: "go.mod" - name: Setup goreleaser - uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0 + uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0 with: distribution: goreleaser-pro install-only: true diff --git a/.goreleaser.develop.yaml b/.goreleaser.develop.yaml index c3126b30f6..08d8e4de94 100644 --- a/.goreleaser.develop.yaml +++ b/.goreleaser.develop.yaml @@ -1,5 +1,7 @@ project_name: chainlink +version: 2 + env: - ZIG_EXEC={{ if index .Env "ZIG_EXEC" }}{{ .Env.ZIG_EXEC }}{{ else }}zig{{ end }} - IMAGE_PREFIX={{ if index .Env "IMAGE_PREFIX" }}{{ .Env.IMAGE_PREFIX }}{{ else }}localhost:5001{{ end }} @@ -196,7 +198,7 @@ checksum: name_template: "checksums.txt" snapshot: - name_template: "{{ .Env.CHAINLINK_VERSION }}-{{ .ShortCommit }}" + version_template: "{{ .Env.CHAINLINK_VERSION }}-{{ .ShortCommit }}" partial: by: target diff --git a/.goreleaser.devspace.yaml b/.goreleaser.devspace.yaml index bca65e9045..d0167b34cd 100644 --- a/.goreleaser.devspace.yaml +++ b/.goreleaser.devspace.yaml @@ -1,6 +1,7 @@ -## goreleaser <1.14.0 project_name: chainlink-devspace +version: 2 + env: - ZIG_EXEC={{ if index .Env "ZIG_EXEC" }}{{ .Env.ZIG_EXEC }}{{ else }}zig{{ end }} - IMAGE_LABEL_DESCRIPTION="node of the decentralized oracle network, bridging on and off-chain computation" @@ -75,7 +76,7 @@ checksum: name_template: "checksums.txt" snapshot: - name_template: '{{ .Env.CHAINLINK_VERSION }}-{{ .Runtime.Goarch }}-{{ .Now.Format "2006-01-02-15-04-05Z" }}' + version_template: '{{ .Env.CHAINLINK_VERSION }}-{{ .Runtime.Goarch }}-{{ .Now.Format "2006-01-02-15-04-05Z" }}' changelog: sort: asc From 9c240b686753c72f94f8fb7e8c636483d5759963 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Thu, 22 Aug 2024 12:03:43 -0400 Subject: [PATCH 145/432] auto-10161: implement without zksync forwarder interface change (#14037) * add changeset * add some basic foundry tests * add zksync module and interfaces * update * update * add tests * fix lint * add more tests * update * test * format * add a zksync interface * update * update * add overhead funcs * update * update * update * update * update * clean up 1 * clean up 2 --- contracts/.changeset/thirty-lamps-reply.md | 5 + contracts/.solhintignore | 1 - ...zksync-automation-master-interface-v2_3.ts | 58 + .../automation/ZKSyncAutomationForwarder.sol | 31 +- .../interfaces/zksync/IGasBoundCaller.sol | 8 + .../interfaces/zksync/ISystemContext.sol | 10 + .../IZKSyncAutomationRegistryMaster2_3.sol | 441 ++ .../test/v2_3_zksync/BaseTest.t.sol | 500 ++ .../ZKSyncAutomationRegistry2_3.t.sol | 2772 +++++++++++ .../testhelpers/UpkeepCounterNew.sol | 126 + .../ZKSyncAutomationRegistry2_3.sol | 37 +- .../ZKSyncAutomationRegistryBase2_3.sol | 29 +- .../ZKSyncAutomationRegistryLogicC2_3.sol | 12 - .../src/v0.8/tests/MockGasBoundCaller.sol | 32 + .../v0.8/tests/MockZKSyncSystemContext.sol | 16 + .../ZKSyncAutomationRegistry2_3.test.ts | 4403 +++++++++++++++++ contracts/test/v0.8/automation/helpers.ts | 49 + 17 files changed, 8463 insertions(+), 67 deletions(-) create mode 100644 contracts/.changeset/thirty-lamps-reply.md create mode 100644 contracts/scripts/generate-zksync-automation-master-interface-v2_3.ts create mode 100644 contracts/src/v0.8/automation/interfaces/zksync/IGasBoundCaller.sol create mode 100644 contracts/src/v0.8/automation/interfaces/zksync/ISystemContext.sol create mode 100644 contracts/src/v0.8/automation/interfaces/zksync/IZKSyncAutomationRegistryMaster2_3.sol create mode 100644 contracts/src/v0.8/automation/test/v2_3_zksync/BaseTest.t.sol create mode 100644 contracts/src/v0.8/automation/test/v2_3_zksync/ZKSyncAutomationRegistry2_3.t.sol create mode 100644 contracts/src/v0.8/automation/testhelpers/UpkeepCounterNew.sol create mode 100644 contracts/src/v0.8/tests/MockGasBoundCaller.sol create mode 100644 contracts/src/v0.8/tests/MockZKSyncSystemContext.sol create mode 100644 contracts/test/v0.8/automation/ZKSyncAutomationRegistry2_3.test.ts diff --git a/contracts/.changeset/thirty-lamps-reply.md b/contracts/.changeset/thirty-lamps-reply.md new file mode 100644 index 0000000000..d8bcf8d4e8 --- /dev/null +++ b/contracts/.changeset/thirty-lamps-reply.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +implement an auto registry for zksync with no forwarder interface change diff --git a/contracts/.solhintignore b/contracts/.solhintignore index 55d195c305..bad1935442 100644 --- a/contracts/.solhintignore +++ b/contracts/.solhintignore @@ -18,7 +18,6 @@ ./src/v0.8/automation/libraries/internal/Cron.sol ./src/v0.8/automation/AutomationForwarder.sol ./src/v0.8/automation/AutomationForwarderLogic.sol -./src/v0.8/automation/ZKSyncAutomationForwarder.sol ./src/v0.8/automation/interfaces/v2_2/IAutomationRegistryMaster.sol ./src/v0.8/automation/interfaces/v2_3/IAutomationRegistryMaster2_3.sol diff --git a/contracts/scripts/generate-zksync-automation-master-interface-v2_3.ts b/contracts/scripts/generate-zksync-automation-master-interface-v2_3.ts new file mode 100644 index 0000000000..1b91fd3636 --- /dev/null +++ b/contracts/scripts/generate-zksync-automation-master-interface-v2_3.ts @@ -0,0 +1,58 @@ +/** + * @description this script generates a master interface for interacting with the automation registry + * @notice run this script with pnpm ts-node ./scripts/generate-zksync-automation-master-interface-v2_3.ts + */ +import { ZKSyncAutomationRegistry2_3__factory as Registry } from '../typechain/factories/ZKSyncAutomationRegistry2_3__factory' +import { ZKSyncAutomationRegistryLogicA2_3__factory as RegistryLogicA } from '../typechain/factories/ZKSyncAutomationRegistryLogicA2_3__factory' +import { ZKSyncAutomationRegistryLogicB2_3__factory as RegistryLogicB } from '../typechain/factories/ZKSyncAutomationRegistryLogicB2_3__factory' +import { ZKSyncAutomationRegistryLogicC2_3__factory as RegistryLogicC } from '../typechain/factories/ZKSyncAutomationRegistryLogicC2_3__factory' +import { utils } from 'ethers' +import fs from 'fs' +import { exec } from 'child_process' + +const dest = 'src/v0.8/automation/interfaces/zksync' +const srcDest = `${dest}/IZKSyncAutomationRegistryMaster2_3.sol` +const tmpDest = `${dest}/tmp.txt` + +const combinedABI = [] +const abiSet = new Set() +const abis = [ + Registry.abi, + RegistryLogicA.abi, + RegistryLogicB.abi, + RegistryLogicC.abi, +] + +for (const abi of abis) { + for (const entry of abi) { + const id = utils.id(JSON.stringify(entry)) + if (!abiSet.has(id)) { + abiSet.add(id) + if ( + entry.type === 'function' && + (entry.name === 'checkUpkeep' || + entry.name === 'checkCallback' || + entry.name === 'simulatePerformUpkeep') + ) { + entry.stateMutability = 'view' // override stateMutability for check / callback / simulate functions + } + combinedABI.push(entry) + } + } +} + +const checksum = utils.id(abis.join('')) + +fs.writeFileSync(`${tmpDest}`, JSON.stringify(combinedABI)) + +const cmd = ` +cat ${tmpDest} | pnpm abi-to-sol --solidity-version ^0.8.4 --license MIT > ${srcDest} IZKSyncAutomationRegistryMaster2_3; +echo "// solhint-disable \n// abi-checksum: ${checksum}" | cat - ${srcDest} > ${tmpDest} && mv ${tmpDest} ${srcDest}; +pnpm prettier --write ${srcDest}; +` + +exec(cmd) + +console.log( + 'generated new master interface for zksync automation registry v2_3', +) diff --git a/contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol b/contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol index cfbff1365e..fd6eb3dee9 100644 --- a/contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol +++ b/contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol @@ -2,16 +2,19 @@ pragma solidity ^0.8.16; import {IAutomationRegistryConsumer} from "./interfaces/IAutomationRegistryConsumer.sol"; +import {GAS_BOUND_CALLER, IGasBoundCaller} from "./interfaces/zksync/IGasBoundCaller.sol"; -uint256 constant PERFORM_GAS_CUSHION = 5_000; +uint256 constant PERFORM_GAS_CUSHION = 50_000; /** - * @title AutomationForwarder is a relayer that sits between the registry and the customer's target contract + * @title ZKSyncAutomationForwarder is a relayer that sits between the registry and the customer's target contract * @dev The purpose of the forwarder is to give customers a consistent address to authorize against, * which stays consistent between migrations. The Forwarder also exposes the registry address, so that users who * want to programmatically interact with the registry (ie top up funds) can do so. */ contract ZKSyncAutomationForwarder { + error InvalidCaller(address); + /// @notice the user's target contract address address private immutable i_target; @@ -31,11 +34,14 @@ contract ZKSyncAutomationForwarder { * @param gasAmount is the amount of gas to use in the call * @param data is the 4 bytes function selector + arbitrary function data * @return success indicating whether the target call succeeded or failed + * @return gasUsed the total gas used from this forwarding call */ function forward(uint256 gasAmount, bytes memory data) external returns (bool success, uint256 gasUsed) { - if (msg.sender != address(s_registry)) revert(); + if (msg.sender != address(s_registry)) revert InvalidCaller(msg.sender); + + uint256 g1 = gasleft(); address target = i_target; - gasUsed = gasleft(); + assembly { let g := gas() // Compute g -= PERFORM_GAS_CUSHION and check for underflow @@ -52,10 +58,18 @@ contract ZKSyncAutomationForwarder { if iszero(extcodesize(target)) { revert(0, 0) } - // call with exact gas - success := call(gasAmount, target, 0, add(data, 0x20), mload(data), 0, 0) } - gasUsed = gasUsed - gasleft(); + + bytes memory returnData; + // solhint-disable-next-line avoid-low-level-calls + (success, returnData) = GAS_BOUND_CALLER.delegatecall{gas: gasAmount}( + abi.encodeWithSelector(IGasBoundCaller.gasBoundCall.selector, target, gasAmount, data) + ); + uint256 pubdataGasSpent; + if (success) { + (, pubdataGasSpent) = abi.decode(returnData, (bytes, uint256)); + } + gasUsed = g1 - gasleft() + pubdataGasSpent; return (success, gasUsed); } @@ -63,7 +77,8 @@ contract ZKSyncAutomationForwarder { return i_target; } - fallback() external { + // solhint-disable-next-line no-complex-fallback + fallback() external payable { // copy to memory for assembly access address logic = i_logic; // copied directly from OZ's Proxy contract diff --git a/contracts/src/v0.8/automation/interfaces/zksync/IGasBoundCaller.sol b/contracts/src/v0.8/automation/interfaces/zksync/IGasBoundCaller.sol new file mode 100644 index 0000000000..9edb541f9a --- /dev/null +++ b/contracts/src/v0.8/automation/interfaces/zksync/IGasBoundCaller.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +address constant GAS_BOUND_CALLER = address(0xc706EC7dfA5D4Dc87f29f859094165E8290530f5); + +interface IGasBoundCaller { + function gasBoundCall(address _to, uint256 _maxTotalGas, bytes calldata _data) external payable; +} diff --git a/contracts/src/v0.8/automation/interfaces/zksync/ISystemContext.sol b/contracts/src/v0.8/automation/interfaces/zksync/ISystemContext.sol new file mode 100644 index 0000000000..c8f480065c --- /dev/null +++ b/contracts/src/v0.8/automation/interfaces/zksync/ISystemContext.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +ISystemContext constant SYSTEM_CONTEXT_CONTRACT = ISystemContext(address(0x800b)); + +interface ISystemContext { + function gasPrice() external view returns (uint256); + function gasPerPubdataByte() external view returns (uint256 gasPerPubdataByte); + function getCurrentPubdataSpent() external view returns (uint256 currentPubdataSpent); +} diff --git a/contracts/src/v0.8/automation/interfaces/zksync/IZKSyncAutomationRegistryMaster2_3.sol b/contracts/src/v0.8/automation/interfaces/zksync/IZKSyncAutomationRegistryMaster2_3.sol new file mode 100644 index 0000000000..26b8a7d5c5 --- /dev/null +++ b/contracts/src/v0.8/automation/interfaces/zksync/IZKSyncAutomationRegistryMaster2_3.sol @@ -0,0 +1,441 @@ +// solhint-disable +// abi-checksum: 0x5857a77a981fcb60dbdac0700e68420cbe544249b20d9326d51c5ef8584c5dd7 +// SPDX-License-Identifier: MIT +// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.6.6. SEE SOURCE BELOW. !! +pragma solidity ^0.8.4; + +interface IZKSyncAutomationRegistryMaster2_3 { + error ArrayHasNoEntries(); + error CannotCancel(); + error CheckDataExceedsLimit(); + error ConfigDigestMismatch(); + error DuplicateEntry(); + error DuplicateSigners(); + error GasLimitCanOnlyIncrease(); + error GasLimitOutsideRange(); + error IncorrectNumberOfFaultyOracles(); + error IncorrectNumberOfSignatures(); + error IncorrectNumberOfSigners(); + error IndexOutOfRange(); + error InsufficientBalance(uint256 available, uint256 requested); + error InsufficientLinkLiquidity(); + error InvalidDataLength(); + error InvalidFeed(); + error InvalidPayee(); + error InvalidRecipient(); + error InvalidReport(); + error InvalidSigner(); + error InvalidToken(); + error InvalidTransmitter(); + error InvalidTrigger(); + error InvalidTriggerType(); + error MigrationNotPermitted(); + error MustSettleOffchain(); + error MustSettleOnchain(); + error NotAContract(); + error OnlyActiveSigners(); + error OnlyActiveTransmitters(); + error OnlyCallableByAdmin(); + error OnlyCallableByLINKToken(); + error OnlyCallableByOwnerOrAdmin(); + error OnlyCallableByOwnerOrRegistrar(); + error OnlyCallableByPayee(); + error OnlyCallableByProposedAdmin(); + error OnlyCallableByProposedPayee(); + error OnlyCallableByUpkeepPrivilegeManager(); + error OnlyFinanceAdmin(); + error OnlyPausedUpkeep(); + error OnlySimulatedBackend(); + error OnlyUnpausedUpkeep(); + error ParameterLengthError(); + error ReentrantCall(); + error RegistryPaused(); + error RepeatedSigner(); + error RepeatedTransmitter(); + error TargetCheckReverted(bytes reason); + error TooManyOracles(); + error TranscoderNotSet(); + error TransferFailed(); + error UpkeepAlreadyExists(); + error UpkeepCancelled(); + error UpkeepNotCanceled(); + error UpkeepNotNeeded(); + error ValueNotChanged(); + error ZeroAddressNotAllowed(); + event AdminPrivilegeConfigSet(address indexed admin, bytes privilegeConfig); + event BillingConfigOverridden(uint256 indexed id, ZKSyncAutomationRegistryBase2_3.BillingOverrides overrides); + event BillingConfigOverrideRemoved(uint256 indexed id); + event BillingConfigSet(address indexed token, ZKSyncAutomationRegistryBase2_3.BillingConfig config); + event CancelledUpkeepReport(uint256 indexed id, bytes trigger); + event ChainSpecificModuleUpdated(address newModule); + event ConfigSet( + uint32 previousConfigBlockNumber, + bytes32 configDigest, + uint64 configCount, + address[] signers, + address[] transmitters, + uint8 f, + bytes onchainConfig, + uint64 offchainConfigVersion, + bytes offchainConfig + ); + event DedupKeyAdded(bytes32 indexed dedupKey); + event FeesWithdrawn(address indexed assetAddress, address indexed recipient, uint256 amount); + event FundsAdded(uint256 indexed id, address indexed from, uint96 amount); + event FundsWithdrawn(uint256 indexed id, uint256 amount, address to); + event InsufficientFundsUpkeepReport(uint256 indexed id, bytes trigger); + event NOPsSettledOffchain(address[] payees, uint256[] payments); + event OwnershipTransferRequested(address indexed from, address indexed to); + event OwnershipTransferred(address indexed from, address indexed to); + event Paused(address account); + event PayeesUpdated(address[] transmitters, address[] payees); + event PayeeshipTransferRequested(address indexed transmitter, address indexed from, address indexed to); + event PayeeshipTransferred(address indexed transmitter, address indexed from, address indexed to); + event PaymentWithdrawn(address indexed transmitter, uint256 indexed amount, address indexed to, address payee); + event ReorgedUpkeepReport(uint256 indexed id, bytes trigger); + event StaleUpkeepReport(uint256 indexed id, bytes trigger); + event Transmitted(bytes32 configDigest, uint32 epoch); + event Unpaused(address account); + event UpkeepAdminTransferRequested(uint256 indexed id, address indexed from, address indexed to); + event UpkeepAdminTransferred(uint256 indexed id, address indexed from, address indexed to); + event UpkeepCanceled(uint256 indexed id, uint64 indexed atBlockHeight); + event UpkeepCharged(uint256 indexed id, ZKSyncAutomationRegistryBase2_3.PaymentReceipt receipt); + event UpkeepCheckDataSet(uint256 indexed id, bytes newCheckData); + event UpkeepGasLimitSet(uint256 indexed id, uint96 gasLimit); + event UpkeepMigrated(uint256 indexed id, uint256 remainingBalance, address destination); + event UpkeepOffchainConfigSet(uint256 indexed id, bytes offchainConfig); + event UpkeepPaused(uint256 indexed id); + event UpkeepPerformed( + uint256 indexed id, + bool indexed success, + uint96 totalPayment, + uint256 gasUsed, + uint256 gasOverhead, + bytes trigger + ); + event UpkeepPrivilegeConfigSet(uint256 indexed id, bytes privilegeConfig); + event UpkeepReceived(uint256 indexed id, uint256 startingBalance, address importedFrom); + event UpkeepRegistered(uint256 indexed id, uint32 performGas, address admin); + event UpkeepTriggerConfigSet(uint256 indexed id, bytes triggerConfig); + event UpkeepUnpaused(uint256 indexed id); + fallback() external payable; + function acceptOwnership() external; + function fallbackTo() external view returns (address); + function latestConfigDetails() external view returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest); + function latestConfigDigestAndEpoch() external view returns (bool scanLogs, bytes32 configDigest, uint32 epoch); + function owner() external view returns (address); + function setConfig( + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfigBytes, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external; + function setConfigTypeSafe( + address[] memory signers, + address[] memory transmitters, + uint8 f, + ZKSyncAutomationRegistryBase2_3.OnchainConfig memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + address[] memory billingTokens, + ZKSyncAutomationRegistryBase2_3.BillingConfig[] memory billingConfigs + ) external; + function transferOwnership(address to) external; + function transmit( + bytes32[3] memory reportContext, + bytes memory rawReport, + bytes32[] memory rs, + bytes32[] memory ss, + bytes32 rawVs + ) external; + function typeAndVersion() external view returns (string memory); + + function cancelUpkeep(uint256 id) external; + function migrateUpkeeps(uint256[] memory ids, address destination) external; + function onTokenTransfer(address sender, uint256 amount, bytes memory data) external; + function receiveUpkeeps(bytes memory encodedUpkeeps) external; + function registerUpkeep( + address target, + uint32 gasLimit, + address admin, + uint8 triggerType, + address billingToken, + bytes memory checkData, + bytes memory triggerConfig, + bytes memory offchainConfig + ) external returns (uint256 id); + + function acceptUpkeepAdmin(uint256 id) external; + function addFunds(uint256 id, uint96 amount) external payable; + function checkCallback( + uint256 id, + bytes[] memory values, + bytes memory extraData + ) external view returns (bool upkeepNeeded, bytes memory performData, uint8 upkeepFailureReason, uint256 gasUsed); + function checkUpkeep( + uint256 id, + bytes memory triggerData + ) + external + view + returns ( + bool upkeepNeeded, + bytes memory performData, + uint8 upkeepFailureReason, + uint256 gasUsed, + uint256 gasLimit, + uint256 fastGasWei, + uint256 linkUSD + ); + function checkUpkeep( + uint256 id + ) + external + view + returns ( + bool upkeepNeeded, + bytes memory performData, + uint8 upkeepFailureReason, + uint256 gasUsed, + uint256 gasLimit, + uint256 fastGasWei, + uint256 linkUSD + ); + function executeCallback( + uint256 id, + bytes memory payload + ) external returns (bool upkeepNeeded, bytes memory performData, uint8 upkeepFailureReason, uint256 gasUsed); + function pauseUpkeep(uint256 id) external; + function removeBillingOverrides(uint256 id) external; + function setBillingOverrides( + uint256 id, + ZKSyncAutomationRegistryBase2_3.BillingOverrides memory billingOverrides + ) external; + function setUpkeepCheckData(uint256 id, bytes memory newCheckData) external; + function setUpkeepGasLimit(uint256 id, uint32 gasLimit) external; + function setUpkeepOffchainConfig(uint256 id, bytes memory config) external; + function setUpkeepTriggerConfig(uint256 id, bytes memory triggerConfig) external; + function simulatePerformUpkeep( + uint256 id, + bytes memory performData + ) external view returns (bool success, uint256 gasUsed); + function transferUpkeepAdmin(uint256 id, address proposed) external; + function unpauseUpkeep(uint256 id) external; + function withdrawERC20Fees(address asset, address to, uint256 amount) external; + function withdrawFunds(uint256 id, address to) external; + function withdrawLink(address to, uint256 amount) external; + + function acceptPayeeship(address transmitter) external; + function disableOffchainPayments() external; + function getActiveUpkeepIDs(uint256 startIndex, uint256 maxCount) external view returns (uint256[] memory); + function getAdminPrivilegeConfig(address admin) external view returns (bytes memory); + function getAllowedReadOnlyAddress() external view returns (address); + function getAutomationForwarderLogic() external view returns (address); + function getAvailableERC20ForPayment(address billingToken) external view returns (uint256); + function getBalance(uint256 id) external view returns (uint96 balance); + function getBillingConfig( + address billingToken + ) external view returns (ZKSyncAutomationRegistryBase2_3.BillingConfig memory); + function getBillingOverrides( + uint256 upkeepID + ) external view returns (ZKSyncAutomationRegistryBase2_3.BillingOverrides memory); + function getBillingOverridesEnabled(uint256 upkeepID) external view returns (bool); + function getBillingToken(uint256 upkeepID) external view returns (address); + function getBillingTokenConfig( + address token + ) external view returns (ZKSyncAutomationRegistryBase2_3.BillingConfig memory); + function getBillingTokens() external view returns (address[] memory); + function getCancellationDelay() external pure returns (uint256); + function getChainModule() external view returns (address chainModule); + function getConditionalGasOverhead() external pure returns (uint256); + function getConfig() external view returns (ZKSyncAutomationRegistryBase2_3.OnchainConfig memory); + function getFallbackNativePrice() external view returns (uint256); + function getFastGasFeedAddress() external view returns (address); + function getForwarder(uint256 upkeepID) external view returns (address); + function getHotVars() external view returns (ZKSyncAutomationRegistryBase2_3.HotVars memory); + function getLinkAddress() external view returns (address); + function getLinkUSDFeedAddress() external view returns (address); + function getLogGasOverhead() external pure returns (uint256); + function getMaxPaymentForGas( + uint256 id, + uint8 triggerType, + uint32 gasLimit, + address billingToken + ) external view returns (uint96 maxPayment); + function getMinBalance(uint256 id) external view returns (uint96); + function getMinBalanceForUpkeep(uint256 id) external view returns (uint96 minBalance); + function getNativeUSDFeedAddress() external view returns (address); + function getNumUpkeeps() external view returns (uint256); + function getPayoutMode() external view returns (uint8); + function getPeerRegistryMigrationPermission(address peer) external view returns (uint8); + function getPerSignerGasOverhead() external pure returns (uint256); + function getReorgProtectionEnabled() external view returns (bool reorgProtectionEnabled); + function getReserveAmount(address billingToken) external view returns (uint256); + function getSignerInfo(address query) external view returns (bool active, uint8 index); + function getState() + external + view + returns ( + IAutomationV21PlusCommon.StateLegacy memory state, + IAutomationV21PlusCommon.OnchainConfigLegacy memory config, + address[] memory signers, + address[] memory transmitters, + uint8 f + ); + function getStorage() external view returns (ZKSyncAutomationRegistryBase2_3.Storage memory); + function getTransmitterInfo( + address query + ) external view returns (bool active, uint8 index, uint96 balance, uint96 lastCollected, address payee); + function getTransmittersWithPayees() + external + view + returns (ZKSyncAutomationRegistryBase2_3.TransmitterPayeeInfo[] memory); + function getTriggerType(uint256 upkeepId) external pure returns (uint8); + function getUpkeep(uint256 id) external view returns (IAutomationV21PlusCommon.UpkeepInfoLegacy memory upkeepInfo); + function getUpkeepPrivilegeConfig(uint256 upkeepId) external view returns (bytes memory); + function getUpkeepTriggerConfig(uint256 upkeepId) external view returns (bytes memory); + function getWrappedNativeTokenAddress() external view returns (address); + function hasDedupKey(bytes32 dedupKey) external view returns (bool); + function linkAvailableForPayment() external view returns (int256); + function pause() external; + function setAdminPrivilegeConfig(address admin, bytes memory newPrivilegeConfig) external; + function setPayees(address[] memory payees) external; + function setPeerRegistryMigrationPermission(address peer, uint8 permission) external; + function setUpkeepPrivilegeConfig(uint256 upkeepId, bytes memory newPrivilegeConfig) external; + function settleNOPsOffchain() external; + function supportsBillingToken(address token) external view returns (bool); + function transferPayeeship(address transmitter, address proposed) external; + function unpause() external; + function upkeepVersion() external pure returns (uint8); + function withdrawPayment(address from, address to) external; +} + +interface ZKSyncAutomationRegistryBase2_3 { + struct BillingOverrides { + uint32 gasFeePPB; + uint24 flatFeeMilliCents; + } + + struct BillingConfig { + uint32 gasFeePPB; + uint24 flatFeeMilliCents; + address priceFeed; + uint8 decimals; + uint256 fallbackPrice; + uint96 minSpend; + } + + struct PaymentReceipt { + uint96 gasChargeInBillingToken; + uint96 premiumInBillingToken; + uint96 gasReimbursementInJuels; + uint96 premiumInJuels; + address billingToken; + uint96 linkUSD; + uint96 nativeUSD; + uint96 billingUSD; + } + + struct OnchainConfig { + uint32 checkGasLimit; + uint32 maxPerformGas; + uint32 maxCheckDataSize; + address transcoder; + bool reorgProtectionEnabled; + uint24 stalenessSeconds; + uint32 maxPerformDataSize; + uint32 maxRevertDataSize; + address upkeepPrivilegeManager; + uint16 gasCeilingMultiplier; + address financeAdmin; + uint256 fallbackGasPrice; + uint256 fallbackLinkPrice; + uint256 fallbackNativePrice; + address[] registrars; + address chainModule; + } + + struct HotVars { + uint96 totalPremium; + uint32 latestEpoch; + uint24 stalenessSeconds; + uint16 gasCeilingMultiplier; + uint8 f; + bool paused; + bool reentrancyGuard; + bool reorgProtectionEnabled; + address chainModule; + } + + struct Storage { + address transcoder; + uint32 checkGasLimit; + uint32 maxPerformGas; + uint32 nonce; + address upkeepPrivilegeManager; + uint32 configCount; + uint32 latestConfigBlockNumber; + uint32 maxCheckDataSize; + address financeAdmin; + uint32 maxPerformDataSize; + uint32 maxRevertDataSize; + } + + struct TransmitterPayeeInfo { + address transmitterAddress; + address payeeAddress; + } +} + +interface IAutomationV21PlusCommon { + struct StateLegacy { + uint32 nonce; + uint96 ownerLinkBalance; + uint256 expectedLinkBalance; + uint96 totalPremium; + uint256 numUpkeeps; + uint32 configCount; + uint32 latestConfigBlockNumber; + bytes32 latestConfigDigest; + uint32 latestEpoch; + bool paused; + } + + struct OnchainConfigLegacy { + uint32 paymentPremiumPPB; + uint32 flatFeeMicroLink; + uint32 checkGasLimit; + uint24 stalenessSeconds; + uint16 gasCeilingMultiplier; + uint96 minUpkeepSpend; + uint32 maxPerformGas; + uint32 maxCheckDataSize; + uint32 maxPerformDataSize; + uint32 maxRevertDataSize; + uint256 fallbackGasPrice; + uint256 fallbackLinkPrice; + address transcoder; + address[] registrars; + address upkeepPrivilegeManager; + } + + struct UpkeepInfoLegacy { + address target; + uint32 performGas; + bytes checkData; + uint96 balance; + address admin; + uint64 maxValidBlocknumber; + uint32 lastPerformedBlockNumber; + uint96 amountSpent; + bool paused; + bytes offchainConfig; + } +} + +// THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON: +/* +[{"inputs":[{"internalType":"contract ZKSyncAutomationRegistryLogicA2_3","name":"logicA","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayHasNoEntries","type":"error"},{"inputs":[],"name":"CannotCancel","type":"error"},{"inputs":[],"name":"CheckDataExceedsLimit","type":"error"},{"inputs":[],"name":"ConfigDigestMismatch","type":"error"},{"inputs":[],"name":"DuplicateEntry","type":"error"},{"inputs":[],"name":"DuplicateSigners","type":"error"},{"inputs":[],"name":"GasLimitCanOnlyIncrease","type":"error"},{"inputs":[],"name":"GasLimitOutsideRange","type":"error"},{"inputs":[],"name":"IncorrectNumberOfFaultyOracles","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSignatures","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSigners","type":"error"},{"inputs":[],"name":"IndexOutOfRange","type":"error"},{"inputs":[{"internalType":"uint256","name":"available","type":"uint256"},{"internalType":"uint256","name":"requested","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InsufficientLinkLiquidity","type":"error"},{"inputs":[],"name":"InvalidDataLength","type":"error"},{"inputs":[],"name":"InvalidFeed","type":"error"},{"inputs":[],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"InvalidTransmitter","type":"error"},{"inputs":[],"name":"InvalidTrigger","type":"error"},{"inputs":[],"name":"InvalidTriggerType","type":"error"},{"inputs":[],"name":"MigrationNotPermitted","type":"error"},{"inputs":[],"name":"MustSettleOffchain","type":"error"},{"inputs":[],"name":"MustSettleOnchain","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"OnlyActiveSigners","type":"error"},{"inputs":[],"name":"OnlyActiveTransmitters","type":"error"},{"inputs":[],"name":"OnlyCallableByAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByLINKToken","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrRegistrar","type":"error"},{"inputs":[],"name":"OnlyCallableByPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByUpkeepPrivilegeManager","type":"error"},{"inputs":[],"name":"OnlyFinanceAdmin","type":"error"},{"inputs":[],"name":"OnlyPausedUpkeep","type":"error"},{"inputs":[],"name":"OnlySimulatedBackend","type":"error"},{"inputs":[],"name":"OnlyUnpausedUpkeep","type":"error"},{"inputs":[],"name":"ParameterLengthError","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"RegistryPaused","type":"error"},{"inputs":[],"name":"RepeatedSigner","type":"error"},{"inputs":[],"name":"RepeatedTransmitter","type":"error"},{"inputs":[{"internalType":"bytes","name":"reason","type":"bytes"}],"name":"TargetCheckReverted","type":"error"},{"inputs":[],"name":"TooManyOracles","type":"error"},{"inputs":[],"name":"TranscoderNotSet","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"UpkeepAlreadyExists","type":"error"},{"inputs":[],"name":"UpkeepCancelled","type":"error"},{"inputs":[],"name":"UpkeepNotCanceled","type":"error"},{"inputs":[],"name":"UpkeepNotNeeded","type":"error"},{"inputs":[],"name":"ValueNotChanged","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"AdminPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"}],"indexed":false,"internalType":"struct ZKSyncAutomationRegistryBase2_3.BillingOverrides","name":"overrides","type":"tuple"}],"name":"BillingConfigOverridden","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"BillingConfigOverrideRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20Metadata","name":"token","type":"address"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"indexed":false,"internalType":"struct ZKSyncAutomationRegistryBase2_3.BillingConfig","name":"config","type":"tuple"}],"name":"BillingConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"CancelledUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newModule","type":"address"}],"name":"ChainSpecificModuleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"DedupKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"assetAddress","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"FundsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"InsufficientFundsUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"payments","type":"uint256[]"}],"name":"NOPsSettledOffchain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"}],"name":"PayeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"}],"name":"PaymentWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"ReorgedUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"StaleUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"atBlockHeight","type":"uint64"}],"name":"UpkeepCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint96","name":"gasChargeInBillingToken","type":"uint96"},{"internalType":"uint96","name":"premiumInBillingToken","type":"uint96"},{"internalType":"uint96","name":"gasReimbursementInJuels","type":"uint96"},{"internalType":"uint96","name":"premiumInJuels","type":"uint96"},{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"},{"internalType":"uint96","name":"linkUSD","type":"uint96"},{"internalType":"uint96","name":"nativeUSD","type":"uint96"},{"internalType":"uint96","name":"billingUSD","type":"uint96"}],"indexed":false,"internalType":"struct ZKSyncAutomationRegistryBase2_3.PaymentReceipt","name":"receipt","type":"tuple"}],"name":"UpkeepCharged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"UpkeepCheckDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint96","name":"gasLimit","type":"uint96"}],"name":"UpkeepGasLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"UpkeepMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"UpkeepOffchainConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"uint96","name":"totalPayment","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"UpkeepPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"UpkeepPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"importedFrom","type":"address"}],"name":"UpkeepReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"performGas","type":"uint32"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"UpkeepRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"UpkeepTriggerConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepUnpaused","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fallbackTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfigBytes","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"components":[{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackNativePrice","type":"uint256"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct ZKSyncAutomationRegistryBase2_3.OnchainConfig","name":"onchainConfig","type":"tuple"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"},{"internalType":"contract IERC20Metadata[]","name":"billingTokens","type":"address[]"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"internalType":"struct ZKSyncAutomationRegistryBase2_3.BillingConfig[]","name":"billingConfigs","type":"tuple[]"}],"name":"setConfigTypeSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"internalType":"bytes","name":"rawReport","type":"bytes"},{"internalType":"bytes32[]","name":"rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ss","type":"bytes32[]"},{"internalType":"bytes32","name":"rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ZKSyncAutomationRegistryLogicB2_3","name":"logicB","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"destination","type":"address"}],"name":"migrateUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpkeeps","type":"bytes"}],"name":"receiveUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"enum ZKSyncAutomationRegistryBase2_3.Trigger","name":"triggerType","type":"uint8"},{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ZKSyncAutomationRegistryLogicC2_3","name":"logicC","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"acceptUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"checkCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum ZKSyncAutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum ZKSyncAutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkUSD","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum ZKSyncAutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkUSD","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"executeCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum ZKSyncAutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"pauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"removeBillingOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"}],"internalType":"struct ZKSyncAutomationRegistryBase2_3.BillingOverrides","name":"billingOverrides","type":"tuple"}],"name":"setBillingOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"setUpkeepCheckData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"setUpkeepGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"config","type":"bytes"}],"name":"setUpkeepOffchainConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"setUpkeepTriggerConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"simulatePerformUpkeep","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"asset","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawERC20Fees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawLink","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkUSDFeed","type":"address"},{"internalType":"address","name":"nativeUSDFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"},{"internalType":"address","name":"automationForwarderLogic","type":"address"},{"internalType":"address","name":"allowedReadOnlyAddress","type":"address"},{"internalType":"enum ZKSyncAutomationRegistryBase2_3.PayoutMode","name":"payoutMode","type":"uint8"},{"internalType":"address","name":"wrappedNativeTokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableOffchainPayments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"maxCount","type":"uint256"}],"name":"getActiveUpkeepIDs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"getAdminPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedReadOnlyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAutomationForwarderLogic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"}],"name":"getAvailableERC20ForPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint96","name":"balance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"}],"name":"getBillingConfig","outputs":[{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"internalType":"struct ZKSyncAutomationRegistryBase2_3.BillingConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getBillingOverrides","outputs":[{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"}],"internalType":"struct ZKSyncAutomationRegistryBase2_3.BillingOverrides","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getBillingOverridesEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getBillingToken","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"token","type":"address"}],"name":"getBillingTokenConfig","outputs":[{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"internalType":"struct ZKSyncAutomationRegistryBase2_3.BillingConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBillingTokens","outputs":[{"internalType":"contract IERC20Metadata[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCancellationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getChainModule","outputs":[{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConditionalGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getConfig","outputs":[{"components":[{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackNativePrice","type":"uint256"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct ZKSyncAutomationRegistryBase2_3.OnchainConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFallbackNativePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFastGasFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getForwarder","outputs":[{"internalType":"contract IAutomationForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHotVars","outputs":[{"components":[{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"reentrancyGuard","type":"bool"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct ZKSyncAutomationRegistryBase2_3.HotVars","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkUSDFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLogGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"enum ZKSyncAutomationRegistryBase2_3.Trigger","name":"triggerType","type":"uint8"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"}],"name":"getMaxPaymentForGas","outputs":[{"internalType":"uint96","name":"maxPayment","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalance","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalanceForUpkeep","outputs":[{"internalType":"uint96","name":"minBalance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNativeUSDFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumUpkeeps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPayoutMode","outputs":[{"internalType":"enum ZKSyncAutomationRegistryBase2_3.PayoutMode","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"}],"name":"getPeerRegistryMigrationPermission","outputs":[{"internalType":"enum ZKSyncAutomationRegistryBase2_3.MigrationPermission","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerSignerGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getReorgProtectionEnabled","outputs":[{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"}],"name":"getReserveAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getSignerInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"components":[{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint96","name":"ownerLinkBalance","type":"uint96"},{"internalType":"uint256","name":"expectedLinkBalance","type":"uint256"},{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint256","name":"numUpkeeps","type":"uint256"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"bytes32","name":"latestConfigDigest","type":"bytes32"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"bool","name":"paused","type":"bool"}],"internalType":"struct IAutomationV21PlusCommon.StateLegacy","name":"state","type":"tuple"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"}],"internalType":"struct IAutomationV21PlusCommon.OnchainConfigLegacy","name":"config","type":"tuple"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStorage","outputs":[{"components":[{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"}],"internalType":"struct ZKSyncAutomationRegistryBase2_3.Storage","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getTransmitterInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint96","name":"lastCollected","type":"uint96"},{"internalType":"address","name":"payee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransmittersWithPayees","outputs":[{"components":[{"internalType":"address","name":"transmitterAddress","type":"address"},{"internalType":"address","name":"payeeAddress","type":"address"}],"internalType":"struct ZKSyncAutomationRegistryBase2_3.TransmitterPayeeInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getTriggerType","outputs":[{"internalType":"enum ZKSyncAutomationRegistryBase2_3.Trigger","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getUpkeep","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"performGas","type":"uint32"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint64","name":"maxValidBlocknumber","type":"uint64"},{"internalType":"uint32","name":"lastPerformedBlockNumber","type":"uint32"},{"internalType":"uint96","name":"amountSpent","type":"uint96"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"internalType":"struct IAutomationV21PlusCommon.UpkeepInfoLegacy","name":"upkeepInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepTriggerConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWrappedNativeTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"hasDedupKey","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"linkAvailableForPayment","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setAdminPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"},{"internalType":"enum ZKSyncAutomationRegistryBase2_3.MigrationPermission","name":"permission","type":"uint8"}],"name":"setPeerRegistryMigrationPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setUpkeepPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settleNOPsOffchain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"token","type":"address"}],"name":"supportsBillingToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upkeepVersion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}] +*/ diff --git a/contracts/src/v0.8/automation/test/v2_3_zksync/BaseTest.t.sol b/contracts/src/v0.8/automation/test/v2_3_zksync/BaseTest.t.sol new file mode 100644 index 0000000000..cde05ab3a2 --- /dev/null +++ b/contracts/src/v0.8/automation/test/v2_3_zksync/BaseTest.t.sol @@ -0,0 +1,500 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import "forge-std/Test.sol"; + +import {LinkToken} from "../../../shared/token/ERC677/LinkToken.sol"; +import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {ERC20Mock6Decimals} from "../../mocks/ERC20Mock6Decimals.sol"; +import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol"; +import {AutomationForwarderLogic} from "../../AutomationForwarderLogic.sol"; +import {UpkeepTranscoder5_0 as Transcoder} from "../../v2_3/UpkeepTranscoder5_0.sol"; +import {ZKSyncAutomationRegistry2_3} from "../../v2_3_zksync/ZKSyncAutomationRegistry2_3.sol"; +import {ZKSyncAutomationRegistryLogicA2_3} from "../../v2_3_zksync/ZKSyncAutomationRegistryLogicA2_3.sol"; +import {ZKSyncAutomationRegistryLogicB2_3} from "../../v2_3_zksync/ZKSyncAutomationRegistryLogicB2_3.sol"; +import {ZKSyncAutomationRegistryLogicC2_3} from "../../v2_3_zksync/ZKSyncAutomationRegistryLogicC2_3.sol"; +import {ZKSyncAutomationRegistryBase2_3 as ZKSyncAutoBase} from "../../v2_3_zksync/ZKSyncAutomationRegistryBase2_3.sol"; +import {IAutomationRegistryMaster2_3 as Registry, AutomationRegistryBase2_3} from "../../interfaces/v2_3/IAutomationRegistryMaster2_3.sol"; +import {AutomationRegistrar2_3} from "../../v2_3/AutomationRegistrar2_3.sol"; +import {ChainModuleBase} from "../../chains/ChainModuleBase.sol"; +import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import {MockUpkeep} from "../../mocks/MockUpkeep.sol"; +import {IWrappedNative} from "../../interfaces/v2_3/IWrappedNative.sol"; +import {WETH9} from "../WETH9.sol"; +import {MockGasBoundCaller} from "../../../tests/MockGasBoundCaller.sol"; +import {MockZKSyncSystemContext} from "../../../tests/MockZKSyncSystemContext.sol"; + +/** + * @title BaseTest provides basic test setup procedures and dependencies for use by other + * unit tests + */ +contract BaseTest is Test { + // test state (not exposed to derived tests) + uint256 private nonce; + + // constants + address internal constant ZERO_ADDRESS = address(0); + uint32 internal constant DEFAULT_GAS_FEE_PPB = 10_000_000; + uint24 internal constant DEFAULT_FLAT_FEE_MILLI_CENTS = 2_000; + + // config + uint8 internal constant F = 1; // number of faulty nodes + uint64 internal constant OFFCHAIN_CONFIG_VERSION = 30; // 2 for OCR2 + + // contracts + LinkToken internal linkToken; + ERC20Mock6Decimals internal usdToken6; + ERC20Mock internal usdToken18; + ERC20Mock internal usdToken18_2; + WETH9 internal weth; + MockV3Aggregator internal LINK_USD_FEED; + MockV3Aggregator internal NATIVE_USD_FEED; + MockV3Aggregator internal USDTOKEN_USD_FEED; + MockV3Aggregator internal FAST_GAS_FEED; + MockUpkeep internal TARGET1; + MockUpkeep internal TARGET2; + Transcoder internal TRANSCODER; + MockGasBoundCaller internal GAS_BOUND_CALLER; + MockZKSyncSystemContext internal SYSTEM_CONTEXT; + + // roles + address internal constant OWNER = address(uint160(uint256(keccak256("OWNER")))); + address internal constant UPKEEP_ADMIN = address(uint160(uint256(keccak256("UPKEEP_ADMIN")))); + address internal constant FINANCE_ADMIN = address(uint160(uint256(keccak256("FINANCE_ADMIN")))); + address internal constant STRANGER = address(uint160(uint256(keccak256("STRANGER")))); + address internal constant BROKE_USER = address(uint160(uint256(keccak256("BROKE_USER")))); // do not mint to this address + address internal constant PRIVILEGE_MANAGER = address(uint160(uint256(keccak256("PRIVILEGE_MANAGER")))); + + // nodes + uint256 internal constant SIGNING_KEY0 = 0x7b2e97fe057e6de99d6872a2ef2abf52c9b4469bc848c2465ac3fcd8d336e81d; + uint256 internal constant SIGNING_KEY1 = 0xab56160806b05ef1796789248e1d7f34a6465c5280899159d645218cd216cee6; + uint256 internal constant SIGNING_KEY2 = 0x6ec7caa8406a49b76736602810e0a2871959fbbb675e23a8590839e4717f1f7f; + uint256 internal constant SIGNING_KEY3 = 0x80f14b11da94ae7f29d9a7713ea13dc838e31960a5c0f2baf45ed458947b730a; + address[] internal SIGNERS = new address[](4); + address[] internal TRANSMITTERS = new address[](4); + address[] internal NEW_TRANSMITTERS = new address[](4); + address[] internal PAYEES = new address[](4); + address[] internal NEW_PAYEES = new address[](4); + + function setUp() public virtual { + vm.startPrank(OWNER); + linkToken = new LinkToken(); + linkToken.grantMintRole(OWNER); + usdToken18 = new ERC20Mock("MOCK_ERC20_18Decimals", "MOCK_ERC20_18Decimals", OWNER, 0); + usdToken18_2 = new ERC20Mock("Second_MOCK_ERC20_18Decimals", "Second_MOCK_ERC20_18Decimals", OWNER, 0); + usdToken6 = new ERC20Mock6Decimals("MOCK_ERC20_6Decimals", "MOCK_ERC20_6Decimals", OWNER, 0); + weth = new WETH9(); + + LINK_USD_FEED = new MockV3Aggregator(8, 2_000_000_000); // $20 + NATIVE_USD_FEED = new MockV3Aggregator(8, 400_000_000_000); // $4,000 + USDTOKEN_USD_FEED = new MockV3Aggregator(8, 100_000_000); // $1 + FAST_GAS_FEED = new MockV3Aggregator(0, 1_000_000_000); // 1 gwei + + TARGET1 = new MockUpkeep(); + TARGET2 = new MockUpkeep(); + + TRANSCODER = new Transcoder(); + GAS_BOUND_CALLER = new MockGasBoundCaller(); + SYSTEM_CONTEXT = new MockZKSyncSystemContext(); + + bytes memory callerCode = address(GAS_BOUND_CALLER).code; + vm.etch(0xc706EC7dfA5D4Dc87f29f859094165E8290530f5, callerCode); + + bytes memory contextCode = address(SYSTEM_CONTEXT).code; + vm.etch(0x000000000000000000000000000000000000800B, contextCode); + + SIGNERS[0] = vm.addr(SIGNING_KEY0); //0xc110458BE52CaA6bB68E66969C3218A4D9Db0211 + SIGNERS[1] = vm.addr(SIGNING_KEY1); //0xc110a19c08f1da7F5FfB281dc93630923F8E3719 + SIGNERS[2] = vm.addr(SIGNING_KEY2); //0xc110fdF6e8fD679C7Cc11602d1cd829211A18e9b + SIGNERS[3] = vm.addr(SIGNING_KEY3); //0xc11028017c9b445B6bF8aE7da951B5cC28B326C0 + + TRANSMITTERS[0] = address(uint160(uint256(keccak256("TRANSMITTER1")))); + TRANSMITTERS[1] = address(uint160(uint256(keccak256("TRANSMITTER2")))); + TRANSMITTERS[2] = address(uint160(uint256(keccak256("TRANSMITTER3")))); + TRANSMITTERS[3] = address(uint160(uint256(keccak256("TRANSMITTER4")))); + NEW_TRANSMITTERS[0] = address(uint160(uint256(keccak256("TRANSMITTER1")))); + NEW_TRANSMITTERS[1] = address(uint160(uint256(keccak256("TRANSMITTER2")))); + NEW_TRANSMITTERS[2] = address(uint160(uint256(keccak256("TRANSMITTER5")))); + NEW_TRANSMITTERS[3] = address(uint160(uint256(keccak256("TRANSMITTER6")))); + + PAYEES[0] = address(100); + PAYEES[1] = address(101); + PAYEES[2] = address(102); + PAYEES[3] = address(103); + NEW_PAYEES[0] = address(100); + NEW_PAYEES[1] = address(101); + NEW_PAYEES[2] = address(106); + NEW_PAYEES[3] = address(107); + + // mint funds + vm.deal(OWNER, 100 ether); + vm.deal(UPKEEP_ADMIN, 100 ether); + vm.deal(FINANCE_ADMIN, 100 ether); + vm.deal(STRANGER, 100 ether); + + linkToken.mint(OWNER, 1000e18); + linkToken.mint(UPKEEP_ADMIN, 1000e18); + linkToken.mint(FINANCE_ADMIN, 1000e18); + linkToken.mint(STRANGER, 1000e18); + + usdToken18.mint(OWNER, 1000e18); + usdToken18.mint(UPKEEP_ADMIN, 1000e18); + usdToken18.mint(FINANCE_ADMIN, 1000e18); + usdToken18.mint(STRANGER, 1000e18); + + usdToken18_2.mint(UPKEEP_ADMIN, 1000e18); + + usdToken6.mint(OWNER, 1000e6); + usdToken6.mint(UPKEEP_ADMIN, 1000e6); + usdToken6.mint(FINANCE_ADMIN, 1000e6); + usdToken6.mint(STRANGER, 1000e6); + + weth.mint(OWNER, 1000e18); + weth.mint(UPKEEP_ADMIN, 1000e18); + weth.mint(FINANCE_ADMIN, 1000e18); + weth.mint(STRANGER, 1000e18); + + vm.stopPrank(); + } + + /// @notice deploys the component parts of a registry, but nothing more + function deployZKSyncRegistry(ZKSyncAutoBase.PayoutMode payoutMode) internal returns (Registry) { + AutomationForwarderLogic forwarderLogic = new AutomationForwarderLogic(); + ZKSyncAutomationRegistryLogicC2_3 logicC2_3 = new ZKSyncAutomationRegistryLogicC2_3( + address(linkToken), + address(LINK_USD_FEED), + address(NATIVE_USD_FEED), + address(FAST_GAS_FEED), + address(forwarderLogic), + ZERO_ADDRESS, + payoutMode, + address(weth) + ); + ZKSyncAutomationRegistryLogicB2_3 logicB2_3 = new ZKSyncAutomationRegistryLogicB2_3(logicC2_3); + ZKSyncAutomationRegistryLogicA2_3 logicA2_3 = new ZKSyncAutomationRegistryLogicA2_3(logicB2_3); + return Registry(payable(address(new ZKSyncAutomationRegistry2_3(logicA2_3)))); + } + + /// @notice deploys and configures a registry, registrar, and everything needed for most tests + function deployAndConfigureZKSyncRegistryAndRegistrar( + ZKSyncAutoBase.PayoutMode payoutMode + ) internal returns (Registry, AutomationRegistrar2_3) { + Registry registry = deployZKSyncRegistry(payoutMode); + + IERC20[] memory billingTokens = new IERC20[](4); + billingTokens[0] = IERC20(address(usdToken18)); + billingTokens[1] = IERC20(address(weth)); + billingTokens[2] = IERC20(address(linkToken)); + billingTokens[3] = IERC20(address(usdToken6)); + uint256[] memory minRegistrationFees = new uint256[](billingTokens.length); + minRegistrationFees[0] = 100e18; // 100 USD + minRegistrationFees[1] = 5e18; // 5 Native + minRegistrationFees[2] = 5e18; // 5 LINK + minRegistrationFees[3] = 100e6; // 100 USD + address[] memory billingTokenAddresses = new address[](billingTokens.length); + for (uint256 i = 0; i < billingTokens.length; i++) { + billingTokenAddresses[i] = address(billingTokens[i]); + } + AutomationRegistryBase2_3.BillingConfig[] + memory billingTokenConfigs = new AutomationRegistryBase2_3.BillingConfig[](billingTokens.length); + billingTokenConfigs[0] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: DEFAULT_GAS_FEE_PPB, // 15% + flatFeeMilliCents: DEFAULT_FLAT_FEE_MILLI_CENTS, // 2 cents + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 100_000_000, // $1 + minSpend: 1e18, // 1 USD + decimals: 18 + }); + billingTokenConfigs[1] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: DEFAULT_GAS_FEE_PPB, // 15% + flatFeeMilliCents: DEFAULT_FLAT_FEE_MILLI_CENTS, // 2 cents + priceFeed: address(NATIVE_USD_FEED), + fallbackPrice: 100_000_000, // $1 + minSpend: 5e18, // 5 Native + decimals: 18 + }); + billingTokenConfigs[2] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: DEFAULT_GAS_FEE_PPB, // 10% + flatFeeMilliCents: DEFAULT_FLAT_FEE_MILLI_CENTS, // 2 cents + priceFeed: address(LINK_USD_FEED), + fallbackPrice: 1_000_000_000, // $10 + minSpend: 1e18, // 1 LINK + decimals: 18 + }); + billingTokenConfigs[3] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: DEFAULT_GAS_FEE_PPB, // 15% + flatFeeMilliCents: DEFAULT_FLAT_FEE_MILLI_CENTS, // 2 cents + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 1e8, // $1 + minSpend: 1e6, // 1 USD + decimals: 6 + }); + + if (payoutMode == ZKSyncAutoBase.PayoutMode.OFF_CHAIN) { + // remove LINK as a payment method if we are settling offchain + assembly { + mstore(billingTokens, 2) + mstore(minRegistrationFees, 2) + mstore(billingTokenAddresses, 2) + mstore(billingTokenConfigs, 2) + } + } + + // deploy registrar + AutomationRegistrar2_3.InitialTriggerConfig[] + memory triggerConfigs = new AutomationRegistrar2_3.InitialTriggerConfig[](2); + triggerConfigs[0] = AutomationRegistrar2_3.InitialTriggerConfig({ + triggerType: 0, // condition + autoApproveType: AutomationRegistrar2_3.AutoApproveType.DISABLED, + autoApproveMaxAllowed: 0 + }); + triggerConfigs[1] = AutomationRegistrar2_3.InitialTriggerConfig({ + triggerType: 1, // log + autoApproveType: AutomationRegistrar2_3.AutoApproveType.DISABLED, + autoApproveMaxAllowed: 0 + }); + AutomationRegistrar2_3 registrar = new AutomationRegistrar2_3( + address(linkToken), + registry, + triggerConfigs, + billingTokens, + minRegistrationFees, + IWrappedNative(address(weth)) + ); + + address[] memory registrars; + registrars = new address[](1); + registrars[0] = address(registrar); + + AutomationRegistryBase2_3.OnchainConfig memory cfg = AutomationRegistryBase2_3.OnchainConfig({ + checkGasLimit: 5_000_000, + stalenessSeconds: 90_000, + gasCeilingMultiplier: 2, + maxPerformGas: 10_000_000, + maxCheckDataSize: 5_000, + maxPerformDataSize: 5_000, + maxRevertDataSize: 5_000, + fallbackGasPrice: 20_000_000_000, + fallbackLinkPrice: 2_000_000_000, // $20 + fallbackNativePrice: 400_000_000_000, // $4,000 + transcoder: address(TRANSCODER), + registrars: registrars, + upkeepPrivilegeManager: PRIVILEGE_MANAGER, + chainModule: address(new ChainModuleBase()), + reorgProtectionEnabled: true, + financeAdmin: FINANCE_ADMIN + }); + + registry.setConfigTypeSafe( + SIGNERS, + TRANSMITTERS, + F, + cfg, + OFFCHAIN_CONFIG_VERSION, + "", + billingTokenAddresses, + billingTokenConfigs + ); + return (registry, registrar); + } + + /// @notice this function updates the billing config for the provided token on the provided registry, + /// and throws an error if the token is not found + function _updateBillingTokenConfig( + Registry registry, + address billingToken, + AutomationRegistryBase2_3.BillingConfig memory newConfig + ) internal { + (, , address[] memory signers, address[] memory transmitters, uint8 f) = registry.getState(); + AutomationRegistryBase2_3.OnchainConfig memory config = registry.getConfig(); + address[] memory billingTokens = registry.getBillingTokens(); + + AutomationRegistryBase2_3.BillingConfig[] + memory billingTokenConfigs = new AutomationRegistryBase2_3.BillingConfig[](billingTokens.length); + + bool found = false; + for (uint256 i = 0; i < billingTokens.length; i++) { + if (billingTokens[i] == billingToken) { + found = true; + billingTokenConfigs[i] = newConfig; + } else { + billingTokenConfigs[i] = registry.getBillingTokenConfig(billingTokens[i]); + } + } + require(found, "could not find billing token provided on registry"); + + registry.setConfigTypeSafe( + signers, + transmitters, + f, + config, + OFFCHAIN_CONFIG_VERSION, + "", + billingTokens, + billingTokenConfigs + ); + } + + /// @notice this function removes a billing token from the registry + function _removeBillingTokenConfig(Registry registry, address billingToken) internal { + (, , address[] memory signers, address[] memory transmitters, uint8 f) = registry.getState(); + AutomationRegistryBase2_3.OnchainConfig memory config = registry.getConfig(); + address[] memory billingTokens = registry.getBillingTokens(); + + address[] memory newBillingTokens = new address[](billingTokens.length - 1); + AutomationRegistryBase2_3.BillingConfig[] + memory billingTokenConfigs = new AutomationRegistryBase2_3.BillingConfig[](billingTokens.length - 1); + + uint256 j = 0; + for (uint256 i = 0; i < billingTokens.length; i++) { + if (billingTokens[i] != billingToken) { + if (j == newBillingTokens.length) revert("could not find billing token provided on registry"); + newBillingTokens[j] = billingTokens[i]; + billingTokenConfigs[j] = registry.getBillingTokenConfig(billingTokens[i]); + j++; + } + } + + registry.setConfigTypeSafe( + signers, + transmitters, + f, + config, + OFFCHAIN_CONFIG_VERSION, + "", + newBillingTokens, + billingTokenConfigs + ); + } + + function _transmit(uint256 id, Registry registry, bytes4 selector) internal { + uint256[] memory ids = new uint256[](1); + ids[0] = id; + _transmit(ids, registry, selector); + } + + function _transmit(uint256[] memory ids, Registry registry, bytes4 selector) internal { + bytes memory reportBytes; + { + uint256[] memory upkeepIds = new uint256[](ids.length); + uint256[] memory gasLimits = new uint256[](ids.length); + bytes[] memory performDatas = new bytes[](ids.length); + bytes[] memory triggers = new bytes[](ids.length); + for (uint256 i = 0; i < ids.length; i++) { + upkeepIds[i] = ids[i]; + gasLimits[i] = registry.getUpkeep(ids[i]).performGas; + performDatas[i] = new bytes(0); + uint8 triggerType = registry.getTriggerType(ids[i]); + if (triggerType == 0) { + triggers[i] = _encodeConditionalTrigger( + ZKSyncAutoBase.ConditionalTrigger(uint32(block.number - 1), blockhash(block.number - 1)) + ); + } else { + revert("not implemented"); + } + } + ZKSyncAutoBase.Report memory report = ZKSyncAutoBase.Report( + uint256(1000000000), + uint256(2000000000), + upkeepIds, + gasLimits, + triggers, + performDatas + ); + + reportBytes = _encodeReport(report); + } + (, , bytes32 configDigest) = registry.latestConfigDetails(); + bytes32[3] memory reportContext = [configDigest, configDigest, configDigest]; + uint256[] memory signerPKs = new uint256[](2); + signerPKs[0] = SIGNING_KEY0; + signerPKs[1] = SIGNING_KEY1; + (bytes32[] memory rs, bytes32[] memory ss, bytes32 vs) = _signReport(reportBytes, reportContext, signerPKs); + + vm.startPrank(TRANSMITTERS[0]); + if (selector != bytes4(0)) { + vm.expectRevert(selector); + } + registry.transmit(reportContext, reportBytes, rs, ss, vs); + vm.stopPrank(); + } + + /// @notice Gather signatures on report data + /// @param report - Report bytes generated from `_buildReport` + /// @param reportContext - Report context bytes32 generated from `_buildReport` + /// @param signerPrivateKeys - One or more addresses that will sign the report data + /// @return rawRs - Signature rs + /// @return rawSs - Signature ss + /// @return rawVs - Signature vs + function _signReport( + bytes memory report, + bytes32[3] memory reportContext, + uint256[] memory signerPrivateKeys + ) internal pure returns (bytes32[] memory, bytes32[] memory, bytes32) { + bytes32[] memory rs = new bytes32[](signerPrivateKeys.length); + bytes32[] memory ss = new bytes32[](signerPrivateKeys.length); + bytes memory vs = new bytes(signerPrivateKeys.length); + + bytes32 reportDigest = keccak256(abi.encodePacked(keccak256(report), reportContext)); + + for (uint256 i = 0; i < signerPrivateKeys.length; i++) { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrivateKeys[i], reportDigest); + rs[i] = r; + ss[i] = s; + vs[i] = bytes1(v - 27); + } + + return (rs, ss, bytes32(vs)); + } + + function _encodeReport(ZKSyncAutoBase.Report memory report) internal pure returns (bytes memory reportBytes) { + return abi.encode(report); + } + + function _encodeConditionalTrigger( + ZKSyncAutoBase.ConditionalTrigger memory trigger + ) internal pure returns (bytes memory triggerBytes) { + return abi.encode(trigger.blockNum, trigger.blockHash); + } + + /// @dev mints LINK to the recipient + function _mintLink(address recipient, uint256 amount) internal { + vm.prank(OWNER); + linkToken.mint(recipient, amount); + } + + /// @dev mints USDToken with 18 decimals to the recipient + function _mintERC20_18Decimals(address recipient, uint256 amount) internal { + vm.prank(OWNER); + usdToken18.mint(recipient, amount); + } + + /// @dev returns a pseudo-random 32 bytes + function _random() private returns (bytes32) { + nonce++; + return keccak256(abi.encode(block.timestamp, nonce)); + } + + /// @dev returns a pseudo-random number + function randomNumber() internal returns (uint256) { + return uint256(_random()); + } + + /// @dev returns a pseudo-random address + function randomAddress() internal returns (address) { + return address(uint160(randomNumber())); + } + + /// @dev returns a pseudo-random byte array + function randomBytes(uint256 length) internal returns (bytes memory) { + bytes memory result = new bytes(length); + bytes32 entropy; + for (uint256 i = 0; i < length; i++) { + if (i % 32 == 0) { + entropy = _random(); + } + result[i] = entropy[i % 32]; + } + return result; + } +} diff --git a/contracts/src/v0.8/automation/test/v2_3_zksync/ZKSyncAutomationRegistry2_3.t.sol b/contracts/src/v0.8/automation/test/v2_3_zksync/ZKSyncAutomationRegistry2_3.t.sol new file mode 100644 index 0000000000..7098d9f38f --- /dev/null +++ b/contracts/src/v0.8/automation/test/v2_3_zksync/ZKSyncAutomationRegistry2_3.t.sol @@ -0,0 +1,2772 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {Vm} from "forge-std/Test.sol"; +import {BaseTest} from "./BaseTest.t.sol"; +import {ZKSyncAutomationRegistryBase2_3 as AutoBase} from "../../v2_3_zksync/ZKSyncAutomationRegistryBase2_3.sol"; +import {AutomationRegistrar2_3 as Registrar} from "../../v2_3/AutomationRegistrar2_3.sol"; +import {IAutomationRegistryMaster2_3 as Registry, AutomationRegistryBase2_3, IAutomationV21PlusCommon} from "../../interfaces/v2_3/IAutomationRegistryMaster2_3.sol"; +import {ChainModuleBase} from "../../chains/ChainModuleBase.sol"; +import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import {IWrappedNative} from "../../interfaces/v2_3/IWrappedNative.sol"; + +// forge test --match-path src/v0.8/automation/test/v2_3_zksync/ZKSyncAutomationRegistry2_3.t.sol --match-test + +enum Trigger { + CONDITION, + LOG +} + +contract SetUp is BaseTest { + Registry internal registry; + AutomationRegistryBase2_3.OnchainConfig internal config; + bytes internal constant offchainConfigBytes = abi.encode(1234, ZERO_ADDRESS); + + uint256 linkUpkeepID; + uint256 linkUpkeepID2; // 2 upkeeps use the same billing token (LINK) to test migration scenario + uint256 usdUpkeepID18; // 1 upkeep uses ERC20 token with 18 decimals + uint256 usdUpkeepID6; // 1 upkeep uses ERC20 token with 6 decimals + uint256 nativeUpkeepID; + + function setUp() public virtual override { + super.setUp(); + (registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.ON_CHAIN); + config = registry.getConfig(); + + vm.startPrank(OWNER); + linkToken.approve(address(registry), type(uint256).max); + usdToken6.approve(address(registry), type(uint256).max); + usdToken18.approve(address(registry), type(uint256).max); + weth.approve(address(registry), type(uint256).max); + vm.startPrank(UPKEEP_ADMIN); + linkToken.approve(address(registry), type(uint256).max); + usdToken6.approve(address(registry), type(uint256).max); + usdToken18.approve(address(registry), type(uint256).max); + weth.approve(address(registry), type(uint256).max); + vm.startPrank(STRANGER); + linkToken.approve(address(registry), type(uint256).max); + usdToken6.approve(address(registry), type(uint256).max); + usdToken18.approve(address(registry), type(uint256).max); + weth.approve(address(registry), type(uint256).max); + vm.stopPrank(); + + linkUpkeepID = registry.registerUpkeep( + address(TARGET1), + config.maxPerformGas, + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + address(linkToken), + "", + "", + "" + ); + + linkUpkeepID2 = registry.registerUpkeep( + address(TARGET1), + config.maxPerformGas, + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + address(linkToken), + "", + "", + "" + ); + + usdUpkeepID18 = registry.registerUpkeep( + address(TARGET1), + config.maxPerformGas, + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + address(usdToken18), + "", + "", + "" + ); + + usdUpkeepID6 = registry.registerUpkeep( + address(TARGET1), + config.maxPerformGas, + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + address(usdToken6), + "", + "", + "" + ); + + nativeUpkeepID = registry.registerUpkeep( + address(TARGET1), + config.maxPerformGas, + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + address(weth), + "", + "", + "" + ); + + vm.startPrank(OWNER); + registry.addFunds(linkUpkeepID, registry.getMinBalanceForUpkeep(linkUpkeepID)); + registry.addFunds(linkUpkeepID2, registry.getMinBalanceForUpkeep(linkUpkeepID2)); + registry.addFunds(usdUpkeepID18, registry.getMinBalanceForUpkeep(usdUpkeepID18)); + registry.addFunds(usdUpkeepID6, registry.getMinBalanceForUpkeep(usdUpkeepID6)); + registry.addFunds(nativeUpkeepID, registry.getMinBalanceForUpkeep(nativeUpkeepID)); + vm.stopPrank(); + } +} + +contract LatestConfigDetails is SetUp { + function testGet() public { + (uint32 configCount, uint32 blockNumber, bytes32 configDigest) = registry.latestConfigDetails(); + assertEq(configCount, 1); + assertTrue(blockNumber > 0); + assertNotEq(configDigest, ""); + } +} + +contract CheckUpkeep is SetUp { + function testPreventExecutionOnCheckUpkeep() public { + uint256 id = 1; + bytes memory triggerData = abi.encodePacked("trigger_data"); + + // The tx.origin is the DEFAULT_SENDER (0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38) of foundry + // Expecting a revert since the tx.origin is not address(0) + vm.expectRevert(abi.encodeWithSelector(Registry.OnlySimulatedBackend.selector)); + registry.checkUpkeep(id, triggerData); + } +} + +contract WithdrawFunds is SetUp { + event FundsWithdrawn(uint256 indexed id, uint256 amount, address to); + + function test_RevertsWhen_CalledByNonAdmin() external { + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + vm.prank(STRANGER); + registry.withdrawFunds(linkUpkeepID, STRANGER); + } + + function test_RevertsWhen_InvalidRecipient() external { + vm.expectRevert(Registry.InvalidRecipient.selector); + vm.prank(UPKEEP_ADMIN); + registry.withdrawFunds(linkUpkeepID, ZERO_ADDRESS); + } + + function test_RevertsWhen_UpkeepNotCanceled() external { + vm.expectRevert(Registry.UpkeepNotCanceled.selector); + vm.prank(UPKEEP_ADMIN); + registry.withdrawFunds(linkUpkeepID, UPKEEP_ADMIN); + } + + function test_Happy_Link() external { + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + vm.roll(100 + block.number); + + uint256 startUpkeepAdminBalance = linkToken.balanceOf(UPKEEP_ADMIN); + uint256 startLinkReserveAmountBalance = registry.getReserveAmount(address(linkToken)); + + uint256 upkeepBalance = registry.getBalance(linkUpkeepID); + vm.expectEmit(); + emit FundsWithdrawn(linkUpkeepID, upkeepBalance, address(UPKEEP_ADMIN)); + registry.withdrawFunds(linkUpkeepID, UPKEEP_ADMIN); + + assertEq(registry.getBalance(linkUpkeepID), 0); + assertEq(linkToken.balanceOf(UPKEEP_ADMIN), startUpkeepAdminBalance + upkeepBalance); + assertEq(registry.getReserveAmount(address(linkToken)), startLinkReserveAmountBalance - upkeepBalance); + } + + function test_Happy_USDToken() external { + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(usdUpkeepID6); + vm.roll(100 + block.number); + + uint256 startUpkeepAdminBalance = usdToken6.balanceOf(UPKEEP_ADMIN); + uint256 startUSDToken6ReserveAmountBalance = registry.getReserveAmount(address(usdToken6)); + + uint256 upkeepBalance = registry.getBalance(usdUpkeepID6); + vm.expectEmit(); + emit FundsWithdrawn(usdUpkeepID6, upkeepBalance, address(UPKEEP_ADMIN)); + registry.withdrawFunds(usdUpkeepID6, UPKEEP_ADMIN); + + assertEq(registry.getBalance(usdUpkeepID6), 0); + assertEq(usdToken6.balanceOf(UPKEEP_ADMIN), startUpkeepAdminBalance + upkeepBalance); + assertEq(registry.getReserveAmount(address(usdToken6)), startUSDToken6ReserveAmountBalance - upkeepBalance); + } +} + +contract AddFunds is SetUp { + event FundsAdded(uint256 indexed id, address indexed from, uint96 amount); + + // when msg.value is 0, it uses the ERC20 payment path + function test_HappyWhen_NativeUpkeep_WithMsgValue0() external { + vm.startPrank(OWNER); + uint256 startRegistryBalance = registry.getBalance(nativeUpkeepID); + uint256 startTokenBalance = registry.getBalance(nativeUpkeepID); + registry.addFunds(nativeUpkeepID, 1); + assertEq(registry.getBalance(nativeUpkeepID), startRegistryBalance + 1); + assertEq(weth.balanceOf(address(registry)), startTokenBalance + 1); + assertEq(registry.getAvailableERC20ForPayment(address(weth)), 0); + } + + // when msg.value is not 0, it uses the native payment path + function test_HappyWhen_NativeUpkeep_WithMsgValueNot0() external { + uint256 startRegistryBalance = registry.getBalance(nativeUpkeepID); + uint256 startTokenBalance = registry.getBalance(nativeUpkeepID); + registry.addFunds{value: 1}(nativeUpkeepID, 1000); // parameter amount should be ignored + assertEq(registry.getBalance(nativeUpkeepID), startRegistryBalance + 1); + assertEq(weth.balanceOf(address(registry)), startTokenBalance + 1); + assertEq(registry.getAvailableERC20ForPayment(address(weth)), 0); + } + + // it fails when the billing token is not native, but trying to pay with native + function test_RevertsWhen_NativePaymentDoesntMatchBillingToken() external { + vm.expectRevert(abi.encodeWithSelector(Registry.InvalidToken.selector)); + registry.addFunds{value: 1}(linkUpkeepID, 0); + } + + function test_RevertsWhen_UpkeepDoesNotExist() public { + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.addFunds(randomNumber(), 1); + } + + function test_RevertsWhen_UpkeepIsCanceled() public { + registry.cancelUpkeep(linkUpkeepID); + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.addFunds(linkUpkeepID, 1); + } + + function test_anyoneCanAddFunds() public { + uint256 startAmount = registry.getBalance(linkUpkeepID); + vm.prank(UPKEEP_ADMIN); + registry.addFunds(linkUpkeepID, 1); + assertEq(registry.getBalance(linkUpkeepID), startAmount + 1); + vm.prank(STRANGER); + registry.addFunds(linkUpkeepID, 1); + assertEq(registry.getBalance(linkUpkeepID), startAmount + 2); + } + + function test_movesFundFromCorrectToken() public { + vm.startPrank(UPKEEP_ADMIN); + + uint256 startLINKRegistryBalance = linkToken.balanceOf(address(registry)); + uint256 startUSDRegistryBalance = usdToken18.balanceOf(address(registry)); + uint256 startLinkUpkeepBalance = registry.getBalance(linkUpkeepID); + uint256 startUSDUpkeepBalance = registry.getBalance(usdUpkeepID18); + + registry.addFunds(linkUpkeepID, 1); + assertEq(registry.getBalance(linkUpkeepID), startLinkUpkeepBalance + 1); + assertEq(registry.getBalance(usdUpkeepID18), startUSDRegistryBalance); + assertEq(linkToken.balanceOf(address(registry)), startLINKRegistryBalance + 1); + assertEq(usdToken18.balanceOf(address(registry)), startUSDUpkeepBalance); + + registry.addFunds(usdUpkeepID18, 2); + assertEq(registry.getBalance(linkUpkeepID), startLinkUpkeepBalance + 1); + assertEq(registry.getBalance(usdUpkeepID18), startUSDRegistryBalance + 2); + assertEq(linkToken.balanceOf(address(registry)), startLINKRegistryBalance + 1); + assertEq(usdToken18.balanceOf(address(registry)), startUSDUpkeepBalance + 2); + } + + function test_emitsAnEvent() public { + vm.startPrank(UPKEEP_ADMIN); + vm.expectEmit(); + emit FundsAdded(linkUpkeepID, address(UPKEEP_ADMIN), 100); + registry.addFunds(linkUpkeepID, 100); + } +} + +contract Withdraw is SetUp { + address internal aMockAddress = randomAddress(); + + function testLinkAvailableForPaymentReturnsLinkBalance() public { + uint256 startBalance = linkToken.balanceOf(address(registry)); + int256 startLinkAvailable = registry.linkAvailableForPayment(); + + //simulate a deposit of link to the liquidity pool + _mintLink(address(registry), 1e10); + + //check there's a balance + assertEq(linkToken.balanceOf(address(registry)), startBalance + 1e10); + + //check the link available has increased by the same amount + assertEq(uint256(registry.linkAvailableForPayment()), uint256(startLinkAvailable) + 1e10); + } + + function testWithdrawLinkRevertsBecauseOnlyFinanceAdminAllowed() public { + vm.expectRevert(abi.encodeWithSelector(Registry.OnlyFinanceAdmin.selector)); + registry.withdrawLink(aMockAddress, 1); + } + + function testWithdrawLinkRevertsBecauseOfInsufficientBalance() public { + vm.startPrank(FINANCE_ADMIN); + + // try to withdraw 1 link while there is 0 balance + vm.expectRevert(abi.encodeWithSelector(Registry.InsufficientBalance.selector, 0, 1)); + registry.withdrawLink(aMockAddress, 1); + + vm.stopPrank(); + } + + function testWithdrawLinkRevertsBecauseOfInvalidRecipient() public { + vm.startPrank(FINANCE_ADMIN); + + // try to withdraw 1 link while there is 0 balance + vm.expectRevert(abi.encodeWithSelector(Registry.InvalidRecipient.selector)); + registry.withdrawLink(ZERO_ADDRESS, 1); + + vm.stopPrank(); + } + + function testWithdrawLinkSuccess() public { + //simulate a deposit of link to the liquidity pool + _mintLink(address(registry), 1e10); + uint256 startBalance = linkToken.balanceOf(address(registry)); + + vm.startPrank(FINANCE_ADMIN); + + // try to withdraw 1 link while there is a ton of link available + registry.withdrawLink(aMockAddress, 1); + + vm.stopPrank(); + + assertEq(linkToken.balanceOf(address(aMockAddress)), 1); + assertEq(linkToken.balanceOf(address(registry)), startBalance - 1); + } + + function test_WithdrawERC20Fees_RespectsReserveAmount() public { + assertEq(registry.getBalance(usdUpkeepID18), registry.getReserveAmount(address(usdToken18))); + vm.startPrank(FINANCE_ADMIN); + vm.expectRevert(abi.encodeWithSelector(Registry.InsufficientBalance.selector, 0, 1)); + registry.withdrawERC20Fees(address(usdToken18), FINANCE_ADMIN, 1); + } + + function test_WithdrawERC20Fees_RevertsWhen_AttemptingToWithdrawLINK() public { + _mintLink(address(registry), 1e10); + vm.startPrank(FINANCE_ADMIN); + vm.expectRevert(Registry.InvalidToken.selector); + registry.withdrawERC20Fees(address(linkToken), FINANCE_ADMIN, 1); // should revert + registry.withdrawLink(FINANCE_ADMIN, 1); // but using link withdraw functions succeeds + } + + // default is ON_CHAIN mode + function test_WithdrawERC20Fees_RevertsWhen_LinkAvailableForPaymentIsNegative() public { + _transmit(usdUpkeepID18, registry, bytes4(0)); // adds USD token to finance withdrawable, and gives NOPs a LINK balance + require(registry.linkAvailableForPayment() < 0, "linkAvailableForPayment should be negative"); + require( + registry.getAvailableERC20ForPayment(address(usdToken18)) > 0, + "ERC20AvailableForPayment should be positive" + ); + vm.expectRevert(Registry.InsufficientLinkLiquidity.selector); + vm.prank(FINANCE_ADMIN); + registry.withdrawERC20Fees(address(usdToken18), FINANCE_ADMIN, 1); // should revert + _mintLink(address(registry), uint256(registry.linkAvailableForPayment() * -10)); // top up LINK liquidity pool + vm.prank(FINANCE_ADMIN); + registry.withdrawERC20Fees(address(usdToken18), FINANCE_ADMIN, 1); // now finance can withdraw + } + + function test_WithdrawERC20Fees_InOffChainMode_Happy() public { + // deploy and configure a registry with OFF_CHAIN payout + (Registry registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN); + + // register an upkeep and add funds + uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken18), "", "", ""); + _mintERC20_18Decimals(UPKEEP_ADMIN, 1e20); + vm.startPrank(UPKEEP_ADMIN); + usdToken18.approve(address(registry), 1e20); + registry.addFunds(id, 1e20); + + // manually create a transmit so transmitters earn some rewards + _transmit(id, registry, bytes4(0)); + require(registry.linkAvailableForPayment() < 0, "linkAvailableForPayment should be negative"); + vm.prank(FINANCE_ADMIN); + registry.withdrawERC20Fees(address(usdToken18), aMockAddress, 1); // finance can withdraw + + // recipient should get the funds + assertEq(usdToken18.balanceOf(address(aMockAddress)), 1); + } + + function testWithdrawERC20FeeSuccess() public { + // deposit excess USDToken to the registry (this goes to the "finance withdrawable" pool be default) + uint256 startReserveAmount = registry.getReserveAmount(address(usdToken18)); + uint256 startAmount = usdToken18.balanceOf(address(registry)); + _mintERC20_18Decimals(address(registry), 1e10); + + // depositing shouldn't change reserve amount + assertEq(registry.getReserveAmount(address(usdToken18)), startReserveAmount); + + vm.startPrank(FINANCE_ADMIN); + + // try to withdraw 1 USDToken + registry.withdrawERC20Fees(address(usdToken18), aMockAddress, 1); + + vm.stopPrank(); + + assertEq(usdToken18.balanceOf(address(aMockAddress)), 1); + assertEq(usdToken18.balanceOf(address(registry)), startAmount + 1e10 - 1); + assertEq(registry.getReserveAmount(address(usdToken18)), startReserveAmount); + } +} + +contract SetConfig is SetUp { + event ConfigSet( + uint32 previousConfigBlockNumber, + bytes32 configDigest, + uint64 configCount, + address[] signers, + address[] transmitters, + uint8 f, + bytes onchainConfig, + uint64 offchainConfigVersion, + bytes offchainConfig + ); + + address module = address(new ChainModuleBase()); + + AutomationRegistryBase2_3.OnchainConfig cfg = + AutomationRegistryBase2_3.OnchainConfig({ + checkGasLimit: 5_000_000, + stalenessSeconds: 90_000, + gasCeilingMultiplier: 0, + maxPerformGas: 10_000_000, + maxCheckDataSize: 5_000, + maxPerformDataSize: 5_000, + maxRevertDataSize: 5_000, + fallbackGasPrice: 20_000_000_000, + fallbackLinkPrice: 2_000_000_000, // $20 + fallbackNativePrice: 400_000_000_000, // $4,000 + transcoder: 0xB1e66855FD67f6e85F0f0fA38cd6fBABdf00923c, + registrars: _getRegistrars(), + upkeepPrivilegeManager: PRIVILEGE_MANAGER, + chainModule: module, + reorgProtectionEnabled: true, + financeAdmin: FINANCE_ADMIN + }); + + function testSetConfigSuccess() public { + (uint32 configCount, uint32 blockNumber, ) = registry.latestConfigDetails(); + assertEq(configCount, 1); + + address billingTokenAddress = address(usdToken18); + address[] memory billingTokens = new address[](1); + billingTokens[0] = billingTokenAddress; + + AutomationRegistryBase2_3.BillingConfig[] memory billingConfigs = new AutomationRegistryBase2_3.BillingConfig[](1); + billingConfigs[0] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: 5_000, + flatFeeMilliCents: 20_000, + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 2_000_000_000, // $20 + minSpend: 100_000, + decimals: 18 + }); + + bytes memory onchainConfigBytes = abi.encode(cfg); + bytes memory onchainConfigBytesWithBilling = abi.encode(cfg, billingTokens, billingConfigs); + + bytes32 configDigest = _configDigestFromConfigData( + block.chainid, + address(registry), + ++configCount, + SIGNERS, + TRANSMITTERS, + F, + onchainConfigBytes, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + vm.expectEmit(); + emit ConfigSet( + blockNumber, + configDigest, + configCount, + SIGNERS, + TRANSMITTERS, + F, + onchainConfigBytes, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + registry.setConfig( + SIGNERS, + TRANSMITTERS, + F, + onchainConfigBytesWithBilling, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + (, , address[] memory signers, address[] memory transmitters, uint8 f) = registry.getState(); + + assertEq(signers, SIGNERS); + assertEq(transmitters, TRANSMITTERS); + assertEq(f, F); + + AutomationRegistryBase2_3.BillingConfig memory config = registry.getBillingTokenConfig(billingTokenAddress); + assertEq(config.gasFeePPB, 5_000); + assertEq(config.flatFeeMilliCents, 20_000); + assertEq(config.priceFeed, address(USDTOKEN_USD_FEED)); + assertEq(config.minSpend, 100_000); + + address[] memory tokens = registry.getBillingTokens(); + assertEq(tokens.length, 1); + } + + function testSetConfigMultipleBillingConfigsSuccess() public { + (uint32 configCount, , ) = registry.latestConfigDetails(); + assertEq(configCount, 1); + + address billingTokenAddress1 = address(linkToken); + address billingTokenAddress2 = address(usdToken18); + address[] memory billingTokens = new address[](2); + billingTokens[0] = billingTokenAddress1; + billingTokens[1] = billingTokenAddress2; + + AutomationRegistryBase2_3.BillingConfig[] memory billingConfigs = new AutomationRegistryBase2_3.BillingConfig[](2); + billingConfigs[0] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: 5_001, + flatFeeMilliCents: 20_001, + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 100, + minSpend: 100, + decimals: 18 + }); + billingConfigs[1] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: 5_002, + flatFeeMilliCents: 20_002, + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 200, + minSpend: 200, + decimals: 18 + }); + + bytes memory onchainConfigBytesWithBilling = abi.encode(cfg, billingTokens, billingConfigs); + + registry.setConfig( + SIGNERS, + TRANSMITTERS, + F, + onchainConfigBytesWithBilling, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + (, , address[] memory signers, address[] memory transmitters, uint8 f) = registry.getState(); + + assertEq(signers, SIGNERS); + assertEq(transmitters, TRANSMITTERS); + assertEq(f, F); + + AutomationRegistryBase2_3.BillingConfig memory config1 = registry.getBillingTokenConfig(billingTokenAddress1); + assertEq(config1.gasFeePPB, 5_001); + assertEq(config1.flatFeeMilliCents, 20_001); + assertEq(config1.priceFeed, address(USDTOKEN_USD_FEED)); + assertEq(config1.fallbackPrice, 100); + assertEq(config1.minSpend, 100); + + AutomationRegistryBase2_3.BillingConfig memory config2 = registry.getBillingTokenConfig(billingTokenAddress2); + assertEq(config2.gasFeePPB, 5_002); + assertEq(config2.flatFeeMilliCents, 20_002); + assertEq(config2.priceFeed, address(USDTOKEN_USD_FEED)); + assertEq(config2.fallbackPrice, 200); + assertEq(config2.minSpend, 200); + + address[] memory tokens = registry.getBillingTokens(); + assertEq(tokens.length, 2); + } + + function testSetConfigTwiceAndLastSetOverwrites() public { + (uint32 configCount, , ) = registry.latestConfigDetails(); + assertEq(configCount, 1); + + // BillingConfig1 + address billingTokenAddress1 = address(usdToken18); + address[] memory billingTokens1 = new address[](1); + billingTokens1[0] = billingTokenAddress1; + + AutomationRegistryBase2_3.BillingConfig[] memory billingConfigs1 = new AutomationRegistryBase2_3.BillingConfig[](1); + billingConfigs1[0] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: 5_001, + flatFeeMilliCents: 20_001, + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 100, + minSpend: 100, + decimals: 18 + }); + + // the first time uses the default onchain config with 2 registrars + bytes memory onchainConfigBytesWithBilling1 = abi.encode(cfg, billingTokens1, billingConfigs1); + + // set config once + registry.setConfig( + SIGNERS, + TRANSMITTERS, + F, + onchainConfigBytesWithBilling1, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + (, IAutomationV21PlusCommon.OnchainConfigLegacy memory onchainConfig1, , , ) = registry.getState(); + assertEq(onchainConfig1.registrars.length, 2); + + // BillingConfig2 + address billingTokenAddress2 = address(usdToken18); + address[] memory billingTokens2 = new address[](1); + billingTokens2[0] = billingTokenAddress2; + + AutomationRegistryBase2_3.BillingConfig[] memory billingConfigs2 = new AutomationRegistryBase2_3.BillingConfig[](1); + billingConfigs2[0] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: 5_002, + flatFeeMilliCents: 20_002, + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 200, + minSpend: 200, + decimals: 18 + }); + + address[] memory newRegistrars = new address[](3); + newRegistrars[0] = address(uint160(uint256(keccak256("newRegistrar1")))); + newRegistrars[1] = address(uint160(uint256(keccak256("newRegistrar2")))); + newRegistrars[2] = address(uint160(uint256(keccak256("newRegistrar3")))); + + // new onchain config with 3 new registrars, all other fields stay the same as the default + AutomationRegistryBase2_3.OnchainConfig memory cfg2 = AutomationRegistryBase2_3.OnchainConfig({ + checkGasLimit: 5_000_000, + stalenessSeconds: 90_000, + gasCeilingMultiplier: 0, + maxPerformGas: 10_000_000, + maxCheckDataSize: 5_000, + maxPerformDataSize: 5_000, + maxRevertDataSize: 5_000, + fallbackGasPrice: 20_000_000_000, + fallbackLinkPrice: 2_000_000_000, // $20 + fallbackNativePrice: 400_000_000_000, // $4,000 + transcoder: 0xB1e66855FD67f6e85F0f0fA38cd6fBABdf00923c, + registrars: newRegistrars, + upkeepPrivilegeManager: PRIVILEGE_MANAGER, + chainModule: module, + reorgProtectionEnabled: true, + financeAdmin: FINANCE_ADMIN + }); + + // the second time uses the new onchain config with 3 new registrars and also new billing tokens/configs + bytes memory onchainConfigBytesWithBilling2 = abi.encode(cfg2, billingTokens2, billingConfigs2); + + // set config twice + registry.setConfig( + SIGNERS, + TRANSMITTERS, + F, + onchainConfigBytesWithBilling2, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + ( + , + IAutomationV21PlusCommon.OnchainConfigLegacy memory onchainConfig2, + address[] memory signers, + address[] memory transmitters, + uint8 f + ) = registry.getState(); + + assertEq(onchainConfig2.registrars.length, 3); + for (uint256 i = 0; i < newRegistrars.length; i++) { + assertEq(newRegistrars[i], onchainConfig2.registrars[i]); + } + assertEq(signers, SIGNERS); + assertEq(transmitters, TRANSMITTERS); + assertEq(f, F); + + AutomationRegistryBase2_3.BillingConfig memory config2 = registry.getBillingTokenConfig(billingTokenAddress2); + assertEq(config2.gasFeePPB, 5_002); + assertEq(config2.flatFeeMilliCents, 20_002); + assertEq(config2.priceFeed, address(USDTOKEN_USD_FEED)); + assertEq(config2.fallbackPrice, 200); + assertEq(config2.minSpend, 200); + + address[] memory tokens = registry.getBillingTokens(); + assertEq(tokens.length, 1); + } + + function testSetConfigDuplicateBillingConfigFailure() public { + (uint32 configCount, , ) = registry.latestConfigDetails(); + assertEq(configCount, 1); + + address billingTokenAddress1 = address(linkToken); + address billingTokenAddress2 = address(linkToken); + address[] memory billingTokens = new address[](2); + billingTokens[0] = billingTokenAddress1; + billingTokens[1] = billingTokenAddress2; + + AutomationRegistryBase2_3.BillingConfig[] memory billingConfigs = new AutomationRegistryBase2_3.BillingConfig[](2); + billingConfigs[0] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: 5_001, + flatFeeMilliCents: 20_001, + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 100, + minSpend: 100, + decimals: 18 + }); + billingConfigs[1] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: 5_002, + flatFeeMilliCents: 20_002, + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 200, + minSpend: 200, + decimals: 18 + }); + + bytes memory onchainConfigBytesWithBilling = abi.encode(cfg, billingTokens, billingConfigs); + + // expect revert because of duplicate tokens + vm.expectRevert(abi.encodeWithSelector(Registry.DuplicateEntry.selector)); + registry.setConfig( + SIGNERS, + TRANSMITTERS, + F, + onchainConfigBytesWithBilling, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + } + + function testSetConfigRevertDueToInvalidToken() public { + address[] memory billingTokens = new address[](1); + billingTokens[0] = address(linkToken); + + AutomationRegistryBase2_3.BillingConfig[] memory billingConfigs = new AutomationRegistryBase2_3.BillingConfig[](1); + billingConfigs[0] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: 5_000, + flatFeeMilliCents: 20_000, + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 2_000_000_000, // $20 + minSpend: 100_000, + decimals: 18 + }); + + // deploy registry with OFF_CHAIN payout mode + registry = deployZKSyncRegistry(AutoBase.PayoutMode.OFF_CHAIN); + + vm.expectRevert(abi.encodeWithSelector(Registry.InvalidToken.selector)); + registry.setConfigTypeSafe( + SIGNERS, + TRANSMITTERS, + F, + cfg, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes, + billingTokens, + billingConfigs + ); + } + + function testSetConfigRevertDueToInvalidDecimals() public { + address[] memory billingTokens = new address[](1); + billingTokens[0] = address(linkToken); + + AutomationRegistryBase2_3.BillingConfig[] memory billingConfigs = new AutomationRegistryBase2_3.BillingConfig[](1); + billingConfigs[0] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: 5_000, + flatFeeMilliCents: 20_000, + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 2_000_000_000, // $20 + minSpend: 100_000, + decimals: 6 // link token should have 18 decimals + }); + + vm.expectRevert(abi.encodeWithSelector(Registry.InvalidToken.selector)); + registry.setConfigTypeSafe( + SIGNERS, + TRANSMITTERS, + F, + cfg, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes, + billingTokens, + billingConfigs + ); + } + + function testSetConfigOnTransmittersAndPayees() public { + registry.setPayees(PAYEES); + AutomationRegistryBase2_3.TransmitterPayeeInfo[] memory transmitterPayeeInfos = registry + .getTransmittersWithPayees(); + assertEq(transmitterPayeeInfos.length, TRANSMITTERS.length); + + for (uint256 i = 0; i < transmitterPayeeInfos.length; i++) { + address transmitterAddress = transmitterPayeeInfos[i].transmitterAddress; + address payeeAddress = transmitterPayeeInfos[i].payeeAddress; + + address expectedTransmitter = TRANSMITTERS[i]; + address expectedPayee = PAYEES[i]; + + assertEq(transmitterAddress, expectedTransmitter); + assertEq(payeeAddress, expectedPayee); + } + } + + function testSetConfigWithNewTransmittersSuccess() public { + registry = deployZKSyncRegistry(AutoBase.PayoutMode.OFF_CHAIN); + + (uint32 configCount, uint32 blockNumber, ) = registry.latestConfigDetails(); + assertEq(configCount, 0); + + address billingTokenAddress = address(usdToken18); + address[] memory billingTokens = new address[](1); + billingTokens[0] = billingTokenAddress; + + AutomationRegistryBase2_3.BillingConfig[] memory billingConfigs = new AutomationRegistryBase2_3.BillingConfig[](1); + billingConfigs[0] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: 5_000, + flatFeeMilliCents: 20_000, + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 2_000_000_000, // $20 + minSpend: 100_000, + decimals: 18 + }); + + bytes memory onchainConfigBytes = abi.encode(cfg); + + bytes32 configDigest = _configDigestFromConfigData( + block.chainid, + address(registry), + ++configCount, + SIGNERS, + TRANSMITTERS, + F, + onchainConfigBytes, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + vm.expectEmit(); + emit ConfigSet( + blockNumber, + configDigest, + configCount, + SIGNERS, + TRANSMITTERS, + F, + onchainConfigBytes, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + registry.setConfigTypeSafe( + SIGNERS, + TRANSMITTERS, + F, + cfg, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes, + billingTokens, + billingConfigs + ); + + (, , address[] memory signers, address[] memory transmitters, ) = registry.getState(); + assertEq(signers, SIGNERS); + assertEq(transmitters, TRANSMITTERS); + + (configCount, blockNumber, ) = registry.latestConfigDetails(); + configDigest = _configDigestFromConfigData( + block.chainid, + address(registry), + ++configCount, + SIGNERS, + NEW_TRANSMITTERS, + F, + onchainConfigBytes, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + vm.expectEmit(); + emit ConfigSet( + blockNumber, + configDigest, + configCount, + SIGNERS, + NEW_TRANSMITTERS, + F, + onchainConfigBytes, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + registry.setConfigTypeSafe( + SIGNERS, + NEW_TRANSMITTERS, + F, + cfg, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes, + billingTokens, + billingConfigs + ); + + (, , signers, transmitters, ) = registry.getState(); + assertEq(signers, SIGNERS); + assertEq(transmitters, NEW_TRANSMITTERS); + } + + function _getRegistrars() private pure returns (address[] memory) { + address[] memory registrars = new address[](2); + registrars[0] = address(uint160(uint256(keccak256("registrar1")))); + registrars[1] = address(uint160(uint256(keccak256("registrar2")))); + return registrars; + } + + function _configDigestFromConfigData( + uint256 chainId, + address contractAddress, + uint64 configCount, + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + chainId, + contractAddress, + configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + uint256 prefix = 0x0001 << (256 - 16); // 0x000100..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } +} + +contract NOPsSettlement is SetUp { + event NOPsSettledOffchain(address[] payees, uint256[] payments); + event FundsWithdrawn(uint256 indexed id, uint256 amount, address to); + event PaymentWithdrawn(address indexed transmitter, uint256 indexed amount, address indexed to, address payee); + + function testSettleNOPsOffchainRevertDueToUnauthorizedCaller() public { + (Registry registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.ON_CHAIN); + + vm.expectRevert(abi.encodeWithSelector(Registry.OnlyFinanceAdmin.selector)); + registry.settleNOPsOffchain(); + } + + function testSettleNOPsOffchainRevertDueToOffchainSettlementDisabled() public { + (Registry registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN); + + vm.prank(registry.owner()); + registry.disableOffchainPayments(); + + vm.prank(FINANCE_ADMIN); + vm.expectRevert(abi.encodeWithSelector(Registry.MustSettleOnchain.selector)); + registry.settleNOPsOffchain(); + } + + function testSettleNOPsOffchainSuccess() public { + // deploy and configure a registry with OFF_CHAIN payout + (Registry registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN); + registry.setPayees(PAYEES); + + uint256[] memory payments = new uint256[](TRANSMITTERS.length); + for (uint256 i = 0; i < TRANSMITTERS.length; i++) { + payments[i] = 0; + } + + vm.startPrank(FINANCE_ADMIN); + vm.expectEmit(); + emit NOPsSettledOffchain(PAYEES, payments); + registry.settleNOPsOffchain(); + } + + // 1. transmitter balance zeroed after settlement, 2. admin can withdraw ERC20, 3. switch to onchain mode, 4. link amount owed to NOPs stays the same + function testSettleNOPsOffchainSuccessWithERC20MultiSteps() public { + // deploy and configure a registry with OFF_CHAIN payout + (Registry registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN); + registry.setPayees(PAYEES); + + // register an upkeep and add funds + uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken18), "", "", ""); + _mintERC20_18Decimals(UPKEEP_ADMIN, 1e20); + vm.startPrank(UPKEEP_ADMIN); + usdToken18.approve(address(registry), 1e20); + registry.addFunds(id, 1e20); + + // manually create a transmit so transmitters earn some rewards + _transmit(id, registry, bytes4(0)); + + // verify transmitters have positive balances + uint256[] memory payments = new uint256[](TRANSMITTERS.length); + for (uint256 i = 0; i < TRANSMITTERS.length; i++) { + (bool active, uint8 index, uint96 balance, uint96 lastCollected, ) = registry.getTransmitterInfo(TRANSMITTERS[i]); + assertTrue(active); + assertEq(i, index); + assertTrue(balance > 0); + assertEq(0, lastCollected); + + payments[i] = balance; + } + + // verify offchain settlement will emit NOPs' balances + vm.startPrank(FINANCE_ADMIN); + vm.expectEmit(); + emit NOPsSettledOffchain(PAYEES, payments); + registry.settleNOPsOffchain(); + + // verify that transmitters balance has been zeroed out + for (uint256 i = 0; i < TRANSMITTERS.length; i++) { + (bool active, uint8 index, uint96 balance, , ) = registry.getTransmitterInfo(TRANSMITTERS[i]); + assertTrue(active); + assertEq(i, index); + assertEq(0, balance); + } + + // after the offchain settlement, the total reserve amount of LINK should be 0 + assertEq(registry.getReserveAmount(address(linkToken)), 0); + // should have some ERC20s in registry after transmit + uint256 erc20ForPayment1 = registry.getAvailableERC20ForPayment(address(usdToken18)); + require(erc20ForPayment1 > 0, "ERC20AvailableForPayment should be positive"); + + vm.startPrank(UPKEEP_ADMIN); + vm.roll(100 + block.number); + // manually create a transmit so transmitters earn some rewards + _transmit(id, registry, bytes4(0)); + + uint256 erc20ForPayment2 = registry.getAvailableERC20ForPayment(address(usdToken18)); + require(erc20ForPayment2 > erc20ForPayment1, "ERC20AvailableForPayment should be greater after another transmit"); + + // finance admin comes to withdraw all available ERC20s + vm.startPrank(FINANCE_ADMIN); + registry.withdrawERC20Fees(address(usdToken18), FINANCE_ADMIN, erc20ForPayment2); + + uint256 erc20ForPayment3 = registry.getAvailableERC20ForPayment(address(usdToken18)); + require(erc20ForPayment3 == 0, "ERC20AvailableForPayment should be 0 now after withdrawal"); + + uint256 reservedLink = registry.getReserveAmount(address(linkToken)); + require(reservedLink > 0, "Reserve amount of LINK should be positive since there was another transmit"); + + // owner comes to disable offchain mode + vm.startPrank(registry.owner()); + registry.disableOffchainPayments(); + + // finance admin comes to withdraw all available ERC20s, should revert bc of insufficient link liquidity + vm.startPrank(FINANCE_ADMIN); + uint256 erc20ForPayment4 = registry.getAvailableERC20ForPayment(address(usdToken18)); + vm.expectRevert(abi.encodeWithSelector(Registry.InsufficientLinkLiquidity.selector)); + registry.withdrawERC20Fees(address(usdToken18), FINANCE_ADMIN, erc20ForPayment4); + + // reserved link amount to NOPs should stay the same after switching to onchain mode + assertEq(registry.getReserveAmount(address(linkToken)), reservedLink); + // available ERC20 for payment should be 0 since finance admin withdrew all already + assertEq(erc20ForPayment4, 0); + } + + function testSettleNOPsOffchainForDeactivatedTransmittersSuccess() public { + // deploy and configure a registry with OFF_CHAIN payout + (Registry registry, Registrar registrar) = deployAndConfigureZKSyncRegistryAndRegistrar( + AutoBase.PayoutMode.OFF_CHAIN + ); + + // register an upkeep and add funds + uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken18), "", "", ""); + _mintERC20_18Decimals(UPKEEP_ADMIN, 1e20); + vm.startPrank(UPKEEP_ADMIN); + usdToken18.approve(address(registry), 1e20); + registry.addFunds(id, 1e20); + + // manually create a transmit so TRANSMITTERS earn some rewards + _transmit(id, registry, bytes4(0)); + + // TRANSMITTERS have positive balance now + // configure the registry to use NEW_TRANSMITTERS + _configureWithNewTransmitters(registry, registrar); + + _transmit(id, registry, bytes4(0)); + + // verify all transmitters have positive balances + address[] memory expectedPayees = new address[](6); + uint256[] memory expectedPayments = new uint256[](6); + for (uint256 i = 0; i < NEW_TRANSMITTERS.length; i++) { + (bool active, uint8 index, uint96 balance, uint96 lastCollected, address payee) = registry.getTransmitterInfo( + NEW_TRANSMITTERS[i] + ); + assertTrue(active); + assertEq(i, index); + assertTrue(lastCollected > 0); + expectedPayments[i] = balance; + expectedPayees[i] = payee; + } + for (uint256 i = 2; i < TRANSMITTERS.length; i++) { + (bool active, uint8 index, uint96 balance, uint96 lastCollected, address payee) = registry.getTransmitterInfo( + TRANSMITTERS[i] + ); + assertFalse(active); + assertEq(i, index); + assertTrue(balance > 0); + assertTrue(lastCollected > 0); + expectedPayments[2 + i] = balance; + expectedPayees[2 + i] = payee; + } + + // verify offchain settlement will emit NOPs' balances + vm.startPrank(FINANCE_ADMIN); + + // simply expectEmit won't work here because s_deactivatedTransmitters is an enumerable set so the order of these + // deactivated transmitters is not guaranteed. To handle this, we record logs and decode data field manually. + vm.recordLogs(); + registry.settleNOPsOffchain(); + Vm.Log[] memory entries = vm.getRecordedLogs(); + + assertEq(entries.length, 1); + Vm.Log memory l = entries[0]; + assertEq(l.topics[0], keccak256("NOPsSettledOffchain(address[],uint256[])")); + (address[] memory actualPayees, uint256[] memory actualPayments) = abi.decode(l.data, (address[], uint256[])); + assertEq(actualPayees.length, 6); + assertEq(actualPayments.length, 6); + + // first 4 payees and payments are for NEW_TRANSMITTERS and they are ordered. + for (uint256 i = 0; i < NEW_TRANSMITTERS.length; i++) { + assertEq(actualPayees[i], expectedPayees[i]); + assertEq(actualPayments[i], expectedPayments[i]); + } + + // the last 2 payees and payments for TRANSMITTERS[2] and TRANSMITTERS[3] and they are not ordered + assertTrue( + (actualPayments[5] == expectedPayments[5] && + actualPayees[5] == expectedPayees[5] && + actualPayments[4] == expectedPayments[4] && + actualPayees[4] == expectedPayees[4]) || + (actualPayments[5] == expectedPayments[4] && + actualPayees[5] == expectedPayees[4] && + actualPayments[4] == expectedPayments[5] && + actualPayees[4] == expectedPayees[5]) + ); + + // verify that new transmitters balance has been zeroed out + for (uint256 i = 0; i < NEW_TRANSMITTERS.length; i++) { + (bool active, uint8 index, uint96 balance, , ) = registry.getTransmitterInfo(NEW_TRANSMITTERS[i]); + assertTrue(active); + assertEq(i, index); + assertEq(0, balance); + } + // verify that deactivated transmitters (TRANSMITTERS[2] and TRANSMITTERS[3]) balance has been zeroed out + for (uint256 i = 2; i < TRANSMITTERS.length; i++) { + (bool active, uint8 index, uint96 balance, , ) = registry.getTransmitterInfo(TRANSMITTERS[i]); + assertFalse(active); + assertEq(i, index); + assertEq(0, balance); + } + + // after the offchain settlement, the total reserve amount of LINK should be 0 + assertEq(registry.getReserveAmount(address(linkToken)), 0); + } + + function testDisableOffchainPaymentsRevertDueToUnauthorizedCaller() public { + (Registry registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN); + + vm.startPrank(FINANCE_ADMIN); + vm.expectRevert(bytes("Only callable by owner")); + registry.disableOffchainPayments(); + } + + function testDisableOffchainPaymentsSuccess() public { + (Registry registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN); + + vm.startPrank(registry.owner()); + registry.disableOffchainPayments(); + + assertEq(uint8(AutoBase.PayoutMode.ON_CHAIN), registry.getPayoutMode()); + } + + function testSinglePerformAndNodesCanWithdrawOnchain() public { + // deploy and configure a registry with OFF_CHAIN payout + (Registry registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN); + registry.setPayees(PAYEES); + + // register an upkeep and add funds + uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken18), "", "", ""); + _mintERC20_18Decimals(UPKEEP_ADMIN, 1e20); + vm.startPrank(UPKEEP_ADMIN); + usdToken18.approve(address(registry), 1e20); + registry.addFunds(id, 1e20); + + // manually create a transmit so transmitters earn some rewards + _transmit(id, registry, bytes4(0)); + + // disable offchain payments + _mintLink(address(registry), 1e19); + vm.prank(registry.owner()); + registry.disableOffchainPayments(); + + // payees should be able to withdraw onchain + for (uint256 i = 0; i < TRANSMITTERS.length; i++) { + (, , uint96 balance, , address payee) = registry.getTransmitterInfo(TRANSMITTERS[i]); + vm.prank(payee); + vm.expectEmit(); + emit PaymentWithdrawn(TRANSMITTERS[i], balance, payee, payee); + registry.withdrawPayment(TRANSMITTERS[i], payee); + } + + // allow upkeep admin to withdraw funds + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(id); + vm.roll(100 + block.number); + vm.expectEmit(); + // the upkeep spent less than minimum spending limit so upkeep admin can only withdraw upkeep balance - min spend value + emit FundsWithdrawn(id, 9.9e19, UPKEEP_ADMIN); + registry.withdrawFunds(id, UPKEEP_ADMIN); + } + + function testMultiplePerformsAndNodesCanWithdrawOnchain() public { + // deploy and configure a registry with OFF_CHAIN payout + (Registry registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN); + registry.setPayees(PAYEES); + + // register an upkeep and add funds + uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken18), "", "", ""); + _mintERC20_18Decimals(UPKEEP_ADMIN, 1e20); + vm.startPrank(UPKEEP_ADMIN); + usdToken18.approve(address(registry), 1e20); + registry.addFunds(id, 1e20); + + // manually call transmit so transmitters earn some rewards + for (uint256 i = 0; i < 50; i++) { + vm.roll(100 + block.number); + _transmit(id, registry, bytes4(0)); + } + + // disable offchain payments + _mintLink(address(registry), 1e19); + vm.prank(registry.owner()); + registry.disableOffchainPayments(); + + // manually call transmit after offchain payment is disabled + for (uint256 i = 0; i < 50; i++) { + vm.roll(100 + block.number); + _transmit(id, registry, bytes4(0)); + } + + // payees should be able to withdraw onchain + for (uint256 i = 0; i < TRANSMITTERS.length; i++) { + (, , uint96 balance, , address payee) = registry.getTransmitterInfo(TRANSMITTERS[i]); + vm.prank(payee); + vm.expectEmit(); + emit PaymentWithdrawn(TRANSMITTERS[i], balance, payee, payee); + registry.withdrawPayment(TRANSMITTERS[i], payee); + } + + // allow upkeep admin to withdraw funds + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(id); + vm.roll(100 + block.number); + uint256 balance = registry.getBalance(id); + vm.expectEmit(); + emit FundsWithdrawn(id, balance, UPKEEP_ADMIN); + registry.withdrawFunds(id, UPKEEP_ADMIN); + } + + function _configureWithNewTransmitters(Registry registry, Registrar registrar) internal { + IERC20[] memory billingTokens = new IERC20[](1); + billingTokens[0] = IERC20(address(usdToken18)); + + uint256[] memory minRegistrationFees = new uint256[](billingTokens.length); + minRegistrationFees[0] = 100e18; // 100 USD + + address[] memory billingTokenAddresses = new address[](billingTokens.length); + for (uint256 i = 0; i < billingTokens.length; i++) { + billingTokenAddresses[i] = address(billingTokens[i]); + } + + AutomationRegistryBase2_3.BillingConfig[] + memory billingTokenConfigs = new AutomationRegistryBase2_3.BillingConfig[](billingTokens.length); + billingTokenConfigs[0] = AutomationRegistryBase2_3.BillingConfig({ + gasFeePPB: 10_000_000, // 15% + flatFeeMilliCents: 2_000, // 2 cents + priceFeed: address(USDTOKEN_USD_FEED), + fallbackPrice: 1e8, // $1 + minSpend: 1e18, // 1 USD + decimals: 18 + }); + + address[] memory registrars = new address[](1); + registrars[0] = address(registrar); + + AutomationRegistryBase2_3.OnchainConfig memory cfg = AutomationRegistryBase2_3.OnchainConfig({ + checkGasLimit: 5_000_000, + stalenessSeconds: 90_000, + gasCeilingMultiplier: 2, + maxPerformGas: 10_000_000, + maxCheckDataSize: 5_000, + maxPerformDataSize: 5_000, + maxRevertDataSize: 5_000, + fallbackGasPrice: 20_000_000_000, + fallbackLinkPrice: 2_000_000_000, // $20 + fallbackNativePrice: 400_000_000_000, // $4,000 + transcoder: 0xB1e66855FD67f6e85F0f0fA38cd6fBABdf00923c, + registrars: registrars, + upkeepPrivilegeManager: PRIVILEGE_MANAGER, + chainModule: address(new ChainModuleBase()), + reorgProtectionEnabled: true, + financeAdmin: FINANCE_ADMIN + }); + + registry.setConfigTypeSafe( + SIGNERS, + NEW_TRANSMITTERS, + F, + cfg, + OFFCHAIN_CONFIG_VERSION, + "", + billingTokenAddresses, + billingTokenConfigs + ); + + registry.setPayees(NEW_PAYEES); + } +} + +contract WithdrawPayment is SetUp { + function testWithdrawPaymentRevertDueToOffchainPayoutMode() public { + registry = deployZKSyncRegistry(AutoBase.PayoutMode.OFF_CHAIN); + vm.expectRevert(abi.encodeWithSelector(Registry.MustSettleOffchain.selector)); + vm.prank(TRANSMITTERS[0]); + registry.withdrawPayment(TRANSMITTERS[0], TRANSMITTERS[0]); + } +} + +contract RegisterUpkeep is SetUp { + function test_RevertsWhen_Paused() public { + registry.pause(); + vm.expectRevert(Registry.RegistryPaused.selector); + registry.registerUpkeep( + address(TARGET1), + config.maxPerformGas, + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + address(linkToken), + "", + "", + "" + ); + } + + function test_RevertsWhen_TargetIsNotAContract() public { + vm.expectRevert(Registry.NotAContract.selector); + registry.registerUpkeep( + randomAddress(), + config.maxPerformGas, + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + address(linkToken), + "", + "", + "" + ); + } + + function test_RevertsWhen_CalledByNonOwner() public { + vm.prank(STRANGER); + vm.expectRevert(Registry.OnlyCallableByOwnerOrRegistrar.selector); + registry.registerUpkeep( + address(TARGET1), + config.maxPerformGas, + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + address(linkToken), + "", + "", + "" + ); + } + + function test_RevertsWhen_ExecuteGasIsTooLow() public { + vm.expectRevert(Registry.GasLimitOutsideRange.selector); + registry.registerUpkeep( + address(TARGET1), + 2299, // 1 less than min + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + address(linkToken), + "", + "", + "" + ); + } + + function test_RevertsWhen_ExecuteGasIsTooHigh() public { + vm.expectRevert(Registry.GasLimitOutsideRange.selector); + registry.registerUpkeep( + address(TARGET1), + config.maxPerformGas + 1, + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + address(linkToken), + "", + "", + "" + ); + } + + function test_RevertsWhen_TheBillingTokenIsNotConfigured() public { + vm.expectRevert(Registry.InvalidToken.selector); + registry.registerUpkeep( + address(TARGET1), + config.maxPerformGas, + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + randomAddress(), + "", + "", + "" + ); + } + + function test_RevertsWhen_CheckDataIsTooLarge() public { + vm.expectRevert(Registry.CheckDataExceedsLimit.selector); + registry.registerUpkeep( + address(TARGET1), + config.maxPerformGas, + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + address(linkToken), + randomBytes(config.maxCheckDataSize + 1), + "", + "" + ); + } + + function test_Happy() public { + bytes memory checkData = randomBytes(config.maxCheckDataSize); + bytes memory trigggerConfig = randomBytes(100); + bytes memory offchainConfig = randomBytes(100); + + uint256 upkeepCount = registry.getNumUpkeeps(); + + uint256 upkeepID = registry.registerUpkeep( + address(TARGET1), + config.maxPerformGas, + UPKEEP_ADMIN, + uint8(Trigger.LOG), + address(linkToken), + checkData, + trigggerConfig, + offchainConfig + ); + + assertEq(registry.getNumUpkeeps(), upkeepCount + 1); + assertEq(registry.getUpkeep(upkeepID).target, address(TARGET1)); + assertEq(registry.getUpkeep(upkeepID).performGas, config.maxPerformGas); + assertEq(registry.getUpkeep(upkeepID).checkData, checkData); + assertEq(registry.getUpkeep(upkeepID).balance, 0); + assertEq(registry.getUpkeep(upkeepID).admin, UPKEEP_ADMIN); + assertEq(registry.getUpkeep(upkeepID).offchainConfig, offchainConfig); + assertEq(registry.getUpkeepTriggerConfig(upkeepID), trigggerConfig); + assertEq(uint8(registry.getTriggerType(upkeepID)), uint8(Trigger.LOG)); + } +} + +contract OnTokenTransfer is SetUp { + function test_RevertsWhen_NotCalledByTheLinkToken() public { + vm.expectRevert(Registry.OnlyCallableByLINKToken.selector); + registry.onTokenTransfer(UPKEEP_ADMIN, 100, abi.encode(linkUpkeepID)); + } + + function test_RevertsWhen_NotCalledWithExactly32Bytes() public { + vm.startPrank(address(linkToken)); + vm.expectRevert(Registry.InvalidDataLength.selector); + registry.onTokenTransfer(UPKEEP_ADMIN, 100, randomBytes(31)); + vm.expectRevert(Registry.InvalidDataLength.selector); + registry.onTokenTransfer(UPKEEP_ADMIN, 100, randomBytes(33)); + } + + function test_RevertsWhen_TheUpkeepIsCancelledOrDNE() public { + vm.startPrank(address(linkToken)); + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.onTokenTransfer(UPKEEP_ADMIN, 100, abi.encode(randomNumber())); + } + + function test_RevertsWhen_TheUpkeepDoesNotUseLINKAsItsBillingToken() public { + vm.startPrank(address(linkToken)); + vm.expectRevert(Registry.InvalidToken.selector); + registry.onTokenTransfer(UPKEEP_ADMIN, 100, abi.encode(usdUpkeepID18)); + } + + function test_Happy() public { + vm.startPrank(address(linkToken)); + uint256 beforeBalance = registry.getBalance(linkUpkeepID); + registry.onTokenTransfer(UPKEEP_ADMIN, 100, abi.encode(linkUpkeepID)); + assertEq(registry.getBalance(linkUpkeepID), beforeBalance + 100); + } +} + +contract GetMinBalanceForUpkeep is SetUp { + function test_accountsForFlatFee_with18Decimals() public { + // set fee to 0 + AutomationRegistryBase2_3.BillingConfig memory usdTokenConfig = registry.getBillingTokenConfig(address(usdToken18)); + usdTokenConfig.flatFeeMilliCents = 0; + _updateBillingTokenConfig(registry, address(usdToken18), usdTokenConfig); + + uint256 minBalanceBefore = registry.getMinBalanceForUpkeep(usdUpkeepID18); + + // set fee to non-zero + usdTokenConfig.flatFeeMilliCents = 100; + _updateBillingTokenConfig(registry, address(usdToken18), usdTokenConfig); + + uint256 minBalanceAfter = registry.getMinBalanceForUpkeep(usdUpkeepID18); + assertEq( + minBalanceAfter, + minBalanceBefore + ((uint256(usdTokenConfig.flatFeeMilliCents) * 1e13) / 10 ** (18 - usdTokenConfig.decimals)) + ); + } + + function test_accountsForFlatFee_with6Decimals() public { + // set fee to 0 + AutomationRegistryBase2_3.BillingConfig memory usdTokenConfig = registry.getBillingTokenConfig(address(usdToken6)); + usdTokenConfig.flatFeeMilliCents = 0; + _updateBillingTokenConfig(registry, address(usdToken6), usdTokenConfig); + + uint256 minBalanceBefore = registry.getMinBalanceForUpkeep(usdUpkeepID6); + + // set fee to non-zero + usdTokenConfig.flatFeeMilliCents = 100; + _updateBillingTokenConfig(registry, address(usdToken6), usdTokenConfig); + + uint256 minBalanceAfter = registry.getMinBalanceForUpkeep(usdUpkeepID6); + assertEq( + minBalanceAfter, + minBalanceBefore + ((uint256(usdTokenConfig.flatFeeMilliCents) * 1e13) / 10 ** (18 - usdTokenConfig.decimals)) + ); + } +} + +contract BillingOverrides is SetUp { + event BillingConfigOverridden(uint256 indexed id, AutomationRegistryBase2_3.BillingOverrides overrides); + event BillingConfigOverrideRemoved(uint256 indexed id); + + function test_RevertsWhen_NotPrivilegeManager() public { + AutomationRegistryBase2_3.BillingOverrides memory billingOverrides = AutomationRegistryBase2_3.BillingOverrides({ + gasFeePPB: 5_000, + flatFeeMilliCents: 20_000 + }); + + vm.expectRevert(Registry.OnlyCallableByUpkeepPrivilegeManager.selector); + registry.setBillingOverrides(linkUpkeepID, billingOverrides); + } + + function test_RevertsWhen_UpkeepCancelled() public { + AutomationRegistryBase2_3.BillingOverrides memory billingOverrides = AutomationRegistryBase2_3.BillingOverrides({ + gasFeePPB: 5_000, + flatFeeMilliCents: 20_000 + }); + + registry.cancelUpkeep(linkUpkeepID); + + vm.startPrank(PRIVILEGE_MANAGER); + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.setBillingOverrides(linkUpkeepID, billingOverrides); + } + + function test_Happy_SetBillingOverrides() public { + AutomationRegistryBase2_3.BillingOverrides memory billingOverrides = AutomationRegistryBase2_3.BillingOverrides({ + gasFeePPB: 5_000, + flatFeeMilliCents: 20_000 + }); + + vm.startPrank(PRIVILEGE_MANAGER); + + vm.expectEmit(); + emit BillingConfigOverridden(linkUpkeepID, billingOverrides); + registry.setBillingOverrides(linkUpkeepID, billingOverrides); + } + + function test_Happy_RemoveBillingOverrides() public { + vm.startPrank(PRIVILEGE_MANAGER); + + vm.expectEmit(); + emit BillingConfigOverrideRemoved(linkUpkeepID); + registry.removeBillingOverrides(linkUpkeepID); + } + + function test_Happy_MaxGasPayment_WithBillingOverrides() public { + uint96 maxPayment1 = registry.getMaxPaymentForGas(linkUpkeepID, 0, 5_000_000, address(linkToken)); + + // Double the two billing values + AutomationRegistryBase2_3.BillingOverrides memory billingOverrides = AutomationRegistryBase2_3.BillingOverrides({ + gasFeePPB: DEFAULT_GAS_FEE_PPB * 2, + flatFeeMilliCents: DEFAULT_FLAT_FEE_MILLI_CENTS * 2 + }); + + vm.startPrank(PRIVILEGE_MANAGER); + registry.setBillingOverrides(linkUpkeepID, billingOverrides); + + // maxPayment2 should be greater than maxPayment1 after the overrides + // The 2 numbers should follow this: maxPayment2 - maxPayment1 == 2 * recepit.premium + // We do not apply the exact equation since we couldn't get the receipt.premium value + uint96 maxPayment2 = registry.getMaxPaymentForGas(linkUpkeepID, 0, 5_000_000, address(linkToken)); + assertGt(maxPayment2, maxPayment1); + } +} + +contract Transmit is SetUp { + function test_transmitRevertWithExtraBytes() external { + bytes32[3] memory exampleReportContext = [ + bytes32(0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef), + bytes32(0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890), + bytes32(0x7890abcdef1234567890abcdef1234567890abcdef1234567890abcdef123456) + ]; + + bytes memory exampleRawReport = hex"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; + + bytes32[] memory exampleRs = new bytes32[](3); + exampleRs[0] = bytes32(0x1234561234561234561234561234561234561234561234561234561234561234); + exampleRs[1] = bytes32(0x1234561234561234561234561234561234561234561234561234561234561234); + exampleRs[2] = bytes32(0x7890789078907890789078907890789078907890789078907890789078907890); + + bytes32[] memory exampleSs = new bytes32[](3); + exampleSs[0] = bytes32(0x1234561234561234561234561234561234561234561234561234561234561234); + exampleSs[1] = bytes32(0x1234561234561234561234561234561234561234561234561234561234561234); + exampleSs[2] = bytes32(0x1234561234561234561234561234561234561234561234561234561234561234); + + bytes32 exampleRawVs = bytes32(0x1234561234561234561234561234561234561234561234561234561234561234); + + bytes memory transmitData = abi.encodeWithSelector( + registry.transmit.selector, + exampleReportContext, + exampleRawReport, + exampleRs, + exampleSs, + exampleRawVs + ); + bytes memory badTransmitData = bytes.concat(transmitData, bytes1(0x00)); // add extra data + vm.startPrank(TRANSMITTERS[0]); + (bool success, bytes memory returnData) = address(registry).call(badTransmitData); // send the bogus transmit + assertFalse(success, "Call did not revert as expected"); + assertEq(returnData, abi.encodePacked(Registry.InvalidDataLength.selector)); + vm.stopPrank(); + } + + function test_handlesMixedBatchOfBillingTokens() external { + uint256[] memory prevUpkeepBalances = new uint256[](3); + prevUpkeepBalances[0] = registry.getBalance(linkUpkeepID); + prevUpkeepBalances[1] = registry.getBalance(usdUpkeepID18); + prevUpkeepBalances[2] = registry.getBalance(nativeUpkeepID); + uint256[] memory prevTokenBalances = new uint256[](3); + prevTokenBalances[0] = linkToken.balanceOf(address(registry)); + prevTokenBalances[1] = usdToken18.balanceOf(address(registry)); + prevTokenBalances[2] = weth.balanceOf(address(registry)); + uint256[] memory prevReserveBalances = new uint256[](3); + prevReserveBalances[0] = registry.getReserveAmount(address(linkToken)); + prevReserveBalances[1] = registry.getReserveAmount(address(usdToken18)); + prevReserveBalances[2] = registry.getReserveAmount(address(weth)); + uint256[] memory upkeepIDs = new uint256[](3); + upkeepIDs[0] = linkUpkeepID; + upkeepIDs[1] = usdUpkeepID18; + upkeepIDs[2] = nativeUpkeepID; + + // withdraw-able by finance team should be 0 + require(registry.getAvailableERC20ForPayment(address(usdToken18)) == 0, "ERC20AvailableForPayment should be 0"); + require(registry.getAvailableERC20ForPayment(address(weth)) == 0, "ERC20AvailableForPayment should be 0"); + + // do the thing + _transmit(upkeepIDs, registry, bytes4(0)); + + // withdraw-able by the finance team should be positive + require( + registry.getAvailableERC20ForPayment(address(usdToken18)) > 0, + "ERC20AvailableForPayment should be positive" + ); + require(registry.getAvailableERC20ForPayment(address(weth)) > 0, "ERC20AvailableForPayment should be positive"); + + // assert upkeep balances have decreased + require(prevUpkeepBalances[0] > registry.getBalance(linkUpkeepID), "link upkeep balance should have decreased"); + require(prevUpkeepBalances[1] > registry.getBalance(usdUpkeepID18), "usd upkeep balance should have decreased"); + require(prevUpkeepBalances[2] > registry.getBalance(nativeUpkeepID), "native upkeep balance should have decreased"); + // assert token balances have not changed + assertEq(prevTokenBalances[0], linkToken.balanceOf(address(registry))); + assertEq(prevTokenBalances[1], usdToken18.balanceOf(address(registry))); + assertEq(prevTokenBalances[2], weth.balanceOf(address(registry))); + // assert reserve amounts have adjusted accordingly + require( + prevReserveBalances[0] < registry.getReserveAmount(address(linkToken)), + "usd reserve amount should have increased" + ); // link reserve amount increases in value equal to the decrease of the other reserve amounts + require( + prevReserveBalances[1] > registry.getReserveAmount(address(usdToken18)), + "usd reserve amount should have decreased" + ); + require( + prevReserveBalances[2] > registry.getReserveAmount(address(weth)), + "native reserve amount should have decreased" + ); + } + + function test_handlesInsufficientBalanceWithUSDToken18() external { + // deploy and configure a registry with ON_CHAIN payout + (Registry registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.ON_CHAIN); + + // register an upkeep and add funds + uint256 upkeepID = registry.registerUpkeep( + address(TARGET1), + 1000000, + UPKEEP_ADMIN, + 0, + address(usdToken18), + "", + "", + "" + ); + _mintERC20_18Decimals(UPKEEP_ADMIN, 1e20); + vm.startPrank(UPKEEP_ADMIN); + usdToken18.approve(address(registry), 1e20); + registry.addFunds(upkeepID, 1); // smaller than gasCharge + uint256 balance = registry.getBalance(upkeepID); + + // manually create a transmit + vm.recordLogs(); + _transmit(upkeepID, registry, bytes4(0)); + Vm.Log[] memory entries = vm.getRecordedLogs(); + + assertEq(entries.length, 3); + Vm.Log memory l1 = entries[1]; + assertEq( + l1.topics[0], + keccak256("UpkeepCharged(uint256,(uint96,uint96,uint96,uint96,address,uint96,uint96,uint96))") + ); + ( + uint96 gasChargeInBillingToken, + uint96 premiumInBillingToken, + uint96 gasReimbursementInJuels, + uint96 premiumInJuels, + address billingToken, + uint96 linkUSD, + uint96 nativeUSD, + uint96 billingUSD + ) = abi.decode(l1.data, (uint96, uint96, uint96, uint96, address, uint96, uint96, uint96)); + + assertEq(gasChargeInBillingToken, balance); + assertEq(gasReimbursementInJuels, (balance * billingUSD) / linkUSD); + assertEq(premiumInJuels, 0); + assertEq(premiumInBillingToken, 0); + } + + function test_handlesInsufficientBalanceWithUSDToken6() external { + // deploy and configure a registry with ON_CHAIN payout + (Registry registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.ON_CHAIN); + + // register an upkeep and add funds + uint256 upkeepID = registry.registerUpkeep( + address(TARGET1), + 1000000, + UPKEEP_ADMIN, + 0, + address(usdToken6), + "", + "", + "" + ); + vm.prank(OWNER); + usdToken6.mint(UPKEEP_ADMIN, 1e20); + + vm.startPrank(UPKEEP_ADMIN); + usdToken6.approve(address(registry), 1e20); + registry.addFunds(upkeepID, 100); // this is greater than gasCharge but less than (gasCharge + premium) + uint256 balance = registry.getBalance(upkeepID); + + // manually create a transmit + vm.recordLogs(); + _transmit(upkeepID, registry, bytes4(0)); + Vm.Log[] memory entries = vm.getRecordedLogs(); + + assertEq(entries.length, 3); + Vm.Log memory l1 = entries[1]; + assertEq( + l1.topics[0], + keccak256("UpkeepCharged(uint256,(uint96,uint96,uint96,uint96,address,uint96,uint96,uint96))") + ); + ( + uint96 gasChargeInBillingToken, + uint96 premiumInBillingToken, + uint96 gasReimbursementInJuels, + uint96 premiumInJuels, + address billingToken, + uint96 linkUSD, + uint96 nativeUSD, + uint96 billingUSD + ) = abi.decode(l1.data, (uint96, uint96, uint96, uint96, address, uint96, uint96, uint96)); + + assertEq(premiumInJuels, (balance * billingUSD * 1e12) / linkUSD - gasReimbursementInJuels); // scale to 18 decimals + assertEq(premiumInBillingToken, (premiumInJuels * linkUSD + (billingUSD * 1e12 - 1)) / (billingUSD * 1e12)); + } +} + +contract MigrateReceive is SetUp { + event UpkeepMigrated(uint256 indexed id, uint256 remainingBalance, address destination); + event UpkeepReceived(uint256 indexed id, uint256 startingBalance, address importedFrom); + + Registry newRegistry; + uint256[] idsToMigrate; + + function setUp() public override { + super.setUp(); + (newRegistry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.ON_CHAIN); + idsToMigrate.push(linkUpkeepID); + idsToMigrate.push(linkUpkeepID2); + idsToMigrate.push(usdUpkeepID18); + idsToMigrate.push(nativeUpkeepID); + registry.setPeerRegistryMigrationPermission(address(newRegistry), 1); + newRegistry.setPeerRegistryMigrationPermission(address(registry), 2); + } + + function test_RevertsWhen_PermissionsNotSet() external { + // no permissions + registry.setPeerRegistryMigrationPermission(address(newRegistry), 0); + newRegistry.setPeerRegistryMigrationPermission(address(registry), 0); + vm.expectRevert(Registry.MigrationNotPermitted.selector); + vm.prank(UPKEEP_ADMIN); + registry.migrateUpkeeps(idsToMigrate, address(newRegistry)); + + // only outgoing permissions + registry.setPeerRegistryMigrationPermission(address(newRegistry), 1); + newRegistry.setPeerRegistryMigrationPermission(address(registry), 0); + vm.expectRevert(Registry.MigrationNotPermitted.selector); + vm.prank(UPKEEP_ADMIN); + registry.migrateUpkeeps(idsToMigrate, address(newRegistry)); + + // only incoming permissions + registry.setPeerRegistryMigrationPermission(address(newRegistry), 0); + newRegistry.setPeerRegistryMigrationPermission(address(registry), 2); + vm.expectRevert(Registry.MigrationNotPermitted.selector); + vm.prank(UPKEEP_ADMIN); + registry.migrateUpkeeps(idsToMigrate, address(newRegistry)); + + // permissions opposite direction + registry.setPeerRegistryMigrationPermission(address(newRegistry), 2); + newRegistry.setPeerRegistryMigrationPermission(address(registry), 1); + vm.expectRevert(Registry.MigrationNotPermitted.selector); + vm.prank(UPKEEP_ADMIN); + registry.migrateUpkeeps(idsToMigrate, address(newRegistry)); + } + + function test_RevertsWhen_ReceivingRegistryDoesNotSupportToken() external { + _removeBillingTokenConfig(newRegistry, address(weth)); + vm.expectRevert(Registry.InvalidToken.selector); + vm.prank(UPKEEP_ADMIN); + registry.migrateUpkeeps(idsToMigrate, address(newRegistry)); + idsToMigrate.pop(); // remove native upkeep id + vm.prank(UPKEEP_ADMIN); + registry.migrateUpkeeps(idsToMigrate, address(newRegistry)); // should succeed now + } + + function test_RevertsWhen_CalledByNonAdmin() external { + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + vm.prank(STRANGER); + registry.migrateUpkeeps(idsToMigrate, address(newRegistry)); + } + + function test_Success() external { + vm.startPrank(UPKEEP_ADMIN); + + // add some changes in upkeep data to the mix + registry.pauseUpkeep(usdUpkeepID18); + registry.setUpkeepTriggerConfig(linkUpkeepID, randomBytes(100)); + registry.setUpkeepCheckData(nativeUpkeepID, randomBytes(25)); + + // record previous state + uint256[] memory prevUpkeepBalances = new uint256[](4); + prevUpkeepBalances[0] = registry.getBalance(linkUpkeepID); + prevUpkeepBalances[1] = registry.getBalance(linkUpkeepID2); + prevUpkeepBalances[2] = registry.getBalance(usdUpkeepID18); + prevUpkeepBalances[3] = registry.getBalance(nativeUpkeepID); + uint256[] memory prevReserveBalances = new uint256[](3); + prevReserveBalances[0] = registry.getReserveAmount(address(linkToken)); + prevReserveBalances[1] = registry.getReserveAmount(address(usdToken18)); + prevReserveBalances[2] = registry.getReserveAmount(address(weth)); + uint256[] memory prevTokenBalances = new uint256[](3); + prevTokenBalances[0] = linkToken.balanceOf(address(registry)); + prevTokenBalances[1] = usdToken18.balanceOf(address(registry)); + prevTokenBalances[2] = weth.balanceOf(address(registry)); + bytes[] memory prevUpkeepData = new bytes[](4); + prevUpkeepData[0] = abi.encode(registry.getUpkeep(linkUpkeepID)); + prevUpkeepData[1] = abi.encode(registry.getUpkeep(linkUpkeepID2)); + prevUpkeepData[2] = abi.encode(registry.getUpkeep(usdUpkeepID18)); + prevUpkeepData[3] = abi.encode(registry.getUpkeep(nativeUpkeepID)); + bytes[] memory prevUpkeepTriggerData = new bytes[](4); + prevUpkeepTriggerData[0] = registry.getUpkeepTriggerConfig(linkUpkeepID); + prevUpkeepTriggerData[1] = registry.getUpkeepTriggerConfig(linkUpkeepID2); + prevUpkeepTriggerData[2] = registry.getUpkeepTriggerConfig(usdUpkeepID18); + prevUpkeepTriggerData[3] = registry.getUpkeepTriggerConfig(nativeUpkeepID); + + // event expectations + vm.expectEmit(address(registry)); + emit UpkeepMigrated(linkUpkeepID, prevUpkeepBalances[0], address(newRegistry)); + vm.expectEmit(address(registry)); + emit UpkeepMigrated(linkUpkeepID2, prevUpkeepBalances[1], address(newRegistry)); + vm.expectEmit(address(registry)); + emit UpkeepMigrated(usdUpkeepID18, prevUpkeepBalances[2], address(newRegistry)); + vm.expectEmit(address(registry)); + emit UpkeepMigrated(nativeUpkeepID, prevUpkeepBalances[3], address(newRegistry)); + vm.expectEmit(address(newRegistry)); + emit UpkeepReceived(linkUpkeepID, prevUpkeepBalances[0], address(registry)); + vm.expectEmit(address(newRegistry)); + emit UpkeepReceived(linkUpkeepID2, prevUpkeepBalances[1], address(registry)); + vm.expectEmit(address(newRegistry)); + emit UpkeepReceived(usdUpkeepID18, prevUpkeepBalances[2], address(registry)); + vm.expectEmit(address(newRegistry)); + emit UpkeepReceived(nativeUpkeepID, prevUpkeepBalances[3], address(registry)); + + // do the thing + registry.migrateUpkeeps(idsToMigrate, address(newRegistry)); + + // assert upkeep balances have been migrated + assertEq(registry.getBalance(linkUpkeepID), 0); + assertEq(registry.getBalance(linkUpkeepID2), 0); + assertEq(registry.getBalance(usdUpkeepID18), 0); + assertEq(registry.getBalance(nativeUpkeepID), 0); + assertEq(newRegistry.getBalance(linkUpkeepID), prevUpkeepBalances[0]); + assertEq(newRegistry.getBalance(linkUpkeepID2), prevUpkeepBalances[1]); + assertEq(newRegistry.getBalance(usdUpkeepID18), prevUpkeepBalances[2]); + assertEq(newRegistry.getBalance(nativeUpkeepID), prevUpkeepBalances[3]); + + // assert reserve balances have been adjusted + assertEq( + newRegistry.getReserveAmount(address(linkToken)), + newRegistry.getBalance(linkUpkeepID) + newRegistry.getBalance(linkUpkeepID2) + ); + assertEq(newRegistry.getReserveAmount(address(usdToken18)), newRegistry.getBalance(usdUpkeepID18)); + assertEq(newRegistry.getReserveAmount(address(weth)), newRegistry.getBalance(nativeUpkeepID)); + assertEq( + newRegistry.getReserveAmount(address(linkToken)), + prevReserveBalances[0] - registry.getReserveAmount(address(linkToken)) + ); + assertEq( + newRegistry.getReserveAmount(address(usdToken18)), + prevReserveBalances[1] - registry.getReserveAmount(address(usdToken18)) + ); + assertEq( + newRegistry.getReserveAmount(address(weth)), + prevReserveBalances[2] - registry.getReserveAmount(address(weth)) + ); + + // assert token have been transferred + assertEq( + linkToken.balanceOf(address(newRegistry)), + newRegistry.getBalance(linkUpkeepID) + newRegistry.getBalance(linkUpkeepID2) + ); + assertEq(usdToken18.balanceOf(address(newRegistry)), newRegistry.getBalance(usdUpkeepID18)); + assertEq(weth.balanceOf(address(newRegistry)), newRegistry.getBalance(nativeUpkeepID)); + assertEq(linkToken.balanceOf(address(registry)), prevTokenBalances[0] - linkToken.balanceOf(address(newRegistry))); + assertEq( + usdToken18.balanceOf(address(registry)), + prevTokenBalances[1] - usdToken18.balanceOf(address(newRegistry)) + ); + assertEq(weth.balanceOf(address(registry)), prevTokenBalances[2] - weth.balanceOf(address(newRegistry))); + + // assert upkeep data matches + assertEq(prevUpkeepData[0], abi.encode(newRegistry.getUpkeep(linkUpkeepID))); + assertEq(prevUpkeepData[1], abi.encode(newRegistry.getUpkeep(linkUpkeepID2))); + assertEq(prevUpkeepData[2], abi.encode(newRegistry.getUpkeep(usdUpkeepID18))); + assertEq(prevUpkeepData[3], abi.encode(newRegistry.getUpkeep(nativeUpkeepID))); + assertEq(prevUpkeepTriggerData[0], newRegistry.getUpkeepTriggerConfig(linkUpkeepID)); + assertEq(prevUpkeepTriggerData[1], newRegistry.getUpkeepTriggerConfig(linkUpkeepID2)); + assertEq(prevUpkeepTriggerData[2], newRegistry.getUpkeepTriggerConfig(usdUpkeepID18)); + assertEq(prevUpkeepTriggerData[3], newRegistry.getUpkeepTriggerConfig(nativeUpkeepID)); + + vm.stopPrank(); + } +} + +contract Pause is SetUp { + function test_RevertsWhen_CalledByNonOwner() external { + vm.expectRevert(bytes("Only callable by owner")); + vm.prank(STRANGER); + registry.pause(); + } + + function test_CalledByOwner_success() external { + vm.startPrank(registry.owner()); + registry.pause(); + + (IAutomationV21PlusCommon.StateLegacy memory state, , , , ) = registry.getState(); + assertTrue(state.paused); + } + + function test_revertsWhen_registerUpkeepInPausedRegistry() external { + vm.startPrank(registry.owner()); + registry.pause(); + + vm.expectRevert(Registry.RegistryPaused.selector); + uint256 id = registry.registerUpkeep( + address(TARGET1), + config.maxPerformGas, + UPKEEP_ADMIN, + uint8(Trigger.CONDITION), + address(linkToken), + "", + "", + "" + ); + } + + function test_revertsWhen_transmitInPausedRegistry() external { + vm.startPrank(registry.owner()); + registry.pause(); + + _transmit(usdUpkeepID18, registry, Registry.RegistryPaused.selector); + } +} + +contract Unpause is SetUp { + function test_RevertsWhen_CalledByNonOwner() external { + vm.startPrank(registry.owner()); + registry.pause(); + + vm.expectRevert(bytes("Only callable by owner")); + vm.startPrank(STRANGER); + registry.unpause(); + } + + function test_CalledByOwner_success() external { + vm.startPrank(registry.owner()); + registry.pause(); + (IAutomationV21PlusCommon.StateLegacy memory state1, , , , ) = registry.getState(); + assertTrue(state1.paused); + + registry.unpause(); + (IAutomationV21PlusCommon.StateLegacy memory state2, , , , ) = registry.getState(); + assertFalse(state2.paused); + } +} + +contract CancelUpkeep is SetUp { + event UpkeepCanceled(uint256 indexed id, uint64 indexed atBlockHeight); + + function test_RevertsWhen_IdIsInvalid_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + vm.expectRevert(Registry.CannotCancel.selector); + registry.cancelUpkeep(1111111); + } + + function test_RevertsWhen_IdIsInvalid_CalledByOwner() external { + vm.startPrank(registry.owner()); + vm.expectRevert(Registry.CannotCancel.selector); + registry.cancelUpkeep(1111111); + } + + function test_RevertsWhen_NotCalledByOwnerOrAdmin() external { + vm.startPrank(STRANGER); + vm.expectRevert(Registry.OnlyCallableByOwnerOrAdmin.selector); + registry.cancelUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepAlreadyCanceledByAdmin_CalledByOwner() external { + uint256 bn = block.number; + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.startPrank(registry.owner()); + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.cancelUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepAlreadyCanceledByOwner_CalledByAdmin() external { + uint256 bn = block.number; + vm.startPrank(registry.owner()); + registry.cancelUpkeep(linkUpkeepID); + + vm.startPrank(UPKEEP_ADMIN); + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.cancelUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepAlreadyCanceledByAdmin_CalledByAdmin() external { + uint256 bn = block.number; + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.cancelUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepAlreadyCanceledByOwner_CalledByOwner() external { + uint256 bn = block.number; + vm.startPrank(registry.owner()); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.cancelUpkeep(linkUpkeepID); + } + + function test_CancelUpkeep_SetMaxValidBlockNumber_CalledByAdmin() external { + uint256 bn = block.number; + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + uint256 maxValidBlocknumber = uint256(registry.getUpkeep(linkUpkeepID).maxValidBlocknumber); + + // 50 is the cancellation delay + assertEq(bn + 50, maxValidBlocknumber); + } + + function test_CancelUpkeep_SetMaxValidBlockNumber_CalledByOwner() external { + uint256 bn = block.number; + vm.startPrank(registry.owner()); + registry.cancelUpkeep(linkUpkeepID); + + uint256 maxValidBlocknumber = uint256(registry.getUpkeep(linkUpkeepID).maxValidBlocknumber); + + // cancellation by registry owner is immediate and no cancellation delay is applied + assertEq(bn, maxValidBlocknumber); + } + + function test_CancelUpkeep_EmitEvent_CalledByAdmin() external { + uint256 bn = block.number; + vm.startPrank(UPKEEP_ADMIN); + + vm.expectEmit(); + emit UpkeepCanceled(linkUpkeepID, uint64(bn + 50)); + registry.cancelUpkeep(linkUpkeepID); + } + + function test_CancelUpkeep_EmitEvent_CalledByOwner() external { + uint256 bn = block.number; + vm.startPrank(registry.owner()); + + vm.expectEmit(); + emit UpkeepCanceled(linkUpkeepID, uint64(bn)); + registry.cancelUpkeep(linkUpkeepID); + } +} + +contract SetPeerRegistryMigrationPermission is SetUp { + function test_SetPeerRegistryMigrationPermission_CalledByOwner() external { + address peer = randomAddress(); + vm.startPrank(registry.owner()); + + uint8 permission = registry.getPeerRegistryMigrationPermission(peer); + assertEq(0, permission); + + registry.setPeerRegistryMigrationPermission(peer, 1); + permission = registry.getPeerRegistryMigrationPermission(peer); + assertEq(1, permission); + + registry.setPeerRegistryMigrationPermission(peer, 2); + permission = registry.getPeerRegistryMigrationPermission(peer); + assertEq(2, permission); + + registry.setPeerRegistryMigrationPermission(peer, 0); + permission = registry.getPeerRegistryMigrationPermission(peer); + assertEq(0, permission); + } + + function test_RevertsWhen_InvalidPermission_CalledByOwner() external { + address peer = randomAddress(); + vm.startPrank(registry.owner()); + + vm.expectRevert(); + registry.setPeerRegistryMigrationPermission(peer, 100); + } + + function test_RevertsWhen_CalledByNonOwner() external { + address peer = randomAddress(); + vm.startPrank(STRANGER); + + vm.expectRevert(bytes("Only callable by owner")); + registry.setPeerRegistryMigrationPermission(peer, 1); + } +} + +contract SetUpkeepPrivilegeConfig is SetUp { + function test_RevertsWhen_CalledByNonManager() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByUpkeepPrivilegeManager.selector); + registry.setUpkeepPrivilegeConfig(linkUpkeepID, hex"1233"); + } + + function test_UpkeepHasEmptyConfig() external { + bytes memory cfg = registry.getUpkeepPrivilegeConfig(linkUpkeepID); + assertEq(cfg, bytes("")); + } + + function test_SetUpkeepPrivilegeConfig_CalledByManager() external { + vm.startPrank(PRIVILEGE_MANAGER); + + registry.setUpkeepPrivilegeConfig(linkUpkeepID, hex"1233"); + + bytes memory cfg = registry.getUpkeepPrivilegeConfig(linkUpkeepID); + assertEq(cfg, hex"1233"); + } +} + +contract SetAdminPrivilegeConfig is SetUp { + function test_RevertsWhen_CalledByNonManager() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByUpkeepPrivilegeManager.selector); + registry.setAdminPrivilegeConfig(randomAddress(), hex"1233"); + } + + function test_UpkeepHasEmptyConfig() external { + bytes memory cfg = registry.getAdminPrivilegeConfig(randomAddress()); + assertEq(cfg, bytes("")); + } + + function test_SetAdminPrivilegeConfig_CalledByManager() external { + vm.startPrank(PRIVILEGE_MANAGER); + address admin = randomAddress(); + + registry.setAdminPrivilegeConfig(admin, hex"1233"); + + bytes memory cfg = registry.getAdminPrivilegeConfig(admin); + assertEq(cfg, hex"1233"); + } +} + +contract TransferUpkeepAdmin is SetUp { + event UpkeepAdminTransferRequested(uint256 indexed id, address indexed from, address indexed to); + + function test_RevertsWhen_NotCalledByAdmin() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.transferUpkeepAdmin(linkUpkeepID, randomAddress()); + } + + function test_RevertsWhen_TransferToSelf() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.ValueNotChanged.selector); + registry.transferUpkeepAdmin(linkUpkeepID, UPKEEP_ADMIN); + } + + function test_RevertsWhen_UpkeepCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.transferUpkeepAdmin(linkUpkeepID, randomAddress()); + } + + function test_DoesNotChangeUpkeepAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + registry.transferUpkeepAdmin(linkUpkeepID, randomAddress()); + + assertEq(registry.getUpkeep(linkUpkeepID).admin, UPKEEP_ADMIN); + } + + function test_EmitEvent_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + address newAdmin = randomAddress(); + + vm.expectEmit(); + emit UpkeepAdminTransferRequested(linkUpkeepID, UPKEEP_ADMIN, newAdmin); + registry.transferUpkeepAdmin(linkUpkeepID, newAdmin); + + // transferring to the same propose admin won't yield another event + vm.recordLogs(); + registry.transferUpkeepAdmin(linkUpkeepID, newAdmin); + Vm.Log[] memory entries = vm.getRecordedLogs(); + assertEq(0, entries.length); + } + + function test_CancelTransfer_ByTransferToEmptyAddress() external { + vm.startPrank(UPKEEP_ADMIN); + address newAdmin = randomAddress(); + + vm.expectEmit(); + emit UpkeepAdminTransferRequested(linkUpkeepID, UPKEEP_ADMIN, newAdmin); + registry.transferUpkeepAdmin(linkUpkeepID, newAdmin); + + vm.expectEmit(); + emit UpkeepAdminTransferRequested(linkUpkeepID, UPKEEP_ADMIN, address(0)); + registry.transferUpkeepAdmin(linkUpkeepID, address(0)); + } +} + +contract AcceptUpkeepAdmin is SetUp { + event UpkeepAdminTransferred(uint256 indexed id, address indexed from, address indexed to); + + function test_RevertsWhen_NotCalledByProposedAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + address newAdmin = randomAddress(); + registry.transferUpkeepAdmin(linkUpkeepID, newAdmin); + + vm.startPrank(STRANGER); + vm.expectRevert(Registry.OnlyCallableByProposedAdmin.selector); + registry.acceptUpkeepAdmin(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + address newAdmin = randomAddress(); + registry.transferUpkeepAdmin(linkUpkeepID, newAdmin); + + registry.cancelUpkeep(linkUpkeepID); + + vm.startPrank(newAdmin); + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.acceptUpkeepAdmin(linkUpkeepID); + } + + function test_UpkeepAdminChanged() external { + vm.startPrank(UPKEEP_ADMIN); + address newAdmin = randomAddress(); + registry.transferUpkeepAdmin(linkUpkeepID, newAdmin); + + vm.startPrank(newAdmin); + vm.expectEmit(); + emit UpkeepAdminTransferred(linkUpkeepID, UPKEEP_ADMIN, newAdmin); + registry.acceptUpkeepAdmin(linkUpkeepID); + + assertEq(newAdmin, registry.getUpkeep(linkUpkeepID).admin); + } +} + +contract PauseUpkeep is SetUp { + event UpkeepPaused(uint256 indexed id); + + function test_RevertsWhen_NotCalledByUpkeepAdmin() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.pauseUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_InvalidUpkeepId() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.pauseUpkeep(linkUpkeepID + 1); + } + + function test_RevertsWhen_UpkeepAlreadyCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.pauseUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepAlreadyPaused() external { + vm.startPrank(UPKEEP_ADMIN); + registry.pauseUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.OnlyUnpausedUpkeep.selector); + registry.pauseUpkeep(linkUpkeepID); + } + + function test_EmitEvent_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectEmit(); + emit UpkeepPaused(linkUpkeepID); + registry.pauseUpkeep(linkUpkeepID); + } +} + +contract UnpauseUpkeep is SetUp { + event UpkeepUnpaused(uint256 indexed id); + + function test_RevertsWhen_InvalidUpkeepId() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.unpauseUpkeep(linkUpkeepID + 1); + } + + function test_RevertsWhen_UpkeepIsNotPaused() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyPausedUpkeep.selector); + registry.unpauseUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_UpkeepAlreadyCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + registry.pauseUpkeep(linkUpkeepID); + + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.unpauseUpkeep(linkUpkeepID); + } + + function test_RevertsWhen_NotCalledByUpkeepAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + registry.pauseUpkeep(linkUpkeepID); + + vm.startPrank(STRANGER); + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.unpauseUpkeep(linkUpkeepID); + } + + function test_UnpauseUpkeep_CalledByUpkeepAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + registry.pauseUpkeep(linkUpkeepID); + + uint256[] memory ids1 = registry.getActiveUpkeepIDs(0, 0); + + vm.expectEmit(); + emit UpkeepUnpaused(linkUpkeepID); + registry.unpauseUpkeep(linkUpkeepID); + + uint256[] memory ids2 = registry.getActiveUpkeepIDs(0, 0); + assertEq(ids1.length + 1, ids2.length); + } +} + +contract SetUpkeepCheckData is SetUp { + event UpkeepCheckDataSet(uint256 indexed id, bytes newCheckData); + + function test_RevertsWhen_InvalidUpkeepId() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepCheckData(linkUpkeepID + 1, hex"1234"); + } + + function test_RevertsWhen_UpkeepAlreadyCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.setUpkeepCheckData(linkUpkeepID, hex"1234"); + } + + function test_RevertsWhen_NewCheckDataTooLarge() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.CheckDataExceedsLimit.selector); + registry.setUpkeepCheckData(linkUpkeepID, new bytes(10_000)); + } + + function test_RevertsWhen_NotCalledByAdmin() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepCheckData(linkUpkeepID, hex"1234"); + } + + function test_UpdateOffchainConfig_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectEmit(); + emit UpkeepCheckDataSet(linkUpkeepID, hex"1234"); + registry.setUpkeepCheckData(linkUpkeepID, hex"1234"); + + assertEq(registry.getUpkeep(linkUpkeepID).checkData, hex"1234"); + } + + function test_UpdateOffchainConfigOnPausedUpkeep_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + + registry.pauseUpkeep(linkUpkeepID); + + vm.expectEmit(); + emit UpkeepCheckDataSet(linkUpkeepID, hex"1234"); + registry.setUpkeepCheckData(linkUpkeepID, hex"1234"); + + assertTrue(registry.getUpkeep(linkUpkeepID).paused); + assertEq(registry.getUpkeep(linkUpkeepID).checkData, hex"1234"); + } +} + +contract SetUpkeepGasLimit is SetUp { + event UpkeepGasLimitSet(uint256 indexed id, uint96 gasLimit); + + function test_RevertsWhen_InvalidUpkeepId() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepGasLimit(linkUpkeepID + 1, 1230000); + } + + function test_RevertsWhen_UpkeepAlreadyCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.setUpkeepGasLimit(linkUpkeepID, 1230000); + } + + function test_RevertsWhen_NewGasLimitOutOfRange() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.GasLimitOutsideRange.selector); + registry.setUpkeepGasLimit(linkUpkeepID, 300); + + vm.expectRevert(Registry.GasLimitOutsideRange.selector); + registry.setUpkeepGasLimit(linkUpkeepID, 3000000000); + } + + function test_RevertsWhen_NotCalledByAdmin() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepGasLimit(linkUpkeepID, 1230000); + } + + function test_UpdateGasLimit_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectEmit(); + emit UpkeepGasLimitSet(linkUpkeepID, 1230000); + registry.setUpkeepGasLimit(linkUpkeepID, 1230000); + + assertEq(registry.getUpkeep(linkUpkeepID).performGas, 1230000); + } +} + +contract SetUpkeepOffchainConfig is SetUp { + event UpkeepOffchainConfigSet(uint256 indexed id, bytes offchainConfig); + + function test_RevertsWhen_InvalidUpkeepId() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepOffchainConfig(linkUpkeepID + 1, hex"1233"); + } + + function test_RevertsWhen_UpkeepAlreadyCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.setUpkeepOffchainConfig(linkUpkeepID, hex"1234"); + } + + function test_RevertsWhen_NotCalledByAdmin() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepOffchainConfig(linkUpkeepID, hex"1234"); + } + + function test_UpdateOffchainConfig_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectEmit(); + emit UpkeepOffchainConfigSet(linkUpkeepID, hex"1234"); + registry.setUpkeepOffchainConfig(linkUpkeepID, hex"1234"); + + assertEq(registry.getUpkeep(linkUpkeepID).offchainConfig, hex"1234"); + } +} + +contract SetUpkeepTriggerConfig is SetUp { + event UpkeepTriggerConfigSet(uint256 indexed id, bytes triggerConfig); + + function test_RevertsWhen_InvalidUpkeepId() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepTriggerConfig(linkUpkeepID + 1, hex"1233"); + } + + function test_RevertsWhen_UpkeepAlreadyCanceled() external { + vm.startPrank(UPKEEP_ADMIN); + registry.cancelUpkeep(linkUpkeepID); + + vm.expectRevert(Registry.UpkeepCancelled.selector); + registry.setUpkeepTriggerConfig(linkUpkeepID, hex"1234"); + } + + function test_RevertsWhen_NotCalledByAdmin() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByAdmin.selector); + registry.setUpkeepTriggerConfig(linkUpkeepID, hex"1234"); + } + + function test_UpdateTriggerConfig_CalledByAdmin() external { + vm.startPrank(UPKEEP_ADMIN); + + vm.expectEmit(); + emit UpkeepTriggerConfigSet(linkUpkeepID, hex"1234"); + registry.setUpkeepTriggerConfig(linkUpkeepID, hex"1234"); + + assertEq(registry.getUpkeepTriggerConfig(linkUpkeepID), hex"1234"); + } +} + +contract TransferPayeeship is SetUp { + event PayeeshipTransferRequested(address indexed transmitter, address indexed from, address indexed to); + + function test_RevertsWhen_NotCalledByPayee() external { + vm.startPrank(STRANGER); + + vm.expectRevert(Registry.OnlyCallableByPayee.selector); + registry.transferPayeeship(TRANSMITTERS[0], randomAddress()); + } + + function test_RevertsWhen_TransferToSelf() external { + registry.setPayees(PAYEES); + vm.startPrank(PAYEES[0]); + + vm.expectRevert(Registry.ValueNotChanged.selector); + registry.transferPayeeship(TRANSMITTERS[0], PAYEES[0]); + } + + function test_Transfer_DoesNotChangePayee() external { + registry.setPayees(PAYEES); + + vm.startPrank(PAYEES[0]); + + registry.transferPayeeship(TRANSMITTERS[0], randomAddress()); + + (, , , , address payee) = registry.getTransmitterInfo(TRANSMITTERS[0]); + assertEq(PAYEES[0], payee); + } + + function test_EmitEvent_CalledByPayee() external { + registry.setPayees(PAYEES); + + vm.startPrank(PAYEES[0]); + address newPayee = randomAddress(); + + vm.expectEmit(); + emit PayeeshipTransferRequested(TRANSMITTERS[0], PAYEES[0], newPayee); + registry.transferPayeeship(TRANSMITTERS[0], newPayee); + + // transferring to the same propose payee won't yield another event + vm.recordLogs(); + registry.transferPayeeship(TRANSMITTERS[0], newPayee); + Vm.Log[] memory entries = vm.getRecordedLogs(); + assertEq(0, entries.length); + } +} + +contract AcceptPayeeship is SetUp { + event PayeeshipTransferred(address indexed transmitter, address indexed from, address indexed to); + + function test_RevertsWhen_NotCalledByProposedPayee() external { + registry.setPayees(PAYEES); + + vm.startPrank(PAYEES[0]); + address newPayee = randomAddress(); + registry.transferPayeeship(TRANSMITTERS[0], newPayee); + + vm.startPrank(STRANGER); + vm.expectRevert(Registry.OnlyCallableByProposedPayee.selector); + registry.acceptPayeeship(TRANSMITTERS[0]); + } + + function test_PayeeChanged() external { + registry.setPayees(PAYEES); + + vm.startPrank(PAYEES[0]); + address newPayee = randomAddress(); + registry.transferPayeeship(TRANSMITTERS[0], newPayee); + + vm.startPrank(newPayee); + vm.expectEmit(); + emit PayeeshipTransferred(TRANSMITTERS[0], PAYEES[0], newPayee); + registry.acceptPayeeship(TRANSMITTERS[0]); + + (, , , , address payee) = registry.getTransmitterInfo(TRANSMITTERS[0]); + assertEq(newPayee, payee); + } +} + +contract SetPayees is SetUp { + event PayeesUpdated(address[] transmitters, address[] payees); + + function test_RevertsWhen_NotCalledByOwner() external { + vm.startPrank(STRANGER); + + vm.expectRevert(bytes("Only callable by owner")); + registry.setPayees(NEW_PAYEES); + } + + function test_RevertsWhen_PayeesLengthError() external { + vm.startPrank(registry.owner()); + + address[] memory payees = new address[](5); + vm.expectRevert(Registry.ParameterLengthError.selector); + registry.setPayees(payees); + } + + function test_RevertsWhen_InvalidPayee() external { + vm.startPrank(registry.owner()); + + NEW_PAYEES[0] = address(0); + vm.expectRevert(Registry.InvalidPayee.selector); + registry.setPayees(NEW_PAYEES); + } + + function test_SetPayees_WhenExistingPayeesAreEmpty() external { + (registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.ON_CHAIN); + + for (uint256 i = 0; i < TRANSMITTERS.length; i++) { + (, , , , address payee) = registry.getTransmitterInfo(TRANSMITTERS[i]); + assertEq(address(0), payee); + } + + vm.startPrank(registry.owner()); + + vm.expectEmit(); + emit PayeesUpdated(TRANSMITTERS, PAYEES); + registry.setPayees(PAYEES); + for (uint256 i = 0; i < TRANSMITTERS.length; i++) { + (bool active, , , , address payee) = registry.getTransmitterInfo(TRANSMITTERS[i]); + assertTrue(active); + assertEq(PAYEES[i], payee); + } + } + + function test_DotNotSetPayeesToIgnoredAddress() external { + address IGNORE_ADDRESS = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF; + (registry, ) = deployAndConfigureZKSyncRegistryAndRegistrar(AutoBase.PayoutMode.ON_CHAIN); + PAYEES[0] = IGNORE_ADDRESS; + + registry.setPayees(PAYEES); + (bool active, , , , address payee) = registry.getTransmitterInfo(TRANSMITTERS[0]); + assertTrue(active); + assertEq(address(0), payee); + + (active, , , , payee) = registry.getTransmitterInfo(TRANSMITTERS[1]); + assertTrue(active); + assertEq(PAYEES[1], payee); + } +} + +contract GetActiveUpkeepIDs is SetUp { + function test_RevertsWhen_IndexOutOfRange() external { + vm.expectRevert(Registry.IndexOutOfRange.selector); + registry.getActiveUpkeepIDs(5, 0); + + vm.expectRevert(Registry.IndexOutOfRange.selector); + registry.getActiveUpkeepIDs(6, 0); + } + + function test_ReturnsAllUpkeeps_WhenMaxCountIsZero() external { + uint256[] memory uids = registry.getActiveUpkeepIDs(0, 0); + assertEq(5, uids.length); + + uids = registry.getActiveUpkeepIDs(2, 0); + assertEq(3, uids.length); + } + + function test_ReturnsAllRemainingUpkeeps_WhenMaxCountIsTooLarge() external { + uint256[] memory uids = registry.getActiveUpkeepIDs(2, 20); + assertEq(3, uids.length); + } + + function test_ReturnsUpkeeps_BoundByMaxCount() external { + uint256[] memory uids = registry.getActiveUpkeepIDs(1, 2); + assertEq(2, uids.length); + assertEq(uids[0], linkUpkeepID2); + assertEq(uids[1], usdUpkeepID18); + } +} diff --git a/contracts/src/v0.8/automation/testhelpers/UpkeepCounterNew.sol b/contracts/src/v0.8/automation/testhelpers/UpkeepCounterNew.sol new file mode 100644 index 0000000000..76b3877689 --- /dev/null +++ b/contracts/src/v0.8/automation/testhelpers/UpkeepCounterNew.sol @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +contract UpkeepCounterNew { + event PerformingUpkeep( + address indexed from, + uint256 initialTimestamp, + uint256 lastTimestamp, + uint256 previousBlock, + uint256 counter + ); + error InvalidCaller(address caller, address forwarder); + + uint256 public testRange; + uint256 public interval; + uint256 public lastTimestamp; + uint256 public previousPerformBlock; + uint256 public initialTimestamp; + uint256 public counter; + bool public useMoreCheckGas; + bool public useMorePerformGas; + bool public useMorePerformData; + uint256 public checkGasToBurn; + uint256 public performGasToBurn; + bytes public data; + bytes public dataCopy; + bool public trickSimulation = false; + address public forwarder; + + constructor() { + testRange = 1000000; + interval = 40; + previousPerformBlock = 0; + lastTimestamp = block.timestamp; + initialTimestamp = 0; + counter = 0; + useMoreCheckGas = false; + useMorePerformData = false; + useMorePerformGas = false; + checkGasToBurn = 9700000; + performGasToBurn = 7700000; + } + + function setPerformGasToBurn(uint256 _performGasToBurn) external { + performGasToBurn = _performGasToBurn; + } + + function setCheckGasToBurn(uint256 _checkGasToBurn) external { + checkGasToBurn = _checkGasToBurn; + } + + function setUseMoreCheckGas(bool _useMoreCheckGas) external { + useMoreCheckGas = _useMoreCheckGas; + } + + function setUseMorePerformGas(bool _useMorePerformGas) external { + useMorePerformGas = _useMorePerformGas; + } + + function setUseMorePerformData(bool _useMorePerformData) external { + useMorePerformData = _useMorePerformData; + } + + function setData(bytes calldata _data) external { + data = _data; + } + + function checkUpkeep(bytes calldata) external view returns (bool, bytes memory) { + if (useMoreCheckGas) { + uint256 startGas = gasleft(); + while (startGas - gasleft() < checkGasToBurn) {} // burn gas + } + + if (useMorePerformData) { + return (eligible(), data); + } + return (eligible(), ""); + } + + function setTrickSimulation(bool _trickSimulation) external { + trickSimulation = _trickSimulation; + } + + function performUpkeep(bytes calldata performData) external { + if (trickSimulation && tx.origin == address(0)) { + return; + } + + if (msg.sender != forwarder) { + revert InvalidCaller(msg.sender, forwarder); + } + + if (useMorePerformGas) { + uint256 startGas = gasleft(); + while (startGas - gasleft() < performGasToBurn) {} // burn gas + } + + if (initialTimestamp == 0) { + initialTimestamp = block.timestamp; + } + lastTimestamp = block.timestamp; + counter = counter + 1; + dataCopy = performData; + emit PerformingUpkeep(tx.origin, initialTimestamp, lastTimestamp, previousPerformBlock, counter); + previousPerformBlock = lastTimestamp; + } + + function eligible() public view returns (bool) { + if (initialTimestamp == 0) { + return true; + } + + return (block.timestamp - initialTimestamp) < testRange && (block.timestamp - lastTimestamp) >= interval; + } + + function setSpread(uint256 _testRange, uint256 _interval) external { + testRange = _testRange; + interval = _interval; + initialTimestamp = 0; + counter = 0; + } + + function setForwarder(address _forwarder) external { + forwarder = _forwarder; + } +} diff --git a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol index 00858085e3..67a9a56b3d 100644 --- a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol +++ b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol @@ -72,7 +72,6 @@ contract ZKSyncAutomationRegistry2_3 is ZKSyncAutomationRegistryBase2_3, OCR2Abs uint16 numUpkeepsPassedChecks; uint96 totalReimbursement; uint96 totalPremium; - uint256 totalCalldataWeight; } // ================================================================ @@ -89,7 +88,6 @@ contract ZKSyncAutomationRegistry2_3 is ZKSyncAutomationRegistryBase2_3, OCR2Abs bytes32[] calldata ss, bytes32 rawVs ) external override { - uint256 gasOverhead = gasleft(); // use this msg.data length check to ensure no extra data is included in the call // 4 is first 4 bytes of the keccak-256 hash of the function signature. ss.length == rs.length so use one of them // 4 + (32 * 3) + (rawReport.length + 32 + 32) + (32 * rs.length + 32 + 32) + (32 * ss.length + 32 + 32) + 32 @@ -110,7 +108,7 @@ contract ZKSyncAutomationRegistry2_3 is ZKSyncAutomationRegistryBase2_3, OCR2Abs uint40 epochAndRound = uint40(uint256(reportContext[1])); uint32 epoch = uint32(epochAndRound >> 8); - _handleReport(hotVars, report, gasOverhead); + _handleReport(hotVars, report); if (epoch > hotVars.latestEpoch) { s_hotVars.latestEpoch = epoch; @@ -121,22 +119,20 @@ contract ZKSyncAutomationRegistry2_3 is ZKSyncAutomationRegistryBase2_3, OCR2Abs * @notice handles the report by performing the upkeeps and updating the state * @param hotVars the hot variables of the registry * @param report the report to be handled (already verified and decoded) - * @param gasOverhead the running tally of gas overhead to be split across the upkeeps * @dev had to split this function from transmit() to avoid stack too deep errors * @dev all other internal / private functions are generally defined in the Base contract * we leave this here because it is essentially a continuation of the transmit() function, */ - function _handleReport(HotVars memory hotVars, Report memory report, uint256 gasOverhead) private { + function _handleReport(HotVars memory hotVars, Report memory report) private { UpkeepTransmitInfo[] memory upkeepTransmitInfo = new UpkeepTransmitInfo[](report.upkeepIds.length); TransmitVars memory transmitVars = TransmitVars({ numUpkeepsPassedChecks: 0, - totalCalldataWeight: 0, totalReimbursement: 0, totalPremium: 0 }); uint256 blocknumber = hotVars.chainModule.blockNumber(); - uint256 l1Fee = hotVars.chainModule.getCurrentL1Fee(msg.data.length); // this will be updated + uint256 gasOverhead; for (uint256 i = 0; i < report.upkeepIds.length; i++) { upkeepTransmitInfo[i].upkeep = s_upkeep[report.upkeepIds[i]]; @@ -163,28 +159,25 @@ contract ZKSyncAutomationRegistry2_3 is ZKSyncAutomationRegistryBase2_3, OCR2Abs report.performDatas[i] ); - // To split L1 fee across the upkeeps, assign a weight to this upkeep based on the length - // of the perform data and calldata overhead - upkeepTransmitInfo[i].calldataWeight = - report.performDatas[i].length + - TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD + - (TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD * (hotVars.f + 1)); - transmitVars.totalCalldataWeight += upkeepTransmitInfo[i].calldataWeight; - - // Deduct the gasUsed by upkeep from the overhead tally - upkeeps pay for their own gas individually - gasOverhead -= upkeepTransmitInfo[i].gasUsed; - // Store last perform block number / deduping key for upkeep _updateTriggerMarker(report.upkeepIds[i], blocknumber, upkeepTransmitInfo[i]); + + if (upkeepTransmitInfo[i].triggerType == Trigger.CONDITION) { + gasOverhead += REGISTRY_CONDITIONAL_OVERHEAD; + } else { + gasOverhead += REGISTRY_LOG_OVERHEAD; + } } // No upkeeps to be performed in this report if (transmitVars.numUpkeepsPassedChecks == 0) { return; } - // This is the overall gas overhead that will be split across performed upkeeps - // Take upper bound of 16 gas per callData bytes - gasOverhead = (gasOverhead - gasleft()) + (16 * msg.data.length) + ACCOUNTING_FIXED_GAS_OVERHEAD; + gasOverhead += + 16 * + msg.data.length + + ACCOUNTING_FIXED_GAS_OVERHEAD + + (REGISTRY_PER_SIGNER_GAS_OVERHEAD * (hotVars.f + 1)); gasOverhead = gasOverhead / transmitVars.numUpkeepsPassedChecks + ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD; { @@ -200,7 +193,7 @@ contract ZKSyncAutomationRegistry2_3 is ZKSyncAutomationRegistryBase2_3, OCR2Abs PaymentParams({ gasLimit: upkeepTransmitInfo[i].gasUsed, gasOverhead: gasOverhead, - l1CostWei: (l1Fee * upkeepTransmitInfo[i].calldataWeight) / transmitVars.totalCalldataWeight, + l1CostWei: 0, fastGasWei: report.fastGasWei, linkUSD: report.linkUSD, nativeUSD: nativeUSD, diff --git a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryBase2_3.sol b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryBase2_3.sol index 524ecacc82..41097af7f2 100644 --- a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryBase2_3.sol +++ b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryBase2_3.sol @@ -34,8 +34,6 @@ abstract contract ZKSyncAutomationRegistryBase2_3 is ConfirmedOwner { bytes4 internal constant CHECK_LOG_SELECTOR = ILogAutomation.checkLog.selector; uint256 internal constant PERFORM_GAS_MIN = 2_300; uint256 internal constant CANCELLATION_DELAY = 50; - uint256 internal constant PERFORM_GAS_CUSHION = 5_000; - uint256 internal constant PPB_BASE = 1_000_000_000; uint32 internal constant UINT32_MAX = type(uint32).max; // The first byte of the mask can be 0, because we only ever have 31 oracles uint256 internal constant ORACLE_MASK = 0x0001010101010101010101010101010101010101010101010101010101010101; @@ -47,20 +45,13 @@ abstract contract ZKSyncAutomationRegistryBase2_3 is ConfirmedOwner { uint256 internal constant REGISTRY_CONDITIONAL_OVERHEAD = 98_200; // Fixed gas overhead for conditional upkeeps uint256 internal constant REGISTRY_LOG_OVERHEAD = 122_500; // Fixed gas overhead for log upkeeps uint256 internal constant REGISTRY_PER_SIGNER_GAS_OVERHEAD = 5_600; // Value scales with f - uint256 internal constant REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD = 24; // Per perform data byte overhead - - // The overhead (in bytes) in addition to perform data for upkeep sent in calldata - // This includes overhead for all struct encoding as well as report signatures - // There is a fixed component and a per signer component. This is calculated exactly by doing abi encoding - uint256 internal constant TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD = 932; - uint256 internal constant TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD = 64; // Next block of constants are used in actual payment calculation. We calculate the exact gas used within the // tx itself, but since payment processing itself takes gas, and it needs the overhead as input, we use fixed constants // to account for gas used in payment processing. These values are calibrated using hardhat tests which simulates various cases and verifies that // the variables result in accurate estimation - uint256 internal constant ACCOUNTING_FIXED_GAS_OVERHEAD = 51_200; // Fixed overhead per tx - uint256 internal constant ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD = 14_200; // Overhead per upkeep performed in batch + uint256 internal constant ACCOUNTING_FIXED_GAS_OVERHEAD = 51_000; // Fixed overhead per tx + uint256 internal constant ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD = 20_000; // Overhead per upkeep performed in batch LinkTokenInterface internal immutable i_link; AggregatorV3Interface internal immutable i_linkUSDFeed; @@ -313,7 +304,6 @@ abstract contract ZKSyncAutomationRegistryBase2_3 is ConfirmedOwner { * @member performSuccess whether the perform was successful * @member triggerType the type of trigger * @member gasUsed gasUsed by this upkeep in perform - * @member calldataWeight weight assigned to this upkeep for its contribution to calldata. It is used to split L1 fee * @member dedupID unique ID used to dedup an upkeep/trigger combo */ struct UpkeepTransmitInfo { @@ -322,7 +312,6 @@ abstract contract ZKSyncAutomationRegistryBase2_3 is ConfirmedOwner { bool performSuccess; Trigger triggerType; uint256 gasUsed; - uint256 calldataWeight; bytes32 dedupID; } @@ -739,7 +728,6 @@ abstract contract ZKSyncAutomationRegistryBase2_3 is ConfirmedOwner { uint256 nativeUSD, IERC20 billingToken ) internal view returns (uint96) { - uint256 maxL1Fee; uint256 maxGasOverhead; { @@ -750,15 +738,8 @@ abstract contract ZKSyncAutomationRegistryBase2_3 is ConfirmedOwner { } else { revert InvalidTriggerType(); } - uint256 maxCalldataSize = s_storage.maxPerformDataSize + - TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD + - (TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD * (hotVars.f + 1)); - (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead) = s_hotVars.chainModule.getGasOverhead(); - maxGasOverhead += - (REGISTRY_PER_SIGNER_GAS_OVERHEAD * (hotVars.f + 1)) + - ((REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD + chainModulePerByteOverhead) * maxCalldataSize) + - chainModuleFixedOverhead; - maxL1Fee = hotVars.gasCeilingMultiplier * hotVars.chainModule.getMaxL1Fee(maxCalldataSize); + (uint256 chainModuleFixedOverhead, ) = s_hotVars.chainModule.getGasOverhead(); + maxGasOverhead += (REGISTRY_PER_SIGNER_GAS_OVERHEAD * (hotVars.f + 1)) + chainModuleFixedOverhead; } BillingTokenPaymentParams memory paymentParams = _getBillingTokenPaymentParams(hotVars, billingToken); @@ -774,7 +755,7 @@ abstract contract ZKSyncAutomationRegistryBase2_3 is ConfirmedOwner { PaymentParams({ gasLimit: performGas, gasOverhead: maxGasOverhead, - l1CostWei: maxL1Fee, + l1CostWei: 0, fastGasWei: fastGasWei, linkUSD: linkUSD, nativeUSD: nativeUSD, diff --git a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicC2_3.sol b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicC2_3.sol index 61d0eecfba..3b4b023c7a 100644 --- a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicC2_3.sol +++ b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistryLogicC2_3.sol @@ -222,22 +222,10 @@ contract ZKSyncAutomationRegistryLogicC2_3 is ZKSyncAutomationRegistryBase2_3 { return REGISTRY_LOG_OVERHEAD; } - function getPerPerformByteGasOverhead() external pure returns (uint256) { - return REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD; - } - function getPerSignerGasOverhead() external pure returns (uint256) { return REGISTRY_PER_SIGNER_GAS_OVERHEAD; } - function getTransmitCalldataFixedBytesOverhead() external pure returns (uint256) { - return TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD; - } - - function getTransmitCalldataPerSignerBytesOverhead() external pure returns (uint256) { - return TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD; - } - function getCancellationDelay() external pure returns (uint256) { return CANCELLATION_DELAY; } diff --git a/contracts/src/v0.8/tests/MockGasBoundCaller.sol b/contracts/src/v0.8/tests/MockGasBoundCaller.sol new file mode 100644 index 0000000000..3184f9dba3 --- /dev/null +++ b/contracts/src/v0.8/tests/MockGasBoundCaller.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +contract MockGasBoundCaller { + error TransactionFailed(address target); + + function gasBoundCall(address target, uint256 gasAmount, bytes memory data) external payable { + bool success; + assembly { + success := call(gasAmount, target, 0, add(data, 0x20), mload(data), 0, 0) + } + + // gas bound caller will propagate the revert + if (!success) { + revert TransactionFailed(target); + } + + uint256 pubdataGas = 500000; + bytes memory returnData = abi.encode(address(0), pubdataGas); + + uint256 paddedReturndataLen = returnData.length + 96; + if (paddedReturndataLen % 32 != 0) { + paddedReturndataLen += 32 - (paddedReturndataLen % 32); + } + + assembly { + mstore(sub(returnData, 0x40), 0x40) + mstore(sub(returnData, 0x20), pubdataGas) + return(sub(returnData, 0x40), paddedReturndataLen) + } + } +} diff --git a/contracts/src/v0.8/tests/MockZKSyncSystemContext.sol b/contracts/src/v0.8/tests/MockZKSyncSystemContext.sol new file mode 100644 index 0000000000..265d4b678a --- /dev/null +++ b/contracts/src/v0.8/tests/MockZKSyncSystemContext.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +contract MockZKSyncSystemContext { + function gasPrice() external pure returns (uint256) { + return 250000000; // 0.25 gwei + } + + function gasPerPubdataByte() external pure returns (uint256) { + return 500; + } + + function getCurrentPubdataSpent() external pure returns (uint256 currentPubdataSpent) { + return 1000; + } +} diff --git a/contracts/test/v0.8/automation/ZKSyncAutomationRegistry2_3.test.ts b/contracts/test/v0.8/automation/ZKSyncAutomationRegistry2_3.test.ts new file mode 100644 index 0000000000..95210cf644 --- /dev/null +++ b/contracts/test/v0.8/automation/ZKSyncAutomationRegistry2_3.test.ts @@ -0,0 +1,4403 @@ +import { ethers } from 'hardhat' +import { loadFixture } from '@nomicfoundation/hardhat-network-helpers' +import { assert, expect } from 'chai' +import { + BigNumber, + BigNumberish, + BytesLike, + Contract, + ContractFactory, + ContractReceipt, + ContractTransaction, + Signer, + Wallet, +} from 'ethers' +import { evmRevert, evmRevertCustomError } from '../../test-helpers/matchers' +import { getUsers, Personas } from '../../test-helpers/setup' +import { randomAddress, toWei } from '../../test-helpers/helpers' +import { StreamsLookupUpkeep__factory as StreamsLookupUpkeepFactory } from '../../../typechain/factories/StreamsLookupUpkeep__factory' +import { MockV3Aggregator__factory as MockV3AggregatorFactory } from '../../../typechain/factories/MockV3Aggregator__factory' +import { UpkeepMock__factory as UpkeepMockFactory } from '../../../typechain/factories/UpkeepMock__factory' +import { UpkeepAutoFunder__factory as UpkeepAutoFunderFactory } from '../../../typechain/factories/UpkeepAutoFunder__factory' +import { MockZKSyncSystemContext__factory as MockZKSyncSystemContextFactory } from '../../../typechain/factories/MockZKSyncSystemContext__factory' +import { ChainModuleBase__factory as ChainModuleBaseFactory } from '../../../typechain/factories/ChainModuleBase__factory' +import { MockGasBoundCaller__factory as MockGasBoundCallerFactory } from '../../../typechain/factories/MockGasBoundCaller__factory' +import { ILogAutomation__factory as ILogAutomationactory } from '../../../typechain/factories/ILogAutomation__factory' +import { AutomationCompatibleUtils } from '../../../typechain/AutomationCompatibleUtils' +import { StreamsLookupUpkeep } from '../../../typechain/StreamsLookupUpkeep' +import { MockV3Aggregator } from '../../../typechain/MockV3Aggregator' +import { MockGasBoundCaller } from '../../../typechain/MockGasBoundCaller' +import { UpkeepMock } from '../../../typechain/UpkeepMock' +import { ChainModuleBase } from '../../../typechain/ChainModuleBase' +import { UpkeepTranscoder } from '../../../typechain/UpkeepTranscoder' +import { MockZKSyncSystemContext } from '../../../typechain/MockZKSyncSystemContext' +import { IChainModule, UpkeepAutoFunder } from '../../../typechain' +import { + CancelledUpkeepReportEvent, + IAutomationRegistryMaster2_3 as IAutomationRegistry, + ReorgedUpkeepReportEvent, + StaleUpkeepReportEvent, + UpkeepPerformedEvent, +} from '../../../typechain/IAutomationRegistryMaster2_3' +import { + deployMockContract, + MockContract, +} from '@ethereum-waffle/mock-contract' +import { deployZKSyncRegistry23 } from './helpers' +import { AutomationUtils2_3 } from '../../../typechain/AutomationUtils2_3' + +const describeMaybe = process.env.SKIP_SLOW ? describe.skip : describe +const itMaybe = process.env.SKIP_SLOW ? it.skip : it + +// copied from AutomationRegistryInterface2_3.sol +enum UpkeepFailureReason { + NONE, + UPKEEP_CANCELLED, + UPKEEP_PAUSED, + TARGET_CHECK_REVERTED, + UPKEEP_NOT_NEEDED, + PERFORM_DATA_EXCEEDS_LIMIT, + INSUFFICIENT_BALANCE, + CHECK_CALLBACK_REVERTED, + REVERT_DATA_EXCEEDS_LIMIT, + REGISTRY_PAUSED, +} + +// copied from AutomationRegistryBase2_3.sol +enum Trigger { + CONDITION, + LOG, +} + +// un-exported types that must be extracted from the utils contract +type Report = Parameters[0] +type LogTrigger = Parameters[0] +type ConditionalTrigger = Parameters< + AutomationCompatibleUtils['_conditionalTrigger'] +>[0] +type Log = Parameters[0] +type OnChainConfig = Parameters[3] + +// ----------------------------------------------------------------------------------------------- + +// These values should match the constants declared in registry +let registryConditionalOverhead: BigNumber +let registryLogOverhead: BigNumber +let registryPerSignerGasOverhead: BigNumber +// let registryPerPerformByteGasOverhead: BigNumber +// let registryTransmitCalldataFixedBytesOverhead: BigNumber +// let registryTransmitCalldataPerSignerBytesOverhead: BigNumber +let cancellationDelay: number + +// This is the margin for gas that we test for. Gas charged should always be greater +// than total gas used in tx but should not increase beyond this margin +// const gasCalculationMargin = BigNumber.from(50_000) +// This is the margin for gas overhead estimation in checkUpkeep. The estimated gas +// overhead should be larger than actual gas overhead but should not increase beyond this margin +// const gasEstimationMargin = BigNumber.from(50_000) + +// 1 Link = 0.005 Eth +const linkUSD = BigNumber.from('2000000000') // 1 LINK = $20 +const nativeUSD = BigNumber.from('400000000000') // 1 ETH = $4000 +const gasWei = BigNumber.from(1000000000) // 1 gwei +// ----------------------------------------------------------------------------------------------- +// test-wide configs for upkeeps +const performGas = BigNumber.from('1000000') +const paymentPremiumBase = BigNumber.from('1000000000') +const paymentPremiumPPB = BigNumber.from('250000000') +const flatFeeMilliCents = BigNumber.from(0) + +const randomBytes = '0x1234abcd' +const emptyBytes = '0x' +const emptyBytes32 = + '0x0000000000000000000000000000000000000000000000000000000000000000' + +const pubdataGas = BigNumber.from(500000) +const transmitGasOverhead = 1_040_000 +const checkGasOverhead = 600_000 + +const stalenessSeconds = BigNumber.from(43820) +const gasCeilingMultiplier = BigNumber.from(2) +const checkGasLimit = BigNumber.from(10000000) +const fallbackGasPrice = gasWei.mul(BigNumber.from('2')) +const fallbackLinkPrice = linkUSD.div(BigNumber.from('2')) +const fallbackNativePrice = nativeUSD.div(BigNumber.from('2')) +const maxCheckDataSize = BigNumber.from(1000) +const maxPerformDataSize = BigNumber.from(1000) +const maxRevertDataSize = BigNumber.from(1000) +const maxPerformGas = BigNumber.from(5000000) +const minUpkeepSpend = BigNumber.from(0) +const f = 1 +const offchainVersion = 1 +const offchainBytes = '0x' +const zeroAddress = ethers.constants.AddressZero +const wrappedNativeTokenAddress = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' +const epochAndRound5_1 = + '0x0000000000000000000000000000000000000000000000000000000000000501' + +let logTriggerConfig: string + +// ----------------------------------------------------------------------------------------------- + +// Smart contract factories +let linkTokenFactory: ContractFactory +let mockV3AggregatorFactory: MockV3AggregatorFactory +let mockGasBoundCallerFactory: MockGasBoundCallerFactory +let upkeepMockFactory: UpkeepMockFactory +let upkeepAutoFunderFactory: UpkeepAutoFunderFactory +let moduleBaseFactory: ChainModuleBaseFactory +let mockZKSyncSystemContextFactory: MockZKSyncSystemContextFactory +let streamsLookupUpkeepFactory: StreamsLookupUpkeepFactory +let personas: Personas + +// contracts +let linkToken: Contract +let linkUSDFeed: MockV3Aggregator +let nativeUSDFeed: MockV3Aggregator +let gasPriceFeed: MockV3Aggregator +let registry: IAutomationRegistry // default registry, used for most tests +let mgRegistry: IAutomationRegistry // "migrate registry" used in migration tests +let mock: UpkeepMock +let autoFunderUpkeep: UpkeepAutoFunder +let ltUpkeep: MockContract +let transcoder: UpkeepTranscoder +let moduleBase: ChainModuleBase +let mockGasBoundCaller: MockGasBoundCaller +let mockZKSyncSystemContext: MockZKSyncSystemContext +let streamsLookupUpkeep: StreamsLookupUpkeep +let automationUtils: AutomationCompatibleUtils +let automationUtils2_3: AutomationUtils2_3 + +function now() { + return Math.floor(Date.now() / 1000) +} + +async function getUpkeepID(tx: ContractTransaction): Promise { + const receipt = await tx.wait() + for (const event of receipt.events || []) { + if ( + event.args && + event.eventSignature == 'UpkeepRegistered(uint256,uint32,address)' + ) { + return event.args[0] + } + } + throw new Error('could not find upkeep ID in tx event logs') +} + +const getTriggerType = (upkeepId: BigNumber): Trigger => { + const hexBytes = ethers.utils.defaultAbiCoder.encode(['uint256'], [upkeepId]) + const bytes = ethers.utils.arrayify(hexBytes) + for (let idx = 4; idx < 15; idx++) { + if (bytes[idx] != 0) { + return Trigger.CONDITION + } + } + return bytes[15] as Trigger +} + +const encodeBlockTrigger = (conditionalTrigger: ConditionalTrigger) => { + return ( + '0x' + + automationUtils.interface + .encodeFunctionData('_conditionalTrigger', [conditionalTrigger]) + .slice(10) + ) +} + +const encodeLogTrigger = (logTrigger: LogTrigger) => { + return ( + '0x' + + automationUtils.interface + .encodeFunctionData('_logTrigger', [logTrigger]) + .slice(10) + ) +} + +const encodeLog = (log: Log) => { + return ( + '0x' + automationUtils.interface.encodeFunctionData('_log', [log]).slice(10) + ) +} + +const encodeReport = (report: Report) => { + return ( + '0x' + + automationUtils2_3.interface + .encodeFunctionData('_report', [report]) + .slice(10) + ) +} + +type UpkeepData = { + Id: BigNumberish + performGas: BigNumberish + performData: BytesLike + trigger: BytesLike +} + +const makeReport = (upkeeps: UpkeepData[]) => { + const upkeepIds = upkeeps.map((u) => u.Id) + const performGases = upkeeps.map((u) => u.performGas) + const triggers = upkeeps.map((u) => u.trigger) + const performDatas = upkeeps.map((u) => u.performData) + return encodeReport({ + fastGasWei: gasWei, + linkUSD, + upkeepIds, + gasLimits: performGases, + triggers, + performDatas, + }) +} + +const makeLatestBlockReport = async (upkeepsIDs: BigNumberish[]) => { + const latestBlock = await ethers.provider.getBlock('latest') + const upkeeps: UpkeepData[] = [] + for (let i = 0; i < upkeepsIDs.length; i++) { + upkeeps.push({ + Id: upkeepsIDs[i], + performGas, + trigger: encodeBlockTrigger({ + blockNum: latestBlock.number, + blockHash: latestBlock.hash, + }), + performData: '0x', + }) + } + return makeReport(upkeeps) +} + +const signReport = ( + reportContext: string[], + report: any, + signers: Wallet[], +) => { + const reportDigest = ethers.utils.keccak256(report) + const packedArgs = ethers.utils.solidityPack( + ['bytes32', 'bytes32[3]'], + [reportDigest, reportContext], + ) + const packedDigest = ethers.utils.keccak256(packedArgs) + + const signatures = [] + for (const signer of signers) { + signatures.push(signer._signingKey().signDigest(packedDigest)) + } + const vs = signatures.map((i) => '0' + (i.v - 27).toString(16)).join('') + return { + vs: '0x' + vs.padEnd(64, '0'), + rs: signatures.map((i) => i.r), + ss: signatures.map((i) => i.s), + } +} + +const parseUpkeepPerformedLogs = (receipt: ContractReceipt) => { + const parsedLogs = [] + for (const rawLog of receipt.logs) { + try { + const log = registry.interface.parseLog(rawLog) + if ( + log.name == + registry.interface.events[ + 'UpkeepPerformed(uint256,bool,uint96,uint256,uint256,bytes)' + ].name + ) { + parsedLogs.push(log as unknown as UpkeepPerformedEvent) + } + } catch { + continue + } + } + return parsedLogs +} + +const parseReorgedUpkeepReportLogs = (receipt: ContractReceipt) => { + const parsedLogs = [] + for (const rawLog of receipt.logs) { + try { + const log = registry.interface.parseLog(rawLog) + if ( + log.name == + registry.interface.events['ReorgedUpkeepReport(uint256,bytes)'].name + ) { + parsedLogs.push(log as unknown as ReorgedUpkeepReportEvent) + } + } catch { + continue + } + } + return parsedLogs +} + +const parseStaleUpkeepReportLogs = (receipt: ContractReceipt) => { + const parsedLogs = [] + for (const rawLog of receipt.logs) { + try { + const log = registry.interface.parseLog(rawLog) + if ( + log.name == + registry.interface.events['StaleUpkeepReport(uint256,bytes)'].name + ) { + parsedLogs.push(log as unknown as StaleUpkeepReportEvent) + } + } catch { + continue + } + } + return parsedLogs +} + +const parseCancelledUpkeepReportLogs = (receipt: ContractReceipt) => { + const parsedLogs = [] + for (const rawLog of receipt.logs) { + try { + const log = registry.interface.parseLog(rawLog) + if ( + log.name == + registry.interface.events['CancelledUpkeepReport(uint256,bytes)'].name + ) { + parsedLogs.push(log as unknown as CancelledUpkeepReportEvent) + } + } catch { + continue + } + } + return parsedLogs +} + +describe('ZKSyncAutomationRegistry2_3', () => { + let owner: Signer + let keeper1: Signer + let keeper2: Signer + let keeper3: Signer + let keeper4: Signer + let keeper5: Signer + let nonkeeper: Signer + let signer1: Wallet + let signer2: Wallet + let signer3: Wallet + let signer4: Wallet + let signer5: Wallet + let admin: Signer + let payee1: Signer + let payee2: Signer + let payee3: Signer + let payee4: Signer + let payee5: Signer + let financeAdmin: Signer + + let upkeepId: BigNumber // conditional upkeep + let afUpkeepId: BigNumber // auto funding upkeep + let logUpkeepId: BigNumber // log trigger upkeepID + let streamsLookupUpkeepId: BigNumber // streams lookup upkeep + // const numUpkeeps = 4 // see above + let keeperAddresses: string[] + let payees: string[] + let signers: Wallet[] + let signerAddresses: string[] + let config: OnChainConfig + let baseConfig: Parameters + let upkeepManager: string + + before(async () => { + personas = (await getUsers()).personas + + const compatibleUtilsFactory = await ethers.getContractFactory( + 'AutomationCompatibleUtils', + ) + automationUtils = await compatibleUtilsFactory.deploy() + + const utilsFactory = await ethers.getContractFactory('AutomationUtils2_3') + automationUtils2_3 = await utilsFactory.deploy() + + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.8/shared/test/helpers/LinkTokenTestHelper.sol:LinkTokenTestHelper', + ) + // need full path because there are two contracts with name MockV3Aggregator + mockV3AggregatorFactory = (await ethers.getContractFactory( + 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', + )) as unknown as MockV3AggregatorFactory + mockZKSyncSystemContextFactory = await ethers.getContractFactory( + 'MockZKSyncSystemContext', + ) + mockGasBoundCallerFactory = + await ethers.getContractFactory('MockGasBoundCaller') + upkeepMockFactory = await ethers.getContractFactory('UpkeepMock') + upkeepAutoFunderFactory = + await ethers.getContractFactory('UpkeepAutoFunder') + moduleBaseFactory = await ethers.getContractFactory('ChainModuleBase') + streamsLookupUpkeepFactory = await ethers.getContractFactory( + 'StreamsLookupUpkeep', + ) + + owner = personas.Default + keeper1 = personas.Carol + keeper2 = personas.Eddy + keeper3 = personas.Nancy + keeper4 = personas.Norbert + keeper5 = personas.Nick + nonkeeper = personas.Ned + admin = personas.Neil + payee1 = personas.Nelly + payee2 = personas.Norbert + payee3 = personas.Nick + payee4 = personas.Eddy + payee5 = personas.Carol + upkeepManager = await personas.Norbert.getAddress() + financeAdmin = personas.Nick + // signers + signer1 = new ethers.Wallet( + '0x7777777000000000000000000000000000000000000000000000000000000001', + ) + signer2 = new ethers.Wallet( + '0x7777777000000000000000000000000000000000000000000000000000000002', + ) + signer3 = new ethers.Wallet( + '0x7777777000000000000000000000000000000000000000000000000000000003', + ) + signer4 = new ethers.Wallet( + '0x7777777000000000000000000000000000000000000000000000000000000004', + ) + signer5 = new ethers.Wallet( + '0x7777777000000000000000000000000000000000000000000000000000000005', + ) + + keeperAddresses = [ + await keeper1.getAddress(), + await keeper2.getAddress(), + await keeper3.getAddress(), + await keeper4.getAddress(), + await keeper5.getAddress(), + ] + payees = [ + await payee1.getAddress(), + await payee2.getAddress(), + await payee3.getAddress(), + await payee4.getAddress(), + await payee5.getAddress(), + ] + signers = [signer1, signer2, signer3, signer4, signer5] + + // We append 26 random addresses to keepers, payees and signers to get a system of 31 oracles + // This allows f value of 1 - 10 + for (let i = 0; i < 26; i++) { + keeperAddresses.push(randomAddress()) + payees.push(randomAddress()) + signers.push(ethers.Wallet.createRandom()) + } + signerAddresses = [] + for (const signer of signers) { + signerAddresses.push(await signer.getAddress()) + } + + logTriggerConfig = + '0x' + + automationUtils.interface + .encodeFunctionData('_logTriggerConfig', [ + { + contractAddress: randomAddress(), + filterSelector: 0, + topic0: ethers.utils.randomBytes(32), + topic1: ethers.utils.randomBytes(32), + topic2: ethers.utils.randomBytes(32), + topic3: ethers.utils.randomBytes(32), + }, + ]) + .slice(10) + }) + + // This function is similar to registry's _calculatePaymentAmount + // It uses global fastGasWei, linkEth, and assumes isExecution = false (gasFee = fastGasWei*multiplier) + // rest of the parameters are the same + const linkForGas = ( + upkeepGasSpent: BigNumber, + gasOverhead: BigNumber, + gasMultiplier: BigNumber, + premiumPPB: BigNumber, + flatFee: BigNumber, // in millicents + ) => { + const gasSpent = gasOverhead.add(BigNumber.from(upkeepGasSpent)) + const gasPayment = gasWei + .mul(gasMultiplier) + .mul(gasSpent) + .mul(nativeUSD) + .div(linkUSD) + + const premium = gasWei + .mul(gasMultiplier) + .mul(upkeepGasSpent) + .mul(premiumPPB) + .mul(nativeUSD) + .div(paymentPremiumBase) + .add(flatFee.mul(BigNumber.from(10).pow(21))) + .div(linkUSD) + + return { + total: gasPayment.add(premium), + gasPayment, + premium, + } + } + + const verifyMaxPayment = async ( + registry: IAutomationRegistry, + chainModule: IChainModule, + ) => { + type TestCase = { + name: string + multiplier: number + gas: number + premium: number + flatFee: number + } + + const tests: TestCase[] = [ + { + name: 'no fees', + multiplier: 1, + gas: 100000, + premium: 0, + flatFee: 0, + }, + { + name: 'basic fees', + multiplier: 1, + gas: 100000, + premium: 250000000, + flatFee: 1000000, + }, + { + name: 'max fees', + multiplier: 3, + gas: 10000000, + premium: 250000000, + flatFee: 1000000, + }, + ] + + const fPlusOne = BigNumber.from(f + 1) + const chainModuleOverheads = await chainModule.getGasOverhead() + const totalConditionalOverhead = registryConditionalOverhead + .add(registryPerSignerGasOverhead.mul(fPlusOne)) + .add(chainModuleOverheads.chainModuleFixedOverhead) + + const totalLogOverhead = registryLogOverhead + .add(registryPerSignerGasOverhead.mul(fPlusOne)) + .add(chainModuleOverheads.chainModuleFixedOverhead) + + const financeAdminAddress = await financeAdmin.getAddress() + + for (const test of tests) { + await registry.connect(owner).setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + { + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier: test.multiplier, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + fallbackNativePrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: chainModule.address, + reorgProtectionEnabled: true, + financeAdmin: financeAdminAddress, + }, + offchainVersion, + offchainBytes, + [linkToken.address], + [ + { + gasFeePPB: test.premium, + flatFeeMilliCents: test.flatFee, + priceFeed: linkUSDFeed.address, + fallbackPrice: fallbackLinkPrice, + minSpend: minUpkeepSpend, + decimals: 18, + }, + ], + ) + + const conditionalPrice = await registry.getMaxPaymentForGas( + upkeepId, + Trigger.CONDITION, + test.gas, + linkToken.address, + ) + expect(conditionalPrice).to.equal( + linkForGas( + BigNumber.from(test.gas), + totalConditionalOverhead, + BigNumber.from(test.multiplier), + BigNumber.from(test.premium), + BigNumber.from(test.flatFee), + ).total, + ) + + const logPrice = await registry.getMaxPaymentForGas( + upkeepId, + Trigger.LOG, + test.gas, + linkToken.address, + ) + expect(logPrice).to.equal( + linkForGas( + BigNumber.from(test.gas), + totalLogOverhead, + BigNumber.from(test.multiplier), + BigNumber.from(test.premium), + BigNumber.from(test.flatFee), + ).total, + ) + } + } + + const verifyConsistentAccounting = async ( + maxAllowedSpareChange: BigNumber, + ) => { + const expectedLinkBalance = await registry.getReserveAmount( + linkToken.address, + ) + const linkTokenBalance = await linkToken.balanceOf(registry.address) + const upkeepIdBalance = (await registry.getUpkeep(upkeepId)).balance + let totalKeeperBalance = BigNumber.from(0) + for (let i = 0; i < keeperAddresses.length; i++) { + totalKeeperBalance = totalKeeperBalance.add( + (await registry.getTransmitterInfo(keeperAddresses[i])).balance, + ) + } + + const linkAvailableForPayment = await registry.linkAvailableForPayment() + assert.isTrue(expectedLinkBalance.eq(linkTokenBalance)) + assert.isTrue( + upkeepIdBalance + .add(totalKeeperBalance) + .add(linkAvailableForPayment) + .lte(expectedLinkBalance), + ) + assert.isTrue( + expectedLinkBalance + .sub(upkeepIdBalance) + .sub(totalKeeperBalance) + .sub(linkAvailableForPayment) + .lte(maxAllowedSpareChange), + ) + } + + interface GetTransmitTXOptions { + numSigners?: number + startingSignerIndex?: number + gasLimit?: BigNumberish + gasPrice?: BigNumberish + performGas?: BigNumberish + performDatas?: string[] + checkBlockNum?: number + checkBlockHash?: string + logBlockHash?: BytesLike + txHash?: BytesLike + logIndex?: number + timestamp?: number + } + + const getTransmitTx = async ( + registry: IAutomationRegistry, + transmitter: Signer, + upkeepIds: BigNumber[], + overrides: GetTransmitTXOptions = {}, + ) => { + const latestBlock = await ethers.provider.getBlock('latest') + const configDigest = (await registry.getState()).state.latestConfigDigest + const config = { + numSigners: f + 1, + startingSignerIndex: 0, + performDatas: undefined, + performGas, + checkBlockNum: latestBlock.number, + checkBlockHash: latestBlock.hash, + logIndex: 0, + txHash: undefined, // assigned uniquely below + logBlockHash: undefined, // assigned uniquely below + timestamp: now(), + gasLimit: undefined, + gasPrice: undefined, + } + Object.assign(config, overrides) + const upkeeps: UpkeepData[] = [] + for (let i = 0; i < upkeepIds.length; i++) { + let trigger: string + switch (getTriggerType(upkeepIds[i])) { + case Trigger.CONDITION: + trigger = encodeBlockTrigger({ + blockNum: config.checkBlockNum, + blockHash: config.checkBlockHash, + }) + break + case Trigger.LOG: + trigger = encodeLogTrigger({ + logBlockHash: config.logBlockHash || ethers.utils.randomBytes(32), + txHash: config.txHash || ethers.utils.randomBytes(32), + logIndex: config.logIndex, + blockNum: config.checkBlockNum, + blockHash: config.checkBlockHash, + }) + break + } + upkeeps.push({ + Id: upkeepIds[i], + performGas: config.performGas, + trigger, + performData: config.performDatas ? config.performDatas[i] : '0x', + }) + } + + const report = makeReport(upkeeps) + const reportContext = [configDigest, epochAndRound5_1, emptyBytes32] + const sigs = signReport( + reportContext, + report, + signers.slice( + config.startingSignerIndex, + config.startingSignerIndex + config.numSigners, + ), + ) + + type txOverride = { + gasLimit?: BigNumberish | Promise + gasPrice?: BigNumberish | Promise + } + const txOverrides: txOverride = {} + if (config.gasLimit) { + txOverrides.gasLimit = config.gasLimit + } + if (config.gasPrice) { + txOverrides.gasPrice = config.gasPrice + } + + return registry + .connect(transmitter) + .transmit( + [configDigest, epochAndRound5_1, emptyBytes32], + report, + sigs.rs, + sigs.ss, + sigs.vs, + txOverrides, + ) + } + + const getTransmitTxWithReport = async ( + registry: IAutomationRegistry, + transmitter: Signer, + report: BytesLike, + ) => { + const configDigest = (await registry.getState()).state.latestConfigDigest + const reportContext = [configDigest, epochAndRound5_1, emptyBytes32] + const sigs = signReport(reportContext, report, signers.slice(0, f + 1)) + + return registry + .connect(transmitter) + .transmit( + [configDigest, epochAndRound5_1, emptyBytes32], + report, + sigs.rs, + sigs.ss, + sigs.vs, + ) + } + + const setup = async () => { + linkToken = await linkTokenFactory.connect(owner).deploy() + gasPriceFeed = await mockV3AggregatorFactory + .connect(owner) + .deploy(0, gasWei) + linkUSDFeed = await mockV3AggregatorFactory + .connect(owner) + .deploy(8, linkUSD) + nativeUSDFeed = await mockV3AggregatorFactory + .connect(owner) + .deploy(8, nativeUSD) + const upkeepTranscoderFactory = await ethers.getContractFactory( + 'UpkeepTranscoder5_0', + ) + transcoder = await upkeepTranscoderFactory.connect(owner).deploy() + mockZKSyncSystemContext = await mockZKSyncSystemContextFactory + .connect(owner) + .deploy() + mockGasBoundCaller = await mockGasBoundCallerFactory.connect(owner).deploy() + moduleBase = await moduleBaseFactory.connect(owner).deploy() + streamsLookupUpkeep = await streamsLookupUpkeepFactory + .connect(owner) + .deploy( + BigNumber.from('10000'), + BigNumber.from('100'), + false /* useArbBlock */, + true /* staging */, + false /* verify mercury response */, + ) + + const zksyncSystemContextCode = await ethers.provider.send('eth_getCode', [ + mockZKSyncSystemContext.address, + ]) + await ethers.provider.send('hardhat_setCode', [ + '0x000000000000000000000000000000000000800B', + zksyncSystemContextCode, + ]) + + const gasBoundCallerCode = await ethers.provider.send('eth_getCode', [ + mockGasBoundCaller.address, + ]) + await ethers.provider.send('hardhat_setCode', [ + '0xc706EC7dfA5D4Dc87f29f859094165E8290530f5', + gasBoundCallerCode, + ]) + + const financeAdminAddress = await financeAdmin.getAddress() + + config = { + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + fallbackNativePrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: moduleBase.address, + reorgProtectionEnabled: true, + financeAdmin: financeAdminAddress, + } + + baseConfig = [ + signerAddresses, + keeperAddresses, + f, + config, + offchainVersion, + offchainBytes, + [linkToken.address], + [ + { + gasFeePPB: paymentPremiumPPB, + flatFeeMilliCents, + priceFeed: linkUSDFeed.address, + fallbackPrice: fallbackLinkPrice, + minSpend: minUpkeepSpend, + decimals: 18, + }, + ], + ] + + const registryParams: Parameters = [ + owner, + linkToken.address, + linkUSDFeed.address, + nativeUSDFeed.address, + gasPriceFeed.address, + zeroAddress, + 0, // onchain payout mode + wrappedNativeTokenAddress, + ] + + registry = await deployZKSyncRegistry23(...registryParams) + mgRegistry = await deployZKSyncRegistry23(...registryParams) + + registryConditionalOverhead = await registry.getConditionalGasOverhead() + registryLogOverhead = await registry.getLogGasOverhead() + registryPerSignerGasOverhead = await registry.getPerSignerGasOverhead() + // registryPerPerformByteGasOverhead = + // await registry.getPerPerformByteGasOverhead() + // registryTransmitCalldataFixedBytesOverhead = + // await registry.getTransmitCalldataFixedBytesOverhead() + // registryTransmitCalldataPerSignerBytesOverhead = + // await registry.getTransmitCalldataPerSignerBytesOverhead() + cancellationDelay = (await registry.getCancellationDelay()).toNumber() + + await registry.connect(owner).setConfigTypeSafe(...baseConfig) + await mgRegistry.connect(owner).setConfigTypeSafe(...baseConfig) + for (const reg of [registry, mgRegistry]) { + await reg.connect(owner).setPayees(payees) + await linkToken.connect(admin).approve(reg.address, toWei('1000')) + await linkToken.connect(owner).approve(reg.address, toWei('1000')) + } + + mock = await upkeepMockFactory.deploy() + await linkToken + .connect(owner) + .transfer(await admin.getAddress(), toWei('1000')) + let tx = await registry + .connect(owner) + .registerUpkeep( + mock.address, + performGas, + await admin.getAddress(), + Trigger.CONDITION, + linkToken.address, + randomBytes, + '0x', + '0x', + ) + upkeepId = await getUpkeepID(tx) + + autoFunderUpkeep = await upkeepAutoFunderFactory + .connect(owner) + .deploy(linkToken.address, registry.address) + tx = await registry + .connect(owner) + .registerUpkeep( + autoFunderUpkeep.address, + performGas, + autoFunderUpkeep.address, + Trigger.CONDITION, + linkToken.address, + '0x', + '0x', + '0x', + ) + afUpkeepId = await getUpkeepID(tx) + + ltUpkeep = await deployMockContract(owner, ILogAutomationactory.abi) + tx = await registry + .connect(owner) + .registerUpkeep( + ltUpkeep.address, + performGas, + await admin.getAddress(), + Trigger.LOG, + linkToken.address, + '0x', + logTriggerConfig, + emptyBytes, + ) + logUpkeepId = await getUpkeepID(tx) + + await autoFunderUpkeep.setUpkeepId(afUpkeepId) + // Give enough funds for upkeep as well as to the upkeep contract + await linkToken + .connect(owner) + .transfer(autoFunderUpkeep.address, toWei('1000')) + + tx = await registry + .connect(owner) + .registerUpkeep( + streamsLookupUpkeep.address, + performGas, + await admin.getAddress(), + Trigger.CONDITION, + linkToken.address, + '0x', + '0x', + '0x', + ) + streamsLookupUpkeepId = await getUpkeepID(tx) + } + + const getMultipleUpkeepsDeployedAndFunded = async ( + numPassingConditionalUpkeeps: number, + numPassingLogUpkeeps: number, + numFailingUpkeeps: number, + ) => { + const passingConditionalUpkeepIds = [] + const passingLogUpkeepIds = [] + const failingUpkeepIds = [] + for (let i = 0; i < numPassingConditionalUpkeeps; i++) { + const mock = await upkeepMockFactory.deploy() + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(BigNumber.from('0')) + const tx = await registry + .connect(owner) + .registerUpkeep( + mock.address, + performGas, + await admin.getAddress(), + Trigger.CONDITION, + linkToken.address, + '0x', + '0x', + '0x', + ) + const condUpkeepId = await getUpkeepID(tx) + passingConditionalUpkeepIds.push(condUpkeepId) + + // Add funds to passing upkeeps + await registry.connect(admin).addFunds(condUpkeepId, toWei('100')) + } + for (let i = 0; i < numPassingLogUpkeeps; i++) { + const mock = await upkeepMockFactory.deploy() + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(BigNumber.from('0')) + const tx = await registry + .connect(owner) + .registerUpkeep( + mock.address, + performGas, + await admin.getAddress(), + Trigger.LOG, + linkToken.address, + '0x', + logTriggerConfig, + emptyBytes, + ) + const logUpkeepId = await getUpkeepID(tx) + passingLogUpkeepIds.push(logUpkeepId) + + // Add funds to passing upkeeps + await registry.connect(admin).addFunds(logUpkeepId, toWei('100')) + } + for (let i = 0; i < numFailingUpkeeps; i++) { + const mock = await upkeepMockFactory.deploy() + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(BigNumber.from('0')) + const tx = await registry + .connect(owner) + .registerUpkeep( + mock.address, + performGas, + await admin.getAddress(), + Trigger.CONDITION, + linkToken.address, + '0x', + '0x', + '0x', + ) + const failingUpkeepId = await getUpkeepID(tx) + failingUpkeepIds.push(failingUpkeepId) + } + return { + passingConditionalUpkeepIds, + passingLogUpkeepIds, + failingUpkeepIds, + } + } + + beforeEach(async () => { + await loadFixture(setup) + }) + + describe('#transmit', () => { + const fArray = [1, 5, 10] + + it('reverts when registry is paused', async () => { + await registry.connect(owner).pause() + await evmRevertCustomError( + getTransmitTx(registry, keeper1, [upkeepId]), + registry, + 'RegistryPaused', + ) + }) + + it('reverts when called by non active transmitter', async () => { + await evmRevertCustomError( + getTransmitTx(registry, payee1, [upkeepId]), + registry, + 'OnlyActiveTransmitters', + ) + }) + + it('reverts when report data lengths mismatches', async () => { + const upkeepIds = [] + const gasLimits: BigNumber[] = [] + const triggers: string[] = [] + const performDatas = [] + + upkeepIds.push(upkeepId) + gasLimits.push(performGas) + triggers.push('0x') + performDatas.push('0x') + // Push an extra perform data + performDatas.push('0x') + + const report = encodeReport({ + fastGasWei: 0, + linkUSD: 0, + upkeepIds, + gasLimits, + triggers, + performDatas, + }) + + await evmRevertCustomError( + getTransmitTxWithReport(registry, keeper1, report), + registry, + 'InvalidReport', + ) + }) + + it('returns early when invalid upkeepIds are included in report', async () => { + const tx = await getTransmitTx(registry, keeper1, [ + upkeepId.add(BigNumber.from('1')), + ]) + + const receipt = await tx.wait() + const cancelledUpkeepReportLogs = parseCancelledUpkeepReportLogs(receipt) + // exactly 1 CancelledUpkeepReport log should be emitted + assert.equal(cancelledUpkeepReportLogs.length, 1) + }) + + it('performs even when the upkeep has insufficient funds and the upkeep pays out all the remaining balance', async () => { + // add very little fund to this upkeep + await registry.connect(admin).addFunds(upkeepId, BigNumber.from(10)) + const tx = await getTransmitTx(registry, keeper1, [upkeepId]) + const receipt = await tx.wait() + // the upkeep is underfunded in transmit but still performed + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal(upkeepPerformedLogs.length, 1) + const balance = (await registry.getUpkeep(upkeepId)).balance + assert.equal(balance.toNumber(), 0) + }) + + context('When the upkeep is funded', async () => { + beforeEach(async () => { + // Fund the upkeep + await Promise.all([ + registry.connect(admin).addFunds(upkeepId, toWei('100')), + registry.connect(admin).addFunds(logUpkeepId, toWei('100')), + ]) + }) + + it('handles duplicate upkeepIDs', async () => { + const tests: [string, BigNumber, number, number][] = [ + // [name, upkeep, num stale, num performed] + ['conditional', upkeepId, 1, 1], // checkBlocks must be sequential + ['log-trigger', logUpkeepId, 0, 2], // logs are deduped based on the "trigger ID" + ] + for (const [type, id, nStale, nPerformed] of tests) { + const tx = await getTransmitTx(registry, keeper1, [id, id]) + const receipt = await tx.wait() + const staleUpkeepReport = parseStaleUpkeepReportLogs(receipt) + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal( + staleUpkeepReport.length, + nStale, + `wrong log count for ${type} upkeep`, + ) + assert.equal( + upkeepPerformedLogs.length, + nPerformed, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('handles duplicate log triggers', async () => { + const logBlockHash = ethers.utils.randomBytes(32) + const txHash = ethers.utils.randomBytes(32) + const logIndex = 0 + const expectedDedupKey = ethers.utils.solidityKeccak256( + ['uint256', 'bytes32', 'bytes32', 'uint32'], + [logUpkeepId, logBlockHash, txHash, logIndex], + ) + assert.isFalse(await registry.hasDedupKey(expectedDedupKey)) + const tx = await getTransmitTx( + registry, + keeper1, + [logUpkeepId, logUpkeepId], + { logBlockHash, txHash, logIndex }, // will result in the same dedup key + ) + const receipt = await tx.wait() + const staleUpkeepReport = parseStaleUpkeepReportLogs(receipt) + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal(staleUpkeepReport.length, 1) + assert.equal(upkeepPerformedLogs.length, 1) + assert.isTrue(await registry.hasDedupKey(expectedDedupKey)) + await expect(tx) + .to.emit(registry, 'DedupKeyAdded') + .withArgs(expectedDedupKey) + }) + + it('returns early when check block number is less than last perform (block)', async () => { + // First perform an upkeep to put last perform block number on upkeep state + const tx = await getTransmitTx(registry, keeper1, [upkeepId]) + await tx.wait() + const lastPerformed = (await registry.getUpkeep(upkeepId)) + .lastPerformedBlockNumber + const lastPerformBlock = await ethers.provider.getBlock(lastPerformed) + assert.equal(lastPerformed.toString(), tx.blockNumber?.toString()) + // Try to transmit a report which has checkBlockNumber = lastPerformed-1, should result in stale report + const transmitTx = await getTransmitTx(registry, keeper1, [upkeepId], { + checkBlockNum: lastPerformBlock.number - 1, + checkBlockHash: lastPerformBlock.parentHash, + }) + const receipt = await transmitTx.wait() + const staleUpkeepReportLogs = parseStaleUpkeepReportLogs(receipt) + // exactly 1 StaleUpkeepReportLogs log should be emitted + assert.equal(staleUpkeepReportLogs.length, 1) + }) + + it('handles case when check block hash does not match', async () => { + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + // Try to transmit a report which has incorrect checkBlockHash + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number - 1, + checkBlockHash: latestBlock.hash, // should be latestBlock.parentHash + }) + + const receipt = await tx.wait() + const reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('handles case when check block number is older than 256 blocks', async () => { + for (let i = 0; i < 256; i++) { + await ethers.provider.send('evm_mine', []) + } + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + const old = await ethers.provider.getBlock(latestBlock.number - 256) + // Try to transmit a report which has incorrect checkBlockHash + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: old.number, + checkBlockHash: old.hash, + }) + + const receipt = await tx.wait() + const reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('allows bypassing reorg protection with empty blockhash', async () => { + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number, + checkBlockHash: emptyBytes32, + }) + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal( + upkeepPerformedLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('allows bypassing reorg protection with reorgProtectionEnabled false config', async () => { + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + const newConfig = config + newConfig.reorgProtectionEnabled = false + await registry // used to test initial configurations + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ) + + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + // Try to transmit a report which has incorrect checkBlockHash + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number - 1, + checkBlockHash: latestBlock.hash, // should be latestBlock.parentHash + }) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal( + upkeepPerformedLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('allows very old trigger block numbers when bypassing reorg protection with reorgProtectionEnabled config', async () => { + const newConfig = config + newConfig.reorgProtectionEnabled = false + await registry // used to test initial configurations + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ) + for (let i = 0; i < 256; i++) { + await ethers.provider.send('evm_mine', []) + } + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + const old = await ethers.provider.getBlock(latestBlock.number - 256) + // Try to transmit a report which has incorrect checkBlockHash + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: old.number, + checkBlockHash: old.hash, + }) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal( + upkeepPerformedLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('allows very old trigger block numbers when bypassing reorg protection with empty blockhash', async () => { + // mine enough blocks so that blockhash(1) is unavailable + for (let i = 0; i <= 256; i++) { + await ethers.provider.send('evm_mine', []) + } + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: 1, + checkBlockHash: emptyBytes32, + }) + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal( + upkeepPerformedLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('returns early when future block number is provided as trigger, irrespective of blockhash being present', async () => { + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + + // Should fail when blockhash is empty + let tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number + 100, + checkBlockHash: emptyBytes32, + }) + let receipt = await tx.wait() + let reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + + // Should also fail when blockhash is not empty + tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number + 100, + checkBlockHash: latestBlock.hash, + }) + receipt = await tx.wait() + reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('returns early when future block number is provided as trigger, irrespective of reorgProtectionEnabled config', async () => { + const newConfig = config + newConfig.reorgProtectionEnabled = false + await registry // used to test initial configurations + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ) + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + + // Should fail when blockhash is empty + let tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number + 100, + checkBlockHash: emptyBytes32, + }) + let receipt = await tx.wait() + let reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + + // Should also fail when blockhash is not empty + tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number + 100, + checkBlockHash: latestBlock.hash, + }) + receipt = await tx.wait() + reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('returns early when upkeep is cancelled and cancellation delay has gone', async () => { + const latestBlockReport = await makeLatestBlockReport([upkeepId]) + await registry.connect(admin).cancelUpkeep(upkeepId) + + for (let i = 0; i < cancellationDelay; i++) { + await ethers.provider.send('evm_mine', []) + } + + const tx = await getTransmitTxWithReport( + registry, + keeper1, + latestBlockReport, + ) + + const receipt = await tx.wait() + const cancelledUpkeepReportLogs = + parseCancelledUpkeepReportLogs(receipt) + // exactly 1 CancelledUpkeepReport log should be emitted + assert.equal(cancelledUpkeepReportLogs.length, 1) + }) + + it('does not revert if the target cannot execute', async () => { + await mock.setCanPerform(false) + const tx = await getTransmitTx(registry, keeper1, [upkeepId]) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + + const success = upkeepPerformedLog.args.success + assert.equal(success, false) + }) + + it('does not revert if the target runs out of gas', async () => { + await mock.setCanPerform(false) + + const tx = await getTransmitTx(registry, keeper1, [upkeepId], { + performGas: 10, // too little gas + }) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + + const success = upkeepPerformedLog.args.success + assert.equal(success, false) + }) + + it('reverts if not enough gas supplied', async () => { + await mock.setCanPerform(true) + await evmRevert( + getTransmitTx(registry, keeper1, [upkeepId], { + gasLimit: BigNumber.from(150000), + }), + ) + }) + + it('executes the data passed to the registry', async () => { + await mock.setCanPerform(true) + + const tx = await getTransmitTx(registry, keeper1, [upkeepId], { + performDatas: [randomBytes], + }) + const receipt = await tx.wait() + + const upkeepPerformedWithABI = [ + 'event UpkeepPerformedWith(bytes upkeepData)', + ] + const iface = new ethers.utils.Interface(upkeepPerformedWithABI) + const parsedLogs = [] + for (let i = 0; i < receipt.logs.length; i++) { + const log = receipt.logs[i] + try { + parsedLogs.push(iface.parseLog(log)) + } catch (e) { + // ignore log + } + } + assert.equal(parsedLogs.length, 1) + assert.equal(parsedLogs[0].args.upkeepData, randomBytes) + }) + + it('uses actual execution price for payment and premium calculation', async () => { + // Actual multiplier is 2, but we set gasPrice to be == gasWei + const gasPrice = gasWei + await mock.setCanPerform(true) + const registryPremiumBefore = (await registry.getState()).state + .totalPremium + const tx = await getTransmitTx(registry, keeper1, [upkeepId], { + gasPrice, + }) + const receipt = await tx.wait() + const registryPremiumAfter = (await registry.getState()).state + .totalPremium + const premium = registryPremiumAfter.sub(registryPremiumBefore) + + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + + const gasUsed = upkeepPerformedLog.args.gasUsed // 14657 gasUsed + const gasOverhead = upkeepPerformedLog.args.gasOverhead // 137230 gasOverhead + const totalPayment = upkeepPerformedLog.args.totalPayment + + assert.equal( + linkForGas( + gasUsed, + gasOverhead, + BigNumber.from('1'), // Not the config multiplier, but the actual gas used + paymentPremiumPPB, + flatFeeMilliCents, + // pubdataGas.mul(gasPrice), + ).total.toString(), + totalPayment.toString(), + ) + + assert.equal( + linkForGas( + gasUsed, + gasOverhead, + BigNumber.from('1'), // Not the config multiplier, but the actual gas used + paymentPremiumPPB, + flatFeeMilliCents, + // pubdataGas.mul(gasPrice), + ).premium.toString(), + premium.toString(), + ) + }) + + it('only pays at a rate up to the gas ceiling [ @skip-coverage ]', async () => { + // Actual multiplier is 2, but we set gasPrice to be 10x + const gasPrice = gasWei.mul(BigNumber.from('10')) + await mock.setCanPerform(true) + + const tx = await getTransmitTx(registry, keeper1, [upkeepId], { + gasPrice, + }) + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + + const gasUsed = upkeepPerformedLog.args.gasUsed + const gasOverhead = upkeepPerformedLog.args.gasOverhead + const totalPayment = upkeepPerformedLog.args.totalPayment + + assert.equal( + linkForGas( + gasUsed, + gasOverhead, + gasCeilingMultiplier, // Should be same with exisitng multiplier + paymentPremiumPPB, + flatFeeMilliCents, + // pubdataGas.mul(gasPrice), + ).total.toString(), + totalPayment.toString(), + ) + }) + + itMaybe('can self fund', async () => { + const maxPayment = await registry.getMaxPaymentForGas( + upkeepId, + Trigger.CONDITION, + performGas, + linkToken.address, + ) + + // First set auto funding amount to 0 and verify that balance is deducted upon performUpkeep + let initialBalance = toWei('100') + await registry.connect(owner).addFunds(afUpkeepId, initialBalance) + await autoFunderUpkeep.setAutoFundLink(0) + await autoFunderUpkeep.setIsEligible(true) + await getTransmitTx(registry, keeper1, [afUpkeepId]) + + let postUpkeepBalance = (await registry.getUpkeep(afUpkeepId)).balance + assert.isTrue(postUpkeepBalance.lt(initialBalance)) // Balance should be deducted + assert.isTrue(postUpkeepBalance.gte(initialBalance.sub(maxPayment))) // Balance should not be deducted more than maxPayment + + // Now set auto funding amount to 100 wei and verify that the balance increases + initialBalance = postUpkeepBalance + const autoTopupAmount = toWei('100') + await autoFunderUpkeep.setAutoFundLink(autoTopupAmount) + await autoFunderUpkeep.setIsEligible(true) + await getTransmitTx(registry, keeper1, [afUpkeepId]) + + postUpkeepBalance = (await registry.getUpkeep(afUpkeepId)).balance + // Balance should increase by autoTopupAmount and decrease by max maxPayment + assert.isTrue( + postUpkeepBalance.gte( + initialBalance.add(autoTopupAmount).sub(maxPayment), + ), + ) + }) + + it('can self cancel', async () => { + await registry.connect(owner).addFunds(afUpkeepId, toWei('100')) + + await autoFunderUpkeep.setIsEligible(true) + await autoFunderUpkeep.setShouldCancel(true) + + let registration = await registry.getUpkeep(afUpkeepId) + const oldExpiration = registration.maxValidBlocknumber + + // Do the thing + await getTransmitTx(registry, keeper1, [afUpkeepId]) + + // Verify upkeep gets cancelled + registration = await registry.getUpkeep(afUpkeepId) + const newExpiration = registration.maxValidBlocknumber + assert.isTrue(newExpiration.lt(oldExpiration)) + }) + + it('reverts when configDigest mismatches', async () => { + const report = await makeLatestBlockReport([upkeepId]) + const reportContext = [emptyBytes32, epochAndRound5_1, emptyBytes32] // wrong config digest + const sigs = signReport(reportContext, report, signers.slice(0, f + 1)) + await evmRevertCustomError( + registry + .connect(keeper1) + .transmit( + [reportContext[0], reportContext[1], reportContext[2]], + report, + sigs.rs, + sigs.ss, + sigs.vs, + ), + registry, + 'ConfigDigestMismatch', + ) + }) + + it('reverts with incorrect number of signatures', async () => { + const configDigest = (await registry.getState()).state + .latestConfigDigest + const report = await makeLatestBlockReport([upkeepId]) + const reportContext = [configDigest, epochAndRound5_1, emptyBytes32] // wrong config digest + const sigs = signReport(reportContext, report, signers.slice(0, f + 2)) + await evmRevertCustomError( + registry + .connect(keeper1) + .transmit( + [reportContext[0], reportContext[1], reportContext[2]], + report, + sigs.rs, + sigs.ss, + sigs.vs, + ), + registry, + 'IncorrectNumberOfSignatures', + ) + }) + + it('reverts with invalid signature for inactive signers', async () => { + const configDigest = (await registry.getState()).state + .latestConfigDigest + const report = await makeLatestBlockReport([upkeepId]) + const reportContext = [configDigest, epochAndRound5_1, emptyBytes32] // wrong config digest + const sigs = signReport(reportContext, report, [ + new ethers.Wallet(ethers.Wallet.createRandom()), + new ethers.Wallet(ethers.Wallet.createRandom()), + ]) + await evmRevertCustomError( + registry + .connect(keeper1) + .transmit( + [reportContext[0], reportContext[1], reportContext[2]], + report, + sigs.rs, + sigs.ss, + sigs.vs, + ), + registry, + 'OnlyActiveSigners', + ) + }) + + it('reverts with invalid signature for duplicated signers', async () => { + const configDigest = (await registry.getState()).state + .latestConfigDigest + const report = await makeLatestBlockReport([upkeepId]) + const reportContext = [configDigest, epochAndRound5_1, emptyBytes32] // wrong config digest + const sigs = signReport(reportContext, report, [signer1, signer1]) + await evmRevertCustomError( + registry + .connect(keeper1) + .transmit( + [reportContext[0], reportContext[1], reportContext[2]], + report, + sigs.rs, + sigs.ss, + sigs.vs, + ), + registry, + 'DuplicateSigners', + ) + }) + + itMaybe( + 'has a large enough gas overhead to cover upkeep that use all its gas [ @skip-coverage ]', + async () => { + await registry.connect(owner).setConfigTypeSafe( + signerAddresses, + keeperAddresses, + 10, // maximise f to maximise overhead + config, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ) + const tx = await registry.connect(owner).registerUpkeep( + mock.address, + maxPerformGas, // max allowed gas + await admin.getAddress(), + Trigger.CONDITION, + linkToken.address, + '0x', + '0x', + '0x', + ) + const testUpkeepId = await getUpkeepID(tx) + await registry.connect(admin).addFunds(testUpkeepId, toWei('100')) + + let performData = '0x' + for (let i = 0; i < maxPerformDataSize.toNumber(); i++) { + performData += '11' + } // max allowed performData + + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(maxPerformGas) + + await getTransmitTx(registry, keeper1, [testUpkeepId], { + gasLimit: maxPerformGas.add(transmitGasOverhead), + numSigners: 11, + performDatas: [performData], + }) // Should not revert + }, + ) + + itMaybe( + 'performs upkeep, deducts payment, updates lastPerformed and emits events', + async () => { + await mock.setCanPerform(true) + + for (const i in fArray) { + const newF = fArray[i] + await registry + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + newF, + config, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ) + const checkBlock = await ethers.provider.getBlock('latest') + + const keeperBefore = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const registrationBefore = await registry.getUpkeep(upkeepId) + const registryPremiumBefore = (await registry.getState()).state + .totalPremium + const keeperLinkBefore = await linkToken.balanceOf( + await keeper1.getAddress(), + ) + const registryLinkBefore = await linkToken.balanceOf( + registry.address, + ) + + // Do the thing + const tx = await getTransmitTx(registry, keeper1, [upkeepId], { + checkBlockNum: checkBlock.number, + checkBlockHash: checkBlock.hash, + numSigners: newF + 1, + }) + + const receipt = await tx.wait() + + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + + const id = upkeepPerformedLog.args.id + const success = upkeepPerformedLog.args.success + const trigger = upkeepPerformedLog.args.trigger + const gasUsed = upkeepPerformedLog.args.gasUsed + const gasOverhead = upkeepPerformedLog.args.gasOverhead + const totalPayment = upkeepPerformedLog.args.totalPayment + assert.equal(id.toString(), upkeepId.toString()) + assert.equal(success, true) + assert.equal( + trigger, + encodeBlockTrigger({ + blockNum: checkBlock.number, + blockHash: checkBlock.hash, + }), + ) + assert.isTrue(gasUsed.gt(BigNumber.from('0'))) + assert.isTrue(gasOverhead.gt(BigNumber.from('0'))) + assert.isTrue(totalPayment.gt(BigNumber.from('0'))) + + const keeperAfter = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const registrationAfter = await registry.getUpkeep(upkeepId) + const keeperLinkAfter = await linkToken.balanceOf( + await keeper1.getAddress(), + ) + const registryLinkAfter = await linkToken.balanceOf( + registry.address, + ) + const registryPremiumAfter = (await registry.getState()).state + .totalPremium + const premium = registryPremiumAfter.sub(registryPremiumBefore) + // Keeper payment is gasPayment + premium / num keepers + const keeperPayment = totalPayment + .sub(premium) + .add(premium.div(BigNumber.from(keeperAddresses.length))) + + assert.equal( + keeperAfter.balance.sub(keeperPayment).toString(), + keeperBefore.balance.toString(), + ) + assert.equal( + registrationBefore.balance.sub(totalPayment).toString(), + registrationAfter.balance.toString(), + ) + assert.isTrue(keeperLinkAfter.eq(keeperLinkBefore)) + assert.isTrue(registryLinkBefore.eq(registryLinkAfter)) + + // Amount spent should be updated correctly + assert.equal( + registrationAfter.amountSpent.sub(totalPayment).toString(), + registrationBefore.amountSpent.toString(), + ) + assert.isTrue( + registrationAfter.amountSpent + .sub(registrationBefore.amountSpent) + .eq(registrationBefore.balance.sub(registrationAfter.balance)), + ) + // Last perform block number should be updated + assert.equal( + registrationAfter.lastPerformedBlockNumber.toString(), + tx.blockNumber?.toString(), + ) + + // Latest epoch should be 5 + assert.equal((await registry.getState()).state.latestEpoch, 5) + } + }, + ) + + // describe.only('Gas benchmarking conditional upkeeps [ @skip-coverage ]', function () { + // const fs = [1] + // fs.forEach(function (newF) { + // it( + // 'When f=' + + // newF + + // ' calculates gas overhead appropriately within a margin for different scenarios', + // async () => { + // // Perform the upkeep once to remove non-zero storage slots and have predictable gas measurement + // let tx = await getTransmitTx(registry, keeper1, [upkeepId]) + // await tx.wait() + // + // await registry + // .connect(admin) + // .setUpkeepGasLimit(upkeepId, performGas.mul(3)) + // + // // Different test scenarios + // let longBytes = '0x' + // for (let i = 0; i < maxPerformDataSize.toNumber(); i++) { + // longBytes += '11' + // } + // const upkeepSuccessArray = [true, false] + // const performGasArray = [5000, performGas] + // const performDataArray = ['0x', longBytes] + // const chainModuleOverheads = await moduleBase.getGasOverhead() + // + // for (const i in upkeepSuccessArray) { + // for (const j in performGasArray) { + // for (const k in performDataArray) { + // const upkeepSuccess = upkeepSuccessArray[i] + // const performGas = performGasArray[j] + // const performData = performDataArray[k] + // + // await mock.setCanPerform(upkeepSuccess) + // await mock.setPerformGasToBurn(performGas) + // await registry + // .connect(owner) + // .setConfigTypeSafe( + // signerAddresses, + // keeperAddresses, + // newF, + // config, + // offchainVersion, + // offchainBytes, + // baseConfig[6], + // baseConfig[7], + // ) + // tx = await getTransmitTx(registry, keeper1, [upkeepId], { + // numSigners: newF + 1, + // performDatas: [performData], + // }) + // const receipt = await tx.wait() + // const upkeepPerformedLogs = + // parseUpkeepPerformedLogs(receipt) + // // exactly 1 Upkeep Performed should be emitted + // assert.equal(upkeepPerformedLogs.length, 1) + // const upkeepPerformedLog = upkeepPerformedLogs[0] + // + // const upkeepGasUsed = upkeepPerformedLog.args.gasUsed + // const chargedGasOverhead = + // upkeepPerformedLog.args.gasOverhead + // const actualGasOverhead = receipt.gasUsed + // .sub(upkeepGasUsed) + // .add(500000) // the amount of pubdataGas used returned by mock gas bound caller + // const estimatedGasOverhead = registryConditionalOverhead + // .add( + // registryPerSignerGasOverhead.mul( + // BigNumber.from(newF + 1), + // ), + // ) + // .add(chainModuleOverheads.chainModuleFixedOverhead) + // .add(65_400) + // + // assert.isTrue(upkeepGasUsed.gt(BigNumber.from('0'))) + // assert.isTrue(chargedGasOverhead.gt(BigNumber.from('0'))) + // assert.isTrue(actualGasOverhead.gt(BigNumber.from('0'))) + // + // console.log( + // 'Gas Benchmarking conditional upkeeps:', + // 'upkeepSuccess=', + // upkeepSuccess, + // 'performGas=', + // performGas.toString(), + // 'performData length=', + // performData.length / 2 - 1, + // 'sig verification ( f =', + // newF, + // '): estimated overhead: ', + // estimatedGasOverhead.toString(), // 179800 + // ' charged overhead: ', + // chargedGasOverhead.toString(), // 180560 + // ' actual overhead: ', + // actualGasOverhead.toString(), // 632949 + // ' calculation margin over gasUsed: ', + // chargedGasOverhead.sub(actualGasOverhead).toString(), // 18456 + // ' estimation margin over gasUsed: ', + // estimatedGasOverhead.sub(actualGasOverhead).toString(), // -27744 + // ' upkeepGasUsed: ', + // upkeepGasUsed, // 988620 + // ' receipt.gasUsed: ', + // receipt.gasUsed, // 1121569 + // ) + // + // // The actual gas overhead should be less than charged gas overhead, but not by a lot + // // The charged gas overhead is controlled by ACCOUNTING_FIXED_GAS_OVERHEAD and + // // ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD, and their correct values should be set to + // // satisfy constraints in multiple places + // assert.isTrue( + // chargedGasOverhead.gt(actualGasOverhead), + // 'Gas overhead calculated is too low, increase account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD) by at least ' + + // actualGasOverhead.sub(chargedGasOverhead).toString(), + // ) + // assert.isTrue( + // chargedGasOverhead // 180560 + // .sub(actualGasOverhead) // 132940 + // .lt(gasCalculationMargin), + // 'Gas overhead calculated is too high, decrease account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_SIGNER_GAS_OVERHEAD) by at least ' + + // chargedGasOverhead + // .sub(actualGasOverhead) + // .sub(gasCalculationMargin) + // .toString(), + // ) + // + // // The estimated overhead during checkUpkeep should be close to the actual overhead in transaction + // // It should be greater than the actual overhead but not by a lot + // // The estimated overhead is controlled by variables + // // REGISTRY_CONDITIONAL_OVERHEAD, REGISTRY_LOG_OVERHEAD, REGISTRY_PER_SIGNER_GAS_OVERHEAD + // // REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD + // assert.isTrue( + // estimatedGasOverhead.gt(actualGasOverhead), + // 'Gas overhead estimated in check upkeep is too low, increase estimation gas variables (REGISTRY_CONDITIONAL_OVERHEAD/REGISTRY_LOG_OVERHEAD/REGISTRY_PER_SIGNER_GAS_OVERHEAD/REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD) by at least ' + + // estimatedGasOverhead.sub(chargedGasOverhead).toString(), + // ) + // assert.isTrue( + // estimatedGasOverhead + // .sub(actualGasOverhead) + // .lt(gasEstimationMargin), + // 'Gas overhead estimated is too high, decrease estimation gas variables (REGISTRY_CONDITIONAL_OVERHEAD/REGISTRY_LOG_OVERHEAD/REGISTRY_PER_SIGNER_GAS_OVERHEAD/REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD) by at least ' + + // estimatedGasOverhead + // .sub(actualGasOverhead) + // .sub(gasEstimationMargin) + // .toString(), + // ) + // } + // } + // } + // }, + // ) + // }) + // }) + + // describe.only('Gas benchmarking log upkeeps [ @skip-coverage ]', function () { + // const fs = [1] + // fs.forEach(function (newF) { + // it( + // 'When f=' + + // newF + + // ' calculates gas overhead appropriately within a margin', + // async () => { + // // Perform the upkeep once to remove non-zero storage slots and have predictable gas measurement + // let tx = await getTransmitTx(registry, keeper1, [logUpkeepId]) + // await tx.wait() + // const performData = '0x' + // await mock.setCanPerform(true) + // await mock.setPerformGasToBurn(performGas) + // await registry.setConfigTypeSafe( + // signerAddresses, + // keeperAddresses, + // newF, + // config, + // offchainVersion, + // offchainBytes, + // baseConfig[6], + // baseConfig[7], + // ) + // tx = await getTransmitTx(registry, keeper1, [logUpkeepId], { + // numSigners: newF + 1, + // performDatas: [performData], + // }) + // const receipt = await tx.wait() + // const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // // exactly 1 Upkeep Performed should be emitted + // assert.equal(upkeepPerformedLogs.length, 1) + // const upkeepPerformedLog = upkeepPerformedLogs[0] + // const chainModuleOverheads = await moduleBase.getGasOverhead() + // + // const upkeepGasUsed = upkeepPerformedLog.args.gasUsed + // const chargedGasOverhead = upkeepPerformedLog.args.gasOverhead + // const actualGasOverhead = receipt.gasUsed + // .sub(upkeepGasUsed) + // .add(500000) // the amount of pubdataGas used returned by mock gas bound caller + // const estimatedGasOverhead = registryLogOverhead + // .add(registryPerSignerGasOverhead.mul(BigNumber.from(newF + 1))) + // .add(chainModuleOverheads.chainModuleFixedOverhead) + // .add(65_400) + // + // assert.isTrue(upkeepGasUsed.gt(BigNumber.from('0'))) + // assert.isTrue(chargedGasOverhead.gt(BigNumber.from('0'))) + // assert.isTrue(actualGasOverhead.gt(BigNumber.from('0'))) + // + // console.log( + // 'Gas Benchmarking log upkeeps:', + // 'upkeepSuccess=', + // true, + // 'performGas=', + // performGas.toString(), + // 'performData length=', + // performData.length / 2 - 1, + // 'sig verification ( f =', + // newF, + // '): estimated overhead: ', + // estimatedGasOverhead.toString(), + // ' charged overhead: ', + // chargedGasOverhead.toString(), + // ' actual overhead: ', + // actualGasOverhead.toString(), + // ' calculation margin over gasUsed: ', + // chargedGasOverhead.sub(actualGasOverhead).toString(), + // ' estimation margin over gasUsed: ', + // estimatedGasOverhead.sub(actualGasOverhead).toString(), + // ' upkeepGasUsed: ', + // upkeepGasUsed, + // ' receipt.gasUsed: ', + // receipt.gasUsed, + // ) + // + // assert.isTrue( + // chargedGasOverhead.gt(actualGasOverhead), + // 'Gas overhead calculated is too low, increase account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD) by at least ' + + // actualGasOverhead.sub(chargedGasOverhead).toString(), + // ) + // assert.isTrue( + // chargedGasOverhead + // .sub(actualGasOverhead) + // .lt(gasCalculationMargin), + // 'Gas overhead calculated is too high, decrease account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_SIGNER_GAS_OVERHEAD) by at least ' + + // chargedGasOverhead + // .sub(actualGasOverhead) + // .sub(gasCalculationMargin) + // .toString(), + // ) + // + // assert.isTrue( + // estimatedGasOverhead.gt(actualGasOverhead), + // 'Gas overhead estimated in check upkeep is too low, increase estimation gas variables (REGISTRY_CONDITIONAL_OVERHEAD/REGISTRY_LOG_OVERHEAD/REGISTRY_PER_SIGNER_GAS_OVERHEAD/REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD) by at least ' + + // estimatedGasOverhead.sub(chargedGasOverhead).toString(), + // ) + // assert.isTrue( + // estimatedGasOverhead + // .sub(actualGasOverhead) + // .lt(gasEstimationMargin), + // 'Gas overhead estimated is too high, decrease estimation gas variables (REGISTRY_CONDITIONAL_OVERHEAD/REGISTRY_LOG_OVERHEAD/REGISTRY_PER_SIGNER_GAS_OVERHEAD/REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD) by at least ' + + // estimatedGasOverhead + // .sub(actualGasOverhead) + // .sub(gasEstimationMargin) + // .toString(), + // ) + // }, + // ) + // }) + // }) + }) + }) + + describeMaybe( + '#transmit with upkeep batches [ @skip-coverage ]', + function () { + const numPassingConditionalUpkeepsArray = [0, 1, 5] + const numPassingLogUpkeepsArray = [0, 1, 5] + const numFailingUpkeepsArray = [0, 3] + + for (let idx = 0; idx < numPassingConditionalUpkeepsArray.length; idx++) { + for (let jdx = 0; jdx < numPassingLogUpkeepsArray.length; jdx++) { + for (let kdx = 0; kdx < numFailingUpkeepsArray.length; kdx++) { + const numPassingConditionalUpkeeps = + numPassingConditionalUpkeepsArray[idx] + const numPassingLogUpkeeps = numPassingLogUpkeepsArray[jdx] + const numFailingUpkeeps = numFailingUpkeepsArray[kdx] + if ( + numPassingConditionalUpkeeps == 0 && + numPassingLogUpkeeps == 0 + ) { + continue + } + it( + '[Conditional:' + + numPassingConditionalUpkeeps + + ',Log:' + + numPassingLogUpkeeps + + ',Failures:' + + numFailingUpkeeps + + '] performs successful upkeeps and does not charge failing upkeeps', + async () => { + const allUpkeeps = await getMultipleUpkeepsDeployedAndFunded( + numPassingConditionalUpkeeps, + numPassingLogUpkeeps, + numFailingUpkeeps, + ) + const passingConditionalUpkeepIds = + allUpkeeps.passingConditionalUpkeepIds + const passingLogUpkeepIds = allUpkeeps.passingLogUpkeepIds + const failingUpkeepIds = allUpkeeps.failingUpkeepIds + + const keeperBefore = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const keeperLinkBefore = await linkToken.balanceOf( + await keeper1.getAddress(), + ) + const registryLinkBefore = await linkToken.balanceOf( + registry.address, + ) + const registryPremiumBefore = (await registry.getState()).state + .totalPremium + const registrationConditionalPassingBefore = await Promise.all( + passingConditionalUpkeepIds.map(async (id) => { + const reg = await registry.getUpkeep(BigNumber.from(id)) + assert.equal(reg.lastPerformedBlockNumber.toString(), '0') + return reg + }), + ) + const registrationLogPassingBefore = await Promise.all( + passingLogUpkeepIds.map(async (id) => { + const reg = await registry.getUpkeep(BigNumber.from(id)) + assert.equal(reg.lastPerformedBlockNumber.toString(), '0') + return reg + }), + ) + const registrationFailingBefore = await Promise.all( + failingUpkeepIds.map(async (id) => { + const reg = await registry.getUpkeep(BigNumber.from(id)) + assert.equal(reg.lastPerformedBlockNumber.toString(), '0') + return reg + }), + ) + + // cancel upkeeps so they will fail in the transmit process + // must call the cancel upkeep as the owner to avoid the CANCELLATION_DELAY + for (let ldx = 0; ldx < failingUpkeepIds.length; ldx++) { + await registry + .connect(owner) + .cancelUpkeep(failingUpkeepIds[ldx]) + } + + const tx = await getTransmitTx( + registry, + keeper1, + passingConditionalUpkeepIds.concat( + passingLogUpkeepIds.concat(failingUpkeepIds), + ), + ) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly numPassingUpkeeps Upkeep Performed should be emitted + assert.equal( + upkeepPerformedLogs.length, + numPassingConditionalUpkeeps + numPassingLogUpkeeps, + ) + const cancelledUpkeepReportLogs = + parseCancelledUpkeepReportLogs(receipt) + // exactly numFailingUpkeeps Upkeep Performed should be emitted + assert.equal( + cancelledUpkeepReportLogs.length, + numFailingUpkeeps, + ) + + const keeperAfter = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const keeperLinkAfter = await linkToken.balanceOf( + await keeper1.getAddress(), + ) + const registryLinkAfter = await linkToken.balanceOf( + registry.address, + ) + const registrationConditionalPassingAfter = await Promise.all( + passingConditionalUpkeepIds.map(async (id) => { + return await registry.getUpkeep(BigNumber.from(id)) + }), + ) + const registrationLogPassingAfter = await Promise.all( + passingLogUpkeepIds.map(async (id) => { + return await registry.getUpkeep(BigNumber.from(id)) + }), + ) + const registrationFailingAfter = await Promise.all( + failingUpkeepIds.map(async (id) => { + return await registry.getUpkeep(BigNumber.from(id)) + }), + ) + const registryPremiumAfter = (await registry.getState()).state + .totalPremium + const premium = registryPremiumAfter.sub(registryPremiumBefore) + + let netPayment = BigNumber.from('0') + for (let i = 0; i < numPassingConditionalUpkeeps; i++) { + const id = upkeepPerformedLogs[i].args.id + const gasUsed = upkeepPerformedLogs[i].args.gasUsed + const gasOverhead = upkeepPerformedLogs[i].args.gasOverhead + const totalPayment = upkeepPerformedLogs[i].args.totalPayment + + expect(id).to.equal(passingConditionalUpkeepIds[i]) + assert.isTrue(gasUsed.gt(BigNumber.from('0'))) + assert.isTrue(gasOverhead.gt(BigNumber.from('0'))) + assert.isTrue(totalPayment.gt(BigNumber.from('0'))) + + // Balance should be deducted + assert.equal( + registrationConditionalPassingBefore[i].balance + .sub(totalPayment) + .toString(), + registrationConditionalPassingAfter[i].balance.toString(), + ) + + // Amount spent should be updated correctly + assert.equal( + registrationConditionalPassingAfter[i].amountSpent + .sub(totalPayment) + .toString(), + registrationConditionalPassingBefore[ + i + ].amountSpent.toString(), + ) + + // Last perform block number should be updated + assert.equal( + registrationConditionalPassingAfter[ + i + ].lastPerformedBlockNumber.toString(), + tx.blockNumber?.toString(), + ) + + netPayment = netPayment.add(totalPayment) + } + + for (let i = 0; i < numPassingLogUpkeeps; i++) { + const id = + upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args + .id + const gasUsed = + upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args + .gasUsed + const gasOverhead = + upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args + .gasOverhead + const totalPayment = + upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args + .totalPayment + + expect(id).to.equal(passingLogUpkeepIds[i]) + assert.isTrue(gasUsed.gt(BigNumber.from('0'))) + assert.isTrue(gasOverhead.gt(BigNumber.from('0'))) + assert.isTrue(totalPayment.gt(BigNumber.from('0'))) + + // Balance should be deducted + assert.equal( + registrationLogPassingBefore[i].balance + .sub(totalPayment) + .toString(), + registrationLogPassingAfter[i].balance.toString(), + ) + + // Amount spent should be updated correctly + assert.equal( + registrationLogPassingAfter[i].amountSpent + .sub(totalPayment) + .toString(), + registrationLogPassingBefore[i].amountSpent.toString(), + ) + + // Last perform block number should not be updated for log triggers + assert.equal( + registrationLogPassingAfter[ + i + ].lastPerformedBlockNumber.toString(), + '0', + ) + + netPayment = netPayment.add(totalPayment) + } + + for (let i = 0; i < numFailingUpkeeps; i++) { + // CancelledUpkeep log should be emitted + const id = cancelledUpkeepReportLogs[i].args.id + expect(id).to.equal(failingUpkeepIds[i]) + + // Balance and amount spent should be same + assert.equal( + registrationFailingBefore[i].balance.toString(), + registrationFailingAfter[i].balance.toString(), + ) + assert.equal( + registrationFailingBefore[i].amountSpent.toString(), + registrationFailingAfter[i].amountSpent.toString(), + ) + + // Last perform block number should not be updated + assert.equal( + registrationFailingAfter[ + i + ].lastPerformedBlockNumber.toString(), + '0', + ) + } + + // Keeper payment is gasPayment + premium / num keepers + const keeperPayment = netPayment + .sub(premium) + .add(premium.div(BigNumber.from(keeperAddresses.length))) + + // Keeper should be paid net payment for all passed upkeeps + assert.equal( + keeperAfter.balance.sub(keeperPayment).toString(), + keeperBefore.balance.toString(), + ) + + assert.isTrue(keeperLinkAfter.eq(keeperLinkBefore)) + assert.isTrue(registryLinkBefore.eq(registryLinkAfter)) + }, + ) + + it( + '[Conditional:' + + numPassingConditionalUpkeeps + + ',Log' + + numPassingLogUpkeeps + + ',Failures:' + + numFailingUpkeeps + + '] splits gas overhead appropriately among performed upkeeps [ @skip-coverage ]', + async () => { + const allUpkeeps = await getMultipleUpkeepsDeployedAndFunded( + numPassingConditionalUpkeeps, + numPassingLogUpkeeps, + numFailingUpkeeps, + ) + const passingConditionalUpkeepIds = + allUpkeeps.passingConditionalUpkeepIds + const passingLogUpkeepIds = allUpkeeps.passingLogUpkeepIds + const failingUpkeepIds = allUpkeeps.failingUpkeepIds + + // Perform the upkeeps once to remove non-zero storage slots and have predictable gas measurement + let tx = await getTransmitTx( + registry, + keeper1, + passingConditionalUpkeepIds.concat( + passingLogUpkeepIds.concat(failingUpkeepIds), + ), + ) + + await tx.wait() + + // cancel upkeeps so they will fail in the transmit process + // must call the cancel upkeep as the owner to avoid the CANCELLATION_DELAY + for (let ldx = 0; ldx < failingUpkeepIds.length; ldx++) { + await registry + .connect(owner) + .cancelUpkeep(failingUpkeepIds[ldx]) + } + + // Do the actual thing + + tx = await getTransmitTx( + registry, + keeper1, + passingConditionalUpkeepIds.concat( + passingLogUpkeepIds.concat(failingUpkeepIds), + ), + ) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly numPassingUpkeeps Upkeep Performed should be emitted + assert.equal( + upkeepPerformedLogs.length, + numPassingConditionalUpkeeps + numPassingLogUpkeeps, + ) + + let netGasUsedPlusChargedOverhead = BigNumber.from('0') + for (let i = 0; i < numPassingConditionalUpkeeps; i++) { + const gasUsed = upkeepPerformedLogs[i].args.gasUsed + const chargedGasOverhead = + upkeepPerformedLogs[i].args.gasOverhead + + assert.isTrue(gasUsed.gt(BigNumber.from('0'))) + assert.isTrue(chargedGasOverhead.gt(BigNumber.from('0'))) + + // Overhead should be same for every upkeep + assert.isTrue( + chargedGasOverhead.eq( + upkeepPerformedLogs[0].args.gasOverhead, + ), + ) + netGasUsedPlusChargedOverhead = netGasUsedPlusChargedOverhead + .add(gasUsed) + .add(chargedGasOverhead) + } + + for (let i = 0; i < numPassingLogUpkeeps; i++) { + const gasUsed = + upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args + .gasUsed + const chargedGasOverhead = + upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args + .gasOverhead + + assert.isTrue(gasUsed.gt(BigNumber.from('0'))) + assert.isTrue(chargedGasOverhead.gt(BigNumber.from('0'))) + + // Overhead should be same for every upkeep + assert.isTrue( + chargedGasOverhead.eq( + upkeepPerformedLogs[numPassingConditionalUpkeeps].args + .gasOverhead, + ), + ) + netGasUsedPlusChargedOverhead = netGasUsedPlusChargedOverhead + .add(gasUsed) + .add(chargedGasOverhead) + } + + console.log( + 'Gas Benchmarking - batching (passedConditionalUpkeeps: ', + numPassingConditionalUpkeeps, + 'passedLogUpkeeps:', + numPassingLogUpkeeps, + 'failedUpkeeps:', + numFailingUpkeeps, + '): ', + numPassingConditionalUpkeeps > 0 + ? 'charged conditional overhead' + : '', + numPassingConditionalUpkeeps > 0 + ? upkeepPerformedLogs[0].args.gasOverhead.toString() + : '', + numPassingLogUpkeeps > 0 ? 'charged log overhead' : '', + numPassingLogUpkeeps > 0 + ? upkeepPerformedLogs[ + numPassingConditionalUpkeeps + ].args.gasOverhead.toString() + : '', + ' margin over gasUsed', + netGasUsedPlusChargedOverhead.sub(receipt.gasUsed).toString(), + ) + + // The total gas charged should be greater than tx gas + assert.isTrue( + netGasUsedPlusChargedOverhead.gt(receipt.gasUsed), + 'Charged gas overhead is too low for batch upkeeps, increase ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD', + ) + }, + ) + } + } + } + + it('has enough perform gas overhead for large batches [ @skip-coverage ]', async () => { + const numUpkeeps = 20 + const upkeepIds: BigNumber[] = [] + let totalPerformGas = BigNumber.from('0') + for (let i = 0; i < numUpkeeps; i++) { + const mock = await upkeepMockFactory.deploy() + const tx = await registry + .connect(owner) + .registerUpkeep( + mock.address, + performGas, + await admin.getAddress(), + Trigger.CONDITION, + linkToken.address, + '0x', + '0x', + '0x', + ) + const testUpkeepId = await getUpkeepID(tx) + upkeepIds.push(testUpkeepId) + + // Add funds to passing upkeeps + await registry.connect(owner).addFunds(testUpkeepId, toWei('10')) + + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(performGas) + + totalPerformGas = totalPerformGas.add(performGas) + } + + // Should revert with no overhead added + await evmRevert( + getTransmitTx(registry, keeper1, upkeepIds, { + gasLimit: totalPerformGas, + }), + ) + // Should not revert with overhead added + await getTransmitTx(registry, keeper1, upkeepIds, { + gasLimit: totalPerformGas.add(transmitGasOverhead), + }) + }) + }, + ) + + describe('#recoverFunds', () => { + const sent = toWei('7') + + beforeEach(async () => { + await linkToken.connect(admin).approve(registry.address, toWei('100')) + await linkToken + .connect(owner) + .transfer(await keeper1.getAddress(), toWei('1000')) + + // add funds to upkeep 1 and perform and withdraw some payment + const tx = await registry + .connect(owner) + .registerUpkeep( + mock.address, + performGas, + await admin.getAddress(), + Trigger.CONDITION, + linkToken.address, + '0x', + '0x', + '0x', + ) + + const id1 = await getUpkeepID(tx) + await registry.connect(admin).addFunds(id1, toWei('5')) + + await getTransmitTx(registry, keeper1, [id1]) + await getTransmitTx(registry, keeper2, [id1]) + await getTransmitTx(registry, keeper3, [id1]) + + await registry + .connect(payee1) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ) + + // transfer funds directly to the registry + await linkToken.connect(keeper1).transfer(registry.address, sent) + + // add funds to upkeep 2 and perform and withdraw some payment + const tx2 = await registry + .connect(owner) + .registerUpkeep( + mock.address, + performGas, + await admin.getAddress(), + Trigger.CONDITION, + linkToken.address, + '0x', + '0x', + '0x', + ) + const id2 = await getUpkeepID(tx2) + await registry.connect(admin).addFunds(id2, toWei('5')) + + await getTransmitTx(registry, keeper1, [id2]) + await getTransmitTx(registry, keeper2, [id2]) + await getTransmitTx(registry, keeper3, [id2]) + + await registry + .connect(payee2) + .withdrawPayment( + await keeper2.getAddress(), + await nonkeeper.getAddress(), + ) + + // transfer funds using onTokenTransfer + const data = ethers.utils.defaultAbiCoder.encode(['uint256'], [id2]) + await linkToken + .connect(owner) + .transferAndCall(registry.address, toWei('1'), data) + + // withdraw some funds + await registry.connect(owner).cancelUpkeep(id1) + await registry + .connect(admin) + .withdrawFunds(id1, await nonkeeper.getAddress()) + }) + }) + + describe('#getMinBalanceForUpkeep / #checkUpkeep / #transmit', () => { + it('calculates the minimum balance appropriately', async () => { + await mock.setCanCheck(true) + + const oneWei = BigNumber.from(1) + const minBalance = await registry.getMinBalanceForUpkeep(upkeepId) + const tooLow = minBalance.sub(oneWei) + + await registry.connect(admin).addFunds(upkeepId, tooLow) + let checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.INSUFFICIENT_BALANCE, + ) + + await registry.connect(admin).addFunds(upkeepId, oneWei) + checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + assert.equal(checkUpkeepResult.upkeepNeeded, true) + }) + + it('uses maxPerformData size in checkUpkeep but actual performDataSize in transmit', async () => { + const tx = await registry + .connect(owner) + .registerUpkeep( + mock.address, + performGas, + await admin.getAddress(), + Trigger.CONDITION, + linkToken.address, + '0x', + '0x', + '0x', + ) + const upkeepID = await getUpkeepID(tx) + await mock.setCanCheck(true) + await mock.setCanPerform(true) + + // upkeep is underfunded by 1 wei + const minBalance1 = (await registry.getMinBalanceForUpkeep(upkeepID)).sub( + 1, + ) + await registry.connect(owner).addFunds(upkeepID, minBalance1) + + // upkeep check should return false, 2 should return true + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepID) + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.INSUFFICIENT_BALANCE, + ) + + // however upkeep should perform and pay all the remaining balance + let maxPerformData = '0x' + for (let i = 0; i < maxPerformDataSize.toNumber(); i++) { + maxPerformData += '11' + } + + const tx2 = await getTransmitTx(registry, keeper1, [upkeepID], { + gasPrice: gasWei.mul(gasCeilingMultiplier), + performDatas: [maxPerformData], + }) + + const receipt = await tx2.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal(upkeepPerformedLogs.length, 1) + }) + }) + + describe('#withdrawFunds', () => { + let upkeepId2: BigNumber + + beforeEach(async () => { + const tx = await registry + .connect(owner) + .registerUpkeep( + mock.address, + performGas, + await admin.getAddress(), + Trigger.CONDITION, + linkToken.address, + '0x', + '0x', + '0x', + ) + upkeepId2 = await getUpkeepID(tx) + + await registry.connect(admin).addFunds(upkeepId, toWei('100')) + await registry.connect(admin).addFunds(upkeepId2, toWei('100')) + + // Do a perform so that upkeep is charged some amount + await getTransmitTx(registry, keeper1, [upkeepId]) + await getTransmitTx(registry, keeper1, [upkeepId2]) + }) + + describe('after the registration is paused, then cancelled', () => { + it('allows the admin to withdraw', async () => { + const balance = await registry.getBalance(upkeepId) + const payee = await payee1.getAddress() + await registry.connect(admin).pauseUpkeep(upkeepId) + await registry.connect(owner).cancelUpkeep(upkeepId) + await expect(() => + registry.connect(admin).withdrawFunds(upkeepId, payee), + ).to.changeTokenBalance(linkToken, payee1, balance) + }) + }) + + describe('after the registration is cancelled', () => { + beforeEach(async () => { + await registry.connect(owner).cancelUpkeep(upkeepId) + await registry.connect(owner).cancelUpkeep(upkeepId2) + }) + + it('can be called successively on two upkeeps', async () => { + await registry + .connect(admin) + .withdrawFunds(upkeepId, await payee1.getAddress()) + await registry + .connect(admin) + .withdrawFunds(upkeepId2, await payee1.getAddress()) + }) + + it('moves the funds out and updates the balance and emits an event', async () => { + const payee1Before = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const registryBefore = await linkToken.balanceOf(registry.address) + + let registration = await registry.getUpkeep(upkeepId) + const previousBalance = registration.balance + + const tx = await registry + .connect(admin) + .withdrawFunds(upkeepId, await payee1.getAddress()) + await expect(tx) + .to.emit(registry, 'FundsWithdrawn') + .withArgs(upkeepId, previousBalance, await payee1.getAddress()) + + const payee1After = await linkToken.balanceOf(await payee1.getAddress()) + const registryAfter = await linkToken.balanceOf(registry.address) + + assert.isTrue(payee1Before.add(previousBalance).eq(payee1After)) + assert.isTrue(registryBefore.sub(previousBalance).eq(registryAfter)) + + registration = await registry.getUpkeep(upkeepId) + assert.equal(registration.balance.toNumber(), 0) + }) + }) + }) + + describe('#simulatePerformUpkeep', () => { + it('reverts if called by non zero address', async () => { + await evmRevertCustomError( + registry + .connect(await owner.getAddress()) + .callStatic.simulatePerformUpkeep(upkeepId, '0x'), + registry, + 'OnlySimulatedBackend', + ) + }) + + it('reverts when registry is paused', async () => { + await registry.connect(owner).pause() + await evmRevertCustomError( + registry + .connect(zeroAddress) + .callStatic.simulatePerformUpkeep(upkeepId, '0x'), + registry, + 'RegistryPaused', + ) + }) + + it('returns false and gasUsed when perform fails', async () => { + await mock.setCanPerform(false) + + const simulatePerformResult = await registry + .connect(zeroAddress) + .callStatic.simulatePerformUpkeep(upkeepId, '0x') + + assert.equal(simulatePerformResult.success, false) + assert.isTrue(simulatePerformResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + }) + + it('returns true, gasUsed, and performGas when perform succeeds', async () => { + await mock.setCanPerform(true) + + const simulatePerformResult = await registry + .connect(zeroAddress) + .callStatic.simulatePerformUpkeep(upkeepId, '0x') + + assert.equal(simulatePerformResult.success, true) + assert.isTrue(simulatePerformResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + }) + + it('returns correct amount of gasUsed when perform succeeds', async () => { + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(performGas) // 1,000,000 + + // increase upkeep gas limit because the mock gas bound caller will always return 500,000 as the L1 gas used + // that brings the total gas used to about 1M + 0.5M = 1.5M + await registry + .connect(admin) + .setUpkeepGasLimit(upkeepId, BigNumber.from(2000000)) + + const simulatePerformResult = await registry + .connect(zeroAddress) + .callStatic.simulatePerformUpkeep(upkeepId, '0x') + + // Full execute gas should be used, with some performGasBuffer(1000) + assert.isTrue( + simulatePerformResult.gasUsed.gt( + performGas.add(pubdataGas).sub(BigNumber.from('1000')), + ), + ) + }) + }) + + describe('#checkUpkeep', () => { + it('reverts if called by non zero address', async () => { + await evmRevertCustomError( + registry + .connect(await owner.getAddress()) + .callStatic['checkUpkeep(uint256)'](upkeepId), + registry, + 'OnlySimulatedBackend', + ) + }) + + it('returns false and error code if the upkeep is cancelled by admin', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.UPKEEP_CANCELLED, + ) + expect(checkUpkeepResult.gasUsed).to.equal(0) + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns false and error code if the upkeep is cancelled by owner', async () => { + await registry.connect(owner).cancelUpkeep(upkeepId) + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.UPKEEP_CANCELLED, + ) + expect(checkUpkeepResult.gasUsed).to.equal(0) + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns false and error code if the registry is paused', async () => { + await registry.connect(owner).pause() + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.REGISTRY_PAUSED, + ) + expect(checkUpkeepResult.gasUsed).to.equal(0) + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns false and error code if the upkeep is paused', async () => { + await registry.connect(admin).pauseUpkeep(upkeepId) + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.UPKEEP_PAUSED, + ) + expect(checkUpkeepResult.gasUsed).to.equal(0) + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns false and error code if user is out of funds', async () => { + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.INSUFFICIENT_BALANCE, + ) + expect(checkUpkeepResult.gasUsed).to.equal(0) + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + context('when the registration is funded', () => { + beforeEach(async () => { + await linkToken.connect(admin).approve(registry.address, toWei('200')) + await registry.connect(admin).addFunds(upkeepId, toWei('100')) + await registry.connect(admin).addFunds(logUpkeepId, toWei('100')) + }) + + it('returns false, error code, and revert data if the target check reverts', async () => { + await mock.setShouldRevertCheck(true) + await mock.setCheckRevertReason( + 'custom revert error, clever way to insert offchain data', + ) + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + assert.equal(checkUpkeepResult.upkeepNeeded, false) + + const revertReasonBytes = `0x${checkUpkeepResult.performData.slice(10)}` // remove sighash + assert.equal( + ethers.utils.defaultAbiCoder.decode(['string'], revertReasonBytes)[0], + 'custom revert error, clever way to insert offchain data', + ) + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.TARGET_CHECK_REVERTED, + ) + assert.isTrue(checkUpkeepResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + // Feed data should be returned here + assert.isTrue(checkUpkeepResult.fastGasWei.gt(BigNumber.from('0'))) + assert.isTrue(checkUpkeepResult.linkUSD.gt(BigNumber.from('0'))) + }) + + it('returns false, error code, and no revert data if the target check revert data exceeds maxRevertDataSize', async () => { + await mock.setShouldRevertCheck(true) + let longRevertReason = '' + for (let i = 0; i <= maxRevertDataSize.toNumber(); i++) { + longRevertReason += 'x' + } + await mock.setCheckRevertReason(longRevertReason) + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + assert.equal(checkUpkeepResult.upkeepNeeded, false) + + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.REVERT_DATA_EXCEEDS_LIMIT, + ) + assert.isTrue(checkUpkeepResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns false and error code if the upkeep is not needed', async () => { + await mock.setCanCheck(false) + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.UPKEEP_NOT_NEEDED, + ) + assert.isTrue(checkUpkeepResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns false and error code if the performData exceeds limit', async () => { + let longBytes = '0x' + for (let i = 0; i < 5000; i++) { + longBytes += '1' + } + await mock.setCanCheck(true) + await mock.setPerformData(longBytes) + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.PERFORM_DATA_EXCEEDS_LIMIT, + ) + assert.isTrue(checkUpkeepResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns true with gas used if the target can execute', async () => { + await mock.setCanCheck(true) + await mock.setPerformData(randomBytes) + + const latestBlock = await ethers.provider.getBlock('latest') + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId, { + blockTag: latestBlock.number, + }) + + assert.equal(checkUpkeepResult.upkeepNeeded, true) + assert.equal(checkUpkeepResult.performData, randomBytes) + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.NONE, + ) + assert.isTrue(checkUpkeepResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + assert.isTrue(checkUpkeepResult.fastGasWei.eq(gasWei)) + assert.isTrue(checkUpkeepResult.linkUSD.eq(linkUSD)) + }) + + it('calls checkLog for log-trigger upkeeps', async () => { + const log: Log = { + index: 0, + timestamp: 0, + txHash: ethers.utils.randomBytes(32), + blockNumber: 100, + blockHash: ethers.utils.randomBytes(32), + source: randomAddress(), + topics: [ethers.utils.randomBytes(32), ethers.utils.randomBytes(32)], + data: ethers.utils.randomBytes(1000), + } + + await ltUpkeep.mock.checkLog.withArgs(log, '0x').returns(true, '0x1234') + + const checkData = encodeLog(log) + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256,bytes)'](logUpkeepId, checkData) + + expect(checkUpkeepResult.upkeepNeeded).to.be.true + expect(checkUpkeepResult.performData).to.equal('0x1234') + }) + + itMaybe( + 'has a large enough gas overhead to cover upkeeps that use all their gas [ @skip-coverage ]', + async () => { + await mock.setCanCheck(true) + await mock.setCheckGasToBurn(checkGasLimit) + const gas = checkGasLimit.add(checkGasOverhead) + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId, { + gasLimit: gas, + }) + + assert.equal(checkUpkeepResult.upkeepNeeded, true) + }, + ) + }) + }) + + describe('#getMaxPaymentForGas', () => { + itMaybe('calculates the max fee appropriately in ZKSync', async () => { + await verifyMaxPayment(registry, moduleBase) + }) + + it('uses the fallback gas price if the feed has issues in ZKSync', async () => { + const chainModuleOverheads = await moduleBase.getGasOverhead() + const expectedFallbackMaxPayment = linkForGas( + performGas, + registryConditionalOverhead + .add(registryPerSignerGasOverhead.mul(f + 1)) + .add(chainModuleOverheads.chainModuleFixedOverhead), + gasCeilingMultiplier.mul('2'), // fallbackGasPrice is 2x gas price + paymentPremiumPPB, + flatFeeMilliCents, + ).total + + // Stale feed + let roundId = 99 + const answer = 100 + let updatedAt = 946684800 // New Years 2000 🥳 + let startedAt = 946684799 + await gasPriceFeed + .connect(owner) + .updateRoundData(roundId, answer, updatedAt, startedAt) + + assert.equal( + expectedFallbackMaxPayment.toString(), + ( + await registry.getMaxPaymentForGas( + upkeepId, + Trigger.CONDITION, + performGas, + linkToken.address, + ) + ).toString(), + ) + + // Negative feed price + roundId = 100 + updatedAt = now() + startedAt = 946684799 + await gasPriceFeed + .connect(owner) + .updateRoundData(roundId, -100, updatedAt, startedAt) + + assert.equal( + expectedFallbackMaxPayment.toString(), + ( + await registry.getMaxPaymentForGas( + upkeepId, + Trigger.CONDITION, + performGas, + linkToken.address, + ) + ).toString(), + ) + + // Zero feed price + roundId = 101 + updatedAt = now() + startedAt = 946684799 + await gasPriceFeed + .connect(owner) + .updateRoundData(roundId, 0, updatedAt, startedAt) + + assert.equal( + expectedFallbackMaxPayment.toString(), + ( + await registry.getMaxPaymentForGas( + upkeepId, + Trigger.CONDITION, + performGas, + linkToken.address, + ) + ).toString(), + ) + }) + + it('uses the fallback link price if the feed has issues in ZKSync', async () => { + const chainModuleOverheads = await moduleBase.getGasOverhead() + const expectedFallbackMaxPayment = linkForGas( + performGas, + registryConditionalOverhead + .add(registryPerSignerGasOverhead.mul(f + 1)) + .add(chainModuleOverheads.chainModuleFixedOverhead), + gasCeilingMultiplier.mul('2'), // fallbackLinkPrice is 1/2 link price, so multiply by 2 + paymentPremiumPPB, + flatFeeMilliCents, + ).total + + // Stale feed + let roundId = 99 + const answer = 100 + let updatedAt = 946684800 // New Years 2000 🥳 + let startedAt = 946684799 + await linkUSDFeed + .connect(owner) + .updateRoundData(roundId, answer, updatedAt, startedAt) + + assert.equal( + expectedFallbackMaxPayment.toString(), + ( + await registry.getMaxPaymentForGas( + upkeepId, + Trigger.CONDITION, + performGas, + linkToken.address, + ) + ).toString(), + ) + + // Negative feed price + roundId = 100 + updatedAt = now() + startedAt = 946684799 + await linkUSDFeed + .connect(owner) + .updateRoundData(roundId, -100, updatedAt, startedAt) + + assert.equal( + expectedFallbackMaxPayment.toString(), + ( + await registry.getMaxPaymentForGas( + upkeepId, + Trigger.CONDITION, + performGas, + linkToken.address, + ) + ).toString(), + ) + + // Zero feed price + roundId = 101 + updatedAt = now() + startedAt = 946684799 + await linkUSDFeed + .connect(owner) + .updateRoundData(roundId, 0, updatedAt, startedAt) + + assert.equal( + expectedFallbackMaxPayment.toString(), + ( + await registry.getMaxPaymentForGas( + upkeepId, + Trigger.CONDITION, + performGas, + linkToken.address, + ) + ).toString(), + ) + }) + }) + + describe('#typeAndVersion', () => { + it('uses the correct type and version', async () => { + const typeAndVersion = await registry.typeAndVersion() + assert.equal(typeAndVersion, 'AutomationRegistry 2.3.0') + }) + }) + + describeMaybe('#setConfig - onchain', async () => { + const maxGas = BigNumber.from(6) + const staleness = BigNumber.from(4) + const ceiling = BigNumber.from(5) + const newMaxCheckDataSize = BigNumber.from(10000) + const newMaxPerformDataSize = BigNumber.from(10000) + const newMaxRevertDataSize = BigNumber.from(10000) + const newMaxPerformGas = BigNumber.from(10000000) + const fbGasEth = BigNumber.from(7) + const fbLinkEth = BigNumber.from(8) + const fbNativeEth = BigNumber.from(100) + const newTranscoder = randomAddress() + const newRegistrars = [randomAddress(), randomAddress()] + const upkeepManager = randomAddress() + const financeAdminAddress = randomAddress() + + const newConfig: OnChainConfig = { + checkGasLimit: maxGas, + stalenessSeconds: staleness, + gasCeilingMultiplier: ceiling, + maxCheckDataSize: newMaxCheckDataSize, + maxPerformDataSize: newMaxPerformDataSize, + maxRevertDataSize: newMaxRevertDataSize, + maxPerformGas: newMaxPerformGas, + fallbackGasPrice: fbGasEth, + fallbackLinkPrice: fbLinkEth, + fallbackNativePrice: fbNativeEth, + transcoder: newTranscoder, + registrars: newRegistrars, + upkeepPrivilegeManager: upkeepManager, + chainModule: moduleBase.address, + reorgProtectionEnabled: true, + financeAdmin: financeAdminAddress, + } + + it('reverts when called by anyone but the proposed owner', async () => { + await evmRevert( + registry + .connect(payee1) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ), + 'Only callable by owner', + ) + }) + + it('reverts if signers or transmitters are the zero address', async () => { + await evmRevertCustomError( + registry + .connect(owner) + .setConfigTypeSafe( + [randomAddress(), randomAddress(), randomAddress(), zeroAddress], + [ + randomAddress(), + randomAddress(), + randomAddress(), + randomAddress(), + ], + f, + newConfig, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ), + registry, + 'InvalidSigner', + ) + + await evmRevertCustomError( + registry + .connect(owner) + .setConfigTypeSafe( + [ + randomAddress(), + randomAddress(), + randomAddress(), + randomAddress(), + ], + [randomAddress(), randomAddress(), randomAddress(), zeroAddress], + f, + newConfig, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ), + registry, + 'InvalidTransmitter', + ) + }) + + it('updates the onchainConfig and configDigest', async () => { + const old = await registry.getState() + const oldConfig = await registry.getConfig() + const oldState = old.state + assert.isTrue(stalenessSeconds.eq(oldConfig.stalenessSeconds)) + assert.isTrue(gasCeilingMultiplier.eq(oldConfig.gasCeilingMultiplier)) + + await registry + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + [], + [], + ) + + const updated = await registry.getState() + const updatedConfig = updated.config + const updatedState = updated.state + assert.equal(updatedConfig.stalenessSeconds, staleness.toNumber()) + assert.equal(updatedConfig.gasCeilingMultiplier, ceiling.toNumber()) + assert.equal( + updatedConfig.maxCheckDataSize, + newMaxCheckDataSize.toNumber(), + ) + assert.equal( + updatedConfig.maxPerformDataSize, + newMaxPerformDataSize.toNumber(), + ) + assert.equal( + updatedConfig.maxRevertDataSize, + newMaxRevertDataSize.toNumber(), + ) + assert.equal(updatedConfig.maxPerformGas, newMaxPerformGas.toNumber()) + assert.equal(updatedConfig.checkGasLimit, maxGas.toNumber()) + assert.equal( + updatedConfig.fallbackGasPrice.toNumber(), + fbGasEth.toNumber(), + ) + assert.equal( + updatedConfig.fallbackLinkPrice.toNumber(), + fbLinkEth.toNumber(), + ) + assert.equal(updatedState.latestEpoch, 0) + + assert(oldState.configCount + 1 == updatedState.configCount) + assert( + oldState.latestConfigBlockNumber != + updatedState.latestConfigBlockNumber, + ) + assert(oldState.latestConfigDigest != updatedState.latestConfigDigest) + + assert.equal(updatedConfig.transcoder, newTranscoder) + assert.deepEqual(updatedConfig.registrars, newRegistrars) + assert.equal(updatedConfig.upkeepPrivilegeManager, upkeepManager) + }) + + it('maintains paused state when config is changed', async () => { + await registry.pause() + const old = await registry.getState() + assert.isTrue(old.state.paused) + + await registry + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + [], + [], + ) + + const updated = await registry.getState() + assert.isTrue(updated.state.paused) + }) + + it('emits an event', async () => { + const tx = await registry + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + [], + [], + ) + await expect(tx).to.emit(registry, 'ConfigSet') + }) + }) + + describe('#setConfig - offchain', () => { + let newKeepers: string[] + + beforeEach(async () => { + newKeepers = [ + await personas.Eddy.getAddress(), + await personas.Nick.getAddress(), + await personas.Neil.getAddress(), + await personas.Carol.getAddress(), + ] + }) + + it('reverts when called by anyone but the owner', async () => { + await evmRevert( + registry + .connect(payee1) + .setConfigTypeSafe( + newKeepers, + newKeepers, + f, + config, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ), + 'Only callable by owner', + ) + }) + + it('reverts if too many keeperAddresses set', async () => { + for (let i = 0; i < 40; i++) { + newKeepers.push(randomAddress()) + } + await evmRevertCustomError( + registry + .connect(owner) + .setConfigTypeSafe( + newKeepers, + newKeepers, + f, + config, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ), + registry, + 'TooManyOracles', + ) + }) + + it('reverts if f=0', async () => { + await evmRevertCustomError( + registry + .connect(owner) + .setConfigTypeSafe( + newKeepers, + newKeepers, + 0, + config, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ), + registry, + 'IncorrectNumberOfFaultyOracles', + ) + }) + + it('reverts if signers != transmitters length', async () => { + const signers = [randomAddress()] + await evmRevertCustomError( + registry + .connect(owner) + .setConfigTypeSafe( + signers, + newKeepers, + f, + config, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ), + registry, + 'IncorrectNumberOfSigners', + ) + }) + + it('reverts if signers <= 3f', async () => { + newKeepers.pop() + await evmRevertCustomError( + registry + .connect(owner) + .setConfigTypeSafe( + newKeepers, + newKeepers, + f, + config, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ), + registry, + 'IncorrectNumberOfSigners', + ) + }) + + it('reverts on repeated signers', async () => { + const newSigners = [ + await personas.Eddy.getAddress(), + await personas.Eddy.getAddress(), + await personas.Eddy.getAddress(), + await personas.Eddy.getAddress(), + ] + await evmRevertCustomError( + registry + .connect(owner) + .setConfigTypeSafe( + newSigners, + newKeepers, + f, + config, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ), + registry, + 'RepeatedSigner', + ) + }) + + it('reverts on repeated transmitters', async () => { + const newTransmitters = [ + await personas.Eddy.getAddress(), + await personas.Eddy.getAddress(), + await personas.Eddy.getAddress(), + await personas.Eddy.getAddress(), + ] + await evmRevertCustomError( + registry + .connect(owner) + .setConfigTypeSafe( + newKeepers, + newTransmitters, + f, + config, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ), + registry, + 'RepeatedTransmitter', + ) + }) + + itMaybe('stores new config and emits event', async () => { + // Perform an upkeep so that totalPremium is updated + await registry.connect(admin).addFunds(upkeepId, toWei('100')) + let tx = await getTransmitTx(registry, keeper1, [upkeepId]) + await tx.wait() + + const newOffChainVersion = BigNumber.from('2') + const newOffChainConfig = '0x1122' + + const old = await registry.getState() + const oldState = old.state + assert(oldState.totalPremium.gt(BigNumber.from('0'))) + + const newSigners = newKeepers + tx = await registry + .connect(owner) + .setConfigTypeSafe( + newSigners, + newKeepers, + f, + config, + newOffChainVersion, + newOffChainConfig, + [], + [], + ) + + const updated = await registry.getState() + const updatedState = updated.state + assert(oldState.totalPremium.eq(updatedState.totalPremium)) + + // Old signer addresses which are not in new signers should be non active + for (let i = 0; i < signerAddresses.length; i++) { + const signer = signerAddresses[i] + if (!newSigners.includes(signer)) { + assert(!(await registry.getSignerInfo(signer)).active) + assert((await registry.getSignerInfo(signer)).index == 0) + } + } + // New signer addresses should be active + for (let i = 0; i < newSigners.length; i++) { + const signer = newSigners[i] + assert((await registry.getSignerInfo(signer)).active) + assert((await registry.getSignerInfo(signer)).index == i) + } + // Old transmitter addresses which are not in new transmitter should be non active, update lastCollected but retain other info + for (let i = 0; i < keeperAddresses.length; i++) { + const transmitter = keeperAddresses[i] + if (!newKeepers.includes(transmitter)) { + assert(!(await registry.getTransmitterInfo(transmitter)).active) + assert((await registry.getTransmitterInfo(transmitter)).index == i) + assert( + (await registry.getTransmitterInfo(transmitter)).lastCollected.eq( + oldState.totalPremium.sub( + oldState.totalPremium.mod(keeperAddresses.length), + ), + ), + ) + } + } + // New transmitter addresses should be active + for (let i = 0; i < newKeepers.length; i++) { + const transmitter = newKeepers[i] + assert((await registry.getTransmitterInfo(transmitter)).active) + assert((await registry.getTransmitterInfo(transmitter)).index == i) + assert( + (await registry.getTransmitterInfo(transmitter)).lastCollected.eq( + oldState.totalPremium, + ), + ) + } + + // config digest should be updated + assert(oldState.configCount + 1 == updatedState.configCount) + assert( + oldState.latestConfigBlockNumber != + updatedState.latestConfigBlockNumber, + ) + assert(oldState.latestConfigDigest != updatedState.latestConfigDigest) + + //New config should be updated + assert.deepEqual(updated.signers, newKeepers) + assert.deepEqual(updated.transmitters, newKeepers) + + // Event should have been emitted + await expect(tx).to.emit(registry, 'ConfigSet') + }) + }) + + describe('#cancelUpkeep', () => { + describe('when called by the admin', async () => { + describeMaybe('when an upkeep has been performed', async () => { + beforeEach(async () => { + await linkToken.connect(owner).approve(registry.address, toWei('100')) + await registry.connect(owner).addFunds(upkeepId, toWei('100')) + await getTransmitTx(registry, keeper1, [upkeepId]) + }) + + it('deducts a cancellation fee from the upkeep and adds to reserve', async () => { + const newMinUpkeepSpend = toWei('10') + const financeAdminAddress = await financeAdmin.getAddress() + + await registry.connect(owner).setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + { + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + fallbackNativePrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: moduleBase.address, + reorgProtectionEnabled: true, + financeAdmin: financeAdminAddress, + }, + offchainVersion, + offchainBytes, + [linkToken.address], + [ + { + gasFeePPB: paymentPremiumPPB, + flatFeeMilliCents, + priceFeed: linkUSDFeed.address, + fallbackPrice: fallbackLinkPrice, + minSpend: newMinUpkeepSpend, + decimals: 18, + }, + ], + ) + + const payee1Before = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const upkeepBefore = (await registry.getUpkeep(upkeepId)).balance + const ownerBefore = await registry.linkAvailableForPayment() + + const amountSpent = toWei('100').sub(upkeepBefore) + const cancellationFee = newMinUpkeepSpend.sub(amountSpent) + + await registry.connect(admin).cancelUpkeep(upkeepId) + + const payee1After = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const upkeepAfter = (await registry.getUpkeep(upkeepId)).balance + const ownerAfter = await registry.linkAvailableForPayment() + + // post upkeep balance should be previous balance minus cancellation fee + assert.isTrue(upkeepBefore.sub(cancellationFee).eq(upkeepAfter)) + // payee balance should not change + assert.isTrue(payee1Before.eq(payee1After)) + // owner should receive the cancellation fee + assert.isTrue(ownerAfter.sub(ownerBefore).eq(cancellationFee)) + }) + + it('deducts up to balance as cancellation fee', async () => { + // Very high min spend, should deduct whole balance as cancellation fees + const newMinUpkeepSpend = toWei('1000') + const financeAdminAddress = await financeAdmin.getAddress() + + await registry.connect(owner).setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + { + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + fallbackNativePrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: moduleBase.address, + reorgProtectionEnabled: true, + financeAdmin: financeAdminAddress, + }, + offchainVersion, + offchainBytes, + [linkToken.address], + [ + { + gasFeePPB: paymentPremiumPPB, + flatFeeMilliCents, + priceFeed: linkUSDFeed.address, + fallbackPrice: fallbackLinkPrice, + minSpend: newMinUpkeepSpend, + decimals: 18, + }, + ], + ) + const payee1Before = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const upkeepBefore = (await registry.getUpkeep(upkeepId)).balance + const ownerBefore = await registry.linkAvailableForPayment() + + await registry.connect(admin).cancelUpkeep(upkeepId) + const payee1After = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const ownerAfter = await registry.linkAvailableForPayment() + const upkeepAfter = (await registry.getUpkeep(upkeepId)).balance + + // all upkeep balance is deducted for cancellation fee + assert.equal(upkeepAfter.toNumber(), 0) + // payee balance should not change + assert.isTrue(payee1After.eq(payee1Before)) + // all upkeep balance is transferred to the owner + assert.isTrue(ownerAfter.sub(ownerBefore).eq(upkeepBefore)) + }) + + it('does not deduct cancellation fee if more than minUpkeepSpendDollars is spent', async () => { + // Very low min spend, already spent in one perform upkeep + const newMinUpkeepSpend = BigNumber.from(420) + const financeAdminAddress = await financeAdmin.getAddress() + + await registry.connect(owner).setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + { + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + fallbackNativePrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: moduleBase.address, + reorgProtectionEnabled: true, + financeAdmin: financeAdminAddress, + }, + offchainVersion, + offchainBytes, + [linkToken.address], + [ + { + gasFeePPB: paymentPremiumPPB, + flatFeeMilliCents, + priceFeed: linkUSDFeed.address, + fallbackPrice: fallbackLinkPrice, + minSpend: newMinUpkeepSpend, + decimals: 18, + }, + ], + ) + const payee1Before = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const upkeepBefore = (await registry.getUpkeep(upkeepId)).balance + const ownerBefore = await registry.linkAvailableForPayment() + + await registry.connect(admin).cancelUpkeep(upkeepId) + const payee1After = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const ownerAfter = await registry.linkAvailableForPayment() + const upkeepAfter = (await registry.getUpkeep(upkeepId)).balance + + // upkeep does not pay cancellation fee after cancellation because minimum upkeep spent is met + assert.isTrue(upkeepBefore.eq(upkeepAfter)) + // owner balance does not change + assert.isTrue(ownerAfter.eq(ownerBefore)) + // payee balance does not change + assert.isTrue(payee1Before.eq(payee1After)) + }) + }) + }) + }) + + describe('#withdrawPayment', () => { + beforeEach(async () => { + await linkToken.connect(owner).approve(registry.address, toWei('100')) + await registry.connect(owner).addFunds(upkeepId, toWei('100')) + await getTransmitTx(registry, keeper1, [upkeepId]) + }) + + it('reverts if called by anyone but the payee', async () => { + await evmRevertCustomError( + registry + .connect(payee2) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ), + registry, + 'OnlyCallableByPayee', + ) + }) + + it('reverts if called with the 0 address', async () => { + await evmRevertCustomError( + registry + .connect(payee2) + .withdrawPayment(await keeper1.getAddress(), zeroAddress), + registry, + 'InvalidRecipient', + ) + }) + + it('updates the balances', async () => { + const to = await nonkeeper.getAddress() + const keeperBefore = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const registrationBefore = (await registry.getUpkeep(upkeepId)).balance + const toLinkBefore = await linkToken.balanceOf(to) + const registryLinkBefore = await linkToken.balanceOf(registry.address) + const registryPremiumBefore = (await registry.getState()).state + .totalPremium + const ownerBefore = await registry.linkAvailableForPayment() + + // Withdrawing for first time, last collected = 0 + assert.equal(keeperBefore.lastCollected.toString(), '0') + + //// Do the thing + await registry + .connect(payee1) + .withdrawPayment(await keeper1.getAddress(), to) + + const keeperAfter = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const registrationAfter = (await registry.getUpkeep(upkeepId)).balance + const toLinkAfter = await linkToken.balanceOf(to) + const registryLinkAfter = await linkToken.balanceOf(registry.address) + const registryPremiumAfter = (await registry.getState()).state + .totalPremium + const ownerAfter = await registry.linkAvailableForPayment() + + // registry total premium should not change + assert.isTrue(registryPremiumBefore.eq(registryPremiumAfter)) + + // Last collected should be updated to premium-change + assert.isTrue( + keeperAfter.lastCollected.eq( + registryPremiumBefore.sub( + registryPremiumBefore.mod(keeperAddresses.length), + ), + ), + ) + + // owner balance should remain unchanged + assert.isTrue(ownerAfter.eq(ownerBefore)) + + assert.isTrue(keeperAfter.balance.eq(BigNumber.from(0))) + assert.isTrue(registrationBefore.eq(registrationAfter)) + assert.isTrue(toLinkBefore.add(keeperBefore.balance).eq(toLinkAfter)) + assert.isTrue( + registryLinkBefore.sub(keeperBefore.balance).eq(registryLinkAfter), + ) + }) + + it('emits a log announcing the withdrawal', async () => { + const balance = ( + await registry.getTransmitterInfo(await keeper1.getAddress()) + ).balance + const tx = await registry + .connect(payee1) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ) + await expect(tx) + .to.emit(registry, 'PaymentWithdrawn') + .withArgs( + await keeper1.getAddress(), + balance, + await nonkeeper.getAddress(), + await payee1.getAddress(), + ) + }) + }) + + describe('#checkCallback', () => { + it('returns false with appropriate failure reason when target callback reverts', async () => { + await streamsLookupUpkeep.setShouldRevertCallback(true) + + const values: any[] = ['0x1234', '0xabcd'] + const res = await registry + .connect(zeroAddress) + .callStatic.checkCallback(streamsLookupUpkeepId, values, '0x') + + assert.isFalse(res.upkeepNeeded) + assert.equal(res.performData, '0x') + assert.equal( + res.upkeepFailureReason, + UpkeepFailureReason.CHECK_CALLBACK_REVERTED, + ) + assert.isTrue(res.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + }) + + it('returns false with appropriate failure reason when target callback returns big performData', async () => { + let longBytes = '0x' + for (let i = 0; i <= maxPerformDataSize.toNumber(); i++) { + longBytes += '11' + } + const values: any[] = [longBytes, longBytes] + const res = await registry + .connect(zeroAddress) + .callStatic.checkCallback(streamsLookupUpkeepId, values, '0x') + + assert.isFalse(res.upkeepNeeded) + assert.equal(res.performData, '0x') + assert.equal( + res.upkeepFailureReason, + UpkeepFailureReason.PERFORM_DATA_EXCEEDS_LIMIT, + ) + assert.isTrue(res.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + }) + + it('returns false with appropriate failure reason when target callback returns false', async () => { + await streamsLookupUpkeep.setCallbackReturnBool(false) + const values: any[] = ['0x1234', '0xabcd'] + const res = await registry + .connect(zeroAddress) + .callStatic.checkCallback(streamsLookupUpkeepId, values, '0x') + + assert.isFalse(res.upkeepNeeded) + assert.equal(res.performData, '0x') + assert.equal( + res.upkeepFailureReason, + UpkeepFailureReason.UPKEEP_NOT_NEEDED, + ) + assert.isTrue(res.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + }) + + it('succeeds with upkeep needed', async () => { + const values: any[] = ['0x1234', '0xabcd'] + + const res = await registry + .connect(zeroAddress) + .callStatic.checkCallback(streamsLookupUpkeepId, values, '0x') + const expectedPerformData = ethers.utils.defaultAbiCoder.encode( + ['bytes[]', 'bytes'], + [values, '0x'], + ) + + assert.isTrue(res.upkeepNeeded) + assert.equal(res.performData, expectedPerformData) + assert.equal(res.upkeepFailureReason, UpkeepFailureReason.NONE) + assert.isTrue(res.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + }) + }) + + describe('transmitterPremiumSplit [ @skip-coverage ]', () => { + beforeEach(async () => { + await linkToken.connect(owner).approve(registry.address, toWei('100')) + await registry.connect(owner).addFunds(upkeepId, toWei('100')) + }) + + it('splits premium evenly across transmitters', async () => { + // Do a transmit from keeper1 + await getTransmitTx(registry, keeper1, [upkeepId]) + + const registryPremium = (await registry.getState()).state.totalPremium + assert.isTrue(registryPremium.gt(BigNumber.from(0))) + + const premiumPerTransmitter = registryPremium.div( + BigNumber.from(keeperAddresses.length), + ) + const k1Balance = ( + await registry.getTransmitterInfo(await keeper1.getAddress()) + ).balance + // transmitter should be reimbursed for gas and get the premium + assert.isTrue(k1Balance.gt(premiumPerTransmitter)) + const k1GasReimbursement = k1Balance.sub(premiumPerTransmitter) + + const k2Balance = ( + await registry.getTransmitterInfo(await keeper2.getAddress()) + ).balance + // non transmitter should get its share of premium + assert.isTrue(k2Balance.eq(premiumPerTransmitter)) + + // Now do a transmit from keeper 2 + await getTransmitTx(registry, keeper2, [upkeepId]) + const registryPremiumNew = (await registry.getState()).state.totalPremium + assert.isTrue(registryPremiumNew.gt(registryPremium)) + const premiumPerTransmitterNew = registryPremiumNew.div( + BigNumber.from(keeperAddresses.length), + ) + const additionalPremium = premiumPerTransmitterNew.sub( + premiumPerTransmitter, + ) + + const k1BalanceNew = ( + await registry.getTransmitterInfo(await keeper1.getAddress()) + ).balance + // k1 should get the new premium + assert.isTrue( + k1BalanceNew.eq(k1GasReimbursement.add(premiumPerTransmitterNew)), + ) + + const k2BalanceNew = ( + await registry.getTransmitterInfo(await keeper2.getAddress()) + ).balance + // k2 should get gas reimbursement in addition to new premium + assert.isTrue(k2BalanceNew.gt(k2Balance.add(additionalPremium))) + }) + + it('updates last collected upon payment withdrawn', async () => { + // Do a transmit from keeper1 + await getTransmitTx(registry, keeper1, [upkeepId]) + + const registryPremium = (await registry.getState()).state.totalPremium + const k1 = await registry.getTransmitterInfo(await keeper1.getAddress()) + const k2 = await registry.getTransmitterInfo(await keeper2.getAddress()) + + // Withdrawing for first time, last collected = 0 + assert.isTrue(k1.lastCollected.eq(BigNumber.from(0))) + assert.isTrue(k2.lastCollected.eq(BigNumber.from(0))) + + //// Do the thing + await registry + .connect(payee1) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ) + + const k1New = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const k2New = await registry.getTransmitterInfo( + await keeper2.getAddress(), + ) + + // transmitter info lastCollected should be updated for k1, not for k2 + assert.isTrue( + k1New.lastCollected.eq( + registryPremium.sub(registryPremium.mod(keeperAddresses.length)), + ), + ) + assert.isTrue(k2New.lastCollected.eq(BigNumber.from(0))) + }) + + // itMaybe( + it('maintains consistent balance information across all parties', async () => { + // throughout transmits, withdrawals, setConfigs total claim on balances should remain less than expected balance + // some spare change can get lost but it should be less than maxAllowedSpareChange + + let maxAllowedSpareChange = BigNumber.from('0') + await verifyConsistentAccounting(maxAllowedSpareChange) + + await getTransmitTx(registry, keeper1, [upkeepId]) + maxAllowedSpareChange = maxAllowedSpareChange.add(BigNumber.from('31')) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry + .connect(payee1) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry + .connect(payee2) + .withdrawPayment( + await keeper2.getAddress(), + await nonkeeper.getAddress(), + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await getTransmitTx(registry, keeper1, [upkeepId]) + maxAllowedSpareChange = maxAllowedSpareChange.add(BigNumber.from('31')) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry.connect(owner).setConfigTypeSafe( + signerAddresses.slice(2, 15), // only use 2-14th index keepers + keeperAddresses.slice(2, 15), + f, + config, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await getTransmitTx(registry, keeper3, [upkeepId], { + startingSignerIndex: 2, + }) + maxAllowedSpareChange = maxAllowedSpareChange.add(BigNumber.from('13')) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry + .connect(payee1) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry + .connect(payee3) + .withdrawPayment( + await keeper3.getAddress(), + await nonkeeper.getAddress(), + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry.connect(owner).setConfigTypeSafe( + signerAddresses.slice(0, 4), // only use 0-3rd index keepers + keeperAddresses.slice(0, 4), + f, + config, + offchainVersion, + offchainBytes, + baseConfig[6], + baseConfig[7], + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + await getTransmitTx(registry, keeper1, [upkeepId]) + maxAllowedSpareChange = maxAllowedSpareChange.add(BigNumber.from('4')) + await getTransmitTx(registry, keeper3, [upkeepId]) + maxAllowedSpareChange = maxAllowedSpareChange.add(BigNumber.from('4')) + + await verifyConsistentAccounting(maxAllowedSpareChange) + await registry + .connect(payee5) + .withdrawPayment( + await keeper5.getAddress(), + await nonkeeper.getAddress(), + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry + .connect(payee1) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + }) + }) +}) diff --git a/contracts/test/v0.8/automation/helpers.ts b/contracts/test/v0.8/automation/helpers.ts index b2cdfb4efd..99f2cef9b8 100644 --- a/contracts/test/v0.8/automation/helpers.ts +++ b/contracts/test/v0.8/automation/helpers.ts @@ -9,6 +9,7 @@ import { IAutomationRegistryMaster__factory as IAutomationRegistryMasterFactory import { assert } from 'chai' import { FunctionFragment } from '@ethersproject/abi' import { AutomationRegistryLogicC2_3__factory as AutomationRegistryLogicC2_3Factory } from '../../../typechain/factories/AutomationRegistryLogicC2_3__factory' +import { ZKSyncAutomationRegistryLogicC2_3__factory as ZKSyncAutomationRegistryLogicC2_3Factory } from '../../../typechain/factories/ZKSyncAutomationRegistryLogicC2_3__factory' import { IAutomationRegistryMaster2_3 as IAutomationRegistry2_3 } from '../../../typechain/IAutomationRegistryMaster2_3' import { IAutomationRegistryMaster2_3__factory as IAutomationRegistryMaster2_3Factory } from '../../../typechain/factories/IAutomationRegistryMaster2_3__factory' @@ -212,3 +213,51 @@ export const deployRegistry23 = async ( const master = await registryFactory.connect(from).deploy(logicA.address) return IAutomationRegistryMaster2_3Factory.connect(master.address, from) } + +export const deployZKSyncRegistry23 = async ( + from: Signer, + link: Parameters[0], + linkUSD: Parameters[1], + nativeUSD: Parameters[2], + fastgas: Parameters[3], + allowedReadOnlyAddress: Parameters< + AutomationRegistryLogicC2_3Factory['deploy'] + >[5], + payoutMode: Parameters[6], + wrappedNativeTokenAddress: Parameters< + ZKSyncAutomationRegistryLogicC2_3Factory['deploy'] + >[7], +): Promise => { + const logicCFactory = await ethers.getContractFactory( + 'ZKSyncAutomationRegistryLogicC2_3', + ) + const logicBFactory = await ethers.getContractFactory( + 'ZKSyncAutomationRegistryLogicB2_3', + ) + const logicAFactory = await ethers.getContractFactory( + 'ZKSyncAutomationRegistryLogicA2_3', + ) + const registryFactory = await ethers.getContractFactory( + 'ZKSyncAutomationRegistry2_3', + ) + const forwarderLogicFactory = await ethers.getContractFactory( + 'AutomationForwarderLogic', + ) + const forwarderLogic = await forwarderLogicFactory.connect(from).deploy() + const logicC = await logicCFactory + .connect(from) + .deploy( + link, + linkUSD, + nativeUSD, + fastgas, + forwarderLogic.address, + allowedReadOnlyAddress, + payoutMode, + wrappedNativeTokenAddress, + ) + const logicB = await logicBFactory.connect(from).deploy(logicC.address) + const logicA = await logicAFactory.connect(from).deploy(logicB.address) + const master = await registryFactory.connect(from).deploy(logicA.address) + return IAutomationRegistryMaster2_3Factory.connect(master.address, from) +} From 2521c4b3dee70a9b6210210dd4aa0cb3434a8838 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Thu, 22 Aug 2024 18:05:31 +0200 Subject: [PATCH 146/432] Use new Havoc lib from CTF (#14201) * deps conflict, not building * update havoc dep * update deps again * update deps to tagged CTF version * update core OCR chaos test * update go.mod * fix lint --- integration-tests/crib/chaos.go | 11 +- integration-tests/crib/ocr_test.go | 4 +- integration-tests/go.mod | 67 +++++++----- integration-tests/go.sum | 156 +++++++++++++++++----------- integration-tests/load/go.mod | 58 +++++++---- integration-tests/load/go.sum | 94 +++++++++++------ integration-tests/soak/ocr_test.go | 15 +-- integration-tests/testsetups/ocr.go | 26 ++--- 8 files changed, 261 insertions(+), 170 deletions(-) diff --git a/integration-tests/crib/chaos.go b/integration-tests/crib/chaos.go index bbf6ca681c..463ced483f 100644 --- a/integration-tests/crib/chaos.go +++ b/integration-tests/crib/chaos.go @@ -4,16 +4,17 @@ import ( "time" "github.com/chaos-mesh/chaos-mesh/api/v1alpha1" - "github.com/smartcontractkit/havoc/k8schaos" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/smartcontractkit/chainlink-testing-framework/havoc" ) -func rebootCLNamespace(delay time.Duration, namespace string) (*k8schaos.Chaos, error) { - k8sClient, err := k8schaos.NewChaosMeshClient() +func rebootCLNamespace(delay time.Duration, namespace string) (*havoc.Chaos, error) { + k8sClient, err := havoc.NewChaosMeshClient() if err != nil { return nil, err } - return k8schaos.NewChaos(k8schaos.ChaosOpts{ + return havoc.NewChaos(havoc.ChaosOpts{ Description: "Reboot CRIB", DelayCreate: delay, Object: &v1alpha1.PodChaos{ @@ -40,6 +41,6 @@ func rebootCLNamespace(delay time.Duration, namespace string) (*k8schaos.Chaos, }, }, Client: k8sClient, - Logger: &k8schaos.Logger, + Logger: &havoc.Logger, }) } diff --git a/integration-tests/crib/ocr_test.go b/integration-tests/crib/ocr_test.go index 91a7a1d76b..0b7c38597c 100644 --- a/integration-tests/crib/ocr_test.go +++ b/integration-tests/crib/ocr_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/smartcontractkit/havoc/k8schaos" + "github.com/smartcontractkit/chainlink-testing-framework/havoc" "github.com/stretchr/testify/require" @@ -40,7 +40,7 @@ func TestCRIB(t *testing.T) { os.Getenv("CRIB_NAMESPACE"), ) ch.Create(context.Background()) - ch.AddListener(k8schaos.NewChaosLogger(l)) + ch.AddListener(havoc.NewChaosLogger(l)) t.Cleanup(func() { err := ch.Delete(context.Background()) require.NoError(t, err) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 260e9bef1d..eeb91617a4 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -11,10 +11,10 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 github.com/avast/retry-go/v4 v4.6.0 github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df - github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f + github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a github.com/cli/go-gh/v2 v2.0.0 github.com/ethereum/go-ethereum v1.13.8 - github.com/fxamacker/cbor/v2 v2.6.0 + github.com/fxamacker/cbor/v2 v2.7.0 github.com/go-resty/resty/v2 v2.11.0 github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 @@ -26,7 +26,7 @@ require ( github.com/pelletier/go-toml/v2 v2.2.2 github.com/pkg/errors v0.9.1 github.com/prometheus/common v0.55.0 - github.com/rs/zerolog v1.31.0 + github.com/rs/zerolog v1.33.0 github.com/scylladb/go-reflectx v1.0.1 github.com/segmentio/ksuid v1.0.4 github.com/shopspring/decimal v1.4.0 @@ -34,14 +34,14 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 - github.com/smartcontractkit/chainlink-testing-framework v1.34.5 - github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 + github.com/smartcontractkit/chainlink-testing-framework v1.34.6 + github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 + github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 - github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/seth v1.1.2 github.com/smartcontractkit/wasp v0.4.5 - github.com/spf13/cobra v1.8.0 + github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 github.com/test-go/testify v1.1.4 github.com/testcontainers/testcontainers-go v0.28.0 @@ -54,7 +54,7 @@ require ( golang.org/x/sync v0.8.0 golang.org/x/text v0.17.0 gopkg.in/guregu/null.v4 v4.0.0 - k8s.io/apimachinery v0.28.2 + k8s.io/apimachinery v0.31.0 ) // avoids ambigious imports of indirect dependencies @@ -97,13 +97,28 @@ require ( github.com/avast/retry-go v3.0.0+incompatible // indirect github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect github.com/aws/aws-sdk-go v1.45.25 // indirect + github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect + github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.28 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 // indirect github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect github.com/aws/jsii-runtime-go v1.75.0 // indirect + github.com/aws/smithy-go v1.20.4 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect github.com/blendle/zapdriver v1.3.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/buger/jsonparser v1.1.1 // indirect @@ -168,15 +183,13 @@ require ( github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/esote/minmaxheap v1.0.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect - github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect github.com/fatih/camelcase v1.0.0 // indirect github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/fvbommel/sortorder v1.1.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/solana-go v1.8.4 // indirect @@ -229,7 +242,7 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect + github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/context v1.1.1 // indirect @@ -343,6 +356,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/mwitkow/grpc-proxy v0.0.0-20230212185441-f345521cb9c9 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/oklog/run v1.1.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect @@ -428,10 +442,10 @@ require ( github.com/zondax/ledger-go v0.14.1 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect - go.etcd.io/bbolt v1.3.8 // indirect - go.etcd.io/etcd/api/v3 v3.5.10 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect - go.etcd.io/etcd/client/v3 v3.5.10 // indirect + go.etcd.io/bbolt v1.3.9 // indirect + go.etcd.io/etcd/api/v3 v3.5.14 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect + go.etcd.io/etcd/client/v3 v3.5.14 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 // indirect @@ -464,27 +478,28 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.28.2 // indirect - k8s.io/apiextensions-apiserver v0.28.2 // indirect - k8s.io/cli-runtime v0.28.2 // indirect - k8s.io/client-go v0.28.2 // indirect - k8s.io/component-base v0.28.2 // indirect + k8s.io/api v0.31.0 // indirect + k8s.io/apiextensions-apiserver v0.31.0 // indirect + k8s.io/cli-runtime v0.31.0 // indirect + k8s.io/client-go v0.31.0 // indirect + k8s.io/component-base v0.31.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect - k8s.io/kubectl v0.28.2 // indirect - k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect + k8s.io/kubectl v0.31.0 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect nhooyr.io/websocket v1.8.7 // indirect pgregory.net/rapid v0.5.5 // indirect rsc.io/tmplfunc v0.0.3 // indirect - sigs.k8s.io/controller-runtime v0.16.2 // indirect + sigs.k8s.io/controller-runtime v0.19.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect - sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/api v0.17.2 // indirect + sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/integration-tests/go.sum b/integration-tests/go.sum index be87459a24..fc2836ac78 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -216,10 +216,38 @@ github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8= +github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= +github.com/aws/aws-sdk-go-v2/config v1.27.28 h1:OTxWGW/91C61QlneCtnD62NLb4W616/NM1jA8LhJqbg= +github.com/aws/aws-sdk-go-v2/config v1.27.28/go.mod h1:uzVRVtJSU5EFv6Fu82AoVFKozJi2ZCY6WRCXj06rbvs= +github.com/aws/aws-sdk-go-v2/credentials v1.17.28 h1:m8+AHY/ND8CMHJnPoH7PJIRakWGa4gbfbxuY9TGTUXM= +github.com/aws/aws-sdk-go-v2/credentials v1.17.28/go.mod h1:6TF7dSc78ehD1SL6KpRIPKMA1GyyWflIkjqg+qmf4+c= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 h1:yjwoSyDZF8Jth+mUk5lSPJCkMC0lMy6FaCD51jm6ayE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12/go.mod h1:fuR57fAgMk7ot3WcNQfb6rSEn+SUffl7ri+aa8uKysI= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 h1:UDXu9dqpCZYonj7poM4kFISjzTdWI0v3WUusM+w+Gfc= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5/go.mod h1:5NPkI3RsTOhwz1CuG7VVSgJCm3CINKkoIaUbUZWQ67w= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.5/go.mod h1:ZeDX1SnKsVlejeuz41GiajjZpRSWR7/42q/EyA/QEiM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 h1:SKvPgvdvmiTWoi0GAJ7AsJfOz3ngVkD/ERbs5pUnHNI= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5/go.mod h1:20sz31hv/WsPa3HhU3hfrIet2kxM4Pe0r20eBZ20Tac= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 h1:iAckBT2OeEK/kBDyN/jDtpEExhjeeA/Im2q4X0rJZT8= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.4/go.mod h1:vmSqFK+BVIwVpDAGZB3CoCXHzurt4qBE8lf+I/kRTh0= github.com/aws/constructs-go/constructs/v10 v10.1.255 h1:5hARfEmhBqHSTQf/C3QLA3sWOxO2Dfja0iA1W7ZcI7g= github.com/aws/constructs-go/constructs/v10 v10.1.255/go.mod h1:DCdBSjN04Ck2pajCacTD4RKFqSA7Utya8d62XreYctI= github.com/aws/jsii-runtime-go v1.75.0 h1:NhpUfyiL7/wsRuUekFsz8FFBCYLfPD/l61kKg9kL/a4= github.com/aws/jsii-runtime-go v1.75.0/go.mod h1:TKCyrtM0pygEPo4rDZzbMSDNCDNTSYSN6/mGyHI6O3I= +github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= +github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= @@ -238,6 +266,8 @@ github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsy github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= @@ -279,8 +309,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= -github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f h1:onZ3oc6l1Gz8pVpQ0c1U1Cb11kIMoDb3xtEy/iZbYZM= -github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f/go.mod h1:x11iCbZV6hzzSQWMq610B6Wl5Lg1dhwqcVfeiWQQnQQ= +github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a h1:6Pg3a6j/41QDzH/oYcMLwwKsf3x/HXcu9W/dBaf2Hzs= +github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a/go.mod h1:x11iCbZV6hzzSQWMq610B6Wl5Lg1dhwqcVfeiWQQnQQ= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= @@ -390,8 +420,8 @@ github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHf github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= @@ -518,12 +548,10 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= -github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= -github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= -github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= @@ -587,8 +615,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -682,15 +710,12 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= -github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= -github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= -github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -807,8 +832,8 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= @@ -1152,6 +1177,8 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhn github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/linode/linodego v1.19.0 h1:n4WJrcr9+30e9JGZ6DI0nZbm5SdAj1kSwvvt/998YUw= github.com/linode/linodego v1.19.0/go.mod h1:XZFR+yJ9mm2kwf6itZ6SCpu+6w3KnIevV0Uu5HNWJgQ= +github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= +github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= @@ -1289,6 +1316,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= @@ -1313,8 +1342,8 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= -github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= @@ -1434,8 +1463,8 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= -github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -1502,16 +1531,16 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.5 h1:6itLSDW4NHDDNR+Y+Z8YDzxxCN9SjdKb6SmLCl0vTFM= -github.com/smartcontractkit/chainlink-testing-framework v1.34.5/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= +github.com/smartcontractkit/chainlink-testing-framework v1.34.6 h1:x6pdcJ1hcdRJEQxyQltSMbLs+g5ddRw1HOLuLOAnSaI= +github.com/smartcontractkit/chainlink-testing-framework v1.34.6/go.mod h1:tweBFcNZQpKfRtXDQBrvVRrnAmGclByiyuyF/qAU/Eo= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 h1:1/r1wQZ4TOFpZ13w94r7amdF096Z96RuEnkOmrz1BGE= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= +github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= +github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= -github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1:ZEhn2Yo1jY4hqy8nasDL4k4pNtopT3rS3Ap1GDb7ODc= -github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= github.com/smartcontractkit/seth v1.1.2 h1:98v9VUFUpNhU7UofeF/bGyUIVv9jnt+JlIE+I8mhX2c= @@ -1544,8 +1573,8 @@ github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cA github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -1707,14 +1736,14 @@ go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRL go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= -go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= -go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= -go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= -go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= -go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= -go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= +go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= +go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= +go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= +go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= +go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= +go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= +go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= +go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= @@ -2047,7 +2076,6 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2306,6 +2334,8 @@ gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= @@ -2350,26 +2380,26 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= -k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= -k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= -k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= -k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= -k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= -k8s.io/cli-runtime v0.28.2 h1:64meB2fDj10/ThIMEJLO29a1oujSm0GQmKzh1RtA/uk= -k8s.io/cli-runtime v0.28.2/go.mod h1:bTpGOvpdsPtDKoyfG4EG041WIyFZLV9qq4rPlkyYfDA= -k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= -k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= -k8s.io/component-base v0.28.2 h1:Yc1yU+6AQSlpJZyvehm/NkJBII72rzlEsd6MkBQ+G0E= -k8s.io/component-base v0.28.2/go.mod h1:4IuQPQviQCg3du4si8GpMrhAIegxpsgPngPRR/zWpzc= +k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= +k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= +k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= +k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= +k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc= +k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/cli-runtime v0.31.0 h1:V2Q1gj1u3/WfhD475HBQrIYsoryg/LrhhK4RwpN+DhA= +k8s.io/cli-runtime v0.31.0/go.mod h1:vg3H94wsubuvWfSmStDbekvbla5vFGC+zLWqcf+bGDw= +k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8= +k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= +k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs= +k8s.io/component-base v0.31.0/go.mod h1:TYVuzI1QmN4L5ItVdMSXKvH7/DtvIuas5/mm8YT3rTo= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f h1:2sXuKesAYbRHxL3aE2PN6zX/gcJr22cjrsej+W784Tc= k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= -k8s.io/kubectl v0.28.2 h1:fOWOtU6S0smdNjG1PB9WFbqEIMlkzU5ahyHkc7ESHgM= -k8s.io/kubectl v0.28.2/go.mod h1:6EQWTPySF1fn7yKoQZHYf9TPwIl2AygHEcJoxFekr64= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kubectl v0.31.0 h1:kANwAAPVY02r4U4jARP/C+Q1sssCcN/1p9Nk+7BQKVg= +k8s.io/kubectl v0.31.0/go.mod h1:pB47hhFypGsaHAPjlwrNbvhXgmuAr01ZBvAIIUaI8d4= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= @@ -2381,14 +2411,14 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= -sigs.k8s.io/controller-runtime v0.16.2 h1:mwXAVuEk3EQf478PQwQ48zGOXvW27UJc8NHktQVuIPU= -sigs.k8s.io/controller-runtime v0.16.2/go.mod h1:vpMu3LpI5sYWtujJOa2uPK61nB5rbwlN7BAB8aSLvGU= +sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= +sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= +sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= +sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0= +sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= +sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 8908d3f473..4cc2ab9e56 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -13,11 +13,11 @@ require ( github.com/go-resty/resty/v2 v2.11.0 github.com/pelletier/go-toml/v2 v2.2.2 github.com/pkg/errors v0.9.1 - github.com/rs/zerolog v1.31.0 + github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 - github.com/smartcontractkit/chainlink-testing-framework v1.34.5 + github.com/smartcontractkit/chainlink-testing-framework v1.34.6 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 @@ -36,12 +36,29 @@ require ( cosmossdk.io/errors v1.0.0 // indirect cosmossdk.io/math v1.0.1 // indirect github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect + github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect + github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.28 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 // indirect + github.com/aws/smithy-go v1.20.4 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - k8s.io/apimachinery v0.30.2 // indirect + github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + k8s.io/apimachinery v0.31.0 // indirect ) // avoids ambigious imports of indirect dependencies @@ -100,7 +117,7 @@ require ( github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f // indirect + github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect github.com/cockroachdb/errors v1.9.1 // indirect @@ -159,9 +176,9 @@ require ( github.com/fatih/camelcase v1.0.0 // indirect github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect - github.com/fxamacker/cbor/v2 v2.6.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/solana-go v1.8.4 // indirect @@ -214,7 +231,7 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect + github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/context v1.1.1 // indirect @@ -376,7 +393,6 @@ require ( github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a // indirect - github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.7.3 // indirect github.com/soheilhy/cmux v0.1.5 // indirect @@ -421,10 +437,10 @@ require ( github.com/zondax/ledger-go v0.14.1 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect - go.etcd.io/bbolt v1.3.8 // indirect - go.etcd.io/etcd/api/v3 v3.5.10 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect - go.etcd.io/etcd/client/v3 v3.5.10 // indirect + go.etcd.io/bbolt v1.3.9 // indirect + go.etcd.io/etcd/api/v3 v3.5.14 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect + go.etcd.io/etcd/client/v3 v3.5.14 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 // indirect @@ -469,22 +485,22 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.30.2 // indirect - k8s.io/apiextensions-apiserver v0.30.2 // indirect - k8s.io/cli-runtime v0.28.2 // indirect + k8s.io/api v0.31.0 // indirect + k8s.io/apiextensions-apiserver v0.31.0 // indirect + k8s.io/cli-runtime v0.31.0 // indirect k8s.io/client-go v1.5.2 // indirect - k8s.io/component-base v0.30.2 // indirect + k8s.io/component-base v0.31.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect - k8s.io/kubectl v0.28.2 // indirect - k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect + k8s.io/kubectl v0.31.0 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect nhooyr.io/websocket v1.8.7 // indirect pgregory.net/rapid v0.5.5 // indirect rsc.io/tmplfunc v0.0.3 // indirect - sigs.k8s.io/controller-runtime v0.18.4 // indirect + sigs.k8s.io/controller-runtime v0.19.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect - sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/api v0.17.2 // indirect + sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect; indirect nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index bf36247e5e..0e463efaa8 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -216,10 +216,38 @@ github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8= +github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= +github.com/aws/aws-sdk-go-v2/config v1.27.28 h1:OTxWGW/91C61QlneCtnD62NLb4W616/NM1jA8LhJqbg= +github.com/aws/aws-sdk-go-v2/config v1.27.28/go.mod h1:uzVRVtJSU5EFv6Fu82AoVFKozJi2ZCY6WRCXj06rbvs= +github.com/aws/aws-sdk-go-v2/credentials v1.17.28 h1:m8+AHY/ND8CMHJnPoH7PJIRakWGa4gbfbxuY9TGTUXM= +github.com/aws/aws-sdk-go-v2/credentials v1.17.28/go.mod h1:6TF7dSc78ehD1SL6KpRIPKMA1GyyWflIkjqg+qmf4+c= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 h1:yjwoSyDZF8Jth+mUk5lSPJCkMC0lMy6FaCD51jm6ayE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12/go.mod h1:fuR57fAgMk7ot3WcNQfb6rSEn+SUffl7ri+aa8uKysI= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 h1:UDXu9dqpCZYonj7poM4kFISjzTdWI0v3WUusM+w+Gfc= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5/go.mod h1:5NPkI3RsTOhwz1CuG7VVSgJCm3CINKkoIaUbUZWQ67w= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.5/go.mod h1:ZeDX1SnKsVlejeuz41GiajjZpRSWR7/42q/EyA/QEiM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 h1:SKvPgvdvmiTWoi0GAJ7AsJfOz3ngVkD/ERbs5pUnHNI= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5/go.mod h1:20sz31hv/WsPa3HhU3hfrIet2kxM4Pe0r20eBZ20Tac= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 h1:iAckBT2OeEK/kBDyN/jDtpEExhjeeA/Im2q4X0rJZT8= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.4/go.mod h1:vmSqFK+BVIwVpDAGZB3CoCXHzurt4qBE8lf+I/kRTh0= github.com/aws/constructs-go/constructs/v10 v10.1.255 h1:5hARfEmhBqHSTQf/C3QLA3sWOxO2Dfja0iA1W7ZcI7g= github.com/aws/constructs-go/constructs/v10 v10.1.255/go.mod h1:DCdBSjN04Ck2pajCacTD4RKFqSA7Utya8d62XreYctI= github.com/aws/jsii-runtime-go v1.75.0 h1:NhpUfyiL7/wsRuUekFsz8FFBCYLfPD/l61kKg9kL/a4= github.com/aws/jsii-runtime-go v1.75.0/go.mod h1:TKCyrtM0pygEPo4rDZzbMSDNCDNTSYSN6/mGyHI6O3I= +github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= +github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= @@ -238,6 +266,8 @@ github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsy github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= @@ -508,12 +538,12 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= -github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= -github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= @@ -672,15 +702,12 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= -github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= -github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= -github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -797,8 +824,8 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= @@ -1416,8 +1443,8 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= -github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -1484,16 +1511,16 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.5 h1:6itLSDW4NHDDNR+Y+Z8YDzxxCN9SjdKb6SmLCl0vTFM= -github.com/smartcontractkit/chainlink-testing-framework v1.34.5/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= +github.com/smartcontractkit/chainlink-testing-framework v1.34.6 h1:x6pdcJ1hcdRJEQxyQltSMbLs+g5ddRw1HOLuLOAnSaI= +github.com/smartcontractkit/chainlink-testing-framework v1.34.6/go.mod h1:tweBFcNZQpKfRtXDQBrvVRrnAmGclByiyuyF/qAU/Eo= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a h1:8GtvGJaGyKzx/ar1yX74GxrzIYWTZVTyv4pYB/1ln8w= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= +github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= +github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= -github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1:ZEhn2Yo1jY4hqy8nasDL4k4pNtopT3rS3Ap1GDb7ODc= -github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= github.com/smartcontractkit/seth v1.1.2 h1:98v9VUFUpNhU7UofeF/bGyUIVv9jnt+JlIE+I8mhX2c= @@ -1689,14 +1716,14 @@ go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRL go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= -go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= -go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= -go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= -go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= -go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= -go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= +go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= +go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= +go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= +go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= +go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= +go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= +go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= +go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= @@ -2027,7 +2054,6 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2286,6 +2312,8 @@ gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= @@ -2348,8 +2376,8 @@ k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f h1:2sXuKesAYbRHxL3aE2PN6z k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= k8s.io/kubectl v0.28.2 h1:fOWOtU6S0smdNjG1PB9WFbqEIMlkzU5ahyHkc7ESHgM= k8s.io/kubectl v0.28.2/go.mod h1:6EQWTPySF1fn7yKoQZHYf9TPwIl2AygHEcJoxFekr64= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= @@ -2365,10 +2393,10 @@ sigs.k8s.io/controller-runtime v0.16.2 h1:mwXAVuEk3EQf478PQwQ48zGOXvW27UJc8NHktQ sigs.k8s.io/controller-runtime v0.16.2/go.mod h1:vpMu3LpI5sYWtujJOa2uPK61nB5rbwlN7BAB8aSLvGU= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= +sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= +sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0= +sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= +sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= diff --git a/integration-tests/soak/ocr_test.go b/integration-tests/soak/ocr_test.go index d1440b7c3a..998af1da73 100644 --- a/integration-tests/soak/ocr_test.go +++ b/integration-tests/soak/ocr_test.go @@ -14,9 +14,10 @@ import ( "github.com/chaos-mesh/chaos-mesh/api/v1alpha1" "github.com/google/uuid" - "github.com/smartcontractkit/havoc/k8schaos" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/smartcontractkit/chainlink-testing-framework/havoc" + "github.com/smartcontractkit/chainlink-testing-framework/networks" "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" "github.com/smartcontractkit/chainlink/integration-tests/actions" @@ -100,7 +101,7 @@ func TestOCRSoak_RPCDownForAllCLNodes(t *testing.T) { require.NoError(t, err, "Error creating chaos") ocrSoakTest, err := testsetups.NewOCRSoakTest(t, &config, testsetups.WithNamespace(namespace), - testsetups.WithChaos([]*k8schaos.Chaos{chaos}), + testsetups.WithChaos([]*havoc.Chaos{chaos}), ) require.NoError(t, err, "Error creating OCR soak test") executeOCRSoakTest(t, ocrSoakTest, &config) @@ -133,7 +134,7 @@ func TestOCRSoak_RPCDownForHalfCLNodes(t *testing.T) { require.NoError(t, err, "Error creating chaos") ocrSoakTest, err := testsetups.NewOCRSoakTest(t, &config, testsetups.WithNamespace(namespace), - testsetups.WithChaos([]*k8schaos.Chaos{chaos}), + testsetups.WithChaos([]*havoc.Chaos{chaos}), ) require.NoError(t, err, "Error creating OCR soak test") executeOCRSoakTest(t, ocrSoakTest, &config) @@ -186,12 +187,12 @@ type GethNetworkDownChaosOpts struct { Duration time.Duration } -func gethNetworkDownChaos(opts GethNetworkDownChaosOpts) (*k8schaos.Chaos, error) { - k8sClient, err := k8schaos.NewChaosMeshClient() +func gethNetworkDownChaos(opts GethNetworkDownChaosOpts) (*havoc.Chaos, error) { + k8sClient, err := havoc.NewChaosMeshClient() if err != nil { return nil, err } - return k8schaos.NewChaos(k8schaos.ChaosOpts{ + return havoc.NewChaos(havoc.ChaosOpts{ Description: opts.Description, DelayCreate: opts.DelayCreate, Object: &v1alpha1.NetworkChaos{ @@ -225,7 +226,7 @@ func gethNetworkDownChaos(opts GethNetworkDownChaosOpts) (*k8schaos.Chaos, error }, }, Client: k8sClient, - Logger: &k8schaos.Logger, + Logger: &havoc.Logger, }) } diff --git a/integration-tests/testsetups/ocr.go b/integration-tests/testsetups/ocr.go index 084ea5eca1..ff6ce5749a 100644 --- a/integration-tests/testsetups/ocr.go +++ b/integration-tests/testsetups/ocr.go @@ -29,7 +29,7 @@ import ( "github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" - "github.com/smartcontractkit/havoc/k8schaos" + "github.com/smartcontractkit/chainlink-testing-framework/havoc" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" ctf_client "github.com/smartcontractkit/chainlink-testing-framework/client" @@ -91,12 +91,12 @@ type OCRSoakTest struct { reorgHappened bool // flag to indicate if a reorg happened during the test gasSpikeSimulationHappened bool // flag to indicate if a gas spike simulation happened during the test gasLimitSimulationHappened bool // flag to indicate if a gas limit simulation happened during the test - chaosList []*k8schaos.Chaos // list of chaos simulations to run during the test + chaosList []*havoc.Chaos // list of chaos simulations to run during the test } type OCRSoakTestOption = func(c *OCRSoakTest) -func WithChaos(chaosList []*k8schaos.Chaos) OCRSoakTestOption { +func WithChaos(chaosList []*havoc.Chaos) OCRSoakTestOption { return func(c *OCRSoakTest) { c.chaosList = chaosList } @@ -679,11 +679,11 @@ func (o *OCRSoakTest) testLoop(testDuration time.Duration, newValue int) { if len(o.chaosList) > 0 { for _, chaos := range o.chaosList { chaos.Create(context.Background()) - chaos.AddListener(k8schaos.NewChaosLogger(o.log)) + chaos.AddListener(havoc.NewChaosLogger(o.log)) chaos.AddListener(ocrTestChaosListener{t: o.t}) // Add Grafana annotation if configured if o.Config.Logging.Grafana != nil && o.Config.Logging.Grafana.BaseUrl != nil && o.Config.Logging.Grafana.BearerToken != nil && o.Config.Logging.Grafana.DashboardUID != nil { - chaos.AddListener(k8schaos.NewSingleLineGrafanaAnnotator(*o.Config.Logging.Grafana.BaseUrl, *o.Config.Logging.Grafana.BearerToken, *o.Config.Logging.Grafana.DashboardUID, o.log)) + chaos.AddListener(havoc.NewSingleLineGrafanaAnnotator(*o.Config.Logging.Grafana.BaseUrl, *o.Config.Logging.Grafana.BearerToken, *o.Config.Logging.Grafana.DashboardUID, o.log)) } else { o.log.Warn().Msg("Skipping Grafana annotation for chaos simulation. Grafana config is missing either BearerToken, BaseUrl or DashboardUID") } @@ -1108,28 +1108,28 @@ type ocrTestChaosListener struct { t *testing.T } -func (l ocrTestChaosListener) OnChaosCreated(_ k8schaos.Chaos) { +func (l ocrTestChaosListener) OnChaosCreated(_ havoc.Chaos) { } -func (l ocrTestChaosListener) OnChaosCreationFailed(chaos k8schaos.Chaos, reason error) { +func (l ocrTestChaosListener) OnChaosCreationFailed(chaos havoc.Chaos, reason error) { // Fail the test if chaos creation fails during chaos simulation require.FailNow(l.t, "Error creating chaos simulation", reason.Error(), chaos) } -func (l ocrTestChaosListener) OnChaosStarted(_ k8schaos.Chaos) { +func (l ocrTestChaosListener) OnChaosStarted(_ havoc.Chaos) { } -func (l ocrTestChaosListener) OnChaosPaused(_ k8schaos.Chaos) { +func (l ocrTestChaosListener) OnChaosPaused(_ havoc.Chaos) { } -func (l ocrTestChaosListener) OnChaosEnded(_ k8schaos.Chaos) { +func (l ocrTestChaosListener) OnChaosEnded(_ havoc.Chaos) { } -func (l ocrTestChaosListener) OnChaosStatusUnknown(_ k8schaos.Chaos) { +func (l ocrTestChaosListener) OnChaosStatusUnknown(_ havoc.Chaos) { } -func (l ocrTestChaosListener) OnScheduleCreated(_ k8schaos.Schedule) { +func (l ocrTestChaosListener) OnScheduleCreated(_ havoc.Schedule) { } -func (l ocrTestChaosListener) OnScheduleDeleted(_ k8schaos.Schedule) { +func (l ocrTestChaosListener) OnScheduleDeleted(_ havoc.Schedule) { } From 908e96c0751b019161eb364ff9589dbd4d5e5ff7 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:53:18 +0200 Subject: [PATCH 147/432] Move long running CCIP tests to nightly tests (#14204) --- .github/e2e-tests.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 7b4a2b97eb..3e1fd06b87 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -938,7 +938,6 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPOffRampCapacityLimit$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -949,7 +948,6 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPOffRampAggRateLimit$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: From 621e87538c931d5d3996974589dc27a0ab43f758 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata <96521086+bukata-sa@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:57:21 +0100 Subject: [PATCH 148/432] fix: non-zero default period (#14206) * fix: non-zero default period * Update eight-bees-speak.md --- .changeset/eight-bees-speak.md | 5 +++++ core/services/headreporter/head_reporter.go | 11 ++++++----- core/services/headreporter/head_reporter_test.go | 6 ++++++ 3 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 .changeset/eight-bees-speak.md diff --git a/.changeset/eight-bees-speak.md b/.changeset/eight-bees-speak.md new file mode 100644 index 0000000000..9c8ebe428d --- /dev/null +++ b/.changeset/eight-bees-speak.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#bugfix head reporter non-zero reporting period diff --git a/core/services/headreporter/head_reporter.go b/core/services/headreporter/head_reporter.go index f81a6acf91..94de8ae2be 100644 --- a/core/services/headreporter/head_reporter.go +++ b/core/services/headreporter/head_reporter.go @@ -35,11 +35,12 @@ type ( func NewHeadReporterService(ds sqlutil.DataSource, lggr logger.Logger, reporters ...HeadReporter) *HeadReporterService { return &HeadReporterService{ - ds: ds, - lggr: lggr.Named("HeadReporter"), - newHeads: mailbox.NewSingle[*evmtypes.Head](), - chStop: make(chan struct{}), - reporters: reporters, + ds: ds, + lggr: lggr.Named("HeadReporter"), + newHeads: mailbox.NewSingle[*evmtypes.Head](), + chStop: make(chan struct{}), + reporters: reporters, + reportPeriod: 15 * time.Second, } } diff --git a/core/services/headreporter/head_reporter_test.go b/core/services/headreporter/head_reporter_test.go index ded7e1fb61..304dd59a47 100644 --- a/core/services/headreporter/head_reporter_test.go +++ b/core/services/headreporter/head_reporter_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -42,4 +43,9 @@ func Test_HeadReporterService(t *testing.T) { require.Eventually(t, func() bool { return reportCalls.Load() == 2 }, 5*time.Second, 100*time.Millisecond) }) + + t.Run("has default report period", func(t *testing.T) { + service := NewHeadReporterService(pgtest.NewSqlxDB(t), logger.TestLogger(t), NewMockHeadReporter(t)) + assert.Equal(t, service.reportPeriod, 15*time.Second) + }) } From c98feb205d5eef64d71c42b43516a87b83796a1d Mon Sep 17 00:00:00 2001 From: Matthew Romage <33700623+ma33r@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:31:00 -0400 Subject: [PATCH 149/432] Changed Optimism L1 Oracle to support Mantle (#14160) * edited op stack oracle to include tokenRatio for Mantle * typo fix * fixed syntax errors * fixed compilation errors in test * added unit tests for Mantle oracle changes * typo fix * added changeset file * added hashtag to changeset * changed unit test to include new chaintype * changed test to include new chaintype * typo fix * addressed alphabetical order and error issues * used batch call instead of separate calls for L1 Base Fee * added test cases for RPC errors to Mantle --- .changeset/two-mugs-complain.md | 5 ++ core/chains/evm/config/chaintype/chaintype.go | 6 +- core/chains/evm/gas/rollups/l1_oracle.go | 4 +- core/chains/evm/gas/rollups/l1_oracle_abi.go | 1 + core/chains/evm/gas/rollups/op_l1_oracle.go | 87 +++++++++++++++++- .../evm/gas/rollups/op_l1_oracle_test.go | 88 +++++++++++++++++++ core/services/chainlink/config_test.go | 4 +- 7 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 .changeset/two-mugs-complain.md diff --git a/.changeset/two-mugs-complain.md b/.changeset/two-mugs-complain.md new file mode 100644 index 0000000000..77cdcbfe9e --- /dev/null +++ b/.changeset/two-mugs-complain.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Edited the Optimism Stack L1 Oracle to add support for Mantle #added diff --git a/core/chains/evm/config/chaintype/chaintype.go b/core/chains/evm/config/chaintype/chaintype.go index 07ea620624..35dd214b1f 100644 --- a/core/chains/evm/config/chaintype/chaintype.go +++ b/core/chains/evm/config/chaintype/chaintype.go @@ -14,6 +14,7 @@ const ( ChainGnosis ChainType = "gnosis" ChainHedera ChainType = "hedera" ChainKroma ChainType = "kroma" + ChainMantle ChainType = "mantle" ChainMetis ChainType = "metis" ChainOptimismBedrock ChainType = "optimismBedrock" ChainScroll ChainType = "scroll" @@ -37,7 +38,7 @@ func (c ChainType) IsL2() bool { func (c ChainType) IsValid() bool { switch c { - case "", ChainArbitrum, ChainAstar, ChainCelo, ChainGnosis, ChainHedera, ChainKroma, ChainMetis, ChainOptimismBedrock, ChainScroll, ChainWeMix, ChainXLayer, ChainZkEvm, ChainZkSync: + case "", ChainArbitrum, ChainAstar, ChainCelo, ChainGnosis, ChainHedera, ChainKroma, ChainMantle, ChainMetis, ChainOptimismBedrock, ChainScroll, ChainWeMix, ChainXLayer, ChainZkEvm, ChainZkSync: return true } return false @@ -57,6 +58,8 @@ func ChainTypeFromSlug(slug string) ChainType { return ChainHedera case "kroma": return ChainKroma + case "mantle": + return ChainMantle case "metis": return ChainMetis case "optimismBedrock": @@ -129,6 +132,7 @@ var ErrInvalidChainType = fmt.Errorf("must be one of %s or omitted", strings.Joi string(ChainGnosis), string(ChainHedera), string(ChainKroma), + string(ChainMantle), string(ChainMetis), string(ChainOptimismBedrock), string(ChainScroll), diff --git a/core/chains/evm/gas/rollups/l1_oracle.go b/core/chains/evm/gas/rollups/l1_oracle.go index f707fab684..e1249fdb7e 100644 --- a/core/chains/evm/gas/rollups/l1_oracle.go +++ b/core/chains/evm/gas/rollups/l1_oracle.go @@ -43,7 +43,7 @@ const ( PollPeriod = 6 * time.Second ) -var supportedChainTypes = []chaintype.ChainType{chaintype.ChainArbitrum, chaintype.ChainOptimismBedrock, chaintype.ChainKroma, chaintype.ChainScroll, chaintype.ChainZkSync} +var supportedChainTypes = []chaintype.ChainType{chaintype.ChainArbitrum, chaintype.ChainOptimismBedrock, chaintype.ChainKroma, chaintype.ChainScroll, chaintype.ChainZkSync, chaintype.ChainMantle} func IsRollupWithL1Support(chainType chaintype.ChainType) bool { return slices.Contains(supportedChainTypes, chainType) @@ -56,7 +56,7 @@ func NewL1GasOracle(lggr logger.Logger, ethClient l1OracleClient, chainType chai var l1Oracle L1Oracle var err error switch chainType { - case chaintype.ChainOptimismBedrock, chaintype.ChainKroma, chaintype.ChainScroll: + case chaintype.ChainOptimismBedrock, chaintype.ChainKroma, chaintype.ChainScroll, chaintype.ChainMantle: l1Oracle, err = NewOpStackL1GasOracle(lggr, ethClient, chainType) case chaintype.ChainArbitrum: l1Oracle, err = NewArbitrumL1GasOracle(lggr, ethClient) diff --git a/core/chains/evm/gas/rollups/l1_oracle_abi.go b/core/chains/evm/gas/rollups/l1_oracle_abi.go index fa5d9c8539..848957ce53 100644 --- a/core/chains/evm/gas/rollups/l1_oracle_abi.go +++ b/core/chains/evm/gas/rollups/l1_oracle_abi.go @@ -19,3 +19,4 @@ const OPBaseFeeScalarAbiString = `[{"inputs":[],"name":"baseFeeScalar","outputs" const OPBlobBaseFeeAbiString = `[{"inputs":[],"name":"blobBaseFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]` const OPBlobBaseFeeScalarAbiString = `[{"inputs":[],"name":"blobBaseFeeScalar","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"}]` const OPDecimalsAbiString = `[{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}]` +const MantleTokenRatioAbiString = `[{"inputs":[],"name":"tokenRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]` diff --git a/core/chains/evm/gas/rollups/op_l1_oracle.go b/core/chains/evm/gas/rollups/op_l1_oracle.go index 6805cd7095..1b93f8fc3f 100644 --- a/core/chains/evm/gas/rollups/op_l1_oracle.go +++ b/core/chains/evm/gas/rollups/op_l1_oracle.go @@ -50,6 +50,7 @@ type optimismL1Oracle struct { blobBaseFeeCalldata []byte blobBaseFeeScalarCalldata []byte decimalsCalldata []byte + tokenRatioCalldata []byte isEcotoneCalldata []byte isEcotoneMethodAbi abi.ABI isFjordCalldata []byte @@ -87,7 +88,11 @@ const ( // decimals is a hex encoded call to: // `function decimals() public pure returns (uint256);` decimalsMethod = "decimals" - // OPGasOracleAddress is the address of the precompiled contract that exists on Optimism and Base. + // tokenRatio fetches the tokenRatio used for Mantle's gas price calculation + // tokenRatio is a hex encoded call to: + // `function tokenRatio() public pure returns (uint256);` + tokenRatioMethod = "tokenRatio" + // OPGasOracleAddress is the address of the precompiled contract that exists on Optimism, Base and Mantle. OPGasOracleAddress = "0x420000000000000000000000000000000000000F" // KromaGasOracleAddress is the address of the precompiled contract that exists on Kroma. KromaGasOracleAddress = "0x4200000000000000000000000000000000000005" @@ -98,7 +103,7 @@ const ( func NewOpStackL1GasOracle(lggr logger.Logger, ethClient l1OracleClient, chainType chaintype.ChainType) (*optimismL1Oracle, error) { var precompileAddress string switch chainType { - case chaintype.ChainOptimismBedrock: + case chaintype.ChainOptimismBedrock, chaintype.ChainMantle: precompileAddress = OPGasOracleAddress case chaintype.ChainKroma: precompileAddress = KromaGasOracleAddress @@ -187,6 +192,16 @@ func newOpStackL1GasOracle(lggr logger.Logger, ethClient l1OracleClient, chainTy return nil, fmt.Errorf("failed to parse GasPriceOracle %s() calldata for chain: %s; %w", decimalsMethod, chainType, err) } + // Encode calldata for tokenRatio method + tokenRatioMethodAbi, err := abi.JSON(strings.NewReader(MantleTokenRatioAbiString)) + if err != nil { + return nil, fmt.Errorf("failed to parse GasPriceOracle %s() method ABI for chain: %s; %w", tokenRatioMethod, chainType, err) + } + tokenRatioCalldata, err := tokenRatioMethodAbi.Pack(tokenRatioMethod) + if err != nil { + return nil, fmt.Errorf("failed to parse GasPriceOracle %s() calldata for chain: %s; %w", tokenRatioMethod, chainType, err) + } + return &optimismL1Oracle{ client: ethClient, pollPeriod: PollPeriod, @@ -208,6 +223,7 @@ func newOpStackL1GasOracle(lggr logger.Logger, ethClient l1OracleClient, chainTy blobBaseFeeCalldata: blobBaseFeeCalldata, blobBaseFeeScalarCalldata: blobBaseFeeScalarCalldata, decimalsCalldata: decimalsCalldata, + tokenRatioCalldata: tokenRatioCalldata, isEcotoneCalldata: isEcotoneCalldata, isEcotoneMethodAbi: isEcotoneMethodAbi, isFjordCalldata: isFjordCalldata, @@ -346,6 +362,10 @@ func (o *optimismL1Oracle) GetGasCost(ctx context.Context, tx *gethtypes.Transac } func (o *optimismL1Oracle) GetDAGasPrice(ctx context.Context) (*big.Int, error) { + if o.chainType == chaintype.ChainMantle { + return o.getMantleGasPrice(ctx) + } + err := o.checkForUpgrade(ctx) if err != nil { return nil, err @@ -443,6 +463,69 @@ func (o *optimismL1Oracle) getV1GasPrice(ctx context.Context) (*big.Int, error) return new(big.Int).SetBytes(b), nil } +// Returns the gas price for Mantle. The formula is the same as Optimism Bedrock (getV1GasPrice), but the tokenRatio parameter is multiplied +func (o *optimismL1Oracle) getMantleGasPrice(ctx context.Context) (*big.Int, error) { + // call oracle to get l1BaseFee and tokenRatio + rpcBatchCalls := []rpc.BatchElem{ + { + Method: "eth_call", + Args: []any{ + map[string]interface{}{ + "from": common.Address{}, + "to": o.l1OracleAddress, + "data": hexutil.Bytes(o.l1BaseFeeCalldata), + }, + "latest", + }, + Result: new(string), + }, + { + Method: "eth_call", + Args: []any{ + map[string]interface{}{ + "from": common.Address{}, + "to": o.l1OracleAddress, + "data": hexutil.Bytes(o.tokenRatioCalldata), + }, + "latest", + }, + Result: new(string), + }, + } + + err := o.client.BatchCallContext(ctx, rpcBatchCalls) + if err != nil { + return nil, fmt.Errorf("fetch gas price parameters batch call failed: %w", err) + } + if rpcBatchCalls[0].Error != nil { + return nil, fmt.Errorf("%s call failed in a batch: %w", l1BaseFeeMethod, err) + } + if rpcBatchCalls[1].Error != nil { + return nil, fmt.Errorf("%s call failed in a batch: %w", tokenRatioMethod, err) + } + + // Extract values from responses + l1BaseFeeResult := *(rpcBatchCalls[0].Result.(*string)) + tokenRatioResult := *(rpcBatchCalls[1].Result.(*string)) + + // Decode the responses into bytes + l1BaseFeeBytes, err := hexutil.Decode(l1BaseFeeResult) + if err != nil { + return nil, fmt.Errorf("failed to decode %s rpc result: %w", l1BaseFeeMethod, err) + } + tokenRatioBytes, err := hexutil.Decode(tokenRatioResult) + if err != nil { + return nil, fmt.Errorf("failed to decode %s rpc result: %w", tokenRatioMethod, err) + } + + // Convert bytes to big int for calculations + l1BaseFee := new(big.Int).SetBytes(l1BaseFeeBytes) + tokenRatio := new(big.Int).SetBytes(tokenRatioBytes) + + // multiply l1BaseFee and tokenRatio and return + return new(big.Int).Mul(l1BaseFee, tokenRatio), nil +} + // Returns the scaled gas price using baseFeeScalar, l1BaseFee, blobBaseFeeScalar, and blobBaseFee fields from the oracle // Confirmed the same calculation is used to determine gas price for both Ecotone and Fjord func (o *optimismL1Oracle) getEcotoneFjordGasPrice(ctx context.Context) (*big.Int, error) { diff --git a/core/chains/evm/gas/rollups/op_l1_oracle_test.go b/core/chains/evm/gas/rollups/op_l1_oracle_test.go index f5f009f1ea..88bb96534d 100644 --- a/core/chains/evm/gas/rollups/op_l1_oracle_test.go +++ b/core/chains/evm/gas/rollups/op_l1_oracle_test.go @@ -111,6 +111,94 @@ func TestOPL1Oracle_ReadV1GasPrice(t *testing.T) { } } +func TestOPL1Oracle_ReadMantleGasPrice(t *testing.T) { + l1BaseFee := big.NewInt(100) + tokenRatio := big.NewInt(40) + oracleAddress := common.HexToAddress("0x1234").String() + + t.Parallel() + t.Run("correctly fetches gas price if chain is Mantle", func(t *testing.T) { + // Encode calldata for l1BaseFee method + l1BaseFeeMethodAbi, err := abi.JSON(strings.NewReader(L1BaseFeeAbiString)) + require.NoError(t, err) + l1BaseFeeCalldata, err := l1BaseFeeMethodAbi.Pack(l1BaseFeeMethod) + require.NoError(t, err) + + // Encode calldata for tokenRatio method + tokenRatioMethodAbi, err := abi.JSON(strings.NewReader(MantleTokenRatioAbiString)) + require.NoError(t, err) + tokenRatioCalldata, err := tokenRatioMethodAbi.Pack(tokenRatioMethod) + require.NoError(t, err) + + ethClient := mocks.NewL1OracleClient(t) + ethClient.On("BatchCallContext", mock.Anything, mock.IsType([]rpc.BatchElem{})).Run(func(args mock.Arguments) { + rpcElements := args.Get(1).([]rpc.BatchElem) + require.Equal(t, 2, len(rpcElements)) + for _, rE := range rpcElements { + require.Equal(t, "eth_call", rE.Method) + require.Equal(t, oracleAddress, rE.Args[0].(map[string]interface{})["to"]) + require.Equal(t, "latest", rE.Args[1]) + } + require.Equal(t, hexutil.Bytes(l1BaseFeeCalldata), rpcElements[0].Args[0].(map[string]interface{})["data"]) + require.Equal(t, hexutil.Bytes(tokenRatioCalldata), rpcElements[1].Args[0].(map[string]interface{})["data"]) + + res1 := common.BigToHash(l1BaseFee).Hex() + res2 := common.BigToHash(tokenRatio).Hex() + + rpcElements[0].Result = &res1 + rpcElements[1].Result = &res2 + }).Return(nil).Once() + + oracle, err := newOpStackL1GasOracle(logger.Test(t), ethClient, chaintype.ChainMantle, oracleAddress) + require.NoError(t, err) + + gasPrice, err := oracle.GetDAGasPrice(tests.Context(t)) + require.NoError(t, err) + + assert.Equal(t, new(big.Int).Mul(l1BaseFee, tokenRatio), gasPrice) + }) + + t.Run("fetching Mantle price but rpc returns bad data", func(t *testing.T) { + ethClient := mocks.NewL1OracleClient(t) + ethClient.On("BatchCallContext", mock.Anything, mock.IsType([]rpc.BatchElem{})).Run(func(args mock.Arguments) { + rpcElements := args.Get(1).([]rpc.BatchElem) + var badData = "zzz" + rpcElements[0].Result = &badData + rpcElements[1].Result = &badData + }).Return(nil).Once() + + oracle, err := newOpStackL1GasOracle(logger.Test(t), ethClient, chaintype.ChainMantle, oracleAddress) + require.NoError(t, err) + _, err = oracle.GetDAGasPrice(tests.Context(t)) + assert.Error(t, err) + }) + + t.Run("fetching Mantle price but rpc parent call errors", func(t *testing.T) { + ethClient := mocks.NewL1OracleClient(t) + ethClient.On("BatchCallContext", mock.Anything, mock.IsType([]rpc.BatchElem{})).Return(fmt.Errorf("revert")).Once() + + oracle, err := newOpStackL1GasOracle(logger.Test(t), ethClient, chaintype.ChainMantle, oracleAddress) + require.NoError(t, err) + _, err = oracle.GetDAGasPrice(tests.Context(t)) + assert.Error(t, err) + }) + + t.Run("fetching Mantle price but one of the sub rpc call errors", func(t *testing.T) { + ethClient := mocks.NewL1OracleClient(t) + ethClient.On("BatchCallContext", mock.Anything, mock.IsType([]rpc.BatchElem{})).Run(func(args mock.Arguments) { + rpcElements := args.Get(1).([]rpc.BatchElem) + res := common.BigToHash(l1BaseFee).Hex() + rpcElements[0].Result = &res + rpcElements[1].Error = fmt.Errorf("revert") + }).Return(nil).Once() + + oracle, err := newOpStackL1GasOracle(logger.Test(t), ethClient, chaintype.ChainMantle, oracleAddress) + require.NoError(t, err) + _, err = oracle.GetDAGasPrice(tests.Context(t)) + assert.Error(t, err) + }) +} + func setupUpgradeCheck(t *testing.T, oracleAddress string, isFjord, isEcotone bool) *mocks.L1OracleClient { trueHex := "0x0000000000000000000000000000000000000000000000000000000000000001" falseHex := "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 5fc9babe77..b9d7921d78 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -1304,7 +1304,7 @@ func TestConfig_Validate(t *testing.T) { - 1: 10 errors: - ChainType: invalid value (Foo): must not be set with this chain id - Nodes: missing: must have at least one node - - ChainType: invalid value (Foo): must be one of arbitrum, astar, celo, gnosis, hedera, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync or omitted + - ChainType: invalid value (Foo): must be one of arbitrum, astar, celo, gnosis, hedera, kroma, mantle, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync or omitted - HeadTracker.HistoryDepth: invalid value (30): must be greater than or equal to FinalizedBlockOffset - GasEstimator.BumpThreshold: invalid value (0): cannot be 0 if auto-purge feature is enabled for Foo - Transactions.AutoPurge.Threshold: missing: needs to be set if auto-purge feature is enabled for Foo @@ -1317,7 +1317,7 @@ func TestConfig_Validate(t *testing.T) { - 2: 5 errors: - ChainType: invalid value (Arbitrum): only "optimismBedrock" can be used with this chain id - Nodes: missing: must have at least one node - - ChainType: invalid value (Arbitrum): must be one of arbitrum, astar, celo, gnosis, hedera, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync or omitted + - ChainType: invalid value (Arbitrum): must be one of arbitrum, astar, celo, gnosis, hedera, kroma, mantle, metis, optimismBedrock, scroll, wemix, xlayer, zkevm, zksync or omitted - FinalityDepth: invalid value (0): must be greater than or equal to 1 - MinIncomingConfirmations: invalid value (0): must be greater than or equal to 1 - 3.Nodes: 5 errors: From 8d818ea265ff08887e61ace4f83364a3ee149ef0 Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:15:45 -0500 Subject: [PATCH 150/432] Gas limit estimation feature (#14041) * Added gas limit estimation feature to EVM gas estimators * Added changeset * Fixed linting * Added new failure tests * Fixed test * Fixed mock configs in ccip capabilities * Fixed configs * Fixed test * Refactored GetFee method * Added EstimatedGasBuffer and addressed feedback * Fixed linting * Fixed config doc and tests * Addressed feedback * Fixed typo * Repurposed LimitMultiplier to be used as a buffer for estimated gas * Updated mocks * Removed LimitMultiplier if gas estimation fails and updated config docs * Fixed Broadcaster test * Enabled uncapped gas limit estimation if provided fee limit is 0 * Updated estimate gas buffer to be a fixed value instead of using LimitMultiplier * Updated log message * Updated logs --------- Co-authored-by: Prashant Yadav <34992934+prashantkumar1982@users.noreply.github.com> --- .changeset/loud-windows-call.md | 5 + common/fee/models.go | 1 + common/txmgr/broadcaster.go | 7 +- .../ocrimpls/contract_transmitter_test.go | 1 + .../evm/config/chain_scoped_gas_estimator.go | 4 + core/chains/evm/config/config.go | 1 + core/chains/evm/config/mocks/gas_estimator.go | 45 ++++ core/chains/evm/config/toml/config.go | 14 +- .../evm/config/toml/defaults/fallback.toml | 1 + core/chains/evm/gas/helpers_test.go | 5 + .../chains/evm/gas/mocks/evm_fee_estimator.go | 76 +++---- .../evm/gas/mocks/fee_estimator_client.go | 57 +++++ core/chains/evm/gas/models.go | 89 ++++++-- core/chains/evm/gas/models_test.go | 199 ++++++++++++++++-- core/chains/evm/txmgr/attempts.go | 6 +- core/chains/evm/txmgr/attempts_test.go | 2 +- core/chains/evm/txmgr/broadcaster_test.go | 81 ++++++- core/chains/evm/txmgr/confirmer_test.go | 10 +- core/chains/evm/txmgr/stuck_tx_detector.go | 4 +- .../evm/txmgr/stuck_tx_detector_test.go | 4 +- core/chains/evm/txmgr/test_helpers.go | 1 + core/config/docs/chains-evm.toml | 2 + core/internal/features/features_test.go | 4 +- core/services/chainlink/config_test.go | 2 + .../chainlink/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 3 + core/services/keeper/upkeep_executer_test.go | 2 +- .../ccipdata/commit_store_reader_test.go | 2 +- .../ccip/prices/exec_price_estimator.go | 2 +- .../ccip/prices/exec_price_estimator_test.go | 3 +- .../evmregistry/v21/gasprice/gasprice.go | 2 +- .../evmregistry/v21/gasprice/gasprice_test.go | 6 +- core/services/relay/evm/chain_writer.go | 2 +- core/services/relay/evm/chain_writer_test.go | 10 +- core/web/evm_transfer_controller.go | 6 +- core/web/resolver/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 3 + docs/CONFIG.md | 68 ++++++ .../disk-based-logging-disabled.txtar | 1 + .../validate/disk-based-logging-no-dir.txtar | 1 + .../node/validate/disk-based-logging.txtar | 1 + testdata/scripts/node/validate/invalid.txtar | 1 + testdata/scripts/node/validate/valid.txtar | 1 + 43 files changed, 621 insertions(+), 116 deletions(-) create mode 100644 .changeset/loud-windows-call.md diff --git a/.changeset/loud-windows-call.md b/.changeset/loud-windows-call.md new file mode 100644 index 0000000000..e05bed706a --- /dev/null +++ b/.changeset/loud-windows-call.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Added gas limit estimation feature to EVM gas estimators #added diff --git a/common/fee/models.go b/common/fee/models.go index 0568a2f143..0496d3929c 100644 --- a/common/fee/models.go +++ b/common/fee/models.go @@ -14,6 +14,7 @@ var ( ErrBumpFeeExceedsLimit = errors.New("fee bump exceeds limit") ErrBump = errors.New("fee bump failed") ErrConnectivity = errors.New("transaction propagation issue: transactions are not being mined") + ErrFeeLimitTooLow = errors.New("provided fee limit too low") ) func IsBumpErr(err error) bool { diff --git a/common/txmgr/broadcaster.go b/common/txmgr/broadcaster.go index be3d3ca2f6..1606f58ce0 100644 --- a/common/txmgr/broadcaster.go +++ b/common/txmgr/broadcaster.go @@ -20,6 +20,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/common/client" + commonfee "github.com/smartcontractkit/chainlink/v2/common/fee" feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types" txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" "github.com/smartcontractkit/chainlink/v2/common/types" @@ -434,7 +435,11 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand } attempt, _, _, retryable, err := eb.NewTxAttempt(ctx, *etx, eb.lggr) - if err != nil { + // Mark transaction as fatal if provided gas limit is set too low + if errors.Is(err, commonfee.ErrFeeLimitTooLow) { + etx.Error = null.StringFrom(commonfee.ErrFeeLimitTooLow.Error()) + return eb.saveFatallyErroredTransaction(eb.lggr, etx), false + } else if err != nil { return fmt.Errorf("processUnstartedTxs failed on NewAttempt: %w", err), retryable } diff --git a/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go b/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go index 871afbb669..0c1fa0d384 100644 --- a/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go +++ b/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go @@ -613,6 +613,7 @@ func (g *TestGasEstimatorConfig) LimitJobType() evmconfig.LimitJobType { func (g *TestGasEstimatorConfig) PriceMaxKey(addr common.Address) *assets.Wei { return assets.GWei(1) } +func (g *TestGasEstimatorConfig) EstimateGasLimit() bool { return false } func (e *TestEvmConfig) GasEstimator() evmconfig.GasEstimator { return &TestGasEstimatorConfig{bumpThreshold: e.BumpThreshold} diff --git a/core/chains/evm/config/chain_scoped_gas_estimator.go b/core/chains/evm/config/chain_scoped_gas_estimator.go index 689d5e38b8..4f2d8872d8 100644 --- a/core/chains/evm/config/chain_scoped_gas_estimator.go +++ b/core/chains/evm/config/chain_scoped_gas_estimator.go @@ -108,6 +108,10 @@ func (g *gasEstimatorConfig) LimitJobType() LimitJobType { return &limitJobTypeConfig{c: g.c.LimitJobType} } +func (g *gasEstimatorConfig) EstimateGasLimit() bool { + return *g.c.EstimateGasLimit +} + type limitJobTypeConfig struct { c toml.GasLimitJobType } diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index 3ccdfeea8b..9517c68716 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -136,6 +136,7 @@ type GasEstimator interface { PriceMin() *assets.Wei Mode() string PriceMaxKey(gethcommon.Address) *assets.Wei + EstimateGasLimit() bool } type LimitJobType interface { diff --git a/core/chains/evm/config/mocks/gas_estimator.go b/core/chains/evm/config/mocks/gas_estimator.go index b8e813e806..40c10757b8 100644 --- a/core/chains/evm/config/mocks/gas_estimator.go +++ b/core/chains/evm/config/mocks/gas_estimator.go @@ -298,6 +298,51 @@ func (_c *GasEstimator_EIP1559DynamicFees_Call) RunAndReturn(run func() bool) *G return _c } +// EstimateGasLimit provides a mock function with given fields: +func (_m *GasEstimator) EstimateGasLimit() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for EstimateGasLimit") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// GasEstimator_EstimateGasLimit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EstimateGasLimit' +type GasEstimator_EstimateGasLimit_Call struct { + *mock.Call +} + +// EstimateGasLimit is a helper method to define mock.On call +func (_e *GasEstimator_Expecter) EstimateGasLimit() *GasEstimator_EstimateGasLimit_Call { + return &GasEstimator_EstimateGasLimit_Call{Call: _e.mock.On("EstimateGasLimit")} +} + +func (_c *GasEstimator_EstimateGasLimit_Call) Run(run func()) *GasEstimator_EstimateGasLimit_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *GasEstimator_EstimateGasLimit_Call) Return(_a0 bool) *GasEstimator_EstimateGasLimit_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GasEstimator_EstimateGasLimit_Call) RunAndReturn(run func() bool) *GasEstimator_EstimateGasLimit_Call { + _c.Call.Return(run) + return _c +} + // FeeCapDefault provides a mock function with given fields: func (_m *GasEstimator) FeeCapDefault() *assets.Wei { ret := _m.Called() diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index ac7841ac49..99e61a394b 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -549,11 +549,12 @@ type GasEstimator struct { PriceMax *assets.Wei PriceMin *assets.Wei - LimitDefault *uint64 - LimitMax *uint64 - LimitMultiplier *decimal.Decimal - LimitTransfer *uint64 - LimitJobType GasLimitJobType `toml:",omitempty"` + LimitDefault *uint64 + LimitMax *uint64 + LimitMultiplier *decimal.Decimal + LimitTransfer *uint64 + LimitJobType GasLimitJobType `toml:",omitempty"` + EstimateGasLimit *bool BumpMin *assets.Wei BumpPercent *uint16 @@ -641,6 +642,9 @@ func (e *GasEstimator) setFrom(f *GasEstimator) { if v := f.LimitTransfer; v != nil { e.LimitTransfer = v } + if v := f.EstimateGasLimit; v != nil { + e.EstimateGasLimit = v + } if v := f.PriceDefault; v != nil { e.PriceDefault = v } diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index a47e56bc91..6dd02a8fd5 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -47,6 +47,7 @@ EIP1559DynamicFees = false FeeCapDefault = '100 gwei' TipCapDefault = '1' TipCapMin = '1' +EstimateGasLimit = false [GasEstimator.BlockHistory] BatchSize = 25 diff --git a/core/chains/evm/gas/helpers_test.go b/core/chains/evm/gas/helpers_test.go index 2c12ed426a..d6af645fe8 100644 --- a/core/chains/evm/gas/helpers_test.go +++ b/core/chains/evm/gas/helpers_test.go @@ -157,6 +157,7 @@ type MockGasEstimatorConfig struct { FeeCapDefaultF *assets.Wei LimitMaxF uint64 ModeF string + EstimateGasLimitF bool } func NewMockGasConfig() *MockGasEstimatorConfig { @@ -214,3 +215,7 @@ func (m *MockGasEstimatorConfig) LimitMax() uint64 { func (m *MockGasEstimatorConfig) Mode() string { return m.ModeF } + +func (m *MockGasEstimatorConfig) EstimateGasLimit() bool { + return m.EstimateGasLimitF +} diff --git a/core/chains/evm/gas/mocks/evm_fee_estimator.go b/core/chains/evm/gas/mocks/evm_fee_estimator.go index a9adc261ce..603115a94c 100644 --- a/core/chains/evm/gas/mocks/evm_fee_estimator.go +++ b/core/chains/evm/gas/mocks/evm_fee_estimator.go @@ -7,6 +7,8 @@ import ( assets "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + common "github.com/ethereum/go-ethereum/common" + context "context" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -145,14 +147,14 @@ func (_c *EvmFeeEstimator_Close_Call) RunAndReturn(run func() error) *EvmFeeEsti return _c } -// GetFee provides a mock function with given fields: ctx, calldata, feeLimit, maxFeePrice, opts -func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...types.Opt) (gas.EvmFee, uint64, error) { +// GetFee provides a mock function with given fields: ctx, calldata, feeLimit, maxFeePrice, toAddress, opts +func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...types.Opt) (gas.EvmFee, uint64, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] } var _ca []interface{} - _ca = append(_ca, ctx, calldata, feeLimit, maxFeePrice) + _ca = append(_ca, ctx, calldata, feeLimit, maxFeePrice, toAddress) _ca = append(_ca, _va...) ret := _m.Called(_ca...) @@ -163,23 +165,23 @@ func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit var r0 gas.EvmFee var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) (gas.EvmFee, uint64, error)); ok { - return rf(ctx, calldata, feeLimit, maxFeePrice, opts...) + if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) (gas.EvmFee, uint64, error)); ok { + return rf(ctx, calldata, feeLimit, maxFeePrice, toAddress, opts...) } - if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) gas.EvmFee); ok { - r0 = rf(ctx, calldata, feeLimit, maxFeePrice, opts...) + if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) gas.EvmFee); ok { + r0 = rf(ctx, calldata, feeLimit, maxFeePrice, toAddress, opts...) } else { r0 = ret.Get(0).(gas.EvmFee) } - if rf, ok := ret.Get(1).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) uint64); ok { - r1 = rf(ctx, calldata, feeLimit, maxFeePrice, opts...) + if rf, ok := ret.Get(1).(func(context.Context, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) uint64); ok { + r1 = rf(ctx, calldata, feeLimit, maxFeePrice, toAddress, opts...) } else { r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) error); ok { - r2 = rf(ctx, calldata, feeLimit, maxFeePrice, opts...) + if rf, ok := ret.Get(2).(func(context.Context, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) error); ok { + r2 = rf(ctx, calldata, feeLimit, maxFeePrice, toAddress, opts...) } else { r2 = ret.Error(2) } @@ -197,43 +199,44 @@ type EvmFeeEstimator_GetFee_Call struct { // - calldata []byte // - feeLimit uint64 // - maxFeePrice *assets.Wei +// - toAddress *common.Address // - opts ...types.Opt -func (_e *EvmFeeEstimator_Expecter) GetFee(ctx interface{}, calldata interface{}, feeLimit interface{}, maxFeePrice interface{}, opts ...interface{}) *EvmFeeEstimator_GetFee_Call { +func (_e *EvmFeeEstimator_Expecter) GetFee(ctx interface{}, calldata interface{}, feeLimit interface{}, maxFeePrice interface{}, toAddress interface{}, opts ...interface{}) *EvmFeeEstimator_GetFee_Call { return &EvmFeeEstimator_GetFee_Call{Call: _e.mock.On("GetFee", - append([]interface{}{ctx, calldata, feeLimit, maxFeePrice}, opts...)...)} + append([]interface{}{ctx, calldata, feeLimit, maxFeePrice, toAddress}, opts...)...)} } -func (_c *EvmFeeEstimator_GetFee_Call) Run(run func(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...types.Opt)) *EvmFeeEstimator_GetFee_Call { +func (_c *EvmFeeEstimator_GetFee_Call) Run(run func(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...types.Opt)) *EvmFeeEstimator_GetFee_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]types.Opt, len(args)-4) - for i, a := range args[4:] { + variadicArgs := make([]types.Opt, len(args)-5) + for i, a := range args[5:] { if a != nil { variadicArgs[i] = a.(types.Opt) } } - run(args[0].(context.Context), args[1].([]byte), args[2].(uint64), args[3].(*assets.Wei), variadicArgs...) + run(args[0].(context.Context), args[1].([]byte), args[2].(uint64), args[3].(*assets.Wei), args[4].(*common.Address), variadicArgs...) }) return _c } -func (_c *EvmFeeEstimator_GetFee_Call) Return(fee gas.EvmFee, chainSpecificFeeLimit uint64, err error) *EvmFeeEstimator_GetFee_Call { - _c.Call.Return(fee, chainSpecificFeeLimit, err) +func (_c *EvmFeeEstimator_GetFee_Call) Return(fee gas.EvmFee, estimatedFeeLimit uint64, err error) *EvmFeeEstimator_GetFee_Call { + _c.Call.Return(fee, estimatedFeeLimit, err) return _c } -func (_c *EvmFeeEstimator_GetFee_Call) RunAndReturn(run func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) (gas.EvmFee, uint64, error)) *EvmFeeEstimator_GetFee_Call { +func (_c *EvmFeeEstimator_GetFee_Call) RunAndReturn(run func(context.Context, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) (gas.EvmFee, uint64, error)) *EvmFeeEstimator_GetFee_Call { _c.Call.Return(run) return _c } -// GetMaxCost provides a mock function with given fields: ctx, amount, calldata, feeLimit, maxFeePrice, opts -func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...types.Opt) (*big.Int, error) { +// GetMaxCost provides a mock function with given fields: ctx, amount, calldata, feeLimit, maxFeePrice, toAddress, opts +func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...types.Opt) (*big.Int, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] } var _ca []interface{} - _ca = append(_ca, ctx, amount, calldata, feeLimit, maxFeePrice) + _ca = append(_ca, ctx, amount, calldata, feeLimit, maxFeePrice, toAddress) _ca = append(_ca, _va...) ret := _m.Called(_ca...) @@ -243,19 +246,19 @@ func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, ca var r0 *big.Int var r1 error - if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, ...types.Opt) (*big.Int, error)); ok { - return rf(ctx, amount, calldata, feeLimit, maxFeePrice, opts...) + if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) (*big.Int, error)); ok { + return rf(ctx, amount, calldata, feeLimit, maxFeePrice, toAddress, opts...) } - if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, ...types.Opt) *big.Int); ok { - r0 = rf(ctx, amount, calldata, feeLimit, maxFeePrice, opts...) + if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) *big.Int); ok { + r0 = rf(ctx, amount, calldata, feeLimit, maxFeePrice, toAddress, opts...) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*big.Int) } } - if rf, ok := ret.Get(1).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, ...types.Opt) error); ok { - r1 = rf(ctx, amount, calldata, feeLimit, maxFeePrice, opts...) + if rf, ok := ret.Get(1).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) error); ok { + r1 = rf(ctx, amount, calldata, feeLimit, maxFeePrice, toAddress, opts...) } else { r1 = ret.Error(1) } @@ -274,21 +277,22 @@ type EvmFeeEstimator_GetMaxCost_Call struct { // - calldata []byte // - feeLimit uint64 // - maxFeePrice *assets.Wei +// - toAddress *common.Address // - opts ...types.Opt -func (_e *EvmFeeEstimator_Expecter) GetMaxCost(ctx interface{}, amount interface{}, calldata interface{}, feeLimit interface{}, maxFeePrice interface{}, opts ...interface{}) *EvmFeeEstimator_GetMaxCost_Call { +func (_e *EvmFeeEstimator_Expecter) GetMaxCost(ctx interface{}, amount interface{}, calldata interface{}, feeLimit interface{}, maxFeePrice interface{}, toAddress interface{}, opts ...interface{}) *EvmFeeEstimator_GetMaxCost_Call { return &EvmFeeEstimator_GetMaxCost_Call{Call: _e.mock.On("GetMaxCost", - append([]interface{}{ctx, amount, calldata, feeLimit, maxFeePrice}, opts...)...)} + append([]interface{}{ctx, amount, calldata, feeLimit, maxFeePrice, toAddress}, opts...)...)} } -func (_c *EvmFeeEstimator_GetMaxCost_Call) Run(run func(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...types.Opt)) *EvmFeeEstimator_GetMaxCost_Call { +func (_c *EvmFeeEstimator_GetMaxCost_Call) Run(run func(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...types.Opt)) *EvmFeeEstimator_GetMaxCost_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]types.Opt, len(args)-5) - for i, a := range args[5:] { + variadicArgs := make([]types.Opt, len(args)-6) + for i, a := range args[6:] { if a != nil { variadicArgs[i] = a.(types.Opt) } } - run(args[0].(context.Context), args[1].(assets.Eth), args[2].([]byte), args[3].(uint64), args[4].(*assets.Wei), variadicArgs...) + run(args[0].(context.Context), args[1].(assets.Eth), args[2].([]byte), args[3].(uint64), args[4].(*assets.Wei), args[5].(*common.Address), variadicArgs...) }) return _c } @@ -298,7 +302,7 @@ func (_c *EvmFeeEstimator_GetMaxCost_Call) Return(_a0 *big.Int, _a1 error) *EvmF return _c } -func (_c *EvmFeeEstimator_GetMaxCost_Call) RunAndReturn(run func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, ...types.Opt) (*big.Int, error)) *EvmFeeEstimator_GetMaxCost_Call { +func (_c *EvmFeeEstimator_GetMaxCost_Call) RunAndReturn(run func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) (*big.Int, error)) *EvmFeeEstimator_GetMaxCost_Call { _c.Call.Return(run) return _c } diff --git a/core/chains/evm/gas/mocks/fee_estimator_client.go b/core/chains/evm/gas/mocks/fee_estimator_client.go index 8e10107597..ab99eb7b0d 100644 --- a/core/chains/evm/gas/mocks/fee_estimator_client.go +++ b/core/chains/evm/gas/mocks/fee_estimator_client.go @@ -241,6 +241,63 @@ func (_c *FeeEstimatorClient_ConfiguredChainID_Call) RunAndReturn(run func() *bi return _c } +// EstimateGas provides a mock function with given fields: ctx, call +func (_m *FeeEstimatorClient) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) { + ret := _m.Called(ctx, call) + + if len(ret) == 0 { + panic("no return value specified for EstimateGas") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg) (uint64, error)); ok { + return rf(ctx, call) + } + if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg) uint64); ok { + r0 = rf(ctx, call) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(context.Context, ethereum.CallMsg) error); ok { + r1 = rf(ctx, call) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeEstimatorClient_EstimateGas_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EstimateGas' +type FeeEstimatorClient_EstimateGas_Call struct { + *mock.Call +} + +// EstimateGas is a helper method to define mock.On call +// - ctx context.Context +// - call ethereum.CallMsg +func (_e *FeeEstimatorClient_Expecter) EstimateGas(ctx interface{}, call interface{}) *FeeEstimatorClient_EstimateGas_Call { + return &FeeEstimatorClient_EstimateGas_Call{Call: _e.mock.On("EstimateGas", ctx, call)} +} + +func (_c *FeeEstimatorClient_EstimateGas_Call) Run(run func(ctx context.Context, call ethereum.CallMsg)) *FeeEstimatorClient_EstimateGas_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(ethereum.CallMsg)) + }) + return _c +} + +func (_c *FeeEstimatorClient_EstimateGas_Call) Return(_a0 uint64, _a1 error) *FeeEstimatorClient_EstimateGas_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeEstimatorClient_EstimateGas_Call) RunAndReturn(run func(context.Context, ethereum.CallMsg) (uint64, error)) *FeeEstimatorClient_EstimateGas_Call { + _c.Call.Return(run) + return _c +} + // HeadByNumber provides a mock function with given fields: ctx, n func (_m *FeeEstimatorClient) HeadByNumber(ctx context.Context, n *big.Int) (*types.Head, error) { ret := _m.Called(ctx, n) diff --git a/core/chains/evm/gas/models.go b/core/chains/evm/gas/models.go index 1ff8b66b1d..15adfc0d7a 100644 --- a/core/chains/evm/gas/models.go +++ b/core/chains/evm/gas/models.go @@ -26,6 +26,9 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) +// EstimateGasBuffer is a multiplier applied to estimated gas when the EstimateGasLimit feature is enabled +const EstimateGasBuffer = float32(1.15) + // EvmFeeEstimator provides a unified interface that wraps EvmEstimator and can determine if legacy or dynamic fee estimation should be used type EvmFeeEstimator interface { services.Service @@ -33,11 +36,11 @@ type EvmFeeEstimator interface { // L1Oracle returns the L1 gas price oracle only if the chain has one, e.g. OP stack L2s and Arbitrum. L1Oracle() rollups.L1Oracle - GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint64, err error) + GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...feetypes.Opt) (fee EvmFee, estimatedFeeLimit uint64, err error) BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint64, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint64, err error) // GetMaxCost returns the total value = max price x fee units + transferred value - GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) + GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...feetypes.Opt) (*big.Int, error) } type feeEstimatorClient interface { @@ -46,6 +49,7 @@ type feeEstimatorClient interface { CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error ConfiguredChainID() *big.Int HeadByNumber(ctx context.Context, n *big.Int) (*evmtypes.Head, error) + EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) } // NewEstimator returns the estimator for a given config @@ -70,6 +74,7 @@ func NewEstimator(lggr logger.Logger, ethClient feeEstimatorClient, cfg Config, "tipCapMin", geCfg.TipCapMin(), "priceMax", geCfg.PriceMax(), "priceMin", geCfg.PriceMin(), + "estimateGasLimit", geCfg.EstimateGasLimit(), ) df := geCfg.EIP1559DynamicFees() @@ -110,7 +115,7 @@ func NewEstimator(lggr logger.Logger, ethClient feeEstimatorClient, cfg Config, return NewFixedPriceEstimator(geCfg, ethClient, bh, lggr, l1Oracle) } } - return NewEvmFeeEstimator(lggr, newEstimator, df, geCfg), nil + return NewEvmFeeEstimator(lggr, newEstimator, df, geCfg, ethClient), nil } // DynamicFee encompasses both FeeCap and TipCap for EIP1559 transactions @@ -181,17 +186,19 @@ type evmFeeEstimator struct { EvmEstimator EIP1559Enabled bool geCfg GasEstimatorConfig + ethClient feeEstimatorClient } var _ EvmFeeEstimator = (*evmFeeEstimator)(nil) -func NewEvmFeeEstimator(lggr logger.Logger, newEstimator func(logger.Logger) EvmEstimator, eip1559Enabled bool, geCfg GasEstimatorConfig) EvmFeeEstimator { +func NewEvmFeeEstimator(lggr logger.Logger, newEstimator func(logger.Logger) EvmEstimator, eip1559Enabled bool, geCfg GasEstimatorConfig, ethClient feeEstimatorClient) EvmFeeEstimator { lggr = logger.Named(lggr, "WrappedEvmEstimator") return &evmFeeEstimator{ lggr: lggr, EvmEstimator: newEstimator(lggr), EIP1559Enabled: eip1559Enabled, geCfg: geCfg, + ethClient: ethClient, } } @@ -261,7 +268,10 @@ func (e *evmFeeEstimator) L1Oracle() rollups.L1Oracle { return e.EvmEstimator.L1Oracle() } -func (e *evmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint64, err error) { +// GetFee returns an initial estimated gas price and gas limit for a transaction +// The gas limit provided by the caller can be adjusted by gas estimation or for 2D fees +func (e *evmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...feetypes.Opt) (fee EvmFee, estimatedFeeLimit uint64, err error) { + var chainSpecificFeeLimit uint64 // get dynamic fee if e.EIP1559Enabled { var dynamicFee DynamicFee @@ -269,24 +279,23 @@ func (e *evmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit if err != nil { return } - chainSpecificFeeLimit, err = commonfee.ApplyMultiplier(feeLimit, e.geCfg.LimitMultiplier()) fee.DynamicFeeCap = dynamicFee.FeeCap fee.DynamicTipCap = dynamicFee.TipCap - return - } - - // get legacy fee - fee.Legacy, chainSpecificFeeLimit, err = e.EvmEstimator.GetLegacyGas(ctx, calldata, feeLimit, maxFeePrice, opts...) - if err != nil { - return + chainSpecificFeeLimit = feeLimit + } else { + // get legacy fee + fee.Legacy, chainSpecificFeeLimit, err = e.EvmEstimator.GetLegacyGas(ctx, calldata, feeLimit, maxFeePrice, opts...) + if err != nil { + return + } } - chainSpecificFeeLimit, err = commonfee.ApplyMultiplier(chainSpecificFeeLimit, e.geCfg.LimitMultiplier()) + estimatedFeeLimit, err = e.estimateFeeLimit(ctx, chainSpecificFeeLimit, calldata, toAddress) return } -func (e *evmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) { - fees, gasLimit, err := e.GetFee(ctx, calldata, feeLimit, maxFeePrice, opts...) +func (e *evmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...feetypes.Opt) (*big.Int, error) { + fees, gasLimit, err := e.GetFee(ctx, calldata, feeLimit, maxFeePrice, toAddress, opts...) if err != nil { return nil, err } @@ -337,6 +346,53 @@ func (e *evmFeeEstimator) BumpFee(ctx context.Context, originalFee EvmFee, feeLi return } +func (e *evmFeeEstimator) estimateFeeLimit(ctx context.Context, feeLimit uint64, calldata []byte, toAddress *common.Address) (estimatedFeeLimit uint64, err error) { + // Use the feeLimit * LimitMultiplier as the provided gas limit since this multiplier is applied on top of the caller specified gas limit + providedGasLimit, err := commonfee.ApplyMultiplier(feeLimit, e.geCfg.LimitMultiplier()) + if err != nil { + return estimatedFeeLimit, err + } + // Use provided fee limit by default if EstimateGasLimit is disabled + if !e.geCfg.EstimateGasLimit() { + return providedGasLimit, nil + } + // Create call msg for gas limit estimation + // Skip setting Gas to avoid capping the results of the estimation + callMsg := ethereum.CallMsg{ + To: toAddress, + Data: calldata, + } + estimatedGas, estimateErr := e.ethClient.EstimateGas(ctx, callMsg) + if estimateErr != nil { + if providedGasLimit > 0 { + // Do not return error if estimate gas failed, we can still use the provided limit instead since it is an upper limit + e.lggr.Errorw("failed to estimate gas limit. falling back to the provided gas limit with multiplier", "callMsg", callMsg, "providedGasLimitWithMultiplier", providedGasLimit, "error", estimateErr) + return providedGasLimit, nil + } + return estimatedFeeLimit, fmt.Errorf("gas estimation failed and provided gas limit is 0: %w", estimateErr) + } + e.lggr.Debugw("estimated gas", "estimatedGas", estimatedGas, "providedGasLimitWithMultiplier", providedGasLimit) + // Return error if estimated gas without the buffer exceeds the provided gas limit, if provided + // Transaction would be destined to run out of gas and fail + if providedGasLimit > 0 && estimatedGas > providedGasLimit { + e.lggr.Errorw("estimated gas exceeds provided gas limit with multiplier", "estimatedGas", estimatedGas, "providedGasLimitWithMultiplier", providedGasLimit) + return estimatedFeeLimit, commonfee.ErrFeeLimitTooLow + } + // Apply EstimateGasBuffer to the estimated gas limit + estimatedFeeLimit, err = commonfee.ApplyMultiplier(estimatedGas, EstimateGasBuffer) + if err != nil { + return + } + // If provided gas limit is not 0, fallback to it if the buffer causes the estimated gas limit to exceed it + // The provided gas limit should be used as an upper bound to avoid unexpected behavior for products + if providedGasLimit > 0 && estimatedFeeLimit > providedGasLimit { + e.lggr.Debugw("estimated gas limit with buffer exceeds the provided gas limit with multiplier. falling back to the provided gas limit with multiplier", "estimatedGasLimit", estimatedFeeLimit, "providedGasLimitWithMultiplier", providedGasLimit) + estimatedFeeLimit = providedGasLimit + } + + return +} + // Config defines an interface for configuration in the gas package type Config interface { ChainType() chaintype.ChainType @@ -358,6 +414,7 @@ type GasEstimatorConfig interface { PriceMin() *assets.Wei PriceMax() *assets.Wei Mode() string + EstimateGasLimit() bool } type BlockHistoryConfig interface { diff --git a/core/chains/evm/gas/models_test.go b/core/chains/evm/gas/models_test.go index 92ea901596..14ef085497 100644 --- a/core/chains/evm/gas/models_test.go +++ b/core/chains/evm/gas/models_test.go @@ -1,6 +1,7 @@ package gas_test import ( + "errors" "math/big" "testing" @@ -12,12 +13,14 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + commonfee "github.com/smartcontractkit/chainlink/v2/common/fee" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups" rollupMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/testutils" ) func TestWrappedEvmEstimator(t *testing.T) { @@ -35,9 +38,9 @@ func TestWrappedEvmEstimator(t *testing.T) { est := mocks.NewEvmEstimator(t) est.On("GetDynamicFee", mock.Anything, mock.Anything). - Return(dynamicFee, nil).Twice() + Return(dynamicFee, nil).Times(6) est.On("GetLegacyGas", mock.Anything, mock.Anything, mock.Anything, mock.Anything). - Return(legacyFee, gasLimit, nil).Twice() + Return(legacyFee, gasLimit, nil).Times(6) est.On("BumpDynamicFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(dynamicFee, nil).Once() est.On("BumpLegacyGas", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). @@ -59,7 +62,7 @@ func TestWrappedEvmEstimator(t *testing.T) { getEst := func(logger.Logger) gas.EvmEstimator { return evmEstimator } // expect nil - estimator := gas.NewEvmFeeEstimator(lggr, getEst, false, nil) + estimator := gas.NewEvmFeeEstimator(lggr, getEst, false, nil, nil) l1Oracle := estimator.L1Oracle() assert.Nil(t, l1Oracle) @@ -68,7 +71,7 @@ func TestWrappedEvmEstimator(t *testing.T) { oracle, err := rollups.NewL1GasOracle(lggr, nil, chaintype.ChainOptimismBedrock) require.NoError(t, err) // cast oracle to L1Oracle interface - estimator = gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg) + estimator = gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg, nil) evmEstimator.On("L1Oracle").Return(oracle).Once() l1Oracle = estimator.L1Oracle() @@ -80,8 +83,8 @@ func TestWrappedEvmEstimator(t *testing.T) { lggr := logger.Test(t) // expect legacy fee data dynamicFees := false - estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg) - fee, max, err := estimator.GetFee(ctx, nil, 0, nil) + estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, nil) + fee, max, err := estimator.GetFee(ctx, nil, 0, nil, nil) require.NoError(t, err) assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), max) assert.True(t, legacyFee.Equal(fee.Legacy)) @@ -90,8 +93,8 @@ func TestWrappedEvmEstimator(t *testing.T) { // expect dynamic fee data dynamicFees = true - estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg) - fee, max, err = estimator.GetFee(ctx, nil, gasLimit, nil) + estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, nil) + fee, max, err = estimator.GetFee(ctx, nil, gasLimit, nil, nil) require.NoError(t, err) assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), max) assert.True(t, dynamicFee.FeeCap.Equal(fee.DynamicFeeCap)) @@ -103,7 +106,7 @@ func TestWrappedEvmEstimator(t *testing.T) { t.Run("BumpFee", func(t *testing.T) { lggr := logger.Test(t) dynamicFees := false - estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg) + estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, nil) // expect legacy fee data fee, max, err := estimator.BumpFee(ctx, gas.EvmFee{Legacy: assets.NewWeiI(0)}, 0, nil, nil) @@ -141,8 +144,8 @@ func TestWrappedEvmEstimator(t *testing.T) { // expect legacy fee data dynamicFees := false - estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg) - total, err := estimator.GetMaxCost(ctx, val, nil, gasLimit, nil) + estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, nil) + total, err := estimator.GetMaxCost(ctx, val, nil, gasLimit, nil, nil) require.NoError(t, err) fee := new(big.Int).Mul(legacyFee.ToInt(), big.NewInt(int64(gasLimit))) fee, _ = new(big.Float).Mul(new(big.Float).SetInt(fee), big.NewFloat(float64(limitMultiplier))).Int(nil) @@ -150,8 +153,8 @@ func TestWrappedEvmEstimator(t *testing.T) { // expect dynamic fee data dynamicFees = true - estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg) - total, err = estimator.GetMaxCost(ctx, val, nil, gasLimit, nil) + estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, nil) + total, err = estimator.GetMaxCost(ctx, val, nil, gasLimit, nil, nil) require.NoError(t, err) fee = new(big.Int).Mul(dynamicFee.FeeCap.ToInt(), big.NewInt(int64(gasLimit))) fee, _ = new(big.Float).Mul(new(big.Float).SetInt(fee), big.NewFloat(float64(limitMultiplier))).Int(nil) @@ -166,7 +169,7 @@ func TestWrappedEvmEstimator(t *testing.T) { estimator := gas.NewEvmFeeEstimator(lggr, func(logger.Logger) gas.EvmEstimator { return evmEstimator - }, false, geCfg) + }, false, geCfg, nil) require.Equal(t, mockEstimatorName, estimator.Name()) require.Equal(t, mockEvmEstimatorName, evmEstimator.Name()) @@ -185,7 +188,7 @@ func TestWrappedEvmEstimator(t *testing.T) { evmEstimator.On("L1Oracle", mock.Anything).Return(nil).Twice() - estimator := gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg) + estimator := gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg, nil) err := estimator.Start(ctx) require.NoError(t, err) err = estimator.Close() @@ -193,7 +196,7 @@ func TestWrappedEvmEstimator(t *testing.T) { evmEstimator.On("L1Oracle", mock.Anything).Return(oracle).Twice() - estimator = gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg) + estimator = gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg, nil) err = estimator.Start(ctx) require.NoError(t, err) err = estimator.Close() @@ -210,11 +213,11 @@ func TestWrappedEvmEstimator(t *testing.T) { oracle.On("Ready").Return(nil).Twice() getEst := func(logger.Logger) gas.EvmEstimator { return evmEstimator } - estimator := gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg) + estimator := gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg, nil) err := estimator.Ready() require.NoError(t, err) - estimator = gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg) + estimator = gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg, nil) err = estimator.Ready() require.NoError(t, err) }) @@ -235,7 +238,7 @@ func TestWrappedEvmEstimator(t *testing.T) { oracle.On("HealthReport").Return(map[string]error{oracleKey: oracleError}).Once() getEst := func(logger.Logger) gas.EvmEstimator { return evmEstimator } - estimator := gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg) + estimator := gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg, nil) report := estimator.HealthReport() require.True(t, pkgerrors.Is(report[evmEstimatorKey], evmEstimatorError)) require.Nil(t, report[oracleKey]) @@ -243,10 +246,166 @@ func TestWrappedEvmEstimator(t *testing.T) { evmEstimator.On("L1Oracle").Return(oracle).Once() - estimator = gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg) + estimator = gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg, nil) report = estimator.HealthReport() require.True(t, pkgerrors.Is(report[evmEstimatorKey], evmEstimatorError)) require.True(t, pkgerrors.Is(report[oracleKey], oracleError)) require.NotNil(t, report[mockEstimatorName]) }) + + t.Run("GetFee, estimate gas limit enabled, succeeds", func(t *testing.T) { + estimatedGasLimit := uint64(5) + lggr := logger.Test(t) + // expect legacy fee data + dynamicFees := false + geCfg.EstimateGasLimitF = true + ethClient := testutils.NewEthClientMockWithDefaultChain(t) + ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Twice() + estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) + toAddress := testutils.NewAddress() + fee, limit, err := estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + require.NoError(t, err) + assert.Equal(t, uint64(float32(estimatedGasLimit)*gas.EstimateGasBuffer), limit) + assert.True(t, legacyFee.Equal(fee.Legacy)) + assert.Nil(t, fee.DynamicTipCap) + assert.Nil(t, fee.DynamicFeeCap) + + // expect dynamic fee data + dynamicFees = true + estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) + fee, limit, err = estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + require.NoError(t, err) + assert.Equal(t, uint64(float32(estimatedGasLimit)*gas.EstimateGasBuffer), limit) + assert.True(t, dynamicFee.FeeCap.Equal(fee.DynamicFeeCap)) + assert.True(t, dynamicFee.TipCap.Equal(fee.DynamicTipCap)) + assert.Nil(t, fee.Legacy) + }) + + t.Run("GetFee, estimate gas limit enabled, estimate exceeds provided limit, returns error", func(t *testing.T) { + estimatedGasLimit := uint64(100) + lggr := logger.Test(t) + // expect legacy fee data + dynamicFees := false + geCfg.EstimateGasLimitF = true + ethClient := testutils.NewEthClientMockWithDefaultChain(t) + ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Twice() + estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) + toAddress := testutils.NewAddress() + _, _, err := estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + require.ErrorIs(t, err, commonfee.ErrFeeLimitTooLow) + + // expect dynamic fee data + dynamicFees = true + estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) + _, _, err = estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + require.ErrorIs(t, err, commonfee.ErrFeeLimitTooLow) + }) + + t.Run("GetFee, estimate gas limit enabled, buffer exceeds provided limit, fallsback to provided limit", func(t *testing.T) { + estimatedGasLimit := uint64(15) // same as provided limit + lggr := logger.Test(t) + dynamicFees := false // expect legacy fee data + geCfg.EstimateGasLimitF = true + ethClient := testutils.NewEthClientMockWithDefaultChain(t) + ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Twice() + estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) + toAddress := testutils.NewAddress() + fee, limit, err := estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + require.NoError(t, err) + assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), limit) + assert.True(t, legacyFee.Equal(fee.Legacy)) + assert.Nil(t, fee.DynamicTipCap) + assert.Nil(t, fee.DynamicFeeCap) + + dynamicFees = true // expect dynamic fee data + estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) + fee, limit, err = estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + require.NoError(t, err) + assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), limit) + assert.True(t, dynamicFee.FeeCap.Equal(fee.DynamicFeeCap)) + assert.True(t, dynamicFee.TipCap.Equal(fee.DynamicTipCap)) + assert.Nil(t, fee.Legacy) + }) + + t.Run("GetFee, estimate gas limit enabled, RPC fails and fallsback to provided gas limit", func(t *testing.T) { + lggr := logger.Test(t) + // expect legacy fee data + dynamicFees := false + geCfg.EstimateGasLimitF = true + ethClient := testutils.NewEthClientMockWithDefaultChain(t) + ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(uint64(0), errors.New("something broke")).Twice() + estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) + toAddress := testutils.NewAddress() + fee, limit, err := estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + require.NoError(t, err) + assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), limit) + assert.True(t, legacyFee.Equal(fee.Legacy)) + assert.Nil(t, fee.DynamicTipCap) + assert.Nil(t, fee.DynamicFeeCap) + + // expect dynamic fee data + dynamicFees = true + estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) + fee, limit, err = estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + require.NoError(t, err) + assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), limit) + assert.True(t, dynamicFee.FeeCap.Equal(fee.DynamicFeeCap)) + assert.True(t, dynamicFee.TipCap.Equal(fee.DynamicTipCap)) + assert.Nil(t, fee.Legacy) + }) + + t.Run("GetFee, estimate gas limit enabled, provided fee limit 0, returns uncapped estimation", func(t *testing.T) { + est.On("GetDynamicFee", mock.Anything, mock.Anything). + Return(dynamicFee, nil).Once() + est.On("GetLegacyGas", mock.Anything, mock.Anything, uint64(0), mock.Anything). + Return(legacyFee, uint64(0), nil).Once() + estimatedGasLimit := uint64(100) // same as provided limit + lggr := logger.Test(t) + // expect legacy fee data + dynamicFees := false + geCfg.EstimateGasLimitF = true + ethClient := testutils.NewEthClientMockWithDefaultChain(t) + ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Twice() + estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) + toAddress := testutils.NewAddress() + fee, limit, err := estimator.GetFee(ctx, []byte{}, uint64(0), nil, &toAddress) + require.NoError(t, err) + assert.Equal(t, uint64(float32(estimatedGasLimit)*gas.EstimateGasBuffer), limit) + assert.True(t, legacyFee.Equal(fee.Legacy)) + assert.Nil(t, fee.DynamicTipCap) + assert.Nil(t, fee.DynamicFeeCap) + + // expect dynamic fee data + dynamicFees = true + estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) + fee, limit, err = estimator.GetFee(ctx, []byte{}, 0, nil, &toAddress) + require.NoError(t, err) + assert.Equal(t, uint64(float32(estimatedGasLimit)*gas.EstimateGasBuffer), limit) + assert.True(t, dynamicFee.FeeCap.Equal(fee.DynamicFeeCap)) + assert.True(t, dynamicFee.TipCap.Equal(fee.DynamicTipCap)) + assert.Nil(t, fee.Legacy) + }) + + t.Run("GetFee, estimate gas limit enabled, provided fee limit 0, returns error on failure", func(t *testing.T) { + est.On("GetDynamicFee", mock.Anything, mock.Anything). + Return(dynamicFee, nil).Once() + est.On("GetLegacyGas", mock.Anything, mock.Anything, uint64(0), mock.Anything). + Return(legacyFee, uint64(0), nil).Once() + lggr := logger.Test(t) + // expect legacy fee data + dynamicFees := false + geCfg.EstimateGasLimitF = true + ethClient := testutils.NewEthClientMockWithDefaultChain(t) + ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(uint64(0), errors.New("something broke")).Twice() + estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) + toAddress := testutils.NewAddress() + _, _, err := estimator.GetFee(ctx, []byte{}, 0, nil, &toAddress) + require.Error(t, err) + + // expect dynamic fee data + dynamicFees = true + estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) + _, _, err = estimator.GetFee(ctx, []byte{}, 0, nil, &toAddress) + require.Error(t, err) + }) } diff --git a/core/chains/evm/txmgr/attempts.go b/core/chains/evm/txmgr/attempts.go index 8566adcb5c..c57ecc4412 100644 --- a/core/chains/evm/txmgr/attempts.go +++ b/core/chains/evm/txmgr/attempts.go @@ -58,7 +58,7 @@ func (c *evmTxAttemptBuilder) NewTxAttempt(ctx context.Context, etx Tx, lggr log // used for L2 re-estimation on broadcasting (note EIP1559 must be disabled otherwise this will fail with mismatched fees + tx type) func (c *evmTxAttemptBuilder) NewTxAttemptWithType(ctx context.Context, etx Tx, lggr logger.Logger, txType int, opts ...feetypes.Opt) (attempt TxAttempt, fee gas.EvmFee, feeLimit uint64, retryable bool, err error) { keySpecificMaxGasPriceWei := c.feeConfig.PriceMaxKey(etx.FromAddress) - fee, feeLimit, err = c.EvmFeeEstimator.GetFee(ctx, etx.EncodedPayload, etx.FeeLimit, keySpecificMaxGasPriceWei, opts...) + fee, feeLimit, err = c.EvmFeeEstimator.GetFee(ctx, etx.EncodedPayload, etx.FeeLimit, keySpecificMaxGasPriceWei, &etx.ToAddress, opts...) if err != nil { return attempt, fee, feeLimit, true, pkgerrors.Wrap(err, "failed to get fee") // estimator errors are retryable } @@ -71,8 +71,8 @@ func (c *evmTxAttemptBuilder) NewTxAttemptWithType(ctx context.Context, etx Tx, // used in the txm broadcaster + confirmer when tx ix rejected for too low fee or is not included in a timely manner func (c *evmTxAttemptBuilder) NewBumpTxAttempt(ctx context.Context, etx Tx, previousAttempt TxAttempt, priorAttempts []TxAttempt, lggr logger.Logger) (attempt TxAttempt, bumpedFee gas.EvmFee, bumpedFeeLimit uint64, retryable bool, err error) { keySpecificMaxGasPriceWei := c.feeConfig.PriceMaxKey(etx.FromAddress) - - bumpedFee, bumpedFeeLimit, err = c.EvmFeeEstimator.BumpFee(ctx, previousAttempt.TxFee, etx.FeeLimit, keySpecificMaxGasPriceWei, newEvmPriorAttempts(priorAttempts)) + // Use the fee limit from the previous attempt to maintain limits adjusted for 2D fees or by estimation + bumpedFee, bumpedFeeLimit, err = c.EvmFeeEstimator.BumpFee(ctx, previousAttempt.TxFee, previousAttempt.ChainSpecificFeeLimit, keySpecificMaxGasPriceWei, newEvmPriorAttempts(priorAttempts)) if err != nil { return attempt, bumpedFee, bumpedFeeLimit, true, pkgerrors.Wrap(err, "failed to bump fee") // estimator errors are retryable } diff --git a/core/chains/evm/txmgr/attempts_test.go b/core/chains/evm/txmgr/attempts_test.go index 6be8cd7067..ea00f7a347 100644 --- a/core/chains/evm/txmgr/attempts_test.go +++ b/core/chains/evm/txmgr/attempts_test.go @@ -339,7 +339,7 @@ func TestTxm_NewCustomTxAttempt_NonRetryableErrors(t *testing.T) { func TestTxm_EvmTxAttemptBuilder_RetryableEstimatorError(t *testing.T) { est := gasmocks.NewEvmFeeEstimator(t) - est.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint64(0), pkgerrors.New("fail")) + est.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint64(0), pkgerrors.New("fail")) est.On("BumpFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint64(0), pkgerrors.New("fail")) kst := ksmocks.NewEth(t) diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index c6c342973b..4edc5572f0 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -29,8 +29,10 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" commonclient "github.com/smartcontractkit/chainlink/v2/common/client" + commmonfee "github.com/smartcontractkit/chainlink/v2/common/fee" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" @@ -69,7 +71,7 @@ func NewTestEthBroadcaster( estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator { return gas.NewFixedPriceEstimator(config.EVM().GasEstimator(), nil, ge.BlockHistory(), lggr, nil) - }, ge.EIP1559DynamicFees(), ge) + }, ge.EIP1559DynamicFees(), ge, ethClient) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, keyStore, estimator) ethBroadcaster := txmgrcommon.NewBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), gconfig.Database().Listener(), keyStore, txBuilder, nonceTracker, lggr, checkerFactory, nonceAutoSync, "") @@ -642,7 +644,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_OptimisticLockingOnEthTx(t *testi chStartEstimate := make(chan struct{}) chBlock := make(chan struct{}) - estimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, ccfg.EVM().GasEstimator().PriceMaxKey(fromAddress)).Return(gas.EvmFee{Legacy: assets.GWei(32)}, uint64(500), nil).Run(func(_ mock.Arguments) { + estimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, ccfg.EVM().GasEstimator().PriceMaxKey(fromAddress), mock.Anything).Return(gas.EvmFee{Legacy: assets.GWei(32)}, uint64(500), nil).Run(func(_ mock.Arguments) { close(chStartEstimate) <-chBlock }).Once() @@ -1177,7 +1179,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { t.Run("callback set by ctor", func(t *testing.T) { estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator { return gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), nil, evmcfg.EVM().GasEstimator().BlockHistory(), lggr, nil) - }, evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), evmcfg.EVM().GasEstimator()) + }, evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), evmcfg.EVM().GasEstimator(), ethClient) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), evmcfg.EVM().GasEstimator(), ethKeyStore, estimator) localNextNonce = getLocalNextNonce(t, nonceTracker, fromAddress) eb2 := txmgr.NewEvmBroadcaster(txStore, txmClient, txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(evmcfg.EVM().GasEstimator()), evmcfg.EVM().Transactions(), cfg.Database().Listener(), ethKeyStore, txBuilder, lggr, &testCheckerFactory{}, false, "") @@ -1666,6 +1668,73 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { }) } +func TestEthBroadcaster_ProcessUnstartedEthTxs_GasEstimationError(t *testing.T) { + toAddress := testutils.NewAddress() + value := big.Int(assets.NewEthValue(142)) + gasLimit := uint64(242) + encodedPayload := []byte{0, 1} + + db := pgtest.NewSqlxDB(t) + cfg := configtest.NewTestGeneralConfig(t) + cfg.EVMConfigs()[0].GasEstimator.EstimateGasLimit = ptr(true) // Enabled gas limit estimation + limitMultiplier := float32(1.25) + cfg.EVMConfigs()[0].GasEstimator.LimitMultiplier = ptr(decimal.NewFromFloat32(limitMultiplier)) // Set LimitMultiplier for the buffer + txStore := cltest.NewTestTxStore(t, db) + + ethKeyStore := cltest.NewKeyStore(t, db).Eth() + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + + config := evmtest.NewChainScopedConfig(t, cfg) + ethClient := testutils.NewEthClientMockWithDefaultChain(t) + ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() + lggr := logger.Test(t) + txmClient := txmgr.NewEvmTxmClient(ethClient, nil) + nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmClient) + ge := config.EVM().GasEstimator() + estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator { + return gas.NewFixedPriceEstimator(ge, nil, ge.BlockHistory(), lggr, nil) + }, ge.EIP1559DynamicFees(), ge, ethClient) + txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ethKeyStore, estimator) + eb := txmgrcommon.NewBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), cfg.Database().Listener(), ethKeyStore, txBuilder, nonceTracker, lggr, &testCheckerFactory{}, false, "") + + // Mark instance as test + eb.XXXTestDisableUnstartedTxAutoProcessing() + servicetest.Run(t, eb) + ctx := tests.Context(t) + t.Run("gas limit lowered after estimation", func(t *testing.T) { + estimatedGasLimit := uint64(100) + etx := mustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, testutils.FixtureChainID) + ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Once() + ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { + return tx.Nonce() == uint64(0) + }), fromAddress).Return(commonclient.Successful, nil).Once() + + // Do the thing + retryable, err := eb.ProcessUnstartedTxs(ctx, fromAddress) + assert.NoError(t, err) + assert.False(t, retryable) + + dbEtx, err := txStore.FindTxWithAttempts(ctx, etx.ID) + require.NoError(t, err) + attempt := dbEtx.TxAttempts[0] + require.Equal(t, uint64(float32(estimatedGasLimit)*gas.EstimateGasBuffer), attempt.ChainSpecificFeeLimit) + }) + t.Run("provided gas limit too low, transaction marked as fatal error", func(t *testing.T) { + etx := mustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, testutils.FixtureChainID) + ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(uint64(float32(gasLimit)*limitMultiplier)+1, nil).Once() + + // Do the thing + retryable, err := eb.ProcessUnstartedTxs(ctx, fromAddress) + assert.NoError(t, err) + assert.False(t, retryable) + + dbEtx, err := txStore.FindTxWithAttempts(ctx, etx.ID) + require.NoError(t, err) + require.Equal(t, txmgrcommon.TxFatalError, dbEtx.State) + require.Equal(t, commmonfee.ErrFeeLimitTooLow.Error(), dbEtx.Error.String) + }) +} + func TestEthBroadcaster_ProcessUnstartedEthTxs_KeystoreErrors(t *testing.T) { toAddress := gethCommon.HexToAddress("0x6C03DDA95a2AEd917EeCc6eddD4b9D16E6380411") value := big.Int(assets.NewEthValue(142)) @@ -1760,15 +1829,15 @@ func TestEthBroadcaster_SyncNonce(t *testing.T) { kst := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.RandomKey{Disabled: false}.MustInsertWithState(t, kst) + ethClient := testutils.NewEthClientMockWithDefaultChain(t) estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator { return gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), nil, evmcfg.EVM().GasEstimator().BlockHistory(), lggr, nil) - }, evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), evmcfg.EVM().GasEstimator()) + }, evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), evmcfg.EVM().GasEstimator(), ethClient) checkerFactory := &testCheckerFactory{} ge := evmcfg.EVM().GasEstimator() t.Run("does nothing if nonce sync is disabled", func(t *testing.T) { - ethClient := testutils.NewEthClientMockWithDefaultChain(t) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, kst, estimator) kst := ksmocks.NewEth(t) @@ -1838,7 +1907,7 @@ func TestEthBroadcaster_HederaBroadcastValidation(t *testing.T) { ge := evmcfg.EVM().GasEstimator() estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator { return gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), nil, ge.BlockHistory(), lggr, nil) - }, ge.EIP1559DynamicFees(), ge) + }, ge.EIP1559DynamicFees(), ge, ethClient) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ethKeyStore, estimator) checkerFactory := &txmgr.CheckerFactory{Client: ethClient} ctx := tests.Context(t) diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index eaf79b6aba..24330172b9 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -129,7 +129,7 @@ func TestEthConfirmer_Lifecycle(t *testing.T) { newEst := func(logger.Logger) gas.EvmEstimator { return estimator } lggr := logger.Test(t) ge := config.EVM().GasEstimator() - feeEstimator := gas.NewEvmFeeEstimator(lggr, newEst, ge.EIP1559DynamicFees(), ge) + feeEstimator := gas.NewEvmFeeEstimator(lggr, newEst, ge.EIP1559DynamicFees(), ge, ethClient) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ethKeyStore, feeEstimator) stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), config.EVM().Transactions().AutoPurge(), feeEstimator, txStore, ethClient) ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) @@ -1661,7 +1661,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing newEst := func(logger.Logger) gas.EvmEstimator { return estimator } estimator.On("BumpLegacyGas", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, uint64(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction...")) ge := ccfg.EVM().GasEstimator() - feeEstimator := gas.NewEvmFeeEstimator(lggr, newEst, ge.EIP1559DynamicFees(), ge) + feeEstimator := gas.NewEvmFeeEstimator(lggr, newEst, ge.EIP1559DynamicFees(), ge, ethClient) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, kst, feeEstimator) addresses := []gethCommon.Address{fromAddress} kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Maybe() @@ -1711,7 +1711,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing newEst := func(logger.Logger) gas.EvmEstimator { return estimator } // Create confirmer with necessary state ge := ccfg.EVM().GasEstimator() - feeEstimator := gas.NewEvmFeeEstimator(lggr, newEst, ge.EIP1559DynamicFees(), ge) + feeEstimator := gas.NewEvmFeeEstimator(lggr, newEst, ge.EIP1559DynamicFees(), ge, ethClient) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, kst, feeEstimator) addresses := []gethCommon.Address{fromAddress} kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Maybe() @@ -3218,7 +3218,7 @@ func TestEthConfirmer_ProcessStuckTransactions(t *testing.T) { fee := gas.EvmFee{Legacy: marketGasPrice} bumpedLegacy := assets.GWei(30) bumpedFee := gas.EvmFee{Legacy: bumpedLegacy} - feeEstimator.On("GetFee", mock.Anything, []byte{}, uint64(0), mock.Anything).Return(fee, uint64(0), nil) + feeEstimator.On("GetFee", mock.Anything, []byte{}, uint64(0), mock.Anything, mock.Anything).Return(fee, uint64(0), nil) feeEstimator.On("BumpFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(bumpedFee, uint64(10_000), nil) autoPurgeThreshold := uint32(5) autoPurgeMinAttempts := uint32(3) @@ -3317,7 +3317,7 @@ func newEthConfirmer(t testing.TB, txStore txmgr.EvmTxStore, ethClient client.Cl ge := config.EVM().GasEstimator() estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator { return gas.NewFixedPriceEstimator(ge, nil, ge.BlockHistory(), lggr, nil) - }, ge.EIP1559DynamicFees(), ge) + }, ge.EIP1559DynamicFees(), ge, ethClient) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ks, estimator) stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), config.EVM().Transactions().AutoPurge(), estimator, txStore, ethClient) ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) diff --git a/core/chains/evm/txmgr/stuck_tx_detector.go b/core/chains/evm/txmgr/stuck_tx_detector.go index 5d621dc0b2..4e521d5f8f 100644 --- a/core/chains/evm/txmgr/stuck_tx_detector.go +++ b/core/chains/evm/txmgr/stuck_tx_detector.go @@ -25,7 +25,7 @@ import ( ) type stuckTxDetectorGasEstimator interface { - GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee gas.EvmFee, chainSpecificFeeLimit uint64, err error) + GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...feetypes.Opt) (fee gas.EvmFee, chainSpecificFeeLimit uint64, err error) } type stuckTxDetectorClient interface { @@ -199,7 +199,7 @@ func (d *stuckTxDetector) detectStuckTransactionsHeuristic(ctx context.Context, defer d.purgeBlockNumLock.RUnlock() // Get gas price from internal gas estimator // Send with max gas price time 2 to prevent the results from being capped. Need the market gas price here. - marketGasPrice, _, err := d.gasEstimator.GetFee(ctx, []byte{}, 0, d.maxPrice.Mul(big.NewInt(2))) + marketGasPrice, _, err := d.gasEstimator.GetFee(ctx, []byte{}, 0, d.maxPrice.Mul(big.NewInt(2)), nil) if err != nil { return txs, fmt.Errorf("failed to get market gas price for overflow detection: %w", err) } diff --git a/core/chains/evm/txmgr/stuck_tx_detector_test.go b/core/chains/evm/txmgr/stuck_tx_detector_test.go index def49f8e11..5e022091a6 100644 --- a/core/chains/evm/txmgr/stuck_tx_detector_test.go +++ b/core/chains/evm/txmgr/stuck_tx_detector_test.go @@ -73,7 +73,7 @@ func TestStuckTxDetector_LoadPurgeBlockNumMap(t *testing.T) { feeEstimator := gasmocks.NewEvmFeeEstimator(t) marketGasPrice := assets.GWei(15) fee := gas.EvmFee{Legacy: marketGasPrice} - feeEstimator.On("GetFee", mock.Anything, []byte{}, uint64(0), mock.Anything).Return(fee, uint64(0), nil) + feeEstimator.On("GetFee", mock.Anything, []byte{}, uint64(0), mock.Anything, mock.Anything).Return(fee, uint64(0), nil) autoPurgeThreshold := uint32(5) autoPurgeMinAttempts := uint32(3) autoPurgeCfg := testAutoPurgeConfig{ @@ -194,7 +194,7 @@ func TestStuckTxDetector_DetectStuckTransactionsHeuristic(t *testing.T) { // Return 10 gwei as market gas price marketGasPrice := tenGwei fee := gas.EvmFee{Legacy: marketGasPrice} - feeEstimator.On("GetFee", mock.Anything, []byte{}, uint64(0), mock.Anything).Return(fee, uint64(0), nil) + feeEstimator.On("GetFee", mock.Anything, []byte{}, uint64(0), mock.Anything, mock.Anything).Return(fee, uint64(0), nil) ethClient := testutils.NewEthClientMockWithDefaultChain(t) autoPurgeThreshold := uint32(5) autoPurgeMinAttempts := uint32(3) diff --git a/core/chains/evm/txmgr/test_helpers.go b/core/chains/evm/txmgr/test_helpers.go index 8d20874432..3dea024352 100644 --- a/core/chains/evm/txmgr/test_helpers.go +++ b/core/chains/evm/txmgr/test_helpers.go @@ -92,6 +92,7 @@ func (g *TestGasEstimatorConfig) LimitTransfer() uint64 { return 42 } func (g *TestGasEstimatorConfig) PriceMax() *assets.Wei { return assets.NewWeiI(42) } func (g *TestGasEstimatorConfig) PriceMin() *assets.Wei { return assets.NewWeiI(42) } func (g *TestGasEstimatorConfig) Mode() string { return "FixedPrice" } +func (g *TestGasEstimatorConfig) EstimateGasLimit() bool { return false } func (g *TestGasEstimatorConfig) LimitJobType() evmconfig.LimitJobType { return &TestLimitJobTypeConfig{} } diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index 444804b382..b9a256ddf4 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -193,6 +193,8 @@ LimitMax = 500_000 # Default LimitMultiplier = '1.0' # Default # LimitTransfer is the gas limit used for an ordinary ETH transfer. LimitTransfer = 21_000 # Default +# EstimateGasLimit enables estimating gas limits for transactions. This feature respects the gas limit provided during transaction creation as an upper bound. +EstimateGasLimit = false # Default # BumpMin is the minimum fixed amount of wei by which gas is bumped on each transaction attempt. BumpMin = '5 gwei' # Default # BumpPercent is the percentage by which to bump gas on a transaction that has exceeded `BumpThreshold`. The larger of `BumpPercent` and `BumpMin` is taken for gas bumps. diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go index 046f21b7f7..86e43f44eb 100644 --- a/core/internal/features/features_test.go +++ b/core/internal/features/features_test.go @@ -1339,7 +1339,7 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { chain := evmtest.MustGetDefaultChain(t, legacyChains) estimator := chain.GasEstimator() - gasPrice, gasLimit, err := estimator.GetFee(testutils.Context(t), nil, 500_000, maxGasPrice) + gasPrice, gasLimit, err := estimator.GetFee(testutils.Context(t), nil, 500_000, maxGasPrice, nil) require.NoError(t, err) assert.Equal(t, uint64(500000), gasLimit) assert.Equal(t, "41.5 gwei", gasPrice.Legacy.String()) @@ -1360,7 +1360,7 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { newHeads.TrySend(h43) gomega.NewWithT(t).Eventually(func() string { - gasPrice, _, err := estimator.GetFee(testutils.Context(t), nil, 500000, maxGasPrice) + gasPrice, _, err := estimator.GetFee(testutils.Context(t), nil, 500000, maxGasPrice, nil) require.NoError(t, err) return gasPrice.Legacy.String() }, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.Equal("45 gwei")) diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index b9d7921d78..253e4aa067 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -520,6 +520,7 @@ func TestConfig_Marshal(t *testing.T) { LimitMax: ptr[uint64](17), LimitMultiplier: mustDecimal("1.234"), LimitTransfer: ptr[uint64](100), + EstimateGasLimit: ptr(false), TipCapDefault: assets.NewWeiI(2), TipCapMin: assets.NewWeiI(1), PriceDefault: assets.NewWeiI(math.MaxInt64), @@ -1024,6 +1025,7 @@ LimitDefault = 12 LimitMax = 17 LimitMultiplier = '1.234' LimitTransfer = 100 +EstimateGasLimit = false BumpMin = '100 wei' BumpPercent = 10 BumpThreshold = 6 diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index d752398f03..a7fc9dcb94 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -316,6 +316,7 @@ LimitDefault = 12 LimitMax = 17 LimitMultiplier = '1.234' LimitTransfer = 100 +EstimateGasLimit = false BumpMin = '100 wei' BumpPercent = 10 BumpThreshold = 6 diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 12427650f4..8bfc93c7be 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -303,6 +303,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -403,6 +404,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -497,6 +499,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '20 gwei' BumpPercent = 20 BumpThreshold = 5 diff --git a/core/services/keeper/upkeep_executer_test.go b/core/services/keeper/upkeep_executer_test.go index c70a92c725..0f68543904 100644 --- a/core/services/keeper/upkeep_executer_test.go +++ b/core/services/keeper/upkeep_executer_test.go @@ -48,7 +48,7 @@ func mockEstimator(t *testing.T) gas.EvmFeeEstimator { // note: estimator will only return 1 of legacy or dynamic fees (not both) // assumed to call legacy estimator only estimator := gasmocks.NewEvmFeeEstimator(t) - estimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Maybe().Return(gas.EvmFee{ + estimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Maybe().Return(gas.EvmFee{ Legacy: assets.GWei(60), }, uint32(60), nil) return estimator diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go index 3ba106f280..993829c1b6 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -283,7 +283,7 @@ func TestCommitStoreReaders(t *testing.T) { } gasPrice := big.NewInt(10) daPrice := big.NewInt(20) - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, assets.NewWei(maxGasPrice)).Return(gas.EvmFee{Legacy: assets.NewWei(gasPrice)}, uint64(0), nil) + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, assets.NewWei(maxGasPrice), (*common.Address)(nil)).Return(gas.EvmFee{Legacy: assets.NewWei(gasPrice)}, uint64(0), nil) lm.On("GasPrice", mock.Anything).Return(assets.NewWei(daPrice), nil) for v, cr := range crs { diff --git a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go index 56e1ddb583..031dc25ed8 100644 --- a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go +++ b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go @@ -26,7 +26,7 @@ func NewExecGasPriceEstimator(estimator gas.EvmFeeEstimator, maxGasPrice *big.In } func (g ExecGasPriceEstimator) GetGasPrice(ctx context.Context) (*big.Int, error) { - gasPriceWei, _, err := g.estimator.GetFee(ctx, nil, 0, assets.NewWei(g.maxGasPrice)) + gasPriceWei, _, err := g.estimator.GetFee(ctx, nil, 0, assets.NewWei(g.maxGasPrice), nil) if err != nil { return nil, err } diff --git a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go index e1c2fa0398..6953805709 100644 --- a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go +++ b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go @@ -5,6 +5,7 @@ import ( "math/big" "testing" + "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "github.com/stretchr/testify/assert" @@ -85,7 +86,7 @@ func TestExecPriceEstimator_GetGasPrice(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { sourceFeeEstimator := mocks.NewEvmFeeEstimator(t) - sourceFeeEstimator.On("GetFee", ctx, []byte(nil), uint64(0), assets.NewWei(tc.maxGasPrice)).Return( + sourceFeeEstimator.On("GetFee", ctx, []byte(nil), uint64(0), assets.NewWei(tc.maxGasPrice), (*common.Address)(nil)).Return( tc.sourceFeeEstimatorRespFee, uint64(0), tc.sourceFeeEstimatorRespErr) g := ExecGasPriceEstimator{ diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice.go index 34d7fb7945..d54deea406 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice.go @@ -46,7 +46,7 @@ func CheckGasPrice(ctx context.Context, upkeepId *big.Int, offchainConfigBytes [ } lggr.Debugf("successfully decode offchain config for %s, max gas price is %s", upkeepId.String(), offchainConfig.MaxGasPrice.String()) - fee, _, err := ge.GetFee(ctx, []byte{}, feeLimit, assets.NewWei(big.NewInt(maxFeePrice))) + fee, _, err := ge.GetFee(ctx, []byte{}, feeLimit, assets.NewWei(big.NewInt(maxFeePrice)), nil) if err != nil { lggr.Errorw("failed to get fee, gas price check is disabled", "upkeepId", upkeepId.String(), "err", err) return encoding.UpkeepFailureReasonNone diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice_test.go index 9b5640051d..4418dd0f7c 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice_test.go @@ -86,13 +86,13 @@ func TestGasPrice_Check(t *testing.T) { ctx := testutils.Context(t) ge := gasMocks.NewEvmFeeEstimator(t) if test.FailedToGetFee { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return( + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return( gas.EvmFee{}, feeLimit, errors.New("failed to retrieve gas price"), ) } else if test.CurrentLegacyGasPrice != nil { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return( + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return( gas.EvmFee{ Legacy: assets.NewWei(test.CurrentLegacyGasPrice), }, @@ -100,7 +100,7 @@ func TestGasPrice_Check(t *testing.T) { nil, ) } else if test.CurrentDynamicGasPrice != nil { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return( + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return( gas.EvmFee{ DynamicFeeCap: assets.NewWei(test.CurrentDynamicGasPrice), DynamicTipCap: assets.NewWei(big.NewInt(1_000_000_000)), diff --git a/core/services/relay/evm/chain_writer.go b/core/services/relay/evm/chain_writer.go index 895d276e6b..c456726379 100644 --- a/core/services/relay/evm/chain_writer.go +++ b/core/services/relay/evm/chain_writer.go @@ -186,7 +186,7 @@ func (w *chainWriter) GetFeeComponents(ctx context.Context) (*commontypes.ChainF return nil, fmt.Errorf("gas estimator not available") } - fee, _, err := w.ge.GetFee(ctx, nil, 0, w.maxGasPrice) + fee, _, err := w.ge.GetFee(ctx, nil, 0, w.maxGasPrice, nil) if err != nil { return nil, err } diff --git a/core/services/relay/evm/chain_writer_test.go b/core/services/relay/evm/chain_writer_test.go index ab8b6f0e36..f35e9eece5 100644 --- a/core/services/relay/evm/chain_writer_test.go +++ b/core/services/relay/evm/chain_writer_test.go @@ -87,7 +87,7 @@ func TestChainWriter(t *testing.T) { }) t.Run("GetFeeComponents", func(t *testing.T) { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ Legacy: assets.NewWei(big.NewInt(1000000001)), DynamicFeeCap: assets.NewWei(big.NewInt(1000000002)), DynamicTipCap: assets.NewWei(big.NewInt(1000000003)), @@ -113,7 +113,7 @@ func TestChainWriter(t *testing.T) { }) t.Run("Returns Legacy Fee in absence of Dynamic Fee", func(t *testing.T) { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ Legacy: assets.NewWei(big.NewInt(1000000001)), DynamicFeeCap: nil, DynamicTipCap: assets.NewWei(big.NewInt(1000000003)), @@ -125,7 +125,7 @@ func TestChainWriter(t *testing.T) { }) t.Run("Fails when neither legacy or dynamic fee is available", func(t *testing.T) { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ Legacy: nil, DynamicFeeCap: nil, DynamicTipCap: nil, @@ -137,7 +137,7 @@ func TestChainWriter(t *testing.T) { t.Run("Fails when GetFee returns an error", func(t *testing.T) { expectedErr := fmt.Errorf("GetFee error") - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ Legacy: nil, DynamicFeeCap: nil, DynamicTipCap: nil, @@ -147,7 +147,7 @@ func TestChainWriter(t *testing.T) { }) t.Run("Fails when L1Oracle returns error", func(t *testing.T) { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ Legacy: assets.NewWei(big.NewInt(1000000001)), DynamicFeeCap: assets.NewWei(big.NewInt(1000000002)), DynamicTipCap: assets.NewWei(big.NewInt(1000000003)), diff --git a/core/web/evm_transfer_controller.go b/core/web/evm_transfer_controller.go index 88d3dead4c..3e14aaccd3 100644 --- a/core/web/evm_transfer_controller.go +++ b/core/web/evm_transfer_controller.go @@ -54,7 +54,7 @@ func (tc *EVMTransfersController) Create(c *gin.Context) { } if !tr.AllowHigherAmounts { - err = ValidateEthBalanceForTransfer(c, chain, tr.FromAddress, tr.Amount) + err = ValidateEthBalanceForTransfer(c, chain, tr.FromAddress, tr.Amount, tr.DestinationAddress) if err != nil { jsonAPIError(c, http.StatusUnprocessableEntity, errors.Errorf("transaction failed: %v", err)) return @@ -92,7 +92,7 @@ func (tc *EVMTransfersController) Create(c *gin.Context) { } // ValidateEthBalanceForTransfer validates that the current balance can cover the transaction amount -func ValidateEthBalanceForTransfer(c *gin.Context, chain legacyevm.Chain, fromAddr common.Address, amount assets.Eth) error { +func ValidateEthBalanceForTransfer(c *gin.Context, chain legacyevm.Chain, fromAddr common.Address, amount assets.Eth, toAddr common.Address) error { var err error var balance *big.Int @@ -116,7 +116,7 @@ func ValidateEthBalanceForTransfer(c *gin.Context, chain legacyevm.Chain, fromAd gasLimit := chain.Config().EVM().GasEstimator().LimitTransfer() estimator := chain.GasEstimator() - amountWithFees, err := estimator.GetMaxCost(c, amount, nil, gasLimit, chain.Config().EVM().GasEstimator().PriceMaxKey(fromAddr)) + amountWithFees, err := estimator.GetMaxCost(c, amount, nil, gasLimit, chain.Config().EVM().GasEstimator().PriceMaxKey(fromAddr), &toAddr) if err != nil { return err } diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 9421e6198e..f67d4737b5 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -316,6 +316,7 @@ LimitDefault = 12 LimitMax = 17 LimitMultiplier = '1.234' LimitTransfer = 100 +EstimateGasLimit = false BumpMin = '100 wei' BumpPercent = 10 BumpThreshold = 6 diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 1c4093cbfc..55f998156c 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -303,6 +303,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -403,6 +404,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -497,6 +499,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '20 gwei' BumpPercent = 20 BumpThreshold = 5 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 74afcec740..32ab35b7cc 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1818,6 +1818,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -1912,6 +1913,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2006,6 +2008,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2100,6 +2103,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2195,6 +2199,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -2289,6 +2294,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2383,6 +2389,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2478,6 +2485,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2572,6 +2580,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -2665,6 +2674,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2758,6 +2768,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2852,6 +2863,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -2947,6 +2959,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -3041,6 +3054,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -3135,6 +3149,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '20 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -3229,6 +3244,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '20 mwei' BumpPercent = 40 BumpThreshold = 3 @@ -3323,6 +3339,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '100 mwei' BumpPercent = 40 BumpThreshold = 3 @@ -3417,6 +3434,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -3511,6 +3529,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -3605,6 +3624,7 @@ LimitDefault = 100000000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -3699,6 +3719,7 @@ LimitDefault = 100000000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -3793,6 +3814,7 @@ LimitDefault = 100000000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -3888,6 +3910,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -3982,6 +4005,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -4075,6 +4099,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -4169,6 +4194,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -4263,6 +4289,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '100 mwei' BumpPercent = 40 BumpThreshold = 3 @@ -4357,6 +4384,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -4451,6 +4479,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -4544,6 +4573,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 0 @@ -4638,6 +4668,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '20 mwei' BumpPercent = 40 BumpThreshold = 3 @@ -4732,6 +4763,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -4826,6 +4858,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '20 mwei' BumpPercent = 40 BumpThreshold = 3 @@ -4920,6 +4953,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -5013,6 +5047,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -5107,6 +5142,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -5201,6 +5237,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -5296,6 +5333,7 @@ LimitDefault = 500000 LimitMax = 1000000000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -5391,6 +5429,7 @@ LimitDefault = 500000 LimitMax = 1000000000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -5486,6 +5525,7 @@ LimitDefault = 500000 LimitMax = 1000000000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -5580,6 +5620,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '2 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -5674,6 +5715,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -5768,6 +5810,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -5862,6 +5905,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '2 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -5955,6 +5999,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 40 BumpThreshold = 3 @@ -6048,6 +6093,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -6141,6 +6187,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 40 BumpThreshold = 3 @@ -6235,6 +6282,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -6329,6 +6377,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '20 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -6422,6 +6471,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '20 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -6516,6 +6566,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -6610,6 +6661,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -6705,6 +6757,7 @@ LimitDefault = 500000 LimitMax = 1000000000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -6800,6 +6853,7 @@ LimitDefault = 500000 LimitMax = 1000000000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -6894,6 +6948,7 @@ LimitDefault = 500000 LimitMax = 1000000000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -6988,6 +7043,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '1 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -7082,6 +7138,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '1 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -7176,6 +7233,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -7270,6 +7328,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -7364,6 +7423,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -7458,6 +7518,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -7819,6 +7880,7 @@ LimitDefault = 500_000 # Default LimitMax = 500_000 # Default LimitMultiplier = '1.0' # Default LimitTransfer = 21_000 # Default +EstimateGasLimit = false # Default BumpMin = '5 gwei' # Default BumpPercent = 20 # Default BumpThreshold = 3 # Default @@ -7913,6 +7975,12 @@ LimitTransfer = 21_000 # Default ``` LimitTransfer is the gas limit used for an ordinary ETH transfer. +### EstimateGasLimit +```toml +EstimateGasLimit = false # Default +``` +EstimateGasLimit enables estimating gas limits for transactions. This feature respects the gas limit provided during transaction creation as an upper bound. + ### BumpMin ```toml BumpMin = '5 gwei' # Default diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index f4dd43cb90..016d416d5f 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -359,6 +359,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 75a6ae3641..f8a98b2c49 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -359,6 +359,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 97bae5a84b..aef3b106a5 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -359,6 +359,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index ab6860ec79..2912a80327 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -349,6 +349,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index 603fdaada6..ce40c91f66 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -356,6 +356,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 +EstimateGasLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 From b0e31e08d5a635521afc48570a4b2a01e1daa0fb Mon Sep 17 00:00:00 2001 From: Joe Huang Date: Thu, 22 Aug 2024 21:20:42 -0500 Subject: [PATCH 151/432] Improve TXM performance by optimize Confirmer and Finalizer queries to stop pulling EVM receipt (#14039) * investigate, optimize and test FindTransactionsConfirmedInBlockRange query change * update comments, add changeset * update test * update finalizer query * rename * more rename * fix lint * minor * Amit comments * improve import * Amit comments * grammar * Dimitris comments * format * cleanup * format * comment * improve --- .changeset/cuddly-eels-lay.md | 5 ++ common/txmgr/types/tx_store.go | 2 + core/chains/evm/txmgr/evm_tx_store.go | 67 ++++++++++++++++------ core/chains/evm/txmgr/evm_tx_store_test.go | 6 ++ core/chains/evm/txmgr/finalizer.go | 3 +- 5 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 .changeset/cuddly-eels-lay.md diff --git a/.changeset/cuddly-eels-lay.md b/.changeset/cuddly-eels-lay.md new file mode 100644 index 0000000000..25b38d3164 --- /dev/null +++ b/.changeset/cuddly-eels-lay.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Improve TXM performance by optimizing Confirmer and Finalizer queries to stop pulling EVM receipt. #internal diff --git a/common/txmgr/types/tx_store.go b/common/txmgr/types/tx_store.go index 5489a57e63..3d874cc436 100644 --- a/common/txmgr/types/tx_store.go +++ b/common/txmgr/types/tx_store.go @@ -79,6 +79,8 @@ type TransactionStore[ // Search for Tx using the fromAddress and sequence FindTxWithSequence(ctx context.Context, fromAddress ADDR, seq SEQ) (etx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) FindNextUnstartedTransactionFromAddress(ctx context.Context, fromAddress ADDR, chainID CHAIN_ID) (*Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) + + // FindTransactionsConfirmedInBlockRange retrieves tx with attempts and partial receipt values for optimization purpose FindTransactionsConfirmedInBlockRange(ctx context.Context, highBlockNumber, lowBlockNumber int64, chainID CHAIN_ID) (etxs []*Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) FindEarliestUnconfirmedBroadcastTime(ctx context.Context, chainID CHAIN_ID) (null.Time, error) FindEarliestUnconfirmedTxAttemptBlock(ctx context.Context, chainID CHAIN_ID) (null.Int, error) diff --git a/core/chains/evm/txmgr/evm_tx_store.go b/core/chains/evm/txmgr/evm_tx_store.go index 4bdf191376..fa2251168d 100644 --- a/core/chains/evm/txmgr/evm_tx_store.go +++ b/core/chains/evm/txmgr/evm_tx_store.go @@ -669,10 +669,8 @@ func (o *evmTxStore) loadEthTxAttemptsReceipts(ctx context.Context, etx *Tx) (er return o.loadEthTxesAttemptsReceipts(ctx, []*Tx{etx}) } -func (o *evmTxStore) loadEthTxesAttemptsReceipts(ctx context.Context, etxs []*Tx) (err error) { - if len(etxs) == 0 { - return nil - } +// initEthTxesAttempts takes an input txes slice, return an initialized attempt map and attemptHashes slice +func initEthTxesAttempts(etxs []*Tx) (map[common.Hash]*TxAttempt, [][]byte) { attemptHashM := make(map[common.Hash]*TxAttempt, len(etxs)) // len here is lower bound attemptHashes := make([][]byte, len(etxs)) // len here is lower bound for _, etx := range etxs { @@ -681,6 +679,16 @@ func (o *evmTxStore) loadEthTxesAttemptsReceipts(ctx context.Context, etxs []*Tx attemptHashes = append(attemptHashes, attempt.Hash.Bytes()) } } + + return attemptHashM, attemptHashes +} + +func (o *evmTxStore) loadEthTxesAttemptsReceipts(ctx context.Context, etxs []*Tx) (err error) { + if len(etxs) == 0 { + return nil + } + + attemptHashM, attemptHashes := initEthTxesAttempts(etxs) var rs []DbReceipt if err = o.q.SelectContext(ctx, &rs, `SELECT * FROM evm.receipts WHERE tx_hash = ANY($1)`, pq.Array(attemptHashes)); err != nil { return pkgerrors.Wrap(err, "loadEthTxesAttemptsReceipts failed to load evm.receipts") @@ -697,6 +705,37 @@ func (o *evmTxStore) loadEthTxesAttemptsReceipts(ctx context.Context, etxs []*Tx return nil } +// loadEthTxesAttemptsWithPartialReceipts loads ethTxes with attempts and partial receipts values for optimization +func (o *evmTxStore) loadEthTxesAttemptsWithPartialReceipts(ctx context.Context, etxs []*Tx) (err error) { + if len(etxs) == 0 { + return nil + } + + attemptHashM, attemptHashes := initEthTxesAttempts(etxs) + var rs []DbReceipt + if err = o.q.SelectContext(ctx, &rs, `SELECT evm.receipts.block_hash, evm.receipts.block_number, evm.receipts.transaction_index, evm.receipts.tx_hash FROM evm.receipts WHERE tx_hash = ANY($1)`, pq.Array(attemptHashes)); err != nil { + return pkgerrors.Wrap(err, "loadEthTxesAttemptsReceipts failed to load evm.receipts") + } + + receipts := make([]*evmtypes.Receipt, len(rs)) + for i := 0; i < len(rs); i++ { + receipts[i] = &evmtypes.Receipt{ + BlockHash: rs[i].BlockHash, + BlockNumber: big.NewInt(rs[i].BlockNumber), + TransactionIndex: rs[i].TransactionIndex, + TxHash: rs[i].TxHash, + } + } + + for _, receipt := range receipts { + attempt := attemptHashM[receipt.TxHash] + // Although the attempts struct supports multiple receipts, the expectation for EVM is that there is only one receipt + // per tx and therefore attempt too. + attempt.Receipts = append(attempt.Receipts, receipt) + } + return nil +} + func loadConfirmedAttemptsReceipts(ctx context.Context, q sqlutil.DataSource, attempts []TxAttempt) error { byHash := make(map[string]*TxAttempt, len(attempts)) hashes := make([][]byte, len(attempts)) @@ -1172,7 +1211,9 @@ ORDER BY nonce ASC if err = orm.LoadTxesAttempts(ctx, etxs); err != nil { return pkgerrors.Wrap(err, "FindTransactionsConfirmedInBlockRange failed to load evm.tx_attempts") } - err = orm.loadEthTxesAttemptsReceipts(ctx, etxs) + + // retrieve tx with attempts and partial receipt values for optimization purpose + err = orm.loadEthTxesAttemptsWithPartialReceipts(ctx, etxs) return pkgerrors.Wrap(err, "FindTransactionsConfirmedInBlockRange failed to load evm.receipts") }) return etxs, pkgerrors.Wrap(err, "FindTransactionsConfirmedInBlockRange failed") @@ -2068,24 +2109,18 @@ func (o *evmTxStore) UpdateTxAttemptBroadcastBeforeBlockNum(ctx context.Context, return err } -// Returns all confirmed transactions with receipt block nums older than or equal to the finalized block number +// FindConfirmedTxesReceipts Returns all confirmed transactions with receipt block nums older than or equal to the finalized block number func (o *evmTxStore) FindConfirmedTxesReceipts(ctx context.Context, finalizedBlockNum int64, chainID *big.Int) (receipts []Receipt, err error) { var cancel context.CancelFunc ctx, cancel = o.stopCh.Ctx(ctx) defer cancel() - err = o.Transact(ctx, true, func(orm *evmTxStore) error { - sql := `SELECT evm.receipts.* FROM evm.receipts + + // note the receipts are partially loaded for performance reason + query := `SELECT evm.receipts.id, evm.receipts.tx_hash, evm.receipts.block_hash, evm.receipts.block_number FROM evm.receipts INNER JOIN evm.tx_attempts ON evm.tx_attempts.hash = evm.receipts.tx_hash INNER JOIN evm.txes ON evm.txes.id = evm.tx_attempts.eth_tx_id WHERE evm.txes.state = 'confirmed' AND evm.receipts.block_number <= $1 AND evm.txes.evm_chain_id = $2` - var dbReceipts []DbReceipt - err = o.q.SelectContext(ctx, &dbReceipts, sql, finalizedBlockNum, chainID.String()) - if len(dbReceipts) == 0 { - return nil - } - receipts = dbReceipts - return nil - }) + err = o.q.SelectContext(ctx, &receipts, query, finalizedBlockNum, chainID.String()) return receipts, err } diff --git a/core/chains/evm/txmgr/evm_tx_store_test.go b/core/chains/evm/txmgr/evm_tx_store_test.go index 992bd1f434..c711c2788e 100644 --- a/core/chains/evm/txmgr/evm_tx_store_test.go +++ b/core/chains/evm/txmgr/evm_tx_store_test.go @@ -816,6 +816,12 @@ func TestORM_FindTransactionsConfirmedInBlockRange(t *testing.T) { assert.Equal(t, etxes[0].Sequence, etx_8.Sequence) assert.Equal(t, etxes[1].Sequence, etx_9.Sequence) }) + + t.Run("return empty txes when no transactions in range found", func(t *testing.T) { + etxes, err := txStore.FindTransactionsConfirmedInBlockRange(tests.Context(t), 0, 0, ethClient.ConfiguredChainID()) + require.NoError(t, err) + assert.Len(t, etxes, 0) + }) } func TestORM_FindEarliestUnconfirmedBroadcastTime(t *testing.T) { diff --git a/core/chains/evm/txmgr/finalizer.go b/core/chains/evm/txmgr/finalizer.go index 6d5fb81782..6074463615 100644 --- a/core/chains/evm/txmgr/finalizer.go +++ b/core/chains/evm/txmgr/finalizer.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" ) var _ Finalizer = (*evmFinalizer)(nil) @@ -174,7 +175,7 @@ func (f *evmFinalizer) processFinalizedHead(ctx context.Context, latestFinalized // Find transactions with receipt block nums older than the latest finalized block num and block hashes still in chain for _, receipt := range unfinalizedReceipts { // The tx store query ensures transactions have receipts but leaving this check here for a belts and braces approach - if receipt.Receipt.IsZero() || receipt.Receipt.IsUnmined() { + if receipt.TxHash == utils.EmptyHash || receipt.BlockHash == utils.EmptyHash { f.lggr.AssumptionViolationw("invalid receipt found for confirmed transaction", "receipt", receipt) continue } From e4f346a1a4b57c33b5272221e34ca29a03ad9ad8 Mon Sep 17 00:00:00 2001 From: Radek Scheibinger Date: Fri, 23 Aug 2024 09:51:09 +0200 Subject: [PATCH 152/432] Use develop image from sdlc account (#14202) --- .github/workflows/crib-integration-test.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/crib-integration-test.yml b/.github/workflows/crib-integration-test.yml index 0dda07f285..6fcfe28155 100644 --- a/.github/workflows/crib-integration-test.yml +++ b/.github/workflows/crib-integration-test.yml @@ -73,19 +73,20 @@ jobs: echo $GITHUB_WORKSPACE - name: Deploy and validate CRIB Environment for Core - uses: smartcontractkit/.github/actions/crib-deploy-environment@9a4954089045a765eca4bac68f396b2df5a5ea25 # crib-deploy-environment@0.7.1 + uses: smartcontractkit/.github/actions/crib-deploy-environment@4dd21a9d6e3f1383ffe8b9650b55f6e6031d3d0a # crib-deploy-environment@1.0.0 id: deploy-crib with: github-token: ${{ steps.token.outputs.access-token }} api-gateway-host: ${{ secrets.AWS_API_GW_HOST_K8S_STAGE }} aws-region: ${{ secrets.AWS_REGION }} aws-role-arn: ${{ secrets.AWS_OIDC_CRIB_ROLE_ARN_STAGE }} - ecr-private-registry-stage: ${{ secrets.AWS_ACCOUNT_ID_STAGE }} ecr-private-registry: ${{ secrets.AWS_ACCOUNT_ID_PROD }} ingress-base-domain: ${{ secrets.INGRESS_BASE_DOMAIN_STAGE }} k8s-cluster-name: ${{ secrets.AWS_K8S_CLUSTER_NAME_STAGE }} devspace-profiles: "local-dev-simulated-core-ocr1" crib-alert-slack-webhook: ${{ secrets.CRIB_ALERT_SLACK_WEBHOOK }} + product-image: ${{ secrets.AWS_SDLC_ECR_HOSTNAME }}/chainlink + product-image-tag: develop - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Setup go uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 From 822c5070b95dd804471b7ca08d78d53e5a316732 Mon Sep 17 00:00:00 2001 From: Cedric Date: Fri, 23 Aug 2024 12:58:27 +0100 Subject: [PATCH 153/432] [CAPPL] Make copy private so it can't be misused (#14205) --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- core/services/workflows/state.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index f891dc3e14..2fda380e3c 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index d1c8c65a5e..8c8de1ed3a 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1186,8 +1186,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 h1:88WOOrXy7t8IxS+91AKItN/HTzIHvEgFNetZDOhosKc= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097/go.mod h1:HqdnbHS9j9EKPidpSUI9S37zl0blbVjB+NP4ztdYta8= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 h1:+XvRzgHlcaZYLMJ5HR3HzOjvXNmpVKQFZbuHZiRno68= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/core/services/workflows/state.go b/core/services/workflows/state.go index 28eca199a4..cd4247d0ee 100644 --- a/core/services/workflows/state.go +++ b/core/services/workflows/state.go @@ -20,7 +20,7 @@ func copyState(es store.WorkflowExecution) store.WorkflowExecution { mval = step.Inputs.CopyMap() } - copiedov := step.Outputs.Value.Copy() + copiedov := values.Copy(step.Outputs.Value) newState := &store.WorkflowExecutionStep{ ExecutionID: step.ExecutionID, diff --git a/go.mod b/go.mod index 39517d4340..218ecd5c5e 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index c6ade4ce55..29ef71891c 100644 --- a/go.sum +++ b/go.sum @@ -1141,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 h1:88WOOrXy7t8IxS+91AKItN/HTzIHvEgFNetZDOhosKc= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097/go.mod h1:HqdnbHS9j9EKPidpSUI9S37zl0blbVjB+NP4ztdYta8= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 h1:+XvRzgHlcaZYLMJ5HR3HzOjvXNmpVKQFZbuHZiRno68= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index eeb91617a4..ffbdc634af 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -33,7 +33,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 github.com/smartcontractkit/chainlink-testing-framework v1.34.6 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index fc2836ac78..f98d772a37 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1519,8 +1519,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 h1:88WOOrXy7t8IxS+91AKItN/HTzIHvEgFNetZDOhosKc= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097/go.mod h1:HqdnbHS9j9EKPidpSUI9S37zl0blbVjB+NP4ztdYta8= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 h1:+XvRzgHlcaZYLMJ5HR3HzOjvXNmpVKQFZbuHZiRno68= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 4cc2ab9e56..0d5673ecbd 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 github.com/smartcontractkit/chainlink-testing-framework v1.34.6 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 0e463efaa8..d89fe5001b 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1499,8 +1499,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097 h1:88WOOrXy7t8IxS+91AKItN/HTzIHvEgFNetZDOhosKc= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240821145706-0dd95151c097/go.mod h1:HqdnbHS9j9EKPidpSUI9S37zl0blbVjB+NP4ztdYta8= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 h1:+XvRzgHlcaZYLMJ5HR3HzOjvXNmpVKQFZbuHZiRno68= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= From 8e1ae31693d99f5bb6623ccdd24327c2c7357e90 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Fri, 23 Aug 2024 14:52:43 +0200 Subject: [PATCH 154/432] bump github.com/grafana/pyroscope-go/godeltaprof (#14213) --- core/scripts/go.mod | 4 ++-- core/scripts/go.sum | 8 ++++---- go.mod | 4 ++-- go.sum | 8 ++++---- integration-tests/go.mod | 4 ++-- integration-tests/go.sum | 8 ++++---- integration-tests/load/go.mod | 4 ++-- integration-tests/load/go.sum | 8 ++++---- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 2fda380e3c..3982109071 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -171,7 +171,7 @@ require ( github.com/gorilla/sessions v1.2.2 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/grafana/pyroscope-go v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/graph-gophers/dataloader v5.0.0+incompatible // indirect github.com/graph-gophers/graphql-go v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect @@ -213,7 +213,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.3 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 8c8de1ed3a..9bd6bea031 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -667,8 +667,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= @@ -872,8 +872,8 @@ github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= diff --git a/go.mod b/go.mod index 218ecd5c5e..7ec13ace99 100644 --- a/go.mod +++ b/go.mod @@ -223,7 +223,7 @@ require ( github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/gorilla/context v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect @@ -255,7 +255,7 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.3 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect diff --git a/go.sum b/go.sum index 29ef71891c..4174fc39a3 100644 --- a/go.sum +++ b/go.sum @@ -631,8 +631,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= @@ -836,8 +836,8 @@ github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index ffbdc634af..d1a1bdb8e7 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -258,7 +258,7 @@ require ( github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 // indirect github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect github.com/grafana/pyroscope-go v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect @@ -315,7 +315,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.3 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index f98d772a37..50cb7c6898 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -887,8 +887,8 @@ github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 h1:wQ0FnSeeb github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0= github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= @@ -1133,8 +1133,8 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 0d5673ecbd..1918a2ca47 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -247,7 +247,7 @@ require ( github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 // indirect github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect github.com/grafana/pyroscope-go v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect @@ -304,7 +304,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.3 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index d89fe5001b..185539ef57 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -879,8 +879,8 @@ github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 h1:wQ0FnSeeb github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0= github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= @@ -1123,8 +1123,8 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= From 34658958138d29a362c9079cebda2c81fe189480 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:08:50 +0200 Subject: [PATCH 155/432] Update e2e test workflows (#14210) * Update automation on demand workflow * Migrate to the reusable workflow * Remove integration-staging-tests.yml (confirmed with Sergey) --- .github/e2e-tests.yml | 11 + .../workflows/automation-ondemand-tests.yml | 394 ++++++------------ .../workflows/integration-staging-tests.yml | 132 ------ .../run-automation-ondemand-e2e-tests.yml | 171 -------- 4 files changed, 138 insertions(+), 570 deletions(-) delete mode 100644 .github/workflows/integration-staging-tests.yml delete mode 100644 .github/workflows/run-automation-ondemand-e2e-tests.yml diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 3e1fd06b87..3f5c531cfd 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -557,6 +557,17 @@ runner-test-matrix: test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_2 -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg + - id: reorg/automation_reorg_test.go^TestAutomationReorg/registry_2_3 + path: integration-tests/reorg/automation_reorg_test.go + runs_on: ubuntu-latest + test_env_type: docker + test_env_vars: + TEST_SUITE: reorg + workflows: + - Run Automation On Demand Tests (TEST WORKFLOW) + test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_3 -test.parallel=2 -timeout 30m -count=1 -json + pyroscope_env: ci-automation-on-demand-reorg + - id: chaos/automation_chaos_test.go path: integration-tests/chaos/automation_chaos_test.go test_env_type: k8s-remote-runner diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml index 83da3c3d52..ed69bd5ac0 100644 --- a/.github/workflows/automation-ondemand-tests.yml +++ b/.github/workflows/automation-ondemand-tests.yml @@ -1,16 +1,17 @@ -name: Automation On Demand Tests +name: Run Automation On Demand Tests + on: workflow_dispatch: inputs: chainlinkVersionUpdate: - description: Chainlink image version to upgrade to + description: Chainlink image version to upgrade to (Leave empty to build from head/ref) required: false type: string chainlinkImageUpdate: - description: Chainlink image repo to upgrade to (Leave empty to build from head/ref) + description: Chainlink image repo to upgrade to options: - - public.ecr.aws/chainlink/chainlink - QA_ECR + - public.ecr.aws/chainlink/chainlink type: choice chainlinkVersion: description: Chainlink image version to use initially for upgrade test @@ -34,285 +35,144 @@ on: type: boolean default: false required: true - -env: - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ github.sha }} - CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + with_existing_remote_runner_version: + description: 'Tag of the existing remote runner version to use (Leave empty to build from head/ref)' + required: false + type: string jobs: - build-chainlink: - environment: integration - permissions: - id-token: write - contents: read - strategy: - matrix: - image: - - name: "" - dockerfile: core/chainlink.Dockerfile - tag-suffix: "" - - name: (plugins) - dockerfile: plugins/chainlink.Dockerfile - tag-suffix: -plugins - name: Build Chainlink Image ${{ matrix.image.name }} - runs-on: ubuntu22.04-16cores-64GB + # Set tests to run based on the workflow inputs + set-tests-to-run: + name: Set tests to run + runs-on: ubuntu-latest + outputs: + test_list: ${{ steps.set-tests.outputs.test_list }} + require_chainlink_image_versions_in_qa_ecr: ${{ steps.determine-chainlink-image-check.outputs.require_chainlink_image_versions_in_qa_ecr }} steps: - - name: Collect Metrics - if: inputs.chainlinkImage == '' - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: automation-on-demand-build-chainlink - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Chainlink Image ${{ matrix.image.name }} - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ github.head_ref || github.ref_name }} - - name: Check if image exists - if: inputs.chainlinkImage == '' - id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - repository: chainlink - tag: ${{ github.sha }}${{ matrix.image.tag-suffix }} - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - name: Build Image - if: steps.check-image.outputs.exists == 'false' && inputs.chainlinkImage == '' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - cl_repo: smartcontractkit/chainlink - cl_ref: ${{ github.sha }} - cl_dockerfile: ${{ matrix.image.dockerfile }} - push_tag: ${{ env.CHAINLINK_IMAGE }}:${{ github.sha }}${{ matrix.image.tag-suffix }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - name: Print Chainlink Image Built - if: inputs.chainlinkImage == '' - run: | - echo "### chainlink node image tag used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY - - build-test-image: - environment: integration - permissions: - id-token: write - contents: read - name: Build Test Image - runs-on: ubuntu22.04-16cores-64GB - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: automation-on-demand-build-test-image - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Test Image - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ github.head_ref || github.ref_name }} - - name: Build Test Image - if: inputs.enableChaos || inputs.enableReorg - uses: ./.github/actions/build-test-image - with: - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - - automation-on-demand-tests: - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-test-image] - env: - CHAINLINK_COMMIT_SHA: ${{ github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: info - strategy: - fail-fast: false - matrix: - tests: - - name: chaos - id: chaos - suite: chaos - nodes: 20 - os: ubuntu-latest - enabled: ${{ inputs.enableChaos }} - pyroscope_env: ci-automation-on-demand-chaos - network: SIMULATED - command: -run ^TestAutomationChaos$ ./chaos - - name: reorg 2.0 - id: reorg-2.0 - suite: reorg - nodes: 1 - os: ubuntu-latest - enabled: ${{ inputs.enableReorg }} - pyroscope_env: ci-automation-on-demand-reorg - network: SIMULATED - command: -run ^TestAutomationReorg/registry_2_0 ./reorg - - name: reorg 2.1 - id: reorg-2.1 - suite: reorg - nodes: 2 - os: ubuntu-latest - enabled: ${{ inputs.enableReorg }} - pyroscope_env: ci-automation-on-demand-reorg - network: SIMULATED - command: -run ^TestAutomationReorg/registry_2_1 ./reorg - - name: reorg 2.2 - id: reorg-2.2 - suite: reorg - nodes: 2 - os: ubuntu-latest - enabled: ${{ inputs.enableReorg }} - pyroscope_env: ci-automation-on-demand-reorg - network: SIMULATED - command: -run ^TestAutomationReorg/registry_2_2 ./reorg - - name: reorg 2.3 - id: reorg-2.3 - suite: reorg - nodes: 2 - os: ubuntu-latest - enabled: ${{ inputs.enableReorg }} - pyroscope_env: ci-automation-on-demand-reorg - network: SIMULATED - command: -run ^TestAutomationReorg/registry_2_3 ./reorg - - name: upgrade 2.0 - id: upgrade-2.0 - type: upgrade - suite: smoke - nodes: 1 - os: ubuntu22.04-8cores-32GB - enabled: true - pyroscope_env: ci-automation-on-demand-upgrade - network: SIMULATED - command: -run ^TestAutomationNodeUpgrade/registry_2_0 ./smoke - - name: upgrade 2.1 - id: upgrade-2.1 - type: upgrade - suite: smoke - nodes: 5 - os: ubuntu22.04-8cores-32GB - enabled: true - pyroscope_env: ci-automation-on-demand-upgrade - network: SIMULATED - command: -run ^TestAutomationNodeUpgrade/registry_2_1 ./smoke - - name: upgrade 2.2 - id: upgrade-2.2 - type: upgrade - suite: smoke - nodes: 5 - os: ubuntu22.04-8cores-32GB - enabled: true - pyroscope_env: ci-automation-on-demand-upgrade - network: SIMULATED - command: -run ^TestAutomationNodeUpgrade/registry_2_2 ./smoke - runs-on: ${{ matrix.tests.os }} - name: Automation On Demand ${{ matrix.tests.name }} Test - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ github.head_ref || github.ref_name }} - name: Determine build to use id: determine-build shell: bash run: | if [[ "${{ inputs.chainlinkImage }}" == "QA_ECR" ]]; then - echo "image=${{ env.CHAINLINK_IMAGE }}" >>$GITHUB_OUTPUT + echo "image='{{ env.QA_CHAINLINK_IMAGE }}'" >> $GITHUB_ENV else - echo "image=${{ inputs.chainlinkImage }}" >>$GITHUB_OUTPUT + echo "image=${{ inputs.chainlinkImage }}" >> $GITHUB_ENV fi if [[ "${{ inputs.chainlinkImageUpdate }}" == "QA_ECR" ]]; then - echo "upgrade_image=${{ env.CHAINLINK_IMAGE }}" >>$GITHUB_OUTPUT + echo "upgrade_image='{{ env.QA_CHAINLINK_IMAGE }}'" >> $GITHUB_ENV else - echo "upgrade_image=${{ inputs.chainlinkImageUpdate }}" >>$GITHUB_OUTPUT + echo "upgrade_image=${{ inputs.chainlinkImageUpdate }}" >> $GITHUB_ENV fi if [[ -z "${{ inputs.chainlinkVersion }}" ]] && [[ "${{ inputs.chainlinkImage }}" == "QA_ECR" ]]; then - echo "version=${{ github.sha }}" >>$GITHUB_OUTPUT + echo "version=${{ github.sha }}" >> $GITHUB_ENV else - echo "version=${{ inputs.chainlinkVersion }}" >>$GITHUB_OUTPUT + echo "version=${{ inputs.chainlinkVersion }}" >> $GITHUB_ENV fi if [[ -z "${{ inputs.chainlinkVersionUpdate }}" ]] && [[ "${{ inputs.chainlinkImageUpdate }}" == "QA_ECR" ]]; then - echo "upgrade_version=${{ github.sha }}" >>$GITHUB_OUTPUT + echo "upgrade_version=${{ github.sha }}" >> $GITHUB_ENV else - echo "upgrade_version=${{ inputs.chainlinkVersionUpdate }}" >>$GITHUB_OUTPUT + echo "upgrade_version=${{ inputs.chainlinkVersionUpdate }}" >> $GITHUB_ENV + fi + - name: Check if chainlink image check required + id: determine-chainlink-image-check + shell: bash + run: | + chainlink_image_versions="" + if [ "${{ github.event.inputs.chainlinkImage }}" = "QA_ECR" ]; then + chainlink_image_versions+="${{ env.version }}," + fi + if [ "${{ github.event.inputs.chainlinkImageUpdate }}" = "QA_ECR" ]; then + chainlink_image_versions+="${{ env.upgrade_version }}" fi - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 - if: ${{ matrix.tests.enabled == true }} - with: - test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} - test_command_to_run: cd ./integration-tests && go test -timeout 60m -count=1 -json -test.parallel=${{ matrix.tests.nodes }} ${{ matrix.tests.command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_suite: ${{ matrix.tests.suite }} - test_config_chainlink_version: ${{ steps.determine-build.outputs.version }} - test_config_chainlink_upgrade_version: ${{ steps.determine-build.outputs.upgrade_version }} - test_config_selected_networks: ${{ matrix.tests.network }} - test_config_logging_run_id: ${{ github.run_id }} - test_config_logstream_log_targets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - test_config_test_log_collect: "true" - cl_repo: ${{ steps.determine-build.outputs.image }} - cl_image_tag: ${{ steps.determine-build.outputs.version }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_location: ./integration-tests/${{ matrix.tests.suite }}/logs - publish_check_name: Automation On Demand Results ${{ matrix.tests.name }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - DEFAULT_CHAINLINK_IMAGE: ${{ steps.determine-build.outputs.image }} - DEFAULT_CHAINLINK_UPGRADE_IMAGE: ${{ steps.determine-build.outputs.upgrade_image }} - DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - DEFAULT_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - DEFAULT_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - DEFAULT_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} - DEFAULT_PYROSCOPE_ENABLED: ${{ matrix.tests.pyroscope_env == '' || !startsWith(github.ref, 'refs/tags/') && 'false' || 'true' }} - - - name: Upload test log - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 - if: failure() - with: - name: test-log-${{ matrix.tests.name }} - path: /tmp/gotest.log - retention-days: 7 - continue-on-error: true - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: automation-on-demand-tests-${{ matrix.tests.id }} - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Automation On Demand ${{ matrix.tests.name }} Test - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true + echo "require_chainlink_image_versions_in_qa_ecr=$chainlink_image_versions" >> $GITHUB_OUTPUT + - name: Set tests to run + id: set-tests + run: | + + # Always run upgrade tests + cat > test_list.yaml <> test_list.yaml <> test_list.yaml <> $GITHUB_OUTPUT + + call-run-e2e-tests-workflow: + name: Run E2E Tests + needs: set-tests-to-run + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + test_list: ${{ needs.set-tests-to-run.outputs.test_list }} + require_chainlink_image_versions_in_qa_ecr: ${{ needs.set-tests-to-run.outputs.require_chainlink_image_versions_in_qa_ecr }} + with_existing_remote_runner_version: ${{ github.event.inputs.with_existing_remote_runner_version }} + test_log_upload_on_failure: true + test_log_upload_retention_days: 7 + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + diff --git a/.github/workflows/integration-staging-tests.yml b/.github/workflows/integration-staging-tests.yml deleted file mode 100644 index d092b2bca1..0000000000 --- a/.github/workflows/integration-staging-tests.yml +++ /dev/null @@ -1,132 +0,0 @@ -# NEEDS ADJUSTING TO TOML CONFIG BEFORE USING!! -name: E2E Functions staging tests - -on: -# TODO: enable when env will be stable -# schedule: -# - cron: "0 0 * * *" - workflow_dispatch: - inputs: - network: - description: Blockchain network (testnet) - type: choice - default: "MUMBAI" - options: - - "MUMBAI" - test_type: - description: Test type - type: choice - default: "mumbai_functions_soak_test_real" - options: - - "mumbai_functions_soak_test_http" - - "mumbai_functions_stress_test_http" - - "mumbai_functions_soak_test_only_secrets" - - "mumbai_functions_stress_test_only_secrets" - - "mumbai_functions_soak_test_real" - - "mumbai_functions_stress_test_real" -# TODO: disabled, need GATI access -# - "gateway_secrets_set_soak_test" -# - "gateway_secrets_list_soak_test" - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - e2e-soak-test: - environment: sdlc - runs-on: ubuntu22.04-8cores-32GB - permissions: - contents: read - id-token: write - env: - LOKI_URL: ${{ secrets.LOKI_URL }} - LOKI_TOKEN: ${{ secrets.LOKI_TOKEN }} - SELECTED_NETWORKS: ${{ inputs.network }} - SELECTED_TEST: ${{ inputs.test_type }} - MUMBAI_URLS: ${{ secrets.FUNCTIONS_STAGING_MUMBAI_URLS }} - MUMBAI_KEYS: ${{ secrets.FUNCTIONS_STAGING_MUMBAI_KEYS }} - WASP_LOG_LEVEL: info - steps: - - name: Checkout code - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Prepare Base64 TOML override - env: - PYROSCOPE_SERVER: ${{ secrets.QA_PYROSCOPE_INSTANCE }} - PYROSCOPE_ENVIRONMENT: ci-smoke-${{ matrix.product }}-sepolia - PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - run: | - convert_to_toml_array() { - local IFS=',' - local input_array=($1) - local toml_array_format="[" - - for element in "${input_array[@]}"; do - toml_array_format+="\"$element\"," - done - - toml_array_format="${toml_array_format%,}]" - echo "$toml_array_format" - } - - if [ -n "$PYROSCOPE_SERVER" ]; then - pyroscope_enabled=true - else - pyroscope_enabled=false - fi - - cat << EOF > config.toml - [Common] - chainlink_node_funding=0.5 - - [ChainlinkImage] - image="$CHAINLINK_IMAGE" - version="${{ github.sha }}" - - [Pyroscope] - enabled=$pyroscope_enabled - server_url="$PYROSCOPE_SERVER" - environment="$PYROSCOPE_ENVIRONMENT" - key_secret="$PYROSCOPE_KEY" - - [Logging] - run_id="$RUN_ID" - - [Logging.LogStream] - log_targets=$log_targets - - [Logging.Loki] - tenant_id="$LOKI_TENANT_ID" - endpoint="$LOKI_URL" - basic_auth_secret="$LOKI_BASIC_AUTH" - - [Logging.Grafana] - base_url="$GRAFANA_URL" - dashboard_url="/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - - [Network] - selected_networks=["sepolia"] - - [Network.RpcHttpUrls] - sepolia = $(convert_to_toml_array "$SEPOLIA_HTTP_URLS") - - [Network.RpcWsUrls] - sepolia = $(convert_to_toml_array "$SEPOLIA_URLS") - - [Network.WalletKeys] - sepolia = $(convert_to_toml_array "$EVM_KEYS") - EOF - - BASE64_CONFIG_OVERRIDE=$(cat config.toml | base64 -w 0) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - name: Run E2E soak tests - run: | - cd integration-tests/load/functions - if [[ $SELECTED_TEST == mumbai_functions* ]]; then - go test -v -timeout 6h -run TestFunctionsLoad/$SELECTED_TEST - elif [[ $SELECTED_TEST == gateway* ]]; then - go test -v -timeout 6h -run TestGatewayLoad/$SELECTED_TEST - fi \ No newline at end of file diff --git a/.github/workflows/run-automation-ondemand-e2e-tests.yml b/.github/workflows/run-automation-ondemand-e2e-tests.yml deleted file mode 100644 index 9e62b1557a..0000000000 --- a/.github/workflows/run-automation-ondemand-e2e-tests.yml +++ /dev/null @@ -1,171 +0,0 @@ -name: Run Automation On Demand Tests (TEST WORKFLOW) - -on: - workflow_dispatch: - inputs: - chainlinkVersionUpdate: - description: Chainlink image version to upgrade to (Leave empty to build from head/ref) - required: false - type: string - chainlinkImageUpdate: - description: Chainlink image repo to upgrade to - options: - - QA_ECR - - public.ecr.aws/chainlink/chainlink - type: choice - chainlinkVersion: - description: Chainlink image version to use initially for upgrade test - default: latest - required: true - type: string - chainlinkImage: - description: Chainlink image repo to use initially for upgrade test - required: true - options: - - public.ecr.aws/chainlink/chainlink - - QA_ECR - type: choice - enableChaos: - description: Check to enable chaos tests - type: boolean - default: false - required: true - enableReorg: - description: Check to enable reorg tests - type: boolean - default: false - required: true - with_existing_remote_runner_version: - description: 'Tag of the existing remote runner version to use (Leave empty to build from head/ref)' - required: false - type: string - -jobs: - # Set tests to run based on the workflow inputs - set-tests-to-run: - name: Set tests to run - runs-on: ubuntu-latest - outputs: - test_list: ${{ steps.set-tests.outputs.test_list }} - require_chainlink_image_versions_in_qa_ecr: ${{ steps.determine-chainlink-image-check.outputs.require_chainlink_image_versions_in_qa_ecr }} - steps: - - name: Determine build to use - id: determine-build - shell: bash - run: | - if [[ "${{ inputs.chainlinkImage }}" == "QA_ECR" ]]; then - echo "image='{{ env.QA_CHAINLINK_IMAGE }}'" >>$GITHUB_OUTPUT - else - echo "image=${{ inputs.chainlinkImage }}" >>$GITHUB_OUTPUT - fi - if [[ "${{ inputs.chainlinkImageUpdate }}" == "QA_ECR" ]]; then - echo "upgrade_image='{{ env.QA_CHAINLINK_IMAGE }}'" >>$GITHUB_OUTPUT - else - echo "upgrade_image=${{ inputs.chainlinkImageUpdate }}" >>$GITHUB_OUTPUT - fi - if [[ -z "${{ inputs.chainlinkVersion }}" ]] && [[ "${{ inputs.chainlinkImage }}" == "QA_ECR" ]]; then - echo "version=${{ github.sha }}" >>$GITHUB_OUTPUT - else - echo "version=${{ inputs.chainlinkVersion }}" >>$GITHUB_OUTPUT - fi - if [[ -z "${{ inputs.chainlinkVersionUpdate }}" ]] && [[ "${{ inputs.chainlinkImageUpdate }}" == "QA_ECR" ]]; then - echo "upgrade_version=${{ github.sha }}" >>$GITHUB_OUTPUT - else - echo "upgrade_version=${{ inputs.chainlinkVersionUpdate }}" >>$GITHUB_OUTPUT - fi - - name: Check if chainlink image check required - id: determine-chainlink-image-check - shell: bash - run: | - chainlink_image_versions="" - if [ "${{ github.event.inputs.chainlinkImage }}" = "QA_ECR" ]; then - chainlink_image_versions+="${{ steps.determine-build.outputs.version }}," - fi - if [ "${{ github.event.inputs.chainlinkImageUpdate }}" = "QA_ECR" ]; then - chainlink_image_versions+="${{ steps.determine-build.outputs.upgrade_version }}" - fi - echo "require_chainlink_image_versions_in_qa_ecr=$chainlink_image_versions" >> $GITHUB_OUTPUT - - name: Set tests to run - id: set-tests - run: | - - # Always run upgrade tests - cat > test_list.yaml <> test_list.yaml <> test_list.yaml <> $GITHUB_OUTPUT - - call-run-e2e-tests-workflow: - name: Run E2E Tests - needs: set-tests-to-run - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml - with: - test_list: ${{ needs.set-tests-to-run.outputs.test_list }} - require_chainlink_image_versions_in_qa_ecr: ${{ needs.set-tests-to-run.outputs.require_chainlink_image_versions_in_qa_ecr }} - with_existing_remote_runner_version: ${{ github.event.inputs.with_existing_remote_runner_version }} - test_log_upload_on_failure: true - test_log_upload_retention_days: 7 - secrets: - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} - QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} - GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - From 3335b7e289378940e407091aee81058ece1385bb Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Fri, 23 Aug 2024 16:46:10 +0200 Subject: [PATCH 156/432] simplify modgraph (#14169) * simplify modgraph * group tdh2 --- go.md | 13 +++++++------ tools/bin/modgraph | 13 +++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/go.md b/go.md index 697d6b52ce..f58a5e23e4 100644 --- a/go.md +++ b/go.md @@ -5,11 +5,7 @@ flowchart LR chainlink-cosmos chainlink-solana chainlink-starknet/relayer - subgraph chainlink-integrations - direction LR - chainlink-integrations/evm/relayer - chainlink-integrations/common - end + chainlink-evm end subgraph products @@ -21,8 +17,13 @@ flowchart LR chainlink-vrf end + subgraph tdh2 + tdh2/go/tdh2 + tdh2/go/ocr2/decryptionplugin + end + classDef outline stroke-dasharray:6,fill:none; - class chains,products outline + class chains,products,tdh2 outline chainlink/v2 --> chain-selectors click chain-selectors href "https://github.com/smartcontractkit/chain-selectors" diff --git a/tools/bin/modgraph b/tools/bin/modgraph index 4d8ad108c6..4080e53abe 100755 --- a/tools/bin/modgraph +++ b/tools/bin/modgraph @@ -11,11 +11,7 @@ flowchart LR chainlink-cosmos chainlink-solana chainlink-starknet/relayer - subgraph chainlink-integrations - direction LR - chainlink-integrations/evm/relayer - chainlink-integrations/common - end + chainlink-evm end subgraph products @@ -27,8 +23,13 @@ flowchart LR chainlink-vrf end + subgraph tdh2 + tdh2/go/tdh2 + tdh2/go/ocr2/decryptionplugin + end + classDef outline stroke-dasharray:6,fill:none; - class chains,products outline + class chains,products,tdh2 outline " go mod graph | \ # org only From 977c78af75303d2a97a2854046c97c6690c2ec9a Mon Sep 17 00:00:00 2001 From: Ryan Tinianov Date: Fri, 23 Aug 2024 11:10:13 -0400 Subject: [PATCH 157/432] Add reference to capability request in the engine (#14168) * Add reference to capability request in the engine * add trigger ref and fix version of common... --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- core/services/workflows/engine.go | 7 +++++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 9 files changed, 17 insertions(+), 14 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 3982109071..27073b9ab1 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -272,7 +272,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 9bd6bea031..217c2c19e2 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1190,8 +1190,8 @@ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index c85d4a03b2..aa186f7650 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -338,10 +338,11 @@ func (e *Engine) registerTrigger(ctx context.Context, t *triggerCapability, trig triggerRegRequest := capabilities.CapabilityRequest{ Metadata: capabilities.RequestMetadata{ WorkflowID: e.workflow.id, + WorkflowOwner: e.workflow.owner, + WorkflowName: e.workflow.name, WorkflowDonID: e.localNode.WorkflowDON.ID, WorkflowDonConfigVersion: e.localNode.WorkflowDON.ConfigVersion, - WorkflowName: e.workflow.name, - WorkflowOwner: e.workflow.owner, + ReferenceID: t.Ref, }, Config: t.config.Load(), Inputs: triggerInputs, @@ -763,6 +764,7 @@ func (e *Engine) executeStep(ctx context.Context, msg stepRequest) (*values.Map, WorkflowName: e.workflow.name, WorkflowDonID: e.localNode.WorkflowDON.ID, WorkflowDonConfigVersion: e.localNode.WorkflowDON.ConfigVersion, + ReferenceID: msg.stepRef, }, } @@ -790,6 +792,7 @@ func (e *Engine) deregisterTrigger(ctx context.Context, t *triggerCapability, tr WorkflowDonConfigVersion: e.localNode.WorkflowDON.ConfigVersion, WorkflowName: e.workflow.name, WorkflowOwner: e.workflow.owner, + ReferenceID: t.Ref, }, Inputs: triggerInputs, Config: t.config.Load(), diff --git a/go.mod b/go.mod index 7ec13ace99..22df244575 100644 --- a/go.mod +++ b/go.mod @@ -77,7 +77,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 diff --git a/go.sum b/go.sum index 4174fc39a3..13f045ef2c 100644 --- a/go.sum +++ b/go.sum @@ -1145,8 +1145,8 @@ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index d1a1bdb8e7..708a369fc9 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -397,7 +397,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 50cb7c6898..b8c3d5c94a 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1523,8 +1523,8 @@ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 1918a2ca47..ba5c1d3ef9 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -388,7 +388,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 185539ef57..7f6dddca8d 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1503,8 +1503,8 @@ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f h1:I9fTBJpHkeldFplXUy71eLIn6A6GxuR4xrABoUeD+CM= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240801131703-fd75761c982f/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= From 25d29611543c3d43484c168e7efc23a7bf83f035 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata <96521086+bukata-sa@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:08:43 +0100 Subject: [PATCH 158/432] fix: head report chain_id (#14212) * fix: head report chain_id * test --- .changeset/swift-pumas-taste.md | 5 ++ .../headreporter/telemetry_reporter.go | 1 + .../headreporter/telemetry_reporter_test.go | 2 + .../telem/telem_head_report.pb.go | 47 ++++++++++--------- 4 files changed, 32 insertions(+), 23 deletions(-) create mode 100644 .changeset/swift-pumas-taste.md diff --git a/.changeset/swift-pumas-taste.md b/.changeset/swift-pumas-taste.md new file mode 100644 index 0000000000..eb08662e20 --- /dev/null +++ b/.changeset/swift-pumas-taste.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal add head report chain_id diff --git a/core/services/headreporter/telemetry_reporter.go b/core/services/headreporter/telemetry_reporter.go index 93852f44c0..0d93ca59a4 100644 --- a/core/services/headreporter/telemetry_reporter.go +++ b/core/services/headreporter/telemetry_reporter.go @@ -44,6 +44,7 @@ func (t *telemetryReporter) ReportNewHead(ctx context.Context, head *evmtypes.He } } request := &telem.HeadReportRequest{ + ChainID: head.EVMChainID.String(), Latest: &telem.Block{ Timestamp: uint64(head.Timestamp.UTC().Unix()), Number: uint64(head.Number), diff --git a/core/services/headreporter/telemetry_reporter_test.go b/core/services/headreporter/telemetry_reporter_test.go index 58c0935490..85bfea5866 100644 --- a/core/services/headreporter/telemetry_reporter_test.go +++ b/core/services/headreporter/telemetry_reporter_test.go @@ -35,6 +35,7 @@ func Test_TelemetryReporter_NewHead(t *testing.T) { }, } requestBytes, err := proto.Marshal(&telem.HeadReportRequest{ + ChainID: "100", Latest: &telem.Block{ Timestamp: uint64(head.Timestamp.UTC().Unix()), Number: 42, @@ -70,6 +71,7 @@ func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { IsFinalized: false, } requestBytes, err := proto.Marshal(&telem.HeadReportRequest{ + ChainID: "100", Latest: &telem.Block{ Timestamp: uint64(head.Timestamp.UTC().Unix()), Number: 42, diff --git a/core/services/synchronization/telem/telem_head_report.pb.go b/core/services/synchronization/telem/telem_head_report.pb.go index 18e4532472..12801314a7 100644 --- a/core/services/synchronization/telem/telem_head_report.pb.go +++ b/core/services/synchronization/telem/telem_head_report.pb.go @@ -25,7 +25,7 @@ type HeadReportRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Chain string `protobuf:"bytes,1,opt,name=chain,proto3" json:"chain,omitempty"` + ChainID string `protobuf:"bytes,1,opt,name=chainID,proto3" json:"chainID,omitempty"` Latest *Block `protobuf:"bytes,2,opt,name=latest,proto3" json:"latest,omitempty"` Finalized *Block `protobuf:"bytes,3,opt,name=finalized,proto3,oneof" json:"finalized,omitempty"` } @@ -62,9 +62,9 @@ func (*HeadReportRequest) Descriptor() ([]byte, []int) { return file_core_services_synchronization_telem_telem_head_report_proto_rawDescGZIP(), []int{0} } -func (x *HeadReportRequest) GetChain() string { +func (x *HeadReportRequest) GetChainID() string { if x != nil { - return x.Chain + return x.ChainID } return "" } @@ -153,26 +153,27 @@ var file_core_services_synchronization_telem_telem_head_report_proto_rawDesc = [ 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x74, - 0x65, 0x6c, 0x65, 0x6d, 0x22, 0x8e, 0x01, 0x0a, 0x11, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x12, 0x24, 0x0a, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x06, - 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, - 0x7a, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c, - 0x69, 0x7a, 0x65, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x66, 0x69, 0x6e, 0x61, - 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x51, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1c, - 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, - 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, - 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x42, 0x4e, 0x5a, 0x4c, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x61, 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x69, 0x6e, - 0x6b, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x6c, 0x65, 0x6d, 0x22, 0x92, 0x01, 0x0a, 0x11, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x49, 0x44, 0x12, 0x24, 0x0a, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x52, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x09, 0x66, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x09, 0x66, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, + 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x51, 0x0a, 0x05, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x42, 0x4e, 0x5a, 0x4c, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( From 65998c414f1d44d8be1a90d957e1bc5a92409443 Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Fri, 23 Aug 2024 15:45:27 -0400 Subject: [PATCH 159/432] Bump version and update CHANGELOG for core v2.15.0 (#13947) * Bump version and update CHANGELOG fore core v2.15.0 Signed-off-by: chainchad <96362174+chainchad@users.noreply.github.com> * Fix syntax error in workflow (#13952) (cherry picked from commit 7147653630cd24389e0a3ddab7c56f74a2f0c5b1) * Bump slack-notify-git-ref action for fixes * Cleanup old CRIB file * Use changeset github changelog generator * Fix version * Finalize date on changelog for 2.15.0 (#14144) Signed-off-by: chainchad <96362174+chainchad@users.noreply.github.com> * Use correct changelog generator for changesets --------- Signed-off-by: chainchad <96362174+chainchad@users.noreply.github.com> Co-authored-by: Thanh Nguyen --- .github/workflows/build-publish.yml | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index 0941455a16..033526e033 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -144,7 +144,7 @@ jobs: - name: Checkout repository uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Notify Slack - uses: smartcontractkit/.github/actions/slack-notify-git-ref@7fa90bbeff35aa6ce3a9054f542bcf10b7d47cec # slack-notify-git-ref@0.1.0 + uses: smartcontractkit/.github/actions/slack-notify-git-ref@31e00facdd8f57a2bc7868b5e4c8591bf2aa3727 # slack-notify-git-ref@0.1.2 with: slack-channel-id: ${{ secrets.SLACK_CHANNEL_RELEASE_NOTIFICATIONS }} slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN_RELENG }} # Releng Bot diff --git a/CHANGELOG.md b/CHANGELOG.md index a521df865b..780c68003f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog Chainlink Core -## 2.15.0 +## 2.15.0 - 2024-08-21 ### Minor Changes From af335c1a522769c8c29858d8d6510330af3204cf Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 23 Aug 2024 15:46:50 -0400 Subject: [PATCH 160/432] Support v0.3 schema report format in LLO (#13780) * Support v0.3 legacy reports in streams - Add 'stream' to allowed job type list - Improve streams logging; add "Verbose" option - Bump chainlink-data-streams - Fix some LLO bugs - Close MERC-3525 - Close MERC-4184 - Close MERC-5934 - Handle case where LINK or NATIVE price query fails - Close MERC-5952 * Fix rebase * Prettier * Bump migration number --- .changeset/nice-turtles-begin.md | 5 + contracts/.changeset/eight-timers-sip.md | 5 + .../v0.8/llo-feeds/dev/ChannelConfigStore.sol | 92 +-- .../dev/interfaces/IChannelConfigStore.sol | 26 +- .../dev/test/ChannelConfigStore.t.sol | 41 ++ .../test/mocks/ExposedChannelConfigStore.sol | 15 + core/chains/evm/utils/big/big.go | 5 + core/cmd/shell.go | 3 +- .../channel_config_store.go | 352 +---------- ...rapper-dependency-versions-do-not-edit.txt | 2 +- core/internal/testutils/testutils.go | 13 + core/services/chainlink/relayer_factory.go | 3 + core/services/llo/bm/dummy_transmitter.go | 54 +- .../llo/channel_definition_cache_factory.go | 29 +- core/services/llo/codecs.go | 18 + core/services/llo/codecs_test.go | 16 + core/services/llo/data_source.go | 75 ++- core/services/llo/data_source_test.go | 14 +- core/services/llo/delegate.go | 5 +- core/services/llo/evm/fees.go | 31 + core/services/llo/evm/fees_test.go | 45 ++ .../llo/evm/report_codec_premium_legacy.go | 173 ++++++ .../evm/report_codec_premium_legacy_test.go | 107 ++++ core/services/llo/keyring.go | 68 ++- core/services/llo/keyring_test.go | 115 ++++ .../llo/onchain_channel_definition_cache.go | 463 ++++++++++---- .../onchain_channel_definition_cache_test.go | 436 ++++++++++++- core/services/llo/onchain_config.go | 21 - core/services/llo/orm.go | 59 +- core/services/llo/orm_test.go | 231 ++++--- core/services/llo/transmitter.go | 50 +- core/services/ocr2/delegate.go | 25 +- .../ocr2/plugins/llo/config/config.go | 14 +- .../ocr2/plugins/llo/config/config_test.go | 9 +- .../services/ocr2/plugins/llo/helpers_test.go | 532 ++++++++++++++++ .../ocr2/plugins/llo/integration_test.go | 463 ++++++++++++++ ...annel_definition_cache_integration_test.go | 578 +++++++++++------- .../ocr2/plugins/mercury/integration_test.go | 6 +- core/services/relay/dummy/config_provider.go | 2 +- core/services/relay/dummy/config_tracker.go | 2 +- core/services/relay/dummy/llo_provider.go | 4 - core/services/relay/evm/evm.go | 9 +- core/services/relay/evm/llo_provider.go | 4 - .../relay/evm/mercury/verifier/verifier.go | 111 ++++ .../evm/mercury/verifier/verifier_test.go | 80 +++ core/services/streams/stream.go | 34 -- core/services/streams/stream_test.go | 33 - ...0251_add_don_id_to_channel_definitions.sql | 13 + core/utils/http/http.go | 45 +- core/utils/http/http_allowed_ips.go | 2 +- core/utils/utils.go | 17 + 51 files changed, 3471 insertions(+), 1084 deletions(-) create mode 100644 .changeset/nice-turtles-begin.md create mode 100644 contracts/.changeset/eight-timers-sip.md create mode 100644 contracts/src/v0.8/llo-feeds/dev/test/ChannelConfigStore.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelConfigStore.sol create mode 100644 core/services/llo/codecs.go create mode 100644 core/services/llo/codecs_test.go create mode 100644 core/services/llo/evm/fees.go create mode 100644 core/services/llo/evm/fees_test.go create mode 100644 core/services/llo/evm/report_codec_premium_legacy.go create mode 100644 core/services/llo/evm/report_codec_premium_legacy_test.go create mode 100644 core/services/llo/keyring_test.go delete mode 100644 core/services/llo/onchain_config.go create mode 100644 core/services/ocr2/plugins/llo/helpers_test.go create mode 100644 core/services/ocr2/plugins/llo/integration_test.go create mode 100644 core/services/relay/evm/mercury/verifier/verifier.go create mode 100644 core/services/relay/evm/mercury/verifier/verifier_test.go create mode 100644 core/store/migrate/migrations/0251_add_don_id_to_channel_definitions.sql diff --git a/.changeset/nice-turtles-begin.md b/.changeset/nice-turtles-begin.md new file mode 100644 index 0000000000..70753dfe04 --- /dev/null +++ b/.changeset/nice-turtles-begin.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Further development of LLO plugin (parallel composition) #wip diff --git a/contracts/.changeset/eight-timers-sip.md b/contracts/.changeset/eight-timers-sip.md new file mode 100644 index 0000000000..3f81544e34 --- /dev/null +++ b/contracts/.changeset/eight-timers-sip.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +Add new channel definitions config store contract for parallel compositions #added diff --git a/contracts/src/v0.8/llo-feeds/dev/ChannelConfigStore.sol b/contracts/src/v0.8/llo-feeds/dev/ChannelConfigStore.sol index 6c6a5ec9b3..086379b210 100644 --- a/contracts/src/v0.8/llo-feeds/dev/ChannelConfigStore.sol +++ b/contracts/src/v0.8/llo-feeds/dev/ChannelConfigStore.sol @@ -6,97 +6,21 @@ import {IChannelConfigStore} from "./interfaces/IChannelConfigStore.sol"; import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; contract ChannelConfigStore is ConfirmedOwner, IChannelConfigStore, TypeAndVersionInterface { - mapping(uint32 => ChannelDefinition) private s_channelDefinitions; - - // mapping(bytes32 => ChannelConfiguration) private s_channelProductionConfigurations; - // mapping(bytes32 => ChannelConfiguration) private s_channelStagingConfigurations; - - event NewChannelDefinition(uint32 channelId, ChannelDefinition channelDefinition); - event ChannelDefinitionRemoved(uint32 channelId); - // event NewProductionConfig(ChannelConfiguration channelConfig); - // event NewStagingConfig(ChannelConfiguration channelConfig); - event PromoteStagingConfig(uint32 channelId); - - error OnlyCallableByEOA(); - error StagingConfigAlreadyPromoted(); - error EmptyStreamIDs(); - error ZeroReportFormat(); - error ZeroChainSelector(); - error ChannelDefinitionNotFound(); + event NewChannelDefinition(uint256 indexed donId, uint32 version, string url, bytes32 sha); constructor() ConfirmedOwner(msg.sender) {} - // function setStagingConfig(bytes32 configDigest, ChannelConfiguration calldata channelConfig) external onlyOwner { - // s_channelStagingConfigurations[channelId] = channelConfig; - - // emit NewStagingConfig(channelConfig); - // } - - //// this will trigger the following: - //// - offchain ShouldRetireCache will start returning true for the old (production) - //// protocol instance - //// - once the old production instance retires it will generate a handover - //// retirement report - //// - the staging instance will become the new production instance once - //// any honest oracle that is on both instances forward the retirement - //// report from the old instance to the new instace via the - //// PredecessorRetirementReportCache - //// - //// Note: the promotion flow only works if the previous production instance - //// is working correctly & generating reports. If that's not the case, the - //// owner is expected to "setProductionConfig" directly instead. This will - //// cause "gaps" to be created, but that seems unavoidable in such a scenario. - // function promoteStagingConfig(bytes32 configDigest) external onlyOwner { - // ChannelConfiguration memory stagingConfig = s_channelStagingConfigurations[channelId]; - - // if(stagingConfig.channelConfigId.length == 0) { - // revert StagingConfigAlreadyPromoted(); - // } - - // s_channelProductionConfigurations[channelId] = s_channelStagingConfigurations[channelId]; - - // emit PromoteStagingConfig(channelId); - // } - - function addChannel(uint32 channelId, ChannelDefinition calldata channelDefinition) external onlyOwner { - if (channelDefinition.streamIDs.length == 0) { - revert EmptyStreamIDs(); - } - - if (channelDefinition.chainSelector == 0) { - revert ZeroChainSelector(); - } - - if (channelDefinition.reportFormat == 0) { - revert ZeroReportFormat(); - } - - s_channelDefinitions[channelId] = channelDefinition; - - emit NewChannelDefinition(channelId, channelDefinition); - } - - function removeChannel(uint32 channelId) external onlyOwner { - if (s_channelDefinitions[channelId].streamIDs.length == 0) { - revert ChannelDefinitionNotFound(); - } - - delete s_channelDefinitions[channelId]; - - emit ChannelDefinitionRemoved(channelId); - } - - function getChannelDefinitions(uint32 channelId) external view returns (ChannelDefinition memory) { - // solhint-disable-next-line avoid-tx-origin - if (msg.sender != tx.origin) { - revert OnlyCallableByEOA(); - } + /// @notice The version of a channel definition keyed by DON ID + // Increments by 1 on every update + mapping(uint256 => uint256) internal s_channelDefinitionVersions; - return s_channelDefinitions[channelId]; + function setChannelDefinitions(uint32 donId, string calldata url, bytes32 sha) external onlyOwner { + uint32 newVersion = uint32(++s_channelDefinitionVersions[uint256(donId)]); + emit NewChannelDefinition(donId, newVersion, url, sha); } function typeAndVersion() external pure override returns (string memory) { - return "ChannelConfigStore 0.0.0"; + return "ChannelConfigStore 0.0.1"; } function supportsInterface(bytes4 interfaceId) external pure returns (bool) { diff --git a/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol b/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol index 45e3ee313d..873928b6de 100644 --- a/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol +++ b/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol @@ -4,29 +4,5 @@ pragma solidity 0.8.19; import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; interface IChannelConfigStore is IERC165 { - // function setStagingConfig(bytes32 configDigest, ChannelConfiguration calldata channelConfig) external; - - // function promoteStagingConfig(bytes32 configDigest) external; - - function addChannel(uint32 channelId, ChannelDefinition calldata channelDefinition) external; - - function removeChannel(uint32 channelId) external; - - function getChannelDefinitions(uint32 channelId) external view returns (ChannelDefinition memory); - - // struct ChannelConfiguration { - // bytes32 configDigest; - // } - - struct ChannelDefinition { - // e.g. evm, solana, CosmWasm, kalechain, etc... - uint32 reportFormat; - // Specifies the chain on which this channel can be verified. Currently uses - // CCIP chain selectors, but lots of other schemes are possible as well. - uint64 chainSelector; - // We assume that StreamIDs is always non-empty and that the 0-th stream - // contains the verification price in LINK and the 1-st stream contains the - // verification price in the native coin. - uint32[] streamIDs; - } + function setChannelDefinitions(uint32 donId, string calldata url, bytes32 sha) external; } diff --git a/contracts/src/v0.8/llo-feeds/dev/test/ChannelConfigStore.t.sol b/contracts/src/v0.8/llo-feeds/dev/test/ChannelConfigStore.t.sol new file mode 100644 index 0000000000..70b033e66b --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/dev/test/ChannelConfigStore.t.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {IChannelConfigStore} from "../interfaces/IChannelConfigStore.sol"; +import {Test} from "forge-std/Test.sol"; +import {ChannelConfigStore} from "../ChannelConfigStore.sol"; +import {ExposedChannelConfigStore} from "./mocks/ExposedChannelConfigStore.sol"; + +/** + * @title ChannelConfigStoreTest + * @author samsondav + * @notice Base class for ChannelConfigStore tests + */ +contract ChannelConfigStoreTest is Test { + ExposedChannelConfigStore public channelConfigStore; + event NewChannelDefinition(uint256 indexed donId, uint32 version, string url, bytes32 sha); + + function setUp() public virtual { + channelConfigStore = new ExposedChannelConfigStore(); + } + + function testTypeAndVersion() public view { + assertEq(channelConfigStore.typeAndVersion(), "ChannelConfigStore 0.0.1"); + } + + function testSupportsInterface() public view { + assertTrue(channelConfigStore.supportsInterface(type(IChannelConfigStore).interfaceId)); + } + + function testSetChannelDefinitions() public { + vm.expectEmit(); + emit NewChannelDefinition(42, 1, "url", keccak256("sha")); + channelConfigStore.setChannelDefinitions(42, "url", keccak256("sha")); + + vm.expectEmit(); + emit NewChannelDefinition(42, 2, "url2", keccak256("sha2")); + channelConfigStore.setChannelDefinitions(42, "url2", keccak256("sha2")); + + assertEq(channelConfigStore.exposedReadChannelDefinitionStates(42), uint32(2)); + } +} diff --git a/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelConfigStore.sol b/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelConfigStore.sol new file mode 100644 index 0000000000..1ffd51210f --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelConfigStore.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ChannelConfigStore} from "../../ChannelConfigStore.sol"; + +// Exposed ChannelConfigStore exposes certain internal ChannelConfigStore +// methods/structures so that golang code can access them, and we get +// reliable type checking on their usage +contract ExposedChannelConfigStore is ChannelConfigStore { + constructor() {} + + function exposedReadChannelDefinitionStates(uint256 donId) public view returns (uint256) { + return s_channelDefinitionVersions[donId]; + } +} diff --git a/core/chains/evm/utils/big/big.go b/core/chains/evm/utils/big/big.go index 4bb51e2732..5706fda45b 100644 --- a/core/chains/evm/utils/big/big.go +++ b/core/chains/evm/utils/big/big.go @@ -188,3 +188,8 @@ func (b *Big) Sub(c *Big) *Big { func (b *Big) Mod(c *Big) *Big { return New(bigmath.Mod(b.ToInt(), c.ToInt())) } + +// IsZero returns true if b is zero +func (b *Big) IsZero() bool { + return b.ToInt().Sign() == 0 +} diff --git a/core/cmd/shell.go b/core/cmd/shell.go index 5c864b82cd..515cc96869 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -168,6 +168,7 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G capabilitiesRegistry := capabilities.NewRegistry(appLggr) + unrestrictedClient := clhttp.NewUnrestrictedHTTPClient() // create the relayer-chain interoperators from application configuration relayerFactory := chainlink.RelayerFactory{ Logger: appLggr, @@ -175,6 +176,7 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G GRPCOpts: grpcOpts, MercuryPool: mercuryPool, CapabilitiesRegistry: capabilitiesRegistry, + HTTPClient: unrestrictedClient, } evmFactoryCfg := chainlink.EVMFactoryConfig{ @@ -228,7 +230,6 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G } restrictedClient := clhttp.NewRestrictedHTTPClient(cfg.Database(), appLggr) - unrestrictedClient := clhttp.NewUnrestrictedHTTPClient() externalInitiatorManager := webhook.NewExternalInitiatorManager(ds, unrestrictedClient) return chainlink.NewApplication(chainlink.ApplicationOpts{ Config: cfg, diff --git a/core/gethwrappers/llo-feeds/generated/channel_config_store/channel_config_store.go b/core/gethwrappers/llo-feeds/generated/channel_config_store/channel_config_store.go index 3c67b64227..7dd4407b3a 100644 --- a/core/gethwrappers/llo-feeds/generated/channel_config_store/channel_config_store.go +++ b/core/gethwrappers/llo-feeds/generated/channel_config_store/channel_config_store.go @@ -30,15 +30,9 @@ var ( _ = abi.ConvertType ) -type IChannelConfigStoreChannelDefinition struct { - ReportFormat uint32 - ChainSelector uint64 - StreamIDs []uint32 -} - var ChannelConfigStoreMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ChannelDefinitionNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyStreamIDs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByEOA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StagingConfigAlreadyPromoted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroReportFormat\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"ChannelDefinitionRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"reportFormat\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint32[]\",\"name\":\"streamIDs\",\"type\":\"uint32[]\"}],\"indexed\":false,\"internalType\":\"structIChannelConfigStore.ChannelDefinition\",\"name\":\"channelDefinition\",\"type\":\"tuple\"}],\"name\":\"NewChannelDefinition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"PromoteStagingConfig\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"reportFormat\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint32[]\",\"name\":\"streamIDs\",\"type\":\"uint32[]\"}],\"internalType\":\"structIChannelConfigStore.ChannelDefinition\",\"name\":\"channelDefinition\",\"type\":\"tuple\"}],\"name\":\"addChannel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"getChannelDefinitions\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"reportFormat\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint32[]\",\"name\":\"streamIDs\",\"type\":\"uint32[]\"}],\"internalType\":\"structIChannelConfigStore.ChannelDefinition\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"channelId\",\"type\":\"uint32\"}],\"name\":\"removeChannel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610e4f806101576000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638da5cb5b1161005b5780638da5cb5b146101535780639682a4501461017b578063f2fde38b1461018e578063f5810719146101a157600080fd5b806301ffc9a71461008d578063181f5a77146100f757806379ba5097146101365780637e37e71914610140575b600080fd5b6100e261009b3660046107d1565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1d344450000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b604080518082018252601881527f4368616e6e656c436f6e66696753746f726520302e302e300000000000000000602082015290516100ee919061081a565b61013e6101c1565b005b61013e61014e366004610898565b6102c3565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ee565b61013e6101893660046108b5565b6103a3565b61013e61019c36600461090c565b6104f3565b6101b46101af366004610898565b610507565b6040516100ee9190610942565b60015473ffffffffffffffffffffffffffffffffffffffff163314610247576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6102cb610620565b63ffffffff8116600090815260026020526040812060010154900361031c576040517fd1a751e200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff8116600090815260026020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000168155906103656001830182610798565b505060405163ffffffff821681527f334e877e9691ecae0660510061973bebaa8b4fb37332ed6090052e630c9798619060200160405180910390a150565b6103ab610620565b6103b860408201826109bc565b90506000036103f3576040517f4b620e2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104036040820160208301610a41565b67ffffffffffffffff16600003610446576040517ff89d762900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104536020820182610898565b63ffffffff16600003610492576040517febd3ef0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff8216600090815260026020526040902081906104b38282610c37565b9050507f35d63e43dd8abd374a4c4e0b5b02c8294dd20e1f493e7344a1751123d11ecc1482826040516104e7929190610d7f565b60405180910390a15050565b6104fb610620565b610504816106a3565b50565b6040805160608082018352600080835260208301529181019190915233321461055c576040517f74e2cd5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff82811660009081526002602090815260409182902082516060810184528154948516815264010000000090940467ffffffffffffffff16848301526001810180548451818502810185018652818152929486019383018282801561061057602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116105d35790505b5050505050815250509050919050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161023e565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610722576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161023e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b50805460008255600701600890049060005260206000209081019061050491905b808211156107cd57600081556001016107b9565b5090565b6000602082840312156107e357600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461081357600080fd5b9392505050565b600060208083528351808285015260005b818110156108475785810183015185820160400152820161082b565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b63ffffffff8116811461050457600080fd5b6000602082840312156108aa57600080fd5b813561081381610886565b600080604083850312156108c857600080fd5b82356108d381610886565b9150602083013567ffffffffffffffff8111156108ef57600080fd5b83016060818603121561090157600080fd5b809150509250929050565b60006020828403121561091e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461081357600080fd5b600060208083526080830163ffffffff808651168386015267ffffffffffffffff83870151166040860152604086015160608087015282815180855260a0880191508583019450600092505b808310156109b05784518416825293850193600192909201919085019061098e565b50979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126109f157600080fd5b83018035915067ffffffffffffffff821115610a0c57600080fd5b6020019150600581901b3603821315610a2457600080fd5b9250929050565b67ffffffffffffffff8116811461050457600080fd5b600060208284031215610a5357600080fd5b813561081381610a2b565b60008135610a6b81610886565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b68010000000000000000821115610ab957610ab9610a71565b805482825580831015610b3e576000828152602081206007850160031c81016007840160031c82019150601c8660021b168015610b25577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8083018054828460200360031b1c16815550505b505b81811015610b3a57828155600101610b27565b5050505b505050565b67ffffffffffffffff831115610b5b57610b5b610a71565b610b658382610aa0565b60008181526020902082908460031c60005b81811015610bd0576000805b6008811015610bc357610bb2610b9887610a5e565b63ffffffff908116600584901b90811b91901b1984161790565b602096909601959150600101610b83565b5083820155600101610b77565b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88616808703818814610c2d576000805b82811015610c2757610c16610b9888610a5e565b602097909701969150600101610c02565b50848401555b5050505050505050565b8135610c4281610886565b63ffffffff811690508154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000082161783556020840135610c8281610a2b565b6bffffffffffffffff000000008160201b16837fffffffffffffffffffffffffffffffffffffffff00000000000000000000000084161717845550505060408201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1833603018112610cf457600080fd5b8201803567ffffffffffffffff811115610d0d57600080fd5b6020820191508060051b3603821315610d2557600080fd5b610d33818360018601610b43565b50505050565b8183526000602080850194508260005b85811015610d74578135610d5c81610886565b63ffffffff1687529582019590820190600101610d49565b509495945050505050565b600063ffffffff8085168352604060208401528335610d9d81610886565b1660408301526020830135610db181610a2b565b67ffffffffffffffff8082166060850152604085013591507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1853603018212610df957600080fd5b6020918501918201913581811115610e1057600080fd5b8060051b3603831315610e2257600080fd5b60606080860152610e3760a086018285610d39565b97965050505050505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"donId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"url\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"sha\",\"type\":\"bytes32\"}],\"name\":\"NewChannelDefinition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"url\",\"type\":\"string\"},{\"internalType\":\"bytes32\",\"name\":\"sha\",\"type\":\"bytes32\"}],\"name\":\"setChannelDefinitions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6106d2806101576000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c806379ba50971161005057806379ba5097146101355780638da5cb5b1461013d578063f2fde38b1461016557600080fd5b806301ffc9a714610077578063181f5a77146100e15780635ba5bac214610120575b600080fd5b6100cc610085366004610483565b7fffffffff00000000000000000000000000000000000000000000000000000000167f5ba5bac2000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b604080518082018252601881527f4368616e6e656c436f6e66696753746f726520302e302e310000000000000000602082015290516100d891906104cc565b61013361012e366004610538565b610178565b005b6101336101f5565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100d8565b6101336101733660046105cc565b6102f7565b61018061030b565b63ffffffff84166000908152600260205260408120805482906101a290610602565b91905081905590508463ffffffff167fe5b641a7879fb491e4e5a35a1ce950f0237b2537ee9b1b1e4fb65e29aff1f5e8828686866040516101e69493929190610661565b60405180910390a25050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461027b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6102ff61030b565b6103088161038e565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461038c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610272565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610272565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561049557600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146104c557600080fd5b9392505050565b600060208083528351808285015260005b818110156104f9578581018301518582016040015282016104dd565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000806000806060858703121561054e57600080fd5b843563ffffffff8116811461056257600080fd5b9350602085013567ffffffffffffffff8082111561057f57600080fd5b818701915087601f83011261059357600080fd5b8135818111156105a257600080fd5b8860208285010111156105b457600080fd5b95986020929092019750949560400135945092505050565b6000602082840312156105de57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104c557600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361065a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b63ffffffff851681526060602082015282606082015282846080830137600060808483010152600060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011683010190508260408301529594505050505056fea164736f6c6343000813000a", } var ChannelConfigStoreABI = ChannelConfigStoreMetaData.ABI @@ -177,28 +171,6 @@ func (_ChannelConfigStore *ChannelConfigStoreTransactorRaw) Transact(opts *bind. return _ChannelConfigStore.Contract.contract.Transact(opts, method, params...) } -func (_ChannelConfigStore *ChannelConfigStoreCaller) GetChannelDefinitions(opts *bind.CallOpts, channelId uint32) (IChannelConfigStoreChannelDefinition, error) { - var out []interface{} - err := _ChannelConfigStore.contract.Call(opts, &out, "getChannelDefinitions", channelId) - - if err != nil { - return *new(IChannelConfigStoreChannelDefinition), err - } - - out0 := *abi.ConvertType(out[0], new(IChannelConfigStoreChannelDefinition)).(*IChannelConfigStoreChannelDefinition) - - return out0, err - -} - -func (_ChannelConfigStore *ChannelConfigStoreSession) GetChannelDefinitions(channelId uint32) (IChannelConfigStoreChannelDefinition, error) { - return _ChannelConfigStore.Contract.GetChannelDefinitions(&_ChannelConfigStore.CallOpts, channelId) -} - -func (_ChannelConfigStore *ChannelConfigStoreCallerSession) GetChannelDefinitions(channelId uint32) (IChannelConfigStoreChannelDefinition, error) { - return _ChannelConfigStore.Contract.GetChannelDefinitions(&_ChannelConfigStore.CallOpts, channelId) -} - func (_ChannelConfigStore *ChannelConfigStoreCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} err := _ChannelConfigStore.contract.Call(opts, &out, "owner") @@ -277,28 +249,16 @@ func (_ChannelConfigStore *ChannelConfigStoreTransactorSession) AcceptOwnership( return _ChannelConfigStore.Contract.AcceptOwnership(&_ChannelConfigStore.TransactOpts) } -func (_ChannelConfigStore *ChannelConfigStoreTransactor) AddChannel(opts *bind.TransactOpts, channelId uint32, channelDefinition IChannelConfigStoreChannelDefinition) (*types.Transaction, error) { - return _ChannelConfigStore.contract.Transact(opts, "addChannel", channelId, channelDefinition) -} - -func (_ChannelConfigStore *ChannelConfigStoreSession) AddChannel(channelId uint32, channelDefinition IChannelConfigStoreChannelDefinition) (*types.Transaction, error) { - return _ChannelConfigStore.Contract.AddChannel(&_ChannelConfigStore.TransactOpts, channelId, channelDefinition) -} - -func (_ChannelConfigStore *ChannelConfigStoreTransactorSession) AddChannel(channelId uint32, channelDefinition IChannelConfigStoreChannelDefinition) (*types.Transaction, error) { - return _ChannelConfigStore.Contract.AddChannel(&_ChannelConfigStore.TransactOpts, channelId, channelDefinition) -} - -func (_ChannelConfigStore *ChannelConfigStoreTransactor) RemoveChannel(opts *bind.TransactOpts, channelId uint32) (*types.Transaction, error) { - return _ChannelConfigStore.contract.Transact(opts, "removeChannel", channelId) +func (_ChannelConfigStore *ChannelConfigStoreTransactor) SetChannelDefinitions(opts *bind.TransactOpts, donId uint32, url string, sha [32]byte) (*types.Transaction, error) { + return _ChannelConfigStore.contract.Transact(opts, "setChannelDefinitions", donId, url, sha) } -func (_ChannelConfigStore *ChannelConfigStoreSession) RemoveChannel(channelId uint32) (*types.Transaction, error) { - return _ChannelConfigStore.Contract.RemoveChannel(&_ChannelConfigStore.TransactOpts, channelId) +func (_ChannelConfigStore *ChannelConfigStoreSession) SetChannelDefinitions(donId uint32, url string, sha [32]byte) (*types.Transaction, error) { + return _ChannelConfigStore.Contract.SetChannelDefinitions(&_ChannelConfigStore.TransactOpts, donId, url, sha) } -func (_ChannelConfigStore *ChannelConfigStoreTransactorSession) RemoveChannel(channelId uint32) (*types.Transaction, error) { - return _ChannelConfigStore.Contract.RemoveChannel(&_ChannelConfigStore.TransactOpts, channelId) +func (_ChannelConfigStore *ChannelConfigStoreTransactorSession) SetChannelDefinitions(donId uint32, url string, sha [32]byte) (*types.Transaction, error) { + return _ChannelConfigStore.Contract.SetChannelDefinitions(&_ChannelConfigStore.TransactOpts, donId, url, sha) } func (_ChannelConfigStore *ChannelConfigStoreTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { @@ -313,123 +273,6 @@ func (_ChannelConfigStore *ChannelConfigStoreTransactorSession) TransferOwnershi return _ChannelConfigStore.Contract.TransferOwnership(&_ChannelConfigStore.TransactOpts, to) } -type ChannelConfigStoreChannelDefinitionRemovedIterator struct { - Event *ChannelConfigStoreChannelDefinitionRemoved - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *ChannelConfigStoreChannelDefinitionRemovedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(ChannelConfigStoreChannelDefinitionRemoved) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(ChannelConfigStoreChannelDefinitionRemoved) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *ChannelConfigStoreChannelDefinitionRemovedIterator) Error() error { - return it.fail -} - -func (it *ChannelConfigStoreChannelDefinitionRemovedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type ChannelConfigStoreChannelDefinitionRemoved struct { - ChannelId uint32 - Raw types.Log -} - -func (_ChannelConfigStore *ChannelConfigStoreFilterer) FilterChannelDefinitionRemoved(opts *bind.FilterOpts) (*ChannelConfigStoreChannelDefinitionRemovedIterator, error) { - - logs, sub, err := _ChannelConfigStore.contract.FilterLogs(opts, "ChannelDefinitionRemoved") - if err != nil { - return nil, err - } - return &ChannelConfigStoreChannelDefinitionRemovedIterator{contract: _ChannelConfigStore.contract, event: "ChannelDefinitionRemoved", logs: logs, sub: sub}, nil -} - -func (_ChannelConfigStore *ChannelConfigStoreFilterer) WatchChannelDefinitionRemoved(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreChannelDefinitionRemoved) (event.Subscription, error) { - - logs, sub, err := _ChannelConfigStore.contract.WatchLogs(opts, "ChannelDefinitionRemoved") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(ChannelConfigStoreChannelDefinitionRemoved) - if err := _ChannelConfigStore.contract.UnpackLog(event, "ChannelDefinitionRemoved", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_ChannelConfigStore *ChannelConfigStoreFilterer) ParseChannelDefinitionRemoved(log types.Log) (*ChannelConfigStoreChannelDefinitionRemoved, error) { - event := new(ChannelConfigStoreChannelDefinitionRemoved) - if err := _ChannelConfigStore.contract.UnpackLog(event, "ChannelDefinitionRemoved", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - type ChannelConfigStoreNewChannelDefinitionIterator struct { Event *ChannelConfigStoreNewChannelDefinition @@ -491,23 +334,35 @@ func (it *ChannelConfigStoreNewChannelDefinitionIterator) Close() error { } type ChannelConfigStoreNewChannelDefinition struct { - ChannelId uint32 - ChannelDefinition IChannelConfigStoreChannelDefinition - Raw types.Log + DonId *big.Int + Version uint32 + Url string + Sha [32]byte + Raw types.Log } -func (_ChannelConfigStore *ChannelConfigStoreFilterer) FilterNewChannelDefinition(opts *bind.FilterOpts) (*ChannelConfigStoreNewChannelDefinitionIterator, error) { +func (_ChannelConfigStore *ChannelConfigStoreFilterer) FilterNewChannelDefinition(opts *bind.FilterOpts, donId []*big.Int) (*ChannelConfigStoreNewChannelDefinitionIterator, error) { + + var donIdRule []interface{} + for _, donIdItem := range donId { + donIdRule = append(donIdRule, donIdItem) + } - logs, sub, err := _ChannelConfigStore.contract.FilterLogs(opts, "NewChannelDefinition") + logs, sub, err := _ChannelConfigStore.contract.FilterLogs(opts, "NewChannelDefinition", donIdRule) if err != nil { return nil, err } return &ChannelConfigStoreNewChannelDefinitionIterator{contract: _ChannelConfigStore.contract, event: "NewChannelDefinition", logs: logs, sub: sub}, nil } -func (_ChannelConfigStore *ChannelConfigStoreFilterer) WatchNewChannelDefinition(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreNewChannelDefinition) (event.Subscription, error) { +func (_ChannelConfigStore *ChannelConfigStoreFilterer) WatchNewChannelDefinition(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreNewChannelDefinition, donId []*big.Int) (event.Subscription, error) { + + var donIdRule []interface{} + for _, donIdItem := range donId { + donIdRule = append(donIdRule, donIdItem) + } - logs, sub, err := _ChannelConfigStore.contract.WatchLogs(opts, "NewChannelDefinition") + logs, sub, err := _ChannelConfigStore.contract.WatchLogs(opts, "NewChannelDefinition", donIdRule) if err != nil { return nil, err } @@ -820,147 +675,22 @@ func (_ChannelConfigStore *ChannelConfigStoreFilterer) ParseOwnershipTransferred return event, nil } -type ChannelConfigStorePromoteStagingConfigIterator struct { - Event *ChannelConfigStorePromoteStagingConfig - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *ChannelConfigStorePromoteStagingConfigIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(ChannelConfigStorePromoteStagingConfig) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(ChannelConfigStorePromoteStagingConfig) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *ChannelConfigStorePromoteStagingConfigIterator) Error() error { - return it.fail -} - -func (it *ChannelConfigStorePromoteStagingConfigIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type ChannelConfigStorePromoteStagingConfig struct { - ChannelId uint32 - Raw types.Log -} - -func (_ChannelConfigStore *ChannelConfigStoreFilterer) FilterPromoteStagingConfig(opts *bind.FilterOpts) (*ChannelConfigStorePromoteStagingConfigIterator, error) { - - logs, sub, err := _ChannelConfigStore.contract.FilterLogs(opts, "PromoteStagingConfig") - if err != nil { - return nil, err - } - return &ChannelConfigStorePromoteStagingConfigIterator{contract: _ChannelConfigStore.contract, event: "PromoteStagingConfig", logs: logs, sub: sub}, nil -} - -func (_ChannelConfigStore *ChannelConfigStoreFilterer) WatchPromoteStagingConfig(opts *bind.WatchOpts, sink chan<- *ChannelConfigStorePromoteStagingConfig) (event.Subscription, error) { - - logs, sub, err := _ChannelConfigStore.contract.WatchLogs(opts, "PromoteStagingConfig") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(ChannelConfigStorePromoteStagingConfig) - if err := _ChannelConfigStore.contract.UnpackLog(event, "PromoteStagingConfig", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_ChannelConfigStore *ChannelConfigStoreFilterer) ParsePromoteStagingConfig(log types.Log) (*ChannelConfigStorePromoteStagingConfig, error) { - event := new(ChannelConfigStorePromoteStagingConfig) - if err := _ChannelConfigStore.contract.UnpackLog(event, "PromoteStagingConfig", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - func (_ChannelConfigStore *ChannelConfigStore) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _ChannelConfigStore.abi.Events["ChannelDefinitionRemoved"].ID: - return _ChannelConfigStore.ParseChannelDefinitionRemoved(log) case _ChannelConfigStore.abi.Events["NewChannelDefinition"].ID: return _ChannelConfigStore.ParseNewChannelDefinition(log) case _ChannelConfigStore.abi.Events["OwnershipTransferRequested"].ID: return _ChannelConfigStore.ParseOwnershipTransferRequested(log) case _ChannelConfigStore.abi.Events["OwnershipTransferred"].ID: return _ChannelConfigStore.ParseOwnershipTransferred(log) - case _ChannelConfigStore.abi.Events["PromoteStagingConfig"].ID: - return _ChannelConfigStore.ParsePromoteStagingConfig(log) default: return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) } } -func (ChannelConfigStoreChannelDefinitionRemoved) Topic() common.Hash { - return common.HexToHash("0x334e877e9691ecae0660510061973bebaa8b4fb37332ed6090052e630c979861") -} - func (ChannelConfigStoreNewChannelDefinition) Topic() common.Hash { - return common.HexToHash("0x35d63e43dd8abd374a4c4e0b5b02c8294dd20e1f493e7344a1751123d11ecc14") + return common.HexToHash("0xe5b641a7879fb491e4e5a35a1ce950f0237b2537ee9b1b1e4fb65e29aff1f5e8") } func (ChannelConfigStoreOwnershipTransferRequested) Topic() common.Hash { @@ -971,17 +701,11 @@ func (ChannelConfigStoreOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (ChannelConfigStorePromoteStagingConfig) Topic() common.Hash { - return common.HexToHash("0xbdd8ee023f9979bf23e8af6fd7241f484024e83fb0fabd11bb7fd5e9bed7308a") -} - func (_ChannelConfigStore *ChannelConfigStore) Address() common.Address { return _ChannelConfigStore.address } type ChannelConfigStoreInterface interface { - GetChannelDefinitions(opts *bind.CallOpts, channelId uint32) (IChannelConfigStoreChannelDefinition, error) - Owner(opts *bind.CallOpts) (common.Address, error) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) @@ -990,21 +714,13 @@ type ChannelConfigStoreInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - AddChannel(opts *bind.TransactOpts, channelId uint32, channelDefinition IChannelConfigStoreChannelDefinition) (*types.Transaction, error) - - RemoveChannel(opts *bind.TransactOpts, channelId uint32) (*types.Transaction, error) + SetChannelDefinitions(opts *bind.TransactOpts, donId uint32, url string, sha [32]byte) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - FilterChannelDefinitionRemoved(opts *bind.FilterOpts) (*ChannelConfigStoreChannelDefinitionRemovedIterator, error) - - WatchChannelDefinitionRemoved(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreChannelDefinitionRemoved) (event.Subscription, error) - - ParseChannelDefinitionRemoved(log types.Log) (*ChannelConfigStoreChannelDefinitionRemoved, error) - - FilterNewChannelDefinition(opts *bind.FilterOpts) (*ChannelConfigStoreNewChannelDefinitionIterator, error) + FilterNewChannelDefinition(opts *bind.FilterOpts, donId []*big.Int) (*ChannelConfigStoreNewChannelDefinitionIterator, error) - WatchNewChannelDefinition(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreNewChannelDefinition) (event.Subscription, error) + WatchNewChannelDefinition(opts *bind.WatchOpts, sink chan<- *ChannelConfigStoreNewChannelDefinition, donId []*big.Int) (event.Subscription, error) ParseNewChannelDefinition(log types.Log) (*ChannelConfigStoreNewChannelDefinition, error) @@ -1020,12 +736,6 @@ type ChannelConfigStoreInterface interface { ParseOwnershipTransferred(log types.Log) (*ChannelConfigStoreOwnershipTransferred, error) - FilterPromoteStagingConfig(opts *bind.FilterOpts) (*ChannelConfigStorePromoteStagingConfigIterator, error) - - WatchPromoteStagingConfig(opts *bind.WatchOpts, sink chan<- *ChannelConfigStorePromoteStagingConfig) (event.Subscription, error) - - ParsePromoteStagingConfig(log types.Log) (*ChannelConfigStorePromoteStagingConfig, error) - ParseLog(log types.Log) (generated.AbigenLog, error) Address() common.Address diff --git a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 0eec657b4c..ef04a38f87 100644 --- a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,5 +1,5 @@ GETH_VERSION: 1.13.8 -channel_config_store: ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin c90e29d9f1a885098982b6175e0447416431b28c605273c807694ac7141e9167 +channel_config_store: ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin 3fafe83ea21d50488f5533962f62683988ffa6fd1476dccbbb9040be2369cb37 channel_config_verifier_proxy: ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.abi ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.bin 655658e5f61dfadfe3268de04f948b7e690ad03ca45676e645d6cd6018154661 channel_verifier: ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.abi ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.bin e6020553bd8e3e6b250fcaffe7efd22aea955c8c1a0eb05d282fdeb0ab6550b7 destination_fee_manager: ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.abi ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.bin c581af84832b8fd886685f59518bcdb11bd1c9b508d88b07c04d6226e6a2789e diff --git a/core/internal/testutils/testutils.go b/core/internal/testutils/testutils.go index 45609488b4..4e7f9b05c8 100644 --- a/core/internal/testutils/testutils.go +++ b/core/internal/testutils/testutils.go @@ -380,6 +380,19 @@ func WaitForLogMessage(t *testing.T, observedLogs *observer.ObservedLogs, msg st return } +func WaitForLogMessageWithField(t *testing.T, observedLogs *observer.ObservedLogs, msg, field, value string) (le observer.LoggedEntry) { + AssertEventually(t, func() bool { + for _, l := range observedLogs.All() { + if strings.Contains(l.Message, msg) && strings.Contains(l.ContextMap()[field].(string), value) { + le = l + return true + } + } + return false + }) + return +} + // WaitForLogMessageCount waits until at least count log message containing the // specified msg is emitted func WaitForLogMessageCount(t *testing.T, observedLogs *observer.ObservedLogs, msg string, count int) { diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index 3ddfe27047..11e477a54f 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "net/http" "github.com/pelletier/go-toml/v2" @@ -37,6 +38,7 @@ type RelayerFactory struct { loop.GRPCOpts MercuryPool wsrpc.Pool CapabilitiesRegistry coretypes.CapabilitiesRegistry + HTTPClient *http.Client } type DummyFactoryConfig struct { @@ -85,6 +87,7 @@ func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (m MercuryPool: r.MercuryPool, TransmitterConfig: config.MercuryTransmitter, CapabilitiesRegistry: r.CapabilitiesRegistry, + HTTPClient: r.HTTPClient, } relayer, err2 := evmrelay.NewRelayer(lggr.Named(relayID.ChainID), chain, relayerOpts) if err2 != nil { diff --git a/core/services/llo/bm/dummy_transmitter.go b/core/services/llo/bm/dummy_transmitter.go index aa29938545..06fd0915b3 100644 --- a/core/services/llo/bm/dummy_transmitter.go +++ b/core/services/llo/bm/dummy_transmitter.go @@ -2,6 +2,7 @@ package bm import ( "context" + "fmt" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -10,6 +11,8 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" + "github.com/smartcontractkit/chainlink-data-streams/llo" "github.com/smartcontractkit/chainlink-common/pkg/logger" @@ -59,21 +62,44 @@ func (t *transmitter) Transmit( sigs []types.AttributedOnchainSignature, ) error { lggr := t.lggr - switch report.Info.ReportFormat { - case llotypes.ReportFormatJSON: - r, err := (llo.JSONReportCodec{}).Decode(report.Report) - if err != nil { - lggr.Debugw("Failed to decode JSON report", "err", err) + { + switch report.Info.ReportFormat { + case llotypes.ReportFormatJSON: + r, err := (llo.JSONReportCodec{}).Decode(report.Report) + if err != nil { + lggr.Debugw(fmt.Sprintf("Failed to decode report with type %s", report.Info.ReportFormat), "err", err) + } else if r.SeqNr > 0 { + lggr = logger.With(lggr, + "report.Report.ConfigDigest", r.ConfigDigest, + "report.Report.SeqNr", r.SeqNr, + "report.Report.ChannelID", r.ChannelID, + "report.Report.ValidAfterSeconds", r.ValidAfterSeconds, + "report.Report.ObservationTimestampSeconds", r.ObservationTimestampSeconds, + "report.Report.Values", r.Values, + "report.Report.Specimen", r.Specimen, + ) + } + case llotypes.ReportFormatEVMPremiumLegacy: + r, err := (evm.ReportCodecPremiumLegacy{}).Decode(report.Report) + if err != nil { + lggr.Debugw(fmt.Sprintf("Failed to decode report with type %s", report.Info.ReportFormat), "err", err) + } else if r.ObservationsTimestamp > 0 { + lggr = logger.With(lggr, + "report.Report.FeedId", r.FeedId, + "report.Report.ObservationsTimestamp", r.ObservationsTimestamp, + "report.Report.BenchmarkPrice", r.BenchmarkPrice, + "report.Report.Bid", r.Bid, + "report.Report.Ask", r.Ask, + "report.Report.ValidFromTimestamp", r.ValidFromTimestamp, + "report.Report.ExpiresAt", r.ExpiresAt, + "report.Report.LinkFee", r.LinkFee, + "report.Report.NativeFee", r.NativeFee, + ) + } + default: + err := fmt.Errorf("unhandled report format: %s", report.Info.ReportFormat) + lggr.Debugw(fmt.Sprintf("Failed to decode report with type %s", report.Info.ReportFormat), "err", err) } - lggr = logger.With(lggr, - "report.Report.ConfigDigest", r.ConfigDigest, - "report.Report.SeqNr", r.SeqNr, - "report.Report.ChannelID", r.ChannelID, - "report.Report.ValidAfterSeconds", r.ValidAfterSeconds, - "report.Report.Values", r.Values, - "report.Report.Specimen", r.Specimen, - ) - default: } transmitSuccessCount.Inc() lggr.Infow("Transmit (dummy)", "digest", digest, "seqNr", seqNr, "report.Report", report.Report, "report.Info", report.Info, "sigs", sigs) diff --git a/core/services/llo/channel_definition_cache_factory.go b/core/services/llo/channel_definition_cache_factory.go index 4aa358d64a..0cc2543cdf 100644 --- a/core/services/llo/channel_definition_cache_factory.go +++ b/core/services/llo/channel_definition_cache_factory.go @@ -2,6 +2,7 @@ package llo import ( "fmt" + "net/http" "sync" "github.com/ethereum/go-ethereum/common" @@ -19,25 +20,29 @@ type ChannelDefinitionCacheFactory interface { var _ ChannelDefinitionCacheFactory = &channelDefinitionCacheFactory{} -func NewChannelDefinitionCacheFactory(lggr logger.Logger, orm ChannelDefinitionCacheORM, lp logpoller.LogPoller) ChannelDefinitionCacheFactory { +func NewChannelDefinitionCacheFactory(lggr logger.Logger, orm ChannelDefinitionCacheORM, lp logpoller.LogPoller, client *http.Client) ChannelDefinitionCacheFactory { return &channelDefinitionCacheFactory{ lggr, orm, lp, - make(map[common.Address]struct{}), + client, + make(map[common.Address]map[uint32]struct{}), sync.Mutex{}, } } type channelDefinitionCacheFactory struct { - lggr logger.Logger - orm ChannelDefinitionCacheORM - lp logpoller.LogPoller + lggr logger.Logger + orm ChannelDefinitionCacheORM + lp logpoller.LogPoller + client *http.Client - caches map[common.Address]struct{} + caches map[common.Address]map[uint32]struct{} mu sync.Mutex } +// TODO: Test this +// MERC-3653 func (f *channelDefinitionCacheFactory) NewCache(cfg lloconfig.PluginConfig) (llotypes.ChannelDefinitionCache, error) { if cfg.ChannelDefinitions != "" { return NewStaticChannelDefinitionCache(f.lggr, cfg.ChannelDefinitions) @@ -45,14 +50,18 @@ func (f *channelDefinitionCacheFactory) NewCache(cfg lloconfig.PluginConfig) (ll addr := cfg.ChannelDefinitionsContractAddress fromBlock := cfg.ChannelDefinitionsContractFromBlock + donID := cfg.DonID f.mu.Lock() defer f.mu.Unlock() - if _, exists := f.caches[addr]; exists { + if _, exists := f.caches[addr][donID]; exists { // This shouldn't really happen and isn't supported - return nil, fmt.Errorf("cache already exists for contract address %s", addr.Hex()) + return nil, fmt.Errorf("cache already exists for contract address %s and don ID %d", addr.Hex(), donID) } - f.caches[addr] = struct{}{} - return NewChannelDefinitionCache(f.lggr, f.orm, f.lp, addr, fromBlock), nil + if _, exists := f.caches[addr]; !exists { + f.caches[addr] = make(map[uint32]struct{}) + } + f.caches[addr][donID] = struct{}{} + return NewChannelDefinitionCache(f.lggr, f.orm, f.client, f.lp, addr, donID, fromBlock), nil } diff --git a/core/services/llo/codecs.go b/core/services/llo/codecs.go new file mode 100644 index 0000000000..a67b30d2f2 --- /dev/null +++ b/core/services/llo/codecs.go @@ -0,0 +1,18 @@ +package llo + +import ( + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink-data-streams/llo" + + "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" +) + +// NOTE: All supported codecs must be specified here +func NewCodecs() map[llotypes.ReportFormat]llo.ReportCodec { + codecs := make(map[llotypes.ReportFormat]llo.ReportCodec) + + codecs[llotypes.ReportFormatJSON] = llo.JSONReportCodec{} + codecs[llotypes.ReportFormatEVMPremiumLegacy] = evm.ReportCodecPremiumLegacy{} + + return codecs +} diff --git a/core/services/llo/codecs_test.go b/core/services/llo/codecs_test.go new file mode 100644 index 0000000000..d26b72dd35 --- /dev/null +++ b/core/services/llo/codecs_test.go @@ -0,0 +1,16 @@ +package llo + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" +) + +func Test_NewCodecs(t *testing.T) { + c := NewCodecs() + + assert.Contains(t, c, llotypes.ReportFormatJSON, "expected JSON to be supported") + assert.Contains(t, c, llotypes.ReportFormatEVMPremiumLegacy, "expected EVMPremiumLegacy to be supported") +} diff --git a/core/services/llo/data_source.go b/core/services/llo/data_source.go index 20b14edad5..4f6e91675c 100644 --- a/core/services/llo/data_source.go +++ b/core/services/llo/data_source.go @@ -3,12 +3,12 @@ package llo import ( "context" "fmt" - "math/big" "sort" "sync" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/shopspring/decimal" "golang.org/x/exp/maps" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" @@ -17,6 +17,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/streams" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) var ( @@ -97,7 +98,7 @@ func (d *dataSource) Observe(ctx context.Context, streamValues llo.StreamValues, go func(streamID llotypes.StreamID) { defer wg.Done() - var val *big.Int + var val llo.StreamValue stream, exists := d.registry.Get(streamID) if !exists { @@ -115,9 +116,7 @@ func (d *dataSource) Observe(ctx context.Context, streamValues llo.StreamValues, promObservationErrorCount.WithLabelValues(fmt.Sprintf("%d", streamID)).Inc() return } - // TODO: support types other than *big.Int - // https://smartcontract-it.atlassian.net/browse/MERC-3525 - val, err = streams.ExtractBigInt(trrs) + val, err = ExtractStreamValue(trrs) if err != nil { errmu.Lock() errors = append(errors, ErrObservationFailed{inner: err, run: run, streamID: streamID, reason: "failed to extract big.Int"}) @@ -128,7 +127,7 @@ func (d *dataSource) Observe(ctx context.Context, streamValues llo.StreamValues, if val != nil { svmu.Lock() defer svmu.Unlock() - streamValues[streamID] = nil + streamValues[streamID] = val } }(streamID) } @@ -140,18 +139,18 @@ func (d *dataSource) Observe(ctx context.Context, streamValues llo.StreamValues, if len(errors) > 0 { sort.Slice(errors, func(i, j int) bool { return errors[i].streamID < errors[j].streamID }) failedStreamIDs = make([]streams.StreamID, len(errors)) + errStrs := make([]string, len(errors)) for i, e := range errors { + errStrs[i] = e.String() failedStreamIDs[i] = e.streamID } - d.lggr.Warnw("Observation failed for streams", "failedStreamIDs", failedStreamIDs, "errors", errors, "seqNr", opts.SeqNr()) + d.lggr.Warnw("Observation failed for streams", "failedStreamIDs", failedStreamIDs, "errors", errStrs, "seqNr", opts.SeqNr()) } if opts.VerboseLogging() { successes := make([]streams.StreamID, 0, len(streamValues)) - for strmID, res := range streamValues { - if res != nil { - successes = append(successes, strmID) - } + for strmID, _ := range streamValues { + successes = append(successes, strmID) } sort.Slice(successes, func(i, j int) bool { return successes[i] < successes[j] }) d.lggr.Debugw("Observation complete", "successfulStreamIDs", successes, "failedStreamIDs", failedStreamIDs, "values", streamValues, "seqNr", opts.SeqNr()) @@ -159,3 +158,57 @@ func (d *dataSource) Observe(ctx context.Context, streamValues llo.StreamValues, return nil } + +// ExtractStreamValue extracts a StreamValue from a TaskRunResults +func ExtractStreamValue(trrs pipeline.TaskRunResults) (llo.StreamValue, error) { + // pipeline.TaskRunResults comes ordered asc by index, this is guaranteed + // by the pipeline executor + finaltrrs := trrs.Terminals() + + // TODO: Special handling for missing native/link streams? + // https://smartcontract-it.atlassian.net/browse/MERC-5949 + + // HACK: Right now we rely on the number of outputs to determine whether + // its a Decimal or a Quote. + // This isn't very robust or future-proof but is sufficient to support v0.3 + // compat. + // There are a number of different possible ways to solve this in future. + // See: https://smartcontract-it.atlassian.net/browse/MERC-5934 + switch len(finaltrrs) { + case 1: + res := finaltrrs[0].Result + if res.Error != nil { + return nil, res.Error + } + val, err := toDecimal(res.Value) + if err != nil { + return nil, fmt.Errorf("failed to parse BenchmarkPrice: %w", err) + } + return llo.ToDecimal(val), nil + case 3: + // Expect ordering of Benchmark, Bid, Ask + results := make([]decimal.Decimal, 3) + for i, trr := range finaltrrs { + res := trr.Result + if res.Error != nil { + return nil, fmt.Errorf("failed to parse stream output into Quote (task index: %d): %w", i, res.Error) + } + val, err := toDecimal(res.Value) + if err != nil { + return nil, fmt.Errorf("failed to parse decimal: %w", err) + } + results[i] = val + } + return &llo.Quote{ + Benchmark: results[0], + Bid: results[1], + Ask: results[2], + }, nil + default: + return nil, fmt.Errorf("invalid number of results, expected: 1 or 3, got: %d", len(finaltrrs)) + } +} + +func toDecimal(val interface{}) (decimal.Decimal, error) { + return utils.ToDecimal(val) +} diff --git a/core/services/llo/data_source_test.go b/core/services/llo/data_source_test.go index 3716bb2a58..59cd870bc9 100644 --- a/core/services/llo/data_source_test.go +++ b/core/services/llo/data_source_test.go @@ -6,6 +6,7 @@ import ( "math/big" "testing" + "github.com/shopspring/decimal" "github.com/stretchr/testify/assert" "github.com/smartcontractkit/chainlink-data-streams/llo" @@ -55,7 +56,6 @@ func (m mockOpts) VerboseLogging() bool { return true } func (m mockOpts) SeqNr() uint64 { return 42 } func Test_DataSource(t *testing.T) { - t.Skip("waiting on https://github.com/smartcontractkit/chainlink/pull/13780") lggr := logger.TestLogger(t) reg := &mockRegistry{make(map[streams.StreamID]*mockStream)} ds := newDataSource(lggr, reg) @@ -78,7 +78,11 @@ func Test_DataSource(t *testing.T) { err := ds.Observe(ctx, vals, mockOpts{}) assert.NoError(t, err) - assert.Equal(t, llo.StreamValues{}, vals) + assert.Equal(t, llo.StreamValues{ + 2: llo.ToDecimal(decimal.NewFromInt(40602)), + 1: llo.ToDecimal(decimal.NewFromInt(2181)), + 3: llo.ToDecimal(decimal.NewFromInt(15)), + }, vals) }) t.Run("observes each stream and returns success/errors", func(t *testing.T) { reg.streams[1] = makeStreamWithSingleResult[*big.Int](big.NewInt(2181), errors.New("something exploded")) @@ -89,7 +93,11 @@ func Test_DataSource(t *testing.T) { err := ds.Observe(ctx, vals, mockOpts{}) assert.NoError(t, err) - assert.Equal(t, llo.StreamValues{}, vals) + assert.Equal(t, llo.StreamValues{ + 2: llo.ToDecimal(decimal.NewFromInt(40602)), + 1: nil, + 3: nil, + }, vals) }) }) } diff --git a/core/services/llo/delegate.go b/core/services/llo/delegate.go index ddcab383ef..aff670e807 100644 --- a/core/services/llo/delegate.go +++ b/core/services/llo/delegate.go @@ -76,10 +76,7 @@ func NewDelegate(cfg DelegateConfig) (job.ServiceCtx, error) { if cfg.Registry == nil { return nil, errors.New("Registry must not be nil") } - codecs := make(map[llotypes.ReportFormat]llo.ReportCodec) - - // NOTE: All codecs must be specified here - codecs[llotypes.ReportFormatJSON] = llo.JSONReportCodec{} + codecs := NewCodecs() // TODO: Do these services need starting? // https://smartcontract-it.atlassian.net/browse/MERC-3386 diff --git a/core/services/llo/evm/fees.go b/core/services/llo/evm/fees.go new file mode 100644 index 0000000000..b74d68b08d --- /dev/null +++ b/core/services/llo/evm/fees.go @@ -0,0 +1,31 @@ +package evm + +import ( + "math/big" + + "github.com/shopspring/decimal" +) + +// FeeScalingFactor indicates the multiplier applied to fees. +// e.g. for a 1e18 multiplier, a LINK fee of 7.42 will be represented as 7.42e18 +// This is what will be baked into the report for use on-chain. +var FeeScalingFactor = decimal.NewFromInt(1e18) + +// NOTE: Inexact divisions will have this degree of precision +const Precision int32 = 18 + +// CalculateFee outputs a fee in wei according to the formula: baseUSDFee / tokenPriceInUSD +func CalculateFee(tokenPriceInUSD decimal.Decimal, baseUSDFee decimal.Decimal) *big.Int { + if tokenPriceInUSD.IsZero() || baseUSDFee.IsZero() { + // zero fee if token price or base fee is zero + return big.NewInt(0) + } + + // fee denominated in token + fee := baseUSDFee.DivRound(tokenPriceInUSD, Precision) + + // fee scaled up + fee = fee.Mul(FeeScalingFactor) + + return fee.BigInt() +} diff --git a/core/services/llo/evm/fees_test.go b/core/services/llo/evm/fees_test.go new file mode 100644 index 0000000000..16ee98db7d --- /dev/null +++ b/core/services/llo/evm/fees_test.go @@ -0,0 +1,45 @@ +package evm + +import ( + "math/big" + "testing" + + "github.com/shopspring/decimal" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_Fees(t *testing.T) { + BaseUSDFee, err := decimal.NewFromString("0.70") + require.NoError(t, err) + t.Run("with token price > 1", func(t *testing.T) { + tokenPriceInUSD := decimal.NewFromInt32(1630) + fee := CalculateFee(tokenPriceInUSD, BaseUSDFee) + expectedFee := big.NewInt(429447852760736) + if fee.Cmp(expectedFee) != 0 { + t.Errorf("Expected fee to be %v, got %v", expectedFee, fee) + } + }) + + t.Run("with token price < 1", func(t *testing.T) { + tokenPriceInUSD := decimal.NewFromFloat32(0.4) + fee := CalculateFee(tokenPriceInUSD, BaseUSDFee) + expectedFee := big.NewInt(1750000000000000000) + if fee.Cmp(expectedFee) != 0 { + t.Errorf("Expected fee to be %v, got %v", expectedFee, fee) + } + }) + + t.Run("with token price == 0", func(t *testing.T) { + tokenPriceInUSD := decimal.NewFromInt32(0) + fee := CalculateFee(tokenPriceInUSD, BaseUSDFee) + assert.Equal(t, big.NewInt(0), fee) + }) + + t.Run("with base fee == 0", func(t *testing.T) { + tokenPriceInUSD := decimal.NewFromInt32(123) + BaseUSDFee = decimal.NewFromInt32(0) + fee := CalculateFee(tokenPriceInUSD, BaseUSDFee) + assert.Equal(t, big.NewInt(0), fee) + }) +} diff --git a/core/services/llo/evm/report_codec_premium_legacy.go b/core/services/llo/evm/report_codec_premium_legacy.go new file mode 100644 index 0000000000..a062f77b65 --- /dev/null +++ b/core/services/llo/evm/report_codec_premium_legacy.go @@ -0,0 +1,173 @@ +package evm + +import ( + "encoding/json" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/shopspring/decimal" + + "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" + "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + v3 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" + "github.com/smartcontractkit/chainlink-data-streams/llo" + ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" + reporttypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + reportcodecv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" +) + +var ( + _ llo.ReportCodec = ReportCodecPremiumLegacy{} +) + +type ReportCodecPremiumLegacy struct{ logger.Logger } + +func NewReportCodecPremiumLegacy(lggr logger.Logger) llo.ReportCodec { + return ReportCodecPremiumLegacy{lggr.Named("ReportCodecPremiumLegacy")} +} + +type ReportFormatEVMPremiumLegacyOpts struct { + // BaseUSDFee is the cost on-chain of verifying a report + BaseUSDFee decimal.Decimal `json:"baseUSDFee"` + // Expiration window is the length of time in seconds the report is valid + // for, from the observation timestamp + ExpirationWindow uint32 `json:"expirationWindow"` + // FeedID is for compatibility with existing on-chain verifiers + FeedID common.Hash `json:"feedID"` + // Multiplier is used to scale the bid, benchmark and ask values in the + // report. If not specified, or zero is used, a multiplier of 1 is assumed. + Multiplier *ubig.Big `json:"multiplier"` +} + +func (r *ReportFormatEVMPremiumLegacyOpts) Decode(opts []byte) error { + if len(opts) == 0 { + // special case if opts are unspecified, just use the zero options rather than erroring + return nil + } + if err := json.Unmarshal(opts, r); err != nil { + return err + } + return nil +} + +func (r ReportCodecPremiumLegacy) Encode(report llo.Report, cd llotypes.ChannelDefinition) ([]byte, error) { + if report.Specimen { + return nil, errors.New("ReportCodecPremiumLegacy does not support encoding specimen reports") + } + nativePrice, linkPrice, quote, err := ExtractReportValues(report) + if err != nil { + return nil, fmt.Errorf("ReportCodecPremiumLegacy cannot encode; got unusable report; %w", err) + } + + // NOTE: It seems suboptimal to have to parse the opts on every encode but + // not sure how to avoid it. Should be negligible performance hit as long + // as Opts is small. + opts := ReportFormatEVMPremiumLegacyOpts{} + if err := (&opts).Decode(cd.Opts); err != nil { + return nil, fmt.Errorf("failed to decode opts; got: '%s'; %w", cd.Opts, err) + } + var multiplier decimal.Decimal + if opts.Multiplier == nil { + multiplier = decimal.NewFromInt(1) + } else if opts.Multiplier.IsZero() { + return nil, errors.New("multiplier, if specified in channel opts, must be non-zero") + } else { + multiplier = decimal.NewFromBigInt(opts.Multiplier.ToInt(), 0) + } + + codec := reportcodecv3.NewReportCodec(opts.FeedID, r.Logger) + + rf := v3.ReportFields{ + ValidFromTimestamp: report.ValidAfterSeconds + 1, + Timestamp: report.ObservationTimestampSeconds, + NativeFee: CalculateFee(nativePrice.Decimal(), opts.BaseUSDFee), + LinkFee: CalculateFee(linkPrice.Decimal(), opts.BaseUSDFee), + ExpiresAt: report.ObservationTimestampSeconds + opts.ExpirationWindow, + BenchmarkPrice: quote.Benchmark.Mul(multiplier).BigInt(), + Bid: quote.Bid.Mul(multiplier).BigInt(), + Ask: quote.Ask.Mul(multiplier).BigInt(), + } + return codec.BuildReport(rf) +} + +func (r ReportCodecPremiumLegacy) Decode(b []byte) (*reporttypes.Report, error) { + codec := reportcodecv3.NewReportCodec([32]byte{}, r.Logger) + return codec.Decode(b) +} + +// Pack assembles the report values into a payload for verifying on-chain +func (r ReportCodecPremiumLegacy) Pack(digest types.ConfigDigest, seqNr uint64, report ocr2types.Report, sigs []types.AttributedOnchainSignature) ([]byte, error) { + var rs [][32]byte + var ss [][32]byte + var vs [32]byte + for i, as := range sigs { + r, s, v, err := evmutil.SplitSignature(as.Signature) + if err != nil { + return nil, fmt.Errorf("eventTransmit(ev): error in SplitSignature: %w", err) + } + rs = append(rs, r) + ss = append(ss, s) + vs[i] = v + } + reportCtx := LegacyReportContext(digest, seqNr) + rawReportCtx := evmutil.RawReportContext(reportCtx) + + payload, err := mercury.PayloadTypes.Pack(rawReportCtx, []byte(report), rs, ss, vs) + if err != nil { + return nil, fmt.Errorf("abi.Pack failed; %w", err) + } + return payload, nil +} + +// TODO: Test this +// MERC-3524 +func ExtractReportValues(report llo.Report) (nativePrice, linkPrice *llo.Decimal, quote *llo.Quote, err error) { + if len(report.Values) != 3 { + return nil, nil, nil, fmt.Errorf("ReportCodecPremiumLegacy requires exactly 3 values (NativePrice, LinkPrice, Quote{Bid, Mid, Ask}); got report.Values: %#v", report.Values) + } + var is bool + nativePrice, is = report.Values[0].(*llo.Decimal) + if nativePrice == nil { + // Missing price median will cause a zero fee + nativePrice = llo.ToDecimal(decimal.Zero) + } else if !is { + return nil, nil, nil, fmt.Errorf("ReportCodecPremiumLegacy expects first value to be of type *Decimal; got: %T", report.Values[0]) + } + linkPrice, is = report.Values[1].(*llo.Decimal) + if linkPrice == nil { + // Missing price median will cause a zero fee + linkPrice = llo.ToDecimal(decimal.Zero) + } else if !is { + return nil, nil, nil, fmt.Errorf("ReportCodecPremiumLegacy expects second value to be of type *Decimal; got: %T", report.Values[1]) + } + quote, is = report.Values[2].(*llo.Quote) + if !is { + return nil, nil, nil, fmt.Errorf("ReportCodecPremiumLegacy expects third value to be of type *Quote; got: %T", report.Values[2]) + } + return nativePrice, linkPrice, quote, nil +} + +// TODO: Consider embedding the DON ID here? +// MERC-3524 +var LLOExtraHash = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001") + +func LegacyReportContext(cd ocr2types.ConfigDigest, seqNr uint64) ocr2types.ReportContext { + // Simulate 256 rounds/epoch + epoch := seqNr / 256 + round := seqNr % 256 + return ocr2types.ReportContext{ + ReportTimestamp: ocr2types.ReportTimestamp{ + ConfigDigest: cd, + Epoch: uint32(epoch), + Round: uint8(round), + }, + ExtraHash: LLOExtraHash, // ExtraHash is always zero for mercury, we use LLOExtraHash here to differentiate from the legacy plugin + } +} diff --git a/core/services/llo/evm/report_codec_premium_legacy_test.go b/core/services/llo/evm/report_codec_premium_legacy_test.go new file mode 100644 index 0000000000..c22d29c340 --- /dev/null +++ b/core/services/llo/evm/report_codec_premium_legacy_test.go @@ -0,0 +1,107 @@ +package evm + +import ( + "fmt" + "math/big" + "testing" + + "github.com/shopspring/decimal" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + reporttypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/types" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink-data-streams/llo" +) + +const ethMainnetChainSelector uint64 = 5009297550715157269 + +func newValidPremiumLegacyReport() llo.Report { + return llo.Report{ + ConfigDigest: types.ConfigDigest{1, 2, 3}, + SeqNr: 32, + ChannelID: llotypes.ChannelID(31), + ValidAfterSeconds: 28, + ObservationTimestampSeconds: 34, + Values: []llo.StreamValue{llo.ToDecimal(decimal.NewFromInt(35)), llo.ToDecimal(decimal.NewFromInt(36)), &llo.Quote{Bid: decimal.NewFromInt(37), Benchmark: decimal.NewFromInt(38), Ask: decimal.NewFromInt(39)}}, + Specimen: false, + } +} + +func Test_ReportCodecPremiumLegacy(t *testing.T) { + rc := ReportCodecPremiumLegacy{} + + feedID := [32]uint8{0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} + cd := llotypes.ChannelDefinition{Opts: llotypes.ChannelOpts(fmt.Sprintf(`{"baseUSDFee":"10.50","expirationWindow":60,"feedId":"0x%x","multiplier":10}`, feedID))} + + t.Run("Encode errors if no values", func(t *testing.T) { + _, err := rc.Encode(llo.Report{}, cd) + require.Error(t, err) + + assert.Contains(t, err.Error(), "ReportCodecPremiumLegacy cannot encode; got unusable report; ReportCodecPremiumLegacy requires exactly 3 values (NativePrice, LinkPrice, Quote{Bid, Mid, Ask}); got report.Values: []llo.StreamValue(nil)") + }) + + t.Run("does not encode specimen reports", func(t *testing.T) { + report := newValidPremiumLegacyReport() + report.Specimen = true + + _, err := rc.Encode(report, cd) + require.Error(t, err) + assert.EqualError(t, err, "ReportCodecPremiumLegacy does not support encoding specimen reports") + }) + + t.Run("Encode constructs a report from observations", func(t *testing.T) { + report := newValidPremiumLegacyReport() + + encoded, err := rc.Encode(report, cd) + require.NoError(t, err) + + assert.Len(t, encoded, 288) + assert.Equal(t, []byte{0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x29, 0xd0, 0x69, 0x18, 0x9e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xc, 0x35, 0x49, 0xbb, 0x7d, 0x2a, 0xab, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x86}, encoded) + + decoded, err := reporttypes.Decode(encoded) + require.NoError(t, err) + assert.Equal(t, feedID, decoded.FeedId) + assert.Equal(t, uint32(34), decoded.ObservationsTimestamp) + assert.Equal(t, big.NewInt(380), decoded.BenchmarkPrice) + assert.Equal(t, big.NewInt(370), decoded.Bid) + assert.Equal(t, big.NewInt(390), decoded.Ask) + assert.Equal(t, uint32(29), decoded.ValidFromTimestamp) + assert.Equal(t, uint32(94), decoded.ExpiresAt) + assert.Equal(t, big.NewInt(291666666666666667), decoded.LinkFee) + assert.Equal(t, big.NewInt(300000000000000000), decoded.NativeFee) + + t.Run("Decode decodes the report", func(t *testing.T) { + decoded, err := rc.Decode(encoded) + require.NoError(t, err) + + assert.Equal(t, &reporttypes.Report{ + FeedId: [32]uint8{0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + ObservationsTimestamp: 0x22, + BenchmarkPrice: big.NewInt(380), + Bid: big.NewInt(370), + Ask: big.NewInt(390), + ValidFromTimestamp: 0x1d, + ExpiresAt: uint32(94), + LinkFee: big.NewInt(291666666666666667), + NativeFee: big.NewInt(300000000000000000), + }, decoded) + }) + }) + + t.Run("Decode errors on invalid report", func(t *testing.T) { + _, err := rc.Decode([]byte{1, 2, 3}) + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + + longBad := make([]byte, 64) + for i := 0; i < len(longBad); i++ { + longBad[i] = byte(i) + } + _, err = rc.Decode(longBad) + assert.EqualError(t, err, "failed to decode report: abi: improperly encoded uint32 value") + }) +} diff --git a/core/services/llo/keyring.go b/core/services/llo/keyring.go index 042b5e4625..8137a5ac3d 100644 --- a/core/services/llo/keyring.go +++ b/core/services/llo/keyring.go @@ -1,15 +1,19 @@ package llo import ( + "bytes" "fmt" + "sort" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "golang.org/x/exp/maps" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" ) type LLOOnchainKeyring ocr3types.OnchainKeyring[llotypes.ReportInfo] @@ -17,6 +21,11 @@ type LLOOnchainKeyring ocr3types.OnchainKeyring[llotypes.ReportInfo] var _ LLOOnchainKeyring = &onchainKeyring{} type Key interface { + // Legacy Sign/Verify methods needed for v0.3 report compatibility + // New keys can leave these stubbed + Sign(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) ([]byte, error) + Verify(publicKey ocrtypes.OnchainPublicKey, reportCtx ocrtypes.ReportContext, report ocrtypes.Report, signature []byte) bool + Sign3(digest ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report) (signature []byte, err error) Verify3(publicKey ocrtypes.OnchainPublicKey, cd ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report, signature []byte) bool PublicKey() ocrtypes.OnchainPublicKey @@ -35,12 +44,29 @@ func NewOnchainKeyring(lggr logger.Logger, keys map[llotypes.ReportFormat]Key) L } func (okr *onchainKeyring) PublicKey() types.OnchainPublicKey { - // All public keys combined - var pk []byte - for _, k := range okr.keys { - pk = append(pk, k.PublicKey()...) + // All unique public keys sorted in ascending order and combined into one + // byte string + onchainPublicKey := []byte{} + + keys := maps.Values(okr.keys) + if len(keys) == 0 { + return onchainPublicKey } - return pk + sort.Slice(keys, func(i, j int) bool { + return bytes.Compare(keys[i].PublicKey(), keys[j].PublicKey()) < 0 + }) + + onchainPublicKey = append(onchainPublicKey, keys[0].PublicKey()...) + if len(keys) == 1 { + return onchainPublicKey + } + for i := 1; i < len(keys); i++ { + if keys[i] != keys[i-1] { + onchainPublicKey = append(onchainPublicKey, keys[i].PublicKey()...) + } + } + + return onchainPublicKey } func (okr *onchainKeyring) MaxSignatureLength() (n int) { @@ -52,17 +78,37 @@ func (okr *onchainKeyring) MaxSignatureLength() (n int) { } func (okr *onchainKeyring) Sign(digest types.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[llotypes.ReportInfo]) (signature []byte, err error) { - rf := r.Info.ReportFormat - if key, exists := okr.keys[rf]; exists { - return key.Sign3(digest, seqNr, r.Report) + switch r.Info.ReportFormat { + case llotypes.ReportFormatEVMPremiumLegacy: + rf := r.Info.ReportFormat + if key, exists := okr.keys[rf]; exists { + // NOTE: Must use legacy Sign method for compatibility with v0.3 report verification + rc := evm.LegacyReportContext(digest, seqNr) + return key.Sign(rc, r.Report) + } + default: + rf := r.Info.ReportFormat + if key, exists := okr.keys[rf]; exists { + return key.Sign3(digest, seqNr, r.Report) + } } return nil, fmt.Errorf("Sign failed; unsupported report format: %q", r.Info.ReportFormat) } func (okr *onchainKeyring) Verify(key types.OnchainPublicKey, digest types.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[llotypes.ReportInfo], signature []byte) bool { - rf := r.Info.ReportFormat - if verifier, exists := okr.keys[rf]; exists { - return verifier.Verify3(key, digest, seqNr, r.Report, signature) + switch r.Info.ReportFormat { + case llotypes.ReportFormatEVMPremiumLegacy: + rf := r.Info.ReportFormat + if verifier, exists := okr.keys[rf]; exists { + // NOTE: Must use legacy Verify method for compatibility with v0.3 report verification + rc := evm.LegacyReportContext(digest, seqNr) + return verifier.Verify(key, rc, r.Report, signature) + } + default: + rf := r.Info.ReportFormat + if verifier, exists := okr.keys[rf]; exists { + return verifier.Verify3(key, digest, seqNr, r.Report, signature) + } } okr.lggr.Errorf("Verify failed; unsupported report format: %q", r.Info.ReportFormat) return false diff --git a/core/services/llo/keyring_test.go b/core/services/llo/keyring_test.go new file mode 100644 index 0000000000..44371e1496 --- /dev/null +++ b/core/services/llo/keyring_test.go @@ -0,0 +1,115 @@ +package llo + +import ( + "fmt" + "math/rand" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + ocr3types "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +var _ Key = &mockKey{} + +type mockKey struct { + format llotypes.ReportFormat + verify bool + maxSignatureLen int + sig []byte +} + +func (m *mockKey) Sign(reportCtx ocrtypes.ReportContext, report ocrtypes.Report) ([]byte, error) { + return m.sig, nil +} + +func (m *mockKey) Verify(publicKey ocrtypes.OnchainPublicKey, reportCtx ocrtypes.ReportContext, report ocrtypes.Report, signature []byte) bool { + return m.verify +} + +func (m *mockKey) Sign3(digest ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report) (signature []byte, err error) { + return m.sig, nil +} + +func (m *mockKey) Verify3(publicKey ocrtypes.OnchainPublicKey, cd ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report, signature []byte) bool { + return m.verify +} + +func (m *mockKey) PublicKey() ocrtypes.OnchainPublicKey { + b := make([]byte, m.maxSignatureLen) + for i := 0; i < m.maxSignatureLen; i++ { + b[i] = byte(255) + } + return ocrtypes.OnchainPublicKey(b) +} + +func (m *mockKey) MaxSignatureLength() int { + return m.maxSignatureLen +} + +func (m *mockKey) reset(format llotypes.ReportFormat) { + m.format = format + m.verify = false +} + +func Test_Keyring(t *testing.T) { + lggr := logger.TestLogger(t) + + ks := map[llotypes.ReportFormat]Key{ + llotypes.ReportFormatEVMPremiumLegacy: &mockKey{format: llotypes.ReportFormatEVMPremiumLegacy, maxSignatureLen: 1, sig: []byte("sig-1")}, + llotypes.ReportFormatJSON: &mockKey{format: llotypes.ReportFormatJSON, maxSignatureLen: 2, sig: []byte("sig-2")}, + } + + kr := NewOnchainKeyring(lggr, ks) + + cases := []struct { + format llotypes.ReportFormat + }{ + { + llotypes.ReportFormatEVMPremiumLegacy, + }, + { + llotypes.ReportFormatJSON, + }, + } + + cd, err := ocrtypes.BytesToConfigDigest(testutils.MustRandBytes(32)) + require.NoError(t, err) + seqNr := rand.Uint64() + t.Run("Sign+Verify", func(t *testing.T) { + for _, tc := range cases { + t.Run(tc.format.String(), func(t *testing.T) { + k := ks[tc.format] + defer k.(*mockKey).reset(tc.format) + + sig, err := kr.Sign(cd, seqNr, ocr3types.ReportWithInfo[llotypes.ReportInfo]{Info: llotypes.ReportInfo{ReportFormat: tc.format}}) + require.NoError(t, err) + + assert.Equal(t, []byte(fmt.Sprintf("sig-%d", tc.format)), sig) + + assert.False(t, kr.Verify(nil, cd, seqNr, ocr3types.ReportWithInfo[llotypes.ReportInfo]{Info: llotypes.ReportInfo{ReportFormat: tc.format}}, sig)) + + k.(*mockKey).verify = true + }) + } + }) + + t.Run("MaxSignatureLength", func(t *testing.T) { + assert.Equal(t, 2+1, kr.MaxSignatureLength()) + }) + t.Run("PublicKey", func(t *testing.T) { + b := make([]byte, 2+1) + for i := 0; i < len(b); i++ { + b[i] = byte(255) + } + assert.Equal(t, types.OnchainPublicKey(b), kr.PublicKey()) + }) +} diff --git a/core/services/llo/onchain_channel_definition_cache.go b/core/services/llo/onchain_channel_definition_cache.go index 3362aa9b9d..51cfae964d 100644 --- a/core/services/llo/onchain_channel_definition_cache.go +++ b/core/services/llo/onchain_channel_definition_cache.go @@ -1,17 +1,24 @@ package llo import ( + "bytes" "context" "database/sql" + "encoding/json" "errors" "fmt" + "io" + "io/ioutil" "maps" + "math/big" + "net/http" "strings" "sync" "time" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "golang.org/x/crypto/sha3" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" @@ -19,16 +26,29 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_config_store" + "github.com/smartcontractkit/chainlink/v2/core/utils" + clhttp "github.com/smartcontractkit/chainlink/v2/core/utils/http" ) -type ChannelDefinitionCacheORM interface { - // TODO: What about delete/cleanup? - // https://smartcontract-it.atlassian.net/browse/MERC-3653 - LoadChannelDefinitions(ctx context.Context, addr common.Address) (dfns llotypes.ChannelDefinitions, blockNum int64, err error) - StoreChannelDefinitions(ctx context.Context, addr common.Address, dfns llotypes.ChannelDefinitions, blockNum int64) (err error) -} +const ( + // MaxChannelDefinitionsFileSize is a sanity limit to avoid OOM for a + // maliciously large file. It should be much larger than any real expected + // channel definitions file. + MaxChannelDefinitionsFileSize = 25 * 1024 * 1024 // 25MB + // How often we query logpoller for new logs + defaultLogPollInterval = 1 * time.Second + // How often we check for failed persistence and attempt to save again + dbPersistLoopInterval = 1 * time.Second + + newChannelDefinitionEventName = "NewChannelDefinition" +) + +var ( + channelConfigStoreABI abi.ABI + topicNewChannelDefinition = (channel_config_store.ChannelConfigStoreNewChannelDefinition{}).Topic() -var channelConfigStoreABI abi.ABI + allTopics = []common.Hash{topicNewChannelDefinition} +) func init() { var err error @@ -38,82 +58,126 @@ func init() { } } +type ChannelDefinitionCacheORM interface { + // TODO: What about delete/cleanup? + // https://smartcontract-it.atlassian.net/browse/MERC-3653 + LoadChannelDefinitions(ctx context.Context, addr common.Address, donID uint32) (pd *PersistedDefinitions, err error) + StoreChannelDefinitions(ctx context.Context, addr common.Address, donID, version uint32, dfns llotypes.ChannelDefinitions, blockNum int64) (err error) +} + var _ llotypes.ChannelDefinitionCache = &channelDefinitionCache{} +type LogPoller interface { + RegisterFilter(ctx context.Context, filter logpoller.Filter) error + LatestBlock(ctx context.Context) (logpoller.LogPollerBlock, error) + LogsWithSigs(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) +} + +type Option func(*channelDefinitionCache) + +func WithLogPollInterval(d time.Duration) Option { + return func(c *channelDefinitionCache) { + c.logPollInterval = d + } +} + type channelDefinitionCache struct { services.StateMachine - orm ChannelDefinitionCacheORM + orm ChannelDefinitionCacheORM + client HTTPClient + httpLimit int64 + + filterName string + lp LogPoller + logPollInterval time.Duration + addr common.Address + donID uint32 + lggr logger.SugaredLogger + initialBlockNum int64 - filterName string - lp logpoller.LogPoller - fromBlock int64 - addr common.Address - lggr logger.Logger + newLogMu sync.RWMutex + newLog *channel_config_store.ChannelConfigStoreNewChannelDefinition + newLogCh chan *channel_config_store.ChannelConfigStoreNewChannelDefinition definitionsMu sync.RWMutex definitions llotypes.ChannelDefinitions + definitionsVersion uint32 definitionsBlockNum int64 + persistMu sync.RWMutex + persistedVersion uint32 + wg sync.WaitGroup chStop chan struct{} } -var ( - topicNewChannelDefinition = (channel_config_store.ChannelConfigStoreNewChannelDefinition{}).Topic() - topicChannelDefinitionRemoved = (channel_config_store.ChannelConfigStoreChannelDefinitionRemoved{}).Topic() - - allTopics = []common.Hash{topicNewChannelDefinition, topicChannelDefinitionRemoved} -) +type HTTPClient interface { + Do(req *http.Request) (*http.Response, error) +} -func NewChannelDefinitionCache(lggr logger.Logger, orm ChannelDefinitionCacheORM, lp logpoller.LogPoller, addr common.Address, fromBlock int64) llotypes.ChannelDefinitionCache { - filterName := logpoller.FilterName("OCR3 LLO ChannelDefinitionCachePoller", addr.String()) - return &channelDefinitionCache{ - services.StateMachine{}, - orm, - filterName, - lp, - 0, - addr, - logger.Sugared(lggr).Named("ChannelDefinitionCache").With("addr", addr, "fromBlock", fromBlock), - sync.RWMutex{}, - nil, - fromBlock, - sync.WaitGroup{}, - make(chan struct{}), +func NewChannelDefinitionCache(lggr logger.Logger, orm ChannelDefinitionCacheORM, client HTTPClient, lp logpoller.LogPoller, addr common.Address, donID uint32, fromBlock int64, options ...Option) llotypes.ChannelDefinitionCache { + filterName := logpoller.FilterName("OCR3 LLO ChannelDefinitionCachePoller", addr.String(), donID) + cdc := &channelDefinitionCache{ + orm: orm, + client: client, + httpLimit: MaxChannelDefinitionsFileSize, + filterName: filterName, + lp: lp, + logPollInterval: defaultLogPollInterval, + addr: addr, + donID: donID, + lggr: logger.Sugared(lggr).Named("ChannelDefinitionCache").With("addr", addr, "fromBlock", fromBlock), + newLogCh: make(chan *channel_config_store.ChannelConfigStoreNewChannelDefinition, 1), + initialBlockNum: fromBlock, + chStop: make(chan struct{}), + } + for _, option := range options { + option(cdc) } + return cdc } func (c *channelDefinitionCache) Start(ctx context.Context) error { // Initial load from DB, then async poll from chain thereafter return c.StartOnce("ChannelDefinitionCache", func() (err error) { - err = c.lp.RegisterFilter(ctx, logpoller.Filter{Name: c.filterName, EventSigs: allTopics, Addresses: []common.Address{c.addr}}) + donIDTopic := common.BigToHash(big.NewInt(int64(c.donID))) + err = c.lp.RegisterFilter(ctx, logpoller.Filter{Name: c.filterName, EventSigs: allTopics, Topic2: []common.Hash{donIDTopic}, Addresses: []common.Address{c.addr}}) if err != nil { return err } - if definitions, definitionsBlockNum, err := c.orm.LoadChannelDefinitions(ctx, c.addr); err != nil { + if pd, err := c.orm.LoadChannelDefinitions(ctx, c.addr, c.donID); err != nil { return err - } else if definitions != nil { - c.definitions = definitions - c.definitionsBlockNum = definitionsBlockNum + } else if pd != nil { + c.definitions = pd.Definitions + c.initialBlockNum = pd.BlockNum + 1 + c.definitionsVersion = uint32(pd.Version) } else { // ensure non-nil map ready for assignment later c.definitions = make(llotypes.ChannelDefinitions) - // leave c.definitionsBlockNum as provided fromBlock argument + // leave c.initialBlockNum as provided fromBlock argument } - c.wg.Add(1) - go c.poll() + c.wg.Add(3) + // We have three concurrent loops + // 1. Poll chain for new logs + // 2. Fetch latest definitions from URL and verify SHA, according to latest log + // 3. Retry persisting records to DB, if it failed + go c.pollChainLoop() + go c.fetchLatestLoop() + go c.failedPersistLoop() return nil }) } -// TODO: make this configurable? -const pollInterval = 1 * time.Second +//////////////////////////////////////////////////////////////////// +// Log Polling +//////////////////////////////////////////////////////////////////// -func (c *channelDefinitionCache) poll() { +// pollChainLoop periodically checks logpoller for new logs +func (c *channelDefinitionCache) pollChainLoop() { defer c.wg.Done() - pollT := services.NewTicker(pollInterval) + pollT := services.NewTicker(c.logPollInterval) defer pollT.Stop() for { @@ -121,114 +185,303 @@ func (c *channelDefinitionCache) poll() { case <-c.chStop: return case <-pollT.C: - if n, err := c.fetchFromChain(); err != nil { - // TODO: retry with backoff? - // https://smartcontract-it.atlassian.net/browse/MERC-3653 + // failures will be tried again on the next tick + if err := c.readLogs(); err != nil { c.lggr.Errorw("Failed to fetch channel definitions from chain", "err", err) continue - } else { - if n > 0 { - c.lggr.Infow("Updated channel definitions", "nLogs", n, "definitionsBlockNum", c.definitionsBlockNum) - } else { - c.lggr.Debugw("No new channel definitions", "nLogs", 0, "definitionsBlockNum", c.definitionsBlockNum) - } } } } } -func (c *channelDefinitionCache) fetchFromChain() (nLogs int, err error) { - // TODO: Pass context +func (c *channelDefinitionCache) readLogs() (err error) { ctx, cancel := services.StopChan(c.chStop).NewCtx() defer cancel() - // https://smartcontract-it.atlassian.net/browse/MERC-3653 - latest, err := c.lp.LatestBlock(ctx) + latestBlock, err := c.lp.LatestBlock(ctx) if errors.Is(err, sql.ErrNoRows) { c.lggr.Debug("Logpoller has no logs yet, skipping poll") - return 0, nil + return nil } else if err != nil { - return 0, err + return err } - toBlock := latest.BlockNumber + toBlock := latestBlock.BlockNumber - fromBlock := c.definitionsBlockNum + fromBlock := c.scanFromBlockNum() if toBlock <= fromBlock { - return 0, nil + return nil } - // NOTE: We assume that log poller returns logs in ascending order chronologically + // NOTE: We assume that log poller returns logs in order of block_num, log_index ASC logs, err := c.lp.LogsWithSigs(ctx, fromBlock, toBlock, allTopics, c.addr) if err != nil { - // TODO: retry? - // https://smartcontract-it.atlassian.net/browse/MERC-3653 - return 0, err + return err } + for _, log := range logs { - if err = c.applyLog(log); err != nil { - return 0, err + switch log.EventSig { + case topicNewChannelDefinition: + unpacked := new(channel_config_store.ChannelConfigStoreNewChannelDefinition) + + err := channelConfigStoreABI.UnpackIntoInterface(unpacked, newChannelDefinitionEventName, log.Data) + if err != nil { + return fmt.Errorf("failed to unpack log data: %w", err) + } + if len(log.Topics) < 2 { + // should never happen but must guard against unexpected panics + c.lggr.Warnw("Log missing expected topics", "log", log) + continue + } + unpacked.DonId = new(big.Int).SetBytes(log.Topics[1]) + + if unpacked.DonId.Cmp(big.NewInt(int64(c.donID))) != 0 { + c.lggr.Warnw("Got log for unexpected donID", "donID", unpacked.DonId.String(), "expectedDonID", c.donID) + // ignore logs for other donIDs + // NOTE: shouldn't happen anyway since log poller filters on + // donID + continue + } + + c.newLogMu.Lock() + if c.newLog == nil || unpacked.Version > c.newLog.Version { + // assume that donID is correct due to log poller filtering + c.lggr.Infow("Got new channel definitions from chain", "version", unpacked.Version, "blockNumber", log.BlockNumber, "sha", fmt.Sprintf("%x", unpacked.Sha), "url", unpacked.Url) + c.newLog = unpacked + c.newLogCh <- unpacked + } + c.newLogMu.Unlock() + + default: + // ignore unrecognized logs + continue } } - // Use context.Background() here because we want to try to save even if we - // are closing - if err = c.orm.StoreChannelDefinitions(context.Background(), c.addr, c.Definitions(), toBlock); err != nil { - return 0, err + return nil +} + +func (c *channelDefinitionCache) scanFromBlockNum() int64 { + c.newLogMu.RLock() + defer c.newLogMu.RUnlock() + if c.newLog != nil { + return int64(c.newLog.Raw.BlockNumber) + 1 } + return c.initialBlockNum +} - c.definitionsBlockNum = toBlock +//////////////////////////////////////////////////////////////////// +// Fetch channel definitions from URL based on latest log +//////////////////////////////////////////////////////////////////// - return len(logs), nil +// fetchLatestLoop waits for new logs and tries on a loop to fetch the channel definitions from the specified url +func (c *channelDefinitionCache) fetchLatestLoop() { + defer c.wg.Done() + + var fetchCh chan struct{} + + for { + select { + case latest := <-c.newLogCh: + // kill the old retry loop if any + if fetchCh != nil { + close(fetchCh) + } + + fetchCh = make(chan struct{}) + + c.wg.Add(1) + go c.fetchLoop(fetchCh, latest) + + case <-c.chStop: + return + } + } } -func (c *channelDefinitionCache) applyLog(log logpoller.Log) error { - switch log.EventSig { - case topicNewChannelDefinition: - unpacked := new(channel_config_store.ChannelConfigStoreNewChannelDefinition) +func (c *channelDefinitionCache) fetchLoop(closeCh chan struct{}, log *channel_config_store.ChannelConfigStoreNewChannelDefinition) { + defer c.wg.Done() + b := utils.NewHTTPFetchBackoff() + var attemptCnt int - err := channelConfigStoreABI.UnpackIntoInterface(unpacked, "NewChannelDefinition", log.Data) - if err != nil { - return fmt.Errorf("failed to unpack log data: %w", err) + ctx, cancel := services.StopChan(c.chStop).NewCtx() + defer cancel() + + err := c.fetchAndSetChannelDefinitions(ctx, log) + if err == nil { + c.lggr.Debugw("Set new channel definitions", "donID", c.donID, "version", log.Version, "url", log.Url, "sha", fmt.Sprintf("%x", log.Sha)) + return + } + c.lggr.Warnw("Error while fetching channel definitions", "donID", c.donID, "version", log.Version, "url", log.Url, "sha", fmt.Sprintf("%x", log.Sha), "err", err, "attempt", attemptCnt) + + for { + select { + case <-closeCh: + return + case <-time.After(b.Duration()): + attemptCnt++ + err := c.fetchAndSetChannelDefinitions(ctx, log) + if err != nil { + c.lggr.Warnw("Error while fetching channel definitions", "version", log.Version, "url", log.Url, "sha", fmt.Sprintf("%x", log.Sha), "err", err, "attempt", attemptCnt) + continue + } + c.lggr.Debugw("Set new channel definitions", "donID", c.donID, "version", log.Version, "url", log.Url, "sha", fmt.Sprintf("%x", log.Sha)) + return } + } +} - c.applyNewChannelDefinition(unpacked) - case topicChannelDefinitionRemoved: - unpacked := new(channel_config_store.ChannelConfigStoreChannelDefinitionRemoved) +func (c *channelDefinitionCache) fetchAndSetChannelDefinitions(ctx context.Context, log *channel_config_store.ChannelConfigStoreNewChannelDefinition) error { + c.definitionsMu.RLock() + if log.Version <= c.definitionsVersion { + c.definitionsMu.RUnlock() + return nil + } + c.definitionsMu.RUnlock() - err := channelConfigStoreABI.UnpackIntoInterface(unpacked, "ChannelDefinitionRemoved", log.Data) + cd, err := c.fetchChannelDefinitions(ctx, log.Url, log.Sha) + if err != nil { + return err + } + c.definitionsMu.Lock() + if log.Version <= c.definitionsVersion { + c.definitionsMu.Unlock() + return nil + } + c.definitions = cd + c.definitionsBlockNum = int64(log.Raw.BlockNumber) + c.definitionsVersion = log.Version + c.definitionsMu.Unlock() + + if memoryVersion, persistedVersion, err := c.persist(context.Background()); err != nil { + // If this fails, the failedPersistLoop will try again + c.lggr.Warnw("Failed to persist channel definitions", "err", err, "memoryVersion", memoryVersion, "persistedVersion", persistedVersion) + } + + return nil +} + +func (c *channelDefinitionCache) fetchChannelDefinitions(ctx context.Context, url string, expectedSha [32]byte) (llotypes.ChannelDefinitions, error) { + request, err := http.NewRequestWithContext(ctx, "GET", url, nil) + if err != nil { + return nil, fmt.Errorf("failed to create http.Request; %w", err) + } + request.Header.Set("Content-Type", "application/json") + + httpRequest := clhttp.HTTPRequest{ + Client: c.client, + Request: request, + Config: clhttp.HTTPRequestConfig{SizeLimit: c.httpLimit}, + Logger: c.lggr.Named("HTTPRequest").With("url", url, "expectedSHA", fmt.Sprintf("%x", expectedSha)), + } + + reader, statusCode, _, err := httpRequest.SendRequestReader() + if err != nil { + return nil, fmt.Errorf("error making http request: %w", err) + } + defer reader.Close() + + if statusCode >= 400 { + // NOTE: Truncate the returned body here as we don't want to spam the + // logs with potentially huge messages + body := http.MaxBytesReader(nil, reader, 1024) + defer body.Close() + bodyBytes, err := ioutil.ReadAll(body) if err != nil { - return fmt.Errorf("failed to unpack log data: %w", err) + return nil, fmt.Errorf("got error from %s: (status code: %d, error reading response body: %w, response body: %s)", url, statusCode, err, bodyBytes) } + return nil, fmt.Errorf("got error from %s: (status code: %d, response body: %s)", url, statusCode, string(bodyBytes)) + } + + var buf bytes.Buffer + // Use a teeReader to avoid excessive copying + teeReader := io.TeeReader(reader, &buf) - c.applyChannelDefinitionRemoved(unpacked) - default: - // don't return error here, we want to ignore unrecognized logs and - // continue rather than interrupting the loop - c.lggr.Errorw("Unexpected log topic", "topic", log.EventSig.Hex()) + hash := sha3.New256() + // Stream the data directly into the hash and copy to buf as we go + if _, err := io.Copy(hash, teeReader); err != nil { + return nil, fmt.Errorf("failed to read from body: %w", err) } - return nil + + actualSha := hash.Sum(nil) + if !bytes.Equal(expectedSha[:], actualSha) { + return nil, fmt.Errorf("SHA3 mismatch: expected %x, got %x", expectedSha, actualSha) + } + + var cd llotypes.ChannelDefinitions + decoder := json.NewDecoder(&buf) + if err := decoder.Decode(&cd); err != nil { + return nil, fmt.Errorf("failed to decode JSON: %w", err) + } + + return cd, nil } -func (c *channelDefinitionCache) applyNewChannelDefinition(log *channel_config_store.ChannelConfigStoreNewChannelDefinition) { - streamIDs := make([]llotypes.StreamID, len(log.ChannelDefinition.StreamIDs)) - copy(streamIDs, log.ChannelDefinition.StreamIDs) - c.definitionsMu.Lock() - defer c.definitionsMu.Unlock() - c.definitions[log.ChannelId] = llotypes.ChannelDefinition{ - ReportFormat: llotypes.ReportFormat(log.ChannelDefinition.ReportFormat), +//////////////////////////////////////////////////////////////////// +// Persistence +//////////////////////////////////////////////////////////////////// + +func (c *channelDefinitionCache) persist(ctx context.Context) (memoryVersion, persistedVersion uint32, err error) { + c.persistMu.RLock() + persistedVersion = c.persistedVersion + c.persistMu.RUnlock() + + c.definitionsMu.RLock() + memoryVersion = c.definitionsVersion + dfns := c.definitions + blockNum := c.definitionsBlockNum + c.definitionsMu.RUnlock() + + if memoryVersion <= persistedVersion { + return + } + + if err = c.orm.StoreChannelDefinitions(ctx, c.addr, c.donID, memoryVersion, dfns, blockNum); err != nil { + return + } + + c.persistMu.Lock() + defer c.persistMu.Unlock() + if memoryVersion > c.persistedVersion { + persistedVersion = memoryVersion + c.persistedVersion = persistedVersion } + + // TODO: we could delete the old logs from logpoller here actually + // https://smartcontract-it.atlassian.net/browse/MERC-3653 + return } -func (c *channelDefinitionCache) applyChannelDefinitionRemoved(log *channel_config_store.ChannelConfigStoreChannelDefinitionRemoved) { - c.definitionsMu.Lock() - defer c.definitionsMu.Unlock() - delete(c.definitions, log.ChannelId) +// Checks persisted version and tries to save if necessary on a periodic timer +// Simple backup in case database persistence fails +func (c *channelDefinitionCache) failedPersistLoop() { + defer c.wg.Done() + + ctx, cancel := services.StopChan(c.chStop).NewCtx() + defer cancel() + + for { + select { + case <-time.After(dbPersistLoopInterval): + if memoryVersion, persistedVersion, err := c.persist(ctx); err != nil { + c.lggr.Warnw("Failed to persist channel definitions", "err", err, "memoryVersion", memoryVersion, "persistedVersion", persistedVersion) + } + case <-c.chStop: + // Try one final persist with a short-ish timeout, then return + ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + if memoryVersion, persistedVersion, err := c.persist(ctx); err != nil { + c.lggr.Errorw("Failed to persist channel definitions on shutdown", "err", err, "memoryVersion", memoryVersion, "persistedVersion", persistedVersion) + } + return + } + } } func (c *channelDefinitionCache) Close() error { // TODO: unregister filter (on job delete)? // https://smartcontract-it.atlassian.net/browse/MERC-3653 return c.StopOnce("ChannelDefinitionCache", func() error { + // Cancel all contexts but try one final persist before closing close(c.chStop) c.wg.Wait() return nil diff --git a/core/services/llo/onchain_channel_definition_cache_test.go b/core/services/llo/onchain_channel_definition_cache_test.go index 2fbc0c1b90..5bd7eedbb1 100644 --- a/core/services/llo/onchain_channel_definition_cache_test.go +++ b/core/services/llo/onchain_channel_definition_cache_test.go @@ -1,23 +1,429 @@ package llo import ( + "bytes" + "context" + "database/sql" + "errors" + "fmt" + "io" + "math/big" + "math/rand" + "net/http" "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_config_store" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" ) +type mockLogPoller struct { + latestBlock logpoller.LogPollerBlock + latestBlockErr error + logsWithSigs []logpoller.Log + logsWithSigsErr error +} + +func (m *mockLogPoller) RegisterFilter(ctx context.Context, filter logpoller.Filter) error { + return nil +} +func (m *mockLogPoller) LatestBlock(ctx context.Context) (logpoller.LogPollerBlock, error) { + return m.latestBlock, m.latestBlockErr +} +func (m *mockLogPoller) LogsWithSigs(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) { + return m.logsWithSigs, m.logsWithSigsErr +} + +var _ HTTPClient = &mockHTTPClient{} + +type mockHTTPClient struct { + resp *http.Response + err error +} + +func (m *mockHTTPClient) Do(req *http.Request) (*http.Response, error) { + return m.resp, m.err +} + +var _ ChannelDefinitionCacheORM = &mockORM{} + +type mockORM struct { + err error + + lastPersistedAddr common.Address + lastPersistedDonID uint32 + lastPersistedVersion uint32 + lastPersistedDfns llotypes.ChannelDefinitions + lastPersistedBlockNum int64 +} + +func (m *mockORM) LoadChannelDefinitions(ctx context.Context, addr common.Address, donID uint32) (pd *PersistedDefinitions, err error) { + panic("not implemented") +} +func (m *mockORM) StoreChannelDefinitions(ctx context.Context, addr common.Address, donID, version uint32, dfns llotypes.ChannelDefinitions, blockNum int64) (err error) { + m.lastPersistedAddr = addr + m.lastPersistedDonID = donID + m.lastPersistedVersion = version + m.lastPersistedDfns = dfns + m.lastPersistedBlockNum = blockNum + return m.err +} + +func makeLog(t *testing.T, donID, version uint32, url string, sha [32]byte) logpoller.Log { + data := makeLogData(t, donID, version, url, sha) + return logpoller.Log{EventSig: topicNewChannelDefinition, Topics: [][]byte{topicNewChannelDefinition[:], makeDonIDTopic(donID)}, Data: data} +} + +func makeLogData(t *testing.T, donID, version uint32, url string, sha [32]byte) []byte { + event := channelConfigStoreABI.Events[newChannelDefinitionEventName] + // donID is indexed + // version, url, sha + data, err := event.Inputs.NonIndexed().Pack(version, url, sha) + require.NoError(t, err) + return data +} + +func makeDonIDTopic(donID uint32) []byte { + return common.BigToHash(big.NewInt(int64(donID))).Bytes() +} + func Test_ChannelDefinitionCache(t *testing.T) { - t.Skip("waiting on https://github.com/smartcontractkit/chainlink/pull/13780") - // t.Run("Definitions", func(t *testing.T) { - // // NOTE: this is covered more thoroughly in the integration tests - // dfns := llotypes.ChannelDefinitions(map[llotypes.ChannelID]llotypes.ChannelDefinition{ - // 1: { - // ReportFormat: llotypes.ReportFormat(43), - // ChainSelector: 42, - // StreamIDs: []llotypes.StreamID{1, 2, 3}, - // }, - // }) - - // cdc := &channelDefinitionCache{definitions: dfns} - - // assert.Equal(t, dfns, cdc.Definitions()) - // }) + donID := rand.Uint32() + ctx := tests.Context(t) + + t.Run("Definitions", func(t *testing.T) { + // NOTE: this is covered more thoroughly in the integration tests + dfns := llotypes.ChannelDefinitions(map[llotypes.ChannelID]llotypes.ChannelDefinition{ + 1: { + ReportFormat: llotypes.ReportFormat(43), + Streams: []llotypes.Stream{{StreamID: 1, Aggregator: llotypes.AggregatorMedian}, {StreamID: 2, Aggregator: llotypes.AggregatorMode}, {StreamID: 3, Aggregator: llotypes.AggregatorQuote}}, + Opts: llotypes.ChannelOpts{1, 2, 3}, + }, + }) + + cdc := &channelDefinitionCache{definitions: dfns} + + assert.Equal(t, dfns, cdc.Definitions()) + }) + + t.Run("readLogs", func(t *testing.T) { + lp := &mockLogPoller{latestBlockErr: sql.ErrNoRows} + newLogCh := make(chan *channel_config_store.ChannelConfigStoreNewChannelDefinition, 100) + cdc := &channelDefinitionCache{donID: donID, lp: lp, lggr: logger.TestSugared(t), newLogCh: newLogCh} + + t.Run("skips if logpoller has no blocks", func(t *testing.T) { + err := cdc.readLogs() + assert.NoError(t, err) + assert.Nil(t, cdc.newLog) + }) + t.Run("returns error on LatestBlock failure", func(t *testing.T) { + lp.latestBlockErr = errors.New("test error") + + err := cdc.readLogs() + assert.EqualError(t, err, "test error") + assert.Nil(t, cdc.newLog) + }) + t.Run("does nothing if LatestBlock older or the same as current channel definitions block", func(t *testing.T) { + lp.latestBlockErr = nil + lp.latestBlock = logpoller.LogPollerBlock{BlockNumber: 42} + cdc.definitionsBlockNum = 43 + + err := cdc.readLogs() + assert.NoError(t, err) + assert.Nil(t, cdc.newLog) + }) + t.Run("returns error if LogsWithSigs fails", func(t *testing.T) { + cdc.definitionsBlockNum = 0 + lp.logsWithSigsErr = errors.New("test error 2") + + err := cdc.readLogs() + assert.EqualError(t, err, "test error 2") + assert.Nil(t, cdc.newLog) + }) + t.Run("ignores logs with different topic", func(t *testing.T) { + lp.logsWithSigsErr = nil + lp.logsWithSigs = []logpoller.Log{{EventSig: common.Hash{1, 2, 3, 4}}} + + err := cdc.readLogs() + assert.NoError(t, err) + assert.Nil(t, cdc.newLog) + }) + t.Run("returns error if log is malformed", func(t *testing.T) { + lp.logsWithSigsErr = nil + lp.logsWithSigs = []logpoller.Log{{EventSig: topicNewChannelDefinition}} + + err := cdc.readLogs() + assert.EqualError(t, err, "failed to unpack log data: abi: attempting to unmarshal an empty string while arguments are expected") + assert.Nil(t, cdc.newLog) + }) + t.Run("sets definitions and sends on channel if LogsWithSigs returns new event with a later version", func(t *testing.T) { + lp.logsWithSigsErr = nil + lp.logsWithSigs = []logpoller.Log{makeLog(t, donID, uint32(43), "http://example.com/xxx.json", [32]byte{1, 2, 3, 4})} + + err := cdc.readLogs() + require.NoError(t, err) + require.NotNil(t, cdc.newLog) + assert.Equal(t, uint32(43), cdc.newLog.Version) + assert.Equal(t, "http://example.com/xxx.json", cdc.newLog.Url) + assert.Equal(t, [32]byte{1, 2, 3, 4}, cdc.newLog.Sha) + assert.Equal(t, int64(donID), cdc.newLog.DonId.Int64()) + + func() { + for { + select { + case log := <-newLogCh: + assert.Equal(t, cdc.newLog, log) + default: + return + } + } + }() + }) + t.Run("does nothing if version older or the same as the one currently set", func(t *testing.T) { + lp.logsWithSigsErr = nil + lp.logsWithSigs = []logpoller.Log{ + makeLog(t, donID, uint32(42), "http://example.com/xxx.json", [32]byte{1, 2, 3, 4}), + makeLog(t, donID, uint32(43), "http://example.com/xxx.json", [32]byte{1, 2, 3, 4}), + } + + err := cdc.readLogs() + require.NoError(t, err) + assert.Equal(t, uint32(43), cdc.newLog.Version) + }) + t.Run("in case of multiple logs, takes the latest", func(t *testing.T) { + lp.logsWithSigsErr = nil + lp.logsWithSigs = []logpoller.Log{ + makeLog(t, donID, uint32(42), "http://example.com/xxx.json", [32]byte{1, 2, 3, 4}), + makeLog(t, donID, uint32(45), "http://example.com/xxx2.json", [32]byte{2, 2, 3, 4}), + makeLog(t, donID, uint32(44), "http://example.com/xxx3.json", [32]byte{3, 2, 3, 4}), + makeLog(t, donID, uint32(43), "http://example.com/xxx4.json", [32]byte{4, 2, 3, 4}), + } + + err := cdc.readLogs() + require.NoError(t, err) + assert.Equal(t, uint32(45), cdc.newLog.Version) + assert.Equal(t, "http://example.com/xxx2.json", cdc.newLog.Url) + assert.Equal(t, [32]byte{2, 2, 3, 4}, cdc.newLog.Sha) + assert.Equal(t, int64(donID), cdc.newLog.DonId.Int64()) + + func() { + for { + select { + case log := <-newLogCh: + assert.Equal(t, cdc.newLog, log) + default: + return + } + } + }() + }) + t.Run("ignores logs with incorrect don ID", func(t *testing.T) { + lp.logsWithSigsErr = nil + lp.logsWithSigs = []logpoller.Log{ + makeLog(t, donID+1, uint32(42), "http://example.com/xxx.json", [32]byte{1, 2, 3, 4}), + } + + err := cdc.readLogs() + require.NoError(t, err) + assert.Equal(t, uint32(45), cdc.newLog.Version) + + func() { + for { + select { + case log := <-newLogCh: + t.Fatal("did not expect log with wrong donID, got: ", log) + default: + return + } + } + }() + }) + t.Run("ignores logs with wrong number of topics", func(t *testing.T) { + lp.logsWithSigsErr = nil + lg := makeLog(t, donID, uint32(42), "http://example.com/xxx.json", [32]byte{1, 2, 3, 4}) + lg.Topics = lg.Topics[:1] + lp.logsWithSigs = []logpoller.Log{lg} + + err := cdc.readLogs() + require.NoError(t, err) + assert.Equal(t, uint32(45), cdc.newLog.Version) + + func() { + for { + select { + case log := <-newLogCh: + t.Fatal("did not expect log with missing topics, got: ", log) + default: + return + } + } + }() + }) + }) + + t.Run("fetchChannelDefinitions", func(t *testing.T) { + c := &mockHTTPClient{} + cdc := &channelDefinitionCache{ + lggr: logger.TestSugared(t), + client: c, + httpLimit: 2048, + } + + t.Run("nil ctx returns error", func(t *testing.T) { + _, err := cdc.fetchChannelDefinitions(nil, "notvalid://foos", [32]byte{}) + assert.EqualError(t, err, "failed to create http.Request; net/http: nil Context") + }) + + t.Run("networking error while making request returns error", func(t *testing.T) { + c.resp = nil + c.err = errors.New("http request failed") + + _, err := cdc.fetchChannelDefinitions(ctx, "http://example.com/definitions.json", [32]byte{}) + assert.EqualError(t, err, "error making http request: http request failed") + }) + + t.Run("server returns 500 returns error", func(t *testing.T) { + c.err = nil + c.resp = &http.Response{StatusCode: 500, Body: io.NopCloser(bytes.NewReader([]byte{1, 2, 3}))} + + _, err := cdc.fetchChannelDefinitions(ctx, "http://example.com/definitions.json", [32]byte{}) + assert.EqualError(t, err, "got error from http://example.com/definitions.json: (status code: 500, response body: \x01\x02\x03)") + }) + + var largeBody = make([]byte, 2048) + for i := range largeBody { + largeBody[i] = 'a' + } + + t.Run("server returns 404 returns error (and does not log entirety of huge response body)", func(t *testing.T) { + c.err = nil + c.resp = &http.Response{StatusCode: 404, Body: io.NopCloser(bytes.NewReader(largeBody))} + + _, err := cdc.fetchChannelDefinitions(ctx, "http://example.com/definitions.json", [32]byte{}) + assert.EqualError(t, err, "got error from http://example.com/definitions.json: (status code: 404, error reading response body: http: request body too large, response body: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)") + }) + + var hugeBody = make([]byte, 8096) + c.resp.Body = io.NopCloser(bytes.NewReader(hugeBody)) + + t.Run("server returns body that is too large", func(t *testing.T) { + c.err = nil + c.resp = &http.Response{StatusCode: 200, Body: io.NopCloser(bytes.NewReader(hugeBody))} + + _, err := cdc.fetchChannelDefinitions(ctx, "http://example.com/definitions.json", [32]byte{}) + assert.EqualError(t, err, "failed to read from body: http: request body too large") + }) + + t.Run("server returns invalid JSON returns error", func(t *testing.T) { + c.err = nil + c.resp = &http.Response{StatusCode: 200, Body: io.NopCloser(bytes.NewReader([]byte{1, 2, 3}))} + + _, err := cdc.fetchChannelDefinitions(ctx, "http://example.com/definitions.json", common.HexToHash("0xfd1780a6fc9ee0dab26ceb4b3941ab03e66ccd970d1db91612c66df4515b0a0a")) + assert.EqualError(t, err, "failed to decode JSON: invalid character '\\x01' looking for beginning of value") + }) + + t.Run("SHA mismatch returns error", func(t *testing.T) { + c.err = nil + c.resp = &http.Response{StatusCode: 200, Body: io.NopCloser(bytes.NewReader([]byte(`{"foo":"bar"}`)))} + + _, err := cdc.fetchChannelDefinitions(ctx, "http://example.com/definitions.json", [32]byte{}) + assert.EqualError(t, err, "SHA3 mismatch: expected 0000000000000000000000000000000000000000000000000000000000000000, got 4d3304d0d87c27a031cbb6bdf95da79b7b4552c3d0bef2e5a94f50810121e1e0") + }) + + t.Run("valid JSON matching SHA returns channel definitions", func(t *testing.T) { + chainSelector := 4949039107694359620 // arbitrum mainnet + feedID := [32]byte{00, 03, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} + expirationWindow := 3600 + multiplier := big.NewInt(1e18) + baseUSDFee := 10 + valid := fmt.Sprintf(` +{ + "42": { + "reportFormat": %d, + "chainSelector": %d, + "streams": [{"streamId": 52, "aggregator": %d}, {"streamId": 53, "aggregator": %d}, {"streamId": 55, "aggregator": %d}], + "opts": { + "feedId": "0x%x", + "expirationWindow": %d, + "multiplier": "%s", + "baseUSDFee": "%d" + } + } +}`, llotypes.ReportFormatEVMPremiumLegacy, chainSelector, llotypes.AggregatorMedian, llotypes.AggregatorMedian, llotypes.AggregatorQuote, feedID, expirationWindow, multiplier.String(), baseUSDFee) + + c.err = nil + c.resp = &http.Response{StatusCode: 200, Body: io.NopCloser(bytes.NewReader([]byte(valid)))} + + cd, err := cdc.fetchChannelDefinitions(ctx, "http://example.com/definitions.json", common.HexToHash("0x367bbc75f7b6c9fc66a98ea99f837ea7ac4a3c2d6a9ee284de018bd02c41b52d")) + assert.NoError(t, err) + assert.Equal(t, llotypes.ChannelDefinitions(llotypes.ChannelDefinitions{0x2a: llotypes.ChannelDefinition{ReportFormat: 0x1, Streams: []llotypes.Stream{llotypes.Stream{StreamID: 0x34, Aggregator: 0x1}, llotypes.Stream{StreamID: 0x35, Aggregator: 0x1}, llotypes.Stream{StreamID: 0x37, Aggregator: 0x3}}, Opts: llotypes.ChannelOpts{0x7b, 0x22, 0x62, 0x61, 0x73, 0x65, 0x55, 0x53, 0x44, 0x46, 0x65, 0x65, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x22, 0x2c, 0x22, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 0x3a, 0x33, 0x36, 0x30, 0x30, 0x2c, 0x22, 0x66, 0x65, 0x65, 0x64, 0x49, 0x64, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x30, 0x30, 0x33, 0x36, 0x62, 0x34, 0x61, 0x61, 0x37, 0x65, 0x35, 0x37, 0x63, 0x61, 0x37, 0x62, 0x36, 0x38, 0x61, 0x65, 0x31, 0x62, 0x66, 0x34, 0x35, 0x36, 0x35, 0x33, 0x66, 0x35, 0x36, 0x62, 0x36, 0x35, 0x36, 0x66, 0x64, 0x33, 0x61, 0x61, 0x33, 0x33, 0x35, 0x65, 0x66, 0x37, 0x66, 0x61, 0x65, 0x36, 0x39, 0x36, 0x62, 0x36, 0x36, 0x33, 0x66, 0x31, 0x62, 0x38, 0x34, 0x37, 0x32, 0x22, 0x2c, 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x7d}}}), cd) + }) + }) + + t.Run("persist", func(t *testing.T) { + cdc := &channelDefinitionCache{ + lggr: logger.TestSugared(t), + orm: nil, + addr: testutils.NewAddress(), + donID: donID, + definitions: llotypes.ChannelDefinitions{ + 1: { + ReportFormat: llotypes.ReportFormat(43), + Streams: []llotypes.Stream{{StreamID: 1, Aggregator: llotypes.AggregatorMedian}, {StreamID: 2, Aggregator: llotypes.AggregatorMode}, {StreamID: 3, Aggregator: llotypes.AggregatorQuote}}, + Opts: llotypes.ChannelOpts{1, 2, 3}, + }, + }, + definitionsBlockNum: 142, + } + + t.Run("does nothing if persisted version is up-to-date", func(t *testing.T) { + cdc.definitionsVersion = 42 + cdc.persistedVersion = 42 + + memoryVersion, persistedVersion, err := cdc.persist(ctx) + assert.NoError(t, err) + assert.Equal(t, uint32(42), memoryVersion) + assert.Equal(t, uint32(42), persistedVersion) + assert.Equal(t, uint32(42), cdc.persistedVersion) + }) + + orm := &mockORM{} + cdc.orm = orm + + t.Run("returns error on db failure and does not update persisted version", func(t *testing.T) { + cdc.persistedVersion = 42 + cdc.definitionsVersion = 43 + orm.err = errors.New("test error") + + memoryVersion, persistedVersion, err := cdc.persist(ctx) + assert.EqualError(t, err, "test error") + assert.Equal(t, uint32(43), memoryVersion) + assert.Equal(t, uint32(42), persistedVersion) + assert.Equal(t, uint32(42), cdc.persistedVersion) + }) + + t.Run("updates persisted version on success", func(t *testing.T) { + cdc.definitionsVersion = 43 + orm.err = nil + + memoryVersion, persistedVersion, err := cdc.persist(ctx) + assert.NoError(t, err) + assert.Equal(t, uint32(43), memoryVersion) + assert.Equal(t, uint32(43), persistedVersion) + assert.Equal(t, uint32(43), cdc.persistedVersion) + + assert.Equal(t, cdc.addr, orm.lastPersistedAddr) + assert.Equal(t, cdc.donID, orm.lastPersistedDonID) + assert.Equal(t, cdc.persistedVersion, orm.lastPersistedVersion) + assert.Equal(t, cdc.definitions, orm.lastPersistedDfns) + assert.Equal(t, cdc.definitionsBlockNum, orm.lastPersistedBlockNum) + }) + }) } diff --git a/core/services/llo/onchain_config.go b/core/services/llo/onchain_config.go deleted file mode 100644 index 7b5cfffaa9..0000000000 --- a/core/services/llo/onchain_config.go +++ /dev/null @@ -1,21 +0,0 @@ -package llo - -type OnchainConfig struct{} - -type OnchainConfigCodec interface { - Encode(OnchainConfig) ([]byte, error) - Decode([]byte) (OnchainConfig, error) -} - -var _ OnchainConfigCodec = &JSONOnchainConfigCodec{} - -// TODO: Replace this with protobuf, if it is actually used for something -type JSONOnchainConfigCodec struct{} - -func (c *JSONOnchainConfigCodec) Encode(OnchainConfig) ([]byte, error) { - return nil, nil -} - -func (c *JSONOnchainConfigCodec) Decode([]byte) (OnchainConfig, error) { - return OnchainConfig{}, nil -} diff --git a/core/services/llo/orm.go b/core/services/llo/orm.go index 6b14e54326..acf6e8c721 100644 --- a/core/services/llo/orm.go +++ b/core/services/llo/orm.go @@ -3,10 +3,9 @@ package llo import ( "context" "database/sql" - "encoding/json" "errors" "fmt" - "math/big" + "time" "github.com/ethereum/go-ethereum/common" @@ -18,46 +17,50 @@ type ORM interface { ChannelDefinitionCacheORM } +type PersistedDefinitions struct { + ChainSelector uint64 `db:"chain_selector"` + Address common.Address `db:"addr"` + Definitions llotypes.ChannelDefinitions `db:"definitions"` + // The block number in which the log for this definitions was emitted + BlockNum int64 `db:"block_num"` + DonID uint32 `db:"don_id"` + Version uint32 `db:"version"` + UpdatedAt time.Time `db:"updated_at"` +} + var _ ORM = &orm{} type orm struct { - ds sqlutil.DataSource - evmChainID *big.Int + ds sqlutil.DataSource + chainSelector uint64 } -func NewORM(ds sqlutil.DataSource, evmChainID *big.Int) ORM { - return &orm{ds, evmChainID} +func NewORM(ds sqlutil.DataSource, chainSelector uint64) ORM { + return &orm{ds, chainSelector} } -func (o *orm) LoadChannelDefinitions(ctx context.Context, addr common.Address) (dfns llotypes.ChannelDefinitions, blockNum int64, err error) { - type scd struct { - Definitions []byte `db:"definitions"` - BlockNum int64 `db:"block_num"` - } - var scanned scd - err = o.ds.GetContext(ctx, &scanned, "SELECT definitions, block_num FROM channel_definitions WHERE evm_chain_id = $1 AND addr = $2", o.evmChainID.String(), addr) +func (o *orm) LoadChannelDefinitions(ctx context.Context, addr common.Address, donID uint32) (pd *PersistedDefinitions, err error) { + pd = new(PersistedDefinitions) + err = o.ds.GetContext(ctx, pd, "SELECT * FROM channel_definitions WHERE chain_selector = $1 AND addr = $2 AND don_id = $3", o.chainSelector, addr, donID) if errors.Is(err, sql.ErrNoRows) { - return dfns, blockNum, nil + return nil, nil } else if err != nil { - return nil, 0, fmt.Errorf("failed to LoadChannelDefinitions; %w", err) - } - - if err = json.Unmarshal(scanned.Definitions, &dfns); err != nil { - return nil, 0, fmt.Errorf("failed to LoadChannelDefinitions; JSON Unmarshal failure; %w", err) + return nil, fmt.Errorf("failed to LoadChannelDefinitions; %w", err) } - return dfns, scanned.BlockNum, nil + return pd, nil } -// TODO: Test this method -// https://smartcontract-it.atlassian.net/jira/software/c/projects/MERC/issues/MERC-3653 -func (o *orm) StoreChannelDefinitions(ctx context.Context, addr common.Address, dfns llotypes.ChannelDefinitions, blockNum int64) error { +// StoreChannelDefinitions will store a ChannelDefinitions list for a given chain_selector, addr, don_id +// It only updates if the new version is greater than the existing record +func (o *orm) StoreChannelDefinitions(ctx context.Context, addr common.Address, donID, version uint32, dfns llotypes.ChannelDefinitions, blockNum int64) error { _, err := o.ds.ExecContext(ctx, ` -INSERT INTO channel_definitions (evm_chain_id, addr, definitions, block_num, updated_at) -VALUES ($1, $2, $3, $4, NOW()) -ON CONFLICT (evm_chain_id, addr) DO UPDATE -SET definitions = $3, block_num = $4, updated_at = NOW() -`, o.evmChainID.String(), addr, dfns, blockNum) +INSERT INTO channel_definitions (chain_selector, addr, don_id, definitions, block_num, version, updated_at) +VALUES ($1, $2, $3, $4, $5, $6, NOW()) +ON CONFLICT (chain_selector, addr, don_id) DO UPDATE +SET definitions = $4, block_num = $5, version = $6, updated_at = NOW() +WHERE EXCLUDED.version > channel_definitions.version +`, o.chainSelector, addr, donID, dfns, blockNum, version) if err != nil { return fmt.Errorf("StoreChannelDefinitions failed: %w", err) } diff --git a/core/services/llo/orm_test.go b/core/services/llo/orm_test.go index bc2d88130e..ec3c06e6e6 100644 --- a/core/services/llo/orm_test.go +++ b/core/services/llo/orm_test.go @@ -1,91 +1,156 @@ package llo import ( + "fmt" + "math/rand" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" ) func Test_ORM(t *testing.T) { - t.Skip("waiting on https://github.com/smartcontractkit/chainlink/pull/13780") - // db := pgtest.NewSqlxDB(t) - // orm := NewORM(db, testutils.FixtureChainID) - // ctx := testutils.Context(t) - - // addr1 := testutils.NewAddress() - // addr2 := testutils.NewAddress() - // addr3 := testutils.NewAddress() - - // t.Run("LoadChannelDefinitions", func(t *testing.T) { - // t.Run("returns zero values if nothing in database", func(t *testing.T) { - // cd, blockNum, err := orm.LoadChannelDefinitions(ctx, addr1) - // require.NoError(t, err) - - // assert.Zero(t, cd) - // assert.Zero(t, blockNum) - // }) - // t.Run("loads channel definitions from database", func(t *testing.T) { - // expectedBlockNum := rand.Int63() - // expectedBlockNum2 := rand.Int63() - // cid1 := rand.Uint32() - // cid2 := rand.Uint32() - - // channelDefsJSON := fmt.Sprintf(` - // { - // "%d": { - // "reportFormat": 42, - // "chainSelector": 142, - // "streamIds": [1, 2] - // }, - // "%d": { - // "reportFormat": 42, - // "chainSelector": 142, - // "streamIds": [1, 3] - // } - // } - // `, cid1, cid2) - // pgtest.MustExec(t, db, ` - // INSERT INTO channel_definitions(addr, evm_chain_id, definitions, block_num, updated_at) - // VALUES ( $1, $2, $3, $4, NOW()) - // `, addr1, testutils.FixtureChainID.String(), channelDefsJSON, expectedBlockNum) - - // pgtest.MustExec(t, db, ` - // INSERT INTO channel_definitions(addr, evm_chain_id, definitions, block_num, updated_at) - // VALUES ( $1, $2, $3, $4, NOW()) - // `, addr2, testutils.FixtureChainID.String(), `{}`, expectedBlockNum2) - - // { - // // alternative chain ID; we expect these ones to be ignored - // pgtest.MustExec(t, db, ` - // INSERT INTO channel_definitions(addr, evm_chain_id, definitions, block_num, updated_at) - // VALUES ( $1, $2, $3, $4, NOW()) - // `, addr1, testutils.SimulatedChainID.String(), channelDefsJSON, expectedBlockNum) - // pgtest.MustExec(t, db, ` - // INSERT INTO channel_definitions(addr, evm_chain_id, definitions, block_num, updated_at) - // VALUES ( $1, $2, $3, $4, NOW()) - // `, addr3, testutils.SimulatedChainID.String(), channelDefsJSON, expectedBlockNum) - // } - - // cd, blockNum, err := orm.LoadChannelDefinitions(ctx, addr1) - // require.NoError(t, err) - - // assert.Equal(t, llotypes.ChannelDefinitions{ - // cid1: llotypes.ChannelDefinition{ - // ReportFormat: 42, - // ChainSelector: 142, - // StreamIDs: []llotypes.StreamID{1, 2}, - // }, - // cid2: llotypes.ChannelDefinition{ - // ReportFormat: 42, - // ChainSelector: 142, - // StreamIDs: []llotypes.StreamID{1, 3}, - // }, - // }, cd) - // assert.Equal(t, expectedBlockNum, blockNum) - - // cd, blockNum, err = orm.LoadChannelDefinitions(ctx, addr2) - // require.NoError(t, err) - - // assert.Equal(t, llotypes.ChannelDefinitions{}, cd) - // assert.Equal(t, expectedBlockNum2, blockNum) - // }) - // }) + const ETHMainnetChainSelector uint64 = 5009297550715157269 + const OtherChainSelector uint64 = 1234567890 + + db := pgtest.NewSqlxDB(t) + orm := NewORM(db, ETHMainnetChainSelector) + ctx := testutils.Context(t) + + addr1 := testutils.NewAddress() + addr2 := testutils.NewAddress() + addr3 := testutils.NewAddress() + + donID1 := uint32(1) + donID2 := uint32(2) + + t.Run("LoadChannelDefinitions", func(t *testing.T) { + t.Run("returns zero values if nothing in database", func(t *testing.T) { + pd, err := orm.LoadChannelDefinitions(ctx, addr1, donID1) + assert.NoError(t, err) + assert.Nil(t, pd) + }) + t.Run("loads channel definitions from database for the given don ID", func(t *testing.T) { + expectedBlockNum := rand.Int63() + expectedBlockNum2 := rand.Int63() + cid1 := rand.Uint32() + cid2 := rand.Uint32() + + channelDefsJSON := fmt.Sprintf(` +{ + "%d": { + "reportFormat": 42, + "chainSelector": 142, + "streams": [{"streamId": 1, "aggregator": "median"}, {"streamId": 2, "aggregator": "mode"}], + "opts": {"foo":"bar"} + }, + "%d": { + "reportFormat": 43, + "chainSelector": 142, + "streams": [{"streamId": 1, "aggregator": "median"}, {"streamId": 3, "aggregator": "quote"}] + } +} + `, cid1, cid2) + pgtest.MustExec(t, db, ` + INSERT INTO channel_definitions(addr, chain_selector, don_id, definitions, block_num, version, updated_at) + VALUES ($1, $2, $3, $4, $5, $6, NOW()) + `, addr1, ETHMainnetChainSelector, 1, channelDefsJSON, expectedBlockNum, 1) + + pgtest.MustExec(t, db, ` + INSERT INTO channel_definitions(addr, chain_selector, don_id, definitions, block_num, version, updated_at) + VALUES ($1, $2, $3, $4, $5, $6, NOW()) + `, addr2, ETHMainnetChainSelector, 1, `{}`, expectedBlockNum2, 1) + + { + // alternative chain selector; we expect these ones to be ignored + pgtest.MustExec(t, db, ` + INSERT INTO channel_definitions(addr, chain_selector, don_id, definitions, block_num, version, updated_at) + VALUES ($1, $2, $3, $4, $5, $6, NOW()) + `, addr1, OtherChainSelector, 1, channelDefsJSON, expectedBlockNum, 1) + pgtest.MustExec(t, db, ` + INSERT INTO channel_definitions(addr, chain_selector, don_id, definitions, block_num, version, updated_at) + VALUES ($1, $2, $3, $4, $5, $6, NOW()) + `, addr3, OtherChainSelector, 1, channelDefsJSON, expectedBlockNum, 1) + } + + pd, err := orm.LoadChannelDefinitions(ctx, addr1, donID1) + require.NoError(t, err) + + assert.Equal(t, ETHMainnetChainSelector, pd.ChainSelector) + assert.Equal(t, addr1, pd.Address) + assert.Equal(t, expectedBlockNum, pd.BlockNum) + assert.Equal(t, donID1, pd.DonID) + assert.Equal(t, uint32(1), pd.Version) + assert.Equal(t, llotypes.ChannelDefinitions{ + cid1: llotypes.ChannelDefinition{ + ReportFormat: 42, + Streams: []llotypes.Stream{{StreamID: 1, Aggregator: llotypes.AggregatorMedian}, {StreamID: 2, Aggregator: llotypes.AggregatorMode}}, + Opts: []byte(`{"foo":"bar"}`), + }, + cid2: llotypes.ChannelDefinition{ + ReportFormat: 43, + Streams: []llotypes.Stream{{StreamID: 1, Aggregator: llotypes.AggregatorMedian}, {StreamID: 3, Aggregator: llotypes.AggregatorQuote}}, + }, + }, pd.Definitions) + + // does not load erroneously for a different address + pd, err = orm.LoadChannelDefinitions(ctx, addr2, donID1) + require.NoError(t, err) + + assert.Equal(t, llotypes.ChannelDefinitions{}, pd.Definitions) + assert.Equal(t, expectedBlockNum2, pd.BlockNum) + + // does not load erroneously for a different don ID + pd, err = orm.LoadChannelDefinitions(ctx, addr1, donID2) + require.NoError(t, err) + + assert.Equal(t, (*PersistedDefinitions)(nil), pd) + }) + }) + + t.Run("StoreChannelDefinitions", func(t *testing.T) { + expectedBlockNum := rand.Int63() + cid1 := rand.Uint32() + cid2 := rand.Uint32() + defs := llotypes.ChannelDefinitions{ + cid1: llotypes.ChannelDefinition{ + ReportFormat: llotypes.ReportFormatJSON, + Streams: []llotypes.Stream{{StreamID: 1, Aggregator: llotypes.AggregatorMedian}, {StreamID: 2, Aggregator: llotypes.AggregatorMode}}, + Opts: []byte(`{"foo":"bar"}`), + }, + cid2: llotypes.ChannelDefinition{ + ReportFormat: llotypes.ReportFormatEVMPremiumLegacy, + Streams: []llotypes.Stream{{StreamID: 1, Aggregator: llotypes.AggregatorMedian}, {StreamID: 3, Aggregator: llotypes.AggregatorQuote}}, + }, + } + + t.Run("stores channel definitions in the database", func(t *testing.T) { + err := orm.StoreChannelDefinitions(ctx, addr1, donID1, 42, defs, expectedBlockNum) + require.NoError(t, err) + + pd, err := orm.LoadChannelDefinitions(ctx, addr1, donID1) + require.NoError(t, err) + assert.Equal(t, ETHMainnetChainSelector, pd.ChainSelector) + assert.Equal(t, addr1, pd.Address) + assert.Equal(t, expectedBlockNum, pd.BlockNum) + assert.Equal(t, donID1, pd.DonID) + assert.Equal(t, uint32(42), pd.Version) + assert.Equal(t, defs, pd.Definitions) + }) + t.Run("does not update if version is older than the database persisted version", func(t *testing.T) { + // try to update with an older version + err := orm.StoreChannelDefinitions(ctx, addr1, donID1, 41, llotypes.ChannelDefinitions{}, expectedBlockNum) + require.NoError(t, err) + + pd, err := orm.LoadChannelDefinitions(ctx, addr1, donID1) + require.NoError(t, err) + assert.Equal(t, uint32(42), pd.Version) + assert.Equal(t, defs, pd.Definitions) + }) + }) } diff --git a/core/services/llo/transmitter.go b/core/services/llo/transmitter.go index f876128481..fe6f26c317 100644 --- a/core/services/llo/transmitter.go +++ b/core/services/llo/transmitter.go @@ -3,10 +3,8 @@ package llo import ( "context" "crypto/ed25519" - "errors" "fmt" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" @@ -15,7 +13,9 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/services" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" ) // LLO Transmitter implementation, based on @@ -34,25 +34,6 @@ const ( // transmitTimeout = 5 * time.Second ) -var PayloadTypes = getPayloadTypes() - -func getPayloadTypes() abi.Arguments { - mustNewType := func(t string) abi.Type { - result, err := abi.NewType(t, "", []abi.ArgumentMarshaling{}) - if err != nil { - panic(fmt.Sprintf("Unexpected error during abi.NewType: %s", err)) - } - return result - } - return abi.Arguments([]abi.Argument{ - {Name: "reportContext", Type: mustNewType("bytes32[2]")}, - {Name: "report", Type: mustNewType("bytes")}, - {Name: "rawRs", Type: mustNewType("bytes32[]")}, - {Name: "rawSs", Type: mustNewType("bytes32[]")}, - {Name: "rawVs", Type: mustNewType("bytes32")}, - }) -} - type Transmitter interface { llotypes.Transmitter services.Service @@ -97,7 +78,32 @@ func (t *transmitter) Transmit( report ocr3types.ReportWithInfo[llotypes.ReportInfo], sigs []types.AttributedOnchainSignature, ) (err error) { - return errors.New("not implemented") + var payload []byte + + switch report.Info.ReportFormat { + case llotypes.ReportFormatJSON: + // TODO: exactly how to handle JSON here? + // https://smartcontract-it.atlassian.net/browse/MERC-3659 + fallthrough + case llotypes.ReportFormatEVMPremiumLegacy: + payload, err = evm.ReportCodecPremiumLegacy{}.Pack(digest, seqNr, report.Report, sigs) + default: + return fmt.Errorf("Transmit failed; unsupported report format: %q", report.Info.ReportFormat) + } + + if err != nil { + return fmt.Errorf("Transmit: encode failed; %w", err) + } + + req := &pb.TransmitRequest{ + Payload: payload, + ReportFormat: uint32(report.Info.ReportFormat), + } + + // TODO: persistenceManager and queueing, error handling, retry etc + // https://smartcontract-it.atlassian.net/browse/MERC-3659 + _, err = t.rpcClient.Transmit(ctx, req) + return err } // FromAccount returns the stringified (hex) CSA public key diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index f53ceaefa1..52dbbf87b5 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -49,7 +49,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" "github.com/smartcontractkit/chainlink/v2/core/services/llo" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/ccipcommit" @@ -953,6 +952,7 @@ func (d *Delegate) newServicesLLO( return nil, err } + // Handle key bundle IDs explicitly specified in job spec kbm := make(map[llotypes.ReportFormat]llo.Key) for rfStr, kbid := range pluginCfg.KeyBundleIDs { k, err3 := d.ks.Get(kbid) @@ -965,26 +965,19 @@ func (d *Delegate) newServicesLLO( } kbm[rf] = k } - // NOTE: This is a bit messy because we assume chain type matches report - // format, and it may not in all cases. We don't yet know what report - // formats we need or how they correspond to chain types, so assume it's - // 1:1 for now but will change in future - // + + // Use the default key bundle if not specified + // NOTE: Only JSON and EVMPremiumLegacy supported for now // https://smartcontract-it.atlassian.net/browse/MERC-3722 - for _, s := range chaintype.SupportedChainTypes { - rf, err3 := llotypes.ReportFormatFromString(string(s)) - if err3 != nil { - return nil, fmt.Errorf("job %d (%s) has a chain type with no matching report format %s: %w", jb.ID, jb.Name.ValueOrZero(), s, err3) - } + for _, rf := range []llotypes.ReportFormat{llotypes.ReportFormatJSON, llotypes.ReportFormatEVMPremiumLegacy} { if _, exists := kbm[rf]; !exists { // Use the first if unspecified - kbs, err4 := d.ks.GetAllOfType(s) - if err4 != nil { - return nil, err4 + kbs, err3 := d.ks.GetAllOfType("evm") + if err3 != nil { + return nil, err3 } if len(kbs) == 0 { - // unsupported key type - continue + return nil, fmt.Errorf("no on-chain signing keys found for report format %s", "evm") } else if len(kbs) > 1 { lggr.Debugf("Multiple on-chain signing keys found for report format %s, using the first", rf.String()) } diff --git a/core/services/ocr2/plugins/llo/config/config.go b/core/services/ocr2/plugins/llo/config/config.go index 892229c46c..2460fecd72 100644 --- a/core/services/ocr2/plugins/llo/config/config.go +++ b/core/services/ocr2/plugins/llo/config/config.go @@ -39,6 +39,8 @@ type PluginConfig struct { // KeyBundleIDs maps supported keys to their respective bundle IDs // Key must match llo's ReportFormat KeyBundleIDs map[string]string `json:"keyBundleIDs" toml:"keyBundleIDs"` + + DonID uint32 `json:"donID" toml:"donID"` } func (p *PluginConfig) Unmarshal(data []byte) error { @@ -46,8 +48,12 @@ func (p *PluginConfig) Unmarshal(data []byte) error { } func (p PluginConfig) Validate() (merr error) { + if p.DonID == 0 { + merr = errors.Join(merr, errors.New("llo: DonID must be specified and not zero")) + } + if p.RawServerURL == "" { - merr = errors.New("llo: ServerURL must be specified") + merr = errors.Join(merr, errors.New("llo: ServerURL must be specified")) } else { var normalizedURI string if schemeRegexp.MatchString(p.RawServerURL) { @@ -57,9 +63,9 @@ func (p PluginConfig) Validate() (merr error) { } uri, err := url.ParseRequestURI(normalizedURI) if err != nil { - merr = fmt.Errorf("llo: invalid value for ServerURL: %w", err) + merr = errors.Join(merr, fmt.Errorf("llo: invalid value for ServerURL: %w", err)) } else if uri.Scheme != "wss" { - merr = fmt.Errorf(`llo: invalid scheme specified for MercuryServer, got: %q (scheme: %q) but expected a websocket url e.g. "192.0.2.2:4242" or "wss://192.0.2.2:4242"`, p.RawServerURL, uri.Scheme) + merr = errors.Join(merr, fmt.Errorf(`llo: invalid scheme specified for MercuryServer, got: %q (scheme: %q) but expected a websocket url e.g. "192.0.2.2:4242" or "wss://192.0.2.2:4242"`, p.RawServerURL, uri.Scheme)) } } @@ -74,6 +80,8 @@ func (p PluginConfig) Validate() (merr error) { if err := json.Unmarshal([]byte(p.ChannelDefinitions), &cd); err != nil { merr = errors.Join(merr, fmt.Errorf("channelDefinitions is invalid JSON: %w", err)) } + // TODO: Verify Opts format here? + // MERC-3524 } else { if p.ChannelDefinitionsContractAddress == (common.Address{}) { merr = errors.Join(merr, errors.New("llo: ChannelDefinitionsContractAddress is required if ChannelDefinitions is not specified")) diff --git a/core/services/ocr2/plugins/llo/config/config_test.go b/core/services/ocr2/plugins/llo/config/config_test.go index 136fac87a5..5152dc839b 100644 --- a/core/services/ocr2/plugins/llo/config/config_test.go +++ b/core/services/ocr2/plugins/llo/config/config_test.go @@ -62,6 +62,7 @@ func Test_Config(t *testing.T) { rawToml := fmt.Sprintf(` ServerURL = "example.com:80" ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" + DonID = 12345 ChannelDefinitions = """ %s """`, cdjson) @@ -73,6 +74,7 @@ func Test_Config(t *testing.T) { assert.Equal(t, "example.com:80", mc.RawServerURL) assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) assert.JSONEq(t, cdjson, mc.ChannelDefinitions) + assert.Equal(t, uint32(12345), mc.DonID) assert.False(t, mc.BenchmarkMode) err = mc.Validate() @@ -80,6 +82,7 @@ func Test_Config(t *testing.T) { }) t.Run("with only channelDefinitions contract details", func(t *testing.T) { rawToml := ` + DonID = 12345 ServerURL = "example.com:80" ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" ChannelDefinitionsContractAddress = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"` @@ -91,6 +94,7 @@ func Test_Config(t *testing.T) { assert.Equal(t, "example.com:80", mc.RawServerURL) assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) assert.Equal(t, "0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF", mc.ChannelDefinitionsContractAddress.Hex()) + assert.Equal(t, uint32(12345), mc.DonID) assert.False(t, mc.BenchmarkMode) err = mc.Validate() @@ -99,7 +103,9 @@ func Test_Config(t *testing.T) { t.Run("with missing ChannelDefinitionsContractAddress", func(t *testing.T) { rawToml := ` ServerURL = "example.com:80" - ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93"` + ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" + DonID = 12345 + ` var mc PluginConfig err := toml.Unmarshal([]byte(rawToml), &mc) @@ -107,6 +113,7 @@ func Test_Config(t *testing.T) { assert.Equal(t, "example.com:80", mc.RawServerURL) assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) + assert.Equal(t, uint32(12345), mc.DonID) assert.False(t, mc.BenchmarkMode) err = mc.Validate() diff --git a/core/services/ocr2/plugins/llo/helpers_test.go b/core/services/ocr2/plugins/llo/helpers_test.go new file mode 100644 index 0000000000..1d85a6f0ec --- /dev/null +++ b/core/services/ocr2/plugins/llo/helpers_test.go @@ -0,0 +1,532 @@ +package llo_test + +import ( + "context" + "crypto/ed25519" + "errors" + "fmt" + "io" + "math/big" + "net" + "net/http" + "net/http/httptest" + "net/url" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/shopspring/decimal" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" + + "github.com/smartcontractkit/wsrpc" + "github.com/smartcontractkit/wsrpc/credentials" + "github.com/smartcontractkit/wsrpc/peer" + + "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + + "github.com/smartcontractkit/chainlink/v2/core/bridges" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/destination_verifier" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/destination_verifier_proxy" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/keystest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" + "github.com/smartcontractkit/chainlink/v2/core/services/streams" + "github.com/smartcontractkit/chainlink/v2/core/store/models" +) + +var _ pb.MercuryServer = &mercuryServer{} + +type request struct { + pk credentials.StaticSizedPublicKey + req *pb.TransmitRequest +} + +func (r request) TransmitterID() ocr2types.Account { + return ocr2types.Account(fmt.Sprintf("%x", r.pk)) +} + +type mercuryServer struct { + privKey ed25519.PrivateKey + reqsCh chan request + t *testing.T + buildReport func() []byte +} + +func NewMercuryServer(t *testing.T, privKey ed25519.PrivateKey, reqsCh chan request, buildReport func() []byte) *mercuryServer { + return &mercuryServer{privKey, reqsCh, t, buildReport} +} + +func (s *mercuryServer) Transmit(ctx context.Context, req *pb.TransmitRequest) (*pb.TransmitResponse, error) { + p, ok := peer.FromContext(ctx) + if !ok { + return nil, errors.New("could not extract public key") + } + r := request{p.PublicKey, req} + s.reqsCh <- r + + return &pb.TransmitResponse{ + Code: 1, + Error: "", + }, nil +} + +func (s *mercuryServer) LatestReport(ctx context.Context, lrr *pb.LatestReportRequest) (*pb.LatestReportResponse, error) { + p, ok := peer.FromContext(ctx) + if !ok { + return nil, errors.New("could not extract public key") + } + s.t.Logf("mercury server got latest report from %x for feed id 0x%x", p.PublicKey, lrr.FeedId) + + out := new(pb.LatestReportResponse) + out.Report = new(pb.Report) + out.Report.FeedId = lrr.FeedId + + report := s.buildReport() + payload, err := mercury.PayloadTypes.Pack(evmutil.RawReportContext(ocrtypes.ReportContext{}), report, [][32]byte{}, [][32]byte{}, [32]byte{}) + if err != nil { + require.NoError(s.t, err) + } + out.Report.Payload = payload + return out, nil +} + +func startMercuryServer(t *testing.T, srv *mercuryServer, pubKeys []ed25519.PublicKey) (serverURL string) { + // Set up the wsrpc server + lis, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("[MAIN] failed to listen: %v", err) + } + serverURL = lis.Addr().String() + s := wsrpc.NewServer(wsrpc.Creds(srv.privKey, pubKeys)) + + // Register mercury implementation with the wsrpc server + pb.RegisterMercuryServer(s, srv) + + // Start serving + go s.Serve(lis) + t.Cleanup(s.Stop) + + return +} + +type Node struct { + App chainlink.Application + ClientPubKey credentials.StaticSizedPublicKey + KeyBundle ocr2key.KeyBundle + ObservedLogs *observer.ObservedLogs +} + +func (node *Node) AddStreamJob(t *testing.T, spec string) (id int32) { + job, err := streams.ValidatedStreamSpec(spec) + require.NoError(t, err) + err = node.App.AddJobV2(testutils.Context(t), &job) + require.NoError(t, err) + return job.ID +} + +func (node *Node) DeleteJob(t *testing.T, id int32) { + err := node.App.DeleteJob(testutils.Context(t), id) + require.NoError(t, err) +} + +func (node *Node) AddLLOJob(t *testing.T, spec string) { + c := node.App.GetConfig() + job, err := validate.ValidatedOracleSpecToml(testutils.Context(t), c.OCR2(), c.Insecure(), spec, nil) + require.NoError(t, err) + err = node.App.AddJobV2(testutils.Context(t), &job) + require.NoError(t, err) +} + +func (node *Node) AddBootstrapJob(t *testing.T, spec string) { + job, err := ocrbootstrap.ValidatedBootstrapSpecToml(spec) + require.NoError(t, err) + err = node.App.AddJobV2(testutils.Context(t), &job) + require.NoError(t, err) +} + +func setupNode( + t *testing.T, + port int, + dbName string, + backend *backends.SimulatedBackend, + csaKey csakey.KeyV2, +) (app chainlink.Application, peerID string, clientPubKey credentials.StaticSizedPublicKey, ocr2kb ocr2key.KeyBundle, observedLogs *observer.ObservedLogs) { + k := big.NewInt(int64(port)) // keys unique to port + p2pKey := p2pkey.MustNewV2XXXTestingOnly(k) + rdr := keystest.NewRandReaderFromSeed(int64(port)) + ocr2kb = ocr2key.MustNewInsecure(rdr, chaintype.EVM) + + p2paddresses := []string{fmt.Sprintf("127.0.0.1:%d", port)} + + config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { + // [JobPipeline] + c.JobPipeline.MaxSuccessfulRuns = ptr(uint64(0)) + + // [Feature] + c.Feature.UICSAKeys = ptr(true) + c.Feature.LogPoller = ptr(true) + c.Feature.FeedsManager = ptr(false) + + // [OCR] + c.OCR.Enabled = ptr(false) + + // [OCR2] + c.OCR2.Enabled = ptr(true) + c.OCR2.ContractPollInterval = commonconfig.MustNewDuration(1 * time.Second) + + // [P2P] + c.P2P.PeerID = ptr(p2pKey.PeerID()) + c.P2P.TraceLogging = ptr(true) + + // [P2P.V2] + c.P2P.V2.Enabled = ptr(true) + c.P2P.V2.AnnounceAddresses = &p2paddresses + c.P2P.V2.ListenAddresses = &p2paddresses + c.P2P.V2.DeltaDial = commonconfig.MustNewDuration(500 * time.Millisecond) + c.P2P.V2.DeltaReconcile = commonconfig.MustNewDuration(5 * time.Second) + }) + + lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.DebugLevel) + if backend != nil { + app = cltest.NewApplicationWithConfigV2OnSimulatedBlockchain(t, config, backend, p2pKey, ocr2kb, csaKey, lggr.Named(dbName)) + } else { + app = cltest.NewApplicationWithConfig(t, config, p2pKey, ocr2kb, csaKey, lggr.Named(dbName)) + } + err := app.Start(testutils.Context(t)) + require.NoError(t, err) + + t.Cleanup(func() { + assert.NoError(t, app.Stop()) + }) + + return app, p2pKey.PeerID().Raw(), csaKey.StaticSizedPublicKey(), ocr2kb, observedLogs +} + +func ptr[T any](t T) *T { return &t } + +func addSingleDecimalStreamJob( + t *testing.T, + node Node, + streamID uint32, + bridgeName string, +) (id int32) { + return node.AddStreamJob(t, fmt.Sprintf(` +type = "stream" +schemaVersion = 1 +name = "strm-spec-%d" +streamID = %d +observationSource = """ + // Benchmark Price + price1 [type=bridge name="%s" requestData="{\\"data\\":{\\"data\\":\\"foo\\"}}"]; + price1_parse [type=jsonparse path="result"]; + + price1 -> price1_parse; +""" + + `, + streamID, + streamID, + bridgeName, + )) +} + +func addQuoteStreamJob( + t *testing.T, + node Node, + streamID uint32, + benchmarkBridgeName string, + bidBridgeName string, + askBridgeName string, +) (id int32) { + return node.AddStreamJob(t, fmt.Sprintf(` +type = "stream" +schemaVersion = 1 +name = "strm-spec-%d" +streamID = %d +observationSource = """ + // Benchmark Price + price1 [type=bridge name="%s" requestData="{\\"data\\":{\\"data\\":\\"foo\\"}}"]; + price1_parse [type=jsonparse path="result" index=0]; + + price1 -> price1_parse; + + // Bid + price2 [type=bridge name="%s" requestData="{\\"data\\":{\\"data\\":\\"foo\\"}}"]; + price2_parse [type=jsonparse path="result" index=1]; + + price2 -> price2_parse; + + // Ask + price3 [type=bridge name="%s" requestData="{\\"data\\":{\\"data\\":\\"foo\\"}}"]; + price3_parse [type=jsonparse path="result" index=2]; + + price3 -> price3_parse; +""" + + `, + streamID, + streamID, + benchmarkBridgeName, + bidBridgeName, + askBridgeName, + )) +} +func addBootstrapJob(t *testing.T, bootstrapNode Node, verifierAddress common.Address, name string, relayType, relayConfig string) { + bootstrapNode.AddBootstrapJob(t, fmt.Sprintf(` +type = "bootstrap" +relay = "%s" +schemaVersion = 1 +name = "boot-%s" +contractID = "%s" +contractConfigTrackerPollInterval = "1s" + +[relayConfig] +%s +providerType = "llo"`, relayType, name, verifierAddress.Hex(), relayConfig)) +} + +func addLLOJob( + t *testing.T, + node Node, + verifierAddress common.Address, + bootstrapPeerID string, + bootstrapNodePort int, + clientPubKey ed25519.PublicKey, + jobName string, + pluginConfig, + relayType, + relayConfig string, +) { + node.AddLLOJob(t, fmt.Sprintf(` +type = "offchainreporting2" +schemaVersion = 1 +name = "%s" +forwardingAllowed = false +maxTaskDuration = "1s" +contractID = "%s" +contractConfigTrackerPollInterval = "1s" +ocrKeyBundleID = "%s" +p2pv2Bootstrappers = [ + "%s" +] +relay = "%s" +pluginType = "llo" +transmitterID = "%x" + +[pluginConfig] +%s + +[relayConfig] +%s`, + jobName, + verifierAddress.Hex(), + node.KeyBundle.ID(), + fmt.Sprintf("%s@127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), + relayType, + clientPubKey, + pluginConfig, + relayConfig, + )) +} + +func addOCRJobs( + t *testing.T, + streams []Stream, + serverPubKey ed25519.PublicKey, + serverURL string, + verifierAddress common.Address, + bootstrapPeerID string, + bootstrapNodePort int, + nodes []Node, + configStoreAddress common.Address, + clientPubKeys []ed25519.PublicKey, + pluginConfig, + relayType, + relayConfig string) (streamJobIDs []int32) { + + // Add OCR jobs - one per feed on each node + for i, node := range nodes { + for j, strm := range streams { + bmBridge := createBridge(t, fmt.Sprintf("benchmarkprice-%d-%d", strm.id, j), i, strm.baseBenchmarkPrice, node.App.BridgeORM()) + jobID := addSingleDecimalStreamJob( + t, + node, + strm.id, + bmBridge, + ) + streamJobIDs = append(streamJobIDs, jobID) + } + addLLOJob( + t, + node, + verifierAddress, + bootstrapPeerID, + bootstrapNodePort, + clientPubKeys[i], + "feed-1", + pluginConfig, + relayType, + relayConfig, + ) + } + return streamJobIDs +} + +func createBridge(t *testing.T, name string, i int, p decimal.Decimal, borm bridges.ORM) (bridgeName string) { + ctx := testutils.Context(t) + bridge := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + b, err := io.ReadAll(req.Body) + require.NoError(t, err) + require.Equal(t, `{"data":{"data":"foo"}}`, string(b)) + + res.WriteHeader(http.StatusOK) + val := p.String() + resp := fmt.Sprintf(`{"result": %s}`, val) + _, err = res.Write([]byte(resp)) + require.NoError(t, err) + })) + t.Cleanup(bridge.Close) + u, _ := url.Parse(bridge.URL) + bridgeName = fmt.Sprintf("bridge-%s-%d", name, i) + require.NoError(t, borm.CreateBridgeType(ctx, &bridges.BridgeType{ + Name: bridges.BridgeName(bridgeName), + URL: models.WebURL(*u), + })) + + return bridgeName +} + +func createErroringBridge(t *testing.T, name string, i int, borm bridges.ORM) (bridgeName string) { + ctx := testutils.Context(t) + bridge := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + res.WriteHeader(http.StatusInternalServerError) + })) + t.Cleanup(bridge.Close) + u, _ := url.Parse(bridge.URL) + bridgeName = fmt.Sprintf("bridge-%s-%d", name, i) + require.NoError(t, borm.CreateBridgeType(ctx, &bridges.BridgeType{ + Name: bridges.BridgeName(bridgeName), + URL: models.WebURL(*u), + })) + + return bridgeName +} + +func addOCRJobsEVMPremiumLegacy( + t *testing.T, + streams []Stream, + serverPubKey ed25519.PublicKey, + serverURL string, + verifierAddress common.Address, + bootstrapPeerID string, + bootstrapNodePort int, + nodes []Node, + configStoreAddress common.Address, + clientPubKeys []ed25519.PublicKey, + pluginConfig, + relayType, + relayConfig string) (jobIDs map[int]map[uint32]int32) { + // node idx => stream id => job id + jobIDs = make(map[int]map[uint32]int32) + // Add OCR jobs - one per feed on each node + for i, node := range nodes { + if jobIDs[i] == nil { + jobIDs[i] = make(map[uint32]int32) + } + for j, strm := range streams { + // assume that streams are native, link and quote + if j < 2 { + var name string + if j == 0 { + name = "nativeprice" + } else { + name = "linkprice" + } + name = fmt.Sprintf("%s-%d-%d", name, strm.id, j) + bmBridge := createBridge(t, name, i, strm.baseBenchmarkPrice, node.App.BridgeORM()) + jobID := addSingleDecimalStreamJob( + t, + node, + strm.id, + bmBridge, + ) + jobIDs[i][strm.id] = jobID + } else if j == 2 { + bmBridge := createBridge(t, fmt.Sprintf("benchmarkprice-%d-%d", strm.id, j), i, strm.baseBenchmarkPrice, node.App.BridgeORM()) + bidBridge := createBridge(t, fmt.Sprintf("bid-%d-%d", strm.id, j), i, strm.baseBid, node.App.BridgeORM()) + askBridge := createBridge(t, fmt.Sprintf("ask-%d-%d", strm.id, j), i, strm.baseAsk, node.App.BridgeORM()) + jobID := addQuoteStreamJob( + t, + node, + strm.id, + bmBridge, + bidBridge, + askBridge, + ) + jobIDs[i][strm.id] = jobID + } else { + panic("unexpected stream") + } + } + addLLOJob( + t, + node, + verifierAddress, + bootstrapPeerID, + bootstrapNodePort, + clientPubKeys[i], + "feed-1", + pluginConfig, + relayType, + relayConfig, + ) + } + return jobIDs +} + +func setupV03Blockchain(t *testing.T) (*bind.TransactOpts, *backends.SimulatedBackend, *destination_verifier.DestinationVerifier, *destination_verifier_proxy.DestinationVerifierProxy, common.Address) { + steve := testutils.MustNewSimTransactor(t) // config contract deployer and owner + genesisData := core.GenesisAlloc{steve.From: {Balance: assets.Ether(1000).ToInt()}} + backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) + backend.Commit() // ensure starting block number at least 1 + + // Deploy verifier proxy + verifierProxyAddr, _, verifierProxy, err := destination_verifier_proxy.DeployDestinationVerifierProxy(steve, backend) + require.NoError(t, err) + backend.Commit() + + // Deploy verifier + verifierAddress, _, verifier, err := destination_verifier.DeployDestinationVerifier(steve, backend, verifierProxyAddr) + require.NoError(t, err) + backend.Commit() + + // Set verifier on proxy + _, err = verifierProxy.SetVerifier(steve, verifierAddress) + require.NoError(t, err) + backend.Commit() + + return steve, backend, verifier, verifierProxy, verifierProxyAddr +} diff --git a/core/services/ocr2/plugins/llo/integration_test.go b/core/services/ocr2/plugins/llo/integration_test.go new file mode 100644 index 0000000000..787946b6ad --- /dev/null +++ b/core/services/ocr2/plugins/llo/integration_test.go @@ -0,0 +1,463 @@ +package llo_test + +import ( + "crypto/ed25519" + "encoding/hex" + "encoding/json" + "fmt" + "math/big" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/hashicorp/consul/sdk/freeport" + "github.com/shopspring/decimal" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" + "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + datastreamsllo "github.com/smartcontractkit/chainlink-data-streams/llo" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_config_store" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_verifier" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/destination_verifier" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier_proxy" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" + lloevm "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + mercuryverifier "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/verifier" +) + +var ( + fNodes = uint8(1) + nNodes = 4 // number of nodes (not including bootstrap) +) + +func setupBlockchain(t *testing.T) (*bind.TransactOpts, *backends.SimulatedBackend, *channel_verifier.ChannelVerifier, common.Address, *channel_config_store.ChannelConfigStore, common.Address) { + steve := testutils.MustNewSimTransactor(t) // config contract deployer and owner + genesisData := core.GenesisAlloc{steve.From: {Balance: assets.Ether(1000).ToInt()}} + backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) + backend.Commit() + backend.Commit() // ensure starting block number at least 1 + + // Deploy contracts + verifierProxyAddr, _, _, err := verifier_proxy.DeployVerifierProxy(steve, backend, common.Address{}) // zero address for access controller disables access control + require.NoError(t, err) + + verifierAddress, _, verifierContract, err := channel_verifier.DeployChannelVerifier(steve, backend, verifierProxyAddr) + require.NoError(t, err) + configStoreAddress, _, configStoreContract, err := channel_config_store.DeployChannelConfigStore(steve, backend) + require.NoError(t, err) + + backend.Commit() + + return steve, backend, verifierContract, verifierAddress, configStoreContract, configStoreAddress +} + +type Stream struct { + id uint32 + baseBenchmarkPrice decimal.Decimal + baseBid decimal.Decimal + baseAsk decimal.Decimal +} + +var ( + btcStream = Stream{ + id: 51, + baseBenchmarkPrice: decimal.NewFromFloat32(56_114.41), + } + ethStream = Stream{ + id: 52, + baseBenchmarkPrice: decimal.NewFromFloat32(2_976.39), + } + linkStream = Stream{ + id: 53, + baseBenchmarkPrice: decimal.NewFromFloat32(13.25), + } + dogeStream = Stream{ + id: 54, + baseBenchmarkPrice: decimal.NewFromFloat32(0.10960935), + } + quoteStream = Stream{ + id: 55, + baseBenchmarkPrice: decimal.NewFromFloat32(1000.1212), + baseBid: decimal.NewFromFloat32(998.5431), + baseAsk: decimal.NewFromFloat32(1001.6999), + } +) + +func generateConfig(t *testing.T, oracles []confighelper.OracleIdentityExtra) ( + signers []types.OnchainPublicKey, + transmitters []types.Account, + f uint8, + onchainConfig []byte, + offchainConfigVersion uint64, + offchainConfig []byte, +) { + rawReportingPluginConfig := datastreamsllo.OffchainConfig{} + reportingPluginConfig, err := rawReportingPluginConfig.Encode() + require.NoError(t, err) + + offchainConfig = []byte{} + + signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, err = ocr3confighelper.ContractSetConfigArgsForTests( + 2*time.Second, // DeltaProgress + 20*time.Second, // DeltaResend + 400*time.Millisecond, // DeltaInitial + 1000*time.Millisecond, // DeltaRound + 500*time.Millisecond, // DeltaGrace + 300*time.Millisecond, // DeltaCertifiedCommitRequest + 1*time.Minute, // DeltaStage + 100, // rMax + []int{len(oracles)}, // S + oracles, + reportingPluginConfig, // reportingPluginConfig []byte, + 0, // maxDurationQuery + 250*time.Millisecond, // maxDurationObservation + 0, // maxDurationShouldAcceptAttestedReport + 0, // maxDurationShouldTransmitAcceptedReport + int(fNodes), // f + onchainConfig, // encoded onchain config + ) + + require.NoError(t, err) + + return +} + +func setConfig(t *testing.T, steve *bind.TransactOpts, backend *backends.SimulatedBackend, verifierContract *channel_verifier.ChannelVerifier, verifierAddress common.Address, nodes []Node, oracles []confighelper.OracleIdentityExtra) ocr2types.ConfigDigest { + signers, _, _, _, offchainConfigVersion, offchainConfig := generateConfig(t, oracles) + + signerAddresses, err := evm.OnchainPublicKeyToAddress(signers) + require.NoError(t, err) + offchainTransmitters := make([][32]byte, nNodes) + for i := 0; i < nNodes; i++ { + offchainTransmitters[i] = nodes[i].ClientPubKey + } + _, err = verifierContract.SetConfig(steve, signerAddresses, offchainTransmitters, fNodes, offchainConfig, offchainConfigVersion, offchainConfig, nil) + require.NoError(t, err) + + backend.Commit() + + l, err := verifierContract.LatestConfigDigestAndEpoch(&bind.CallOpts{}) + require.NoError(t, err) + + return l.ConfigDigest +} + +// On-chain format is not finalized yet so use the dummy relayer for testing +func TestIntegration_LLO_Dummy(t *testing.T) { + testStartTimeStamp := time.Now() + + clientCSAKeys := make([]csakey.KeyV2, nNodes) + clientPubKeys := make([]ed25519.PublicKey, nNodes) + for i := 0; i < nNodes; i++ { + k := big.NewInt(int64(i)) + key := csakey.MustNewV2XXXTestingOnly(k) + clientCSAKeys[i] = key + clientPubKeys[i] = key.PublicKey + } + + // Setup bootstrap + bootstrapCSAKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) + bootstrapNodePort := freeport.GetOne(t) + appBootstrap, bootstrapPeerID, _, bootstrapKb, _ := setupNode(t, bootstrapNodePort, "bootstrap_llo", nil, bootstrapCSAKey) + bootstrapNode := Node{App: appBootstrap, KeyBundle: bootstrapKb} + + t.Run("produces reports in v0.3 format", func(t *testing.T) { + streams := []Stream{ethStream, linkStream, quoteStream} + streamMap := make(map[uint32]Stream) + for _, strm := range streams { + streamMap[strm.id] = strm + } + + // Setup oracle nodes + var ( + oracles []confighelper.OracleIdentityExtra + nodes []Node + ) + ports := freeport.GetN(t, nNodes) + for i := 0; i < nNodes; i++ { + app, peerID, transmitter, kb, observedLogs := setupNode(t, ports[i], fmt.Sprintf("oracle_streams_%d", i), nil, clientCSAKeys[i]) + + nodes = append(nodes, Node{ + app, transmitter, kb, observedLogs, + }) + offchainPublicKey, _ := hex.DecodeString(strings.TrimPrefix(kb.OnChainPublicKey(), "0x")) + oracles = append(oracles, confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: offchainPublicKey, + TransmitAccount: ocr2types.Account(fmt.Sprintf("%x", transmitter[:])), + OffchainPublicKey: kb.OffchainPublicKey(), + PeerID: peerID, + }, + ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), + }) + } + + verifierAddress := common.Address{} + chainID := "llo-dummy" + relayType := "dummy" + cd := ocr2types.ConfigDigest{0x01, 0x02, 0x03, 0x04} + signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig := generateConfig(t, oracles) + var signersMarshalled, transmittersMarshalled []byte + { + var err error + signersHex := make([]string, len(signers)) + for i, signer := range signers { + signersHex[i] = fmt.Sprintf("0x%x", signer) + } + signersMarshalled, err = json.Marshal(signersHex) + require.NoError(t, err) + + transmittersMarshalled, err = json.Marshal(transmitters) + require.NoError(t, err) + } + + relayConfig := fmt.Sprintf(`chainID = "%s" +configTracker = { + configDigest = "0x%x", + configCount = 0, + signers = %s, + transmitters = %s, + f = %d, + onchainConfig = "0x%x", + offchainConfigVersion = %d, + offchainConfig = "0x%x", + blockHeight = 10 +}`, chainID, cd[:], string(signersMarshalled), string(transmittersMarshalled), f, onchainConfig, offchainConfigVersion, offchainConfig) + addBootstrapJob(t, bootstrapNode, verifierAddress, "job-2", relayType, relayConfig) + + serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) + serverPubKey := serverKey.PublicKey + serverURL := "foo" + configStoreAddress := common.Address{} + + chainSelector := 4949039107694359620 // arbitrum mainnet + + feedID := [32]byte{00, 03, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} + expirationWindow := 3600 + multiplier := big.NewInt(1e18) + baseUSDFee := 10 + // 52 = eth, 53 = link, 55 = quote + channelDefinitions := fmt.Sprintf(` +{ + "42": { + "reportFormat": %d, + "chainSelector": %d, + "streams": [{"streamId": 52, "aggregator": %d}, {"streamId": 53, "aggregator": %d}, {"streamId": 55, "aggregator": %d}], + "opts": { + "feedId": "0x%x", + "expirationWindow": %d, + "multiplier": "%s", + "baseUSDFee": "%d" + } + } +}`, llotypes.ReportFormatEVMPremiumLegacy, chainSelector, llotypes.AggregatorMedian, llotypes.AggregatorMedian, llotypes.AggregatorQuote, feedID, expirationWindow, multiplier.String(), baseUSDFee) + + pluginConfig := fmt.Sprintf(`serverURL = "foo" +donID = 42 +serverPubKey = "%x" +channelDefinitions = %q`, serverPubKey, channelDefinitions) + jobIDs := addOCRJobsEVMPremiumLegacy(t, streams, serverPubKey, serverURL, verifierAddress, bootstrapPeerID, bootstrapNodePort, nodes, configStoreAddress, clientPubKeys, pluginConfig, relayType, relayConfig) + + steve, backend, verifier, verifierProxy, _ := setupV03Blockchain(t) + + // Set config + recipientAddressesAndWeights := []destination_verifier.CommonAddressAndWeight{} + signerAddresses := make([]common.Address, len(oracles)) + for i, oracle := range oracles { + signerAddresses[i] = common.BytesToAddress(oracle.OracleIdentity.OnchainPublicKey) + } + + _, err := verifier.SetConfig(steve, signerAddresses, f, recipientAddressesAndWeights) + require.NoError(t, err) + backend.Commit() + + for i, node := range nodes { + le := testutils.WaitForLogMessage(t, node.ObservedLogs, "Transmit") + fields := le.ContextMap() + assert.Equal(t, hexutil.Encode(cd[:]), "0x"+fields["digest"].(string)) + assert.Equal(t, llotypes.ReportInfo{LifeCycleStage: "production", ReportFormat: llotypes.ReportFormatEVMPremiumLegacy}, fields["report.Info"]) + + if fields["report.Report"] == nil { + t.Fatal("FAIL: expected log fields to contain 'report.Report'") + } + binaryReport := fields["report.Report"].(types.Report) + report, err := (lloevm.ReportCodecPremiumLegacy{}).Decode(binaryReport) + require.NoError(t, err) + assert.Equal(t, feedID, report.FeedId) + assert.GreaterOrEqual(t, report.ObservationsTimestamp, uint32(testStartTimeStamp.Unix())) + assert.Equal(t, quoteStream.baseBenchmarkPrice.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.BenchmarkPrice.String()) + assert.Equal(t, quoteStream.baseBid.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.Bid.String()) + assert.Equal(t, quoteStream.baseAsk.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.Ask.String()) + assert.GreaterOrEqual(t, report.ValidFromTimestamp, uint32(testStartTimeStamp.Unix())) + assert.Equal(t, report.ObservationsTimestamp+uint32(expirationWindow), report.ExpiresAt) + assert.Equal(t, big.NewInt(754716981132075472), report.LinkFee) + assert.Equal(t, big.NewInt(3359774760700043), report.NativeFee) + + seqNr := fields["seqNr"].(uint64) + assert.Greater(t, int(seqNr), 0) + + sigs := fields["sigs"].([]types.AttributedOnchainSignature) + + t.Run(fmt.Sprintf("emulate mercury server verifying report (local verification) - node %d", i), func(t *testing.T) { + var rs [][32]byte + var ss [][32]byte + var vs [32]byte + for i, as := range sigs { + r, s, v, err := evmutil.SplitSignature(as.Signature) + if err != nil { + panic("error in SplitSignature") + } + rs = append(rs, r) + ss = append(ss, s) + vs[i] = v + } + rc := lloevm.LegacyReportContext(cd, seqNr) + rawReportCtx := evmutil.RawReportContext(rc) + rv := mercuryverifier.NewVerifier() + + reportSigners, err := rv.Verify(mercuryverifier.SignedReport{ + RawRs: rs, + RawSs: ss, + RawVs: vs, + ReportContext: rawReportCtx, + Report: binaryReport, + }, f, signerAddresses) + require.NoError(t, err) + assert.GreaterOrEqual(t, len(reportSigners), int(f+1)) + assert.Subset(t, signerAddresses, reportSigners) + }) + + t.Run(fmt.Sprintf("test on-chain verification - node %d", i), func(t *testing.T) { + signedReport, err := lloevm.ReportCodecPremiumLegacy{}.Pack(cd, seqNr, binaryReport, sigs) + require.NoError(t, err) + + _, err = verifierProxy.Verify(steve, signedReport, []byte{}) + require.NoError(t, err) + + }) + } + + t.Run("if link/eth stream specs start failing, uses 0 for the fee", func(t *testing.T) { + t.Run("link/eth stream specs are missing", func(t *testing.T) { + // delete eth/link stream specs + for idx, strmIDs := range jobIDs { + for strmID, jobID := range strmIDs { + if strmID == ethStream.id || strmID == linkStream.id { + nodes[idx].DeleteJob(t, jobID) + } + } + } + + for _, node := range nodes { + node.ObservedLogs.TakeAll() + + le := testutils.WaitForLogMessage(t, node.ObservedLogs, "Observation failed for streams") + fields := le.ContextMap() + assert.Equal(t, []interface{}{ethStream.id, linkStream.id}, fields["failedStreamIDs"]) + assert.Equal(t, []interface{}{"StreamID: 52; Reason: missing stream: 52", "StreamID: 53; Reason: missing stream: 53"}, fields["errors"]) + + le = testutils.WaitForLogMessage(t, node.ObservedLogs, "Transmit") + fields = le.ContextMap() + assert.Equal(t, hexutil.Encode(cd[:]), "0x"+fields["digest"].(string)) + assert.Equal(t, llotypes.ReportInfo{LifeCycleStage: "production", ReportFormat: llotypes.ReportFormatEVMPremiumLegacy}, fields["report.Info"]) + + if fields["report.Report"] == nil { + t.Fatal("FAIL: expected log fields to contain 'report.Report'") + } + binaryReport := fields["report.Report"].(types.Report) + report, err := (lloevm.ReportCodecPremiumLegacy{}).Decode(binaryReport) + require.NoError(t, err) + assert.Equal(t, feedID, report.FeedId) + assert.GreaterOrEqual(t, report.ObservationsTimestamp, uint32(testStartTimeStamp.Unix())) + assert.Equal(t, quoteStream.baseBenchmarkPrice.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.BenchmarkPrice.String()) + assert.Equal(t, quoteStream.baseBid.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.Bid.String()) + assert.Equal(t, quoteStream.baseAsk.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.Ask.String()) + assert.GreaterOrEqual(t, report.ValidFromTimestamp, uint32(testStartTimeStamp.Unix())) + assert.Equal(t, report.ObservationsTimestamp+uint32(expirationWindow), report.ExpiresAt) + assert.Equal(t, "0", report.LinkFee.String()) + assert.Equal(t, "0", report.NativeFee.String()) + } + }) + + t.Run("link/eth stream specs have EAs that return error", func(t *testing.T) { + // add new stream specs that will fail + for i, node := range nodes { + for j, strm := range streams { + if strm.id == ethStream.id || strm.id == linkStream.id { + var name string + if j == 0 { + name = "nativeprice" + } else { + name = "linkprice" + } + name = fmt.Sprintf("%s-%d-%d-erroring", name, strm.id, j) + bmBridge := createErroringBridge(t, name, i, node.App.BridgeORM()) + addSingleDecimalStreamJob( + t, + node, + strm.id, + bmBridge, + ) + } + } + } + + for _, node := range nodes { + node.ObservedLogs.TakeAll() + + le := testutils.WaitForLogMessage(t, node.ObservedLogs, "Observation failed for streams") + fields := le.ContextMap() + assert.Equal(t, []interface{}{ethStream.id, linkStream.id}, fields["failedStreamIDs"]) + assert.Len(t, fields["errors"], 2) + for _, err := range fields["errors"].([]interface{}) { + assert.Contains(t, err.(string), "Reason: failed to extract big.Int") + assert.Contains(t, err.(string), "status code 500") + } + + le = testutils.WaitForLogMessage(t, node.ObservedLogs, "Transmit") + fields = le.ContextMap() + assert.Equal(t, hexutil.Encode(cd[:]), "0x"+fields["digest"].(string)) + assert.Equal(t, llotypes.ReportInfo{LifeCycleStage: "production", ReportFormat: llotypes.ReportFormatEVMPremiumLegacy}, fields["report.Info"]) + + if fields["report.Report"] == nil { + t.Fatal("FAIL: expected log fields to contain 'report.Report'") + } + binaryReport := fields["report.Report"].(types.Report) + report, err := (lloevm.ReportCodecPremiumLegacy{}).Decode(binaryReport) + require.NoError(t, err) + assert.Equal(t, feedID, report.FeedId) + assert.GreaterOrEqual(t, report.ObservationsTimestamp, uint32(testStartTimeStamp.Unix())) + assert.Equal(t, quoteStream.baseBenchmarkPrice.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.BenchmarkPrice.String()) + assert.Equal(t, quoteStream.baseBid.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.Bid.String()) + assert.Equal(t, quoteStream.baseAsk.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.Ask.String()) + assert.GreaterOrEqual(t, report.ValidFromTimestamp, uint32(testStartTimeStamp.Unix())) + assert.Equal(t, int(report.ObservationsTimestamp+uint32(expirationWindow)), int(report.ExpiresAt)) + assert.Equal(t, "0", report.LinkFee.String()) + assert.Equal(t, "0", report.NativeFee.String()) + } + }) + }) + + t.Run("deleting LLO jobs cleans up resources", func(t *testing.T) { + t.Skip("TODO - https://smartcontract-it.atlassian.net/browse/MERC-3653") + }) + }) +} diff --git a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go index 9d2d52ce50..6103fbbaf4 100644 --- a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go +++ b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go @@ -1,215 +1,379 @@ package llo_test import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "math/rand/v2" + "net/http" + "sync" "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + "golang.org/x/crypto/sha3" + + "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink-common/pkg/utils" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_config_store" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/llo" ) +type mockHTTPClient struct { + resp *http.Response + err error + mu sync.Mutex +} + +func (h *mockHTTPClient) Do(req *http.Request) (*http.Response, error) { + h.mu.Lock() + defer h.mu.Unlock() + return h.resp, h.err +} + +func (h *mockHTTPClient) SetResponse(resp *http.Response, err error) { + h.mu.Lock() + defer h.mu.Unlock() + h.resp = resp + h.err = err +} + +type MockReadCloser struct { + data []byte + reader *bytes.Reader +} + +func NewMockReadCloser(data []byte) *MockReadCloser { + return &MockReadCloser{ + data: data, + reader: bytes.NewReader(data), + } +} + +// Read reads from the underlying data +func (m *MockReadCloser) Read(p []byte) (int, error) { + return m.reader.Read(p) +} + +// Close resets the reader to the beginning of the data +func (m *MockReadCloser) Close() error { + m.reader.Seek(0, io.SeekStart) + return nil +} + func Test_ChannelDefinitionCache_Integration(t *testing.T) { - t.Skip("waiting on https://github.com/smartcontractkit/chainlink/pull/13780") - // lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.InfoLevel) - // db := pgtest.NewSqlxDB(t) - // ctx := testutils.Context(t) - // orm := llo.NewORM(db, testutils.SimulatedChainID) - - // steve := testutils.MustNewSimTransactor(t) // config contract deployer and owner - // genesisData := core.GenesisAlloc{steve.From: {Balance: assets.Ether(1000).ToInt()}} - // backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) - // backend.Commit() // ensure starting block number at least 1 - - // ethClient := client.NewSimulatedBackendClient(t, backend, testutils.SimulatedChainID) - - // configStoreAddress, _, configStoreContract, err := channel_config_store.DeployChannelConfigStore(steve, backend) - // require.NoError(t, err) - - // channel1 := rand.Uint32() - // channel2 := rand.Uint32() - // channel3 := rand.Uint32() - - // chainSelector, err := chainselectors.SelectorFromChainId(testutils.SimulatedChainID.Uint64()) - // require.NoError(t, err) - - // streamIDs := []uint32{1, 2, 3} - // channel1Def := channel_config_store.IChannelConfigStoreChannelDefinition{ - // ReportFormat: uint32(llotypes.ReportFormatSolana), - // ChainSelector: chainSelector, - // StreamIDs: streamIDs, - // } - // channel2Def := channel_config_store.IChannelConfigStoreChannelDefinition{ - // ReportFormat: uint32(llotypes.ReportFormatEVM), - // ChainSelector: chainSelector, - // StreamIDs: streamIDs, - // } - // channel3Def := channel_config_store.IChannelConfigStoreChannelDefinition{ - // ReportFormat: uint32(llotypes.ReportFormatEVM), - // ChainSelector: chainSelector, - // StreamIDs: append(streamIDs, 4), - // } - - // require.NoError(t, utils.JustError(configStoreContract.AddChannel(steve, channel1, channel1Def))) - // require.NoError(t, utils.JustError(configStoreContract.AddChannel(steve, channel2, channel2Def))) - - // h := backend.Commit() - // channel2Block, err := backend.BlockByHash(ctx, h) - // require.NoError(t, err) - - // t.Run("with zero fromblock", func(t *testing.T) { - // lpOpts := logpoller.Opts{ - // PollPeriod: 100 * time.Millisecond, - // FinalityDepth: 1, - // BackfillBatchSize: 3, - // RpcBatchSize: 2, - // KeepFinalizedBlocksDepth: 1000, - // } - // ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) - // lp := logpoller.NewLogPoller( - // logpoller.NewORM(testutils.SimulatedChainID, db, lggr), ethClient, lggr, ht, lpOpts) - // servicetest.Run(t, lp) - // cdc := llo.NewChannelDefinitionCache(lggr, orm, lp, configStoreAddress, 0) - - // servicetest.Run(t, cdc) - - // testutils.WaitForLogMessage(t, observedLogs, "Updated channel definitions") - - // dfns := cdc.Definitions() - - // require.Len(t, dfns, 2) - // require.Contains(t, dfns, channel1) - // require.Contains(t, dfns, channel2) - // assert.Equal(t, llotypes.ChannelDefinition{ - // ReportFormat: llotypes.ReportFormatSolana, - // ChainSelector: chainSelector, - // StreamIDs: []uint32{1, 2, 3}, - // }, dfns[channel1]) - // assert.Equal(t, llotypes.ChannelDefinition{ - // ReportFormat: llotypes.ReportFormatEVM, - // ChainSelector: chainSelector, - // StreamIDs: []uint32{1, 2, 3}, - // }, dfns[channel2]) - - // // remove solana - // require.NoError(t, utils.JustError(configStoreContract.RemoveChannel(steve, channel1))) - // backend.Commit() - // testutils.WaitForLogMessageCount(t, observedLogs, "Updated channel definitions", 2) - // dfns = cdc.Definitions() - - // require.Len(t, dfns, 1) - // assert.NotContains(t, dfns, channel1) - // require.Contains(t, dfns, channel2) - - // assert.Equal(t, llotypes.ChannelDefinition{ - // ReportFormat: llotypes.ReportFormatEVM, - // ChainSelector: chainSelector, - // StreamIDs: []uint32{1, 2, 3}, - // }, dfns[channel2]) - - // // add channel3 with additional stream - // require.NoError(t, utils.JustError(configStoreContract.AddChannel(steve, channel3, channel3Def))) - // backend.Commit() - // testutils.WaitForLogMessageCount(t, observedLogs, "Updated channel definitions", 3) - // dfns = cdc.Definitions() - - // require.Len(t, dfns, 2) - // require.Contains(t, dfns, channel2) - // require.Contains(t, dfns, channel3) - - // assert.Equal(t, llotypes.ChannelDefinition{ - // ReportFormat: llotypes.ReportFormatEVM, - // ChainSelector: chainSelector, - // StreamIDs: []uint32{1, 2, 3}, - // }, dfns[channel2]) - // assert.Equal(t, llotypes.ChannelDefinition{ - // ReportFormat: llotypes.ReportFormatEVM, - // ChainSelector: chainSelector, - // StreamIDs: []uint32{1, 2, 3, 4}, - // }, dfns[channel3]) - // }) - - // t.Run("loads from ORM", func(t *testing.T) { - // // Override logpoller to always return no logs - // lpOpts := logpoller.Opts{ - // PollPeriod: 100 * time.Millisecond, - // FinalityDepth: 1, - // BackfillBatchSize: 3, - // RpcBatchSize: 2, - // KeepFinalizedBlocksDepth: 1000, - // } - // ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) - // lp := &mockLogPoller{ - // LogPoller: logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr), ethClient, lggr, ht, lpOpts), - // LatestBlockFn: func(ctx context.Context) (int64, error) { - // return 0, nil - // }, - // LogsWithSigsFn: func(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) { - // return []logpoller.Log{}, nil - // }, - // } - // cdc := llo.NewChannelDefinitionCache(lggr, orm, lp, configStoreAddress, 0) - - // servicetest.Run(t, cdc) - - // dfns := cdc.Definitions() - - // require.Len(t, dfns, 2) - // require.Contains(t, dfns, channel2) - // require.Contains(t, dfns, channel3) - - // assert.Equal(t, llotypes.ChannelDefinition{ - // ReportFormat: llotypes.ReportFormatEVM, - // ChainSelector: chainSelector, - // StreamIDs: []uint32{1, 2, 3}, - // }, dfns[channel2]) - // assert.Equal(t, llotypes.ChannelDefinition{ - // ReportFormat: llotypes.ReportFormatEVM, - // ChainSelector: chainSelector, - // StreamIDs: []uint32{1, 2, 3, 4}, - // }, dfns[channel3]) - // }) - - // // clear out DB for next test - // pgtest.MustExec(t, db, `DELETE FROM channel_definitions`) - - // t.Run("with non-zero fromBlock", func(t *testing.T) { - // lpOpts := logpoller.Opts{ - // PollPeriod: 100 * time.Millisecond, - // FinalityDepth: 1, - // BackfillBatchSize: 3, - // RpcBatchSize: 2, - // KeepFinalizedBlocksDepth: 1000, - // } - // ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) - // lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr), ethClient, lggr, ht, lpOpts) - // servicetest.Run(t, lp) - // cdc := llo.NewChannelDefinitionCache(lggr, orm, lp, configStoreAddress, channel2Block.Number().Int64()+1) - - // // should only detect events from AFTER channel 2 was added - // servicetest.Run(t, cdc) - - // testutils.WaitForLogMessageCount(t, observedLogs, "Updated channel definitions", 4) - - // dfns := cdc.Definitions() - - // require.Len(t, dfns, 1) - // require.Contains(t, dfns, channel3) - - // assert.Equal(t, llotypes.ChannelDefinition{ - // ReportFormat: llotypes.ReportFormatEVM, - // ChainSelector: chainSelector, - // StreamIDs: []uint32{1, 2, 3, 4}, - // }, dfns[channel3]) - // }) - // } - - // type mockLogPoller struct { - // logpoller.LogPoller - // LatestBlockFn func(ctx context.Context) (int64, error) - // LogsWithSigsFn func(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) - // } - - // func (p *mockLogPoller) LogsWithSigs(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) { - // return p.LogsWithSigsFn(ctx, start, end, eventSigs, address) - // } - // - // func (p *mockLogPoller) LatestBlock(ctx context.Context) (logpoller.LogPollerBlock, error) { - // block, err := p.LatestBlockFn(ctx) - // return logpoller.LogPollerBlock{BlockNumber: block}, err + var ( + invalidDefinitions = []byte(`{{{`) + invalidDefinitionsSHA = sha3.Sum256(invalidDefinitions) + + sampleDefinitions = llotypes.ChannelDefinitions{ + 1: { + ReportFormat: llotypes.ReportFormatJSON, + Streams: []llotypes.Stream{ + { + StreamID: 1, + Aggregator: llotypes.AggregatorMedian, + }, + { + StreamID: 2, + Aggregator: llotypes.AggregatorMode, + }, + }, + }, + 2: { + ReportFormat: llotypes.ReportFormatEVMPremiumLegacy, + Streams: []llotypes.Stream{ + { + StreamID: 1, + Aggregator: llotypes.AggregatorMedian, + }, + { + StreamID: 2, + Aggregator: llotypes.AggregatorMedian, + }, + { + StreamID: 3, + Aggregator: llotypes.AggregatorQuote, + }, + }, + Opts: llotypes.ChannelOpts([]byte(`{"baseUSDFee":"0.1","expirationWindow":86400,"feedId":"0x0003aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","multiplier":"1000000000000000000"}`)), + }, + } + ) + + sampleDefinitionsJSON, err := json.MarshalIndent(sampleDefinitions, "", " ") + require.NoError(t, err) + sampleDefinitionsSHA := sha3.Sum256(sampleDefinitionsJSON) + + lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.DebugLevel) + db := pgtest.NewSqlxDB(t) + const ETHMainnetChainSelector uint64 = 5009297550715157269 + orm := llo.NewORM(db, ETHMainnetChainSelector) + + steve := testutils.MustNewSimTransactor(t) // config contract deployer and owner + genesisData := core.GenesisAlloc{steve.From: {Balance: assets.Ether(1000).ToInt()}} + backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) + backend.Commit() // ensure starting block number at least 1 + + ethClient := client.NewSimulatedBackendClient(t, backend, testutils.SimulatedChainID) + + configStoreAddress, _, configStoreContract, err := channel_config_store.DeployChannelConfigStore(steve, backend) + require.NoError(t, err) + + lpOpts := logpoller.Opts{ + PollPeriod: 100 * time.Millisecond, + FinalityDepth: 1, + BackfillBatchSize: 3, + RpcBatchSize: 2, + KeepFinalizedBlocksDepth: 1000, + } + ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + lp := logpoller.NewLogPoller( + logpoller.NewORM(testutils.SimulatedChainID, db, lggr), ethClient, lggr, ht, lpOpts) + servicetest.Run(t, lp) + + client := &mockHTTPClient{} + donID := rand.Uint32() + + cdc := llo.NewChannelDefinitionCache(lggr, orm, client, lp, configStoreAddress, donID, 0, llo.WithLogPollInterval(100*time.Millisecond)) + servicetest.Run(t, cdc) + + t.Run("before any logs, returns empty Definitions", func(t *testing.T) { + assert.Empty(t, cdc.Definitions()) + }) + + { + rc := NewMockReadCloser(invalidDefinitions) + client.SetResponse(&http.Response{ + StatusCode: 200, + Body: rc, + }, nil) + + url := "http://example.com/foo" + require.NoError(t, utils.JustError(configStoreContract.SetChannelDefinitions(steve, donID, url, sampleDefinitionsSHA))) + + backend.Commit() + } + + t.Run("with sha mismatch, should not update", func(t *testing.T) { + // clear the log messages + t.Cleanup(func() { observedLogs.TakeAll() }) + + testutils.WaitForLogMessage(t, observedLogs, "Got new channel definitions from chain") + le := testutils.WaitForLogMessage(t, observedLogs, "Error while fetching channel definitions") + fields := le.ContextMap() + assert.Contains(t, fields, "err") + assert.Equal(t, fmt.Sprintf("SHA3 mismatch: expected %x, got %x", sampleDefinitionsSHA, invalidDefinitionsSHA), fields["err"]) + + assert.Empty(t, cdc.Definitions()) + }) + + { + rc := NewMockReadCloser(invalidDefinitions) + client.SetResponse(&http.Response{ + StatusCode: 200, + Body: rc, + }, nil) + + url := "http://example.com/foo" + require.NoError(t, utils.JustError(configStoreContract.SetChannelDefinitions(steve, donID, url, invalidDefinitionsSHA))) + backend.Commit() + } + + t.Run("after correcting sha with new channel definitions set on-chain, but with invalid JSON at url, should not update", func(t *testing.T) { + // clear the log messages + t.Cleanup(func() { observedLogs.TakeAll() }) + + testutils.WaitForLogMessage(t, observedLogs, "Got new channel definitions from chain") + testutils.WaitForLogMessageWithField(t, observedLogs, "Error while fetching channel definitions", "err", "failed to decode JSON: invalid character '{' looking for beginning of object key string") + + assert.Empty(t, cdc.Definitions()) + }) + + { + rc := NewMockReadCloser([]byte("not found")) + client.SetResponse(&http.Response{ + StatusCode: 404, + Body: rc, + }, nil) + + url := "http://example.com/foo3" + require.NoError(t, utils.JustError(configStoreContract.SetChannelDefinitions(steve, donID, url, sampleDefinitionsSHA))) + backend.Commit() + } + + t.Run("if server returns 404, should not update", func(t *testing.T) { + // clear the log messages + t.Cleanup(func() { observedLogs.TakeAll() }) + + testutils.WaitForLogMessageWithField(t, observedLogs, "Error while fetching channel definitions", "err", "got error from http://example.com/foo3: (status code: 404, response body: not found)") + }) + + { + rc := NewMockReadCloser([]byte{}) + client.SetResponse(&http.Response{ + StatusCode: 200, + Body: rc, + }, nil) + } + + t.Run("if server starts returning empty body, still does not update", func(t *testing.T) { + // clear the log messages + t.Cleanup(func() { observedLogs.TakeAll() }) + + testutils.WaitForLogMessageWithField(t, observedLogs, "Error while fetching channel definitions", "err", fmt.Sprintf("SHA3 mismatch: expected %x, got %x", sampleDefinitionsSHA, sha3.Sum256([]byte{}))) + }) + + { + rc := NewMockReadCloser(sampleDefinitionsJSON) + client.SetResponse(&http.Response{ + StatusCode: 200, + Body: rc, + }, nil) + } + + t.Run("when URL starts returning valid JSON, updates even without needing new logs", func(t *testing.T) { + // clear the log messages + t.Cleanup(func() { observedLogs.TakeAll() }) + + le := testutils.WaitForLogMessage(t, observedLogs, "Set new channel definitions") + fields := le.ContextMap() + assert.Contains(t, fields, "version") + assert.Contains(t, fields, "url") + assert.Contains(t, fields, "sha") + assert.Contains(t, fields, "donID") + assert.NotContains(t, fields, "err") + + assert.Equal(t, uint32(3), fields["version"]) + assert.Equal(t, "http://example.com/foo3", fields["url"]) + assert.Equal(t, fmt.Sprintf("%x", sampleDefinitionsSHA), fields["sha"]) + assert.Equal(t, donID, fields["donID"]) + + assert.Equal(t, sampleDefinitions, cdc.Definitions()) + + t.Run("latest channel definitions are persisted", func(t *testing.T) { + pd, err := orm.LoadChannelDefinitions(testutils.Context(t), configStoreAddress, donID) + require.NoError(t, err) + assert.Equal(t, ETHMainnetChainSelector, pd.ChainSelector) + assert.Equal(t, configStoreAddress, pd.Address) + assert.Equal(t, sampleDefinitions, pd.Definitions) + assert.Equal(t, donID, pd.DonID) + assert.Equal(t, uint32(3), pd.Version) + }) + + t.Run("new cdc with same config should load from DB", func(t *testing.T) { + // fromBlock far in the future to ensure logs are not used + cdc2 := llo.NewChannelDefinitionCache(lggr, orm, client, lp, configStoreAddress, donID, 1000) + servicetest.Run(t, cdc2) + + assert.Equal(t, sampleDefinitions, cdc.Definitions()) + }) + }) + + { + url := "not a real URL" + require.NoError(t, utils.JustError(configStoreContract.SetChannelDefinitions(steve, donID, url, sampleDefinitionsSHA))) + + backend.Commit() + + client.SetResponse(nil, errors.New("failed; not a real URL")) + } + + t.Run("new log with invalid channel definitions URL does not affect old channel definitions", func(t *testing.T) { + // clear the log messages + t.Cleanup(func() { observedLogs.TakeAll() }) + + le := testutils.WaitForLogMessage(t, observedLogs, "Error while fetching channel definitions") + fields := le.ContextMap() + assert.Contains(t, fields, "err") + assert.Equal(t, "error making http request: failed; not a real URL", fields["err"]) + }) + + { + // add a new definition, it should get loaded + sampleDefinitions[3] = llotypes.ChannelDefinition{ + ReportFormat: llotypes.ReportFormatJSON, + Streams: []llotypes.Stream{ + { + StreamID: 6, + Aggregator: llotypes.AggregatorMedian, + }, + }, + } + var err error + sampleDefinitionsJSON, err = json.MarshalIndent(sampleDefinitions, "", " ") + require.NoError(t, err) + sampleDefinitionsSHA = sha3.Sum256(sampleDefinitionsJSON) + rc := NewMockReadCloser(sampleDefinitionsJSON) + client.SetResponse(&http.Response{ + StatusCode: 200, + Body: rc, + }, nil) + + url := "http://example.com/foo5" + require.NoError(t, utils.JustError(configStoreContract.SetChannelDefinitions(steve, donID, url, sampleDefinitionsSHA))) + + backend.Commit() + } + + t.Run("successfully updates to new channel definitions with new log", func(t *testing.T) { + t.Cleanup(func() { observedLogs.TakeAll() }) + + le := testutils.WaitForLogMessage(t, observedLogs, "Set new channel definitions") + fields := le.ContextMap() + assert.Contains(t, fields, "version") + assert.Contains(t, fields, "url") + assert.Contains(t, fields, "sha") + assert.Contains(t, fields, "donID") + assert.NotContains(t, fields, "err") + + assert.Equal(t, uint32(5), fields["version"]) + assert.Equal(t, "http://example.com/foo5", fields["url"]) + assert.Equal(t, fmt.Sprintf("%x", sampleDefinitionsSHA), fields["sha"]) + assert.Equal(t, donID, fields["donID"]) + + assert.Equal(t, sampleDefinitions, cdc.Definitions()) + }) + + t.Run("latest channel definitions are persisted and overwrite previous value", func(t *testing.T) { + pd, err := orm.LoadChannelDefinitions(testutils.Context(t), configStoreAddress, donID) + require.NoError(t, err) + assert.Equal(t, ETHMainnetChainSelector, pd.ChainSelector) + assert.Equal(t, configStoreAddress, pd.Address) + assert.Equal(t, sampleDefinitions, pd.Definitions) + assert.Equal(t, donID, pd.DonID) + assert.Equal(t, uint32(5), pd.Version) + }) +} + +type mockLogPoller struct { + logpoller.LogPoller + LatestBlockFn func(ctx context.Context) (int64, error) + LogsWithSigsFn func(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) +} + +func (p *mockLogPoller) LogsWithSigs(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) { + return p.LogsWithSigsFn(ctx, start, end, eventSigs, address) +} +func (p *mockLogPoller) LatestBlock(ctx context.Context) (logpoller.LogPollerBlock, error) { + block, err := p.LatestBlockFn(ctx) + return logpoller.LogPollerBlock{BlockNumber: block}, err } diff --git a/core/services/ocr2/plugins/mercury/integration_test.go b/core/services/ocr2/plugins/mercury/integration_test.go index 9e34e9da8b..6f9f373256 100644 --- a/core/services/ocr2/plugins/mercury/integration_test.go +++ b/core/services/ocr2/plugins/mercury/integration_test.go @@ -41,7 +41,7 @@ import ( datastreamsmercury "github.com/smartcontractkit/chainlink-data-streams/mercury" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" - token "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/fee_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/reward_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier" @@ -98,11 +98,11 @@ func setupBlockchain(t *testing.T) (*bind.TransactOpts, *backends.SimulatedBacke t.Cleanup(stopMining) // Deploy contracts - linkTokenAddress, _, linkToken, err := token.DeployLinkToken(steve, backend) + linkTokenAddress, _, linkToken, err := link_token_interface.DeployLinkToken(steve, backend) require.NoError(t, err) _, err = linkToken.Transfer(steve, steve.From, big.NewInt(1000)) require.NoError(t, err) - nativeTokenAddress, _, nativeToken, err := token.DeployLinkToken(steve, backend) + nativeTokenAddress, _, nativeToken, err := link_token_interface.DeployLinkToken(steve, backend) require.NoError(t, err) _, err = nativeToken.Transfer(steve, steve.From, big.NewInt(1000)) require.NoError(t, err) diff --git a/core/services/relay/dummy/config_provider.go b/core/services/relay/dummy/config_provider.go index 10662ee296..db36acba83 100644 --- a/core/services/relay/dummy/config_provider.go +++ b/core/services/relay/dummy/config_provider.go @@ -63,7 +63,7 @@ type configProvider struct { } func NewConfigProvider(lggr logger.Logger, cfg RelayConfig) (types.ConfigProvider, error) { - cp := &configProvider{lggr: lggr.Named("DummyConfigProvider")} + cp := &configProvider{lggr: lggr.Named("DummyConfigProvider").Named(cfg.ConfigTracker.ConfigDigest.String())} { contractConfig, err := cfg.ConfigTracker.ToContractConfig() diff --git a/core/services/relay/dummy/config_tracker.go b/core/services/relay/dummy/config_tracker.go index 0ae188361f..ecd08196e5 100644 --- a/core/services/relay/dummy/config_tracker.go +++ b/core/services/relay/dummy/config_tracker.go @@ -21,7 +21,7 @@ func NewContractConfigTracker(lggr logger.Logger, cfg ConfigTrackerCfg) (ocrtype if err != nil { return nil, err } - return &configTracker{lggr.Named("DummyConfigProvider"), contractConfig, cfg.ChangedInBlock, cfg.BlockHeight}, nil + return &configTracker{lggr.Named("DummyConfigTracker"), contractConfig, cfg.ChangedInBlock, cfg.BlockHeight}, nil } // Notify may optionally emit notification events when the contract's diff --git a/core/services/relay/dummy/llo_provider.go b/core/services/relay/dummy/llo_provider.go index 4aeb21bed8..887fa13430 100644 --- a/core/services/relay/dummy/llo_provider.go +++ b/core/services/relay/dummy/llo_provider.go @@ -73,10 +73,6 @@ func (p *lloProvider) OffchainConfigDigester() ocrtypes.OffchainConfigDigester { return p.cp.OffchainConfigDigester() } -func (p *lloProvider) OnchainConfigCodec() llo.OnchainConfigCodec { - return &llo.JSONOnchainConfigCodec{} -} - func (p *lloProvider) ContractTransmitter() llotypes.Transmitter { return p.transmitter } diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 9596ab29d0..7b85268d11 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "math/big" + "net/http" "strings" "github.com/ethereum/go-ethereum/accounts/abi" @@ -21,6 +22,8 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median/evmreportcodec" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + chainselectors "github.com/smartcontractkit/chain-selectors" + ocr3capability "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/triggers" "github.com/smartcontractkit/chainlink-common/pkg/logger" @@ -162,6 +165,7 @@ type RelayerOpts struct { MercuryPool wsrpc.Pool TransmitterConfig mercury.TransmitterConfig CapabilitiesRegistry coretypes.CapabilitiesRegistry + HTTPClient *http.Client } func (c RelayerOpts) Validate() error { @@ -189,8 +193,9 @@ func NewRelayer(lggr logger.Logger, chain legacyevm.Chain, opts RelayerOpts) (*R sugared := logger.Sugared(lggr).Named("Relayer") mercuryORM := mercury.NewORM(opts.DS) - lloORM := llo.NewORM(opts.DS, chain.ID()) - cdcFactory := llo.NewChannelDefinitionCacheFactory(sugared, lloORM, chain.LogPoller()) + chainSelector, err := chainselectors.SelectorFromChainId(chain.ID().Uint64()) + lloORM := llo.NewORM(opts.DS, chainSelector) + cdcFactory := llo.NewChannelDefinitionCacheFactory(sugared, lloORM, chain.LogPoller(), opts.HTTPClient) relayer := &Relayer{ ds: opts.DS, chain: chain, diff --git a/core/services/relay/evm/llo_provider.go b/core/services/relay/evm/llo_provider.go index caedf0e771..55b80bd58e 100644 --- a/core/services/relay/evm/llo_provider.go +++ b/core/services/relay/evm/llo_provider.go @@ -74,10 +74,6 @@ func (p *lloProvider) OffchainConfigDigester() ocrtypes.OffchainConfigDigester { return p.cp.OffchainConfigDigester() } -func (p *lloProvider) OnchainConfigCodec() llo.OnchainConfigCodec { - return &llo.JSONOnchainConfigCodec{} -} - func (p *lloProvider) ContractTransmitter() llotypes.Transmitter { return p.transmitter } diff --git a/core/services/relay/evm/mercury/verifier/verifier.go b/core/services/relay/evm/mercury/verifier/verifier.go new file mode 100644 index 0000000000..02bb17d387 --- /dev/null +++ b/core/services/relay/evm/mercury/verifier/verifier.go @@ -0,0 +1,111 @@ +package verifier + +import ( + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" +) + +var ( + ErrVerificationFailed = errors.New("verification failed") + + ErrFailedUnmarshalPubkey = fmt.Errorf("%w: failed to unmarshal pubkey", ErrVerificationFailed) + ErrVerifyInvalidSignatureCount = fmt.Errorf("%w: invalid signature count", ErrVerificationFailed) + ErrVerifyMismatchedSignatureCount = fmt.Errorf("%w: mismatched signature count", ErrVerificationFailed) + ErrVerifyInvalidSignature = fmt.Errorf("%w: invalid signature", ErrVerificationFailed) + ErrVerifySomeSignerUnauthorized = fmt.Errorf("%w: node unauthorized", ErrVerificationFailed) + ErrVerifyNonUniqueSignature = fmt.Errorf("%w: signer has already signed", ErrVerificationFailed) +) + +type SignedReport struct { + RawRs [][32]byte + RawSs [][32]byte + RawVs [32]byte + ReportContext [3][32]byte + Report []byte +} + +type Verifier interface { + // Verify checks the report against its configuration, and then verifies signatures. + // It replicates the Verifier contract's "verify" function for server side + // report verification. + // See also: contracts/src/v0.8/llo-feeds/Verifier.sol + Verify(report SignedReport, f uint8, authorizedSigners []common.Address) (signers []common.Address, err error) +} + +var _ Verifier = (*verifier)(nil) + +type verifier struct{} + +func NewVerifier() Verifier { + return &verifier{} +} + +func (v *verifier) Verify(sr SignedReport, f uint8, authorizedSigners []common.Address) (signers []common.Address, err error) { + if len(sr.RawRs) != int(f+1) { + return signers, fmt.Errorf("%w: expected the number of signatures (len(rs)) to equal the number of signatures required (f), but f=%d and len(rs)=%d", ErrVerifyInvalidSignatureCount, f+1, len(sr.RawRs)) + } + if len(sr.RawRs) != len(sr.RawSs) { + return signers, fmt.Errorf("%w: got %d rs and %d ss, expected equal", ErrVerifyMismatchedSignatureCount, len(sr.RawRs), len(sr.RawSs)) + } + + sigData := ReportToSigData(sr.ReportContext, sr.Report) + + signerMap := make(map[common.Address]bool) + for _, signer := range authorizedSigners { + signerMap[signer] = false + } + + // Loop over every signature and collect errors. This wastes some CPU cycles, but we need to know everyone who + // signed the report. Some risk mitigated by checking that the number of signatures matches the expected (F) earlier + var verifyErrors error + reportSigners := make([]common.Address, len(sr.RawRs)) // For logging + metrics, string for convenience + for i := 0; i < len(sr.RawRs); i++ { + sig := append(sr.RawRs[i][:], sr.RawSs[i][:]...) + sig = append(sig, sr.RawVs[i]) // In the contract, you'll see vs+27. We don't do that here since geth adds +27 internally + + sigPubKey, err := crypto.Ecrecover(sigData, sig) + if err != nil { + verifyErrors = errors.Join(verifyErrors, fmt.Errorf("failed to recover signature: %w", err)) + continue + } + + verified := crypto.VerifySignature(sigPubKey, sigData, sig[:64]) + if !verified { + verifyErrors = errors.Join(verifyErrors, ErrVerifyInvalidSignature, fmt.Errorf("signature verification failed for pubKey: %x, sig: %x", sigPubKey, sig)) + continue + } + + unmarshalledPub, err := crypto.UnmarshalPubkey(sigPubKey) + if err != nil { + verifyErrors = errors.Join(verifyErrors, ErrFailedUnmarshalPubkey, fmt.Errorf("public key=%x error=%w", sigPubKey, err)) + continue + } + + address := crypto.PubkeyToAddress(*unmarshalledPub) + reportSigners[i] = address + encountered, authorized := signerMap[address] + if !authorized { + verifyErrors = errors.Join(verifyErrors, ErrVerifySomeSignerUnauthorized, fmt.Errorf("signer %s not in list of authorized nodes", address.String())) + continue + } + if encountered { + verifyErrors = errors.Join(verifyErrors, ErrVerifyNonUniqueSignature, fmt.Errorf("signer %s has already signed this report", address.String())) + continue + } + signerMap[address] = true + signers = append(signers, address) + } + return signers, verifyErrors +} + +func ReportToSigData(reportCtx [3][32]byte, sr types.Report) []byte { + sigData := crypto.Keccak256(sr) + sigData = append(sigData, reportCtx[0][:]...) + sigData = append(sigData, reportCtx[1][:]...) + sigData = append(sigData, reportCtx[2][:]...) + return crypto.Keccak256(sigData) +} diff --git a/core/services/relay/evm/mercury/verifier/verifier_test.go b/core/services/relay/evm/mercury/verifier/verifier_test.go new file mode 100644 index 0000000000..4cc9dcc9bf --- /dev/null +++ b/core/services/relay/evm/mercury/verifier/verifier_test.go @@ -0,0 +1,80 @@ +package verifier + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/test-go/testify/assert" + "github.com/test-go/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" +) + +func Test_Verifier(t *testing.T) { + t.Parallel() + + signedReportBinary := hexutil.MustDecode(`0x0006e1dde86b8a12add45546a14ea7e5efd10b67a373c6f4c41ecfa17d0005350000000000000000000000000000000000000000000000000000000000000201000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000002800001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000034c9214519c942ad0aa84a3dd31870e6efe8b3fcab4e176c5226879b26c77000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000669150aa0000000000000000000000000000000000001504e1e6c380271bb8b129ac8f7c0000000000000000000000000000000000001504e1e6c380271bb8b129ac8f7c00000000000000000000000000000000000000000000000000000000669150ab0000000000000000000000000000000000000000000000000000002482116240000000000000000000000000000000000000000000000000000000247625a04000000000000000000000000000000000000000000000000000000024880743400000000000000000000000000000000000000000000000000000000000000002710ac21df88ab70c8822b68be53d7bed65c82ffc9204c1d7ccf3c6c4048b3ca2cafb26e7bbd8f13fe626c946baa5ffcb444319c4229b945ea65d0c99c21978a100000000000000000000000000000000000000000000000000000000000000022c07843f17aa3ecd55f52e99e889906f825f49e4ddfa9c74ca487dd4ff101cc636108a5323be838e658dffa1be67bd91e99f68c4bf86936b76c5d8193b707597`) + m := make(map[string]interface{}) + err := mercury.PayloadTypes.UnpackIntoMap(m, signedReportBinary) + require.NoError(t, err) + + signedReport := SignedReport{ + RawRs: m["rawRs"].([][32]byte), + RawSs: m["rawSs"].([][32]byte), + RawVs: m["rawVs"].([32]byte), + ReportContext: m["reportContext"].([3][32]byte), + Report: m["report"].([]byte), + } + + f := uint8(1) + + v := NewVerifier() + + t.Run("Verify errors with unauthorized signers", func(t *testing.T) { + _, err := v.Verify(signedReport, f, []common.Address{}) + require.Error(t, err) + assert.EqualError(t, err, "verification failed: node unauthorized\nsigner 0x3fc9FaA15d71EeD614e5322bd9554Fb35cC381d2 not in list of authorized nodes\nverification failed: node unauthorized\nsigner 0xBa6534da0E49c71cD9d0292203F1524876f33E23 not in list of authorized nodes") + }) + + t.Run("Verify succeeds with authorized signers", func(t *testing.T) { + signers, err := v.Verify(signedReport, f, []common.Address{ + common.HexToAddress("0xde25e5b4005f611e356ce203900da4e37d72d58f"), + common.HexToAddress("0x256431d41cf0d944f5877bc6c93846a9829dfc03"), + common.HexToAddress("0x3fc9faa15d71eed614e5322bd9554fb35cc381d2"), + common.HexToAddress("0xba6534da0e49c71cd9d0292203f1524876f33e23"), + }) + require.NoError(t, err) + assert.Equal(t, []common.Address{ + common.HexToAddress("0x3fc9faa15d71eed614e5322bd9554fb35cc381d2"), + common.HexToAddress("0xBa6534da0E49c71cD9d0292203F1524876f33E23"), + }, signers) + }) + + t.Run("Verify fails if report has been tampered with", func(t *testing.T) { + badReport := signedReport + badReport.Report = []byte{0x0011} + _, err := v.Verify(badReport, f, []common.Address{ + common.HexToAddress("0xde25e5b4005f611e356ce203900da4e37d72d58f"), + common.HexToAddress("0x256431d41cf0d944f5877bc6c93846a9829dfc03"), + common.HexToAddress("0x3fc9faa15d71eed614e5322bd9554fb35cc381d2"), + common.HexToAddress("0xba6534da0e49c71cd9d0292203f1524876f33e23"), + }) + + require.Error(t, err) + }) + + t.Run("Verify fails if rawVs has been changed", func(t *testing.T) { + badReport := signedReport + badReport.RawVs = [32]byte{0x0011} + _, err := v.Verify(badReport, f, []common.Address{ + common.HexToAddress("0xde25e5b4005f611e356ce203900da4e37d72d58f"), + common.HexToAddress("0x256431d41cf0d944f5877bc6c93846a9829dfc03"), + common.HexToAddress("0x3fc9faa15d71eed614e5322bd9554fb35cc381d2"), + common.HexToAddress("0xba6534da0e49c71cd9d0292203f1524876f33e23"), + }) + + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to recover signature: invalid signature recovery id") + }) +} diff --git a/core/services/streams/stream.go b/core/services/streams/stream.go index 8825cd3b34..b65c6dc12f 100644 --- a/core/services/streams/stream.go +++ b/core/services/streams/stream.go @@ -3,12 +3,10 @@ package streams import ( "context" "fmt" - "math/big" "sync" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) type Runner interface { @@ -94,35 +92,3 @@ func (s *stream) executeRun(ctx context.Context) (*pipeline.Run, pipeline.TaskRu return run, trrs, err } - -// ExtractBigInt returns a result of a pipeline run that returns one single -// decimal result, as a *big.Int. -// This acts as a reference/example method, other methods can be implemented to -// extract any desired type that matches a particular pipeline run output. -// Returns error on parse errors: if results are wrong type -func ExtractBigInt(trrs pipeline.TaskRunResults) (*big.Int, error) { - // pipeline.TaskRunResults comes ordered asc by index, this is guaranteed - // by the pipeline executor - finaltrrs := trrs.Terminals() - - if len(finaltrrs) != 1 { - return nil, fmt.Errorf("invalid number of results, expected: 1, got: %d", len(finaltrrs)) - } - res := finaltrrs[0].Result - if res.Error != nil { - return nil, res.Error - } - val, err := toBigInt(res.Value) - if err != nil { - return nil, fmt.Errorf("failed to parse BenchmarkPrice: %w", err) - } - return val, nil -} - -func toBigInt(val interface{}) (*big.Int, error) { - dec, err := utils.ToDecimal(val) - if err != nil { - return nil, err - } - return dec.BigInt(), nil -} diff --git a/core/services/streams/stream_test.go b/core/services/streams/stream_test.go index 61e5187880..7817413812 100644 --- a/core/services/streams/stream_test.go +++ b/core/services/streams/stream_test.go @@ -2,7 +2,6 @@ package streams import ( "context" - "math/big" "testing" "time" @@ -99,35 +98,3 @@ succeed; }) }) } - -func Test_ExtractBigInt(t *testing.T) { - t.Run("wrong number of inputs", func(t *testing.T) { - trrs := []pipeline.TaskRunResult{} - - _, err := ExtractBigInt(trrs) - assert.EqualError(t, err, "invalid number of results, expected: 1, got: 0") - }) - t.Run("wrong type", func(t *testing.T) { - trrs := []pipeline.TaskRunResult{ - { - Result: pipeline.Result{Value: []byte{1, 2, 3}}, - Task: &MockTask{}, - }, - } - - _, err := ExtractBigInt(trrs) - assert.EqualError(t, err, "failed to parse BenchmarkPrice: type []uint8 cannot be converted to decimal.Decimal ([1 2 3])") - }) - t.Run("correct inputs", func(t *testing.T) { - trrs := []pipeline.TaskRunResult{ - { - Result: pipeline.Result{Value: "122.345"}, - Task: &MockTask{}, - }, - } - - val, err := ExtractBigInt(trrs) - require.NoError(t, err) - assert.Equal(t, big.NewInt(122), val) - }) -} diff --git a/core/store/migrate/migrations/0251_add_don_id_to_channel_definitions.sql b/core/store/migrate/migrations/0251_add_don_id_to_channel_definitions.sql new file mode 100644 index 0000000000..9c77592b0a --- /dev/null +++ b/core/store/migrate/migrations/0251_add_don_id_to_channel_definitions.sql @@ -0,0 +1,13 @@ +-- +goose Up +DELETE FROM channel_definitions; +ALTER TABLE channel_definitions DROP CONSTRAINT channel_definitions_pkey; +ALTER TABLE channel_definitions ADD COLUMN don_id bigint, ADD COLUMN version bigint; +ALTER TABLE channel_definitions RENAME COLUMN evm_chain_id TO chain_selector; +ALTER TABLE channel_definitions ALTER COLUMN chain_selector TYPE NUMERIC(20, 0); +ALTER TABLE channel_definitions ADD PRIMARY KEY (chain_selector, addr, don_id); + +-- +goose Down +ALTER TABLE channel_definitions DROP COLUMN don_id, DROP COLUMN version; +ALTER TABLE channel_definitions RENAME COLUMN chain_selector TO evm_chain_id; +ALTER TABLE channel_definitions ALTER COLUMN evm_chain_id TYPE bigint; +ALTER TABLE channel_definitions ADD PRIMARY KEY (evm_chain_id, addr); diff --git a/core/utils/http/http.go b/core/utils/http/http.go index 3336ac9f42..0c713f9662 100644 --- a/core/utils/http/http.go +++ b/core/utils/http/http.go @@ -7,7 +7,7 @@ import ( "net/url" "time" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink-common/pkg/logger" ) type httpClientConfig interface { @@ -38,9 +38,13 @@ func newDefaultTransport() *http.Transport { return t } +type HTTPClient interface { + Do(req *http.Request) (*http.Response, error) +} + // HTTPRequest holds the request and config struct for a http request type HTTPRequest struct { - Client *http.Client + Client HTTPClient Request *http.Request Config HTTPRequestConfig Logger logger.Logger @@ -48,35 +52,46 @@ type HTTPRequest struct { // HTTPRequestConfig holds the configurable settings for a http request type HTTPRequestConfig struct { + // SizeLimit in bytes SizeLimit int64 } -// SendRequest sends a HTTPRequest, -// returns a body, status code, and error. -func (h *HTTPRequest) SendRequest() (responseBody []byte, statusCode int, headers http.Header, err error) { +// SendRequestReader allows for streaming the body directly and does not read +// it all into memory +// +// CALLER IS RESPONSIBLE FOR CLOSING RETURNED RESPONSE BODY +func (h *HTTPRequest) SendRequestReader() (responseBody io.ReadCloser, statusCode int, headers http.Header, err error) { start := time.Now() - r, err := h.Client.Do(h.Request) if err != nil { - h.Logger.Tracew("http adapter got error", "err", err) + logger.Sugared(h.Logger).Tracew("http adapter got error", "err", err) return nil, 0, nil, err } - defer logger.Sugared(h.Logger).ErrorIfFn(r.Body.Close, "Error closing SendRequest response body") statusCode = r.StatusCode elapsed := time.Since(start) - h.Logger.Tracew(fmt.Sprintf("http adapter got %v in %s", statusCode, elapsed), "statusCode", statusCode, "timeElapsedSeconds", elapsed) + logger.Sugared(h.Logger).Tracew(fmt.Sprintf("http adapter got %v in %s", statusCode, elapsed), "statusCode", statusCode, "timeElapsedSeconds", elapsed) source := http.MaxBytesReader(nil, r.Body, h.Config.SizeLimit) - bytes, err := io.ReadAll(source) + + return source, statusCode, r.Header, nil +} + +// SendRequest sends a HTTPRequest, +// returns a body, status code, and error. +func (h *HTTPRequest) SendRequest() (responseBody []byte, statusCode int, headers http.Header, err error) { + start := time.Now() + + source, statusCode, headers, err := h.SendRequestReader() if err != nil { - h.Logger.Errorw("http adapter error reading body", "err", err) - return nil, statusCode, nil, err + return nil, statusCode, headers, err } - elapsed = time.Since(start) - h.Logger.Tracew(fmt.Sprintf("http adapter finished after %s", elapsed), "statusCode", statusCode, "timeElapsedSeconds", elapsed) + defer logger.Sugared(h.Logger).ErrorIfFn(source.Close, "Error closing SendRequest response body") + bytes, err := io.ReadAll(source) + elapsed := time.Since(start) + logger.Sugared(h.Logger).Tracew(fmt.Sprintf("http adapter finished after %s", elapsed), "statusCode", statusCode, "timeElapsedSeconds", elapsed) responseBody = bytes - return responseBody, statusCode, r.Header, nil + return responseBody, statusCode, headers, nil } diff --git a/core/utils/http/http_allowed_ips.go b/core/utils/http/http_allowed_ips.go index 6432e4ff91..2b77e89c7d 100644 --- a/core/utils/http/http_allowed_ips.go +++ b/core/utils/http/http_allowed_ips.go @@ -9,7 +9,7 @@ import ( "github.com/pkg/errors" "go.uber.org/multierr" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink-common/pkg/logger" ) var privateIPBlocks []*net.IPNet diff --git a/core/utils/utils.go b/core/utils/utils.go index d076284112..237f6a4358 100644 --- a/core/utils/utils.go +++ b/core/utils/utils.go @@ -481,6 +481,23 @@ func NewRedialBackoff() backoff.Backoff { } } +func NewHTTPFetchBackoff() backoff.Backoff { + return backoff.Backoff{ + Min: 100 * time.Millisecond, + Max: 15 * time.Second, + Jitter: true, + } +} + +// NewDBBackoff is a standard backoff to use for database connection issues +func NewDBBackoff() backoff.Backoff { + return backoff.Backoff{ + Min: 100 * time.Millisecond, + Max: 5 * time.Second, + Jitter: true, + } +} + // KeyedMutex allows to lock based on particular values type KeyedMutex struct { mutexes sync.Map From 32a2ccd2ba4cbe59e46779c82ec35c909141ba2a Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Fri, 23 Aug 2024 21:55:09 +0100 Subject: [PATCH 161/432] KS-398 gas limit on tx meta (#14214) * change to make gas limit sendeable on transaction submit and make the default limit configurable * fix tests * fix docs test --------- Co-authored-by: Bolek Kulbabinski <1416262+bolekk@users.noreply.github.com> --- .changeset/mighty-points-switch.md | 5 ++ .../keystone_contracts_setup.go | 6 ++ core/capabilities/targets/write_target.go | 32 +++++++--- .../capabilities/targets/write_target_test.go | 59 +++++++++++++++++-- .../evm/config/chain_scoped_workflow.go | 4 ++ core/chains/evm/config/config.go | 1 + core/chains/evm/config/toml/config.go | 15 +++-- .../evm/config/toml/defaults/fallback.toml | 3 + core/config/docs/chains-evm.toml | 2 + core/config/docs/docs_test.go | 3 + core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/relay/evm/chain_writer.go | 7 ++- core/services/relay/evm/evm.go | 3 +- core/services/relay/evm/write_target.go | 7 +-- core/services/relay/evm/write_target_test.go | 8 ++- docs/CONFIG.md | 7 +++ go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 23 files changed, 147 insertions(+), 39 deletions(-) create mode 100644 .changeset/mighty-points-switch.md diff --git a/.changeset/mighty-points-switch.md b/.changeset/mighty-points-switch.md new file mode 100644 index 0000000000..c42913ad11 --- /dev/null +++ b/.changeset/mighty-points-switch.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal allow gas limit to be specified when submitting transaction diff --git a/core/capabilities/integration_tests/keystone_contracts_setup.go b/core/capabilities/integration_tests/keystone_contracts_setup.go index b138b8f812..fbd3da5cc5 100644 --- a/core/capabilities/integration_tests/keystone_contracts_setup.go +++ b/core/capabilities/integration_tests/keystone_contracts_setup.go @@ -241,6 +241,12 @@ func setupCapabilitiesRegistryContract(ctx context.Context, t *testing.T, workfl require.NoError(t, err) targetCapabilityConfig := newCapabilityConfig() + + configWithLimit, err := values.WrapMap(map[string]any{"gasLimit": 500000}) + require.NoError(t, err) + + targetCapabilityConfig.DefaultConfig = values.Proto(configWithLimit).GetMapValue() + targetCapabilityConfig.RemoteConfig = &pb.CapabilityConfig_RemoteTargetConfig{ RemoteTargetConfig: &pb.RemoteTargetConfig{ RequestHashExcludedAttributes: []string{"signed_report.Signatures"}, diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index da9841948d..eb3a390de4 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -107,6 +107,8 @@ func decodeReportMetadata(data []byte) (metadata ReportV1Metadata, err error) { type Config struct { // Address of the contract that will get the forwarded report Address string + // Optional gas limit that overrides the default limit sent to the chain writer + GasLimit *uint64 } type Inputs struct { @@ -222,19 +224,23 @@ func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.Cap switch { case transmissionInfo.State == 0: // NOT_ATTEMPTED - cap.lggr.Infow("non-empty report - tranasmission not attempted - attempting to push to txmgr", "request", request, "reportLen", len(request.Inputs.SignedReport.Report), "reportContextLen", len(request.Inputs.SignedReport.Context), "nSignatures", len(request.Inputs.SignedReport.Signatures), "executionID", request.Metadata.WorkflowExecutionID) + cap.lggr.Infow("non-empty report - transmission not attempted - attempting to push to txmgr", "request", request, "reportLen", len(request.Inputs.SignedReport.Report), "reportContextLen", len(request.Inputs.SignedReport.Context), "nSignatures", len(request.Inputs.SignedReport.Signatures), "executionID", request.Metadata.WorkflowExecutionID) case transmissionInfo.State == 1: // SUCCEEDED - cap.lggr.Infow("returning without a tranmission attempt - report already onchain ", "executionID", request.Metadata.WorkflowExecutionID) + cap.lggr.Infow("returning without a transmission attempt - report already onchain ", "executionID", request.Metadata.WorkflowExecutionID) return success(), nil case transmissionInfo.State == 2: // INVALID_RECEIVER - cap.lggr.Infow("returning without a tranmission attempt - transmission already attempted, receiver was marked as invalid", "executionID", request.Metadata.WorkflowExecutionID) + cap.lggr.Infow("returning without a transmission attempt - transmission already attempted, receiver was marked as invalid", "executionID", request.Metadata.WorkflowExecutionID) return success(), nil case transmissionInfo.State == 3: // FAILED - if transmissionInfo.GasLimit.Uint64() > cap.receiverGasMinimum { - cap.lggr.Infow("returning without a tranmission attempt - transmission already attempted and failed, sufficient gas was provided", "executionID", request.Metadata.WorkflowExecutionID, "receiverGasMinimum", cap.receiverGasMinimum, "transmissionGasLimit", transmissionInfo.GasLimit) + receiverGasMinimum := cap.receiverGasMinimum + if request.Config.GasLimit != nil { + receiverGasMinimum = *request.Config.GasLimit - FORWARDER_CONTRACT_LOGIC_GAS_COST + } + if transmissionInfo.GasLimit.Uint64() > receiverGasMinimum { + cap.lggr.Infow("returning without a transmission attempt - transmission already attempted and failed, sufficient gas was provided", "executionID", request.Metadata.WorkflowExecutionID, "receiverGasMinimum", receiverGasMinimum, "transmissionGasLimit", transmissionInfo.GasLimit) return success(), nil } else { - cap.lggr.Infow("non-empty report - retrying a failed transmission - attempting to push to txmgr", "request", request, "reportLen", len(request.Inputs.SignedReport.Report), "reportContextLen", len(request.Inputs.SignedReport.Context), "nSignatures", len(request.Inputs.SignedReport.Signatures), "executionID", request.Metadata.WorkflowExecutionID, "receiverGasMinimum", cap.receiverGasMinimum, "transmissionGasLimit", transmissionInfo.GasLimit) + cap.lggr.Infow("non-empty report - retrying a failed transmission - attempting to push to txmgr", "request", request, "reportLen", len(request.Inputs.SignedReport.Report), "reportContextLen", len(request.Inputs.SignedReport.Context), "nSignatures", len(request.Inputs.SignedReport.Signatures), "executionID", request.Metadata.WorkflowExecutionID, "receiverGasMinimum", receiverGasMinimum, "transmissionGasLimit", transmissionInfo.GasLimit) } default: return nil, fmt.Errorf("unexpected transmission state: %v", transmissionInfo.State) @@ -269,10 +275,22 @@ func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.Cap cap.lggr.Debugw("Transaction raw report", "report", hex.EncodeToString(req.RawReport)) meta := commontypes.TxMeta{WorkflowExecutionID: &request.Metadata.WorkflowExecutionID} + if request.Config.GasLimit != nil { + meta.GasLimit = new(big.Int).SetUint64(*request.Config.GasLimit) + } + value := big.NewInt(0) if err := cap.cw.SubmitTransaction(ctx, "forwarder", "report", req, txID.String(), cap.forwarderAddress, &meta, value); err != nil { - return nil, err + if commontypes.ErrSettingTransactionGasLimitNotSupported.Is(err) { + meta.GasLimit = nil + if err := cap.cw.SubmitTransaction(ctx, "forwarder", "report", req, txID.String(), cap.forwarderAddress, &meta, value); err != nil { + return nil, fmt.Errorf("failed to submit transaction: %w", err) + } + } else { + return nil, fmt.Errorf("failed to submit transaction: %w", err) + } } + cap.lggr.Debugw("Transaction submitted", "request", request, "transaction", txID) return success(), nil } diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go index 522fee3251..9f7b6a2de2 100644 --- a/core/capabilities/targets/write_target_test.go +++ b/core/capabilities/targets/write_target_test.go @@ -86,7 +86,7 @@ func TestWriteTarget(t *testing.T) { TransmissionId: [32]byte{}, Transmitter: common.HexToAddress("0x0"), } - }).Once() + }) cw.On("SubmitTransaction", mock.Anything, "forwarder", "report", mock.Anything, mock.Anything, forwarderAddr, mock.Anything, mock.Anything).Return(nil).Once() @@ -103,25 +103,74 @@ func TestWriteTarget(t *testing.T) { require.NotNil(t, response) }) - t.Run("fails when ChainReader's GetLatestValue returns error", func(t *testing.T) { + t.Run("fails when ChainWriter's SubmitTransaction returns error", func(t *testing.T) { req := capabilities.CapabilityRequest{ Metadata: validMetadata, Config: config, Inputs: validInputs, } - cr.On("GetLatestValue", mock.Anything, "forwarder", "getTransmissionInfo", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("reader error")) + cw.On("SubmitTransaction", mock.Anything, "forwarder", "report", mock.Anything, mock.Anything, forwarderAddr, mock.Anything, mock.Anything).Return(errors.New("writer error")) _, err = writeTarget.Execute(ctx, req) require.Error(t, err) }) - t.Run("fails when ChainWriter's SubmitTransaction returns error", func(t *testing.T) { + t.Run("passes gas limit set on config to the chain writer", func(t *testing.T) { + configGasLimit, err := values.NewMap(map[string]any{ + "Address": forwarderAddr, + "GasLimit": 500000, + }) + require.NoError(t, err) + req := capabilities.CapabilityRequest{ + Metadata: validMetadata, + Config: configGasLimit, + Inputs: validInputs, + } + + meta := types.TxMeta{WorkflowExecutionID: &req.Metadata.WorkflowExecutionID, GasLimit: big.NewInt(500000)} + cw.On("SubmitTransaction", mock.Anything, "forwarder", "report", mock.Anything, mock.Anything, forwarderAddr, &meta, mock.Anything).Return(types.ErrSettingTransactionGasLimitNotSupported) + + _, err2 := writeTarget.Execute(ctx, req) + require.Error(t, err2) + }) + + t.Run("retries without gas limit when ChainWriter's SubmitTransaction returns error due to gas limit not supported", func(t *testing.T) { + configGasLimit, err := values.NewMap(map[string]any{ + "Address": forwarderAddr, + "GasLimit": 500000, + }) + require.NoError(t, err) + req := capabilities.CapabilityRequest{ + Metadata: validMetadata, + Config: configGasLimit, + Inputs: validInputs, + } + + meta := types.TxMeta{WorkflowExecutionID: &req.Metadata.WorkflowExecutionID, GasLimit: big.NewInt(500000)} + cw.On("SubmitTransaction", mock.Anything, "forwarder", "report", mock.Anything, mock.Anything, forwarderAddr, &meta, mock.Anything).Return(types.ErrSettingTransactionGasLimitNotSupported) + meta = types.TxMeta{WorkflowExecutionID: &req.Metadata.WorkflowExecutionID} + cw.On("SubmitTransaction", mock.Anything, "forwarder", "report", mock.Anything, mock.Anything, forwarderAddr, &meta, mock.Anything).Return(nil) + + configGasLimit, err = values.NewMap(map[string]any{ + "Address": forwarderAddr, + }) + req = capabilities.CapabilityRequest{ + Metadata: validMetadata, + Config: configGasLimit, + Inputs: validInputs, + } + + _, err2 := writeTarget.Execute(ctx, req) + require.Error(t, err2) + }) + + t.Run("fails when ChainReader's GetLatestValue returns error", func(t *testing.T) { req := capabilities.CapabilityRequest{ Metadata: validMetadata, Config: config, Inputs: validInputs, } - cw.On("SubmitTransaction", mock.Anything, "forwarder", "report", mock.Anything, mock.Anything, forwarderAddr, mock.Anything, mock.Anything).Return(errors.New("writer error")) + cr.On("GetLatestValue", mock.Anything, "forwarder", "getTransmissionInfo", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("reader error")) _, err = writeTarget.Execute(ctx, req) require.Error(t, err) diff --git a/core/chains/evm/config/chain_scoped_workflow.go b/core/chains/evm/config/chain_scoped_workflow.go index 36dcb3ea41..42bc8aed95 100644 --- a/core/chains/evm/config/chain_scoped_workflow.go +++ b/core/chains/evm/config/chain_scoped_workflow.go @@ -16,3 +16,7 @@ func (b *workflowConfig) FromAddress() *types.EIP55Address { func (b *workflowConfig) ForwarderAddress() *types.EIP55Address { return b.c.ForwarderAddress } + +func (b *workflowConfig) DefaultGasLimit() uint64 { + return b.c.DefaultGasLimit +} diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index 9517c68716..aeb39cbf8d 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -161,6 +161,7 @@ type BlockHistory interface { type Workflow interface { FromAddress() *types.EIP55Address ForwarderAddress() *types.EIP55Address + DefaultGasLimit() uint64 } type NodePool interface { diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 99e61a394b..8b926bf087 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -521,6 +521,7 @@ func (a *Automation) setFrom(f *Automation) { type Workflow struct { FromAddress *types.EIP55Address `toml:",omitempty"` ForwarderAddress *types.EIP55Address `toml:",omitempty"` + DefaultGasLimit uint64 } func (m *Workflow) setFrom(f *Workflow) { @@ -530,6 +531,8 @@ func (m *Workflow) setFrom(f *Workflow) { if v := f.ForwarderAddress; v != nil { m.ForwarderAddress = v } + + m.DefaultGasLimit = f.DefaultGasLimit } type BalanceMonitor struct { @@ -549,12 +552,12 @@ type GasEstimator struct { PriceMax *assets.Wei PriceMin *assets.Wei - LimitDefault *uint64 - LimitMax *uint64 - LimitMultiplier *decimal.Decimal - LimitTransfer *uint64 - LimitJobType GasLimitJobType `toml:",omitempty"` - EstimateGasLimit *bool + LimitDefault *uint64 + LimitMax *uint64 + LimitMultiplier *decimal.Decimal + LimitTransfer *uint64 + LimitJobType GasLimitJobType `toml:",omitempty"` + EstimateGasLimit *bool BumpMin *assets.Wei BumpPercent *uint16 diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index 6dd02a8fd5..a3def55b4a 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -84,3 +84,6 @@ ObservationGracePeriod = '1s' [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +DefaultGasLimit = 400_000 diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index b9a256ddf4..2186f502f4 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -469,3 +469,5 @@ GasLimit = 5400000 # Default FromAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example # ForwarderAddress is the keystone forwarder contract address on chain. ForwarderAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example +# DefaultGasLimit is the default gas limit for workflow transactions. +DefaultGasLimit = 400_000 # Default diff --git a/core/config/docs/docs_test.go b/core/config/docs/docs_test.go index 8f46497cb5..7a7d665044 100644 --- a/core/config/docs/docs_test.go +++ b/core/config/docs/docs_test.go @@ -83,8 +83,11 @@ func TestDoc(t *testing.T) { docDefaults.OperatorFactoryAddress = nil require.Empty(t, docDefaults.Workflow.FromAddress) require.Empty(t, docDefaults.Workflow.ForwarderAddress) + require.Equal(t, uint64(400_000), docDefaults.Workflow.DefaultGasLimit) + docDefaults.Workflow.FromAddress = nil docDefaults.Workflow.ForwarderAddress = nil + docDefaults.Workflow.DefaultGasLimit = uint64(400_000) docDefaults.NodePool.Errors = evmcfg.ClientErrors{} // Transactions.AutoPurge configs are only set if the feature is enabled diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 27073b9ab1..765accddc0 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 217c2c19e2..ba0c66277b 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1186,8 +1186,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 h1:+XvRzgHlcaZYLMJ5HR3HzOjvXNmpVKQFZbuHZiRno68= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 h1:W8jK09xMKjhnduR4FsyM2aQKe+4/K1EsAhfJQgv2DEk= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= diff --git a/core/services/relay/evm/chain_writer.go b/core/services/relay/evm/chain_writer.go index c456726379..6f30ceb4bb 100644 --- a/core/services/relay/evm/chain_writer.go +++ b/core/services/relay/evm/chain_writer.go @@ -122,11 +122,16 @@ func (w *chainWriter) SubmitTransaction(ctx context.Context, contract, method st } } + gasLimit := methodConfig.GasLimit + if meta != nil && meta.GasLimit != nil { + gasLimit = meta.GasLimit.Uint64() + } + req := evmtxmgr.TxRequest{ FromAddress: methodConfig.FromAddress, ToAddress: common.HexToAddress(toAddress), EncodedPayload: calldata, - FeeLimit: methodConfig.GasLimit, + FeeLimit: gasLimit, Meta: txMeta, IdempotencyKey: &transactionID, Strategy: w.sendStrategy, diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 7b85268d11..ee22f19814 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -212,7 +212,8 @@ func NewRelayer(lggr logger.Logger, chain legacyevm.Chain, opts RelayerOpts) (*R // Initialize write target capability if configuration is defined if chain.Config().EVM().Workflow().ForwarderAddress() != nil { ctx := context.Background() - capability, err := NewWriteTarget(ctx, relayer, chain, lggr) + capability, err := NewWriteTarget(ctx, relayer, chain, chain.Config().EVM().Workflow().DefaultGasLimit(), + lggr) if err != nil { return nil, fmt.Errorf("failed to initialize write target: %w", err) } diff --git a/core/services/relay/evm/write_target.go b/core/services/relay/evm/write_target.go index 699c5013ea..69ee23ee85 100644 --- a/core/services/relay/evm/write_target.go +++ b/core/services/relay/evm/write_target.go @@ -15,7 +15,7 @@ import ( relayevmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) -func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain, lggr logger.Logger) (*targets.WriteTarget, error) { +func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain, defaultGasLimit uint64, lggr logger.Logger) (*targets.WriteTarget, error) { // generate ID based on chain selector id := fmt.Sprintf("write_%v@1.0.0", chain.ID()) chainName, err := chainselectors.NameFromChainId(chain.ID().Uint64()) @@ -47,7 +47,6 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain return nil, err } - var gasLimit uint64 = 400_000 chainWriterConfig := relayevmtypes.ChainWriterConfig{ Contracts: map[string]*relayevmtypes.ContractConfig{ "forwarder": { @@ -57,7 +56,7 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain ChainSpecificName: "report", Checker: "simulate", FromAddress: config.FromAddress().Address(), - GasLimit: gasLimit, + GasLimit: defaultGasLimit, }, }, }, @@ -75,5 +74,5 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain return nil, err } - return targets.NewWriteTarget(logger.Named(lggr, "WriteTarget"), id, cr, cw, config.ForwarderAddress().String(), gasLimit), nil + return targets.NewWriteTarget(logger.Named(lggr, "WriteTarget"), id, cr, cw, config.ForwarderAddress().String(), defaultGasLimit), nil } diff --git a/core/services/relay/evm/write_target_test.go b/core/services/relay/evm/write_target_test.go index 54e3671422..67e45228cf 100644 --- a/core/services/relay/evm/write_target_test.go +++ b/core/services/relay/evm/write_target_test.go @@ -196,9 +196,11 @@ func TestEvmWrite(t *testing.T) { require.Equal(t, signatures, payload["signatures"]) }).Once() + defaultGasLimit := uint64(400_000) + t.Run("succeeds with valid report", func(t *testing.T) { ctx := testutils.Context(t) - capability, err := evm.NewWriteTarget(ctx, relayer, chain, lggr) + capability, err := evm.NewWriteTarget(ctx, relayer, chain, defaultGasLimit, lggr) require.NoError(t, err) req := capabilities.CapabilityRequest{ @@ -216,7 +218,7 @@ func TestEvmWrite(t *testing.T) { t.Run("fails with invalid config", func(t *testing.T) { ctx := testutils.Context(t) - capability, err := evm.NewWriteTarget(ctx, relayer, chain, logger.TestLogger(t)) + capability, err := evm.NewWriteTarget(ctx, relayer, chain, defaultGasLimit, logger.TestLogger(t)) require.NoError(t, err) invalidConfig, err := values.NewMap(map[string]any{ @@ -236,7 +238,7 @@ func TestEvmWrite(t *testing.T) { t.Run("fails when TXM CreateTransaction returns error", func(t *testing.T) { ctx := testutils.Context(t) - capability, err := evm.NewWriteTarget(ctx, relayer, chain, logger.TestLogger(t)) + capability, err := evm.NewWriteTarget(ctx, relayer, chain, defaultGasLimit, logger.TestLogger(t)) require.NoError(t, err) req := capabilities.CapabilityRequest{ diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 32ab35b7cc..7c54682367 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -8588,6 +8588,7 @@ GasLimit controls the gas limit for transmit transactions from ocr2automation jo [EVM.Workflow] FromAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example ForwarderAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example +DefaultGasLimit = 400_000 # Default ``` @@ -8603,6 +8604,12 @@ ForwarderAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example ``` ForwarderAddress is the keystone forwarder contract address on chain. +### DefaultGasLimit +```toml +DefaultGasLimit = 400_000 # Default +``` +DefaultGasLimit is the default gas limit for workflow transactions. + ## Cosmos ```toml [[Cosmos]] diff --git a/go.mod b/go.mod index 22df244575..7210941bd0 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index 13f045ef2c..fb9d877c56 100644 --- a/go.sum +++ b/go.sum @@ -1141,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 h1:+XvRzgHlcaZYLMJ5HR3HzOjvXNmpVKQFZbuHZiRno68= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 h1:W8jK09xMKjhnduR4FsyM2aQKe+4/K1EsAhfJQgv2DEk= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 708a369fc9..d50ac2673e 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -33,7 +33,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 github.com/smartcontractkit/chainlink-testing-framework v1.34.6 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index b8c3d5c94a..5bd93085ea 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1519,8 +1519,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 h1:+XvRzgHlcaZYLMJ5HR3HzOjvXNmpVKQFZbuHZiRno68= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 h1:W8jK09xMKjhnduR4FsyM2aQKe+4/K1EsAhfJQgv2DEk= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index ba5c1d3ef9..b0b65ac384 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 github.com/smartcontractkit/chainlink-testing-framework v1.34.6 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 7f6dddca8d..2f92d1e6b4 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1499,8 +1499,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5 h1:+XvRzgHlcaZYLMJ5HR3HzOjvXNmpVKQFZbuHZiRno68= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823093917-c07a4fa0caa5/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 h1:W8jK09xMKjhnduR4FsyM2aQKe+4/K1EsAhfJQgv2DEk= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= From 6b2fa6f86de4bbc1b41ce44aa45190044f40517e Mon Sep 17 00:00:00 2001 From: Brad Miller Date: Fri, 23 Aug 2024 15:18:12 -0600 Subject: [PATCH 162/432] Add keystone codeowner (#14218) * Update CODEOWNERS Adding keystone tag as codeowner * fix CODEOWNERS typo --- .github/CODEOWNERS | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c7eb22991b..0e686b024f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -62,11 +62,10 @@ core/scripts/gateway @smartcontractkit/functions /contracts/**/*upkeep* @smartcontractkit/keepers /contracts/**/*automation* @smartcontractkit/keepers /contracts/**/*functions* @smartcontractkit/functions -/contracts/**/*llo-feeds* @smartcontrackit/mercury-team +/contracts/**/*llo-feeds* @smartcontractkit/mercury-team /contracts/**/*vrf* @smartcontractkit/vrf-team /contracts/**/*l2ep* @smartcontractkit/bix-ship -# TODO: replace with a team tag when ready -/contracts/**/*keystone* @archseer @bolekk @patrick-dowell +/contracts/**/*keystone* @smartcontractkit/keystone /contracts/src/v0.8/automation @smartcontractkit/keepers /contracts/src/v0.8/functions @smartcontractkit/functions From 0352a7d79db26b6f32f2ea8695a3cd11e32046c4 Mon Sep 17 00:00:00 2001 From: Austin Born Date: Sun, 25 Aug 2024 10:31:07 -0700 Subject: [PATCH 163/432] Update Op Forwarder code owner to Data Feeds Eng (#14222) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0e686b024f..b021b8de37 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -73,7 +73,7 @@ core/scripts/gateway @smartcontractkit/functions /contracts/src/v0.8/l2ep @chris-de-leon-cll /contracts/src/v0.8/llo-feeds @smartcontractkit/mercury-team # TODO: mocks folder, folder should be removed and files moved to the correct folders -/contracts/src/v0.8/operatorforwarder @austinborn +/contracts/src/v0.8/operatorforwarder @smartcontractkit/data-feeds-engineers /contracts/src/v0.8/shared @RensR # TODO: tests folder, folder should be removed and files moved to the correct folders # TODO: transmission folder, owner should be found From 445dd3c2534a310e2d86c58b512166869e83c2a8 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Mon, 26 Aug 2024 10:23:27 +0200 Subject: [PATCH 164/432] Add test_secrets_override_key to remaining workflows that use base64TestConfig (#14211) * Add test_secrets_override_key to remaining workflows * Remove unused workflow Confirmed with Bartek Tofel --- .../workflows/automation-benchmark-tests.yml | 6 ++++ .../workflows/automation-nightly-tests.yml | 33 ++++++++---------- .github/workflows/on-demand-log-poller.yml | 34 ------------------- 3 files changed, 21 insertions(+), 52 deletions(-) delete mode 100644 .github/workflows/on-demand-log-poller.yml diff --git a/.github/workflows/automation-benchmark-tests.yml b/.github/workflows/automation-benchmark-tests.yml index c21171a83d..c5ee22cbfd 100644 --- a/.github/workflows/automation-benchmark-tests.yml +++ b/.github/workflows/automation-benchmark-tests.yml @@ -16,6 +16,11 @@ on: required: true default: U02Q14G80TY type: string + test_secrets_override_key: + description: 'Key to run tests with custom test secrets' + required: false + type: string + jobs: automation_benchmark: environment: integration @@ -80,6 +85,7 @@ jobs: with: test_command_to_run: cd integration-tests && go test -timeout 30m -v -run ^TestAutomationBenchmark$ ./benchmark -count=1 test_download_vendor_packages_command: make gomod + test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/automation-nightly-tests.yml b/.github/workflows/automation-nightly-tests.yml index f018124624..437bc5e2be 100644 --- a/.github/workflows/automation-nightly-tests.yml +++ b/.github/workflows/automation-nightly-tests.yml @@ -96,27 +96,24 @@ jobs: api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} # other inputs duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-upgrade-config - with: - selectedNetworks: ${{ env.SELECTED_NETWORKS }} - chainlinkImage: "public.ecr.aws/chainlink/chainlink" - chainlinkVersion: "latest" - upgradeImage: ${{ env.CHAINLINK_IMAGE }} - upgradeVersion: ${{ github.sha }} - runId: ${{ github.run_id }} - testLogCollect: "true" - lokiEndpoint: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - lokiTenantId: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - lokiBasicAuth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c164251be2a7c5b2b23a6e5f7014982f232c14 # v2.3.32 env: TEST_SUITE: ${{ matrix.tests.suite }} + E2E_TEST_SELECTED_NETWORK: ${{ env.SELECTED_NETWORKS }} + E2E_TEST_CHAINLINK_IMAGE: "public.ecr.aws/chainlink/chainlink" + E2E_TEST_CHAINLINK_VERSION: "latest" + E2E_TEST_CHAINLINK_UPGRADE_IMAGE: ${{ env.CHAINLINK_IMAGE }} + E2E_TEST_CHAINLINK_UPGRADE_VERSION: ${{ github.sha }} + E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} + E2E_TEST_LOG_COLLECT: "true" + E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + E2E_TEST_LOG_STREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} + E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" + E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} with: test_command_to_run: cd ./integration-tests && go test -timeout 60m -count=1 -json -test.parallel=${{ matrix.tests.nodes }} ${{ matrix.tests.command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download diff --git a/.github/workflows/on-demand-log-poller.yml b/.github/workflows/on-demand-log-poller.yml deleted file mode 100644 index 1685c7e455..0000000000 --- a/.github/workflows/on-demand-log-poller.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: On Demand Log Poller Consistency Test -on: - workflow_dispatch: - inputs: - base64Config: - description: base64-ed config - required: true - type: string - -jobs: - test: - env: - REF_NAME: ${{ github.head_ref || github.ref_name }} - runs-on: ubuntu22.04-8cores-32GB - steps: - - name: Add masks and export base64 config - run: | - BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64Config' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ env.REF_NAME }} - - name: Setup Go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 - with: - go-version-file: "integration-tests/go.mod" - cache: true - - name: Run tests - run: | - cd integration-tests - go mod download - go test -v -timeout 5h -v -count=1 -run ^TestLogPollerFewFiltersFixedDepth$ ./smoke/log_poller_test.go From a749e652572269cb774357ba92a43ef578780657 Mon Sep 17 00:00:00 2001 From: Cedric Date: Mon, 26 Aug 2024 12:22:45 +0100 Subject: [PATCH 165/432] Fix flakey test runner (#14226) --- .github/workflows/ci-core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 74369493eb..ba89ab4045 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -319,7 +319,7 @@ jobs: -gh_run_id=$GITHUB_RUN_ID \ -gh_repo=$GITHUB_REPO \ -command=./tools/bin/go_core_tests \ - `ls -R ./artifacts/go_core_tests*/output.txt` + `ls -R ./artifacts/output.txt` - name: Store logs artifacts if: ${{ needs.filter.outputs.changes == 'true' && always() }} uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 From 3d2efc3e4b5c39fc96c93412fe2b6b86720a3579 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Mon, 26 Aug 2024 14:40:13 +0200 Subject: [PATCH 166/432] [TT-1505] fix name of step used to generate changesets (#14217) * fix name of step used to generate changesets * copy foundry.toml to root before Slither * remove retention period (use default), add base_ref to artifact name * add comment to 'invalid' input --- .../workflows/solidity-foundry-artifacts.yml | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/.github/workflows/solidity-foundry-artifacts.yml b/.github/workflows/solidity-foundry-artifacts.yml index 9bba72b2e4..061caf1ea7 100644 --- a/.github/workflows/solidity-foundry-artifacts.yml +++ b/.github/workflows/solidity-foundry-artifacts.yml @@ -34,7 +34,6 @@ jobs: name: Detect changes runs-on: ubuntu-latest outputs: - changes: ${{ steps.changes.outputs.sol }} product_changes: ${{ steps.changes-transform.outputs.product_changes }} product_files: ${{ steps.changes-transform.outputs.product_files }} changeset_changes: ${{ steps.changes-dorny.outputs.changeset }} @@ -46,10 +45,11 @@ jobs: ref: ${{ inputs.commit_to_use || github.sha }} - name: Find modified contracts uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 - id: changes + id: changes-dorny with: list-files: 'csv' base: ${{ inputs.base_ref }} + # This is a valid input, see https://github.com/dorny/paths-filter/pull/226 predicate-quantifier: every filters: | ignored: &ignored @@ -81,33 +81,33 @@ jobs: run: | if [ "${{ inputs.product }}" = "shared" ]; then echo "::debug:: Product is shared, transforming changes" - if [[ "${{ steps.changes.outputs.product }}" == "true" && "${{ steps.changes.outputs.other_shared }}" == "true" ]]; then + if [[ "${{ steps.changes-dorny.outputs.product }}" == "true" && "${{ steps.changes-dorny.outputs.other_shared }}" == "true" ]]; then echo "::debug:: Changes were found in 'shared' folder and in 'interfaces' and root folders" echo "product_changes=true" >> $GITHUB_OUTPUT - echo "product_files=${{ steps.changes.outputs.product_files }},${{ steps.changes.outputs.other_shared_files }}" >> $GITHUB_OUTPUT - elif [[ "${{ steps.changes.outputs.product }}" == "false" && "${{ steps.changes.outputs.other_shared }}" == "true" ]]; then + echo "product_files=${{ steps.changes-dorny.outputs.product_files }},${{ steps.changes-dorny.outputs.other_shared_files }}" >> $GITHUB_OUTPUT + elif [[ "${{ steps.changes-dorny.outputs.product }}" == "false" && "${{ steps.changes-dorny.outputs.other_shared }}" == "true" ]]; then echo "::debug:: Only contracts in' interfaces' and root folders were modified" echo "product_changes=true" >> $GITHUB_OUTPUT - echo "product_files=${{ steps.changes.outputs.other_shared_files }}" >> $GITHUB_OUTPUT - elif [[ "${{ steps.changes.outputs.product }}" == "true" && "${{ steps.changes.outputs.other_shared }}" == "false" ]]; then + echo "product_files=${{ steps.changes-dorny.outputs.other_shared_files }}" >> $GITHUB_OUTPUT + elif [[ "${{ steps.changes-dorny.outputs.product }}" == "true" && "${{ steps.changes-dorny.outputs.other_shared }}" == "false" ]]; then echo "::debug:: Only contracts in 'shared' folder were modified" echo "product_changes=true" >> $GITHUB_OUTPUT - echo "product_files=${{ steps.changes.outputs.product_files }}" >> $GITHUB_OUTPUT + echo "product_files=${{ steps.changes-dorny.outputs.product_files }}" >> $GITHUB_OUTPUT else echo "::debug:: No contracts were modified" echo "product_changes=false" >> $GITHUB_OUTPUT echo "product_files=" >> $GITHUB_OUTPUT fi else - echo "product_changes=${{ steps.changes.outputs.product }}" >> $GITHUB_OUTPUT - echo "product_files=${{ steps.changes.outputs.product_files }}" >> $GITHUB_OUTPUT + echo "product_changes=${{ steps.changes-dorny.outputs.product }}" >> $GITHUB_OUTPUT + echo "product_files=${{ steps.changes-dorny.outputs.product_files }}" >> $GITHUB_OUTPUT fi - name: Check for changes outside of artifact scope uses: ./.github/actions/validate-artifact-scope - if: ${{ steps.changes.outputs.sol == 'true' }} + if: ${{ steps.changes-dorny.outputs.sol == 'true' }} with: - sol_files: ${{ steps.changes.outputs.sol_files }} + sol_files: ${{ steps.changes-dorny.outputs.sol_files }} product: ${{ inputs.product }} gather-basic-info: @@ -134,7 +134,7 @@ jobs: run: | mkdir -p contracts/changesets files="${{ needs.changes.outputs.changeset_files }}" - IFS=",' + IFS="," for changeset in $files; do echo "::debug:: Copying $changeset" cp $changeset contracts/changesets @@ -303,7 +303,7 @@ jobs: # modify remappings so that solc can find dependencies ./contracts/scripts/ci/modify_remappings.sh contracts contracts/remappings.txt - mv remappings_modified.txt remappings.txt + mv remappings_modified.txt remappings.txt ./contracts/scripts/ci/generate_uml.sh "./" "contracts/uml-diagrams" "$contract_list" @@ -311,6 +311,9 @@ jobs: run: | contract_list="${{ needs.changes.outputs.product_files }}" + # without it Slither sometimes fails to use remappings correctly + cp contracts/foundry.toml foundry.toml + echo "::debug::Processing contracts: $contract_list" ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ inputs.commit_to_use || github.sha }}/" contracts/configs/slither/.slither.config-artifacts.json "." "$contract_list" "contracts/slither-reports" "--solc-remaps @=contracts/node_modules/@" @@ -349,9 +352,8 @@ jobs: - name: Upload all artifacts as single package uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: - name: review-artifacts-${{ inputs.product }}-${{ inputs.commit_to_use || github.sha }} + name: review-artifacts-${{ inputs.product }}-${{ inputs.base_ref }}-${{ inputs.commit_to_use || github.sha }} path: review_artifacts - retention-days: 60 - name: Remove temporary artifacts uses: geekyeggo/delete-artifact@24928e75e6e6590170563b8ddae9fac674508aa1 # v5.0 From 3257b8fe00c59049cac7452f60c6886e346d2e69 Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs <5300706+iljapavlovs@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:42:52 +0300 Subject: [PATCH 167/432] =?UTF-8?q?DEVSVCS-138:=20adding=20default=20test?= =?UTF-8?q?=20config=20for=20VRF=20CTF=20tests;=20adding=20abi=E2=80=A6=20?= =?UTF-8?q?(#14184)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * DEVSVCS-138: adding default test config for VRF CTF tests; adding ability to deploy Test Coordinator, Arbitrum Coordinator for V2Plus, also Arbitrum Wrapper * DEVSVCS-138: fixing lint solidity issues --- contracts/scripts/native_solc_compile_all_vrf | 1 + .../testhelpers/VRFCoordinatorTestV2_5.sol | 773 ++++ .../src/v0.8/vrf/dev/testhelpers/VRFOld.sol | 588 +++ .../vrf_coordinator_test_v2_5.go | 3994 +++++++++++++++++ ...rapper-dependency-versions-do-not-edit.txt | 1 + core/gethwrappers/go_generate.go | 1 + integration-tests/actions/actions.go | 5 + .../actions/vrf/vrfv2/setup_steps.go | 40 +- .../actions/vrf/vrfv2plus/contract_steps.go | 27 + .../actions/vrf/vrfv2plus/setup_steps.go | 5 +- .../contracts/ethereum_vrfv2plus_contracts.go | 105 +- integration-tests/load/vrfv2/vrfv2_test.go | 4 +- integration-tests/testconfig/vrfv2/vrfv2.toml | 1 + .../testconfig/vrfv2plus/config.go | 5 + .../testconfig/vrfv2plus/vrfv2plus.toml | 192 +- 15 files changed, 5694 insertions(+), 48 deletions(-) create mode 100644 contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorTestV2_5.sol create mode 100644 contracts/src/v0.8/vrf/dev/testhelpers/VRFOld.sol create mode 100644 core/gethwrappers/generated/vrf_coordinator_test_v2_5/vrf_coordinator_test_v2_5.go diff --git a/contracts/scripts/native_solc_compile_all_vrf b/contracts/scripts/native_solc_compile_all_vrf index 4bfd4ecac7..88e7b3e147 100755 --- a/contracts/scripts/native_solc_compile_all_vrf +++ b/contracts/scripts/native_solc_compile_all_vrf @@ -114,6 +114,7 @@ compileContract vrf/dev/testhelpers/VRFV2PlusWrapperConsumerExample.sol compileContract vrf/dev/testhelpers/VRFV2PlusRevertingExample.sol compileContract vrf/dev/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol compileContract vrf/dev/testhelpers/VRFV2PlusMaliciousMigrator.sol +compileContractAltOpts vrf/dev/testhelpers/VRFCoordinatorTestV2_5.sol 500 compileContract vrf/dev/libraries/VRFV2PlusClient.sol compileContract vrf/dev/testhelpers/VRFCoordinatorV2Plus_V2Example.sol compileContract vrf/dev/TrustedBlockhashStore.sol diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorTestV2_5.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorTestV2_5.sol new file mode 100644 index 0000000000..2e9c4a2da7 --- /dev/null +++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorTestV2_5.sol @@ -0,0 +1,773 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {BlockhashStoreInterface} from "../../interfaces/BlockhashStoreInterface.sol"; +import {VRFOld} from "./VRFOld.sol"; +import {VRFTypes} from "../../VRFTypes.sol"; +import {VRFConsumerBaseV2Plus, IVRFMigratableConsumerV2Plus} from "../VRFConsumerBaseV2Plus.sol"; +import {ChainSpecificUtil} from "../../../ChainSpecificUtil.sol"; +import {SubscriptionAPI} from "../SubscriptionAPI.sol"; +import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; +import {IVRFCoordinatorV2PlusMigration} from "../interfaces/IVRFCoordinatorV2PlusMigration.sol"; +// solhint-disable-next-line no-unused-import +import {IVRFCoordinatorV2Plus, IVRFSubscriptionV2Plus} from "../interfaces/IVRFCoordinatorV2Plus.sol"; + +// solhint-disable-next-line contract-name-camelcase +contract VRFCoordinatorTestV2_5 is VRFOld, SubscriptionAPI, IVRFCoordinatorV2Plus { + /// @dev should always be available + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i + BlockhashStoreInterface public immutable BLOCKHASH_STORE; + + // Set this maximum to 200 to give us a 56 block window to fulfill + // the request before requiring the block hash feeder. + uint16 public constant MAX_REQUEST_CONFIRMATIONS = 200; + uint32 public constant MAX_NUM_WORDS = 500; + // 5k is plenty for an EXTCODESIZE call (2600) + warm CALL (100) + // and some arithmetic operations. + uint256 private constant GAS_FOR_CALL_EXACT_CHECK = 5_000; + // upper bound limit for premium percentages to make sure fee calculations don't overflow + uint8 private constant PREMIUM_PERCENTAGE_MAX = 155; + error InvalidRequestConfirmations(uint16 have, uint16 min, uint16 max); + error GasLimitTooBig(uint32 have, uint32 want); + error NumWordsTooBig(uint32 have, uint32 want); + error MsgDataTooBig(uint256 have, uint32 max); + error ProvingKeyAlreadyRegistered(bytes32 keyHash); + error NoSuchProvingKey(bytes32 keyHash); + error InvalidLinkWeiPrice(int256 linkWei); + error LinkDiscountTooHigh(uint32 flatFeeLinkDiscountPPM, uint32 flatFeeNativePPM); + error InvalidPremiumPercentage(uint8 premiumPercentage, uint8 max); + error NoCorrespondingRequest(); + error IncorrectCommitment(); + error BlockhashNotInStore(uint256 blockNum); + error PaymentTooLarge(); + error InvalidExtraArgsTag(); + error GasPriceExceeded(uint256 gasPrice, uint256 maxGas); + + struct ProvingKey { + bool exists; // proving key exists + uint64 maxGas; // gas lane max gas price for fulfilling requests + } + + mapping(bytes32 => ProvingKey) /* keyHash */ /* provingKey */ public s_provingKeys; + bytes32[] public s_provingKeyHashes; + mapping(uint256 => bytes32) /* requestID */ /* commitment */ public s_requestCommitments; + event ProvingKeyRegistered(bytes32 keyHash, uint64 maxGas); + event ProvingKeyDeregistered(bytes32 keyHash, uint64 maxGas); + + event RandomWordsRequested( + bytes32 indexed keyHash, + uint256 requestId, + uint256 preSeed, + uint256 indexed subId, + uint16 minimumRequestConfirmations, + uint32 callbackGasLimit, + uint32 numWords, + bytes extraArgs, + address indexed sender + ); + + event RandomWordsFulfilled( + uint256 indexed requestId, + uint256 outputSeed, + uint256 indexed subId, + uint96 payment, + bool nativePayment, + bool success, + bool onlyPremium + ); + + int256 public s_fallbackWeiPerUnitLink; + + event ConfigSet( + uint16 minimumRequestConfirmations, + uint32 maxGasLimit, + uint32 stalenessSeconds, + uint32 gasAfterPaymentCalculation, + int256 fallbackWeiPerUnitLink, + uint32 fulfillmentFlatFeeNativePPM, + uint32 fulfillmentFlatFeeLinkDiscountPPM, + uint8 nativePremiumPercentage, + uint8 linkPremiumPercentage + ); + + event FallbackWeiPerUnitLinkUsed(uint256 requestId, int256 fallbackWeiPerUnitLink); + + constructor(address blockhashStore) SubscriptionAPI() { + BLOCKHASH_STORE = BlockhashStoreInterface(blockhashStore); + } + + /** + * @notice Registers a proving key to. + * @param publicProvingKey key that oracle can use to submit vrf fulfillments + */ + function registerProvingKey(uint256[2] calldata publicProvingKey, uint64 maxGas) external onlyOwner { + bytes32 kh = hashOfKey(publicProvingKey); + if (s_provingKeys[kh].exists) { + revert ProvingKeyAlreadyRegistered(kh); + } + s_provingKeys[kh] = ProvingKey({exists: true, maxGas: maxGas}); + s_provingKeyHashes.push(kh); + emit ProvingKeyRegistered(kh, maxGas); + } + + /** + * @notice Deregisters a proving key. + * @param publicProvingKey key that oracle can use to submit vrf fulfillments + */ + function deregisterProvingKey(uint256[2] calldata publicProvingKey) external onlyOwner { + bytes32 kh = hashOfKey(publicProvingKey); + ProvingKey memory key = s_provingKeys[kh]; + if (!key.exists) { + revert NoSuchProvingKey(kh); + } + delete s_provingKeys[kh]; + uint256 s_provingKeyHashesLength = s_provingKeyHashes.length; + for (uint256 i = 0; i < s_provingKeyHashesLength; ++i) { + if (s_provingKeyHashes[i] == kh) { + // Copy last element and overwrite kh to be deleted with it + s_provingKeyHashes[i] = s_provingKeyHashes[s_provingKeyHashesLength - 1]; + s_provingKeyHashes.pop(); + break; + } + } + emit ProvingKeyDeregistered(kh, key.maxGas); + } + + /** + * @notice Returns the proving key hash key associated with this public key + * @param publicKey the key to return the hash of + */ + function hashOfKey(uint256[2] memory publicKey) public pure returns (bytes32) { + return keccak256(abi.encode(publicKey)); + } + + /** + * @notice Sets the configuration of the vrfv2 coordinator + * @param minimumRequestConfirmations global min for request confirmations + * @param maxGasLimit global max for request gas limit + * @param stalenessSeconds if the native/link feed is more stale then this, use the fallback price + * @param gasAfterPaymentCalculation gas used in doing accounting after completing the gas measurement + * @param fallbackWeiPerUnitLink fallback native/link price in the case of a stale feed + * @param fulfillmentFlatFeeNativePPM flat fee in native for native payment + * @param fulfillmentFlatFeeLinkDiscountPPM flat fee discount for link payment in native + * @param nativePremiumPercentage native premium percentage + * @param linkPremiumPercentage link premium percentage + */ + function setConfig( + uint16 minimumRequestConfirmations, + uint32 maxGasLimit, + uint32 stalenessSeconds, + uint32 gasAfterPaymentCalculation, + int256 fallbackWeiPerUnitLink, + uint32 fulfillmentFlatFeeNativePPM, + uint32 fulfillmentFlatFeeLinkDiscountPPM, + uint8 nativePremiumPercentage, + uint8 linkPremiumPercentage + ) external onlyOwner { + if (minimumRequestConfirmations > MAX_REQUEST_CONFIRMATIONS) { + revert InvalidRequestConfirmations( + minimumRequestConfirmations, + minimumRequestConfirmations, + MAX_REQUEST_CONFIRMATIONS + ); + } + if (fallbackWeiPerUnitLink <= 0) { + revert InvalidLinkWeiPrice(fallbackWeiPerUnitLink); + } + if (fulfillmentFlatFeeLinkDiscountPPM > fulfillmentFlatFeeNativePPM) { + revert LinkDiscountTooHigh(fulfillmentFlatFeeLinkDiscountPPM, fulfillmentFlatFeeNativePPM); + } + if (nativePremiumPercentage > PREMIUM_PERCENTAGE_MAX) { + revert InvalidPremiumPercentage(nativePremiumPercentage, PREMIUM_PERCENTAGE_MAX); + } + if (linkPremiumPercentage > PREMIUM_PERCENTAGE_MAX) { + revert InvalidPremiumPercentage(linkPremiumPercentage, PREMIUM_PERCENTAGE_MAX); + } + s_config = Config({ + minimumRequestConfirmations: minimumRequestConfirmations, + maxGasLimit: maxGasLimit, + stalenessSeconds: stalenessSeconds, + gasAfterPaymentCalculation: gasAfterPaymentCalculation, + reentrancyLock: false, + fulfillmentFlatFeeNativePPM: fulfillmentFlatFeeNativePPM, + fulfillmentFlatFeeLinkDiscountPPM: fulfillmentFlatFeeLinkDiscountPPM, + nativePremiumPercentage: nativePremiumPercentage, + linkPremiumPercentage: linkPremiumPercentage + }); + s_fallbackWeiPerUnitLink = fallbackWeiPerUnitLink; + emit ConfigSet( + minimumRequestConfirmations, + maxGasLimit, + stalenessSeconds, + gasAfterPaymentCalculation, + fallbackWeiPerUnitLink, + fulfillmentFlatFeeNativePPM, + fulfillmentFlatFeeLinkDiscountPPM, + nativePremiumPercentage, + linkPremiumPercentage + ); + } + + /// @dev Convert the extra args bytes into a struct + /// @param extraArgs The extra args bytes + /// @return The extra args struct + function _fromBytes(bytes calldata extraArgs) internal pure returns (VRFV2PlusClient.ExtraArgsV1 memory) { + if (extraArgs.length == 0) { + return VRFV2PlusClient.ExtraArgsV1({nativePayment: false}); + } + if (bytes4(extraArgs) != VRFV2PlusClient.EXTRA_ARGS_V1_TAG) revert InvalidExtraArgsTag(); + return abi.decode(extraArgs[4:], (VRFV2PlusClient.ExtraArgsV1)); + } + + /** + * @notice Request a set of random words. + * @param req - a struct containing following fiels for randomness request: + * keyHash - Corresponds to a particular oracle job which uses + * that key for generating the VRF proof. Different keyHash's have different gas price + * ceilings, so you can select a specific one to bound your maximum per request cost. + * subId - The ID of the VRF subscription. Must be funded + * with the minimum subscription balance required for the selected keyHash. + * requestConfirmations - How many blocks you'd like the + * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS + * for why you may want to request more. The acceptable range is + * [minimumRequestBlockConfirmations, 200]. + * callbackGasLimit - How much gas you'd like to receive in your + * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords + * may be slightly less than this amount because of gas used calling the function + * (argument decoding etc.), so you may need to request slightly more than you expect + * to have inside fulfillRandomWords. The acceptable range is + * [0, maxGasLimit] + * numWords - The number of uint256 random values you'd like to receive + * in your fulfillRandomWords callback. Note these numbers are expanded in a + * secure way by the VRFCoordinator from a single random value supplied by the oracle. + * extraArgs - Encoded extra arguments that has a boolean flag for whether payment + * should be made in native or LINK. Payment in LINK is only available if the LINK token is available to this contract. + * @return requestId - A unique identifier of the request. Can be used to match + * a request to a response in fulfillRandomWords. + */ + function requestRandomWords( + VRFV2PlusClient.RandomWordsRequest calldata req + ) external override nonReentrant returns (uint256 requestId) { + // Input validation using the subscription storage. + uint256 subId = req.subId; + if (s_subscriptionConfigs[subId].owner == address(0)) { + revert InvalidSubscription(); + } + // Its important to ensure that the consumer is in fact who they say they + // are, otherwise they could use someone else's subscription balance. + mapping(uint256 => ConsumerConfig) storage consumerConfigs = s_consumers[msg.sender]; + ConsumerConfig memory consumerConfig = consumerConfigs[subId]; + if (!consumerConfig.active) { + revert InvalidConsumer(subId, msg.sender); + } + // Input validation using the config storage word. + if ( + req.requestConfirmations < s_config.minimumRequestConfirmations || + req.requestConfirmations > MAX_REQUEST_CONFIRMATIONS + ) { + revert InvalidRequestConfirmations( + req.requestConfirmations, + s_config.minimumRequestConfirmations, + MAX_REQUEST_CONFIRMATIONS + ); + } + // No lower bound on the requested gas limit. A user could request 0 + // and they would simply be billed for the proof verification and wouldn't be + // able to do anything with the random value. + if (req.callbackGasLimit > s_config.maxGasLimit) { + revert GasLimitTooBig(req.callbackGasLimit, s_config.maxGasLimit); + } + if (req.numWords > MAX_NUM_WORDS) { + revert NumWordsTooBig(req.numWords, MAX_NUM_WORDS); + } + + // Note we do not check whether the keyHash is valid to save gas. + // The consequence for users is that they can send requests + // for invalid keyHashes which will simply not be fulfilled. + ++consumerConfig.nonce; + ++consumerConfig.pendingReqCount; + uint256 preSeed; + (requestId, preSeed) = _computeRequestId(req.keyHash, msg.sender, subId, consumerConfig.nonce); + + bytes memory extraArgsBytes = VRFV2PlusClient._argsToBytes(_fromBytes(req.extraArgs)); + s_requestCommitments[requestId] = keccak256( + abi.encode( + requestId, + ChainSpecificUtil._getBlockNumber(), + subId, + req.callbackGasLimit, + req.numWords, + msg.sender, + extraArgsBytes + ) + ); + emit RandomWordsRequested( + req.keyHash, + requestId, + preSeed, + subId, + req.requestConfirmations, + req.callbackGasLimit, + req.numWords, + extraArgsBytes, + msg.sender + ); + consumerConfigs[subId] = consumerConfig; + + return requestId; + } + + function _computeRequestId( + bytes32 keyHash, + address sender, + uint256 subId, + uint64 nonce + ) internal pure returns (uint256, uint256) { + uint256 preSeed = uint256(keccak256(abi.encode(keyHash, sender, subId, nonce))); + return (uint256(keccak256(abi.encode(keyHash, preSeed))), preSeed); + } + + /** + * @dev calls target address with exactly gasAmount gas and data as calldata + * or reverts if at least gasAmount gas is not available. + */ + function _callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) { + assembly { + let g := gas() + // Compute g -= GAS_FOR_CALL_EXACT_CHECK and check for underflow + // The gas actually passed to the callee is min(gasAmount, 63//64*gas available). + // We want to ensure that we revert if gasAmount > 63//64*gas available + // as we do not want to provide them with less, however that check itself costs + // gas. GAS_FOR_CALL_EXACT_CHECK ensures we have at least enough gas to be able + // to revert if gasAmount > 63//64*gas available. + if lt(g, GAS_FOR_CALL_EXACT_CHECK) { + revert(0, 0) + } + g := sub(g, GAS_FOR_CALL_EXACT_CHECK) + // if g - g//64 <= gasAmount, revert + // (we subtract g//64 because of EIP-150) + if iszero(gt(sub(g, div(g, 64)), gasAmount)) { + revert(0, 0) + } + // solidity calls check that a contract actually exists at the destination, so we do the same + if iszero(extcodesize(target)) { + revert(0, 0) + } + // call and return whether we succeeded. ignore return data + // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) + success := call(gasAmount, target, 0, add(data, 0x20), mload(data), 0, 0) + } + return success; + } + + struct Output { + ProvingKey provingKey; + uint256 requestId; + uint256 randomness; + } + + function _getRandomnessFromProof( + Proof memory proof, + VRFTypes.RequestCommitmentV2Plus memory rc + ) internal view returns (Output memory) { + bytes32 keyHash = hashOfKey(proof.pk); + ProvingKey memory key = s_provingKeys[keyHash]; + // Only registered proving keys are permitted. + if (!key.exists) { + revert NoSuchProvingKey(keyHash); + } + uint256 requestId = uint256(keccak256(abi.encode(keyHash, proof.seed))); + bytes32 commitment = s_requestCommitments[requestId]; + if (commitment == 0) { + revert NoCorrespondingRequest(); + } + if ( + commitment != + keccak256(abi.encode(requestId, rc.blockNum, rc.subId, rc.callbackGasLimit, rc.numWords, rc.sender, rc.extraArgs)) + ) { + revert IncorrectCommitment(); + } + + bytes32 blockHash = ChainSpecificUtil._getBlockhash(rc.blockNum); + if (blockHash == bytes32(0)) { + blockHash = BLOCKHASH_STORE.getBlockhash(rc.blockNum); + if (blockHash == bytes32(0)) { + revert BlockhashNotInStore(rc.blockNum); + } + } + + // The seed actually used by the VRF machinery, mixing in the blockhash + uint256 actualSeed = uint256(keccak256(abi.encodePacked(proof.seed, blockHash))); + uint256 randomness = VRFOld._randomValueFromVRFProof(proof, actualSeed); // Reverts on failure + return Output(key, requestId, randomness); + } + + function _getValidatedGasPrice(bool onlyPremium, uint64 gasLaneMaxGas) internal view returns (uint256 gasPrice) { + if (tx.gasprice > gasLaneMaxGas) { + if (onlyPremium) { + // if only the premium amount needs to be billed, then the premium is capped by the gas lane max + return uint256(gasLaneMaxGas); + } else { + // Ensure gas price does not exceed the gas lane max gas price + revert GasPriceExceeded(tx.gasprice, gasLaneMaxGas); + } + } + return tx.gasprice; + } + + function _deliverRandomness( + uint256 requestId, + VRFTypes.RequestCommitmentV2Plus memory rc, + uint256[] memory randomWords + ) internal returns (bool success) { + VRFConsumerBaseV2Plus v; + bytes memory resp = abi.encodeWithSelector(v.rawFulfillRandomWords.selector, requestId, randomWords); + // Call with explicitly the amount of callback gas requested + // Important to not let them exhaust the gas budget and avoid oracle payment. + // Do not allow any non-view/non-pure coordinator functions to be called + // during the consumers callback code via reentrancyLock. + // Note that _callWithExactGas will revert if we do not have sufficient gas + // to give the callee their requested amount. + s_config.reentrancyLock = true; + success = _callWithExactGas(rc.callbackGasLimit, rc.sender, resp); + s_config.reentrancyLock = false; + return success; + } + + /* + * @notice Fulfill a randomness request. + * @param proof contains the proof and randomness + * @param rc request commitment pre-image, committed to at request time + * @param onlyPremium only charge premium + * @return payment amount billed to the subscription + * @dev simulated offchain to determine if sufficient balance is present to fulfill the request + */ + function fulfillRandomWords( + Proof memory proof, + VRFTypes.RequestCommitmentV2Plus memory rc, + bool onlyPremium + ) external nonReentrant returns (uint96 payment) { + uint256 startGas = gasleft(); + // fulfillRandomWords msg.data has 772 bytes and with an additional + // buffer of 32 bytes, we get 804 bytes. + /* Data size split: + * fulfillRandomWords function signature - 4 bytes + * proof - 416 bytes + * pk - 64 bytes + * gamma - 64 bytes + * c - 32 bytes + * s - 32 bytes + * seed - 32 bytes + * uWitness - 32 bytes + * cGammaWitness - 64 bytes + * sHashWitness - 64 bytes + * zInv - 32 bytes + * requestCommitment - 320 bytes + * blockNum - 32 bytes + * subId - 32 bytes + * callbackGasLimit - 32 bytes + * numWords - 32 bytes + * sender - 32 bytes + * extraArgs - 128 bytes + * onlyPremium - 32 bytes + */ + if (msg.data.length > 804) { + revert MsgDataTooBig(msg.data.length, 804); + } + Output memory output = _getRandomnessFromProof(proof, rc); + uint256 gasPrice = _getValidatedGasPrice(onlyPremium, output.provingKey.maxGas); + + uint256[] memory randomWords; + uint256 randomness = output.randomness; + // stack too deep error + { + uint256 numWords = rc.numWords; + randomWords = new uint256[](numWords); + for (uint256 i = 0; i < numWords; ++i) { + randomWords[i] = uint256(keccak256(abi.encode(randomness, i))); + } + } + + delete s_requestCommitments[output.requestId]; + bool success = _deliverRandomness(output.requestId, rc, randomWords); + + // Increment the req count for the subscription. + ++s_subscriptions[rc.subId].reqCount; + // Decrement the pending req count for the consumer. + --s_consumers[rc.sender][rc.subId].pendingReqCount; + + bool nativePayment = uint8(rc.extraArgs[rc.extraArgs.length - 1]) == 1; + + // stack too deep error + { + // We want to charge users exactly for how much gas they use in their callback with + // an additional premium. If onlyPremium is true, only premium is charged without + // the gas cost. The gasAfterPaymentCalculation is meant to cover these additional + // operations where we decrement the subscription balance and increment the + // withdrawable balance. + bool isFeedStale; + (payment, isFeedStale) = _calculatePaymentAmount(startGas, gasPrice, nativePayment, onlyPremium); + if (isFeedStale) { + emit FallbackWeiPerUnitLinkUsed(output.requestId, s_fallbackWeiPerUnitLink); + } + } + + _chargePayment(payment, nativePayment, rc.subId); + + // Include payment in the event for tracking costs. + emit RandomWordsFulfilled(output.requestId, randomness, rc.subId, payment, nativePayment, success, onlyPremium); + + return payment; + } + + function _chargePayment(uint96 payment, bool nativePayment, uint256 subId) internal { + Subscription storage subcription = s_subscriptions[subId]; + if (nativePayment) { + uint96 prevBal = subcription.nativeBalance; + if (prevBal < payment) { + revert InsufficientBalance(); + } + subcription.nativeBalance = prevBal - payment; + s_withdrawableNative += payment; + } else { + uint96 prevBal = subcription.balance; + if (prevBal < payment) { + revert InsufficientBalance(); + } + subcription.balance = prevBal - payment; + s_withdrawableTokens += payment; + } + } + + function _calculatePaymentAmount( + uint256 startGas, + uint256 weiPerUnitGas, + bool nativePayment, + bool onlyPremium + ) internal view returns (uint96, bool) { + if (nativePayment) { + return (_calculatePaymentAmountNative(startGas, weiPerUnitGas, onlyPremium), false); + } + return _calculatePaymentAmountLink(startGas, weiPerUnitGas, onlyPremium); + } + + function _calculatePaymentAmountNative( + uint256 startGas, + uint256 weiPerUnitGas, + bool onlyPremium + ) internal view returns (uint96) { + // Will return non-zero on chains that have this enabled + uint256 l1CostWei = ChainSpecificUtil._getCurrentTxL1GasFees(msg.data); + // calculate the payment without the premium + uint256 baseFeeWei = weiPerUnitGas * (s_config.gasAfterPaymentCalculation + startGas - gasleft()); + // calculate flat fee in native + uint256 flatFeeWei = 1e12 * uint256(s_config.fulfillmentFlatFeeNativePPM); + if (onlyPremium) { + return uint96((((l1CostWei + baseFeeWei) * (s_config.nativePremiumPercentage)) / 100) + flatFeeWei); + } else { + return uint96((((l1CostWei + baseFeeWei) * (100 + s_config.nativePremiumPercentage)) / 100) + flatFeeWei); + } + } + + // Get the amount of gas used for fulfillment + function _calculatePaymentAmountLink( + uint256 startGas, + uint256 weiPerUnitGas, + bool onlyPremium + ) internal view returns (uint96, bool) { + (int256 weiPerUnitLink, bool isFeedStale) = _getFeedData(); + if (weiPerUnitLink <= 0) { + revert InvalidLinkWeiPrice(weiPerUnitLink); + } + // Will return non-zero on chains that have this enabled + uint256 l1CostWei = ChainSpecificUtil._getCurrentTxL1GasFees(msg.data); + // (1e18 juels/link) ((wei/gas * gas) + l1wei) / (wei/link) = juels + uint256 paymentNoFee = (1e18 * + (weiPerUnitGas * (s_config.gasAfterPaymentCalculation + startGas - gasleft()) + l1CostWei)) / + uint256(weiPerUnitLink); + // calculate the flat fee in wei + uint256 flatFeeWei = 1e12 * + uint256(s_config.fulfillmentFlatFeeNativePPM - s_config.fulfillmentFlatFeeLinkDiscountPPM); + uint256 flatFeeJuels = (1e18 * flatFeeWei) / uint256(weiPerUnitLink); + uint256 payment; + if (onlyPremium) { + payment = ((paymentNoFee * (s_config.linkPremiumPercentage)) / 100 + flatFeeJuels); + } else { + payment = ((paymentNoFee * (100 + s_config.linkPremiumPercentage)) / 100 + flatFeeJuels); + } + if (payment > 1e27) { + revert PaymentTooLarge(); // Payment + fee cannot be more than all of the link in existence. + } + return (uint96(payment), isFeedStale); + } + + function _getFeedData() private view returns (int256 weiPerUnitLink, bool isFeedStale) { + uint32 stalenessSeconds = s_config.stalenessSeconds; + uint256 timestamp; + (, weiPerUnitLink, , timestamp, ) = LINK_NATIVE_FEED.latestRoundData(); + // solhint-disable-next-line not-rely-on-time + isFeedStale = stalenessSeconds > 0 && stalenessSeconds < block.timestamp - timestamp; + if (isFeedStale) { + weiPerUnitLink = s_fallbackWeiPerUnitLink; + } + return (weiPerUnitLink, isFeedStale); + } + + /** + * @inheritdoc IVRFSubscriptionV2Plus + */ + function pendingRequestExists(uint256 subId) public view override returns (bool) { + address[] storage consumers = s_subscriptionConfigs[subId].consumers; + uint256 consumersLength = consumers.length; + if (consumersLength == 0) { + return false; + } + for (uint256 i = 0; i < consumersLength; ++i) { + if (s_consumers[consumers[i]][subId].pendingReqCount > 0) { + return true; + } + } + return false; + } + + /** + * @inheritdoc IVRFSubscriptionV2Plus + */ + function removeConsumer(uint256 subId, address consumer) external override onlySubOwner(subId) nonReentrant { + if (pendingRequestExists(subId)) { + revert PendingRequestExists(); + } + if (!s_consumers[consumer][subId].active) { + revert InvalidConsumer(subId, consumer); + } + // Note bounded by MAX_CONSUMERS + address[] memory consumers = s_subscriptionConfigs[subId].consumers; + uint256 lastConsumerIndex = consumers.length - 1; + for (uint256 i = 0; i < consumers.length; ++i) { + if (consumers[i] == consumer) { + address last = consumers[lastConsumerIndex]; + // Storage write to preserve last element + s_subscriptionConfigs[subId].consumers[i] = last; + // Storage remove last element + s_subscriptionConfigs[subId].consumers.pop(); + break; + } + } + s_consumers[consumer][subId].active = false; + emit SubscriptionConsumerRemoved(subId, consumer); + } + + /** + * @inheritdoc IVRFSubscriptionV2Plus + */ + function cancelSubscription(uint256 subId, address to) external override onlySubOwner(subId) nonReentrant { + if (pendingRequestExists(subId)) { + revert PendingRequestExists(); + } + _cancelSubscriptionHelper(subId, to); + } + + /*************************************************************************** + * Section: Migration + ***************************************************************************/ + + address[] internal s_migrationTargets; + + /// @dev Emitted when new coordinator is registered as migratable target + event CoordinatorRegistered(address coordinatorAddress); + + /// @dev Emitted when new coordinator is deregistered + event CoordinatorDeregistered(address coordinatorAddress); + + /// @notice emitted when migration to new coordinator completes successfully + /// @param newCoordinator coordinator address after migration + /// @param subId subscription ID + event MigrationCompleted(address newCoordinator, uint256 subId); + + /// @notice emitted when migrate() is called and given coordinator is not registered as migratable target + error CoordinatorNotRegistered(address coordinatorAddress); + + /// @notice emitted when migrate() is called and given coordinator is registered as migratable target + error CoordinatorAlreadyRegistered(address coordinatorAddress); + + /// @dev encapsulates data to be migrated from current coordinator + // solhint-disable-next-line gas-struct-packing + struct V1MigrationData { + uint8 fromVersion; + uint256 subId; + address subOwner; + address[] consumers; + uint96 linkBalance; + uint96 nativeBalance; + } + + function _isTargetRegistered(address target) internal view returns (bool) { + uint256 migrationTargetsLength = s_migrationTargets.length; + for (uint256 i = 0; i < migrationTargetsLength; ++i) { + if (s_migrationTargets[i] == target) { + return true; + } + } + return false; + } + + function registerMigratableCoordinator(address target) external onlyOwner { + if (_isTargetRegistered(target)) { + revert CoordinatorAlreadyRegistered(target); + } + s_migrationTargets.push(target); + emit CoordinatorRegistered(target); + } + + function deregisterMigratableCoordinator(address target) external onlyOwner { + uint256 nTargets = s_migrationTargets.length; + for (uint256 i = 0; i < nTargets; ++i) { + if (s_migrationTargets[i] == target) { + s_migrationTargets[i] = s_migrationTargets[nTargets - 1]; + s_migrationTargets.pop(); + emit CoordinatorDeregistered(target); + return; + } + } + revert CoordinatorNotRegistered(target); + } + + function migrate(uint256 subId, address newCoordinator) external nonReentrant { + if (!_isTargetRegistered(newCoordinator)) { + revert CoordinatorNotRegistered(newCoordinator); + } + (uint96 balance, uint96 nativeBalance, , address subOwner, address[] memory consumers) = getSubscription(subId); + // solhint-disable-next-line gas-custom-errors + require(subOwner == msg.sender, "Not subscription owner"); + // solhint-disable-next-line gas-custom-errors + require(!pendingRequestExists(subId), "Pending request exists"); + + V1MigrationData memory migrationData = V1MigrationData({ + fromVersion: 1, + subId: subId, + subOwner: subOwner, + consumers: consumers, + linkBalance: balance, + nativeBalance: nativeBalance + }); + bytes memory encodedData = abi.encode(migrationData); + _deleteSubscription(subId); + IVRFCoordinatorV2PlusMigration(newCoordinator).onMigration{value: nativeBalance}(encodedData); + + // Only transfer LINK if the token is active and there is a balance. + if (address(LINK) != address(0) && balance != 0) { + // solhint-disable-next-line gas-custom-errors + require(LINK.transfer(address(newCoordinator), balance), "insufficient funds"); + } + + // despite the fact that we follow best practices this is still probably safest + // to prevent any re-entrancy possibilities. + s_config.reentrancyLock = true; + for (uint256 i = 0; i < consumers.length; ++i) { + IVRFMigratableConsumerV2Plus(consumers[i]).setCoordinator(newCoordinator); + } + s_config.reentrancyLock = false; + + emit MigrationCompleted(newCoordinator, subId); + } +} diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFOld.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFOld.sol new file mode 100644 index 0000000000..137235fd0a --- /dev/null +++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFOld.sol @@ -0,0 +1,588 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/** **************************************************************************** + * @notice Verification of verifiable-random-function (VRF) proofs, following + * @notice https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.3 + * @notice See https://eprint.iacr.org/2017/099.pdf for security proofs. + + * @dev Bibliographic references: + + * @dev Goldberg, et al., "Verifiable Random Functions (VRFs)", Internet Draft + * @dev draft-irtf-cfrg-vrf-05, IETF, Aug 11 2019, + * @dev https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05 + + * @dev Papadopoulos, et al., "Making NSEC5 Practical for DNSSEC", Cryptology + * @dev ePrint Archive, Report 2017/099, https://eprint.iacr.org/2017/099.pdf + * **************************************************************************** + * @dev USAGE + + * @dev The main entry point is _randomValueFromVRFProof. See its docstring. + * **************************************************************************** + * @dev PURPOSE + + * @dev Reggie the Random Oracle (not his real job) wants to provide randomness + * @dev to Vera the verifier in such a way that Vera can be sure he's not + * @dev making his output up to suit himself. Reggie provides Vera a public key + * @dev to which he knows the secret key. Each time Vera provides a seed to + * @dev Reggie, he gives back a value which is computed completely + * @dev deterministically from the seed and the secret key. + + * @dev Reggie provides a proof by which Vera can verify that the output was + * @dev correctly computed once Reggie tells it to her, but without that proof, + * @dev the output is computationally indistinguishable to her from a uniform + * @dev random sample from the output space. + + * @dev The purpose of this contract is to perform that verification. + * **************************************************************************** + * @dev DESIGN NOTES + + * @dev The VRF algorithm verified here satisfies the full uniqueness, full + * @dev collision resistance, and full pseudo-randomness security properties. + * @dev See "SECURITY PROPERTIES" below, and + * @dev https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-3 + + * @dev An elliptic curve point is generally represented in the solidity code + * @dev as a uint256[2], corresponding to its affine coordinates in + * @dev GF(FIELD_SIZE). + + * @dev For the sake of efficiency, this implementation deviates from the spec + * @dev in some minor ways: + + * @dev - Keccak hash rather than the SHA256 hash recommended in + * @dev https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.5 + * @dev Keccak costs much less gas on the EVM, and provides similar security. + + * @dev - Secp256k1 curve instead of the P-256 or ED25519 curves recommended in + * @dev https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.5 + * @dev For curve-point multiplication, it's much cheaper to abuse ECRECOVER + + * @dev - _hashToCurve recursively hashes until it finds a curve x-ordinate. On + * @dev the EVM, this is slightly more efficient than the recommendation in + * @dev https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.4.1.1 + * @dev step 5, to concatenate with a nonce then hash, and rehash with the + * @dev nonce updated until a valid x-ordinate is found. + + * @dev - _hashToCurve does not include a cipher version string or the byte 0x1 + * @dev in the hash message, as recommended in step 5.B of the draft + * @dev standard. They are unnecessary here because no variation in the + * @dev cipher suite is allowed. + + * @dev - Similarly, the hash input in _scalarFromCurvePoints does not include a + * @dev commitment to the cipher suite, either, which differs from step 2 of + * @dev https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.4.3 + * @dev . Also, the hash input is the concatenation of the uncompressed + * @dev points, not the compressed points as recommended in step 3. + + * @dev - In the calculation of the challenge value "c", the "u" value (i.e. + * @dev the value computed by Reggie as the nonce times the secp256k1 + * @dev generator point, see steps 5 and 7 of + * @dev https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.3 + * @dev ) is replaced by its ethereum address, i.e. the lower 160 bits of the + * @dev keccak hash of the original u. This is because we only verify the + * @dev calculation of u up to its address, by abusing ECRECOVER. + * **************************************************************************** + * @dev SECURITY PROPERTIES + + * @dev Here are the security properties for this VRF: + + * @dev Full uniqueness: For any seed and valid VRF public key, there is + * @dev exactly one VRF output which can be proved to come from that seed, in + * @dev the sense that the proof will pass _verifyVRFProof. + + * @dev Full collision resistance: It's cryptographically infeasible to find + * @dev two seeds with same VRF output from a fixed, valid VRF key + + * @dev Full pseudorandomness: Absent the proofs that the VRF outputs are + * @dev derived from a given seed, the outputs are computationally + * @dev indistinguishable from randomness. + + * @dev https://eprint.iacr.org/2017/099.pdf, Appendix B contains the proofs + * @dev for these properties. + + * @dev For secp256k1, the key validation described in section + * @dev https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.6 + * @dev is unnecessary, because secp256k1 has cofactor 1, and the + * @dev representation of the public key used here (affine x- and y-ordinates + * @dev of the secp256k1 point on the standard y^2=x^3+7 curve) cannot refer to + * @dev the point at infinity. + * **************************************************************************** + * @dev OTHER SECURITY CONSIDERATIONS + * + * @dev The seed input to the VRF could in principle force an arbitrary amount + * @dev of work in _hashToCurve, by requiring extra rounds of hashing and + * @dev checking whether that's yielded the x ordinate of a secp256k1 point. + * @dev However, under the Random Oracle Model the probability of choosing a + * @dev point which forces n extra rounds in _hashToCurve is 2⁻ⁿ. The base cost + * @dev for calling _hashToCurve is about 25,000 gas, and each round of checking + * @dev for a valid x ordinate costs about 15,555 gas, so to find a seed for + * @dev which _hashToCurve would cost more than 2,017,000 gas, one would have to + * @dev try, in expectation, about 2¹²⁸ seeds, which is infeasible for any + * @dev foreseeable computational resources. (25,000 + 128 * 15,555 < 2,017,000.) + + * @dev Since the gas block limit for the Ethereum main net is 10,000,000 gas, + * @dev this means it is infeasible for an adversary to prevent correct + * @dev operation of this contract by choosing an adverse seed. + + * @dev (See TestMeasureHashToCurveGasCost for verification of the gas cost for + * @dev _hashToCurve.) + + * @dev It may be possible to make a secure constant-time _hashToCurve function. + * @dev See notes in _hashToCurve docstring. +*/ +contract VRFOld { + // See https://www.secg.org/sec2-v2.pdf, section 2.4.1, for these constants. + // Number of points in Secp256k1 + uint256 private constant GROUP_ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; + // Prime characteristic of the galois field over which Secp256k1 is defined + uint256 private constant FIELD_SIZE = + // solium-disable-next-line indentation + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F; + uint256 private constant WORD_LENGTH_BYTES = 0x20; + + // (base^exponent) % FIELD_SIZE + // Cribbed from https://medium.com/@rbkhmrcr/precompiles-solidity-e5d29bd428c4 + function _bigModExp(uint256 base, uint256 exponent) internal view returns (uint256 exponentiation) { + uint256 callResult; + uint256[6] memory bigModExpContractInputs; + bigModExpContractInputs[0] = WORD_LENGTH_BYTES; // Length of base + bigModExpContractInputs[1] = WORD_LENGTH_BYTES; // Length of exponent + bigModExpContractInputs[2] = WORD_LENGTH_BYTES; // Length of modulus + bigModExpContractInputs[3] = base; + bigModExpContractInputs[4] = exponent; + bigModExpContractInputs[5] = FIELD_SIZE; + uint256[1] memory output; + assembly { + callResult := staticcall( + not(0), // Gas cost: no limit + 0x05, // Bigmodexp contract address + bigModExpContractInputs, + 0xc0, // Length of input segment: 6*0x20-bytes + output, + 0x20 // Length of output segment + ) + } + if (callResult == 0) { + // solhint-disable-next-line gas-custom-errors + revert("bigModExp failure!"); + } + return output[0]; + } + + // Let q=FIELD_SIZE. q % 4 = 3, ∴ x≡r^2 mod q ⇒ x^SQRT_POWER≡±r mod q. See + // https://en.wikipedia.org/wiki/Modular_square_root#Prime_or_prime_power_modulus + uint256 private constant SQRT_POWER = (FIELD_SIZE + 1) >> 2; + + // Computes a s.t. a^2 = x in the field. Assumes a exists + function _squareRoot(uint256 x) internal view returns (uint256) { + return _bigModExp(x, SQRT_POWER); + } + + // The value of y^2 given that (x,y) is on secp256k1. + function _ySquared(uint256 x) internal pure returns (uint256) { + // Curve is y^2=x^3+7. See section 2.4.1 of https://www.secg.org/sec2-v2.pdf + uint256 xCubed = mulmod(x, mulmod(x, x, FIELD_SIZE), FIELD_SIZE); + return addmod(xCubed, 7, FIELD_SIZE); + } + + // True iff p is on secp256k1 + function _isOnCurve(uint256[2] memory p) internal pure returns (bool) { + // Section 2.3.6. in https://www.secg.org/sec1-v2.pdf + // requires each ordinate to be in [0, ..., FIELD_SIZE-1] + // solhint-disable-next-line gas-custom-errors + require(p[0] < FIELD_SIZE, "invalid x-ordinate"); + // solhint-disable-next-line gas-custom-errors + require(p[1] < FIELD_SIZE, "invalid y-ordinate"); + return _ySquared(p[0]) == mulmod(p[1], p[1], FIELD_SIZE); + } + + // Hash x uniformly into {0, ..., FIELD_SIZE-1}. + function _fieldHash(bytes memory b) internal pure returns (uint256 x_) { + x_ = uint256(keccak256(b)); + // Rejecting if x >= FIELD_SIZE corresponds to step 2.1 in section 2.3.4 of + // http://www.secg.org/sec1-v2.pdf , which is part of the definition of + // string_to_point in the IETF draft + while (x_ >= FIELD_SIZE) { + x_ = uint256(keccak256(abi.encodePacked(x_))); + } + return x_; + } + + // Hash b to a random point which hopefully lies on secp256k1. The y ordinate + // is always even, due to + // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.4.1.1 + // step 5.C, which references arbitrary_string_to_point, defined in + // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.5 as + // returning the point with given x ordinate, and even y ordinate. + function _newCandidateSecp256k1Point(bytes memory b) internal view returns (uint256[2] memory p) { + unchecked { + p[0] = _fieldHash(b); + p[1] = _squareRoot(_ySquared(p[0])); + if (p[1] % 2 == 1) { + // Note that 0 <= p[1] < FIELD_SIZE + // so this cannot wrap, we use unchecked to save gas. + p[1] = FIELD_SIZE - p[1]; + } + } + return p; + } + + // Domain-separation tag for initial hash in _hashToCurve. Corresponds to + // vrf.go/hashToCurveHashPrefix + uint256 internal constant HASH_TO_CURVE_HASH_PREFIX = 1; + + // Cryptographic hash function onto the curve. + // + // Corresponds to algorithm in section 5.4.1.1 of the draft standard. (But see + // DESIGN NOTES above for slight differences.) + // + // TODO(alx): Implement a bounded-computation hash-to-curve, as described in + // "Construction of Rational Points on Elliptic Curves over Finite Fields" + // http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.831.5299&rep=rep1&type=pdf + // and suggested by + // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-01#section-5.2.2 + // (Though we can't used exactly that because secp256k1's j-invariant is 0.) + // + // This would greatly simplify the analysis in "OTHER SECURITY CONSIDERATIONS" + // https://www.pivotaltracker.com/story/show/171120900 + function _hashToCurve(uint256[2] memory pk, uint256 input) internal view returns (uint256[2] memory rv) { + rv = _newCandidateSecp256k1Point(abi.encodePacked(HASH_TO_CURVE_HASH_PREFIX, pk, input)); + while (!_isOnCurve(rv)) { + rv = _newCandidateSecp256k1Point(abi.encodePacked(rv[0])); + } + return rv; + } + + /** ********************************************************************* + * @notice Check that product==scalar*multiplicand + * + * @dev Based on Vitalik Buterin's idea in ethresear.ch post cited below. + * + * @param multiplicand: secp256k1 point + * @param scalar: non-zero GF(GROUP_ORDER) scalar + * @param product: secp256k1 expected to be multiplier * multiplicand + * @return verifies true iff product==scalar*multiplicand, with cryptographically high probability + */ + function _ecmulVerify( + uint256[2] memory multiplicand, + uint256 scalar, + uint256[2] memory product + ) internal pure returns (bool verifies) { + // solhint-disable-next-line gas-custom-errors + require(scalar != 0, "zero scalar"); // Rules out an ecrecover failure case + uint256 x = multiplicand[0]; // x ordinate of multiplicand + uint8 v = multiplicand[1] % 2 == 0 ? 27 : 28; // parity of y ordinate + // https://ethresear.ch/t/you-can-kinda-abuse-ecrecover-to-do-ecmul-in-secp256k1-today/2384/9 + // Point corresponding to address ecrecover(0, v, x, s=scalar*x) is + // (x⁻¹ mod GROUP_ORDER) * (scalar * x * multiplicand - 0 * g), i.e. + // scalar*multiplicand. See https://crypto.stackexchange.com/a/18106 + bytes32 scalarTimesX = bytes32(mulmod(scalar, x, GROUP_ORDER)); + address actual = ecrecover(bytes32(0), v, bytes32(x), scalarTimesX); + // Explicit conversion to address takes bottom 160 bits + address expected = address(uint160(uint256(keccak256(abi.encodePacked(product))))); + return (actual == expected); + } + + // Returns x1/z1-x2/z2=(x1z2-x2z1)/(z1z2) in projective coordinates on P¹(𝔽ₙ) + function _projectiveSub( + uint256 x1, + uint256 z1, + uint256 x2, + uint256 z2 + ) internal pure returns (uint256 x3, uint256 z3) { + unchecked { + uint256 num1 = mulmod(z2, x1, FIELD_SIZE); + // Note this cannot wrap since x2 is a point in [0, FIELD_SIZE-1] + // we use unchecked to save gas. + uint256 num2 = mulmod(FIELD_SIZE - x2, z1, FIELD_SIZE); + (x3, z3) = (addmod(num1, num2, FIELD_SIZE), mulmod(z1, z2, FIELD_SIZE)); + } + return (x3, z3); + } + + // Returns x1/z1*x2/z2=(x1x2)/(z1z2), in projective coordinates on P¹(𝔽ₙ) + function _projectiveMul( + uint256 x1, + uint256 z1, + uint256 x2, + uint256 z2 + ) internal pure returns (uint256 x3, uint256 z3) { + (x3, z3) = (mulmod(x1, x2, FIELD_SIZE), mulmod(z1, z2, FIELD_SIZE)); + return (x3, z3); + } + + /** ************************************************************************** + @notice Computes elliptic-curve sum, in projective co-ordinates + + @dev Using projective coordinates avoids costly divisions + + @dev To use this with p and q in affine coordinates, call + @dev _projectiveECAdd(px, py, qx, qy). This will return + @dev the addition of (px, py, 1) and (qx, qy, 1), in the + @dev secp256k1 group. + + @dev This can be used to calculate the z which is the inverse to zInv + @dev in isValidVRFOutput. But consider using a faster + @dev re-implementation such as ProjectiveECAdd in the golang vrf package. + + @dev This function assumes [px,py,1],[qx,qy,1] are valid projective + coordinates of secp256k1 points. That is safe in this contract, + because this method is only used by _linearCombination, which checks + points are on the curve via ecrecover. + ************************************************************************** + @param px The first affine coordinate of the first summand + @param py The second affine coordinate of the first summand + @param qx The first affine coordinate of the second summand + @param qy The second affine coordinate of the second summand + + (px,py) and (qx,qy) must be distinct, valid secp256k1 points. + ************************************************************************** + Return values are projective coordinates of [px,py,1]+[qx,qy,1] as points + on secp256k1, in P²(𝔽ₙ) + @return sx + @return sy + @return sz + */ + function _projectiveECAdd( + uint256 px, + uint256 py, + uint256 qx, + uint256 qy + ) internal pure returns (uint256 sx, uint256 sy, uint256 sz) { + unchecked { + // See "Group law for E/K : y^2 = x^3 + ax + b", in section 3.1.2, p. 80, + // "Guide to Elliptic Curve Cryptography" by Hankerson, Menezes and Vanstone + // We take the equations there for (sx,sy), and homogenize them to + // projective coordinates. That way, no inverses are required, here, and we + // only need the one inverse in _affineECAdd. + + // We only need the "point addition" equations from Hankerson et al. Can + // skip the "point doubling" equations because p1 == p2 is cryptographically + // impossible, and required not to be the case in _linearCombination. + + // Add extra "projective coordinate" to the two points + (uint256 z1, uint256 z2) = (1, 1); + + // (lx, lz) = (qy-py)/(qx-px), i.e., gradient of secant line. + // Cannot wrap since px and py are in [0, FIELD_SIZE-1] + uint256 lx = addmod(qy, FIELD_SIZE - py, FIELD_SIZE); + uint256 lz = addmod(qx, FIELD_SIZE - px, FIELD_SIZE); + + uint256 dx; // Accumulates denominator from sx calculation + // sx=((qy-py)/(qx-px))^2-px-qx + (sx, dx) = _projectiveMul(lx, lz, lx, lz); // ((qy-py)/(qx-px))^2 + (sx, dx) = _projectiveSub(sx, dx, px, z1); // ((qy-py)/(qx-px))^2-px + (sx, dx) = _projectiveSub(sx, dx, qx, z2); // ((qy-py)/(qx-px))^2-px-qx + + uint256 dy; // Accumulates denominator from sy calculation + // sy=((qy-py)/(qx-px))(px-sx)-py + (sy, dy) = _projectiveSub(px, z1, sx, dx); // px-sx + (sy, dy) = _projectiveMul(sy, dy, lx, lz); // ((qy-py)/(qx-px))(px-sx) + (sy, dy) = _projectiveSub(sy, dy, py, z1); // ((qy-py)/(qx-px))(px-sx)-py + + if (dx != dy) { + // Cross-multiply to put everything over a common denominator + sx = mulmod(sx, dy, FIELD_SIZE); + sy = mulmod(sy, dx, FIELD_SIZE); + sz = mulmod(dx, dy, FIELD_SIZE); + } else { + // Already over a common denominator, use that for z ordinate + sz = dx; + } + } + return (sx, sy, sz); + } + + // p1+p2, as affine points on secp256k1. + // + // invZ must be the inverse of the z returned by _projectiveECAdd(p1, p2). + // It is computed off-chain to save gas. + // + // p1 and p2 must be distinct, because _projectiveECAdd doesn't handle + // point doubling. + function _affineECAdd( + uint256[2] memory p1, + uint256[2] memory p2, + uint256 invZ + ) internal pure returns (uint256[2] memory) { + uint256 x; + uint256 y; + uint256 z; + (x, y, z) = _projectiveECAdd(p1[0], p1[1], p2[0], p2[1]); + // solhint-disable-next-line gas-custom-errors + require(mulmod(z, invZ, FIELD_SIZE) == 1, "invZ must be inverse of z"); + // Clear the z ordinate of the projective representation by dividing through + // by it, to obtain the affine representation + return [mulmod(x, invZ, FIELD_SIZE), mulmod(y, invZ, FIELD_SIZE)]; + } + + // True iff address(c*p+s*g) == lcWitness, where g is generator. (With + // cryptographically high probability.) + function _verifyLinearCombinationWithGenerator( + uint256 c, + uint256[2] memory p, + uint256 s, + address lcWitness + ) internal pure returns (bool) { + // Rule out ecrecover failure modes which return address 0. + unchecked { + // solhint-disable-next-line gas-custom-errors + require(lcWitness != address(0), "bad witness"); + uint8 v = (p[1] % 2 == 0) ? 27 : 28; // parity of y-ordinate of p + // Note this cannot wrap (X - Y % X), but we use unchecked to save + // gas. + bytes32 pseudoHash = bytes32(GROUP_ORDER - mulmod(p[0], s, GROUP_ORDER)); // -s*p[0] + bytes32 pseudoSignature = bytes32(mulmod(c, p[0], GROUP_ORDER)); // c*p[0] + // https://ethresear.ch/t/you-can-kinda-abuse-ecrecover-to-do-ecmul-in-secp256k1-today/2384/9 + // The point corresponding to the address returned by + // ecrecover(-s*p[0],v,p[0],c*p[0]) is + // (p[0]⁻¹ mod GROUP_ORDER)*(c*p[0]-(-s)*p[0]*g)=c*p+s*g. + // See https://crypto.stackexchange.com/a/18106 + // https://bitcoin.stackexchange.com/questions/38351/ecdsa-v-r-s-what-is-v + address computed = ecrecover(pseudoHash, v, bytes32(p[0]), pseudoSignature); + return computed == lcWitness; + } + } + + // c*p1 + s*p2. Requires cp1Witness=c*p1 and sp2Witness=s*p2. Also + // requires cp1Witness != sp2Witness (which is fine for this application, + // since it is cryptographically impossible for them to be equal. In the + // (cryptographically impossible) case that a prover accidentally derives + // a proof with equal c*p1 and s*p2, they should retry with a different + // proof nonce.) Assumes that all points are on secp256k1 + // (which is checked in _verifyVRFProof below.) + function _linearCombination( + uint256 c, + uint256[2] memory p1, + uint256[2] memory cp1Witness, + uint256 s, + uint256[2] memory p2, + uint256[2] memory sp2Witness, + uint256 zInv + ) internal pure returns (uint256[2] memory) { + unchecked { + // Note we are relying on the wrap around here + // solhint-disable-next-line gas-custom-errors + require((cp1Witness[0] % FIELD_SIZE) != (sp2Witness[0] % FIELD_SIZE), "points in sum must be distinct"); + // solhint-disable-next-line gas-custom-errors + require(_ecmulVerify(p1, c, cp1Witness), "First mul check failed"); + // solhint-disable-next-line gas-custom-errors + require(_ecmulVerify(p2, s, sp2Witness), "Second mul check failed"); + return _affineECAdd(cp1Witness, sp2Witness, zInv); + } + } + + // Domain-separation tag for the hash taken in _scalarFromCurvePoints. + // Corresponds to scalarFromCurveHashPrefix in vrf.go + uint256 internal constant SCALAR_FROM_CURVE_POINTS_HASH_PREFIX = 2; + + // Pseudo-random number from inputs. Matches vrf.go/_scalarFromCurvePoints, and + // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.4.3 + // The draft calls (in step 7, via the definition of string_to_int, in + // https://datatracker.ietf.org/doc/html/rfc8017#section-4.2 ) for taking the + // first hash without checking that it corresponds to a number less than the + // group order, which will lead to a slight bias in the sample. + // + // TODO(alx): We could save a bit of gas by following the standard here and + // using the compressed representation of the points, if we collated the y + // parities into a single bytes32. + // https://www.pivotaltracker.com/story/show/171120588 + function _scalarFromCurvePoints( + uint256[2] memory hash, + uint256[2] memory pk, + uint256[2] memory gamma, + address uWitness, + uint256[2] memory v + ) internal pure returns (uint256 s) { + return uint256(keccak256(abi.encodePacked(SCALAR_FROM_CURVE_POINTS_HASH_PREFIX, hash, pk, gamma, v, uWitness))); + } + + // True if (gamma, c, s) is a correctly constructed randomness proof from pk + // and seed. zInv must be the inverse of the third ordinate from + // _projectiveECAdd applied to cGammaWitness and sHashWitness. Corresponds to + // section 5.3 of the IETF draft. + // + // TODO(alx): Since I'm only using pk in the ecrecover call, I could only pass + // the x ordinate, and the parity of the y ordinate in the top bit of uWitness + // (which I could make a uint256 without using any extra space.) Would save + // about 2000 gas. https://www.pivotaltracker.com/story/show/170828567 + function _verifyVRFProof( + uint256[2] memory pk, + uint256[2] memory gamma, + uint256 c, + uint256 s, + uint256 seed, + address uWitness, + uint256[2] memory cGammaWitness, + uint256[2] memory sHashWitness, + uint256 zInv + ) internal view { + unchecked { + // solhint-disable-next-line gas-custom-errors + require(_isOnCurve(pk), "public key is not on curve"); + // solhint-disable-next-line gas-custom-errors + require(_isOnCurve(gamma), "gamma is not on curve"); + // solhint-disable-next-line gas-custom-errors + require(_isOnCurve(cGammaWitness), "cGammaWitness is not on curve"); + // solhint-disable-next-line gas-custom-errors + require(_isOnCurve(sHashWitness), "sHashWitness is not on curve"); + // Step 5. of IETF draft section 5.3 (pk corresponds to 5.3's Y, and here + // we use the address of u instead of u itself. Also, here we add the + // terms instead of taking the difference, and in the proof construction in + // vrf.GenerateProof, we correspondingly take the difference instead of + // taking the sum as they do in step 7 of section 5.1.) + // solhint-disable-next-line gas-custom-errors + require(_verifyLinearCombinationWithGenerator(c, pk, s, uWitness), "addr(c*pk+s*g)!=_uWitness"); + // Step 4. of IETF draft section 5.3 (pk corresponds to Y, seed to alpha_string) + uint256[2] memory hash = _hashToCurve(pk, seed); + // Step 6. of IETF draft section 5.3, but see note for step 5 about +/- terms + uint256[2] memory v = _linearCombination(c, gamma, cGammaWitness, s, hash, sHashWitness, zInv); + // Steps 7. and 8. of IETF draft section 5.3 + uint256 derivedC = _scalarFromCurvePoints(hash, pk, gamma, uWitness, v); + // solhint-disable-next-line gas-custom-errors + require(c == derivedC, "invalid proof"); + } + } + + // Domain-separation tag for the hash used as the final VRF output. + // Corresponds to vrfRandomOutputHashPrefix in vrf.go + uint256 internal constant VRF_RANDOM_OUTPUT_HASH_PREFIX = 3; + + struct Proof { + uint256[2] pk; + uint256[2] gamma; + uint256 c; + uint256 s; + uint256 seed; + address uWitness; + uint256[2] cGammaWitness; + uint256[2] sHashWitness; + uint256 zInv; + } + + /* *************************************************************************** + * @notice Returns proof's output, if proof is valid. Otherwise reverts + + * @param proof vrf proof components + * @param seed seed used to generate the vrf output + * + * Throws if proof is invalid, otherwise: + * @return output i.e., the random output implied by the proof + * *************************************************************************** + */ + function _randomValueFromVRFProof(Proof memory proof, uint256 seed) internal view returns (uint256 output) { + _verifyVRFProof( + proof.pk, + proof.gamma, + proof.c, + proof.s, + seed, + proof.uWitness, + proof.cGammaWitness, + proof.sHashWitness, + proof.zInv + ); + output = uint256(keccak256(abi.encode(VRF_RANDOM_OUTPUT_HASH_PREFIX, proof.gamma))); + return output; + } +} diff --git a/core/gethwrappers/generated/vrf_coordinator_test_v2_5/vrf_coordinator_test_v2_5.go b/core/gethwrappers/generated/vrf_coordinator_test_v2_5/vrf_coordinator_test_v2_5.go new file mode 100644 index 0000000000..6d6d38ef38 --- /dev/null +++ b/core/gethwrappers/generated/vrf_coordinator_test_v2_5/vrf_coordinator_test_v2_5.go @@ -0,0 +1,3994 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package vrf_coordinator_test_v2_5 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type VRFOldProof struct { + Pk [2]*big.Int + Gamma [2]*big.Int + C *big.Int + S *big.Int + Seed *big.Int + UWitness common.Address + CGammaWitness [2]*big.Int + SHashWitness [2]*big.Int + ZInv *big.Int +} + +type VRFTypesRequestCommitmentV2Plus struct { + BlockNum uint64 + SubId *big.Int + CallbackGasLimit uint32 + NumWords uint32 + Sender common.Address + ExtraArgs []byte +} + +type VRFV2PlusClientRandomWordsRequest struct { + KeyHash [32]byte + SubId *big.Int + RequestConfirmations uint16 + CallbackGasLimit uint32 + NumWords uint32 + ExtraArgs []byte +} + +var VRFCoordinatorTestV25MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxGas\",\"type\":\"uint256\"}],\"name\":\"GasPriceExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"premiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"max\",\"type\":\"uint8\"}],\"name\":\"InvalidPremiumPercentage\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"flatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"LinkDiscountTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"have\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"max\",\"type\":\"uint32\"}],\"name\":\"MsgDataTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"}],\"name\":\"FallbackWeiPerUnitLinkUsed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"deregisterMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"deregisterProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRFOld.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFTypes.RequestCommitmentV2Plus\",\"name\":\"rc\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fallbackWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_provingKeys\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"exists\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162005e6338038062005e6383398101604081905262000034916200017e565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d3565b5050506001600160a01b0316608052620001b0565b336001600160a01b038216036200012d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019157600080fd5b81516001600160a01b0381168114620001a957600080fd5b9392505050565b608051615c90620001d3600039600081816105d2015261331e0152615c906000f3fe60806040526004361061028c5760003560e01c80638402595e11610164578063b2a7cac5116100c6578063da2f26101161008a578063e72f6e3011610064578063e72f6e3014610904578063ee9d2d3814610924578063f2fde38b1461095157600080fd5b8063da2f261014610854578063dac83d29146108b3578063dc311dd3146108d357600080fd5b8063b2a7cac5146107b4578063bec4c08c146107d4578063caf70c4a146107f4578063cb63179714610814578063d98e620e1461083457600080fd5b80639d40a6fd11610128578063a63e0bfb11610102578063a63e0bfb14610747578063aa433aff14610767578063aefb212f1461078757600080fd5b80639d40a6fd146106da578063a21a23e414610712578063a4c0ed361461072757600080fd5b80638402595e1461064957806386fe91c7146106695780638da5cb5b1461068957806395b55cfc146106a75780639b1c385e146106ba57600080fd5b8063405b84fa1161020d57806364d51a2a116101d157806372e9d565116101ab57806372e9d565146105f457806379ba5097146106145780637a5a2aef1461062957600080fd5b806364d51a2a1461058b57806365982744146105a0578063689c4517146105c057600080fd5b8063405b84fa146104d057806340d6bb82146104f057806341af6c871461051b57806351cff8d91461054b5780635d06b4ab1461056b57600080fd5b806315c48b841161025457806315c48b84146103f157806318e3dd27146104195780631b6b6d23146104585780632f622e6b14610490578063301f42e9146104b057600080fd5b806304104edb14610291578063043bd6ae146102b3578063088070f5146102dc57806308821d58146103b15780630ae09540146103d1575b600080fd5b34801561029d57600080fd5b506102b16102ac366004614f21565b610971565b005b3480156102bf57600080fd5b506102c960105481565b6040519081526020015b60405180910390f35b3480156102e857600080fd5b50600c546103549061ffff81169063ffffffff62010000820481169160ff660100000000000082048116926701000000000000008304811692600160581b8104821692600160781b8204831692600160981b83041691600160b81b8104821691600160c01b9091041689565b6040805161ffff909a168a5263ffffffff98891660208b01529615159689019690965293861660608801529185166080870152841660a08601529290921660c084015260ff91821660e084015216610100820152610120016102d3565b3480156103bd57600080fd5b506102b16103cc366004614f4f565b610aea565b3480156103dd57600080fd5b506102b16103ec366004614f6b565b610ca7565b3480156103fd57600080fd5b5061040660c881565b60405161ffff90911681526020016102d3565b34801561042557600080fd5b50600a5461044090600160601b90046001600160601b031681565b6040516001600160601b0390911681526020016102d3565b34801561046457600080fd5b50600254610478906001600160a01b031681565b6040516001600160a01b0390911681526020016102d3565b34801561049c57600080fd5b506102b16104ab366004614f21565b610cef565b3480156104bc57600080fd5b506104406104cb3660046151cd565b610d95565b3480156104dc57600080fd5b506102b16104eb366004614f6b565b6110ab565b3480156104fc57600080fd5b506105066101f481565b60405163ffffffff90911681526020016102d3565b34801561052757600080fd5b5061053b6105363660046152bb565b61148d565b60405190151581526020016102d3565b34801561055757600080fd5b506102b1610566366004614f21565b611541565b34801561057757600080fd5b506102b1610586366004614f21565b611666565b34801561059757600080fd5b50610406606481565b3480156105ac57600080fd5b506102b16105bb3660046152d4565b611724565b3480156105cc57600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b34801561060057600080fd5b50600354610478906001600160a01b031681565b34801561062057600080fd5b506102b1611784565b34801561063557600080fd5b506102b1610644366004615302565b611835565b34801561065557600080fd5b506102b1610664366004614f21565b611969565b34801561067557600080fd5b50600a54610440906001600160601b031681565b34801561069557600080fd5b506000546001600160a01b0316610478565b6102b16106b53660046152bb565b611a84565b3480156106c657600080fd5b506102c96106d5366004615336565b611b94565b3480156106e657600080fd5b506007546106fa906001600160401b031681565b6040516001600160401b0390911681526020016102d3565b34801561071e57600080fd5b506102c9611fda565b34801561073357600080fd5b506102b1610742366004615370565b6121c1565b34801561075357600080fd5b506102b161076236600461541b565b612329565b34801561077357600080fd5b506102b16107823660046152bb565b612610565b34801561079357600080fd5b506107a76107a23660046154bc565b612643565b6040516102d39190615519565b3480156107c057600080fd5b506102b16107cf3660046152bb565b612745565b3480156107e057600080fd5b506102b16107ef366004614f6b565b612834565b34801561080057600080fd5b506102c961080f36600461552c565b612927565b34801561082057600080fd5b506102b161082f366004614f6b565b612957565b34801561084057600080fd5b506102c961084f3660046152bb565b612bc5565b34801561086057600080fd5b5061089461086f3660046152bb565b600d6020526000908152604090205460ff81169061010090046001600160401b031682565b6040805192151583526001600160401b039091166020830152016102d3565b3480156108bf57600080fd5b506102b16108ce366004614f6b565b612be6565b3480156108df57600080fd5b506108f36108ee3660046152bb565b612c81565b6040516102d3959493929190615581565b34801561091057600080fd5b506102b161091f366004614f21565b612d5a565b34801561093057600080fd5b506102c961093f3660046152bb565b600f6020526000908152604090205481565b34801561095d57600080fd5b506102b161096c366004614f21565b612f1b565b610979612f2c565b60115460005b81811015610abd57826001600160a01b0316601182815481106109a4576109a46155d6565b6000918252602090912001546001600160a01b031603610aad5760116109cb600184615602565b815481106109db576109db6155d6565b600091825260209091200154601180546001600160a01b039092169183908110610a0757610a076155d6565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506011805480610a4657610a46615615565b6000828152602090819020600019908301810180546001600160a01b03191690559091019091556040516001600160a01b03851681527ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af3791015b60405180910390a1505050565b610ab68161562b565b905061097f565b50604051635428d44960e01b81526001600160a01b03831660048201526024015b60405180910390fd5b50565b610af2612f2c565b604080518082018252600091610b21919084906002908390839080828437600092019190915250612927915050565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b03169183019190915291925090610b7f57604051631dfd6e1360e21b815260048101839052602401610ade565b6000828152600d60205260408120805468ffffffffffffffffff19169055600e54905b81811015610c515783600e8281548110610bbe57610bbe6155d6565b906000526020600020015403610c4157600e610bdb600184615602565b81548110610beb57610beb6155d6565b9060005260206000200154600e8281548110610c0957610c096155d6565b600091825260209091200155600e805480610c2657610c26615615565b60019003818190600052602060002001600090559055610c51565b610c4a8161562b565b9050610ba2565b507f9b6868e0eb737bcd72205360baa6bfd0ba4e4819a33ade2db384e8a8025639a5838360200151604051610c999291909182526001600160401b0316602082015260400190565b60405180910390a150505050565b81610cb181612f88565b610cb9612fdd565b610cc28361148d565b15610ce057604051631685ecdd60e31b815260040160405180910390fd5b610cea838361300b565b505050565b610cf7612fdd565b610cff612f2c565b600b54600160601b90046001600160601b0316610d1d8115156130ee565b600b80546bffffffffffffffffffffffff60601b19169055600a8054829190600c90610d5a908490600160601b90046001600160601b0316615644565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550610d9182826001600160601b031661310c565b5050565b6000610d9f612fdd565b60005a9050610324361115610dd157604051630f28961b60e01b81523660048201526103246024820152604401610ade565b6000610ddd8686613180565b90506000610df385836000015160200151613431565b60408301516060888101519293509163ffffffff16806001600160401b03811115610e2057610e20614f9b565b604051908082528060200260200182016040528015610e49578160200160208202803683370190505b50925060005b81811015610eb15760408051602081018590529081018290526060016040516020818303038152906040528051906020012060001c848281518110610e9657610e966155d6565b6020908102919091010152610eaa8161562b565b9050610e4f565b5050602080850180516000908152600f9092526040822082905551610ed7908a8561348c565b60208a8101516000908152600690915260409020805491925090601890610f0d90600160c01b90046001600160401b0316615664565b82546101009290920a6001600160401b0381810219909316918316021790915560808a01516001600160a01b03166000908152600460209081526040808320828e01518452909152902080549091600991610f7091600160481b9091041661568a565b91906101000a8154816001600160401b0302191690836001600160401b0316021790555060008960a0015160018b60a0015151610fad9190615602565b81518110610fbd57610fbd6155d6565b60209101015160f81c60011490506000610fd98887848d613530565b909950905080156110245760208088015160105460408051928352928201527f6ca648a381f22ead7e37773d934e64885dcf861fbfbb26c40354cbf0c4662d1a910160405180910390a15b5061103488828c60200151613568565b6020808b015187820151604080518781526001600160601b038d16948101949094528415159084015284151560608401528b1515608084015290917faeb4b4786571e184246d39587f659abf0e26f41f6a3358692250382c0cdb47b79060a00160405180910390a3505050505050505b9392505050565b6110b3612fdd565b6110bc816136c5565b6110e457604051635428d44960e01b81526001600160a01b0382166004820152602401610ade565b6000806000806110f386612c81565b945094505093509350336001600160a01b0316826001600160a01b03161461115d5760405162461bcd60e51b815260206004820152601660248201527f4e6f7420737562736372697074696f6e206f776e6572000000000000000000006044820152606401610ade565b6111668661148d565b156111b35760405162461bcd60e51b815260206004820152601660248201527f50656e64696e67207265717565737420657869737473000000000000000000006044820152606401610ade565b6040805160c0810182526001815260208082018990526001600160a01b03851682840152606082018490526001600160601b038088166080840152861660a083015291519091600091611208918491016156ad565b604051602081830303815290604052905061122288613730565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b0388169061125b908590600401615772565b6000604051808303818588803b15801561127457600080fd5b505af1158015611288573d6000803e3d6000fd5b50506002546001600160a01b0316158015935091506112b1905057506001600160601b03861615155b156113815760025460405163a9059cbb60e01b81526001600160a01b0389811660048301526001600160601b03891660248301529091169063a9059cbb906044016020604051808303816000875af1158015611311573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113359190615785565b6113815760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610ade565b600c805466ff0000000000001916660100000000000017905560005b8351811015611430578381815181106113b8576113b86155d6565b6020908102919091010151604051638ea9811760e01b81526001600160a01b038a8116600483015290911690638ea9811790602401600060405180830381600087803b15801561140757600080fd5b505af115801561141b573d6000803e3d6000fd5b50505050806114299061562b565b905061139d565b50600c805466ff00000000000019169055604080516001600160a01b0389168152602081018a90527fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187910160405180910390a15050505050505050565b600081815260056020526040812060020180548083036114b1575060009392505050565b60005b81811015611536576000600460008584815481106114d4576114d46155d6565b60009182526020808320909101546001600160a01b0316835282810193909352604091820181208982529092529020546001600160401b03600160481b90910416111561152657506001949350505050565b61152f8161562b565b90506114b4565b506000949350505050565b611549612fdd565b611551612f2c565b6002546001600160a01b031661157a5760405163c1f0c0a160e01b815260040160405180910390fd5b600b546001600160601b03166115918115156130ee565b600b80546bffffffffffffffffffffffff19169055600a80548291906000906115c49084906001600160601b0316615644565b82546101009290920a6001600160601b0381810219909316918316021790915560025460405163a9059cbb60e01b81526001600160a01b0386811660048301529285166024820152610d91935091169063a9059cbb906044015b6020604051808303816000875af115801561163d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116619190615785565b6130ee565b61166e612f2c565b611677816136c5565b156116a05760405163ac8a27ef60e01b81526001600160a01b0382166004820152602401610ade565b601180546001810182556000919091527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af016259060200160405180910390a150565b61172c612f2c565b6002546001600160a01b03161561175657604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001546001600160a01b031633146117de5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610ade565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61183d612f2c565b60408051808201825260009161186c919085906002908390839080828437600092019190915250612927915050565b6000818152600d602052604090205490915060ff16156118a257604051634a0b8fa760e01b815260048101829052602401610ade565b60408051808201825260018082526001600160401b0385811660208085018281526000888152600d835287812096518754925168ffffffffffffffffff1990931690151568ffffffffffffffff00191617610100929095169190910293909317909455600e805493840181559091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd9091018490558251848152918201527f9b911b2c240bfbef3b6a8f7ed6ee321d1258bb2a3fe6becab52ac1cd3210afd39101610aa0565b611971612f2c565b600a544790600160601b90046001600160601b0316818111156119b1576040516354ced18160e11b81526004810182905260248101839052604401610ade565b81811015610cea5760006119c58284615602565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114611a14576040519150601f19603f3d011682016040523d82523d6000602084013e611a19565b606091505b5050905080611a3b5760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b0387168152602081018490527f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c910160405180910390a15050505050565b611a8c612fdd565b600081815260056020526040902054611aad906001600160a01b03166138e2565b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611adc83856157a2565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611b2491906157a2565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902823484611b7791906157c2565b604080519283526020830191909152015b60405180910390a25050565b6000611b9e612fdd565b602080830135600081815260059092526040909120546001600160a01b0316611bda57604051630fb532db60e11b815260040160405180910390fd5b336000908152600460209081526040808320848452808352928190208151606081018352905460ff811615158083526001600160401b036101008304811695840195909552600160481b9091049093169181019190915290611c58576040516379bfd40160e01b815260048101849052336024820152604401610ade565b600c5461ffff16611c6f60608701604088016157d5565b61ffff161080611c92575060c8611c8c60608701604088016157d5565b61ffff16115b15611cd857611ca760608601604087016157d5565b600c5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610ade565b600c5462010000900463ffffffff16611cf760808701606088016157f0565b63ffffffff161115611d4757611d1360808601606087016157f0565b600c54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610ade565b6101f4611d5a60a08701608088016157f0565b63ffffffff161115611da057611d7660a08601608087016157f0565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610ade565b806020018051611daf90615664565b6001600160401b03169052604081018051611dc990615664565b6001600160401b03908116909152602082810151604080518935818501819052338284015260608201899052929094166080808601919091528151808603909101815260a08501825280519084012060c085019290925260e08085018390528151808603909101815261010090940190528251929091019190912060009190955090506000611e6b611e66611e6160a08a018a61580b565b613909565b61398a565b905085611e766139fb565b86611e8760808b0160608c016157f0565b611e9760a08c0160808d016157f0565b3386604051602001611eaf9796959493929190615858565b60405160208183030381529060405280519060200120600f600088815260200190815260200160002081905550336001600160a01b03168588600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e89868c6040016020810190611f2291906157d5565b8d6060016020810190611f3591906157f0565b8e6080016020810190611f4891906157f0565b89604051611f5b969594939291906158af565b60405180910390a45050600092835260209182526040928390208151815493830151929094015168ffffffffffffffffff1990931693151568ffffffffffffffff001916939093176101006001600160401b03928316021770ffffffffffffffff0000000000000000001916600160481b91909216021790555b919050565b6000611fe4612fdd565b6007546001600160401b031633611ffc600143615602565b6040516bffffffffffffffffffffffff19606093841b81166020830152914060348201523090921b1660548201526001600160c01b031960c083901b16606882015260700160408051601f19818403018152919052805160209091012091506120668160016158ee565b6007805467ffffffffffffffff19166001600160401b03928316179055604080516000808252608082018352602080830182815283850183815260608086018581528a86526006855287862093518454935191516001600160601b039182166001600160c01b031990951694909417600160601b91909216021777ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b9290981691909102969096179055835194850184523385528481018281528585018481528884526005835294909220855181546001600160a01b03199081166001600160a01b0392831617835593516001830180549095169116179092559251805192949391926121769260028501920190614e0f565b5061218691506008905084613a7c565b5060405133815283907f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d9060200160405180910390a2505090565b6121c9612fdd565b6002546001600160a01b031633146121f4576040516344b0e3c360e01b815260040160405180910390fd5b6020811461221557604051638129bbcd60e01b815260040160405180910390fd5b6000612223828401846152bb565b600081815260056020526040902054909150612247906001600160a01b03166138e2565b600081815260066020526040812080546001600160601b03169186919061226e83856157a2565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166122b691906157a2565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a82878461230991906157c2565b6040805192835260208301919091520160405180910390a2505050505050565b612331612f2c565b60c861ffff8a16111561236b5760405163539c34bb60e11b815261ffff8a1660048201819052602482015260c86044820152606401610ade565b6000851361238f576040516321ea67b360e11b815260048101869052602401610ade565b8363ffffffff168363ffffffff1611156123cc576040516313c06e5960e11b815263ffffffff808516600483015285166024820152604401610ade565b609b60ff831611156123fd57604051631d66288d60e11b815260ff83166004820152609b6024820152604401610ade565b609b60ff8216111561242e57604051631d66288d60e11b815260ff82166004820152609b6024820152604401610ade565b604080516101208101825261ffff8b1680825263ffffffff808c16602084018190526000848601528b8216606085018190528b8316608086018190528a841660a08701819052938a1660c0870181905260ff808b1660e08901819052908a16610100909801889052600c8054600160c01b90990260ff60c01b19600160b81b9093029290921661ffff60b81b19600160981b90940263ffffffff60981b19600160781b9099029890981676ffffffffffffffff00000000000000000000000000000019600160581b9096026effffffff000000000000000000000019670100000000000000909802979097166effffffffffffffffff000000000000196201000090990265ffffffffffff19909c16909a179a909a1796909616979097179390931791909116959095179290921793909316929092179190911790556010869055517f2c6b6b12413678366b05b145c5f00745bdd00e739131ab5de82484a50c9d78b6906125fd908b908b908b908b908b908b908b908b908b9061ffff99909916895263ffffffff97881660208a0152958716604089015293861660608801526080870192909252841660a086015290921660c084015260ff91821660e0840152166101008201526101200190565b60405180910390a1505050505050505050565b612618612f2c565b6000818152600560205260409020546001600160a01b0316612639816138e2565b610d91828261300b565b606060006126516008613a88565b905080841061267357604051631390f2a160e01b815260040160405180910390fd5b600061267f84866157c2565b90508181118061268d575083155b6126975780612699565b815b905060006126a78683615602565b9050806001600160401b038111156126c1576126c1614f9b565b6040519080825280602002602001820160405280156126ea578160200160208202803683370190505b50935060005b8181101561273a5761270d61270588836157c2565b600890613a92565b85828151811061271f5761271f6155d6565b60209081029190910101526127338161562b565b90506126f0565b505050505b92915050565b61274d612fdd565b6000818152600560205260409020546001600160a01b031661276e816138e2565b6000828152600560205260409020600101546001600160a01b031633146127c7576000828152600560205260409081902060010154905163d084e97560e01b81526001600160a01b039091166004820152602401610ade565b6000828152600560209081526040918290208054336001600160a01b03199182168117835560019092018054909116905582516001600160a01b03851681529182015283917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c93869101611b88565b8161283e81612f88565b612846612fdd565b6001600160a01b03821660009081526004602090815260408083208684529091529020805460ff16156128795750505050565b60008481526005602052604090206002018054606319016128ad576040516305a48e0f60e01b815260040160405180910390fd5b8154600160ff199091168117835581549081018255600082815260209081902090910180546001600160a01b0319166001600160a01b03871690811790915560405190815286917f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e191015b60405180910390a25050505050565b60008160405160200161293a9190615931565b604051602081830303815290604052805190602001209050919050565b8161296181612f88565b612969612fdd565b6129728361148d565b1561299057604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b038216600090815260046020908152604080832086845290915290205460ff166129e6576040516379bfd40160e01b8152600481018490526001600160a01b0383166024820152604401610ade565b600083815260056020908152604080832060020180548251818502810185019093528083529192909190830182828015612a4957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612a2b575b50505050509050600060018251612a609190615602565b905060005b8251811015612b6957846001600160a01b0316838281518110612a8a57612a8a6155d6565b60200260200101516001600160a01b031603612b59576000838381518110612ab457612ab46155d6565b6020026020010151905080600560008981526020019081526020016000206002018381548110612ae657612ae66155d6565b600091825260208083209190910180546001600160a01b0319166001600160a01b039490941693909317909255888152600590915260409020600201805480612b3157612b31615615565b600082815260209020810160001990810180546001600160a01b031916905501905550612b69565b612b628161562b565b9050612a65565b506001600160a01b0384166000818152600460209081526040808320898452825291829020805460ff19169055905191825286917f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a79101612918565b600e8181548110612bd557600080fd5b600091825260209091200154905081565b81612bf081612f88565b612bf8612fdd565b600083815260056020526040902060018101546001600160a01b03848116911614612c7b576001810180546001600160a01b0319166001600160a01b03851690811790915560408051338152602081019290925285917f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a191015b60405180910390a25b50505050565b600081815260056020526040812054819081906001600160a01b03166060612ca8826138e2565b600086815260066020908152604080832054600583529281902060020180548251818502810185019093528083526001600160601b0380861695600160601b810490911694600160c01b9091046001600160401b0316938893929091839190830182828015612d4057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612d22575b505050505090509450945094509450945091939590929450565b612d62612f2c565b6002546001600160a01b0316612d8b5760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612dd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612df8919061593f565b600a549091506001600160601b031681811115612e32576040516354ced18160e11b81526004810182905260248101839052604401610ade565b81811015610cea576000612e468284615602565b60025460405163a9059cbb60e01b81526001600160a01b0387811660048301526024820184905292935091169063a9059cbb906044016020604051808303816000875af1158015612e9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ebf9190615785565b612edc57604051631f01ff1360e21b815260040160405180910390fd5b604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b4366009101610c99565b612f23612f2c565b610ae781613a9e565b6000546001600160a01b03163314612f865760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610ade565b565b6000818152600560205260409020546001600160a01b0316612fa9816138e2565b336001600160a01b03821614610d9157604051636c51fda960e11b81526001600160a01b0382166004820152602401610ade565b600c546601000000000000900460ff1615612f865760405163769dd35360e11b815260040160405180910390fd5b60008061301784613730565b60025491935091506001600160a01b03161580159061303e57506001600160601b03821615155b156130865760025460405163a9059cbb60e01b81526001600160a01b0385811660048301526001600160601b038516602483015261308692169063a9059cbb9060440161161e565b61309983826001600160601b031661310c565b604080516001600160a01b03851681526001600160601b03808516602083015283169181019190915284907f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c490606001612c72565b80610ae757604051631e9acf1760e31b815260040160405180910390fd5b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613159576040519150601f19603f3d011682016040523d82523d6000602084013e61315e565b606091505b5050905080610cea5760405163950b247960e01b815260040160405180910390fd5b6040805160a081018252600060608201818152608083018290528252602082018190529181019190915260006131b98460000151612927565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b0316918301919091529192509061321757604051631dfd6e1360e21b815260048101839052602401610ade565b6000828660800151604051602001613239929190918252602082015260400190565b60408051601f1981840301815291815281516020928301206000818152600f909352908220549092509081900361328357604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d015193516132b2978a979096959101615958565b6040516020818303038152906040528051906020012081146132e75760405163354a450b60e21b815260040160405180910390fd5b60006132f68760000151613b47565b9050806133bf578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d3890602401602060405180830381865afa15801561336d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613391919061593f565b9050806133bf57865160405163175dadad60e01b81526001600160401b039091166004820152602401610ade565b60008860800151826040516020016133e1929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905060006134088a83613c1a565b604080516060810182529788526020880196909652948601949094525092979650505050505050565b6000816001600160401b03163a111561348457821561345a57506001600160401b03811661273f565b60405163435e532d60e11b81523a60048201526001600160401b0383166024820152604401610ade565b503a92915050565b6000806000631fe543e360e01b86856040516024016134ac9291906159ab565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600c805466ff000000000000191666010000000000001790559086015160808701519192506135169163ffffffff9091169083613c85565b600c805466ff000000000000191690559695505050505050565b600080831561354f57613544868685613cd1565b60009150915061355f565b61355a868685613de2565b915091505b94509492505050565b6000818152600660205260409020821561362c5780546001600160601b03600160601b90910481169085168110156135b357604051631e9acf1760e31b815260040160405180910390fd5b6135bd8582615644565b82546bffffffffffffffffffffffff60601b1916600160601b6001600160601b039283168102919091178455600b805488939192600c926136029286929004166157a2565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555050612c7b565b80546001600160601b0390811690851681101561365c57604051631e9acf1760e31b815260040160405180910390fd5b6136668582615644565b82546bffffffffffffffffffffffff19166001600160601b03918216178355600b8054879260009161369a918591166157a2565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050505050565b601154600090815b8181101561372657836001600160a01b0316601182815481106136f2576136f26155d6565b6000918252602090912001546001600160a01b031603613716575060019392505050565b61371f8161562b565b90506136cd565b5060009392505050565b60008181526005602090815260408083206006909252822054600290910180546001600160601b0380841694600160601b90940416925b818110156137dc5760046000848381548110613785576137856155d6565b60009182526020808320909101546001600160a01b0316835282810193909352604091820181208982529092529020805470ffffffffffffffffffffffffffffffffff191690556137d58161562b565b9050613767565b50600085815260056020526040812080546001600160a01b031990811682556001820180549091169055906138146002830182614e74565b5050600085815260066020526040812055613830600886613fd4565b506001600160601b0384161561388357600a805485919060009061385e9084906001600160601b0316615644565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001600160601b038316156138db5782600a600c8282829054906101000a90046001600160601b03166138b69190615644565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b5050915091565b6001600160a01b038116610ae757604051630fb532db60e11b815260040160405180910390fd5b6040805160208101909152600081526000829003613936575060408051602081019091526000815261273f565b63125fa26760e31b61394883856159cc565b6001600160e01b0319161461397057604051632923fee760e11b815260040160405180910390fd5b61397d82600481866159fc565b8101906110a49190615a26565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa826040516024016139c391511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b600046613a0781613fe0565b15613a755760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a6f919061593f565b91505090565b4391505090565b60006110a48383614003565b600061273f825490565b60006110a48383614052565b336001600160a01b03821603613af65760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610ade565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613b5381613fe0565b15613c0b57610100836001600160401b0316613b6d6139fb565b613b779190615602565b1180613b935750613b866139fb565b836001600160401b031610155b15613ba15750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a82906024015b602060405180830381865afa158015613be7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a4919061593f565b50506001600160401b03164090565b6000613c4e8360000151846020015185604001518660600151868860a001518960c001518a60e001518b610100015161407c565b60038360200151604051602001613c66929190615a71565b60408051601f1981840301815291905280516020909101209392505050565b60005a611388811015613c9757600080fd5b611388810390508460408204820311613caf57600080fd5b50823b613cbb57600080fd5b60008083516020850160008789f1949350505050565b600080613d146000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506142a792505050565b905060005a600c54613d34908890600160581b900463ffffffff166157c2565b613d3e9190615602565b613d489086615a85565b600c54909150600090613d6d90600160781b900463ffffffff1664e8d4a51000615a85565b90508415613db957600c548190606490600160b81b900460ff16613d9185876157c2565b613d9b9190615a85565b613da59190615ab2565b613daf91906157c2565b93505050506110a4565b600c548190606490613dd590600160b81b900460ff1682615ac6565b60ff16613d9185876157c2565b600080600080613df0614387565b9150915060008213613e18576040516321ea67b360e11b815260048101839052602401610ade565b6000613e5a6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506142a792505050565b9050600083825a600c54613e7c908d90600160581b900463ffffffff166157c2565b613e869190615602565b613e90908b615a85565b613e9a91906157c2565b613eac90670de0b6b3a7640000615a85565b613eb69190615ab2565b600c54909150600090613edf9063ffffffff600160981b8204811691600160781b900416615adf565b613ef49063ffffffff1664e8d4a51000615a85565b9050600085613f0b83670de0b6b3a7640000615a85565b613f159190615ab2565b905060008915613f5657600c548290606490613f3b90600160c01b900460ff1687615a85565b613f459190615ab2565b613f4f91906157c2565b9050613f96565b600c548290606490613f7290600160c01b900460ff1682615ac6565b613f7f9060ff1687615a85565b613f899190615ab2565b613f9391906157c2565b90505b6b033b2e3c9fd0803ce8000000811115613fc35760405163e80fa38160e01b815260040160405180910390fd5b9b949a509398505050505050505050565b60006110a48383614452565b600061a4b1821480613ff4575062066eed82145b8061273f57505062066eee1490565b600081815260018301602052604081205461404a5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561273f565b50600061273f565b6000826000018281548110614069576140696155d6565b9060005260206000200154905092915050565b6140858961454c565b6140d15760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e2063757276650000000000006044820152606401610ade565b6140da8861454c565b6141265760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e20637572766500000000000000000000006044820152606401610ade565b61412f8361454c565b61417b5760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610ade565b6141848261454c565b6141d05760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610ade565b6141dc878a8887614625565b6142285760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e657373000000000000006044820152606401610ade565b60006142348a87614748565b90506000614247898b878b8689896147ac565b90506000614258838d8d8a866148d8565b9050808a146142995760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610ade565b505050505050505050505050565b6000466142b381613fe0565b156142f757606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613be7573d6000803e3d6000fd5b61430081614918565b1561437e5773420000000000000000000000000000000000000f6001600160a01b03166349948e0e84604051806080016040528060488152602001615c3c60489139604051602001614353929190615afc565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613bca9190615772565b50600092915050565b600c5460035460408051633fabe5a360e21b81529051600093849367010000000000000090910463ffffffff169284926001600160a01b039092169163feaf968c9160048082019260a0929091908290030181865afa1580156143ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144129190615b45565b50919650909250505063ffffffff82161580159061443e57506144358142615602565b8263ffffffff16105b9250821561444c5760105493505b50509091565b6000818152600183016020526040812054801561453b576000614476600183615602565b855490915060009061448a90600190615602565b90508181146144ef5760008660000182815481106144aa576144aa6155d6565b90600052602060002001549050808760000184815481106144cd576144cd6155d6565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061450057614500615615565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061273f565b600091505061273f565b5092915050565b80516000906401000003d019116145a55760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e61746500000000000000000000000000006044820152606401610ade565b60208201516401000003d019116145fe5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e61746500000000000000000000000000006044820152606401610ade565b60208201516401000003d01990800961461e8360005b602002015161495f565b1492915050565b60006001600160a01b03821661466b5760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610ade565b60208401516000906001161561468257601c614685565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614720573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614750614e92565b61477d6001848460405160200161476993929190615b95565b604051602081830303815290604052614983565b90505b6147898161454c565b61273f5780516040805160208101929092526147a59101614769565b9050614780565b6147b4614e92565b825186516401000003d01991829006919006036148135760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610ade565b61481e8789886149d0565b61486a5760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c6564000000000000000000006044820152606401610ade565b6148758486856149d0565b6148c15760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c65640000000000000000006044820152606401610ade565b6148cc868484614afb565b98975050505050505050565b6000600286868685876040516020016148f696959493929190615bb6565b60408051601f1981840301815291905280516020909101209695505050505050565b6000600a82148061492a57506101a482145b80614937575062aa37dc82145b80614943575061210582145b80614950575062014a3382145b8061273f57505062014a341490565b6000806401000003d01980848509840990506401000003d019600782089392505050565b61498b614e92565b61499482614bc2565b81526149a96149a4826000614614565b614bfd565b6020820181905260029006600103611fd5576020810180516401000003d019039052919050565b600082600003614a105760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610ade565b83516020850151600090614a2690600290615c15565b15614a3257601c614a35565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614aa7573d6000803e3d6000fd5b505050602060405103519050600086604051602001614ac69190615c29565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614b03614e92565b835160208086015185519186015160009384938493614b2493909190614c1d565b919450925090506401000003d019858209600114614b845760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a000000000000006044820152606401610ade565b60405180604001604052806401000003d01980614ba357614ba3615a9c565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611fd557604080516020808201939093528151808203840181529082019091528051910120614bca565b600061273f826002614c166401000003d01960016157c2565b901c614cfd565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614c5d83838585614da2565b9098509050614c6e88828e88614dc6565b9098509050614c7f88828c87614dc6565b90985090506000614c928d878b85614dc6565b9098509050614ca388828686614da2565b9098509050614cb488828e89614dc6565b9098509050818114614ce9576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614ced565b8196505b5050505050509450945094915050565b600080614d08614eb0565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614d3a614ece565b60208160c0846005600019fa925082600003614d985760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c7572652100000000000000000000000000006044820152606401610ade565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614e64579160200282015b82811115614e6457825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614e2f565b50614e70929150614eec565b5090565b5080546000825590600052602060002090810190610ae79190614eec565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614e705760008155600101614eed565b6001600160a01b0381168114610ae757600080fd5b8035611fd581614f01565b600060208284031215614f3357600080fd5b81356110a481614f01565b806040810183101561273f57600080fd5b600060408284031215614f6157600080fd5b6110a48383614f3e565b60008060408385031215614f7e57600080fd5b823591506020830135614f9081614f01565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715614fd357614fd3614f9b565b60405290565b60405161012081016001600160401b0381118282101715614fd357614fd3614f9b565b604051601f8201601f191681016001600160401b038111828210171561502457615024614f9b565b604052919050565b600082601f83011261503d57600080fd5b604051604081018181106001600160401b038211171561505f5761505f614f9b565b806040525080604084018581111561507657600080fd5b845b81811015615090578035835260209283019201615078565b509195945050505050565b80356001600160401b0381168114611fd557600080fd5b803563ffffffff81168114611fd557600080fd5b600060c082840312156150d857600080fd5b6150e0614fb1565b90506150eb8261509b565b815260208083013581830152615103604084016150b2565b6040830152615114606084016150b2565b6060830152608083013561512781614f01565b608083015260a08301356001600160401b038082111561514657600080fd5b818501915085601f83011261515a57600080fd5b81358181111561516c5761516c614f9b565b61517e601f8201601f19168501614ffc565b9150808252868482850101111561519457600080fd5b80848401858401376000848284010152508060a085015250505092915050565b8015158114610ae757600080fd5b8035611fd5816151b4565b60008060008385036101e08112156151e457600080fd5b6101a0808212156151f457600080fd5b6151fc614fd9565b9150615208878761502c565b8252615217876040880161502c565b60208301526080860135604083015260a0860135606083015260c0860135608083015261524660e08701614f16565b60a083015261010061525a8882890161502c565b60c084015261526d88610140890161502c565b60e0840152610180870135908301529093508401356001600160401b0381111561529657600080fd5b6152a2868287016150c6565b9250506152b26101c085016151c2565b90509250925092565b6000602082840312156152cd57600080fd5b5035919050565b600080604083850312156152e757600080fd5b82356152f281614f01565b91506020830135614f9081614f01565b6000806060838503121561531557600080fd5b61531f8484614f3e565b915061532d6040840161509b565b90509250929050565b60006020828403121561534857600080fd5b81356001600160401b0381111561535e57600080fd5b820160c081850312156110a457600080fd5b6000806000806060858703121561538657600080fd5b843561539181614f01565b93506020850135925060408501356001600160401b03808211156153b457600080fd5b818701915087601f8301126153c857600080fd5b8135818111156153d757600080fd5b8860208285010111156153e957600080fd5b95989497505060200194505050565b803561ffff81168114611fd557600080fd5b803560ff81168114611fd557600080fd5b60008060008060008060008060006101208a8c03121561543a57600080fd5b6154438a6153f8565b985061545160208b016150b2565b975061545f60408b016150b2565b965061546d60608b016150b2565b955060808a0135945061548260a08b016150b2565b935061549060c08b016150b2565b925061549e60e08b0161540a565b91506154ad6101008b0161540a565b90509295985092959850929598565b600080604083850312156154cf57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b8381101561550e578151875295820195908201906001016154f2565b509495945050505050565b6020815260006110a460208301846154de565b60006040828403121561553e57600080fd5b6110a4838361502c565b600081518084526020808501945080840160005b8381101561550e5781516001600160a01b03168752958201959082019060010161555c565b60006001600160601b0380881683528087166020840152506001600160401b03851660408301526001600160a01b038416606083015260a060808301526155cb60a0830184615548565b979650505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561273f5761273f6155ec565b634e487b7160e01b600052603160045260246000fd5b60006001820161563d5761563d6155ec565b5060010190565b6001600160601b03828116828216039080821115614545576145456155ec565b60006001600160401b03808316818103615680576156806155ec565b6001019392505050565b60006001600160401b038216806156a3576156a36155ec565b6000190192915050565b6020815260ff8251166020820152602082015160408201526001600160a01b0360408301511660608201526000606083015160c060808401526156f360e0840182615548565b905060808401516001600160601b0380821660a08601528060a08701511660c086015250508091505092915050565b60005b8381101561573d578181015183820152602001615725565b50506000910152565b6000815180845261575e816020860160208601615722565b601f01601f19169290920160200192915050565b6020815260006110a46020830184615746565b60006020828403121561579757600080fd5b81516110a4816151b4565b6001600160601b03818116838216019080821115614545576145456155ec565b8082018082111561273f5761273f6155ec565b6000602082840312156157e757600080fd5b6110a4826153f8565b60006020828403121561580257600080fd5b6110a4826150b2565b6000808335601e1984360301811261582257600080fd5b8301803591506001600160401b0382111561583c57600080fd5b60200191503681900382131561585157600080fd5b9250929050565b878152866020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526158a260e0830184615746565b9998505050505050505050565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a08301526148cc60c0830184615746565b6001600160401b03818116838216019080821115614545576145456155ec565b8060005b6002811015612c7b578151845260209384019390910190600101615912565b6040810161273f828461590e565b60006020828403121561595157600080fd5b5051919050565b8781526001600160401b0387166020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526158a260e0830184615746565b8281526040602082015260006159c460408301846154de565b949350505050565b6001600160e01b031981358181169160048510156159f45780818660040360031b1b83161692505b505092915050565b60008085851115615a0c57600080fd5b83861115615a1957600080fd5b5050820193919092039150565b600060208284031215615a3857600080fd5b604051602081018181106001600160401b0382111715615a5a57615a5a614f9b565b6040528235615a68816151b4565b81529392505050565b828152606081016110a4602083018461590e565b808202811582820484141761273f5761273f6155ec565b634e487b7160e01b600052601260045260246000fd5b600082615ac157615ac1615a9c565b500490565b60ff818116838216019081111561273f5761273f6155ec565b63ffffffff828116828216039080821115614545576145456155ec565b60008351615b0e818460208801615722565b835190830190615b22818360208801615722565b01949350505050565b805169ffffffffffffffffffff81168114611fd557600080fd5b600080600080600060a08688031215615b5d57600080fd5b615b6686615b2b565b9450602086015193506040860151925060608601519150615b8960808701615b2b565b90509295509295909350565b838152615ba5602082018461590e565b606081019190915260800192915050565b868152615bc6602082018761590e565b615bd3606082018661590e565b615be060a082018561590e565b615bed60e082018461590e565b60609190911b6bffffffffffffffffffffffff19166101208201526101340195945050505050565b600082615c2457615c24615a9c565b500690565b615c33818361590e565b60400191905056fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", +} + +var VRFCoordinatorTestV25ABI = VRFCoordinatorTestV25MetaData.ABI + +var VRFCoordinatorTestV25Bin = VRFCoordinatorTestV25MetaData.Bin + +func DeployVRFCoordinatorTestV25(auth *bind.TransactOpts, backend bind.ContractBackend, blockhashStore common.Address) (common.Address, *types.Transaction, *VRFCoordinatorTestV25, error) { + parsed, err := VRFCoordinatorTestV25MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VRFCoordinatorTestV25Bin), backend, blockhashStore) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &VRFCoordinatorTestV25{address: address, abi: *parsed, VRFCoordinatorTestV25Caller: VRFCoordinatorTestV25Caller{contract: contract}, VRFCoordinatorTestV25Transactor: VRFCoordinatorTestV25Transactor{contract: contract}, VRFCoordinatorTestV25Filterer: VRFCoordinatorTestV25Filterer{contract: contract}}, nil +} + +type VRFCoordinatorTestV25 struct { + address common.Address + abi abi.ABI + VRFCoordinatorTestV25Caller + VRFCoordinatorTestV25Transactor + VRFCoordinatorTestV25Filterer +} + +type VRFCoordinatorTestV25Caller struct { + contract *bind.BoundContract +} + +type VRFCoordinatorTestV25Transactor struct { + contract *bind.BoundContract +} + +type VRFCoordinatorTestV25Filterer struct { + contract *bind.BoundContract +} + +type VRFCoordinatorTestV25Session struct { + Contract *VRFCoordinatorTestV25 + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VRFCoordinatorTestV25CallerSession struct { + Contract *VRFCoordinatorTestV25Caller + CallOpts bind.CallOpts +} + +type VRFCoordinatorTestV25TransactorSession struct { + Contract *VRFCoordinatorTestV25Transactor + TransactOpts bind.TransactOpts +} + +type VRFCoordinatorTestV25Raw struct { + Contract *VRFCoordinatorTestV25 +} + +type VRFCoordinatorTestV25CallerRaw struct { + Contract *VRFCoordinatorTestV25Caller +} + +type VRFCoordinatorTestV25TransactorRaw struct { + Contract *VRFCoordinatorTestV25Transactor +} + +func NewVRFCoordinatorTestV25(address common.Address, backend bind.ContractBackend) (*VRFCoordinatorTestV25, error) { + abi, err := abi.JSON(strings.NewReader(VRFCoordinatorTestV25ABI)) + if err != nil { + return nil, err + } + contract, err := bindVRFCoordinatorTestV25(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25{address: address, abi: abi, VRFCoordinatorTestV25Caller: VRFCoordinatorTestV25Caller{contract: contract}, VRFCoordinatorTestV25Transactor: VRFCoordinatorTestV25Transactor{contract: contract}, VRFCoordinatorTestV25Filterer: VRFCoordinatorTestV25Filterer{contract: contract}}, nil +} + +func NewVRFCoordinatorTestV25Caller(address common.Address, caller bind.ContractCaller) (*VRFCoordinatorTestV25Caller, error) { + contract, err := bindVRFCoordinatorTestV25(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25Caller{contract: contract}, nil +} + +func NewVRFCoordinatorTestV25Transactor(address common.Address, transactor bind.ContractTransactor) (*VRFCoordinatorTestV25Transactor, error) { + contract, err := bindVRFCoordinatorTestV25(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25Transactor{contract: contract}, nil +} + +func NewVRFCoordinatorTestV25Filterer(address common.Address, filterer bind.ContractFilterer) (*VRFCoordinatorTestV25Filterer, error) { + contract, err := bindVRFCoordinatorTestV25(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25Filterer{contract: contract}, nil +} + +func bindVRFCoordinatorTestV25(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VRFCoordinatorTestV25MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFCoordinatorTestV25.Contract.VRFCoordinatorTestV25Caller.contract.Call(opts, result, method, params...) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.VRFCoordinatorTestV25Transactor.contract.Transfer(opts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.VRFCoordinatorTestV25Transactor.contract.Transact(opts, method, params...) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFCoordinatorTestV25.Contract.contract.Call(opts, result, method, params...) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.contract.Transfer(opts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.contract.Transact(opts, method, params...) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) BLOCKHASHSTORE(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "BLOCKHASH_STORE") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) BLOCKHASHSTORE() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.BLOCKHASHSTORE(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) BLOCKHASHSTORE() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.BLOCKHASHSTORE(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) LINK(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "LINK") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) LINK() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.LINK(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) LINK() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.LINK(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) LINKNATIVEFEED(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "LINK_NATIVE_FEED") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) LINKNATIVEFEED() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.LINKNATIVEFEED(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) LINKNATIVEFEED() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.LINKNATIVEFEED(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "MAX_CONSUMERS") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) MAXCONSUMERS() (uint16, error) { + return _VRFCoordinatorTestV25.Contract.MAXCONSUMERS(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) MAXCONSUMERS() (uint16, error) { + return _VRFCoordinatorTestV25.Contract.MAXCONSUMERS(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) MAXNUMWORDS(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "MAX_NUM_WORDS") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) MAXNUMWORDS() (uint32, error) { + return _VRFCoordinatorTestV25.Contract.MAXNUMWORDS(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) MAXNUMWORDS() (uint32, error) { + return _VRFCoordinatorTestV25.Contract.MAXNUMWORDS(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) MAXREQUESTCONFIRMATIONS(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "MAX_REQUEST_CONFIRMATIONS") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) MAXREQUESTCONFIRMATIONS() (uint16, error) { + return _VRFCoordinatorTestV25.Contract.MAXREQUESTCONFIRMATIONS(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) MAXREQUESTCONFIRMATIONS() (uint16, error) { + return _VRFCoordinatorTestV25.Contract.MAXREQUESTCONFIRMATIONS(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) GetActiveSubscriptionIds(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "getActiveSubscriptionIds", startIndex, maxCount) + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) GetActiveSubscriptionIds(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.GetActiveSubscriptionIds(&_VRFCoordinatorTestV25.CallOpts, startIndex, maxCount) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) GetActiveSubscriptionIds(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.GetActiveSubscriptionIds(&_VRFCoordinatorTestV25.CallOpts, startIndex, maxCount) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, + + error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "getSubscription", subId) + + outstruct := new(GetSubscription) + if err != nil { + return *outstruct, err + } + + outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.NativeBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.ReqCount = *abi.ConvertType(out[2], new(uint64)).(*uint64) + outstruct.SubOwner = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) + outstruct.Consumers = *abi.ConvertType(out[4], new([]common.Address)).(*[]common.Address) + + return *outstruct, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) GetSubscription(subId *big.Int) (GetSubscription, + + error) { + return _VRFCoordinatorTestV25.Contract.GetSubscription(&_VRFCoordinatorTestV25.CallOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) GetSubscription(subId *big.Int) (GetSubscription, + + error) { + return _VRFCoordinatorTestV25.Contract.GetSubscription(&_VRFCoordinatorTestV25.CallOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) HashOfKey(opts *bind.CallOpts, publicKey [2]*big.Int) ([32]byte, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "hashOfKey", publicKey) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) HashOfKey(publicKey [2]*big.Int) ([32]byte, error) { + return _VRFCoordinatorTestV25.Contract.HashOfKey(&_VRFCoordinatorTestV25.CallOpts, publicKey) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) HashOfKey(publicKey [2]*big.Int) ([32]byte, error) { + return _VRFCoordinatorTestV25.Contract.HashOfKey(&_VRFCoordinatorTestV25.CallOpts, publicKey) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) Owner() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.Owner(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) Owner() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.Owner(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) PendingRequestExists(opts *bind.CallOpts, subId *big.Int) (bool, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "pendingRequestExists", subId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) PendingRequestExists(subId *big.Int) (bool, error) { + return _VRFCoordinatorTestV25.Contract.PendingRequestExists(&_VRFCoordinatorTestV25.CallOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) PendingRequestExists(subId *big.Int) (bool, error) { + return _VRFCoordinatorTestV25.Contract.PendingRequestExists(&_VRFCoordinatorTestV25.CallOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) SConfig(opts *bind.CallOpts) (SConfig, + + error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_config") + + outstruct := new(SConfig) + if err != nil { + return *outstruct, err + } + + outstruct.MinimumRequestConfirmations = *abi.ConvertType(out[0], new(uint16)).(*uint16) + outstruct.MaxGasLimit = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ReentrancyLock = *abi.ConvertType(out[2], new(bool)).(*bool) + outstruct.StalenessSeconds = *abi.ConvertType(out[3], new(uint32)).(*uint32) + outstruct.GasAfterPaymentCalculation = *abi.ConvertType(out[4], new(uint32)).(*uint32) + outstruct.FulfillmentFlatFeeNativePPM = *abi.ConvertType(out[5], new(uint32)).(*uint32) + outstruct.FulfillmentFlatFeeLinkDiscountPPM = *abi.ConvertType(out[6], new(uint32)).(*uint32) + outstruct.NativePremiumPercentage = *abi.ConvertType(out[7], new(uint8)).(*uint8) + outstruct.LinkPremiumPercentage = *abi.ConvertType(out[8], new(uint8)).(*uint8) + + return *outstruct, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SConfig() (SConfig, + + error) { + return _VRFCoordinatorTestV25.Contract.SConfig(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) SConfig() (SConfig, + + error) { + return _VRFCoordinatorTestV25.Contract.SConfig(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) SCurrentSubNonce(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_currentSubNonce") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SCurrentSubNonce() (uint64, error) { + return _VRFCoordinatorTestV25.Contract.SCurrentSubNonce(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) SCurrentSubNonce() (uint64, error) { + return _VRFCoordinatorTestV25.Contract.SCurrentSubNonce(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_fallbackWeiPerUnitLink") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SFallbackWeiPerUnitLink() (*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) SFallbackWeiPerUnitLink() (*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_provingKeyHashes", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SProvingKeyHashes(arg0 *big.Int) ([32]byte, error) { + return _VRFCoordinatorTestV25.Contract.SProvingKeyHashes(&_VRFCoordinatorTestV25.CallOpts, arg0) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) SProvingKeyHashes(arg0 *big.Int) ([32]byte, error) { + return _VRFCoordinatorTestV25.Contract.SProvingKeyHashes(&_VRFCoordinatorTestV25.CallOpts, arg0) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (SProvingKeys, + + error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_provingKeys", arg0) + + outstruct := new(SProvingKeys) + if err != nil { + return *outstruct, err + } + + outstruct.Exists = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.MaxGas = *abi.ConvertType(out[1], new(uint64)).(*uint64) + + return *outstruct, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SProvingKeys(arg0 [32]byte) (SProvingKeys, + + error) { + return _VRFCoordinatorTestV25.Contract.SProvingKeys(&_VRFCoordinatorTestV25.CallOpts, arg0) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) SProvingKeys(arg0 [32]byte) (SProvingKeys, + + error) { + return _VRFCoordinatorTestV25.Contract.SProvingKeys(&_VRFCoordinatorTestV25.CallOpts, arg0) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_requestCommitments", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SRequestCommitments(arg0 *big.Int) ([32]byte, error) { + return _VRFCoordinatorTestV25.Contract.SRequestCommitments(&_VRFCoordinatorTestV25.CallOpts, arg0) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) SRequestCommitments(arg0 *big.Int) ([32]byte, error) { + return _VRFCoordinatorTestV25.Contract.SRequestCommitments(&_VRFCoordinatorTestV25.CallOpts, arg0) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) STotalBalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_totalBalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) STotalBalance() (*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.STotalBalance(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) STotalBalance() (*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.STotalBalance(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) STotalNativeBalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_totalNativeBalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) STotalNativeBalance() (*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.STotalNativeBalance(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) STotalNativeBalance() (*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.STotalNativeBalance(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "acceptOwnership") +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) AcceptOwnership() (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.AcceptOwnership(&_VRFCoordinatorTestV25.TransactOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.AcceptOwnership(&_VRFCoordinatorTestV25.TransactOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "acceptSubscriptionOwnerTransfer", subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinatorTestV25.TransactOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinatorTestV25.TransactOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "addConsumer", subId, consumer) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.AddConsumer(&_VRFCoordinatorTestV25.TransactOpts, subId, consumer) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.AddConsumer(&_VRFCoordinatorTestV25.TransactOpts, subId, consumer) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "cancelSubscription", subId, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.CancelSubscription(&_VRFCoordinatorTestV25.TransactOpts, subId, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.CancelSubscription(&_VRFCoordinatorTestV25.TransactOpts, subId, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "createSubscription") +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) CreateSubscription() (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.CreateSubscription(&_VRFCoordinatorTestV25.TransactOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) CreateSubscription() (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.CreateSubscription(&_VRFCoordinatorTestV25.TransactOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) DeregisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "deregisterMigratableCoordinator", target) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) DeregisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.DeregisterMigratableCoordinator(&_VRFCoordinatorTestV25.TransactOpts, target) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) DeregisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.DeregisterMigratableCoordinator(&_VRFCoordinatorTestV25.TransactOpts, target) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) DeregisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "deregisterProvingKey", publicProvingKey) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) DeregisterProvingKey(publicProvingKey [2]*big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.DeregisterProvingKey(&_VRFCoordinatorTestV25.TransactOpts, publicProvingKey) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) DeregisterProvingKey(publicProvingKey [2]*big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.DeregisterProvingKey(&_VRFCoordinatorTestV25.TransactOpts, publicProvingKey) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) FulfillRandomWords(opts *bind.TransactOpts, proof VRFOldProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "fulfillRandomWords", proof, rc, onlyPremium) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) FulfillRandomWords(proof VRFOldProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.FulfillRandomWords(&_VRFCoordinatorTestV25.TransactOpts, proof, rc, onlyPremium) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) FulfillRandomWords(proof VRFOldProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.FulfillRandomWords(&_VRFCoordinatorTestV25.TransactOpts, proof, rc, onlyPremium) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "fundSubscriptionWithNative", subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) FundSubscriptionWithNative(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.FundSubscriptionWithNative(&_VRFCoordinatorTestV25.TransactOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) FundSubscriptionWithNative(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.FundSubscriptionWithNative(&_VRFCoordinatorTestV25.TransactOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) Migrate(opts *bind.TransactOpts, subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "migrate", subId, newCoordinator) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) Migrate(subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.Migrate(&_VRFCoordinatorTestV25.TransactOpts, subId, newCoordinator) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) Migrate(subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.Migrate(&_VRFCoordinatorTestV25.TransactOpts, subId, newCoordinator) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "onTokenTransfer", arg0, amount, data) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.OnTokenTransfer(&_VRFCoordinatorTestV25.TransactOpts, arg0, amount, data) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.OnTokenTransfer(&_VRFCoordinatorTestV25.TransactOpts, arg0, amount, data) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) OwnerCancelSubscription(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "ownerCancelSubscription", subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) OwnerCancelSubscription(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.OwnerCancelSubscription(&_VRFCoordinatorTestV25.TransactOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) OwnerCancelSubscription(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.OwnerCancelSubscription(&_VRFCoordinatorTestV25.TransactOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "recoverFunds", to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RecoverFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RecoverFunds(&_VRFCoordinatorTestV25.TransactOpts, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RecoverFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RecoverFunds(&_VRFCoordinatorTestV25.TransactOpts, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RecoverNativeFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "recoverNativeFunds", to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RecoverNativeFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RecoverNativeFunds(&_VRFCoordinatorTestV25.TransactOpts, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RecoverNativeFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RecoverNativeFunds(&_VRFCoordinatorTestV25.TransactOpts, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "registerMigratableCoordinator", target) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RegisterMigratableCoordinator(&_VRFCoordinatorTestV25.TransactOpts, target) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RegisterMigratableCoordinator(&_VRFCoordinatorTestV25.TransactOpts, target) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RegisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "registerProvingKey", publicProvingKey, maxGas) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RegisterProvingKey(publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RegisterProvingKey(&_VRFCoordinatorTestV25.TransactOpts, publicProvingKey, maxGas) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RegisterProvingKey(publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RegisterProvingKey(&_VRFCoordinatorTestV25.TransactOpts, publicProvingKey, maxGas) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "removeConsumer", subId, consumer) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RemoveConsumer(&_VRFCoordinatorTestV25.TransactOpts, subId, consumer) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RemoveConsumer(&_VRFCoordinatorTestV25.TransactOpts, subId, consumer) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RequestRandomWords(opts *bind.TransactOpts, req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "requestRandomWords", req) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RequestRandomWords(&_VRFCoordinatorTestV25.TransactOpts, req) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RequestRandomWords(&_VRFCoordinatorTestV25.TransactOpts, req) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "requestSubscriptionOwnerTransfer", subId, newOwner) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinatorTestV25.TransactOpts, subId, newOwner) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinatorTestV25.TransactOpts, subId, newOwner) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) SetConfig(opts *bind.TransactOpts, minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeNativePPM uint32, fulfillmentFlatFeeLinkDiscountPPM uint32, nativePremiumPercentage uint8, linkPremiumPercentage uint8) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "setConfig", minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, fulfillmentFlatFeeNativePPM, fulfillmentFlatFeeLinkDiscountPPM, nativePremiumPercentage, linkPremiumPercentage) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeNativePPM uint32, fulfillmentFlatFeeLinkDiscountPPM uint32, nativePremiumPercentage uint8, linkPremiumPercentage uint8) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.SetConfig(&_VRFCoordinatorTestV25.TransactOpts, minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, fulfillmentFlatFeeNativePPM, fulfillmentFlatFeeLinkDiscountPPM, nativePremiumPercentage, linkPremiumPercentage) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeNativePPM uint32, fulfillmentFlatFeeLinkDiscountPPM uint32, nativePremiumPercentage uint8, linkPremiumPercentage uint8) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.SetConfig(&_VRFCoordinatorTestV25.TransactOpts, minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, fulfillmentFlatFeeNativePPM, fulfillmentFlatFeeLinkDiscountPPM, nativePremiumPercentage, linkPremiumPercentage) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) SetLINKAndLINKNativeFeed(opts *bind.TransactOpts, link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "setLINKAndLINKNativeFeed", link, linkNativeFeed) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SetLINKAndLINKNativeFeed(link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.SetLINKAndLINKNativeFeed(&_VRFCoordinatorTestV25.TransactOpts, link, linkNativeFeed) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) SetLINKAndLINKNativeFeed(link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.SetLINKAndLINKNativeFeed(&_VRFCoordinatorTestV25.TransactOpts, link, linkNativeFeed) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "transferOwnership", to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.TransferOwnership(&_VRFCoordinatorTestV25.TransactOpts, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.TransferOwnership(&_VRFCoordinatorTestV25.TransactOpts, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) Withdraw(opts *bind.TransactOpts, recipient common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "withdraw", recipient) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) Withdraw(recipient common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.Withdraw(&_VRFCoordinatorTestV25.TransactOpts, recipient) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) Withdraw(recipient common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.Withdraw(&_VRFCoordinatorTestV25.TransactOpts, recipient) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) WithdrawNative(opts *bind.TransactOpts, recipient common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "withdrawNative", recipient) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) WithdrawNative(recipient common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.WithdrawNative(&_VRFCoordinatorTestV25.TransactOpts, recipient) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) WithdrawNative(recipient common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.WithdrawNative(&_VRFCoordinatorTestV25.TransactOpts, recipient) +} + +type VRFCoordinatorTestV25ConfigSetIterator struct { + Event *VRFCoordinatorTestV25ConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25ConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25ConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25ConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25ConfigSetIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25ConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25ConfigSet struct { + MinimumRequestConfirmations uint16 + MaxGasLimit uint32 + StalenessSeconds uint32 + GasAfterPaymentCalculation uint32 + FallbackWeiPerUnitLink *big.Int + FulfillmentFlatFeeNativePPM uint32 + FulfillmentFlatFeeLinkDiscountPPM uint32 + NativePremiumPercentage uint8 + LinkPremiumPercentage uint8 + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorTestV25ConfigSetIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25ConfigSetIterator{contract: _VRFCoordinatorTestV25.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25ConfigSet) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25ConfigSet) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseConfigSet(log types.Log) (*VRFCoordinatorTestV25ConfigSet, error) { + event := new(VRFCoordinatorTestV25ConfigSet) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25CoordinatorDeregisteredIterator struct { + Event *VRFCoordinatorTestV25CoordinatorDeregistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25CoordinatorDeregisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25CoordinatorDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25CoordinatorDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25CoordinatorDeregisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25CoordinatorDeregisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25CoordinatorDeregistered struct { + CoordinatorAddress common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterCoordinatorDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25CoordinatorDeregisteredIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "CoordinatorDeregistered") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25CoordinatorDeregisteredIterator{contract: _VRFCoordinatorTestV25.contract, event: "CoordinatorDeregistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchCoordinatorDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25CoordinatorDeregistered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "CoordinatorDeregistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25CoordinatorDeregistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "CoordinatorDeregistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseCoordinatorDeregistered(log types.Log) (*VRFCoordinatorTestV25CoordinatorDeregistered, error) { + event := new(VRFCoordinatorTestV25CoordinatorDeregistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "CoordinatorDeregistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25CoordinatorRegisteredIterator struct { + Event *VRFCoordinatorTestV25CoordinatorRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25CoordinatorRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25CoordinatorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25CoordinatorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25CoordinatorRegisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25CoordinatorRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25CoordinatorRegistered struct { + CoordinatorAddress common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25CoordinatorRegisteredIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "CoordinatorRegistered") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25CoordinatorRegisteredIterator{contract: _VRFCoordinatorTestV25.contract, event: "CoordinatorRegistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25CoordinatorRegistered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "CoordinatorRegistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25CoordinatorRegistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "CoordinatorRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorTestV25CoordinatorRegistered, error) { + event := new(VRFCoordinatorTestV25CoordinatorRegistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "CoordinatorRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator struct { + Event *VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed struct { + RequestId *big.Int + FallbackWeiPerUnitLink *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterFallbackWeiPerUnitLinkUsed(opts *bind.FilterOpts) (*VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "FallbackWeiPerUnitLinkUsed") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator{contract: _VRFCoordinatorTestV25.contract, event: "FallbackWeiPerUnitLinkUsed", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchFallbackWeiPerUnitLinkUsed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "FallbackWeiPerUnitLinkUsed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "FallbackWeiPerUnitLinkUsed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseFallbackWeiPerUnitLinkUsed(log types.Log) (*VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed, error) { + event := new(VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "FallbackWeiPerUnitLinkUsed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25FundsRecoveredIterator struct { + Event *VRFCoordinatorTestV25FundsRecovered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25FundsRecoveredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25FundsRecovered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25FundsRecovered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25FundsRecoveredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25FundsRecoveredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25FundsRecovered struct { + To common.Address + Amount *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25FundsRecoveredIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "FundsRecovered") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25FundsRecoveredIterator{contract: _VRFCoordinatorTestV25.contract, event: "FundsRecovered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25FundsRecovered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "FundsRecovered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25FundsRecovered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "FundsRecovered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseFundsRecovered(log types.Log) (*VRFCoordinatorTestV25FundsRecovered, error) { + event := new(VRFCoordinatorTestV25FundsRecovered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "FundsRecovered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25MigrationCompletedIterator struct { + Event *VRFCoordinatorTestV25MigrationCompleted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25MigrationCompletedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25MigrationCompleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25MigrationCompleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25MigrationCompletedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25MigrationCompletedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25MigrationCompleted struct { + NewCoordinator common.Address + SubId *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterMigrationCompleted(opts *bind.FilterOpts) (*VRFCoordinatorTestV25MigrationCompletedIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "MigrationCompleted") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25MigrationCompletedIterator{contract: _VRFCoordinatorTestV25.contract, event: "MigrationCompleted", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25MigrationCompleted) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "MigrationCompleted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25MigrationCompleted) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseMigrationCompleted(log types.Log) (*VRFCoordinatorTestV25MigrationCompleted, error) { + event := new(VRFCoordinatorTestV25MigrationCompleted) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25NativeFundsRecoveredIterator struct { + Event *VRFCoordinatorTestV25NativeFundsRecovered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25NativeFundsRecoveredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25NativeFundsRecovered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25NativeFundsRecovered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25NativeFundsRecoveredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25NativeFundsRecoveredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25NativeFundsRecovered struct { + To common.Address + Amount *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterNativeFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25NativeFundsRecoveredIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "NativeFundsRecovered") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25NativeFundsRecoveredIterator{contract: _VRFCoordinatorTestV25.contract, event: "NativeFundsRecovered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchNativeFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25NativeFundsRecovered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "NativeFundsRecovered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25NativeFundsRecovered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "NativeFundsRecovered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseNativeFundsRecovered(log types.Log) (*VRFCoordinatorTestV25NativeFundsRecovered, error) { + event := new(VRFCoordinatorTestV25NativeFundsRecovered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "NativeFundsRecovered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25OwnershipTransferRequestedIterator struct { + Event *VRFCoordinatorTestV25OwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25OwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25OwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25OwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25OwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25OwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25OwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorTestV25OwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25OwnershipTransferRequestedIterator{contract: _VRFCoordinatorTestV25.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25OwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25OwnershipTransferRequested) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorTestV25OwnershipTransferRequested, error) { + event := new(VRFCoordinatorTestV25OwnershipTransferRequested) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25OwnershipTransferredIterator struct { + Event *VRFCoordinatorTestV25OwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25OwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25OwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25OwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25OwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25OwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25OwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorTestV25OwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25OwnershipTransferredIterator{contract: _VRFCoordinatorTestV25.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25OwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25OwnershipTransferred) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorTestV25OwnershipTransferred, error) { + event := new(VRFCoordinatorTestV25OwnershipTransferred) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25ProvingKeyDeregisteredIterator struct { + Event *VRFCoordinatorTestV25ProvingKeyDeregistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25ProvingKeyDeregisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25ProvingKeyDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25ProvingKeyDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25ProvingKeyDeregisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25ProvingKeyDeregisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25ProvingKeyDeregistered struct { + KeyHash [32]byte + MaxGas uint64 + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterProvingKeyDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25ProvingKeyDeregisteredIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "ProvingKeyDeregistered") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25ProvingKeyDeregisteredIterator{contract: _VRFCoordinatorTestV25.contract, event: "ProvingKeyDeregistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchProvingKeyDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25ProvingKeyDeregistered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "ProvingKeyDeregistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25ProvingKeyDeregistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "ProvingKeyDeregistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseProvingKeyDeregistered(log types.Log) (*VRFCoordinatorTestV25ProvingKeyDeregistered, error) { + event := new(VRFCoordinatorTestV25ProvingKeyDeregistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "ProvingKeyDeregistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25ProvingKeyRegisteredIterator struct { + Event *VRFCoordinatorTestV25ProvingKeyRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25ProvingKeyRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25ProvingKeyRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25ProvingKeyRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25ProvingKeyRegisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25ProvingKeyRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25ProvingKeyRegistered struct { + KeyHash [32]byte + MaxGas uint64 + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterProvingKeyRegistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25ProvingKeyRegisteredIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "ProvingKeyRegistered") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25ProvingKeyRegisteredIterator{contract: _VRFCoordinatorTestV25.contract, event: "ProvingKeyRegistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchProvingKeyRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25ProvingKeyRegistered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "ProvingKeyRegistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25ProvingKeyRegistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "ProvingKeyRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorTestV25ProvingKeyRegistered, error) { + event := new(VRFCoordinatorTestV25ProvingKeyRegistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "ProvingKeyRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25RandomWordsFulfilledIterator struct { + Event *VRFCoordinatorTestV25RandomWordsFulfilled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25RandomWordsFulfilledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25RandomWordsFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25RandomWordsFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25RandomWordsFulfilledIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25RandomWordsFulfilledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25RandomWordsFulfilled struct { + RequestId *big.Int + OutputSeed *big.Int + SubId *big.Int + Payment *big.Int + NativePayment bool + Success bool + OnlyPremium bool + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*VRFCoordinatorTestV25RandomWordsFulfilledIterator, error) { + + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "RandomWordsFulfilled", requestIdRule, subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25RandomWordsFulfilledIterator{contract: _VRFCoordinatorTestV25.contract, event: "RandomWordsFulfilled", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25RandomWordsFulfilled, requestId []*big.Int, subId []*big.Int) (event.Subscription, error) { + + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "RandomWordsFulfilled", requestIdRule, subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25RandomWordsFulfilled) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorTestV25RandomWordsFulfilled, error) { + event := new(VRFCoordinatorTestV25RandomWordsFulfilled) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25RandomWordsRequestedIterator struct { + Event *VRFCoordinatorTestV25RandomWordsRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25RandomWordsRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25RandomWordsRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25RandomWordsRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25RandomWordsRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25RandomWordsRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25RandomWordsRequested struct { + KeyHash [32]byte + RequestId *big.Int + PreSeed *big.Int + SubId *big.Int + MinimumRequestConfirmations uint16 + CallbackGasLimit uint32 + NumWords uint32 + ExtraArgs []byte + Sender common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (*VRFCoordinatorTestV25RandomWordsRequestedIterator, error) { + + var keyHashRule []interface{} + for _, keyHashItem := range keyHash { + keyHashRule = append(keyHashRule, keyHashItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "RandomWordsRequested", keyHashRule, subIdRule, senderRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25RandomWordsRequestedIterator{contract: _VRFCoordinatorTestV25.contract, event: "RandomWordsRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchRandomWordsRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25RandomWordsRequested, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (event.Subscription, error) { + + var keyHashRule []interface{} + for _, keyHashItem := range keyHash { + keyHashRule = append(keyHashRule, keyHashItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "RandomWordsRequested", keyHashRule, subIdRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25RandomWordsRequested) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "RandomWordsRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseRandomWordsRequested(log types.Log) (*VRFCoordinatorTestV25RandomWordsRequested, error) { + event := new(VRFCoordinatorTestV25RandomWordsRequested) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "RandomWordsRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionCanceledIterator struct { + Event *VRFCoordinatorTestV25SubscriptionCanceled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionCanceledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionCanceledIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionCanceledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionCanceled struct { + SubId *big.Int + To common.Address + AmountLink *big.Int + AmountNative *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionCanceledIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionCanceled", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionCanceledIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionCanceled", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionCanceled, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionCanceled", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionCanceled) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorTestV25SubscriptionCanceled, error) { + event := new(VRFCoordinatorTestV25SubscriptionCanceled) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionConsumerAddedIterator struct { + Event *VRFCoordinatorTestV25SubscriptionConsumerAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionConsumerAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionConsumerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionConsumerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionConsumerAddedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionConsumerAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionConsumerAdded struct { + SubId *big.Int + Consumer common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionConsumerAddedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionConsumerAdded", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionConsumerAddedIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionConsumerAdded", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionConsumerAdded", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionConsumerAdded) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorTestV25SubscriptionConsumerAdded, error) { + event := new(VRFCoordinatorTestV25SubscriptionConsumerAdded) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator struct { + Event *VRFCoordinatorTestV25SubscriptionConsumerRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionConsumerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionConsumerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionConsumerRemoved struct { + SubId *big.Int + Consumer common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionConsumerRemoved", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionConsumerRemoved", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionConsumerRemoved", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionConsumerRemoved) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorTestV25SubscriptionConsumerRemoved, error) { + event := new(VRFCoordinatorTestV25SubscriptionConsumerRemoved) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionCreatedIterator struct { + Event *VRFCoordinatorTestV25SubscriptionCreated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionCreatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionCreatedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionCreated struct { + SubId *big.Int + Owner common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionCreatedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionCreated", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionCreatedIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionCreated", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionCreated, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionCreated", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionCreated) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorTestV25SubscriptionCreated, error) { + event := new(VRFCoordinatorTestV25SubscriptionCreated) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionFundedIterator struct { + Event *VRFCoordinatorTestV25SubscriptionFunded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionFundedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionFunded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionFunded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionFundedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionFundedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionFunded struct { + SubId *big.Int + OldBalance *big.Int + NewBalance *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionFundedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionFunded", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionFundedIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionFunded", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionFunded, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionFunded", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionFunded) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorTestV25SubscriptionFunded, error) { + event := new(VRFCoordinatorTestV25SubscriptionFunded) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator struct { + Event *VRFCoordinatorTestV25SubscriptionFundedWithNative + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionFundedWithNative) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionFundedWithNative) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionFundedWithNative struct { + SubId *big.Int + OldNativeBalance *big.Int + NewNativeBalance *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionFundedWithNative(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionFundedWithNative", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionFundedWithNative", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionFundedWithNative(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionFundedWithNative, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionFundedWithNative", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionFundedWithNative) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionFundedWithNative", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionFundedWithNative(log types.Log) (*VRFCoordinatorTestV25SubscriptionFundedWithNative, error) { + event := new(VRFCoordinatorTestV25SubscriptionFundedWithNative) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionFundedWithNative", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator struct { + Event *VRFCoordinatorTestV25SubscriptionOwnerTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionOwnerTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionOwnerTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionOwnerTransferRequested struct { + SubId *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionOwnerTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionOwnerTransferRequested) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorTestV25SubscriptionOwnerTransferRequested, error) { + event := new(VRFCoordinatorTestV25SubscriptionOwnerTransferRequested) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator struct { + Event *VRFCoordinatorTestV25SubscriptionOwnerTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionOwnerTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionOwnerTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionOwnerTransferred struct { + SubId *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionOwnerTransferred", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionOwnerTransferred", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionOwnerTransferred", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionOwnerTransferred) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionOwnerTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorTestV25SubscriptionOwnerTransferred, error) { + event := new(VRFCoordinatorTestV25SubscriptionOwnerTransferred) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionOwnerTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetSubscription struct { + Balance *big.Int + NativeBalance *big.Int + ReqCount uint64 + SubOwner common.Address + Consumers []common.Address +} +type SConfig struct { + MinimumRequestConfirmations uint16 + MaxGasLimit uint32 + ReentrancyLock bool + StalenessSeconds uint32 + GasAfterPaymentCalculation uint32 + FulfillmentFlatFeeNativePPM uint32 + FulfillmentFlatFeeLinkDiscountPPM uint32 + NativePremiumPercentage uint8 + LinkPremiumPercentage uint8 +} +type SProvingKeys struct { + Exists bool + MaxGas uint64 +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _VRFCoordinatorTestV25.abi.Events["ConfigSet"].ID: + return _VRFCoordinatorTestV25.ParseConfigSet(log) + case _VRFCoordinatorTestV25.abi.Events["CoordinatorDeregistered"].ID: + return _VRFCoordinatorTestV25.ParseCoordinatorDeregistered(log) + case _VRFCoordinatorTestV25.abi.Events["CoordinatorRegistered"].ID: + return _VRFCoordinatorTestV25.ParseCoordinatorRegistered(log) + case _VRFCoordinatorTestV25.abi.Events["FallbackWeiPerUnitLinkUsed"].ID: + return _VRFCoordinatorTestV25.ParseFallbackWeiPerUnitLinkUsed(log) + case _VRFCoordinatorTestV25.abi.Events["FundsRecovered"].ID: + return _VRFCoordinatorTestV25.ParseFundsRecovered(log) + case _VRFCoordinatorTestV25.abi.Events["MigrationCompleted"].ID: + return _VRFCoordinatorTestV25.ParseMigrationCompleted(log) + case _VRFCoordinatorTestV25.abi.Events["NativeFundsRecovered"].ID: + return _VRFCoordinatorTestV25.ParseNativeFundsRecovered(log) + case _VRFCoordinatorTestV25.abi.Events["OwnershipTransferRequested"].ID: + return _VRFCoordinatorTestV25.ParseOwnershipTransferRequested(log) + case _VRFCoordinatorTestV25.abi.Events["OwnershipTransferred"].ID: + return _VRFCoordinatorTestV25.ParseOwnershipTransferred(log) + case _VRFCoordinatorTestV25.abi.Events["ProvingKeyDeregistered"].ID: + return _VRFCoordinatorTestV25.ParseProvingKeyDeregistered(log) + case _VRFCoordinatorTestV25.abi.Events["ProvingKeyRegistered"].ID: + return _VRFCoordinatorTestV25.ParseProvingKeyRegistered(log) + case _VRFCoordinatorTestV25.abi.Events["RandomWordsFulfilled"].ID: + return _VRFCoordinatorTestV25.ParseRandomWordsFulfilled(log) + case _VRFCoordinatorTestV25.abi.Events["RandomWordsRequested"].ID: + return _VRFCoordinatorTestV25.ParseRandomWordsRequested(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionCanceled"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionCanceled(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionConsumerAdded"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionConsumerAdded(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionConsumerRemoved"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionConsumerRemoved(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionCreated"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionCreated(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionFunded"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionFunded(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionFundedWithNative"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionFundedWithNative(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionOwnerTransferRequested"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionOwnerTransferRequested(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionOwnerTransferred"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionOwnerTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (VRFCoordinatorTestV25ConfigSet) Topic() common.Hash { + return common.HexToHash("0x2c6b6b12413678366b05b145c5f00745bdd00e739131ab5de82484a50c9d78b6") +} + +func (VRFCoordinatorTestV25CoordinatorDeregistered) Topic() common.Hash { + return common.HexToHash("0xf80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37") +} + +func (VRFCoordinatorTestV25CoordinatorRegistered) Topic() common.Hash { + return common.HexToHash("0xb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625") +} + +func (VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) Topic() common.Hash { + return common.HexToHash("0x6ca648a381f22ead7e37773d934e64885dcf861fbfbb26c40354cbf0c4662d1a") +} + +func (VRFCoordinatorTestV25FundsRecovered) Topic() common.Hash { + return common.HexToHash("0x59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600") +} + +func (VRFCoordinatorTestV25MigrationCompleted) Topic() common.Hash { + return common.HexToHash("0xd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187") +} + +func (VRFCoordinatorTestV25NativeFundsRecovered) Topic() common.Hash { + return common.HexToHash("0x4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c") +} + +func (VRFCoordinatorTestV25OwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (VRFCoordinatorTestV25OwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (VRFCoordinatorTestV25ProvingKeyDeregistered) Topic() common.Hash { + return common.HexToHash("0x9b6868e0eb737bcd72205360baa6bfd0ba4e4819a33ade2db384e8a8025639a5") +} + +func (VRFCoordinatorTestV25ProvingKeyRegistered) Topic() common.Hash { + return common.HexToHash("0x9b911b2c240bfbef3b6a8f7ed6ee321d1258bb2a3fe6becab52ac1cd3210afd3") +} + +func (VRFCoordinatorTestV25RandomWordsFulfilled) Topic() common.Hash { + return common.HexToHash("0xaeb4b4786571e184246d39587f659abf0e26f41f6a3358692250382c0cdb47b7") +} + +func (VRFCoordinatorTestV25RandomWordsRequested) Topic() common.Hash { + return common.HexToHash("0xeb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e") +} + +func (VRFCoordinatorTestV25SubscriptionCanceled) Topic() common.Hash { + return common.HexToHash("0x8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4") +} + +func (VRFCoordinatorTestV25SubscriptionConsumerAdded) Topic() common.Hash { + return common.HexToHash("0x1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1") +} + +func (VRFCoordinatorTestV25SubscriptionConsumerRemoved) Topic() common.Hash { + return common.HexToHash("0x32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7") +} + +func (VRFCoordinatorTestV25SubscriptionCreated) Topic() common.Hash { + return common.HexToHash("0x1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d") +} + +func (VRFCoordinatorTestV25SubscriptionFunded) Topic() common.Hash { + return common.HexToHash("0x1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a") +} + +func (VRFCoordinatorTestV25SubscriptionFundedWithNative) Topic() common.Hash { + return common.HexToHash("0x7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902") +} + +func (VRFCoordinatorTestV25SubscriptionOwnerTransferRequested) Topic() common.Hash { + return common.HexToHash("0x21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a1") +} + +func (VRFCoordinatorTestV25SubscriptionOwnerTransferred) Topic() common.Hash { + return common.HexToHash("0xd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c9386") +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25) Address() common.Address { + return _VRFCoordinatorTestV25.address +} + +type VRFCoordinatorTestV25Interface interface { + BLOCKHASHSTORE(opts *bind.CallOpts) (common.Address, error) + + LINK(opts *bind.CallOpts) (common.Address, error) + + LINKNATIVEFEED(opts *bind.CallOpts) (common.Address, error) + + MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) + + MAXNUMWORDS(opts *bind.CallOpts) (uint32, error) + + MAXREQUESTCONFIRMATIONS(opts *bind.CallOpts) (uint16, error) + + GetActiveSubscriptionIds(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) + + GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, + + error) + + HashOfKey(opts *bind.CallOpts, publicKey [2]*big.Int) ([32]byte, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + PendingRequestExists(opts *bind.CallOpts, subId *big.Int) (bool, error) + + SConfig(opts *bind.CallOpts) (SConfig, + + error) + + SCurrentSubNonce(opts *bind.CallOpts) (uint64, error) + + SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) + + SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) + + SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (SProvingKeys, + + error) + + SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) + + STotalBalance(opts *bind.CallOpts) (*big.Int, error) + + STotalNativeBalance(opts *bind.CallOpts) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + + AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) + + CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) + + CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) + + DeregisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) + + DeregisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int) (*types.Transaction, error) + + FulfillRandomWords(opts *bind.TransactOpts, proof VRFOldProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) + + FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + + Migrate(opts *bind.TransactOpts, subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) + + OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) + + OwnerCancelSubscription(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + + RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + RecoverNativeFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) + + RegisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) + + RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) + + RequestRandomWords(opts *bind.TransactOpts, req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) + + RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeNativePPM uint32, fulfillmentFlatFeeLinkDiscountPPM uint32, nativePremiumPercentage uint8, linkPremiumPercentage uint8) (*types.Transaction, error) + + SetLINKAndLINKNativeFeed(opts *bind.TransactOpts, link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Withdraw(opts *bind.TransactOpts, recipient common.Address) (*types.Transaction, error) + + WithdrawNative(opts *bind.TransactOpts, recipient common.Address) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorTestV25ConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25ConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*VRFCoordinatorTestV25ConfigSet, error) + + FilterCoordinatorDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25CoordinatorDeregisteredIterator, error) + + WatchCoordinatorDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25CoordinatorDeregistered) (event.Subscription, error) + + ParseCoordinatorDeregistered(log types.Log) (*VRFCoordinatorTestV25CoordinatorDeregistered, error) + + FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25CoordinatorRegisteredIterator, error) + + WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25CoordinatorRegistered) (event.Subscription, error) + + ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorTestV25CoordinatorRegistered, error) + + FilterFallbackWeiPerUnitLinkUsed(opts *bind.FilterOpts) (*VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator, error) + + WatchFallbackWeiPerUnitLinkUsed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) (event.Subscription, error) + + ParseFallbackWeiPerUnitLinkUsed(log types.Log) (*VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed, error) + + FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25FundsRecoveredIterator, error) + + WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25FundsRecovered) (event.Subscription, error) + + ParseFundsRecovered(log types.Log) (*VRFCoordinatorTestV25FundsRecovered, error) + + FilterMigrationCompleted(opts *bind.FilterOpts) (*VRFCoordinatorTestV25MigrationCompletedIterator, error) + + WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25MigrationCompleted) (event.Subscription, error) + + ParseMigrationCompleted(log types.Log) (*VRFCoordinatorTestV25MigrationCompleted, error) + + FilterNativeFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25NativeFundsRecoveredIterator, error) + + WatchNativeFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25NativeFundsRecovered) (event.Subscription, error) + + ParseNativeFundsRecovered(log types.Log) (*VRFCoordinatorTestV25NativeFundsRecovered, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorTestV25OwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25OwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorTestV25OwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorTestV25OwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25OwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorTestV25OwnershipTransferred, error) + + FilterProvingKeyDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25ProvingKeyDeregisteredIterator, error) + + WatchProvingKeyDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25ProvingKeyDeregistered) (event.Subscription, error) + + ParseProvingKeyDeregistered(log types.Log) (*VRFCoordinatorTestV25ProvingKeyDeregistered, error) + + FilterProvingKeyRegistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25ProvingKeyRegisteredIterator, error) + + WatchProvingKeyRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25ProvingKeyRegistered) (event.Subscription, error) + + ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorTestV25ProvingKeyRegistered, error) + + FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*VRFCoordinatorTestV25RandomWordsFulfilledIterator, error) + + WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25RandomWordsFulfilled, requestId []*big.Int, subId []*big.Int) (event.Subscription, error) + + ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorTestV25RandomWordsFulfilled, error) + + FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (*VRFCoordinatorTestV25RandomWordsRequestedIterator, error) + + WatchRandomWordsRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25RandomWordsRequested, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (event.Subscription, error) + + ParseRandomWordsRequested(log types.Log) (*VRFCoordinatorTestV25RandomWordsRequested, error) + + FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionCanceledIterator, error) + + WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionCanceled, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorTestV25SubscriptionCanceled, error) + + FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionConsumerAddedIterator, error) + + WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorTestV25SubscriptionConsumerAdded, error) + + FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator, error) + + WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorTestV25SubscriptionConsumerRemoved, error) + + FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionCreatedIterator, error) + + WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionCreated, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorTestV25SubscriptionCreated, error) + + FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionFundedIterator, error) + + WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionFunded, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorTestV25SubscriptionFunded, error) + + FilterSubscriptionFundedWithNative(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator, error) + + WatchSubscriptionFundedWithNative(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionFundedWithNative, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionFundedWithNative(log types.Log) (*VRFCoordinatorTestV25SubscriptionFundedWithNative, error) + + FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator, error) + + WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorTestV25SubscriptionOwnerTransferRequested, error) + + FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator, error) + + WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorTestV25SubscriptionOwnerTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 8862fef8c8..c363892b9d 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -82,6 +82,7 @@ vrf_consumer_v2_plus_upgradeable_example: ../../contracts/solc/v0.8.19/VRFConsum vrf_consumer_v2_upgradeable_example: ../../contracts/solc/v0.8.6/VRFConsumerV2UpgradeableExample/VRFConsumerV2UpgradeableExample.abi ../../contracts/solc/v0.8.6/VRFConsumerV2UpgradeableExample/VRFConsumerV2UpgradeableExample.bin f1790a9a2f2a04c730593e483459709cb89e897f8a19d7a3ac0cfe6a97265e6e vrf_coordinator_mock: ../../contracts/solc/v0.8.6/VRFCoordinatorMock/VRFCoordinatorMock.abi ../../contracts/solc/v0.8.6/VRFCoordinatorMock/VRFCoordinatorMock.bin 5c495cf8df1f46d8736b9150cdf174cce358cb8352f60f0d5bb9581e23920501 vrf_coordinator_test_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorTestV2/VRFCoordinatorTestV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorTestV2/VRFCoordinatorTestV2.bin ff6c0056c6181ea75f667beed21ff4610f417dd50ceabf2dec8fa42e84851f50 +vrf_coordinator_test_v2_5: ../../contracts/solc/v0.8.19/VRFCoordinatorTestV2_5/VRFCoordinatorTestV2_5.abi ../../contracts/solc/v0.8.19/VRFCoordinatorTestV2_5/VRFCoordinatorTestV2_5.bin ab793e7d72b2d10d5c80b5358ca98caf5ff8a8686700735b198ed811272d7910 vrf_coordinator_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorV2/VRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2/VRFCoordinatorV2.bin 156fbbc19489383901087c2076648ccd343bcd9a332f1ad25974da834c5be961 vrf_coordinator_v2_5: ../../contracts/solc/v0.8.19/VRFCoordinatorV2_5/VRFCoordinatorV2_5.abi ../../contracts/solc/v0.8.19/VRFCoordinatorV2_5/VRFCoordinatorV2_5.bin 3c766dbdefcc895ad475de96c65b6c48c868b8dc889ee750bba6711b1e5ec41d vrf_coordinator_v2_5_arbitrum: ../../contracts/solc/v0.8.19/VRFCoordinatorV2_5_Arbitrum/VRFCoordinatorV2_5_Arbitrum.abi ../../contracts/solc/v0.8.19/VRFCoordinatorV2_5_Arbitrum/VRFCoordinatorV2_5_Arbitrum.bin 1a2431ee76e307b45f683c439d08b9096a08f08aaf9ca132ea5b36b409962abe diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index d877c7a8db..32db02f2bf 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -143,6 +143,7 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/VRFCoordinatorV2_5_Optimism/VRFCoordinatorV2_5_Optimism.abi ../../contracts/solc/v0.8.19/VRFCoordinatorV2_5_Optimism/VRFCoordinatorV2_5_Optimism.bin VRFCoordinatorV2_5_Optimism vrf_coordinator_v2_5_optimism //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/VRFV2PlusWrapper_Arbitrum/VRFV2PlusWrapper_Arbitrum.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapper_Arbitrum/VRFV2PlusWrapper_Arbitrum.bin VRFV2PlusWrapper_Arbitrum vrfv2plus_wrapper_arbitrum //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/VRFV2PlusWrapper_Optimism/VRFV2PlusWrapper_Optimism.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapper_Optimism/VRFV2PlusWrapper_Optimism.bin VRFV2PlusWrapper_Optimism vrfv2plus_wrapper_optimism +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/VRFCoordinatorTestV2_5/VRFCoordinatorTestV2_5.abi ../../contracts/solc/v0.8.19/VRFCoordinatorTestV2_5/VRFCoordinatorTestV2_5.bin VRFCoordinatorTestV2_5 vrf_coordinator_test_v2_5 // Aggregators //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV2V3Interface.abi ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV2V3Interface.bin AggregatorV2V3Interface aggregator_v2v3_interface diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index b274b59416..ae4d62ddb3 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -1243,6 +1243,11 @@ func IsOPStackChain(chainID int64) bool { chainID == 11155420 //OPTIMISM SEPOLIA } +func IsArbitrumChain(chainID int64) bool { + return chainID == 42161 || //Arbitrum MAINNET + chainID == 421614 //Arbitrum Sepolia +} + func RandBool() bool { return rand.Intn(2) == 1 } diff --git a/integration-tests/actions/vrf/vrfv2/setup_steps.go b/integration-tests/actions/vrf/vrfv2/setup_steps.go index c025a56304..0e0b68e640 100644 --- a/integration-tests/actions/vrf/vrfv2/setup_steps.go +++ b/integration-tests/actions/vrf/vrfv2/setup_steps.go @@ -42,7 +42,7 @@ func CreateVRFV2Job( } ost, err := os.String() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrParseJob, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrParseJob, err) } spec := &client.VRFV2JobSpec{ @@ -69,7 +69,7 @@ func CreateVRFV2Job( } job, err := chainlinkNode.MustCreateJob(spec) if err != nil { - return nil, fmt.Errorf("%s, err %w", ErrCreatingVRFv2Job, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrCreatingVRFv2Job, err) } return job, nil } @@ -113,15 +113,14 @@ func SetupVRFV2Environment( if err != nil { return nil, nil, nil, err } - l.Info().Str("Coordinator", vrfContracts.CoordinatorV2.Address()).Msg("Registering Proving Key") provingKey, err := VRFV2RegisterProvingKey(vrfKey, registerProvingKeyAgainstAddress, vrfContracts.CoordinatorV2) if err != nil { - return nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRegisteringProvingKey, err) + return nil, nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrRegisteringProvingKey, err) } keyHash, err := vrfContracts.CoordinatorV2.HashOfKey(ctx, provingKey) if err != nil { - return nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrCreatingProvingKeyHash, err) + return nil, nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrCreatingProvingKeyHash, err) } vrfTXKeyAddressStrings, vrfTXKeyAddresses, err := vrfcommon.CreateFundAndGetSendingKeys( @@ -189,44 +188,47 @@ func SetupVRFV2Environment( return vrfContracts, &vrfKeyData, nodeTypeToNodeMap, nil } -func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, vrfv2Config *testconfig.General, pubKeyCompressed string, vrfOwnerConfig *vrfcommon.VRFOwnerConfig, l zerolog.Logger, vrfNode *vrfcommon.VRFNode) error { +func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, config *testconfig.General, pubKeyCompressed string, vrfOwnerConfig *vrfcommon.VRFOwnerConfig, l zerolog.Logger, vrfNode *vrfcommon.VRFNode) error { vrfJobSpecConfig := vrfcommon.VRFJobSpecConfig{ - ForwardingAllowed: *vrfv2Config.VRFJobForwardingAllowed, + ForwardingAllowed: *config.VRFJobForwardingAllowed, CoordinatorAddress: contracts.CoordinatorV2.Address(), BatchCoordinatorAddress: contracts.BatchCoordinatorV2.Address(), FromAddresses: vrfNode.TXKeyAddressStrings, EVMChainID: chainID.String(), - MinIncomingConfirmations: int(*vrfv2Config.MinimumConfirmations), + MinIncomingConfirmations: int(*config.MinimumConfirmations), PublicKey: pubKeyCompressed, - EstimateGasMultiplier: *vrfv2Config.VRFJobEstimateGasMultiplier, - BatchFulfillmentEnabled: *vrfv2Config.VRFJobBatchFulfillmentEnabled, - BatchFulfillmentGasMultiplier: *vrfv2Config.VRFJobBatchFulfillmentGasMultiplier, - PollPeriod: vrfv2Config.VRFJobPollPeriod.Duration, - RequestTimeout: vrfv2Config.VRFJobRequestTimeout.Duration, - SimulationBlock: vrfv2Config.VRFJobSimulationBlock, + EstimateGasMultiplier: *config.VRFJobEstimateGasMultiplier, + BatchFulfillmentEnabled: *config.VRFJobBatchFulfillmentEnabled, + BatchFulfillmentGasMultiplier: *config.VRFJobBatchFulfillmentGasMultiplier, + PollPeriod: config.VRFJobPollPeriod.Duration, + RequestTimeout: config.VRFJobRequestTimeout.Duration, + SimulationBlock: config.VRFJobSimulationBlock, VRFOwnerConfig: vrfOwnerConfig, } l.Info().Msg("Creating VRFV2 Job") - vrfV2job, err := CreateVRFV2Job( + job, err := CreateVRFV2Job( vrfNode.CLNode.API, vrfJobSpecConfig, ) if err != nil { return fmt.Errorf("%s, err %w", ErrCreateVRFV2Jobs, err) } - vrfNode.Job = vrfV2job + vrfNode.Job = job // this part is here because VRFv2 can work with only a specific key // [[EVM.KeySpecific]] // Key = '...' nodeConfig := node.NewConfig(vrfNode.CLNode.NodeConfig, - node.WithKeySpecificMaxGasPrice(vrfNode.TXKeyAddressStrings, *vrfv2Config.CLNodeMaxGasPriceGWei), + node.WithKeySpecificMaxGasPrice(vrfNode.TXKeyAddressStrings, *config.CLNodeMaxGasPriceGWei), ) - l.Info().Msg("Restarting Node with new sending key PriceMax configuration") + l.Info(). + Strs("Sending Keys", vrfNode.TXKeyAddressStrings). + Int64("Price Max Setting", *config.CLNodeMaxGasPriceGWei). + Msg("Restarting Node with new sending key PriceMax configuration") err = vrfNode.CLNode.Restart(nodeConfig) if err != nil { - return fmt.Errorf("%s, err %w", vrfcommon.ErrRestartCLNode, err) + return fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrRestartCLNode, err) } return nil } diff --git a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go index 5a4ec9ba11..740e9bcbce 100644 --- a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go @@ -48,6 +48,24 @@ func DeployVRFV2_5Contracts( if err != nil { return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrLoadingCoordinator, err) } + } else if actions.IsArbitrumChain(chainClient.ChainID) { + arbitrumCoordinator, err := contracts.DeployVRFCoordinatorV2_5_Arbitrum(chainClient, bhs.Address()) + if err != nil { + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployCoordinatorV2Plus, err) + } + coordinator, err = contracts.LoadVRFCoordinatorV2_5(chainClient, arbitrumCoordinator.Address.String()) + if err != nil { + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrLoadingCoordinator, err) + } + } else if *configGeneral.UseTestCoordinator { + testCoordinator, err := contracts.DeployVRFCoordinatorTestV2_5(chainClient, bhs.Address()) + if err != nil { + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployCoordinatorV2Plus, err) + } + coordinator, err = contracts.LoadVRFCoordinatorV2_5(chainClient, testCoordinator.Address.String()) + if err != nil { + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrLoadingCoordinator, err) + } } else { coordinator, err = contracts.DeployVRFCoordinatorV2_5(chainClient, bhs.Address()) if err != nil { @@ -426,6 +444,15 @@ func DeployVRFV2PlusDirectFundingContracts( if err != nil { return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrLoadingCoordinator, err) } + } else if actions.IsArbitrumChain(sethClient.ChainID) { + arbitrumWrapper, err := contracts.DeployVRFV2PlusWrapperArbitrum(sethClient, linkTokenAddress, linkEthFeedAddress, coordinator.Address(), wrapperSubId) + if err != nil { + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployCoordinatorV2Plus, err) + } + vrfv2PlusWrapper, err = contracts.LoadVRFV2PlusWrapper(sethClient, arbitrumWrapper.Address.String()) + if err != nil { + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrLoadingCoordinator, err) + } } else { vrfv2PlusWrapper, err = contracts.DeployVRFV2PlusWrapper(sethClient, linkTokenAddress, linkEthFeedAddress, coordinator.Address(), wrapperSubId) if err != nil { diff --git a/integration-tests/actions/vrf/vrfv2plus/setup_steps.go b/integration-tests/actions/vrf/vrfv2plus/setup_steps.go index 4833afb9fe..fe06222a79 100644 --- a/integration-tests/actions/vrf/vrfv2plus/setup_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/setup_steps.go @@ -63,12 +63,10 @@ func CreateVRFV2PlusJob( if vrfJobSpecConfig.BatchFulfillmentEnabled { jobSpec.BatchCoordinatorAddress = vrfJobSpecConfig.BatchCoordinatorAddress } - job, err := chainlinkNode.MustCreateJob(&jobSpec) if err != nil { return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrCreatingVRFv2PlusJob, err) } - return job, nil } @@ -87,7 +85,6 @@ func SetupVRFV2_5Environment( ) (*vrfcommon.VRFContracts, *vrfcommon.VRFKeyData, map[vrfcommon.VRFNodeType]*vrfcommon.VRFNode, error) { l.Info().Msg("Starting VRFV2 Plus environment setup") configGeneral := vrfv2PlusTestConfig.GetVRFv2PlusConfig().General - vrfContracts, err := SetupVRFV2PlusContracts( sethClient, linkToken, @@ -361,7 +358,7 @@ func SetupVRFV2PlusWrapperForNewEnv( vrfv2PlusConfig, ) if err != nil { - return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) + return nil, nil, err } // once the wrapper is deployed, wrapper address will become consumer of external EOA subscription err = vrfContracts.CoordinatorV2Plus.AddConsumer(wrapperSubId, wrapperContracts.VRFV2PlusWrapper.Address()) diff --git a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go index 9b286a1d05..5926f90cf0 100644 --- a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go @@ -16,11 +16,14 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/wrappers" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_blockhash_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_vrf_coordinator_v2plus" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_test_v2_5" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5_arbitrum" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5_optimism" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_arbitrum" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_optimism" ) @@ -37,6 +40,18 @@ type EthereumVRFCoordinatorV2_5_Optimism struct { coordinator vrf_coordinator_v2_5_optimism.VRFCoordinatorV25Optimism } +type EthereumVRFCoordinatorV2_5_Arbitrum struct { + Address common.Address + client *seth.Client + coordinator vrf_coordinator_v2_5_arbitrum.VRFCoordinatorV25Arbitrum +} + +type EthereumVRFCoordinatorTestV2_5 struct { + Address common.Address + client *seth.Client + coordinator vrf_coordinator_test_v2_5.VRFCoordinatorTestV25 +} + type EthereumBatchVRFCoordinatorV2Plus struct { address common.Address client *seth.Client @@ -74,6 +89,12 @@ type EthereumVRFV2PlusWrapperOptimism struct { wrapper *vrfv2plus_wrapper_optimism.VRFV2PlusWrapperOptimism } +type EthereumVRFV2PlusWrapperArbitrum struct { + Address common.Address + client *seth.Client + wrapper *vrfv2plus_wrapper_arbitrum.VRFV2PlusWrapperArbitrum +} + func (v *EthereumVRFV2PlusWrapper) Address() string { return v.address.Hex() } @@ -178,6 +199,56 @@ func DeployVRFCoordinatorV2_5_Optimism(seth *seth.Client, bhsAddr string) (*Ethe }, err } +func DeployVRFCoordinatorV2_5_Arbitrum(seth *seth.Client, bhsAddr string) (*EthereumVRFCoordinatorV2_5_Arbitrum, error) { + abi, err := vrf_coordinator_v2_5_arbitrum.VRFCoordinatorV25ArbitrumMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get VRFCoordinatorV2_5_Arbitrum ABI: %w", err) + } + coordinatorDeploymentData, err := seth.DeployContract( + seth.NewTXOpts(), + "VRFCoordinatorV2_5_Arbitrum", + *abi, + common.FromHex(vrf_coordinator_v2_5_arbitrum.VRFCoordinatorV25ArbitrumMetaData.Bin), + common.HexToAddress(bhsAddr)) + if err != nil { + return nil, fmt.Errorf("VRFCoordinatorV2_5_Arbitrum instance deployment have failed: %w", err) + } + contract, err := vrf_coordinator_v2_5_arbitrum.NewVRFCoordinatorV25Arbitrum(coordinatorDeploymentData.Address, wrappers.MustNewWrappedContractBackend(nil, seth)) + if err != nil { + return nil, fmt.Errorf("failed to instantiate VRFCoordinatorV2_5_Arbitrum instance: %w", err) + } + return &EthereumVRFCoordinatorV2_5_Arbitrum{ + client: seth, + coordinator: *contract, + Address: coordinatorDeploymentData.Address, + }, err +} + +func DeployVRFCoordinatorTestV2_5(seth *seth.Client, bhsAddr string) (*EthereumVRFCoordinatorTestV2_5, error) { + abi, err := vrf_coordinator_test_v2_5.VRFCoordinatorTestV25MetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get VRFCoordinatorTestV2_5 ABI: %w", err) + } + coordinatorDeploymentData, err := seth.DeployContract( + seth.NewTXOpts(), + "VRFCoordinatorTestV2_5", + *abi, + common.FromHex(vrf_coordinator_test_v2_5.VRFCoordinatorTestV25MetaData.Bin), + common.HexToAddress(bhsAddr)) + if err != nil { + return nil, fmt.Errorf("VRFCoordinatorTestV2_5 instance deployment have failed: %w", err) + } + contract, err := vrf_coordinator_test_v2_5.NewVRFCoordinatorTestV25(coordinatorDeploymentData.Address, wrappers.MustNewWrappedContractBackend(nil, seth)) + if err != nil { + return nil, fmt.Errorf("failed to instantiate VRFCoordinatorTestV2_5 instance: %w", err) + } + return &EthereumVRFCoordinatorTestV2_5{ + client: seth, + coordinator: *contract, + Address: coordinatorDeploymentData.Address, + }, err +} + func DeployBatchVRFCoordinatorV2Plus(seth *seth.Client, coordinatorAddress string) (BatchVRFCoordinatorV2Plus, error) { abi, err := batch_vrf_coordinator_v2plus.BatchVRFCoordinatorV2PlusMetaData.GetAbi() if err != nil { @@ -1185,24 +1256,50 @@ func DeployVRFV2PlusWrapper(seth *seth.Client, linkAddr string, linkEthFeedAddr }, err } +func DeployVRFV2PlusWrapperArbitrum(seth *seth.Client, linkAddr string, linkEthFeedAddr string, coordinatorAddr string, subId *big.Int) (*EthereumVRFV2PlusWrapperArbitrum, error) { + abi, err := vrfv2plus_wrapper_arbitrum.VRFV2PlusWrapperArbitrumMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get VRFV2PlusWrapper_Arbitrum ABI: %w", err) + } + data, err := seth.DeployContract( + seth.NewTXOpts(), + "VRFV2PlusWrapper_Arbitrum", + *abi, + common.FromHex(vrfv2plus_wrapper_arbitrum.VRFV2PlusWrapperArbitrumMetaData.Bin), + common.HexToAddress(linkAddr), common.HexToAddress(linkEthFeedAddr), + common.HexToAddress(coordinatorAddr), subId) + if err != nil { + return nil, fmt.Errorf("VRFV2PlusWrapper_Arbitrum instance deployment have failed: %w", err) + } + contract, err := vrfv2plus_wrapper_arbitrum.NewVRFV2PlusWrapperArbitrum(data.Address, wrappers.MustNewWrappedContractBackend(nil, seth)) + if err != nil { + return nil, fmt.Errorf("failed to instantiate VRFV2PlusWrapper_Arbitrum instance: %w", err) + } + return &EthereumVRFV2PlusWrapperArbitrum{ + client: seth, + wrapper: contract, + Address: data.Address, + }, err +} + func DeployVRFV2PlusWrapperOptimism(seth *seth.Client, linkAddr string, linkEthFeedAddr string, coordinatorAddr string, subId *big.Int) (*EthereumVRFV2PlusWrapperOptimism, error) { abi, err := vrfv2plus_wrapper_optimism.VRFV2PlusWrapperOptimismMetaData.GetAbi() if err != nil { - return nil, fmt.Errorf("failed to get VRFV2PlusWrapperOptimism ABI: %w", err) + return nil, fmt.Errorf("failed to get VRFV2PlusWrapper_Optimism ABI: %w", err) } data, err := seth.DeployContract( seth.NewTXOpts(), - "VRFV2PlusWrapperOptimism", + "VRFV2PlusWrapper_Optimism", *abi, common.FromHex(vrfv2plus_wrapper_optimism.VRFV2PlusWrapperOptimismMetaData.Bin), common.HexToAddress(linkAddr), common.HexToAddress(linkEthFeedAddr), common.HexToAddress(coordinatorAddr), subId) if err != nil { - return nil, fmt.Errorf("VRFV2PlusWrapperOptimism instance deployment have failed: %w", err) + return nil, fmt.Errorf("VRFV2PlusWrapper_Optimism instance deployment have failed: %w", err) } contract, err := vrfv2plus_wrapper_optimism.NewVRFV2PlusWrapperOptimism(data.Address, wrappers.MustNewWrappedContractBackend(nil, seth)) if err != nil { - return nil, fmt.Errorf("failed to instantiate VRFV2PlusWrapperOptimism instance: %w", err) + return nil, fmt.Errorf("failed to instantiate VRFV2PlusWrapper_Optimism instance: %w", err) } return &EthereumVRFV2PlusWrapperOptimism{ client: seth, diff --git a/integration-tests/load/vrfv2/vrfv2_test.go b/integration-tests/load/vrfv2/vrfv2_test.go index 7913d26904..c0a4153ba0 100644 --- a/integration-tests/load/vrfv2/vrfv2_test.go +++ b/integration-tests/load/vrfv2/vrfv2_test.go @@ -72,9 +72,9 @@ func TestVRFV2Performance(t *testing.T) { Uint16("RandomnessRequestCountPerRequestDeviation", *vrfv2Config.General.RandomnessRequestCountPerRequestDeviation). Bool("UseExistingEnv", *vrfv2Config.General.UseExistingEnv). Msg("Performance Test Configuration") + cleanupFn := func() { teardown(t, vrfContracts.VRFV2Consumers[0], lc, updatedLabels, testReporter, testType, &testConfig) - require.NoError(t, err, "Getting Seth client shouldn't fail") if sethClient.Cfg.IsSimulatedNetwork() { l.Info(). @@ -309,7 +309,7 @@ func TestVRFV2BHSPerformance(t *testing.T) { wgBlockNumberTobe.Add(1) //Wait at least 256 blocks latestBlockNumber, err := sethClient.Client.BlockNumber(testcontext.Get(t)) - require.NoError(t, err) + require.NoError(t, err, "error getting latest block number") _, err = actions.WaitForBlockNumberToBe( testcontext.Get(t), latestBlockNumber+uint64(257), diff --git a/integration-tests/testconfig/vrfv2/vrfv2.toml b/integration-tests/testconfig/vrfv2/vrfv2.toml index de7200b1e7..634e3074fe 100644 --- a/integration-tests/testconfig/vrfv2/vrfv2.toml +++ b/integration-tests/testconfig/vrfv2/vrfv2.toml @@ -19,6 +19,7 @@ MaxSize = '0b' [WebServer] AllowOrigins = '*' HTTPPort = 6688 +HTTPWriteTimeout = '1m0s' SecureCookies = false [WebServer.RateLimit] diff --git a/integration-tests/testconfig/vrfv2plus/config.go b/integration-tests/testconfig/vrfv2plus/config.go index 9d863afdd1..52d518e539 100644 --- a/integration-tests/testconfig/vrfv2plus/config.go +++ b/integration-tests/testconfig/vrfv2plus/config.go @@ -59,6 +59,8 @@ type General struct { //OP Stack chains settings L1FeeCalculationMode uint8 `toml:"l1_fee_calculation_mode"` L1FeeCoefficient uint8 `toml:"l1_fee_coefficient"` + + UseTestCoordinator *bool `toml:"use_test_coordinator"` } func (c *General) Validate() error { @@ -101,6 +103,9 @@ func (c *General) Validate() error { if c.CoordinatorLinkPremiumPercentage == nil { return errors.New("coordinator_link_premium_percentage must not be nil") } + if c.UseTestCoordinator == nil { + return errors.New("use_test_coordinator must not be nil") + } return nil } diff --git a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml index 860c0c158b..1281ae7f2d 100644 --- a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml +++ b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml @@ -30,7 +30,78 @@ Unauthenticated = 100 HTTPSPort = 0 """ +# Node TOML config depending on the chain [NodeConfig.ChainConfigTOMLByChainID] +# ETHEREUM SEPOLIA +11155111 = """ +BlockBackfillDepth = 500 +MinIncomingConfirmations = 3 + +[GasEstimator] +LimitDefault = 3500000 +""" + +# BNB TESTNET +97 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + +# Polygon Amoy +80002 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 + +[Transactions] +MaxInFlight = 128 +MaxQueued = 0 + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + +# Avalanche Fuji +43113 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + +# Arbitrum Sepolia +# NOTE: PROD env has `LimitDefault = 100_000_000`, but it is decreased in order not to over spend testnet tokens +421614 = """ +BlockBackfillDepth = 15000 +LogBackfillBatchSize = 1000 +RPCDefaultBatchSize = 25 + +[Transactions] +MaxInFlight = 128 +MaxQueued = 0 + +[GasEstimator] +LimitDefault = 3_500_000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + # OPTIMISM SEPOLIA 11155420 = """ BlockBackfillDepth = 500 @@ -56,12 +127,69 @@ LimitDefault = 3500000 [GasEstimator.BlockHistory] BatchSize = 100 """ +# Nexon Staging +847799 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 +NoNewHeadsThreshold = '0s' + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + +# Nexon QA +807424 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 +NoNewHeadsThreshold = '0s' + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + +# Nexon TEST +595581 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 +NoNewHeadsThreshold = '0s' + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + +# Nexon DEV +5668 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 +NoNewHeadsThreshold = '0s' + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + [Common] chainlink_node_funding = 0.7 [VRFv2Plus] [VRFv2Plus.General] +use_test_coordinator = false cancel_subs_after_test_run = true use_existing_env = false #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request @@ -222,8 +350,10 @@ bhs_test_rate_limit_unit_duration = "3s" bhs_test_rps = 1 ### POLYGON AMOY Config - +[POLYGON_AMOY.Common] +chainlink_node_funding = 5 [POLYGON_AMOY.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 3 @@ -233,7 +363,7 @@ callback_gas_limit = 1000000 # NEW ENV CONFIG # CL Node config -cl_node_max_gas_price_gwei = 200 +cl_node_max_gas_price_gwei = 500 number_of_sending_keys_to_create = 0 # Coordinator config @@ -303,16 +433,16 @@ node_sending_keys = [ randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5 +subscription_funding_amount_link = 3 subscription_funding_amount_native = 1 -subscription_refunding_amount_link = 5 +subscription_refunding_amount_link = 3 subscription_refunding_amount_native = 1 number_of_words = 1 random_words_fulfilled_event_timeout = "1m30s" wait_for_256_blocks_timeout = "15m" wrapper_consumer_funding_amount_native_token = 1.0 -wrapper_consumer_funding_amount_link = 5 +wrapper_consumer_funding_amount_link = 3 [POLYGON_AMOY-Smoke.VRFv2Plus.Performance] @@ -364,15 +494,20 @@ rps = 1 ### ARBITRUM SEPOLIA Config [ARBITRUM_SEPOLIA.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 0 -subscription_billing_type = "LINK_AND_NATIVE" +## NEW ENV CONFIG +## CL Node config cl_node_max_gas_price_gwei = 50 number_of_sending_keys_to_create = 0 -# Coordinator config +# Consumer Request config +subscription_billing_type = "LINK_AND_NATIVE" callback_gas_limit = 1000000 + +# Coordinator config max_gas_limit_coordinator_config = 2500000 fallback_wei_per_unit_link = "5352799651145251" staleness_seconds = 172_800 @@ -445,8 +580,8 @@ randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be l number_of_sub_to_create = 1 subscription_funding_amount_link = 5 subscription_funding_amount_native = 1 -subscription_refunding_amount_link = 20 -subscription_refunding_amount_native = 10 +subscription_refunding_amount_link = 5 +subscription_refunding_amount_native = 1 number_of_words = 1 random_words_fulfilled_event_timeout = "1m30s" wait_for_256_blocks_timeout = "100s" @@ -502,7 +637,10 @@ rps = 1 ### AVALANCHE FUJI Config +[AVALANCHE_FUJI.Common] +chainlink_node_funding = 3 [AVALANCHE_FUJI.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 0 @@ -568,10 +706,10 @@ node_sending_keys = [ randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 20 -subscription_funding_amount_native = 20 -subscription_refunding_amount_link = 20 -subscription_refunding_amount_native = 20 +subscription_funding_amount_link = 3 +subscription_funding_amount_native = 1 +subscription_refunding_amount_link = 3 +subscription_refunding_amount_native = 1 number_of_words = 1 random_words_fulfilled_event_timeout = "1m30s" wait_for_256_blocks_timeout = "10m" @@ -627,6 +765,7 @@ rps = 1 ### ETH SEPOLIA Config [SEPOLIA.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 3 @@ -692,16 +831,16 @@ node_sending_keys = [ randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5 +subscription_funding_amount_link = 3 subscription_funding_amount_native = 1 -subscription_refunding_amount_link = 5 +subscription_refunding_amount_link = 3 subscription_refunding_amount_native = 1 number_of_words = 1 random_words_fulfilled_event_timeout = "1m30s" wait_for_256_blocks_timeout = "70m" wrapper_consumer_funding_amount_native_token = 1.0 -wrapper_consumer_funding_amount_link = 5 +wrapper_consumer_funding_amount_link = 3 [SEPOLIA-Smoke.VRFv2Plus.Performance] test_duration = "2s" @@ -747,8 +886,9 @@ test_duration = "2m" rate_limit_unit_duration = "3s" rps = 1 -### BSC SEPOLIA Config +### BSC TESTNET Config [BSC_TESTNET.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 3 @@ -814,8 +954,16 @@ node_sending_keys = [ randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 10 -subscription_funding_amount_native = 10 +subscription_funding_amount_link = 3 +subscription_funding_amount_native = 1 +subscription_refunding_amount_link = 3 +subscription_refunding_amount_native = 1 +number_of_words = 1 +random_words_fulfilled_event_timeout = "1m30s" +wait_for_256_blocks_timeout = "15m" + +wrapper_consumer_funding_amount_native_token = 1.0 +wrapper_consumer_funding_amount_link = 5 [BSC_TESTNET-Smoke.VRFv2Plus.Performance] test_duration = "15s" @@ -866,6 +1014,7 @@ rps = 1 ### NEXON QA Config [NEXON_QA.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 0 generate_txs_on_chain = true @@ -952,6 +1101,7 @@ rps = 1 ### NEXON DEV Config [NEXON_DEV.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 0 generate_txs_on_chain = true @@ -1037,6 +1187,7 @@ rps = 1 ### NEXON TEST Config [NEXON_TEST.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 0 generate_txs_on_chain = true @@ -1123,6 +1274,7 @@ rps = 1 ### NEXON STAGE Config [NEXON_STAGE.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 0 generate_txs_on_chain = true @@ -1201,3 +1353,5 @@ subscription_funding_amount_native = 0.1 test_duration = "2m" rate_limit_unit_duration = "3s" rps = 1 + + From 95ae74437c42699d27e1d37f66ca8ddef68ce58f Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Mon, 26 Aug 2024 15:57:50 +0200 Subject: [PATCH 168/432] Bump NPM and Forge dependencies (#14093) * bump npm * more npm * bump foundry dep * make snapshot * rm gas tests * fix change in gas cost * fix blockhash, this breaks the proof * Regenerated VRF proofs and fixed payment outputs in Foundry tests * Updated gas cost for LINK payments in unit tests * try with no coverage, exclude test files from Slither * add support for extra code coverage params * fix warnings and snapshot * changeset * fix codeowners * fix tests and bump foundry * add missing changes quantifier --------- Co-authored-by: Iva Brajer Co-authored-by: Bartek Tofel --- .github/CODEOWNERS | 4 +- .github/workflows/solidity-foundry.yml | 37 +- contracts/.changeset/few-camels-tan.md | 5 + contracts/GNUmakefile | 2 +- contracts/gas-snapshots/ccip.gas-snapshot | 58 +- .../gas-snapshots/functions.gas-snapshot | 18 +- contracts/gas-snapshots/keystone.gas-snapshot | 135 +- contracts/gas-snapshots/l2ep.gas-snapshot | 44 +- .../liquiditymanager.gas-snapshot | 2 +- .../gas-snapshots/llo-feeds.gas-snapshot | 7 +- .../operatorforwarder.gas-snapshot | 8 +- contracts/gas-snapshots/shared.gas-snapshot | 24 +- contracts/package.json | 30 +- contracts/pnpm-lock.yaml | 1083 ++++++----------- .../mocks/MaliciousConfigurationContract.sol | 2 +- .../ArbitrumSequencerUptimeFeed.t.sol | 196 --- .../OptimismSequencerUptimeFeed.t.sol | 204 ---- .../scroll/ScrollSequencerUptimeFeed.t.sol | 204 ---- .../libraries/test/ByteUtilTest.t.sol | 24 +- .../test/testhelpers/MaliciousConsumer.sol | 2 +- .../MaliciousMultiWordConsumer.sol | 2 +- .../shared/test/call/CallWithExactGas.t.sol | 4 +- .../shared/test/testhelpers/GasConsumer.sol | 5 +- .../test/token/ERC677/BurnMintERC677.t.sol | 2 +- .../token/ERC677/OpStackBurnMintERC677.t.sol | 2 +- .../test/util/SortedSetValidationUtil.t.sol | 8 +- .../vrf/test/BatchVRFCoordinatorV2Plus.t.sol | 80 +- contracts/src/v0.8/vrf/test/VRFV2Plus.t.sol | 249 ++-- core/scripts/vrfv2plus/testnet/proofs.go | 2 +- 29 files changed, 761 insertions(+), 1682 deletions(-) create mode 100644 contracts/.changeset/few-camels-tan.md diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b021b8de37..3e32ae4956 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -51,7 +51,7 @@ core/scripts/functions @smartcontractkit/functions core/scripts/gateway @smartcontractkit/functions # Contracts -/contracts/ @RensR +/contracts/ @RensR @matYang @RayXpub @elatoskinas # First we match on project names to catch files like the compilation scripts, # gas snapshots and other files not places in the project directories. @@ -74,7 +74,7 @@ core/scripts/gateway @smartcontractkit/functions /contracts/src/v0.8/llo-feeds @smartcontractkit/mercury-team # TODO: mocks folder, folder should be removed and files moved to the correct folders /contracts/src/v0.8/operatorforwarder @smartcontractkit/data-feeds-engineers -/contracts/src/v0.8/shared @RensR +/contracts/src/v0.8/shared @RensR @matYang @RayXpub @elatoskinas # TODO: tests folder, folder should be removed and files moved to the correct folders # TODO: transmission folder, owner should be found /contracts/src/v0.8/vrf @smartcontractkit/vrf-team diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index ef643e32e8..0c0c3be434 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -35,7 +35,7 @@ jobs: { "name": "liquiditymanager", "setup": { "run-coverage": true, "min-coverage": 46.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "llo-feeds", "setup": { "run-coverage": true, "min-coverage": 49.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "operatorforwarder", "setup": { "run-coverage": true, "min-coverage": 55.7, "run-gas-snapshot": true, "run-forge-fmt": false }}, - { "name": "shared", "setup": { "run-coverage": true, "min-coverage": 32.6, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "shared", "setup": { "run-coverage": true, "extra-coverage-params": "--no-match-path='*CallWithExactGas*'", "min-coverage": 32.6, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "transmission", "setup": { "run-coverage": true, "min-coverage": 65.6, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "vrf", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": false, "run-forge-fmt": false }} ] @@ -62,13 +62,14 @@ jobs: sol_modified_added_files: ${{ steps.changes.outputs.sol_files }} sol_mod_only: ${{ steps.changes.outputs.sol_mod_only }} sol_mod_only_files: ${{ steps.changes.outputs.sol_mod_only_files }} - not_test_sol_modified: ${{ steps.changes.outputs.not_test_sol }} - not_test_sol_modified_files: ${{ steps.changes.outputs.not_test_sol_files }} + not_test_sol_modified: ${{ steps.changes-non-test.outputs.not_test_sol }} + not_test_sol_modified_files: ${{ steps.changes-non-test.outputs.not_test_sol_files }} all_changes: ${{ steps.changes.outputs.changes }} steps: - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + - name: Detect changes + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 id: changes with: list-files: 'shell' @@ -111,6 +112,26 @@ jobs: transmission: - 'contracts/src/v0.8/transmission/**/*.sol' + - name: Detect non-test changes + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: changes-non-test + with: + list-files: 'shell' + # This is a valid input, see https://github.com/dorny/paths-filter/pull/226 + predicate-quantifier: every + filters: | + not_test_sol: + - modified|added: 'contracts/src/v0.8/**/!(*.t).sol' + - '!contracts/src/v0.8/**/test/**' + - '!contracts/src/v0.8/**/tests/**' + - '!contracts/src/v0.8/**/mock/**' + - '!contracts/src/v0.8/**/mocks/**' + - '!contracts/src/v0.8/**/*.t.sol' + - '!contracts/src/v0.8/*.t.sol' + - '!contracts/src/v0.8/**/testhelpers/**' + - '!contracts/src/v0.8/testhelpers/**' + - '!contracts/src/v0.8/vendor/**' + tests: if: ${{ needs.changes.outputs.non_src_changes == 'true' || needs.changes.outputs.sol_modified_added == 'true' }} strategy: @@ -198,7 +219,13 @@ jobs: || needs.changes.outputs.non_src_changes == 'true') && matrix.product.setup.run-coverage }} working-directory: contracts - run: forge coverage --report lcov + shell: bash + run: | + if [[ -n "${{ matrix.product.setup.extra-coverage-params }}" ]]; then + forge coverage --report lcov ${{ matrix.product.setup.extra-coverage-params }} + else + forge coverage --report lcov + fi env: FOUNDRY_PROFILE: ${{ matrix.product.name }} diff --git a/contracts/.changeset/few-camels-tan.md b/contracts/.changeset/few-camels-tan.md new file mode 100644 index 0000000000..ca2574171d --- /dev/null +++ b/contracts/.changeset/few-camels-tan.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +bump dependencies diff --git a/contracts/GNUmakefile b/contracts/GNUmakefile index 0ebad8446e..2f111be018 100644 --- a/contracts/GNUmakefile +++ b/contracts/GNUmakefile @@ -43,7 +43,7 @@ mockery: $(mockery) ## Install mockery. .PHONY: foundry foundry: ## Install foundry. - foundryup --version nightly-de33b6af53005037b463318d2628b5cfcaf39916 + foundryup --version nightly-515a4cc8aba1627a717a1057ff4f09c8cd3bf51f .PHONY: foundry-refresh foundry-refresh: foundry diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 5fc99a9a40..eb96103c40 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -100,7 +100,7 @@ CommitStore_report:test_OnlyPriceUpdateStaleReport_Revert() (gas: 59049) CommitStore_report:test_OnlyTokenPriceUpdates_Success() (gas: 53251) CommitStore_report:test_Paused_Revert() (gas: 21259) CommitStore_report:test_ReportAndPriceUpdate_Success() (gas: 84242) -CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56313) +CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56249) CommitStore_report:test_RootAlreadyCommitted_Revert() (gas: 63969) CommitStore_report:test_StaleReportWithRoot_Success() (gas: 119420) CommitStore_report:test_Unhealthy_Revert() (gas: 44751) @@ -120,7 +120,7 @@ CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424253) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1103438) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1100092) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38157) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 108343) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 116811) @@ -179,7 +179,7 @@ EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17154) EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18413) EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249368) EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20672) -EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 201673) +EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 204173) EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48860) EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48381) EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 232798) @@ -201,12 +201,12 @@ EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Suc EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 173962) EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 193657) EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259648) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 129585) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 129288) EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 391710) EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65899) EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80955) EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 535429) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 480345) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 479260) EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35763) EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 520344) EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 517712) @@ -272,10 +272,10 @@ EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Succ EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 224545) EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 140840) EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 162262) -EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3803257) +EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3805757) EVM2EVMMultiOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 127615) EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 93044) -EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 282576) +EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 285076) EVM2EVMMultiOnRamp_getFee:test_EmptyMessage_Success() (gas: 104423) EVM2EVMMultiOnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 74041) EVM2EVMMultiOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119755) @@ -323,13 +323,13 @@ EVM2EVMOffRamp_execute:test_RouterYULCall_Revert() (gas: 402506) EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 159387) EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 174622) EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 248634) -EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 115017) +EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114706) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 409338) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54173) EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 132056) EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52200) EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 560178) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 499424) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 498159) EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35442) EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 546987) EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64045) @@ -338,7 +338,7 @@ EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (ga EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 20582) EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 281891) EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20231) -EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 219228) +EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 221728) EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48632) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48120) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 316477) @@ -384,14 +384,14 @@ EVM2EVMOnRamp_forwardFromRouter:test_MaxFeeBalanceReached_Revert() (gas: 36457) EVM2EVMOnRamp_forwardFromRouter:test_MessageGasLimitTooHigh_Revert() (gas: 29037) EVM2EVMOnRamp_forwardFromRouter:test_MessageTooLarge_Revert() (gas: 107526) EVM2EVMOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 22635) -EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 223665) +EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 226165) EVM2EVMOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 53935) EVM2EVMOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 25481) EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59303) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179141) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 177355) EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137297) -EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3731767) +EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3734267) EVM2EVMOnRamp_forwardFromRouter:test_TooManyTokens_Revert() (gas: 30187) EVM2EVMOnRamp_forwardFromRouter:test_Unhealthy_Revert() (gas: 43300) EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109258) @@ -429,7 +429,7 @@ EVM2EVMOnRamp_getTokenTransferCost:test__getTokenTransferCost_selfServeUsesDefau EVM2EVMOnRamp_linkAvailableForPayment:test_InsufficientLinkBalance_Success() (gas: 32615) EVM2EVMOnRamp_linkAvailableForPayment:test_LinkAvailableForPayment_Success() (gas: 134833) EVM2EVMOnRamp_payNops:test_AdminPayNops_Success() (gas: 143054) -EVM2EVMOnRamp_payNops:test_InsufficientBalance_Revert() (gas: 26543) +EVM2EVMOnRamp_payNops:test_InsufficientBalance_Revert() (gas: 29043) EVM2EVMOnRamp_payNops:test_NoFeesToPay_Revert() (gas: 127367) EVM2EVMOnRamp_payNops:test_NoNopsToPay_Revert() (gas: 133251) EVM2EVMOnRamp_payNops:test_NopPayNops_Success() (gas: 146341) @@ -461,7 +461,7 @@ EVM2EVMOnRamp_withdrawNonLinkFees:test_SettlingBalance_Success() (gas: 272015) EVM2EVMOnRamp_withdrawNonLinkFees:test_WithdrawNonLinkFees_Success() (gas: 53446) EVM2EVMOnRamp_withdrawNonLinkFees:test_WithdrawToZeroAddress_Revert() (gas: 12830) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_fallbackToWethTransfer() (gas: 96729) -EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 47688) +EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 49688) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongToken() (gas: 17384) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongTokenAmount() (gas: 15677) EtherSenderReceiverTest_ccipSend:test_ccipSend_reverts_insufficientFee_feeToken() (gas: 99741) @@ -548,7 +548,7 @@ MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExce MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78780) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 263510) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54784) -MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 9223372036854754743) +MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 1073667518) MultiAggregateRateLimiter_onOutboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 19104) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 15778) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 189438) @@ -590,16 +590,16 @@ MultiOCR3Base_transmit:test_InsufficientSignatures_Revert() (gas: 76930) MultiOCR3Base_transmit:test_NonUniqueSignature_Revert() (gas: 66127) MultiOCR3Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 33419) MultiOCR3Base_transmit:test_TooManySignatures_Revert() (gas: 79521) -MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34131) +MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34020) MultiOCR3Base_transmit:test_TransmitWithExtraCalldataArgs_Revert() (gas: 47114) MultiOCR3Base_transmit:test_TransmitWithLessCalldataArgs_Revert() (gas: 25682) -MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18726) +MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18714) MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 412349) -MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1426976) +MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1423227) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) @@ -628,7 +628,7 @@ OCR2BaseNoChecks_setOCR2Config:test_TooManyTransmitter_Revert() (gas: 36938) OCR2BaseNoChecks_setOCR2Config:test_TransmitterCannotBeZeroAddress_Revert() (gas: 24158) OCR2BaseNoChecks_transmit:test_ConfigDigestMismatch_Revert() (gas: 17448) OCR2BaseNoChecks_transmit:test_ForkedChain_Revert() (gas: 26726) -OCR2BaseNoChecks_transmit:test_TransmitSuccess_gas() (gas: 27478) +OCR2BaseNoChecks_transmit:test_TransmitSuccess_gas() (gas: 27466) OCR2BaseNoChecks_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 21296) OCR2Base_setOCR2Config:test_FMustBePositive_Revert() (gas: 12189) OCR2Base_setOCR2Config:test_FTooHigh_Revert() (gas: 12345) @@ -642,12 +642,12 @@ OCR2Base_transmit:test_ConfigDigestMismatch_Revert() (gas: 19623) OCR2Base_transmit:test_ForkedChain_Revert() (gas: 37683) OCR2Base_transmit:test_NonUniqueSignature_Revert() (gas: 55309) OCR2Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 20962) -OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51686) +OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51674) OCR2Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 23484) OCR2Base_transmit:test_UnauthorizedSigner_Revert() (gas: 39665) OCR2Base_transmit:test_WrongNumberOfSignatures_Revert() (gas: 20557) OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 380360) -PingPong_ccipReceive:test_CcipReceive_Success() (gas: 148380) +PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150880) PingPong_plumbing:test_Pausing_Success() (gas: 17803) PingPong_startPingPong:test_StartPingPong_Success() (gas: 178340) PriceRegistry_applyDestChainConfigUpdates:test_InvalidChainFamilySelector_Revert() (gas: 16719) @@ -759,7 +759,7 @@ RMN_ownerUnbless:test_Unbless_Success() (gas: 74699) RMN_ownerUnvoteToCurse:test_CanBlessAndCurseAfterGlobalCurseIsLifted() (gas: 470965) RMN_ownerUnvoteToCurse:test_IsIdempotent() (gas: 397532) RMN_ownerUnvoteToCurse:test_NonOwner_Revert() (gas: 18591) -RMN_ownerUnvoteToCurse:test_OwnerUnvoteToCurseSuccess_gas() (gas: 357403) +RMN_ownerUnvoteToCurse:test_OwnerUnvoteToCurseSuccess_gas() (gas: 357400) RMN_ownerUnvoteToCurse:test_UnknownVoter_Revert() (gas: 32980) RMN_ownerUnvoteToCurse_Benchmark:test_OwnerUnvoteToCurse_1Voter_LiftsCurse_gas() (gas: 261985) RMN_permaBlessing:test_PermaBlessing() (gas: 202686) @@ -767,7 +767,7 @@ RMN_setConfig:test_BlessVoterIsZeroAddress_Revert() (gas: 15494) RMN_setConfig:test_EitherThresholdIsZero_Revert() (gas: 21095) RMN_setConfig:test_NonOwner_Revert() (gas: 14713) RMN_setConfig:test_RepeatedAddress_Revert() (gas: 18213) -RMN_setConfig:test_SetConfigSuccess_gas() (gas: 104204) +RMN_setConfig:test_SetConfigSuccess_gas() (gas: 104022) RMN_setConfig:test_TotalWeightsSmallerThanEachThreshold_Revert() (gas: 30173) RMN_setConfig:test_VoteToBlessByEjectedVoter_Revert() (gas: 130303) RMN_setConfig:test_VotersLengthIsZero_Revert() (gas: 12128) @@ -852,18 +852,18 @@ Router_getFee:test_GetFeeSupportedChain_Success() (gas: 46464) Router_getFee:test_UnsupportedDestinationChain_Revert() (gas: 17138) Router_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10460) Router_recoverTokens:test_RecoverTokensInvalidRecipient_Revert() (gas: 11316) -Router_recoverTokens:test_RecoverTokensNoFunds_Revert() (gas: 17761) +Router_recoverTokens:test_RecoverTokensNoFunds_Revert() (gas: 20261) Router_recoverTokens:test_RecoverTokensNonOwner_Revert() (gas: 11159) Router_recoverTokens:test_RecoverTokensValueReceiver_Revert() (gas: 422138) -Router_recoverTokens:test_RecoverTokens_Success() (gas: 50437) +Router_recoverTokens:test_RecoverTokens_Success() (gas: 52437) Router_routeMessage:test_AutoExec_Success() (gas: 42684) Router_routeMessage:test_ExecutionEvent_Success() (gas: 158002) Router_routeMessage:test_ManualExec_Success() (gas: 35381) Router_routeMessage:test_OnlyOffRamp_Revert() (gas: 25116) Router_routeMessage:test_WhenNotHealthy_Revert() (gas: 44724) Router_setWrappedNative:test_OnlyOwner_Revert() (gas: 10985) -SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 53540) -SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 416930) +SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 55540) +SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 419430) SelfFundedPingPong_setCountIncrBeforeFunding:test_setCountIncrBeforeFunding() (gas: 20157) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_OnlyPendingAdministrator_Revert() (gas: 51085) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_Success() (gas: 43947) @@ -889,8 +889,8 @@ TokenAdminRegistry_transferAdminRole:test_transferAdminRole_OnlyAdministrator_Re TokenAdminRegistry_transferAdminRole:test_transferAdminRole_Success() (gas: 49390) TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6036775) TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6282531) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6883397) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7067512) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6885897) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7070012) TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2169749) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12089) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23280) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index 44d557ebcf..69e0271684 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -45,7 +45,7 @@ FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_Success() (gas: 88970) FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_RevertNotOwner() (gas: 13915) FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_Success() (gas: 513165) FunctionsCoordinator_StartRequest:test_StartRequest_RevertIfNotRouter() (gas: 22802) -FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 150150) +FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 152650) FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessFound() (gas: 15106) FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessNotFound() (gas: 22916) FunctionsRequest_DEFAULT_BUFFER_SIZE:test_DEFAULT_BUFFER_SIZE() (gas: 3089) @@ -200,7 +200,7 @@ FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_ FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 89013) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23620) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866619) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 26026) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 28526) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1946966) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 104555) FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15535) @@ -232,10 +232,10 @@ FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84725) Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79140) Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73419) -Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MaximumGas() (gas: 20717) -Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MinimumGas() (gas: 20157) -Gas_FulfillRequest_Success:test_FulfillRequest_Success_MaximumGas() (gas: 501339) -Gas_FulfillRequest_Success:test_FulfillRequest_Success_MinimumGas() (gas: 202509) -Gas_FundSubscription:test_FundSubscription_Gas() (gas: 38524) -Gas_SendRequest:test_SendRequest_MaximumGas() (gas: 988895) -Gas_SendRequest:test_SendRequest_MinimumGas() (gas: 181579) \ No newline at end of file +Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MaximumGas() (gas: 20562) +Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MinimumGas() (gas: 20024) +Gas_FulfillRequest_Success:test_FulfillRequest_Success_MaximumGas() (gas: 501184) +Gas_FulfillRequest_Success:test_FulfillRequest_Success_MinimumGas() (gas: 202376) +Gas_FundSubscription:test_FundSubscription_Gas() (gas: 38518) +Gas_SendRequest:test_SendRequest_MaximumGas() (gas: 984338) +Gas_SendRequest:test_SendRequest_MinimumGas() (gas: 181561) \ No newline at end of file diff --git a/contracts/gas-snapshots/keystone.gas-snapshot b/contracts/gas-snapshots/keystone.gas-snapshot index 49b1d4add4..d75d68a172 100644 --- a/contracts/gas-snapshots/keystone.gas-snapshot +++ b/contracts/gas-snapshots/keystone.gas-snapshot @@ -1,86 +1,87 @@ -CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_NoConfigurationContract() (gas: 154832) -CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_WithConfiguration() (gas: 178813) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 24723) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CapabilityExists() (gas: 145703) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractDoesNotMatchInterface() (gas: 94606) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractNotDeployed() (gas: 92961) -CapabilitiesRegistry_AddDONTest:test_AddDON() (gas: 372302) +CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_NoConfigurationContract() (gas: 154809) +CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_WithConfiguration() (gas: 178790) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 24678) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CapabilityExists() (gas: 145613) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractDoesNotMatchInterface() (gas: 94561) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractNotDeployed() (gas: 92916) +CapabilitiesRegistry_AddDONTest:test_AddDON() (gas: 373685) CapabilitiesRegistry_AddDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19273) CapabilitiesRegistry_AddDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 169752) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 239789) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 249596) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 239724) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 250935) CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 116890) CapabilitiesRegistry_AddDONTest:test_RevertWhen_FaultToleranceIsZero() (gas: 43358) CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeAlreadyBelongsToWorkflowDON() (gas: 343924) CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 180150) -CapabilitiesRegistry_AddNodeOperatorsTest:test_AddNodeOperators() (gas: 184135) -CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_CalledByNonAdmin() (gas: 17602) -CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_NodeOperatorAdminAddressZero() (gas: 18498) -CapabilitiesRegistry_AddNodesTest:test_AddsNodeParams() (gas: 358448) -CapabilitiesRegistry_AddNodesTest:test_OwnerCanAddNodes() (gas: 358414) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingDuplicateP2PId() (gas: 301229) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 55174) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidNodeOperator() (gas: 24895) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithoutCapabilities() (gas: 27669) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25108) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 27408) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 27047) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressNotUnique() (gas: 309679) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_DeprecatesCapability() (gas: 89807) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_EmitsEvent() (gas: 89935) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 22944) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 16231) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityIsDeprecated() (gas: 91264) -CapabilitiesRegistry_GetCapabilitiesTest:test_ReturnsCapabilities() (gas: 135553) +CapabilitiesRegistry_AddDONTest_WhenMaliciousCapabilityConfigurationConfigured:test_RevertWhen_MaliciousCapabilitiesConfigContractTriesToRemoveCapabilitiesFromDONNodes() (gas: 340499) +CapabilitiesRegistry_AddNodeOperatorsTest:test_AddNodeOperators() (gas: 184157) +CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_CalledByNonAdmin() (gas: 17624) +CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_NodeOperatorAdminAddressZero() (gas: 18520) +CapabilitiesRegistry_AddNodesTest:test_AddsNodeParams() (gas: 358492) +CapabilitiesRegistry_AddNodesTest:test_OwnerCanAddNodes() (gas: 358458) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingDuplicateP2PId() (gas: 301273) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 55196) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidNodeOperator() (gas: 24917) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithoutCapabilities() (gas: 27691) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25130) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 27430) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 27069) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressNotUnique() (gas: 309723) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_DeprecatesCapability() (gas: 89742) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_EmitsEvent() (gas: 89870) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 22879) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 16166) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityIsDeprecated() (gas: 91134) +CapabilitiesRegistry_GetCapabilitiesTest:test_ReturnsCapabilities() (gas: 135488) CapabilitiesRegistry_GetDONsTest:test_CorrectlyFetchesDONs() (gas: 65468) CapabilitiesRegistry_GetDONsTest:test_DoesNotIncludeRemovedDONs() (gas: 64924) CapabilitiesRegistry_GetHashedCapabilityTest:test_CorrectlyGeneratesHashedCapabilityId() (gas: 11428) CapabilitiesRegistry_GetHashedCapabilityTest:test_DoesNotCauseIncorrectClashes() (gas: 13087) -CapabilitiesRegistry_GetNodeOperatorsTest:test_CorrectlyFetchesNodeOperators() (gas: 36407) -CapabilitiesRegistry_GetNodeOperatorsTest:test_DoesNotIncludeRemovedNodeOperators() (gas: 38692) +CapabilitiesRegistry_GetNodeOperatorsTest:test_CorrectlyFetchesNodeOperators() (gas: 36429) +CapabilitiesRegistry_GetNodeOperatorsTest:test_DoesNotIncludeRemovedNodeOperators() (gas: 38714) CapabilitiesRegistry_GetNodesTest:test_CorrectlyFetchesNodes() (gas: 65288) -CapabilitiesRegistry_GetNodesTest:test_DoesNotIncludeRemovedNodes() (gas: 73533) -CapabilitiesRegistry_RemoveDONsTest:test_RemovesDON() (gas: 54761) +CapabilitiesRegistry_GetNodesTest:test_DoesNotIncludeRemovedNodes() (gas: 73497) +CapabilitiesRegistry_RemoveDONsTest:test_RemovesDON() (gas: 54783) CapabilitiesRegistry_RemoveDONsTest:test_RevertWhen_CalledByNonAdmin() (gas: 15647) CapabilitiesRegistry_RemoveDONsTest:test_RevertWhen_DONDoesNotExist() (gas: 16550) CapabilitiesRegistry_RemoveNodeOperatorsTest:test_RemovesNodeOperator() (gas: 36122) CapabilitiesRegistry_RemoveNodeOperatorsTest:test_RevertWhen_CalledByNonOwner() (gas: 15816) -CapabilitiesRegistry_RemoveNodesTest:test_CanAddNodeWithSameSignerAddressAfterRemoving() (gas: 115151) -CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenDONDeleted() (gas: 287716) -CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenNodeNoLongerPartOfDON() (gas: 561023) -CapabilitiesRegistry_RemoveNodesTest:test_OwnerCanRemoveNodes() (gas: 73376) -CapabilitiesRegistry_RemoveNodesTest:test_RemovesNode() (gas: 75211) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25053) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 18418) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodePartOfCapabilitiesDON() (gas: 385369) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 18408) +CapabilitiesRegistry_RemoveNodesTest:test_CanAddNodeWithSameSignerAddressAfterRemoving() (gas: 115150) +CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenDONDeleted() (gas: 287648) +CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenNodeNoLongerPartOfDON() (gas: 560993) +CapabilitiesRegistry_RemoveNodesTest:test_OwnerCanRemoveNodes() (gas: 73358) +CapabilitiesRegistry_RemoveNodesTest:test_RemovesNode() (gas: 75192) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25008) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 18373) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodePartOfCapabilitiesDON() (gas: 385324) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 18363) CapabilitiesRegistry_TypeAndVersionTest:test_TypeAndVersion() (gas: 9796) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19415) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 152914) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DONDoesNotExist() (gas: 17835) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 222996) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 232804) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 107643) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 163357) -CapabilitiesRegistry_UpdateDONTest:test_UpdatesDON() (gas: 371909) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_CalledByNonAdminAndNonOwner() (gas: 20728) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorAdminIsZeroAddress() (gas: 20052) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorDoesNotExist() (gas: 19790) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorIdAndParamLengthsMismatch() (gas: 15430) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_UpdatesNodeOperator() (gas: 37034) -CapabilitiesRegistry_UpdateNodesTest:test_CanUpdateParamsIfNodeSignerAddressNoLongerUsed() (gas: 256371) -CapabilitiesRegistry_UpdateNodesTest:test_OwnerCanUpdateNodes() (gas: 162166) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 35873) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByAnotherNodeOperatorAdmin() (gas: 29200) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 29377) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 29199) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeSignerAlreadyAssignedToAnotherNode() (gas: 31326) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 29165) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByCapabilityDON() (gas: 470910) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByWorkflowDON() (gas: 341191) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 29058) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 27587) -CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162220) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19314) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 152949) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DONDoesNotExist() (gas: 17740) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 222966) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 236977) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 107678) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 163392) +CapabilitiesRegistry_UpdateDONTest:test_UpdatesDON() (gas: 373308) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_CalledByNonAdminAndNonOwner() (gas: 20684) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorAdminIsZeroAddress() (gas: 20008) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorDoesNotExist() (gas: 19746) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorIdAndParamLengthsMismatch() (gas: 15386) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_UpdatesNodeOperator() (gas: 36990) +CapabilitiesRegistry_UpdateNodesTest:test_CanUpdateParamsIfNodeSignerAddressNoLongerUsed() (gas: 256437) +CapabilitiesRegistry_UpdateNodesTest:test_OwnerCanUpdateNodes() (gas: 162210) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 35895) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByAnotherNodeOperatorAdmin() (gas: 29222) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 29399) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 29221) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeSignerAlreadyAssignedToAnotherNode() (gas: 31348) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 29187) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByCapabilityDON() (gas: 470932) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByWorkflowDON() (gas: 341213) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 29080) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 27609) +CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162264) KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 2003568) KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() (gas: 124908) KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverNotContract() (gas: 126927) diff --git a/contracts/gas-snapshots/l2ep.gas-snapshot b/contracts/gas-snapshots/l2ep.gas-snapshot index 324cacfc02..42a9aa0b35 100644 --- a/contracts/gas-snapshots/l2ep.gas-snapshot +++ b/contracts/gas-snapshots/l2ep.gas-snapshot @@ -24,17 +24,9 @@ ArbitrumCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 4 ArbitrumCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 19312) ArbitrumCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 18671) ArbitrumCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 13219) -ArbitrumSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForGetAnswer() (gas: 92790) -ArbitrumSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForGetRoundData() (gas: 93351) -ArbitrumSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForGetTimestamp() (gas: 92711) -ArbitrumSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForLatestAnswer() (gas: 90485) -ArbitrumSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForLatestRound() (gas: 90377) -ArbitrumSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForLatestRoundData() (gas: 90924) -ArbitrumSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForLatestTimestamp() (gas: 90362) ArbitrumSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 104994) ArbitrumSequencerUptimeFeed_AggregatorV3Interface:test_Return0WhenRoundDoesNotExistYet() (gas: 20033) ArbitrumSequencerUptimeFeed_Constants:test_InitialState() (gas: 8530) -ArbitrumSequencerUptimeFeed_GasCosts:test_GasCosts() (gas: 99865) ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 604414) ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574476) ArbitrumSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 99662) @@ -68,27 +60,19 @@ OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 4 OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28775) OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16482) OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11030) -OptimismSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForGetAnswer() (gas: 59785) -OptimismSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForGetRoundData() (gas: 60331) -OptimismSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForGetTimestamp() (gas: 59640) -OptimismSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForLatestAnswer() (gas: 57577) -OptimismSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForLatestRound() (gas: 57463) -OptimismSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForLatestRoundData() (gas: 58005) -OptimismSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForLatestTimestamp() (gas: 57430) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 71804) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 74304) OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17679) OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17897) OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17603) OptimismSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22110) -OptimismSequencerUptimeFeed_GasCosts:test_GasCosts() (gas: 69567) OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601843) OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574481) -OptimismSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67230) +OptimismSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 69730) OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13214) OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23632) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77137) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 97545) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 97605) +OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 79637) +OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 100045) +OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 100105) OptimismValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18695) OptimismValidator_Validate:test_PostSequencerOffline() (gas: 74813) OptimismValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 74869) @@ -119,27 +103,19 @@ ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 489 ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28841) ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16482) ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11030) -ScrollSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForGetAnswer() (gas: 57940) -ScrollSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForGetRoundData() (gas: 58476) -ScrollSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForGetTimestamp() (gas: 57795) -ScrollSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForLatestAnswer() (gas: 55578) -ScrollSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForLatestRound() (gas: 55458) -ScrollSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForLatestRoundData() (gas: 56169) -ScrollSequencerUptimeFeed_AggregatorInterfaceGasCosts:test_GasUsageForLatestTimestamp() (gas: 55448) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 70090) +ScrollSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72590) ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17675) ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17893) ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17599) ScrollSequencerUptimeFeed_Constructor:test_InitialState() (gas: 103508) -ScrollSequencerUptimeFeed_GasCosts:test_GasCosts() (gas: 67258) ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601694) ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574481) -ScrollSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 65115) +ScrollSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67615) ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13214) ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23632) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 74720) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 93408) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 93468) +ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77220) +ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 95908) +ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 95968) ScrollValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18829) ScrollValidator_Validate:test_PostSequencerOffline() (gas: 78349) ScrollValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 78411) diff --git a/contracts/gas-snapshots/liquiditymanager.gas-snapshot b/contracts/gas-snapshots/liquiditymanager.gas-snapshot index 53483ed6c7..4966013617 100644 --- a/contracts/gas-snapshots/liquiditymanager.gas-snapshot +++ b/contracts/gas-snapshots/liquiditymanager.gas-snapshot @@ -39,7 +39,7 @@ OCR3Base_transmit:testForkedChainReverts() (gas: 42846) OCR3Base_transmit:testNonIncreasingSequenceNumberReverts() (gas: 30522) OCR3Base_transmit:testNonUniqueSignatureReverts() (gas: 60370) OCR3Base_transmit:testSignatureOutOfRegistrationReverts() (gas: 26128) -OCR3Base_transmit:testTransmit2SignersSuccess_gas() (gas: 56783) +OCR3Base_transmit:testTransmit2SignersSuccess_gas() (gas: 56771) OCR3Base_transmit:testUnAuthorizedTransmitterReverts() (gas: 28618) OCR3Base_transmit:testUnauthorizedSignerReverts() (gas: 44759) OCR3Base_transmit:testWrongNumberOfSignaturesReverts() (gas: 25678) diff --git a/contracts/gas-snapshots/llo-feeds.gas-snapshot b/contracts/gas-snapshots/llo-feeds.gas-snapshot index 89073a7846..68f3c016f6 100644 --- a/contracts/gas-snapshots/llo-feeds.gas-snapshot +++ b/contracts/gas-snapshots/llo-feeds.gas-snapshot @@ -18,6 +18,9 @@ ByteUtilTest:test_readUint32MultiWord() (gas: 3393) ByteUtilTest:test_readUint32WithEmptyArray() (gas: 3253) ByteUtilTest:test_readUint32WithNotEnoughBytes() (gas: 3272) ByteUtilTest:test_readZeroAddress() (gas: 3365) +ChannelConfigStoreTest:testSetChannelDefinitions() (gas: 46927) +ChannelConfigStoreTest:testSupportsInterface() (gas: 8367) +ChannelConfigStoreTest:testTypeAndVersion() (gas: 9621) DestinationFeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52669) DestinationFeeManagerProcessFeeTest:test_DiscountIsReturnedForNative() (gas: 52685) DestinationFeeManagerProcessFeeTest:test_DiscountIsReturnedForNativeWithSurcharge() (gas: 78876) @@ -76,7 +79,7 @@ DestinationFeeManagerProcessFeeTest:test_poolIdsCannotBeZeroAddress() (gas: 1153 DestinationFeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 121475) DestinationFeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 29745) DestinationFeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 165393) -DestinationFeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 30063) +DestinationFeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 32563) DestinationFeeManagerProcessFeeTest:test_processFeeNative() (gas: 178204) DestinationFeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 122766) DestinationFeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 31822) @@ -286,7 +289,7 @@ FeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 198803) FeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 117088) FeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 27462) FeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 163205) -FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 27827) +FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 30327) FeeManagerProcessFeeTest:test_processFeeNative() (gas: 173826) FeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 118379) FeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 29536) diff --git a/contracts/gas-snapshots/operatorforwarder.gas-snapshot b/contracts/gas-snapshots/operatorforwarder.gas-snapshot index 7cfc963f74..66bb19f1f6 100644 --- a/contracts/gas-snapshots/operatorforwarder.gas-snapshot +++ b/contracts/gas-snapshots/operatorforwarder.gas-snapshot @@ -2,8 +2,8 @@ FactoryTest:test_DeployNewForwarderAndTransferOwnership_Success() (gas: 1059722) FactoryTest:test_DeployNewForwarder_Success() (gas: 1048209) FactoryTest:test_DeployNewOperatorAndForwarder_Success() (gas: 4069305) FactoryTest:test_DeployNewOperator_Success() (gas: 3020464) -ForwarderTest:test_Forward_Success(uint256) (runs: 256, μ: 226200, ~: 227289) -ForwarderTest:test_MultiForward_Success(uint256,uint256) (runs: 256, μ: 257876, ~: 259120) +ForwarderTest:test_Forward_Success(uint256) (runs: 257, μ: 226979, ~: 227289) +ForwarderTest:test_MultiForward_Success(uint256,uint256) (runs: 257, μ: 258577, ~: 259120) ForwarderTest:test_OwnerForward_Success() (gas: 30118) ForwarderTest:test_SetAuthorizedSenders_Success() (gas: 160524) ForwarderTest:test_TransferOwnershipWithMessage_Success() (gas: 35123) @@ -11,5 +11,5 @@ OperatorTest:test_CancelOracleRequest_Success() (gas: 274436) OperatorTest:test_FulfillOracleRequest_Success() (gas: 330603) OperatorTest:test_NotAuthorizedSender_Revert() (gas: 246716) OperatorTest:test_OracleRequest_Success() (gas: 250019) -OperatorTest:test_SendRequestAndCancelRequest_Success(uint96) (runs: 256, μ: 387120, ~: 387124) -OperatorTest:test_SendRequest_Success(uint96) (runs: 256, μ: 303611, ~: 303615) \ No newline at end of file +OperatorTest:test_SendRequestAndCancelRequest_Success(uint96) (runs: 257, μ: 387121, ~: 387124) +OperatorTest:test_SendRequest_Success(uint96) (runs: 257, μ: 303612, ~: 303615) \ No newline at end of file diff --git a/contracts/gas-snapshots/shared.gas-snapshot b/contracts/gas-snapshots/shared.gas-snapshot index 3cc143ecc0..d7a4e21978 100644 --- a/contracts/gas-snapshots/shared.gas-snapshot +++ b/contracts/gas-snapshots/shared.gas-snapshot @@ -39,41 +39,41 @@ CallWithExactGas__callWithExactGas:test_CallWithExactGasSafeReturnDataExactGas() CallWithExactGas__callWithExactGas:test_NoContractReverts() (gas: 11559) CallWithExactGas__callWithExactGas:test_NoGasForCallExactCheckReverts() (gas: 15788) CallWithExactGas__callWithExactGas:test_NotEnoughGasForCallReverts() (gas: 16241) -CallWithExactGas__callWithExactGas:test_callWithExactGasSuccess(bytes,bytes4) (runs: 256, μ: 15811, ~: 15752) +CallWithExactGas__callWithExactGas:test_callWithExactGasSuccess(bytes,bytes4) (runs: 257, μ: 15766, ~: 15719) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractExactGasSuccess() (gas: 20116) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractReceiverErrorSuccess() (gas: 67721) -CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractSuccess(bytes,bytes4) (runs: 256, μ: 16321, ~: 16262) +CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractSuccess(bytes,bytes4) (runs: 257, μ: 16276, ~: 16229) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoContractSuccess() (gas: 12962) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoGasForCallExactCheckReturnFalseSuccess() (gas: 13005) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NotEnoughGasForCallReturnsFalseSuccess() (gas: 13317) CallWithExactGas__callWithExactGasSafeReturnData:test_CallWithExactGasSafeReturnDataExactGas() (gas: 20331) CallWithExactGas__callWithExactGasSafeReturnData:test_NoContractReverts() (gas: 13917) CallWithExactGas__callWithExactGasSafeReturnData:test_NoGasForCallExactCheckReverts() (gas: 16139) -CallWithExactGas__callWithExactGasSafeReturnData:test_NotEnoughGasForCallReverts() (gas: 16547) -CallWithExactGas__callWithExactGasSafeReturnData:test_callWithExactGasSafeReturnData_ThrowOOGError_Revert() (gas: 36752) +CallWithExactGas__callWithExactGasSafeReturnData:test_NotEnoughGasForCallReverts() (gas: 16569) +CallWithExactGas__callWithExactGasSafeReturnData:test_callWithExactGasSafeReturnData_ThrowOOGError_Revert() (gas: 36708) EnumerableMapAddresses_at:testAtSuccess() (gas: 95086) EnumerableMapAddresses_at:testBytes32AtSuccess() (gas: 94877) +EnumerableMapAddresses_at:testBytesAtSuccess() (gas: 96564) EnumerableMapAddresses_contains:testBytes32ContainsSuccess() (gas: 93518) +EnumerableMapAddresses_contains:testBytesContainsSuccess() (gas: 94012) EnumerableMapAddresses_contains:testContainsSuccess() (gas: 93696) EnumerableMapAddresses_get:testBytes32GetSuccess() (gas: 94278) +EnumerableMapAddresses_get:testBytesGetSuccess() (gas: 95879) EnumerableMapAddresses_get:testGetSuccess() (gas: 94453) +EnumerableMapAddresses_get_errorMessage:testBytesGetErrorMessageSuccess() (gas: 95878) EnumerableMapAddresses_get_errorMessage:testGetErrorMessageSuccess() (gas: 94489) EnumerableMapAddresses_length:testBytes32LengthSuccess() (gas: 72445) +EnumerableMapAddresses_length:testBytesLengthSuccess() (gas: 73011) EnumerableMapAddresses_length:testLengthSuccess() (gas: 72640) EnumerableMapAddresses_remove:testBytes32RemoveSuccess() (gas: 73462) +EnumerableMapAddresses_remove:testBytesRemoveSuccess() (gas: 74249) EnumerableMapAddresses_remove:testRemoveSuccess() (gas: 73686) EnumerableMapAddresses_set:testBytes32SetSuccess() (gas: 94496) +EnumerableMapAddresses_set:testBytesSetSuccess() (gas: 95428) EnumerableMapAddresses_set:testSetSuccess() (gas: 94685) EnumerableMapAddresses_tryGet:testBytes32TryGetSuccess() (gas: 94622) -EnumerableMapAddresses_tryGet:testTryGetSuccess() (gas: 94893) -EnumerableMapAddresses_at:testBytesAtSuccess() (gas: 96564) -EnumerableMapAddresses_contains:testBytesContainsSuccess() (gas: 94012) -EnumerableMapAddresses_get:testBytesGetSuccess() (gas: 95879) -EnumerableMapAddresses_get_errorMessage:testBytesGetErrorMessageSuccess() (gas: 95878) -EnumerableMapAddresses_length:testBytesLengthSuccess() (gas: 73011) -EnumerableMapAddresses_remove:testBytesRemoveSuccess() (gas: 74249) -EnumerableMapAddresses_set:testBytesSetSuccess() (gas: 95428) EnumerableMapAddresses_tryGet:testBytesTryGetSuccess() (gas: 96279) +EnumerableMapAddresses_tryGet:testTryGetSuccess() (gas: 94893) OpStackBurnMintERC677_constructor:testConstructorSuccess() (gas: 1743649) OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 298649) OpStackBurnMintERC677_interfaceCompatibility:testMintCompatibility() (gas: 137957) diff --git a/contracts/package.json b/contracts/package.json index 85bae226c4..26fbd88570 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -43,49 +43,49 @@ "@ethersproject/providers": "~5.7.2", "@nomicfoundation/hardhat-chai-matchers": "^1.0.6", "@nomicfoundation/hardhat-ethers": "^3.0.6", - "@nomicfoundation/hardhat-network-helpers": "^1.0.9", - "@nomicfoundation/hardhat-verify": "^2.0.7", + "@nomicfoundation/hardhat-network-helpers": "^1.0.11", + "@nomicfoundation/hardhat-verify": "^2.0.9", "@typechain/ethers-v5": "^7.2.0", "@typechain/hardhat": "^7.0.0", "@types/cbor": "~5.0.1", - "@types/chai": "^4.3.16", + "@types/chai": "^4.3.17", "@types/debug": "^4.1.12", "@types/deep-equal-in-any-order": "^1.0.3", - "@types/mocha": "^10.0.6", - "@types/node": "^20.12.12", - "@typescript-eslint/eslint-plugin": "^7.10.0", - "@typescript-eslint/parser": "^7.10.0", + "@types/mocha": "^10.0.7", + "@types/node": "^20.14.15", + "@typescript-eslint/eslint-plugin": "^7.18.0", + "@typescript-eslint/parser": "^7.18.0", "abi-to-sol": "^0.6.6", "cbor": "^5.2.0", - "chai": "^4.3.10", - "debug": "^4.3.4", + "chai": "^4.5.0", + "debug": "^4.3.6", "deep-equal-in-any-order": "^2.0.6", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-prettier": "^5.2.1", "ethers": "~5.7.2", "hardhat": "~2.20.1", "hardhat-abi-exporter": "^2.10.1", "hardhat-ignore-warnings": "^0.2.6", "moment": "^2.30.1", - "prettier": "^3.2.5", + "prettier": "^3.3.3", "prettier-plugin-solidity": "^1.3.1", - "solhint": "^5.0.1", + "solhint": "^5.0.3", "solhint-plugin-chainlink-solidity": "git+https://github.com/smartcontractkit/chainlink-solhint-rules.git#v1.2.1", "solhint-plugin-prettier": "^0.1.0", "ts-node": "^10.9.2", "typechain": "^8.2.1", - "typescript": "^5.4.5" + "typescript": "^5.5.4" }, "dependencies": { "@arbitrum/nitro-contracts": "1.1.1", "@arbitrum/token-bridge-contracts": "1.1.2", "@changesets/changelog-github": "^0.5.0", - "@changesets/cli": "~2.27.3", + "@changesets/cli": "~2.27.7", "@eth-optimism/contracts": "0.6.0", "@openzeppelin/contracts": "4.9.3", "@openzeppelin/contracts-upgradeable": "4.9.3", "@scroll-tech/contracts": "0.1.0", - "semver": "^7.6.2" + "semver": "^7.6.3" } } diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index 825715f416..5c45da8ab0 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -21,8 +21,8 @@ importers: specifier: ^0.5.0 version: 0.5.0 '@changesets/cli': - specifier: ~2.27.3 - version: 2.27.3 + specifier: ~2.27.7 + version: 2.27.7 '@eth-optimism/contracts': specifier: 0.6.0 version: 0.6.0(ethers@5.7.2) @@ -36,8 +36,8 @@ importers: specifier: 0.1.0 version: 0.1.0 semver: - specifier: ^7.6.2 - version: 7.6.2 + specifier: ^7.6.3 + version: 7.6.3 devDependencies: '@ethereum-waffle/mock-contract': specifier: ^3.4.4 @@ -56,28 +56,28 @@ importers: version: 5.7.2 '@nomicfoundation/hardhat-chai-matchers': specifier: ^1.0.6 - version: 1.0.6(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)))(chai@4.4.1)(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)) + version: 1.0.6(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4)))(chai@4.5.0)(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4)) '@nomicfoundation/hardhat-ethers': specifier: ^3.0.6 - version: 3.0.6(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)) + version: 3.0.6(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4)) '@nomicfoundation/hardhat-network-helpers': - specifier: ^1.0.9 - version: 1.0.10(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)) + specifier: ^1.0.11 + version: 1.0.11(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4)) '@nomicfoundation/hardhat-verify': - specifier: ^2.0.7 - version: 2.0.7(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)) + specifier: ^2.0.9 + version: 2.0.9(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4)) '@typechain/ethers-v5': specifier: ^7.2.0 - version: 7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.4.5))(typescript@5.4.5) + version: 7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.5.4))(typescript@5.5.4) '@typechain/hardhat': specifier: ^7.0.0 - version: 7.0.0(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.4.5))(typescript@5.4.5))(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))(typechain@8.3.2(typescript@5.4.5)) + version: 7.0.0(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.5.4))(typescript@5.5.4))(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4))(typechain@8.3.2(typescript@5.5.4)) '@types/cbor': specifier: ~5.0.1 version: 5.0.1 '@types/chai': - specifier: ^4.3.16 - version: 4.3.16 + specifier: ^4.3.17 + version: 4.3.17 '@types/debug': specifier: ^4.1.12 version: 4.1.12 @@ -85,17 +85,17 @@ importers: specifier: ^1.0.3 version: 1.0.3 '@types/mocha': - specifier: ^10.0.6 - version: 10.0.6 + specifier: ^10.0.7 + version: 10.0.7 '@types/node': - specifier: ^20.12.12 - version: 20.12.12 + specifier: ^20.14.15 + version: 20.14.15 '@typescript-eslint/eslint-plugin': - specifier: ^7.10.0 - version: 7.10.0(@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + specifier: ^7.18.0 + version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) '@typescript-eslint/parser': - specifier: ^7.10.0 - version: 7.10.0(eslint@8.57.0)(typescript@5.4.5) + specifier: ^7.18.0 + version: 7.18.0(eslint@8.57.0)(typescript@5.5.4) abi-to-sol: specifier: ^0.6.6 version: 0.6.6 @@ -103,11 +103,11 @@ importers: specifier: ^5.2.0 version: 5.2.0 chai: - specifier: ^4.3.10 - version: 4.4.1 + specifier: ^4.5.0 + version: 4.5.0 debug: - specifier: ^4.3.4 - version: 4.3.4(supports-color@8.1.1) + specifier: ^4.3.6 + version: 4.3.6 deep-equal-in-any-order: specifier: ^2.0.6 version: 2.0.6 @@ -118,17 +118,17 @@ importers: specifier: ^9.1.0 version: 9.1.0(eslint@8.57.0) eslint-plugin-prettier: - specifier: ^5.1.3 - version: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.2.5) + specifier: ^5.2.1 + version: 5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.3) ethers: specifier: ~5.7.2 version: 5.7.2 hardhat: specifier: ~2.20.1 - version: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) + version: 2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4) hardhat-abi-exporter: specifier: ^2.10.1 - version: 2.10.1(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)) + version: 2.10.1(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4)) hardhat-ignore-warnings: specifier: ^0.2.6 version: 0.2.11 @@ -136,29 +136,29 @@ importers: specifier: ^2.30.1 version: 2.30.1 prettier: - specifier: ^3.2.5 - version: 3.2.5 + specifier: ^3.3.3 + version: 3.3.3 prettier-plugin-solidity: specifier: ^1.3.1 - version: 1.3.1(prettier@3.2.5) + version: 1.3.1(prettier@3.3.3) solhint: - specifier: ^5.0.1 - version: 5.0.1 + specifier: ^5.0.3 + version: 5.0.3 solhint-plugin-chainlink-solidity: specifier: git+https://github.com/smartcontractkit/chainlink-solhint-rules.git#v1.2.1 version: '@chainlink/solhint-plugin-chainlink-solidity@https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c' solhint-plugin-prettier: specifier: ^0.1.0 - version: 0.1.0(prettier-plugin-solidity@1.3.1(prettier@3.2.5))(prettier@3.2.5) + version: 0.1.0(prettier-plugin-solidity@1.3.1(prettier@3.3.3))(prettier@3.3.3) ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@20.12.12)(typescript@5.4.5) + version: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) typechain: specifier: ^8.2.1 - version: 8.3.2(typescript@5.4.5) + version: 8.3.2(typescript@5.5.4) typescript: - specifier: ^5.4.5 - version: 5.4.5 + specifier: ^5.5.4 + version: 5.5.4 packages: @@ -192,11 +192,11 @@ packages: resolution: {tarball: https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c} version: 1.2.0 - '@changesets/apply-release-plan@7.0.1': - resolution: {integrity: sha512-aPdSq/R++HOyfEeBGjEe6LNG8gs0KMSyRETD/J2092OkNq8mOioAxyKjMbvVUdzgr/HTawzMOz7lfw339KnsCA==} + '@changesets/apply-release-plan@7.0.4': + resolution: {integrity: sha512-HLFwhKWayKinWAul0Vj+76jVx1Pc2v55MGPVjZ924Y/ROeSsBMFutv9heHmCUj48lJyRfOTJG5+ar+29FUky/A==} - '@changesets/assemble-release-plan@6.0.0': - resolution: {integrity: sha512-4QG7NuisAjisbW4hkLCmGW2lRYdPrKzro+fCtZaILX+3zdUELSvYjpL4GTv0E4aM9Mef3PuIQp89VmHJ4y2bfw==} + '@changesets/assemble-release-plan@6.0.3': + resolution: {integrity: sha512-bLNh9/Lgl1VwkjWZTq8JmRqH+hj7/Yzfz0jsQ/zJJ+FTmVqmqPj3szeKOri8O/hEM8JmHW019vh2gTO9iq5Cuw==} '@changesets/changelog-git@0.2.0': resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} @@ -204,24 +204,24 @@ packages: '@changesets/changelog-github@0.5.0': resolution: {integrity: sha512-zoeq2LJJVcPJcIotHRJEEA2qCqX0AQIeFE+L21L8sRLPVqDhSXY8ZWAt2sohtBpFZkBwu+LUwMSKRr2lMy3LJA==} - '@changesets/cli@2.27.3': - resolution: {integrity: sha512-ve/VpWApILlSs8cr0okNx5C2LKRawI9XZgvfmf58S8sar2nhx5DPJREFXYZBahs0FeTfvH0rdVl+nGe8QF45Ig==} + '@changesets/cli@2.27.7': + resolution: {integrity: sha512-6lr8JltiiXPIjDeYg4iM2MeePP6VN/JkmqBsVA5XRiy01hGS3y629LtSDvKcycj/w/5Eur1rEwby/MjcYS+e2A==} hasBin: true - '@changesets/config@3.0.0': - resolution: {integrity: sha512-o/rwLNnAo/+j9Yvw9mkBQOZySDYyOr/q+wptRLcAVGlU6djOeP9v1nlalbL9MFsobuBVQbZCTp+dIzdq+CLQUA==} + '@changesets/config@3.0.2': + resolution: {integrity: sha512-cdEhS4t8woKCX2M8AotcV2BOWnBp09sqICxKapgLHf9m5KdENpWjyrFNMjkLqGJtUys9U+w93OxWT0czorVDfw==} '@changesets/errors@0.2.0': resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} - '@changesets/get-dependents-graph@2.0.0': - resolution: {integrity: sha512-cafUXponivK4vBgZ3yLu944mTvam06XEn2IZGjjKc0antpenkYANXiiE6GExV/yKdsCnE8dXVZ25yGqLYZmScA==} + '@changesets/get-dependents-graph@2.1.1': + resolution: {integrity: sha512-LRFjjvigBSzfnPU2n/AhFsuWR5DK++1x47aq6qZ8dzYsPtS/I5mNhIGAS68IAxh1xjO9BTtz55FwefhANZ+FCA==} '@changesets/get-github-info@0.6.0': resolution: {integrity: sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==} - '@changesets/get-release-plan@4.0.0': - resolution: {integrity: sha512-9L9xCUeD/Tb6L/oKmpm8nyzsOzhdNBBbt/ZNcjynbHC07WW4E1eX8NMGC5g5SbM5z/V+MOrYsJ4lRW41GCbg3w==} + '@changesets/get-release-plan@4.0.3': + resolution: {integrity: sha512-6PLgvOIwTSdJPTtpdcr3sLtGatT+Jr22+cQwEBJBy6wP0rjB4yJ9lv583J9fVpn1bfQlBkDa8JxbS2g/n9lIyA==} '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} @@ -241,6 +241,9 @@ packages: '@changesets/read@0.6.0': resolution: {integrity: sha512-ZypqX8+/im1Fm98K4YcZtmLKgjs1kDQ5zHpc2U1qdtNBmZZfo/IBiG162RoP0CUF05tvp2y4IspH11PLnPxuuw==} + '@changesets/should-skip-package@0.1.0': + resolution: {integrity: sha512-FxG6Mhjw7yFStlSM7Z0Gmg3RiyQ98d/9VpQAZ3Fzr59dCOM9G6ZdYbjiSAt0XtFr9JR5U2tBaJWPjrkGGc618g==} + '@changesets/types@4.1.0': resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} @@ -503,15 +506,15 @@ packages: ethers: ^6.1.0 hardhat: ^2.0.0 - '@nomicfoundation/hardhat-network-helpers@1.0.10': - resolution: {integrity: sha512-R35/BMBlx7tWN5V6d/8/19QCwEmIdbnA4ZrsuXgvs8i2qFx5i7h6mH5pBS4Pwi4WigLH+upl6faYusrNPuzMrQ==} + '@nomicfoundation/hardhat-network-helpers@1.0.11': + resolution: {integrity: sha512-uGPL7QSKvxrHRU69dx8jzoBvuztlLCtyFsbgfXIwIjnO3dqZRz2GNMHJoO3C3dIiUNM6jdNF4AUnoQKDscdYrA==} peerDependencies: hardhat: ^2.9.5 - '@nomicfoundation/hardhat-verify@2.0.7': - resolution: {integrity: sha512-jiYHBX+K6bBN0YhwFHQ5SWWc3dQZliM3pdgpH33C7tnsVACsX1ubZn6gZ9hfwlzG0tyjFM72XQhpaXQ56cE6Ew==} + '@nomicfoundation/hardhat-verify@2.0.9': + resolution: {integrity: sha512-7kD8hu1+zlnX87gC+UN4S0HTKBnIsDfXZ/pproq1gYsK94hgCk+exvzXbwR0X2giiY/RZPkqY9oKRi0Uev91hQ==} peerDependencies: - hardhat: ^2.0.4 + hardhat: ^2.22.72.0.4 '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0': resolution: {integrity: sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw==} @@ -742,8 +745,8 @@ packages: '@types/chai-as-promised@7.1.8': resolution: {integrity: sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==} - '@types/chai@4.3.16': - resolution: {integrity: sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==} + '@types/chai@4.3.17': + resolution: {integrity: sha512-zmZ21EWzR71B4Sscphjief5djsLre50M6lI622OSySTmn9DB3j+C3kWroHfBQWXbOBwbgg/M8CG/hUxDLIloow==} '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -760,11 +763,8 @@ packages: '@types/lru-cache@5.1.1': resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==} - '@types/minimist@1.2.5': - resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - - '@types/mocha@10.0.6': - resolution: {integrity: sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==} + '@types/mocha@10.0.7': + resolution: {integrity: sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==} '@types/ms@0.7.31': resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} @@ -772,11 +772,8 @@ packages: '@types/node@12.19.16': resolution: {integrity: sha512-7xHmXm/QJ7cbK2laF+YYD7gb5MggHIIQwqyjin3bpEGiSuvScMQ5JZZXPvRipi1MwckTQbJZROMns/JxdnIL1Q==} - '@types/node@20.12.12': - resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==} - - '@types/normalize-package-data@2.4.4': - resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/node@20.14.15': + resolution: {integrity: sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==} '@types/pbkdf2@3.1.0': resolution: {integrity: sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==} @@ -796,8 +793,8 @@ packages: '@types/semver@7.5.0': resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} - '@typescript-eslint/eslint-plugin@7.10.0': - resolution: {integrity: sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==} + '@typescript-eslint/eslint-plugin@7.18.0': + resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -807,8 +804,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@7.10.0': - resolution: {integrity: sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==} + '@typescript-eslint/parser@7.18.0': + resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -817,12 +814,12 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@7.10.0': - resolution: {integrity: sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==} + '@typescript-eslint/scope-manager@7.18.0': + resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/type-utils@7.10.0': - resolution: {integrity: sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==} + '@typescript-eslint/type-utils@7.18.0': + resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -831,12 +828,12 @@ packages: typescript: optional: true - '@typescript-eslint/types@7.10.0': - resolution: {integrity: sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==} + '@typescript-eslint/types@7.18.0': + resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/typescript-estree@7.10.0': - resolution: {integrity: sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==} + '@typescript-eslint/typescript-estree@7.18.0': + resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' @@ -844,14 +841,14 @@ packages: typescript: optional: true - '@typescript-eslint/utils@7.10.0': - resolution: {integrity: sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==} + '@typescript-eslint/utils@7.18.0': + resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 - '@typescript-eslint/visitor-keys@7.10.0': - resolution: {integrity: sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==} + '@typescript-eslint/visitor-keys@7.18.0': + resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} engines: {node: ^18.18.0 || >=20.0.0} '@ungap/structured-clone@1.2.0': @@ -975,10 +972,6 @@ packages: resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} engines: {node: '>= 0.4'} - array.prototype.flat@1.3.2: - resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} - engines: {node: '>= 0.4'} - arraybuffer.prototype.slice@1.0.2: resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} engines: {node: '>= 0.4'} @@ -987,10 +980,6 @@ packages: resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} - arrify@1.0.1: - resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} - engines: {node: '>=0.10.0'} - assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} @@ -1068,9 +1057,6 @@ packages: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} - breakword@1.0.6: - resolution: {integrity: sha512-yjxDAYyK/pBvws9H4xKYpLDpYKEH6CzrBPAuXq3x18I+c/2MkVtT3qAr7Oloi6Dss9qNhPVueAAVU1CSeNDIXw==} - brorand@1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} @@ -1122,14 +1108,6 @@ packages: camel-case@3.0.0: resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==} - camelcase-keys@6.2.2: - resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} - engines: {node: '>=8'} - - camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} @@ -1151,8 +1129,8 @@ packages: peerDependencies: chai: '>= 2.1.2 < 5' - chai@4.4.1: - resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} + chai@4.5.0: + resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} engines: {node: '>=4'} chalk@2.4.2: @@ -1194,23 +1172,12 @@ packages: resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} engines: {node: '>=6'} - cliui@6.0.0: - resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} - cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - clone-response@1.0.2: resolution: {integrity: sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==} - clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - code-error-fragment@0.0.230: resolution: {integrity: sha512-cadkfKp6932H8UkhzE/gcUqhRMNf8jHzkAN7+5Myabswaghu4xABTgPHDCjW+dBAJxj/SpkTYokpzDqY4pCzQw==} engines: {node: '>= 4'} @@ -1289,19 +1256,6 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} - csv-generate@3.4.3: - resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} - - csv-parse@4.16.3: - resolution: {integrity: sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==} - - csv-stringify@5.6.5: - resolution: {integrity: sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==} - - csv@5.5.3: - resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==} - engines: {node: '>= 0.1.90'} - data-view-buffer@1.0.1: resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} engines: {node: '>= 0.4'} @@ -1326,13 +1280,14 @@ packages: supports-color: optional: true - decamelize-keys@1.1.1: - resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} - engines: {node: '>=0.10.0'} - - decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} + debug@4.3.6: + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true decamelize@4.0.0: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} @@ -1356,9 +1311,6 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - defer-to-connect@2.0.1: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} @@ -1484,8 +1436,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-plugin-prettier@5.1.3: - resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} + eslint-plugin-prettier@5.2.1: + resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' @@ -1741,6 +1693,7 @@ packages: glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} @@ -1770,10 +1723,6 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - hard-rejection@2.1.0: - resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} - engines: {node: '>=6'} - hardhat-abi-exporter@2.10.1: resolution: {integrity: sha512-X8GRxUTtebMAd2k4fcPyVnCdPa6dYK4lBsrwzKP5yiSq4i+WadWPIumaLfce53TUf/o2TnLpLOduyO1ylE2NHQ==} engines: {node: '>=14.14.0'} @@ -1832,10 +1781,6 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - hash-base@3.1.0: resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} engines: {node: '>=4'} @@ -1861,9 +1806,6 @@ packages: hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} - hosted-git-info@2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - http-cache-semantics@4.0.3: resolution: {integrity: sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew==} @@ -1958,9 +1900,6 @@ packages: resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} hasBin: true - is-core-module@2.10.0: - resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==} - is-data-view@1.0.1: resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} engines: {node: '>= 0.4'} @@ -2013,10 +1952,6 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} - is-plain-obj@1.1.0: - resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} - engines: {node: '>=0.10.0'} - is-plain-obj@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} @@ -2129,26 +2064,15 @@ packages: resolution: {integrity: sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==} engines: {node: '>=10.0.0'} - keyv@4.5.0: - resolution: {integrity: sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==} - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - klaw-sync@6.0.0: resolution: {integrity: sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==} klaw@1.3.1: resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} - kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - latest-version@7.0.0: resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} engines: {node: '>=14.16'} @@ -2238,14 +2162,6 @@ packages: make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - map-obj@1.0.1: - resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} - engines: {node: '>=0.10.0'} - - map-obj@4.3.0: - resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} - engines: {node: '>=8'} - md5.js@1.3.5: resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} @@ -2253,10 +2169,6 @@ packages: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} - meow@6.1.1: - resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} - engines: {node: '>=8'} - merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -2273,10 +2185,6 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} - min-indent@1.0.1: - resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} - engines: {node: '>=4'} - minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} @@ -2298,17 +2206,9 @@ packages: resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} engines: {node: '>=16 || 14 >=14.17'} - minimist-options@4.1.0: - resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} - engines: {node: '>= 6'} - minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - mixme@0.5.10: - resolution: {integrity: sha512-5H76ANWinB1H3twpJ6JY8uvAtpmFvHNArpilJAjXRKXSDDLPIMoZArw5SH0q9z+lLs8IrMw7Q2VWpWimFKFT1Q==} - engines: {node: '>= 8.0.0'} - mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} @@ -2325,6 +2225,10 @@ packages: moment@2.30.1: resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -2376,9 +2280,6 @@ packages: resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} engines: {node: '>=12.19'} - normalize-package-data@2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} - normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -2585,8 +2486,8 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - prettier@3.2.5: - resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} hasBin: true @@ -2609,10 +2510,6 @@ packages: pure-rand@5.0.3: resolution: {integrity: sha512-9N8x1h8dptBQpHyC7aZMS+iNOAm97WMGY0AFrguU1cpfW3I5jINkWe5BIY5md0ofy+1TCIELsVcm/GJXZSaPbw==} - quick-lru@4.0.1: - resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} - engines: {node: '>=8'} - quick-lru@5.1.1: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} @@ -2628,14 +2525,6 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - read-pkg-up@7.0.1: - resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} - engines: {node: '>=8'} - - read-pkg@5.2.0: - resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} - engines: {node: '>=8'} - read-yaml-file@1.1.0: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} @@ -2648,10 +2537,6 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} - redent@3.0.0: - resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} - engines: {node: '>=8'} - reduce-flatten@2.0.0: resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} engines: {node: '>=6'} @@ -2683,9 +2568,6 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - require-main-filename@2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} @@ -2700,10 +2582,6 @@ packages: resolve@1.17.0: resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} - resolve@1.22.1: - resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} - hasBin: true - responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} @@ -2778,8 +2656,8 @@ packages: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} hasBin: true - semver@7.6.2: - resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true @@ -2789,9 +2667,6 @@ packages: serialize-javascript@6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} - set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - set-function-length@1.1.1: resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} engines: {node: '>= 0.4'} @@ -2851,11 +2726,6 @@ packages: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} - smartwrap@2.0.2: - resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} - engines: {node: '>=6'} - hasBin: true - snake-case@2.1.0: resolution: {integrity: sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==} @@ -2870,8 +2740,8 @@ packages: prettier: ^3.0.0 prettier-plugin-solidity: ^1.0.0 - solhint@5.0.1: - resolution: {integrity: sha512-QeQLS9HGCnIiibt+xiOa/+MuP7BWz9N7C5+Mj9pLHshdkNhuo3AzCpWmjfWVZBUuwIUO3YyCRVIcYLR3YOKGfg==} + solhint@5.0.3: + resolution: {integrity: sha512-OLCH6qm/mZTCpplTXzXTJGId1zrtNuDYP5c2e6snIv/hdRVxPfBBz/bAlL91bY/Accavkayp2Zp2BaDSrLVXTQ==} hasBin: true solidity-ast@0.4.56: @@ -2957,18 +2827,6 @@ packages: spawndamnit@2.0.0: resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} - spdx-correct@3.1.1: - resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} - - spdx-exceptions@2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} - - spdx-expression-parse@3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - - spdx-license-ids@3.0.12: - resolution: {integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==} - sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -2980,9 +2838,6 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - stream-transform@2.1.3: - resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} - string-format@2.0.0: resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} @@ -3026,10 +2881,6 @@ packages: resolution: {integrity: sha1-DF8VX+8RUTczd96du1iNoFUA428=} engines: {node: '>=6.5.0', npm: '>=3'} - strip-indent@3.0.0: - resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} - engines: {node: '>=8'} - strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} @@ -3050,15 +2901,11 @@ packages: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - swap-case@1.1.2: resolution: {integrity: sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==} - synckit@0.8.8: - resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} + synckit@0.9.1: + resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==} engines: {node: ^14.18.0 || >=16.0.0} table-layout@1.0.2: @@ -3094,10 +2941,6 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - trim-newlines@3.0.1: - resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} - engines: {node: '>=8'} - ts-api-utils@1.3.0: resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} engines: {node: '>=16'} @@ -3136,11 +2979,6 @@ packages: tsort@0.0.1: resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} - tty-table@4.2.3: - resolution: {integrity: sha512-Fs15mu0vGzCrj8fmJNP7Ynxt5J7praPXqFN0leZeZBXJwkMxv9cb2D454k1ltrtUSJbZ4yH4e0CynsHLxmUfFA==} - engines: {node: '>=8.0.0'} - hasBin: true - tweetnacl-util@0.15.1: resolution: {integrity: sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==} @@ -3155,9 +2993,9 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} - type-fest@0.13.1: - resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} - engines: {node: '>=10'} + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} @@ -3167,18 +3005,10 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - type-fest@0.6.0: - resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} - engines: {node: '>=8'} - type-fest@0.7.1: resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} engines: {node: '>=8'} - type-fest@0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} - typechain@8.3.2: resolution: {integrity: sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==} hasBin: true @@ -3216,8 +3046,8 @@ packages: resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} engines: {node: '>= 0.4'} - typescript@5.4.5: - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} engines: {node: '>=14.17'} hasBin: true @@ -3273,12 +3103,6 @@ packages: v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - validate-npm-package-license@3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - web3-utils@1.7.4: resolution: {integrity: sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==} engines: {node: '>=8.0.0'} @@ -3292,9 +3116,6 @@ packages: which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - which-module@2.0.0: - resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} - which-pm@2.0.0: resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==} engines: {node: '>=8.15'} @@ -3327,10 +3148,6 @@ packages: workerpool@6.2.1: resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -3362,9 +3179,6 @@ packages: utf-8-validate: optional: true - y18n@4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} - y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -3376,34 +3190,18 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yargs-parser@18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} - engines: {node: '>=6'} - yargs-parser@20.2.4: resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} engines: {node: '>=10'} - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - yargs-unparser@2.0.0: resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} engines: {node: '>=10'} - yargs@15.4.1: - resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} - engines: {node: '>=8'} - yargs@16.2.0: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} @@ -3452,12 +3250,13 @@ snapshots: '@chainlink/solhint-plugin-chainlink-solidity@https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c': {} - '@changesets/apply-release-plan@7.0.1': + '@changesets/apply-release-plan@7.0.4': dependencies: '@babel/runtime': 7.24.0 - '@changesets/config': 3.0.0 + '@changesets/config': 3.0.2 '@changesets/get-version-range-type': 0.4.0 '@changesets/git': 3.0.0 + '@changesets/should-skip-package': 0.1.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 detect-indent: 6.1.0 @@ -3466,16 +3265,17 @@ snapshots: outdent: 0.5.0 prettier: 2.8.8 resolve-from: 5.0.0 - semver: 7.6.2 + semver: 7.6.3 - '@changesets/assemble-release-plan@6.0.0': + '@changesets/assemble-release-plan@6.0.3': dependencies: '@babel/runtime': 7.24.0 '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.0.0 + '@changesets/get-dependents-graph': 2.1.1 + '@changesets/should-skip-package': 0.1.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 - semver: 7.6.2 + semver: 7.6.3 '@changesets/changelog-git@0.2.0': dependencies: @@ -3489,20 +3289,21 @@ snapshots: transitivePeerDependencies: - encoding - '@changesets/cli@2.27.3': + '@changesets/cli@2.27.7': dependencies: '@babel/runtime': 7.24.0 - '@changesets/apply-release-plan': 7.0.1 - '@changesets/assemble-release-plan': 6.0.0 + '@changesets/apply-release-plan': 7.0.4 + '@changesets/assemble-release-plan': 6.0.3 '@changesets/changelog-git': 0.2.0 - '@changesets/config': 3.0.0 + '@changesets/config': 3.0.2 '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.0.0 - '@changesets/get-release-plan': 4.0.0 + '@changesets/get-dependents-graph': 2.1.1 + '@changesets/get-release-plan': 4.0.3 '@changesets/git': 3.0.0 '@changesets/logger': 0.1.0 '@changesets/pre': 2.0.0 '@changesets/read': 0.6.0 + '@changesets/should-skip-package': 0.1.0 '@changesets/types': 6.0.0 '@changesets/write': 0.3.1 '@manypkg/get-packages': 1.1.3 @@ -3514,20 +3315,19 @@ snapshots: external-editor: 3.1.0 fs-extra: 7.0.1 human-id: 1.0.2 - meow: 6.1.1 + mri: 1.2.0 outdent: 0.5.0 p-limit: 2.3.0 preferred-pm: 3.1.3 resolve-from: 5.0.0 - semver: 7.6.2 + semver: 7.6.3 spawndamnit: 2.0.0 term-size: 2.2.1 - tty-table: 4.2.3 - '@changesets/config@3.0.0': + '@changesets/config@3.0.2': dependencies: '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.0.0 + '@changesets/get-dependents-graph': 2.1.1 '@changesets/logger': 0.1.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 @@ -3538,13 +3338,13 @@ snapshots: dependencies: extendable-error: 0.1.7 - '@changesets/get-dependents-graph@2.0.0': + '@changesets/get-dependents-graph@2.1.1': dependencies: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 chalk: 2.4.2 fs-extra: 7.0.1 - semver: 7.6.2 + semver: 7.6.3 '@changesets/get-github-info@0.6.0': dependencies: @@ -3553,11 +3353,11 @@ snapshots: transitivePeerDependencies: - encoding - '@changesets/get-release-plan@4.0.0': + '@changesets/get-release-plan@4.0.3': dependencies: '@babel/runtime': 7.24.0 - '@changesets/assemble-release-plan': 6.0.0 - '@changesets/config': 3.0.0 + '@changesets/assemble-release-plan': 6.0.3 + '@changesets/config': 3.0.2 '@changesets/pre': 2.0.0 '@changesets/read': 0.6.0 '@changesets/types': 6.0.0 @@ -3603,6 +3403,12 @@ snapshots: fs-extra: 7.0.1 p-filter: 2.1.0 + '@changesets/should-skip-package@0.1.0': + dependencies: + '@babel/runtime': 7.24.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + '@changesets/types@4.1.0': {} '@changesets/types@6.0.0': {} @@ -3629,7 +3435,7 @@ snapshots: '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 espree: 9.6.1 globals: 13.24.0 ignore: 5.3.1 @@ -3669,7 +3475,7 @@ snapshots: '@ethersproject/transactions': 5.7.0 '@ethersproject/web': 5.7.1 bufio: 1.0.7 - chai: 4.4.1 + chai: 4.5.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -3942,7 +3748,7 @@ snapshots: '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -4020,7 +3826,7 @@ snapshots: '@nomicfoundation/ethereumjs-trie': 6.0.4 '@nomicfoundation/ethereumjs-tx': 5.0.4 '@nomicfoundation/ethereumjs-util': 9.0.4 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 ethereum-cryptography: 0.1.3 lru-cache: 10.2.2 transitivePeerDependencies: @@ -4050,7 +3856,7 @@ snapshots: '@nomicfoundation/ethereumjs-tx': 5.0.4 '@nomicfoundation/ethereumjs-util': 9.0.4 '@types/debug': 4.1.12 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 ethereum-cryptography: 0.1.3 rustbn-wasm: 0.2.0 transitivePeerDependencies: @@ -4066,7 +3872,7 @@ snapshots: '@nomicfoundation/ethereumjs-rlp': 5.0.4 '@nomicfoundation/ethereumjs-trie': 6.0.4 '@nomicfoundation/ethereumjs-util': 9.0.4 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 ethereum-cryptography: 0.1.3 js-sdsl: 4.4.2 lru-cache: 10.2.2 @@ -4119,47 +3925,47 @@ snapshots: '@nomicfoundation/ethereumjs-trie': 6.0.4 '@nomicfoundation/ethereumjs-tx': 5.0.4 '@nomicfoundation/ethereumjs-util': 9.0.4 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 ethereum-cryptography: 0.1.3 transitivePeerDependencies: - '@nomicfoundation/ethereumjs-verkle' - c-kzg - supports-color - '@nomicfoundation/hardhat-chai-matchers@1.0.6(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)))(chai@4.4.1)(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))': + '@nomicfoundation/hardhat-chai-matchers@1.0.6(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4)))(chai@4.5.0)(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4))': dependencies: '@ethersproject/abi': 5.7.0 - '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)) + '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4)) '@types/chai-as-promised': 7.1.8 - chai: 4.4.1 - chai-as-promised: 7.1.1(chai@4.4.1) + chai: 4.5.0 + chai-as-promised: 7.1.1(chai@4.5.0) deep-eql: 4.1.3 ethers: 5.7.2 - hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4) ordinal: 1.0.3 - '@nomicfoundation/hardhat-ethers@3.0.6(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))': + '@nomicfoundation/hardhat-ethers@3.0.6(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4))': dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 ethers: 5.7.2 - hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4) lodash.isequal: 4.5.0 transitivePeerDependencies: - supports-color - '@nomicfoundation/hardhat-network-helpers@1.0.10(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))': + '@nomicfoundation/hardhat-network-helpers@1.0.11(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4))': dependencies: ethereumjs-util: 7.1.5 - hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4) - '@nomicfoundation/hardhat-verify@2.0.7(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))': + '@nomicfoundation/hardhat-verify@2.0.9(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4))': dependencies: '@ethersproject/abi': 5.7.0 '@ethersproject/address': 5.7.0 cbor: 8.1.0 chalk: 2.4.2 - debug: 4.3.4(supports-color@8.1.1) - hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) + debug: 4.3.6 + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4) lodash.clonedeep: 4.5.0 semver: 6.3.0 table: 6.8.1 @@ -4210,10 +4016,10 @@ snapshots: '@nomicfoundation/solidity-analyzer-win32-ia32-msvc': 0.1.0 '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.0 - '@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))': + '@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4))': dependencies: ethers: 5.7.2 - hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4) '@offchainlabs/upgrade-executor@1.1.0-beta.0': dependencies: @@ -4241,7 +4047,7 @@ snapshots: cbor: 9.0.2 chalk: 4.1.2 compare-versions: 6.1.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 ethereumjs-util: 7.1.5 minimist: 1.2.8 proper-lockfile: 4.1.2 @@ -4264,9 +4070,9 @@ snapshots: '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 - '@prettier/sync@0.3.0(prettier@3.2.5)': + '@prettier/sync@0.3.0(prettier@3.3.3)': dependencies: - prettier: 3.2.5 + prettier: 3.3.3 '@scroll-tech/contracts@0.1.0': {} @@ -4351,7 +4157,7 @@ snapshots: '@truffle/contract-schema@3.4.10': dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 transitivePeerDependencies: - supports-color @@ -4363,51 +4169,51 @@ snapshots: '@tsconfig/node16@1.0.3': {} - '@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.4.5))(typescript@5.4.5)': + '@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.5.4))(typescript@5.5.4)': dependencies: '@ethersproject/abi': 5.7.0 '@ethersproject/bytes': 5.7.0 '@ethersproject/providers': 5.7.2 ethers: 5.7.2 lodash: 4.17.21 - ts-essentials: 7.0.3(typescript@5.4.5) - typechain: 8.3.2(typescript@5.4.5) - typescript: 5.4.5 + ts-essentials: 7.0.3(typescript@5.5.4) + typechain: 8.3.2(typescript@5.5.4) + typescript: 5.5.4 - '@typechain/hardhat@7.0.0(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.4.5))(typescript@5.4.5))(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5))(typechain@8.3.2(typescript@5.4.5))': + '@typechain/hardhat@7.0.0(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.5.4))(typescript@5.5.4))(ethers@5.7.2)(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4))(typechain@8.3.2(typescript@5.5.4))': dependencies: '@ethersproject/abi': 5.7.0 '@ethersproject/providers': 5.7.2 - '@typechain/ethers-v5': 7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.4.5))(typescript@5.4.5) + '@typechain/ethers-v5': 7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.2(typescript@5.5.4))(typescript@5.5.4) ethers: 5.7.2 fs-extra: 9.1.0 - hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) - typechain: 8.3.2(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4) + typechain: 8.3.2(typescript@5.5.4) '@types/bn.js@4.11.6': dependencies: - '@types/node': 20.12.12 + '@types/node': 20.14.15 '@types/bn.js@5.1.1': dependencies: - '@types/node': 20.12.12 + '@types/node': 20.14.15 '@types/cacheable-request@6.0.2': dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.4 - '@types/node': 20.12.12 + '@types/node': 20.14.15 '@types/responselike': 1.0.0 '@types/cbor@5.0.1': dependencies: - '@types/node': 20.12.12 + '@types/node': 20.14.15 '@types/chai-as-promised@7.1.8': dependencies: - '@types/chai': 4.3.16 + '@types/chai': 4.3.17 - '@types/chai@4.3.16': {} + '@types/chai@4.3.17': {} '@types/debug@4.1.12': dependencies: @@ -4419,124 +4225,120 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 20.12.12 + '@types/node': 20.14.15 '@types/lru-cache@5.1.1': {} - '@types/minimist@1.2.5': {} - - '@types/mocha@10.0.6': {} + '@types/mocha@10.0.7': {} '@types/ms@0.7.31': {} '@types/node@12.19.16': {} - '@types/node@20.12.12': + '@types/node@20.14.15': dependencies: undici-types: 5.26.5 - '@types/normalize-package-data@2.4.4': {} - '@types/pbkdf2@3.1.0': dependencies: - '@types/node': 20.12.12 + '@types/node': 20.14.15 '@types/prettier@2.7.1': {} '@types/readable-stream@2.3.15': dependencies: - '@types/node': 20.12.12 + '@types/node': 20.14.15 safe-buffer: 5.1.2 '@types/responselike@1.0.0': dependencies: - '@types/node': 20.12.12 + '@types/node': 20.14.15 '@types/secp256k1@4.0.3': dependencies: - '@types/node': 20.12.12 + '@types/node': 20.14.15 '@types/semver@7.5.0': {} - '@typescript-eslint/eslint-plugin@7.10.0(@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.10.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/scope-manager': 7.10.0 - '@typescript-eslint/type-utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.10.0 + '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 7.18.0 eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: - '@typescript-eslint/scope-manager': 7.10.0 - '@typescript-eslint/types': 7.10.0 - '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.10.0 - debug: 4.3.4(supports-color@8.1.1) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.3.6 eslint: 8.57.0 optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@7.10.0': + '@typescript-eslint/scope-manager@7.18.0': dependencies: - '@typescript-eslint/types': 7.10.0 - '@typescript-eslint/visitor-keys': 7.10.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 - '@typescript-eslint/type-utils@7.10.0(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: - '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) - '@typescript-eslint/utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) - debug: 4.3.4(supports-color@8.1.1) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + debug: 4.3.6 eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@7.10.0': {} + '@typescript-eslint/types@7.18.0': {} - '@typescript-eslint/typescript-estree@7.10.0(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.5.4)': dependencies: - '@typescript-eslint/types': 7.10.0 - '@typescript-eslint/visitor-keys': 7.10.0 - debug: 4.3.4(supports-color@8.1.1) + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.3.6 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.4 - semver: 7.6.2 - ts-api-utils: 1.3.0(typescript@5.4.5) + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.10.0(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@typescript-eslint/scope-manager': 7.10.0 - '@typescript-eslint/types': 7.10.0 - '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) eslint: 8.57.0 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@7.10.0': + '@typescript-eslint/visitor-keys@7.18.0': dependencies: - '@typescript-eslint/types': 7.10.0 + '@typescript-eslint/types': 7.18.0 eslint-visitor-keys: 3.4.3 '@ungap/structured-clone@1.2.0': {} @@ -4550,7 +4352,7 @@ snapshots: ajv: 6.12.6 better-ajv-errors: 0.8.2(ajv@6.12.6) neodoc: 2.0.2 - semver: 7.6.2 + semver: 7.6.3 source-map-support: 0.5.21 optionalDependencies: prettier: 2.8.8 @@ -4574,7 +4376,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 transitivePeerDependencies: - supports-color @@ -4644,6 +4446,7 @@ snapshots: dependencies: call-bind: 1.0.5 is-array-buffer: 3.0.2 + optional: true array-buffer-byte-length@1.0.1: dependencies: @@ -4663,13 +4466,6 @@ snapshots: es-shim-unscopables: 1.0.2 optional: true - array.prototype.flat@1.3.2: - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - es-shim-unscopables: 1.0.2 - arraybuffer.prototype.slice@1.0.2: dependencies: array-buffer-byte-length: 1.0.0 @@ -4679,6 +4475,7 @@ snapshots: get-intrinsic: 1.2.2 is-array-buffer: 3.0.2 is-shared-array-buffer: 1.0.2 + optional: true arraybuffer.prototype.slice@1.0.3: dependencies: @@ -4692,8 +4489,6 @@ snapshots: is-shared-array-buffer: 1.0.3 optional: true - arrify@1.0.1: {} - assertion-error@1.1.0: {} ast-parents@0.0.1: {} @@ -4702,7 +4497,8 @@ snapshots: at-least-node@1.0.0: {} - available-typed-arrays@1.0.5: {} + available-typed-arrays@1.0.5: + optional: true available-typed-arrays@1.0.7: dependencies: @@ -4770,10 +4566,6 @@ snapshots: dependencies: fill-range: 7.0.1 - breakword@1.0.6: - dependencies: - wcwidth: 1.0.1 - brorand@1.1.0: {} browser-stdout@1.3.1: {} @@ -4812,7 +4604,7 @@ snapshots: clone-response: 1.0.2 get-stream: 5.1.0 http-cache-semantics: 4.0.3 - keyv: 4.5.0 + keyv: 4.5.4 lowercase-keys: 2.0.0 normalize-url: 6.1.0 responselike: 2.0.1 @@ -4822,6 +4614,7 @@ snapshots: function-bind: 1.1.2 get-intrinsic: 1.2.2 set-function-length: 1.1.1 + optional: true call-bind@1.0.7: dependencies: @@ -4839,14 +4632,6 @@ snapshots: no-case: 2.3.2 upper-case: 1.1.3 - camelcase-keys@6.2.2: - dependencies: - camelcase: 5.3.1 - map-obj: 4.3.0 - quick-lru: 4.0.1 - - camelcase@5.3.1: {} - camelcase@6.3.0: {} cbor@5.2.0: @@ -4863,12 +4648,12 @@ snapshots: nofilter: 3.1.0 optional: true - chai-as-promised@7.1.1(chai@4.4.1): + chai-as-promised@7.1.1(chai@4.5.0): dependencies: - chai: 4.4.1 + chai: 4.5.0 check-error: 1.0.3 - chai@4.4.1: + chai@4.5.0: dependencies: assertion-error: 1.1.0 check-error: 1.0.3 @@ -4876,7 +4661,7 @@ snapshots: get-func-name: 2.0.2 loupe: 2.3.7 pathval: 1.1.1 - type-detect: 4.0.8 + type-detect: 4.1.0 chalk@2.4.2: dependencies: @@ -4941,30 +4726,16 @@ snapshots: cli-boxes@2.2.1: {} - cliui@6.0.0: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 - cliui@7.0.4: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - clone-response@1.0.2: dependencies: mimic-response: 1.0.1 - clone@1.0.4: {} - code-error-fragment@0.0.230: {} color-convert@1.9.3: @@ -5064,19 +4835,6 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - csv-generate@3.4.3: {} - - csv-parse@4.16.3: {} - - csv-stringify@5.6.5: {} - - csv@5.5.3: - dependencies: - csv-generate: 3.4.3 - csv-parse: 4.16.3 - csv-stringify: 5.6.5 - stream-transform: 2.1.3 - data-view-buffer@1.0.1: dependencies: call-bind: 1.0.7 @@ -5106,12 +4864,9 @@ snapshots: optionalDependencies: supports-color: 8.1.1 - decamelize-keys@1.1.1: + debug@4.3.6: dependencies: - decamelize: 1.2.0 - map-obj: 1.0.1 - - decamelize@1.2.0: {} + ms: 2.1.2 decamelize@4.0.0: {} @@ -5132,10 +4887,6 @@ snapshots: deep-is@0.1.4: {} - defaults@1.0.4: - dependencies: - clone: 1.0.4 - defer-to-connect@2.0.1: {} define-data-property@1.1.1: @@ -5143,6 +4894,7 @@ snapshots: get-intrinsic: 1.2.2 gopd: 1.0.1 has-property-descriptors: 1.0.0 + optional: true define-data-property@1.1.4: dependencies: @@ -5156,6 +4908,7 @@ snapshots: define-data-property: 1.1.1 has-property-descriptors: 1.0.0 object-keys: 1.1.1 + optional: true delete-empty@3.0.0: dependencies: @@ -5253,6 +5006,7 @@ snapshots: typed-array-length: 1.0.4 unbox-primitive: 1.0.2 which-typed-array: 1.1.13 + optional: true es-abstract@1.23.3: dependencies: @@ -5322,6 +5076,7 @@ snapshots: get-intrinsic: 1.2.2 has-tostringtag: 1.0.0 hasown: 2.0.0 + optional: true es-set-tostringtag@2.0.3: dependencies: @@ -5333,12 +5088,14 @@ snapshots: es-shim-unscopables@1.0.2: dependencies: hasown: 2.0.0 + optional: true es-to-primitive@1.2.1: dependencies: is-callable: 1.2.7 is-date-object: 1.0.2 is-symbol: 1.0.3 + optional: true escalade@3.1.1: {} @@ -5350,12 +5107,12 @@ snapshots: dependencies: eslint: 8.57.0 - eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.2.5): + eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.3): dependencies: eslint: 8.57.0 - prettier: 3.2.5 + prettier: 3.3.3 prettier-linter-helpers: 1.0.0 - synckit: 0.8.8 + synckit: 0.9.1 optionalDependencies: eslint-config-prettier: 9.1.0(eslint@8.57.0) @@ -5379,7 +5136,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -5609,13 +5366,14 @@ snapshots: flatted@3.3.1: {} - follow-redirects@1.15.6(debug@4.3.4): + follow-redirects@1.15.6(debug@4.3.6): optionalDependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 for-each@0.3.3: dependencies: is-callable: 1.2.7 + optional: true form-data-encoder@1.7.1: {} @@ -5653,7 +5411,8 @@ snapshots: fsevents@2.3.2: optional: true - function-bind@1.1.2: {} + function-bind@1.1.2: + optional: true function.prototype.name@1.1.6: dependencies: @@ -5661,8 +5420,10 @@ snapshots: define-properties: 1.2.1 es-abstract: 1.22.3 functions-have-names: 1.2.3 + optional: true - functions-have-names@1.2.3: {} + functions-have-names@1.2.3: + optional: true get-caller-file@2.0.5: {} @@ -5674,6 +5435,7 @@ snapshots: has-proto: 1.0.1 has-symbols: 1.0.3 hasown: 2.0.0 + optional: true get-intrinsic@1.2.4: dependencies: @@ -5694,6 +5456,7 @@ snapshots: dependencies: call-bind: 1.0.5 get-intrinsic: 1.2.2 + optional: true get-symbol-description@1.0.2: dependencies: @@ -5752,6 +5515,7 @@ snapshots: globalthis@1.0.3: dependencies: define-properties: 1.2.1 + optional: true globby@11.1.0: dependencies: @@ -5765,6 +5529,7 @@ snapshots: gopd@1.0.1: dependencies: get-intrinsic: 1.2.2 + optional: true got@12.1.0: dependencies: @@ -5788,13 +5553,11 @@ snapshots: graphemer@1.4.0: {} - hard-rejection@2.1.0: {} - - hardhat-abi-exporter@2.10.1(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5)): + hardhat-abi-exporter@2.10.1(hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4)): dependencies: '@ethersproject/abi': 5.7.0 delete-empty: 3.0.0 - hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5) + hardhat: 2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4) hardhat-ignore-warnings@0.2.11: dependencies: @@ -5802,7 +5565,7 @@ snapshots: node-interval-tree: 2.1.2 solidity-comments: 0.0.2 - hardhat@2.20.1(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5))(typescript@5.4.5): + hardhat@2.20.1(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))(typescript@5.5.4): dependencies: '@ethersproject/abi': 5.7.0 '@metamask/eth-sig-util': 4.0.1 @@ -5828,7 +5591,7 @@ snapshots: chalk: 2.4.2 chokidar: 3.5.3 ci-info: 2.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 enquirer: 2.3.6 env-paths: 2.2.1 ethereum-cryptography: 1.1.2 @@ -5847,7 +5610,7 @@ snapshots: raw-body: 2.5.1 resolve: 1.17.0 semver: 6.3.0 - solc: 0.7.3(debug@4.3.4) + solc: 0.7.3(debug@4.3.6) source-map-support: 0.5.21 stacktrace-parser: 0.1.10 tsort: 0.0.1 @@ -5855,15 +5618,16 @@ snapshots: uuid: 8.3.2 ws: 7.5.9 optionalDependencies: - ts-node: 10.9.2(@types/node@20.12.12)(typescript@5.4.5) - typescript: 5.4.5 + ts-node: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) + typescript: 5.5.4 transitivePeerDependencies: - bufferutil - c-kzg - supports-color - utf-8-validate - has-bigints@1.0.2: {} + has-bigints@1.0.2: + optional: true has-flag@3.0.0: {} @@ -5872,32 +5636,32 @@ snapshots: has-property-descriptors@1.0.0: dependencies: get-intrinsic: 1.2.2 + optional: true has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.0 optional: true - has-proto@1.0.1: {} + has-proto@1.0.1: + optional: true has-proto@1.0.3: optional: true - has-symbols@1.0.3: {} + has-symbols@1.0.3: + optional: true has-tostringtag@1.0.0: dependencies: has-symbols: 1.0.3 + optional: true has-tostringtag@1.0.2: dependencies: has-symbols: 1.0.3 optional: true - has@1.0.3: - dependencies: - function-bind: 1.1.2 - hash-base@3.1.0: dependencies: inherits: 2.0.4 @@ -5912,6 +5676,7 @@ snapshots: hasown@2.0.0: dependencies: function-bind: 1.1.2 + optional: true hasown@2.0.2: dependencies: @@ -5931,8 +5696,6 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - hosted-git-info@2.8.9: {} - http-cache-semantics@4.0.3: {} http-errors@2.0.0: @@ -5951,7 +5714,7 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 transitivePeerDependencies: - supports-color @@ -5990,6 +5753,7 @@ snapshots: get-intrinsic: 1.2.2 hasown: 2.0.0 side-channel: 1.0.4 + optional: true internal-slot@1.0.7: dependencies: @@ -6007,6 +5771,7 @@ snapshots: call-bind: 1.0.5 get-intrinsic: 1.2.2 is-typed-array: 1.1.12 + optional: true is-array-buffer@3.0.4: dependencies: @@ -6019,6 +5784,7 @@ snapshots: is-bigint@1.0.4: dependencies: has-bigints: 1.0.2 + optional: true is-binary-path@2.1.0: dependencies: @@ -6028,23 +5794,22 @@ snapshots: dependencies: call-bind: 1.0.5 has-tostringtag: 1.0.0 + optional: true - is-callable@1.2.7: {} + is-callable@1.2.7: + optional: true is-ci@2.0.0: dependencies: ci-info: 2.0.0 - is-core-module@2.10.0: - dependencies: - has: 1.0.3 - is-data-view@1.0.1: dependencies: is-typed-array: 1.1.13 optional: true - is-date-object@1.0.2: {} + is-date-object@1.0.2: + optional: true is-docker@2.2.1: {} @@ -6062,7 +5827,8 @@ snapshots: dependencies: lower-case: 1.1.4 - is-negative-zero@2.0.2: {} + is-negative-zero@2.0.2: + optional: true is-negative-zero@2.0.3: optional: true @@ -6070,23 +5836,24 @@ snapshots: is-number-object@1.0.7: dependencies: has-tostringtag: 1.0.0 + optional: true is-number@7.0.0: {} is-path-inside@3.0.3: {} - is-plain-obj@1.1.0: {} - is-plain-obj@2.1.0: {} is-regex@1.1.4: dependencies: call-bind: 1.0.5 has-tostringtag: 1.0.0 + optional: true is-shared-array-buffer@1.0.2: dependencies: call-bind: 1.0.5 + optional: true is-shared-array-buffer@1.0.3: dependencies: @@ -6096,6 +5863,7 @@ snapshots: is-string@1.0.7: dependencies: has-tostringtag: 1.0.0 + optional: true is-subdir@1.2.0: dependencies: @@ -6104,10 +5872,12 @@ snapshots: is-symbol@1.0.3: dependencies: has-symbols: 1.0.3 + optional: true is-typed-array@1.1.12: dependencies: which-typed-array: 1.1.13 + optional: true is-typed-array@1.1.13: dependencies: @@ -6123,6 +5893,7 @@ snapshots: is-weakref@1.0.2: dependencies: call-bind: 1.0.5 + optional: true is-windows@1.0.2: {} @@ -6130,7 +5901,8 @@ snapshots: dependencies: is-docker: 2.2.1 - isarray@2.0.5: {} + isarray@2.0.5: + optional: true isexe@2.0.0: {} @@ -6186,16 +5958,10 @@ snapshots: node-gyp-build: 4.5.0 readable-stream: 3.6.0 - keyv@4.5.0: - dependencies: - json-buffer: 3.0.1 - keyv@4.5.4: dependencies: json-buffer: 3.0.1 - kind-of@6.0.3: {} - klaw-sync@6.0.0: dependencies: graceful-fs: 4.2.10 @@ -6204,8 +5970,6 @@ snapshots: optionalDependencies: graceful-fs: 4.2.10 - kleur@4.1.5: {} - latest-version@7.0.0: dependencies: package-json: 8.1.1 @@ -6285,10 +6049,6 @@ snapshots: make-error@1.3.6: {} - map-obj@1.0.1: {} - - map-obj@4.3.0: {} - md5.js@1.3.5: dependencies: hash-base: 3.1.0 @@ -6297,20 +6057,6 @@ snapshots: memorystream@0.3.1: {} - meow@6.1.1: - dependencies: - '@types/minimist': 1.2.5 - camelcase-keys: 6.2.2 - decamelize-keys: 1.1.1 - hard-rejection: 2.1.0 - minimist-options: 4.1.0 - normalize-package-data: 2.5.0 - read-pkg-up: 7.0.1 - redent: 3.0.0 - trim-newlines: 3.0.1 - type-fest: 0.13.1 - yargs-parser: 18.1.3 - merge2@1.4.1: {} micromatch@4.0.5: @@ -6322,8 +6068,6 @@ snapshots: mimic-response@3.1.0: {} - min-indent@1.0.1: {} - minimalistic-assert@1.0.1: {} minimalistic-crypto-utils@1.0.1: {} @@ -6344,16 +6088,8 @@ snapshots: dependencies: brace-expansion: 2.0.1 - minimist-options@4.1.0: - dependencies: - arrify: 1.0.1 - is-plain-obj: 1.1.0 - kind-of: 6.0.3 - minimist@1.2.8: {} - mixme@0.5.10: {} - mkdirp@1.0.4: {} mnemonist@0.38.5: @@ -6386,6 +6122,8 @@ snapshots: moment@2.30.1: {} + mri@1.2.0: {} + ms@2.1.2: {} ms@2.1.3: {} @@ -6420,13 +6158,6 @@ snapshots: nofilter@3.1.0: {} - normalize-package-data@2.5.0: - dependencies: - hosted-git-info: 2.8.9 - resolve: 1.22.1 - semver: 5.7.1 - validate-npm-package-license: 3.0.4 - normalize-path@3.0.0: {} normalize-url@6.1.0: {} @@ -6436,9 +6167,11 @@ snapshots: bn.js: 4.11.6 strip-hex-prefix: 1.0.0 - object-inspect@1.13.1: {} + object-inspect@1.13.1: + optional: true - object-keys@1.1.1: {} + object-keys@1.1.1: + optional: true object.assign@4.1.4: dependencies: @@ -6446,6 +6179,7 @@ snapshots: define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 + optional: true object.assign@4.1.5: dependencies: @@ -6526,7 +6260,7 @@ snapshots: got: 12.1.0 registry-auth-token: 5.0.2 registry-url: 6.0.1 - semver: 7.6.2 + semver: 7.6.3 param-case@2.1.1: dependencies: @@ -6625,20 +6359,20 @@ snapshots: dependencies: '@solidity-parser/parser': 0.17.0 prettier: 2.8.8 - semver: 7.6.2 + semver: 7.6.3 solidity-comments-extractor: 0.0.8 optional: true - prettier-plugin-solidity@1.3.1(prettier@3.2.5): + prettier-plugin-solidity@1.3.1(prettier@3.3.3): dependencies: '@solidity-parser/parser': 0.17.0 - prettier: 3.2.5 - semver: 7.6.2 + prettier: 3.3.3 + semver: 7.6.3 solidity-comments-extractor: 0.0.8 prettier@2.8.8: {} - prettier@3.2.5: {} + prettier@3.3.3: {} proper-lockfile@4.1.2: dependencies: @@ -6660,8 +6394,6 @@ snapshots: pure-rand@5.0.3: {} - quick-lru@4.0.1: {} - quick-lru@5.1.1: {} randombytes@2.1.0: @@ -6682,19 +6414,6 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - read-pkg-up@7.0.1: - dependencies: - find-up: 4.1.0 - read-pkg: 5.2.0 - type-fest: 0.8.1 - - read-pkg@5.2.0: - dependencies: - '@types/normalize-package-data': 2.4.4 - normalize-package-data: 2.5.0 - parse-json: 5.2.0 - type-fest: 0.6.0 - read-yaml-file@1.1.0: dependencies: graceful-fs: 4.2.10 @@ -6712,11 +6431,6 @@ snapshots: dependencies: picomatch: 2.3.1 - redent@3.0.0: - dependencies: - indent-string: 4.0.0 - strip-indent: 3.0.0 - reduce-flatten@2.0.0: {} regenerator-runtime@0.14.1: {} @@ -6726,6 +6440,7 @@ snapshots: call-bind: 1.0.5 define-properties: 1.2.1 set-function-name: 2.0.1 + optional: true regexp.prototype.flags@1.5.2: dependencies: @@ -6747,8 +6462,6 @@ snapshots: require-from-string@2.0.2: {} - require-main-filename@2.0.0: {} - resolve-alpn@1.2.1: {} resolve-from@4.0.0: {} @@ -6759,12 +6472,6 @@ snapshots: dependencies: path-parse: 1.0.7 - resolve@1.22.1: - dependencies: - is-core-module: 2.10.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - responselike@2.0.1: dependencies: lowercase-keys: 2.0.0 @@ -6805,6 +6512,7 @@ snapshots: get-intrinsic: 1.2.2 has-symbols: 1.0.3 isarray: 2.0.5 + optional: true safe-array-concat@1.1.2: dependencies: @@ -6823,6 +6531,7 @@ snapshots: call-bind: 1.0.5 get-intrinsic: 1.2.2 is-regex: 1.1.4 + optional: true safe-regex-test@1.0.3: dependencies: @@ -6845,7 +6554,7 @@ snapshots: semver@6.3.0: {} - semver@7.6.2: {} + semver@7.6.3: {} sentence-case@2.1.1: dependencies: @@ -6856,14 +6565,13 @@ snapshots: dependencies: randombytes: 2.1.0 - set-blocking@2.0.0: {} - set-function-length@1.1.1: dependencies: define-data-property: 1.1.1 get-intrinsic: 1.2.2 gopd: 1.0.1 has-property-descriptors: 1.0.0 + optional: true set-function-length@1.2.2: dependencies: @@ -6880,6 +6588,7 @@ snapshots: define-data-property: 1.1.1 functions-have-names: 1.2.3 has-property-descriptors: 1.0.0 + optional: true setimmediate@1.0.5: {} @@ -6909,6 +6618,7 @@ snapshots: call-bind: 1.0.5 get-intrinsic: 1.2.2 object-inspect: 1.13.1 + optional: true signal-exit@3.0.7: {} @@ -6922,24 +6632,15 @@ snapshots: astral-regex: 2.0.0 is-fullwidth-code-point: 3.0.0 - smartwrap@2.0.2: - dependencies: - array.prototype.flat: 1.3.2 - breakword: 1.0.6 - grapheme-splitter: 1.0.4 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - yargs: 15.4.1 - snake-case@2.1.0: dependencies: no-case: 2.3.2 - solc@0.7.3(debug@4.3.4): + solc@0.7.3(debug@4.3.6): dependencies: command-exists: 1.2.9 commander: 3.0.2 - follow-redirects: 1.15.6(debug@4.3.4) + follow-redirects: 1.15.6(debug@4.3.6) fs-extra: 0.30.0 js-sha3: 0.8.0 memorystream: 0.3.1 @@ -6949,14 +6650,14 @@ snapshots: transitivePeerDependencies: - debug - solhint-plugin-prettier@0.1.0(prettier-plugin-solidity@1.3.1(prettier@3.2.5))(prettier@3.2.5): + solhint-plugin-prettier@0.1.0(prettier-plugin-solidity@1.3.1(prettier@3.3.3))(prettier@3.3.3): dependencies: - '@prettier/sync': 0.3.0(prettier@3.2.5) - prettier: 3.2.5 + '@prettier/sync': 0.3.0(prettier@3.3.3) + prettier: 3.3.3 prettier-linter-helpers: 1.0.0 - prettier-plugin-solidity: 1.3.1(prettier@3.2.5) + prettier-plugin-solidity: 1.3.1(prettier@3.3.3) - solhint@5.0.1: + solhint@5.0.3: dependencies: '@solidity-parser/parser': 0.18.0 ajv: 6.12.6 @@ -6967,12 +6668,12 @@ snapshots: cosmiconfig: 8.2.0 fast-diff: 1.2.0 glob: 8.1.0 - ignore: 5.2.4 + ignore: 5.3.1 js-yaml: 4.1.0 latest-version: 7.0.0 lodash: 4.17.21 pluralize: 8.0.0 - semver: 7.6.2 + semver: 7.6.3 strip-ansi: 6.0.1 table: 6.8.1 text-table: 0.2.0 @@ -7045,20 +6746,6 @@ snapshots: cross-spawn: 5.1.0 signal-exit: 3.0.7 - spdx-correct@3.1.1: - dependencies: - spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.12 - - spdx-exceptions@2.3.0: {} - - spdx-expression-parse@3.0.1: - dependencies: - spdx-exceptions: 2.3.0 - spdx-license-ids: 3.0.12 - - spdx-license-ids@3.0.12: {} - sprintf-js@1.0.3: {} stacktrace-parser@0.1.10: @@ -7067,10 +6754,6 @@ snapshots: statuses@2.0.1: {} - stream-transform@2.1.3: - dependencies: - mixme: 0.5.10 - string-format@2.0.0: {} string-width@4.2.3: @@ -7084,6 +6767,7 @@ snapshots: call-bind: 1.0.5 define-properties: 1.2.1 es-abstract: 1.22.3 + optional: true string.prototype.trim@1.2.9: dependencies: @@ -7098,6 +6782,7 @@ snapshots: call-bind: 1.0.5 define-properties: 1.2.1 es-abstract: 1.22.3 + optional: true string.prototype.trimend@1.0.8: dependencies: @@ -7111,6 +6796,7 @@ snapshots: call-bind: 1.0.5 define-properties: 1.2.1 es-abstract: 1.22.3 + optional: true string.prototype.trimstart@1.0.8: dependencies: @@ -7133,10 +6819,6 @@ snapshots: dependencies: is-hex-prefixed: 1.0.0 - strip-indent@3.0.0: - dependencies: - min-indent: 1.0.1 - strip-json-comments@2.0.1: {} strip-json-comments@3.1.1: {} @@ -7153,14 +6835,12 @@ snapshots: dependencies: has-flag: 4.0.0 - supports-preserve-symlinks-flag@1.0.0: {} - swap-case@1.1.2: dependencies: lower-case: 1.1.4 upper-case: 1.1.3 - synckit@0.8.8: + synckit@0.9.1: dependencies: '@pkgr/core': 0.1.1 tslib: 2.6.2 @@ -7201,11 +6881,9 @@ snapshots: tr46@0.0.3: {} - trim-newlines@3.0.1: {} - - ts-api-utils@1.3.0(typescript@5.4.5): + ts-api-utils@1.3.0(typescript@5.5.4): dependencies: - typescript: 5.4.5 + typescript: 5.5.4 ts-command-line-args@2.5.1: dependencies: @@ -7214,25 +6892,25 @@ snapshots: command-line-usage: 6.1.3 string-format: 2.0.0 - ts-essentials@7.0.3(typescript@5.4.5): + ts-essentials@7.0.3(typescript@5.5.4): dependencies: - typescript: 5.4.5 + typescript: 5.5.4 - ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5): + ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.9 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.3 - '@types/node': 20.12.12 + '@types/node': 20.14.15 acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.4.5 + typescript: 5.5.4 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 @@ -7242,16 +6920,6 @@ snapshots: tsort@0.0.1: {} - tty-table@4.2.3: - dependencies: - chalk: 4.1.2 - csv: 5.5.3 - kleur: 4.1.5 - smartwrap: 2.0.2 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - yargs: 17.7.2 - tweetnacl-util@0.15.1: {} tweetnacl@1.0.3: {} @@ -7262,22 +6930,18 @@ snapshots: type-detect@4.0.8: {} - type-fest@0.13.1: {} + type-detect@4.1.0: {} type-fest@0.20.2: {} type-fest@0.21.3: {} - type-fest@0.6.0: {} - type-fest@0.7.1: {} - type-fest@0.8.1: {} - - typechain@8.3.2(typescript@5.4.5): + typechain@8.3.2(typescript@5.5.4): dependencies: '@types/prettier': 2.7.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.6 fs-extra: 7.0.1 glob: 7.1.7 js-sha3: 0.8.0 @@ -7285,8 +6949,8 @@ snapshots: mkdirp: 1.0.4 prettier: 2.8.8 ts-command-line-args: 2.5.1 - ts-essentials: 7.0.3(typescript@5.4.5) - typescript: 5.4.5 + ts-essentials: 7.0.3(typescript@5.5.4) + typescript: 5.5.4 transitivePeerDependencies: - supports-color @@ -7295,6 +6959,7 @@ snapshots: call-bind: 1.0.5 get-intrinsic: 1.2.2 is-typed-array: 1.1.12 + optional: true typed-array-buffer@1.0.2: dependencies: @@ -7309,6 +6974,7 @@ snapshots: for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 + optional: true typed-array-byte-length@1.0.1: dependencies: @@ -7326,6 +6992,7 @@ snapshots: for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 + optional: true typed-array-byte-offset@1.0.2: dependencies: @@ -7342,6 +7009,7 @@ snapshots: call-bind: 1.0.5 for-each: 0.3.3 is-typed-array: 1.1.12 + optional: true typed-array-length@1.0.6: dependencies: @@ -7353,7 +7021,7 @@ snapshots: possible-typed-array-names: 1.0.0 optional: true - typescript@5.4.5: {} + typescript@5.5.4: {} typical@4.0.0: {} @@ -7365,6 +7033,7 @@ snapshots: has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 + optional: true undici-types@5.26.5: {} @@ -7396,15 +7065,6 @@ snapshots: v8-compile-cache-lib@3.0.1: {} - validate-npm-package-license@3.0.4: - dependencies: - spdx-correct: 3.1.1 - spdx-expression-parse: 3.0.1 - - wcwidth@1.0.1: - dependencies: - defaults: 1.0.4 - web3-utils@1.7.4: dependencies: bn.js: 5.2.1 @@ -7429,8 +7089,7 @@ snapshots: is-number-object: 1.0.7 is-string: 1.0.7 is-symbol: 1.0.3 - - which-module@2.0.0: {} + optional: true which-pm@2.0.0: dependencies: @@ -7444,6 +7103,7 @@ snapshots: for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.0 + optional: true which-typed-array@1.1.15: dependencies: @@ -7473,12 +7133,6 @@ snapshots: workerpool@6.2.1: {} - wrap-ansi@6.2.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -7491,23 +7145,14 @@ snapshots: ws@7.5.9: {} - y18n@4.0.3: {} - y18n@5.0.8: {} yallist@2.1.2: {} yaml@1.10.2: {} - yargs-parser@18.1.3: - dependencies: - camelcase: 5.3.1 - decamelize: 1.2.0 - yargs-parser@20.2.4: {} - yargs-parser@21.1.1: {} - yargs-unparser@2.0.0: dependencies: camelcase: 6.3.0 @@ -7515,20 +7160,6 @@ snapshots: flat: 5.0.2 is-plain-obj: 2.1.0 - yargs@15.4.1: - dependencies: - cliui: 6.0.0 - decamelize: 1.2.0 - find-up: 4.1.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - require-main-filename: 2.0.0 - set-blocking: 2.0.0 - string-width: 4.2.3 - which-module: 2.0.0 - y18n: 4.0.3 - yargs-parser: 18.1.3 - yargs@16.2.0: dependencies: cliui: 7.0.4 @@ -7539,16 +7170,6 @@ snapshots: y18n: 5.0.8 yargs-parser: 20.2.4 - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - yn@3.1.1: {} yocto-queue@0.1.0: {} diff --git a/contracts/src/v0.8/keystone/test/mocks/MaliciousConfigurationContract.sol b/contracts/src/v0.8/keystone/test/mocks/MaliciousConfigurationContract.sol index 72c2e23efe..3618124297 100644 --- a/contracts/src/v0.8/keystone/test/mocks/MaliciousConfigurationContract.sol +++ b/contracts/src/v0.8/keystone/test/mocks/MaliciousConfigurationContract.sol @@ -13,7 +13,7 @@ contract MaliciousConfigurationContract is ICapabilityConfiguration, ERC165, Con s_capabilityWithConfigurationContractId = capabilityWithConfigContractId; } - function getCapabilityConfiguration(uint32) external view returns (bytes memory configuration) { + function getCapabilityConfiguration(uint32) external pure returns (bytes memory configuration) { return bytes(""); } diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumSequencerUptimeFeed.t.sol index 3b9df3bf91..5565409709 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumSequencerUptimeFeed.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumSequencerUptimeFeed.t.sol @@ -246,199 +246,3 @@ contract ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFuncti assertEq(answer, 0); } } - -contract ArbitrumSequencerUptimeFeed_GasCosts is ArbitrumSequencerUptimeFeedTest { - /// @notice it should consume a known amount of gas for updates - function test_GasCosts() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l2MessengerAddr, s_l2MessengerAddr); - - // Assert initial conditions - uint256 timestamp = s_arbitrumSequencerUptimeFeed.latestTimestamp(); - assertEq(s_arbitrumSequencerUptimeFeed.latestAnswer(), 0); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed; - uint256 gasStart; - uint256 gasFinal; - - // measures gas used for no update - expectedGasUsed = 5507; // NOTE: used to be 28300 in hardhat tests - gasStart = gasleft(); - s_arbitrumSequencerUptimeFeed.updateStatus(false, uint64(timestamp + 1000)); - gasFinal = gasleft(); - assertEq(s_arbitrumSequencerUptimeFeed.latestAnswer(), 0); - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - - // measures gas used for update - expectedGasUsed = 68198; // NOTE: used to be 93015 in hardhat tests - gasStart = gasleft(); - s_arbitrumSequencerUptimeFeed.updateStatus(true, uint64(timestamp + 1000)); - gasFinal = gasleft(); - assertEq(s_arbitrumSequencerUptimeFeed.latestAnswer(), 1); - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } -} - -contract ArbitrumSequencerUptimeFeed_AggregatorInterfaceGasCosts is ArbitrumSequencerUptimeFeedTest { - /// @notice it should consume a known amount of gas for getRoundData(uint80) - function test_GasUsageForGetRoundData() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l2MessengerAddr, s_l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 4658; // NOTE: used to be 31157 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_arbitrumSequencerUptimeFeed.latestTimestamp() + 1000; - s_arbitrumSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_arbitrumSequencerUptimeFeed.getRoundData(1); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for latestRoundData() - function test_GasUsageForLatestRoundData() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l2MessengerAddr, s_l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 2154; // NOTE: used to be 28523 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_arbitrumSequencerUptimeFeed.latestTimestamp() + 1000; - s_arbitrumSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_arbitrumSequencerUptimeFeed.latestRoundData(); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for latestAnswer() - function test_GasUsageForLatestAnswer() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l2MessengerAddr, s_l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 1722; // NOTE: used to be 28329 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_arbitrumSequencerUptimeFeed.latestTimestamp() + 1000; - s_arbitrumSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_arbitrumSequencerUptimeFeed.latestAnswer(); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for latestTimestamp() - function test_GasUsageForLatestTimestamp() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l2MessengerAddr, s_l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 1652; // NOTE: used to be 28229 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_arbitrumSequencerUptimeFeed.latestTimestamp() + 1000; - s_arbitrumSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_arbitrumSequencerUptimeFeed.latestTimestamp(); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for latestRound() - function test_GasUsageForLatestRound() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l2MessengerAddr, s_l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 1632; // NOTE: used to be 28245 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_arbitrumSequencerUptimeFeed.latestTimestamp() + 1000; - s_arbitrumSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_arbitrumSequencerUptimeFeed.latestRound(); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for getAnswer() - function test_GasUsageForGetAnswer() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l2MessengerAddr, s_l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 4059; // NOTE: used to be 30799 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_arbitrumSequencerUptimeFeed.latestTimestamp() + 1000; - s_arbitrumSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_arbitrumSequencerUptimeFeed.getAnswer(1); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for getTimestamp() - function test_GasUsageForGetTimestamp() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l2MessengerAddr, s_l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 4024; // NOTE: used to be 30753 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_arbitrumSequencerUptimeFeed.latestTimestamp() + 1000; - s_arbitrumSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_arbitrumSequencerUptimeFeed.getTimestamp(1); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } -} diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol index 60598b9f95..071d6e5b42 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol @@ -318,207 +318,3 @@ contract OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFuncti assertEq(answer, 0); } } - -contract OptimismSequencerUptimeFeed_GasCosts is OptimismSequencerUptimeFeedTest { - /// @notice it should consume a known amount of gas for updates - function test_GasCosts() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Assert initial conditions - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp(); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 0); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed; - uint256 gasStart; - uint256 gasFinal; - - // measures gas used for no update - expectedGasUsed = 10197; // NOTE: used to be 38594 in hardhat tests - gasStart = gasleft(); - s_optimismSequencerUptimeFeed.updateStatus(false, uint64(timestamp + 1000)); - gasFinal = gasleft(); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 0); - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - - // measures gas used for update - expectedGasUsed = 33348; // NOTE: used to be 60170 in hardhat tests - gasStart = gasleft(); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp + 1000)); - gasFinal = gasleft(); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 1); - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } -} - -contract OptimismSequencerUptimeFeed_AggregatorInterfaceGasCosts is OptimismSequencerUptimeFeedTest { - /// @notice it should consume a known amount of gas for getRoundData(uint80) - function test_GasUsageForGetRoundData() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 4504; // NOTE: used to be 30952 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp() + 1000; - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_optimismSequencerUptimeFeed.getRoundData(1); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for latestRoundData() - function test_GasUsageForLatestRoundData() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 2154; // NOTE: used to be 28523 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp() + 1000; - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_optimismSequencerUptimeFeed.latestRoundData(); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for latestAnswer() - function test_GasUsageForLatestAnswer() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 1722; // NOTE: used to be 28329 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp() + 1000; - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_optimismSequencerUptimeFeed.latestAnswer(); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for latestTimestamp() - function test_GasUsageForLatestTimestamp() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 1598; // NOTE: used to be 28229 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp() + 1000; - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_optimismSequencerUptimeFeed.latestTimestamp(); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for latestRound() - function test_GasUsageForLatestRound() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 1632; // NOTE: used to be 28245 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp() + 1000; - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_optimismSequencerUptimeFeed.latestRound(); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for getAnswer() - function test_GasUsageForGetAnswer() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 3929; // NOTE: used to be 30682 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp() + 1000; - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_optimismSequencerUptimeFeed.getAnswer(1); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for getTimestamp() - function test_GasUsageForGetTimestamp() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 3817; // NOTE: used to be 30570 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp() + 1000; - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_optimismSequencerUptimeFeed.getTimestamp(1); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } -} diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol index 520fbf6dfd..3aac50e7c1 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol @@ -322,207 +322,3 @@ contract ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunction assertEq(answer, 0); } } - -contract ScrollSequencerUptimeFeed_GasCosts is ScrollSequencerUptimeFeedTest { - /// @notice it should consume a known amount of gas for updates - function test_GasCosts() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Assert initial conditions - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp(); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 0); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed; - uint256 gasStart; - uint256 gasFinal; - - // measures gas used for no update - expectedGasUsed = 10197; // NOTE: used to be 38594 in hardhat tests - gasStart = gasleft(); - s_scrollSequencerUptimeFeed.updateStatus(false, uint64(timestamp + 1000)); - gasFinal = gasleft(); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 0); - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - - // measures gas used for update - expectedGasUsed = 31644; // NOTE: used to be 58458 in hardhat tests - gasStart = gasleft(); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp + 1000)); - gasFinal = gasleft(); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 1); - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } -} - -contract ScrollSequencerUptimeFeed_AggregatorInterfaceGasCosts is ScrollSequencerUptimeFeedTest { - /// @notice it should consume a known amount of gas for getRoundData(uint80) - function test_GasUsageForGetRoundData() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 4504; // NOTE: used to be 30952 in hardhat tesst - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp() + 1000; - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_scrollSequencerUptimeFeed.getRoundData(1); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for latestRoundData() - function test_GasUsageForLatestRoundData() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 2154; // NOTE: used to be 28523 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp() + 1000; - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_scrollSequencerUptimeFeed.latestRoundData(); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for latestAnswer() - function test_GasUsageForLatestAnswer() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 1566; // NOTE: used to be 28229 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp() + 1000; - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_scrollSequencerUptimeFeed.latestAnswer(); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for latestTimestamp() - function test_GasUsageForLatestTimestamp() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 1459; // NOTE: used to be 28129 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp() + 1000; - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_scrollSequencerUptimeFeed.latestTimestamp(); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for latestRound() - function test_GasUsageForLatestRound() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 1470; // NOTE: used to be 28145 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp() + 1000; - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_scrollSequencerUptimeFeed.latestRound(); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for getAnswer() - function test_GasUsageForGetAnswer() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 3929; // NOTE: used to be 30682 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp() + 1000; - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_scrollSequencerUptimeFeed.getAnswer(1); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } - - /// @notice it should consume a known amount of gas for getTimestamp() - function test_GasUsageForGetTimestamp() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Defines helper variables for measuring gas usage - uint256 expectedGasUsed = 3817; // NOTE: used to be 30570 in hardhat tests - uint256 gasStart; - uint256 gasFinal; - - // Initializes a round - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp() + 1000; - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - - // Measures gas usage - gasStart = gasleft(); - s_scrollSequencerUptimeFeed.getTimestamp(1); - gasFinal = gasleft(); - - // Checks that gas usage is within expected range - assertGasUsageIsCloseTo(expectedGasUsed, gasStart, gasFinal, GAS_USED_DEVIATION); - } -} diff --git a/contracts/src/v0.8/llo-feeds/libraries/test/ByteUtilTest.t.sol b/contracts/src/v0.8/llo-feeds/libraries/test/ByteUtilTest.t.sol index 8b5343866f..8f11dab093 100644 --- a/contracts/src/v0.8/llo-feeds/libraries/test/ByteUtilTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/libraries/test/ByteUtilTest.t.sol @@ -15,7 +15,7 @@ contract ByteUtilTest is Test { bytes4 internal constant MALFORMED_ERROR_SELECTOR = bytes4(keccak256("MalformedData()")); - function test_readUint256Max() public { + function test_readUint256Max() public pure { //read the first 32 bytes uint256 result = B_512._readUint256(0); @@ -23,7 +23,7 @@ contract ByteUtilTest is Test { assertEq(result, type(uint256).max); } - function test_readUint192Max() public { + function test_readUint192Max() public pure { //read the first 24 bytes uint256 result = B_512._readUint192(0); @@ -31,7 +31,7 @@ contract ByteUtilTest is Test { assertEq(result, type(uint192).max); } - function test_readUint32Max() public { + function test_readUint32Max() public pure { //read the first 4 bytes uint256 result = B_512._readUint32(0); @@ -39,7 +39,7 @@ contract ByteUtilTest is Test { assertEq(result, type(uint32).max); } - function test_readUint256Min() public { + function test_readUint256Min() public pure { //read the second 32 bytes uint256 result = B_512._readUint256(32); @@ -47,7 +47,7 @@ contract ByteUtilTest is Test { assertEq(result, type(uint256).min); } - function test_readUint192Min() public { + function test_readUint192Min() public pure { //read the second 24 bytes uint256 result = B_512._readUint192(32); @@ -55,7 +55,7 @@ contract ByteUtilTest is Test { assertEq(result, type(uint192).min); } - function test_readUint32Min() public { + function test_readUint32Min() public pure { //read the second 4 bytes uint256 result = B_512._readUint32(32); @@ -63,7 +63,7 @@ contract ByteUtilTest is Test { assertEq(result, type(uint32).min); } - function test_readUint256MultiWord() public { + function test_readUint256MultiWord() public pure { //read the first 32 bytes uint256 result = B_512._readUint256(31); @@ -71,7 +71,7 @@ contract ByteUtilTest is Test { assertEq(result, type(uint256).max << 248); } - function test_readUint192MultiWord() public { + function test_readUint192MultiWord() public pure { //read the first 24 bytes uint256 result = B_512._readUint192(31); @@ -79,7 +79,7 @@ contract ByteUtilTest is Test { assertEq(result, type(uint192).max << 184); } - function test_readUint32MultiWord() public { + function test_readUint32MultiWord() public pure { //read the first 4 bytes uint256 result = B_512._readUint32(31); @@ -135,7 +135,7 @@ contract ByteUtilTest is Test { B_EMPTY._readUint32(0); } - function test_readAddress() public { + function test_readAddress() public pure { //read the first 20 bytes address result = B_512._readAddress(0); @@ -143,7 +143,7 @@ contract ByteUtilTest is Test { assertEq(result, address(type(uint160).max)); } - function test_readZeroAddress() public { + function test_readZeroAddress() public pure { //read the first 32 bytes after the first word address result = B_512._readAddress(32); @@ -151,7 +151,7 @@ contract ByteUtilTest is Test { assertEq(result, address(type(uint160).min)); } - function test_readAddressMultiWord() public { + function test_readAddressMultiWord() public pure { //read the first 20 bytes after byte 13 address result = B_512._readAddress(13); diff --git a/contracts/src/v0.8/operatorforwarder/test/testhelpers/MaliciousConsumer.sol b/contracts/src/v0.8/operatorforwarder/test/testhelpers/MaliciousConsumer.sol index 842eec9054..bd731c7718 100644 --- a/contracts/src/v0.8/operatorforwarder/test/testhelpers/MaliciousConsumer.sol +++ b/contracts/src/v0.8/operatorforwarder/test/testhelpers/MaliciousConsumer.sol @@ -7,7 +7,7 @@ contract MaliciousConsumer is Chainlinked { uint256 private constant ORACLE_PAYMENT = 1 ether; uint256 private s_expiration; - constructor(address _link, address _oracle) public payable { + constructor(address _link, address _oracle) payable { setLinkToken(_link); setOracle(_oracle); } diff --git a/contracts/src/v0.8/operatorforwarder/test/testhelpers/MaliciousMultiWordConsumer.sol b/contracts/src/v0.8/operatorforwarder/test/testhelpers/MaliciousMultiWordConsumer.sol index 6e5881524f..93af16f64f 100644 --- a/contracts/src/v0.8/operatorforwarder/test/testhelpers/MaliciousMultiWordConsumer.sol +++ b/contracts/src/v0.8/operatorforwarder/test/testhelpers/MaliciousMultiWordConsumer.sol @@ -8,7 +8,7 @@ contract MaliciousMultiWordConsumer is ChainlinkClient { uint256 private constant ORACLE_PAYMENT = 1 ether; uint256 private s_expiration; - constructor(address _link, address _oracle) public payable { + constructor(address _link, address _oracle) payable { _setChainlinkToken(_link); _setChainlinkOracle(_oracle); } diff --git a/contracts/src/v0.8/shared/test/call/CallWithExactGas.t.sol b/contracts/src/v0.8/shared/test/call/CallWithExactGas.t.sol index 444112d2d8..3623cb8b12 100644 --- a/contracts/src/v0.8/shared/test/call/CallWithExactGas.t.sol +++ b/contracts/src/v0.8/shared/test/call/CallWithExactGas.t.sol @@ -220,7 +220,7 @@ contract CallWithExactGas__callWithExactGasSafeReturnData is CallWithExactGasSet assertGt(gasUsed, 500); } - function testFuzz_CallWithExactGasSafeReturnData_ConsumeAllGas_Success(uint8 gasLimitMultiplier) external { + function test_Fuzz_CallWithExactGasSafeReturnData_ConsumeAllGas_Success(uint8 gasLimitMultiplier) external { vm.assume(gasLimitMultiplier > 0); // Assume not zero to avoid zero gas being passed to s_gasConsumer uint16 maxRetBytes = 0; @@ -244,7 +244,7 @@ contract CallWithExactGas__callWithExactGasSafeReturnData is CallWithExactGasSet assertTrue(success, "Error: External Call Failed"); - //Assert equal within a margin of error of 1/64 of the gas limit to account for excess gas used by execution library + // Assert equal within a margin of error of 1/64 of the gas limit to account for excess gas used by execution library assertApproxEqAbs( gasUsed - CALL_WITH_EXACT_GAS_SAFE_RETURN_DATA_GAS_OVERHEAD, gasLimit, diff --git a/contracts/src/v0.8/shared/test/testhelpers/GasConsumer.sol b/contracts/src/v0.8/shared/test/testhelpers/GasConsumer.sol index 3c7bd2d596..efac2d15c1 100644 --- a/contracts/src/v0.8/shared/test/testhelpers/GasConsumer.sol +++ b/contracts/src/v0.8/shared/test/testhelpers/GasConsumer.sol @@ -9,8 +9,9 @@ contract GasConsumer { } lt(0, 1) { } { - // If 60 gas is remaining, then exit the loop by returning. 60 was determined by manual binary search to be the minimal amount of gas needed but less than the cost of another loop - if lt(gas(), 60) { + // If 100 gas is remaining, then exit the loop by returning. 100 was determined by manual binary search to be + // the minimal amount of gas needed but less than the cost of another loop + if lt(gas(), 100) { return(0x0, 0x0) // Return with no return data } } diff --git a/contracts/src/v0.8/shared/test/token/ERC677/BurnMintERC677.t.sol b/contracts/src/v0.8/shared/test/token/ERC677/BurnMintERC677.t.sol index de9067a569..2815f99256 100644 --- a/contracts/src/v0.8/shared/test/token/ERC677/BurnMintERC677.t.sol +++ b/contracts/src/v0.8/shared/test/token/ERC677/BurnMintERC677.t.sol @@ -338,7 +338,7 @@ contract BurnMintERC677_increaseApproval is BurnMintERC677Setup { } contract BurnMintERC677_supportsInterface is BurnMintERC677Setup { - function testConstructorSuccess() public { + function testConstructorSuccess() public view { assertTrue(s_burnMintERC677.supportsInterface(type(IERC20).interfaceId)); assertTrue(s_burnMintERC677.supportsInterface(type(IERC677).interfaceId)); assertTrue(s_burnMintERC677.supportsInterface(type(IBurnMintERC20).interfaceId)); diff --git a/contracts/src/v0.8/shared/test/token/ERC677/OpStackBurnMintERC677.t.sol b/contracts/src/v0.8/shared/test/token/ERC677/OpStackBurnMintERC677.t.sol index 7987fefec4..614b3bea15 100644 --- a/contracts/src/v0.8/shared/test/token/ERC677/OpStackBurnMintERC677.t.sol +++ b/contracts/src/v0.8/shared/test/token/ERC677/OpStackBurnMintERC677.t.sol @@ -41,7 +41,7 @@ contract OpStackBurnMintERC677_constructor is OpStackBurnMintERC677Setup { } contract OpStackBurnMintERC677_supportsInterface is OpStackBurnMintERC677Setup { - function testConstructorSuccess() public { + function testConstructorSuccess() public view { assertTrue(s_opStackBurnMintERC677.supportsInterface(type(IOptimismMintableERC20Minimal).interfaceId)); assertTrue(s_opStackBurnMintERC677.supportsInterface(type(IERC677).interfaceId)); assertTrue(s_opStackBurnMintERC677.supportsInterface(type(IBurnMintERC20).interfaceId)); diff --git a/contracts/src/v0.8/shared/test/util/SortedSetValidationUtil.t.sol b/contracts/src/v0.8/shared/test/util/SortedSetValidationUtil.t.sol index ae7eba479f..bf88df64ad 100644 --- a/contracts/src/v0.8/shared/test/util/SortedSetValidationUtil.t.sol +++ b/contracts/src/v0.8/shared/test/util/SortedSetValidationUtil.t.sol @@ -50,7 +50,7 @@ contract SortedSetValidationUtilBaseTest is BaseTest { contract SortedSetValidationUtil_CheckIsValidUniqueSubsetTest is SortedSetValidationUtilBaseTest { // Successes. - function test__checkIsValidUniqueSubset_ValidSubset_Success() public { + function test__checkIsValidUniqueSubset_ValidSubset_Success() public pure { (bytes32[] memory subset, bytes32[] memory superset) = _createSets(3, 5); _convertArrayToSortedSet(superset, OFFSET); _convertArrayToSubset(subset, superset); @@ -123,7 +123,7 @@ contract SortedSetValidationUtil_CheckIsValidUniqueSubsetTest is SortedSetValida SortedSetValidationUtil._checkIsValidUniqueSubset(subset, superset); } - function test__checkIsValidUniqueSubset_SubsetEqualsSuperset_NoRevert() public { + function test__checkIsValidUniqueSubset_SubsetEqualsSuperset_NoRevert() public pure { (bytes32[] memory subset, bytes32[] memory superset) = _createSets(5, 5); _convertArrayToSortedSet(subset, OFFSET); _convertArrayToSortedSet(superset, OFFSET); @@ -131,7 +131,7 @@ contract SortedSetValidationUtil_CheckIsValidUniqueSubsetTest is SortedSetValida SortedSetValidationUtil._checkIsValidUniqueSubset(subset, superset); } - function test__checkIsValidUniqueSubset_SingleElementSubset() public { + function test__checkIsValidUniqueSubset_SingleElementSubset() public pure { (bytes32[] memory subset, bytes32[] memory superset) = _createSets(1, 5); _convertArrayToSortedSet(superset, OFFSET); _convertArrayToSubset(subset, superset); @@ -139,7 +139,7 @@ contract SortedSetValidationUtil_CheckIsValidUniqueSubsetTest is SortedSetValida SortedSetValidationUtil._checkIsValidUniqueSubset(subset, superset); } - function test__checkIsValidUniqueSubset_SingleElementSubsetAndSuperset_Equal() public { + function test__checkIsValidUniqueSubset_SingleElementSubsetAndSuperset_Equal() public pure { (bytes32[] memory subset, bytes32[] memory superset) = _createSets(1, 1); _convertArrayToSortedSet(subset, OFFSET); _convertArrayToSortedSet(superset, OFFSET); diff --git a/contracts/src/v0.8/vrf/test/BatchVRFCoordinatorV2Plus.t.sol b/contracts/src/v0.8/vrf/test/BatchVRFCoordinatorV2Plus.t.sol index c2938cb35b..4197073aa5 100644 --- a/contracts/src/v0.8/vrf/test/BatchVRFCoordinatorV2Plus.t.sol +++ b/contracts/src/v0.8/vrf/test/BatchVRFCoordinatorV2Plus.t.sol @@ -48,17 +48,26 @@ contract BatchVRFCoordinatorV2PlusTest is FixtureVRFCoordinatorV2_5 { // Store the previous block's blockhash. vm.roll(requestBlock + 1); s_bhs.store(requestBlock); + assertEq(hex"1a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac", s_bhs.getBlockhash(requestBlock)); VRFTypes.Proof[] memory proofs = new VRFTypes.Proof[](2); VRFTypes.RequestCommitmentV2Plus[] memory rcs = new VRFTypes.RequestCommitmentV2Plus[](2); - // Proof generated via the generate-proof-v2-plus script command. Example usage: - // _printGenerateProofV2PlusCommand(address(s_consumer), 1, requestBlock, true); + // Proof generated via the generate-proof-v2-plus script command. + // 1st step: Uncomment the print command below and run the test to print the output. + // _printGenerateProofV2PlusCommand(address(s_consumer1), 1, requestBlock, false); + // 2nd step: export the following environment variables to run the generate-proof-v2-plus script. + // export ETH_URL=https://ethereum-sepolia-rpc.publicnode.com # or any other RPC provider you prefer + // export ETH_CHAIN_ID=11155111 # or switch to any other chain + // export ACCOUNT_KEY= + // 3rd step: copy the output from the 1st step and update the command below, then run the command + // and copy the command output in the proof section below /* + Run from this folder: chainlink/core/scripts/vrfv2plus/testnet go run . generate-proof-v2-plus \ -key-hash 0x9f2353bde94264dbc3d554a94cceba2d7d2b4fdce4304d3e09a1fea9fbeb1528 \ - -pre-seed 33855227690351884611579800220581891477580182035146587491531555927634180294480 \ - -block-hash 0x0a \ + -pre-seed 4430852740828987645228960511496023658059009607317025880962658187812299131155 \ + -block-hash 0x1a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac \ -block-num 10 \ -sender 0xdc90e8ce61c1af8a638b95264037c8e67ee5765c \ -native-payment true @@ -70,22 +79,22 @@ contract BatchVRFCoordinatorV2PlusTest is FixtureVRFCoordinatorV2_5 { 62070622898698443831883535403436258712770888294397026493185421712108624767191 ], gamma: [ - 80420391742429647505172101941811820476888293644816377569181566466584288434705, - 24046736031266889997051641830469514057863365715722268340801477580836256044582 + 26762213923453052192184693334574145607290366984305044804336172347176490943606, + 70503534560525619072578237689732581746976650376431765635714023643649039207077 ], - c: 74775128390693502914275156263410881155583102046081919417827483535122161050585, - s: 69563235412360165148368009853509434870917653835330501139204071967997764190111, - seed: 33855227690351884611579800220581891477580182035146587491531555927634180294480, - uWitness: 0xfB0663eaf48785540dE0FD0F837FD9c09BF4B80A, + c: 10992233996918874905152274435276937088064589467016709044984819613170049539489, + s: 79662863379962724455809192044326025082567113176696761949197261107120333769102, + seed: 4430852740828987645228960511496023658059009607317025880962658187812299131155, + uWitness: 0x421A52Fb797d76Fb610aA1a0c020346fC1Ee2DeB, cGammaWitness: [ - 53711159452748734758194447734939737695995909567499536035707522847057731697403, - 113650002631484103366420937668971311744887820666944514581352028601506700116835 + 50748523246052507241857300891945475679319243536065937584940024494820365165901, + 85746856994474260612851047426766648416105284284185975301552792881940939754570 ], sHashWitness: [ - 89656531714223714144489731263049239277719465105516547297952288438117443488525, - 90859682705760125677895017864538514058733199985667976488434404721197234427011 + 78637275871978664522379716948105702461748200460627087255706483027519919611423, + 82219236913923465822780520561305604064850823877720616893986252854976640396959 ], - zInv: 97275608653505690744303242942631893944856831559408852202478373762878300587548 + zInv: 60547558497534848069125896511700272238016171243048151035528198622956754542730 }); rcs[0] = VRFTypes.RequestCommitmentV2Plus({ blockNum: requestBlock, @@ -116,14 +125,23 @@ contract BatchVRFCoordinatorV2PlusTest is FixtureVRFCoordinatorV2_5 { // Store the previous block's blockhash. vm.roll(requestBlock + 1); s_bhs.store(requestBlock); + assertEq(hex"731dc163f73d31d8c68f9917ce4ff967753939f70432973c04fd2c2a48148607", s_bhs.getBlockhash(requestBlock)); - // Proof generated via the generate-proof-v2-plus script command. Example usage: + // Proof generated via the generate-proof-v2-plus script command. + // 1st step: Uncomment the print command below and run the test to print the output. // _printGenerateProofV2PlusCommand(address(s_consumer1), 1, requestBlock, false); + // 2nd step: export the following environment variables to run the generate-proof-v2-plus script. + // export ETH_URL=https://ethereum-sepolia-rpc.publicnode.com # or any other RPC provider you prefer + // export ETH_CHAIN_ID=11155111 # or switch to any other chain + // export ACCOUNT_KEY= + // 3rd step: copy the output from the 1st step and update the command below, then run the command + // and copy the command output in the proof section below /* + Run from this folder: chainlink/core/scripts/vrfv2plus/testnet go run . generate-proof-v2-plus \ -key-hash 0x9f2353bde94264dbc3d554a94cceba2d7d2b4fdce4304d3e09a1fea9fbeb1528 \ - -pre-seed 76568185840201037774581758921393822690942290841865097674309745036496166431060 \ - -block-hash 0x14 \ + -pre-seed 14541556911652758131165474365357244907354309169650401973525070879190071151266 \ + -block-hash 0x731dc163f73d31d8c68f9917ce4ff967753939f70432973c04fd2c2a48148607 \ -block-num 20 \ -sender 0x2f1c0761d6e4b1e5f01968d6c746f695e5f3e25d \ -native-payment false @@ -134,22 +152,22 @@ contract BatchVRFCoordinatorV2PlusTest is FixtureVRFCoordinatorV2_5 { 62070622898698443831883535403436258712770888294397026493185421712108624767191 ], gamma: [ - 21323932463597506192387578758854201988004673105893105492473194972397109828006, - 96834737826889397196571646974355352644437196500310392203712129010026003355112 + 97658842840420719674383370910135023062422561858595941631054490821636116883585, + 44255438468488339528368406358785988551798314198954634050943346751039644360856 ], - c: 8775807990949224376582975115621037245862755412370175152581490650310350359728, - s: 6805708577951013810918872616271445638109899206333819877111740872779453350091, - seed: 76568185840201037774581758921393822690942290841865097674309745036496166431060, - uWitness: 0xE82fF24Fecfbe73d682f38308bE3E039Dfabdf5c, + c: 5233652943248967403606766735502925802264855214922758107203237169366748118852, + s: 87931642435666855739510477620068257005869145374865238974094299759068218698655, + seed: 14541556911652758131165474365357244907354309169650401973525070879190071151266, + uWitness: 0x0A87a9CB71983cE0F2C4bA41D0c1A6Fb1785c46A, cGammaWitness: [ - 92810770919624535241476539842820168209710445519252592382122118536598338376923, - 17271305664006119131434661141858450289379246199095231636439133258170648418554 + 54062743217909816783918413821204010151082432359411822104552882037459289383418, + 67491004534731980264926765871774299056809003077448271411776926359153820235981 ], sHashWitness: [ - 29540023305939374439696120003978246982707698669656874393367212257432197207536, - 93902323936532381028323379401739289810874348405259732508442252936582467730050 + 7745933951617569731026754652291310837540252155195826133994719499558406927394, + 58405861596456412358325504621101233475720292237067230796670629212111423924259 ], - zInv: 88845170436601946907659333156418518556235340365885668267853966404617557948692 + zInv: 44253513765558903217330502897662324213800000485156126961643960636269885275795 }); rcs[1] = VRFTypes.RequestCommitmentV2Plus({ blockNum: requestBlock, @@ -168,9 +186,9 @@ contract BatchVRFCoordinatorV2PlusTest is FixtureVRFCoordinatorV2_5 { // The payments are NOT pre-calculated and simply copied from the actual event. // We can assert and ignore the payment field but the code will be considerably longer. vm.expectEmit(true, true, false, true, address(s_coordinator)); - emit RandomWordsFulfilled(output.requestId, output.randomness, s_subId, 500000000000143283, true, true, false); + emit RandomWordsFulfilled(output.requestId, output.randomness, s_subId, 500000000000143261, true, true, false); vm.expectEmit(true, true, false, true, address(s_coordinator)); - emit RandomWordsFulfilled(output1.requestId, output1.randomness, s_subId, 800000000000306143, false, true, false); + emit RandomWordsFulfilled(output1.requestId, output1.randomness, s_subId, 800000000000312358, false, true, false); // Fulfill the requests. s_batchCoordinator.fulfillRandomWords(proofs, rcs); diff --git a/contracts/src/v0.8/vrf/test/VRFV2Plus.t.sol b/contracts/src/v0.8/vrf/test/VRFV2Plus.t.sol index 75a8d96927..dd3f54b580 100644 --- a/contracts/src/v0.8/vrf/test/VRFV2Plus.t.sol +++ b/contracts/src/v0.8/vrf/test/VRFV2Plus.t.sol @@ -513,26 +513,33 @@ contract VRFV2Plus is BaseTest { assertEq(fulfilled, false); assertTrue(s_testCoordinator.pendingRequestExists(subId)); - // Uncomment these console logs to see info about the request: - // console.log("requestId: ", requestId); - // console.log("preSeed: ", preSeed); - // console.log("sender: ", address(s_testConsumer)); - // Move on to the next block. // Store the previous block's blockhash, and assert that it is as expected. vm.roll(requestBlock + 1); s_bhs.store(requestBlock); - assertEq(hex"0000000000000000000000000000000000000000000000000000000000000014", s_bhs.getBlockhash(requestBlock)); + assertEq(hex"731dc163f73d31d8c68f9917ce4ff967753939f70432973c04fd2c2a48148607", s_bhs.getBlockhash(requestBlock)); // Fulfill the request. - // Proof generated via the generate-proof-v2-plus script command. Example usage: + // Proof generated via the generate-proof-v2-plus script command. + // 1st step: Uncomment these 3 console logs to see info about the request and run the test to get output: + // console.log("requestId: ", requestId); + // console.log("preSeed: ", preSeed); + // console.log("sender: ", address(s_testConsumer)); + // 2nd step: Update pre-seed in the command commented out below with new value printed in console logs. + // 3rd step: export the following environment variables to run the generate-proof-v2-plus script. + // export ETH_URL=https://ethereum-sepolia-rpc.publicnode.com # or any other RPC provider you prefer + // export ETH_CHAIN_ID=11155111 # or switch to any other chain + // export ACCOUNT_KEY= + // 4th step: run the command and copy the command output in the proof section below. /* + Run from this folder: chainlink/core/scripts/vrfv2plus/testnet go run . generate-proof-v2-plus \ -key-hash 0x9f2353bde94264dbc3d554a94cceba2d7d2b4fdce4304d3e09a1fea9fbeb1528 \ - -pre-seed 58424872742560034068603954318478134981993109073728628043159461959392650534066 \ - -block-hash 0x0000000000000000000000000000000000000000000000000000000000000014 \ + -pre-seed 77134414723242246520332717536018735794426514244521954002798799849127623496871 \ + -block-hash 0x731dc163f73d31d8c68f9917ce4ff967753939f70432973c04fd2c2a48148607 \ -block-num 20 \ - -sender 0x90A8820424CC8a819d14cBdE54D12fD3fbFa9bb2 + -sender 0x90A8820424CC8a819d14cBdE54D12fD3fbFa9bb2 \ + -native-payment false */ proof = VRF.Proof({ pk: [ @@ -540,22 +547,22 @@ contract VRFV2Plus is BaseTest { 62070622898698443831883535403436258712770888294397026493185421712108624767191 ], gamma: [ - 38041205470219573731614166317842050442610096576830191475863676359766283013831, - 31897503406364148988967447112698248795931483458172800286988696482435433838056 + 103927982338770370318312316555080928288985522873495041111817988974598585393796, + 56789421278806198480964888112155620425048056183534931202752833185923411715624 ], - c: 114706080610174375269579192101772790158458728655229562781479812703475130740224, - s: 91869928024010088265014058436030407245056128545665425448353233998362687232253, - seed: 58424872742560034068603954318478134981993109073728628043159461959392650534066, - uWitness: 0x1514536B09a51E671d070312bcD3653386d5a82b, + c: 23645475075665525321781505993434124657388421977074956645288621921391376468128, + s: 106817081950846808215350231311242951539230271757396902089035477907017240898689, + seed: 77134414723242246520332717536018735794426514244521954002798799849127623496871, + uWitness: 0xD6899602060d574DE03FE1cf76fDf66afE12d549, cGammaWitness: [ - 90605489216274499662544489893800286859751132311034850249229378789467669572783, - 76568417372883461229305641415175605031997103681542349721251313705711146936024 + 9892458071712426452033749279561067220589549155902380165087951541202159693388, + 61235995320721681444549354910430438435754757626312862714628885100042911955139 ], sHashWitness: [ - 43417948503950579681520475434461454031791886587406480417092620950034789197994, - 100772571879140362396088596211082924128900752544164141322636815729889228000249 + 101478618362722903511580105256015180591690884037598276249676652094434483808775, + 82512235485399822034680598942438982472006937353405384896956013889074719896188 ], - zInv: 82374292458278672300647114418593830323283909625362447038989596015264004164958 + zInv: 82281039329215616805111360985152709712368762415186906218863971780664103705723 }); rc = VRFTypes.RequestCommitmentV2Plus({ blockNum: requestBlock, @@ -602,24 +609,30 @@ contract VRFV2Plus is BaseTest { assertEq(fulfilled, false); assertTrue(s_testCoordinator.pendingRequestExists(subId)); - // Uncomment these console logs to see info about the request: - // console.log("requestId: ", requestId); - // console.log("preSeed: ", preSeed); - // console.log("sender: ", address(s_testConsumer)); - // Move on to the next block. // Store the previous block's blockhash, and assert that it is as expected. vm.roll(requestBlock + 1); s_bhs.store(requestBlock); - assertEq(hex"000000000000000000000000000000000000000000000000000000000000000a", s_bhs.getBlockhash(requestBlock)); + assertEq(hex"1a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac", s_bhs.getBlockhash(requestBlock)); // Fulfill the request. - // Proof generated via the generate-proof-v2-plus script command. Example usage: + // Proof generated via the generate-proof-v2-plus script command. + // 1st step: Uncomment these 3 console logs to see info about the request and run the test to get output: + // console.log("requestId: ", requestId); + // console.log("preSeed: ", preSeed); + // console.log("sender: ", address(s_testConsumer)); + // 2nd step: Update pre-seed in the command commented out below with new value printed in console logs. + // 3rd step: export the following environment variables to run the generate-proof-v2-plus script. + // export ETH_URL=https://ethereum-sepolia-rpc.publicnode.com # or any other RPC provider you prefer + // export ETH_CHAIN_ID=11155111 # or switch to any other chain + // export ACCOUNT_KEY= + // 4th step: run the command and copy the command output in the proof section below. /* + Run from this folder: chainlink/core/scripts/vrfv2plus/testnet go run . generate-proof-v2-plus \ -key-hash 0x9f2353bde94264dbc3d554a94cceba2d7d2b4fdce4304d3e09a1fea9fbeb1528 \ - -pre-seed 83266692323404068105564931899467966321583332182309426611016082057597749986430 \ - -block-hash 0x000000000000000000000000000000000000000000000000000000000000000a \ + -pre-seed 88177119495082281213609405072572269421661478022189589823108119237563684383163 \ + -block-hash 0x1a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac \ -block-num 10 \ -sender 0x90A8820424CC8a819d14cBdE54D12fD3fbFa9bb2 \ -native-payment true @@ -630,22 +643,22 @@ contract VRFV2Plus is BaseTest { 62070622898698443831883535403436258712770888294397026493185421712108624767191 ], gamma: [ - 47144451677122876068574640250190132179872561942855874114516471019540736524783, - 63001220656590641645486673489302242739512599229187442248048295264418080499391 + 102142782721757938350759722545721736888276217484353597703162772276193136052353, + 87167280284008869627768921028415708350806510214000539818296353518495698939660 ], - c: 42928477813589729783511577059394077774341588261592343937605454161333818133643, - s: 14447529458406454898597883219032514356523135029224613793880920230249515634875, - seed: 83266692323404068105564931899467966321583332182309426611016082057597749986430, - uWitness: 0x5Ed3bb2AA8EAFe168a23079644d5dfBf892B1038, + c: 78738462581063211677832865654743924688552792392007862664964608134754001810280, + s: 97066881804257970453329086439696419448135613089654606517271688187030953014593, + seed: 88177119495082281213609405072572269421661478022189589823108119237563684383163, + uWitness: 0xa335ea8dF652d5331a276B60b16c9733435D4f73, cGammaWitness: [ - 40742088032247467257043132769297935807697466810312051815364187117543257089153, - 110399474382135664619186049639190334359061769014381608543009407662815758204131 + 114435126227922602743444254494036972095649501991695809092954325430947992864624, + 63032211040463927862594425238691911311087931119674607521158894139074063158678 ], sHashWitness: [ - 26556776392895292893984393164594214244553035014769995354896600239759043777485, - 67126706735912782218279556535631175449291035782208850310724682668198932501077 + 105043781471073183057173130563345930784924139079040814418442661347864735908726, + 68696469914696211053833437482938344908217760552761185546164836556562945431554 ], - zInv: 88742453392918610091640193378775723954629905126315835248392650970979000380325 + zInv: 73325637847357165955904789471972164751975373195750497508525598331798833112175 }); rc = VRFTypes.RequestCommitmentV2Plus({ blockNum: requestBlock, @@ -750,26 +763,26 @@ contract VRFV2Plus is BaseTest { (bool fulfilled, , ) = s_testConsumer.s_requests(requestId); assertEq(fulfilled, true); - // The cost of fulfillRandomWords is approximately 86_700 gas. + // The cost of fulfillRandomWords is approximately 89_100 gas. // gasAfterPaymentCalculation is 50_000. // // The cost of the VRF fulfillment charged to the user is: // paymentNoFee = (weiPerUnitGas * (gasAfterPaymentCalculation + startGas - gasleft() + l1CostWei) / link_native_ratio) // network gas price is capped at gas lane max gas (5000 gwei) - // paymentNoFee = (5e12 * (50_000 + 86_700 + 0)) / .5 - // paymentNoFee = 1.367e+18 + // paymentNoFee = (5e12 * (50_000 + 89_100 + 0)) / .5 + // paymentNoFee = 1.391e+18 // flatFeeWei = 1e12 * (fulfillmentFlatFeeNativePPM - fulfillmentFlatFeeLinkDiscountPPM) // flatFeeWei = 1e12 * (500_000 - 100_000) // flatFeeJuels = 1e18 * flatFeeWei / link_native_ratio // flatFeeJuels = 4e17 / 0.5 = 8e17 // billed_fee = paymentNoFee * (10 / 100) + 8e17 - // billed_fee = 1.367e+18 * 0.1 + 8e17 - // billed_fee = 9.367e+17 + // billed_fee = 1.391e+18 * 0.1 + 8e17 + // billed_fee = 9.391e+17 // note: delta is doubled from the native test to account for more variance due to the link/native ratio (uint96 linkBalanceAfter, , , , ) = s_testCoordinator.getSubscription(subId); // 1e15 is less than 1 percent discrepancy - assertApproxEqAbs(payment, 9.367 * 1e17, 1e15); - assertApproxEqAbs(linkBalanceAfter, linkBalanceBefore - 9.367 * 1e17, 1e15); + assertApproxEqAbs(payment, 9.391 * 1e17, 1e15); + assertApproxEqAbs(linkBalanceAfter, linkBalanceBefore - 9.391 * 1e17, 1e15); assertFalse(s_testCoordinator.pendingRequestExists(subId)); } @@ -834,24 +847,30 @@ contract VRFV2Plus is BaseTest { ); assertTrue(s_testCoordinator.pendingRequestExists(subId)); - // 3. Fulfill the request above - //console.log("requestId: ", requestId); - //console.log("preSeed: ", preSeed); - //console.log("sender: ", address(consumer)); - // Move on to the next block. // Store the previous block's blockhash, and assert that it is as expected. vm.roll(requestBlock + 1); s_bhs.store(requestBlock); - assertEq(hex"000000000000000000000000000000000000000000000000000000000000000a", s_bhs.getBlockhash(requestBlock)); + assertEq(hex"1a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac", s_bhs.getBlockhash(requestBlock)); - // Fulfill the request. - // Proof generated via the generate-proof-v2-plus script command. Example usage: + // 3. Fulfill the request above + // Proof generated via the generate-proof-v2-plus script command. + // 1st step: Uncomment these 3 console logs to see info about the request and run the test to get output: + // console.log("requestId: ", requestId); + // console.log("preSeed: ", preSeed); + // console.log("sender: ", address(s_testConsumer)); + // 2nd step: Update pre-seed in the command commented out below with new value printed in console logs. + // 3rd step: export the following environment variables to run the generate-proof-v2-plus script. + // export ETH_URL=https://ethereum-sepolia-rpc.publicnode.com # or any other RPC provider you prefer + // export ETH_CHAIN_ID=11155111 # or switch to any other chain + // export ACCOUNT_KEY= + // 4th step: run the command and copy the command output in the proof section below. /* + Run from this folder: chainlink/core/scripts/vrfv2plus/testnet go run . generate-proof-v2-plus \ -key-hash 0x9f2353bde94264dbc3d554a94cceba2d7d2b4fdce4304d3e09a1fea9fbeb1528 \ - -pre-seed 94043941380654896554739370173616551044559721638888689173752661912204412136884 \ - -block-hash 0x000000000000000000000000000000000000000000000000000000000000000a \ + -pre-seed 78857362017365444144484359594634073685493503942324326290718892836953423263381 \ + -block-hash 0x1a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac \ -block-num 10 \ -sender 0x44CAfC03154A0708F9DCf988681821f648dA74aF \ -native-payment true @@ -862,22 +881,22 @@ contract VRFV2Plus is BaseTest { 62070622898698443831883535403436258712770888294397026493185421712108624767191 ], gamma: [ - 18593555375562408458806406536059989757338587469093035962641476877033456068708, - 55675218112764789548330682504442195066741636758414578491295297591596761905475 + 65913937398148449626792563067325648649534055460473988721938103219381973178278, + 63156327344180203180831822252171874192175272818200597638000091892096122362120 ], - c: 56595337384472359782910435918403237878894172750128610188222417200315739516270, - s: 60666722370046279064490737533582002977678558769715798604164042022636022215663, - seed: 94043941380654896554739370173616551044559721638888689173752661912204412136884, - uWitness: 0xEdbE15fd105cfEFb9CCcbBD84403d1F62719E50d, + c: 96524997218413735279221574381819903278651909890109201564980667824986706861580, + s: 32941032142956097592442894642111025677491308239274769364799856748447418202313, + seed: 78857362017365444144484359594634073685493503942324326290718892836953423263381, + uWitness: 0xda613621Dc2347d9A6670a1cBA812d52A7ec3A3A, cGammaWitness: [ - 11752391553651713021860307604522059957920042356542944931263270793211985356642, - 14713353048309058367510422609936133400473710094544154206129568172815229277104 + 6776842114900054689355891239487365968068230823400902903493665825747641410781, + 753482930067864853610521010650481816782338376846697006021590704037205560592 ], sHashWitness: [ - 109716108880570827107616596438987062129934448629902940427517663799192095060206, - 79378277044196229730810703755304140279837983575681427317104232794580059801930 + 76619528582417858778905184311764104068650968652636772643050945629834129417915, + 27947566794040118487986033070014357750801611688958204148187927873566412002355 ], - zInv: 18898957977631212231148068121702167284572066246731769473720131179584458697812 + zInv: 77351076831418813780936064446565588198113457019145030499544500588309236458362 }); VRFTypes.RequestCommitmentV2Plus memory rc = VRFTypes.RequestCommitmentV2Plus({ blockNum: requestBlock, @@ -988,20 +1007,26 @@ contract VRFV2Plus is BaseTest { // Store the previous block's blockhash, and assert that it is as expected. vm.roll(requestBlock + 1); s_bhs.store(requestBlock); - assertEq(hex"000000000000000000000000000000000000000000000000000000000000000a", s_bhs.getBlockhash(requestBlock)); + assertEq(hex"1a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac", s_bhs.getBlockhash(requestBlock)); // 3. Fulfill the 1st request above - console.log("requestId: ", requestId1); - console.log("preSeed: ", preSeed1); - console.log("sender: ", address(consumer1)); - - // Fulfill the request. - // Proof generated via the generate-proof-v2-plus script command. Example usage: + // Proof generated via the generate-proof-v2-plus script command. + // 1st step: Uncomment these 3 console logs to see info about the request and run the test to get output: + // console.log("requestId: ", requestId); + // console.log("preSeed: ", preSeed); + // console.log("sender: ", address(s_testConsumer)); + // 2nd step: Update pre-seed in the command commented out below with new value printed in console logs. + // 3rd step: export the following environment variables to run the generate-proof-v2-plus script. + // export ETH_URL=https://ethereum-sepolia-rpc.publicnode.com # or any other RPC provider you prefer + // export ETH_CHAIN_ID=11155111 # or switch to any other chain + // export ACCOUNT_KEY= + // 4th step: run the command and copy the command output in the proof section below. /* + Run from this folder: chainlink/core/scripts/vrfv2plus/testnet go run . generate-proof-v2-plus \ -key-hash 0x9f2353bde94264dbc3d554a94cceba2d7d2b4fdce4304d3e09a1fea9fbeb1528 \ - -pre-seed 94043941380654896554739370173616551044559721638888689173752661912204412136884 \ - -block-hash 0x000000000000000000000000000000000000000000000000000000000000000a \ + -pre-seed 78857362017365444144484359594634073685493503942324326290718892836953423263381 \ + -block-hash 0x1a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac \ -block-num 10 \ -sender 0x44CAfC03154A0708F9DCf988681821f648dA74aF \ -native-payment true @@ -1012,22 +1037,22 @@ contract VRFV2Plus is BaseTest { 62070622898698443831883535403436258712770888294397026493185421712108624767191 ], gamma: [ - 18593555375562408458806406536059989757338587469093035962641476877033456068708, - 55675218112764789548330682504442195066741636758414578491295297591596761905475 + 65913937398148449626792563067325648649534055460473988721938103219381973178278, + 63156327344180203180831822252171874192175272818200597638000091892096122362120 ], - c: 56595337384472359782910435918403237878894172750128610188222417200315739516270, - s: 60666722370046279064490737533582002977678558769715798604164042022636022215663, - seed: 94043941380654896554739370173616551044559721638888689173752661912204412136884, - uWitness: 0xEdbE15fd105cfEFb9CCcbBD84403d1F62719E50d, + c: 103296526941774692908067234360350834482645116475454593803823148315342533216203, + s: 50291245814080656739779812653411869801334231723444391096753849942661931376590, + seed: 78857362017365444144484359594634073685493503942324326290718892836953423263381, + uWitness: 0x38500711AdcB471ac1A566c4b915759eb9cBCE2F, cGammaWitness: [ - 11752391553651713021860307604522059957920042356542944931263270793211985356642, - 14713353048309058367510422609936133400473710094544154206129568172815229277104 + 56476970720509547210740928951846471668018949971632948991136782499758110143588, + 44326075300781389077656415325167171692706436527877070415603658305817367373598 ], sHashWitness: [ - 109716108880570827107616596438987062129934448629902940427517663799192095060206, - 79378277044196229730810703755304140279837983575681427317104232794580059801930 + 109524696164787283409393383708118913934136014139634321235031691839206768278439, + 52690039857779635909051684567562068782378693408005554345469129234366171822741 ], - zInv: 18898957977631212231148068121702167284572066246731769473720131179584458697812 + zInv: 108537983043800425266290112227943788107669768716438017124275578856644517258573 }); VRFTypes.RequestCommitmentV2Plus memory rc = VRFTypes.RequestCommitmentV2Plus({ blockNum: requestBlock, @@ -1040,18 +1065,24 @@ contract VRFV2Plus is BaseTest { s_testCoordinator.fulfillRandomWords(proof, rc, true /* onlyPremium */); assertTrue(s_testCoordinator.pendingRequestExists(subId)); - //4. Fulfill the 2nd request - console.log("requestId: ", requestId2); - console.log("preSeed: ", preSeed2); - console.log("sender: ", address(consumer2)); - - // Fulfill the request. - // Proof generated via the generate-proof-v2-plus script command. Example usage: + // 4. Fulfill the 2nd request + // Proof generated via the generate-proof-v2-plus script command. + // 1st step: Uncomment these 3 console logs to see info about the request and run the test to get output: + // console.log("requestId: ", requestId); + // console.log("preSeed: ", preSeed); + // console.log("sender: ", address(s_testConsumer)); + // 2nd step: Update pre-seed in the command commented out below with new value printed in console logs. + // 3rd step: export the following environment variables to run the generate-proof-v2-plus script. + // export ETH_URL=https://ethereum-sepolia-rpc.publicnode.com # or any other RPC provider you prefer + // export ETH_CHAIN_ID=11155111 # or switch to any other chain + // export ACCOUNT_KEY= + // 4th step: run the command and copy the command output in the proof section below. /* + Run from this folder: chainlink/core/scripts/vrfv2plus/testnet go run . generate-proof-v2-plus \ -key-hash 0x9f2353bde94264dbc3d554a94cceba2d7d2b4fdce4304d3e09a1fea9fbeb1528 \ - -pre-seed 60086281972849674111646805013521068579710860774417505336898013292594859262126 \ - -block-hash 0x000000000000000000000000000000000000000000000000000000000000000a \ + -pre-seed 53330100288105770463016865504321558518073051667771993294213115153676065708950 \ + -block-hash 0x1a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac \ -block-num 10 \ -sender 0xf5a165378E120f93784395aDF1E08a437e902865 \ -native-payment true @@ -1062,22 +1093,22 @@ contract VRFV2Plus is BaseTest { 62070622898698443831883535403436258712770888294397026493185421712108624767191 ], gamma: [ - 8781676794493524976318989249067879326013864868749595045909181134740761572122, - 70144896394968351242907510966944756907625107566821127114847472296460405612124 + 7260273098301741284457725182313945178888499328441106869722941415453613782770, + 91648498042618923465107471165504200585847250228048015102713552756245653299952 ], - c: 67847193668837615807355025316836592349514589069599294392546721746916067719949, - s: 114946531382736685625345450298146929067341928840493664822961336014597880904075, - seed: 60086281972849674111646805013521068579710860774417505336898013292594859262126, - uWitness: 0xe1de4fD69277D0C5516cAE4d760b1d08BC340A28, + c: 64987886290696558870328339791409334400119338012796549091587853494368167422332, + s: 69469162696695326295567645789624554797683340898724555794078876350372084267572, + seed: 53330100288105770463016865504321558518073051667771993294213115153676065708950, + uWitness: 0xa6ce21aD47eC5E90Ac7a2c6152D9710234Afe8ab, cGammaWitness: [ - 90301582727701442026215692513959255065128476395727596945643431833363167168678, - 61501369717028493801369453424028509804064958915788808540582630993703331669978 + 57318358662553647785891634403735348577492991113152343207139729697842283565417, + 57942043484796308689103390068712967247519265087617809262260051163954389512396 ], sHashWitness: [ - 98738650825542176387169085844714248077697103572877410412808249468787326424906, - 85647963391545223707301702874240345890884970941786094239896961457539737216630 + 113345999157319332195230171660555736547709417795439282230372737104445523493539, + 113358219039155973560933190466797830695088313506343976960055230355894888727567 ], - zInv: 29080001901010358083725892808339807464533563010468652346220922643802059192842 + zInv: 68349552569605209428774574139615352877146713490794995768725549089572297658255 }); rc = VRFTypes.RequestCommitmentV2Plus({ blockNum: requestBlock, diff --git a/core/scripts/vrfv2plus/testnet/proofs.go b/core/scripts/vrfv2plus/testnet/proofs.go index 23ddc8ecfd..ea6943c63f 100644 --- a/core/scripts/vrfv2plus/testnet/proofs.go +++ b/core/scripts/vrfv2plus/testnet/proofs.go @@ -54,7 +54,7 @@ var rcTemplate = `{ ` func generateProofForV2Plus(e helpers.Environment) { - deployCmd := flag.NewFlagSet("generate-proof", flag.ExitOnError) + deployCmd := flag.NewFlagSet("generate-proof-v2-plus", flag.ExitOnError) keyHashString := deployCmd.String("key-hash", "", "key hash for VRF request") preSeedString := deployCmd.String("pre-seed", "", "pre-seed for VRF request") From 5070cf8f74e7ffd84fd2b8a1067ac0a93d69d1c2 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 26 Aug 2024 19:04:02 +0200 Subject: [PATCH 169/432] use services.Config.NewService/Engine (part 3) (#14170) --- common/client/poller.go | 58 ++++++------ common/client/poller_test.go | 23 +++-- .../remote/target/endtoend_test.go | 74 ++++++--------- core/chains/evm/client/rpc_client.go | 4 +- .../evm/forwarders/forwarder_manager.go | 93 +++++++------------ .../internal/ccipdata/v1_0_0/commit_store.go | 9 +- plugins/medianpoc/plugin.go | 40 ++------ 7 files changed, 117 insertions(+), 184 deletions(-) diff --git a/common/client/poller.go b/common/client/poller.go index d6080722c5..eeb6c3af57 100644 --- a/common/client/poller.go +++ b/common/client/poller.go @@ -2,7 +2,6 @@ package client import ( "context" - "sync" "time" "github.com/smartcontractkit/chainlink-common/pkg/logger" @@ -15,83 +14,80 @@ import ( // and delivers the result to a channel. It is used by multinode to poll // for new heads and implements the Subscription interface. type Poller[T any] struct { - services.StateMachine + services.Service + eng *services.Engine + pollingInterval time.Duration pollingFunc func(ctx context.Context) (T, error) pollingTimeout time.Duration - logger logger.Logger channel chan<- T errCh chan error - - stopCh services.StopChan - wg sync.WaitGroup } // NewPoller creates a new Poller instance and returns a channel to receive the polled data func NewPoller[ T any, -](pollingInterval time.Duration, pollingFunc func(ctx context.Context) (T, error), pollingTimeout time.Duration, logger logger.Logger) (Poller[T], <-chan T) { +](pollingInterval time.Duration, pollingFunc func(ctx context.Context) (T, error), pollingTimeout time.Duration, lggr logger.Logger) (Poller[T], <-chan T) { channel := make(chan T) - return Poller[T]{ + p := Poller[T]{ pollingInterval: pollingInterval, pollingFunc: pollingFunc, pollingTimeout: pollingTimeout, channel: channel, - logger: logger, errCh: make(chan error), - stopCh: make(chan struct{}), - }, channel + } + p.Service, p.eng = services.Config{ + Name: "Poller", + Start: p.start, + Close: p.close, + }.NewServiceEngine(lggr) + return p, channel } var _ types.Subscription = &Poller[any]{} -func (p *Poller[T]) Start() error { - return p.StartOnce("Poller", func() error { - p.wg.Add(1) - go p.pollingLoop() - return nil - }) +func (p *Poller[T]) start(ctx context.Context) error { + p.eng.Go(p.pollingLoop) + return nil } // Unsubscribe cancels the sending of events to the data channel func (p *Poller[T]) Unsubscribe() { - _ = p.StopOnce("Poller", func() error { - close(p.stopCh) - p.wg.Wait() - close(p.errCh) - close(p.channel) - return nil - }) + _ = p.Close() +} + +func (p *Poller[T]) close() error { + close(p.errCh) + close(p.channel) + return nil } func (p *Poller[T]) Err() <-chan error { return p.errCh } -func (p *Poller[T]) pollingLoop() { - defer p.wg.Done() - +func (p *Poller[T]) pollingLoop(ctx context.Context) { ticker := time.NewTicker(p.pollingInterval) defer ticker.Stop() for { select { - case <-p.stopCh: + case <-ctx.Done(): return case <-ticker.C: // Set polling timeout - pollingCtx, cancelPolling := p.stopCh.CtxCancel(context.WithTimeout(context.Background(), p.pollingTimeout)) + pollingCtx, cancelPolling := context.WithTimeout(ctx, p.pollingTimeout) // Execute polling function result, err := p.pollingFunc(pollingCtx) cancelPolling() if err != nil { - p.logger.Warnf("polling error: %v", err) + p.eng.Warnf("polling error: %v", err) continue } // Send result to channel or block if channel is full select { case p.channel <- result: - case <-p.stopCh: + case <-ctx.Done(): return } } diff --git a/common/client/poller_test.go b/common/client/poller_test.go index 91af579307..930b101751 100644 --- a/common/client/poller_test.go +++ b/common/client/poller_test.go @@ -20,20 +20,22 @@ func Test_Poller(t *testing.T) { lggr := logger.Test(t) t.Run("Test multiple start", func(t *testing.T) { + ctx := tests.Context(t) pollFunc := func(ctx context.Context) (Head, error) { return nil, nil } poller, _ := NewPoller[Head](time.Millisecond, pollFunc, time.Second, lggr) - err := poller.Start() + err := poller.Start(ctx) require.NoError(t, err) - err = poller.Start() + err = poller.Start(ctx) require.Error(t, err) poller.Unsubscribe() }) t.Run("Test polling for heads", func(t *testing.T) { + ctx := tests.Context(t) // Mock polling function that returns a new value every time it's called var pollNumber int pollLock := sync.Mutex{} @@ -50,7 +52,7 @@ func Test_Poller(t *testing.T) { // Create poller and start to receive data poller, channel := NewPoller[Head](time.Millisecond, pollFunc, time.Second, lggr) - require.NoError(t, poller.Start()) + require.NoError(t, poller.Start(ctx)) defer poller.Unsubscribe() // Receive updates from the poller @@ -63,6 +65,7 @@ func Test_Poller(t *testing.T) { }) t.Run("Test polling errors", func(t *testing.T) { + ctx := tests.Context(t) // Mock polling function that returns an error var pollNumber int pollLock := sync.Mutex{} @@ -77,7 +80,7 @@ func Test_Poller(t *testing.T) { // Create poller and subscribe to receive data poller, _ := NewPoller[Head](time.Millisecond, pollFunc, time.Second, olggr) - require.NoError(t, poller.Start()) + require.NoError(t, poller.Start(ctx)) defer poller.Unsubscribe() // Ensure that all errors were logged as expected @@ -94,6 +97,7 @@ func Test_Poller(t *testing.T) { }) t.Run("Test polling timeout", func(t *testing.T) { + ctx := tests.Context(t) pollFunc := func(ctx context.Context) (Head, error) { if <-ctx.Done(); true { return nil, ctx.Err() @@ -108,7 +112,7 @@ func Test_Poller(t *testing.T) { // Create poller and subscribe to receive data poller, _ := NewPoller[Head](time.Millisecond, pollFunc, pollingTimeout, olggr) - require.NoError(t, poller.Start()) + require.NoError(t, poller.Start(ctx)) defer poller.Unsubscribe() // Ensure that timeout errors were logged as expected @@ -119,6 +123,7 @@ func Test_Poller(t *testing.T) { }) t.Run("Test unsubscribe during polling", func(t *testing.T) { + ctx := tests.Context(t) wait := make(chan struct{}) closeOnce := sync.OnceFunc(func() { close(wait) }) pollFunc := func(ctx context.Context) (Head, error) { @@ -137,7 +142,7 @@ func Test_Poller(t *testing.T) { // Create poller and subscribe to receive data poller, _ := NewPoller[Head](time.Millisecond, pollFunc, pollingTimeout, olggr) - require.NoError(t, poller.Start()) + require.NoError(t, poller.Start(ctx)) // Unsubscribe while blocked in polling function <-wait @@ -167,8 +172,9 @@ func Test_Poller_Unsubscribe(t *testing.T) { } t.Run("Test multiple unsubscribe", func(t *testing.T) { + ctx := tests.Context(t) poller, channel := NewPoller[Head](time.Millisecond, pollFunc, time.Second, lggr) - err := poller.Start() + err := poller.Start(ctx) require.NoError(t, err) <-channel @@ -177,8 +183,9 @@ func Test_Poller_Unsubscribe(t *testing.T) { }) t.Run("Read channel after unsubscribe", func(t *testing.T) { + ctx := tests.Context(t) poller, channel := NewPoller[Head](time.Millisecond, pollFunc, time.Second, lggr) - err := poller.Start() + err := poller.Start(ctx) require.NoError(t, err) poller.Unsubscribe() diff --git a/core/capabilities/remote/target/endtoend_test.go b/core/capabilities/remote/target/endtoend_test.go index 31bdc83e26..9abb6e99d5 100644 --- a/core/capabilities/remote/target/endtoend_test.go +++ b/core/capabilities/remote/target/endtoend_test.go @@ -276,67 +276,47 @@ func testRemoteTarget(ctx context.Context, t *testing.T, underlying commoncap.Ta } type testAsyncMessageBroker struct { - services.StateMachine - t *testing.T + services.Service + eng *services.Engine + t *testing.T nodes map[p2ptypes.PeerID]remotetypes.Receiver sendCh chan *remotetypes.MessageBody - - stopCh services.StopChan - wg sync.WaitGroup -} - -func (a *testAsyncMessageBroker) HealthReport() map[string]error { - return nil -} - -func (a *testAsyncMessageBroker) Name() string { - return "testAsyncMessageBroker" } func newTestAsyncMessageBroker(t *testing.T, sendChBufferSize int) *testAsyncMessageBroker { - return &testAsyncMessageBroker{ + b := &testAsyncMessageBroker{ t: t, nodes: make(map[p2ptypes.PeerID]remotetypes.Receiver), - stopCh: make(services.StopChan), sendCh: make(chan *remotetypes.MessageBody, sendChBufferSize), } -} - -func (a *testAsyncMessageBroker) Start(ctx context.Context) error { - return a.StartOnce("testAsyncMessageBroker", func() error { - a.wg.Add(1) - go func() { - defer a.wg.Done() - - for { - select { - case <-a.stopCh: - return - case msg := <-a.sendCh: - receiverId := toPeerID(msg.Receiver) - - receiver, ok := a.nodes[receiverId] - if !ok { - panic("server not found for peer id") - } - - receiver.Receive(tests.Context(a.t), msg) + b.Service, b.eng = services.Config{ + Name: "testAsyncMessageBroker", + Start: b.start, + }.NewServiceEngine(logger.TestLogger(t)) + return b +} + +func (a *testAsyncMessageBroker) start(ctx context.Context) error { + a.eng.Go(func(ctx context.Context) { + for { + select { + case <-ctx.Done(): + return + case msg := <-a.sendCh: + receiverId := toPeerID(msg.Receiver) + + receiver, ok := a.nodes[receiverId] + if !ok { + panic("server not found for peer id") } - } - }() - return nil - }) -} - -func (a *testAsyncMessageBroker) Close() error { - return a.StopOnce("testAsyncMessageBroker", func() error { - close(a.stopCh) - a.wg.Wait() - return nil + receiver.Receive(tests.Context(a.t), msg) + } + } }) + return nil } func (a *testAsyncMessageBroker) NewDispatcherForNode(nodePeerID p2ptypes.PeerID) remotetypes.Dispatcher { diff --git a/core/chains/evm/client/rpc_client.go b/core/chains/evm/client/rpc_client.go index 07aa86fc45..c9e172326e 100644 --- a/core/chains/evm/client/rpc_client.go +++ b/core/chains/evm/client/rpc_client.go @@ -546,14 +546,14 @@ func (r *rpcClient) SubscribeToHeads(ctx context.Context) (ch <-chan *evmtypes.H return channel, forwarder, err } -func (r *rpcClient) SubscribeToFinalizedHeads(_ context.Context) (<-chan *evmtypes.Head, commontypes.Subscription, error) { +func (r *rpcClient) SubscribeToFinalizedHeads(ctx context.Context) (<-chan *evmtypes.Head, commontypes.Subscription, error) { interval := r.finalizedBlockPollInterval if interval == 0 { return nil, nil, errors.New("FinalizedBlockPollInterval is 0") } timeout := interval poller, channel := commonclient.NewPoller[*evmtypes.Head](interval, r.LatestFinalizedBlock, timeout, r.rpcLog) - if err := poller.Start(); err != nil { + if err := poller.Start(ctx); err != nil { return nil, nil, err } return channel, &poller, nil diff --git a/core/chains/evm/forwarders/forwarder_manager.go b/core/chains/evm/forwarders/forwarder_manager.go index 6436988ba8..0e9f8781c3 100644 --- a/core/chains/evm/forwarders/forwarder_manager.go +++ b/core/chains/evm/forwarders/forwarder_manager.go @@ -33,7 +33,9 @@ type Config interface { } type FwdMgr struct { - services.StateMachine + services.Service + eng *services.Engine + ORM ORM evmClient evmclient.Client cfg Config @@ -48,61 +50,51 @@ type FwdMgr struct { authRcvr authorized_receiver.AuthorizedReceiverInterface offchainAgg offchain_aggregator_wrapper.OffchainAggregatorInterface - stopCh services.StopChan - cacheMu sync.RWMutex - wg sync.WaitGroup } -func NewFwdMgr(ds sqlutil.DataSource, client evmclient.Client, logpoller evmlogpoller.LogPoller, l logger.Logger, cfg Config) *FwdMgr { - lggr := logger.Sugared(logger.Named(l, "EVMForwarderManager")) - fwdMgr := FwdMgr{ - logger: lggr, +func NewFwdMgr(ds sqlutil.DataSource, client evmclient.Client, logpoller evmlogpoller.LogPoller, lggr logger.Logger, cfg Config) *FwdMgr { + fm := FwdMgr{ cfg: cfg, evmClient: client, ORM: NewORM(ds), logpoller: logpoller, sendersCache: make(map[common.Address][]common.Address), } - fwdMgr.stopCh = make(chan struct{}) - return &fwdMgr -} - -func (f *FwdMgr) Name() string { - return f.logger.Name() + fm.Service, fm.eng = services.Config{ + Name: "ForwarderManager", + Start: fm.start, + }.NewServiceEngine(lggr) + fm.logger = logger.Sugared(fm.eng) + return &fm } -// Start starts Forwarder Manager. -func (f *FwdMgr) Start(ctx context.Context) error { - return f.StartOnce("EVMForwarderManager", func() error { - f.logger.Debug("Initializing EVM forwarder manager") - chainId := f.evmClient.ConfiguredChainID() +func (f *FwdMgr) start(ctx context.Context) error { + chainId := f.evmClient.ConfiguredChainID() - fwdrs, err := f.ORM.FindForwardersByChain(ctx, big.Big(*chainId)) - if err != nil { - return pkgerrors.Wrapf(err, "Failed to retrieve forwarders for chain %d", chainId) - } - if len(fwdrs) != 0 { - f.initForwardersCache(ctx, fwdrs) - if err = f.subscribeForwardersLogs(ctx, fwdrs); err != nil { - return err - } + fwdrs, err := f.ORM.FindForwardersByChain(ctx, big.Big(*chainId)) + if err != nil { + return pkgerrors.Wrapf(err, "Failed to retrieve forwarders for chain %d", chainId) + } + if len(fwdrs) != 0 { + f.initForwardersCache(ctx, fwdrs) + if err = f.subscribeForwardersLogs(ctx, fwdrs); err != nil { + return err } + } - f.authRcvr, err = authorized_receiver.NewAuthorizedReceiver(common.Address{}, f.evmClient) - if err != nil { - return pkgerrors.Wrap(err, "Failed to init AuthorizedReceiver") - } + f.authRcvr, err = authorized_receiver.NewAuthorizedReceiver(common.Address{}, f.evmClient) + if err != nil { + return pkgerrors.Wrap(err, "Failed to init AuthorizedReceiver") + } - f.offchainAgg, err = offchain_aggregator_wrapper.NewOffchainAggregator(common.Address{}, f.evmClient) - if err != nil { - return pkgerrors.Wrap(err, "Failed to init OffchainAggregator") - } + f.offchainAgg, err = offchain_aggregator_wrapper.NewOffchainAggregator(common.Address{}, f.evmClient) + if err != nil { + return pkgerrors.Wrap(err, "Failed to init OffchainAggregator") + } - f.wg.Add(1) - go f.runLoop() - return nil - }) + f.eng.Go(f.runLoop) + return nil } func FilterName(addr common.Address) string { @@ -176,7 +168,7 @@ func (f *FwdMgr) ConvertPayload(dest common.Address, origPayload []byte) ([]byte if err != nil { f.logger.AssumptionViolationw("Forwarder encoding failed, this should never happen", "err", err, "to", dest, "payload", origPayload) - f.SvcErrBuffer.Append(err) + f.eng.EmitHealthErr(err) } } return databytes, nil @@ -269,11 +261,7 @@ func (f *FwdMgr) getCachedSenders(addr common.Address) ([]common.Address, bool) return addrs, ok } -func (f *FwdMgr) runLoop() { - defer f.wg.Done() - ctx, cancel := f.stopCh.NewCtx() - defer cancel() - +func (f *FwdMgr) runLoop(ctx context.Context) { ticker := services.NewTicker(time.Minute) defer ticker.Stop() @@ -353,16 +341,3 @@ func (f *FwdMgr) collectAddresses() (addrs []common.Address) { } return } - -// Stop cancels all outgoings calls and stops internal ticker loop. -func (f *FwdMgr) Close() error { - return f.StopOnce("EVMForwarderManager", func() (err error) { - close(f.stopCh) - f.wg.Wait() - return nil - }) -} - -func (f *FwdMgr) HealthReport() map[string]error { - return map[string]error{f.Name(): f.Healthy()} -} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go index d0559b800e..f6e957746e 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go @@ -2,6 +2,7 @@ package v1_0_0 import ( "context" + "errors" "fmt" "math/big" "sync" @@ -11,7 +12,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/pkg/errors" + "golang.org/x/exp/maps" "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/logger" @@ -90,7 +91,7 @@ func encodeCommitReport(commitReportArgs abi.Arguments, report cciptypes.CommitS var usdPerUnitGas = big.NewInt(0) var destChainSelector = uint64(0) if len(report.GasPrices) > 1 { - return []byte{}, errors.Errorf("CommitStore V1_0_0 can only accept 1 gas price, received: %d", len(report.GasPrices)) + return []byte{}, fmt.Errorf("CommitStore V1_0_0 can only accept 1 gas price, received: %d", len(report.GasPrices)) } if len(report.GasPrices) > 0 { usdPerUnitGas = report.GasPrices[0].Value @@ -133,7 +134,7 @@ func DecodeCommitReport(commitReportArgs abi.Arguments, report []byte) (cciptype MerkleRoot [32]byte `json:"merkleRoot"` }) if !ok { - return cciptypes.CommitStoreReport{}, errors.Errorf("invalid commit report got %T", unpacked[0]) + return cciptypes.CommitStoreReport{}, fmt.Errorf("invalid commit report got %T", unpacked[0]) } var tokenPriceUpdates []cciptypes.TokenPrice @@ -382,7 +383,7 @@ func (c *CommitStore) GetLatestPriceEpochAndRound(ctx context.Context) (uint64, } func (c *CommitStore) IsDestChainHealthy(context.Context) (bool, error) { - if err := c.lp.Healthy(); err != nil { + if err := errors.Join(maps.Values(c.lp.HealthReport())...); err != nil { return false, nil } return true, nil diff --git a/plugins/medianpoc/plugin.go b/plugins/medianpoc/plugin.go index 41580afe49..e6ada1bec8 100644 --- a/plugins/medianpoc/plugin.go +++ b/plugins/medianpoc/plugin.go @@ -40,7 +40,7 @@ func (e *PipelineNotFoundError) Error() string { } func (p *Plugin) NewValidationService(ctx context.Context) (core.ValidationService, error) { - s := &reportingPluginValidationService{lggr: p.Logger} + s := &reportingPluginValidationService{Service: services.Config{Name: "ValidationService"}.NewService(p.Logger)} p.SubService(s) return s, nil } @@ -81,7 +81,10 @@ func (p *Plugin) NewReportingPluginFactory( if err != nil { return nil, err } - s := &reportingPluginFactoryService{lggr: p.Logger, ReportingPluginFactory: f} + s := &reportingPluginFactoryService{ + Service: services.Config{Name: "ReportingPluginFactory"}.NewService(p.Logger), + ReportingPluginFactory: f, + } p.SubService(s) return s, nil } @@ -157,28 +160,12 @@ func (p *Plugin) newFactory(ctx context.Context, config core.ReportingPluginServ } type reportingPluginFactoryService struct { - services.StateMachine - lggr logger.Logger + services.Service ocrtypes.ReportingPluginFactory } -func (r *reportingPluginFactoryService) Name() string { return r.lggr.Name() } - -func (r *reportingPluginFactoryService) Start(ctx context.Context) error { - return r.StartOnce("ReportingPluginFactory", func() error { return nil }) -} - -func (r *reportingPluginFactoryService) Close() error { - return r.StopOnce("ReportingPluginFactory", func() error { return nil }) -} - -func (r *reportingPluginFactoryService) HealthReport() map[string]error { - return map[string]error{r.Name(): r.Healthy()} -} - type reportingPluginValidationService struct { - services.StateMachine - lggr logger.Logger + services.Service } func (r *reportingPluginValidationService) ValidateConfig(ctx context.Context, config map[string]interface{}) error { @@ -196,16 +183,3 @@ func (r *reportingPluginValidationService) ValidateConfig(ctx context.Context, c return nil } -func (r *reportingPluginValidationService) Name() string { return r.lggr.Name() } - -func (r *reportingPluginValidationService) Start(ctx context.Context) error { - return r.StartOnce("ValidationService", func() error { return nil }) -} - -func (r *reportingPluginValidationService) Close() error { - return r.StopOnce("ValidationService", func() error { return nil }) -} - -func (r *reportingPluginValidationService) HealthReport() map[string]error { - return map[string]error{r.Name(): r.Healthy()} -} From 9e7406e03e8c752655408de0715c282aa881a627 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 26 Aug 2024 21:07:59 +0200 Subject: [PATCH 170/432] core/services/ocr/plugins/llo: fix onchain cache test race (#14232) --- .../llo/onchain_channel_definition_cache_integration_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go index 6103fbbaf4..d084e51531 100644 --- a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go +++ b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go @@ -58,6 +58,7 @@ func (h *mockHTTPClient) SetResponse(resp *http.Response, err error) { type MockReadCloser struct { data []byte + mu sync.RWMutex reader *bytes.Reader } @@ -70,11 +71,15 @@ func NewMockReadCloser(data []byte) *MockReadCloser { // Read reads from the underlying data func (m *MockReadCloser) Read(p []byte) (int, error) { + m.mu.RLock() + defer m.mu.RUnlock() return m.reader.Read(p) } // Close resets the reader to the beginning of the data func (m *MockReadCloser) Close() error { + m.mu.Lock() + defer m.mu.Unlock() m.reader.Seek(0, io.SeekStart) return nil } From c00ac968e651fd7b09f473d20f0fe4755ba57367 Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Mon, 26 Aug 2024 14:19:43 -0700 Subject: [PATCH 171/432] Ccip-3076 deployment package (#14209) * deployment package inclusion * go mod * Add README * Add changeset * Fix changeset * change confirm function * ignore linter for now * core generate * add todo ticket * fix test --------- Co-authored-by: Lukasz <120112546+lukaszcl@users.noreply.github.com> Co-authored-by: connorwstein --- .changeset/small-seas-stare.md | 5 + .../ccip_integration_tests/ocr_node_helper.go | 4 +- .../ocrimpls/contract_transmitter_test.go | 2 +- core/capabilities/integration_tests/setup.go | 3 +- .../remote/target/request/server_request.go | 2 +- core/chains/evm/gas/models.go | 2 +- core/chains/evm/logpoller/log_poller_test.go | 2 +- core/chains/evm/logpoller/orm_test.go | 2 +- core/chains/evm/txmgr/broadcaster_test.go | 2 +- core/cmd/shell_local_test.go | 3 +- .../price_registry_1_2_0/price_registry.go | 2 +- core/internal/features/features_test.go | 3 +- .../features/ocr2/features_ocr2_test.go | 2 +- core/services/feeds/proto/feeds_manager.pb.go | 5 +- .../feeds/proto/feeds_manager_wsrpc.pb.go | 1 + .../fluxmonitorv2/flux_monitor_test.go | 3 +- .../fluxmonitorv2/integrations_test.go | 3 +- core/services/job/job_orm_test.go | 2 +- core/services/keeper/integration_test.go | 3 +- .../ccip/testhelpers/integration/chainlink.go | 2 +- .../testhelpers_1_4_0/chainlink.go | 2 +- .../functions/config/config_types.pb.go | 5 +- .../functions/encoding/ocr_types.pb.go | 5 +- .../v1/internal/testutils.go | 3 +- .../services/ocr2/plugins/llo/helpers_test.go | 2 +- .../ocr2/plugins/mercury/helpers_test.go | 3 +- .../v21/logprovider/integration_test.go | 2 +- .../plugins/ocr2keeper/integration_test.go | 2 +- core/services/ocr2/plugins/s4/messages.pb.go | 5 +- core/services/pg/lease_lock_test.go | 2 +- core/services/pipeline/orm_test.go | 2 +- .../synchronization/telem/telem.pb.go | 5 +- .../telem/telem_automation_custom.pb.go | 5 +- .../telem/telem_enhanced_ea.pb.go | 5 +- .../telem/telem_enhanced_ea_mercury.pb.go | 5 +- .../telem/telem_functions_request.pb.go | 5 +- .../telem/telem_head_report.pb.go | 5 +- .../synchronization/telem/telem_wsrpc.pb.go | 1 + core/services/vrf/v1/integration_test.go | 3 +- core/services/vrf/v2/bhs_feeder_test.go | 2 +- .../vrf/v2/integration_helpers_test.go | 2 +- .../vrf/v2/integration_v2_plus_test.go | 3 +- .../v2/integration_v2_reverted_txns_test.go | 2 +- core/services/vrf/v2/integration_v2_test.go | 2 +- core/store/migrate/migrate_test.go | 2 +- .../testutils}/heavyweight/orm.go | 0 dashboard-lib/atlas-don/component.go | 1 + .../ccip-load-test-view/component.go | 1 + dashboard-lib/config.go | 3 +- dashboard-lib/core-don/component.go | 1 + dashboard-lib/core-ocrv2-ccip/component.go | 1 + dashboard-lib/dashboard.go | 5 +- integration-tests/.golangci.yml | 3 + integration-tests/deployment/README.md | 58 + integration-tests/deployment/address_book.go | 158 + .../deployment/address_book_test.go | 112 + integration-tests/deployment/changeset.go | 28 + integration-tests/deployment/environment.go | 195 + .../deployment/jd/job/v1/job.pb.go | 1768 ++++++ .../deployment/jd/job/v1/job_grpc.pb.go | 346 ++ .../deployment/jd/node/v1/node.pb.go | 1652 ++++++ .../deployment/jd/node/v1/node_grpc.pb.go | 188 + .../deployment/jd/node/v1/shared.pb.go | 240 + .../deployment/jd/shared/ptypes/label.pb.go | 312 + integration-tests/deployment/memory/chain.go | 74 + .../deployment/memory/environment.go | 139 + .../deployment/memory/job_client.go | 126 + integration-tests/deployment/memory/node.go | 292 + .../deployment/memory/node_test.go | 23 + integration-tests/go.mod | 89 +- integration-tests/go.sum | 368 +- integration-tests/load/go.mod | 75 +- integration-tests/load/go.sum | 347 +- integration-tests/web/sdk/README.md | 13 + integration-tests/web/sdk/client/client.go | 156 + .../web/sdk/client/internal/doer/doer.go | 20 + integration-tests/web/sdk/genqlient.yaml | 15 + .../web/sdk/internal/generated/generated.go | 5007 +++++++++++++++++ .../web/sdk/internal/genqlient.graphql | 320 ++ .../web/sdk/internal/schema.graphql | 1045 ++++ integration-tests/web/sdk/main.go | 21 + integration-tests/web/sdk/taskfile.yml | 6 + 82 files changed, 12683 insertions(+), 658 deletions(-) create mode 100644 .changeset/small-seas-stare.md rename core/{internal/cltest => utils/testutils}/heavyweight/orm.go (100%) create mode 100644 integration-tests/deployment/README.md create mode 100644 integration-tests/deployment/address_book.go create mode 100644 integration-tests/deployment/address_book_test.go create mode 100644 integration-tests/deployment/changeset.go create mode 100644 integration-tests/deployment/environment.go create mode 100644 integration-tests/deployment/jd/job/v1/job.pb.go create mode 100644 integration-tests/deployment/jd/job/v1/job_grpc.pb.go create mode 100644 integration-tests/deployment/jd/node/v1/node.pb.go create mode 100644 integration-tests/deployment/jd/node/v1/node_grpc.pb.go create mode 100644 integration-tests/deployment/jd/node/v1/shared.pb.go create mode 100644 integration-tests/deployment/jd/shared/ptypes/label.pb.go create mode 100644 integration-tests/deployment/memory/chain.go create mode 100644 integration-tests/deployment/memory/environment.go create mode 100644 integration-tests/deployment/memory/job_client.go create mode 100644 integration-tests/deployment/memory/node.go create mode 100644 integration-tests/deployment/memory/node_test.go create mode 100644 integration-tests/web/sdk/README.md create mode 100644 integration-tests/web/sdk/client/client.go create mode 100644 integration-tests/web/sdk/client/internal/doer/doer.go create mode 100644 integration-tests/web/sdk/genqlient.yaml create mode 100644 integration-tests/web/sdk/internal/generated/generated.go create mode 100644 integration-tests/web/sdk/internal/genqlient.graphql create mode 100644 integration-tests/web/sdk/internal/schema.graphql create mode 100644 integration-tests/web/sdk/main.go create mode 100644 integration-tests/web/sdk/taskfile.yml diff --git a/.changeset/small-seas-stare.md b/.changeset/small-seas-stare.md new file mode 100644 index 0000000000..22e447bbc8 --- /dev/null +++ b/.changeset/small-seas-stare.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal Adding deployment package as new pattern for product deployment/configuration diff --git a/core/capabilities/ccip/ccip_integration_tests/ocr_node_helper.go b/core/capabilities/ccip/ccip_integration_tests/ocr_node_helper.go index 75b0e0ee94..d8bbd5eace 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ocr_node_helper.go +++ b/core/capabilities/ccip/ccip_integration_tests/ocr_node_helper.go @@ -11,6 +11,7 @@ import ( "time" coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core/mocks" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -25,6 +26,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" @@ -33,7 +35,6 @@ import ( evmutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" configv2 "github.com/smartcontractkit/chainlink/v2/core/config/toml" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" @@ -42,6 +43,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" "github.com/smartcontractkit/chainlink/v2/plugins" "github.com/stretchr/testify/require" diff --git a/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go b/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go index 0c1fa0d384..6c39990643 100644 --- a/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go +++ b/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go @@ -613,7 +613,7 @@ func (g *TestGasEstimatorConfig) LimitJobType() evmconfig.LimitJobType { func (g *TestGasEstimatorConfig) PriceMaxKey(addr common.Address) *assets.Wei { return assets.GWei(1) } -func (g *TestGasEstimatorConfig) EstimateGasLimit() bool { return false } +func (g *TestGasEstimatorConfig) EstimateGasLimit() bool { return false } func (e *TestEvmConfig) GasEstimator() evmconfig.GasEstimator { return &TestGasEstimatorConfig{bumpThreshold: e.BumpThreshold} diff --git a/core/capabilities/integration_tests/setup.go b/core/capabilities/integration_tests/setup.go index 69b8c3eaa0..f419c05e6c 100644 --- a/core/capabilities/integration_tests/setup.go +++ b/core/capabilities/integration_tests/setup.go @@ -28,12 +28,12 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core" v3 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" + "github.com/smartcontractkit/chainlink/v2/core/capabilities" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -43,6 +43,7 @@ import ( p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) const ( diff --git a/core/capabilities/remote/target/request/server_request.go b/core/capabilities/remote/target/request/server_request.go index 4aaee11854..e16742a246 100644 --- a/core/capabilities/remote/target/request/server_request.go +++ b/core/capabilities/remote/target/request/server_request.go @@ -78,7 +78,7 @@ func (e *ServerRequest) OnMessage(ctx context.Context, msg *types.MessageBody) e if err != nil { return fmt.Errorf("failed to convert message sender to PeerID: %w", err) } - + if err := e.addRequester(requester); err != nil { return fmt.Errorf("failed to add requester to request: %w", err) } diff --git a/core/chains/evm/gas/models.go b/core/chains/evm/gas/models.go index 15adfc0d7a..f3fae4e574 100644 --- a/core/chains/evm/gas/models.go +++ b/core/chains/evm/gas/models.go @@ -389,7 +389,7 @@ func (e *evmFeeEstimator) estimateFeeLimit(ctx context.Context, feeLimit uint64, e.lggr.Debugw("estimated gas limit with buffer exceeds the provided gas limit with multiplier. falling back to the provided gas limit with multiplier", "estimatedGasLimit", estimatedFeeLimit, "providedGasLimitWithMultiplier", providedGasLimit) estimatedFeeLimit = providedGasLimit } - + return } diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index 860b588c77..548711c19b 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -36,10 +36,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_emitter" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) func logRuntime(t testing.TB, start time.Time) { diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index 0df34196ff..ab8d126e10 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -28,8 +28,8 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) type block struct { diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 4edc5572f0..343988196c 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -45,11 +45,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) // NewEthBroadcaster creates a new txmgr.EthBroadcaster for use in testing. diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go index 8ed48dcaa2..783781723e 100644 --- a/core/cmd/shell_local_test.go +++ b/core/cmd/shell_local_test.go @@ -11,13 +11,13 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + "github.com/smartcontractkit/chainlink/v2/common/client" "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/cmd" cmdMocks "github.com/smartcontractkit/chainlink/v2/core/cmd/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" @@ -32,6 +32,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/store/dialects" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" "github.com/smartcontractkit/chainlink/v2/plugins" gethTypes "github.com/ethereum/go-ethereum/core/types" diff --git a/core/gethwrappers/ccip/generated/price_registry_1_2_0/price_registry.go b/core/gethwrappers/ccip/generated/price_registry_1_2_0/price_registry.go index 64e16bd1dc..30b1b26da9 100644 --- a/core/gethwrappers/ccip/generated/price_registry_1_2_0/price_registry.go +++ b/core/gethwrappers/ccip/generated/price_registry_1_2_0/price_registry.go @@ -1690,4 +1690,4 @@ type PriceRegistryInterface interface { ParseLog(log types.Log) (generated.AbigenLog, error) Address() common.Address -} \ No newline at end of file +} diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go index 86e43f44eb..6f35b9b0b5 100644 --- a/core/internal/features/features_test.go +++ b/core/internal/features/features_test.go @@ -41,6 +41,7 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + "github.com/smartcontractkit/chainlink/v2/core/auth" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" @@ -57,7 +58,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/multiwordconsumer_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/operator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" @@ -74,6 +74,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/static" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/web" webauth "github.com/smartcontractkit/chainlink/v2/core/web/auth" ) diff --git a/core/internal/features/ocr2/features_ocr2_test.go b/core/internal/features/ocr2/features_ocr2_test.go index d0f157d8bd..9160310261 100644 --- a/core/internal/features/ocr2/features_ocr2_test.go +++ b/core/internal/features/ocr2/features_ocr2_test.go @@ -43,7 +43,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/authorized_forwarder" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -54,6 +53,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) type ocr2Node struct { diff --git a/core/services/feeds/proto/feeds_manager.pb.go b/core/services/feeds/proto/feeds_manager.pb.go index ee5bcef393..010ee44ae8 100644 --- a/core/services/feeds/proto/feeds_manager.pb.go +++ b/core/services/feeds/proto/feeds_manager.pb.go @@ -7,10 +7,11 @@ package proto import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/core/services/feeds/proto/feeds_manager_wsrpc.pb.go b/core/services/feeds/proto/feeds_manager_wsrpc.pb.go index 17fe100b4f..85476b1188 100644 --- a/core/services/feeds/proto/feeds_manager_wsrpc.pb.go +++ b/core/services/feeds/proto/feeds_manager_wsrpc.pb.go @@ -7,6 +7,7 @@ package proto import ( context "context" + wsrpc "github.com/smartcontractkit/wsrpc" ) diff --git a/core/services/fluxmonitorv2/flux_monitor_test.go b/core/services/fluxmonitorv2/flux_monitor_test.go index 1d1ed676e4..098b1f4a47 100644 --- a/core/services/fluxmonitorv2/flux_monitor_test.go +++ b/core/services/fluxmonitorv2/flux_monitor_test.go @@ -23,13 +23,13 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" logmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" @@ -42,6 +42,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" pipelinemocks "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/mocks" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) const oracleCount uint8 = 17 diff --git a/core/services/fluxmonitorv2/integrations_test.go b/core/services/fluxmonitorv2/integrations_test.go index 2dacac5428..40bdf71743 100644 --- a/core/services/fluxmonitorv2/integrations_test.go +++ b/core/services/fluxmonitorv2/integrations_test.go @@ -26,6 +26,7 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" @@ -35,7 +36,6 @@ import ( faw "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -45,6 +45,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/web" ) diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go index 6defdeeb61..b6af86df33 100644 --- a/core/services/job/job_orm_test.go +++ b/core/services/job/job_orm_test.go @@ -26,7 +26,6 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" @@ -48,6 +47,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) const mercuryOracleTOML = `name = 'LINK / ETH | 0x0000000000000000000000000000000000000000000000000000000000000001 | verifier_proxy 0x0000000000000000000000000000000000000001' diff --git a/core/services/keeper/integration_test.go b/core/services/keeper/integration_test.go index cbbe89b3f2..494e0a1615 100644 --- a/core/services/keeper/integration_test.go +++ b/core/services/keeper/integration_test.go @@ -17,6 +17,7 @@ import ( "github.com/stretchr/testify/require" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/forwarders" @@ -30,12 +31,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_3" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keeper" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" webpresenters "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go index fe9021e4c1..676ae79e35 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go @@ -49,7 +49,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -75,6 +74,7 @@ import ( evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" clutils "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" "github.com/smartcontractkit/chainlink/v2/plugins" ) diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go index 25be1c2a9a..2569aa5324 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go @@ -48,7 +48,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" @@ -73,6 +72,7 @@ import ( evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" clutils "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" "github.com/smartcontractkit/chainlink/v2/plugins" ) diff --git a/core/services/ocr2/plugins/functions/config/config_types.pb.go b/core/services/ocr2/plugins/functions/config/config_types.pb.go index b9debdcd46..2e749c95e3 100644 --- a/core/services/ocr2/plugins/functions/config/config_types.pb.go +++ b/core/services/ocr2/plugins/functions/config/config_types.pb.go @@ -7,10 +7,11 @@ package config import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/core/services/ocr2/plugins/functions/encoding/ocr_types.pb.go b/core/services/ocr2/plugins/functions/encoding/ocr_types.pb.go index 4022076334..ad60927c3f 100644 --- a/core/services/ocr2/plugins/functions/encoding/ocr_types.pb.go +++ b/core/services/ocr2/plugins/functions/encoding/ocr_types.pb.go @@ -7,10 +7,11 @@ package encoding import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go index ef81028f20..104e9f4da6 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go +++ b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go @@ -29,6 +29,7 @@ import ( ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" @@ -39,7 +40,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/functions" @@ -50,6 +50,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) var nilOpts *bind.CallOpts diff --git a/core/services/ocr2/plugins/llo/helpers_test.go b/core/services/ocr2/plugins/llo/helpers_test.go index 1d85a6f0ec..23a0cc7064 100644 --- a/core/services/ocr2/plugins/llo/helpers_test.go +++ b/core/services/ocr2/plugins/llo/helpers_test.go @@ -40,7 +40,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/destination_verifier" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/destination_verifier_proxy" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/keystest" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -55,6 +54,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" "github.com/smartcontractkit/chainlink/v2/core/services/streams" "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) var _ pb.MercuryServer = &mercuryServer{} diff --git a/core/services/ocr2/plugins/mercury/helpers_test.go b/core/services/ocr2/plugins/mercury/helpers_test.go index 9691e8d4fa..6a01bcf8c0 100644 --- a/core/services/ocr2/plugins/mercury/helpers_test.go +++ b/core/services/ocr2/plugins/mercury/helpers_test.go @@ -27,9 +27,9 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/keystest" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -42,6 +42,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) var _ pb.MercuryServer = &mercuryServer{} diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go index 9942609395..49741b7911 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go @@ -25,12 +25,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_upkeep_counter_wrapper" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" evmregistry21 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) func TestIntegration_LogEventProvider(t *testing.T) { diff --git a/core/services/ocr2/plugins/ocr2keeper/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/integration_test.go index 2ce9ff3d24..4796c43569 100644 --- a/core/services/ocr2/plugins/ocr2keeper/integration_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/integration_test.go @@ -44,7 +44,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -59,6 +58,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) const ( diff --git a/core/services/ocr2/plugins/s4/messages.pb.go b/core/services/ocr2/plugins/s4/messages.pb.go index e629633cb1..66bbeb7dbb 100644 --- a/core/services/ocr2/plugins/s4/messages.pb.go +++ b/core/services/ocr2/plugins/s4/messages.pb.go @@ -7,10 +7,11 @@ package s4 import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/core/services/pg/lease_lock_test.go b/core/services/pg/lease_lock_test.go index 1b4116b5bf..65bbe3b861 100644 --- a/core/services/pg/lease_lock_test.go +++ b/core/services/pg/lease_lock_test.go @@ -12,11 +12,11 @@ import ( "github.com/jmoiron/sqlx" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) func newLeaseLock(t *testing.T, db *sqlx.DB, cfg pg.LeaseLockConfig) pg.LeaseLock { diff --git a/core/services/pipeline/orm_test.go b/core/services/pipeline/orm_test.go index 877aa9e4aa..f3d529d87e 100644 --- a/core/services/pipeline/orm_test.go +++ b/core/services/pipeline/orm_test.go @@ -21,7 +21,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" @@ -30,6 +29,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) type testOnlyORM interface { diff --git a/core/services/synchronization/telem/telem.pb.go b/core/services/synchronization/telem/telem.pb.go index d51b9628e2..ec1ac5ee52 100644 --- a/core/services/synchronization/telem/telem.pb.go +++ b/core/services/synchronization/telem/telem.pb.go @@ -7,10 +7,11 @@ package telem import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/core/services/synchronization/telem/telem_automation_custom.pb.go b/core/services/synchronization/telem/telem_automation_custom.pb.go index 30ddce6f79..118e76d680 100644 --- a/core/services/synchronization/telem/telem_automation_custom.pb.go +++ b/core/services/synchronization/telem/telem_automation_custom.pb.go @@ -7,10 +7,11 @@ package telem import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/core/services/synchronization/telem/telem_enhanced_ea.pb.go b/core/services/synchronization/telem/telem_enhanced_ea.pb.go index c8983a06fe..c78cd65848 100644 --- a/core/services/synchronization/telem/telem_enhanced_ea.pb.go +++ b/core/services/synchronization/telem/telem_enhanced_ea.pb.go @@ -7,10 +7,11 @@ package telem import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go b/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go index 856619e193..325c6708f9 100644 --- a/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go +++ b/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go @@ -7,10 +7,11 @@ package telem import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/core/services/synchronization/telem/telem_functions_request.pb.go b/core/services/synchronization/telem/telem_functions_request.pb.go index 89aa9e3fe3..85cf6915d8 100644 --- a/core/services/synchronization/telem/telem_functions_request.pb.go +++ b/core/services/synchronization/telem/telem_functions_request.pb.go @@ -7,10 +7,11 @@ package telem import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/core/services/synchronization/telem/telem_head_report.pb.go b/core/services/synchronization/telem/telem_head_report.pb.go index 12801314a7..a53eb6ca1d 100644 --- a/core/services/synchronization/telem/telem_head_report.pb.go +++ b/core/services/synchronization/telem/telem_head_report.pb.go @@ -7,10 +7,11 @@ package telem import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/core/services/synchronization/telem/telem_wsrpc.pb.go b/core/services/synchronization/telem/telem_wsrpc.pb.go index e4028b4de4..344ace7169 100644 --- a/core/services/synchronization/telem/telem_wsrpc.pb.go +++ b/core/services/synchronization/telem/telem_wsrpc.pb.go @@ -7,6 +7,7 @@ package telem import ( context "context" + wsrpc "github.com/smartcontractkit/wsrpc" ) diff --git a/core/services/vrf/v1/integration_test.go b/core/services/vrf/v1/integration_test.go index 74006639c6..125388b6b2 100644 --- a/core/services/vrf/v1/integration_test.go +++ b/core/services/vrf/v1/integration_test.go @@ -16,11 +16,11 @@ import ( "gopkg.in/guregu/null.v4" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_coordinator_interface" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -30,6 +30,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrftesthelpers" "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) func TestIntegration_VRF_JPV2(t *testing.T) { diff --git a/core/services/vrf/v2/bhs_feeder_test.go b/core/services/vrf/v2/bhs_feeder_test.go index b39fd0dec7..d3e0008f18 100644 --- a/core/services/vrf/v2/bhs_feeder_test.go +++ b/core/services/vrf/v2/bhs_feeder_test.go @@ -12,10 +12,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrftesthelpers" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) func TestStartHeartbeats(t *testing.T) { diff --git a/core/services/vrf/v2/integration_helpers_test.go b/core/services/vrf/v2/integration_helpers_test.go index d61779c571..2fccdb2b2e 100644 --- a/core/services/vrf/v2/integration_helpers_test.go +++ b/core/services/vrf/v2/integration_helpers_test.go @@ -30,7 +30,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_external_sub_owner_example" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2_transparent_upgradeable_proxy" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -41,6 +40,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrftesthelpers" "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) func testSingleConsumerHappyPath( diff --git a/core/services/vrf/v2/integration_v2_plus_test.go b/core/services/vrf/v2/integration_v2_plus_test.go index 53baaa0eda..764c950ec3 100644 --- a/core/services/vrf/v2/integration_v2_plus_test.go +++ b/core/services/vrf/v2/integration_v2_plus_test.go @@ -17,6 +17,7 @@ import ( "github.com/stretchr/testify/require" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -40,7 +41,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_consumer_example" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_reverting_example" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -51,6 +51,7 @@ import ( v22 "github.com/smartcontractkit/chainlink/v2/core/services/vrf/v2" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrftesthelpers" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) type coordinatorV2PlusUniverse struct { diff --git a/core/services/vrf/v2/integration_v2_reverted_txns_test.go b/core/services/vrf/v2/integration_v2_reverted_txns_test.go index 25e3afcf75..6682fe9e88 100644 --- a/core/services/vrf/v2/integration_v2_reverted_txns_test.go +++ b/core/services/vrf/v2/integration_v2_reverted_txns_test.go @@ -27,7 +27,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_external_sub_owner_example" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -37,6 +36,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) var ( diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index 178b555667..33ed5a76b5 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -63,7 +63,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2_wrapper_consumer_example" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" @@ -83,6 +82,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrftesthelpers" "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) var defaultMaxGasPrice = uint64(1e12) diff --git a/core/store/migrate/migrate_test.go b/core/store/migrate/migrate_test.go index f4e91f0a2d..adbc0ca2f6 100644 --- a/core/store/migrate/migrate_test.go +++ b/core/store/migrate/migrate_test.go @@ -19,7 +19,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/config/env" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -28,6 +27,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/store/migrate" "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" ) type OffchainReporting2OracleSpec100 struct { diff --git a/core/internal/cltest/heavyweight/orm.go b/core/utils/testutils/heavyweight/orm.go similarity index 100% rename from core/internal/cltest/heavyweight/orm.go rename to core/utils/testutils/heavyweight/orm.go diff --git a/dashboard-lib/atlas-don/component.go b/dashboard-lib/atlas-don/component.go index 39218c7aea..beda6f48ec 100644 --- a/dashboard-lib/atlas-don/component.go +++ b/dashboard-lib/atlas-don/component.go @@ -2,6 +2,7 @@ package atlas_don import ( "fmt" + "github.com/K-Phoen/grabana/dashboard" "github.com/K-Phoen/grabana/row" "github.com/K-Phoen/grabana/stat" diff --git a/dashboard-lib/ccip-load-test-view/component.go b/dashboard-lib/ccip-load-test-view/component.go index 9f58438410..790ea6e9a9 100644 --- a/dashboard-lib/ccip-load-test-view/component.go +++ b/dashboard-lib/ccip-load-test-view/component.go @@ -3,6 +3,7 @@ package ccip_load_test_view import ( "encoding/json" "fmt" + "github.com/K-Phoen/grabana/dashboard" "github.com/K-Phoen/grabana/logs" "github.com/K-Phoen/grabana/row" diff --git a/dashboard-lib/config.go b/dashboard-lib/config.go index 2e0b9cad99..386082dae0 100644 --- a/dashboard-lib/config.go +++ b/dashboard-lib/config.go @@ -2,9 +2,10 @@ package dashboard_lib import ( "encoding/base64" - "github.com/pkg/errors" "os" "strings" + + "github.com/pkg/errors" ) type EnvConfig struct { diff --git a/dashboard-lib/core-don/component.go b/dashboard-lib/core-don/component.go index 24173fb6cc..0589ab5cf8 100644 --- a/dashboard-lib/core-don/component.go +++ b/dashboard-lib/core-don/component.go @@ -2,6 +2,7 @@ package core_don import ( "fmt" + "github.com/K-Phoen/grabana/dashboard" "github.com/K-Phoen/grabana/gauge" "github.com/K-Phoen/grabana/row" diff --git a/dashboard-lib/core-ocrv2-ccip/component.go b/dashboard-lib/core-ocrv2-ccip/component.go index 837f693fcc..56b35587e1 100644 --- a/dashboard-lib/core-ocrv2-ccip/component.go +++ b/dashboard-lib/core-ocrv2-ccip/component.go @@ -2,6 +2,7 @@ package core_ocrv2_ccip import ( "fmt" + "github.com/K-Phoen/grabana/dashboard" "github.com/K-Phoen/grabana/row" "github.com/K-Phoen/grabana/target/prometheus" diff --git a/dashboard-lib/dashboard.go b/dashboard-lib/dashboard.go index 70892586bb..92c4691a5e 100644 --- a/dashboard-lib/dashboard.go +++ b/dashboard-lib/dashboard.go @@ -4,11 +4,12 @@ import ( "context" "encoding/json" "fmt" + "net/http" + "os" + "github.com/K-Phoen/grabana" "github.com/K-Phoen/grabana/dashboard" "github.com/pkg/errors" - "net/http" - "os" ) type Dashboard struct { diff --git a/integration-tests/.golangci.yml b/integration-tests/.golangci.yml index 897c72d1ec..a75f9a5e46 100644 --- a/integration-tests/.golangci.yml +++ b/integration-tests/.golangci.yml @@ -70,6 +70,9 @@ linters-settings: - name: atomic issues: exclude-rules: + - path: deployment/memory/(.+)\.go + linters: + - revive - text: "^G404: Use of weak random number generator" linters: - gosec diff --git a/integration-tests/deployment/README.md b/integration-tests/deployment/README.md new file mode 100644 index 0000000000..7e0f82b546 --- /dev/null +++ b/integration-tests/deployment/README.md @@ -0,0 +1,58 @@ +### Overview +The deployment package in the integration-tests Go module serves +as a product agnostic set of environment abstractions used +to deploy and configure products including both on/offchain +dependencies. The environment abstractions allow for +complex and critical deployment/configuration logic to be tested +against ephemeral environments and then exposed for use in persistent +environments like testnet/mainnet. + +### Directory structure + +/deployment +- package name `deployment` +- Product agnostic environment abstractions and helpers using those +abstractions + +/deployment/memory +- package name `memory` +- In-memory environment for fast integration testing +- EVM only + +/deployment/docker +- Coming soon +- package name `docker` +- Docker environment for higher fidelity testing +- Support non-EVMs + +/deployment/ccip +- package name `ccipdeployment` +- Files and tests per product deployment/configuration workflows +- Tests can use deployment/memory for fast integration testing +- TODO: System state representation is defined here, need to define +an interface to comply with for all products. + +/deployment/ccip/changeset +- package name `changeset` imported as `ccipchangesets` +- These function like scripts describing state transitions +you wish to apply to _persistent_ environments like testnet/mainnet +- Ordered list of Go functions following the format +```Go +0001_descriptive_name.go +func Apply0001(env deployment.Environment, c ccipdeployment.Config) (deployment.ChangesetOutput, error) +{ + // Deploy contracts, generate MCMS proposals, generate + // job specs according to contracts etc. + return deployment.ChangesetOutput{}, nil +} +0001_descriptive_name_test.go +func TestApply0001(t *testing.T) +{ + // Set up memory env + // Apply0001 function + // Take the artifacts from ChangeSet output + // Apply them to the memory env + // Send traffic, run assertions etc. +} +``` +- Changesets are exposed and applied via a different repo. \ No newline at end of file diff --git a/integration-tests/deployment/address_book.go b/integration-tests/deployment/address_book.go new file mode 100644 index 0000000000..4a5916111c --- /dev/null +++ b/integration-tests/deployment/address_book.go @@ -0,0 +1,158 @@ +package deployment + +import ( + "fmt" + "strings" + + "github.com/Masterminds/semver/v3" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + chainsel "github.com/smartcontractkit/chain-selectors" +) + +var ( + ErrInvalidChainSelector = fmt.Errorf("invalid chain selector") + ErrInvalidAddress = fmt.Errorf("invalid address") +) + +// ContractType is a simple string type for identifying contract types. +type ContractType string + +var ( + Version1_0_0 = *semver.MustParse("1.0.0") + Version1_1_0 = *semver.MustParse("1.1.0") + Version1_2_0 = *semver.MustParse("1.2.0") + Version1_5_0 = *semver.MustParse("1.5.0") + Version1_6_0_dev = *semver.MustParse("1.6.0-dev") +) + +type TypeAndVersion struct { + Type ContractType + Version semver.Version +} + +func (tv TypeAndVersion) String() string { + return fmt.Sprintf("%s %s", tv.Type, tv.Version.String()) +} + +func (tv TypeAndVersion) Equal(other TypeAndVersion) bool { + return tv.String() == other.String() +} + +func MustTypeAndVersionFromString(s string) TypeAndVersion { + tv, err := TypeAndVersionFromString(s) + if err != nil { + panic(err) + } + return tv +} + +// Note this will become useful for validation. When we want +// to assert an onchain call to typeAndVersion yields whats expected. +func TypeAndVersionFromString(s string) (TypeAndVersion, error) { + parts := strings.Split(s, " ") + if len(parts) != 2 { + return TypeAndVersion{}, fmt.Errorf("invalid type and version string: %s", s) + } + v, err := semver.NewVersion(parts[1]) + if err != nil { + return TypeAndVersion{}, err + } + return TypeAndVersion{ + Type: ContractType(parts[0]), + Version: *v, + }, nil +} + +func NewTypeAndVersion(t ContractType, v semver.Version) TypeAndVersion { + return TypeAndVersion{ + Type: t, + Version: v, + } +} + +// AddressBook is a simple interface for storing and retrieving contract addresses across +// chains. It is family agnostic as the keys are chain selectors. +// We store rather than derive typeAndVersion as some contracts do not support it. +// For ethereum addresses are always stored in EIP55 format. +type AddressBook interface { + Save(chainSelector uint64, address string, tv TypeAndVersion) error + Addresses() (map[uint64]map[string]TypeAndVersion, error) + AddressesForChain(chain uint64) (map[string]TypeAndVersion, error) + // Allows for merging address books (e.g. new deployments with existing ones) + Merge(other AddressBook) error +} + +type AddressBookMap struct { + AddressesByChain map[uint64]map[string]TypeAndVersion +} + +func (m *AddressBookMap) Save(chainSelector uint64, address string, typeAndVersion TypeAndVersion) error { + _, exists := chainsel.ChainBySelector(chainSelector) + if !exists { + return errors.Wrapf(ErrInvalidChainSelector, "chain selector %d not found", chainSelector) + } + if address == "" || address == common.HexToAddress("0x0").Hex() { + return errors.Wrap(ErrInvalidAddress, "address cannot be empty") + } + if common.IsHexAddress(address) { + // IMPORTANT: WE ALWAYS STANDARDIZE ETHEREUM ADDRESS STRINGS TO EIP55 + address = common.HexToAddress(address).Hex() + } else { + return errors.Wrapf(ErrInvalidAddress, "address %s is not a valid Ethereum address, only Ethereum addresses supported", address) + } + if typeAndVersion.Type == "" { + return fmt.Errorf("type cannot be empty") + } + if _, exists := m.AddressesByChain[chainSelector]; !exists { + // First time chain add, create map + m.AddressesByChain[chainSelector] = make(map[string]TypeAndVersion) + } + if _, exists := m.AddressesByChain[chainSelector][address]; exists { + return fmt.Errorf("address %s already exists for chain %d", address, chainSelector) + } + m.AddressesByChain[chainSelector][address] = typeAndVersion + return nil +} + +func (m *AddressBookMap) Addresses() (map[uint64]map[string]TypeAndVersion, error) { + return m.AddressesByChain, nil +} + +func (m *AddressBookMap) AddressesForChain(chain uint64) (map[string]TypeAndVersion, error) { + if _, exists := m.AddressesByChain[chain]; !exists { + return nil, fmt.Errorf("chain %d not found", chain) + } + return m.AddressesByChain[chain], nil +} + +// Attention this will mutate existing book +func (m *AddressBookMap) Merge(ab AddressBook) error { + addresses, err := ab.Addresses() + if err != nil { + return err + } + for chain, chainAddresses := range addresses { + for address, typeAndVersions := range chainAddresses { + if err := m.Save(chain, address, typeAndVersions); err != nil { + return err + } + } + } + return nil +} + +// TODO: Maybe could add an environment argument +// which would ensure only mainnet/testnet chain selectors are used +// for further safety? +func NewMemoryAddressBook() *AddressBookMap { + return &AddressBookMap{ + AddressesByChain: make(map[uint64]map[string]TypeAndVersion), + } +} + +func NewMemoryAddressBookFromMap(addressesByChain map[uint64]map[string]TypeAndVersion) *AddressBookMap { + return &AddressBookMap{ + AddressesByChain: addressesByChain, + } +} diff --git a/integration-tests/deployment/address_book_test.go b/integration-tests/deployment/address_book_test.go new file mode 100644 index 0000000000..c6967df0ca --- /dev/null +++ b/integration-tests/deployment/address_book_test.go @@ -0,0 +1,112 @@ +package deployment + +import ( + "errors" + "testing" + + "github.com/ethereum/go-ethereum/common" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" + "gotest.tools/v3/assert" +) + +func TestAddressBook_Save(t *testing.T) { + ab := NewMemoryAddressBook() + onRamp100 := NewTypeAndVersion("OnRamp", Version1_0_0) + onRamp110 := NewTypeAndVersion("OnRamp", Version1_1_0) + addr1 := common.HexToAddress("0x1").String() + addr2 := common.HexToAddress("0x2").String() + + err := ab.Save(chainsel.TEST_90000001.Selector, addr1, onRamp100) + require.NoError(t, err) + + // Check input validation + err = ab.Save(chainsel.TEST_90000001.Selector, "asdlfkj", onRamp100) + require.Error(t, err) + assert.Equal(t, errors.Is(err, ErrInvalidAddress), true, "err %s", err) + err = ab.Save(0, addr1, onRamp100) + require.Error(t, err) + assert.Equal(t, errors.Is(err, ErrInvalidChainSelector), true) + // Duplicate + err = ab.Save(chainsel.TEST_90000001.Selector, addr1, onRamp100) + require.Error(t, err) + // Zero address + err = ab.Save(chainsel.TEST_90000001.Selector, common.HexToAddress("0x0").Hex(), onRamp100) + require.Error(t, err) + + // Distinct address same TV will not + err = ab.Save(chainsel.TEST_90000001.Selector, addr2, onRamp100) + require.NoError(t, err) + // Same address different chain will not error + err = ab.Save(chainsel.TEST_90000002.Selector, addr1, onRamp100) + require.NoError(t, err) + // We can save different versions of the same contract + err = ab.Save(chainsel.TEST_90000002.Selector, addr2, onRamp110) + require.NoError(t, err) + + addresses, err := ab.Addresses() + require.NoError(t, err) + assert.DeepEqual(t, addresses, map[uint64]map[string]TypeAndVersion{ + chainsel.TEST_90000001.Selector: { + addr1: onRamp100, + addr2: onRamp100, + }, + chainsel.TEST_90000002.Selector: { + addr1: onRamp100, + addr2: onRamp110, + }, + }) +} + +func TestAddressBook_Merge(t *testing.T) { + onRamp100 := NewTypeAndVersion("OnRamp", Version1_0_0) + onRamp110 := NewTypeAndVersion("OnRamp", Version1_1_0) + addr1 := common.HexToAddress("0x1").String() + addr2 := common.HexToAddress("0x2").String() + a1 := NewMemoryAddressBookFromMap(map[uint64]map[string]TypeAndVersion{ + chainsel.TEST_90000001.Selector: { + addr1: onRamp100, + }, + }) + a2 := NewMemoryAddressBookFromMap(map[uint64]map[string]TypeAndVersion{ + chainsel.TEST_90000001.Selector: { + addr2: onRamp100, + }, + chainsel.TEST_90000002.Selector: { + addr1: onRamp110, + }, + }) + require.NoError(t, a1.Merge(a2)) + + addresses, err := a1.Addresses() + require.NoError(t, err) + assert.DeepEqual(t, addresses, map[uint64]map[string]TypeAndVersion{ + chainsel.TEST_90000001.Selector: { + addr1: onRamp100, + addr2: onRamp100, + }, + chainsel.TEST_90000002.Selector: { + addr1: onRamp110, + }, + }) + + // Merge with conflicting addresses should error + a3 := NewMemoryAddressBookFromMap(map[uint64]map[string]TypeAndVersion{ + chainsel.TEST_90000001.Selector: { + addr1: onRamp100, + }, + }) + require.Error(t, a1.Merge(a3)) + // a1 should not have changed + addresses, err = a1.Addresses() + require.NoError(t, err) + assert.DeepEqual(t, addresses, map[uint64]map[string]TypeAndVersion{ + chainsel.TEST_90000001.Selector: { + addr1: onRamp100, + addr2: onRamp100, + }, + chainsel.TEST_90000002.Selector: { + addr1: onRamp110, + }, + }) +} diff --git a/integration-tests/deployment/changeset.go b/integration-tests/deployment/changeset.go new file mode 100644 index 0000000000..d929022ed9 --- /dev/null +++ b/integration-tests/deployment/changeset.go @@ -0,0 +1,28 @@ +package deployment + +import ( + owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" +) + +// TODO: Move to real MCM structs once available. +type Proposal struct { + // keccak256(abi.encode(root, validUntil)) is what is signed by MCMS + // signers. + ValidUntil uint32 + // Leaves are the items in the proposal. + // Uses these to generate the root as well as display whats in the root. + // These Ops may be destined for distinct chains. + Ops []owner_wrappers.ManyChainMultiSigOp +} + +func (p Proposal) String() string { + // TODO + return "" +} + +// Services as input to CI/Async tasks +type ChangesetOutput struct { + JobSpecs map[string][]string + Proposals []Proposal + AddressBook AddressBook +} diff --git a/integration-tests/deployment/environment.go b/integration-tests/deployment/environment.go new file mode 100644 index 0000000000..e06bcb1dda --- /dev/null +++ b/integration-tests/deployment/environment.go @@ -0,0 +1,195 @@ +package deployment + +import ( + "context" + "errors" + "fmt" + "math/big" + "strconv" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" + chain_selectors "github.com/smartcontractkit/chain-selectors" + types2 "github.com/smartcontractkit/libocr/offchainreporting2/types" + types3 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" + nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" +) + +type OnchainClient interface { + // For EVM specifically we can use existing geth interface + // to abstract chain clients. + bind.ContractBackend +} + +type OffchainClient interface { + // The job distributor grpc interface can be used to abstract offchain read/writes + jobv1.JobServiceClient + nodev1.NodeServiceClient +} + +type Chain struct { + // Selectors used as canonical chain identifier. + Selector uint64 + Client OnchainClient + // Note the Sign function can be abstract supporting a variety of key storage mechanisms (e.g. KMS etc). + DeployerKey *bind.TransactOpts + Confirm func(tx common.Hash) (uint64, error) +} + +type Environment struct { + Name string + Chains map[uint64]Chain + Offchain OffchainClient + NodeIDs []string + Logger logger.Logger +} + +func (e Environment) AllChainSelectors() []uint64 { + var selectors []uint64 + for sel := range e.Chains { + selectors = append(selectors, sel) + } + return selectors +} + +func ConfirmIfNoError(chain Chain, tx *types.Transaction, err error) (uint64, error) { + if err != nil { + //revive:disable + var d rpc.DataError + ok := errors.As(err, &d) + if ok { + return 0, fmt.Errorf("got Data Error: %s", d.ErrorData()) + } + return 0, err + } + return chain.Confirm(tx.Hash()) +} + +func MaybeDataErr(err error) error { + //revive:disable + var d rpc.DataError + ok := errors.As(err, &d) + if ok { + return d + } + return err +} + +func UBigInt(i uint64) *big.Int { + return new(big.Int).SetUint64(i) +} + +func E18Mult(amount uint64) *big.Int { + return new(big.Int).Mul(UBigInt(amount), UBigInt(1e18)) +} + +type OCRConfig struct { + OffchainPublicKey types2.OffchainPublicKey + // For EVM-chains, this an *address*. + OnchainPublicKey types2.OnchainPublicKey + PeerID p2pkey.PeerID + TransmitAccount types2.Account + ConfigEncryptionPublicKey types3.ConfigEncryptionPublicKey + IsBootstrap bool + MultiAddr string // TODO: type +} + +type Nodes []Node + +func (n Nodes) PeerIDs(chainSel uint64) [][32]byte { + var peerIDs [][32]byte + for _, node := range n { + cfg := node.SelToOCRConfig[chainSel] + // NOTE: Assume same peerID for all chains. + // Might make sense to change proto as peerID is 1-1 with node? + peerIDs = append(peerIDs, cfg.PeerID) + } + return peerIDs +} + +func (n Nodes) BootstrapPeerIDs(chainSel uint64) [][32]byte { + var peerIDs [][32]byte + for _, node := range n { + cfg := node.SelToOCRConfig[chainSel] + if !cfg.IsBootstrap { + continue + } + peerIDs = append(peerIDs, cfg.PeerID) + } + return peerIDs +} + +// OffchainPublicKey types.OffchainPublicKey +// // For EVM-chains, this an *address*. +// OnchainPublicKey types.OnchainPublicKey +// PeerID string +// TransmitAccount types.Account +type Node struct { + SelToOCRConfig map[uint64]OCRConfig +} + +func MustPeerIDFromString(s string) p2pkey.PeerID { + p := p2pkey.PeerID{} + if err := p.UnmarshalString(s); err != nil { + panic(err) + } + return p +} + +// Gathers all the node info through JD required to be able to set +// OCR config for example. +func NodeInfo(nodeIDs []string, oc OffchainClient) (Nodes, error) { + var nodes []Node + for _, node := range nodeIDs { + // TODO: Filter should accept multiple nodes + nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ + NodeId: node, + }}) + if err != nil { + return nil, err + } + selToOCRConfig := make(map[uint64]OCRConfig) + for _, chainConfig := range nodeChainConfigs.ChainConfigs { + if chainConfig.Chain.Type == nodev1.ChainType_CHAIN_TYPE_SOLANA { + // Note supported for CCIP yet. + continue + } + evmChainID, err := strconv.Atoi(chainConfig.Chain.Id) + if err != nil { + return nil, err + } + sel, err := chain_selectors.SelectorFromChainId(uint64(evmChainID)) + if err != nil { + return nil, err + } + b := common.Hex2Bytes(chainConfig.Ocr2Config.OcrKeyBundle.OffchainPublicKey) + var opk types2.OffchainPublicKey + copy(opk[:], b) + + b = common.Hex2Bytes(chainConfig.Ocr2Config.OcrKeyBundle.ConfigPublicKey) + var cpk types3.ConfigEncryptionPublicKey + copy(cpk[:], b) + + selToOCRConfig[sel] = OCRConfig{ + OffchainPublicKey: opk, + OnchainPublicKey: common.HexToAddress(chainConfig.Ocr2Config.OcrKeyBundle.OnchainSigningAddress).Bytes(), + PeerID: MustPeerIDFromString(chainConfig.Ocr2Config.P2PKeyBundle.PeerId), + TransmitAccount: types2.Account(chainConfig.AccountAddress), + ConfigEncryptionPublicKey: cpk, + IsBootstrap: chainConfig.Ocr2Config.IsBootstrap, + MultiAddr: chainConfig.Ocr2Config.Multiaddr, + } + } + nodes = append(nodes, Node{ + SelToOCRConfig: selToOCRConfig, + }) + } + return nodes, nil +} diff --git a/integration-tests/deployment/jd/job/v1/job.pb.go b/integration-tests/deployment/jd/job/v1/job.pb.go new file mode 100644 index 0000000000..788888b4c7 --- /dev/null +++ b/integration-tests/deployment/jd/job/v1/job.pb.go @@ -0,0 +1,1768 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.29.0 +// protoc v4.25.3 +// source: job/v1/job.proto + +package v1 + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// ProposalStatus defines the possible states of a job proposal. +type ProposalStatus int32 + +const ( + ProposalStatus_PROPOSAL_STATUS_UNSPECIFIED ProposalStatus = 0 + ProposalStatus_PROPOSAL_STATUS_PROPOSED ProposalStatus = 1 // Proposal has been made but not yet decided upon. + ProposalStatus_PROPOSAL_STATUS_APPROVED ProposalStatus = 2 // Proposal has been accepted. + ProposalStatus_PROPOSAL_STATUS_REJECTED ProposalStatus = 3 // Proposal has been rejected. + ProposalStatus_PROPOSAL_STATUS_CANCELLED ProposalStatus = 4 // Proposal has been cancelled. + ProposalStatus_PROPOSAL_STATUS_PENDING ProposalStatus = 5 // Proposal is pending review. + ProposalStatus_PROPOSAL_STATUS_REVOKED ProposalStatus = 6 // Proposal has been revoked after being proposed. +) + +// Enum value maps for ProposalStatus. +var ( + ProposalStatus_name = map[int32]string{ + 0: "PROPOSAL_STATUS_UNSPECIFIED", + 1: "PROPOSAL_STATUS_PROPOSED", + 2: "PROPOSAL_STATUS_APPROVED", + 3: "PROPOSAL_STATUS_REJECTED", + 4: "PROPOSAL_STATUS_CANCELLED", + 5: "PROPOSAL_STATUS_PENDING", + 6: "PROPOSAL_STATUS_REVOKED", + } + ProposalStatus_value = map[string]int32{ + "PROPOSAL_STATUS_UNSPECIFIED": 0, + "PROPOSAL_STATUS_PROPOSED": 1, + "PROPOSAL_STATUS_APPROVED": 2, + "PROPOSAL_STATUS_REJECTED": 3, + "PROPOSAL_STATUS_CANCELLED": 4, + "PROPOSAL_STATUS_PENDING": 5, + "PROPOSAL_STATUS_REVOKED": 6, + } +) + +func (x ProposalStatus) Enum() *ProposalStatus { + p := new(ProposalStatus) + *p = x + return p +} + +func (x ProposalStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProposalStatus) Descriptor() protoreflect.EnumDescriptor { + return file_job_v1_job_proto_enumTypes[0].Descriptor() +} + +func (ProposalStatus) Type() protoreflect.EnumType { + return &file_job_v1_job_proto_enumTypes[0] +} + +func (x ProposalStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ProposalStatus.Descriptor instead. +func (ProposalStatus) EnumDescriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{0} +} + +// ProposalDeliveryStatus defines the delivery status of the proposal to the node. +type ProposalDeliveryStatus int32 + +const ( + ProposalDeliveryStatus_PROPOSAL_DELIVERY_STATUS_UNSPECIFIED ProposalDeliveryStatus = 0 + ProposalDeliveryStatus_PROPOSAL_DELIVERY_STATUS_DELIVERED ProposalDeliveryStatus = 1 // Delivered to the node. + ProposalDeliveryStatus_PROPOSAL_DELIVERY_STATUS_ACKNOWLEDGED ProposalDeliveryStatus = 2 // Acknowledged by the node. + ProposalDeliveryStatus_PROPOSAL_DELIVERY_STATUS_FAILED ProposalDeliveryStatus = 3 // Delivery failed. +) + +// Enum value maps for ProposalDeliveryStatus. +var ( + ProposalDeliveryStatus_name = map[int32]string{ + 0: "PROPOSAL_DELIVERY_STATUS_UNSPECIFIED", + 1: "PROPOSAL_DELIVERY_STATUS_DELIVERED", + 2: "PROPOSAL_DELIVERY_STATUS_ACKNOWLEDGED", + 3: "PROPOSAL_DELIVERY_STATUS_FAILED", + } + ProposalDeliveryStatus_value = map[string]int32{ + "PROPOSAL_DELIVERY_STATUS_UNSPECIFIED": 0, + "PROPOSAL_DELIVERY_STATUS_DELIVERED": 1, + "PROPOSAL_DELIVERY_STATUS_ACKNOWLEDGED": 2, + "PROPOSAL_DELIVERY_STATUS_FAILED": 3, + } +) + +func (x ProposalDeliveryStatus) Enum() *ProposalDeliveryStatus { + p := new(ProposalDeliveryStatus) + *p = x + return p +} + +func (x ProposalDeliveryStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProposalDeliveryStatus) Descriptor() protoreflect.EnumDescriptor { + return file_job_v1_job_proto_enumTypes[1].Descriptor() +} + +func (ProposalDeliveryStatus) Type() protoreflect.EnumType { + return &file_job_v1_job_proto_enumTypes[1] +} + +func (x ProposalDeliveryStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ProposalDeliveryStatus.Descriptor instead. +func (ProposalDeliveryStatus) EnumDescriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{1} +} + +// Job represents the structured data of a job within the system. +type Job struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier for the job. + Uuid string `protobuf:"bytes,2,opt,name=uuid,proto3" json:"uuid,omitempty"` // Universally unique identifier for the job. + NodeId string `protobuf:"bytes,3,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` // ID of the node associated with this job. + ProposalIds []string `protobuf:"bytes,4,rep,name=proposal_ids,json=proposalIds,proto3" json:"proposal_ids,omitempty"` // List of proposal IDs associated with this job. + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Timestamp when the job was created. + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // Timestamp when the job was last updated. + DeletedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=deleted_at,json=deletedAt,proto3" json:"deleted_at,omitempty"` // Timestamp when the job was deleted, if applicable. +} + +func (x *Job) Reset() { + *x = Job{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Job) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Job) ProtoMessage() {} + +func (x *Job) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Job.ProtoReflect.Descriptor instead. +func (*Job) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{0} +} + +func (x *Job) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Job) GetUuid() string { + if x != nil { + return x.Uuid + } + return "" +} + +func (x *Job) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +func (x *Job) GetProposalIds() []string { + if x != nil { + return x.ProposalIds + } + return nil +} + +func (x *Job) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Job) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *Job) GetDeletedAt() *timestamppb.Timestamp { + if x != nil { + return x.DeletedAt + } + return nil +} + +// Proposal represents a job proposal. +type Proposal struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier for the proposal. + Version int64 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"` // Version number of the proposal. + Status ProposalStatus `protobuf:"varint,3,opt,name=status,proto3,enum=api.job.v1.ProposalStatus" json:"status,omitempty"` // Current status of the proposal. + DeliveryStatus ProposalDeliveryStatus `protobuf:"varint,4,opt,name=delivery_status,json=deliveryStatus,proto3,enum=api.job.v1.ProposalDeliveryStatus" json:"delivery_status,omitempty"` // Delivery status of the proposal. + Spec string `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` // Specification of the job proposed. + JobId string `protobuf:"bytes,6,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` // ID of the job associated with this proposal. + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Timestamp when the proposal was created. + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // Timestamp when the proposal was last updated. + AckedAt *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=acked_at,json=ackedAt,proto3,oneof" json:"acked_at,omitempty"` // Timestamp when the proposal was acknowledged. + ResponseReceivedAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=response_received_at,json=responseReceivedAt,proto3,oneof" json:"response_received_at,omitempty"` // Timestamp when a response was received. +} + +func (x *Proposal) Reset() { + *x = Proposal{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Proposal) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Proposal) ProtoMessage() {} + +func (x *Proposal) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Proposal.ProtoReflect.Descriptor instead. +func (*Proposal) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{1} +} + +func (x *Proposal) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Proposal) GetVersion() int64 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *Proposal) GetStatus() ProposalStatus { + if x != nil { + return x.Status + } + return ProposalStatus_PROPOSAL_STATUS_UNSPECIFIED +} + +func (x *Proposal) GetDeliveryStatus() ProposalDeliveryStatus { + if x != nil { + return x.DeliveryStatus + } + return ProposalDeliveryStatus_PROPOSAL_DELIVERY_STATUS_UNSPECIFIED +} + +func (x *Proposal) GetSpec() string { + if x != nil { + return x.Spec + } + return "" +} + +func (x *Proposal) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +func (x *Proposal) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Proposal) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *Proposal) GetAckedAt() *timestamppb.Timestamp { + if x != nil { + return x.AckedAt + } + return nil +} + +func (x *Proposal) GetResponseReceivedAt() *timestamppb.Timestamp { + if x != nil { + return x.ResponseReceivedAt + } + return nil +} + +// GetJobRequest specifies the criteria for retrieving a job. +type GetJobRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to IdOneof: + // + // *GetJobRequest_Id + // *GetJobRequest_Uuid + IdOneof isGetJobRequest_IdOneof `protobuf_oneof:"id_oneof"` +} + +func (x *GetJobRequest) Reset() { + *x = GetJobRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetJobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetJobRequest) ProtoMessage() {} + +func (x *GetJobRequest) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetJobRequest.ProtoReflect.Descriptor instead. +func (*GetJobRequest) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{2} +} + +func (m *GetJobRequest) GetIdOneof() isGetJobRequest_IdOneof { + if m != nil { + return m.IdOneof + } + return nil +} + +func (x *GetJobRequest) GetId() string { + if x, ok := x.GetIdOneof().(*GetJobRequest_Id); ok { + return x.Id + } + return "" +} + +func (x *GetJobRequest) GetUuid() string { + if x, ok := x.GetIdOneof().(*GetJobRequest_Uuid); ok { + return x.Uuid + } + return "" +} + +type isGetJobRequest_IdOneof interface { + isGetJobRequest_IdOneof() +} + +type GetJobRequest_Id struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3,oneof"` // Unique identifier of the job. +} + +type GetJobRequest_Uuid struct { + Uuid string `protobuf:"bytes,2,opt,name=uuid,proto3,oneof"` // Universally unique identifier of the job. +} + +func (*GetJobRequest_Id) isGetJobRequest_IdOneof() {} + +func (*GetJobRequest_Uuid) isGetJobRequest_IdOneof() {} + +// GetJobResponse contains the job details. +type GetJobResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Job *Job `protobuf:"bytes,1,opt,name=job,proto3" json:"job,omitempty"` // Details of the retrieved job. +} + +func (x *GetJobResponse) Reset() { + *x = GetJobResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetJobResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetJobResponse) ProtoMessage() {} + +func (x *GetJobResponse) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetJobResponse.ProtoReflect.Descriptor instead. +func (*GetJobResponse) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{3} +} + +func (x *GetJobResponse) GetJob() *Job { + if x != nil { + return x.Job + } + return nil +} + +// GetProposalRequest specifies the criteria for retrieving a proposal. +type GetProposalRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier of the proposal to retrieve. +} + +func (x *GetProposalRequest) Reset() { + *x = GetProposalRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProposalRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProposalRequest) ProtoMessage() {} + +func (x *GetProposalRequest) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProposalRequest.ProtoReflect.Descriptor instead. +func (*GetProposalRequest) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{4} +} + +func (x *GetProposalRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// GetProposalResponse contains the proposal details. +type GetProposalResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Proposal *Proposal `protobuf:"bytes,1,opt,name=proposal,proto3" json:"proposal,omitempty"` // Details of the retrieved proposal. +} + +func (x *GetProposalResponse) Reset() { + *x = GetProposalResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProposalResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProposalResponse) ProtoMessage() {} + +func (x *GetProposalResponse) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProposalResponse.ProtoReflect.Descriptor instead. +func (*GetProposalResponse) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{5} +} + +func (x *GetProposalResponse) GetProposal() *Proposal { + if x != nil { + return x.Proposal + } + return nil +} + +// ListJobsRequest specifies filters for listing jobs. +type ListJobsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Filter *ListJobsRequest_Filter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` // Filters applied to the job listing. +} + +func (x *ListJobsRequest) Reset() { + *x = ListJobsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListJobsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListJobsRequest) ProtoMessage() {} + +func (x *ListJobsRequest) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListJobsRequest.ProtoReflect.Descriptor instead. +func (*ListJobsRequest) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{6} +} + +func (x *ListJobsRequest) GetFilter() *ListJobsRequest_Filter { + if x != nil { + return x.Filter + } + return nil +} + +// ListJobsResponse contains a list of jobs that match the filters. +type ListJobsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Jobs []*Job `protobuf:"bytes,1,rep,name=jobs,proto3" json:"jobs,omitempty"` // List of jobs. +} + +func (x *ListJobsResponse) Reset() { + *x = ListJobsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListJobsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListJobsResponse) ProtoMessage() {} + +func (x *ListJobsResponse) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListJobsResponse.ProtoReflect.Descriptor instead. +func (*ListJobsResponse) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{7} +} + +func (x *ListJobsResponse) GetJobs() []*Job { + if x != nil { + return x.Jobs + } + return nil +} + +// ListProposalsRequest specifies filters for listing proposals. +type ListProposalsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Filter *ListProposalsRequest_Filter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` // Filters applied to the proposal listing. +} + +func (x *ListProposalsRequest) Reset() { + *x = ListProposalsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListProposalsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListProposalsRequest) ProtoMessage() {} + +func (x *ListProposalsRequest) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListProposalsRequest.ProtoReflect.Descriptor instead. +func (*ListProposalsRequest) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{8} +} + +func (x *ListProposalsRequest) GetFilter() *ListProposalsRequest_Filter { + if x != nil { + return x.Filter + } + return nil +} + +// ListProposalsResponse contains a list of proposals that match the filters. +type ListProposalsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Proposals []*Proposal `protobuf:"bytes,1,rep,name=proposals,proto3" json:"proposals,omitempty"` // List of proposals. +} + +func (x *ListProposalsResponse) Reset() { + *x = ListProposalsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListProposalsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListProposalsResponse) ProtoMessage() {} + +func (x *ListProposalsResponse) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListProposalsResponse.ProtoReflect.Descriptor instead. +func (*ListProposalsResponse) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{9} +} + +func (x *ListProposalsResponse) GetProposals() []*Proposal { + if x != nil { + return x.Proposals + } + return nil +} + +// ProposeJobRequest contains the information needed to submit a new job proposal. +type ProposeJobRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` // ID of the node to which the job is proposed. + Spec string `protobuf:"bytes,2,opt,name=spec,proto3" json:"spec,omitempty"` // Specification of the job being proposed. +} + +func (x *ProposeJobRequest) Reset() { + *x = ProposeJobRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProposeJobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProposeJobRequest) ProtoMessage() {} + +func (x *ProposeJobRequest) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProposeJobRequest.ProtoReflect.Descriptor instead. +func (*ProposeJobRequest) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{10} +} + +func (x *ProposeJobRequest) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +func (x *ProposeJobRequest) GetSpec() string { + if x != nil { + return x.Spec + } + return "" +} + +// ProposeJobResponse returns the newly created proposal. +type ProposeJobResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Proposal *Proposal `protobuf:"bytes,1,opt,name=proposal,proto3" json:"proposal,omitempty"` // Details of the newly created proposal. +} + +func (x *ProposeJobResponse) Reset() { + *x = ProposeJobResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProposeJobResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProposeJobResponse) ProtoMessage() {} + +func (x *ProposeJobResponse) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProposeJobResponse.ProtoReflect.Descriptor instead. +func (*ProposeJobResponse) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{11} +} + +func (x *ProposeJobResponse) GetProposal() *Proposal { + if x != nil { + return x.Proposal + } + return nil +} + +// RevokeJobRequest specifies the criteria for revoking a job proposal. +type RevokeJobRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to IdOneof: + // + // *RevokeJobRequest_Id + // *RevokeJobRequest_Uuid + IdOneof isRevokeJobRequest_IdOneof `protobuf_oneof:"id_oneof"` +} + +func (x *RevokeJobRequest) Reset() { + *x = RevokeJobRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RevokeJobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RevokeJobRequest) ProtoMessage() {} + +func (x *RevokeJobRequest) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RevokeJobRequest.ProtoReflect.Descriptor instead. +func (*RevokeJobRequest) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{12} +} + +func (m *RevokeJobRequest) GetIdOneof() isRevokeJobRequest_IdOneof { + if m != nil { + return m.IdOneof + } + return nil +} + +func (x *RevokeJobRequest) GetId() string { + if x, ok := x.GetIdOneof().(*RevokeJobRequest_Id); ok { + return x.Id + } + return "" +} + +func (x *RevokeJobRequest) GetUuid() string { + if x, ok := x.GetIdOneof().(*RevokeJobRequest_Uuid); ok { + return x.Uuid + } + return "" +} + +type isRevokeJobRequest_IdOneof interface { + isRevokeJobRequest_IdOneof() +} + +type RevokeJobRequest_Id struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3,oneof"` // Unique identifier of the proposal to revoke. +} + +type RevokeJobRequest_Uuid struct { + Uuid string `protobuf:"bytes,2,opt,name=uuid,proto3,oneof"` // Universally unique identifier of the proposal to revoke. +} + +func (*RevokeJobRequest_Id) isRevokeJobRequest_IdOneof() {} + +func (*RevokeJobRequest_Uuid) isRevokeJobRequest_IdOneof() {} + +// RevokeJobResponse returns the revoked proposal. +type RevokeJobResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Proposal *Proposal `protobuf:"bytes,1,opt,name=proposal,proto3" json:"proposal,omitempty"` // Details of the revoked proposal. +} + +func (x *RevokeJobResponse) Reset() { + *x = RevokeJobResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RevokeJobResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RevokeJobResponse) ProtoMessage() {} + +func (x *RevokeJobResponse) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RevokeJobResponse.ProtoReflect.Descriptor instead. +func (*RevokeJobResponse) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{13} +} + +func (x *RevokeJobResponse) GetProposal() *Proposal { + if x != nil { + return x.Proposal + } + return nil +} + +// DeleteJobRequest specifies the criteria for deleting a job. +type DeleteJobRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to IdOneof: + // + // *DeleteJobRequest_Id + // *DeleteJobRequest_Uuid + IdOneof isDeleteJobRequest_IdOneof `protobuf_oneof:"id_oneof"` +} + +func (x *DeleteJobRequest) Reset() { + *x = DeleteJobRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteJobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteJobRequest) ProtoMessage() {} + +func (x *DeleteJobRequest) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteJobRequest.ProtoReflect.Descriptor instead. +func (*DeleteJobRequest) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{14} +} + +func (m *DeleteJobRequest) GetIdOneof() isDeleteJobRequest_IdOneof { + if m != nil { + return m.IdOneof + } + return nil +} + +func (x *DeleteJobRequest) GetId() string { + if x, ok := x.GetIdOneof().(*DeleteJobRequest_Id); ok { + return x.Id + } + return "" +} + +func (x *DeleteJobRequest) GetUuid() string { + if x, ok := x.GetIdOneof().(*DeleteJobRequest_Uuid); ok { + return x.Uuid + } + return "" +} + +type isDeleteJobRequest_IdOneof interface { + isDeleteJobRequest_IdOneof() +} + +type DeleteJobRequest_Id struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3,oneof"` // Unique identifier of the job to delete. +} + +type DeleteJobRequest_Uuid struct { + Uuid string `protobuf:"bytes,2,opt,name=uuid,proto3,oneof"` // Universally unique identifier of the job to delete. +} + +func (*DeleteJobRequest_Id) isDeleteJobRequest_IdOneof() {} + +func (*DeleteJobRequest_Uuid) isDeleteJobRequest_IdOneof() {} + +// DeleteJobResponse returns details of the deleted job. +type DeleteJobResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Job *Job `protobuf:"bytes,1,opt,name=job,proto3" json:"job,omitempty"` // Details of the deleted job. +} + +func (x *DeleteJobResponse) Reset() { + *x = DeleteJobResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteJobResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteJobResponse) ProtoMessage() {} + +func (x *DeleteJobResponse) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteJobResponse.ProtoReflect.Descriptor instead. +func (*DeleteJobResponse) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{15} +} + +func (x *DeleteJobResponse) GetJob() *Job { + if x != nil { + return x.Job + } + return nil +} + +type ListJobsRequest_Filter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"` // Filter by job IDs. + NodeIds []string `protobuf:"bytes,2,rep,name=node_ids,json=nodeIds,proto3" json:"node_ids,omitempty"` // Filter by node IDs. +} + +func (x *ListJobsRequest_Filter) Reset() { + *x = ListJobsRequest_Filter{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListJobsRequest_Filter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListJobsRequest_Filter) ProtoMessage() {} + +func (x *ListJobsRequest_Filter) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListJobsRequest_Filter.ProtoReflect.Descriptor instead. +func (*ListJobsRequest_Filter) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{6, 0} +} + +func (x *ListJobsRequest_Filter) GetIds() []string { + if x != nil { + return x.Ids + } + return nil +} + +func (x *ListJobsRequest_Filter) GetNodeIds() []string { + if x != nil { + return x.NodeIds + } + return nil +} + +type ListProposalsRequest_Filter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"` // Filter by proposal IDs. + JobIds []string `protobuf:"bytes,2,rep,name=job_ids,json=jobIds,proto3" json:"job_ids,omitempty"` // Filter by job IDs. +} + +func (x *ListProposalsRequest_Filter) Reset() { + *x = ListProposalsRequest_Filter{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListProposalsRequest_Filter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListProposalsRequest_Filter) ProtoMessage() {} + +func (x *ListProposalsRequest_Filter) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListProposalsRequest_Filter.ProtoReflect.Descriptor instead. +func (*ListProposalsRequest_Filter) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{8, 0} +} + +func (x *ListProposalsRequest_Filter) GetIds() []string { + if x != nil { + return x.Ids + } + return nil +} + +func (x *ListProposalsRequest_Filter) GetJobIds() []string { + if x != nil { + return x.JobIds + } + return nil +} + +var File_job_v1_job_proto protoreflect.FileDescriptor + +var file_job_v1_job_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x6a, 0x6f, 0x62, 0x2f, 0x76, 0x31, 0x2f, 0x6a, 0x6f, 0x62, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x0a, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x1a, 0x1f, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0x96, 0x02, 0x0a, 0x03, 0x4a, 0x6f, 0x62, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6e, + 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, + 0x64, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, + 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x70, + 0x6f, 0x73, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, + 0x0a, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x8b, 0x04, 0x0a, 0x08, 0x50, 0x72, 0x6f, + 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x32, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, + 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, + 0x61, 0x6c, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x0e, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x73, 0x70, 0x65, 0x63, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, + 0x00, 0x52, 0x07, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x51, 0x0a, + 0x14, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x01, 0x52, 0x12, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, + 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x42, 0x17, 0x0a, + 0x15, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, + 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x22, 0x43, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x04, 0x75, 0x75, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x42, + 0x0a, 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x33, 0x0a, 0x0e, 0x47, + 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, + 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x03, 0x6a, 0x6f, 0x62, + 0x22, 0x24, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x47, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, + 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, + 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, + 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x22, + 0x84, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, + 0x35, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6e, + 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6e, + 0x6f, 0x64, 0x65, 0x49, 0x64, 0x73, 0x22, 0x37, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, + 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x6a, 0x6f, + 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, + 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x22, + 0x8c, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, + 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, + 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x33, 0x0a, 0x06, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x73, 0x22, 0x4b, + 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x70, 0x6f, + 0x73, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, + 0x52, 0x09, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x73, 0x22, 0x40, 0x0a, 0x11, 0x50, + 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x65, + 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x46, 0x0a, + 0x12, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, + 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x22, 0x46, 0x0a, 0x10, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, + 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x04, 0x75, + 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x75, 0x75, 0x69, + 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x45, 0x0a, + 0x11, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, + 0x6f, 0x73, 0x61, 0x6c, 0x22, 0x46, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, + 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x04, 0x75, 0x75, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, + 0x42, 0x0a, 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x36, 0x0a, 0x11, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x21, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4a, 0x6f, 0x62, 0x52, + 0x03, 0x6a, 0x6f, 0x62, 0x2a, 0xe4, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, + 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x50, 0x52, 0x4f, 0x50, 0x4f, + 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x4f, 0x50, + 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x50, + 0x4f, 0x53, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, + 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, + 0x45, 0x44, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, + 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, + 0x04, 0x12, 0x1b, 0x0a, 0x17, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x1b, + 0x0a, 0x17, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x52, 0x45, 0x56, 0x4f, 0x4b, 0x45, 0x44, 0x10, 0x06, 0x2a, 0xba, 0x01, 0x0a, 0x16, + 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, 0x24, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, + 0x41, 0x4c, 0x5f, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x26, 0x0a, 0x22, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x44, 0x45, 0x4c, + 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x45, 0x4c, + 0x49, 0x56, 0x45, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x29, 0x0a, 0x25, 0x50, 0x52, 0x4f, 0x50, + 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x4b, 0x4e, 0x4f, 0x57, 0x4c, 0x45, 0x44, 0x47, 0x45, + 0x44, 0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, + 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x32, 0xa9, 0x04, 0x0a, 0x0a, 0x4a, 0x6f, 0x62, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4a, 0x6f, + 0x62, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0b, 0x47, 0x65, + 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, + 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, + 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x08, + 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, + 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, + 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x73, 0x12, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, + 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, + 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4d, 0x0a, + 0x0a, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1d, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, + 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, + 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x09, + 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, + 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, + 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x6a, 0x6f, 0x62, 0x2f, 0x76, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_job_v1_job_proto_rawDescOnce sync.Once + file_job_v1_job_proto_rawDescData = file_job_v1_job_proto_rawDesc +) + +func file_job_v1_job_proto_rawDescGZIP() []byte { + file_job_v1_job_proto_rawDescOnce.Do(func() { + file_job_v1_job_proto_rawDescData = protoimpl.X.CompressGZIP(file_job_v1_job_proto_rawDescData) + }) + return file_job_v1_job_proto_rawDescData +} + +var file_job_v1_job_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_job_v1_job_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_job_v1_job_proto_goTypes = []interface{}{ + (ProposalStatus)(0), // 0: api.job.v1.ProposalStatus + (ProposalDeliveryStatus)(0), // 1: api.job.v1.ProposalDeliveryStatus + (*Job)(nil), // 2: api.job.v1.Job + (*Proposal)(nil), // 3: api.job.v1.Proposal + (*GetJobRequest)(nil), // 4: api.job.v1.GetJobRequest + (*GetJobResponse)(nil), // 5: api.job.v1.GetJobResponse + (*GetProposalRequest)(nil), // 6: api.job.v1.GetProposalRequest + (*GetProposalResponse)(nil), // 7: api.job.v1.GetProposalResponse + (*ListJobsRequest)(nil), // 8: api.job.v1.ListJobsRequest + (*ListJobsResponse)(nil), // 9: api.job.v1.ListJobsResponse + (*ListProposalsRequest)(nil), // 10: api.job.v1.ListProposalsRequest + (*ListProposalsResponse)(nil), // 11: api.job.v1.ListProposalsResponse + (*ProposeJobRequest)(nil), // 12: api.job.v1.ProposeJobRequest + (*ProposeJobResponse)(nil), // 13: api.job.v1.ProposeJobResponse + (*RevokeJobRequest)(nil), // 14: api.job.v1.RevokeJobRequest + (*RevokeJobResponse)(nil), // 15: api.job.v1.RevokeJobResponse + (*DeleteJobRequest)(nil), // 16: api.job.v1.DeleteJobRequest + (*DeleteJobResponse)(nil), // 17: api.job.v1.DeleteJobResponse + (*ListJobsRequest_Filter)(nil), // 18: api.job.v1.ListJobsRequest.Filter + (*ListProposalsRequest_Filter)(nil), // 19: api.job.v1.ListProposalsRequest.Filter + (*timestamppb.Timestamp)(nil), // 20: google.protobuf.Timestamp +} +var file_job_v1_job_proto_depIdxs = []int32{ + 20, // 0: api.job.v1.Job.created_at:type_name -> google.protobuf.Timestamp + 20, // 1: api.job.v1.Job.updated_at:type_name -> google.protobuf.Timestamp + 20, // 2: api.job.v1.Job.deleted_at:type_name -> google.protobuf.Timestamp + 0, // 3: api.job.v1.Proposal.status:type_name -> api.job.v1.ProposalStatus + 1, // 4: api.job.v1.Proposal.delivery_status:type_name -> api.job.v1.ProposalDeliveryStatus + 20, // 5: api.job.v1.Proposal.created_at:type_name -> google.protobuf.Timestamp + 20, // 6: api.job.v1.Proposal.updated_at:type_name -> google.protobuf.Timestamp + 20, // 7: api.job.v1.Proposal.acked_at:type_name -> google.protobuf.Timestamp + 20, // 8: api.job.v1.Proposal.response_received_at:type_name -> google.protobuf.Timestamp + 2, // 9: api.job.v1.GetJobResponse.job:type_name -> api.job.v1.Job + 3, // 10: api.job.v1.GetProposalResponse.proposal:type_name -> api.job.v1.Proposal + 18, // 11: api.job.v1.ListJobsRequest.filter:type_name -> api.job.v1.ListJobsRequest.Filter + 2, // 12: api.job.v1.ListJobsResponse.jobs:type_name -> api.job.v1.Job + 19, // 13: api.job.v1.ListProposalsRequest.filter:type_name -> api.job.v1.ListProposalsRequest.Filter + 3, // 14: api.job.v1.ListProposalsResponse.proposals:type_name -> api.job.v1.Proposal + 3, // 15: api.job.v1.ProposeJobResponse.proposal:type_name -> api.job.v1.Proposal + 3, // 16: api.job.v1.RevokeJobResponse.proposal:type_name -> api.job.v1.Proposal + 2, // 17: api.job.v1.DeleteJobResponse.job:type_name -> api.job.v1.Job + 4, // 18: api.job.v1.JobService.GetJob:input_type -> api.job.v1.GetJobRequest + 6, // 19: api.job.v1.JobService.GetProposal:input_type -> api.job.v1.GetProposalRequest + 8, // 20: api.job.v1.JobService.ListJobs:input_type -> api.job.v1.ListJobsRequest + 10, // 21: api.job.v1.JobService.ListProposals:input_type -> api.job.v1.ListProposalsRequest + 12, // 22: api.job.v1.JobService.ProposeJob:input_type -> api.job.v1.ProposeJobRequest + 14, // 23: api.job.v1.JobService.RevokeJob:input_type -> api.job.v1.RevokeJobRequest + 16, // 24: api.job.v1.JobService.DeleteJob:input_type -> api.job.v1.DeleteJobRequest + 5, // 25: api.job.v1.JobService.GetJob:output_type -> api.job.v1.GetJobResponse + 7, // 26: api.job.v1.JobService.GetProposal:output_type -> api.job.v1.GetProposalResponse + 9, // 27: api.job.v1.JobService.ListJobs:output_type -> api.job.v1.ListJobsResponse + 11, // 28: api.job.v1.JobService.ListProposals:output_type -> api.job.v1.ListProposalsResponse + 13, // 29: api.job.v1.JobService.ProposeJob:output_type -> api.job.v1.ProposeJobResponse + 15, // 30: api.job.v1.JobService.RevokeJob:output_type -> api.job.v1.RevokeJobResponse + 17, // 31: api.job.v1.JobService.DeleteJob:output_type -> api.job.v1.DeleteJobResponse + 25, // [25:32] is the sub-list for method output_type + 18, // [18:25] is the sub-list for method input_type + 18, // [18:18] is the sub-list for extension type_name + 18, // [18:18] is the sub-list for extension extendee + 0, // [0:18] is the sub-list for field type_name +} + +func init() { file_job_v1_job_proto_init() } +func file_job_v1_job_proto_init() { + if File_job_v1_job_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_job_v1_job_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Job); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Proposal); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetJobRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetJobResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProposalRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProposalResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListJobsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListJobsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListProposalsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListProposalsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProposeJobRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProposeJobResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RevokeJobRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RevokeJobResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteJobRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteJobResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListJobsRequest_Filter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListProposalsRequest_Filter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_job_v1_job_proto_msgTypes[1].OneofWrappers = []interface{}{} + file_job_v1_job_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*GetJobRequest_Id)(nil), + (*GetJobRequest_Uuid)(nil), + } + file_job_v1_job_proto_msgTypes[12].OneofWrappers = []interface{}{ + (*RevokeJobRequest_Id)(nil), + (*RevokeJobRequest_Uuid)(nil), + } + file_job_v1_job_proto_msgTypes[14].OneofWrappers = []interface{}{ + (*DeleteJobRequest_Id)(nil), + (*DeleteJobRequest_Uuid)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_job_v1_job_proto_rawDesc, + NumEnums: 2, + NumMessages: 18, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_job_v1_job_proto_goTypes, + DependencyIndexes: file_job_v1_job_proto_depIdxs, + EnumInfos: file_job_v1_job_proto_enumTypes, + MessageInfos: file_job_v1_job_proto_msgTypes, + }.Build() + File_job_v1_job_proto = out.File + file_job_v1_job_proto_rawDesc = nil + file_job_v1_job_proto_goTypes = nil + file_job_v1_job_proto_depIdxs = nil +} diff --git a/integration-tests/deployment/jd/job/v1/job_grpc.pb.go b/integration-tests/deployment/jd/job/v1/job_grpc.pb.go new file mode 100644 index 0000000000..64c6d285d3 --- /dev/null +++ b/integration-tests/deployment/jd/job/v1/job_grpc.pb.go @@ -0,0 +1,346 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.25.3 +// source: job/v1/job.proto + +package v1 + +import ( + context "context" + + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + JobService_GetJob_FullMethodName = "/api.job.v1.JobService/GetJob" + JobService_GetProposal_FullMethodName = "/api.job.v1.JobService/GetProposal" + JobService_ListJobs_FullMethodName = "/api.job.v1.JobService/ListJobs" + JobService_ListProposals_FullMethodName = "/api.job.v1.JobService/ListProposals" + JobService_ProposeJob_FullMethodName = "/api.job.v1.JobService/ProposeJob" + JobService_RevokeJob_FullMethodName = "/api.job.v1.JobService/RevokeJob" + JobService_DeleteJob_FullMethodName = "/api.job.v1.JobService/DeleteJob" +) + +// JobServiceClient is the client API for JobService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type JobServiceClient interface { + // GetJob retrieves the details of a specific job by its ID or UUID. + GetJob(ctx context.Context, in *GetJobRequest, opts ...grpc.CallOption) (*GetJobResponse, error) + // GetProposal retrieves the details of a specific proposal by its ID. + GetProposal(ctx context.Context, in *GetProposalRequest, opts ...grpc.CallOption) (*GetProposalResponse, error) + // ListJobs returns a list of jobs, optionally filtered by IDs or node IDs. + ListJobs(ctx context.Context, in *ListJobsRequest, opts ...grpc.CallOption) (*ListJobsResponse, error) + // ListProposals returns a list of proposals, optionally filtered by proposal or job IDs. + ListProposals(ctx context.Context, in *ListProposalsRequest, opts ...grpc.CallOption) (*ListProposalsResponse, error) + // ProposeJob submits a new job proposal to a node. + ProposeJob(ctx context.Context, in *ProposeJobRequest, opts ...grpc.CallOption) (*ProposeJobResponse, error) + // RevokeJob revokes an existing job proposal. + RevokeJob(ctx context.Context, in *RevokeJobRequest, opts ...grpc.CallOption) (*RevokeJobResponse, error) + // DeleteJob deletes a job from the system. + DeleteJob(ctx context.Context, in *DeleteJobRequest, opts ...grpc.CallOption) (*DeleteJobResponse, error) +} + +type jobServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewJobServiceClient(cc grpc.ClientConnInterface) JobServiceClient { + return &jobServiceClient{cc} +} + +func (c *jobServiceClient) GetJob(ctx context.Context, in *GetJobRequest, opts ...grpc.CallOption) (*GetJobResponse, error) { + out := new(GetJobResponse) + err := c.cc.Invoke(ctx, JobService_GetJob_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *jobServiceClient) GetProposal(ctx context.Context, in *GetProposalRequest, opts ...grpc.CallOption) (*GetProposalResponse, error) { + out := new(GetProposalResponse) + err := c.cc.Invoke(ctx, JobService_GetProposal_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *jobServiceClient) ListJobs(ctx context.Context, in *ListJobsRequest, opts ...grpc.CallOption) (*ListJobsResponse, error) { + out := new(ListJobsResponse) + err := c.cc.Invoke(ctx, JobService_ListJobs_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *jobServiceClient) ListProposals(ctx context.Context, in *ListProposalsRequest, opts ...grpc.CallOption) (*ListProposalsResponse, error) { + out := new(ListProposalsResponse) + err := c.cc.Invoke(ctx, JobService_ListProposals_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *jobServiceClient) ProposeJob(ctx context.Context, in *ProposeJobRequest, opts ...grpc.CallOption) (*ProposeJobResponse, error) { + out := new(ProposeJobResponse) + err := c.cc.Invoke(ctx, JobService_ProposeJob_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *jobServiceClient) RevokeJob(ctx context.Context, in *RevokeJobRequest, opts ...grpc.CallOption) (*RevokeJobResponse, error) { + out := new(RevokeJobResponse) + err := c.cc.Invoke(ctx, JobService_RevokeJob_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *jobServiceClient) DeleteJob(ctx context.Context, in *DeleteJobRequest, opts ...grpc.CallOption) (*DeleteJobResponse, error) { + out := new(DeleteJobResponse) + err := c.cc.Invoke(ctx, JobService_DeleteJob_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// JobServiceServer is the server API for JobService service. +// All implementations must embed UnimplementedJobServiceServer +// for forward compatibility +type JobServiceServer interface { + // GetJob retrieves the details of a specific job by its ID or UUID. + GetJob(context.Context, *GetJobRequest) (*GetJobResponse, error) + // GetProposal retrieves the details of a specific proposal by its ID. + GetProposal(context.Context, *GetProposalRequest) (*GetProposalResponse, error) + // ListJobs returns a list of jobs, optionally filtered by IDs or node IDs. + ListJobs(context.Context, *ListJobsRequest) (*ListJobsResponse, error) + // ListProposals returns a list of proposals, optionally filtered by proposal or job IDs. + ListProposals(context.Context, *ListProposalsRequest) (*ListProposalsResponse, error) + // ProposeJob submits a new job proposal to a node. + ProposeJob(context.Context, *ProposeJobRequest) (*ProposeJobResponse, error) + // RevokeJob revokes an existing job proposal. + RevokeJob(context.Context, *RevokeJobRequest) (*RevokeJobResponse, error) + // DeleteJob deletes a job from the system. + DeleteJob(context.Context, *DeleteJobRequest) (*DeleteJobResponse, error) + mustEmbedUnimplementedJobServiceServer() +} + +// UnimplementedJobServiceServer must be embedded to have forward compatible implementations. +type UnimplementedJobServiceServer struct { +} + +func (UnimplementedJobServiceServer) GetJob(context.Context, *GetJobRequest) (*GetJobResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetJob not implemented") +} +func (UnimplementedJobServiceServer) GetProposal(context.Context, *GetProposalRequest) (*GetProposalResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetProposal not implemented") +} +func (UnimplementedJobServiceServer) ListJobs(context.Context, *ListJobsRequest) (*ListJobsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListJobs not implemented") +} +func (UnimplementedJobServiceServer) ListProposals(context.Context, *ListProposalsRequest) (*ListProposalsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListProposals not implemented") +} +func (UnimplementedJobServiceServer) ProposeJob(context.Context, *ProposeJobRequest) (*ProposeJobResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ProposeJob not implemented") +} +func (UnimplementedJobServiceServer) RevokeJob(context.Context, *RevokeJobRequest) (*RevokeJobResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RevokeJob not implemented") +} +func (UnimplementedJobServiceServer) DeleteJob(context.Context, *DeleteJobRequest) (*DeleteJobResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteJob not implemented") +} +func (UnimplementedJobServiceServer) mustEmbedUnimplementedJobServiceServer() {} + +// UnsafeJobServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to JobServiceServer will +// result in compilation errors. +type UnsafeJobServiceServer interface { + mustEmbedUnimplementedJobServiceServer() +} + +func RegisterJobServiceServer(s grpc.ServiceRegistrar, srv JobServiceServer) { + s.RegisterService(&JobService_ServiceDesc, srv) +} + +func _JobService_GetJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetJobRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(JobServiceServer).GetJob(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: JobService_GetJob_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(JobServiceServer).GetJob(ctx, req.(*GetJobRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _JobService_GetProposal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetProposalRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(JobServiceServer).GetProposal(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: JobService_GetProposal_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(JobServiceServer).GetProposal(ctx, req.(*GetProposalRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _JobService_ListJobs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListJobsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(JobServiceServer).ListJobs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: JobService_ListJobs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(JobServiceServer).ListJobs(ctx, req.(*ListJobsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _JobService_ListProposals_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListProposalsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(JobServiceServer).ListProposals(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: JobService_ListProposals_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(JobServiceServer).ListProposals(ctx, req.(*ListProposalsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _JobService_ProposeJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ProposeJobRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(JobServiceServer).ProposeJob(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: JobService_ProposeJob_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(JobServiceServer).ProposeJob(ctx, req.(*ProposeJobRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _JobService_RevokeJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RevokeJobRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(JobServiceServer).RevokeJob(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: JobService_RevokeJob_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(JobServiceServer).RevokeJob(ctx, req.(*RevokeJobRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _JobService_DeleteJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteJobRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(JobServiceServer).DeleteJob(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: JobService_DeleteJob_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(JobServiceServer).DeleteJob(ctx, req.(*DeleteJobRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// JobService_ServiceDesc is the grpc.ServiceDesc for JobService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var JobService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "api.job.v1.JobService", + HandlerType: (*JobServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetJob", + Handler: _JobService_GetJob_Handler, + }, + { + MethodName: "GetProposal", + Handler: _JobService_GetProposal_Handler, + }, + { + MethodName: "ListJobs", + Handler: _JobService_ListJobs_Handler, + }, + { + MethodName: "ListProposals", + Handler: _JobService_ListProposals_Handler, + }, + { + MethodName: "ProposeJob", + Handler: _JobService_ProposeJob_Handler, + }, + { + MethodName: "RevokeJob", + Handler: _JobService_RevokeJob_Handler, + }, + { + MethodName: "DeleteJob", + Handler: _JobService_DeleteJob_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "job/v1/job.proto", +} diff --git a/integration-tests/deployment/jd/node/v1/node.pb.go b/integration-tests/deployment/jd/node/v1/node.pb.go new file mode 100644 index 0000000000..f5b22ba3ae --- /dev/null +++ b/integration-tests/deployment/jd/node/v1/node.pb.go @@ -0,0 +1,1652 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.29.0 +// protoc v4.25.3 +// source: node/v1/node.proto + +package v1 + +import ( + "reflect" + "sync" + + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoimpl" + _ "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/shared/ptypes" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ChainType int32 + +const ( + ChainType_CHAIN_TYPE_UNSPECIFIED ChainType = 0 + ChainType_CHAIN_TYPE_EVM ChainType = 1 + ChainType_CHAIN_TYPE_SOLANA ChainType = 2 +) + +// Enum value maps for ChainType. +var ( + ChainType_name = map[int32]string{ + 0: "CHAIN_TYPE_UNSPECIFIED", + 1: "CHAIN_TYPE_EVM", + 2: "CHAIN_TYPE_SOLANA", + } + ChainType_value = map[string]int32{ + "CHAIN_TYPE_UNSPECIFIED": 0, + "CHAIN_TYPE_EVM": 1, + "CHAIN_TYPE_SOLANA": 2, + } +) + +func (x ChainType) Enum() *ChainType { + p := new(ChainType) + *p = x + return p +} + +func (x ChainType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ChainType) Descriptor() protoreflect.EnumDescriptor { + return file_node_v1_node_proto_enumTypes[0].Descriptor() +} + +func (ChainType) Type() protoreflect.EnumType { + return &file_node_v1_node_proto_enumTypes[0] +} + +func (x ChainType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ChainType.Descriptor instead. +func (ChainType) EnumDescriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{0} +} + +// ArchiveState represents the archived state of the node. +type ArchiveState int32 + +const ( + ArchiveState_ARCHIVE_STATE_UNSPECIFIED ArchiveState = 0 + ArchiveState_ARCHIVE_STATE_ARCHIVED ArchiveState = 1 + ArchiveState_ARCHIVE_STATE_ACTIVE ArchiveState = 2 +) + +// Enum value maps for ArchiveState. +var ( + ArchiveState_name = map[int32]string{ + 0: "ARCHIVE_STATE_UNSPECIFIED", + 1: "ARCHIVE_STATE_ARCHIVED", + 2: "ARCHIVE_STATE_ACTIVE", + } + ArchiveState_value = map[string]int32{ + "ARCHIVE_STATE_UNSPECIFIED": 0, + "ARCHIVE_STATE_ARCHIVED": 1, + "ARCHIVE_STATE_ACTIVE": 2, + } +) + +func (x ArchiveState) Enum() *ArchiveState { + p := new(ArchiveState) + *p = x + return p +} + +func (x ArchiveState) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ArchiveState) Descriptor() protoreflect.EnumDescriptor { + return file_node_v1_node_proto_enumTypes[1].Descriptor() +} + +func (ArchiveState) Type() protoreflect.EnumType { + return &file_node_v1_node_proto_enumTypes[1] +} + +func (x ArchiveState) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ArchiveState.Descriptor instead. +func (ArchiveState) EnumDescriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{1} +} + +type Chain struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Type ChainType `protobuf:"varint,2,opt,name=type,proto3,enum=api.node.v1.ChainType" json:"type,omitempty"` +} + +func (x *Chain) Reset() { + *x = Chain{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Chain) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Chain) ProtoMessage() {} + +func (x *Chain) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Chain.ProtoReflect.Descriptor instead. +func (*Chain) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{0} +} + +func (x *Chain) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Chain) GetType() ChainType { + if x != nil { + return x.Type + } + return ChainType_CHAIN_TYPE_UNSPECIFIED +} + +type OCR1Config struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + IsBootstrap bool `protobuf:"varint,2,opt,name=is_bootstrap,json=isBootstrap,proto3" json:"is_bootstrap,omitempty"` + P2PKeyBundle *OCR1Config_P2PKeyBundle `protobuf:"bytes,3,opt,name=p2p_key_bundle,json=p2pKeyBundle,proto3" json:"p2p_key_bundle,omitempty"` + OcrKeyBundle *OCR1Config_OCRKeyBundle `protobuf:"bytes,4,opt,name=ocr_key_bundle,json=ocrKeyBundle,proto3" json:"ocr_key_bundle,omitempty"` + Multiaddr string `protobuf:"bytes,5,opt,name=multiaddr,proto3" json:"multiaddr,omitempty"` +} + +func (x *OCR1Config) Reset() { + *x = OCR1Config{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OCR1Config) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OCR1Config) ProtoMessage() {} + +func (x *OCR1Config) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OCR1Config.ProtoReflect.Descriptor instead. +func (*OCR1Config) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{1} +} + +func (x *OCR1Config) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *OCR1Config) GetIsBootstrap() bool { + if x != nil { + return x.IsBootstrap + } + return false +} + +func (x *OCR1Config) GetP2PKeyBundle() *OCR1Config_P2PKeyBundle { + if x != nil { + return x.P2PKeyBundle + } + return nil +} + +func (x *OCR1Config) GetOcrKeyBundle() *OCR1Config_OCRKeyBundle { + if x != nil { + return x.OcrKeyBundle + } + return nil +} + +func (x *OCR1Config) GetMultiaddr() string { + if x != nil { + return x.Multiaddr + } + return "" +} + +type OCR2Config struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + IsBootstrap bool `protobuf:"varint,2,opt,name=is_bootstrap,json=isBootstrap,proto3" json:"is_bootstrap,omitempty"` + P2PKeyBundle *OCR2Config_P2PKeyBundle `protobuf:"bytes,3,opt,name=p2p_key_bundle,json=p2pKeyBundle,proto3" json:"p2p_key_bundle,omitempty"` + OcrKeyBundle *OCR2Config_OCRKeyBundle `protobuf:"bytes,4,opt,name=ocr_key_bundle,json=ocrKeyBundle,proto3" json:"ocr_key_bundle,omitempty"` + Multiaddr string `protobuf:"bytes,5,opt,name=multiaddr,proto3" json:"multiaddr,omitempty"` + Plugins *OCR2Config_Plugins `protobuf:"bytes,6,opt,name=plugins,proto3" json:"plugins,omitempty"` + ForwarderAddress string `protobuf:"bytes,7,opt,name=forwarder_address,json=forwarderAddress,proto3" json:"forwarder_address,omitempty"` +} + +func (x *OCR2Config) Reset() { + *x = OCR2Config{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OCR2Config) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OCR2Config) ProtoMessage() {} + +func (x *OCR2Config) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OCR2Config.ProtoReflect.Descriptor instead. +func (*OCR2Config) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{2} +} + +func (x *OCR2Config) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *OCR2Config) GetIsBootstrap() bool { + if x != nil { + return x.IsBootstrap + } + return false +} + +func (x *OCR2Config) GetP2PKeyBundle() *OCR2Config_P2PKeyBundle { + if x != nil { + return x.P2PKeyBundle + } + return nil +} + +func (x *OCR2Config) GetOcrKeyBundle() *OCR2Config_OCRKeyBundle { + if x != nil { + return x.OcrKeyBundle + } + return nil +} + +func (x *OCR2Config) GetMultiaddr() string { + if x != nil { + return x.Multiaddr + } + return "" +} + +func (x *OCR2Config) GetPlugins() *OCR2Config_Plugins { + if x != nil { + return x.Plugins + } + return nil +} + +func (x *OCR2Config) GetForwarderAddress() string { + if x != nil { + return x.ForwarderAddress + } + return "" +} + +type ChainConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Chain *Chain `protobuf:"bytes,1,opt,name=chain,proto3" json:"chain,omitempty"` + AccountAddress string `protobuf:"bytes,2,opt,name=account_address,json=accountAddress,proto3" json:"account_address,omitempty"` + AdminAddress string `protobuf:"bytes,3,opt,name=admin_address,json=adminAddress,proto3" json:"admin_address,omitempty"` + Ocr1Config *OCR1Config `protobuf:"bytes,4,opt,name=ocr1_config,json=ocr1Config,proto3" json:"ocr1_config,omitempty"` + Ocr2Config *OCR2Config `protobuf:"bytes,5,opt,name=ocr2_config,json=ocr2Config,proto3" json:"ocr2_config,omitempty"` +} + +func (x *ChainConfig) Reset() { + *x = ChainConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChainConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChainConfig) ProtoMessage() {} + +func (x *ChainConfig) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChainConfig.ProtoReflect.Descriptor instead. +func (*ChainConfig) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{3} +} + +func (x *ChainConfig) GetChain() *Chain { + if x != nil { + return x.Chain + } + return nil +} + +func (x *ChainConfig) GetAccountAddress() string { + if x != nil { + return x.AccountAddress + } + return "" +} + +func (x *ChainConfig) GetAdminAddress() string { + if x != nil { + return x.AdminAddress + } + return "" +} + +func (x *ChainConfig) GetOcr1Config() *OCR1Config { + if x != nil { + return x.Ocr1Config + } + return nil +} + +func (x *ChainConfig) GetOcr2Config() *OCR2Config { + if x != nil { + return x.Ocr2Config + } + return nil +} + +// GetNodeRequest is the request to retrieve a single node by its ID. +type GetNodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier of the node to retrieve. +} + +func (x *GetNodeRequest) Reset() { + *x = GetNodeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeRequest) ProtoMessage() {} + +func (x *GetNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeRequest.ProtoReflect.Descriptor instead. +func (*GetNodeRequest) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{4} +} + +func (x *GetNodeRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// GetNodeResponse is the response containing the requested node. +type GetNodeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` // Details of the retrieved node. +} + +func (x *GetNodeResponse) Reset() { + *x = GetNodeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeResponse) ProtoMessage() {} + +func (x *GetNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeResponse.ProtoReflect.Descriptor instead. +func (*GetNodeResponse) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{5} +} + +func (x *GetNodeResponse) GetNode() *Node { + if x != nil { + return x.Node + } + return nil +} + +// * +// ListNodesRequest is the request object for the ListNodes method. +// +// Provide a filter to return a subset of data. Nodes can be filtered by: +// - ids - A list of node ids. +// - archived - The archived state of the node. +// - selectors - A list of selectors to filter nodes by their labels. +// +// If no filter is provided, all nodes are returned. +type ListNodesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Filter *ListNodesRequest_Filter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` +} + +func (x *ListNodesRequest) Reset() { + *x = ListNodesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListNodesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListNodesRequest) ProtoMessage() {} + +func (x *ListNodesRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListNodesRequest.ProtoReflect.Descriptor instead. +func (*ListNodesRequest) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{6} +} + +func (x *ListNodesRequest) GetFilter() *ListNodesRequest_Filter { + if x != nil { + return x.Filter + } + return nil +} + +// * +// ListNodesResponse is the response object for the ListNodes method. +// +// It returns a list of nodes that match the filter criteria. +type ListNodesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nodes []*Node `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"` // List of nodes. +} + +func (x *ListNodesResponse) Reset() { + *x = ListNodesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListNodesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListNodesResponse) ProtoMessage() {} + +func (x *ListNodesResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListNodesResponse.ProtoReflect.Descriptor instead. +func (*ListNodesResponse) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{7} +} + +func (x *ListNodesResponse) GetNodes() []*Node { + if x != nil { + return x.Nodes + } + return nil +} + +type ListNodeChainConfigsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Filter *ListNodeChainConfigsRequest_Filter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` +} + +func (x *ListNodeChainConfigsRequest) Reset() { + *x = ListNodeChainConfigsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListNodeChainConfigsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListNodeChainConfigsRequest) ProtoMessage() {} + +func (x *ListNodeChainConfigsRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListNodeChainConfigsRequest.ProtoReflect.Descriptor instead. +func (*ListNodeChainConfigsRequest) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{8} +} + +func (x *ListNodeChainConfigsRequest) GetFilter() *ListNodeChainConfigsRequest_Filter { + if x != nil { + return x.Filter + } + return nil +} + +type ListNodeChainConfigsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ChainConfigs []*ChainConfig `protobuf:"bytes,1,rep,name=chain_configs,json=chainConfigs,proto3" json:"chain_configs,omitempty"` +} + +func (x *ListNodeChainConfigsResponse) Reset() { + *x = ListNodeChainConfigsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListNodeChainConfigsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListNodeChainConfigsResponse) ProtoMessage() {} + +func (x *ListNodeChainConfigsResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListNodeChainConfigsResponse.ProtoReflect.Descriptor instead. +func (*ListNodeChainConfigsResponse) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{9} +} + +func (x *ListNodeChainConfigsResponse) GetChainConfigs() []*ChainConfig { + if x != nil { + return x.ChainConfigs + } + return nil +} + +type OCR1Config_P2PKeyBundle struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PeerId string `protobuf:"bytes,1,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + PublicKey string `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` +} + +func (x *OCR1Config_P2PKeyBundle) Reset() { + *x = OCR1Config_P2PKeyBundle{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OCR1Config_P2PKeyBundle) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OCR1Config_P2PKeyBundle) ProtoMessage() {} + +func (x *OCR1Config_P2PKeyBundle) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OCR1Config_P2PKeyBundle.ProtoReflect.Descriptor instead. +func (*OCR1Config_P2PKeyBundle) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{1, 0} +} + +func (x *OCR1Config_P2PKeyBundle) GetPeerId() string { + if x != nil { + return x.PeerId + } + return "" +} + +func (x *OCR1Config_P2PKeyBundle) GetPublicKey() string { + if x != nil { + return x.PublicKey + } + return "" +} + +type OCR1Config_OCRKeyBundle struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BundleId string `protobuf:"bytes,1,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty"` + ConfigPublicKey string `protobuf:"bytes,2,opt,name=config_public_key,json=configPublicKey,proto3" json:"config_public_key,omitempty"` + OffchainPublicKey string `protobuf:"bytes,3,opt,name=offchain_public_key,json=offchainPublicKey,proto3" json:"offchain_public_key,omitempty"` + OnchainSigningAddress string `protobuf:"bytes,4,opt,name=onchain_signing_address,json=onchainSigningAddress,proto3" json:"onchain_signing_address,omitempty"` +} + +func (x *OCR1Config_OCRKeyBundle) Reset() { + *x = OCR1Config_OCRKeyBundle{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OCR1Config_OCRKeyBundle) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OCR1Config_OCRKeyBundle) ProtoMessage() {} + +func (x *OCR1Config_OCRKeyBundle) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OCR1Config_OCRKeyBundle.ProtoReflect.Descriptor instead. +func (*OCR1Config_OCRKeyBundle) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{1, 1} +} + +func (x *OCR1Config_OCRKeyBundle) GetBundleId() string { + if x != nil { + return x.BundleId + } + return "" +} + +func (x *OCR1Config_OCRKeyBundle) GetConfigPublicKey() string { + if x != nil { + return x.ConfigPublicKey + } + return "" +} + +func (x *OCR1Config_OCRKeyBundle) GetOffchainPublicKey() string { + if x != nil { + return x.OffchainPublicKey + } + return "" +} + +func (x *OCR1Config_OCRKeyBundle) GetOnchainSigningAddress() string { + if x != nil { + return x.OnchainSigningAddress + } + return "" +} + +type OCR2Config_P2PKeyBundle struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PeerId string `protobuf:"bytes,1,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + PublicKey string `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` +} + +func (x *OCR2Config_P2PKeyBundle) Reset() { + *x = OCR2Config_P2PKeyBundle{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OCR2Config_P2PKeyBundle) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OCR2Config_P2PKeyBundle) ProtoMessage() {} + +func (x *OCR2Config_P2PKeyBundle) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OCR2Config_P2PKeyBundle.ProtoReflect.Descriptor instead. +func (*OCR2Config_P2PKeyBundle) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{2, 0} +} + +func (x *OCR2Config_P2PKeyBundle) GetPeerId() string { + if x != nil { + return x.PeerId + } + return "" +} + +func (x *OCR2Config_P2PKeyBundle) GetPublicKey() string { + if x != nil { + return x.PublicKey + } + return "" +} + +type OCR2Config_OCRKeyBundle struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BundleId string `protobuf:"bytes,1,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty"` + ConfigPublicKey string `protobuf:"bytes,2,opt,name=config_public_key,json=configPublicKey,proto3" json:"config_public_key,omitempty"` + OffchainPublicKey string `protobuf:"bytes,3,opt,name=offchain_public_key,json=offchainPublicKey,proto3" json:"offchain_public_key,omitempty"` + OnchainSigningAddress string `protobuf:"bytes,4,opt,name=onchain_signing_address,json=onchainSigningAddress,proto3" json:"onchain_signing_address,omitempty"` +} + +func (x *OCR2Config_OCRKeyBundle) Reset() { + *x = OCR2Config_OCRKeyBundle{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OCR2Config_OCRKeyBundle) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OCR2Config_OCRKeyBundle) ProtoMessage() {} + +func (x *OCR2Config_OCRKeyBundle) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OCR2Config_OCRKeyBundle.ProtoReflect.Descriptor instead. +func (*OCR2Config_OCRKeyBundle) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{2, 1} +} + +func (x *OCR2Config_OCRKeyBundle) GetBundleId() string { + if x != nil { + return x.BundleId + } + return "" +} + +func (x *OCR2Config_OCRKeyBundle) GetConfigPublicKey() string { + if x != nil { + return x.ConfigPublicKey + } + return "" +} + +func (x *OCR2Config_OCRKeyBundle) GetOffchainPublicKey() string { + if x != nil { + return x.OffchainPublicKey + } + return "" +} + +func (x *OCR2Config_OCRKeyBundle) GetOnchainSigningAddress() string { + if x != nil { + return x.OnchainSigningAddress + } + return "" +} + +type OCR2Config_Plugins struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Commit bool `protobuf:"varint,1,opt,name=commit,proto3" json:"commit,omitempty"` + Execute bool `protobuf:"varint,2,opt,name=execute,proto3" json:"execute,omitempty"` + Median bool `protobuf:"varint,3,opt,name=median,proto3" json:"median,omitempty"` + Mercury bool `protobuf:"varint,4,opt,name=mercury,proto3" json:"mercury,omitempty"` + Rebalancer bool `protobuf:"varint,5,opt,name=rebalancer,proto3" json:"rebalancer,omitempty"` +} + +func (x *OCR2Config_Plugins) Reset() { + *x = OCR2Config_Plugins{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OCR2Config_Plugins) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OCR2Config_Plugins) ProtoMessage() {} + +func (x *OCR2Config_Plugins) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OCR2Config_Plugins.ProtoReflect.Descriptor instead. +func (*OCR2Config_Plugins) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{2, 2} +} + +func (x *OCR2Config_Plugins) GetCommit() bool { + if x != nil { + return x.Commit + } + return false +} + +func (x *OCR2Config_Plugins) GetExecute() bool { + if x != nil { + return x.Execute + } + return false +} + +func (x *OCR2Config_Plugins) GetMedian() bool { + if x != nil { + return x.Median + } + return false +} + +func (x *OCR2Config_Plugins) GetMercury() bool { + if x != nil { + return x.Mercury + } + return false +} + +func (x *OCR2Config_Plugins) GetRebalancer() bool { + if x != nil { + return x.Rebalancer + } + return false +} + +type ListNodesRequest_Filter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"` + Archived ArchiveState `protobuf:"varint,2,opt,name=archived,proto3,enum=api.node.v1.ArchiveState" json:"archived,omitempty"` + Selectors []*ptypes.Selector `protobuf:"bytes,3,rep,name=selectors,proto3" json:"selectors,omitempty"` +} + +func (x *ListNodesRequest_Filter) Reset() { + *x = ListNodesRequest_Filter{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListNodesRequest_Filter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListNodesRequest_Filter) ProtoMessage() {} + +func (x *ListNodesRequest_Filter) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListNodesRequest_Filter.ProtoReflect.Descriptor instead. +func (*ListNodesRequest_Filter) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{6, 0} +} + +func (x *ListNodesRequest_Filter) GetIds() []string { + if x != nil { + return x.Ids + } + return nil +} + +func (x *ListNodesRequest_Filter) GetArchived() ArchiveState { + if x != nil { + return x.Archived + } + return ArchiveState_ARCHIVE_STATE_UNSPECIFIED +} + +func (x *ListNodesRequest_Filter) GetSelectors() []*ptypes.Selector { + if x != nil { + return x.Selectors + } + return nil +} + +type ListNodeChainConfigsRequest_Filter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` +} + +func (x *ListNodeChainConfigsRequest_Filter) Reset() { + *x = ListNodeChainConfigsRequest_Filter{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListNodeChainConfigsRequest_Filter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListNodeChainConfigsRequest_Filter) ProtoMessage() {} + +func (x *ListNodeChainConfigsRequest_Filter) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListNodeChainConfigsRequest_Filter.ProtoReflect.Descriptor instead. +func (*ListNodeChainConfigsRequest_Filter) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{8, 0} +} + +func (x *ListNodeChainConfigsRequest_Filter) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +var File_node_v1_node_proto protoreflect.FileDescriptor + +var file_node_v1_node_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, + 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x14, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x68, 0x61, 0x72, + 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, + 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x43, 0x0a, 0x05, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x89, 0x04, 0x0a, 0x0a, 0x4f, 0x43, 0x52, + 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, + 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x42, 0x6f, 0x6f, 0x74, 0x73, + 0x74, 0x72, 0x61, 0x70, 0x12, 0x4a, 0x0a, 0x0e, 0x70, 0x32, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, + 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x31, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x32, 0x50, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x52, 0x0c, 0x70, 0x32, 0x70, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, + 0x12, 0x4a, 0x0a, 0x0e, 0x6f, 0x63, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x4f, 0x43, 0x52, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x0c, + 0x6f, 0x63, 0x72, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x1a, 0x46, 0x0a, 0x0c, 0x50, 0x32, + 0x50, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x65, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x65, 0x79, 0x1a, 0xbf, 0x01, 0x0a, 0x0c, 0x4f, 0x43, 0x52, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x49, 0x64, + 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x13, + 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6f, 0x66, 0x66, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x17, + 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x6f, + 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x22, 0x81, 0x06, 0x0a, 0x0a, 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, + 0x0c, 0x69, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, + 0x12, 0x4a, 0x0a, 0x0e, 0x70, 0x32, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x50, 0x32, 0x50, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x0c, + 0x70, 0x32, 0x70, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x4a, 0x0a, 0x0e, + 0x6f, 0x63, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4f, 0x43, + 0x52, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x0c, 0x6f, 0x63, 0x72, 0x4b, + 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, + 0x69, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x75, 0x6c, + 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x52, 0x07, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x66, 0x6f, + 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x1a, 0x46, + 0x0a, 0x0c, 0x50, 0x32, 0x50, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x17, + 0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x1a, 0xbf, 0x01, 0x0a, 0x0c, 0x4f, 0x43, 0x52, 0x4b, 0x65, + 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x75, 0x6e, 0x64, 0x6c, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x12, 0x2e, 0x0a, 0x13, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6f, + 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x12, 0x36, 0x0a, 0x17, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x6e, + 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x15, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, + 0x67, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x1a, 0x8d, 0x01, 0x0a, 0x07, 0x50, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x12, 0x18, + 0x0a, 0x07, 0x6d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x6d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x65, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x22, 0xf9, 0x01, 0x0a, 0x0b, 0x43, 0x68, 0x61, + 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, + 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x38, 0x0a, 0x0b, 0x6f, 0x63, 0x72, 0x31, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, + 0x6f, 0x63, 0x72, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x0b, 0x6f, 0x63, + 0x72, 0x32, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, + 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x6f, 0x63, 0x72, 0x32, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x22, 0x20, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x38, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x6e, 0x6f, 0x64, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, + 0x22, 0xd7, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x1a, 0x84, 0x01, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x10, + 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, + 0x12, 0x35, 0x0a, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x61, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x31, 0x0a, 0x09, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, + 0x09, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x3c, 0x0a, 0x11, 0x4c, 0x69, + 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x27, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, + 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x89, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, + 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x1a, 0x21, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x6e, + 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, + 0x64, 0x65, 0x49, 0x64, 0x22, 0x5d, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x73, 0x2a, 0x52, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, + 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x56, 0x4d, 0x10, 0x01, + 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, + 0x4f, 0x4c, 0x41, 0x4e, 0x41, 0x10, 0x02, 0x2a, 0x63, 0x0a, 0x0c, 0x41, 0x72, 0x63, 0x68, 0x69, + 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x52, 0x43, 0x48, 0x49, + 0x56, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, + 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x44, + 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x32, 0x92, 0x02, 0x0a, + 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x07, + 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, + 0x73, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x68, + 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x28, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, + 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x42, 0x09, 0x5a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_node_v1_node_proto_rawDescOnce sync.Once + file_node_v1_node_proto_rawDescData = file_node_v1_node_proto_rawDesc +) + +func file_node_v1_node_proto_rawDescGZIP() []byte { + file_node_v1_node_proto_rawDescOnce.Do(func() { + file_node_v1_node_proto_rawDescData = protoimpl.X.CompressGZIP(file_node_v1_node_proto_rawDescData) + }) + return file_node_v1_node_proto_rawDescData +} + +var file_node_v1_node_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_node_v1_node_proto_goTypes = []interface{}{ + (ChainType)(0), // 0: api.node.v1.ChainType + (ArchiveState)(0), // 1: api.node.v1.ArchiveState + (*Chain)(nil), // 2: api.node.v1.Chain + (*OCR1Config)(nil), // 3: api.node.v1.OCR1Config + (*OCR2Config)(nil), // 4: api.node.v1.OCR2Config + (*ChainConfig)(nil), // 5: api.node.v1.ChainConfig + (*GetNodeRequest)(nil), // 6: api.node.v1.GetNodeRequest + (*GetNodeResponse)(nil), // 7: api.node.v1.GetNodeResponse + (*ListNodesRequest)(nil), // 8: api.node.v1.ListNodesRequest + (*ListNodesResponse)(nil), // 9: api.node.v1.ListNodesResponse + (*ListNodeChainConfigsRequest)(nil), // 10: api.node.v1.ListNodeChainConfigsRequest + (*ListNodeChainConfigsResponse)(nil), // 11: api.node.v1.ListNodeChainConfigsResponse + (*OCR1Config_P2PKeyBundle)(nil), // 12: api.node.v1.OCR1Config.P2PKeyBundle + (*OCR1Config_OCRKeyBundle)(nil), // 13: api.node.v1.OCR1Config.OCRKeyBundle + (*OCR2Config_P2PKeyBundle)(nil), // 14: api.node.v1.OCR2Config.P2PKeyBundle + (*OCR2Config_OCRKeyBundle)(nil), // 15: api.node.v1.OCR2Config.OCRKeyBundle + (*OCR2Config_Plugins)(nil), // 16: api.node.v1.OCR2Config.Plugins + (*ListNodesRequest_Filter)(nil), // 17: api.node.v1.ListNodesRequest.Filter + (*ListNodeChainConfigsRequest_Filter)(nil), // 18: api.node.v1.ListNodeChainConfigsRequest.Filter + (*Node)(nil), // 19: api.node.v1.Node + (*ptypes.Selector)(nil), // 20: api.label.Selector +} +var file_node_v1_node_proto_depIdxs = []int32{ + 0, // 0: api.node.v1.Chain.type:type_name -> api.node.v1.ChainType + 12, // 1: api.node.v1.OCR1Config.p2p_key_bundle:type_name -> api.node.v1.OCR1Config.P2PKeyBundle + 13, // 2: api.node.v1.OCR1Config.ocr_key_bundle:type_name -> api.node.v1.OCR1Config.OCRKeyBundle + 14, // 3: api.node.v1.OCR2Config.p2p_key_bundle:type_name -> api.node.v1.OCR2Config.P2PKeyBundle + 15, // 4: api.node.v1.OCR2Config.ocr_key_bundle:type_name -> api.node.v1.OCR2Config.OCRKeyBundle + 16, // 5: api.node.v1.OCR2Config.plugins:type_name -> api.node.v1.OCR2Config.Plugins + 2, // 6: api.node.v1.ChainConfig.chain:type_name -> api.node.v1.Chain + 3, // 7: api.node.v1.ChainConfig.ocr1_config:type_name -> api.node.v1.OCR1Config + 4, // 8: api.node.v1.ChainConfig.ocr2_config:type_name -> api.node.v1.OCR2Config + 19, // 9: api.node.v1.GetNodeResponse.node:type_name -> api.node.v1.Node + 17, // 10: api.node.v1.ListNodesRequest.filter:type_name -> api.node.v1.ListNodesRequest.Filter + 19, // 11: api.node.v1.ListNodesResponse.nodes:type_name -> api.node.v1.Node + 18, // 12: api.node.v1.ListNodeChainConfigsRequest.filter:type_name -> api.node.v1.ListNodeChainConfigsRequest.Filter + 5, // 13: api.node.v1.ListNodeChainConfigsResponse.chain_configs:type_name -> api.node.v1.ChainConfig + 1, // 14: api.node.v1.ListNodesRequest.Filter.archived:type_name -> api.node.v1.ArchiveState + 20, // 15: api.node.v1.ListNodesRequest.Filter.selectors:type_name -> api.label.Selector + 6, // 16: api.node.v1.NodeService.GetNode:input_type -> api.node.v1.GetNodeRequest + 8, // 17: api.node.v1.NodeService.ListNodes:input_type -> api.node.v1.ListNodesRequest + 10, // 18: api.node.v1.NodeService.ListNodeChainConfigs:input_type -> api.node.v1.ListNodeChainConfigsRequest + 7, // 19: api.node.v1.NodeService.GetNode:output_type -> api.node.v1.GetNodeResponse + 9, // 20: api.node.v1.NodeService.ListNodes:output_type -> api.node.v1.ListNodesResponse + 11, // 21: api.node.v1.NodeService.ListNodeChainConfigs:output_type -> api.node.v1.ListNodeChainConfigsResponse + 19, // [19:22] is the sub-list for method output_type + 16, // [16:19] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name +} + +func init() { file_node_v1_node_proto_init() } +func file_node_v1_node_proto_init() { + if File_node_v1_node_proto != nil { + return + } + file_node_v1_shared_proto_init() + if !protoimpl.UnsafeEnabled { + file_node_v1_node_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Chain); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCR1Config); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCR2Config); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChainConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNodeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNodeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNodesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNodesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNodeChainConfigsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNodeChainConfigsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCR1Config_P2PKeyBundle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCR1Config_OCRKeyBundle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCR2Config_P2PKeyBundle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCR2Config_OCRKeyBundle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCR2Config_Plugins); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNodesRequest_Filter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNodeChainConfigsRequest_Filter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_node_v1_node_proto_rawDesc, + NumEnums: 2, + NumMessages: 17, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_node_v1_node_proto_goTypes, + DependencyIndexes: file_node_v1_node_proto_depIdxs, + EnumInfos: file_node_v1_node_proto_enumTypes, + MessageInfos: file_node_v1_node_proto_msgTypes, + }.Build() + File_node_v1_node_proto = out.File + file_node_v1_node_proto_rawDesc = nil + file_node_v1_node_proto_goTypes = nil + file_node_v1_node_proto_depIdxs = nil +} diff --git a/integration-tests/deployment/jd/node/v1/node_grpc.pb.go b/integration-tests/deployment/jd/node/v1/node_grpc.pb.go new file mode 100644 index 0000000000..d23741687e --- /dev/null +++ b/integration-tests/deployment/jd/node/v1/node_grpc.pb.go @@ -0,0 +1,188 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.25.3 +// source: node/v1/node.proto + +package v1 + +import ( + context "context" + + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + NodeService_GetNode_FullMethodName = "/api.node.v1.NodeService/GetNode" + NodeService_ListNodes_FullMethodName = "/api.node.v1.NodeService/ListNodes" + NodeService_ListNodeChainConfigs_FullMethodName = "/api.node.v1.NodeService/ListNodeChainConfigs" +) + +// NodeServiceClient is the client API for NodeService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type NodeServiceClient interface { + // GetNode retrieves the details of a node by its unique identifier. + GetNode(ctx context.Context, in *GetNodeRequest, opts ...grpc.CallOption) (*GetNodeResponse, error) + // ListNodes returns a list of nodes, optionally filtered by the provided criteria. + ListNodes(ctx context.Context, in *ListNodesRequest, opts ...grpc.CallOption) (*ListNodesResponse, error) + ListNodeChainConfigs(ctx context.Context, in *ListNodeChainConfigsRequest, opts ...grpc.CallOption) (*ListNodeChainConfigsResponse, error) +} + +type nodeServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewNodeServiceClient(cc grpc.ClientConnInterface) NodeServiceClient { + return &nodeServiceClient{cc} +} + +func (c *nodeServiceClient) GetNode(ctx context.Context, in *GetNodeRequest, opts ...grpc.CallOption) (*GetNodeResponse, error) { + out := new(GetNodeResponse) + err := c.cc.Invoke(ctx, NodeService_GetNode_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nodeServiceClient) ListNodes(ctx context.Context, in *ListNodesRequest, opts ...grpc.CallOption) (*ListNodesResponse, error) { + out := new(ListNodesResponse) + err := c.cc.Invoke(ctx, NodeService_ListNodes_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nodeServiceClient) ListNodeChainConfigs(ctx context.Context, in *ListNodeChainConfigsRequest, opts ...grpc.CallOption) (*ListNodeChainConfigsResponse, error) { + out := new(ListNodeChainConfigsResponse) + err := c.cc.Invoke(ctx, NodeService_ListNodeChainConfigs_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// NodeServiceServer is the server API for NodeService service. +// All implementations must embed UnimplementedNodeServiceServer +// for forward compatibility +type NodeServiceServer interface { + // GetNode retrieves the details of a node by its unique identifier. + GetNode(context.Context, *GetNodeRequest) (*GetNodeResponse, error) + // ListNodes returns a list of nodes, optionally filtered by the provided criteria. + ListNodes(context.Context, *ListNodesRequest) (*ListNodesResponse, error) + ListNodeChainConfigs(context.Context, *ListNodeChainConfigsRequest) (*ListNodeChainConfigsResponse, error) + mustEmbedUnimplementedNodeServiceServer() +} + +// UnimplementedNodeServiceServer must be embedded to have forward compatible implementations. +type UnimplementedNodeServiceServer struct { +} + +func (UnimplementedNodeServiceServer) GetNode(context.Context, *GetNodeRequest) (*GetNodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetNode not implemented") +} +func (UnimplementedNodeServiceServer) ListNodes(context.Context, *ListNodesRequest) (*ListNodesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListNodes not implemented") +} +func (UnimplementedNodeServiceServer) ListNodeChainConfigs(context.Context, *ListNodeChainConfigsRequest) (*ListNodeChainConfigsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListNodeChainConfigs not implemented") +} +func (UnimplementedNodeServiceServer) mustEmbedUnimplementedNodeServiceServer() {} + +// UnsafeNodeServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to NodeServiceServer will +// result in compilation errors. +type UnsafeNodeServiceServer interface { + mustEmbedUnimplementedNodeServiceServer() +} + +func RegisterNodeServiceServer(s grpc.ServiceRegistrar, srv NodeServiceServer) { + s.RegisterService(&NodeService_ServiceDesc, srv) +} + +func _NodeService_GetNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).GetNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: NodeService_GetNode_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).GetNode(ctx, req.(*GetNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NodeService_ListNodes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListNodesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).ListNodes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: NodeService_ListNodes_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).ListNodes(ctx, req.(*ListNodesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NodeService_ListNodeChainConfigs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListNodeChainConfigsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).ListNodeChainConfigs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: NodeService_ListNodeChainConfigs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).ListNodeChainConfigs(ctx, req.(*ListNodeChainConfigsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// NodeService_ServiceDesc is the grpc.ServiceDesc for NodeService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var NodeService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "api.node.v1.NodeService", + HandlerType: (*NodeServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetNode", + Handler: _NodeService_GetNode_Handler, + }, + { + MethodName: "ListNodes", + Handler: _NodeService_ListNodes_Handler, + }, + { + MethodName: "ListNodeChainConfigs", + Handler: _NodeService_ListNodeChainConfigs_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "node/v1/node.proto", +} diff --git a/integration-tests/deployment/jd/node/v1/shared.pb.go b/integration-tests/deployment/jd/node/v1/shared.pb.go new file mode 100644 index 0000000000..449de98fd8 --- /dev/null +++ b/integration-tests/deployment/jd/node/v1/shared.pb.go @@ -0,0 +1,240 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.29.0 +// protoc v4.25.3 +// source: node/v1/shared.proto + +package v1 + +import ( + reflect "reflect" + sync "sync" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/shared/ptypes" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Node represents a node within the Job Distributor system. +type Node struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier for the node. + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // Human-readable name for the node. + PublicKey string `protobuf:"bytes,3,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` // Public key used for secure communications. + IsEnabled bool `protobuf:"varint,4,opt,name=is_enabled,json=isEnabled,proto3" json:"is_enabled,omitempty"` // Indicates if the node is currently enabled. + IsConnected bool `protobuf:"varint,5,opt,name=is_connected,json=isConnected,proto3" json:"is_connected,omitempty"` // Indicates if the node is currently connected to the network. + Labels []*ptypes.Label `protobuf:"bytes,6,rep,name=labels,proto3" json:"labels,omitempty"` // Set of labels associated with the node. + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Timestamp when the node was created. + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // Timestamp when the node was last updated. + ArchivedAt *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=archived_at,json=archivedAt,proto3" json:"archived_at,omitempty"` // Timestamp when the node was archived. +} + +func (x *Node) Reset() { + *x = Node{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_shared_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Node) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Node) ProtoMessage() {} + +func (x *Node) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_shared_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Node.ProtoReflect.Descriptor instead. +func (*Node) Descriptor() ([]byte, []int) { + return file_node_v1_shared_proto_rawDescGZIP(), []int{0} +} + +func (x *Node) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Node) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Node) GetPublicKey() string { + if x != nil { + return x.PublicKey + } + return "" +} + +func (x *Node) GetIsEnabled() bool { + if x != nil { + return x.IsEnabled + } + return false +} + +func (x *Node) GetIsConnected() bool { + if x != nil { + return x.IsConnected + } + return false +} + +func (x *Node) GetLabels() []*ptypes.Label { + if x != nil { + return x.Labels + } + return nil +} + +func (x *Node) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Node) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *Node) GetArchivedAt() *timestamppb.Timestamp { + if x != nil { + return x.ArchivedAt + } + return nil +} + +var File_node_v1_shared_proto protoreflect.FileDescriptor + +var file_node_v1_shared_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, + 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0xe8, 0x02, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x69, + 0x73, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x69, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, + 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0b, 0x69, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x28, 0x0a, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3b, 0x0a, + 0x0b, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x42, 0x09, 0x5a, 0x07, 0x6e, 0x6f, + 0x64, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_node_v1_shared_proto_rawDescOnce sync.Once + file_node_v1_shared_proto_rawDescData = file_node_v1_shared_proto_rawDesc +) + +func file_node_v1_shared_proto_rawDescGZIP() []byte { + file_node_v1_shared_proto_rawDescOnce.Do(func() { + file_node_v1_shared_proto_rawDescData = protoimpl.X.CompressGZIP(file_node_v1_shared_proto_rawDescData) + }) + return file_node_v1_shared_proto_rawDescData +} + +var file_node_v1_shared_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_node_v1_shared_proto_goTypes = []interface{}{ + (*Node)(nil), // 0: api.node.v1.Node + (*ptypes.Label)(nil), // 1: api.label.Label + (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp +} +var file_node_v1_shared_proto_depIdxs = []int32{ + 1, // 0: api.node.v1.Node.labels:type_name -> api.label.Label + 2, // 1: api.node.v1.Node.created_at:type_name -> google.protobuf.Timestamp + 2, // 2: api.node.v1.Node.updated_at:type_name -> google.protobuf.Timestamp + 2, // 3: api.node.v1.Node.archived_at:type_name -> google.protobuf.Timestamp + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_node_v1_shared_proto_init() } +func file_node_v1_shared_proto_init() { + if File_node_v1_shared_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_node_v1_shared_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Node); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_node_v1_shared_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_node_v1_shared_proto_goTypes, + DependencyIndexes: file_node_v1_shared_proto_depIdxs, + MessageInfos: file_node_v1_shared_proto_msgTypes, + }.Build() + File_node_v1_shared_proto = out.File + file_node_v1_shared_proto_rawDesc = nil + file_node_v1_shared_proto_goTypes = nil + file_node_v1_shared_proto_depIdxs = nil +} diff --git a/integration-tests/deployment/jd/shared/ptypes/label.pb.go b/integration-tests/deployment/jd/shared/ptypes/label.pb.go new file mode 100644 index 0000000000..a7c374c6d9 --- /dev/null +++ b/integration-tests/deployment/jd/shared/ptypes/label.pb.go @@ -0,0 +1,312 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.29.0 +// protoc v4.25.3 +// source: shared/ptypes/label.proto + +package ptypes + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// SelectorOp defines the operation to be used in a selector +type SelectorOp int32 + +const ( + SelectorOp_EQ SelectorOp = 0 + SelectorOp_NOT_EQ SelectorOp = 1 + SelectorOp_IN SelectorOp = 2 + SelectorOp_NOT_IN SelectorOp = 3 + SelectorOp_EXIST SelectorOp = 4 + SelectorOp_NOT_EXIST SelectorOp = 5 +) + +// Enum value maps for SelectorOp. +var ( + SelectorOp_name = map[int32]string{ + 0: "EQ", + 1: "NOT_EQ", + 2: "IN", + 3: "NOT_IN", + 4: "EXIST", + 5: "NOT_EXIST", + } + SelectorOp_value = map[string]int32{ + "EQ": 0, + "NOT_EQ": 1, + "IN": 2, + "NOT_IN": 3, + "EXIST": 4, + "NOT_EXIST": 5, + } +) + +func (x SelectorOp) Enum() *SelectorOp { + p := new(SelectorOp) + *p = x + return p +} + +func (x SelectorOp) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SelectorOp) Descriptor() protoreflect.EnumDescriptor { + return file_shared_ptypes_label_proto_enumTypes[0].Descriptor() +} + +func (SelectorOp) Type() protoreflect.EnumType { + return &file_shared_ptypes_label_proto_enumTypes[0] +} + +func (x SelectorOp) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SelectorOp.Descriptor instead. +func (SelectorOp) EnumDescriptor() ([]byte, []int) { + return file_shared_ptypes_label_proto_rawDescGZIP(), []int{0} +} + +// Label defines a label as a key value pair +type Label struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value *string `protobuf:"bytes,2,opt,name=value,proto3,oneof" json:"value,omitempty"` +} + +func (x *Label) Reset() { + *x = Label{} + if protoimpl.UnsafeEnabled { + mi := &file_shared_ptypes_label_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Label) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Label) ProtoMessage() {} + +func (x *Label) ProtoReflect() protoreflect.Message { + mi := &file_shared_ptypes_label_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Label.ProtoReflect.Descriptor instead. +func (*Label) Descriptor() ([]byte, []int) { + return file_shared_ptypes_label_proto_rawDescGZIP(), []int{0} +} + +func (x *Label) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *Label) GetValue() string { + if x != nil && x.Value != nil { + return *x.Value + } + return "" +} + +// Selector defines a selector as a key value pair with an operation +type Selector struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Op SelectorOp `protobuf:"varint,2,opt,name=op,proto3,enum=api.label.SelectorOp" json:"op,omitempty"` + Value *string `protobuf:"bytes,3,opt,name=value,proto3,oneof" json:"value,omitempty"` +} + +func (x *Selector) Reset() { + *x = Selector{} + if protoimpl.UnsafeEnabled { + mi := &file_shared_ptypes_label_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Selector) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Selector) ProtoMessage() {} + +func (x *Selector) ProtoReflect() protoreflect.Message { + mi := &file_shared_ptypes_label_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Selector.ProtoReflect.Descriptor instead. +func (*Selector) Descriptor() ([]byte, []int) { + return file_shared_ptypes_label_proto_rawDescGZIP(), []int{1} +} + +func (x *Selector) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *Selector) GetOp() SelectorOp { + if x != nil { + return x.Op + } + return SelectorOp_EQ +} + +func (x *Selector) GetValue() string { + if x != nil && x.Value != nil { + return *x.Value + } + return "" +} + +var File_shared_ptypes_label_proto protoreflect.FileDescriptor + +var file_shared_ptypes_label_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x61, 0x70, 0x69, + 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x3e, 0x0a, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x19, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x68, 0x0a, 0x08, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x25, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x4f, 0x70, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x19, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x2a, 0x4e, 0x0a, 0x0a, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x4f, 0x70, 0x12, 0x06, + 0x0a, 0x02, 0x45, 0x51, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x54, 0x5f, 0x45, 0x51, + 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, + 0x54, 0x5f, 0x49, 0x4e, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x58, 0x49, 0x53, 0x54, 0x10, + 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x10, 0x05, + 0x42, 0x47, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, + 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, + 0x6a, 0x6f, 0x62, 0x2d, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x2f, + 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x68, 0x61, 0x72, + 0x65, 0x64, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_shared_ptypes_label_proto_rawDescOnce sync.Once + file_shared_ptypes_label_proto_rawDescData = file_shared_ptypes_label_proto_rawDesc +) + +func file_shared_ptypes_label_proto_rawDescGZIP() []byte { + file_shared_ptypes_label_proto_rawDescOnce.Do(func() { + file_shared_ptypes_label_proto_rawDescData = protoimpl.X.CompressGZIP(file_shared_ptypes_label_proto_rawDescData) + }) + return file_shared_ptypes_label_proto_rawDescData +} + +var file_shared_ptypes_label_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_shared_ptypes_label_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_shared_ptypes_label_proto_goTypes = []interface{}{ + (SelectorOp)(0), // 0: api.label.SelectorOp + (*Label)(nil), // 1: api.label.Label + (*Selector)(nil), // 2: api.label.Selector +} +var file_shared_ptypes_label_proto_depIdxs = []int32{ + 0, // 0: api.label.Selector.op:type_name -> api.label.SelectorOp + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_shared_ptypes_label_proto_init() } +func file_shared_ptypes_label_proto_init() { + if File_shared_ptypes_label_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_shared_ptypes_label_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Label); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shared_ptypes_label_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Selector); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_shared_ptypes_label_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_shared_ptypes_label_proto_msgTypes[1].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_shared_ptypes_label_proto_rawDesc, + NumEnums: 1, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_shared_ptypes_label_proto_goTypes, + DependencyIndexes: file_shared_ptypes_label_proto_depIdxs, + EnumInfos: file_shared_ptypes_label_proto_enumTypes, + MessageInfos: file_shared_ptypes_label_proto_msgTypes, + }.Build() + File_shared_ptypes_label_proto = out.File + file_shared_ptypes_label_proto_rawDesc = nil + file_shared_ptypes_label_proto_goTypes = nil + file_shared_ptypes_label_proto_depIdxs = nil +} diff --git a/integration-tests/deployment/memory/chain.go b/integration-tests/deployment/memory/chain.go new file mode 100644 index 0000000000..153d9d19e9 --- /dev/null +++ b/integration-tests/deployment/memory/chain.go @@ -0,0 +1,74 @@ +package memory + +import ( + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + gethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" +) + +type EVMChain struct { + Backend *backends.SimulatedBackend + DeployerKey *bind.TransactOpts +} + +// CCIP relies on block timestamps, but SimulatedBackend uses by default clock starting from 1970-01-01 +// This trick is used to move the clock closer to the current time. We set first block to be X hours ago. +// Tests create plenty of transactions so this number can't be too low, every new block mined will tick the clock, +// if you mine more than "X hours" transactions, SimulatedBackend will panic because generated timestamps will be in the future. +func tweakChainTimestamp(t *testing.T, backend *backends.SimulatedBackend, tweak time.Duration) { + blockTime := time.Unix(int64(backend.Blockchain().CurrentHeader().Time), 0) + sinceBlockTime := time.Since(blockTime) + diff := sinceBlockTime - tweak + err := backend.AdjustTime(diff) + require.NoError(t, err, "unable to adjust time on simulated chain") + backend.Commit() + backend.Commit() +} + +func fundAddress(t *testing.T, from *bind.TransactOpts, to common.Address, amount *big.Int, backend *backends.SimulatedBackend) { + nonce, err := backend.PendingNonceAt(Context(t), from.From) + require.NoError(t, err) + gp, err := backend.SuggestGasPrice(Context(t)) + require.NoError(t, err) + rawTx := gethtypes.NewTx(&gethtypes.LegacyTx{ + Nonce: nonce, + GasPrice: gp, + Gas: 21000, + To: &to, + Value: amount, + }) + signedTx, err := from.Signer(from.From, rawTx) + require.NoError(t, err) + err = backend.SendTransaction(Context(t), signedTx) + require.NoError(t, err) + backend.Commit() +} + +func GenerateChains(t *testing.T, numChains int) map[uint64]EVMChain { + chains := make(map[uint64]EVMChain) + for i := 0; i < numChains; i++ { + chainID := chainsel.TEST_90000001.EvmChainID + uint64(i) + key, err := crypto.GenerateKey() + require.NoError(t, err) + owner, err := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + require.NoError(t, err) + backend := backends.NewSimulatedBackend(core.GenesisAlloc{ + owner.From: {Balance: big.NewInt(0).Mul(big.NewInt(100), big.NewInt(params.Ether))}}, 10000000) + tweakChainTimestamp(t, backend, time.Hour*8) + chains[chainID] = EVMChain{ + Backend: backend, + DeployerKey: owner, + } + } + return chains +} diff --git a/integration-tests/deployment/memory/environment.go b/integration-tests/deployment/memory/environment.go new file mode 100644 index 0000000000..4d5d6a3c27 --- /dev/null +++ b/integration-tests/deployment/memory/environment.go @@ -0,0 +1,139 @@ +package memory + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/hashicorp/consul/sdk/freeport" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" +) + +const ( + Memory = "memory" +) + +type MemoryEnvironmentConfig struct { + Chains int + Nodes int + Bootstraps int + RegistryConfig RegistryConfig +} + +// Needed for environment variables on the node which point to prexisitng addresses. +// i.e. CapReg. +func NewMemoryChains(t *testing.T, numChains int) map[uint64]deployment.Chain { + mchains := GenerateChains(t, numChains) + chains := make(map[uint64]deployment.Chain) + for cid, chain := range mchains { + sel, err := chainsel.SelectorFromChainId(cid) + require.NoError(t, err) + chains[sel] = deployment.Chain{ + Selector: sel, + Client: chain.Backend, + DeployerKey: chain.DeployerKey, + Confirm: func(tx common.Hash) (uint64, error) { + for { + chain.Backend.Commit() + receipt, err := chain.Backend.TransactionReceipt(context.Background(), tx) + if err != nil { + t.Log("failed to get receipt", err) + continue + } + if receipt.Status == 0 { + t.Logf("Status (reverted) %d for txhash %s\n", receipt.Status, tx.String()) + } + return receipt.BlockNumber.Uint64(), nil + } + }, + } + } + return chains +} + +func NewNodes(t *testing.T, logLevel zapcore.Level, chains map[uint64]deployment.Chain, numNodes, numBootstraps int, registryConfig RegistryConfig) map[string]Node { + mchains := make(map[uint64]EVMChain) + for _, chain := range chains { + evmChainID, err := chainsel.ChainIdFromSelector(chain.Selector) + if err != nil { + t.Fatal(err) + } + mchains[evmChainID] = EVMChain{ + Backend: chain.Client.(*backends.SimulatedBackend), + DeployerKey: chain.DeployerKey, + } + } + nodesByPeerID := make(map[string]Node) + ports := freeport.GetN(t, numNodes) + var existingNumBootstraps int + for i := 0; i < numNodes; i++ { + bootstrap := false + if existingNumBootstraps < numBootstraps { + bootstrap = true + existingNumBootstraps++ + } + node := NewNode(t, ports[i], mchains, logLevel, bootstrap, registryConfig) + nodesByPeerID[node.Keys.PeerID.String()] = *node + // Note in real env, this ID is allocated by JD. + } + return nodesByPeerID +} + +func NewMemoryEnvironmentFromChainsNodes(t *testing.T, + lggr logger.Logger, + chains map[uint64]deployment.Chain, + nodes map[string]Node) deployment.Environment { + var nodeIDs []string + for id := range nodes { + nodeIDs = append(nodeIDs, id) + } + return deployment.Environment{ + Name: Memory, + Offchain: NewMemoryJobClient(nodes), + // Note these have the p2p_ prefix. + NodeIDs: nodeIDs, + Chains: chains, + Logger: lggr, + } +} + +//func NewMemoryEnvironmentExistingChains(t *testing.T, lggr logger.Logger, +// chains map[uint64]deployment.Chain, config MemoryEnvironmentConfig) deployment.Environment { +// nodes := NewNodes(t, chains, config.Nodes, config.Bootstraps, config.RegistryConfig) +// var nodeIDs []string +// for id := range nodes { +// nodeIDs = append(nodeIDs, id) +// } +// return deployment.Environment{ +// Name: Memory, +// Offchain: NewMemoryJobClient(nodes), +// // Note these have the p2p_ prefix. +// NodeIDs: nodeIDs, +// Chains: chains, +// Logger: lggr, +// } +//} + +// To be used by tests and any kind of deployment logic. +func NewMemoryEnvironment(t *testing.T, lggr logger.Logger, logLevel zapcore.Level, config MemoryEnvironmentConfig) deployment.Environment { + chains := NewMemoryChains(t, config.Chains) + nodes := NewNodes(t, logLevel, chains, config.Nodes, config.Bootstraps, config.RegistryConfig) + var nodeIDs []string + for id := range nodes { + nodeIDs = append(nodeIDs, id) + } + return deployment.Environment{ + Name: Memory, + Offchain: NewMemoryJobClient(nodes), + NodeIDs: nodeIDs, + Chains: chains, + Logger: lggr, + } +} diff --git a/integration-tests/deployment/memory/job_client.go b/integration-tests/deployment/memory/job_client.go new file mode 100644 index 0000000000..326ae6093b --- /dev/null +++ b/integration-tests/deployment/memory/job_client.go @@ -0,0 +1,126 @@ +package memory + +import ( + "context" + "strconv" + + "github.com/ethereum/go-ethereum/common" + "google.golang.org/grpc" + + jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" + nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" +) + +type JobClient struct { + Nodes map[string]Node +} + +func (j JobClient) GetNode(ctx context.Context, in *nodev1.GetNodeRequest, opts ...grpc.CallOption) (*nodev1.GetNodeResponse, error) { + //TODO CCIP-3108 + panic("implement me") +} + +func (j JobClient) ListNodes(ctx context.Context, in *nodev1.ListNodesRequest, opts ...grpc.CallOption) (*nodev1.ListNodesResponse, error) { + //TODO CCIP-3108 + panic("implement me") +} + +func (j JobClient) ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNodeChainConfigsRequest, opts ...grpc.CallOption) (*nodev1.ListNodeChainConfigsResponse, error) { + n := j.Nodes[in.Filter.NodeId] + offpk := n.Keys.OCRKeyBundle.OffchainPublicKey() + cpk := n.Keys.OCRKeyBundle.ConfigEncryptionPublicKey() + var chainConfigs []*nodev1.ChainConfig + for evmChainID, transmitter := range n.Keys.TransmittersByEVMChainID { + chainConfigs = append(chainConfigs, &nodev1.ChainConfig{ + Chain: &nodev1.Chain{ + Id: strconv.Itoa(int(evmChainID)), + Type: nodev1.ChainType_CHAIN_TYPE_EVM, + }, + AccountAddress: transmitter.String(), + AdminAddress: "", + Ocr1Config: nil, + Ocr2Config: &nodev1.OCR2Config{ + Enabled: true, + IsBootstrap: n.IsBoostrap, + P2PKeyBundle: &nodev1.OCR2Config_P2PKeyBundle{ + PeerId: n.Keys.PeerID.String(), + }, + OcrKeyBundle: &nodev1.OCR2Config_OCRKeyBundle{ + BundleId: n.Keys.OCRKeyBundle.ID(), + ConfigPublicKey: common.Bytes2Hex(cpk[:]), + OffchainPublicKey: common.Bytes2Hex(offpk[:]), + OnchainSigningAddress: n.Keys.OCRKeyBundle.OnChainPublicKey(), + }, + Multiaddr: n.Addr.String(), + Plugins: nil, + ForwarderAddress: "", + }, + }) + } + + // TODO: I think we can pull it from the feeds manager. + return &nodev1.ListNodeChainConfigsResponse{ + ChainConfigs: chainConfigs, + }, nil +} + +func (j JobClient) GetJob(ctx context.Context, in *jobv1.GetJobRequest, opts ...grpc.CallOption) (*jobv1.GetJobResponse, error) { + //TODO CCIP-3108 + panic("implement me") +} + +func (j JobClient) GetProposal(ctx context.Context, in *jobv1.GetProposalRequest, opts ...grpc.CallOption) (*jobv1.GetProposalResponse, error) { + //TODO CCIP-3108 + panic("implement me") +} + +func (j JobClient) ListJobs(ctx context.Context, in *jobv1.ListJobsRequest, opts ...grpc.CallOption) (*jobv1.ListJobsResponse, error) { + //TODO CCIP-3108 + panic("implement me") +} + +func (j JobClient) ListProposals(ctx context.Context, in *jobv1.ListProposalsRequest, opts ...grpc.CallOption) (*jobv1.ListProposalsResponse, error) { + //TODO CCIP-3108 + panic("implement me") +} + +func (j JobClient) ProposeJob(ctx context.Context, in *jobv1.ProposeJobRequest, opts ...grpc.CallOption) (*jobv1.ProposeJobResponse, error) { + n := j.Nodes[in.NodeId] + // TODO: Use FMS + jb, err := validate.ValidatedCCIPSpec(in.Spec) + if err != nil { + return nil, err + } + err = n.App.AddJobV2(ctx, &jb) + if err != nil { + return nil, err + } + return &jobv1.ProposeJobResponse{Proposal: &jobv1.Proposal{ + Id: "", + Version: 0, + // Auto approve for now + Status: jobv1.ProposalStatus_PROPOSAL_STATUS_APPROVED, + DeliveryStatus: jobv1.ProposalDeliveryStatus_PROPOSAL_DELIVERY_STATUS_DELIVERED, + Spec: in.Spec, + JobId: jb.ExternalJobID.String(), + CreatedAt: nil, + UpdatedAt: nil, + AckedAt: nil, + ResponseReceivedAt: nil, + }}, nil +} + +func (j JobClient) RevokeJob(ctx context.Context, in *jobv1.RevokeJobRequest, opts ...grpc.CallOption) (*jobv1.RevokeJobResponse, error) { + //TODO CCIP-3108 + panic("implement me") +} + +func (j JobClient) DeleteJob(ctx context.Context, in *jobv1.DeleteJobRequest, opts ...grpc.CallOption) (*jobv1.DeleteJobResponse, error) { + //TODO CCIP-3108 + panic("implement me") +} + +func NewMemoryJobClient(nodesByPeerID map[string]Node) *JobClient { + return &JobClient{nodesByPeerID} +} diff --git a/integration-tests/deployment/memory/node.go b/integration-tests/deployment/memory/node.go new file mode 100644 index 0000000000..55ecd23337 --- /dev/null +++ b/integration-tests/deployment/memory/node.go @@ -0,0 +1,292 @@ +package memory + +import ( + "context" + "fmt" + "math/big" + "net" + "net/http" + "strconv" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + gethtypes "github.com/ethereum/go-ethereum/core/types" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + v2toml "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + evmutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + configv2 "github.com/smartcontractkit/chainlink/v2/core/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/logger/audit" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" + "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" + "github.com/smartcontractkit/chainlink/v2/plugins" +) + +func Context(tb testing.TB) context.Context { + ctx := context.Background() + var cancel func() + switch t := tb.(type) { + case *testing.T: + if d, ok := t.Deadline(); ok { + ctx, cancel = context.WithDeadline(ctx, d) + } + } + if cancel == nil { + ctx, cancel = context.WithCancel(ctx) + } + tb.Cleanup(cancel) + return ctx +} + +type Node struct { + App chainlink.Application + // Transmitter key/OCR keys for this node + Keys Keys + Addr net.TCPAddr + IsBoostrap bool +} + +func (n Node) ReplayLogs(chains map[uint64]uint64) error { + for sel, block := range chains { + chainID, _ := chainsel.ChainIdFromSelector(sel) + if err := n.App.ReplayFromBlock(big.NewInt(int64(chainID)), block, false); err != nil { + return err + } + } + return nil +} + +type RegistryConfig struct { + EVMChainID uint64 + Contract common.Address +} + +// Creates a CL node which is: +// - Configured for OCR +// - Configured for the chains specified +// - Transmitter keys funded. +func NewNode( + t *testing.T, + port int, // Port for the P2P V2 listener. + chains map[uint64]EVMChain, + logLevel zapcore.Level, + bootstrap bool, + registryConfig RegistryConfig, +) *Node { + // Do not want to load fixtures as they contain a dummy chainID. + // Create database and initial configuration. + cfg, db := heavyweight.FullTestDBNoFixturesV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.Insecure.OCRDevelopmentMode = ptr(true) // Disables ocr spec validation so we can have fast polling for the test. + + c.Feature.LogPoller = ptr(true) + + // P2P V2 configs. + c.P2P.V2.Enabled = ptr(true) + c.P2P.V2.DeltaDial = config.MustNewDuration(500 * time.Millisecond) + c.P2P.V2.DeltaReconcile = config.MustNewDuration(5 * time.Second) + c.P2P.V2.ListenAddresses = &[]string{fmt.Sprintf("127.0.0.1:%d", port)} + + // Enable Capabilities, This is a pre-requisite for registrySyncer to work. + if registryConfig.Contract != common.HexToAddress("0x0") { + c.Capabilities.ExternalRegistry.NetworkID = ptr(relay.NetworkEVM) + c.Capabilities.ExternalRegistry.ChainID = ptr(strconv.FormatUint(uint64(registryConfig.EVMChainID), 10)) + c.Capabilities.ExternalRegistry.Address = ptr(registryConfig.Contract.String()) + } + + // OCR configs + c.OCR.Enabled = ptr(false) + c.OCR.DefaultTransactionQueueDepth = ptr(uint32(200)) + c.OCR2.Enabled = ptr(true) + c.OCR2.ContractPollInterval = config.MustNewDuration(5 * time.Second) + + c.Log.Level = ptr(configv2.LogLevel(logLevel)) + + var chainConfigs v2toml.EVMConfigs + for chainID := range chains { + chainConfigs = append(chainConfigs, createConfigV2Chain(chainID)) + } + c.EVM = chainConfigs + }) + + // Set logging. + lggr := logger.TestLogger(t) + lggr.SetLogLevel(logLevel) + + // Create clients for the core node backed by sim. + clients := make(map[uint64]client.Client) + for chainID, chain := range chains { + clients[chainID] = client.NewSimulatedBackendClient(t, chain.Backend, big.NewInt(int64(chainID))) + } + + // Create keystore + master := keystore.New(db, utils.FastScryptParams, lggr) + kStore := KeystoreSim{ + eks: &EthKeystoreSim{ + Eth: master.Eth(), + }, + csa: master.CSA(), + } + + // Build evm factory using clients + keystore. + mailMon := mailbox.NewMonitor("node", lggr.Named("mailbox")) + evmOpts := chainlink.EVMFactoryConfig{ + ChainOpts: legacyevm.ChainOpts{ + AppConfig: cfg, + GenEthClient: func(i *big.Int) client.Client { + ethClient, ok := clients[i.Uint64()] + if !ok { + t.Fatal("no backend for chainID", i) + } + return ethClient + }, + MailMon: mailMon, + DS: db, + }, + CSAETHKeystore: kStore, + } + + // Build relayer factory with EVM. + relayerFactory := chainlink.RelayerFactory{ + Logger: lggr, + LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), cfg.Tracing()), + GRPCOpts: loop.GRPCOpts{}, + } + initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitEVM(context.Background(), relayerFactory, evmOpts)} + rci, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) + require.NoError(t, err) + + app, err := chainlink.NewApplication(chainlink.ApplicationOpts{ + Config: cfg, + DS: db, + KeyStore: master, + RelayerChainInteroperators: rci, + Logger: lggr, + ExternalInitiatorManager: nil, + CloseLogger: lggr.Sync, + UnrestrictedHTTPClient: &http.Client{}, + RestrictedHTTPClient: &http.Client{}, + AuditLogger: audit.NoopLogger, + MailMon: mailMon, + LoopRegistry: plugins.NewLoopRegistry(lggr, cfg.Tracing()), + }) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, db.Close()) + }) + keys := CreateKeys(t, app, chains) + + return &Node{ + App: app, + Keys: keys, + Addr: net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: port}, + IsBoostrap: bootstrap, + } +} + +type Keys struct { + PeerID p2pkey.PeerID + TransmittersByEVMChainID map[uint64]common.Address + OCRKeyBundle ocr2key.KeyBundle +} + +func CreateKeys(t *testing.T, + app chainlink.Application, chains map[uint64]EVMChain) Keys { + ctx := Context(t) + require.NoError(t, app.GetKeyStore().Unlock(ctx, "password")) + _, err := app.GetKeyStore().P2P().Create(ctx) + require.NoError(t, err) + + p2pIDs, err := app.GetKeyStore().P2P().GetAll() + require.NoError(t, err) + require.Len(t, p2pIDs, 1) + peerID := p2pIDs[0].PeerID() + // create a transmitter for each chain + transmitters := make(map[uint64]common.Address) + for chainID, chain := range chains { + cid := big.NewInt(int64(chainID)) + addrs, err2 := app.GetKeyStore().Eth().EnabledAddressesForChain(Context(t), cid) + require.NoError(t, err2) + if len(addrs) == 1 { + // just fund the address + fundAddress(t, chain.DeployerKey, addrs[0], assets.Ether(10).ToInt(), chain.Backend) + transmitters[chainID] = addrs[0] + } else { + // create key and fund it + _, err3 := app.GetKeyStore().Eth().Create(Context(t), cid) + require.NoError(t, err3, "failed to create key for chain", chainID) + sendingKeys, err3 := app.GetKeyStore().Eth().EnabledAddressesForChain(Context(t), cid) + require.NoError(t, err3) + require.Len(t, sendingKeys, 1) + fundAddress(t, chain.DeployerKey, sendingKeys[0], assets.Ether(10).ToInt(), chain.Backend) + transmitters[chainID] = sendingKeys[0] + } + } + require.Len(t, transmitters, len(chains)) + + keybundle, err := app.GetKeyStore().OCR2().Create(ctx, chaintype.EVM) + require.NoError(t, err) + return Keys{ + PeerID: peerID, + TransmittersByEVMChainID: transmitters, + OCRKeyBundle: keybundle, + } +} + +func createConfigV2Chain(chainID uint64) *v2toml.EVMConfig { + chainIDBig := evmutils.NewI(int64(chainID)) + chain := v2toml.Defaults(chainIDBig) + chain.GasEstimator.LimitDefault = ptr(uint64(5e6)) + chain.LogPollInterval = config.MustNewDuration(1000 * time.Millisecond) + chain.Transactions.ForwardersEnabled = ptr(false) + chain.FinalityDepth = ptr(uint32(2)) + return &v2toml.EVMConfig{ + ChainID: chainIDBig, + Enabled: ptr(true), + Chain: chain, + Nodes: v2toml.EVMNodes{&v2toml.Node{}}, + } +} + +func ptr[T any](v T) *T { return &v } + +var _ keystore.Eth = &EthKeystoreSim{} + +type EthKeystoreSim struct { + keystore.Eth +} + +// override +func (e *EthKeystoreSim) SignTx(ctx context.Context, address common.Address, tx *gethtypes.Transaction, chainID *big.Int) (*gethtypes.Transaction, error) { + // always sign with chain id 1337 for the simulated backend + return e.Eth.SignTx(ctx, address, tx, big.NewInt(1337)) +} + +type KeystoreSim struct { + eks keystore.Eth + csa keystore.CSA +} + +func (e KeystoreSim) Eth() keystore.Eth { + return e.eks +} + +func (e KeystoreSim) CSA() keystore.CSA { + return e.csa +} diff --git a/integration-tests/deployment/memory/node_test.go b/integration-tests/deployment/memory/node_test.go new file mode 100644 index 0000000000..d64c7717fc --- /dev/null +++ b/integration-tests/deployment/memory/node_test.go @@ -0,0 +1,23 @@ +package memory + +import ( + "testing" + + "github.com/hashicorp/consul/sdk/freeport" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" +) + +func TestNode(t *testing.T) { + chains := GenerateChains(t, 3) + ports := freeport.GetN(t, 1) + node := NewNode(t, ports[0], chains, zapcore.DebugLevel, false, RegistryConfig{}) + // We expect 3 transmitter keys + keys, err := node.App.GetKeyStore().Eth().GetAll(Context(t)) + require.NoError(t, err) + require.Len(t, keys, 3) + // We expect 3 chains supported + evmChains := node.App.GetRelayers().LegacyEVMChains().Slice() + require.NoError(t, err) + require.Len(t, evmChains, 3) +} diff --git a/integration-tests/go.mod b/integration-tests/go.mod index d50ac2673e..8fca475001 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -8,6 +8,7 @@ replace github.com/smartcontractkit/chainlink/v2 => ../ require ( dario.cat/mergo v1.0.0 github.com/AlekSi/pointer v1.1.0 + github.com/Khan/genqlient v0.7.0 github.com/Masterminds/semver/v3 v3.2.1 github.com/avast/retry-go/v4 v4.6.0 github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df @@ -18,6 +19,7 @@ require ( github.com/go-resty/resty/v2 v2.11.0 github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 + github.com/hashicorp/consul/sdk v0.16.0 github.com/jmoiron/sqlx v1.4.0 github.com/lib/pq v1.10.9 github.com/manifoldco/promptui v0.9.0 @@ -31,6 +33,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 + github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 @@ -53,7 +56,10 @@ require ( golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa golang.org/x/sync v0.8.0 golang.org/x/text v0.17.0 + google.golang.org/grpc v1.65.0 + google.golang.org/protobuf v1.34.2 gopkg.in/guregu/null.v4 v4.0.0 + gotest.tools/v3 v3.5.1 k8s.io/apimachinery v0.31.0 ) @@ -64,9 +70,9 @@ require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect - cosmossdk.io/depinject v1.0.0-alpha.3 // indirect - cosmossdk.io/errors v1.0.0 // indirect - cosmossdk.io/math v1.0.1 // indirect + cosmossdk.io/depinject v1.0.0-alpha.4 // indirect + cosmossdk.io/errors v1.0.1 // indirect + cosmossdk.io/math v1.3.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect @@ -76,7 +82,7 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect - github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/CosmWasm/wasmd v0.40.1 // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect @@ -85,13 +91,16 @@ require ( github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/Microsoft/hcsshim v0.11.5 // indirect github.com/NethermindEth/juno v0.3.1 // indirect github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/XSAM/otelsql v0.27.0 // indirect + github.com/agnivade/levenshtein v1.1.1 // indirect github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect + github.com/alexflint/go-arg v1.4.2 // indirect + github.com/alexflint/go-scalar v1.0.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/avast/retry-go v3.0.0+incompatible // indirect @@ -135,29 +144,30 @@ require ( github.com/chenzhuoyu/iasm v0.9.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cli/safeexec v1.0.0 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/errors v1.10.0 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.37.2 // indirect - github.com/cometbft/cometbft-db v0.7.0 // indirect + github.com/cometbft/cometbft v0.37.5 // indirect + github.com/cometbft/cometbft-db v0.8.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/containerd/containerd v1.7.12 // indirect + github.com/containerd/containerd v1.7.18 // indirect + github.com/containerd/errdefs v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect - github.com/cosmos/cosmos-sdk v0.47.4 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect + github.com/cosmos/cosmos-sdk v0.47.11 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.11 // indirect - github.com/cosmos/iavl v0.20.0 // indirect - github.com/cosmos/ibc-go/v7 v7.0.1 // indirect - github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect - github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect + github.com/cosmos/iavl v0.20.1 // indirect + github.com/cosmos/ibc-go/v7 v7.5.1 // indirect + github.com/cosmos/ics23/go v0.10.0 // indirect + github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect @@ -171,7 +181,7 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/distribution/reference v0.5.0 // indirect + github.com/distribution/reference v0.6.0 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v25.0.2+incompatible // indirect github.com/docker/go-connections v0.5.0 // indirect @@ -190,13 +200,13 @@ require ( github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/solana-go v1.8.4 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect - github.com/getsentry/sentry-go v0.19.0 // indirect + github.com/getsentry/sentry-go v0.23.0 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-gonic/gin v1.9.1 // indirect @@ -209,7 +219,7 @@ require ( github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.4 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect @@ -221,7 +231,7 @@ require ( github.com/go-openapi/validate v0.22.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.15.5 // indirect + github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect @@ -243,7 +253,6 @@ require ( github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect - github.com/google/s2a-go v0.1.7 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/context v1.1.1 // indirect github.com/gorilla/mux v1.8.0 // indirect @@ -269,8 +278,7 @@ require ( github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect - github.com/hashicorp/consul/api v1.25.1 // indirect - github.com/hashicorp/consul/sdk v0.16.0 // indirect + github.com/hashicorp/consul/api v1.28.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-envparse v0.1.0 // indirect @@ -321,9 +329,10 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect + github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -361,7 +370,7 @@ require ( github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc5 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect github.com/opencontainers/runc v1.1.7 // indirect github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e // indirect github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect @@ -381,12 +390,14 @@ require ( github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/prometheus/prometheus v0.48.1 // indirect + github.com/prometheus/prometheus v1.8.2-0.20200727090838-6f296594a852 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect @@ -403,21 +414,20 @@ require ( github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect - github.com/smartcontractkit/wsrpc v0.7.3 // indirect + github.com/smartcontractkit/wsrpc v0.8.1 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect - github.com/spf13/afero v1.9.5 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.15.0 // indirect + github.com/spf13/viper v1.19.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/subosito/gotenv v1.4.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect - github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a // indirect @@ -434,12 +444,13 @@ require ( github.com/ugorji/go/codec v1.2.12 // indirect github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 // indirect github.com/valyala/fastjson v1.4.1 // indirect + github.com/vektah/gqlparser/v2 v2.5.11 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zondax/hid v0.9.1 // indirect - github.com/zondax/ledger-go v0.14.1 // indirect + github.com/zondax/hid v0.9.2 // indirect + github.com/zondax/ledger-go v0.14.3 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect go.etcd.io/bbolt v1.3.9 // indirect @@ -476,8 +487,6 @@ require ( google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/grpc v1.65.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect @@ -493,8 +502,8 @@ require ( k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect k8s.io/kubectl v0.31.0 // indirect k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect - nhooyr.io/websocket v1.8.7 // indirect - pgregory.net/rapid v0.5.5 // indirect + nhooyr.io/websocket v1.8.10 // indirect + pgregory.net/rapid v1.1.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/controller-runtime v0.19.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 5bd93085ea..7f58213cf4 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -4,7 +4,6 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -15,9 +14,6 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= @@ -48,7 +44,6 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= @@ -59,14 +54,14 @@ cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= -cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= -cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= -cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= -cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= -cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca h1:msenprh2BLLRwNT7zN56TbBHOGk/7ARQckXHxXyvjoQ= -cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c= -cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= -cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= +cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= +cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= +cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= +cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= +cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= +cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= +cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= +cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= @@ -83,7 +78,6 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9 github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-sdk-for-go v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw= github.com/Azure/azure-sdk-for-go v65.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 h1:9kDVnTz3vbfweTqAUmk/a/pH5pWFCHtvRpHYC0G/dcA= @@ -116,10 +110,8 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 h1:WpB/QDNLpMw github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= +github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= github.com/CosmWasm/wasmd v0.40.1/go.mod h1:6EOwnv7MpuFaEqxcUOdFV9i4yvrdOciaY6VQ1o7A3yg= github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= @@ -133,11 +125,12 @@ github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/K-Phoen/grabana v0.22.1 h1:b/O+C3H2H6VNYSeMCYUO4X4wYuwFXgBcRkvYa+fjpQA= github.com/K-Phoen/grabana v0.22.1/go.mod h1:3LTXrTzQzTKTgvKSXdRjlsJbizSOW/V23Q3iX00R5bU= github.com/K-Phoen/sdk v0.12.4 h1:j2EYuBJm3zDTD0fGKACVFWxAXtkR0q5QzfVqxmHSeGQ= github.com/K-Phoen/sdk v0.12.4/go.mod h1:qmM0wO23CtoDux528MXPpYvS4XkRWkWX6rvX9Za8EVU= +github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= +github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -148,10 +141,10 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0 github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= -github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/Microsoft/hcsshim v0.11.5 h1:haEcLNpj9Ka1gd3B3tAEs9CpE0c+1IhoL59w/exYU38= +github.com/Microsoft/hcsshim v0.11.5/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU= github.com/NethermindEth/juno v0.3.1 h1:AW72LiAm9gqUeCVJWvepnZcTnpU4Vkl0KzPMxS+42FA= github.com/NethermindEth/juno v0.3.1/go.mod h1:SGbTpgGaCsxhFsKOid7Ylnz//WZ8swtILk+NbHGsk/Q= github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb h1:Mv8SscePPyw2ju4igIJAjFgcq5zCQfjgbz53DwYu5mc= @@ -163,7 +156,6 @@ github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8 github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= @@ -172,17 +164,20 @@ github.com/Workiva/go-datastructures v1.1.0 h1:hu20UpgZneBhQ3ZvwiOGlqJSKIosin2Rd github.com/Workiva/go-datastructures v1.1.0/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= +github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= -github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= -github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg= github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= +github.com/alexflint/go-arg v1.4.2 h1:lDWZAXxpAnZUq4qwb86p/3rIJJ2Li81EoMbTMujhVa0= +github.com/alexflint/go-arg v1.4.2/go.mod h1:9iRbDxne7LcR/GSvEr7ma++GLpdIU1zrghf2y2768kM= +github.com/alexflint/go-scalar v1.0.0 h1:NGupf1XV/Xb04wXskDFzS0KWOLH632W/EO4fAFi+A70= +github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis v2.5.0+incompatible h1:yBHoLpsyjupjz3NL3MhKMVkR41j82Yjf3KFv7ApYzUI= @@ -192,7 +187,11 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -248,7 +247,6 @@ github.com/aws/jsii-runtime-go v1.75.0 h1:NhpUfyiL7/wsRuUekFsz8FFBCYLfPD/l61kKg9 github.com/aws/jsii-runtime-go v1.75.0/go.mod h1:TKCyrtM0pygEPo4rDZzbMSDNCDNTSYSN6/mGyHI6O3I= github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= @@ -270,6 +268,8 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= +github.com/bradleyjkemp/cupaloy/v2 v2.6.0 h1:knToPYa2xtfg42U3I6punFEjaGFKWQRXJwj0JTv4mTs= +github.com/bradleyjkemp/cupaloy/v2 v2.6.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= @@ -336,7 +336,6 @@ github.com/cli/shurcooL-graphql v0.0.3 h1:CtpPxyGDs136/+ZeyAfUKYmcQBjDlq5aqnrDCW github.com/cli/shurcooL-graphql v0.0.3/go.mod h1:tlrLmw/n5Q/+4qSvosT+9/W5zc8ZMjnJeYBxSdb4nWA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw= github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= @@ -344,39 +343,36 @@ github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= -github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= -github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/errors v1.10.0 h1:lfxS8zZz1+OjtV4MtNWgboi/W5tyLEB6VQZBXN+0VUU= +github.com/cockroachdb/errors v1.10.0/go.mod h1:lknhIsEVQ9Ss/qKDBQS/UqFSvPQjOwNq2qyKAxtHRqE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= -github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= -github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= -github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= -github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= +github.com/cometbft/cometbft v0.37.5 h1:/U/TlgMh4NdnXNo+YU9T2NMCWyhXNDF34Mx582jlvq0= +github.com/cometbft/cometbft v0.37.5/go.mod h1:QC+mU0lBhKn8r9qvmnq53Dmf3DWBt4VtkcKw2C81wxY= +github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= +github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= -github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= +github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao= +github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= +github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -394,10 +390,10 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= -github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.47.4 h1:FVUpEprm58nMmBX4xkRdMDaIG5Nr4yy92HZAfGAw9bg= -github.com/cosmos/cosmos-sdk v0.47.4/go.mod h1:R5n+uM7vguVPFap4pgkdvQCT1nVo/OtPwrlAU40rvok= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= +github.com/cosmos/cosmos-sdk v0.47.11 h1:0Qx7eORw0RJqPv+mvDuU8NQ1LV3nJJKJnPoYblWHolc= +github.com/cosmos/cosmos-sdk v0.47.11/go.mod h1:ADjORYzUQqQv/FxDi0H0K5gW/rAk1CiDR3ZKsExfJV0= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -405,14 +401,14 @@ github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiK github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= -github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= -github.com/cosmos/ibc-go/v7 v7.0.1 h1:NIBNRWjlOoFvFQu1ZlgwkaSeHO5avf4C1YQiWegt8jw= -github.com/cosmos/ibc-go/v7 v7.0.1/go.mod h1:vEaapV6nuLPQlS+g8IKmxMo6auPi0i7HMv1PhViht/E= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= -github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= -github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/iavl v0.20.1 h1:rM1kqeG3/HBT85vsZdoSNsehciqUQPWrR4BYmqE2+zg= +github.com/cosmos/iavl v0.20.1/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/ibc-go/v7 v7.5.1 h1:KqS/g7W7EMX1OtOvufS8lWMJibOKpdgtNNZIU6fAgVU= +github.com/cosmos/ibc-go/v7 v7.5.1/go.mod h1:ktFg5GvKOyrGCqTWtW7Grj5uweU4ZapxrNeVS1CLLbo= +github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= +github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= +github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw= +github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M= github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= @@ -432,10 +428,6 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= -github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= -github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= -github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -458,7 +450,6 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFM github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70/go.mod h1:EoK/8RFbMEteaCaz89uessDTnCWjbbcr+DXcBh4el5o= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= @@ -470,10 +461,12 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E= github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA= -github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= -github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= @@ -493,15 +486,12 @@ github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9Tzqv github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjletLK6K0rbxyZI= github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= @@ -509,7 +499,6 @@ github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/esote/minmaxheap v1.0.0 h1:rgA7StnXXpZG6qlM0S7pUmEv1KpWe32rYT4x8J8ntaA= github.com/esote/minmaxheap v1.0.0/go.mod h1:Ln8+i7fS1k3PLgZI2JAo0iA1as95QnIYiGCrqSJ5FZk= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= @@ -520,15 +509,8 @@ github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0 github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4= github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -536,7 +518,6 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -552,8 +533,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= @@ -562,16 +543,14 @@ github.com/gagliardetto/solana-go v1.8.4 h1:vmD/JmTlonyXGy39bAo0inMhmbdAwV7rXZtL github.com/gagliardetto/solana-go v1.8.4/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.19.0 h1:BcCH3CN5tXt5aML+gwmbFwVptLLQA+eT866fCO9wVOM= -github.com/getsentry/sentry-go v0.19.0/go.mod h1:y3+lGEFEFexZtpbG1GUE2WD/f9zGyKYwpEqryTOC/nE= +github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE= +github.com/getsentry/sentry-go v0.23.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= @@ -581,17 +560,12 @@ github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfm github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs97miaG2+7neKY= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibOShaOw1jH8hUYz+Ak8NLsR/GI0Hv5I= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -617,9 +591,9 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= @@ -655,18 +629,14 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= -github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= @@ -710,12 +680,6 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -729,11 +693,8 @@ github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/gogo/status v1.1.1 h1:DuHXlSFHNKqTQ+/ACf5Vs6r4X/dH2EgIzR9Vr+H65kg= github.com/gogo/status v1.1.1/go.mod h1:jpG3dM5QPcqu19Hg8lkUhBFBa3TcLs1DG7+2Jqci7oU= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= @@ -781,7 +742,6 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -797,7 +757,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= @@ -807,7 +766,6 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= @@ -818,7 +776,6 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -828,9 +785,6 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= @@ -842,17 +796,15 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= -github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/gophercloud/gophercloud v1.5.0 h1:cDN6XFCLKiiqvYpjQLq9AiM7RDRbIC9450WpPH+yvXo= github.com/gophercloud/gophercloud v1.5.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -867,7 +819,6 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= @@ -919,8 +870,8 @@ github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/b github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE= -github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= +github.com/hashicorp/consul/api v1.28.2 h1:mXfkRHrpHN4YY3RqL09nXU1eHKLNiuAN4kHvDQ16k/8= +github.com/hashicorp/consul/api v1.28.2/go.mod h1:KyzqzgMEya+IZPcD65YFoOVAgPpbfERu4I/tzG6/ueE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.16.0 h1:SE9m0W6DEfgIVCJX7xU+iv/hUl4m/nxqMTnCdMxDpJ8= github.com/hashicorp/consul/sdk v0.16.0/go.mod h1:7pxqqhqoaPqnBnzXD1StKed62LqJeClzVsUEy85Zr0A= @@ -968,7 +919,6 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= @@ -1014,13 +964,11 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -1030,11 +978,6 @@ github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10C github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/ionos-cloud/sdk-go/v6 v6.1.8 h1:493wE/BkZxJf7x79UCE0cYGPZoqQcPiEBALvt7uVGY0= github.com/ionos-cloud/sdk-go/v6 v6.1.8/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -1107,7 +1050,6 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -1115,27 +1057,17 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -1144,11 +1076,9 @@ github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJ github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -1158,13 +1088,10 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -1177,6 +1104,8 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhn github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/linode/linodego v1.19.0 h1:n4WJrcr9+30e9JGZ6DI0nZbm5SdAj1kSwvvt/998YUw= github.com/linode/linodego v1.19.0/go.mod h1:XZFR+yJ9mm2kwf6itZ6SCpu+6w3KnIevV0Uu5HNWJgQ= +github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= +github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= @@ -1202,12 +1131,9 @@ github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsI github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -1215,7 +1141,6 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -1229,14 +1154,11 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= @@ -1290,7 +1212,6 @@ github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= @@ -1303,7 +1224,6 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= @@ -1318,10 +1238,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE= @@ -1336,7 +1252,6 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -1352,8 +1267,8 @@ github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= -github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg= @@ -1400,7 +1315,6 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -1438,8 +1352,6 @@ github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= -github.com/regen-network/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -1452,8 +1364,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= @@ -1471,6 +1381,10 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= @@ -1478,7 +1392,6 @@ github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZj github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.20 h1:a9hSJdJcd16e0HoMsnFvaHvxB3pxSD+SC7+CISp7xY0= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.20/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= @@ -1487,7 +1400,6 @@ github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= github.com/sercand/kuberesolver/v5 v5.1.1 h1:CYH+d67G0sGBj7q5wLK61yzqJJ8gLLC8aeprPTHb6yY= github.com/sercand/kuberesolver/v5 v5.1.1/go.mod h1:Fs1KbKhVRnB2aDWN12NjKCB+RgYMWZJ294T3BtmVCpQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= @@ -1513,6 +1425,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 h1:jakAsdhDxV4cMgRAcSvHraXjyePi8umG5SEUTGFvuy8= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685/go.mod h1:p7L/xNEQpHDdZtgFA6/FavuZHqvV3kYhQysxBywmq1k= github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1WonwhVOPtOStpqTmLC4E= github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= @@ -1551,8 +1465,8 @@ github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:D github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= github.com/smartcontractkit/wasp v0.4.5 h1:pgiXwBci2m15eo33AzspzhpNG/gxg+8QGxl+I5LpfsQ= github.com/smartcontractkit/wasp v0.4.5/go.mod h1:eVhBVLbVv0qORUlN7aR5C4aTN/lTYO3KnN1erO4ROOI= -github.com/smartcontractkit/wsrpc v0.7.3 h1:CKYZfawZShZGfvsQep1F9oBansnFk9ByZPCdTMpLphw= -github.com/smartcontractkit/wsrpc v0.7.3/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= +github.com/smartcontractkit/wsrpc v0.8.1 h1:kk0SXLqWrWaZ3J6c7n8D0NZ2uTMBBBpG5dZZXZX8UGE= +github.com/smartcontractkit/wsrpc v0.8.1/go.mod h1:yfg8v8fPLXkb6Mcnx6Pm/snP6jJ0r5Kf762Yd1a/KpA= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1560,12 +1474,14 @@ github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= @@ -1576,16 +1492,14 @@ github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= -github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= @@ -1607,19 +1521,16 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= @@ -1657,10 +1568,7 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= @@ -1677,14 +1585,12 @@ github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE= github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= +github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= @@ -1696,9 +1602,6 @@ github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+ github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= @@ -1706,11 +1609,7 @@ github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1722,10 +1621,10 @@ github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7 github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= -github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= -github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= +github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= +github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= @@ -1815,7 +1714,6 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= @@ -1832,26 +1730,21 @@ golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaE golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= @@ -1882,7 +1775,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1891,8 +1783,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -1907,7 +1797,6 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1916,7 +1805,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1935,11 +1823,8 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= @@ -1947,7 +1832,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -1966,10 +1850,6 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= @@ -1984,7 +1864,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2040,24 +1919,18 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2065,9 +1938,7 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2119,18 +1990,15 @@ golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -2180,16 +2048,9 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= @@ -2223,9 +2084,6 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -2271,15 +2129,7 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= @@ -2301,13 +2151,9 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -2337,18 +2183,14 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -2362,16 +2204,14 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= -gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2400,11 +2240,11 @@ k8s.io/kubectl v0.31.0 h1:kANwAAPVY02r4U4jARP/C+Q1sssCcN/1p9Nk+7BQKVg= k8s.io/kubectl v0.31.0/go.mod h1:pB47hhFypGsaHAPjlwrNbvhXgmuAr01ZBvAIIUaI8d4= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= +nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= -pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index b0b65ac384..99af135bd3 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -32,9 +32,9 @@ require ( require ( cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect - cosmossdk.io/depinject v1.0.0-alpha.3 // indirect - cosmossdk.io/errors v1.0.0 // indirect - cosmossdk.io/math v1.0.1 // indirect + cosmossdk.io/depinject v1.0.0-alpha.4 // indirect + cosmossdk.io/errors v1.0.1 // indirect + cosmossdk.io/math v1.3.0 // indirect github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect @@ -51,12 +51,17 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 // indirect github.com/aws/smithy-go v1.20.4 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/containerd/errdefs v0.1.0 // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect + github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect k8s.io/apimachinery v0.31.0 // indirect ) @@ -76,7 +81,7 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect - github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/CosmWasm/wasmd v0.40.1 // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect @@ -85,8 +90,8 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/Microsoft/hcsshim v0.11.5 // indirect github.com/NethermindEth/juno v0.3.1 // indirect github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect @@ -120,30 +125,30 @@ require ( github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/errors v1.10.0 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.37.2 // indirect - github.com/cometbft/cometbft-db v0.7.0 // indirect + github.com/cometbft/cometbft v0.37.5 // indirect + github.com/cometbft/cometbft-db v0.8.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/containerd/containerd v1.7.12 // indirect + github.com/containerd/containerd v1.7.18 // indirect github.com/containerd/continuity v0.4.3 // indirect github.com/containerd/log v0.1.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect - github.com/cosmos/cosmos-sdk v0.47.4 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect + github.com/cosmos/cosmos-sdk v0.47.11 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.11 // indirect - github.com/cosmos/iavl v0.20.0 // indirect - github.com/cosmos/ibc-go/v7 v7.0.1 // indirect - github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect - github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect + github.com/cosmos/iavl v0.20.1 // indirect + github.com/cosmos/ibc-go/v7 v7.5.1 // indirect + github.com/cosmos/ics23/go v0.10.0 // indirect + github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect @@ -157,7 +162,7 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/distribution/reference v0.5.0 // indirect + github.com/distribution/reference v0.6.0 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v25.0.2+incompatible // indirect github.com/docker/go-connections v0.5.0 // indirect @@ -179,13 +184,13 @@ require ( github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/solana-go v1.8.4 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect - github.com/getsentry/sentry-go v0.19.0 // indirect + github.com/getsentry/sentry-go v0.23.0 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-gonic/gin v1.9.1 // indirect @@ -198,7 +203,7 @@ require ( github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.4 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect @@ -210,7 +215,7 @@ require ( github.com/go-openapi/validate v0.22.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.15.5 // indirect + github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect @@ -258,7 +263,7 @@ require ( github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect - github.com/hashicorp/consul/api v1.25.1 // indirect + github.com/hashicorp/consul/api v1.28.2 // indirect github.com/hashicorp/consul/sdk v0.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -310,7 +315,7 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect @@ -350,7 +355,7 @@ require ( github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc5 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect github.com/opencontainers/runc v1.1.10 // indirect github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e // indirect github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect @@ -371,7 +376,7 @@ require ( github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/prometheus/prometheus v0.48.1 // indirect + github.com/prometheus/prometheus v1.8.2-0.20200727090838-6f296594a852 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect @@ -394,22 +399,20 @@ require ( github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect - github.com/smartcontractkit/wsrpc v0.7.3 // indirect + github.com/smartcontractkit/wsrpc v0.8.1 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect - github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cobra v1.8.1 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.15.0 // indirect + github.com/spf13/viper v1.19.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/subosito/gotenv v1.4.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect - github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect github.com/test-go/testify v1.1.4 // indirect @@ -433,8 +436,8 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zondax/hid v0.9.1 // indirect - github.com/zondax/ledger-go v0.14.1 // indirect + github.com/zondax/hid v0.9.2 // indirect + github.com/zondax/ledger-go v0.14.3 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect go.etcd.io/bbolt v1.3.9 // indirect @@ -494,8 +497,8 @@ require ( k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect k8s.io/kubectl v0.31.0 // indirect k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect - nhooyr.io/websocket v1.8.7 // indirect - pgregory.net/rapid v0.5.5 // indirect + nhooyr.io/websocket v1.8.10 // indirect + pgregory.net/rapid v1.1.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/controller-runtime v0.19.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 2f92d1e6b4..86ebb20817 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -4,7 +4,6 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -15,9 +14,6 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= @@ -48,7 +44,6 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= @@ -59,14 +54,14 @@ cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= -cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= -cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= -cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= -cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= -cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca h1:msenprh2BLLRwNT7zN56TbBHOGk/7ARQckXHxXyvjoQ= -cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c= -cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= -cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= +cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= +cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= +cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= +cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= +cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= +cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= +cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= +cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= @@ -83,7 +78,6 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9 github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-sdk-for-go v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw= github.com/Azure/azure-sdk-for-go v65.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 h1:9kDVnTz3vbfweTqAUmk/a/pH5pWFCHtvRpHYC0G/dcA= @@ -116,10 +110,8 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 h1:WpB/QDNLpMw github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= +github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= github.com/CosmWasm/wasmd v0.40.1/go.mod h1:6EOwnv7MpuFaEqxcUOdFV9i4yvrdOciaY6VQ1o7A3yg= github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= @@ -133,7 +125,6 @@ github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/K-Phoen/grabana v0.22.1 h1:b/O+C3H2H6VNYSeMCYUO4X4wYuwFXgBcRkvYa+fjpQA= github.com/K-Phoen/grabana v0.22.1/go.mod h1:3LTXrTzQzTKTgvKSXdRjlsJbizSOW/V23Q3iX00R5bU= github.com/K-Phoen/sdk v0.12.4 h1:j2EYuBJm3zDTD0fGKACVFWxAXtkR0q5QzfVqxmHSeGQ= @@ -148,10 +139,10 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0 github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= -github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/Microsoft/hcsshim v0.11.5 h1:haEcLNpj9Ka1gd3B3tAEs9CpE0c+1IhoL59w/exYU38= +github.com/Microsoft/hcsshim v0.11.5/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU= github.com/NethermindEth/juno v0.3.1 h1:AW72LiAm9gqUeCVJWvepnZcTnpU4Vkl0KzPMxS+42FA= github.com/NethermindEth/juno v0.3.1/go.mod h1:SGbTpgGaCsxhFsKOid7Ylnz//WZ8swtILk+NbHGsk/Q= github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb h1:Mv8SscePPyw2ju4igIJAjFgcq5zCQfjgbz53DwYu5mc= @@ -163,7 +154,6 @@ github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8 github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= @@ -172,11 +162,8 @@ github.com/Workiva/go-datastructures v1.1.0 h1:hu20UpgZneBhQ3ZvwiOGlqJSKIosin2Rd github.com/Workiva/go-datastructures v1.1.0/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= -github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= -github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg= @@ -248,7 +235,6 @@ github.com/aws/jsii-runtime-go v1.75.0 h1:NhpUfyiL7/wsRuUekFsz8FFBCYLfPD/l61kKg9 github.com/aws/jsii-runtime-go v1.75.0/go.mod h1:TKCyrtM0pygEPo4rDZzbMSDNCDNTSYSN6/mGyHI6O3I= github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= @@ -326,7 +312,6 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw= github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= @@ -334,39 +319,36 @@ github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= -github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= -github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/errors v1.10.0 h1:lfxS8zZz1+OjtV4MtNWgboi/W5tyLEB6VQZBXN+0VUU= +github.com/cockroachdb/errors v1.10.0/go.mod h1:lknhIsEVQ9Ss/qKDBQS/UqFSvPQjOwNq2qyKAxtHRqE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= -github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= -github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= -github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= -github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= +github.com/cometbft/cometbft v0.37.5 h1:/U/TlgMh4NdnXNo+YU9T2NMCWyhXNDF34Mx582jlvq0= +github.com/cometbft/cometbft v0.37.5/go.mod h1:QC+mU0lBhKn8r9qvmnq53Dmf3DWBt4VtkcKw2C81wxY= +github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= +github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= -github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= +github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao= +github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4= github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= +github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -384,10 +366,10 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= -github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.47.4 h1:FVUpEprm58nMmBX4xkRdMDaIG5Nr4yy92HZAfGAw9bg= -github.com/cosmos/cosmos-sdk v0.47.4/go.mod h1:R5n+uM7vguVPFap4pgkdvQCT1nVo/OtPwrlAU40rvok= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= +github.com/cosmos/cosmos-sdk v0.47.11 h1:0Qx7eORw0RJqPv+mvDuU8NQ1LV3nJJKJnPoYblWHolc= +github.com/cosmos/cosmos-sdk v0.47.11/go.mod h1:ADjORYzUQqQv/FxDi0H0K5gW/rAk1CiDR3ZKsExfJV0= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -395,14 +377,14 @@ github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiK github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= -github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= -github.com/cosmos/ibc-go/v7 v7.0.1 h1:NIBNRWjlOoFvFQu1ZlgwkaSeHO5avf4C1YQiWegt8jw= -github.com/cosmos/ibc-go/v7 v7.0.1/go.mod h1:vEaapV6nuLPQlS+g8IKmxMo6auPi0i7HMv1PhViht/E= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= -github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= -github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/iavl v0.20.1 h1:rM1kqeG3/HBT85vsZdoSNsehciqUQPWrR4BYmqE2+zg= +github.com/cosmos/iavl v0.20.1/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/ibc-go/v7 v7.5.1 h1:KqS/g7W7EMX1OtOvufS8lWMJibOKpdgtNNZIU6fAgVU= +github.com/cosmos/ibc-go/v7 v7.5.1/go.mod h1:ktFg5GvKOyrGCqTWtW7Grj5uweU4ZapxrNeVS1CLLbo= +github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= +github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= +github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw= +github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M= github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= @@ -422,10 +404,6 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= -github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= -github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= -github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -448,7 +426,6 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFM github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70/go.mod h1:EoK/8RFbMEteaCaz89uessDTnCWjbbcr+DXcBh4el5o= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= @@ -462,8 +439,8 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E= github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA= -github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= -github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= @@ -483,15 +460,12 @@ github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9Tzqv github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjletLK6K0rbxyZI= github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= @@ -499,7 +473,6 @@ github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/esote/minmaxheap v1.0.0 h1:rgA7StnXXpZG6qlM0S7pUmEv1KpWe32rYT4x8J8ntaA= github.com/esote/minmaxheap v1.0.0/go.mod h1:Ln8+i7fS1k3PLgZI2JAo0iA1as95QnIYiGCrqSJ5FZk= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= @@ -510,15 +483,8 @@ github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0 github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4= github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -526,7 +492,6 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -544,8 +509,8 @@ github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQ github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= @@ -554,16 +519,14 @@ github.com/gagliardetto/solana-go v1.8.4 h1:vmD/JmTlonyXGy39bAo0inMhmbdAwV7rXZtL github.com/gagliardetto/solana-go v1.8.4/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.19.0 h1:BcCH3CN5tXt5aML+gwmbFwVptLLQA+eT866fCO9wVOM= -github.com/getsentry/sentry-go v0.19.0/go.mod h1:y3+lGEFEFexZtpbG1GUE2WD/f9zGyKYwpEqryTOC/nE= +github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE= +github.com/getsentry/sentry-go v0.23.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= @@ -573,17 +536,12 @@ github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfm github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs97miaG2+7neKY= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibOShaOw1jH8hUYz+Ak8NLsR/GI0Hv5I= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -609,9 +567,9 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= @@ -647,18 +605,14 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= -github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= @@ -702,12 +656,6 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -721,11 +669,8 @@ github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/gogo/status v1.1.1 h1:DuHXlSFHNKqTQ+/ACf5Vs6r4X/dH2EgIzR9Vr+H65kg= github.com/gogo/status v1.1.1/go.mod h1:jpG3dM5QPcqu19Hg8lkUhBFBa3TcLs1DG7+2Jqci7oU= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= @@ -773,7 +718,6 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -789,7 +733,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= @@ -799,7 +742,6 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= @@ -810,7 +752,6 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -820,9 +761,6 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= @@ -834,17 +772,15 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= -github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/gophercloud/gophercloud v1.5.0 h1:cDN6XFCLKiiqvYpjQLq9AiM7RDRbIC9450WpPH+yvXo= github.com/gophercloud/gophercloud v1.5.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -859,7 +795,6 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= @@ -911,8 +846,8 @@ github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/b github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE= -github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= +github.com/hashicorp/consul/api v1.28.2 h1:mXfkRHrpHN4YY3RqL09nXU1eHKLNiuAN4kHvDQ16k/8= +github.com/hashicorp/consul/api v1.28.2/go.mod h1:KyzqzgMEya+IZPcD65YFoOVAgPpbfERu4I/tzG6/ueE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.16.0 h1:SE9m0W6DEfgIVCJX7xU+iv/hUl4m/nxqMTnCdMxDpJ8= github.com/hashicorp/consul/sdk v0.16.0/go.mod h1:7pxqqhqoaPqnBnzXD1StKed62LqJeClzVsUEy85Zr0A= @@ -960,7 +895,6 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= @@ -1004,13 +938,11 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -1020,11 +952,6 @@ github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10C github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/ionos-cloud/sdk-go/v6 v6.1.8 h1:493wE/BkZxJf7x79UCE0cYGPZoqQcPiEBALvt7uVGY0= github.com/ionos-cloud/sdk-go/v6 v6.1.8/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -1097,7 +1024,6 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -1105,27 +1031,17 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -1134,11 +1050,9 @@ github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJ github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -1148,13 +1062,10 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -1167,6 +1078,8 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhn github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/linode/linodego v1.19.0 h1:n4WJrcr9+30e9JGZ6DI0nZbm5SdAj1kSwvvt/998YUw= github.com/linode/linodego v1.19.0/go.mod h1:XZFR+yJ9mm2kwf6itZ6SCpu+6w3KnIevV0Uu5HNWJgQ= +github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= +github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -1188,12 +1101,9 @@ github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsI github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -1201,7 +1111,6 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -1215,14 +1124,11 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= @@ -1276,7 +1182,6 @@ github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= @@ -1289,7 +1194,6 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= @@ -1298,10 +1202,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE= @@ -1316,7 +1216,6 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -1332,8 +1231,8 @@ github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= -github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opencontainers/runc v1.1.10 h1:EaL5WeO9lv9wmS6SASjszOeQdSctvpbu0DdBQBizE40= github.com/opencontainers/runc v1.1.10/go.mod h1:+/R6+KmDlh+hOO8NkjmgkG9Qzvypzk0yXxAPYYR65+M= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg= @@ -1380,7 +1279,6 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -1418,8 +1316,6 @@ github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= -github.com/regen-network/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -1432,8 +1328,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= @@ -1451,6 +1345,10 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= @@ -1458,7 +1356,6 @@ github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZj github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.20 h1:a9hSJdJcd16e0HoMsnFvaHvxB3pxSD+SC7+CISp7xY0= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.20/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= @@ -1467,7 +1364,6 @@ github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= github.com/sercand/kuberesolver/v5 v5.1.1 h1:CYH+d67G0sGBj7q5wLK61yzqJJ8gLLC8aeprPTHb6yY= github.com/sercand/kuberesolver/v5 v5.1.1/go.mod h1:Fs1KbKhVRnB2aDWN12NjKCB+RgYMWZJ294T3BtmVCpQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= @@ -1531,8 +1427,8 @@ github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:D github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= github.com/smartcontractkit/wasp v0.4.7 h1:7mKJfwzFbuE8xVLUYtLt7Bjw8q/bmVZRW6Ks8kc1LVM= github.com/smartcontractkit/wasp v0.4.7/go.mod h1:jeabvyXikb2aNoLQwcZGqaz17efrR8NJhpq4seAmdgs= -github.com/smartcontractkit/wsrpc v0.7.3 h1:CKYZfawZShZGfvsQep1F9oBansnFk9ByZPCdTMpLphw= -github.com/smartcontractkit/wsrpc v0.7.3/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= +github.com/smartcontractkit/wsrpc v0.8.1 h1:kk0SXLqWrWaZ3J6c7n8D0NZ2uTMBBBpG5dZZXZX8UGE= +github.com/smartcontractkit/wsrpc v0.8.1/go.mod h1:yfg8v8fPLXkb6Mcnx6Pm/snP6jJ0r5Kf762Yd1a/KpA= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1540,12 +1436,14 @@ github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= @@ -1556,16 +1454,14 @@ github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= -github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= @@ -1587,19 +1483,16 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= @@ -1635,10 +1528,7 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= @@ -1655,14 +1545,10 @@ github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE= github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/wiremock/go-wiremock v1.9.0 h1:9xcU4/IoEfgCaH4TGhQTtiQyBh2eMtu9JB6ppWduK+E= @@ -1676,9 +1562,6 @@ github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+ github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= @@ -1686,11 +1569,7 @@ github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1702,10 +1581,10 @@ github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7 github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= -github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= -github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= +github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= +github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= @@ -1795,7 +1674,6 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= @@ -1812,26 +1690,21 @@ golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaE golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= @@ -1862,7 +1735,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1871,8 +1743,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -1887,7 +1757,6 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1896,7 +1765,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1915,11 +1783,8 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= @@ -1927,7 +1792,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -1946,10 +1810,6 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= @@ -1964,7 +1824,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2019,24 +1878,18 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2044,9 +1897,7 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2097,18 +1948,15 @@ golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -2158,16 +2006,9 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= @@ -2201,9 +2042,6 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -2249,15 +2087,7 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= @@ -2279,13 +2109,9 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -2315,18 +2141,14 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -2340,7 +2162,6 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -2348,8 +2169,8 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= -gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2378,11 +2199,11 @@ k8s.io/kubectl v0.28.2 h1:fOWOtU6S0smdNjG1PB9WFbqEIMlkzU5ahyHkc7ESHgM= k8s.io/kubectl v0.28.2/go.mod h1:6EQWTPySF1fn7yKoQZHYf9TPwIl2AygHEcJoxFekr64= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= +nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= -pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/integration-tests/web/sdk/README.md b/integration-tests/web/sdk/README.md new file mode 100644 index 0000000000..aa730e3a94 --- /dev/null +++ b/integration-tests/web/sdk/README.md @@ -0,0 +1,13 @@ +## GQL SDK + +This package exports a `Client` for interacting with the `feeds-manager` service of core. The implementation is based on code generated via `[genqlient](https://github.com/Khan/genqlient)`. + +### Extending the Client + +Add additional queries or mutations to `genqlient.graphql` and then regenerate the implementation via the Taskfile: + +```bash +$ task generate +``` + +Next, extend the `Client` interface and the `client` implementation. diff --git a/integration-tests/web/sdk/client/client.go b/integration-tests/web/sdk/client/client.go new file mode 100644 index 0000000000..bcfd3b1f0b --- /dev/null +++ b/integration-tests/web/sdk/client/client.go @@ -0,0 +1,156 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/Khan/genqlient/graphql" + + "github.com/smartcontractkit/chainlink/integration-tests/web/sdk/client/internal/doer" + "github.com/smartcontractkit/chainlink/integration-tests/web/sdk/internal/generated" +) + +type Client interface { + GetCSAKeys(ctx context.Context) (*generated.GetCSAKeysResponse, error) + GetJob(ctx context.Context, id string) (*generated.GetJobResponse, error) + ListJobs(ctx context.Context, offset, limit int) (*generated.ListJobsResponse, error) + GetBridge(ctx context.Context, id string) (*generated.GetBridgeResponse, error) + ListBridges(ctx context.Context, offset, limit int) (*generated.ListBridgesResponse, error) + GetFeedsManager(ctx context.Context, id string) (*generated.GetFeedsManagerResponse, error) + ListFeedsManagers(ctx context.Context) (*generated.ListFeedsManagersResponse, error) + CreateFeedsManager(ctx context.Context, cmd generated.CreateFeedsManagerInput) (*generated.CreateFeedsManagerResponse, error) + UpdateFeedsManager(ctx context.Context, id string, cmd generated.UpdateFeedsManagerInput) (*generated.UpdateFeedsManagerResponse, error) + GetJobProposal(ctx context.Context, id string) (*generated.GetJobProposalResponse, error) + ApproveJobProposalSpec(ctx context.Context, id string, force bool) (*generated.ApproveJobProposalSpecResponse, error) + CancelJobProposalSpec(ctx context.Context, id string) (*generated.CancelJobProposalSpecResponse, error) + RejectJobProposalSpec(ctx context.Context, id string) (*generated.RejectJobProposalSpecResponse, error) + UpdateJobProposalSpecDefinition(ctx context.Context, id string, cmd generated.UpdateJobProposalSpecDefinitionInput) (*generated.UpdateJobProposalSpecDefinitionResponse, error) +} + +type client struct { + gqlClient graphql.Client + credentials Credentials + endpoints endpoints + cookie string +} + +type endpoints struct { + Sessions string + Query string +} + +type Credentials struct { + Email string `json:"email"` + Password string `json:"password"` +} + +func New(baseURI string, creds Credentials) (Client, error) { + e := endpoints{ + Sessions: baseURI + "/sessions", + Query: baseURI + "/query", + } + c := &client{ + endpoints: e, + credentials: creds, + } + + if err := c.login(); err != nil { + return nil, fmt.Errorf("failed to login to node: %w", err) + } + + c.gqlClient = graphql.NewClient( + c.endpoints.Query, + doer.NewAuthed(c.cookie), + ) + + return c, nil +} + +func (c *client) GetCSAKeys(ctx context.Context) (*generated.GetCSAKeysResponse, error) { + return generated.GetCSAKeys(ctx, c.gqlClient) +} + +func (c *client) GetJob(ctx context.Context, id string) (*generated.GetJobResponse, error) { + return generated.GetJob(ctx, c.gqlClient, id) +} + +func (c *client) ListJobs(ctx context.Context, offset, limit int) (*generated.ListJobsResponse, error) { + return generated.ListJobs(ctx, c.gqlClient, offset, limit) +} + +func (c *client) GetBridge(ctx context.Context, id string) (*generated.GetBridgeResponse, error) { + return generated.GetBridge(ctx, c.gqlClient, id) +} + +func (c *client) ListBridges(ctx context.Context, offset, limit int) (*generated.ListBridgesResponse, error) { + return generated.ListBridges(ctx, c.gqlClient, offset, limit) +} + +func (c *client) GetFeedsManager(ctx context.Context, id string) (*generated.GetFeedsManagerResponse, error) { + return generated.GetFeedsManager(ctx, c.gqlClient, id) +} + +func (c *client) ListFeedsManagers(ctx context.Context) (*generated.ListFeedsManagersResponse, error) { + return generated.ListFeedsManagers(ctx, c.gqlClient) +} + +func (c *client) CreateFeedsManager(ctx context.Context, cmd generated.CreateFeedsManagerInput) (*generated.CreateFeedsManagerResponse, error) { + return generated.CreateFeedsManager(ctx, c.gqlClient, cmd) +} + +func (c *client) UpdateFeedsManager(ctx context.Context, id string, cmd generated.UpdateFeedsManagerInput) (*generated.UpdateFeedsManagerResponse, error) { + return generated.UpdateFeedsManager(ctx, c.gqlClient, id, cmd) +} + +func (c *client) GetJobProposal(ctx context.Context, id string) (*generated.GetJobProposalResponse, error) { + return generated.GetJobProposal(ctx, c.gqlClient, id) +} + +func (c *client) ApproveJobProposalSpec(ctx context.Context, id string, force bool) (*generated.ApproveJobProposalSpecResponse, error) { + return generated.ApproveJobProposalSpec(ctx, c.gqlClient, id, force) +} + +func (c *client) CancelJobProposalSpec(ctx context.Context, id string) (*generated.CancelJobProposalSpecResponse, error) { + return generated.CancelJobProposalSpec(ctx, c.gqlClient, id) +} + +func (c *client) RejectJobProposalSpec(ctx context.Context, id string) (*generated.RejectJobProposalSpecResponse, error) { + return generated.RejectJobProposalSpec(ctx, c.gqlClient, id) +} + +func (c *client) UpdateJobProposalSpecDefinition(ctx context.Context, id string, cmd generated.UpdateJobProposalSpecDefinitionInput) (*generated.UpdateJobProposalSpecDefinitionResponse, error) { + return generated.UpdateJobProposalSpecDefinition(ctx, c.gqlClient, id, cmd) +} + +func (c *client) login() error { + b, err := json.Marshal(c.credentials) + if err != nil { + return fmt.Errorf("failed to marshal credentials: %w", err) + } + + payload := strings.NewReader(string(b)) + + req, err := http.NewRequest("POST", c.endpoints.Sessions, payload) + if err != nil { + return err + } + + req.Header.Add("Content-Type", "application/json") + + res, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer res.Body.Close() + + cookieHeader := res.Header.Get("Set-Cookie") + if cookieHeader == "" { + return fmt.Errorf("no cookie found in header") + } + + c.cookie = strings.Split(cookieHeader, ";")[0] + return nil +} diff --git a/integration-tests/web/sdk/client/internal/doer/doer.go b/integration-tests/web/sdk/client/internal/doer/doer.go new file mode 100644 index 0000000000..dde842bae5 --- /dev/null +++ b/integration-tests/web/sdk/client/internal/doer/doer.go @@ -0,0 +1,20 @@ +package doer + +import "net/http" + +type Authed struct { + cookie string + wrapped *http.Client +} + +func NewAuthed(cookie string) *Authed { + return &Authed{ + cookie: cookie, + wrapped: http.DefaultClient, + } +} + +func (a *Authed) Do(req *http.Request) (*http.Response, error) { + req.Header.Set("cookie", a.cookie) + return a.wrapped.Do(req) +} diff --git a/integration-tests/web/sdk/genqlient.yaml b/integration-tests/web/sdk/genqlient.yaml new file mode 100644 index 0000000000..2b861a92ee --- /dev/null +++ b/integration-tests/web/sdk/genqlient.yaml @@ -0,0 +1,15 @@ +# Default genqlient config; for full documentation see: +# https://github.com/Khan/genqlient/blob/main/docs/genqlient.yaml +schema: ./internal/schema.graphql + +operations: +- ./internal/genqlient.graphql + +generated: ./internal/generated/generated.go + +bindings: + Time: + type: string + +package_bindings: +- package: github.com/smartcontractkit/chainlink/v2/core/web/gqlscalar diff --git a/integration-tests/web/sdk/internal/generated/generated.go b/integration-tests/web/sdk/internal/generated/generated.go new file mode 100644 index 0000000000..bcb8106959 --- /dev/null +++ b/integration-tests/web/sdk/internal/generated/generated.go @@ -0,0 +1,5007 @@ +// Code generated by github.com/Khan/genqlient, DO NOT EDIT. + +package generated + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/Khan/genqlient/graphql" + "github.com/smartcontractkit/chainlink/v2/core/web/gqlscalar" +) + +// ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload includes the requested fields of the GraphQL interface ApproveJobProposalSpecPayload. +// +// ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload is implemented by the following types: +// ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccess +// ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError +// ApproveJobProposalSpecApproveJobProposalSpecNotFoundError +type ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload interface { + implementsGraphQLInterfaceApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccess) implementsGraphQLInterfaceApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload() { +} +func (v *ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError) implementsGraphQLInterfaceApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload() { +} +func (v *ApproveJobProposalSpecApproveJobProposalSpecNotFoundError) implementsGraphQLInterfaceApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload() { +} + +func __unmarshalApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload(b []byte, v *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "ApproveJobProposalSpecSuccess": + *v = new(ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccess) + return json.Unmarshal(b, *v) + case "JobAlreadyExistsError": + *v = new(ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError) + return json.Unmarshal(b, *v) + case "NotFoundError": + *v = new(ApproveJobProposalSpecApproveJobProposalSpecNotFoundError) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing ApproveJobProposalSpecPayload.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload: "%v"`, tn.TypeName) + } +} + +func __marshalApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload(v *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccess: + typename = "ApproveJobProposalSpecSuccess" + + result := struct { + TypeName string `json:"__typename"` + *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccess + }{typename, v} + return json.Marshal(result) + case *ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError: + typename = "JobAlreadyExistsError" + + result := struct { + TypeName string `json:"__typename"` + *ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError + }{typename, v} + return json.Marshal(result) + case *ApproveJobProposalSpecApproveJobProposalSpecNotFoundError: + typename = "NotFoundError" + + result := struct { + TypeName string `json:"__typename"` + *ApproveJobProposalSpecApproveJobProposalSpecNotFoundError + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload: "%T"`, v) + } +} + +// ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccess includes the requested fields of the GraphQL type ApproveJobProposalSpecSuccess. +type ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccess struct { + Typename string `json:"__typename"` + Spec ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec `json:"spec"` +} + +// GetTypename returns ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccess.Typename, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccess) GetTypename() string { + return v.Typename +} + +// GetSpec returns ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccess.Spec, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccess) GetSpec() ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec { + return v.Spec +} + +// ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec includes the requested fields of the GraphQL type JobProposalSpec. +type ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec struct { + Id string `json:"id"` + Definition string `json:"definition"` + Version int `json:"version"` + Status SpecStatus `json:"status"` + StatusUpdatedAt string `json:"statusUpdatedAt"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +} + +// GetId returns ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec.Id, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec) GetId() string { + return v.Id +} + +// GetDefinition returns ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec.Definition, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec) GetDefinition() string { + return v.Definition +} + +// GetVersion returns ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec.Version, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec) GetVersion() int { + return v.Version +} + +// GetStatus returns ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec.Status, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec) GetStatus() SpecStatus { + return v.Status +} + +// GetStatusUpdatedAt returns ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec.StatusUpdatedAt, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec) GetStatusUpdatedAt() string { + return v.StatusUpdatedAt +} + +// GetCreatedAt returns ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec.CreatedAt, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec) GetCreatedAt() string { + return v.CreatedAt +} + +// GetUpdatedAt returns ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec.UpdatedAt, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccessSpecJobProposalSpec) GetUpdatedAt() string { + return v.UpdatedAt +} + +// ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError includes the requested fields of the GraphQL type JobAlreadyExistsError. +type ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError.Typename, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError) GetTypename() string { + return v.Typename +} + +// GetMessage returns ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError.Message, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError) GetMessage() string { + return v.Message +} + +// GetCode returns ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError.Code, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecJobAlreadyExistsError) GetCode() ErrorCode { + return v.Code +} + +// ApproveJobProposalSpecApproveJobProposalSpecNotFoundError includes the requested fields of the GraphQL type NotFoundError. +type ApproveJobProposalSpecApproveJobProposalSpecNotFoundError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns ApproveJobProposalSpecApproveJobProposalSpecNotFoundError.Typename, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecNotFoundError) GetTypename() string { + return v.Typename +} + +// GetMessage returns ApproveJobProposalSpecApproveJobProposalSpecNotFoundError.Message, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecNotFoundError) GetMessage() string { + return v.Message +} + +// GetCode returns ApproveJobProposalSpecApproveJobProposalSpecNotFoundError.Code, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecApproveJobProposalSpecNotFoundError) GetCode() ErrorCode { + return v.Code +} + +// ApproveJobProposalSpecResponse is returned by ApproveJobProposalSpec on success. +type ApproveJobProposalSpecResponse struct { + ApproveJobProposalSpec ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload `json:"-"` +} + +// GetApproveJobProposalSpec returns ApproveJobProposalSpecResponse.ApproveJobProposalSpec, and is useful for accessing the field via an interface. +func (v *ApproveJobProposalSpecResponse) GetApproveJobProposalSpec() ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload { + return v.ApproveJobProposalSpec +} + +func (v *ApproveJobProposalSpecResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ApproveJobProposalSpecResponse + ApproveJobProposalSpec json.RawMessage `json:"approveJobProposalSpec"` + graphql.NoUnmarshalJSON + } + firstPass.ApproveJobProposalSpecResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.ApproveJobProposalSpec + src := firstPass.ApproveJobProposalSpec + if len(src) != 0 && string(src) != "null" { + err = __unmarshalApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal ApproveJobProposalSpecResponse.ApproveJobProposalSpec: %w", err) + } + } + } + return nil +} + +type __premarshalApproveJobProposalSpecResponse struct { + ApproveJobProposalSpec json.RawMessage `json:"approveJobProposalSpec"` +} + +func (v *ApproveJobProposalSpecResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ApproveJobProposalSpecResponse) __premarshalJSON() (*__premarshalApproveJobProposalSpecResponse, error) { + var retval __premarshalApproveJobProposalSpecResponse + + { + + dst := &retval.ApproveJobProposalSpec + src := v.ApproveJobProposalSpec + var err error + *dst, err = __marshalApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecPayload( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ApproveJobProposalSpecResponse.ApproveJobProposalSpec: %w", err) + } + } + return &retval, nil +} + +// BridgeParts includes the GraphQL fields of Bridge requested by the fragment BridgeParts. +type BridgeParts struct { + Id string `json:"id"` + Name string `json:"name"` + Url string `json:"url"` + Confirmations int `json:"confirmations"` + OutgoingToken string `json:"outgoingToken"` + MinimumContractPayment string `json:"minimumContractPayment"` + CreatedAt string `json:"createdAt"` +} + +// GetId returns BridgeParts.Id, and is useful for accessing the field via an interface. +func (v *BridgeParts) GetId() string { return v.Id } + +// GetName returns BridgeParts.Name, and is useful for accessing the field via an interface. +func (v *BridgeParts) GetName() string { return v.Name } + +// GetUrl returns BridgeParts.Url, and is useful for accessing the field via an interface. +func (v *BridgeParts) GetUrl() string { return v.Url } + +// GetConfirmations returns BridgeParts.Confirmations, and is useful for accessing the field via an interface. +func (v *BridgeParts) GetConfirmations() int { return v.Confirmations } + +// GetOutgoingToken returns BridgeParts.OutgoingToken, and is useful for accessing the field via an interface. +func (v *BridgeParts) GetOutgoingToken() string { return v.OutgoingToken } + +// GetMinimumContractPayment returns BridgeParts.MinimumContractPayment, and is useful for accessing the field via an interface. +func (v *BridgeParts) GetMinimumContractPayment() string { return v.MinimumContractPayment } + +// GetCreatedAt returns BridgeParts.CreatedAt, and is useful for accessing the field via an interface. +func (v *BridgeParts) GetCreatedAt() string { return v.CreatedAt } + +// CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload includes the requested fields of the GraphQL interface CancelJobProposalSpecPayload. +// +// CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload is implemented by the following types: +// CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccess +// CancelJobProposalSpecCancelJobProposalSpecNotFoundError +type CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload interface { + implementsGraphQLInterfaceCancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccess) implementsGraphQLInterfaceCancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload() { +} +func (v *CancelJobProposalSpecCancelJobProposalSpecNotFoundError) implementsGraphQLInterfaceCancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload() { +} + +func __unmarshalCancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload(b []byte, v *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "CancelJobProposalSpecSuccess": + *v = new(CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccess) + return json.Unmarshal(b, *v) + case "NotFoundError": + *v = new(CancelJobProposalSpecCancelJobProposalSpecNotFoundError) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing CancelJobProposalSpecPayload.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload: "%v"`, tn.TypeName) + } +} + +func __marshalCancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload(v *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccess: + typename = "CancelJobProposalSpecSuccess" + + result := struct { + TypeName string `json:"__typename"` + *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccess + }{typename, v} + return json.Marshal(result) + case *CancelJobProposalSpecCancelJobProposalSpecNotFoundError: + typename = "NotFoundError" + + result := struct { + TypeName string `json:"__typename"` + *CancelJobProposalSpecCancelJobProposalSpecNotFoundError + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload: "%T"`, v) + } +} + +// CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccess includes the requested fields of the GraphQL type CancelJobProposalSpecSuccess. +type CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccess struct { + Typename string `json:"__typename"` + Spec CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec `json:"spec"` +} + +// GetTypename returns CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccess.Typename, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccess) GetTypename() string { + return v.Typename +} + +// GetSpec returns CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccess.Spec, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccess) GetSpec() CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec { + return v.Spec +} + +// CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec includes the requested fields of the GraphQL type JobProposalSpec. +type CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec struct { + Id string `json:"id"` + Definition string `json:"definition"` + Version int `json:"version"` + Status SpecStatus `json:"status"` + StatusUpdatedAt string `json:"statusUpdatedAt"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +} + +// GetId returns CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec.Id, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec) GetId() string { + return v.Id +} + +// GetDefinition returns CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec.Definition, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec) GetDefinition() string { + return v.Definition +} + +// GetVersion returns CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec.Version, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec) GetVersion() int { + return v.Version +} + +// GetStatus returns CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec.Status, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec) GetStatus() SpecStatus { + return v.Status +} + +// GetStatusUpdatedAt returns CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec.StatusUpdatedAt, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec) GetStatusUpdatedAt() string { + return v.StatusUpdatedAt +} + +// GetCreatedAt returns CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec.CreatedAt, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec) GetCreatedAt() string { + return v.CreatedAt +} + +// GetUpdatedAt returns CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec.UpdatedAt, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecSuccessSpecJobProposalSpec) GetUpdatedAt() string { + return v.UpdatedAt +} + +// CancelJobProposalSpecCancelJobProposalSpecNotFoundError includes the requested fields of the GraphQL type NotFoundError. +type CancelJobProposalSpecCancelJobProposalSpecNotFoundError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns CancelJobProposalSpecCancelJobProposalSpecNotFoundError.Typename, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecCancelJobProposalSpecNotFoundError) GetTypename() string { + return v.Typename +} + +// GetMessage returns CancelJobProposalSpecCancelJobProposalSpecNotFoundError.Message, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecCancelJobProposalSpecNotFoundError) GetMessage() string { + return v.Message +} + +// GetCode returns CancelJobProposalSpecCancelJobProposalSpecNotFoundError.Code, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecCancelJobProposalSpecNotFoundError) GetCode() ErrorCode { return v.Code } + +// CancelJobProposalSpecResponse is returned by CancelJobProposalSpec on success. +type CancelJobProposalSpecResponse struct { + CancelJobProposalSpec CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload `json:"-"` +} + +// GetCancelJobProposalSpec returns CancelJobProposalSpecResponse.CancelJobProposalSpec, and is useful for accessing the field via an interface. +func (v *CancelJobProposalSpecResponse) GetCancelJobProposalSpec() CancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload { + return v.CancelJobProposalSpec +} + +func (v *CancelJobProposalSpecResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CancelJobProposalSpecResponse + CancelJobProposalSpec json.RawMessage `json:"cancelJobProposalSpec"` + graphql.NoUnmarshalJSON + } + firstPass.CancelJobProposalSpecResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.CancelJobProposalSpec + src := firstPass.CancelJobProposalSpec + if len(src) != 0 && string(src) != "null" { + err = __unmarshalCancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal CancelJobProposalSpecResponse.CancelJobProposalSpec: %w", err) + } + } + } + return nil +} + +type __premarshalCancelJobProposalSpecResponse struct { + CancelJobProposalSpec json.RawMessage `json:"cancelJobProposalSpec"` +} + +func (v *CancelJobProposalSpecResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CancelJobProposalSpecResponse) __premarshalJSON() (*__premarshalCancelJobProposalSpecResponse, error) { + var retval __premarshalCancelJobProposalSpecResponse + + { + + dst := &retval.CancelJobProposalSpec + src := v.CancelJobProposalSpec + var err error + *dst, err = __marshalCancelJobProposalSpecCancelJobProposalSpecCancelJobProposalSpecPayload( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal CancelJobProposalSpecResponse.CancelJobProposalSpec: %w", err) + } + } + return &retval, nil +} + +// CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload includes the requested fields of the GraphQL interface CreateFeedsManagerPayload. +// +// CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload is implemented by the following types: +// CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess +// CreateFeedsManagerCreateFeedsManagerInputErrors +// CreateFeedsManagerCreateFeedsManagerNotFoundError +// CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError +type CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload interface { + implementsGraphQLInterfaceCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess) implementsGraphQLInterfaceCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload() { +} +func (v *CreateFeedsManagerCreateFeedsManagerInputErrors) implementsGraphQLInterfaceCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload() { +} +func (v *CreateFeedsManagerCreateFeedsManagerNotFoundError) implementsGraphQLInterfaceCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload() { +} +func (v *CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError) implementsGraphQLInterfaceCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload() { +} + +func __unmarshalCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload(b []byte, v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "CreateFeedsManagerSuccess": + *v = new(CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess) + return json.Unmarshal(b, *v) + case "InputErrors": + *v = new(CreateFeedsManagerCreateFeedsManagerInputErrors) + return json.Unmarshal(b, *v) + case "NotFoundError": + *v = new(CreateFeedsManagerCreateFeedsManagerNotFoundError) + return json.Unmarshal(b, *v) + case "SingleFeedsManagerError": + *v = new(CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing CreateFeedsManagerPayload.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload: "%v"`, tn.TypeName) + } +} + +func __marshalCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload(v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess: + typename = "CreateFeedsManagerSuccess" + + result := struct { + TypeName string `json:"__typename"` + *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess + }{typename, v} + return json.Marshal(result) + case *CreateFeedsManagerCreateFeedsManagerInputErrors: + typename = "InputErrors" + + result := struct { + TypeName string `json:"__typename"` + *CreateFeedsManagerCreateFeedsManagerInputErrors + }{typename, v} + return json.Marshal(result) + case *CreateFeedsManagerCreateFeedsManagerNotFoundError: + typename = "NotFoundError" + + result := struct { + TypeName string `json:"__typename"` + *CreateFeedsManagerCreateFeedsManagerNotFoundError + }{typename, v} + return json.Marshal(result) + case *CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError: + typename = "SingleFeedsManagerError" + + result := struct { + TypeName string `json:"__typename"` + *CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload: "%T"`, v) + } +} + +// CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess includes the requested fields of the GraphQL type CreateFeedsManagerSuccess. +type CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess struct { + Typename string `json:"__typename"` + FeedsManager CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager `json:"feedsManager"` +} + +// GetTypename returns CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess.Typename, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess) GetTypename() string { + return v.Typename +} + +// GetFeedsManager returns CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess.FeedsManager, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess) GetFeedsManager() CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager { + return v.FeedsManager +} + +// CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager includes the requested fields of the GraphQL type FeedsManager. +type CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager struct { + FeedsManagerParts `json:"-"` +} + +// GetId returns CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager.Id, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager) GetId() string { + return v.FeedsManagerParts.Id +} + +// GetName returns CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager.Name, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager) GetName() string { + return v.FeedsManagerParts.Name +} + +// GetUri returns CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager.Uri, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager) GetUri() string { + return v.FeedsManagerParts.Uri +} + +// GetPublicKey returns CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager.PublicKey, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager) GetPublicKey() string { + return v.FeedsManagerParts.PublicKey +} + +// GetIsConnectionActive returns CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager.IsConnectionActive, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager) GetIsConnectionActive() bool { + return v.FeedsManagerParts.IsConnectionActive +} + +// GetCreatedAt returns CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager.CreatedAt, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager) GetCreatedAt() string { + return v.FeedsManagerParts.CreatedAt +} + +func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager + graphql.NoUnmarshalJSON + } + firstPass.CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.FeedsManagerParts) + if err != nil { + return err + } + return nil +} + +type __premarshalCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager struct { + Id string `json:"id"` + + Name string `json:"name"` + + Uri string `json:"uri"` + + PublicKey string `json:"publicKey"` + + IsConnectionActive bool `json:"isConnectionActive"` + + CreatedAt string `json:"createdAt"` +} + +func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager) __premarshalJSON() (*__premarshalCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager, error) { + var retval __premarshalCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManager + + retval.Id = v.FeedsManagerParts.Id + retval.Name = v.FeedsManagerParts.Name + retval.Uri = v.FeedsManagerParts.Uri + retval.PublicKey = v.FeedsManagerParts.PublicKey + retval.IsConnectionActive = v.FeedsManagerParts.IsConnectionActive + retval.CreatedAt = v.FeedsManagerParts.CreatedAt + return &retval, nil +} + +// CreateFeedsManagerCreateFeedsManagerInputErrors includes the requested fields of the GraphQL type InputErrors. +type CreateFeedsManagerCreateFeedsManagerInputErrors struct { + Typename string `json:"__typename"` + Errors []CreateFeedsManagerCreateFeedsManagerInputErrorsErrorsInputError `json:"errors"` +} + +// GetTypename returns CreateFeedsManagerCreateFeedsManagerInputErrors.Typename, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerInputErrors) GetTypename() string { return v.Typename } + +// GetErrors returns CreateFeedsManagerCreateFeedsManagerInputErrors.Errors, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerInputErrors) GetErrors() []CreateFeedsManagerCreateFeedsManagerInputErrorsErrorsInputError { + return v.Errors +} + +// CreateFeedsManagerCreateFeedsManagerInputErrorsErrorsInputError includes the requested fields of the GraphQL type InputError. +type CreateFeedsManagerCreateFeedsManagerInputErrorsErrorsInputError struct { + Message string `json:"message"` + Code ErrorCode `json:"code"` + Path string `json:"path"` +} + +// GetMessage returns CreateFeedsManagerCreateFeedsManagerInputErrorsErrorsInputError.Message, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerInputErrorsErrorsInputError) GetMessage() string { + return v.Message +} + +// GetCode returns CreateFeedsManagerCreateFeedsManagerInputErrorsErrorsInputError.Code, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerInputErrorsErrorsInputError) GetCode() ErrorCode { + return v.Code +} + +// GetPath returns CreateFeedsManagerCreateFeedsManagerInputErrorsErrorsInputError.Path, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerInputErrorsErrorsInputError) GetPath() string { + return v.Path +} + +// CreateFeedsManagerCreateFeedsManagerNotFoundError includes the requested fields of the GraphQL type NotFoundError. +type CreateFeedsManagerCreateFeedsManagerNotFoundError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns CreateFeedsManagerCreateFeedsManagerNotFoundError.Typename, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerNotFoundError) GetTypename() string { return v.Typename } + +// GetMessage returns CreateFeedsManagerCreateFeedsManagerNotFoundError.Message, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerNotFoundError) GetMessage() string { return v.Message } + +// GetCode returns CreateFeedsManagerCreateFeedsManagerNotFoundError.Code, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerNotFoundError) GetCode() ErrorCode { return v.Code } + +// CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError includes the requested fields of the GraphQL type SingleFeedsManagerError. +type CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError.Typename, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError) GetTypename() string { + return v.Typename +} + +// GetMessage returns CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError.Message, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError) GetMessage() string { + return v.Message +} + +// GetCode returns CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError.Code, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError) GetCode() ErrorCode { + return v.Code +} + +type CreateFeedsManagerInput struct { + Name string `json:"name"` + Uri string `json:"uri"` + PublicKey string `json:"publicKey"` +} + +// GetName returns CreateFeedsManagerInput.Name, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerInput) GetName() string { return v.Name } + +// GetUri returns CreateFeedsManagerInput.Uri, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerInput) GetUri() string { return v.Uri } + +// GetPublicKey returns CreateFeedsManagerInput.PublicKey, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerInput) GetPublicKey() string { return v.PublicKey } + +// CreateFeedsManagerResponse is returned by CreateFeedsManager on success. +type CreateFeedsManagerResponse struct { + CreateFeedsManager CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload `json:"-"` +} + +// GetCreateFeedsManager returns CreateFeedsManagerResponse.CreateFeedsManager, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerResponse) GetCreateFeedsManager() CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload { + return v.CreateFeedsManager +} + +func (v *CreateFeedsManagerResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CreateFeedsManagerResponse + CreateFeedsManager json.RawMessage `json:"createFeedsManager"` + graphql.NoUnmarshalJSON + } + firstPass.CreateFeedsManagerResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.CreateFeedsManager + src := firstPass.CreateFeedsManager + if len(src) != 0 && string(src) != "null" { + err = __unmarshalCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal CreateFeedsManagerResponse.CreateFeedsManager: %w", err) + } + } + } + return nil +} + +type __premarshalCreateFeedsManagerResponse struct { + CreateFeedsManager json.RawMessage `json:"createFeedsManager"` +} + +func (v *CreateFeedsManagerResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CreateFeedsManagerResponse) __premarshalJSON() (*__premarshalCreateFeedsManagerResponse, error) { + var retval __premarshalCreateFeedsManagerResponse + + { + + dst := &retval.CreateFeedsManager + src := v.CreateFeedsManager + var err error + *dst, err = __marshalCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal CreateFeedsManagerResponse.CreateFeedsManager: %w", err) + } + } + return &retval, nil +} + +type ErrorCode string + +const ( + ErrorCodeNotFound ErrorCode = "NOT_FOUND" + ErrorCodeInvalidInput ErrorCode = "INVALID_INPUT" + ErrorCodeUnprocessable ErrorCode = "UNPROCESSABLE" +) + +// FeedsManagerParts includes the GraphQL fields of FeedsManager requested by the fragment FeedsManagerParts. +type FeedsManagerParts struct { + Id string `json:"id"` + Name string `json:"name"` + Uri string `json:"uri"` + PublicKey string `json:"publicKey"` + IsConnectionActive bool `json:"isConnectionActive"` + CreatedAt string `json:"createdAt"` +} + +// GetId returns FeedsManagerParts.Id, and is useful for accessing the field via an interface. +func (v *FeedsManagerParts) GetId() string { return v.Id } + +// GetName returns FeedsManagerParts.Name, and is useful for accessing the field via an interface. +func (v *FeedsManagerParts) GetName() string { return v.Name } + +// GetUri returns FeedsManagerParts.Uri, and is useful for accessing the field via an interface. +func (v *FeedsManagerParts) GetUri() string { return v.Uri } + +// GetPublicKey returns FeedsManagerParts.PublicKey, and is useful for accessing the field via an interface. +func (v *FeedsManagerParts) GetPublicKey() string { return v.PublicKey } + +// GetIsConnectionActive returns FeedsManagerParts.IsConnectionActive, and is useful for accessing the field via an interface. +func (v *FeedsManagerParts) GetIsConnectionActive() bool { return v.IsConnectionActive } + +// GetCreatedAt returns FeedsManagerParts.CreatedAt, and is useful for accessing the field via an interface. +func (v *FeedsManagerParts) GetCreatedAt() string { return v.CreatedAt } + +// GetBridgeBridge includes the requested fields of the GraphQL type Bridge. +type GetBridgeBridge struct { + Typename string `json:"__typename"` + BridgeParts `json:"-"` +} + +// GetTypename returns GetBridgeBridge.Typename, and is useful for accessing the field via an interface. +func (v *GetBridgeBridge) GetTypename() string { return v.Typename } + +// GetId returns GetBridgeBridge.Id, and is useful for accessing the field via an interface. +func (v *GetBridgeBridge) GetId() string { return v.BridgeParts.Id } + +// GetName returns GetBridgeBridge.Name, and is useful for accessing the field via an interface. +func (v *GetBridgeBridge) GetName() string { return v.BridgeParts.Name } + +// GetUrl returns GetBridgeBridge.Url, and is useful for accessing the field via an interface. +func (v *GetBridgeBridge) GetUrl() string { return v.BridgeParts.Url } + +// GetConfirmations returns GetBridgeBridge.Confirmations, and is useful for accessing the field via an interface. +func (v *GetBridgeBridge) GetConfirmations() int { return v.BridgeParts.Confirmations } + +// GetOutgoingToken returns GetBridgeBridge.OutgoingToken, and is useful for accessing the field via an interface. +func (v *GetBridgeBridge) GetOutgoingToken() string { return v.BridgeParts.OutgoingToken } + +// GetMinimumContractPayment returns GetBridgeBridge.MinimumContractPayment, and is useful for accessing the field via an interface. +func (v *GetBridgeBridge) GetMinimumContractPayment() string { + return v.BridgeParts.MinimumContractPayment +} + +// GetCreatedAt returns GetBridgeBridge.CreatedAt, and is useful for accessing the field via an interface. +func (v *GetBridgeBridge) GetCreatedAt() string { return v.BridgeParts.CreatedAt } + +func (v *GetBridgeBridge) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetBridgeBridge + graphql.NoUnmarshalJSON + } + firstPass.GetBridgeBridge = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.BridgeParts) + if err != nil { + return err + } + return nil +} + +type __premarshalGetBridgeBridge struct { + Typename string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + Url string `json:"url"` + + Confirmations int `json:"confirmations"` + + OutgoingToken string `json:"outgoingToken"` + + MinimumContractPayment string `json:"minimumContractPayment"` + + CreatedAt string `json:"createdAt"` +} + +func (v *GetBridgeBridge) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetBridgeBridge) __premarshalJSON() (*__premarshalGetBridgeBridge, error) { + var retval __premarshalGetBridgeBridge + + retval.Typename = v.Typename + retval.Id = v.BridgeParts.Id + retval.Name = v.BridgeParts.Name + retval.Url = v.BridgeParts.Url + retval.Confirmations = v.BridgeParts.Confirmations + retval.OutgoingToken = v.BridgeParts.OutgoingToken + retval.MinimumContractPayment = v.BridgeParts.MinimumContractPayment + retval.CreatedAt = v.BridgeParts.CreatedAt + return &retval, nil +} + +// GetBridgeBridgeBridgePayload includes the requested fields of the GraphQL interface BridgePayload. +// +// GetBridgeBridgeBridgePayload is implemented by the following types: +// GetBridgeBridge +// GetBridgeBridgeNotFoundError +type GetBridgeBridgeBridgePayload interface { + implementsGraphQLInterfaceGetBridgeBridgeBridgePayload() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *GetBridgeBridge) implementsGraphQLInterfaceGetBridgeBridgeBridgePayload() {} +func (v *GetBridgeBridgeNotFoundError) implementsGraphQLInterfaceGetBridgeBridgeBridgePayload() {} + +func __unmarshalGetBridgeBridgeBridgePayload(b []byte, v *GetBridgeBridgeBridgePayload) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Bridge": + *v = new(GetBridgeBridge) + return json.Unmarshal(b, *v) + case "NotFoundError": + *v = new(GetBridgeBridgeNotFoundError) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing BridgePayload.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for GetBridgeBridgeBridgePayload: "%v"`, tn.TypeName) + } +} + +func __marshalGetBridgeBridgeBridgePayload(v *GetBridgeBridgeBridgePayload) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *GetBridgeBridge: + typename = "Bridge" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetBridgeBridge + }{typename, premarshaled} + return json.Marshal(result) + case *GetBridgeBridgeNotFoundError: + typename = "NotFoundError" + + result := struct { + TypeName string `json:"__typename"` + *GetBridgeBridgeNotFoundError + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for GetBridgeBridgeBridgePayload: "%T"`, v) + } +} + +// GetBridgeBridgeNotFoundError includes the requested fields of the GraphQL type NotFoundError. +type GetBridgeBridgeNotFoundError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns GetBridgeBridgeNotFoundError.Typename, and is useful for accessing the field via an interface. +func (v *GetBridgeBridgeNotFoundError) GetTypename() string { return v.Typename } + +// GetMessage returns GetBridgeBridgeNotFoundError.Message, and is useful for accessing the field via an interface. +func (v *GetBridgeBridgeNotFoundError) GetMessage() string { return v.Message } + +// GetCode returns GetBridgeBridgeNotFoundError.Code, and is useful for accessing the field via an interface. +func (v *GetBridgeBridgeNotFoundError) GetCode() ErrorCode { return v.Code } + +// GetBridgeResponse is returned by GetBridge on success. +type GetBridgeResponse struct { + Bridge GetBridgeBridgeBridgePayload `json:"-"` +} + +// GetBridge returns GetBridgeResponse.Bridge, and is useful for accessing the field via an interface. +func (v *GetBridgeResponse) GetBridge() GetBridgeBridgeBridgePayload { return v.Bridge } + +func (v *GetBridgeResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetBridgeResponse + Bridge json.RawMessage `json:"bridge"` + graphql.NoUnmarshalJSON + } + firstPass.GetBridgeResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Bridge + src := firstPass.Bridge + if len(src) != 0 && string(src) != "null" { + err = __unmarshalGetBridgeBridgeBridgePayload( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal GetBridgeResponse.Bridge: %w", err) + } + } + } + return nil +} + +type __premarshalGetBridgeResponse struct { + Bridge json.RawMessage `json:"bridge"` +} + +func (v *GetBridgeResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetBridgeResponse) __premarshalJSON() (*__premarshalGetBridgeResponse, error) { + var retval __premarshalGetBridgeResponse + + { + + dst := &retval.Bridge + src := v.Bridge + var err error + *dst, err = __marshalGetBridgeBridgeBridgePayload( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetBridgeResponse.Bridge: %w", err) + } + } + return &retval, nil +} + +// GetCSAKeysCsaKeysCSAKeysPayload includes the requested fields of the GraphQL type CSAKeysPayload. +type GetCSAKeysCsaKeysCSAKeysPayload struct { + Results []GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey `json:"results"` +} + +// GetResults returns GetCSAKeysCsaKeysCSAKeysPayload.Results, and is useful for accessing the field via an interface. +func (v *GetCSAKeysCsaKeysCSAKeysPayload) GetResults() []GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey { + return v.Results +} + +// GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey includes the requested fields of the GraphQL type CSAKey. +type GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey struct { + Id string `json:"id"` + PublicKey string `json:"publicKey"` + Version int `json:"version"` +} + +// GetId returns GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey.Id, and is useful for accessing the field via an interface. +func (v *GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey) GetId() string { return v.Id } + +// GetPublicKey returns GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey.PublicKey, and is useful for accessing the field via an interface. +func (v *GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey) GetPublicKey() string { return v.PublicKey } + +// GetVersion returns GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey.Version, and is useful for accessing the field via an interface. +func (v *GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey) GetVersion() int { return v.Version } + +// GetCSAKeysResponse is returned by GetCSAKeys on success. +type GetCSAKeysResponse struct { + CsaKeys GetCSAKeysCsaKeysCSAKeysPayload `json:"csaKeys"` +} + +// GetCsaKeys returns GetCSAKeysResponse.CsaKeys, and is useful for accessing the field via an interface. +func (v *GetCSAKeysResponse) GetCsaKeys() GetCSAKeysCsaKeysCSAKeysPayload { return v.CsaKeys } + +// GetFeedsManagerFeedsManager includes the requested fields of the GraphQL type FeedsManager. +type GetFeedsManagerFeedsManager struct { + Typename string `json:"__typename"` + FeedsManagerParts `json:"-"` +} + +// GetTypename returns GetFeedsManagerFeedsManager.Typename, and is useful for accessing the field via an interface. +func (v *GetFeedsManagerFeedsManager) GetTypename() string { return v.Typename } + +// GetId returns GetFeedsManagerFeedsManager.Id, and is useful for accessing the field via an interface. +func (v *GetFeedsManagerFeedsManager) GetId() string { return v.FeedsManagerParts.Id } + +// GetName returns GetFeedsManagerFeedsManager.Name, and is useful for accessing the field via an interface. +func (v *GetFeedsManagerFeedsManager) GetName() string { return v.FeedsManagerParts.Name } + +// GetUri returns GetFeedsManagerFeedsManager.Uri, and is useful for accessing the field via an interface. +func (v *GetFeedsManagerFeedsManager) GetUri() string { return v.FeedsManagerParts.Uri } + +// GetPublicKey returns GetFeedsManagerFeedsManager.PublicKey, and is useful for accessing the field via an interface. +func (v *GetFeedsManagerFeedsManager) GetPublicKey() string { return v.FeedsManagerParts.PublicKey } + +// GetIsConnectionActive returns GetFeedsManagerFeedsManager.IsConnectionActive, and is useful for accessing the field via an interface. +func (v *GetFeedsManagerFeedsManager) GetIsConnectionActive() bool { + return v.FeedsManagerParts.IsConnectionActive +} + +// GetCreatedAt returns GetFeedsManagerFeedsManager.CreatedAt, and is useful for accessing the field via an interface. +func (v *GetFeedsManagerFeedsManager) GetCreatedAt() string { return v.FeedsManagerParts.CreatedAt } + +func (v *GetFeedsManagerFeedsManager) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetFeedsManagerFeedsManager + graphql.NoUnmarshalJSON + } + firstPass.GetFeedsManagerFeedsManager = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.FeedsManagerParts) + if err != nil { + return err + } + return nil +} + +type __premarshalGetFeedsManagerFeedsManager struct { + Typename string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + Uri string `json:"uri"` + + PublicKey string `json:"publicKey"` + + IsConnectionActive bool `json:"isConnectionActive"` + + CreatedAt string `json:"createdAt"` +} + +func (v *GetFeedsManagerFeedsManager) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetFeedsManagerFeedsManager) __premarshalJSON() (*__premarshalGetFeedsManagerFeedsManager, error) { + var retval __premarshalGetFeedsManagerFeedsManager + + retval.Typename = v.Typename + retval.Id = v.FeedsManagerParts.Id + retval.Name = v.FeedsManagerParts.Name + retval.Uri = v.FeedsManagerParts.Uri + retval.PublicKey = v.FeedsManagerParts.PublicKey + retval.IsConnectionActive = v.FeedsManagerParts.IsConnectionActive + retval.CreatedAt = v.FeedsManagerParts.CreatedAt + return &retval, nil +} + +// GetFeedsManagerFeedsManagerFeedsManagerPayload includes the requested fields of the GraphQL interface FeedsManagerPayload. +// +// GetFeedsManagerFeedsManagerFeedsManagerPayload is implemented by the following types: +// GetFeedsManagerFeedsManager +// GetFeedsManagerFeedsManagerNotFoundError +type GetFeedsManagerFeedsManagerFeedsManagerPayload interface { + implementsGraphQLInterfaceGetFeedsManagerFeedsManagerFeedsManagerPayload() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *GetFeedsManagerFeedsManager) implementsGraphQLInterfaceGetFeedsManagerFeedsManagerFeedsManagerPayload() { +} +func (v *GetFeedsManagerFeedsManagerNotFoundError) implementsGraphQLInterfaceGetFeedsManagerFeedsManagerFeedsManagerPayload() { +} + +func __unmarshalGetFeedsManagerFeedsManagerFeedsManagerPayload(b []byte, v *GetFeedsManagerFeedsManagerFeedsManagerPayload) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "FeedsManager": + *v = new(GetFeedsManagerFeedsManager) + return json.Unmarshal(b, *v) + case "NotFoundError": + *v = new(GetFeedsManagerFeedsManagerNotFoundError) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing FeedsManagerPayload.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for GetFeedsManagerFeedsManagerFeedsManagerPayload: "%v"`, tn.TypeName) + } +} + +func __marshalGetFeedsManagerFeedsManagerFeedsManagerPayload(v *GetFeedsManagerFeedsManagerFeedsManagerPayload) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *GetFeedsManagerFeedsManager: + typename = "FeedsManager" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetFeedsManagerFeedsManager + }{typename, premarshaled} + return json.Marshal(result) + case *GetFeedsManagerFeedsManagerNotFoundError: + typename = "NotFoundError" + + result := struct { + TypeName string `json:"__typename"` + *GetFeedsManagerFeedsManagerNotFoundError + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for GetFeedsManagerFeedsManagerFeedsManagerPayload: "%T"`, v) + } +} + +// GetFeedsManagerFeedsManagerNotFoundError includes the requested fields of the GraphQL type NotFoundError. +type GetFeedsManagerFeedsManagerNotFoundError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns GetFeedsManagerFeedsManagerNotFoundError.Typename, and is useful for accessing the field via an interface. +func (v *GetFeedsManagerFeedsManagerNotFoundError) GetTypename() string { return v.Typename } + +// GetMessage returns GetFeedsManagerFeedsManagerNotFoundError.Message, and is useful for accessing the field via an interface. +func (v *GetFeedsManagerFeedsManagerNotFoundError) GetMessage() string { return v.Message } + +// GetCode returns GetFeedsManagerFeedsManagerNotFoundError.Code, and is useful for accessing the field via an interface. +func (v *GetFeedsManagerFeedsManagerNotFoundError) GetCode() ErrorCode { return v.Code } + +// GetFeedsManagerResponse is returned by GetFeedsManager on success. +type GetFeedsManagerResponse struct { + FeedsManager GetFeedsManagerFeedsManagerFeedsManagerPayload `json:"-"` +} + +// GetFeedsManager returns GetFeedsManagerResponse.FeedsManager, and is useful for accessing the field via an interface. +func (v *GetFeedsManagerResponse) GetFeedsManager() GetFeedsManagerFeedsManagerFeedsManagerPayload { + return v.FeedsManager +} + +func (v *GetFeedsManagerResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetFeedsManagerResponse + FeedsManager json.RawMessage `json:"feedsManager"` + graphql.NoUnmarshalJSON + } + firstPass.GetFeedsManagerResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.FeedsManager + src := firstPass.FeedsManager + if len(src) != 0 && string(src) != "null" { + err = __unmarshalGetFeedsManagerFeedsManagerFeedsManagerPayload( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal GetFeedsManagerResponse.FeedsManager: %w", err) + } + } + } + return nil +} + +type __premarshalGetFeedsManagerResponse struct { + FeedsManager json.RawMessage `json:"feedsManager"` +} + +func (v *GetFeedsManagerResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetFeedsManagerResponse) __premarshalJSON() (*__premarshalGetFeedsManagerResponse, error) { + var retval __premarshalGetFeedsManagerResponse + + { + + dst := &retval.FeedsManager + src := v.FeedsManager + var err error + *dst, err = __marshalGetFeedsManagerFeedsManagerFeedsManagerPayload( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetFeedsManagerResponse.FeedsManager: %w", err) + } + } + return &retval, nil +} + +// GetJobJob includes the requested fields of the GraphQL type Job. +type GetJobJob struct { + Typename string `json:"__typename"` + JobParts `json:"-"` +} + +// GetTypename returns GetJobJob.Typename, and is useful for accessing the field via an interface. +func (v *GetJobJob) GetTypename() string { return v.Typename } + +// GetId returns GetJobJob.Id, and is useful for accessing the field via an interface. +func (v *GetJobJob) GetId() string { return v.JobParts.Id } + +// GetName returns GetJobJob.Name, and is useful for accessing the field via an interface. +func (v *GetJobJob) GetName() string { return v.JobParts.Name } + +// GetSchemaVersion returns GetJobJob.SchemaVersion, and is useful for accessing the field via an interface. +func (v *GetJobJob) GetSchemaVersion() int { return v.JobParts.SchemaVersion } + +// GetGasLimit returns GetJobJob.GasLimit, and is useful for accessing the field via an interface. +func (v *GetJobJob) GetGasLimit() int { return v.JobParts.GasLimit } + +// GetForwardingAllowed returns GetJobJob.ForwardingAllowed, and is useful for accessing the field via an interface. +func (v *GetJobJob) GetForwardingAllowed() bool { return v.JobParts.ForwardingAllowed } + +// GetMaxTaskDuration returns GetJobJob.MaxTaskDuration, and is useful for accessing the field via an interface. +func (v *GetJobJob) GetMaxTaskDuration() string { return v.JobParts.MaxTaskDuration } + +// GetExternalJobID returns GetJobJob.ExternalJobID, and is useful for accessing the field via an interface. +func (v *GetJobJob) GetExternalJobID() string { return v.JobParts.ExternalJobID } + +// GetType returns GetJobJob.Type, and is useful for accessing the field via an interface. +func (v *GetJobJob) GetType() string { return v.JobParts.Type } + +// GetSpec returns GetJobJob.Spec, and is useful for accessing the field via an interface. +func (v *GetJobJob) GetSpec() JobPartsSpecJobSpec { return v.JobParts.Spec } + +// GetObservationSource returns GetJobJob.ObservationSource, and is useful for accessing the field via an interface. +func (v *GetJobJob) GetObservationSource() string { return v.JobParts.ObservationSource } + +// GetErrors returns GetJobJob.Errors, and is useful for accessing the field via an interface. +func (v *GetJobJob) GetErrors() []JobPartsErrorsJobError { return v.JobParts.Errors } + +func (v *GetJobJob) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetJobJob + graphql.NoUnmarshalJSON + } + firstPass.GetJobJob = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.JobParts) + if err != nil { + return err + } + return nil +} + +type __premarshalGetJobJob struct { + Typename string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + SchemaVersion int `json:"schemaVersion"` + + GasLimit int `json:"gasLimit"` + + ForwardingAllowed bool `json:"forwardingAllowed"` + + MaxTaskDuration string `json:"maxTaskDuration"` + + ExternalJobID string `json:"externalJobID"` + + Type string `json:"type"` + + Spec json.RawMessage `json:"spec"` + + ObservationSource string `json:"observationSource"` + + Errors []JobPartsErrorsJobError `json:"errors"` +} + +func (v *GetJobJob) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetJobJob) __premarshalJSON() (*__premarshalGetJobJob, error) { + var retval __premarshalGetJobJob + + retval.Typename = v.Typename + retval.Id = v.JobParts.Id + retval.Name = v.JobParts.Name + retval.SchemaVersion = v.JobParts.SchemaVersion + retval.GasLimit = v.JobParts.GasLimit + retval.ForwardingAllowed = v.JobParts.ForwardingAllowed + retval.MaxTaskDuration = v.JobParts.MaxTaskDuration + retval.ExternalJobID = v.JobParts.ExternalJobID + retval.Type = v.JobParts.Type + { + + dst := &retval.Spec + src := v.JobParts.Spec + var err error + *dst, err = __marshalJobPartsSpecJobSpec( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetJobJob.JobParts.Spec: %w", err) + } + } + retval.ObservationSource = v.JobParts.ObservationSource + retval.Errors = v.JobParts.Errors + return &retval, nil +} + +// GetJobJobJobPayload includes the requested fields of the GraphQL interface JobPayload. +// +// GetJobJobJobPayload is implemented by the following types: +// GetJobJob +// GetJobJobNotFoundError +type GetJobJobJobPayload interface { + implementsGraphQLInterfaceGetJobJobJobPayload() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *GetJobJob) implementsGraphQLInterfaceGetJobJobJobPayload() {} +func (v *GetJobJobNotFoundError) implementsGraphQLInterfaceGetJobJobJobPayload() {} + +func __unmarshalGetJobJobJobPayload(b []byte, v *GetJobJobJobPayload) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Job": + *v = new(GetJobJob) + return json.Unmarshal(b, *v) + case "NotFoundError": + *v = new(GetJobJobNotFoundError) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing JobPayload.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for GetJobJobJobPayload: "%v"`, tn.TypeName) + } +} + +func __marshalGetJobJobJobPayload(v *GetJobJobJobPayload) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *GetJobJob: + typename = "Job" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetJobJob + }{typename, premarshaled} + return json.Marshal(result) + case *GetJobJobNotFoundError: + typename = "NotFoundError" + + result := struct { + TypeName string `json:"__typename"` + *GetJobJobNotFoundError + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for GetJobJobJobPayload: "%T"`, v) + } +} + +// GetJobJobNotFoundError includes the requested fields of the GraphQL type NotFoundError. +type GetJobJobNotFoundError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns GetJobJobNotFoundError.Typename, and is useful for accessing the field via an interface. +func (v *GetJobJobNotFoundError) GetTypename() string { return v.Typename } + +// GetMessage returns GetJobJobNotFoundError.Message, and is useful for accessing the field via an interface. +func (v *GetJobJobNotFoundError) GetMessage() string { return v.Message } + +// GetCode returns GetJobJobNotFoundError.Code, and is useful for accessing the field via an interface. +func (v *GetJobJobNotFoundError) GetCode() ErrorCode { return v.Code } + +// GetJobProposalJobProposal includes the requested fields of the GraphQL type JobProposal. +type GetJobProposalJobProposal struct { + Typename string `json:"__typename"` + Id string `json:"id"` + Name string `json:"name"` + Status JobProposalStatus `json:"status"` + RemoteUUID string `json:"remoteUUID"` + ExternalJobID string `json:"externalJobID"` + JobID string `json:"jobID"` + FeedsManager GetJobProposalJobProposalFeedsManager `json:"feedsManager"` + MultiAddrs []string `json:"multiAddrs"` + PendingUpdate bool `json:"pendingUpdate"` + Specs []GetJobProposalJobProposalSpecsJobProposalSpec `json:"specs"` + LatestSpec GetJobProposalJobProposalLatestSpecJobProposalSpec `json:"latestSpec"` +} + +// GetTypename returns GetJobProposalJobProposal.Typename, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposal) GetTypename() string { return v.Typename } + +// GetId returns GetJobProposalJobProposal.Id, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposal) GetId() string { return v.Id } + +// GetName returns GetJobProposalJobProposal.Name, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposal) GetName() string { return v.Name } + +// GetStatus returns GetJobProposalJobProposal.Status, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposal) GetStatus() JobProposalStatus { return v.Status } + +// GetRemoteUUID returns GetJobProposalJobProposal.RemoteUUID, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposal) GetRemoteUUID() string { return v.RemoteUUID } + +// GetExternalJobID returns GetJobProposalJobProposal.ExternalJobID, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposal) GetExternalJobID() string { return v.ExternalJobID } + +// GetJobID returns GetJobProposalJobProposal.JobID, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposal) GetJobID() string { return v.JobID } + +// GetFeedsManager returns GetJobProposalJobProposal.FeedsManager, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposal) GetFeedsManager() GetJobProposalJobProposalFeedsManager { + return v.FeedsManager +} + +// GetMultiAddrs returns GetJobProposalJobProposal.MultiAddrs, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposal) GetMultiAddrs() []string { return v.MultiAddrs } + +// GetPendingUpdate returns GetJobProposalJobProposal.PendingUpdate, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposal) GetPendingUpdate() bool { return v.PendingUpdate } + +// GetSpecs returns GetJobProposalJobProposal.Specs, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposal) GetSpecs() []GetJobProposalJobProposalSpecsJobProposalSpec { + return v.Specs +} + +// GetLatestSpec returns GetJobProposalJobProposal.LatestSpec, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposal) GetLatestSpec() GetJobProposalJobProposalLatestSpecJobProposalSpec { + return v.LatestSpec +} + +// GetJobProposalJobProposalFeedsManager includes the requested fields of the GraphQL type FeedsManager. +type GetJobProposalJobProposalFeedsManager struct { + FeedsManagerParts `json:"-"` +} + +// GetId returns GetJobProposalJobProposalFeedsManager.Id, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalFeedsManager) GetId() string { return v.FeedsManagerParts.Id } + +// GetName returns GetJobProposalJobProposalFeedsManager.Name, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalFeedsManager) GetName() string { return v.FeedsManagerParts.Name } + +// GetUri returns GetJobProposalJobProposalFeedsManager.Uri, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalFeedsManager) GetUri() string { return v.FeedsManagerParts.Uri } + +// GetPublicKey returns GetJobProposalJobProposalFeedsManager.PublicKey, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalFeedsManager) GetPublicKey() string { + return v.FeedsManagerParts.PublicKey +} + +// GetIsConnectionActive returns GetJobProposalJobProposalFeedsManager.IsConnectionActive, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalFeedsManager) GetIsConnectionActive() bool { + return v.FeedsManagerParts.IsConnectionActive +} + +// GetCreatedAt returns GetJobProposalJobProposalFeedsManager.CreatedAt, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalFeedsManager) GetCreatedAt() string { + return v.FeedsManagerParts.CreatedAt +} + +func (v *GetJobProposalJobProposalFeedsManager) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetJobProposalJobProposalFeedsManager + graphql.NoUnmarshalJSON + } + firstPass.GetJobProposalJobProposalFeedsManager = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.FeedsManagerParts) + if err != nil { + return err + } + return nil +} + +type __premarshalGetJobProposalJobProposalFeedsManager struct { + Id string `json:"id"` + + Name string `json:"name"` + + Uri string `json:"uri"` + + PublicKey string `json:"publicKey"` + + IsConnectionActive bool `json:"isConnectionActive"` + + CreatedAt string `json:"createdAt"` +} + +func (v *GetJobProposalJobProposalFeedsManager) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetJobProposalJobProposalFeedsManager) __premarshalJSON() (*__premarshalGetJobProposalJobProposalFeedsManager, error) { + var retval __premarshalGetJobProposalJobProposalFeedsManager + + retval.Id = v.FeedsManagerParts.Id + retval.Name = v.FeedsManagerParts.Name + retval.Uri = v.FeedsManagerParts.Uri + retval.PublicKey = v.FeedsManagerParts.PublicKey + retval.IsConnectionActive = v.FeedsManagerParts.IsConnectionActive + retval.CreatedAt = v.FeedsManagerParts.CreatedAt + return &retval, nil +} + +// GetJobProposalJobProposalJobProposalPayload includes the requested fields of the GraphQL interface JobProposalPayload. +// +// GetJobProposalJobProposalJobProposalPayload is implemented by the following types: +// GetJobProposalJobProposal +// GetJobProposalJobProposalNotFoundError +type GetJobProposalJobProposalJobProposalPayload interface { + implementsGraphQLInterfaceGetJobProposalJobProposalJobProposalPayload() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *GetJobProposalJobProposal) implementsGraphQLInterfaceGetJobProposalJobProposalJobProposalPayload() { +} +func (v *GetJobProposalJobProposalNotFoundError) implementsGraphQLInterfaceGetJobProposalJobProposalJobProposalPayload() { +} + +func __unmarshalGetJobProposalJobProposalJobProposalPayload(b []byte, v *GetJobProposalJobProposalJobProposalPayload) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "JobProposal": + *v = new(GetJobProposalJobProposal) + return json.Unmarshal(b, *v) + case "NotFoundError": + *v = new(GetJobProposalJobProposalNotFoundError) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing JobProposalPayload.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for GetJobProposalJobProposalJobProposalPayload: "%v"`, tn.TypeName) + } +} + +func __marshalGetJobProposalJobProposalJobProposalPayload(v *GetJobProposalJobProposalJobProposalPayload) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *GetJobProposalJobProposal: + typename = "JobProposal" + + result := struct { + TypeName string `json:"__typename"` + *GetJobProposalJobProposal + }{typename, v} + return json.Marshal(result) + case *GetJobProposalJobProposalNotFoundError: + typename = "NotFoundError" + + result := struct { + TypeName string `json:"__typename"` + *GetJobProposalJobProposalNotFoundError + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for GetJobProposalJobProposalJobProposalPayload: "%T"`, v) + } +} + +// GetJobProposalJobProposalLatestSpecJobProposalSpec includes the requested fields of the GraphQL type JobProposalSpec. +type GetJobProposalJobProposalLatestSpecJobProposalSpec struct { + Id string `json:"id"` + Definition string `json:"definition"` + Version int `json:"version"` + Status SpecStatus `json:"status"` + StatusUpdatedAt string `json:"statusUpdatedAt"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +} + +// GetId returns GetJobProposalJobProposalLatestSpecJobProposalSpec.Id, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalLatestSpecJobProposalSpec) GetId() string { return v.Id } + +// GetDefinition returns GetJobProposalJobProposalLatestSpecJobProposalSpec.Definition, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalLatestSpecJobProposalSpec) GetDefinition() string { + return v.Definition +} + +// GetVersion returns GetJobProposalJobProposalLatestSpecJobProposalSpec.Version, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalLatestSpecJobProposalSpec) GetVersion() int { return v.Version } + +// GetStatus returns GetJobProposalJobProposalLatestSpecJobProposalSpec.Status, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalLatestSpecJobProposalSpec) GetStatus() SpecStatus { return v.Status } + +// GetStatusUpdatedAt returns GetJobProposalJobProposalLatestSpecJobProposalSpec.StatusUpdatedAt, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalLatestSpecJobProposalSpec) GetStatusUpdatedAt() string { + return v.StatusUpdatedAt +} + +// GetCreatedAt returns GetJobProposalJobProposalLatestSpecJobProposalSpec.CreatedAt, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalLatestSpecJobProposalSpec) GetCreatedAt() string { + return v.CreatedAt +} + +// GetUpdatedAt returns GetJobProposalJobProposalLatestSpecJobProposalSpec.UpdatedAt, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalLatestSpecJobProposalSpec) GetUpdatedAt() string { + return v.UpdatedAt +} + +// GetJobProposalJobProposalNotFoundError includes the requested fields of the GraphQL type NotFoundError. +type GetJobProposalJobProposalNotFoundError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns GetJobProposalJobProposalNotFoundError.Typename, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalNotFoundError) GetTypename() string { return v.Typename } + +// GetMessage returns GetJobProposalJobProposalNotFoundError.Message, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalNotFoundError) GetMessage() string { return v.Message } + +// GetCode returns GetJobProposalJobProposalNotFoundError.Code, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalNotFoundError) GetCode() ErrorCode { return v.Code } + +// GetJobProposalJobProposalSpecsJobProposalSpec includes the requested fields of the GraphQL type JobProposalSpec. +type GetJobProposalJobProposalSpecsJobProposalSpec struct { + Id string `json:"id"` + Definition string `json:"definition"` + Version int `json:"version"` + Status SpecStatus `json:"status"` + StatusUpdatedAt string `json:"statusUpdatedAt"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +} + +// GetId returns GetJobProposalJobProposalSpecsJobProposalSpec.Id, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalSpecsJobProposalSpec) GetId() string { return v.Id } + +// GetDefinition returns GetJobProposalJobProposalSpecsJobProposalSpec.Definition, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalSpecsJobProposalSpec) GetDefinition() string { return v.Definition } + +// GetVersion returns GetJobProposalJobProposalSpecsJobProposalSpec.Version, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalSpecsJobProposalSpec) GetVersion() int { return v.Version } + +// GetStatus returns GetJobProposalJobProposalSpecsJobProposalSpec.Status, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalSpecsJobProposalSpec) GetStatus() SpecStatus { return v.Status } + +// GetStatusUpdatedAt returns GetJobProposalJobProposalSpecsJobProposalSpec.StatusUpdatedAt, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalSpecsJobProposalSpec) GetStatusUpdatedAt() string { + return v.StatusUpdatedAt +} + +// GetCreatedAt returns GetJobProposalJobProposalSpecsJobProposalSpec.CreatedAt, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalSpecsJobProposalSpec) GetCreatedAt() string { return v.CreatedAt } + +// GetUpdatedAt returns GetJobProposalJobProposalSpecsJobProposalSpec.UpdatedAt, and is useful for accessing the field via an interface. +func (v *GetJobProposalJobProposalSpecsJobProposalSpec) GetUpdatedAt() string { return v.UpdatedAt } + +// GetJobProposalResponse is returned by GetJobProposal on success. +type GetJobProposalResponse struct { + JobProposal GetJobProposalJobProposalJobProposalPayload `json:"-"` +} + +// GetJobProposal returns GetJobProposalResponse.JobProposal, and is useful for accessing the field via an interface. +func (v *GetJobProposalResponse) GetJobProposal() GetJobProposalJobProposalJobProposalPayload { + return v.JobProposal +} + +func (v *GetJobProposalResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetJobProposalResponse + JobProposal json.RawMessage `json:"jobProposal"` + graphql.NoUnmarshalJSON + } + firstPass.GetJobProposalResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.JobProposal + src := firstPass.JobProposal + if len(src) != 0 && string(src) != "null" { + err = __unmarshalGetJobProposalJobProposalJobProposalPayload( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal GetJobProposalResponse.JobProposal: %w", err) + } + } + } + return nil +} + +type __premarshalGetJobProposalResponse struct { + JobProposal json.RawMessage `json:"jobProposal"` +} + +func (v *GetJobProposalResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetJobProposalResponse) __premarshalJSON() (*__premarshalGetJobProposalResponse, error) { + var retval __premarshalGetJobProposalResponse + + { + + dst := &retval.JobProposal + src := v.JobProposal + var err error + *dst, err = __marshalGetJobProposalJobProposalJobProposalPayload( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetJobProposalResponse.JobProposal: %w", err) + } + } + return &retval, nil +} + +// GetJobResponse is returned by GetJob on success. +type GetJobResponse struct { + Job GetJobJobJobPayload `json:"-"` +} + +// GetJob returns GetJobResponse.Job, and is useful for accessing the field via an interface. +func (v *GetJobResponse) GetJob() GetJobJobJobPayload { return v.Job } + +func (v *GetJobResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetJobResponse + Job json.RawMessage `json:"job"` + graphql.NoUnmarshalJSON + } + firstPass.GetJobResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Job + src := firstPass.Job + if len(src) != 0 && string(src) != "null" { + err = __unmarshalGetJobJobJobPayload( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal GetJobResponse.Job: %w", err) + } + } + } + return nil +} + +type __premarshalGetJobResponse struct { + Job json.RawMessage `json:"job"` +} + +func (v *GetJobResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetJobResponse) __premarshalJSON() (*__premarshalGetJobResponse, error) { + var retval __premarshalGetJobResponse + + { + + dst := &retval.Job + src := v.Job + var err error + *dst, err = __marshalGetJobJobJobPayload( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetJobResponse.Job: %w", err) + } + } + return &retval, nil +} + +// JobParts includes the GraphQL fields of Job requested by the fragment JobParts. +type JobParts struct { + Id string `json:"id"` + Name string `json:"name"` + SchemaVersion int `json:"schemaVersion"` + GasLimit int `json:"gasLimit"` + ForwardingAllowed bool `json:"forwardingAllowed"` + MaxTaskDuration string `json:"maxTaskDuration"` + ExternalJobID string `json:"externalJobID"` + Type string `json:"type"` + Spec JobPartsSpecJobSpec `json:"-"` + ObservationSource string `json:"observationSource"` + Errors []JobPartsErrorsJobError `json:"errors"` +} + +// GetId returns JobParts.Id, and is useful for accessing the field via an interface. +func (v *JobParts) GetId() string { return v.Id } + +// GetName returns JobParts.Name, and is useful for accessing the field via an interface. +func (v *JobParts) GetName() string { return v.Name } + +// GetSchemaVersion returns JobParts.SchemaVersion, and is useful for accessing the field via an interface. +func (v *JobParts) GetSchemaVersion() int { return v.SchemaVersion } + +// GetGasLimit returns JobParts.GasLimit, and is useful for accessing the field via an interface. +func (v *JobParts) GetGasLimit() int { return v.GasLimit } + +// GetForwardingAllowed returns JobParts.ForwardingAllowed, and is useful for accessing the field via an interface. +func (v *JobParts) GetForwardingAllowed() bool { return v.ForwardingAllowed } + +// GetMaxTaskDuration returns JobParts.MaxTaskDuration, and is useful for accessing the field via an interface. +func (v *JobParts) GetMaxTaskDuration() string { return v.MaxTaskDuration } + +// GetExternalJobID returns JobParts.ExternalJobID, and is useful for accessing the field via an interface. +func (v *JobParts) GetExternalJobID() string { return v.ExternalJobID } + +// GetType returns JobParts.Type, and is useful for accessing the field via an interface. +func (v *JobParts) GetType() string { return v.Type } + +// GetSpec returns JobParts.Spec, and is useful for accessing the field via an interface. +func (v *JobParts) GetSpec() JobPartsSpecJobSpec { return v.Spec } + +// GetObservationSource returns JobParts.ObservationSource, and is useful for accessing the field via an interface. +func (v *JobParts) GetObservationSource() string { return v.ObservationSource } + +// GetErrors returns JobParts.Errors, and is useful for accessing the field via an interface. +func (v *JobParts) GetErrors() []JobPartsErrorsJobError { return v.Errors } + +func (v *JobParts) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *JobParts + Spec json.RawMessage `json:"spec"` + graphql.NoUnmarshalJSON + } + firstPass.JobParts = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Spec + src := firstPass.Spec + if len(src) != 0 && string(src) != "null" { + err = __unmarshalJobPartsSpecJobSpec( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal JobParts.Spec: %w", err) + } + } + } + return nil +} + +type __premarshalJobParts struct { + Id string `json:"id"` + + Name string `json:"name"` + + SchemaVersion int `json:"schemaVersion"` + + GasLimit int `json:"gasLimit"` + + ForwardingAllowed bool `json:"forwardingAllowed"` + + MaxTaskDuration string `json:"maxTaskDuration"` + + ExternalJobID string `json:"externalJobID"` + + Type string `json:"type"` + + Spec json.RawMessage `json:"spec"` + + ObservationSource string `json:"observationSource"` + + Errors []JobPartsErrorsJobError `json:"errors"` +} + +func (v *JobParts) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *JobParts) __premarshalJSON() (*__premarshalJobParts, error) { + var retval __premarshalJobParts + + retval.Id = v.Id + retval.Name = v.Name + retval.SchemaVersion = v.SchemaVersion + retval.GasLimit = v.GasLimit + retval.ForwardingAllowed = v.ForwardingAllowed + retval.MaxTaskDuration = v.MaxTaskDuration + retval.ExternalJobID = v.ExternalJobID + retval.Type = v.Type + { + + dst := &retval.Spec + src := v.Spec + var err error + *dst, err = __marshalJobPartsSpecJobSpec( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal JobParts.Spec: %w", err) + } + } + retval.ObservationSource = v.ObservationSource + retval.Errors = v.Errors + return &retval, nil +} + +// JobPartsErrorsJobError includes the requested fields of the GraphQL type JobError. +type JobPartsErrorsJobError struct { + Id string `json:"id"` + Description string `json:"description"` + Occurrences int `json:"occurrences"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +} + +// GetId returns JobPartsErrorsJobError.Id, and is useful for accessing the field via an interface. +func (v *JobPartsErrorsJobError) GetId() string { return v.Id } + +// GetDescription returns JobPartsErrorsJobError.Description, and is useful for accessing the field via an interface. +func (v *JobPartsErrorsJobError) GetDescription() string { return v.Description } + +// GetOccurrences returns JobPartsErrorsJobError.Occurrences, and is useful for accessing the field via an interface. +func (v *JobPartsErrorsJobError) GetOccurrences() int { return v.Occurrences } + +// GetCreatedAt returns JobPartsErrorsJobError.CreatedAt, and is useful for accessing the field via an interface. +func (v *JobPartsErrorsJobError) GetCreatedAt() string { return v.CreatedAt } + +// GetUpdatedAt returns JobPartsErrorsJobError.UpdatedAt, and is useful for accessing the field via an interface. +func (v *JobPartsErrorsJobError) GetUpdatedAt() string { return v.UpdatedAt } + +// JobPartsSpecBlockHeaderFeederSpec includes the requested fields of the GraphQL type BlockHeaderFeederSpec. +type JobPartsSpecBlockHeaderFeederSpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecBlockHeaderFeederSpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecBlockHeaderFeederSpec) GetTypename() string { return v.Typename } + +// JobPartsSpecBlockhashStoreSpec includes the requested fields of the GraphQL type BlockhashStoreSpec. +type JobPartsSpecBlockhashStoreSpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecBlockhashStoreSpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecBlockhashStoreSpec) GetTypename() string { return v.Typename } + +// JobPartsSpecBootstrapSpec includes the requested fields of the GraphQL type BootstrapSpec. +type JobPartsSpecBootstrapSpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecBootstrapSpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecBootstrapSpec) GetTypename() string { return v.Typename } + +// JobPartsSpecCronSpec includes the requested fields of the GraphQL type CronSpec. +type JobPartsSpecCronSpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecCronSpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecCronSpec) GetTypename() string { return v.Typename } + +// JobPartsSpecDirectRequestSpec includes the requested fields of the GraphQL type DirectRequestSpec. +type JobPartsSpecDirectRequestSpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecDirectRequestSpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecDirectRequestSpec) GetTypename() string { return v.Typename } + +// JobPartsSpecFluxMonitorSpec includes the requested fields of the GraphQL type FluxMonitorSpec. +type JobPartsSpecFluxMonitorSpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecFluxMonitorSpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecFluxMonitorSpec) GetTypename() string { return v.Typename } + +// JobPartsSpecGatewaySpec includes the requested fields of the GraphQL type GatewaySpec. +type JobPartsSpecGatewaySpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecGatewaySpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecGatewaySpec) GetTypename() string { return v.Typename } + +// JobPartsSpecJobSpec includes the requested fields of the GraphQL interface JobSpec. +// +// JobPartsSpecJobSpec is implemented by the following types: +// JobPartsSpecBlockHeaderFeederSpec +// JobPartsSpecBlockhashStoreSpec +// JobPartsSpecBootstrapSpec +// JobPartsSpecCronSpec +// JobPartsSpecDirectRequestSpec +// JobPartsSpecFluxMonitorSpec +// JobPartsSpecGatewaySpec +// JobPartsSpecKeeperSpec +// JobPartsSpecOCR2Spec +// JobPartsSpecOCRSpec +// JobPartsSpecStandardCapabilitiesSpec +// JobPartsSpecVRFSpec +// JobPartsSpecWebhookSpec +// JobPartsSpecWorkflowSpec +type JobPartsSpecJobSpec interface { + implementsGraphQLInterfaceJobPartsSpecJobSpec() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *JobPartsSpecBlockHeaderFeederSpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecBlockhashStoreSpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecBootstrapSpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecCronSpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecDirectRequestSpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecFluxMonitorSpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecGatewaySpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecKeeperSpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecOCR2Spec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecOCRSpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecStandardCapabilitiesSpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecVRFSpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecWebhookSpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} +func (v *JobPartsSpecWorkflowSpec) implementsGraphQLInterfaceJobPartsSpecJobSpec() {} + +func __unmarshalJobPartsSpecJobSpec(b []byte, v *JobPartsSpecJobSpec) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "BlockHeaderFeederSpec": + *v = new(JobPartsSpecBlockHeaderFeederSpec) + return json.Unmarshal(b, *v) + case "BlockhashStoreSpec": + *v = new(JobPartsSpecBlockhashStoreSpec) + return json.Unmarshal(b, *v) + case "BootstrapSpec": + *v = new(JobPartsSpecBootstrapSpec) + return json.Unmarshal(b, *v) + case "CronSpec": + *v = new(JobPartsSpecCronSpec) + return json.Unmarshal(b, *v) + case "DirectRequestSpec": + *v = new(JobPartsSpecDirectRequestSpec) + return json.Unmarshal(b, *v) + case "FluxMonitorSpec": + *v = new(JobPartsSpecFluxMonitorSpec) + return json.Unmarshal(b, *v) + case "GatewaySpec": + *v = new(JobPartsSpecGatewaySpec) + return json.Unmarshal(b, *v) + case "KeeperSpec": + *v = new(JobPartsSpecKeeperSpec) + return json.Unmarshal(b, *v) + case "OCR2Spec": + *v = new(JobPartsSpecOCR2Spec) + return json.Unmarshal(b, *v) + case "OCRSpec": + *v = new(JobPartsSpecOCRSpec) + return json.Unmarshal(b, *v) + case "StandardCapabilitiesSpec": + *v = new(JobPartsSpecStandardCapabilitiesSpec) + return json.Unmarshal(b, *v) + case "VRFSpec": + *v = new(JobPartsSpecVRFSpec) + return json.Unmarshal(b, *v) + case "WebhookSpec": + *v = new(JobPartsSpecWebhookSpec) + return json.Unmarshal(b, *v) + case "WorkflowSpec": + *v = new(JobPartsSpecWorkflowSpec) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing JobSpec.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for JobPartsSpecJobSpec: "%v"`, tn.TypeName) + } +} + +func __marshalJobPartsSpecJobSpec(v *JobPartsSpecJobSpec) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *JobPartsSpecBlockHeaderFeederSpec: + typename = "BlockHeaderFeederSpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecBlockHeaderFeederSpec + }{typename, v} + return json.Marshal(result) + case *JobPartsSpecBlockhashStoreSpec: + typename = "BlockhashStoreSpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecBlockhashStoreSpec + }{typename, v} + return json.Marshal(result) + case *JobPartsSpecBootstrapSpec: + typename = "BootstrapSpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecBootstrapSpec + }{typename, v} + return json.Marshal(result) + case *JobPartsSpecCronSpec: + typename = "CronSpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecCronSpec + }{typename, v} + return json.Marshal(result) + case *JobPartsSpecDirectRequestSpec: + typename = "DirectRequestSpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecDirectRequestSpec + }{typename, v} + return json.Marshal(result) + case *JobPartsSpecFluxMonitorSpec: + typename = "FluxMonitorSpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecFluxMonitorSpec + }{typename, v} + return json.Marshal(result) + case *JobPartsSpecGatewaySpec: + typename = "GatewaySpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecGatewaySpec + }{typename, v} + return json.Marshal(result) + case *JobPartsSpecKeeperSpec: + typename = "KeeperSpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecKeeperSpec + }{typename, v} + return json.Marshal(result) + case *JobPartsSpecOCR2Spec: + typename = "OCR2Spec" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalJobPartsSpecOCR2Spec + }{typename, premarshaled} + return json.Marshal(result) + case *JobPartsSpecOCRSpec: + typename = "OCRSpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecOCRSpec + }{typename, v} + return json.Marshal(result) + case *JobPartsSpecStandardCapabilitiesSpec: + typename = "StandardCapabilitiesSpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecStandardCapabilitiesSpec + }{typename, v} + return json.Marshal(result) + case *JobPartsSpecVRFSpec: + typename = "VRFSpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecVRFSpec + }{typename, v} + return json.Marshal(result) + case *JobPartsSpecWebhookSpec: + typename = "WebhookSpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecWebhookSpec + }{typename, v} + return json.Marshal(result) + case *JobPartsSpecWorkflowSpec: + typename = "WorkflowSpec" + + result := struct { + TypeName string `json:"__typename"` + *JobPartsSpecWorkflowSpec + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for JobPartsSpecJobSpec: "%T"`, v) + } +} + +// JobPartsSpecKeeperSpec includes the requested fields of the GraphQL type KeeperSpec. +type JobPartsSpecKeeperSpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecKeeperSpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecKeeperSpec) GetTypename() string { return v.Typename } + +// JobPartsSpecOCR2Spec includes the requested fields of the GraphQL type OCR2Spec. +type JobPartsSpecOCR2Spec struct { + Typename string `json:"__typename"` + OCR2Spec `json:"-"` +} + +// GetTypename returns JobPartsSpecOCR2Spec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetTypename() string { return v.Typename } + +// GetBlockchainTimeout returns JobPartsSpecOCR2Spec.BlockchainTimeout, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetBlockchainTimeout() string { return v.OCR2Spec.BlockchainTimeout } + +// GetContractID returns JobPartsSpecOCR2Spec.ContractID, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetContractID() string { return v.OCR2Spec.ContractID } + +// GetContractConfigConfirmations returns JobPartsSpecOCR2Spec.ContractConfigConfirmations, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetContractConfigConfirmations() int { + return v.OCR2Spec.ContractConfigConfirmations +} + +// GetContractConfigTrackerPollInterval returns JobPartsSpecOCR2Spec.ContractConfigTrackerPollInterval, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetContractConfigTrackerPollInterval() string { + return v.OCR2Spec.ContractConfigTrackerPollInterval +} + +// GetCreatedAt returns JobPartsSpecOCR2Spec.CreatedAt, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetCreatedAt() string { return v.OCR2Spec.CreatedAt } + +// GetOcrKeyBundleID returns JobPartsSpecOCR2Spec.OcrKeyBundleID, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetOcrKeyBundleID() string { return v.OCR2Spec.OcrKeyBundleID } + +// GetMonitoringEndpoint returns JobPartsSpecOCR2Spec.MonitoringEndpoint, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetMonitoringEndpoint() string { return v.OCR2Spec.MonitoringEndpoint } + +// GetP2pv2Bootstrappers returns JobPartsSpecOCR2Spec.P2pv2Bootstrappers, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetP2pv2Bootstrappers() []string { return v.OCR2Spec.P2pv2Bootstrappers } + +// GetRelay returns JobPartsSpecOCR2Spec.Relay, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetRelay() string { return v.OCR2Spec.Relay } + +// GetRelayConfig returns JobPartsSpecOCR2Spec.RelayConfig, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetRelayConfig() gqlscalar.Map { return v.OCR2Spec.RelayConfig } + +// GetTransmitterID returns JobPartsSpecOCR2Spec.TransmitterID, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetTransmitterID() string { return v.OCR2Spec.TransmitterID } + +// GetPluginType returns JobPartsSpecOCR2Spec.PluginType, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetPluginType() string { return v.OCR2Spec.PluginType } + +// GetPluginConfig returns JobPartsSpecOCR2Spec.PluginConfig, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCR2Spec) GetPluginConfig() gqlscalar.Map { return v.OCR2Spec.PluginConfig } + +func (v *JobPartsSpecOCR2Spec) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *JobPartsSpecOCR2Spec + graphql.NoUnmarshalJSON + } + firstPass.JobPartsSpecOCR2Spec = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.OCR2Spec) + if err != nil { + return err + } + return nil +} + +type __premarshalJobPartsSpecOCR2Spec struct { + Typename string `json:"__typename"` + + BlockchainTimeout string `json:"blockchainTimeout"` + + ContractID string `json:"contractID"` + + ContractConfigConfirmations int `json:"contractConfigConfirmations"` + + ContractConfigTrackerPollInterval string `json:"contractConfigTrackerPollInterval"` + + CreatedAt string `json:"createdAt"` + + OcrKeyBundleID string `json:"ocrKeyBundleID"` + + MonitoringEndpoint string `json:"monitoringEndpoint"` + + P2pv2Bootstrappers []string `json:"p2pv2Bootstrappers"` + + Relay string `json:"relay"` + + RelayConfig gqlscalar.Map `json:"relayConfig"` + + TransmitterID string `json:"transmitterID"` + + PluginType string `json:"pluginType"` + + PluginConfig gqlscalar.Map `json:"pluginConfig"` +} + +func (v *JobPartsSpecOCR2Spec) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *JobPartsSpecOCR2Spec) __premarshalJSON() (*__premarshalJobPartsSpecOCR2Spec, error) { + var retval __premarshalJobPartsSpecOCR2Spec + + retval.Typename = v.Typename + retval.BlockchainTimeout = v.OCR2Spec.BlockchainTimeout + retval.ContractID = v.OCR2Spec.ContractID + retval.ContractConfigConfirmations = v.OCR2Spec.ContractConfigConfirmations + retval.ContractConfigTrackerPollInterval = v.OCR2Spec.ContractConfigTrackerPollInterval + retval.CreatedAt = v.OCR2Spec.CreatedAt + retval.OcrKeyBundleID = v.OCR2Spec.OcrKeyBundleID + retval.MonitoringEndpoint = v.OCR2Spec.MonitoringEndpoint + retval.P2pv2Bootstrappers = v.OCR2Spec.P2pv2Bootstrappers + retval.Relay = v.OCR2Spec.Relay + retval.RelayConfig = v.OCR2Spec.RelayConfig + retval.TransmitterID = v.OCR2Spec.TransmitterID + retval.PluginType = v.OCR2Spec.PluginType + retval.PluginConfig = v.OCR2Spec.PluginConfig + return &retval, nil +} + +// JobPartsSpecOCRSpec includes the requested fields of the GraphQL type OCRSpec. +type JobPartsSpecOCRSpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecOCRSpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecOCRSpec) GetTypename() string { return v.Typename } + +// JobPartsSpecStandardCapabilitiesSpec includes the requested fields of the GraphQL type StandardCapabilitiesSpec. +type JobPartsSpecStandardCapabilitiesSpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecStandardCapabilitiesSpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecStandardCapabilitiesSpec) GetTypename() string { return v.Typename } + +// JobPartsSpecVRFSpec includes the requested fields of the GraphQL type VRFSpec. +type JobPartsSpecVRFSpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecVRFSpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecVRFSpec) GetTypename() string { return v.Typename } + +// JobPartsSpecWebhookSpec includes the requested fields of the GraphQL type WebhookSpec. +type JobPartsSpecWebhookSpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecWebhookSpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecWebhookSpec) GetTypename() string { return v.Typename } + +// JobPartsSpecWorkflowSpec includes the requested fields of the GraphQL type WorkflowSpec. +type JobPartsSpecWorkflowSpec struct { + Typename string `json:"__typename"` +} + +// GetTypename returns JobPartsSpecWorkflowSpec.Typename, and is useful for accessing the field via an interface. +func (v *JobPartsSpecWorkflowSpec) GetTypename() string { return v.Typename } + +type JobProposalStatus string + +const ( + JobProposalStatusPending JobProposalStatus = "PENDING" + JobProposalStatusApproved JobProposalStatus = "APPROVED" + JobProposalStatusRejected JobProposalStatus = "REJECTED" + JobProposalStatusCancelled JobProposalStatus = "CANCELLED" + JobProposalStatusDeleted JobProposalStatus = "DELETED" + JobProposalStatusRevoked JobProposalStatus = "REVOKED" +) + +// ListBridgesBridgesBridgesPayload includes the requested fields of the GraphQL type BridgesPayload. +type ListBridgesBridgesBridgesPayload struct { + Results []ListBridgesBridgesBridgesPayloadResultsBridge `json:"results"` + Metadata ListBridgesBridgesBridgesPayloadMetadataPaginationMetadata `json:"metadata"` +} + +// GetResults returns ListBridgesBridgesBridgesPayload.Results, and is useful for accessing the field via an interface. +func (v *ListBridgesBridgesBridgesPayload) GetResults() []ListBridgesBridgesBridgesPayloadResultsBridge { + return v.Results +} + +// GetMetadata returns ListBridgesBridgesBridgesPayload.Metadata, and is useful for accessing the field via an interface. +func (v *ListBridgesBridgesBridgesPayload) GetMetadata() ListBridgesBridgesBridgesPayloadMetadataPaginationMetadata { + return v.Metadata +} + +// ListBridgesBridgesBridgesPayloadMetadataPaginationMetadata includes the requested fields of the GraphQL type PaginationMetadata. +type ListBridgesBridgesBridgesPayloadMetadataPaginationMetadata struct { + Total int `json:"total"` +} + +// GetTotal returns ListBridgesBridgesBridgesPayloadMetadataPaginationMetadata.Total, and is useful for accessing the field via an interface. +func (v *ListBridgesBridgesBridgesPayloadMetadataPaginationMetadata) GetTotal() int { return v.Total } + +// ListBridgesBridgesBridgesPayloadResultsBridge includes the requested fields of the GraphQL type Bridge. +type ListBridgesBridgesBridgesPayloadResultsBridge struct { + BridgeParts `json:"-"` +} + +// GetId returns ListBridgesBridgesBridgesPayloadResultsBridge.Id, and is useful for accessing the field via an interface. +func (v *ListBridgesBridgesBridgesPayloadResultsBridge) GetId() string { return v.BridgeParts.Id } + +// GetName returns ListBridgesBridgesBridgesPayloadResultsBridge.Name, and is useful for accessing the field via an interface. +func (v *ListBridgesBridgesBridgesPayloadResultsBridge) GetName() string { return v.BridgeParts.Name } + +// GetUrl returns ListBridgesBridgesBridgesPayloadResultsBridge.Url, and is useful for accessing the field via an interface. +func (v *ListBridgesBridgesBridgesPayloadResultsBridge) GetUrl() string { return v.BridgeParts.Url } + +// GetConfirmations returns ListBridgesBridgesBridgesPayloadResultsBridge.Confirmations, and is useful for accessing the field via an interface. +func (v *ListBridgesBridgesBridgesPayloadResultsBridge) GetConfirmations() int { + return v.BridgeParts.Confirmations +} + +// GetOutgoingToken returns ListBridgesBridgesBridgesPayloadResultsBridge.OutgoingToken, and is useful for accessing the field via an interface. +func (v *ListBridgesBridgesBridgesPayloadResultsBridge) GetOutgoingToken() string { + return v.BridgeParts.OutgoingToken +} + +// GetMinimumContractPayment returns ListBridgesBridgesBridgesPayloadResultsBridge.MinimumContractPayment, and is useful for accessing the field via an interface. +func (v *ListBridgesBridgesBridgesPayloadResultsBridge) GetMinimumContractPayment() string { + return v.BridgeParts.MinimumContractPayment +} + +// GetCreatedAt returns ListBridgesBridgesBridgesPayloadResultsBridge.CreatedAt, and is useful for accessing the field via an interface. +func (v *ListBridgesBridgesBridgesPayloadResultsBridge) GetCreatedAt() string { + return v.BridgeParts.CreatedAt +} + +func (v *ListBridgesBridgesBridgesPayloadResultsBridge) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListBridgesBridgesBridgesPayloadResultsBridge + graphql.NoUnmarshalJSON + } + firstPass.ListBridgesBridgesBridgesPayloadResultsBridge = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.BridgeParts) + if err != nil { + return err + } + return nil +} + +type __premarshalListBridgesBridgesBridgesPayloadResultsBridge struct { + Id string `json:"id"` + + Name string `json:"name"` + + Url string `json:"url"` + + Confirmations int `json:"confirmations"` + + OutgoingToken string `json:"outgoingToken"` + + MinimumContractPayment string `json:"minimumContractPayment"` + + CreatedAt string `json:"createdAt"` +} + +func (v *ListBridgesBridgesBridgesPayloadResultsBridge) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListBridgesBridgesBridgesPayloadResultsBridge) __premarshalJSON() (*__premarshalListBridgesBridgesBridgesPayloadResultsBridge, error) { + var retval __premarshalListBridgesBridgesBridgesPayloadResultsBridge + + retval.Id = v.BridgeParts.Id + retval.Name = v.BridgeParts.Name + retval.Url = v.BridgeParts.Url + retval.Confirmations = v.BridgeParts.Confirmations + retval.OutgoingToken = v.BridgeParts.OutgoingToken + retval.MinimumContractPayment = v.BridgeParts.MinimumContractPayment + retval.CreatedAt = v.BridgeParts.CreatedAt + return &retval, nil +} + +// ListBridgesResponse is returned by ListBridges on success. +type ListBridgesResponse struct { + Bridges ListBridgesBridgesBridgesPayload `json:"bridges"` +} + +// GetBridges returns ListBridgesResponse.Bridges, and is useful for accessing the field via an interface. +func (v *ListBridgesResponse) GetBridges() ListBridgesBridgesBridgesPayload { return v.Bridges } + +// ListFeedsManagersFeedsManagersFeedsManagersPayload includes the requested fields of the GraphQL type FeedsManagersPayload. +type ListFeedsManagersFeedsManagersFeedsManagersPayload struct { + Results []ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager `json:"results"` +} + +// GetResults returns ListFeedsManagersFeedsManagersFeedsManagersPayload.Results, and is useful for accessing the field via an interface. +func (v *ListFeedsManagersFeedsManagersFeedsManagersPayload) GetResults() []ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager { + return v.Results +} + +// ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager includes the requested fields of the GraphQL type FeedsManager. +type ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager struct { + FeedsManagerParts `json:"-"` +} + +// GetId returns ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager.Id, and is useful for accessing the field via an interface. +func (v *ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager) GetId() string { + return v.FeedsManagerParts.Id +} + +// GetName returns ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager.Name, and is useful for accessing the field via an interface. +func (v *ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager) GetName() string { + return v.FeedsManagerParts.Name +} + +// GetUri returns ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager.Uri, and is useful for accessing the field via an interface. +func (v *ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager) GetUri() string { + return v.FeedsManagerParts.Uri +} + +// GetPublicKey returns ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager.PublicKey, and is useful for accessing the field via an interface. +func (v *ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager) GetPublicKey() string { + return v.FeedsManagerParts.PublicKey +} + +// GetIsConnectionActive returns ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager.IsConnectionActive, and is useful for accessing the field via an interface. +func (v *ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager) GetIsConnectionActive() bool { + return v.FeedsManagerParts.IsConnectionActive +} + +// GetCreatedAt returns ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager.CreatedAt, and is useful for accessing the field via an interface. +func (v *ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager) GetCreatedAt() string { + return v.FeedsManagerParts.CreatedAt +} + +func (v *ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager + graphql.NoUnmarshalJSON + } + firstPass.ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.FeedsManagerParts) + if err != nil { + return err + } + return nil +} + +type __premarshalListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager struct { + Id string `json:"id"` + + Name string `json:"name"` + + Uri string `json:"uri"` + + PublicKey string `json:"publicKey"` + + IsConnectionActive bool `json:"isConnectionActive"` + + CreatedAt string `json:"createdAt"` +} + +func (v *ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager) __premarshalJSON() (*__premarshalListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager, error) { + var retval __premarshalListFeedsManagersFeedsManagersFeedsManagersPayloadResultsFeedsManager + + retval.Id = v.FeedsManagerParts.Id + retval.Name = v.FeedsManagerParts.Name + retval.Uri = v.FeedsManagerParts.Uri + retval.PublicKey = v.FeedsManagerParts.PublicKey + retval.IsConnectionActive = v.FeedsManagerParts.IsConnectionActive + retval.CreatedAt = v.FeedsManagerParts.CreatedAt + return &retval, nil +} + +// ListFeedsManagersResponse is returned by ListFeedsManagers on success. +type ListFeedsManagersResponse struct { + FeedsManagers ListFeedsManagersFeedsManagersFeedsManagersPayload `json:"feedsManagers"` +} + +// GetFeedsManagers returns ListFeedsManagersResponse.FeedsManagers, and is useful for accessing the field via an interface. +func (v *ListFeedsManagersResponse) GetFeedsManagers() ListFeedsManagersFeedsManagersFeedsManagersPayload { + return v.FeedsManagers +} + +// ListJobsJobsJobsPayload includes the requested fields of the GraphQL type JobsPayload. +type ListJobsJobsJobsPayload struct { + Results []ListJobsJobsJobsPayloadResultsJob `json:"results"` + Metadata ListJobsJobsJobsPayloadMetadataPaginationMetadata `json:"metadata"` +} + +// GetResults returns ListJobsJobsJobsPayload.Results, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayload) GetResults() []ListJobsJobsJobsPayloadResultsJob { return v.Results } + +// GetMetadata returns ListJobsJobsJobsPayload.Metadata, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayload) GetMetadata() ListJobsJobsJobsPayloadMetadataPaginationMetadata { + return v.Metadata +} + +// ListJobsJobsJobsPayloadMetadataPaginationMetadata includes the requested fields of the GraphQL type PaginationMetadata. +type ListJobsJobsJobsPayloadMetadataPaginationMetadata struct { + Total int `json:"total"` +} + +// GetTotal returns ListJobsJobsJobsPayloadMetadataPaginationMetadata.Total, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayloadMetadataPaginationMetadata) GetTotal() int { return v.Total } + +// ListJobsJobsJobsPayloadResultsJob includes the requested fields of the GraphQL type Job. +type ListJobsJobsJobsPayloadResultsJob struct { + JobParts `json:"-"` +} + +// GetId returns ListJobsJobsJobsPayloadResultsJob.Id, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayloadResultsJob) GetId() string { return v.JobParts.Id } + +// GetName returns ListJobsJobsJobsPayloadResultsJob.Name, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayloadResultsJob) GetName() string { return v.JobParts.Name } + +// GetSchemaVersion returns ListJobsJobsJobsPayloadResultsJob.SchemaVersion, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayloadResultsJob) GetSchemaVersion() int { return v.JobParts.SchemaVersion } + +// GetGasLimit returns ListJobsJobsJobsPayloadResultsJob.GasLimit, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayloadResultsJob) GetGasLimit() int { return v.JobParts.GasLimit } + +// GetForwardingAllowed returns ListJobsJobsJobsPayloadResultsJob.ForwardingAllowed, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayloadResultsJob) GetForwardingAllowed() bool { + return v.JobParts.ForwardingAllowed +} + +// GetMaxTaskDuration returns ListJobsJobsJobsPayloadResultsJob.MaxTaskDuration, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayloadResultsJob) GetMaxTaskDuration() string { + return v.JobParts.MaxTaskDuration +} + +// GetExternalJobID returns ListJobsJobsJobsPayloadResultsJob.ExternalJobID, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayloadResultsJob) GetExternalJobID() string { + return v.JobParts.ExternalJobID +} + +// GetType returns ListJobsJobsJobsPayloadResultsJob.Type, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayloadResultsJob) GetType() string { return v.JobParts.Type } + +// GetSpec returns ListJobsJobsJobsPayloadResultsJob.Spec, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayloadResultsJob) GetSpec() JobPartsSpecJobSpec { return v.JobParts.Spec } + +// GetObservationSource returns ListJobsJobsJobsPayloadResultsJob.ObservationSource, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayloadResultsJob) GetObservationSource() string { + return v.JobParts.ObservationSource +} + +// GetErrors returns ListJobsJobsJobsPayloadResultsJob.Errors, and is useful for accessing the field via an interface. +func (v *ListJobsJobsJobsPayloadResultsJob) GetErrors() []JobPartsErrorsJobError { + return v.JobParts.Errors +} + +func (v *ListJobsJobsJobsPayloadResultsJob) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListJobsJobsJobsPayloadResultsJob + graphql.NoUnmarshalJSON + } + firstPass.ListJobsJobsJobsPayloadResultsJob = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.JobParts) + if err != nil { + return err + } + return nil +} + +type __premarshalListJobsJobsJobsPayloadResultsJob struct { + Id string `json:"id"` + + Name string `json:"name"` + + SchemaVersion int `json:"schemaVersion"` + + GasLimit int `json:"gasLimit"` + + ForwardingAllowed bool `json:"forwardingAllowed"` + + MaxTaskDuration string `json:"maxTaskDuration"` + + ExternalJobID string `json:"externalJobID"` + + Type string `json:"type"` + + Spec json.RawMessage `json:"spec"` + + ObservationSource string `json:"observationSource"` + + Errors []JobPartsErrorsJobError `json:"errors"` +} + +func (v *ListJobsJobsJobsPayloadResultsJob) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListJobsJobsJobsPayloadResultsJob) __premarshalJSON() (*__premarshalListJobsJobsJobsPayloadResultsJob, error) { + var retval __premarshalListJobsJobsJobsPayloadResultsJob + + retval.Id = v.JobParts.Id + retval.Name = v.JobParts.Name + retval.SchemaVersion = v.JobParts.SchemaVersion + retval.GasLimit = v.JobParts.GasLimit + retval.ForwardingAllowed = v.JobParts.ForwardingAllowed + retval.MaxTaskDuration = v.JobParts.MaxTaskDuration + retval.ExternalJobID = v.JobParts.ExternalJobID + retval.Type = v.JobParts.Type + { + + dst := &retval.Spec + src := v.JobParts.Spec + var err error + *dst, err = __marshalJobPartsSpecJobSpec( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListJobsJobsJobsPayloadResultsJob.JobParts.Spec: %w", err) + } + } + retval.ObservationSource = v.JobParts.ObservationSource + retval.Errors = v.JobParts.Errors + return &retval, nil +} + +// ListJobsResponse is returned by ListJobs on success. +type ListJobsResponse struct { + Jobs ListJobsJobsJobsPayload `json:"jobs"` +} + +// GetJobs returns ListJobsResponse.Jobs, and is useful for accessing the field via an interface. +func (v *ListJobsResponse) GetJobs() ListJobsJobsJobsPayload { return v.Jobs } + +// #################### +// Jobs and Job Proposals +// #################### +type OCR2Spec struct { + BlockchainTimeout string `json:"blockchainTimeout"` + ContractID string `json:"contractID"` + ContractConfigConfirmations int `json:"contractConfigConfirmations"` + ContractConfigTrackerPollInterval string `json:"contractConfigTrackerPollInterval"` + CreatedAt string `json:"createdAt"` + OcrKeyBundleID string `json:"ocrKeyBundleID"` + MonitoringEndpoint string `json:"monitoringEndpoint"` + P2pv2Bootstrappers []string `json:"p2pv2Bootstrappers"` + Relay string `json:"relay"` + RelayConfig gqlscalar.Map `json:"relayConfig"` + TransmitterID string `json:"transmitterID"` + PluginType string `json:"pluginType"` + PluginConfig gqlscalar.Map `json:"pluginConfig"` +} + +// GetBlockchainTimeout returns OCR2Spec.BlockchainTimeout, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetBlockchainTimeout() string { return v.BlockchainTimeout } + +// GetContractID returns OCR2Spec.ContractID, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetContractID() string { return v.ContractID } + +// GetContractConfigConfirmations returns OCR2Spec.ContractConfigConfirmations, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetContractConfigConfirmations() int { return v.ContractConfigConfirmations } + +// GetContractConfigTrackerPollInterval returns OCR2Spec.ContractConfigTrackerPollInterval, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetContractConfigTrackerPollInterval() string { + return v.ContractConfigTrackerPollInterval +} + +// GetCreatedAt returns OCR2Spec.CreatedAt, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetCreatedAt() string { return v.CreatedAt } + +// GetOcrKeyBundleID returns OCR2Spec.OcrKeyBundleID, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetOcrKeyBundleID() string { return v.OcrKeyBundleID } + +// GetMonitoringEndpoint returns OCR2Spec.MonitoringEndpoint, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetMonitoringEndpoint() string { return v.MonitoringEndpoint } + +// GetP2pv2Bootstrappers returns OCR2Spec.P2pv2Bootstrappers, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetP2pv2Bootstrappers() []string { return v.P2pv2Bootstrappers } + +// GetRelay returns OCR2Spec.Relay, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetRelay() string { return v.Relay } + +// GetRelayConfig returns OCR2Spec.RelayConfig, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetRelayConfig() gqlscalar.Map { return v.RelayConfig } + +// GetTransmitterID returns OCR2Spec.TransmitterID, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetTransmitterID() string { return v.TransmitterID } + +// GetPluginType returns OCR2Spec.PluginType, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetPluginType() string { return v.PluginType } + +// GetPluginConfig returns OCR2Spec.PluginConfig, and is useful for accessing the field via an interface. +func (v *OCR2Spec) GetPluginConfig() gqlscalar.Map { return v.PluginConfig } + +// RejectJobProposalSpecRejectJobProposalSpecNotFoundError includes the requested fields of the GraphQL type NotFoundError. +type RejectJobProposalSpecRejectJobProposalSpecNotFoundError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns RejectJobProposalSpecRejectJobProposalSpecNotFoundError.Typename, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecRejectJobProposalSpecNotFoundError) GetTypename() string { + return v.Typename +} + +// GetMessage returns RejectJobProposalSpecRejectJobProposalSpecNotFoundError.Message, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecRejectJobProposalSpecNotFoundError) GetMessage() string { + return v.Message +} + +// GetCode returns RejectJobProposalSpecRejectJobProposalSpecNotFoundError.Code, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecRejectJobProposalSpecNotFoundError) GetCode() ErrorCode { return v.Code } + +// RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload includes the requested fields of the GraphQL interface RejectJobProposalSpecPayload. +// +// RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload is implemented by the following types: +// RejectJobProposalSpecRejectJobProposalSpecNotFoundError +// RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccess +type RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload interface { + implementsGraphQLInterfaceRejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *RejectJobProposalSpecRejectJobProposalSpecNotFoundError) implementsGraphQLInterfaceRejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload() { +} +func (v *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccess) implementsGraphQLInterfaceRejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload() { +} + +func __unmarshalRejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload(b []byte, v *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "NotFoundError": + *v = new(RejectJobProposalSpecRejectJobProposalSpecNotFoundError) + return json.Unmarshal(b, *v) + case "RejectJobProposalSpecSuccess": + *v = new(RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccess) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing RejectJobProposalSpecPayload.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload: "%v"`, tn.TypeName) + } +} + +func __marshalRejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload(v *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *RejectJobProposalSpecRejectJobProposalSpecNotFoundError: + typename = "NotFoundError" + + result := struct { + TypeName string `json:"__typename"` + *RejectJobProposalSpecRejectJobProposalSpecNotFoundError + }{typename, v} + return json.Marshal(result) + case *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccess: + typename = "RejectJobProposalSpecSuccess" + + result := struct { + TypeName string `json:"__typename"` + *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccess + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload: "%T"`, v) + } +} + +// RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccess includes the requested fields of the GraphQL type RejectJobProposalSpecSuccess. +type RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccess struct { + Typename string `json:"__typename"` + Spec RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec `json:"spec"` +} + +// GetTypename returns RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccess.Typename, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccess) GetTypename() string { + return v.Typename +} + +// GetSpec returns RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccess.Spec, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccess) GetSpec() RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec { + return v.Spec +} + +// RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec includes the requested fields of the GraphQL type JobProposalSpec. +type RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec struct { + Id string `json:"id"` + Definition string `json:"definition"` + Version int `json:"version"` + Status SpecStatus `json:"status"` + StatusUpdatedAt string `json:"statusUpdatedAt"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +} + +// GetId returns RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec.Id, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec) GetId() string { + return v.Id +} + +// GetDefinition returns RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec.Definition, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec) GetDefinition() string { + return v.Definition +} + +// GetVersion returns RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec.Version, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec) GetVersion() int { + return v.Version +} + +// GetStatus returns RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec.Status, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec) GetStatus() SpecStatus { + return v.Status +} + +// GetStatusUpdatedAt returns RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec.StatusUpdatedAt, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec) GetStatusUpdatedAt() string { + return v.StatusUpdatedAt +} + +// GetCreatedAt returns RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec.CreatedAt, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec) GetCreatedAt() string { + return v.CreatedAt +} + +// GetUpdatedAt returns RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec.UpdatedAt, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecSuccessSpecJobProposalSpec) GetUpdatedAt() string { + return v.UpdatedAt +} + +// RejectJobProposalSpecResponse is returned by RejectJobProposalSpec on success. +type RejectJobProposalSpecResponse struct { + RejectJobProposalSpec RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload `json:"-"` +} + +// GetRejectJobProposalSpec returns RejectJobProposalSpecResponse.RejectJobProposalSpec, and is useful for accessing the field via an interface. +func (v *RejectJobProposalSpecResponse) GetRejectJobProposalSpec() RejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload { + return v.RejectJobProposalSpec +} + +func (v *RejectJobProposalSpecResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *RejectJobProposalSpecResponse + RejectJobProposalSpec json.RawMessage `json:"rejectJobProposalSpec"` + graphql.NoUnmarshalJSON + } + firstPass.RejectJobProposalSpecResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.RejectJobProposalSpec + src := firstPass.RejectJobProposalSpec + if len(src) != 0 && string(src) != "null" { + err = __unmarshalRejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal RejectJobProposalSpecResponse.RejectJobProposalSpec: %w", err) + } + } + } + return nil +} + +type __premarshalRejectJobProposalSpecResponse struct { + RejectJobProposalSpec json.RawMessage `json:"rejectJobProposalSpec"` +} + +func (v *RejectJobProposalSpecResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *RejectJobProposalSpecResponse) __premarshalJSON() (*__premarshalRejectJobProposalSpecResponse, error) { + var retval __premarshalRejectJobProposalSpecResponse + + { + + dst := &retval.RejectJobProposalSpec + src := v.RejectJobProposalSpec + var err error + *dst, err = __marshalRejectJobProposalSpecRejectJobProposalSpecRejectJobProposalSpecPayload( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal RejectJobProposalSpecResponse.RejectJobProposalSpec: %w", err) + } + } + return &retval, nil +} + +type SpecStatus string + +const ( + SpecStatusUnknown SpecStatus = "UNKNOWN" + SpecStatusPending SpecStatus = "PENDING" + SpecStatusApproved SpecStatus = "APPROVED" + SpecStatusRejected SpecStatus = "REJECTED" + SpecStatusCancelled SpecStatus = "CANCELLED" + SpecStatusRevoked SpecStatus = "REVOKED" +) + +type UpdateFeedsManagerInput struct { + Name string `json:"name"` + Uri string `json:"uri"` + PublicKey string `json:"publicKey"` +} + +// GetName returns UpdateFeedsManagerInput.Name, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerInput) GetName() string { return v.Name } + +// GetUri returns UpdateFeedsManagerInput.Uri, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerInput) GetUri() string { return v.Uri } + +// GetPublicKey returns UpdateFeedsManagerInput.PublicKey, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerInput) GetPublicKey() string { return v.PublicKey } + +// UpdateFeedsManagerResponse is returned by UpdateFeedsManager on success. +type UpdateFeedsManagerResponse struct { + UpdateFeedsManager UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload `json:"-"` +} + +// GetUpdateFeedsManager returns UpdateFeedsManagerResponse.UpdateFeedsManager, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerResponse) GetUpdateFeedsManager() UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload { + return v.UpdateFeedsManager +} + +func (v *UpdateFeedsManagerResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *UpdateFeedsManagerResponse + UpdateFeedsManager json.RawMessage `json:"updateFeedsManager"` + graphql.NoUnmarshalJSON + } + firstPass.UpdateFeedsManagerResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.UpdateFeedsManager + src := firstPass.UpdateFeedsManager + if len(src) != 0 && string(src) != "null" { + err = __unmarshalUpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal UpdateFeedsManagerResponse.UpdateFeedsManager: %w", err) + } + } + } + return nil +} + +type __premarshalUpdateFeedsManagerResponse struct { + UpdateFeedsManager json.RawMessage `json:"updateFeedsManager"` +} + +func (v *UpdateFeedsManagerResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *UpdateFeedsManagerResponse) __premarshalJSON() (*__premarshalUpdateFeedsManagerResponse, error) { + var retval __premarshalUpdateFeedsManagerResponse + + { + + dst := &retval.UpdateFeedsManager + src := v.UpdateFeedsManager + var err error + *dst, err = __marshalUpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal UpdateFeedsManagerResponse.UpdateFeedsManager: %w", err) + } + } + return &retval, nil +} + +// UpdateFeedsManagerUpdateFeedsManagerInputErrors includes the requested fields of the GraphQL type InputErrors. +type UpdateFeedsManagerUpdateFeedsManagerInputErrors struct { + Typename string `json:"__typename"` + Errors []UpdateFeedsManagerUpdateFeedsManagerInputErrorsErrorsInputError `json:"errors"` +} + +// GetTypename returns UpdateFeedsManagerUpdateFeedsManagerInputErrors.Typename, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerInputErrors) GetTypename() string { return v.Typename } + +// GetErrors returns UpdateFeedsManagerUpdateFeedsManagerInputErrors.Errors, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerInputErrors) GetErrors() []UpdateFeedsManagerUpdateFeedsManagerInputErrorsErrorsInputError { + return v.Errors +} + +// UpdateFeedsManagerUpdateFeedsManagerInputErrorsErrorsInputError includes the requested fields of the GraphQL type InputError. +type UpdateFeedsManagerUpdateFeedsManagerInputErrorsErrorsInputError struct { + Message string `json:"message"` + Code ErrorCode `json:"code"` + Path string `json:"path"` +} + +// GetMessage returns UpdateFeedsManagerUpdateFeedsManagerInputErrorsErrorsInputError.Message, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerInputErrorsErrorsInputError) GetMessage() string { + return v.Message +} + +// GetCode returns UpdateFeedsManagerUpdateFeedsManagerInputErrorsErrorsInputError.Code, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerInputErrorsErrorsInputError) GetCode() ErrorCode { + return v.Code +} + +// GetPath returns UpdateFeedsManagerUpdateFeedsManagerInputErrorsErrorsInputError.Path, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerInputErrorsErrorsInputError) GetPath() string { + return v.Path +} + +// UpdateFeedsManagerUpdateFeedsManagerNotFoundError includes the requested fields of the GraphQL type NotFoundError. +type UpdateFeedsManagerUpdateFeedsManagerNotFoundError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns UpdateFeedsManagerUpdateFeedsManagerNotFoundError.Typename, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerNotFoundError) GetTypename() string { return v.Typename } + +// GetMessage returns UpdateFeedsManagerUpdateFeedsManagerNotFoundError.Message, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerNotFoundError) GetMessage() string { return v.Message } + +// GetCode returns UpdateFeedsManagerUpdateFeedsManagerNotFoundError.Code, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerNotFoundError) GetCode() ErrorCode { return v.Code } + +// UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload includes the requested fields of the GraphQL interface UpdateFeedsManagerPayload. +// +// UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload is implemented by the following types: +// UpdateFeedsManagerUpdateFeedsManagerInputErrors +// UpdateFeedsManagerUpdateFeedsManagerNotFoundError +// UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccess +type UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload interface { + implementsGraphQLInterfaceUpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *UpdateFeedsManagerUpdateFeedsManagerInputErrors) implementsGraphQLInterfaceUpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload() { +} +func (v *UpdateFeedsManagerUpdateFeedsManagerNotFoundError) implementsGraphQLInterfaceUpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload() { +} +func (v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccess) implementsGraphQLInterfaceUpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload() { +} + +func __unmarshalUpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload(b []byte, v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "InputErrors": + *v = new(UpdateFeedsManagerUpdateFeedsManagerInputErrors) + return json.Unmarshal(b, *v) + case "NotFoundError": + *v = new(UpdateFeedsManagerUpdateFeedsManagerNotFoundError) + return json.Unmarshal(b, *v) + case "UpdateFeedsManagerSuccess": + *v = new(UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccess) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing UpdateFeedsManagerPayload.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload: "%v"`, tn.TypeName) + } +} + +func __marshalUpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload(v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *UpdateFeedsManagerUpdateFeedsManagerInputErrors: + typename = "InputErrors" + + result := struct { + TypeName string `json:"__typename"` + *UpdateFeedsManagerUpdateFeedsManagerInputErrors + }{typename, v} + return json.Marshal(result) + case *UpdateFeedsManagerUpdateFeedsManagerNotFoundError: + typename = "NotFoundError" + + result := struct { + TypeName string `json:"__typename"` + *UpdateFeedsManagerUpdateFeedsManagerNotFoundError + }{typename, v} + return json.Marshal(result) + case *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccess: + typename = "UpdateFeedsManagerSuccess" + + result := struct { + TypeName string `json:"__typename"` + *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccess + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerPayload: "%T"`, v) + } +} + +// UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccess includes the requested fields of the GraphQL type UpdateFeedsManagerSuccess. +type UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccess struct { + Typename string `json:"__typename"` + FeedsManager UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager `json:"feedsManager"` +} + +// GetTypename returns UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccess.Typename, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccess) GetTypename() string { + return v.Typename +} + +// GetFeedsManager returns UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccess.FeedsManager, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccess) GetFeedsManager() UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager { + return v.FeedsManager +} + +// UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager includes the requested fields of the GraphQL type FeedsManager. +type UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager struct { + FeedsManagerParts `json:"-"` +} + +// GetId returns UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager.Id, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager) GetId() string { + return v.FeedsManagerParts.Id +} + +// GetName returns UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager.Name, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager) GetName() string { + return v.FeedsManagerParts.Name +} + +// GetUri returns UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager.Uri, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager) GetUri() string { + return v.FeedsManagerParts.Uri +} + +// GetPublicKey returns UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager.PublicKey, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager) GetPublicKey() string { + return v.FeedsManagerParts.PublicKey +} + +// GetIsConnectionActive returns UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager.IsConnectionActive, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager) GetIsConnectionActive() bool { + return v.FeedsManagerParts.IsConnectionActive +} + +// GetCreatedAt returns UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager.CreatedAt, and is useful for accessing the field via an interface. +func (v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager) GetCreatedAt() string { + return v.FeedsManagerParts.CreatedAt +} + +func (v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager + graphql.NoUnmarshalJSON + } + firstPass.UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.FeedsManagerParts) + if err != nil { + return err + } + return nil +} + +type __premarshalUpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager struct { + Id string `json:"id"` + + Name string `json:"name"` + + Uri string `json:"uri"` + + PublicKey string `json:"publicKey"` + + IsConnectionActive bool `json:"isConnectionActive"` + + CreatedAt string `json:"createdAt"` +} + +func (v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *UpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager) __premarshalJSON() (*__premarshalUpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager, error) { + var retval __premarshalUpdateFeedsManagerUpdateFeedsManagerUpdateFeedsManagerSuccessFeedsManager + + retval.Id = v.FeedsManagerParts.Id + retval.Name = v.FeedsManagerParts.Name + retval.Uri = v.FeedsManagerParts.Uri + retval.PublicKey = v.FeedsManagerParts.PublicKey + retval.IsConnectionActive = v.FeedsManagerParts.IsConnectionActive + retval.CreatedAt = v.FeedsManagerParts.CreatedAt + return &retval, nil +} + +type UpdateJobProposalSpecDefinitionInput struct { + Definition string `json:"definition"` +} + +// GetDefinition returns UpdateJobProposalSpecDefinitionInput.Definition, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionInput) GetDefinition() string { return v.Definition } + +// UpdateJobProposalSpecDefinitionResponse is returned by UpdateJobProposalSpecDefinition on success. +type UpdateJobProposalSpecDefinitionResponse struct { + UpdateJobProposalSpecDefinition UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload `json:"-"` +} + +// GetUpdateJobProposalSpecDefinition returns UpdateJobProposalSpecDefinitionResponse.UpdateJobProposalSpecDefinition, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionResponse) GetUpdateJobProposalSpecDefinition() UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload { + return v.UpdateJobProposalSpecDefinition +} + +func (v *UpdateJobProposalSpecDefinitionResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *UpdateJobProposalSpecDefinitionResponse + UpdateJobProposalSpecDefinition json.RawMessage `json:"updateJobProposalSpecDefinition"` + graphql.NoUnmarshalJSON + } + firstPass.UpdateJobProposalSpecDefinitionResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.UpdateJobProposalSpecDefinition + src := firstPass.UpdateJobProposalSpecDefinition + if len(src) != 0 && string(src) != "null" { + err = __unmarshalUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal UpdateJobProposalSpecDefinitionResponse.UpdateJobProposalSpecDefinition: %w", err) + } + } + } + return nil +} + +type __premarshalUpdateJobProposalSpecDefinitionResponse struct { + UpdateJobProposalSpecDefinition json.RawMessage `json:"updateJobProposalSpecDefinition"` +} + +func (v *UpdateJobProposalSpecDefinitionResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *UpdateJobProposalSpecDefinitionResponse) __premarshalJSON() (*__premarshalUpdateJobProposalSpecDefinitionResponse, error) { + var retval __premarshalUpdateJobProposalSpecDefinitionResponse + + { + + dst := &retval.UpdateJobProposalSpecDefinition + src := v.UpdateJobProposalSpecDefinition + var err error + *dst, err = __marshalUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal UpdateJobProposalSpecDefinitionResponse.UpdateJobProposalSpecDefinition: %w", err) + } + } + return &retval, nil +} + +// UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError includes the requested fields of the GraphQL type NotFoundError. +type UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError.Typename, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError) GetTypename() string { + return v.Typename +} + +// GetMessage returns UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError.Message, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError) GetMessage() string { + return v.Message +} + +// GetCode returns UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError.Code, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError) GetCode() ErrorCode { + return v.Code +} + +// UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload includes the requested fields of the GraphQL interface UpdateJobProposalSpecDefinitionPayload. +// +// UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload is implemented by the following types: +// UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError +// UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccess +type UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload interface { + implementsGraphQLInterfaceUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError) implementsGraphQLInterfaceUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload() { +} +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccess) implementsGraphQLInterfaceUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload() { +} + +func __unmarshalUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload(b []byte, v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "NotFoundError": + *v = new(UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError) + return json.Unmarshal(b, *v) + case "UpdateJobProposalSpecDefinitionSuccess": + *v = new(UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccess) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing UpdateJobProposalSpecDefinitionPayload.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload: "%v"`, tn.TypeName) + } +} + +func __marshalUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload(v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError: + typename = "NotFoundError" + + result := struct { + TypeName string `json:"__typename"` + *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionNotFoundError + }{typename, v} + return json.Marshal(result) + case *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccess: + typename = "UpdateJobProposalSpecDefinitionSuccess" + + result := struct { + TypeName string `json:"__typename"` + *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccess + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionPayload: "%T"`, v) + } +} + +// UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccess includes the requested fields of the GraphQL type UpdateJobProposalSpecDefinitionSuccess. +type UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccess struct { + Typename string `json:"__typename"` + Spec UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec `json:"spec"` +} + +// GetTypename returns UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccess.Typename, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccess) GetTypename() string { + return v.Typename +} + +// GetSpec returns UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccess.Spec, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccess) GetSpec() UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec { + return v.Spec +} + +// UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec includes the requested fields of the GraphQL type JobProposalSpec. +type UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec struct { + Id string `json:"id"` + Definition string `json:"definition"` + Version int `json:"version"` + Status SpecStatus `json:"status"` + StatusUpdatedAt string `json:"statusUpdatedAt"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +} + +// GetId returns UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec.Id, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec) GetId() string { + return v.Id +} + +// GetDefinition returns UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec.Definition, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec) GetDefinition() string { + return v.Definition +} + +// GetVersion returns UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec.Version, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec) GetVersion() int { + return v.Version +} + +// GetStatus returns UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec.Status, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec) GetStatus() SpecStatus { + return v.Status +} + +// GetStatusUpdatedAt returns UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec.StatusUpdatedAt, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec) GetStatusUpdatedAt() string { + return v.StatusUpdatedAt +} + +// GetCreatedAt returns UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec.CreatedAt, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec) GetCreatedAt() string { + return v.CreatedAt +} + +// GetUpdatedAt returns UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec.UpdatedAt, and is useful for accessing the field via an interface. +func (v *UpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionUpdateJobProposalSpecDefinitionSuccessSpecJobProposalSpec) GetUpdatedAt() string { + return v.UpdatedAt +} + +// __ApproveJobProposalSpecInput is used internally by genqlient +type __ApproveJobProposalSpecInput struct { + Id string `json:"id"` + Force bool `json:"force"` +} + +// GetId returns __ApproveJobProposalSpecInput.Id, and is useful for accessing the field via an interface. +func (v *__ApproveJobProposalSpecInput) GetId() string { return v.Id } + +// GetForce returns __ApproveJobProposalSpecInput.Force, and is useful for accessing the field via an interface. +func (v *__ApproveJobProposalSpecInput) GetForce() bool { return v.Force } + +// __CancelJobProposalSpecInput is used internally by genqlient +type __CancelJobProposalSpecInput struct { + Id string `json:"id"` +} + +// GetId returns __CancelJobProposalSpecInput.Id, and is useful for accessing the field via an interface. +func (v *__CancelJobProposalSpecInput) GetId() string { return v.Id } + +// __CreateFeedsManagerInput is used internally by genqlient +type __CreateFeedsManagerInput struct { + Input CreateFeedsManagerInput `json:"input"` +} + +// GetInput returns __CreateFeedsManagerInput.Input, and is useful for accessing the field via an interface. +func (v *__CreateFeedsManagerInput) GetInput() CreateFeedsManagerInput { return v.Input } + +// __GetBridgeInput is used internally by genqlient +type __GetBridgeInput struct { + Id string `json:"id"` +} + +// GetId returns __GetBridgeInput.Id, and is useful for accessing the field via an interface. +func (v *__GetBridgeInput) GetId() string { return v.Id } + +// __GetFeedsManagerInput is used internally by genqlient +type __GetFeedsManagerInput struct { + Id string `json:"id"` +} + +// GetId returns __GetFeedsManagerInput.Id, and is useful for accessing the field via an interface. +func (v *__GetFeedsManagerInput) GetId() string { return v.Id } + +// __GetJobInput is used internally by genqlient +type __GetJobInput struct { + Id string `json:"id"` +} + +// GetId returns __GetJobInput.Id, and is useful for accessing the field via an interface. +func (v *__GetJobInput) GetId() string { return v.Id } + +// __GetJobProposalInput is used internally by genqlient +type __GetJobProposalInput struct { + Id string `json:"id"` +} + +// GetId returns __GetJobProposalInput.Id, and is useful for accessing the field via an interface. +func (v *__GetJobProposalInput) GetId() string { return v.Id } + +// __ListBridgesInput is used internally by genqlient +type __ListBridgesInput struct { + Offset int `json:"offset"` + Limit int `json:"limit"` +} + +// GetOffset returns __ListBridgesInput.Offset, and is useful for accessing the field via an interface. +func (v *__ListBridgesInput) GetOffset() int { return v.Offset } + +// GetLimit returns __ListBridgesInput.Limit, and is useful for accessing the field via an interface. +func (v *__ListBridgesInput) GetLimit() int { return v.Limit } + +// __ListJobsInput is used internally by genqlient +type __ListJobsInput struct { + Offset int `json:"offset"` + Limit int `json:"limit"` +} + +// GetOffset returns __ListJobsInput.Offset, and is useful for accessing the field via an interface. +func (v *__ListJobsInput) GetOffset() int { return v.Offset } + +// GetLimit returns __ListJobsInput.Limit, and is useful for accessing the field via an interface. +func (v *__ListJobsInput) GetLimit() int { return v.Limit } + +// __RejectJobProposalSpecInput is used internally by genqlient +type __RejectJobProposalSpecInput struct { + Id string `json:"id"` +} + +// GetId returns __RejectJobProposalSpecInput.Id, and is useful for accessing the field via an interface. +func (v *__RejectJobProposalSpecInput) GetId() string { return v.Id } + +// __UpdateFeedsManagerInput is used internally by genqlient +type __UpdateFeedsManagerInput struct { + Id string `json:"id"` + Input UpdateFeedsManagerInput `json:"input"` +} + +// GetId returns __UpdateFeedsManagerInput.Id, and is useful for accessing the field via an interface. +func (v *__UpdateFeedsManagerInput) GetId() string { return v.Id } + +// GetInput returns __UpdateFeedsManagerInput.Input, and is useful for accessing the field via an interface. +func (v *__UpdateFeedsManagerInput) GetInput() UpdateFeedsManagerInput { return v.Input } + +// __UpdateJobProposalSpecDefinitionInput is used internally by genqlient +type __UpdateJobProposalSpecDefinitionInput struct { + Id string `json:"id"` + Input UpdateJobProposalSpecDefinitionInput `json:"input"` +} + +// GetId returns __UpdateJobProposalSpecDefinitionInput.Id, and is useful for accessing the field via an interface. +func (v *__UpdateJobProposalSpecDefinitionInput) GetId() string { return v.Id } + +// GetInput returns __UpdateJobProposalSpecDefinitionInput.Input, and is useful for accessing the field via an interface. +func (v *__UpdateJobProposalSpecDefinitionInput) GetInput() UpdateJobProposalSpecDefinitionInput { + return v.Input +} + +// The query or mutation executed by ApproveJobProposalSpec. +const ApproveJobProposalSpec_Operation = ` +mutation ApproveJobProposalSpec ($id: ID!, $force: Boolean) { + approveJobProposalSpec(id: $id, force: $force) { + __typename + ... on ApproveJobProposalSpecSuccess { + spec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on JobAlreadyExistsError { + message + code + } + ... on NotFoundError { + message + code + } + } +} +` + +func ApproveJobProposalSpec( + ctx_ context.Context, + client_ graphql.Client, + id string, + force bool, +) (*ApproveJobProposalSpecResponse, error) { + req_ := &graphql.Request{ + OpName: "ApproveJobProposalSpec", + Query: ApproveJobProposalSpec_Operation, + Variables: &__ApproveJobProposalSpecInput{ + Id: id, + Force: force, + }, + } + var err_ error + + var data_ ApproveJobProposalSpecResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CancelJobProposalSpec. +const CancelJobProposalSpec_Operation = ` +mutation CancelJobProposalSpec ($id: ID!) { + cancelJobProposalSpec(id: $id) { + __typename + ... on CancelJobProposalSpecSuccess { + spec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on NotFoundError { + message + code + } + } +} +` + +func CancelJobProposalSpec( + ctx_ context.Context, + client_ graphql.Client, + id string, +) (*CancelJobProposalSpecResponse, error) { + req_ := &graphql.Request{ + OpName: "CancelJobProposalSpec", + Query: CancelJobProposalSpec_Operation, + Variables: &__CancelJobProposalSpecInput{ + Id: id, + }, + } + var err_ error + + var data_ CancelJobProposalSpecResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateFeedsManager. +const CreateFeedsManager_Operation = ` +mutation CreateFeedsManager ($input: CreateFeedsManagerInput!) { + createFeedsManager(input: $input) { + __typename + ... on CreateFeedsManagerSuccess { + feedsManager { + ... FeedsManagerParts + } + } + ... on SingleFeedsManagerError { + message + code + } + ... on NotFoundError { + message + code + } + ... on InputErrors { + errors { + message + code + path + } + } + } +} +fragment FeedsManagerParts on FeedsManager { + id + name + uri + publicKey + isConnectionActive + createdAt +} +` + +func CreateFeedsManager( + ctx_ context.Context, + client_ graphql.Client, + input CreateFeedsManagerInput, +) (*CreateFeedsManagerResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateFeedsManager", + Query: CreateFeedsManager_Operation, + Variables: &__CreateFeedsManagerInput{ + Input: input, + }, + } + var err_ error + + var data_ CreateFeedsManagerResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetBridge. +const GetBridge_Operation = ` +query GetBridge ($id: ID!) { + bridge(id: $id) { + __typename + ... BridgeParts + ... on NotFoundError { + message + code + } + } +} +fragment BridgeParts on Bridge { + id + name + url + confirmations + outgoingToken + minimumContractPayment + createdAt +} +` + +func GetBridge( + ctx_ context.Context, + client_ graphql.Client, + id string, +) (*GetBridgeResponse, error) { + req_ := &graphql.Request{ + OpName: "GetBridge", + Query: GetBridge_Operation, + Variables: &__GetBridgeInput{ + Id: id, + }, + } + var err_ error + + var data_ GetBridgeResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetCSAKeys. +const GetCSAKeys_Operation = ` +query GetCSAKeys { + csaKeys { + results { + id + publicKey + version + } + } +} +` + +func GetCSAKeys( + ctx_ context.Context, + client_ graphql.Client, +) (*GetCSAKeysResponse, error) { + req_ := &graphql.Request{ + OpName: "GetCSAKeys", + Query: GetCSAKeys_Operation, + } + var err_ error + + var data_ GetCSAKeysResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetFeedsManager. +const GetFeedsManager_Operation = ` +query GetFeedsManager ($id: ID!) { + feedsManager(id: $id) { + __typename + ... FeedsManagerParts + ... on NotFoundError { + message + code + } + } +} +fragment FeedsManagerParts on FeedsManager { + id + name + uri + publicKey + isConnectionActive + createdAt +} +` + +func GetFeedsManager( + ctx_ context.Context, + client_ graphql.Client, + id string, +) (*GetFeedsManagerResponse, error) { + req_ := &graphql.Request{ + OpName: "GetFeedsManager", + Query: GetFeedsManager_Operation, + Variables: &__GetFeedsManagerInput{ + Id: id, + }, + } + var err_ error + + var data_ GetFeedsManagerResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetJob. +const GetJob_Operation = ` +query GetJob ($id: ID!) { + job(id: $id) { + __typename + ... JobParts + ... on NotFoundError { + message + code + } + } +} +fragment JobParts on Job { + id + name + schemaVersion + gasLimit + forwardingAllowed + maxTaskDuration + externalJobID + type + spec { + __typename + ... on OCR2Spec { + ... OCR2Spec + } + } + observationSource + errors { + id + description + occurrences + createdAt + updatedAt + } +} +fragment OCR2Spec on OCR2Spec { + blockchainTimeout + contractID + contractConfigConfirmations + contractConfigTrackerPollInterval + createdAt + ocrKeyBundleID + monitoringEndpoint + p2pv2Bootstrappers + relay + relayConfig + transmitterID + pluginType + pluginConfig +} +` + +func GetJob( + ctx_ context.Context, + client_ graphql.Client, + id string, +) (*GetJobResponse, error) { + req_ := &graphql.Request{ + OpName: "GetJob", + Query: GetJob_Operation, + Variables: &__GetJobInput{ + Id: id, + }, + } + var err_ error + + var data_ GetJobResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetJobProposal. +const GetJobProposal_Operation = ` +query GetJobProposal ($id: ID!) { + jobProposal(id: $id) { + __typename + ... on JobProposal { + id + name + status + remoteUUID + externalJobID + jobID + feedsManager { + ... FeedsManagerParts + } + multiAddrs + pendingUpdate + specs { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + latestSpec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on NotFoundError { + message + code + } + } +} +fragment FeedsManagerParts on FeedsManager { + id + name + uri + publicKey + isConnectionActive + createdAt +} +` + +func GetJobProposal( + ctx_ context.Context, + client_ graphql.Client, + id string, +) (*GetJobProposalResponse, error) { + req_ := &graphql.Request{ + OpName: "GetJobProposal", + Query: GetJobProposal_Operation, + Variables: &__GetJobProposalInput{ + Id: id, + }, + } + var err_ error + + var data_ GetJobProposalResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by ListBridges. +const ListBridges_Operation = ` +query ListBridges ($offset: Int, $limit: Int) { + bridges(offset: $offset, limit: $limit) { + results { + ... BridgeParts + } + metadata { + total + } + } +} +fragment BridgeParts on Bridge { + id + name + url + confirmations + outgoingToken + minimumContractPayment + createdAt +} +` + +func ListBridges( + ctx_ context.Context, + client_ graphql.Client, + offset int, + limit int, +) (*ListBridgesResponse, error) { + req_ := &graphql.Request{ + OpName: "ListBridges", + Query: ListBridges_Operation, + Variables: &__ListBridgesInput{ + Offset: offset, + Limit: limit, + }, + } + var err_ error + + var data_ ListBridgesResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by ListFeedsManagers. +const ListFeedsManagers_Operation = ` +query ListFeedsManagers { + feedsManagers { + results { + ... FeedsManagerParts + } + } +} +fragment FeedsManagerParts on FeedsManager { + id + name + uri + publicKey + isConnectionActive + createdAt +} +` + +func ListFeedsManagers( + ctx_ context.Context, + client_ graphql.Client, +) (*ListFeedsManagersResponse, error) { + req_ := &graphql.Request{ + OpName: "ListFeedsManagers", + Query: ListFeedsManagers_Operation, + } + var err_ error + + var data_ ListFeedsManagersResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by ListJobs. +const ListJobs_Operation = ` +query ListJobs ($offset: Int, $limit: Int) { + jobs(offset: $offset, limit: $limit) { + results { + ... JobParts + } + metadata { + total + } + } +} +fragment JobParts on Job { + id + name + schemaVersion + gasLimit + forwardingAllowed + maxTaskDuration + externalJobID + type + spec { + __typename + ... on OCR2Spec { + ... OCR2Spec + } + } + observationSource + errors { + id + description + occurrences + createdAt + updatedAt + } +} +fragment OCR2Spec on OCR2Spec { + blockchainTimeout + contractID + contractConfigConfirmations + contractConfigTrackerPollInterval + createdAt + ocrKeyBundleID + monitoringEndpoint + p2pv2Bootstrappers + relay + relayConfig + transmitterID + pluginType + pluginConfig +} +` + +func ListJobs( + ctx_ context.Context, + client_ graphql.Client, + offset int, + limit int, +) (*ListJobsResponse, error) { + req_ := &graphql.Request{ + OpName: "ListJobs", + Query: ListJobs_Operation, + Variables: &__ListJobsInput{ + Offset: offset, + Limit: limit, + }, + } + var err_ error + + var data_ ListJobsResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by RejectJobProposalSpec. +const RejectJobProposalSpec_Operation = ` +mutation RejectJobProposalSpec ($id: ID!) { + rejectJobProposalSpec(id: $id) { + __typename + ... on RejectJobProposalSpecSuccess { + spec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on NotFoundError { + message + code + } + } +} +` + +func RejectJobProposalSpec( + ctx_ context.Context, + client_ graphql.Client, + id string, +) (*RejectJobProposalSpecResponse, error) { + req_ := &graphql.Request{ + OpName: "RejectJobProposalSpec", + Query: RejectJobProposalSpec_Operation, + Variables: &__RejectJobProposalSpecInput{ + Id: id, + }, + } + var err_ error + + var data_ RejectJobProposalSpecResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateFeedsManager. +const UpdateFeedsManager_Operation = ` +mutation UpdateFeedsManager ($id: ID!, $input: UpdateFeedsManagerInput!) { + updateFeedsManager(id: $id, input: $input) { + __typename + ... on UpdateFeedsManagerSuccess { + feedsManager { + ... FeedsManagerParts + } + } + ... on NotFoundError { + message + code + } + ... on InputErrors { + errors { + message + code + path + } + } + } +} +fragment FeedsManagerParts on FeedsManager { + id + name + uri + publicKey + isConnectionActive + createdAt +} +` + +func UpdateFeedsManager( + ctx_ context.Context, + client_ graphql.Client, + id string, + input UpdateFeedsManagerInput, +) (*UpdateFeedsManagerResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateFeedsManager", + Query: UpdateFeedsManager_Operation, + Variables: &__UpdateFeedsManagerInput{ + Id: id, + Input: input, + }, + } + var err_ error + + var data_ UpdateFeedsManagerResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateJobProposalSpecDefinition. +const UpdateJobProposalSpecDefinition_Operation = ` +mutation UpdateJobProposalSpecDefinition ($id: ID!, $input: UpdateJobProposalSpecDefinitionInput!) { + updateJobProposalSpecDefinition(id: $id, input: $input) { + __typename + ... on UpdateJobProposalSpecDefinitionSuccess { + spec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on NotFoundError { + message + code + } + } +} +` + +func UpdateJobProposalSpecDefinition( + ctx_ context.Context, + client_ graphql.Client, + id string, + input UpdateJobProposalSpecDefinitionInput, +) (*UpdateJobProposalSpecDefinitionResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateJobProposalSpecDefinition", + Query: UpdateJobProposalSpecDefinition_Operation, + Variables: &__UpdateJobProposalSpecDefinitionInput{ + Id: id, + Input: input, + }, + } + var err_ error + + var data_ UpdateJobProposalSpecDefinitionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} diff --git a/integration-tests/web/sdk/internal/genqlient.graphql b/integration-tests/web/sdk/internal/genqlient.graphql new file mode 100644 index 0000000000..f9e8fc1843 --- /dev/null +++ b/integration-tests/web/sdk/internal/genqlient.graphql @@ -0,0 +1,320 @@ +##################### +# CSA Keys +##################### + +query GetCSAKeys { + csaKeys { + results { + id + publicKey + version + } + } +} + +##################### +# Jobs and Job Proposals +##################### +fragment OCR2Spec on OCR2Spec { + blockchainTimeout + contractID + contractConfigConfirmations + contractConfigTrackerPollInterval + createdAt + ocrKeyBundleID + monitoringEndpoint + p2pv2Bootstrappers + relay + relayConfig + transmitterID + pluginType + pluginConfig +} + +fragment JobParts on Job { + id + name + schemaVersion + gasLimit + forwardingAllowed + maxTaskDuration + externalJobID + type + spec { + ... on OCR2Spec { + ...OCR2Spec + } + } + observationSource + errors { + id + description + occurrences + createdAt + updatedAt + } +} + +query GetJob($id: ID!) { + job(id: $id) { + ...JobParts + ... on NotFoundError { + message + code + } + } +} + +query ListJobs($offset: Int, $limit: Int) { + jobs(offset: $offset, limit: $limit) { + results { + ...JobParts + } + metadata { + total + } + } +} + +query GetJobProposal($id: ID!) { + jobProposal(id: $id) { + ... on JobProposal { + id + name + status + remoteUUID + externalJobID + jobID + feedsManager { + ...FeedsManagerParts + } + multiAddrs + pendingUpdate + specs { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + latestSpec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on NotFoundError { + message + code + } + } +} + +##################### +# Bridges +##################### + +fragment BridgeParts on Bridge { + id + name + url + confirmations + outgoingToken + minimumContractPayment + createdAt +} + +query ListBridges($offset: Int, $limit: Int) { + bridges(offset: $offset, limit: $limit) { + results { + ...BridgeParts + } + metadata { + total + } + } +} + +query GetBridge($id: ID!) { + bridge(id: $id) { + ...BridgeParts + ... on NotFoundError { + message + code + } + } +} + +##################### +# Feeds Manager +##################### + +fragment FeedsManagerParts on FeedsManager { + id + name + uri + publicKey + isConnectionActive + createdAt +} + +query GetFeedsManager($id: ID!) { + feedsManager(id: $id) { + ...FeedsManagerParts + ... on NotFoundError { + message + code + } + } +} + +query ListFeedsManagers { + feedsManagers { + results { + ...FeedsManagerParts + } + } +} + +mutation CreateFeedsManager($input: CreateFeedsManagerInput!) { + createFeedsManager(input: $input) { + ... on CreateFeedsManagerSuccess { + feedsManager { + ...FeedsManagerParts + } + } + ... on SingleFeedsManagerError { + message + code + } + ... on NotFoundError { + message + code + } + ... on InputErrors { + errors { + message + code + path + } + } + } +} + +mutation UpdateFeedsManager($id: ID!, $input: UpdateFeedsManagerInput!) { + updateFeedsManager(id: $id, input: $input) { + ... on UpdateFeedsManagerSuccess { + feedsManager { + ...FeedsManagerParts + } + } + ... on NotFoundError { + message + code + } + ... on InputErrors { + errors { + message + code + path + } + } + } +} + +##################### +# Job Proposals +##################### + +mutation ApproveJobProposalSpec($id: ID!, $force: Boolean) { + approveJobProposalSpec(id: $id, force: $force) { + ... on ApproveJobProposalSpecSuccess { + spec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on JobAlreadyExistsError { + message + code + } + ... on NotFoundError { + message + code + } + } +} + +mutation CancelJobProposalSpec($id: ID!) { + cancelJobProposalSpec(id: $id) { + ... on CancelJobProposalSpecSuccess { + spec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on NotFoundError { + message + code + } + } +} + +mutation RejectJobProposalSpec($id: ID!) { + rejectJobProposalSpec(id: $id) { + ... on RejectJobProposalSpecSuccess { + spec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on NotFoundError { + message + code + } + } +} + +mutation UpdateJobProposalSpecDefinition( + $id: ID! + $input: UpdateJobProposalSpecDefinitionInput! +) { + updateJobProposalSpecDefinition(id: $id, input: $input) { + ... on UpdateJobProposalSpecDefinitionSuccess { + spec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on NotFoundError { + message + code + } + } +} diff --git a/integration-tests/web/sdk/internal/schema.graphql b/integration-tests/web/sdk/internal/schema.graphql new file mode 100644 index 0000000000..64b7e479ab --- /dev/null +++ b/integration-tests/web/sdk/internal/schema.graphql @@ -0,0 +1,1045 @@ +scalar Time +scalar Map +scalar Bytes + +schema { + query: Query + mutation: Mutation +} + +type Query { + bridge(id: ID!): BridgePayload! + bridges(offset: Int, limit: Int): BridgesPayload! + chain(id: ID!): ChainPayload! + chains(offset: Int, limit: Int): ChainsPayload! + configv2: ConfigV2Payload! + csaKeys: CSAKeysPayload! + ethKeys: EthKeysPayload! + ethTransaction(hash: ID!): EthTransactionPayload! + ethTransactions(offset: Int, limit: Int): EthTransactionsPayload! + ethTransactionsAttempts(offset: Int, limit: Int): EthTransactionAttemptsPayload! + features: FeaturesPayload! + feedsManager(id: ID!): FeedsManagerPayload! + feedsManagers: FeedsManagersPayload! + globalLogLevel: GlobalLogLevelPayload! + job(id: ID!): JobPayload! + jobs(offset: Int, limit: Int): JobsPayload! + jobProposal(id: ID!): JobProposalPayload! + jobRun(id: ID!): JobRunPayload! + jobRuns(offset: Int, limit: Int): JobRunsPayload! + node(id: ID!): NodePayload! + nodes(offset: Int, limit: Int): NodesPayload! + ocrKeyBundles: OCRKeyBundlesPayload! + ocr2KeyBundles: OCR2KeyBundlesPayload! + p2pKeys: P2PKeysPayload! + solanaKeys: SolanaKeysPayload! + sqlLogging: GetSQLLoggingPayload! + vrfKey(id: ID!): VRFKeyPayload! + vrfKeys: VRFKeysPayload! +} + +type Mutation { + approveJobProposalSpec(id: ID!, force: Boolean): ApproveJobProposalSpecPayload! + cancelJobProposalSpec(id: ID!): CancelJobProposalSpecPayload! + createAPIToken(input: CreateAPITokenInput!): CreateAPITokenPayload! + createBridge(input: CreateBridgeInput!): CreateBridgePayload! + createCSAKey: CreateCSAKeyPayload! + createFeedsManager(input: CreateFeedsManagerInput!): CreateFeedsManagerPayload! + createFeedsManagerChainConfig(input: CreateFeedsManagerChainConfigInput!): CreateFeedsManagerChainConfigPayload! + createJob(input: CreateJobInput!): CreateJobPayload! + createOCRKeyBundle: CreateOCRKeyBundlePayload! + createOCR2KeyBundle(chainType: OCR2ChainType!): CreateOCR2KeyBundlePayload! + createP2PKey: CreateP2PKeyPayload! + deleteAPIToken(input: DeleteAPITokenInput!): DeleteAPITokenPayload! + deleteBridge(id: ID!): DeleteBridgePayload! + deleteCSAKey(id: ID!): DeleteCSAKeyPayload! + deleteFeedsManagerChainConfig(id: ID!): DeleteFeedsManagerChainConfigPayload! + deleteJob(id: ID!): DeleteJobPayload! + deleteOCRKeyBundle(id: ID!): DeleteOCRKeyBundlePayload! + deleteOCR2KeyBundle(id: ID!): DeleteOCR2KeyBundlePayload! + deleteP2PKey(id: ID!): DeleteP2PKeyPayload! + createVRFKey: CreateVRFKeyPayload! + deleteVRFKey(id: ID!): DeleteVRFKeyPayload! + dismissJobError(id: ID!): DismissJobErrorPayload! + rejectJobProposalSpec(id: ID!): RejectJobProposalSpecPayload! + runJob(id: ID!): RunJobPayload! + setGlobalLogLevel(level: LogLevel!): SetGlobalLogLevelPayload! + setSQLLogging(input: SetSQLLoggingInput!): SetSQLLoggingPayload! + updateBridge(id: ID!, input: UpdateBridgeInput!): UpdateBridgePayload! + updateFeedsManager(id: ID!, input: UpdateFeedsManagerInput!): UpdateFeedsManagerPayload! + updateFeedsManagerChainConfig(id: ID!, input: UpdateFeedsManagerChainConfigInput!): UpdateFeedsManagerChainConfigPayload! + updateJobProposalSpecDefinition(id: ID!, input: UpdateJobProposalSpecDefinitionInput!): UpdateJobProposalSpecDefinitionPayload! + updateUserPassword(input: UpdatePasswordInput!): UpdatePasswordPayload! +} +type APIToken { + accessKey: String! + secret: String! +} + +input CreateAPITokenInput { + password: String! +} + +type CreateAPITokenSuccess { + token: APIToken! +} + +union CreateAPITokenPayload = CreateAPITokenSuccess | InputErrors + +input DeleteAPITokenInput { + password: String! +} + +type DeleteAPITokenResult { + accessKey: String! +} + +type DeleteAPITokenSuccess { + token: DeleteAPITokenResult! +} + +union DeleteAPITokenPayload = DeleteAPITokenSuccess | InputErrors +type Bridge { + id: ID! + name: String! + url: String! + confirmations: Int! + outgoingToken: String! + minimumContractPayment: String! + createdAt: Time! +} + +# BridgePayload defines the response to fetch a single bridge by name +union BridgePayload = Bridge | NotFoundError + +# BridgesPayload defines the response when fetching a page of bridges +type BridgesPayload implements PaginatedPayload { + results: [Bridge!]! + metadata: PaginationMetadata! +} + +# CreateBridgeInput defines the input to create a bridge +input CreateBridgeInput { + name: String! + url: String! + confirmations: Int! + minimumContractPayment: String! +} + +# CreateBridgeSuccess defines the success response when creating a bridge +type CreateBridgeSuccess { + bridge: Bridge! + incomingToken: String! +} + +# CreateBridgeInput defines the response when creating a bridge +union CreateBridgePayload = CreateBridgeSuccess + +# UpdateBridgeInput defines the input to update a bridge +input UpdateBridgeInput { + name: String! + url: String! + confirmations: Int! + minimumContractPayment: String! +} + +# UpdateBridgeSuccess defines the success response when updating a bridge +type UpdateBridgeSuccess { + bridge: Bridge! +} + +# CreateBridgeInput defines the response when updating a bridge +union UpdateBridgePayload = UpdateBridgeSuccess | NotFoundError + +type DeleteBridgeSuccess { + bridge: Bridge! +} + +type DeleteBridgeInvalidNameError implements Error { + code: ErrorCode! + message: String! +} + +type DeleteBridgeConflictError implements Error { + code: ErrorCode! + message: String! +} + +union DeleteBridgePayload = DeleteBridgeSuccess + | DeleteBridgeInvalidNameError + | DeleteBridgeConflictError + | NotFoundError +type Chain { + id: ID! + enabled: Boolean! + config: String! +} + +union ChainPayload = Chain | NotFoundError + +type ChainsPayload implements PaginatedPayload { + results: [Chain!]! + metadata: PaginationMetadata! +} +type ConfigV2Payload { + user: String! + effective: String! +} +type CSAKey { + id: ID! + publicKey: String! + version: Int! +} + +type CSAKeysPayload { + results: [CSAKey!]! +} + +type CreateCSAKeySuccess { + csaKey: CSAKey! +} + +type CSAKeyExistsError implements Error { + message: String! + code: ErrorCode! +} + +union CreateCSAKeyPayload = CreateCSAKeySuccess | CSAKeyExistsError + +type DeleteCSAKeySuccess { + csaKey: CSAKey! +} + +union DeleteCSAKeyPayload = DeleteCSAKeySuccess | NotFoundError +enum ErrorCode { + NOT_FOUND + INVALID_INPUT + UNPROCESSABLE +} + +interface Error { + message: String! + code: ErrorCode! +} + +type NotFoundError implements Error { + message: String! + code: ErrorCode! +} + +type InputError implements Error { + message: String! + code: ErrorCode! + path: String! + } + +type InputErrors { + errors: [InputError!]! +} +type EthKey { + address: String! + isDisabled: Boolean! + createdAt: Time! + updatedAt: Time! + chain: Chain! + ethBalance: String + linkBalance: String + maxGasPriceWei: String +} + +type EthKeysPayload { + results: [EthKey!]! +} +type EthTransaction { + state: String! + data: Bytes! + from: String! + to: String! + gasLimit: String! + value: String! + evmChainID: ID! + nonce: String + gasPrice: String! + hash: String! + hex: String! + sentAt: String + chain: Chain! + attempts: [EthTransactionAttempt!]! +} + +union EthTransactionPayload = EthTransaction | NotFoundError + +type EthTransactionsPayload implements PaginatedPayload { + results: [EthTransaction!]! + metadata: PaginationMetadata! +} +type EthTransactionAttempt { + gasPrice: String! + hash: String! + hex: String! + sentAt: String +} + +type EthTransactionAttemptsPayload implements PaginatedPayload { + results: [EthTransactionAttempt!]! + metadata: PaginationMetadata! +} +type Features { + csa: Boolean! + feedsManager: Boolean! +} + +# FeaturesPayload defines the response of fetching the features availability in the UI +union FeaturesPayload = Features +enum JobType { + FLUX_MONITOR + OCR + OCR2 +} + +type Plugins { + commit: Boolean! + execute: Boolean! + median: Boolean! + mercury: Boolean! + rebalancer: Boolean! +} + +type FeedsManager { + id: ID! + name: String! + uri: String! + publicKey: String! + jobProposals: [JobProposal!]! + isConnectionActive: Boolean! + createdAt: Time! + chainConfigs: [FeedsManagerChainConfig!]! +} + +type FeedsManagerChainConfig { + id: ID! + chainID: String! + chainType: String! + accountAddr: String! + accountAddrPubKey: String + adminAddr: String! + fluxMonitorJobConfig: FluxMonitorJobConfig! + ocr1JobConfig: OCR1JobConfig! + ocr2JobConfig: OCR2JobConfig! +} + +type FluxMonitorJobConfig { + enabled: Boolean! +} + +type OCR1JobConfig { + enabled: Boolean! + isBootstrap: Boolean! + multiaddr: String + p2pPeerID: String + keyBundleID: String +} + +type OCR2JobConfig { + enabled: Boolean! + isBootstrap: Boolean! + multiaddr: String + forwarderAddress: String + p2pPeerID: String + keyBundleID: String + plugins: Plugins! +} + +# FeedsManagerPayload defines the response to fetch a single feeds manager by id +union FeedsManagerPayload = FeedsManager | NotFoundError + +# FeedsManagersPayload defines the response when fetching feeds managers +type FeedsManagersPayload { + results: [FeedsManager!]! +} + +input CreateFeedsManagerInput { + name: String! + uri: String! + publicKey: String! +} + +# CreateFeedsManagerSuccess defines the success response when creating a feeds +# manager +type CreateFeedsManagerSuccess { + feedsManager: FeedsManager! +} + +type SingleFeedsManagerError implements Error { + message: String! + code: ErrorCode! +} + +# CreateFeedsManagerPayload defines the response when creating a feeds manager +union CreateFeedsManagerPayload = CreateFeedsManagerSuccess + | SingleFeedsManagerError + | NotFoundError + | InputErrors + +input UpdateFeedsManagerInput { + name: String! + uri: String! + publicKey: String! +} + +# UpdateFeedsManagerSuccess defines the success response when updating a feeds +# manager +type UpdateFeedsManagerSuccess { + feedsManager: FeedsManager! +} + +# UpdateFeedsManagerPayload defines the response when updating a feeds manager +union UpdateFeedsManagerPayload = UpdateFeedsManagerSuccess + | NotFoundError + | InputErrors + +input CreateFeedsManagerChainConfigInput { + feedsManagerID: ID! + chainID: String! + chainType: String! + accountAddr: String! + accountAddrPubKey: String + adminAddr: String! + fluxMonitorEnabled: Boolean! + ocr1Enabled: Boolean! + ocr1IsBootstrap: Boolean + ocr1Multiaddr: String + ocr1P2PPeerID: String + ocr1KeyBundleID: String + ocr2Enabled: Boolean! + ocr2IsBootstrap: Boolean + ocr2Multiaddr: String + ocr2ForwarderAddress: String + ocr2P2PPeerID: String + ocr2KeyBundleID: String + ocr2Plugins: String! +} + +# CreateFeedsManagerChainConfigSuccess defines the success response when +# creating a chain config for a feeds manager. +type CreateFeedsManagerChainConfigSuccess { + chainConfig: FeedsManagerChainConfig! +} + +# CreateFeedsManagerChainConfigPayload defines the response when creating a +# feeds manager chain config. +union CreateFeedsManagerChainConfigPayload = CreateFeedsManagerChainConfigSuccess + | NotFoundError + | InputErrors + +# DeleteFeedsManagerChainConfigSuccess defines the success response when +# deleting a chain config for a feeds manager. +type DeleteFeedsManagerChainConfigSuccess { + chainConfig: FeedsManagerChainConfig! +} + +# DeleteFeedsManagerChainConfigPayload defines the response when creating a +# feeds manager chain config. +union DeleteFeedsManagerChainConfigPayload = DeleteFeedsManagerChainConfigSuccess + | NotFoundError + +input UpdateFeedsManagerChainConfigInput { + accountAddr: String! + accountAddrPubKey: String + adminAddr: String! + fluxMonitorEnabled: Boolean! + ocr1Enabled: Boolean! + ocr1IsBootstrap: Boolean + ocr1Multiaddr: String + ocr1P2PPeerID: String + ocr1KeyBundleID: String + ocr2Enabled: Boolean! + ocr2IsBootstrap: Boolean + ocr2Multiaddr: String + ocr2ForwarderAddress: String + ocr2P2PPeerID: String + ocr2KeyBundleID: String + ocr2Plugins: String! +} + +# UpdateFeedsManagerChainConfigSuccess defines the success response when +# updating a chain config for a feeds manager. +type UpdateFeedsManagerChainConfigSuccess { + chainConfig: FeedsManagerChainConfig! +} + +# UpdateFeedsManagerChainConfigPayload defines the response when updating a +# feeds manager chain config. +union UpdateFeedsManagerChainConfigPayload = UpdateFeedsManagerChainConfigSuccess + | NotFoundError + | InputErrors +type Job { + id: ID! + name: String! + schemaVersion: Int! + gasLimit: Int + forwardingAllowed: Boolean + maxTaskDuration: String! + externalJobID: String! + type: String! + spec: JobSpec! + runs(offset: Int, limit: Int): JobRunsPayload! + observationSource: String! + errors: [JobError!]! + createdAt: Time! +} + +# JobsPayload defines the response when fetching a page of jobs +type JobsPayload implements PaginatedPayload { + results: [Job!]! + metadata: PaginationMetadata! +} + +# JobPayload defines the response when a job +union JobPayload = Job | NotFoundError + +input CreateJobInput { + TOML: String! +} + +type CreateJobSuccess { + job: Job! +} + +union CreateJobPayload = CreateJobSuccess | InputErrors + +type DeleteJobSuccess { + job: Job! +} + +union DeleteJobPayload = DeleteJobSuccess | NotFoundError +type JobError { + id: ID! + description: String! + occurrences: Int! + createdAt: Time! + updatedAt: Time! +} + +type DismissJobErrorSuccess { + jobError: JobError! +} + +union DismissJobErrorPayload = DismissJobErrorSuccess | NotFoundError +enum JobProposalStatus { + PENDING + APPROVED + REJECTED + CANCELLED + DELETED + REVOKED +} + +type JobProposal { + id: ID! + name: String + status: JobProposalStatus! + remoteUUID: String! + externalJobID: String + jobID: String + feedsManager: FeedsManager! + multiAddrs: [String!]! + pendingUpdate: Boolean! + specs: [JobProposalSpec!]! + latestSpec: JobProposalSpec! +} + +union JobProposalPayload = JobProposal | NotFoundError +enum SpecStatus { + UNKNOWN + PENDING + APPROVED + REJECTED + CANCELLED + REVOKED +} + +type JobProposalSpec { + id: ID! + definition: String! + version: Int! + status: SpecStatus! + statusUpdatedAt: Time! + createdAt: Time! + updatedAt: Time! +} + +type JobAlreadyExistsError implements Error { + message: String! + code: ErrorCode! +} + + +# ApproveJobProposalSpec + +type ApproveJobProposalSpecSuccess { + spec: JobProposalSpec! +} + +union ApproveJobProposalSpecPayload = ApproveJobProposalSpecSuccess | NotFoundError | JobAlreadyExistsError + +# CancelJobProposalSpec + +type CancelJobProposalSpecSuccess { + spec: JobProposalSpec! +} + +union CancelJobProposalSpecPayload = CancelJobProposalSpecSuccess | NotFoundError + + +# RejectJobProposalSpec + +type RejectJobProposalSpecSuccess { + spec: JobProposalSpec! +} + +union RejectJobProposalSpecPayload = RejectJobProposalSpecSuccess | NotFoundError + +# UpdateJobProposalSpec + +input UpdateJobProposalSpecDefinitionInput { + definition: String! +} + +type UpdateJobProposalSpecDefinitionSuccess { + spec: JobProposalSpec! +} + +union UpdateJobProposalSpecDefinitionPayload = UpdateJobProposalSpecDefinitionSuccess | NotFoundError +enum JobRunStatus { + UNKNOWN + RUNNING + SUSPENDED + ERRORED + COMPLETED +} + +type JobRun { + id: ID! + outputs: [String]! + allErrors: [String!]! + fatalErrors: [String!]! + inputs: String! + createdAt: Time! + finishedAt: Time + taskRuns: [TaskRun!]! + status: JobRunStatus! + job: Job! +} + +# JobRunsPayload defines the response when fetching a page of runs +type JobRunsPayload implements PaginatedPayload { + results: [JobRun!]! + metadata: PaginationMetadata! +} + +union JobRunPayload = JobRun | NotFoundError + +type RunJobSuccess { + jobRun: JobRun! +} + +type RunJobCannotRunError implements Error { + message: String! + code: ErrorCode! +} + +union RunJobPayload = RunJobSuccess | NotFoundError | RunJobCannotRunError +enum LogLevel { + DEBUG + INFO + WARN + ERROR +} + +type GlobalLogLevel { + level: LogLevel! +} + +union GlobalLogLevelPayload = GlobalLogLevel + +type LogLevelConfig { + keeper: LogLevel + headTracker: LogLevel + fluxMonitor: LogLevel +} + +input LogLevelConfigInput { + keeper: LogLevel + headTracker: LogLevel + fluxMonitor: LogLevel +} + +input SetServicesLogLevelsInput { + config: LogLevelConfigInput! +} + +type SetServicesLogLevelsSuccess { + config: LogLevelConfig! +} + +union SetServicesLogLevelsPayload = SetServicesLogLevelsSuccess | InputErrors + +type SQLLogging { + enabled: Boolean! +} + +input SetSQLLoggingInput { + enabled: Boolean! +} + +type SetSQLLoggingSuccess { + sqlLogging: SQLLogging! +} + +union SetSQLLoggingPayload = SetSQLLoggingSuccess + +union GetSQLLoggingPayload = SQLLogging + +type SetGlobalLogLevelSuccess { + globalLogLevel: GlobalLogLevel! +} + +union SetGlobalLogLevelPayload = SetGlobalLogLevelSuccess | InputErrors +type Node { + id: ID! + name: String! + wsURL: String! + httpURL: String! + chain: Chain! + state: String! + sendOnly: Boolean! + order: Int +} + +union NodePayload = Node | NotFoundError + +type NodesPayload implements PaginatedPayload { + results: [Node!]! + metadata: PaginationMetadata! +} +type OCRKeyBundle { + id: ID! + configPublicKey: String! + offChainPublicKey: String! + onChainSigningAddress: String! +} + +type OCRKeyBundlesPayload { + results: [OCRKeyBundle!]! +} + +type CreateOCRKeyBundleSuccess { + bundle: OCRKeyBundle! +} + +union CreateOCRKeyBundlePayload = CreateOCRKeyBundleSuccess + +type DeleteOCRKeyBundleSuccess { + bundle: OCRKeyBundle! +} + +union DeleteOCRKeyBundlePayload = DeleteOCRKeyBundleSuccess | NotFoundError +enum OCR2ChainType { + EVM + COSMOS + SOLANA + STARKNET + APTOS +} + +type OCR2KeyBundle { + id: ID! + chainType: OCR2ChainType + configPublicKey: String! + onChainPublicKey: String! + offChainPublicKey: String! +} + +type OCR2KeyBundlesPayload { + results: [OCR2KeyBundle!]! +} + +type CreateOCR2KeyBundleSuccess { + bundle: OCR2KeyBundle! +} + +union CreateOCR2KeyBundlePayload = CreateOCR2KeyBundleSuccess + +type DeleteOCR2KeyBundleSuccess { + bundle: OCR2KeyBundle! +} + +union DeleteOCR2KeyBundlePayload = DeleteOCR2KeyBundleSuccess | NotFoundError +type P2PKey { + id: ID! + peerID: String! + publicKey: String! +} + +type P2PKeysPayload { + results: [P2PKey!]! +} + +type CreateP2PKeySuccess { + p2pKey: P2PKey! +} + +union CreateP2PKeyPayload = CreateP2PKeySuccess + + +type DeleteP2PKeySuccess { + p2pKey: P2PKey! +} + +union DeleteP2PKeyPayload = DeleteP2PKeySuccess | NotFoundError +type PaginationMetadata { + total: Int! +} + +interface PaginatedPayload { + metadata: PaginationMetadata! +} +type SolanaKey { + id: ID! +} + +type SolanaKeysPayload { + results: [SolanaKey!]! +} +union JobSpec = + CronSpec | + DirectRequestSpec | + KeeperSpec | + FluxMonitorSpec | + OCRSpec | + OCR2Spec | + VRFSpec | + WebhookSpec | + BlockhashStoreSpec | + BlockHeaderFeederSpec | + BootstrapSpec | + GatewaySpec | + WorkflowSpec | + StandardCapabilitiesSpec + +type CronSpec { + schedule: String! + evmChainID: String + createdAt: Time! +} + +type DirectRequestSpec { + contractAddress: String! + createdAt: Time! + evmChainID: String + minIncomingConfirmations: Int! + minContractPaymentLinkJuels: String! + requesters: [String!] +} + +type FluxMonitorSpec { + absoluteThreshold: Float! + contractAddress: String! + createdAt: Time! + drumbeatEnabled: Boolean! + drumbeatRandomDelay: String + drumbeatSchedule: String + evmChainID: String + idleTimerDisabled: Boolean! + idleTimerPeriod: String! + minPayment: String + pollTimerDisabled: Boolean! + pollTimerPeriod: String! + threshold: Float! +} + +type KeeperSpec { + contractAddress: String! + createdAt: Time! + evmChainID: String + fromAddress: String +} + +type OCRSpec { + blockchainTimeout: String + contractAddress: String! + contractConfigConfirmations: Int + contractConfigTrackerPollInterval: String + contractConfigTrackerSubscribeInterval: String + createdAt: Time! + evmChainID: String + isBootstrapPeer: Boolean! + keyBundleID: String + observationTimeout: String + p2pv2Bootstrappers: [String!] + transmitterAddress: String + databaseTimeout: String! + observationGracePeriod: String! + contractTransmitterTransmitTimeout: String! +} + +type OCR2Spec { + blockchainTimeout: String + contractID: String! + contractConfigConfirmations: Int + contractConfigTrackerPollInterval: String + createdAt: Time! + ocrKeyBundleID: String + monitoringEndpoint: String + p2pv2Bootstrappers: [String!] + relay: String! + relayConfig: Map! + transmitterID: String + pluginType: String! + pluginConfig: Map! + feedID: String +} + +type VRFSpec { + coordinatorAddress: String! + createdAt: Time! + evmChainID: String + fromAddresses: [String!] + minIncomingConfirmations: Int! + pollPeriod: String! + publicKey: String! + requestedConfsDelay: Int! + requestTimeout: String! + batchCoordinatorAddress: String + batchFulfillmentEnabled: Boolean! + batchFulfillmentGasMultiplier: Float! + customRevertsPipelineEnabled: Boolean + chunkSize: Int! + backoffInitialDelay: String! + backoffMaxDelay: String! + gasLanePrice: String + vrfOwnerAddress: String +} + +type WebhookSpec { + createdAt: Time! +} + +type BlockhashStoreSpec { + coordinatorV1Address: String + coordinatorV2Address: String + coordinatorV2PlusAddress: String + waitBlocks: Int! + lookbackBlocks: Int! + blockhashStoreAddress: String! + trustedBlockhashStoreAddress: String + trustedBlockhashStoreBatchSize: Int! + heartbeatPeriod: String! + pollPeriod: String! + runTimeout: String! + evmChainID: String + fromAddresses: [String!] + createdAt: Time! +} + +type BlockHeaderFeederSpec { + coordinatorV1Address: String + coordinatorV2Address: String + coordinatorV2PlusAddress: String + waitBlocks: Int! + lookbackBlocks: Int! + blockhashStoreAddress: String! + batchBlockhashStoreAddress: String! + pollPeriod: String! + runTimeout: String! + evmChainID: String + getBlockhashesBatchSize: Int! + storeBlockhashesBatchSize: Int! + fromAddresses: [String!] + createdAt: Time! +} + +type BootstrapSpec { + id: ID! + contractID: String! + relay: String! + relayConfig: Map! + monitoringEndpoint: String + blockchainTimeout: String + contractConfigTrackerPollInterval: String + contractConfigConfirmations: Int + createdAt: Time! +} + +type GatewaySpec { + id: ID! + gatewayConfig: Map! + createdAt: Time! +} + +type WorkflowSpec { + id: ID! + workflowID: String! + workflow: String! + workflowOwner: String! + createdAt: Time! + updatedAt: Time! +} + +type StandardCapabilitiesSpec { + id: ID! + createdAt: Time! + command: String! + config: String +} +type TaskRun { + id: ID! + dotID: String! + type: String! + output: String! + error: String + createdAt: Time! + finishedAt: Time +} +type User { + email: String! + createdAt: Time! +} + +input UpdatePasswordInput { + oldPassword: String! + newPassword: String! +} + +type UpdatePasswordSuccess { + user: User! +} + +union UpdatePasswordPayload = UpdatePasswordSuccess | InputErrors +type VRFKey { + id: ID! + compressed: String! + uncompressed: String! + hash: String! +} + +type VRFKeySuccess { + key: VRFKey! +} + +union VRFKeyPayload = VRFKeySuccess | NotFoundError + +type VRFKeysPayload { + results: [VRFKey!]! +} + +type CreateVRFKeyPayload { + key: VRFKey! +} + +type DeleteVRFKeySuccess { + key: VRFKey! +} + +union DeleteVRFKeyPayload = DeleteVRFKeySuccess | NotFoundError diff --git a/integration-tests/web/sdk/main.go b/integration-tests/web/sdk/main.go new file mode 100644 index 0000000000..e2993ddb44 --- /dev/null +++ b/integration-tests/web/sdk/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "os" + + "github.com/Khan/genqlient/generate" + + "github.com/smartcontractkit/chainlink/v2/core/web/schema" +) + +func main() { + schema := schema.MustGetRootSchema() + + if err := os.WriteFile("./internal/schema.graphql", []byte(schema), 0600); err != nil { + fmt.Println(err) + os.Exit(1) + } + + generate.Main() +} diff --git a/integration-tests/web/sdk/taskfile.yml b/integration-tests/web/sdk/taskfile.yml new file mode 100644 index 0000000000..76cf0c9b42 --- /dev/null +++ b/integration-tests/web/sdk/taskfile.yml @@ -0,0 +1,6 @@ +version: '3' + +tasks: + generate: + cmds: + - go run main.go \ No newline at end of file From 0294e1f3813c0643b61af828ec438307dcab3123 Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Date: Mon, 26 Aug 2024 23:37:21 +0200 Subject: [PATCH 172/432] Fix RPCClient Deadlock on Unsubscribe and NewHead (#14236) * Fix RPCClient Deadlock on Unsubscribe and NewHead * changeset --- .changeset/curly-birds-guess.md | 5 ++++ core/chains/evm/client/rpc_client.go | 15 +++++++----- core/chains/evm/client/rpc_client_test.go | 28 +++++++++++++++++++++++ 3 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 .changeset/curly-birds-guess.md diff --git a/.changeset/curly-birds-guess.md b/.changeset/curly-birds-guess.md new file mode 100644 index 0000000000..c66bd54178 --- /dev/null +++ b/.changeset/curly-birds-guess.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Fixed deadlock in RPCClient causing CL Node to stop performing RPC requests for the affected chain #bugfix diff --git a/core/chains/evm/client/rpc_client.go b/core/chains/evm/client/rpc_client.go index c9e172326e..53ab46a696 100644 --- a/core/chains/evm/client/rpc_client.go +++ b/core/chains/evm/client/rpc_client.go @@ -141,6 +141,7 @@ type rpcClient struct { // stateMu since it can happen on state transitions as well as rpcClient Close. chStopInFlight chan struct{} + chainInfoLock sync.RWMutex // intercepted values seen by callers of the rpcClient excluding health check calls. Need to ensure MultiNode provides repeatable read guarantee highestUserObservations commonclient.ChainInfo // most recent chain info observed during current lifecycle (reseted on DisconnectAll) @@ -336,7 +337,9 @@ func (r *rpcClient) DisconnectAll() { } r.cancelInflightRequests() r.unsubscribeAll() + r.chainInfoLock.Lock() r.latestChainInfo = commonclient.ChainInfo{} + r.chainInfoLock.Unlock() } // unsubscribeAll unsubscribes all subscriptions @@ -1379,8 +1382,8 @@ func (r *rpcClient) onNewHead(ctx context.Context, requestCh <-chan struct{}, he return } - r.stateMu.Lock() - defer r.stateMu.Unlock() + r.chainInfoLock.Lock() + defer r.chainInfoLock.Unlock() if !commonclient.CtxIsHeathCheckRequest(ctx) { r.highestUserObservations.BlockNumber = max(r.highestUserObservations.BlockNumber, head.Number) r.highestUserObservations.TotalDifficulty = commonclient.MaxTotalDifficulty(r.highestUserObservations.TotalDifficulty, head.TotalDifficulty) @@ -1398,8 +1401,8 @@ func (r *rpcClient) onNewFinalizedHead(ctx context.Context, requestCh <-chan str if head == nil { return } - r.stateMu.Lock() - defer r.stateMu.Unlock() + r.chainInfoLock.Lock() + defer r.chainInfoLock.Unlock() if !commonclient.CtxIsHeathCheckRequest(ctx) { r.highestUserObservations.FinalizedBlockNumber = max(r.highestUserObservations.FinalizedBlockNumber, head.Number) } @@ -1412,8 +1415,8 @@ func (r *rpcClient) onNewFinalizedHead(ctx context.Context, requestCh <-chan str } func (r *rpcClient) GetInterceptedChainInfo() (latest, highestUserObservations commonclient.ChainInfo) { - r.stateMu.RLock() - defer r.stateMu.RUnlock() + r.chainInfoLock.RLock() + defer r.chainInfoLock.RUnlock() return r.latestChainInfo, r.highestUserObservations } diff --git a/core/chains/evm/client/rpc_client_test.go b/core/chains/evm/client/rpc_client_test.go index 1282188099..eafbea5cd5 100644 --- a/core/chains/evm/client/rpc_client_test.go +++ b/core/chains/evm/client/rpc_client_test.go @@ -7,6 +7,7 @@ import ( "fmt" "math/big" "net/url" + "sync" "testing" "time" @@ -130,6 +131,33 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { assert.Equal(t, int64(0), highestUserObservations.FinalizedBlockNumber) assert.Equal(t, (*big.Int)(nil), highestUserObservations.TotalDifficulty) }) + t.Run("Concurrent Unsubscribe and onNewHead calls do not lead to a deadlock", func(t *testing.T) { + const numberOfAttempts = 1000 // need a large number to increase the odds of reproducing the issue + server := testutils.NewWSServer(t, chainId, serverCallBack) + wsURL := server.WSURL() + + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") + defer rpc.Close() + require.NoError(t, rpc.Dial(ctx)) + var wg sync.WaitGroup + for i := 0; i < numberOfAttempts; i++ { + ch := make(chan *evmtypes.Head) + sub, err := rpc.SubscribeNewHead(tests.Context(t), ch) + require.NoError(t, err) + wg.Add(2) + go func() { + server.MustWriteBinaryMessageSync(t, makeNewHeadWSMessage(&evmtypes.Head{Number: 256, TotalDifficulty: big.NewInt(1000)})) + wg.Done() + }() + go func() { + rpc.UnsubscribeAllExceptAliveLoop() + sub.Unsubscribe() + wg.Done() + }() + wg.Wait() + } + + }) t.Run("Block's chain ID matched configured", func(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() From e7d993bcc4f47c6711dd2a05260d19f2d3165b1d Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:16:59 +0200 Subject: [PATCH 173/432] Migrate more e2e test workflows to use the reusable workflow (#14235) * Refactor integration-chaos-tests.yml * Update names * Remove unused workflow * Fix chaos/ocr_chaos_test.go * Refactor ccip-chaos-tests.yml * Fix * Fix * Fix ccip * Fix * Fix * test * Fix * Allow custom E2E_TEST_GRAFANA_DASHBOARD_URL * Add timeout for setting up GAP --- .github/e2e-tests.yml | 48 +++- .github/workflows/ccip-chaos-tests.yml | 271 ++---------------- .github/workflows/integration-chaos-tests.yml | 168 ++--------- .../run-e2e-tests-reusable-workflow.yml | 13 +- 4 files changed, 101 insertions(+), 399 deletions(-) diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 3f5c531cfd..a3f64e4853 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -164,6 +164,17 @@ runner-test-matrix: E2E_TEST_CHAINLINK_VERSION: '{{ env.DEFAULT_CHAINLINK_PLUGINS_VERSION }}' # This is the chainlink version that has the plugins ENABLE_OTEL_TRACES: true + - id: chaos/ocr_chaos_test.go + path: integration-tests/chaos/ocr_chaos_test.go + test_env_type: k8s-remote-runner + runs_on: ubuntu-latest + workflows: + - Automation On Demand Tests + - E2E Chaos Tests + test_cmd: cd integration-tests/chaos && DETACH_RUNNER=false go test -test.run "^TestOCRChaos$" -v -test.parallel=10 -timeout 60m -count=1 -json + test_env_vars: + TEST_SUITE: chaos + # END: OCR tests # START: Automation tests @@ -531,7 +542,7 @@ runner-test-matrix: test_env_vars: TEST_SUITE: reorg workflows: - - Run Automation On Demand Tests (TEST WORKFLOW) + - Automation On Demand Tests test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_0 -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg @@ -542,7 +553,7 @@ runner-test-matrix: test_env_vars: TEST_SUITE: reorg workflows: - - Run Automation On Demand Tests (TEST WORKFLOW) + - Automation On Demand Tests test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_1 -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg @@ -553,7 +564,7 @@ runner-test-matrix: test_env_vars: TEST_SUITE: reorg workflows: - - Run Automation On Demand Tests (TEST WORKFLOW) + - Automation On Demand Tests test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_2 -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg @@ -564,7 +575,7 @@ runner-test-matrix: test_env_vars: TEST_SUITE: reorg workflows: - - Run Automation On Demand Tests (TEST WORKFLOW) + - Automation On Demand Tests test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_3 -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg @@ -573,7 +584,8 @@ runner-test-matrix: test_env_type: k8s-remote-runner runs_on: ubuntu-latest workflows: - - Run Automation On Demand Tests (TEST WORKFLOW) + - Automation On Demand Tests + - E2E Chaos Tests test_cmd: cd integration-tests/chaos && DETACH_RUNNER=false go test -v -test.run ^TestAutomationChaos$ -test.parallel=20 -timeout 60m -count=1 -json pyroscope_env: ci-automation-on-demand-chaos test_env_vars: @@ -964,4 +976,30 @@ runner-test-matrix: test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + - id: ccip-tests/chaos/ccip_test.go + path: integration-tests/ccip-tests/chaos/ccip_test.go + test_env_type: k8s-remote-runner + runs_on: ubuntu-latest + workflows: + - E2E CCIP Chaos Tests + test_cmd: cd integration-tests/ccip-tests/chaos && DETACH_RUNNER=false go test ccip_test.go -v -test.parallel=11 -timeout 60m -count=1 -json + test_env_vars: + TEST_SUITE: chaos + TEST_TRIGGERED_BY: ccip-cron-chaos-eth + TEST_LOG_LEVEL: debug + + - id: ccip-tests/load/ccip_test.go:^TestLoadCCIPStableWithPodChaosDiffCommitAndExec + path: integration-tests/ccip-tests/load/ccip_test.go + test_env_type: k8s-remote-runner + runs_on: ubuntu-latest + workflows: + # Disabled until CCIP-2555 is resolved + # - E2E CCIP Chaos Tests + test_cmd: cd integration-tests/ccip-tests/load && DETACH_RUNNER=false go test -run '^TestLoadCCIPStableWithPodChaosDiffCommitAndExec' -v -test.parallel=4 -timeout 120m -count=1 -json + test_env_vars: + TEST_SUITE: chaos + TEST_TRIGGERED_BY: ccip-cron-chaos-eth + TEST_LOG_LEVEL: debug + E2E_TEST_GRAFANA_DASHBOARD_URL: /d/6vjVx-1V8/ccip-long-running-tests + # END: CCIP tests \ No newline at end of file diff --git a/.github/workflows/ccip-chaos-tests.yml b/.github/workflows/ccip-chaos-tests.yml index 03f809b44c..1d37551d9f 100644 --- a/.github/workflows/ccip-chaos-tests.yml +++ b/.github/workflows/ccip-chaos-tests.yml @@ -11,248 +11,31 @@ concurrency: group: chaos-ccip-tests-chainlink-${{ github.ref }} cancel-in-progress: true -env: - # TODO: TT-1470 - Update image names as we solidify new realease strategy - CL_ECR: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ github.sha }} - MOD_CACHE_VERSION: 1 - jobs: - build-chainlink: - environment: integration - permissions: - id-token: write - contents: read - name: Build Chainlink Image - runs-on: ubuntu20.04-16cores-64GB - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Check if image exists - id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 - with: - repository: chainlink - tag: ${{ github.sha }} - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - name: Build Image - if: steps.check-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 - env: - GH_TOKEN: ${{ github.token }} - with: - cl_repo: smartcontractkit/chainlink - cl_ref: ${{ github.sha }} - push_tag: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:${{ github.sha }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: ccip-chaos-tests-build-chainlink-image - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Chainlink Image - continue-on-error: true - - build-test-image: - environment: integration - permissions: - id-token: write - contents: read - name: Build Test Image - runs-on: ubuntu20.04-16cores-64GB - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: ccip-chaos-tests-build-test-image - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Test Image - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Build Test Image - uses: ./.github/actions/build-test-image - with: - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - - ccip-chaos-tests: - environment: integration - permissions: - issues: read - checks: write - pull-requests: write - id-token: write - contents: read - name: CCIP Chaos Tests - runs-on: ubuntu-latest - needs: [ build-chainlink, build-test-image ] - env: - TEST_SUITE: chaos - TEST_ARGS: -test.timeout 30m - CHAINLINK_COMMIT_SHA: ${{ github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_TRIGGERED_BY: ccip-cron-chaos-eth - TEST_LOG_LEVEL: debug - DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable - GH_TOKEN: ${{ github.token }} - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: ccip-chaos-tests - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: CCIP Chaos Tests - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Prepare Base64 TOML override for CCIP secrets - uses: ./.github/actions/setup-create-base64-config-ccip - id: setup_create_base64_config_ccip - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkVersion: ${{ github.sha }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - - name: Run Chaos Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d38226be720c5ccc1ff4d3cee40608ebf264cd59 # v2.3.26 - env: - BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} - TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} - with: - test_command_to_run: cd ./integration-tests && go test -timeout 1h -count=1 -json -test.parallel 11 -run 'TestChaosCCIP' ./chaos 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci - test_download_vendor_packages_command: make gomod - artifacts_location: ./integration-tests/chaos/logs - publish_check_name: CCIP Chaos Test Results - publish_report_paths: ./tests-chaos-report.xml - triggered_by: ${{ env.TEST_TRIGGERED_BY }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - CGO_ENABLED: "1" - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - cache_key_id: ccip-load-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - DEFAULT_LOKI_TENANT_ID: ${{ vars.LOKI_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} - DEFAULT_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - DEFAULT_GRAFANA_BASE_URL: ${{ vars.GRAFANA_URL }} - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - - ## Notify in slack if the job fails - - name: Notify Slack - if: failure() && github.event_name != 'workflow_dispatch' - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - env: - SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - with: - channel-id: "#ccip-testing" - slack-message: ":x: :mild-panic-intensifies: CCIP chaos tests failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}" - ## Run Cleanup if the job succeeds - - name: cleanup - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/cleanup@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 - with: - triggered_by: ${{ env.TEST_TRIGGERED_BY }} - - ccip-chaos-with-load-tests: - environment: integration - permissions: - issues: read - checks: write - pull-requests: write - id-token: write - contents: read - name: CCIP Load With Chaos Tests - if: false # Disabled until CCIP-2555 is resolved - runs-on: ubuntu-latest - needs: [ build-chainlink, build-test-image ] - env: - TEST_SUITE: load - TEST_ARGS: -test.timeout 1h - CHAINLINK_COMMIT_SHA: ${{ github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_TRIGGERED_BY: ccip-cron-chaos-and-load-eth - TEST_LOG_LEVEL: debug - DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable - GH_TOKEN: ${{ github.token }} - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: ccip-chaos-tests-with-load-test - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: CCIP load with chaos test - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Prepare Base64 TOML override for CCIP secrests - uses: ./.github/actions/setup-create-base64-config-ccip - id: setup_create_base64_config_ccip - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkVersion: ${{ github.sha }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - - name: Run Load With Chaos Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d38226be720c5ccc1ff4d3cee40608ebf264cd59 # v2.3.26 - env: - BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} - TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} - with: - test_command_to_run: cd ./integration-tests/ccip-tests && go test -timeout 2h -count=1 -json -test.parallel 4 -run '^TestLoadCCIPStableWithPodChaosDiffCommitAndExec' ./load 2>&1 | tee /tmp/gotest.log | gotestfmt - test_download_vendor_packages_command: make gomod - artifacts_location: ./integration-tests/load/logs - publish_check_name: CCIP Chaos With Load Test Results - publish_report_paths: ./tests-chaos-with-load-report.xml - triggered_by: ${{ env.TEST_TRIGGERED_BY }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - CGO_ENABLED: "1" - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - cache_key_id: ccip-load-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - DEFAULT_LOKI_TENANT_ID: ${{ vars.LOKI_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} - DEFAULT_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - DEFAULT_GRAFANA_BASE_URL: ${{ vars.GRAFANA_URL }} - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" - ## Notify in slack if the job fails - - name: Notify Slack - if: failure() && github.event_name != 'workflow_dispatch' - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - env: - SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - with: - channel-id: "#ccip-testing" - slack-message: ":x: :mild-panic-intensifies: CCIP chaos with load tests failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}" - ## Run Cleanup if the job succeeds - - name: cleanup - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/cleanup@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 - with: - triggered_by: ${{ env.TEST_TRIGGERED_BY }} \ No newline at end of file + run-e2e-tests-workflow: + name: Run E2E Tests + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + chainlink_version: ${{ github.sha }} + require_chainlink_image_versions_in_qa_ecr: ${{ github.sha }} + test_workflow: E2E CCIP Chaos Tests + test_log_level: debug + slack_notification_after_tests: on_failure + slack_notification_after_tests_channel_id: '#ccip-testing' + slack_notification_after_tests_name: CCIP Chaos E2E Tests + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} diff --git a/.github/workflows/integration-chaos-tests.yml b/.github/workflows/integration-chaos-tests.yml index 673614bf2c..1f7e6f40fb 100644 --- a/.github/workflows/integration-chaos-tests.yml +++ b/.github/workflows/integration-chaos-tests.yml @@ -7,148 +7,28 @@ on: - "*" workflow_dispatch: -env: - CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ github.sha }} - TEST_SUITE: chaos - TEST_ARGS: -test.timeout 1h - CHAINLINK_COMMIT_SHA: ${{ github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: debug - jobs: - build-chainlink: - environment: integration - permissions: - id-token: write - contents: read - name: Build Chainlink Image - runs-on: ubuntu-latest - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Check if image exists - id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - repository: chainlink - tag: ${{ github.sha }} - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - name: Build Image - if: steps.check-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - cl_repo: smartcontractkit/chainlink - cl_ref: ${{ github.sha }} - push_tag: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:${{ github.sha }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - name: Print Chainlink Image Built - id: push - run: | - echo "### chainlink node image tag used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: e2e-chaos-build-chainlink - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Chainlink Image - continue-on-error: true - - build-test-runner: - environment: integration - permissions: - id-token: write - contents: read - name: Build Test Runner Image - runs-on: ubuntu-latest - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Build Test Image - uses: ./.github/actions/build-test-image - with: - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: e2e-chaos-build-test-image - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Test Runner Image - continue-on-error: true - - chaos-tests: - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - name: EVM Pods Chaos Tests - runs-on: ubuntu-latest - needs: [build-test-runner, build-chainlink] - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: e2e-chaos-tests - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: EVM Pods Chaos Tests - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Prepare Base64 TOML config - env: - CHAINLINK_VERSION: ${{ github.sha }} - run: | - echo ::add-mask::$CHAINLINK_IMAGE - - cat << EOF > config.toml - [Network] - selected_networks=["SIMULATED"] - - [ChainlinkImage] - image="$CHAINLINK_IMAGE" - version="$CHAINLINK_VERSION" - EOF - - BASE64_CONFIG_OVERRIDE=$(cat config.toml | base64 -w 0) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 - with: - test_command_to_run: cd integration-tests && go test -timeout 1h -count=1 -json -test.parallel 11 ./chaos 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs - test_download_vendor_packages_command: cd ./integration-tests && go mod download - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - artifacts_location: ./integration-tests/chaos/logs - publish_check_name: EVM Pods Chaos Test Results - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Upload test log - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 - if: failure() - with: - name: Test Results Log - path: /tmp/gotest.log - retention-days: 7 + run-e2e-tests-workflow: + name: Run E2E Tests + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + chainlink_version: ${{ github.sha }} + require_chainlink_image_versions_in_qa_ecr: ${{ github.sha }} + test_workflow: E2E Chaos Tests + test_log_level: debug + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index 182e0f31d5..6644bba8d9 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -52,10 +52,9 @@ on: required: false type: string slack_notification_after_tests: - description: 'Set to "true" to send a slack notification after the tests' + description: 'Set to "always" to always send a slack notification after the tests. Set "on_failure" to send a notification only on test failure' required: false - type: boolean - default: false + type: string slack_notification_after_tests_channel_id: description: 'Slack channel ID to send the notification to' required: false @@ -449,6 +448,7 @@ jobs: - name: Setup GAP for Grafana uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 id: setup-gap + timeout-minutes: 3 with: aws-region: ${{ secrets.AWS_REGION }} aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} @@ -499,7 +499,7 @@ jobs: E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" - E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + E2E_TEST_GRAFANA_DASHBOARD_URL: ${{ matrix.tests.test_env_vars.E2E_TEST_GRAFANA_DASHBOARD_URL || '/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs' }} E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} E2E_TEST_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} E2E_TEST_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} @@ -689,12 +689,13 @@ jobs: E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" - E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + E2E_TEST_GRAFANA_DASHBOARD_URL: ${{ matrix.tests.test_env_vars.E2E_TEST_GRAFANA_DASHBOARD_URL || '/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs' }} E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} E2E_TEST_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} E2E_TEST_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} E2E_TEST_PYROSCOPE_KEY: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_KEY || '' }} E2E_TEST_PYROSCOPE_ENABLED: ${{ matrix.tests.pyroscope_env != '' && 'true' || '' }} + DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable with: test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: make gomod @@ -756,7 +757,7 @@ jobs: - name: Send Slack notification uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - if: ${{ inputs.slack_notification_after_tests }} + if: ${{ inputs.slack_notification_after_tests == 'true' || inputs.slack_notification_after_tests == 'always' || (inputs.slack_notification_after_tests == 'on_failure' && contains(join(needs.*.result, ','), 'failure')) }} id: slack env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} From 8cea1b26be5fce5aefbf9d177f3961f9a55b04a8 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:30:46 +0200 Subject: [PATCH 174/432] Run smoke/ocr2_test.go on develop-plugins by default (#14240) --- .github/e2e-tests.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index a3f64e4853..16a5152f14 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -150,7 +150,9 @@ runner-test-matrix: - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/ocr2_test.go -timeout 30m -count=1 -test.parallel=6 -json pyroscope_env: ci-smoke-ocr2-evm-simulated - + test_env_vars: + E2E_TEST_CHAINLINK_VERSION: '{{ env.DEFAULT_CHAINLINK_PLUGINS_VERSION }}' # This is the chainlink version that has the plugins + - id: smoke/ocr2_test.go:*-plugins path: integration-tests/smoke/ocr2_test.go test_env_type: docker From 3500089975b675f0ef72efafe14785b2eb310b6d Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Tue, 27 Aug 2024 12:43:13 +0400 Subject: [PATCH 175/432] update test to remove logic for zkevm-node (#14143) --- .../contracts/ethereum_contracts_automation.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/integration-tests/contracts/ethereum_contracts_automation.go b/integration-tests/contracts/ethereum_contracts_automation.go index 9c01511ff1..d1098d9c48 100644 --- a/integration-tests/contracts/ethereum_contracts_automation.go +++ b/integration-tests/contracts/ethereum_contracts_automation.go @@ -1368,12 +1368,7 @@ func deployRegistry22(client *seth.Client, opts *KeeperRegistryOpts) (KeeperRegi return nil, err } - var allowedReadOnlyAddress common.Address - if chainId == networks.PolygonZkEvmMainnet.ChainID || chainId == networks.PolygonZkEvmCardona.ChainID { - allowedReadOnlyAddress = common.HexToAddress("0x1111111111111111111111111111111111111111") - } else { - allowedReadOnlyAddress = common.HexToAddress("0x0000000000000000000000000000000000000000") - } + allowedReadOnlyAddress := common.HexToAddress("0x0000000000000000000000000000000000000000") logicBAbi, err := registrylogicb22.AutomationRegistryLogicBMetaData.GetAbi() if err != nil { @@ -1456,12 +1451,7 @@ func deployRegistry23(client *seth.Client, opts *KeeperRegistryOpts) (KeeperRegi return nil, err } - var allowedReadOnlyAddress common.Address - if chainId == networks.PolygonZkEvmMainnet.ChainID || chainId == networks.PolygonZkEvmCardona.ChainID { - allowedReadOnlyAddress = common.HexToAddress("0x1111111111111111111111111111111111111111") - } else { - allowedReadOnlyAddress = common.HexToAddress("0x0000000000000000000000000000000000000000") - } + allowedReadOnlyAddress := common.HexToAddress("0x0000000000000000000000000000000000000000") logicCAbi, err := registrylogicc23.AutomationRegistryLogicCMetaData.GetAbi() if err != nil { From f8e2cb2cff65a3fc46644de49cb6395fc2be2ba3 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 27 Aug 2024 12:28:21 +0200 Subject: [PATCH 176/432] use Seth from CTF repo (#14233) --- integration-tests/README.md | 2 +- integration-tests/README_SETH.md | 8 ++++---- integration-tests/actions/actions.go | 3 ++- integration-tests/actions/automation_ocr_helpers.go | 3 ++- integration-tests/actions/automationv2/actions.go | 3 ++- integration-tests/actions/keeper_helpers.go | 3 ++- integration-tests/actions/ocr_helpers.go | 3 ++- integration-tests/actions/refund.go | 3 ++- integration-tests/actions/vrf/common/actions.go | 3 ++- integration-tests/actions/vrf/vrfv1/actions.go | 2 +- .../actions/vrf/vrfv2/contract_steps.go | 2 +- integration-tests/actions/vrf/vrfv2/setup_steps.go | 2 +- .../actions/vrf/vrfv2plus/contract_steps.go | 3 ++- .../actions/vrf/vrfv2plus/setup_steps.go | 2 +- integration-tests/ccip-tests/testconfig/global.go | 3 ++- integration-tests/contracts/contract_vrf_models.go | 2 +- integration-tests/contracts/ethereum_contracts.go | 4 +++- .../contracts/ethereum_contracts_atlas.go | 3 ++- .../contracts/ethereum_contracts_automation.go | 3 ++- .../contracts/ethereum_vrf_contracts.go | 2 +- .../contracts/ethereum_vrfv2_contracts.go | 2 +- .../contracts/ethereum_vrfv2plus_contracts.go | 2 +- integration-tests/contracts/multicall.go | 3 ++- integration-tests/contracts/test_contracts.go | 3 ++- integration-tests/crib/connect.go | 3 ++- .../docker/test_env/test_env_builder.go | 2 +- integration-tests/go.mod | 6 +++--- integration-tests/go.sum | 12 ++++++------ integration-tests/load/automationv2_1/gun.go | 3 ++- integration-tests/load/automationv2_1/helpers.go | 3 ++- integration-tests/load/functions/setup.go | 3 ++- integration-tests/load/go.mod | 6 +++--- integration-tests/load/go.sum | 12 ++++++------ integration-tests/load/ocr/gun.go | 3 ++- integration-tests/load/ocr/vu.go | 2 +- integration-tests/load/vrfv2/gun.go | 3 ++- integration-tests/load/vrfv2/vrfv2_test.go | 2 +- integration-tests/load/vrfv2plus/gun.go | 3 ++- integration-tests/load/vrfv2plus/vrfv2plus_test.go | 2 +- integration-tests/reorg/automation_reorg_test.go | 2 +- integration-tests/smoke/keeper_test.go | 3 ++- integration-tests/smoke/log_poller_test.go | 2 +- integration-tests/smoke/ocr2_test.go | 3 ++- integration-tests/smoke/ocr_test.go | 3 ++- integration-tests/smoke/reorg_above_finality_test.go | 2 +- integration-tests/smoke/vrf_test.go | 5 ++--- integration-tests/smoke/vrfv2_test.go | 2 +- integration-tests/smoke/vrfv2plus_test.go | 2 +- integration-tests/testconfig/testconfig.go | 2 +- integration-tests/testsetups/keeper_benchmark.go | 3 ++- integration-tests/testsetups/ocr.go | 9 +++++---- integration-tests/universal/log_poller/helpers.go | 3 ++- integration-tests/utils/seth.go | 3 +-- integration-tests/wrappers/contract_caller.go | 3 +-- 54 files changed, 103 insertions(+), 78 deletions(-) diff --git a/integration-tests/README.md b/integration-tests/README.md index 1510c8c91b..5647a62316 100644 --- a/integration-tests/README.md +++ b/integration-tests/README.md @@ -53,7 +53,7 @@ It's generally recommended to run only one test at a time on a local machine as ### Configure Seth -Our new evm client is Seth. Detailed instructions on how to configure it can be found in the [Seth README](./README_SETH.md) in this repo as well as in [Seth repository](https://github.com/smartcontractkit/seth). +Our new evm client is Seth. Detailed instructions on how to configure it can be found in the [Seth README](./README_SETH.md) in this repo as well as in [Seth repository](https://github.com/smartcontractkit/chainlink-testing-framework/tree/main/seth). ## Analyze diff --git a/integration-tests/README_SETH.md b/integration-tests/README_SETH.md index 92302ab9ce..26fbfc1a79 100644 --- a/integration-tests/README_SETH.md +++ b/integration-tests/README_SETH.md @@ -41,7 +41,7 @@ ## Introduction -[Seth](https://github.com/smartcontractkit/seth) is the Ethereum client we use for integration tests. It is designed to be a thin wrapper over `go-ethereum` client that adds a couple of key features: +[Seth](https://github.com/smartcontractkit/chainlink-testing-framework/tree/main/seth) is the Ethereum client we use for integration tests. It is designed to be a thin wrapper over `go-ethereum` client that adds a couple of key features: * key management * transaction decoding and tracing * gas estimation @@ -65,7 +65,7 @@ tracing_level = "all" # trace all transactions regardless of whether they are re ``` ### Documentation and Further Details -For a comprehensive description of all available configuration options, refer to the `[Seth]` section of configuration documentation in the [default.toml](./testconfig/default.toml) file or consult the Seth [README.md on GitHub](https://github.com/smartcontractkit/seth/blob/master/README.md). +For a comprehensive description of all available configuration options, refer to the `[Seth]` section of configuration documentation in the [default.toml](./testconfig/default.toml) file or consult the Seth [README.md on GitHub](https://github.com/smartcontractkit/chainlink-testing-framework/tree/main/seth/blob/master/README.md). ## How to set Seth logging level ### Locally @@ -155,7 +155,7 @@ The most important thing to keep in mind that the CLI requires you to provide a * `keys` commands requires `SETH_KEYFILE_PATH`, `SETH_CONFIG_PATH` and `SETH_ROOT_PRIVATE_KEY` environment variables * `gas` and `stats` command requires `SETH_CONFIG_PATH` environment variable -You can find a sample `Seth.toml` file [here](https://github.com/smartcontractkit/seth/blob/master/seth.toml). Currently, you cannot use your test TOML file as a Seth configuration file, but we will add ability that in the future. +You can find a sample `Seth.toml` file [here](https://github.com/smartcontractkit/chainlink-testing-framework/tree/main/seth/blob/master/seth.toml). Currently, you cannot use your test TOML file as a Seth configuration file, but we will add ability that in the future. ## How to get Fallback (Hardcoded) Values There are two primary methods to obtain fallback values for network configuration: @@ -166,7 +166,7 @@ There are two primary methods to obtain fallback values for network configuratio 1. **Clone the Seth Repository:** Clone the repository from GitHub using: ```bash -git clone https://github.com/smartcontractkit/seth +git clone https://github.com/smartcontractkit/chainlink-testing-framework/tree/main/seth ``` 2. **Run Seth CLI:** diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index ae4d62ddb3..04767c842e 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -38,7 +38,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" gethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index 3e552371f9..f524f95e8a 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -10,7 +10,8 @@ import ( "time" "github.com/pkg/errors" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3" diff --git a/integration-tests/actions/automationv2/actions.go b/integration-tests/actions/automationv2/actions.go index 9075b863b6..e2785f21aa 100644 --- a/integration-tests/actions/automationv2/actions.go +++ b/integration-tests/actions/automationv2/actions.go @@ -20,11 +20,12 @@ import ( ocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/smartcontractkit/seth" "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3" ocr2keepers20config "github.com/smartcontractkit/chainlink-automation/pkg/v2/config" diff --git a/integration-tests/actions/keeper_helpers.go b/integration-tests/actions/keeper_helpers.go index 618ca96933..d5994676e4 100644 --- a/integration-tests/actions/keeper_helpers.go +++ b/integration-tests/actions/keeper_helpers.go @@ -11,7 +11,8 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/google/uuid" "github.com/pkg/errors" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" ctf_concurrency "github.com/smartcontractkit/chainlink-testing-framework/concurrency" "github.com/smartcontractkit/chainlink-testing-framework/logging" diff --git a/integration-tests/actions/ocr_helpers.go b/integration-tests/actions/ocr_helpers.go index 0622167c99..b0292dc518 100644 --- a/integration-tests/actions/ocr_helpers.go +++ b/integration-tests/actions/ocr_helpers.go @@ -10,7 +10,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/google/uuid" "github.com/stretchr/testify/require" diff --git a/integration-tests/actions/refund.go b/integration-tests/actions/refund.go index 38c4dfad3b..d49b74c699 100644 --- a/integration-tests/actions/refund.go +++ b/integration-tests/actions/refund.go @@ -16,7 +16,8 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/pkg/errors" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" diff --git a/integration-tests/actions/vrf/common/actions.go b/integration-tests/actions/vrf/common/actions.go index e1bda549e7..59ee324ea0 100644 --- a/integration-tests/actions/vrf/common/actions.go +++ b/integration-tests/actions/vrf/common/actions.go @@ -17,7 +17,8 @@ import ( "github.com/go-resty/resty/v2" "github.com/google/uuid" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" diff --git a/integration-tests/actions/vrf/vrfv1/actions.go b/integration-tests/actions/vrf/vrfv1/actions.go index 67110c543e..f5fae76a39 100644 --- a/integration-tests/actions/vrf/vrfv1/actions.go +++ b/integration-tests/actions/vrf/vrfv1/actions.go @@ -3,7 +3,7 @@ package vrfv1 import ( "fmt" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink/integration-tests/contracts" ) diff --git a/integration-tests/actions/vrf/vrfv2/contract_steps.go b/integration-tests/actions/vrf/vrfv2/contract_steps.go index 1b909be9b8..305024f72d 100644 --- a/integration-tests/actions/vrf/vrfv2/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2/contract_steps.go @@ -11,7 +11,7 @@ import ( "github.com/rs/zerolog" "github.com/shopspring/decimal" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" "github.com/smartcontractkit/chainlink/integration-tests/actions" diff --git a/integration-tests/actions/vrf/vrfv2/setup_steps.go b/integration-tests/actions/vrf/vrfv2/setup_steps.go index 0e0b68e640..97948c8a1f 100644 --- a/integration-tests/actions/vrf/vrfv2/setup_steps.go +++ b/integration-tests/actions/vrf/vrfv2/setup_steps.go @@ -6,7 +6,7 @@ import ( "math/big" "testing" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" diff --git a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go index 740e9bcbce..6b3345edd0 100644 --- a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go @@ -10,7 +10,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" "github.com/shopspring/decimal" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" "github.com/smartcontractkit/chainlink/integration-tests/actions" diff --git a/integration-tests/actions/vrf/vrfv2plus/setup_steps.go b/integration-tests/actions/vrf/vrfv2plus/setup_steps.go index fe06222a79..c937046434 100644 --- a/integration-tests/actions/vrf/vrfv2plus/setup_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/setup_steps.go @@ -6,7 +6,7 @@ import ( "math/big" "testing" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/shopspring/decimal" "golang.org/x/sync/errgroup" diff --git a/integration-tests/ccip-tests/testconfig/global.go b/integration-tests/ccip-tests/testconfig/global.go index 25e87bac2a..b20c4ff86f 100644 --- a/integration-tests/ccip-tests/testconfig/global.go +++ b/integration-tests/ccip-tests/testconfig/global.go @@ -12,7 +12,8 @@ import ( "github.com/pelletier/go-toml/v2" "github.com/pkg/errors" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/logging" diff --git a/integration-tests/contracts/contract_vrf_models.go b/integration-tests/contracts/contract_vrf_models.go index c798c4921c..db8b427b07 100644 --- a/integration-tests/contracts/contract_vrf_models.go +++ b/integration-tests/contracts/contract_vrf_models.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index 0d493dff45..c77b5e9bd8 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -14,11 +14,13 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" "github.com/rs/zerolog/log" + "github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" ocrConfigHelper "github.com/smartcontractkit/libocr/offchainreporting/confighelper" ocrTypes "github.com/smartcontractkit/libocr/offchainreporting/types" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/counter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3" diff --git a/integration-tests/contracts/ethereum_contracts_atlas.go b/integration-tests/contracts/ethereum_contracts_atlas.go index c28e519868..4636a92a19 100644 --- a/integration-tests/contracts/ethereum_contracts_atlas.go +++ b/integration-tests/contracts/ethereum_contracts_atlas.go @@ -5,7 +5,8 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/smartcontractkit/chainlink/integration-tests/wrappers" diff --git a/integration-tests/contracts/ethereum_contracts_automation.go b/integration-tests/contracts/ethereum_contracts_automation.go index d1098d9c48..068088eda6 100644 --- a/integration-tests/contracts/ethereum_contracts_automation.go +++ b/integration-tests/contracts/ethereum_contracts_automation.go @@ -14,7 +14,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" cltypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" registrylogicc23 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_logic_c_wrapper_2_3" diff --git a/integration-tests/contracts/ethereum_vrf_contracts.go b/integration-tests/contracts/ethereum_vrf_contracts.go index a09cc809c6..3f83d8fd30 100644 --- a/integration-tests/contracts/ethereum_vrf_contracts.go +++ b/integration-tests/contracts/ethereum_vrf_contracts.go @@ -16,7 +16,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_optimism" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink/integration-tests/wrappers" diff --git a/integration-tests/contracts/ethereum_vrfv2_contracts.go b/integration-tests/contracts/ethereum_vrfv2_contracts.go index df4a6fb9fb..708fdb211e 100644 --- a/integration-tests/contracts/ethereum_vrfv2_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2_contracts.go @@ -13,7 +13,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink/integration-tests/wrappers" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" diff --git a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go index 5926f90cf0..2741209114 100644 --- a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go @@ -11,7 +11,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/montanaflynn/stats" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink/integration-tests/wrappers" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_blockhash_store" diff --git a/integration-tests/contracts/multicall.go b/integration-tests/contracts/multicall.go index 6b73aed084..cd7134a8d8 100644 --- a/integration-tests/contracts/multicall.go +++ b/integration-tests/contracts/multicall.go @@ -8,7 +8,8 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink/integration-tests/wrappers" ) diff --git a/integration-tests/contracts/test_contracts.go b/integration-tests/contracts/test_contracts.go index 85e76054c7..f8674e2136 100644 --- a/integration-tests/contracts/test_contracts.go +++ b/integration-tests/contracts/test_contracts.go @@ -7,7 +7,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink/integration-tests/wrappers" le "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_emitter" diff --git a/integration-tests/crib/connect.go b/integration-tests/crib/connect.go index c180b2ff2e..ae62d31a0e 100644 --- a/integration-tests/crib/connect.go +++ b/integration-tests/crib/connect.go @@ -7,7 +7,8 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/crib" "github.com/pkg/errors" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go index 1ab577bf54..3540e0e877 100644 --- a/integration-tests/docker/test_env/test_env_builder.go +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -13,7 +13,7 @@ import ( "github.com/rs/zerolog/log" "go.uber.org/zap/zapcore" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 8fca475001..ca83d3ac12 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -37,12 +37,12 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 - github.com/smartcontractkit/chainlink-testing-framework v1.34.6 + github.com/smartcontractkit/chainlink-testing-framework v1.34.9 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 + github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/smartcontractkit/seth v1.1.2 github.com/smartcontractkit/wasp v0.4.5 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 @@ -480,7 +480,7 @@ require ( golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sys v0.23.0 // indirect golang.org/x/term v0.23.0 // indirect - golang.org/x/time v0.5.0 // indirect + golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.24.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 7f58213cf4..0014577f21 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1445,20 +1445,20 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.6 h1:x6pdcJ1hcdRJEQxyQltSMbLs+g5ddRw1HOLuLOAnSaI= -github.com/smartcontractkit/chainlink-testing-framework v1.34.6/go.mod h1:tweBFcNZQpKfRtXDQBrvVRrnAmGclByiyuyF/qAU/Eo= +github.com/smartcontractkit/chainlink-testing-framework v1.34.9 h1:SA7YdICzBmIOFMzLBMAol3CYPyLEF7yKkx63SUrB4RE= +github.com/smartcontractkit/chainlink-testing-framework v1.34.9/go.mod h1:t2au5jHgrDklr25+Nurcy40Bgy5o5VBJvjipmnm6nVc= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 h1:1/r1wQZ4TOFpZ13w94r7amdF096Z96RuEnkOmrz1BGE= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 h1:wEc6EKMOOK/9w6z/zv2/wPZsV/txctbYoVJ1sCxhXwI= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0/go.mod h1:upYGPS9lOBW2pJg6XD8TTNSD1GtRfayU2Ct5bcfvqFw= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= -github.com/smartcontractkit/seth v1.1.2 h1:98v9VUFUpNhU7UofeF/bGyUIVv9jnt+JlIE+I8mhX2c= -github.com/smartcontractkit/seth v1.1.2/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= @@ -1991,8 +1991,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/integration-tests/load/automationv2_1/gun.go b/integration-tests/load/automationv2_1/gun.go index 162aca251f..a5fd52c40c 100644 --- a/integration-tests/load/automationv2_1/gun.go +++ b/integration-tests/load/automationv2_1/gun.go @@ -5,9 +5,10 @@ import ( "sync" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" "github.com/smartcontractkit/wasp" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_emitter" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/load/automationv2_1/helpers.go b/integration-tests/load/automationv2_1/helpers.go index 30559743e1..f770ba7573 100644 --- a/integration-tests/load/automationv2_1/helpers.go +++ b/integration-tests/load/automationv2_1/helpers.go @@ -8,7 +8,8 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog" "github.com/slack-go/slack" - "github.com/smartcontractkit/seth" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" ctf_concurrency "github.com/smartcontractkit/chainlink-testing-framework/concurrency" reportModel "github.com/smartcontractkit/chainlink-testing-framework/testreporters" diff --git a/integration-tests/load/functions/setup.go b/integration-tests/load/functions/setup.go index 5519c90846..8151342021 100644 --- a/integration-tests/load/functions/setup.go +++ b/integration-tests/load/functions/setup.go @@ -13,9 +13,10 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/go-resty/resty/v2" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/seth" "github.com/smartcontractkit/tdh2/go/tdh2/tdh2easy" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + chainlinkutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 99af135bd3..6562e45d0a 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,11 +17,11 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 - github.com/smartcontractkit/chainlink-testing-framework v1.34.6 + github.com/smartcontractkit/chainlink-testing-framework v1.34.9 + github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/smartcontractkit/seth v1.1.2 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 github.com/smartcontractkit/wasp v0.4.7 github.com/stretchr/testify v1.9.0 @@ -473,7 +473,7 @@ require ( golang.org/x/sys v0.23.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect - golang.org/x/time v0.5.0 // indirect + golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.24.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 86ebb20817..c0e8e044fd 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1407,20 +1407,20 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.6 h1:x6pdcJ1hcdRJEQxyQltSMbLs+g5ddRw1HOLuLOAnSaI= -github.com/smartcontractkit/chainlink-testing-framework v1.34.6/go.mod h1:tweBFcNZQpKfRtXDQBrvVRrnAmGclByiyuyF/qAU/Eo= +github.com/smartcontractkit/chainlink-testing-framework v1.34.9 h1:SA7YdICzBmIOFMzLBMAol3CYPyLEF7yKkx63SUrB4RE= +github.com/smartcontractkit/chainlink-testing-framework v1.34.9/go.mod h1:t2au5jHgrDklr25+Nurcy40Bgy5o5VBJvjipmnm6nVc= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a h1:8GtvGJaGyKzx/ar1yX74GxrzIYWTZVTyv4pYB/1ln8w= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 h1:wEc6EKMOOK/9w6z/zv2/wPZsV/txctbYoVJ1sCxhXwI= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0/go.mod h1:upYGPS9lOBW2pJg6XD8TTNSD1GtRfayU2Ct5bcfvqFw= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= -github.com/smartcontractkit/seth v1.1.2 h1:98v9VUFUpNhU7UofeF/bGyUIVv9jnt+JlIE+I8mhX2c= -github.com/smartcontractkit/seth v1.1.2/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= @@ -1949,8 +1949,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/integration-tests/load/ocr/gun.go b/integration-tests/load/ocr/gun.go index c4b79ceaf4..5ed71f1672 100644 --- a/integration-tests/load/ocr/gun.go +++ b/integration-tests/load/ocr/gun.go @@ -6,9 +6,10 @@ import ( "time" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" "github.com/smartcontractkit/wasp" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" ) diff --git a/integration-tests/load/ocr/vu.go b/integration-tests/load/ocr/vu.go index 88f186c5ee..a50b52c690 100644 --- a/integration-tests/load/ocr/vu.go +++ b/integration-tests/load/ocr/vu.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/wasp" "go.uber.org/ratelimit" diff --git a/integration-tests/load/vrfv2/gun.go b/integration-tests/load/vrfv2/gun.go index bf7449a247..0eef5b1481 100644 --- a/integration-tests/load/vrfv2/gun.go +++ b/integration-tests/load/vrfv2/gun.go @@ -4,9 +4,10 @@ import ( "math/rand" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" "github.com/smartcontractkit/wasp" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" diff --git a/integration-tests/load/vrfv2/vrfv2_test.go b/integration-tests/load/vrfv2/vrfv2_test.go index c0a4153ba0..b75f930ec1 100644 --- a/integration-tests/load/vrfv2/vrfv2_test.go +++ b/integration-tests/load/vrfv2/vrfv2_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/rs/zerolog/log" "github.com/smartcontractkit/wasp" diff --git a/integration-tests/load/vrfv2plus/gun.go b/integration-tests/load/vrfv2plus/gun.go index 430e9f5ff1..8d4162ab88 100644 --- a/integration-tests/load/vrfv2plus/gun.go +++ b/integration-tests/load/vrfv2plus/gun.go @@ -5,9 +5,10 @@ import ( "math/rand" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" "github.com/smartcontractkit/wasp" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" "github.com/smartcontractkit/chainlink/integration-tests/actions" diff --git a/integration-tests/load/vrfv2plus/vrfv2plus_test.go b/integration-tests/load/vrfv2plus/vrfv2plus_test.go index a1e5deabcb..97e45e0d9c 100644 --- a/integration-tests/load/vrfv2plus/vrfv2plus_test.go +++ b/integration-tests/load/vrfv2plus/vrfv2plus_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/rs/zerolog/log" "github.com/smartcontractkit/wasp" diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index 808e394d69..87b3aee752 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -132,7 +132,7 @@ func TestAutomationReorg(t *testing.T) { err = actions.FundChainlinkNodesFromRootAddress(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs()), big.NewFloat(*config.GetCommonConfig().ChainlinkNodeFunding)) require.NoError(t, err, "Failed to fund the nodes") - gethRPCClient := ctfClient.NewRPCClient(evmNetwork.HTTPURLs[0]) + gethRPCClient := ctfClient.NewRPCClient(evmNetwork.HTTPURLs[0], nil) registryConfig := actions.AutomationDefaultRegistryConfig(config) registryConfig.RegistryVersion = registryVersion diff --git a/integration-tests/smoke/keeper_test.go b/integration-tests/smoke/keeper_test.go index b6118025a1..29602da34f 100644 --- a/integration-tests/smoke/keeper_test.go +++ b/integration-tests/smoke/keeper_test.go @@ -13,9 +13,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/onsi/gomega" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" diff --git a/integration-tests/smoke/log_poller_test.go b/integration-tests/smoke/log_poller_test.go index f1a257552a..18862e13b7 100644 --- a/integration-tests/smoke/log_poller_test.go +++ b/integration-tests/smoke/log_poller_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/onsi/gomega" diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index 90afff94cf..03c0d81c46 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -12,9 +12,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/logstream" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" diff --git a/integration-tests/smoke/ocr_test.go b/integration-tests/smoke/ocr_test.go index 8d17a02071..41cc1fb641 100644 --- a/integration-tests/smoke/ocr_test.go +++ b/integration-tests/smoke/ocr_test.go @@ -7,9 +7,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" diff --git a/integration-tests/smoke/reorg_above_finality_test.go b/integration-tests/smoke/reorg_above_finality_test.go index e7b9e4a218..78132848e5 100644 --- a/integration-tests/smoke/reorg_above_finality_test.go +++ b/integration-tests/smoke/reorg_above_finality_test.go @@ -53,7 +53,7 @@ func TestReorgAboveFinality_FinalityTagDisabled(t *testing.T) { evmNetwork, err := testEnv.GetFirstEvmNetwork() require.NoError(t, err, "Error getting first evm network") - client := ctf_client.NewRPCClient(evmNetwork.HTTPURLs[0]) + client := ctf_client.NewRPCClient(evmNetwork.HTTPURLs[0], nil) // Wait for chain to progress require.Eventually(t, func() bool { diff --git a/integration-tests/smoke/vrf_test.go b/integration-tests/smoke/vrf_test.go index 53e74ac7ff..76a4a06c6f 100644 --- a/integration-tests/smoke/vrf_test.go +++ b/integration-tests/smoke/vrf_test.go @@ -6,15 +6,13 @@ import ( "testing" "time" - "github.com/smartcontractkit/chainlink/integration-tests/utils" - "github.com/google/uuid" "github.com/onsi/gomega" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" @@ -24,6 +22,7 @@ import ( ethcontracts "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/utils" ) func TestVRFBasic(t *testing.T) { diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index 48fbc0071c..a72af0a229 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/ethereum/go-ethereum/common" "github.com/google/go-cmp/cmp" diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index a1ac5fd554..76d1523f89 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/ethereum/go-ethereum/common" "github.com/google/go-cmp/cmp" diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index 016531ed49..9510886f06 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -17,7 +17,7 @@ import ( "golang.org/x/text/cases" "golang.org/x/text/language" - "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink-testing-framework/seth" ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" k8s_config "github.com/smartcontractkit/chainlink-testing-framework/k8s/config" diff --git a/integration-tests/testsetups/keeper_benchmark.go b/integration-tests/testsetups/keeper_benchmark.go index 5ea3fb8a3c..ffe71893ba 100644 --- a/integration-tests/testsetups/keeper_benchmark.go +++ b/integration-tests/testsetups/keeper_benchmark.go @@ -21,10 +21,11 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/slack-go/slack" - "github.com/smartcontractkit/seth" "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" "github.com/smartcontractkit/chainlink-testing-framework/logging" diff --git a/integration-tests/testsetups/ocr.go b/integration-tests/testsetups/ocr.go index ff6ce5749a..413e2518a4 100644 --- a/integration-tests/testsetups/ocr.go +++ b/integration-tests/testsetups/ocr.go @@ -23,9 +23,10 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/pelletier/go-toml/v2" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + "github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" @@ -740,7 +741,7 @@ func (o *OCRSoakTest) complete() { } func (o *OCRSoakTest) startGethBlockchainReorg(network blockchain.EVMNetwork, conf ctf_config.ReorgConfig) { - client := ctf_client.NewRPCClient(network.HTTPURLs[0]) + client := ctf_client.NewRPCClient(network.HTTPURLs[0], nil) o.log.Info(). Str("URL", client.URL). Int("Depth", conf.Depth). @@ -752,7 +753,7 @@ func (o *OCRSoakTest) startGethBlockchainReorg(network blockchain.EVMNetwork, co } func (o *OCRSoakTest) startAnvilGasSpikeSimulation(network blockchain.EVMNetwork, conf ctf_config.GasSpikeSimulationConfig) { - client := ctf_client.NewRPCClient(network.HTTPURLs[0]) + client := ctf_client.NewRPCClient(network.HTTPURLs[0], nil) o.log.Info(). Str("URL", client.URL). Any("GasSpikeSimulationConfig", conf). @@ -765,7 +766,7 @@ func (o *OCRSoakTest) startAnvilGasSpikeSimulation(network blockchain.EVMNetwork } func (o *OCRSoakTest) startAnvilGasLimitSimulation(network blockchain.EVMNetwork, conf ctf_config.GasLimitSimulationConfig) { - client := ctf_client.NewRPCClient(network.HTTPURLs[0]) + client := ctf_client.NewRPCClient(network.HTTPURLs[0], nil) latestBlock, err := o.seth.Client.BlockByNumber(context.Background(), nil) require.NoError(o.t, err) newGasLimit := int64(math.Ceil(float64(latestBlock.GasUsed()) * conf.NextGasLimitPercentage)) diff --git a/integration-tests/universal/log_poller/helpers.go b/integration-tests/universal/log_poller/helpers.go index bacb5db6ed..c73a19be5b 100644 --- a/integration-tests/universal/log_poller/helpers.go +++ b/integration-tests/universal/log_poller/helpers.go @@ -16,9 +16,10 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/seth" "github.com/smartcontractkit/wasp" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + geth "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" diff --git a/integration-tests/utils/seth.go b/integration-tests/utils/seth.go index 237be1a508..123a7f325e 100644 --- a/integration-tests/utils/seth.go +++ b/integration-tests/utils/seth.go @@ -4,10 +4,9 @@ import ( "fmt" "testing" - pkg_seth "github.com/smartcontractkit/seth" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" + pkg_seth "github.com/smartcontractkit/chainlink-testing-framework/seth" seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" ) diff --git a/integration-tests/wrappers/contract_caller.go b/integration-tests/wrappers/contract_caller.go index 0eea760e02..9703a57295 100644 --- a/integration-tests/wrappers/contract_caller.go +++ b/integration-tests/wrappers/contract_caller.go @@ -16,10 +16,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "github.com/pkg/errors" "github.com/rs/zerolog" - "github.com/smartcontractkit/seth" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - + "github.com/smartcontractkit/chainlink-testing-framework/seth" evmClient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" ) From 7a41ae73bcb5f5eb9ffbc4f25059dbbc236a7e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Tue, 27 Aug 2024 14:34:19 +0300 Subject: [PATCH 177/432] Use ERC165Checker in CapabilitiesRegistry (#14231) * Use ERC165Checker * Update snapshot * Update gethwrappers --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/.changeset/unlucky-rocks-marry.md | 5 ++ contracts/gas-snapshots/keystone.gas-snapshot | 52 +++++++++---------- .../v0.8/keystone/CapabilitiesRegistry.sol | 5 +- .../mocks/CapabilityConfigurationContract.sol | 8 +-- .../mocks/MaliciousConfigurationContract.sol | 8 +-- .../capabilities_registry.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 7 files changed, 43 insertions(+), 39 deletions(-) create mode 100644 contracts/.changeset/unlucky-rocks-marry.md diff --git a/contracts/.changeset/unlucky-rocks-marry.md b/contracts/.changeset/unlucky-rocks-marry.md new file mode 100644 index 0000000000..723bb1e130 --- /dev/null +++ b/contracts/.changeset/unlucky-rocks-marry.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +#internal use ERC165Checker diff --git a/contracts/gas-snapshots/keystone.gas-snapshot b/contracts/gas-snapshots/keystone.gas-snapshot index d75d68a172..ad8bc2798e 100644 --- a/contracts/gas-snapshots/keystone.gas-snapshot +++ b/contracts/gas-snapshots/keystone.gas-snapshot @@ -1,19 +1,19 @@ CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_NoConfigurationContract() (gas: 154809) -CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_WithConfiguration() (gas: 178790) +CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_WithConfiguration() (gas: 180379) CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 24678) CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CapabilityExists() (gas: 145613) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractDoesNotMatchInterface() (gas: 94561) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractNotDeployed() (gas: 92916) -CapabilitiesRegistry_AddDONTest:test_AddDON() (gas: 373685) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19273) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 169752) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 239724) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 250935) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 116890) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_FaultToleranceIsZero() (gas: 43358) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeAlreadyBelongsToWorkflowDON() (gas: 343924) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 180150) -CapabilitiesRegistry_AddDONTest_WhenMaliciousCapabilityConfigurationConfigured:test_RevertWhen_MaliciousCapabilitiesConfigContractTriesToRemoveCapabilitiesFromDONNodes() (gas: 340499) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractDoesNotMatchInterface() (gas: 94543) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractNotDeployed() (gas: 96326) +CapabilitiesRegistry_AddDONTest:test_AddDON() (gas: 373700) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19288) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 169767) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 239739) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 250950) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 116905) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_FaultToleranceIsZero() (gas: 43373) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeAlreadyBelongsToWorkflowDON() (gas: 343954) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 180165) +CapabilitiesRegistry_AddDONTest_WhenMaliciousCapabilityConfigurationConfigured:test_RevertWhen_MaliciousCapabilitiesConfigContractTriesToRemoveCapabilitiesFromDONNodes() (gas: 340514) CapabilitiesRegistry_AddNodeOperatorsTest:test_AddNodeOperators() (gas: 184157) CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_CalledByNonAdmin() (gas: 17624) CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_NodeOperatorAdminAddressZero() (gas: 18520) @@ -47,23 +47,23 @@ CapabilitiesRegistry_RemoveDONsTest:test_RevertWhen_DONDoesNotExist() (gas: 1655 CapabilitiesRegistry_RemoveNodeOperatorsTest:test_RemovesNodeOperator() (gas: 36122) CapabilitiesRegistry_RemoveNodeOperatorsTest:test_RevertWhen_CalledByNonOwner() (gas: 15816) CapabilitiesRegistry_RemoveNodesTest:test_CanAddNodeWithSameSignerAddressAfterRemoving() (gas: 115150) -CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenDONDeleted() (gas: 287648) -CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenNodeNoLongerPartOfDON() (gas: 560993) +CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenDONDeleted() (gas: 287663) +CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenNodeNoLongerPartOfDON() (gas: 561017) CapabilitiesRegistry_RemoveNodesTest:test_OwnerCanRemoveNodes() (gas: 73358) CapabilitiesRegistry_RemoveNodesTest:test_RemovesNode() (gas: 75192) CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25008) CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 18373) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodePartOfCapabilitiesDON() (gas: 385324) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodePartOfCapabilitiesDON() (gas: 385339) CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 18363) CapabilitiesRegistry_TypeAndVersionTest:test_TypeAndVersion() (gas: 9796) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19314) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 152949) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DONDoesNotExist() (gas: 17740) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 222966) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 236977) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 107678) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 163392) -CapabilitiesRegistry_UpdateDONTest:test_UpdatesDON() (gas: 373308) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19323) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 152958) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DONDoesNotExist() (gas: 17749) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 222975) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 236986) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 107687) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 163401) +CapabilitiesRegistry_UpdateDONTest:test_UpdatesDON() (gas: 373317) CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_CalledByNonAdminAndNonOwner() (gas: 20684) CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorAdminIsZeroAddress() (gas: 20008) CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorDoesNotExist() (gas: 19746) @@ -77,8 +77,8 @@ CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdmi CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 29221) CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeSignerAlreadyAssignedToAnotherNode() (gas: 31348) CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 29187) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByCapabilityDON() (gas: 470932) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByWorkflowDON() (gas: 341213) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByCapabilityDON() (gas: 470947) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByWorkflowDON() (gas: 341228) CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 29080) CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 27609) CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162264) diff --git a/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol b/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol index 2b8a82a285..461bbca898 100644 --- a/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol +++ b/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.24; import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol"; -import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; import {EnumerableSet} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; +import {ERC165Checker} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol"; import {ICapabilityConfiguration} from "./interfaces/ICapabilityConfiguration.sol"; /// @notice CapabilitiesRegistry is used to manage Nodes (including their links to Node @@ -1021,8 +1021,7 @@ contract CapabilitiesRegistry is OwnerIsCreator, TypeAndVersionInterface { /// by implementing both getCapabilityConfiguration and /// beforeCapabilityConfigSet if ( - capability.configurationContract.code.length == 0 || - !IERC165(capability.configurationContract).supportsInterface(type(ICapabilityConfiguration).interfaceId) + !ERC165Checker.supportsInterface(capability.configurationContract, type(ICapabilityConfiguration).interfaceId) ) revert InvalidCapabilityConfigurationContractInterface(capability.configurationContract); } s_capabilities[hashedCapabilityId] = capability; diff --git a/contracts/src/v0.8/keystone/test/mocks/CapabilityConfigurationContract.sol b/contracts/src/v0.8/keystone/test/mocks/CapabilityConfigurationContract.sol index c2a916c87e..105c89006f 100644 --- a/contracts/src/v0.8/keystone/test/mocks/CapabilityConfigurationContract.sol +++ b/contracts/src/v0.8/keystone/test/mocks/CapabilityConfigurationContract.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.24; import {ICapabilityConfiguration} from "../../interfaces/ICapabilityConfiguration.sol"; -import {ERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -contract CapabilityConfigurationContract is ICapabilityConfiguration, ERC165 { +contract CapabilityConfigurationContract is ICapabilityConfiguration, IERC165 { mapping(uint256 => bytes) private s_donConfiguration; function getCapabilityConfiguration(uint32 donId) external view returns (bytes memory configuration) { @@ -17,7 +17,7 @@ contract CapabilityConfigurationContract is ICapabilityConfiguration, ERC165 { s_donConfiguration[donId] = config; } - function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { - return interfaceId == this.getCapabilityConfiguration.selector ^ this.beforeCapabilityConfigSet.selector; + function supportsInterface(bytes4 interfaceId) public pure returns (bool) { + return interfaceId == type(ICapabilityConfiguration).interfaceId || interfaceId == type(IERC165).interfaceId; } } diff --git a/contracts/src/v0.8/keystone/test/mocks/MaliciousConfigurationContract.sol b/contracts/src/v0.8/keystone/test/mocks/MaliciousConfigurationContract.sol index 3618124297..2a7fc4d18d 100644 --- a/contracts/src/v0.8/keystone/test/mocks/MaliciousConfigurationContract.sol +++ b/contracts/src/v0.8/keystone/test/mocks/MaliciousConfigurationContract.sol @@ -3,10 +3,10 @@ pragma solidity 0.8.24; import {ICapabilityConfiguration} from "../../interfaces/ICapabilityConfiguration.sol"; import {CapabilitiesRegistry} from "../../CapabilitiesRegistry.sol"; -import {ERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; import {Constants} from "../Constants.t.sol"; -contract MaliciousConfigurationContract is ICapabilityConfiguration, ERC165, Constants { +contract MaliciousConfigurationContract is ICapabilityConfiguration, IERC165, Constants { bytes32 internal s_capabilityWithConfigurationContractId; constructor(bytes32 capabilityWithConfigContractId) { @@ -41,7 +41,7 @@ contract MaliciousConfigurationContract is ICapabilityConfiguration, ERC165, Con CapabilitiesRegistry(msg.sender).updateNodes(nodes); } - function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { - return interfaceId == this.getCapabilityConfiguration.selector ^ this.beforeCapabilityConfigSet.selector; + function supportsInterface(bytes4 interfaceId) public pure returns (bool) { + return interfaceId == type(ICapabilityConfiguration).interfaceId || interfaceId == type(IERC165).interfaceId; } } diff --git a/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go b/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go index 9245f2c738..e5ae52c71c 100644 --- a/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go +++ b/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go @@ -87,7 +87,7 @@ type CapabilitiesRegistryNodeParams struct { var CapabilitiesRegistryMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityIsDeprecated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"CapabilityRequiredByDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"DONDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONNode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"nodeCount\",\"type\":\"uint256\"}],\"name\":\"InvalidFaultTolerance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"InvalidNodeCapabilities\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"InvalidNodeP2PId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotSupportCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfCapabilitiesDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfWorkflowDON\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilitiesRegistry.Capability[]\",\"name\":\"capabilities\",\"type\":\"tuple[]\"}],\"name\":\"addCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"addDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"addNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"deprecateCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityConfigs\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"getDON\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"getHashedCapabilityId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"getNode\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo\",\"name\":\"nodeInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodeOperators\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodes\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"isCapabilityDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"donIds\",\"type\":\"uint32[]\"}],\"name\":\"removeDONs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"removedNodeP2PIds\",\"type\":\"bytes32[]\"}],\"name\":\"removeNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"updateDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"updateNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6080604052600e80546001600160401b0319166401000000011790553480156200002857600080fd5b503380600081620000805760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000b357620000b381620000bc565b50505062000167565b336001600160a01b03821603620001165760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000077565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6150e080620001776000396000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80635d83d967116100ee57806386fa424611610097578063d8bc7b6811610071578063d8bc7b68146103f6578063ddbe4f8214610409578063e29581aa1461041e578063f2fde38b1461043357600080fd5b806386fa42461461039b5780638da5cb5b146103ae5780639cb7c5f4146103d657600080fd5b8063715f5295116100c8578063715f52951461036d57806373ac22b41461038057806379ba50971461039357600080fd5b80635d83d967146103325780635e65e3091461034557806366acaa331461035857600080fd5b8063235374051161015b5780632c01a1e8116101355780632c01a1e8146102cb578063398f3773146102de5780633f2a13c9146102f157806350c946fe1461031257600080fd5b80632353740514610285578063275459f2146102a55780632a852933146102b857600080fd5b80631d05394c1161018c5780631d05394c1461023b578063214502431461025057806322bdbcbc1461026557600080fd5b80630fe5800a146101b357806312570011146101d9578063181f5a77146101fc575b600080fd5b6101c66101c1366004613ea3565b610446565b6040519081526020015b60405180910390f35b6101ec6101e7366004613f07565b61047a565b60405190151581526020016101d0565b604080518082018252601a81527f4361706162696c6974696573526567697374727920312e302e30000000000000602082015290516101d09190613f8e565b61024e610249366004613fe6565b610487565b005b61025861069c565b6040516101d09190614168565b610278610273366004614203565b6107f9565b6040516101d0919061425b565b610298610293366004614203565b6108e6565b6040516101d0919061426e565b61024e6102b3366004613fe6565b61092a565b61024e6102c63660046142a0565b610a01565b61024e6102d9366004613fe6565b610ae1565b61024e6102ec366004613fe6565b610d7d565b6103046102ff366004614343565b610f3c565b6040516101d092919061436d565b610325610320366004613f07565b611128565b6040516101d09190614432565b61024e610340366004613fe6565b611202565b61024e610353366004613fe6565b6112f7565b610360611a1f565b6040516101d09190614445565b61024e61037b366004613fe6565b611c02565b61024e61038e366004613fe6565b611cb4565b61024e612182565b61024e6103a93660046144ba565b61227f565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d0565b6103e96103e4366004613f07565b6125bf565b6040516101d09190614609565b61024e61040436600461461c565b6127fa565b6104116128c4565b6040516101d091906146a5565b6104266129b8565b6040516101d0919061471a565b61024e6104413660046147b3565b612ac1565b6000828260405160200161045b92919061436d565b6040516020818303038152906040528051906020012090505b92915050565b6000610474600583612ad5565b61048f612af0565b60005b818110156106975760008383838181106104ae576104ae6147ce565b90506020020160208101906104c39190614203565b63ffffffff8181166000908152600d60209081526040808320805464010000000081049095168085526001820190935290832094955093909290916a010000000000000000000090910460ff16905b61051b83612b73565b8110156105bb57811561057157600c60006105368584612b7d565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556105b3565b6105b18663ffffffff16600c60006105928588612b7d90919063ffffffff16565b8152602001908152602001600020600401612b8990919063ffffffff16565b505b600101610512565b508354640100000000900463ffffffff16600003610612576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff861660048201526024015b60405180910390fd5b63ffffffff85166000818152600d6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffff00000000000000000000001690558051938452908301919091527ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c1581703651910160405180910390a15050505050806001019050610492565b505050565b600e54606090640100000000900463ffffffff1660006106bd60018361482c565b63ffffffff1667ffffffffffffffff8111156106db576106db613d3d565b60405190808252806020026020018201604052801561076257816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816106f95790505b509050600060015b8363ffffffff168163ffffffff1610156107d65763ffffffff8082166000908152600d602052604090205416156107ce576107a481612b95565b8383815181106107b6576107b66147ce565b6020026020010181905250816107cb90614849565b91505b60010161076a565b506107e260018461482c565b63ffffffff1681146107f2578082525b5092915050565b60408051808201909152600081526060602082015263ffffffff82166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161085d90614881565b80601f016020809104026020016040519081016040528092919081815260200182805461088990614881565b80156108d65780601f106108ab576101008083540402835291602001916108d6565b820191906000526020600020905b8154815290600101906020018083116108b957829003601f168201915b5050505050815250509050919050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c081019190915261047482612b95565b610932612af0565b60005b63ffffffff811682111561069757600083838363ffffffff1681811061095d5761095d6147ce565b90506020020160208101906109729190614203565b63ffffffff81166000908152600b6020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559192506109bd6001830182613cd0565b505060405163ffffffff8216907fa59268ca81d40429e65ccea5385b59cf2d3fc6519371dee92f8eb1dae5107a7a90600090a2506109fa816148d4565b9050610935565b610a09612af0565b63ffffffff8088166000908152600d60205260408120805490926401000000009091041690819003610a6f576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff8a166004820152602401610609565b610ad6888888886040518060a001604052808f63ffffffff16815260200187610a97906148d4565b63ffffffff811682528b15156020830152895460ff6a01000000000000000000009091048116151560408401528b166060909201919091529650612e60565b505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d77576000848483818110610b1b57610b1b6147ce565b602090810292909201356000818152600c90935260409092206001810154929350919050610b78576040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260048101839052602401610609565b6000610b8682600401612b73565b1115610bdb57610b996004820184612b7d565b6040517f60a6d89800000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101839052604401610609565b805468010000000000000000900463ffffffff1615610c435780546040517f60b9df730000000000000000000000000000000000000000000000000000000081526801000000000000000090910463ffffffff16600482015260248101839052604401610609565b83158015610c7d5750805463ffffffff166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15610cb6576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6001810154610cc790600790612b89565b506002810154610cd990600990612b89565b506000828152600c6020526040812080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815560018101829055600281018290559060048201818181610d2e8282613d0a565b5050505050507f5254e609a97bab37b7cc79fe128f85c097bd6015c6e1624ae0ba392eb975320582604051610d6591815260200190565b60405180910390a15050600101610aff565b50505050565b610d85612af0565b60005b81811015610697576000838383818110610da457610da46147ce565b9050602002810190610db691906148f7565b610dbf90614935565b805190915073ffffffffffffffffffffffffffffffffffffffff16610e10576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815263ffffffff9095166000818152600b909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251919290916001820190610e9c90826149ef565b5050600e8054909150600090610eb79063ffffffff166148d4565b91906101000a81548163ffffffff021916908363ffffffff160217905550816000015173ffffffffffffffffffffffffffffffffffffffff168163ffffffff167f78e94ca80be2c30abc061b99e7eb8583b1254781734b1e3ce339abb57da2fe8e8460200151604051610f2a9190613f8e565b60405180910390a35050600101610d88565b63ffffffff8083166000908152600d60209081526040808320805464010000000090049094168084526001909401825280832085845260030190915281208054606093849390929091610f8e90614881565b80601f0160208091040260200160405190810160405280929190818152602001828054610fba90614881565b80156110075780601f10610fdc57610100808354040283529160200191611007565b820191906000526020600020905b815481529060010190602001808311610fea57829003601f168201915b5050506000888152600260208190526040909120015492935060609262010000900473ffffffffffffffffffffffffffffffffffffffff1615915061111a905057600086815260026020819052604091829020015490517f8318ed5d00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526201000090910473ffffffffffffffffffffffffffffffffffffffff1690638318ed5d90602401600060405180830381865afa1580156110d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111179190810190614b09565b90505b9093509150505b9250929050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c08101919091526040805160e0810182526000848152600c6020908152838220805463ffffffff8082168652640100000000820481168487018190526801000000000000000090920416858701526001820154606086015260028201546080860152835260030190529190912060a08201906111d790613685565b81526020016111fa600c6000868152602001908152602001600020600401613685565b905292915050565b61120a612af0565b60005b81811015610697576000838383818110611229576112296147ce565b905060200201359050611246816003612ad590919063ffffffff16565b61127f576040517fe181733f00000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b61128a600582613692565b6112c3576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b60405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a25060010161120d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d77576000848483818110611331576113316147ce565b90506020028101906113439190614b77565b61134c90614bab565b6040808201516000908152600c6020908152828220805463ffffffff168352600b82528383208451808601909552805473ffffffffffffffffffffffffffffffffffffffff16855260018101805496975091959394939092840191906113b190614881565b80601f01602080910402602001604051908101604052809291908181526020018280546113dd90614881565b801561142a5780601f106113ff5761010080835404028352916020019161142a565b820191906000526020600020905b81548152906001019060200180831161140d57829003601f168201915b50505091909252505050600183015490915061147a5782604001516040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b8415801561149f5750805173ffffffffffffffffffffffffffffffffffffffff163314155b156114d8576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6020830151611513576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018201546020840151811461159457602084015161153490600790612ad5565b1561156b576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208401516001840155611580600782612b89565b50602084015161159290600790613692565b505b606084015180516000036115d657806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c7e565b835460009085906004906115f790640100000000900463ffffffff166148d4565b91906101000a81548163ffffffff021916908363ffffffff1602179055905060005b82518110156116dc5761164f838281518110611637576116376147ce565b60200260200101516003612ad590919063ffffffff16565b61168757826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c7e565b6116d383828151811061169c5761169c6147ce565b60200260200101518760030160008563ffffffff1663ffffffff16815260200190815260200160002061369290919063ffffffff16565b50600101611619565b50845468010000000000000000900463ffffffff16801561183d5763ffffffff8082166000908152600d60209081526040808320805464010000000090049094168352600190930181528282206002018054845181840281018401909552808552929392909183018282801561177157602002820191906000526020600020905b81548152602001906001019080831161175d575b5050505050905060005b815181101561183a576117d0828281518110611799576117996147ce565b60200260200101518960030160008763ffffffff1663ffffffff168152602001908152602001600020612ad590919063ffffffff16565b611832578181815181106117e6576117e66147ce565b6020026020010151836040517f03dcd86200000000000000000000000000000000000000000000000000000000815260040161060992919091825263ffffffff16602082015260400190565b60010161177b565b50505b600061184b87600401613685565b905060005b81518163ffffffff161015611991576000828263ffffffff1681518110611879576118796147ce565b60209081029190910181015163ffffffff8082166000908152600d8452604080822080546401000000009004909316825260019092018452818120600201805483518187028101870190945280845293955090939192909183018282801561190057602002820191906000526020600020905b8154815260200190600101908083116118ec575b5050505050905060005b815181101561197d5761195f828281518110611928576119286147ce565b60200260200101518c60030160008a63ffffffff1663ffffffff168152602001908152602001600020612ad590919063ffffffff16565b611975578181815181106117e6576117e66147ce565b60010161190a565b5050508061198a906148d4565b9050611850565b50875187547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90911690811788556040808a015160028a018190556020808c01518351928352908201527f4b5b465e22eea0c3d40c30e936643245b80d19b2dcf75788c0699fe8d8db645b910160405180910390a25050505050505050806001019050611315565b600e5460609063ffffffff166000611a3860018361482c565b63ffffffff1667ffffffffffffffff811115611a5657611a56613d3d565b604051908082528060200260200182016040528015611a9c57816020015b604080518082019091526000815260606020820152815260200190600190039081611a745790505b509050600060015b8363ffffffff168163ffffffff161015611bec5763ffffffff81166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611be45763ffffffff81166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191611b3890614881565b80601f0160208091040260200160405190810160405280929190818152602001828054611b6490614881565b8015611bb15780601f10611b8657610100808354040283529160200191611bb1565b820191906000526020600020905b815481529060010190602001808311611b9457829003601f168201915b505050505081525050838381518110611bcc57611bcc6147ce565b602002602001018190525081611be190614849565b91505b600101611aa4565b50600e546107e29060019063ffffffff1661482c565b611c0a612af0565b60005b81811015610697576000838383818110611c2957611c296147ce565b9050602002810190611c3b9190614cc2565b611c4490614d05565b90506000611c5a82600001518360200151610446565b9050611c67600382613692565b611ca0576040517febf5255100000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b611caa818361369e565b5050600101611c0d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d77576000848483818110611cee57611cee6147ce565b9050602002810190611d009190614b77565b611d0990614bab565b805163ffffffff166000908152600b602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191611d5f90614881565b80601f0160208091040260200160405190810160405280929190818152602001828054611d8b90614881565b8015611dd85780601f10611dad57610100808354040283529160200191611dd8565b820191906000526020600020905b815481529060010190602001808311611dbb57829003601f168201915b50505091909252505081519192505073ffffffffffffffffffffffffffffffffffffffff16611e3e5781516040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff9091166004820152602401610609565b83158015611e635750805173ffffffffffffffffffffffffffffffffffffffff163314155b15611e9c576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6040808301516000908152600c60205220600181015415611ef15782604001516040517f5461848300000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b6040830151611f345782604001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b60208301511580611f5157506020830151611f5190600790612ad5565b15611f88576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608301518051600003611fca57806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c7e565b81548290600490611fe890640100000000900463ffffffff166148d4565b82546101009290920a63ffffffff818102199093169183160217909155825464010000000090041660005b82518110156120be57612031838281518110611637576116376147ce565b61206957826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614c7e565b6120b583828151811061207e5761207e6147ce565b60200260200101518560030160008563ffffffff1663ffffffff16815260200190815260200160002061369290919063ffffffff16565b50600101612013565b50845183547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff91821617845560408601516002850155602086015160018501819055612114916007919061369216565b50604085015161212690600990613692565b50845160408087015160208089015183519283529082015263ffffffff909216917f74becb12a5e8fd0e98077d02dfba8f647c9670c9df177e42c2418cf17a636f05910160405180910390a25050505050806001019050611cd2565b60015473ffffffffffffffffffffffffffffffffffffffff163314612203576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610609565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b8281146122c2576040517fab8b67c60000000000000000000000000000000000000000000000000000000081526004810184905260248101829052604401610609565b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156125b75760008686838181106122fa576122fa6147ce565b905060200201602081019061230f9190614203565b63ffffffff81166000908152600b6020526040902080549192509073ffffffffffffffffffffffffffffffffffffffff1661237e576040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff83166004820152602401610609565b6000868685818110612392576123926147ce565b90506020028101906123a491906148f7565b6123ad90614935565b805190915073ffffffffffffffffffffffffffffffffffffffff166123fe576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815473ffffffffffffffffffffffffffffffffffffffff16331480159061243b57503373ffffffffffffffffffffffffffffffffffffffff861614155b15612474576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b8051825473ffffffffffffffffffffffffffffffffffffffff90811691161415806124f057506020808201516040516124ad9201613f8e565b60405160208183030381529060405280519060200120826001016040516020016124d79190614dab565b6040516020818303038152906040528051906020012014155b156125a957805182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020810151600183019061254a90826149ef565b50806000015173ffffffffffffffffffffffffffffffffffffffff168363ffffffff167f86f41145bde5dd7f523305452e4aad3685508c181432ec733d5f345009358a2883602001516040516125a09190613f8e565b60405180910390a35b5050508060010190506122de565b505050505050565b6126006040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b6040805160e0810182528381526000848152600260209081529290208054919283019161262c90614881565b80601f016020809104026020016040519081016040528092919081815260200182805461265890614881565b80156126a55780601f1061267a576101008083540402835291602001916126a5565b820191906000526020600020905b81548152906001019060200180831161268857829003601f168201915b505050505081526020016002600085815260200190815260200160002060010180546126d090614881565b80601f01602080910402602001604051908101604052809291908181526020018280546126fc90614881565b80156127495780601f1061271e57610100808354040283529160200191612749565b820191906000526020600020905b81548152906001019060200180831161272c57829003601f168201915b50505091835250506000848152600260208181526040909220015491019060ff16600381111561277b5761277b614526565b815260008481526002602081815260409092200154910190610100900460ff1660018111156127ac576127ac614526565b81526000848152600260208181526040928390209091015462010000900473ffffffffffffffffffffffffffffffffffffffff1690830152016127f0600585612ad5565b1515905292915050565b612802612af0565b600e805460009164010000000090910463ffffffff16906004612824836148d4565b82546101009290920a63ffffffff81810219909316918316021790915581166000818152600d602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001684179055815160a08101835292835260019083015286151590820152841515606082015260ff841660808201529091506128ba908990899089908990612e60565b5050505050505050565b606060006128d26003613685565b90506000815167ffffffffffffffff8111156128f0576128f0613d3d565b60405190808252806020026020018201604052801561296257816020015b61294f6040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b81526020019060019003908161290e5790505b50905060005b82518110156107f257612993838281518110612986576129866147ce565b60200260200101516125bf565b8282815181106129a5576129a56147ce565b6020908102919091010152600101612968565b606060006129c66009613685565b90506000815167ffffffffffffffff8111156129e4576129e4613d3d565b604051908082528060200260200182016040528015612a6b57816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181612a025790505b50905060005b82518110156107f257612a9c838281518110612a8f57612a8f6147ce565b6020026020010151611128565b828281518110612aae57612aae6147ce565b6020908102919091010152600101612a71565b612ac9612af0565b612ad281613932565b50565b600081815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612b71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610609565b565b6000610474825490565b6000612ae98383613a27565b6000612ae98383613a51565b6040805160e0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840181905260c084015263ffffffff8581168352600d8252848320805464010000000090049091168084526001909101825284832060028101805487518186028101860190985280885295969295919493909190830182828015612c4657602002820191906000526020600020905b815481526020019060010190808311612c32575b505050505090506000815167ffffffffffffffff811115612c6957612c69613d3d565b604051908082528060200260200182016040528015612caf57816020015b604080518082019091526000815260606020820152815260200190600190039081612c875790505b50905060005b8151811015612dc7576040518060400160405280848381518110612cdb57612cdb6147ce565b60200260200101518152602001856003016000868581518110612d0057612d006147ce565b602002602001015181526020019081526020016000208054612d2190614881565b80601f0160208091040260200160405190810160405280929190818152602001828054612d4d90614881565b8015612d9a5780601f10612d6f57610100808354040283529160200191612d9a565b820191906000526020600020905b815481529060010190602001808311612d7d57829003601f168201915b5050505050815250828281518110612db457612db46147ce565b6020908102919091010152600101612cb5565b506040805160e08101825263ffffffff8089166000818152600d6020818152868320548086168752948b168187015260ff680100000000000000008604811697870197909752690100000000000000000085048716151560608701529290915290526a010000000000000000000090049091161515608082015260a08101612e4e85613685565b81526020019190915295945050505050565b805163ffffffff9081166000908152600d602090815260408083208286015190941683526001909301905220608082015160ff161580612eb2575060808201518590612ead906001614e59565b60ff16115b15612efb5760808201516040517f25b4d61800000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101869052604401610609565b6001826020015163ffffffff161115612fe357815163ffffffff166000908152600d602090815260408220908401516001918201918391612f3c919061482c565b63ffffffff1663ffffffff168152602001908152602001600020905060005b612f6482612b73565b811015612fe057612f93846000015163ffffffff16600c60006105928587600001612b7d90919063ffffffff16565b50600c6000612fa28484612b7d565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff169055600101612f5b565b50505b60005b8581101561321d57613013878783818110613003576130036147ce565b8592602090910201359050613692565b61307457825187878381811061302b5761302b6147ce565b6040517f636e405700000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8260600151156131cb57825163ffffffff16600c600089898581811061309c5761309c6147ce565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff16148015906131165750600c60008888848181106130e7576130e76147ce565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff1615155b1561317857825187878381811061312f5761312f6147ce565b6040517f60b9df7300000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8251600c6000898985818110613190576131906147ce565b90506020020135815260200190815260200160002060000160086101000a81548163ffffffff021916908363ffffffff160217905550613215565b82516132139063ffffffff16600c60008a8a868181106131ed576131ed6147ce565b90506020020135815260200190815260200160002060040161369290919063ffffffff16565b505b600101612fe6565b5060005b8381101561362b573685858381811061323c5761323c6147ce565b905060200281019061324e91906148f7565b905061325c60038235612ad5565b613295576040517fe181733f00000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b6132a160058235612ad5565b156132db576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b80356000908152600384016020526040812080546132f890614881565b905011156133445783516040517f3927d08000000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015281356024820152604401610609565b60005b8781101561344e576133eb8235600c60008c8c8681811061336a5761336a6147ce565b9050602002013581526020019081526020016000206003016000600c60008e8e8881811061339a5761339a6147ce565b90506020020135815260200190815260200160002060000160049054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020612ad590919063ffffffff16565b61344657888882818110613401576134016147ce565b6040517fa7e792500000000000000000000000000000000000000000000000000000000081526020909102929092013560048301525082356024820152604401610609565b600101613347565b506002830180546001810182556000918252602091829020833591015561347790820182614e72565b82356000908152600386016020526040902091613495919083614ed7565b50604080850151855163ffffffff9081166000908152600d602090815284822080549415156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff90951694909417909355606088015188518316825284822080549115156a0100000000000000000000027fffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff9092169190911790556080880151885183168252848220805460ff9290921668010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff909216919091179055828801805189518416835294909120805494909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9094169390931790558551915161362292918435908c908c906135e890880188614e72565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613b4492505050565b50600101613221565b50815160208301516040517ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c15817036519261367592909163ffffffff92831681529116602082015260400190565b60405180910390a1505050505050565b60606000612ae983613c25565b6000612ae98383613c81565b608081015173ffffffffffffffffffffffffffffffffffffffff16156137ec57608081015173ffffffffffffffffffffffffffffffffffffffff163b1580613797575060808101516040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f78bea72100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff909116906301ffc9a790602401602060405180830381865afa158015613771573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137959190614ff2565b155b156137ec5760808101516040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610609565b60008281526002602052604090208151829190819061380b90826149ef565b506020820151600182019061382090826149ef565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600381111561386257613862614526565b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156138a9576138a9614526565b0217905550608091909101516002909101805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff90921691909117905560405182907f04f0a9bcf3f3a3b42a4d7ca081119755f82ebe43e0d30c8f7292c4fe0dc4a2ae90600090a25050565b3373ffffffffffffffffffffffffffffffffffffffff8216036139b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610609565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613a3e57613a3e6147ce565b9060005260206000200154905092915050565b60008181526001830160205260408120548015613b3a576000613a7560018361500f565b8554909150600090613a899060019061500f565b9050818114613aee576000866000018281548110613aa957613aa96147ce565b9060005260206000200154905080876000018481548110613acc57613acc6147ce565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613aff57613aff615022565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610474565b6000915050610474565b6000848152600260208190526040909120015462010000900473ffffffffffffffffffffffffffffffffffffffff16156125b757600084815260026020819052604091829020015490517ffba64a7c0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169063fba64a7c90613beb908690869086908b908d90600401615051565b600060405180830381600087803b158015613c0557600080fd5b505af1158015613c19573d6000803e3d6000fd5b50505050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015613c7557602002820191906000526020600020905b815481526020019060010190808311613c61575b50505050509050919050565b6000818152600183016020526040812054613cc857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610474565b506000610474565b508054613cdc90614881565b6000825580601f10613cec575050565b601f016020900490600052602060002090810190612ad29190613d24565b5080546000825590600052602060002090810190612ad291905b5b80821115613d395760008155600101613d25565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613d8f57613d8f613d3d565b60405290565b60405160a0810167ffffffffffffffff81118282101715613d8f57613d8f613d3d565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613dff57613dff613d3d565b604052919050565b600067ffffffffffffffff821115613e2157613e21613d3d565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613e5e57600080fd5b8135613e71613e6c82613e07565b613db8565b818152846020838601011115613e8657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613eb657600080fd5b823567ffffffffffffffff80821115613ece57600080fd5b613eda86838701613e4d565b93506020850135915080821115613ef057600080fd5b50613efd85828601613e4d565b9150509250929050565b600060208284031215613f1957600080fd5b5035919050565b60005b83811015613f3b578181015183820152602001613f23565b50506000910152565b60008151808452613f5c816020860160208601613f20565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612ae96020830184613f44565b60008083601f840112613fb357600080fd5b50813567ffffffffffffffff811115613fcb57600080fd5b6020830191508360208260051b850101111561112157600080fd5b60008060208385031215613ff957600080fd5b823567ffffffffffffffff81111561401057600080fd5b61401c85828601613fa1565b90969095509350505050565b60008151808452602080850194506020840160005b838110156140595781518752958201959082019060010161403d565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b848110156140e1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051845284015160408585018190526140cd81860183613f44565b9a86019a9450505090830190600101614081565b5090979650505050505050565b600063ffffffff8083511684528060208401511660208501525060ff604083015116604084015260608201511515606084015260808201511515608084015260a082015160e060a085015261414660e0850182614028565b905060c083015184820360c086015261415f8282614064565b95945050505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526141cb8583516140ee565b94509285019290850190600101614191565b5092979650505050505050565b803563ffffffff811681146141fe57600080fd5b919050565b60006020828403121561421557600080fd5b612ae9826141ea565b73ffffffffffffffffffffffffffffffffffffffff815116825260006020820151604060208501526142536040850182613f44565b949350505050565b602081526000612ae9602083018461421e565b602081526000612ae960208301846140ee565b8015158114612ad257600080fd5b803560ff811681146141fe57600080fd5b600080600080600080600060a0888a0312156142bb57600080fd5b6142c4886141ea565b9650602088013567ffffffffffffffff808211156142e157600080fd5b6142ed8b838c01613fa1565b909850965060408a013591508082111561430657600080fd5b506143138a828b01613fa1565b909550935050606088013561432781614281565b91506143356080890161428f565b905092959891949750929550565b6000806040838503121561435657600080fd5b61435f836141ea565b946020939093013593505050565b6040815260006143806040830185613f44565b828103602084015261415f8185613f44565b600063ffffffff808351168452602081818501511681860152816040850151166040860152606084015160608601526080840151608086015260a0840151915060e060a08601526143e660e0860183614028565b60c08581015187830391880191909152805180835290830193506000918301905b808310156144275784518252938301936001929092019190830190614407565b509695505050505050565b602081526000612ae96020830184614392565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526144a885835161421e565b9450928501929085019060010161446e565b600080600080604085870312156144d057600080fd5b843567ffffffffffffffff808211156144e857600080fd5b6144f488838901613fa1565b9096509450602087013591508082111561450d57600080fd5b5061451a87828801613fa1565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b805182526000602082015160e0602085015261457460e0850182613f44565b90506040830151848203604086015261458d8282613f44565b9150506060830151600481106145a5576145a5614526565b60608501526080830151600281106145bf576145bf614526565b8060808601525060a08301516145ed60a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015161460160c086018215159052565b509392505050565b602081526000612ae96020830184614555565b600080600080600080600060a0888a03121561463757600080fd5b873567ffffffffffffffff8082111561464f57600080fd5b61465b8b838c01613fa1565b909950975060208a013591508082111561467457600080fd5b506146818a828b01613fa1565b909650945050604088013561469581614281565b9250606088013561432781614281565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452614708858351614555565b945092850192908501906001016146ce565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156141dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261477d858351614392565b94509285019290850190600101614743565b803573ffffffffffffffffffffffffffffffffffffffff811681146141fe57600080fd5b6000602082840312156147c557600080fd5b612ae98261478f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff8281168282160390808211156107f2576107f26147fd565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361487a5761487a6147fd565b5060010190565b600181811c9082168061489557607f821691505b6020821081036148ce577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600063ffffffff8083168181036148ed576148ed6147fd565b6001019392505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261492b57600080fd5b9190910192915050565b60006040823603121561494757600080fd5b6040516040810167ffffffffffffffff828210818311171561496b5761496b613d3d565b816040526149788561478f565b8352602085013591508082111561498e57600080fd5b5061499b36828601613e4d565b60208301525092915050565b601f821115610697576000816000526020600020601f850160051c810160208610156149d05750805b601f850160051c820191505b818110156125b7578281556001016149dc565b815167ffffffffffffffff811115614a0957614a09613d3d565b614a1d81614a178454614881565b846149a7565b602080601f831160018114614a705760008415614a3a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556125b7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614abd57888601518255948401946001909101908401614a9e565b5085821015614af957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215614b1b57600080fd5b815167ffffffffffffffff811115614b3257600080fd5b8201601f81018413614b4357600080fd5b8051614b51613e6c82613e07565b818152856020838501011115614b6657600080fd5b61415f826020830160208601613f20565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183360301811261492b57600080fd5b600060808236031215614bbd57600080fd5b614bc5613d6c565b614bce836141ea565b81526020808401358183015260408401356040830152606084013567ffffffffffffffff80821115614bff57600080fd5b9085019036601f830112614c1257600080fd5b813581811115614c2457614c24613d3d565b8060051b9150614c35848301613db8565b8181529183018401918481019036841115614c4f57600080fd5b938501935b83851015614c6d57843582529385019390850190614c54565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614cb657835183529284019291840191600101614c9a565b50909695505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261492b57600080fd5b8035600281106141fe57600080fd5b600060a08236031215614d1757600080fd5b614d1f613d95565b823567ffffffffffffffff80821115614d3757600080fd5b614d4336838701613e4d565b83526020850135915080821115614d5957600080fd5b50614d6636828601613e4d565b602083015250604083013560048110614d7e57600080fd5b6040820152614d8f60608401614cf6565b6060820152614da06080840161478f565b608082015292915050565b6000602080835260008454614dbf81614881565b8060208701526040600180841660008114614de15760018114614e1b57614e4b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550614e4b565b89600052602060002060005b85811015614e425781548b8201860152908301908801614e27565b8a016040019650505b509398975050505050505050565b60ff8181168382160190811115610474576104746147fd565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614ea757600080fd5b83018035915067ffffffffffffffff821115614ec257600080fd5b60200191503681900382131561112157600080fd5b67ffffffffffffffff831115614eef57614eef613d3d565b614f0383614efd8354614881565b836149a7565b6000601f841160018114614f555760008515614f1f5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614feb565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015614fa45786850135825560209485019460019092019101614f84565b5086821015614fdf577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60006020828403121561500457600080fd5b8151612ae981614281565b81810381811115610474576104746147fd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6080815284608082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86111561508a57600080fd5b8560051b808860a0850137820182810360a090810160208501526150b090820187613f44565b91505063ffffffff8085166040840152808416606084015250969550505050505056fea164736f6c6343000818000a", + Bin: "0x6080604052600e80546001600160401b0319166401000000011790553480156200002857600080fd5b503380600081620000805760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000b357620000b381620000bc565b50505062000167565b336001600160a01b03821603620001165760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000077565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61516480620001776000396000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80635d83d967116100ee57806386fa424611610097578063d8bc7b6811610071578063d8bc7b68146103f6578063ddbe4f8214610409578063e29581aa1461041e578063f2fde38b1461043357600080fd5b806386fa42461461039b5780638da5cb5b146103ae5780639cb7c5f4146103d657600080fd5b8063715f5295116100c8578063715f52951461036d57806373ac22b41461038057806379ba50971461039357600080fd5b80635d83d967146103325780635e65e3091461034557806366acaa331461035857600080fd5b8063235374051161015b5780632c01a1e8116101355780632c01a1e8146102cb578063398f3773146102de5780633f2a13c9146102f157806350c946fe1461031257600080fd5b80632353740514610285578063275459f2146102a55780632a852933146102b857600080fd5b80631d05394c1161018c5780631d05394c1461023b578063214502431461025057806322bdbcbc1461026557600080fd5b80630fe5800a146101b357806312570011146101d9578063181f5a77146101fc575b600080fd5b6101c66101c1366004613f46565b610446565b6040519081526020015b60405180910390f35b6101ec6101e7366004613faa565b61047a565b60405190151581526020016101d0565b604080518082018252601a81527f4361706162696c6974696573526567697374727920312e302e30000000000000602082015290516101d09190614031565b61024e610249366004614089565b610487565b005b61025861069c565b6040516101d0919061420b565b6102786102733660046142a6565b6107f9565b6040516101d091906142fe565b6102986102933660046142a6565b6108e6565b6040516101d09190614311565b61024e6102b3366004614089565b61092a565b61024e6102c6366004614345565b610a01565b61024e6102d9366004614089565b610ae1565b61024e6102ec366004614089565b610d7d565b6103046102ff3660046143e7565b610f3c565b6040516101d0929190614411565b610325610320366004613faa565b611128565b6040516101d091906144d6565b61024e610340366004614089565b611202565b61024e610353366004614089565b6112f7565b610360611a1f565b6040516101d091906144e9565b61024e61037b366004614089565b611c02565b61024e61038e366004614089565b611cb4565b61024e612182565b61024e6103a936600461455e565b61227f565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d0565b6103e96103e4366004613faa565b6125bf565b6040516101d091906146ad565b61024e6104043660046146c0565b6127fa565b6104116128c4565b6040516101d09190614746565b6104266129b8565b6040516101d091906147bb565b61024e610441366004614854565b612ac1565b6000828260405160200161045b929190614411565b6040516020818303038152906040528051906020012090505b92915050565b6000610474600583612ad5565b61048f612af0565b60005b818110156106975760008383838181106104ae576104ae61486f565b90506020020160208101906104c391906142a6565b63ffffffff8181166000908152600d60209081526040808320805464010000000081049095168085526001820190935290832094955093909290916a010000000000000000000090910460ff16905b61051b83612b73565b8110156105bb57811561057157600c60006105368584612b7d565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556105b3565b6105b18663ffffffff16600c60006105928588612b7d90919063ffffffff16565b8152602001908152602001600020600401612b8990919063ffffffff16565b505b600101610512565b508354640100000000900463ffffffff16600003610612576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff861660048201526024015b60405180910390fd5b63ffffffff85166000818152600d6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffff00000000000000000000001690558051938452908301919091527ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c1581703651910160405180910390a15050505050806001019050610492565b505050565b600e54606090640100000000900463ffffffff1660006106bd6001836148cd565b63ffffffff1667ffffffffffffffff8111156106db576106db613de0565b60405190808252806020026020018201604052801561076257816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816106f95790505b509050600060015b8363ffffffff168163ffffffff1610156107d65763ffffffff8082166000908152600d602052604090205416156107ce576107a481612b95565b8383815181106107b6576107b661486f565b6020026020010181905250816107cb906148ea565b91505b60010161076a565b506107e26001846148cd565b63ffffffff1681146107f2578082525b5092915050565b60408051808201909152600081526060602082015263ffffffff82166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161085d90614922565b80601f016020809104026020016040519081016040528092919081815260200182805461088990614922565b80156108d65780601f106108ab576101008083540402835291602001916108d6565b820191906000526020600020905b8154815290600101906020018083116108b957829003601f168201915b5050505050815250509050919050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c081019190915261047482612b95565b610932612af0565b60005b63ffffffff811682111561069757600083838363ffffffff1681811061095d5761095d61486f565b905060200201602081019061097291906142a6565b63ffffffff81166000908152600b6020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559192506109bd6001830182613d73565b505060405163ffffffff8216907fa59268ca81d40429e65ccea5385b59cf2d3fc6519371dee92f8eb1dae5107a7a90600090a2506109fa81614975565b9050610935565b610a09612af0565b63ffffffff8088166000908152600d60205260408120805490926401000000009091041690819003610a6f576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff8a166004820152602401610609565b610ad6888888886040518060a001604052808f63ffffffff16815260200187610a9790614975565b63ffffffff811682528b15156020830152895460ff6a01000000000000000000009091048116151560408401528b166060909201919091529650612e60565b505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d77576000848483818110610b1b57610b1b61486f565b602090810292909201356000818152600c90935260409092206001810154929350919050610b78576040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260048101839052602401610609565b6000610b8682600401612b73565b1115610bdb57610b996004820184612b7d565b6040517f60a6d89800000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101839052604401610609565b805468010000000000000000900463ffffffff1615610c435780546040517f60b9df730000000000000000000000000000000000000000000000000000000081526801000000000000000090910463ffffffff16600482015260248101839052604401610609565b83158015610c7d5750805463ffffffff166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15610cb6576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6001810154610cc790600790612b89565b506002810154610cd990600990612b89565b506000828152600c6020526040812080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815560018101829055600281018290559060048201818181610d2e8282613dad565b5050505050507f5254e609a97bab37b7cc79fe128f85c097bd6015c6e1624ae0ba392eb975320582604051610d6591815260200190565b60405180910390a15050600101610aff565b50505050565b610d85612af0565b60005b81811015610697576000838383818110610da457610da461486f565b9050602002810190610db69190614998565b610dbf906149d6565b805190915073ffffffffffffffffffffffffffffffffffffffff16610e10576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815263ffffffff9095166000818152600b909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251919290916001820190610e9c9082614a90565b5050600e8054909150600090610eb79063ffffffff16614975565b91906101000a81548163ffffffff021916908363ffffffff160217905550816000015173ffffffffffffffffffffffffffffffffffffffff168163ffffffff167f78e94ca80be2c30abc061b99e7eb8583b1254781734b1e3ce339abb57da2fe8e8460200151604051610f2a9190614031565b60405180910390a35050600101610d88565b63ffffffff8083166000908152600d60209081526040808320805464010000000090049094168084526001909401825280832085845260030190915281208054606093849390929091610f8e90614922565b80601f0160208091040260200160405190810160405280929190818152602001828054610fba90614922565b80156110075780601f10610fdc57610100808354040283529160200191611007565b820191906000526020600020905b815481529060010190602001808311610fea57829003601f168201915b5050506000888152600260208190526040909120015492935060609262010000900473ffffffffffffffffffffffffffffffffffffffff1615915061111a905057600086815260026020819052604091829020015490517f8318ed5d00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526201000090910473ffffffffffffffffffffffffffffffffffffffff1690638318ed5d90602401600060405180830381865afa1580156110d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111179190810190614baa565b90505b9093509150505b9250929050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c08101919091526040805160e0810182526000848152600c6020908152838220805463ffffffff8082168652640100000000820481168487018190526801000000000000000090920416858701526001820154606086015260028201546080860152835260030190529190912060a08201906111d790613685565b81526020016111fa600c6000868152602001908152602001600020600401613685565b905292915050565b61120a612af0565b60005b818110156106975760008383838181106112295761122961486f565b905060200201359050611246816003612ad590919063ffffffff16565b61127f576040517fe181733f00000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b61128a600582613692565b6112c3576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b60405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a25060010161120d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d775760008484838181106113315761133161486f565b90506020028101906113439190614c18565b61134c90614c4c565b6040808201516000908152600c6020908152828220805463ffffffff168352600b82528383208451808601909552805473ffffffffffffffffffffffffffffffffffffffff16855260018101805496975091959394939092840191906113b190614922565b80601f01602080910402602001604051908101604052809291908181526020018280546113dd90614922565b801561142a5780601f106113ff5761010080835404028352916020019161142a565b820191906000526020600020905b81548152906001019060200180831161140d57829003601f168201915b50505091909252505050600183015490915061147a5782604001516040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b8415801561149f5750805173ffffffffffffffffffffffffffffffffffffffff163314155b156114d8576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6020830151611513576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018201546020840151811461159457602084015161153490600790612ad5565b1561156b576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208401516001840155611580600782612b89565b50602084015161159290600790613692565b505b606084015180516000036115d657806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614d1f565b835460009085906004906115f790640100000000900463ffffffff16614975565b91906101000a81548163ffffffff021916908363ffffffff1602179055905060005b82518110156116dc5761164f8382815181106116375761163761486f565b60200260200101516003612ad590919063ffffffff16565b61168757826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614d1f565b6116d383828151811061169c5761169c61486f565b60200260200101518760030160008563ffffffff1663ffffffff16815260200190815260200160002061369290919063ffffffff16565b50600101611619565b50845468010000000000000000900463ffffffff16801561183d5763ffffffff8082166000908152600d60209081526040808320805464010000000090049094168352600190930181528282206002018054845181840281018401909552808552929392909183018282801561177157602002820191906000526020600020905b81548152602001906001019080831161175d575b5050505050905060005b815181101561183a576117d08282815181106117995761179961486f565b60200260200101518960030160008763ffffffff1663ffffffff168152602001908152602001600020612ad590919063ffffffff16565b611832578181815181106117e6576117e661486f565b6020026020010151836040517f03dcd86200000000000000000000000000000000000000000000000000000000815260040161060992919091825263ffffffff16602082015260400190565b60010161177b565b50505b600061184b87600401613685565b905060005b81518163ffffffff161015611991576000828263ffffffff16815181106118795761187961486f565b60209081029190910181015163ffffffff8082166000908152600d8452604080822080546401000000009004909316825260019092018452818120600201805483518187028101870190945280845293955090939192909183018282801561190057602002820191906000526020600020905b8154815260200190600101908083116118ec575b5050505050905060005b815181101561197d5761195f8282815181106119285761192861486f565b60200260200101518c60030160008a63ffffffff1663ffffffff168152602001908152602001600020612ad590919063ffffffff16565b611975578181815181106117e6576117e661486f565b60010161190a565b5050508061198a90614975565b9050611850565b50875187547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90911690811788556040808a015160028a018190556020808c01518351928352908201527f4b5b465e22eea0c3d40c30e936643245b80d19b2dcf75788c0699fe8d8db645b910160405180910390a25050505050505050806001019050611315565b600e5460609063ffffffff166000611a386001836148cd565b63ffffffff1667ffffffffffffffff811115611a5657611a56613de0565b604051908082528060200260200182016040528015611a9c57816020015b604080518082019091526000815260606020820152815260200190600190039081611a745790505b509050600060015b8363ffffffff168163ffffffff161015611bec5763ffffffff81166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611be45763ffffffff81166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191611b3890614922565b80601f0160208091040260200160405190810160405280929190818152602001828054611b6490614922565b8015611bb15780601f10611b8657610100808354040283529160200191611bb1565b820191906000526020600020905b815481529060010190602001808311611b9457829003601f168201915b505050505081525050838381518110611bcc57611bcc61486f565b602002602001018190525081611be1906148ea565b91505b600101611aa4565b50600e546107e29060019063ffffffff166148cd565b611c0a612af0565b60005b81811015610697576000838383818110611c2957611c2961486f565b9050602002810190611c3b9190614d63565b611c4490614da6565b90506000611c5a82600001518360200151610446565b9050611c67600382613692565b611ca0576040517febf5255100000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b611caa818361369e565b5050600101611c0d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d77576000848483818110611cee57611cee61486f565b9050602002810190611d009190614c18565b611d0990614c4c565b805163ffffffff166000908152600b602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191611d5f90614922565b80601f0160208091040260200160405190810160405280929190818152602001828054611d8b90614922565b8015611dd85780601f10611dad57610100808354040283529160200191611dd8565b820191906000526020600020905b815481529060010190602001808311611dbb57829003601f168201915b50505091909252505081519192505073ffffffffffffffffffffffffffffffffffffffff16611e3e5781516040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff9091166004820152602401610609565b83158015611e635750805173ffffffffffffffffffffffffffffffffffffffff163314155b15611e9c576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6040808301516000908152600c60205220600181015415611ef15782604001516040517f5461848300000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b6040830151611f345782604001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b60208301511580611f5157506020830151611f5190600790612ad5565b15611f88576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608301518051600003611fca57806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614d1f565b81548290600490611fe890640100000000900463ffffffff16614975565b82546101009290920a63ffffffff818102199093169183160217909155825464010000000090041660005b82518110156120be576120318382815181106116375761163761486f565b61206957826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614d1f565b6120b583828151811061207e5761207e61486f565b60200260200101518560030160008563ffffffff1663ffffffff16815260200190815260200160002061369290919063ffffffff16565b50600101612013565b50845183547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff91821617845560408601516002850155602086015160018501819055612114916007919061369216565b50604085015161212690600990613692565b50845160408087015160208089015183519283529082015263ffffffff909216917f74becb12a5e8fd0e98077d02dfba8f647c9670c9df177e42c2418cf17a636f05910160405180910390a25050505050806001019050611cd2565b60015473ffffffffffffffffffffffffffffffffffffffff163314612203576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610609565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b8281146122c2576040517fab8b67c60000000000000000000000000000000000000000000000000000000081526004810184905260248101829052604401610609565b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156125b75760008686838181106122fa576122fa61486f565b905060200201602081019061230f91906142a6565b63ffffffff81166000908152600b6020526040902080549192509073ffffffffffffffffffffffffffffffffffffffff1661237e576040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff83166004820152602401610609565b60008686858181106123925761239261486f565b90506020028101906123a49190614998565b6123ad906149d6565b805190915073ffffffffffffffffffffffffffffffffffffffff166123fe576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815473ffffffffffffffffffffffffffffffffffffffff16331480159061243b57503373ffffffffffffffffffffffffffffffffffffffff861614155b15612474576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b8051825473ffffffffffffffffffffffffffffffffffffffff90811691161415806124f057506020808201516040516124ad9201614031565b60405160208183030381529060405280519060200120826001016040516020016124d79190614e4c565b6040516020818303038152906040528051906020012014155b156125a957805182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020810151600183019061254a9082614a90565b50806000015173ffffffffffffffffffffffffffffffffffffffff168363ffffffff167f86f41145bde5dd7f523305452e4aad3685508c181432ec733d5f345009358a2883602001516040516125a09190614031565b60405180910390a35b5050508060010190506122de565b505050505050565b6126006040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b6040805160e0810182528381526000848152600260209081529290208054919283019161262c90614922565b80601f016020809104026020016040519081016040528092919081815260200182805461265890614922565b80156126a55780601f1061267a576101008083540402835291602001916126a5565b820191906000526020600020905b81548152906001019060200180831161268857829003601f168201915b505050505081526020016002600085815260200190815260200160002060010180546126d090614922565b80601f01602080910402602001604051908101604052809291908181526020018280546126fc90614922565b80156127495780601f1061271e57610100808354040283529160200191612749565b820191906000526020600020905b81548152906001019060200180831161272c57829003601f168201915b50505091835250506000848152600260208181526040909220015491019060ff16600381111561277b5761277b6145ca565b815260008481526002602081815260409092200154910190610100900460ff1660018111156127ac576127ac6145ca565b81526000848152600260208181526040928390209091015462010000900473ffffffffffffffffffffffffffffffffffffffff1690830152016127f0600585612ad5565b1515905292915050565b612802612af0565b600e805460009164010000000090910463ffffffff1690600461282483614975565b82546101009290920a63ffffffff81810219909316918316021790915581166000818152600d602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001684179055815160a08101835292835260019083015286151590820152841515606082015260ff841660808201529091506128ba908990899089908990612e60565b5050505050505050565b606060006128d26003613685565b90506000815167ffffffffffffffff8111156128f0576128f0613de0565b60405190808252806020026020018201604052801561296257816020015b61294f6040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b81526020019060019003908161290e5790505b50905060005b82518110156107f2576129938382815181106129865761298661486f565b60200260200101516125bf565b8282815181106129a5576129a561486f565b6020908102919091010152600101612968565b606060006129c66009613685565b90506000815167ffffffffffffffff8111156129e4576129e4613de0565b604051908082528060200260200182016040528015612a6b57816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181612a025790505b50905060005b82518110156107f257612a9c838281518110612a8f57612a8f61486f565b6020026020010151611128565b828281518110612aae57612aae61486f565b6020908102919091010152600101612a71565b612ac9612af0565b612ad281613886565b50565b600081815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612b71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610609565b565b6000610474825490565b6000612ae9838361397b565b6000612ae983836139a5565b6040805160e0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840181905260c084015263ffffffff8581168352600d8252848320805464010000000090049091168084526001909101825284832060028101805487518186028101860190985280885295969295919493909190830182828015612c4657602002820191906000526020600020905b815481526020019060010190808311612c32575b505050505090506000815167ffffffffffffffff811115612c6957612c69613de0565b604051908082528060200260200182016040528015612caf57816020015b604080518082019091526000815260606020820152815260200190600190039081612c875790505b50905060005b8151811015612dc7576040518060400160405280848381518110612cdb57612cdb61486f565b60200260200101518152602001856003016000868581518110612d0057612d0061486f565b602002602001015181526020019081526020016000208054612d2190614922565b80601f0160208091040260200160405190810160405280929190818152602001828054612d4d90614922565b8015612d9a5780601f10612d6f57610100808354040283529160200191612d9a565b820191906000526020600020905b815481529060010190602001808311612d7d57829003601f168201915b5050505050815250828281518110612db457612db461486f565b6020908102919091010152600101612cb5565b506040805160e08101825263ffffffff8089166000818152600d6020818152868320548086168752948b168187015260ff680100000000000000008604811697870197909752690100000000000000000085048716151560608701529290915290526a010000000000000000000090049091161515608082015260a08101612e4e85613685565b81526020019190915295945050505050565b805163ffffffff9081166000908152600d602090815260408083208286015190941683526001909301905220608082015160ff161580612eb2575060808201518590612ead906001614efa565b60ff16115b15612efb5760808201516040517f25b4d61800000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101869052604401610609565b6001826020015163ffffffff161115612fe357815163ffffffff166000908152600d602090815260408220908401516001918201918391612f3c91906148cd565b63ffffffff1663ffffffff168152602001908152602001600020905060005b612f6482612b73565b811015612fe057612f93846000015163ffffffff16600c60006105928587600001612b7d90919063ffffffff16565b50600c6000612fa28484612b7d565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff169055600101612f5b565b50505b60005b8581101561321d576130138787838181106130035761300361486f565b8592602090910201359050613692565b61307457825187878381811061302b5761302b61486f565b6040517f636e405700000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8260600151156131cb57825163ffffffff16600c600089898581811061309c5761309c61486f565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff16148015906131165750600c60008888848181106130e7576130e761486f565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff1615155b1561317857825187878381811061312f5761312f61486f565b6040517f60b9df7300000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8251600c60008989858181106131905761319061486f565b90506020020135815260200190815260200160002060000160086101000a81548163ffffffff021916908363ffffffff160217905550613215565b82516132139063ffffffff16600c60008a8a868181106131ed576131ed61486f565b90506020020135815260200190815260200160002060040161369290919063ffffffff16565b505b600101612fe6565b5060005b8381101561362b573685858381811061323c5761323c61486f565b905060200281019061324e9190614998565b905061325c60038235612ad5565b613295576040517fe181733f00000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b6132a160058235612ad5565b156132db576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b80356000908152600384016020526040812080546132f890614922565b905011156133445783516040517f3927d08000000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015281356024820152604401610609565b60005b8781101561344e576133eb8235600c60008c8c8681811061336a5761336a61486f565b9050602002013581526020019081526020016000206003016000600c60008e8e8881811061339a5761339a61486f565b90506020020135815260200190815260200160002060000160049054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020612ad590919063ffffffff16565b613446578888828181106134015761340161486f565b6040517fa7e792500000000000000000000000000000000000000000000000000000000081526020909102929092013560048301525082356024820152604401610609565b600101613347565b506002830180546001810182556000918252602091829020833591015561347790820182614f13565b82356000908152600386016020526040902091613495919083614f78565b50604080850151855163ffffffff9081166000908152600d602090815284822080549415156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff90951694909417909355606088015188518316825284822080549115156a0100000000000000000000027fffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff9092169190911790556080880151885183168252848220805460ff9290921668010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff909216919091179055828801805189518416835294909120805494909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9094169390931790558551915161362292918435908c908c906135e890880188614f13565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9892505050565b50600101613221565b50815160208301516040517ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c15817036519261367592909163ffffffff92831681529116602082015260400190565b60405180910390a1505050505050565b60606000612ae983613b79565b6000612ae98383613bd5565b608081015173ffffffffffffffffffffffffffffffffffffffff1615613740576136ec81608001517f78bea72100000000000000000000000000000000000000000000000000000000613c24565b6137405760808101516040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610609565b60008281526002602052604090208151829190819061375f9082614a90565b50602082015160018201906137749082614a90565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660018360038111156137b6576137b66145ca565b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156137fd576137fd6145ca565b0217905550608091909101516002909101805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff90921691909117905560405182907f04f0a9bcf3f3a3b42a4d7ca081119755f82ebe43e0d30c8f7292c4fe0dc4a2ae90600090a25050565b3373ffffffffffffffffffffffffffffffffffffffff821603613905576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610609565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008260000182815481106139925761399261486f565b9060005260206000200154905092915050565b60008181526001830160205260408120548015613a8e5760006139c9600183615093565b85549091506000906139dd90600190615093565b9050818114613a425760008660000182815481106139fd576139fd61486f565b9060005260206000200154905080876000018481548110613a2057613a2061486f565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613a5357613a536150a6565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610474565b6000915050610474565b6000848152600260208190526040909120015462010000900473ffffffffffffffffffffffffffffffffffffffff16156125b757600084815260026020819052604091829020015490517ffba64a7c0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169063fba64a7c90613b3f908690869086908b908d906004016150d5565b600060405180830381600087803b158015613b5957600080fd5b505af1158015613b6d573d6000803e3d6000fd5b50505050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015613bc957602002820191906000526020600020905b815481526020019060010190808311613bb5575b50505050509050919050565b6000818152600183016020526040812054613c1c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610474565b506000610474565b6000613c2f83613c40565b8015612ae95750612ae98383613ca4565b6000613c6c827f01ffc9a700000000000000000000000000000000000000000000000000000000613ca4565b80156104745750613c9d827fffffffff00000000000000000000000000000000000000000000000000000000613ca4565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613d5c575060208210155b8015613d685750600081115b979650505050505050565b508054613d7f90614922565b6000825580601f10613d8f575050565b601f016020900490600052602060002090810190612ad29190613dc7565b5080546000825590600052602060002090810190612ad291905b5b80821115613ddc5760008155600101613dc8565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613e3257613e32613de0565b60405290565b60405160a0810167ffffffffffffffff81118282101715613e3257613e32613de0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613ea257613ea2613de0565b604052919050565b600067ffffffffffffffff821115613ec457613ec4613de0565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613f0157600080fd5b8135613f14613f0f82613eaa565b613e5b565b818152846020838601011115613f2957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613f5957600080fd5b823567ffffffffffffffff80821115613f7157600080fd5b613f7d86838701613ef0565b93506020850135915080821115613f9357600080fd5b50613fa085828601613ef0565b9150509250929050565b600060208284031215613fbc57600080fd5b5035919050565b60005b83811015613fde578181015183820152602001613fc6565b50506000910152565b60008151808452613fff816020860160208601613fc3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612ae96020830184613fe7565b60008083601f84011261405657600080fd5b50813567ffffffffffffffff81111561406e57600080fd5b6020830191508360208260051b850101111561112157600080fd5b6000806020838503121561409c57600080fd5b823567ffffffffffffffff8111156140b357600080fd5b6140bf85828601614044565b90969095509350505050565b60008151808452602080850194506020840160005b838110156140fc578151875295820195908201906001016140e0565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b84811015614184578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018952815180518452840151604085850181905261417081860183613fe7565b9a86019a9450505090830190600101614124565b5090979650505050505050565b600063ffffffff8083511684528060208401511660208501525060ff604083015116604084015260608201511515606084015260808201511515608084015260a082015160e060a08501526141e960e08501826140cb565b905060c083015184820360c08601526142028282614107565b95945050505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614280577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261426e858351614191565b94509285019290850190600101614234565b5092979650505050505050565b803563ffffffff811681146142a157600080fd5b919050565b6000602082840312156142b857600080fd5b612ae98261428d565b73ffffffffffffffffffffffffffffffffffffffff815116825260006020820151604060208501526142f66040850182613fe7565b949350505050565b602081526000612ae960208301846142c1565b602081526000612ae96020830184614191565b803580151581146142a157600080fd5b803560ff811681146142a157600080fd5b600080600080600080600060a0888a03121561436057600080fd5b6143698861428d565b9650602088013567ffffffffffffffff8082111561438657600080fd5b6143928b838c01614044565b909850965060408a01359150808211156143ab57600080fd5b506143b88a828b01614044565b90955093506143cb905060608901614324565b91506143d960808901614334565b905092959891949750929550565b600080604083850312156143fa57600080fd5b6144038361428d565b946020939093013593505050565b6040815260006144246040830185613fe7565b82810360208401526142028185613fe7565b600063ffffffff808351168452602081818501511681860152816040850151166040860152606084015160608601526080840151608086015260a0840151915060e060a086015261448a60e08601836140cb565b60c08581015187830391880191909152805180835290830193506000918301905b808310156144cb57845182529383019360019290920191908301906144ab565b509695505050505050565b602081526000612ae96020830184614436565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614280577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261454c8583516142c1565b94509285019290850190600101614512565b6000806000806040858703121561457457600080fd5b843567ffffffffffffffff8082111561458c57600080fd5b61459888838901614044565b909650945060208701359150808211156145b157600080fd5b506145be87828801614044565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b805182526000602082015160e0602085015261461860e0850182613fe7565b9050604083015184820360408601526146318282613fe7565b915050606083015160048110614649576146496145ca565b6060850152608083015160028110614663576146636145ca565b8060808601525060a083015161469160a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c08301516146a560c086018215159052565b509392505050565b602081526000612ae960208301846145f9565b600080600080600080600060a0888a0312156146db57600080fd5b873567ffffffffffffffff808211156146f357600080fd5b6146ff8b838c01614044565b909950975060208a013591508082111561471857600080fd5b506147258a828b01614044565b9096509450614738905060408901614324565b92506143cb60608901614324565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614280577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526147a98583516145f9565b9450928501929085019060010161476f565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614280577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261481e858351614436565b945092850192908501906001016147e4565b803573ffffffffffffffffffffffffffffffffffffffff811681146142a157600080fd5b60006020828403121561486657600080fd5b612ae982614830565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff8281168282160390808211156107f2576107f261489e565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361491b5761491b61489e565b5060010190565b600181811c9082168061493657607f821691505b60208210810361496f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600063ffffffff80831681810361498e5761498e61489e565b6001019392505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126149cc57600080fd5b9190910192915050565b6000604082360312156149e857600080fd5b6040516040810167ffffffffffffffff8282108183111715614a0c57614a0c613de0565b81604052614a1985614830565b83526020850135915080821115614a2f57600080fd5b50614a3c36828601613ef0565b60208301525092915050565b601f821115610697576000816000526020600020601f850160051c81016020861015614a715750805b601f850160051c820191505b818110156125b757828155600101614a7d565b815167ffffffffffffffff811115614aaa57614aaa613de0565b614abe81614ab88454614922565b84614a48565b602080601f831160018114614b115760008415614adb5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556125b7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614b5e57888601518255948401946001909101908401614b3f565b5085821015614b9a57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215614bbc57600080fd5b815167ffffffffffffffff811115614bd357600080fd5b8201601f81018413614be457600080fd5b8051614bf2613f0f82613eaa565b818152856020838501011115614c0757600080fd5b614202826020830160208601613fc3565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126149cc57600080fd5b600060808236031215614c5e57600080fd5b614c66613e0f565b614c6f8361428d565b81526020808401358183015260408401356040830152606084013567ffffffffffffffff80821115614ca057600080fd5b9085019036601f830112614cb357600080fd5b813581811115614cc557614cc5613de0565b8060051b9150614cd6848301613e5b565b8181529183018401918481019036841115614cf057600080fd5b938501935b83851015614d0e57843582529385019390850190614cf5565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614d5757835183529284019291840191600101614d3b565b50909695505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff618336030181126149cc57600080fd5b8035600281106142a157600080fd5b600060a08236031215614db857600080fd5b614dc0613e38565b823567ffffffffffffffff80821115614dd857600080fd5b614de436838701613ef0565b83526020850135915080821115614dfa57600080fd5b50614e0736828601613ef0565b602083015250604083013560048110614e1f57600080fd5b6040820152614e3060608401614d97565b6060820152614e4160808401614830565b608082015292915050565b6000602080835260008454614e6081614922565b8060208701526040600180841660008114614e825760018114614ebc57614eec565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550614eec565b89600052602060002060005b85811015614ee35781548b8201860152908301908801614ec8565b8a016040019650505b509398975050505050505050565b60ff81811683821601908111156104745761047461489e565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614f4857600080fd5b83018035915067ffffffffffffffff821115614f6357600080fd5b60200191503681900382131561112157600080fd5b67ffffffffffffffff831115614f9057614f90613de0565b614fa483614f9e8354614922565b83614a48565b6000601f841160018114614ff65760008515614fc05750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561508c565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156150455786850135825560209485019460019092019101615025565b5086821015615080577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b818103818111156104745761047461489e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6080815284608082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86111561510e57600080fd5b8560051b808860a0850137820182810360a0908101602085015261513490820187613fe7565b91505063ffffffff8085166040840152808416606084015250969550505050505056fea164736f6c6343000818000a", } var CapabilitiesRegistryABI = CapabilitiesRegistryMetaData.ABI diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 30396c12e7..26ad8f3315 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,5 +1,5 @@ GETH_VERSION: 1.13.8 -capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin 7e95d72f24940f08ada0ee3b85d894d6bfccfd6c8a3e0ceeff65bae52c899d54 +capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin 2c8947475e3db9e4feadde2c4325bb093f905e352879518dadac470f33e000ce feeds_consumer: ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin 8c3a2b18a80be41e7c40d2bc3a4c8d1b5e18d55c1fd20ad5af68cebb66109fc5 forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin 45d9b866c64b41c1349a90b6764aee42a6d078b454d38f369b5fe02b23b9d16e ocr3_capability: ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.bin 8bf0f53f222efce7143dea6134552eb26ea1eef845407b4475a0d79b7d7ba9f8 From bf2b72d164f8cc714cfbf57df59a3f3bf952b153 Mon Sep 17 00:00:00 2001 From: Domino Valdano Date: Tue, 27 Aug 2024 08:06:02 -0700 Subject: [PATCH 178/432] [BCF-3250]: Fix FilterLog error handling in LogPoller (#11654) * Fix error handling of results from FilterLogs() This was logging a critical error when any error other than an rpc error happened (eg networking issue, or context timeout) when batch_size was = 1. Should have only been logging at that level for rpc error "Limit Exceeded" More specifically, there are 4 interrelated issues addressed in this PR: 1. The logic for whether to retry or reduce batch size was wrong--so it was retrying with reduced batch size unnecessariy for transient errors 2. The error was being matched against a concrete JsonError type which is very fragile due to the number of types the type gets wrapped and re-formatted while it's propagated up the stack from geth through different layers. (It may have matched only in simulated geth but not with a live rpc server). Now it's matched against rpc.Error interface defined in geth for this purpose, which should work more generally. 3. There was a bug in the test for this feature (related to pointer indirection) which caused a false positive PASS 4. In addition to the rate limiting error returned by infura, alchemy, etc. I've added a similar error code geth can return when the request size is too large Also: A new subtest has been added to make sure that unrelated errors do not log this error message * pnpm changeset * Fix whitespace for lint * Add ErrorData() implementation to satisfy rpc.DataError This will make our JsonError fully parallel with jsonError, so they can both be treated in the same way. * Add more sophisticated classificaiton of FilterLogs error codes There are a lot of different error codes and messages which can be returned depending on what type of rpc server it is. Classification has been expanded to include both the codes and regex matching of the messages, and moved into client/errors.go where a similar process happens to disambiguate SendTx error * Add TooManyResults to docs example & full-config.toml * Add tests for IsTooManyResults() --- .changeset/poor-pumas-occur.md | 5 + core/chains/evm/client/errors.go | 105 ++++++++++- core/chains/evm/client/errors_test.go | 85 +++++++++ core/chains/evm/client/helpers_test.go | 3 + .../evm/client/simulated_backend_client.go | 4 +- .../evm/config/chain_scoped_client_errors.go | 1 + core/chains/evm/config/config.go | 1 + core/chains/evm/config/config_test.go | 2 + core/chains/evm/config/toml/config.go | 4 + core/chains/evm/logpoller/log_poller.go | 16 +- core/chains/evm/logpoller/log_poller_test.go | 165 +++++++++++------- core/chains/legacyevm/chain.go | 1 + core/config/docs/chains-evm.toml | 2 + core/services/chainlink/config_test.go | 2 + .../chainlink/testdata/config-full.toml | 1 + core/web/resolver/testdata/config-full.toml | 1 + docs/CONFIG.md | 7 + 17 files changed, 331 insertions(+), 74 deletions(-) create mode 100644 .changeset/poor-pumas-occur.md diff --git a/.changeset/poor-pumas-occur.md b/.changeset/poor-pumas-occur.md new file mode 100644 index 0000000000..df3e1e2f5f --- /dev/null +++ b/.changeset/poor-pumas-occur.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#bugfix More robust error handling in LogPoller, including no more misleading CRITICAL errors emitted under non-critical conditions diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index 5980b0dd96..76411cb040 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" pkgerrors "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-common/pkg/logger" @@ -62,6 +63,7 @@ const ( Fatal ServiceUnavailable TerminallyStuck + TooManyResults ) type ClientErrors map[int]*regexp.Regexp @@ -298,6 +300,7 @@ func ClientErrorRegexes(errsRegex config.ClientErrors) *ClientErrors { TransactionAlreadyMined: regexp.MustCompile(errsRegex.TransactionAlreadyMined()), Fatal: regexp.MustCompile(errsRegex.Fatal()), ServiceUnavailable: regexp.MustCompile(errsRegex.ServiceUnavailable()), + TooManyResults: regexp.MustCompile(errsRegex.TooManyResults()), } } @@ -457,6 +460,11 @@ func isFatalSendError(err error) bool { return false } +var ( + _ rpc.Error = JsonError{} + _ rpc.DataError = JsonError{} +) + // go-ethereum@v1.10.0/rpc/json.go type JsonError struct { Code int `json:"code"` @@ -471,7 +479,17 @@ func (err JsonError) Error() string { return err.Message } -func (err *JsonError) String() string { +// To satisfy rpc.Error interface +func (err JsonError) ErrorCode() int { + return err.Code +} + +// To satisfy rpc.DataError +func (err JsonError) ErrorData() interface{} { + return err.Data +} + +func (err JsonError) String() string { return fmt.Sprintf("json-rpc error { Code = %d, Message = '%s', Data = '%v' }", err.Code, err.Message, err.Data) } @@ -610,3 +628,88 @@ func ClassifySendError(err error, clientErrors config.ClientErrors, lggr logger. lggr.Criticalw("Unknown error encountered when sending transaction", "err", err, "etx", tx) return commonclient.Unknown } + +var infura = ClientErrors{ + TooManyResults: regexp.MustCompile(`(: |^)query returned more than [0-9]+ results. Try with this block range \[0x[0-9A-F]+, 0x[0-9A-F]+\].$`), +} + +var alchemy = ClientErrors{ + TooManyResults: regexp.MustCompile(`(: |^)Log response size exceeded. You can make eth_getLogs requests with up to a [0-9A-Z]+ block range and no limit on the response size, or you can request any block range with a cap of [0-9A-Z]+ logs in the response. Based on your parameters and the response size limit, this block range should work: \[0x[0-9a-f]+, 0x[0-9a-f]+\]$`), +} + +var quicknode = ClientErrors{ + TooManyResults: regexp.MustCompile(`(: |^)eth_getLogs is limited to a [0-9,]+ range$`), +} + +var simplyvc = ClientErrors{ + TooManyResults: regexp.MustCompile(`too wide blocks range, the limit is [0-9,]+$`), +} + +var drpc = ClientErrors{ + TooManyResults: regexp.MustCompile(`(: |^)requested too many blocks from [0-9]+ to [0-9]+, maximum is set to [0-9,]+$`), +} + +// Linkpool, Blockdaemon, and Chainstack all return "request timed out" if the log results are too large for them to process +var defaultClient = ClientErrors{ + TooManyResults: regexp.MustCompile(`request timed out`), +} + +// JSON-RPC error codes which can indicate a refusal of the server to process an eth_getLogs request because the result set is too large +const ( + jsonRpcServerError = -32000 // Server error. SimplyVC uses this error code when too many results are returned + + // Server timeout. When the rpc server has its own limit on how long it can take to compile the results + // Examples: Linkpool, Chainstack, Block Daemon + jsonRpcTimedOut = -32002 + + // See: https://github.com/ethereum/go-ethereum/blob/master/rpc/errors.go#L63 + // Can occur if the rpc server is configured with a maximum byte limit on the response size of batch requests + jsonRpcResponseTooLarge = -32003 + + // Not implemented in geth by default, but is defined in EIP 1474 and implemented by infura and some other 3rd party rpc servers + // See: https://community.infura.io/t/getlogs-error-query-returned-more-than-1000-results/358/5 + jsonRpcLimitExceeded = -32005 // See also: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1474.md + + jsonRpcInvalidParams = -32602 // Invalid method params. Returned by alchemy if the block range is too large or there are too many results to return + + jsonRpcQuicknodeTooManyResults = -32614 // Undocumented error code used by Quicknode for too many results error +) + +func IsTooManyResults(err error, clientErrors config.ClientErrors) bool { + var rpcErr rpc.Error + + if !pkgerrors.As(err, &rpcErr) { + return false + } + configErrors := ClientErrorRegexes(clientErrors) + if configErrors.ErrIs(rpcErr, TooManyResults) { + return true + } + + switch rpcErr.ErrorCode() { + case jsonRpcResponseTooLarge: + return true + case jsonRpcLimitExceeded: + if infura.ErrIs(rpcErr, TooManyResults) { + return true + } + case jsonRpcInvalidParams: + if alchemy.ErrIs(rpcErr, TooManyResults) { + return true + } + case jsonRpcQuicknodeTooManyResults: + if quicknode.ErrIs(rpcErr, TooManyResults) { + return true + } + case jsonRpcTimedOut: + if defaultClient.ErrIs(rpcErr, TooManyResults) { + return true + } + case jsonRpcServerError: + if simplyvc.ErrIs(rpcErr, TooManyResults) || + drpc.ErrIs(rpcErr, TooManyResults) { + return true + } + } + return false +} diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index 095e291f5e..7d11279d32 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -1,7 +1,9 @@ package client_test import ( + "encoding/json" "errors" + "fmt" "testing" pkgerrors "github.com/pkg/errors" @@ -439,3 +441,86 @@ func Test_Config_Errors(t *testing.T) { assert.False(t, clientErrors.ErrIs(errors.New("some old bollocks"), evmclient.NonceTooLow)) }) } + +func Test_IsTooManyResultsError(t *testing.T) { + customErrors := evmclient.NewTestClientErrors() + + tests := []errorCase{ + {`{ + "code":-32602, + "message":"Log response size exceeded. You can make eth_getLogs requests with up to a 2K block range and no limit on the response size, or you can request any block range with a cap of 10K logs in the response. Based on your parameters and the response size limit, this block range should work: [0x0, 0x133e71]"}`, + true, + "alchemy", + }, {`{ + "code":-32005, + "data":{"from":"0xCB3D","limit":10000,"to":"0x7B737"}, + "message":"query returned more than 10000 results. Try with this block range [0xCB3D, 0x7B737]."}`, + true, + "infura", + }, {`{ + "code":-32002, + "message":"request timed out"}`, + true, + "LinkPool-Blockdaemon-Chainstack", + }, {`{ + "code":-32614, + "message":"eth_getLogs is limited to a 10,000 range"}`, + true, + "Quicknode", + }, {`{ + "code":-32000, + "message":"too wide blocks range, the limit is 100"}`, + true, + "SimplyVC", + }, {`{ + "message":"requested too many blocks from 0 to 16777216, maximum is set to 2048", + "code":-32000}`, + true, + "Drpc", + }, {` + + + + 503 Backend fetch failed + + +

    Error 503 Backend fetch failed

    +

    Backend fetch failed

    +

    Guru Meditation:

    +

    XID: 343710611

    +
    +

    Varnish cache server

    + +`, + false, + "Nirvana Labs"}, // This isn't an error response we can handle, but including for completeness. }, + + {`{ + "code":-32000", + "message":"unrelated server error"}`, + false, + "any", + }, {`{ + "code":-32500, + "message":"unrelated error code"}`, + false, + "any2", + }, {fmt.Sprintf(`{ + "code" : -43106, + "message" : "%s"}`, customErrors.TooManyResults()), + true, + "custom chain with error specified in toml config", + }, + } + + for _, test := range tests { + t.Run(test.network, func(t *testing.T) { + jsonRpcErr := evmclient.JsonError{} + err := json.Unmarshal([]byte(test.message), &jsonRpcErr) + if err == nil { + err = jsonRpcErr + } + assert.Equal(t, test.expect, evmclient.IsTooManyResults(err, &customErrors)) + }) + } +} diff --git a/core/chains/evm/client/helpers_test.go b/core/chains/evm/client/helpers_test.go index e996ccc5e4..67977b180e 100644 --- a/core/chains/evm/client/helpers_test.go +++ b/core/chains/evm/client/helpers_test.go @@ -34,6 +34,7 @@ type TestClientErrors struct { transactionAlreadyMined string fatal string serviceUnavailable string + tooManyResults string } func NewTestClientErrors() TestClientErrors { @@ -52,6 +53,7 @@ func NewTestClientErrors() TestClientErrors { transactionAlreadyMined: "client error transaction already mined", fatal: "client error fatal", serviceUnavailable: "client error service unavailable", + tooManyResults: "client error too many results", } } @@ -77,6 +79,7 @@ func (c *TestClientErrors) L2Full() string { return c.l2Full } func (c *TestClientErrors) TransactionAlreadyMined() string { return c.transactionAlreadyMined } func (c *TestClientErrors) Fatal() string { return c.fatal } func (c *TestClientErrors) ServiceUnavailable() string { return c.serviceUnavailable } +func (c *TestClientErrors) TooManyResults() string { return c.serviceUnavailable } type TestNodePoolConfig struct { NodePollFailureThreshold uint32 diff --git a/core/chains/evm/client/simulated_backend_client.go b/core/chains/evm/client/simulated_backend_client.go index 7dfd39f444..9f8da08e80 100644 --- a/core/chains/evm/client/simulated_backend_client.go +++ b/core/chains/evm/client/simulated_backend_client.go @@ -415,7 +415,7 @@ func (c *SimulatedBackendClient) CallContract(ctx context.Context, msg ethereum. res, err := c.b.CallContract(ctx, msg, blockNumber) if err != nil { dataErr := revertError{} - if errors.Is(err, &dataErr) { + if errors.As(err, &dataErr) { return nil, &JsonError{Data: dataErr.ErrorData(), Message: dataErr.Error(), Code: 3} } // Generic revert, no data @@ -434,7 +434,7 @@ func (c *SimulatedBackendClient) PendingCallContract(ctx context.Context, msg et res, err := c.b.PendingCallContract(ctx, msg) if err != nil { dataErr := revertError{} - if errors.Is(err, &dataErr) { + if errors.As(err, &dataErr) { return nil, &JsonError{Data: dataErr.ErrorData(), Message: dataErr.Error(), Code: 3} } // Generic revert, no data diff --git a/core/chains/evm/config/chain_scoped_client_errors.go b/core/chains/evm/config/chain_scoped_client_errors.go index 53bb04846d..f9d2096e90 100644 --- a/core/chains/evm/config/chain_scoped_client_errors.go +++ b/core/chains/evm/config/chain_scoped_client_errors.go @@ -48,3 +48,4 @@ func (c *clientErrorsConfig) Fatal() string { return derefOrDefault(c.c.Fatal) } func (c *clientErrorsConfig) ServiceUnavailable() string { return derefOrDefault(c.c.ServiceUnavailable) } +func (c *clientErrorsConfig) TooManyResults() string { return derefOrDefault(c.c.TooManyResults) } diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index aeb39cbf8d..e313438038 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -96,6 +96,7 @@ type ClientErrors interface { TransactionAlreadyMined() string Fatal() string ServiceUnavailable() string + TooManyResults() string } type Transactions interface { diff --git a/core/chains/evm/config/config_test.go b/core/chains/evm/config/config_test.go index ba362bda98..678d04425b 100644 --- a/core/chains/evm/config/config_test.go +++ b/core/chains/evm/config/config_test.go @@ -353,6 +353,7 @@ func TestClientErrorsConfig(t *testing.T) { TransactionAlreadyMined: ptr("client error transaction already mined"), Fatal: ptr("client error fatal"), ServiceUnavailable: ptr("client error service unavailable"), + TooManyResults: ptr("client error too many results"), }, } }) @@ -372,6 +373,7 @@ func TestClientErrorsConfig(t *testing.T) { assert.Equal(t, "client error transaction already mined", errors.TransactionAlreadyMined()) assert.Equal(t, "client error fatal", errors.Fatal()) assert.Equal(t, "client error service unavailable", errors.ServiceUnavailable()) + assert.Equal(t, "client error too many results", errors.TooManyResults()) }) } diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 8b926bf087..a22fa31ddf 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -807,6 +807,7 @@ type ClientErrors struct { TransactionAlreadyMined *string `toml:",omitempty"` Fatal *string `toml:",omitempty"` ServiceUnavailable *string `toml:",omitempty"` + TooManyResults *string `toml:",omitempty"` } func (r *ClientErrors) setFrom(f *ClientErrors) bool { @@ -852,6 +853,9 @@ func (r *ClientErrors) setFrom(f *ClientErrors) bool { if v := f.ServiceUnavailable; v != nil { r.ServiceUnavailable = v } + if v := f.TooManyResults; v != nil { + r.TooManyResults = v + } return true } diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index dee5d1d1a5..a4560c967c 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -29,6 +29,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/mathutil" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" ) @@ -113,6 +114,7 @@ type logPoller struct { backfillBatchSize int64 // batch size to use when backfilling finalized logs rpcBatchSize int64 // batch size to use for fallback RPC calls made in GetBlocks logPrunePageSize int64 + clientErrors config.ClientErrors backupPollerNextBlock int64 // next block to be processed by Backup LogPoller backupPollerBlockDelay int64 // how far behind regular LogPoller should BackupLogPoller run. 0 = disabled @@ -143,6 +145,7 @@ type Opts struct { KeepFinalizedBlocksDepth int64 BackupPollerBlockDelay int64 LogPrunePageSize int64 + ClientErrors config.ClientErrors } // NewLogPoller creates a log poller. Note there is an assumption @@ -172,6 +175,7 @@ func NewLogPoller(orm ORM, ec Client, lggr logger.Logger, headTracker HeadTracke rpcBatchSize: opts.RpcBatchSize, keepFinalizedBlocksDepth: opts.KeepFinalizedBlocksDepth, logPrunePageSize: opts.LogPrunePageSize, + clientErrors: opts.ClientErrors, filters: make(map[string]Filter), filterDirty: true, // Always build Filter on first call to cache an empty filter if nothing registered yet. finalityViolated: new(atomic.Bool), @@ -794,8 +798,6 @@ func (lp *logPoller) blocksFromLogs(ctx context.Context, logs []types.Log, endBl return lp.GetBlocksRange(ctx, numbers) } -const jsonRpcLimitExceeded = -32005 // See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1474.md - // backfill will query FilterLogs in batches for logs in the // block range [start, end] and save them to the db. // Retries until ctx cancelled. Will return an error if cancelled @@ -807,13 +809,11 @@ func (lp *logPoller) backfill(ctx context.Context, start, end int64) error { gethLogs, err := lp.ec.FilterLogs(ctx, lp.Filter(big.NewInt(from), big.NewInt(to), nil)) if err != nil { - var rpcErr client.JsonError - if pkgerrors.As(err, &rpcErr) { - if rpcErr.Code != jsonRpcLimitExceeded { - lp.lggr.Errorw("Unable to query for logs", "err", err, "from", from, "to", to) - return err - } + if !client.IsTooManyResults(err, lp.clientErrors) { + lp.lggr.Errorw("Unable to query for logs", "err", err, "from", from, "to", to) + return err } + if batchSize == 1 { lp.lggr.Criticalw("Too many log results in a single block, failed to retrieve logs! Node may be running in a degraded state.", "err", err, "from", from, "to", to, "LogBackfillBatchSize", lp.backfillBatchSize) return err diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index 548711c19b..73302877f9 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -1542,6 +1542,8 @@ type getLogErrData struct { } func TestTooManyLogResults(t *testing.T) { + t.Parallel() + ctx := testutils.Context(t) ec := evmtest.NewEthClientMockWithDefaultChain(t) lggr, obs := logger.TestObserved(t, zapcore.DebugLevel) @@ -1561,89 +1563,126 @@ func TestTooManyLogResults(t *testing.T) { lp := logpoller.NewLogPoller(o, ec, lggr, headTracker, lpOpts) expected := []int64{10, 5, 2, 1} - clientErr := client.JsonError{ + tooLargeErr := client.JsonError{ Code: -32005, Data: getLogErrData{"0x100E698", "0x100E6D4", 10000}, Message: "query returned more than 10000 results. Try with this block range [0x100E698, 0x100E6D4].", } - // Simulate currentBlock = 300 - head := &evmtypes.Head{Number: 300} - finalized := &evmtypes.Head{Number: head.Number - lpOpts.FinalityDepth} - headTracker.On("LatestAndFinalizedBlock", mock.Anything).Return(head, finalized, nil).Once() - call1 := ec.On("HeadByNumber", mock.Anything, mock.Anything).Return(func(ctx context.Context, blockNumber *big.Int) (*evmtypes.Head, error) { + var filterLogsCall *mock.Call + head := &evmtypes.Head{} + finalized := &evmtypes.Head{} + + ec.On("HeadByNumber", mock.Anything, mock.Anything).Return(func(ctx context.Context, blockNumber *big.Int) (*evmtypes.Head, error) { if blockNumber == nil { require.FailNow(t, "unexpected call to get current head") } return &evmtypes.Head{Number: blockNumber.Int64()}, nil }) - call2 := ec.On("FilterLogs", mock.Anything, mock.Anything).Return(func(ctx context.Context, fq ethereum.FilterQuery) (logs []types.Log, err error) { - if fq.BlockHash != nil { - return []types.Log{}, nil // succeed when single block requested - } - from := fq.FromBlock.Uint64() - to := fq.ToBlock.Uint64() - if to-from >= 4 { - return []types.Log{}, &clientErr // return "too many results" error if block range spans 4 or more blocks - } - return logs, err - }) + t.Run("halves size until small enough, then succeeds", func(t *testing.T) { + // Simulate currentBlock = 300 + head.Number = 300 + finalized.Number = head.Number - lpOpts.FinalityDepth + headTracker.On("LatestAndFinalizedBlock", mock.Anything).Return(head, finalized, nil).Once() - addr := testutils.NewAddress() - err := lp.RegisterFilter(ctx, logpoller.Filter{ - Name: "Integration test", - EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, - Addresses: []common.Address{addr}, - }) - require.NoError(t, err) - lp.PollAndSaveLogs(ctx, 5) - block, err2 := o.SelectLatestBlock(ctx) - require.NoError(t, err2) - assert.Equal(t, int64(298), block.BlockNumber) - - logs := obs.FilterLevelExact(zapcore.WarnLevel).FilterMessageSnippet("halving block range batch size").FilterFieldKey("newBatchSize").All() - // Should have tried again 3 times--first reducing batch size to 10, then 5, then 2 - require.Len(t, logs, 3) - for i, s := range expected[:3] { - assert.Equal(t, s, logs[i].ContextMap()["newBatchSize"]) - } + filterLogsCall = ec.On("FilterLogs", mock.Anything, mock.Anything).Return(func(ctx context.Context, fq ethereum.FilterQuery) (logs []types.Log, err error) { + if fq.BlockHash != nil { + return []types.Log{}, nil // succeed when single block requested + } + from := fq.FromBlock.Uint64() + to := fq.ToBlock.Uint64() + if to-from >= 4 { + return []types.Log{}, tooLargeErr // return "too many results" error if block range spans 4 or more blocks + } + return logs, err + }) - obs.TakeAll() - call1.Unset() - call2.Unset() + addr := testutils.NewAddress() + err := lp.RegisterFilter(ctx, logpoller.Filter{ + Name: "Integration test", + EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, + Addresses: []common.Address{addr}, + }) + require.NoError(t, err) + lp.PollAndSaveLogs(ctx, 5) + block, err2 := o.SelectLatestBlock(ctx) + require.NoError(t, err2) + assert.Equal(t, int64(298), block.BlockNumber) - // Now jump to block 500, but return error no matter how small the block range gets. - // Should exit the loop with a critical error instead of hanging. - head = &evmtypes.Head{Number: 500} - finalized = &evmtypes.Head{Number: head.Number - lpOpts.FinalityDepth} - headTracker.On("LatestAndFinalizedBlock", mock.Anything).Return(head, finalized, nil).Once() - call1.On("HeadByNumber", mock.Anything, mock.Anything).Return(func(ctx context.Context, blockNumber *big.Int) (*evmtypes.Head, error) { - if blockNumber == nil { - require.FailNow(t, "unexpected call to get current head") + logs := obs.FilterLevelExact(zapcore.WarnLevel).FilterMessageSnippet("halving block range batch size").FilterFieldKey("newBatchSize").All() + // Should have tried again 3 times--first reducing batch size to 10, then 5, then 2 + require.Len(t, logs, 3) + for i, s := range expected[:3] { + assert.Equal(t, s, logs[i].ContextMap()["newBatchSize"]) } - return &evmtypes.Head{Number: blockNumber.Int64()}, nil + filterLogsCall.Unset() }) - call2.On("FilterLogs", mock.Anything, mock.Anything).Return(func(ctx context.Context, fq ethereum.FilterQuery) (logs []types.Log, err error) { - if fq.BlockHash != nil { - return []types.Log{}, nil // succeed when single block requested + + t.Run("Halves size until single block, then reports critical error", func(t *testing.T) { + obs.TakeAll() + + // Now jump to block 500, but return error no matter how small the block range gets. + // Should exit the loop with a critical error instead of hanging. + head.Number = 500 + finalized.Number = head.Number - lpOpts.FinalityDepth + headTracker.On("LatestAndFinalizedBlock", mock.Anything).Return(head, finalized, nil).Once() + filterLogsCall = ec.On("FilterLogs", mock.Anything, mock.Anything).Return(func(ctx context.Context, fq ethereum.FilterQuery) (logs []types.Log, err error) { + if fq.BlockHash != nil { + return []types.Log{}, nil // succeed when single block requested + } + return []types.Log{}, tooLargeErr // return "too many results" error if block range spans 4 or more blocks + }) + + lp.PollAndSaveLogs(ctx, 298) + block, err := o.SelectLatestBlock(ctx) + if err != nil { + assert.ErrorContains(t, err, "no rows") // In case this subtest is run by itself + } else { + assert.Equal(t, int64(298), block.BlockNumber) + } + warns := obs.FilterMessageSnippet("halving block range").FilterLevelExact(zapcore.WarnLevel).All() + crit := obs.FilterMessageSnippet("failed to retrieve logs").FilterLevelExact(zapcore.DPanicLevel).All() + require.Len(t, warns, 4) + for i, s := range expected { + assert.Equal(t, s, warns[i].ContextMap()["newBatchSize"]) } - return []types.Log{}, &clientErr // return "too many results" error if block range spans 4 or more blocks + + require.Len(t, crit, 1) + assert.Contains(t, crit[0].Message, "Too many log results in a single block") + filterLogsCall.Unset() }) - lp.PollAndSaveLogs(ctx, 298) - block, err2 = o.SelectLatestBlock(ctx) - require.NoError(t, err2) - assert.Equal(t, int64(298), block.BlockNumber) - warns := obs.FilterMessageSnippet("halving block range").FilterLevelExact(zapcore.WarnLevel).All() - crit := obs.FilterMessageSnippet("failed to retrieve logs").FilterLevelExact(zapcore.DPanicLevel).All() - require.Len(t, warns, 4) - for i, s := range expected { - assert.Equal(t, s, warns[i].ContextMap()["newBatchSize"]) - } + t.Run("Unrelated error are retried without adjusting size", func(t *testing.T) { + unrelatedError := fmt.Errorf("Unrelated to the size of the request") + head.Number = 500 + finalized.Number = head.Number - lpOpts.FinalityDepth + + obs.TakeAll() + filterLogsCall = ec.On("FilterLogs", mock.Anything, mock.Anything).Return(func(ctx context.Context, fq ethereum.FilterQuery) (logs []types.Log, err error) { + if fq.BlockHash != nil { + return []types.Log{}, nil // succeed when single block requested + } + return []types.Log{}, unrelatedError // return an unrelated error that should just be retried with same size + }) + headTracker.On("LatestAndFinalizedBlock", mock.Anything).Return(head, finalized, nil).Once() - require.Len(t, crit, 1) - assert.Contains(t, crit[0].Message, "Too many log results in a single block") + lp.PollAndSaveLogs(ctx, 298) + block, err := o.SelectLatestBlock(ctx) + if err != nil { + assert.ErrorContains(t, err, "no rows") // In case this subtest is run by itself + } else { + assert.Equal(t, int64(298), block.BlockNumber) + } + crit := obs.FilterLevelExact(zapcore.DPanicLevel).All() + errors := obs.FilterLevelExact(zapcore.ErrorLevel).All() + warns := obs.FilterLevelExact(zapcore.WarnLevel).All() + assert.Len(t, crit, 0) + require.Len(t, errors, 1) + assert.Equal(t, errors[0].Message, "Unable to query for logs") + require.Len(t, warns, 1) + assert.Contains(t, warns[0].Message, "retrying later") + }) } func Test_PollAndQueryFinalizedBlocks(t *testing.T) { diff --git a/core/chains/legacyevm/chain.go b/core/chains/legacyevm/chain.go index 68ff8d4e11..022f4cc531 100644 --- a/core/chains/legacyevm/chain.go +++ b/core/chains/legacyevm/chain.go @@ -241,6 +241,7 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod KeepFinalizedBlocksDepth: int64(cfg.EVM().LogKeepBlocksDepth()), LogPrunePageSize: int64(cfg.EVM().LogPrunePageSize()), BackupPollerBlockDelay: int64(cfg.EVM().BackupLogPollerBlockDelay()), + ClientErrors: cfg.EVM().NodePool().Errors(), } logPoller = logpoller.NewLogPoller(logpoller.NewObservedORM(chainID, opts.DS, l), client, l, headTracker, lpOpts) } diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index 2186f502f4..aef9be0966 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -429,6 +429,8 @@ TransactionAlreadyMined = '(: |^)transaction already mined' # Example Fatal = '(: |^)fatal' # Example # ServiceUnavailable is a regex pattern to match against service unavailable errors. ServiceUnavailable = '(: |^)service unavailable' # Example +# TooManyResults is a regex pattern to match an eth_getLogs error indicating the result set is too large to return +TooManyResults = '(: |^)too many results' # Example [EVM.OCR] # ContractConfirmations sets `OCR.ContractConfirmations` for this EVM chain. diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 253e4aa067..56b0661854 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -615,6 +615,7 @@ func TestConfig_Marshal(t *testing.T) { TransactionAlreadyMined: ptr[string]("(: |^)transaction already mined"), Fatal: ptr[string]("(: |^)fatal"), ServiceUnavailable: ptr[string]("(: |^)service unavailable"), + TooManyResults: ptr[string]("(: |^)too many results"), }, }, OCR: evmcfg.OCR{ @@ -1090,6 +1091,7 @@ L2Full = '(: |^)l2 full' TransactionAlreadyMined = '(: |^)transaction already mined' Fatal = '(: |^)fatal' ServiceUnavailable = '(: |^)service unavailable' +TooManyResults = '(: |^)too many results' [EVM.OCR] ContractConfirmations = 11 diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index a7fc9dcb94..ff044fff58 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -381,6 +381,7 @@ L2Full = '(: |^)l2 full' TransactionAlreadyMined = '(: |^)transaction already mined' Fatal = '(: |^)fatal' ServiceUnavailable = '(: |^)service unavailable' +TooManyResults = '(: |^)too many results' [EVM.OCR] ContractConfirmations = 11 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index f67d4737b5..37644c1d22 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -380,6 +380,7 @@ L2Full = '(: |^)l2 full' TransactionAlreadyMined = '(: |^)transaction already mined' Fatal = '(: |^)fatal' ServiceUnavailable = '(: |^)service unavailable' +TooManyResults = '(: |^)too many results' [EVM.OCR] ContractConfirmations = 11 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 7c54682367..264f73d003 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -8390,6 +8390,7 @@ L2Full = '(: |^)l2 full' # Example TransactionAlreadyMined = '(: |^)transaction already mined' # Example Fatal = '(: |^)fatal' # Example ServiceUnavailable = '(: |^)service unavailable' # Example +TooManyResults = '(: |^)too many results' # Example ``` Errors enable the node to provide custom regex patterns to match against error messages from RPCs. @@ -8477,6 +8478,12 @@ ServiceUnavailable = '(: |^)service unavailable' # Example ``` ServiceUnavailable is a regex pattern to match against service unavailable errors. +### TooManyResults +```toml +TooManyResults = '(: |^)too many results' # Example +``` +TooManyResults is a regex pattern to match an eth_getLogs error indicating the result set is too large to return + ## EVM.OCR ```toml [EVM.OCR] From 0f557ae1e08040c931f6f3e5c6a96b93b1ca2182 Mon Sep 17 00:00:00 2001 From: Jaden Foldesi Date: Tue, 27 Aug 2024 12:06:58 -0400 Subject: [PATCH 179/432] [SHIP-1877] Bump BSC Mainnet's Default PriceMin to 3 gwei (#13853) * bump bsc PriceMin to 3 gwei * add bugfix tag * Update core/chains/evm/config/toml/defaults/BSC_Mainnet.toml Co-authored-by: amit-momin <108959691+amit-momin@users.noreply.github.com> --------- Co-authored-by: amit-momin <108959691+amit-momin@users.noreply.github.com> Co-authored-by: Simson --- .changeset/pink-fans-sparkle.md | 5 +++++ core/chains/evm/config/toml/defaults/BSC_Mainnet.toml | 2 ++ docs/CONFIG.md | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 .changeset/pink-fans-sparkle.md diff --git a/.changeset/pink-fans-sparkle.md b/.changeset/pink-fans-sparkle.md new file mode 100644 index 0000000000..c182e6dea3 --- /dev/null +++ b/.changeset/pink-fans-sparkle.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#bugfix Bump BSC PriceMin to 3 gwei to match BSC node's required gas price. This value can be pushed back down to 1 gwei to enable cheaper transactions if the GasPrice field under the Eth.Miner header in the BSC node's config is also pushed down to 1000000000 diff --git a/core/chains/evm/config/toml/defaults/BSC_Mainnet.toml b/core/chains/evm/config/toml/defaults/BSC_Mainnet.toml index 1b248a8c45..79ad43ab3e 100644 --- a/core/chains/evm/config/toml/defaults/BSC_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/BSC_Mainnet.toml @@ -10,6 +10,8 @@ NoNewFinalizedHeadsThreshold = '45s' [GasEstimator] PriceDefault = '5 gwei' +# Set to the BSC node's default Eth.Miner.GasPrice config +PriceMin = '3 gwei' # 15s delay since feeds update every minute in volatile situations BumpThreshold = 5 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 264f73d003..883bb49d31 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -2575,7 +2575,7 @@ Enabled = true Mode = 'BlockHistory' PriceDefault = '5 gwei' PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' -PriceMin = '1 gwei' +PriceMin = '3 gwei' LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' From f1bc2e7ad3610339145930991bf6a3c9ef94fa52 Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:53:17 -0500 Subject: [PATCH 180/432] Set From address for gas limit estimation feature (#14246) * Set from address for gas limit estimation * Updated tests * Added changeset --- .changeset/great-timers-agree.md | 5 ++ .../chains/evm/gas/mocks/evm_fee_estimator.go | 70 ++++++++++--------- core/chains/evm/gas/models.go | 17 +++-- core/chains/evm/gas/models_test.go | 41 +++++------ core/chains/evm/txmgr/attempts.go | 2 +- core/chains/evm/txmgr/attempts_test.go | 2 +- core/chains/evm/txmgr/broadcaster_test.go | 2 +- core/chains/evm/txmgr/confirmer_test.go | 2 +- core/chains/evm/txmgr/stuck_tx_detector.go | 4 +- .../evm/txmgr/stuck_tx_detector_test.go | 4 +- core/internal/features/features_test.go | 4 +- core/services/keeper/upkeep_executer_test.go | 2 +- .../ccipdata/commit_store_reader_test.go | 2 +- .../ccip/prices/exec_price_estimator.go | 2 +- .../ccip/prices/exec_price_estimator_test.go | 2 +- .../evmregistry/v21/gasprice/gasprice.go | 2 +- .../evmregistry/v21/gasprice/gasprice_test.go | 6 +- core/services/relay/evm/chain_writer.go | 2 +- core/services/relay/evm/chain_writer_test.go | 10 +-- core/web/evm_transfer_controller.go | 2 +- 20 files changed, 95 insertions(+), 88 deletions(-) create mode 100644 .changeset/great-timers-agree.md diff --git a/.changeset/great-timers-agree.md b/.changeset/great-timers-agree.md new file mode 100644 index 0000000000..bfa27761fb --- /dev/null +++ b/.changeset/great-timers-agree.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Updated gas limit estimation feature to set From address #internal diff --git a/core/chains/evm/gas/mocks/evm_fee_estimator.go b/core/chains/evm/gas/mocks/evm_fee_estimator.go index 603115a94c..a7deca2c63 100644 --- a/core/chains/evm/gas/mocks/evm_fee_estimator.go +++ b/core/chains/evm/gas/mocks/evm_fee_estimator.go @@ -147,14 +147,14 @@ func (_c *EvmFeeEstimator_Close_Call) RunAndReturn(run func() error) *EvmFeeEsti return _c } -// GetFee provides a mock function with given fields: ctx, calldata, feeLimit, maxFeePrice, toAddress, opts -func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...types.Opt) (gas.EvmFee, uint64, error) { +// GetFee provides a mock function with given fields: ctx, calldata, feeLimit, maxFeePrice, fromAddress, toAddress, opts +func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, fromAddress *common.Address, toAddress *common.Address, opts ...types.Opt) (gas.EvmFee, uint64, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] } var _ca []interface{} - _ca = append(_ca, ctx, calldata, feeLimit, maxFeePrice, toAddress) + _ca = append(_ca, ctx, calldata, feeLimit, maxFeePrice, fromAddress, toAddress) _ca = append(_ca, _va...) ret := _m.Called(_ca...) @@ -165,23 +165,23 @@ func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit var r0 gas.EvmFee var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) (gas.EvmFee, uint64, error)); ok { - return rf(ctx, calldata, feeLimit, maxFeePrice, toAddress, opts...) + if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, *common.Address, *common.Address, ...types.Opt) (gas.EvmFee, uint64, error)); ok { + return rf(ctx, calldata, feeLimit, maxFeePrice, fromAddress, toAddress, opts...) } - if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) gas.EvmFee); ok { - r0 = rf(ctx, calldata, feeLimit, maxFeePrice, toAddress, opts...) + if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, *common.Address, *common.Address, ...types.Opt) gas.EvmFee); ok { + r0 = rf(ctx, calldata, feeLimit, maxFeePrice, fromAddress, toAddress, opts...) } else { r0 = ret.Get(0).(gas.EvmFee) } - if rf, ok := ret.Get(1).(func(context.Context, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) uint64); ok { - r1 = rf(ctx, calldata, feeLimit, maxFeePrice, toAddress, opts...) + if rf, ok := ret.Get(1).(func(context.Context, []byte, uint64, *assets.Wei, *common.Address, *common.Address, ...types.Opt) uint64); ok { + r1 = rf(ctx, calldata, feeLimit, maxFeePrice, fromAddress, toAddress, opts...) } else { r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) error); ok { - r2 = rf(ctx, calldata, feeLimit, maxFeePrice, toAddress, opts...) + if rf, ok := ret.Get(2).(func(context.Context, []byte, uint64, *assets.Wei, *common.Address, *common.Address, ...types.Opt) error); ok { + r2 = rf(ctx, calldata, feeLimit, maxFeePrice, fromAddress, toAddress, opts...) } else { r2 = ret.Error(2) } @@ -199,22 +199,23 @@ type EvmFeeEstimator_GetFee_Call struct { // - calldata []byte // - feeLimit uint64 // - maxFeePrice *assets.Wei +// - fromAddress *common.Address // - toAddress *common.Address // - opts ...types.Opt -func (_e *EvmFeeEstimator_Expecter) GetFee(ctx interface{}, calldata interface{}, feeLimit interface{}, maxFeePrice interface{}, toAddress interface{}, opts ...interface{}) *EvmFeeEstimator_GetFee_Call { +func (_e *EvmFeeEstimator_Expecter) GetFee(ctx interface{}, calldata interface{}, feeLimit interface{}, maxFeePrice interface{}, fromAddress interface{}, toAddress interface{}, opts ...interface{}) *EvmFeeEstimator_GetFee_Call { return &EvmFeeEstimator_GetFee_Call{Call: _e.mock.On("GetFee", - append([]interface{}{ctx, calldata, feeLimit, maxFeePrice, toAddress}, opts...)...)} + append([]interface{}{ctx, calldata, feeLimit, maxFeePrice, fromAddress, toAddress}, opts...)...)} } -func (_c *EvmFeeEstimator_GetFee_Call) Run(run func(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...types.Opt)) *EvmFeeEstimator_GetFee_Call { +func (_c *EvmFeeEstimator_GetFee_Call) Run(run func(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, fromAddress *common.Address, toAddress *common.Address, opts ...types.Opt)) *EvmFeeEstimator_GetFee_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]types.Opt, len(args)-5) - for i, a := range args[5:] { + variadicArgs := make([]types.Opt, len(args)-6) + for i, a := range args[6:] { if a != nil { variadicArgs[i] = a.(types.Opt) } } - run(args[0].(context.Context), args[1].([]byte), args[2].(uint64), args[3].(*assets.Wei), args[4].(*common.Address), variadicArgs...) + run(args[0].(context.Context), args[1].([]byte), args[2].(uint64), args[3].(*assets.Wei), args[4].(*common.Address), args[5].(*common.Address), variadicArgs...) }) return _c } @@ -224,19 +225,19 @@ func (_c *EvmFeeEstimator_GetFee_Call) Return(fee gas.EvmFee, estimatedFeeLimit return _c } -func (_c *EvmFeeEstimator_GetFee_Call) RunAndReturn(run func(context.Context, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) (gas.EvmFee, uint64, error)) *EvmFeeEstimator_GetFee_Call { +func (_c *EvmFeeEstimator_GetFee_Call) RunAndReturn(run func(context.Context, []byte, uint64, *assets.Wei, *common.Address, *common.Address, ...types.Opt) (gas.EvmFee, uint64, error)) *EvmFeeEstimator_GetFee_Call { _c.Call.Return(run) return _c } -// GetMaxCost provides a mock function with given fields: ctx, amount, calldata, feeLimit, maxFeePrice, toAddress, opts -func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...types.Opt) (*big.Int, error) { +// GetMaxCost provides a mock function with given fields: ctx, amount, calldata, feeLimit, maxFeePrice, fromAddress, toAddress, opts +func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, fromAddress *common.Address, toAddress *common.Address, opts ...types.Opt) (*big.Int, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] } var _ca []interface{} - _ca = append(_ca, ctx, amount, calldata, feeLimit, maxFeePrice, toAddress) + _ca = append(_ca, ctx, amount, calldata, feeLimit, maxFeePrice, fromAddress, toAddress) _ca = append(_ca, _va...) ret := _m.Called(_ca...) @@ -246,19 +247,19 @@ func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, ca var r0 *big.Int var r1 error - if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) (*big.Int, error)); ok { - return rf(ctx, amount, calldata, feeLimit, maxFeePrice, toAddress, opts...) + if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, *common.Address, *common.Address, ...types.Opt) (*big.Int, error)); ok { + return rf(ctx, amount, calldata, feeLimit, maxFeePrice, fromAddress, toAddress, opts...) } - if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) *big.Int); ok { - r0 = rf(ctx, amount, calldata, feeLimit, maxFeePrice, toAddress, opts...) + if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, *common.Address, *common.Address, ...types.Opt) *big.Int); ok { + r0 = rf(ctx, amount, calldata, feeLimit, maxFeePrice, fromAddress, toAddress, opts...) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*big.Int) } } - if rf, ok := ret.Get(1).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) error); ok { - r1 = rf(ctx, amount, calldata, feeLimit, maxFeePrice, toAddress, opts...) + if rf, ok := ret.Get(1).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, *common.Address, *common.Address, ...types.Opt) error); ok { + r1 = rf(ctx, amount, calldata, feeLimit, maxFeePrice, fromAddress, toAddress, opts...) } else { r1 = ret.Error(1) } @@ -277,22 +278,23 @@ type EvmFeeEstimator_GetMaxCost_Call struct { // - calldata []byte // - feeLimit uint64 // - maxFeePrice *assets.Wei +// - fromAddress *common.Address // - toAddress *common.Address // - opts ...types.Opt -func (_e *EvmFeeEstimator_Expecter) GetMaxCost(ctx interface{}, amount interface{}, calldata interface{}, feeLimit interface{}, maxFeePrice interface{}, toAddress interface{}, opts ...interface{}) *EvmFeeEstimator_GetMaxCost_Call { +func (_e *EvmFeeEstimator_Expecter) GetMaxCost(ctx interface{}, amount interface{}, calldata interface{}, feeLimit interface{}, maxFeePrice interface{}, fromAddress interface{}, toAddress interface{}, opts ...interface{}) *EvmFeeEstimator_GetMaxCost_Call { return &EvmFeeEstimator_GetMaxCost_Call{Call: _e.mock.On("GetMaxCost", - append([]interface{}{ctx, amount, calldata, feeLimit, maxFeePrice, toAddress}, opts...)...)} + append([]interface{}{ctx, amount, calldata, feeLimit, maxFeePrice, fromAddress, toAddress}, opts...)...)} } -func (_c *EvmFeeEstimator_GetMaxCost_Call) Run(run func(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...types.Opt)) *EvmFeeEstimator_GetMaxCost_Call { +func (_c *EvmFeeEstimator_GetMaxCost_Call) Run(run func(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, fromAddress *common.Address, toAddress *common.Address, opts ...types.Opt)) *EvmFeeEstimator_GetMaxCost_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]types.Opt, len(args)-6) - for i, a := range args[6:] { + variadicArgs := make([]types.Opt, len(args)-7) + for i, a := range args[7:] { if a != nil { variadicArgs[i] = a.(types.Opt) } } - run(args[0].(context.Context), args[1].(assets.Eth), args[2].([]byte), args[3].(uint64), args[4].(*assets.Wei), args[5].(*common.Address), variadicArgs...) + run(args[0].(context.Context), args[1].(assets.Eth), args[2].([]byte), args[3].(uint64), args[4].(*assets.Wei), args[5].(*common.Address), args[6].(*common.Address), variadicArgs...) }) return _c } @@ -302,7 +304,7 @@ func (_c *EvmFeeEstimator_GetMaxCost_Call) Return(_a0 *big.Int, _a1 error) *EvmF return _c } -func (_c *EvmFeeEstimator_GetMaxCost_Call) RunAndReturn(run func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, *common.Address, ...types.Opt) (*big.Int, error)) *EvmFeeEstimator_GetMaxCost_Call { +func (_c *EvmFeeEstimator_GetMaxCost_Call) RunAndReturn(run func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, *common.Address, *common.Address, ...types.Opt) (*big.Int, error)) *EvmFeeEstimator_GetMaxCost_Call { _c.Call.Return(run) return _c } diff --git a/core/chains/evm/gas/models.go b/core/chains/evm/gas/models.go index f3fae4e574..00062d8462 100644 --- a/core/chains/evm/gas/models.go +++ b/core/chains/evm/gas/models.go @@ -36,11 +36,11 @@ type EvmFeeEstimator interface { // L1Oracle returns the L1 gas price oracle only if the chain has one, e.g. OP stack L2s and Arbitrum. L1Oracle() rollups.L1Oracle - GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...feetypes.Opt) (fee EvmFee, estimatedFeeLimit uint64, err error) + GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, fromAddress, toAddress *common.Address, opts ...feetypes.Opt) (fee EvmFee, estimatedFeeLimit uint64, err error) BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint64, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint64, err error) // GetMaxCost returns the total value = max price x fee units + transferred value - GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...feetypes.Opt) (*big.Int, error) + GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, fromAddress, toAddress *common.Address, opts ...feetypes.Opt) (*big.Int, error) } type feeEstimatorClient interface { @@ -270,7 +270,7 @@ func (e *evmFeeEstimator) L1Oracle() rollups.L1Oracle { // GetFee returns an initial estimated gas price and gas limit for a transaction // The gas limit provided by the caller can be adjusted by gas estimation or for 2D fees -func (e *evmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...feetypes.Opt) (fee EvmFee, estimatedFeeLimit uint64, err error) { +func (e *evmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, fromAddress, toAddress *common.Address, opts ...feetypes.Opt) (fee EvmFee, estimatedFeeLimit uint64, err error) { var chainSpecificFeeLimit uint64 // get dynamic fee if e.EIP1559Enabled { @@ -290,12 +290,12 @@ func (e *evmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit } } - estimatedFeeLimit, err = e.estimateFeeLimit(ctx, chainSpecificFeeLimit, calldata, toAddress) + estimatedFeeLimit, err = e.estimateFeeLimit(ctx, chainSpecificFeeLimit, calldata, fromAddress, toAddress) return } -func (e *evmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...feetypes.Opt) (*big.Int, error) { - fees, gasLimit, err := e.GetFee(ctx, calldata, feeLimit, maxFeePrice, toAddress, opts...) +func (e *evmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, fromAddress, toAddress *common.Address, opts ...feetypes.Opt) (*big.Int, error) { + fees, gasLimit, err := e.GetFee(ctx, calldata, feeLimit, maxFeePrice, fromAddress, toAddress, opts...) if err != nil { return nil, err } @@ -346,7 +346,7 @@ func (e *evmFeeEstimator) BumpFee(ctx context.Context, originalFee EvmFee, feeLi return } -func (e *evmFeeEstimator) estimateFeeLimit(ctx context.Context, feeLimit uint64, calldata []byte, toAddress *common.Address) (estimatedFeeLimit uint64, err error) { +func (e *evmFeeEstimator) estimateFeeLimit(ctx context.Context, feeLimit uint64, calldata []byte, fromAddress, toAddress *common.Address) (estimatedFeeLimit uint64, err error) { // Use the feeLimit * LimitMultiplier as the provided gas limit since this multiplier is applied on top of the caller specified gas limit providedGasLimit, err := commonfee.ApplyMultiplier(feeLimit, e.geCfg.LimitMultiplier()) if err != nil { @@ -362,6 +362,9 @@ func (e *evmFeeEstimator) estimateFeeLimit(ctx context.Context, feeLimit uint64, To: toAddress, Data: calldata, } + if fromAddress != nil { + callMsg.From = *fromAddress + } estimatedGas, estimateErr := e.ethClient.EstimateGas(ctx, callMsg) if estimateErr != nil { if providedGasLimit > 0 { diff --git a/core/chains/evm/gas/models_test.go b/core/chains/evm/gas/models_test.go index 14ef085497..ea5e53c228 100644 --- a/core/chains/evm/gas/models_test.go +++ b/core/chains/evm/gas/models_test.go @@ -52,6 +52,9 @@ func TestWrappedEvmEstimator(t *testing.T) { mockEstimatorName := "WrappedEvmEstimator" mockEvmEstimatorName := "WrappedEvmEstimator.MockEstimator" + fromAddress := testutils.NewAddress() + toAddress := testutils.NewAddress() + // L1Oracle returns the correct L1Oracle interface t.Run("L1Oracle", func(t *testing.T) { lggr := logger.Test(t) @@ -84,7 +87,7 @@ func TestWrappedEvmEstimator(t *testing.T) { // expect legacy fee data dynamicFees := false estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, nil) - fee, max, err := estimator.GetFee(ctx, nil, 0, nil, nil) + fee, max, err := estimator.GetFee(ctx, nil, 0, nil, nil, nil) require.NoError(t, err) assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), max) assert.True(t, legacyFee.Equal(fee.Legacy)) @@ -94,7 +97,7 @@ func TestWrappedEvmEstimator(t *testing.T) { // expect dynamic fee data dynamicFees = true estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, nil) - fee, max, err = estimator.GetFee(ctx, nil, gasLimit, nil, nil) + fee, max, err = estimator.GetFee(ctx, nil, gasLimit, nil, nil, nil) require.NoError(t, err) assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), max) assert.True(t, dynamicFee.FeeCap.Equal(fee.DynamicFeeCap)) @@ -145,7 +148,7 @@ func TestWrappedEvmEstimator(t *testing.T) { // expect legacy fee data dynamicFees := false estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, nil) - total, err := estimator.GetMaxCost(ctx, val, nil, gasLimit, nil, nil) + total, err := estimator.GetMaxCost(ctx, val, nil, gasLimit, nil, nil, nil) require.NoError(t, err) fee := new(big.Int).Mul(legacyFee.ToInt(), big.NewInt(int64(gasLimit))) fee, _ = new(big.Float).Mul(new(big.Float).SetInt(fee), big.NewFloat(float64(limitMultiplier))).Int(nil) @@ -154,7 +157,7 @@ func TestWrappedEvmEstimator(t *testing.T) { // expect dynamic fee data dynamicFees = true estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, nil) - total, err = estimator.GetMaxCost(ctx, val, nil, gasLimit, nil, nil) + total, err = estimator.GetMaxCost(ctx, val, nil, gasLimit, nil, nil, nil) require.NoError(t, err) fee = new(big.Int).Mul(dynamicFee.FeeCap.ToInt(), big.NewInt(int64(gasLimit))) fee, _ = new(big.Float).Mul(new(big.Float).SetInt(fee), big.NewFloat(float64(limitMultiplier))).Int(nil) @@ -262,8 +265,7 @@ func TestWrappedEvmEstimator(t *testing.T) { ethClient := testutils.NewEthClientMockWithDefaultChain(t) ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Twice() estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) - toAddress := testutils.NewAddress() - fee, limit, err := estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + fee, limit, err := estimator.GetFee(ctx, []byte{}, gasLimit, nil, &fromAddress, &toAddress) require.NoError(t, err) assert.Equal(t, uint64(float32(estimatedGasLimit)*gas.EstimateGasBuffer), limit) assert.True(t, legacyFee.Equal(fee.Legacy)) @@ -273,7 +275,7 @@ func TestWrappedEvmEstimator(t *testing.T) { // expect dynamic fee data dynamicFees = true estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) - fee, limit, err = estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + fee, limit, err = estimator.GetFee(ctx, []byte{}, gasLimit, nil, &fromAddress, &toAddress) require.NoError(t, err) assert.Equal(t, uint64(float32(estimatedGasLimit)*gas.EstimateGasBuffer), limit) assert.True(t, dynamicFee.FeeCap.Equal(fee.DynamicFeeCap)) @@ -290,14 +292,13 @@ func TestWrappedEvmEstimator(t *testing.T) { ethClient := testutils.NewEthClientMockWithDefaultChain(t) ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Twice() estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) - toAddress := testutils.NewAddress() - _, _, err := estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + _, _, err := estimator.GetFee(ctx, []byte{}, gasLimit, nil, &fromAddress, &toAddress) require.ErrorIs(t, err, commonfee.ErrFeeLimitTooLow) // expect dynamic fee data dynamicFees = true estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) - _, _, err = estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + _, _, err = estimator.GetFee(ctx, []byte{}, gasLimit, nil, &fromAddress, &toAddress) require.ErrorIs(t, err, commonfee.ErrFeeLimitTooLow) }) @@ -309,8 +310,7 @@ func TestWrappedEvmEstimator(t *testing.T) { ethClient := testutils.NewEthClientMockWithDefaultChain(t) ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Twice() estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) - toAddress := testutils.NewAddress() - fee, limit, err := estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + fee, limit, err := estimator.GetFee(ctx, []byte{}, gasLimit, nil, &fromAddress, &toAddress) require.NoError(t, err) assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), limit) assert.True(t, legacyFee.Equal(fee.Legacy)) @@ -319,7 +319,7 @@ func TestWrappedEvmEstimator(t *testing.T) { dynamicFees = true // expect dynamic fee data estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) - fee, limit, err = estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + fee, limit, err = estimator.GetFee(ctx, []byte{}, gasLimit, nil, &fromAddress, &toAddress) require.NoError(t, err) assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), limit) assert.True(t, dynamicFee.FeeCap.Equal(fee.DynamicFeeCap)) @@ -335,8 +335,7 @@ func TestWrappedEvmEstimator(t *testing.T) { ethClient := testutils.NewEthClientMockWithDefaultChain(t) ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(uint64(0), errors.New("something broke")).Twice() estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) - toAddress := testutils.NewAddress() - fee, limit, err := estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + fee, limit, err := estimator.GetFee(ctx, []byte{}, gasLimit, nil, &fromAddress, &toAddress) require.NoError(t, err) assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), limit) assert.True(t, legacyFee.Equal(fee.Legacy)) @@ -346,7 +345,7 @@ func TestWrappedEvmEstimator(t *testing.T) { // expect dynamic fee data dynamicFees = true estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) - fee, limit, err = estimator.GetFee(ctx, []byte{}, gasLimit, nil, &toAddress) + fee, limit, err = estimator.GetFee(ctx, []byte{}, gasLimit, nil, &fromAddress, &toAddress) require.NoError(t, err) assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), limit) assert.True(t, dynamicFee.FeeCap.Equal(fee.DynamicFeeCap)) @@ -367,8 +366,7 @@ func TestWrappedEvmEstimator(t *testing.T) { ethClient := testutils.NewEthClientMockWithDefaultChain(t) ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Twice() estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) - toAddress := testutils.NewAddress() - fee, limit, err := estimator.GetFee(ctx, []byte{}, uint64(0), nil, &toAddress) + fee, limit, err := estimator.GetFee(ctx, []byte{}, uint64(0), nil, &fromAddress, &toAddress) require.NoError(t, err) assert.Equal(t, uint64(float32(estimatedGasLimit)*gas.EstimateGasBuffer), limit) assert.True(t, legacyFee.Equal(fee.Legacy)) @@ -378,7 +376,7 @@ func TestWrappedEvmEstimator(t *testing.T) { // expect dynamic fee data dynamicFees = true estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) - fee, limit, err = estimator.GetFee(ctx, []byte{}, 0, nil, &toAddress) + fee, limit, err = estimator.GetFee(ctx, []byte{}, 0, nil, &fromAddress, &toAddress) require.NoError(t, err) assert.Equal(t, uint64(float32(estimatedGasLimit)*gas.EstimateGasBuffer), limit) assert.True(t, dynamicFee.FeeCap.Equal(fee.DynamicFeeCap)) @@ -398,14 +396,13 @@ func TestWrappedEvmEstimator(t *testing.T) { ethClient := testutils.NewEthClientMockWithDefaultChain(t) ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(uint64(0), errors.New("something broke")).Twice() estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) - toAddress := testutils.NewAddress() - _, _, err := estimator.GetFee(ctx, []byte{}, 0, nil, &toAddress) + _, _, err := estimator.GetFee(ctx, []byte{}, 0, nil, &fromAddress, &toAddress) require.Error(t, err) // expect dynamic fee data dynamicFees = true estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) - _, _, err = estimator.GetFee(ctx, []byte{}, 0, nil, &toAddress) + _, _, err = estimator.GetFee(ctx, []byte{}, 0, nil, &fromAddress, &toAddress) require.Error(t, err) }) } diff --git a/core/chains/evm/txmgr/attempts.go b/core/chains/evm/txmgr/attempts.go index c57ecc4412..c284ee77bd 100644 --- a/core/chains/evm/txmgr/attempts.go +++ b/core/chains/evm/txmgr/attempts.go @@ -58,7 +58,7 @@ func (c *evmTxAttemptBuilder) NewTxAttempt(ctx context.Context, etx Tx, lggr log // used for L2 re-estimation on broadcasting (note EIP1559 must be disabled otherwise this will fail with mismatched fees + tx type) func (c *evmTxAttemptBuilder) NewTxAttemptWithType(ctx context.Context, etx Tx, lggr logger.Logger, txType int, opts ...feetypes.Opt) (attempt TxAttempt, fee gas.EvmFee, feeLimit uint64, retryable bool, err error) { keySpecificMaxGasPriceWei := c.feeConfig.PriceMaxKey(etx.FromAddress) - fee, feeLimit, err = c.EvmFeeEstimator.GetFee(ctx, etx.EncodedPayload, etx.FeeLimit, keySpecificMaxGasPriceWei, &etx.ToAddress, opts...) + fee, feeLimit, err = c.EvmFeeEstimator.GetFee(ctx, etx.EncodedPayload, etx.FeeLimit, keySpecificMaxGasPriceWei, &etx.FromAddress, &etx.ToAddress, opts...) if err != nil { return attempt, fee, feeLimit, true, pkgerrors.Wrap(err, "failed to get fee") // estimator errors are retryable } diff --git a/core/chains/evm/txmgr/attempts_test.go b/core/chains/evm/txmgr/attempts_test.go index ea00f7a347..5c43368fcc 100644 --- a/core/chains/evm/txmgr/attempts_test.go +++ b/core/chains/evm/txmgr/attempts_test.go @@ -339,7 +339,7 @@ func TestTxm_NewCustomTxAttempt_NonRetryableErrors(t *testing.T) { func TestTxm_EvmTxAttemptBuilder_RetryableEstimatorError(t *testing.T) { est := gasmocks.NewEvmFeeEstimator(t) - est.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint64(0), pkgerrors.New("fail")) + est.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint64(0), pkgerrors.New("fail")) est.On("BumpFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint64(0), pkgerrors.New("fail")) kst := ksmocks.NewEth(t) diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 343988196c..41f50f4434 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -644,7 +644,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_OptimisticLockingOnEthTx(t *testi chStartEstimate := make(chan struct{}) chBlock := make(chan struct{}) - estimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, ccfg.EVM().GasEstimator().PriceMaxKey(fromAddress), mock.Anything).Return(gas.EvmFee{Legacy: assets.GWei(32)}, uint64(500), nil).Run(func(_ mock.Arguments) { + estimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, ccfg.EVM().GasEstimator().PriceMaxKey(fromAddress), mock.Anything, mock.Anything).Return(gas.EvmFee{Legacy: assets.GWei(32)}, uint64(500), nil).Run(func(_ mock.Arguments) { close(chStartEstimate) <-chBlock }).Once() diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index 24330172b9..a9dec223bf 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -3218,7 +3218,7 @@ func TestEthConfirmer_ProcessStuckTransactions(t *testing.T) { fee := gas.EvmFee{Legacy: marketGasPrice} bumpedLegacy := assets.GWei(30) bumpedFee := gas.EvmFee{Legacy: bumpedLegacy} - feeEstimator.On("GetFee", mock.Anything, []byte{}, uint64(0), mock.Anything, mock.Anything).Return(fee, uint64(0), nil) + feeEstimator.On("GetFee", mock.Anything, []byte{}, uint64(0), mock.Anything, mock.Anything, mock.Anything).Return(fee, uint64(0), nil) feeEstimator.On("BumpFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(bumpedFee, uint64(10_000), nil) autoPurgeThreshold := uint32(5) autoPurgeMinAttempts := uint32(3) diff --git a/core/chains/evm/txmgr/stuck_tx_detector.go b/core/chains/evm/txmgr/stuck_tx_detector.go index 4e521d5f8f..362bb6c0a5 100644 --- a/core/chains/evm/txmgr/stuck_tx_detector.go +++ b/core/chains/evm/txmgr/stuck_tx_detector.go @@ -25,7 +25,7 @@ import ( ) type stuckTxDetectorGasEstimator interface { - GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, toAddress *common.Address, opts ...feetypes.Opt) (fee gas.EvmFee, chainSpecificFeeLimit uint64, err error) + GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, fromAddress, toAddress *common.Address, opts ...feetypes.Opt) (fee gas.EvmFee, chainSpecificFeeLimit uint64, err error) } type stuckTxDetectorClient interface { @@ -199,7 +199,7 @@ func (d *stuckTxDetector) detectStuckTransactionsHeuristic(ctx context.Context, defer d.purgeBlockNumLock.RUnlock() // Get gas price from internal gas estimator // Send with max gas price time 2 to prevent the results from being capped. Need the market gas price here. - marketGasPrice, _, err := d.gasEstimator.GetFee(ctx, []byte{}, 0, d.maxPrice.Mul(big.NewInt(2)), nil) + marketGasPrice, _, err := d.gasEstimator.GetFee(ctx, []byte{}, 0, d.maxPrice.Mul(big.NewInt(2)), nil, nil) if err != nil { return txs, fmt.Errorf("failed to get market gas price for overflow detection: %w", err) } diff --git a/core/chains/evm/txmgr/stuck_tx_detector_test.go b/core/chains/evm/txmgr/stuck_tx_detector_test.go index 5e022091a6..eb22830ef3 100644 --- a/core/chains/evm/txmgr/stuck_tx_detector_test.go +++ b/core/chains/evm/txmgr/stuck_tx_detector_test.go @@ -73,7 +73,7 @@ func TestStuckTxDetector_LoadPurgeBlockNumMap(t *testing.T) { feeEstimator := gasmocks.NewEvmFeeEstimator(t) marketGasPrice := assets.GWei(15) fee := gas.EvmFee{Legacy: marketGasPrice} - feeEstimator.On("GetFee", mock.Anything, []byte{}, uint64(0), mock.Anything, mock.Anything).Return(fee, uint64(0), nil) + feeEstimator.On("GetFee", mock.Anything, []byte{}, uint64(0), mock.Anything, mock.Anything, mock.Anything).Return(fee, uint64(0), nil) autoPurgeThreshold := uint32(5) autoPurgeMinAttempts := uint32(3) autoPurgeCfg := testAutoPurgeConfig{ @@ -194,7 +194,7 @@ func TestStuckTxDetector_DetectStuckTransactionsHeuristic(t *testing.T) { // Return 10 gwei as market gas price marketGasPrice := tenGwei fee := gas.EvmFee{Legacy: marketGasPrice} - feeEstimator.On("GetFee", mock.Anything, []byte{}, uint64(0), mock.Anything, mock.Anything).Return(fee, uint64(0), nil) + feeEstimator.On("GetFee", mock.Anything, []byte{}, uint64(0), mock.Anything, mock.Anything, mock.Anything).Return(fee, uint64(0), nil) ethClient := testutils.NewEthClientMockWithDefaultChain(t) autoPurgeThreshold := uint32(5) autoPurgeMinAttempts := uint32(3) diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go index 6f35b9b0b5..159ea27e93 100644 --- a/core/internal/features/features_test.go +++ b/core/internal/features/features_test.go @@ -1340,7 +1340,7 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { chain := evmtest.MustGetDefaultChain(t, legacyChains) estimator := chain.GasEstimator() - gasPrice, gasLimit, err := estimator.GetFee(testutils.Context(t), nil, 500_000, maxGasPrice, nil) + gasPrice, gasLimit, err := estimator.GetFee(testutils.Context(t), nil, 500_000, maxGasPrice, nil, nil) require.NoError(t, err) assert.Equal(t, uint64(500000), gasLimit) assert.Equal(t, "41.5 gwei", gasPrice.Legacy.String()) @@ -1361,7 +1361,7 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { newHeads.TrySend(h43) gomega.NewWithT(t).Eventually(func() string { - gasPrice, _, err := estimator.GetFee(testutils.Context(t), nil, 500000, maxGasPrice, nil) + gasPrice, _, err := estimator.GetFee(testutils.Context(t), nil, 500000, maxGasPrice, nil, nil) require.NoError(t, err) return gasPrice.Legacy.String() }, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.Equal("45 gwei")) diff --git a/core/services/keeper/upkeep_executer_test.go b/core/services/keeper/upkeep_executer_test.go index 0f68543904..55926242a2 100644 --- a/core/services/keeper/upkeep_executer_test.go +++ b/core/services/keeper/upkeep_executer_test.go @@ -48,7 +48,7 @@ func mockEstimator(t *testing.T) gas.EvmFeeEstimator { // note: estimator will only return 1 of legacy or dynamic fees (not both) // assumed to call legacy estimator only estimator := gasmocks.NewEvmFeeEstimator(t) - estimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Maybe().Return(gas.EvmFee{ + estimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Maybe().Return(gas.EvmFee{ Legacy: assets.GWei(60), }, uint32(60), nil) return estimator diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go index 993829c1b6..b571ce6f70 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -283,7 +283,7 @@ func TestCommitStoreReaders(t *testing.T) { } gasPrice := big.NewInt(10) daPrice := big.NewInt(20) - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, assets.NewWei(maxGasPrice), (*common.Address)(nil)).Return(gas.EvmFee{Legacy: assets.NewWei(gasPrice)}, uint64(0), nil) + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, assets.NewWei(maxGasPrice), (*common.Address)(nil), (*common.Address)(nil)).Return(gas.EvmFee{Legacy: assets.NewWei(gasPrice)}, uint64(0), nil) lm.On("GasPrice", mock.Anything).Return(assets.NewWei(daPrice), nil) for v, cr := range crs { diff --git a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go index 031dc25ed8..84a6014bef 100644 --- a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go +++ b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go @@ -26,7 +26,7 @@ func NewExecGasPriceEstimator(estimator gas.EvmFeeEstimator, maxGasPrice *big.In } func (g ExecGasPriceEstimator) GetGasPrice(ctx context.Context) (*big.Int, error) { - gasPriceWei, _, err := g.estimator.GetFee(ctx, nil, 0, assets.NewWei(g.maxGasPrice), nil) + gasPriceWei, _, err := g.estimator.GetFee(ctx, nil, 0, assets.NewWei(g.maxGasPrice), nil, nil) if err != nil { return nil, err } diff --git a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go index 6953805709..f9ba1523e5 100644 --- a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go +++ b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go @@ -86,7 +86,7 @@ func TestExecPriceEstimator_GetGasPrice(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { sourceFeeEstimator := mocks.NewEvmFeeEstimator(t) - sourceFeeEstimator.On("GetFee", ctx, []byte(nil), uint64(0), assets.NewWei(tc.maxGasPrice), (*common.Address)(nil)).Return( + sourceFeeEstimator.On("GetFee", ctx, []byte(nil), uint64(0), assets.NewWei(tc.maxGasPrice), (*common.Address)(nil), (*common.Address)(nil)).Return( tc.sourceFeeEstimatorRespFee, uint64(0), tc.sourceFeeEstimatorRespErr) g := ExecGasPriceEstimator{ diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice.go index d54deea406..095972fbf5 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice.go @@ -46,7 +46,7 @@ func CheckGasPrice(ctx context.Context, upkeepId *big.Int, offchainConfigBytes [ } lggr.Debugf("successfully decode offchain config for %s, max gas price is %s", upkeepId.String(), offchainConfig.MaxGasPrice.String()) - fee, _, err := ge.GetFee(ctx, []byte{}, feeLimit, assets.NewWei(big.NewInt(maxFeePrice)), nil) + fee, _, err := ge.GetFee(ctx, []byte{}, feeLimit, assets.NewWei(big.NewInt(maxFeePrice)), nil, nil) if err != nil { lggr.Errorw("failed to get fee, gas price check is disabled", "upkeepId", upkeepId.String(), "err", err) return encoding.UpkeepFailureReasonNone diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice_test.go index 4418dd0f7c..7b5ef999f3 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/gasprice/gasprice_test.go @@ -86,13 +86,13 @@ func TestGasPrice_Check(t *testing.T) { ctx := testutils.Context(t) ge := gasMocks.NewEvmFeeEstimator(t) if test.FailedToGetFee { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return( + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return( gas.EvmFee{}, feeLimit, errors.New("failed to retrieve gas price"), ) } else if test.CurrentLegacyGasPrice != nil { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return( + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return( gas.EvmFee{ Legacy: assets.NewWei(test.CurrentLegacyGasPrice), }, @@ -100,7 +100,7 @@ func TestGasPrice_Check(t *testing.T) { nil, ) } else if test.CurrentDynamicGasPrice != nil { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return( + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return( gas.EvmFee{ DynamicFeeCap: assets.NewWei(test.CurrentDynamicGasPrice), DynamicTipCap: assets.NewWei(big.NewInt(1_000_000_000)), diff --git a/core/services/relay/evm/chain_writer.go b/core/services/relay/evm/chain_writer.go index 6f30ceb4bb..1e07003b88 100644 --- a/core/services/relay/evm/chain_writer.go +++ b/core/services/relay/evm/chain_writer.go @@ -191,7 +191,7 @@ func (w *chainWriter) GetFeeComponents(ctx context.Context) (*commontypes.ChainF return nil, fmt.Errorf("gas estimator not available") } - fee, _, err := w.ge.GetFee(ctx, nil, 0, w.maxGasPrice, nil) + fee, _, err := w.ge.GetFee(ctx, nil, 0, w.maxGasPrice, nil, nil) if err != nil { return nil, err } diff --git a/core/services/relay/evm/chain_writer_test.go b/core/services/relay/evm/chain_writer_test.go index f35e9eece5..b70a0dd0e3 100644 --- a/core/services/relay/evm/chain_writer_test.go +++ b/core/services/relay/evm/chain_writer_test.go @@ -87,7 +87,7 @@ func TestChainWriter(t *testing.T) { }) t.Run("GetFeeComponents", func(t *testing.T) { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ Legacy: assets.NewWei(big.NewInt(1000000001)), DynamicFeeCap: assets.NewWei(big.NewInt(1000000002)), DynamicTipCap: assets.NewWei(big.NewInt(1000000003)), @@ -113,7 +113,7 @@ func TestChainWriter(t *testing.T) { }) t.Run("Returns Legacy Fee in absence of Dynamic Fee", func(t *testing.T) { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ Legacy: assets.NewWei(big.NewInt(1000000001)), DynamicFeeCap: nil, DynamicTipCap: assets.NewWei(big.NewInt(1000000003)), @@ -125,7 +125,7 @@ func TestChainWriter(t *testing.T) { }) t.Run("Fails when neither legacy or dynamic fee is available", func(t *testing.T) { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ Legacy: nil, DynamicFeeCap: nil, DynamicTipCap: nil, @@ -137,7 +137,7 @@ func TestChainWriter(t *testing.T) { t.Run("Fails when GetFee returns an error", func(t *testing.T) { expectedErr := fmt.Errorf("GetFee error") - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ Legacy: nil, DynamicFeeCap: nil, DynamicTipCap: nil, @@ -147,7 +147,7 @@ func TestChainWriter(t *testing.T) { }) t.Run("Fails when L1Oracle returns error", func(t *testing.T) { - ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{ Legacy: assets.NewWei(big.NewInt(1000000001)), DynamicFeeCap: assets.NewWei(big.NewInt(1000000002)), DynamicTipCap: assets.NewWei(big.NewInt(1000000003)), diff --git a/core/web/evm_transfer_controller.go b/core/web/evm_transfer_controller.go index 3e14aaccd3..75f6c07b6d 100644 --- a/core/web/evm_transfer_controller.go +++ b/core/web/evm_transfer_controller.go @@ -116,7 +116,7 @@ func ValidateEthBalanceForTransfer(c *gin.Context, chain legacyevm.Chain, fromAd gasLimit := chain.Config().EVM().GasEstimator().LimitTransfer() estimator := chain.GasEstimator() - amountWithFees, err := estimator.GetMaxCost(c, amount, nil, gasLimit, chain.Config().EVM().GasEstimator().PriceMaxKey(fromAddr), &toAddr) + amountWithFees, err := estimator.GetMaxCost(c, amount, nil, gasLimit, chain.Config().EVM().GasEstimator().PriceMaxKey(fromAddr), &fromAddr, &toAddr) if err != nil { return err } From 808912db8794c0a89cdea960143ae7e73be93d11 Mon Sep 17 00:00:00 2001 From: Clement Date: Tue, 27 Aug 2024 21:18:16 +0200 Subject: [PATCH 181/432] feat(docker): add observability stack (#14203) --- tools/docker/README.md | 5 ++ tools/docker/alertmanager/alertmanager.yml | 15 +++++ tools/docker/compose | 13 +++- .../docker/docker-compose.observability.yaml | 44 ++++++++++++++ tools/docker/grafana/config.monitoring | 2 + .../provisioning/datasources/datasource.yml | 59 +++++++++++++++++++ tools/docker/prometheus/prometheus.yaml | 13 ++++ 7 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 tools/docker/alertmanager/alertmanager.yml create mode 100644 tools/docker/docker-compose.observability.yaml create mode 100644 tools/docker/grafana/config.monitoring create mode 100644 tools/docker/grafana/provisioning/datasources/datasource.yml create mode 100644 tools/docker/prometheus/prometheus.yaml diff --git a/tools/docker/README.md b/tools/docker/README.md index e0ccadd68c..527951e64c 100644 --- a/tools/docker/README.md +++ b/tools/docker/README.md @@ -23,6 +23,7 @@ cd tools/docker ### Compose script env vars The following env vars are used for the compose script : +- `WITH_OBSERVABILITY=true` to enable grafana, prometheus and alertmanager - `GETH_MODE=true` to use geth instead of parity - `CHAIN_ID=` to specify the chainID (default is 34055 for parity and 1337 for geth) - `HTTPURL=` to specify the RPC node HTTP url (default is set if you use geth or parity) @@ -35,6 +36,10 @@ for example : CHAIN_ID=11155111 WSURL=wss://eth.sepolia HTTPURL=https://eth.sepolia ./compose dev ``` +```sh +WITH_OBSERVABILITY=true ./compose up +``` + ## Dev Will run one node with a postgres database and by default a devnet RPC node that can be either geth or parity. diff --git a/tools/docker/alertmanager/alertmanager.yml b/tools/docker/alertmanager/alertmanager.yml new file mode 100644 index 0000000000..7521fd768b --- /dev/null +++ b/tools/docker/alertmanager/alertmanager.yml @@ -0,0 +1,15 @@ + +route: + receiver: 'mail' + repeat_interval: 4h + group_by: [ alertname ] + + +receivers: + - name: 'mail' + email_configs: + - smarthost: 'smtp.gmail.com:465' + auth_username: 'your_mail@gmail.com' + auth_password: "" + from: 'your_mail@gmail.com' + to: 'some_mail@gmail.com' \ No newline at end of file diff --git a/tools/docker/compose b/tools/docker/compose index 0e754a5ffc..abaf377333 100755 --- a/tools/docker/compose +++ b/tools/docker/compose @@ -16,7 +16,14 @@ if [ -z "$WSURL" ] && [ -z "$HTTPURL" ]; then fi fi -base="docker-compose $base_files" +args="node" + +if [ "$WITH_OBSERVABILITY" ]; then + base_files="$base_files -f docker-compose.observability.yaml" + args="$args grafana" +fi + +base="docker compose $base_files" dev="$base -f docker-compose.dev.yaml" configure() { @@ -41,7 +48,7 @@ configure() { clean_docker() { $base down -v --remove-orphans $dev down -v --remove-orphans - rm -f config.toml + rm -rf config.toml } usage() { @@ -71,7 +78,7 @@ logs) dev) configure $dev build - $dev up -d node + $dev up -d $args $dev watch --no-up node ;; connect) diff --git a/tools/docker/docker-compose.observability.yaml b/tools/docker/docker-compose.observability.yaml new file mode 100644 index 0000000000..c82c050d58 --- /dev/null +++ b/tools/docker/docker-compose.observability.yaml @@ -0,0 +1,44 @@ +services: + prometheus: + image: prom/prometheus:main + container_name: chainlink-prometheus + volumes: + - ./prometheus/:/etc/prometheus/ + - prometheus_data:/prometheus + command: + - '--config.file=/etc/prometheus/prometheus.yaml' + - '--storage.tsdb.path=/prometheus' + - '--web.console.libraries=/usr/share/prometheus/console_libraries' + - '--web.console.templates=/usr/share/prometheus/consoles' + restart: always + ports: + - 9090:9090 + grafana: + image: grafana/grafana:10.4.3 + user: "472" + depends_on: + - prometheus + - alertmanager + ports: + - 3000:3000 + volumes: + - grafana_data:/var/lib/grafana + - ./grafana/provisioning/:/etc/grafana/provisioning/ + env_file: + - ./grafana/config.monitoring + restart: always + alertmanager: + image: prom/alertmanager:main + container_name: chainlink-alertmanager + volumes: + - "./alertmanager:/config" + - alertmanager-data:/data + command: --config.file=/config/alertmanager.yml --log.level=debug + restart: always + ports: + - 9093:9093 + +volumes: + alertmanager-data: {} + prometheus_data: {} + grafana_data: {} diff --git a/tools/docker/grafana/config.monitoring b/tools/docker/grafana/config.monitoring new file mode 100644 index 0000000000..a2b009166b --- /dev/null +++ b/tools/docker/grafana/config.monitoring @@ -0,0 +1,2 @@ +GF_SECURITY_ADMIN_PASSWORD=foobar +GF_USERS_ALLOW_SIGN_UP=false \ No newline at end of file diff --git a/tools/docker/grafana/provisioning/datasources/datasource.yml b/tools/docker/grafana/provisioning/datasources/datasource.yml new file mode 100644 index 0000000000..f57418b29f --- /dev/null +++ b/tools/docker/grafana/provisioning/datasources/datasource.yml @@ -0,0 +1,59 @@ +# config file version +apiVersion: 1 + +# list of datasources that should be deleted from the database +deleteDatasources: + - name: Prometheus + orgId: 1 + +# list of datasources to insert/update depending +# whats available in the database +datasources: + # name of the datasource. Required + - name: Prometheus + # datasource type. Required + type: prometheus + # access mode. direct or proxy. Required + access: proxy + # org id. will default to orgId 1 if not specified + orgId: 1 + # url + url: http://prometheus:9090 + # database password, if used + password: + # database user, if used + user: + # database name, if used + database: + # enable/disable basic auth + basicAuth: false + # basic auth username, if used + basicAuthUser: + # basic auth password, if used + basicAuthPassword: + # enable/disable with credentials headers + withCredentials: + # mark as default datasource. Max one per org + isDefault: true + # fields that will be converted to json and stored in json_data + jsonData: + graphiteVersion: "1.1" + tlsAuth: false + tlsAuthWithCACert: false + # json object of data that will be encrypted. + secureJsonData: + tlsCACert: "..." + tlsClientCert: "..." + tlsClientKey: "..." + version: 1 + # allow users to edit datasources from the UI. + editable: true + - name: Alertmanager + type: alertmanager + url: http://alertmanager:9093 + access: proxy + jsonData: + # Valid options for implementation include mimir, cortex and prometheus + implementation: prometheus + # Whether or not Grafana should send alert instances to this Alertmanager + handleGrafanaManagedAlerts: false \ No newline at end of file diff --git a/tools/docker/prometheus/prometheus.yaml b/tools/docker/prometheus/prometheus.yaml new file mode 100644 index 0000000000..96ca106493 --- /dev/null +++ b/tools/docker/prometheus/prometheus.yaml @@ -0,0 +1,13 @@ +global: + scrape_interval: 5s +scrape_configs: + - job_name: 'local_scrape' + scrape_interval: 1s + static_configs: + - targets: ['chainlink-node:6688', 'chainlink-node-2:6688'] + metrics_path: '/metrics' +alerting: + alertmanagers: + - scheme: http + static_configs: + - targets: ['alertmanager:9093'] \ No newline at end of file From ca7b95841843e8e315d0be3c35b4911310cbc175 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:58:19 -0700 Subject: [PATCH 182/432] RE 2877 Jira<->Changeset traceability for solidity changes (#14141) * Migrate contract changeset handling to solidity-jira * Update solidity-jira to handle jira tracability as a whole * Fix changesets output typo * Make file paths absolute * Prevent merge commits from being added by auto commit action * Add issue number to tail of document rather than head * Tighten up file pattern for committing * Add GATI so workflows run on auto commits * Modify workflow to generate jira traceabillity * Add checkout * Fix typo * Add better naming for job * Add more logging * Append to step summary from within script * Extract functions and use labels over individual issues * Fix comments handling * Use plain artifacts URL for action * Add test for jira issues in the middle of comments * Formatting * Actually write to step summary * Make jira host public * Handle csv output rather than JSON * Fix typo in changeset reference * Comment out broken step * Notify that auto commits are made via bot * Pin planetscale/ghcommit-action * Rename * Add pull-requests write perm for comments * Add always() to gha metrics * Use env var for head_ref * Formatting * Use JIRA_HOST rather than hard coded URL --- .../scripts/jira/create-jira-traceability.ts | 205 ++++++++++++++++++ .github/scripts/jira/enforce-jira-issue.ts | 46 +++- .github/scripts/jira/lib.test.ts | 106 ++++++++- .github/scripts/jira/lib.ts | 74 ++++++- .github/scripts/jira/package.json | 1 + .github/workflows/changeset.yml | 25 --- .../workflows/solidity-foundry-artifacts.yml | 64 ++++-- .github/workflows/solidity-jira.yml | 100 --------- .github/workflows/solidity-tracability.yml | 136 ++++++++++++ 9 files changed, 611 insertions(+), 146 deletions(-) create mode 100644 .github/scripts/jira/create-jira-traceability.ts delete mode 100644 .github/workflows/solidity-jira.yml create mode 100644 .github/workflows/solidity-tracability.yml diff --git a/.github/scripts/jira/create-jira-traceability.ts b/.github/scripts/jira/create-jira-traceability.ts new file mode 100644 index 0000000000..b151c9d5ea --- /dev/null +++ b/.github/scripts/jira/create-jira-traceability.ts @@ -0,0 +1,205 @@ +import * as jira from "jira.js"; +import { + createJiraClient, + extractJiraIssueNumbersFrom, + generateIssueLabel, + generateJiraIssuesLink, + getJiraEnvVars, +} from "./lib"; +import * as core from "@actions/core"; + +/** + * Extracts the list of changeset files. Intended to be used with https://github.com/dorny/paths-filter with + * the 'csv' output format. + * + * @returns An array of strings representing the changeset files. + * @throws {Error} If the required environment variable CHANGESET_FILES is missing. + * @throws {Error} If no changeset file exists. + */ +function extractChangesetFiles(): string[] { + const changesetFiles = process.env.CHANGESET_FILES; + if (!changesetFiles) { + throw Error("Missing required environment variable CHANGESET_FILES"); + } + const parsedChangesetFiles = changesetFiles.split(","); + if (parsedChangesetFiles.length === 0) { + throw Error("At least one changeset file must exist"); + } + + core.info( + `Changeset to extract issues from: ${parsedChangesetFiles.join(", ")}` + ); + return parsedChangesetFiles; +} + +/** + * Adds traceability to JIRA issues by commenting on each issue with a link to the artifact payload + * along with a label to connect all issues to the same chainlink product review. + * + * @param client The jira client + * @param issues The list of JIRA issue numbers to add traceability to + * @param label The label to add to each issue + * @param artifactUrl The url to the artifact payload that we'll comment on each issue with + */ +async function addTraceabillityToJiraIssues( + client: jira.Version3Client, + issues: string[], + label: string, + artifactUrl: string +) { + for (const issue of issues) { + await checkAndAddArtifactPayloadComment(client, issue, artifactUrl); + + // CHECK: We don't need to see if the label exists, should no-op + core.info(`Adding label ${label} to issue ${issue}`); + await client.issues.editIssue({ + issueIdOrKey: issue, + update: { + labels: [{ add: label }], + }, + }); + } +} + +/** + * Checks if the artifact payload already exists as a comment on the issue, if not, adds it. + */ +async function checkAndAddArtifactPayloadComment( + client: jira.Version3.Version3Client, + issue: string, + artifactUrl: string +) { + const maxResults = 5000; + const getCommentsResponse = await client.issueComments.getComments({ + issueIdOrKey: issue, + maxResults, // this is the default maxResults, see https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-get + }); + core.debug(JSON.stringify(getCommentsResponse.comments)); + if ((getCommentsResponse.total ?? 0) > maxResults) { + throw Error( + `Too many (${getCommentsResponse.total}) comments on issue ${issue}, please increase maxResults (${maxResults})` + ); + } + + // Search path is getCommentsResponse.comments[].body.content[].content[].marks[].attrs.href + // + // Example: + // [ // getCommentsResponse.comments + // { + // body: { + // type: "doc", + // version: 1, + // content: [ + // { + // type: "paragraph", + // content: [ + // { + // type: "text", + // text: "Artifact URL", + // marks: [ + // { + // type: "link", + // attrs: { + // href: "https://github.com/smartcontractkit/chainlink/actions/runs/10517121836/artifacts/1844867108", + // }, + // }, + // ], + // }, + // ], + // }, + // ], + // }, + // }, + // ]; + const commentExists = getCommentsResponse.comments?.some((c) => + c?.body?.content?.some((innerContent) => + innerContent?.content?.some((c) => + c.marks?.some((m) => m.attrs?.href === artifactUrl) + ) + ) + ); + + if (commentExists) { + core.info(`Artifact payload already exists as comment on issue, skipping`); + } else { + core.info(`Adding artifact payload as comment on issue ${issue}`); + await client.issueComments.addComment({ + issueIdOrKey: issue, + comment: { + type: "doc", + version: 1, + content: [ + { + type: "paragraph", + content: [ + { + type: "text", + text: "Artifact Download URL", + marks: [ + { + type: "link", + attrs: { + href: artifactUrl, + }, + }, + ], + }, + ], + }, + ], + }, + }); + } +} + +function fetchEnvironmentVariables() { + const product = process.env.CHAINLINK_PRODUCT; + if (!product) { + throw Error("CHAINLINK_PRODUCT environment variable is missing"); + } + const baseRef = process.env.BASE_REF; + if (!baseRef) { + throw Error("BASE_REF environment variable is missing"); + } + const headRef = process.env.HEAD_REF; + if (!headRef) { + throw Error("HEAD_REF environment variable is missing"); + } + + const artifactUrl = process.env.ARTIFACT_URL; + if (!artifactUrl) { + throw Error("ARTIFACT_URL environment variable is missing"); + } + return { product, baseRef, headRef, artifactUrl }; +} + +/** + * For all affected jira issues listed within the changeset files supplied, + * we update each jira issue so that they are all labelled and have a comment linking them + * to the relevant artifact URL. + */ +async function main() { + const { product, baseRef, headRef, artifactUrl } = + fetchEnvironmentVariables(); + const changesetFiles = extractChangesetFiles(); + core.info( + `Extracting Jira issue numbers from changeset files: ${changesetFiles.join( + ", " + )}` + ); + const jiraIssueNumbers = await extractJiraIssueNumbersFrom(changesetFiles); + + const client = createJiraClient(); + const label = generateIssueLabel(product, baseRef, headRef); + await addTraceabillityToJiraIssues( + client, + jiraIssueNumbers, + label, + artifactUrl + ); + + const { jiraHost } = getJiraEnvVars() + core.summary.addLink("Jira Issues", generateJiraIssuesLink(`${jiraHost}/issues/`, label)); + core.summary.write(); +} +main(); diff --git a/.github/scripts/jira/enforce-jira-issue.ts b/.github/scripts/jira/enforce-jira-issue.ts index e0054b25d0..9d8c6e490e 100644 --- a/.github/scripts/jira/enforce-jira-issue.ts +++ b/.github/scripts/jira/enforce-jira-issue.ts @@ -1,6 +1,8 @@ import * as core from "@actions/core"; import jira from "jira.js"; -import { createJiraClient, parseIssueNumberFrom } from "./lib"; +import { createJiraClient, getGitTopLevel, parseIssueNumberFrom } from "./lib"; +import { promises as fs } from "fs"; +import { join } from "path"; async function doesIssueExist( client: jira.Version3Client, @@ -44,6 +46,8 @@ async function main() { const commitMessage = process.env.COMMIT_MESSAGE; const branchName = process.env.BRANCH_NAME; const dryRun = !!process.env.DRY_RUN; + const { changesetFile } = extractChangesetFile(); + const client = createJiraClient(); // Checks for the Jira issue number and exit if it can't find it @@ -58,9 +62,47 @@ async function main() { const exists = await doesIssueExist(client, issueNumber, dryRun); if (!exists) { - core.setFailed(`JIRA issue ${issueNumber} not found, this pull request must be associated with a JIRA issue.`); + core.setFailed( + `JIRA issue ${issueNumber} not found, this pull request must be associated with a JIRA issue.` + ); + return; + } + + core.info(`Appending JIRA issue ${issueNumber} to changeset file`); + await appendIssueNumberToChangesetFile(changesetFile, issueNumber); +} + +async function appendIssueNumberToChangesetFile( + changesetFile: string, + issueNumber: string +) { + const gitTopLevel = await getGitTopLevel(); + const fullChangesetPath = join(gitTopLevel, changesetFile); + const changesetContents = await fs.readFile(fullChangesetPath, "utf-8"); + // Check if the issue number is already in the changeset file + if (changesetContents.includes(issueNumber)) { + core.info("Issue number already exists in changeset file, skipping..."); return; } + + const updatedChangesetContents = `${changesetContents}\n\n${issueNumber}`; + await fs.writeFile(fullChangesetPath, updatedChangesetContents); +} + +function extractChangesetFile() { + const changesetFiles = process.env.CHANGESET_FILES; + if (!changesetFiles) { + throw Error("Missing required environment variable CHANGESET_FILES"); + } + const parsedChangesetFiles = JSON.parse(changesetFiles); + if (parsedChangesetFiles.length !== 1) { + throw Error( + "This action only supports one changeset file per pull request." + ); + } + const [changesetFile] = parsedChangesetFiles; + + return { changesetFile }; } async function run() { diff --git a/.github/scripts/jira/lib.test.ts b/.github/scripts/jira/lib.test.ts index 9c751e8408..6ef629a53e 100644 --- a/.github/scripts/jira/lib.test.ts +++ b/.github/scripts/jira/lib.test.ts @@ -1,5 +1,12 @@ -import { expect, describe, it } from "vitest"; -import { parseIssueNumberFrom, tagsToLabels } from "./lib"; +import { expect, describe, it, vi } from "vitest"; +import { + generateIssueLabel, + generateJiraIssuesLink, + getGitTopLevel, + parseIssueNumberFrom, + tagsToLabels, +} from "./lib"; +import * as core from "@actions/core"; describe("parseIssueNumberFrom", () => { it("should return the first JIRA issue number found", () => { @@ -33,6 +40,20 @@ CORE-1011`, const result = parseIssueNumberFrom("No issue number"); expect(result).to.be.undefined; }); + + it("works when the label is in the middle of the commit message", () => { + let r = parseIssueNumberFrom( + "This is a commit message with CORE-123 in the middle", + "CORE-456", + "CORE-789" + ); + expect(r).to.equal("CORE-123"); + + r = parseIssueNumberFrom( + "#internal address security vulnerabilities RE-2917 around updating nodes and node operators on capabilities registry" + ); + expect(r).to.equal("RE-2917"); + }); }); describe("tagsToLabels", () => { @@ -45,3 +66,84 @@ describe("tagsToLabels", () => { ]); }); }); + +const mockExecPromise = vi.fn(); +vi.mock("util", () => ({ + promisify: () => mockExecPromise, +})); + +describe("getGitTopLevel", () => { + it("should log the top-level directory when git command succeeds", async () => { + mockExecPromise.mockResolvedValueOnce({ + stdout: "/path/to/top-level-dir", + stderr: "", + }); + + const mockConsoleLog = vi.spyOn(core, "info"); + await getGitTopLevel(); + + expect(mockExecPromise).toHaveBeenCalledWith( + "git rev-parse --show-toplevel" + ); + expect(mockConsoleLog).toHaveBeenCalledWith( + "Top-level directory: /path/to/top-level-dir" + ); + }); + + it("should log an error message when git command fails", async () => { + mockExecPromise.mockRejectedValueOnce({ + message: "Command failed", + }); + + const mockConsoleError = vi.spyOn(core, "error"); + await getGitTopLevel().catch(() => {}); + + expect(mockExecPromise).toHaveBeenCalledWith( + "git rev-parse --show-toplevel" + ); + expect(mockConsoleError).toHaveBeenCalledWith( + "Error executing command: Command failed" + ); + }); + + it("should log an error message when git command output contains an error", async () => { + mockExecPromise.mockResolvedValueOnce({ + stdout: "", + stderr: "Error: Command failed", + }); + + const mockConsoleError = vi.spyOn(core, "error"); + await getGitTopLevel().catch(() => {}); + + expect(mockExecPromise).toHaveBeenCalledWith( + "git rev-parse --show-toplevel" + ); + expect(mockConsoleError).toHaveBeenCalledWith( + "Error in command output: Error: Command failed" + ); + }); +}); + +describe("generateJiraIssuesLink", () => { + it("should generate a Jira issues link", () => { + expect( + generateJiraIssuesLink( + "https://smartcontract-it.atlassian.net/issues/", + "review-artifacts-automation-base:0de9b3b-head:e5b3b9d" + ) + ).toMatchInlineSnapshot( + `"https://smartcontract-it.atlassian.net/issues/?jql=labels+%3D+%22review-artifacts-automation-base%3A0de9b3b-head%3Ae5b3b9d%22"` + ); + }); +}); + +describe("generateIssueLabel", () => { + it("should generate an issue label", () => { + const product = "automation"; + const baseRef = "0de9b3b"; + const headRef = "e5b3b9d"; + expect(generateIssueLabel(product, baseRef, headRef)).toMatchInlineSnapshot( + `"review-artifacts-automation-base:0de9b3b-head:e5b3b9d"` + ); + }); +}); diff --git a/.github/scripts/jira/lib.ts b/.github/scripts/jira/lib.ts index 72f1d57966..0d0983f5c3 100644 --- a/.github/scripts/jira/lib.ts +++ b/.github/scripts/jira/lib.ts @@ -1,6 +1,51 @@ +import { readFile } from "fs/promises"; +import * as core from "@actions/core"; +import * as jira from "jira.js"; +import { exec } from "child_process"; +import { promisify } from "util"; +import { join } from "path"; -import * as core from '@actions/core' -import * as jira from 'jira.js' +export function generateJiraIssuesLink(baseUrl: string, label: string) { + // https://smartcontract-it.atlassian.net/issues/?jql=labels%20%3D%20%22review-artifacts-automation-base%3A8d818ea265ff08887e61ace4f83364a3ee149ef0-head%3A3c45b71f3610de28f429cef0163936eaa448e63c%22 + const jqlQuery = `labels = "${label}"`; + const fullUrl = new URL(baseUrl); + fullUrl.searchParams.set("jql", jqlQuery); + + const urlStr = fullUrl.toString(); + core.info(`Jira issues link: ${urlStr}`); + return urlStr; +} + +export function generateIssueLabel( + product: string, + baseRef: string, + headRef: string +) { + return `review-artifacts-${product}-base:${baseRef}-head:${headRef}`; +} + +export async function getGitTopLevel(): Promise { + const execPromise = promisify(exec); + try { + const { stdout, stderr } = await execPromise( + "git rev-parse --show-toplevel" + ); + + if (stderr) { + const msg = `Error in command output: ${stderr}`; + core.error(msg); + throw Error(msg); + } + + const topLevelDir = stdout.trim(); + core.info(`Top-level directory: ${topLevelDir}`); + return topLevelDir; + } catch (error) { + const msg = `Error executing command: ${(error as any).message}`; + core.error(msg); + throw Error(msg); + } +} /** * Given a list of strings, this function will return the first JIRA issue number it finds. @@ -24,6 +69,24 @@ export function parseIssueNumberFrom( return parsed[0]; } +export async function extractJiraIssueNumbersFrom(filePaths: string[]) { + const issueNumbers: string[] = []; + const gitTopLevel = await getGitTopLevel(); + + for (const path of filePaths) { + const fullPath = join(gitTopLevel, path); + core.info(`Reading file: ${fullPath}`); + const content = await readFile(fullPath, "utf-8"); + const issueNumber = parseIssueNumberFrom(content); + core.info(`Extracted issue number: ${issueNumber}`); + if (issueNumber) { + issueNumbers.push(issueNumber); + } + } + + return issueNumbers; +} + /** * Converts an array of tags to an array of labels. * @@ -39,7 +102,7 @@ export function tagsToLabels(tags: string[]) { })); } -export function createJiraClient() { +export function getJiraEnvVars() { const jiraHost = process.env.JIRA_HOST; const jiraUserName = process.env.JIRA_USERNAME; const jiraApiToken = process.env.JIRA_API_TOKEN; @@ -51,6 +114,11 @@ export function createJiraClient() { process.exit(1); } + return { jiraHost, jiraUserName, jiraApiToken }; +} + +export function createJiraClient() { + const { jiraHost, jiraUserName, jiraApiToken } = getJiraEnvVars(); return new jira.Version3Client({ host: jiraHost, authentication: { diff --git a/.github/scripts/jira/package.json b/.github/scripts/jira/package.json index 95bfbb1e48..94a805314a 100644 --- a/.github/scripts/jira/package.json +++ b/.github/scripts/jira/package.json @@ -15,6 +15,7 @@ "scripts": { "issue:update": "tsx update-jira-issue.ts", "issue:enforce": "tsx enforce-jira-issue.ts", + "issue:traceability": "tsx create-jira-traceability.ts", "test": "vitest" }, "dependencies": { diff --git a/.github/workflows/changeset.yml b/.github/workflows/changeset.yml index 5e16b90c40..a89e91171e 100644 --- a/.github/workflows/changeset.yml +++ b/.github/workflows/changeset.yml @@ -50,13 +50,8 @@ jobs: - '!core/**/*.json' - '!core/chainlink.goreleaser.Dockerfile' - '!core/chainlink.Dockerfile' - contracts: - - contracts/**/*.sol - - '!contracts/**/*.t.sol' core-changeset: - added: '.changeset/**' - contracts-changeset: - - added: 'contracts/.changeset/**' - name: Check for changeset tags for core id: changeset-tags @@ -120,19 +115,6 @@ jobs: mode: ${{ steps.files-changed.outputs.core-changeset == 'false' && 'upsert' || 'delete' }} create_if_not_exists: ${{ steps.files-changed.outputs.core-changeset == 'false' && 'true' || 'false' }} - - name: Make a comment - uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0 - if: ${{ steps.files-changed.outputs.contracts == 'true' }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - message: | - I see you updated files related to `contracts`. Please run `pnpm changeset` in the `contracts` directory to add a changeset. - reactions: eyes - comment_tag: changeset-contracts - mode: ${{ steps.files-changed.outputs.contracts-changeset == 'false' && 'upsert' || 'delete' }} - create_if_not_exists: ${{ steps.files-changed.outputs.contracts-changeset == 'false' && 'true' || 'false' }} - - name: Check for new changeset for core if: ${{ (steps.files-changed.outputs.core == 'true' || steps.files-changed.outputs.shared == 'true') && steps.files-changed.outputs.core-changeset == 'false' }} shell: bash @@ -140,13 +122,6 @@ jobs: echo "Please run pnpm changeset to add a changeset for core and include in the text at least one tag." exit 1 - - name: Check for new changeset for contracts - if: ${{ steps.files-changed.outputs.contracts == 'true' && steps.files-changed.outputs.contracts-changeset == 'false' }} - shell: bash - run: | - echo "Please run pnpm changeset to add a changeset for contracts." - exit 1 - - name: Make a comment uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0 if: ${{ steps.files-changed.outputs.core-changeset == 'true' }} diff --git a/.github/workflows/solidity-foundry-artifacts.yml b/.github/workflows/solidity-foundry-artifacts.yml index 061caf1ea7..5f03acbe1d 100644 --- a/.github/workflows/solidity-foundry-artifacts.yml +++ b/.github/workflows/solidity-foundry-artifacts.yml @@ -28,6 +28,9 @@ on: env: FOUNDRY_PROFILE: ci + # Unfortunately, we can't use the "default" field in the inputs section, because it does not have + # access to the workflow context + head_ref: ${{ inputs.commit_to_use || github.sha }} jobs: changes: @@ -36,13 +39,13 @@ jobs: outputs: product_changes: ${{ steps.changes-transform.outputs.product_changes }} product_files: ${{ steps.changes-transform.outputs.product_files }} - changeset_changes: ${{ steps.changes-dorny.outputs.changeset }} - changeset_files: ${{ steps.changes-dorny.outputs.changeset_files }} + changeset_changes: ${{ steps.changes.outputs.changeset }} + changeset_files: ${{ steps.changes.outputs.changeset_files }} steps: - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: - ref: ${{ inputs.commit_to_use || github.sha }} + ref: ${{ env.head_ref }} - name: Find modified contracts uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 id: changes-dorny @@ -144,13 +147,13 @@ jobs: shell: bash run: | echo "Product: ${{ inputs.product }}" > contracts/commit_sha_base_ref.txt - echo "Commit SHA used to generate artifacts: ${{ inputs.commit_to_use || github.sha }}" >> contracts/commit_sha_base_ref.txt + echo "Commit SHA used to generate artifacts: ${{ env.head_ref }}" >> contracts/commit_sha_base_ref.txt echo "Base reference SHA used to find modified contracts: ${{ inputs.base_ref }}" >> contracts/commit_sha_base_ref.txt IFS=',' read -r -a modified_files <<< "${{ needs.changes.outputs.product_files }}" echo "# Modified contracts:" > contracts/modified_contracts.md for file in "${modified_files[@]}"; do - echo " - [$file](${{ github.server_url }}/${{ github.repository }}/blob/${{ inputs.commit_to_use || github.sha }}/$file)" >> contracts/modified_contracts.md + echo " - [$file](${{ github.server_url }}/${{ github.repository }}/blob/${{ env.head_ref }}/$file)" >> contracts/modified_contracts.md echo "$file" >> contracts/modified_contracts.txt done @@ -187,7 +190,7 @@ jobs: - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: - ref: ${{ inputs.commit_to_use || github.sha }} + ref: ${{ env.head_ref }} - name: Setup NodeJS uses: ./.github/actions/setup-nodejs @@ -268,7 +271,7 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: fetch-depth: 0 - ref: ${{ inputs.commit_to_use || github.sha }} + ref: ${{ env.head_ref }} - name: Setup NodeJS uses: ./.github/actions/setup-nodejs @@ -315,7 +318,7 @@ jobs: cp contracts/foundry.toml foundry.toml echo "::debug::Processing contracts: $contract_list" - ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ inputs.commit_to_use || github.sha }}/" contracts/configs/slither/.slither.config-artifacts.json "." "$contract_list" "contracts/slither-reports" "--solc-remaps @=contracts/node_modules/@" + ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ env.head_ref }}/" contracts/configs/slither/.slither.config-artifacts.json "." "$contract_list" "contracts/slither-reports" "--solc-remaps @=contracts/node_modules/@" - name: Upload UMLs and Slither reports uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 @@ -343,6 +346,11 @@ jobs: runs-on: ubuntu-latest needs: [coverage-and-book, uml-static-analysis, gather-basic-info, changes] steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + ref: ${{ env.head_ref }} + - name: Download all artifacts uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: @@ -352,7 +360,7 @@ jobs: - name: Upload all artifacts as single package uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: - name: review-artifacts-${{ inputs.product }}-${{ inputs.base_ref }}-${{ inputs.commit_to_use || github.sha }} + name: review-artifacts-${{ inputs.product }}-${{ inputs.base_ref }}-${{ env.head_ref }} path: review_artifacts - name: Remove temporary artifacts @@ -361,18 +369,46 @@ jobs: name: tmp-* - name: Print Artifact URL in job summary + id: gather-all-artifacts env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | ARTIFACTS=$(gh api -X GET repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts) - ARTIFACT_ID=$(echo "$ARTIFACTS" | jq '.artifacts[] | select(.name=="review-artifacts-${{ inputs.product }}-${{ inputs.commit_to_use || github.sha }}") | .id') + ARTIFACT_ID=$(echo "$ARTIFACTS" | jq '.artifacts[] | select(.name=="review-artifacts-${{ inputs.product }}-${{ env.head_ref }}") | .id') echo "Artifact ID: $ARTIFACT_ID" echo "# Solidity Review Artifact Generated" >> $GITHUB_STEP_SUMMARY echo "Product: **${{ inputs.product }}**" >> $GITHUB_STEP_SUMMARY echo "Base Ref used: **${{ inputs.base_ref }}**" >> $GITHUB_STEP_SUMMARY - echo "Commit SHA used: **${{ inputs.commit_to_use || github.sha }}**" >> $GITHUB_STEP_SUMMARY - echo "[Artifact URL](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/$ARTIFACT_ID)" >> $GITHUB_STEP_SUMMARY + echo "Commit SHA used: **${{ env.head_ref }}**" >> $GITHUB_STEP_SUMMARY + + artifact_url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/$ARTIFACT_ID" + echo "[Artifact URL]($artifact_url)" >> $GITHUB_STEP_SUMMARY + echo "artifact-url=$artifact_url" >> $GITHUB_OUTPUT + + - name: Setup NodeJS + uses: ./.github/actions/setup-nodejs + + - name: Setup Jira + working-directory: ./.github/scripts/jira + run: pnpm i + + - name: Create Traceability + working-directory: ./.github/scripts/jira + run: | + pnpm issue:traceability + env: + CHANGESET_FILES: ${{ needs.changes.outputs.changeset_files }} + CHAINLINK_PRODUCT: ${{ inputs.product }} + BASE_REF: ${{ inputs.base_ref }} + HEAD_REF: ${{ env.head_ref }} + ARTIFACT_URL: ${{ steps.gather-all-artifacts.outputs.artifact-url }} + + JIRA_HOST: https://smartcontract-it.atlassian.net/ + JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} + JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} + + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} notify-no-changes: if: ${{ needs.changes.outputs.product_changes == 'false' }} @@ -384,9 +420,9 @@ jobs: run: | echo "# Solidity Review Artifact NOT Generated" >> $GITHUB_STEP_SUMMARY echo "Base Ref used: **${{ inputs.base_ref }}**" >> $GITHUB_STEP_SUMMARY - echo "Commit SHA used: **${{ inputs.commit_to_use || github.sha }}**" >> $GITHUB_STEP_SUMMARY + echo "Commit SHA used: **${{ env.head_ref }}**" >> $GITHUB_STEP_SUMMARY echo "## Reason: No modified Solidity files found for ${{ inputs.product }}" >> $GITHUB_STEP_SUMMARY - echo "* no modified Solidity files found between ${{ inputs.base_ref }} and ${{ inputs.commit_to_use || github.sha }} commits" >> $GITHUB_STEP_SUMMARY + echo "* no modified Solidity files found between ${{ inputs.base_ref }} and ${{ env.head_ref }} commits" >> $GITHUB_STEP_SUMMARY echo "* or they are located outside of ./contracts/src/v0.8 folder" >> $GITHUB_STEP_SUMMARY echo "* or they were limited to test files" >> $GITHUB_STEP_SUMMARY exit 1 diff --git a/.github/workflows/solidity-jira.yml b/.github/workflows/solidity-jira.yml deleted file mode 100644 index 1054bfa987..0000000000 --- a/.github/workflows/solidity-jira.yml +++ /dev/null @@ -1,100 +0,0 @@ -# This is its own independent workflow since "solidity.yml" depends on "merge_group" and "push" events. -# But for ensuring that JIRA tickets are always updated, we only care about "pull_request" events. -# -# We still need to add "merge_group" event and noop so that we'll pass required workflow checks. -# -# I didn't add this to the "changeset.yml" workflow because the "changeset" job isnt required, and we'd need to add the "merge_group" event to the "changeset.yml" workflow. -# If we made the change to make it required. -name: Solidity Jira - -on: - merge_group: - pull_request: - -defaults: - run: - shell: bash - -jobs: - skip-enforce-jira-issue: - name: Should Skip - # We want to skip merge_group events, and any release branches - # Since we only want to enforce Jira issues on pull requests related to feature branches - if: ${{ github.event_name != 'merge_group' && !startsWith(github.head_ref, 'release/') }} - outputs: - should-enforce: ${{ steps.changed_files.outputs.only_src_contracts }} - runs-on: ubuntu-latest - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - # We don't use detect-solidity-file-changes here because we need to use the "every" predicate quantifier - - name: Filter paths - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 - id: changed_files - with: - list-files: "csv" - # This is a valid input, see https://github.com/dorny/paths-filter/pull/226 - predicate-quantifier: "every" - filters: | - only_src_contracts: - - contracts/**/*.sol - - '!contracts/**/*.t.sol' - - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: solidity-jira - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Should Skip - continue-on-error: true - - enforce-jira-issue: - name: Enforce Jira Issue - runs-on: ubuntu-latest - # If a needs job is skipped, this job will be skipped and counted as successful - # The job skips on merge_group events, and any release branches - # Since we only want to enforce Jira issues on pull requests related to feature branches - needs: [skip-enforce-jira-issue] - # In addition to the above conditions, we only want to running on solidity related PRs. - # - # Note: A job that is skipped will report its status as "Success". - # It will not prevent a pull request from merging, even if it is a required check. - if: ${{ needs.skip-enforce-jira-issue.outputs.should-enforce == 'true' }} - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - - name: Setup NodeJS - uses: ./.github/actions/setup-nodejs - - - name: Setup Jira - working-directory: ./.github/scripts/jira - run: pnpm i - - - name: Enforce Jira Issue - working-directory: ./.github/scripts/jira - run: | - echo "COMMIT_MESSAGE=$(git log -1 --pretty=format:'%s')" >> $GITHUB_ENV - pnpm issue:enforce - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - JIRA_HOST: ${{ secrets.JIRA_HOST }} - JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - PR_TITLE: ${{ github.event.pull_request.title }} - BRANCH_NAME: ${{ github.event.pull_request.head.ref }} - - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: solidity-jira - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Enforce Jira Issue - continue-on-error: true diff --git a/.github/workflows/solidity-tracability.yml b/.github/workflows/solidity-tracability.yml new file mode 100644 index 0000000000..4acf94688a --- /dev/null +++ b/.github/workflows/solidity-tracability.yml @@ -0,0 +1,136 @@ +# This workflow handles the enforcement of code Traceability via changesets and jira issue linking for our Solidity codebase. +name: Solidity Tracability + +on: + merge_group: + pull_request: + +defaults: + run: + shell: bash + +jobs: + files-changed: + # The job skips on merge_group events, and any release branches, and forks + # Since we only want to enforce Jira issues on pull requests related to feature branches + if: ${{ github.event_name != 'merge_group' && !startsWith(github.head_ref, 'release/') && github.event.pull_request.head.repo.full_name == 'smartcontractkit/chainlink' }} + name: Detect Changes + runs-on: ubuntu-latest + outputs: + source: ${{ steps.files-changed.outputs.source }} + changesets: ${{ steps.files-changed.outputs.changesets }} + changesets_files: ${{ steps.files-changed.outputs.changesets_files }} + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Filter paths + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: files-changed + with: + list-files: "json" + # This is a valid input, see https://github.com/dorny/paths-filter/pull/226 + predicate-quantifier: "every" + filters: | + source: + - contracts/**/*.sol + - '!contracts/**/*.t.sol' + changesets: + - 'contracts/.changeset/**' + + enforce-traceability: + # Note: A job that is skipped will report its status as "Success". + # It will not prevent a pull request from merging, even if it is a required check. + needs: [files-changed] + # We only want to run this job if the source files have changed + if: ${{ needs.files-changed.outputs.source == 'true' }} + name: Enforce Traceability + runs-on: ubuntu-latest + permissions: + actions: read + id-token: write + contents: read + pull-requests: write + steps: + # https://github.com/planetscale/ghcommit-action/blob/c7915d6c18d5ce4eb42b0eff3f10a29fe0766e4c/README.md?plain=1#L41 + # + # Include the pull request ref in the checkout action to prevent merge commit + # https://github.com/actions/checkout?tab=readme-ov-file#checkout-pull-request-head-commit-instead-of-merge-commit + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Assume role capable of dispatching action + uses: smartcontractkit/.github/actions/setup-github-token@ef78fa97bf3c77de6563db1175422703e9e6674f # setup-github-token@0.2.1 + id: get-gh-token + with: + aws-role-arn: ${{ secrets.AWS_OIDC_CHAINLINK_CI_AUTO_PR_TOKEN_ISSUER_ROLE_ARN }} + aws-lambda-url: ${{ secrets.AWS_INFRA_RELENG_TOKEN_ISSUER_LAMBDA_URL }} + aws-region: ${{ secrets.AWS_REGION }} + + - name: Make a comment + uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0 + with: + message: | + I see you updated files related to `contracts`. Please run `pnpm changeset` in the `contracts` directory to add a changeset. + reactions: eyes + comment_tag: changeset-contracts + # If the changeset is added, then we delete the comment, otherwise we add it. + mode: ${{ needs.files-changed.outputs.changesets == 'true' && 'delete' || 'upsert' }} + # We only create the comment if the changeset is not added + create_if_not_exists: ${{ needs.files-changed.outputs.changesets == 'true' && 'false' || 'true' }} + + - name: Check for new changeset for contracts + if: ${{ needs.files-changed.outputs.changesets == 'false' }} + shell: bash + run: | + echo "Please run pnpm changeset to add a changeset for contracts." + exit 1 + + - name: Setup NodeJS + uses: ./.github/actions/setup-nodejs + + - name: Setup Jira + working-directory: ./.github/scripts/jira + run: pnpm i + + # Because of our earlier checks, we know that both the source and changeset files have changed + - name: Enforce Traceability + working-directory: ./.github/scripts/jira + run: | + echo "COMMIT_MESSAGE=$(git log -1 --pretty=format:'%s')" >> $GITHUB_ENV + pnpm issue:enforce + env: + CHANGESET_FILES: ${{ needs.files-changed.outputs.changesets_files }} + + PR_TITLE: ${{ github.event.pull_request.title }} + BRANCH_NAME: ${{ github.event.pull_request.head.ref }} + + JIRA_HOST: https://smartcontract-it.atlassian.net/ + JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} + JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} + + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Commit appended changeset file back to repo + - uses: planetscale/ghcommit-action@13a844326508cdefc72235201bb0446d6d10a85f # v0.1.6 + with: + commit_message: "[Bot] Update changeset file with jira issue" + repo: ${{ github.repository }} + branch: ${{ github.head_ref }} + file_pattern: "contracts/.changeset/*" + env: + GITHUB_TOKEN: ${{ steps.get-gh-token.outputs.access-token }} + + - name: Collect Metrics + id: collect-gha-metrics + if: always() + uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 + with: + id: soldity-traceability + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Enforce Traceability + continue-on-error: true From c39590e20fb3a4adc82cdd1c6132fe5d0d29164f Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 28 Aug 2024 12:19:01 +0200 Subject: [PATCH 183/432] bump common for sql performance improvements (#14247) --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 765accddc0..ce08618dfc 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index ba0c66277b..7a9b3d4599 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1186,8 +1186,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 h1:W8jK09xMKjhnduR4FsyM2aQKe+4/K1EsAhfJQgv2DEk= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 h1:udSMgCcpOWlx+OjLlqYKGAveHUO0ZujuO8I2dmwDHQ8= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= diff --git a/go.mod b/go.mod index 7210941bd0..e82f6dbc1f 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index fb9d877c56..f47f747072 100644 --- a/go.sum +++ b/go.sum @@ -1141,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 h1:W8jK09xMKjhnduR4FsyM2aQKe+4/K1EsAhfJQgv2DEk= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 h1:udSMgCcpOWlx+OjLlqYKGAveHUO0ZujuO8I2dmwDHQ8= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index ca83d3ac12..9a3a5b1ca4 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -36,7 +36,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 github.com/smartcontractkit/chainlink-testing-framework v1.34.9 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 0014577f21..74d3e8fd13 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1433,8 +1433,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 h1:W8jK09xMKjhnduR4FsyM2aQKe+4/K1EsAhfJQgv2DEk= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 h1:udSMgCcpOWlx+OjLlqYKGAveHUO0ZujuO8I2dmwDHQ8= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 6562e45d0a..cebedca102 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 github.com/smartcontractkit/chainlink-testing-framework v1.34.9 github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index c0e8e044fd..c481761607 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1395,8 +1395,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84 h1:W8jK09xMKjhnduR4FsyM2aQKe+4/K1EsAhfJQgv2DEk= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240823143943-86fc7c5deb84/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 h1:udSMgCcpOWlx+OjLlqYKGAveHUO0ZujuO8I2dmwDHQ8= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= From d0d2f3046d44dc929b97bfff69b2daf4de2d4c8e Mon Sep 17 00:00:00 2001 From: Juan Farber Date: Wed, 28 Aug 2024 08:44:50 -0300 Subject: [PATCH 184/432] [BCI-3991] - Remove CR from relayer struct (#14146) * remove CR from relayer struct * add changeset * init contract reader from relay args --- .changeset/tasty-dogs-arrive.md | 5 +++++ core/services/relay/evm/evm.go | 22 ++++++++++++++++----- core/services/relay/evm/mercury_provider.go | 5 +---- core/services/relay/evm/plugin_provider.go | 21 ++++++++++++++------ 4 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 .changeset/tasty-dogs-arrive.md diff --git a/.changeset/tasty-dogs-arrive.md b/.changeset/tasty-dogs-arrive.md new file mode 100644 index 0000000000..1e149f7081 --- /dev/null +++ b/.changeset/tasty-dogs-arrive.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +remove chainReader from the Relayer struct. #internal diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index ee22f19814..fffac7194d 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -140,7 +140,6 @@ type Relayer struct { lggr logger.SugaredLogger ks CSAETHKeystore mercuryPool wsrpc.Pool - chainReader commontypes.ContractReader codec commontypes.Codec capabilitiesRegistry coretypes.CapabilitiesRegistry @@ -273,10 +272,14 @@ func (r *Relayer) NewOCR3CapabilityProvider(rargs commontypes.RelayArgs, pargs c func (r *Relayer) NewPluginProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.PluginProvider, error) { // TODO https://smartcontract-it.atlassian.net/browse/BCF-2887 ctx := context.Background() - lggr := logger.Sugared(r.lggr).Named("PluginProvider").Named(rargs.ExternalJobID.String()) + relayOpts := types.NewRelayOpts(rargs) + relayConfig, err := relayOpts.RelayConfig() + if err != nil { + return nil, fmt.Errorf("failed to get relay config: %w", err) + } - configWatcher, err := newStandardConfigProvider(ctx, r.lggr, r.chain, types.NewRelayOpts(rargs)) + configWatcher, err := newStandardConfigProvider(ctx, r.lggr, r.chain, relayOpts) if err != nil { return nil, err } @@ -286,8 +289,17 @@ func (r *Relayer) NewPluginProvider(rargs commontypes.RelayArgs, pargs commontyp return nil, err } + var chainReaderService ChainReaderService + if relayConfig.ChainReader != nil { + if chainReaderService, err = NewChainReaderService(ctx, lggr, r.chain.LogPoller(), r.chain.HeadTracker(), r.chain.Client(), *relayConfig.ChainReader); err != nil { + return nil, err + } + } else { + lggr.Info("ChainReader missing from RelayConfig") + } + return NewPluginProvider( - r.chainReader, + chainReaderService, r.codec, transmitter, configWatcher, @@ -379,7 +391,7 @@ func (r *Relayer) NewMercuryProvider(rargs commontypes.RelayArgs, pargs commonty } transmitter := mercury.NewTransmitter(lggr, r.transmitterCfg, clients, privKey.PublicKey, rargs.JobID, *relayConfig.FeedID, r.mercuryORM, transmitterCodec, r.triggerCapability) - return NewMercuryProvider(cp, r.chainReader, r.codec, NewMercuryChainReader(r.chain.HeadTracker()), transmitter, reportCodecV1, reportCodecV2, reportCodecV3, reportCodecV4, lggr), nil + return NewMercuryProvider(cp, r.codec, NewMercuryChainReader(r.chain.HeadTracker()), transmitter, reportCodecV1, reportCodecV2, reportCodecV3, reportCodecV4, lggr), nil } func (r *Relayer) NewLLOProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.LLOProvider, error) { diff --git a/core/services/relay/evm/mercury_provider.go b/core/services/relay/evm/mercury_provider.go index 58806e3dd7..807ace6ce1 100644 --- a/core/services/relay/evm/mercury_provider.go +++ b/core/services/relay/evm/mercury_provider.go @@ -25,7 +25,6 @@ var _ commontypes.MercuryProvider = (*mercuryProvider)(nil) type mercuryProvider struct { cp commontypes.ConfigProvider - chainReader commontypes.ContractReader codec commontypes.Codec transmitter evmmercury.Transmitter reportCodecV1 v1.ReportCodec @@ -39,7 +38,6 @@ type mercuryProvider struct { func NewMercuryProvider( cp commontypes.ConfigProvider, - chainReader commontypes.ContractReader, codec commontypes.Codec, mercuryChainReader mercurytypes.ChainReader, transmitter evmmercury.Transmitter, @@ -51,7 +49,6 @@ func NewMercuryProvider( ) *mercuryProvider { return &mercuryProvider{ cp, - chainReader, codec, transmitter, reportCodecV1, @@ -132,7 +129,7 @@ func (p *mercuryProvider) MercuryServerFetcher() mercurytypes.ServerFetcher { } func (p *mercuryProvider) ChainReader() commontypes.ContractReader { - return p.chainReader + return nil } var _ mercurytypes.ChainReader = (*mercuryChainReader)(nil) diff --git a/core/services/relay/evm/plugin_provider.go b/core/services/relay/evm/plugin_provider.go index 58bfc1e525..780b134074 100644 --- a/core/services/relay/evm/plugin_provider.go +++ b/core/services/relay/evm/plugin_provider.go @@ -12,9 +12,9 @@ import ( type pluginProvider struct { services.Service - chainReader types.ContractReader + chainReader ChainReaderService codec types.Codec - contractTransmitter ocrtypes.ContractTransmitter + contractTransmitter ContractTransmitter configWatcher *configWatcher lggr logger.Logger ms services.MultiStart @@ -23,9 +23,9 @@ type pluginProvider struct { var _ types.PluginProvider = (*pluginProvider)(nil) func NewPluginProvider( - chainReader types.ContractReader, + chainReader ChainReaderService, codec types.Codec, - contractTransmitter ocrtypes.ContractTransmitter, + contractTransmitter ContractTransmitter, configWatcher *configWatcher, lggr logger.Logger, ) *pluginProvider { @@ -46,6 +46,10 @@ func (p *pluginProvider) Ready() error { return nil } func (p *pluginProvider) HealthReport() map[string]error { hp := map[string]error{p.Name(): p.Ready()} services.CopyHealth(hp, p.configWatcher.HealthReport()) + services.CopyHealth(hp, p.contractTransmitter.HealthReport()) + if p.chainReader != nil { + services.CopyHealth(hp, p.chainReader.HealthReport()) + } return hp } @@ -70,9 +74,14 @@ func (p *pluginProvider) Codec() types.Codec { } func (p *pluginProvider) Start(ctx context.Context) error { - return p.configWatcher.Start(ctx) + srvcs := []services.StartClose{p.configWatcher, p.contractTransmitter} + if p.chainReader != nil { + srvcs = append(srvcs, p.chainReader) + } + + return p.ms.Start(ctx, srvcs...) } func (p *pluginProvider) Close() error { - return p.configWatcher.Close() + return p.ms.Close() } From 710d48e35ca539bfeae59ec5e9af15957bf3b7d1 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Wed, 28 Aug 2024 15:44:58 +0200 Subject: [PATCH 185/432] switch to CTF WASP package (#14255) * switch to CTF WASP package * fix goimports * update to wasp tag * update CTF, remove dep * update CTF, remove dep * fix goimports * fix goimports --- .../ccip-tests/load/ccip_loadgen.go | 3 +- .../ccip-tests/load/ccip_multicall_loadgen.go | 3 +- integration-tests/ccip-tests/load/helper.go | 3 +- .../ethereum/OffchainAggregatorEventsMock.go | 1 + .../contracts/ethereum/StakingEventsMock.go | 1 + integration-tests/go.mod | 12 +++----- integration-tests/go.sum | 28 ++++++------------- .../automationv2_1/automationv2_1_test.go | 3 +- integration-tests/load/automationv2_1/gun.go | 3 +- .../load/functions/functions_test.go | 3 +- .../load/functions/functionscmd/dashboard.go | 3 +- .../load/functions/gateway_gun.go | 3 +- .../load/functions/gateway_test.go | 3 +- .../load/functions/onchain_monitoring.go | 3 +- .../load/functions/request_gun.go | 2 +- integration-tests/load/go.mod | 8 +++--- integration-tests/load/go.sum | 20 ++++++------- integration-tests/load/ocr/gun.go | 3 +- integration-tests/load/ocr/ocr_test.go | 2 +- integration-tests/load/ocr/vu.go | 3 +- integration-tests/load/vrfv2/gun.go | 3 +- .../load/vrfv2/onchain_monitoring.go | 3 +- integration-tests/load/vrfv2/vrfv2_test.go | 3 +- .../load/vrfv2/vrfv2cmd/dashboard.go | 2 +- integration-tests/load/vrfv2plus/gun.go | 3 +- .../load/vrfv2plus/onchain_monitoring.go | 3 +- .../load/vrfv2plus/vrfv2plus_test.go | 3 +- .../load/vrfv2plus/vrfv2pluscmd/dashboard.go | 2 +- .../load/zcluster/cluster_entrypoint_test.go | 3 +- integration-tests/universal/log_poller/gun.go | 2 +- .../universal/log_poller/helpers.go | 3 +- .../web/sdk/internal/generated/generated.go | 1 + 32 files changed, 72 insertions(+), 69 deletions(-) diff --git a/integration-tests/ccip-tests/load/ccip_loadgen.go b/integration-tests/ccip-tests/load/ccip_loadgen.go index 4ed54a45fd..9dc8ce16e5 100644 --- a/integration-tests/ccip-tests/load/ccip_loadgen.go +++ b/integration-tests/ccip-tests/load/ccip_loadgen.go @@ -15,10 +15,11 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/rs/zerolog" chain_selectors "github.com/smartcontractkit/chain-selectors" - "github.com/smartcontractkit/wasp" "github.com/stretchr/testify/require" "go.uber.org/atomic" + "github.com/smartcontractkit/chainlink-testing-framework/wasp" + "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" diff --git a/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go b/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go index ad3960dee2..85f0ac222a 100644 --- a/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go +++ b/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go @@ -12,7 +12,8 @@ import ( "golang.org/x/sync/errgroup" chain_selectors "github.com/smartcontractkit/chain-selectors" - "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/logging" diff --git a/integration-tests/ccip-tests/load/helper.go b/integration-tests/ccip-tests/load/helper.go index 9522a6c346..8fd2c94c08 100644 --- a/integration-tests/ccip-tests/load/helper.go +++ b/integration-tests/ccip-tests/load/helper.go @@ -12,11 +12,12 @@ import ( "github.com/AlekSi/pointer" "github.com/rs/zerolog" - "github.com/smartcontractkit/wasp" "github.com/stretchr/testify/require" "go.uber.org/atomic" "golang.org/x/sync/errgroup" + "github.com/smartcontractkit/chainlink-testing-framework/wasp" + "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-testing-framework/k8s/chaos" diff --git a/integration-tests/contracts/ethereum/OffchainAggregatorEventsMock.go b/integration-tests/contracts/ethereum/OffchainAggregatorEventsMock.go index 86963e01a4..1006daa034 100644 --- a/integration-tests/contracts/ethereum/OffchainAggregatorEventsMock.go +++ b/integration-tests/contracts/ethereum/OffchainAggregatorEventsMock.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" ) diff --git a/integration-tests/contracts/ethereum/StakingEventsMock.go b/integration-tests/contracts/ethereum/StakingEventsMock.go index 5a1a1663ba..b3b695ea30 100644 --- a/integration-tests/contracts/ethereum/StakingEventsMock.go +++ b/integration-tests/contracts/ethereum/StakingEventsMock.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" ) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 9a3a5b1ca4..cd6865c99c 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -37,13 +37,13 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 - github.com/smartcontractkit/chainlink-testing-framework v1.34.9 + github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 - github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 + github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 + github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/smartcontractkit/wasp v0.4.5 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 github.com/test-go/testify v1.1.4 @@ -86,8 +86,6 @@ require ( github.com/CosmWasm/wasmd v0.40.1 // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect - github.com/K-Phoen/grabana v0.22.1 // indirect - github.com/K-Phoen/sdk v0.12.4 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect @@ -259,14 +257,12 @@ require ( github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/sessions v1.2.2 // indirect github.com/gorilla/websocket v1.5.1 // indirect - github.com/gosimple/slug v1.13.1 // indirect - github.com/gosimple/unidecode v1.0.1 // indirect github.com/grafana/dskit v0.0.0-20231120170505-765e343eda4f // indirect github.com/grafana/gomemcache v0.0.0-20231023152154-6947259a0586 // indirect github.com/grafana/grafana-foundation-sdk/go v0.0.0-20240326122733-6f96a993222b // indirect github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 // indirect github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect - github.com/grafana/pyroscope-go v1.1.1 // indirect + github.com/grafana/pyroscope-go v1.1.2 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 74d3e8fd13..d126883627 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -125,10 +125,6 @@ github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/K-Phoen/grabana v0.22.1 h1:b/O+C3H2H6VNYSeMCYUO4X4wYuwFXgBcRkvYa+fjpQA= -github.com/K-Phoen/grabana v0.22.1/go.mod h1:3LTXrTzQzTKTgvKSXdRjlsJbizSOW/V23Q3iX00R5bU= -github.com/K-Phoen/sdk v0.12.4 h1:j2EYuBJm3zDTD0fGKACVFWxAXtkR0q5QzfVqxmHSeGQ= -github.com/K-Phoen/sdk v0.12.4/go.mod h1:qmM0wO23CtoDux528MXPpYvS4XkRWkWX6rvX9Za8EVU= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= @@ -822,10 +818,6 @@ github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8L github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/gosimple/slug v1.13.1 h1:bQ+kpX9Qa6tHRaK+fZR0A0M2Kd7Pa5eHPPsb1JpHD+Q= -github.com/gosimple/slug v1.13.1/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= -github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= -github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= github.com/grafana/dskit v0.0.0-20231120170505-765e343eda4f h1:gyojr97YeWZ70pKNakWv5/tKwBHuLy3icnIeCo9gQr4= github.com/grafana/dskit v0.0.0-20231120170505-765e343eda4f/go.mod h1:8dsy5tQOkeNQyjXpm5mQsbCu3H5uzeBD35MzRQFznKU= github.com/grafana/gomemcache v0.0.0-20231023152154-6947259a0586 h1:/of8Z8taCPftShATouOrBVy6GaTTjgQd/VfNiZp/VXQ= @@ -836,8 +828,8 @@ github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 h1:gdrsYbmk8822v6qv github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503/go.mod h1:d8seWXCEXkL42mhuIJYcGi6DxfehzoIpLrMQWJojvOo= github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 h1:wQ0FnSeebhJIBkgYOD06Mxk9HV2KhtEG0hp/7R+5RUQ= github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0= -github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= -github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= +github.com/grafana/pyroscope-go v1.1.2 h1:7vCfdORYQMCxIzI3NlYAs3FcBP760+gWuYWOyiVyYx8= +github.com/grafana/pyroscope-go v1.1.2/go.mod h1:HSSmHo2KRn6FasBA4vK7BMiQqyQq8KSuBKvrhkXxYPU= github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= @@ -1344,10 +1336,6 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 h1:6ksZ7t1hNOzGPPs8DK7SvXQf6UfWzi+W5Z7PCBl8gx4= github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510/go.mod h1:UC0TwJiF90m2T3iYPQBKnGu8gv3s55dF/EgpTq8gyvo= -github.com/pyroscope-io/client v0.7.1 h1:yFRhj3vbgjBxehvxQmedmUWJQ4CAfCHhn+itPsuWsHw= -github.com/pyroscope-io/client v0.7.1/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU= -github.com/pyroscope-io/godeltaprof v0.1.2 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4= -github.com/pyroscope-io/godeltaprof v0.1.2/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= @@ -1445,14 +1433,16 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.9 h1:SA7YdICzBmIOFMzLBMAol3CYPyLEF7yKkx63SUrB4RE= -github.com/smartcontractkit/chainlink-testing-framework v1.34.9/go.mod h1:t2au5jHgrDklr25+Nurcy40Bgy5o5VBJvjipmnm6nVc= +github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe h1:5EaoT0jYlmubsDawLVLgPxgEWG7IPxjuxJP3cJ1wRzw= +github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 h1:1/r1wQZ4TOFpZ13w94r7amdF096Z96RuEnkOmrz1BGE= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 h1:wEc6EKMOOK/9w6z/zv2/wPZsV/txctbYoVJ1sCxhXwI= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0/go.mod h1:upYGPS9lOBW2pJg6XD8TTNSD1GtRfayU2Ct5bcfvqFw= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 h1:ItZ75xmt+VHR/lw+GJwSWj9XICpgZ94dJ+I/5jdet7c= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= +github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= +github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= @@ -1463,8 +1453,6 @@ github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235- github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= -github.com/smartcontractkit/wasp v0.4.5 h1:pgiXwBci2m15eo33AzspzhpNG/gxg+8QGxl+I5LpfsQ= -github.com/smartcontractkit/wasp v0.4.5/go.mod h1:eVhBVLbVv0qORUlN7aR5C4aTN/lTYO3KnN1erO4ROOI= github.com/smartcontractkit/wsrpc v0.8.1 h1:kk0SXLqWrWaZ3J6c7n8D0NZ2uTMBBBpG5dZZXZX8UGE= github.com/smartcontractkit/wsrpc v0.8.1/go.mod h1:yfg8v8fPLXkb6Mcnx6Pm/snP6jJ0r5Kf762Yd1a/KpA= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= diff --git a/integration-tests/load/automationv2_1/automationv2_1_test.go b/integration-tests/load/automationv2_1/automationv2_1_test.go index 0fe13d4bc7..cc9bbb9291 100644 --- a/integration-tests/load/automationv2_1/automationv2_1_test.go +++ b/integration-tests/load/automationv2_1/automationv2_1_test.go @@ -23,7 +23,8 @@ import ( "github.com/stretchr/testify/require" ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/wasp" ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" diff --git a/integration-tests/load/automationv2_1/gun.go b/integration-tests/load/automationv2_1/gun.go index a5fd52c40c..aa61562741 100644 --- a/integration-tests/load/automationv2_1/gun.go +++ b/integration-tests/load/automationv2_1/gun.go @@ -5,7 +5,8 @@ import ( "sync" "github.com/rs/zerolog" - "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink-testing-framework/seth" diff --git a/integration-tests/load/functions/functions_test.go b/integration-tests/load/functions/functions_test.go index 374b3df705..90c163ca37 100644 --- a/integration-tests/load/functions/functions_test.go +++ b/integration-tests/load/functions/functions_test.go @@ -4,9 +4,10 @@ import ( "testing" "time" - "github.com/smartcontractkit/wasp" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/wasp" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" ) diff --git a/integration-tests/load/functions/functionscmd/dashboard.go b/integration-tests/load/functions/functionscmd/dashboard.go index ccf5674023..b0a00602f8 100644 --- a/integration-tests/load/functions/functionscmd/dashboard.go +++ b/integration-tests/load/functions/functionscmd/dashboard.go @@ -4,7 +4,8 @@ import ( "github.com/K-Phoen/grabana/dashboard" "github.com/K-Phoen/grabana/logs" "github.com/K-Phoen/grabana/row" - db "github.com/smartcontractkit/wasp/dashboard" + + db "github.com/smartcontractkit/chainlink-testing-framework/wasp/dashboard" ) func main() { diff --git a/integration-tests/load/functions/gateway_gun.go b/integration-tests/load/functions/gateway_gun.go index cc6132e94e..38eddd3163 100644 --- a/integration-tests/load/functions/gateway_gun.go +++ b/integration-tests/load/functions/gateway_gun.go @@ -10,7 +10,8 @@ import ( "github.com/go-resty/resty/v2" "github.com/rs/zerolog/log" "github.com/smartcontractkit/tdh2/go/tdh2/tdh2easy" - "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink/integration-tests/types" ) diff --git a/integration-tests/load/functions/gateway_test.go b/integration-tests/load/functions/gateway_test.go index dd1092a595..9812b7ea08 100644 --- a/integration-tests/load/functions/gateway_test.go +++ b/integration-tests/load/functions/gateway_test.go @@ -3,9 +3,10 @@ package loadfunctions import ( "testing" - "github.com/smartcontractkit/wasp" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/wasp" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" ) diff --git a/integration-tests/load/functions/onchain_monitoring.go b/integration-tests/load/functions/onchain_monitoring.go index 31ca8752dd..942103a78b 100644 --- a/integration-tests/load/functions/onchain_monitoring.go +++ b/integration-tests/load/functions/onchain_monitoring.go @@ -5,7 +5,8 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/wasp" ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" ) diff --git a/integration-tests/load/functions/request_gun.go b/integration-tests/load/functions/request_gun.go index 6b79a2f19e..ca9ba82c51 100644 --- a/integration-tests/load/functions/request_gun.go +++ b/integration-tests/load/functions/request_gun.go @@ -1,7 +1,7 @@ package loadfunctions import ( - "github.com/smartcontractkit/wasp" + "github.com/smartcontractkit/chainlink-testing-framework/wasp" ) type TestMode int diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index cebedca102..94999b7328 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,13 +17,13 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 - github.com/smartcontractkit/chainlink-testing-framework v1.34.9 - github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 + github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe + github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 + github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 - github.com/smartcontractkit/wasp v0.4.7 github.com/stretchr/testify v1.9.0 github.com/wiremock/go-wiremock v1.9.0 go.uber.org/ratelimit v0.3.0 @@ -251,7 +251,7 @@ require ( github.com/grafana/grafana-foundation-sdk/go v0.0.0-20240326122733-6f96a993222b // indirect github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 // indirect github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect - github.com/grafana/pyroscope-go v1.1.1 // indirect + github.com/grafana/pyroscope-go v1.1.2 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index c481761607..24a13b5a38 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -812,8 +812,8 @@ github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 h1:gdrsYbmk8822v6qv github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503/go.mod h1:d8seWXCEXkL42mhuIJYcGi6DxfehzoIpLrMQWJojvOo= github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 h1:wQ0FnSeebhJIBkgYOD06Mxk9HV2KhtEG0hp/7R+5RUQ= github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0= -github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= -github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= +github.com/grafana/pyroscope-go v1.1.2 h1:7vCfdORYQMCxIzI3NlYAs3FcBP760+gWuYWOyiVyYx8= +github.com/grafana/pyroscope-go v1.1.2/go.mod h1:HSSmHo2KRn6FasBA4vK7BMiQqyQq8KSuBKvrhkXxYPU= github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= @@ -1308,10 +1308,6 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 h1:6ksZ7t1hNOzGPPs8DK7SvXQf6UfWzi+W5Z7PCBl8gx4= github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510/go.mod h1:UC0TwJiF90m2T3iYPQBKnGu8gv3s55dF/EgpTq8gyvo= -github.com/pyroscope-io/client v0.7.1 h1:yFRhj3vbgjBxehvxQmedmUWJQ4CAfCHhn+itPsuWsHw= -github.com/pyroscope-io/client v0.7.1/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU= -github.com/pyroscope-io/godeltaprof v0.1.2 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4= -github.com/pyroscope-io/godeltaprof v0.1.2/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= @@ -1407,14 +1403,16 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.9 h1:SA7YdICzBmIOFMzLBMAol3CYPyLEF7yKkx63SUrB4RE= -github.com/smartcontractkit/chainlink-testing-framework v1.34.9/go.mod h1:t2au5jHgrDklr25+Nurcy40Bgy5o5VBJvjipmnm6nVc= +github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe h1:5EaoT0jYlmubsDawLVLgPxgEWG7IPxjuxJP3cJ1wRzw= +github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a h1:8GtvGJaGyKzx/ar1yX74GxrzIYWTZVTyv4pYB/1ln8w= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 h1:wEc6EKMOOK/9w6z/zv2/wPZsV/txctbYoVJ1sCxhXwI= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0/go.mod h1:upYGPS9lOBW2pJg6XD8TTNSD1GtRfayU2Ct5bcfvqFw= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 h1:ItZ75xmt+VHR/lw+GJwSWj9XICpgZ94dJ+I/5jdet7c= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= +github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= +github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= @@ -1425,8 +1423,6 @@ github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235- github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= -github.com/smartcontractkit/wasp v0.4.7 h1:7mKJfwzFbuE8xVLUYtLt7Bjw8q/bmVZRW6Ks8kc1LVM= -github.com/smartcontractkit/wasp v0.4.7/go.mod h1:jeabvyXikb2aNoLQwcZGqaz17efrR8NJhpq4seAmdgs= github.com/smartcontractkit/wsrpc v0.8.1 h1:kk0SXLqWrWaZ3J6c7n8D0NZ2uTMBBBpG5dZZXZX8UGE= github.com/smartcontractkit/wsrpc v0.8.1/go.mod h1:yfg8v8fPLXkb6Mcnx6Pm/snP6jJ0r5Kf762Yd1a/KpA= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= diff --git a/integration-tests/load/ocr/gun.go b/integration-tests/load/ocr/gun.go index 5ed71f1672..990c77e0b3 100644 --- a/integration-tests/load/ocr/gun.go +++ b/integration-tests/load/ocr/gun.go @@ -6,7 +6,8 @@ import ( "time" "github.com/rs/zerolog" - "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink-testing-framework/seth" diff --git a/integration-tests/load/ocr/ocr_test.go b/integration-tests/load/ocr/ocr_test.go index 49bce3eca5..69475b09da 100644 --- a/integration-tests/load/ocr/ocr_test.go +++ b/integration-tests/load/ocr/ocr_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/smartcontractkit/wasp" + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink-testing-framework/logging" diff --git a/integration-tests/load/ocr/vu.go b/integration-tests/load/ocr/vu.go index a50b52c690..8e15344610 100644 --- a/integration-tests/load/ocr/vu.go +++ b/integration-tests/load/ocr/vu.go @@ -11,9 +11,10 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/wasp" "go.uber.org/ratelimit" + "github.com/smartcontractkit/chainlink-testing-framework/wasp" + client2 "github.com/smartcontractkit/chainlink-testing-framework/client" "github.com/smartcontractkit/chainlink/integration-tests/actions" diff --git a/integration-tests/load/vrfv2/gun.go b/integration-tests/load/vrfv2/gun.go index 0eef5b1481..e9e7de9bef 100644 --- a/integration-tests/load/vrfv2/gun.go +++ b/integration-tests/load/vrfv2/gun.go @@ -4,7 +4,8 @@ import ( "math/rand" "github.com/rs/zerolog" - "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink-testing-framework/seth" diff --git a/integration-tests/load/vrfv2/onchain_monitoring.go b/integration-tests/load/vrfv2/onchain_monitoring.go index e057e7f8d2..9ba53f39e7 100644 --- a/integration-tests/load/vrfv2/onchain_monitoring.go +++ b/integration-tests/load/vrfv2/onchain_monitoring.go @@ -6,7 +6,8 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink/integration-tests/contracts" ) diff --git a/integration-tests/load/vrfv2/vrfv2_test.go b/integration-tests/load/vrfv2/vrfv2_test.go index b75f930ec1..8e2a42fd21 100644 --- a/integration-tests/load/vrfv2/vrfv2_test.go +++ b/integration-tests/load/vrfv2/vrfv2_test.go @@ -10,7 +10,8 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/networks" diff --git a/integration-tests/load/vrfv2/vrfv2cmd/dashboard.go b/integration-tests/load/vrfv2/vrfv2cmd/dashboard.go index e80d7516fd..24e6799138 100644 --- a/integration-tests/load/vrfv2/vrfv2cmd/dashboard.go +++ b/integration-tests/load/vrfv2/vrfv2cmd/dashboard.go @@ -3,7 +3,7 @@ package main import ( "os" - db "github.com/smartcontractkit/wasp/dashboard" + db "github.com/smartcontractkit/chainlink-testing-framework/wasp/dashboard" "github.com/K-Phoen/grabana/dashboard" "github.com/K-Phoen/grabana/logs" diff --git a/integration-tests/load/vrfv2plus/gun.go b/integration-tests/load/vrfv2plus/gun.go index 8d4162ab88..3c16bbafdc 100644 --- a/integration-tests/load/vrfv2plus/gun.go +++ b/integration-tests/load/vrfv2plus/gun.go @@ -5,7 +5,8 @@ import ( "math/rand" "github.com/rs/zerolog" - "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink-testing-framework/seth" diff --git a/integration-tests/load/vrfv2plus/onchain_monitoring.go b/integration-tests/load/vrfv2plus/onchain_monitoring.go index 50c0ac18a9..2bb082dc11 100644 --- a/integration-tests/load/vrfv2plus/onchain_monitoring.go +++ b/integration-tests/load/vrfv2plus/onchain_monitoring.go @@ -6,7 +6,8 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink/integration-tests/contracts" ) diff --git a/integration-tests/load/vrfv2plus/vrfv2plus_test.go b/integration-tests/load/vrfv2plus/vrfv2plus_test.go index 97e45e0d9c..30d33aa3c6 100644 --- a/integration-tests/load/vrfv2plus/vrfv2plus_test.go +++ b/integration-tests/load/vrfv2plus/vrfv2plus_test.go @@ -9,9 +9,10 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/wasp" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/wasp" + "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/networks" "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" diff --git a/integration-tests/load/vrfv2plus/vrfv2pluscmd/dashboard.go b/integration-tests/load/vrfv2plus/vrfv2pluscmd/dashboard.go index 75853e7e21..569a0bd134 100644 --- a/integration-tests/load/vrfv2plus/vrfv2pluscmd/dashboard.go +++ b/integration-tests/load/vrfv2plus/vrfv2pluscmd/dashboard.go @@ -3,7 +3,7 @@ package main import ( "os" - db "github.com/smartcontractkit/wasp/dashboard" + db "github.com/smartcontractkit/chainlink-testing-framework/wasp/dashboard" "github.com/K-Phoen/grabana/dashboard" "github.com/K-Phoen/grabana/logs" diff --git a/integration-tests/load/zcluster/cluster_entrypoint_test.go b/integration-tests/load/zcluster/cluster_entrypoint_test.go index aace97b082..0f3ea5e404 100644 --- a/integration-tests/load/zcluster/cluster_entrypoint_test.go +++ b/integration-tests/load/zcluster/cluster_entrypoint_test.go @@ -3,9 +3,10 @@ package zcluster import ( "testing" - "github.com/smartcontractkit/wasp" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/wasp" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" ) diff --git a/integration-tests/universal/log_poller/gun.go b/integration-tests/universal/log_poller/gun.go index a75209aa10..287041ce41 100644 --- a/integration-tests/universal/log_poller/gun.go +++ b/integration-tests/universal/log_poller/gun.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/rs/zerolog" - "github.com/smartcontractkit/wasp" + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink/integration-tests/contracts" ) diff --git a/integration-tests/universal/log_poller/helpers.go b/integration-tests/universal/log_poller/helpers.go index c73a19be5b..4f7451d866 100644 --- a/integration-tests/universal/log_poller/helpers.go +++ b/integration-tests/universal/log_poller/helpers.go @@ -16,7 +16,8 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/wasp" + + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink-testing-framework/seth" diff --git a/integration-tests/web/sdk/internal/generated/generated.go b/integration-tests/web/sdk/internal/generated/generated.go index bcb8106959..6fada0aaa0 100644 --- a/integration-tests/web/sdk/internal/generated/generated.go +++ b/integration-tests/web/sdk/internal/generated/generated.go @@ -8,6 +8,7 @@ import ( "fmt" "github.com/Khan/genqlient/graphql" + "github.com/smartcontractkit/chainlink/v2/core/web/gqlscalar" ) From 567ce229ed434a74b09124feadf3265017ec5313 Mon Sep 17 00:00:00 2001 From: Cedric Date: Wed, 28 Aug 2024 16:21:03 +0100 Subject: [PATCH 186/432] [CAPPL-6] Formalize trigger API (#14145) * [CAPPL-6-formalize-trigger-API * Fix tests * WIP * WIP * Update common * Fix tests * Address feedback * Update common * Update common * Fix test --- .changeset/wise-snakes-protect.md | 5 ++ .../integration_tests/mock_trigger.go | 48 ++++++++----------- core/capabilities/launcher_test.go | 4 +- core/capabilities/remote/trigger_publisher.go | 21 ++++---- .../remote/trigger_publisher_test.go | 14 +++--- .../capabilities/remote/trigger_subscriber.go | 10 ++-- .../remote/trigger_subscriber_test.go | 14 +++--- core/capabilities/remote/types/types.go | 2 +- core/capabilities/remote/utils.go | 8 ++-- core/capabilities/remote/utils_test.go | 20 ++++---- core/capabilities/streams/codec.go | 6 ++- .../streams/consensus_agg_test.go | 23 +++------ core/capabilities/streams/trigger_test.go | 28 +++++------ core/scripts/go.mod | 12 ++--- core/scripts/go.sum | 24 +++++----- core/services/workflows/engine.go | 43 +++++------------ core/services/workflows/engine_test.go | 40 +++++++++------- go.mod | 12 ++--- go.sum | 24 +++++----- integration-tests/go.mod | 12 ++--- integration-tests/go.sum | 24 +++++----- integration-tests/load/go.mod | 12 ++--- integration-tests/load/go.sum | 24 +++++----- 23 files changed, 201 insertions(+), 229 deletions(-) create mode 100644 .changeset/wise-snakes-protect.md diff --git a/.changeset/wise-snakes-protect.md b/.changeset/wise-snakes-protect.md new file mode 100644 index 0000000000..ebc0ec4091 --- /dev/null +++ b/.changeset/wise-snakes-protect.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Formalize trigger API #internal diff --git a/core/capabilities/integration_tests/mock_trigger.go b/core/capabilities/integration_tests/mock_trigger.go index 0ed1fe5c8d..35b05b054c 100644 --- a/core/capabilities/integration_tests/mock_trigger.go +++ b/core/capabilities/integration_tests/mock_trigger.go @@ -2,8 +2,6 @@ package integration_tests import ( "context" - "fmt" - "strconv" "sync" "testing" @@ -45,7 +43,7 @@ func (r *reportsSink) Close() error { func (r *reportsSink) sendReports(reportList []*datastreams.FeedReport) { for _, trigger := range r.triggers { - resp, err := wrapReports(reportList, "1", 12, datastreams.SignersMetadata{}) + resp, err := wrapReports(reportList, "1", 12, datastreams.Metadata{}) if err != nil { panic(err) } @@ -54,7 +52,7 @@ func (r *reportsSink) sendReports(reportList []*datastreams.FeedReport) { } func (r *reportsSink) getNewTrigger(t *testing.T) *streamsTrigger { - trigger := streamsTrigger{t: t, toSend: make(chan capabilities.CapabilityResponse, 1000), + trigger := streamsTrigger{t: t, toSend: make(chan capabilities.TriggerResponse, 1000), wg: &r.wg, stopCh: r.stopCh} r.triggers = append(r.triggers, trigger) return &trigger @@ -63,13 +61,13 @@ func (r *reportsSink) getNewTrigger(t *testing.T) *streamsTrigger { type streamsTrigger struct { t *testing.T cancel context.CancelFunc - toSend chan capabilities.CapabilityResponse + toSend chan capabilities.TriggerResponse wg *sync.WaitGroup stopCh services.StopChan } -func (s *streamsTrigger) sendResponse(resp capabilities.CapabilityResponse) { +func (s *streamsTrigger) sendResponse(resp capabilities.TriggerResponse) { s.toSend <- resp } @@ -81,12 +79,12 @@ func (s *streamsTrigger) Info(ctx context.Context) (capabilities.CapabilityInfo, ), nil } -func (s *streamsTrigger) RegisterTrigger(ctx context.Context, request capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) { +func (s *streamsTrigger) RegisterTrigger(ctx context.Context, request capabilities.TriggerRegistrationRequest) (<-chan capabilities.TriggerResponse, error) { if s.cancel != nil { s.t.Fatal("trigger already registered") } - responseCh := make(chan capabilities.CapabilityResponse) + responseCh := make(chan capabilities.TriggerResponse) ctxWithCancel, cancel := context.WithCancel(context.Background()) s.cancel = cancel @@ -108,7 +106,7 @@ func (s *streamsTrigger) RegisterTrigger(ctx context.Context, request capabiliti return responseCh, nil } -func (s *streamsTrigger) UnregisterTrigger(ctx context.Context, request capabilities.CapabilityRequest) error { +func (s *streamsTrigger) UnregisterTrigger(ctx context.Context, request capabilities.TriggerRegistrationRequest) error { if s.cancel == nil { s.t.Fatal("trigger not registered") } @@ -118,32 +116,28 @@ func (s *streamsTrigger) UnregisterTrigger(ctx context.Context, request capabili return nil } -func wrapReports(reportList []*datastreams.FeedReport, eventID string, timestamp int64, meta datastreams.SignersMetadata) (capabilities.CapabilityResponse, error) { - val, err := values.Wrap(reportList) - if err != nil { - return capabilities.CapabilityResponse{}, err +func wrapReports(reportList []*datastreams.FeedReport, eventID string, timestamp int64, meta datastreams.Metadata) (capabilities.TriggerResponse, error) { + rl := []datastreams.FeedReport{} + for _, r := range reportList { + rl = append(rl, *r) } - - metaVal, err := values.Wrap(meta) + outputs, err := values.WrapMap(datastreams.StreamsTriggerEvent{ + Payload: rl, + Metadata: meta, + Timestamp: timestamp, + }) if err != nil { - return capabilities.CapabilityResponse{}, err + return capabilities.TriggerResponse{}, err } triggerEvent := capabilities.TriggerEvent{ TriggerType: triggerID, ID: eventID, - Timestamp: strconv.FormatInt(timestamp, 10), - Metadata: metaVal, - Payload: val, - } - - triggerEventMapValue, err := values.WrapMap(triggerEvent) - if err != nil { - return capabilities.CapabilityResponse{}, fmt.Errorf("failed to wrap trigger event: %w", err) + Outputs: outputs, } - // Create a new CapabilityResponse with the MercuryTriggerEvent - return capabilities.CapabilityResponse{ - Value: triggerEventMapValue, + // Create a new TriggerResponse with the MercuryTriggerEvent + return capabilities.TriggerResponse{ + Event: triggerEvent, }, nil } diff --git a/core/capabilities/launcher_test.go b/core/capabilities/launcher_test.go index 8bca3be0db..220a7838db 100644 --- a/core/capabilities/launcher_test.go +++ b/core/capabilities/launcher_test.go @@ -30,11 +30,11 @@ type mockTrigger struct { capabilities.CapabilityInfo } -func (m *mockTrigger) RegisterTrigger(ctx context.Context, request capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) { +func (m *mockTrigger) RegisterTrigger(ctx context.Context, request capabilities.TriggerRegistrationRequest) (<-chan capabilities.TriggerResponse, error) { return nil, nil } -func (m *mockTrigger) UnregisterTrigger(ctx context.Context, request capabilities.CapabilityRequest) error { +func (m *mockTrigger) UnregisterTrigger(ctx context.Context, request capabilities.TriggerRegistrationRequest) error { return nil } diff --git a/core/capabilities/remote/trigger_publisher.go b/core/capabilities/remote/trigger_publisher.go index ad0b9b27c6..b46d8bcb72 100644 --- a/core/capabilities/remote/trigger_publisher.go +++ b/core/capabilities/remote/trigger_publisher.go @@ -43,8 +43,8 @@ type registrationKey struct { } type pubRegState struct { - callback <-chan commoncap.CapabilityResponse - request commoncap.CapabilityRequest + callback <-chan commoncap.TriggerResponse + request commoncap.TriggerRegistrationRequest } var _ types.Receiver = &triggerPublisher{} @@ -94,9 +94,9 @@ func (p *triggerPublisher) Receive(_ context.Context, msg *types.MessageBody) { } if msg.Method == types.MethodRegisterTrigger { - req, err := pb.UnmarshalCapabilityRequest(msg.Payload) + req, err := pb.UnmarshalTriggerRegistrationRequest(msg.Payload) if err != nil { - p.lggr.Errorw("failed to unmarshal capability request", "capabilityId", p.capInfo.ID, "err", err) + p.lggr.Errorw("failed to unmarshal trigger registration request", "capabilityId", p.capInfo.ID, "err", err) return } callerDon, ok := p.workflowDONs[msg.CallerDonId] @@ -135,7 +135,7 @@ func (p *triggerPublisher) Receive(_ context.Context, msg *types.MessageBody) { p.lggr.Errorw("failed to aggregate trigger registrations", "capabilityId", p.capInfo.ID, "workflowId", req.Metadata.WorkflowID, "err", err) return } - unmarshaled, err := pb.UnmarshalCapabilityRequest(aggregated) + unmarshaled, err := pb.UnmarshalTriggerRegistrationRequest(aggregated) if err != nil { p.lggr.Errorw("failed to unmarshal request", "capabilityId", p.capInfo.ID, "err", err) return @@ -189,7 +189,7 @@ func (p *triggerPublisher) registrationCleanupLoop() { } } -func (p *triggerPublisher) triggerEventLoop(callbackCh <-chan commoncap.CapabilityResponse, key registrationKey) { +func (p *triggerPublisher) triggerEventLoop(callbackCh <-chan commoncap.TriggerResponse, key registrationKey) { defer p.wg.Done() for { select { @@ -200,14 +200,9 @@ func (p *triggerPublisher) triggerEventLoop(callbackCh <-chan commoncap.Capabili p.lggr.Infow("triggerEventLoop channel closed", "capabilityId", p.capInfo.ID, "workflowId", key.workflowId) return } - triggerEvent := capabilities.TriggerEvent{} - err := response.Value.UnwrapTo(&triggerEvent) - if err != nil { - p.lggr.Errorw("can't unwrap trigger event", "capabilityId", p.capInfo.ID, "workflowId", key.workflowId, "err", err) - break - } + triggerEvent := response.Event p.lggr.Debugw("received trigger event", "capabilityId", p.capInfo.ID, "workflowId", key.workflowId, "triggerEventID", triggerEvent.ID) - marshaled, err := pb.MarshalCapabilityResponse(response) + marshaled, err := pb.MarshalTriggerResponse(response) if err != nil { p.lggr.Debugw("can't marshal trigger event", "err", err) break diff --git a/core/capabilities/remote/trigger_publisher_test.go b/core/capabilities/remote/trigger_publisher_test.go index 32de37a95a..bcc79b4fbb 100644 --- a/core/capabilities/remote/trigger_publisher_test.go +++ b/core/capabilities/remote/trigger_publisher_test.go @@ -52,18 +52,18 @@ func TestTriggerPublisher_Register(t *testing.T) { } underlying := &testTrigger{ info: capInfo, - registrationsCh: make(chan commoncap.CapabilityRequest, 2), + registrationsCh: make(chan commoncap.TriggerRegistrationRequest, 2), } publisher := remote.NewTriggerPublisher(config, underlying, capInfo, capDonInfo, workflowDONs, dispatcher, lggr) require.NoError(t, publisher.Start(ctx)) // trigger registration event - capRequest := commoncap.CapabilityRequest{ + triggerRequest := commoncap.TriggerRegistrationRequest{ Metadata: commoncap.RequestMetadata{ WorkflowID: workflowID1, }, } - marshaled, err := pb.MarshalCapabilityRequest(capRequest) + marshaled, err := pb.MarshalTriggerRegistrationRequest(triggerRequest) require.NoError(t, err) regEvent := &remotetypes.MessageBody{ Sender: p1[:], @@ -79,25 +79,25 @@ func TestTriggerPublisher_Register(t *testing.T) { publisher.Receive(ctx, regEvent) require.NotEmpty(t, underlying.registrationsCh) forwarded := <-underlying.registrationsCh - require.Equal(t, capRequest.Metadata.WorkflowID, forwarded.Metadata.WorkflowID) + require.Equal(t, triggerRequest.Metadata.WorkflowID, forwarded.Metadata.WorkflowID) require.NoError(t, publisher.Close()) } type testTrigger struct { info commoncap.CapabilityInfo - registrationsCh chan commoncap.CapabilityRequest + registrationsCh chan commoncap.TriggerRegistrationRequest } func (t *testTrigger) Info(_ context.Context) (commoncap.CapabilityInfo, error) { return t.info, nil } -func (t *testTrigger) RegisterTrigger(_ context.Context, request commoncap.CapabilityRequest) (<-chan commoncap.CapabilityResponse, error) { +func (t *testTrigger) RegisterTrigger(_ context.Context, request commoncap.TriggerRegistrationRequest) (<-chan commoncap.TriggerResponse, error) { t.registrationsCh <- request return nil, nil } -func (t *testTrigger) UnregisterTrigger(_ context.Context, request commoncap.CapabilityRequest) error { +func (t *testTrigger) UnregisterTrigger(_ context.Context, request commoncap.TriggerRegistrationRequest) error { return nil } diff --git a/core/capabilities/remote/trigger_subscriber.go b/core/capabilities/remote/trigger_subscriber.go index f880735f4f..967b59258a 100644 --- a/core/capabilities/remote/trigger_subscriber.go +++ b/core/capabilities/remote/trigger_subscriber.go @@ -43,7 +43,7 @@ type triggerEventKey struct { } type subRegState struct { - callback chan commoncap.CapabilityResponse + callback chan commoncap.TriggerResponse rawRequest []byte } @@ -98,8 +98,8 @@ func (s *triggerSubscriber) Info(ctx context.Context) (commoncap.CapabilityInfo, return s.capInfo, nil } -func (s *triggerSubscriber) RegisterTrigger(ctx context.Context, request commoncap.CapabilityRequest) (<-chan commoncap.CapabilityResponse, error) { - rawRequest, err := pb.MarshalCapabilityRequest(request) +func (s *triggerSubscriber) RegisterTrigger(ctx context.Context, request commoncap.TriggerRegistrationRequest) (<-chan commoncap.TriggerResponse, error) { + rawRequest, err := pb.MarshalTriggerRegistrationRequest(request) if err != nil { return nil, err } @@ -113,7 +113,7 @@ func (s *triggerSubscriber) RegisterTrigger(ctx context.Context, request commonc regState, ok := s.registeredWorkflows[request.Metadata.WorkflowID] if !ok { regState = &subRegState{ - callback: make(chan commoncap.CapabilityResponse, defaultSendChannelBufferSize), + callback: make(chan commoncap.TriggerResponse, defaultSendChannelBufferSize), rawRequest: rawRequest, } s.registeredWorkflows[request.Metadata.WorkflowID] = regState @@ -160,7 +160,7 @@ func (s *triggerSubscriber) registrationLoop() { } } -func (s *triggerSubscriber) UnregisterTrigger(ctx context.Context, request commoncap.CapabilityRequest) error { +func (s *triggerSubscriber) UnregisterTrigger(ctx context.Context, request commoncap.TriggerRegistrationRequest) error { s.mu.Lock() defer s.mu.Unlock() diff --git a/core/capabilities/remote/trigger_subscriber_test.go b/core/capabilities/remote/trigger_subscriber_test.go index c834a271d5..b8cc3ddc7b 100644 --- a/core/capabilities/remote/trigger_subscriber_test.go +++ b/core/capabilities/remote/trigger_subscriber_test.go @@ -71,7 +71,7 @@ func TestTriggerSubscriber_RegisterAndReceive(t *testing.T) { subscriber := remote.NewTriggerSubscriber(config, capInfo, capDonInfo, workflowDonInfo, dispatcher, nil, lggr) require.NoError(t, subscriber.Start(ctx)) - req := commoncap.CapabilityRequest{ + req := commoncap.TriggerRegistrationRequest{ Metadata: commoncap.RequestMetadata{ WorkflowID: workflowID1, }, @@ -83,11 +83,13 @@ func TestTriggerSubscriber_RegisterAndReceive(t *testing.T) { // receive trigger event triggerEventValue, err := values.NewMap(triggerEvent1) require.NoError(t, err) - capResponse := commoncap.CapabilityResponse{ - Value: triggerEventValue, - Err: nil, + capResponse := commoncap.TriggerResponse{ + Event: commoncap.TriggerEvent{ + Outputs: triggerEventValue, + }, + Err: nil, } - marshaled, err := pb.MarshalCapabilityResponse(capResponse) + marshaled, err := pb.MarshalTriggerResponse(capResponse) require.NoError(t, err) triggerEvent := &remotetypes.MessageBody{ Sender: p1[:], @@ -101,7 +103,7 @@ func TestTriggerSubscriber_RegisterAndReceive(t *testing.T) { } subscriber.Receive(ctx, triggerEvent) response := <-triggerEventCallbackCh - require.Equal(t, response.Value, triggerEventValue) + require.Equal(t, response.Event.Outputs, triggerEventValue) require.NoError(t, subscriber.UnregisterTrigger(ctx, req)) require.NoError(t, subscriber.UnregisterTrigger(ctx, req)) diff --git a/core/capabilities/remote/types/types.go b/core/capabilities/remote/types/types.go index 3629fc06fe..7f3868486a 100644 --- a/core/capabilities/remote/types/types.go +++ b/core/capabilities/remote/types/types.go @@ -31,7 +31,7 @@ type Receiver interface { } type Aggregator interface { - Aggregate(eventID string, responses [][]byte) (commoncap.CapabilityResponse, error) + Aggregate(eventID string, responses [][]byte) (commoncap.TriggerResponse, error) } // NOTE: this type will become part of the Registry (KS-108) diff --git a/core/capabilities/remote/utils.go b/core/capabilities/remote/utils.go index a1fe4dcb84..ea6a3efb18 100644 --- a/core/capabilities/remote/utils.go +++ b/core/capabilities/remote/utils.go @@ -71,15 +71,15 @@ func NewDefaultModeAggregator(minIdenticalResponses uint32) *defaultModeAggregat } } -func (a *defaultModeAggregator) Aggregate(_ string, responses [][]byte) (commoncap.CapabilityResponse, error) { +func (a *defaultModeAggregator) Aggregate(_ string, responses [][]byte) (commoncap.TriggerResponse, error) { found, err := AggregateModeRaw(responses, a.minIdenticalResponses) if err != nil { - return commoncap.CapabilityResponse{}, fmt.Errorf("failed to aggregate responses, err: %w", err) + return commoncap.TriggerResponse{}, fmt.Errorf("failed to aggregate responses, err: %w", err) } - unmarshaled, err := pb.UnmarshalCapabilityResponse(found) + unmarshaled, err := pb.UnmarshalTriggerResponse(found) if err != nil { - return commoncap.CapabilityResponse{}, fmt.Errorf("failed to unmarshal aggregated responses, err: %w", err) + return commoncap.TriggerResponse{}, fmt.Errorf("failed to unmarshal aggregated responses, err: %w", err) } return unmarshaled, nil } diff --git a/core/capabilities/remote/utils_test.go b/core/capabilities/remote/utils_test.go index 4a38a226e5..6707e6ffb2 100644 --- a/core/capabilities/remote/utils_test.go +++ b/core/capabilities/remote/utils_test.go @@ -92,20 +92,24 @@ func TestToPeerID(t *testing.T) { func TestDefaultModeAggregator_Aggregate(t *testing.T) { val, err := values.NewMap(triggerEvent1) require.NoError(t, err) - capResponse1 := commoncap.CapabilityResponse{ - Value: val, - Err: nil, + capResponse1 := commoncap.TriggerResponse{ + Event: commoncap.TriggerEvent{ + Outputs: val, + }, + Err: nil, } - marshaled1, err := pb.MarshalCapabilityResponse(capResponse1) + marshaled1, err := pb.MarshalTriggerResponse(capResponse1) require.NoError(t, err) val2, err := values.NewMap(triggerEvent2) require.NoError(t, err) - capResponse2 := commoncap.CapabilityResponse{ - Value: val2, - Err: nil, + capResponse2 := commoncap.TriggerResponse{ + Event: commoncap.TriggerEvent{ + Outputs: val2, + }, + Err: nil, } - marshaled2, err := pb.MarshalCapabilityResponse(capResponse2) + marshaled2, err := pb.MarshalTriggerResponse(capResponse2) require.NoError(t, err) agg := remote.NewDefaultModeAggregator(2) diff --git a/core/capabilities/streams/codec.go b/core/capabilities/streams/codec.go index 26011cb7f3..d6918f0c73 100644 --- a/core/capabilities/streams/codec.go +++ b/core/capabilities/streams/codec.go @@ -20,7 +20,7 @@ type codec struct { var _ datastreams.ReportCodec = &codec{} func (c *codec) Unwrap(wrapped values.Value) ([]datastreams.FeedReport, error) { - dest, err := datastreams.UnwrapFeedReportList(wrapped) + dest, err := datastreams.UnwrapStreamsTriggerEventToFeedReportList(wrapped) if err != nil { return nil, fmt.Errorf("failed to unwrap: %v", err) } @@ -45,7 +45,9 @@ func (c *codec) Unwrap(wrapped values.Value) ([]datastreams.FeedReport, error) { } func (c *codec) Wrap(reports []datastreams.FeedReport) (values.Value, error) { - return values.Wrap(reports) + return values.Wrap(&datastreams.StreamsTriggerEvent{ + Payload: reports, + }) } func (c *codec) Validate(report datastreams.FeedReport, allowedSigners [][]byte, minRequiredSignatures int) error { diff --git a/core/capabilities/streams/consensus_agg_test.go b/core/capabilities/streams/consensus_agg_test.go index 506ad26f86..04396a38ba 100644 --- a/core/capabilities/streams/consensus_agg_test.go +++ b/core/capabilities/streams/consensus_agg_test.go @@ -9,7 +9,6 @@ import ( "github.com/smartcontractkit/libocr/commontypes" - "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3/datafeeds" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/datastreams" "github.com/smartcontractkit/chainlink-common/pkg/values" @@ -98,26 +97,18 @@ func newObservations(t *testing.T, nNodes int, feeds []feed, minRequiredSignatur reportList = append(reportList, signedStreamsReport) } - payloadVal, err := values.Wrap(reportList) - require.NoError(t, err) - - meta := datastreams.SignersMetadata{ + meta := datastreams.Metadata{ Signers: allowedSigners, MinRequiredSignatures: minRequiredSignatures, } - metaVal, err := values.Wrap(meta) - require.NoError(t, err) - - triggerEvent := capabilities.TriggerEvent{ - TriggerType: triggerID, - ID: "unused", - Timestamp: "1234", - Metadata: metaVal, - Payload: payloadVal, + p := datastreams.StreamsTriggerEvent{ + Payload: reportList, + Metadata: meta, } - wrappedEvent, err := values.Wrap(triggerEvent) + outputs, err := values.WrapMap(p) require.NoError(t, err) - observations[commontypes.OracleID(i)] = []values.Value{wrappedEvent} + + observations[commontypes.OracleID(i)] = []values.Value{outputs} } return observations } diff --git a/core/capabilities/streams/trigger_test.go b/core/capabilities/streams/trigger_test.go index 853f07f2aa..3db6f2445e 100644 --- a/core/capabilities/streams/trigger_test.go +++ b/core/capabilities/streams/trigger_test.go @@ -93,7 +93,7 @@ func TestStreamsTrigger(t *testing.T) { subscriber := remote.NewTriggerSubscriber(config, capInfo, capDonInfo, capabilities.DON{}, nil, agg, lggr) // register trigger - req := capabilities.CapabilityRequest{ + req := capabilities.TriggerRegistrationRequest{ Metadata: capabilities.RequestMetadata{ WorkflowID: workflowID, }, @@ -131,7 +131,7 @@ func TestStreamsTrigger(t *testing.T) { } response := <-triggerEventCallbackCh - validateLatestReports(t, response.Value, P, basePrice+R-1, baseTimestamp+R-1) + validateLatestReports(t, response.Event.Outputs, P, basePrice+R-1, baseTimestamp+R-1) } totalTime := time.Now().UnixMilli() - startTs lggr.Infow("elapsed", "totalMs", totalTime, "processingMs", processingTime) @@ -180,24 +180,20 @@ func newFeedsWithSignedReports(t *testing.T, nodes []node, N, P, R int) []feed { } func newTriggerEvent(t *testing.T, reportList []datastreams.FeedReport, triggerEventID string, sender ragetypes.PeerID) *remotetypes.MessageBody { - val, err := values.Wrap(reportList) + outputs, err := values.WrapMap(&datastreams.StreamsTriggerEvent{ + Timestamp: 10, + Payload: reportList, + }) require.NoError(t, err) triggerEvent := capabilities.TriggerEvent{ TriggerType: triggerID, ID: triggerEventID, - Timestamp: strconv.FormatInt(1000, 10), - Metadata: nil, - Payload: val, + Outputs: outputs, } - eventVal, err := values.WrapMap(triggerEvent) - require.NoError(t, err) + marshaled, err := pb.MarshalTriggerResponse(capabilities.TriggerResponse{Event: triggerEvent}) - marshaled, err := pb.MarshalCapabilityResponse( - capabilities.CapabilityResponse{ - Value: eventVal, - }) require.NoError(t, err) msg := &remotetypes.MessageBody{ Sender: sender[:], @@ -214,13 +210,11 @@ func newTriggerEvent(t *testing.T, reportList []datastreams.FeedReport, triggerE } func validateLatestReports(t *testing.T, wrapped values.Value, expectedFeedsLen int, expectedPrice int, expectedTimestamp int) { - triggerEvent := capabilities.TriggerEvent{} + triggerEvent := datastreams.StreamsTriggerEvent{} require.NoError(t, wrapped.UnwrapTo(&triggerEvent)) - reports := []datastreams.FeedReport{} - require.NoError(t, triggerEvent.Payload.UnwrapTo(&reports)) - require.Equal(t, expectedFeedsLen, len(reports)) + require.Equal(t, expectedFeedsLen, len(triggerEvent.Payload)) priceBig := big.NewInt(int64(expectedPrice)) - for _, report := range reports { + for _, report := range triggerEvent.Payload { require.Equal(t, priceBig.Bytes(), report.BenchmarkPrice) require.Equal(t, int64(expectedTimestamp), report.ObservationTimestamp) } diff --git a/core/scripts/go.mod b/core/scripts/go.mod index ce08618dfc..f106525d2a 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 @@ -178,7 +178,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect @@ -334,17 +334,17 @@ require ( golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.24.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect google.golang.org/grpc v1.65.0 // indirect gopkg.in/guregu/null.v4 v4.0.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 7a9b3d4599..fbc83070e4 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -684,8 +684,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= @@ -1186,8 +1186,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 h1:udSMgCcpOWlx+OjLlqYKGAveHUO0ZujuO8I2dmwDHQ8= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= @@ -1584,8 +1584,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1686,8 +1686,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1869,10 +1869,10 @@ google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaE google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index aa186f7650..f3bca4b900 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -36,7 +36,7 @@ type Engine struct { localNode capabilities.Node executionStates store.Store pendingStepRequests chan stepRequest - triggerEvents chan capabilities.CapabilityResponse + triggerEvents chan capabilities.TriggerResponse stepUpdateCh chan store.WorkflowExecutionStep wg sync.WaitGroup stopCh services.StopChan @@ -319,14 +319,6 @@ func generateTriggerId(workflowID string, triggerIdx int) string { // registerTrigger is used during the initialization phase to bind a trigger to this workflow func (e *Engine) registerTrigger(ctx context.Context, t *triggerCapability, triggerIdx int) error { triggerID := generateTriggerId(e.workflow.id, triggerIdx) - triggerInputs, err := values.NewMap( - map[string]any{ - "triggerId": triggerID, - }, - ) - if err != nil { - return err - } tc, err := values.NewMap(t.Config) if err != nil { @@ -335,7 +327,7 @@ func (e *Engine) registerTrigger(ctx context.Context, t *triggerCapability, trig t.config.Store(tc) - triggerRegRequest := capabilities.CapabilityRequest{ + triggerRegRequest := capabilities.TriggerRegistrationRequest{ Metadata: capabilities.RequestMetadata{ WorkflowID: e.workflow.id, WorkflowOwner: e.workflow.owner, @@ -344,8 +336,8 @@ func (e *Engine) registerTrigger(ctx context.Context, t *triggerCapability, trig WorkflowDonConfigVersion: e.localNode.WorkflowDON.ConfigVersion, ReferenceID: t.Ref, }, - Config: t.config.Load(), - Inputs: triggerInputs, + Config: t.config.Load(), + TriggerID: triggerID, } eventsCh, err := t.trigger.RegisterTrigger(ctx, triggerRegRequest) if err != nil { @@ -423,12 +415,7 @@ func (e *Engine) loop(ctx context.Context) { continue } - te := &capabilities.TriggerEvent{} - err := resp.Value.UnwrapTo(te) - if err != nil { - e.logger.Errorf("could not unwrap trigger event; error %v", resp.Err) - continue - } + te := resp.Event executionID, err := generateExecutionID(e.workflow.id, te.ID) if err != nil { @@ -436,7 +423,7 @@ func (e *Engine) loop(ctx context.Context) { continue } - err = e.startExecution(ctx, executionID, resp.Value) + err = e.startExecution(ctx, executionID, resp.Event.Outputs) if err != nil { e.logger.With(eIDKey, executionID).Errorf("failed to start execution: %v", err) } @@ -467,7 +454,7 @@ func generateExecutionID(workflowID, eventID string) (string, error) { } // startExecution kicks off a new workflow execution when a trigger event is received. -func (e *Engine) startExecution(ctx context.Context, executionID string, event values.Value) error { +func (e *Engine) startExecution(ctx context.Context, executionID string, event *values.Map) error { e.logger.With("event", event, eIDKey, executionID).Debug("executing on a trigger event") ec := &store.WorkflowExecution{ Steps: map[string]*store.WorkflowExecutionStep{ @@ -777,15 +764,7 @@ func (e *Engine) executeStep(ctx context.Context, msg stepRequest) (*values.Map, } func (e *Engine) deregisterTrigger(ctx context.Context, t *triggerCapability, triggerIdx int) error { - triggerInputs, err := values.NewMap( - map[string]any{ - "triggerId": generateTriggerId(e.workflow.id, triggerIdx), - }, - ) - if err != nil { - return err - } - deregRequest := capabilities.CapabilityRequest{ + deregRequest := capabilities.TriggerRegistrationRequest{ Metadata: capabilities.RequestMetadata{ WorkflowID: e.workflow.id, WorkflowDonID: e.localNode.WorkflowDON.ID, @@ -794,8 +773,8 @@ func (e *Engine) deregisterTrigger(ctx context.Context, t *triggerCapability, tr WorkflowOwner: e.workflow.owner, ReferenceID: t.Ref, }, - Inputs: triggerInputs, - Config: t.config.Load(), + TriggerID: generateTriggerId(e.workflow.id, triggerIdx), + Config: t.config.Load(), } // if t.trigger == nil, then we haven't initialized the workflow @@ -959,7 +938,7 @@ func NewEngine(cfg Config) (engine *Engine, err error) { executionStates: cfg.Store, pendingStepRequests: make(chan stepRequest, cfg.QueueSize), stepUpdateCh: make(chan store.WorkflowExecutionStep), - triggerEvents: make(chan capabilities.CapabilityResponse), + triggerEvents: make(chan capabilities.TriggerResponse), stopCh: make(chan struct{}), newWorkerTimeout: cfg.NewWorkerTimeout, maxExecutionDuration: cfg.MaxExecutionDuration, diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index 0a38bf719b..2d862823cf 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -223,20 +223,20 @@ func (m *mockCapability) UnregisterFromWorkflow(ctx context.Context, request cap type mockTriggerCapability struct { capabilities.CapabilityInfo - triggerEvent *capabilities.CapabilityResponse - ch chan capabilities.CapabilityResponse + triggerEvent *capabilities.TriggerResponse + ch chan capabilities.TriggerResponse } var _ capabilities.TriggerCapability = (*mockTriggerCapability)(nil) -func (m *mockTriggerCapability) RegisterTrigger(ctx context.Context, req capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) { +func (m *mockTriggerCapability) RegisterTrigger(ctx context.Context, req capabilities.TriggerRegistrationRequest) (<-chan capabilities.TriggerResponse, error) { if m.triggerEvent != nil { m.ch <- *m.triggerEvent } return m.ch, nil } -func (m *mockTriggerCapability) UnregisterTrigger(ctx context.Context, req capabilities.CapabilityRequest) error { +func (m *mockTriggerCapability) UnregisterTrigger(ctx context.Context, req capabilities.TriggerRegistrationRequest) error { return nil } @@ -275,8 +275,13 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { servicetest.Run(t, eng) eid := getExecutionId(t, eng, testHooks) - assert.Equal(t, cr, <-target1.response) - assert.Equal(t, cr, <-target2.response) + resp1 := <-target1.response + assert.NoError(t, resp1.Err) + assert.Equal(t, cr.Event.Outputs, resp1.Value) + + resp2 := <-target2.response + assert.NoError(t, resp2.Err) + assert.Equal(t, cr.Event.Outputs, resp2.Value) state, err := eng.executionStates.Get(ctx, eid) require.NoError(t, err) @@ -327,14 +332,14 @@ targets: ` ) -func mockTrigger(t *testing.T) (capabilities.TriggerCapability, capabilities.CapabilityResponse) { +func mockTrigger(t *testing.T) (capabilities.TriggerCapability, capabilities.TriggerResponse) { mt := &mockTriggerCapability{ CapabilityInfo: capabilities.MustNewCapabilityInfo( "mercury-trigger@1.0.0", capabilities.CapabilityTypeTrigger, "issues a trigger when a mercury report is received.", ), - ch: make(chan capabilities.CapabilityResponse, 10), + ch: make(chan capabilities.TriggerResponse, 10), } resp, err := values.NewMap(map[string]any{ "123": decimal.NewFromFloat(1.00), @@ -342,11 +347,13 @@ func mockTrigger(t *testing.T) (capabilities.TriggerCapability, capabilities.Cap "789": decimal.NewFromFloat(1.50), }) require.NoError(t, err) - cr := capabilities.CapabilityResponse{ - Value: resp, + tr := capabilities.TriggerResponse{ + Event: capabilities.TriggerEvent{ + Outputs: resp, + }, } - mt.triggerEvent = &cr - return mt, cr + mt.triggerEvent = &tr + return mt, tr } func mockNoopTrigger(t *testing.T) capabilities.TriggerCapability { @@ -356,7 +363,7 @@ func mockNoopTrigger(t *testing.T) capabilities.TriggerCapability { capabilities.CapabilityTypeTrigger, "issues a trigger when a mercury report is received.", ), - ch: make(chan capabilities.CapabilityResponse, 10), + ch: make(chan capabilities.TriggerResponse, 10), } return mt } @@ -551,7 +558,7 @@ func TestEngine_MultiStepDependencies(t *testing.T) { ctx := testutils.Context(t) reg := coreCap.NewRegistry(logger.TestLogger(t)) - trigger, cr := mockTrigger(t) + trigger, tr := mockTrigger(t) require.NoError(t, reg.Add(ctx, trigger)) require.NoError(t, reg.Add(ctx, mockConsensus())) @@ -578,9 +585,10 @@ func TestEngine_MultiStepDependencies(t *testing.T) { obs := unw.(map[string]any)["observations"] assert.Len(t, obs, 2) - tunw, err := values.Unwrap(cr.Value) require.NoError(t, err) - assert.Equal(t, obs.([]any)[0], tunw) + uo, err := values.Unwrap(tr.Event.Outputs) + require.NoError(t, err) + assert.Equal(t, obs.([]any)[0].(map[string]any), uo) o, err := values.Unwrap(out) require.NoError(t, err) diff --git a/go.mod b/go.mod index e82f6dbc1f..3fec96a015 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 @@ -228,7 +228,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect @@ -330,17 +330,15 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.28.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/ratelimit v0.3.0 // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect google.golang.org/api v0.188.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect gopkg.in/guregu/null.v2 v2.1.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index f47f747072..eeb48f39e6 100644 --- a/go.sum +++ b/go.sum @@ -648,8 +648,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= @@ -1141,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 h1:udSMgCcpOWlx+OjLlqYKGAveHUO0ZujuO8I2dmwDHQ8= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= @@ -1535,8 +1535,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1636,8 +1636,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1821,10 +1821,10 @@ google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaE google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index cd6865c99c..783be44031 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -36,7 +36,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 @@ -270,7 +270,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect @@ -473,16 +473,16 @@ require ( golang.org/x/arch v0.8.0 // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/sys v0.24.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.24.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index d126883627..745644e1bb 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -851,8 +851,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= @@ -1421,8 +1421,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 h1:udSMgCcpOWlx+OjLlqYKGAveHUO0ZujuO8I2dmwDHQ8= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= @@ -1840,8 +1840,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1945,8 +1945,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2120,10 +2120,10 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 94999b7328..c887e800ab 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 @@ -259,7 +259,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect @@ -468,9 +468,9 @@ require ( golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect @@ -478,8 +478,8 @@ require ( gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/guregu/null.v4 v4.0.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 24a13b5a38..9f2ad9a92c 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -835,8 +835,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= @@ -1391,8 +1391,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99 h1:udSMgCcpOWlx+OjLlqYKGAveHUO0ZujuO8I2dmwDHQ8= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240827205028-46de70e37a99/go.mod h1:5rmU5YKBkIOwWkuNZi26sMXlBUBm6weBFXh+8BEEp2s= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= @@ -1808,8 +1808,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1911,8 +1911,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2086,10 +2086,10 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= From 905cf6548e8ceb20d90796fd67108a08551c2444 Mon Sep 17 00:00:00 2001 From: momentmaker Date: Wed, 28 Aug 2024 11:53:33 -0500 Subject: [PATCH 187/432] fix: goreleaser-build-sign-publish-chainlink workflow (#14139) * remove other gha workflows and test build-publish workflow * update cosigner gha and version * add env GORELEASER_KEY * add GITHUB_TOKEN env * temp add current_tag env * add --skip=validate temp * remove prev * skip release * use disable instead * fix post release publish bug * use keyless signing * revert and comment stdin * comment all cosign user/pass * add args to docker_signs * remove cosign user/pass env and uncomment other workflow * update cosign to keyless for regular docker build images * use keyless input and temp remove slack-notify * use image digest for signing * use --yes flag in cosign sign and update cosign-installer version * add --yes flag to cosign verify * fix typo and remove --yes * refactor to remove cosign keypair way and only use keyless signing * revert back deleted gha workflow files * refactor with suggestions * fix set env step * fix typos and naming --- .../build-sign-publish-chainlink/action.yml | 92 +++++-------------- .../goreleaser-build-sign-publish/action.yml | 19 +--- .../action_utils | 14 +-- .github/workflows/build-publish.yml | 14 +-- .goreleaser.develop.yaml | 9 +- 5 files changed, 41 insertions(+), 107 deletions(-) diff --git a/.github/actions/build-sign-publish-chainlink/action.yml b/.github/actions/build-sign-publish-chainlink/action.yml index b992edfbf7..b0e70b742d 100644 --- a/.github/actions/build-sign-publish-chainlink/action.yml +++ b/.github/actions/build-sign-publish-chainlink/action.yml @@ -51,23 +51,11 @@ inputs: description: When set to the string boolean value of "true", the resulting build image will be signed default: "false" required: false - cosign-private-key: - description: The private key to be used with cosign to sign the image - required: false - cosign-public-key: - description: The public key to be used with cosign for verification - required: false - cosign-password: - description: The password to decrypt the cosign private key needed to sign the image - required: false - sign-method: - description: Build image will be signed using keypair or keyless methods - default: "keypair" - required: true verify-signature: description: When set to the string boolean value of "true", the resulting build image signature will be verified default: "false" required: false + outputs: docker-image-tag: description: The docker image tag that was built and pushed @@ -84,6 +72,8 @@ runs: # See https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#multiline-strings run: | SHARED_IMAGES=${{ inputs.ecr-hostname }}/${{ inputs.ecr-image-name }} + OIDC_ISSUER=https://token.actions.githubusercontent.com + OIDC_IDENTITY=https://github.com/smartcontractkit/chainlink/.github/workflows/build-publish.yml@${{ github.ref }} SHARED_TAG_LIST=$(cat << EOF type=ref,event=branch,suffix=${{ inputs.ecr-tag-suffix }} @@ -101,6 +91,9 @@ runs: echo "$SHARED_IMAGES" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV + echo "oidc-issuer=${OIDC_ISSUER}" >> $GITHUB_ENV + echo "oidc-identity=${OIDC_IDENTITY}" >> $GITHUB_ENV + echo "shared-tag-list<> $GITHUB_ENV echo "$SHARED_TAG_LIST" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV @@ -171,7 +164,9 @@ runs: run: | IMAGES_NAME_RAW=${{ fromJSON(steps.buildpush-root.outputs.metadata)['image.name'] }} IMAGE_NAME=$(echo "$IMAGES_NAME_RAW" | cut -d"," -f1) + IMAGE_DIGEST=${{ fromJSON(steps.buildpush-root.outputs.metadata)['containerimage.digest'] }} echo "root_image_name=${IMAGE_NAME}" >> $GITHUB_ENV + echo "root_image_digest=${IMAGE_DIGEST}" >> $GITHUB_ENV - name: Generate docker metadata for non-root image id: meta-nonroot @@ -217,6 +212,7 @@ runs: IMAGE_NAME=$(echo "$IMAGES_NAME_RAW" | cut -d"," -f1) IMAGE_TAG=$(echo "$IMAGES_NAME_RAW" | cut -d":" -f2) echo "nonroot_image_name=${IMAGE_NAME}" >> $GITHUB_ENV + echo "nonroot_image_digest=${IMAGE_DIGEST}" >> $GITHUB_ENV echo '### Docker Image' >> $GITHUB_STEP_SUMMARY echo "Image Name: ${IMAGE_NAME}" >> $GITHUB_STEP_SUMMARY echo "Image Digest: ${IMAGE_DIGEST}" >> $GITHUB_STEP_SUMMARY @@ -239,74 +235,36 @@ runs: - if: inputs.sign-images == 'true' name: Install cosign - uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 # v3.4.0 + uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3.6.0 with: - cosign-release: "v1.6.0" + cosign-release: "v2.4.0" - - if: inputs.sign-images == 'true' && inputs.sign-method == 'keypair' - name: Sign the published root Docker image using keypair method - shell: sh - env: - COSIGN_PASSWORD: "${{ inputs.cosign-password }}" - run: | - echo "${{ inputs.cosign-private-key }}" > cosign.key - cosign sign --key cosign.key "${{ env.root_image_name }}" - rm -f cosign.key - - - if: inputs.verify-signature == 'true' && inputs.sign-method == 'keypair' - name: Verify the signature of the published root Docker image using keypair - shell: sh - run: | - echo "${{ inputs.cosign-public-key }}" > cosign.key - cosign verify --key cosign.key "${{ env.root_image_name }}" - rm -f cosign.key - - - if: inputs.sign-images == 'true' && inputs.sign-method == 'keyless' + # This automatically signs the image with the correct OIDC provider from Github + - if: inputs.sign-images == 'true' name: Sign the published root Docker image using keyless method shell: sh - env: - COSIGN_EXPERIMENTAL: 1 run: | - cosign sign "${{ env.root_image_name }}" + cosign sign "${{ env.root_image_name }}" --yes - - if: inputs.verify-signature == 'true' && inputs.sign-method == 'keyless' + - if: inputs.verify-signature == 'true' name: Verify the signature of the published root Docker image using keyless shell: sh - env: - COSIGN_EXPERIMENTAL: 1 - run: | - cosign verify "${{ env.root_image_name }}" - - - if: inputs.sign-images == 'true' && inputs.sign-method == 'keypair' - name: Sign the published non-root Docker image using keypair method - shell: sh - env: - COSIGN_PASSWORD: "${{ inputs.cosign-password }}" - run: | - echo "${{ inputs.cosign-private-key }}" > cosign.key - cosign sign --key cosign.key "${{ env.nonroot_image_name }}" - rm -f cosign.key - - - if: inputs.verify-signature == 'true' && inputs.sign-method == 'keypair' - name: Verify the signature of the published non-root Docker image using keypair - shell: sh run: | - echo "${{ inputs.cosign-public-key }}" > cosign.key - cosign verify --key cosign.key "${{ env.nonroot_image_name }}" - rm -f cosign.key + cosign verify "${{ env.root_image_name }}" \ + --certificate-oidc-issuer ${{ env.oidc-issuer }} \ + --certificate-identity "${{ env.oidc-identity }}" - - if: inputs.sign-images == 'true' && inputs.sign-method == 'keyless' + # This automatically signs the image with the correct OIDC provider from Github + - if: inputs.sign-images == 'true' name: Sign the published non-root Docker image using keyless method shell: sh - env: - COSIGN_EXPERIMENTAL: 1 run: | - cosign sign "${{ env.nonroot_image_name }}" + cosign sign "${{ env.nonroot_image_name }}" --yes - - if: inputs.verify-signature == 'true' && inputs.sign-method == 'keyless' + - if: inputs.verify-signature == 'true' name: Verify the signature of the published non-root Docker image using keyless shell: sh - env: - COSIGN_EXPERIMENTAL: 1 run: | - cosign verify "${{ env.nonroot_image_name }}" + cosign verify "${{ env.nonroot_image_name }}" \ + --certificate-oidc-issuer ${{ env.oidc-issuer }} \ + --certificate-identity "${{ env.oidc-identity }}" diff --git a/.github/actions/goreleaser-build-sign-publish/action.yml b/.github/actions/goreleaser-build-sign-publish/action.yml index cf9da323de..69630e8e5f 100644 --- a/.github/actions/goreleaser-build-sign-publish/action.yml +++ b/.github/actions/goreleaser-build-sign-publish/action.yml @@ -14,7 +14,7 @@ inputs: required: false cosign-version: description: The cosign version - default: v2.2.2 + default: v2.4.0 required: false macos-sdk-dir: description: The macos sdk directory @@ -62,15 +62,6 @@ inputs: description: Enable signing of docker images default: "false" required: false - cosign-private-key: - description: The private key to be used with cosign to sign the image - required: false - cosign-public-key: - description: The public key to be used with cosign for verification - required: false - cosign-password: - description: The password to decrypt the cosign private key needed to sign the image - required: false runs: using: composite steps: @@ -96,7 +87,7 @@ runs: version: ${{ inputs.zig-version }} - name: Setup cosign if: inputs.enable-cosign == 'true' - uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 # v3.4.0 + uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3.6.0 with: cosign-release: ${{ inputs.cosign-version }} - name: Login to docker registry @@ -113,7 +104,6 @@ runs: - name: Run goreleaser release shell: bash env: - ENABLE_COSIGN: ${{ inputs.enable-cosign }} ENABLE_GORELEASER_SNAPSHOT: ${{ inputs.enable-goreleaser-snapshot }} ENABLE_GORELEASER_SPLIT: ${{ inputs.enable-goreleaser-split }} ENABLE_DOCKER_PUBLISH: ${{ inputs.enable-docker-publish }} @@ -122,9 +112,8 @@ runs: IMAGE_TAG: ${{ inputs.docker-image-tag }} GORELEASER_EXEC: ${{ inputs.goreleaser-exec }} GORELEASER_CONFIG: ${{ inputs.goreleaser-config }} - COSIGN_PASSWORD: ${{ inputs.cosign-password }} - COSIGN_PUBLIC_KEY: ${{ inputs.cosign-public-key }} - COSIGN_PRIVATE_KEY: ${{ inputs.cosign-private-key }} + GORELEASER_KEY: ${{ inputs.goreleaser-key }} + GITHUB_TOKEN: ${{ github.token }} MACOS_SDK_DIR: ${{ inputs.macos-sdk-dir }} run: | # https://github.com/orgs/community/discussions/24950 diff --git a/.github/actions/goreleaser-build-sign-publish/action_utils b/.github/actions/goreleaser-build-sign-publish/action_utils index 051e0763fb..51c7c90aa1 100755 --- a/.github/actions/goreleaser-build-sign-publish/action_utils +++ b/.github/actions/goreleaser-build-sign-publish/action_utils @@ -2,11 +2,9 @@ set -x set -euo pipefail -ENABLE_COSIGN=${ENABLE_COSIGN:-false} ENABLE_GORELEASER_SNAPSHOT=${ENABLE_GORELEASER_SNAPSHOT:-false} ENABLE_GORELEASER_SPLIT=${ENABLE_GORELEASER_SPLIT:-false} ENABLE_DOCKER_PUBLISH=${ENABLE_DOCKER_PUBLISH:-false} -COSIGN_PASSWORD=${COSIGN_PASSWORD:-""} GORELEASER_EXEC=${GORELEASER_EXEC:-goreleaser} GORELEASER_CONFIG=${GORELEASER_CONFIG:-.goreleaser.yaml} IMAGE_PREFIX=${IMAGE_PREFIX:-"localhost:5001"} @@ -69,26 +67,16 @@ goreleaser_release() { flags=$(printf "%s " "${goreleaser_flags[@]}") flags=$(echo "$flags" | sed 's/ *$//') - if [[ $ENABLE_COSIGN == "true" ]]; then - echo "$COSIGN_PUBLIC_KEY" > cosign.pub - echo "$COSIGN_PRIVATE_KEY" > cosign.key - fi - if [[ -n $MACOS_SDK_DIR ]]; then MACOS_SDK_DIR=$(echo "$(cd "$(dirname "$MACOS_SDK_DIR")" || exit; pwd)/$(basename "$MACOS_SDK_DIR")") fi $GORELEASER_EXEC release ${flags} --config "$GORELEASER_CONFIG" "$@" - if [[ $ENABLE_DOCKER_PUBLISH == "true" ]]; then + if [[ $ENABLE_DOCKER_PUBLISH == "true" ]] && [[ $ENABLE_GORELEASER_SNAPSHOT == "true" ]]; then _publish_snapshot_images _publish_snapshot_manifests fi - - if [[ $ENABLE_COSIGN == "true" ]]; then - rm -rf cosign.pub - rm -rf cosign.key - fi } "$@" diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index 033526e033..fa01d27e7c 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -51,13 +51,9 @@ jobs: aws-region: ${{ secrets.AWS_REGION }} ecr-hostname: ${{ env.ECR_HOSTNAME }} ecr-image-name: ${{ env.ECR_IMAGE_NAME }} - sign-images: true - sign-method: "keypair" - cosign-private-key: ${{ secrets.COSIGN_PRIVATE_KEY }} - cosign-public-key: ${{ secrets.COSIGN_PUBLIC_KEY }} - cosign-password: ${{ secrets.COSIGN_PASSWORD }} dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} + sign-images: true verify-signature: true - name: Collect Metrics @@ -97,7 +93,6 @@ jobs: id: goreleaser-build-sign-publish uses: ./.github/actions/goreleaser-build-sign-publish with: - enable-docker-publish: "true" docker-registry: ${{ env.ECR_HOSTNAME}} docker-image-name: ${{ env.ECR_IMAGE_NAME }} docker-image-tag: ${{ github.ref_name }} @@ -105,11 +100,8 @@ jobs: goreleaser-config: .goreleaser.develop.yaml goreleaser-key: ${{ secrets.GORELEASER_KEY }} zig-version: 0.11.0 - enable-cosign: "true" - cosign-version: 3.4.0 - cosign-password: ${{ secrets.COSIGN_PASSWORD }} - cosign-public-key: ${{ secrets.COSIGN_PUBLIC_KEY }} - cosign-private-key: ${{ secrets.COSIGN_PRIVATE_KEY }} + enable-cosign: true + cosign-version: "v2.4.0" - name: Output image name and digest shell: sh diff --git a/.goreleaser.develop.yaml b/.goreleaser.develop.yaml index 08d8e4de94..f8757676f8 100644 --- a/.goreleaser.develop.yaml +++ b/.goreleaser.develop.yaml @@ -192,7 +192,10 @@ docker_manifests: # See https://goreleaser.com/customization/docker_sign/ docker_signs: - artifacts: all - stdin: "{{ .Env.COSIGN_PASSWORD }}" + args: + - "sign" + - "${artifact}" + - "--yes" checksum: name_template: "checksums.txt" @@ -203,6 +206,10 @@ snapshot: partial: by: target +# See https://goreleaser.com/customization/release/ +release: + disable: true + changelog: sort: asc filters: From 71582d85a7ff4462369d9e63e063ebd61f8ec31e Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Thu, 1 Aug 2024 14:15:57 +0200 Subject: [PATCH 188/432] Misc onchain fixes (#1212) Various minor onchain fixes - improve accounting for token payload data - rm old check in usdc pool - fix comment on precompile range - add transferLiquidity function to LockReleaseTokenPool - move rate limit admin logic from lockRelease pool to TokenPool New changes - removed defaultTokenDestBytesOverhead and used CCIP_LOCK_OR_BURN_V1_RET_BYTES as default value - Add uint32 destGasAmount to the SourceTokenData struct to allow us to send the amount we billed on source to dest - This single value is used for the releaseOrMint and what is left after that call is used for transfer - Removed the defaults for releaseOrMint and transfer from the offRamp --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/gas-snapshots/ccip.gas-snapshot | 516 +++++++++--------- .../liquiditymanager.gas-snapshot | 8 +- .../src/v0.8/ccip/libraries/Internal.sol | 66 ++- contracts/src/v0.8/ccip/libraries/Pool.sol | 4 +- .../src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol | 11 +- .../src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol | 33 +- .../v0.8/ccip/pools/LockReleaseTokenPool.sol | 50 +- .../pools/LockReleaseTokenPoolAndProxy.sol | 46 +- contracts/src/v0.8/ccip/pools/TokenPool.sol | 22 +- .../v0.8/ccip/pools/USDC/USDCTokenPool.sol | 5 - contracts/src/v0.8/ccip/test/BaseTest.t.sol | 4 +- .../src/v0.8/ccip/test/NonceManager.t.sol | 1 - .../ccip/test/legacy/TokenPoolAndProxy.t.sol | 128 +---- .../offRamp/EVM2EVMMultiOffRampSetup.t.sol | 6 +- .../ccip/test/offRamp/EVM2EVMOffRamp.t.sol | 30 +- .../test/offRamp/EVM2EVMOffRampSetup.t.sol | 12 +- .../v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol | 148 +++-- .../ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol | 26 +- .../test/pools/LockReleaseTokenPool.t.sol | 131 +---- .../src/v0.8/ccip/test/pools/TokenPool.t.sol | 21 +- .../v0.8/ccip/test/pools/USDCTokenPool.t.sol | 31 +- .../test/priceRegistry/PriceRegistry.t.sol | 99 ++-- .../v0.8/ccip/test/router/RouterSetup.t.sol | 3 +- .../burn_from_mint_token_pool.go | 42 +- .../burn_mint_token_pool.go | 42 +- .../burn_mint_token_pool_and_proxy.go | 42 +- .../burn_with_from_mint_token_pool.go | 42 +- .../evm_2_evm_offramp/evm_2_evm_offramp.go | 8 +- .../evm_2_evm_onramp/evm_2_evm_onramp.go | 7 +- .../lock_release_token_pool.go | 158 +++++- .../lock_release_token_pool_and_proxy.go | 18 +- .../price_registry/price_registry.go | 2 +- .../ccip/generated/token_pool/token_pool.go | 40 +- .../usdc_token_pool/usdc_token_pool.go | 42 +- ...rapper-dependency-versions-do-not-edit.txt | 23 +- .../ocr2/plugins/ccip/integration_test.go | 2 - .../internal/ccipdata/onramp_reader_test.go | 3 +- .../ccip/internal/ccipdata/v1_5_0/offramp.go | 10 +- .../internal/ccipdata/v1_5_0/onramp_test.go | 3 +- .../ccip/testhelpers/ccip_contracts.go | 22 +- .../ocr2/plugins/ccip/testhelpers/config.go | 6 +- .../ccip-tests/contracts/contract_deployer.go | 119 ++-- 42 files changed, 1095 insertions(+), 937 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index eb96103c40..1fdf7e27d9 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -19,22 +19,22 @@ AggregateTokenLimiter_setAdmin:test_Owner_Success() (gas: 18989) AggregateTokenLimiter_setRateLimiterConfig:test_OnlyOnlyCallableByAdminOrOwner_Revert() (gas: 17479) AggregateTokenLimiter_setRateLimiterConfig:test_Owner_Success() (gas: 30062) AggregateTokenLimiter_setRateLimiterConfig:test_TokenLimitAdmin_Success() (gas: 32071) -BurnFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28675) -BurnFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55158) -BurnFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243525) -BurnFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 23907) -BurnMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 27565) -BurnMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55158) -BurnMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 241416) -BurnMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 17633) -BurnMintTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 28537) -BurnMintTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 55991) +BurnFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28761) +BurnFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) +BurnFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243491) +BurnFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 23951) +BurnMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 27522) +BurnMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) +BurnMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 241381) +BurnMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 17677) +BurnMintTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 28623) +BurnMintTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56078) BurnMintTokenPool_releaseOrMint:test_PoolMint_Success() (gas: 110657) -BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28675) -BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55158) -BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243552) -BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 24260) -CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2131281) +BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28761) +BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) +BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243517) +BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 24304) +CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2132877) CCIPConfigSetup:test_getCapabilityConfiguration_Success() (gas: 9495) CCIPConfig_ConfigStateMachine:test__computeConfigDigest_Success() (gas: 70755) CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_InitToRunning_Success() (gas: 363647) @@ -100,7 +100,7 @@ CommitStore_report:test_OnlyPriceUpdateStaleReport_Revert() (gas: 59049) CommitStore_report:test_OnlyTokenPriceUpdates_Success() (gas: 53251) CommitStore_report:test_Paused_Revert() (gas: 21259) CommitStore_report:test_ReportAndPriceUpdate_Success() (gas: 84242) -CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56249) +CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56313) CommitStore_report:test_RootAlreadyCommitted_Revert() (gas: 63969) CommitStore_report:test_StaleReportWithRoot_Success() (gas: 119420) CommitStore_report:test_Unhealthy_Revert() (gas: 44751) @@ -120,10 +120,10 @@ CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424253) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1100092) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1110438) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38157) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 108343) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 116811) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 108321) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 116789) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 460560) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 95542) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12463) @@ -136,7 +136,7 @@ EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 2 EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 158863) EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 189303) EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 147582) -EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 521508) +EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 521464) EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10459) EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15662) EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67195) @@ -158,7 +158,7 @@ EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77605) EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 207057) EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6389130) EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47785) -EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 5981174) +EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 5980336) EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 157326) EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103815) EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101686) @@ -177,18 +177,18 @@ EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 149137) EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6807322) EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17154) EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18413) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249368) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249346) EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20672) -EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 204173) +EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 201673) EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48860) EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48381) EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 232798) EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 89392) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 278146) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 278124) EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 93615) EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35083) EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23907) -EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 451358) +EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 451314) EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54475) EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35917) EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154369) @@ -201,16 +201,16 @@ EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Suc EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 173962) EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 193657) EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259648) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 129288) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 391710) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 129585) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 391688) EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65899) EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80955) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 535429) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 479260) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 535385) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 480301) EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35763) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 520344) -EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 517712) -EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 487848) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 520300) +EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 517668) +EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 487804) EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 127921) EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 157144) EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3655340) @@ -223,7 +223,7 @@ EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26004) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152867) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 507480) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails() (gas: 2307925) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails() (gas: 2307903) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 209633) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 210210) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 668610) @@ -232,20 +232,20 @@ EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 24131) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 59105) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 40405) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 76130) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 178951) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 76108) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 178929) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 278805) EVM2EVMMultiOffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11379) EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215406) EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14374) EVM2EVMMultiOffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11898) EVM2EVMMultiOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 14054) -EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 55771) -EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 33781) +EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 54933) +EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 32943) EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 238004) EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246667) -EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 299499) -EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 280579) +EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 299477) +EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 280557) EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176604) EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178672) EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141533) @@ -272,12 +272,12 @@ EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Succ EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 224545) EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 140840) EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 162262) -EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3805757) +EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3843523) EVM2EVMMultiOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 127615) EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 93044) -EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 285076) +EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 282576) EVM2EVMMultiOnRamp_getFee:test_EmptyMessage_Success() (gas: 104423) -EVM2EVMMultiOnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 74041) +EVM2EVMMultiOnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 74053) EVM2EVMMultiOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119755) EVM2EVMMultiOnRamp_getFee:test_Unhealthy_Revert() (gas: 43657) EVM2EVMMultiOnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10438) @@ -288,60 +288,60 @@ EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 1 EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 16287) EVM2EVMMultiOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 58439) EVM2EVMMultiOnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97185) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 38028) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 108191) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_revert_Revert() (gas: 116732) -EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 391880) -EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 145379) -EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 788000) -EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 176208) -EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 29700) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 63325) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 44501) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 214151) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 306912) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 38281) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 106252) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_revert_Revert() (gas: 114736) +EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 392159) +EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 145614) +EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 789382) +EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 176510) +EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 29914) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 61712) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 44959) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 214456) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 307176) EVM2EVMOffRamp__report:test_Report_Success() (gas: 127459) -EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 255047) -EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 263638) -EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 335707) -EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 314443) +EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 255279) +EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 263870) +EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 336203) +EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 314960) EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17009) -EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153427) -EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5464875) -EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 144183) -EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21345) -EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36442) +EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153158) +EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5275448) +EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 143892) +EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21323) +EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36486) EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51701) -EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 473575) +EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 473025) EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 46423) EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152453) -EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 101458) -EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 165036) -EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 177824) +EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 102724) +EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 164818) +EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 177584) EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 41317) -EVM2EVMOffRamp_execute:test_RouterYULCall_Revert() (gas: 402506) -EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 159387) -EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 174622) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 159365) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 174600) EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 248634) -EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114706) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 409338) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54173) +EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 115040) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 410767) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54196) EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 132056) -EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52200) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 560178) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 498159) -EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35442) -EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 546987) -EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64045) -EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 123223) -EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 143388) +EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52178) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 561690) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 500288) +EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35486) +EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 549267) +EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64023) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 123201) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 143411) +EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 428233) EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 20582) -EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 281891) -EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20231) -EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 221728) +EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 282255) +EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20209) +EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 219644) EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48632) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48120) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 316477) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48098) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 317243) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 72423) EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 231326) EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 279867) @@ -351,59 +351,60 @@ EVM2EVMOffRamp_execute_upgrade:test_V2_Success() (gas: 131682) EVM2EVMOffRamp_getAllRateLimitTokens:test_GetAllRateLimitTokens_Success() (gas: 38408) EVM2EVMOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3213556) EVM2EVMOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 83091) -EVM2EVMOffRamp_manuallyExecute:test_LowGasLimitManualExec_Success() (gas: 483328) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 186413) +EVM2EVMOffRamp_manuallyExecute:test_LowGasLimitManualExec_Success() (gas: 483110) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 185977) EVM2EVMOffRamp_manuallyExecute:test_ManualExecForkedChain_Revert() (gas: 25824) EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 43449) EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 25927) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithGasOverride_Success() (gas: 188518) -EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187965) -EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails() (gas: 2027441) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143803) -EVM2EVMOffRamp_metadataHash:test_MetadataHash_Success() (gas: 8871) -EVM2EVMOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 40429) -EVM2EVMOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 38804) -EVM2EVMOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 146790) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithGasOverride_Success() (gas: 188300) +EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187747) +EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails() (gas: 2050054) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143563) +EVM2EVMOffRamp_metadataHash:test_MetadataHash_Success() (gas: 8838) +EVM2EVMOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 40131) +EVM2EVMOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 38214) +EVM2EVMOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 142006) EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_AddsAndRemoves_Success() (gas: 162464) EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_NonOwner_Revert() (gas: 16667) EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_Success() (gas: 197660) -EVM2EVMOnRamp_constructor:test_Constructor_Success() (gas: 5619710) +EVM2EVMOnRamp_constructor:test_Constructor_Success() (gas: 5579769) EVM2EVMOnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 35778) -EVM2EVMOnRamp_forwardFromRouter:test_EnforceOutOfOrder_Revert() (gas: 99470) -EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 114210) -EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 114252) -EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 130118) -EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 138650) -EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 129804) -EVM2EVMOnRamp_forwardFromRouter:test_InvalidAddressEncodePacked_Revert() (gas: 38254) -EVM2EVMOnRamp_forwardFromRouter:test_InvalidAddress_Revert() (gas: 38370) -EVM2EVMOnRamp_forwardFromRouter:test_InvalidChainSelector_Revert() (gas: 25511) -EVM2EVMOnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 25297) +EVM2EVMOnRamp_forwardFromRouter:test_EnforceOutOfOrder_Revert() (gas: 98428) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 114198) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 114240) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 130207) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 138653) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 129829) +EVM2EVMOnRamp_forwardFromRouter:test_InvalidAddressEncodePacked_Revert() (gas: 38257) +EVM2EVMOnRamp_forwardFromRouter:test_InvalidAddress_Revert() (gas: 38440) +EVM2EVMOnRamp_forwardFromRouter:test_InvalidChainSelector_Revert() (gas: 25489) +EVM2EVMOnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 25275) EVM2EVMOnRamp_forwardFromRouter:test_MaxCapacityExceeded_Revert() (gas: 86041) EVM2EVMOnRamp_forwardFromRouter:test_MaxFeeBalanceReached_Revert() (gas: 36457) -EVM2EVMOnRamp_forwardFromRouter:test_MessageGasLimitTooHigh_Revert() (gas: 29037) -EVM2EVMOnRamp_forwardFromRouter:test_MessageTooLarge_Revert() (gas: 107526) -EVM2EVMOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 22635) -EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 226165) -EVM2EVMOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 53935) +EVM2EVMOnRamp_forwardFromRouter:test_MessageGasLimitTooHigh_Revert() (gas: 29015) +EVM2EVMOnRamp_forwardFromRouter:test_MessageTooLarge_Revert() (gas: 107571) +EVM2EVMOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 22679) +EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 224625) +EVM2EVMOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 53072) EVM2EVMOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 25481) -EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59303) -EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179141) -EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 177355) -EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137297) -EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3734267) +EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59347) +EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179148) +EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 177430) +EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137322) +EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3774775) EVM2EVMOnRamp_forwardFromRouter:test_TooManyTokens_Revert() (gas: 30187) EVM2EVMOnRamp_forwardFromRouter:test_Unhealthy_Revert() (gas: 43300) -EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109258) -EVM2EVMOnRamp_forwardFromRouter:test_ZeroAddressReceiver_Revert() (gas: 312351) -EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_ShouldStoreLinkFees_Success() (gas: 112319) -EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 72181) -EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 147614) -EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 190454) -EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 121245) -EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2_Success() (gas: 95324) -EVM2EVMOnRamp_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 20760) -EVM2EVMOnRamp_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 21128) +EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109283) +EVM2EVMOnRamp_forwardFromRouter:test_ZeroAddressReceiver_Revert() (gas: 312579) +EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_ShouldStoreLinkFees_Success() (gas: 112322) +EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 72206) +EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 710661) +EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 147664) +EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 190529) +EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 121320) +EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2_Success() (gas: 95349) +EVM2EVMOnRamp_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 20544) +EVM2EVMOnRamp_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20912) EVM2EVMOnRamp_getFee:test_EmptyMessage_Success() (gas: 78242) EVM2EVMOnRamp_getFee:test_HighGasMessage_Success() (gas: 234090) EVM2EVMOnRamp_getFee:test_MessageGasLimitTooHigh_Revert() (gas: 16715) @@ -412,56 +413,55 @@ EVM2EVMOnRamp_getFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 159220 EVM2EVMOnRamp_getFee:test_NotAFeeToken_Revert() (gas: 24089) EVM2EVMOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 117858) EVM2EVMOnRamp_getFee:test_TooManyTokens_Revert() (gas: 19902) -EVM2EVMOnRamp_getFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 65663) +EVM2EVMOnRamp_getFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 64654) EVM2EVMOnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10460) EVM2EVMOnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35195) -EVM2EVMOnRamp_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 45037) -EVM2EVMOnRamp_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 33041) +EVM2EVMOnRamp_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 45082) +EVM2EVMOnRamp_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 33019) EVM2EVMOnRamp_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 28296) -EVM2EVMOnRamp_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 130189) -EVM2EVMOnRamp_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 15260) +EVM2EVMOnRamp_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 126225) +EVM2EVMOnRamp_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 15238) EVM2EVMOnRamp_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 28104) EVM2EVMOnRamp_getTokenTransferCost:test_UnsupportedToken_Revert() (gas: 21248) -EVM2EVMOnRamp_getTokenTransferCost:test_WETHTokenBpsFee_Success() (gas: 38922) -EVM2EVMOnRamp_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 28149) -EVM2EVMOnRamp_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 38615) -EVM2EVMOnRamp_getTokenTransferCost:test__getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29527) +EVM2EVMOnRamp_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 28127) +EVM2EVMOnRamp_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 38599) +EVM2EVMOnRamp_getTokenTransferCost:test__getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29404) EVM2EVMOnRamp_linkAvailableForPayment:test_InsufficientLinkBalance_Success() (gas: 32615) EVM2EVMOnRamp_linkAvailableForPayment:test_LinkAvailableForPayment_Success() (gas: 134833) -EVM2EVMOnRamp_payNops:test_AdminPayNops_Success() (gas: 143054) -EVM2EVMOnRamp_payNops:test_InsufficientBalance_Revert() (gas: 29043) +EVM2EVMOnRamp_payNops:test_AdminPayNops_Success() (gas: 143159) +EVM2EVMOnRamp_payNops:test_InsufficientBalance_Revert() (gas: 26543) EVM2EVMOnRamp_payNops:test_NoFeesToPay_Revert() (gas: 127367) EVM2EVMOnRamp_payNops:test_NoNopsToPay_Revert() (gas: 133251) -EVM2EVMOnRamp_payNops:test_NopPayNops_Success() (gas: 146341) -EVM2EVMOnRamp_payNops:test_OwnerPayNops_Success() (gas: 140916) -EVM2EVMOnRamp_payNops:test_PayNopsSuccessAfterSetNops() (gas: 297485) +EVM2EVMOnRamp_payNops:test_NopPayNops_Success() (gas: 146446) +EVM2EVMOnRamp_payNops:test_OwnerPayNops_Success() (gas: 141021) +EVM2EVMOnRamp_payNops:test_PayNopsSuccessAfterSetNops() (gas: 297510) EVM2EVMOnRamp_payNops:test_WrongPermissions_Revert() (gas: 15294) -EVM2EVMOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 43376) -EVM2EVMOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 21646) -EVM2EVMOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 55086) +EVM2EVMOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 42365) +EVM2EVMOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 21246) +EVM2EVMOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 53764) EVM2EVMOnRamp_setFeeTokenConfig:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 13464) EVM2EVMOnRamp_setFeeTokenConfig:test_SetFeeTokenConfigByAdmin_Success() (gas: 16449) EVM2EVMOnRamp_setFeeTokenConfig:test_SetFeeTokenConfig_Success() (gas: 13994) EVM2EVMOnRamp_setNops:test_AdminCanSetNops_Success() (gas: 61759) -EVM2EVMOnRamp_setNops:test_IncludesPayment_Success() (gas: 469097) +EVM2EVMOnRamp_setNops:test_IncludesPayment_Success() (gas: 469227) EVM2EVMOnRamp_setNops:test_LinkTokenCannotBeNop_Revert() (gas: 57255) EVM2EVMOnRamp_setNops:test_NonOwnerOrAdmin_Revert() (gas: 14665) -EVM2EVMOnRamp_setNops:test_NotEnoughFundsForPayout_Revert() (gas: 84455) +EVM2EVMOnRamp_setNops:test_NotEnoughFundsForPayout_Revert() (gas: 84480) EVM2EVMOnRamp_setNops:test_SetNopsRemovesOldNopsCompletely_Success() (gas: 60637) -EVM2EVMOnRamp_setNops:test_SetNops_Success() (gas: 173677) +EVM2EVMOnRamp_setNops:test_SetNops_Success() (gas: 173782) EVM2EVMOnRamp_setNops:test_TooManyNops_Revert() (gas: 190338) EVM2EVMOnRamp_setNops:test_ZeroAddressCannotBeNop_Revert() (gas: 53596) -EVM2EVMOnRamp_setTokenTransferFeeConfig:test__setTokenTransferFeeConfig_InvalidDestBytesOverhead_Revert() (gas: 14493) +EVM2EVMOnRamp_setTokenTransferFeeConfig:test__setTokenTransferFeeConfig_InvalidDestBytesOverhead_Revert() (gas: 14499) EVM2EVMOnRamp_setTokenTransferFeeConfig:test__setTokenTransferFeeConfig_OnlyCallableByOwnerOrAdmin_Revert() (gas: 14277) -EVM2EVMOnRamp_setTokenTransferFeeConfig:test__setTokenTransferFeeConfig_Success() (gas: 84017) +EVM2EVMOnRamp_setTokenTransferFeeConfig:test__setTokenTransferFeeConfig_Success() (gas: 84029) EVM2EVMOnRamp_setTokenTransferFeeConfig:test__setTokenTransferFeeConfig_byAdmin_Success() (gas: 17369) -EVM2EVMOnRamp_withdrawNonLinkFees:test_LinkBalanceNotSettled_Revert() (gas: 82980) +EVM2EVMOnRamp_withdrawNonLinkFees:test_LinkBalanceNotSettled_Revert() (gas: 83005) EVM2EVMOnRamp_withdrawNonLinkFees:test_NonOwnerOrAdmin_Revert() (gas: 15275) -EVM2EVMOnRamp_withdrawNonLinkFees:test_SettlingBalance_Success() (gas: 272015) +EVM2EVMOnRamp_withdrawNonLinkFees:test_SettlingBalance_Success() (gas: 272035) EVM2EVMOnRamp_withdrawNonLinkFees:test_WithdrawNonLinkFees_Success() (gas: 53446) EVM2EVMOnRamp_withdrawNonLinkFees:test_WithdrawToZeroAddress_Revert() (gas: 12830) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_fallbackToWethTransfer() (gas: 96729) -EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 49688) +EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 47688) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongToken() (gas: 17384) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongTokenAmount() (gas: 15677) EtherSenderReceiverTest_ccipSend:test_ccipSend_reverts_insufficientFee_feeToken() (gas: 99741) @@ -481,38 +481,32 @@ EtherSenderReceiverTest_validatedMessage:test_validatedMessage_emptyDataOverwrit EtherSenderReceiverTest_validatedMessage:test_validatedMessage_invalidTokenAmounts() (gas: 17895) EtherSenderReceiverTest_validatedMessage:test_validatedMessage_tokenOverwrittenToWeth() (gas: 25287) EtherSenderReceiverTest_validatedMessage:test_validatedMessage_validMessage_extraArgs() (gas: 26292) -LockReleaseTokenPoolAndProxy_setRateLimitAdmin:test_SetRateLimitAdmin_Revert() (gas: 11058) -LockReleaseTokenPoolAndProxy_setRateLimitAdmin:test_SetRateLimitAdmin_Success() (gas: 35097) -LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Revert() (gas: 10970) -LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Success() (gas: 18036) -LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3313980) -LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3310379) +LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Revert() (gas: 10992) +LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Success() (gas: 18058) +LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3355878) +LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3352276) LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_Unauthorized_Revert() (gas: 11380) -LockReleaseTokenPoolPoolAndProxy_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 17135) -LockReleaseTokenPoolPoolAndProxy_setChainRateLimiterConfig:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 69142) -LockReleaseTokenPoolPoolAndProxy_setChainRateLimiterConfig:test_OnlyOwner_Revert() (gas: 17319) LockReleaseTokenPoolPoolAndProxy_supportsInterface:test_SupportsInterface_Success() (gas: 9977) LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60043) LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11355) -LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3067883) +LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3121619) LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29942) LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Success() (gas: 79844) LockReleaseTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 59464) -LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3064325) +LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3118061) LockReleaseTokenPool_provideLiquidity:test_Unauthorized_Revert() (gas: 11380) -LockReleaseTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 72662) -LockReleaseTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56131) -LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 238673) -LockReleaseTokenPool_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 17102) -LockReleaseTokenPool_setChainRateLimiterConfig:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 69075) -LockReleaseTokenPool_setChainRateLimiterConfig:test_OnlyOwner_Revert() (gas: 17297) -LockReleaseTokenPool_setRateLimitAdmin:test_SetRateLimitAdmin_Revert() (gas: 11057) -LockReleaseTokenPool_setRateLimitAdmin:test_SetRateLimitAdmin_Success() (gas: 35140) +LockReleaseTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 72644) +LockReleaseTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56196) +LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 238656) LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Revert() (gas: 10992) -LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Success() (gas: 17926) +LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Success() (gas: 18058) LockReleaseTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 9977) +LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_Success() (gas: 83171) +LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_transferTooMuch_Revert() (gas: 55878) LockReleaseTokenPool_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60043) LockReleaseTokenPool_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11355) +LockRelease_setRateLimitAdmin:test_SetRateLimitAdmin_Revert() (gas: 11029) +LockRelease_setRateLimitAdmin:test_SetRateLimitAdmin_Success() (gas: 35030) MerkleMultiProofTest:test_CVE_2023_34459() (gas: 5451) MerkleMultiProofTest:test_EmptyLeaf_Revert() (gas: 3552) MerkleMultiProofTest:test_MerkleRoot256() (gas: 394876) @@ -548,7 +542,7 @@ MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExce MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78780) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 263510) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54784) -MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 1073667518) +MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 9223372036854754743) MultiAggregateRateLimiter_onOutboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 19104) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 15778) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 189438) @@ -590,16 +584,16 @@ MultiOCR3Base_transmit:test_InsufficientSignatures_Revert() (gas: 76930) MultiOCR3Base_transmit:test_NonUniqueSignature_Revert() (gas: 66127) MultiOCR3Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 33419) MultiOCR3Base_transmit:test_TooManySignatures_Revert() (gas: 79521) -MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34020) +MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34131) MultiOCR3Base_transmit:test_TransmitWithExtraCalldataArgs_Revert() (gas: 47114) MultiOCR3Base_transmit:test_TransmitWithLessCalldataArgs_Revert() (gas: 25682) -MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18714) +MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18726) MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) -MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 412349) -MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1423227) +MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 412263) +MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1426954) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) @@ -611,9 +605,9 @@ NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success( NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 247990) NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 236024) NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 144774) -NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 186669) -NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 237737) -NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 124995) +NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 186694) +NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 237762) +NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 125923) NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 122899) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOffRamp_Revert() (gas: 42959) @@ -628,7 +622,7 @@ OCR2BaseNoChecks_setOCR2Config:test_TooManyTransmitter_Revert() (gas: 36938) OCR2BaseNoChecks_setOCR2Config:test_TransmitterCannotBeZeroAddress_Revert() (gas: 24158) OCR2BaseNoChecks_transmit:test_ConfigDigestMismatch_Revert() (gas: 17448) OCR2BaseNoChecks_transmit:test_ForkedChain_Revert() (gas: 26726) -OCR2BaseNoChecks_transmit:test_TransmitSuccess_gas() (gas: 27466) +OCR2BaseNoChecks_transmit:test_TransmitSuccess_gas() (gas: 27478) OCR2BaseNoChecks_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 21296) OCR2Base_setOCR2Config:test_FMustBePositive_Revert() (gas: 12189) OCR2Base_setOCR2Config:test_FTooHigh_Revert() (gas: 12345) @@ -642,38 +636,38 @@ OCR2Base_transmit:test_ConfigDigestMismatch_Revert() (gas: 19623) OCR2Base_transmit:test_ForkedChain_Revert() (gas: 37683) OCR2Base_transmit:test_NonUniqueSignature_Revert() (gas: 55309) OCR2Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 20962) -OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51674) +OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51686) OCR2Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 23484) OCR2Base_transmit:test_UnauthorizedSigner_Revert() (gas: 39665) OCR2Base_transmit:test_WrongNumberOfSignatures_Revert() (gas: 20557) -OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 380360) -PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150880) +OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 390410) +PingPong_ccipReceive:test_CcipReceive_Success() (gas: 148405) PingPong_plumbing:test_Pausing_Success() (gas: 17803) -PingPong_startPingPong:test_StartPingPong_Success() (gas: 178340) -PriceRegistry_applyDestChainConfigUpdates:test_InvalidChainFamilySelector_Revert() (gas: 16719) -PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 16784) -PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestChainConfigDestChainSelectorEqZero_Revert() (gas: 16611) -PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitEqZero_Revert() (gas: 16675) -PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitGtMaxPerMessageGasLimit_Revert() (gas: 40953) +PingPong_startPingPong:test_StartPingPong_Success() (gas: 178365) +PriceRegistry_applyDestChainConfigUpdates:test_InvalidChainFamilySelector_Revert() (gas: 16725) +PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 16816) +PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestChainConfigDestChainSelectorEqZero_Revert() (gas: 16617) +PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitEqZero_Revert() (gas: 16681) +PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitGtMaxPerMessageGasLimit_Revert() (gas: 40971) PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesZeroIntput_Success() (gas: 12341) -PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdates_Success() (gas: 139564) +PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdates_Success() (gas: 139588) PriceRegistry_applyFeeTokensUpdates:test_ApplyFeeTokensUpdates_Success() (gas: 80002) PriceRegistry_applyFeeTokensUpdates:test_OnlyCallableByOwner_Revert() (gas: 12603) PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 11465) PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesMultipleTokens_Success() (gas: 54149) PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesSingleToken_Success() (gas: 44835) PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesZeroInput() (gas: 12301) -PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfig_Success() (gas: 86826) +PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfig_Success() (gas: 86838) PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeZeroInput() (gas: 13089) -PriceRegistry_applyTokenTransferFeeConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 17045) +PriceRegistry_applyTokenTransferFeeConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 17071) PriceRegistry_applyTokenTransferFeeConfigUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 12240) -PriceRegistry_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 105966) -PriceRegistry_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 110316) -PriceRegistry_constructor:test_InvalidStalenessThreshold_Revert() (gas: 110369) -PriceRegistry_constructor:test_Setup_Success() (gas: 4650895) +PriceRegistry_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 100407) +PriceRegistry_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 104757) +PriceRegistry_constructor:test_InvalidStalenessThreshold_Revert() (gas: 104810) +PriceRegistry_constructor:test_Setup_Success() (gas: 4615196) PriceRegistry_convertTokenAmount:test_ConvertTokenAmount_Success() (gas: 72751) PriceRegistry_convertTokenAmount:test_LinkTokenNotSupported_Revert() (gas: 30981) -PriceRegistry_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 95575) +PriceRegistry_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 95587) PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCostUnsupportedDestChainSelector_Success() (gas: 14636) PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20614) PriceRegistry_getTokenAndGasPrices:test_GetFeeTokenAndGasPrices_Success() (gas: 70449) @@ -682,19 +676,18 @@ PriceRegistry_getTokenAndGasPrices:test_UnsupportedChain_Revert() (gas: 16140) PriceRegistry_getTokenAndGasPrices:test_ZeroGasPrice_Success() (gas: 45734) PriceRegistry_getTokenPrice:test_GetTokenPriceFromFeed_Success() (gas: 62311) PriceRegistry_getTokenPrices:test_GetTokenPrices_Success() (gas: 84774) -PriceRegistry_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 41283) -PriceRegistry_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 34733) -PriceRegistry_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 27807) -PriceRegistry_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 108018) -PriceRegistry_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 20359) -PriceRegistry_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 27615) -PriceRegistry_getTokenTransferCost:test_WETHTokenBpsFee_Success() (gas: 40668) -PriceRegistry_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 27638) -PriceRegistry_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 40015) -PriceRegistry_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29343) +PriceRegistry_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 41255) +PriceRegistry_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 34705) +PriceRegistry_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 27779) +PriceRegistry_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 101708) +PriceRegistry_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 20398) +PriceRegistry_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 27654) +PriceRegistry_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 27610) +PriceRegistry_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 40058) +PriceRegistry_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29337) PriceRegistry_getValidatedFee:test_DestinationChainNotEnabled_Revert() (gas: 18203) PriceRegistry_getValidatedFee:test_EmptyMessage_Success() (gas: 81464) -PriceRegistry_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 55184) +PriceRegistry_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 55196) PriceRegistry_getValidatedFee:test_HighGasMessage_Success() (gas: 237926) PriceRegistry_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 19971) PriceRegistry_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 31775) @@ -703,7 +696,7 @@ PriceRegistry_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (ga PriceRegistry_getValidatedFee:test_NotAFeeToken_Revert() (gas: 29435) PriceRegistry_getValidatedFee:test_SingleTokenMessage_Success() (gas: 112283) PriceRegistry_getValidatedFee:test_TooManyTokens_Revert() (gas: 20107) -PriceRegistry_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 62956) +PriceRegistry_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 62962) PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Above18Decimals_Success() (gas: 2094532) PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Below18Decimals_Success() (gas: 2094490) PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt0Decimals_Success() (gas: 2074609) @@ -749,7 +742,7 @@ PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddress_Revert() (gas: 10 PriceRegistry_validateDestFamilyAddress:test_ValidEVMAddress_Success() (gas: 6660) PriceRegistry_validateDestFamilyAddress:test_ValidNonEVMAddress_Success() (gas: 6440) PriceRegistry_validatePoolReturnData:test_InvalidEVMAddressDestToken_Revert() (gas: 35457) -PriceRegistry_validatePoolReturnData:test_SourceTokenDataTooLarge_Revert() (gas: 90631) +PriceRegistry_validatePoolReturnData:test_SourceTokenDataTooLarge_Revert() (gas: 90709) PriceRegistry_validatePoolReturnData:test_TokenAmountArraysMismatching_Revert() (gas: 32749) PriceRegistry_validatePoolReturnData:test_WithSingleToken_Success() (gas: 31293) RMN_constructor:test_Constructor_Success() (gas: 48838) @@ -759,7 +752,7 @@ RMN_ownerUnbless:test_Unbless_Success() (gas: 74699) RMN_ownerUnvoteToCurse:test_CanBlessAndCurseAfterGlobalCurseIsLifted() (gas: 470965) RMN_ownerUnvoteToCurse:test_IsIdempotent() (gas: 397532) RMN_ownerUnvoteToCurse:test_NonOwner_Revert() (gas: 18591) -RMN_ownerUnvoteToCurse:test_OwnerUnvoteToCurseSuccess_gas() (gas: 357400) +RMN_ownerUnvoteToCurse:test_OwnerUnvoteToCurseSuccess_gas() (gas: 357403) RMN_ownerUnvoteToCurse:test_UnknownVoter_Revert() (gas: 32980) RMN_ownerUnvoteToCurse_Benchmark:test_OwnerUnvoteToCurse_1Voter_LiftsCurse_gas() (gas: 261985) RMN_permaBlessing:test_PermaBlessing() (gas: 202686) @@ -767,7 +760,7 @@ RMN_setConfig:test_BlessVoterIsZeroAddress_Revert() (gas: 15494) RMN_setConfig:test_EitherThresholdIsZero_Revert() (gas: 21095) RMN_setConfig:test_NonOwner_Revert() (gas: 14713) RMN_setConfig:test_RepeatedAddress_Revert() (gas: 18213) -RMN_setConfig:test_SetConfigSuccess_gas() (gas: 104022) +RMN_setConfig:test_SetConfigSuccess_gas() (gas: 104204) RMN_setConfig:test_TotalWeightsSmallerThanEachThreshold_Revert() (gas: 30173) RMN_setConfig:test_VoteToBlessByEjectedVoter_Revert() (gas: 130303) RMN_setConfig:test_VotersLengthIsZero_Revert() (gas: 12128) @@ -831,39 +824,39 @@ Router_applyRampUpdates:test_OffRampMismatch_Revert() (gas: 89288) Router_applyRampUpdates:test_OffRampUpdatesWithRouting() (gas: 10642128) Router_applyRampUpdates:test_OnRampDisable() (gas: 55913) Router_applyRampUpdates:test_OnlyOwner_Revert() (gas: 12311) -Router_ccipSend:test_CCIPSendLinkFeeNoTokenSuccess_gas() (gas: 113861) -Router_ccipSend:test_CCIPSendLinkFeeOneTokenSuccess_gas() (gas: 200634) -Router_ccipSend:test_CCIPSendNativeFeeNoTokenSuccess_gas() (gas: 128508) -Router_ccipSend:test_CCIPSendNativeFeeOneTokenSuccess_gas() (gas: 215283) +Router_ccipSend:test_CCIPSendLinkFeeNoTokenSuccess_gas() (gas: 113886) +Router_ccipSend:test_CCIPSendLinkFeeOneTokenSuccess_gas() (gas: 201407) +Router_ccipSend:test_CCIPSendNativeFeeNoTokenSuccess_gas() (gas: 128533) +Router_ccipSend:test_CCIPSendNativeFeeOneTokenSuccess_gas() (gas: 216056) Router_ccipSend:test_FeeTokenAmountTooLow_Revert() (gas: 66275) Router_ccipSend:test_InvalidMsgValue() (gas: 31963) -Router_ccipSend:test_NativeFeeTokenInsufficientValue() (gas: 68711) -Router_ccipSend:test_NativeFeeTokenOverpay_Success() (gas: 173605) +Router_ccipSend:test_NativeFeeTokenInsufficientValue() (gas: 68746) +Router_ccipSend:test_NativeFeeTokenOverpay_Success() (gas: 173630) Router_ccipSend:test_NativeFeeTokenZeroValue() (gas: 56037) -Router_ccipSend:test_NativeFeeToken_Success() (gas: 172199) -Router_ccipSend:test_NonLinkFeeToken_Success() (gas: 242707) +Router_ccipSend:test_NativeFeeToken_Success() (gas: 172224) +Router_ccipSend:test_NonLinkFeeToken_Success() (gas: 242732) Router_ccipSend:test_UnsupportedDestinationChain_Revert() (gas: 24749) Router_ccipSend:test_WhenNotHealthy_Revert() (gas: 44724) -Router_ccipSend:test_WrappedNativeFeeToken_Success() (gas: 174415) -Router_ccipSend:test_ZeroFeeAndGasPrice_Success() (gas: 245121) +Router_ccipSend:test_WrappedNativeFeeToken_Success() (gas: 174440) +Router_ccipSend:test_ZeroFeeAndGasPrice_Success() (gas: 245146) Router_constructor:test_Constructor_Success() (gas: 13074) Router_getArmProxy:test_getArmProxy() (gas: 10561) Router_getFee:test_GetFeeSupportedChain_Success() (gas: 46464) Router_getFee:test_UnsupportedDestinationChain_Revert() (gas: 17138) Router_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10460) Router_recoverTokens:test_RecoverTokensInvalidRecipient_Revert() (gas: 11316) -Router_recoverTokens:test_RecoverTokensNoFunds_Revert() (gas: 20261) +Router_recoverTokens:test_RecoverTokensNoFunds_Revert() (gas: 17761) Router_recoverTokens:test_RecoverTokensNonOwner_Revert() (gas: 11159) Router_recoverTokens:test_RecoverTokensValueReceiver_Revert() (gas: 422138) -Router_recoverTokens:test_RecoverTokens_Success() (gas: 52437) +Router_recoverTokens:test_RecoverTokens_Success() (gas: 50437) Router_routeMessage:test_AutoExec_Success() (gas: 42684) -Router_routeMessage:test_ExecutionEvent_Success() (gas: 158002) +Router_routeMessage:test_ExecutionEvent_Success() (gas: 157980) Router_routeMessage:test_ManualExec_Success() (gas: 35381) Router_routeMessage:test_OnlyOffRamp_Revert() (gas: 25116) Router_routeMessage:test_WhenNotHealthy_Revert() (gas: 44724) Router_setWrappedNative:test_OnlyOwner_Revert() (gas: 10985) -SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 55540) -SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 419430) +SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 53540) +SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 417080) SelfFundedPingPong_setCountIncrBeforeFunding:test_setCountIncrBeforeFunding() (gas: 20157) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_OnlyPendingAdministrator_Revert() (gas: 51085) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_Success() (gas: 43947) @@ -887,57 +880,56 @@ TokenAdminRegistry_setPool:test_setPool_Success() (gas: 35943) TokenAdminRegistry_setPool:test_setPool_ZeroAddressRemovesPool_Success() (gas: 30617) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_OnlyAdministrator_Revert() (gas: 18043) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_Success() (gas: 49390) -TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6036775) -TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6282531) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6885897) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7070012) -TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2169749) +TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6076728) +TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6324538) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6924810) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7108901) +TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2209837) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12089) -TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23280) -TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowList_Success() (gas: 177516) -TokenPoolWithAllowList_getAllowList:test_GetAllowList_Success() (gas: 23648) +TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23324) +TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowList_Success() (gas: 177568) +TokenPoolWithAllowList_getAllowList:test_GetAllowList_Success() (gas: 23670) TokenPoolWithAllowList_getAllowListEnabled:test_GetAllowListEnabled_Success() (gas: 8363) -TokenPoolWithAllowList_setRouter:test_SetRouter_Success() (gas: 24765) +TokenPoolWithAllowList_setRouter:test_SetRouter_Success() (gas: 24831) TokenPool_applyChainUpdates:test_applyChainUpdates_DisabledNonZeroRateLimit_Revert() (gas: 271305) TokenPool_applyChainUpdates:test_applyChainUpdates_InvalidRateLimitRate_Revert() (gas: 541162) TokenPool_applyChainUpdates:test_applyChainUpdates_NonExistentChain_Revert() (gas: 18344) TokenPool_applyChainUpdates:test_applyChainUpdates_OnlyCallableByOwner_Revert() (gas: 11385) -TokenPool_applyChainUpdates:test_applyChainUpdates_Success() (gas: 476472) +TokenPool_applyChainUpdates:test_applyChainUpdates_Success() (gas: 476468) TokenPool_applyChainUpdates:test_applyChainUpdates_ZeroAddressNotAllowed_Revert() (gas: 157074) -TokenPool_constructor:test_ZeroAddressNotAllowed_Revert() (gas: 70676) -TokenPool_constructor:test_immutableFields_Success() (gas: 20522) +TokenPool_constructor:test_ZeroAddressNotAllowed_Revert() (gas: 70721) +TokenPool_constructor:test_immutableFields_Success() (gas: 20544) TokenPool_getRemotePool:test_getRemotePool_Success() (gas: 273962) -TokenPool_onlyOffRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 276952) -TokenPool_onlyOffRamp:test_ChainNotAllowed_Revert() (gas: 289509) -TokenPool_onlyOffRamp:test_onlyOffRamp_Success() (gas: 349763) +TokenPool_onlyOffRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 276909) +TokenPool_onlyOffRamp:test_ChainNotAllowed_Revert() (gas: 289406) +TokenPool_onlyOffRamp:test_onlyOffRamp_Success() (gas: 349720) TokenPool_onlyOnRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 276643) -TokenPool_onlyOnRamp:test_ChainNotAllowed_Revert() (gas: 253466) +TokenPool_onlyOnRamp:test_ChainNotAllowed_Revert() (gas: 253432) TokenPool_onlyOnRamp:test_onlyOnRamp_Success() (gas: 304761) -TokenPool_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 14906) -TokenPool_setChainRateLimiterConfig:test_OnlyOwner_Revert() (gas: 12565) -TokenPool_setRemotePool:test_setRemotePool_NonExistentChain_Reverts() (gas: 15598) -TokenPool_setRemotePool:test_setRemotePool_OnlyOwner_Reverts() (gas: 13173) -TokenPool_setRemotePool:test_setRemotePool_Success() (gas: 281890) +TokenPool_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 17061) +TokenPool_setChainRateLimiterConfig:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 15062) +TokenPool_setRemotePool:test_setRemotePool_NonExistentChain_Reverts() (gas: 15620) +TokenPool_setRemotePool:test_setRemotePool_OnlyOwner_Reverts() (gas: 13195) +TokenPool_setRemotePool:test_setRemotePool_Success() (gas: 281912) TokenProxy_ccipSend:test_CcipSendGasShouldBeZero_Revert() (gas: 17109) -TokenProxy_ccipSend:test_CcipSendInsufficientAllowance_Revert() (gas: 136351) +TokenProxy_ccipSend:test_CcipSendInsufficientAllowance_Revert() (gas: 136228) TokenProxy_ccipSend:test_CcipSendInvalidToken_Revert() (gas: 15919) -TokenProxy_ccipSend:test_CcipSendNative_Success() (gas: 244483) +TokenProxy_ccipSend:test_CcipSendNative_Success() (gas: 245256) TokenProxy_ccipSend:test_CcipSendNoDataAllowed_Revert() (gas: 16303) -TokenProxy_ccipSend:test_CcipSend_Success() (gas: 261100) +TokenProxy_ccipSend:test_CcipSend_Success() (gas: 261620) TokenProxy_constructor:test_Constructor() (gas: 13812) TokenProxy_getFee:test_GetFeeGasShouldBeZero_Revert() (gas: 16827) TokenProxy_getFee:test_GetFeeInvalidToken_Revert() (gas: 12658) TokenProxy_getFee:test_GetFeeNoDataAllowed_Revert() (gas: 15849) -TokenProxy_getFee:test_GetFee_Success() (gas: 86948) -USDCTokenPool__validateMessage:test_ValidateInvalidMessage_Revert() (gas: 24960) -USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35312) -USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 30063) -USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 132864) -USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 477209) -USDCTokenPool_lockOrBurn:test_lockOrBurn_InvalidReceiver_Revert() (gas: 52606) -USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 289268) -USDCTokenPool_releaseOrMint:test_TokenMaxCapacityExceeded_Revert() (gas: 50682) -USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 119185) +TokenProxy_getFee:test_GetFee_Success() (gas: 86702) +USDCTokenPool__validateMessage:test_ValidateInvalidMessage_Revert() (gas: 25290) +USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35322) +USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 30073) +USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 132756) +USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 477205) +USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 289263) +USDCTokenPool_releaseOrMint:test_TokenMaxCapacityExceeded_Revert() (gas: 50676) +USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 118987) USDCTokenPool_setDomains:test_InvalidDomain_Revert() (gas: 66150) USDCTokenPool_setDomains:test_OnlyOwner_Revert() (gas: 11339) USDCTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 9876) \ No newline at end of file diff --git a/contracts/gas-snapshots/liquiditymanager.gas-snapshot b/contracts/gas-snapshots/liquiditymanager.gas-snapshot index 4966013617..fbf8074c3e 100644 --- a/contracts/gas-snapshots/liquiditymanager.gas-snapshot +++ b/contracts/gas-snapshots/liquiditymanager.gas-snapshot @@ -3,9 +3,9 @@ LiquidityManager_addLiquidity:test_addLiquiditySuccess() (gas: 279154) LiquidityManager_rebalanceLiquidity:test_InsufficientLiquidityReverts() (gas: 206745) LiquidityManager_rebalanceLiquidity:test_InvalidRemoteChainReverts() (gas: 192319) LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess() (gas: 9141768) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 8898695) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 8893901) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 8821699) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 8957594) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 8952800) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 8880598) LiquidityManager_rebalanceLiquidity:test_rebalanceLiquiditySuccess() (gas: 382897) LiquidityManager_receive:test_receive_success() (gas: 21182) LiquidityManager_removeLiquidity:test_InsufficientLiquidityReverts() (gas: 184869) @@ -19,7 +19,7 @@ LiquidityManager_setFinanceRole:test_OnlyOwnerReverts() (gas: 10987) LiquidityManager_setFinanceRole:test_setFinanceRoleSuccess() (gas: 21836) LiquidityManager_setLocalLiquidityContainer:test_OnlyOwnerReverts() (gas: 11052) LiquidityManager_setLocalLiquidityContainer:test_ReverstWhen_CalledWithTheZeroAddress() (gas: 10643) -LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3436651) +LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3495598) LiquidityManager_setMinimumLiquidity:test_OnlyOwnerReverts() (gas: 10925) LiquidityManager_setMinimumLiquidity:test_setMinimumLiquiditySuccess() (gas: 36389) LiquidityManager_withdrawERC20:test_withdrawERC20Reverts() (gas: 180359) diff --git a/contracts/src/v0.8/ccip/libraries/Internal.sol b/contracts/src/v0.8/ccip/libraries/Internal.sol index db2bc05ee5..4aa2f975e4 100644 --- a/contracts/src/v0.8/ccip/libraries/Internal.sol +++ b/contracts/src/v0.8/ccip/libraries/Internal.sol @@ -65,6 +65,7 @@ library Internal { // CCIP_LOCK_OR_BURN_V1_RET_BYTES bytes. If more data is required, the TokenTransferFeeConfig.destBytesOverhead // has to be set for the specific token. bytes extraData; + uint32 destGasAmount; // The amount of gas available for the releaseOrMint and transfer calls on the offRamp } /// @notice Report that is submitted by the execution DON at the execution phase. (including chain selector data) @@ -91,19 +92,19 @@ library Internal { /// @notice The cross chain message that gets committed to EVM chains. /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. struct EVM2EVMMessage { - uint64 sourceChainSelector; // ───────────╮ the chain selector of the source chain, note: not chainId - address sender; // ───────────────────────╯ sender address on the source chain - address receiver; // ─────────────────────╮ receiver address on the destination chain - uint64 sequenceNumber; // ────────────────╯ sequence number, not unique across lanes - uint256 gasLimit; // user supplied maximum gas amount available for dest chain execution - bool strict; // ──────────────────────────╮ DEPRECATED - uint64 nonce; // │ nonce for this lane for this sender, not unique across senders/lanes - address feeToken; // ─────────────────────╯ fee token - uint256 feeTokenAmount; // fee token amount - bytes data; // arbitrary data payload supplied by the message sender - Client.EVMTokenAmount[] tokenAmounts; // array of tokens and amounts to transfer - bytes[] sourceTokenData; // array of token data, one per token - bytes32 messageId; // a hash of the message data + uint64 sourceChainSelector; // ────────╮ the chain selector of the source chain, note: not chainId + address sender; // ────────────────────╯ sender address on the source chain + address receiver; // ──────────────────╮ receiver address on the destination chain + uint64 sequenceNumber; // ─────────────╯ sequence number, not unique across lanes + uint256 gasLimit; // user supplied maximum gas amount available for dest chain execution + bool strict; // ───────────────────────╮ DEPRECATED + uint64 nonce; // │ nonce for this lane for this sender, not unique across senders/lanes + address feeToken; // ──────────────────╯ fee token + uint256 feeTokenAmount; // fee token amount + bytes data; // arbitrary data payload supplied by the message sender + Client.EVMTokenAmount[] tokenAmounts; // array of tokens and amounts to transfer + bytes[] sourceTokenData; // array of token data, one per token + bytes32 messageId; // a hash of the message data } /// @dev EVM2EVMMessage struct has 13 fields, including 3 variable arrays. @@ -113,9 +114,20 @@ library Internal { /// For structs that contain arrays, 1 more slot is added to the front, reaching a total of 17. uint256 public constant MESSAGE_FIXED_BYTES = 32 * 17; - /// @dev Each token transfer adds 1 EVMTokenAmount and 1 bytes. - /// When abiEncoded, each EVMTokenAmount takes 2 slots, each bytes takes 2 slots, excl bytes contents - uint256 public constant MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * 4; + /// @dev Each token transfer adds 1 EVMTokenAmount and 3 bytes at 3 slots each and one slot for the destGasAmount. + /// When abi encoded, each EVMTokenAmount takes 2 slots, each bytes takes 1 slot for length, one slot of data and one + /// slot for the offset. This results in effectively 3*3 slots per SourceTokenData. + /// 0x20 + /// destGasAmount + /// sourcePoolAddress_offset + /// destTokenAddress_offset + /// extraData_offset + /// sourcePoolAddress_length + /// sourcePoolAddress_content // assume 1 slot + /// destTokenAddress_length + /// destTokenAddress_content // assume 1 slot + /// extraData_length // contents billed separately + uint256 public constant MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * ((1 + 3 * 3) + 2); /// @dev Any2EVMRampMessage struct has 10 fields, including 3 variable unnested arrays (data, receiver and tokenAmounts). /// Each variable array takes 1 more slot to store its length. @@ -127,9 +139,9 @@ library Internal { /// @dev Each token transfer adds 1 RampTokenAmount /// RampTokenAmount has 4 fields, including 3 bytes. - /// Each bytes takes 1 more slot to store its length. - /// When abi encoded, each token transfer takes up 7 slots, excl bytes contents. - uint256 public constant ANY_2_EVM_MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * 7; + /// Each bytes takes 1 more slot to store its length, and one slot to store the offset. + /// When abi encoded, each token transfer takes up 10 slots, excl bytes contents. + uint256 public constant ANY_2_EVM_MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * 10; bytes32 internal constant EVM_2_EVM_MESSAGE_HASH = keccak256("EVM2EVMMessageHashV2"); @@ -226,8 +238,12 @@ library Internal { ); } - /// @dev We disallow the first 1024 addresses to never allow calling precompiles. It is extremely unlikely that - /// anyone would ever be able to generate an address in this range. + /// @dev We disallow the first 1024 addresses to avoid calling into a range known for hosting precompiles. Calling + /// into precompiles probably won't cause any issues, but to be safe we can disallow this range. It is extremely + /// unlikely that anyone would ever be able to generate an address in this range. There is no official range of + /// precompiles, but EIP-7587 proposes to reserve the range 0x100 to 0x1ff. Our range is more conservative, even + /// though it might not be exhaustive for all chains, which is OK. We also disallow the zero address, which is a + /// common practice. uint256 public constant PRECOMPILE_SPACE = 1024; /// @notice This methods provides validation for parsing abi encoded addresses by ensuring the @@ -282,10 +298,10 @@ library Internal { /// The messageId is not expected to match hash(message), since it may originate from another ramp family struct RampMessageHeader { bytes32 messageId; // Unique identifier for the message, generated with the source chain's encoding scheme (i.e. not necessarily abi.encoded) - uint64 sourceChainSelector; // ───────╮ the chain selector of the source chain, note: not chainId - uint64 destChainSelector; // | the chain selector of the destination chain, note: not chainId - uint64 sequenceNumber; // │ sequence number, not unique across lanes - uint64 nonce; // ─────────────────────╯ nonce for this lane for this sender, not unique across senders/lanes + uint64 sourceChainSelector; // ──╮ the chain selector of the source chain, note: not chainId + uint64 destChainSelector; // | the chain selector of the destination chain, note: not chainId + uint64 sequenceNumber; // │ sequence number, not unique across lanes + uint64 nonce; // ────────────────╯ nonce for this lane for this sender, not unique across senders/lanes } /// @notice Family-agnostic message routed to an OffRamp diff --git a/contracts/src/v0.8/ccip/libraries/Pool.sol b/contracts/src/v0.8/ccip/libraries/Pool.sol index 3f1895dcf5..263ee380e8 100644 --- a/contracts/src/v0.8/ccip/libraries/Pool.sol +++ b/contracts/src/v0.8/ccip/libraries/Pool.sol @@ -14,7 +14,7 @@ library Pool { // The default max number of bytes in the return data for a pool v1 lockOrBurn call. // This data can be used to send information to the destination chain token pool. Can be overwritten // in the TokenTransferFeeConfig.destBytesOverhead if more data is required. - uint256 public constant CCIP_LOCK_OR_BURN_V1_RET_BYTES = 32; + uint32 public constant CCIP_LOCK_OR_BURN_V1_RET_BYTES = 32; struct LockOrBurnInV1 { bytes receiver; // The recipient of the tokens on the destination chain, abi encoded @@ -25,7 +25,7 @@ library Pool { } struct LockOrBurnOutV1 { - // The address of the destination token pool, abi encoded in the case of EVM chains + // The address of the destination token, abi encoded in the case of EVM chains // This value is UNTRUSTED as any pool owner can return whatever value they want. bytes destTokenAddress; // Optional pool data to be transferred to the destination chain. Be default this is capped at diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol index 1aec436ef8..9950ff4259 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol @@ -90,9 +90,7 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio uint32 maxDataBytes; // │ Maximum payload data size in bytes uint16 maxNumberOfTokensPerMsg; // │ Maximum number of ERC20 token transfers that can be included per message address router; // ─────────────────────────────────╯ Router address - address priceRegistry; // ──────────╮ Price registry address - uint32 maxPoolReleaseOrMintGas; // │ Maximum amount of gas passed on to token pool `releaseOrMint` call - uint32 maxTokenTransferGas; // ─────╯ Maximum amount of gas passed on to token `transfer` call + address priceRegistry; // Price registry address } /// @notice RateLimitToken struct containing both the source and destination token addresses @@ -625,7 +623,8 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio // contains a contract. If it doesn't it reverts with a known error, which we catch gracefully. // We call the pool with exact gas to increase resistance against malicious tokens or token pools. // We protects against return data bombs by capping the return data size at MAX_RET_BYTES. - (bool success, bytes memory returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( + (bool success, bytes memory returnData, uint256 gasUsedReleaseOrMint) = CallWithExactGas + ._callWithExactGasSafeReturnData( abi.encodeCall( IPoolV1.releaseOrMint, Pool.ReleaseOrMintInV1({ @@ -640,7 +639,7 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio }) ), localPoolAddress, - s_dynamicConfig.maxPoolReleaseOrMintGas, + sourceTokenData.destGasAmount, Internal.GAS_FOR_CALL_EXACT_CHECK, Internal.MAX_RET_BYTES ); @@ -659,7 +658,7 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio (success, returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( abi.encodeCall(IERC20.transfer, (receiver, localAmount)), localToken, - s_dynamicConfig.maxTokenTransferGas, + sourceTokenData.destGasAmount - gasUsedReleaseOrMint, Internal.GAS_FOR_CALL_EXACT_CHECK, Internal.MAX_RET_BYTES ); diff --git a/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol b/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol index 0e978596e4..45dfdacd30 100644 --- a/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol @@ -96,8 +96,6 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, // The following three properties are defaults, they can be overridden by setting the TokenTransferFeeConfig for a token uint16 defaultTokenFeeUSDCents; // ──────────╮ Default token fee charged per token transfer uint32 defaultTokenDestGasOverhead; // │ Default gas charged to execute the token transfer on the destination chain - // │ Default data availability bytes that are returned from the source pool and sent - uint32 defaultTokenDestBytesOverhead; // | to the destination pool. Must be >= Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES bool enforceOutOfOrder; // ──────────────────╯ Whether to enforce the allowOutOfOrderExecution extraArg value to be true. } @@ -304,11 +302,15 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, } if (s_nopFeesJuels > i_maxNopFeesJuels) revert MaxFeeBalanceReached(); - if (i_prevOnRamp != address(0)) { - if (s_senderNonce[originalSender] == 0) { - // If this is first time send for a sender in new OnRamp, check if they have a nonce - // from the previous OnRamp and start from there instead of zero. - s_senderNonce[originalSender] = IEVM2AnyOnRamp(i_prevOnRamp).getSenderNonce(originalSender); + // Get the current nonce if the message is an ordered message. If it's not ordered, we don't have to make the + // external call. + if (!extraArgs.allowOutOfOrderExecution) { + if (i_prevOnRamp != address(0)) { + if (s_senderNonce[originalSender] == 0) { + // If this is first time send for a sender in new OnRamp, check if they have a nonce + // from the previous OnRamp and start from there instead of zero. + s_senderNonce[originalSender] = IEVM2AnyOnRamp(i_prevOnRamp).getSenderNonce(originalSender); + } } } @@ -359,10 +361,14 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, // extraData. This prevents gas bomb attacks on the NOPs. As destBytesOverhead accounts for both // extraData and offchainData, this caps the worst case abuse to the number of bytes reserved for offchainData. if (poolReturnData.destPoolData.length > Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) { + // If TokenTransferFeeConfig.enabled is false, there is no config. That means destBytesOverhead is zero and + // this check is always true. That ensures that a pool without config cannot send more than + // Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES bytes of data. if (poolReturnData.destPoolData.length > s_tokenTransferFeeConfig[tokenAndAmount.token].destBytesOverhead) { revert SourceTokenDataTooLarge(tokenAndAmount.token); } } + // We validate the token address to ensure it is a valid EVM address Internal._validateEVMAddress(poolReturnData.destTokenAddress); @@ -370,7 +376,12 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, Internal.SourceTokenData({ sourcePoolAddress: abi.encode(sourcePool), destTokenAddress: poolReturnData.destTokenAddress, - extraData: poolReturnData.destPoolData + extraData: poolReturnData.destPoolData, + // The user will be billed either the default or the override, so we send the exact amount that we billed for + // to the destination chain to be used for the token releaseOrMint and transfer. + destGasAmount: s_tokenTransferFeeConfig[tokenAndAmount.token].isEnabled + ? s_tokenTransferFeeConfig[tokenAndAmount.token].destGasOverhead + : s_dynamicConfig.defaultTokenDestGasOverhead }) ); } @@ -464,10 +475,6 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, function _setDynamicConfig(DynamicConfig memory dynamicConfig) internal { // We permit router to be set to zero as a way to pause the contract. if (dynamicConfig.priceRegistry == address(0)) revert InvalidConfig(); - if (dynamicConfig.defaultTokenDestBytesOverhead < Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) { - revert InvalidDestBytesOverhead(address(0), dynamicConfig.defaultTokenDestBytesOverhead); - } - s_dynamicConfig = dynamicConfig; emit ConfigSet( @@ -635,7 +642,7 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, if (!transferFeeConfig.isEnabled) { tokenTransferFeeUSDWei += uint256(s_dynamicConfig.defaultTokenFeeUSDCents) * 1e16; tokenTransferGas += s_dynamicConfig.defaultTokenDestGasOverhead; - tokenTransferBytesOverhead += s_dynamicConfig.defaultTokenDestBytesOverhead; + tokenTransferBytesOverhead += Pool.CCIP_POOL_V1_RET_BYTES; continue; } diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol index 5716777fb5..db168f994d 100644 --- a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol @@ -5,7 +5,6 @@ import {ILiquidityContainer} from "../../liquiditymanager/interfaces/ILiquidityC import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; import {Pool} from "../libraries/Pool.sol"; -import {RateLimiter} from "../libraries/RateLimiter.sol"; import {TokenPool} from "./TokenPool.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; @@ -20,20 +19,18 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion error InsufficientLiquidity(); error LiquidityNotAccepted(); - error Unauthorized(address caller); + + event LiquidityTransferred(address indexed from, uint256 amount); string public constant override typeAndVersion = "LockReleaseTokenPool 1.5.0-dev"; /// @dev Whether or not the pool accepts liquidity. /// External liquidity is not required when there is one canonical token deployed to a chain, /// and CCIP is facilitating mint/burn on all the other chains, in which case the invariant - /// balanceOf(pool) on home chain == sum(totalSupply(mint/burn "wrapped" token) on all remote chains) should always hold + /// balanceOf(pool) on home chain >= sum(totalSupply(mint/burn "wrapped" token) on all remote chains) should always hold bool internal immutable i_acceptLiquidity; /// @notice The address of the rebalancer. address internal s_rebalancer; - /// @notice The address of the rate limiter admin. - /// @dev Can be address(0) if none is configured. - address internal s_rateLimitAdmin; constructor( IERC20 token, @@ -95,18 +92,6 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion s_rebalancer = rebalancer; } - /// @notice Sets the rate limiter admin address. - /// @dev Only callable by the owner. - /// @param rateLimitAdmin The new rate limiter admin address. - function setRateLimitAdmin(address rateLimitAdmin) external onlyOwner { - s_rateLimitAdmin = rateLimitAdmin; - } - - /// @notice Gets the rate limiter admin address. - function getRateLimitAdmin() external view returns (address) { - return s_rateLimitAdmin; - } - /// @notice Checks if the pool can accept liquidity. /// @return true if the pool can accept liquidity, false otherwise. function canAcceptLiquidity() external view returns (bool) { @@ -133,19 +118,20 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion emit LiquidityRemoved(msg.sender, amount); } - /// @notice Sets the rate limiter admin address. - /// @dev Only callable by the owner or the rate limiter admin. NOTE: overwrites the normal - /// onlyAdmin check in the base implementation to also allow the rate limiter admin. - /// @param remoteChainSelector The remote chain selector for which the rate limits apply. - /// @param outboundConfig The new outbound rate limiter config. - /// @param inboundConfig The new inbound rate limiter config. - function setChainRateLimiterConfig( - uint64 remoteChainSelector, - RateLimiter.Config memory outboundConfig, - RateLimiter.Config memory inboundConfig - ) external override { - if (msg.sender != s_rateLimitAdmin && msg.sender != owner()) revert Unauthorized(msg.sender); - - _setRateLimitConfig(remoteChainSelector, outboundConfig, inboundConfig); + /// @notice This function can be used to transfer liquidity from an older version of the pool to this pool. To do so + /// this pool will have to be set as the rebalancer in the older version of the pool. This allows it to transfer the + /// funds in the old pool to the new pool. + /// @dev When upgrading a LockRelease pool, this function can be called at the same time as the pool is changed in the + /// TokenAdminRegistry. This allows for a smooth transition of both liquidity and transactions to the new pool. + /// Alternatively, when no multicall is available, a portion of the funds can be transferred to the new pool before + /// changing which pool CCIP uses, to ensure both pools can operate. Then the pool should be changed in the + /// TokenAdminRegistry, which will activate the new pool. All new transactions will use the new pool and its + /// liquidity. Finally, the remaining liquidity can be transferred to the new pool using this function one more time. + /// @param from The address of the old pool. + /// @param amount The amount of liquidity to transfer. + function transferLiquidity(address from, uint256 amount) external onlyOwner { + LockReleaseTokenPool(from).withdrawLiquidity(amount); + + emit LiquidityTransferred(from, amount); } } diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol index 91766d5f26..dcd78ee969 100644 --- a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol @@ -5,7 +5,6 @@ import {ILiquidityContainer} from "../../liquiditymanager/interfaces/ILiquidityC import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; import {Pool} from "../libraries/Pool.sol"; -import {RateLimiter} from "../libraries/RateLimiter.sol"; import {LegacyPoolWrapper} from "./LegacyPoolWrapper.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; @@ -20,20 +19,16 @@ contract LockReleaseTokenPoolAndProxy is LegacyPoolWrapper, ILiquidityContainer, error InsufficientLiquidity(); error LiquidityNotAccepted(); - error Unauthorized(address caller); string public constant override typeAndVersion = "LockReleaseTokenPoolAndProxy 1.5.0-dev"; /// @dev Whether or not the pool accepts liquidity. /// External liquidity is not required when there is one canonical token deployed to a chain, /// and CCIP is facilitating mint/burn on all the other chains, in which case the invariant - /// balanceOf(pool) on home chain == sum(totalSupply(mint/burn "wrapped" token) on all remote chains) should always hold + /// balanceOf(pool) on home chain >= sum(totalSupply(mint/burn "wrapped" token) on all remote chains) should always hold bool internal immutable i_acceptLiquidity; /// @notice The address of the rebalancer. address internal s_rebalancer; - /// @notice The address of the rate limiter admin. - /// @dev Can be address(0) if none is configured. - address internal s_rateLimitAdmin; constructor( IERC20 token, @@ -103,18 +98,6 @@ contract LockReleaseTokenPoolAndProxy is LegacyPoolWrapper, ILiquidityContainer, s_rebalancer = rebalancer; } - /// @notice Sets the rate limiter admin address. - /// @dev Only callable by the owner. - /// @param rateLimitAdmin The new rate limiter admin address. - function setRateLimitAdmin(address rateLimitAdmin) external onlyOwner { - s_rateLimitAdmin = rateLimitAdmin; - } - - /// @notice Gets the rate limiter admin address. - function getRateLimitAdmin() external view returns (address) { - return s_rateLimitAdmin; - } - /// @notice Checks if the pool can accept liquidity. /// @return true if the pool can accept liquidity, false otherwise. function canAcceptLiquidity() external view returns (bool) { @@ -141,19 +124,18 @@ contract LockReleaseTokenPoolAndProxy is LegacyPoolWrapper, ILiquidityContainer, emit LiquidityRemoved(msg.sender, amount); } - /// @notice Sets the rate limiter admin address. - /// @dev Only callable by the owner or the rate limiter admin. NOTE: overwrites the normal - /// onlyAdmin check in the base implementation to also allow the rate limiter admin. - /// @param remoteChainSelector The remote chain selector for which the rate limits apply. - /// @param outboundConfig The new outbound rate limiter config. - /// @param inboundConfig The new inbound rate limiter config. - function setChainRateLimiterConfig( - uint64 remoteChainSelector, - RateLimiter.Config memory outboundConfig, - RateLimiter.Config memory inboundConfig - ) external override { - if (msg.sender != s_rateLimitAdmin && msg.sender != owner()) revert Unauthorized(msg.sender); - - _setRateLimitConfig(remoteChainSelector, outboundConfig, inboundConfig); + /// @notice This function can be used to transfer liquidity from an older version of the pool to this pool. To do so + /// this pool will have to be set as the rebalancer in the older version of the pool. This allows it to transfer the + /// funds in the old pool to the new pool. + /// @dev When upgrading a LockRelease pool, this function can be called at the same time as the pool is changed in the + /// TokenAdminRegistry. This allows for a smooth transition of both liquidity and transactions to the new pool. + /// Alternatively, when no multicall is available, a portion of the funds can be transferred to the new pool before + /// changing which pool CCIP uses, to ensure both pools can operate. Then the pool should be changed in the + /// TokenAdminRegistry, which will activate the new pool. All new transactions will use the new pool and its + /// liquidity. Finally, the remaining liquidity can be transferred to the new pool using this function one more time. + /// @param from The address of the old pool. + /// @param amount The amount of liquidity to transfer. + function transferLiquidity(address from, uint256 amount) external onlyOwner { + LockReleaseTokenPoolAndProxy(from).withdrawLiquidity(amount); } } diff --git a/contracts/src/v0.8/ccip/pools/TokenPool.sol b/contracts/src/v0.8/ccip/pools/TokenPool.sol index fb1f8c49e6..c0c6f2198d 100644 --- a/contracts/src/v0.8/ccip/pools/TokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/TokenPool.sol @@ -31,6 +31,7 @@ abstract contract TokenPool is IPoolV1, OwnerIsCreator { error ChainAlreadyExists(uint64 chainSelector); error InvalidSourcePoolAddress(bytes sourcePoolAddress); error InvalidToken(address token); + error Unauthorized(address caller); event Locked(address indexed sender, uint256 amount); event Burned(address indexed sender, uint256 amount); @@ -87,6 +88,9 @@ abstract contract TokenPool is IPoolV1, OwnerIsCreator { /// @dev The chain selectors are in uint256 format because of the EnumerableSet implementation. EnumerableSet.UintSet internal s_remoteChainSelectors; mapping(uint64 remoteChainSelector => RemoteChainConfig) internal s_remoteChainConfigs; + /// @notice The address of the rate limiter admin. + /// @dev Can be address(0) if none is configured. + address internal s_rateLimitAdmin; constructor(IERC20 token, address[] memory allowlist, address rmnProxy, address router) { if (address(token) == address(0) || router == address(0) || rmnProxy == address(0)) revert ZeroAddressNotAllowed(); @@ -169,7 +173,7 @@ abstract contract TokenPool is IPoolV1, OwnerIsCreator { /// - if the source pool is valid /// - rate limit status /// @param releaseOrMintIn The input to validate. - /// @dev This function should always be called before executing a lock or burn. Not doing so would allow + /// @dev This function should always be called before executing a release or mint. Not doing so would allow /// for various exploits. function _validateReleaseOrMint(Pool.ReleaseOrMintInV1 memory releaseOrMintIn) internal { if (!isSupportedToken(releaseOrMintIn.localToken)) revert InvalidToken(releaseOrMintIn.localToken); @@ -297,6 +301,18 @@ abstract contract TokenPool is IPoolV1, OwnerIsCreator { // │ Rate limiting │ // ================================================================ + /// @notice Sets the rate limiter admin address. + /// @dev Only callable by the owner. + /// @param rateLimitAdmin The new rate limiter admin address. + function setRateLimitAdmin(address rateLimitAdmin) external onlyOwner { + s_rateLimitAdmin = rateLimitAdmin; + } + + /// @notice Gets the rate limiter admin address. + function getRateLimitAdmin() external view returns (address) { + return s_rateLimitAdmin; + } + /// @notice Consumes outbound rate limiting capacity in this pool function _consumeOutboundRateLimit(uint64 remoteChainSelector, uint256 amount) internal { s_remoteChainConfigs[remoteChainSelector].outboundRateLimiterConfig._consume(amount, address(i_token)); @@ -335,7 +351,9 @@ abstract contract TokenPool is IPoolV1, OwnerIsCreator { uint64 remoteChainSelector, RateLimiter.Config memory outboundConfig, RateLimiter.Config memory inboundConfig - ) external virtual onlyOwner { + ) external { + if (msg.sender != s_rateLimitAdmin && msg.sender != owner()) revert Unauthorized(msg.sender); + _setRateLimitConfig(remoteChainSelector, outboundConfig, inboundConfig); } diff --git a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol index 339ed09992..adaf946b1e 100644 --- a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol @@ -94,8 +94,6 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { } /// @notice Burn the token in the pool - /// @dev Burn is not rate limited at per-pool level. Burn does not contribute to honey pot risk. - /// Benefits of rate limiting here does not justify the extra gas cost. /// @dev emits ITokenMessenger.DepositForBurn /// @dev Assumes caller has validated destinationReceiver function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) @@ -108,9 +106,6 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { Domain memory domain = s_chainToDomain[lockOrBurnIn.remoteChainSelector]; if (!domain.enabled) revert UnknownDomain(lockOrBurnIn.remoteChainSelector); - if (lockOrBurnIn.receiver.length != 32) { - revert InvalidReceiver(lockOrBurnIn.receiver); - } // Since this pool is the msg sender of the CCTP transaction, only this contract // is able to call replaceDepositForBurn. Since this contract does not implement diff --git a/contracts/src/v0.8/ccip/test/BaseTest.t.sol b/contracts/src/v0.8/ccip/test/BaseTest.t.sol index ee3f3e6fd4..498b1c5731 100644 --- a/contracts/src/v0.8/ccip/test/BaseTest.t.sol +++ b/contracts/src/v0.8/ccip/test/BaseTest.t.sol @@ -38,8 +38,8 @@ contract BaseTest is Test { uint16 internal constant DEST_GAS_PER_PAYLOAD_BYTE = 16; uint16 internal constant DEFAULT_TOKEN_FEE_USD_CENTS = 50; - uint32 internal constant DEFAULT_TOKEN_DEST_GAS_OVERHEAD = 34_000; - uint32 internal constant DEFAULT_TOKEN_BYTES_OVERHEAD = 50; + uint32 internal constant DEFAULT_TOKEN_DEST_GAS_OVERHEAD = 110_000; + uint32 internal constant DEFAULT_TOKEN_BYTES_OVERHEAD = 32; bool private s_baseTestInitialized; diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol index 75de4db8c5..92ea1f221d 100644 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -230,7 +230,6 @@ contract NonceManager_OnRampUpgrade is EVM2EVMMultiOnRampSetup { maxPerMsgGasLimit: MAX_GAS_LIMIT, defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, - defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, enforceOutOfOrder: false }), RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e15}), diff --git a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol index 292ac9a3bf..927c7e1f03 100644 --- a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol +++ b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol @@ -585,7 +585,7 @@ contract LockReleaseTokenPoolPoolAndProxy_provideLiquidity is LockReleaseTokenPo function test_Unauthorized_Revert() public { vm.startPrank(STRANGER); - vm.expectRevert(abi.encodeWithSelector(LockReleaseTokenPoolAndProxy.Unauthorized.selector, STRANGER)); + vm.expectRevert(abi.encodeWithSelector(TokenPool.Unauthorized.selector, STRANGER)); s_lockReleaseTokenPoolAndProxy.provideLiquidity(1); } @@ -620,7 +620,7 @@ contract LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity is LockReleaseToke function test_Unauthorized_Revert() public { vm.startPrank(STRANGER); - vm.expectRevert(abi.encodeWithSelector(LockReleaseTokenPoolAndProxy.Unauthorized.selector, STRANGER)); + vm.expectRevert(abi.encodeWithSelector(TokenPool.Unauthorized.selector, STRANGER)); s_lockReleaseTokenPoolAndProxy.withdrawLiquidity(1); } @@ -645,127 +645,3 @@ contract LockReleaseTokenPoolPoolAndProxy_supportsInterface is LockReleaseTokenP assertTrue(s_lockReleaseTokenPoolAndProxy.supportsInterface(type(IERC165).interfaceId)); } } - -contract LockReleaseTokenPoolPoolAndProxy_setChainRateLimiterConfig is LockReleaseTokenPoolAndProxySetup { - event ConfigChanged(RateLimiter.Config); - event ChainConfigured( - uint64 chainSelector, RateLimiter.Config outboundRateLimiterConfig, RateLimiter.Config inboundRateLimiterConfig - ); - - uint64 internal s_remoteChainSelector; - - function setUp() public virtual override { - LockReleaseTokenPoolAndProxySetup.setUp(); - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); - s_remoteChainSelector = 123124; - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: s_remoteChainSelector, - remotePoolAddress: abi.encode(address(1)), - remoteTokenAddress: abi.encode(address(2)), - allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() - }); - s_lockReleaseTokenPoolAndProxy.applyChainUpdates(chainUpdates); - } - - function test_Fuzz_SetChainRateLimiterConfig_Success(uint128 capacity, uint128 rate, uint32 newTime) public { - // Cap the lower bound to 4 so 4/2 is still >= 2 - vm.assume(capacity >= 4); - // Cap the lower bound to 2 so 2/2 is still >= 1 - rate = uint128(bound(rate, 2, capacity - 2)); - // Bucket updates only work on increasing time - newTime = uint32(bound(newTime, block.timestamp + 1, type(uint32).max)); - vm.warp(newTime); - - uint256 oldOutboundTokens = - s_lockReleaseTokenPoolAndProxy.getCurrentOutboundRateLimiterState(s_remoteChainSelector).tokens; - uint256 oldInboundTokens = - s_lockReleaseTokenPoolAndProxy.getCurrentInboundRateLimiterState(s_remoteChainSelector).tokens; - - RateLimiter.Config memory newOutboundConfig = RateLimiter.Config({isEnabled: true, capacity: capacity, rate: rate}); - RateLimiter.Config memory newInboundConfig = - RateLimiter.Config({isEnabled: true, capacity: capacity / 2, rate: rate / 2}); - - vm.expectEmit(); - emit ConfigChanged(newOutboundConfig); - vm.expectEmit(); - emit ConfigChanged(newInboundConfig); - vm.expectEmit(); - emit ChainConfigured(s_remoteChainSelector, newOutboundConfig, newInboundConfig); - - s_lockReleaseTokenPoolAndProxy.setChainRateLimiterConfig(s_remoteChainSelector, newOutboundConfig, newInboundConfig); - - uint256 expectedTokens = RateLimiter._min(newOutboundConfig.capacity, oldOutboundTokens); - - RateLimiter.TokenBucket memory bucket = - s_lockReleaseTokenPoolAndProxy.getCurrentOutboundRateLimiterState(s_remoteChainSelector); - assertEq(bucket.capacity, newOutboundConfig.capacity); - assertEq(bucket.rate, newOutboundConfig.rate); - assertEq(bucket.tokens, expectedTokens); - assertEq(bucket.lastUpdated, newTime); - - expectedTokens = RateLimiter._min(newInboundConfig.capacity, oldInboundTokens); - - bucket = s_lockReleaseTokenPoolAndProxy.getCurrentInboundRateLimiterState(s_remoteChainSelector); - assertEq(bucket.capacity, newInboundConfig.capacity); - assertEq(bucket.rate, newInboundConfig.rate); - assertEq(bucket.tokens, expectedTokens); - assertEq(bucket.lastUpdated, newTime); - } - - function test_OnlyOwnerOrRateLimitAdmin_Revert() public { - address rateLimiterAdmin = address(28973509103597907); - - s_lockReleaseTokenPoolAndProxy.setRateLimitAdmin(rateLimiterAdmin); - - vm.startPrank(rateLimiterAdmin); - - s_lockReleaseTokenPoolAndProxy.setChainRateLimiterConfig( - s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() - ); - - vm.startPrank(OWNER); - - s_lockReleaseTokenPoolAndProxy.setChainRateLimiterConfig( - s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() - ); - } - - // Reverts - - function test_OnlyOwner_Revert() public { - vm.startPrank(STRANGER); - - vm.expectRevert(abi.encodeWithSelector(LockReleaseTokenPoolAndProxy.Unauthorized.selector, STRANGER)); - s_lockReleaseTokenPoolAndProxy.setChainRateLimiterConfig( - s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() - ); - } - - function test_NonExistentChain_Revert() public { - uint64 wrongChainSelector = 9084102894; - - vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, wrongChainSelector)); - s_lockReleaseTokenPoolAndProxy.setChainRateLimiterConfig( - wrongChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() - ); - } -} - -contract LockReleaseTokenPoolAndProxy_setRateLimitAdmin is LockReleaseTokenPoolAndProxySetup { - function test_SetRateLimitAdmin_Success() public { - assertEq(address(0), s_lockReleaseTokenPoolAndProxy.getRateLimitAdmin()); - s_lockReleaseTokenPoolAndProxy.setRateLimitAdmin(OWNER); - assertEq(OWNER, s_lockReleaseTokenPoolAndProxy.getRateLimitAdmin()); - } - - // Reverts - - function test_SetRateLimitAdmin_Revert() public { - vm.startPrank(STRANGER); - - vm.expectRevert("Only callable by owner"); - s_lockReleaseTokenPoolAndProxy.setRateLimitAdmin(STRANGER); - } -} diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol index 507e966a70..ffd40d9de9 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol @@ -222,9 +222,7 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba router: router, priceRegistry: priceRegistry, maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, - maxDataBytes: MAX_DATA_SIZE, - maxPoolReleaseOrMintGas: MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS, - maxTokenTransferGas: MAX_TOKEN_POOL_TRANSFER_GAS + maxDataBytes: MAX_DATA_SIZE }); } @@ -400,8 +398,6 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba ) public pure { assertEq(a.permissionLessExecutionThresholdSeconds, b.permissionLessExecutionThresholdSeconds); assertEq(a.router, b.router); - assertEq(a.maxPoolReleaseOrMintGas, b.maxPoolReleaseOrMintGas); - assertEq(a.maxTokenTransferGas, b.maxTokenTransferGas); assertEq(a.messageValidator, b.messageValidator); assertEq(a.priceRegistry, b.priceRegistry); } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol index e94184e3c5..4f2b219e69 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol @@ -590,7 +590,8 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { Internal.SourceTokenData({ sourcePoolAddress: abi.encode(fakePoolAddress), destTokenAddress: abi.encode(s_destTokenBySourceToken[messages[0].tokenAmounts[0].token]), - extraData: "" + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }) ); @@ -1218,7 +1219,8 @@ contract EVM2EVMOffRamp_manuallyExecute is EVM2EVMOffRampSetup { Internal.SourceTokenData({ sourcePoolAddress: abi.encode(s_sourcePoolByToken[s_sourceFeeToken]), destTokenAddress: abi.encode(s_destTokenBySourceToken[s_sourceFeeToken]), - extraData: "" + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }) ); @@ -1403,7 +1405,8 @@ contract EVM2EVMOffRamp__trialExecute is EVM2EVMOffRampSetup { Internal.SourceTokenData({ sourcePoolAddress: abi.encode(address(0)), destTokenAddress: abi.encode(address(0)), - extraData: "" + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }) ); @@ -1426,7 +1429,8 @@ contract EVM2EVMOffRamp__trialExecute is EVM2EVMOffRampSetup { Internal.SourceTokenData({ sourcePoolAddress: abi.encode(address(0)), destTokenAddress: abi.encode(notAContract), - extraData: "" + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }) ); @@ -1457,7 +1461,8 @@ contract EVM2EVMOffRamp__releaseOrMintToken is EVM2EVMOffRampSetup { Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), - extraData: "" + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }); vm.expectCall( @@ -1493,7 +1498,8 @@ contract EVM2EVMOffRamp__releaseOrMintToken is EVM2EVMOffRampSetup { Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), destTokenAddress: abi.encode(destToken), - extraData: "" + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }); // Address(0) should always revert @@ -1534,7 +1540,8 @@ contract EVM2EVMOffRamp__releaseOrMintToken is EVM2EVMOffRampSetup { Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), destTokenAddress: abi.encode(destToken), - extraData: "" + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }); bytes memory revertData = "call reverted :o"; @@ -1728,7 +1735,8 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { Internal.SourceTokenData({ sourcePoolAddress: abi.encode(s_sourcePoolByToken[srcTokenAmounts[0].token]), destTokenAddress: wrongAddress, - extraData: "" + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }) ); @@ -1775,7 +1783,8 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { Internal.SourceTokenData({ sourcePoolAddress: abi.encode(fakePoolAddress), destTokenAddress: abi.encode(fakePoolAddress), - extraData: "" + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }) ); @@ -1818,7 +1827,8 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { Internal.SourceTokenData({ sourcePoolAddress: unusedVar, destTokenAddress: abi.encode(destPool), - extraData: unusedVar + extraData: unusedVar, + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }) ); diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol index 053869b88a..b67adbf37e 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol @@ -90,9 +90,7 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { router: router, priceRegistry: priceRegistry, maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, - maxDataBytes: MAX_DATA_SIZE, - maxPoolReleaseOrMintGas: MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS, - maxTokenTransferGas: MAX_TOKEN_POOL_TRANSFER_GAS + maxDataBytes: MAX_DATA_SIZE }); } @@ -170,7 +168,8 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { Internal.SourceTokenData({ sourcePoolAddress: abi.encode(s_sourcePoolByToken[tokenAmounts[i].token]), destTokenAddress: abi.encode(s_destTokenBySourceToken[tokenAmounts[i].token]), - extraData: "" + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }) ); } @@ -240,8 +239,6 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { assertEq(a.priceRegistry, b.priceRegistry); assertEq(a.maxNumberOfTokensPerMsg, b.maxNumberOfTokensPerMsg); assertEq(a.maxDataBytes, b.maxDataBytes); - assertEq(a.maxPoolReleaseOrMintGas, b.maxPoolReleaseOrMintGas); - assertEq(a.maxTokenTransferGas, b.maxTokenTransferGas); } function _getDefaultSourceTokenData(Client.EVMTokenAmount[] memory srcTokenAmounts) @@ -255,7 +252,8 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { Internal.SourceTokenData({ sourcePoolAddress: abi.encode(s_sourcePoolByToken[srcTokenAmounts[i].token]), destTokenAddress: abi.encode(s_destTokenBySourceToken[srcTokenAmounts[i].token]), - extraData: "" + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }) ); } diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol index 197a87b708..a30ecc9130 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol @@ -339,7 +339,6 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { maxPerMsgGasLimit: dynamicConfig.maxPerMsgGasLimit, defaultTokenFeeUSDCents: dynamicConfig.defaultTokenFeeUSDCents, defaultTokenDestGasOverhead: dynamicConfig.defaultTokenDestGasOverhead, - defaultTokenDestBytesOverhead: dynamicConfig.defaultTokenDestBytesOverhead, enforceOutOfOrder: enforce }) ); @@ -522,6 +521,68 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); } + function test_forwardFromRouter_correctSourceTokenData_Success() public { + Client.EVM2AnyMessage memory message = _generateTokenMessage(); + + for (uint256 i = 0; i < message.tokenAmounts.length; ++i) { + address token = message.tokenAmounts[i].token; + deal(token, s_sourcePoolByToken[token], message.tokenAmounts[i].amount * 2); + } + + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount * 2); + + Internal.EVM2EVMMessage memory expectedEvent = _messageToEvent(message, 1, 1, feeAmount, OWNER); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(expectedEvent); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + + // Same message, but we change the onchain config which should be reflected in the event. + // We get the event before changing the onRamp config, as the event generation code uses the current + // onramp to generate the event. This test checks if it does so correctly. + expectedEvent = _messageToEvent(message, 2, 2, feeAmount, OWNER); + + uint256 tokenIndexToChange = 1; + address changedToken = message.tokenAmounts[tokenIndexToChange].token; + + // Set token config to change the destGasOverhead + vm.startPrank(OWNER); + EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + new EVM2EVMOnRamp.TokenTransferFeeConfigArgs[](1); + tokenTransferFeeConfigArgs[0] = EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ + token: changedToken, + minFeeUSDCents: 0, + maxFeeUSDCents: 100, + deciBps: 0, + destGasOverhead: 1_000_111, + destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) + 32, + aggregateRateLimitEnabled: false + }); + s_onRamp.setTokenTransferFeeConfig(tokenTransferFeeConfigArgs, new address[](0)); + + vm.startPrank(address(s_sourceRouter)); + + expectedEvent.sourceTokenData[tokenIndexToChange] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[changedToken]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[changedToken]), + extraData: "", + // The user will be billed either the default or the override, so we send the exact amount that we billed for + // to the destination chain to be used for the token releaseOrMint and transfer. + destGasAmount: tokenTransferFeeConfigArgs[0].destGasOverhead + }) + ); + // Update the hash because we manually changed sourceTokenData + expectedEvent.messageId = Internal._hash(expectedEvent, s_metadataHash); + + vm.expectEmit(); + emit EVM2EVMOnRamp.CCIPSendRequested(expectedEvent); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + // Reverts function test_Paused_Revert() public { @@ -806,7 +867,6 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { maxPerMsgGasLimit: dynamicConfig.maxPerMsgGasLimit, defaultTokenFeeUSDCents: dynamicConfig.defaultTokenFeeUSDCents, defaultTokenDestGasOverhead: dynamicConfig.defaultTokenDestGasOverhead, - defaultTokenDestBytesOverhead: dynamicConfig.defaultTokenDestBytesOverhead, enforceOutOfOrder: true }) ); @@ -1155,32 +1215,6 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { assertEq(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, destBytesOverhead); } - function test_WETHTokenBpsFee_Success() public view { - uint256 tokenAmount = 100e18; - - Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ - receiver: abi.encode(OWNER), - data: "", - tokenAmounts: new Client.EVMTokenAmount[](1), - feeToken: s_sourceRouter.getWrappedNative(), - extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) - }); - message.tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceRouter.getWrappedNative(), amount: tokenAmount}); - - EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = - s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[0].token); - - (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = - s_onRamp.getTokenTransferCost(message.feeToken, s_wrappedTokenPrice, message.tokenAmounts); - - uint256 usdWei = calcUSDValueFromTokenAmount(s_wrappedTokenPrice, tokenAmount); - uint256 bpsUSDWei = applyBpsRatio(usdWei, s_tokenTransferFeeConfigArgs[1].deciBps); - - assertEq(bpsUSDWei, feeUSDWei); - assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); - assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); - } - function test_CustomTokenBpsFee_Success() public view { uint256 tokenAmount = 200000e18; @@ -1200,7 +1234,7 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts); uint256 usdWei = calcUSDValueFromTokenAmount(s_customTokenPrice, tokenAmount); - uint256 bpsUSDWei = applyBpsRatio(usdWei, s_tokenTransferFeeConfigArgs[2].deciBps); + uint256 bpsUSDWei = applyBpsRatio(usdWei, s_tokenTransferFeeConfigArgs[1].deciBps); assertEq(bpsUSDWei, feeUSDWei); assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); @@ -1280,51 +1314,57 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { // Start with small token transfers, total bps fee is lower than min token transfer fee for (uint256 i = 0; i < testTokens.length; ++i) { message.tokenAmounts[i] = Client.EVMTokenAmount({token: testTokens[i], amount: 1e14}); - expectedTotalGas += s_onRamp.getTokenTransferFeeConfig(testTokens[i]).destGasOverhead; - uint32 dstBytesOverhead = s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[i].token).destBytesOverhead; - expectedTotalBytes += dstBytesOverhead == 0 ? uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) : dstBytesOverhead; + EVM2EVMOnRamp.TokenTransferFeeConfig memory tokenTransferFeeConfig = + s_onRamp.getTokenTransferFeeConfig(testTokens[i]); + expectedTotalGas += tokenTransferFeeConfig.destGasOverhead == 0 + ? DEFAULT_TOKEN_DEST_GAS_OVERHEAD + : tokenTransferFeeConfig.destGasOverhead; + expectedTotalBytes += tokenTransferFeeConfig.destBytesOverhead == 0 + ? uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) + : tokenTransferFeeConfig.destBytesOverhead; } (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = s_onRamp.getTokenTransferCost(message.feeToken, s_wrappedTokenPrice, message.tokenAmounts); uint256 expectedFeeUSDWei = 0; for (uint256 i = 0; i < testTokens.length; ++i) { - expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[i].minFeeUSDCents); + expectedFeeUSDWei += configUSDCentToWei( + tokenTransferFeeConfigs[i].minFeeUSDCents == 0 + ? DEFAULT_TOKEN_FEE_USD_CENTS + : tokenTransferFeeConfigs[i].minFeeUSDCents + ); } - assertEq(expectedFeeUSDWei, feeUSDWei); - assertEq(expectedTotalGas, destGasOverhead); - assertEq(expectedTotalBytes, destBytesOverhead); + assertEq(expectedFeeUSDWei, feeUSDWei, "wrong feeUSDWei 1"); + assertEq(expectedTotalGas, destGasOverhead, "wrong destGasOverhead 1"); + assertEq(expectedTotalBytes, destBytesOverhead, "wrong destBytesOverhead 1"); // Set 1st token transfer to a meaningful amount so its bps fee is now between min and max fee message.tokenAmounts[0] = Client.EVMTokenAmount({token: testTokens[0], amount: 10000e18}); - (feeUSDWei, destGasOverhead, destBytesOverhead) = - s_onRamp.getTokenTransferCost(message.feeToken, s_wrappedTokenPrice, message.tokenAmounts); - expectedFeeUSDWei = applyBpsRatio( + uint256 token0USDWei = applyBpsRatio( calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), tokenTransferFeeConfigs[0].deciBps ); - expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[1].minFeeUSDCents); - expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); + uint256 token1USDWei = configUSDCentToWei(DEFAULT_TOKEN_FEE_USD_CENTS); + + (feeUSDWei, destGasOverhead, destBytesOverhead) = + s_onRamp.getTokenTransferCost(message.feeToken, s_wrappedTokenPrice, message.tokenAmounts); + expectedFeeUSDWei = token0USDWei + token1USDWei + configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); - assertEq(expectedFeeUSDWei, feeUSDWei); - assertEq(expectedTotalGas, destGasOverhead); - assertEq(expectedTotalBytes, destBytesOverhead); + assertEq(expectedFeeUSDWei, feeUSDWei, "wrong feeUSDWei 2"); + assertEq(expectedTotalGas, destGasOverhead, "wrong destGasOverhead 2"); + assertEq(expectedTotalBytes, destBytesOverhead, "wrong destBytesOverhead 2"); // Set 2nd token transfer to a large amount that is higher than maxFeeUSD - message.tokenAmounts[1] = Client.EVMTokenAmount({token: testTokens[1], amount: 1e36}); + message.tokenAmounts[2] = Client.EVMTokenAmount({token: testTokens[2], amount: 1e36}); (feeUSDWei, destGasOverhead, destBytesOverhead) = s_onRamp.getTokenTransferCost(message.feeToken, s_wrappedTokenPrice, message.tokenAmounts); - expectedFeeUSDWei = applyBpsRatio( - calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), tokenTransferFeeConfigs[0].deciBps - ); - expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[1].maxFeeUSDCents); - expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); + expectedFeeUSDWei = token0USDWei + token1USDWei + configUSDCentToWei(tokenTransferFeeConfigs[2].maxFeeUSDCents); - assertEq(expectedFeeUSDWei, feeUSDWei); - assertEq(expectedTotalGas, destGasOverhead); - assertEq(expectedTotalBytes, destBytesOverhead); + assertEq(expectedFeeUSDWei, feeUSDWei, "wrong feeUSDWei 3"); + assertEq(expectedTotalGas, destGasOverhead, "wrong destGasOverhead 3"); + assertEq(expectedTotalBytes, destBytesOverhead, "wrong destBytesOverhead 3"); } // reverts @@ -1926,7 +1966,6 @@ contract EVM2EVMOnRamp_setDynamicConfig is EVM2EVMOnRampSetup { maxPerMsgGasLimit: MAX_GAS_LIMIT / 2, defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, - defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, enforceOutOfOrder: false }); @@ -1961,7 +2000,6 @@ contract EVM2EVMOnRamp_setDynamicConfig is EVM2EVMOnRampSetup { maxPerMsgGasLimit: MAX_GAS_LIMIT / 2, defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, - defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, enforceOutOfOrder: false }); diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol index 6659b1217f..91e47a7e98 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol @@ -65,29 +65,18 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { minFeeUSDCents: 1_00, // 1 USD maxFeeUSDCents: 1000_00, // 1,000 USD deciBps: 2_5, // 2.5 bps, or 0.025% - destGasOverhead: 40_000, + destGasOverhead: 100_000, destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES), aggregateRateLimitEnabled: true }) ); - s_tokenTransferFeeConfigArgs.push( - EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ - token: s_sourceRouter.getWrappedNative(), - minFeeUSDCents: 50, // 0.5 USD - maxFeeUSDCents: 500_00, // 500 USD - deciBps: 5_0, // 5 bps, or 0.05% - destGasOverhead: 10_000, - destBytesOverhead: 100, - aggregateRateLimitEnabled: true - }) - ); s_tokenTransferFeeConfigArgs.push( EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ token: CUSTOM_TOKEN, minFeeUSDCents: 2_00, // 1 USD - maxFeeUSDCents: 2000_00, // 1,000 USD + maxFeeUSDCents: 500_00, // 500 USD deciBps: 10_0, // 10 bps, or 0.1% - destGasOverhead: 1, + destGasOverhead: 90_000, destBytesOverhead: 200, aggregateRateLimitEnabled: true }) @@ -157,7 +146,6 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { maxPerMsgGasLimit: MAX_GAS_LIMIT, defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, - defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, enforceOutOfOrder: false }); } @@ -232,11 +220,17 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { }); for (uint256 i = 0; i < numberOfTokens; ++i) { + EVM2EVMOnRamp.TokenTransferFeeConfig memory tokenTransferFeeConfig = + s_onRamp.getTokenTransferFeeConfig(message.tokenAmounts[i].token); + messageEvent.sourceTokenData[i] = abi.encode( Internal.SourceTokenData({ sourcePoolAddress: abi.encode(s_sourcePoolByToken[message.tokenAmounts[i].token]), destTokenAddress: abi.encode(s_destTokenBySourceToken[message.tokenAmounts[i].token]), - extraData: "" + extraData: "", + destGasAmount: tokenTransferFeeConfig.isEnabled + ? tokenTransferFeeConfig.destGasOverhead + : DEFAULT_TOKEN_DEST_GAS_OVERHEAD }) ); } diff --git a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol index 97d0d4e894..6af905cfe5 100644 --- a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol @@ -333,7 +333,7 @@ contract LockReleaseTokenPool_provideLiquidity is LockReleaseTokenPoolSetup { function test_Unauthorized_Revert() public { vm.startPrank(STRANGER); - vm.expectRevert(abi.encodeWithSelector(LockReleaseTokenPool.Unauthorized.selector, STRANGER)); + vm.expectRevert(abi.encodeWithSelector(TokenPool.Unauthorized.selector, STRANGER)); s_lockReleaseTokenPool.provideLiquidity(1); } @@ -368,7 +368,7 @@ contract LockReleaseTokenPool_withdrawalLiquidity is LockReleaseTokenPoolSetup { function test_Unauthorized_Revert() public { vm.startPrank(STRANGER); - vm.expectRevert(abi.encodeWithSelector(LockReleaseTokenPool.Unauthorized.selector, STRANGER)); + vm.expectRevert(abi.encodeWithSelector(TokenPool.Unauthorized.selector, STRANGER)); s_lockReleaseTokenPool.withdrawLiquidity(1); } @@ -387,126 +387,47 @@ contract LockReleaseTokenPool_withdrawalLiquidity is LockReleaseTokenPoolSetup { } } -contract LockReleaseTokenPool_supportsInterface is LockReleaseTokenPoolSetup { - function test_SupportsInterface_Success() public view { - assertTrue(s_lockReleaseTokenPool.supportsInterface(type(IPoolV1).interfaceId)); - assertTrue(s_lockReleaseTokenPool.supportsInterface(type(IERC165).interfaceId)); - } -} - -contract LockReleaseTokenPool_setChainRateLimiterConfig is LockReleaseTokenPoolSetup { - uint64 internal s_remoteChainSelector; +contract LockReleaseTokenPool_transferLiquidity is LockReleaseTokenPoolSetup { + LockReleaseTokenPool internal s_oldLockReleaseTokenPool; + uint256 internal s_amount = 100000; function setUp() public virtual override { - LockReleaseTokenPoolSetup.setUp(); - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); - s_remoteChainSelector = 123124; - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: s_remoteChainSelector, - remotePoolAddress: abi.encode(address(1)), - remoteTokenAddress: abi.encode(address(2)), - allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() - }); - s_lockReleaseTokenPool.applyChainUpdates(chainUpdates); - } - - function test_Fuzz_SetChainRateLimiterConfig_Success(uint128 capacity, uint128 rate, uint32 newTime) public { - // Cap the lower bound to 4 so 4/2 is still >= 2 - vm.assume(capacity >= 4); - // Cap the lower bound to 2 so 2/2 is still >= 1 - rate = uint128(bound(rate, 2, capacity - 2)); - // Bucket updates only work on increasing time - newTime = uint32(bound(newTime, block.timestamp + 1, type(uint32).max)); - vm.warp(newTime); - - uint256 oldOutboundTokens = s_lockReleaseTokenPool.getCurrentOutboundRateLimiterState(s_remoteChainSelector).tokens; - uint256 oldInboundTokens = s_lockReleaseTokenPool.getCurrentInboundRateLimiterState(s_remoteChainSelector).tokens; - - RateLimiter.Config memory newOutboundConfig = RateLimiter.Config({isEnabled: true, capacity: capacity, rate: rate}); - RateLimiter.Config memory newInboundConfig = - RateLimiter.Config({isEnabled: true, capacity: capacity / 2, rate: rate / 2}); - - vm.expectEmit(); - emit RateLimiter.ConfigChanged(newOutboundConfig); - vm.expectEmit(); - emit RateLimiter.ConfigChanged(newInboundConfig); - vm.expectEmit(); - emit TokenPool.ChainConfigured(s_remoteChainSelector, newOutboundConfig, newInboundConfig); - - s_lockReleaseTokenPool.setChainRateLimiterConfig(s_remoteChainSelector, newOutboundConfig, newInboundConfig); - - uint256 expectedTokens = RateLimiter._min(newOutboundConfig.capacity, oldOutboundTokens); - - RateLimiter.TokenBucket memory bucket = - s_lockReleaseTokenPool.getCurrentOutboundRateLimiterState(s_remoteChainSelector); - assertEq(bucket.capacity, newOutboundConfig.capacity); - assertEq(bucket.rate, newOutboundConfig.rate); - assertEq(bucket.tokens, expectedTokens); - assertEq(bucket.lastUpdated, newTime); + super.setUp(); - expectedTokens = RateLimiter._min(newInboundConfig.capacity, oldInboundTokens); + s_oldLockReleaseTokenPool = + new LockReleaseTokenPool(s_token, new address[](0), address(s_mockRMN), true, address(s_sourceRouter)); - bucket = s_lockReleaseTokenPool.getCurrentInboundRateLimiterState(s_remoteChainSelector); - assertEq(bucket.capacity, newInboundConfig.capacity); - assertEq(bucket.rate, newInboundConfig.rate); - assertEq(bucket.tokens, expectedTokens); - assertEq(bucket.lastUpdated, newTime); + deal(address(s_token), address(s_oldLockReleaseTokenPool), s_amount); } - function test_OnlyOwnerOrRateLimitAdmin_Revert() public { - address rateLimiterAdmin = address(28973509103597907); - - s_lockReleaseTokenPool.setRateLimitAdmin(rateLimiterAdmin); + function test_transferLiquidity_Success() public { + uint256 balancePre = s_token.balanceOf(address(s_lockReleaseTokenPool)); - vm.startPrank(rateLimiterAdmin); + s_oldLockReleaseTokenPool.setRebalancer(address(s_lockReleaseTokenPool)); - s_lockReleaseTokenPool.setChainRateLimiterConfig( - s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() - ); + vm.expectEmit(); + emit LockReleaseTokenPool.LiquidityTransferred(address(s_oldLockReleaseTokenPool), s_amount); - vm.startPrank(OWNER); + s_lockReleaseTokenPool.transferLiquidity(address(s_oldLockReleaseTokenPool), s_amount); - s_lockReleaseTokenPool.setChainRateLimiterConfig( - s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() - ); + assertEq(s_token.balanceOf(address(s_lockReleaseTokenPool)), balancePre + s_amount); } - // Reverts - - function test_OnlyOwner_Revert() public { - vm.startPrank(STRANGER); + function test_transferLiquidity_transferTooMuch_Revert() public { + uint256 balancePre = s_token.balanceOf(address(s_lockReleaseTokenPool)); - vm.expectRevert(abi.encodeWithSelector(LockReleaseTokenPool.Unauthorized.selector, STRANGER)); - s_lockReleaseTokenPool.setChainRateLimiterConfig( - s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() - ); - } + s_oldLockReleaseTokenPool.setRebalancer(address(s_lockReleaseTokenPool)); - function test_NonExistentChain_Revert() public { - uint64 wrongChainSelector = 9084102894; + vm.expectRevert(LockReleaseTokenPool.InsufficientLiquidity.selector); + s_lockReleaseTokenPool.transferLiquidity(address(s_oldLockReleaseTokenPool), s_amount + 1); - vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, wrongChainSelector)); - s_lockReleaseTokenPool.setChainRateLimiterConfig( - wrongChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() - ); + assertEq(s_token.balanceOf(address(s_lockReleaseTokenPool)), balancePre); } } -contract LockReleaseTokenPool_setRateLimitAdmin is LockReleaseTokenPoolSetup { - function test_SetRateLimitAdmin_Success() public { - assertEq(address(0), s_lockReleaseTokenPool.getRateLimitAdmin()); - s_lockReleaseTokenPool.setRateLimitAdmin(OWNER); - assertEq(OWNER, s_lockReleaseTokenPool.getRateLimitAdmin()); - } - - // Reverts - - function test_SetRateLimitAdmin_Revert() public { - vm.startPrank(STRANGER); - - vm.expectRevert("Only callable by owner"); - s_lockReleaseTokenPool.setRateLimitAdmin(STRANGER); +contract LockReleaseTokenPool_supportsInterface is LockReleaseTokenPoolSetup { + function test_SupportsInterface_Success() public view { + assertTrue(s_lockReleaseTokenPool.supportsInterface(type(IPoolV1).interfaceId)); + assertTrue(s_lockReleaseTokenPool.supportsInterface(type(IERC165).interfaceId)); } } diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool.t.sol index e5eb04b741..2c9eaf6df0 100644 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool.t.sol @@ -429,10 +429,10 @@ contract TokenPool_setChainRateLimiterConfig is TokenPoolSetup { // Reverts - function test_OnlyOwner_Revert() public { + function test_OnlyOwnerOrRateLimitAdmin_Revert() public { vm.startPrank(STRANGER); - vm.expectRevert("Only callable by owner"); + vm.expectRevert(abi.encodeWithSelector(TokenPool.Unauthorized.selector, STRANGER)); s_tokenPool.setChainRateLimiterConfig( s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() ); @@ -448,6 +448,23 @@ contract TokenPool_setChainRateLimiterConfig is TokenPoolSetup { } } +contract LockRelease_setRateLimitAdmin is TokenPoolSetup { + function test_SetRateLimitAdmin_Success() public { + assertEq(address(0), s_tokenPool.getRateLimitAdmin()); + s_tokenPool.setRateLimitAdmin(OWNER); + assertEq(OWNER, s_tokenPool.getRateLimitAdmin()); + } + + // Reverts + + function test_SetRateLimitAdmin_Revert() public { + vm.startPrank(STRANGER); + + vm.expectRevert("Only callable by owner"); + s_tokenPool.setRateLimitAdmin(STRANGER); + } +} + contract TokenPool_onlyOnRamp is TokenPoolSetup { function test_onlyOnRamp_Success() public { uint64 chainSelector = 13377; diff --git a/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol index 200ffb4f6d..564407df5a 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol @@ -23,6 +23,7 @@ contract USDCTokenPoolSetup is BaseTest { IBurnMintERC20 internal s_token; MockUSDCTokenMessenger internal s_mockUSDC; MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; + uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; struct USDCMessage { uint32 version; @@ -319,24 +320,6 @@ contract USDCTokenPool_lockOrBurn is USDCTokenPoolSetup { }) ); } - - function test_lockOrBurn_InvalidReceiver_Revert() public { - vm.startPrank(s_routerAllowedOnRamp); - - bytes memory receiver = abi.encodePacked(address(0), address(1)); - - vm.expectRevert(abi.encodeWithSelector(USDCTokenPool.InvalidReceiver.selector, receiver)); - - s_usdcTokenPool.lockOrBurn( - Pool.LockOrBurnInV1({ - originalSender: OWNER, - receiver: receiver, - amount: 1, - remoteChainSelector: DEST_CHAIN_SELECTOR, - localToken: address(s_token) - }) - ); - } } contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { @@ -363,7 +346,8 @@ contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { destTokenAddress: abi.encode(address(s_usdcTokenPool)), extraData: abi.encode( USDCTokenPool.SourceTokenDataPayload({nonce: usdcMessage.nonce, sourceDomain: SOURCE_DOMAIN_IDENTIFIER}) - ) + ), + destGasAmount: USDC_DEST_TOKEN_GAS }); bytes memory offchainTokenData = @@ -408,7 +392,8 @@ contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ sourcePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), destTokenAddress: abi.encode(address(s_usdcTokenPool)), - extraData: abi.encode(USDCTokenPool.SourceTokenDataPayload({nonce: nonce, sourceDomain: sourceDomain})) + extraData: abi.encode(USDCTokenPool.SourceTokenDataPayload({nonce: nonce, sourceDomain: sourceDomain})), + destGasAmount: USDC_DEST_TOKEN_GAS }); // The mocked receiver does not release the token to the pool, so we manually do it here @@ -460,7 +445,8 @@ contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { destTokenAddress: abi.encode(address(s_usdcTokenPool)), extraData: abi.encode( USDCTokenPool.SourceTokenDataPayload({nonce: usdcMessage.nonce, sourceDomain: SOURCE_DOMAIN_IDENTIFIER}) - ) + ), + destGasAmount: USDC_DEST_TOKEN_GAS }); bytes memory offchainTokenData = abi.encode( @@ -492,7 +478,8 @@ contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ sourcePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), destTokenAddress: abi.encode(address(s_usdcTokenPool)), - extraData: abi.encode(USDCTokenPool.SourceTokenDataPayload({nonce: 1, sourceDomain: SOURCE_DOMAIN_IDENTIFIER})) + extraData: abi.encode(USDCTokenPool.SourceTokenDataPayload({nonce: 1, sourceDomain: SOURCE_DOMAIN_IDENTIFIER})), + destGasAmount: USDC_DEST_TOKEN_GAS }); bytes memory offchainTokenData = diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol index c3c22ef290..b26eb56474 100644 --- a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol +++ b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol @@ -139,19 +139,6 @@ contract PriceRegistrySetup is TokenSetup { }) }) ); - s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( - PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ - token: s_sourceRouter.getWrappedNative(), - tokenTransferFeeConfig: PriceRegistry.TokenTransferFeeConfig({ - minFeeUSDCents: 50, // 0.5 USD - maxFeeUSDCents: 500_00, // 500 USD - deciBps: 5_0, // 5 bps, or 0.05% - destGasOverhead: 10_000, - destBytesOverhead: 100, - isEnabled: true - }) - }) - ); s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ token: CUSTOM_TOKEN, @@ -1777,35 +1764,6 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); } - function test_WETHTokenBpsFee_Success() public view { - uint256 tokenAmount = 100e18; - - Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ - receiver: abi.encode(OWNER), - data: "", - tokenAmounts: new Client.EVMTokenAmount[](1), - feeToken: s_sourceRouter.getWrappedNative(), - extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) - }); - message.tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceRouter.getWrappedNative(), amount: tokenAmount}); - - PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); - - (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = s_priceRegistry.getTokenTransferCost( - DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts - ); - - uint256 usdWei = calcUSDValueFromTokenAmount(s_wrappedTokenPrice, tokenAmount); - uint256 bpsUSDWei = applyBpsRatio( - usdWei, s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig.deciBps - ); - - assertEq(bpsUSDWei, feeUSDWei); - assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); - assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); - } - function test_CustomTokenBpsFee_Success() public view { uint256 tokenAmount = 200000e18; @@ -1826,7 +1784,7 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { uint256 usdWei = calcUSDValueFromTokenAmount(s_customTokenPrice, tokenAmount); uint256 bpsUSDWei = applyBpsRatio( - usdWei, s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[2].tokenTransferFeeConfig.deciBps + usdWei, s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig.deciBps ); assertEq(bpsUSDWei, feeUSDWei); @@ -1914,9 +1872,15 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { // Start with small token transfers, total bps fee is lower than min token transfer fee for (uint256 i = 0; i < testTokens.length; ++i) { message.tokenAmounts[i] = Client.EVMTokenAmount({token: testTokens[i], amount: 1e14}); - expectedTotalGas += s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[i]).destGasOverhead; - expectedTotalBytes += - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[i]).destBytesOverhead; + PriceRegistry.TokenTransferFeeConfig memory tokenTransferFeeConfig = + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[i]); + + expectedTotalGas += tokenTransferFeeConfig.destGasOverhead == 0 + ? DEFAULT_TOKEN_DEST_GAS_OVERHEAD + : tokenTransferFeeConfig.destGasOverhead; + expectedTotalBytes += tokenTransferFeeConfig.destBytesOverhead == 0 + ? DEFAULT_TOKEN_BYTES_OVERHEAD + : tokenTransferFeeConfig.destBytesOverhead; } (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = s_priceRegistry.getTokenTransferCost( DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts @@ -1924,44 +1888,45 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { uint256 expectedFeeUSDWei = 0; for (uint256 i = 0; i < testTokens.length; ++i) { - expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[i].minFeeUSDCents); + expectedFeeUSDWei += configUSDCentToWei( + tokenTransferFeeConfigs[i].minFeeUSDCents == 0 + ? DEFAULT_TOKEN_FEE_USD_CENTS + : tokenTransferFeeConfigs[i].minFeeUSDCents + ); } - assertEq(expectedFeeUSDWei, feeUSDWei); - assertEq(expectedTotalGas, destGasOverhead); - assertEq(expectedTotalBytes, destBytesOverhead); + assertEq(expectedFeeUSDWei, feeUSDWei, "wrong feeUSDWei 1"); + assertEq(expectedTotalGas, destGasOverhead, "wrong destGasOverhead 1"); + assertEq(expectedTotalBytes, destBytesOverhead, "wrong destBytesOverhead 1"); // Set 1st token transfer to a meaningful amount so its bps fee is now between min and max fee message.tokenAmounts[0] = Client.EVMTokenAmount({token: testTokens[0], amount: 10000e18}); + uint256 token0USDWei = applyBpsRatio( + calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), tokenTransferFeeConfigs[0].deciBps + ); + uint256 token1USDWei = configUSDCentToWei(DEFAULT_TOKEN_FEE_USD_CENTS); + (feeUSDWei, destGasOverhead, destBytesOverhead) = s_priceRegistry.getTokenTransferCost( DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts ); - expectedFeeUSDWei = applyBpsRatio( - calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), tokenTransferFeeConfigs[0].deciBps - ); - expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[1].minFeeUSDCents); - expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); + expectedFeeUSDWei = token0USDWei + token1USDWei + configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); - assertEq(expectedFeeUSDWei, feeUSDWei); - assertEq(expectedTotalGas, destGasOverhead); - assertEq(expectedTotalBytes, destBytesOverhead); + assertEq(expectedFeeUSDWei, feeUSDWei, "wrong feeUSDWei 2"); + assertEq(expectedTotalGas, destGasOverhead, "wrong destGasOverhead 2"); + assertEq(expectedTotalBytes, destBytesOverhead, "wrong destBytesOverhead 2"); // Set 2nd token transfer to a large amount that is higher than maxFeeUSD - message.tokenAmounts[1] = Client.EVMTokenAmount({token: testTokens[1], amount: 1e36}); + message.tokenAmounts[2] = Client.EVMTokenAmount({token: testTokens[2], amount: 1e36}); (feeUSDWei, destGasOverhead, destBytesOverhead) = s_priceRegistry.getTokenTransferCost( DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts ); - expectedFeeUSDWei = applyBpsRatio( - calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), tokenTransferFeeConfigs[0].deciBps - ); - expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[1].maxFeeUSDCents); - expectedFeeUSDWei += configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); + expectedFeeUSDWei = token0USDWei + token1USDWei + configUSDCentToWei(tokenTransferFeeConfigs[2].maxFeeUSDCents); - assertEq(expectedFeeUSDWei, feeUSDWei); - assertEq(expectedTotalGas, destGasOverhead); - assertEq(expectedTotalBytes, destBytesOverhead); + assertEq(expectedFeeUSDWei, feeUSDWei, "wrong feeUSDWei 3"); + assertEq(expectedTotalGas, destGasOverhead, "wrong destGasOverhead 3"); + assertEq(expectedTotalBytes, destBytesOverhead, "wrong destBytesOverhead 3"); } } diff --git a/contracts/src/v0.8/ccip/test/router/RouterSetup.t.sol b/contracts/src/v0.8/ccip/test/router/RouterSetup.t.sol index de75161761..423a47951d 100644 --- a/contracts/src/v0.8/ccip/test/router/RouterSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/router/RouterSetup.t.sol @@ -41,7 +41,8 @@ contract RouterSetup is BaseTest { return Internal.SourceTokenData({ sourcePoolAddress: abi.encode(address(12312412312)), destTokenAddress: abi.encode(address(9809808909)), - extraData: "" + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD }); } } diff --git a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go index 28e67b0dff..e5a9e0be79 100644 --- a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go @@ -82,8 +82,8 @@ type TokenPoolChainUpdate struct { } var BurnFromMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620043d9380380620043d98339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161386062000b79600039600081816104960152818161164501526120290152600081816104700152818161147601526118fb01526000818161022301528181610278015281816106ba015281816113960152818161181b01528181611a1301528181611fbf015261221401526138606000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c8063a7cd63b7116100e3578063c75eea9c1161008c578063dc0bd97111610066578063dc0bd9711461046e578063e0351e1314610494578063f2fde38b146104ba57600080fd5b8063c75eea9c14610435578063cf7401f314610448578063db6327dc1461045b57600080fd5b8063b7946580116100bd578063b7946580146103fa578063c0d786551461040d578063c4bffe2b1461042057600080fd5b8063a7cd63b714610358578063af58d59f1461036d578063b0f479a1146103dc57600080fd5b806354c8a4f3116101455780638926f54f1161011f5780638926f54f146103075780638da5cb5b1461031a5780639a4575b91461033857600080fd5b806354c8a4f3146102d757806378a010b2146102ec57806379ba5097146102ff57600080fd5b806321df0da71161017657806321df0da714610221578063240028e81461026857806339077537146102b557600080fd5b806301ffc9a71461019d5780630a2fd493146101c5578063181f5a77146101e5575b600080fd5b6101b06101ab3660046129b7565b6104cd565b60405190151581526020015b60405180910390f35b6101d86101d3366004612a16565b6105b2565b6040516101bc9190612a95565b6101d86040518060400160405280601f81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e302d6465760081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b6101b0610276366004612ad5565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102c86102c3366004612af2565b610662565b604051905181526020016101bc565b6102ea6102e5366004612b7a565b6107bd565b005b6102ea6102fa366004612be6565b610838565b6102ea6109ac565b6101b0610315366004612a16565b610aa9565b60005473ffffffffffffffffffffffffffffffffffffffff16610243565b61034b610346366004612c69565b610ac0565b6040516101bc9190612ca4565b610360610b67565b6040516101bc9190612d04565b61038061037b366004612a16565b610b78565b6040516101bc919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610243565b6101d8610408366004612a16565b610c4d565b6102ea61041b366004612ad5565b610c78565b610428610d53565b6040516101bc9190612d5e565b610380610443366004612a16565b610e0b565b6102ea610456366004612ec6565b610edd565b6102ea610469366004612f0b565b610ef5565b7f0000000000000000000000000000000000000000000000000000000000000000610243565b7f00000000000000000000000000000000000000000000000000000000000000006101b0565b6102ea6104c8366004612ad5565b61137b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061056057507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105ac57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906105dd90612f4d565b80601f016020809104026020016040519081016040528092919081815260200182805461060990612f4d565b80156106565780601f1061062b57610100808354040283529160200191610656565b820191906000526020600020905b81548152906001019060200180831161063957829003601f168201915b50505050509050919050565b60408051602081019091526000815261068261067d8361304b565b61138f565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561071357600080fd5b505af1158015610727573d6000803e3d6000fd5b5061073c925050506060830160408401612ad5565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161079e91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6107c56115c0565b6108328484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061164392505050565b50505050565b6108406115c0565b61084983610aa9565b610890576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546108b790612f4d565b80601f01602080910402602001604051908101604052809291908181526020018280546108e390612f4d565b80156109305780601f1061090557610100808354040283529160200191610930565b820191906000526020600020905b81548152906001019060200180831161091357829003601f168201915b5050505067ffffffffffffffff861660009081526007602052604090209192505060040161095f838583613190565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf82858560405161099e939291906132aa565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610887565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006105ac600567ffffffffffffffff84166117f9565b6040805180820190915260608082526020820152610ae5610ae08361330e565b611814565b610af282606001356119de565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b4c8460200160208101906104089190612a16565b81526040805160208181019092526000815291015292915050565b6060610b736002611a87565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105ac90611a94565b67ffffffffffffffff811660009081526007602052604090206005018054606091906105dd90612f4d565b610c806115c0565b73ffffffffffffffffffffffffffffffffffffffff8116610ccd576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610d616005611a87565b90506000815167ffffffffffffffff811115610d7f57610d7f612da0565b604051908082528060200260200182016040528015610da8578160200160208202803683370190505b50905060005b8251811015610e0457828181518110610dc957610dc96133b0565b6020026020010151828281518110610de357610de36133b0565b67ffffffffffffffff90921660209283029190910190910152600101610dae565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105ac90611a94565b610ee56115c0565b610ef0838383611b46565b505050565b610efd6115c0565b60005b81811015610ef0576000838383818110610f1c57610f1c6133b0565b9050602002810190610f2e91906133df565b610f379061341d565b9050610f4c8160800151826020015115611c30565b610f5f8160a00151826020015115611c30565b80602001511561125b578051610f819060059067ffffffffffffffff16611d69565b610fc65780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610887565b6040810151511580610fdb5750606081015151155b15611012576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906111f390826134d1565b506060820151600582019061120890826134d1565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061124e94939291906135eb565b60405180910390a1611372565b80516112739060059067ffffffffffffffff16611d75565b6112b85780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610887565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906113216004830182612969565b61132f600583016000612969565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101610f00565b6113836115c0565b61138c81611d81565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146114245760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610887565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f69190613684565b1561152d576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61153a8160200151611e76565b600061154982602001516105b2565b905080516000148061156d575080805190602001208260a001518051906020012014155b156115aa578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108879190612a95565b6115bc82602001518360600151611f9c565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611641576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610887565b565b7f000000000000000000000000000000000000000000000000000000000000000061169a576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156117305760008382815181106116ba576116ba6133b0565b602002602001015190506116d8816002611fe390919063ffffffff16565b156117275760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010161169d565b5060005b8151811015610ef0576000828281518110611751576117516133b0565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361179557506117f1565b6117a0600282612005565b156117ef5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611734565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146118a95760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610887565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197b9190613684565b156119b2576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119bf8160400151612027565b6119cc81602001516120a6565b61138c816020015182606001516121f4565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015611a6c57600080fd5b505af1158015611a80573d6000803e3d6000fd5b5050505050565b6060600061180d83612238565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611b2282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611b0691906136d0565b85608001516fffffffffffffffffffffffffffffffff16612293565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611b4f83610aa9565b611b91576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610887565b611b9c826000611c30565b67ffffffffffffffff83166000908152600760205260409020611bbf90836122bd565b611bca816000611c30565b67ffffffffffffffff83166000908152600760205260409020611bf090600201826122bd565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611c23939291906136e3565b60405180910390a1505050565b815115611cf75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611c86575060408201516fffffffffffffffffffffffffffffffff16155b15611cbf57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108879190613766565b80156115bc576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611d30575060208201516fffffffffffffffffffffffffffffffff1615155b156115bc57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108879190613766565b600061180d838361245f565b600061180d83836124ae565b3373ffffffffffffffffffffffffffffffffffffffff821603611e00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610887565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611e7f81610aa9565b611ec1576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610887565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015611f40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f649190613684565b61138c576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610887565b67ffffffffffffffff821660009081526007602052604090206115bc90600201827f00000000000000000000000000000000000000000000000000000000000000006125a1565b600061180d8373ffffffffffffffffffffffffffffffffffffffff84166124ae565b600061180d8373ffffffffffffffffffffffffffffffffffffffff841661245f565b7f00000000000000000000000000000000000000000000000000000000000000001561138c57612058600282612924565b61138c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610887565b6120af81610aa9565b6120f1576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610887565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561216a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061218e91906137a2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461138c576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610887565b67ffffffffffffffff821660009081526007602052604090206115bc90827f00000000000000000000000000000000000000000000000000000000000000006125a1565b60608160000180548060200260200160405190810160405280929190818152602001828054801561065657602002820191906000526020600020905b8154815260200190600101908083116122745750505050509050919050565b60006122b2856122a384866137bf565b6122ad90876137d6565b612953565b90505b949350505050565b81546000906122e690700100000000000000000000000000000000900463ffffffff16426136d0565b90508015612388576001830154835461232e916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612293565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546123ae916fffffffffffffffffffffffffffffffff9081169116612953565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611c23908490613766565b60008181526001830160205260408120546124a6575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105ac565b5060006105ac565b600081815260018301602052604081205480156125975760006124d26001836136d0565b85549091506000906124e6906001906136d0565b905081811461254b576000866000018281548110612506576125066133b0565b9060005260206000200154905080876000018481548110612529576125296133b0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061255c5761255c6137e9565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105ac565b60009150506105ac565b825474010000000000000000000000000000000000000000900460ff1615806125c8575081155b156125d257505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061261890700100000000000000000000000000000000900463ffffffff16426136d0565b905080156126d8578183111561265a576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546126949083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612293565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561278f5773ffffffffffffffffffffffffffffffffffffffff8416612737576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610887565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610887565b848310156128a25760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906127d390826136d0565b6127dd878a6136d0565b6127e791906137d6565b6127f19190613818565b905073ffffffffffffffffffffffffffffffffffffffff861661284a576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610887565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610887565b6128ac85846136d0565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561180d565b6000818310612962578161180d565b5090919050565b50805461297590612f4d565b6000825580601f10612985575050565b601f01602090049060005260206000209081019061138c91905b808211156129b3576000815560010161299f565b5090565b6000602082840312156129c957600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461180d57600080fd5b803567ffffffffffffffff81168114612a1157600080fd5b919050565b600060208284031215612a2857600080fd5b61180d826129f9565b6000815180845260005b81811015612a5757602081850181015186830182015201612a3b565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061180d6020830184612a31565b73ffffffffffffffffffffffffffffffffffffffff8116811461138c57600080fd5b8035612a1181612aa8565b600060208284031215612ae757600080fd5b813561180d81612aa8565b600060208284031215612b0457600080fd5b813567ffffffffffffffff811115612b1b57600080fd5b8201610100818503121561180d57600080fd5b60008083601f840112612b4057600080fd5b50813567ffffffffffffffff811115612b5857600080fd5b6020830191508360208260051b8501011115612b7357600080fd5b9250929050565b60008060008060408587031215612b9057600080fd5b843567ffffffffffffffff80821115612ba857600080fd5b612bb488838901612b2e565b90965094506020870135915080821115612bcd57600080fd5b50612bda87828801612b2e565b95989497509550505050565b600080600060408486031215612bfb57600080fd5b612c04846129f9565b9250602084013567ffffffffffffffff80821115612c2157600080fd5b818601915086601f830112612c3557600080fd5b813581811115612c4457600080fd5b876020828501011115612c5657600080fd5b6020830194508093505050509250925092565b600060208284031215612c7b57600080fd5b813567ffffffffffffffff811115612c9257600080fd5b820160a0818503121561180d57600080fd5b602081526000825160406020840152612cc06060840182612a31565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612cfb8282612a31565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d5257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612d20565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d5257835167ffffffffffffffff1683529284019291840191600101612d7a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612df357612df3612da0565b60405290565b60405160c0810167ffffffffffffffff81118282101715612df357612df3612da0565b801515811461138c57600080fd5b8035612a1181612e1c565b80356fffffffffffffffffffffffffffffffff81168114612a1157600080fd5b600060608284031215612e6757600080fd5b6040516060810181811067ffffffffffffffff82111715612e8a57612e8a612da0565b6040529050808235612e9b81612e1c565b8152612ea960208401612e35565b6020820152612eba60408401612e35565b60408201525092915050565b600080600060e08486031215612edb57600080fd5b612ee4846129f9565b9250612ef38560208601612e55565b9150612f028560808601612e55565b90509250925092565b60008060208385031215612f1e57600080fd5b823567ffffffffffffffff811115612f3557600080fd5b612f4185828601612b2e565b90969095509350505050565b600181811c90821680612f6157607f821691505b602082108103612f9a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f830112612fb157600080fd5b813567ffffffffffffffff80821115612fcc57612fcc612da0565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561301257613012612da0565b8160405283815286602085880101111561302b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561305e57600080fd5b613066612dcf565b823567ffffffffffffffff8082111561307e57600080fd5b61308a36838701612fa0565b8352613098602086016129f9565b60208401526130a960408601612aca565b6040840152606085013560608401526130c460808601612aca565b608084015260a08501359150808211156130dd57600080fd5b6130e936838701612fa0565b60a084015260c085013591508082111561310257600080fd5b61310e36838701612fa0565b60c084015260e085013591508082111561312757600080fd5b5061313436828601612fa0565b60e08301525092915050565b601f821115610ef0576000816000526020600020601f850160051c810160208610156131695750805b601f850160051c820191505b8181101561318857828155600101613175565b505050505050565b67ffffffffffffffff8311156131a8576131a8612da0565b6131bc836131b68354612f4d565b83613140565b6000601f84116001811461320e57600085156131d85750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a80565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561325d578685013582556020948501946001909201910161323d565b5086821015613298577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006132bd6040830186612a31565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561332057600080fd5b60405160a0810167ffffffffffffffff828210818311171561334457613344612da0565b81604052843591508082111561335957600080fd5b5061336636828601612fa0565b825250613375602084016129f9565b6020820152604083013561338881612aa8565b60408201526060838101359082015260808301356133a581612aa8565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261341357600080fd5b9190910192915050565b6000610140823603121561343057600080fd5b613438612df9565b613441836129f9565b815261344f60208401612e2a565b6020820152604083013567ffffffffffffffff8082111561346f57600080fd5b61347b36838701612fa0565b6040840152606085013591508082111561349457600080fd5b506134a136828601612fa0565b6060830152506134b43660808501612e55565b60808201526134c63660e08501612e55565b60a082015292915050565b815167ffffffffffffffff8111156134eb576134eb612da0565b6134ff816134f98454612f4d565b84613140565b602080601f831160018114613552576000841561351c5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613188565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561359f57888601518255948401946001909101908401613580565b50858210156135db57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261360f81840187612a31565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061364d9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612cfb565b60006020828403121561369657600080fd5b815161180d81612e1c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105ac576105ac6136a1565b67ffffffffffffffff8416815260e0810161372f60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526122b5565b606081016105ac82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156137b457600080fd5b815161180d81612aa8565b80820281158282048414176105ac576105ac6136a1565b808201808211156105ac576105ac6136a1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261384e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b50604051620044e0380380620044e08339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161396762000b79600039600081816104dd0152818161174c01526121300152600081816104b70152818161157d0152611a020152600081816102390152818161028e015281816107010152818161149d0152818161192201528181611b1a015281816120c6015261231b01526139676000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612abe565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b1d565b6105f9565b6040516101d29190612b9c565b6101ee6040518060400160405280601f81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e302d6465760081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612bdc565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612bf9565b6106a9565b604051905181526020016101d2565b6103006102fb366004612c81565b610804565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612ced565b61087f565b6103006109f3565b610300610349366004612bdc565b610af0565b6101c661035c366004612b1d565b610b3f565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d70565b610b56565b6040516101d29190612dab565b6103a7610bfd565b6040516101d29190612e0b565b6103c76103c2366004612b1d565b610c0e565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b1d565b610ce3565b610300610462366004612bdc565b610d0e565b61046f610de9565b6040516101d29190612e65565b6103c761048a366004612b1d565b610ea1565b61030061049d366004612fcd565b610f73565b6103006104b0366004613012565b610ffc565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612bdc565b611482565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061062490613054565b80601f016020809104026020016040519081016040528092919081815260200182805461065090613054565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c483613152565b611496565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561075a57600080fd5b505af115801561076e573d6000803e3d6000fd5b50610783925050506060830160408401612bdc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f084606001356040516107e591815260200190565b60405180910390a3506040805160208101909152606090910135815290565b61080c6116c7565b6108798484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061174a92505050565b50505050565b6108876116c7565b61089083610b3f565b6108d7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546108fe90613054565b80601f016020809104026020016040519081016040528092919081815260200182805461092a90613054565b80156109775780601f1061094c57610100808354040283529160200191610977565b820191906000526020600020905b81548152906001019060200180831161095a57829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109a6838583613297565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf8285856040516109e5939291906133b1565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108ce565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610af86116c7565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff8416611900565b6040805180820190915260608082526020820152610b7b610b7683613415565b61191b565b610b888260600135611ae5565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610be284602001602081019061044f9190612b1d565b81526040805160208181019092526000815291015292915050565b6060610c096002611b8e565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611b9b565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061062490613054565b610d166116c7565b73ffffffffffffffffffffffffffffffffffffffff8116610d63576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610df76005611b8e565b90506000815167ffffffffffffffff811115610e1557610e15612ea7565b604051908082528060200260200182016040528015610e3e578160200160208202803683370190505b50905060005b8251811015610e9a57828181518110610e5f57610e5f6134b7565b6020026020010151828281518110610e7957610e796134b7565b67ffffffffffffffff90921660209283029190910190910152600101610e44565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611b9b565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fb3575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610fec576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108ce565b610ff7838383611c4d565b505050565b6110046116c7565b60005b81811015610ff7576000838383818110611023576110236134b7565b905060200281019061103591906134e6565b61103e90613524565b90506110538160800151826020015115611d37565b6110668160a00151826020015115611d37565b8060200151156113625780516110889060059067ffffffffffffffff16611e70565b6110cd5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108ce565b60408101515115806110e25750606081015151155b15611119576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906112fa90826135d8565b506060820151600582019061130f90826135d8565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061135594939291906136f2565b60405180910390a1611479565b805161137a9060059067ffffffffffffffff16611e7c565b6113bf5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108ce565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114286004830182612a70565b611436600583016000612a70565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611007565b61148a6116c7565b61149381611e88565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461152b5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108ce565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156115d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fd919061378b565b15611634576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116418160200151611f7d565b600061165082602001516105f9565b9050805160001480611674575080805190602001208260a001518051906020012014155b156116b1578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108ce9190612b9c565b6116c3826020015183606001516120a3565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108ce565b565b7f00000000000000000000000000000000000000000000000000000000000000006117a1576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118375760008382815181106117c1576117c16134b7565b602002602001015190506117df8160026120ea90919063ffffffff16565b1561182e5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117a4565b5060005b8151811015610ff7576000828281518110611858576118586134b7565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361189c57506118f8565b6118a760028261210c565b156118f65760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161183b565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119b05760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108ce565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a82919061378b565b15611ab9576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ac6816040015161212e565b611ad381602001516121ad565b611493816020015182606001516122fb565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015611b7357600080fd5b505af1158015611b87573d6000803e3d6000fd5b5050505050565b606060006119148361233f565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c2982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c0d91906137d7565b85608001516fffffffffffffffffffffffffffffffff1661239a565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c5683610b3f565b611c98576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108ce565b611ca3826000611d37565b67ffffffffffffffff83166000908152600760205260409020611cc690836123c4565b611cd1816000611d37565b67ffffffffffffffff83166000908152600760205260409020611cf790600201826123c4565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d2a939291906137ea565b60405180910390a1505050565b815115611dfe5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611d8d575060408201516fffffffffffffffffffffffffffffffff16155b15611dc657816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108ce919061386d565b80156116c3576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e37575060208201516fffffffffffffffffffffffffffffffff1615155b156116c357816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108ce919061386d565b60006119148383612566565b600061191483836125b5565b3373ffffffffffffffffffffffffffffffffffffffff821603611f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108ce565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611f8681610b3f565b611fc8576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108ce565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612047573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061206b919061378b565b611493576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108ce565b67ffffffffffffffff821660009081526007602052604090206116c390600201827f00000000000000000000000000000000000000000000000000000000000000006126a8565b60006119148373ffffffffffffffffffffffffffffffffffffffff84166125b5565b60006119148373ffffffffffffffffffffffffffffffffffffffff8416612566565b7f0000000000000000000000000000000000000000000000000000000000000000156114935761215f600282612a2b565b611493576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108ce565b6121b681610b3f565b6121f8576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108ce565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612271573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229591906138a9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611493576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108ce565b67ffffffffffffffff821660009081526007602052604090206116c390827f00000000000000000000000000000000000000000000000000000000000000006126a8565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b81548152602001906001019080831161237b5750505050509050919050565b60006123b9856123aa84866138c6565b6123b490876138dd565b612a5a565b90505b949350505050565b81546000906123ed90700100000000000000000000000000000000900463ffffffff16426137d7565b9050801561248f5760018301548354612435916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661239a565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124b5916fffffffffffffffffffffffffffffffff9081169116612a5a565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d2a90849061386d565b60008181526001830160205260408120546125ad575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b6000818152600183016020526040812054801561269e5760006125d96001836137d7565b85549091506000906125ed906001906137d7565b905081811461265257600086600001828154811061260d5761260d6134b7565b9060005260206000200154905080876000018481548110612630576126306134b7565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612663576126636138f0565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126cf575081155b156126d957505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061271f90700100000000000000000000000000000000900463ffffffff16426137d7565b905080156127df5781831115612761576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461279b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661239a565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128965773ffffffffffffffffffffffffffffffffffffffff841661283e576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108ce565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108ce565b848310156129a95760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128da90826137d7565b6128e4878a6137d7565b6128ee91906138dd565b6128f8919061391f565b905073ffffffffffffffffffffffffffffffffffffffff8616612951576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108ce565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108ce565b6129b385846137d7565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611914565b6000818310612a695781611914565b5090919050565b508054612a7c90613054565b6000825580601f10612a8c575050565b601f01602090049060005260206000209081019061149391905b80821115612aba5760008155600101612aa6565b5090565b600060208284031215612ad057600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461191457600080fd5b803567ffffffffffffffff81168114612b1857600080fd5b919050565b600060208284031215612b2f57600080fd5b61191482612b00565b6000815180845260005b81811015612b5e57602081850181015186830182015201612b42565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119146020830184612b38565b73ffffffffffffffffffffffffffffffffffffffff8116811461149357600080fd5b8035612b1881612baf565b600060208284031215612bee57600080fd5b813561191481612baf565b600060208284031215612c0b57600080fd5b813567ffffffffffffffff811115612c2257600080fd5b8201610100818503121561191457600080fd5b60008083601f840112612c4757600080fd5b50813567ffffffffffffffff811115612c5f57600080fd5b6020830191508360208260051b8501011115612c7a57600080fd5b9250929050565b60008060008060408587031215612c9757600080fd5b843567ffffffffffffffff80821115612caf57600080fd5b612cbb88838901612c35565b90965094506020870135915080821115612cd457600080fd5b50612ce187828801612c35565b95989497509550505050565b600080600060408486031215612d0257600080fd5b612d0b84612b00565b9250602084013567ffffffffffffffff80821115612d2857600080fd5b818601915086601f830112612d3c57600080fd5b813581811115612d4b57600080fd5b876020828501011115612d5d57600080fd5b6020830194508093505050509250925092565b600060208284031215612d8257600080fd5b813567ffffffffffffffff811115612d9957600080fd5b820160a0818503121561191457600080fd5b602081526000825160406020840152612dc76060840182612b38565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e028282612b38565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e5957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e27565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e5957835167ffffffffffffffff1683529284019291840191600101612e81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612efa57612efa612ea7565b60405290565b60405160c0810167ffffffffffffffff81118282101715612efa57612efa612ea7565b801515811461149357600080fd5b8035612b1881612f23565b80356fffffffffffffffffffffffffffffffff81168114612b1857600080fd5b600060608284031215612f6e57600080fd5b6040516060810181811067ffffffffffffffff82111715612f9157612f91612ea7565b6040529050808235612fa281612f23565b8152612fb060208401612f3c565b6020820152612fc160408401612f3c565b60408201525092915050565b600080600060e08486031215612fe257600080fd5b612feb84612b00565b9250612ffa8560208601612f5c565b91506130098560808601612f5c565b90509250925092565b6000806020838503121561302557600080fd5b823567ffffffffffffffff81111561303c57600080fd5b61304885828601612c35565b90969095509350505050565b600181811c9082168061306857607f821691505b6020821081036130a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130b857600080fd5b813567ffffffffffffffff808211156130d3576130d3612ea7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561311957613119612ea7565b8160405283815286602085880101111561313257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561316557600080fd5b61316d612ed6565b823567ffffffffffffffff8082111561318557600080fd5b613191368387016130a7565b835261319f60208601612b00565b60208401526131b060408601612bd1565b6040840152606085013560608401526131cb60808601612bd1565b608084015260a08501359150808211156131e457600080fd5b6131f0368387016130a7565b60a084015260c085013591508082111561320957600080fd5b613215368387016130a7565b60c084015260e085013591508082111561322e57600080fd5b5061323b368286016130a7565b60e08301525092915050565b601f821115610ff7576000816000526020600020601f850160051c810160208610156132705750805b601f850160051c820191505b8181101561328f5782815560010161327c565b505050505050565b67ffffffffffffffff8311156132af576132af612ea7565b6132c3836132bd8354613054565b83613247565b6000601f84116001811461331557600085156132df5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611b87565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156133645786850135825560209485019460019092019101613344565b508682101561339f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133c46040830186612b38565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561342757600080fd5b60405160a0810167ffffffffffffffff828210818311171561344b5761344b612ea7565b81604052843591508082111561346057600080fd5b5061346d368286016130a7565b82525061347c60208401612b00565b6020820152604083013561348f81612baf565b60408201526060838101359082015260808301356134ac81612baf565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261351a57600080fd5b9190910192915050565b6000610140823603121561353757600080fd5b61353f612f00565b61354883612b00565b815261355660208401612f31565b6020820152604083013567ffffffffffffffff8082111561357657600080fd5b613582368387016130a7565b6040840152606085013591508082111561359b57600080fd5b506135a8368286016130a7565b6060830152506135bb3660808501612f5c565b60808201526135cd3660e08501612f5c565b60a082015292915050565b815167ffffffffffffffff8111156135f2576135f2612ea7565b613606816136008454613054565b84613247565b602080601f83116001811461365957600084156136235750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561328f565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136a657888601518255948401946001909101908401613687565b50858210156136e257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261371681840187612b38565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506137549050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e02565b60006020828403121561379d57600080fd5b815161191481612f23565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137a8565b67ffffffffffffffff8416815260e0810161383660208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123bc565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138bb57600080fd5b815161191481612baf565b80820281158282048414176105f3576105f36137a8565b808201808211156105f3576105f36137a8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613955577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var BurnFromMintTokenPoolABI = BurnFromMintTokenPoolMetaData.ABI @@ -310,6 +310,28 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetCurrentOutb return _BurnFromMintTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) } +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getRateLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetRateLimitAdmin() (common.Address, error) { + return _BurnFromMintTokenPool.Contract.GetRateLimitAdmin(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetRateLimitAdmin() (common.Address, error) { + return _BurnFromMintTokenPool.Contract.GetRateLimitAdmin(&_BurnFromMintTokenPool.CallOpts) +} + func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { var out []interface{} err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) @@ -624,6 +646,18 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) SetChainRa return _BurnFromMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.SetRateLimitAdmin(&_BurnFromMintTokenPool.TransactOpts, rateLimitAdmin) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.SetRateLimitAdmin(&_BurnFromMintTokenPool.TransactOpts, rateLimitAdmin) +} + func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { return _BurnFromMintTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) } @@ -2644,6 +2678,8 @@ type BurnFromMintTokenPoolInterface interface { GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) @@ -2678,6 +2714,8 @@ type BurnFromMintTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go index 70e2f9393e..500b31ec51 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go @@ -82,8 +82,8 @@ type TokenPoolChainUpdate struct { } var BurnMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b5060405162003f8138038062003f8183398101604081905262000034916200054c565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000176565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001685760408051600081526020810190915262000168908462000221565b5050505050505050620006aa565b336001600160a01b03821603620001d05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000242576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002cd5760008382815181106200026657620002666200065c565b60209081029190910101519050620002806002826200037e565b15620002c3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000245565b5060005b815181101562000379576000828281518110620002f257620002f26200065c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200031e575062000370565b6200032b6002826200039e565b156200036e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d1565b505050565b600062000395836001600160a01b038416620003b5565b90505b92915050565b600062000395836001600160a01b038416620004b9565b60008181526001830160205260408120548015620004ae576000620003dc60018362000672565b8554909150600090620003f29060019062000672565b90508181146200045e5760008660000182815481106200041657620004166200065c565b90600052602060002001549050808760000184815481106200043c576200043c6200065c565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000472576200047262000694565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000398565b600091505062000398565b6000818152600183016020526040812054620005025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000398565b50600062000398565b6001600160a01b03811681146200052157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000547816200050b565b919050565b600080600080608085870312156200056357600080fd5b845162000570816200050b565b602086810151919550906001600160401b03808211156200059057600080fd5b818801915088601f830112620005a557600080fd5b815181811115620005ba57620005ba62000524565b8060051b604051601f19603f83011681018181108582111715620005e257620005e262000524565b60405291825284820192508381018501918b8311156200060157600080fd5b938501935b828510156200062a576200061a856200053a565b8452938501939285019262000606565b80985050505050505062000641604086016200053a565b915062000651606086016200053a565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161385a62000727600039600081816104960152818161164501526120230152600081816104700152818161147601526118fb01526000818161022301528181610278015281816106ba015281816113960152818161181b01528181611a0d01528181611fb9015261220e015261385a6000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c8063a7cd63b7116100e3578063c75eea9c1161008c578063dc0bd97111610066578063dc0bd9711461046e578063e0351e1314610494578063f2fde38b146104ba57600080fd5b8063c75eea9c14610435578063cf7401f314610448578063db6327dc1461045b57600080fd5b8063b7946580116100bd578063b7946580146103fa578063c0d786551461040d578063c4bffe2b1461042057600080fd5b8063a7cd63b714610358578063af58d59f1461036d578063b0f479a1146103dc57600080fd5b806354c8a4f3116101455780638926f54f1161011f5780638926f54f146103075780638da5cb5b1461031a5780639a4575b91461033857600080fd5b806354c8a4f3146102d757806378a010b2146102ec57806379ba5097146102ff57600080fd5b806321df0da71161017657806321df0da714610221578063240028e81461026857806339077537146102b557600080fd5b806301ffc9a71461019d5780630a2fd493146101c5578063181f5a77146101e5575b600080fd5b6101b06101ab3660046129b1565b6104cd565b60405190151581526020015b60405180910390f35b6101d86101d3366004612a10565b6105b2565b6040516101bc9190612a8f565b6101d86040518060400160405280601b81526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e302d646576000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b6101b0610276366004612acf565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102c86102c3366004612aec565b610662565b604051905181526020016101bc565b6102ea6102e5366004612b74565b6107bd565b005b6102ea6102fa366004612be0565b610838565b6102ea6109ac565b6101b0610315366004612a10565b610aa9565b60005473ffffffffffffffffffffffffffffffffffffffff16610243565b61034b610346366004612c63565b610ac0565b6040516101bc9190612c9e565b610360610b67565b6040516101bc9190612cfe565b61038061037b366004612a10565b610b78565b6040516101bc919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610243565b6101d8610408366004612a10565b610c4d565b6102ea61041b366004612acf565b610c78565b610428610d53565b6040516101bc9190612d58565b610380610443366004612a10565b610e0b565b6102ea610456366004612ec0565b610edd565b6102ea610469366004612f05565b610ef5565b7f0000000000000000000000000000000000000000000000000000000000000000610243565b7f00000000000000000000000000000000000000000000000000000000000000006101b0565b6102ea6104c8366004612acf565b61137b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061056057507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105ac57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906105dd90612f47565b80601f016020809104026020016040519081016040528092919081815260200182805461060990612f47565b80156106565780601f1061062b57610100808354040283529160200191610656565b820191906000526020600020905b81548152906001019060200180831161063957829003601f168201915b50505050509050919050565b60408051602081019091526000815261068261067d83613045565b61138f565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561071357600080fd5b505af1158015610727573d6000803e3d6000fd5b5061073c925050506060830160408401612acf565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161079e91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6107c56115c0565b6108328484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061164392505050565b50505050565b6108406115c0565b61084983610aa9565b610890576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546108b790612f47565b80601f01602080910402602001604051908101604052809291908181526020018280546108e390612f47565b80156109305780601f1061090557610100808354040283529160200191610930565b820191906000526020600020905b81548152906001019060200180831161091357829003601f168201915b5050505067ffffffffffffffff861660009081526007602052604090209192505060040161095f83858361318a565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf82858560405161099e939291906132a4565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610887565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006105ac600567ffffffffffffffff84166117f9565b6040805180820190915260608082526020820152610ae5610ae083613308565b611814565b610af282606001356119de565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b4c8460200160208101906104089190612a10565b81526040805160208181019092526000815291015292915050565b6060610b736002611a81565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105ac90611a8e565b67ffffffffffffffff811660009081526007602052604090206005018054606091906105dd90612f47565b610c806115c0565b73ffffffffffffffffffffffffffffffffffffffff8116610ccd576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610d616005611a81565b90506000815167ffffffffffffffff811115610d7f57610d7f612d9a565b604051908082528060200260200182016040528015610da8578160200160208202803683370190505b50905060005b8251811015610e0457828181518110610dc957610dc96133aa565b6020026020010151828281518110610de357610de36133aa565b67ffffffffffffffff90921660209283029190910190910152600101610dae565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105ac90611a8e565b610ee56115c0565b610ef0838383611b40565b505050565b610efd6115c0565b60005b81811015610ef0576000838383818110610f1c57610f1c6133aa565b9050602002810190610f2e91906133d9565b610f3790613417565b9050610f4c8160800151826020015115611c2a565b610f5f8160a00151826020015115611c2a565b80602001511561125b578051610f819060059067ffffffffffffffff16611d63565b610fc65780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610887565b6040810151511580610fdb5750606081015151155b15611012576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906111f390826134cb565b506060820151600582019061120890826134cb565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061124e94939291906135e5565b60405180910390a1611372565b80516112739060059067ffffffffffffffff16611d6f565b6112b85780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610887565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906113216004830182612963565b61132f600583016000612963565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101610f00565b6113836115c0565b61138c81611d7b565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146114245760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610887565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f6919061367e565b1561152d576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61153a8160200151611e70565b600061154982602001516105b2565b905080516000148061156d575080805190602001208260a001518051906020012014155b156115aa578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108879190612a8f565b6115bc82602001518360600151611f96565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611641576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610887565b565b7f000000000000000000000000000000000000000000000000000000000000000061169a576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156117305760008382815181106116ba576116ba6133aa565b602002602001015190506116d8816002611fdd90919063ffffffff16565b156117275760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010161169d565b5060005b8151811015610ef0576000828281518110611751576117516133aa565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361179557506117f1565b6117a0600282611fff565b156117ef5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611734565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146118a95760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610887565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197b919061367e565b156119b2576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119bf8160400151612021565b6119cc81602001516120a0565b61138c816020015182606001516121ee565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611a6657600080fd5b505af1158015611a7a573d6000803e3d6000fd5b5050505050565b6060600061180d83612232565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611b1c82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611b0091906136ca565b85608001516fffffffffffffffffffffffffffffffff1661228d565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611b4983610aa9565b611b8b576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610887565b611b96826000611c2a565b67ffffffffffffffff83166000908152600760205260409020611bb990836122b7565b611bc4816000611c2a565b67ffffffffffffffff83166000908152600760205260409020611bea90600201826122b7565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611c1d939291906136dd565b60405180910390a1505050565b815115611cf15781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611c80575060408201516fffffffffffffffffffffffffffffffff16155b15611cb957816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108879190613760565b80156115bc576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611d2a575060208201516fffffffffffffffffffffffffffffffff1615155b156115bc57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108879190613760565b600061180d8383612459565b600061180d83836124a8565b3373ffffffffffffffffffffffffffffffffffffffff821603611dfa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610887565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611e7981610aa9565b611ebb576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610887565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015611f3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5e919061367e565b61138c576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610887565b67ffffffffffffffff821660009081526007602052604090206115bc90600201827f000000000000000000000000000000000000000000000000000000000000000061259b565b600061180d8373ffffffffffffffffffffffffffffffffffffffff84166124a8565b600061180d8373ffffffffffffffffffffffffffffffffffffffff8416612459565b7f00000000000000000000000000000000000000000000000000000000000000001561138c5761205260028261291e565b61138c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610887565b6120a981610aa9565b6120eb576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610887565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612164573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612188919061379c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461138c576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610887565b67ffffffffffffffff821660009081526007602052604090206115bc90827f000000000000000000000000000000000000000000000000000000000000000061259b565b60608160000180548060200260200160405190810160405280929190818152602001828054801561065657602002820191906000526020600020905b81548152602001906001019080831161226e5750505050509050919050565b60006122ac8561229d84866137b9565b6122a790876137d0565b61294d565b90505b949350505050565b81546000906122e090700100000000000000000000000000000000900463ffffffff16426136ca565b905080156123825760018301548354612328916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661228d565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546123a8916fffffffffffffffffffffffffffffffff908116911661294d565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611c1d908490613760565b60008181526001830160205260408120546124a0575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105ac565b5060006105ac565b600081815260018301602052604081205480156125915760006124cc6001836136ca565b85549091506000906124e0906001906136ca565b9050818114612545576000866000018281548110612500576125006133aa565b9060005260206000200154905080876000018481548110612523576125236133aa565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612556576125566137e3565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105ac565b60009150506105ac565b825474010000000000000000000000000000000000000000900460ff1615806125c2575081155b156125cc57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061261290700100000000000000000000000000000000900463ffffffff16426136ca565b905080156126d25781831115612654576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461268e9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661228d565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156127895773ffffffffffffffffffffffffffffffffffffffff8416612731576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610887565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610887565b8483101561289c5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906127cd90826136ca565b6127d7878a6136ca565b6127e191906137d0565b6127eb9190613812565b905073ffffffffffffffffffffffffffffffffffffffff8616612844576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610887565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610887565b6128a685846136ca565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561180d565b600081831061295c578161180d565b5090919050565b50805461296f90612f47565b6000825580601f1061297f575050565b601f01602090049060005260206000209081019061138c91905b808211156129ad5760008155600101612999565b5090565b6000602082840312156129c357600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461180d57600080fd5b803567ffffffffffffffff81168114612a0b57600080fd5b919050565b600060208284031215612a2257600080fd5b61180d826129f3565b6000815180845260005b81811015612a5157602081850181015186830182015201612a35565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061180d6020830184612a2b565b73ffffffffffffffffffffffffffffffffffffffff8116811461138c57600080fd5b8035612a0b81612aa2565b600060208284031215612ae157600080fd5b813561180d81612aa2565b600060208284031215612afe57600080fd5b813567ffffffffffffffff811115612b1557600080fd5b8201610100818503121561180d57600080fd5b60008083601f840112612b3a57600080fd5b50813567ffffffffffffffff811115612b5257600080fd5b6020830191508360208260051b8501011115612b6d57600080fd5b9250929050565b60008060008060408587031215612b8a57600080fd5b843567ffffffffffffffff80821115612ba257600080fd5b612bae88838901612b28565b90965094506020870135915080821115612bc757600080fd5b50612bd487828801612b28565b95989497509550505050565b600080600060408486031215612bf557600080fd5b612bfe846129f3565b9250602084013567ffffffffffffffff80821115612c1b57600080fd5b818601915086601f830112612c2f57600080fd5b813581811115612c3e57600080fd5b876020828501011115612c5057600080fd5b6020830194508093505050509250925092565b600060208284031215612c7557600080fd5b813567ffffffffffffffff811115612c8c57600080fd5b820160a0818503121561180d57600080fd5b602081526000825160406020840152612cba6060840182612a2b565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612cf58282612a2b565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d4c57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612d1a565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d4c57835167ffffffffffffffff1683529284019291840191600101612d74565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612ded57612ded612d9a565b60405290565b60405160c0810167ffffffffffffffff81118282101715612ded57612ded612d9a565b801515811461138c57600080fd5b8035612a0b81612e16565b80356fffffffffffffffffffffffffffffffff81168114612a0b57600080fd5b600060608284031215612e6157600080fd5b6040516060810181811067ffffffffffffffff82111715612e8457612e84612d9a565b6040529050808235612e9581612e16565b8152612ea360208401612e2f565b6020820152612eb460408401612e2f565b60408201525092915050565b600080600060e08486031215612ed557600080fd5b612ede846129f3565b9250612eed8560208601612e4f565b9150612efc8560808601612e4f565b90509250925092565b60008060208385031215612f1857600080fd5b823567ffffffffffffffff811115612f2f57600080fd5b612f3b85828601612b28565b90969095509350505050565b600181811c90821680612f5b57607f821691505b602082108103612f94577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f830112612fab57600080fd5b813567ffffffffffffffff80821115612fc657612fc6612d9a565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561300c5761300c612d9a565b8160405283815286602085880101111561302557600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561305857600080fd5b613060612dc9565b823567ffffffffffffffff8082111561307857600080fd5b61308436838701612f9a565b8352613092602086016129f3565b60208401526130a360408601612ac4565b6040840152606085013560608401526130be60808601612ac4565b608084015260a08501359150808211156130d757600080fd5b6130e336838701612f9a565b60a084015260c08501359150808211156130fc57600080fd5b61310836838701612f9a565b60c084015260e085013591508082111561312157600080fd5b5061312e36828601612f9a565b60e08301525092915050565b601f821115610ef0576000816000526020600020601f850160051c810160208610156131635750805b601f850160051c820191505b818110156131825782815560010161316f565b505050505050565b67ffffffffffffffff8311156131a2576131a2612d9a565b6131b6836131b08354612f47565b8361313a565b6000601f84116001811461320857600085156131d25750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a7a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156132575786850135825560209485019460019092019101613237565b5086821015613292577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006132b76040830186612a2b565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561331a57600080fd5b60405160a0810167ffffffffffffffff828210818311171561333e5761333e612d9a565b81604052843591508082111561335357600080fd5b5061336036828601612f9a565b82525061336f602084016129f3565b6020820152604083013561338281612aa2565b604082015260608381013590820152608083013561339f81612aa2565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261340d57600080fd5b9190910192915050565b6000610140823603121561342a57600080fd5b613432612df3565b61343b836129f3565b815261344960208401612e24565b6020820152604083013567ffffffffffffffff8082111561346957600080fd5b61347536838701612f9a565b6040840152606085013591508082111561348e57600080fd5b5061349b36828601612f9a565b6060830152506134ae3660808501612e4f565b60808201526134c03660e08501612e4f565b60a082015292915050565b815167ffffffffffffffff8111156134e5576134e5612d9a565b6134f9816134f38454612f47565b8461313a565b602080601f83116001811461354c57600084156135165750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613182565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156135995788860151825594840194600190910190840161357a565b50858210156135d557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261360981840187612a2b565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506136479050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612cf5565b60006020828403121561369057600080fd5b815161180d81612e16565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105ac576105ac61369b565b67ffffffffffffffff8416815260e0810161372960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526122af565b606081016105ac82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156137ae57600080fd5b815161180d81612aa2565b80820281158282048414176105ac576105ac61369b565b808201808211156105ac576105ac61369b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613848577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b50604051620040883803806200408883398101604081905262000034916200054c565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000176565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001685760408051600081526020810190915262000168908462000221565b5050505050505050620006aa565b336001600160a01b03821603620001d05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000242576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002cd5760008382815181106200026657620002666200065c565b60209081029190910101519050620002806002826200037e565b15620002c3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000245565b5060005b815181101562000379576000828281518110620002f257620002f26200065c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200031e575062000370565b6200032b6002826200039e565b156200036e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d1565b505050565b600062000395836001600160a01b038416620003b5565b90505b92915050565b600062000395836001600160a01b038416620004b9565b60008181526001830160205260408120548015620004ae576000620003dc60018362000672565b8554909150600090620003f29060019062000672565b90508181146200045e5760008660000182815481106200041657620004166200065c565b90600052602060002001549050808760000184815481106200043c576200043c6200065c565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000472576200047262000694565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000398565b600091505062000398565b6000818152600183016020526040812054620005025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000398565b50600062000398565b6001600160a01b03811681146200052157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000547816200050b565b919050565b600080600080608085870312156200056357600080fd5b845162000570816200050b565b602086810151919550906001600160401b03808211156200059057600080fd5b818801915088601f830112620005a557600080fd5b815181811115620005ba57620005ba62000524565b8060051b604051601f19603f83011681018181108582111715620005e257620005e262000524565b60405291825284820192508381018501918b8311156200060157600080fd5b938501935b828510156200062a576200061a856200053a565b8452938501939285019262000606565b80985050505050505062000641604086016200053a565b915062000651606086016200053a565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161396162000727600039600081816104dd0152818161174c015261212a0152600081816104b70152818161157d0152611a020152600081816102390152818161028e015281816107010152818161149d0152818161192201528181611b14015281816120c0015261231501526139616000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ab8565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b17565b6105f9565b6040516101d29190612b96565b6101ee6040518060400160405280601b81526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e302d646576000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612bd6565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612bf3565b6106a9565b604051905181526020016101d2565b6103006102fb366004612c7b565b610804565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612ce7565b61087f565b6103006109f3565b610300610349366004612bd6565b610af0565b6101c661035c366004612b17565b610b3f565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d6a565b610b56565b6040516101d29190612da5565b6103a7610bfd565b6040516101d29190612e05565b6103c76103c2366004612b17565b610c0e565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b17565b610ce3565b610300610462366004612bd6565b610d0e565b61046f610de9565b6040516101d29190612e5f565b6103c761048a366004612b17565b610ea1565b61030061049d366004612fc7565b610f73565b6103006104b036600461300c565b610ffc565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612bd6565b611482565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061304e565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061304e565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361314c565b611496565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561075a57600080fd5b505af115801561076e573d6000803e3d6000fd5b50610783925050506060830160408401612bd6565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f084606001356040516107e591815260200190565b60405180910390a3506040805160208101909152606090910135815290565b61080c6116c7565b6108798484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061174a92505050565b50505050565b6108876116c7565b61089083610b3f565b6108d7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546108fe9061304e565b80601f016020809104026020016040519081016040528092919081815260200182805461092a9061304e565b80156109775780601f1061094c57610100808354040283529160200191610977565b820191906000526020600020905b81548152906001019060200180831161095a57829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109a6838583613291565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf8285856040516109e5939291906133ab565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108ce565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610af86116c7565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff8416611900565b6040805180820190915260608082526020820152610b7b610b768361340f565b61191b565b610b888260600135611ae5565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610be284602001602081019061044f9190612b17565b81526040805160208181019092526000815291015292915050565b6060610c096002611b88565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611b95565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061304e565b610d166116c7565b73ffffffffffffffffffffffffffffffffffffffff8116610d63576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610df76005611b88565b90506000815167ffffffffffffffff811115610e1557610e15612ea1565b604051908082528060200260200182016040528015610e3e578160200160208202803683370190505b50905060005b8251811015610e9a57828181518110610e5f57610e5f6134b1565b6020026020010151828281518110610e7957610e796134b1565b67ffffffffffffffff90921660209283029190910190910152600101610e44565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611b95565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fb3575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610fec576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108ce565b610ff7838383611c47565b505050565b6110046116c7565b60005b81811015610ff7576000838383818110611023576110236134b1565b905060200281019061103591906134e0565b61103e9061351e565b90506110538160800151826020015115611d31565b6110668160a00151826020015115611d31565b8060200151156113625780516110889060059067ffffffffffffffff16611e6a565b6110cd5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108ce565b60408101515115806110e25750606081015151155b15611119576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906112fa90826135d2565b506060820151600582019061130f90826135d2565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061135594939291906136ec565b60405180910390a1611479565b805161137a9060059067ffffffffffffffff16611e76565b6113bf5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108ce565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114286004830182612a6a565b611436600583016000612a6a565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611007565b61148a6116c7565b61149381611e82565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461152b5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108ce565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156115d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fd9190613785565b15611634576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116418160200151611f77565b600061165082602001516105f9565b9050805160001480611674575080805190602001208260a001518051906020012014155b156116b1578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108ce9190612b96565b6116c38260200151836060015161209d565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108ce565b565b7f00000000000000000000000000000000000000000000000000000000000000006117a1576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118375760008382815181106117c1576117c16134b1565b602002602001015190506117df8160026120e490919063ffffffff16565b1561182e5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117a4565b5060005b8151811015610ff7576000828281518110611858576118586134b1565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361189c57506118f8565b6118a7600282612106565b156118f65760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161183b565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119b05760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108ce565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a829190613785565b15611ab9576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ac68160400151612128565b611ad381602001516121a7565b611493816020015182606001516122f5565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611b6d57600080fd5b505af1158015611b81573d6000803e3d6000fd5b5050505050565b6060600061191483612339565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c2382606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c0791906137d1565b85608001516fffffffffffffffffffffffffffffffff16612394565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c5083610b3f565b611c92576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108ce565b611c9d826000611d31565b67ffffffffffffffff83166000908152600760205260409020611cc090836123be565b611ccb816000611d31565b67ffffffffffffffff83166000908152600760205260409020611cf190600201826123be565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d24939291906137e4565b60405180910390a1505050565b815115611df85781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611d87575060408201516fffffffffffffffffffffffffffffffff16155b15611dc057816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108ce9190613867565b80156116c3576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e31575060208201516fffffffffffffffffffffffffffffffff1615155b156116c357816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108ce9190613867565b60006119148383612560565b600061191483836125af565b3373ffffffffffffffffffffffffffffffffffffffff821603611f01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108ce565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611f8081610b3f565b611fc2576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108ce565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612041573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120659190613785565b611493576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108ce565b67ffffffffffffffff821660009081526007602052604090206116c390600201827f00000000000000000000000000000000000000000000000000000000000000006126a2565b60006119148373ffffffffffffffffffffffffffffffffffffffff84166125af565b60006119148373ffffffffffffffffffffffffffffffffffffffff8416612560565b7f00000000000000000000000000000000000000000000000000000000000000001561149357612159600282612a25565b611493576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108ce565b6121b081610b3f565b6121f2576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108ce565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561226b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228f91906138a3565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611493576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108ce565b67ffffffffffffffff821660009081526007602052604090206116c390827f00000000000000000000000000000000000000000000000000000000000000006126a2565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123755750505050509050919050565b60006123b3856123a484866138c0565b6123ae90876138d7565b612a54565b90505b949350505050565b81546000906123e790700100000000000000000000000000000000900463ffffffff16426137d1565b90508015612489576001830154835461242f916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612394565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124af916fffffffffffffffffffffffffffffffff9081169116612a54565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d24908490613867565b60008181526001830160205260408120546125a7575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126985760006125d36001836137d1565b85549091506000906125e7906001906137d1565b905081811461264c576000866000018281548110612607576126076134b1565b906000526020600020015490508087600001848154811061262a5761262a6134b1565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061265d5761265d6138ea565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126c9575081155b156126d357505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061271990700100000000000000000000000000000000900463ffffffff16426137d1565b905080156127d9578183111561275b576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127959083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612394565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128905773ffffffffffffffffffffffffffffffffffffffff8416612838576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108ce565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108ce565b848310156129a35760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128d490826137d1565b6128de878a6137d1565b6128e891906138d7565b6128f29190613919565b905073ffffffffffffffffffffffffffffffffffffffff861661294b576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108ce565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108ce565b6129ad85846137d1565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611914565b6000818310612a635781611914565b5090919050565b508054612a769061304e565b6000825580601f10612a86575050565b601f01602090049060005260206000209081019061149391905b80821115612ab45760008155600101612aa0565b5090565b600060208284031215612aca57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461191457600080fd5b803567ffffffffffffffff81168114612b1257600080fd5b919050565b600060208284031215612b2957600080fd5b61191482612afa565b6000815180845260005b81811015612b5857602081850181015186830182015201612b3c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119146020830184612b32565b73ffffffffffffffffffffffffffffffffffffffff8116811461149357600080fd5b8035612b1281612ba9565b600060208284031215612be857600080fd5b813561191481612ba9565b600060208284031215612c0557600080fd5b813567ffffffffffffffff811115612c1c57600080fd5b8201610100818503121561191457600080fd5b60008083601f840112612c4157600080fd5b50813567ffffffffffffffff811115612c5957600080fd5b6020830191508360208260051b8501011115612c7457600080fd5b9250929050565b60008060008060408587031215612c9157600080fd5b843567ffffffffffffffff80821115612ca957600080fd5b612cb588838901612c2f565b90965094506020870135915080821115612cce57600080fd5b50612cdb87828801612c2f565b95989497509550505050565b600080600060408486031215612cfc57600080fd5b612d0584612afa565b9250602084013567ffffffffffffffff80821115612d2257600080fd5b818601915086601f830112612d3657600080fd5b813581811115612d4557600080fd5b876020828501011115612d5757600080fd5b6020830194508093505050509250925092565b600060208284031215612d7c57600080fd5b813567ffffffffffffffff811115612d9357600080fd5b820160a0818503121561191457600080fd5b602081526000825160406020840152612dc16060840182612b32565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612dfc8282612b32565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e5357835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e21565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e5357835167ffffffffffffffff1683529284019291840191600101612e7b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612ef457612ef4612ea1565b60405290565b60405160c0810167ffffffffffffffff81118282101715612ef457612ef4612ea1565b801515811461149357600080fd5b8035612b1281612f1d565b80356fffffffffffffffffffffffffffffffff81168114612b1257600080fd5b600060608284031215612f6857600080fd5b6040516060810181811067ffffffffffffffff82111715612f8b57612f8b612ea1565b6040529050808235612f9c81612f1d565b8152612faa60208401612f36565b6020820152612fbb60408401612f36565b60408201525092915050565b600080600060e08486031215612fdc57600080fd5b612fe584612afa565b9250612ff48560208601612f56565b91506130038560808601612f56565b90509250925092565b6000806020838503121561301f57600080fd5b823567ffffffffffffffff81111561303657600080fd5b61304285828601612c2f565b90969095509350505050565b600181811c9082168061306257607f821691505b60208210810361309b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130b257600080fd5b813567ffffffffffffffff808211156130cd576130cd612ea1565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561311357613113612ea1565b8160405283815286602085880101111561312c57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561315f57600080fd5b613167612ed0565b823567ffffffffffffffff8082111561317f57600080fd5b61318b368387016130a1565b835261319960208601612afa565b60208401526131aa60408601612bcb565b6040840152606085013560608401526131c560808601612bcb565b608084015260a08501359150808211156131de57600080fd5b6131ea368387016130a1565b60a084015260c085013591508082111561320357600080fd5b61320f368387016130a1565b60c084015260e085013591508082111561322857600080fd5b50613235368286016130a1565b60e08301525092915050565b601f821115610ff7576000816000526020600020601f850160051c8101602086101561326a5750805b601f850160051c820191505b8181101561328957828155600101613276565b505050505050565b67ffffffffffffffff8311156132a9576132a9612ea1565b6132bd836132b7835461304e565b83613241565b6000601f84116001811461330f57600085156132d95750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611b81565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561335e578685013582556020948501946001909201910161333e565b5086821015613399577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133be6040830186612b32565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561342157600080fd5b60405160a0810167ffffffffffffffff828210818311171561344557613445612ea1565b81604052843591508082111561345a57600080fd5b50613467368286016130a1565b82525061347660208401612afa565b6020820152604083013561348981612ba9565b60408201526060838101359082015260808301356134a681612ba9565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261351457600080fd5b9190910192915050565b6000610140823603121561353157600080fd5b613539612efa565b61354283612afa565b815261355060208401612f2b565b6020820152604083013567ffffffffffffffff8082111561357057600080fd5b61357c368387016130a1565b6040840152606085013591508082111561359557600080fd5b506135a2368286016130a1565b6060830152506135b53660808501612f56565b60808201526135c73660e08501612f56565b60a082015292915050565b815167ffffffffffffffff8111156135ec576135ec612ea1565b613600816135fa845461304e565b84613241565b602080601f831160018114613653576000841561361d5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613289565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136a057888601518255948401946001909101908401613681565b50858210156136dc57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261371081840187612b32565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061374e9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612dfc565b60006020828403121561379757600080fd5b815161191481612f1d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137a2565b67ffffffffffffffff8416815260e0810161383060208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123b6565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138b557600080fd5b815161191481612ba9565b80820281158282048414176105f3576105f36137a2565b808201808211156105f3576105f36137a2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261394f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var BurnMintTokenPoolABI = BurnMintTokenPoolMetaData.ABI @@ -310,6 +310,28 @@ func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetCurrentOutboundRate return _BurnMintTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_BurnMintTokenPool.CallOpts, remoteChainSelector) } +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getRateLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetRateLimitAdmin() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetRateLimitAdmin(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetRateLimitAdmin() (common.Address, error) { + return _BurnMintTokenPool.Contract.GetRateLimitAdmin(&_BurnMintTokenPool.CallOpts) +} + func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { var out []interface{} err := _BurnMintTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) @@ -624,6 +646,18 @@ func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetChainRateLimite return _BurnMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetRateLimitAdmin(&_BurnMintTokenPool.TransactOpts, rateLimitAdmin) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetRateLimitAdmin(&_BurnMintTokenPool.TransactOpts, rateLimitAdmin) +} + func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { return _BurnMintTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) } @@ -2644,6 +2678,8 @@ type BurnMintTokenPoolInterface interface { GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) @@ -2678,6 +2714,8 @@ type BurnMintTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go index b7ef316764..2c24ff0c6c 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go @@ -82,8 +82,8 @@ type TokenPoolChainUpdate struct { } var BurnMintTokenPoolAndProxyMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b506040516200481e3803806200481e833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050818114620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c0516140e862000736600039600081816104bc0152818161197001526123c2015260008181610496015281816117080152611c23015260008181610210015281816102650152818161071901528181610d040152818161162801528181611b4301528181611d290152818161235801526125ad01526140e86000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80639a4575b9116100f9578063c4bffe2b11610097578063db6327dc11610071578063db6327dc14610481578063dc0bd97114610494578063e0351e13146104ba578063f2fde38b146104e057600080fd5b8063c4bffe2b14610446578063c75eea9c1461045b578063cf7401f31461046e57600080fd5b8063af58d59f116100d3578063af58d59f14610393578063b0f479a114610402578063b794658014610420578063c0d786551461043357600080fd5b80639a4575b91461034b578063a7cd63b71461036b578063a8d87a3b1461038057600080fd5b806354c8a4f31161016657806383826b2b1161014057806383826b2b146102f45780638926f54f146103075780638da5cb5b1461031a5780639766b9321461033857600080fd5b806354c8a4f3146102c457806378a010b2146102d957806379ba5097146102ec57600080fd5b806321df0da71161019757806321df0da71461020e578063240028e81461025557806339077537146102a257600080fd5b806301ffc9a7146101be5780630a2fd493146101e6578063181f5a7714610206575b600080fd5b6101d16101cc36600461305a565b6104f3565b60405190151581526020015b60405180910390f35b6101f96101f43660046130b9565b6105d8565b6040516101dd9190613142565b6101f9610688565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101dd565b6101d1610263366004613182565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102b56102b036600461319f565b6106a4565b604051905181526020016101dd565b6102d76102d2366004613227565b610831565b005b6102d76102e7366004613293565b6108ac565b6102d7610a20565b6101d1610302366004613316565b610b1d565b6101d16103153660046130b9565b610bea565b60005473ffffffffffffffffffffffffffffffffffffffff16610230565b6102d7610346366004613182565b610c01565b61035e61035936600461334d565b610c90565b6040516101dd9190613388565b610373610e00565b6040516101dd91906133e8565b61023061038e3660046130b9565b503090565b6103a66103a13660046130b9565b610e11565b6040516101dd919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610230565b6101f961042e3660046130b9565b610ee6565b6102d7610441366004613182565b610f11565b61044e610fe5565b6040516101dd9190613442565b6103a66104693660046130b9565b61109d565b6102d761047c3660046135f9565b61116f565b6102d761048f36600461363e565b611187565b7f0000000000000000000000000000000000000000000000000000000000000000610230565b7f00000000000000000000000000000000000000000000000000000000000000006101d1565b6102d76104ee366004613182565b61160d565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061058657507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105d257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061060390613680565b80601f016020809104026020016040519081016040528092919081815260200182805461062f90613680565b801561067c5780601f106106515761010080835404028352916020019161067c565b820191906000526020600020905b81548152906001019060200180831161065f57829003601f168201915b50505050509050919050565b6040518060600160405280602381526020016140b96023913981565b6040805160208101909152600081526106c46106bf8361376f565b611621565b60085473ffffffffffffffffffffffffffffffffffffffff1661078f576040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561077257600080fd5b505af1158015610786573d6000803e3d6000fd5b505050506107a0565b6107a061079b8361376f565b611852565b6107b06060830160408401613182565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081291815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108396118eb565b6108a68484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061196e92505050565b50505050565b6108b46118eb565b6108bd83610bea565b610904576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461092b90613680565b80601f016020809104026020016040519081016040528092919081815260200182805461095790613680565b80156109a45780601f10610979576101008083540402835291602001916109a4565b820191906000526020600020905b81548152906001019060200180831161098757829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d38385836138b4565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a12939291906139ce565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610aa1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108fb565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610be35750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610bbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be39190613a32565b9392505050565b60006105d2600567ffffffffffffffff8416611b24565b610c096118eb565b6008805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610cb5610cb083613a4f565b611b3c565b60085473ffffffffffffffffffffffffffffffffffffffff16610d7a576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610d5d57600080fd5b505af1158015610d71573d6000803e3d6000fd5b50505050610d8b565b610d8b610d8683613a4f565b611d06565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610de584602001602081019061042e91906130b9565b81526040805160208181019092526000815291015292915050565b6060610e0c6002611e20565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105d290611e2d565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061060390613680565b610f196118eb565b73ffffffffffffffffffffffffffffffffffffffff8116610f66576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610c84565b60606000610ff36005611e20565b90506000815167ffffffffffffffff81111561101157611011613484565b60405190808252806020026020018201604052801561103a578160200160208202803683370190505b50905060005b82518110156110965782818151811061105b5761105b613af1565b602002602001015182828151811061107557611075613af1565b67ffffffffffffffff90921660209283029190910190910152600101611040565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105d290611e2d565b6111776118eb565b611182838383611edf565b505050565b61118f6118eb565b60005b818110156111825760008383838181106111ae576111ae613af1565b90506020028101906111c09190613b20565b6111c990613b5e565b90506111de8160800151826020015115611fc9565b6111f18160a00151826020015115611fc9565b8060200151156114ed5780516112139060059067ffffffffffffffff16612102565b6112585780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108fb565b604081015151158061126d5750606081015151155b156112a4576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906114859082613c12565b506060820151600582019061149a9082613c12565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506114e09493929190613d2c565b60405180910390a1611604565b80516115059060059067ffffffffffffffff1661210e565b61154a5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108fb565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906115b3600483018261300c565b6115c160058301600061300c565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611192565b6116156118eb565b61161e8161211a565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146116b65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108fb565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611764573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117889190613a32565b156117bf576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6117cc816020015161220f565b60006117db82602001516105d8565b90508051600014806117ff575080805190602001208260a001518051906020012014155b1561183c578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108fb9190613142565b61184e82602001518360600151612335565b5050565b6008548151606083015160208401516040517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90941693638627fad6936118b69390923392600401613dc5565b600060405180830381600087803b1580156118d057600080fd5b505af11580156118e4573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461196c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108fb565b565b7f00000000000000000000000000000000000000000000000000000000000000006119c5576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611a5b5760008382815181106119e5576119e5613af1565b60200260200101519050611a0381600261237c90919063ffffffff16565b15611a525760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016119c8565b5060005b8151811015611182576000828281518110611a7c57611a7c613af1565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ac05750611b1c565b611acb60028261239e565b15611b1a5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611a5f565b60008181526001830160205260408120541515610be3565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611bd15760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108fb565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611c7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca39190613a32565b15611cda576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ce781604001516123c0565b611cf4816020015161243f565b61161e8160200151826060015161258d565b6008546060820151611d539173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116929116906125d1565b60085460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611dbb94939291600401613e26565b6000604051808303816000875af1158015611dda573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261184e9190810190613e86565b60606000610be38361265e565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611ebb82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611e9f9190613f23565b85608001516fffffffffffffffffffffffffffffffff166126b9565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611ee883610bea565b611f2a576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108fb565b611f35826000611fc9565b67ffffffffffffffff83166000908152600760205260409020611f5890836126e3565b611f63816000611fc9565b67ffffffffffffffff83166000908152600760205260409020611f8990600201826126e3565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611fbc93929190613f36565b60405180910390a1505050565b8151156120905781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061201f575060408201516fffffffffffffffffffffffffffffffff16155b1561205857816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108fb9190613fb9565b801561184e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806120c9575060208201516fffffffffffffffffffffffffffffffff1615155b1561184e57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108fb9190613fb9565b6000610be38383612885565b6000610be383836128d4565b3373ffffffffffffffffffffffffffffffffffffffff821603612199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108fb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61221881610bea565b61225a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108fb565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156122d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122fd9190613a32565b61161e576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108fb565b67ffffffffffffffff8216600090815260076020526040902061184e90600201827f00000000000000000000000000000000000000000000000000000000000000006129c7565b6000610be38373ffffffffffffffffffffffffffffffffffffffff84166128d4565b6000610be38373ffffffffffffffffffffffffffffffffffffffff8416612885565b7f00000000000000000000000000000000000000000000000000000000000000001561161e576123f1600282612d4a565b61161e576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108fb565b61244881610bea565b61248a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108fb565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612503573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125279190613ff5565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461161e576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108fb565b67ffffffffffffffff8216600090815260076020526040902061184e90827f00000000000000000000000000000000000000000000000000000000000000006129c7565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611182908490612d79565b60608160000180548060200260200160405190810160405280929190818152602001828054801561067c57602002820191906000526020600020905b81548152602001906001019080831161269a5750505050509050919050565b60006126d8856126c98486614012565b6126d39087614029565b612e85565b90505b949350505050565b815460009061270c90700100000000000000000000000000000000900463ffffffff1642613f23565b905080156127ae5760018301548354612754916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166126b9565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546127d4916fffffffffffffffffffffffffffffffff9081169116612e85565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611fbc908490613fb9565b60008181526001830160205260408120546128cc575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105d2565b5060006105d2565b600081815260018301602052604081205480156129bd5760006128f8600183613f23565b855490915060009061290c90600190613f23565b905081811461297157600086600001828154811061292c5761292c613af1565b906000526020600020015490508087600001848154811061294f5761294f613af1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806129825761298261403c565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105d2565b60009150506105d2565b825474010000000000000000000000000000000000000000900460ff1615806129ee575081155b156129f857505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612a3e90700100000000000000000000000000000000900463ffffffff1642613f23565b90508015612afe5781831115612a80576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612aba9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166126b9565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612bb55773ffffffffffffffffffffffffffffffffffffffff8416612b5d576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108fb565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108fb565b84831015612cc85760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612bf99082613f23565b612c03878a613f23565b612c0d9190614029565b612c17919061406b565b905073ffffffffffffffffffffffffffffffffffffffff8616612c70576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108fb565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108fb565b612cd28584613f23565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610be3565b6000612ddb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612e9b9092919063ffffffff16565b8051909150156111825780806020019051810190612df99190613a32565b611182576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108fb565b6000818310612e945781610be3565b5090919050565b60606126db8484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051612ecf91906140a6565b60006040518083038185875af1925050503d8060008114612f0c576040519150601f19603f3d011682016040523d82523d6000602084013e612f11565b606091505b5091509150612f2287838387612f2d565b979650505050505050565b60608315612fc3578251600003612fbc5773ffffffffffffffffffffffffffffffffffffffff85163b612fbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108fb565b50816126db565b6126db8383815115612fd85781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108fb9190613142565b50805461301890613680565b6000825580601f10613028575050565b601f01602090049060005260206000209081019061161e91905b808211156130565760008155600101613042565b5090565b60006020828403121561306c57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610be357600080fd5b803567ffffffffffffffff811681146130b457600080fd5b919050565b6000602082840312156130cb57600080fd5b610be38261309c565b60005b838110156130ef5781810151838201526020016130d7565b50506000910152565b600081518084526131108160208601602086016130d4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610be360208301846130f8565b73ffffffffffffffffffffffffffffffffffffffff8116811461161e57600080fd5b80356130b481613155565b60006020828403121561319457600080fd5b8135610be381613155565b6000602082840312156131b157600080fd5b813567ffffffffffffffff8111156131c857600080fd5b82016101008185031215610be357600080fd5b60008083601f8401126131ed57600080fd5b50813567ffffffffffffffff81111561320557600080fd5b6020830191508360208260051b850101111561322057600080fd5b9250929050565b6000806000806040858703121561323d57600080fd5b843567ffffffffffffffff8082111561325557600080fd5b613261888389016131db565b9096509450602087013591508082111561327a57600080fd5b50613287878288016131db565b95989497509550505050565b6000806000604084860312156132a857600080fd5b6132b18461309c565b9250602084013567ffffffffffffffff808211156132ce57600080fd5b818601915086601f8301126132e257600080fd5b8135818111156132f157600080fd5b87602082850101111561330357600080fd5b6020830194508093505050509250925092565b6000806040838503121561332957600080fd5b6133328361309c565b9150602083013561334281613155565b809150509250929050565b60006020828403121561335f57600080fd5b813567ffffffffffffffff81111561337657600080fd5b820160a08185031215610be357600080fd5b6020815260008251604060208401526133a460608401826130f8565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526133df82826130f8565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561343657835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613404565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561343657835167ffffffffffffffff168352928401929184019160010161345e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156134d7576134d7613484565b60405290565b60405160c0810167ffffffffffffffff811182821017156134d7576134d7613484565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561354757613547613484565b604052919050565b801515811461161e57600080fd5b80356130b48161354f565b80356fffffffffffffffffffffffffffffffff811681146130b457600080fd5b60006060828403121561359a57600080fd5b6040516060810181811067ffffffffffffffff821117156135bd576135bd613484565b60405290508082356135ce8161354f565b81526135dc60208401613568565b60208201526135ed60408401613568565b60408201525092915050565b600080600060e0848603121561360e57600080fd5b6136178461309c565b92506136268560208601613588565b91506136358560808601613588565b90509250925092565b6000806020838503121561365157600080fd5b823567ffffffffffffffff81111561366857600080fd5b613674858286016131db565b90969095509350505050565b600181811c9082168061369457607f821691505b6020821081036136cd577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff8211156136ed576136ed613484565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261372a57600080fd5b813561373d613738826136d3565b613500565b81815284602083860101111561375257600080fd5b816020850160208301376000918101602001919091529392505050565b6000610100823603121561378257600080fd5b61378a6134b3565b823567ffffffffffffffff808211156137a257600080fd5b6137ae36838701613719565b83526137bc6020860161309c565b60208401526137cd60408601613177565b6040840152606085013560608401526137e860808601613177565b608084015260a085013591508082111561380157600080fd5b61380d36838701613719565b60a084015260c085013591508082111561382657600080fd5b61383236838701613719565b60c084015260e085013591508082111561384b57600080fd5b5061385836828601613719565b60e08301525092915050565b601f821115611182576000816000526020600020601f850160051c8101602086101561388d5750805b601f850160051c820191505b818110156138ac57828155600101613899565b505050505050565b67ffffffffffffffff8311156138cc576138cc613484565b6138e0836138da8354613680565b83613864565b6000601f84116001811461393257600085156138fc5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556118e4565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156139815786850135825560209485019460019092019101613961565b50868210156139bc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006139e160408301866130f8565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613a4457600080fd5b8151610be38161354f565b600060a08236031215613a6157600080fd5b60405160a0810167ffffffffffffffff8282108183111715613a8557613a85613484565b816040528435915080821115613a9a57600080fd5b50613aa736828601613719565b825250613ab66020840161309c565b60208201526040830135613ac981613155565b6040820152606083810135908201526080830135613ae681613155565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613b5457600080fd5b9190910192915050565b60006101408236031215613b7157600080fd5b613b796134dd565b613b828361309c565b8152613b906020840161355d565b6020820152604083013567ffffffffffffffff80821115613bb057600080fd5b613bbc36838701613719565b60408401526060850135915080821115613bd557600080fd5b50613be236828601613719565b606083015250613bf53660808501613588565b6080820152613c073660e08501613588565b60a082015292915050565b815167ffffffffffffffff811115613c2c57613c2c613484565b613c4081613c3a8454613680565b84613864565b602080601f831160018114613c935760008415613c5d5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556138ac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613ce057888601518255948401946001909101908401613cc1565b5085821015613d1c57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613d50818401876130f8565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613d8e9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526133df565b60a081526000613dd860a08301876130f8565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613e5560a08301866130f8565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613e9857600080fd5b815167ffffffffffffffff811115613eaf57600080fd5b8201601f81018413613ec057600080fd5b8051613ece613738826136d3565b818152856020838501011115613ee357600080fd5b6133df8260208301602086016130d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105d2576105d2613ef4565b67ffffffffffffffff8416815260e08101613f8260208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526126db565b606081016105d282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561400757600080fd5b8151610be381613155565b80820281158282048414176105d2576105d2613ef4565b808201808211156105d2576105d2613ef4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826140a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613b548184602087016130d456fe4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b506040516200492538038062004925833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050818114620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c0516141ef620007366000396000818161050301528181611a7701526124c90152600081816104dd0152818161180f0152611d2a0152600081816102260152818161027b0152818161076001528181610d9a0152818161172f01528181611c4a01528181611e300152818161245f01526126b401526141ef6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639766b93211610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104c8578063dc0bd971146104db578063e0351e1314610501578063f2fde38b1461052757600080fd5b8063c0d786551461047a578063c4bffe2b1461048d578063c75eea9c146104a2578063cf7401f3146104b557600080fd5b8063a8d87a3b116100de578063a8d87a3b146103c7578063af58d59f146103da578063b0f479a114610449578063b79465801461046757600080fd5b80639766b9321461037f5780639a4575b914610392578063a7cd63b7146103b257600080fd5b80636d3d1a58116101715780637d54534e1161014b5780637d54534e1461032857806383826b2b1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b80636d3d1a58146102ef57806378a010b21461030d57806379ba50971461032057600080fd5b806321df0da7116101ad57806321df0da714610224578063240028e81461026b57806339077537146102b857806354c8a4f3146102da57600080fd5b806301ffc9a7146101d45780630a2fd493146101fc578063181f5a771461021c575b600080fd5b6101e76101e2366004613161565b61053a565b60405190151581526020015b60405180910390f35b61020f61020a3660046131c0565b61061f565b6040516101f39190613249565b61020f6106cf565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e7610279366004613289565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102cb6102c63660046132a6565b6106eb565b604051905181526020016101f3565b6102ed6102e836600461332e565b610878565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61031b36600461339a565b6108f3565b6102ed610a67565b6102ed610336366004613289565b610b64565b6101e761034936600461341d565b610bb3565b6101e761035c3660046131c0565b610c80565b60005473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61038d366004613289565b610c97565b6103a56103a0366004613454565b610d26565b6040516101f3919061348f565b6103ba610e96565b6040516101f391906134ef565b6102466103d53660046131c0565b503090565b6103ed6103e83660046131c0565b610ea7565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610246565b61020f6104753660046131c0565b610f7c565b6102ed610488366004613289565b610fa7565b61049561107b565b6040516101f39190613549565b6103ed6104b03660046131c0565b611133565b6102ed6104c3366004613700565b611205565b6102ed6104d6366004613745565b61128e565b7f0000000000000000000000000000000000000000000000000000000000000000610246565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b6102ed610535366004613289565b611714565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105cd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061061957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061064a90613787565b80601f016020809104026020016040519081016040528092919081815260200182805461067690613787565b80156106c35780601f10610698576101008083540402835291602001916106c3565b820191906000526020600020905b8154815290600101906020018083116106a657829003601f168201915b50505050509050919050565b6040518060600160405280602381526020016141c06023913981565b60408051602081019091526000815261070b61070683613876565b611728565b60095473ffffffffffffffffffffffffffffffffffffffff166107d6576040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b1580156107b957600080fd5b505af11580156107cd573d6000803e3d6000fd5b505050506107e7565b6107e76107e283613876565b611959565b6107f76060830160408401613289565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161085991815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108806119f2565b6108ed84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611a7592505050565b50505050565b6108fb6119f2565b61090483610c80565b61094b576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461097290613787565b80601f016020809104026020016040519081016040528092919081815260200182805461099e90613787565b80156109eb5780601f106109c0576101008083540402835291602001916109eb565b820191906000526020600020905b8154815290600101906020018083116109ce57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a1a8385836139bb565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a5993929190613ad5565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ae8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610942565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b6c6119f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610c795750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c799190613b39565b9392505050565b6000610619600567ffffffffffffffff8416611c2b565b610c9f6119f2565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d4b610d4683613b56565b611c43565b60095473ffffffffffffffffffffffffffffffffffffffff16610e10576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610df357600080fd5b505af1158015610e07573d6000803e3d6000fd5b50505050610e21565b610e21610e1c83613b56565b611e0d565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610e7b84602001602081019061047591906131c0565b81526040805160208181019092526000815291015292915050565b6060610ea26002611f27565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261061990611f34565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061064a90613787565b610faf6119f2565b73ffffffffffffffffffffffffffffffffffffffff8116610ffc576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d1a565b606060006110896005611f27565b90506000815167ffffffffffffffff8111156110a7576110a761358b565b6040519080825280602002602001820160405280156110d0578160200160208202803683370190505b50905060005b825181101561112c578281815181106110f1576110f1613bf8565b602002602001015182828151811061110b5761110b613bf8565b67ffffffffffffffff909216602092830291909101909101526001016110d6565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261061990611f34565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611245575060005473ffffffffffffffffffffffffffffffffffffffff163314155b1561127e576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610942565b611289838383611fe6565b505050565b6112966119f2565b60005b818110156112895760008383838181106112b5576112b5613bf8565b90506020028101906112c79190613c27565b6112d090613c65565b90506112e581608001518260200151156120d0565b6112f88160a001518260200151156120d0565b8060200151156115f457805161131a9060059067ffffffffffffffff16612209565b61135f5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610942565b60408101515115806113745750606081015151155b156113ab576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061158c9082613d19565b50606082015160058201906115a19082613d19565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506115e79493929190613e33565b60405180910390a161170b565b805161160c9060059067ffffffffffffffff16612215565b6116515780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610942565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116ba6004830182613113565b6116c8600583016000613113565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611299565b61171c6119f2565b61172581612221565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146117bd5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610942565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561186b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188f9190613b39565b156118c6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d38160200151612316565b60006118e2826020015161061f565b9050805160001480611906575080805190602001208260a001518051906020012014155b15611943578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109429190613249565b6119558260200151836060015161243c565b5050565b6009548151606083015160208401516040517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90941693638627fad6936119bd9390923392600401613ecc565b600060405180830381600087803b1580156119d757600080fd5b505af11580156119eb573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610942565b565b7f0000000000000000000000000000000000000000000000000000000000000000611acc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611b62576000838281518110611aec57611aec613bf8565b60200260200101519050611b0a81600261248390919063ffffffff16565b15611b595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611acf565b5060005b8151811015611289576000828281518110611b8357611b83613bf8565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bc75750611c23565b611bd26002826124a5565b15611c215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611b66565b60008181526001830160205260408120541515610c79565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611cd85760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610942565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611daa9190613b39565b15611de1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dee81604001516124c7565b611dfb8160200151612546565b61172581602001518260600151612694565b6009546060820151611e5a9173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116929116906126d8565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611ec294939291600401613f2d565b6000604051808303816000875af1158015611ee1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119559190810190613f8d565b60606000610c7983612765565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611fc282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611fa6919061402a565b85608001516fffffffffffffffffffffffffffffffff166127c0565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611fef83610c80565b612031576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610942565b61203c8260006120d0565b67ffffffffffffffff8316600090815260076020526040902061205f90836127ea565b61206a8160006120d0565b67ffffffffffffffff8316600090815260076020526040902061209090600201826127ea565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516120c39392919061403d565b60405180910390a1505050565b8151156121975781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612126575060408201516fffffffffffffffffffffffffffffffff16155b1561215f57816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161094291906140c0565b8015611955576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806121d0575060208201516fffffffffffffffffffffffffffffffff1615155b1561195557816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161094291906140c0565b6000610c79838361298c565b6000610c7983836129db565b3373ffffffffffffffffffffffffffffffffffffffff8216036122a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610942565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61231f81610c80565b612361576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610942565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156123e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124049190613b39565b611725576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610942565b67ffffffffffffffff8216600090815260076020526040902061195590600201827f0000000000000000000000000000000000000000000000000000000000000000612ace565b6000610c798373ffffffffffffffffffffffffffffffffffffffff84166129db565b6000610c798373ffffffffffffffffffffffffffffffffffffffff841661298c565b7f000000000000000000000000000000000000000000000000000000000000000015611725576124f8600282612e51565b611725576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610942565b61254f81610c80565b612591576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610942565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561260a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262e91906140fc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611725576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610942565b67ffffffffffffffff8216600090815260076020526040902061195590827f0000000000000000000000000000000000000000000000000000000000000000612ace565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611289908490612e80565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106c357602002820191906000526020600020905b8154815260200190600101908083116127a15750505050509050919050565b60006127df856127d08486614119565b6127da9087614130565b612f8c565b90505b949350505050565b815460009061281390700100000000000000000000000000000000900463ffffffff164261402a565b905080156128b5576001830154835461285b916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166127c0565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546128db916fffffffffffffffffffffffffffffffff9081169116612f8c565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906120c39084906140c0565b60008181526001830160205260408120546129d357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610619565b506000610619565b60008181526001830160205260408120548015612ac45760006129ff60018361402a565b8554909150600090612a139060019061402a565b9050818114612a78576000866000018281548110612a3357612a33613bf8565b9060005260206000200154905080876000018481548110612a5657612a56613bf8565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612a8957612a89614143565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610619565b6000915050610619565b825474010000000000000000000000000000000000000000900460ff161580612af5575081155b15612aff57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612b4590700100000000000000000000000000000000900463ffffffff164261402a565b90508015612c055781831115612b87576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612bc19083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166127c0565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612cbc5773ffffffffffffffffffffffffffffffffffffffff8416612c64576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610942565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610942565b84831015612dcf5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612d00908261402a565b612d0a878a61402a565b612d149190614130565b612d1e9190614172565b905073ffffffffffffffffffffffffffffffffffffffff8616612d77576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610942565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610942565b612dd9858461402a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610c79565b6000612ee2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612fa29092919063ffffffff16565b8051909150156112895780806020019051810190612f009190613b39565b611289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610942565b6000818310612f9b5781610c79565b5090919050565b60606127e28484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051612fd691906141ad565b60006040518083038185875af1925050503d8060008114613013576040519150601f19603f3d011682016040523d82523d6000602084013e613018565b606091505b509150915061302987838387613034565b979650505050505050565b606083156130ca5782516000036130c35773ffffffffffffffffffffffffffffffffffffffff85163b6130c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610942565b50816127e2565b6127e283838151156130df5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109429190613249565b50805461311f90613787565b6000825580601f1061312f575050565b601f01602090049060005260206000209081019061172591905b8082111561315d5760008155600101613149565b5090565b60006020828403121561317357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610c7957600080fd5b803567ffffffffffffffff811681146131bb57600080fd5b919050565b6000602082840312156131d257600080fd5b610c79826131a3565b60005b838110156131f65781810151838201526020016131de565b50506000910152565b600081518084526132178160208601602086016131db565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610c7960208301846131ff565b73ffffffffffffffffffffffffffffffffffffffff8116811461172557600080fd5b80356131bb8161325c565b60006020828403121561329b57600080fd5b8135610c798161325c565b6000602082840312156132b857600080fd5b813567ffffffffffffffff8111156132cf57600080fd5b82016101008185031215610c7957600080fd5b60008083601f8401126132f457600080fd5b50813567ffffffffffffffff81111561330c57600080fd5b6020830191508360208260051b850101111561332757600080fd5b9250929050565b6000806000806040858703121561334457600080fd5b843567ffffffffffffffff8082111561335c57600080fd5b613368888389016132e2565b9096509450602087013591508082111561338157600080fd5b5061338e878288016132e2565b95989497509550505050565b6000806000604084860312156133af57600080fd5b6133b8846131a3565b9250602084013567ffffffffffffffff808211156133d557600080fd5b818601915086601f8301126133e957600080fd5b8135818111156133f857600080fd5b87602082850101111561340a57600080fd5b6020830194508093505050509250925092565b6000806040838503121561343057600080fd5b613439836131a3565b915060208301356134498161325c565b809150509250929050565b60006020828403121561346657600080fd5b813567ffffffffffffffff81111561347d57600080fd5b820160a08185031215610c7957600080fd5b6020815260008251604060208401526134ab60608401826131ff565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526134e682826131ff565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561353d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161350b565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561353d57835167ffffffffffffffff1683529284019291840191600101613565565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156135de576135de61358b565b60405290565b60405160c0810167ffffffffffffffff811182821017156135de576135de61358b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561364e5761364e61358b565b604052919050565b801515811461172557600080fd5b80356131bb81613656565b80356fffffffffffffffffffffffffffffffff811681146131bb57600080fd5b6000606082840312156136a157600080fd5b6040516060810181811067ffffffffffffffff821117156136c4576136c461358b565b60405290508082356136d581613656565b81526136e36020840161366f565b60208201526136f46040840161366f565b60408201525092915050565b600080600060e0848603121561371557600080fd5b61371e846131a3565b925061372d856020860161368f565b915061373c856080860161368f565b90509250925092565b6000806020838503121561375857600080fd5b823567ffffffffffffffff81111561376f57600080fd5b61377b858286016132e2565b90969095509350505050565b600181811c9082168061379b57607f821691505b6020821081036137d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff8211156137f4576137f461358b565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261383157600080fd5b813561384461383f826137da565b613607565b81815284602083860101111561385957600080fd5b816020850160208301376000918101602001919091529392505050565b6000610100823603121561388957600080fd5b6138916135ba565b823567ffffffffffffffff808211156138a957600080fd5b6138b536838701613820565b83526138c3602086016131a3565b60208401526138d46040860161327e565b6040840152606085013560608401526138ef6080860161327e565b608084015260a085013591508082111561390857600080fd5b61391436838701613820565b60a084015260c085013591508082111561392d57600080fd5b61393936838701613820565b60c084015260e085013591508082111561395257600080fd5b5061395f36828601613820565b60e08301525092915050565b601f821115611289576000816000526020600020601f850160051c810160208610156139945750805b601f850160051c820191505b818110156139b3578281556001016139a0565b505050505050565b67ffffffffffffffff8311156139d3576139d361358b565b6139e7836139e18354613787565b8361396b565b6000601f841160018114613a395760008515613a035750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556119eb565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613a885786850135825560209485019460019092019101613a68565b5086821015613ac3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613ae860408301866131ff565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613b4b57600080fd5b8151610c7981613656565b600060a08236031215613b6857600080fd5b60405160a0810167ffffffffffffffff8282108183111715613b8c57613b8c61358b565b816040528435915080821115613ba157600080fd5b50613bae36828601613820565b825250613bbd602084016131a3565b60208201526040830135613bd08161325c565b6040820152606083810135908201526080830135613bed8161325c565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613c5b57600080fd5b9190910192915050565b60006101408236031215613c7857600080fd5b613c806135e4565b613c89836131a3565b8152613c9760208401613664565b6020820152604083013567ffffffffffffffff80821115613cb757600080fd5b613cc336838701613820565b60408401526060850135915080821115613cdc57600080fd5b50613ce936828601613820565b606083015250613cfc366080850161368f565b6080820152613d0e3660e0850161368f565b60a082015292915050565b815167ffffffffffffffff811115613d3357613d3361358b565b613d4781613d418454613787565b8461396b565b602080601f831160018114613d9a5760008415613d645750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139b3565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613de757888601518255948401946001909101908401613dc8565b5085821015613e2357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613e57818401876131ff565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613e959050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526134e6565b60a081526000613edf60a08301876131ff565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613f5c60a08301866131ff565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613f9f57600080fd5b815167ffffffffffffffff811115613fb657600080fd5b8201601f81018413613fc757600080fd5b8051613fd561383f826137da565b818152856020838501011115613fea57600080fd5b6134e68260208301602086016131db565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561061957610619613ffb565b67ffffffffffffffff8416815260e0810161408960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526127e2565b6060810161061982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561410e57600080fd5b8151610c798161325c565b808202811582820484141761061957610619613ffb565b8082018082111561061957610619613ffb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826141a8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613c5b8184602087016131db56fe4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", } var BurnMintTokenPoolAndProxyABI = BurnMintTokenPoolAndProxyMetaData.ABI @@ -332,6 +332,28 @@ func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetOnR return _BurnMintTokenPoolAndProxy.Contract.GetOnRamp(&_BurnMintTokenPoolAndProxy.CallOpts, arg0) } +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getRateLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetRateLimitAdmin() (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetRateLimitAdmin(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetRateLimitAdmin() (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetRateLimitAdmin(&_BurnMintTokenPoolAndProxy.CallOpts) +} + func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { var out []interface{} err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) @@ -680,6 +702,18 @@ func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorSession) Se return _BurnMintTokenPoolAndProxy.Contract.SetPreviousPool(&_BurnMintTokenPoolAndProxy.TransactOpts, prevPool) } +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.SetRateLimitAdmin(&_BurnMintTokenPoolAndProxy.TransactOpts, rateLimitAdmin) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactorSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnMintTokenPoolAndProxy.Contract.SetRateLimitAdmin(&_BurnMintTokenPoolAndProxy.TransactOpts, rateLimitAdmin) +} + func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { return _BurnMintTokenPoolAndProxy.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) } @@ -2826,6 +2860,8 @@ type BurnMintTokenPoolAndProxyInterface interface { GetOnRamp(opts *bind.CallOpts, arg0 uint64) (common.Address, error) + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) @@ -2864,6 +2900,8 @@ type BurnMintTokenPoolAndProxyInterface interface { SetPreviousPool(opts *bind.TransactOpts, prevPool common.Address) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go index 07489bbb01..6631733928 100644 --- a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go @@ -82,8 +82,8 @@ type TokenPoolChainUpdate struct { } var BurnWithFromMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620043e4380380620043e48339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161386b62000b79600039600081816104620152818161162d015261201101526000818161043c0152818161145e01526118e30152600081816101ef01528181610244015281816106a20152818161137e01528181611803015281816119fb01528181611fa701526121fc015261386b6000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c8063a7cd63b7116100e3578063c75eea9c1161008c578063dc0bd97111610066578063dc0bd9711461043a578063e0351e1314610460578063f2fde38b1461048657600080fd5b8063c75eea9c14610401578063cf7401f314610414578063db6327dc1461042757600080fd5b8063b7946580116100bd578063b7946580146103c6578063c0d78655146103d9578063c4bffe2b146103ec57600080fd5b8063a7cd63b714610324578063af58d59f14610339578063b0f479a1146103a857600080fd5b806354c8a4f3116101455780638926f54f1161011f5780638926f54f146102d35780638da5cb5b146102e65780639a4575b91461030457600080fd5b806354c8a4f3146102a357806378a010b2146102b857806379ba5097146102cb57600080fd5b806321df0da71161017657806321df0da7146101ed578063240028e814610234578063390775371461028157600080fd5b806301ffc9a71461019d5780630a2fd493146101c5578063181f5a77146101e5575b600080fd5b6101b06101ab36600461299f565b610499565b60405190151581526020015b60405180910390f35b6101d86101d33660046129fe565b61057e565b6040516101bc9190612a7d565b6101d861062e565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b6101b0610242366004612abd565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61029461028f366004612ada565b61064a565b604051905181526020016101bc565b6102b66102b1366004612b62565b6107a5565b005b6102b66102c6366004612bce565b610820565b6102b6610994565b6101b06102e13660046129fe565b610a91565b60005473ffffffffffffffffffffffffffffffffffffffff1661020f565b610317610312366004612c51565b610aa8565b6040516101bc9190612c8c565b61032c610b4f565b6040516101bc9190612cec565b61034c6103473660046129fe565b610b60565b6040516101bc919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff1661020f565b6101d86103d43660046129fe565b610c35565b6102b66103e7366004612abd565b610c60565b6103f4610d3b565b6040516101bc9190612d46565b61034c61040f3660046129fe565b610df3565b6102b6610422366004612eae565b610ec5565b6102b6610435366004612ef3565b610edd565b7f000000000000000000000000000000000000000000000000000000000000000061020f565b7f00000000000000000000000000000000000000000000000000000000000000006101b0565b6102b6610494366004612abd565b611363565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061052c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061057857507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906105a990612f35565b80601f01602080910402602001604051908101604052809291908181526020018280546105d590612f35565b80156106225780601f106105f757610100808354040283529160200191610622565b820191906000526020600020905b81548152906001019060200180831161060557829003601f168201915b50505050509050919050565b60405180606001604052806023815260200161383c6023913981565b60408051602081019091526000815261066a61066583613033565b611377565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b1580156106fb57600080fd5b505af115801561070f573d6000803e3d6000fd5b50610724925050506060830160408401612abd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161078691815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6107ad6115a8565b61081a8484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061162b92505050565b50505050565b6108286115a8565b61083183610a91565b610878576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461089f90612f35565b80601f01602080910402602001604051908101604052809291908181526020018280546108cb90612f35565b80156109185780601f106108ed57610100808354040283529160200191610918565b820191906000526020600020905b8154815290600101906020018083116108fb57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610947838583613178565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf82858560405161098693929190613292565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161086f565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000610578600567ffffffffffffffff84166117e1565b6040805180820190915260608082526020820152610acd610ac8836132f6565b6117fc565b610ada82606001356119c6565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b348460200160208101906103d491906129fe565b81526040805160208181019092526000815291015292915050565b6060610b5b6002611a6f565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261057890611a7c565b67ffffffffffffffff811660009081526007602052604090206005018054606091906105a990612f35565b610c686115a8565b73ffffffffffffffffffffffffffffffffffffffff8116610cb5576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610d496005611a6f565b90506000815167ffffffffffffffff811115610d6757610d67612d88565b604051908082528060200260200182016040528015610d90578160200160208202803683370190505b50905060005b8251811015610dec57828181518110610db157610db1613398565b6020026020010151828281518110610dcb57610dcb613398565b67ffffffffffffffff90921660209283029190910190910152600101610d96565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261057890611a7c565b610ecd6115a8565b610ed8838383611b2e565b505050565b610ee56115a8565b60005b81811015610ed8576000838383818110610f0457610f04613398565b9050602002810190610f1691906133c7565b610f1f90613405565b9050610f348160800151826020015115611c18565b610f478160a00151826020015115611c18565b806020015115611243578051610f699060059067ffffffffffffffff16611d51565b610fae5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161086f565b6040810151511580610fc35750606081015151155b15610ffa576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906111db90826134b9565b50606082015160058201906111f090826134b9565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061123694939291906135d3565b60405180910390a161135a565b805161125b9060059067ffffffffffffffff16611d5d565b6112a05780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161086f565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906113096004830182612951565b611317600583016000612951565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101610ee8565b61136b6115a8565b61137481611d69565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461140c5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161086f565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156114ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114de919061366c565b15611515576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115228160200151611e5e565b6000611531826020015161057e565b9050805160001480611555575080805190602001208260a001518051906020012014155b15611592578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161086f9190612a7d565b6115a482602001518360600151611f84565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161086f565b565b7f0000000000000000000000000000000000000000000000000000000000000000611682576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156117185760008382815181106116a2576116a2613398565b602002602001015190506116c0816002611fcb90919063ffffffff16565b1561170f5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611685565b5060005b8151811015610ed857600082828151811061173957611739613398565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361177d57506117d9565b611788600282611fed565b156117d75760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161171c565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146118915760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161086f565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561193f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611963919061366c565b1561199a576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119a7816040015161200f565b6119b4816020015161208e565b611374816020015182606001516121dc565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b158015611a5457600080fd5b505af1158015611a68573d6000803e3d6000fd5b5050505050565b606060006117f583612220565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611b0a82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611aee91906136b8565b85608001516fffffffffffffffffffffffffffffffff1661227b565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611b3783610a91565b611b79576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161086f565b611b84826000611c18565b67ffffffffffffffff83166000908152600760205260409020611ba790836122a5565b611bb2816000611c18565b67ffffffffffffffff83166000908152600760205260409020611bd890600201826122a5565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611c0b939291906136cb565b60405180910390a1505050565b815115611cdf5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611c6e575060408201516fffffffffffffffffffffffffffffffff16155b15611ca757816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161086f919061374e565b80156115a4576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611d18575060208201516fffffffffffffffffffffffffffffffff1615155b156115a457816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161086f919061374e565b60006117f58383612447565b60006117f58383612496565b3373ffffffffffffffffffffffffffffffffffffffff821603611de8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161086f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611e6781610a91565b611ea9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161086f565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015611f28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4c919061366c565b611374576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161086f565b67ffffffffffffffff821660009081526007602052604090206115a490600201827f0000000000000000000000000000000000000000000000000000000000000000612589565b60006117f58373ffffffffffffffffffffffffffffffffffffffff8416612496565b60006117f58373ffffffffffffffffffffffffffffffffffffffff8416612447565b7f0000000000000000000000000000000000000000000000000000000000000000156113745761204060028261290c565b611374576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161086f565b61209781610a91565b6120d9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161086f565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612152573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612176919061378a565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611374576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161086f565b67ffffffffffffffff821660009081526007602052604090206115a490827f0000000000000000000000000000000000000000000000000000000000000000612589565b60608160000180548060200260200160405190810160405280929190818152602001828054801561062257602002820191906000526020600020905b81548152602001906001019080831161225c5750505050509050919050565b600061229a8561228b84866137a7565b61229590876137be565b61293b565b90505b949350505050565b81546000906122ce90700100000000000000000000000000000000900463ffffffff16426136b8565b905080156123705760018301548354612316916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661227b565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612396916fffffffffffffffffffffffffffffffff908116911661293b565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611c0b90849061374e565b600081815260018301602052604081205461248e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610578565b506000610578565b6000818152600183016020526040812054801561257f5760006124ba6001836136b8565b85549091506000906124ce906001906136b8565b90508181146125335760008660000182815481106124ee576124ee613398565b906000526020600020015490508087600001848154811061251157612511613398565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612544576125446137d1565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610578565b6000915050610578565b825474010000000000000000000000000000000000000000900460ff1615806125b0575081155b156125ba57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061260090700100000000000000000000000000000000900463ffffffff16426136b8565b905080156126c05781831115612642576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461267c9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661227b565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156127775773ffffffffffffffffffffffffffffffffffffffff841661271f576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161086f565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161086f565b8483101561288a5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906127bb90826136b8565b6127c5878a6136b8565b6127cf91906137be565b6127d99190613800565b905073ffffffffffffffffffffffffffffffffffffffff8616612832576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161086f565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161086f565b61289485846136b8565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156117f5565b600081831061294a57816117f5565b5090919050565b50805461295d90612f35565b6000825580601f1061296d575050565b601f01602090049060005260206000209081019061137491905b8082111561299b5760008155600101612987565b5090565b6000602082840312156129b157600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146117f557600080fd5b803567ffffffffffffffff811681146129f957600080fd5b919050565b600060208284031215612a1057600080fd5b6117f5826129e1565b6000815180845260005b81811015612a3f57602081850181015186830182015201612a23565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006117f56020830184612a19565b73ffffffffffffffffffffffffffffffffffffffff8116811461137457600080fd5b80356129f981612a90565b600060208284031215612acf57600080fd5b81356117f581612a90565b600060208284031215612aec57600080fd5b813567ffffffffffffffff811115612b0357600080fd5b820161010081850312156117f557600080fd5b60008083601f840112612b2857600080fd5b50813567ffffffffffffffff811115612b4057600080fd5b6020830191508360208260051b8501011115612b5b57600080fd5b9250929050565b60008060008060408587031215612b7857600080fd5b843567ffffffffffffffff80821115612b9057600080fd5b612b9c88838901612b16565b90965094506020870135915080821115612bb557600080fd5b50612bc287828801612b16565b95989497509550505050565b600080600060408486031215612be357600080fd5b612bec846129e1565b9250602084013567ffffffffffffffff80821115612c0957600080fd5b818601915086601f830112612c1d57600080fd5b813581811115612c2c57600080fd5b876020828501011115612c3e57600080fd5b6020830194508093505050509250925092565b600060208284031215612c6357600080fd5b813567ffffffffffffffff811115612c7a57600080fd5b820160a081850312156117f557600080fd5b602081526000825160406020840152612ca86060840182612a19565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612ce38282612a19565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d3a57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612d08565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d3a57835167ffffffffffffffff1683529284019291840191600101612d62565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612ddb57612ddb612d88565b60405290565b60405160c0810167ffffffffffffffff81118282101715612ddb57612ddb612d88565b801515811461137457600080fd5b80356129f981612e04565b80356fffffffffffffffffffffffffffffffff811681146129f957600080fd5b600060608284031215612e4f57600080fd5b6040516060810181811067ffffffffffffffff82111715612e7257612e72612d88565b6040529050808235612e8381612e04565b8152612e9160208401612e1d565b6020820152612ea260408401612e1d565b60408201525092915050565b600080600060e08486031215612ec357600080fd5b612ecc846129e1565b9250612edb8560208601612e3d565b9150612eea8560808601612e3d565b90509250925092565b60008060208385031215612f0657600080fd5b823567ffffffffffffffff811115612f1d57600080fd5b612f2985828601612b16565b90969095509350505050565b600181811c90821680612f4957607f821691505b602082108103612f82577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f830112612f9957600080fd5b813567ffffffffffffffff80821115612fb457612fb4612d88565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ffa57612ffa612d88565b8160405283815286602085880101111561301357600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561304657600080fd5b61304e612db7565b823567ffffffffffffffff8082111561306657600080fd5b61307236838701612f88565b8352613080602086016129e1565b602084015261309160408601612ab2565b6040840152606085013560608401526130ac60808601612ab2565b608084015260a08501359150808211156130c557600080fd5b6130d136838701612f88565b60a084015260c08501359150808211156130ea57600080fd5b6130f636838701612f88565b60c084015260e085013591508082111561310f57600080fd5b5061311c36828601612f88565b60e08301525092915050565b601f821115610ed8576000816000526020600020601f850160051c810160208610156131515750805b601f850160051c820191505b818110156131705782815560010161315d565b505050505050565b67ffffffffffffffff83111561319057613190612d88565b6131a48361319e8354612f35565b83613128565b6000601f8411600181146131f657600085156131c05750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a68565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156132455786850135825560209485019460019092019101613225565b5086821015613280577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006132a56040830186612a19565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561330857600080fd5b60405160a0810167ffffffffffffffff828210818311171561332c5761332c612d88565b81604052843591508082111561334157600080fd5b5061334e36828601612f88565b82525061335d602084016129e1565b6020820152604083013561337081612a90565b604082015260608381013590820152608083013561338d81612a90565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126133fb57600080fd5b9190910192915050565b6000610140823603121561341857600080fd5b613420612de1565b613429836129e1565b815261343760208401612e12565b6020820152604083013567ffffffffffffffff8082111561345757600080fd5b61346336838701612f88565b6040840152606085013591508082111561347c57600080fd5b5061348936828601612f88565b60608301525061349c3660808501612e3d565b60808201526134ae3660e08501612e3d565b60a082015292915050565b815167ffffffffffffffff8111156134d3576134d3612d88565b6134e7816134e18454612f35565b84613128565b602080601f83116001811461353a57600084156135045750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613170565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561358757888601518255948401946001909101908401613568565b50858210156135c357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526135f781840187612a19565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506136359050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612ce3565b60006020828403121561367e57600080fd5b81516117f581612e04565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561057857610578613689565b67ffffffffffffffff8416815260e0810161371760208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261229d565b6060810161057882848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561379c57600080fd5b81516117f581612a90565b808202811582820484141761057857610578613689565b8082018082111561057857610578613689565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613836577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fe4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e302d646576a164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b50604051620044eb380380620044eb8339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161397262000b79600039600081816104a90152818161173401526121180152600081816104830152818161156501526119ea0152600081816102050152818161025a015281816106e9015281816114850152818161190a01528181611b02015281816120ae015261230301526139726000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc1461046e578063dc0bd97114610481578063e0351e13146104a7578063f2fde38b146104cd57600080fd5b8063c4bffe2b14610433578063c75eea9c14610448578063cf7401f31461045b57600080fd5b8063b0f479a1116100c8578063b0f479a1146103ef578063b79465801461040d578063c0d786551461042057600080fd5b80639a4575b91461034b578063a7cd63b71461036b578063af58d59f1461038057600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146102ff5780637d54534e146103075780638926f54f1461031a5780638da5cb5b1461032d57600080fd5b806354c8a4f3146102b95780636d3d1a58146102ce57806378a010b2146102ec57600080fd5b806321df0da71161018c57806321df0da714610203578063240028e81461024a578063390775371461029757600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612aa6565b6104e0565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b05565b6105c5565b6040516101d29190612b84565b6101ee610675565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c6610258366004612bc4565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102aa6102a5366004612be1565b610691565b604051905181526020016101d2565b6102cc6102c7366004612c69565b6107ec565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610225565b6102cc6102fa366004612cd5565b610867565b6102cc6109db565b6102cc610315366004612bc4565b610ad8565b6101c6610328366004612b05565b610b27565b60005473ffffffffffffffffffffffffffffffffffffffff16610225565b61035e610359366004612d58565b610b3e565b6040516101d29190612d93565b610373610be5565b6040516101d29190612df3565b61039361038e366004612b05565b610bf6565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610225565b6101ee61041b366004612b05565b610ccb565b6102cc61042e366004612bc4565b610cf6565b61043b610dd1565b6040516101d29190612e4d565b610393610456366004612b05565b610e89565b6102cc610469366004612fb5565b610f5b565b6102cc61047c366004612ffa565b610fe4565b7f0000000000000000000000000000000000000000000000000000000000000000610225565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b6102cc6104db366004612bc4565b61146a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061057357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105bf57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906105f09061303c565b80601f016020809104026020016040519081016040528092919081815260200182805461061c9061303c565b80156106695780601f1061063e57610100808354040283529160200191610669565b820191906000526020600020905b81548152906001019060200180831161064c57829003601f168201915b50505050509050919050565b6040518060600160405280602381526020016139436023913981565b6040805160208101909152600081526106b16106ac8361313a565b61147e565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561074257600080fd5b505af1158015610756573d6000803e3d6000fd5b5061076b925050506060830160408401612bc4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f084606001356040516107cd91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6107f46116af565b6108618484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061173292505050565b50505050565b61086f6116af565b61087883610b27565b6108bf576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546108e69061303c565b80601f01602080910402602001604051908101604052809291908181526020018280546109129061303c565b801561095f5780601f106109345761010080835404028352916020019161095f565b820191906000526020600020905b81548152906001019060200180831161094257829003601f168201915b5050505067ffffffffffffffff861660009081526007602052604090209192505060040161098e83858361327f565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf8285856040516109cd93929190613399565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108b6565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ae06116af565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105bf600567ffffffffffffffff84166118e8565b6040805180820190915260608082526020820152610b63610b5e836133fd565b611903565b610b708260600135611acd565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610bca84602001602081019061041b9190612b05565b81526040805160208181019092526000815291015292915050565b6060610bf16002611b76565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105bf90611b83565b67ffffffffffffffff811660009081526007602052604090206005018054606091906105f09061303c565b610cfe6116af565b73ffffffffffffffffffffffffffffffffffffffff8116610d4b576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610ddf6005611b76565b90506000815167ffffffffffffffff811115610dfd57610dfd612e8f565b604051908082528060200260200182016040528015610e26578160200160208202803683370190505b50905060005b8251811015610e8257828181518110610e4757610e4761349f565b6020026020010151828281518110610e6157610e6161349f565b67ffffffffffffffff90921660209283029190910190910152600101610e2c565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105bf90611b83565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610f9b575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610fd4576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108b6565b610fdf838383611c35565b505050565b610fec6116af565b60005b81811015610fdf57600083838381811061100b5761100b61349f565b905060200281019061101d91906134ce565b6110269061350c565b905061103b8160800151826020015115611d1f565b61104e8160a00151826020015115611d1f565b80602001511561134a5780516110709060059067ffffffffffffffff16611e58565b6110b55780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108b6565b60408101515115806110ca5750606081015151155b15611101576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906112e290826135c0565b50606082015160058201906112f790826135c0565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061133d94939291906136da565b60405180910390a1611461565b80516113629060059067ffffffffffffffff16611e64565b6113a75780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108b6565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114106004830182612a58565b61141e600583016000612a58565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101610fef565b6114726116af565b61147b81611e70565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115135760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108b6565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156115c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e59190613773565b1561161c576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116298160200151611f65565b600061163882602001516105c5565b905080516000148061165c575080805190602001208260a001518051906020012014155b15611699578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108b69190612b84565b6116ab8260200151836060015161208b565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611730576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108b6565b565b7f0000000000000000000000000000000000000000000000000000000000000000611789576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561181f5760008382815181106117a9576117a961349f565b602002602001015190506117c78160026120d290919063ffffffff16565b156118165760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010161178c565b5060005b8151811015610fdf5760008282815181106118405761184061349f565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361188457506118e0565b61188f6002826120f4565b156118de5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611823565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119985760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108b6565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6a9190613773565b15611aa1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611aae8160400151612116565b611abb8160200151612195565b61147b816020015182606001516122e3565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b158015611b5b57600080fd5b505af1158015611b6f573d6000803e3d6000fd5b5050505050565b606060006118fc83612327565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c1182606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611bf591906137bf565b85608001516fffffffffffffffffffffffffffffffff16612382565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c3e83610b27565b611c80576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108b6565b611c8b826000611d1f565b67ffffffffffffffff83166000908152600760205260409020611cae90836123ac565b611cb9816000611d1f565b67ffffffffffffffff83166000908152600760205260409020611cdf90600201826123ac565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d12939291906137d2565b60405180910390a1505050565b815115611de65781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611d75575060408201516fffffffffffffffffffffffffffffffff16155b15611dae57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108b69190613855565b80156116ab576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e1f575060208201516fffffffffffffffffffffffffffffffff1615155b156116ab57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108b69190613855565b60006118fc838361254e565b60006118fc838361259d565b3373ffffffffffffffffffffffffffffffffffffffff821603611eef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108b6565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611f6e81610b27565b611fb0576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108b6565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561202f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120539190613773565b61147b576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108b6565b67ffffffffffffffff821660009081526007602052604090206116ab90600201827f0000000000000000000000000000000000000000000000000000000000000000612690565b60006118fc8373ffffffffffffffffffffffffffffffffffffffff841661259d565b60006118fc8373ffffffffffffffffffffffffffffffffffffffff841661254e565b7f00000000000000000000000000000000000000000000000000000000000000001561147b57612147600282612a13565b61147b576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108b6565b61219e81610b27565b6121e0576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108b6565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612259573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227d9190613891565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461147b576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108b6565b67ffffffffffffffff821660009081526007602052604090206116ab90827f0000000000000000000000000000000000000000000000000000000000000000612690565b60608160000180548060200260200160405190810160405280929190818152602001828054801561066957602002820191906000526020600020905b8154815260200190600101908083116123635750505050509050919050565b60006123a18561239284866138ae565b61239c90876138c5565b612a42565b90505b949350505050565b81546000906123d590700100000000000000000000000000000000900463ffffffff16426137bf565b90508015612477576001830154835461241d916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612382565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461249d916fffffffffffffffffffffffffffffffff9081169116612a42565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d12908490613855565b6000818152600183016020526040812054612595575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105bf565b5060006105bf565b600081815260018301602052604081205480156126865760006125c16001836137bf565b85549091506000906125d5906001906137bf565b905081811461263a5760008660000182815481106125f5576125f561349f565b90600052602060002001549050808760000184815481106126185761261861349f565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061264b5761264b6138d8565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105bf565b60009150506105bf565b825474010000000000000000000000000000000000000000900460ff1615806126b7575081155b156126c157505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061270790700100000000000000000000000000000000900463ffffffff16426137bf565b905080156127c75781831115612749576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127839083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612382565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561287e5773ffffffffffffffffffffffffffffffffffffffff8416612826576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108b6565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108b6565b848310156129915760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128c290826137bf565b6128cc878a6137bf565b6128d691906138c5565b6128e09190613907565b905073ffffffffffffffffffffffffffffffffffffffff8616612939576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108b6565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108b6565b61299b85846137bf565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156118fc565b6000818310612a5157816118fc565b5090919050565b508054612a649061303c565b6000825580601f10612a74575050565b601f01602090049060005260206000209081019061147b91905b80821115612aa25760008155600101612a8e565b5090565b600060208284031215612ab857600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146118fc57600080fd5b803567ffffffffffffffff81168114612b0057600080fd5b919050565b600060208284031215612b1757600080fd5b6118fc82612ae8565b6000815180845260005b81811015612b4657602081850181015186830182015201612b2a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006118fc6020830184612b20565b73ffffffffffffffffffffffffffffffffffffffff8116811461147b57600080fd5b8035612b0081612b97565b600060208284031215612bd657600080fd5b81356118fc81612b97565b600060208284031215612bf357600080fd5b813567ffffffffffffffff811115612c0a57600080fd5b820161010081850312156118fc57600080fd5b60008083601f840112612c2f57600080fd5b50813567ffffffffffffffff811115612c4757600080fd5b6020830191508360208260051b8501011115612c6257600080fd5b9250929050565b60008060008060408587031215612c7f57600080fd5b843567ffffffffffffffff80821115612c9757600080fd5b612ca388838901612c1d565b90965094506020870135915080821115612cbc57600080fd5b50612cc987828801612c1d565b95989497509550505050565b600080600060408486031215612cea57600080fd5b612cf384612ae8565b9250602084013567ffffffffffffffff80821115612d1057600080fd5b818601915086601f830112612d2457600080fd5b813581811115612d3357600080fd5b876020828501011115612d4557600080fd5b6020830194508093505050509250925092565b600060208284031215612d6a57600080fd5b813567ffffffffffffffff811115612d8157600080fd5b820160a081850312156118fc57600080fd5b602081526000825160406020840152612daf6060840182612b20565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612dea8282612b20565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e4157835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e0f565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e4157835167ffffffffffffffff1683529284019291840191600101612e69565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612ee257612ee2612e8f565b60405290565b60405160c0810167ffffffffffffffff81118282101715612ee257612ee2612e8f565b801515811461147b57600080fd5b8035612b0081612f0b565b80356fffffffffffffffffffffffffffffffff81168114612b0057600080fd5b600060608284031215612f5657600080fd5b6040516060810181811067ffffffffffffffff82111715612f7957612f79612e8f565b6040529050808235612f8a81612f0b565b8152612f9860208401612f24565b6020820152612fa960408401612f24565b60408201525092915050565b600080600060e08486031215612fca57600080fd5b612fd384612ae8565b9250612fe28560208601612f44565b9150612ff18560808601612f44565b90509250925092565b6000806020838503121561300d57600080fd5b823567ffffffffffffffff81111561302457600080fd5b61303085828601612c1d565b90969095509350505050565b600181811c9082168061305057607f821691505b602082108103613089577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130a057600080fd5b813567ffffffffffffffff808211156130bb576130bb612e8f565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561310157613101612e8f565b8160405283815286602085880101111561311a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561314d57600080fd5b613155612ebe565b823567ffffffffffffffff8082111561316d57600080fd5b6131793683870161308f565b835261318760208601612ae8565b602084015261319860408601612bb9565b6040840152606085013560608401526131b360808601612bb9565b608084015260a08501359150808211156131cc57600080fd5b6131d83683870161308f565b60a084015260c08501359150808211156131f157600080fd5b6131fd3683870161308f565b60c084015260e085013591508082111561321657600080fd5b506132233682860161308f565b60e08301525092915050565b601f821115610fdf576000816000526020600020601f850160051c810160208610156132585750805b601f850160051c820191505b8181101561327757828155600101613264565b505050505050565b67ffffffffffffffff83111561329757613297612e8f565b6132ab836132a5835461303c565b8361322f565b6000601f8411600181146132fd57600085156132c75750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611b6f565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561334c578685013582556020948501946001909201910161332c565b5086821015613387577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133ac6040830186612b20565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561340f57600080fd5b60405160a0810167ffffffffffffffff828210818311171561343357613433612e8f565b81604052843591508082111561344857600080fd5b506134553682860161308f565b82525061346460208401612ae8565b6020820152604083013561347781612b97565b604082015260608381013590820152608083013561349481612b97565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261350257600080fd5b9190910192915050565b6000610140823603121561351f57600080fd5b613527612ee8565b61353083612ae8565b815261353e60208401612f19565b6020820152604083013567ffffffffffffffff8082111561355e57600080fd5b61356a3683870161308f565b6040840152606085013591508082111561358357600080fd5b506135903682860161308f565b6060830152506135a33660808501612f44565b60808201526135b53660e08501612f44565b60a082015292915050565b815167ffffffffffffffff8111156135da576135da612e8f565b6135ee816135e8845461303c565b8461322f565b602080601f831160018114613641576000841561360b5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613277565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561368e5788860151825594840194600190910190840161366f565b50858210156136ca57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526136fe81840187612b20565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061373c9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612dea565b60006020828403121561378557600080fd5b81516118fc81612f0b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105bf576105bf613790565b67ffffffffffffffff8416815260e0810161381e60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123a4565b606081016105bf82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138a357600080fd5b81516118fc81612b97565b80820281158282048414176105bf576105bf613790565b808201808211156105bf576105bf613790565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261393d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fe4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e302d646576a164736f6c6343000818000a", } var BurnWithFromMintTokenPoolABI = BurnWithFromMintTokenPoolMetaData.ABI @@ -310,6 +310,28 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetCur return _BurnWithFromMintTokenPool.Contract.GetCurrentOutboundRateLimiterState(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) } +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getRateLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetRateLimitAdmin() (common.Address, error) { + return _BurnWithFromMintTokenPool.Contract.GetRateLimitAdmin(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetRateLimitAdmin() (common.Address, error) { + return _BurnWithFromMintTokenPool.Contract.GetRateLimitAdmin(&_BurnWithFromMintTokenPool.CallOpts) +} + func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { var out []interface{} err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) @@ -624,6 +646,18 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) Se return _BurnWithFromMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.SetRateLimitAdmin(&_BurnWithFromMintTokenPool.TransactOpts, rateLimitAdmin) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.SetRateLimitAdmin(&_BurnWithFromMintTokenPool.TransactOpts, rateLimitAdmin) +} + func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { return _BurnWithFromMintTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) } @@ -2644,6 +2678,8 @@ type BurnWithFromMintTokenPoolInterface interface { GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) @@ -2678,6 +2714,8 @@ type BurnWithFromMintTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go index e4f47eb0a5..2a4605bfd2 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go @@ -49,8 +49,6 @@ type EVM2EVMOffRampDynamicConfig struct { MaxNumberOfTokensPerMsg uint16 Router common.Address PriceRegistry common.Address - MaxPoolReleaseOrMintGas uint32 - MaxTokenTransferGas uint32 } type EVM2EVMOffRampRateLimitToken struct { @@ -106,8 +104,8 @@ type RateLimiterTokenBucket struct { } var EVM2EVMOffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101a06040523480156200001257600080fd5b5060405162006213380380620062138339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615b4a620006c9600039600081816102ec01528181611b1201526133890152600081816102bd01528181611aeb0152611d9d01526000818161028e01528181610ed201528181610f3701528181611ac40152818161234501526123af01526000611f3c01526000818161025f0152611a9a0152600081816101ff0152611a4801526000818161022f01528181611a7201528181611d5a01528181612dc101526134980152600081816101d001528181611a1a015261201c015260008181611cb40152611d000152615b4a6000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806381ff7048116100d8578063afcb95d71161008c578063f077b59211610066578063f077b59214610646578063f2fde38b1461065c578063f52121a51461066f57600080fd5b8063afcb95d714610600578063b1dc65a414610620578063c92b28321461063357600080fd5b8063856c8247116100bd578063856c8247146105b0578063873504d7146105dc5780638da5cb5b146105ef57600080fd5b806381ff70481461057257806385572ffb146105a257600080fd5b8063599f64311161013a578063740f415011610114578063740f4150146104615780637437ff9f1461047457806379ba50971461056a57600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60405161032991906141e7565b60405180910390f35b61034561034036600461427d565b610682565b60405161032991906142dd565b61038e6040518060400160405280601881526020017f45564d3245564d4f666652616d7020312e352e302d646576000000000000000081525081565b604051610329919061433b565b6103ae6103a93660046145aa565b6106fd565b005b6103b8610af1565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610ba6565b60405161032991906146bc565b6103ae61045c3660046146cf565b610c08565b6103ae61046f366004614b2f565b610cd1565b61055d6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152506040805160e081018252600a5463ffffffff808216835264010000000082048116602084015261ffff68010000000000000000830416938301939093526001600160a01b036a010000000000000000000090910481166060830152600b549081166080830152740100000000000000000000000000000000000000008104831660a08301527801000000000000000000000000000000000000000000000000900490911660c082015290565b6040516103299190614bea565b6103ae610dc3565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae610182366004614c58565b6105c36105be3660046146cf565b610ea6565b60405167ffffffffffffffff9091168152602001610329565b6103ae6105ea366004614d24565b610fa9565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae61062e366004614dcd565b611177565b6103ae610641366004614ed2565b611382565b61064e6113ed565b604051610329929190614f22565b6103ae61066a3660046146cf565b611513565b6103ae61067d366004614f47565b611524565b600061069060016004614fd0565b600261069d608085615012565b67ffffffffffffffff166106b19190615039565b601060006106c0608087615050565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106f7576106f761429a565b92915050565b84518460ff16601f82111561074a5760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016107419190615077565b60405180910390fd5b806000036107875760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016107419190615077565b61078f6117c4565b6107988561183a565b60095460005b8181101561080f5760086000600983815481106107bd576107bd615091565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161079e565b5050865160005b818110156109b257600089828151811061083257610832615091565b602002602001015190506000600281111561084f5761084f61429a565b6001600160a01b038216600090815260086020526040902054610100900460ff1660028111156108815761088161429a565b146108bb5760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016107419190615077565b6001600160a01b0381166108fb576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561099e5761099e61429a565b021790555090505050806001019050610816565b5087516109c69060099060208b0190614155565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a161717905560078054610a4c914691309190600090610a1e9063ffffffff166150c0565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611b72565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610add9487949293918316921691909117908f908f908f908f908f908f906150e3565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610ba190611bff565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bfe57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610be0575b5050505050905090565b6000546001600160a01b03163314801590610c2e57506002546001600160a01b03163314155b15610c65576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b610cd9611cb1565b81515181518114610d16576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610db3576000838281518110610d3557610d35615091565b6020026020010151905080600014610daa578451805183908110610d5b57610d5b615091565b602002602001015160800151811015610daa576040517f085e39cf0000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610741565b50600101610d19565b50610dbe8383611d32565b505050565b6001546001600160a01b03163314610e37576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610741565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106f7577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106f7576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa29190615179565b9392505050565b610fb16117c4565b60005b825181101561108457610fee838281518110610fd257610fd2615091565b602002602001015160200151600c6127b590919063ffffffff16565b1561107c577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d5878283828151811061102657611026615091565b60200260200101516000015184838151811061104457611044615091565b6020026020010151602001516040516110739291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610fb4565b5060005b8151811015610dbe576110e18282815181106110a6576110a6615091565b6020026020010151602001518383815181106110c4576110c4615091565b602002602001015160000151600c6127ca9092919063ffffffff16565b1561116f577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a82828151811061111957611119615091565b60200260200101516000015183838151811061113757611137615091565b6020026020010151602001516040516111669291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101611088565b61118187876127e8565b6005548835908082146111ca576040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610741565b6111d2611cb1565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561125a5761125a61429a565b600281111561126b5761126b61429a565b90525090506002816020015160028111156112885761128861429a565b1480156112c257506009816000015160ff16815481106112aa576112aa615091565b6000918252602090912001546001600160a01b031633145b6112f8576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611306856020615039565b611311886020615039565b61131d8b610144615196565b6113279190615196565b6113319190615196565b9050368114611375576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610741565b5050505050505050505050565b6000546001600160a01b031633148015906113a857506002546001600160a01b03163314155b156113df576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ea60038261280f565b50565b60608060006113fc600c6129f4565b90508067ffffffffffffffff8111156114175761141761434e565b604051908082528060200260200182016040528015611440578160200160208202803683370190505b5092508067ffffffffffffffff81111561145c5761145c61434e565b604051908082528060200260200182016040528015611485578160200160208202803683370190505b50915060005b8181101561150d576000806114a1600c846129ff565b91509150808684815181106114b8576114b8615091565b60200260200101906001600160a01b031690816001600160a01b031681525050818584815181106114eb576114eb615091565b6001600160a01b0390921660209283029190910190910152505060010161148b565b50509091565b61151b6117c4565b6113ea81612a1d565b33301461155d576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516000808252602082019092528161159a565b60408051808201909152600080825260208201528152602001906001900390816115735790505b5061014084015151909150156115fa576115f783610140015184602001516040516020016115d791906001600160a01b0391909116815260200190565b604051602081830303815290604052856040015186610160015186612af8565b90505b6101208301515115801561161057506080830151155b80611627575060408301516001600160a01b03163b155b8061166757506040830151611665906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612c29565b155b1561167157505050565b600080600a600001600a9054906101000a90046001600160a01b03166001600160a01b0316633cf979836040518060a001604052808861018001518152602001886000015167ffffffffffffffff16815260200188602001516040516020016116e991906001600160a01b0391909116815260200190565b6040516020818303038152906040528152602001886101200151815260200186815250611388886080015189604001516040518563ffffffff1660e01b815260040161173894939291906151ee565b6000604051808303816000875af1158015611757573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261177f91908101906152f8565b5091509150816117bd57806040517f0a8d6e8c000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b5050505050565b6000546001600160a01b03163314611838576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610741565b565b6000818060200190518101906118509190615371565b60608101519091506001600160a01b0316611897576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a80546020808501516040808701516060808901516001600160a01b039081166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff61ffff9094166801000000000000000002939093167fffff00000000000000000000000000000000000000000000ffffffffffffffff63ffffffff968716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009099169a87169a909a1797909717989098169590951717909455608080870151600b805460a0808b015160c0808d015188167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9290981674010000000000000000000000000000000000000000027fffffffffffffffff000000000000000000000000000000000000000000000000909416958c16959095179290921791909116949094179055855160e0810187527f00000000000000000000000000000000000000000000000000000000000000008816815267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116958201959095527f0000000000000000000000000000000000000000000000000000000000000000909416848701527f00000000000000000000000000000000000000000000000000000000000000008716948401949094527f00000000000000000000000000000000000000000000000000000000000000008616908301527f00000000000000000000000000000000000000000000000000000000000000008516908201527f000000000000000000000000000000000000000000000000000000000000000090931690830152517ff02fcc22535d64d92d17b995475893d63edd51da163fed74a6ee9b4bc4895cc491611b6691849061540c565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611b96999897969594939291906154e8565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c8d82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c719190614fd0565b85608001516fffffffffffffffffffffffffffffffff16612c45565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b467f000000000000000000000000000000000000000000000000000000000000000014611838576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610741565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611dec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e109190615570565b15611e47576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151516000819003611e84576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114611ec2576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff811115611edd57611edd61434e565b604051908082528060200260200182016040528015611f06578160200160208202803683370190505b50905060005b82811015611fde57600085600001518281518110611f2c57611f2c615091565b60200260200101519050611f60817f0000000000000000000000000000000000000000000000000000000000000000612c64565b838381518110611f7257611f72615091565b602002602001018181525050806101800151838381518110611f9657611f96615091565b602002602001015114611fd5576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101611f0c565b50604080850151606086015191517f320488750000000000000000000000000000000000000000000000000000000081526000926001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692633204887592612052928792916004016155be565b602060405180830381865afa15801561206f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209391906155f4565b9050806000036120cf576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b848110156127ac576000876000015182815181106120f6576120f6615091565b60200260200101519050600061210f8260600151610682565b905060028160038111156121255761212561429a565b0361216c57816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a250506127a4565b60008160038111156121805761218061429a565b148061219d5750600381600381111561219b5761219b61429a565b145b6121e55760608201516040517f50a6e05200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b83156122a257600a5460009063ffffffff166122018742614fd0565b11905080806122215750600382600381111561221f5761221f61429a565b145b612257576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88848151811061226957612269615091565b602002602001015160001461229c5788848151811061228a5761228a615091565b60200260200101518360800181815250505b506122ff565b60008160038111156122b6576122b661429a565b146122ff5760608201516040517f67d9ba0f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b60c082015167ffffffffffffffff161561257e576020808301516001600160a01b03166000908152600f909152604081205467ffffffffffffffff16908190036124e9577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156124e95760208301516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa1580156123f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241c9190615179565b60c084015190915067ffffffffffffffff1661243982600161560d565b67ffffffffffffffff16146124995782602001516001600160a01b03168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a35050506127a4565b6020838101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b60008260038111156124fd576124fd61429a565b0361257c5760c083015167ffffffffffffffff1661251c82600161560d565b67ffffffffffffffff161461257c5782602001516001600160a01b03168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a35050506127a4565b505b60008960200151848151811061259657612596615091565b602002602001015190506125c28360600151846000015185610140015151866101200151518551612dbf565b6125d183606001516001612f39565b6000806125de8584612fe3565b915091506125f0856060015183612f39565b861561265c57600382600381111561260a5761260a61429a565b0361265c5760008460038111156126235761262361429a565b1461265c57806040517fcf19edfd000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b60028260038111156126705761267061429a565b146126c85760038260038111156126895761268961429a565b146126c8578460600151826040517f9e26160300000000000000000000000000000000000000000000000000000000815260040161074192919061562e565b60c085015167ffffffffffffffff16156127505760008460038111156126f0576126f061429a565b03612750576020808601516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff16916127288361564c565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b846101800151856060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef658484604051612796929190615669565b60405180910390a350505050505b6001016120d6565b50505050505050565b6000610fa2836001600160a01b0384166132d6565b60006127e0846001600160a01b038516846132e2565b949350505050565b61280b6127f782840184615689565b604080516000815260208101909152611d32565b5050565b815460009061283890700100000000000000000000000000000000900463ffffffff1642614fd0565b905080156128da5760018301548354612880916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612c45565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612900916fffffffffffffffffffffffffffffffff90811691166132f8565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906129e79084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106f78261330e565b6000808080612a0e8686613319565b909450925050505b9250929050565b336001600160a01b03821603612a8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610741565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b846000805b8751811015612c0e57612b75888281518110612b1b57612b1b615091565b6020026020010151602001518888888581518110612b3b57612b3b615091565b6020026020010151806020019051810190612b5691906156be565b888681518110612b6857612b68615091565b6020026020010151613328565b838281518110612b8757612b87615091565b6020026020010181905250612bc3838281518110612ba757612ba7615091565b602002602001015160000151600c61374b90919063ffffffff16565b15612c0657612bf9838281518110612bdd57612bdd615091565b6020908102919091010151600b546001600160a01b0316613760565b612c039083615196565b91505b600101612afd565b508015612c1e57612c1e81613881565b505b95945050505050565b6000612c348361388e565b8015610fa25750610fa283836138f2565b6000612c2085612c558486615039565b612c5f9087615196565b6132f8565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612cfa9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612d339190615773565b60405160208183030381529060405280519060200120876101600151604051602001612d5f91906157e0565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff1614612e38576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610741565b600a5468010000000000000000900461ffff16831115612e90576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610741565b808314612ed5576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610741565b600a54640100000000900463ffffffff168211156117bd57600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff16600482015260248101839052604401610741565b60006002612f48608085615012565b67ffffffffffffffff16612f5c9190615039565b90506000601081612f6e608087615050565b67ffffffffffffffff168152602081019190915260400160002054905081612f9860016004614fd0565b901b191681836003811115612faf57612faf61429a565b901b178060106000612fc2608088615050565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a59061302790879087906004016157f3565b600060405180830381600087803b15801561304157600080fd5b505af1925050508015613052575060015b6132bb573d808015613080576040519150601f19603f3d011682016040523d82523d6000602084013e613085565b606091505b5061308f81615956565b7fffffffff00000000000000000000000000000000000000000000000000000000167f0a8d6e8c00000000000000000000000000000000000000000000000000000000148061312757506130e281615956565b7fffffffff00000000000000000000000000000000000000000000000000000000167fe1cd550900000000000000000000000000000000000000000000000000000000145b8061317b575061313681615956565b7fffffffff00000000000000000000000000000000000000000000000000000000167f8d666f6000000000000000000000000000000000000000000000000000000000145b806131cf575061318a81615956565b7fffffffff00000000000000000000000000000000000000000000000000000000167f78ef802400000000000000000000000000000000000000000000000000000000145b8061322357506131de81615956565b7fffffffff00000000000000000000000000000000000000000000000000000000167f0c3b563c00000000000000000000000000000000000000000000000000000000145b80613277575061323281615956565b7fffffffff00000000000000000000000000000000000000000000000000000000167fae9b4ce900000000000000000000000000000000000000000000000000000000145b1561328757600392509050612a16565b806040517fcf19edfd000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b50506040805160208101909152600081526002909250929050565b6000610fa283836139c1565b60006127e084846001600160a01b0385166139de565b60008183106133075781610fa2565b5090919050565b60006106f7826139fb565b6000808080612a0e8686613a06565b6040805180820190915260008082526020820152600061334b8460200151613a31565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa1580156133d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f491906159a6565b90506001600160a01b038116158061343c575061343a6001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612c29565b155b1561347e576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610741565b6000806135986040518061010001604052808b81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018a6001600160a01b031681526020018c8152602001866001600160a01b0316815260200189600001518152602001896040015181526020018881525060405160240161351291906159c3565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3907753700000000000000000000000000000000000000000000000000000000179052600b54859063ffffffff74010000000000000000000000000000000000000000909104166113886084613ad7565b5091509150816135d657806040517fe1cd5509000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b805160201461361e5780516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610741565b60008180602001905181019061363491906155f4565b6040516001600160a01b038b166024820152604481018290529091506136e19060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600b54879063ffffffff7801000000000000000000000000000000000000000000000000909104166113886084613ad7565b5090935091508261372057816040517fe1cd5509000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b604080518082019091526001600160a01b039095168552602085015250919250505095945050505050565b6000610fa2836001600160a01b038416613bfd565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa1580156137c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ea9190615a9a565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036138535783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610741565b60208401516127e0907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690613c09565b6113ea6003826000613c46565b60006138ba827f01ffc9a7000000000000000000000000000000000000000000000000000000006138f2565b80156106f757506138eb827fffffffff000000000000000000000000000000000000000000000000000000006138f2565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156139aa575060208210155b80156139b65750600081115b979650505050505050565b60008181526002830160205260408120819055610fa28383613f95565b600082815260028401602052604081208290556127e08484613fa1565b60006106f782613fad565b60008080613a148585613fb7565b600081815260029690960160205260409095205494959350505050565b60008151602014613a7057816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b600082806020019051810190613a8691906155f4565b90506001600160a01b03811180613a9e575061040081105b156106f757826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610741919061433b565b6000606060008361ffff1667ffffffffffffffff811115613afa57613afa61434e565b6040519080825280601f01601f191660200182016040528015613b24576020820181803683370190505b509150863b613b57577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613b8a577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613bc3577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613be65750835b808352806000602085013e50955095509592505050565b6000610fa28383613fc3565b6000670de0b6b3a7640000613c3c837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616615039565b610fa29190615afa565b825474010000000000000000000000000000000000000000900460ff161580613c6d575081155b15613c7757505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090613cbd90700100000000000000000000000000000000900463ffffffff1642614fd0565b90508015613d7d5781831115613cff576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613d399083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612c45565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613e1a576001600160a01b038416613dcf576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610741565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610741565b84831015613f135760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613e5e9082614fd0565b613e68878a614fd0565b613e729190615196565b613e7c9190615afa565b90506001600160a01b038616613ec8576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610741565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610741565b613f1d8584614fd0565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610fa28383613fe2565b6000610fa283836140dc565b60006106f7825490565b6000610fa2838361412b565b6000610fa2838360008181526001830160205260408120541515610fa2565b600081815260018301602052604081205480156140cb576000614006600183614fd0565b855490915060009061401a90600190614fd0565b905081811461407f57600086600001828154811061403a5761403a615091565b906000526020600020015490508087600001848154811061405d5761405d615091565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061409057614090615b0e565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106f7565b60009150506106f7565b5092915050565b6000818152600183016020526040812054614123575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106f7565b5060006106f7565b600082600001828154811061414257614142615091565b9060005260206000200154905092915050565b8280548282559060005260206000209081019282156141c2579160200282015b828111156141c257825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190614175565b506141ce9291506141d2565b5090565b5b808211156141ce57600081556001016141d3565b60e081016106f782846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff811681146113ea57600080fd5b803561427881614257565b919050565b60006020828403121561428f57600080fd5b8135610fa281614257565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600481106142d9576142d961429a565b9052565b602081016106f782846142c9565b60005b838110156143065781810151838201526020016142ee565b50506000910152565b600081518084526143278160208601602086016142eb565b601f01601f19169290920160200192915050565b602081526000610fa2602083018461430f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156143a0576143a061434e565b60405290565b6040516101a0810167ffffffffffffffff811182821017156143a0576143a061434e565b6040516080810167ffffffffffffffff811182821017156143a0576143a061434e565b6040516060810167ffffffffffffffff811182821017156143a0576143a061434e565b60405160e0810167ffffffffffffffff811182821017156143a0576143a061434e565b604051601f8201601f1916810167ffffffffffffffff8111828210171561445c5761445c61434e565b604052919050565b600067ffffffffffffffff82111561447e5761447e61434e565b5060051b60200190565b6001600160a01b03811681146113ea57600080fd5b803561427881614488565b600082601f8301126144b957600080fd5b813560206144ce6144c983614464565b614433565b8083825260208201915060208460051b8701019350868411156144f057600080fd5b602086015b8481101561451557803561450881614488565b83529183019183016144f5565b509695505050505050565b803560ff8116811461427857600080fd5b600067ffffffffffffffff82111561454b5761454b61434e565b50601f01601f191660200190565b600082601f83011261456a57600080fd5b81356145786144c982614531565b81815284602083860101111561458d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156145c357600080fd5b863567ffffffffffffffff808211156145db57600080fd5b6145e78a838b016144a8565b975060208901359150808211156145fd57600080fd5b6146098a838b016144a8565b965061461760408a01614520565b9550606089013591508082111561462d57600080fd5b6146398a838b01614559565b945061464760808a0161426d565b935060a089013591508082111561465d57600080fd5b5061466a89828a01614559565b9150509295509295509295565b60008151808452602080850194506020840160005b838110156146b15781516001600160a01b03168752958201959082019060010161468c565b509495945050505050565b602081526000610fa26020830184614677565b6000602082840312156146e157600080fd5b8135610fa281614488565b80151581146113ea57600080fd5b8035614278816146ec565b600082601f83011261471657600080fd5b813560206147266144c983614464565b82815260069290921b8401810191818101908684111561474557600080fd5b8286015b8481101561451557604081890312156147625760008081fd5b61476a61437d565b813561477581614488565b81528185013585820152835291830191604001614749565b600082601f83011261479e57600080fd5b813560206147ae6144c983614464565b82815260059290921b840181019181810190868411156147cd57600080fd5b8286015b8481101561451557803567ffffffffffffffff8111156147f15760008081fd5b6147ff8986838b0101614559565b8452509183019183016147d1565b60006101a0828403121561482057600080fd5b6148286143a6565b90506148338261426d565b81526148416020830161449d565b60208201526148526040830161449d565b60408201526148636060830161426d565b60608201526080820135608082015261487e60a083016146fa565b60a082015261488f60c0830161426d565b60c08201526148a060e0830161449d565b60e082015261010082810135908201526101208083013567ffffffffffffffff808211156148cd57600080fd5b6148d986838701614559565b838501526101409250828501359150808211156148f557600080fd5b61490186838701614705565b8385015261016092508285013591508082111561491d57600080fd5b5061492a8582860161478d565b82840152505061018080830135818301525092915050565b600082601f83011261495357600080fd5b813560206149636144c983614464565b82815260059290921b8401810191818101908684111561498257600080fd5b8286015b8481101561451557803567ffffffffffffffff8111156149a65760008081fd5b6149b48986838b010161478d565b845250918301918301614986565b600082601f8301126149d357600080fd5b813560206149e36144c983614464565b8083825260208201915060208460051b870101935086841115614a0557600080fd5b602086015b848110156145155780358352918301918301614a0a565b600060808284031215614a3357600080fd5b614a3b6143ca565b9050813567ffffffffffffffff80821115614a5557600080fd5b818401915084601f830112614a6957600080fd5b81356020614a796144c983614464565b82815260059290921b84018101918181019088841115614a9857600080fd5b8286015b84811015614ad057803586811115614ab45760008081fd5b614ac28b86838b010161480d565b845250918301918301614a9c565b5086525085810135935082841115614ae757600080fd5b614af387858801614942565b90850152506040840135915080821115614b0c57600080fd5b50614b19848285016149c2565b6040830152506060820135606082015292915050565b60008060408385031215614b4257600080fd5b823567ffffffffffffffff80821115614b5a57600080fd5b614b6686838701614a21565b9350602091508185013581811115614b7d57600080fd5b85019050601f81018613614b9057600080fd5b8035614b9e6144c982614464565b81815260059190911b82018301908381019088831115614bbd57600080fd5b928401925b82841015614bdb57833582529284019290840190614bc2565b80955050505050509250929050565b60e081016106f7828463ffffffff80825116835280602083015116602084015261ffff604083015116604084015260608201516001600160a01b03808216606086015280608085015116608086015250508060a08301511660a08401528060c08301511660c0840152505050565b600060208284031215614c6a57600080fd5b813567ffffffffffffffff811115614c8157600080fd5b820160a08185031215610fa257600080fd5b600082601f830112614ca457600080fd5b81356020614cb46144c983614464565b82815260069290921b84018101918181019086841115614cd357600080fd5b8286015b848110156145155760408189031215614cf05760008081fd5b614cf861437d565b8135614d0381614488565b815281850135614d1281614488565b81860152835291830191604001614cd7565b60008060408385031215614d3757600080fd5b823567ffffffffffffffff80821115614d4f57600080fd5b614d5b86838701614c93565b93506020850135915080821115614d7157600080fd5b50614d7e85828601614c93565b9150509250929050565b60008083601f840112614d9a57600080fd5b50813567ffffffffffffffff811115614db257600080fd5b6020830191508360208260051b8501011115612a1657600080fd5b60008060008060008060008060e0898b031215614de957600080fd5b606089018a811115614dfa57600080fd5b8998503567ffffffffffffffff80821115614e1457600080fd5b818b0191508b601f830112614e2857600080fd5b813581811115614e3757600080fd5b8c6020828501011115614e4957600080fd5b6020830199508098505060808b0135915080821115614e6757600080fd5b614e738c838d01614d88565b909750955060a08b0135915080821115614e8c57600080fd5b50614e998b828c01614d88565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff8116811461427857600080fd5b600060608284031215614ee457600080fd5b614eec6143ed565b8235614ef7816146ec565b8152614f0560208401614eb2565b6020820152614f1660408401614eb2565b60408201529392505050565b604081526000614f356040830185614677565b8281036020840152612c208185614677565b60008060408385031215614f5a57600080fd5b823567ffffffffffffffff80821115614f7257600080fd5b614f7e8683870161480d565b93506020850135915080821115614f9457600080fd5b50614d7e8582860161478d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106f7576106f7614fa1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061502d5761502d614fe3565b92169190910692915050565b80820281158282048414176106f7576106f7614fa1565b600067ffffffffffffffff8084168061506b5761506b614fe3565b92169190910492915050565b602081016003831061508b5761508b61429a565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff8083168181036150d9576150d9614fa1565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526151138184018a614677565b905082810360808401526151278189614677565b905060ff871660a084015282810360c0840152615144818761430f565b905067ffffffffffffffff851660e0840152828103610100840152615169818561430f565b9c9b505050505050505050505050565b60006020828403121561518b57600080fd5b8151610fa281614257565b808201808211156106f7576106f7614fa1565b60008151808452602080850194506020840160005b838110156146b157815180516001600160a01b0316885283015183880152604090960195908201906001016151be565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c084015261522961012084018261430f565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e0860152615265838361430f565b92506080890151915080858403016101008601525061528482826151a9565b92505050615298602083018661ffff169052565b836040830152612c2060608301846001600160a01b03169052565b600082601f8301126152c457600080fd5b81516152d26144c982614531565b8181528460208386010111156152e757600080fd5b6127e08260208301602087016142eb565b60008060006060848603121561530d57600080fd5b8351615318816146ec565b602085015190935067ffffffffffffffff81111561533557600080fd5b615341868287016152b3565b925050604084015190509250925092565b805163ffffffff8116811461427857600080fd5b805161427881614488565b600060e0828403121561538357600080fd5b61538b614410565b61539483615352565b81526153a260208401615352565b6020820152604083015161ffff811681146153bc57600080fd5b60408201526153cd60608401615366565b60608201526153de60808401615366565b60808201526153ef60a08401615352565b60a082015261540060c08401615352565b60c08201529392505050565b6101c0810161547d82856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e084015260208401518116610100840152604084015161ffff1661012084015260608401516001600160a01b0390811661014085015260808501511661016084015260a0840151811661018084015260c0840151166101a0830152610fa2565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526155228285018b614677565b91508382036080850152615536828a614677565b915060ff881660a085015283820360c0850152615553828861430f565b90861660e08501528381036101008501529050615169818561430f565b60006020828403121561558257600080fd5b8151610fa2816146ec565b60008151808452602080850194506020840160005b838110156146b1578151875295820195908201906001016155a2565b6060815260006155d1606083018661558d565b82810360208401526155e3818661558d565b915050826040830152949350505050565b60006020828403121561560657600080fd5b5051919050565b67ffffffffffffffff8181168382160190808211156140d5576140d5614fa1565b67ffffffffffffffff8316815260408101610fa260208301846142c9565b600067ffffffffffffffff8083168181036150d9576150d9614fa1565b61567381846142c9565b6040602082015260006127e0604083018461430f565b60006020828403121561569b57600080fd5b813567ffffffffffffffff8111156156b257600080fd5b6127e084828501614a21565b6000602082840312156156d057600080fd5b815167ffffffffffffffff808211156156e857600080fd5b90830190606082860312156156fc57600080fd5b6157046143ed565b82518281111561571357600080fd5b61571f878286016152b3565b82525060208301518281111561573457600080fd5b615740878286016152b3565b60208301525060408301518281111561575857600080fd5b615764878286016152b3565b60408301525095945050505050565b602081526000610fa260208301846151a9565b60008282518085526020808601955060208260051b8401016020860160005b848110156157d357601f198684030189526157c183835161430f565b988401989250908301906001016157a5565b5090979650505050505050565b602081526000610fa26020830184615786565b6040815261580e60408201845167ffffffffffffffff169052565b6000602084015161582a60608401826001600160a01b03169052565b5060408401516001600160a01b038116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c084015161010061588b8185018367ffffffffffffffff169052565b60e086015191506101206158a9818601846001600160a01b03169052565b81870151925061014091508282860152808701519250506101a061016081818701526158d96101e087018561430f565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc061018081888703018189015261591886866151a9565b9550828a015194508188870301848901526159338686615786565b9550808a01516101c089015250505050508281036020840152612c208185615786565b6000815160208301517fffffffff000000000000000000000000000000000000000000000000000000008082169350600483101561599e5780818460040360031b1b83161693505b505050919050565b6000602082840312156159b857600080fd5b8151610fa281614488565b60208152600082516101008060208501526159e261012085018361430f565b915060208501516159ff604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615a3960a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615a56848361430f565b935060c08701519150808685030160e0870152615a73848361430f565b935060e0870151915080868503018387015250615a90838261430f565b9695505050505050565b600060408284031215615aac57600080fd5b615ab461437d565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114615ae057600080fd5b8152615aee60208401615352565b60208201529392505050565b600082615b0957615b09614fe3565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101a06040523480156200001257600080fd5b5060405162005e6138038062005e618339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615798620006c9600039600081816102ec01528181611a52015261309e0152600081816102bd01528181611a2a0152611cdc01526000818161028e01528181610e7f01528181610ee401528181611a000152818161228401526122ee01526000611e7b01526000818161025f01526119d60152600081816101ff015261197a01526000818161022f015281816119ae01528181611c9901528181612d0001526131af0152600081816101d0015281816119550152611f5b015260008181611bf30152611c3f01526157986000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806381ff7048116100d8578063afcb95d71161008c578063f077b59211610066578063f077b592146105f3578063f2fde38b14610609578063f52121a51461061c57600080fd5b8063afcb95d7146105ad578063b1dc65a4146105cd578063c92b2832146105e057600080fd5b8063856c8247116100bd578063856c82471461055d578063873504d7146105895780638da5cb5b1461059c57600080fd5b806381ff70481461051f57806385572ffb1461054f57600080fd5b8063599f64311161013a578063740f415011610114578063740f4150146104615780637437ff9f1461047457806379ba50971461051757600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516103299190613ed9565b60405180910390f35b610345610340366004613f6f565b61062f565b6040516103299190613fcf565b61038e6040518060400160405280601881526020017f45564d3245564d4f666652616d7020312e352e302d646576000000000000000081525081565b604051610329919061402d565b6103ae6103a9366004614256565b6106aa565b005b6103b8610a9e565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610b53565b6040516103299190614368565b6103ae61045c36600461437b565b610bb5565b6103ae61046f3660046147db565b610c7e565b61050a6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a01000000000000000000009091046001600160a01b039081166060830152600b5416608082015290565b6040516103299190614896565b6103ae610d70565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae6101823660046148ec565b61057061056b36600461437b565b610e53565b60405167ffffffffffffffff9091168152602001610329565b6103ae6105973660046149b8565b610f56565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae6105db366004614a61565b611124565b6103ae6105ee366004614b66565b61132f565b6105fb61139a565b604051610329929190614bd4565b6103ae61061736600461437b565b6114c0565b6103ae61062a366004614bf9565b6114d1565b600061063d60016004614c82565b600261064a608085614cc4565b67ffffffffffffffff1661065e9190614ceb565b6010600061066d608087614d02565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106a4576106a4613f8c565b92915050565b84518460ff16601f8211156106f75760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614d29565b60405180910390fd5b806000036107345760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614d29565b61073c611771565b610745856117e7565b60095460005b818110156107bc57600860006009838154811061076a5761076a614d43565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161074b565b5050865160005b8181101561095f5760008982815181106107df576107df614d43565b60200260200101519050600060028111156107fc576107fc613f8c565b6001600160a01b038216600090815260086020526040902054610100900460ff16600281111561082e5761082e613f8c565b146108685760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614d29565b6001600160a01b0381166108a8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561094b5761094b613f8c565b0217905550905050508060010190506107c3565b5087516109739060099060208b0190613e47565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a1617179055600780546109f99146913091906000906109cb9063ffffffff16614d72565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611ab1565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610a8a9487949293918316921691909117908f908f908f908f908f908f90614d95565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610b4e90611b3e565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bab57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8d575b5050505050905090565b6000546001600160a01b03163314801590610bdb57506002546001600160a01b03163314155b15610c12576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b610c86611bf0565b81515181518114610cc3576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d60576000838281518110610ce257610ce2614d43565b6020026020010151905080600014610d57578451805183908110610d0857610d08614d43565b602002602001015160800151811015610d57576040517f085e39cf00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016106ee565b50600101610cc6565b50610d6b8383611c71565b505050565b6001546001600160a01b03163314610de4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106ee565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106a4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106a4576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4f9190614e2b565b9392505050565b610f5e611771565b60005b825181101561103157610f9b838281518110610f7f57610f7f614d43565b602002602001015160200151600c6126f490919063ffffffff16565b15611029577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d58782838281518110610fd357610fd3614d43565b602002602001015160000151848381518110610ff157610ff1614d43565b6020026020010151602001516040516110209291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610f61565b5060005b8151811015610d6b5761108e82828151811061105357611053614d43565b60200260200101516020015183838151811061107157611071614d43565b602002602001015160000151600c6127099092919063ffffffff16565b1561111c577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a8282815181106110c6576110c6614d43565b6020026020010151600001518383815181106110e4576110e4614d43565b6020026020010151602001516040516111139291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101611035565b61112e8787612727565b600554883590808214611177576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016106ee565b61117f611bf0565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561120757611207613f8c565b600281111561121857611218613f8c565b905250905060028160200151600281111561123557611235613f8c565b14801561126f57506009816000015160ff168154811061125757611257614d43565b6000918252602090912001546001600160a01b031633145b6112a5576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006112b3856020614ceb565b6112be886020614ceb565b6112ca8b610144614e48565b6112d49190614e48565b6112de9190614e48565b9050368114611322576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016106ee565b5050505050505050505050565b6000546001600160a01b0316331480159061135557506002546001600160a01b03163314155b1561138c576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61139760038261274e565b50565b60608060006113a9600c612933565b90508067ffffffffffffffff8111156113c4576113c4614040565b6040519080825280602002602001820160405280156113ed578160200160208202803683370190505b5092508067ffffffffffffffff81111561140957611409614040565b604051908082528060200260200182016040528015611432578160200160208202803683370190505b50915060005b818110156114ba5760008061144e600c8461293e565b915091508086848151811061146557611465614d43565b60200260200101906001600160a01b031690816001600160a01b0316815250508185848151811061149857611498614d43565b6001600160a01b03909216602092830291909101909101525050600101611438565b50509091565b6114c8611771565b6113978161295c565b33301461150a576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611547565b60408051808201909152600080825260208201528152602001906001900390816115205790505b5061014084015151909150156115a7576115a4836101400151846020015160405160200161158491906001600160a01b0391909116815260200190565b604051602081830303815290604052856040015186610160015186612a37565b90505b610120830151511580156115bd57506080830151155b806115d4575060408301516001600160a01b03163b155b8061161457506040830151611612906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612b68565b155b1561161e57505050565b600080600a600001600a9054906101000a90046001600160a01b03166001600160a01b0316633cf979836040518060a001604052808861018001518152602001886000015167ffffffffffffffff168152602001886020015160405160200161169691906001600160a01b0391909116815260200190565b6040516020818303038152906040528152602001886101200151815260200186815250611388886080015189604001516040518563ffffffff1660e01b81526004016116e59493929190614ea0565b6000604051808303816000875af1158015611704573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261172c9190810190614faa565b50915091508161176a57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016106ee919061402d565b5050505050565b6000546001600160a01b031633146117e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106ee565b565b6000818060200190518101906117fd9190615018565b60608101519091506001600160a01b0316611844576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a01000000000000000000006001600160a01b039485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611aa59184906150b3565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611ad599989796959493929190615175565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611bcc82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611bb09190614c82565b85608001516fffffffffffffffffffffffffffffffff16612b84565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b467f0000000000000000000000000000000000000000000000000000000000000000146117e5576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016106ee565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d4f91906151fd565b15611d86576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151516000819003611dc3576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114611e01576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff811115611e1c57611e1c614040565b604051908082528060200260200182016040528015611e45578160200160208202803683370190505b50905060005b82811015611f1d57600085600001518281518110611e6b57611e6b614d43565b60200260200101519050611e9f817f0000000000000000000000000000000000000000000000000000000000000000612ba3565b838381518110611eb157611eb1614d43565b602002602001018181525050806101800151838381518110611ed557611ed5614d43565b602002602001015114611f14576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101611e4b565b50604080850151606086015191517f320488750000000000000000000000000000000000000000000000000000000081526000926001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692633204887592611f919287929160040161524b565b602060405180830381865afa158015611fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd29190615281565b90508060000361200e576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b848110156126eb5760008760000151828151811061203557612035614d43565b60200260200101519050600061204e826060015161062f565b9050600281600381111561206457612064613f8c565b036120ab57816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a250506126e3565b60008160038111156120bf576120bf613f8c565b14806120dc575060038160038111156120da576120da613f8c565b145b6121245760608201516040517f50a6e05200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016106ee565b83156121e157600a5460009063ffffffff166121408742614c82565b11905080806121605750600382600381111561215e5761215e613f8c565b145b612196576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8884815181106121a8576121a8614d43565b60200260200101516000146121db578884815181106121c9576121c9614d43565b60200260200101518360800181815250505b5061223e565b60008160038111156121f5576121f5613f8c565b1461223e5760608201516040517f67d9ba0f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016106ee565b60c082015167ffffffffffffffff16156124bd576020808301516001600160a01b03166000908152600f909152604081205467ffffffffffffffff1690819003612428577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156124285760208301516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa158015612337573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235b9190614e2b565b60c084015190915067ffffffffffffffff1661237882600161529a565b67ffffffffffffffff16146123d85782602001516001600160a01b03168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a35050506126e3565b6020838101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b600082600381111561243c5761243c613f8c565b036124bb5760c083015167ffffffffffffffff1661245b82600161529a565b67ffffffffffffffff16146124bb5782602001516001600160a01b03168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a35050506126e3565b505b6000896020015184815181106124d5576124d5614d43565b602002602001015190506125018360600151846000015185610140015151866101200151518551612cfe565b61251083606001516001612e78565b60008061251d8584612f22565b9150915061252f856060015183612e78565b861561259b57600382600381111561254957612549613f8c565b0361259b57600084600381111561256257612562613f8c565b1461259b57806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016106ee919061402d565b60028260038111156125af576125af613f8c565b146126075760038260038111156125c8576125c8613f8c565b14612607578460600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016106ee9291906152bb565b60c085015167ffffffffffffffff161561268f57600084600381111561262f5761262f613f8c565b0361268f576020808601516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff1691612667836152d9565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b846101800151856060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef6584846040516126d59291906152f6565b60405180910390a350505050505b600101612015565b50505050505050565b6000610f4f836001600160a01b038416612feb565b600061271f846001600160a01b03851684612ff7565b949350505050565b61274a61273682840184615316565b604080516000815260208101909152611c71565b5050565b815460009061277790700100000000000000000000000000000000900463ffffffff1642614c82565b9050801561281957600183015483546127bf916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b84565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461283f916fffffffffffffffffffffffffffffffff908116911661300d565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906129269084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106a482613023565b600080808061294d868661302e565b909450925050505b9250929050565b336001600160a01b038216036129ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106ee565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b846000805b8751811015612b4d57612ab4888281518110612a5a57612a5a614d43565b6020026020010151602001518888888581518110612a7a57612a7a614d43565b6020026020010151806020019051810190612a95919061534b565b888681518110612aa757612aa7614d43565b602002602001015161303d565b838281518110612ac657612ac6614d43565b6020026020010181905250612b02838281518110612ae657612ae6614d43565b602002602001015160000151600c61343d90919063ffffffff16565b15612b4557612b38838281518110612b1c57612b1c614d43565b6020908102919091010151600b546001600160a01b0316613452565b612b429083614e48565b91505b600101612a3c565b508015612b5d57612b5d81613573565b505b95945050505050565b6000612b7383613580565b8015610f4f5750610f4f83836135e4565b6000612b5f85612b948486614ceb565b612b9e9087614e48565b61300d565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612c399897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612c729190615411565b60405160208183030381529060405280519060200120876101600151604051602001612c9e919061547e565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff1614612d77576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016106ee565b600a5468010000000000000000900461ffff16831115612dcf576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b808314612e14576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b600a54640100000000900463ffffffff1682111561176a57600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff166004820152602481018390526044016106ee565b60006002612e87608085614cc4565b67ffffffffffffffff16612e9b9190614ceb565b90506000601081612ead608087614d02565b67ffffffffffffffff168152602081019190915260400160002054905081612ed760016004614c82565b901b191681836003811115612eee57612eee613f8c565b901b178060106000612f01608088614d02565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a590612f669087908790600401615491565b600060405180830381600087803b158015612f8057600080fd5b505af1925050508015612f91575060015b612fd0573d808015612fbf576040519150601f19603f3d011682016040523d82523d6000602084013e612fc4565b606091505b50600392509050612955565b50506040805160208101909152600081526002909250929050565b6000610f4f83836136b3565b600061271f84846001600160a01b0385166136d0565b600081831061301c5781610f4f565b5090919050565b60006106a4826136ed565b600080808061294d86866136f8565b604080518082019091526000808252602082015260006130608460200151613723565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa1580156130e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310991906155f4565b90506001600160a01b0381161580613151575061314f6001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612b68565b155b15613193576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016106ee565b60008060006132986040518061010001604052808c81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018b6001600160a01b031681526020018d8152602001876001600160a01b031681526020018a6000015181526020018a604001518152602001898152506040516024016132299190615611565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905260608a0151869063ffffffff1661138860846137c9565b925092509250826132d757816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee919061402d565b815160201461331f5781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b6000828060200190518101906133359190615281565b6040516001600160a01b038c166024820152604481018290529091506133d29060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905260608b015188906133c890869063ffffffff16614c82565b61138860846137c9565b5090945092508361341157826040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee919061402d565b604080518082019091526001600160a01b03909616865260208601525092935050505095945050505050565b6000610f4f836001600160a01b0384166138ef565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa1580156134b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134dc91906156e8565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036135455783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016106ee565b602084015161271f907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316906138fb565b6113976003826000613938565b60006135ac827f01ffc9a7000000000000000000000000000000000000000000000000000000006135e4565b80156106a457506135dd827fffffffff000000000000000000000000000000000000000000000000000000006135e4565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561369c575060208210155b80156136a85750600081115b979650505050505050565b60008181526002830160205260408120819055610f4f8383613c87565b6000828152600284016020526040812082905561271f8484613c93565b60006106a482613c9f565b600080806137068585613ca9565b600081815260029690960160205260409095205494959350505050565b6000815160201461376257816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee919061402d565b6000828060200190518101906137789190615281565b90506001600160a01b03811180613790575061040081105b156106a457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee919061402d565b6000606060008361ffff1667ffffffffffffffff8111156137ec576137ec614040565b6040519080825280601f01601f191660200182016040528015613816576020820181803683370190505b509150863b613849577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a8581101561387c577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b85900360408104810387106138b5577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156138d85750835b808352806000602085013e50955095509592505050565b6000610f4f8383613cb5565b6000670de0b6b3a764000061392e837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616614ceb565b610f4f9190615748565b825474010000000000000000000000000000000000000000900460ff16158061395f575081155b1561396957505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906139af90700100000000000000000000000000000000900463ffffffff1642614c82565b90508015613a6f57818311156139f1576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613a2b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b84565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613b0c576001600160a01b038416613ac1576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106ee565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b03851660448201526064016106ee565b84831015613c055760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613b509082614c82565b613b5a878a614c82565b613b649190614e48565b613b6e9190615748565b90506001600160a01b038616613bba576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106ee565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b03871660448201526064016106ee565b613c0f8584614c82565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f4f8383613cd4565b6000610f4f8383613dce565b60006106a4825490565b6000610f4f8383613e1d565b6000610f4f838360008181526001830160205260408120541515610f4f565b60008181526001830160205260408120548015613dbd576000613cf8600183614c82565b8554909150600090613d0c90600190614c82565b9050818114613d71576000866000018281548110613d2c57613d2c614d43565b9060005260206000200154905080876000018481548110613d4f57613d4f614d43565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613d8257613d8261575c565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106a4565b60009150506106a4565b5092915050565b6000818152600183016020526040812054613e15575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106a4565b5060006106a4565b6000826000018281548110613e3457613e34614d43565b9060005260206000200154905092915050565b828054828255906000526020600020908101928215613eb4579160200282015b82811115613eb457825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190613e67565b50613ec0929150613ec4565b5090565b5b80821115613ec05760008155600101613ec5565b60e081016106a482846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff8116811461139757600080fd5b8035613f6a81613f49565b919050565b600060208284031215613f8157600080fd5b8135610f4f81613f49565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110613fcb57613fcb613f8c565b9052565b602081016106a48284613fbb565b60005b83811015613ff8578181015183820152602001613fe0565b50506000910152565b60008151808452614019816020860160208601613fdd565b601f01601f19169290920160200192915050565b602081526000610f4f6020830184614001565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561409257614092614040565b60405290565b6040516101a0810167ffffffffffffffff8111828210171561409257614092614040565b6040516080810167ffffffffffffffff8111828210171561409257614092614040565b604051601f8201601f1916810167ffffffffffffffff8111828210171561410857614108614040565b604052919050565b600067ffffffffffffffff82111561412a5761412a614040565b5060051b60200190565b6001600160a01b038116811461139757600080fd5b8035613f6a81614134565b600082601f83011261416557600080fd5b8135602061417a61417583614110565b6140df565b8083825260208201915060208460051b87010193508684111561419c57600080fd5b602086015b848110156141c15780356141b481614134565b83529183019183016141a1565b509695505050505050565b803560ff81168114613f6a57600080fd5b600067ffffffffffffffff8211156141f7576141f7614040565b50601f01601f191660200190565b600082601f83011261421657600080fd5b8135614224614175826141dd565b81815284602083860101111561423957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561426f57600080fd5b863567ffffffffffffffff8082111561428757600080fd5b6142938a838b01614154565b975060208901359150808211156142a957600080fd5b6142b58a838b01614154565b96506142c360408a016141cc565b955060608901359150808211156142d957600080fd5b6142e58a838b01614205565b94506142f360808a01613f5f565b935060a089013591508082111561430957600080fd5b5061431689828a01614205565b9150509295509295509295565b60008151808452602080850194506020840160005b8381101561435d5781516001600160a01b031687529582019590820190600101614338565b509495945050505050565b602081526000610f4f6020830184614323565b60006020828403121561438d57600080fd5b8135610f4f81614134565b801515811461139757600080fd5b8035613f6a81614398565b600082601f8301126143c257600080fd5b813560206143d261417583614110565b82815260069290921b840181019181810190868411156143f157600080fd5b8286015b848110156141c1576040818903121561440e5760008081fd5b61441661406f565b813561442181614134565b815281850135858201528352918301916040016143f5565b600082601f83011261444a57600080fd5b8135602061445a61417583614110565b82815260059290921b8401810191818101908684111561447957600080fd5b8286015b848110156141c157803567ffffffffffffffff81111561449d5760008081fd5b6144ab8986838b0101614205565b84525091830191830161447d565b60006101a082840312156144cc57600080fd5b6144d4614098565b90506144df82613f5f565b81526144ed60208301614149565b60208201526144fe60408301614149565b604082015261450f60608301613f5f565b60608201526080820135608082015261452a60a083016143a6565b60a082015261453b60c08301613f5f565b60c082015261454c60e08301614149565b60e082015261010082810135908201526101208083013567ffffffffffffffff8082111561457957600080fd5b61458586838701614205565b838501526101409250828501359150808211156145a157600080fd5b6145ad868387016143b1565b838501526101609250828501359150808211156145c957600080fd5b506145d685828601614439565b82840152505061018080830135818301525092915050565b600082601f8301126145ff57600080fd5b8135602061460f61417583614110565b82815260059290921b8401810191818101908684111561462e57600080fd5b8286015b848110156141c157803567ffffffffffffffff8111156146525760008081fd5b6146608986838b0101614439565b845250918301918301614632565b600082601f83011261467f57600080fd5b8135602061468f61417583614110565b8083825260208201915060208460051b8701019350868411156146b157600080fd5b602086015b848110156141c157803583529183019183016146b6565b6000608082840312156146df57600080fd5b6146e76140bc565b9050813567ffffffffffffffff8082111561470157600080fd5b818401915084601f83011261471557600080fd5b8135602061472561417583614110565b82815260059290921b8401810191818101908884111561474457600080fd5b8286015b8481101561477c578035868111156147605760008081fd5b61476e8b86838b01016144b9565b845250918301918301614748565b508652508581013593508284111561479357600080fd5b61479f878588016145ee565b908501525060408401359150808211156147b857600080fd5b506147c58482850161466e565b6040830152506060820135606082015292915050565b600080604083850312156147ee57600080fd5b823567ffffffffffffffff8082111561480657600080fd5b614812868387016146cd565b935060209150818501358181111561482957600080fd5b85019050601f8101861361483c57600080fd5b803561484a61417582614110565b81815260059190911b8201830190838101908883111561486957600080fd5b928401925b828410156148875783358252928401929084019061486e565b80955050505050509250929050565b60a081016106a4828463ffffffff8082511683528060208301511660208401525061ffff604082015116604083015260608101516001600160a01b03808216606085015280608084015116608085015250505050565b6000602082840312156148fe57600080fd5b813567ffffffffffffffff81111561491557600080fd5b820160a08185031215610f4f57600080fd5b600082601f83011261493857600080fd5b8135602061494861417583614110565b82815260069290921b8401810191818101908684111561496757600080fd5b8286015b848110156141c157604081890312156149845760008081fd5b61498c61406f565b813561499781614134565b8152818501356149a681614134565b8186015283529183019160400161496b565b600080604083850312156149cb57600080fd5b823567ffffffffffffffff808211156149e357600080fd5b6149ef86838701614927565b93506020850135915080821115614a0557600080fd5b50614a1285828601614927565b9150509250929050565b60008083601f840112614a2e57600080fd5b50813567ffffffffffffffff811115614a4657600080fd5b6020830191508360208260051b850101111561295557600080fd5b60008060008060008060008060e0898b031215614a7d57600080fd5b606089018a811115614a8e57600080fd5b8998503567ffffffffffffffff80821115614aa857600080fd5b818b0191508b601f830112614abc57600080fd5b813581811115614acb57600080fd5b8c6020828501011115614add57600080fd5b6020830199508098505060808b0135915080821115614afb57600080fd5b614b078c838d01614a1c565b909750955060a08b0135915080821115614b2057600080fd5b50614b2d8b828c01614a1c565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff81168114613f6a57600080fd5b600060608284031215614b7857600080fd5b6040516060810181811067ffffffffffffffff82111715614b9b57614b9b614040565b6040528235614ba981614398565b8152614bb760208401614b46565b6020820152614bc860408401614b46565b60408201529392505050565b604081526000614be76040830185614323565b8281036020840152612b5f8185614323565b60008060408385031215614c0c57600080fd5b823567ffffffffffffffff80821115614c2457600080fd5b614c30868387016144b9565b93506020850135915080821115614c4657600080fd5b50614a1285828601614439565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106a4576106a4614c53565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680614cdf57614cdf614c95565b92169190910692915050565b80820281158282048414176106a4576106a4614c53565b600067ffffffffffffffff80841680614d1d57614d1d614c95565b92169190910492915050565b6020810160038310614d3d57614d3d613f8c565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103614d8b57614d8b614c53565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614dc58184018a614323565b90508281036080840152614dd98189614323565b905060ff871660a084015282810360c0840152614df68187614001565b905067ffffffffffffffff851660e0840152828103610100840152614e1b8185614001565b9c9b505050505050505050505050565b600060208284031215614e3d57600080fd5b8151610f4f81613f49565b808201808211156106a4576106a4614c53565b60008151808452602080850194506020840160005b8381101561435d57815180516001600160a01b031688528301518388015260409096019590820190600101614e70565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152614edb610120840182614001565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e0860152614f178383614001565b925060808901519150808584030161010086015250614f368282614e5b565b92505050614f4a602083018661ffff169052565b836040830152612b5f60608301846001600160a01b03169052565b600082601f830112614f7657600080fd5b8151614f84614175826141dd565b818152846020838601011115614f9957600080fd5b61271f826020830160208701613fdd565b600080600060608486031215614fbf57600080fd5b8351614fca81614398565b602085015190935067ffffffffffffffff811115614fe757600080fd5b614ff386828701614f65565b925050604084015190509250925092565b805163ffffffff81168114613f6a57600080fd5b600060a0828403121561502a57600080fd5b60405160a0810181811067ffffffffffffffff8211171561504d5761504d614040565b60405261505983615004565b815261506760208401615004565b6020820152604083015161ffff8116811461508157600080fd5b6040820152606083015161509481614134565b606082015260808301516150a781614134565b60808201529392505050565b610180810161512482856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff1661012083015260608301516001600160a01b03908116610140840152608084015116610160830152610f4f565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526151af8285018b614323565b915083820360808501526151c3828a614323565b915060ff881660a085015283820360c08501526151e08288614001565b90861660e08501528381036101008501529050614e1b8185614001565b60006020828403121561520f57600080fd5b8151610f4f81614398565b60008151808452602080850194506020840160005b8381101561435d5781518752958201959082019060010161522f565b60608152600061525e606083018661521a565b8281036020840152615270818661521a565b915050826040830152949350505050565b60006020828403121561529357600080fd5b5051919050565b67ffffffffffffffff818116838216019080821115613dc757613dc7614c53565b67ffffffffffffffff8316815260408101610f4f6020830184613fbb565b600067ffffffffffffffff808316818103614d8b57614d8b614c53565b6153008184613fbb565b60406020820152600061271f6040830184614001565b60006020828403121561532857600080fd5b813567ffffffffffffffff81111561533f57600080fd5b61271f848285016146cd565b60006020828403121561535d57600080fd5b815167ffffffffffffffff8082111561537557600080fd5b908301906080828603121561538957600080fd5b6153916140bc565b8251828111156153a057600080fd5b6153ac87828601614f65565b8252506020830151828111156153c157600080fd5b6153cd87828601614f65565b6020830152506040830151828111156153e557600080fd5b6153f187828601614f65565b60408301525061540360608401615004565b606082015295945050505050565b602081526000610f4f6020830184614e5b565b60008282518085526020808601955060208260051b8401016020860160005b8481101561547157601f1986840301895261545f838351614001565b98840198925090830190600101615443565b5090979650505050505050565b602081526000610f4f6020830184615424565b604081526154ac60408201845167ffffffffffffffff169052565b600060208401516154c860608401826001600160a01b03169052565b5060408401516001600160a01b038116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c08401516101006155298185018367ffffffffffffffff169052565b60e08601519150610120615547818601846001600160a01b03169052565b81870151925061014091508282860152808701519250506101a061016081818701526155776101e0870185614001565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc06101808188870301818901526155b68686614e5b565b9550828a015194508188870301848901526155d18686615424565b9550808a01516101c089015250505050508281036020840152612b5f8185615424565b60006020828403121561560657600080fd5b8151610f4f81614134565b6020815260008251610100806020850152615630610120850183614001565b9150602085015161564d604086018267ffffffffffffffff169052565b5060408501516001600160a01b03811660608601525060608501516080850152608085015161568760a08601826001600160a01b03169052565b5060a0850151601f19808685030160c08701526156a48483614001565b935060c08701519150808685030160e08701526156c18483614001565b935060e08701519150808685030183870152506156de8382614001565b9695505050505050565b6000604082840312156156fa57600080fd5b61570261406f565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461572e57600080fd5b815261573c60208401615004565b60208201529392505050565b60008261575757615757614c95565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var EVM2EVMOffRampABI = EVM2EVMOffRampMetaData.ABI @@ -2481,7 +2479,7 @@ func (EVM2EVMOffRampConfigChanged) Topic() common.Hash { } func (EVM2EVMOffRampConfigSet) Topic() common.Hash { - return common.HexToHash("0xf02fcc22535d64d92d17b995475893d63edd51da163fed74a6ee9b4bc4895cc4") + return common.HexToHash("0x7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d611260") } func (EVM2EVMOffRampConfigSet0) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go index be9c2395a0..d186229b59 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go @@ -56,7 +56,6 @@ type EVM2EVMOnRampDynamicConfig struct { MaxPerMsgGasLimit uint32 DefaultTokenFeeUSDCents uint16 DefaultTokenDestGasOverhead uint32 - DefaultTokenDestBytesOverhead uint32 EnforceOutOfOrder bool } @@ -142,8 +141,8 @@ type RateLimiterTokenBucket struct { } var EVM2EVMOnRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidChainSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"}],\"name\":\"InvalidNopAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWithdrawParams\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkBalanceNotSettled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeeBalanceReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoFeesToPay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoNopsToPay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdminOrNop\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyNops\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeConfig\",\"type\":\"tuple[]\"}],\"name\":\"FeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NopPaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nopWeightsTotal\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"NopsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"transferFeeConfig\",\"type\":\"tuple[]\"}],\"name\":\"TokenTransferFeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getFeeTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfig\",\"name\":\"feeTokenConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNopFeesJuels\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNops\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"weightsTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setFeeTokenConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"address[]\"}],\"name\":\"setTokenTransferFeeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawNonLinkFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101a06040523480156200001257600080fd5b50604051620082d4380380620082d4833981016040819052620000359162001b0e565b8333806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c0816200030b565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555085516001600160a01b0316158062000169575060208601516001600160401b0316155b8062000180575060408601516001600160401b0316155b8062000197575060608601516001600160401b0316155b80620001ae575060c08601516001600160a01b0316155b80620001c5575060e08601516001600160a01b0316155b15620001e4576040516306b7c75960e31b815260040160405180910390fd5b60208087015160408089015181517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3948101949094526001600160401b039283169184019190915216606082015230608082015260a00160408051601f198184030181529181528151602092830120608090815288516001600160a01b0390811660e0908152938a01516001600160401b0390811661010052928a015183166101205260608a015190921660a0908152908901516001600160601b031660c090815290890151821661014052880151811661016052908701511661018052620002cd85620003b6565b620002d8836200071a565b604080516000815260208101909152620002f49083906200084a565b620002ff8162000aea565b50505050505062002212565b336001600160a01b03821603620003655760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e08101516001600160a01b0316620003e2576040516306b7c75960e31b815260040160405180910390fd5b602081610180015163ffffffff16101562000427576101808101516040516312766e0160e11b81526000600482015263ffffffff909116602482015260440162000084565b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548163ffffffff021916908363ffffffff1602179055506101a082015181600201600a6101000a81548160ff0219169083151502179055509050507fe375c8cb6ea9807cd0371503b632b93da5ee0f1f64205db8b5b28b95d6b588b060405180610100016040528060e0516001600160a01b03168152602001610100516001600160401b03168152602001610120516001600160401b0316815260200160a0516001600160401b0316815260200160c0516001600160601b03168152602001610140516001600160a01b03168152602001610160516001600160a01b03168152602001610180516001600160a01b0316815250826040516200070f92919062001da4565b60405180910390a150565b60005b8151811015620008185760008282815181106200073e576200073e62001e69565b60209081029190910181015160408051608080820183528385015163ffffffff9081168352838501516001600160401b03908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b0260ff60a01b199688166c010000000000000000000000000296909616600160601b600160a81b031993909716640100000000026001600160601b0319909516911617929092179190911692909217179055506001016200071d565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e816040516200070f919062001e7f565b60005b825181101562000a095760008382815181106200086e576200086e62001e69565b6020026020010151905060208160a0015163ffffffff161015620008c457805160a08201516040516312766e0160e11b81526001600160a01b03909216600483015263ffffffff16602482015260440162000084565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087166001600160401b031990961695909517640100000000928716929092029190911765ffffffffffff60401b191668010000000000000000939092169290920263ffffffff60501b1916176a0100000000000000000000918416919091021764ffffffffff60701b1916600160701b939092169290920260ff60901b191617600160901b941515949094029390931760ff60981b1916600160981b9315159390930292909217909155016200084d565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d08260405162000a3b919062001f0e565b60405180910390a160005b815181101562000aa357600c600083838151811062000a695762000a6962001e69565b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160a01b031916905560010162000a46565b5080511562000ae6577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b8160405162000add919062001fa3565b60405180910390a15b5050565b8051604081111562000b0f57604051635ad0867d60e11b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff161562000b6257600e5463ffffffff6c010000000000000000000000008204166001600160601b039091161062000b625762000b6262000d05565b600062000b70600862000ef1565b90505b801562000bbc57600062000b9662000b8d60018462002008565b60089062000f04565b50905062000ba660088262000f22565b50508062000bb4906200201e565b905062000b73565b506000805b8281101562000c9c57600084828151811062000be15762000be162001e69565b6020026020010151600001519050600085838151811062000c065762000c0662001e69565b602002602001015160200151905060e0516001600160a01b0316826001600160a01b0316148062000c3e57506001600160a01b038216155b1562000c6957604051634de938d160e01b81526001600160a01b038316600482015260240162000084565b62000c7b60088361ffff841662000f40565b5062000c8c61ffff82168562002038565b9350505080600101905062000bc1565b50600e805463ffffffff60601b19166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249062000cf8908390869062002058565b60405180910390a1505050565b6000546001600160a01b0316331462000d56576002546001600160a01b0316331462000d565762000d3860083362000f60565b62000d565760405163032bb72b60e31b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff16600081900362000d925760405163990e30bf60e01b815260040160405180910390fd5b600e546001600160601b03168181101562000dc0576040516311a1ee3b60e31b815260040160405180910390fd5b600062000dcc62000f77565b121562000dec57604051631e9acf1760e31b815260040160405180910390fd5b80600062000dfb600862000ef1565b905060005b8181101562000ecb5760008062000e1960088462000f04565b909250905060008762000e36836001600160601b038a16620020c8565b62000e429190620020e2565b905062000e50818762002105565b60e05190965062000e75906001600160a01b0316846001600160601b03841662001005565b6040516001600160601b03821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a250505080600101905062000e00565b5050600e80546001600160601b0319166001600160601b03929092169190911790555050565b600062000efe8262001062565b92915050565b600080808062000f1586866200106f565b9097909650945050505050565b600062000f39836001600160a01b0384166200109c565b9392505050565b600062000f58846001600160a01b03851684620010bb565b949350505050565b600062000f39836001600160a01b038416620010da565b600e5460e0516040516370a0823160e01b81523060048201526000926001600160601b0316916001600160a01b0316906370a0823190602401602060405180830381865afa15801562000fce573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ff4919062002128565b62001000919062002142565b905090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b179091526200105d918591620010e816565b505050565b600062000efe82620011b9565b600080806200107f8585620011c4565b600081815260029690960160205260409095205494959350505050565b6000818152600283016020526040812081905562000f398383620011d2565b6000828152600284016020526040812082905562000f588484620011e0565b600062000f398383620011ee565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062001137906001600160a01b03851690849062001207565b8051909150156200105d578080602001905181019062001158919062002165565b6200105d5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000084565b600062000efe825490565b600062000f39838362001218565b600062000f39838362001245565b600062000f39838362001350565b6000818152600183016020526040812054151562000f39565b606062000f588484600085620013a2565b600082600001828154811062001232576200123262001e69565b9060005260206000200154905092915050565b600081815260018301602052604081205480156200133e5760006200126c60018362002008565b8554909150600090620012829060019062002008565b9050818114620012ee576000866000018281548110620012a657620012a662001e69565b9060005260206000200154905080876000018481548110620012cc57620012cc62001e69565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062001302576200130262002183565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000efe565b600091505062000efe565b5092915050565b6000818152600183016020526040812054620013995750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000efe565b50600062000efe565b606082471015620014055760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000084565b600080866001600160a01b03168587604051620014239190620021bf565b60006040518083038185875af1925050503d806000811462001462576040519150601f19603f3d011682016040523d82523d6000602084013e62001467565b606091505b5090925090506200147b8783838762001486565b979650505050505050565b60608315620014fa578251600003620014f2576001600160a01b0385163b620014f25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000084565b508162000f58565b62000f588383815115620015115781518083602001fd5b8060405162461bcd60e51b8152600401620000849190620021dd565b634e487b7160e01b600052604160045260246000fd5b6040516101c081016001600160401b03811182821017156200156957620015696200152d565b60405290565b60405160a081016001600160401b03811182821017156200156957620015696200152d565b60405160e081016001600160401b03811182821017156200156957620015696200152d565b604080519081016001600160401b03811182821017156200156957620015696200152d565b60405161010081016001600160401b03811182821017156200156957620015696200152d565b604051601f8201601f191681016001600160401b03811182821017156200162f576200162f6200152d565b604052919050565b80516001600160a01b03811681146200164f57600080fd5b919050565b80516001600160401b03811681146200164f57600080fd5b805161ffff811681146200164f57600080fd5b805163ffffffff811681146200164f57600080fd5b805180151581146200164f57600080fd5b60006101c08284031215620016b957600080fd5b620016c362001543565b9050620016d08262001637565b8152620016e0602083016200166c565b6020820152620016f3604083016200167f565b604082015262001706606083016200166c565b606082015262001719608083016200167f565b60808201526200172c60a083016200166c565b60a08201526200173f60c083016200166c565b60c08201526200175260e0830162001637565b60e0820152610100620017678184016200167f565b908201526101206200177b8382016200167f565b908201526101406200178f8382016200166c565b90820152610160620017a38382016200167f565b90820152610180620017b78382016200167f565b908201526101a0620017cb83820162001694565b9082015292915050565b80516001600160801b03811681146200164f57600080fd5b6000606082840312156200180057600080fd5b604051606081016001600160401b03811182821017156200182557620018256200152d565b604052905080620018368362001694565b81526200184660208401620017d5565b60208201526200185960408401620017d5565b60408201525092915050565b60006001600160401b038211156200188157620018816200152d565b5060051b60200190565b600082601f8301126200189d57600080fd5b81516020620018b6620018b08362001865565b62001604565b82815260a09283028501820192828201919087851115620018d657600080fd5b8387015b85811015620019635781818a031215620018f45760008081fd5b620018fe6200156f565b620019098262001637565b8152620019188683016200167f565b8682015260406200192b81840162001654565b9082015260606200193e83820162001654565b9082015260806200195183820162001694565b908201528452928401928101620018da565b5090979650505050505050565b600082601f8301126200198257600080fd5b8151602062001995620018b08362001865565b82815260e09283028501820192828201919087851115620019b557600080fd5b8387015b85811015620019635781818a031215620019d35760008081fd5b620019dd62001594565b620019e88262001637565b8152620019f78683016200167f565b86820152604062001a0a8184016200167f565b90820152606062001a1d8382016200166c565b90820152608062001a308382016200167f565b9082015260a062001a438382016200167f565b9082015260c062001a5683820162001694565b908201528452928401928101620019b9565b600082601f83011262001a7a57600080fd5b8151602062001a8d620018b08362001865565b82815260069290921b8401810191818101908684111562001aad57600080fd5b8286015b8481101562001b03576040818903121562001acc5760008081fd5b62001ad6620015b9565b62001ae18262001637565b815262001af08583016200166c565b8186015283529183019160400162001ab1565b509695505050505050565b60008060008060008086880361038081121562001b2a57600080fd5b6101008082121562001b3b57600080fd5b62001b45620015de565b915062001b528962001637565b825262001b6260208a0162001654565b602083015262001b7560408a0162001654565b604083015262001b8860608a0162001654565b606083015260808901516001600160601b038116811462001ba857600080fd5b608083015262001bbb60a08a0162001637565b60a083015262001bce60c08a0162001637565b60c083015262001be160e08a0162001637565b60e083015281975062001bf78a828b01620016a5565b9650505062001c0b886102c08901620017ed565b6103208801519094506001600160401b038082111562001c2a57600080fd5b62001c388a838b016200188b565b945061034089015191508082111562001c5057600080fd5b62001c5e8a838b0162001970565b935061036089015191508082111562001c7657600080fd5b5062001c8589828a0162001a68565b9150509295509295509295565b80516001600160a01b03168252602081015162001cb5602084018261ffff169052565b50604081015162001cce604084018263ffffffff169052565b50606081015162001ce5606084018261ffff169052565b50608081015162001cfe608084018263ffffffff169052565b5060a081015162001d1560a084018261ffff169052565b5060c081015162001d2c60c084018261ffff169052565b5060e081015162001d4860e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015182169084015261018080830151909116908301526101a0908101511515910152565b82516001600160a01b031681526020808401516001600160401b0390811691830191909152604080850151821690830152606080850151918216908301526102c082019050608084015162001e0460808401826001600160601b03169052565b5060a084015162001e2060a08401826001600160a01b03169052565b5060c084015162001e3c60c08401826001600160a01b03169052565b5060e084015162001e5860e08401826001600160a01b03169052565b5062000f3961010083018462001c92565b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000919060409081850190868401855b8281101562001f0157815180516001600160a01b031685528681015163ffffffff1687860152858101516001600160401b03908116878701526060808301519091169086015260809081015115159085015260a0909301929085019060010162001e9c565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b8281101562001f0157815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e0909301929085019060010162001f2b565b6020808252825182820181905260009190848201906040850190845b8181101562001fe65783516001600160a01b03168352928401929184019160010162001fbf565b50909695505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000efe5762000efe62001ff2565b60008162002030576200203062001ff2565b506000190190565b63ffffffff81811683821601908082111562001349576200134962001ff2565b6000604080830163ffffffff8616845260206040602086015281865180845260608701915060208801935060005b81811015620020ba57845180516001600160a01b0316845284015161ffff1684840152938301939185019160010162002086565b509098975050505050505050565b808202811582820484141762000efe5762000efe62001ff2565b6000826200210057634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b0382811682821603908082111562001349576200134962001ff2565b6000602082840312156200213b57600080fd5b5051919050565b818103600083128015838313168383128216171562001349576200134962001ff2565b6000602082840312156200217857600080fd5b62000f398262001694565b634e487b7160e01b600052603160045260246000fd5b60005b83811015620021b65781810151838201526020016200219c565b50506000910152565b60008251620021d381846020870162002199565b9190910192915050565b6020815260008251806020840152620021fe81604085016020870162002199565b601f01601f19169190910160400192915050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f94620023406000396000818161036101528181610f1801526137a3015260008181610332015281816117160152613774015260008181610303015281816113cc0152818161143101528181611c8901528181611d17015261374501526000818161026f01528181610a4e0152818161183e0152818161223701528181612acf01526136b101526000818161023f01528181611de80152613681015260008181610210015281816110c30152818161164201528181611a5f01528181611b6001528181612666015281816136520152613a410152600081816102cf01528181611c2c015261371101526000818161029f015281816127c101526136e10152600061243f0152615f946000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80637437ff9f116100f9578063c92b283211610097578063eff7cc4811610071578063eff7cc48146109fc578063f25561fd14610a04578063f2fde38b14610a17578063fbca3b7414610a2a57600080fd5b8063c92b2832146109ce578063d09dc339146109e1578063df0aa9e9146109e957600080fd5b8063856c8247116100d3578063856c8247146108a05780638da5cb5b146108b35780639a113c36146108c4578063b06d41bc146109b857600080fd5b80637437ff9f146106c057806376f6ae761461088557806379ba50971461089857600080fd5b806348a98aa411610166578063549e946f11610140578063549e946f1461066957806354b714681461067c578063599f64311461069c578063704b6c02146106ad57600080fd5b806348a98aa4146105c7578063528d4a92146105f2578063546719cd1461060557600080fd5b806320487ded1161019757806320487ded146105705780634120fccd146105915780634816f4f7146105b257600080fd5b806306285c69146101be5780631772047e146103a7578063181f5a7714610527575b600080fd5b6103916040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091526040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60405161039e9190614ba3565b60405180910390f35b6104bb6103b5366004614bd7565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152506001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c082015290565b60405161039e9190600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b6105636040518060400160405280601781526020017f45564d3245564d4f6e52616d7020312e352e302d64657600000000000000000081525081565b60405161039e9190614c44565b61058361057e366004614c85565b610a4a565b60405190815260200161039e565b610599610ea0565b60405167ffffffffffffffff909116815260200161039e565b6105c56105c0366004614e93565b610ec7565b005b6105da6105d5366004614fd0565b610edd565b6040516001600160a01b03909116815260200161039e565b6105c5610600366004615009565b610f8c565b61060d610fa0565b60405161039e919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6105c5610677366004615119565b611032565b600e546040516bffffffffffffffffffffffff909116815260200161039e565b6002546001600160a01b03166105da565b6105c56106bb366004614bd7565b6111ab565b610878604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915250604080516101c0810182526005546001600160a01b038082168352600160a01b820461ffff9081166020850152760100000000000000000000000000000000000000000000830463ffffffff908116958501959095527a0100000000000000000000000000000000000000000000000000008304811660608501527c0100000000000000000000000000000000000000000000000000000000928390048516608085015260065480821660a086015262010000808204831660c0870152640100000000820490931660e086015278010000000000000000000000000000000000000000000000008104861661010086015292909204841661012084015260075491821661014084015281048316610160830152660100000000000081049092166101808201526a010000000000000000000090910460ff1615156101a082015290565b60405161039e9190615242565b6105c5610893366004615251565b611275565b6105c56112d8565b6105996108ae366004614bd7565b6113a1565b6000546001600160a01b03166105da565b61096e6108d2366004614bd7565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b03166000908152600b60209081526040918290208251608081018452905463ffffffff8116825267ffffffffffffffff64010000000082048116938301939093526c0100000000000000000000000081049092169281019290925260ff600160a01b909104161515606082015290565b60408051825163ffffffff16815260208084015167ffffffffffffffff9081169183019190915283830151169181019190915260609182015115159181019190915260800161039e565b6109c061149c565b60405161039e92919061531a565b6105c56109dc36600461535c565b611597565b6105836115ff565b6105836109f73660046153ca565b6116bf565b6105c56124b3565b6105c5610a12366004615436565b612738565b6105c5610a25366004614bd7565b612749565b610a3d610a38366004615535565b61275a565b60405161039e9190615552565b60007f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168367ffffffffffffffff1614610aca576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6000610ae1610adc608085018561559f565b61278e565b9050610b11610af3602085018561559f565b8351909150610b056040870187615604565b9050846020015161291b565b6000600b81610b266080870160608801614bd7565b6001600160a01b0316815260208082019290925260409081016000208151608081018352905463ffffffff81168252640100000000810467ffffffffffffffff908116948301949094526c01000000000000000000000000810490931691810191909152600160a01b90910460ff16151560608201819052909150610bf357610bb56080850160608601614bd7565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610ac1565b600654600090819064010000000090046001600160a01b031663ffdb4b37610c216080890160608a01614bd7565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff8a1660248201526044016040805180830381865afa158015610c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb09190615698565b90925090506000808080610cc760408b018b615604565b90501115610d0157610cf5610ce260808b0160608c01614bd7565b86610cf060408d018d615604565b612a84565b91945092509050610d1d565b8551610d1a9063ffffffff16662386f26fc100006156e1565b92505b60065460009062010000900461ffff1615610d7157610d6e6dffffffffffffffffffffffffffff607087901c16610d5760208d018d61559f565b9050610d6660408e018e615604565b905085612e66565b90505b60208781015160055460009267ffffffffffffffff9092169163ffffffff8716917a010000000000000000000000000000000000000000000000000000900461ffff1690610dc1908f018f61559f565b610dcc9291506156e1565b6005548c51610dfb91760100000000000000000000000000000000000000000000900463ffffffff16906156f8565b610e0591906156f8565b610e0f91906156f8565b610e29906dffffffffffffffffffffffffffff89166156e1565b610e3391906156e1565b9050867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1682828a6040015167ffffffffffffffff1688610e7091906156e1565b610e7a91906156f8565b610e8491906156f8565b610e8e919061570b565b99505050505050505050505b92915050565b600e54600090610ec290600160801b900467ffffffffffffffff16600161572d565b905090565b610ecf612f36565b610ed98282612f8e565b5050565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610f61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f85919061574e565b9392505050565b610f9461330a565b610f9d81613364565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff8082168352600160801b80830463ffffffff166020850152600160a01b90920460ff161515938301939093526004548084166060840152049091166080820152610ec2906137dd565b61103a612f36565b6001600160a01b03811661107a576040517f232cb97f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006110846115ff565b905060008112156110c1576040517f02075e0000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316036111135761110e6001600160a01b038416838361388f565b505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015261110e9083906001600160a01b038616906370a0823190602401602060405180830381865afa158015611176573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119a919061576b565b6001600160a01b038616919061388f565b6000546001600160a01b031633148015906111d157506002546001600160a01b03163314155b15611208576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b61127d612f36565b610ed98282808060200260200160405190810160405280939291908181526020016000905b828210156112ce576112bf60408302860136819003810190615784565b815260200190600101906112a2565b505050505061390f565b6001546001600160a01b031633146113325760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610ac1565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b038082166000908152600d6020526040812054909167ffffffffffffffff909116907f00000000000000000000000000000000000000000000000000000000000000001615610e9a5780600003610e9a576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611478573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8591906157c3565b60606000806114ab6008613b75565b90508067ffffffffffffffff8111156114c6576114c6614cd5565b60405190808252806020026020018201604052801561150b57816020015b60408051808201909152600080825260208201528152602001906001900390816114e45790505b50925060005b8181101561157457600080611527600884613b80565b915091506040518060400160405280836001600160a01b031681526020018261ffff1681525086848151811061155f5761155f6157e0565b60209081029190910101525050600101611511565b5050600e5491926c0100000000000000000000000090920463ffffffff16919050565b6000546001600160a01b031633148015906115bd57506002546001600160a01b03163314155b156115f4576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f9d600382613b9e565b600e546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916bffffffffffffffffffffffff16907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611691573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b5919061576b565b610ec291906157f6565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608086901b1660048201526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561175d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117819190615816565b156117b8576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0382166117f8576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b0316331461183c576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168567ffffffffffffffff16146118b5576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610ac1565b60006118c7610adc608087018761559f565b905060006118d86040870187615604565b91506118fe90506118ec602088018861559f565b9050836000015183856020015161291b565b8015611a55576000805b82811015611a435761191d6040890189615604565b8281811061192d5761192d6157e0565b90506040020160200135600003611970576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c600061198160408b018b615604565b84818110611991576119916157e0565b6119a79260206040909202019081019150614bd7565b6001600160a01b031681526020810191909152604001600020547201000000000000000000000000000000000000900460ff1615611a3b57611a2e6119ef60408a018a615604565b838181106119ff576119ff6157e0565b905060400201803603810190611a159190615833565b60065464010000000090046001600160a01b0316613d31565b611a3890836156f8565b91505b600101611908565b508015611a5357611a5381613e52565b505b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016611a8f6080880160608901614bd7565b6001600160a01b031603611af357600e8054869190600090611ac09084906bffffffffffffffffffffffff1661586d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550611c1a565b60065464010000000090046001600160a01b03166241e5be611b1b6080890160608a01614bd7565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018990527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa158015611ba7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bcb919061576b565b600e8054600090611beb9084906bffffffffffffffffffffffff1661586d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b600e546bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811691161115611c87576040517fe5c7a49100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615611dd2576001600160a01b0384166000908152600d602052604081205467ffffffffffffffff169003611dd2576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d8291906157c3565b6001600160a01b0385166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790555b604080516101a08101825267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526001600160a01b03861660208201526000918101611e65611e2b8a8061559f565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613e5f92505050565b6001600160a01b03168152602001600e601081819054906101000a900467ffffffffffffffff16611e9590615892565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff168152602001846000015181526020016000151581526020018460200151611f3f576001600160a01b0387166000908152600d602052604081208054909190611f159067ffffffffffffffff16615892565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055611f42565b60005b67ffffffffffffffff168152602001611f6160808a0160608b01614bd7565b6001600160a01b03168152602001878152602001888060200190611f85919061559f565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001611fcc60408a018a615604565b808060200260200160405190810160405280939291908181526020016000905b828210156120185761200960408302860136819003810190615833565b81526020019060010190611fec565b505050505081526020018367ffffffffffffffff81111561203b5761203b614cd5565b60405190808252806020026020018201604052801561206e57816020015b60608152602001906001900390816120595790505b508152600060209091018190529091505b8281101561243857600061209660408a018a615604565b838181106120a6576120a66157e0565b9050604002018036038101906120bc9190615833565b905060006120ce8b8360000151610edd565b90506001600160a01b038116158061218457506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa15801561215e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121829190615816565b155b156121c95781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610ac1565b6000816001600160a01b0316639a4575b96040518060a001604052808e80600001906121f5919061559f565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525067ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166020808301919091526001600160a01b03808f16604080850191909152918901516060840152885116608090920191909152517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526122c091906004016158b9565b6000604051808303816000875af11580156122df573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526123079190810190615986565b9050602081602001515111156123985782516001600160a01b03166000908152600c602090815260409091205490820151516e01000000000000000000000000000090910463ffffffff1610156123985782516040517f36f536ca0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610ac1565b80516123a390613e5f565b5060408051606081019091526001600160a01b03831660808201528060a0810160405160208183030381529060405281526020018260000151815260200182602001518152506040516020016123f99190615a17565b604051602081830303815290604052856101600151858151811061241f5761241f6157e0565b602002602001018190525050505080600101905061207f565b50612463817f0000000000000000000000000000000000000000000000000000000000000000613f05565b6101808201526040517fd0c3c799bf9e2639de44391e7f524d229b2b55f5b1ea94b2bf7da42f7243dddd90612499908390615b0e565b60405180910390a16101800151925050505b949350505050565b6000546001600160a01b03163314612518576002546001600160a01b03163314612518576124e2600833614060565b612518576040517f195db95800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff16600081900361256c576040517f990e30bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546bffffffffffffffffffffffff16818110156125b7576040517f8d0f71d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006125c16115ff565b12156125f9576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060006126066008613b75565b905060005b818110156126f557600080612621600884613b80565b9092509050600087612641836bffffffffffffffffffffffff8a166156e1565b61264b919061570b565b90506126578187615c43565b955061269b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846bffffffffffffffffffffffff841661388f565b6040516bffffffffffffffffffffffff821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a250505080600101905061260b565b5050600e80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff929092169190911790555050565b612740612f36565b610f9d81614075565b61275161330a565b610f9d816141e7565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091526000808252602082015260008290036127ef57506040805180820190915267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260006020820152610e9a565b60006127fb8385615c68565b90507fe7e230f0000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601612868576128538360048187615cb0565b8101906128609190615cda565b915050610e9a565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016128e95760408051808201909152806128c98560048189615cb0565b8101906128d69190615d06565b815260006020909101529150610e9a9050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006547801000000000000000000000000000000000000000000000000900463ffffffff1680851115612984576040517f869337890000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610ac1565b6006547c0100000000000000000000000000000000000000000000000000000000900463ffffffff168411156129e6576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554600160a01b900461ffff16831115612a2d576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81612a7d576007546a0100000000000000000000900460ff1615612a7d576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000808083815b81811015612e5a576000878783818110612aa757612aa76157e0565b905060400201803603810190612abd9190615833565b905060006001600160a01b0316612af87f00000000000000000000000000000000000000000000000000000000000000008360000151610edd565b6001600160a01b031603612b465780516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610ac1565b80516001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c08201819052612c7e57600754612c2f9061ffff16662386f26fc100006156e1565b612c3990886156f8565b600754909750612c559062010000900463ffffffff1687615d1f565b600754909650612c75906601000000000000900463ffffffff1686615d1f565b94505050612e52565b604081015160009061ffff1615612da25760008c6001600160a01b031684600001516001600160a01b031614612d455760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526401000000009092041690634ab35b0b90602401602060405180830381865afa158015612d1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d3e9190615d3c565b9050612d48565b508a5b620186a0836040015161ffff16612d8a8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166142a890919063ffffffff16565b612d9491906156e1565b612d9e919061570b565b9150505b6060820151612db19088615d1f565b9650816080015186612dc39190615d1f565b8251909650600090612de29063ffffffff16662386f26fc100006156e1565b905080821015612e0157612df6818a6156f8565b985050505050612e52565b6000836020015163ffffffff16662386f26fc10000612e2091906156e1565b905080831115612e4057612e34818b6156f8565b99505050505050612e52565b612e4a838b6156f8565b995050505050505b600101612a8b565b50509450945094915050565b60008063ffffffff8316612e7b6080866156e1565b612e87876102206156f8565b612e9191906156f8565b612e9b91906156f8565b6005546006549192506000917c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690612edd9061ffff16846156e1565b612ee791906156f8565b60065490915062010000900461ffff16612f116dffffffffffffffffffffffffffff8916836156e1565b612f1b91906156e1565b612f2b90655af3107a40006156e1565b979650505050505050565b6000546001600160a01b03163314612f8c576002546001600160a01b03163314612f8c576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60005b825181101561321c576000838281518110612fae57612fae6157e0565b6020026020010151905060208160a0015163ffffffff16101561301b57805160a08201516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526001600160a01b03909216600483015263ffffffff166024820152604401610ac1565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009096169590951764010000000092871692909202919091177fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff166801000000000000000093909216929092027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff16176a010000000000000000000091841691909102177fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff166e01000000000000000000000000000093909216929092027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1617720100000000000000000000000000000000000094151594909402939093177fffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff16730100000000000000000000000000000000000000931515939093029290921790915501612f91565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d08260405161324c9190615d57565b60405180910390a160005b81518110156132c757600c6000838381518110613276576132766157e0565b6020908102919091018101516001600160a01b0316825281019190915260400160002080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055600101613257565b50805115610ed9577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b816040516132fe9190615552565b60405180910390a15050565b6000546001600160a01b03163314612f8c5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610ac1565b60e08101516001600160a01b03166133a8576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081610180015163ffffffff161015613404576101808101516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526000600482015263ffffffff9091166024820152604401610ac1565b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548163ffffffff021916908363ffffffff1602179055506101a082015181600201600a6101000a81548160ff0219169083151502179055509050507fe375c8cb6ea9807cd0371503b632b93da5ee0f1f64205db8b5b28b95d6b588b06040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152508260405161126a929190615df7565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261386b82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261384f9190615e14565b85608001516fffffffffffffffffffffffffffffffff166142e5565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261110e90849061430d565b8051604081111561394c576040517fb5a10cfa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff16156139a057600e5463ffffffff6c010000000000000000000000008204166bffffffffffffffffffffffff909116106139a0576139a06124b3565b60006139ac6008613b75565b90505b80156139ee5760006139cd6139c5600184615e14565b600890613b80565b5090506139db6008826143f2565b5050806139e790615e27565b90506139af565b506000805b82811015613af6576000848281518110613a0f57613a0f6157e0565b60200260200101516000015190506000858381518110613a3157613a316157e0565b60200260200101516020015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480613a8657506001600160a01b038216155b15613ac8576040517f4de938d10000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610ac1565b613ad860088361ffff8416614407565b50613ae761ffff821685615d1f565b935050508060010190506139f3565b50600e80547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd2490613b689083908690615e5c565b60405180910390a1505050565b6000610e9a8261441d565b6000808080613b8f8686614428565b909450925050505b9250929050565b8154600090613bba90600160801b900463ffffffff1642615e14565b90508015613c425760018301548354613bf5916fffffffffffffffffffffffffffffffff808216928116918591600160801b909104166142e5565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617600160801b4263ffffffff16021783555b60208201518354613c68916fffffffffffffffffffffffffffffffff9081169116614453565b835483511515600160a01b027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff9283161717845560208301516040808501518316600160801b0291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990613b689084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613d97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dbb9190615e7b565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613e245783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610ac1565b60208401516124ab907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316906142a8565b610f9d6003826000614469565b60008151602014613e9e57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610ac19190614c44565b600082806020019051810190613eb4919061576b565b90506001600160a01b03811180613ecc575061040081105b15610e9a57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610ac19190614c44565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001613f9b9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001613fd49190615eae565b604051602081830303815290604052805190602001208761016001516040516020016140009190615ec1565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b6000610f85836001600160a01b038416614773565b60005b81518110156141b7576000828281518110614095576140956157e0565b60209081029190910181015160408051608080820183528385015163ffffffff90811683528385015167ffffffffffffffff908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9688166c0100000000000000000000000002969096167fffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090951691161792909217919091169290921717905550600101614078565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e8160405161126a9190615ed4565b336001600160a01b0382160361423f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610ac1565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a76400006142db837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166156e1565b610f85919061570b565b6000614304856142f584866156e1565b6142ff90876156f8565b614453565b95945050505050565b6000614362826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661477f9092919063ffffffff16565b80519091501561110e57808060200190518101906143809190615816565b61110e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ac1565b6000610f85836001600160a01b03841661478e565b60006124ab846001600160a01b038516846147ab565b6000610e9a826147c8565b6000808061443685856147d2565b600081815260029690960160205260409095205494959350505050565b60008183106144625781610f85565b5090919050565b8254600160a01b900460ff16158061447f575081155b1561448957505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906144c290600160801b900463ffffffff1642615e14565b905080156145685781831115614504576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461453190839085908490600160801b90046fffffffffffffffffffffffffffffffff166142e5565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff16600160801b4263ffffffff160217875592505b84821015614605576001600160a01b0384166145ba576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610ac1565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610ac1565b848310156146f157600186810154600160801b90046fffffffffffffffffffffffffffffffff1690600090829061463c9082615e14565b614646878a615e14565b61465091906156f8565b61465a919061570b565b90506001600160a01b0386166146a6576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610ac1565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610ac1565b6146fb8584615e14565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f8583836147de565b60606124ab84846000856147f6565b60008181526002830160205260408120819055610f8583836148dd565b600082815260028401602052604081208290556124ab84846148e9565b6000610e9a825490565b6000610f8583836148f5565b60008181526001830160205260408120541515610f85565b60608247101561486e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ac1565b600080866001600160a01b0316858760405161488a9190615f55565b60006040518083038185875af1925050503d80600081146148c7576040519150601f19603f3d011682016040523d82523d6000602084013e6148cc565b606091505b5091509150612f2b8783838761491f565b6000610f858383614998565b6000610f858383614a92565b600082600001828154811061490c5761490c6157e0565b9060005260206000200154905092915050565b6060831561498e578251600003614987576001600160a01b0385163b6149875760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ac1565b50816124ab565b6124ab8383614ae1565b60008181526001830160205260408120548015614a815760006149bc600183615e14565b85549091506000906149d090600190615e14565b9050818114614a355760008660000182815481106149f0576149f06157e0565b9060005260206000200154905080876000018481548110614a1357614a136157e0565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614a4657614a46615f71565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610e9a565b6000915050610e9a565b5092915050565b6000818152600183016020526040812054614ad957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e9a565b506000610e9a565b815115614af15781518083602001fd5b8060405162461bcd60e51b8152600401610ac19190614c44565b6001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401525060c0810151614b8860c08401826001600160a01b03169052565b5060e081015161110e60e08401826001600160a01b03169052565b6101008101610e9a8284614b0b565b6001600160a01b0381168114610f9d57600080fd5b8035614bd281614bb2565b919050565b600060208284031215614be957600080fd5b8135610f8581614bb2565b60005b83811015614c0f578181015183820152602001614bf7565b50506000910152565b60008151808452614c30816020860160208601614bf4565b601f01601f19169290920160200192915050565b602081526000610f856020830184614c18565b67ffffffffffffffff81168114610f9d57600080fd5b600060a08284031215614c7f57600080fd5b50919050565b60008060408385031215614c9857600080fd5b8235614ca381614c57565b9150602083013567ffffffffffffffff811115614cbf57600080fd5b614ccb85828601614c6d565b9150509250929050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614d0e57614d0e614cd5565b60405290565b6040516101c0810167ffffffffffffffff81118282101715614d0e57614d0e614cd5565b60405160a0810167ffffffffffffffff81118282101715614d0e57614d0e614cd5565b6040805190810167ffffffffffffffff81118282101715614d0e57614d0e614cd5565b604051601f8201601f1916810167ffffffffffffffff81118282101715614da757614da7614cd5565b604052919050565b600067ffffffffffffffff821115614dc957614dc9614cd5565b5060051b60200190565b63ffffffff81168114610f9d57600080fd5b8035614bd281614dd3565b803561ffff81168114614bd257600080fd5b8015158114610f9d57600080fd5b8035614bd281614e02565b600082601f830112614e2c57600080fd5b81356020614e41614e3c83614daf565b614d7e565b8083825260208201915060208460051b870101935086841115614e6357600080fd5b602086015b84811015614e88578035614e7b81614bb2565b8352918301918301614e68565b509695505050505050565b6000806040808486031215614ea757600080fd5b833567ffffffffffffffff80821115614ebf57600080fd5b818601915086601f830112614ed357600080fd5b81356020614ee3614e3c83614daf565b82815260e0928302850182019282820191908b851115614f0257600080fd5b958301955b84871015614fab5780878d031215614f1f5760008081fd5b614f27614ceb565b8735614f3281614bb2565b815287850135614f4181614dd3565b8186015287890135614f5281614dd3565b818a01526060614f63898201614df0565b90820152608088810135614f7681614dd3565b9082015260a0614f87898201614de5565b9082015260c0614f98898201614e10565b9082015283529586019591830191614f07565b5097505087013593505080831115614fc257600080fd5b5050614ccb85828601614e1b565b60008060408385031215614fe357600080fd5b8235614fee81614c57565b91506020830135614ffe81614bb2565b809150509250929050565b60006101c0828403121561501c57600080fd5b615024614d14565b61502d83614bc7565b815261503b60208401614df0565b602082015261504c60408401614de5565b604082015261505d60608401614df0565b606082015261506e60808401614de5565b608082015261507f60a08401614df0565b60a082015261509060c08401614df0565b60c08201526150a160e08401614bc7565b60e08201526101006150b4818501614de5565b908201526101206150c6848201614de5565b908201526101406150d8848201614df0565b908201526101606150ea848201614de5565b908201526101806150fc848201614de5565b908201526101a061510e848201614e10565b908201529392505050565b6000806040838503121561512c57600080fd5b8235614fee81614bb2565b80516001600160a01b031682526020810151615159602084018261ffff169052565b506040810151615171604084018263ffffffff169052565b506060810151615187606084018261ffff169052565b50608081015161519f608084018263ffffffff169052565b5060a08101516151b560a084018261ffff169052565b5060c08101516151cb60c084018261ffff169052565b5060e08101516151e660e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015182169084015261018080830151909116908301526101a0908101511515910152565b6101c08101610e9a8284615137565b6000806020838503121561526457600080fd5b823567ffffffffffffffff8082111561527c57600080fd5b818501915085601f83011261529057600080fd5b81358181111561529f57600080fd5b8660208260061b85010111156152b457600080fd5b60209290920196919550909350505050565b60008151808452602080850194506020840160005b8381101561530f57815180516001600160a01b0316885283015161ffff1683880152604090960195908201906001016152db565b509495945050505050565b60408152600061532d60408301856152c6565b90508260208301529392505050565b80356fffffffffffffffffffffffffffffffff81168114614bd257600080fd5b60006060828403121561536e57600080fd5b6040516060810181811067ffffffffffffffff8211171561539157615391614cd5565b604052823561539f81614e02565b81526153ad6020840161533c565b60208201526153be6040840161533c565b60408201529392505050565b600080600080608085870312156153e057600080fd5b84356153eb81614c57565b9350602085013567ffffffffffffffff81111561540757600080fd5b61541387828801614c6d565b93505060408501359150606085013561542b81614bb2565b939692955090935050565b6000602080838503121561544957600080fd5b823567ffffffffffffffff81111561546057600080fd5b8301601f8101851361547157600080fd5b803561547f614e3c82614daf565b81815260a0918202830184019184820191908884111561549e57600080fd5b938501935b838510156155295780858a0312156154bb5760008081fd5b6154c3614d38565b85356154ce81614bb2565b8152858701356154dd81614dd3565b818801526040868101356154f081614c57565b9082015260608681013561550381614c57565b9082015260808681013561551681614e02565b90820152835293840193918501916154a3565b50979650505050505050565b60006020828403121561554757600080fd5b8135610f8581614c57565b6020808252825182820181905260009190848201906040850190845b818110156155935783516001600160a01b03168352928401929184019160010161556e565b50909695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155d457600080fd5b83018035915067ffffffffffffffff8211156155ef57600080fd5b602001915036819003821315613b9757600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261563957600080fd5b83018035915067ffffffffffffffff82111561565457600080fd5b6020019150600681901b3603821315613b9757600080fd5b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114614bd257600080fd5b600080604083850312156156ab57600080fd5b6156b48361566c565b91506156c26020840161566c565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e9a57610e9a6156cb565b80820180821115610e9a57610e9a6156cb565b60008261572857634e487b7160e01b600052601260045260246000fd5b500490565b67ffffffffffffffff818116838216019080821115614a8b57614a8b6156cb565b60006020828403121561576057600080fd5b8151610f8581614bb2565b60006020828403121561577d57600080fd5b5051919050565b60006040828403121561579657600080fd5b61579e614d5b565b82356157a981614bb2565b81526157b760208401614df0565b60208201529392505050565b6000602082840312156157d557600080fd5b8151610f8581614c57565b634e487b7160e01b600052603260045260246000fd5b8181036000831280158383131683831282161715614a8b57614a8b6156cb565b60006020828403121561582857600080fd5b8151610f8581614e02565b60006040828403121561584557600080fd5b61584d614d5b565b823561585881614bb2565b81526020928301359281019290925250919050565b6bffffffffffffffffffffffff818116838216019080821115614a8b57614a8b6156cb565b600067ffffffffffffffff8083168181036158af576158af6156cb565b6001019392505050565b602081526000825160a060208401526158d560c0840182614c18565b905067ffffffffffffffff602085015116604084015260408401516001600160a01b038082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600082601f83011261593357600080fd5b815167ffffffffffffffff81111561594d5761594d614cd5565b6159606020601f19601f84011601614d7e565b81815284602083860101111561597557600080fd5b6124ab826020830160208701614bf4565b60006020828403121561599857600080fd5b815167ffffffffffffffff808211156159b057600080fd5b90830190604082860312156159c457600080fd5b6159cc614d5b565b8251828111156159db57600080fd5b6159e787828601615922565b8252506020830151828111156159fc57600080fd5b615a0887828601615922565b60208301525095945050505050565b602081526000825160606020840152615a336080840182614c18565b90506020840151601f1980858403016040860152615a518383614c18565b92506040860151915080858403016060860152506143048282614c18565b60008151808452602080850194506020840160005b8381101561530f57815180516001600160a01b031688528301518388015260409096019590820190600101615a84565b60008282518085526020808601955060208260051b8401016020860160005b84811015615b0157601f19868403018952615aef838351614c18565b98840198925090830190600101615ad3565b5090979650505050505050565b60208152615b2960208201835167ffffffffffffffff169052565b60006020830151615b4560408401826001600160a01b03169052565b5060408301516001600160a01b038116606084015250606083015167ffffffffffffffff8116608084015250608083015160a083015260a0830151615b8e60c084018215159052565b5060c083015167ffffffffffffffff811660e08401525060e0830151610100615bc1818501836001600160a01b03169052565b840151610120848101919091528401516101a061014080860182905291925090615bef6101c0860184614c18565b9250808601519050601f19610160818786030181880152615c108584615a6f565b945080880151925050610180818786030181880152615c2f8584615ab4565b970151959092019490945250929392505050565b6bffffffffffffffffffffffff828116828216039080821115614a8b57614a8b6156cb565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015615ca85780818660040360031b1b83161692505b505092915050565b60008085851115615cc057600080fd5b83861115615ccd57600080fd5b5050820193919092039150565b600060408284031215615cec57600080fd5b615cf4614d5b565b8235815260208301356157b781614e02565b600060208284031215615d1857600080fd5b5035919050565b63ffffffff818116838216019080821115614a8b57614a8b6156cb565b600060208284031215615d4e57600080fd5b610f858261566c565b602080825282518282018190526000919060409081850190868401855b82811015615dea57815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e09093019290850190600101615d74565b5091979650505050505050565b6102c08101615e068285614b0b565b610f85610100830184615137565b81810381811115610e9a57610e9a6156cb565b600081615e3657615e366156cb565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b63ffffffff831681526040602082015260006124ab60408301846152c6565b600060408284031215615e8d57600080fd5b615e95614d5b565b615e9e8361566c565b815260208301516157b781614dd3565b602081526000610f856020830184615a6f565b602081526000610f856020830184615ab4565b602080825282518282018190526000919060409081850190868401855b82811015615dea57815180516001600160a01b031685528681015163ffffffff16878601528581015167ffffffffffffffff908116878701526060808301519091169086015260809081015115159085015260a09093019290850190600101615ef1565b60008251615f67818460208701614bf4565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidChainSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"}],\"name\":\"InvalidNopAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWithdrawParams\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkBalanceNotSettled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeeBalanceReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoFeesToPay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoNopsToPay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdminOrNop\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyNops\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeConfig\",\"type\":\"tuple[]\"}],\"name\":\"FeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NopPaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nopWeightsTotal\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"NopsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"transferFeeConfig\",\"type\":\"tuple[]\"}],\"name\":\"TokenTransferFeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getFeeTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfig\",\"name\":\"feeTokenConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNopFeesJuels\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNops\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"weightsTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setFeeTokenConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"address[]\"}],\"name\":\"setTokenTransferFeeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawNonLinkFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101a06040523480156200001257600080fd5b506040516200822d3803806200822d833981016040819052620000359162001a93565b8333806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c0816200030b565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555085516001600160a01b0316158062000169575060208601516001600160401b0316155b8062000180575060408601516001600160401b0316155b8062000197575060608601516001600160401b0316155b80620001ae575060c08601516001600160a01b0316155b80620001c5575060e08601516001600160a01b0316155b15620001e4576040516306b7c75960e31b815260040160405180910390fd5b60208087015160408089015181517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3948101949094526001600160401b039283169184019190915216606082015230608082015260a00160408051601f198184030181529181528151602092830120608090815288516001600160a01b0390811660e0908152938a01516001600160401b0390811661010052928a015183166101205260608a015190921660a0908152908901516001600160601b031660c090815290890151821661014052880151811661016052908701511661018052620002cd85620003b6565b620002d883620006ad565b604080516000815260208101909152620002f4908390620007dd565b620002ff8162000a83565b5050505050506200218a565b336001600160a01b03821603620003655760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e08101516001600160a01b0316620003e2576040516306b7c75960e31b815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548160ff0219169083151502179055509050507f45b5ad483aa608464c2c7f278bd413d284d7790cdc836e40652e23a02770822060405180610100016040528060e0516001600160a01b03168152602001610100516001600160401b03168152602001610120516001600160401b0316815260200160a0516001600160401b0316815260200160c0516001600160601b03168152602001610140516001600160a01b03168152602001610160516001600160a01b03168152602001610180516001600160a01b031681525082604051620006a292919062001d1c565b60405180910390a150565b60005b8151811015620007ab576000828281518110620006d157620006d162001de1565b60209081029190910181015160408051608080820183528385015163ffffffff9081168352838501516001600160401b03908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b0260ff60a01b199688166c010000000000000000000000000296909616600160601b600160a81b031993909716640100000000026001600160601b031990951691161792909217919091169290921717905550600101620006b0565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e81604051620006a2919062001df7565b60005b8251811015620009a257600083828151811062000801576200080162001de1565b60200260200101519050602063ffffffff168160a0015163ffffffff1610156200085d57805160a08201516040516312766e0160e11b81526001600160a01b03909216600483015263ffffffff16602482015260440162000084565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087166001600160401b031990961695909517640100000000928716929092029190911765ffffffffffff60401b191668010000000000000000939092169290920263ffffffff60501b1916176a0100000000000000000000918416919091021764ffffffffff60701b1916600160701b939092169290920260ff60901b191617600160901b941515949094029390931760ff60981b1916600160981b931515939093029290921790915501620007e0565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d082604051620009d4919062001e86565b60405180910390a160005b815181101562000a3c57600c600083838151811062000a025762000a0262001de1565b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055600101620009df565b5080511562000a7f577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b8160405162000a76919062001f1b565b60405180910390a15b5050565b8051604081111562000aa857604051635ad0867d60e11b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff161562000afb57600e5463ffffffff6c010000000000000000000000008204166001600160601b039091161062000afb5762000afb62000c9e565b600062000b09600862000e8a565b90505b801562000b5557600062000b2f62000b2660018462001f80565b60089062000e9d565b50905062000b3f60088262000ebb565b50508062000b4d9062001f96565b905062000b0c565b506000805b8281101562000c3557600084828151811062000b7a5762000b7a62001de1565b6020026020010151600001519050600085838151811062000b9f5762000b9f62001de1565b602002602001015160200151905060e0516001600160a01b0316826001600160a01b0316148062000bd757506001600160a01b038216155b1562000c0257604051634de938d160e01b81526001600160a01b038316600482015260240162000084565b62000c1460088361ffff841662000ed9565b5062000c2561ffff82168562001fb0565b9350505080600101905062000b5a565b50600e805463ffffffff60601b19166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249062000c91908390869062001fd0565b60405180910390a1505050565b6000546001600160a01b0316331462000cef576002546001600160a01b0316331462000cef5762000cd160083362000ef9565b62000cef5760405163032bb72b60e31b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff16600081900362000d2b5760405163990e30bf60e01b815260040160405180910390fd5b600e546001600160601b03168181101562000d59576040516311a1ee3b60e31b815260040160405180910390fd5b600062000d6562000f10565b121562000d8557604051631e9acf1760e31b815260040160405180910390fd5b80600062000d94600862000e8a565b905060005b8181101562000e645760008062000db260088462000e9d565b909250905060008762000dcf836001600160601b038a1662002040565b62000ddb91906200205a565b905062000de981876200207d565b60e05190965062000e0e906001600160a01b0316846001600160601b03841662000f9e565b6040516001600160601b03821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a250505080600101905062000d99565b5050600e80546001600160601b0319166001600160601b03929092169190911790555050565b600062000e978262000ffb565b92915050565b600080808062000eae868662001008565b9097909650945050505050565b600062000ed2836001600160a01b03841662001035565b9392505050565b600062000ef1846001600160a01b0385168462001054565b949350505050565b600062000ed2836001600160a01b03841662001073565b600e5460e0516040516370a0823160e01b81523060048201526000926001600160601b0316916001600160a01b0316906370a0823190602401602060405180830381865afa15801562000f67573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f8d9190620020a0565b62000f999190620020ba565b905090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915262000ff69185916200108116565b505050565b600062000e978262001152565b600080806200101885856200115d565b600081815260029690960160205260409095205494959350505050565b6000818152600283016020526040812081905562000ed283836200116b565b6000828152600284016020526040812082905562000ef1848462001179565b600062000ed2838362001187565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620010d0906001600160a01b038516908490620011a0565b80519091501562000ff65780806020019051810190620010f19190620020dd565b62000ff65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000084565b600062000e97825490565b600062000ed28383620011b1565b600062000ed28383620011de565b600062000ed28383620012e9565b6000818152600183016020526040812054151562000ed2565b606062000ef184846000856200133b565b6000826000018281548110620011cb57620011cb62001de1565b9060005260206000200154905092915050565b60008181526001830160205260408120548015620012d75760006200120560018362001f80565b85549091506000906200121b9060019062001f80565b9050818114620012875760008660000182815481106200123f576200123f62001de1565b906000526020600020015490508087600001848154811062001265576200126562001de1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200129b576200129b620020fb565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e97565b600091505062000e97565b5092915050565b6000818152600183016020526040812054620013325750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e97565b50600062000e97565b6060824710156200139e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000084565b600080866001600160a01b03168587604051620013bc919062002137565b60006040518083038185875af1925050503d8060008114620013fb576040519150601f19603f3d011682016040523d82523d6000602084013e62001400565b606091505b50909250905062001414878383876200141f565b979650505050505050565b60608315620014935782516000036200148b576001600160a01b0385163b6200148b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000084565b508162000ef1565b62000ef18383815115620014aa5781518083602001fd5b8060405162461bcd60e51b815260040162000084919062002155565b634e487b7160e01b600052604160045260246000fd5b6040516101a081016001600160401b0381118282101715620015025762001502620014c6565b60405290565b60405160a081016001600160401b0381118282101715620015025762001502620014c6565b60405160e081016001600160401b0381118282101715620015025762001502620014c6565b604080519081016001600160401b0381118282101715620015025762001502620014c6565b60405161010081016001600160401b0381118282101715620015025762001502620014c6565b604051601f8201601f191681016001600160401b0381118282101715620015c857620015c8620014c6565b604052919050565b80516001600160a01b0381168114620015e857600080fd5b919050565b80516001600160401b0381168114620015e857600080fd5b805161ffff81168114620015e857600080fd5b805163ffffffff81168114620015e857600080fd5b80518015158114620015e857600080fd5b60006101a082840312156200165257600080fd5b6200165c620014dc565b90506200166982620015d0565b8152620016796020830162001605565b60208201526200168c6040830162001618565b60408201526200169f6060830162001605565b6060820152620016b26080830162001618565b6080820152620016c560a0830162001605565b60a0820152620016d860c0830162001605565b60c0820152620016eb60e08301620015d0565b60e08201526101006200170081840162001618565b908201526101206200171483820162001618565b908201526101406200172883820162001605565b908201526101606200173c83820162001618565b90820152610180620017508382016200162d565b9082015292915050565b80516001600160801b0381168114620015e857600080fd5b6000606082840312156200178557600080fd5b604051606081016001600160401b0381118282101715620017aa57620017aa620014c6565b604052905080620017bb836200162d565b8152620017cb602084016200175a565b6020820152620017de604084016200175a565b60408201525092915050565b60006001600160401b03821115620018065762001806620014c6565b5060051b60200190565b600082601f8301126200182257600080fd5b815160206200183b6200183583620017ea565b6200159d565b82815260a092830285018201928282019190878511156200185b57600080fd5b8387015b85811015620018e85781818a031215620018795760008081fd5b6200188362001508565b6200188e82620015d0565b81526200189d86830162001618565b868201526040620018b0818401620015ed565b908201526060620018c3838201620015ed565b908201526080620018d68382016200162d565b9082015284529284019281016200185f565b5090979650505050505050565b600082601f8301126200190757600080fd5b815160206200191a6200183583620017ea565b82815260e092830285018201928282019190878511156200193a57600080fd5b8387015b85811015620018e85781818a031215620019585760008081fd5b620019626200152d565b6200196d82620015d0565b81526200197c86830162001618565b8682015260406200198f81840162001618565b908201526060620019a283820162001605565b908201526080620019b583820162001618565b9082015260a0620019c883820162001618565b9082015260c0620019db8382016200162d565b9082015284529284019281016200193e565b600082601f830112620019ff57600080fd5b8151602062001a126200183583620017ea565b82815260069290921b8401810191818101908684111562001a3257600080fd5b8286015b8481101562001a88576040818903121562001a515760008081fd5b62001a5b62001552565b62001a6682620015d0565b815262001a7585830162001605565b8186015283529183019160400162001a36565b509695505050505050565b60008060008060008086880361036081121562001aaf57600080fd5b6101008082121562001ac057600080fd5b62001aca62001577565b915062001ad789620015d0565b825262001ae760208a01620015ed565b602083015262001afa60408a01620015ed565b604083015262001b0d60608a01620015ed565b606083015260808901516001600160601b038116811462001b2d57600080fd5b608083015262001b4060a08a01620015d0565b60a083015262001b5360c08a01620015d0565b60c083015262001b6660e08a01620015d0565b60e083015281975062001b7c8a828b016200163e565b9650505062001b90886102a0890162001772565b6103008801519094506001600160401b038082111562001baf57600080fd5b62001bbd8a838b0162001810565b945061032089015191508082111562001bd557600080fd5b62001be38a838b01620018f5565b935061034089015191508082111562001bfb57600080fd5b5062001c0a89828a01620019ed565b9150509295509295509295565b80516001600160a01b03168252602081015162001c3a602084018261ffff169052565b50604081015162001c53604084018263ffffffff169052565b50606081015162001c6a606084018261ffff169052565b50608081015162001c83608084018263ffffffff169052565b5060a081015162001c9a60a084018261ffff169052565b5060c081015162001cb160c084018261ffff169052565b5060e081015162001ccd60e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015190911690830152610180908101511515910152565b82516001600160a01b031681526020808401516001600160401b0390811691830191909152604080850151821690830152606080850151918216908301526102a082019050608084015162001d7c60808401826001600160601b03169052565b5060a084015162001d9860a08401826001600160a01b03169052565b5060c084015162001db460c08401826001600160a01b03169052565b5060e084015162001dd060e08401826001600160a01b03169052565b5062000ed261010083018462001c17565b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000919060409081850190868401855b8281101562001e7957815180516001600160a01b031685528681015163ffffffff1687860152858101516001600160401b03908116878701526060808301519091169086015260809081015115159085015260a0909301929085019060010162001e14565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b8281101562001e7957815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e0909301929085019060010162001ea3565b6020808252825182820181905260009190848201906040850190845b8181101562001f5e5783516001600160a01b03168352928401929184019160010162001f37565b50909695505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000e975762000e9762001f6a565b60008162001fa85762001fa862001f6a565b506000190190565b63ffffffff818116838216019080821115620012e257620012e262001f6a565b6000604080830163ffffffff8616845260206040602086015281865180845260608701915060208801935060005b818110156200203257845180516001600160a01b0316845284015161ffff1684840152938301939185019160010162001ffe565b509098975050505050505050565b808202811582820484141762000e975762000e9762001f6a565b6000826200207857634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b03828116828216039080821115620012e257620012e262001f6a565b600060208284031215620020b357600080fd5b5051919050565b8181036000831280158383131683831282161715620012e257620012e262001f6a565b600060208284031215620020f057600080fd5b62000ed2826200162d565b634e487b7160e01b600052603160045260246000fd5b60005b838110156200212e57818101518382015260200162002114565b50506000910152565b600082516200214b81846020870162002111565b9190910192915050565b60208152600082518060208401526200217681604085016020870162002111565b601f01601f19169190910160400192915050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f75620022b86000396000818161036101528181610efa0152613786015260008181610332015281816116f80152613757015260008181610303015281816113ae0152818161141301528181611c7401528181611d02015261372801526000818161026f01528181610a30015281816118200152818161222201528181612b42015261369401526000818161023f01528181611dd30152613664015260008181610210015281816110a50152818161162401528181611a4101528181611b42015281816126dd015281816136350152613a240152600081816102cf01528181611c0e01526136f401526000818161029f0152818161283801526136c4015260006124b60152615f756000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80637437ff9f116100f9578063c92b283211610097578063eff7cc4811610071578063eff7cc48146109de578063f25561fd146109e6578063f2fde38b146109f9578063fbca3b7414610a0c57600080fd5b8063c92b2832146109b0578063d09dc339146109c3578063df0aa9e9146109cb57600080fd5b8063856c8247116100d3578063856c8247146108825780638da5cb5b146108955780639a113c36146108a6578063b06d41bc1461099a57600080fd5b80637437ff9f146106c057806376f6ae761461086757806379ba50971461087a57600080fd5b806348a98aa411610166578063549e946f11610140578063549e946f1461066957806354b714681461067c578063599f64311461069c578063704b6c02146106ad57600080fd5b806348a98aa4146105c7578063504bffe0146105f2578063546719cd1461060557600080fd5b806320487ded1161019757806320487ded146105705780634120fccd146105915780634816f4f7146105b257600080fd5b806306285c69146101be5780631772047e146103a7578063181f5a7714610527575b600080fd5b6103916040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091526040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60405161039e9190614b86565b60405180910390f35b6104bb6103b5366004614bba565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152506001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c082015290565b60405161039e9190600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b6105636040518060400160405280601781526020017f45564d3245564d4f6e52616d7020312e352e302d64657600000000000000000081525081565b60405161039e9190614c27565b61058361057e366004614c68565b610a2c565b60405190815260200161039e565b610599610e82565b60405167ffffffffffffffff909116815260200161039e565b6105c56105c0366004614e76565b610ea9565b005b6105da6105d5366004614fb3565b610ebf565b6040516001600160a01b03909116815260200161039e565b6105c5610600366004614fec565b610f6e565b61060d610f82565b60405161039e919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6105c56106773660046150ea565b611014565b600e546040516bffffffffffffffffffffffff909116815260200161039e565b6002546001600160a01b03166105da565b6105c56106bb366004614bba565b61118d565b61085a604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915250604080516101a0810182526005546001600160a01b038082168352600160a01b820461ffff9081166020850152760100000000000000000000000000000000000000000000830463ffffffff908116958501959095527a0100000000000000000000000000000000000000000000000000008304811660608501527c0100000000000000000000000000000000000000000000000000000000928390048516608085015260065480821660a086015262010000808204831660c0870152640100000000820490931660e08601527801000000000000000000000000000000000000000000000000810486166101008601529290920484166101208401526007549182166101408401528104909216610160820152660100000000000090910460ff16151561018082015290565b60405161039e9190615206565b6105c5610875366004615215565b611257565b6105c56112ba565b610599610890366004614bba565b611383565b6000546001600160a01b03166105da565b6109506108b4366004614bba565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b03166000908152600b60209081526040918290208251608081018452905463ffffffff8116825267ffffffffffffffff64010000000082048116938301939093526c0100000000000000000000000081049092169281019290925260ff600160a01b909104161515606082015290565b60408051825163ffffffff16815260208084015167ffffffffffffffff9081169183019190915283830151169181019190915260609182015115159181019190915260800161039e565b6109a261147e565b60405161039e9291906152de565b6105c56109be366004615320565b611579565b6105836115e1565b6105836109d936600461538e565b6116a1565b6105c561252a565b6105c56109f43660046153fa565b6127af565b6105c5610a07366004614bba565b6127c0565b610a1f610a1a3660046154f9565b6127d1565b60405161039e9190615516565b60007f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168367ffffffffffffffff1614610aac576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6000610ac3610abe6080850185615563565b612805565b9050610af3610ad56020850185615563565b8351909150610ae760408701876155c8565b90508460200151612992565b6000600b81610b086080870160608801614bba565b6001600160a01b0316815260208082019290925260409081016000208151608081018352905463ffffffff81168252640100000000810467ffffffffffffffff908116948301949094526c01000000000000000000000000810490931691810191909152600160a01b90910460ff16151560608201819052909150610bd557610b976080850160608601614bba565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b600654600090819064010000000090046001600160a01b031663ffdb4b37610c036080890160608a01614bba565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff8a1660248201526044016040805180830381865afa158015610c6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c92919061565c565b90925090506000808080610ca960408b018b6155c8565b90501115610ce357610cd7610cc460808b0160608c01614bba565b86610cd260408d018d6155c8565b612af7565b91945092509050610cff565b8551610cfc9063ffffffff16662386f26fc100006156a5565b92505b60065460009062010000900461ffff1615610d5357610d506dffffffffffffffffffffffffffff607087901c16610d3960208d018d615563565b9050610d4860408e018e6155c8565b905085612ec6565b90505b60208781015160055460009267ffffffffffffffff9092169163ffffffff8716917a010000000000000000000000000000000000000000000000000000900461ffff1690610da3908f018f615563565b610dae9291506156a5565b6005548c51610ddd91760100000000000000000000000000000000000000000000900463ffffffff16906156bc565b610de791906156bc565b610df191906156bc565b610e0b906dffffffffffffffffffffffffffff89166156a5565b610e1591906156a5565b9050867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1682828a6040015167ffffffffffffffff1688610e5291906156a5565b610e5c91906156bc565b610e6691906156bc565b610e7091906156cf565b99505050505050505050505b92915050565b600e54600090610ea490600160801b900467ffffffffffffffff1660016156f1565b905090565b610eb1612f97565b610ebb8282612fef565b5050565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190615712565b9392505050565b610f76613371565b610f7f816133cb565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff8082168352600160801b80830463ffffffff166020850152600160a01b90920460ff161515938301939093526004548084166060840152049091166080820152610ea4906137c0565b61101c612f97565b6001600160a01b03811661105c576040517f232cb97f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006110666115e1565b905060008112156110a3576040517f02075e0000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316036110f5576110f06001600160a01b0384168383613872565b505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526110f09083906001600160a01b038616906370a0823190602401602060405180830381865afa158015611158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117c919061572f565b6001600160a01b0386169190613872565b6000546001600160a01b031633148015906111b357506002546001600160a01b03163314155b156111ea576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b61125f612f97565b610ebb8282808060200260200160405190810160405280939291908181526020016000905b828210156112b0576112a160408302860136819003810190615748565b81526020019060010190611284565b50505050506138f2565b6001546001600160a01b031633146113145760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610aa3565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b038082166000908152600d6020526040812054909167ffffffffffffffff909116907f00000000000000000000000000000000000000000000000000000000000000001615610e7c5780600003610e7c576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa15801561145a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190615787565b606060008061148d6008613b58565b90508067ffffffffffffffff8111156114a8576114a8614cb8565b6040519080825280602002602001820160405280156114ed57816020015b60408051808201909152600080825260208201528152602001906001900390816114c65790505b50925060005b8181101561155657600080611509600884613b63565b915091506040518060400160405280836001600160a01b031681526020018261ffff16815250868481518110611541576115416157a4565b602090810291909101015250506001016114f3565b5050600e5491926c0100000000000000000000000090920463ffffffff16919050565b6000546001600160a01b0316331480159061159f57506002546001600160a01b03163314155b156115d6576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f7f600382613b81565b600e546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916bffffffffffffffffffffffff16907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611673573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611697919061572f565b610ea491906157ba565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608086901b1660048201526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561173f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176391906157da565b1561179a576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0382166117da576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b0316331461181e576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168567ffffffffffffffff1614611897576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610aa3565b60006118a9610abe6080870187615563565b905060006118ba60408701876155c8565b91506118e090506118ce6020880188615563565b90508360000151838560200151612992565b8015611a37576000805b82811015611a25576118ff60408901896155c8565b8281811061190f5761190f6157a4565b90506040020160200135600003611952576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c600061196360408b018b6155c8565b84818110611973576119736157a4565b6119899260206040909202019081019150614bba565b6001600160a01b031681526020810191909152604001600020547201000000000000000000000000000000000000900460ff1615611a1d57611a106119d160408a018a6155c8565b838181106119e1576119e16157a4565b9050604002018036038101906119f791906157f7565b60065464010000000090046001600160a01b0316613d14565b611a1a90836156bc565b91505b6001016118ea565b508015611a3557611a3581613e35565b505b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016611a716080880160608901614bba565b6001600160a01b031603611ad557600e8054869190600090611aa29084906bffffffffffffffffffffffff16615831565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550611bfc565b60065464010000000090046001600160a01b03166241e5be611afd6080890160608a01614bba565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018990527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa158015611b89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bad919061572f565b600e8054600090611bcd9084906bffffffffffffffffffffffff16615831565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b600e546bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811691161115611c69576040517fe5c7a49100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160200151611dbd577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615611dbd576001600160a01b0384166000908152600d602052604081205467ffffffffffffffff169003611dbd576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611d49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6d9190615787565b6001600160a01b0385166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790555b604080516101a08101825267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526001600160a01b03861660208201526000918101611e50611e168a80615563565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613e4292505050565b6001600160a01b03168152602001600e601081819054906101000a900467ffffffffffffffff16611e8090615856565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff168152602001846000015181526020016000151581526020018460200151611f2a576001600160a01b0387166000908152600d602052604081208054909190611f009067ffffffffffffffff16615856565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055611f2d565b60005b67ffffffffffffffff168152602001611f4c60808a0160608b01614bba565b6001600160a01b03168152602001878152602001888060200190611f709190615563565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001611fb760408a018a6155c8565b808060200260200160405190810160405280939291908181526020016000905b8282101561200357611ff4604083028601368190038101906157f7565b81526020019060010190611fd7565b505050505081526020018367ffffffffffffffff81111561202657612026614cb8565b60405190808252806020026020018201604052801561205957816020015b60608152602001906001900390816120445790505b508152600060209091018190529091505b828110156124af57600061208160408a018a6155c8565b83818110612091576120916157a4565b9050604002018036038101906120a791906157f7565b905060006120b98b8360000151610ebf565b90506001600160a01b038116158061216f57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa158015612149573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216d91906157da565b155b156121b45781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b6000816001600160a01b0316639a4575b96040518060a001604052808e80600001906121e09190615563565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525067ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166020808301919091526001600160a01b03808f16604080850191909152918901516060840152885116608090920191909152517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526122ab919060040161587d565b6000604051808303816000875af11580156122ca573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526122f2919081019061594a565b9050602063ffffffff1681602001515111156123895782516001600160a01b03166000908152600c602090815260409091205490820151516e01000000000000000000000000000090910463ffffffff1610156123895782516040517f36f536ca0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b805161239490613e42565b5060408051608081019091526001600160a01b03831660a08201528060c0810160408051808303601f190181529181529082528351602080840191909152808501518383015286516001600160a01b03166000908152600c9091522054606090910190730100000000000000000000000000000000000000900460ff166124295760075462010000900463ffffffff16612458565b84516001600160a01b03166000908152600c60205260409020546a0100000000000000000000900463ffffffff165b63ffffffff16905260405161247091906020016159db565b6040516020818303038152906040528561016001518581518110612496576124966157a4565b602002602001018190525050505080600101905061206a565b506124da817f0000000000000000000000000000000000000000000000000000000000000000613ee8565b6101808201526040517fd0c3c799bf9e2639de44391e7f524d229b2b55f5b1ea94b2bf7da42f7243dddd90612510908390615aef565b60405180910390a16101800151925050505b949350505050565b6000546001600160a01b0316331461258f576002546001600160a01b0316331461258f57612559600833614043565b61258f576040517f195db95800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff1660008190036125e3576040517f990e30bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546bffffffffffffffffffffffff168181101561262e576040517f8d0f71d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006126386115e1565b1215612670576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600061267d6008613b58565b905060005b8181101561276c57600080612698600884613b63565b90925090506000876126b8836bffffffffffffffffffffffff8a166156a5565b6126c291906156cf565b90506126ce8187615c24565b95506127126001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846bffffffffffffffffffffffff8416613872565b6040516bffffffffffffffffffffffff821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a2505050806001019050612682565b5050600e80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff929092169190911790555050565b6127b7612f97565b610f7f81614058565b6127c8613371565b610f7f816141ca565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260008082526020820152600082900361286657506040805180820190915267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260006020820152610e7c565b60006128728385615c49565b90507fe7e230f0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016128df576128ca8360048187615c91565b8101906128d79190615cbb565b915050610e7c565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016129605760408051808201909152806129408560048189615c91565b81019061294d9190615ce7565b815260006020909101529150610e7c9050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006547801000000000000000000000000000000000000000000000000900463ffffffff16808511156129fb576040517f869337890000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610aa3565b6006547c0100000000000000000000000000000000000000000000000000000000900463ffffffff16841115612a5d576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554600160a01b900461ffff16831115612aa4576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81612af0576007546601000000000000900460ff1615612af0576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000808083815b81811015612eba576000878783818110612b1a57612b1a6157a4565b905060400201803603810190612b3091906157f7565b905060006001600160a01b0316612b6b7f00000000000000000000000000000000000000000000000000000000000000008360000151610ebf565b6001600160a01b031603612bb95780516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b80516001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c08201819052612cde57600754612ca29061ffff16662386f26fc100006156a5565b612cac90886156bc565b600754909750612cc89062010000900463ffffffff1687615d00565b9550612cd5602086615d00565b94505050612eb2565b604081015160009061ffff1615612e025760008c6001600160a01b031684600001516001600160a01b031614612da55760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526401000000009092041690634ab35b0b90602401602060405180830381865afa158015612d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d9e9190615d1d565b9050612da8565b508a5b620186a0836040015161ffff16612dea8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661428b90919063ffffffff16565b612df491906156a5565b612dfe91906156cf565b9150505b6060820151612e119088615d00565b9650816080015186612e239190615d00565b8251909650600090612e429063ffffffff16662386f26fc100006156a5565b905080821015612e6157612e56818a6156bc565b985050505050612eb2565b6000836020015163ffffffff16662386f26fc10000612e8091906156a5565b905080831115612ea057612e94818b6156bc565b99505050505050612eb2565b612eaa838b6156bc565b995050505050505b600101612afe565b50509450945094915050565b60008063ffffffff8316612edc610180866156a5565b612ee8876102206156bc565b612ef291906156bc565b612efc91906156bc565b6005546006549192506000917c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690612f3e9061ffff16846156a5565b612f4891906156bc565b60065490915062010000900461ffff16612f726dffffffffffffffffffffffffffff8916836156a5565b612f7c91906156a5565b612f8c90655af3107a40006156a5565b979650505050505050565b6000546001600160a01b03163314612fed576002546001600160a01b03163314612fed576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60005b825181101561328357600083828151811061300f5761300f6157a4565b60200260200101519050602063ffffffff168160a0015163ffffffff16101561308257805160a08201516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526001600160a01b03909216600483015263ffffffff166024820152604401610aa3565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009096169590951764010000000092871692909202919091177fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff166801000000000000000093909216929092027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff16176a010000000000000000000091841691909102177fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff166e01000000000000000000000000000093909216929092027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1617720100000000000000000000000000000000000094151594909402939093177fffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff16730100000000000000000000000000000000000000931515939093029290921790915501612ff2565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d0826040516132b39190615d38565b60405180910390a160005b815181101561332e57600c60008383815181106132dd576132dd6157a4565b6020908102919091018101516001600160a01b0316825281019190915260400160002080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556001016132be565b50805115610ebb577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b816040516133659190615516565b60405180910390a15050565b6000546001600160a01b03163314612fed5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610aa3565b60e08101516001600160a01b031661340f576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548160ff0219169083151502179055509050507f45b5ad483aa608464c2c7f278bd413d284d7790cdc836e40652e23a0277082206040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152508260405161124c929190615dd8565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261384e82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426138329190615df5565b85608001516fffffffffffffffffffffffffffffffff166142c8565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526110f09084906142f0565b8051604081111561392f576040517fb5a10cfa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff161561398357600e5463ffffffff6c010000000000000000000000008204166bffffffffffffffffffffffff909116106139835761398361252a565b600061398f6008613b58565b90505b80156139d15760006139b06139a8600184615df5565b600890613b63565b5090506139be6008826143d5565b5050806139ca90615e08565b9050613992565b506000805b82811015613ad95760008482815181106139f2576139f26157a4565b60200260200101516000015190506000858381518110613a1457613a146157a4565b60200260200101516020015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480613a6957506001600160a01b038216155b15613aab576040517f4de938d10000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610aa3565b613abb60088361ffff84166143ea565b50613aca61ffff821685615d00565b935050508060010190506139d6565b50600e80547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd2490613b4b9083908690615e3d565b60405180910390a1505050565b6000610e7c82614400565b6000808080613b72868661440b565b909450925050505b9250929050565b8154600090613b9d90600160801b900463ffffffff1642615df5565b90508015613c255760018301548354613bd8916fffffffffffffffffffffffffffffffff808216928116918591600160801b909104166142c8565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617600160801b4263ffffffff16021783555b60208201518354613c4b916fffffffffffffffffffffffffffffffff9081169116614436565b835483511515600160a01b027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff9283161717845560208301516040808501518316600160801b0291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990613b4b9084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d9e9190615e5c565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613e075783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b6020840151612522907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83169061428b565b610f7f600382600061444c565b60008151602014613e8157816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610aa39190614c27565b600082806020019051810190613e97919061572f565b90506001600160a01b03811180613eaf575061040081105b15610e7c57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610aa39190614c27565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001613f7e9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001613fb79190615e8f565b60405160208183030381529060405280519060200120876101600151604051602001613fe39190615ea2565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b6000610f67836001600160a01b038416614756565b60005b815181101561419a576000828281518110614078576140786157a4565b60209081029190910181015160408051608080820183528385015163ffffffff90811683528385015167ffffffffffffffff908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9688166c0100000000000000000000000002969096167fffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009095169116179290921791909116929092171790555060010161405b565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e8160405161124c9190615eb5565b336001600160a01b038216036142225760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610aa3565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a76400006142be837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166156a5565b610f6791906156cf565b60006142e7856142d884866156a5565b6142e290876156bc565b614436565b95945050505050565b6000614345826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166147629092919063ffffffff16565b8051909150156110f0578080602001905181019061436391906157da565b6110f05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa3565b6000610f67836001600160a01b038416614771565b6000612522846001600160a01b0385168461478e565b6000610e7c826147ab565b6000808061441985856147b5565b600081815260029690960160205260409095205494959350505050565b60008183106144455781610f67565b5090919050565b8254600160a01b900460ff161580614462575081155b1561446c57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906144a590600160801b900463ffffffff1642615df5565b9050801561454b57818311156144e7576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461451490839085908490600160801b90046fffffffffffffffffffffffffffffffff166142c8565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff16600160801b4263ffffffff160217875592505b848210156145e8576001600160a01b03841661459d576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610aa3565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610aa3565b848310156146d457600186810154600160801b90046fffffffffffffffffffffffffffffffff1690600090829061461f9082615df5565b614629878a615df5565b61463391906156bc565b61463d91906156cf565b90506001600160a01b038616614689576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610aa3565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610aa3565b6146de8584615df5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f6783836147c1565b606061252284846000856147d9565b60008181526002830160205260408120819055610f6783836148c0565b6000828152600284016020526040812082905561252284846148cc565b6000610e7c825490565b6000610f6783836148d8565b60008181526001830160205260408120541515610f67565b6060824710156148515760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa3565b600080866001600160a01b0316858760405161486d9190615f36565b60006040518083038185875af1925050503d80600081146148aa576040519150601f19603f3d011682016040523d82523d6000602084013e6148af565b606091505b5091509150612f8c87838387614902565b6000610f67838361497b565b6000610f678383614a75565b60008260000182815481106148ef576148ef6157a4565b9060005260206000200154905092915050565b6060831561497157825160000361496a576001600160a01b0385163b61496a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa3565b5081612522565b6125228383614ac4565b60008181526001830160205260408120548015614a6457600061499f600183615df5565b85549091506000906149b390600190615df5565b9050818114614a185760008660000182815481106149d3576149d36157a4565b90600052602060002001549050808760000184815481106149f6576149f66157a4565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614a2957614a29615f52565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610e7c565b6000915050610e7c565b5092915050565b6000818152600183016020526040812054614abc57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e7c565b506000610e7c565b815115614ad45781518083602001fd5b8060405162461bcd60e51b8152600401610aa39190614c27565b6001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401525060c0810151614b6b60c08401826001600160a01b03169052565b5060e08101516110f060e08401826001600160a01b03169052565b6101008101610e7c8284614aee565b6001600160a01b0381168114610f7f57600080fd5b8035614bb581614b95565b919050565b600060208284031215614bcc57600080fd5b8135610f6781614b95565b60005b83811015614bf2578181015183820152602001614bda565b50506000910152565b60008151808452614c13816020860160208601614bd7565b601f01601f19169290920160200192915050565b602081526000610f676020830184614bfb565b67ffffffffffffffff81168114610f7f57600080fd5b600060a08284031215614c6257600080fd5b50919050565b60008060408385031215614c7b57600080fd5b8235614c8681614c3a565b9150602083013567ffffffffffffffff811115614ca257600080fd5b614cae85828601614c50565b9150509250929050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b60405290565b6040516101a0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b60405160a0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b6040805190810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b604051601f8201601f1916810167ffffffffffffffff81118282101715614d8a57614d8a614cb8565b604052919050565b600067ffffffffffffffff821115614dac57614dac614cb8565b5060051b60200190565b63ffffffff81168114610f7f57600080fd5b8035614bb581614db6565b803561ffff81168114614bb557600080fd5b8015158114610f7f57600080fd5b8035614bb581614de5565b600082601f830112614e0f57600080fd5b81356020614e24614e1f83614d92565b614d61565b8083825260208201915060208460051b870101935086841115614e4657600080fd5b602086015b84811015614e6b578035614e5e81614b95565b8352918301918301614e4b565b509695505050505050565b6000806040808486031215614e8a57600080fd5b833567ffffffffffffffff80821115614ea257600080fd5b818601915086601f830112614eb657600080fd5b81356020614ec6614e1f83614d92565b82815260e0928302850182019282820191908b851115614ee557600080fd5b958301955b84871015614f8e5780878d031215614f025760008081fd5b614f0a614cce565b8735614f1581614b95565b815287850135614f2481614db6565b8186015287890135614f3581614db6565b818a01526060614f46898201614dd3565b90820152608088810135614f5981614db6565b9082015260a0614f6a898201614dc8565b9082015260c0614f7b898201614df3565b9082015283529586019591830191614eea565b5097505087013593505080831115614fa557600080fd5b5050614cae85828601614dfe565b60008060408385031215614fc657600080fd5b8235614fd181614c3a565b91506020830135614fe181614b95565b809150509250929050565b60006101a08284031215614fff57600080fd5b615007614cf7565b61501083614baa565b815261501e60208401614dd3565b602082015261502f60408401614dc8565b604082015261504060608401614dd3565b606082015261505160808401614dc8565b608082015261506260a08401614dd3565b60a082015261507360c08401614dd3565b60c082015261508460e08401614baa565b60e0820152610100615097818501614dc8565b908201526101206150a9848201614dc8565b908201526101406150bb848201614dd3565b908201526101606150cd848201614dc8565b908201526101806150df848201614df3565b908201529392505050565b600080604083850312156150fd57600080fd5b8235614fd181614b95565b80516001600160a01b03168252602081015161512a602084018261ffff169052565b506040810151615142604084018263ffffffff169052565b506060810151615158606084018261ffff169052565b506080810151615170608084018263ffffffff169052565b5060a081015161518660a084018261ffff169052565b5060c081015161519c60c084018261ffff169052565b5060e08101516151b760e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015190911690830152610180908101511515910152565b6101a08101610e7c8284615108565b6000806020838503121561522857600080fd5b823567ffffffffffffffff8082111561524057600080fd5b818501915085601f83011261525457600080fd5b81358181111561526357600080fd5b8660208260061b850101111561527857600080fd5b60209290920196919550909350505050565b60008151808452602080850194506020840160005b838110156152d357815180516001600160a01b0316885283015161ffff16838801526040909601959082019060010161529f565b509495945050505050565b6040815260006152f1604083018561528a565b90508260208301529392505050565b80356fffffffffffffffffffffffffffffffff81168114614bb557600080fd5b60006060828403121561533257600080fd5b6040516060810181811067ffffffffffffffff8211171561535557615355614cb8565b604052823561536381614de5565b815261537160208401615300565b602082015261538260408401615300565b60408201529392505050565b600080600080608085870312156153a457600080fd5b84356153af81614c3a565b9350602085013567ffffffffffffffff8111156153cb57600080fd5b6153d787828801614c50565b9350506040850135915060608501356153ef81614b95565b939692955090935050565b6000602080838503121561540d57600080fd5b823567ffffffffffffffff81111561542457600080fd5b8301601f8101851361543557600080fd5b8035615443614e1f82614d92565b81815260a0918202830184019184820191908884111561546257600080fd5b938501935b838510156154ed5780858a03121561547f5760008081fd5b615487614d1b565b853561549281614b95565b8152858701356154a181614db6565b818801526040868101356154b481614c3a565b908201526060868101356154c781614c3a565b908201526080868101356154da81614de5565b9082015283529384019391850191615467565b50979650505050505050565b60006020828403121561550b57600080fd5b8135610f6781614c3a565b6020808252825182820181905260009190848201906040850190845b818110156155575783516001600160a01b031683529284019291840191600101615532565b50909695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261559857600080fd5b83018035915067ffffffffffffffff8211156155b357600080fd5b602001915036819003821315613b7a57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155fd57600080fd5b83018035915067ffffffffffffffff82111561561857600080fd5b6020019150600681901b3603821315613b7a57600080fd5b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114614bb557600080fd5b6000806040838503121561566f57600080fd5b61567883615630565b915061568660208401615630565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e7c57610e7c61568f565b80820180821115610e7c57610e7c61568f565b6000826156ec57634e487b7160e01b600052601260045260246000fd5b500490565b67ffffffffffffffff818116838216019080821115614a6e57614a6e61568f565b60006020828403121561572457600080fd5b8151610f6781614b95565b60006020828403121561574157600080fd5b5051919050565b60006040828403121561575a57600080fd5b615762614d3e565b823561576d81614b95565b815261577b60208401614dd3565b60208201529392505050565b60006020828403121561579957600080fd5b8151610f6781614c3a565b634e487b7160e01b600052603260045260246000fd5b8181036000831280158383131683831282161715614a6e57614a6e61568f565b6000602082840312156157ec57600080fd5b8151610f6781614de5565b60006040828403121561580957600080fd5b615811614d3e565b823561581c81614b95565b81526020928301359281019290925250919050565b6bffffffffffffffffffffffff818116838216019080821115614a6e57614a6e61568f565b600067ffffffffffffffff8083168181036158735761587361568f565b6001019392505050565b602081526000825160a0602084015261589960c0840182614bfb565b905067ffffffffffffffff602085015116604084015260408401516001600160a01b038082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600082601f8301126158f757600080fd5b815167ffffffffffffffff81111561591157615911614cb8565b6159246020601f19601f84011601614d61565b81815284602083860101111561593957600080fd5b612522826020830160208701614bd7565b60006020828403121561595c57600080fd5b815167ffffffffffffffff8082111561597457600080fd5b908301906040828603121561598857600080fd5b615990614d3e565b82518281111561599f57600080fd5b6159ab878286016158e6565b8252506020830151828111156159c057600080fd5b6159cc878286016158e6565b60208301525095945050505050565b6020815260008251608060208401526159f760a0840182614bfb565b90506020840151601f1980858403016040860152615a158383614bfb565b9250604086015191508085840301606086015250615a338282614bfb565b91505063ffffffff60608501511660808401528091505092915050565b60008151808452602080850194506020840160005b838110156152d357815180516001600160a01b031688528301518388015260409096019590820190600101615a65565b60008282518085526020808601955060208260051b8401016020860160005b84811015615ae257601f19868403018952615ad0838351614bfb565b98840198925090830190600101615ab4565b5090979650505050505050565b60208152615b0a60208201835167ffffffffffffffff169052565b60006020830151615b2660408401826001600160a01b03169052565b5060408301516001600160a01b038116606084015250606083015167ffffffffffffffff8116608084015250608083015160a083015260a0830151615b6f60c084018215159052565b5060c083015167ffffffffffffffff811660e08401525060e0830151610100615ba2818501836001600160a01b03169052565b840151610120848101919091528401516101a061014080860182905291925090615bd06101c0860184614bfb565b9250808601519050601f19610160818786030181880152615bf18584615a50565b945080880151925050610180818786030181880152615c108584615a95565b970151959092019490945250929392505050565b6bffffffffffffffffffffffff828116828216039080821115614a6e57614a6e61568f565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015615c895780818660040360031b1b83161692505b505092915050565b60008085851115615ca157600080fd5b83861115615cae57600080fd5b5050820193919092039150565b600060408284031215615ccd57600080fd5b615cd5614d3e565b82358152602083013561577b81614de5565b600060208284031215615cf957600080fd5b5035919050565b63ffffffff818116838216019080821115614a6e57614a6e61568f565b600060208284031215615d2f57600080fd5b610f6782615630565b602080825282518282018190526000919060409081850190868401855b82811015615dcb57815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e09093019290850190600101615d55565b5091979650505050505050565b6102a08101615de78285614aee565b610f67610100830184615108565b81810381811115610e7c57610e7c61568f565b600081615e1757615e1761568f565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b63ffffffff83168152604060208201526000612522604083018461528a565b600060408284031215615e6e57600080fd5b615e76614d3e565b615e7f83615630565b8152602083015161577b81614db6565b602081526000610f676020830184615a50565b602081526000610f676020830184615a95565b602080825282518282018190526000919060409081850190868401855b82811015615dcb57815180516001600160a01b031685528681015163ffffffff16878601528581015167ffffffffffffffff908116878701526060808301519091169086015260809081015115159085015260a09093019290850190600101615ed2565b60008251615f48818460208701614bd7565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfea164736f6c6343000818000a", } var EVM2EVMOnRampABI = EVM2EVMOnRampMetaData.ABI @@ -2279,7 +2278,7 @@ func (EVM2EVMOnRampConfigChanged) Topic() common.Hash { } func (EVM2EVMOnRampConfigSet) Topic() common.Hash { - return common.HexToHash("0xe375c8cb6ea9807cd0371503b632b93da5ee0f1f64205db8b5b28b95d6b588b0") + return common.HexToHash("0x45b5ad483aa608464c2c7f278bd413d284d7790cdc836e40652e23a027708220") } func (EVM2EVMOnRampFeeConfigSet) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go index fe2ac3f87e..b2ee5137da 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go @@ -82,8 +82,8 @@ type TokenPoolChainUpdate struct { } var LockReleaseTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b506040516200487838038062004878833981016040819052620000359162000565565b848484833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200017e565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001695760408051600081526020810190915262000169908462000229565b5050505090151560e05250620006d692505050565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000688565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000688565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200069e565b8554909150600090620003fa906001906200069e565b9050818114620004665760008660000182815481106200041e576200041e62000688565b906000526020600020015490508087600001848154811062000444576200044462000688565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a620006c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b805180151581146200054f57600080fd5b600080600080600060a086880312156200057e57600080fd5b85516200058b8162000513565b602087810151919650906001600160401b0380821115620005ab57600080fd5b818901915089601f830112620005c057600080fd5b815181811115620005d557620005d56200052c565b8060051b604051601f19603f83011681018181108582111715620005fd57620005fd6200052c565b60405291825284820192508381018501918c8311156200061c57600080fd5b938501935b828510156200064557620006358562000542565b8452938501939285019262000621565b8099505050505050506200065c6040870162000542565b92506200066c6060870162000554565b91506200067c6080870162000542565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161410662000772600039600081816104d1015261163801526000818161057e01528181611bd4015261267901526000818161055801528181611a050152611e8a015260008181610285015281816102da0152818161075c0152818161082e015281816108bf015281816116fa0152818161192501528181611daa0152818161260f015261286401526141066000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80638da5cb5b1161010f578063c4bffe2b116100a2578063dc0bd97111610071578063dc0bd97114610556578063e0351e131461057c578063eb521a4c146105a2578063f2fde38b146105b557600080fd5b8063c4bffe2b14610508578063c75eea9c1461051d578063cf7401f314610530578063db6327dc1461054357600080fd5b8063b0f479a1116100de578063b0f479a11461049e578063b7946580146104bc578063bb98546b146104cf578063c0d78655146104f557600080fd5b80638da5cb5b146103dc5780639a4575b9146103fa578063a7cd63b71461041a578063af58d59f1461042f57600080fd5b8063432a6ba31161018757806378a010b21161015657806378a010b21461039b57806379ba5097146103ae5780637d54534e146103b65780638926f54f146103c957600080fd5b8063432a6ba31461033957806354c8a4f3146103575780636cfd15531461036a5780636d3d1a581461037d57600080fd5b8063181f5a77116101c3578063181f5a771461024757806321df0da714610283578063240028e8146102ca578063390775371461031757600080fd5b806301ffc9a7146101ea5780630a2fd493146102125780630a861f2a14610232575b600080fd5b6101fd6101f836600461320e565b6105c8565b60405190151581526020015b60405180910390f35b61022561022036600461326d565b610624565b60405161020991906132f6565b610245610240366004613309565b6106d4565b005b6102256040518060400160405280601e81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e302d646576000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610209565b6101fd6102d836600461334f565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61032a61032536600461336c565b610885565b60405190518152602001610209565b60085473ffffffffffffffffffffffffffffffffffffffff166102a5565b6102456103653660046133f4565b61097b565b61024561037836600461334f565b6109f6565b60095473ffffffffffffffffffffffffffffffffffffffff166102a5565b6102456103a9366004613460565b610a45565b610245610bb4565b6102456103c436600461334f565b610cb1565b6101fd6103d736600461326d565b610d00565b60005473ffffffffffffffffffffffffffffffffffffffff166102a5565b61040d6104083660046134e3565b610d17565b604051610209919061351e565b610422610db1565b604051610209919061357e565b61044261043d36600461326d565b610dc2565b604051610209919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102a5565b6102256104ca36600461326d565b610e97565b7f00000000000000000000000000000000000000000000000000000000000000006101fd565b61024561050336600461334f565b610ec2565b610510610f9d565b60405161020991906135d8565b61044261052b36600461326d565b611055565b61024561053e366004613740565b611127565b610245610551366004613785565b6111b0565b7f00000000000000000000000000000000000000000000000000000000000000006102a5565b7f00000000000000000000000000000000000000000000000000000000000000006101fd565b6102456105b0366004613309565b611636565b6102456105c336600461334f565b611752565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061061e575061061e82611766565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061064f906137c7565b80601f016020809104026020016040519081016040528092919081815260200182805461067b906137c7565b80156106c85780601f1061069d576101008083540402835291602001916106c8565b820191906000526020600020905b8154815290600101906020018083116106ab57829003601f168201915b50505050509050919050565b60085473ffffffffffffffffffffffffffffffffffffffff16331461072c576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107dc919061381a565b1015610814576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61085573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016338361184a565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108a56108a0836138de565b61191e565b6108ea73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633606085013561184a565b6108fa606083016040840161334f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52846060013560405161095c91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610983611b4f565b6109f084848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611bd292505050565b50505050565b6109fe611b4f565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610a4d611b4f565b610a5683610d00565b610a98576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610723565b67ffffffffffffffff831660009081526007602052604081206004018054610abf906137c7565b80601f0160208091040260200160405190810160405280929190818152602001828054610aeb906137c7565b8015610b385780601f10610b0d57610100808354040283529160200191610b38565b820191906000526020600020905b815481529060010190602001808311610b1b57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610b67838583613a23565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610ba693929190613b3e565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610723565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610cb9611b4f565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061061e600567ffffffffffffffff8416611d88565b6040805180820190915260608082526020820152610d3c610d3783613ba2565b611da3565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610d968460200160208101906104ca919061326d565b81526040805160208181019092526000815291015292915050565b6060610dbd6002611f6d565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261061e90611f7a565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061064f906137c7565b610eca611b4f565b73ffffffffffffffffffffffffffffffffffffffff8116610f17576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610fab6005611f6d565b90506000815167ffffffffffffffff811115610fc957610fc961361a565b604051908082528060200260200182016040528015610ff2578160200160208202803683370190505b50905060005b825181101561104e5782818151811061101357611013613c44565b602002602001015182828151811061102d5761102d613c44565b67ffffffffffffffff90921660209283029190910190910152600101610ff8565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261061e90611f7a565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590611167575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156111a0576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610723565b6111ab83838361202c565b505050565b6111b8611b4f565b60005b818110156111ab5760008383838181106111d7576111d7613c44565b90506020028101906111e99190613c73565b6111f290613cb1565b90506112078160800151826020015115612116565b61121a8160a00151826020015115612116565b80602001511561151657805161123c9060059067ffffffffffffffff1661224f565b6112815780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610723565b60408101515115806112965750606081015151155b156112cd576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906114ae9082613d65565b50606082015160058201906114c39082613d65565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506115099493929190613e7f565b60405180910390a161162d565b805161152e9060059067ffffffffffffffff1661225b565b6115735780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610723565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906115dc60048301826131c0565b6115ea6005830160006131c0565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016111bb565b7f000000000000000000000000000000000000000000000000000000000000000061168d576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085473ffffffffffffffffffffffffffffffffffffffff1633146116e0576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610723565b61172273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612267565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b61175a611b4f565b611763816122c5565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806117f957507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061061e57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526111ab9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526123ba565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119b35760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610723565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a859190613f18565b15611abc576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ac981602001516124c6565b6000611ad88260200151610624565b9050805160001480611afc575080805190602001208260a001518051906020012014155b15611b39578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161072391906132f6565b611b4b826020015183606001516125ec565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611bd0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610723565b565b7f0000000000000000000000000000000000000000000000000000000000000000611c29576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611cbf576000838281518110611c4957611c49613c44565b60200260200101519050611c6781600261263390919063ffffffff16565b15611cb65760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611c2c565b5060005b81518110156111ab576000828281518110611ce057611ce0613c44565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d245750611d80565b611d2f600282612655565b15611d7e5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611cc3565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611e385760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610723565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611ee6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f0a9190613f18565b15611f41576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f4e8160400151612677565b611f5b81602001516126f6565b61176381602001518260600151612844565b60606000611d9c83612888565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261200882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611fec9190613f64565b85608001516fffffffffffffffffffffffffffffffff166128e3565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61203583610d00565b612077576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610723565b612082826000612116565b67ffffffffffffffff831660009081526007602052604090206120a5908361290d565b6120b0816000612116565b67ffffffffffffffff831660009081526007602052604090206120d6906002018261290d565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161210993929190613f77565b60405180910390a1505050565b8151156121dd5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061216c575060408201516fffffffffffffffffffffffffffffffff16155b156121a557816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107239190613ffa565b8015611b4b576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612216575060208201516fffffffffffffffffffffffffffffffff1615155b15611b4b57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107239190613ffa565b6000611d9c8383612aaf565b6000611d9c8383612afe565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109f09085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161189c565b3373ffffffffffffffffffffffffffffffffffffffff821603612344576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610723565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061241c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612bf19092919063ffffffff16565b8051909150156111ab578080602001905181019061243a9190613f18565b6111ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610723565b6124cf81610d00565b612511576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610723565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612590573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b49190613f18565b611763576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610723565b67ffffffffffffffff82166000908152600760205260409020611b4b90600201827f0000000000000000000000000000000000000000000000000000000000000000612c00565b6000611d9c8373ffffffffffffffffffffffffffffffffffffffff8416612afe565b6000611d9c8373ffffffffffffffffffffffffffffffffffffffff8416612aaf565b7f000000000000000000000000000000000000000000000000000000000000000015611763576126a8600282612f83565b611763576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610723565b6126ff81610d00565b612741576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610723565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156127ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127de9190614036565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611763576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610723565b67ffffffffffffffff82166000908152600760205260409020611b4b90827f0000000000000000000000000000000000000000000000000000000000000000612c00565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106c857602002820191906000526020600020905b8154815260200190600101908083116128c45750505050509050919050565b6000612902856128f38486614053565b6128fd908761406a565b612fb2565b90505b949350505050565b815460009061293690700100000000000000000000000000000000900463ffffffff1642613f64565b905080156129d8576001830154835461297e916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166128e3565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546129fe916fffffffffffffffffffffffffffffffff9081169116612fb2565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612109908490613ffa565b6000818152600183016020526040812054612af65750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561061e565b50600061061e565b60008181526001830160205260408120548015612be7576000612b22600183613f64565b8554909150600090612b3690600190613f64565b9050818114612b9b576000866000018281548110612b5657612b56613c44565b9060005260206000200154905080876000018481548110612b7957612b79613c44565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612bac57612bac61407d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061061e565b600091505061061e565b60606129058484600085612fc8565b825474010000000000000000000000000000000000000000900460ff161580612c27575081155b15612c3157505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612c7790700100000000000000000000000000000000900463ffffffff1642613f64565b90508015612d375781831115612cb9576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612cf39083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166128e3565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612dee5773ffffffffffffffffffffffffffffffffffffffff8416612d96576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610723565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610723565b84831015612f015760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612e329082613f64565b612e3c878a613f64565b612e46919061406a565b612e5091906140ac565b905073ffffffffffffffffffffffffffffffffffffffff8616612ea9576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610723565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610723565b612f0b8584613f64565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611d9c565b6000818310612fc15781611d9c565b5090919050565b60608247101561305a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610723565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161308391906140e7565b60006040518083038185875af1925050503d80600081146130c0576040519150601f19603f3d011682016040523d82523d6000602084013e6130c5565b606091505b50915091506130d6878383876130e1565b979650505050505050565b606083156131775782516000036131705773ffffffffffffffffffffffffffffffffffffffff85163b613170576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610723565b5081612905565b612905838381511561318c5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072391906132f6565b5080546131cc906137c7565b6000825580601f106131dc575050565b601f01602090049060005260206000209081019061176391905b8082111561320a57600081556001016131f6565b5090565b60006020828403121561322057600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611d9c57600080fd5b803567ffffffffffffffff8116811461326857600080fd5b919050565b60006020828403121561327f57600080fd5b611d9c82613250565b60005b838110156132a357818101518382015260200161328b565b50506000910152565b600081518084526132c4816020860160208601613288565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d9c60208301846132ac565b60006020828403121561331b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461176357600080fd5b803561326881613322565b60006020828403121561336157600080fd5b8135611d9c81613322565b60006020828403121561337e57600080fd5b813567ffffffffffffffff81111561339557600080fd5b82016101008185031215611d9c57600080fd5b60008083601f8401126133ba57600080fd5b50813567ffffffffffffffff8111156133d257600080fd5b6020830191508360208260051b85010111156133ed57600080fd5b9250929050565b6000806000806040858703121561340a57600080fd5b843567ffffffffffffffff8082111561342257600080fd5b61342e888389016133a8565b9096509450602087013591508082111561344757600080fd5b50613454878288016133a8565b95989497509550505050565b60008060006040848603121561347557600080fd5b61347e84613250565b9250602084013567ffffffffffffffff8082111561349b57600080fd5b818601915086601f8301126134af57600080fd5b8135818111156134be57600080fd5b8760208285010111156134d057600080fd5b6020830194508093505050509250925092565b6000602082840312156134f557600080fd5b813567ffffffffffffffff81111561350c57600080fd5b820160a08185031215611d9c57600080fd5b60208152600082516040602084015261353a60608401826132ac565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261357582826132ac565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156135cc57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161359a565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156135cc57835167ffffffffffffffff16835292840192918401916001016135f4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561366d5761366d61361a565b60405290565b60405160c0810167ffffffffffffffff8111828210171561366d5761366d61361a565b801515811461176357600080fd5b803561326881613696565b80356fffffffffffffffffffffffffffffffff8116811461326857600080fd5b6000606082840312156136e157600080fd5b6040516060810181811067ffffffffffffffff821117156137045761370461361a565b604052905080823561371581613696565b8152613723602084016136af565b6020820152613734604084016136af565b60408201525092915050565b600080600060e0848603121561375557600080fd5b61375e84613250565b925061376d85602086016136cf565b915061377c85608086016136cf565b90509250925092565b6000806020838503121561379857600080fd5b823567ffffffffffffffff8111156137af57600080fd5b6137bb858286016133a8565b90969095509350505050565b600181811c908216806137db57607f821691505b602082108103613814577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561382c57600080fd5b5051919050565b600082601f83011261384457600080fd5b813567ffffffffffffffff8082111561385f5761385f61361a565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156138a5576138a561361a565b816040528381528660208588010111156138be57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600061010082360312156138f157600080fd5b6138f9613649565b823567ffffffffffffffff8082111561391157600080fd5b61391d36838701613833565b835261392b60208601613250565b602084015261393c60408601613344565b60408401526060850135606084015261395760808601613344565b608084015260a085013591508082111561397057600080fd5b61397c36838701613833565b60a084015260c085013591508082111561399557600080fd5b6139a136838701613833565b60c084015260e08501359150808211156139ba57600080fd5b506139c736828601613833565b60e08301525092915050565b601f8211156111ab576000816000526020600020601f850160051c810160208610156139fc5750805b601f850160051c820191505b81811015613a1b57828155600101613a08565b505050505050565b67ffffffffffffffff831115613a3b57613a3b61361a565b613a4f83613a4983546137c7565b836139d3565b6000601f841160018114613aa15760008515613a6b5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613b37565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613af05786850135825560209485019460019092019101613ad0565b5086821015613b2b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613b5160408301866132ac565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613bb457600080fd5b60405160a0810167ffffffffffffffff8282108183111715613bd857613bd861361a565b816040528435915080821115613bed57600080fd5b50613bfa36828601613833565b825250613c0960208401613250565b60208201526040830135613c1c81613322565b6040820152606083810135908201526080830135613c3981613322565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ca757600080fd5b9190910192915050565b60006101408236031215613cc457600080fd5b613ccc613673565b613cd583613250565b8152613ce3602084016136a4565b6020820152604083013567ffffffffffffffff80821115613d0357600080fd5b613d0f36838701613833565b60408401526060850135915080821115613d2857600080fd5b50613d3536828601613833565b606083015250613d4836608085016136cf565b6080820152613d5a3660e085016136cf565b60a082015292915050565b815167ffffffffffffffff811115613d7f57613d7f61361a565b613d9381613d8d84546137c7565b846139d3565b602080601f831160018114613de65760008415613db05750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613a1b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e3357888601518255948401946001909101908401613e14565b5085821015613e6f57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613ea3818401876132ac565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613ee19050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613575565b600060208284031215613f2a57600080fd5b8151611d9c81613696565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561061e5761061e613f35565b67ffffffffffffffff8416815260e08101613fc360208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612905565b6060810161061e82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561404857600080fd5b8151611d9c81613322565b808202811582820484141761061e5761061e613f35565b8082018082111561061e5761061e613f35565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826140e2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613ca781846020870161328856fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b506040516200499e3803806200499e833981016040819052620000359162000565565b848484833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200017e565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001695760408051600081526020810190915262000169908462000229565b5050505090151560e05250620006d692505050565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000688565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000688565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200069e565b8554909150600090620003fa906001906200069e565b9050818114620004665760008660000182815481106200041e576200041e62000688565b906000526020600020015490508087600001848154811062000444576200044462000688565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a620006c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b805180151581146200054f57600080fd5b600080600080600060a086880312156200057e57600080fd5b85516200058b8162000513565b602087810151919650906001600160401b0380821115620005ab57600080fd5b818901915089601f830112620005c057600080fd5b815181811115620005d557620005d56200052c565b8060051b604051601f19603f83011681018181108582111715620005fd57620005fd6200052c565b60405291825284820192508381018501918c8311156200061c57600080fd5b938501935b828510156200064557620006358562000542565b8452938501939285019262000621565b8099505050505050506200065c6040870162000542565b92506200066c6060870162000554565b91506200067c6080870162000542565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161422c62000772600039600081816104ef015261173201526000818161059c01528181611cce015261277301526000818161057601528181611aff0152611f84015260008181610290015281816102e50152818161077a0152818161084c015281816108dd015281816117f401528181611a1f01528181611ea401528181612709015261295e015261422c6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063c4bffe2b116100a2578063dc0bd97111610071578063dc0bd97114610574578063e0351e131461059a578063eb521a4c146105c0578063f2fde38b146105d357600080fd5b8063c4bffe2b14610526578063c75eea9c1461053b578063cf7401f31461054e578063db6327dc1461056157600080fd5b8063b0f479a1116100de578063b0f479a1146104bc578063b7946580146104da578063bb98546b146104ed578063c0d786551461051357600080fd5b80638da5cb5b146103fa5780639a4575b914610418578063a7cd63b714610438578063af58d59f1461044d57600080fd5b806354c8a4f31161018757806378a010b21161015657806378a010b2146103b957806379ba5097146103cc5780637d54534e146103d45780638926f54f146103e757600080fd5b806354c8a4f31461036257806366320087146103755780636cfd1553146103885780636d3d1a581461039b57600080fd5b806321df0da7116101c357806321df0da71461028e578063240028e8146102d55780633907753714610322578063432a6ba31461034457600080fd5b806301ffc9a7146101f55780630a2fd4931461021d5780630a861f2a1461023d578063181f5a7714610252575b600080fd5b610208610203366004613308565b6105e6565b60405190151581526020015b60405180910390f35b61023061022b366004613367565b610642565b60405161021491906133f0565b61025061024b366004613403565b6106f2565b005b6102306040518060400160405280601e81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e302d646576000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b6102086102e3366004613449565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b610335610330366004613466565b6108a3565b60405190518152602001610214565b60095473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103703660046134ee565b610999565b61025061038336600461355a565b610a14565b610250610396366004613449565b610af0565b60085473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103c7366004613586565b610b3f565b610250610cae565b6102506103e2366004613449565b610dab565b6102086103f5366004613367565b610dfa565b60005473ffffffffffffffffffffffffffffffffffffffff166102b0565b61042b610426366004613609565b610e11565b6040516102149190613644565b610440610eab565b60405161021491906136a4565b61046061045b366004613367565b610ebc565b604051610214919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102306104e8366004613367565b610f91565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b610250610521366004613449565b610fbc565b61052e611097565b60405161021491906136fe565b610460610549366004613367565b61114f565b61025061055c366004613866565b611221565b61025061056f3660046138ab565b6112aa565b7f00000000000000000000000000000000000000000000000000000000000000006102b0565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105ce366004613403565b611730565b6102506105e1366004613449565b61184c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061063c575061063c82611860565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061066d906138ed565b80601f0160208091040260200160405190810160405280929190818152602001828054610699906138ed565b80156106e65780601f106106bb576101008083540402835291602001916106e6565b820191906000526020600020905b8154815290600101906020018083116106c957829003601f168201915b50505050509050919050565b60095473ffffffffffffffffffffffffffffffffffffffff16331461074a576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa9190613940565b1015610832576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611944565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c36108be83613a04565b611a18565b61090873ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016336060850135611944565b6109186060830160408401613449565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52846060013560405161097a91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6109a1611c49565b610a0e84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ccc92505050565b50505050565b610a1c611c49565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610a8457600080fd5b505af1158015610a98573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610ae491815260200190565b60405180910390a25050565b610af8611c49565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b47611c49565b610b5083610dfa565b610b92576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b67ffffffffffffffff831660009081526007602052604081206004018054610bb9906138ed565b80601f0160208091040260200160405190810160405280929190818152602001828054610be5906138ed565b8015610c325780601f10610c0757610100808354040283529160200191610c32565b820191906000526020600020905b815481529060010190602001808311610c1557829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610c61838583613b49565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610ca093929190613c64565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610741565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610db3611c49565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061063c600567ffffffffffffffff8416611e82565b6040805180820190915260608082526020820152610e36610e3183613cc8565b611e9d565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610e908460200160208101906104e89190613367565b81526040805160208181019092526000815291015292915050565b6060610eb76002612067565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261063c90612074565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061066d906138ed565b610fc4611c49565b73ffffffffffffffffffffffffffffffffffffffff8116611011576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110a56005612067565b90506000815167ffffffffffffffff8111156110c3576110c3613740565b6040519080825280602002602001820160405280156110ec578160200160208202803683370190505b50905060005b82518110156111485782818151811061110d5761110d613d6a565b602002602001015182828151811061112757611127613d6a565b67ffffffffffffffff909216602092830291909101909101526001016110f2565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261063c90612074565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611261575060005473ffffffffffffffffffffffffffffffffffffffff163314155b1561129a576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b6112a5838383612126565b505050565b6112b2611c49565b60005b818110156112a55760008383838181106112d1576112d1613d6a565b90506020028101906112e39190613d99565b6112ec90613dd7565b90506113018160800151826020015115612210565b6113148160a00151826020015115612210565b8060200151156116105780516113369060059067ffffffffffffffff16612349565b61137b5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b60408101515115806113905750606081015151155b156113c7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115a89082613e8b565b50606082015160058201906115bd9082613e8b565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116039493929190613fa5565b60405180910390a1611727565b80516116289060059067ffffffffffffffff16612355565b61166d5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116d660048301826132ba565b6116e46005830160006132ba565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112b5565b7f0000000000000000000000000000000000000000000000000000000000000000611787576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff1633146117da576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b61181c73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612361565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611854611c49565b61185d816123bf565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806118f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061063c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112a59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526124b4565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611aad5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b7f919061403e565b15611bb6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bc381602001516125c0565b6000611bd28260200151610642565b9050805160001480611bf6575080805190602001208260a001518051906020012014155b15611c33578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161074191906133f0565b611c45826020015183606001516126e6565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611cca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610741565b565b7f0000000000000000000000000000000000000000000000000000000000000000611d23576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611db9576000838281518110611d4357611d43613d6a565b60200260200101519050611d6181600261272d90919063ffffffff16565b15611db05760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611d26565b5060005b81518110156112a5576000828281518110611dda57611dda613d6a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e1e5750611e7a565b611e2960028261274f565b15611e785760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611dbd565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611f325760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611fe0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612004919061403e565b1561203b576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120488160400151612771565b61205581602001516127f0565b61185d8160200151826060015161293e565b60606000611e9683612982565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261210282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426120e6919061408a565b85608001516fffffffffffffffffffffffffffffffff166129dd565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61212f83610dfa565b612171576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b61217c826000612210565b67ffffffffffffffff8316600090815260076020526040902061219f9083612a07565b6121aa816000612210565b67ffffffffffffffff831660009081526007602052604090206121d09060020182612a07565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516122039392919061409d565b60405180910390a1505050565b8151156122d75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612266575060408201516fffffffffffffffffffffffffffffffff16155b1561229f57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107419190614120565b8015611c45576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612310575060208201516fffffffffffffffffffffffffffffffff1615155b15611c4557816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107419190614120565b6000611e968383612ba9565b6000611e968383612bf8565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a0e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611996565b3373ffffffffffffffffffffffffffffffffffffffff82160361243e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610741565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612516826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612ceb9092919063ffffffff16565b8051909150156112a55780806020019051810190612534919061403e565b6112a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610741565b6125c981610dfa565b61260b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561268a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ae919061403e565b61185d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c4590600201827f0000000000000000000000000000000000000000000000000000000000000000612cfa565b6000611e968373ffffffffffffffffffffffffffffffffffffffff8416612bf8565b6000611e968373ffffffffffffffffffffffffffffffffffffffff8416612ba9565b7f00000000000000000000000000000000000000000000000000000000000000001561185d576127a260028261307d565b61185d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610741565b6127f981610dfa565b61283b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156128b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128d8919061415c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461185d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c4590827f0000000000000000000000000000000000000000000000000000000000000000612cfa565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106e657602002820191906000526020600020905b8154815260200190600101908083116129be5750505050509050919050565b60006129fc856129ed8486614179565b6129f79087614190565b6130ac565b90505b949350505050565b8154600090612a3090700100000000000000000000000000000000900463ffffffff164261408a565b90508015612ad25760018301548354612a78916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166129dd565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612af8916fffffffffffffffffffffffffffffffff90811691166130ac565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612203908490614120565b6000818152600183016020526040812054612bf05750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561063c565b50600061063c565b60008181526001830160205260408120548015612ce1576000612c1c60018361408a565b8554909150600090612c309060019061408a565b9050818114612c95576000866000018281548110612c5057612c50613d6a565b9060005260206000200154905080876000018481548110612c7357612c73613d6a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ca657612ca66141a3565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061063c565b600091505061063c565b60606129ff84846000856130c2565b825474010000000000000000000000000000000000000000900460ff161580612d21575081155b15612d2b57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612d7190700100000000000000000000000000000000900463ffffffff164261408a565b90508015612e315781831115612db3576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612ded9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166129dd565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612ee85773ffffffffffffffffffffffffffffffffffffffff8416612e90576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610741565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610741565b84831015612ffb5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f2c908261408a565b612f36878a61408a565b612f409190614190565b612f4a91906141d2565b905073ffffffffffffffffffffffffffffffffffffffff8616612fa3576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610741565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610741565b613005858461408a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611e96565b60008183106130bb5781611e96565b5090919050565b606082471015613154576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610741565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161317d919061420d565b60006040518083038185875af1925050503d80600081146131ba576040519150601f19603f3d011682016040523d82523d6000602084013e6131bf565b606091505b50915091506131d0878383876131db565b979650505050505050565b6060831561327157825160000361326a5773ffffffffffffffffffffffffffffffffffffffff85163b61326a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610741565b50816129ff565b6129ff83838151156132865781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074191906133f0565b5080546132c6906138ed565b6000825580601f106132d6575050565b601f01602090049060005260206000209081019061185d91905b8082111561330457600081556001016132f0565b5090565b60006020828403121561331a57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611e9657600080fd5b803567ffffffffffffffff8116811461336257600080fd5b919050565b60006020828403121561337957600080fd5b611e968261334a565b60005b8381101561339d578181015183820152602001613385565b50506000910152565b600081518084526133be816020860160208601613382565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611e9660208301846133a6565b60006020828403121561341557600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461185d57600080fd5b80356133628161341c565b60006020828403121561345b57600080fd5b8135611e968161341c565b60006020828403121561347857600080fd5b813567ffffffffffffffff81111561348f57600080fd5b82016101008185031215611e9657600080fd5b60008083601f8401126134b457600080fd5b50813567ffffffffffffffff8111156134cc57600080fd5b6020830191508360208260051b85010111156134e757600080fd5b9250929050565b6000806000806040858703121561350457600080fd5b843567ffffffffffffffff8082111561351c57600080fd5b613528888389016134a2565b9096509450602087013591508082111561354157600080fd5b5061354e878288016134a2565b95989497509550505050565b6000806040838503121561356d57600080fd5b82356135788161341c565b946020939093013593505050565b60008060006040848603121561359b57600080fd5b6135a48461334a565b9250602084013567ffffffffffffffff808211156135c157600080fd5b818601915086601f8301126135d557600080fd5b8135818111156135e457600080fd5b8760208285010111156135f657600080fd5b6020830194508093505050509250925092565b60006020828403121561361b57600080fd5b813567ffffffffffffffff81111561363257600080fd5b820160a08185031215611e9657600080fd5b60208152600082516040602084015261366060608401826133a6565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261369b82826133a6565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156136f257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016136c0565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156136f257835167ffffffffffffffff168352928401929184019160010161371a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561379357613793613740565b60405290565b60405160c0810167ffffffffffffffff8111828210171561379357613793613740565b801515811461185d57600080fd5b8035613362816137bc565b80356fffffffffffffffffffffffffffffffff8116811461336257600080fd5b60006060828403121561380757600080fd5b6040516060810181811067ffffffffffffffff8211171561382a5761382a613740565b604052905080823561383b816137bc565b8152613849602084016137d5565b602082015261385a604084016137d5565b60408201525092915050565b600080600060e0848603121561387b57600080fd5b6138848461334a565b925061389385602086016137f5565b91506138a285608086016137f5565b90509250925092565b600080602083850312156138be57600080fd5b823567ffffffffffffffff8111156138d557600080fd5b6138e1858286016134a2565b90969095509350505050565b600181811c9082168061390157607f821691505b60208210810361393a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561395257600080fd5b5051919050565b600082601f83011261396a57600080fd5b813567ffffffffffffffff8082111561398557613985613740565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156139cb576139cb613740565b816040528381528660208588010111156139e457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613a1757600080fd5b613a1f61376f565b823567ffffffffffffffff80821115613a3757600080fd5b613a4336838701613959565b8352613a516020860161334a565b6020840152613a626040860161343e565b604084015260608501356060840152613a7d6080860161343e565b608084015260a0850135915080821115613a9657600080fd5b613aa236838701613959565b60a084015260c0850135915080821115613abb57600080fd5b613ac736838701613959565b60c084015260e0850135915080821115613ae057600080fd5b50613aed36828601613959565b60e08301525092915050565b601f8211156112a5576000816000526020600020601f850160051c81016020861015613b225750805b601f850160051c820191505b81811015613b4157828155600101613b2e565b505050505050565b67ffffffffffffffff831115613b6157613b61613740565b613b7583613b6f83546138ed565b83613af9565b6000601f841160018114613bc75760008515613b915750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613c5d565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613c165786850135825560209485019460019092019101613bf6565b5086821015613c51577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613c7760408301866133a6565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613cda57600080fd5b60405160a0810167ffffffffffffffff8282108183111715613cfe57613cfe613740565b816040528435915080821115613d1357600080fd5b50613d2036828601613959565b825250613d2f6020840161334a565b60208201526040830135613d428161341c565b6040820152606083810135908201526080830135613d5f8161341c565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613dcd57600080fd5b9190910192915050565b60006101408236031215613dea57600080fd5b613df2613799565b613dfb8361334a565b8152613e09602084016137ca565b6020820152604083013567ffffffffffffffff80821115613e2957600080fd5b613e3536838701613959565b60408401526060850135915080821115613e4e57600080fd5b50613e5b36828601613959565b606083015250613e6e36608085016137f5565b6080820152613e803660e085016137f5565b60a082015292915050565b815167ffffffffffffffff811115613ea557613ea5613740565b613eb981613eb384546138ed565b84613af9565b602080601f831160018114613f0c5760008415613ed65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b41565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613f5957888601518255948401946001909101908401613f3a565b5085821015613f9557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613fc9818401876133a6565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506140079050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e083015261369b565b60006020828403121561405057600080fd5b8151611e96816137bc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561063c5761063c61405b565b67ffffffffffffffff8416815260e081016140e960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526129ff565b6060810161063c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561416e57600080fd5b8151611e968161341c565b808202811582820484141761063c5761063c61405b565b8082018082111561063c5761063c61405b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614208577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613dcd81846020870161338256fea164736f6c6343000818000a", } var LockReleaseTokenPoolABI = LockReleaseTokenPoolMetaData.ABI @@ -750,6 +750,18 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetRouter(ne return _LockReleaseTokenPool.Contract.SetRouter(&_LockReleaseTokenPool.TransactOpts, newRouter) } +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) TransferLiquidity(opts *bind.TransactOpts, from common.Address, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "transferLiquidity", from, amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) TransferLiquidity(from common.Address, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.TransferLiquidity(&_LockReleaseTokenPool.TransactOpts, from, amount) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) TransferLiquidity(from common.Address, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.TransferLiquidity(&_LockReleaseTokenPool.TransactOpts, from, amount) +} + func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return _LockReleaseTokenPool.contract.Transact(opts, "transferOwnership", to) } @@ -1881,6 +1893,134 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseLiquidityRemoved return event, nil } +type LockReleaseTokenPoolLiquidityTransferredIterator struct { + Event *LockReleaseTokenPoolLiquidityTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolLiquidityTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolLiquidityTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LockReleaseTokenPoolLiquidityTransferredIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolLiquidityTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolLiquidityTransferred struct { + From common.Address + Amount *big.Int + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterLiquidityTransferred(opts *bind.FilterOpts, from []common.Address) (*LockReleaseTokenPoolLiquidityTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "LiquidityTransferred", fromRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolLiquidityTransferredIterator{contract: _LockReleaseTokenPool.contract, event: "LiquidityTransferred", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchLiquidityTransferred(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityTransferred, from []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "LiquidityTransferred", fromRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolLiquidityTransferred) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseLiquidityTransferred(log types.Log) (*LockReleaseTokenPoolLiquidityTransferred, error) { + event := new(LockReleaseTokenPoolLiquidityTransferred) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "LiquidityTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type LockReleaseTokenPoolLockedIterator struct { Event *LockReleaseTokenPoolLocked @@ -2939,6 +3079,8 @@ func (_LockReleaseTokenPool *LockReleaseTokenPool) ParseLog(log types.Log) (gene return _LockReleaseTokenPool.ParseLiquidityAdded(log) case _LockReleaseTokenPool.abi.Events["LiquidityRemoved"].ID: return _LockReleaseTokenPool.ParseLiquidityRemoved(log) + case _LockReleaseTokenPool.abi.Events["LiquidityTransferred"].ID: + return _LockReleaseTokenPool.ParseLiquidityTransferred(log) case _LockReleaseTokenPool.abi.Events["Locked"].ID: return _LockReleaseTokenPool.ParseLocked(log) case _LockReleaseTokenPool.abi.Events["Minted"].ID: @@ -2997,6 +3139,10 @@ func (LockReleaseTokenPoolLiquidityRemoved) Topic() common.Hash { return common.HexToHash("0xc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf9840171719") } +func (LockReleaseTokenPoolLiquidityTransferred) Topic() common.Hash { + return common.HexToHash("0x6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db62") +} + func (LockReleaseTokenPoolLocked) Topic() common.Hash { return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") } @@ -3092,6 +3238,8 @@ type LockReleaseTokenPoolInterface interface { SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + TransferLiquidity(opts *bind.TransactOpts, from common.Address, amount *big.Int) (*types.Transaction, error) + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) WithdrawLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) @@ -3150,6 +3298,12 @@ type LockReleaseTokenPoolInterface interface { ParseLiquidityRemoved(log types.Log) (*LockReleaseTokenPoolLiquidityRemoved, error) + FilterLiquidityTransferred(opts *bind.FilterOpts, from []common.Address) (*LockReleaseTokenPoolLiquidityTransferredIterator, error) + + WatchLiquidityTransferred(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLiquidityTransferred, from []common.Address) (event.Subscription, error) + + ParseLiquidityTransferred(log types.Log) (*LockReleaseTokenPoolLiquidityTransferred, error) + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*LockReleaseTokenPoolLockedIterator, error) WatchLocked(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolLocked, sender []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go index 15dd411741..73f2ea6dc4 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go @@ -82,8 +82,8 @@ type TokenPoolChainUpdate struct { } var LockReleaseTokenPoolAndProxyMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162004e1b38038062004e1b83398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508181146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161469a620007816000396000818161051701526118510152600081816105c401528181611e860152612a4201526000818161059e01528181611c1e0152612139015260008181610292015281816102e7015281816107a2015281816108740152818161093e0152818161191301528181611b3e015281816120590152818161223f015281816129d80152612c2d015261469a6000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c80639766b9321161012a578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e13146105c2578063eb521a4c146105e8578063f2fde38b146105fb57600080fd5b8063db6327dc14610589578063dc0bd9711461059c57600080fd5b8063c0d786551461053b578063c4bffe2b1461054e578063c75eea9c14610563578063cf7401f31461057657600080fd5b8063af58d59f116100f9578063af58d59f14610475578063b0f479a1146104e4578063b794658014610502578063bb98546b1461051557600080fd5b80639766b9321461041a5780639a4575b91461042d578063a7cd63b71461044d578063a8d87a3b1461046257600080fd5b806354c8a4f3116101bd57806379ba50971161018c57806383826b2b1161017157806383826b2b146103d65780638926f54f146103e95780638da5cb5b146103fc57600080fd5b806379ba5097146103bb5780637d54534e146103c357600080fd5b806354c8a4f3146103645780636cfd1553146103775780636d3d1a581461038a57806378a010b2146103a857600080fd5b806321df0da7116101f957806321df0da714610290578063240028e8146102d75780633907753714610324578063432a6ba31461034657600080fd5b806301ffc9a71461022b5780630a2fd493146102535780630a861f2a14610273578063181f5a7714610288575b600080fd5b61023e6102393660046135d7565b61060e565b60405190151581526020015b60405180910390f35b610266610261366004613636565b61066a565b60405161024a91906136bf565b6102866102813660046136d2565b61071a565b005b6102666108cb565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161024a565b61023e6102e5366004613718565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b610337610332366004613735565b6108e7565b6040519051815260200161024a565b60095473ffffffffffffffffffffffffffffffffffffffff166102b2565b6102866103723660046137bd565b610a10565b610286610385366004613718565b610a8b565b600a5473ffffffffffffffffffffffffffffffffffffffff166102b2565b6102866103b6366004613829565b610ada565b610286610c49565b6102866103d1366004613718565b610d46565b61023e6103e43660046138ac565b610d95565b61023e6103f7366004613636565b610e62565b60005473ffffffffffffffffffffffffffffffffffffffff166102b2565b610286610428366004613718565b610e79565b61044061043b3660046138e3565b610f08565b60405161024a919061391e565b610455610fd1565b60405161024a919061397e565b6102b2610470366004613636565b503090565b610488610483366004613636565b610fe2565b60405161024a919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102b2565b610266610510366004613636565b6110b7565b7f000000000000000000000000000000000000000000000000000000000000000061023e565b610286610549366004613718565b6110e2565b6105566111b6565b60405161024a91906139d8565b610488610571366004613636565b61126e565b610286610584366004613b8f565b611340565b610286610597366004613bd4565b6113c9565b7f00000000000000000000000000000000000000000000000000000000000000006102b2565b7f000000000000000000000000000000000000000000000000000000000000000061023e565b6102866105f63660046136d2565b61184f565b610286610609366004613718565b61196b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061066457506106648261197f565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061069590613c16565b80601f01602080910402602001604051908101604052809291908181526020018280546106c190613c16565b801561070e5780601f106106e35761010080835404028352916020019161070e565b820191906000526020600020905b8154815290600101906020018083116106f157829003601f168201915b50505050509050919050565b60095473ffffffffffffffffffffffffffffffffffffffff163314610772576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108229190613c69565b101561085a576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61089b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611a63565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040518060600160405280602681526020016146686026913981565b60408051602081019091526000815261090761090283613d1e565b611b37565b60085473ffffffffffffffffffffffffffffffffffffffff1661096e5761096973ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016336060850135611a63565b61097f565b61097f61097a83613d1e565b611d68565b61098f6060830160408401613718565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f5284606001356040516109f191815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a18611e01565b610a8584848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611e8492505050565b50505050565b610a93611e01565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610ae2611e01565b610aeb83610e62565b610b2d576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610769565b67ffffffffffffffff831660009081526007602052604081206004018054610b5490613c16565b80601f0160208091040260200160405190810160405280929190818152602001828054610b8090613c16565b8015610bcd5780601f10610ba257610100808354040283529160200191610bcd565b820191906000526020600020905b815481529060010190602001808311610bb057829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610bfc838583613e63565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610c3b93929190613f7d565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610cca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610769565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610d4e611e01565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610e5b5750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610e37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5b9190613fe1565b9392505050565b6000610664600567ffffffffffffffff841661203a565b610e81611e01565b6008805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610f2d610f2883613ffe565b612052565b60085473ffffffffffffffffffffffffffffffffffffffff1615610f5c57610f5c610f5783613ffe565b61221c565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610fb68460200160208101906105109190613636565b81526040805160208181019092526000815291015292915050565b6060610fdd6002612336565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261066490612343565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061069590613c16565b6110ea611e01565b73ffffffffffffffffffffffffffffffffffffffff8116611137576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610efc565b606060006111c46005612336565b90506000815167ffffffffffffffff8111156111e2576111e2613a1a565b60405190808252806020026020018201604052801561120b578160200160208202803683370190505b50905060005b82518110156112675782818151811061122c5761122c6140a0565b6020026020010151828281518110611246576112466140a0565b67ffffffffffffffff90921660209283029190910190910152600101611211565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261066490612343565b600a5473ffffffffffffffffffffffffffffffffffffffff163314801590611380575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156113b9576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610769565b6113c48383836123f5565b505050565b6113d1611e01565b60005b818110156113c45760008383838181106113f0576113f06140a0565b905060200281019061140291906140cf565b61140b9061410d565b905061142081608001518260200151156124df565b6114338160a001518260200151156124df565b80602001511561172f5780516114559060059067ffffffffffffffff16612618565b61149a5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610769565b60408101515115806114af5750606081015151155b156114e6576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906116c790826141c1565b50606082015160058201906116dc90826141c1565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061172294939291906142db565b60405180910390a1611846565b80516117479060059067ffffffffffffffff16612624565b61178c5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610769565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906117f56004830182613589565b611803600583016000613589565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016113d4565b7f00000000000000000000000000000000000000000000000000000000000000006118a6576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff1633146118f9576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610769565b61193b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612630565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611973611e01565b61197c8161268e565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611a1257507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061066457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526113c49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612783565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611bcc5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610769565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611c7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9e9190613fe1565b15611cd5576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ce2816020015161288f565b6000611cf1826020015161066a565b9050805160001480611d15575080805190602001208260a001518051906020012014155b15611d52578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161076991906136bf565b611d64826020015183606001516129b5565b5050565b6008548151606083015160208401516040517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90941693638627fad693611dcc9390923392600401614374565b600060405180830381600087803b158015611de657600080fd5b505af1158015611dfa573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610769565b565b7f0000000000000000000000000000000000000000000000000000000000000000611edb576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611f71576000838281518110611efb57611efb6140a0565b60200260200101519050611f198160026129fc90919063ffffffff16565b15611f685760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611ede565b5060005b81518110156113c4576000828281518110611f9257611f926140a0565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611fd65750612032565b611fe1600282612a1e565b156120305760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611f75565b60008181526001830160205260408120541515610e5b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146120e75760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610769565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612195573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121b99190613fe1565b156121f0576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121fd8160400151612a40565b61220a8160200151612abf565b61197c81602001518260600151612c0d565b60085460608201516122699173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611a63565b60085460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909516946396875445946122d1949392916004016143d5565b6000604051808303816000875af11580156122f0573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611d649190810190614435565b60606000610e5b83612c51565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526123d182606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426123b591906144d2565b85608001516fffffffffffffffffffffffffffffffff16612cac565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6123fe83610e62565b612440576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610769565b61244b8260006124df565b67ffffffffffffffff8316600090815260076020526040902061246e9083612cd6565b6124798160006124df565b67ffffffffffffffff8316600090815260076020526040902061249f9060020182612cd6565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516124d2939291906144e5565b60405180910390a1505050565b8151156125a65781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612535575060408201516fffffffffffffffffffffffffffffffff16155b1561256e57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107699190614568565b8015611d64576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806125df575060208201516fffffffffffffffffffffffffffffffff1615155b15611d6457816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107699190614568565b6000610e5b8383612e78565b6000610e5b8383612ec7565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a859085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611ab5565b3373ffffffffffffffffffffffffffffffffffffffff82160361270d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610769565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006127e5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612fba9092919063ffffffff16565b8051909150156113c457808060200190518101906128039190613fe1565b6113c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610769565b61289881610e62565b6128da576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610769565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061297d9190613fe1565b61197c576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610769565b67ffffffffffffffff82166000908152600760205260409020611d6490600201827f0000000000000000000000000000000000000000000000000000000000000000612fc9565b6000610e5b8373ffffffffffffffffffffffffffffffffffffffff8416612ec7565b6000610e5b8373ffffffffffffffffffffffffffffffffffffffff8416612e78565b7f00000000000000000000000000000000000000000000000000000000000000001561197c57612a7160028261334c565b61197c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610769565b612ac881610e62565b612b0a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610769565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612b83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba791906145a4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461197c576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610769565b67ffffffffffffffff82166000908152600760205260409020611d6490827f0000000000000000000000000000000000000000000000000000000000000000612fc9565b60608160000180548060200260200160405190810160405280929190818152602001828054801561070e57602002820191906000526020600020905b815481526020019060010190808311612c8d5750505050509050919050565b6000612ccb85612cbc84866145c1565b612cc690876145d8565b61337b565b90505b949350505050565b8154600090612cff90700100000000000000000000000000000000900463ffffffff16426144d2565b90508015612da15760018301548354612d47916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612cac565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612dc7916fffffffffffffffffffffffffffffffff908116911661337b565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906124d2908490614568565b6000818152600183016020526040812054612ebf57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610664565b506000610664565b60008181526001830160205260408120548015612fb0576000612eeb6001836144d2565b8554909150600090612eff906001906144d2565b9050818114612f64576000866000018281548110612f1f57612f1f6140a0565b9060005260206000200154905080876000018481548110612f4257612f426140a0565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612f7557612f756145eb565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610664565b6000915050610664565b6060612cce8484600085613391565b825474010000000000000000000000000000000000000000900460ff161580612ff0575081155b15612ffa57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061304090700100000000000000000000000000000000900463ffffffff16426144d2565b905080156131005781831115613082576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546130bc9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612cac565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156131b75773ffffffffffffffffffffffffffffffffffffffff841661315f576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610769565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610769565b848310156132ca5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906131fb90826144d2565b613205878a6144d2565b61320f91906145d8565b613219919061461a565b905073ffffffffffffffffffffffffffffffffffffffff8616613272576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610769565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610769565b6132d485846144d2565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610e5b565b600081831061338a5781610e5b565b5090919050565b606082471015613423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610769565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161344c9190614655565b60006040518083038185875af1925050503d8060008114613489576040519150601f19603f3d011682016040523d82523d6000602084013e61348e565b606091505b509150915061349f878383876134aa565b979650505050505050565b606083156135405782516000036135395773ffffffffffffffffffffffffffffffffffffffff85163b613539576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610769565b5081612cce565b612cce83838151156135555781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076991906136bf565b50805461359590613c16565b6000825580601f106135a5575050565b601f01602090049060005260206000209081019061197c91905b808211156135d357600081556001016135bf565b5090565b6000602082840312156135e957600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e5b57600080fd5b803567ffffffffffffffff8116811461363157600080fd5b919050565b60006020828403121561364857600080fd5b610e5b82613619565b60005b8381101561366c578181015183820152602001613654565b50506000910152565b6000815180845261368d816020860160208601613651565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610e5b6020830184613675565b6000602082840312156136e457600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461197c57600080fd5b8035613631816136eb565b60006020828403121561372a57600080fd5b8135610e5b816136eb565b60006020828403121561374757600080fd5b813567ffffffffffffffff81111561375e57600080fd5b82016101008185031215610e5b57600080fd5b60008083601f84011261378357600080fd5b50813567ffffffffffffffff81111561379b57600080fd5b6020830191508360208260051b85010111156137b657600080fd5b9250929050565b600080600080604085870312156137d357600080fd5b843567ffffffffffffffff808211156137eb57600080fd5b6137f788838901613771565b9096509450602087013591508082111561381057600080fd5b5061381d87828801613771565b95989497509550505050565b60008060006040848603121561383e57600080fd5b61384784613619565b9250602084013567ffffffffffffffff8082111561386457600080fd5b818601915086601f83011261387857600080fd5b81358181111561388757600080fd5b87602082850101111561389957600080fd5b6020830194508093505050509250925092565b600080604083850312156138bf57600080fd5b6138c883613619565b915060208301356138d8816136eb565b809150509250929050565b6000602082840312156138f557600080fd5b813567ffffffffffffffff81111561390c57600080fd5b820160a08185031215610e5b57600080fd5b60208152600082516040602084015261393a6060840182613675565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526139758282613675565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156139cc57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161399a565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156139cc57835167ffffffffffffffff16835292840192918401916001016139f4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613a6d57613a6d613a1a565b60405290565b60405160c0810167ffffffffffffffff81118282101715613a6d57613a6d613a1a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613add57613add613a1a565b604052919050565b801515811461197c57600080fd5b803561363181613ae5565b80356fffffffffffffffffffffffffffffffff8116811461363157600080fd5b600060608284031215613b3057600080fd5b6040516060810181811067ffffffffffffffff82111715613b5357613b53613a1a565b6040529050808235613b6481613ae5565b8152613b7260208401613afe565b6020820152613b8360408401613afe565b60408201525092915050565b600080600060e08486031215613ba457600080fd5b613bad84613619565b9250613bbc8560208601613b1e565b9150613bcb8560808601613b1e565b90509250925092565b60008060208385031215613be757600080fd5b823567ffffffffffffffff811115613bfe57600080fd5b613c0a85828601613771565b90969095509350505050565b600181811c90821680613c2a57607f821691505b602082108103613c63577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613c7b57600080fd5b5051919050565b600067ffffffffffffffff821115613c9c57613c9c613a1a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613cd957600080fd5b8135613cec613ce782613c82565b613a96565b818152846020838601011115613d0157600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613d3157600080fd5b613d39613a49565b823567ffffffffffffffff80821115613d5157600080fd5b613d5d36838701613cc8565b8352613d6b60208601613619565b6020840152613d7c6040860161370d565b604084015260608501356060840152613d976080860161370d565b608084015260a0850135915080821115613db057600080fd5b613dbc36838701613cc8565b60a084015260c0850135915080821115613dd557600080fd5b613de136838701613cc8565b60c084015260e0850135915080821115613dfa57600080fd5b50613e0736828601613cc8565b60e08301525092915050565b601f8211156113c4576000816000526020600020601f850160051c81016020861015613e3c5750805b601f850160051c820191505b81811015613e5b57828155600101613e48565b505050505050565b67ffffffffffffffff831115613e7b57613e7b613a1a565b613e8f83613e898354613c16565b83613e13565b6000601f841160018114613ee15760008515613eab5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611dfa565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613f305786850135825560209485019460019092019101613f10565b5086821015613f6b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613f906040830186613675565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613ff357600080fd5b8151610e5b81613ae5565b600060a0823603121561401057600080fd5b60405160a0810167ffffffffffffffff828210818311171561403457614034613a1a565b81604052843591508082111561404957600080fd5b5061405636828601613cc8565b82525061406560208401613619565b60208201526040830135614078816136eb565b6040820152606083810135908201526080830135614095816136eb565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261410357600080fd5b9190910192915050565b6000610140823603121561412057600080fd5b614128613a73565b61413183613619565b815261413f60208401613af3565b6020820152604083013567ffffffffffffffff8082111561415f57600080fd5b61416b36838701613cc8565b6040840152606085013591508082111561418457600080fd5b5061419136828601613cc8565b6060830152506141a43660808501613b1e565b60808201526141b63660e08501613b1e565b60a082015292915050565b815167ffffffffffffffff8111156141db576141db613a1a565b6141ef816141e98454613c16565b84613e13565b602080601f831160018114614242576000841561420c5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613e5b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561428f57888601518255948401946001909101908401614270565b50858210156142cb57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526142ff81840187613675565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061433d9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613975565b60a08152600061438760a0830187613675565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a06020820152600061440460a0830186613675565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561444757600080fd5b815167ffffffffffffffff81111561445e57600080fd5b8201601f8101841361446f57600080fd5b805161447d613ce782613c82565b81815285602083850101111561449257600080fd5b613975826020830160208601613651565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610664576106646144a3565b67ffffffffffffffff8416815260e0810161453160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612cce565b6060810161066482848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156145b657600080fd5b8151610e5b816136eb565b8082028115828204841417610664576106646144a3565b80820180821115610664576106646144a3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614650577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000825161410381846020870161365156fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004ef938038062004ef983398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508181146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516147786200078160003960008181610545015261190b0152600081816105f201528181611f400152612afc0152600081816105cc01528181611cd801526121f30152600081816102ad01528181610302015281816107d0015281816108a20152818161096c015281816119cd01528181611bf801528181612113015281816122f901528181612a920152612ce701526147786000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e13146105f0578063eb521a4c14610616578063f2fde38b1461062957600080fd5b8063db6327dc146105b7578063dc0bd971146105ca57600080fd5b8063c0d7865514610569578063c4bffe2b1461057c578063c75eea9c14610591578063cf7401f3146105a457600080fd5b8063a8d87a3b11610114578063b0f479a1116100f9578063b0f479a114610512578063b794658014610530578063bb98546b1461054357600080fd5b8063a8d87a3b14610490578063af58d59f146104a357600080fd5b80638da5cb5b1461042a5780639766b932146104485780639a4575b91461045b578063a7cd63b71461047b57600080fd5b806354c8a4f3116101d857806378a010b2116101a75780637d54534e1161018c5780637d54534e146103f157806383826b2b146104045780638926f54f1461041757600080fd5b806378a010b2146103d657806379ba5097146103e957600080fd5b806354c8a4f31461037f57806366320087146103925780636cfd1553146103a55780636d3d1a58146103b857600080fd5b806321df0da71161021457806321df0da7146102ab578063240028e8146102f2578063390775371461033f578063432a6ba31461036157600080fd5b806301ffc9a7146102465780630a2fd4931461026e5780630a861f2a1461028e578063181f5a77146102a3575b600080fd5b610259610254366004613691565b61063c565b60405190151581526020015b60405180910390f35b61028161027c3660046136f0565b610698565b6040516102659190613779565b6102a161029c36600461378c565b610748565b005b6102816108f9565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102596103003660046137d2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61035261034d3660046137ef565b610915565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a161038d366004613877565b610a3e565b6102a16103a03660046138e3565b610ab9565b6102a16103b33660046137d2565b610b45565b60085473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16103e436600461390f565b610b94565b6102a1610d03565b6102a16103ff3660046137d2565b610e00565b610259610412366004613992565b610e4f565b6102596104253660046136f0565b610f1c565b60005473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16104563660046137d2565b610f33565b61046e6104693660046139c9565b610fc2565b6040516102659190613a04565b61048361108b565b6040516102659190613a64565b6102cd61049e3660046136f0565b503090565b6104b66104b13660046136f0565b61109c565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102cd565b61028161053e3660046136f0565b611171565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16105773660046137d2565b61119c565b610584611270565b6040516102659190613abe565b6104b661059f3660046136f0565b611328565b6102a16105b2366004613c75565b6113fa565b6102a16105c5366004613cba565b611483565b7f00000000000000000000000000000000000000000000000000000000000000006102cd565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a161062436600461378c565b611909565b6102a16106373660046137d2565b611a25565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d40566000000000000000000000000000000000000000000000000000000001480610692575061069282611a39565b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106c390613cfc565b80601f01602080910402602001604051908101604052809291908181526020018280546106ef90613cfc565b801561073c5780601f106107115761010080835404028352916020019161073c565b820191906000526020600020905b81548152906001019060200180831161071f57829003601f168201915b50505050509050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146107a0576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190613d4f565b1015610888576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108c973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611b1d565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040518060600160405280602681526020016147466026913981565b60408051602081019091526000815261093561093083613e04565b611bf1565b60095473ffffffffffffffffffffffffffffffffffffffff1661099c5761099773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016336060850135611b1d565b6109ad565b6109ad6109a883613e04565b611e22565b6109bd60608301604084016137d2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f528460600135604051610a1f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a46611ebb565b610ab384848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f3e92505050565b50505050565b610ac1611ebb565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610b2957600080fd5b505af1158015610b3d573d6000803e3d6000fd5b505050505050565b610b4d611ebb565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b9c611ebb565b610ba583610f1c565b610be7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b67ffffffffffffffff831660009081526007602052604081206004018054610c0e90613cfc565b80601f0160208091040260200160405190810160405280929190818152602001828054610c3a90613cfc565b8015610c875780601f10610c5c57610100808354040283529160200191610c87565b820191906000526020600020905b815481529060010190602001808311610c6a57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cb6838583613f41565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610cf59392919061405b565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610797565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e08611ebb565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610f155750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610ef1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1591906140bf565b9392505050565b6000610692600567ffffffffffffffff84166120f4565b610f3b611ebb565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610fe7610fe2836140dc565b61210c565b60095473ffffffffffffffffffffffffffffffffffffffff161561101657611016611011836140dc565b6122d6565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a2604051806040016040528061107084602001602081019061053e91906136f0565b81526040805160208181019092526000815291015292915050565b606061109760026123f0565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610692906123fd565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106c390613cfc565b6111a4611ebb565b73ffffffffffffffffffffffffffffffffffffffff81166111f1576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610fb6565b6060600061127e60056123f0565b90506000815167ffffffffffffffff81111561129c5761129c613b00565b6040519080825280602002602001820160405280156112c5578160200160208202803683370190505b50905060005b8251811015611321578281815181106112e6576112e661417e565b60200260200101518282815181106113005761130061417e565b67ffffffffffffffff909216602092830291909101909101526001016112cb565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610692906123fd565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061143a575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611473576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b61147e8383836124af565b505050565b61148b611ebb565b60005b8181101561147e5760008383838181106114aa576114aa61417e565b90506020028101906114bc91906141ad565b6114c5906141eb565b90506114da8160800151826020015115612599565b6114ed8160a00151826020015115612599565b8060200151156117e957805161150f9060059067ffffffffffffffff166126d2565b6115545780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b60408101515115806115695750606081015151155b156115a0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c17909116961515029590951790985590810151940151938116931690910291909117600382015591519091906004820190611781908261429f565b5060608201516005820190611796908261429f565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506117dc94939291906143b9565b60405180910390a1611900565b80516118019060059067ffffffffffffffff166126de565b6118465780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118af6004830182613643565b6118bd600583016000613643565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161148e565b7f0000000000000000000000000000000000000000000000000000000000000000611960576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff1633146119b3576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b6119f573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846126ea565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611a2d611ebb565b611a3681612748565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611acc57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261147e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261283d565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611c865760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d5891906140bf565b15611d8f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d9c8160200151612949565b6000611dab8260200151610698565b9050805160001480611dcf575080805190602001208260a001518051906020012014155b15611e0c578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107979190613779565b611e1e82602001518360600151612a6f565b5050565b6009548151606083015160208401516040517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90941693638627fad693611e869390923392600401614452565b600060405180830381600087803b158015611ea057600080fd5b505af1158015611eb4573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611f3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610797565b565b7f0000000000000000000000000000000000000000000000000000000000000000611f95576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561202b576000838281518110611fb557611fb561417e565b60200260200101519050611fd3816002612ab690919063ffffffff16565b156120225760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f98565b5060005b815181101561147e57600082828151811061204c5761204c61417e565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361209057506120ec565b61209b600282612ad8565b156120ea5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161202f565b60008181526001830160205260408120541515610f15565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121a15760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561224f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227391906140bf565b156122aa576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122b78160400151612afa565b6122c48160200151612b79565b611a3681602001518260600151612cc7565b60095460608201516123239173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611b1d565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9095169463968754459461238b949392916004016144b3565b6000604051808303816000875af11580156123aa573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e1e9190810190614513565b60606000610f1583612d0b565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261248b82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261246f91906145b0565b85608001516fffffffffffffffffffffffffffffffff16612d66565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6124b883610f1c565b6124fa576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b612505826000612599565b67ffffffffffffffff831660009081526007602052604090206125289083612d90565b612533816000612599565b67ffffffffffffffff831660009081526007602052604090206125599060020182612d90565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161258c939291906145c3565b60405180910390a1505050565b8151156126605781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806125ef575060408201516fffffffffffffffffffffffffffffffff16155b1561262857816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107979190614646565b8015611e1e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612699575060208201516fffffffffffffffffffffffffffffffff1615155b15611e1e57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107979190614646565b6000610f158383612f32565b6000610f158383612f81565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ab39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611b6f565b3373ffffffffffffffffffffffffffffffffffffffff8216036127c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610797565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061289f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130749092919063ffffffff16565b80519091501561147e57808060200190518101906128bd91906140bf565b61147e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610797565b61295281610f1c565b612994576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612a13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a3791906140bf565b611a36576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e1e90600201827f0000000000000000000000000000000000000000000000000000000000000000613083565b6000610f158373ffffffffffffffffffffffffffffffffffffffff8416612f81565b6000610f158373ffffffffffffffffffffffffffffffffffffffff8416612f32565b7f000000000000000000000000000000000000000000000000000000000000000015611a3657612b2b600282613406565b611a36576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610797565b612b8281610f1c565b612bc4576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c619190614682565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a36576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e1e90827f0000000000000000000000000000000000000000000000000000000000000000613083565b60608160000180548060200260200160405190810160405280929190818152602001828054801561073c57602002820191906000526020600020905b815481526020019060010190808311612d475750505050509050919050565b6000612d8585612d76848661469f565b612d8090876146b6565b613435565b90505b949350505050565b8154600090612db990700100000000000000000000000000000000900463ffffffff16426145b0565b90508015612e5b5760018301548354612e01916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612d66565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612e81916fffffffffffffffffffffffffffffffff9081169116613435565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061258c908490614646565b6000818152600183016020526040812054612f7957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610692565b506000610692565b6000818152600183016020526040812054801561306a576000612fa56001836145b0565b8554909150600090612fb9906001906145b0565b905081811461301e576000866000018281548110612fd957612fd961417e565b9060005260206000200154905080876000018481548110612ffc57612ffc61417e565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061302f5761302f6146c9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610692565b6000915050610692565b6060612d88848460008561344b565b825474010000000000000000000000000000000000000000900460ff1615806130aa575081155b156130b457505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906130fa90700100000000000000000000000000000000900463ffffffff16426145b0565b905080156131ba578183111561313c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546131769083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612d66565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156132715773ffffffffffffffffffffffffffffffffffffffff8416613219576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610797565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610797565b848310156133845760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906132b590826145b0565b6132bf878a6145b0565b6132c991906146b6565b6132d391906146f8565b905073ffffffffffffffffffffffffffffffffffffffff861661332c576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610797565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610797565b61338e85846145b0565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610f15565b60008183106134445781610f15565b5090919050565b6060824710156134dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610797565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516135069190614733565b60006040518083038185875af1925050503d8060008114613543576040519150601f19603f3d011682016040523d82523d6000602084013e613548565b606091505b509150915061355987838387613564565b979650505050505050565b606083156135fa5782516000036135f35773ffffffffffffffffffffffffffffffffffffffff85163b6135f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610797565b5081612d88565b612d88838381511561360f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107979190613779565b50805461364f90613cfc565b6000825580601f1061365f575050565b601f016020900490600052602060002090810190611a3691905b8082111561368d5760008155600101613679565b5090565b6000602082840312156136a357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f1557600080fd5b803567ffffffffffffffff811681146136eb57600080fd5b919050565b60006020828403121561370257600080fd5b610f15826136d3565b60005b8381101561372657818101518382015260200161370e565b50506000910152565b6000815180845261374781602086016020860161370b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f15602083018461372f565b60006020828403121561379e57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a3657600080fd5b80356136eb816137a5565b6000602082840312156137e457600080fd5b8135610f15816137a5565b60006020828403121561380157600080fd5b813567ffffffffffffffff81111561381857600080fd5b82016101008185031215610f1557600080fd5b60008083601f84011261383d57600080fd5b50813567ffffffffffffffff81111561385557600080fd5b6020830191508360208260051b850101111561387057600080fd5b9250929050565b6000806000806040858703121561388d57600080fd5b843567ffffffffffffffff808211156138a557600080fd5b6138b18883890161382b565b909650945060208701359150808211156138ca57600080fd5b506138d78782880161382b565b95989497509550505050565b600080604083850312156138f657600080fd5b8235613901816137a5565b946020939093013593505050565b60008060006040848603121561392457600080fd5b61392d846136d3565b9250602084013567ffffffffffffffff8082111561394a57600080fd5b818601915086601f83011261395e57600080fd5b81358181111561396d57600080fd5b87602082850101111561397f57600080fd5b6020830194508093505050509250925092565b600080604083850312156139a557600080fd5b6139ae836136d3565b915060208301356139be816137a5565b809150509250929050565b6000602082840312156139db57600080fd5b813567ffffffffffffffff8111156139f257600080fd5b820160a08185031215610f1557600080fd5b602081526000825160406020840152613a20606084018261372f565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613a5b828261372f565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ab257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613a80565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ab257835167ffffffffffffffff1683529284019291840191600101613ada565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613b5357613b53613b00565b60405290565b60405160c0810167ffffffffffffffff81118282101715613b5357613b53613b00565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bc357613bc3613b00565b604052919050565b8015158114611a3657600080fd5b80356136eb81613bcb565b80356fffffffffffffffffffffffffffffffff811681146136eb57600080fd5b600060608284031215613c1657600080fd5b6040516060810181811067ffffffffffffffff82111715613c3957613c39613b00565b6040529050808235613c4a81613bcb565b8152613c5860208401613be4565b6020820152613c6960408401613be4565b60408201525092915050565b600080600060e08486031215613c8a57600080fd5b613c93846136d3565b9250613ca28560208601613c04565b9150613cb18560808601613c04565b90509250925092565b60008060208385031215613ccd57600080fd5b823567ffffffffffffffff811115613ce457600080fd5b613cf08582860161382b565b90969095509350505050565b600181811c90821680613d1057607f821691505b602082108103613d49577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613d6157600080fd5b5051919050565b600067ffffffffffffffff821115613d8257613d82613b00565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613dbf57600080fd5b8135613dd2613dcd82613d68565b613b7c565b818152846020838601011115613de757600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613e1757600080fd5b613e1f613b2f565b823567ffffffffffffffff80821115613e3757600080fd5b613e4336838701613dae565b8352613e51602086016136d3565b6020840152613e62604086016137c7565b604084015260608501356060840152613e7d608086016137c7565b608084015260a0850135915080821115613e9657600080fd5b613ea236838701613dae565b60a084015260c0850135915080821115613ebb57600080fd5b613ec736838701613dae565b60c084015260e0850135915080821115613ee057600080fd5b50613eed36828601613dae565b60e08301525092915050565b601f82111561147e576000816000526020600020601f850160051c81016020861015613f225750805b601f850160051c820191505b81811015610b3d57828155600101613f2e565b67ffffffffffffffff831115613f5957613f59613b00565b613f6d83613f678354613cfc565b83613ef9565b6000601f841160018114613fbf5760008515613f895750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611eb4565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561400e5786850135825560209485019460019092019101613fee565b5086821015614049577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b60408152600061406e604083018661372f565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b6000602082840312156140d157600080fd5b8151610f1581613bcb565b600060a082360312156140ee57600080fd5b60405160a0810167ffffffffffffffff828210818311171561411257614112613b00565b81604052843591508082111561412757600080fd5b5061413436828601613dae565b825250614143602084016136d3565b60208201526040830135614156816137a5565b6040820152606083810135908201526080830135614173816137a5565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126141e157600080fd5b9190910192915050565b600061014082360312156141fe57600080fd5b614206613b59565b61420f836136d3565b815261421d60208401613bd9565b6020820152604083013567ffffffffffffffff8082111561423d57600080fd5b61424936838701613dae565b6040840152606085013591508082111561426257600080fd5b5061426f36828601613dae565b6060830152506142823660808501613c04565b60808201526142943660e08501613c04565b60a082015292915050565b815167ffffffffffffffff8111156142b9576142b9613b00565b6142cd816142c78454613cfc565b84613ef9565b602080601f83116001811461432057600084156142ea5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610b3d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561436d5788860151825594840194600190910190840161434e565b50858210156143a957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526143dd8184018761372f565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061441b9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613a5b565b60a08152600061446560a083018761372f565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a0602082015260006144e260a083018661372f565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561452557600080fd5b815167ffffffffffffffff81111561453c57600080fd5b8201601f8101841361454d57600080fd5b805161455b613dcd82613d68565b81815285602083850101111561457057600080fd5b613a5b82602083016020860161370b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561069257610692614581565b67ffffffffffffffff8416815260e0810161460f60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612d88565b6060810161069282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561469457600080fd5b8151610f15816137a5565b808202811582820484141761069257610692614581565b8082018082111561069257610692614581565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261472e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082516141e181846020870161370b56fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", } var LockReleaseTokenPoolAndProxyABI = LockReleaseTokenPoolAndProxyMetaData.ABI @@ -806,6 +806,18 @@ func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSessi return _LockReleaseTokenPoolAndProxy.Contract.SetRouter(&_LockReleaseTokenPoolAndProxy.TransactOpts, newRouter) } +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) TransferLiquidity(opts *bind.TransactOpts, from common.Address, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "transferLiquidity", from, amount) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) TransferLiquidity(from common.Address, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.TransferLiquidity(&_LockReleaseTokenPoolAndProxy.TransactOpts, from, amount) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactorSession) TransferLiquidity(from common.Address, amount *big.Int) (*types.Transaction, error) { + return _LockReleaseTokenPoolAndProxy.Contract.TransferLiquidity(&_LockReleaseTokenPoolAndProxy.TransactOpts, from, amount) +} + func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return _LockReleaseTokenPoolAndProxy.contract.Transact(opts, "transferOwnership", to) } @@ -3278,6 +3290,8 @@ type LockReleaseTokenPoolAndProxyInterface interface { SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + TransferLiquidity(opts *bind.TransactOpts, from common.Address, amount *big.Int) (*types.Transaction, error) + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) WithdrawLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/price_registry/price_registry.go b/core/gethwrappers/ccip/generated/price_registry/price_registry.go index 19f1bd4a19..a93faaf82c 100644 --- a/core/gethwrappers/ccip/generated/price_registry/price_registry.go +++ b/core/gethwrappers/ccip/generated/price_registry/price_registry.go @@ -147,7 +147,7 @@ type PriceRegistryTokenTransferFeeConfigSingleTokenArgs struct { var PriceRegistryMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"validatePoolReturnData\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620069373803806200693783398101604081905262000034916200180a565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a99565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b65565b5050505050505062001ac8565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001929565b60209081029190910101519050620002f560028262000e98565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001929565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000eb8565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001929565b6020026020010151600c62000eb860201b90919060201c565b1562000499578281815181106200045b576200045b62001929565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001929565b6020026020010151600c62000e9860201b90919060201c565b156200053b57818181518110620004fd57620004fd62001929565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001929565b6020908102919091018101518051818301516001600160a01b0380831660008181526006875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001929565b6020026020010151905060008383815181106200065f576200065f62001929565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061018081015163ffffffff16155b80620006ba57506102008101516001600160e01b031916630a04b54b60e21b14155b80620006d15750602081610160015163ffffffff16105b80620006f15750806060015163ffffffff1681610180015163ffffffff16115b156200071c5760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260086020526040812060010154600160a81b900460e01b6001600160e01b03191690036200079c57816001600160401b03167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516200078e91906200193f565b60405180910390a2620007e0565b816001600160401b03167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad9382604051620007d791906200193f565b60405180910390a25b8060086000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a8154816001600160401b0302191690836001600160401b031602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000abd5762000abd62001929565b6020026020010151600001519050600083838151811062000ae25762000ae262001929565b6020908102919091018101518101516001600160a01b03841660008181526007845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a9c565b60005b825181101562000dd257600083828151811062000b895762000b8962001929565b6020026020010151905060008160000151905060005b82602001515181101562000dc35760008360200151828151811062000bc85762000bc862001929565b602002602001015160200151905060008460200151838151811062000bf15762000bf162001929565b60200260200101516000015190506020826080015163ffffffff16101562000c4a5760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b03841660008181526009602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000db0908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000b9f565b50505080600101905062000b68565b5060005b81518110156200054457600082828151811062000df75762000df762001929565b6020026020010151600001519050600083838151811062000e1c5762000e1c62001929565b6020908102919091018101518101516001600160401b03841660008181526009845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000dd6565b600062000eaf836001600160a01b03841662000ecf565b90505b92915050565b600062000eaf836001600160a01b03841662000fd3565b6000818152600183016020526040812054801562000fc857600062000ef660018362001a90565b855490915060009062000f0c9060019062001a90565b905081811462000f7857600086600001828154811062000f305762000f3062001929565b906000526020600020015490508087600001848154811062000f565762000f5662001929565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f8c5762000f8c62001ab2565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000eb2565b600091505062000eb2565b60008181526001830160205260408120546200101c5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000eb2565b50600062000eb2565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171562001060576200106062001025565b60405290565b60405160c081016001600160401b038111828210171562001060576200106062001025565b60405161022081016001600160401b038111828210171562001060576200106062001025565b604051601f8201601f191681016001600160401b0381118282101715620010dc57620010dc62001025565b604052919050565b80516001600160a01b0381168114620010fc57600080fd5b919050565b805163ffffffff81168114620010fc57600080fd5b6000606082840312156200112957600080fd5b604051606081016001600160401b03811182821017156200114e576200114e62001025565b604052825190915081906001600160601b03811681146200116e57600080fd5b81526200117e60208401620010e4565b6020820152620011916040840162001101565b60408201525092915050565b60006001600160401b03821115620011b957620011b962001025565b5060051b60200190565b600082601f830112620011d557600080fd5b81516020620011ee620011e8836200119d565b620010b1565b8083825260208201915060208460051b8701019350868411156200121157600080fd5b602086015b8481101562001238576200122a81620010e4565b835291830191830162001216565b509695505050505050565b600082601f8301126200125557600080fd5b8151602062001268620011e8836200119d565b828152606092830285018201928282019190878511156200128857600080fd5b8387015b858110156200131b5780890382811215620012a75760008081fd5b620012b16200103b565b620012bc83620010e4565b8152604080601f1984011215620012d35760008081fd5b620012dd6200103b565b9250620012ec888501620010e4565b835283015160ff81168114620013025760008081fd5b828801528087019190915284529284019281016200128c565b5090979650505050505050565b80516001600160401b0381168114620010fc57600080fd5b805161ffff81168114620010fc57600080fd5b80518015158114620010fc57600080fd5b600082601f8301126200137657600080fd5b8151602062001389620011e8836200119d565b82815260059290921b84018101918181019086841115620013a957600080fd5b8286015b84811015620012385780516001600160401b0380821115620013ce57600080fd5b908801906040601f19838c038101821315620013e957600080fd5b620013f36200103b565b6200140089860162001328565b815282850151848111156200141457600080fd5b8086019550508c603f8601126200142a57600080fd5b8885015193506200143f620011e8856200119d565b84815260e09094028501830193898101908e8611156200145e57600080fd5b958401955b858710156200153757868f0360e08112156200147e57600080fd5b620014886200103b565b6200149389620010e4565b815260c08683011215620014a657600080fd5b620014b062001066565b9150620014bf8d8a0162001101565b8252620014ce878a0162001101565b8d830152620014e060608a0162001340565b87830152620014f260808a0162001101565b60608301526200150560a08a0162001101565b60808301526200151860c08a0162001353565b60a0830152808d0191909152825260e09690960195908a019062001463565b828b015250875250505092840192508301620013ad565b600082601f8301126200156057600080fd5b8151602062001573620011e8836200119d565b82815260069290921b840181019181810190868411156200159357600080fd5b8286015b84811015620012385760408189031215620015b25760008081fd5b620015bc6200103b565b620015c782620010e4565b8152620015d685830162001328565b8186015283529183019160400162001597565b80516001600160e01b031981168114620010fc57600080fd5b600082601f8301126200161457600080fd5b8151602062001627620011e8836200119d565b82815261024092830285018201928282019190878511156200164857600080fd5b8387015b858110156200131b5780890382811215620016675760008081fd5b620016716200103b565b6200167c8362001328565b815261022080601f1984011215620016945760008081fd5b6200169e6200108b565b9250620016ad88850162001353565b83526040620016be81860162001340565b898501526060620016d181870162001101565b8286015260809150620016e682870162001101565b9085015260a0620016f986820162001101565b8286015260c091506200170e82870162001340565b9085015260e06200172186820162001101565b8286015261010091506200173782870162001340565b908501526101206200174b86820162001340565b8286015261014091506200176182870162001340565b908501526101606200177586820162001101565b8286015261018091506200178b82870162001101565b908501526101a06200179f86820162001101565b828601526101c09150620017b582870162001328565b908501526101e0620017c986820162001101565b828601526102009150620017df82870162001353565b90850152620017f0858301620015e9565b90840152508087019190915284529284019281016200164c565b6000806000806000806000610120888a0312156200182757600080fd5b62001833898962001116565b60608901519097506001600160401b03808211156200185157600080fd5b6200185f8b838c01620011c3565b975060808a01519150808211156200187657600080fd5b620018848b838c01620011c3565b965060a08a01519150808211156200189b57600080fd5b620018a98b838c0162001243565b955060c08a0151915080821115620018c057600080fd5b620018ce8b838c0162001364565b945060e08a0151915080821115620018e557600080fd5b620018f38b838c016200154e565b93506101008a01519150808211156200190b57600080fd5b506200191a8a828b0162001602565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b8151151581526102208101602083015162001960602084018261ffff169052565b50604083015162001979604084018263ffffffff169052565b50606083015162001992606084018263ffffffff169052565b506080830151620019ab608084018263ffffffff169052565b5060a0830151620019c260a084018261ffff169052565b5060c0830151620019db60c084018263ffffffff169052565b5060e0830151620019f260e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a0808501516001600160401b0316908401526101c080850151909116908301526101e080840151151590830152610200928301516001600160e01b031916929091019190915290565b8181038181111562000eb257634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051614e1562001b22600039600081816102d901528181611ad30152611b3c01526000818161029d0152818161104e01526110ae015260008181610269015281816110d701526111470152614e156000f3fe608060405234801561001057600080fd5b50600436106101b85760003560e01c80637afac322116100f9578063cc88924c11610097578063d8694ccd11610071578063d8694ccd14610a5c578063f2fde38b14610a6f578063f700042a14610a82578063ffdb4b3714610a9557600080fd5b8063cc88924c14610a2e578063cdc73d5114610a41578063d02641a014610a4957600080fd5b806391a2749a116100d357806391a2749a14610939578063a69c64c01461094c578063bf78e03f1461095f578063c4276bfc14610a0c57600080fd5b80637afac3221461078e57806382b49eb0146107a15780638da5cb5b1461091157600080fd5b8063407e108611610166578063514e8cff11610140578063514e8cff146104385780636def4ce7146104db578063770e2dc41461077357806379ba50971461078657600080fd5b8063407e1086146103c557806345ac924d146103d85780634ab35b0b146103f857600080fd5b8063181f5a7711610197578063181f5a77146103525780632451a6271461039b5780633937306f146103b057600080fd5b806241e5be146101bd578063061877e3146101e357806306285c691461023c575b600080fd5b6101d06101cb366004613802565b610add565b6040519081526020015b60405180910390f35b6102236101f136600461383e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101da565b610306604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101da565b61038e6040518060400160405280601781526020017f5072696365526567697374727920312e362e302d64657600000000000000000081525081565b6040516101da91906138bd565b6103a3610b4b565b6040516101da91906138d0565b6103c36103be36600461392a565b610b5c565b005b6103c36103d3366004613a86565b610e11565b6103eb6103e6366004613be4565b610e25565b6040516101da9190613c26565b61040b61040636600461383e565b610ef0565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6104ce610446366004613cb9565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600460209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101da9190613cd4565b6107666104e9366004613cb9565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081018290526102008101919091525067ffffffffffffffff908116600090815260086020908152604091829020825161022081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a0850152710100000000000000000000000000000000008304871660c08501527501000000000000000000000000000000000000000000808404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b010000000000000000000000000000000000000000000000000000009092048616610140840152600190930154808616610160840152640100000000810486166101808401526801000000000000000081049096166101a083015270010000000000000000000000000000000086049094166101c082015274010000000000000000000000000000000000000000850490911615156101e08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b1661020082015290565b6040516101da9190613d0f565b6103c3610781366004613f4c565b610efb565b6103c3610f11565b6103c361079c366004614266565b611013565b6108b16107af3660046142ca565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff91909116600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101da9190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6103c36109473660046142f4565b611025565b6103c361095a366004614385565b611036565b6109d861096d36600461383e565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526006825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101da565b610a1f610a1a36600461444a565b611047565b6040516101da939291906144e5565b6103c3610a3c36600461450f565b611245565b6103a361141b565b6104ce610a5736600461383e565b611427565b6101d0610a6a3660046145aa565b611523565b6103c3610a7d36600461383e565b6119dd565b6103c3610a9036600461462f565b6119ee565b610aa8610aa336600461484f565b6119ff565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101da565b6000610ae882611b8a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b0f85611b8a565b610b37907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16856148a8565b610b4191906148bf565b90505b9392505050565b6060610b576002611c24565b905090565b610b64611c31565b6000610b7082806148fa565b9050905060005b81811015610cba576000610b8b84806148fa565b83818110610b9b57610b9b614962565b905060400201803603810190610bb191906149bd565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a92610ca99290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610b77565b506000610cca60208401846148fa565b9050905060005b81811015610e0b576000610ce860208601866148fa565b83818110610cf857610cf8614962565b905060400201803603810190610d0e91906149fa565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600490975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e92610dfa9290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610cd1565b50505050565b610e19611c76565b610e2281611cf7565b50565b60608160008167ffffffffffffffff811115610e4357610e43613965565b604051908082528060200260200182016040528015610e8857816020015b6040805180820190915260008082526020820152815260200190600190039081610e615790505b50905060005b82811015610ee557610ec0868683818110610eab57610eab614962565b9050602002016020810190610a57919061383e565b828281518110610ed257610ed2614962565b6020908102919091010152600101610e8e565b509150505b92915050565b6000610eea82611b8a565b610f03611c76565b610f0d8282611df5565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61101b611c76565b610f0d8282612201565b61102d611c76565b610e2281612348565b61103e611c76565b610e22816124d4565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036110a7578592506110d5565b6110d287877f0000000000000000000000000000000000000000000000000000000000000000610add565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611174576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610f8e565b67ffffffffffffffff8816600090815260086020526040812060010154640100000000900463ffffffff16906111ab8787846125be565b9050806020015193508484611232836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b67ffffffffffffffff85166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b905b8481101561141257600084848381811061129c5761129c614962565b6112b2926020604090920201908101915061383e565b905060008787848181106112c8576112c8614962565b90506020028101906112da9190614a1d565b6112e8906040810190614a5b565b91505060208111156113985767ffffffffffffffff8916600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115611398576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610f8e565b611408848989868181106113ae576113ae614962565b90506020028101906113c09190614a1d565b6113ce906020810190614a5b565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061276792505050565b5050600101611280565b50505050505050565b6060610b57600c611c24565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600660209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff16908201529061151a57505073ffffffffffffffffffffffffffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b44816127b9565b67ffffffffffffffff8083166000908152600860209081526040808320815161022081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a0860152710100000000000000000000000000000000008404871660c08601527501000000000000000000000000000000000000000000808504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b010000000000000000000000000000000000000000000000000000009093048616610140850152600190940154808616610160850152640100000000810486166101808501526801000000000000000081049098166101a084015270010000000000000000000000000000000088049094166101c083015274010000000000000000000000000000000000000000870490931615156101e08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b16610200840152909190611759576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b600061176860408501856148fa565b91506117c490508261177d6020870187614a5b565b90508361178a8880614a5b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129fc92505050565b60006007816117d9608088016060890161383e565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff169150806118286118226080890160608a0161383e565b896119ff565b909250905060008080861561186e57611862888c61184c60808e0160608f0161383e565b888e806040019061185d91906148fa565b612aa6565b9194509250905061188e565b6101c088015161188b9063ffffffff16662386f26fc100006148a8565b92505b61010088015160009061ffff16156118d2576118cf896dffffffffffffffffffffffffffff607088901c166118c660208f018f614a5b565b90508b86612d84565b90505b6101a089015160009067ffffffffffffffff166118fb6118f560808f018f614a5b565b8d612e33565b600001518563ffffffff168c60a0015161ffff168f806020019061191f9190614a5b565b61192a9291506148a8565b8d6080015163ffffffff1661193f9190614ac0565b6119499190614ac0565b6119539190614ac0565b61196d906dffffffffffffffffffffffffffff89166148a8565b61197791906148a8565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff871682826119ae67ffffffffffffffff8c16896148a8565b6119b89190614ac0565b6119c29190614ac0565b6119cc91906148bf565b9d9c50505050505050505050505050565b6119e5611c76565b610e2281612ef4565b6119f6611c76565b610e2281612fe9565b67ffffffffffffffff811660009081526004602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203611ab7576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b6000816020015163ffffffff1642611acf9190614ad3565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115611b70576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610f8e565b611b7986611b8a565b9151919350909150505b9250929050565b600080611b9683611427565b9050806020015163ffffffff1660001480611bce575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15611c1d576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610f8e565b5192915050565b60606000610b44836134d1565b611c3c60023361352d565b611c74576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610f8e565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314611c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610f8e565b60005b8151811015610f0d576000828281518110611d1757611d17614962565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526006875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a2505050806001019050611cfa565b60005b8251811015612118576000838281518110611e1557611e15614962565b6020026020010151905060008160000151905060005b82602001515181101561210a57600083602001518281518110611e5057611e50614962565b6020026020010151602001519050600084602001518381518110611e7657611e76614962565b60200260200101516000015190506020826080015163ffffffff161015611ef35760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610f8e565b67ffffffffffffffff8416600081815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906120f8908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101611e2b565b505050806001019050611df8565b5060005b81518110156121fc57600082828151811061213957612139614962565b6020026020010151600001519050600083838151811061215b5761215b614962565b60209081029190910181015181015167ffffffffffffffff8416600081815260098452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010161211c565b505050565b60005b82518110156122a45761223a83828151811061222257612222614962565b6020026020010151600c61355c90919063ffffffff16565b1561229c5782818151811061225157612251614962565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b600101612204565b5060005b81518110156121fc576122de8282815181106122c6576122c6614962565b6020026020010151600c61357e90919063ffffffff16565b15612340578181815181106122f5576122f5614962565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6001016122a8565b602081015160005b81518110156123e357600082828151811061236d5761236d614962565b6020026020010151905061238b81600261357e90919063ffffffff16565b156123da5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612350565b50815160005b8151811015610e0b57600082828151811061240657612406614962565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612476576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61248160028261355c565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016123e9565b60005b8151811015610f0d5760008282815181106124f4576124f4614962565b6020026020010151600001519050600083838151811061251657612516614962565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526007845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a250506001016124d7565b604080518082019091526000808252602082015260008390036125ff57506040805180820190915267ffffffffffffffff8216815260006020820152610b44565b600061260b8486614ae6565b9050600061261c8560048189614b2c565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f000000000000000000000000000000000000000000000000000000000016126b957808060200190518101906126b09190614b56565b92505050610b44565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601612735576040518060400160405280828060200190518101906127219190614b82565b815260006020909101529250610b44915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610f0d576121fc816135a0565b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612823573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128479190614bb5565b5050509150506000811215612888576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000819050600085602001518473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129039190614c05565b61290d9190614c22565b905060248160ff16111561294257612926602482614c3b565b61293190600a614d74565b61293b90836148bf565b9150612965565b61294d816024614c3b565b61295890600a614d74565b61296290836148a8565b91505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8211156129bb576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff42166020820152949350505050565b836040015163ffffffff16831115612a555760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610f8e565b836020015161ffff16821115612a97576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e0b84610200015182612767565b6000808083815b81811015612d76576000878783818110612ac957612ac9614962565b905060400201803603810190612adf9190614d83565b67ffffffffffffffff8c166000908152600960209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090612c05576101208d0151612bcc9061ffff16662386f26fc100006148a8565b612bd69088614ac0565b96508c610140015186612be99190614dbc565b95508c610160015185612bfc9190614dbc565b94505050612d6e565b604081015160009061ffff1615612cbe5760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614612c61578351612c5a90611b8a565b9050612c64565b508a5b620186a0836040015161ffff16612ca68660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661365390919063ffffffff16565b612cb091906148a8565b612cba91906148bf565b9150505b6060820151612ccd9088614dbc565b9650816080015186612cdf9190614dbc565b8251909650600090612cfe9063ffffffff16662386f26fc100006148a8565b905080821015612d1d57612d12818a614ac0565b985050505050612d6e565b6000836020015163ffffffff16662386f26fc10000612d3c91906148a8565b905080831115612d5c57612d50818b614ac0565b99505050505050612d6e565b612d66838b614ac0565b995050505050505b600101612aad565b505096509650969350505050565b60008063ffffffff8316612d9960e0866148a8565b612da5876101c0614ac0565b612daf9190614ac0565b612db99190614ac0565b905060008760c0015163ffffffff168860e0015161ffff1683612ddc91906148a8565b612de69190614ac0565b61010089015190915061ffff16612e0d6dffffffffffffffffffffffffffff8916836148a8565b612e1791906148a8565b612e2790655af3107a40006148a8565b98975050505050505050565b60408051808201909152600080825260208201526000612e5f858585610180015163ffffffff166125be565b9050826060015163ffffffff1681600001511115612ea9576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101e001518015612ebd57508060200151155b15610b41576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612f73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610f8e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b8151811015610f0d57600082828151811061300957613009614962565b60200260200101519050600083838151811061302757613027614962565b60200260200101516000015190506000826020015190508167ffffffffffffffff1660001480613060575061018081015163ffffffff16155b806130b257506102008101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130c85750602081610160015163ffffffff16105b806130e75750806060015163ffffffff1681610180015163ffffffff16115b1561312a576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610f8e565b67ffffffffffffffff82166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131d2578167ffffffffffffffff167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516131c59190613d0f565b60405180910390a2613215565b8167ffffffffffffffff167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad938260405161320c9190613d0f565b60405180910390a25b80600860008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612fec565b60608160000180548060200260200160405190810160405280929190818152602001828054801561352157602002820191906000526020600020905b81548152602001906001019080831161350d575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b44565b6000610b448373ffffffffffffffffffffffffffffffffffffffff8416613690565b6000610b448373ffffffffffffffffffffffffffffffffffffffff84166136df565b600081516020146135df57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e91906138bd565b6000828060200190518101906135f59190614b82565b905073ffffffffffffffffffffffffffffffffffffffff81118061361a575061040081105b15610eea57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e91906138bd565b6000670de0b6b3a7640000613686837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166148a8565b610b4491906148bf565b60008181526001830160205260408120546136d757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610eea565b506000610eea565b600081815260018301602052604081205480156137c8576000613703600183614ad3565b855490915060009061371790600190614ad3565b905081811461377c57600086600001828154811061373757613737614962565b906000526020600020015490508087600001848154811061375a5761375a614962565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061378d5761378d614dd9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610eea565b6000915050610eea565b5092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146137fd57600080fd5b919050565b60008060006060848603121561381757600080fd5b613820846137d9565b925060208401359150613835604085016137d9565b90509250925092565b60006020828403121561385057600080fd5b610b44826137d9565b6000815180845260005b8181101561387f57602081850181015186830182015201613863565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b446020830184613859565b6020808252825182820181905260009190848201906040850190845b8181101561391e57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016138ec565b50909695505050505050565b60006020828403121561393c57600080fd5b813567ffffffffffffffff81111561395357600080fd5b820160408185031215610b4457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156139b7576139b7613965565b60405290565b60405160c0810167ffffffffffffffff811182821017156139b7576139b7613965565b604051610220810167ffffffffffffffff811182821017156139b7576139b7613965565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613a4b57613a4b613965565b604052919050565b600067ffffffffffffffff821115613a6d57613a6d613965565b5060051b60200190565b60ff81168114610e2257600080fd5b60006020808385031215613a9957600080fd5b823567ffffffffffffffff811115613ab057600080fd5b8301601f81018513613ac157600080fd5b8035613ad4613acf82613a53565b613a04565b81815260609182028301840191848201919088841115613af357600080fd5b938501935b83851015613b935784890381811215613b115760008081fd5b613b19613994565b613b22876137d9565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084011215613b565760008081fd5b613b5e613994565b9250613b6b8989016137d9565b8352870135613b7981613a77565b828901528088019190915283529384019391850191613af8565b50979650505050505050565b60008083601f840112613bb157600080fd5b50813567ffffffffffffffff811115613bc957600080fd5b6020830191508360208260051b8501011115611b8357600080fd5b60008060208385031215613bf757600080fd5b823567ffffffffffffffff811115613c0e57600080fd5b613c1a85828601613b9f565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b82811015613c9457613c8484835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101613c43565b5091979650505050505050565b803567ffffffffffffffff811681146137fd57600080fd5b600060208284031215613ccb57600080fd5b610b4482613ca1565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff169082015260408101610eea565b81511515815261022081016020830151613d2f602084018261ffff169052565b506040830151613d47604084018263ffffffff169052565b506060830151613d5f606084018263ffffffff169052565b506080830151613d77608084018263ffffffff169052565b5060a0830151613d8d60a084018261ffff169052565b5060c0830151613da560c084018263ffffffff169052565b5060e0830151613dbb60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a08085015167ffffffffffffffff16908401526101c080850151909116908301526101e080840151151590830152610200808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff811681146137fd57600080fd5b803561ffff811681146137fd57600080fd5b8015158114610e2257600080fd5b80356137fd81613e9b565b600082601f830112613ec557600080fd5b81356020613ed5613acf83613a53565b82815260069290921b84018101918181019086841115613ef457600080fd5b8286015b84811015613f415760408189031215613f115760008081fd5b613f19613994565b613f2282613ca1565b8152613f2f8583016137d9565b81860152835291830191604001613ef8565b509695505050505050565b60008060408385031215613f5f57600080fd5b67ffffffffffffffff83351115613f7557600080fd5b83601f843585010112613f8757600080fd5b613f97613acf8435850135613a53565b8335840180358083526020808401939260059290921b90910101861015613fbd57600080fd5b602085358601015b85358601803560051b016020018110156141ca5767ffffffffffffffff81351115613fef57600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a0301121561402857600080fd5b614030613994565b61403c60208301613ca1565b815267ffffffffffffffff6040830135111561405757600080fd5b88603f60408401358401011261406c57600080fd5b614082613acf6020604085013585010135613a53565b6020604084810135850182810135808552928401939260e00201018b10156140a957600080fd5b6040808501358501015b6040858101358601602081013560e00201018110156141ab5760e0818d0312156140dc57600080fd5b6140e4613994565b6140ed826137d9565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f0301121561412157600080fd5b6141296139bd565b61413560208401613e75565b815261414360408401613e75565b602082015261415460608401613e89565b604082015261416560808401613e75565b606082015261417660a08401613e75565b608082015261418860c0840135613e9b565b60c083013560a0820152602082810191909152908452929092019160e0016140b3565b5080602084015250508085525050602083019250602081019050613fc5565b5092505067ffffffffffffffff602084013511156141e757600080fd5b6141f78460208501358501613eb4565b90509250929050565b600082601f83011261421157600080fd5b81356020614221613acf83613a53565b8083825260208201915060208460051b87010193508684111561424357600080fd5b602086015b84811015613f4157614259816137d9565b8352918301918301614248565b6000806040838503121561427957600080fd5b823567ffffffffffffffff8082111561429157600080fd5b61429d86838701614200565b935060208501359150808211156142b357600080fd5b506142c085828601614200565b9150509250929050565b600080604083850312156142dd57600080fd5b6142e683613ca1565b91506141f7602084016137d9565b60006020828403121561430657600080fd5b813567ffffffffffffffff8082111561431e57600080fd5b908301906040828603121561433257600080fd5b61433a613994565b82358281111561434957600080fd5b61435587828601614200565b82525060208301358281111561436a57600080fd5b61437687828601614200565b60208301525095945050505050565b6000602080838503121561439857600080fd5b823567ffffffffffffffff8111156143af57600080fd5b8301601f810185136143c057600080fd5b80356143ce613acf82613a53565b81815260069190911b820183019083810190878311156143ed57600080fd5b928401925b8284101561443f576040848903121561440b5760008081fd5b614413613994565b61441c856137d9565b8152614429868601613ca1565b81870152825260409390930192908401906143f2565b979650505050505050565b60008060008060006080868803121561446257600080fd5b61446b86613ca1565b9450614479602087016137d9565b935060408601359250606086013567ffffffffffffffff8082111561449d57600080fd5b818801915088601f8301126144b157600080fd5b8135818111156144c057600080fd5b8960208285010111156144d257600080fd5b9699959850939650602001949392505050565b83815282151560208201526060604082015260006145066060830184613859565b95945050505050565b60008060008060006060868803121561452757600080fd5b61453086613ca1565b9450602086013567ffffffffffffffff8082111561454d57600080fd5b61455989838a01613b9f565b9096509450604088013591508082111561457257600080fd5b818801915088601f83011261458657600080fd5b81358181111561459557600080fd5b8960208260061b85010111156144d257600080fd5b600080604083850312156145bd57600080fd5b6145c683613ca1565b9150602083013567ffffffffffffffff8111156145e257600080fd5b830160a081860312156145f457600080fd5b809150509250929050565b80357fffffffff00000000000000000000000000000000000000000000000000000000811681146137fd57600080fd5b6000602080838503121561464257600080fd5b823567ffffffffffffffff81111561465957600080fd5b8301601f8101851361466a57600080fd5b8035614678613acf82613a53565b818152610240918202830184019184820191908884111561469857600080fd5b938501935b83851015613b9357848903818112156146b65760008081fd5b6146be613994565b6146c787613ca1565b8152610220807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156146fc5760008081fd5b6147046139e0565b9250614711898901613ea9565b83526040614720818a01613e89565b8a8501526060614731818b01613e75565b8286015260809150614744828b01613e75565b9085015260a06147558a8201613e75565b8286015260c09150614768828b01613e89565b9085015260e06147798a8201613e75565b82860152610100915061478d828b01613e89565b9085015261012061479f8a8201613e89565b8286015261014091506147b3828b01613e89565b908501526101606147c58a8201613e75565b8286015261018091506147d9828b01613e75565b908501526101a06147eb8a8201613e75565b828601526101c091506147ff828b01613ca1565b908501526101e06148118a8201613e75565b828601526102009150614825828b01613ea9565b908501526148348983016145ff565b9084015250808801919091528352938401939185019161469d565b6000806040838503121561486257600080fd5b61486b836137d9565b91506141f760208401613ca1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610eea57610eea614879565b6000826148f5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261492f57600080fd5b83018035915067ffffffffffffffff82111561494a57600080fd5b6020019150600681901b3603821315611b8357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146137fd57600080fd5b6000604082840312156149cf57600080fd5b6149d7613994565b6149e0836137d9565b81526149ee60208401614991565b60208201529392505050565b600060408284031215614a0c57600080fd5b614a14613994565b6149e083613ca1565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112614a5157600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614a9057600080fd5b83018035915067ffffffffffffffff821115614aab57600080fd5b602001915036819003821315611b8357600080fd5b80820180821115610eea57610eea614879565b81810381811115610eea57610eea614879565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015613e6d5760049490940360031b84901b1690921692915050565b60008085851115614b3c57600080fd5b83861115614b4957600080fd5b5050820193919092039150565b600060408284031215614b6857600080fd5b614b70613994565b8251815260208301516149ee81613e9b565b600060208284031215614b9457600080fd5b5051919050565b805169ffffffffffffffffffff811681146137fd57600080fd5b600080600080600060a08688031215614bcd57600080fd5b614bd686614b9b565b9450602086015193506040860151925060608601519150614bf960808701614b9b565b90509295509295909350565b600060208284031215614c1757600080fd5b8151610b4481613a77565b60ff8181168382160190811115610eea57610eea614879565b60ff8281168282160390811115610eea57610eea614879565b600181815b80851115614cad57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614c9357614c93614879565b80851615614ca057918102915b93841c9390800290614c59565b509250929050565b600082614cc457506001610eea565b81614cd157506000610eea565b8160018114614ce75760028114614cf157614d0d565b6001915050610eea565b60ff841115614d0257614d02614879565b50506001821b610eea565b5060208310610133831016604e8410600b8410161715614d30575081810a610eea565b614d3a8383614c54565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614d6c57614d6c614879565b029392505050565b6000610b4460ff841683614cb5565b600060408284031215614d9557600080fd5b614d9d613994565b614da6836137d9565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156137d2576137d2614879565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b506040516200695038038062006950833981016040819052620000349162001816565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a9f565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b6b565b5050505050505062001ad4565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001935565b60209081029190910101519050620002f560028262000ea4565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001935565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000ec4565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001935565b6020026020010151600c62000ec460201b90919060201c565b1562000499578281815181106200045b576200045b62001935565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001935565b6020026020010151600c62000ea460201b90919060201c565b156200053b57818181518110620004fd57620004fd62001935565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001935565b6020908102919091018101518051818301516001600160a01b0380831660008181526006875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001935565b6020026020010151905060008383815181106200065f576200065f62001935565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061018081015163ffffffff16155b80620006ba57506102008101516001600160e01b031916630a04b54b60e21b14155b80620006d75750602063ffffffff1681610160015163ffffffff16105b80620006f75750806060015163ffffffff1681610180015163ffffffff16115b15620007225760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260086020526040812060010154600160a81b900460e01b6001600160e01b0319169003620007a257816001600160401b03167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516200079491906200194b565b60405180910390a2620007e6565b816001600160401b03167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad9382604051620007dd91906200194b565b60405180910390a25b8060086000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a8154816001600160401b0302191690836001600160401b031602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000ac35762000ac362001935565b6020026020010151600001519050600083838151811062000ae85762000ae862001935565b6020908102919091018101518101516001600160a01b03841660008181526007845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000aa2565b60005b825181101562000dde57600083828151811062000b8f5762000b8f62001935565b6020026020010151905060008160000151905060005b82602001515181101562000dcf5760008360200151828151811062000bce5762000bce62001935565b602002602001015160200151905060008460200151838151811062000bf75762000bf762001935565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c565760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b03841660008181526009602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000dbc908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000ba5565b50505080600101905062000b6e565b5060005b81518110156200054457600082828151811062000e035762000e0362001935565b6020026020010151600001519050600083838151811062000e285762000e2862001935565b6020908102919091018101518101516001600160401b03841660008181526009845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000de2565b600062000ebb836001600160a01b03841662000edb565b90505b92915050565b600062000ebb836001600160a01b03841662000fdf565b6000818152600183016020526040812054801562000fd457600062000f0260018362001a9c565b855490915060009062000f189060019062001a9c565b905081811462000f8457600086600001828154811062000f3c5762000f3c62001935565b906000526020600020015490508087600001848154811062000f625762000f6262001935565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f985762000f9862001abe565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000ebe565b600091505062000ebe565b6000818152600183016020526040812054620010285750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000ebe565b50600062000ebe565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200106c576200106c62001031565b60405290565b60405160c081016001600160401b03811182821017156200106c576200106c62001031565b60405161022081016001600160401b03811182821017156200106c576200106c62001031565b604051601f8201601f191681016001600160401b0381118282101715620010e857620010e862001031565b604052919050565b80516001600160a01b03811681146200110857600080fd5b919050565b805163ffffffff811681146200110857600080fd5b6000606082840312156200113557600080fd5b604051606081016001600160401b03811182821017156200115a576200115a62001031565b604052825190915081906001600160601b03811681146200117a57600080fd5b81526200118a60208401620010f0565b60208201526200119d604084016200110d565b60408201525092915050565b60006001600160401b03821115620011c557620011c562001031565b5060051b60200190565b600082601f830112620011e157600080fd5b81516020620011fa620011f483620011a9565b620010bd565b8083825260208201915060208460051b8701019350868411156200121d57600080fd5b602086015b8481101562001244576200123681620010f0565b835291830191830162001222565b509695505050505050565b600082601f8301126200126157600080fd5b8151602062001274620011f483620011a9565b828152606092830285018201928282019190878511156200129457600080fd5b8387015b85811015620013275780890382811215620012b35760008081fd5b620012bd62001047565b620012c883620010f0565b8152604080601f1984011215620012df5760008081fd5b620012e962001047565b9250620012f8888501620010f0565b835283015160ff811681146200130e5760008081fd5b8288015280870191909152845292840192810162001298565b5090979650505050505050565b80516001600160401b03811681146200110857600080fd5b805161ffff811681146200110857600080fd5b805180151581146200110857600080fd5b600082601f8301126200138257600080fd5b8151602062001395620011f483620011a9565b82815260059290921b84018101918181019086841115620013b557600080fd5b8286015b84811015620012445780516001600160401b0380821115620013da57600080fd5b908801906040601f19838c038101821315620013f557600080fd5b620013ff62001047565b6200140c89860162001334565b815282850151848111156200142057600080fd5b8086019550508c603f8601126200143657600080fd5b8885015193506200144b620011f485620011a9565b84815260e09094028501830193898101908e8611156200146a57600080fd5b958401955b858710156200154357868f0360e08112156200148a57600080fd5b6200149462001047565b6200149f89620010f0565b815260c08683011215620014b257600080fd5b620014bc62001072565b9150620014cb8d8a016200110d565b8252620014da878a016200110d565b8d830152620014ec60608a016200134c565b87830152620014fe60808a016200110d565b60608301526200151160a08a016200110d565b60808301526200152460c08a016200135f565b60a0830152808d0191909152825260e09690960195908a01906200146f565b828b015250875250505092840192508301620013b9565b600082601f8301126200156c57600080fd5b815160206200157f620011f483620011a9565b82815260069290921b840181019181810190868411156200159f57600080fd5b8286015b84811015620012445760408189031215620015be5760008081fd5b620015c862001047565b620015d382620010f0565b8152620015e285830162001334565b81860152835291830191604001620015a3565b80516001600160e01b0319811681146200110857600080fd5b600082601f8301126200162057600080fd5b8151602062001633620011f483620011a9565b82815261024092830285018201928282019190878511156200165457600080fd5b8387015b85811015620013275780890382811215620016735760008081fd5b6200167d62001047565b620016888362001334565b815261022080601f1984011215620016a05760008081fd5b620016aa62001097565b9250620016b98885016200135f565b83526040620016ca8186016200134c565b898501526060620016dd8187016200110d565b8286015260809150620016f28287016200110d565b9085015260a0620017058682016200110d565b8286015260c091506200171a8287016200134c565b9085015260e06200172d8682016200110d565b828601526101009150620017438287016200134c565b90850152610120620017578682016200134c565b8286015261014091506200176d8287016200134c565b90850152610160620017818682016200110d565b828601526101809150620017978287016200110d565b908501526101a0620017ab8682016200110d565b828601526101c09150620017c182870162001334565b908501526101e0620017d58682016200110d565b828601526102009150620017eb8287016200135f565b90850152620017fc858301620015f5565b908401525080870191909152845292840192810162001658565b6000806000806000806000610120888a0312156200183357600080fd5b6200183f898962001122565b60608901519097506001600160401b03808211156200185d57600080fd5b6200186b8b838c01620011cf565b975060808a01519150808211156200188257600080fd5b620018908b838c01620011cf565b965060a08a0151915080821115620018a757600080fd5b620018b58b838c016200124f565b955060c08a0151915080821115620018cc57600080fd5b620018da8b838c0162001370565b945060e08a0151915080821115620018f157600080fd5b620018ff8b838c016200155a565b93506101008a01519150808211156200191757600080fd5b50620019268a828b016200160e565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610220810160208301516200196c602084018261ffff169052565b50604083015162001985604084018263ffffffff169052565b5060608301516200199e606084018263ffffffff169052565b506080830151620019b7608084018263ffffffff169052565b5060a0830151620019ce60a084018261ffff169052565b5060c0830151620019e760c084018263ffffffff169052565b5060e0830151620019fe60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a0808501516001600160401b0316908401526101c080850151909116908301526101e080840151151590830152610200928301516001600160e01b031916929091019190915290565b8181038181111562000ebe57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051614e2262001b2e600039600081816102d901528181611ad30152611b3c01526000818161029d0152818161104e01526110ae015260008181610269015281816110d701526111470152614e226000f3fe608060405234801561001057600080fd5b50600436106101b85760003560e01c80637afac322116100f9578063cc88924c11610097578063d8694ccd11610071578063d8694ccd14610a5c578063f2fde38b14610a6f578063f700042a14610a82578063ffdb4b3714610a9557600080fd5b8063cc88924c14610a2e578063cdc73d5114610a41578063d02641a014610a4957600080fd5b806391a2749a116100d357806391a2749a14610939578063a69c64c01461094c578063bf78e03f1461095f578063c4276bfc14610a0c57600080fd5b80637afac3221461078e57806382b49eb0146107a15780638da5cb5b1461091157600080fd5b8063407e108611610166578063514e8cff11610140578063514e8cff146104385780636def4ce7146104db578063770e2dc41461077357806379ba50971461078657600080fd5b8063407e1086146103c557806345ac924d146103d85780634ab35b0b146103f857600080fd5b8063181f5a7711610197578063181f5a77146103525780632451a6271461039b5780633937306f146103b057600080fd5b806241e5be146101bd578063061877e3146101e357806306285c691461023c575b600080fd5b6101d06101cb36600461380f565b610add565b6040519081526020015b60405180910390f35b6102236101f136600461384b565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101da565b610306604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101da565b61038e6040518060400160405280601781526020017f5072696365526567697374727920312e362e302d64657600000000000000000081525081565b6040516101da91906138ca565b6103a3610b4b565b6040516101da91906138dd565b6103c36103be366004613937565b610b5c565b005b6103c36103d3366004613a93565b610e11565b6103eb6103e6366004613bf1565b610e25565b6040516101da9190613c33565b61040b61040636600461384b565b610ef0565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6104ce610446366004613cc6565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600460209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101da9190613ce1565b6107666104e9366004613cc6565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081018290526102008101919091525067ffffffffffffffff908116600090815260086020908152604091829020825161022081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a0850152710100000000000000000000000000000000008304871660c08501527501000000000000000000000000000000000000000000808404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b010000000000000000000000000000000000000000000000000000009092048616610140840152600190930154808616610160840152640100000000810486166101808401526801000000000000000081049096166101a083015270010000000000000000000000000000000086049094166101c082015274010000000000000000000000000000000000000000850490911615156101e08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b1661020082015290565b6040516101da9190613d1c565b6103c3610781366004613f59565b610efb565b6103c3610f11565b6103c361079c366004614273565b611013565b6108b16107af3660046142d7565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff91909116600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101da9190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6103c3610947366004614301565b611025565b6103c361095a366004614392565b611036565b6109d861096d36600461384b565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526006825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101da565b610a1f610a1a366004614457565b611047565b6040516101da939291906144f2565b6103c3610a3c36600461451c565b611245565b6103a361141b565b6104ce610a5736600461384b565b611427565b6101d0610a6a3660046145b7565b611523565b6103c3610a7d36600461384b565b6119dd565b6103c3610a9036600461463c565b6119ee565b610aa8610aa336600461485c565b6119ff565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101da565b6000610ae882611b8a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b0f85611b8a565b610b37907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16856148b5565b610b4191906148cc565b90505b9392505050565b6060610b576002611c24565b905090565b610b64611c31565b6000610b708280614907565b9050905060005b81811015610cba576000610b8b8480614907565b83818110610b9b57610b9b61496f565b905060400201803603810190610bb191906149ca565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a92610ca99290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610b77565b506000610cca6020840184614907565b9050905060005b81811015610e0b576000610ce86020860186614907565b83818110610cf857610cf861496f565b905060400201803603810190610d0e9190614a07565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600490975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e92610dfa9290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610cd1565b50505050565b610e19611c76565b610e2281611cf7565b50565b60608160008167ffffffffffffffff811115610e4357610e43613972565b604051908082528060200260200182016040528015610e8857816020015b6040805180820190915260008082526020820152815260200190600190039081610e615790505b50905060005b82811015610ee557610ec0868683818110610eab57610eab61496f565b9050602002016020810190610a57919061384b565b828281518110610ed257610ed261496f565b6020908102919091010152600101610e8e565b509150505b92915050565b6000610eea82611b8a565b610f03611c76565b610f0d8282611df5565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61101b611c76565b610f0d8282612207565b61102d611c76565b610e228161234e565b61103e611c76565b610e22816124da565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036110a7578592506110d5565b6110d287877f0000000000000000000000000000000000000000000000000000000000000000610add565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611174576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610f8e565b67ffffffffffffffff8816600090815260086020526040812060010154640100000000900463ffffffff16906111ab8787846125c4565b9050806020015193508484611232836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b67ffffffffffffffff85166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b905b8481101561141257600084848381811061129c5761129c61496f565b6112b2926020604090920201908101915061384b565b905060008787848181106112c8576112c861496f565b90506020028101906112da9190614a2a565b6112e8906040810190614a68565b91505060208111156113985767ffffffffffffffff8916600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115611398576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610f8e565b611408848989868181106113ae576113ae61496f565b90506020028101906113c09190614a2a565b6113ce906020810190614a68565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061276d92505050565b5050600101611280565b50505050505050565b6060610b57600c611c24565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600660209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff16908201529061151a57505073ffffffffffffffffffffffffffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b44816127bf565b67ffffffffffffffff8083166000908152600860209081526040808320815161022081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a0860152710100000000000000000000000000000000008404871660c08601527501000000000000000000000000000000000000000000808504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b010000000000000000000000000000000000000000000000000000009093048616610140850152600190940154808616610160850152640100000000810486166101808501526801000000000000000081049098166101a084015270010000000000000000000000000000000088049094166101c083015274010000000000000000000000000000000000000000870490931615156101e08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b16610200840152909190611759576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b60006117686040850185614907565b91506117c490508261177d6020870187614a68565b90508361178a8880614a68565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a0292505050565b60006007816117d9608088016060890161384b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff169150806118286118226080890160608a0161384b565b896119ff565b909250905060008080861561186e57611862888c61184c60808e0160608f0161384b565b888e806040019061185d9190614907565b612aac565b9194509250905061188e565b6101c088015161188b9063ffffffff16662386f26fc100006148b5565b92505b61010088015160009061ffff16156118d2576118cf896dffffffffffffffffffffffffffff607088901c166118c660208f018f614a68565b90508b86612d8a565b90505b6101a089015160009067ffffffffffffffff166118fb6118f560808f018f614a68565b8d612e3a565b600001518563ffffffff168c60a0015161ffff168f806020019061191f9190614a68565b61192a9291506148b5565b8d6080015163ffffffff1661193f9190614acd565b6119499190614acd565b6119539190614acd565b61196d906dffffffffffffffffffffffffffff89166148b5565b61197791906148b5565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff871682826119ae67ffffffffffffffff8c16896148b5565b6119b89190614acd565b6119c29190614acd565b6119cc91906148cc565b9d9c50505050505050505050505050565b6119e5611c76565b610e2281612efb565b6119f6611c76565b610e2281612ff0565b67ffffffffffffffff811660009081526004602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203611ab7576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b6000816020015163ffffffff1642611acf9190614ae0565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115611b70576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610f8e565b611b7986611b8a565b9151919350909150505b9250929050565b600080611b9683611427565b9050806020015163ffffffff1660001480611bce575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15611c1d576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610f8e565b5192915050565b60606000610b44836134de565b611c3c60023361353a565b611c74576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610f8e565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314611c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610f8e565b60005b8151811015610f0d576000828281518110611d1757611d1761496f565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526006875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a2505050806001019050611cfa565b60005b825181101561211e576000838281518110611e1557611e1561496f565b6020026020010151905060008160000151905060005b82602001515181101561211057600083602001518281518110611e5057611e5061496f565b6020026020010151602001519050600084602001518381518110611e7657611e7661496f565b6020026020010151600001519050602063ffffffff16826080015163ffffffff161015611ef95760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610f8e565b67ffffffffffffffff8416600081815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906120fe908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101611e2b565b505050806001019050611df8565b5060005b815181101561220257600082828151811061213f5761213f61496f565b602002602001015160000151905060008383815181106121615761216161496f565b60209081029190910181015181015167ffffffffffffffff8416600081815260098452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612122565b505050565b60005b82518110156122aa576122408382815181106122285761222861496f565b6020026020010151600c61356990919063ffffffff16565b156122a2578281815181106122575761225761496f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010161220a565b5060005b8151811015612202576122e48282815181106122cc576122cc61496f565b6020026020010151600c61358b90919063ffffffff16565b15612346578181815181106122fb576122fb61496f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6001016122ae565b602081015160005b81518110156123e95760008282815181106123735761237361496f565b6020026020010151905061239181600261358b90919063ffffffff16565b156123e05760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612356565b50815160005b8151811015610e0b57600082828151811061240c5761240c61496f565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361247c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612487600282613569565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016123ef565b60005b8151811015610f0d5760008282815181106124fa576124fa61496f565b6020026020010151600001519050600083838151811061251c5761251c61496f565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526007845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a250506001016124dd565b6040805180820190915260008082526020820152600083900361260557506040805180820190915267ffffffffffffffff8216815260006020820152610b44565b60006126118486614af3565b905060006126228560048189614b39565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f000000000000000000000000000000000000000000000000000000000016126bf57808060200190518101906126b69190614b63565b92505050610b44565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161273b576040518060400160405280828060200190518101906127279190614b8f565b815260006020909101529250610b44915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610f0d57612202816135ad565b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284d9190614bc2565b505050915050600081121561288e576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000819050600085602001518473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129099190614c12565b6129139190614c2f565b905060248160ff1611156129485761292c602482614c48565b61293790600a614d81565b61294190836148cc565b915061296b565b612953816024614c48565b61295e90600a614d81565b61296890836148b5565b91505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8211156129c1576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff42166020820152949350505050565b836040015163ffffffff16831115612a5b5760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610f8e565b836020015161ffff16821115612a9d576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e0b8461020001518261276d565b6000808083815b81811015612d7c576000878783818110612acf57612acf61496f565b905060400201803603810190612ae59190614d90565b67ffffffffffffffff8c166000908152600960209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090612c0b576101208d0151612bd29061ffff16662386f26fc100006148b5565b612bdc9088614acd565b96508c610140015186612bef9190614dc9565b95508c610160015185612c029190614dc9565b94505050612d74565b604081015160009061ffff1615612cc45760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614612c67578351612c6090611b8a565b9050612c6a565b508a5b620186a0836040015161ffff16612cac8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661366090919063ffffffff16565b612cb691906148b5565b612cc091906148cc565b9150505b6060820151612cd39088614dc9565b9650816080015186612ce59190614dc9565b8251909650600090612d049063ffffffff16662386f26fc100006148b5565b905080821015612d2357612d18818a614acd565b985050505050612d74565b6000836020015163ffffffff16662386f26fc10000612d4291906148b5565b905080831115612d6257612d56818b614acd565b99505050505050612d74565b612d6c838b614acd565b995050505050505b600101612ab3565b505096509650969350505050565b60008063ffffffff8316612da0610140866148b5565b612dac876101c0614acd565b612db69190614acd565b612dc09190614acd565b905060008760c0015163ffffffff168860e0015161ffff1683612de391906148b5565b612ded9190614acd565b61010089015190915061ffff16612e146dffffffffffffffffffffffffffff8916836148b5565b612e1e91906148b5565b612e2e90655af3107a40006148b5565b98975050505050505050565b60408051808201909152600080825260208201526000612e66858585610180015163ffffffff166125c4565b9050826060015163ffffffff1681600001511115612eb0576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101e001518015612ec457508060200151155b15610b41576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610f8e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b8151811015610f0d5760008282815181106130105761301061496f565b60200260200101519050600083838151811061302e5761302e61496f565b60200260200101516000015190506000826020015190508167ffffffffffffffff1660001480613067575061018081015163ffffffff16155b806130b957506102008101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130d55750602063ffffffff1681610160015163ffffffff16105b806130f45750806060015163ffffffff1681610180015163ffffffff16115b15613137576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610f8e565b67ffffffffffffffff82166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131df578167ffffffffffffffff167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516131d29190613d1c565b60405180910390a2613222565b8167ffffffffffffffff167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad93826040516132199190613d1c565b60405180910390a25b80600860008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612ff3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561352e57602002820191906000526020600020905b81548152602001906001019080831161351a575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b44565b6000610b448373ffffffffffffffffffffffffffffffffffffffff841661369d565b6000610b448373ffffffffffffffffffffffffffffffffffffffff84166136ec565b600081516020146135ec57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e91906138ca565b6000828060200190518101906136029190614b8f565b905073ffffffffffffffffffffffffffffffffffffffff811180613627575061040081105b15610eea57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e91906138ca565b6000670de0b6b3a7640000613693837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166148b5565b610b4491906148cc565b60008181526001830160205260408120546136e457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610eea565b506000610eea565b600081815260018301602052604081205480156137d5576000613710600183614ae0565b855490915060009061372490600190614ae0565b90508181146137895760008660000182815481106137445761374461496f565b90600052602060002001549050808760000184815481106137675761376761496f565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061379a5761379a614de6565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610eea565b6000915050610eea565b5092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461380a57600080fd5b919050565b60008060006060848603121561382457600080fd5b61382d846137e6565b925060208401359150613842604085016137e6565b90509250925092565b60006020828403121561385d57600080fd5b610b44826137e6565b6000815180845260005b8181101561388c57602081850181015186830182015201613870565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b446020830184613866565b6020808252825182820181905260009190848201906040850190845b8181101561392b57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016138f9565b50909695505050505050565b60006020828403121561394957600080fd5b813567ffffffffffffffff81111561396057600080fd5b820160408185031215610b4457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156139c4576139c4613972565b60405290565b60405160c0810167ffffffffffffffff811182821017156139c4576139c4613972565b604051610220810167ffffffffffffffff811182821017156139c4576139c4613972565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613a5857613a58613972565b604052919050565b600067ffffffffffffffff821115613a7a57613a7a613972565b5060051b60200190565b60ff81168114610e2257600080fd5b60006020808385031215613aa657600080fd5b823567ffffffffffffffff811115613abd57600080fd5b8301601f81018513613ace57600080fd5b8035613ae1613adc82613a60565b613a11565b81815260609182028301840191848201919088841115613b0057600080fd5b938501935b83851015613ba05784890381811215613b1e5760008081fd5b613b266139a1565b613b2f876137e6565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084011215613b635760008081fd5b613b6b6139a1565b9250613b788989016137e6565b8352870135613b8681613a84565b828901528088019190915283529384019391850191613b05565b50979650505050505050565b60008083601f840112613bbe57600080fd5b50813567ffffffffffffffff811115613bd657600080fd5b6020830191508360208260051b8501011115611b8357600080fd5b60008060208385031215613c0457600080fd5b823567ffffffffffffffff811115613c1b57600080fd5b613c2785828601613bac565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b82811015613ca157613c9184835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101613c50565b5091979650505050505050565b803567ffffffffffffffff8116811461380a57600080fd5b600060208284031215613cd857600080fd5b610b4482613cae565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff169082015260408101610eea565b81511515815261022081016020830151613d3c602084018261ffff169052565b506040830151613d54604084018263ffffffff169052565b506060830151613d6c606084018263ffffffff169052565b506080830151613d84608084018263ffffffff169052565b5060a0830151613d9a60a084018261ffff169052565b5060c0830151613db260c084018263ffffffff169052565b5060e0830151613dc860e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a08085015167ffffffffffffffff16908401526101c080850151909116908301526101e080840151151590830152610200808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461380a57600080fd5b803561ffff8116811461380a57600080fd5b8015158114610e2257600080fd5b803561380a81613ea8565b600082601f830112613ed257600080fd5b81356020613ee2613adc83613a60565b82815260069290921b84018101918181019086841115613f0157600080fd5b8286015b84811015613f4e5760408189031215613f1e5760008081fd5b613f266139a1565b613f2f82613cae565b8152613f3c8583016137e6565b81860152835291830191604001613f05565b509695505050505050565b60008060408385031215613f6c57600080fd5b67ffffffffffffffff83351115613f8257600080fd5b83601f843585010112613f9457600080fd5b613fa4613adc8435850135613a60565b8335840180358083526020808401939260059290921b90910101861015613fca57600080fd5b602085358601015b85358601803560051b016020018110156141d75767ffffffffffffffff81351115613ffc57600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a0301121561403557600080fd5b61403d6139a1565b61404960208301613cae565b815267ffffffffffffffff6040830135111561406457600080fd5b88603f60408401358401011261407957600080fd5b61408f613adc6020604085013585010135613a60565b6020604084810135850182810135808552928401939260e00201018b10156140b657600080fd5b6040808501358501015b6040858101358601602081013560e00201018110156141b85760e0818d0312156140e957600080fd5b6140f16139a1565b6140fa826137e6565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f0301121561412e57600080fd5b6141366139ca565b61414260208401613e82565b815261415060408401613e82565b602082015261416160608401613e96565b604082015261417260808401613e82565b606082015261418360a08401613e82565b608082015261419560c0840135613ea8565b60c083013560a0820152602082810191909152908452929092019160e0016140c0565b5080602084015250508085525050602083019250602081019050613fd2565b5092505067ffffffffffffffff602084013511156141f457600080fd5b6142048460208501358501613ec1565b90509250929050565b600082601f83011261421e57600080fd5b8135602061422e613adc83613a60565b8083825260208201915060208460051b87010193508684111561425057600080fd5b602086015b84811015613f4e57614266816137e6565b8352918301918301614255565b6000806040838503121561428657600080fd5b823567ffffffffffffffff8082111561429e57600080fd5b6142aa8683870161420d565b935060208501359150808211156142c057600080fd5b506142cd8582860161420d565b9150509250929050565b600080604083850312156142ea57600080fd5b6142f383613cae565b9150614204602084016137e6565b60006020828403121561431357600080fd5b813567ffffffffffffffff8082111561432b57600080fd5b908301906040828603121561433f57600080fd5b6143476139a1565b82358281111561435657600080fd5b6143628782860161420d565b82525060208301358281111561437757600080fd5b6143838782860161420d565b60208301525095945050505050565b600060208083850312156143a557600080fd5b823567ffffffffffffffff8111156143bc57600080fd5b8301601f810185136143cd57600080fd5b80356143db613adc82613a60565b81815260069190911b820183019083810190878311156143fa57600080fd5b928401925b8284101561444c57604084890312156144185760008081fd5b6144206139a1565b614429856137e6565b8152614436868601613cae565b81870152825260409390930192908401906143ff565b979650505050505050565b60008060008060006080868803121561446f57600080fd5b61447886613cae565b9450614486602087016137e6565b935060408601359250606086013567ffffffffffffffff808211156144aa57600080fd5b818801915088601f8301126144be57600080fd5b8135818111156144cd57600080fd5b8960208285010111156144df57600080fd5b9699959850939650602001949392505050565b83815282151560208201526060604082015260006145136060830184613866565b95945050505050565b60008060008060006060868803121561453457600080fd5b61453d86613cae565b9450602086013567ffffffffffffffff8082111561455a57600080fd5b61456689838a01613bac565b9096509450604088013591508082111561457f57600080fd5b818801915088601f83011261459357600080fd5b8135818111156145a257600080fd5b8960208260061b85010111156144df57600080fd5b600080604083850312156145ca57600080fd5b6145d383613cae565b9150602083013567ffffffffffffffff8111156145ef57600080fd5b830160a0818603121561460157600080fd5b809150509250929050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461380a57600080fd5b6000602080838503121561464f57600080fd5b823567ffffffffffffffff81111561466657600080fd5b8301601f8101851361467757600080fd5b8035614685613adc82613a60565b81815261024091820283018401918482019190888411156146a557600080fd5b938501935b83851015613ba057848903818112156146c35760008081fd5b6146cb6139a1565b6146d487613cae565b8152610220807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147095760008081fd5b6147116139ed565b925061471e898901613eb6565b8352604061472d818a01613e96565b8a850152606061473e818b01613e82565b8286015260809150614751828b01613e82565b9085015260a06147628a8201613e82565b8286015260c09150614775828b01613e96565b9085015260e06147868a8201613e82565b82860152610100915061479a828b01613e96565b908501526101206147ac8a8201613e96565b8286015261014091506147c0828b01613e96565b908501526101606147d28a8201613e82565b8286015261018091506147e6828b01613e82565b908501526101a06147f88a8201613e82565b828601526101c0915061480c828b01613cae565b908501526101e061481e8a8201613e82565b828601526102009150614832828b01613eb6565b9085015261484189830161460c565b908401525080880191909152835293840193918501916146aa565b6000806040838503121561486f57600080fd5b614878836137e6565b915061420460208401613cae565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610eea57610eea614886565b600082614902577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261493c57600080fd5b83018035915067ffffffffffffffff82111561495757600080fd5b6020019150600681901b3603821315611b8357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461380a57600080fd5b6000604082840312156149dc57600080fd5b6149e46139a1565b6149ed836137e6565b81526149fb6020840161499e565b60208201529392505050565b600060408284031215614a1957600080fd5b614a216139a1565b6149ed83613cae565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112614a5e57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614a9d57600080fd5b83018035915067ffffffffffffffff821115614ab857600080fd5b602001915036819003821315611b8357600080fd5b80820180821115610eea57610eea614886565b81810381811115610eea57610eea614886565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015613e7a5760049490940360031b84901b1690921692915050565b60008085851115614b4957600080fd5b83861115614b5657600080fd5b5050820193919092039150565b600060408284031215614b7557600080fd5b614b7d6139a1565b8251815260208301516149fb81613ea8565b600060208284031215614ba157600080fd5b5051919050565b805169ffffffffffffffffffff8116811461380a57600080fd5b600080600080600060a08688031215614bda57600080fd5b614be386614ba8565b9450602086015193506040860151925060608601519150614c0660808701614ba8565b90509295509295909350565b600060208284031215614c2457600080fd5b8151610b4481613a84565b60ff8181168382160190811115610eea57610eea614886565b60ff8281168282160390811115610eea57610eea614886565b600181815b80851115614cba57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614ca057614ca0614886565b80851615614cad57918102915b93841c9390800290614c66565b509250929050565b600082614cd157506001610eea565b81614cde57506000610eea565b8160018114614cf45760028114614cfe57614d1a565b6001915050610eea565b60ff841115614d0f57614d0f614886565b50506001821b610eea565b5060208310610133831016604e8410600b8410161715614d3d575081810a610eea565b614d478383614c61565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614d7957614d79614886565b029392505050565b6000610b4460ff841683614cc2565b600060408284031215614da257600080fd5b614daa6139a1565b614db3836137e6565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156137df576137df614886565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var PriceRegistryABI = PriceRegistryMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/token_pool/token_pool.go b/core/gethwrappers/ccip/generated/token_pool/token_pool.go index 0fb4c4e087..0bca23641c 100644 --- a/core/gethwrappers/ccip/generated/token_pool/token_pool.go +++ b/core/gethwrappers/ccip/generated/token_pool/token_pool.go @@ -82,7 +82,7 @@ type TokenPoolChainUpdate struct { } var TokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"lockOrBurnOut\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"lockOrBurnOut\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } var TokenPoolABI = TokenPoolMetaData.ABI @@ -291,6 +291,28 @@ func (_TokenPool *TokenPoolCallerSession) GetCurrentOutboundRateLimiterState(rem return _TokenPool.Contract.GetCurrentOutboundRateLimiterState(&_TokenPool.CallOpts, remoteChainSelector) } +func (_TokenPool *TokenPoolCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getRateLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetRateLimitAdmin() (common.Address, error) { + return _TokenPool.Contract.GetRateLimitAdmin(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetRateLimitAdmin() (common.Address, error) { + return _TokenPool.Contract.GetRateLimitAdmin(&_TokenPool.CallOpts) +} + func (_TokenPool *TokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { var out []interface{} err := _TokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) @@ -583,6 +605,18 @@ func (_TokenPool *TokenPoolTransactorSession) SetChainRateLimiterConfig(remoteCh return _TokenPool.Contract.SetChainRateLimiterConfig(&_TokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_TokenPool *TokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) +} + +func (_TokenPool *TokenPoolSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.SetRateLimitAdmin(&_TokenPool.TransactOpts, rateLimitAdmin) +} + +func (_TokenPool *TokenPoolTransactorSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _TokenPool.Contract.SetRateLimitAdmin(&_TokenPool.TransactOpts, rateLimitAdmin) +} + func (_TokenPool *TokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { return _TokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) } @@ -2480,6 +2514,8 @@ type TokenPoolInterface interface { GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) @@ -2512,6 +2548,8 @@ type TokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go index 1e15b6b6cd..a4e4f9de70 100644 --- a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go +++ b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go @@ -95,8 +95,8 @@ type USDCTokenPoolDomainUpdate struct { } var USDCTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b506040516200559338038062005593833981016040819052620000359162000b4c565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200041b565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016957604080516000815260208101909152620001699084620004c6565b5050506001600160a01b038616905062000196576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fd919062000c72565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000240573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000266919062000c99565b905063ffffffff81161562000297576040516334697c6b60e11b815263ffffffff8216600482015260240162000087565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fe919062000c99565b905063ffffffff8116156200032f576040516316ba39c560e31b815263ffffffff8216600482015260240162000087565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa15801562000381573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a7919062000c99565b63ffffffff166101205260e051608051620003d1916001600160a01b039091169060001962000623565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000de6565b336001600160a01b03821603620004755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620004e7576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005725760008382815181106200050b576200050b62000cc1565b602090810291909101015190506200052560028262000709565b1562000568576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620004ea565b5060005b81518110156200061e57600082828151811062000597576200059762000cc1565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005c3575062000615565b620005d060028262000729565b1562000613576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000576565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200069b919062000cd7565b620006a7919062000d07565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000703918691906200074016565b50505050565b600062000720836001600160a01b03841662000811565b90505b92915050565b600062000720836001600160a01b03841662000915565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200078f906001600160a01b03851690849062000967565b8051909150156200061e5780806020019051810190620007b0919062000d1d565b6200061e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000087565b600081815260018301602052604081205480156200090a5760006200083860018362000d41565b85549091506000906200084e9060019062000d41565b9050818114620008ba57600086600001828154811062000872576200087262000cc1565b906000526020600020015490508087600001848154811062000898576200089862000cc1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620008ce57620008ce62000d57565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000723565b600091505062000723565b60008181526001830160205260408120546200095e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000723565b50600062000723565b606062000978848460008562000980565b949350505050565b606082471015620009e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000087565b600080866001600160a01b0316858760405162000a01919062000d93565b60006040518083038185875af1925050503d806000811462000a40576040519150601f19603f3d011682016040523d82523d6000602084013e62000a45565b606091505b50909250905062000a598783838762000a64565b979650505050505050565b6060831562000ad857825160000362000ad0576001600160a01b0385163b62000ad05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000087565b508162000978565b62000978838381511562000aef5781518083602001fd5b8060405162461bcd60e51b815260040162000087919062000db1565b6001600160a01b038116811462000b2157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b478162000b0b565b919050565b600080600080600060a0868803121562000b6557600080fd5b855162000b728162000b0b565b8095505060208087015162000b878162000b0b565b60408801519095506001600160401b038082111562000ba557600080fd5b818901915089601f83011262000bba57600080fd5b81518181111562000bcf5762000bcf62000b24565b8060051b604051601f19603f8301168101818110858211171562000bf75762000bf762000b24565b60405291825284820192508381018501918c83111562000c1657600080fd5b938501935b8285101562000c3f5762000c2f8562000b3a565b8452938501939285019262000c1b565b80985050505050505062000c566060870162000b3a565b915062000c666080870162000b3a565b90509295509295909350565b60006020828403121562000c8557600080fd5b815162000c928162000b0b565b9392505050565b60006020828403121562000cac57600080fd5b815163ffffffff8116811462000c9257600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000cea57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000723576200072362000cf1565b60006020828403121562000d3057600080fd5b8151801515811462000c9257600080fd5b8181038181111562000723576200072362000cf1565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d8a57818101518382015260200162000d70565b50506000910152565b6000825162000da781846020870162000d6d565b9190910192915050565b602081526000825180602084015262000dd281604085016020870162000d6d565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516146ed62000ea66000396000818161036c0152818161116601528181611d6d0152611dcb01526000818161062f0152610a31015260008181610345015261107a0152600081816105f301528181611ef5015261293c01526000818161052f01528181611b6b01526121ab015260008181610279015281816102ce01528181610af70152818161104701528181611a8b015281816120cb015281816127c60152612b2701526146ed6000f3fe608060405234801561001057600080fd5b50600436106101d95760003560e01c80639fdf13ff11610104578063c75eea9c116100a2578063dfadfa3511610071578063dfadfa3514610553578063e0351e13146105f1578063f2fde38b14610617578063fbf84dd71461062a57600080fd5b8063c75eea9c146104f4578063cf7401f314610507578063db6327dc1461051a578063dc0bd9711461052d57600080fd5b8063b0f479a1116100de578063b0f479a11461049b578063b7946580146104b9578063c0d78655146104cc578063c4bffe2b146104df57600080fd5b80639fdf13ff1461040f578063a7cd63b714610417578063af58d59f1461042c57600080fd5b806354c8a4f31161017c57806379ba50971161014b57806379ba5097146103b65780638926f54f146103be5780638da5cb5b146103d15780639a4575b9146103ef57600080fd5b806354c8a4f31461032d5780636155cda0146103405780636b716b0d1461036757806378a010b2146103a357600080fd5b8063181f5a77116101b8578063181f5a771461023b57806321df0da714610277578063240028e8146102be578063390775371461030b57600080fd5b806241d3c1146101de57806301ffc9a7146101f35780630a2fd4931461021b575b600080fd5b6101f16101ec3660046134d1565b610651565b005b610206610201366004613546565b6107ee565b60405190151581526020015b60405180910390f35b61022e6102293660046135ae565b6108d3565b6040516102129190613639565b61022e6040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e342e300000000000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610212565b6102066102cc366004613679565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61031e610319366004613696565b610983565b60405190518152602001610212565b6101f161033b36600461371e565b610bb5565b6102997f000000000000000000000000000000000000000000000000000000000000000081565b61038e7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610212565b6101f16103b136600461378a565b610c30565b6101f1610d9f565b6102066103cc3660046135ae565b610e9c565b60005473ffffffffffffffffffffffffffffffffffffffff16610299565b6104026103fd36600461380f565b610eb3565b604051610212919061384a565b61038e600081565b61041f6111e0565b60405161021291906138aa565b61043f61043a3660046135ae565b6111f1565b604051610212919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610299565b61022e6104c73660046135ae565b6112c6565b6101f16104da366004613679565b6112f1565b6104e76113c5565b6040516102129190613904565b61043f6105023660046135ae565b61147d565b6101f1610515366004613a8f565b61154f565b6101f1610528366004613ad6565b611567565b7f0000000000000000000000000000000000000000000000000000000000000000610299565b6105c76105613660046135ae565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600882529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610212565b7f0000000000000000000000000000000000000000000000000000000000000000610206565b6101f1610625366004613679565b6119ed565b6102997f000000000000000000000000000000000000000000000000000000000000000081565b610659611a01565b60005b818110156107b057600083838381811061067857610678613b18565b90506080020180360381019061068e9190613b5b565b805190915015806106ab5750604081015167ffffffffffffffff16155b1561071a57604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600890925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090951691909316179290921790550161065c565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee5682826040516107e2929190613bd5565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061088157507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806108cd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906108fe90613c5c565b80601f016020809104026020016040519081016040528092919081815260200182805461092a90613c5c565b80156109775780601f1061094c57610100808354040283529160200191610977565b820191906000526020600020905b81548152906001019060200180831161095a57829003601f168201915b50505050509050919050565b6040805160208101909152600081526109a361099e83613d5a565b611a84565b60006109b260c0840184613e4f565b8101906109bf9190613eb4565b905060006109d060e0850185613e4f565b8101906109dd9190613ef3565b90506109ed816000015183611cb5565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610a6492600401613f84565b6020604051808303816000875af1158015610a83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa79190613fa9565b610add576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b2273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016336060870135611e66565b610b326060850160408601613679565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610b9491815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b610bbd611a01565b610c2a84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ef392505050565b50505050565b610c38611a01565b610c4183610e9c565b610c83576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610711565b67ffffffffffffffff831660009081526007602052604081206004018054610caa90613c5c565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd690613c5c565b8015610d235780601f10610cf857610100808354040283529160200191610d23565b820191906000526020600020905b815481529060010190602001808311610d0657829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610d5283858361400e565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d9193929190614172565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610711565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006108cd600567ffffffffffffffff84166120a9565b6040805180820190915260608082526020820152610ed8610ed3836141a2565b6120c4565b6000600881610eed60408601602087016135ae565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff161515908201819052909150610f9457610f5560408401602085016135ae565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610711565b610f9e8380613e4f565b9050602014610fe557610fb18380613e4f565b6040517fa3c8cf09000000000000000000000000000000000000000000000000000000008152600401610711929190614246565b602081015181516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060860135600482015263ffffffff90921660248301526044820181905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091526000917f00000000000000000000000000000000000000000000000000000000000000009091169063f856ddb69060a4016020604051808303816000875af11580156110c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e9919061425a565b6040516060860135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260405180604001604052806111468660200160208101906104c791906135ae565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529052949350505050565b60606111ec600261228e565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526108cd9061229b565b67ffffffffffffffff811660009081526007602052604090206005018054606091906108fe90613c5c565b6112f9611a01565b73ffffffffffffffffffffffffffffffffffffffff8116611346576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f168491016107e2565b606060006113d3600561228e565b90506000815167ffffffffffffffff8111156113f1576113f1613946565b60405190808252806020026020018201604052801561141a578160200160208202803683370190505b50905060005b82518110156114765782818151811061143b5761143b613b18565b602002602001015182828151811061145557611455613b18565b67ffffffffffffffff90921660209283029190910190910152600101611420565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526108cd9061229b565b611557611a01565b61156283838361234d565b505050565b61156f611a01565b60005b8181101561156257600083838381811061158e5761158e613b18565b90506020028101906115a09190614277565b6115a9906142b5565b90506115be8160800151826020015115612437565b6115d18160a00151826020015115612437565b8060200151156118cd5780516115f39060059067ffffffffffffffff16612570565b6116385780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610711565b604081015151158061164d5750606081015151155b15611684576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906118659082614369565b506060820151600582019061187a9082614369565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506118c09493929190614483565b60405180910390a16119e4565b80516118e59060059067ffffffffffffffff1661257c565b61192a5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610711565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906119936004830182613483565b6119a1600583016000613483565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611572565b6119f5611a01565b6119fe81612588565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610711565b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611b195760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610711565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611bc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611beb9190613fa9565b15611c22576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c2f816020015161267d565b6000611c3e82602001516108d3565b9050805160001480611c62575080805190602001208260a001518051906020012014155b15611c9f578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107119190613639565b611cb1826020015183606001516127a3565b5050565b600482015163ffffffff811615611d00576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610711565b6008830151600c8401516014850151602085015163ffffffff808516911614611d6b5760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff91821660048201529084166024820152604401610711565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611e00576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015283166024820152604401610711565b845167ffffffffffffffff828116911614611e5e5784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821660048201529082166024820152604401610711565b505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526115629084906127ea565b7f0000000000000000000000000000000000000000000000000000000000000000611f4a576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611fe0576000838281518110611f6a57611f6a613b18565b60200260200101519050611f888160026128f690919063ffffffff16565b15611fd75760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f4d565b5060005b815181101561156257600082828151811061200157612001613b18565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361204557506120a1565b612050600282612918565b1561209f5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611fe4565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121595760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610711565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612207573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222b9190613fa9565b15612262576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61226f816040015161293a565b61227c81602001516129b9565b6119fe81602001518260600151612b07565b606060006120bd83612b4b565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261232982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261230d919061454b565b85608001516fffffffffffffffffffffffffffffffff16612ba6565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61235683610e9c565b612398576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610711565b6123a3826000612437565b67ffffffffffffffff831660009081526007602052604090206123c69083612bd0565b6123d1816000612437565b67ffffffffffffffff831660009081526007602052604090206123f79060020182612bd0565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161242a9392919061455e565b60405180910390a1505050565b8151156124fe5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061248d575060408201516fffffffffffffffffffffffffffffffff16155b156124c657816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161071191906145e1565b8015611cb1576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612537575060208201516fffffffffffffffffffffffffffffffff1615155b15611cb157816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161071191906145e1565b60006120bd8383612d72565b60006120bd8383612dc1565b3373ffffffffffffffffffffffffffffffffffffffff821603612607576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610711565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61268681610e9c565b6126c8576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610711565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612747573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276b9190613fa9565b6119fe576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610711565b67ffffffffffffffff82166000908152600760205260409020611cb190600201827f0000000000000000000000000000000000000000000000000000000000000000612eb4565b600061284c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166132379092919063ffffffff16565b805190915015611562578080602001905181019061286a9190613fa9565b611562576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610711565b60006120bd8373ffffffffffffffffffffffffffffffffffffffff8416612dc1565b60006120bd8373ffffffffffffffffffffffffffffffffffffffff8416612d72565b7f0000000000000000000000000000000000000000000000000000000000000000156119fe5761296b600282613246565b6119fe576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610711565b6129c281610e9c565b612a04576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610711565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612a7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aa1919061461d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146119fe576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610711565b67ffffffffffffffff82166000908152600760205260409020611cb190827f0000000000000000000000000000000000000000000000000000000000000000612eb4565b60608160000180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020905b815481526020019060010190808311612b875750505050509050919050565b6000612bc585612bb6848661463a565b612bc09087614651565b613275565b90505b949350505050565b8154600090612bf990700100000000000000000000000000000000900463ffffffff164261454b565b90508015612c9b5760018301548354612c41916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612ba6565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612cc1916fffffffffffffffffffffffffffffffff9081169116613275565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061242a9084906145e1565b6000818152600183016020526040812054612db9575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108cd565b5060006108cd565b60008181526001830160205260408120548015612eaa576000612de560018361454b565b8554909150600090612df99060019061454b565b9050818114612e5e576000866000018281548110612e1957612e19613b18565b9060005260206000200154905080876000018481548110612e3c57612e3c613b18565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612e6f57612e6f614664565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108cd565b60009150506108cd565b825474010000000000000000000000000000000000000000900460ff161580612edb575081155b15612ee557505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612f2b90700100000000000000000000000000000000900463ffffffff164261454b565b90508015612feb5781831115612f6d576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612fa79083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612ba6565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156130a25773ffffffffffffffffffffffffffffffffffffffff841661304a576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610711565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610711565b848310156131b55760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906130e6908261454b565b6130f0878a61454b565b6130fa9190614651565b6131049190614693565b905073ffffffffffffffffffffffffffffffffffffffff861661315d576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610711565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610711565b6131bf858461454b565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6060612bc8848460008561328b565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156120bd565b600081831061328457816120bd565b5090919050565b60608247101561331d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610711565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161334691906146ce565b60006040518083038185875af1925050503d8060008114613383576040519150601f19603f3d011682016040523d82523d6000602084013e613388565b606091505b5091509150613399878383876133a4565b979650505050505050565b6060831561343a5782516000036134335773ffffffffffffffffffffffffffffffffffffffff85163b613433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610711565b5081612bc8565b612bc8838381511561344f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107119190613639565b50805461348f90613c5c565b6000825580601f1061349f575050565b601f0160209004906000526020600020908101906119fe91905b808211156134cd57600081556001016134b9565b5090565b600080602083850312156134e457600080fd5b823567ffffffffffffffff808211156134fc57600080fd5b818501915085601f83011261351057600080fd5b81358181111561351f57600080fd5b8660208260071b850101111561353457600080fd5b60209290920196919550909350505050565b60006020828403121561355857600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146120bd57600080fd5b67ffffffffffffffff811681146119fe57600080fd5b80356135a981613588565b919050565b6000602082840312156135c057600080fd5b81356120bd81613588565b60005b838110156135e65781810151838201526020016135ce565b50506000910152565b600081518084526136078160208601602086016135cb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006120bd60208301846135ef565b73ffffffffffffffffffffffffffffffffffffffff811681146119fe57600080fd5b80356135a98161364c565b60006020828403121561368b57600080fd5b81356120bd8161364c565b6000602082840312156136a857600080fd5b813567ffffffffffffffff8111156136bf57600080fd5b820161010081850312156120bd57600080fd5b60008083601f8401126136e457600080fd5b50813567ffffffffffffffff8111156136fc57600080fd5b6020830191508360208260051b850101111561371757600080fd5b9250929050565b6000806000806040858703121561373457600080fd5b843567ffffffffffffffff8082111561374c57600080fd5b613758888389016136d2565b9096509450602087013591508082111561377157600080fd5b5061377e878288016136d2565b95989497509550505050565b60008060006040848603121561379f57600080fd5b83356137aa81613588565b9250602084013567ffffffffffffffff808211156137c757600080fd5b818601915086601f8301126137db57600080fd5b8135818111156137ea57600080fd5b8760208285010111156137fc57600080fd5b6020830194508093505050509250925092565b60006020828403121561382157600080fd5b813567ffffffffffffffff81111561383857600080fd5b820160a081850312156120bd57600080fd5b60208152600082516040602084015261386660608401826135ef565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526138a182826135ef565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156138f857835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016138c6565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156138f857835167ffffffffffffffff1683529284019291840191600101613920565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561399957613999613946565b60405290565b6040805190810167ffffffffffffffff8111828210171561399957613999613946565b60405160c0810167ffffffffffffffff8111828210171561399957613999613946565b80151581146119fe57600080fd5b80356135a9816139e5565b80356fffffffffffffffffffffffffffffffff811681146135a957600080fd5b600060608284031215613a3057600080fd5b6040516060810181811067ffffffffffffffff82111715613a5357613a53613946565b6040529050808235613a64816139e5565b8152613a72602084016139fe565b6020820152613a83604084016139fe565b60408201525092915050565b600080600060e08486031215613aa457600080fd5b8335613aaf81613588565b9250613abe8560208601613a1e565b9150613acd8560808601613a1e565b90509250925092565b60008060208385031215613ae957600080fd5b823567ffffffffffffffff811115613b0057600080fd5b613b0c858286016136d2565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff811681146135a957600080fd5b600060808284031215613b6d57600080fd5b6040516080810181811067ffffffffffffffff82111715613b9057613b90613946565b60405282358152613ba360208401613b47565b60208201526040830135613bb681613588565b60408201526060830135613bc9816139e5565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613c4f578135835263ffffffff613c07868401613b47565b168584015283820135613c1981613588565b67ffffffffffffffff1683850152606082810135613c36816139e5565b1515908401526080928301929190910190600101613beb565b5090979650505050505050565b600181811c90821680613c7057607f821691505b602082108103613ca9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f830112613cc057600080fd5b813567ffffffffffffffff80821115613cdb57613cdb613946565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613d2157613d21613946565b81604052838152866020858801011115613d3a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613d6d57600080fd5b613d75613975565b823567ffffffffffffffff80821115613d8d57600080fd5b613d9936838701613caf565b8352613da76020860161359e565b6020840152613db86040860161366e565b604084015260608501356060840152613dd36080860161366e565b608084015260a0850135915080821115613dec57600080fd5b613df836838701613caf565b60a084015260c0850135915080821115613e1157600080fd5b613e1d36838701613caf565b60c084015260e0850135915080821115613e3657600080fd5b50613e4336828601613caf565b60e08301525092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613e8457600080fd5b83018035915067ffffffffffffffff821115613e9f57600080fd5b60200191503681900382131561371757600080fd5b600060408284031215613ec657600080fd5b613ece61399f565b8235613ed981613588565b8152613ee760208401613b47565b60208201529392505050565b600060208284031215613f0557600080fd5b813567ffffffffffffffff80821115613f1d57600080fd5b9083019060408286031215613f3157600080fd5b613f3961399f565b823582811115613f4857600080fd5b613f5487828601613caf565b825250602083013582811115613f6957600080fd5b613f7587828601613caf565b60208301525095945050505050565b604081526000613f9760408301856135ef565b82810360208401526138a181856135ef565b600060208284031215613fbb57600080fd5b81516120bd816139e5565b601f821115611562576000816000526020600020601f850160051c81016020861015613fef5750805b601f850160051c820191505b81811015611e5e57828155600101613ffb565b67ffffffffffffffff83111561402657614026613946565b61403a836140348354613c5c565b83613fc6565b6000601f84116001811461408c57600085156140565750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614122565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140db57868501358255602094850194600190920191016140bb565b5086821015614116577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60408152600061418560408301866135ef565b8281036020840152614198818587614129565b9695505050505050565b600060a082360312156141b457600080fd5b60405160a0810167ffffffffffffffff82821081831117156141d8576141d8613946565b8160405284359150808211156141ed57600080fd5b506141fa36828601613caf565b825250602083013561420b81613588565b6020820152604083013561421e8161364c565b604082015260608381013590820152608083013561423b8161364c565b608082015292915050565b602081526000612bc8602083018486614129565b60006020828403121561426c57600080fd5b81516120bd81613588565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126142ab57600080fd5b9190910192915050565b600061014082360312156142c857600080fd5b6142d06139c2565b6142d98361359e565b81526142e7602084016139f3565b6020820152604083013567ffffffffffffffff8082111561430757600080fd5b61431336838701613caf565b6040840152606085013591508082111561432c57600080fd5b5061433936828601613caf565b60608301525061434c3660808501613a1e565b608082015261435e3660e08501613a1e565b60a082015292915050565b815167ffffffffffffffff81111561438357614383613946565b614397816143918454613c5c565b84613fc6565b602080601f8311600181146143ea57600084156143b45750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611e5e565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561443757888601518255948401946001909101908401614418565b508582101561447357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526144a7818401876135ef565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506144e59050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526138a1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156108cd576108cd61451c565b67ffffffffffffffff8416815260e081016145aa60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612bc8565b606081016108cd82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561462f57600080fd5b81516120bd8161364c565b80820281158282048414176108cd576108cd61451c565b808201808211156108cd576108cd61451c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826146c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082516142ab8184602087016135cb56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101406040523480156200001257600080fd5b506040516200562038038062005620833981016040819052620000359162000b4c565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200041b565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016957604080516000815260208101909152620001699084620004c6565b5050506001600160a01b038616905062000196576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fd919062000c72565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000240573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000266919062000c99565b905063ffffffff81161562000297576040516334697c6b60e11b815263ffffffff8216600482015260240162000087565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fe919062000c99565b905063ffffffff8116156200032f576040516316ba39c560e31b815263ffffffff8216600482015260240162000087565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa15801562000381573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a7919062000c99565b63ffffffff166101205260e051608051620003d1916001600160a01b039091169060001962000623565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000de6565b336001600160a01b03821603620004755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620004e7576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005725760008382815181106200050b576200050b62000cc1565b602090810291909101015190506200052560028262000709565b1562000568576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620004ea565b5060005b81518110156200061e57600082828151811062000597576200059762000cc1565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005c3575062000615565b620005d060028262000729565b1562000613576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000576565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200069b919062000cd7565b620006a7919062000d07565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000703918691906200074016565b50505050565b600062000720836001600160a01b03841662000811565b90505b92915050565b600062000720836001600160a01b03841662000915565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200078f906001600160a01b03851690849062000967565b8051909150156200061e5780806020019051810190620007b0919062000d1d565b6200061e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000087565b600081815260018301602052604081205480156200090a5760006200083860018362000d41565b85549091506000906200084e9060019062000d41565b9050818114620008ba57600086600001828154811062000872576200087262000cc1565b906000526020600020015490508087600001848154811062000898576200089862000cc1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620008ce57620008ce62000d57565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000723565b600091505062000723565b60008181526001830160205260408120546200095e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000723565b50600062000723565b606062000978848460008562000980565b949350505050565b606082471015620009e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000087565b600080866001600160a01b0316858760405162000a01919062000d93565b60006040518083038185875af1925050503d806000811462000a40576040519150601f19603f3d011682016040523d82523d6000602084013e62000a45565b606091505b50909250905062000a598783838762000a64565b979650505050505050565b6060831562000ad857825160000362000ad0576001600160a01b0385163b62000ad05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000087565b508162000978565b62000978838381511562000aef5781518083602001fd5b8060405162461bcd60e51b815260040162000087919062000db1565b6001600160a01b038116811462000b2157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b478162000b0b565b919050565b600080600080600060a0868803121562000b6557600080fd5b855162000b728162000b0b565b8095505060208087015162000b878162000b0b565b60408801519095506001600160401b038082111562000ba557600080fd5b818901915089601f83011262000bba57600080fd5b81518181111562000bcf5762000bcf62000b24565b8060051b604051601f19603f8301168101818110858211171562000bf75762000bf762000b24565b60405291825284820192508381018501918c83111562000c1657600080fd5b938501935b8285101562000c3f5762000c2f8562000b3a565b8452938501939285019262000c1b565b80985050505050505062000c566060870162000b3a565b915062000c666080870162000b3a565b90509295509295909350565b60006020828403121562000c8557600080fd5b815162000c928162000b0b565b9392505050565b60006020828403121562000cac57600080fd5b815163ffffffff8116811462000c9257600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000cea57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000723576200072362000cf1565b60006020828403121562000d3057600080fd5b8151801515811462000c9257600080fd5b8181038181111562000723576200072362000cf1565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d8a57818101518382015260200162000d70565b50506000910152565b6000825162000da781846020870162000d6d565b9190910192915050565b602081526000825180602084015262000dd281604085016020870162000d6d565b601f01601f19169190910160400192915050565b60805160a05160c05160e051610100516101205161477a62000ea660003960008181610382015281816111ab01528181611e230152611e810152600081816106760152610a7801526000818161035b01526110bf01526000818161063a01528181611fab01526129f201526000818161057601528181611c21015261226101526000818161028f015281816102e401528181610b3e0152818161108c01528181611b41015281816121810152818161287c0152612bdd015261477a6000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80639a4575b91161010f578063c75eea9c116100a2578063dfadfa3511610071578063dfadfa351461059a578063e0351e1314610638578063f2fde38b1461065e578063fbf84dd71461067157600080fd5b8063c75eea9c1461053b578063cf7401f31461054e578063db6327dc14610561578063dc0bd9711461057457600080fd5b8063b0f479a1116100de578063b0f479a1146104e2578063b794658014610500578063c0d7865514610513578063c4bffe2b1461052657600080fd5b80639a4575b9146104365780639fdf13ff14610456578063a7cd63b71461045e578063af58d59f1461047357600080fd5b80636155cda01161018757806379ba50971161015657806379ba5097146103ea5780637d54534e146103f25780638926f54f146104055780638da5cb5b1461041857600080fd5b80636155cda0146103565780636b716b0d1461037d5780636d3d1a58146103b957806378a010b2146103d757600080fd5b806321df0da7116101c357806321df0da71461028d578063240028e8146102d4578063390775371461032157806354c8a4f31461034357600080fd5b806241d3c1146101f457806301ffc9a7146102095780630a2fd49314610231578063181f5a7714610251575b600080fd5b610207610202366004613587565b610698565b005b61021c6102173660046135fc565b610835565b60405190151581526020015b60405180910390f35b61024461023f366004613664565b61091a565b60405161022891906136ef565b6102446040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e342e300000000000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610228565b61021c6102e236600461372f565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61033461032f36600461374c565b6109ca565b60405190518152602001610228565b6102076103513660046137d4565b610bfc565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6103a47f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610228565b60085473ffffffffffffffffffffffffffffffffffffffff166102af565b6102076103e5366004613840565b610c77565b610207610de6565b61020761040036600461372f565b610ee3565b61021c610413366004613664565b610f32565b60005473ffffffffffffffffffffffffffffffffffffffff166102af565b6104496104443660046138c5565b610f49565b6040516102289190613900565b6103a4600081565b610466611225565b6040516102289190613960565b610486610481366004613664565b611236565b604051610228919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102af565b61024461050e366004613664565b61130b565b61020761052136600461372f565b611336565b61052e61140a565b60405161022891906139ba565b610486610549366004613664565b6114c2565b61020761055c366004613b45565b611594565b61020761056f366004613b8c565b61161d565b7f00000000000000000000000000000000000000000000000000000000000000006102af565b61060e6105a8366004613664565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600982529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610228565b7f000000000000000000000000000000000000000000000000000000000000000061021c565b61020761066c36600461372f565b611aa3565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6106a0611ab7565b60005b818110156107f75760008383838181106106bf576106bf613bce565b9050608002018036038101906106d59190613c11565b805190915015806106f25750604081015167ffffffffffffffff16155b1561076157604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600990925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169190931617929092179055016106a3565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee568282604051610829929190613c8b565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806108c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061091457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061094590613d12565b80601f016020809104026020016040519081016040528092919081815260200182805461097190613d12565b80156109be5780601f10610993576101008083540402835291602001916109be565b820191906000526020600020905b8154815290600101906020018083116109a157829003601f168201915b50505050509050919050565b6040805160208101909152600081526109ea6109e583613e10565b611b3a565b60006109f960c0840184613f05565b810190610a069190613f6a565b90506000610a1760e0850185613f05565b810190610a249190613fa9565b9050610a34816000015183611d6b565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aab9260040161403a565b6020604051808303816000875af1158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee919061405f565b610b24576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b6973ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016336060870135611f1c565b610b79606085016040860161372f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610bdb91815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b610c04611ab7565b610c7184848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611fa992505050565b50505050565b610c7f611ab7565b610c8883610f32565b610cca576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b67ffffffffffffffff831660009081526007602052604081206004018054610cf190613d12565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1d90613d12565b8015610d6a5780601f10610d3f57610100808354040283529160200191610d6a565b820191906000526020600020905b815481529060010190602001808311610d4d57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610d998385836140c4565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610dd8939291906141df565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610758565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610eeb611ab7565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610914600567ffffffffffffffff841661215f565b6040805180820190915260608082526020820152610f6e610f6983614243565b61217a565b6000600981610f836040860160208701613664565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff16151590820181905290915061102a57610feb6040840160208501613664565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b602081015181516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060860135600482015263ffffffff90921660248301526044820181905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091526000917f00000000000000000000000000000000000000000000000000000000000000009091169063f856ddb69060a4016020604051808303816000875af115801561110a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112e91906142e7565b6040516060860135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a2604051806040016040528061118b86602001602081019061050e9190613664565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529052949350505050565b60606112316002612344565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261091490612351565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061094590613d12565b61133e611ab7565b73ffffffffffffffffffffffffffffffffffffffff811661138b576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610829565b606060006114186005612344565b90506000815167ffffffffffffffff811115611436576114366139fc565b60405190808252806020026020018201604052801561145f578160200160208202803683370190505b50905060005b82518110156114bb5782818151811061148057611480613bce565b602002602001015182828151811061149a5761149a613bce565b67ffffffffffffffff90921660209283029190910190910152600101611465565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261091490612351565b60085473ffffffffffffffffffffffffffffffffffffffff1633148015906115d4575060005473ffffffffffffffffffffffffffffffffffffffff163314155b1561160d576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b611618838383612403565b505050565b611625611ab7565b60005b8181101561161857600083838381811061164457611644613bce565b90506020028101906116569190614304565b61165f90614342565b905061167481608001518260200151156124ed565b6116878160a001518260200151156124ed565b8060200151156119835780516116a99060059067ffffffffffffffff16612626565b6116ee5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b60408101515115806117035750606081015151155b1561173a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061191b90826143f6565b506060820151600582019061193090826143f6565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506119769493929190614510565b60405180910390a1611a9a565b805161199b9060059067ffffffffffffffff16612632565b6119e05780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611a496004830182613539565b611a57600583016000613539565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611628565b611aab611ab7565b611ab48161263e565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b38576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610758565b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611bcf5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611c7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca1919061405f565b15611cd8576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ce58160200151612733565b6000611cf4826020015161091a565b9050805160001480611d18575080805190602001208260a001518051906020012014155b15611d55578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161075891906136ef565b611d6782602001518360600151612859565b5050565b600482015163ffffffff811615611db6576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610758565b6008830151600c8401516014850151602085015163ffffffff808516911614611e215760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff91821660048201529084166024820152604401610758565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611eb6576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015283166024820152604401610758565b845167ffffffffffffffff828116911614611f145784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821660048201529082166024820152604401610758565b505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526116189084906128a0565b7f0000000000000000000000000000000000000000000000000000000000000000612000576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561209657600083828151811061202057612020613bce565b6020026020010151905061203e8160026129ac90919063ffffffff16565b1561208d5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101612003565b5060005b81518110156116185760008282815181106120b7576120b7613bce565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120fb5750612157565b6121066002826129ce565b156121555760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161209a565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461220f5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156122bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e1919061405f565b15612318576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61232581604001516129f0565b6123328160200151612a6f565b611ab481602001518260600151612bbd565b6060600061217383612c01565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526123df82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426123c391906145d8565b85608001516fffffffffffffffffffffffffffffffff16612c5c565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61240c83610f32565b61244e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b6124598260006124ed565b67ffffffffffffffff8316600090815260076020526040902061247c9083612c86565b6124878160006124ed565b67ffffffffffffffff831660009081526007602052604090206124ad9060020182612c86565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516124e0939291906145eb565b60405180910390a1505050565b8151156125b45781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612543575060408201516fffffffffffffffffffffffffffffffff16155b1561257c57816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610758919061466e565b8015611d67576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806125ed575060208201516fffffffffffffffffffffffffffffffff1615155b15611d6757816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610758919061466e565b60006121738383612e28565b60006121738383612e77565b3373ffffffffffffffffffffffffffffffffffffffff8216036126bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610758565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61273c81610f32565b61277e576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156127fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612821919061405f565b611ab4576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d6790600201827f0000000000000000000000000000000000000000000000000000000000000000612f6a565b6000612902826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166132ed9092919063ffffffff16565b8051909150156116185780806020019051810190612920919061405f565b611618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610758565b60006121738373ffffffffffffffffffffffffffffffffffffffff8416612e77565b60006121738373ffffffffffffffffffffffffffffffffffffffff8416612e28565b7f000000000000000000000000000000000000000000000000000000000000000015611ab457612a216002826132fc565b611ab4576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610758565b612a7881610f32565b612aba576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612b33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b5791906146aa565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611ab4576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d6790827f0000000000000000000000000000000000000000000000000000000000000000612f6a565b6060816000018054806020026020016040519081016040528092919081815260200182805480156109be57602002820191906000526020600020905b815481526020019060010190808311612c3d5750505050509050919050565b6000612c7b85612c6c84866146c7565b612c7690876146de565b61332b565b90505b949350505050565b8154600090612caf90700100000000000000000000000000000000900463ffffffff16426145d8565b90508015612d515760018301548354612cf7916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612c5c565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612d77916fffffffffffffffffffffffffffffffff908116911661332b565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906124e090849061466e565b6000818152600183016020526040812054612e6f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610914565b506000610914565b60008181526001830160205260408120548015612f60576000612e9b6001836145d8565b8554909150600090612eaf906001906145d8565b9050818114612f14576000866000018281548110612ecf57612ecf613bce565b9060005260206000200154905080876000018481548110612ef257612ef2613bce565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612f2557612f256146f1565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610914565b6000915050610914565b825474010000000000000000000000000000000000000000900460ff161580612f91575081155b15612f9b57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612fe190700100000000000000000000000000000000900463ffffffff16426145d8565b905080156130a15781831115613023576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461305d9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612c5c565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156131585773ffffffffffffffffffffffffffffffffffffffff8416613100576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610758565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610758565b8483101561326b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061319c90826145d8565b6131a6878a6145d8565b6131b091906146de565b6131ba9190614720565b905073ffffffffffffffffffffffffffffffffffffffff8616613213576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610758565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610758565b61327585846145d8565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6060612c7e8484600085613341565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515612173565b600081831061333a5781612173565b5090919050565b6060824710156133d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610758565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516133fc919061475b565b60006040518083038185875af1925050503d8060008114613439576040519150601f19603f3d011682016040523d82523d6000602084013e61343e565b606091505b509150915061344f8783838761345a565b979650505050505050565b606083156134f05782516000036134e95773ffffffffffffffffffffffffffffffffffffffff85163b6134e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610758565b5081612c7e565b612c7e83838151156135055781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075891906136ef565b50805461354590613d12565b6000825580601f10613555575050565b601f016020900490600052602060002090810190611ab491905b80821115613583576000815560010161356f565b5090565b6000806020838503121561359a57600080fd5b823567ffffffffffffffff808211156135b257600080fd5b818501915085601f8301126135c657600080fd5b8135818111156135d557600080fd5b8660208260071b85010111156135ea57600080fd5b60209290920196919550909350505050565b60006020828403121561360e57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461217357600080fd5b67ffffffffffffffff81168114611ab457600080fd5b803561365f8161363e565b919050565b60006020828403121561367657600080fd5b81356121738161363e565b60005b8381101561369c578181015183820152602001613684565b50506000910152565b600081518084526136bd816020860160208601613681565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061217360208301846136a5565b73ffffffffffffffffffffffffffffffffffffffff81168114611ab457600080fd5b803561365f81613702565b60006020828403121561374157600080fd5b813561217381613702565b60006020828403121561375e57600080fd5b813567ffffffffffffffff81111561377557600080fd5b8201610100818503121561217357600080fd5b60008083601f84011261379a57600080fd5b50813567ffffffffffffffff8111156137b257600080fd5b6020830191508360208260051b85010111156137cd57600080fd5b9250929050565b600080600080604085870312156137ea57600080fd5b843567ffffffffffffffff8082111561380257600080fd5b61380e88838901613788565b9096509450602087013591508082111561382757600080fd5b5061383487828801613788565b95989497509550505050565b60008060006040848603121561385557600080fd5b83356138608161363e565b9250602084013567ffffffffffffffff8082111561387d57600080fd5b818601915086601f83011261389157600080fd5b8135818111156138a057600080fd5b8760208285010111156138b257600080fd5b6020830194508093505050509250925092565b6000602082840312156138d757600080fd5b813567ffffffffffffffff8111156138ee57600080fd5b820160a0818503121561217357600080fd5b60208152600082516040602084015261391c60608401826136a5565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261395782826136a5565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156139ae57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161397c565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156139ae57835167ffffffffffffffff16835292840192918401916001016139d6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613a4f57613a4f6139fc565b60405290565b6040805190810167ffffffffffffffff81118282101715613a4f57613a4f6139fc565b60405160c0810167ffffffffffffffff81118282101715613a4f57613a4f6139fc565b8015158114611ab457600080fd5b803561365f81613a9b565b80356fffffffffffffffffffffffffffffffff8116811461365f57600080fd5b600060608284031215613ae657600080fd5b6040516060810181811067ffffffffffffffff82111715613b0957613b096139fc565b6040529050808235613b1a81613a9b565b8152613b2860208401613ab4565b6020820152613b3960408401613ab4565b60408201525092915050565b600080600060e08486031215613b5a57600080fd5b8335613b658161363e565b9250613b748560208601613ad4565b9150613b838560808601613ad4565b90509250925092565b60008060208385031215613b9f57600080fd5b823567ffffffffffffffff811115613bb657600080fd5b613bc285828601613788565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff8116811461365f57600080fd5b600060808284031215613c2357600080fd5b6040516080810181811067ffffffffffffffff82111715613c4657613c466139fc565b60405282358152613c5960208401613bfd565b60208201526040830135613c6c8161363e565b60408201526060830135613c7f81613a9b565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613d05578135835263ffffffff613cbd868401613bfd565b168584015283820135613ccf8161363e565b67ffffffffffffffff1683850152606082810135613cec81613a9b565b1515908401526080928301929190910190600101613ca1565b5090979650505050505050565b600181811c90821680613d2657607f821691505b602082108103613d5f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f830112613d7657600080fd5b813567ffffffffffffffff80821115613d9157613d916139fc565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613dd757613dd76139fc565b81604052838152866020858801011115613df057600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613e2357600080fd5b613e2b613a2b565b823567ffffffffffffffff80821115613e4357600080fd5b613e4f36838701613d65565b8352613e5d60208601613654565b6020840152613e6e60408601613724565b604084015260608501356060840152613e8960808601613724565b608084015260a0850135915080821115613ea257600080fd5b613eae36838701613d65565b60a084015260c0850135915080821115613ec757600080fd5b613ed336838701613d65565b60c084015260e0850135915080821115613eec57600080fd5b50613ef936828601613d65565b60e08301525092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f3a57600080fd5b83018035915067ffffffffffffffff821115613f5557600080fd5b6020019150368190038213156137cd57600080fd5b600060408284031215613f7c57600080fd5b613f84613a55565b8235613f8f8161363e565b8152613f9d60208401613bfd565b60208201529392505050565b600060208284031215613fbb57600080fd5b813567ffffffffffffffff80821115613fd357600080fd5b9083019060408286031215613fe757600080fd5b613fef613a55565b823582811115613ffe57600080fd5b61400a87828601613d65565b82525060208301358281111561401f57600080fd5b61402b87828601613d65565b60208301525095945050505050565b60408152600061404d60408301856136a5565b828103602084015261395781856136a5565b60006020828403121561407157600080fd5b815161217381613a9b565b601f821115611618576000816000526020600020601f850160051c810160208610156140a55750805b601f850160051c820191505b81811015611f14578281556001016140b1565b67ffffffffffffffff8311156140dc576140dc6139fc565b6140f0836140ea8354613d12565b8361407c565b6000601f841160018114614142576000851561410c5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556141d8565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156141915786850135825560209485019460019092019101614171565b50868210156141cc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b6040815260006141f260408301866136a5565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561425557600080fd5b60405160a0810167ffffffffffffffff8282108183111715614279576142796139fc565b81604052843591508082111561428e57600080fd5b5061429b36828601613d65565b82525060208301356142ac8161363e565b602082015260408301356142bf81613702565b60408201526060838101359082015260808301356142dc81613702565b608082015292915050565b6000602082840312156142f957600080fd5b81516121738161363e565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261433857600080fd5b9190910192915050565b6000610140823603121561435557600080fd5b61435d613a78565b61436683613654565b815261437460208401613aa9565b6020820152604083013567ffffffffffffffff8082111561439457600080fd5b6143a036838701613d65565b604084015260608501359150808211156143b957600080fd5b506143c636828601613d65565b6060830152506143d93660808501613ad4565b60808201526143eb3660e08501613ad4565b60a082015292915050565b815167ffffffffffffffff811115614410576144106139fc565b6144248161441e8454613d12565b8461407c565b602080601f83116001811461447757600084156144415750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611f14565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156144c4578886015182559484019460019091019084016144a5565b508582101561450057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152614534818401876136a5565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506145729050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613957565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610914576109146145a9565b67ffffffffffffffff8416815260e0810161463760208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612c7e565b6060810161091482848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156146bc57600080fd5b815161217381613702565b8082028115828204841417610914576109146145a9565b80820180821115610914576109146145a9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614756577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000825161433881846020870161368156fea164736f6c6343000818000a", } var USDCTokenPoolABI = USDCTokenPoolMetaData.ABI @@ -367,6 +367,28 @@ func (_USDCTokenPool *USDCTokenPoolCallerSession) GetDomain(chainSelector uint64 return _USDCTokenPool.Contract.GetDomain(&_USDCTokenPool.CallOpts, chainSelector) } +func (_USDCTokenPool *USDCTokenPoolCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getRateLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetRateLimitAdmin() (common.Address, error) { + return _USDCTokenPool.Contract.GetRateLimitAdmin(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetRateLimitAdmin() (common.Address, error) { + return _USDCTokenPool.Contract.GetRateLimitAdmin(&_USDCTokenPool.CallOpts) +} + func (_USDCTokenPool *USDCTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { var out []interface{} err := _USDCTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) @@ -759,6 +781,18 @@ func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetDomains(domains []USDCT return _USDCTokenPool.Contract.SetDomains(&_USDCTokenPool.TransactOpts, domains) } +func (_USDCTokenPool *USDCTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) +} + +func (_USDCTokenPool *USDCTokenPoolSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetRateLimitAdmin(&_USDCTokenPool.TransactOpts, rateLimitAdmin) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetRateLimitAdmin(&_USDCTokenPool.TransactOpts, rateLimitAdmin) +} + func (_USDCTokenPool *USDCTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { return _USDCTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) } @@ -3029,6 +3063,8 @@ type USDCTokenPoolInterface interface { GetDomain(opts *bind.CallOpts, chainSelector uint64) (USDCTokenPoolDomain, error) + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) @@ -3071,6 +3107,8 @@ type USDCTokenPoolInterface interface { SetDomains(opts *bind.TransactOpts, domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 663eacb5dd..63ec39c74c 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,20 +1,21 @@ GETH_VERSION: 1.13.8 arm_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 1a0abacf84def916519013f713b667f106434a091af8b9f441e12cc90aa2cdf8 arm_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 -burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin d0708a0ae657eb7df01a5177ff4d5850c5823c821f5f6bbd0a468b3982330b13 -burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin fcb85edfc871504a5146db2e3951193c2de089fe491dd7a2fbc755fd92725cac -burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 17bcd03828f43f50028bc4d66fdfb0cf576aaf28895d8f86c6ff598159a0cd64 -burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6f40135e1488097eafa843839a719fe9a3c21354565b64eb377a24a0a55782ef +burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 62d9963a998b8e5c4b9bfa537e916559c167863329c40e9a75eb4defebceb810 +burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 1bbffb552c3256097fbe61a430de408073816f40e17b17b102b793527d44f046 +burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 5be8832498c8aab49957bfff94fbb1d22373833d1d56f5d8ace259343b27fc24 +burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 9215cb5efe441e9893f871de31b4a5d4171c479f276aac4084046514990f1bd6 ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin c06c1cf1d004a803585a2c9d7a71ee5997b5fca86c2e111335cb8b930d9e3b5a +ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin 02be3227883ca4b69383892d27ba7a9af747151a06f4815d18ccd8aaf89b4fb9 commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin ddc26c10c2a52b59624faae9005827b09b98db4566887a736005e8cc37cf8a51 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin ebd8aac686fa28a71d4212bcd25a28f8f640d50dce5e50498b2f6b8534890b69 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 25a7bf3aa46252844c7afabc15db1051e7b6a717e296fc4c6e2f2f93d16033c5 evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 9478aedc9f0072fbdafb54a6f82248de1efbcd7bdff18a90d8556b9aaff67455 -evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin a8c23c9280a713544eae0a0b8841a9caf97e616338d31ebc62501d8b4ab0eed6 -evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 116d5cb8447a1af61664a8d1db2d76086c042a3228337bc5cd49b9abd3e815f7 -lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin 95a93517b01f51c35d82711a0015995f4804820ed67f6b46b785c4c94815df93 -lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin 05e308151b5adc9ba8d33385b8f82d55aad638652fe50e3ea8b09b1d0bbfd367 +evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin bca94c29d523e7679db6ef86ffffcc52864a7499e9f0c51807c901bcc1927fda +evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin bf1a3090a2f8d1632b82a6d45200cf6f3833a1e27303745405c1ed13ffc0cf83 +lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin f049909cfef0aa3b8158c85e7b64516b9d7b32f4930705574090e5b9cab534b1 +lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin d897366aa5c58f426eaf3fc748d9def8f78111d9ac8c122e390952f640de22fc maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin 1d5146d43e1b99cd2d6f9f06475be19087e4349f7cee0fdbbf134ba65e967c93 mock_arm_contract: ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.abi ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.bin e7a3a6c3eda5fb882e16bcc2b4340f78523acb67907bcdcaf3c8ffc51488688e @@ -26,12 +27,12 @@ multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Help nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 78b58f4f192db7496e2b6de805d6a2c918b98d4fa62f3c7ed145ef3b5657a40d ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 1588313bb5e781d181a825247d30828f59007700f36b4b9b00391592b06ff4b4 -price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 09cdd37920d6f605c8a264f805bdba183813517169b2b5df4547e995d9ce73f7 +price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 955eeb1da5f001fa01dc9914bf8a02b7e3b58e080ee775424261dcd97f88d70d registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 7b2a47349d3fdb8d8b4e206d68577219deca7fabd1e893686fa8f118ad980d2d report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin c07af8433bf8dbc7981725b18922a9c4e2dea068dd204bc62adc0e926cb499c3 router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 42576577e81beea9a069bd9229caaa9a71227fbaef3871a1a2e69fd218216290 self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 86e169636e5633854ed0b709c804066b615040bceba25aa5137450fbe6f76fa3 token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin fb06d2cf5f7476e512c6fb7aab8eab43545efd7f0f6ca133c64ff4e3963902c4 -token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 47a83e91b28ad1381a2a5882e2adfe168809a63a8f533ab1631f174550c64bed -usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin a54136ed9bffc74fff830c5066dbfcee6db1f31d636795317267d6baf1e0427a +token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 7c01fd89f5153baa4d7409d14beabb3f861abfbf8880d3c6d06802cc398570f9 +usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin e259cffee304678cfce3632f122cf96ecc06b4ab01905940cd0111f2fd50e4d8 weth9: ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin 2970d79a0ca6dd6279cde130de45e56c8790ed695eae477fb5ba4c1bb75b720d diff --git a/core/services/ocr2/plugins/ccip/integration_test.go b/core/services/ocr2/plugins/ccip/integration_test.go index bbf785efa8..bfd270fb66 100644 --- a/core/services/ocr2/plugins/ccip/integration_test.go +++ b/core/services/ocr2/plugins/ccip/integration_test.go @@ -618,8 +618,6 @@ func TestIntegration_CCIP(t *testing.T) { PriceRegistry: ccipTH.Dest.PriceRegistry.Address(), MaxDataBytes: 1e5, MaxNumberOfTokensPerMsg: 5, - MaxPoolReleaseOrMintGas: 200_000, - MaxTokenTransferGas: 100_000, }) node.EventuallyNodeUsesUpdatedPriceRegistry(t, ccipTH) } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_test.go index 2f0ccbc246..85aea6ab99 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_test.go @@ -351,8 +351,7 @@ func setupOnRampV1_5_0(t *testing.T, user *bind.TransactOpts, bc *client.Simulat MaxDataBytes: 0, MaxPerMsgGasLimit: 0, DefaultTokenFeeUSDCents: 50, - DefaultTokenDestGasOverhead: 34_000, - DefaultTokenDestBytesOverhead: 500, + DefaultTokenDestGasOverhead: 125_000, } rateLimiterConfig := evm_2_evm_onramp.RateLimiterConfig{ IsEnabled: false, diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp.go index 2db9498de9..0c45f0d6ea 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/offramp.go @@ -43,9 +43,7 @@ func (d ExecOnchainConfig) AbiString() string { {"name": "maxDataBytes", "type": "uint32"}, {"name": "maxNumberOfTokensPerMsg", "type": "uint16"}, {"name": "router", "type": "address"}, - {"name": "priceRegistry", "type": "address"}, - {"name": "maxPoolReleaseOrMintGas", "type": "uint32"}, - {"name": "maxTokenTransferGas", "type": "uint32"} + {"name": "priceRegistry", "type": "address"} ], "type": "tuple" } @@ -65,12 +63,6 @@ func (d ExecOnchainConfig) Validate() error { if d.MaxNumberOfTokensPerMsg == 0 { return errors.New("must set MaxNumberOfTokensPerMsg") } - if d.MaxPoolReleaseOrMintGas == 0 { - return errors.New("must set MaxPoolReleaseOrMintGas") - } - if d.MaxTokenTransferGas == 0 { - return errors.New("must set MaxTokenTransferGas") - } return nil } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go index f072fc2b38..3009718301 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go @@ -158,8 +158,7 @@ func setupOnRampV1_5_0(t testing.TB, user *bind.TransactOpts, bc *client.Simulat MaxDataBytes: 0, MaxPerMsgGasLimit: 0, DefaultTokenFeeUSDCents: 50, - DefaultTokenDestGasOverhead: 34_000, - DefaultTokenDestBytesOverhead: 500, + DefaultTokenDestGasOverhead: 125_000, } rateLimiterConfig := evm_2_evm_onramp.RateLimiterConfig{ IsEnabled: false, diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go index 805c49d91a..1f745df9d5 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -124,23 +124,13 @@ type ExecOnchainConfig struct { v1_5_0.ExecOnchainConfig } -func NewExecOnchainConfig( - PermissionLessExecutionThresholdSeconds uint32, - Router common.Address, - PriceRegistry common.Address, - MaxNumberOfTokensPerMsg uint16, - MaxDataBytes uint32, - MaxPoolReleaseOrMintGas uint32, - MaxTokenTransferGas uint32, -) ExecOnchainConfig { +func NewExecOnchainConfig(PermissionLessExecutionThresholdSeconds uint32, Router common.Address, PriceRegistry common.Address, MaxNumberOfTokensPerMsg uint16, MaxDataBytes uint32) ExecOnchainConfig { return ExecOnchainConfig{v1_5_0.ExecOnchainConfig{ PermissionLessExecutionThresholdSeconds: PermissionLessExecutionThresholdSeconds, Router: Router, PriceRegistry: PriceRegistry, MaxNumberOfTokensPerMsg: MaxNumberOfTokensPerMsg, MaxDataBytes: MaxDataBytes, - MaxPoolReleaseOrMintGas: MaxPoolReleaseOrMintGas, - MaxTokenTransferGas: MaxTokenTransferGas, }} } @@ -323,8 +313,7 @@ func (c *CCIPContracts) DeployNewOnRamp(t *testing.T) { MaxDataBytes: 1e5, MaxPerMsgGasLimit: 4_000_000, DefaultTokenFeeUSDCents: 50, - DefaultTokenDestGasOverhead: 34_000, - DefaultTokenDestBytesOverhead: 500, + DefaultTokenDestGasOverhead: DefaultTokenDestGasOverhead, }, evm_2_evm_onramp.RateLimiterConfig{ IsEnabled: true, @@ -353,7 +342,7 @@ func (c *CCIPContracts) DeployNewOnRamp(t *testing.T) { MinFeeUSDCents: 50, // $0.5 MaxFeeUSDCents: 1_000_000_00, // $ 1 million DeciBps: 5_0, // 5 bps - DestGasOverhead: 34_000, + DestGasOverhead: 110_000, DestBytesOverhead: 32, AggregateRateLimitEnabled: true, }, @@ -1048,8 +1037,7 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh MaxDataBytes: 1e5, MaxPerMsgGasLimit: 4_000_000, DefaultTokenFeeUSDCents: 50, - DefaultTokenDestGasOverhead: 34_000, - DefaultTokenDestBytesOverhead: 500, + DefaultTokenDestGasOverhead: DefaultTokenDestGasOverhead, }, evm_2_evm_onramp.RateLimiterConfig{ IsEnabled: true, @@ -1078,7 +1066,7 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh MinFeeUSDCents: 50, // $0.5 MaxFeeUSDCents: 1_000_000_00, // $ 1 million DeciBps: 5_0, // 5 bps - DestGasOverhead: 34_000, + DestGasOverhead: 350_000, DestBytesOverhead: 32, AggregateRateLimitEnabled: true, }, diff --git a/core/services/ocr2/plugins/ccip/testhelpers/config.go b/core/services/ocr2/plugins/ccip/testhelpers/config.go index f70f1954f1..4e2f358835 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/config.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/config.go @@ -15,6 +15,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0" ) +const ( + DefaultTokenDestGasOverhead = 125_000 +) + var PermissionLessExecutionThresholdSeconds = uint32(FirstBlockAge.Seconds()) func (c *CCIPContracts) CreateDefaultCommitOnchainConfig(t *testing.T) []byte { @@ -49,8 +53,6 @@ func (c *CCIPContracts) CreateDefaultExecOnchainConfig(t *testing.T) []byte { PriceRegistry: c.Dest.PriceRegistry.Address(), MaxDataBytes: 1e5, MaxNumberOfTokensPerMsg: 5, - MaxPoolReleaseOrMintGas: 200_000, - MaxTokenTransferGas: 100_000, }) require.NoError(t, err) return config diff --git a/integration-tests/ccip-tests/contracts/contract_deployer.go b/integration-tests/ccip-tests/contracts/contract_deployer.go index 8656656e0b..57d96e5cb6 100644 --- a/integration-tests/ccip-tests/contracts/contract_deployer.go +++ b/integration-tests/ccip-tests/contracts/contract_deployer.go @@ -1044,7 +1044,6 @@ func (e *CCIPContractsDeployer) DeployOnRamp( MaxPerMsgGasLimit: 4_000_000, DefaultTokenFeeUSDCents: 50, DefaultTokenDestGasOverhead: 125_000, - DefaultTokenDestBytesOverhead: 500, }, evm_2_evm_onramp.RateLimiterConfig{ Capacity: opts.Capacity, @@ -1289,30 +1288,30 @@ func OCR2ParamsForCommit(blockTime time.Duration) contracts.OffChainAggregatorV2 // slow blocktime chains like Ethereum if blockTime >= 10*time.Second { return contracts.OffChainAggregatorV2Config{ - DeltaProgress: 2 * time.Minute, - DeltaResend: 5 * time.Second, - DeltaRound: 90 * time.Second, - DeltaGrace: 5 * time.Second, - DeltaStage: 60 * time.Second, - MaxDurationQuery: 100 * time.Millisecond, - MaxDurationObservation: 35 * time.Second, - MaxDurationReport: 10 * time.Second, - MaxDurationShouldAcceptFinalizedReport: 5 * time.Second, - MaxDurationShouldTransmitAcceptedReport: 10 * time.Second, + DeltaProgress: config.MustNewDuration(2 * time.Minute), + DeltaResend: config.MustNewDuration(5 * time.Second), + DeltaRound: config.MustNewDuration(90 * time.Second), + DeltaGrace: config.MustNewDuration(5 * time.Second), + DeltaStage: config.MustNewDuration(60 * time.Second), + MaxDurationQuery: config.MustNewDuration(100 * time.Millisecond), + MaxDurationObservation: config.MustNewDuration(35 * time.Second), + MaxDurationReport: config.MustNewDuration(10 * time.Second), + MaxDurationShouldAcceptFinalizedReport: config.MustNewDuration(5 * time.Second), + MaxDurationShouldTransmitAcceptedReport: config.MustNewDuration(10 * time.Second), } } // fast blocktime chains like Avalanche return contracts.OffChainAggregatorV2Config{ - DeltaProgress: 2 * time.Minute, - DeltaResend: 5 * time.Second, - DeltaRound: 60 * time.Second, - DeltaGrace: 5 * time.Second, - DeltaStage: 25 * time.Second, - MaxDurationQuery: 100 * time.Millisecond, - MaxDurationObservation: 35 * time.Second, - MaxDurationReport: 10 * time.Second, - MaxDurationShouldAcceptFinalizedReport: 5 * time.Second, - MaxDurationShouldTransmitAcceptedReport: 10 * time.Second, + DeltaProgress: config.MustNewDuration(2 * time.Minute), + DeltaResend: config.MustNewDuration(5 * time.Second), + DeltaRound: config.MustNewDuration(60 * time.Second), + DeltaGrace: config.MustNewDuration(5 * time.Second), + DeltaStage: config.MustNewDuration(25 * time.Second), + MaxDurationQuery: config.MustNewDuration(100 * time.Millisecond), + MaxDurationObservation: config.MustNewDuration(35 * time.Second), + MaxDurationReport: config.MustNewDuration(10 * time.Second), + MaxDurationShouldAcceptFinalizedReport: config.MustNewDuration(5 * time.Second), + MaxDurationShouldTransmitAcceptedReport: config.MustNewDuration(10 * time.Second), } } @@ -1320,30 +1319,30 @@ func OCR2ParamsForExec(blockTime time.Duration) contracts.OffChainAggregatorV2Co // slow blocktime chains like Ethereum if blockTime >= 10*time.Second { return contracts.OffChainAggregatorV2Config{ - DeltaProgress: 2 * time.Minute, - DeltaResend: 5 * time.Second, - DeltaRound: 90 * time.Second, - DeltaGrace: 5 * time.Second, - DeltaStage: 60 * time.Second, - MaxDurationQuery: 100 * time.Millisecond, - MaxDurationObservation: 35 * time.Second, - MaxDurationReport: 10 * time.Second, - MaxDurationShouldAcceptFinalizedReport: 5 * time.Second, - MaxDurationShouldTransmitAcceptedReport: 10 * time.Second, + DeltaProgress: config.MustNewDuration(2 * time.Minute), + DeltaResend: config.MustNewDuration(5 * time.Second), + DeltaRound: config.MustNewDuration(90 * time.Second), + DeltaGrace: config.MustNewDuration(5 * time.Second), + DeltaStage: config.MustNewDuration(60 * time.Second), + MaxDurationQuery: config.MustNewDuration(100 * time.Millisecond), + MaxDurationObservation: config.MustNewDuration(35 * time.Second), + MaxDurationReport: config.MustNewDuration(10 * time.Second), + MaxDurationShouldAcceptFinalizedReport: config.MustNewDuration(5 * time.Second), + MaxDurationShouldTransmitAcceptedReport: config.MustNewDuration(10 * time.Second), } } // fast blocktime chains like Avalanche return contracts.OffChainAggregatorV2Config{ - DeltaProgress: 120 * time.Second, - DeltaResend: 5 * time.Second, - DeltaRound: 30 * time.Second, - DeltaGrace: 5 * time.Second, - DeltaStage: 10 * time.Second, - MaxDurationQuery: 100 * time.Millisecond, - MaxDurationObservation: 35 * time.Second, - MaxDurationReport: 10 * time.Second, - MaxDurationShouldAcceptFinalizedReport: 5 * time.Second, - MaxDurationShouldTransmitAcceptedReport: 10 * time.Second, + DeltaProgress: config.MustNewDuration(120 * time.Second), + DeltaResend: config.MustNewDuration(5 * time.Second), + DeltaRound: config.MustNewDuration(30 * time.Second), + DeltaGrace: config.MustNewDuration(5 * time.Second), + DeltaStage: config.MustNewDuration(10 * time.Second), + MaxDurationQuery: config.MustNewDuration(100 * time.Millisecond), + MaxDurationObservation: config.MustNewDuration(35 * time.Second), + MaxDurationReport: config.MustNewDuration(10 * time.Second), + MaxDurationShouldAcceptFinalizedReport: config.MustNewDuration(5 * time.Second), + MaxDurationShouldTransmitAcceptedReport: config.MustNewDuration(10 * time.Second), } } @@ -1364,8 +1363,8 @@ func OffChainAggregatorV2ConfigWithNodes(numberNodes int, inflightExpiry time.Du if faultyNodes == 0 { faultyNodes = 1 } - if cfg.DeltaStage == 0 { - cfg.DeltaStage = inflightExpiry + if cfg.DeltaStage == nil { + cfg.DeltaStage = config.MustNewDuration(inflightExpiry) } return contracts.OffChainAggregatorV2Config{ DeltaProgress: cfg.DeltaProgress, @@ -1400,9 +1399,7 @@ func NewCommitOffchainConfig( ExecGasPriceDeviationPPB uint32, TokenPriceHeartBeat config.Duration, TokenPriceDeviationPPB uint32, - InflightCacheExpiry config.Duration, - _ bool, // TODO: priceReportingDisabled added after this merge -) (ccipconfig.OffchainConfig, error) { + InflightCacheExpiry config.Duration) (ccipconfig.OffchainConfig, error) { switch VersionMap[CommitStoreContract] { case Latest: return testhelpers.NewCommitOffchainConfig( @@ -1450,15 +1447,7 @@ func NewExecOnchainConfig( ) (abihelpers.AbiDefined, error) { switch VersionMap[OffRampContract] { case Latest: - return testhelpers.NewExecOnchainConfig( - PermissionLessExecutionThresholdSeconds, - Router, - PriceRegistry, - MaxNumberOfTokensPerMsg, - MaxDataBytes, - MaxPoolReleaseOrMintGas, // TODO: obsolete soon after this merge - 50_000, // TODO: MaxTokenTransferGas, obsolete soon after this merge - ), nil + return testhelpers.NewExecOnchainConfig(PermissionLessExecutionThresholdSeconds, Router, PriceRegistry, MaxNumberOfTokensPerMsg, MaxDataBytes), nil case V1_2_0: return testhelpers_1_4_0.NewExecOnchainConfig( PermissionLessExecutionThresholdSeconds, @@ -1565,20 +1554,20 @@ func NewOffChainAggregatorV2ConfigForCCIPPlugin[T ccipconfig.OffchainConfig]( } _, _, f_, onchainConfig_, offchainConfigVersion, offchainConfig, err = ocrconfighelper2.ContractSetConfigArgsForTests( - ocrConfig.DeltaProgress, - ocrConfig.DeltaResend, - ocrConfig.DeltaRound, - ocrConfig.DeltaGrace, - ocrConfig.DeltaStage, + ocrConfig.DeltaProgress.Duration(), + ocrConfig.DeltaResend.Duration(), + ocrConfig.DeltaRound.Duration(), + ocrConfig.DeltaGrace.Duration(), + ocrConfig.DeltaStage.Duration(), ocrConfig.RMax, ocrConfig.S, ocrConfig.Oracles, ocrConfig.ReportingPluginConfig, - ocrConfig.MaxDurationQuery, - ocrConfig.MaxDurationObservation, - ocrConfig.MaxDurationReport, - ocrConfig.MaxDurationShouldAcceptFinalizedReport, - ocrConfig.MaxDurationShouldTransmitAcceptedReport, + ocrConfig.MaxDurationQuery.Duration(), + ocrConfig.MaxDurationObservation.Duration(), + ocrConfig.MaxDurationReport.Duration(), + ocrConfig.MaxDurationShouldAcceptFinalizedReport.Duration(), + ocrConfig.MaxDurationShouldTransmitAcceptedReport.Duration(), ocrConfig.F, ocrConfig.OnchainConfig, ) From b30d6002eb8bb0e0b21cb927e43184ac15f87886 Mon Sep 17 00:00:00 2001 From: Ryan <80392855+RayXpub@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:50:37 +0400 Subject: [PATCH 189/432] Add missing type and version (#1243) ## Motivation `NonceManager` and `MultiAggregateRateLimiter` contracts were missing `typeAndVersion`. ## Solution Add `ITypeAndVersion` inheritance to both contracts. --- contracts/gas-snapshots/ccip.gas-snapshot | 57 ++++++++++--------- .../v0.8/ccip/MultiAggregateRateLimiter.sol | 5 +- contracts/src/v0.8/ccip/NonceManager.sol | 5 +- .../src/v0.8/ccip/test/NonceManager.t.sol | 13 +++++ .../MultiAggregateRateLimiter.t.sol | 1 + .../multi_aggregate_rate_limiter.go | 28 ++++++++- .../generated/nonce_manager/nonce_manager.go | 28 ++++++++- ...rapper-dependency-versions-do-not-edit.txt | 4 +- 8 files changed, 105 insertions(+), 36 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 1fdf7e27d9..9d31647634 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -142,8 +142,8 @@ EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15662) EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67195) EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59698) EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58778) -EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6394741) -EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 5977968) +EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6394807) +EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 5978034) EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106229) EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116228) EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106272) @@ -156,7 +156,7 @@ EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 227807) EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117527) EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77605) EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 207057) -EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6389130) +EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6389196) EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47785) EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 5980336) EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 157326) @@ -169,12 +169,12 @@ EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17280) EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1559406) EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 342924) EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 260178) -EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6445247) -EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6028193) +EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6445313) +EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6028259) EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 27681) EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 165181) EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 149137) -EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6807322) +EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6807388) EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17154) EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18413) EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249346) @@ -526,42 +526,42 @@ MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_UpdateExistingConfi MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_UpdateExistingConfig_Success() (gas: 53092) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_ZeroChainSelector_Revert() (gas: 17019) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_ZeroConfigs_Success() (gas: 12295) -MultiAggregateRateLimiter_constructor:test_ConstructorNoAuthorizedCallers_Success() (gas: 1971805) -MultiAggregateRateLimiter_constructor:test_Constructor_Success() (gas: 2085252) +MultiAggregateRateLimiter_constructor:test_ConstructorNoAuthorizedCallers_Success() (gas: 2006714) +MultiAggregateRateLimiter_constructor:test_Constructor_Success() (gas: 2122927) MultiAggregateRateLimiter_getTokenBucket:test_GetTokenBucket_Success() (gas: 30248) MultiAggregateRateLimiter_getTokenBucket:test_Refill_Success() (gas: 47358) MultiAggregateRateLimiter_getTokenBucket:test_TimeUnderflow_Revert() (gas: 15821) -MultiAggregateRateLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19668) -MultiAggregateRateLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21253) +MultiAggregateRateLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19690) +MultiAggregateRateLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21275) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 14527) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 189450) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 59927) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 189472) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 59949) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 17593) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitDisabled_Success() (gas: 44895) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExceeded_Revert() (gas: 50598) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78780) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 263510) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 263532) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54784) MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 9223372036854754743) MultiAggregateRateLimiter_onOutboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 19104) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 15778) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 189438) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 61662) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 189460) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 61684) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitDisabled_Success() (gas: 46683) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitExceeded_Revert() (gas: 52371) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitReset_Success() (gas: 79845) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 263724) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 263746) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokens_Success() (gas: 56541) -MultiAggregateRateLimiter_setPriceRegistry:test_OnlyOwner_Revert() (gas: 11336) -MultiAggregateRateLimiter_setPriceRegistry:test_Owner_Success() (gas: 19124) -MultiAggregateRateLimiter_setPriceRegistry:test_ZeroAddress_Revert() (gas: 10608) -MultiAggregateRateLimiter_updateRateLimitTokens:test_NonOwner_Revert() (gas: 16085) -MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensMultipleChains_Success() (gas: 225643) -MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensSingleChain_Success() (gas: 200192) -MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_AddsAndRemoves_Success() (gas: 162053) -MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_RemoveNonExistentToken_Success() (gas: 28509) -MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroDestToken_Revert() (gas: 17430) -MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroSourceToken_Revert() (gas: 17485) +MultiAggregateRateLimiter_setPriceRegistry:test_OnlyOwner_Revert() (gas: 11358) +MultiAggregateRateLimiter_setPriceRegistry:test_Owner_Success() (gas: 19146) +MultiAggregateRateLimiter_setPriceRegistry:test_ZeroAddress_Revert() (gas: 10630) +MultiAggregateRateLimiter_updateRateLimitTokens:test_NonOwner_Revert() (gas: 16107) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensMultipleChains_Success() (gas: 225533) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensSingleChain_Success() (gas: 200148) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_AddsAndRemoves_Success() (gas: 162036) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_RemoveNonExistentToken_Success() (gas: 28465) +MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroDestToken_Revert() (gas: 17452) +MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroSourceToken_Revert() (gas: 17507) MultiOCR3Base_setOCR3Configs:test_FMustBePositive_Revert() (gas: 59331) MultiOCR3Base_setOCR3Configs:test_FTooHigh_Revert() (gas: 44298) MultiOCR3Base_setOCR3Configs:test_RepeatSignerAddress_Revert() (gas: 283711) @@ -609,12 +609,13 @@ NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 237762) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 125923) -NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 122899) +NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 122943) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOffRamp_Revert() (gas: 42959) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRampAndOffRamp_Revert() (gas: 64282) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRamp_Revert() (gas: 42823) -NonceManager_applyPreviousRampsUpdates:test_SingleRampUpdate() (gas: 66548) +NonceManager_applyPreviousRampsUpdates:test_SingleRampUpdate() (gas: 66570) NonceManager_applyPreviousRampsUpdates:test_ZeroInput() (gas: 12025) +NonceManager_typeAndVersion:test_typeAndVersion() (gas: 9675) OCR2BaseNoChecks_setOCR2Config:test_FMustBePositive_Revert() (gas: 12171) OCR2BaseNoChecks_setOCR2Config:test_RepeatAddress_Revert() (gas: 42233) OCR2BaseNoChecks_setOCR2Config:test_SetConfigSuccess_gas() (gas: 84124) diff --git a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol index 2a9d087a26..4252d0defd 100644 --- a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol +++ b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; import {IMessageInterceptor} from "./interfaces/IMessageInterceptor.sol"; import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol"; @@ -17,7 +18,7 @@ import {EnumerableSet} from "./../vendor/openzeppelin-solidity/v4.7.3/contracts/ /// token transfers, using a price registry to convert to a numeraire asset (e.g. USD). /// The contract is a standalone multi-lane message validator contract, which can be called by authorized /// ramp contracts to apply rate limit changes to lanes, and revert when the rate limits get breached. -contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers { +contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, ITypeAndVersion { using RateLimiter for RateLimiter.TokenBucket; using USDPriceWith18Decimals for uint224; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; @@ -57,6 +58,8 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers { RateLimiter.TokenBucket outboundLaneBucket; // Bucket for the outbound lane (local -> remote) } + string public constant override typeAndVersion = "MultiAggregateRateLimiter 1.6.0-dev"; + /// @dev Tokens that should be included in Aggregate Rate Limiting (from local chain (this chain) -> remote), /// grouped per-remote chain. mapping(uint64 remoteChainSelector => EnumerableMapAddresses.AddressToBytes32Map tokensLocalToRemote) internal diff --git a/contracts/src/v0.8/ccip/NonceManager.sol b/contracts/src/v0.8/ccip/NonceManager.sol index 2cfcbbe9e2..de9b9ce4a3 100644 --- a/contracts/src/v0.8/ccip/NonceManager.sol +++ b/contracts/src/v0.8/ccip/NonceManager.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; import {IEVM2AnyOnRamp} from "./interfaces/IEVM2AnyOnRamp.sol"; import {INonceManager} from "./interfaces/INonceManager.sol"; @@ -8,7 +9,7 @@ import {AuthorizedCallers} from "../shared/access/AuthorizedCallers.sol"; /// @title NonceManager /// @notice NonceManager contract that manages sender nonces for the on/off ramps -contract NonceManager is INonceManager, AuthorizedCallers { +contract NonceManager is INonceManager, AuthorizedCallers, ITypeAndVersion { error PreviousRampAlreadySet(); event PreviousRampsUpdated(uint64 indexed remoteChainSelector, PreviousRamps prevRamp); @@ -27,6 +28,8 @@ contract NonceManager is INonceManager, AuthorizedCallers { PreviousRamps prevRamps; // Previous on/off ramps } + string public constant override typeAndVersion = "NonceManager 1.6.0-dev"; + /// @dev previous ramps mapping(uint64 chainSelector => PreviousRamps previousRamps) private s_previousRamps; /// @dev The current outbound nonce per sender used on the onramp diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol index 92ea1f221d..6ba08597ca 100644 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -18,6 +18,19 @@ import {EVM2EVMOnRampHelper} from "./helpers/EVM2EVMOnRampHelper.sol"; import {MockCommitStore} from "./mocks/MockCommitStore.sol"; import {EVM2EVMMultiOffRampSetup} from "./offRamp/EVM2EVMMultiOffRampSetup.t.sol"; import {EVM2EVMMultiOnRampSetup} from "./onRamp/EVM2EVMMultiOnRampSetup.t.sol"; +import {Test} from "forge-std/Test.sol"; + +contract NonceManager_typeAndVersion is Test { + NonceManager private s_nonceManager; + + function setUp() public { + s_nonceManager = new NonceManager(new address[](0)); + } + + function test_typeAndVersion() public { + assertEq(s_nonceManager.typeAndVersion(), "NonceManager 1.6.0-dev"); + } +} contract NonceManager_NonceIncrementation is BaseTest { NonceManager private s_nonceManager; diff --git a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol index 2bd31452f0..dd1698288b 100644 --- a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol +++ b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol @@ -136,6 +136,7 @@ contract MultiAggregateRateLimiter_constructor is MultiAggregateRateLimiterSetup assertEq(OWNER, s_rateLimiter.owner()); assertEq(address(s_priceRegistry), s_rateLimiter.getPriceRegistry()); + assertEq(s_rateLimiter.typeAndVersion(), "MultiAggregateRateLimiter 1.6.0-dev"); } } diff --git a/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go b/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go index 9fca2d1d36..910fbfb76f 100644 --- a/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go +++ b/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go @@ -87,8 +87,8 @@ type RateLimiterTokenBucket struct { } var MultiAggregateRateLimiterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"PriceRegistrySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"RateLimiterConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"remoteToken\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimiterConfigArgs[]\",\"name\":\"rateLimiterUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applyRateLimiterConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"}],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"localTokens\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"remoteTokens\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onInboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onOutboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"setPriceRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken\",\"name\":\"localTokenArgs\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"remoteToken\",\"type\":\"bytes32\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimitTokenArgs[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b5060405162002e2f38038062002e2f833981016040819052620000349162000538565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000102565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001ad565b50620000fa82620002fc565b50506200066f565b336001600160a01b038216036200015c5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b81518110156200023d576000828281518110620001d657620001d662000621565b60209081029190910101519050620001f060028262000378565b1562000233576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001b5565b50815160005b8151811015620002f657600082828151811062000264576200026462000621565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002a2576040516342bcdf7f60e11b815260040160405180910390fd5b620002af60028262000398565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000243565b50505050565b6001600160a01b03811662000324576040516342bcdf7f60e11b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b60006200038f836001600160a01b038416620003af565b90505b92915050565b60006200038f836001600160a01b038416620004b3565b60008181526001830160205260408120548015620004a8576000620003d660018362000637565b8554909150600090620003ec9060019062000637565b90508181146200045857600086600001828154811062000410576200041062000621565b906000526020600020015490508087600001848154811062000436576200043662000621565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200046c576200046c62000659565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000392565b600091505062000392565b6000818152600183016020526040812054620004fc5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000392565b50600062000392565b80516001600160a01b03811681146200051d57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200054c57600080fd5b620005578362000505565b602084810151919350906001600160401b03808211156200057757600080fd5b818601915086601f8301126200058c57600080fd5b815181811115620005a157620005a162000522565b8060051b604051601f19603f83011681018181108582111715620005c957620005c962000522565b604052918252848201925083810185019189831115620005e857600080fd5b938501935b828510156200061157620006018562000505565b84529385019392850192620005ed565b8096505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039257634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b6127b0806200067f6000396000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806379ba50971161008c57806391a2749a1161006657806391a2749a14610232578063e0a0e50614610245578063f2fde38b14610258578063fe843cd01461026b57600080fd5b806379ba5097146101f95780637c8b5e9a146102015780638da5cb5b1461021457600080fd5b80632451a627116100bd5780632451a627146101b0578063508ee9de146101c5578063537e304e146101d857600080fd5b806308d450a1146100e45780630a35bcc4146100f95780630d6c107e14610171575b600080fd5b6100f76100f2366004611ef5565b61027e565b005b61010c610107366004611fd5565b61029d565b604051610168919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60405180910390f35b60055473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610168565b6101b8610362565b604051610168919061205a565b6100f76101d336600461206d565b610373565b6101eb6101e6366004612088565b610384565b6040516101689291906120a3565b6100f76104e7565b6100f761020f3660046121c4565b6105e9565b60005473ffffffffffffffffffffffffffffffffffffffff1661018b565b6100f76102403660046122f5565b610838565b6100f7610253366004612386565b610849565b6100f761026636600461206d565b6108be565b6100f76102793660046123fb565b6108cf565b610286610c0e565b61029a816020015182608001516000610c53565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526103596102d58484610d2a565b6040805160a08101825282546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff16151593830193909352600190930154808316606083015292909204166080820152610d5a565b90505b92915050565b606061036e6002610e0c565b905090565b61037b610e20565b61029a81610ea1565b67ffffffffffffffff8116600090815260046020526040812060609182916103ab90610f67565b90508067ffffffffffffffff8111156103c6576103c6611c66565b6040519080825280602002602001820160405280156103ef578160200160208202803683370190505b5092508067ffffffffffffffff81111561040b5761040b611c66565b604051908082528060200260200182016040528015610434578160200160208202803683370190505b50915060005b818110156104e05767ffffffffffffffff8516600090815260046020526040812081906104679084610f72565b915091508186848151811061047e5761047e61252f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808584815181106104cb576104cb61252f565b6020908102919091010152505060010161043a565b5050915091565b60015473ffffffffffffffffffffffffffffffffffffffff16331461056d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6105f1610e20565b60005b82518110156106cf5760008382815181106106115761061161252f565b602002602001015160200151905060008483815181106106335761063361252f565b6020908102919091018101515167ffffffffffffffff81166000908152600490925260409091209091506106679083610f90565b156106c5576040805167ffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff841660208201527f530cabd30786b7235e124a6c0db77e0b685ef22813b1fe87554247f404eb8ed6910160405180910390a15b50506001016105f4565b5060005b81518110156108335760008282815181106106f0576106f061252f565b602002602001015160000151905060008383815181106107125761071261252f565b6020026020010151602001519050600082602001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610762575081155b15610799576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825167ffffffffffffffff811660009081526004602052604090206107bf908385610fb2565b15610824576040805167ffffffffffffffff831681526020810185905273ffffffffffffffffffffffffffffffffffffffff84168183015290517ffd96f5ca8894a9584abba5645131a95480f9340bd5e0046ceff789111ff16c6d9181900360600190a15b505050508060010190506106d3565b505050565b610840610e20565b61029a81610fdd565b610851610c0e565b6108ba82610862604084018461255e565b808060200260200160405190810160405280939291908181526020016000905b828210156108ae5761089f604083028601368190038101906125c6565b81526020019060010190610882565b50505050506001610c53565b5050565b6108c6610e20565b61029a81611169565b6108d7610e20565b60005b81518110156108ba5760008282815181106108f7576108f761252f565b6020908102919091010151604081015181519192509067ffffffffffffffff8116600003610951576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015160006109628383610d2a565b8054909150700100000000000000000000000000000000900463ffffffff16600003610bb0576040805160a081018252602080870180516fffffffffffffffffffffffffffffffff908116845263ffffffff421692840192909252875115158385015251811660608301529186015190911660808201528215610ac95767ffffffffffffffff8416600090815260066020908152604091829020835160028201805493860151948601516fffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009095169490941770010000000000000000000000000000000063ffffffff9096168602177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000941515949094029390931790925560608401516080850151908316921690920217600390910155610baa565b67ffffffffffffffff84166000908152600660209081526040918290208351815492850151938501516fffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff00000000000000000000000000000000000000009094169390931770010000000000000000000000000000000063ffffffff9095168502177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000093151593909302929092178155606084015160808501519083169216909202176001909101555b50610bba565b610bba818561125e565b8267ffffffffffffffff167ff14a5415ce6988a9e870a85fff0b9d7b7dd79bbc228cb63cad610daf6f7b6b978386604051610bf69291906125e2565b60405180910390a250505050508060010190506108da565b610c1960023361140d565b610c51576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610564565b565b6000610c5f8483610d2a565b805490915074010000000000000000000000000000000000000000900460ff1615610d24576000805b8451811015610d0f57610cd3858281518110610ca657610ca661252f565b6020908102919091018101515167ffffffffffffffff89166000908152600490925260409091209061143c565b15610d0757610cfa858281518110610ced57610ced61252f565b602002602001015161145e565b610d049083612655565b91505b600101610c88565b508015610d2257610d228282600061159a565b505b50505050565b67ffffffffffffffff821660009081526006602052604081208215610d5357600201905061035c565b905061035c565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152610de882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642610dcc9190612668565b85608001516fffffffffffffffffffffffffffffffff1661191d565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60606000610e1983611945565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610564565b73ffffffffffffffffffffffffffffffffffffffff8116610eee576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b600061035c826119a1565b6000808080610f8186866119ac565b909450925050505b9250929050565b60006103598373ffffffffffffffffffffffffffffffffffffffff84166119d7565b6000610fd58473ffffffffffffffffffffffffffffffffffffffff8516846119f4565b949350505050565b602081015160005b81518110156110785760008282815181106110025761100261252f565b60200260200101519050611020816002611a1190919063ffffffff16565b1561106f5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101610fe5565b50815160005b8151811015610d2457600082828151811061109b5761109b61252f565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361110b576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611116600282611a33565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010161107e565b3373ffffffffffffffffffffffffffffffffffffffff8216036111e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610564565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b815460009061128790700100000000000000000000000000000000900463ffffffff1642612668565b9050801561132957600183015483546112cf916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661191d565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461134f916fffffffffffffffffffffffffffffffff9081169116611a55565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061140090849061267b565b60405180910390a1505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610359565b60006103598373ffffffffffffffffffffffffffffffffffffffff8416611a6b565b60055481516040517fd02641a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526000928392169063d02641a0906024016040805180830381865afa1580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f691906126b7565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660000361156c5782516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610564565b6020830151610e19907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690611a77565b825474010000000000000000000000000000000000000000900460ff1615806115c1575081155b156115cb57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061161190700100000000000000000000000000000000900463ffffffff1642612668565b905080156116d15781831115611653576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461168d9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661191d565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156117885773ffffffffffffffffffffffffffffffffffffffff8416611730576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610564565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610564565b8483101561189b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906117cc9082612668565b6117d6878a612668565b6117e09190612655565b6117ea9190612722565b905073ffffffffffffffffffffffffffffffffffffffff8616611843576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610564565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610564565b6118a58584612668565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600061193c8561192d848661275d565b6119379087612655565b611a55565b95945050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561199557602002820191906000526020600020905b815481526020019060010190808311611981575b50505050509050919050565b600061035c82611ab4565b600080806119ba8585611abe565b600081815260029690960160205260409095205494959350505050565b600081815260028301602052604081208190556103598383611aca565b60008281526002840160205260408120829055610fd58484611ad6565b60006103598373ffffffffffffffffffffffffffffffffffffffff8416611ae2565b60006103598373ffffffffffffffffffffffffffffffffffffffff8416611bd5565b6000818310611a645781610359565b5090919050565b60006103598383611c24565b6000670de0b6b3a7640000611aaa837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff861661275d565b6103599190612722565b600061035c825490565b60006103598383611c3c565b60006103598383611ae2565b60006103598383611bd5565b60008181526001830160205260408120548015611bcb576000611b06600183612668565b8554909150600090611b1a90600190612668565b9050818114611b7f576000866000018281548110611b3a57611b3a61252f565b9060005260206000200154905080876000018481548110611b5d57611b5d61252f565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611b9057611b90612774565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061035c565b600091505061035c565b6000818152600183016020526040812054611c1c5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561035c565b50600061035c565b60008181526001830160205260408120541515610359565b6000826000018281548110611c5357611c5361252f565b9060005260206000200154905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611cb857611cb8611c66565b60405290565b60405160a0810167ffffffffffffffff81118282101715611cb857611cb8611c66565b6040516060810167ffffffffffffffff81118282101715611cb857611cb8611c66565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d4b57611d4b611c66565b604052919050565b803567ffffffffffffffff81168114611d6b57600080fd5b919050565b600082601f830112611d8157600080fd5b813567ffffffffffffffff811115611d9b57611d9b611c66565b611dcc60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611d04565b818152846020838601011115611de157600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115611e1857611e18611c66565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d6b57600080fd5b600060408284031215611e5857600080fd5b611e60611c95565b9050611e6b82611e22565b81526020820135602082015292915050565b600082601f830112611e8e57600080fd5b81356020611ea3611e9e83611dfe565b611d04565b8083825260208201915060208460061b870101935086841115611ec557600080fd5b602086015b84811015611eea57611edc8882611e46565b835291830191604001611eca565b509695505050505050565b600060208284031215611f0757600080fd5b813567ffffffffffffffff80821115611f1f57600080fd5b9083019060a08286031215611f3357600080fd5b611f3b611cbe565b82358152611f4b60208401611d53565b6020820152604083013582811115611f6257600080fd5b611f6e87828601611d70565b604083015250606083013582811115611f8657600080fd5b611f9287828601611d70565b606083015250608083013582811115611faa57600080fd5b611fb687828601611e7d565b60808301525095945050505050565b80358015158114611d6b57600080fd5b60008060408385031215611fe857600080fd5b611ff183611d53565b9150611fff60208401611fc5565b90509250929050565b60008151808452602080850194506020840160005b8381101561204f57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161201d565b509495945050505050565b6020815260006103596020830184612008565b60006020828403121561207f57600080fd5b61035982611e22565b60006020828403121561209a57600080fd5b61035982611d53565b6040815260006120b66040830185612008565b82810360208481019190915284518083528582019282019060005b818110156120ed578451835293830193918301916001016120d1565b5090979650505050505050565b60006040828403121561210c57600080fd5b612114611c95565b905061211f82611d53565b815261212d60208301611e22565b602082015292915050565b600082601f83011261214957600080fd5b81356020612159611e9e83611dfe565b80838252602082019150606060206060860288010194508785111561217d57600080fd5b602087015b858110156120ed5781818a03121561219a5760008081fd5b6121a2611c95565b6121ac8a836120fa565b81526040820135868201528452928401928101612182565b60008060408084860312156121d857600080fd5b833567ffffffffffffffff808211156121f057600080fd5b818601915086601f83011261220457600080fd5b81356020612214611e9e83611dfe565b8083825260208201915060208460061b87010193508a84111561223657600080fd5b6020860195505b8386101561225e5761224f8b876120fa565b8252948601949082019061223d565b9750505050602086013592508083111561227757600080fd5b505061228585828601612138565b9150509250929050565b600082601f8301126122a057600080fd5b813560206122b0611e9e83611dfe565b8083825260208201915060208460051b8701019350868411156122d257600080fd5b602086015b84811015611eea576122e881611e22565b83529183019183016122d7565b60006020828403121561230757600080fd5b813567ffffffffffffffff8082111561231f57600080fd5b908301906040828603121561233357600080fd5b61233b611c95565b82358281111561234a57600080fd5b6123568782860161228f565b82525060208301358281111561236b57600080fd5b6123778782860161228f565b60208301525095945050505050565b6000806040838503121561239957600080fd5b6123a283611d53565b9150602083013567ffffffffffffffff8111156123be57600080fd5b830160a081860312156123d057600080fd5b809150509250929050565b80356fffffffffffffffffffffffffffffffff81168114611d6b57600080fd5b6000602080838503121561240e57600080fd5b823567ffffffffffffffff81111561242557600080fd5b8301601f8101851361243657600080fd5b8035612444611e9e82611dfe565b81815260a0918202830184019184820191908884111561246357600080fd5b938501935b8385101561252357848903818112156124815760008081fd5b612489611ce1565b61249287611d53565b815261249f888801611fc5565b8882015260406060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0850112156124d75760008081fd5b6124df611ce1565b93506124ec828a01611fc5565b84526124f9818a016123db565b8a8501525061250a608089016123db565b8382015281019190915283529384019391850191612468565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261259357600080fd5b83018035915067ffffffffffffffff8211156125ae57600080fd5b6020019150600681901b3603821315610f8957600080fd5b6000604082840312156125d857600080fd5b6103598383611e46565b821515815260808101610e1960208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561035c5761035c612626565b8181038181111561035c5761035c612626565b6060810161035c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000604082840312156126c957600080fd5b6126d1611c95565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146126fd57600080fd5b8152602083015163ffffffff8116811461271657600080fd5b60208201529392505050565b600082612758577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761035c5761035c612626565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"PriceRegistrySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"RateLimiterConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"remoteToken\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimiterConfigArgs[]\",\"name\":\"rateLimiterUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applyRateLimiterConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"}],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"localTokens\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"remoteTokens\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onInboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onOutboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"setPriceRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken\",\"name\":\"localTokenArgs\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"remoteToken\",\"type\":\"bytes32\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimitTokenArgs[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b5060405162002efb38038062002efb833981016040819052620000349162000538565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000102565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001ad565b50620000fa82620002fc565b50506200066f565b336001600160a01b038216036200015c5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b81518110156200023d576000828281518110620001d657620001d662000621565b60209081029190910101519050620001f060028262000378565b1562000233576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001b5565b50815160005b8151811015620002f657600082828151811062000264576200026462000621565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002a2576040516342bcdf7f60e11b815260040160405180910390fd5b620002af60028262000398565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000243565b50505050565b6001600160a01b03811662000324576040516342bcdf7f60e11b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b60006200038f836001600160a01b038416620003af565b90505b92915050565b60006200038f836001600160a01b038416620004b3565b60008181526001830160205260408120548015620004a8576000620003d660018362000637565b8554909150600090620003ec9060019062000637565b90508181146200045857600086600001828154811062000410576200041062000621565b906000526020600020015490508087600001848154811062000436576200043662000621565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200046c576200046c62000659565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000392565b600091505062000392565b6000818152600183016020526040812054620004fc5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000392565b50600062000392565b80516001600160a01b03811681146200051d57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200054c57600080fd5b620005578362000505565b602084810151919350906001600160401b03808211156200057757600080fd5b818601915086601f8301126200058c57600080fd5b815181811115620005a157620005a162000522565b8060051b604051601f19603f83011681018181108582111715620005c957620005c962000522565b604052918252848201925083810185019189831115620005e857600080fd5b938501935b828510156200061157620006018562000505565b84529385019392850192620005ed565b8096505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039257634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b61287c806200067f6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379ba50971161008c57806391a2749a1161006657806391a2749a14610252578063e0a0e50614610265578063f2fde38b14610278578063fe843cd01461028b57600080fd5b806379ba5097146102195780637c8b5e9a146102215780638da5cb5b1461023457600080fd5b8063181f5a77116100c8578063181f5a77146101bb5780632451a627146101d0578063508ee9de146101e5578063537e304e146101f857600080fd5b806308d450a1146100ef5780630a35bcc4146101045780630d6c107e1461017c575b600080fd5b6101026100fd366004611f31565b61029e565b005b610117610112366004612011565b6102bd565b604051610173919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60405180910390f35b60055473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b6101c3610382565b6040516101739190612044565b6101d861039e565b6040516101739190612103565b6101026101f3366004612116565b6103af565b61020b610206366004612131565b6103c0565b60405161017392919061214c565b610102610523565b61010261022f36600461226d565b610625565b60005473ffffffffffffffffffffffffffffffffffffffff16610196565b61010261026036600461239e565b610874565b61010261027336600461242f565b610885565b610102610286366004612116565b6108fa565b6101026102993660046124a4565b61090b565b6102a6610c4a565b6102ba816020015182608001516000610c8f565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526103796102f58484610d66565b6040805160a08101825282546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff16151593830193909352600190930154808316606083015292909204166080820152610d96565b90505b92915050565b60405180606001604052806023815260200161284d6023913981565b60606103aa6002610e48565b905090565b6103b7610e5c565b6102ba81610edd565b67ffffffffffffffff8116600090815260046020526040812060609182916103e790610fa3565b90508067ffffffffffffffff81111561040257610402611ca2565b60405190808252806020026020018201604052801561042b578160200160208202803683370190505b5092508067ffffffffffffffff81111561044757610447611ca2565b604051908082528060200260200182016040528015610470578160200160208202803683370190505b50915060005b8181101561051c5767ffffffffffffffff8516600090815260046020526040812081906104a39084610fae565b91509150818684815181106104ba576104ba6125d8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080858481518110610507576105076125d8565b60209081029190910101525050600101610476565b5050915091565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61062d610e5c565b60005b825181101561070b57600083828151811061064d5761064d6125d8565b6020026020010151602001519050600084838151811061066f5761066f6125d8565b6020908102919091018101515167ffffffffffffffff81166000908152600490925260409091209091506106a39083610fcc565b15610701576040805167ffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff841660208201527f530cabd30786b7235e124a6c0db77e0b685ef22813b1fe87554247f404eb8ed6910160405180910390a15b5050600101610630565b5060005b815181101561086f57600082828151811061072c5761072c6125d8565b6020026020010151600001519050600083838151811061074e5761074e6125d8565b6020026020010151602001519050600082602001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061079e575081155b156107d5576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825167ffffffffffffffff811660009081526004602052604090206107fb908385610fee565b15610860576040805167ffffffffffffffff831681526020810185905273ffffffffffffffffffffffffffffffffffffffff84168183015290517ffd96f5ca8894a9584abba5645131a95480f9340bd5e0046ceff789111ff16c6d9181900360600190a15b5050505080600101905061070f565b505050565b61087c610e5c565b6102ba81611019565b61088d610c4a565b6108f68261089e6040840184612607565b808060200260200160405190810160405280939291908181526020016000905b828210156108ea576108db6040830286013681900381019061266f565b815260200190600101906108be565b50505050506001610c8f565b5050565b610902610e5c565b6102ba816111a5565b610913610e5c565b60005b81518110156108f6576000828281518110610933576109336125d8565b6020908102919091010151604081015181519192509067ffffffffffffffff811660000361098d576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020830151600061099e8383610d66565b8054909150700100000000000000000000000000000000900463ffffffff16600003610bec576040805160a081018252602080870180516fffffffffffffffffffffffffffffffff908116845263ffffffff421692840192909252875115158385015251811660608301529186015190911660808201528215610b055767ffffffffffffffff8416600090815260066020908152604091829020835160028201805493860151948601516fffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009095169490941770010000000000000000000000000000000063ffffffff9096168602177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000941515949094029390931790925560608401516080850151908316921690920217600390910155610be6565b67ffffffffffffffff84166000908152600660209081526040918290208351815492850151938501516fffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff00000000000000000000000000000000000000009094169390931770010000000000000000000000000000000063ffffffff9095168502177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000093151593909302929092178155606084015160808501519083169216909202176001909101555b50610bf6565b610bf6818561129a565b8267ffffffffffffffff167ff14a5415ce6988a9e870a85fff0b9d7b7dd79bbc228cb63cad610daf6f7b6b978386604051610c3292919061268b565b60405180910390a25050505050806001019050610916565b610c55600233611449565b610c8d576040517fd86ad9cf0000000000000000000000000000000000000000000000000000000081523360048201526024016105a0565b565b6000610c9b8483610d66565b805490915074010000000000000000000000000000000000000000900460ff1615610d60576000805b8451811015610d4b57610d0f858281518110610ce257610ce26125d8565b6020908102919091018101515167ffffffffffffffff891660009081526004909252604090912090611478565b15610d4357610d36858281518110610d2957610d296125d8565b602002602001015161149a565b610d4090836126fe565b91505b600101610cc4565b508015610d5e57610d5e828260006115d6565b505b50505050565b67ffffffffffffffff821660009081526006602052604081208215610d8f57600201905061037c565b905061037c565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152610e2482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642610e089190612711565b85608001516fffffffffffffffffffffffffffffffff16611959565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60606000610e5583611981565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105a0565b73ffffffffffffffffffffffffffffffffffffffff8116610f2a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b600061037c826119dd565b6000808080610fbd86866119e8565b909450925050505b9250929050565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611a13565b60006110118473ffffffffffffffffffffffffffffffffffffffff851684611a30565b949350505050565b602081015160005b81518110156110b457600082828151811061103e5761103e6125d8565b6020026020010151905061105c816002611a4d90919063ffffffff16565b156110ab5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101611021565b50815160005b8151811015610d605760008282815181106110d7576110d76125d8565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611147576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611152600282611a6f565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016110ba565b3373ffffffffffffffffffffffffffffffffffffffff821603611224576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105a0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b81546000906112c390700100000000000000000000000000000000900463ffffffff1642612711565b90508015611365576001830154835461130b916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416611959565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461138b916fffffffffffffffffffffffffffffffff9081169116611a91565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061143c908490612724565b60405180910390a1505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610379565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611aa7565b60055481516040517fd02641a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526000928392169063d02641a0906024016040805180830381865afa15801561150e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115329190612760565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036115a85782516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016105a0565b6020830151610e55907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690611ab3565b825474010000000000000000000000000000000000000000900460ff1615806115fd575081155b1561160757505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061164d90700100000000000000000000000000000000900463ffffffff1642612711565b9050801561170d578183111561168f576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546116c99083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16611959565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156117c45773ffffffffffffffffffffffffffffffffffffffff841661176c576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016105a0565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016105a0565b848310156118d75760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906118089082612711565b611812878a612711565b61181c91906126fe565b61182691906127cb565b905073ffffffffffffffffffffffffffffffffffffffff861661187f576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016105a0565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016105a0565b6118e18584612711565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000611978856119698486612806565b61197390876126fe565b611a91565b95945050505050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156119d157602002820191906000526020600020905b8154815260200190600101908083116119bd575b50505050509050919050565b600061037c82611af0565b600080806119f68585611afa565b600081815260029690960160205260409095205494959350505050565b600081815260028301602052604081208190556103798383611b06565b600082815260028401602052604081208290556110118484611b12565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611b1e565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611c11565b6000818310611aa05781610379565b5090919050565b60006103798383611c60565b6000670de0b6b3a7640000611ae6837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616612806565b61037991906127cb565b600061037c825490565b60006103798383611c78565b60006103798383611b1e565b60006103798383611c11565b60008181526001830160205260408120548015611c07576000611b42600183612711565b8554909150600090611b5690600190612711565b9050818114611bbb576000866000018281548110611b7657611b766125d8565b9060005260206000200154905080876000018481548110611b9957611b996125d8565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611bcc57611bcc61281d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061037c565b600091505061037c565b6000818152600183016020526040812054611c585750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561037c565b50600061037c565b60008181526001830160205260408120541515610379565b6000826000018281548110611c8f57611c8f6125d8565b9060005260206000200154905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611cf457611cf4611ca2565b60405290565b60405160a0810167ffffffffffffffff81118282101715611cf457611cf4611ca2565b6040516060810167ffffffffffffffff81118282101715611cf457611cf4611ca2565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d8757611d87611ca2565b604052919050565b803567ffffffffffffffff81168114611da757600080fd5b919050565b600082601f830112611dbd57600080fd5b813567ffffffffffffffff811115611dd757611dd7611ca2565b611e0860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611d40565b818152846020838601011115611e1d57600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115611e5457611e54611ca2565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff81168114611da757600080fd5b600060408284031215611e9457600080fd5b611e9c611cd1565b9050611ea782611e5e565b81526020820135602082015292915050565b600082601f830112611eca57600080fd5b81356020611edf611eda83611e3a565b611d40565b8083825260208201915060208460061b870101935086841115611f0157600080fd5b602086015b84811015611f2657611f188882611e82565b835291830191604001611f06565b509695505050505050565b600060208284031215611f4357600080fd5b813567ffffffffffffffff80821115611f5b57600080fd5b9083019060a08286031215611f6f57600080fd5b611f77611cfa565b82358152611f8760208401611d8f565b6020820152604083013582811115611f9e57600080fd5b611faa87828601611dac565b604083015250606083013582811115611fc257600080fd5b611fce87828601611dac565b606083015250608083013582811115611fe657600080fd5b611ff287828601611eb9565b60808301525095945050505050565b80358015158114611da757600080fd5b6000806040838503121561202457600080fd5b61202d83611d8f565b915061203b60208401612001565b90509250929050565b60006020808352835180602085015260005b8181101561207257858101830151858201604001528201612056565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60008151808452602080850194506020840160005b838110156120f857815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016120c6565b509495945050505050565b60208152600061037960208301846120b1565b60006020828403121561212857600080fd5b61037982611e5e565b60006020828403121561214357600080fd5b61037982611d8f565b60408152600061215f60408301856120b1565b82810360208481019190915284518083528582019282019060005b818110156121965784518352938301939183019160010161217a565b5090979650505050505050565b6000604082840312156121b557600080fd5b6121bd611cd1565b90506121c882611d8f565b81526121d660208301611e5e565b602082015292915050565b600082601f8301126121f257600080fd5b81356020612202611eda83611e3a565b80838252602082019150606060206060860288010194508785111561222657600080fd5b602087015b858110156121965781818a0312156122435760008081fd5b61224b611cd1565b6122558a836121a3565b8152604082013586820152845292840192810161222b565b600080604080848603121561228157600080fd5b833567ffffffffffffffff8082111561229957600080fd5b818601915086601f8301126122ad57600080fd5b813560206122bd611eda83611e3a565b8083825260208201915060208460061b87010193508a8411156122df57600080fd5b6020860195505b83861015612307576122f88b876121a3565b825294860194908201906122e6565b9750505050602086013592508083111561232057600080fd5b505061232e858286016121e1565b9150509250929050565b600082601f83011261234957600080fd5b81356020612359611eda83611e3a565b8083825260208201915060208460051b87010193508684111561237b57600080fd5b602086015b84811015611f265761239181611e5e565b8352918301918301612380565b6000602082840312156123b057600080fd5b813567ffffffffffffffff808211156123c857600080fd5b90830190604082860312156123dc57600080fd5b6123e4611cd1565b8235828111156123f357600080fd5b6123ff87828601612338565b82525060208301358281111561241457600080fd5b61242087828601612338565b60208301525095945050505050565b6000806040838503121561244257600080fd5b61244b83611d8f565b9150602083013567ffffffffffffffff81111561246757600080fd5b830160a0818603121561247957600080fd5b809150509250929050565b80356fffffffffffffffffffffffffffffffff81168114611da757600080fd5b600060208083850312156124b757600080fd5b823567ffffffffffffffff8111156124ce57600080fd5b8301601f810185136124df57600080fd5b80356124ed611eda82611e3a565b81815260a0918202830184019184820191908884111561250c57600080fd5b938501935b838510156125cc578489038181121561252a5760008081fd5b612532611d1d565b61253b87611d8f565b8152612548888801612001565b8882015260406060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0850112156125805760008081fd5b612588611d1d565b9350612595828a01612001565b84526125a2818a01612484565b8a850152506125b360808901612484565b8382015281019190915283529384019391850191612511565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261263c57600080fd5b83018035915067ffffffffffffffff82111561265757600080fd5b6020019150600681901b3603821315610fc557600080fd5b60006040828403121561268157600080fd5b6103798383611e82565b821515815260808101610e5560208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561037c5761037c6126cf565b8181038181111561037c5761037c6126cf565b6060810161037c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006040828403121561277257600080fd5b61277a611cd1565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146127a657600080fd5b8152602083015163ffffffff811681146127bf57600080fd5b60208201529392505050565b600082612801577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761037c5761037c6126cf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe4d756c7469416767726567617465526174654c696d6974657220312e362e302d646576a164736f6c6343000818000a", } var MultiAggregateRateLimiterABI = MultiAggregateRateLimiterMetaData.ABI @@ -345,6 +345,28 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerSession) Owner( return _MultiAggregateRateLimiter.Contract.Owner(&_MultiAggregateRateLimiter.CallOpts) } +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _MultiAggregateRateLimiter.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) TypeAndVersion() (string, error) { + return _MultiAggregateRateLimiter.Contract.TypeAndVersion(&_MultiAggregateRateLimiter.CallOpts) +} + +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerSession) TypeAndVersion() (string, error) { + return _MultiAggregateRateLimiter.Contract.TypeAndVersion(&_MultiAggregateRateLimiter.CallOpts) +} + func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { return _MultiAggregateRateLimiter.contract.Transact(opts, "acceptOwnership") } @@ -1754,6 +1776,8 @@ type MultiAggregateRateLimiterInterface interface { Owner(opts *bind.CallOpts) (common.Address, error) + TypeAndVersion(opts *bind.CallOpts) (string, error) + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go b/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go index 14979b4fe3..b93daf75c3 100644 --- a/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go +++ b/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go @@ -46,8 +46,8 @@ type NonceManagerPreviousRampsArgs struct { } var NonceManagerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"PreviousRampAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"prevRamp\",\"type\":\"tuple\"}],\"name\":\"PreviousRampsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"}],\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"prevRamps\",\"type\":\"tuple\"}],\"internalType\":\"structNonceManager.PreviousRampsArgs[]\",\"name\":\"previousRampsArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPreviousRampsUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"getInboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getIncrementedOutboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getOutboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getPreviousRamps\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"}],\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expectedNonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"incrementInboundNonce\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b5060405162001ad538038062001ad58339810160408190526200003491620004b0565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620000f6565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001a1565b5050620005d0565b336001600160a01b03821603620001505760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000231576000828281518110620001ca57620001ca62000582565b60209081029190910101519050620001e4600282620002f0565b1562000227576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001a9565b50815160005b8151811015620002ea57600082828151811062000258576200025862000582565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000296576040516342bcdf7f60e11b815260040160405180910390fd5b620002a360028262000310565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000237565b50505050565b600062000307836001600160a01b03841662000327565b90505b92915050565b600062000307836001600160a01b0384166200042b565b60008181526001830160205260408120548015620004205760006200034e60018362000598565b8554909150600090620003649060019062000598565b9050818114620003d057600086600001828154811062000388576200038862000582565b9060005260206000200154905080876000018481548110620003ae57620003ae62000582565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620003e457620003e4620005ba565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200030a565b60009150506200030a565b600081815260018301602052604081205462000474575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200030a565b5060006200030a565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b0381168114620004ab57600080fd5b919050565b60006020808385031215620004c457600080fd5b82516001600160401b0380821115620004dc57600080fd5b818501915085601f830112620004f157600080fd5b8151818111156200050657620005066200047d565b8060051b604051601f19603f830116810181811085821117156200052e576200052e6200047d565b6040529182528482019250838101850191888311156200054d57600080fd5b938501935b828510156200057657620005668562000493565b8452938501939285019262000552565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200030a57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b6114f580620005e06000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c806391a2749a11610081578063e0e03cae1161005b578063e0e03cae14610228578063ea458c0c1461024b578063f2fde38b1461025e57600080fd5b806391a2749a146101d6578063bf18402a146101e9578063c92236251461021557600080fd5b806379ba5097116100b257806379ba50971461019157806384d8acf71461019b5780638da5cb5b146101ae57600080fd5b80632451a627146100ce578063294b5630146100ec575b600080fd5b6100d6610271565b6040516100e39190610f2e565b60405180910390f35b61015d6100fa366004610f9e565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600460209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff9081168452600190910154169082015290565b60408051825173ffffffffffffffffffffffffffffffffffffffff90811682526020938401511692810192909252016100e3565b610199610282565b005b6101996101a9366004610fbb565b610384565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e3565b6101996101e4366004611146565b610560565b6101fc6101f73660046111ed565b610574565b60405167ffffffffffffffff90911681526020016100e3565b6101fc61022336600461126f565b610589565b61023b6102363660046112c4565b6105a0565b60405190151581526020016100e3565b6101fc6102593660046111ed565b6106a9565b61019961026c366004611329565b61073d565b606061027d600261074e565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314610308576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61038c61075b565b60005b8181101561055b57368383838181106103aa576103aa611346565b606002919091019150600090506004816103c76020850185610f9e565b67ffffffffffffffff1681526020810191909152604001600020805490915073ffffffffffffffffffffffffffffffffffffffff161515806104225750600181015473ffffffffffffffffffffffffffffffffffffffff1615155b15610459576040517fc6117ae200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104696040830160208401611329565b81547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff919091161781556104b96060830160408401611329565b6001820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561050d6020830183610f9e565b67ffffffffffffffff167fa2e43edcbc4fd175ae4bebbe3fd6139871ed1f1783cd4a1ace59b90d302c3319836020016040516105499190611375565b60405180910390a2505060010161038f565b505050565b61056861075b565b610571816107de565b50565b60006105808383610970565b90505b92915050565b6000610596848484610a8d565b90505b9392505050565b60006105aa610bde565b60006105b7868585610a8d565b6105c29060016113ec565b90508467ffffffffffffffff168167ffffffffffffffff1614610626577f606ff8179e5e3c059b82df931acc496b7b6053e8879042f8267f930e0595f69f86868686604051610614949392919061140d565b60405180910390a160009150506106a1565b67ffffffffffffffff86166000908152600660205260409081902090518291906106539087908790611479565b908152604051908190036020019020805467ffffffffffffffff929092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090921691909117905550600190505b949350505050565b60006106b3610bde565b60006106bf8484610970565b6106ca9060016113ec565b67ffffffffffffffff808616600090815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff89168452909152902080549183167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090921691909117905591505092915050565b61074561075b565b61057181610c21565b6060600061059983610d16565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102ff565b565b602081015160005b815181101561087957600082828151811061080357610803611346565b60200260200101519050610821816002610d7290919063ffffffff16565b156108705760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b506001016107e6565b50815160005b815181101561096a57600082828151811061089c5761089c611346565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361090c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610917600282610d94565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010161087f565b50505050565b67ffffffffffffffff808316600090815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120549091168082036105805767ffffffffffffffff841660009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff168015610a85576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015282169063856c824790602401602060405180830381865afa158015610a58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7c9190611489565b92505050610583565b509392505050565b67ffffffffffffffff83166000908152600660205260408082209051829190610ab99086908690611479565b9081526040519081900360200190205467ffffffffffffffff16905060008190036105965767ffffffffffffffff851660009081526004602052604090206001015473ffffffffffffffffffffffffffffffffffffffff168015610bd55773ffffffffffffffffffffffffffffffffffffffff811663856c8247610b3f86880188611329565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401602060405180830381865afa158015610ba8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bcc9190611489565b92505050610599565b50949350505050565b610be9600233610db6565b6107dc576040517fd86ad9cf0000000000000000000000000000000000000000000000000000000081523360048201526024016102ff565b3373ffffffffffffffffffffffffffffffffffffffff821603610ca0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102ff565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b606081600001805480602002602001604051908101604052809291908181526020018280548015610d6657602002820191906000526020600020905b815481526020019060010190808311610d52575b50505050509050919050565b60006105808373ffffffffffffffffffffffffffffffffffffffff8416610de5565b60006105808373ffffffffffffffffffffffffffffffffffffffff8416610edf565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610580565b60008181526001830160205260408120548015610ece576000610e096001836114a6565b8554909150600090610e1d906001906114a6565b9050818114610e82576000866000018281548110610e3d57610e3d611346565b9060005260206000200154905080876000018481548110610e6057610e60611346565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610e9357610e936114b9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610583565b6000915050610583565b5092915050565b6000818152600183016020526040812054610f2657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610583565b506000610583565b6020808252825182820181905260009190848201906040850190845b81811015610f7c57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610f4a565b50909695505050505050565b67ffffffffffffffff8116811461057157600080fd5b600060208284031215610fb057600080fd5b813561058081610f88565b60008060208385031215610fce57600080fd5b823567ffffffffffffffff80821115610fe657600080fd5b818501915085601f830112610ffa57600080fd5b81358181111561100957600080fd5b86602060608302850101111561101e57600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461057157600080fd5b600082601f83011261109257600080fd5b8135602067ffffffffffffffff808311156110af576110af611030565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811084821117156110f2576110f2611030565b604052938452602081870181019490810192508785111561111257600080fd5b6020870191505b8482101561113b57813561112c8161105f565b83529183019190830190611119565b979650505050505050565b60006020828403121561115857600080fd5b813567ffffffffffffffff8082111561117057600080fd5b908301906040828603121561118457600080fd5b60405160408101818110838211171561119f5761119f611030565b6040528235828111156111b157600080fd5b6111bd87828601611081565b8252506020830135828111156111d257600080fd5b6111de87828601611081565b60208301525095945050505050565b6000806040838503121561120057600080fd5b823561120b81610f88565b9150602083013561121b8161105f565b809150509250929050565b60008083601f84011261123857600080fd5b50813567ffffffffffffffff81111561125057600080fd5b60208301915083602082850101111561126857600080fd5b9250929050565b60008060006040848603121561128457600080fd5b833561128f81610f88565b9250602084013567ffffffffffffffff8111156112ab57600080fd5b6112b786828701611226565b9497909650939450505050565b600080600080606085870312156112da57600080fd5b84356112e581610f88565b935060208501356112f581610f88565b9250604085013567ffffffffffffffff81111561131157600080fd5b61131d87828801611226565b95989497509550505050565b60006020828403121561133b57600080fd5b81356105808161105f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040810182356113848161105f565b73ffffffffffffffffffffffffffffffffffffffff90811683526020840135906113ad8261105f565b8082166020850152505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff818116838216019080821115610ed857610ed86113bd565b600067ffffffffffffffff8087168352808616602084015250606060408301528260608301528284608084013760006080848401015260807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905095945050505050565b8183823760009101908152919050565b60006020828403121561149b57600080fd5b815161058081610f88565b81810381811115610583576105836113bd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"PreviousRampAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"prevRamp\",\"type\":\"tuple\"}],\"name\":\"PreviousRampsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"}],\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"prevRamps\",\"type\":\"tuple\"}],\"internalType\":\"structNonceManager.PreviousRampsArgs[]\",\"name\":\"previousRampsArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPreviousRampsUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"getInboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getIncrementedOutboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getOutboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getPreviousRamps\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"}],\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expectedNonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"incrementInboundNonce\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b5060405162001b9638038062001b968339810160408190526200003491620004b0565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620000f6565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001a1565b5050620005d0565b336001600160a01b03821603620001505760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000231576000828281518110620001ca57620001ca62000582565b60209081029190910101519050620001e4600282620002f0565b1562000227576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001a9565b50815160005b8151811015620002ea57600082828151811062000258576200025862000582565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000296576040516342bcdf7f60e11b815260040160405180910390fd5b620002a360028262000310565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000237565b50505050565b600062000307836001600160a01b03841662000327565b90505b92915050565b600062000307836001600160a01b0384166200042b565b60008181526001830160205260408120548015620004205760006200034e60018362000598565b8554909150600090620003649060019062000598565b9050818114620003d057600086600001828154811062000388576200038862000582565b9060005260206000200154905080876000018481548110620003ae57620003ae62000582565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620003e457620003e4620005ba565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200030a565b60009150506200030a565b600081815260018301602052604081205462000474575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200030a565b5060006200030a565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b0381168114620004ab57600080fd5b919050565b60006020808385031215620004c457600080fd5b82516001600160401b0380821115620004dc57600080fd5b818501915085601f830112620004f157600080fd5b8151818111156200050657620005066200047d565b8060051b604051601f19603f830116810181811085821117156200052e576200052e6200047d565b6040529182528482019250838101850191888311156200054d57600080fd5b938501935b828510156200057657620005668562000493565b8452938501939285019262000552565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200030a57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b6115b680620005e06000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806391a2749a11610081578063e0e03cae1161005b578063e0e03cae1461027c578063ea458c0c1461029f578063f2fde38b146102b257600080fd5b806391a2749a1461022a578063bf18402a1461023d578063c92236251461026957600080fd5b806379ba5097116100b257806379ba5097146101e557806384d8acf7146101ef5780638da5cb5b1461020257600080fd5b8063181f5a77146100d95780632451a6271461012b578063294b563014610140575b600080fd5b6101156040518060400160405280601681526020017f4e6f6e63654d616e6167657220312e362e302d6465760000000000000000000081525081565b6040516101229190610f82565b60405180910390f35b6101336102c5565b6040516101229190610fef565b6101b161014e36600461105f565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600460209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff9081168452600190910154169082015290565b60408051825173ffffffffffffffffffffffffffffffffffffffff9081168252602093840151169281019290925201610122565b6101ed6102d6565b005b6101ed6101fd36600461107c565b6103d8565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b6101ed610238366004611207565b6105b4565b61025061024b3660046112ae565b6105c8565b60405167ffffffffffffffff9091168152602001610122565b610250610277366004611330565b6105dd565b61028f61028a366004611385565b6105f4565b6040519015158152602001610122565b6102506102ad3660046112ae565b6106fd565b6101ed6102c03660046113ea565b610791565b60606102d160026107a2565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331461035c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6103e06107af565b60005b818110156105af57368383838181106103fe576103fe611407565b6060029190910191506000905060048161041b602085018561105f565b67ffffffffffffffff1681526020810191909152604001600020805490915073ffffffffffffffffffffffffffffffffffffffff161515806104765750600181015473ffffffffffffffffffffffffffffffffffffffff1615155b156104ad576040517fc6117ae200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104bd60408301602084016113ea565b81547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9190911617815561050d60608301604084016113ea565b6001820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055610561602083018361105f565b67ffffffffffffffff167fa2e43edcbc4fd175ae4bebbe3fd6139871ed1f1783cd4a1ace59b90d302c33198360200160405161059d9190611436565b60405180910390a250506001016103e3565b505050565b6105bc6107af565b6105c581610832565b50565b60006105d483836109c4565b90505b92915050565b60006105ea848484610ae1565b90505b9392505050565b60006105fe610c32565b600061060b868585610ae1565b6106169060016114ad565b90508467ffffffffffffffff168167ffffffffffffffff161461067a577f606ff8179e5e3c059b82df931acc496b7b6053e8879042f8267f930e0595f69f8686868660405161066894939291906114ce565b60405180910390a160009150506106f5565b67ffffffffffffffff86166000908152600660205260409081902090518291906106a7908790879061153a565b908152604051908190036020019020805467ffffffffffffffff929092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090921691909117905550600190505b949350505050565b6000610707610c32565b600061071384846109c4565b61071e9060016114ad565b67ffffffffffffffff808616600090815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff89168452909152902080549183167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090921691909117905591505092915050565b6107996107af565b6105c581610c75565b606060006105ed83610d6a565b60005473ffffffffffffffffffffffffffffffffffffffff163314610830576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610353565b565b602081015160005b81518110156108cd57600082828151811061085757610857611407565b60200260200101519050610875816002610dc690919063ffffffff16565b156108c45760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b5060010161083a565b50815160005b81518110156109be5760008282815181106108f0576108f0611407565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610960576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61096b600282610de8565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016108d3565b50505050565b67ffffffffffffffff808316600090815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120549091168082036105d45767ffffffffffffffff841660009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff168015610ad9576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015282169063856c824790602401602060405180830381865afa158015610aac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad0919061154a565b925050506105d7565b509392505050565b67ffffffffffffffff83166000908152600660205260408082209051829190610b0d908690869061153a565b9081526040519081900360200190205467ffffffffffffffff16905060008190036105ea5767ffffffffffffffff851660009081526004602052604090206001015473ffffffffffffffffffffffffffffffffffffffff168015610c295773ffffffffffffffffffffffffffffffffffffffff811663856c8247610b93868801886113ea565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401602060405180830381865afa158015610bfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c20919061154a565b925050506105ed565b50949350505050565b610c3d600233610e0a565b610830576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610353565b3373ffffffffffffffffffffffffffffffffffffffff821603610cf4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610353565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b606081600001805480602002602001604051908101604052809291908181526020018280548015610dba57602002820191906000526020600020905b815481526020019060010190808311610da6575b50505050509050919050565b60006105d48373ffffffffffffffffffffffffffffffffffffffff8416610e39565b60006105d48373ffffffffffffffffffffffffffffffffffffffff8416610f33565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156105d4565b60008181526001830160205260408120548015610f22576000610e5d600183611567565b8554909150600090610e7190600190611567565b9050818114610ed6576000866000018281548110610e9157610e91611407565b9060005260206000200154905080876000018481548110610eb457610eb4611407565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610ee757610ee761157a565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105d7565b60009150506105d7565b5092915050565b6000818152600183016020526040812054610f7a575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105d7565b5060006105d7565b60006020808352835180602085015260005b81811015610fb057858101830151858201604001528201610f94565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6020808252825182820181905260009190848201906040850190845b8181101561103d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161100b565b50909695505050505050565b67ffffffffffffffff811681146105c557600080fd5b60006020828403121561107157600080fd5b81356105d481611049565b6000806020838503121561108f57600080fd5b823567ffffffffffffffff808211156110a757600080fd5b818501915085601f8301126110bb57600080fd5b8135818111156110ca57600080fd5b8660206060830285010111156110df57600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146105c557600080fd5b600082601f83011261115357600080fd5b8135602067ffffffffffffffff80831115611170576111706110f1565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811084821117156111b3576111b36110f1565b60405293845260208187018101949081019250878511156111d357600080fd5b6020870191505b848210156111fc5781356111ed81611120565b835291830191908301906111da565b979650505050505050565b60006020828403121561121957600080fd5b813567ffffffffffffffff8082111561123157600080fd5b908301906040828603121561124557600080fd5b604051604081018181108382111715611260576112606110f1565b60405282358281111561127257600080fd5b61127e87828601611142565b82525060208301358281111561129357600080fd5b61129f87828601611142565b60208301525095945050505050565b600080604083850312156112c157600080fd5b82356112cc81611049565b915060208301356112dc81611120565b809150509250929050565b60008083601f8401126112f957600080fd5b50813567ffffffffffffffff81111561131157600080fd5b60208301915083602082850101111561132957600080fd5b9250929050565b60008060006040848603121561134557600080fd5b833561135081611049565b9250602084013567ffffffffffffffff81111561136c57600080fd5b611378868287016112e7565b9497909650939450505050565b6000806000806060858703121561139b57600080fd5b84356113a681611049565b935060208501356113b681611049565b9250604085013567ffffffffffffffff8111156113d257600080fd5b6113de878288016112e7565b95989497509550505050565b6000602082840312156113fc57600080fd5b81356105d481611120565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60408101823561144581611120565b73ffffffffffffffffffffffffffffffffffffffff908116835260208401359061146e82611120565b8082166020850152505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff818116838216019080821115610f2c57610f2c61147e565b600067ffffffffffffffff8087168352808616602084015250606060408301528260608301528284608084013760006080848401015260807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905095945050505050565b8183823760009101908152919050565b60006020828403121561155c57600080fd5b81516105d481611049565b818103818111156105d7576105d761147e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var NonceManagerABI = NonceManagerMetaData.ABI @@ -296,6 +296,28 @@ func (_NonceManager *NonceManagerCallerSession) Owner() (common.Address, error) return _NonceManager.Contract.Owner(&_NonceManager.CallOpts) } +func (_NonceManager *NonceManagerCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _NonceManager.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_NonceManager *NonceManagerSession) TypeAndVersion() (string, error) { + return _NonceManager.Contract.TypeAndVersion(&_NonceManager.CallOpts) +} + +func (_NonceManager *NonceManagerCallerSession) TypeAndVersion() (string, error) { + return _NonceManager.Contract.TypeAndVersion(&_NonceManager.CallOpts) +} + func (_NonceManager *NonceManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { return _NonceManager.contract.Transact(opts, "acceptOwnership") } @@ -1180,6 +1202,8 @@ type NonceManagerInterface interface { Owner(opts *bind.CallOpts) (common.Address, error) + TypeAndVersion(opts *bind.CallOpts) (string, error) + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 63ec39c74c..c9da4f5973 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -22,9 +22,9 @@ mock_arm_contract: ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.abi ../../ mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin e0cf17a38b438239fc6294ddca88f86b6c39e4542aefd9815b2d92987191b8bd mock_usdc_token_transmitter: ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin 33bdad70822e889de7c720ed20085cf9cd3f8eba8b68f26bd6535197749595fe mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin 518e19efa2ff52b0fefd8e597b05765317ee7638189bfe34ca43de2f6599faf4 -multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin abb0ecb1ed8621f26e43b39f5fa25f3d0b6d6c184fa37c404c4389605ecb74e7 +multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin 44e1f40d928fd0e1f36e1ee5edfb6ab2a54fee0174e5f83c57a06cf79ec0c96c multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin aa299e0c2659d53aad4eace4d66be0e734b1366008593669cf30361ff529da6a -nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 78b58f4f192db7496e2b6de805d6a2c918b98d4fa62f3c7ed145ef3b5657a40d +nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 6f64e1083b356c06ee66b9138e398b9c97a4cd3e8c9ec38cf3010cebc79af536 ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 1588313bb5e781d181a825247d30828f59007700f36b4b9b00391592b06ff4b4 price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 955eeb1da5f001fa01dc9914bf8a02b7e3b58e080ee775424261dcd97f88d70d From 983554ebd98c70ef59d59fbf36240d7adff347cb Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Fri, 2 Aug 2024 19:57:07 +0200 Subject: [PATCH 190/432] Remove revert cases in exec race conditions (#1246) Since the separation of manual exec window and DON exec window, it would theoretically be possible that two executions happen at the same time (although unlikely). Remove reverts to ensure other msgs in the batches are unaffected --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/gas-snapshots/ccip.gas-snapshot | 202 +++++++++--------- .../v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 20 +- .../src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol | 22 +- .../test/offRamp/EVM2EVMMultiOffRamp.t.sol | 34 ++- .../ccip/test/offRamp/EVM2EVMOffRamp.t.sol | 198 ++++++++--------- .../evm_2_evm_multi_offramp.go | 134 +++++++++++- .../evm_2_evm_offramp/evm_2_evm_offramp.go | 133 +++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 4 +- .../ccip/mocks/evm2_evm_off_ramp_interface.go | 175 +++++++++++++++ 9 files changed, 678 insertions(+), 244 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 9d31647634..07822638c6 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -120,7 +120,7 @@ CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424253) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1110438) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1110291) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38157) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 108321) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 116789) @@ -131,19 +131,19 @@ EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRam EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 105586) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 15719) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 13057) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 298564) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 239899) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 158863) -EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 189303) -EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 147582) -EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 521464) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 298417) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 239752) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 158869) +EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 189205) +EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 147533) +EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 521366) EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10459) EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15662) EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67195) EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59698) EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58778) -EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6394807) -EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 5978034) +EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6373551) +EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 5956778) EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106229) EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116228) EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106272) @@ -156,25 +156,25 @@ EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 227807) EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117527) EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77605) EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 207057) -EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6389196) +EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6367940) EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47785) -EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 5980336) -EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 157326) -EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103815) -EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101686) -EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 159832) -EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101585) -EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101652) +EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 5959080) +EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 157297) +EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103786) +EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101657) +EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 159802) +EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101556) +EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101623) EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17280) -EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1559406) -EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 342924) -EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 260178) -EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6445313) -EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6028259) +EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1557936) +EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 342777) +EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 260031) +EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6424008) +EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6006954) EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 27681) -EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 165181) -EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 149137) -EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6807388) +EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 165132) +EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 149088) +EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6786083) EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17154) EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18413) EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249346) @@ -188,46 +188,46 @@ EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Su EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 93615) EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35083) EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23907) -EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 451314) -EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54475) +EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 451216) +EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54426) EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35917) EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154369) EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35317) -EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 181353) -EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 190627) +EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 181304) +EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 192594) EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48053) -EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 443030) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 251770) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 173962) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 193657) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259648) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 129585) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 391688) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65899) -EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80955) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 535385) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 480301) +EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 442981) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 251672) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 173864) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 193559) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259599) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 129536) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 391590) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65850) +EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80906) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 535287) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 480203) EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35763) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 520300) -EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 517668) -EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 487804) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 127921) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 157144) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 520202) +EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 517570) +EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 487706) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 127927) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 157150) EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3655340) EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118224) EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87461) EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75600) EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26461) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 163081) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 207379) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 163032) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 207236) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26004) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152867) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 507480) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails() (gas: 2307903) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 209633) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 210210) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 668610) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 299477) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 507382) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2285227) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 209491) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 210112) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 668120) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 299303) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 160598) EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 24131) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 59105) @@ -300,41 +300,41 @@ EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthRe EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 44959) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 214456) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 307176) -EVM2EVMOffRamp__report:test_Report_Success() (gas: 127459) +EVM2EVMOffRamp__report:test_Report_Success() (gas: 127410) EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 255279) EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 263870) EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 336203) EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 314960) EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17009) -EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153158) -EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5275448) -EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 143892) +EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153130) +EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5257993) +EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 143864) EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21323) EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36486) -EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51701) -EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 473025) -EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 46423) -EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152453) -EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 102724) -EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 164818) -EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 177584) +EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51652) +EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 472927) +EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 46374) +EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152404) +EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 102702) +EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 164769) +EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Success() (gas: 179100) EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 41317) -EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 159365) -EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 174600) -EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 248634) -EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 115040) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 410767) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54196) -EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 132056) -EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52178) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 561690) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 500288) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 159267) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 174480) +EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 248585) +EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114991) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 410714) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54147) +EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 132007) +EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52129) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 561592) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 500168) EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35486) -EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 549267) -EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64023) -EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 123201) -EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 143411) -EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 428233) +EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 549169) +EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 63974) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 123206) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 143416) +EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 428184) EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 20582) EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 282255) EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20209) @@ -343,23 +343,23 @@ EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 4863 EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48098) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 317243) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 72423) -EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 231326) -EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 279867) -EVM2EVMOffRamp_execute_upgrade:test_V2OffRampNonceSkipsIfMsgInFlight_Success() (gas: 261109) -EVM2EVMOffRamp_execute_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 229397) -EVM2EVMOffRamp_execute_upgrade:test_V2_Success() (gas: 131682) +EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 231228) +EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 279720) +EVM2EVMOffRamp_execute_upgrade:test_V2OffRampNonceSkipsIfMsgInFlight_Success() (gas: 260962) +EVM2EVMOffRamp_execute_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 229250) +EVM2EVMOffRamp_execute_upgrade:test_V2_Success() (gas: 131633) EVM2EVMOffRamp_getAllRateLimitTokens:test_GetAllRateLimitTokens_Success() (gas: 38408) EVM2EVMOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3213556) EVM2EVMOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 83091) -EVM2EVMOffRamp_manuallyExecute:test_LowGasLimitManualExec_Success() (gas: 483110) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 185977) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecForkedChain_Revert() (gas: 25824) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 43449) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 25927) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithGasOverride_Success() (gas: 188300) -EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187747) -EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails() (gas: 2050054) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143563) +EVM2EVMOffRamp_manuallyExecute:test_LowGasLimitManualExec_Success() (gas: 483152) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 186041) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecForkedChain_Revert() (gas: 25894) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 43519) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 25997) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithGasOverride_Success() (gas: 188342) +EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187789) +EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2027924) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143654) EVM2EVMOffRamp_metadataHash:test_MetadataHash_Success() (gas: 8838) EVM2EVMOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 40131) EVM2EVMOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 38214) @@ -593,18 +593,18 @@ MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 412263) -MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1426954) +MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1426807) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71847) -NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 252566) -NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 254866) -NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 307885) -NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 290962) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 247990) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 236024) -NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 144774) +NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 252468) +NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 254768) +NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 307738) +NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 290815) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 247843) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 235877) +NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 144725) NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 186694) NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 237762) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol index 809e4e22a4..89c066dd11 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -33,7 +33,6 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { using ERC165Checker for address; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; - error AlreadyAttempted(uint64 sourceChainSelector, uint64 sequenceNumber); error AlreadyExecuted(uint64 sourceChainSelector, uint64 sequenceNumber); error ZeroChainSelectorNotAllowed(); error ExecutionError(bytes32 messageId, bytes err); @@ -74,6 +73,7 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { event SourceChainSelectorAdded(uint64 sourceChainSelector); event SourceChainConfigSet(uint64 indexed sourceChainSelector, SourceChainConfig sourceConfig); event SkippedAlreadyExecutedMessage(uint64 sourceChainSelector, uint64 sequenceNumber); + event AlreadyAttempted(uint64 sourceChainSelector, uint64 sequenceNumber); /// @dev RMN depends on this event, if changing, please notify the RMN maintainers. event CommitReportAccepted(CommitReport report); event RootRemoved(bytes32 root); @@ -375,13 +375,6 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { Internal.MessageExecutionState originalState = getExecutionState(sourceChainSelector, message.header.sequenceNumber); - if (originalState == Internal.MessageExecutionState.SUCCESS) { - // If the message has already been executed, we skip it. We want to not revert on race conditions between - // executing parties. This will allow us to open up manual exec while also attempting with the DON, without - // reverting an entire DON batch when a user manually executes while the tx is inflight. - emit SkippedAlreadyExecutedMessage(sourceChainSelector, message.header.sequenceNumber); - continue; - } // Two valid cases here, we either have never touched this message before, or we tried to execute // and failed. This check protects against reentry and re-execution because the other state is // IN_PROGRESS which should not be allowed to execute. @@ -390,7 +383,13 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { originalState == Internal.MessageExecutionState.UNTOUCHED || originalState == Internal.MessageExecutionState.FAILURE ) - ) revert AlreadyExecuted(sourceChainSelector, message.header.sequenceNumber); + ) { + // If the message has already been executed, we skip it. We want to not revert on race conditions between + // executing parties. This will allow us to open up manual exec while also attempting with the DON, without + // reverting an entire DON batch when a user manually executes while the tx is inflight. + emit SkippedAlreadyExecutedMessage(sourceChainSelector, message.header.sequenceNumber); + continue; + } if (manualExecution) { bool isOldCommitReport = @@ -409,7 +408,8 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { // DON can only execute a message once // Acceptable state transitions: UNTOUCHED->SUCCESS, UNTOUCHED->FAILURE if (originalState != Internal.MessageExecutionState.UNTOUCHED) { - revert AlreadyAttempted(sourceChainSelector, message.header.sequenceNumber); + emit AlreadyAttempted(sourceChainSelector, message.header.sequenceNumber); + continue; } } diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol index 9950ff4259..f60f0c13f9 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol @@ -34,7 +34,6 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio using ERC165Checker for address; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; - error AlreadyAttempted(uint64 sequenceNumber); error AlreadyExecuted(uint64 sequenceNumber); error ZeroAddressNotAllowed(); error CommitStoreAlreadyInUse(); @@ -69,6 +68,7 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio event TokenAggregateRateLimitAdded(address sourceToken, address destToken); event TokenAggregateRateLimitRemoved(address sourceToken, address destToken); event SkippedAlreadyExecutedMessage(uint64 indexed sequenceNumber); + event AlreadyAttempted(uint64 sequenceNumber); /// @notice Static offRamp config /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. @@ -276,13 +276,6 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio for (uint256 i = 0; i < numMsgs; ++i) { Internal.EVM2EVMMessage memory message = report.messages[i]; Internal.MessageExecutionState originalState = getExecutionState(message.sequenceNumber); - if (originalState == Internal.MessageExecutionState.SUCCESS) { - // If the message has already been executed, we skip it. We want to not revert on race conditions between - // executing parties. This will allow us to open up manual exec while also attempting with the DON, without - // reverting an entire DON batch when a user manually executes while the tx is inflight. - emit SkippedAlreadyExecutedMessage(message.sequenceNumber); - continue; - } // Two valid cases here, we either have never touched this message before, or we tried to execute // and failed. This check protects against reentry and re-execution because the other state is // IN_PROGRESS which should not be allowed to execute. @@ -291,7 +284,13 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio originalState == Internal.MessageExecutionState.UNTOUCHED || originalState == Internal.MessageExecutionState.FAILURE ) - ) revert AlreadyExecuted(message.sequenceNumber); + ) { + // If the message has already been executed, we skip it. We want to not revert on race conditions between + // executing parties. This will allow us to open up manual exec while also attempting with the DON, without + // reverting an entire DON batch when a user manually executes while the tx is inflight. + emit SkippedAlreadyExecutedMessage(message.sequenceNumber); + continue; + } if (manualExecution) { bool isOldCommitReport = @@ -309,7 +308,10 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio } else { // DON can only execute a message once // Acceptable state transitions: UNTOUCHED->SUCCESS, UNTOUCHED->FAILURE - if (originalState != Internal.MessageExecutionState.UNTOUCHED) revert AlreadyAttempted(message.sequenceNumber); + if (originalState != Internal.MessageExecutionState.UNTOUCHED) { + emit AlreadyAttempted(message.sequenceNumber); + continue; + } } if (message.nonce != 0) { diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol index 43899cbfd6..fcb0d9006c 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol @@ -945,11 +945,10 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { ); s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); - vm.expectRevert( - abi.encodeWithSelector( - EVM2EVMMultiOffRamp.AlreadyAttempted.selector, SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber - ) - ); + // The second time should skip the msg + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.AlreadyAttempted(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); } @@ -1681,7 +1680,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); } - function test_manuallyExecute_ReentrancyFails() public { + function test_manuallyExecute_ReentrancyFails_Success() public { uint256 tokenAmount = 1e9; IERC20 tokenToAbuse = IERC20(s_destFeeToken); @@ -1715,29 +1714,26 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { uint256[][] memory gasLimitOverrides = new uint256[][](1); gasLimitOverrides[0] = _getGasLimitsFromMessages(messages); - // The first entry should be fine and triggers the second entry. This one fails - // but since it's an inner tx of the first one it is caught in the try-catch. - // This means the first tx is marked `FAILURE` with the error message of the second tx. + // The first entry should be fine and triggers the second entry which is skipped. Due to the reentrancy + // the second completes first, so we expect the skip event before the success event. + vm.expectEmit(); + emit EVM2EVMMultiOffRamp.SkippedAlreadyExecutedMessage( + messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber + ); + vm.expectEmit(); emit EVM2EVMMultiOffRamp.ExecutionStateChanged( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, - Internal.MessageExecutionState.FAILURE, - abi.encodeWithSelector( - EVM2EVMMultiOffRamp.ReceiverError.selector, - abi.encodeWithSelector( - EVM2EVMMultiOffRamp.AlreadyExecuted.selector, - messages[0].header.sourceChainSelector, - messages[0].header.sequenceNumber - ) - ) + Internal.MessageExecutionState.SUCCESS, + "" ); s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); // Since the tx failed we don't release the tokens - assertEq(tokenToAbuse.balanceOf(address(receiver)), balancePre); + assertEq(tokenToAbuse.balanceOf(address(receiver)), balancePre + tokenAmount); } } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol index 4f2b219e69..89f0f95fd4 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol @@ -612,6 +612,57 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); } + function test_execute_RouterYULCall_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + // gas limit too high, Router's external call should revert + messages[0].gasLimit = 1e36; + messages[0].receiver = address(new ConformingReceiver(address(s_destRouter), s_destFeeToken)); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + Internal.ExecutionReport memory executionReport = _generateReportFromMessages(messages); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, + messages[0].messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector(CallWithExactGas.NotEnoughGasForCall.selector) + ); + + s_offRamp.execute(executionReport, new uint256[](0)); + } + + function test_RetryFailedMessageWithoutManualExecution_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + + bytes memory realError1 = new bytes(2); + realError1[0] = 0xbe; + realError1[1] = 0xef; + s_reverting_receiver.setErr(realError1); + + messages[0].receiver = address(s_reverting_receiver); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, + messages[0].messageId, + Internal.MessageExecutionState.FAILURE, + abi.encodeWithSelector( + EVM2EVMOffRamp.ReceiverError.selector, + abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, realError1) + ) + ); + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + + // The second time should skip the msg + vm.expectEmit(); + emit EVM2EVMOffRamp.AlreadyAttempted(messages[0].sequenceNumber); + + s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + } + // Reverts function test_InvalidMessageId_Revert() public { @@ -723,51 +774,6 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { ); s_offRamp.execute(executionReport, new uint256[](0)); } - - function test_RouterYULCall_Revert() public { - Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); - - // gas limit too high, Router's external call should revert - messages[0].gasLimit = 1e36; - messages[0].receiver = address(new ConformingReceiver(address(s_destRouter), s_destFeeToken)); - messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); - - Internal.ExecutionReport memory executionReport = _generateReportFromMessages(messages); - - vm.expectRevert( - abi.encodeWithSelector( - EVM2EVMOffRamp.ExecutionError.selector, abi.encodeWithSelector(CallWithExactGas.NotEnoughGasForCall.selector) - ) - ); - s_offRamp.execute(executionReport, new uint256[](0)); - } - - function test_RetryFailedMessageWithoutManualExecution_Revert() public { - Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); - - bytes memory realError1 = new bytes(2); - realError1[0] = 0xbe; - realError1[1] = 0xef; - s_reverting_receiver.setErr(realError1); - - messages[0].receiver = address(s_reverting_receiver); - messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); - - vm.expectEmit(); - emit EVM2EVMOffRamp.ExecutionStateChanged( - messages[0].sequenceNumber, - messages[0].messageId, - Internal.MessageExecutionState.FAILURE, - abi.encodeWithSelector( - EVM2EVMOffRamp.ReceiverError.selector, - abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, realError1) - ) - ); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); - - vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.AlreadyAttempted.selector, messages[0].sequenceNumber)); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); - } } contract EVM2EVMOffRamp_execute_upgrade is EVM2EVMOffRampSetup { @@ -1141,6 +1147,55 @@ contract EVM2EVMOffRamp_manuallyExecute is EVM2EVMOffRampSetup { s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimitOverrides); } + function test_ReentrancyManualExecuteFails_Success() public { + uint256 tokenAmount = 1e9; + IERC20 tokenToAbuse = IERC20(s_destFeeToken); + + // This needs to be deployed before the source chain message is sent + // because we need the address for the receiver. + ReentrancyAbuser receiver = new ReentrancyAbuser(address(s_destRouter), s_offRamp); + uint256 balancePre = tokenToAbuse.balanceOf(address(receiver)); + + // For this test any message will be flagged as correct by the + // commitStore. In a real scenario the abuser would have to actually + // send the message that they want to replay. + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + messages[0].tokenAmounts = new Client.EVMTokenAmount[](1); + messages[0].tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceFeeToken, amount: tokenAmount}); + messages[0].receiver = address(receiver); + messages[0].sourceTokenData = new bytes[](1); + messages[0].sourceTokenData[0] = abi.encode( + Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[s_sourceFeeToken]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[s_sourceFeeToken]), + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD + }) + ); + + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + + Internal.ExecutionReport memory report = _generateReportFromMessages(messages); + + // sets the report to be repeated on the ReentrancyAbuser to be able to replay + receiver.setPayload(report); + + // The first entry should be fine and triggers the second entry which is skipped. Due to the reentrancy + // the second completes first, so we expect the skip event before the success event. + vm.expectEmit(); + emit EVM2EVMOffRamp.SkippedAlreadyExecutedMessage(messages[0].sequenceNumber); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + + s_offRamp.manuallyExecute(report, _getGasLimitsFromMessages(messages)); + + // Assert that they only got the tokens once, not twice + assertEq(tokenToAbuse.balanceOf(address(receiver)), balancePre + tokenAmount); + } + function test_ManualExecForkedChain_Revert() public { Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); @@ -1197,59 +1252,6 @@ contract EVM2EVMOffRamp_manuallyExecute is EVM2EVMOffRampSetup { ); s_offRamp.manuallyExecute(_generateReportFromMessages(messages), _getGasLimitsFromMessages(messages)); } - - function test_ReentrancyManualExecuteFails() public { - uint256 tokenAmount = 1e9; - IERC20 tokenToAbuse = IERC20(s_destFeeToken); - - // This needs to be deployed before the source chain message is sent - // because we need the address for the receiver. - ReentrancyAbuser receiver = new ReentrancyAbuser(address(s_destRouter), s_offRamp); - uint256 balancePre = tokenToAbuse.balanceOf(address(receiver)); - - // For this test any message will be flagged as correct by the - // commitStore. In a real scenario the abuser would have to actually - // send the message that they want to replay. - Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); - messages[0].tokenAmounts = new Client.EVMTokenAmount[](1); - messages[0].tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceFeeToken, amount: tokenAmount}); - messages[0].receiver = address(receiver); - messages[0].sourceTokenData = new bytes[](1); - messages[0].sourceTokenData[0] = abi.encode( - Internal.SourceTokenData({ - sourcePoolAddress: abi.encode(s_sourcePoolByToken[s_sourceFeeToken]), - destTokenAddress: abi.encode(s_destTokenBySourceToken[s_sourceFeeToken]), - extraData: "", - destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD - }) - ); - - messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); - - Internal.ExecutionReport memory report = _generateReportFromMessages(messages); - - // sets the report to be repeated on the ReentrancyAbuser to be able to replay - receiver.setPayload(report); - - // The first entry should be fine and triggers the second entry. This one fails - // but since it's an inner tx of the first one it is caught in the try-catch. - // This means the first tx is marked `FAILURE` with the error message of the second tx. - vm.expectEmit(); - emit EVM2EVMOffRamp.ExecutionStateChanged( - messages[0].sequenceNumber, - messages[0].messageId, - Internal.MessageExecutionState.FAILURE, - abi.encodeWithSelector( - EVM2EVMOffRamp.ReceiverError.selector, - abi.encodeWithSelector(EVM2EVMOffRamp.AlreadyExecuted.selector, messages[0].sequenceNumber) - ) - ); - - s_offRamp.manuallyExecute(report, _getGasLimitsFromMessages(messages)); - - // Since the tx failed we don't release the tokens - assertEq(tokenToAbuse.balanceOf(address(receiver)), balancePre); - } } contract EVM2EVMOffRamp_getExecutionState is EVM2EVMOffRampSetup { diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go index 9d5e7a4aa7..a61c4fde4b 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go @@ -162,8 +162,8 @@ type MultiOCR3BaseOCRConfigArgs struct { } var EVM2EVMMultiOffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162006af738038062006af78339810160408190526200003591620008e2565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003fc565b50505062000c57565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60a08101516001600160a01b03161580620002c8575080516001600160a01b0316155b15620002e7576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b0319908116928e1692909217905560a0808e01805160068054909416908f161790925586519a8b5297518716988a0198909852925185169388019390935251909216958501959095525185169383019390935251909216908201527f0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c9060c00160405180910390a150565b60005b81518110156200064e57600082828151811062000420576200042062000a20565b60200260200101519050600081600001519050806001600160401b03166000036200045e5760405163c656089560e01b815260040160405180910390fd5b6001600160401b03811660009081526007602052604081206001810180549192916200048a9062000a36565b80601f0160208091040260200160405190810160405280929190818152602001828054620004b89062000a36565b8015620005095780601f10620004dd5761010080835404028352916020019162000509565b820191906000526020600020905b815481529060010190602001808311620004eb57829003601f168201915b505050505090506000846040015190508151600003620005ac57805160000362000546576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000556828262000ac7565b508254610100600160481b0319166101001783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005e7565b8080519060200120828051906020012014620005e75760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b6020850151835460ff19169015151783556040516001600160401b038516907f4f49973170c548fddd4a48341b75e131818913f38f44d47af57e8735eee588ba906200063590869062000b93565b60405180910390a25050505050806001019050620003ff565b5050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200068d576200068d62000652565b60405290565b604051608081016001600160401b03811182821017156200068d576200068d62000652565b60405160c081016001600160401b03811182821017156200068d576200068d62000652565b604051601f8201601f191681016001600160401b038111828210171562000708576200070862000652565b604052919050565b80516001600160401b03811681146200072857600080fd5b919050565b80516001600160a01b03811681146200072857600080fd5b805163ffffffff811681146200072857600080fd5b6000601f83601f8401126200076e57600080fd5b825160206001600160401b03808311156200078d576200078d62000652565b8260051b6200079e838201620006dd565b9384528681018301938381019089861115620007b957600080fd5b84890192505b85831015620008d557825184811115620007d95760008081fd5b89016060601f19828d038101821315620007f35760008081fd5b620007fd62000668565b6200080a89850162000710565b81526040808501518015158114620008225760008081fd5b828b01529284015192888411156200083a5760008081fd5b83850194508e603f8601126200085257600093508384fd5b898501519350888411156200086b576200086b62000652565b6200087c8a848e87011601620006dd565b92508383528e81858701011115620008945760008081fd5b60005b84811015620008b4578581018201518482018c01528a0162000897565b5060009383018a0193909352918201528352509184019190840190620007bf565b9998505050505050505050565b6000806000838503610160811215620008fa57600080fd5b60808112156200090957600080fd5b6200091362000693565b6200091e8662000710565b81526200092e602087016200072d565b602082015262000941604087016200072d565b604082015262000954606087016200072d565b6060820152935060c0607f19820112156200096e57600080fd5b5062000979620006b8565b62000987608086016200072d565b81526200099760a0860162000745565b6020820152620009aa60c0860162000745565b6040820152620009bd60e0860162000745565b6060820152620009d161010086016200072d565b6080820152620009e561012086016200072d565b60a08201526101408501519092506001600160401b0381111562000a0857600080fd5b62000a16868287016200075a565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4b57607f821691505b60208210810362000a6c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000ac2576000816000526020600020601f850160051c8101602086101562000a9d5750805b601f850160051c820191505b8181101562000abe5782815560010162000aa9565b5050505b505050565b81516001600160401b0381111562000ae35762000ae362000652565b62000afb8162000af4845462000a36565b8462000a72565b602080601f83116001811462000b33576000841562000b1a5750858301515b600019600386901b1c1916600185901b17855562000abe565b600085815260208120601f198616915b8281101562000b645788860151825594840194600190910190840162000b43565b508582101562000b835787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252825460ff811615158383015260081c6001600160401b0316604083015260608083015260018084018054600093929190849062000bd58162000a36565b80608089015260a0600183166000811462000bf9576001811462000c165762000c48565b60ff19841660a08b015260a083151560051b8b0101945062000c48565b85600052602060002060005b8481101562000c3f5781548c820185015290880190890162000c22565b8b0160a0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615e3162000cc66000396000818161023e0152612c5201526000818161020f0152612f2c0152600081816101e00152818161141801526114cf0152600081816101b001526127cc015260008181611caa0152611cf60152615e316000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b146105ca578063f716f99f146105dd578063ff888fb1146105f057600080fd5b8063d2a15d3514610584578063e9d68a8e14610597578063ece670b6146105b757600080fd5b8063a12a9870116100bd578063a12a98701461050c578063c673e5841461051f578063ccd37ba31461053f57600080fd5b806385572ffb146104e35780638da5cb5b146104f157600080fd5b8063403b2d631161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104c85780637d4eef60146104d057600080fd5b8063403b2d63146103525780635e36480c1461036557600080fd5b80632d04ab76116101605780632d04ab761461030e578063311cd513146103235780633f4b04aa1461033657600080fd5b806306285c691461017c578063181f5a77146102c5575b600080fd5b61026e60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102bc9190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103016040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102bc9190613e9e565b61032161031c366004613f49565b610613565b005b610321610331366004613ffc565b6109d9565b600a5460405167ffffffffffffffff90911681526020016102bc565b610321610360366004614185565b610a42565b610378610373366004614224565b610a56565b6040516102bc9190614281565b61045f6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c0810182526004546001600160a01b03808216835263ffffffff74010000000000000000000000000000000000000000830481166020850152780100000000000000000000000000000000000000000000000083048116948401949094527c010000000000000000000000000000000000000000000000000000000090910490921660608201526005548216608082015260065490911660a082015290565b6040516102bc9190600060c0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401528060a08501511660a08401525092915050565b610321610aac565b6103216104de366004614885565b610b6a565b6103216101773660046149b0565b6000546040516001600160a01b0390911681526020016102bc565b61032161051a366004614a04565b610d0a565b61053261052d366004614b1e565b610d1b565b6040516102bc9190614b7e565b61057661054d366004614bf3565b67ffffffffffffffff919091166000908152600960209081526040808320938352929052205490565b6040519081526020016102bc565b610321610592366004614c1d565b610e79565b6105aa6105a5366004614c92565b610f33565b6040516102bc9190614cad565b6103216105c5366004614ce8565b61101c565b6103216105d8366004614d4c565b61136f565b6103216105eb366004614dd1565b611380565b6106036105fe366004614f0f565b6113c2565b60405190151581526020016102bc565b6000610621878901896150ad565b8051515190915015158061063a57508051602001515115155b1561073a57600a5460208a01359067ffffffffffffffff808316911610156106f957600a805467ffffffffffffffff191667ffffffffffffffff831617905560065482516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921691633937306f916106c291600401615315565b600060405180830381600087803b1580156106dc57600080fd5b505af11580156106f0573d6000803e3d6000fd5b50505050610738565b816020015151600003610738576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109225760008260200151828151811061076257610762615218565b6020026020010151905060008160000151905061077e81611483565b600061078982611585565b602084015151815491925067ffffffffffffffff908116610100909204161415806107cb575060208084015190810151905167ffffffffffffffff9182169116115b1561081457825160208401516040517feefb0cac00000000000000000000000000000000000000000000000000000000815261080b929190600401615328565b60405180910390fd5b604083015180610850576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600960209081526040808320848452909152902054156108c35783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024810182905260440161080b565b60208085015101516108d6906001615373565b825468ffffffffffffffff00191661010067ffffffffffffffff92831602179092559251166000908152600960209081526040808320948352939052919091204290555060010161073d565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610952919061539b565b60405180910390a16109ce60008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506115e5915050565b505050505050505050565b610a196109e882840184615438565b6040805160008082526020820190925290610a13565b60608152602001906001900390816109fe5790505b5061195c565b604080516000808252602082019092529050610a3c6001858585858660006115e5565b50505050565b610a4a611a0c565b610a5381611a68565b50565b6000610a646001600461546d565b6002610a71608085615496565b67ffffffffffffffff16610a8591906154bd565b610a8f8585611c60565b901c166003811115610aa357610aa3614257565b90505b92915050565b6001546001600160a01b03163314610b065760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161080b565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b72611ca7565b815181518114610bae576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610cfa576000848281518110610bcd57610bcd615218565b60200260200101519050600081602001515190506000858481518110610bf557610bf5615218565b6020026020010151905080518214610c39576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610ceb576000828281518110610c5857610c58615218565b6020026020010151905080600014610ce25784602001518281518110610c8057610c80615218565b602002602001015160800151811015610ce25784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018390526044810182905260640161080b565b50600101610c3c565b50505050806001019050610bb1565b50610d05838361195c565b505050565b610d12611a0c565b610a5381611d28565b610d5e6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610e0757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610de9575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e6957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e4b575b5050505050815250509050919050565b610e81611a0c565b60005b81811015610d05576000838383818110610ea057610ea0615218565b905060400201803603810190610eb691906154d4565b9050610ec581602001516113c2565b610f2a57805167ffffffffffffffff1660009081526009602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e84565b60408051606080820183526000808352602080840182905283850183905267ffffffffffffffff8681168352600782529185902085519384018652805460ff811615158552610100900490921690830152600181018054939492939192840191610f9c9061550d565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc89061550d565b8015610e695780601f10610fea57610100808354040283529160200191610e69565b820191906000526020600020905b815481529060010190602001808311610ff857505050919092525091949350505050565b333014611055576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611092565b604080518082019091526000808252602082015281526020019060019003908161106b5790505b5060a084015151909150156110c5576110c28360a001518460200151856060015186600001516020015186611fb4565b90505b6040805160a0810182528451518152845160209081015167ffffffffffffffff1681830152808601518351600094840192611101929101613e9e565b60408051601f19818403018152918152908252868101516020830152018390526005549091506001600160a01b0316801561120e576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a19061117b9085906004016155e9565b600060405180830381600087803b15801561119557600080fd5b505af19250505080156111a6575060015b61120e573d8080156111d4576040519150601f19603f3d011682016040523d82523d6000602084013e6111d9565b606091505b50806040517f09c2532500000000000000000000000000000000000000000000000000000000815260040161080b9190613e9e565b60408501515115801561122357506080850151155b8061123a575060608501516001600160a01b03163b155b8061127a57506060850151611278906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612092565b155b15611286575050505050565b60048054608087015160608801516040517f3cf9798300000000000000000000000000000000000000000000000000000000815260009485946001600160a01b031693633cf97983936112e1938a93611388939291016155fc565b6000604051808303816000875af1158015611300573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113289190810190615638565b50915091508161136657806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161080b9190613e9e565b50505050505050565b611377611a0c565b610a53816120ae565b611388611a0c565b60005b81518110156113be576113b68282815181106113a9576113a9615218565b6020026020010151612164565b60010161138b565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa15801561145f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa691906156ce565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561151e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154291906156ce565b15610a53576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080b565b67ffffffffffffffff81166000908152600760205260408120805460ff16610aa6576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080b565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906116448760a46156eb565b905082606001511561168c57845161165d9060206154bd565b865161166a9060206154bd565b6116759060a06156eb565b61167f91906156eb565b61168990826156eb565b90505b3681146116ce576040517f8e1192e10000000000000000000000000000000000000000000000000000000081526004810182905236602482015260440161080b565b50815181146117165781516040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101919091526024810182905260440161080b565b61171e611ca7565b60ff808a166000908152600360209081526040808320338452825280832081518083019092528054808616835293949193909284019161010090910416600281111561176c5761176c614257565b600281111561177d5761177d614257565b905250905060028160200151600281111561179a5761179a614257565b1480156117ee5750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff16815481106117d6576117d6615218565b6000918252602090912001546001600160a01b031633145b611824576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5081606001511561190657602082015161183f9060016156fe565b60ff1685511461187b576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83518551146118b6576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600087876040516118c8929190615717565b6040519081900381206118df918b90602001615727565b6040516020818303038152906040528051906020012090506119048a828888886124a8565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611996576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611a05576119fd8582815181106119cb576119cb615218565b6020026020010151846119f7578583815181106119ea576119ea615218565b60200260200101516126bf565b836126bf565b6001016119ad565b5050505050565b6000546001600160a01b03163314611a665760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161080b565b565b60a08101516001600160a01b03161580611a8a575080516001600160a01b0316155b15611ac1576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a177401000000000000000000000000000000000000000063ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16939093177c010000000000000000000000000000000000000000000000000000000093871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff19908116928e1692909217905560a0808e01805160068054909416908f161790925586519a8b5297518716988a0198909852925185169388019390935251909216958501959095525185169383019390935251909216908201527f0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c9060c00160405180910390a150565b67ffffffffffffffff8216600090815260086020526040812081611c8560808561573b565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f000000000000000000000000000000000000000000000000000000000000000014611a66576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015246602482015260440161080b565b60005b81518110156113be576000828281518110611d4857611d48615218565b602002602001015190506000816000015190508067ffffffffffffffff16600003611d9f576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600760205260408120600181018054919291611dca9061550d565b80601f0160208091040260200160405190810160405280929190818152602001828054611df69061550d565b8015611e435780601f10611e1857610100808354040283529160200191611e43565b820191906000526020600020905b815481529060010190602001808311611e2657829003601f168201915b505050505090506000846040015190508151600003611efc578051600003611e97576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301611ea582826157aa565b50825468ffffffffffffffff00191661010017835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611f4f565b8080519060200120828051906020012014611f4f576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8516600482015260240161080b565b6020850151835460ff191690151517835560405167ffffffffffffffff8516907f4f49973170c548fddd4a48341b75e131818913f38f44d47af57e8735eee588ba90611f9c90869061586a565b60405180910390a25050505050806001019050611d2b565b6060855167ffffffffffffffff811115611fd057611fd0614050565b60405190808252806020026020018201604052801561201557816020015b6040805180820190915260008082526020820152815260200190600190039081611fee5790505b50905060005b86518110156120885761206387828151811061203957612039615218565b602002602001015187878787868151811061205657612056615218565b6020026020010151612ecb565b82828151811061207557612075615218565b602090810291909101015260010161201b565b5095945050505050565b600061209d836132da565b8015610aa35750610aa3838361333e565b336001600160a01b038216036121065760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161080b565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff1660000361218f576000604051631b3fab5160e11b815260040161080b9190615926565b60208082015160ff808216600090815260029093526040832060018101549293909283921690036121fc57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612251565b6060840151600182015460ff6201000090910416151590151514612251576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff8416600482015260240161080b565b60a08401518051601f60ff82161115612280576001604051631b3fab5160e11b815260040161080b9190615926565b6122e685856003018054806020026020016040519081016040528092919081815260200182805480156122dc57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122be575b505050505061340d565b8560600151156124155761235485856002018054806020026020016040519081016040528092919081815260200182805480156122dc576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122be57505050505061340d565b6080860151805161236e9060028701906020840190613da8565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f10156123ce576002604051631b3fab5160e11b815260040161080b9190615926565b60408801516123de906003615940565b60ff168160ff1611612406576003604051631b3fab5160e11b815260040161080b9190615926565b61241287836001613476565b50505b61242185836002613476565b81516124369060038601906020850190613da8565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f5479361248f938a939260028b0192919061595c565b60405180910390a16124a0856135f6565b505050505050565b6124b0613e1a565b835160005b818110156126b55760006001888684602081106124d4576124d4615218565b6124e191901a601b6156fe565b8985815181106124f3576124f3615218565b602002602001015189868151811061250d5761250d615218565b60200260200101516040516000815260200160405260405161254b949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561256d573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b038516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156125ce576125ce614257565b60028111156125df576125df614257565b90525090506001816020015160028111156125fc576125fc614257565b14612633576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061264a5761264a615218565b602002015115612686576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126a1576126a1615218565b9115156020909202015250506001016124b5565b5050505050505050565b81516126ca81611483565b60006126d582611585565b6020850151519091506000819003612718576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151518114612756576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561277157612771614050565b60405190808252806020026020018201604052801561279a578160200160208202803683370190505b50905060005b8281101561290f576000876020015182815181106127c0576127c0615218565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461285357805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161080b565b6128e9818660010180546128669061550d565b80601f01602080910402602001604051908101604052809291908181526020018280546128929061550d565b80156128df5780601f106128b4576101008083540402835291602001916128df565b820191906000526020600020905b8154815290600101906020018083116128c257829003601f168201915b5050505050613612565b8383815181106128fb576128fb615218565b6020908102919091010152506001016127a0565b506000612926858389606001518a60800151613734565b90508060000361296e576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015260240161080b565b8551151560005b848110156109ce5760008960200151828151811061299557612995615218565b6020026020010151905060006129b389836000015160600151610a56565b905060028160038111156129c9576129c9614257565b03612a20578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c910160405180910390a15050612ec3565b6000816003811115612a3457612a34614257565b1480612a5157506003816003811115612a4f57612a4f614257565b145b612aa2578151606001516040517f25507e7f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c166004830152909116602482015260440161080b565b8315612b835760045460009074010000000000000000000000000000000000000000900463ffffffff16612ad6874261546d565b1190508080612af657506003826003811115612af457612af4614257565b145b612b38576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b16600482015260240161080b565b8a8481518110612b4a57612b4a615218565b6020026020010151600014612b7d578a8481518110612b6b57612b6b615218565b60200260200101518360800181815250505b50612be9565b6000816003811115612b9757612b97614257565b14612be9578151606001516040517f3ef2a99c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808c166004830152909116602482015260440161080b565b81516080015167ffffffffffffffff1615612cd7576000816003811115612c1257612c12614257565b03612cd75781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c89928e9291906004016159e2565b6020604051808303816000875af1158015612ca8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ccc91906156ce565b612cd7575050612ec3565b60008b604001518481518110612cef57612cef615218565b6020026020010151905080518360a001515114612d53578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d166004830152909116602482015260440161080b565b612d678a846000015160600151600161378a565b600080612d748584613832565b91509150612d8b8c8660000151606001518461378a565b8615612dfb576003826003811115612da557612da5614257565b03612dfb576000846003811115612dbe57612dbe614257565b14612dfb578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261080b91908390600401615a0f565b6002826003811115612e0f57612e0f614257565b14612e69576003826003811115612e2857612e28614257565b14612e69578451606001516040517f926c5a3e00000000000000000000000000000000000000000000000000000000815261080b918e918590600401615a28565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612eb59087908790615a4e565b60405180910390a450505050505b600101612975565b60408051808201909152600080825260208201526000612eee87602001516138fc565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f979190615a6e565b90506001600160a01b0381161580612fdf5750612fdd6001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612092565b155b15613021576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b038216600482015260240161080b565b6000806131276040518061010001604052808b81526020018967ffffffffffffffff1681526020018a6001600160a01b031681526020018c606001518152602001866001600160a01b031681526020018c6000015181526020018c604001518152602001888152506040516024016130999190615a8b565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3907753700000000000000000000000000000000000000000000000000000000179052600454859063ffffffff7c01000000000000000000000000000000000000000000000000000000009091041661138860846139a2565b50915091508161316557806040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161080b9190613e9e565b80516020146131ad5780516040517f78ef802400000000000000000000000000000000000000000000000000000000815260206004820152602481019190915260440161080b565b6000818060200190518101906131c39190615b62565b6040516001600160a01b038b166024820152604481018290529091506132709060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600454879063ffffffff78010000000000000000000000000000000000000000000000009091041661138860846139a2565b509093509150826132af57816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161080b9190613e9e565b604080518082019091526001600160a01b039095168552602085015250919250505095945050505050565b6000613306827f01ffc9a70000000000000000000000000000000000000000000000000000000061333e565b8015610aa65750613337827fffffffff0000000000000000000000000000000000000000000000000000000061333e565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156133f6575060208210155b80156134025750600081115b979650505050505050565b60005b8151811015610d055760ff83166000908152600360205260408120835190919084908490811061344257613442615218565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613410565b60005b82518160ff161015610a3c576000838260ff168151811061349c5761349c615218565b60200260200101519050600060028111156134b9576134b9614257565b60ff80871660009081526003602090815260408083206001600160a01b038716845290915290205461010090041660028111156134f8576134f8614257565b14613519576004604051631b3fab5160e11b815260040161080b9190615926565b6001600160a01b038116613559576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff16815260200184600281111561357f5761357f614257565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff1916176101008360028111156135dc576135dc614257565b021790555090505050806135ef90615b7b565b9050613479565b60ff8116610a5357600a805467ffffffffffffffff1916905550565b815160208082015160409283015192516000938493613658937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615b9a565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976136a19794969395929491939101615bcd565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136d89190615cc4565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b600080613742858585613ac8565b905061374d816113c2565b61375b576000915050613782565b67ffffffffffffffff86166000908152600960209081526040808320938352929052205490505b949350505050565b60006002613799608085615496565b67ffffffffffffffff166137ad91906154bd565b905060006137bb8585611c60565b9050816137ca6001600461546d565b901b1916818360038111156137e1576137e1614257565b67ffffffffffffffff871660009081526008602052604081209190921b9290921791829161381060808861573b565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906138769087908790600401615d24565b600060405180830381600087803b15801561389057600080fd5b505af19250505080156138a1575060015b6138e0573d8080156138cf576040519150601f19603f3d011682016040523d82523d6000602084013e6138d4565b606091505b506003925090506138f5565b50506040805160208101909152600081526002905b9250929050565b6000815160201461393b57816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161080b9190613e9e565b6000828060200190518101906139519190615b62565b90506001600160a01b03811180613969575061040081105b15610aa657826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161080b9190613e9e565b6000606060008361ffff1667ffffffffffffffff8111156139c5576139c5614050565b6040519080825280601f01601f1916602001820160405280156139ef576020820181803683370190505b509150863b613a22577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613a55577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613a8e577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613ab15750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b09576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b1d57506101018111155b613b3a576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613b64576040516309bde33960e01b815260040160405180910390fd5b80600003613b915786600081518110613b7f57613b7f615218565b60200260200101519350505050613d60565b60008167ffffffffffffffff811115613bac57613bac614050565b604051908082528060200260200182016040528015613bd5578160200160208202803683370190505b50905060008080805b85811015613cff5760006001821b8b811603613c395788851015613c22578c5160018601958e918110613c1357613c13615218565b60200260200101519050613c5b565b8551600185019487918110613c1357613c13615218565b8b5160018401938d918110613c5057613c50615218565b602002602001015190505b600089861015613c8b578d5160018701968f918110613c7c57613c7c615218565b60200260200101519050613cad565b8651600186019588918110613ca257613ca2615218565b602002602001015190505b82851115613cce576040516309bde33960e01b815260040160405180910390fd5b613cd88282613d67565b878481518110613cea57613cea615218565b60209081029190910101525050600101613bde565b506001850382148015613d1157508683145b8015613d1c57508581145b613d39576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613d4e57613d4e615218565b60200260200101519750505050505050505b9392505050565b6000818310613d7f57613d7a8284613d85565b610aa3565b610aa383835b604080516001602082015290810183905260608101829052600090608001613716565b828054828255906000526020600020908101928215613e0a579160200282015b82811115613e0a578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613dc8565b50613e16929150613e39565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e165760008155600101613e3a565b60005b83811015613e69578181015183820152602001613e51565b50506000910152565b60008151808452613e8a816020860160208601613e4e565b601f01601f19169290920160200192915050565b602081526000610aa36020830184613e72565b8060608101831015610aa657600080fd5b60008083601f840112613ed457600080fd5b50813567ffffffffffffffff811115613eec57600080fd5b6020830191508360208285010111156138f557600080fd5b60008083601f840112613f1657600080fd5b50813567ffffffffffffffff811115613f2e57600080fd5b6020830191508360208260051b85010111156138f557600080fd5b60008060008060008060008060e0898b031215613f6557600080fd5b613f6f8a8a613eb1565b9750606089013567ffffffffffffffff80821115613f8c57600080fd5b613f988c838d01613ec2565b909950975060808b0135915080821115613fb157600080fd5b613fbd8c838d01613f04565b909750955060a08b0135915080821115613fd657600080fd5b50613fe38b828c01613f04565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561401157600080fd5b61401b8585613eb1565b9250606084013567ffffffffffffffff81111561403757600080fd5b61404386828701613ec2565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff8111828210171561408957614089614050565b60405290565b60405160a0810167ffffffffffffffff8111828210171561408957614089614050565b6040516080810167ffffffffffffffff8111828210171561408957614089614050565b6040516060810167ffffffffffffffff8111828210171561408957614089614050565b6040805190810167ffffffffffffffff8111828210171561408957614089614050565b604051601f8201601f1916810167ffffffffffffffff8111828210171561414457614144614050565b604052919050565b6001600160a01b0381168114610a5357600080fd5b803561416c8161414c565b919050565b803563ffffffff8116811461416c57600080fd5b600060c0828403121561419757600080fd5b61419f614066565b82356141aa8161414c565b81526141b860208401614171565b60208201526141c960408401614171565b60408201526141da60608401614171565b606082015260808301356141ed8161414c565b608082015260a08301356142008161414c565b60a08201529392505050565b803567ffffffffffffffff8116811461416c57600080fd5b6000806040838503121561423757600080fd5b6142408361420c565b915061424e6020840161420c565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061427d5761427d614257565b9052565b60208101610aa6828461426d565b600067ffffffffffffffff8211156142a9576142a9614050565b5060051b60200190565b600060a082840312156142c557600080fd5b6142cd61408f565b9050813581526142df6020830161420c565b60208201526142f06040830161420c565b60408201526143016060830161420c565b60608201526143126080830161420c565b608082015292915050565b600067ffffffffffffffff82111561433757614337614050565b50601f01601f191660200190565b600082601f83011261435657600080fd5b81356143696143648261431d565b61411b565b81815284602083860101111561437e57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126143ac57600080fd5b813560206143bc6143648361428f565b82815260059290921b840181019181810190868411156143db57600080fd5b8286015b848110156144b157803567ffffffffffffffff808211156144005760008081fd5b8189019150608080601f19848d0301121561441b5760008081fd5b6144236140b2565b87840135838111156144355760008081fd5b6144438d8a83880101614345565b8252506040808501358481111561445a5760008081fd5b6144688e8b83890101614345565b8a84015250606080860135858111156144815760008081fd5b61448f8f8c838a0101614345565b92840192909252949092013593810193909352505083529183019183016143df565b509695505050505050565b600061014082840312156144cf57600080fd5b6144d7614066565b90506144e383836142b3565b815260a082013567ffffffffffffffff8082111561450057600080fd5b61450c85838601614345565b602084015260c084013591508082111561452557600080fd5b61453185838601614345565b604084015261454260e08501614161565b6060840152610100840135608084015261012084013591508082111561456757600080fd5b506145748482850161439b565b60a08301525092915050565b600082601f83011261459157600080fd5b813560206145a16143648361428f565b82815260059290921b840181019181810190868411156145c057600080fd5b8286015b848110156144b157803567ffffffffffffffff8111156145e45760008081fd5b6145f28986838b01016144bc565b8452509183019183016145c4565b600082601f83011261461157600080fd5b813560206146216143648361428f565b82815260059290921b8401810191818101908684111561464057600080fd5b8286015b848110156144b157803567ffffffffffffffff8111156146645760008081fd5b6146728986838b0101614345565b845250918301918301614644565b600082601f83011261469157600080fd5b813560206146a16143648361428f565b82815260059290921b840181019181810190868411156146c057600080fd5b8286015b848110156144b157803567ffffffffffffffff8111156146e45760008081fd5b6146f28986838b0101614600565b8452509183019183016146c4565b600082601f83011261471157600080fd5b813560206147216143648361428f565b8083825260208201915060208460051b87010193508684111561474357600080fd5b602086015b848110156144b15780358352918301918301614748565b600082601f83011261477057600080fd5b813560206147806143648361428f565b82815260059290921b8401810191818101908684111561479f57600080fd5b8286015b848110156144b157803567ffffffffffffffff808211156147c45760008081fd5b818901915060a080601f19848d030112156147df5760008081fd5b6147e761408f565b6147f288850161420c565b8152604080850135848111156148085760008081fd5b6148168e8b83890101614580565b8a840152506060808601358581111561482f5760008081fd5b61483d8f8c838a0101614680565b83850152506080915081860135858111156148585760008081fd5b6148668f8c838a0101614700565b91840191909152509190930135908301525083529183019183016147a3565b600080604080848603121561489957600080fd5b833567ffffffffffffffff808211156148b157600080fd5b6148bd8783880161475f565b94506020915081860135818111156148d457600080fd5b8601601f810188136148e557600080fd5b80356148f36143648261428f565b81815260059190911b8201840190848101908a83111561491257600080fd5b8584015b8381101561499e5780358681111561492e5760008081fd5b8501603f81018d136149405760008081fd5b878101356149506143648261428f565b81815260059190911b82018a0190898101908f8311156149705760008081fd5b928b01925b8284101561498e5783358252928a0192908a0190614975565b8652505050918601918601614916565b50809750505050505050509250929050565b6000602082840312156149c257600080fd5b813567ffffffffffffffff8111156149d957600080fd5b820160a08185031215613d6057600080fd5b8015158114610a5357600080fd5b803561416c816149eb565b60006020808385031215614a1757600080fd5b823567ffffffffffffffff80821115614a2f57600080fd5b818501915085601f830112614a4357600080fd5b8135614a516143648261428f565b81815260059190911b83018401908481019088831115614a7057600080fd5b8585015b83811015614b0057803585811115614a8c5760008081fd5b86016060818c03601f1901811315614aa45760008081fd5b614aac6140d5565b614ab78a840161420c565b8152604080840135614ac8816149eb565b828c0152918301359188831115614adf5760008081fd5b614aed8e8c85870101614345565b9082015285525050918601918601614a74565b5098975050505050505050565b803560ff8116811461416c57600080fd5b600060208284031215614b3057600080fd5b610aa382614b0d565b60008151808452602080850194506020840160005b83811015614b735781516001600160a01b031687529582019590820190600101614b4e565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614bcd60e0840182614b39565b90506040840151601f198483030160c0850152614bea8282614b39565b95945050505050565b60008060408385031215614c0657600080fd5b614c0f8361420c565b946020939093013593505050565b60008060208385031215614c3057600080fd5b823567ffffffffffffffff80821115614c4857600080fd5b818501915085601f830112614c5c57600080fd5b813581811115614c6b57600080fd5b8660208260061b8501011115614c8057600080fd5b60209290920196919550909350505050565b600060208284031215614ca457600080fd5b610aa38261420c565b6020815281511515602082015267ffffffffffffffff6020830151166040820152600060408301516060808401526137826080840182613e72565b60008060408385031215614cfb57600080fd5b823567ffffffffffffffff80821115614d1357600080fd5b614d1f868387016144bc565b93506020850135915080821115614d3557600080fd5b50614d4285828601614600565b9150509250929050565b600060208284031215614d5e57600080fd5b8135613d608161414c565b600082601f830112614d7a57600080fd5b81356020614d8a6143648361428f565b8083825260208201915060208460051b870101935086841115614dac57600080fd5b602086015b848110156144b1578035614dc48161414c565b8352918301918301614db1565b60006020808385031215614de457600080fd5b823567ffffffffffffffff80821115614dfc57600080fd5b818501915085601f830112614e1057600080fd5b8135614e1e6143648261428f565b81815260059190911b83018401908481019088831115614e3d57600080fd5b8585015b83811015614b0057803585811115614e5857600080fd5b860160c0818c03601f19011215614e6f5760008081fd5b614e77614066565b8882013581526040614e8a818401614b0d565b8a8301526060614e9b818501614b0d565b8284015260809150614eae8285016149f9565b9083015260a08381013589811115614ec65760008081fd5b614ed48f8d83880101614d69565b838501525060c0840135915088821115614eee5760008081fd5b614efc8e8c84870101614d69565b9083015250845250918601918601614e41565b600060208284031215614f2157600080fd5b5035919050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461416c57600080fd5b600082601f830112614f6557600080fd5b81356020614f756143648361428f565b82815260069290921b84018101918181019086841115614f9457600080fd5b8286015b848110156144b15760408189031215614fb15760008081fd5b614fb96140f8565b614fc28261420c565b8152614fcf858301614f28565b81860152835291830191604001614f98565b600082601f830112614ff257600080fd5b813560206150026143648361428f565b82815260079290921b8401810191818101908684111561502157600080fd5b8286015b848110156144b157808803608081121561503f5760008081fd5b6150476140d5565b6150508361420c565b8152604080601f19840112156150665760008081fd5b61506e6140f8565b925061507b87850161420c565b835261508881850161420c565b8388015281870192909252606083013591810191909152835291830191608001615025565b600060208083850312156150c057600080fd5b823567ffffffffffffffff808211156150d857600080fd5b818501915060408083880312156150ee57600080fd5b6150f66140f8565b83358381111561510557600080fd5b84016040818a03121561511757600080fd5b61511f6140f8565b81358581111561512e57600080fd5b8201601f81018b1361513f57600080fd5b803561514d6143648261428f565b81815260069190911b8201890190898101908d83111561516c57600080fd5b928a01925b828410156151bc5787848f0312156151895760008081fd5b6151916140f8565b843561519c8161414c565b81526151a9858d01614f28565b818d0152825292870192908a0190615171565b8452505050818701359350848411156151d457600080fd5b6151e08a858401614f54565b81880152825250838501359150828211156151fa57600080fd5b61520688838601614fe1565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561529a57835180516001600160a01b031684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685840152928401929185019160010161524e565b50508583015187820388850152805180835290840192506000918401905b80831015615309578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858301529284019260019290920191908501906152b8565b50979650505050505050565b602081526000610aa3602083018461522e565b67ffffffffffffffff8316815260608101613d606020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153945761539461535d565b5092915050565b6000602080835260608451604080848701526153ba606087018361522e565b87850151878203601f19016040890152805180835290860193506000918601905b80831015614b0057845167ffffffffffffffff81511683528781015161541a89850182805167ffffffffffffffff908116835260209182015116910152565b508401518287015293860193600192909201916080909101906153db565b60006020828403121561544a57600080fd5b813567ffffffffffffffff81111561546157600080fd5b6137828482850161475f565b81810381811115610aa657610aa661535d565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff808416806154b1576154b1615480565b92169190910692915050565b8082028115828204841417610aa657610aa661535d565b6000604082840312156154e657600080fd5b6154ee6140f8565b6154f78361420c565b8152602083013560208201528091505092915050565b600181811c9082168061552157607f821691505b60208210810361554157634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261557b60a0870182613e72565b9050606085015186820360608801526155948282613e72565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561530957835180516001600160a01b03168352860151868301529285019260019290920191908401906155b7565b602081526000610aa36020830184615547565b60808152600061560f6080830187615547565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561564d57600080fd5b8351615658816149eb565b602085015190935067ffffffffffffffff81111561567557600080fd5b8401601f8101861361568657600080fd5b80516156946143648261431d565b8181528760208385010111156156a957600080fd5b6156ba826020830160208601613e4e565b809450505050604084015190509250925092565b6000602082840312156156e057600080fd5b8151613d60816149eb565b80820180821115610aa657610aa661535d565b60ff8181168382160190811115610aa657610aa661535d565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061575657615756615480565b92169190910492915050565b601f821115610d05576000816000526020600020601f850160051c8101602086101561578b5750805b601f850160051c820191505b818110156124a057828155600101615797565b815167ffffffffffffffff8111156157c4576157c4614050565b6157d8816157d2845461550d565b84615762565b602080601f83116001811461580d57600084156157f55750858301515b600019600386901b1c1916600185901b1785556124a0565b600085815260208120601f198616915b8281101561583c5788860151825594840194600190910190840161581d565b508582101561585a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020808352835460ff81161515602085015267ffffffffffffffff8160081c166040850152506001808501606080860152600081546158aa8161550d565b80608089015260a060018316600081146158cb57600181146158e757615917565b60ff19841660a08b015260a083151560051b8b01019450615917565b85600052602060002060005b8481101561590e5781548c82018501529088019089016158f3565b8b0160a0019550505b50929998505050505050505050565b602081016005831061593a5761593a614257565b91905290565b60ff81811683821602908116908181146153945761539461535d565b600060a0820160ff88168352602087602085015260a0604085015281875480845260c086019150886000526020600020935060005b818110156159b65784546001600160a01b031683526001948501949284019201615991565b505084810360608601526159ca8188614b39565b935050505060ff831660808301529695505050505050565b600067ffffffffffffffff808616835280851660208401525060606040830152614bea6060830184613e72565b8281526040602082015260006137826040830184613e72565b67ffffffffffffffff84811682528316602082015260608101613782604083018461426d565b615a58818461426d565b6040602082015260006137826040830184613e72565b600060208284031215615a8057600080fd5b8151613d608161414c565b6020815260008251610100806020850152615aaa610120850183613e72565b91506020850151615ac7604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615b0160a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615b1e8483613e72565b935060c08701519150808685030160e0870152615b3b8483613e72565b935060e0870151915080868503018387015250615b588382613e72565b9695505050505050565b600060208284031215615b7457600080fd5b5051919050565b600060ff821660ff8103615b9157615b9161535d565b60010192915050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152615b586080830184613e72565b86815260c060208201526000615be660c0830188613e72565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615cb757601f19868403018952815160808151818652615c6382870182613e72565b9150508582015185820387870152615c7b8282613e72565b91505060408083015186830382880152615c958382613e72565b6060948501519790940196909652505098840198925090830190600101615c3d565b5090979650505050505050565b602081526000610aa36020830184615c20565b60008282518085526020808601955060208260051b8401016020860160005b84811015615cb757601f19868403018952615d12838351613e72565b98840198925090830190600101615cf6565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615d8c610180850183613e72565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615dc98483613e72565b935060608801519150615de86101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615e0f8282615c20565b9150508281036020840152614bea8185615cd756fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162006a8d38038062006a8d8339810160408190526200003591620008e2565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003fc565b50505062000c57565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60a08101516001600160a01b03161580620002c8575080516001600160a01b0316155b15620002e7576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b0319908116928e1692909217905560a0808e01805160068054909416908f161790925586519a8b5297518716988a0198909852925185169388019390935251909216958501959095525185169383019390935251909216908201527f0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c9060c00160405180910390a150565b60005b81518110156200064e57600082828151811062000420576200042062000a20565b60200260200101519050600081600001519050806001600160401b03166000036200045e5760405163c656089560e01b815260040160405180910390fd5b6001600160401b03811660009081526007602052604081206001810180549192916200048a9062000a36565b80601f0160208091040260200160405190810160405280929190818152602001828054620004b89062000a36565b8015620005095780601f10620004dd5761010080835404028352916020019162000509565b820191906000526020600020905b815481529060010190602001808311620004eb57829003601f168201915b505050505090506000846040015190508151600003620005ac57805160000362000546576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000556828262000ac7565b508254610100600160481b0319166101001783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005e7565b8080519060200120828051906020012014620005e75760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b6020850151835460ff19169015151783556040516001600160401b038516907f4f49973170c548fddd4a48341b75e131818913f38f44d47af57e8735eee588ba906200063590869062000b93565b60405180910390a25050505050806001019050620003ff565b5050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200068d576200068d62000652565b60405290565b604051608081016001600160401b03811182821017156200068d576200068d62000652565b60405160c081016001600160401b03811182821017156200068d576200068d62000652565b604051601f8201601f191681016001600160401b038111828210171562000708576200070862000652565b604052919050565b80516001600160401b03811681146200072857600080fd5b919050565b80516001600160a01b03811681146200072857600080fd5b805163ffffffff811681146200072857600080fd5b6000601f83601f8401126200076e57600080fd5b825160206001600160401b03808311156200078d576200078d62000652565b8260051b6200079e838201620006dd565b9384528681018301938381019089861115620007b957600080fd5b84890192505b85831015620008d557825184811115620007d95760008081fd5b89016060601f19828d038101821315620007f35760008081fd5b620007fd62000668565b6200080a89850162000710565b81526040808501518015158114620008225760008081fd5b828b01529284015192888411156200083a5760008081fd5b83850194508e603f8601126200085257600093508384fd5b898501519350888411156200086b576200086b62000652565b6200087c8a848e87011601620006dd565b92508383528e81858701011115620008945760008081fd5b60005b84811015620008b4578581018201518482018c01528a0162000897565b5060009383018a0193909352918201528352509184019190840190620007bf565b9998505050505050505050565b6000806000838503610160811215620008fa57600080fd5b60808112156200090957600080fd5b6200091362000693565b6200091e8662000710565b81526200092e602087016200072d565b602082015262000941604087016200072d565b604082015262000954606087016200072d565b6060820152935060c0607f19820112156200096e57600080fd5b5062000979620006b8565b62000987608086016200072d565b81526200099760a0860162000745565b6020820152620009aa60c0860162000745565b6040820152620009bd60e0860162000745565b6060820152620009d161010086016200072d565b6080820152620009e561012086016200072d565b60a08201526101408501519092506001600160401b0381111562000a0857600080fd5b62000a16868287016200075a565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4b57607f821691505b60208210810362000a6c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000ac2576000816000526020600020601f850160051c8101602086101562000a9d5750805b601f850160051c820191505b8181101562000abe5782815560010162000aa9565b5050505b505050565b81516001600160401b0381111562000ae35762000ae362000652565b62000afb8162000af4845462000a36565b8462000a72565b602080601f83116001811462000b33576000841562000b1a5750858301515b600019600386901b1c1916600185901b17855562000abe565b600085815260208120601f198616915b8281101562000b645788860151825594840194600190910190840162000b43565b508582101562000b835787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252825460ff811615158383015260081c6001600160401b0316604083015260608083015260018084018054600093929190849062000bd58162000a36565b80608089015260a0600183166000811462000bf9576001811462000c165762000c48565b60ff19841660a08b015260a083151560051b8b0101945062000c48565b85600052602060002060005b8481101562000c3f5781548c820185015290880190890162000c22565b8b0160a0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615dc762000cc66000396000818161023e0152612be801526000818161020f0152612ec20152600081816101e00152818161141801526114cf0152600081816101b001526127cc015260008181611caa0152611cf60152615dc76000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b146105ca578063f716f99f146105dd578063ff888fb1146105f057600080fd5b8063d2a15d3514610584578063e9d68a8e14610597578063ece670b6146105b757600080fd5b8063a12a9870116100bd578063a12a98701461050c578063c673e5841461051f578063ccd37ba31461053f57600080fd5b806385572ffb146104e35780638da5cb5b146104f157600080fd5b8063403b2d631161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104c85780637d4eef60146104d057600080fd5b8063403b2d63146103525780635e36480c1461036557600080fd5b80632d04ab76116101605780632d04ab761461030e578063311cd513146103235780633f4b04aa1461033657600080fd5b806306285c691461017c578063181f5a77146102c5575b600080fd5b61026e60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102bc9190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103016040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102bc9190613e34565b61032161031c366004613edf565b610613565b005b610321610331366004613f92565b6109d9565b600a5460405167ffffffffffffffff90911681526020016102bc565b61032161036036600461411b565b610a42565b6103786103733660046141ba565b610a56565b6040516102bc9190614217565b61045f6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c0810182526004546001600160a01b03808216835263ffffffff74010000000000000000000000000000000000000000830481166020850152780100000000000000000000000000000000000000000000000083048116948401949094527c010000000000000000000000000000000000000000000000000000000090910490921660608201526005548216608082015260065490911660a082015290565b6040516102bc9190600060c0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401528060a08501511660a08401525092915050565b610321610aac565b6103216104de36600461481b565b610b6a565b610321610177366004614946565b6000546040516001600160a01b0390911681526020016102bc565b61032161051a36600461499a565b610d0a565b61053261052d366004614ab4565b610d1b565b6040516102bc9190614b14565b61057661054d366004614b89565b67ffffffffffffffff919091166000908152600960209081526040808320938352929052205490565b6040519081526020016102bc565b610321610592366004614bb3565b610e79565b6105aa6105a5366004614c28565b610f33565b6040516102bc9190614c43565b6103216105c5366004614c7e565b61101c565b6103216105d8366004614ce2565b61136f565b6103216105eb366004614d67565b611380565b6106036105fe366004614ea5565b6113c2565b60405190151581526020016102bc565b600061062187890189615043565b8051515190915015158061063a57508051602001515115155b1561073a57600a5460208a01359067ffffffffffffffff808316911610156106f957600a805467ffffffffffffffff191667ffffffffffffffff831617905560065482516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921691633937306f916106c2916004016152ab565b600060405180830381600087803b1580156106dc57600080fd5b505af11580156106f0573d6000803e3d6000fd5b50505050610738565b816020015151600003610738576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b81602001515181101561092257600082602001518281518110610762576107626151ae565b6020026020010151905060008160000151905061077e81611483565b600061078982611585565b602084015151815491925067ffffffffffffffff908116610100909204161415806107cb575060208084015190810151905167ffffffffffffffff9182169116115b1561081457825160208401516040517feefb0cac00000000000000000000000000000000000000000000000000000000815261080b9291906004016152be565b60405180910390fd5b604083015180610850576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600960209081526040808320848452909152902054156108c35783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024810182905260440161080b565b60208085015101516108d6906001615309565b825468ffffffffffffffff00191661010067ffffffffffffffff92831602179092559251166000908152600960209081526040808320948352939052919091204290555060010161073d565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d816040516109529190615331565b60405180910390a16109ce60008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506115e5915050565b505050505050505050565b610a196109e8828401846153ce565b6040805160008082526020820190925290610a13565b60608152602001906001900390816109fe5790505b5061195c565b604080516000808252602082019092529050610a3c6001858585858660006115e5565b50505050565b610a4a611a0c565b610a5381611a68565b50565b6000610a6460016004615403565b6002610a7160808561542c565b67ffffffffffffffff16610a859190615453565b610a8f8585611c60565b901c166003811115610aa357610aa36141ed565b90505b92915050565b6001546001600160a01b03163314610b065760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161080b565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b72611ca7565b815181518114610bae576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610cfa576000848281518110610bcd57610bcd6151ae565b60200260200101519050600081602001515190506000858481518110610bf557610bf56151ae565b6020026020010151905080518214610c39576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610ceb576000828281518110610c5857610c586151ae565b6020026020010151905080600014610ce25784602001518281518110610c8057610c806151ae565b602002602001015160800151811015610ce25784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018390526044810182905260640161080b565b50600101610c3c565b50505050806001019050610bb1565b50610d05838361195c565b505050565b610d12611a0c565b610a5381611d28565b610d5e6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610e0757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610de9575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e6957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e4b575b5050505050815250509050919050565b610e81611a0c565b60005b81811015610d05576000838383818110610ea057610ea06151ae565b905060400201803603810190610eb6919061546a565b9050610ec581602001516113c2565b610f2a57805167ffffffffffffffff1660009081526009602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e84565b60408051606080820183526000808352602080840182905283850183905267ffffffffffffffff8681168352600782529185902085519384018652805460ff811615158552610100900490921690830152600181018054939492939192840191610f9c906154a3565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc8906154a3565b8015610e695780601f10610fea57610100808354040283529160200191610e69565b820191906000526020600020905b815481529060010190602001808311610ff857505050919092525091949350505050565b333014611055576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611092565b604080518082019091526000808252602082015281526020019060019003908161106b5790505b5060a084015151909150156110c5576110c28360a001518460200151856060015186600001516020015186611fb4565b90505b6040805160a0810182528451518152845160209081015167ffffffffffffffff1681830152808601518351600094840192611101929101613e34565b60408051601f19818403018152918152908252868101516020830152018390526005549091506001600160a01b0316801561120e576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a19061117b90859060040161557f565b600060405180830381600087803b15801561119557600080fd5b505af19250505080156111a6575060015b61120e573d8080156111d4576040519150601f19603f3d011682016040523d82523d6000602084013e6111d9565b606091505b50806040517f09c2532500000000000000000000000000000000000000000000000000000000815260040161080b9190613e34565b60408501515115801561122357506080850151155b8061123a575060608501516001600160a01b03163b155b8061127a57506060850151611278906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612092565b155b15611286575050505050565b60048054608087015160608801516040517f3cf9798300000000000000000000000000000000000000000000000000000000815260009485946001600160a01b031693633cf97983936112e1938a9361138893929101615592565b6000604051808303816000875af1158015611300573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261132891908101906155ce565b50915091508161136657806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161080b9190613e34565b50505050505050565b611377611a0c565b610a53816120ae565b611388611a0c565b60005b81518110156113be576113b68282815181106113a9576113a96151ae565b6020026020010151612164565b60010161138b565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa15801561145f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa69190615664565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561151e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115429190615664565b15610a53576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080b565b67ffffffffffffffff81166000908152600760205260408120805460ff16610aa6576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080b565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906116448760a4615681565b905082606001511561168c57845161165d906020615453565b865161166a906020615453565b6116759060a0615681565b61167f9190615681565b6116899082615681565b90505b3681146116ce576040517f8e1192e10000000000000000000000000000000000000000000000000000000081526004810182905236602482015260440161080b565b50815181146117165781516040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101919091526024810182905260440161080b565b61171e611ca7565b60ff808a166000908152600360209081526040808320338452825280832081518083019092528054808616835293949193909284019161010090910416600281111561176c5761176c6141ed565b600281111561177d5761177d6141ed565b905250905060028160200151600281111561179a5761179a6141ed565b1480156117ee5750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff16815481106117d6576117d66151ae565b6000918252602090912001546001600160a01b031633145b611824576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5081606001511561190657602082015161183f906001615694565b60ff1685511461187b576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83518551146118b6576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600087876040516118c89291906156ad565b6040519081900381206118df918b906020016156bd565b6040516020818303038152906040528051906020012090506119048a828888886124a8565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611996576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611a05576119fd8582815181106119cb576119cb6151ae565b6020026020010151846119f7578583815181106119ea576119ea6151ae565b60200260200101516126bf565b836126bf565b6001016119ad565b5050505050565b6000546001600160a01b03163314611a665760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161080b565b565b60a08101516001600160a01b03161580611a8a575080516001600160a01b0316155b15611ac1576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a177401000000000000000000000000000000000000000063ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16939093177c010000000000000000000000000000000000000000000000000000000093871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff19908116928e1692909217905560a0808e01805160068054909416908f161790925586519a8b5297518716988a0198909852925185169388019390935251909216958501959095525185169383019390935251909216908201527f0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c9060c00160405180910390a150565b67ffffffffffffffff8216600090815260086020526040812081611c856080856156d1565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f000000000000000000000000000000000000000000000000000000000000000014611a66576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015246602482015260440161080b565b60005b81518110156113be576000828281518110611d4857611d486151ae565b602002602001015190506000816000015190508067ffffffffffffffff16600003611d9f576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600760205260408120600181018054919291611dca906154a3565b80601f0160208091040260200160405190810160405280929190818152602001828054611df6906154a3565b8015611e435780601f10611e1857610100808354040283529160200191611e43565b820191906000526020600020905b815481529060010190602001808311611e2657829003601f168201915b505050505090506000846040015190508151600003611efc578051600003611e97576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301611ea58282615740565b50825468ffffffffffffffff00191661010017835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611f4f565b8080519060200120828051906020012014611f4f576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8516600482015260240161080b565b6020850151835460ff191690151517835560405167ffffffffffffffff8516907f4f49973170c548fddd4a48341b75e131818913f38f44d47af57e8735eee588ba90611f9c908690615800565b60405180910390a25050505050806001019050611d2b565b6060855167ffffffffffffffff811115611fd057611fd0613fe6565b60405190808252806020026020018201604052801561201557816020015b6040805180820190915260008082526020820152815260200190600190039081611fee5790505b50905060005b865181101561208857612063878281518110612039576120396151ae565b6020026020010151878787878681518110612056576120566151ae565b6020026020010151612e61565b828281518110612075576120756151ae565b602090810291909101015260010161201b565b5095945050505050565b600061209d83613270565b8015610aa35750610aa383836132d4565b336001600160a01b038216036121065760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161080b565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff1660000361218f576000604051631b3fab5160e11b815260040161080b91906158bc565b60208082015160ff808216600090815260029093526040832060018101549293909283921690036121fc57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612251565b6060840151600182015460ff6201000090910416151590151514612251576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff8416600482015260240161080b565b60a08401518051601f60ff82161115612280576001604051631b3fab5160e11b815260040161080b91906158bc565b6122e685856003018054806020026020016040519081016040528092919081815260200182805480156122dc57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122be575b50505050506133a3565b8560600151156124155761235485856002018054806020026020016040519081016040528092919081815260200182805480156122dc576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122be5750505050506133a3565b6080860151805161236e9060028701906020840190613d3e565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f10156123ce576002604051631b3fab5160e11b815260040161080b91906158bc565b60408801516123de9060036158d6565b60ff168160ff1611612406576003604051631b3fab5160e11b815260040161080b91906158bc565b6124128783600161340c565b50505b6124218583600261340c565b81516124369060038601906020850190613d3e565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f5479361248f938a939260028b019291906158f2565b60405180910390a16124a08561358c565b505050505050565b6124b0613db0565b835160005b818110156126b55760006001888684602081106124d4576124d46151ae565b6124e191901a601b615694565b8985815181106124f3576124f36151ae565b602002602001015189868151811061250d5761250d6151ae565b60200260200101516040516000815260200160405260405161254b949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561256d573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b038516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156125ce576125ce6141ed565b60028111156125df576125df6141ed565b90525090506001816020015160028111156125fc576125fc6141ed565b14612633576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061264a5761264a6151ae565b602002015115612686576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126a1576126a16151ae565b9115156020909202015250506001016124b5565b5050505050505050565b81516126ca81611483565b60006126d582611585565b6020850151519091506000819003612718576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151518114612756576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561277157612771613fe6565b60405190808252806020026020018201604052801561279a578160200160208202803683370190505b50905060005b8281101561290f576000876020015182815181106127c0576127c06151ae565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461285357805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161080b565b6128e981866001018054612866906154a3565b80601f0160208091040260200160405190810160405280929190818152602001828054612892906154a3565b80156128df5780601f106128b4576101008083540402835291602001916128df565b820191906000526020600020905b8154815290600101906020018083116128c257829003601f168201915b50505050506135a8565b8383815181106128fb576128fb6151ae565b6020908102919091010152506001016127a0565b506000612926858389606001518a608001516136ca565b90508060000361296e576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015260240161080b565b8551151560005b848110156109ce57600089602001518281518110612995576129956151ae565b6020026020010151905060006129b389836000015160600151610a56565b905060008160038111156129c9576129c96141ed565b14806129e6575060038160038111156129e4576129e46141ed565b145b612a3d578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612e59565b8315612b1e5760045460009074010000000000000000000000000000000000000000900463ffffffff16612a718742615403565b1190508080612a9157506003826003811115612a8f57612a8f6141ed565b145b612ad3576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b16600482015260240161080b565b8a8481518110612ae557612ae56151ae565b6020026020010151600014612b18578a8481518110612b0657612b066151ae565b60200260200101518360800181815250505b50612b7f565b6000816003811115612b3257612b326141ed565b14612b7f578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612a2e565b81516080015167ffffffffffffffff1615612c6d576000816003811115612ba857612ba86141ed565b03612c6d5781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c1f928e929190600401615978565b6020604051808303816000875af1158015612c3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c629190615664565b612c6d575050612e59565b60008b604001518481518110612c8557612c856151ae565b6020026020010151905080518360a001515114612ce9578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d166004830152909116602482015260440161080b565b612cfd8a8460000151606001516001613720565b600080612d0a85846137c8565b91509150612d218c86600001516060015184613720565b8615612d91576003826003811115612d3b57612d3b6141ed565b03612d91576000846003811115612d5457612d546141ed565b14612d91578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261080b919083906004016159a5565b6002826003811115612da557612da56141ed565b14612dff576003826003811115612dbe57612dbe6141ed565b14612dff578451606001516040517f926c5a3e00000000000000000000000000000000000000000000000000000000815261080b918e9185906004016159be565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612e4b90879087906159e4565b60405180910390a450505050505b600101612975565b60408051808201909152600080825260208201526000612e848760200151613892565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f2d9190615a04565b90506001600160a01b0381161580612f755750612f736001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612092565b155b15612fb7576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b038216600482015260240161080b565b6000806130bd6040518061010001604052808b81526020018967ffffffffffffffff1681526020018a6001600160a01b031681526020018c606001518152602001866001600160a01b031681526020018c6000015181526020018c6040015181526020018881525060405160240161302f9190615a21565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3907753700000000000000000000000000000000000000000000000000000000179052600454859063ffffffff7c0100000000000000000000000000000000000000000000000000000000909104166113886084613938565b5091509150816130fb57806040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161080b9190613e34565b80516020146131435780516040517f78ef802400000000000000000000000000000000000000000000000000000000815260206004820152602481019190915260440161080b565b6000818060200190518101906131599190615af8565b6040516001600160a01b038b166024820152604481018290529091506132069060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600454879063ffffffff7801000000000000000000000000000000000000000000000000909104166113886084613938565b5090935091508261324557816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161080b9190613e34565b604080518082019091526001600160a01b039095168552602085015250919250505095945050505050565b600061329c827f01ffc9a7000000000000000000000000000000000000000000000000000000006132d4565b8015610aa657506132cd827fffffffff000000000000000000000000000000000000000000000000000000006132d4565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561338c575060208210155b80156133985750600081115b979650505050505050565b60005b8151811015610d055760ff8316600090815260036020526040812083519091908490849081106133d8576133d86151ae565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff191690556001016133a6565b60005b82518160ff161015610a3c576000838260ff1681518110613432576134326151ae565b602002602001015190506000600281111561344f5761344f6141ed565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561348e5761348e6141ed565b146134af576004604051631b3fab5160e11b815260040161080b91906158bc565b6001600160a01b0381166134ef576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff168152602001846002811115613515576135156141ed565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff191617610100836002811115613572576135726141ed565b0217905550905050508061358590615b11565b905061340f565b60ff8116610a5357600a805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936135ee937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615b30565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976136379794969395929491939101615b63565b604051602081830303815290604052805190602001208560400151805190602001208660a0015160405160200161366e9190615c5a565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b6000806136d8858585613a5e565b90506136e3816113c2565b6136f1576000915050613718565b67ffffffffffffffff86166000908152600960209081526040808320938352929052205490505b949350505050565b6000600261372f60808561542c565b67ffffffffffffffff166137439190615453565b905060006137518585611c60565b90508161376060016004615403565b901b191681836003811115613777576137776141ed565b67ffffffffffffffff871660009081526008602052604081209190921b929092179182916137a66080886156d1565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b69061380c9087908790600401615cba565b600060405180830381600087803b15801561382657600080fd5b505af1925050508015613837575060015b613876573d808015613865576040519150601f19603f3d011682016040523d82523d6000602084013e61386a565b606091505b5060039250905061388b565b50506040805160208101909152600081526002905b9250929050565b600081516020146138d157816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161080b9190613e34565b6000828060200190518101906138e79190615af8565b90506001600160a01b038111806138ff575061040081105b15610aa657826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161080b9190613e34565b6000606060008361ffff1667ffffffffffffffff81111561395b5761395b613fe6565b6040519080825280601f01601f191660200182016040528015613985576020820181803683370190505b509150863b6139b8577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a858110156139eb577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613a24577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613a475750835b808352806000602085013e50955095509592505050565b8251825160009190818303613a9f576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613ab357506101018111155b613ad0576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613afa576040516309bde33960e01b815260040160405180910390fd5b80600003613b275786600081518110613b1557613b156151ae565b60200260200101519350505050613cf6565b60008167ffffffffffffffff811115613b4257613b42613fe6565b604051908082528060200260200182016040528015613b6b578160200160208202803683370190505b50905060008080805b85811015613c955760006001821b8b811603613bcf5788851015613bb8578c5160018601958e918110613ba957613ba96151ae565b60200260200101519050613bf1565b8551600185019487918110613ba957613ba96151ae565b8b5160018401938d918110613be657613be66151ae565b602002602001015190505b600089861015613c21578d5160018701968f918110613c1257613c126151ae565b60200260200101519050613c43565b8651600186019588918110613c3857613c386151ae565b602002602001015190505b82851115613c64576040516309bde33960e01b815260040160405180910390fd5b613c6e8282613cfd565b878481518110613c8057613c806151ae565b60209081029190910101525050600101613b74565b506001850382148015613ca757508683145b8015613cb257508581145b613ccf576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613ce457613ce46151ae565b60200260200101519750505050505050505b9392505050565b6000818310613d1557613d108284613d1b565b610aa3565b610aa383835b6040805160016020820152908101839052606081018290526000906080016136ac565b828054828255906000526020600020908101928215613da0579160200282015b82811115613da0578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613d5e565b50613dac929150613dcf565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613dac5760008155600101613dd0565b60005b83811015613dff578181015183820152602001613de7565b50506000910152565b60008151808452613e20816020860160208601613de4565b601f01601f19169290920160200192915050565b602081526000610aa36020830184613e08565b8060608101831015610aa657600080fd5b60008083601f840112613e6a57600080fd5b50813567ffffffffffffffff811115613e8257600080fd5b60208301915083602082850101111561388b57600080fd5b60008083601f840112613eac57600080fd5b50813567ffffffffffffffff811115613ec457600080fd5b6020830191508360208260051b850101111561388b57600080fd5b60008060008060008060008060e0898b031215613efb57600080fd5b613f058a8a613e47565b9750606089013567ffffffffffffffff80821115613f2257600080fd5b613f2e8c838d01613e58565b909950975060808b0135915080821115613f4757600080fd5b613f538c838d01613e9a565b909750955060a08b0135915080821115613f6c57600080fd5b50613f798b828c01613e9a565b999c989b50969995989497949560c00135949350505050565b600080600060808486031215613fa757600080fd5b613fb18585613e47565b9250606084013567ffffffffffffffff811115613fcd57600080fd5b613fd986828701613e58565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff8111828210171561401f5761401f613fe6565b60405290565b60405160a0810167ffffffffffffffff8111828210171561401f5761401f613fe6565b6040516080810167ffffffffffffffff8111828210171561401f5761401f613fe6565b6040516060810167ffffffffffffffff8111828210171561401f5761401f613fe6565b6040805190810167ffffffffffffffff8111828210171561401f5761401f613fe6565b604051601f8201601f1916810167ffffffffffffffff811182821017156140da576140da613fe6565b604052919050565b6001600160a01b0381168114610a5357600080fd5b8035614102816140e2565b919050565b803563ffffffff8116811461410257600080fd5b600060c0828403121561412d57600080fd5b614135613ffc565b8235614140816140e2565b815261414e60208401614107565b602082015261415f60408401614107565b604082015261417060608401614107565b60608201526080830135614183816140e2565b608082015260a0830135614196816140e2565b60a08201529392505050565b803567ffffffffffffffff8116811461410257600080fd5b600080604083850312156141cd57600080fd5b6141d6836141a2565b91506141e4602084016141a2565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614213576142136141ed565b9052565b60208101610aa68284614203565b600067ffffffffffffffff82111561423f5761423f613fe6565b5060051b60200190565b600060a0828403121561425b57600080fd5b614263614025565b905081358152614275602083016141a2565b6020820152614286604083016141a2565b6040820152614297606083016141a2565b60608201526142a8608083016141a2565b608082015292915050565b600067ffffffffffffffff8211156142cd576142cd613fe6565b50601f01601f191660200190565b600082601f8301126142ec57600080fd5b81356142ff6142fa826142b3565b6140b1565b81815284602083860101111561431457600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261434257600080fd5b813560206143526142fa83614225565b82815260059290921b8401810191818101908684111561437157600080fd5b8286015b8481101561444757803567ffffffffffffffff808211156143965760008081fd5b8189019150608080601f19848d030112156143b15760008081fd5b6143b9614048565b87840135838111156143cb5760008081fd5b6143d98d8a838801016142db565b825250604080850135848111156143f05760008081fd5b6143fe8e8b838901016142db565b8a84015250606080860135858111156144175760008081fd5b6144258f8c838a01016142db565b9284019290925294909201359381019390935250508352918301918301614375565b509695505050505050565b6000610140828403121561446557600080fd5b61446d613ffc565b90506144798383614249565b815260a082013567ffffffffffffffff8082111561449657600080fd5b6144a2858386016142db565b602084015260c08401359150808211156144bb57600080fd5b6144c7858386016142db565b60408401526144d860e085016140f7565b606084015261010084013560808401526101208401359150808211156144fd57600080fd5b5061450a84828501614331565b60a08301525092915050565b600082601f83011261452757600080fd5b813560206145376142fa83614225565b82815260059290921b8401810191818101908684111561455657600080fd5b8286015b8481101561444757803567ffffffffffffffff81111561457a5760008081fd5b6145888986838b0101614452565b84525091830191830161455a565b600082601f8301126145a757600080fd5b813560206145b76142fa83614225565b82815260059290921b840181019181810190868411156145d657600080fd5b8286015b8481101561444757803567ffffffffffffffff8111156145fa5760008081fd5b6146088986838b01016142db565b8452509183019183016145da565b600082601f83011261462757600080fd5b813560206146376142fa83614225565b82815260059290921b8401810191818101908684111561465657600080fd5b8286015b8481101561444757803567ffffffffffffffff81111561467a5760008081fd5b6146888986838b0101614596565b84525091830191830161465a565b600082601f8301126146a757600080fd5b813560206146b76142fa83614225565b8083825260208201915060208460051b8701019350868411156146d957600080fd5b602086015b8481101561444757803583529183019183016146de565b600082601f83011261470657600080fd5b813560206147166142fa83614225565b82815260059290921b8401810191818101908684111561473557600080fd5b8286015b8481101561444757803567ffffffffffffffff8082111561475a5760008081fd5b818901915060a080601f19848d030112156147755760008081fd5b61477d614025565b6147888885016141a2565b81526040808501358481111561479e5760008081fd5b6147ac8e8b83890101614516565b8a84015250606080860135858111156147c55760008081fd5b6147d38f8c838a0101614616565b83850152506080915081860135858111156147ee5760008081fd5b6147fc8f8c838a0101614696565b9184019190915250919093013590830152508352918301918301614739565b600080604080848603121561482f57600080fd5b833567ffffffffffffffff8082111561484757600080fd5b614853878388016146f5565b945060209150818601358181111561486a57600080fd5b8601601f8101881361487b57600080fd5b80356148896142fa82614225565b81815260059190911b8201840190848101908a8311156148a857600080fd5b8584015b83811015614934578035868111156148c45760008081fd5b8501603f81018d136148d65760008081fd5b878101356148e66142fa82614225565b81815260059190911b82018a0190898101908f8311156149065760008081fd5b928b01925b828410156149245783358252928a0192908a019061490b565b86525050509186019186016148ac565b50809750505050505050509250929050565b60006020828403121561495857600080fd5b813567ffffffffffffffff81111561496f57600080fd5b820160a08185031215613cf657600080fd5b8015158114610a5357600080fd5b803561410281614981565b600060208083850312156149ad57600080fd5b823567ffffffffffffffff808211156149c557600080fd5b818501915085601f8301126149d957600080fd5b81356149e76142fa82614225565b81815260059190911b83018401908481019088831115614a0657600080fd5b8585015b83811015614a9657803585811115614a225760008081fd5b86016060818c03601f1901811315614a3a5760008081fd5b614a4261406b565b614a4d8a84016141a2565b8152604080840135614a5e81614981565b828c0152918301359188831115614a755760008081fd5b614a838e8c858701016142db565b9082015285525050918601918601614a0a565b5098975050505050505050565b803560ff8116811461410257600080fd5b600060208284031215614ac657600080fd5b610aa382614aa3565b60008151808452602080850194506020840160005b83811015614b095781516001600160a01b031687529582019590820190600101614ae4565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614b6360e0840182614acf565b90506040840151601f198483030160c0850152614b808282614acf565b95945050505050565b60008060408385031215614b9c57600080fd5b614ba5836141a2565b946020939093013593505050565b60008060208385031215614bc657600080fd5b823567ffffffffffffffff80821115614bde57600080fd5b818501915085601f830112614bf257600080fd5b813581811115614c0157600080fd5b8660208260061b8501011115614c1657600080fd5b60209290920196919550909350505050565b600060208284031215614c3a57600080fd5b610aa3826141a2565b6020815281511515602082015267ffffffffffffffff6020830151166040820152600060408301516060808401526137186080840182613e08565b60008060408385031215614c9157600080fd5b823567ffffffffffffffff80821115614ca957600080fd5b614cb586838701614452565b93506020850135915080821115614ccb57600080fd5b50614cd885828601614596565b9150509250929050565b600060208284031215614cf457600080fd5b8135613cf6816140e2565b600082601f830112614d1057600080fd5b81356020614d206142fa83614225565b8083825260208201915060208460051b870101935086841115614d4257600080fd5b602086015b84811015614447578035614d5a816140e2565b8352918301918301614d47565b60006020808385031215614d7a57600080fd5b823567ffffffffffffffff80821115614d9257600080fd5b818501915085601f830112614da657600080fd5b8135614db46142fa82614225565b81815260059190911b83018401908481019088831115614dd357600080fd5b8585015b83811015614a9657803585811115614dee57600080fd5b860160c0818c03601f19011215614e055760008081fd5b614e0d613ffc565b8882013581526040614e20818401614aa3565b8a8301526060614e31818501614aa3565b8284015260809150614e4482850161498f565b9083015260a08381013589811115614e5c5760008081fd5b614e6a8f8d83880101614cff565b838501525060c0840135915088821115614e845760008081fd5b614e928e8c84870101614cff565b9083015250845250918601918601614dd7565b600060208284031215614eb757600080fd5b5035919050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461410257600080fd5b600082601f830112614efb57600080fd5b81356020614f0b6142fa83614225565b82815260069290921b84018101918181019086841115614f2a57600080fd5b8286015b848110156144475760408189031215614f475760008081fd5b614f4f61408e565b614f58826141a2565b8152614f65858301614ebe565b81860152835291830191604001614f2e565b600082601f830112614f8857600080fd5b81356020614f986142fa83614225565b82815260079290921b84018101918181019086841115614fb757600080fd5b8286015b84811015614447578088036080811215614fd55760008081fd5b614fdd61406b565b614fe6836141a2565b8152604080601f1984011215614ffc5760008081fd5b61500461408e565b92506150118785016141a2565b835261501e8185016141a2565b8388015281870192909252606083013591810191909152835291830191608001614fbb565b6000602080838503121561505657600080fd5b823567ffffffffffffffff8082111561506e57600080fd5b8185019150604080838803121561508457600080fd5b61508c61408e565b83358381111561509b57600080fd5b84016040818a0312156150ad57600080fd5b6150b561408e565b8135858111156150c457600080fd5b8201601f81018b136150d557600080fd5b80356150e36142fa82614225565b81815260069190911b8201890190898101908d83111561510257600080fd5b928a01925b828410156151525787848f03121561511f5760008081fd5b61512761408e565b8435615132816140e2565b815261513f858d01614ebe565b818d0152825292870192908a0190615107565b84525050508187013593508484111561516a57600080fd5b6151768a858401614eea565b818801528252508385013591508282111561519057600080fd5b61519c88838601614f77565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561523057835180516001600160a01b031684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168584015292840192918501916001016151e4565b50508583015187820388850152805180835290840192506000918401905b8083101561529f578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168583015292840192600192909201919085019061524e565b50979650505050505050565b602081526000610aa360208301846151c4565b67ffffffffffffffff8316815260608101613cf66020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561532a5761532a6152f3565b5092915050565b60006020808352606084516040808487015261535060608701836151c4565b87850151878203601f19016040890152805180835290860193506000918601905b80831015614a9657845167ffffffffffffffff8151168352878101516153b089850182805167ffffffffffffffff908116835260209182015116910152565b50840151828701529386019360019290920191608090910190615371565b6000602082840312156153e057600080fd5b813567ffffffffffffffff8111156153f757600080fd5b613718848285016146f5565b81810381811115610aa657610aa66152f3565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff8084168061544757615447615416565b92169190910692915050565b8082028115828204841417610aa657610aa66152f3565b60006040828403121561547c57600080fd5b61548461408e565b61548d836141a2565b8152602083013560208201528091505092915050565b600181811c908216806154b757607f821691505b6020821081036154d757634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261551160a0870182613e08565b90506060850151868203606088015261552a8282613e08565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561529f57835180516001600160a01b031683528601518683015292850192600192909201919084019061554d565b602081526000610aa360208301846154dd565b6080815260006155a560808301876154dd565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b6000806000606084860312156155e357600080fd5b83516155ee81614981565b602085015190935067ffffffffffffffff81111561560b57600080fd5b8401601f8101861361561c57600080fd5b805161562a6142fa826142b3565b81815287602083850101111561563f57600080fd5b615650826020830160208601613de4565b809450505050604084015190509250925092565b60006020828403121561567657600080fd5b8151613cf681614981565b80820180821115610aa657610aa66152f3565b60ff8181168382160190811115610aa657610aa66152f3565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff808416806156ec576156ec615416565b92169190910492915050565b601f821115610d05576000816000526020600020601f850160051c810160208610156157215750805b601f850160051c820191505b818110156124a05782815560010161572d565b815167ffffffffffffffff81111561575a5761575a613fe6565b61576e8161576884546154a3565b846156f8565b602080601f8311600181146157a3576000841561578b5750858301515b600019600386901b1c1916600185901b1785556124a0565b600085815260208120601f198616915b828110156157d2578886015182559484019460019091019084016157b3565b50858210156157f05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020808352835460ff81161515602085015267ffffffffffffffff8160081c16604085015250600180850160608086015260008154615840816154a3565b80608089015260a06001831660008114615861576001811461587d576158ad565b60ff19841660a08b015260a083151560051b8b010194506158ad565b85600052602060002060005b848110156158a45781548c8201850152908801908901615889565b8b0160a0019550505b50929998505050505050505050565b60208101600583106158d0576158d06141ed565b91905290565b60ff818116838216029081169081811461532a5761532a6152f3565b600060a0820160ff88168352602087602085015260a0604085015281875480845260c086019150886000526020600020935060005b8181101561594c5784546001600160a01b031683526001948501949284019201615927565b505084810360608601526159608188614acf565b935050505060ff831660808301529695505050505050565b600067ffffffffffffffff808616835280851660208401525060606040830152614b806060830184613e08565b8281526040602082015260006137186040830184613e08565b67ffffffffffffffff848116825283166020820152606081016137186040830184614203565b6159ee8184614203565b6040602082015260006137186040830184613e08565b600060208284031215615a1657600080fd5b8151613cf6816140e2565b6020815260008251610100806020850152615a40610120850183613e08565b91506020850151615a5d604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615a9760a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615ab48483613e08565b935060c08701519150808685030160e0870152615ad18483613e08565b935060e0870151915080868503018387015250615aee8382613e08565b9695505050505050565b600060208284031215615b0a57600080fd5b5051919050565b600060ff821660ff8103615b2757615b276152f3565b60010192915050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152615aee6080830184613e08565b86815260c060208201526000615b7c60c0830188613e08565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615c4d57601f19868403018952815160808151818652615bf982870182613e08565b9150508582015185820387870152615c118282613e08565b91505060408083015186830382880152615c2b8382613e08565b6060948501519790940196909652505098840198925090830190600101615bd3565b5090979650505050505050565b602081526000610aa36020830184615bb6565b60008282518085526020808601955060208260051b8401016020860160005b84811015615c4d57601f19868403018952615ca8838351613e08565b98840198925090830190600101615c8c565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615d22610180850183613e08565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615d5f8483613e08565b935060608801519150615d7e6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615da58282615bb6565b9150508281036020840152614b808185615c6d56fea164736f6c6343000818000a", } var EVM2EVMMultiOffRampABI = EVM2EVMMultiOffRampMetaData.ABI @@ -662,6 +662,124 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) TransferOwners return _EVM2EVMMultiOffRamp.Contract.TransferOwnership(&_EVM2EVMMultiOffRamp.TransactOpts, to) } +type EVM2EVMMultiOffRampAlreadyAttemptedIterator struct { + Event *EVM2EVMMultiOffRampAlreadyAttempted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOffRampAlreadyAttemptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampAlreadyAttempted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOffRampAlreadyAttempted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOffRampAlreadyAttemptedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOffRampAlreadyAttemptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOffRampAlreadyAttempted struct { + SourceChainSelector uint64 + SequenceNumber uint64 + Raw types.Log +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterAlreadyAttempted(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampAlreadyAttemptedIterator, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "AlreadyAttempted") + if err != nil { + return nil, err + } + return &EVM2EVMMultiOffRampAlreadyAttemptedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "AlreadyAttempted", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchAlreadyAttempted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampAlreadyAttempted) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "AlreadyAttempted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOffRampAlreadyAttempted) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "AlreadyAttempted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseAlreadyAttempted(log types.Log) (*EVM2EVMMultiOffRampAlreadyAttempted, error) { + event := new(EVM2EVMMultiOffRampAlreadyAttempted) + if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "AlreadyAttempted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type EVM2EVMMultiOffRampCommitReportAcceptedIterator struct { Event *EVM2EVMMultiOffRampCommitReportAccepted @@ -2164,6 +2282,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseTransmitted(log ty func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { + case _EVM2EVMMultiOffRamp.abi.Events["AlreadyAttempted"].ID: + return _EVM2EVMMultiOffRamp.ParseAlreadyAttempted(log) case _EVM2EVMMultiOffRamp.abi.Events["CommitReportAccepted"].ID: return _EVM2EVMMultiOffRamp.ParseCommitReportAccepted(log) case _EVM2EVMMultiOffRamp.abi.Events["ConfigSet"].ID: @@ -2194,6 +2314,10 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRamp) ParseLog(log types.Log) (genera } } +func (EVM2EVMMultiOffRampAlreadyAttempted) Topic() common.Hash { + return common.HexToHash("0x3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe65120") +} + func (EVM2EVMMultiOffRampCommitReportAccepted) Topic() common.Hash { return common.HexToHash("0x3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d") } @@ -2289,6 +2413,12 @@ type EVM2EVMMultiOffRampInterface interface { TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + FilterAlreadyAttempted(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampAlreadyAttemptedIterator, error) + + WatchAlreadyAttempted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampAlreadyAttempted) (event.Subscription, error) + + ParseAlreadyAttempted(log types.Log) (*EVM2EVMMultiOffRampAlreadyAttempted, error) + FilterCommitReportAccepted(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampCommitReportAcceptedIterator, error) WatchCommitReportAccepted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampCommitReportAccepted) (event.Subscription, error) diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go index 2a4605bfd2..8e2cab8d8f 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go @@ -104,8 +104,8 @@ type RateLimiterTokenBucket struct { } var EVM2EVMOffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101a06040523480156200001257600080fd5b5060405162005e6138038062005e618339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615798620006c9600039600081816102ec01528181611a52015261309e0152600081816102bd01528181611a2a0152611cdc01526000818161028e01528181610e7f01528181610ee401528181611a000152818161228401526122ee01526000611e7b01526000818161025f01526119d60152600081816101ff015261197a01526000818161022f015281816119ae01528181611c9901528181612d0001526131af0152600081816101d0015281816119550152611f5b015260008181611bf30152611c3f01526157986000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806381ff7048116100d8578063afcb95d71161008c578063f077b59211610066578063f077b592146105f3578063f2fde38b14610609578063f52121a51461061c57600080fd5b8063afcb95d7146105ad578063b1dc65a4146105cd578063c92b2832146105e057600080fd5b8063856c8247116100bd578063856c82471461055d578063873504d7146105895780638da5cb5b1461059c57600080fd5b806381ff70481461051f57806385572ffb1461054f57600080fd5b8063599f64311161013a578063740f415011610114578063740f4150146104615780637437ff9f1461047457806379ba50971461051757600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516103299190613ed9565b60405180910390f35b610345610340366004613f6f565b61062f565b6040516103299190613fcf565b61038e6040518060400160405280601881526020017f45564d3245564d4f666652616d7020312e352e302d646576000000000000000081525081565b604051610329919061402d565b6103ae6103a9366004614256565b6106aa565b005b6103b8610a9e565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610b53565b6040516103299190614368565b6103ae61045c36600461437b565b610bb5565b6103ae61046f3660046147db565b610c7e565b61050a6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a01000000000000000000009091046001600160a01b039081166060830152600b5416608082015290565b6040516103299190614896565b6103ae610d70565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae6101823660046148ec565b61057061056b36600461437b565b610e53565b60405167ffffffffffffffff9091168152602001610329565b6103ae6105973660046149b8565b610f56565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae6105db366004614a61565b611124565b6103ae6105ee366004614b66565b61132f565b6105fb61139a565b604051610329929190614bd4565b6103ae61061736600461437b565b6114c0565b6103ae61062a366004614bf9565b6114d1565b600061063d60016004614c82565b600261064a608085614cc4565b67ffffffffffffffff1661065e9190614ceb565b6010600061066d608087614d02565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106a4576106a4613f8c565b92915050565b84518460ff16601f8211156106f75760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614d29565b60405180910390fd5b806000036107345760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614d29565b61073c611771565b610745856117e7565b60095460005b818110156107bc57600860006009838154811061076a5761076a614d43565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161074b565b5050865160005b8181101561095f5760008982815181106107df576107df614d43565b60200260200101519050600060028111156107fc576107fc613f8c565b6001600160a01b038216600090815260086020526040902054610100900460ff16600281111561082e5761082e613f8c565b146108685760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614d29565b6001600160a01b0381166108a8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561094b5761094b613f8c565b0217905550905050508060010190506107c3565b5087516109739060099060208b0190613e47565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a1617179055600780546109f99146913091906000906109cb9063ffffffff16614d72565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611ab1565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610a8a9487949293918316921691909117908f908f908f908f908f908f90614d95565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610b4e90611b3e565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bab57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8d575b5050505050905090565b6000546001600160a01b03163314801590610bdb57506002546001600160a01b03163314155b15610c12576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b610c86611bf0565b81515181518114610cc3576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d60576000838281518110610ce257610ce2614d43565b6020026020010151905080600014610d57578451805183908110610d0857610d08614d43565b602002602001015160800151811015610d57576040517f085e39cf00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016106ee565b50600101610cc6565b50610d6b8383611c71565b505050565b6001546001600160a01b03163314610de4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106ee565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106a4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106a4576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4f9190614e2b565b9392505050565b610f5e611771565b60005b825181101561103157610f9b838281518110610f7f57610f7f614d43565b602002602001015160200151600c6126f490919063ffffffff16565b15611029577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d58782838281518110610fd357610fd3614d43565b602002602001015160000151848381518110610ff157610ff1614d43565b6020026020010151602001516040516110209291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610f61565b5060005b8151811015610d6b5761108e82828151811061105357611053614d43565b60200260200101516020015183838151811061107157611071614d43565b602002602001015160000151600c6127099092919063ffffffff16565b1561111c577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a8282815181106110c6576110c6614d43565b6020026020010151600001518383815181106110e4576110e4614d43565b6020026020010151602001516040516111139291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101611035565b61112e8787612727565b600554883590808214611177576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016106ee565b61117f611bf0565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561120757611207613f8c565b600281111561121857611218613f8c565b905250905060028160200151600281111561123557611235613f8c565b14801561126f57506009816000015160ff168154811061125757611257614d43565b6000918252602090912001546001600160a01b031633145b6112a5576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006112b3856020614ceb565b6112be886020614ceb565b6112ca8b610144614e48565b6112d49190614e48565b6112de9190614e48565b9050368114611322576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016106ee565b5050505050505050505050565b6000546001600160a01b0316331480159061135557506002546001600160a01b03163314155b1561138c576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61139760038261274e565b50565b60608060006113a9600c612933565b90508067ffffffffffffffff8111156113c4576113c4614040565b6040519080825280602002602001820160405280156113ed578160200160208202803683370190505b5092508067ffffffffffffffff81111561140957611409614040565b604051908082528060200260200182016040528015611432578160200160208202803683370190505b50915060005b818110156114ba5760008061144e600c8461293e565b915091508086848151811061146557611465614d43565b60200260200101906001600160a01b031690816001600160a01b0316815250508185848151811061149857611498614d43565b6001600160a01b03909216602092830291909101909101525050600101611438565b50509091565b6114c8611771565b6113978161295c565b33301461150a576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611547565b60408051808201909152600080825260208201528152602001906001900390816115205790505b5061014084015151909150156115a7576115a4836101400151846020015160405160200161158491906001600160a01b0391909116815260200190565b604051602081830303815290604052856040015186610160015186612a37565b90505b610120830151511580156115bd57506080830151155b806115d4575060408301516001600160a01b03163b155b8061161457506040830151611612906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612b68565b155b1561161e57505050565b600080600a600001600a9054906101000a90046001600160a01b03166001600160a01b0316633cf979836040518060a001604052808861018001518152602001886000015167ffffffffffffffff168152602001886020015160405160200161169691906001600160a01b0391909116815260200190565b6040516020818303038152906040528152602001886101200151815260200186815250611388886080015189604001516040518563ffffffff1660e01b81526004016116e59493929190614ea0565b6000604051808303816000875af1158015611704573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261172c9190810190614faa565b50915091508161176a57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016106ee919061402d565b5050505050565b6000546001600160a01b031633146117e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106ee565b565b6000818060200190518101906117fd9190615018565b60608101519091506001600160a01b0316611844576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a01000000000000000000006001600160a01b039485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611aa59184906150b3565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611ad599989796959493929190615175565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611bcc82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611bb09190614c82565b85608001516fffffffffffffffffffffffffffffffff16612b84565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b467f0000000000000000000000000000000000000000000000000000000000000000146117e5576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016106ee565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d4f91906151fd565b15611d86576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151516000819003611dc3576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114611e01576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff811115611e1c57611e1c614040565b604051908082528060200260200182016040528015611e45578160200160208202803683370190505b50905060005b82811015611f1d57600085600001518281518110611e6b57611e6b614d43565b60200260200101519050611e9f817f0000000000000000000000000000000000000000000000000000000000000000612ba3565b838381518110611eb157611eb1614d43565b602002602001018181525050806101800151838381518110611ed557611ed5614d43565b602002602001015114611f14576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101611e4b565b50604080850151606086015191517f320488750000000000000000000000000000000000000000000000000000000081526000926001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692633204887592611f919287929160040161524b565b602060405180830381865afa158015611fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd29190615281565b90508060000361200e576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b848110156126eb5760008760000151828151811061203557612035614d43565b60200260200101519050600061204e826060015161062f565b9050600281600381111561206457612064613f8c565b036120ab57816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a250506126e3565b60008160038111156120bf576120bf613f8c565b14806120dc575060038160038111156120da576120da613f8c565b145b6121245760608201516040517f50a6e05200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016106ee565b83156121e157600a5460009063ffffffff166121408742614c82565b11905080806121605750600382600381111561215e5761215e613f8c565b145b612196576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8884815181106121a8576121a8614d43565b60200260200101516000146121db578884815181106121c9576121c9614d43565b60200260200101518360800181815250505b5061223e565b60008160038111156121f5576121f5613f8c565b1461223e5760608201516040517f67d9ba0f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016106ee565b60c082015167ffffffffffffffff16156124bd576020808301516001600160a01b03166000908152600f909152604081205467ffffffffffffffff1690819003612428577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156124285760208301516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa158015612337573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235b9190614e2b565b60c084015190915067ffffffffffffffff1661237882600161529a565b67ffffffffffffffff16146123d85782602001516001600160a01b03168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a35050506126e3565b6020838101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b600082600381111561243c5761243c613f8c565b036124bb5760c083015167ffffffffffffffff1661245b82600161529a565b67ffffffffffffffff16146124bb5782602001516001600160a01b03168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a35050506126e3565b505b6000896020015184815181106124d5576124d5614d43565b602002602001015190506125018360600151846000015185610140015151866101200151518551612cfe565b61251083606001516001612e78565b60008061251d8584612f22565b9150915061252f856060015183612e78565b861561259b57600382600381111561254957612549613f8c565b0361259b57600084600381111561256257612562613f8c565b1461259b57806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016106ee919061402d565b60028260038111156125af576125af613f8c565b146126075760038260038111156125c8576125c8613f8c565b14612607578460600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016106ee9291906152bb565b60c085015167ffffffffffffffff161561268f57600084600381111561262f5761262f613f8c565b0361268f576020808601516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff1691612667836152d9565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b846101800151856060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef6584846040516126d59291906152f6565b60405180910390a350505050505b600101612015565b50505050505050565b6000610f4f836001600160a01b038416612feb565b600061271f846001600160a01b03851684612ff7565b949350505050565b61274a61273682840184615316565b604080516000815260208101909152611c71565b5050565b815460009061277790700100000000000000000000000000000000900463ffffffff1642614c82565b9050801561281957600183015483546127bf916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b84565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461283f916fffffffffffffffffffffffffffffffff908116911661300d565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906129269084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106a482613023565b600080808061294d868661302e565b909450925050505b9250929050565b336001600160a01b038216036129ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106ee565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b846000805b8751811015612b4d57612ab4888281518110612a5a57612a5a614d43565b6020026020010151602001518888888581518110612a7a57612a7a614d43565b6020026020010151806020019051810190612a95919061534b565b888681518110612aa757612aa7614d43565b602002602001015161303d565b838281518110612ac657612ac6614d43565b6020026020010181905250612b02838281518110612ae657612ae6614d43565b602002602001015160000151600c61343d90919063ffffffff16565b15612b4557612b38838281518110612b1c57612b1c614d43565b6020908102919091010151600b546001600160a01b0316613452565b612b429083614e48565b91505b600101612a3c565b508015612b5d57612b5d81613573565b505b95945050505050565b6000612b7383613580565b8015610f4f5750610f4f83836135e4565b6000612b5f85612b948486614ceb565b612b9e9087614e48565b61300d565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612c399897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612c729190615411565b60405160208183030381529060405280519060200120876101600151604051602001612c9e919061547e565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff1614612d77576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016106ee565b600a5468010000000000000000900461ffff16831115612dcf576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b808314612e14576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b600a54640100000000900463ffffffff1682111561176a57600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff166004820152602481018390526044016106ee565b60006002612e87608085614cc4565b67ffffffffffffffff16612e9b9190614ceb565b90506000601081612ead608087614d02565b67ffffffffffffffff168152602081019190915260400160002054905081612ed760016004614c82565b901b191681836003811115612eee57612eee613f8c565b901b178060106000612f01608088614d02565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a590612f669087908790600401615491565b600060405180830381600087803b158015612f8057600080fd5b505af1925050508015612f91575060015b612fd0573d808015612fbf576040519150601f19603f3d011682016040523d82523d6000602084013e612fc4565b606091505b50600392509050612955565b50506040805160208101909152600081526002909250929050565b6000610f4f83836136b3565b600061271f84846001600160a01b0385166136d0565b600081831061301c5781610f4f565b5090919050565b60006106a4826136ed565b600080808061294d86866136f8565b604080518082019091526000808252602082015260006130608460200151613723565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa1580156130e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310991906155f4565b90506001600160a01b0381161580613151575061314f6001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612b68565b155b15613193576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016106ee565b60008060006132986040518061010001604052808c81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018b6001600160a01b031681526020018d8152602001876001600160a01b031681526020018a6000015181526020018a604001518152602001898152506040516024016132299190615611565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905260608a0151869063ffffffff1661138860846137c9565b925092509250826132d757816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee919061402d565b815160201461331f5781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b6000828060200190518101906133359190615281565b6040516001600160a01b038c166024820152604481018290529091506133d29060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905260608b015188906133c890869063ffffffff16614c82565b61138860846137c9565b5090945092508361341157826040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee919061402d565b604080518082019091526001600160a01b03909616865260208601525092935050505095945050505050565b6000610f4f836001600160a01b0384166138ef565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa1580156134b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134dc91906156e8565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036135455783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016106ee565b602084015161271f907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316906138fb565b6113976003826000613938565b60006135ac827f01ffc9a7000000000000000000000000000000000000000000000000000000006135e4565b80156106a457506135dd827fffffffff000000000000000000000000000000000000000000000000000000006135e4565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561369c575060208210155b80156136a85750600081115b979650505050505050565b60008181526002830160205260408120819055610f4f8383613c87565b6000828152600284016020526040812082905561271f8484613c93565b60006106a482613c9f565b600080806137068585613ca9565b600081815260029690960160205260409095205494959350505050565b6000815160201461376257816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee919061402d565b6000828060200190518101906137789190615281565b90506001600160a01b03811180613790575061040081105b156106a457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee919061402d565b6000606060008361ffff1667ffffffffffffffff8111156137ec576137ec614040565b6040519080825280601f01601f191660200182016040528015613816576020820181803683370190505b509150863b613849577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a8581101561387c577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b85900360408104810387106138b5577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156138d85750835b808352806000602085013e50955095509592505050565b6000610f4f8383613cb5565b6000670de0b6b3a764000061392e837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616614ceb565b610f4f9190615748565b825474010000000000000000000000000000000000000000900460ff16158061395f575081155b1561396957505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906139af90700100000000000000000000000000000000900463ffffffff1642614c82565b90508015613a6f57818311156139f1576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613a2b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b84565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613b0c576001600160a01b038416613ac1576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106ee565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b03851660448201526064016106ee565b84831015613c055760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613b509082614c82565b613b5a878a614c82565b613b649190614e48565b613b6e9190615748565b90506001600160a01b038616613bba576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106ee565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b03871660448201526064016106ee565b613c0f8584614c82565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f4f8383613cd4565b6000610f4f8383613dce565b60006106a4825490565b6000610f4f8383613e1d565b6000610f4f838360008181526001830160205260408120541515610f4f565b60008181526001830160205260408120548015613dbd576000613cf8600183614c82565b8554909150600090613d0c90600190614c82565b9050818114613d71576000866000018281548110613d2c57613d2c614d43565b9060005260206000200154905080876000018481548110613d4f57613d4f614d43565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613d8257613d8261575c565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106a4565b60009150506106a4565b5092915050565b6000818152600183016020526040812054613e15575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106a4565b5060006106a4565b6000826000018281548110613e3457613e34614d43565b9060005260206000200154905092915050565b828054828255906000526020600020908101928215613eb4579160200282015b82811115613eb457825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190613e67565b50613ec0929150613ec4565b5090565b5b80821115613ec05760008155600101613ec5565b60e081016106a482846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff8116811461139757600080fd5b8035613f6a81613f49565b919050565b600060208284031215613f8157600080fd5b8135610f4f81613f49565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110613fcb57613fcb613f8c565b9052565b602081016106a48284613fbb565b60005b83811015613ff8578181015183820152602001613fe0565b50506000910152565b60008151808452614019816020860160208601613fdd565b601f01601f19169290920160200192915050565b602081526000610f4f6020830184614001565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561409257614092614040565b60405290565b6040516101a0810167ffffffffffffffff8111828210171561409257614092614040565b6040516080810167ffffffffffffffff8111828210171561409257614092614040565b604051601f8201601f1916810167ffffffffffffffff8111828210171561410857614108614040565b604052919050565b600067ffffffffffffffff82111561412a5761412a614040565b5060051b60200190565b6001600160a01b038116811461139757600080fd5b8035613f6a81614134565b600082601f83011261416557600080fd5b8135602061417a61417583614110565b6140df565b8083825260208201915060208460051b87010193508684111561419c57600080fd5b602086015b848110156141c15780356141b481614134565b83529183019183016141a1565b509695505050505050565b803560ff81168114613f6a57600080fd5b600067ffffffffffffffff8211156141f7576141f7614040565b50601f01601f191660200190565b600082601f83011261421657600080fd5b8135614224614175826141dd565b81815284602083860101111561423957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561426f57600080fd5b863567ffffffffffffffff8082111561428757600080fd5b6142938a838b01614154565b975060208901359150808211156142a957600080fd5b6142b58a838b01614154565b96506142c360408a016141cc565b955060608901359150808211156142d957600080fd5b6142e58a838b01614205565b94506142f360808a01613f5f565b935060a089013591508082111561430957600080fd5b5061431689828a01614205565b9150509295509295509295565b60008151808452602080850194506020840160005b8381101561435d5781516001600160a01b031687529582019590820190600101614338565b509495945050505050565b602081526000610f4f6020830184614323565b60006020828403121561438d57600080fd5b8135610f4f81614134565b801515811461139757600080fd5b8035613f6a81614398565b600082601f8301126143c257600080fd5b813560206143d261417583614110565b82815260069290921b840181019181810190868411156143f157600080fd5b8286015b848110156141c1576040818903121561440e5760008081fd5b61441661406f565b813561442181614134565b815281850135858201528352918301916040016143f5565b600082601f83011261444a57600080fd5b8135602061445a61417583614110565b82815260059290921b8401810191818101908684111561447957600080fd5b8286015b848110156141c157803567ffffffffffffffff81111561449d5760008081fd5b6144ab8986838b0101614205565b84525091830191830161447d565b60006101a082840312156144cc57600080fd5b6144d4614098565b90506144df82613f5f565b81526144ed60208301614149565b60208201526144fe60408301614149565b604082015261450f60608301613f5f565b60608201526080820135608082015261452a60a083016143a6565b60a082015261453b60c08301613f5f565b60c082015261454c60e08301614149565b60e082015261010082810135908201526101208083013567ffffffffffffffff8082111561457957600080fd5b61458586838701614205565b838501526101409250828501359150808211156145a157600080fd5b6145ad868387016143b1565b838501526101609250828501359150808211156145c957600080fd5b506145d685828601614439565b82840152505061018080830135818301525092915050565b600082601f8301126145ff57600080fd5b8135602061460f61417583614110565b82815260059290921b8401810191818101908684111561462e57600080fd5b8286015b848110156141c157803567ffffffffffffffff8111156146525760008081fd5b6146608986838b0101614439565b845250918301918301614632565b600082601f83011261467f57600080fd5b8135602061468f61417583614110565b8083825260208201915060208460051b8701019350868411156146b157600080fd5b602086015b848110156141c157803583529183019183016146b6565b6000608082840312156146df57600080fd5b6146e76140bc565b9050813567ffffffffffffffff8082111561470157600080fd5b818401915084601f83011261471557600080fd5b8135602061472561417583614110565b82815260059290921b8401810191818101908884111561474457600080fd5b8286015b8481101561477c578035868111156147605760008081fd5b61476e8b86838b01016144b9565b845250918301918301614748565b508652508581013593508284111561479357600080fd5b61479f878588016145ee565b908501525060408401359150808211156147b857600080fd5b506147c58482850161466e565b6040830152506060820135606082015292915050565b600080604083850312156147ee57600080fd5b823567ffffffffffffffff8082111561480657600080fd5b614812868387016146cd565b935060209150818501358181111561482957600080fd5b85019050601f8101861361483c57600080fd5b803561484a61417582614110565b81815260059190911b8201830190838101908883111561486957600080fd5b928401925b828410156148875783358252928401929084019061486e565b80955050505050509250929050565b60a081016106a4828463ffffffff8082511683528060208301511660208401525061ffff604082015116604083015260608101516001600160a01b03808216606085015280608084015116608085015250505050565b6000602082840312156148fe57600080fd5b813567ffffffffffffffff81111561491557600080fd5b820160a08185031215610f4f57600080fd5b600082601f83011261493857600080fd5b8135602061494861417583614110565b82815260069290921b8401810191818101908684111561496757600080fd5b8286015b848110156141c157604081890312156149845760008081fd5b61498c61406f565b813561499781614134565b8152818501356149a681614134565b8186015283529183019160400161496b565b600080604083850312156149cb57600080fd5b823567ffffffffffffffff808211156149e357600080fd5b6149ef86838701614927565b93506020850135915080821115614a0557600080fd5b50614a1285828601614927565b9150509250929050565b60008083601f840112614a2e57600080fd5b50813567ffffffffffffffff811115614a4657600080fd5b6020830191508360208260051b850101111561295557600080fd5b60008060008060008060008060e0898b031215614a7d57600080fd5b606089018a811115614a8e57600080fd5b8998503567ffffffffffffffff80821115614aa857600080fd5b818b0191508b601f830112614abc57600080fd5b813581811115614acb57600080fd5b8c6020828501011115614add57600080fd5b6020830199508098505060808b0135915080821115614afb57600080fd5b614b078c838d01614a1c565b909750955060a08b0135915080821115614b2057600080fd5b50614b2d8b828c01614a1c565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff81168114613f6a57600080fd5b600060608284031215614b7857600080fd5b6040516060810181811067ffffffffffffffff82111715614b9b57614b9b614040565b6040528235614ba981614398565b8152614bb760208401614b46565b6020820152614bc860408401614b46565b60408201529392505050565b604081526000614be76040830185614323565b8281036020840152612b5f8185614323565b60008060408385031215614c0c57600080fd5b823567ffffffffffffffff80821115614c2457600080fd5b614c30868387016144b9565b93506020850135915080821115614c4657600080fd5b50614a1285828601614439565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106a4576106a4614c53565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680614cdf57614cdf614c95565b92169190910692915050565b80820281158282048414176106a4576106a4614c53565b600067ffffffffffffffff80841680614d1d57614d1d614c95565b92169190910492915050565b6020810160038310614d3d57614d3d613f8c565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103614d8b57614d8b614c53565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614dc58184018a614323565b90508281036080840152614dd98189614323565b905060ff871660a084015282810360c0840152614df68187614001565b905067ffffffffffffffff851660e0840152828103610100840152614e1b8185614001565b9c9b505050505050505050505050565b600060208284031215614e3d57600080fd5b8151610f4f81613f49565b808201808211156106a4576106a4614c53565b60008151808452602080850194506020840160005b8381101561435d57815180516001600160a01b031688528301518388015260409096019590820190600101614e70565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152614edb610120840182614001565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e0860152614f178383614001565b925060808901519150808584030161010086015250614f368282614e5b565b92505050614f4a602083018661ffff169052565b836040830152612b5f60608301846001600160a01b03169052565b600082601f830112614f7657600080fd5b8151614f84614175826141dd565b818152846020838601011115614f9957600080fd5b61271f826020830160208701613fdd565b600080600060608486031215614fbf57600080fd5b8351614fca81614398565b602085015190935067ffffffffffffffff811115614fe757600080fd5b614ff386828701614f65565b925050604084015190509250925092565b805163ffffffff81168114613f6a57600080fd5b600060a0828403121561502a57600080fd5b60405160a0810181811067ffffffffffffffff8211171561504d5761504d614040565b60405261505983615004565b815261506760208401615004565b6020820152604083015161ffff8116811461508157600080fd5b6040820152606083015161509481614134565b606082015260808301516150a781614134565b60808201529392505050565b610180810161512482856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff1661012083015260608301516001600160a01b03908116610140840152608084015116610160830152610f4f565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526151af8285018b614323565b915083820360808501526151c3828a614323565b915060ff881660a085015283820360c08501526151e08288614001565b90861660e08501528381036101008501529050614e1b8185614001565b60006020828403121561520f57600080fd5b8151610f4f81614398565b60008151808452602080850194506020840160005b8381101561435d5781518752958201959082019060010161522f565b60608152600061525e606083018661521a565b8281036020840152615270818661521a565b915050826040830152949350505050565b60006020828403121561529357600080fd5b5051919050565b67ffffffffffffffff818116838216019080821115613dc757613dc7614c53565b67ffffffffffffffff8316815260408101610f4f6020830184613fbb565b600067ffffffffffffffff808316818103614d8b57614d8b614c53565b6153008184613fbb565b60406020820152600061271f6040830184614001565b60006020828403121561532857600080fd5b813567ffffffffffffffff81111561533f57600080fd5b61271f848285016146cd565b60006020828403121561535d57600080fd5b815167ffffffffffffffff8082111561537557600080fd5b908301906080828603121561538957600080fd5b6153916140bc565b8251828111156153a057600080fd5b6153ac87828601614f65565b8252506020830151828111156153c157600080fd5b6153cd87828601614f65565b6020830152506040830151828111156153e557600080fd5b6153f187828601614f65565b60408301525061540360608401615004565b606082015295945050505050565b602081526000610f4f6020830184614e5b565b60008282518085526020808601955060208260051b8401016020860160005b8481101561547157601f1986840301895261545f838351614001565b98840198925090830190600101615443565b5090979650505050505050565b602081526000610f4f6020830184615424565b604081526154ac60408201845167ffffffffffffffff169052565b600060208401516154c860608401826001600160a01b03169052565b5060408401516001600160a01b038116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c08401516101006155298185018367ffffffffffffffff169052565b60e08601519150610120615547818601846001600160a01b03169052565b81870151925061014091508282860152808701519250506101a061016081818701526155776101e0870185614001565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc06101808188870301818901526155b68686614e5b565b9550828a015194508188870301848901526155d18686615424565b9550808a01516101c089015250505050508281036020840152612b5f8185615424565b60006020828403121561560657600080fd5b8151610f4f81614134565b6020815260008251610100806020850152615630610120850183614001565b9150602085015161564d604086018267ffffffffffffffff169052565b5060408501516001600160a01b03811660608601525060608501516080850152608085015161568760a08601826001600160a01b03169052565b5060a0850151601f19808685030160c08701526156a48483614001565b935060c08701519150808685030160e08701526156c18483614001565b935060e08701519150808685030183870152506156de8382614001565b9695505050505050565b6000604082840312156156fa57600080fd5b61570261406f565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461572e57600080fd5b815261573c60208401615004565b60208201529392505050565b60008261575757615757614c95565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101a06040523480156200001257600080fd5b5060405162005e0a38038062005e0a8339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615741620006c9600039600081816102ec01528181611a5201526130470152600081816102bd01528181611a2a0152611cdc01526000818161028e01528181610e7f01528181610ee401528181611a000152818161222d015261229701526000611e7b01526000818161025f01526119d60152600081816101ff015261197a01526000818161022f015281816119ae01528181611c9901528181612ca901526131580152600081816101d0015281816119550152611f5b015260008181611bf30152611c3f01526157416000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806381ff7048116100d8578063afcb95d71161008c578063f077b59211610066578063f077b592146105f3578063f2fde38b14610609578063f52121a51461061c57600080fd5b8063afcb95d7146105ad578063b1dc65a4146105cd578063c92b2832146105e057600080fd5b8063856c8247116100bd578063856c82471461055d578063873504d7146105895780638da5cb5b1461059c57600080fd5b806381ff70481461051f57806385572ffb1461054f57600080fd5b8063599f64311161013a578063740f415011610114578063740f4150146104615780637437ff9f1461047457806379ba50971461051757600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516103299190613e82565b60405180910390f35b610345610340366004613f18565b61062f565b6040516103299190613f78565b61038e6040518060400160405280601881526020017f45564d3245564d4f666652616d7020312e352e302d646576000000000000000081525081565b6040516103299190613fd6565b6103ae6103a93660046141ff565b6106aa565b005b6103b8610a9e565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610b53565b6040516103299190614311565b6103ae61045c366004614324565b610bb5565b6103ae61046f366004614784565b610c7e565b61050a6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a01000000000000000000009091046001600160a01b039081166060830152600b5416608082015290565b604051610329919061483f565b6103ae610d70565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae610182366004614895565b61057061056b366004614324565b610e53565b60405167ffffffffffffffff9091168152602001610329565b6103ae610597366004614961565b610f56565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae6105db366004614a0a565b611124565b6103ae6105ee366004614b0f565b61132f565b6105fb61139a565b604051610329929190614b7d565b6103ae610617366004614324565b6114c0565b6103ae61062a366004614ba2565b6114d1565b600061063d60016004614c2b565b600261064a608085614c6d565b67ffffffffffffffff1661065e9190614c94565b6010600061066d608087614cab565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106a4576106a4613f35565b92915050565b84518460ff16601f8211156106f75760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614cd2565b60405180910390fd5b806000036107345760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614cd2565b61073c611771565b610745856117e7565b60095460005b818110156107bc57600860006009838154811061076a5761076a614cec565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161074b565b5050865160005b8181101561095f5760008982815181106107df576107df614cec565b60200260200101519050600060028111156107fc576107fc613f35565b6001600160a01b038216600090815260086020526040902054610100900460ff16600281111561082e5761082e613f35565b146108685760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614cd2565b6001600160a01b0381166108a8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561094b5761094b613f35565b0217905550905050508060010190506107c3565b5087516109739060099060208b0190613df0565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a1617179055600780546109f99146913091906000906109cb9063ffffffff16614d1b565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611ab1565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610a8a9487949293918316921691909117908f908f908f908f908f908f90614d3e565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610b4e90611b3e565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bab57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8d575b5050505050905090565b6000546001600160a01b03163314801590610bdb57506002546001600160a01b03163314155b15610c12576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b610c86611bf0565b81515181518114610cc3576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d60576000838281518110610ce257610ce2614cec565b6020026020010151905080600014610d57578451805183908110610d0857610d08614cec565b602002602001015160800151811015610d57576040517f085e39cf00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016106ee565b50600101610cc6565b50610d6b8383611c71565b505050565b6001546001600160a01b03163314610de4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106ee565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106a4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106a4576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4f9190614dd4565b9392505050565b610f5e611771565b60005b825181101561103157610f9b838281518110610f7f57610f7f614cec565b602002602001015160200151600c61269d90919063ffffffff16565b15611029577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d58782838281518110610fd357610fd3614cec565b602002602001015160000151848381518110610ff157610ff1614cec565b6020026020010151602001516040516110209291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610f61565b5060005b8151811015610d6b5761108e82828151811061105357611053614cec565b60200260200101516020015183838151811061107157611071614cec565b602002602001015160000151600c6126b29092919063ffffffff16565b1561111c577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a8282815181106110c6576110c6614cec565b6020026020010151600001518383815181106110e4576110e4614cec565b6020026020010151602001516040516111139291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101611035565b61112e87876126d0565b600554883590808214611177576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016106ee565b61117f611bf0565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561120757611207613f35565b600281111561121857611218613f35565b905250905060028160200151600281111561123557611235613f35565b14801561126f57506009816000015160ff168154811061125757611257614cec565b6000918252602090912001546001600160a01b031633145b6112a5576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006112b3856020614c94565b6112be886020614c94565b6112ca8b610144614df1565b6112d49190614df1565b6112de9190614df1565b9050368114611322576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016106ee565b5050505050505050505050565b6000546001600160a01b0316331480159061135557506002546001600160a01b03163314155b1561138c576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113976003826126f7565b50565b60608060006113a9600c6128dc565b90508067ffffffffffffffff8111156113c4576113c4613fe9565b6040519080825280602002602001820160405280156113ed578160200160208202803683370190505b5092508067ffffffffffffffff81111561140957611409613fe9565b604051908082528060200260200182016040528015611432578160200160208202803683370190505b50915060005b818110156114ba5760008061144e600c846128e7565b915091508086848151811061146557611465614cec565b60200260200101906001600160a01b031690816001600160a01b0316815250508185848151811061149857611498614cec565b6001600160a01b03909216602092830291909101909101525050600101611438565b50509091565b6114c8611771565b61139781612905565b33301461150a576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611547565b60408051808201909152600080825260208201528152602001906001900390816115205790505b5061014084015151909150156115a7576115a4836101400151846020015160405160200161158491906001600160a01b0391909116815260200190565b6040516020818303038152906040528560400151866101600151866129e0565b90505b610120830151511580156115bd57506080830151155b806115d4575060408301516001600160a01b03163b155b8061161457506040830151611612906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612b11565b155b1561161e57505050565b600080600a600001600a9054906101000a90046001600160a01b03166001600160a01b0316633cf979836040518060a001604052808861018001518152602001886000015167ffffffffffffffff168152602001886020015160405160200161169691906001600160a01b0391909116815260200190565b6040516020818303038152906040528152602001886101200151815260200186815250611388886080015189604001516040518563ffffffff1660e01b81526004016116e59493929190614e49565b6000604051808303816000875af1158015611704573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261172c9190810190614f53565b50915091508161176a57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016106ee9190613fd6565b5050505050565b6000546001600160a01b031633146117e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106ee565b565b6000818060200190518101906117fd9190614fc1565b60608101519091506001600160a01b0316611844576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a01000000000000000000006001600160a01b039485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611aa591849061505c565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611ad59998979695949392919061511e565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611bcc82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611bb09190614c2b565b85608001516fffffffffffffffffffffffffffffffff16612b2d565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b467f0000000000000000000000000000000000000000000000000000000000000000146117e5576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016106ee565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d4f91906151a6565b15611d86576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151516000819003611dc3576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114611e01576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff811115611e1c57611e1c613fe9565b604051908082528060200260200182016040528015611e45578160200160208202803683370190505b50905060005b82811015611f1d57600085600001518281518110611e6b57611e6b614cec565b60200260200101519050611e9f817f0000000000000000000000000000000000000000000000000000000000000000612b4c565b838381518110611eb157611eb1614cec565b602002602001018181525050806101800151838381518110611ed557611ed5614cec565b602002602001015114611f14576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101611e4b565b50604080850151606086015191517f320488750000000000000000000000000000000000000000000000000000000081526000926001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692633204887592611f91928792916004016151f4565b602060405180830381865afa158015611fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd2919061522a565b90508060000361200e576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b848110156126945760008760000151828151811061203557612035614cec565b60200260200101519050600061204e826060015161062f565b9050600081600381111561206457612064613f35565b14806120815750600381600381111561207f5761207f613f35565b145b6120c757816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a2505061268c565b831561218457600a5460009063ffffffff166120e38742614c2b565b11905080806121035750600382600381111561210157612101613f35565b145b612139576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88848151811061214b5761214b614cec565b602002602001015160001461217e5788848151811061216c5761216c614cec565b60200260200101518360800181815250505b506121e7565b600081600381111561219857612198613f35565b146121e757606082015160405167ffffffffffffffff90911681527f67d9ba0f63d427c482c2736300e6d5a34c6691dbcdea8ad35828a1f1ba47e8729060200160405180910390a1505061268c565b60c082015167ffffffffffffffff1615612466576020808301516001600160a01b03166000908152600f909152604081205467ffffffffffffffff16908190036123d1577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156123d15760208301516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa1580156122e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123049190614dd4565b60c084015190915067ffffffffffffffff16612321826001615243565b67ffffffffffffffff16146123815782602001516001600160a01b03168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a350505061268c565b6020838101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b60008260038111156123e5576123e5613f35565b036124645760c083015167ffffffffffffffff16612404826001615243565b67ffffffffffffffff16146124645782602001516001600160a01b03168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a350505061268c565b505b60008960200151848151811061247e5761247e614cec565b602002602001015190506124aa8360600151846000015185610140015151866101200151518551612ca7565b6124b983606001516001612e21565b6000806124c68584612ecb565b915091506124d8856060015183612e21565b86156125445760038260038111156124f2576124f2613f35565b0361254457600084600381111561250b5761250b613f35565b1461254457806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016106ee9190613fd6565b600282600381111561255857612558613f35565b146125b057600382600381111561257157612571613f35565b146125b0578460600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016106ee929190615264565b60c085015167ffffffffffffffff16156126385760008460038111156125d8576125d8613f35565b03612638576020808601516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff169161261083615282565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b846101800151856060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef65848460405161267e92919061529f565b60405180910390a350505050505b600101612015565b50505050505050565b6000610f4f836001600160a01b038416612f94565b60006126c8846001600160a01b03851684612fa0565b949350505050565b6126f36126df828401846152bf565b604080516000815260208101909152611c71565b5050565b815460009061272090700100000000000000000000000000000000900463ffffffff1642614c2b565b905080156127c25760018301548354612768916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b2d565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546127e8916fffffffffffffffffffffffffffffffff9081169116612fb6565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906128cf9084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106a482612fcc565b60008080806128f68686612fd7565b909450925050505b9250929050565b336001600160a01b03821603612977576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106ee565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b846000805b8751811015612af657612a5d888281518110612a0357612a03614cec565b6020026020010151602001518888888581518110612a2357612a23614cec565b6020026020010151806020019051810190612a3e91906152f4565b888681518110612a5057612a50614cec565b6020026020010151612fe6565b838281518110612a6f57612a6f614cec565b6020026020010181905250612aab838281518110612a8f57612a8f614cec565b602002602001015160000151600c6133e690919063ffffffff16565b15612aee57612ae1838281518110612ac557612ac5614cec565b6020908102919091010151600b546001600160a01b03166133fb565b612aeb9083614df1565b91505b6001016129e5565b508015612b0657612b068161351c565b505b95945050505050565b6000612b1c83613529565b8015610f4f5750610f4f838361358d565b6000612b0885612b3d8486614c94565b612b479087614df1565b612fb6565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612be29897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612c1b91906153ba565b60405160208183030381529060405280519060200120876101600151604051602001612c479190615427565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff1614612d20576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016106ee565b600a5468010000000000000000900461ffff16831115612d78576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b808314612dbd576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b600a54640100000000900463ffffffff1682111561176a57600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff166004820152602481018390526044016106ee565b60006002612e30608085614c6d565b67ffffffffffffffff16612e449190614c94565b90506000601081612e56608087614cab565b67ffffffffffffffff168152602081019190915260400160002054905081612e8060016004614c2b565b901b191681836003811115612e9757612e97613f35565b901b178060106000612eaa608088614cab565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a590612f0f908790879060040161543a565b600060405180830381600087803b158015612f2957600080fd5b505af1925050508015612f3a575060015b612f79573d808015612f68576040519150601f19603f3d011682016040523d82523d6000602084013e612f6d565b606091505b506003925090506128fe565b50506040805160208101909152600081526002909250929050565b6000610f4f838361365c565b60006126c884846001600160a01b038516613679565b6000818310612fc55781610f4f565b5090919050565b60006106a482613696565b60008080806128f686866136a1565b6040805180820190915260008082526020820152600061300984602001516136cc565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa15801561308e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130b2919061559d565b90506001600160a01b03811615806130fa57506130f86001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612b11565b155b1561313c576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016106ee565b60008060006132416040518061010001604052808c81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018b6001600160a01b031681526020018d8152602001876001600160a01b031681526020018a6000015181526020018a604001518152602001898152506040516024016131d291906155ba565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905260608a0151869063ffffffff166113886084613772565b9250925092508261328057816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190613fd6565b81516020146132c85781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b6000828060200190518101906132de919061522a565b6040516001600160a01b038c1660248201526044810182905290915061337b9060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905260608b0151889061337190869063ffffffff16614c2b565b6113886084613772565b509094509250836133ba57826040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190613fd6565b604080518082019091526001600160a01b03909616865260208601525092935050505095945050505050565b6000610f4f836001600160a01b038416613898565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613461573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134859190615691565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036134ee5783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016106ee565b60208401516126c8907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316906138a4565b61139760038260006138e1565b6000613555827f01ffc9a70000000000000000000000000000000000000000000000000000000061358d565b80156106a45750613586827fffffffff0000000000000000000000000000000000000000000000000000000061358d565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613645575060208210155b80156136515750600081115b979650505050505050565b60008181526002830160205260408120819055610f4f8383613c30565b600082815260028401602052604081208290556126c88484613c3c565b60006106a482613c48565b600080806136af8585613c52565b600081815260029690960160205260409095205494959350505050565b6000815160201461370b57816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190613fd6565b600082806020019051810190613721919061522a565b90506001600160a01b03811180613739575061040081105b156106a457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190613fd6565b6000606060008361ffff1667ffffffffffffffff81111561379557613795613fe9565b6040519080825280601f01601f1916602001820160405280156137bf576020820181803683370190505b509150863b6137f2577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613825577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b859003604081048103871061385e577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156138815750835b808352806000602085013e50955095509592505050565b6000610f4f8383613c5e565b6000670de0b6b3a76400006138d7837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616614c94565b610f4f91906156f1565b825474010000000000000000000000000000000000000000900460ff161580613908575081155b1561391257505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061395890700100000000000000000000000000000000900463ffffffff1642614c2b565b90508015613a18578183111561399a576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546139d49083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b2d565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613ab5576001600160a01b038416613a6a576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106ee565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b03851660448201526064016106ee565b84831015613bae5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613af99082614c2b565b613b03878a614c2b565b613b0d9190614df1565b613b1791906156f1565b90506001600160a01b038616613b63576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106ee565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b03871660448201526064016106ee565b613bb88584614c2b565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f4f8383613c7d565b6000610f4f8383613d77565b60006106a4825490565b6000610f4f8383613dc6565b6000610f4f838360008181526001830160205260408120541515610f4f565b60008181526001830160205260408120548015613d66576000613ca1600183614c2b565b8554909150600090613cb590600190614c2b565b9050818114613d1a576000866000018281548110613cd557613cd5614cec565b9060005260206000200154905080876000018481548110613cf857613cf8614cec565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613d2b57613d2b615705565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106a4565b60009150506106a4565b5092915050565b6000818152600183016020526040812054613dbe575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106a4565b5060006106a4565b6000826000018281548110613ddd57613ddd614cec565b9060005260206000200154905092915050565b828054828255906000526020600020908101928215613e5d579160200282015b82811115613e5d57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190613e10565b50613e69929150613e6d565b5090565b5b80821115613e695760008155600101613e6e565b60e081016106a482846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff8116811461139757600080fd5b8035613f1381613ef2565b919050565b600060208284031215613f2a57600080fd5b8135610f4f81613ef2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110613f7457613f74613f35565b9052565b602081016106a48284613f64565b60005b83811015613fa1578181015183820152602001613f89565b50506000910152565b60008151808452613fc2816020860160208601613f86565b601f01601f19169290920160200192915050565b602081526000610f4f6020830184613faa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561403b5761403b613fe9565b60405290565b6040516101a0810167ffffffffffffffff8111828210171561403b5761403b613fe9565b6040516080810167ffffffffffffffff8111828210171561403b5761403b613fe9565b604051601f8201601f1916810167ffffffffffffffff811182821017156140b1576140b1613fe9565b604052919050565b600067ffffffffffffffff8211156140d3576140d3613fe9565b5060051b60200190565b6001600160a01b038116811461139757600080fd5b8035613f13816140dd565b600082601f83011261410e57600080fd5b8135602061412361411e836140b9565b614088565b8083825260208201915060208460051b87010193508684111561414557600080fd5b602086015b8481101561416a57803561415d816140dd565b835291830191830161414a565b509695505050505050565b803560ff81168114613f1357600080fd5b600067ffffffffffffffff8211156141a0576141a0613fe9565b50601f01601f191660200190565b600082601f8301126141bf57600080fd5b81356141cd61411e82614186565b8181528460208386010111156141e257600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561421857600080fd5b863567ffffffffffffffff8082111561423057600080fd5b61423c8a838b016140fd565b9750602089013591508082111561425257600080fd5b61425e8a838b016140fd565b965061426c60408a01614175565b9550606089013591508082111561428257600080fd5b61428e8a838b016141ae565b945061429c60808a01613f08565b935060a08901359150808211156142b257600080fd5b506142bf89828a016141ae565b9150509295509295509295565b60008151808452602080850194506020840160005b838110156143065781516001600160a01b0316875295820195908201906001016142e1565b509495945050505050565b602081526000610f4f60208301846142cc565b60006020828403121561433657600080fd5b8135610f4f816140dd565b801515811461139757600080fd5b8035613f1381614341565b600082601f83011261436b57600080fd5b8135602061437b61411e836140b9565b82815260069290921b8401810191818101908684111561439a57600080fd5b8286015b8481101561416a57604081890312156143b75760008081fd5b6143bf614018565b81356143ca816140dd565b8152818501358582015283529183019160400161439e565b600082601f8301126143f357600080fd5b8135602061440361411e836140b9565b82815260059290921b8401810191818101908684111561442257600080fd5b8286015b8481101561416a57803567ffffffffffffffff8111156144465760008081fd5b6144548986838b01016141ae565b845250918301918301614426565b60006101a0828403121561447557600080fd5b61447d614041565b905061448882613f08565b8152614496602083016140f2565b60208201526144a7604083016140f2565b60408201526144b860608301613f08565b6060820152608082013560808201526144d360a0830161434f565b60a08201526144e460c08301613f08565b60c08201526144f560e083016140f2565b60e082015261010082810135908201526101208083013567ffffffffffffffff8082111561452257600080fd5b61452e868387016141ae565b8385015261014092508285013591508082111561454a57600080fd5b6145568683870161435a565b8385015261016092508285013591508082111561457257600080fd5b5061457f858286016143e2565b82840152505061018080830135818301525092915050565b600082601f8301126145a857600080fd5b813560206145b861411e836140b9565b82815260059290921b840181019181810190868411156145d757600080fd5b8286015b8481101561416a57803567ffffffffffffffff8111156145fb5760008081fd5b6146098986838b01016143e2565b8452509183019183016145db565b600082601f83011261462857600080fd5b8135602061463861411e836140b9565b8083825260208201915060208460051b87010193508684111561465a57600080fd5b602086015b8481101561416a578035835291830191830161465f565b60006080828403121561468857600080fd5b614690614065565b9050813567ffffffffffffffff808211156146aa57600080fd5b818401915084601f8301126146be57600080fd5b813560206146ce61411e836140b9565b82815260059290921b840181019181810190888411156146ed57600080fd5b8286015b84811015614725578035868111156147095760008081fd5b6147178b86838b0101614462565b8452509183019183016146f1565b508652508581013593508284111561473c57600080fd5b61474887858801614597565b9085015250604084013591508082111561476157600080fd5b5061476e84828501614617565b6040830152506060820135606082015292915050565b6000806040838503121561479757600080fd5b823567ffffffffffffffff808211156147af57600080fd5b6147bb86838701614676565b93506020915081850135818111156147d257600080fd5b85019050601f810186136147e557600080fd5b80356147f361411e826140b9565b81815260059190911b8201830190838101908883111561481257600080fd5b928401925b8284101561483057833582529284019290840190614817565b80955050505050509250929050565b60a081016106a4828463ffffffff8082511683528060208301511660208401525061ffff604082015116604083015260608101516001600160a01b03808216606085015280608084015116608085015250505050565b6000602082840312156148a757600080fd5b813567ffffffffffffffff8111156148be57600080fd5b820160a08185031215610f4f57600080fd5b600082601f8301126148e157600080fd5b813560206148f161411e836140b9565b82815260069290921b8401810191818101908684111561491057600080fd5b8286015b8481101561416a576040818903121561492d5760008081fd5b614935614018565b8135614940816140dd565b81528185013561494f816140dd565b81860152835291830191604001614914565b6000806040838503121561497457600080fd5b823567ffffffffffffffff8082111561498c57600080fd5b614998868387016148d0565b935060208501359150808211156149ae57600080fd5b506149bb858286016148d0565b9150509250929050565b60008083601f8401126149d757600080fd5b50813567ffffffffffffffff8111156149ef57600080fd5b6020830191508360208260051b85010111156128fe57600080fd5b60008060008060008060008060e0898b031215614a2657600080fd5b606089018a811115614a3757600080fd5b8998503567ffffffffffffffff80821115614a5157600080fd5b818b0191508b601f830112614a6557600080fd5b813581811115614a7457600080fd5b8c6020828501011115614a8657600080fd5b6020830199508098505060808b0135915080821115614aa457600080fd5b614ab08c838d016149c5565b909750955060a08b0135915080821115614ac957600080fd5b50614ad68b828c016149c5565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff81168114613f1357600080fd5b600060608284031215614b2157600080fd5b6040516060810181811067ffffffffffffffff82111715614b4457614b44613fe9565b6040528235614b5281614341565b8152614b6060208401614aef565b6020820152614b7160408401614aef565b60408201529392505050565b604081526000614b9060408301856142cc565b8281036020840152612b0881856142cc565b60008060408385031215614bb557600080fd5b823567ffffffffffffffff80821115614bcd57600080fd5b614bd986838701614462565b93506020850135915080821115614bef57600080fd5b506149bb858286016143e2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106a4576106a4614bfc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680614c8857614c88614c3e565b92169190910692915050565b80820281158282048414176106a4576106a4614bfc565b600067ffffffffffffffff80841680614cc657614cc6614c3e565b92169190910492915050565b6020810160038310614ce657614ce6613f35565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103614d3457614d34614bfc565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614d6e8184018a6142cc565b90508281036080840152614d8281896142cc565b905060ff871660a084015282810360c0840152614d9f8187613faa565b905067ffffffffffffffff851660e0840152828103610100840152614dc48185613faa565b9c9b505050505050505050505050565b600060208284031215614de657600080fd5b8151610f4f81613ef2565b808201808211156106a4576106a4614bfc565b60008151808452602080850194506020840160005b8381101561430657815180516001600160a01b031688528301518388015260409096019590820190600101614e19565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152614e84610120840182613faa565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e0860152614ec08383613faa565b925060808901519150808584030161010086015250614edf8282614e04565b92505050614ef3602083018661ffff169052565b836040830152612b0860608301846001600160a01b03169052565b600082601f830112614f1f57600080fd5b8151614f2d61411e82614186565b818152846020838601011115614f4257600080fd5b6126c8826020830160208701613f86565b600080600060608486031215614f6857600080fd5b8351614f7381614341565b602085015190935067ffffffffffffffff811115614f9057600080fd5b614f9c86828701614f0e565b925050604084015190509250925092565b805163ffffffff81168114613f1357600080fd5b600060a08284031215614fd357600080fd5b60405160a0810181811067ffffffffffffffff82111715614ff657614ff6613fe9565b60405261500283614fad565b815261501060208401614fad565b6020820152604083015161ffff8116811461502a57600080fd5b6040820152606083015161503d816140dd565b60608201526080830151615050816140dd565b60808201529392505050565b61018081016150cd82856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff1661012083015260608301516001600160a01b03908116610140840152608084015116610160830152610f4f565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526151588285018b6142cc565b9150838203608085015261516c828a6142cc565b915060ff881660a085015283820360c08501526151898288613faa565b90861660e08501528381036101008501529050614dc48185613faa565b6000602082840312156151b857600080fd5b8151610f4f81614341565b60008151808452602080850194506020840160005b83811015614306578151875295820195908201906001016151d8565b60608152600061520760608301866151c3565b828103602084015261521981866151c3565b915050826040830152949350505050565b60006020828403121561523c57600080fd5b5051919050565b67ffffffffffffffff818116838216019080821115613d7057613d70614bfc565b67ffffffffffffffff8316815260408101610f4f6020830184613f64565b600067ffffffffffffffff808316818103614d3457614d34614bfc565b6152a98184613f64565b6040602082015260006126c86040830184613faa565b6000602082840312156152d157600080fd5b813567ffffffffffffffff8111156152e857600080fd5b6126c884828501614676565b60006020828403121561530657600080fd5b815167ffffffffffffffff8082111561531e57600080fd5b908301906080828603121561533257600080fd5b61533a614065565b82518281111561534957600080fd5b61535587828601614f0e565b82525060208301518281111561536a57600080fd5b61537687828601614f0e565b60208301525060408301518281111561538e57600080fd5b61539a87828601614f0e565b6040830152506153ac60608401614fad565b606082015295945050505050565b602081526000610f4f6020830184614e04565b60008282518085526020808601955060208260051b8401016020860160005b8481101561541a57601f19868403018952615408838351613faa565b988401989250908301906001016153ec565b5090979650505050505050565b602081526000610f4f60208301846153cd565b6040815261545560408201845167ffffffffffffffff169052565b6000602084015161547160608401826001600160a01b03169052565b5060408401516001600160a01b038116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c08401516101006154d28185018367ffffffffffffffff169052565b60e086015191506101206154f0818601846001600160a01b03169052565b81870151925061014091508282860152808701519250506101a061016081818701526155206101e0870185613faa565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc061018081888703018189015261555f8686614e04565b9550828a0151945081888703018489015261557a86866153cd565b9550808a01516101c089015250505050508281036020840152612b0881856153cd565b6000602082840312156155af57600080fd5b8151610f4f816140dd565b60208152600082516101008060208501526155d9610120850183613faa565b915060208501516155f6604086018267ffffffffffffffff169052565b5060408501516001600160a01b03811660608601525060608501516080850152608085015161563060a08601826001600160a01b03169052565b5060a0850151601f19808685030160c087015261564d8483613faa565b935060c08701519150808685030160e087015261566a8483613faa565b935060e08701519150808685030183870152506156878382613faa565b9695505050505050565b6000604082840312156156a357600080fd5b6156ab614018565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146156d757600080fd5b81526156e560208401614fad565b60208201529392505050565b60008261570057615700614c3e565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var EVM2EVMOffRampABI = EVM2EVMOffRampMetaData.ABI @@ -779,6 +779,123 @@ func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseAdminSet(log types.Log) (*EV return event, nil } +type EVM2EVMOffRampAlreadyAttemptedIterator struct { + Event *EVM2EVMOffRampAlreadyAttempted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMOffRampAlreadyAttemptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampAlreadyAttempted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMOffRampAlreadyAttempted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMOffRampAlreadyAttemptedIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMOffRampAlreadyAttemptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMOffRampAlreadyAttempted struct { + SequenceNumber uint64 + Raw types.Log +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) FilterAlreadyAttempted(opts *bind.FilterOpts) (*EVM2EVMOffRampAlreadyAttemptedIterator, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.FilterLogs(opts, "AlreadyAttempted") + if err != nil { + return nil, err + } + return &EVM2EVMOffRampAlreadyAttemptedIterator{contract: _EVM2EVMOffRamp.contract, event: "AlreadyAttempted", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) WatchAlreadyAttempted(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampAlreadyAttempted) (event.Subscription, error) { + + logs, sub, err := _EVM2EVMOffRamp.contract.WatchLogs(opts, "AlreadyAttempted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMOffRampAlreadyAttempted) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "AlreadyAttempted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMOffRamp *EVM2EVMOffRampFilterer) ParseAlreadyAttempted(log types.Log) (*EVM2EVMOffRampAlreadyAttempted, error) { + event := new(EVM2EVMOffRampAlreadyAttempted) + if err := _EVM2EVMOffRamp.contract.UnpackLog(event, "AlreadyAttempted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type EVM2EVMOffRampConfigChangedIterator struct { Event *EVM2EVMOffRampConfigChanged @@ -2438,6 +2555,8 @@ func (_EVM2EVMOffRamp *EVM2EVMOffRamp) ParseLog(log types.Log) (generated.Abigen switch log.Topics[0] { case _EVM2EVMOffRamp.abi.Events["AdminSet"].ID: return _EVM2EVMOffRamp.ParseAdminSet(log) + case _EVM2EVMOffRamp.abi.Events["AlreadyAttempted"].ID: + return _EVM2EVMOffRamp.ParseAlreadyAttempted(log) case _EVM2EVMOffRamp.abi.Events["ConfigChanged"].ID: return _EVM2EVMOffRamp.ParseConfigChanged(log) case _EVM2EVMOffRamp.abi.Events["ConfigSet"].ID: @@ -2474,6 +2593,10 @@ func (EVM2EVMOffRampAdminSet) Topic() common.Hash { return common.HexToHash("0x8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c") } +func (EVM2EVMOffRampAlreadyAttempted) Topic() common.Hash { + return common.HexToHash("0x67d9ba0f63d427c482c2736300e6d5a34c6691dbcdea8ad35828a1f1ba47e872") +} + func (EVM2EVMOffRampConfigChanged) Topic() common.Hash { return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") } @@ -2587,6 +2710,12 @@ type EVM2EVMOffRampInterface interface { ParseAdminSet(log types.Log) (*EVM2EVMOffRampAdminSet, error) + FilterAlreadyAttempted(opts *bind.FilterOpts) (*EVM2EVMOffRampAlreadyAttemptedIterator, error) + + WatchAlreadyAttempted(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampAlreadyAttempted) (event.Subscription, error) + + ParseAlreadyAttempted(log types.Log) (*EVM2EVMOffRampAlreadyAttempted, error) + FilterConfigChanged(opts *bind.FilterOpts) (*EVM2EVMOffRampConfigChangedIterator, error) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMOffRampConfigChanged) (event.Subscription, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index c9da4f5973..71552045c6 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -10,9 +10,9 @@ ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderT commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin ddc26c10c2a52b59624faae9005827b09b98db4566887a736005e8cc37cf8a51 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin ebd8aac686fa28a71d4212bcd25a28f8f640d50dce5e50498b2f6b8534890b69 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de -evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 25a7bf3aa46252844c7afabc15db1051e7b6a717e296fc4c6e2f2f93d16033c5 +evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 3ea3974c9848e0df0dbe1fc7192134589e7735017c2ea8d4755084b3c95035d1 evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 9478aedc9f0072fbdafb54a6f82248de1efbcd7bdff18a90d8556b9aaff67455 -evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin bca94c29d523e7679db6ef86ffffcc52864a7499e9f0c51807c901bcc1927fda +evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin bdafc343d33f1eb753871ea6d215339cd8e087c1a8c7297257791dd1e453be8f evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin bf1a3090a2f8d1632b82a6d45200cf6f3833a1e27303745405c1ed13ffc0cf83 lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin f049909cfef0aa3b8158c85e7b64516b9d7b32f4930705574090e5b9cab534b1 lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin d897366aa5c58f426eaf3fc748d9def8f78111d9ac8c122e390952f640de22fc diff --git a/core/gethwrappers/ccip/mocks/evm2_evm_off_ramp_interface.go b/core/gethwrappers/ccip/mocks/evm2_evm_off_ramp_interface.go index 6da66583e6..9d63c34b02 100644 --- a/core/gethwrappers/ccip/mocks/evm2_evm_off_ramp_interface.go +++ b/core/gethwrappers/ccip/mocks/evm2_evm_off_ramp_interface.go @@ -358,6 +358,64 @@ func (_c *EVM2EVMOffRampInterface_FilterAdminSet_Call) RunAndReturn(run func(*bi return _c } +// FilterAlreadyAttempted provides a mock function with given fields: opts +func (_m *EVM2EVMOffRampInterface) FilterAlreadyAttempted(opts *bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttemptedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterAlreadyAttempted") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttemptedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttemptedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttemptedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttemptedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_FilterAlreadyAttempted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterAlreadyAttempted' +type EVM2EVMOffRampInterface_FilterAlreadyAttempted_Call struct { + *mock.Call +} + +// FilterAlreadyAttempted is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *EVM2EVMOffRampInterface_Expecter) FilterAlreadyAttempted(opts interface{}) *EVM2EVMOffRampInterface_FilterAlreadyAttempted_Call { + return &EVM2EVMOffRampInterface_FilterAlreadyAttempted_Call{Call: _e.mock.On("FilterAlreadyAttempted", opts)} +} + +func (_c *EVM2EVMOffRampInterface_FilterAlreadyAttempted_Call) Run(run func(opts *bind.FilterOpts)) *EVM2EVMOffRampInterface_FilterAlreadyAttempted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterAlreadyAttempted_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttemptedIterator, _a1 error) *EVM2EVMOffRampInterface_FilterAlreadyAttempted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_FilterAlreadyAttempted_Call) RunAndReturn(run func(*bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttemptedIterator, error)) *EVM2EVMOffRampInterface_FilterAlreadyAttempted_Call { + _c.Call.Return(run) + return _c +} + // FilterConfigChanged provides a mock function with given fields: opts func (_m *EVM2EVMOffRampInterface) FilterConfigChanged(opts *bind.FilterOpts) (*evm_2_evm_offramp.EVM2EVMOffRampConfigChangedIterator, error) { ret := _m.Called(opts) @@ -1809,6 +1867,64 @@ func (_c *EVM2EVMOffRampInterface_ParseAdminSet_Call) RunAndReturn(run func(type return _c } +// ParseAlreadyAttempted provides a mock function with given fields: log +func (_m *EVM2EVMOffRampInterface) ParseAlreadyAttempted(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseAlreadyAttempted") + } + + var r0 *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_ParseAlreadyAttempted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseAlreadyAttempted' +type EVM2EVMOffRampInterface_ParseAlreadyAttempted_Call struct { + *mock.Call +} + +// ParseAlreadyAttempted is a helper method to define mock.On call +// - log types.Log +func (_e *EVM2EVMOffRampInterface_Expecter) ParseAlreadyAttempted(log interface{}) *EVM2EVMOffRampInterface_ParseAlreadyAttempted_Call { + return &EVM2EVMOffRampInterface_ParseAlreadyAttempted_Call{Call: _e.mock.On("ParseAlreadyAttempted", log)} +} + +func (_c *EVM2EVMOffRampInterface_ParseAlreadyAttempted_Call) Run(run func(log types.Log)) *EVM2EVMOffRampInterface_ParseAlreadyAttempted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseAlreadyAttempted_Call) Return(_a0 *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted, _a1 error) *EVM2EVMOffRampInterface_ParseAlreadyAttempted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_ParseAlreadyAttempted_Call) RunAndReturn(run func(types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted, error)) *EVM2EVMOffRampInterface_ParseAlreadyAttempted_Call { + _c.Call.Return(run) + return _c +} + // ParseConfigChanged provides a mock function with given fields: log func (_m *EVM2EVMOffRampInterface) ParseConfigChanged(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampConfigChanged, error) { ret := _m.Called(log) @@ -3100,6 +3216,65 @@ func (_c *EVM2EVMOffRampInterface_WatchAdminSet_Call) RunAndReturn(run func(*bin return _c } +// WatchAlreadyAttempted provides a mock function with given fields: opts, sink +func (_m *EVM2EVMOffRampInterface) WatchAlreadyAttempted(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchAlreadyAttempted") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EVM2EVMOffRampInterface_WatchAlreadyAttempted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchAlreadyAttempted' +type EVM2EVMOffRampInterface_WatchAlreadyAttempted_Call struct { + *mock.Call +} + +// WatchAlreadyAttempted is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted +func (_e *EVM2EVMOffRampInterface_Expecter) WatchAlreadyAttempted(opts interface{}, sink interface{}) *EVM2EVMOffRampInterface_WatchAlreadyAttempted_Call { + return &EVM2EVMOffRampInterface_WatchAlreadyAttempted_Call{Call: _e.mock.On("WatchAlreadyAttempted", opts, sink)} +} + +func (_c *EVM2EVMOffRampInterface_WatchAlreadyAttempted_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted)) *EVM2EVMOffRampInterface_WatchAlreadyAttempted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted)) + }) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchAlreadyAttempted_Call) Return(_a0 event.Subscription, _a1 error) *EVM2EVMOffRampInterface_WatchAlreadyAttempted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *EVM2EVMOffRampInterface_WatchAlreadyAttempted_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *evm_2_evm_offramp.EVM2EVMOffRampAlreadyAttempted) (event.Subscription, error)) *EVM2EVMOffRampInterface_WatchAlreadyAttempted_Call { + _c.Call.Return(run) + return _c +} + // WatchConfigChanged provides a mock function with given fields: opts, sink func (_m *EVM2EVMOffRampInterface) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *evm_2_evm_offramp.EVM2EVMOffRampConfigChanged) (event.Subscription, error) { ret := _m.Called(opts, sink) From b1694e21c6ab039654d80a551f83be2eec3442ac Mon Sep 17 00:00:00 2001 From: Ryan <80392855+RayXpub@users.noreply.github.com> Date: Mon, 5 Aug 2024 19:02:38 +0400 Subject: [PATCH 191/432] Static analysis fixes (#1255) ## Motivation This PR applies several fixes from static analysis findings. ## Solution Fixes include: - Unused state variables removal - Unused imports removal - Unused events removal - Unused custom errors removal - Add of missing zero address check - Implementation of missing getter - Use of constants instead of magic numbers --- contracts/gas-snapshots/ccip.gas-snapshot | 68 ++-- .../v0.8/ccip/MultiAggregateRateLimiter.sol | 3 - contracts/src/v0.8/ccip/PriceRegistry.sol | 5 - .../src/v0.8/ccip/capability/CCIPConfig.sol | 21 +- .../v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 2 +- .../v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol | 13 - .../src/v0.8/ccip/test/NonceManager.t.sol | 2 +- .../ccip/test/capability/CCIPConfig.t.sol | 23 +- .../ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol | 2 +- .../ccip/generated/ccip_config/ccip_config.go | 28 +- .../evm_2_evm_multi_onramp.go | 131 +------ .../price_registry/price_registry.go | 282 +------------- ...rapper-dependency-versions-do-not-edit.txt | 6 +- .../ccip/mocks/price_registry_interface.go | 354 ------------------ 14 files changed, 104 insertions(+), 836 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 07822638c6..4bb6701f8f 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -35,43 +35,45 @@ BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243517) BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 24304) CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2132877) -CCIPConfigSetup:test_getCapabilityConfiguration_Success() (gas: 9495) -CCIPConfig_ConfigStateMachine:test__computeConfigDigest_Success() (gas: 70755) -CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_InitToRunning_Success() (gas: 363647) -CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_RunningToStaging_Success() (gas: 488774) -CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_StagingToRunning_Success() (gas: 453384) +CCIPConfigSetup:test_getCapabilityConfiguration_Success() (gas: 9517) +CCIPConfig_ConfigStateMachine:test__computeConfigDigest_Success() (gas: 70831) +CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_InitToRunning_Success() (gas: 363708) +CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_RunningToStaging_Success() (gas: 488870) +CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_StagingToRunning_Success() (gas: 453483) CCIPConfig_ConfigStateMachine:test__groupByPluginType_TooManyOCR3Configs_Reverts() (gas: 37027) CCIPConfig_ConfigStateMachine:test__groupByPluginType_threeCommitConfigs_Reverts() (gas: 61043) CCIPConfig_ConfigStateMachine:test__groupByPluginType_threeExecutionConfigs_Reverts() (gas: 60963) -CCIPConfig_ConfigStateMachine:test__stateFromConfigLength_Success() (gas: 11764) -CCIPConfig_ConfigStateMachine:test__validateConfigStateTransition_Success() (gas: 8765) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_InitToRunning_Success() (gas: 311991) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_InitToRunning_WrongConfigCount_Reverts() (gas: 49663) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_NonExistentConfigTransition_Reverts() (gas: 32275) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_Success() (gas: 376576) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_WrongConfigCount_Reverts() (gas: 120943) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_WrongConfigDigestBlueGreen_Reverts() (gas: 157105) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_StagingToRunning_Success() (gas: 376352) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_StagingToRunning_WrongConfigDigest_Reverts() (gas: 157172) -CCIPConfig_ConfigStateMachine:test_getCapabilityConfiguration_Success() (gas: 9583) -CCIPConfig__updatePluginConfig:test__updatePluginConfig_InitToRunning_Success() (gas: 1057393) -CCIPConfig__updatePluginConfig:test__updatePluginConfig_InvalidConfigLength_Reverts() (gas: 27539) -CCIPConfig__updatePluginConfig:test__updatePluginConfig_InvalidConfigStateTransition_Reverts() (gas: 23105) -CCIPConfig__updatePluginConfig:test__updatePluginConfig_RunningToStaging_Success() (gas: 2009309) -CCIPConfig__updatePluginConfig:test__updatePluginConfig_StagingToRunning_Success() (gas: 2616177) -CCIPConfig__updatePluginConfig:test_getCapabilityConfiguration_Success() (gas: 9583) -CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_CommitAndExecConfig_Success() (gas: 1851188) -CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_CommitConfigOnly_Success() (gas: 1068362) -CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_ExecConfigOnly_Success() (gas: 1068393) +CCIPConfig_ConfigStateMachine:test__stateFromConfigLength_Success() (gas: 11635) +CCIPConfig_ConfigStateMachine:test__validateConfigStateTransition_Success() (gas: 8831) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_InitToRunning_Success() (gas: 312055) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_InitToRunning_WrongConfigCount_Reverts() (gas: 49727) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_NonExistentConfigTransition_Reverts() (gas: 32320) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_Success() (gas: 376678) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_WrongConfigCount_Reverts() (gas: 121045) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_WrongConfigDigestBlueGreen_Reverts() (gas: 157245) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_StagingToRunning_Success() (gas: 376454) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_StagingToRunning_WrongConfigDigest_Reverts() (gas: 157312) +CCIPConfig_ConfigStateMachine:test_getCapabilityConfiguration_Success() (gas: 9605) +CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_CommitAndExecConfig_Success() (gas: 1851094) +CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_CommitConfigOnly_Success() (gas: 1068315) +CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_ExecConfigOnly_Success() (gas: 1068346) CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_OnlyCapabilitiesRegistryCanCall_Reverts() (gas: 9599) CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_ZeroLengthConfig_Success() (gas: 16070) -CCIPConfig_beforeCapabilityConfigSet:test_getCapabilityConfiguration_Success() (gas: 9583) +CCIPConfig_beforeCapabilityConfigSet:test_getCapabilityConfiguration_Success() (gas: 9605) CCIPConfig_chainConfig:test__applyChainConfigUpdates_FChainNotPositive_Reverts() (gas: 184703) CCIPConfig_chainConfig:test_applyChainConfigUpdates_addChainConfigs_Success() (gas: 344332) CCIPConfig_chainConfig:test_applyChainConfigUpdates_nodeNotInRegistry_Reverts() (gas: 20258) CCIPConfig_chainConfig:test_applyChainConfigUpdates_removeChainConfigs_Success() (gas: 267558) CCIPConfig_chainConfig:test_applyChainConfigUpdates_selectorNotFound_Reverts() (gas: 14829) -CCIPConfig_chainConfig:test_getCapabilityConfiguration_Success() (gas: 9626) +CCIPConfig_chainConfig:test_getCapabilityConfiguration_Success() (gas: 9648) +CCIPConfig_constructor:test_constructor_Success() (gas: 3567986) +CCIPConfig_constructor:test_constructor_ZeroAddressNotAllowed_Revert() (gas: 61720) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_InitToRunning_Success() (gas: 1057346) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_InvalidConfigLength_Reverts() (gas: 27539) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_InvalidConfigStateTransition_Reverts() (gas: 23105) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_RunningToStaging_Success() (gas: 2009267) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_StagingToRunning_Success() (gas: 2616097) +CCIPConfig_updatePluginConfig:test_getCapabilityConfiguration_Success() (gas: 9605) CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsHasDuplicates_Reverts() (gas: 294893) CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsNotASubsetOfP2PIds_Reverts() (gas: 298325) CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsNotSorted_Reverts() (gas: 295038) @@ -89,7 +91,7 @@ CCIPConfig_validateConfig:test__validateConfig_Success() (gas: 302186) CCIPConfig_validateConfig:test__validateConfig_TooManyBootstrapP2PIds_Reverts() (gas: 294539) CCIPConfig_validateConfig:test__validateConfig_TooManySigners_Reverts() (gas: 1215861) CCIPConfig_validateConfig:test__validateConfig_TooManyTransmitters_Reverts() (gas: 1214264) -CCIPConfig_validateConfig:test_getCapabilityConfiguration_Success() (gas: 9562) +CCIPConfig_validateConfig:test_getCapabilityConfiguration_Success() (gas: 9584) CommitStore_constructor:test_Constructor_Success() (gas: 3091326) CommitStore_isUnpausedAndRMNHealthy:test_RMN_Success() (gas: 73420) CommitStore_report:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 28670) @@ -250,11 +252,11 @@ EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176604) EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178672) EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141533) EVM2EVMMultiOffRamp_verify:test_TooManyLeaves_Revert() (gas: 51508) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94528) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92480) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97483) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92538) -EVM2EVMMultiOnRamp_constructor:test_Constructor_Success() (gas: 2260144) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94508) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92460) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97463) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92518) +EVM2EVMMultiOnRamp_constructor:test_Constructor_Success() (gas: 2256117) EVM2EVMMultiOnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 90987) EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 130983) EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 161753) diff --git a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol index 4252d0defd..f86bbed2c0 100644 --- a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol +++ b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol @@ -11,8 +11,6 @@ import {Client} from "./libraries/Client.sol"; import {RateLimiter} from "./libraries/RateLimiter.sol"; import {USDPriceWith18Decimals} from "./libraries/USDPriceWith18Decimals.sol"; -import {EnumerableSet} from "./../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; - /// @notice The aggregate rate limiter is a wrapper of the token bucket rate limiter /// which permits rate limiting based on the aggregate value of a group of /// token transfers, using a price registry to convert to a numeraire asset (e.g. USD). @@ -22,7 +20,6 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT using RateLimiter for RateLimiter.TokenBucket; using USDPriceWith18Decimals for uint224; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; - using EnumerableSet for EnumerableSet.AddressSet; error PriceNotFoundForToken(address token); error ZeroChainSelectorNotAllowed(); diff --git a/contracts/src/v0.8/ccip/PriceRegistry.sol b/contracts/src/v0.8/ccip/PriceRegistry.sol index f15232271e..c6250d7bc9 100644 --- a/contracts/src/v0.8/ccip/PriceRegistry.sol +++ b/contracts/src/v0.8/ccip/PriceRegistry.sol @@ -51,14 +51,11 @@ contract PriceRegistry is AuthorizedCallers, IPriceRegistry, ITypeAndVersion { error MessageTooLarge(uint256 maxSize, uint256 actualSize); error UnsupportedNumberOfTokens(); - event PriceUpdaterSet(address indexed priceUpdater); - event PriceUpdaterRemoved(address indexed priceUpdater); event FeeTokenAdded(address indexed feeToken); event FeeTokenRemoved(address indexed feeToken); event UsdPerUnitGasUpdated(uint64 indexed destChain, uint256 value, uint256 timestamp); event UsdPerTokenUpdated(address indexed token, uint256 value, uint256 timestamp); event PriceFeedPerTokenUpdated(address indexed token, IPriceRegistry.TokenPriceFeedConfig priceFeedConfig); - event TokenTransferFeeConfigUpdated( uint64 indexed destChainSelector, address indexed token, TokenTransferFeeConfig tokenTransferFeeConfig ); @@ -178,8 +175,6 @@ contract PriceRegistry is AuthorizedCallers, IPriceRegistry, ITypeAndVersion { /// @dev The link token address address internal immutable i_linkToken; - // Price updaters are allowed to update the prices. - EnumerableSet.AddressSet private s_priceUpdaters; // Subset of tokens which prices tracked by this registry which are fee tokens. EnumerableSet.AddressSet private s_feeTokens; // The amount of time a gas price can be stale before it is considered invalid. diff --git a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol index 40b7a4a2f9..9a88c4bccd 100644 --- a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol +++ b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol @@ -31,7 +31,6 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator /// @param chainSelector The chain selector. event ChainConfigRemoved(uint64 chainSelector); - error ChainConfigNotSetForChain(uint64 chainSelector); error NodeNotInRegistry(bytes32 p2pId); error OnlyCapabilitiesRegistryCanCall(); error ChainSelectorNotFound(uint64 chainSelector); @@ -55,6 +54,7 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator error WrongConfigCount(uint64 got, uint64 expected); error WrongConfigDigest(bytes32 got, bytes32 expected); error WrongConfigDigestBlueGreen(bytes32 got, bytes32 expected); + error ZeroAddressNotAllowed(); /// @notice Type and version override. string public constant override typeAndVersion = "CCIPConfig 1.6.0-dev"; @@ -75,15 +75,18 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator uint32 donId => mapping(Internal.OCRPluginType pluginType => CCIPConfigTypes.OCR3ConfigWithMeta[] ocr3Configs) ) internal s_ocr3Configs; - /// @notice The DONs that have been configured. - EnumerableSet.UintSet internal s_donIds; - uint8 internal constant MAX_OCR3_CONFIGS_PER_PLUGIN = 2; uint8 internal constant MAX_OCR3_CONFIGS_PER_DON = 4; uint8 internal constant MAX_NUM_ORACLES = 31; + uint256 internal constant CONFIG_DIGEST_PREFIX_MASK = type(uint256).max << (256 - 16); // 0xFFFF00..0 + /// @dev must be equal to libocr multi role: https://github.com/smartcontractkit/libocr/blob/ae747ca5b81236ffdbf1714318c652e923a5ff4d/offchainreporting2plus/types/config_digest.go#L28 + uint256 internal constant CONFIG_DIGEST_PREFIX = 0x000a << (256 - 16); // 0x000a00..00 /// @param capabilitiesRegistry the canonical capabilities registry address. constructor(address capabilitiesRegistry) { + if (capabilitiesRegistry == address(0)) { + revert ZeroAddressNotAllowed(); + } i_capabilitiesRegistry = capabilitiesRegistry; } @@ -95,6 +98,11 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator // ================================================================ // │ Config Getters │ // ================================================================ + /// @notice Returns the capabilities registry address. + /// @return The capabilities registry address. + function getCapabilityRegistry() external view returns (address) { + return i_capabilitiesRegistry; + } /// @notice Returns all the chain configurations. /// @return The chain configurations. @@ -413,9 +421,8 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator ) ) ); - uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 - uint256 prefix = 0x000a << (256 - 16); // 0x000a00..00 - return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + + return bytes32((CONFIG_DIGEST_PREFIX & CONFIG_DIGEST_PREFIX_MASK) | (h & ~CONFIG_DIGEST_PREFIX_MASK)); } // ================================================================ diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol index 89c066dd11..34e4793d22 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -618,7 +618,7 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { /// @notice Returns the sequence number of the last price update. /// @return the latest price update sequence number. - function getLatestPriceSequenceNumber() public view returns (uint64) { + function getLatestPriceSequenceNumber() external view returns (uint64) { return s_latestPriceSequenceNumber; } diff --git a/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol b/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol index fc455cc869..10d2a11079 100644 --- a/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol @@ -27,10 +27,6 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre using USDPriceWith18Decimals for uint224; error CannotSendZeroTokens(); - error InvalidExtraArgsTag(); - error ExtraArgOutOfOrderExecutionMustBeTrue(); - error OnlyCallableByOwnerOrAdmin(); - error MessageGasLimitTooHigh(); error UnsupportedToken(address token); error MustBeCalledByRouter(); error RouterMustSetOriginalSender(); @@ -38,7 +34,6 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre error CursedByRMN(uint64 sourceChainSelector); error GetSupportedTokensFunctionalityRemovedCheckAdminRegistry(); - event AdminSet(address newAdmin); event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig); event FeePaid(address indexed feeToken, uint256 feeValueJuels); event FeeTokenWithdrawn(address indexed feeAggregator, address indexed feeToken, uint256 amount); @@ -75,8 +70,6 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre /// @dev The address of the token admin registry address internal immutable i_tokenAdminRegistry; /// @dev the maximum number of nops that can be configured at the same time. - /// Used to bound gas for loops over nops. - uint256 private constant MAX_NUMBER_OF_NOPS = 64; // DYNAMIC CONFIG /// @dev The config for the onRamp @@ -87,12 +80,6 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre /// 0 is not a valid sequence number for any real transaction. mapping(uint64 destChainSelector => uint64 sequenceNumber) internal s_destChainSequenceNumbers; - // STATE - /// @dev The amount of LINK available to pay NOPS - uint96 internal s_nopFeesJuels; - /// @dev The combined weight of all NOPs weights - uint32 internal s_nopWeightsTotal; - constructor(StaticConfig memory staticConfig, DynamicConfig memory dynamicConfig) { if ( staticConfig.chainSelector == 0 || staticConfig.rmnProxy == address(0) || staticConfig.nonceManager == address(0) diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol index 6ba08597ca..48d00fbaee 100644 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -27,7 +27,7 @@ contract NonceManager_typeAndVersion is Test { s_nonceManager = new NonceManager(new address[](0)); } - function test_typeAndVersion() public { + function test_typeAndVersion() public view { assertEq(s_nonceManager.typeAndVersion(), "NonceManager 1.6.0-dev"); } } diff --git a/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol b/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol index 0c3108d279..2bb29cd38d 100644 --- a/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol +++ b/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol @@ -1,14 +1,13 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; -import {Test} from "forge-std/Test.sol"; - import {SortedSetValidationUtil} from "../../../shared/util/SortedSetValidationUtil.sol"; import {CCIPConfig} from "../../capability/CCIPConfig.sol"; import {ICapabilitiesRegistry} from "../../capability/interfaces/ICapabilitiesRegistry.sol"; import {CCIPConfigTypes} from "../../capability/libraries/CCIPConfigTypes.sol"; import {Internal} from "../../libraries/Internal.sol"; import {CCIPConfigHelper} from "../helpers/CCIPConfigHelper.sol"; +import {Test} from "forge-std/Test.sol"; contract CCIPConfigSetup is Test { address public constant OWNER = 0x82ae2B4F57CA5C1CBF8f744ADbD3697aD1a35AFe; @@ -109,6 +108,24 @@ contract CCIPConfigSetup is Test { } } +contract CCIPConfig_constructor is Test { + // Successes. + + function test_constructor_Success() public { + address capabilitiesRegistry = makeAddr("capabilitiesRegistry"); + CCIPConfigHelper ccipCC = new CCIPConfigHelper(capabilitiesRegistry); + assertEq(address(ccipCC.getCapabilityRegistry()), capabilitiesRegistry); + assertEq(ccipCC.typeAndVersion(), "CCIPConfig 1.6.0-dev"); + } + + // Reverts. + + function test_constructor_ZeroAddressNotAllowed_Revert() public { + vm.expectRevert(CCIPConfig.ZeroAddressNotAllowed.selector); + new CCIPConfigHelper(address(0)); + } +} + contract CCIPConfig_chainConfig is CCIPConfigSetup { // Successes. @@ -1360,7 +1377,7 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { } } -contract CCIPConfig__updatePluginConfig is CCIPConfigSetup { +contract CCIPConfig_updatePluginConfig is CCIPConfigSetup { // Successes. function test__updatePluginConfig_InitToRunning_Success() public { diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol index bc7fac95be..08e468e622 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol @@ -337,7 +337,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); message.extraArgs = bytes("bad args"); - vm.expectRevert(EVM2EVMMultiOnRamp.InvalidExtraArgsTag.selector); + vm.expectRevert(PriceRegistry.InvalidExtraArgsTag.selector); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); } diff --git a/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go b/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go index e35a8726de..d367872b05 100644 --- a/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go +++ b/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go @@ -61,8 +61,8 @@ type CCIPConfigTypesOCR3ConfigWithMeta struct { } var CCIPConfigMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigNotSetForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidConfigLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"currentState\",\"type\":\"uint8\"},{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"proposedState\",\"type\":\"uint8\"}],\"name\":\"InvalidConfigStateTransition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeNotInRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonExistentConfigTransition\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"set\",\"type\":\"bytes32[]\"}],\"name\":\"NotASortedSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"subset\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"superset\",\"type\":\"bytes32[]\"}],\"name\":\"NotASubset\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"NotEnoughTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfframpAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p2pIdsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"signersLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transmittersLength\",\"type\":\"uint256\"}],\"name\":\"P2PIdsLengthNotMatching\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyBootstrapP2PIds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOCR3Configs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyTransmitters\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"}],\"name\":\"WrongConfigCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigestBlueGreen\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapabilityConfigurationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"chainSelectorRemoves\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllChainConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getOCRConfig\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"bootstrapP2PIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"internalType\":\"structCCIPConfigTypes.OCR3ConfigWithMeta[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620043cc380380620043cc83398101604081905262000034916200017e565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d3565b5050506001600160a01b0316608052620001b0565b336001600160a01b038216036200012d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019157600080fd5b81516001600160a01b0381168114620001a957600080fd5b9392505050565b6080516141f9620001d360003960008181610e4e01526110e301526141f96000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80638da5cb5b11610076578063f2fde38b1161005b578063f2fde38b146101bc578063f442c89a146101cf578063fba64a7c146101e257600080fd5b80638da5cb5b1461017f578063ddc042a8146101a757600080fd5b80634bd0473f116100a75780634bd0473f1461013457806379ba5097146101545780638318ed5d1461015e57600080fd5b806301ffc9a7146100c3578063181f5a77146100eb575b600080fd5b6100d66100d1366004612f77565b6101f5565b60405190151581526020015b60405180910390f35b6101276040518060400160405280601481526020017f43434950436f6e66696720312e362e302d64657600000000000000000000000081525081565b6040516100e2919061301d565b610147610142366004613061565b61028e565b6040516100e2919061318d565b61015c61075e565b005b61012761016c36600461336a565b5060408051602081019091526000815290565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e2565b6101af610860565b6040516100e291906133cb565b61015c6101ca36600461345b565b610a52565b61015c6101dd3660046134dd565b610a66565b61015c6101f0366004613561565b610e36565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea72100000000000000000000000000000000000000000000000000000000148061028857507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b63ffffffff821660009081526005602052604081206060918360018111156102b8576102b8613096565b60018111156102c9576102c9613096565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561075257600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff16600181111561033c5761033c613096565b600181111561034d5761034d613096565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916103a59061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546103d19061361e565b801561041e5780601f106103f35761010080835404028352916020019161041e565b820191906000526020600020905b81548152906001019060200180831161040157829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561047657602002820191906000526020600020905b815481526020019060010190808311610462575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156104ce57602002820191906000526020600020905b8154815260200190600101908083116104ba575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156105a857838290600052602060002001805461051b9061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546105479061361e565b80156105945780601f1061056957610100808354040283529160200191610594565b820191906000526020600020905b81548152906001019060200180831161057757829003601f168201915b5050505050815260200190600101906104fc565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156106815783829060005260206000200180546105f49061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546106209061361e565b801561066d5780601f106106425761010080835404028352916020019161066d565b820191906000526020600020905b81548152906001019060200180831161065057829003601f168201915b5050505050815260200190600101906105d5565b5050505081526020016006820180546106999061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546106c59061361e565b80156107125780601f106106e757610100808354040283529160200191610712565b820191906000526020600020905b8154815290600101906020018083116106f557829003601f168201915b505050919092525050508152600782015467ffffffffffffffff1660208083019190915260089092015460409091015290825260019290920191016102f7565b50505050905092915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6060600061086e6003610ef7565b9050600061087c6003610f0b565b67ffffffffffffffff81111561089457610894613671565b6040519080825280602002602001820160405280156108cd57816020015b6108ba612d08565b8152602001906001900390816108b25790505b50905060005b8251811015610a4b5760008382815181106108f0576108f06136a0565b60209081029190910181015160408051808201825267ffffffffffffffff83168082526000908152600285528290208251815460808188028301810190955260608201818152959750929586019490939192849284919084018282801561097657602002820191906000526020600020905b815481526020019060010190808311610962575b5050509183525050600182015460ff1660208201526002820180546040909201916109a09061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546109cc9061361e565b8015610a195780601f106109ee57610100808354040283529160200191610a19565b820191906000526020600020905b8154815290600101906020018083116109fc57829003601f168201915b505050505081525050815250838381518110610a3757610a376136a0565b6020908102919091010152506001016108d3565b5092915050565b610a5a610f15565b610a6381610f98565b50565b610a6e610f15565b60005b83811015610c5457610ab5858583818110610a8e57610a8e6136a0565b9050602002016020810190610aa391906136cf565b60039067ffffffffffffffff1661108d565b610b1f57848482818110610acb57610acb6136a0565b9050602002016020810190610ae091906136cf565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107db565b60026000868684818110610b3557610b356136a0565b9050602002016020810190610b4a91906136cf565b67ffffffffffffffff1681526020810191909152604001600090812090610b718282612d50565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610ba9600283016000612d6e565b5050610be7858583818110610bc057610bc06136a0565b9050602002016020810190610bd591906136cf565b60039067ffffffffffffffff166110a5565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110610c1b57610c1b6136a0565b9050602002016020810190610c3091906136cf565b60405167ffffffffffffffff909116815260200160405180910390a1600101610a71565b5060005b81811015610e2f576000838383818110610c7457610c746136a0565b9050602002810190610c8691906136ea565b610c94906020810190613728565b610c9d9061392a565b80519091506000858585818110610cb657610cb66136a0565b9050602002810190610cc891906136ea565b610cd69060208101906136cf565b905060005b8251811015610d0e57610d06838281518110610cf957610cf96136a0565b60200260200101516110b1565b600101610cdb565b50826020015160ff16600003610d50576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120845180518693610d80928492910190612da8565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560408201516002820190610dcd9082613a11565b50610de791506003905067ffffffffffffffff83166111ca565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e08184604051610e19929190613b2b565b60405180910390a1505050806001019050610c58565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610ea5576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610eb384860186613bd6565b9050600080610ec1836111d6565b8151919350915015610ed957610ed98460008461142f565b805115610eec57610eec8460018361142f565b505050505050505050565b60606000610f0483611c10565b9392505050565b6000610288825490565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107db565b565b3373ffffffffffffffffffffffffffffffffffffffff821603611017576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107db565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515610f04565b6000610f048383611c6c565b6040517f50c946fe000000000000000000000000000000000000000000000000000000008152600481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906350c946fe90602401600060405180830381865afa15801561113f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111859190810190613e47565b60808101519091506111c6576040517f8907a4fa000000000000000000000000000000000000000000000000000000008152600481018390526024016107db565b5050565b6000610f048383611d5f565b606080600460ff1683511115611218576040517f8854586400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160028082526060820190925290816020015b61129c6040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161122e57505060408051600280825260608201909252919350602082015b6113346040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b8152602001906001900390816112c657905050905060008060005b855181101561142257600086828151811061136c5761136c6136a0565b602002602001015160000151600181111561138957611389613096565b036113d6578581815181106113a0576113a06136a0565b60200260200101518584815181106113ba576113ba6136a0565b6020026020010181905250826113cf90613f4e565b925061141a565b8581815181106113e8576113e86136a0565b6020026020010151848381518110611402576114026136a0565b60200260200101819052508161141790613f4e565b91505b60010161134f565b5090835281529092909150565b63ffffffff831660009081526005602052604081208184600181111561145757611457613096565b600181111561146857611468613096565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156118f157600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff1660018111156114db576114db613096565b60018111156114ec576114ec613096565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916115449061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546115709061361e565b80156115bd5780601f10611592576101008083540402835291602001916115bd565b820191906000526020600020905b8154815290600101906020018083116115a057829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561161557602002820191906000526020600020905b815481526020019060010190808311611601575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561166d57602002820191906000526020600020905b815481526020019060010190808311611659575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156117475783829060005260206000200180546116ba9061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546116e69061361e565b80156117335780601f1061170857610100808354040283529160200191611733565b820191906000526020600020905b81548152906001019060200180831161171657829003601f168201915b50505050508152602001906001019061169b565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156118205783829060005260206000200180546117939061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546117bf9061361e565b801561180c5780601f106117e15761010080835404028352916020019161180c565b820191906000526020600020905b8154815290600101906020018083116117ef57829003601f168201915b505050505081526020019060010190611774565b5050505081526020016006820180546118389061361e565b80601f01602080910402602001604051908101604052809291908181526020018280546118649061361e565b80156118b15780601f10611886576101008083540402835291602001916118b1565b820191906000526020600020905b81548152906001019060200180831161189457829003601f168201915b505050919092525050508152600782015467ffffffffffffffff166020808301919091526008909201546040909101529082526001929092019101611496565b50505050905060006119038251611dae565b905060006119118451611dae565b905061191d8282611e00565b600061192c8785878686611ebc565b905061193884826122a8565b63ffffffff871660009081526005602052604081209087600181111561196057611960613096565b600181111561197157611971613096565b8152602001908152602001600020600061198b9190612df3565b60005b8151811015611c065763ffffffff88166000908152600560205260408120908860018111156119bf576119bf613096565b60018111156119d0576119d0613096565b81526020019081526020016000208282815181106119f0576119f06136a0565b6020908102919091018101518254600181810185556000948552929093208151805160099095029091018054929490939192849283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908381811115611a5a57611a5a613096565b021790555060208201518154604084015160608501517fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90921661010067ffffffffffffffff948516027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1617690100000000000000000060ff90921691909102177fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a0100000000000000000000929091169190910217815560808201516001820190611b299082613a11565b5060a08201518051611b45916002840191602090910190612da8565b5060c08201518051611b61916003840191602090910190612da8565b5060e08201518051611b7d916004840191602090910190612e14565b506101008201518051611b9a916005840191602090910190612e14565b506101208201516006820190611bb09082613a11565b50505060208201516007820180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff90921691909117905560409091015160089091015560010161198e565b5050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611c6057602002820191906000526020600020905b815481526020019060010190808311611c4c575b50505050509050919050565b60008181526001830160205260408120548015611d55576000611c90600183613f86565b8554909150600090611ca490600190613f86565b9050818114611d09576000866000018281548110611cc457611cc46136a0565b9060005260206000200154905080876000018481548110611ce757611ce76136a0565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611d1a57611d1a613f99565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610288565b6000915050610288565b6000818152600183016020526040812054611da657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610288565b506000610288565b60006002821115611dee576040517f3e478526000000000000000000000000000000000000000000000000000000008152600481018390526024016107db565b81600281111561028857610288613096565b6000826002811115611e1457611e14613096565b826002811115611e2657611e26613096565b611e309190613fc8565b90508060011480611e7c5750807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff148015611e7c57506002836002811115611e7a57611e7a613096565b145b15611e8657505050565b82826040517f0a6b675b0000000000000000000000000000000000000000000000000000000081526004016107db929190613ff8565b60606000845167ffffffffffffffff811115611eda57611eda613671565b604051908082528060200260200182016040528015611f03578160200160208202803683370190505b5090506000846002811115611f1a57611f1a613096565b148015611f3857506001836002811115611f3657611f36613096565b145b15611f7957600181600081518110611f5257611f526136a0565b602002602001019067ffffffffffffffff16908167ffffffffffffffff16815250506120e1565b6001846002811115611f8d57611f8d613096565b148015611fab57506002836002811115611fa957611fa9613096565b145b156120425785600081518110611fc357611fc36136a0565b60200260200101516020015181600081518110611fe257611fe26136a0565b602002602001019067ffffffffffffffff16908167ffffffffffffffff168152505085600081518110612017576120176136a0565b602002602001015160200151600161202f9190614013565b81600181518110611f5257611f526136a0565b600284600281111561205657612056613096565b1480156120745750600183600281111561207257612072613096565b145b156120ab578560018151811061208c5761208c6136a0565b60200260200101516020015181600081518110611f5257611f526136a0565b83836040517f0a6b675b0000000000000000000000000000000000000000000000000000000081526004016107db929190613ff8565b6000855167ffffffffffffffff8111156120fd576120fd613671565b6040519080825280602002602001820160405280156121b357816020015b604080516101a081018252600060608083018281526080840183905260a0840183905260c0840183905260e084018290526101008401829052610120840182905261014084018290526101608401829052610180840191909152825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161211b5790505b50905060005b825181101561229c576121e48782815181106121d7576121d76136a0565b6020026020010151612627565b6040518060600160405280888381518110612201576122016136a0565b60200260200101518152602001848381518110612220576122206136a0565b602002602001015167ffffffffffffffff1681526020016122748b86858151811061224d5761224d6136a0565b60200260200101518b8681518110612267576122676136a0565b6020026020010151612a2d565b815250828281518110612289576122896136a0565b60209081029190910101526001016121b9565b50979650505050505050565b81518151811580156122ba5750806001145b1561235c57826000815181106122d2576122d26136a0565b60200260200101516020015167ffffffffffffffff166001146123565782600081518110612302576123026136a0565b60209081029190910181015101516040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152600160248201526044016107db565b50505050565b81600114801561236c5750806002145b156125225783600081518110612384576123846136a0565b602002602001015160400151836000815181106123a3576123a36136a0565b6020026020010151604001511461242f57826000815181106123c7576123c76136a0565b602002602001015160400151846000815181106123e6576123e66136a0565b6020026020010151604001516040517fc7ccdd7f0000000000000000000000000000000000000000000000000000000081526004016107db929190918252602082015260400190565b83600081518110612442576124426136a0565b602002602001015160200151600161245a9190614013565b67ffffffffffffffff1683600181518110612477576124776136a0565b60200260200101516020015167ffffffffffffffff161461235657826001815181106124a5576124a56136a0565b602002602001015160200151846000815181106124c4576124c46136a0565b60200260200101516020015160016124dc9190614013565b6040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9283166004820152911660248201526044016107db565b8160021480156125325750806001145b156125f5578360018151811061254a5761254a6136a0565b60200260200101516040015183600081518110612569576125696136a0565b60200260200101516040015114612356578260008151811061258d5761258d6136a0565b602002602001015160400151846001815181106125ac576125ac6136a0565b6020026020010151604001516040517f9e9756700000000000000000000000000000000000000000000000000000000081526004016107db929190918252602082015260400190565b6040517f1f1b2bb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015167ffffffffffffffff1660000361266f576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008151600181111561268457612684613096565b141580156126a557506001815160018111156126a2576126a2613096565b14155b156126dc576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80608001515160000361271b576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101516127369060039067ffffffffffffffff1661108d565b61277e5760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107db565b60e081015151601f10156127be576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010081015151601f10156127ff576040517f645960ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015167ffffffffffffffff1660009081526002909152604081206001015461282f9060ff166003614034565b61283a906001614050565b60ff1690508082610100015151101561289157610100820151516040517f548dd21f0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107db565b816040015160ff166000036128d2576040517f39d1a4d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516128e2906003614034565b60ff168260e001515111612922576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160e00151518260c00151511415806129465750816101000151518260c001515114155b156129a15760c08201515160e083015151610100840151516040517fba900f6d0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016107db565b8160c00151518260a001515111156129e5576040517f8473d80700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129f78260a001518360c00151612b02565b60005b8260e0015151811015612a2857612a208360c001518281518110610cf957610cf96136a0565b6001016129fa565b505050565b60008082602001518584600001518560800151878760a001518860c001518960e001518a61010001518b604001518c606001518d6101200151604051602001612a819c9b9a999897969594939291906140d4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0a000000000000000000000000000000000000000000000000000000000000179150509392505050565b81511580612b0f57508051155b15612b46576040517fe249684100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b4f82612c7d565b612b5881612c7d565b6000805b835182108015612b6c5750825181105b15612c3e57828181518110612b8357612b836136a0565b6020026020010151848381518110612b9d57612b9d6136a0565b60200260200101511115612bbb57612bb481613f4e565b9050612b5c565b828181518110612bcd57612bcd6136a0565b6020026020010151848381518110612be757612be76136a0565b602002602001015103612c0857612bfd82613f4e565b9150612bb481613f4e565b83836040517fd671700c0000000000000000000000000000000000000000000000000000000081526004016107db9291906141b4565b83518210156123565783836040517fd671700c0000000000000000000000000000000000000000000000000000000081526004016107db9291906141b4565b60015b81518110156111c65781612c95600183613f86565b81518110612ca557612ca56136a0565b6020026020010151828281518110612cbf57612cbf6136a0565b602002602001015111612d0057816040517f1bc41b420000000000000000000000000000000000000000000000000000000081526004016107db91906141d9565b600101612c80565b6040518060400160405280600067ffffffffffffffff168152602001612d4b604051806060016040528060608152602001600060ff168152602001606081525090565b905290565b5080546000825590600052602060002090810190610a639190612e66565b508054612d7a9061361e565b6000825580601f10612d8a575050565b601f016020900490600052602060002090810190610a639190612e66565b828054828255906000526020600020908101928215612de3579160200282015b82811115612de3578251825591602001919060010190612dc8565b50612def929150612e66565b5090565b5080546000825560090290600052602060002090810190610a639190612e7b565b828054828255906000526020600020908101928215612e5a579160200282015b82811115612e5a5782518290612e4a9082613a11565b5091602001919060010190612e34565b50612def929150612f3c565b5b80821115612def5760008155600101612e67565b80821115612def5780547fffffffffffffffffffffffffffff00000000000000000000000000000000000016815560008181612eba6001830182612d6e565b612ec8600283016000612d50565b612ed6600383016000612d50565b612ee4600483016000612f59565b612ef2600583016000612f59565b612f00600683016000612d6e565b5050506007810180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560006008820155600901612e7b565b80821115612def576000612f508282612d6e565b50600101612f3c565b5080546000825590600052602060002090810190610a639190612f3c565b600060208284031215612f8957600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f0457600080fd5b6000815180845260005b81811015612fdf57602081850181015186830182015201612fc3565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610f046020830184612fb9565b63ffffffff81168114610a6357600080fd5b803561304d81613030565b919050565b80356002811061304d57600080fd5b6000806040838503121561307457600080fd5b823561307f81613030565b915061308d60208401613052565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106130d5576130d5613096565b9052565b60008151808452602080850194506020840160005b8381101561310a578151875295820195908201906001016130ee565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015613180577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086840301895261316e838351612fb9565b98840198925090830190600101613134565b5090979650505050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b8381101561335c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08984030185528151606081518186526131fb82870182516130c5565b8981015160806132168189018367ffffffffffffffff169052565b8a830151915060a061322c818a018460ff169052565b938301519360c0925061324a8984018667ffffffffffffffff169052565b818401519450610140915060e082818b015261326a6101a08b0187612fb9565b95508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0610100818c890301818d01526132a988856130d9565b97508587015195506101209350818c890301848d01526132c988876130d9565b9750828701519550818c890301858d01526132e48887613115565b975080870151955050808b8803016101608c01526133028786613115565b9650828601519550808b8803016101808c015250505050506133248282612fb9565b915050888201516133408a87018267ffffffffffffffff169052565b50908701519387019390935293860193908601906001016131b6565b509098975050505050505050565b60006020828403121561337c57600080fd5b8135610f0481613030565b600081516060845261339c60608501826130d9565b905060ff6020840151166020850152604083015184820360408601526133c28282612fb9565b95945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b8381101561335c578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff16845287015187840187905261344887850182613387565b95880195935050908601906001016133f4565b60006020828403121561346d57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f0457600080fd5b60008083601f8401126134a357600080fd5b50813567ffffffffffffffff8111156134bb57600080fd5b6020830191508360208260051b85010111156134d657600080fd5b9250929050565b600080600080604085870312156134f357600080fd5b843567ffffffffffffffff8082111561350b57600080fd5b61351788838901613491565b9096509450602087013591508082111561353057600080fd5b5061353d87828801613491565b95989497509550505050565b803567ffffffffffffffff8116811461304d57600080fd5b6000806000806000806080878903121561357a57600080fd5b863567ffffffffffffffff8082111561359257600080fd5b61359e8a838b01613491565b909850965060208901359150808211156135b757600080fd5b818901915089601f8301126135cb57600080fd5b8135818111156135da57600080fd5b8a60208285010111156135ec57600080fd5b60208301965080955050505061360460408801613549565b915061361260608801613042565b90509295509295509295565b600181811c9082168061363257607f821691505b60208210810361366b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156136e157600080fd5b610f0482613549565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261371e57600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261371e57600080fd5b604051610140810167ffffffffffffffff8111828210171561378057613780613671565b60405290565b60405160e0810167ffffffffffffffff8111828210171561378057613780613671565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156137f0576137f0613671565b604052919050565b600067ffffffffffffffff82111561381257613812613671565b5060051b60200190565b600082601f83011261382d57600080fd5b8135602061384261383d836137f8565b6137a9565b8083825260208201915060208460051b87010193508684111561386457600080fd5b602086015b848110156138805780358352918301918301613869565b509695505050505050565b803560ff8116811461304d57600080fd5b600082601f8301126138ad57600080fd5b813567ffffffffffffffff8111156138c7576138c7613671565b6138f860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016137a9565b81815284602083860101111561390d57600080fd5b816020850160208301376000918101602001919091529392505050565b60006060823603121561393c57600080fd5b6040516060810167ffffffffffffffff828210818311171561396057613960613671565b81604052843591508082111561397557600080fd5b6139813683870161381c565b835261398f6020860161388b565b602084015260408501359150808211156139a857600080fd5b506139b53682860161389c565b60408301525092915050565b601f821115612a28576000816000526020600020601f850160051c810160208610156139ea5750805b601f850160051c820191505b81811015613a09578281556001016139f6565b505050505050565b815167ffffffffffffffff811115613a2b57613a2b613671565b613a3f81613a39845461361e565b846139c1565b602080601f831160018114613a925760008415613a5c5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613a09565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613adf57888601518255948401946001909101908401613ac0565b5085821015613b1b57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83168152604060208201526000613b4e6040830184613387565b949350505050565b600082601f830112613b6757600080fd5b81356020613b7761383d836137f8565b82815260059290921b84018101918181019086841115613b9657600080fd5b8286015b8481101561388057803567ffffffffffffffff811115613bba5760008081fd5b613bc88986838b010161389c565b845250918301918301613b9a565b60006020808385031215613be957600080fd5b823567ffffffffffffffff80821115613c0157600080fd5b818501915085601f830112613c1557600080fd5b8135613c2361383d826137f8565b81815260059190911b83018401908481019088831115613c4257600080fd5b8585015b83811015613dd057803585811115613c5d57600080fd5b8601610140818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215613c9257600080fd5b613c9a61375c565b613ca5898301613052565b8152613cb360408301613549565b89820152613cc36060830161388b565b6040820152613cd460808301613549565b606082015260a082013587811115613ceb57600080fd5b613cf98d8b8386010161389c565b60808301525060c082013587811115613d1157600080fd5b613d1f8d8b8386010161381c565b60a08301525060e082013587811115613d3757600080fd5b613d458d8b8386010161381c565b60c0830152506101008083013588811115613d5f57600080fd5b613d6d8e8c83870101613b56565b60e0840152506101208084013589811115613d8757600080fd5b613d958f8d83880101613b56565b8385015250610140840135915088821115613daf57600080fd5b613dbd8e8c8487010161389c565b9083015250845250918601918601613c46565b5098975050505050505050565b805161304d81613030565b600082601f830112613df957600080fd5b81516020613e0961383d836137f8565b8083825260208201915060208460051b870101935086841115613e2b57600080fd5b602086015b848110156138805780518352918301918301613e30565b600060208284031215613e5957600080fd5b815167ffffffffffffffff80821115613e7157600080fd5b9083019060e08286031215613e8557600080fd5b613e8d613786565b613e9683613ddd565b8152613ea460208401613ddd565b6020820152613eb560408401613ddd565b6040820152606083015160608201526080830151608082015260a083015182811115613ee057600080fd5b613eec87828601613de8565b60a08301525060c083015182811115613f0457600080fd5b613f1087828601613de8565b60c08301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613f7f57613f7f613f1f565b5060010190565b8181038181111561028857610288613f1f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8181036000831280158383131683831282161715610a4b57610a4b613f1f565b600381106130d5576130d5613096565b604081016140068285613fe8565b610f046020830184613fe8565b67ffffffffffffffff818116838216019080821115610a4b57610a4b613f1f565b60ff8181168382160290811690818114610a4b57610a4b613f1f565b60ff818116838216019081111561028857610288613f1f565b60008282518085526020808601955060208260051b8401016020860160005b84811015613180577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189526140c2838351612fb9565b98840198925090830190600101614088565b67ffffffffffffffff8d16815263ffffffff8c1660208201526140fa604082018c6130c5565b6101806060820152600061411261018083018c612fb9565b67ffffffffffffffff8b16608084015282810360a0840152614134818b6130d9565b905082810360c0840152614148818a6130d9565b905082810360e084015261415c8189614069565b90508281036101008401526141718188614069565b60ff8716610120850152905067ffffffffffffffff85166101408401528281036101608401526141a18185612fb9565b9f9e505050505050505050505050505050565b6040815260006141c760408301856130d9565b82810360208401526133c281856130d9565b602081526000610f0460208301846130d956fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidConfigLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"currentState\",\"type\":\"uint8\"},{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"proposedState\",\"type\":\"uint8\"}],\"name\":\"InvalidConfigStateTransition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeNotInRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonExistentConfigTransition\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"set\",\"type\":\"bytes32[]\"}],\"name\":\"NotASortedSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"subset\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"superset\",\"type\":\"bytes32[]\"}],\"name\":\"NotASubset\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"NotEnoughTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfframpAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p2pIdsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"signersLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transmittersLength\",\"type\":\"uint256\"}],\"name\":\"P2PIdsLengthNotMatching\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyBootstrapP2PIds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOCR3Configs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyTransmitters\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"}],\"name\":\"WrongConfigCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigestBlueGreen\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapabilityConfigurationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"chainSelectorRemoves\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllChainConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilityRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getOCRConfig\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"bootstrapP2PIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"internalType\":\"structCCIPConfigTypes.OCR3ConfigWithMeta[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b50604051620043d7380380620043d78339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e9576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b6080516141d6620002016000396000818160f801528181610e96015261112b01526141d66000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638318ed5d11610081578063f2fde38b1161005b578063f2fde38b14610204578063f442c89a14610217578063fba64a7c1461022a57600080fd5b80638318ed5d146101b05780638da5cb5b146101d1578063ddc042a8146101ef57600080fd5b8063181f5a77116100b2578063181f5a771461013d5780634bd0473f1461018657806379ba5097146101a657600080fd5b806301ffc9a7146100ce578063020330e6146100f6575b600080fd5b6100e16100dc366004612fbf565b61023d565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b6101796040518060400160405280601481526020017f43434950436f6e66696720312e362e302d64657600000000000000000000000081525081565b6040516100ed9190613065565b6101996101943660046130a9565b6102d6565b6040516100ed91906131d5565b6101ae6107a6565b005b6101796101be3660046133b2565b5060408051602081019091526000815290565b60005473ffffffffffffffffffffffffffffffffffffffff16610118565b6101f76108a8565b6040516100ed9190613413565b6101ae6102123660046134a3565b610a9a565b6101ae610225366004613525565b610aae565b6101ae6102383660046135a9565b610e7e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea7210000000000000000000000000000000000000000000000000000000014806102d057507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b63ffffffff82166000908152600560205260408120606091836001811115610300576103006130de565b6001811115610311576103116130de565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561079a57600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff166001811115610384576103846130de565b6001811115610395576103956130de565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916103ed90613666565b80601f016020809104026020016040519081016040528092919081815260200182805461041990613666565b80156104665780601f1061043b57610100808354040283529160200191610466565b820191906000526020600020905b81548152906001019060200180831161044957829003601f168201915b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156104be57602002820191906000526020600020905b8154815260200190600101908083116104aa575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561051657602002820191906000526020600020905b815481526020019060010190808311610502575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156105f057838290600052602060002001805461056390613666565b80601f016020809104026020016040519081016040528092919081815260200182805461058f90613666565b80156105dc5780601f106105b1576101008083540402835291602001916105dc565b820191906000526020600020905b8154815290600101906020018083116105bf57829003601f168201915b505050505081526020019060010190610544565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156106c957838290600052602060002001805461063c90613666565b80601f016020809104026020016040519081016040528092919081815260200182805461066890613666565b80156106b55780601f1061068a576101008083540402835291602001916106b5565b820191906000526020600020905b81548152906001019060200180831161069857829003601f168201915b50505050508152602001906001019061061d565b5050505081526020016006820180546106e190613666565b80601f016020809104026020016040519081016040528092919081815260200182805461070d90613666565b801561075a5780601f1061072f5761010080835404028352916020019161075a565b820191906000526020600020905b81548152906001019060200180831161073d57829003601f168201915b505050919092525050508152600782015467ffffffffffffffff16602080830191909152600890920154604090910152908252600192909201910161033f565b50505050905092915050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461082c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b606060006108b66003610f3f565b905060006108c46003610f53565b67ffffffffffffffff8111156108dc576108dc6136b9565b60405190808252806020026020018201604052801561091557816020015b610902612d50565b8152602001906001900390816108fa5790505b50905060005b8251811015610a93576000838281518110610938576109386136e8565b60209081029190910181015160408051808201825267ffffffffffffffff8316808252600090815260028552829020825181546080818802830181019095526060820181815295975092958601949093919284928491908401828280156109be57602002820191906000526020600020905b8154815260200190600101908083116109aa575b5050509183525050600182015460ff1660208201526002820180546040909201916109e890613666565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1490613666565b8015610a615780601f10610a3657610100808354040283529160200191610a61565b820191906000526020600020905b815481529060010190602001808311610a4457829003601f168201915b505050505081525050815250838381518110610a7f57610a7f6136e8565b60209081029190910101525060010161091b565b5092915050565b610aa2610f5d565b610aab81610fe0565b50565b610ab6610f5d565b60005b83811015610c9c57610afd858583818110610ad657610ad66136e8565b9050602002016020810190610aeb9190613717565b60039067ffffffffffffffff166110d5565b610b6757848482818110610b1357610b136136e8565b9050602002016020810190610b289190613717565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610823565b60026000868684818110610b7d57610b7d6136e8565b9050602002016020810190610b929190613717565b67ffffffffffffffff1681526020810191909152604001600090812090610bb98282612d98565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610bf1600283016000612db6565b5050610c2f858583818110610c0857610c086136e8565b9050602002016020810190610c1d9190613717565b60039067ffffffffffffffff166110ed565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110610c6357610c636136e8565b9050602002016020810190610c789190613717565b60405167ffffffffffffffff909116815260200160405180910390a1600101610ab9565b5060005b81811015610e77576000838383818110610cbc57610cbc6136e8565b9050602002810190610cce9190613732565b610cdc906020810190613770565b610ce590613972565b80519091506000858585818110610cfe57610cfe6136e8565b9050602002810190610d109190613732565b610d1e906020810190613717565b905060005b8251811015610d5657610d4e838281518110610d4157610d416136e8565b60200260200101516110f9565b600101610d23565b50826020015160ff16600003610d98576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120845180518693610dc8928492910190612df0565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560408201516002820190610e159082613a59565b50610e2f91506003905067ffffffffffffffff8316611212565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e08184604051610e61929190613b73565b60405180910390a1505050806001019050610ca0565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610eed576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610efb84860186613c1e565b9050600080610f098361121e565b8151919350915015610f2157610f2184600084611477565b805115610f3457610f3484600183611477565b505050505050505050565b60606000610f4c83611c58565b9392505050565b60006102d0825490565b60005473ffffffffffffffffffffffffffffffffffffffff163314610fde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610823565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361105f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610823565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515610f4c565b6000610f4c8383611cb4565b6040517f50c946fe000000000000000000000000000000000000000000000000000000008152600481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906350c946fe90602401600060405180830381865afa158015611187573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111cd9190810190613e8f565b608081015190915061120e576040517f8907a4fa00000000000000000000000000000000000000000000000000000000815260048101839052602401610823565b5050565b6000610f4c8383611da7565b606080600460ff1683511115611260576040517f8854586400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160028082526060820190925290816020015b6112e46040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161127657505060408051600280825260608201909252919350602082015b61137c6040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161130e57905050905060008060005b855181101561146a5760008682815181106113b4576113b46136e8565b60200260200101516000015160018111156113d1576113d16130de565b0361141e578581815181106113e8576113e86136e8565b6020026020010151858481518110611402576114026136e8565b60200260200101819052508261141790613f96565b9250611462565b858181518110611430576114306136e8565b602002602001015184838151811061144a5761144a6136e8565b60200260200101819052508161145f90613f96565b91505b600101611397565b5090835281529092909150565b63ffffffff831660009081526005602052604081208184600181111561149f5761149f6130de565b60018111156114b0576114b06130de565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561193957600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff166001811115611523576115236130de565b6001811115611534576115346130de565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a010000000000000000000090910416606082015260018201805460809092019161158c90613666565b80601f01602080910402602001604051908101604052809291908181526020018280546115b890613666565b80156116055780601f106115da57610100808354040283529160200191611605565b820191906000526020600020905b8154815290600101906020018083116115e857829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561165d57602002820191906000526020600020905b815481526020019060010190808311611649575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156116b557602002820191906000526020600020905b8154815260200190600101908083116116a1575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b8282101561178f57838290600052602060002001805461170290613666565b80601f016020809104026020016040519081016040528092919081815260200182805461172e90613666565b801561177b5780601f106117505761010080835404028352916020019161177b565b820191906000526020600020905b81548152906001019060200180831161175e57829003601f168201915b5050505050815260200190600101906116e3565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156118685783829060005260206000200180546117db90613666565b80601f016020809104026020016040519081016040528092919081815260200182805461180790613666565b80156118545780601f1061182957610100808354040283529160200191611854565b820191906000526020600020905b81548152906001019060200180831161183757829003601f168201915b5050505050815260200190600101906117bc565b50505050815260200160068201805461188090613666565b80601f01602080910402602001604051908101604052809291908181526020018280546118ac90613666565b80156118f95780601f106118ce576101008083540402835291602001916118f9565b820191906000526020600020905b8154815290600101906020018083116118dc57829003601f168201915b505050919092525050508152600782015467ffffffffffffffff1660208083019190915260089092015460409091015290825260019290920191016114de565b505050509050600061194b8251611df6565b905060006119598451611df6565b90506119658282611e48565b60006119748785878686611f04565b905061198084826122f0565b63ffffffff87166000908152600560205260408120908760018111156119a8576119a86130de565b60018111156119b9576119b96130de565b815260200190815260200160002060006119d39190612e3b565b60005b8151811015611c4e5763ffffffff8816600090815260056020526040812090886001811115611a0757611a076130de565b6001811115611a1857611a186130de565b8152602001908152602001600020828281518110611a3857611a386136e8565b6020908102919091018101518254600181810185556000948552929093208151805160099095029091018054929490939192849283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908381811115611aa257611aa26130de565b021790555060208201518154604084015160608501517fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90921661010067ffffffffffffffff948516027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1617690100000000000000000060ff90921691909102177fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a0100000000000000000000929091169190910217815560808201516001820190611b719082613a59565b5060a08201518051611b8d916002840191602090910190612df0565b5060c08201518051611ba9916003840191602090910190612df0565b5060e08201518051611bc5916004840191602090910190612e5c565b506101008201518051611be2916005840191602090910190612e5c565b506101208201516006820190611bf89082613a59565b50505060208201516007820180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9092169190911790556040909101516008909101556001016119d6565b5050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611ca857602002820191906000526020600020905b815481526020019060010190808311611c94575b50505050509050919050565b60008181526001830160205260408120548015611d9d576000611cd8600183613fce565b8554909150600090611cec90600190613fce565b9050818114611d51576000866000018281548110611d0c57611d0c6136e8565b9060005260206000200154905080876000018481548110611d2f57611d2f6136e8565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611d6257611d62613fe1565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506102d0565b60009150506102d0565b6000818152600183016020526040812054611dee575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556102d0565b5060006102d0565b60006002821115611e36576040517f3e47852600000000000000000000000000000000000000000000000000000000815260048101839052602401610823565b8160028111156102d0576102d06130de565b6000826002811115611e5c57611e5c6130de565b826002811115611e6e57611e6e6130de565b611e789190614010565b90508060011480611ec45750807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff148015611ec457506002836002811115611ec257611ec26130de565b145b15611ece57505050565b82826040517f0a6b675b000000000000000000000000000000000000000000000000000000008152600401610823929190614040565b60606000845167ffffffffffffffff811115611f2257611f226136b9565b604051908082528060200260200182016040528015611f4b578160200160208202803683370190505b5090506000846002811115611f6257611f626130de565b148015611f8057506001836002811115611f7e57611f7e6130de565b145b15611fc157600181600081518110611f9a57611f9a6136e8565b602002602001019067ffffffffffffffff16908167ffffffffffffffff1681525050612129565b6001846002811115611fd557611fd56130de565b148015611ff357506002836002811115611ff157611ff16130de565b145b1561208a578560008151811061200b5761200b6136e8565b6020026020010151602001518160008151811061202a5761202a6136e8565b602002602001019067ffffffffffffffff16908167ffffffffffffffff16815250508560008151811061205f5761205f6136e8565b6020026020010151602001516001612077919061405b565b81600181518110611f9a57611f9a6136e8565b600284600281111561209e5761209e6130de565b1480156120bc575060018360028111156120ba576120ba6130de565b145b156120f357856001815181106120d4576120d46136e8565b60200260200101516020015181600081518110611f9a57611f9a6136e8565b83836040517f0a6b675b000000000000000000000000000000000000000000000000000000008152600401610823929190614040565b6000855167ffffffffffffffff811115612145576121456136b9565b6040519080825280602002602001820160405280156121fb57816020015b604080516101a081018252600060608083018281526080840183905260a0840183905260c0840183905260e084018290526101008401829052610120840182905261014084018290526101608401829052610180840191909152825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816121635790505b50905060005b82518110156122e45761222c87828151811061221f5761221f6136e8565b602002602001015161266f565b6040518060600160405280888381518110612249576122496136e8565b60200260200101518152602001848381518110612268576122686136e8565b602002602001015167ffffffffffffffff1681526020016122bc8b868581518110612295576122956136e8565b60200260200101518b86815181106122af576122af6136e8565b6020026020010151612a75565b8152508282815181106122d1576122d16136e8565b6020908102919091010152600101612201565b50979650505050505050565b81518151811580156123025750806001145b156123a4578260008151811061231a5761231a6136e8565b60200260200101516020015167ffffffffffffffff1660011461239e578260008151811061234a5761234a6136e8565b60209081029190910181015101516040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260016024820152604401610823565b50505050565b8160011480156123b45750806002145b1561256a57836000815181106123cc576123cc6136e8565b602002602001015160400151836000815181106123eb576123eb6136e8565b60200260200101516040015114612477578260008151811061240f5761240f6136e8565b6020026020010151604001518460008151811061242e5761242e6136e8565b6020026020010151604001516040517fc7ccdd7f000000000000000000000000000000000000000000000000000000008152600401610823929190918252602082015260400190565b8360008151811061248a5761248a6136e8565b60200260200101516020015160016124a2919061405b565b67ffffffffffffffff16836001815181106124bf576124bf6136e8565b60200260200101516020015167ffffffffffffffff161461239e57826001815181106124ed576124ed6136e8565b6020026020010151602001518460008151811061250c5761250c6136e8565b6020026020010151602001516001612524919061405b565b6040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff928316600482015291166024820152604401610823565b81600214801561257a5750806001145b1561263d5783600181518110612592576125926136e8565b602002602001015160400151836000815181106125b1576125b16136e8565b6020026020010151604001511461239e57826000815181106125d5576125d56136e8565b602002602001015160400151846001815181106125f4576125f46136e8565b6020026020010151604001516040517f9e975670000000000000000000000000000000000000000000000000000000008152600401610823929190918252602082015260400190565b6040517f1f1b2bb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015167ffffffffffffffff166000036126b7576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815160018111156126cc576126cc6130de565b141580156126ed57506001815160018111156126ea576126ea6130de565b14155b15612724576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806080015151600003612763576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015161277e9060039067ffffffffffffffff166110d5565b6127c65760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610823565b60e081015151601f1015612806576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010081015151601f1015612847576040517f645960ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015167ffffffffffffffff166000908152600290915260408120600101546128779060ff16600361407c565b612882906001614098565b60ff169050808261010001515110156128d957610100820151516040517f548dd21f000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610823565b816040015160ff1660000361291a576040517f39d1a4d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604082015161292a90600361407c565b60ff168260e00151511161296a576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160e00151518260c001515114158061298e5750816101000151518260c001515114155b156129e95760c08201515160e083015151610100840151516040517fba900f6d000000000000000000000000000000000000000000000000000000008152600481019390935260248301919091526044820152606401610823565b8160c00151518260a00151511115612a2d576040517f8473d80700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a3f8260a001518360c00151612b4a565b60005b8260e0015151811015612a7057612a688360c001518281518110610d4157610d416136e8565b600101612a42565b505050565b60008082602001518584600001518560800151878760a001518860c001518960e001518a61010001518b604001518c606001518d6101200151604051602001612ac99c9b9a999897969594939291906140b1565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0a000000000000000000000000000000000000000000000000000000000000179150509392505050565b81511580612b5757508051155b15612b8e576040517fe249684100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b9782612cc5565b612ba081612cc5565b6000805b835182108015612bb45750825181105b15612c8657828181518110612bcb57612bcb6136e8565b6020026020010151848381518110612be557612be56136e8565b60200260200101511115612c0357612bfc81613f96565b9050612ba4565b828181518110612c1557612c156136e8565b6020026020010151848381518110612c2f57612c2f6136e8565b602002602001015103612c5057612c4582613f96565b9150612bfc81613f96565b83836040517fd671700c000000000000000000000000000000000000000000000000000000008152600401610823929190614191565b835182101561239e5783836040517fd671700c000000000000000000000000000000000000000000000000000000008152600401610823929190614191565b60015b815181101561120e5781612cdd600183613fce565b81518110612ced57612ced6136e8565b6020026020010151828281518110612d0757612d076136e8565b602002602001015111612d4857816040517f1bc41b4200000000000000000000000000000000000000000000000000000000815260040161082391906141b6565b600101612cc8565b6040518060400160405280600067ffffffffffffffff168152602001612d93604051806060016040528060608152602001600060ff168152602001606081525090565b905290565b5080546000825590600052602060002090810190610aab9190612eae565b508054612dc290613666565b6000825580601f10612dd2575050565b601f016020900490600052602060002090810190610aab9190612eae565b828054828255906000526020600020908101928215612e2b579160200282015b82811115612e2b578251825591602001919060010190612e10565b50612e37929150612eae565b5090565b5080546000825560090290600052602060002090810190610aab9190612ec3565b828054828255906000526020600020908101928215612ea2579160200282015b82811115612ea25782518290612e929082613a59565b5091602001919060010190612e7c565b50612e37929150612f84565b5b80821115612e375760008155600101612eaf565b80821115612e375780547fffffffffffffffffffffffffffff00000000000000000000000000000000000016815560008181612f026001830182612db6565b612f10600283016000612d98565b612f1e600383016000612d98565b612f2c600483016000612fa1565b612f3a600583016000612fa1565b612f48600683016000612db6565b5050506007810180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560006008820155600901612ec3565b80821115612e37576000612f988282612db6565b50600101612f84565b5080546000825590600052602060002090810190610aab9190612f84565b600060208284031215612fd157600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f4c57600080fd5b6000815180845260005b818110156130275760208185018101518683018201520161300b565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610f4c6020830184613001565b63ffffffff81168114610aab57600080fd5b803561309581613078565b919050565b80356002811061309557600080fd5b600080604083850312156130bc57600080fd5b82356130c781613078565b91506130d56020840161309a565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6002811061311d5761311d6130de565b9052565b60008151808452602080850194506020840160005b8381101561315257815187529582019590820190600101613136565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b848110156131c8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189526131b6838351613001565b9884019892509083019060010161317c565b5090979650505050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b838110156133a4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0898403018552815160608151818652613243828701825161310d565b89810151608061325e8189018367ffffffffffffffff169052565b8a830151915060a0613274818a018460ff169052565b938301519360c092506132928984018667ffffffffffffffff169052565b818401519450610140915060e082818b01526132b26101a08b0187613001565b95508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0610100818c890301818d01526132f18885613121565b97508587015195506101209350818c890301848d01526133118887613121565b9750828701519550818c890301858d015261332c888761315d565b975080870151955050808b8803016101608c015261334a878661315d565b9650828601519550808b8803016101808c0152505050505061336c8282613001565b915050888201516133888a87018267ffffffffffffffff169052565b50908701519387019390935293860193908601906001016131fe565b509098975050505050505050565b6000602082840312156133c457600080fd5b8135610f4c81613078565b60008151606084526133e46060850182613121565b905060ff60208401511660208501526040830151848203604086015261340a8282613001565b95945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b838110156133a4578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff168452870151878401879052613490878501826133cf565b958801959350509086019060010161343c565b6000602082840312156134b557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f4c57600080fd5b60008083601f8401126134eb57600080fd5b50813567ffffffffffffffff81111561350357600080fd5b6020830191508360208260051b850101111561351e57600080fd5b9250929050565b6000806000806040858703121561353b57600080fd5b843567ffffffffffffffff8082111561355357600080fd5b61355f888389016134d9565b9096509450602087013591508082111561357857600080fd5b50613585878288016134d9565b95989497509550505050565b803567ffffffffffffffff8116811461309557600080fd5b600080600080600080608087890312156135c257600080fd5b863567ffffffffffffffff808211156135da57600080fd5b6135e68a838b016134d9565b909850965060208901359150808211156135ff57600080fd5b818901915089601f83011261361357600080fd5b81358181111561362257600080fd5b8a602082850101111561363457600080fd5b60208301965080955050505061364c60408801613591565b915061365a6060880161308a565b90509295509295509295565b600181811c9082168061367a57607f821691505b6020821081036136b3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561372957600080fd5b610f4c82613591565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261376657600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261376657600080fd5b604051610140810167ffffffffffffffff811182821017156137c8576137c86136b9565b60405290565b60405160e0810167ffffffffffffffff811182821017156137c8576137c86136b9565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613838576138386136b9565b604052919050565b600067ffffffffffffffff82111561385a5761385a6136b9565b5060051b60200190565b600082601f83011261387557600080fd5b8135602061388a61388583613840565b6137f1565b8083825260208201915060208460051b8701019350868411156138ac57600080fd5b602086015b848110156138c857803583529183019183016138b1565b509695505050505050565b803560ff8116811461309557600080fd5b600082601f8301126138f557600080fd5b813567ffffffffffffffff81111561390f5761390f6136b9565b61394060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016137f1565b81815284602083860101111561395557600080fd5b816020850160208301376000918101602001919091529392505050565b60006060823603121561398457600080fd5b6040516060810167ffffffffffffffff82821081831117156139a8576139a86136b9565b8160405284359150808211156139bd57600080fd5b6139c936838701613864565b83526139d7602086016138d3565b602084015260408501359150808211156139f057600080fd5b506139fd368286016138e4565b60408301525092915050565b601f821115612a70576000816000526020600020601f850160051c81016020861015613a325750805b601f850160051c820191505b81811015613a5157828155600101613a3e565b505050505050565b815167ffffffffffffffff811115613a7357613a736136b9565b613a8781613a818454613666565b84613a09565b602080601f831160018114613ada5760008415613aa45750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613a51565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613b2757888601518255948401946001909101908401613b08565b5085821015613b6357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83168152604060208201526000613b9660408301846133cf565b949350505050565b600082601f830112613baf57600080fd5b81356020613bbf61388583613840565b82815260059290921b84018101918181019086841115613bde57600080fd5b8286015b848110156138c857803567ffffffffffffffff811115613c025760008081fd5b613c108986838b01016138e4565b845250918301918301613be2565b60006020808385031215613c3157600080fd5b823567ffffffffffffffff80821115613c4957600080fd5b818501915085601f830112613c5d57600080fd5b8135613c6b61388582613840565b81815260059190911b83018401908481019088831115613c8a57600080fd5b8585015b83811015613e1857803585811115613ca557600080fd5b8601610140818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215613cda57600080fd5b613ce26137a4565b613ced89830161309a565b8152613cfb60408301613591565b89820152613d0b606083016138d3565b6040820152613d1c60808301613591565b606082015260a082013587811115613d3357600080fd5b613d418d8b838601016138e4565b60808301525060c082013587811115613d5957600080fd5b613d678d8b83860101613864565b60a08301525060e082013587811115613d7f57600080fd5b613d8d8d8b83860101613864565b60c0830152506101008083013588811115613da757600080fd5b613db58e8c83870101613b9e565b60e0840152506101208084013589811115613dcf57600080fd5b613ddd8f8d83880101613b9e565b8385015250610140840135915088821115613df757600080fd5b613e058e8c848701016138e4565b9083015250845250918601918601613c8e565b5098975050505050505050565b805161309581613078565b600082601f830112613e4157600080fd5b81516020613e5161388583613840565b8083825260208201915060208460051b870101935086841115613e7357600080fd5b602086015b848110156138c85780518352918301918301613e78565b600060208284031215613ea157600080fd5b815167ffffffffffffffff80821115613eb957600080fd5b9083019060e08286031215613ecd57600080fd5b613ed56137ce565b613ede83613e25565b8152613eec60208401613e25565b6020820152613efd60408401613e25565b6040820152606083015160608201526080830151608082015260a083015182811115613f2857600080fd5b613f3487828601613e30565b60a08301525060c083015182811115613f4c57600080fd5b613f5887828601613e30565b60c08301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fc757613fc7613f67565b5060010190565b818103818111156102d0576102d0613f67565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8181036000831280158383131683831282161715610a9357610a93613f67565b6003811061311d5761311d6130de565b6040810161404e8285614030565b610f4c6020830184614030565b67ffffffffffffffff818116838216019080821115610a9357610a93613f67565b60ff8181168382160290811690818114610a9357610a93613f67565b60ff81811683821601908111156102d0576102d0613f67565b67ffffffffffffffff8d16815263ffffffff8c1660208201526140d7604082018c61310d565b610180606082015260006140ef61018083018c613001565b67ffffffffffffffff8b16608084015282810360a0840152614111818b613121565b905082810360c0840152614125818a613121565b905082810360e0840152614139818961315d565b905082810361010084015261414e818861315d565b60ff8716610120850152905067ffffffffffffffff851661014084015282810361016084015261417e8185613001565b9f9e505050505050505050505050505050565b6040815260006141a46040830185613121565b828103602084015261340a8185613121565b602081526000610f4c602083018461312156fea164736f6c6343000818000a", } var CCIPConfigABI = CCIPConfigMetaData.ABI @@ -245,6 +245,28 @@ func (_CCIPConfig *CCIPConfigCallerSession) GetCapabilityConfiguration(arg0 uint return _CCIPConfig.Contract.GetCapabilityConfiguration(&_CCIPConfig.CallOpts, arg0) } +func (_CCIPConfig *CCIPConfigCaller) GetCapabilityRegistry(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _CCIPConfig.contract.Call(opts, &out, "getCapabilityRegistry") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_CCIPConfig *CCIPConfigSession) GetCapabilityRegistry() (common.Address, error) { + return _CCIPConfig.Contract.GetCapabilityRegistry(&_CCIPConfig.CallOpts) +} + +func (_CCIPConfig *CCIPConfigCallerSession) GetCapabilityRegistry() (common.Address, error) { + return _CCIPConfig.Contract.GetCapabilityRegistry(&_CCIPConfig.CallOpts) +} + func (_CCIPConfig *CCIPConfigCaller) GetOCRConfig(opts *bind.CallOpts, donId uint32, pluginType uint8) ([]CCIPConfigTypesOCR3ConfigWithMeta, error) { var out []interface{} err := _CCIPConfig.contract.Call(opts, &out, "getOCRConfig", donId, pluginType) @@ -1051,6 +1073,8 @@ type CCIPConfigInterface interface { GetCapabilityConfiguration(opts *bind.CallOpts, arg0 uint32) ([]byte, error) + GetCapabilityRegistry(opts *bind.CallOpts) (common.Address, error) + GetOCRConfig(opts *bind.CallOpts, donId uint32, pluginType uint8) ([]CCIPConfigTypesOCR3ConfigWithMeta, error) Owner(opts *bind.CallOpts) (common.Address, error) diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go index e8c07cb93d..7b6971d5ec 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go @@ -84,7 +84,7 @@ type InternalRampTokenAmount struct { } var EVM2EVMMultiOnRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Bin: "0x6101006040523480156200001257600080fd5b5060405162003161380380620031618339810160408190526200003591620003db565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf816200017a565b505082516001600160401b031615905080620000e6575060208201516001600160a01b0316155b80620000fd575060408201516001600160a01b0316155b8062000114575060608201516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b81516001600160401b031660805260208201516001600160a01b0390811660a0526040830151811660c05260608301511660e052620001728162000225565b5050620004d1565b336001600160a01b03821603620001d45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60208101516001600160a01b031615806200024b575060608101516001600160a01b0316155b156200026a576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b0393841617909155602080840180516003805485169186169190911790556040808601805160048054871691881691909117905560608088018051600580549098169089161790965582516080808201855280516001600160401b031680835260a080518b16848a0190815260c080518d16868a0190815260e080518f169789019788528a5195865292518e169b85019b909b5299518c169783019790975292518a169381019390935289518916908301529351871693810193909352518516928201929092529151909216918101919091527f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32906101000160405180910390a150565b604051608081016001600160401b0381118282101715620003b857634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b0381168114620003d657600080fd5b919050565b600080828403610100811215620003f157600080fd5b60808112156200040057600080fd5b6200040a62000387565b84516001600160401b03811681146200042257600080fd5b81526200043260208601620003be565b60208201526200044560408601620003be565b60408201526200045860608601620003be565b606082015292506080607f19820112156200047257600080fd5b506200047d62000387565b6200048b60808501620003be565b81526200049b60a08501620003be565b6020820152620004ae60c08501620003be565b6040820152620004c160e08501620003be565b6060820152809150509250929050565b60805160a05160c05160e051612c176200054a600039600081816101c00152818161081b015261147901526000818161018401528181610d3801526114520152600081816101480152818161044e015261142801526000818161011801528181610c55015281816110ee01526113fb0152612c176000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806379ba50971161008c578063a6f3ab6c11610066578063a6f3ab6c14610391578063df0aa9e9146103a4578063f2fde38b146103b7578063fbca3b74146103ca57600080fd5b806379ba50971461033f5780638da5cb5b146103475780639041be3d1461036557600080fd5b80633a019940116100bd5780633a0199401461027d57806348a98aa4146102875780637437ff9f146102bf57600080fd5b806306285c69146100e4578063181f5a771461021357806320487ded1461025c575b600080fd5b6101fd60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161020a9190611cf8565b60405180910390f35b61024f6040518060400160405280601c81526020017f45564d3245564d4d756c74694f6e52616d7020312e362e302d6465760000000081525081565b60405161020a9190611dbd565b61026f61026a366004611dfe565b6103ea565b60405190815260200161020a565b6102856105a3565b005b61029a610295366004611e70565b6107d3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161020a565b610332604080516080810182526000808252602082018190529181018290526060810191909152506040805160808101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454811692820192909252600554909116606082015290565b60405161020a9190611ea9565b610285610888565b60005473ffffffffffffffffffffffffffffffffffffffff1661029a565b610378610373366004611ef2565b610985565b60405167ffffffffffffffff909116815260200161020a565b61028561039f366004611fc6565b6109ae565b61026f6103b236600461204b565b6109c2565b6102856103c53660046120b7565b6111a2565b6103dd6103d8366004611ef2565b6111b3565b60405161020a91906120d4565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa158015610495573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b9919061213e565b15610501576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6003546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd90610559908690869060040161226d565b602060405180830381865afa158015610576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a91906123b6565b90505b92915050565b600354604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610612573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261065891908101906123cf565b60055490915073ffffffffffffffffffffffffffffffffffffffff1660005b82518110156107ce57600083828151811061069457610694612481565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561070f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073391906123b6565b905080156107c45761075c73ffffffffffffffffffffffffffffffffffffffff831685836111e7565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e836040516107bb91815260200190565b60405180910390a35b5050600101610677565b505050565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610864573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a91906124b0565b60015473ffffffffffffffffffffffffffffffffffffffff163314610909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016104f8565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff808216600090815260066020526040812054909161059d911660016124fc565b6109b6611274565b6109bf816112f7565b50565b600073ffffffffffffffffffffffffffffffffffffffff8216610a11576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025473ffffffffffffffffffffffffffffffffffffffff163314610a62576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60045473ffffffffffffffffffffffffffffffffffffffff168015610b08576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610ad5908990899060040161226d565b600060405180830381600087803b158015610aef57600080fd5b505af1158015610b03573d6000803e3d6000fd5b505050505b6003546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a610b3e60808c0160608d016120b7565b8a610b4c60808e018e612524565b6040518663ffffffff1660e01b8152600401610b6c959493929190612589565b600060405180830381865afa158015610b89573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610bcf9190810190612651565b91945092509050610be66080890160608a016120b7565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f84604051610c2d91815260200190565b60405180910390a2604080516101a0810182526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528d8116610140850181905283526006602052938220805492948493610160850192918791610caa91166126a8565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200186610daa576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015610d81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da591906126cf565b610dad565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a8060200190610deb9190612524565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610e2f8b80612524565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610e7660808c018c612524565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610ec060808c0160608d016120b7565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190610ef191906126ec565b905067ffffffffffffffff811115610f0b57610f0b611f0f565b604051908082528060200260200182016040528015610f6757816020015b610f546040518060800160405280606081526020016060815260200160608152602001600081525090565b815260200190600190039081610f295790505b509052905060005b610f7c60408b018b6126ec565b905081101561102b57611002610f9560408c018c6126ec565b83818110610fa557610fa5612481565b905060400201803603810190610fbb9190612754565b8c610fc68d80612524565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92506114dc915050565b8260e00151828151811061101857611018612481565b6020908102919091010152600101610f6f565b5060035460e082015173ffffffffffffffffffffffffffffffffffffffff9091169063cc88924c908c9061106260408e018e6126ec565b6040518563ffffffff1660e01b81526004016110819493929190612850565b60006040518083038186803b15801561109957600080fd5b505afa1580156110ad573d6000803e3d6000fd5b505050506080808201839052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908c166060820152309181019190915261114a90829060a001604051602081830303815290604052805190602001206117e6565b81515260405167ffffffffffffffff8b16907f0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab2990611189908490612886565b60405180910390a251519450505050505b949350505050565b6111aa611274565b6109bf816118e6565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526107ce9084906119db565b60005473ffffffffffffffffffffffffffffffffffffffff1633146112f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104f8565b565b602081015173ffffffffffffffffffffffffffffffffffffffff1615806113365750606081015173ffffffffffffffffffffffffffffffffffffffff16155b1561136d576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480548516918616919091179055606080860151600580549095169086161790935580516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008516928101929092527f00000000000000000000000000000000000000000000000000000000000000008416828201527f00000000000000000000000000000000000000000000000000000000000000009093169181019190915290517f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32916114d19184906129d4565b60405180910390a150565b6115076040518060800160405280606081526020016060815260200160608152602001600081525090565b8460200151600003611545576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006115558587600001516107d3565b905073ffffffffffffffffffffffffffffffffffffffff8116158061162557506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156115ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611623919061213e565b155b156116775785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016104f8565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b81526004016117169190612a73565b6000604051808303816000875af1158015611735573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261177b9190810190612ae9565b604080516080810190915273ffffffffffffffffffffffffffffffffffffffff841660a08201529091508060c0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c0015160405160200161182896959493929190612b7a565b604051602081830303815290604052805190602001208560400151805190602001208660e0015160405160200161185f9190612bdb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611965576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104f8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611a3d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611ae79092919063ffffffff16565b8051909150156107ce5780806020019051810190611a5b919061213e565b6107ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016104f8565b6060611af68484600085611b00565b90505b9392505050565b606082471015611b92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016104f8565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbb9190612bee565b60006040518083038185875af1925050503d8060008114611bf8576040519150601f19603f3d011682016040523d82523d6000602084013e611bfd565b606091505b5091509150611c0e87838387611c19565b979650505050505050565b60608315611caf578251600003611ca85773ffffffffffffffffffffffffffffffffffffffff85163b611ca8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104f8565b508161119a565b61119a8383815115611cc45781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190611dbd565b6080810161059d828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b83811015611d6a578181015183820152602001611d52565b50506000910152565b60008151808452611d8b816020860160208601611d4f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061059a6020830184611d73565b67ffffffffffffffff811681146109bf57600080fd5b600060a08284031215611df857600080fd5b50919050565b60008060408385031215611e1157600080fd5b8235611e1c81611dd0565b9150602083013567ffffffffffffffff811115611e3857600080fd5b611e4485828601611de6565b9150509250929050565b73ffffffffffffffffffffffffffffffffffffffff811681146109bf57600080fd5b60008060408385031215611e8357600080fd5b8235611e8e81611dd0565b91506020830135611e9e81611e4e565b809150509250929050565b6080810161059d8284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260408083015182169084015260609182015116910152565b600060208284031215611f0457600080fd5b8135611af981611dd0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611f6157611f61611f0f565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611fae57611fae611f0f565b604052919050565b8035611fc181611e4e565b919050565b600060808284031215611fd857600080fd5b6040516080810181811067ffffffffffffffff82111715611ffb57611ffb611f0f565b604052823561200981611e4e565b8152602083013561201981611e4e565b6020820152604083013561202c81611e4e565b6040820152606083013561203f81611e4e565b60608201529392505050565b6000806000806080858703121561206157600080fd5b843561206c81611dd0565b9350602085013567ffffffffffffffff81111561208857600080fd5b61209487828801611de6565b9350506040850135915060608501356120ac81611e4e565b939692955090935050565b6000602082840312156120c957600080fd5b8135611af981611e4e565b6020808252825182820181905260009190848201906040850190845b8181101561212257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016120f0565b50909695505050505050565b80518015158114611fc157600080fd5b60006020828403121561215057600080fd5b61059a8261212e565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261218e57600080fd5b830160208101925035905067ffffffffffffffff8111156121ae57600080fd5b8036038213156121bd57600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b8581101561226257813561223081611e4e565b73ffffffffffffffffffffffffffffffffffffffff16875281830135838801526040968701969091019060010161221d565b509495945050505050565b600067ffffffffffffffff80851683526040602084015261228e8485612159565b60a060408601526122a360e0860182846121c4565b9150506122b36020860186612159565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808785030160608801526122e98483856121c4565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe188360301831261232257600080fd5b6020928801928301923591508482111561233b57600080fd5b8160061b360383131561234d57600080fd5b8087850301608088015261236284838561220d565b945061237060608901611fb6565b73ffffffffffffffffffffffffffffffffffffffff811660a0890152935061239b6080890189612159565b94509250808786030160c08801525050611c0e8383836121c4565b6000602082840312156123c857600080fd5b5051919050565b600060208083850312156123e257600080fd5b825167ffffffffffffffff808211156123fa57600080fd5b818501915085601f83011261240e57600080fd5b81518181111561242057612420611f0f565b8060051b9150612431848301611f67565b818152918301840191848101908884111561244b57600080fd5b938501935b83851015612475578451925061246583611e4e565b8282529385019390850190612450565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156124c257600080fd5b8151611af981611e4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561251d5761251d6124cd565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261255957600080fd5b83018035915067ffffffffffffffff82111561257457600080fd5b6020019150368190038213156121bd57600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152608060608201526000611c0e6080830184866121c4565b600082601f8301126125e057600080fd5b815167ffffffffffffffff8111156125fa576125fa611f0f565b61262b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611f67565b81815284602083860101111561264057600080fd5b61119a826020830160208701611d4f565b60008060006060848603121561266657600080fd5b835192506126766020850161212e565b9150604084015167ffffffffffffffff81111561269257600080fd5b61269e868287016125cf565b9150509250925092565b600067ffffffffffffffff8083168181036126c5576126c56124cd565b6001019392505050565b6000602082840312156126e157600080fd5b8151611af981611dd0565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261272157600080fd5b83018035915067ffffffffffffffff82111561273c57600080fd5b6020019150600681901b36038213156121bd57600080fd5b60006040828403121561276657600080fd5b61276e611f3e565b823561277981611e4e565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b84811015612843577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189528151608081518186526127ef82870182611d73565b91505085820151858203878701526128078282611d73565b915050604080830151868303828801526128218382611d73565b60609485015197909401969096525050988401989250908301906001016127ab565b5090979650505050505050565b67ffffffffffffffff85168152606060208201526000612873606083018661278e565b8281036040840152611c0e81858761220d565b602081526128d760208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b6000602083015161290060c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e085015261291d6101a0850183611d73565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808685030161010087015261295a8483611d73565b93506080870151915080868503016101208701526129788483611d73565b935060a087015191506129a461014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e08701519150808685030183870152506129ca838261278e565b9695505050505050565b6101008101612a2c828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a08401526040840151811660c084015260608401511660e0830152611af9565b602081526000825160a06020840152612a8f60c0840182611d73565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600060208284031215612afb57600080fd5b815167ffffffffffffffff80821115612b1357600080fd5b9083019060408286031215612b2757600080fd5b612b2f611f3e565b825182811115612b3e57600080fd5b612b4a878286016125cf565b825250602083015182811115612b5f57600080fd5b612b6b878286016125cf565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c06020840152612baa60c0840189611d73565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b60208152600061059a602083018461278e565b60008251612c00818460208701611d4f565b919091019291505056fea164736f6c6343000818000a", } @@ -460,123 +460,6 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) WithdrawFeeToken return _EVM2EVMMultiOnRamp.Contract.WithdrawFeeTokens(&_EVM2EVMMultiOnRamp.TransactOpts) } -type EVM2EVMMultiOnRampAdminSetIterator struct { - Event *EVM2EVMMultiOnRampAdminSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *EVM2EVMMultiOnRampAdminSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampAdminSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampAdminSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *EVM2EVMMultiOnRampAdminSetIterator) Error() error { - return it.fail -} - -func (it *EVM2EVMMultiOnRampAdminSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type EVM2EVMMultiOnRampAdminSet struct { - NewAdmin common.Address - Raw types.Log -} - -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMMultiOnRampAdminSetIterator, error) { - - logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "AdminSet") - if err != nil { - return nil, err - } - return &EVM2EVMMultiOnRampAdminSetIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "AdminSet", logs: logs, sub: sub}, nil -} - -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampAdminSet) (event.Subscription, error) { - - logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "AdminSet") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(EVM2EVMMultiOnRampAdminSet) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseAdminSet(log types.Log) (*EVM2EVMMultiOnRampAdminSet, error) { - event := new(EVM2EVMMultiOnRampAdminSet) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "AdminSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - type EVM2EVMMultiOnRampCCIPSendRequestedIterator struct { Event *EVM2EVMMultiOnRampCCIPSendRequested @@ -1362,8 +1245,6 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseOwnershipTransferred func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _EVM2EVMMultiOnRamp.abi.Events["AdminSet"].ID: - return _EVM2EVMMultiOnRamp.ParseAdminSet(log) case _EVM2EVMMultiOnRamp.abi.Events["CCIPSendRequested"].ID: return _EVM2EVMMultiOnRamp.ParseCCIPSendRequested(log) case _EVM2EVMMultiOnRamp.abi.Events["ConfigSet"].ID: @@ -1382,10 +1263,6 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRamp) ParseLog(log types.Log) (generate } } -func (EVM2EVMMultiOnRampAdminSet) Topic() common.Hash { - return common.HexToHash("0x8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c") -} - func (EVM2EVMMultiOnRampCCIPSendRequested) Topic() common.Hash { return common.HexToHash("0x0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab29") } @@ -1441,12 +1318,6 @@ type EVM2EVMMultiOnRampInterface interface { WithdrawFeeTokens(opts *bind.TransactOpts) (*types.Transaction, error) - FilterAdminSet(opts *bind.FilterOpts) (*EVM2EVMMultiOnRampAdminSetIterator, error) - - WatchAdminSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampAdminSet) (event.Subscription, error) - - ParseAdminSet(log types.Log) (*EVM2EVMMultiOnRampAdminSet, error) - FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*EVM2EVMMultiOnRampCCIPSendRequestedIterator, error) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) diff --git a/core/gethwrappers/ccip/generated/price_registry/price_registry.go b/core/gethwrappers/ccip/generated/price_registry/price_registry.go index a93faaf82c..6f04601fcb 100644 --- a/core/gethwrappers/ccip/generated/price_registry/price_registry.go +++ b/core/gethwrappers/ccip/generated/price_registry/price_registry.go @@ -146,8 +146,8 @@ type PriceRegistryTokenTransferFeeConfigSingleTokenArgs struct { } var PriceRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"validatePoolReturnData\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b506040516200695038038062006950833981016040819052620000349162001816565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a9f565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b6b565b5050505050505062001ad4565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001935565b60209081029190910101519050620002f560028262000ea4565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001935565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000ec4565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001935565b6020026020010151600c62000ec460201b90919060201c565b1562000499578281815181106200045b576200045b62001935565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001935565b6020026020010151600c62000ea460201b90919060201c565b156200053b57818181518110620004fd57620004fd62001935565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001935565b6020908102919091018101518051818301516001600160a01b0380831660008181526006875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001935565b6020026020010151905060008383815181106200065f576200065f62001935565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061018081015163ffffffff16155b80620006ba57506102008101516001600160e01b031916630a04b54b60e21b14155b80620006d75750602063ffffffff1681610160015163ffffffff16105b80620006f75750806060015163ffffffff1681610180015163ffffffff16115b15620007225760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260086020526040812060010154600160a81b900460e01b6001600160e01b0319169003620007a257816001600160401b03167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516200079491906200194b565b60405180910390a2620007e6565b816001600160401b03167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad9382604051620007dd91906200194b565b60405180910390a25b8060086000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a8154816001600160401b0302191690836001600160401b031602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000ac35762000ac362001935565b6020026020010151600001519050600083838151811062000ae85762000ae862001935565b6020908102919091018101518101516001600160a01b03841660008181526007845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000aa2565b60005b825181101562000dde57600083828151811062000b8f5762000b8f62001935565b6020026020010151905060008160000151905060005b82602001515181101562000dcf5760008360200151828151811062000bce5762000bce62001935565b602002602001015160200151905060008460200151838151811062000bf75762000bf762001935565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c565760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b03841660008181526009602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000dbc908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000ba5565b50505080600101905062000b6e565b5060005b81518110156200054457600082828151811062000e035762000e0362001935565b6020026020010151600001519050600083838151811062000e285762000e2862001935565b6020908102919091018101518101516001600160401b03841660008181526009845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000de2565b600062000ebb836001600160a01b03841662000edb565b90505b92915050565b600062000ebb836001600160a01b03841662000fdf565b6000818152600183016020526040812054801562000fd457600062000f0260018362001a9c565b855490915060009062000f189060019062001a9c565b905081811462000f8457600086600001828154811062000f3c5762000f3c62001935565b906000526020600020015490508087600001848154811062000f625762000f6262001935565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f985762000f9862001abe565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000ebe565b600091505062000ebe565b6000818152600183016020526040812054620010285750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000ebe565b50600062000ebe565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200106c576200106c62001031565b60405290565b60405160c081016001600160401b03811182821017156200106c576200106c62001031565b60405161022081016001600160401b03811182821017156200106c576200106c62001031565b604051601f8201601f191681016001600160401b0381118282101715620010e857620010e862001031565b604052919050565b80516001600160a01b03811681146200110857600080fd5b919050565b805163ffffffff811681146200110857600080fd5b6000606082840312156200113557600080fd5b604051606081016001600160401b03811182821017156200115a576200115a62001031565b604052825190915081906001600160601b03811681146200117a57600080fd5b81526200118a60208401620010f0565b60208201526200119d604084016200110d565b60408201525092915050565b60006001600160401b03821115620011c557620011c562001031565b5060051b60200190565b600082601f830112620011e157600080fd5b81516020620011fa620011f483620011a9565b620010bd565b8083825260208201915060208460051b8701019350868411156200121d57600080fd5b602086015b8481101562001244576200123681620010f0565b835291830191830162001222565b509695505050505050565b600082601f8301126200126157600080fd5b8151602062001274620011f483620011a9565b828152606092830285018201928282019190878511156200129457600080fd5b8387015b85811015620013275780890382811215620012b35760008081fd5b620012bd62001047565b620012c883620010f0565b8152604080601f1984011215620012df5760008081fd5b620012e962001047565b9250620012f8888501620010f0565b835283015160ff811681146200130e5760008081fd5b8288015280870191909152845292840192810162001298565b5090979650505050505050565b80516001600160401b03811681146200110857600080fd5b805161ffff811681146200110857600080fd5b805180151581146200110857600080fd5b600082601f8301126200138257600080fd5b8151602062001395620011f483620011a9565b82815260059290921b84018101918181019086841115620013b557600080fd5b8286015b84811015620012445780516001600160401b0380821115620013da57600080fd5b908801906040601f19838c038101821315620013f557600080fd5b620013ff62001047565b6200140c89860162001334565b815282850151848111156200142057600080fd5b8086019550508c603f8601126200143657600080fd5b8885015193506200144b620011f485620011a9565b84815260e09094028501830193898101908e8611156200146a57600080fd5b958401955b858710156200154357868f0360e08112156200148a57600080fd5b6200149462001047565b6200149f89620010f0565b815260c08683011215620014b257600080fd5b620014bc62001072565b9150620014cb8d8a016200110d565b8252620014da878a016200110d565b8d830152620014ec60608a016200134c565b87830152620014fe60808a016200110d565b60608301526200151160a08a016200110d565b60808301526200152460c08a016200135f565b60a0830152808d0191909152825260e09690960195908a01906200146f565b828b015250875250505092840192508301620013b9565b600082601f8301126200156c57600080fd5b815160206200157f620011f483620011a9565b82815260069290921b840181019181810190868411156200159f57600080fd5b8286015b84811015620012445760408189031215620015be5760008081fd5b620015c862001047565b620015d382620010f0565b8152620015e285830162001334565b81860152835291830191604001620015a3565b80516001600160e01b0319811681146200110857600080fd5b600082601f8301126200162057600080fd5b8151602062001633620011f483620011a9565b82815261024092830285018201928282019190878511156200165457600080fd5b8387015b85811015620013275780890382811215620016735760008081fd5b6200167d62001047565b620016888362001334565b815261022080601f1984011215620016a05760008081fd5b620016aa62001097565b9250620016b98885016200135f565b83526040620016ca8186016200134c565b898501526060620016dd8187016200110d565b8286015260809150620016f28287016200110d565b9085015260a0620017058682016200110d565b8286015260c091506200171a8287016200134c565b9085015260e06200172d8682016200110d565b828601526101009150620017438287016200134c565b90850152610120620017578682016200134c565b8286015261014091506200176d8287016200134c565b90850152610160620017818682016200110d565b828601526101809150620017978287016200110d565b908501526101a0620017ab8682016200110d565b828601526101c09150620017c182870162001334565b908501526101e0620017d58682016200110d565b828601526102009150620017eb8287016200135f565b90850152620017fc858301620015f5565b908401525080870191909152845292840192810162001658565b6000806000806000806000610120888a0312156200183357600080fd5b6200183f898962001122565b60608901519097506001600160401b03808211156200185d57600080fd5b6200186b8b838c01620011cf565b975060808a01519150808211156200188257600080fd5b620018908b838c01620011cf565b965060a08a0151915080821115620018a757600080fd5b620018b58b838c016200124f565b955060c08a0151915080821115620018cc57600080fd5b620018da8b838c0162001370565b945060e08a0151915080821115620018f157600080fd5b620018ff8b838c016200155a565b93506101008a01519150808211156200191757600080fd5b50620019268a828b016200160e565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610220810160208301516200196c602084018261ffff169052565b50604083015162001985604084018263ffffffff169052565b5060608301516200199e606084018263ffffffff169052565b506080830151620019b7608084018263ffffffff169052565b5060a0830151620019ce60a084018261ffff169052565b5060c0830151620019e760c084018263ffffffff169052565b5060e0830151620019fe60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a0808501516001600160401b0316908401526101c080850151909116908301526101e080840151151590830152610200928301516001600160e01b031916929091019190915290565b8181038181111562000ebe57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051614e2262001b2e600039600081816102d901528181611ad30152611b3c01526000818161029d0152818161104e01526110ae015260008181610269015281816110d701526111470152614e226000f3fe608060405234801561001057600080fd5b50600436106101b85760003560e01c80637afac322116100f9578063cc88924c11610097578063d8694ccd11610071578063d8694ccd14610a5c578063f2fde38b14610a6f578063f700042a14610a82578063ffdb4b3714610a9557600080fd5b8063cc88924c14610a2e578063cdc73d5114610a41578063d02641a014610a4957600080fd5b806391a2749a116100d357806391a2749a14610939578063a69c64c01461094c578063bf78e03f1461095f578063c4276bfc14610a0c57600080fd5b80637afac3221461078e57806382b49eb0146107a15780638da5cb5b1461091157600080fd5b8063407e108611610166578063514e8cff11610140578063514e8cff146104385780636def4ce7146104db578063770e2dc41461077357806379ba50971461078657600080fd5b8063407e1086146103c557806345ac924d146103d85780634ab35b0b146103f857600080fd5b8063181f5a7711610197578063181f5a77146103525780632451a6271461039b5780633937306f146103b057600080fd5b806241e5be146101bd578063061877e3146101e357806306285c691461023c575b600080fd5b6101d06101cb36600461380f565b610add565b6040519081526020015b60405180910390f35b6102236101f136600461384b565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101da565b610306604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101da565b61038e6040518060400160405280601781526020017f5072696365526567697374727920312e362e302d64657600000000000000000081525081565b6040516101da91906138ca565b6103a3610b4b565b6040516101da91906138dd565b6103c36103be366004613937565b610b5c565b005b6103c36103d3366004613a93565b610e11565b6103eb6103e6366004613bf1565b610e25565b6040516101da9190613c33565b61040b61040636600461384b565b610ef0565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6104ce610446366004613cc6565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600460209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101da9190613ce1565b6107666104e9366004613cc6565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081018290526102008101919091525067ffffffffffffffff908116600090815260086020908152604091829020825161022081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a0850152710100000000000000000000000000000000008304871660c08501527501000000000000000000000000000000000000000000808404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b010000000000000000000000000000000000000000000000000000009092048616610140840152600190930154808616610160840152640100000000810486166101808401526801000000000000000081049096166101a083015270010000000000000000000000000000000086049094166101c082015274010000000000000000000000000000000000000000850490911615156101e08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b1661020082015290565b6040516101da9190613d1c565b6103c3610781366004613f59565b610efb565b6103c3610f11565b6103c361079c366004614273565b611013565b6108b16107af3660046142d7565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff91909116600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101da9190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6103c3610947366004614301565b611025565b6103c361095a366004614392565b611036565b6109d861096d36600461384b565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526006825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101da565b610a1f610a1a366004614457565b611047565b6040516101da939291906144f2565b6103c3610a3c36600461451c565b611245565b6103a361141b565b6104ce610a5736600461384b565b611427565b6101d0610a6a3660046145b7565b611523565b6103c3610a7d36600461384b565b6119dd565b6103c3610a9036600461463c565b6119ee565b610aa8610aa336600461485c565b6119ff565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101da565b6000610ae882611b8a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b0f85611b8a565b610b37907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16856148b5565b610b4191906148cc565b90505b9392505050565b6060610b576002611c24565b905090565b610b64611c31565b6000610b708280614907565b9050905060005b81811015610cba576000610b8b8480614907565b83818110610b9b57610b9b61496f565b905060400201803603810190610bb191906149ca565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a92610ca99290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610b77565b506000610cca6020840184614907565b9050905060005b81811015610e0b576000610ce86020860186614907565b83818110610cf857610cf861496f565b905060400201803603810190610d0e9190614a07565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600490975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e92610dfa9290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610cd1565b50505050565b610e19611c76565b610e2281611cf7565b50565b60608160008167ffffffffffffffff811115610e4357610e43613972565b604051908082528060200260200182016040528015610e8857816020015b6040805180820190915260008082526020820152815260200190600190039081610e615790505b50905060005b82811015610ee557610ec0868683818110610eab57610eab61496f565b9050602002016020810190610a57919061384b565b828281518110610ed257610ed261496f565b6020908102919091010152600101610e8e565b509150505b92915050565b6000610eea82611b8a565b610f03611c76565b610f0d8282611df5565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61101b611c76565b610f0d8282612207565b61102d611c76565b610e228161234e565b61103e611c76565b610e22816124da565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036110a7578592506110d5565b6110d287877f0000000000000000000000000000000000000000000000000000000000000000610add565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611174576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610f8e565b67ffffffffffffffff8816600090815260086020526040812060010154640100000000900463ffffffff16906111ab8787846125c4565b9050806020015193508484611232836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b67ffffffffffffffff85166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b905b8481101561141257600084848381811061129c5761129c61496f565b6112b2926020604090920201908101915061384b565b905060008787848181106112c8576112c861496f565b90506020028101906112da9190614a2a565b6112e8906040810190614a68565b91505060208111156113985767ffffffffffffffff8916600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115611398576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610f8e565b611408848989868181106113ae576113ae61496f565b90506020028101906113c09190614a2a565b6113ce906020810190614a68565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061276d92505050565b5050600101611280565b50505050505050565b6060610b57600c611c24565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600660209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff16908201529061151a57505073ffffffffffffffffffffffffffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b44816127bf565b67ffffffffffffffff8083166000908152600860209081526040808320815161022081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a0860152710100000000000000000000000000000000008404871660c08601527501000000000000000000000000000000000000000000808504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b010000000000000000000000000000000000000000000000000000009093048616610140850152600190940154808616610160850152640100000000810486166101808501526801000000000000000081049098166101a084015270010000000000000000000000000000000088049094166101c083015274010000000000000000000000000000000000000000870490931615156101e08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b16610200840152909190611759576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b60006117686040850185614907565b91506117c490508261177d6020870187614a68565b90508361178a8880614a68565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a0292505050565b60006007816117d9608088016060890161384b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff169150806118286118226080890160608a0161384b565b896119ff565b909250905060008080861561186e57611862888c61184c60808e0160608f0161384b565b888e806040019061185d9190614907565b612aac565b9194509250905061188e565b6101c088015161188b9063ffffffff16662386f26fc100006148b5565b92505b61010088015160009061ffff16156118d2576118cf896dffffffffffffffffffffffffffff607088901c166118c660208f018f614a68565b90508b86612d8a565b90505b6101a089015160009067ffffffffffffffff166118fb6118f560808f018f614a68565b8d612e3a565b600001518563ffffffff168c60a0015161ffff168f806020019061191f9190614a68565b61192a9291506148b5565b8d6080015163ffffffff1661193f9190614acd565b6119499190614acd565b6119539190614acd565b61196d906dffffffffffffffffffffffffffff89166148b5565b61197791906148b5565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff871682826119ae67ffffffffffffffff8c16896148b5565b6119b89190614acd565b6119c29190614acd565b6119cc91906148cc565b9d9c50505050505050505050505050565b6119e5611c76565b610e2281612efb565b6119f6611c76565b610e2281612ff0565b67ffffffffffffffff811660009081526004602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203611ab7576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b6000816020015163ffffffff1642611acf9190614ae0565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115611b70576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610f8e565b611b7986611b8a565b9151919350909150505b9250929050565b600080611b9683611427565b9050806020015163ffffffff1660001480611bce575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15611c1d576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610f8e565b5192915050565b60606000610b44836134de565b611c3c60023361353a565b611c74576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610f8e565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314611c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610f8e565b60005b8151811015610f0d576000828281518110611d1757611d1761496f565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526006875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a2505050806001019050611cfa565b60005b825181101561211e576000838281518110611e1557611e1561496f565b6020026020010151905060008160000151905060005b82602001515181101561211057600083602001518281518110611e5057611e5061496f565b6020026020010151602001519050600084602001518381518110611e7657611e7661496f565b6020026020010151600001519050602063ffffffff16826080015163ffffffff161015611ef95760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610f8e565b67ffffffffffffffff8416600081815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906120fe908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101611e2b565b505050806001019050611df8565b5060005b815181101561220257600082828151811061213f5761213f61496f565b602002602001015160000151905060008383815181106121615761216161496f565b60209081029190910181015181015167ffffffffffffffff8416600081815260098452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612122565b505050565b60005b82518110156122aa576122408382815181106122285761222861496f565b6020026020010151600c61356990919063ffffffff16565b156122a2578281815181106122575761225761496f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010161220a565b5060005b8151811015612202576122e48282815181106122cc576122cc61496f565b6020026020010151600c61358b90919063ffffffff16565b15612346578181815181106122fb576122fb61496f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6001016122ae565b602081015160005b81518110156123e95760008282815181106123735761237361496f565b6020026020010151905061239181600261358b90919063ffffffff16565b156123e05760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612356565b50815160005b8151811015610e0b57600082828151811061240c5761240c61496f565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361247c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612487600282613569565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016123ef565b60005b8151811015610f0d5760008282815181106124fa576124fa61496f565b6020026020010151600001519050600083838151811061251c5761251c61496f565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526007845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a250506001016124dd565b6040805180820190915260008082526020820152600083900361260557506040805180820190915267ffffffffffffffff8216815260006020820152610b44565b60006126118486614af3565b905060006126228560048189614b39565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f000000000000000000000000000000000000000000000000000000000016126bf57808060200190518101906126b69190614b63565b92505050610b44565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161273b576040518060400160405280828060200190518101906127279190614b8f565b815260006020909101529250610b44915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610f0d57612202816135ad565b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284d9190614bc2565b505050915050600081121561288e576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000819050600085602001518473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129099190614c12565b6129139190614c2f565b905060248160ff1611156129485761292c602482614c48565b61293790600a614d81565b61294190836148cc565b915061296b565b612953816024614c48565b61295e90600a614d81565b61296890836148b5565b91505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8211156129c1576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff42166020820152949350505050565b836040015163ffffffff16831115612a5b5760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610f8e565b836020015161ffff16821115612a9d576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e0b8461020001518261276d565b6000808083815b81811015612d7c576000878783818110612acf57612acf61496f565b905060400201803603810190612ae59190614d90565b67ffffffffffffffff8c166000908152600960209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090612c0b576101208d0151612bd29061ffff16662386f26fc100006148b5565b612bdc9088614acd565b96508c610140015186612bef9190614dc9565b95508c610160015185612c029190614dc9565b94505050612d74565b604081015160009061ffff1615612cc45760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614612c67578351612c6090611b8a565b9050612c6a565b508a5b620186a0836040015161ffff16612cac8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661366090919063ffffffff16565b612cb691906148b5565b612cc091906148cc565b9150505b6060820151612cd39088614dc9565b9650816080015186612ce59190614dc9565b8251909650600090612d049063ffffffff16662386f26fc100006148b5565b905080821015612d2357612d18818a614acd565b985050505050612d74565b6000836020015163ffffffff16662386f26fc10000612d4291906148b5565b905080831115612d6257612d56818b614acd565b99505050505050612d74565b612d6c838b614acd565b995050505050505b600101612ab3565b505096509650969350505050565b60008063ffffffff8316612da0610140866148b5565b612dac876101c0614acd565b612db69190614acd565b612dc09190614acd565b905060008760c0015163ffffffff168860e0015161ffff1683612de391906148b5565b612ded9190614acd565b61010089015190915061ffff16612e146dffffffffffffffffffffffffffff8916836148b5565b612e1e91906148b5565b612e2e90655af3107a40006148b5565b98975050505050505050565b60408051808201909152600080825260208201526000612e66858585610180015163ffffffff166125c4565b9050826060015163ffffffff1681600001511115612eb0576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101e001518015612ec457508060200151155b15610b41576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610f8e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b8151811015610f0d5760008282815181106130105761301061496f565b60200260200101519050600083838151811061302e5761302e61496f565b60200260200101516000015190506000826020015190508167ffffffffffffffff1660001480613067575061018081015163ffffffff16155b806130b957506102008101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130d55750602063ffffffff1681610160015163ffffffff16105b806130f45750806060015163ffffffff1681610180015163ffffffff16115b15613137576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610f8e565b67ffffffffffffffff82166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131df578167ffffffffffffffff167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516131d29190613d1c565b60405180910390a2613222565b8167ffffffffffffffff167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad93826040516132199190613d1c565b60405180910390a25b80600860008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612ff3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561352e57602002820191906000526020600020905b81548152602001906001019080831161351a575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b44565b6000610b448373ffffffffffffffffffffffffffffffffffffffff841661369d565b6000610b448373ffffffffffffffffffffffffffffffffffffffff84166136ec565b600081516020146135ec57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e91906138ca565b6000828060200190518101906136029190614b8f565b905073ffffffffffffffffffffffffffffffffffffffff811180613627575061040081105b15610eea57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e91906138ca565b6000670de0b6b3a7640000613693837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166148b5565b610b4491906148cc565b60008181526001830160205260408120546136e457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610eea565b506000610eea565b600081815260018301602052604081205480156137d5576000613710600183614ae0565b855490915060009061372490600190614ae0565b90508181146137895760008660000182815481106137445761374461496f565b90600052602060002001549050808760000184815481106137675761376761496f565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061379a5761379a614de6565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610eea565b6000915050610eea565b5092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461380a57600080fd5b919050565b60008060006060848603121561382457600080fd5b61382d846137e6565b925060208401359150613842604085016137e6565b90509250925092565b60006020828403121561385d57600080fd5b610b44826137e6565b6000815180845260005b8181101561388c57602081850181015186830182015201613870565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b446020830184613866565b6020808252825182820181905260009190848201906040850190845b8181101561392b57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016138f9565b50909695505050505050565b60006020828403121561394957600080fd5b813567ffffffffffffffff81111561396057600080fd5b820160408185031215610b4457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156139c4576139c4613972565b60405290565b60405160c0810167ffffffffffffffff811182821017156139c4576139c4613972565b604051610220810167ffffffffffffffff811182821017156139c4576139c4613972565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613a5857613a58613972565b604052919050565b600067ffffffffffffffff821115613a7a57613a7a613972565b5060051b60200190565b60ff81168114610e2257600080fd5b60006020808385031215613aa657600080fd5b823567ffffffffffffffff811115613abd57600080fd5b8301601f81018513613ace57600080fd5b8035613ae1613adc82613a60565b613a11565b81815260609182028301840191848201919088841115613b0057600080fd5b938501935b83851015613ba05784890381811215613b1e5760008081fd5b613b266139a1565b613b2f876137e6565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084011215613b635760008081fd5b613b6b6139a1565b9250613b788989016137e6565b8352870135613b8681613a84565b828901528088019190915283529384019391850191613b05565b50979650505050505050565b60008083601f840112613bbe57600080fd5b50813567ffffffffffffffff811115613bd657600080fd5b6020830191508360208260051b8501011115611b8357600080fd5b60008060208385031215613c0457600080fd5b823567ffffffffffffffff811115613c1b57600080fd5b613c2785828601613bac565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b82811015613ca157613c9184835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101613c50565b5091979650505050505050565b803567ffffffffffffffff8116811461380a57600080fd5b600060208284031215613cd857600080fd5b610b4482613cae565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff169082015260408101610eea565b81511515815261022081016020830151613d3c602084018261ffff169052565b506040830151613d54604084018263ffffffff169052565b506060830151613d6c606084018263ffffffff169052565b506080830151613d84608084018263ffffffff169052565b5060a0830151613d9a60a084018261ffff169052565b5060c0830151613db260c084018263ffffffff169052565b5060e0830151613dc860e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a08085015167ffffffffffffffff16908401526101c080850151909116908301526101e080840151151590830152610200808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461380a57600080fd5b803561ffff8116811461380a57600080fd5b8015158114610e2257600080fd5b803561380a81613ea8565b600082601f830112613ed257600080fd5b81356020613ee2613adc83613a60565b82815260069290921b84018101918181019086841115613f0157600080fd5b8286015b84811015613f4e5760408189031215613f1e5760008081fd5b613f266139a1565b613f2f82613cae565b8152613f3c8583016137e6565b81860152835291830191604001613f05565b509695505050505050565b60008060408385031215613f6c57600080fd5b67ffffffffffffffff83351115613f8257600080fd5b83601f843585010112613f9457600080fd5b613fa4613adc8435850135613a60565b8335840180358083526020808401939260059290921b90910101861015613fca57600080fd5b602085358601015b85358601803560051b016020018110156141d75767ffffffffffffffff81351115613ffc57600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a0301121561403557600080fd5b61403d6139a1565b61404960208301613cae565b815267ffffffffffffffff6040830135111561406457600080fd5b88603f60408401358401011261407957600080fd5b61408f613adc6020604085013585010135613a60565b6020604084810135850182810135808552928401939260e00201018b10156140b657600080fd5b6040808501358501015b6040858101358601602081013560e00201018110156141b85760e0818d0312156140e957600080fd5b6140f16139a1565b6140fa826137e6565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f0301121561412e57600080fd5b6141366139ca565b61414260208401613e82565b815261415060408401613e82565b602082015261416160608401613e96565b604082015261417260808401613e82565b606082015261418360a08401613e82565b608082015261419560c0840135613ea8565b60c083013560a0820152602082810191909152908452929092019160e0016140c0565b5080602084015250508085525050602083019250602081019050613fd2565b5092505067ffffffffffffffff602084013511156141f457600080fd5b6142048460208501358501613ec1565b90509250929050565b600082601f83011261421e57600080fd5b8135602061422e613adc83613a60565b8083825260208201915060208460051b87010193508684111561425057600080fd5b602086015b84811015613f4e57614266816137e6565b8352918301918301614255565b6000806040838503121561428657600080fd5b823567ffffffffffffffff8082111561429e57600080fd5b6142aa8683870161420d565b935060208501359150808211156142c057600080fd5b506142cd8582860161420d565b9150509250929050565b600080604083850312156142ea57600080fd5b6142f383613cae565b9150614204602084016137e6565b60006020828403121561431357600080fd5b813567ffffffffffffffff8082111561432b57600080fd5b908301906040828603121561433f57600080fd5b6143476139a1565b82358281111561435657600080fd5b6143628782860161420d565b82525060208301358281111561437757600080fd5b6143838782860161420d565b60208301525095945050505050565b600060208083850312156143a557600080fd5b823567ffffffffffffffff8111156143bc57600080fd5b8301601f810185136143cd57600080fd5b80356143db613adc82613a60565b81815260069190911b820183019083810190878311156143fa57600080fd5b928401925b8284101561444c57604084890312156144185760008081fd5b6144206139a1565b614429856137e6565b8152614436868601613cae565b81870152825260409390930192908401906143ff565b979650505050505050565b60008060008060006080868803121561446f57600080fd5b61447886613cae565b9450614486602087016137e6565b935060408601359250606086013567ffffffffffffffff808211156144aa57600080fd5b818801915088601f8301126144be57600080fd5b8135818111156144cd57600080fd5b8960208285010111156144df57600080fd5b9699959850939650602001949392505050565b83815282151560208201526060604082015260006145136060830184613866565b95945050505050565b60008060008060006060868803121561453457600080fd5b61453d86613cae565b9450602086013567ffffffffffffffff8082111561455a57600080fd5b61456689838a01613bac565b9096509450604088013591508082111561457f57600080fd5b818801915088601f83011261459357600080fd5b8135818111156145a257600080fd5b8960208260061b85010111156144df57600080fd5b600080604083850312156145ca57600080fd5b6145d383613cae565b9150602083013567ffffffffffffffff8111156145ef57600080fd5b830160a0818603121561460157600080fd5b809150509250929050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461380a57600080fd5b6000602080838503121561464f57600080fd5b823567ffffffffffffffff81111561466657600080fd5b8301601f8101851361467757600080fd5b8035614685613adc82613a60565b81815261024091820283018401918482019190888411156146a557600080fd5b938501935b83851015613ba057848903818112156146c35760008081fd5b6146cb6139a1565b6146d487613cae565b8152610220807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147095760008081fd5b6147116139ed565b925061471e898901613eb6565b8352604061472d818a01613e96565b8a850152606061473e818b01613e82565b8286015260809150614751828b01613e82565b9085015260a06147628a8201613e82565b8286015260c09150614775828b01613e96565b9085015260e06147868a8201613e82565b82860152610100915061479a828b01613e96565b908501526101206147ac8a8201613e96565b8286015261014091506147c0828b01613e96565b908501526101606147d28a8201613e82565b8286015261018091506147e6828b01613e82565b908501526101a06147f88a8201613e82565b828601526101c0915061480c828b01613cae565b908501526101e061481e8a8201613e82565b828601526102009150614832828b01613eb6565b9085015261484189830161460c565b908401525080880191909152835293840193918501916146aa565b6000806040838503121561486f57600080fd5b614878836137e6565b915061420460208401613cae565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610eea57610eea614886565b600082614902577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261493c57600080fd5b83018035915067ffffffffffffffff82111561495757600080fd5b6020019150600681901b3603821315611b8357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461380a57600080fd5b6000604082840312156149dc57600080fd5b6149e46139a1565b6149ed836137e6565b81526149fb6020840161499e565b60208201529392505050565b600060408284031215614a1957600080fd5b614a216139a1565b6149ed83613cae565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112614a5e57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614a9d57600080fd5b83018035915067ffffffffffffffff821115614ab857600080fd5b602001915036819003821315611b8357600080fd5b80820180821115610eea57610eea614886565b81810381811115610eea57610eea614886565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015613e7a5760049490940360031b84901b1690921692915050565b60008085851115614b4957600080fd5b83861115614b5657600080fd5b5050820193919092039150565b600060408284031215614b7557600080fd5b614b7d6139a1565b8251815260208301516149fb81613ea8565b600060208284031215614ba157600080fd5b5051919050565b805169ffffffffffffffffffff8116811461380a57600080fd5b600080600080600060a08688031215614bda57600080fd5b614be386614ba8565b9450602086015193506040860151925060608601519150614c0660808701614ba8565b90509295509295909350565b600060208284031215614c2457600080fd5b8151610b4481613a84565b60ff8181168382160190811115610eea57610eea614886565b60ff8281168282160390811115610eea57610eea614886565b600181815b80851115614cba57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614ca057614ca0614886565b80851615614cad57918102915b93841c9390800290614c66565b509250929050565b600082614cd157506001610eea565b81614cde57506000610eea565b8160018114614cf45760028114614cfe57614d1a565b6001915050610eea565b60ff841115614d0f57614d0f614886565b50506001821b610eea565b5060208310610133831016604e8410600b8410161715614d3d575081810a610eea565b614d478383614c61565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614d7957614d79614886565b029392505050565b6000610b4460ff841683614cc2565b600060408284031215614da257600080fd5b614daa6139a1565b614db3836137e6565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156137df576137df614886565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"validatePoolReturnData\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b506040516200695038038062006950833981016040819052620000349162001816565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a9f565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b6b565b5050505050505062001ad4565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001935565b60209081029190910101519050620002f560028262000ea4565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001935565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000ec4565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001935565b6020026020010151600a62000ec460201b90919060201c565b1562000499578281815181106200045b576200045b62001935565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001935565b6020026020010151600a62000ea460201b90919060201c565b156200053b57818181518110620004fd57620004fd62001935565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001935565b6020908102919091018101518051818301516001600160a01b0380831660008181526006875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001935565b6020026020010151905060008383815181106200065f576200065f62001935565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061018081015163ffffffff16155b80620006ba57506102008101516001600160e01b031916630a04b54b60e21b14155b80620006d75750602063ffffffff1681610160015163ffffffff16105b80620006f75750806060015163ffffffff1681610180015163ffffffff16115b15620007225760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260086020526040812060010154600160a81b900460e01b6001600160e01b0319169003620007a257816001600160401b03167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516200079491906200194b565b60405180910390a2620007e6565b816001600160401b03167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad9382604051620007dd91906200194b565b60405180910390a25b8060086000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a8154816001600160401b0302191690836001600160401b031602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000ac35762000ac362001935565b6020026020010151600001519050600083838151811062000ae85762000ae862001935565b6020908102919091018101518101516001600160a01b03841660008181526007845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000aa2565b60005b825181101562000dde57600083828151811062000b8f5762000b8f62001935565b6020026020010151905060008160000151905060005b82602001515181101562000dcf5760008360200151828151811062000bce5762000bce62001935565b602002602001015160200151905060008460200151838151811062000bf75762000bf762001935565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c565760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b03841660008181526009602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000dbc908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000ba5565b50505080600101905062000b6e565b5060005b81518110156200054457600082828151811062000e035762000e0362001935565b6020026020010151600001519050600083838151811062000e285762000e2862001935565b6020908102919091018101518101516001600160401b03841660008181526009845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000de2565b600062000ebb836001600160a01b03841662000edb565b90505b92915050565b600062000ebb836001600160a01b03841662000fdf565b6000818152600183016020526040812054801562000fd457600062000f0260018362001a9c565b855490915060009062000f189060019062001a9c565b905081811462000f8457600086600001828154811062000f3c5762000f3c62001935565b906000526020600020015490508087600001848154811062000f625762000f6262001935565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f985762000f9862001abe565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000ebe565b600091505062000ebe565b6000818152600183016020526040812054620010285750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000ebe565b50600062000ebe565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200106c576200106c62001031565b60405290565b60405160c081016001600160401b03811182821017156200106c576200106c62001031565b60405161022081016001600160401b03811182821017156200106c576200106c62001031565b604051601f8201601f191681016001600160401b0381118282101715620010e857620010e862001031565b604052919050565b80516001600160a01b03811681146200110857600080fd5b919050565b805163ffffffff811681146200110857600080fd5b6000606082840312156200113557600080fd5b604051606081016001600160401b03811182821017156200115a576200115a62001031565b604052825190915081906001600160601b03811681146200117a57600080fd5b81526200118a60208401620010f0565b60208201526200119d604084016200110d565b60408201525092915050565b60006001600160401b03821115620011c557620011c562001031565b5060051b60200190565b600082601f830112620011e157600080fd5b81516020620011fa620011f483620011a9565b620010bd565b8083825260208201915060208460051b8701019350868411156200121d57600080fd5b602086015b8481101562001244576200123681620010f0565b835291830191830162001222565b509695505050505050565b600082601f8301126200126157600080fd5b8151602062001274620011f483620011a9565b828152606092830285018201928282019190878511156200129457600080fd5b8387015b85811015620013275780890382811215620012b35760008081fd5b620012bd62001047565b620012c883620010f0565b8152604080601f1984011215620012df5760008081fd5b620012e962001047565b9250620012f8888501620010f0565b835283015160ff811681146200130e5760008081fd5b8288015280870191909152845292840192810162001298565b5090979650505050505050565b80516001600160401b03811681146200110857600080fd5b805161ffff811681146200110857600080fd5b805180151581146200110857600080fd5b600082601f8301126200138257600080fd5b8151602062001395620011f483620011a9565b82815260059290921b84018101918181019086841115620013b557600080fd5b8286015b84811015620012445780516001600160401b0380821115620013da57600080fd5b908801906040601f19838c038101821315620013f557600080fd5b620013ff62001047565b6200140c89860162001334565b815282850151848111156200142057600080fd5b8086019550508c603f8601126200143657600080fd5b8885015193506200144b620011f485620011a9565b84815260e09094028501830193898101908e8611156200146a57600080fd5b958401955b858710156200154357868f0360e08112156200148a57600080fd5b6200149462001047565b6200149f89620010f0565b815260c08683011215620014b257600080fd5b620014bc62001072565b9150620014cb8d8a016200110d565b8252620014da878a016200110d565b8d830152620014ec60608a016200134c565b87830152620014fe60808a016200110d565b60608301526200151160a08a016200110d565b60808301526200152460c08a016200135f565b60a0830152808d0191909152825260e09690960195908a01906200146f565b828b015250875250505092840192508301620013b9565b600082601f8301126200156c57600080fd5b815160206200157f620011f483620011a9565b82815260069290921b840181019181810190868411156200159f57600080fd5b8286015b84811015620012445760408189031215620015be5760008081fd5b620015c862001047565b620015d382620010f0565b8152620015e285830162001334565b81860152835291830191604001620015a3565b80516001600160e01b0319811681146200110857600080fd5b600082601f8301126200162057600080fd5b8151602062001633620011f483620011a9565b82815261024092830285018201928282019190878511156200165457600080fd5b8387015b85811015620013275780890382811215620016735760008081fd5b6200167d62001047565b620016888362001334565b815261022080601f1984011215620016a05760008081fd5b620016aa62001097565b9250620016b98885016200135f565b83526040620016ca8186016200134c565b898501526060620016dd8187016200110d565b8286015260809150620016f28287016200110d565b9085015260a0620017058682016200110d565b8286015260c091506200171a8287016200134c565b9085015260e06200172d8682016200110d565b828601526101009150620017438287016200134c565b90850152610120620017578682016200134c565b8286015261014091506200176d8287016200134c565b90850152610160620017818682016200110d565b828601526101809150620017978287016200110d565b908501526101a0620017ab8682016200110d565b828601526101c09150620017c182870162001334565b908501526101e0620017d58682016200110d565b828601526102009150620017eb8287016200135f565b90850152620017fc858301620015f5565b908401525080870191909152845292840192810162001658565b6000806000806000806000610120888a0312156200183357600080fd5b6200183f898962001122565b60608901519097506001600160401b03808211156200185d57600080fd5b6200186b8b838c01620011cf565b975060808a01519150808211156200188257600080fd5b620018908b838c01620011cf565b965060a08a0151915080821115620018a757600080fd5b620018b58b838c016200124f565b955060c08a0151915080821115620018cc57600080fd5b620018da8b838c0162001370565b945060e08a0151915080821115620018f157600080fd5b620018ff8b838c016200155a565b93506101008a01519150808211156200191757600080fd5b50620019268a828b016200160e565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610220810160208301516200196c602084018261ffff169052565b50604083015162001985604084018263ffffffff169052565b5060608301516200199e606084018263ffffffff169052565b506080830151620019b7608084018263ffffffff169052565b5060a0830151620019ce60a084018261ffff169052565b5060c0830151620019e760c084018263ffffffff169052565b5060e0830151620019fe60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a0808501516001600160401b0316908401526101c080850151909116908301526101e080840151151590830152610200928301516001600160e01b031916929091019190915290565b8181038181111562000ebe57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051614e2262001b2e600039600081816102d901528181611ad30152611b3c01526000818161029d0152818161104e01526110ae015260008181610269015281816110d701526111470152614e226000f3fe608060405234801561001057600080fd5b50600436106101b85760003560e01c80637afac322116100f9578063cc88924c11610097578063d8694ccd11610071578063d8694ccd14610a5c578063f2fde38b14610a6f578063f700042a14610a82578063ffdb4b3714610a9557600080fd5b8063cc88924c14610a2e578063cdc73d5114610a41578063d02641a014610a4957600080fd5b806391a2749a116100d357806391a2749a14610939578063a69c64c01461094c578063bf78e03f1461095f578063c4276bfc14610a0c57600080fd5b80637afac3221461078e57806382b49eb0146107a15780638da5cb5b1461091157600080fd5b8063407e108611610166578063514e8cff11610140578063514e8cff146104385780636def4ce7146104db578063770e2dc41461077357806379ba50971461078657600080fd5b8063407e1086146103c557806345ac924d146103d85780634ab35b0b146103f857600080fd5b8063181f5a7711610197578063181f5a77146103525780632451a6271461039b5780633937306f146103b057600080fd5b806241e5be146101bd578063061877e3146101e357806306285c691461023c575b600080fd5b6101d06101cb36600461380f565b610add565b6040519081526020015b60405180910390f35b6102236101f136600461384b565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101da565b610306604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101da565b61038e6040518060400160405280601781526020017f5072696365526567697374727920312e362e302d64657600000000000000000081525081565b6040516101da91906138ca565b6103a3610b4b565b6040516101da91906138dd565b6103c36103be366004613937565b610b5c565b005b6103c36103d3366004613a93565b610e11565b6103eb6103e6366004613bf1565b610e25565b6040516101da9190613c33565b61040b61040636600461384b565b610ef0565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6104ce610446366004613cc6565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600460209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101da9190613ce1565b6107666104e9366004613cc6565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081018290526102008101919091525067ffffffffffffffff908116600090815260086020908152604091829020825161022081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a0850152710100000000000000000000000000000000008304871660c08501527501000000000000000000000000000000000000000000808404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b010000000000000000000000000000000000000000000000000000009092048616610140840152600190930154808616610160840152640100000000810486166101808401526801000000000000000081049096166101a083015270010000000000000000000000000000000086049094166101c082015274010000000000000000000000000000000000000000850490911615156101e08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b1661020082015290565b6040516101da9190613d1c565b6103c3610781366004613f59565b610efb565b6103c3610f11565b6103c361079c366004614273565b611013565b6108b16107af3660046142d7565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff91909116600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101da9190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6103c3610947366004614301565b611025565b6103c361095a366004614392565b611036565b6109d861096d36600461384b565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526006825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101da565b610a1f610a1a366004614457565b611047565b6040516101da939291906144f2565b6103c3610a3c36600461451c565b611245565b6103a361141b565b6104ce610a5736600461384b565b611427565b6101d0610a6a3660046145b7565b611523565b6103c3610a7d36600461384b565b6119dd565b6103c3610a9036600461463c565b6119ee565b610aa8610aa336600461485c565b6119ff565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101da565b6000610ae882611b8a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b0f85611b8a565b610b37907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16856148b5565b610b4191906148cc565b90505b9392505050565b6060610b576002611c24565b905090565b610b64611c31565b6000610b708280614907565b9050905060005b81811015610cba576000610b8b8480614907565b83818110610b9b57610b9b61496f565b905060400201803603810190610bb191906149ca565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a92610ca99290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610b77565b506000610cca6020840184614907565b9050905060005b81811015610e0b576000610ce86020860186614907565b83818110610cf857610cf861496f565b905060400201803603810190610d0e9190614a07565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600490975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e92610dfa9290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610cd1565b50505050565b610e19611c76565b610e2281611cf7565b50565b60608160008167ffffffffffffffff811115610e4357610e43613972565b604051908082528060200260200182016040528015610e8857816020015b6040805180820190915260008082526020820152815260200190600190039081610e615790505b50905060005b82811015610ee557610ec0868683818110610eab57610eab61496f565b9050602002016020810190610a57919061384b565b828281518110610ed257610ed261496f565b6020908102919091010152600101610e8e565b509150505b92915050565b6000610eea82611b8a565b610f03611c76565b610f0d8282611df5565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61101b611c76565b610f0d8282612207565b61102d611c76565b610e228161234e565b61103e611c76565b610e22816124da565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036110a7578592506110d5565b6110d287877f0000000000000000000000000000000000000000000000000000000000000000610add565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611174576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610f8e565b67ffffffffffffffff8816600090815260086020526040812060010154640100000000900463ffffffff16906111ab8787846125c4565b9050806020015193508484611232836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b67ffffffffffffffff85166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b905b8481101561141257600084848381811061129c5761129c61496f565b6112b2926020604090920201908101915061384b565b905060008787848181106112c8576112c861496f565b90506020028101906112da9190614a2a565b6112e8906040810190614a68565b91505060208111156113985767ffffffffffffffff8916600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115611398576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610f8e565b611408848989868181106113ae576113ae61496f565b90506020028101906113c09190614a2a565b6113ce906020810190614a68565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061276d92505050565b5050600101611280565b50505050505050565b6060610b57600a611c24565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600660209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff16908201529061151a57505073ffffffffffffffffffffffffffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b44816127bf565b67ffffffffffffffff8083166000908152600860209081526040808320815161022081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a0860152710100000000000000000000000000000000008404871660c08601527501000000000000000000000000000000000000000000808504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b010000000000000000000000000000000000000000000000000000009093048616610140850152600190940154808616610160850152640100000000810486166101808501526801000000000000000081049098166101a084015270010000000000000000000000000000000088049094166101c083015274010000000000000000000000000000000000000000870490931615156101e08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b16610200840152909190611759576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b60006117686040850185614907565b91506117c490508261177d6020870187614a68565b90508361178a8880614a68565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a0292505050565b60006007816117d9608088016060890161384b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff169150806118286118226080890160608a0161384b565b896119ff565b909250905060008080861561186e57611862888c61184c60808e0160608f0161384b565b888e806040019061185d9190614907565b612aac565b9194509250905061188e565b6101c088015161188b9063ffffffff16662386f26fc100006148b5565b92505b61010088015160009061ffff16156118d2576118cf896dffffffffffffffffffffffffffff607088901c166118c660208f018f614a68565b90508b86612d8a565b90505b6101a089015160009067ffffffffffffffff166118fb6118f560808f018f614a68565b8d612e3a565b600001518563ffffffff168c60a0015161ffff168f806020019061191f9190614a68565b61192a9291506148b5565b8d6080015163ffffffff1661193f9190614acd565b6119499190614acd565b6119539190614acd565b61196d906dffffffffffffffffffffffffffff89166148b5565b61197791906148b5565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff871682826119ae67ffffffffffffffff8c16896148b5565b6119b89190614acd565b6119c29190614acd565b6119cc91906148cc565b9d9c50505050505050505050505050565b6119e5611c76565b610e2281612efb565b6119f6611c76565b610e2281612ff0565b67ffffffffffffffff811660009081526004602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203611ab7576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b6000816020015163ffffffff1642611acf9190614ae0565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115611b70576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610f8e565b611b7986611b8a565b9151919350909150505b9250929050565b600080611b9683611427565b9050806020015163ffffffff1660001480611bce575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15611c1d576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610f8e565b5192915050565b60606000610b44836134de565b611c3c60023361353a565b611c74576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610f8e565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314611c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610f8e565b60005b8151811015610f0d576000828281518110611d1757611d1761496f565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526006875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a2505050806001019050611cfa565b60005b825181101561211e576000838281518110611e1557611e1561496f565b6020026020010151905060008160000151905060005b82602001515181101561211057600083602001518281518110611e5057611e5061496f565b6020026020010151602001519050600084602001518381518110611e7657611e7661496f565b6020026020010151600001519050602063ffffffff16826080015163ffffffff161015611ef95760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610f8e565b67ffffffffffffffff8416600081815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906120fe908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101611e2b565b505050806001019050611df8565b5060005b815181101561220257600082828151811061213f5761213f61496f565b602002602001015160000151905060008383815181106121615761216161496f565b60209081029190910181015181015167ffffffffffffffff8416600081815260098452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612122565b505050565b60005b82518110156122aa576122408382815181106122285761222861496f565b6020026020010151600a61356990919063ffffffff16565b156122a2578281815181106122575761225761496f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010161220a565b5060005b8151811015612202576122e48282815181106122cc576122cc61496f565b6020026020010151600a61358b90919063ffffffff16565b15612346578181815181106122fb576122fb61496f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6001016122ae565b602081015160005b81518110156123e95760008282815181106123735761237361496f565b6020026020010151905061239181600261358b90919063ffffffff16565b156123e05760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612356565b50815160005b8151811015610e0b57600082828151811061240c5761240c61496f565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361247c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612487600282613569565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016123ef565b60005b8151811015610f0d5760008282815181106124fa576124fa61496f565b6020026020010151600001519050600083838151811061251c5761251c61496f565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526007845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a250506001016124dd565b6040805180820190915260008082526020820152600083900361260557506040805180820190915267ffffffffffffffff8216815260006020820152610b44565b60006126118486614af3565b905060006126228560048189614b39565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f000000000000000000000000000000000000000000000000000000000016126bf57808060200190518101906126b69190614b63565b92505050610b44565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161273b576040518060400160405280828060200190518101906127279190614b8f565b815260006020909101529250610b44915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610f0d57612202816135ad565b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284d9190614bc2565b505050915050600081121561288e576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000819050600085602001518473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129099190614c12565b6129139190614c2f565b905060248160ff1611156129485761292c602482614c48565b61293790600a614d81565b61294190836148cc565b915061296b565b612953816024614c48565b61295e90600a614d81565b61296890836148b5565b91505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8211156129c1576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff42166020820152949350505050565b836040015163ffffffff16831115612a5b5760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610f8e565b836020015161ffff16821115612a9d576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e0b8461020001518261276d565b6000808083815b81811015612d7c576000878783818110612acf57612acf61496f565b905060400201803603810190612ae59190614d90565b67ffffffffffffffff8c166000908152600960209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090612c0b576101208d0151612bd29061ffff16662386f26fc100006148b5565b612bdc9088614acd565b96508c610140015186612bef9190614dc9565b95508c610160015185612c029190614dc9565b94505050612d74565b604081015160009061ffff1615612cc45760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614612c67578351612c6090611b8a565b9050612c6a565b508a5b620186a0836040015161ffff16612cac8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661366090919063ffffffff16565b612cb691906148b5565b612cc091906148cc565b9150505b6060820151612cd39088614dc9565b9650816080015186612ce59190614dc9565b8251909650600090612d049063ffffffff16662386f26fc100006148b5565b905080821015612d2357612d18818a614acd565b985050505050612d74565b6000836020015163ffffffff16662386f26fc10000612d4291906148b5565b905080831115612d6257612d56818b614acd565b99505050505050612d74565b612d6c838b614acd565b995050505050505b600101612ab3565b505096509650969350505050565b60008063ffffffff8316612da0610140866148b5565b612dac876101c0614acd565b612db69190614acd565b612dc09190614acd565b905060008760c0015163ffffffff168860e0015161ffff1683612de391906148b5565b612ded9190614acd565b61010089015190915061ffff16612e146dffffffffffffffffffffffffffff8916836148b5565b612e1e91906148b5565b612e2e90655af3107a40006148b5565b98975050505050505050565b60408051808201909152600080825260208201526000612e66858585610180015163ffffffff166125c4565b9050826060015163ffffffff1681600001511115612eb0576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101e001518015612ec457508060200151155b15610b41576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610f8e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b8151811015610f0d5760008282815181106130105761301061496f565b60200260200101519050600083838151811061302e5761302e61496f565b60200260200101516000015190506000826020015190508167ffffffffffffffff1660001480613067575061018081015163ffffffff16155b806130b957506102008101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130d55750602063ffffffff1681610160015163ffffffff16105b806130f45750806060015163ffffffff1681610180015163ffffffff16115b15613137576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610f8e565b67ffffffffffffffff82166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131df578167ffffffffffffffff167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516131d29190613d1c565b60405180910390a2613222565b8167ffffffffffffffff167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad93826040516132199190613d1c565b60405180910390a25b80600860008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612ff3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561352e57602002820191906000526020600020905b81548152602001906001019080831161351a575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b44565b6000610b448373ffffffffffffffffffffffffffffffffffffffff841661369d565b6000610b448373ffffffffffffffffffffffffffffffffffffffff84166136ec565b600081516020146135ec57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e91906138ca565b6000828060200190518101906136029190614b8f565b905073ffffffffffffffffffffffffffffffffffffffff811180613627575061040081105b15610eea57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e91906138ca565b6000670de0b6b3a7640000613693837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166148b5565b610b4491906148cc565b60008181526001830160205260408120546136e457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610eea565b506000610eea565b600081815260018301602052604081205480156137d5576000613710600183614ae0565b855490915060009061372490600190614ae0565b90508181146137895760008660000182815481106137445761374461496f565b90600052602060002001549050808760000184815481106137675761376761496f565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061379a5761379a614de6565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610eea565b6000915050610eea565b5092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461380a57600080fd5b919050565b60008060006060848603121561382457600080fd5b61382d846137e6565b925060208401359150613842604085016137e6565b90509250925092565b60006020828403121561385d57600080fd5b610b44826137e6565b6000815180845260005b8181101561388c57602081850181015186830182015201613870565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b446020830184613866565b6020808252825182820181905260009190848201906040850190845b8181101561392b57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016138f9565b50909695505050505050565b60006020828403121561394957600080fd5b813567ffffffffffffffff81111561396057600080fd5b820160408185031215610b4457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156139c4576139c4613972565b60405290565b60405160c0810167ffffffffffffffff811182821017156139c4576139c4613972565b604051610220810167ffffffffffffffff811182821017156139c4576139c4613972565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613a5857613a58613972565b604052919050565b600067ffffffffffffffff821115613a7a57613a7a613972565b5060051b60200190565b60ff81168114610e2257600080fd5b60006020808385031215613aa657600080fd5b823567ffffffffffffffff811115613abd57600080fd5b8301601f81018513613ace57600080fd5b8035613ae1613adc82613a60565b613a11565b81815260609182028301840191848201919088841115613b0057600080fd5b938501935b83851015613ba05784890381811215613b1e5760008081fd5b613b266139a1565b613b2f876137e6565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084011215613b635760008081fd5b613b6b6139a1565b9250613b788989016137e6565b8352870135613b8681613a84565b828901528088019190915283529384019391850191613b05565b50979650505050505050565b60008083601f840112613bbe57600080fd5b50813567ffffffffffffffff811115613bd657600080fd5b6020830191508360208260051b8501011115611b8357600080fd5b60008060208385031215613c0457600080fd5b823567ffffffffffffffff811115613c1b57600080fd5b613c2785828601613bac565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b82811015613ca157613c9184835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101613c50565b5091979650505050505050565b803567ffffffffffffffff8116811461380a57600080fd5b600060208284031215613cd857600080fd5b610b4482613cae565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff169082015260408101610eea565b81511515815261022081016020830151613d3c602084018261ffff169052565b506040830151613d54604084018263ffffffff169052565b506060830151613d6c606084018263ffffffff169052565b506080830151613d84608084018263ffffffff169052565b5060a0830151613d9a60a084018261ffff169052565b5060c0830151613db260c084018263ffffffff169052565b5060e0830151613dc860e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a08085015167ffffffffffffffff16908401526101c080850151909116908301526101e080840151151590830152610200808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461380a57600080fd5b803561ffff8116811461380a57600080fd5b8015158114610e2257600080fd5b803561380a81613ea8565b600082601f830112613ed257600080fd5b81356020613ee2613adc83613a60565b82815260069290921b84018101918181019086841115613f0157600080fd5b8286015b84811015613f4e5760408189031215613f1e5760008081fd5b613f266139a1565b613f2f82613cae565b8152613f3c8583016137e6565b81860152835291830191604001613f05565b509695505050505050565b60008060408385031215613f6c57600080fd5b67ffffffffffffffff83351115613f8257600080fd5b83601f843585010112613f9457600080fd5b613fa4613adc8435850135613a60565b8335840180358083526020808401939260059290921b90910101861015613fca57600080fd5b602085358601015b85358601803560051b016020018110156141d75767ffffffffffffffff81351115613ffc57600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a0301121561403557600080fd5b61403d6139a1565b61404960208301613cae565b815267ffffffffffffffff6040830135111561406457600080fd5b88603f60408401358401011261407957600080fd5b61408f613adc6020604085013585010135613a60565b6020604084810135850182810135808552928401939260e00201018b10156140b657600080fd5b6040808501358501015b6040858101358601602081013560e00201018110156141b85760e0818d0312156140e957600080fd5b6140f16139a1565b6140fa826137e6565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f0301121561412e57600080fd5b6141366139ca565b61414260208401613e82565b815261415060408401613e82565b602082015261416160608401613e96565b604082015261417260808401613e82565b606082015261418360a08401613e82565b608082015261419560c0840135613ea8565b60c083013560a0820152602082810191909152908452929092019160e0016140c0565b5080602084015250508085525050602083019250602081019050613fd2565b5092505067ffffffffffffffff602084013511156141f457600080fd5b6142048460208501358501613ec1565b90509250929050565b600082601f83011261421e57600080fd5b8135602061422e613adc83613a60565b8083825260208201915060208460051b87010193508684111561425057600080fd5b602086015b84811015613f4e57614266816137e6565b8352918301918301614255565b6000806040838503121561428657600080fd5b823567ffffffffffffffff8082111561429e57600080fd5b6142aa8683870161420d565b935060208501359150808211156142c057600080fd5b506142cd8582860161420d565b9150509250929050565b600080604083850312156142ea57600080fd5b6142f383613cae565b9150614204602084016137e6565b60006020828403121561431357600080fd5b813567ffffffffffffffff8082111561432b57600080fd5b908301906040828603121561433f57600080fd5b6143476139a1565b82358281111561435657600080fd5b6143628782860161420d565b82525060208301358281111561437757600080fd5b6143838782860161420d565b60208301525095945050505050565b600060208083850312156143a557600080fd5b823567ffffffffffffffff8111156143bc57600080fd5b8301601f810185136143cd57600080fd5b80356143db613adc82613a60565b81815260069190911b820183019083810190878311156143fa57600080fd5b928401925b8284101561444c57604084890312156144185760008081fd5b6144206139a1565b614429856137e6565b8152614436868601613cae565b81870152825260409390930192908401906143ff565b979650505050505050565b60008060008060006080868803121561446f57600080fd5b61447886613cae565b9450614486602087016137e6565b935060408601359250606086013567ffffffffffffffff808211156144aa57600080fd5b818801915088601f8301126144be57600080fd5b8135818111156144cd57600080fd5b8960208285010111156144df57600080fd5b9699959850939650602001949392505050565b83815282151560208201526060604082015260006145136060830184613866565b95945050505050565b60008060008060006060868803121561453457600080fd5b61453d86613cae565b9450602086013567ffffffffffffffff8082111561455a57600080fd5b61456689838a01613bac565b9096509450604088013591508082111561457f57600080fd5b818801915088601f83011261459357600080fd5b8135818111156145a257600080fd5b8960208260061b85010111156144df57600080fd5b600080604083850312156145ca57600080fd5b6145d383613cae565b9150602083013567ffffffffffffffff8111156145ef57600080fd5b830160a0818603121561460157600080fd5b809150509250929050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461380a57600080fd5b6000602080838503121561464f57600080fd5b823567ffffffffffffffff81111561466657600080fd5b8301601f8101851361467757600080fd5b8035614685613adc82613a60565b81815261024091820283018401918482019190888411156146a557600080fd5b938501935b83851015613ba057848903818112156146c35760008081fd5b6146cb6139a1565b6146d487613cae565b8152610220807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147095760008081fd5b6147116139ed565b925061471e898901613eb6565b8352604061472d818a01613e96565b8a850152606061473e818b01613e82565b8286015260809150614751828b01613e82565b9085015260a06147628a8201613e82565b8286015260c09150614775828b01613e96565b9085015260e06147868a8201613e82565b82860152610100915061479a828b01613e96565b908501526101206147ac8a8201613e96565b8286015261014091506147c0828b01613e96565b908501526101606147d28a8201613e82565b8286015261018091506147e6828b01613e82565b908501526101a06147f88a8201613e82565b828601526101c0915061480c828b01613cae565b908501526101e061481e8a8201613e82565b828601526102009150614832828b01613eb6565b9085015261484189830161460c565b908401525080880191909152835293840193918501916146aa565b6000806040838503121561486f57600080fd5b614878836137e6565b915061420460208401613cae565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610eea57610eea614886565b600082614902577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261493c57600080fd5b83018035915067ffffffffffffffff82111561495757600080fd5b6020019150600681901b3603821315611b8357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461380a57600080fd5b6000604082840312156149dc57600080fd5b6149e46139a1565b6149ed836137e6565b81526149fb6020840161499e565b60208201529392505050565b600060408284031215614a1957600080fd5b614a216139a1565b6149ed83613cae565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112614a5e57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614a9d57600080fd5b83018035915067ffffffffffffffff821115614ab857600080fd5b602001915036819003821315611b8357600080fd5b80820180821115610eea57610eea614886565b81810381811115610eea57610eea614886565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015613e7a5760049490940360031b84901b1690921692915050565b60008085851115614b4957600080fd5b83861115614b5657600080fd5b5050820193919092039150565b600060408284031215614b7557600080fd5b614b7d6139a1565b8251815260208301516149fb81613ea8565b600060208284031215614ba157600080fd5b5051919050565b805169ffffffffffffffffffff8116811461380a57600080fd5b600080600080600060a08688031215614bda57600080fd5b614be386614ba8565b9450602086015193506040860151925060608601519150614c0660808701614ba8565b90509295509295909350565b600060208284031215614c2457600080fd5b8151610b4481613a84565b60ff8181168382160190811115610eea57610eea614886565b60ff8281168282160390811115610eea57610eea614886565b600181815b80851115614cba57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614ca057614ca0614886565b80851615614cad57918102915b93841c9390800290614c66565b509250929050565b600082614cd157506001610eea565b81614cde57506000610eea565b8160018114614cf45760028114614cfe57614d1a565b6001915050610eea565b60ff841115614d0f57614d0f614886565b50506001821b610eea565b5060208310610133831016604e8410600b8410161715614d3d575081810a610eea565b614d478383614c61565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614d7957614d79614886565b029392505050565b6000610b4460ff841683614cc2565b600060408284031215614da257600080fd5b614daa6139a1565b614db3836137e6565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156137df576137df614886565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var PriceRegistryABI = PriceRegistryMetaData.ABI @@ -2077,260 +2077,6 @@ func (_PriceRegistry *PriceRegistryFilterer) ParsePriceFeedPerTokenUpdated(log t return event, nil } -type PriceRegistryPriceUpdaterRemovedIterator struct { - Event *PriceRegistryPriceUpdaterRemoved - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *PriceRegistryPriceUpdaterRemovedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(PriceRegistryPriceUpdaterRemoved) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(PriceRegistryPriceUpdaterRemoved) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *PriceRegistryPriceUpdaterRemovedIterator) Error() error { - return it.fail -} - -func (it *PriceRegistryPriceUpdaterRemovedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type PriceRegistryPriceUpdaterRemoved struct { - PriceUpdater common.Address - Raw types.Log -} - -func (_PriceRegistry *PriceRegistryFilterer) FilterPriceUpdaterRemoved(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterRemovedIterator, error) { - - var priceUpdaterRule []interface{} - for _, priceUpdaterItem := range priceUpdater { - priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) - } - - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PriceUpdaterRemoved", priceUpdaterRule) - if err != nil { - return nil, err - } - return &PriceRegistryPriceUpdaterRemovedIterator{contract: _PriceRegistry.contract, event: "PriceUpdaterRemoved", logs: logs, sub: sub}, nil -} - -func (_PriceRegistry *PriceRegistryFilterer) WatchPriceUpdaterRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address) (event.Subscription, error) { - - var priceUpdaterRule []interface{} - for _, priceUpdaterItem := range priceUpdater { - priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) - } - - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PriceUpdaterRemoved", priceUpdaterRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(PriceRegistryPriceUpdaterRemoved) - if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterRemoved", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_PriceRegistry *PriceRegistryFilterer) ParsePriceUpdaterRemoved(log types.Log) (*PriceRegistryPriceUpdaterRemoved, error) { - event := new(PriceRegistryPriceUpdaterRemoved) - if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterRemoved", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type PriceRegistryPriceUpdaterSetIterator struct { - Event *PriceRegistryPriceUpdaterSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *PriceRegistryPriceUpdaterSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(PriceRegistryPriceUpdaterSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(PriceRegistryPriceUpdaterSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *PriceRegistryPriceUpdaterSetIterator) Error() error { - return it.fail -} - -func (it *PriceRegistryPriceUpdaterSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type PriceRegistryPriceUpdaterSet struct { - PriceUpdater common.Address - Raw types.Log -} - -func (_PriceRegistry *PriceRegistryFilterer) FilterPriceUpdaterSet(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterSetIterator, error) { - - var priceUpdaterRule []interface{} - for _, priceUpdaterItem := range priceUpdater { - priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) - } - - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PriceUpdaterSet", priceUpdaterRule) - if err != nil { - return nil, err - } - return &PriceRegistryPriceUpdaterSetIterator{contract: _PriceRegistry.contract, event: "PriceUpdaterSet", logs: logs, sub: sub}, nil -} - -func (_PriceRegistry *PriceRegistryFilterer) WatchPriceUpdaterSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterSet, priceUpdater []common.Address) (event.Subscription, error) { - - var priceUpdaterRule []interface{} - for _, priceUpdaterItem := range priceUpdater { - priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) - } - - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PriceUpdaterSet", priceUpdaterRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(PriceRegistryPriceUpdaterSet) - if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterSet", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_PriceRegistry *PriceRegistryFilterer) ParsePriceUpdaterSet(log types.Log) (*PriceRegistryPriceUpdaterSet, error) { - event := new(PriceRegistryPriceUpdaterSet) - if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - type PriceRegistryTokenTransferFeeConfigDeletedIterator struct { Event *PriceRegistryTokenTransferFeeConfigDeleted @@ -2894,10 +2640,6 @@ func (_PriceRegistry *PriceRegistry) ParseLog(log types.Log) (generated.AbigenLo return _PriceRegistry.ParsePremiumMultiplierWeiPerEthUpdated(log) case _PriceRegistry.abi.Events["PriceFeedPerTokenUpdated"].ID: return _PriceRegistry.ParsePriceFeedPerTokenUpdated(log) - case _PriceRegistry.abi.Events["PriceUpdaterRemoved"].ID: - return _PriceRegistry.ParsePriceUpdaterRemoved(log) - case _PriceRegistry.abi.Events["PriceUpdaterSet"].ID: - return _PriceRegistry.ParsePriceUpdaterSet(log) case _PriceRegistry.abi.Events["TokenTransferFeeConfigDeleted"].ID: return _PriceRegistry.ParseTokenTransferFeeConfigDeleted(log) case _PriceRegistry.abi.Events["TokenTransferFeeConfigUpdated"].ID: @@ -2952,14 +2694,6 @@ func (PriceRegistryPriceFeedPerTokenUpdated) Topic() common.Hash { return common.HexToHash("0x08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464") } -func (PriceRegistryPriceUpdaterRemoved) Topic() common.Hash { - return common.HexToHash("0xff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c") -} - -func (PriceRegistryPriceUpdaterSet) Topic() common.Hash { - return common.HexToHash("0x34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b8") -} - func (PriceRegistryTokenTransferFeeConfigDeleted) Topic() common.Hash { return common.HexToHash("0x4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b") } @@ -3099,18 +2833,6 @@ type PriceRegistryInterface interface { ParsePriceFeedPerTokenUpdated(log types.Log) (*PriceRegistryPriceFeedPerTokenUpdated, error) - FilterPriceUpdaterRemoved(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterRemovedIterator, error) - - WatchPriceUpdaterRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address) (event.Subscription, error) - - ParsePriceUpdaterRemoved(log types.Log) (*PriceRegistryPriceUpdaterRemoved, error) - - FilterPriceUpdaterSet(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterSetIterator, error) - - WatchPriceUpdaterSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterSet, priceUpdater []common.Address) (event.Subscription, error) - - ParsePriceUpdaterSet(log types.Log) (*PriceRegistryPriceUpdaterSet, error) - FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*PriceRegistryTokenTransferFeeConfigDeletedIterator, error) WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *PriceRegistryTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 71552045c6..e23a89fb9c 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -5,13 +5,13 @@ burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 1bbffb552c3256097fbe61a430de408073816f40e17b17b102b793527d44f046 burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 5be8832498c8aab49957bfff94fbb1d22373833d1d56f5d8ace259343b27fc24 burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 9215cb5efe441e9893f871de31b4a5d4171c479f276aac4084046514990f1bd6 -ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin c06c1cf1d004a803585a2c9d7a71ee5997b5fca86c2e111335cb8b930d9e3b5a +ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 970bf6a2a817813eb3302c92ec3ad0bc0fc6c2e693f33c13f57733d003f44d0d ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin 02be3227883ca4b69383892d27ba7a9af747151a06f4815d18ccd8aaf89b4fb9 commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin ddc26c10c2a52b59624faae9005827b09b98db4566887a736005e8cc37cf8a51 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin ebd8aac686fa28a71d4212bcd25a28f8f640d50dce5e50498b2f6b8534890b69 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 3ea3974c9848e0df0dbe1fc7192134589e7735017c2ea8d4755084b3c95035d1 -evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 9478aedc9f0072fbdafb54a6f82248de1efbcd7bdff18a90d8556b9aaff67455 +evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin a9aaf33667cab483adab20358d2c04b0694f4ecb26cf90c8e489f78e7f5f407a evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin bdafc343d33f1eb753871ea6d215339cd8e087c1a8c7297257791dd1e453be8f evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin bf1a3090a2f8d1632b82a6d45200cf6f3833a1e27303745405c1ed13ffc0cf83 lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin f049909cfef0aa3b8158c85e7b64516b9d7b32f4930705574090e5b9cab534b1 @@ -27,7 +27,7 @@ multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Help nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 6f64e1083b356c06ee66b9138e398b9c97a4cd3e8c9ec38cf3010cebc79af536 ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 1588313bb5e781d181a825247d30828f59007700f36b4b9b00391592b06ff4b4 -price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 955eeb1da5f001fa01dc9914bf8a02b7e3b58e080ee775424261dcd97f88d70d +price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 7320907b45fe2bdc3a06f5891dd34b8ab270823a652fec15676ec8a898764273 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 7b2a47349d3fdb8d8b4e206d68577219deca7fabd1e893686fa8f118ad980d2d report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin c07af8433bf8dbc7981725b18922a9c4e2dea068dd204bc62adc0e926cb499c3 router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 42576577e81beea9a069bd9229caaa9a71227fbaef3871a1a2e69fd218216290 diff --git a/core/gethwrappers/ccip/mocks/price_registry_interface.go b/core/gethwrappers/ccip/mocks/price_registry_interface.go index 8c2834acce..b8b90b1293 100644 --- a/core/gethwrappers/ccip/mocks/price_registry_interface.go +++ b/core/gethwrappers/ccip/mocks/price_registry_interface.go @@ -1085,124 +1085,6 @@ func (_c *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call) RunAndRetu return _c } -// FilterPriceUpdaterRemoved provides a mock function with given fields: opts, priceUpdater -func (_m *PriceRegistryInterface) FilterPriceUpdaterRemoved(opts *bind.FilterOpts, priceUpdater []common.Address) (*price_registry.PriceRegistryPriceUpdaterRemovedIterator, error) { - ret := _m.Called(opts, priceUpdater) - - if len(ret) == 0 { - panic("no return value specified for FilterPriceUpdaterRemoved") - } - - var r0 *price_registry.PriceRegistryPriceUpdaterRemovedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPriceUpdaterRemovedIterator, error)); ok { - return rf(opts, priceUpdater) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryPriceUpdaterRemovedIterator); ok { - r0 = rf(opts, priceUpdater) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryPriceUpdaterRemovedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { - r1 = rf(opts, priceUpdater) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterPriceUpdaterRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPriceUpdaterRemoved' -type PriceRegistryInterface_FilterPriceUpdaterRemoved_Call struct { - *mock.Call -} - -// FilterPriceUpdaterRemoved is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - priceUpdater []common.Address -func (_e *PriceRegistryInterface_Expecter) FilterPriceUpdaterRemoved(opts interface{}, priceUpdater interface{}) *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call { - return &PriceRegistryInterface_FilterPriceUpdaterRemoved_Call{Call: _e.mock.On("FilterPriceUpdaterRemoved", opts, priceUpdater)} -} - -func (_c *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call) Run(run func(opts *bind.FilterOpts, priceUpdater []common.Address)) *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call) Return(_a0 *price_registry.PriceRegistryPriceUpdaterRemovedIterator, _a1 error) *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPriceUpdaterRemovedIterator, error)) *PriceRegistryInterface_FilterPriceUpdaterRemoved_Call { - _c.Call.Return(run) - return _c -} - -// FilterPriceUpdaterSet provides a mock function with given fields: opts, priceUpdater -func (_m *PriceRegistryInterface) FilterPriceUpdaterSet(opts *bind.FilterOpts, priceUpdater []common.Address) (*price_registry.PriceRegistryPriceUpdaterSetIterator, error) { - ret := _m.Called(opts, priceUpdater) - - if len(ret) == 0 { - panic("no return value specified for FilterPriceUpdaterSet") - } - - var r0 *price_registry.PriceRegistryPriceUpdaterSetIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPriceUpdaterSetIterator, error)); ok { - return rf(opts, priceUpdater) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryPriceUpdaterSetIterator); ok { - r0 = rf(opts, priceUpdater) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryPriceUpdaterSetIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { - r1 = rf(opts, priceUpdater) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterPriceUpdaterSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPriceUpdaterSet' -type PriceRegistryInterface_FilterPriceUpdaterSet_Call struct { - *mock.Call -} - -// FilterPriceUpdaterSet is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - priceUpdater []common.Address -func (_e *PriceRegistryInterface_Expecter) FilterPriceUpdaterSet(opts interface{}, priceUpdater interface{}) *PriceRegistryInterface_FilterPriceUpdaterSet_Call { - return &PriceRegistryInterface_FilterPriceUpdaterSet_Call{Call: _e.mock.On("FilterPriceUpdaterSet", opts, priceUpdater)} -} - -func (_c *PriceRegistryInterface_FilterPriceUpdaterSet_Call) Run(run func(opts *bind.FilterOpts, priceUpdater []common.Address)) *PriceRegistryInterface_FilterPriceUpdaterSet_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterPriceUpdaterSet_Call) Return(_a0 *price_registry.PriceRegistryPriceUpdaterSetIterator, _a1 error) *PriceRegistryInterface_FilterPriceUpdaterSet_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterPriceUpdaterSet_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPriceUpdaterSetIterator, error)) *PriceRegistryInterface_FilterPriceUpdaterSet_Call { - _c.Call.Return(run) - return _c -} - // FilterTokenTransferFeeConfigDeleted provides a mock function with given fields: opts, destChainSelector, token func (_m *PriceRegistryInterface) FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator, error) { ret := _m.Called(opts, destChainSelector, token) @@ -2888,122 +2770,6 @@ func (_c *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call) RunAndRetur return _c } -// ParsePriceUpdaterRemoved provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParsePriceUpdaterRemoved(log types.Log) (*price_registry.PriceRegistryPriceUpdaterRemoved, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParsePriceUpdaterRemoved") - } - - var r0 *price_registry.PriceRegistryPriceUpdaterRemoved - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryPriceUpdaterRemoved, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryPriceUpdaterRemoved); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryPriceUpdaterRemoved) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParsePriceUpdaterRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePriceUpdaterRemoved' -type PriceRegistryInterface_ParsePriceUpdaterRemoved_Call struct { - *mock.Call -} - -// ParsePriceUpdaterRemoved is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParsePriceUpdaterRemoved(log interface{}) *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call { - return &PriceRegistryInterface_ParsePriceUpdaterRemoved_Call{Call: _e.mock.On("ParsePriceUpdaterRemoved", log)} -} - -func (_c *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call) Return(_a0 *price_registry.PriceRegistryPriceUpdaterRemoved, _a1 error) *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryPriceUpdaterRemoved, error)) *PriceRegistryInterface_ParsePriceUpdaterRemoved_Call { - _c.Call.Return(run) - return _c -} - -// ParsePriceUpdaterSet provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParsePriceUpdaterSet(log types.Log) (*price_registry.PriceRegistryPriceUpdaterSet, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParsePriceUpdaterSet") - } - - var r0 *price_registry.PriceRegistryPriceUpdaterSet - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryPriceUpdaterSet, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryPriceUpdaterSet); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryPriceUpdaterSet) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParsePriceUpdaterSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePriceUpdaterSet' -type PriceRegistryInterface_ParsePriceUpdaterSet_Call struct { - *mock.Call -} - -// ParsePriceUpdaterSet is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParsePriceUpdaterSet(log interface{}) *PriceRegistryInterface_ParsePriceUpdaterSet_Call { - return &PriceRegistryInterface_ParsePriceUpdaterSet_Call{Call: _e.mock.On("ParsePriceUpdaterSet", log)} -} - -func (_c *PriceRegistryInterface_ParsePriceUpdaterSet_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParsePriceUpdaterSet_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParsePriceUpdaterSet_Call) Return(_a0 *price_registry.PriceRegistryPriceUpdaterSet, _a1 error) *PriceRegistryInterface_ParsePriceUpdaterSet_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParsePriceUpdaterSet_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryPriceUpdaterSet, error)) *PriceRegistryInterface_ParsePriceUpdaterSet_Call { - _c.Call.Return(run) - return _c -} - // ParseTokenTransferFeeConfigDeleted provides a mock function with given fields: log func (_m *PriceRegistryInterface) ParseTokenTransferFeeConfigDeleted(log types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigDeleted, error) { ret := _m.Called(log) @@ -4178,126 +3944,6 @@ func (_c *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call) RunAndRetur return _c } -// WatchPriceUpdaterRemoved provides a mock function with given fields: opts, sink, priceUpdater -func (_m *PriceRegistryInterface) WatchPriceUpdaterRemoved(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address) (event.Subscription, error) { - ret := _m.Called(opts, sink, priceUpdater) - - if len(ret) == 0 { - panic("no return value specified for WatchPriceUpdaterRemoved") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterRemoved, []common.Address) (event.Subscription, error)); ok { - return rf(opts, sink, priceUpdater) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterRemoved, []common.Address) event.Subscription); ok { - r0 = rf(opts, sink, priceUpdater) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterRemoved, []common.Address) error); ok { - r1 = rf(opts, sink, priceUpdater) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchPriceUpdaterRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPriceUpdaterRemoved' -type PriceRegistryInterface_WatchPriceUpdaterRemoved_Call struct { - *mock.Call -} - -// WatchPriceUpdaterRemoved is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryPriceUpdaterRemoved -// - priceUpdater []common.Address -func (_e *PriceRegistryInterface_Expecter) WatchPriceUpdaterRemoved(opts interface{}, sink interface{}, priceUpdater interface{}) *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call { - return &PriceRegistryInterface_WatchPriceUpdaterRemoved_Call{Call: _e.mock.On("WatchPriceUpdaterRemoved", opts, sink, priceUpdater)} -} - -func (_c *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address)) *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryPriceUpdaterRemoved), args[2].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterRemoved, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchPriceUpdaterRemoved_Call { - _c.Call.Return(run) - return _c -} - -// WatchPriceUpdaterSet provides a mock function with given fields: opts, sink, priceUpdater -func (_m *PriceRegistryInterface) WatchPriceUpdaterSet(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPriceUpdaterSet, priceUpdater []common.Address) (event.Subscription, error) { - ret := _m.Called(opts, sink, priceUpdater) - - if len(ret) == 0 { - panic("no return value specified for WatchPriceUpdaterSet") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterSet, []common.Address) (event.Subscription, error)); ok { - return rf(opts, sink, priceUpdater) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterSet, []common.Address) event.Subscription); ok { - r0 = rf(opts, sink, priceUpdater) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterSet, []common.Address) error); ok { - r1 = rf(opts, sink, priceUpdater) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchPriceUpdaterSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPriceUpdaterSet' -type PriceRegistryInterface_WatchPriceUpdaterSet_Call struct { - *mock.Call -} - -// WatchPriceUpdaterSet is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryPriceUpdaterSet -// - priceUpdater []common.Address -func (_e *PriceRegistryInterface_Expecter) WatchPriceUpdaterSet(opts interface{}, sink interface{}, priceUpdater interface{}) *PriceRegistryInterface_WatchPriceUpdaterSet_Call { - return &PriceRegistryInterface_WatchPriceUpdaterSet_Call{Call: _e.mock.On("WatchPriceUpdaterSet", opts, sink, priceUpdater)} -} - -func (_c *PriceRegistryInterface_WatchPriceUpdaterSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPriceUpdaterSet, priceUpdater []common.Address)) *PriceRegistryInterface_WatchPriceUpdaterSet_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryPriceUpdaterSet), args[2].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchPriceUpdaterSet_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchPriceUpdaterSet_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchPriceUpdaterSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceUpdaterSet, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchPriceUpdaterSet_Call { - _c.Call.Return(run) - return _c -} - // WatchTokenTransferFeeConfigDeleted provides a mock function with given fields: opts, sink, destChainSelector, token func (_m *PriceRegistryInterface) WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { ret := _m.Called(opts, sink, destChainSelector, token) From 26b77df62f58420205a4b6e9737dbaef57e0a96b Mon Sep 17 00:00:00 2001 From: Ryan Hall Date: Tue, 6 Aug 2024 09:27:45 -0400 Subject: [PATCH 192/432] Make router destination/source chain specific (#1242) ## Motivation We want the ability to test new lanes using custom, test routers. Therefore, we need a one-to-many relationship b/t routers and lanes, rather than a singleton. ## Solution Make routers configurable per lane, rather than per contract --- contracts/gas-snapshots/ccip.gas-snapshot | 333 +++++++++--------- .../v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 23 +- .../v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol | 86 ++++- .../src/v0.8/ccip/test/NonceManager.t.sol | 5 +- .../v0.8/ccip/test/e2e/MultiRampsEnd2End.sol | 6 +- .../test/helpers/EVM2EVMMultiOnRampHelper.sol | 5 +- .../test/offRamp/EVM2EVMMultiOffRamp.t.sol | 112 ++++-- .../offRamp/EVM2EVMMultiOffRampSetup.t.sol | 27 +- .../ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol | 105 +++++- .../test/onRamp/EVM2EVMMultiOnRampSetup.t.sol | 30 +- .../ccip/ccip_integration_tests/helpers.go | 26 +- .../ccip_reader_tester/ccip_reader_tester.go | 5 +- .../evm_2_evm_multi_offramp.go | 13 +- .../evm_2_evm_multi_onramp.go | 199 ++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 6 +- 15 files changed, 697 insertions(+), 284 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 4bb6701f8f..23cf48a63b 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -123,173 +123,176 @@ CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424253) E2E:test_E2E_3MessagesSuccess_gas() (gas: 1110291) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38157) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 108321) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 116789) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 460560) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 95542) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12463) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 90385) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 105586) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 15719) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 13057) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 298417) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 239752) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 158869) -EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 189205) -EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 147533) -EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 521366) -EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10459) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38185) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 108335) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 116870) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 468131) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99235) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12399) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 93193) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 109906) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13267) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17992) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15347) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 296705) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 238095) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 157010) +EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187408) +EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 145607) +EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 521737) +EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10437) EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15662) -EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67195) -EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59698) -EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58778) -EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6373551) -EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 5956778) -EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106229) -EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116228) -EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106272) -EVM2EVMMultiOffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351414) -EVM2EVMMultiOffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159132) -EVM2EVMMultiOffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136253) -EVM2EVMMultiOffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136831) -EVM2EVMMultiOffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 59046) -EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 227807) -EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117527) -EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77605) -EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 207057) -EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6367940) -EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47785) -EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 5959080) -EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 157297) -EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103786) -EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101657) -EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 159802) -EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101556) -EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101623) -EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17280) -EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1557936) -EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 342777) -EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 260031) -EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6424008) -EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6006954) -EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 27681) -EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 165132) -EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 149088) -EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6786083) +EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67352) +EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59642) +EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58722) +EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6404489) +EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 5987629) +EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106187) +EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116097) +EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106208) +EVM2EVMMultiOffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351415) +EVM2EVMMultiOffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159329) +EVM2EVMMultiOffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136447) +EVM2EVMMultiOffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136719) +EVM2EVMMultiOffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 58990) +EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225639) +EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117474) +EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77538) +EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 204931) +EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6398812) +EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47718) +EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 5991681) +EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 136870) +EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103588) +EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101459) +EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139444) +EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101358) +EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101403) +EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17302) +EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1558948) +EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 339903) +EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 258341) +EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6455106) +EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6037987) +EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 27703) +EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 163239) +EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147217) +EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6817158) EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17154) EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18413) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249346) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249352) EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20672) -EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 201673) -EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48860) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48381) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 232798) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 89392) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 278124) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 93615) -EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35083) -EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23907) -EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 451216) -EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54426) -EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35917) -EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154369) -EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35317) -EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 181304) -EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 192594) -EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48053) -EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 442981) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 251672) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 173864) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 193559) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259599) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 129536) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 391590) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65850) -EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80906) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 535287) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 480203) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35763) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 520202) -EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 517570) -EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 487706) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 127927) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 157150) +EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 201744) +EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48956) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48477) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229787) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86425) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 280248) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92678) +EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35117) +EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23918) +EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 451435) +EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54437) +EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35906) +EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154347) +EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35328) +EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 179411) +EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 190690) +EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48064) +EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 441088) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 249886) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 172078) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 191751) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259610) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 127621) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 391759) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65861) +EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80895) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 535602) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 480560) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35774) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 520573) +EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 517941) +EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 488065) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 126045) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 155268) EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3655340) -EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118224) +EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118202) EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87461) EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75600) EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26461) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 163032) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 207236) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 163139) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205495) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26004) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152867) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 507382) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2285227) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 209491) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 210112) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 668120) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 299303) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 160598) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 24131) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 59105) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 40405) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 76108) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 178929) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 278805) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 505596) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2285365) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 207749) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 208326) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 659124) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 299687) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 160626) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 24145) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 59111) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 40433) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 76136) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 178957) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 278828) EVM2EVMMultiOffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11379) -EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215406) -EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14374) -EVM2EVMMultiOffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11898) -EVM2EVMMultiOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 14054) -EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 54933) -EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 32943) -EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 238004) -EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246667) -EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 299477) -EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 280557) -EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176604) -EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178672) -EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141533) +EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215350) +EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14162) +EVM2EVMMultiOffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11660) +EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49203) +EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27169) +EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 238126) +EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246723) +EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 301741) +EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 282687) +EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176548) +EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178616) +EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141477) EVM2EVMMultiOffRamp_verify:test_TooManyLeaves_Revert() (gas: 51508) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94508) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92460) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97463) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92518) -EVM2EVMMultiOnRamp_constructor:test_Constructor_Success() (gas: 2256117) -EVM2EVMMultiOnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 90987) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 130983) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 161753) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 161306) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 159506) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 161536) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 160928) -EVM2EVMMultiOnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 26206) -EVM2EVMMultiOnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 134082) -EVM2EVMMultiOnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 24272) -EVM2EVMMultiOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12819) -EVM2EVMMultiOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 30695) -EVM2EVMMultiOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 15675) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 198276) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 224545) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 140840) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 162262) -EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3843523) -EVM2EVMMultiOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 127615) -EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 93044) -EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 282576) -EVM2EVMMultiOnRamp_getFee:test_EmptyMessage_Success() (gas: 104423) -EVM2EVMMultiOnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 74053) -EVM2EVMMultiOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119755) -EVM2EVMMultiOnRamp_getFee:test_Unhealthy_Revert() (gas: 43657) +EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 63649) +EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() (gas: 13308) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94175) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92092) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97113) +EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92150) +EVM2EVMMultiOnRamp_constructor:test_Constructor_Success() (gas: 2384439) +EVM2EVMMultiOnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 71918) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 111914) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 142684) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 142260) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 140437) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 142490) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 141859) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 134347) +EVM2EVMMultiOnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 26294) +EVM2EVMMultiOnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 133253) +EVM2EVMMultiOnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 24360) +EVM2EVMMultiOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12872) +EVM2EVMMultiOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 32033) +EVM2EVMMultiOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 15762) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179401) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 205670) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 121815) +EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 143193) +EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3824556) +EVM2EVMMultiOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108546) +EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 73975) +EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 262685) +EVM2EVMMultiOnRamp_getFee:test_EmptyMessage_Success() (gas: 104467) +EVM2EVMMultiOnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 74075) +EVM2EVMMultiOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119799) +EVM2EVMMultiOnRamp_getFee:test_Unhealthy_Revert() (gas: 43679) EVM2EVMMultiOnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10438) -EVM2EVMMultiOnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35204) -EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11356) -EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() (gas: 12956) -EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11313) -EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 16287) -EVM2EVMMultiOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 58439) -EVM2EVMMultiOnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97185) +EVM2EVMMultiOnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35270) +EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11155) +EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() (gas: 12740) +EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11112) +EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939) +EVM2EVMMultiOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 51996) +EVM2EVMMultiOnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97214) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 38281) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 106252) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_revert_Revert() (gas: 114736) @@ -594,23 +597,23 @@ MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) -MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 412263) -MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1426807) +MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 393335) +MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1389396) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71847) -NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 252468) -NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 254768) -NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 307738) -NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 290815) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 247843) +NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 250575) +NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 252898) +NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 305952) +NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 288933) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 247821) NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 235877) -NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 144725) -NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 186694) -NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 237762) +NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 142832) +NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 167625) +NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 218724) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) -NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 125923) +NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 106854) NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 122943) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOffRamp_Revert() (gas: 42959) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRampAndOffRamp_Revert() (gas: 64282) diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol index 34e4793d22..554533e39b 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -89,14 +89,16 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { /// @notice Per-chain source config (defining a lane from a Source Chain -> Dest OffRamp) struct SourceChainConfig { - bool isEnabled; // ──────────╮ Flag whether the source chain is enabled or not + IRouter router; // ──────────╮ Local router to use for messages coming from this source chain + bool isEnabled; // | Flag whether the source chain is enabled or not uint64 minSeqNr; // ─────────╯ The min sequence number expected for future messages bytes onRamp; // OnRamp address on the source chain } /// @notice SourceChainConfig update args scoped to one source chain struct SourceChainConfigArgs { - uint64 sourceChainSelector; // ───╮ Source chain selector of the config to update + IRouter router; // ────────────────╮ Local router to use for messages coming from this source chain + uint64 sourceChainSelector; // | Source chain selector of the config to update bool isEnabled; // ────────────────╯ Flag whether the source chain is enabled or not bytes onRamp; // OnRamp address on the source chain } @@ -104,12 +106,11 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { /// @notice Dynamic offRamp config /// @dev since OffRampConfig is part of OffRampConfigChanged event, if changing it, we should update the ABI on Atlas struct DynamicConfig { - address router; // ─────────────────────────────────╮ Router address + address priceRegistry; // ──────────────────────────╮ Price registry address on the local chain uint32 permissionLessExecutionThresholdSeconds; // │ Waiting time before manual execution is enabled uint32 maxTokenTransferGas; // │ Maximum amount of gas passed on to token `transfer` call uint32 maxPoolReleaseOrMintGas; // ─────────────────╯ Maximum amount of gas passed on to token pool when calling releaseOrMint address messageValidator; // Optional message validator to validate incoming messages (zero address = no validator) - address priceRegistry; // Price registry address on the local chain } /// @notice a sequenceNumber interval @@ -534,9 +535,9 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { || !message.receiver.supportsInterface(type(IAny2EVMMessageReceiver).interfaceId) ) return; - (bool success, bytes memory returnData,) = IRouter(s_dynamicConfig.router).routeMessage( - any2EvmMessage, Internal.GAS_FOR_CALL_EXACT_CHECK, message.gasLimit, message.receiver - ); + (bool success, bytes memory returnData,) = s_sourceChainConfigs[message.header.sourceChainSelector] + .router + .routeMessage(any2EvmMessage, Internal.GAS_FOR_CALL_EXACT_CHECK, message.gasLimit, message.receiver); // If CCIP receiver execution is not successful, revert the call including token transfers if (!success) revert ReceiverError(returnData); } @@ -729,6 +730,10 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { revert ZeroChainSelectorNotAllowed(); } + if (address(sourceConfigUpdate.router) == address(0)) { + revert ZeroAddressNotAllowed(); + } + SourceChainConfig storage currentConfig = s_sourceChainConfigs[sourceChainSelector]; bytes memory currentOnRamp = currentConfig.onRamp; bytes memory newOnRamp = sourceConfigUpdate.onRamp; @@ -746,8 +751,8 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { revert InvalidStaticConfig(sourceChainSelector); } - // The only dynamic config is the isEnabled flag currentConfig.isEnabled = sourceConfigUpdate.isEnabled; + currentConfig.router = sourceConfigUpdate.router; emit SourceChainConfigSet(sourceChainSelector, currentConfig); } } @@ -761,7 +766,7 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { /// @notice Sets the dynamic config. /// @param dynamicConfig The dynamic config. function _setDynamicConfig(DynamicConfig memory dynamicConfig) internal { - if (dynamicConfig.priceRegistry == address(0) || dynamicConfig.router == address(0)) { + if (dynamicConfig.priceRegistry == address(0)) { revert ZeroAddressNotAllowed(); } diff --git a/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol b/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol index 10d2a11079..10a5c5876e 100644 --- a/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol @@ -8,6 +8,7 @@ import {INonceManager} from "../interfaces/INonceManager.sol"; import {IPoolV1} from "../interfaces/IPool.sol"; import {IPriceRegistry} from "../interfaces/IPriceRegistry.sol"; import {IRMN} from "../interfaces/IRMN.sol"; +import {IRouter} from "../interfaces/IRouter.sol"; import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol"; import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; @@ -33,8 +34,10 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre error InvalidConfig(); error CursedByRMN(uint64 sourceChainSelector); error GetSupportedTokensFunctionalityRemovedCheckAdminRegistry(); + error InvalidDestChainConfig(uint64 sourceChainSelector); event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig); + event DestChainConfigSet(uint64 indexed destChainSelector, DestChainConfig destChainConfig); event FeePaid(address indexed feeToken, uint256 feeValueJuels); event FeeTokenWithdrawn(address indexed feeAggregator, address indexed feeToken, uint256 amount); /// RMN depends on this event, if changing, please notify the RMN maintainers. @@ -53,12 +56,29 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre /// @dev Struct to contains the dynamic configuration // solhint-disable-next-line gas-struct-packing struct DynamicConfig { - address router; // Router address address priceRegistry; // Price registry address address messageValidator; // Optional message validator to validate outbound messages (zero address = no validator) address feeAggregator; // Fee aggregator address } + /// @dev Struct to hold the configs for a destination chain + struct DestChainConfig { + // The last used sequence number. This is zero in the case where no messages has been sent yet. + // 0 is not a valid sequence number for any real transaction. + uint64 sequenceNumber; + // This is the local router address that is allowed to send messages to the destination chain. + // This is NOT the receiving router address on the destination chain. + IRouter router; + } + + /// @dev Same as DestChainConfig but with the destChainSelector so that an array of these + /// can be passed in the constructor and the applyDestChainConfigUpdates function + //solhint-disable gas-struct-packing + struct DestChainConfigArgs { + uint64 destChainSelector; // Destination chain selector + IRouter router; // Source router address + } + // STATIC CONFIG string public constant override typeAndVersion = "EVM2EVMMultiOnRamp 1.6.0-dev"; /// @dev The chain ID of the source chain that this contract is deployed to @@ -75,12 +95,14 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre /// @dev The config for the onRamp DynamicConfig internal s_dynamicConfig; - /// @dev Last used sequence number per destination chain. - /// This is zero in the case where no messages have been sent yet. - /// 0 is not a valid sequence number for any real transaction. - mapping(uint64 destChainSelector => uint64 sequenceNumber) internal s_destChainSequenceNumbers; + /// @dev The destination chain specific configs + mapping(uint64 destChainSelector => DestChainConfig destChainConfig) internal s_destChainConfigs; - constructor(StaticConfig memory staticConfig, DynamicConfig memory dynamicConfig) { + constructor( + StaticConfig memory staticConfig, + DynamicConfig memory dynamicConfig, + DestChainConfigArgs[] memory destChainConfigArgs + ) { if ( staticConfig.chainSelector == 0 || staticConfig.rmnProxy == address(0) || staticConfig.nonceManager == address(0) || staticConfig.tokenAdminRegistry == address(0) @@ -94,6 +116,7 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre i_tokenAdminRegistry = staticConfig.tokenAdminRegistry; _setDynamicConfig(dynamicConfig); + _applyDestChainConfigUpdates(destChainConfigArgs); } // ================================================================ @@ -104,7 +127,7 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre /// @param destChainSelector The destination chain selector /// @return the next sequence number to be used function getExpectedNextSequenceNumber(uint64 destChainSelector) external view returns (uint64) { - return s_destChainSequenceNumbers[destChainSelector] + 1; + return s_destChainConfigs[destChainSelector].sequenceNumber + 1; } /// @inheritdoc IEVM2AnyOnRampClient @@ -114,15 +137,20 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre uint256 feeTokenAmount, address originalSender ) external returns (bytes32) { + DestChainConfig storage destChainConfig = s_destChainConfigs[destChainSelector]; + // NOTE: assumes the message has already been validated through the getFee call // Validate message sender is set and allowed. Not validated in `getFee` since it is not user-driven. if (originalSender == address(0)) revert RouterMustSetOriginalSender(); // Router address may be zero intentionally to pause. - if (msg.sender != s_dynamicConfig.router) revert MustBeCalledByRouter(); + if (msg.sender != address(destChainConfig.router)) revert MustBeCalledByRouter(); - address messageValidator = s_dynamicConfig.messageValidator; - if (messageValidator != address(0)) { - IMessageInterceptor(messageValidator).onOutboundMessage(destChainSelector, message); + { + // scoped to reduce stack usage + address messageValidator = s_dynamicConfig.messageValidator; + if (messageValidator != address(0)) { + IMessageInterceptor(messageValidator).onOutboundMessage(destChainSelector, message); + } } // Convert message fee to juels and retrieve converted args @@ -139,7 +167,7 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre sourceChainSelector: i_chainSelector, destChainSelector: destChainSelector, // We need the next available sequence number so we increment before we use the value - sequenceNumber: ++s_destChainSequenceNumbers[destChainSelector], + sequenceNumber: ++destChainConfig.sequenceNumber, // Only bump nonce for messages that specify allowOutOfOrderExecution == false. Otherwise, we // may block ordered message nonces, which is not what we want. nonce: isOutOfOrderExecution @@ -256,9 +284,15 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre _setDynamicConfig(dynamicConfig); } + /// @notice Gets the source router for a destination chain + /// @param destChainSelector The destination chain selector + /// @return router the router for the provided destination chain + function getRouter(uint64 destChainSelector) external view returns (IRouter) { + return s_destChainConfigs[destChainSelector].router; + } + /// @notice Internal version of setDynamicConfig to allow for reuse in the constructor. function _setDynamicConfig(DynamicConfig memory dynamicConfig) internal { - // We permit router to be set to zero as a way to pause the contract. if (dynamicConfig.priceRegistry == address(0) || dynamicConfig.feeAggregator == address(0)) revert InvalidConfig(); s_dynamicConfig = dynamicConfig; @@ -274,6 +308,32 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre ); } + /// @notice Updates the destination chain specific config. + /// @param destChainConfigArgs Array of source chain specific configs. + function applyDestChainConfigUpdates(DestChainConfigArgs[] memory destChainConfigArgs) external onlyOwner { + _applyDestChainConfigUpdates(destChainConfigArgs); + } + + /// @notice Internal version of applyDestChainConfigUpdates. + function _applyDestChainConfigUpdates(DestChainConfigArgs[] memory destChainConfigArgs) internal { + for (uint256 i = 0; i < destChainConfigArgs.length; ++i) { + DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[i]; + uint64 destChainSelector = destChainConfigArgs[i].destChainSelector; + + if (destChainSelector == 0) { + revert InvalidDestChainConfig(destChainSelector); + } + + DestChainConfig memory newDestChainConfig = DestChainConfig({ + sequenceNumber: s_destChainConfigs[destChainSelector].sequenceNumber, + router: destChainConfigArg.router + }); + s_destChainConfigs[destChainSelector] = newDestChainConfig; + + emit DestChainConfigSet(destChainSelector, newDestChainConfig); + } + } + // ================================================================ // │ Tokens and pools │ // ================================================================ diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol index 48d00fbaee..42285097e1 100644 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -257,7 +257,7 @@ contract NonceManager_OnRampUpgrade is EVM2EVMMultiOnRampSetup { s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); (s_onRamp, s_metadataHash) = _deployOnRamp( - SOURCE_CHAIN_SELECTOR, address(s_sourceRouter), address(s_outboundNonceManager), address(s_tokenAdminRegistry) + SOURCE_CHAIN_SELECTOR, s_sourceRouter, address(s_outboundNonceManager), address(s_tokenAdminRegistry) ); vm.startPrank(address(s_sourceRouter)); @@ -370,16 +370,19 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](3); sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, isEnabled: true, onRamp: ON_RAMP_ADDRESS_1 }); sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_2, isEnabled: true, onRamp: ON_RAMP_ADDRESS_2 }); sourceChainConfigs[2] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_3, isEnabled: true, onRamp: ON_RAMP_ADDRESS_3 diff --git a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol index cbe8a35dce..52436503d2 100644 --- a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol +++ b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol @@ -66,7 +66,7 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { s_onRamp2, s_metadataHash2 ) = _deployOnRamp( - SOURCE_CHAIN_SELECTOR + 1, address(s_sourceRouter2), address(s_nonceManager2), address(s_tokenAdminRegistry2) + SOURCE_CHAIN_SELECTOR + 1, s_sourceRouter2, address(s_nonceManager2), address(s_tokenAdminRegistry2) ); address[] memory authorizedCallers = new address[](1); @@ -81,18 +81,20 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { s_sourceRouter2.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), new Router.OffRamp[](0)); // Deploy offramp - _deployOffRamp(s_destRouter, s_mockRMN, s_inboundNonceManager); + _deployOffRamp(s_mockRMN, s_inboundNonceManager); // Enable source chains on offramp EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](2); sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR, isEnabled: true, // Must match OnRamp address onRamp: abi.encode(address(s_onRamp)) }); sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR + 1, isEnabled: true, onRamp: abi.encode(address(s_onRamp2)) diff --git a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOnRampHelper.sol b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOnRampHelper.sol index 0532697d64..88992a8749 100644 --- a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOnRampHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOnRampHelper.sol @@ -7,6 +7,7 @@ import {IgnoreContractSize} from "./IgnoreContractSize.sol"; contract EVM2EVMMultiOnRampHelper is EVM2EVMMultiOnRamp, IgnoreContractSize { constructor( StaticConfig memory staticConfig, - DynamicConfig memory dynamicConfig - ) EVM2EVMMultiOnRamp(staticConfig, dynamicConfig) {} + DynamicConfig memory dynamicConfig, + DestChainConfigArgs[] memory destChainConfigArgs + ) EVM2EVMMultiOnRamp(staticConfig, dynamicConfig, destChainConfigArgs) {} } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol index fcb0d9006c..5280c56ceb 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol @@ -5,6 +5,7 @@ import {ICommitStore} from "../../interfaces/ICommitStore.sol"; import {IMessageInterceptor} from "../../interfaces/IMessageInterceptor.sol"; import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; import {IRMN} from "../../interfaces/IRMN.sol"; +import {IRouter} from "../../interfaces/IRouter.sol"; import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; import {CallWithExactGas} from "../../../shared/call/CallWithExactGas.sol"; @@ -43,26 +44,36 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { nonceManager: address(s_inboundNonceManager) }); EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = - _generateDynamicMultiOffRampConfig(address(s_destRouter), address(s_priceRegistry)); + _generateDynamicMultiOffRampConfig(address(s_priceRegistry)); EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](2); sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true }); sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1 + 1, onRamp: ON_RAMP_ADDRESS_2, isEnabled: true }); - EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig1 = - EVM2EVMMultiOffRamp.SourceChainConfig({isEnabled: true, minSeqNr: 1, onRamp: sourceChainConfigs[0].onRamp}); + EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig1 = EVM2EVMMultiOffRamp.SourceChainConfig({ + router: s_destRouter, + isEnabled: true, + minSeqNr: 1, + onRamp: sourceChainConfigs[0].onRamp + }); - EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig2 = - EVM2EVMMultiOffRamp.SourceChainConfig({isEnabled: true, minSeqNr: 1, onRamp: sourceChainConfigs[1].onRamp}); + EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig2 = EVM2EVMMultiOffRamp.SourceChainConfig({ + router: s_destRouter, + isEnabled: true, + minSeqNr: 1, + onRamp: sourceChainConfigs[1].onRamp + }); vm.expectEmit(); emit EVM2EVMMultiOffRamp.StaticConfigSet(staticConfig); @@ -141,6 +152,7 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: new bytes(0), isEnabled: true @@ -155,7 +167,7 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)), + _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); } @@ -166,8 +178,12 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); - sourceChainConfigs[0] = - EVM2EVMMultiOffRamp.SourceChainConfigArgs({sourceChainSelector: 0, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true}); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, + sourceChainSelector: 0, + onRamp: ON_RAMP_ADDRESS_1, + isEnabled: true + }); vm.expectRevert(EVM2EVMMultiOffRamp.ZeroChainSelectorNotAllowed.selector); @@ -178,7 +194,7 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)), + _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); } @@ -199,7 +215,7 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)), + _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); } @@ -220,7 +236,7 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)), + _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); } @@ -241,7 +257,7 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { tokenAdminRegistry: ZERO_ADDRESS, nonceManager: address(s_inboundNonceManager) }), - _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)), + _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); } @@ -262,7 +278,7 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: ZERO_ADDRESS }), - _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)), + _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); } @@ -271,7 +287,7 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { contract EVM2EVMMultiOffRamp_setDynamicConfig is EVM2EVMMultiOffRampSetup { function test_SetDynamicConfig_Success() public { EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = - _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)); + _generateDynamicMultiOffRampConfig(address(s_priceRegistry)); vm.expectEmit(); emit EVM2EVMMultiOffRamp.DynamicConfigSet(dynamicConfig); @@ -284,7 +300,7 @@ contract EVM2EVMMultiOffRamp_setDynamicConfig is EVM2EVMMultiOffRampSetup { function test_SetDynamicConfigWithValidator_Success() public { EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = - _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)); + _generateDynamicMultiOffRampConfig(address(s_priceRegistry)); dynamicConfig.messageValidator = address(s_inboundMessageValidator); vm.expectEmit(); @@ -301,24 +317,15 @@ contract EVM2EVMMultiOffRamp_setDynamicConfig is EVM2EVMMultiOffRampSetup { function test_NonOwner_Revert() public { vm.startPrank(STRANGER); EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = - _generateDynamicMultiOffRampConfig(USER_3, address(s_priceRegistry)); + _generateDynamicMultiOffRampConfig(address(s_priceRegistry)); vm.expectRevert("Only callable by owner"); s_offRamp.setDynamicConfig(dynamicConfig); } - function test_RouterZeroAddress_Revert() public { - EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = - _generateDynamicMultiOffRampConfig(ZERO_ADDRESS, address(s_priceRegistry)); - - vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); - - s_offRamp.setDynamicConfig(dynamicConfig); - } - function test_PriceRegistryZeroAddress_Revert() public { - EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = _generateDynamicMultiOffRampConfig(USER_3, ZERO_ADDRESS); + EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = _generateDynamicMultiOffRampConfig(ZERO_ADDRESS); vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); @@ -2654,13 +2661,18 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true }); - EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig = - EVM2EVMMultiOffRamp.SourceChainConfig({isEnabled: true, minSeqNr: 1, onRamp: ON_RAMP_ADDRESS_1}); + EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig = EVM2EVMMultiOffRamp.SourceChainConfig({ + router: s_destRouter, + isEnabled: true, + minSeqNr: 1, + onRamp: ON_RAMP_ADDRESS_1 + }); vm.expectEmit(); emit EVM2EVMMultiOffRamp.SourceChainSelectorAdded(SOURCE_CHAIN_SELECTOR_1); @@ -2677,6 +2689,7 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true @@ -2685,8 +2698,12 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); sourceChainConfigs[0].isEnabled = false; - EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig = - EVM2EVMMultiOffRamp.SourceChainConfig({isEnabled: false, minSeqNr: 1, onRamp: ON_RAMP_ADDRESS_1}); + EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig = EVM2EVMMultiOffRamp.SourceChainConfig({ + router: s_destRouter, + isEnabled: false, + minSeqNr: 1, + onRamp: ON_RAMP_ADDRESS_1 + }); vm.expectEmit(); emit EVM2EVMMultiOffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1, expectedSourceChainConfig); @@ -2709,16 +2726,19 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](3); sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: abi.encode(ON_RAMP_ADDRESS_1, 0), isEnabled: true }); sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1 + 1, onRamp: abi.encode(ON_RAMP_ADDRESS_1, 1), isEnabled: false }); sourceChainConfigs[2] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1 + 2, onRamp: abi.encode(ON_RAMP_ADDRESS_1, 2), isEnabled: true @@ -2728,6 +2748,7 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam new EVM2EVMMultiOffRamp.SourceChainConfig[](3); for (uint256 i = 0; i < 3; ++i) { expectedSourceChainConfigs[i] = EVM2EVMMultiOffRamp.SourceChainConfig({ + router: s_destRouter, isEnabled: sourceChainConfigs[i].isEnabled, minSeqNr: 1, onRamp: abi.encode(ON_RAMP_ADDRESS_1, i) @@ -2757,10 +2778,12 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam // Skip invalid inputs vm.assume(sourceChainConfigArgs.sourceChainSelector != 0); vm.assume(sourceChainConfigArgs.onRamp.length != 0); + vm.assume(address(sourceChainConfigArgs.router) != address(0)); EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](2); sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true @@ -2774,6 +2797,7 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam } EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig = EVM2EVMMultiOffRamp.SourceChainConfig({ + router: sourceChainConfigArgs.router, isEnabled: sourceChainConfigArgs.isEnabled, minSeqNr: 1, onRamp: sourceChainConfigArgs.onRamp @@ -2800,6 +2824,7 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: new bytes(0), isEnabled: true @@ -2809,11 +2834,29 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); } + function test_RouterAddress_Revert() public { + EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = + new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: IRouter(address(0)), + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + onRamp: ON_RAMP_ADDRESS_1, + isEnabled: true + }); + + vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); + } + function test_ZeroSourceChainSelector_Revert() public { EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); - sourceChainConfigs[0] = - EVM2EVMMultiOffRamp.SourceChainConfigArgs({sourceChainSelector: 0, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true}); + sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, + sourceChainSelector: 0, + onRamp: ON_RAMP_ADDRESS_1, + isEnabled: true + }); vm.expectRevert(EVM2EVMMultiOffRamp.ZeroChainSelectorNotAllowed.selector); s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); @@ -2823,6 +2866,7 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true @@ -3278,7 +3322,7 @@ contract EVM2EVMMultiOffRamp_resetUnblessedRoots is EVM2EVMMultiOffRampSetup { function setUp() public virtual override { super.setUp(); _setupRealRMN(); - _deployOffRamp(s_destRouter, s_realRMN, s_inboundNonceManager); + _deployOffRamp(s_realRMN, s_inboundNonceManager); _setupMultipleOffRamps(); } @@ -3344,7 +3388,7 @@ contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { function setUp() public virtual override { super.setUp(); _setupRealRMN(); - _deployOffRamp(s_destRouter, s_realRMN, s_inboundNonceManager); + _deployOffRamp(s_realRMN, s_inboundNonceManager); _setupMultipleOffRamps(); } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol index ffd40d9de9..4aef61f052 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol @@ -73,10 +73,10 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba s_maybeRevertingPool = MaybeRevertingBurnMintTokenPool(s_destPoolByToken[s_destTokens[1]]); s_inboundNonceManager = new NonceManager(new address[](0)); - _deployOffRamp(s_destRouter, s_mockRMN, s_inboundNonceManager); + _deployOffRamp(s_mockRMN, s_inboundNonceManager); } - function _deployOffRamp(Router router, IRMN rmnProxy, NonceManager nonceManager) internal { + function _deployOffRamp(IRMN rmnProxy, NonceManager nonceManager) internal { EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); @@ -87,7 +87,7 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(nonceManager) }), - _generateDynamicMultiOffRampConfig(address(router), address(s_priceRegistry)), + _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); @@ -112,7 +112,7 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba transmitters: s_validTransmitters }); - s_offRamp.setDynamicConfig(_generateDynamicMultiOffRampConfig(address(router), address(s_priceRegistry))); + s_offRamp.setDynamicConfig(_generateDynamicMultiOffRampConfig(address(s_priceRegistry))); s_offRamp.setOCR3Configs(ocrConfigs); address[] memory authorizedCallers = new address[](1); @@ -175,16 +175,19 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](3); sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true }); sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_2, onRamp: ON_RAMP_ADDRESS_2, isEnabled: false }); sourceChainConfigs[2] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_3, onRamp: ON_RAMP_ADDRESS_3, isEnabled: true @@ -226,13 +229,13 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba }); } - function _generateDynamicMultiOffRampConfig( - address router, - address priceRegistry - ) internal pure returns (EVM2EVMMultiOffRamp.DynamicConfig memory) { + function _generateDynamicMultiOffRampConfig(address priceRegistry) + internal + pure + returns (EVM2EVMMultiOffRamp.DynamicConfig memory) + { return EVM2EVMMultiOffRamp.DynamicConfig({ permissionLessExecutionThresholdSeconds: PERMISSION_LESS_EXECUTION_THRESHOLD_SECONDS, - router: router, priceRegistry: priceRegistry, messageValidator: address(0), maxPoolReleaseOrMintGas: MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS, @@ -397,7 +400,8 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba EVM2EVMMultiOffRamp.DynamicConfig memory b ) public pure { assertEq(a.permissionLessExecutionThresholdSeconds, b.permissionLessExecutionThresholdSeconds); - assertEq(a.router, b.router); + assertEq(a.maxPoolReleaseOrMintGas, b.maxPoolReleaseOrMintGas); + assertEq(a.maxTokenTransferGas, b.maxTokenTransferGas); assertEq(a.messageValidator, b.messageValidator); assertEq(a.priceRegistry, b.priceRegistry); } @@ -409,6 +413,7 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba assertEq(config1.isEnabled, config2.isEnabled); assertEq(config1.minSeqNr, config2.minSeqNr); assertEq(config1.onRamp, config2.onRamp); + assertEq(address(config1.router), address(config2.router)); } function _getDefaultSourceTokenData(Client.EVMTokenAmount[] memory srcTokenAmounts) @@ -442,7 +447,7 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicMultiOffRampConfig(address(s_destRouter), address(s_priceRegistry)), + _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0) ); diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol index 08e468e622..f148177094 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol @@ -25,16 +25,17 @@ contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }); - EVM2EVMMultiOnRamp.DynamicConfig memory dynamicConfig = - _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)); + EVM2EVMMultiOnRamp.DynamicConfig memory dynamicConfig = _generateDynamicMultiOnRampConfig(address(s_priceRegistry)); vm.expectEmit(); emit EVM2EVMMultiOnRamp.ConfigSet(staticConfig, dynamicConfig); - - _deployOnRamp( - SOURCE_CHAIN_SELECTOR, address(s_sourceRouter), address(s_outboundNonceManager), address(s_tokenAdminRegistry) + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.DestChainConfigSet( + DEST_CHAIN_SELECTOR, EVM2EVMMultiOnRamp.DestChainConfig(0, s_sourceRouter) ); + _deployOnRamp(SOURCE_CHAIN_SELECTOR, s_sourceRouter, address(s_outboundNonceManager), address(s_tokenAdminRegistry)); + EVM2EVMMultiOnRamp.StaticConfig memory gotStaticConfig = s_onRamp.getStaticConfig(); _assertStaticConfigsEqual(staticConfig, gotStaticConfig); @@ -45,6 +46,7 @@ contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { assertEq("EVM2EVMMultiOnRamp 1.6.0-dev", s_onRamp.typeAndVersion()); assertEq(OWNER, s_onRamp.owner()); assertEq(1, s_onRamp.getExpectedNextSequenceNumber(DEST_CHAIN_SELECTOR)); + assertEq(address(s_sourceRouter), address(s_onRamp.getRouter(DEST_CHAIN_SELECTOR))); } function test_Constructor_InvalidConfigChainSelectorEqZero_Revert() public { @@ -56,7 +58,8 @@ contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)) + _generateDynamicMultiOnRampConfig(address(s_priceRegistry)), + _generateDestChainConfigArgs(IRouter(address(0))) ); } @@ -69,7 +72,8 @@ contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)) + _generateDynamicMultiOnRampConfig(address(s_priceRegistry)), + _generateDestChainConfigArgs(IRouter(address(0))) ); } @@ -82,7 +86,8 @@ contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { nonceManager: address(0), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)) + _generateDynamicMultiOnRampConfig(address(s_priceRegistry)), + _generateDestChainConfigArgs(IRouter(address(0))) ); } @@ -95,7 +100,8 @@ contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(0) }), - _generateDynamicMultiOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)) + _generateDynamicMultiOnRampConfig(address(s_priceRegistry)), + _generateDestChainConfigArgs(IRouter(address(0))) ); } } @@ -131,6 +137,28 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } + function test_ForwardFromRouter_Success_ConfigurableSourceRouter() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT * 2})); + uint256 feeAmount = 1234567890; + IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); + + // Change the source router for this lane + IRouter newRouter = IRouter(makeAddr("NEW ROUTER")); + vm.stopPrank(); + vm.prank(OWNER); + s_onRamp.applyDestChainConfigUpdates(_generateDestChainConfigArgs(newRouter)); + + // forward fails from wrong router + vm.prank(address(s_sourceRouter)); + vm.expectRevert(EVM2EVMMultiOnRamp.MustBeCalledByRouter.selector); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + + // forward succeeds from correct router + vm.prank(address(newRouter)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); + } + function test_ForwardFromRouterSuccessLegacyExtraArgs() public { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); message.extraArgs = @@ -327,8 +355,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { // We pause by disabling the whitelist vm.stopPrank(); vm.startPrank(OWNER); - address router = address(0); - s_onRamp.setDynamicConfig(_generateDynamicMultiOnRampConfig(router, address(2))); + s_onRamp.setDynamicConfig(_generateDynamicMultiOnRampConfig(address(2))); vm.expectRevert(EVM2EVMMultiOnRamp.MustBeCalledByRouter.selector); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, OWNER); } @@ -577,7 +604,6 @@ contract EVM2EVMMultiOnRamp_setDynamicConfig is EVM2EVMMultiOnRampSetup { function test_SetDynamicConfig_Success() public { EVM2EVMMultiOnRamp.StaticConfig memory staticConfig = s_onRamp.getStaticConfig(); EVM2EVMMultiOnRamp.DynamicConfig memory newConfig = EVM2EVMMultiOnRamp.DynamicConfig({ - router: address(2134), priceRegistry: address(23423), messageValidator: makeAddr("messageValidator"), feeAggregator: FEE_AGGREGATOR @@ -589,7 +615,6 @@ contract EVM2EVMMultiOnRamp_setDynamicConfig is EVM2EVMMultiOnRampSetup { s_onRamp.setDynamicConfig(newConfig); EVM2EVMMultiOnRamp.DynamicConfig memory gotDynamicConfig = s_onRamp.getDynamicConfig(); - assertEq(newConfig.router, gotDynamicConfig.router); assertEq(newConfig.priceRegistry, gotDynamicConfig.priceRegistry); } @@ -597,7 +622,6 @@ contract EVM2EVMMultiOnRamp_setDynamicConfig is EVM2EVMMultiOnRampSetup { function test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() public { EVM2EVMMultiOnRamp.DynamicConfig memory newConfig = EVM2EVMMultiOnRamp.DynamicConfig({ - router: address(2134), priceRegistry: address(0), feeAggregator: FEE_AGGREGATOR, messageValidator: makeAddr("messageValidator") @@ -609,7 +633,6 @@ contract EVM2EVMMultiOnRamp_setDynamicConfig is EVM2EVMMultiOnRampSetup { function test_SetConfigInvalidConfig_Revert() public { EVM2EVMMultiOnRamp.DynamicConfig memory newConfig = EVM2EVMMultiOnRamp.DynamicConfig({ - router: address(1), priceRegistry: address(23423), messageValidator: address(0), feeAggregator: FEE_AGGREGATOR @@ -623,7 +646,6 @@ contract EVM2EVMMultiOnRamp_setDynamicConfig is EVM2EVMMultiOnRampSetup { function test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() public { EVM2EVMMultiOnRamp.DynamicConfig memory newConfig = EVM2EVMMultiOnRamp.DynamicConfig({ - router: address(2134), priceRegistry: address(23423), messageValidator: address(0), feeAggregator: address(0) @@ -635,10 +657,10 @@ contract EVM2EVMMultiOnRamp_setDynamicConfig is EVM2EVMMultiOnRampSetup { function test_SetConfigOnlyOwner_Revert() public { vm.startPrank(STRANGER); vm.expectRevert("Only callable by owner"); - s_onRamp.setDynamicConfig(_generateDynamicMultiOnRampConfig(address(1), address(2))); + s_onRamp.setDynamicConfig(_generateDynamicMultiOnRampConfig(address(2))); vm.startPrank(ADMIN); vm.expectRevert("Only callable by owner"); - s_onRamp.setDynamicConfig(_generateDynamicMultiOnRampConfig(address(1), address(2))); + s_onRamp.setDynamicConfig(_generateDynamicMultiOnRampConfig(address(2))); } } @@ -718,3 +740,50 @@ contract EVM2EVMMultiOnRamp_getTokenPool is EVM2EVMMultiOnRampSetup { assertEq(address(0), nonExistentPool); } } + +contract EVM2EVMMultiOnRamp_applyDestChainConfigUpdates is EVM2EVMMultiOnRampSetup { + function test_ApplyDestChainConfigUpdates_Success() external { + vm.stopPrank(); + vm.startPrank(OWNER); + EVM2EVMMultiOnRamp.DestChainConfigArgs[] memory configArgs = new EVM2EVMMultiOnRamp.DestChainConfigArgs[](1); + configArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; + + // supports disabling a lane by setting a router to zero + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.DestChainConfigSet( + DEST_CHAIN_SELECTOR, EVM2EVMMultiOnRamp.DestChainConfig(0, IRouter(address(0))) + ); + s_onRamp.applyDestChainConfigUpdates(configArgs); + assertEq(address(0), address(s_onRamp.getRouter(DEST_CHAIN_SELECTOR))); + + // supports updating and adding lanes simultaneously + configArgs = new EVM2EVMMultiOnRamp.DestChainConfigArgs[](2); + configArgs[0] = + EVM2EVMMultiOnRamp.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, router: s_sourceRouter}); + configArgs[1] = EVM2EVMMultiOnRamp.DestChainConfigArgs({destChainSelector: 9999, router: IRouter(address(9999))}); + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.DestChainConfigSet( + DEST_CHAIN_SELECTOR, EVM2EVMMultiOnRamp.DestChainConfig(0, s_sourceRouter) + ); + vm.expectEmit(); + emit EVM2EVMMultiOnRamp.DestChainConfigSet(9999, EVM2EVMMultiOnRamp.DestChainConfig(0, IRouter(address(9999)))); + s_onRamp.applyDestChainConfigUpdates(configArgs); + assertEq(address(s_sourceRouter), address(s_onRamp.getRouter(DEST_CHAIN_SELECTOR))); + assertEq(address(9999), address(s_onRamp.getRouter(9999))); + + // handles empty list + uint256 numLogs = vm.getRecordedLogs().length; + configArgs = new EVM2EVMMultiOnRamp.DestChainConfigArgs[](0); + s_onRamp.applyDestChainConfigUpdates(configArgs); + assertEq(numLogs, vm.getRecordedLogs().length); // indicates no changes made + } + + function test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() external { + vm.stopPrank(); + vm.startPrank(OWNER); + EVM2EVMMultiOnRamp.DestChainConfigArgs[] memory configArgs = new EVM2EVMMultiOnRamp.DestChainConfigArgs[](1); + configArgs[0].destChainSelector = 0; // invalid + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOnRamp.InvalidDestChainConfig.selector, 0)); + s_onRamp.applyDestChainConfigUpdates(configArgs); + } +} diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol index f085185753..d237a23e8f 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.24; import {IPoolV1} from "../../interfaces/IPool.sol"; +import {IRouter} from "../../interfaces/IRouter.sol"; import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; import {NonceManager} from "../../NonceManager.sol"; @@ -38,7 +39,7 @@ contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistryFeeSetup { s_outboundMessageValidator = new MessageInterceptorHelper(); s_outboundNonceManager = new NonceManager(new address[](0)); (s_onRamp, s_metadataHash) = _deployOnRamp( - SOURCE_CHAIN_SELECTOR, address(s_sourceRouter), address(s_outboundNonceManager), address(s_tokenAdminRegistry) + SOURCE_CHAIN_SELECTOR, s_sourceRouter, address(s_outboundNonceManager), address(s_tokenAdminRegistry) ); s_offRamps = new address[](2); @@ -90,12 +91,12 @@ contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistryFeeSetup { ); } - function _generateDynamicMultiOnRampConfig( - address router, - address priceRegistry - ) internal pure returns (EVM2EVMMultiOnRamp.DynamicConfig memory) { + function _generateDynamicMultiOnRampConfig(address priceRegistry) + internal + pure + returns (EVM2EVMMultiOnRamp.DynamicConfig memory) + { return EVM2EVMMultiOnRamp.DynamicConfig({ - router: router, priceRegistry: priceRegistry, messageValidator: address(0), feeAggregator: FEE_AGGREGATOR @@ -111,9 +112,20 @@ contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistryFeeSetup { return result; } + function _generateDestChainConfigArgs(IRouter router) + internal + pure + returns (EVM2EVMMultiOnRamp.DestChainConfigArgs[] memory) + { + EVM2EVMMultiOnRamp.DestChainConfigArgs[] memory destChainConfigs = new EVM2EVMMultiOnRamp.DestChainConfigArgs[](1); + destChainConfigs[0] = + EVM2EVMMultiOnRamp.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, router: router}); + return destChainConfigs; + } + function _deployOnRamp( uint64 sourceChainSelector, - address sourceRouter, + IRouter router, address nonceManager, address tokenAdminRegistry ) internal returns (EVM2EVMMultiOnRampHelper, bytes32 metadataHash) { @@ -124,7 +136,8 @@ contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistryFeeSetup { nonceManager: nonceManager, tokenAdminRegistry: tokenAdminRegistry }), - _generateDynamicMultiOnRampConfig(sourceRouter, address(s_priceRegistry)) + _generateDynamicMultiOnRampConfig(address(s_priceRegistry)), + _generateDestChainConfigArgs(router) ); address[] memory authorizedCallers = new address[](1); @@ -174,7 +187,6 @@ contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistryFeeSetup { EVM2EVMMultiOnRamp.DynamicConfig memory a, EVM2EVMMultiOnRamp.DynamicConfig memory b ) internal pure { - assertEq(a.router, b.router); assertEq(a.priceRegistry, b.priceRegistry); } } diff --git a/core/capabilities/ccip/ccip_integration_tests/helpers.go b/core/capabilities/ccip/ccip_integration_tests/helpers.go index 7606c8bbeb..7792dfd361 100644 --- a/core/capabilities/ccip/ccip_integration_tests/helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/helpers.go @@ -200,12 +200,13 @@ func createUniverses( TokenAdminRegistry: tokenAdminRegistry.Address(), }, evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDynamicConfig{ - Router: rout.Address(), PriceRegistry: priceRegistry.Address(), // `withdrawFeeTokens` onRamp function is not part of the message flow // so we can set this to any address FeeAggregator: testutils.NewAddress(), }, + // Destination chain configs will be set up later once we have all chains + []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs{}, ) require.NoErrorf(t, err, "failed to deploy onramp on chain id %d", chainID) backend.Commit() @@ -225,7 +226,6 @@ func createUniverses( NonceManager: nonceManager.Address(), }, evm_2_evm_multi_offramp.EVM2EVMMultiOffRampDynamicConfig{ - Router: rout.Address(), PriceRegistry: priceRegistry.Address(), }, // Source chain configs will be set up later once we have all chains @@ -630,6 +630,7 @@ func connectUniverses( for _, uni := range universes { wireRouter(t, uni, universes) wirePriceRegistry(t, uni, universes) + wireOnRamp(t, uni, universes) wireOffRamp(t, uni, universes) initRemoteChainsGasPrices(t, uni, universes) } @@ -743,6 +744,24 @@ func wirePriceRegistry(t *testing.T, uni onchainUniverse, universes map[uint64]o uni.backend.Commit() } +// Setting OnRampDestChainConfigs +func wireOnRamp(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { + owner := uni.owner + var onrampSourceChainConfigArgs []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs + for remoteChainID := range universes { + if remoteChainID == uni.chainID { + continue + } + onrampSourceChainConfigArgs = append(onrampSourceChainConfigArgs, evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs{ + DestChainSelector: getSelector(remoteChainID), + Router: uni.router.Address(), + }) + } + _, err := uni.onramp.ApplyDestChainConfigUpdates(owner, onrampSourceChainConfigArgs) + require.NoErrorf(t, err, "failed to apply dest chain config updates on onramp with chain id %d", uni.chainID) + uni.backend.Commit() +} + // Setting OffRampSourceChainConfigs func wireOffRamp(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { owner := uni.owner @@ -752,8 +771,9 @@ func wireOffRamp(t *testing.T, uni onchainUniverse, universes map[uint64]onchain continue } offrampSourceChainConfigArgs = append(offrampSourceChainConfigArgs, evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{ - SourceChainSelector: getSelector(remoteChainID), // for each destination chain, add a source chain config + SourceChainSelector: getSelector(remoteChainID), IsEnabled: true, + Router: uni.router.Address(), OnRamp: remoteUniverse.onramp.Address().Bytes(), }) } diff --git a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go index fdef138528..9c49b3f882 100644 --- a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go +++ b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go @@ -47,6 +47,7 @@ type EVM2EVMMultiOffRampMerkleRoot struct { } type EVM2EVMMultiOffRampSourceChainConfig struct { + Router common.Address IsEnabled bool MinSeqNr uint64 OnRamp []byte @@ -94,8 +95,8 @@ type InternalTokenPriceUpdate struct { } var CCIPReaderTesterMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPSendRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b506110cc806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80634cf66e361461005c578063a65558f614610071578063e44302b714610084578063e9d68a8e14610097578063f831af81146100c0575b600080fd5b61006f61006a366004610462565b6100d3565b005b61006f61007f3660046106c7565b610128565b61006f610092366004610965565b61016d565b6100aa6100a5366004610acd565b6101a7565b6040516100b79190610b35565b60405180910390f35b61006f6100ce366004610b76565b610297565b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051610119929190610c1e565b60405180910390a45050505050565b816001600160401b03167f0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab29826040516101619190610d06565b60405180910390a25050565b7f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161019c9190610ec0565b60405180910390a150565b6040805160608082018352600080835260208084018290528385018390526001600160401b0386811683528282529185902085519384018652805460ff81161515855261010090049092169083015260018101805493949293919284019161020e90610f75565b80601f016020809104026020016040519081016040528092919081815260200182805461023a90610f75565b80156102875780601f1061025c57610100808354040283529160200191610287565b820191906000526020600020905b81548152906001019060200180831161026a57829003601f168201915b5050505050815250509050919050565b6001600160401b038281166000908152602081815260409182902084518154928601516001600160481b0319909316901515610100600160481b03191617610100929094169190910292909217825582015182919060018201906102fb9082611000565b5050505050565b80356001600160401b038116811461031957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156103565761035661031e565b60405290565b60405161010081016001600160401b03811182821017156103565761035661031e565b604080519081016001600160401b03811182821017156103565761035661031e565b604051606081016001600160401b03811182821017156103565761035661031e565b604051601f8201601f191681016001600160401b03811182821017156103eb576103eb61031e565b604052919050565b600082601f83011261040457600080fd5b81356001600160401b0381111561041d5761041d61031e565b610430601f8201601f19166020016103c3565b81815284602083860101111561044557600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561047a57600080fd5b61048386610302565b945061049160208701610302565b9350604086013592506060860135600481106104ac57600080fd5b915060808601356001600160401b038111156104c757600080fd5b6104d3888289016103f3565b9150509295509295909350565b600060a082840312156104f257600080fd5b60405160a081016001600160401b03811182821017156105145761051461031e565b6040528235815290508061052a60208401610302565b602082015261053b60408401610302565b604082015261054c60608401610302565b606082015261055d60808401610302565b60808201525092915050565b80356001600160a01b038116811461031957600080fd5b60006001600160401b038211156105995761059961031e565b5060051b60200190565b600082601f8301126105b457600080fd5b813560206105c96105c483610580565b6103c3565b82815260059290921b840181019181810190868411156105e857600080fd5b8286015b848110156106bc5780356001600160401b038082111561060c5760008081fd5b908801906080828b03601f19018113156106265760008081fd5b61062e610334565b87840135838111156106405760008081fd5b61064e8d8a838801016103f3565b825250604080850135848111156106655760008081fd5b6106738e8b838901016103f3565b8a840152506060808601358581111561068c5760008081fd5b61069a8f8c838a01016103f3565b92840192909252949092013593810193909352505083529183019183016105ec565b509695505050505050565b600080604083850312156106da57600080fd5b6106e383610302565b915060208301356001600160401b03808211156106ff57600080fd5b90840190610180828703121561071457600080fd5b61071c61035c565b61072687846104e0565b815261073460a08401610569565b602082015260c08301358281111561074b57600080fd5b610757888286016103f3565b60408301525060e08301358281111561076f57600080fd5b61077b888286016103f3565b6060830152506101008301358281111561079457600080fd5b6107a0888286016103f3565b6080830152506107b36101208401610569565b60a082015261014083013560c0820152610160830135828111156107d657600080fd5b6107e2888286016105a3565b60e0830152508093505050509250929050565b80356001600160e01b038116811461031957600080fd5b600082601f83011261081d57600080fd5b8135602061082d6105c483610580565b82815260069290921b8401810191818101908684111561084c57600080fd5b8286015b848110156106bc57604081890312156108695760008081fd5b61087161037f565b61087a82610302565b81526108878583016107f5565b81860152835291830191604001610850565b600082601f8301126108aa57600080fd5b813560206108ba6105c483610580565b82815260079290921b840181019181810190868411156108d957600080fd5b8286015b848110156106bc5780880360808112156108f75760008081fd5b6108ff6103a1565b61090883610302565b8152604080601f198401121561091e5760008081fd5b61092661037f565b9250610933878501610302565b8352610940818501610302565b83880152818701929092526060830135918101919091528352918301916080016108dd565b6000602080838503121561097857600080fd5b82356001600160401b038082111561098f57600080fd5b818501915060408083880312156109a557600080fd5b6109ad61037f565b8335838111156109bc57600080fd5b84016040818a0312156109ce57600080fd5b6109d661037f565b8135858111156109e557600080fd5b8201601f81018b136109f657600080fd5b8035610a046105c482610580565b81815260069190911b8201890190898101908d831115610a2357600080fd5b928a01925b82841015610a715787848f031215610a405760008081fd5b610a4861037f565b610a5185610569565b8152610a5e8c86016107f5565b818d0152825292870192908a0190610a28565b845250505081870135935084841115610a8957600080fd5b610a958a85840161080c565b8188015282525083850135915082821115610aaf57600080fd5b610abb88838601610899565b85820152809550505050505092915050565b600060208284031215610adf57600080fd5b610ae882610302565b9392505050565b6000815180845260005b81811015610b1557602081850181015186830182015201610af9565b506000602082860101526020601f19601f83011685010191505092915050565b6020815281511515602082015260018060401b03602083015116604082015260006040830151606080840152610b6e6080840182610aef565b949350505050565b60008060408385031215610b8957600080fd5b610b9283610302565b915060208301356001600160401b0380821115610bae57600080fd5b9084019060608287031215610bc257600080fd5b610bca6103a1565b82358015158114610bda57600080fd5b8152610be860208401610302565b6020820152604083013582811115610bff57600080fd5b610c0b888286016103f3565b6040830152508093505050509250929050565b600060048410610c3e57634e487b7160e01b600052602160045260246000fd5b83825260406020830152610b6e6040830184610aef565b6001600160a01b03169052565b600082825180855260208086019550808260051b84010181860160005b84811015610cf957601f19868403018952815160808151818652610ca582870182610aef565b9150508582015185820387870152610cbd8282610aef565b91505060408083015186830382880152610cd78382610aef565b6060948501519790940196909652505098840198925090830190600101610c7f565b5090979650505050505050565b60208152610d53602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b60006020830151610d6760c0840182610c55565b5060408301516101808060e0850152610d846101a0850183610aef565b91506060850151601f198086850301610100870152610da38483610aef565b9350608087015191508086850301610120870152610dc18483610aef565b935060a08701519150610dd8610140870183610c55565b60c087015161016087015260e0870151915080868503018387015250610dfe8382610c62565b9695505050505050565b60008151808452602080850194506020840160005b83811015610e5657815180516001600160401b031688528301516001600160e01b03168388015260409096019590820190600101610e1d565b509495945050505050565b600081518084526020808501945080840160005b83811015610e5657815180516001600160401b0390811689528482015180518216868b0152850151166040898101919091520151606088015260809096019590820190600101610e75565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b80831015610f2e57835180516001600160a01b031683528701516001600160e01b031687830152928601926001929092019190840190610ef3565b5093850151878503605f1901608089015293610f4a8186610e08565b945050505050818501519150601f19848203016040850152610f6c8183610e61565b95945050505050565b600181811c90821680610f8957607f821691505b602082108103610fa957634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610ffb576000816000526020600020601f850160051c81016020861015610fd85750805b601f850160051c820191505b81811015610ff757828155600101610fe4565b5050505b505050565b81516001600160401b038111156110195761101961031e565b61102d816110278454610f75565b84610faf565b602080601f831160018114611062576000841561104a5750858301515b600019600386901b1c1916600185901b178555610ff7565b600085815260208120601f198616915b8281101561109157888601518255948401946001909101908401611072565b50858210156110af5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPSendRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50611149806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80634cf66e361461005c578063a65558f614610071578063e44302b714610084578063e83eabba14610097578063e9d68a8e146100aa575b600080fd5b61006f61006a3660046104a7565b6100d3565b005b61006f61007f366004610718565b610128565b61006f6100923660046109b6565b61016d565b61006f6100a5366004610b20565b6101a7565b6100bd6100b8366004610bdb565b610233565b6040516100ca9190610c43565b60405180910390f35b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051610119929190610c9b565b60405180910390a45050505050565b816001600160401b03167f0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab29826040516101619190610d83565b60405180910390a25050565b7f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161019c9190610f3d565b60405180910390a150565b6001600160401b0380831660009081526020818152604091829020845181549286015193860151909416600160a81b02600160a81b600160e81b0319931515600160a01b026001600160a81b03199093166001600160a01b039095169490941791909117919091169190911781556060820151829190600182019061022c908261107d565b5050505050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b038781168452838352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b9092049092169483019490945260018401805493949293918401916102be90610ff2565b80601f01602080910402602001604051908101604052809291908181526020018280546102ea90610ff2565b80156103375780601f1061030c57610100808354040283529160200191610337565b820191906000526020600020905b81548152906001019060200180831161031a57829003601f168201915b5050505050815250509050919050565b80356001600160401b038116811461035e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b038111828210171561039b5761039b610363565b60405290565b60405161010081016001600160401b038111828210171561039b5761039b610363565b604080519081016001600160401b038111828210171561039b5761039b610363565b604051606081016001600160401b038111828210171561039b5761039b610363565b604051601f8201601f191681016001600160401b038111828210171561043057610430610363565b604052919050565b600082601f83011261044957600080fd5b81356001600160401b0381111561046257610462610363565b610475601f8201601f1916602001610408565b81815284602083860101111561048a57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a086880312156104bf57600080fd5b6104c886610347565b94506104d660208701610347565b9350604086013592506060860135600481106104f157600080fd5b915060808601356001600160401b0381111561050c57600080fd5b61051888828901610438565b9150509295509295909350565b600060a0828403121561053757600080fd5b60405160a081016001600160401b038111828210171561055957610559610363565b6040528235815290508061056f60208401610347565b602082015261058060408401610347565b604082015261059160608401610347565b60608201526105a260808401610347565b60808201525092915050565b6001600160a01b03811681146105c357600080fd5b50565b803561035e816105ae565b60006001600160401b038211156105ea576105ea610363565b5060051b60200190565b600082601f83011261060557600080fd5b8135602061061a610615836105d1565b610408565b82815260059290921b8401810191818101908684111561063957600080fd5b8286015b8481101561070d5780356001600160401b038082111561065d5760008081fd5b908801906080828b03601f19018113156106775760008081fd5b61067f610379565b87840135838111156106915760008081fd5b61069f8d8a83880101610438565b825250604080850135848111156106b65760008081fd5b6106c48e8b83890101610438565b8a84015250606080860135858111156106dd5760008081fd5b6106eb8f8c838a0101610438565b928401929092529490920135938101939093525050835291830191830161063d565b509695505050505050565b6000806040838503121561072b57600080fd5b61073483610347565b915060208301356001600160401b038082111561075057600080fd5b90840190610180828703121561076557600080fd5b61076d6103a1565b6107778784610525565b815261078560a084016105c6565b602082015260c08301358281111561079c57600080fd5b6107a888828601610438565b60408301525060e0830135828111156107c057600080fd5b6107cc88828601610438565b606083015250610100830135828111156107e557600080fd5b6107f188828601610438565b60808301525061080461012084016105c6565b60a082015261014083013560c08201526101608301358281111561082757600080fd5b610833888286016105f4565b60e0830152508093505050509250929050565b80356001600160e01b038116811461035e57600080fd5b600082601f83011261086e57600080fd5b8135602061087e610615836105d1565b82815260069290921b8401810191818101908684111561089d57600080fd5b8286015b8481101561070d57604081890312156108ba5760008081fd5b6108c26103c4565b6108cb82610347565b81526108d8858301610846565b818601528352918301916040016108a1565b600082601f8301126108fb57600080fd5b8135602061090b610615836105d1565b82815260079290921b8401810191818101908684111561092a57600080fd5b8286015b8481101561070d5780880360808112156109485760008081fd5b6109506103e6565b61095983610347565b8152604080601f198401121561096f5760008081fd5b6109776103c4565b9250610984878501610347565b8352610991818501610347565b838801528187019290925260608301359181019190915283529183019160800161092e565b600060208083850312156109c957600080fd5b82356001600160401b03808211156109e057600080fd5b818501915060408083880312156109f657600080fd5b6109fe6103c4565b833583811115610a0d57600080fd5b84016040818a031215610a1f57600080fd5b610a276103c4565b813585811115610a3657600080fd5b8201601f81018b13610a4757600080fd5b8035610a55610615826105d1565b81815260069190911b8201890190898101908d831115610a7457600080fd5b928a01925b82841015610ac45787848f031215610a915760008081fd5b610a996103c4565b8435610aa4816105ae565b8152610ab1858d01610846565b818d0152825292870192908a0190610a79565b845250505081870135935084841115610adc57600080fd5b610ae88a85840161085d565b8188015282525083850135915082821115610b0257600080fd5b610b0e888386016108ea565b85820152809550505050505092915050565b60008060408385031215610b3357600080fd5b610b3c83610347565b915060208301356001600160401b0380821115610b5857600080fd5b9084019060808287031215610b6c57600080fd5b610b74610379565b8235610b7f816105ae565b815260208301358015158114610b9457600080fd5b6020820152610ba560408401610347565b6040820152606083013582811115610bbc57600080fd5b610bc888828601610438565b6060830152508093505050509250929050565b600060208284031215610bed57600080fd5b610bf682610347565b9392505050565b6000815180845260005b81811015610c2357602081850181015186830182015201610c07565b506000602082860101526020601f19601f83011685010191505092915050565b602080825282516001600160a01b03168282015282015115156040808301919091528201516001600160401b0316606080830191909152820151608080830152600090610c9360a0840182610bfd565b949350505050565b600060048410610cbb57634e487b7160e01b600052602160045260246000fd5b83825260406020830152610c936040830184610bfd565b6001600160a01b03169052565b600082825180855260208086019550808260051b84010181860160005b84811015610d7657601f19868403018952815160808151818652610d2282870182610bfd565b9150508582015185820387870152610d3a8282610bfd565b91505060408083015186830382880152610d548382610bfd565b6060948501519790940196909652505098840198925090830190600101610cfc565b5090979650505050505050565b60208152610dd0602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b60006020830151610de460c0840182610cd2565b5060408301516101808060e0850152610e016101a0850183610bfd565b91506060850151601f198086850301610100870152610e208483610bfd565b9350608087015191508086850301610120870152610e3e8483610bfd565b935060a08701519150610e55610140870183610cd2565b60c087015161016087015260e0870151915080868503018387015250610e7b8382610cdf565b9695505050505050565b60008151808452602080850194506020840160005b83811015610ed357815180516001600160401b031688528301516001600160e01b03168388015260409096019590820190600101610e9a565b509495945050505050565b600081518084526020808501945080840160005b83811015610ed357815180516001600160401b0390811689528482015180518216868b0152850151166040898101919091520151606088015260809096019590820190600101610ef2565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b80831015610fab57835180516001600160a01b031683528701516001600160e01b031687830152928601926001929092019190840190610f70565b5093850151878503605f1901608089015293610fc78186610e85565b945050505050818501519150601f19848203016040850152610fe98183610ede565b95945050505050565b600181811c9082168061100657607f821691505b60208210810361102657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115611078576000816000526020600020601f850160051c810160208610156110555750805b601f850160051c820191505b8181101561107457828155600101611061565b5050505b505050565b81516001600160401b0381111561109657611096610363565b6110aa816110a48454610ff2565b8461102c565b602080601f8311600181146110df57600084156110c75750858301515b600019600386901b1c1916600185901b178555611074565b600085815260208120601f198616915b8281101561110e578886015182559484019460019091019084016110ef565b508582101561112c5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", } var CCIPReaderTesterABI = CCIPReaderTesterMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go index a61c4fde4b..a414481a3c 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go @@ -49,12 +49,11 @@ type EVM2EVMMultiOffRampCommitReport struct { } type EVM2EVMMultiOffRampDynamicConfig struct { - Router common.Address + PriceRegistry common.Address PermissionLessExecutionThresholdSeconds uint32 MaxTokenTransferGas uint32 MaxPoolReleaseOrMintGas uint32 MessageValidator common.Address - PriceRegistry common.Address } type EVM2EVMMultiOffRampInterval struct { @@ -69,12 +68,14 @@ type EVM2EVMMultiOffRampMerkleRoot struct { } type EVM2EVMMultiOffRampSourceChainConfig struct { + Router common.Address IsEnabled bool MinSeqNr uint64 OnRamp []byte } type EVM2EVMMultiOffRampSourceChainConfigArgs struct { + Router common.Address SourceChainSelector uint64 IsEnabled bool OnRamp []byte @@ -162,8 +163,8 @@ type MultiOCR3BaseOCRConfigArgs struct { } var EVM2EVMMultiOffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162006a8d38038062006a8d8339810160408190526200003591620008e2565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003fc565b50505062000c57565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60a08101516001600160a01b03161580620002c8575080516001600160a01b0316155b15620002e7576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b0319908116928e1692909217905560a0808e01805160068054909416908f161790925586519a8b5297518716988a0198909852925185169388019390935251909216958501959095525185169383019390935251909216908201527f0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c9060c00160405180910390a150565b60005b81518110156200064e57600082828151811062000420576200042062000a20565b60200260200101519050600081600001519050806001600160401b03166000036200045e5760405163c656089560e01b815260040160405180910390fd5b6001600160401b03811660009081526007602052604081206001810180549192916200048a9062000a36565b80601f0160208091040260200160405190810160405280929190818152602001828054620004b89062000a36565b8015620005095780601f10620004dd5761010080835404028352916020019162000509565b820191906000526020600020905b815481529060010190602001808311620004eb57829003601f168201915b505050505090506000846040015190508151600003620005ac57805160000362000546576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000556828262000ac7565b508254610100600160481b0319166101001783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005e7565b8080519060200120828051906020012014620005e75760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b6020850151835460ff19169015151783556040516001600160401b038516907f4f49973170c548fddd4a48341b75e131818913f38f44d47af57e8735eee588ba906200063590869062000b93565b60405180910390a25050505050806001019050620003ff565b5050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200068d576200068d62000652565b60405290565b604051608081016001600160401b03811182821017156200068d576200068d62000652565b60405160c081016001600160401b03811182821017156200068d576200068d62000652565b604051601f8201601f191681016001600160401b038111828210171562000708576200070862000652565b604052919050565b80516001600160401b03811681146200072857600080fd5b919050565b80516001600160a01b03811681146200072857600080fd5b805163ffffffff811681146200072857600080fd5b6000601f83601f8401126200076e57600080fd5b825160206001600160401b03808311156200078d576200078d62000652565b8260051b6200079e838201620006dd565b9384528681018301938381019089861115620007b957600080fd5b84890192505b85831015620008d557825184811115620007d95760008081fd5b89016060601f19828d038101821315620007f35760008081fd5b620007fd62000668565b6200080a89850162000710565b81526040808501518015158114620008225760008081fd5b828b01529284015192888411156200083a5760008081fd5b83850194508e603f8601126200085257600093508384fd5b898501519350888411156200086b576200086b62000652565b6200087c8a848e87011601620006dd565b92508383528e81858701011115620008945760008081fd5b60005b84811015620008b4578581018201518482018c01528a0162000897565b5060009383018a0193909352918201528352509184019190840190620007bf565b9998505050505050505050565b6000806000838503610160811215620008fa57600080fd5b60808112156200090957600080fd5b6200091362000693565b6200091e8662000710565b81526200092e602087016200072d565b602082015262000941604087016200072d565b604082015262000954606087016200072d565b6060820152935060c0607f19820112156200096e57600080fd5b5062000979620006b8565b62000987608086016200072d565b81526200099760a0860162000745565b6020820152620009aa60c0860162000745565b6040820152620009bd60e0860162000745565b6060820152620009d161010086016200072d565b6080820152620009e561012086016200072d565b60a08201526101408501519092506001600160401b0381111562000a0857600080fd5b62000a16868287016200075a565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4b57607f821691505b60208210810362000a6c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000ac2576000816000526020600020601f850160051c8101602086101562000a9d5750805b601f850160051c820191505b8181101562000abe5782815560010162000aa9565b5050505b505050565b81516001600160401b0381111562000ae35762000ae362000652565b62000afb8162000af4845462000a36565b8462000a72565b602080601f83116001811462000b33576000841562000b1a5750858301515b600019600386901b1c1916600185901b17855562000abe565b600085815260208120601f198616915b8281101562000b645788860151825594840194600190910190840162000b43565b508582101562000b835787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252825460ff811615158383015260081c6001600160401b0316604083015260608083015260018084018054600093929190849062000bd58162000a36565b80608089015260a0600183166000811462000bf9576001811462000c165762000c48565b60ff19841660a08b015260a083151560051b8b0101945062000c48565b85600052602060002060005b8481101562000c3f5781548c820185015290880190890162000c22565b8b0160a0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615dc762000cc66000396000818161023e0152612be801526000818161020f0152612ec20152600081816101e00152818161141801526114cf0152600081816101b001526127cc015260008181611caa0152611cf60152615dc76000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b146105ca578063f716f99f146105dd578063ff888fb1146105f057600080fd5b8063d2a15d3514610584578063e9d68a8e14610597578063ece670b6146105b757600080fd5b8063a12a9870116100bd578063a12a98701461050c578063c673e5841461051f578063ccd37ba31461053f57600080fd5b806385572ffb146104e35780638da5cb5b146104f157600080fd5b8063403b2d631161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104c85780637d4eef60146104d057600080fd5b8063403b2d63146103525780635e36480c1461036557600080fd5b80632d04ab76116101605780632d04ab761461030e578063311cd513146103235780633f4b04aa1461033657600080fd5b806306285c691461017c578063181f5a77146102c5575b600080fd5b61026e60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102bc9190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103016040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102bc9190613e34565b61032161031c366004613edf565b610613565b005b610321610331366004613f92565b6109d9565b600a5460405167ffffffffffffffff90911681526020016102bc565b61032161036036600461411b565b610a42565b6103786103733660046141ba565b610a56565b6040516102bc9190614217565b61045f6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c0810182526004546001600160a01b03808216835263ffffffff74010000000000000000000000000000000000000000830481166020850152780100000000000000000000000000000000000000000000000083048116948401949094527c010000000000000000000000000000000000000000000000000000000090910490921660608201526005548216608082015260065490911660a082015290565b6040516102bc9190600060c0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401528060a08501511660a08401525092915050565b610321610aac565b6103216104de36600461481b565b610b6a565b610321610177366004614946565b6000546040516001600160a01b0390911681526020016102bc565b61032161051a36600461499a565b610d0a565b61053261052d366004614ab4565b610d1b565b6040516102bc9190614b14565b61057661054d366004614b89565b67ffffffffffffffff919091166000908152600960209081526040808320938352929052205490565b6040519081526020016102bc565b610321610592366004614bb3565b610e79565b6105aa6105a5366004614c28565b610f33565b6040516102bc9190614c43565b6103216105c5366004614c7e565b61101c565b6103216105d8366004614ce2565b61136f565b6103216105eb366004614d67565b611380565b6106036105fe366004614ea5565b6113c2565b60405190151581526020016102bc565b600061062187890189615043565b8051515190915015158061063a57508051602001515115155b1561073a57600a5460208a01359067ffffffffffffffff808316911610156106f957600a805467ffffffffffffffff191667ffffffffffffffff831617905560065482516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921691633937306f916106c2916004016152ab565b600060405180830381600087803b1580156106dc57600080fd5b505af11580156106f0573d6000803e3d6000fd5b50505050610738565b816020015151600003610738576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b81602001515181101561092257600082602001518281518110610762576107626151ae565b6020026020010151905060008160000151905061077e81611483565b600061078982611585565b602084015151815491925067ffffffffffffffff908116610100909204161415806107cb575060208084015190810151905167ffffffffffffffff9182169116115b1561081457825160208401516040517feefb0cac00000000000000000000000000000000000000000000000000000000815261080b9291906004016152be565b60405180910390fd5b604083015180610850576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600960209081526040808320848452909152902054156108c35783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024810182905260440161080b565b60208085015101516108d6906001615309565b825468ffffffffffffffff00191661010067ffffffffffffffff92831602179092559251166000908152600960209081526040808320948352939052919091204290555060010161073d565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d816040516109529190615331565b60405180910390a16109ce60008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506115e5915050565b505050505050505050565b610a196109e8828401846153ce565b6040805160008082526020820190925290610a13565b60608152602001906001900390816109fe5790505b5061195c565b604080516000808252602082019092529050610a3c6001858585858660006115e5565b50505050565b610a4a611a0c565b610a5381611a68565b50565b6000610a6460016004615403565b6002610a7160808561542c565b67ffffffffffffffff16610a859190615453565b610a8f8585611c60565b901c166003811115610aa357610aa36141ed565b90505b92915050565b6001546001600160a01b03163314610b065760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161080b565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b72611ca7565b815181518114610bae576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610cfa576000848281518110610bcd57610bcd6151ae565b60200260200101519050600081602001515190506000858481518110610bf557610bf56151ae565b6020026020010151905080518214610c39576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610ceb576000828281518110610c5857610c586151ae565b6020026020010151905080600014610ce25784602001518281518110610c8057610c806151ae565b602002602001015160800151811015610ce25784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018390526044810182905260640161080b565b50600101610c3c565b50505050806001019050610bb1565b50610d05838361195c565b505050565b610d12611a0c565b610a5381611d28565b610d5e6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610e0757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610de9575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e6957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e4b575b5050505050815250509050919050565b610e81611a0c565b60005b81811015610d05576000838383818110610ea057610ea06151ae565b905060400201803603810190610eb6919061546a565b9050610ec581602001516113c2565b610f2a57805167ffffffffffffffff1660009081526009602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e84565b60408051606080820183526000808352602080840182905283850183905267ffffffffffffffff8681168352600782529185902085519384018652805460ff811615158552610100900490921690830152600181018054939492939192840191610f9c906154a3565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc8906154a3565b8015610e695780601f10610fea57610100808354040283529160200191610e69565b820191906000526020600020905b815481529060010190602001808311610ff857505050919092525091949350505050565b333014611055576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611092565b604080518082019091526000808252602082015281526020019060019003908161106b5790505b5060a084015151909150156110c5576110c28360a001518460200151856060015186600001516020015186611fb4565b90505b6040805160a0810182528451518152845160209081015167ffffffffffffffff1681830152808601518351600094840192611101929101613e34565b60408051601f19818403018152918152908252868101516020830152018390526005549091506001600160a01b0316801561120e576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a19061117b90859060040161557f565b600060405180830381600087803b15801561119557600080fd5b505af19250505080156111a6575060015b61120e573d8080156111d4576040519150601f19603f3d011682016040523d82523d6000602084013e6111d9565b606091505b50806040517f09c2532500000000000000000000000000000000000000000000000000000000815260040161080b9190613e34565b60408501515115801561122357506080850151155b8061123a575060608501516001600160a01b03163b155b8061127a57506060850151611278906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612092565b155b15611286575050505050565b60048054608087015160608801516040517f3cf9798300000000000000000000000000000000000000000000000000000000815260009485946001600160a01b031693633cf97983936112e1938a9361138893929101615592565b6000604051808303816000875af1158015611300573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261132891908101906155ce565b50915091508161136657806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161080b9190613e34565b50505050505050565b611377611a0c565b610a53816120ae565b611388611a0c565b60005b81518110156113be576113b68282815181106113a9576113a96151ae565b6020026020010151612164565b60010161138b565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa15801561145f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa69190615664565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561151e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115429190615664565b15610a53576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080b565b67ffffffffffffffff81166000908152600760205260408120805460ff16610aa6576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080b565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906116448760a4615681565b905082606001511561168c57845161165d906020615453565b865161166a906020615453565b6116759060a0615681565b61167f9190615681565b6116899082615681565b90505b3681146116ce576040517f8e1192e10000000000000000000000000000000000000000000000000000000081526004810182905236602482015260440161080b565b50815181146117165781516040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101919091526024810182905260440161080b565b61171e611ca7565b60ff808a166000908152600360209081526040808320338452825280832081518083019092528054808616835293949193909284019161010090910416600281111561176c5761176c6141ed565b600281111561177d5761177d6141ed565b905250905060028160200151600281111561179a5761179a6141ed565b1480156117ee5750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff16815481106117d6576117d66151ae565b6000918252602090912001546001600160a01b031633145b611824576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5081606001511561190657602082015161183f906001615694565b60ff1685511461187b576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83518551146118b6576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600087876040516118c89291906156ad565b6040519081900381206118df918b906020016156bd565b6040516020818303038152906040528051906020012090506119048a828888886124a8565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611996576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611a05576119fd8582815181106119cb576119cb6151ae565b6020026020010151846119f7578583815181106119ea576119ea6151ae565b60200260200101516126bf565b836126bf565b6001016119ad565b5050505050565b6000546001600160a01b03163314611a665760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161080b565b565b60a08101516001600160a01b03161580611a8a575080516001600160a01b0316155b15611ac1576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a177401000000000000000000000000000000000000000063ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16939093177c010000000000000000000000000000000000000000000000000000000093871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff19908116928e1692909217905560a0808e01805160068054909416908f161790925586519a8b5297518716988a0198909852925185169388019390935251909216958501959095525185169383019390935251909216908201527f0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c9060c00160405180910390a150565b67ffffffffffffffff8216600090815260086020526040812081611c856080856156d1565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f000000000000000000000000000000000000000000000000000000000000000014611a66576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015246602482015260440161080b565b60005b81518110156113be576000828281518110611d4857611d486151ae565b602002602001015190506000816000015190508067ffffffffffffffff16600003611d9f576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600760205260408120600181018054919291611dca906154a3565b80601f0160208091040260200160405190810160405280929190818152602001828054611df6906154a3565b8015611e435780601f10611e1857610100808354040283529160200191611e43565b820191906000526020600020905b815481529060010190602001808311611e2657829003601f168201915b505050505090506000846040015190508151600003611efc578051600003611e97576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018301611ea58282615740565b50825468ffffffffffffffff00191661010017835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611f4f565b8080519060200120828051906020012014611f4f576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8516600482015260240161080b565b6020850151835460ff191690151517835560405167ffffffffffffffff8516907f4f49973170c548fddd4a48341b75e131818913f38f44d47af57e8735eee588ba90611f9c908690615800565b60405180910390a25050505050806001019050611d2b565b6060855167ffffffffffffffff811115611fd057611fd0613fe6565b60405190808252806020026020018201604052801561201557816020015b6040805180820190915260008082526020820152815260200190600190039081611fee5790505b50905060005b865181101561208857612063878281518110612039576120396151ae565b6020026020010151878787878681518110612056576120566151ae565b6020026020010151612e61565b828281518110612075576120756151ae565b602090810291909101015260010161201b565b5095945050505050565b600061209d83613270565b8015610aa35750610aa383836132d4565b336001600160a01b038216036121065760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161080b565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff1660000361218f576000604051631b3fab5160e11b815260040161080b91906158bc565b60208082015160ff808216600090815260029093526040832060018101549293909283921690036121fc57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612251565b6060840151600182015460ff6201000090910416151590151514612251576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff8416600482015260240161080b565b60a08401518051601f60ff82161115612280576001604051631b3fab5160e11b815260040161080b91906158bc565b6122e685856003018054806020026020016040519081016040528092919081815260200182805480156122dc57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122be575b50505050506133a3565b8560600151156124155761235485856002018054806020026020016040519081016040528092919081815260200182805480156122dc576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122be5750505050506133a3565b6080860151805161236e9060028701906020840190613d3e565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f10156123ce576002604051631b3fab5160e11b815260040161080b91906158bc565b60408801516123de9060036158d6565b60ff168160ff1611612406576003604051631b3fab5160e11b815260040161080b91906158bc565b6124128783600161340c565b50505b6124218583600261340c565b81516124369060038601906020850190613d3e565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f5479361248f938a939260028b019291906158f2565b60405180910390a16124a08561358c565b505050505050565b6124b0613db0565b835160005b818110156126b55760006001888684602081106124d4576124d46151ae565b6124e191901a601b615694565b8985815181106124f3576124f36151ae565b602002602001015189868151811061250d5761250d6151ae565b60200260200101516040516000815260200160405260405161254b949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561256d573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b038516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156125ce576125ce6141ed565b60028111156125df576125df6141ed565b90525090506001816020015160028111156125fc576125fc6141ed565b14612633576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061264a5761264a6151ae565b602002015115612686576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126a1576126a16151ae565b9115156020909202015250506001016124b5565b5050505050505050565b81516126ca81611483565b60006126d582611585565b6020850151519091506000819003612718576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151518114612756576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561277157612771613fe6565b60405190808252806020026020018201604052801561279a578160200160208202803683370190505b50905060005b8281101561290f576000876020015182815181106127c0576127c06151ae565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461285357805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161080b565b6128e981866001018054612866906154a3565b80601f0160208091040260200160405190810160405280929190818152602001828054612892906154a3565b80156128df5780601f106128b4576101008083540402835291602001916128df565b820191906000526020600020905b8154815290600101906020018083116128c257829003601f168201915b50505050506135a8565b8383815181106128fb576128fb6151ae565b6020908102919091010152506001016127a0565b506000612926858389606001518a608001516136ca565b90508060000361296e576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015260240161080b565b8551151560005b848110156109ce57600089602001518281518110612995576129956151ae565b6020026020010151905060006129b389836000015160600151610a56565b905060008160038111156129c9576129c96141ed565b14806129e6575060038160038111156129e4576129e46141ed565b145b612a3d578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612e59565b8315612b1e5760045460009074010000000000000000000000000000000000000000900463ffffffff16612a718742615403565b1190508080612a9157506003826003811115612a8f57612a8f6141ed565b145b612ad3576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b16600482015260240161080b565b8a8481518110612ae557612ae56151ae565b6020026020010151600014612b18578a8481518110612b0657612b066151ae565b60200260200101518360800181815250505b50612b7f565b6000816003811115612b3257612b326141ed565b14612b7f578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612a2e565b81516080015167ffffffffffffffff1615612c6d576000816003811115612ba857612ba86141ed565b03612c6d5781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c1f928e929190600401615978565b6020604051808303816000875af1158015612c3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c629190615664565b612c6d575050612e59565b60008b604001518481518110612c8557612c856151ae565b6020026020010151905080518360a001515114612ce9578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d166004830152909116602482015260440161080b565b612cfd8a8460000151606001516001613720565b600080612d0a85846137c8565b91509150612d218c86600001516060015184613720565b8615612d91576003826003811115612d3b57612d3b6141ed565b03612d91576000846003811115612d5457612d546141ed565b14612d91578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261080b919083906004016159a5565b6002826003811115612da557612da56141ed565b14612dff576003826003811115612dbe57612dbe6141ed565b14612dff578451606001516040517f926c5a3e00000000000000000000000000000000000000000000000000000000815261080b918e9185906004016159be565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612e4b90879087906159e4565b60405180910390a450505050505b600101612975565b60408051808201909152600080825260208201526000612e848760200151613892565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f2d9190615a04565b90506001600160a01b0381161580612f755750612f736001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612092565b155b15612fb7576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b038216600482015260240161080b565b6000806130bd6040518061010001604052808b81526020018967ffffffffffffffff1681526020018a6001600160a01b031681526020018c606001518152602001866001600160a01b031681526020018c6000015181526020018c6040015181526020018881525060405160240161302f9190615a21565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3907753700000000000000000000000000000000000000000000000000000000179052600454859063ffffffff7c0100000000000000000000000000000000000000000000000000000000909104166113886084613938565b5091509150816130fb57806040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161080b9190613e34565b80516020146131435780516040517f78ef802400000000000000000000000000000000000000000000000000000000815260206004820152602481019190915260440161080b565b6000818060200190518101906131599190615af8565b6040516001600160a01b038b166024820152604481018290529091506132069060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600454879063ffffffff7801000000000000000000000000000000000000000000000000909104166113886084613938565b5090935091508261324557816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161080b9190613e34565b604080518082019091526001600160a01b039095168552602085015250919250505095945050505050565b600061329c827f01ffc9a7000000000000000000000000000000000000000000000000000000006132d4565b8015610aa657506132cd827fffffffff000000000000000000000000000000000000000000000000000000006132d4565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561338c575060208210155b80156133985750600081115b979650505050505050565b60005b8151811015610d055760ff8316600090815260036020526040812083519091908490849081106133d8576133d86151ae565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff191690556001016133a6565b60005b82518160ff161015610a3c576000838260ff1681518110613432576134326151ae565b602002602001015190506000600281111561344f5761344f6141ed565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561348e5761348e6141ed565b146134af576004604051631b3fab5160e11b815260040161080b91906158bc565b6001600160a01b0381166134ef576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff168152602001846002811115613515576135156141ed565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff191617610100836002811115613572576135726141ed565b0217905550905050508061358590615b11565b905061340f565b60ff8116610a5357600a805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936135ee937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615b30565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976136379794969395929491939101615b63565b604051602081830303815290604052805190602001208560400151805190602001208660a0015160405160200161366e9190615c5a565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b6000806136d8858585613a5e565b90506136e3816113c2565b6136f1576000915050613718565b67ffffffffffffffff86166000908152600960209081526040808320938352929052205490505b949350505050565b6000600261372f60808561542c565b67ffffffffffffffff166137439190615453565b905060006137518585611c60565b90508161376060016004615403565b901b191681836003811115613777576137776141ed565b67ffffffffffffffff871660009081526008602052604081209190921b929092179182916137a66080886156d1565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b69061380c9087908790600401615cba565b600060405180830381600087803b15801561382657600080fd5b505af1925050508015613837575060015b613876573d808015613865576040519150601f19603f3d011682016040523d82523d6000602084013e61386a565b606091505b5060039250905061388b565b50506040805160208101909152600081526002905b9250929050565b600081516020146138d157816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161080b9190613e34565b6000828060200190518101906138e79190615af8565b90506001600160a01b038111806138ff575061040081105b15610aa657826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161080b9190613e34565b6000606060008361ffff1667ffffffffffffffff81111561395b5761395b613fe6565b6040519080825280601f01601f191660200182016040528015613985576020820181803683370190505b509150863b6139b8577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a858110156139eb577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613a24577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613a475750835b808352806000602085013e50955095509592505050565b8251825160009190818303613a9f576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613ab357506101018111155b613ad0576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613afa576040516309bde33960e01b815260040160405180910390fd5b80600003613b275786600081518110613b1557613b156151ae565b60200260200101519350505050613cf6565b60008167ffffffffffffffff811115613b4257613b42613fe6565b604051908082528060200260200182016040528015613b6b578160200160208202803683370190505b50905060008080805b85811015613c955760006001821b8b811603613bcf5788851015613bb8578c5160018601958e918110613ba957613ba96151ae565b60200260200101519050613bf1565b8551600185019487918110613ba957613ba96151ae565b8b5160018401938d918110613be657613be66151ae565b602002602001015190505b600089861015613c21578d5160018701968f918110613c1257613c126151ae565b60200260200101519050613c43565b8651600186019588918110613c3857613c386151ae565b602002602001015190505b82851115613c64576040516309bde33960e01b815260040160405180910390fd5b613c6e8282613cfd565b878481518110613c8057613c806151ae565b60209081029190910101525050600101613b74565b506001850382148015613ca757508683145b8015613cb257508581145b613ccf576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613ce457613ce46151ae565b60200260200101519750505050505050505b9392505050565b6000818310613d1557613d108284613d1b565b610aa3565b610aa383835b6040805160016020820152908101839052606081018290526000906080016136ac565b828054828255906000526020600020908101928215613da0579160200282015b82811115613da0578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613d5e565b50613dac929150613dcf565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613dac5760008155600101613dd0565b60005b83811015613dff578181015183820152602001613de7565b50506000910152565b60008151808452613e20816020860160208601613de4565b601f01601f19169290920160200192915050565b602081526000610aa36020830184613e08565b8060608101831015610aa657600080fd5b60008083601f840112613e6a57600080fd5b50813567ffffffffffffffff811115613e8257600080fd5b60208301915083602082850101111561388b57600080fd5b60008083601f840112613eac57600080fd5b50813567ffffffffffffffff811115613ec457600080fd5b6020830191508360208260051b850101111561388b57600080fd5b60008060008060008060008060e0898b031215613efb57600080fd5b613f058a8a613e47565b9750606089013567ffffffffffffffff80821115613f2257600080fd5b613f2e8c838d01613e58565b909950975060808b0135915080821115613f4757600080fd5b613f538c838d01613e9a565b909750955060a08b0135915080821115613f6c57600080fd5b50613f798b828c01613e9a565b999c989b50969995989497949560c00135949350505050565b600080600060808486031215613fa757600080fd5b613fb18585613e47565b9250606084013567ffffffffffffffff811115613fcd57600080fd5b613fd986828701613e58565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff8111828210171561401f5761401f613fe6565b60405290565b60405160a0810167ffffffffffffffff8111828210171561401f5761401f613fe6565b6040516080810167ffffffffffffffff8111828210171561401f5761401f613fe6565b6040516060810167ffffffffffffffff8111828210171561401f5761401f613fe6565b6040805190810167ffffffffffffffff8111828210171561401f5761401f613fe6565b604051601f8201601f1916810167ffffffffffffffff811182821017156140da576140da613fe6565b604052919050565b6001600160a01b0381168114610a5357600080fd5b8035614102816140e2565b919050565b803563ffffffff8116811461410257600080fd5b600060c0828403121561412d57600080fd5b614135613ffc565b8235614140816140e2565b815261414e60208401614107565b602082015261415f60408401614107565b604082015261417060608401614107565b60608201526080830135614183816140e2565b608082015260a0830135614196816140e2565b60a08201529392505050565b803567ffffffffffffffff8116811461410257600080fd5b600080604083850312156141cd57600080fd5b6141d6836141a2565b91506141e4602084016141a2565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614213576142136141ed565b9052565b60208101610aa68284614203565b600067ffffffffffffffff82111561423f5761423f613fe6565b5060051b60200190565b600060a0828403121561425b57600080fd5b614263614025565b905081358152614275602083016141a2565b6020820152614286604083016141a2565b6040820152614297606083016141a2565b60608201526142a8608083016141a2565b608082015292915050565b600067ffffffffffffffff8211156142cd576142cd613fe6565b50601f01601f191660200190565b600082601f8301126142ec57600080fd5b81356142ff6142fa826142b3565b6140b1565b81815284602083860101111561431457600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261434257600080fd5b813560206143526142fa83614225565b82815260059290921b8401810191818101908684111561437157600080fd5b8286015b8481101561444757803567ffffffffffffffff808211156143965760008081fd5b8189019150608080601f19848d030112156143b15760008081fd5b6143b9614048565b87840135838111156143cb5760008081fd5b6143d98d8a838801016142db565b825250604080850135848111156143f05760008081fd5b6143fe8e8b838901016142db565b8a84015250606080860135858111156144175760008081fd5b6144258f8c838a01016142db565b9284019290925294909201359381019390935250508352918301918301614375565b509695505050505050565b6000610140828403121561446557600080fd5b61446d613ffc565b90506144798383614249565b815260a082013567ffffffffffffffff8082111561449657600080fd5b6144a2858386016142db565b602084015260c08401359150808211156144bb57600080fd5b6144c7858386016142db565b60408401526144d860e085016140f7565b606084015261010084013560808401526101208401359150808211156144fd57600080fd5b5061450a84828501614331565b60a08301525092915050565b600082601f83011261452757600080fd5b813560206145376142fa83614225565b82815260059290921b8401810191818101908684111561455657600080fd5b8286015b8481101561444757803567ffffffffffffffff81111561457a5760008081fd5b6145888986838b0101614452565b84525091830191830161455a565b600082601f8301126145a757600080fd5b813560206145b76142fa83614225565b82815260059290921b840181019181810190868411156145d657600080fd5b8286015b8481101561444757803567ffffffffffffffff8111156145fa5760008081fd5b6146088986838b01016142db565b8452509183019183016145da565b600082601f83011261462757600080fd5b813560206146376142fa83614225565b82815260059290921b8401810191818101908684111561465657600080fd5b8286015b8481101561444757803567ffffffffffffffff81111561467a5760008081fd5b6146888986838b0101614596565b84525091830191830161465a565b600082601f8301126146a757600080fd5b813560206146b76142fa83614225565b8083825260208201915060208460051b8701019350868411156146d957600080fd5b602086015b8481101561444757803583529183019183016146de565b600082601f83011261470657600080fd5b813560206147166142fa83614225565b82815260059290921b8401810191818101908684111561473557600080fd5b8286015b8481101561444757803567ffffffffffffffff8082111561475a5760008081fd5b818901915060a080601f19848d030112156147755760008081fd5b61477d614025565b6147888885016141a2565b81526040808501358481111561479e5760008081fd5b6147ac8e8b83890101614516565b8a84015250606080860135858111156147c55760008081fd5b6147d38f8c838a0101614616565b83850152506080915081860135858111156147ee5760008081fd5b6147fc8f8c838a0101614696565b9184019190915250919093013590830152508352918301918301614739565b600080604080848603121561482f57600080fd5b833567ffffffffffffffff8082111561484757600080fd5b614853878388016146f5565b945060209150818601358181111561486a57600080fd5b8601601f8101881361487b57600080fd5b80356148896142fa82614225565b81815260059190911b8201840190848101908a8311156148a857600080fd5b8584015b83811015614934578035868111156148c45760008081fd5b8501603f81018d136148d65760008081fd5b878101356148e66142fa82614225565b81815260059190911b82018a0190898101908f8311156149065760008081fd5b928b01925b828410156149245783358252928a0192908a019061490b565b86525050509186019186016148ac565b50809750505050505050509250929050565b60006020828403121561495857600080fd5b813567ffffffffffffffff81111561496f57600080fd5b820160a08185031215613cf657600080fd5b8015158114610a5357600080fd5b803561410281614981565b600060208083850312156149ad57600080fd5b823567ffffffffffffffff808211156149c557600080fd5b818501915085601f8301126149d957600080fd5b81356149e76142fa82614225565b81815260059190911b83018401908481019088831115614a0657600080fd5b8585015b83811015614a9657803585811115614a225760008081fd5b86016060818c03601f1901811315614a3a5760008081fd5b614a4261406b565b614a4d8a84016141a2565b8152604080840135614a5e81614981565b828c0152918301359188831115614a755760008081fd5b614a838e8c858701016142db565b9082015285525050918601918601614a0a565b5098975050505050505050565b803560ff8116811461410257600080fd5b600060208284031215614ac657600080fd5b610aa382614aa3565b60008151808452602080850194506020840160005b83811015614b095781516001600160a01b031687529582019590820190600101614ae4565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614b6360e0840182614acf565b90506040840151601f198483030160c0850152614b808282614acf565b95945050505050565b60008060408385031215614b9c57600080fd5b614ba5836141a2565b946020939093013593505050565b60008060208385031215614bc657600080fd5b823567ffffffffffffffff80821115614bde57600080fd5b818501915085601f830112614bf257600080fd5b813581811115614c0157600080fd5b8660208260061b8501011115614c1657600080fd5b60209290920196919550909350505050565b600060208284031215614c3a57600080fd5b610aa3826141a2565b6020815281511515602082015267ffffffffffffffff6020830151166040820152600060408301516060808401526137186080840182613e08565b60008060408385031215614c9157600080fd5b823567ffffffffffffffff80821115614ca957600080fd5b614cb586838701614452565b93506020850135915080821115614ccb57600080fd5b50614cd885828601614596565b9150509250929050565b600060208284031215614cf457600080fd5b8135613cf6816140e2565b600082601f830112614d1057600080fd5b81356020614d206142fa83614225565b8083825260208201915060208460051b870101935086841115614d4257600080fd5b602086015b84811015614447578035614d5a816140e2565b8352918301918301614d47565b60006020808385031215614d7a57600080fd5b823567ffffffffffffffff80821115614d9257600080fd5b818501915085601f830112614da657600080fd5b8135614db46142fa82614225565b81815260059190911b83018401908481019088831115614dd357600080fd5b8585015b83811015614a9657803585811115614dee57600080fd5b860160c0818c03601f19011215614e055760008081fd5b614e0d613ffc565b8882013581526040614e20818401614aa3565b8a8301526060614e31818501614aa3565b8284015260809150614e4482850161498f565b9083015260a08381013589811115614e5c5760008081fd5b614e6a8f8d83880101614cff565b838501525060c0840135915088821115614e845760008081fd5b614e928e8c84870101614cff565b9083015250845250918601918601614dd7565b600060208284031215614eb757600080fd5b5035919050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461410257600080fd5b600082601f830112614efb57600080fd5b81356020614f0b6142fa83614225565b82815260069290921b84018101918181019086841115614f2a57600080fd5b8286015b848110156144475760408189031215614f475760008081fd5b614f4f61408e565b614f58826141a2565b8152614f65858301614ebe565b81860152835291830191604001614f2e565b600082601f830112614f8857600080fd5b81356020614f986142fa83614225565b82815260079290921b84018101918181019086841115614fb757600080fd5b8286015b84811015614447578088036080811215614fd55760008081fd5b614fdd61406b565b614fe6836141a2565b8152604080601f1984011215614ffc5760008081fd5b61500461408e565b92506150118785016141a2565b835261501e8185016141a2565b8388015281870192909252606083013591810191909152835291830191608001614fbb565b6000602080838503121561505657600080fd5b823567ffffffffffffffff8082111561506e57600080fd5b8185019150604080838803121561508457600080fd5b61508c61408e565b83358381111561509b57600080fd5b84016040818a0312156150ad57600080fd5b6150b561408e565b8135858111156150c457600080fd5b8201601f81018b136150d557600080fd5b80356150e36142fa82614225565b81815260069190911b8201890190898101908d83111561510257600080fd5b928a01925b828410156151525787848f03121561511f5760008081fd5b61512761408e565b8435615132816140e2565b815261513f858d01614ebe565b818d0152825292870192908a0190615107565b84525050508187013593508484111561516a57600080fd5b6151768a858401614eea565b818801528252508385013591508282111561519057600080fd5b61519c88838601614f77565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561523057835180516001600160a01b031684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168584015292840192918501916001016151e4565b50508583015187820388850152805180835290840192506000918401905b8083101561529f578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168583015292840192600192909201919085019061524e565b50979650505050505050565b602081526000610aa360208301846151c4565b67ffffffffffffffff8316815260608101613cf66020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561532a5761532a6152f3565b5092915050565b60006020808352606084516040808487015261535060608701836151c4565b87850151878203601f19016040890152805180835290860193506000918601905b80831015614a9657845167ffffffffffffffff8151168352878101516153b089850182805167ffffffffffffffff908116835260209182015116910152565b50840151828701529386019360019290920191608090910190615371565b6000602082840312156153e057600080fd5b813567ffffffffffffffff8111156153f757600080fd5b613718848285016146f5565b81810381811115610aa657610aa66152f3565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff8084168061544757615447615416565b92169190910692915050565b8082028115828204841417610aa657610aa66152f3565b60006040828403121561547c57600080fd5b61548461408e565b61548d836141a2565b8152602083013560208201528091505092915050565b600181811c908216806154b757607f821691505b6020821081036154d757634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261551160a0870182613e08565b90506060850151868203606088015261552a8282613e08565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561529f57835180516001600160a01b031683528601518683015292850192600192909201919084019061554d565b602081526000610aa360208301846154dd565b6080815260006155a560808301876154dd565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b6000806000606084860312156155e357600080fd5b83516155ee81614981565b602085015190935067ffffffffffffffff81111561560b57600080fd5b8401601f8101861361561c57600080fd5b805161562a6142fa826142b3565b81815287602083850101111561563f57600080fd5b615650826020830160208601613de4565b809450505050604084015190509250925092565b60006020828403121561567657600080fd5b8151613cf681614981565b80820180821115610aa657610aa66152f3565b60ff8181168382160190811115610aa657610aa66152f3565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff808416806156ec576156ec615416565b92169190910492915050565b601f821115610d05576000816000526020600020601f850160051c810160208610156157215750805b601f850160051c820191505b818110156124a05782815560010161572d565b815167ffffffffffffffff81111561575a5761575a613fe6565b61576e8161576884546154a3565b846156f8565b602080601f8311600181146157a3576000841561578b5750858301515b600019600386901b1c1916600185901b1785556124a0565b600085815260208120601f198616915b828110156157d2578886015182559484019460019091019084016157b3565b50858210156157f05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020808352835460ff81161515602085015267ffffffffffffffff8160081c16604085015250600180850160608086015260008154615840816154a3565b80608089015260a06001831660008114615861576001811461587d576158ad565b60ff19841660a08b015260a083151560051b8b010194506158ad565b85600052602060002060005b848110156158a45781548c8201850152908801908901615889565b8b0160a0019550505b50929998505050505050505050565b60208101600583106158d0576158d06141ed565b91905290565b60ff818116838216029081169081811461532a5761532a6152f3565b600060a0820160ff88168352602087602085015260a0604085015281875480845260c086019150886000526020600020935060005b8181101561594c5784546001600160a01b031683526001948501949284019201615927565b505084810360608601526159608188614acf565b935050505060ff831660808301529695505050505050565b600067ffffffffffffffff808616835280851660208401525060606040830152614b806060830184613e08565b8281526040602082015260006137186040830184613e08565b67ffffffffffffffff848116825283166020820152606081016137186040830184614203565b6159ee8184614203565b6040602082015260006137186040830184613e08565b600060208284031215615a1657600080fd5b8151613cf6816140e2565b6020815260008251610100806020850152615a40610120850183613e08565b91506020850151615a5d604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615a9760a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615ab48483613e08565b935060c08701519150808685030160e0870152615ad18483613e08565b935060e0870151915080868503018387015250615aee8382613e08565b9695505050505050565b600060208284031215615b0a57600080fd5b5051919050565b600060ff821660ff8103615b2757615b276152f3565b60010192915050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152615aee6080830184613e08565b86815260c060208201526000615b7c60c0830188613e08565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615c4d57601f19868403018952815160808151818652615bf982870182613e08565b9150508582015185820387870152615c118282613e08565b91505060408083015186830382880152615c2b8382613e08565b6060948501519790940196909652505098840198925090830190600101615bd3565b5090979650505050505050565b602081526000610aa36020830184615bb6565b60008282518085526020808601955060208260051b8401016020860160005b84811015615c4d57601f19868403018952615ca8838351613e08565b98840198925090830190600101615c8c565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615d22610180850183613e08565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615d5f8483613e08565b935060608801519150615d7e6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615da58282615bb6565b9150508281036020840152614b808185615c6d56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162006bab38038062006bab8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615ed562000cd6600039600081816102530152612cac0152600081816102240152612f860152600081816101f50152818161147b01526118d00152600081816101c501526128a1015260008181611e5e0152611eaa0152615ed56000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b1461059c578063f716f99f146105af578063ff888fb1146105c257600080fd5b8063d2a15d3514610556578063e9d68a8e14610569578063ece670b61461058957600080fd5b8063991a5018116100bd578063991a5018146104de578063c673e584146104f1578063ccd37ba31461051157600080fd5b806385572ffb146104b55780638da5cb5b146104c357600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba50971461049a5780637d4eef60146104a257600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a366004614091565b6105e5565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d19190614200565b61018f6103313660046142ab565b6105f9565b61018f61034436600461435e565b6109fd565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143b2565b610a66565b6040516102d1919061440f565b61043d6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b830481166020850152780100000000000000000000000000000000000000000000000083048116948401949094527c01000000000000000000000000000000000000000000000000000000009091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610abc565b61018f6104b036600461497c565b610b7a565b61018f610177366004614aa7565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104ec366004614af6565b610d1a565b6105046104ff366004614b7b565b610d2b565b6040516102d19190614bdb565b61054861051f366004614c50565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f610564366004614c7a565b610e89565b61057c610577366004614cef565b610f43565b6040516102d19190614d0a565b61018f610597366004614d58565b611062565b61018f6105aa366004614dbc565b6113d2565b61018f6105bd366004614e41565b6113e3565b6105d56105d0366004614f7f565b611425565b60405190151581526020016102d1565b6105ed6114e6565b6105f681611542565b50565b60006106078789018961511d565b8051515190915015158061062057508051602001515115155b156107205760095460208a01359067ffffffffffffffff808316911610156106df576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f926106a8929101615385565b600060405180830381600087803b1580156106c257600080fd5b505af11580156106d6573d6000803e3d6000fd5b5050505061071e565b81602001515160000361071e576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109465760008260200151828151811061074857610748615288565b6020026020010151905060008160000151905061076481611884565b600061076f82611986565b602084015151815491925067ffffffffffffffff9081167501000000000000000000000000000000000000000000909204161415806107c5575060208084015190810151905167ffffffffffffffff9182169116115b1561080e57825160208401516040517feefb0cac000000000000000000000000000000000000000000000000000000008152610805929190600401615398565b60405180910390fd5b60408301518061084a576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108bd5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101829052604401610805565b60208085015101516108d09060016153e3565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000067ffffffffffffffff928316021790925592511660009081526008602090815260408083209483529390529190912042905550600101610723565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610976919061540b565b60405180910390a16109f260008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506119ed915050565b505050505050505050565b610a3d610a0c828401846154a8565b6040805160008082526020820190925290610a37565b6060815260200190600190039081610a225790505b50611d64565b604080516000808252602082019092529050610a606001858585858660006119ed565b50505050565b6000610a74600160046154dd565b6002610a81608085615506565b67ffffffffffffffff16610a95919061552d565b610a9f8585611e14565b901c166003811115610ab357610ab36143e5565b90505b92915050565b6001546001600160a01b03163314610b165760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610805565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b82611e5b565b815181518114610bbe576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d0a576000848281518110610bdd57610bdd615288565b60200260200101519050600081602001515190506000858481518110610c0557610c05615288565b6020026020010151905080518214610c49576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cfb576000828281518110610c6857610c68615288565b6020026020010151905080600014610cf25784602001518281518110610c9057610c90615288565b602002602001015160800151811015610cf25784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024810183905260448101829052606401610805565b50600101610c4c565b50505050806001019050610bc1565b50610d158383611d64565b505050565b610d226114e6565b6105f681611edc565b610d6e6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610e1757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610df9575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e7957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e5b575b5050505050815250509050919050565b610e916114e6565b60005b81811015610d15576000838383818110610eb057610eb0615288565b905060400201803603810190610ec69190615544565b9050610ed58160200151611425565b610f3a57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e94565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff161515938601939093527501000000000000000000000000000000000000000000909204909216948301949094526001840180549394929391840191610fe29061557d565b80601f016020809104026020016040519081016040528092919081815260200182805461100e9061557d565b8015610e795780601f1061103057610100808354040283529160200191610e79565b820191906000526020600020905b81548152906001019060200180831161103e57505050919092525091949350505050565b33301461109b576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600080825260208201909252816110d8565b60408051808201909152600080825260208201528152602001906001900390816110b15790505b5060a0840151519091501561110b576111088360a001518460200151856060015186600001516020015186612089565b90505b6040805160a0810182528451518152845160209081015167ffffffffffffffff1681830152808601518351600094840192611147929101614200565b60408051601f19818403018152918152908252868101516020830152018390526005549091506001600160a01b03168015611254576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a1906111c1908590600401615659565b600060405180830381600087803b1580156111db57600080fd5b505af19250505080156111ec575060015b611254573d80801561121a576040519150601f19603f3d011682016040523d82523d6000602084013e61121f565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016108059190614200565b60408501515115801561126957506080850151155b80611280575060608501516001600160a01b03163b155b806112c0575060608501516112be906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612167565b155b156112cc575050505050565b845160209081015167ffffffffffffffff16600090815260069091526040808220546080880151606089015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf9798392611344928992611388929160040161566c565b6000604051808303816000875af1158015611363573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261138b91908101906156a8565b5091509150816113c957806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016108059190614200565b50505050505050565b6113da6114e6565b6105f681612183565b6113eb6114e6565b60005b81518110156114215761141982828151811061140c5761140c615288565b6020026020010151612239565b6001016113ee565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156114c2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab6919061573e565b6000546001600160a01b031633146115405760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610805565b565b60005b815181101561142157600082828151811061156257611562615288565b602002602001015190506000816020015190508067ffffffffffffffff166000036115b9576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b03166115fa576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916116259061557d565b80601f01602080910402602001604051908101604052809291908181526020018280546116519061557d565b801561169e5780601f106116735761010080835404028352916020019161169e565b820191906000526020600020905b81548152906001019060200180831161168157829003601f168201915b5050505050905060008460600151905081516000036117815780516000036116f2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001830161170082826157a3565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000017835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16117d4565b80805190602001208280519060200120146117d4576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610805565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b9061186c908690615863565b60405180910390a25050505050806001019050611545565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561191f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611943919061573e565b156105f6576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610805565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610ab6576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610805565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611a4c8760a4615931565b9050826060015115611a94578451611a6590602061552d565b8651611a7290602061552d565b611a7d9060a0615931565b611a879190615931565b611a919082615931565b90505b368114611ad6576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610805565b5081518114611b1e5781516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610805565b611b26611e5b565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611b7457611b746143e5565b6002811115611b8557611b856143e5565b9052509050600281602001516002811115611ba257611ba26143e5565b148015611bf65750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611bde57611bde615288565b6000918252602090912001546001600160a01b031633145b611c2c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611d0e576020820151611c47906001615944565b60ff16855114611c83576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611cbe576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611cd092919061595d565b604051908190038120611ce7918b9060200161596d565b604051602081830303815290604052805190602001209050611d0c8a8288888861257d565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d9e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611e0d57611e05858281518110611dd357611dd3615288565b602002602001015184611dff57858381518110611df257611df2615288565b6020026020010151612794565b83612794565b600101611db5565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611e39608085615981565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f000000000000000000000000000000000000000000000000000000000000000014611540576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610805565b80516001600160a01b0316611f1d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16939093177c010000000000000000000000000000000000000000000000000000000093871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060855167ffffffffffffffff8111156120a5576120a5613ea8565b6040519080825280602002602001820160405280156120ea57816020015b60408051808201909152600080825260208201528152602001906001900390816120c35790505b50905060005b865181101561215d5761213887828151811061210e5761210e615288565b602002602001015187878787868151811061212b5761212b615288565b6020026020010151612f25565b82828151811061214a5761214a615288565b60209081029190910101526001016120f0565b5095945050505050565b600061217283613334565b8015610ab35750610ab38383613398565b336001600160a01b038216036121db5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610805565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff16600003612264576000604051631b3fab5160e11b815260040161080591906159a8565b60208082015160ff808216600090815260029093526040832060018101549293909283921690036122d157606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612326565b6060840151600182015460ff6201000090910416151590151514612326576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff84166004820152602401610805565b60a08401518051601f60ff82161115612355576001604051631b3fab5160e11b815260040161080591906159a8565b6123bb85856003018054806020026020016040519081016040528092919081815260200182805480156123b157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612393575b5050505050613467565b8560600151156124ea5761242985856002018054806020026020016040519081016040528092919081815260200182805480156123b1576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311612393575050505050613467565b608086015180516124439060028701906020840190613e02565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f10156124a3576002604051631b3fab5160e11b815260040161080591906159a8565b60408801516124b39060036159c2565b60ff168160ff16116124db576003604051631b3fab5160e11b815260040161080591906159a8565b6124e7878360016134d0565b50505b6124f6858360026134d0565b815161250b9060038601906020850190613e02565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f54793612564938a939260028b019291906159de565b60405180910390a161257585613650565b505050505050565b612585613e74565b835160005b8181101561278a5760006001888684602081106125a9576125a9615288565b6125b691901a601b615944565b8985815181106125c8576125c8615288565b60200260200101518986815181106125e2576125e2615288565b602002602001015160405160008152602001604052604051612620949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612642573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b038516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156126a3576126a36143e5565b60028111156126b4576126b46143e5565b90525090506001816020015160028111156126d1576126d16143e5565b14612708576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061271f5761271f615288565b60200201511561275b576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061277657612776615288565b91151560209092020152505060010161258a565b5050505050505050565b815161279f81611884565b60006127aa82611986565b60208501515190915060008190036127ed576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461282b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561284657612846613ea8565b60405190808252806020026020018201604052801561286f578160200160208202803683370190505b50905060005b828110156129e45760008760200151828151811061289557612895615288565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461292857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610805565b6129be8186600101805461293b9061557d565b80601f01602080910402602001604051908101604052809291908181526020018280546129679061557d565b80156129b45780601f10612989576101008083540402835291602001916129b4565b820191906000526020600020905b81548152906001019060200180831161299757829003601f168201915b505050505061366c565b8383815181106129d0576129d0615288565b602090810291909101015250600101612875565b5060006129fb858389606001518a6080015161378e565b905080600003612a43576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610805565b8551151560005b848110156109f257600089602001518281518110612a6a57612a6a615288565b602002602001015190506000612a8889836000015160600151610a66565b90506000816003811115612a9e57612a9e6143e5565b1480612abb57506003816003811115612ab957612ab96143e5565b145b612b12578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612f1d565b8315612be257600454600090600160a01b900463ffffffff16612b3587426154dd565b1190508080612b5557506003826003811115612b5357612b536143e5565b145b612b97576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b166004820152602401610805565b8a8481518110612ba957612ba9615288565b6020026020010151600014612bdc578a8481518110612bca57612bca615288565b60200260200101518360800181815250505b50612c43565b6000816003811115612bf657612bf66143e5565b14612c43578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612b03565b81516080015167ffffffffffffffff1615612d31576000816003811115612c6c57612c6c6143e5565b03612d315781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612ce3928e929190600401615a90565b6020604051808303816000875af1158015612d02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d26919061573e565b612d31575050612f1d565b60008b604001518481518110612d4957612d49615288565b6020026020010151905080518360a001515114612dad578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d1660048301529091166024820152604401610805565b612dc18a84600001516060015160016137e4565b600080612dce858461388c565b91509150612de58c866000015160600151846137e4565b8615612e55576003826003811115612dff57612dff6143e5565b03612e55576000846003811115612e1857612e186143e5565b14612e55578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261080591908390600401615abd565b6002826003811115612e6957612e696143e5565b14612ec3576003826003811115612e8257612e826143e5565b14612ec3578451606001516040517f926c5a3e000000000000000000000000000000000000000000000000000000008152610805918e918590600401615ad6565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612f0f9087908790615afc565b60405180910390a450505050505b600101612a4a565b60408051808201909152600080825260208201526000612f488760200151613956565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612fcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ff19190615b1c565b90506001600160a01b038116158061303957506130376001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612167565b155b1561307b576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610805565b6000806131816040518061010001604052808b81526020018967ffffffffffffffff1681526020018a6001600160a01b031681526020018c606001518152602001866001600160a01b031681526020018c6000015181526020018c604001518152602001888152506040516024016130f39190615b39565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3907753700000000000000000000000000000000000000000000000000000000179052600454859063ffffffff7c01000000000000000000000000000000000000000000000000000000009091041661138860846139fc565b5091509150816131bf57806040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016108059190614200565b80516020146132075780516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610805565b60008180602001905181019061321d9190615c06565b6040516001600160a01b038b166024820152604481018290529091506132ca9060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600454879063ffffffff78010000000000000000000000000000000000000000000000009091041661138860846139fc565b5090935091508261330957816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016108059190614200565b604080518082019091526001600160a01b039095168552602085015250919250505095945050505050565b6000613360827f01ffc9a700000000000000000000000000000000000000000000000000000000613398565b8015610ab65750613391827fffffffff00000000000000000000000000000000000000000000000000000000613398565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613450575060208210155b801561345c5750600081115b979650505050505050565b60005b8151811015610d155760ff83166000908152600360205260408120835190919084908490811061349c5761349c615288565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161346a565b60005b82518160ff161015610a60576000838260ff16815181106134f6576134f6615288565b6020026020010151905060006002811115613513576135136143e5565b60ff80871660009081526003602090815260408083206001600160a01b03871684529091529020546101009004166002811115613552576135526143e5565b14613573576004604051631b3fab5160e11b815260040161080591906159a8565b6001600160a01b0381166135b3576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156135d9576135d96143e5565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff191617610100836002811115613636576136366143e5565b0217905550905050508061364990615c1f565b90506134d3565b60ff81166105f6576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936136b2937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c3e565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976136fb9794969395929491939101615c71565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016137329190615d68565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061379c858585613b22565b90506137a781611425565b6137b55760009150506137dc565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026137f3608085615506565b67ffffffffffffffff16613807919061552d565b905060006138158585611e14565b905081613824600160046154dd565b901b19168183600381111561383b5761383b6143e5565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161386a608088615981565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906138d09087908790600401615dc8565b600060405180830381600087803b1580156138ea57600080fd5b505af19250505080156138fb575060015b61393a573d808015613929576040519150601f19603f3d011682016040523d82523d6000602084013e61392e565b606091505b5060039250905061394f565b50506040805160208101909152600081526002905b9250929050565b6000815160201461399557816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016108059190614200565b6000828060200190518101906139ab9190615c06565b90506001600160a01b038111806139c3575061040081105b15610ab657826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016108059190614200565b6000606060008361ffff1667ffffffffffffffff811115613a1f57613a1f613ea8565b6040519080825280601f01601f191660200182016040528015613a49576020820181803683370190505b509150863b613a7c577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613aaf577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613ae8577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b0b5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b63576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b7757506101018111155b613b94576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bbe576040516309bde33960e01b815260040160405180910390fd5b80600003613beb5786600081518110613bd957613bd9615288565b60200260200101519350505050613dba565b60008167ffffffffffffffff811115613c0657613c06613ea8565b604051908082528060200260200182016040528015613c2f578160200160208202803683370190505b50905060008080805b85811015613d595760006001821b8b811603613c935788851015613c7c578c5160018601958e918110613c6d57613c6d615288565b60200260200101519050613cb5565b8551600185019487918110613c6d57613c6d615288565b8b5160018401938d918110613caa57613caa615288565b602002602001015190505b600089861015613ce5578d5160018701968f918110613cd657613cd6615288565b60200260200101519050613d07565b8651600186019588918110613cfc57613cfc615288565b602002602001015190505b82851115613d28576040516309bde33960e01b815260040160405180910390fd5b613d328282613dc1565b878481518110613d4457613d44615288565b60209081029190910101525050600101613c38565b506001850382148015613d6b57508683145b8015613d7657508581145b613d93576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613da857613da8615288565b60200260200101519750505050505050505b9392505050565b6000818310613dd957613dd48284613ddf565b610ab3565b610ab383835b604080516001602082015290810183905260608101829052600090608001613770565b828054828255906000526020600020908101928215613e64579160200282015b82811115613e64578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e22565b50613e70929150613e93565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e705760008155600101613e94565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613ee157613ee1613ea8565b60405290565b60405160a0810167ffffffffffffffff81118282101715613ee157613ee1613ea8565b60405160c0810167ffffffffffffffff81118282101715613ee157613ee1613ea8565b6040805190810167ffffffffffffffff81118282101715613ee157613ee1613ea8565b6040516060810167ffffffffffffffff81118282101715613ee157613ee1613ea8565b604051601f8201601f1916810167ffffffffffffffff81118282101715613f9c57613f9c613ea8565b604052919050565b600067ffffffffffffffff821115613fbe57613fbe613ea8565b5060051b60200190565b6001600160a01b03811681146105f657600080fd5b803567ffffffffffffffff81168114613ff557600080fd5b919050565b80151581146105f657600080fd5b8035613ff581613ffa565b600067ffffffffffffffff82111561402d5761402d613ea8565b50601f01601f191660200190565b600082601f83011261404c57600080fd5b813561405f61405a82614013565b613f73565b81815284602083860101111561407457600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140a457600080fd5b823567ffffffffffffffff808211156140bc57600080fd5b818501915085601f8301126140d057600080fd5b81356140de61405a82613fa4565b81815260059190911b830184019084810190888311156140fd57600080fd5b8585015b838110156141a3578035858111156141195760008081fd5b86016080818c03601f19018113156141315760008081fd5b614139613ebe565b8983013561414681613fc8565b81526040614155848201613fdd565b8b83015260608085013561416881613ffa565b8383015292840135928984111561418157600091508182fd5b61418f8f8d8688010161403b565b908301525085525050918601918601614101565b5098975050505050505050565b60005b838110156141cb5781810151838201526020016141b3565b50506000910152565b600081518084526141ec8160208601602086016141b0565b601f01601f19169290920160200192915050565b602081526000610ab360208301846141d4565b8060608101831015610ab657600080fd5b60008083601f84011261423657600080fd5b50813567ffffffffffffffff81111561424e57600080fd5b60208301915083602082850101111561394f57600080fd5b60008083601f84011261427857600080fd5b50813567ffffffffffffffff81111561429057600080fd5b6020830191508360208260051b850101111561394f57600080fd5b60008060008060008060008060e0898b0312156142c757600080fd5b6142d18a8a614213565b9750606089013567ffffffffffffffff808211156142ee57600080fd5b6142fa8c838d01614224565b909950975060808b013591508082111561431357600080fd5b61431f8c838d01614266565b909750955060a08b013591508082111561433857600080fd5b506143458b828c01614266565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561437357600080fd5b61437d8585614213565b9250606084013567ffffffffffffffff81111561439957600080fd5b6143a586828701614224565b9497909650939450505050565b600080604083850312156143c557600080fd5b6143ce83613fdd565b91506143dc60208401613fdd565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061440b5761440b6143e5565b9052565b60208101610ab682846143fb565b600060a0828403121561442f57600080fd5b614437613ee7565b90508135815261444960208301613fdd565b602082015261445a60408301613fdd565b604082015261446b60608301613fdd565b606082015261447c60808301613fdd565b608082015292915050565b8035613ff581613fc8565b600082601f8301126144a357600080fd5b813560206144b361405a83613fa4565b82815260059290921b840181019181810190868411156144d257600080fd5b8286015b848110156145a857803567ffffffffffffffff808211156144f75760008081fd5b8189019150608080601f19848d030112156145125760008081fd5b61451a613ebe565b878401358381111561452c5760008081fd5b61453a8d8a8388010161403b565b825250604080850135848111156145515760008081fd5b61455f8e8b8389010161403b565b8a84015250606080860135858111156145785760008081fd5b6145868f8c838a010161403b565b92840192909252949092013593810193909352505083529183019183016144d6565b509695505050505050565b600061014082840312156145c657600080fd5b6145ce613f0a565b90506145da838361441d565b815260a082013567ffffffffffffffff808211156145f757600080fd5b6146038583860161403b565b602084015260c084013591508082111561461c57600080fd5b6146288583860161403b565b604084015261463960e08501614487565b6060840152610100840135608084015261012084013591508082111561465e57600080fd5b5061466b84828501614492565b60a08301525092915050565b600082601f83011261468857600080fd5b8135602061469861405a83613fa4565b82815260059290921b840181019181810190868411156146b757600080fd5b8286015b848110156145a857803567ffffffffffffffff8111156146db5760008081fd5b6146e98986838b01016145b3565b8452509183019183016146bb565b600082601f83011261470857600080fd5b8135602061471861405a83613fa4565b82815260059290921b8401810191818101908684111561473757600080fd5b8286015b848110156145a857803567ffffffffffffffff81111561475b5760008081fd5b6147698986838b010161403b565b84525091830191830161473b565b600082601f83011261478857600080fd5b8135602061479861405a83613fa4565b82815260059290921b840181019181810190868411156147b757600080fd5b8286015b848110156145a857803567ffffffffffffffff8111156147db5760008081fd5b6147e98986838b01016146f7565b8452509183019183016147bb565b600082601f83011261480857600080fd5b8135602061481861405a83613fa4565b8083825260208201915060208460051b87010193508684111561483a57600080fd5b602086015b848110156145a8578035835291830191830161483f565b600082601f83011261486757600080fd5b8135602061487761405a83613fa4565b82815260059290921b8401810191818101908684111561489657600080fd5b8286015b848110156145a857803567ffffffffffffffff808211156148bb5760008081fd5b818901915060a080601f19848d030112156148d65760008081fd5b6148de613ee7565b6148e9888501613fdd565b8152604080850135848111156148ff5760008081fd5b61490d8e8b83890101614677565b8a84015250606080860135858111156149265760008081fd5b6149348f8c838a0101614777565b838501525060809150818601358581111561494f5760008081fd5b61495d8f8c838a01016147f7565b918401919091525091909301359083015250835291830191830161489a565b600080604080848603121561499057600080fd5b833567ffffffffffffffff808211156149a857600080fd5b6149b487838801614856565b94506020915081860135818111156149cb57600080fd5b8601601f810188136149dc57600080fd5b80356149ea61405a82613fa4565b81815260059190911b8201840190848101908a831115614a0957600080fd5b8584015b83811015614a9557803586811115614a255760008081fd5b8501603f81018d13614a375760008081fd5b87810135614a4761405a82613fa4565b81815260059190911b82018a0190898101908f831115614a675760008081fd5b928b01925b82841015614a855783358252928a0192908a0190614a6c565b8652505050918601918601614a0d565b50809750505050505050509250929050565b600060208284031215614ab957600080fd5b813567ffffffffffffffff811115614ad057600080fd5b820160a08185031215613dba57600080fd5b803563ffffffff81168114613ff557600080fd5b600060a08284031215614b0857600080fd5b614b10613ee7565b8235614b1b81613fc8565b8152614b2960208401614ae2565b6020820152614b3a60408401614ae2565b6040820152614b4b60608401614ae2565b60608201526080830135614b5e81613fc8565b60808201529392505050565b803560ff81168114613ff557600080fd5b600060208284031215614b8d57600080fd5b610ab382614b6a565b60008151808452602080850194506020840160005b83811015614bd05781516001600160a01b031687529582019590820190600101614bab565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c2a60e0840182614b96565b90506040840151601f198483030160c0850152614c478282614b96565b95945050505050565b60008060408385031215614c6357600080fd5b614c6c83613fdd565b946020939093013593505050565b60008060208385031215614c8d57600080fd5b823567ffffffffffffffff80821115614ca557600080fd5b818501915085601f830112614cb957600080fd5b813581811115614cc857600080fd5b8660208260061b8501011115614cdd57600080fd5b60209290920196919550909350505050565b600060208284031215614d0157600080fd5b610ab382613fdd565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526137dc60a08401826141d4565b60008060408385031215614d6b57600080fd5b823567ffffffffffffffff80821115614d8357600080fd5b614d8f868387016145b3565b93506020850135915080821115614da557600080fd5b50614db2858286016146f7565b9150509250929050565b600060208284031215614dce57600080fd5b8135613dba81613fc8565b600082601f830112614dea57600080fd5b81356020614dfa61405a83613fa4565b8083825260208201915060208460051b870101935086841115614e1c57600080fd5b602086015b848110156145a8578035614e3481613fc8565b8352918301918301614e21565b60006020808385031215614e5457600080fd5b823567ffffffffffffffff80821115614e6c57600080fd5b818501915085601f830112614e8057600080fd5b8135614e8e61405a82613fa4565b81815260059190911b83018401908481019088831115614ead57600080fd5b8585015b838110156141a357803585811115614ec857600080fd5b860160c0818c03601f19011215614edf5760008081fd5b614ee7613f0a565b8882013581526040614efa818401614b6a565b8a8301526060614f0b818501614b6a565b8284015260809150614f1e828501614008565b9083015260a08381013589811115614f365760008081fd5b614f448f8d83880101614dd9565b838501525060c0840135915088821115614f5e5760008081fd5b614f6c8e8c84870101614dd9565b9083015250845250918601918601614eb1565b600060208284031215614f9157600080fd5b5035919050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114613ff557600080fd5b600082601f830112614fd557600080fd5b81356020614fe561405a83613fa4565b82815260069290921b8401810191818101908684111561500457600080fd5b8286015b848110156145a857604081890312156150215760008081fd5b615029613f2d565b61503282613fdd565b815261503f858301614f98565b81860152835291830191604001615008565b600082601f83011261506257600080fd5b8135602061507261405a83613fa4565b82815260079290921b8401810191818101908684111561509157600080fd5b8286015b848110156145a85780880360808112156150af5760008081fd5b6150b7613f50565b6150c083613fdd565b8152604080601f19840112156150d65760008081fd5b6150de613f2d565b92506150eb878501613fdd565b83526150f8818501613fdd565b8388015281870192909252606083013591810191909152835291830191608001615095565b6000602080838503121561513057600080fd5b823567ffffffffffffffff8082111561514857600080fd5b8185019150604080838803121561515e57600080fd5b615166613f2d565b83358381111561517557600080fd5b84016040818a03121561518757600080fd5b61518f613f2d565b81358581111561519e57600080fd5b8201601f81018b136151af57600080fd5b80356151bd61405a82613fa4565b81815260069190911b8201890190898101908d8311156151dc57600080fd5b928a01925b8284101561522c5787848f0312156151f95760008081fd5b615201613f2d565b843561520c81613fc8565b8152615219858d01614f98565b818d0152825292870192908a01906151e1565b84525050508187013593508484111561524457600080fd5b6152508a858401614fc4565b818801528252508385013591508282111561526a57600080fd5b61527688838601615051565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561530a57835180516001600160a01b031684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168584015292840192918501916001016152be565b50508583015187820388850152805180835290840192506000918401905b80831015615379578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685830152928401926001929092019190850190615328565b50979650505050505050565b602081526000610ab3602083018461529e565b67ffffffffffffffff8316815260608101613dba6020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff818116838216019080821115615404576154046153cd565b5092915050565b60006020808352606084516040808487015261542a606087018361529e565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141a357845167ffffffffffffffff81511683528781015161548a89850182805167ffffffffffffffff908116835260209182015116910152565b5084015182870152938601936001929092019160809091019061544b565b6000602082840312156154ba57600080fd5b813567ffffffffffffffff8111156154d157600080fd5b6137dc84828501614856565b81810381811115610ab657610ab66153cd565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff80841680615521576155216154f0565b92169190910692915050565b8082028115828204841417610ab657610ab66153cd565b60006040828403121561555657600080fd5b61555e613f2d565b61556783613fdd565b8152602083013560208201528091505092915050565b600181811c9082168061559157607f821691505b6020821081036155b157634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a060408701526155eb60a08701826141d4565b90506060850151868203606088015261560482826141d4565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561537957835180516001600160a01b0316835286015186830152928501926001929092019190840190615627565b602081526000610ab360208301846155b7565b60808152600061567f60808301876155b7565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b6000806000606084860312156156bd57600080fd5b83516156c881613ffa565b602085015190935067ffffffffffffffff8111156156e557600080fd5b8401601f810186136156f657600080fd5b805161570461405a82614013565b81815287602083850101111561571957600080fd5b61572a8260208301602086016141b0565b809450505050604084015190509250925092565b60006020828403121561575057600080fd5b8151613dba81613ffa565b601f821115610d15576000816000526020600020601f850160051c810160208610156157845750805b601f850160051c820191505b8181101561257557828155600101615790565b815167ffffffffffffffff8111156157bd576157bd613ea8565b6157d1816157cb845461557d565b8461575b565b602080601f83116001811461580657600084156157ee5750858301515b600019600386901b1c1916600185901b178555612575565b600085815260208120601f198616915b8281101561583557888601518255948401946001909101908401615816565b50858210156158535787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546158b58161557d565b8060a089015260c060018316600081146158d657600181146158f257615922565b60ff19841660c08b015260c083151560051b8b01019450615922565b85600052602060002060005b848110156159195781548c82018501529088019089016158fe565b8b0160c0019550505b50929998505050505050505050565b80820180821115610ab657610ab66153cd565b60ff8181168382160190811115610ab657610ab66153cd565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061599c5761599c6154f0565b92169190910492915050565b60208101600583106159bc576159bc6143e5565b91905290565b60ff8181168382160290811690818114615404576154046153cd565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a365784546001600160a01b031683526001948501949284019201615a11565b50508481036060860152865180825290820192508187019060005b81811015615a765782516001600160a01b031685529383019391830191600101615a51565b50505060ff851660808501525090505b9695505050505050565b600067ffffffffffffffff808616835280851660208401525060606040830152614c4760608301846141d4565b8281526040602082015260006137dc60408301846141d4565b67ffffffffffffffff848116825283166020820152606081016137dc60408301846143fb565b615b0681846143fb565b6040602082015260006137dc60408301846141d4565b600060208284031215615b2e57600080fd5b8151613dba81613fc8565b6020815260008251610100806020850152615b586101208501836141d4565b91506020850151615b75604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615baf60a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bcc84836141d4565b935060c08701519150808685030160e0870152615be984836141d4565b935060e0870151915080868503018387015250615a8683826141d4565b600060208284031215615c1857600080fd5b5051919050565b600060ff821660ff8103615c3557615c356153cd565b60010192915050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152615a8660808301846141d4565b86815260c060208201526000615c8a60c08301886141d4565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d5b57601f19868403018952815160808151818652615d07828701826141d4565b9150508582015185820387870152615d1f82826141d4565b91505060408083015186830382880152615d3983826141d4565b6060948501519790940196909652505098840198925090830190600101615ce1565b5090979650505050505050565b602081526000610ab36020830184615cc4565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d5b57601f19868403018952615db68383516141d4565b98840198925090830190600101615d9a565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e306101808501836141d4565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e6d84836141d4565b935060608801519150615e8c6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615eb38282615cc4565b9150508281036020840152614c478185615d7b56fea164736f6c6343000818000a", } var EVM2EVMMultiOffRampABI = EVM2EVMMultiOffRampMetaData.ABI @@ -2327,7 +2328,7 @@ func (EVM2EVMMultiOffRampConfigSet) Topic() common.Hash { } func (EVM2EVMMultiOffRampDynamicConfigSet) Topic() common.Hash { - return common.HexToHash("0x0da37fd00459f4f5f0b8210d31525e4910ae674b8bab34b561d146bb45773a4c") + return common.HexToHash("0xa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d") } func (EVM2EVMMultiOffRampExecutionStateChanged) Topic() common.Hash { @@ -2351,7 +2352,7 @@ func (EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) Topic() common.Hash { } func (EVM2EVMMultiOffRampSourceChainConfigSet) Topic() common.Hash { - return common.HexToHash("0x4f49973170c548fddd4a48341b75e131818913f38f44d47af57e8735eee588ba") + return common.HexToHash("0x49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b") } func (EVM2EVMMultiOffRampSourceChainSelectorAdded) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go index 7b6971d5ec..b3cbed0be5 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go @@ -43,8 +43,17 @@ type ClientEVMTokenAmount struct { Amount *big.Int } +type EVM2EVMMultiOnRampDestChainConfig struct { + SequenceNumber uint64 + Router common.Address +} + +type EVM2EVMMultiOnRampDestChainConfigArgs struct { + DestChainSelector uint64 + Router common.Address +} + type EVM2EVMMultiOnRampDynamicConfig struct { - Router common.Address PriceRegistry common.Address MessageValidator common.Address FeeAggregator common.Address @@ -84,15 +93,15 @@ type InternalRampTokenAmount struct { } var EVM2EVMMultiOnRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162003161380380620031618339810160408190526200003591620003db565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf816200017a565b505082516001600160401b031615905080620000e6575060208201516001600160a01b0316155b80620000fd575060408201516001600160a01b0316155b8062000114575060608201516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b81516001600160401b031660805260208201516001600160a01b0390811660a0526040830151811660c05260608301511660e052620001728162000225565b5050620004d1565b336001600160a01b03821603620001d45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60208101516001600160a01b031615806200024b575060608101516001600160a01b0316155b156200026a576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b0393841617909155602080840180516003805485169186169190911790556040808601805160048054871691881691909117905560608088018051600580549098169089161790965582516080808201855280516001600160401b031680835260a080518b16848a0190815260c080518d16868a0190815260e080518f169789019788528a5195865292518e169b85019b909b5299518c169783019790975292518a169381019390935289518916908301529351871693810193909352518516928201929092529151909216918101919091527f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32906101000160405180910390a150565b604051608081016001600160401b0381118282101715620003b857634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b0381168114620003d657600080fd5b919050565b600080828403610100811215620003f157600080fd5b60808112156200040057600080fd5b6200040a62000387565b84516001600160401b03811681146200042257600080fd5b81526200043260208601620003be565b60208201526200044560408601620003be565b60408201526200045860608601620003be565b606082015292506080607f19820112156200047257600080fd5b506200047d62000387565b6200048b60808501620003be565b81526200049b60a08501620003be565b6020820152620004ae60c08501620003be565b6040820152620004c160e08501620003be565b6060820152809150509250929050565b60805160a05160c05160e051612c176200054a600039600081816101c00152818161081b015261147901526000818161018401528181610d3801526114520152600081816101480152818161044e015261142801526000818161011801528181610c55015281816110ee01526113fb0152612c176000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806379ba50971161008c578063a6f3ab6c11610066578063a6f3ab6c14610391578063df0aa9e9146103a4578063f2fde38b146103b7578063fbca3b74146103ca57600080fd5b806379ba50971461033f5780638da5cb5b146103475780639041be3d1461036557600080fd5b80633a019940116100bd5780633a0199401461027d57806348a98aa4146102875780637437ff9f146102bf57600080fd5b806306285c69146100e4578063181f5a771461021357806320487ded1461025c575b600080fd5b6101fd60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161020a9190611cf8565b60405180910390f35b61024f6040518060400160405280601c81526020017f45564d3245564d4d756c74694f6e52616d7020312e362e302d6465760000000081525081565b60405161020a9190611dbd565b61026f61026a366004611dfe565b6103ea565b60405190815260200161020a565b6102856105a3565b005b61029a610295366004611e70565b6107d3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161020a565b610332604080516080810182526000808252602082018190529181018290526060810191909152506040805160808101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454811692820192909252600554909116606082015290565b60405161020a9190611ea9565b610285610888565b60005473ffffffffffffffffffffffffffffffffffffffff1661029a565b610378610373366004611ef2565b610985565b60405167ffffffffffffffff909116815260200161020a565b61028561039f366004611fc6565b6109ae565b61026f6103b236600461204b565b6109c2565b6102856103c53660046120b7565b6111a2565b6103dd6103d8366004611ef2565b6111b3565b60405161020a91906120d4565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa158015610495573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b9919061213e565b15610501576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6003546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd90610559908690869060040161226d565b602060405180830381865afa158015610576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a91906123b6565b90505b92915050565b600354604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610612573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261065891908101906123cf565b60055490915073ffffffffffffffffffffffffffffffffffffffff1660005b82518110156107ce57600083828151811061069457610694612481565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561070f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073391906123b6565b905080156107c45761075c73ffffffffffffffffffffffffffffffffffffffff831685836111e7565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e836040516107bb91815260200190565b60405180910390a35b5050600101610677565b505050565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610864573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a91906124b0565b60015473ffffffffffffffffffffffffffffffffffffffff163314610909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016104f8565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff808216600090815260066020526040812054909161059d911660016124fc565b6109b6611274565b6109bf816112f7565b50565b600073ffffffffffffffffffffffffffffffffffffffff8216610a11576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025473ffffffffffffffffffffffffffffffffffffffff163314610a62576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60045473ffffffffffffffffffffffffffffffffffffffff168015610b08576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610ad5908990899060040161226d565b600060405180830381600087803b158015610aef57600080fd5b505af1158015610b03573d6000803e3d6000fd5b505050505b6003546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a610b3e60808c0160608d016120b7565b8a610b4c60808e018e612524565b6040518663ffffffff1660e01b8152600401610b6c959493929190612589565b600060405180830381865afa158015610b89573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610bcf9190810190612651565b91945092509050610be66080890160608a016120b7565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f84604051610c2d91815260200190565b60405180910390a2604080516101a0810182526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528d8116610140850181905283526006602052938220805492948493610160850192918791610caa91166126a8565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200186610daa576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015610d81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da591906126cf565b610dad565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a8060200190610deb9190612524565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610e2f8b80612524565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610e7660808c018c612524565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610ec060808c0160608d016120b7565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190610ef191906126ec565b905067ffffffffffffffff811115610f0b57610f0b611f0f565b604051908082528060200260200182016040528015610f6757816020015b610f546040518060800160405280606081526020016060815260200160608152602001600081525090565b815260200190600190039081610f295790505b509052905060005b610f7c60408b018b6126ec565b905081101561102b57611002610f9560408c018c6126ec565b83818110610fa557610fa5612481565b905060400201803603810190610fbb9190612754565b8c610fc68d80612524565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92506114dc915050565b8260e00151828151811061101857611018612481565b6020908102919091010152600101610f6f565b5060035460e082015173ffffffffffffffffffffffffffffffffffffffff9091169063cc88924c908c9061106260408e018e6126ec565b6040518563ffffffff1660e01b81526004016110819493929190612850565b60006040518083038186803b15801561109957600080fd5b505afa1580156110ad573d6000803e3d6000fd5b505050506080808201839052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908c166060820152309181019190915261114a90829060a001604051602081830303815290604052805190602001206117e6565b81515260405167ffffffffffffffff8b16907f0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab2990611189908490612886565b60405180910390a251519450505050505b949350505050565b6111aa611274565b6109bf816118e6565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526107ce9084906119db565b60005473ffffffffffffffffffffffffffffffffffffffff1633146112f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104f8565b565b602081015173ffffffffffffffffffffffffffffffffffffffff1615806113365750606081015173ffffffffffffffffffffffffffffffffffffffff16155b1561136d576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480548516918616919091179055606080860151600580549095169086161790935580516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008516928101929092527f00000000000000000000000000000000000000000000000000000000000000008416828201527f00000000000000000000000000000000000000000000000000000000000000009093169181019190915290517f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32916114d19184906129d4565b60405180910390a150565b6115076040518060800160405280606081526020016060815260200160608152602001600081525090565b8460200151600003611545576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006115558587600001516107d3565b905073ffffffffffffffffffffffffffffffffffffffff8116158061162557506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156115ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611623919061213e565b155b156116775785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016104f8565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b81526004016117169190612a73565b6000604051808303816000875af1158015611735573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261177b9190810190612ae9565b604080516080810190915273ffffffffffffffffffffffffffffffffffffffff841660a08201529091508060c0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c0015160405160200161182896959493929190612b7a565b604051602081830303815290604052805190602001208560400151805190602001208660e0015160405160200161185f9190612bdb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611965576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104f8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611a3d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611ae79092919063ffffffff16565b8051909150156107ce5780806020019051810190611a5b919061213e565b6107ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016104f8565b6060611af68484600085611b00565b90505b9392505050565b606082471015611b92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016104f8565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbb9190612bee565b60006040518083038185875af1925050503d8060008114611bf8576040519150601f19603f3d011682016040523d82523d6000602084013e611bfd565b606091505b5091509150611c0e87838387611c19565b979650505050505050565b60608315611caf578251600003611ca85773ffffffffffffffffffffffffffffffffffffffff85163b611ca8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104f8565b508161119a565b61119a8383815115611cc45781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190611dbd565b6080810161059d828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b83811015611d6a578181015183820152602001611d52565b50506000910152565b60008151808452611d8b816020860160208601611d4f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061059a6020830184611d73565b67ffffffffffffffff811681146109bf57600080fd5b600060a08284031215611df857600080fd5b50919050565b60008060408385031215611e1157600080fd5b8235611e1c81611dd0565b9150602083013567ffffffffffffffff811115611e3857600080fd5b611e4485828601611de6565b9150509250929050565b73ffffffffffffffffffffffffffffffffffffffff811681146109bf57600080fd5b60008060408385031215611e8357600080fd5b8235611e8e81611dd0565b91506020830135611e9e81611e4e565b809150509250929050565b6080810161059d8284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260408083015182169084015260609182015116910152565b600060208284031215611f0457600080fd5b8135611af981611dd0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611f6157611f61611f0f565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611fae57611fae611f0f565b604052919050565b8035611fc181611e4e565b919050565b600060808284031215611fd857600080fd5b6040516080810181811067ffffffffffffffff82111715611ffb57611ffb611f0f565b604052823561200981611e4e565b8152602083013561201981611e4e565b6020820152604083013561202c81611e4e565b6040820152606083013561203f81611e4e565b60608201529392505050565b6000806000806080858703121561206157600080fd5b843561206c81611dd0565b9350602085013567ffffffffffffffff81111561208857600080fd5b61209487828801611de6565b9350506040850135915060608501356120ac81611e4e565b939692955090935050565b6000602082840312156120c957600080fd5b8135611af981611e4e565b6020808252825182820181905260009190848201906040850190845b8181101561212257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016120f0565b50909695505050505050565b80518015158114611fc157600080fd5b60006020828403121561215057600080fd5b61059a8261212e565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261218e57600080fd5b830160208101925035905067ffffffffffffffff8111156121ae57600080fd5b8036038213156121bd57600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b8581101561226257813561223081611e4e565b73ffffffffffffffffffffffffffffffffffffffff16875281830135838801526040968701969091019060010161221d565b509495945050505050565b600067ffffffffffffffff80851683526040602084015261228e8485612159565b60a060408601526122a360e0860182846121c4565b9150506122b36020860186612159565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808785030160608801526122e98483856121c4565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe188360301831261232257600080fd5b6020928801928301923591508482111561233b57600080fd5b8160061b360383131561234d57600080fd5b8087850301608088015261236284838561220d565b945061237060608901611fb6565b73ffffffffffffffffffffffffffffffffffffffff811660a0890152935061239b6080890189612159565b94509250808786030160c08801525050611c0e8383836121c4565b6000602082840312156123c857600080fd5b5051919050565b600060208083850312156123e257600080fd5b825167ffffffffffffffff808211156123fa57600080fd5b818501915085601f83011261240e57600080fd5b81518181111561242057612420611f0f565b8060051b9150612431848301611f67565b818152918301840191848101908884111561244b57600080fd5b938501935b83851015612475578451925061246583611e4e565b8282529385019390850190612450565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156124c257600080fd5b8151611af981611e4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561251d5761251d6124cd565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261255957600080fd5b83018035915067ffffffffffffffff82111561257457600080fd5b6020019150368190038213156121bd57600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152608060608201526000611c0e6080830184866121c4565b600082601f8301126125e057600080fd5b815167ffffffffffffffff8111156125fa576125fa611f0f565b61262b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611f67565b81815284602083860101111561264057600080fd5b61119a826020830160208701611d4f565b60008060006060848603121561266657600080fd5b835192506126766020850161212e565b9150604084015167ffffffffffffffff81111561269257600080fd5b61269e868287016125cf565b9150509250925092565b600067ffffffffffffffff8083168181036126c5576126c56124cd565b6001019392505050565b6000602082840312156126e157600080fd5b8151611af981611dd0565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261272157600080fd5b83018035915067ffffffffffffffff82111561273c57600080fd5b6020019150600681901b36038213156121bd57600080fd5b60006040828403121561276657600080fd5b61276e611f3e565b823561277981611e4e565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b84811015612843577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189528151608081518186526127ef82870182611d73565b91505085820151858203878701526128078282611d73565b915050604080830151868303828801526128218382611d73565b60609485015197909401969096525050988401989250908301906001016127ab565b5090979650505050505050565b67ffffffffffffffff85168152606060208201526000612873606083018661278e565b8281036040840152611c0e81858761220d565b602081526128d760208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b6000602083015161290060c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e085015261291d6101a0850183611d73565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808685030161010087015261295a8483611d73565b93506080870151915080868503016101208701526129788483611d73565b935060a087015191506129a461014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e08701519150808685030183870152506129ca838261278e565b9695505050505050565b6101008101612a2c828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a08401526040840151811660c084015260608401511660e0830152611af9565b602081526000825160a06020840152612a8f60c0840182611d73565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600060208284031215612afb57600080fd5b815167ffffffffffffffff80821115612b1357600080fd5b9083019060408286031215612b2757600080fd5b612b2f611f3e565b825182811115612b3e57600080fd5b612b4a878286016125cf565b825250602083015182811115612b5f57600080fd5b612b6b878286016125cf565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c06020840152612baa60c0840189611d73565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b60208152600061059a602083018461278e565b60008251612c00818460208701611d4f565b919091019291505056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b50604051620036af380380620036af83398101604081905262000035916200069c565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000186565b505083516001600160401b031615905080620000e6575060208301516001600160a01b0316155b80620000fd575060408301516001600160a01b0316155b8062000114575060608301516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b82516001600160401b031660805260208301516001600160a01b0390811660a0526040840151811660c05260608401511660e052620001728262000231565b6200017d816200036d565b5050506200079c565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316158062000254575060408101516001600160a01b0316155b1562000273576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b03938416179091556020808401805160038054851691861691909117905560408086018051600480549096169087161790945580516080808201835280516001600160401b031680835260a08051891684880190815260c080518b1686880190815260e080518d166060988901908152895196875293518d169a86019a909a52518b169684019690965251891693820193909352885188169181019190915292518616908301529251909316918301919091527f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558910160405180910390a150565b60005b8151811015620004aa57600082828151811062000391576200039162000786565b602002602001015190506000838381518110620003b257620003b262000786565b6020026020010151600001519050806001600160401b0316600003620003f75760405163c35aa79d60e01b81526001600160401b038216600482015260240162000083565b6040805180820182526001600160401b03838116600081815260056020818152868320805480871688528a8301516001600160a01b03908116848a019081529587905293835287518551851668010000000000000000026001600160e01b0319909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a250505080600101905062000370565b5050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620004e957620004e9620004ae565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200051a576200051a620004ae565b604052919050565b80516001600160401b03811681146200053a57600080fd5b919050565b6001600160a01b03811681146200055557600080fd5b50565b6000606082840312156200056b57600080fd5b604051606081016001600160401b0381118282101715620005905762000590620004ae565b80604052508091508251620005a5816200053f565b81526020830151620005b7816200053f565b60208201526040830151620005cc816200053f565b6040919091015292915050565b600082601f830112620005eb57600080fd5b815160206001600160401b03821115620006095762000609620004ae565b62000619818360051b01620004ef565b82815260069290921b840181019181810190868411156200063957600080fd5b8286015b84811015620006915760408189031215620006585760008081fd5b62000662620004c4565b6200066d8262000522565b8152848201516200067e816200053f565b818601528352918301916040016200063d565b509695505050505050565b6000806000838503610100811215620006b457600080fd5b6080811215620006c357600080fd5b50604051608081016001600160401b038082118383101715620006ea57620006ea620004ae565b81604052620006f98762000522565b8352602087015191506200070d826200053f565b8160208401526040870151915062000725826200053f565b816040840152606087015191506200073d826200053f565b81606084015282955062000755886080890162000558565b945060e08701519250808311156200076c57600080fd5b50506200077c86828701620005d9565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e051612e9a62000815600039600081816101eb015281816108a201526115da0152600081816101af01528181610dc601526115b3015260008181610173015281816104c4015261158901526000818161014301528181610cec0152818161117c015261155c0152612e9a6000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637437ff9f11610097578063d77d5ed011610066578063d77d5ed0146103ba578063df0aa9e914610406578063f2fde38b14610419578063fbca3b741461042c57600080fd5b80637437ff9f146102fb57806379ba5097146103685780638da5cb5b146103705780639041be3d1461038e57600080fd5b806320487ded116100d357806320487ded1461028757806334d560e4146102a85780633a019940146102bb57806348a98aa4146102c357600080fd5b80630242cf60146100fa57806306285c691461010f578063181f5a771461023e575b600080fd5b61010d610108366004611fe6565b61044c565b005b61022860408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161023591906120a9565b60405180910390f35b61027a6040518060400160405280601c81526020017f45564d3245564d4d756c74694f6e52616d7020312e362e302d6465760000000081525081565b604051610235919061216e565b61029a610295366004612199565b610460565b604051908152602001610235565b61010d6102b63660046121f9565b610619565b61010d61062a565b6102d66102d136600461226b565b61085a565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610235565b61035b6040805160608101825260008082526020820181905291810191909152506040805160608101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454169181019190915290565b60405161023591906122a4565b61010d61090f565b60005473ffffffffffffffffffffffffffffffffffffffff166102d6565b6103a161039c3660046122e1565b610a0c565b60405167ffffffffffffffff9091168152602001610235565b6102d66103c83660046122e1565b67ffffffffffffffff1660009081526005602052604090205468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b61029a6104143660046122fe565b610a35565b61010d61042736600461236a565b611230565b61043f61043a3660046122e1565b611241565b6040516102359190612387565b610454611275565b61045d816112f8565b50565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561050b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052f91906123f1565b15610577576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6002546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd906105cf9086908690600401612520565b602060405180830381865afa1580156105ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106109190612669565b90505b92915050565b610621611275565b61045d81611470565b600254604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610699573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106df9190810190612682565b60045490915073ffffffffffffffffffffffffffffffffffffffff1660005b825181101561085557600083828151811061071b5761071b612711565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610796573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ba9190612669565b9050801561084b576107e373ffffffffffffffffffffffffffffffffffffffff8316858361163a565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e8360405161084291815260200190565b60405180910390a35b50506001016106fe565b505050565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa1580156108eb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106109190612740565b60015473ffffffffffffffffffffffffffffffffffffffff163314610990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161056e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff80821660009081526005602052604081205490916106139116600161278c565b67ffffffffffffffff8416600090815260056020526040812073ffffffffffffffffffffffffffffffffffffffff8316610a9b576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610af7576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035473ffffffffffffffffffffffffffffffffffffffff168015610b9d576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610b6a908a908a90600401612520565b600060405180830381600087803b158015610b8457600080fd5b505af1158015610b98573d6000803e3d6000fd5b505050505b506002546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a610bd460808c0160608d0161236a565b8a610be260808e018e6127b4565b6040518663ffffffff1660e01b8152600401610c02959493929190612819565b600060405180830381865afa158015610c1f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c6591908101906128e1565b91945092509050610c7c6080890160608a0161236a565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f84604051610cc391815260200190565b60405180910390a2604080516101a081019091526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528c811661014085015287549293928392916101608401918a918791610d389116612938565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200186610e38576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e33919061295f565b610e3b565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a8060200190610e7991906127b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610ebd8b806127b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f0460808c018c6127b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f4e60808c0160608d0161236a565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190610f7f919061297c565b905067ffffffffffffffff811115610f9957610f99611ee3565b604051908082528060200260200182016040528015610ff557816020015b610fe26040518060800160405280606081526020016060815260200160608152602001600081525090565b815260200190600190039081610fb75790505b509052905060005b61100a60408b018b61297c565b90508110156110b95761109061102360408c018c61297c565b8381811061103357611033612711565b90506040020180360381019061104991906129e4565b8c6110548d806127b4565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92506116c7915050565b8260e0015182815181106110a6576110a6612711565b6020908102919091010152600101610ffd565b5060025460e082015173ffffffffffffffffffffffffffffffffffffffff9091169063cc88924c908c906110f060408e018e61297c565b6040518563ffffffff1660e01b815260040161110f9493929190612ae0565b60006040518083038186803b15801561112757600080fd5b505afa15801561113b573d6000803e3d6000fd5b505050506080808201839052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908c16606082015230918101919091526111d890829060a001604051602081830303815290604052805190602001206119d1565b81515260405167ffffffffffffffff8b16907f0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab2990611217908490612b16565b60405180910390a251519450505050505b949350505050565b611238611275565b61045d81611ad1565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff1633146112f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161056e565b565b60005b815181101561146c57600082828151811061131857611318612711565b60200260200101519050600083838151811061133657611336612711565b60200260200101516000015190508067ffffffffffffffff16600003611394576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161056e565b60408051808201825267ffffffffffffffff838116600081815260056020818152868320805480871688528a83015173ffffffffffffffffffffffffffffffffffffffff908116848a019081529587905293835287518551851668010000000000000000027fffffffff00000000000000000000000000000000000000000000000000000000909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a25050508060010190506112fb565b5050565b805173ffffffffffffffffffffffffffffffffffffffff1615806114ac5750604081015173ffffffffffffffffffffffffffffffffffffffff16155b156114e3576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480549094169085161790925581516080810183527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008416918101919091527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea45589161162f918490612c64565b60405180910390a150565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610855908490611bc6565b6116f26040518060800160405280606081526020016060815260200160608152602001600081525090565b8460200151600003611730576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061174085876000015161085a565b905073ffffffffffffffffffffffffffffffffffffffff8116158061181057506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156117ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180e91906123f1565b155b156118625785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161056e565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b81526004016119019190612cf6565b6000604051808303816000875af1158015611920573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119669190810190612d6c565b604080516080810190915273ffffffffffffffffffffffffffffffffffffffff841660a08201529091508060c0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c00151604051602001611a1396959493929190612dfd565b604051602081830303815290604052805190602001208560400151805190602001208660e00151604051602001611a4a9190612e5e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611b50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161056e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611c28826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611cd29092919063ffffffff16565b8051909150156108555780806020019051810190611c4691906123f1565b610855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161056e565b6060611ce18484600085611ceb565b90505b9392505050565b606082471015611d7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161056e565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611da69190612e71565b60006040518083038185875af1925050503d8060008114611de3576040519150601f19603f3d011682016040523d82523d6000602084013e611de8565b606091505b5091509150611df987838387611e04565b979650505050505050565b60608315611e9a578251600003611e935773ffffffffffffffffffffffffffffffffffffffff85163b611e93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161056e565b5081611228565b6112288383815115611eaf5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056e919061216e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611f3557611f35611ee3565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611f8257611f82611ee3565b604052919050565b600067ffffffffffffffff821115611fa457611fa4611ee3565b5060051b60200190565b67ffffffffffffffff8116811461045d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461045d57600080fd5b60006020808385031215611ff957600080fd5b823567ffffffffffffffff81111561201057600080fd5b8301601f8101851361202157600080fd5b803561203461202f82611f8a565b611f3b565b81815260069190911b8201830190838101908783111561205357600080fd5b928401925b82841015611df957604084890312156120715760008081fd5b612079611f12565b843561208481611fae565b81528486013561209381611fc4565b8187015282526040939093019290840190612058565b60808101610613828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b8381101561211b578181015183820152602001612103565b50506000910152565b6000815180845261213c816020860160208601612100565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106106020830184612124565b600060a0828403121561219357600080fd5b50919050565b600080604083850312156121ac57600080fd5b82356121b781611fae565b9150602083013567ffffffffffffffff8111156121d357600080fd5b6121df85828601612181565b9150509250929050565b80356121f481611fc4565b919050565b60006060828403121561220b57600080fd5b6040516060810181811067ffffffffffffffff8211171561222e5761222e611ee3565b604052823561223c81611fc4565b8152602083013561224c81611fc4565b6020820152604083013561225f81611fc4565b60408201529392505050565b6000806040838503121561227e57600080fd5b823561228981611fae565b9150602083013561229981611fc4565b809150509250929050565b606081016106138284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260409182015116910152565b6000602082840312156122f357600080fd5b8135611ce481611fae565b6000806000806080858703121561231457600080fd5b843561231f81611fae565b9350602085013567ffffffffffffffff81111561233b57600080fd5b61234787828801612181565b93505060408501359150606085013561235f81611fc4565b939692955090935050565b60006020828403121561237c57600080fd5b8135611ce481611fc4565b6020808252825182820181905260009190848201906040850190845b818110156123d557835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016123a3565b50909695505050505050565b805180151581146121f457600080fd5b60006020828403121561240357600080fd5b610610826123e1565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261244157600080fd5b830160208101925035905067ffffffffffffffff81111561246157600080fd5b80360382131561247057600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156125155781356124e381611fc4565b73ffffffffffffffffffffffffffffffffffffffff1687528183013583880152604096870196909101906001016124d0565b509495945050505050565b600067ffffffffffffffff808516835260406020840152612541848561240c565b60a0604086015261255660e086018284612477565b915050612566602086018661240c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087850301606088015261259c848385612477565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030183126125d557600080fd5b602092880192830192359150848211156125ee57600080fd5b8160061b360383131561260057600080fd5b808785030160808801526126158483856124c0565b9450612623606089016121e9565b73ffffffffffffffffffffffffffffffffffffffff811660a0890152935061264e608089018961240c565b94509250808786030160c08801525050611df9838383612477565b60006020828403121561267b57600080fd5b5051919050565b6000602080838503121561269557600080fd5b825167ffffffffffffffff8111156126ac57600080fd5b8301601f810185136126bd57600080fd5b80516126cb61202f82611f8a565b81815260059190911b820183019083810190878311156126ea57600080fd5b928401925b82841015611df957835161270281611fc4565b825292840192908401906126ef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561275257600080fd5b8151611ce481611fc4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156127ad576127ad61275d565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126127e957600080fd5b83018035915067ffffffffffffffff82111561280457600080fd5b60200191503681900382131561247057600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152608060608201526000611df9608083018486612477565b600082601f83011261287057600080fd5b815167ffffffffffffffff81111561288a5761288a611ee3565b6128bb60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611f3b565b8181528460208386010111156128d057600080fd5b611228826020830160208701612100565b6000806000606084860312156128f657600080fd5b83519250612906602085016123e1565b9150604084015167ffffffffffffffff81111561292257600080fd5b61292e8682870161285f565b9150509250925092565b600067ffffffffffffffff8083168181036129555761295561275d565b6001019392505050565b60006020828403121561297157600080fd5b8151611ce481611fae565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126129b157600080fd5b83018035915067ffffffffffffffff8211156129cc57600080fd5b6020019150600681901b360382131561247057600080fd5b6000604082840312156129f657600080fd5b6129fe611f12565b8235612a0981611fc4565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b84811015612ad3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160808151818652612a7f82870182612124565b9150508582015185820387870152612a978282612124565b91505060408083015186830382880152612ab18382612124565b6060948501519790940196909652505098840198925090830190600101612a3b565b5090979650505050505050565b67ffffffffffffffff85168152606060208201526000612b036060830186612a1e565b8281036040840152611df98185876124c0565b60208152612b6760208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b60006020830151612b9060c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e0850152612bad6101a0850183612124565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301610100870152612bea8483612124565b9350608087015191508086850301610120870152612c088483612124565b935060a08701519150612c3461014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e0870151915080868503018387015250612c5a8382612a1e565b9695505050505050565b60e08101612cbb828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a084015260408401511660c0830152611ce4565b602081526000825160a06020840152612d1260c0840182612124565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600060208284031215612d7e57600080fd5b815167ffffffffffffffff80821115612d9657600080fd5b9083019060408286031215612daa57600080fd5b612db2611f12565b825182811115612dc157600080fd5b612dcd8782860161285f565b825250602083015182811115612de257600080fd5b612dee8782860161285f565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c06020840152612e2d60c0840189612124565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b6020815260006106106020830184612a1e565b60008251612e83818460208701612100565b919091019291505056fea164736f6c6343000818000a", } var EVM2EVMMultiOnRampABI = EVM2EVMMultiOnRampMetaData.ABI var EVM2EVMMultiOnRampBin = EVM2EVMMultiOnRampMetaData.Bin -func DeployEVM2EVMMultiOnRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMMultiOnRampStaticConfig, dynamicConfig EVM2EVMMultiOnRampDynamicConfig) (common.Address, *types.Transaction, *EVM2EVMMultiOnRamp, error) { +func DeployEVM2EVMMultiOnRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMMultiOnRampStaticConfig, dynamicConfig EVM2EVMMultiOnRampDynamicConfig, destChainConfigArgs []EVM2EVMMultiOnRampDestChainConfigArgs) (common.Address, *types.Transaction, *EVM2EVMMultiOnRamp, error) { parsed, err := EVM2EVMMultiOnRampMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -101,7 +110,7 @@ func DeployEVM2EVMMultiOnRamp(auth *bind.TransactOpts, backend bind.ContractBack return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMMultiOnRampBin), backend, staticConfig, dynamicConfig) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMMultiOnRampBin), backend, staticConfig, dynamicConfig, destChainConfigArgs) if err != nil { return common.Address{}, nil, nil, err } @@ -312,6 +321,28 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetPoolBySourceToken return _EVM2EVMMultiOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMMultiOnRamp.CallOpts, arg0, sourceToken) } +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetRouter(opts *bind.CallOpts, destChainSelector uint64) (common.Address, error) { + var out []interface{} + err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getRouter", destChainSelector) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetRouter(destChainSelector uint64) (common.Address, error) { + return _EVM2EVMMultiOnRamp.Contract.GetRouter(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetRouter(destChainSelector uint64) (common.Address, error) { + return _EVM2EVMMultiOnRamp.Contract.GetRouter(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector) +} + func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMMultiOnRampStaticConfig, error) { var out []interface{} err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getStaticConfig") @@ -412,6 +443,18 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) AcceptOwnership( return _EVM2EVMMultiOnRamp.Contract.AcceptOwnership(&_EVM2EVMMultiOnRamp.TransactOpts) } +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []EVM2EVMMultiOnRampDestChainConfigArgs) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.contract.Transact(opts, "applyDestChainConfigUpdates", destChainConfigArgs) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) ApplyDestChainConfigUpdates(destChainConfigArgs []EVM2EVMMultiOnRampDestChainConfigArgs) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.ApplyDestChainConfigUpdates(&_EVM2EVMMultiOnRamp.TransactOpts, destChainConfigArgs) +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) ApplyDestChainConfigUpdates(destChainConfigArgs []EVM2EVMMultiOnRampDestChainConfigArgs) (*types.Transaction, error) { + return _EVM2EVMMultiOnRamp.Contract.ApplyDestChainConfigUpdates(&_EVM2EVMMultiOnRamp.TransactOpts, destChainConfigArgs) +} + func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { return _EVM2EVMMultiOnRamp.contract.Transact(opts, "forwardFromRouter", destChainSelector, message, feeTokenAmount, originalSender) } @@ -706,6 +749,134 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseConfigSet(log types. return event, nil } +type EVM2EVMMultiOnRampDestChainConfigSetIterator struct { + Event *EVM2EVMMultiOnRampDestChainConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *EVM2EVMMultiOnRampDestChainConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampDestChainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(EVM2EVMMultiOnRampDestChainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *EVM2EVMMultiOnRampDestChainConfigSetIterator) Error() error { + return it.fail +} + +func (it *EVM2EVMMultiOnRampDestChainConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type EVM2EVMMultiOnRampDestChainConfigSet struct { + DestChainSelector uint64 + DestChainConfig EVM2EVMMultiOnRampDestChainConfig + Raw types.Log +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterDestChainConfigSet(opts *bind.FilterOpts, destChainSelector []uint64) (*EVM2EVMMultiOnRampDestChainConfigSetIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "DestChainConfigSet", destChainSelectorRule) + if err != nil { + return nil, err + } + return &EVM2EVMMultiOnRampDestChainConfigSetIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "DestChainConfigSet", logs: logs, sub: sub}, nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchDestChainConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampDestChainConfigSet, destChainSelector []uint64) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "DestChainConfigSet", destChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(EVM2EVMMultiOnRampDestChainConfigSet) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "DestChainConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseDestChainConfigSet(log types.Log) (*EVM2EVMMultiOnRampDestChainConfigSet, error) { + event := new(EVM2EVMMultiOnRampDestChainConfigSet) + if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "DestChainConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type EVM2EVMMultiOnRampFeePaidIterator struct { Event *EVM2EVMMultiOnRampFeePaid @@ -1249,6 +1420,8 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRamp) ParseLog(log types.Log) (generate return _EVM2EVMMultiOnRamp.ParseCCIPSendRequested(log) case _EVM2EVMMultiOnRamp.abi.Events["ConfigSet"].ID: return _EVM2EVMMultiOnRamp.ParseConfigSet(log) + case _EVM2EVMMultiOnRamp.abi.Events["DestChainConfigSet"].ID: + return _EVM2EVMMultiOnRamp.ParseDestChainConfigSet(log) case _EVM2EVMMultiOnRamp.abi.Events["FeePaid"].ID: return _EVM2EVMMultiOnRamp.ParseFeePaid(log) case _EVM2EVMMultiOnRamp.abi.Events["FeeTokenWithdrawn"].ID: @@ -1268,7 +1441,11 @@ func (EVM2EVMMultiOnRampCCIPSendRequested) Topic() common.Hash { } func (EVM2EVMMultiOnRampConfigSet) Topic() common.Hash { - return common.HexToHash("0x23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32") + return common.HexToHash("0x2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558") +} + +func (EVM2EVMMultiOnRampDestChainConfigSet) Topic() common.Hash { + return common.HexToHash("0x324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6") } func (EVM2EVMMultiOnRampFeePaid) Topic() common.Hash { @@ -1300,6 +1477,8 @@ type EVM2EVMMultiOnRampInterface interface { GetPoolBySourceToken(opts *bind.CallOpts, arg0 uint64, sourceToken common.Address) (common.Address, error) + GetRouter(opts *bind.CallOpts, destChainSelector uint64) (common.Address, error) + GetStaticConfig(opts *bind.CallOpts) (EVM2EVMMultiOnRampStaticConfig, error) GetSupportedTokens(opts *bind.CallOpts, arg0 uint64) ([]common.Address, error) @@ -1310,6 +1489,8 @@ type EVM2EVMMultiOnRampInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []EVM2EVMMultiOnRampDestChainConfigArgs) (*types.Transaction, error) + ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMMultiOnRampDynamicConfig) (*types.Transaction, error) @@ -1330,6 +1511,12 @@ type EVM2EVMMultiOnRampInterface interface { ParseConfigSet(log types.Log) (*EVM2EVMMultiOnRampConfigSet, error) + FilterDestChainConfigSet(opts *bind.FilterOpts, destChainSelector []uint64) (*EVM2EVMMultiOnRampDestChainConfigSetIterator, error) + + WatchDestChainConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampDestChainConfigSet, destChainSelector []uint64) (event.Subscription, error) + + ParseDestChainConfigSet(log types.Log) (*EVM2EVMMultiOnRampDestChainConfigSet, error) + FilterFeePaid(opts *bind.FilterOpts, feeToken []common.Address) (*EVM2EVMMultiOnRampFeePaidIterator, error) WatchFeePaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampFeePaid, feeToken []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index e23a89fb9c..ef84a7d75b 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -6,12 +6,12 @@ burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMint burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 5be8832498c8aab49957bfff94fbb1d22373833d1d56f5d8ace259343b27fc24 burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 9215cb5efe441e9893f871de31b4a5d4171c479f276aac4084046514990f1bd6 ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 970bf6a2a817813eb3302c92ec3ad0bc0fc6c2e693f33c13f57733d003f44d0d -ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin 02be3227883ca4b69383892d27ba7a9af747151a06f4815d18ccd8aaf89b4fb9 +ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin fcced2263564f51b5bf086c221e813ec06a71d2bb2e246b4e28cd60098a6de6f commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin ddc26c10c2a52b59624faae9005827b09b98db4566887a736005e8cc37cf8a51 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin ebd8aac686fa28a71d4212bcd25a28f8f640d50dce5e50498b2f6b8534890b69 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de -evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 3ea3974c9848e0df0dbe1fc7192134589e7735017c2ea8d4755084b3c95035d1 -evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin a9aaf33667cab483adab20358d2c04b0694f4ecb26cf90c8e489f78e7f5f407a +evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 10a0cbf8290778fce7e9aaf193aaffaa566bc55d0168b8876f94ceb14ff7cd30 +evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 15cd5695049ab4be1f396ec1d7b609738b2bcefa3740a7a48316e1f72506a34a evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin bdafc343d33f1eb753871ea6d215339cd8e087c1a8c7297257791dd1e453be8f evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin bf1a3090a2f8d1632b82a6d45200cf6f3833a1e27303745405c1ed13ffc0cf83 lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin f049909cfef0aa3b8158c85e7b64516b9d7b32f4930705574090e5b9cab534b1 From 1c8d278d0187509fed46b306066aa63fc1221c2a Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Tue, 6 Aug 2024 16:39:38 +0200 Subject: [PATCH 193/432] use transferFrom(pool -> receiver) over hop through offRamp (#1258) ## Motivation Change the hop through the offRamp to a transferFrom so the funds never touch CCIP contracts outside of the pool ## Solution --- contracts/gas-snapshots/ccip.gas-snapshot | 138 +++++++++--------- .../liquiditymanager.gas-snapshot | 8 +- .../v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 2 +- .../src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol | 2 +- .../ccip/pools/BurnMintTokenPoolAbstract.sol | 3 +- .../src/v0.8/ccip/pools/LegacyPoolWrapper.sol | 3 +- .../v0.8/ccip/pools/LockReleaseTokenPool.sol | 2 +- .../v0.8/ccip/pools/USDC/USDCTokenPool.sol | 5 +- contracts/src/v0.8/ccip/test/BaseTest.t.sol | 2 +- .../MaybeRevertingBurnMintTokenPool.sol | 4 +- .../ccip/test/legacy/TokenPoolAndProxy.t.sol | 5 +- .../test/offRamp/EVM2EVMMultiOffRamp.t.sol | 38 ++--- .../ccip/test/offRamp/EVM2EVMOffRamp.t.sol | 48 +++--- .../ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol | 4 +- .../ccip/test/pools/BurnMintTokenPool.t.sol | 4 +- .../burn_from_mint_token_pool.go | 2 +- .../burn_mint_token_pool.go | 2 +- .../burn_mint_token_pool_and_proxy.go | 2 +- .../burn_with_from_mint_token_pool.go | 2 +- .../evm_2_evm_multi_offramp.go | 2 +- .../evm_2_evm_offramp/evm_2_evm_offramp.go | 2 +- .../lock_release_token_pool.go | 2 +- .../lock_release_token_pool_and_proxy.go | 2 +- .../usdc_token_pool/usdc_token_pool.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 18 +-- 25 files changed, 162 insertions(+), 142 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 23cf48a63b..6d407195a8 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -29,7 +29,7 @@ BurnMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 241381) BurnMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 17677) BurnMintTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 28623) BurnMintTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56078) -BurnMintTokenPool_releaseOrMint:test_PoolMint_Success() (gas: 110657) +BurnMintTokenPool_releaseOrMint:test_PoolMint_Success() (gas: 136256) BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28761) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243517) @@ -122,10 +122,10 @@ CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424253) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1110291) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1134031) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38185) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 108335) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 116870) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 109684) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 82608) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 468131) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99235) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12399) @@ -139,14 +139,14 @@ EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 2 EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 157010) EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187408) EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 145607) -EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 521737) +EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 538299) EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10437) EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15662) EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67352) EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59642) EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58722) -EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6404489) -EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 5987629) +EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6406089) +EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 5989229) EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106187) EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116097) EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106208) @@ -159,9 +159,9 @@ EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225639) EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117474) EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77538) EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 204931) -EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6398812) +EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6400412) EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47718) -EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 5991681) +EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 5993281) EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 136870) EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103588) EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101459) @@ -172,26 +172,26 @@ EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17302) EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1558948) EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 339903) EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 258341) -EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6455106) -EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6037987) +EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6456706) +EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6039587) EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 27703) EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 163239) EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147217) -EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6817158) +EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6818758) EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17154) EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18413) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249352) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 258732) EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20672) -EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 201744) +EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 203093) EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48956) EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48477) EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229787) EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86425) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 280248) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 289629) EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92678) EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35117) EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23918) -EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 451435) +EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 460816) EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54437) EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35906) EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154347) @@ -205,15 +205,15 @@ EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Succ EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 191751) EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259610) EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 127621) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 391759) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 401140) EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65861) EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80895) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 535602) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 480560) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 552164) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 497122) EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35774) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 520573) -EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 517941) -EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 488065) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 537135) +EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 534830) +EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 504627) EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 126045) EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 155268) EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3655340) @@ -226,28 +226,28 @@ EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26004) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152867) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 505596) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2285365) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2286715) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 207749) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 208326) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 659124) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 299687) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 160626) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 161976) EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 24145) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 59111) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 40433) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 76136) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 178957) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 278828) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 188337) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 305691) EVM2EVMMultiOffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11379) EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215350) EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14162) EVM2EVMMultiOffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11660) EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49203) EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27169) -EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 238126) -EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246723) -EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 301741) -EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 282687) +EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 239475) +EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 248072) +EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 311122) +EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 292068) EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176548) EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178616) EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141477) @@ -277,7 +277,7 @@ EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Succ EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 205670) EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 121815) EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 143193) -EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3824556) +EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3859258) EVM2EVMMultiOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108546) EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 73975) EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 262685) @@ -294,30 +294,30 @@ EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939 EVM2EVMMultiOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 51996) EVM2EVMMultiOnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97214) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 38281) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 106252) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_revert_Revert() (gas: 114736) -EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 392159) -EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 145614) -EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 789382) -EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 176510) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 107601) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_revert_Revert() (gas: 80501) +EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 410921) +EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 146964) +EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 796129) +EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 177860) EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 29914) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 61712) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 44959) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 214456) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 307176) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 223836) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 333749) EVM2EVMOffRamp__report:test_Report_Success() (gas: 127410) -EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 255279) -EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 263870) -EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 336203) -EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 314960) +EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 256629) +EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 265220) +EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 345584) +EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 324341) EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17009) EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153130) -EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5257993) +EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5259602) EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 143864) EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21323) EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36486) EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51652) -EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 472927) +EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 482308) EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 46374) EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152404) EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 102702) @@ -328,25 +328,25 @@ EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 15926 EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 174480) EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 248585) EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114991) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 410714) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 420095) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54147) EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 132007) EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52129) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 561592) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 500168) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 578154) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 516730) EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35486) -EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 549169) +EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 565731) EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 63974) EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 123206) EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 143416) EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 428184) EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 20582) -EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 282255) +EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 291635) EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20209) -EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 219644) +EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 220994) EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48632) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48098) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 317243) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 326624) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 72423) EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 231228) EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 279720) @@ -363,7 +363,7 @@ EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 43 EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 25997) EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithGasOverride_Success() (gas: 188342) EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187789) -EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2027924) +EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2029273) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143654) EVM2EVMOffRamp_metadataHash:test_MetadataHash_Success() (gas: 8838) EVM2EVMOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 40131) @@ -396,7 +396,7 @@ EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59347) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179148) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 177430) EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137322) -EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3774775) +EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3809477) EVM2EVMOnRamp_forwardFromRouter:test_TooManyTokens_Revert() (gas: 30187) EVM2EVMOnRamp_forwardFromRouter:test_Unhealthy_Revert() (gas: 43300) EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109283) @@ -488,21 +488,21 @@ EtherSenderReceiverTest_validatedMessage:test_validatedMessage_tokenOverwrittenT EtherSenderReceiverTest_validatedMessage:test_validatedMessage_validMessage_extraArgs() (gas: 26292) LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Revert() (gas: 10992) LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Success() (gas: 18058) -LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3355878) -LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3352276) +LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3390790) +LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3387189) LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_Unauthorized_Revert() (gas: 11380) LockReleaseTokenPoolPoolAndProxy_supportsInterface:test_SupportsInterface_Success() (gas: 9977) LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60043) LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11355) -LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3121619) +LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3145874) LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29942) LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Success() (gas: 79844) LockReleaseTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 59464) -LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3118061) +LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3142317) LockReleaseTokenPool_provideLiquidity:test_Unauthorized_Revert() (gas: 11380) LockReleaseTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 72644) LockReleaseTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56196) -LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 238656) +LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 237556) LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Revert() (gas: 10992) LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Success() (gas: 18058) LockReleaseTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 9977) @@ -598,7 +598,7 @@ MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 393335) -MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1389396) +MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1413114) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) @@ -886,10 +886,10 @@ TokenAdminRegistry_setPool:test_setPool_Success() (gas: 35943) TokenAdminRegistry_setPool:test_setPool_ZeroAddressRemovesPool_Success() (gas: 30617) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_OnlyAdministrator_Revert() (gas: 18043) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_Success() (gas: 49390) -TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6076728) -TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6324538) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6924810) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7108901) +TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6139245) +TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6406966) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6984900) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7168991) TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2209837) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12089) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23324) @@ -931,11 +931,11 @@ TokenProxy_getFee:test_GetFee_Success() (gas: 86702) USDCTokenPool__validateMessage:test_ValidateInvalidMessage_Revert() (gas: 25290) USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35322) USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 30073) -USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 132756) -USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 477205) -USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 289263) +USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 132731) +USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 477183) +USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 288285) USDCTokenPool_releaseOrMint:test_TokenMaxCapacityExceeded_Revert() (gas: 50676) -USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 118987) +USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 118967) USDCTokenPool_setDomains:test_InvalidDomain_Revert() (gas: 66150) -USDCTokenPool_setDomains:test_OnlyOwner_Revert() (gas: 11339) +USDCTokenPool_setDomains:test_OnlyOwner_Revert() (gas: 11333) USDCTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 9876) \ No newline at end of file diff --git a/contracts/gas-snapshots/liquiditymanager.gas-snapshot b/contracts/gas-snapshots/liquiditymanager.gas-snapshot index fbf8074c3e..52a99e078d 100644 --- a/contracts/gas-snapshots/liquiditymanager.gas-snapshot +++ b/contracts/gas-snapshots/liquiditymanager.gas-snapshot @@ -3,9 +3,9 @@ LiquidityManager_addLiquidity:test_addLiquiditySuccess() (gas: 279154) LiquidityManager_rebalanceLiquidity:test_InsufficientLiquidityReverts() (gas: 206745) LiquidityManager_rebalanceLiquidity:test_InvalidRemoteChainReverts() (gas: 192319) LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess() (gas: 9141768) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 8957594) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 8952800) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 8880598) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 8981838) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 8977044) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 8904842) LiquidityManager_rebalanceLiquidity:test_rebalanceLiquiditySuccess() (gas: 382897) LiquidityManager_receive:test_receive_success() (gas: 21182) LiquidityManager_removeLiquidity:test_InsufficientLiquidityReverts() (gas: 184869) @@ -19,7 +19,7 @@ LiquidityManager_setFinanceRole:test_OnlyOwnerReverts() (gas: 10987) LiquidityManager_setFinanceRole:test_setFinanceRoleSuccess() (gas: 21836) LiquidityManager_setLocalLiquidityContainer:test_OnlyOwnerReverts() (gas: 11052) LiquidityManager_setLocalLiquidityContainer:test_ReverstWhen_CalledWithTheZeroAddress() (gas: 10643) -LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3495598) +LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3519863) LiquidityManager_setMinimumLiquidity:test_OnlyOwnerReverts() (gas: 10925) LiquidityManager_setMinimumLiquidity:test_setMinimumLiquiditySuccess() (gas: 36389) LiquidityManager_withdrawERC20:test_withdrawERC20Reverts() (gas: 180359) diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol index 554533e39b..cf2b836a56 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -860,7 +860,7 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { // transfer them to the final receiver. We use the _callWithExactGasSafeReturnData function because // the token contracts are not considered trusted. (success, returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( - abi.encodeCall(IERC20.transfer, (receiver, localAmount)), + abi.encodeCall(IERC20.transferFrom, (localPoolAddress, receiver, localAmount)), localToken, s_dynamicConfig.maxTokenTransferGas, Internal.GAS_FOR_CALL_EXACT_CHECK, diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol index f60f0c13f9..2d24682609 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol @@ -658,7 +658,7 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio // transfer them to the final receiver. We use the _callWithExactGasSafeReturnData function because // the token contracts are not considered trusted. (success, returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( - abi.encodeCall(IERC20.transfer, (receiver, localAmount)), + abi.encodeCall(IERC20.transferFrom, (localPoolAddress, receiver, localAmount)), localToken, sourceTokenData.destGasAmount - gasUsedReleaseOrMint, Internal.GAS_FOR_CALL_EXACT_CHECK, diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol index 2085c9427b..1968b3c03d 100644 --- a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol @@ -40,7 +40,8 @@ abstract contract BurnMintTokenPoolAbstract is TokenPool { _validateReleaseOrMint(releaseOrMintIn); // Mint to the offRamp, which forwards it to the recipient - IBurnMintERC20(address(i_token)).mint(msg.sender, releaseOrMintIn.amount); + IBurnMintERC20(address(i_token)).mint(address(this), releaseOrMintIn.amount); + IBurnMintERC20(address(i_token)).approve(msg.sender, releaseOrMintIn.amount); emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); diff --git a/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol b/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol index 125a3a28ee..969f0ac1f7 100644 --- a/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol +++ b/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol @@ -75,7 +75,8 @@ abstract contract LegacyPoolWrapper is TokenPool { /// @dev Since extraData has never been used in LockRelease or MintBurn token pools, we can safely ignore it. function _releaseOrMintLegacy(Pool.ReleaseOrMintInV1 memory releaseOrMintIn) internal { s_previousPool.releaseOrMint( - releaseOrMintIn.originalSender, msg.sender, releaseOrMintIn.amount, releaseOrMintIn.remoteChainSelector, "" + releaseOrMintIn.originalSender, address(this), releaseOrMintIn.amount, releaseOrMintIn.remoteChainSelector, "" ); + i_token.approve(msg.sender, releaseOrMintIn.amount); } } diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol index db168f994d..be3a599a97 100644 --- a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol @@ -68,7 +68,7 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion _validateReleaseOrMint(releaseOrMintIn); // Release to the offRamp, which forwards it to the recipient - getToken().safeTransfer(msg.sender, releaseOrMintIn.amount); + getToken().approve(msg.sender, releaseOrMintIn.amount); emit Released(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); diff --git a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol index adaf946b1e..d46fcbacd6 100644 --- a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol @@ -141,6 +141,7 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { /// specific message that was sent on source. function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) external + virtual override returns (Pool.ReleaseOrMintOutV1 memory) { @@ -155,8 +156,8 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { if (!i_messageTransmitter.receiveMessage(msgAndAttestation.message, msgAndAttestation.attestation)) { revert UnlockingUSDCFailed(); } - // Since the tokens are minted to the pool, the pool has to send it to the offRamp - getToken().safeTransfer(msg.sender, releaseOrMintIn.amount); + // Since the tokens are minted to the pool, the pool has to approve it for the offRamp + getToken().approve(msg.sender, releaseOrMintIn.amount); emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); diff --git a/contracts/src/v0.8/ccip/test/BaseTest.t.sol b/contracts/src/v0.8/ccip/test/BaseTest.t.sol index 498b1c5731..887ffbf616 100644 --- a/contracts/src/v0.8/ccip/test/BaseTest.t.sol +++ b/contracts/src/v0.8/ccip/test/BaseTest.t.sol @@ -38,7 +38,7 @@ contract BaseTest is Test { uint16 internal constant DEST_GAS_PER_PAYLOAD_BYTE = 16; uint16 internal constant DEFAULT_TOKEN_FEE_USD_CENTS = 50; - uint32 internal constant DEFAULT_TOKEN_DEST_GAS_OVERHEAD = 110_000; + uint32 internal constant DEFAULT_TOKEN_DEST_GAS_OVERHEAD = 144_000; uint32 internal constant DEFAULT_TOKEN_BYTES_OVERHEAD = 32; bool private s_baseTestInitialized; diff --git a/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol b/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol index e572f798ad..a30c4779dd 100644 --- a/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol +++ b/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol @@ -63,7 +63,9 @@ contract MaybeRevertingBurnMintTokenPool is BurnMintTokenPool { revert(add(32, revertReason), mload(revertReason)) } } - IBurnMintERC20(address(i_token)).mint(msg.sender, releaseOrMintIn.amount); + IBurnMintERC20(address(i_token)).mint(address(this), releaseOrMintIn.amount); + IBurnMintERC20(address(i_token)).approve(msg.sender, releaseOrMintIn.amount); + emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); } diff --git a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol index 927c7e1f03..a7e6083825 100644 --- a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol +++ b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol @@ -478,7 +478,10 @@ contract TokenPoolAndProxy is EVM2EVMOnRampSetup { vm.startPrank(address(s_fakeOffRamp)); vm.expectEmit(address(s_legacyPool)); - emit Minted(address(s_pool), s_fakeOffRamp, amount); + emit Minted(address(s_pool), address(s_pool), amount); + + vm.expectEmit(address(s_token)); + emit IERC20.Approval(address(s_pool), address(s_fakeOffRamp), amount); s_pool.releaseOrMint( Pool.ReleaseOrMintInV1({ diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol index 5280c56ceb..603705e00a 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol @@ -2396,7 +2396,7 @@ contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSet bytes memory revertData = "call reverted :o"; - vm.mockCallRevert(destToken, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount), revertData); + vm.mockCallRevert(destToken, abi.encodeWithSelector(IERC20.approve.selector, s_offRamp, amount), revertData); vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, revertData)); s_offRamp.releaseOrMintSingleToken( @@ -2449,7 +2449,6 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { function test_releaseOrMintTokens_destDenominatedDecimals_Success() public { Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); - address destToken = s_destFeeToken; uint256 amount = 100; uint256 destinationDenominationMultiplier = 1000; srcTokenAmounts[0].amount = amount; @@ -2458,24 +2457,29 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { Internal.RampTokenAmount[] memory sourceTokenAmounts = _getDefaultSourceTokenData(srcTokenAmounts); - // Since the pool call is mocked, we manually release funds to the offRamp - deal(destToken, address(s_offRamp), amount * destinationDenominationMultiplier); + address pool = s_destPoolBySourceToken[srcTokenAmounts[0].token]; + address destToken = s_destTokenBySourceToken[srcTokenAmounts[0].token]; + + // Since the pool call is mocked, we manually approve funds to the offRamp + deal(destToken, pool, amount * destinationDenominationMultiplier); + vm.startPrank(pool); + IERC20(destToken).approve(address(s_offRamp), amount * destinationDenominationMultiplier); + vm.startPrank(OWNER); + + Pool.ReleaseOrMintInV1 memory releaseOrMintIn = Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + receiver: OWNER, + amount: amount, + localToken: destToken, + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenAmounts[0].sourcePoolAddress, + sourcePoolData: sourceTokenAmounts[0].extraData, + offchainTokenData: offchainTokenData[0] + }); vm.mockCall( s_destPoolBySourceToken[srcTokenAmounts[0].token], - abi.encodeWithSelector( - LockReleaseTokenPool.releaseOrMint.selector, - Pool.ReleaseOrMintInV1({ - originalSender: abi.encode(OWNER), - receiver: OWNER, - amount: amount, - localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], - remoteChainSelector: SOURCE_CHAIN_SELECTOR_1, - sourcePoolAddress: sourceTokenAmounts[0].sourcePoolAddress, - sourcePoolData: sourceTokenAmounts[0].extraData, - offchainTokenData: offchainTokenData[0] - }) - ), + abi.encodeWithSelector(LockReleaseTokenPool.releaseOrMint.selector, releaseOrMintIn), abi.encode(amount * destinationDenominationMultiplier) ); diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol index 89f0f95fd4..16358f75ba 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol @@ -235,13 +235,17 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { amounts[1] = uint256(tokenAmount); Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageWithTokens(1, amounts); - // console.log(message.length); message.data = messageData; IERC20 dstToken0 = IERC20(s_destTokens[0]); uint256 startingBalance = dstToken0.balanceOf(message.receiver); - vm.expectCall(s_destTokens[0], abi.encodeWithSelector(IERC20.transfer.selector, address(s_receiver), amounts[0])); + vm.expectCall( + address(dstToken0), + abi.encodeWithSelector( + IERC20.transferFrom.selector, s_destPoolByToken[address(dstToken0)], address(s_receiver), amounts[0] + ) + ); (Internal.MessageExecutionState newState, bytes memory err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); @@ -1548,7 +1552,7 @@ contract EVM2EVMOffRamp__releaseOrMintToken is EVM2EVMOffRampSetup { bytes memory revertData = "call reverted :o"; - vm.mockCallRevert(destToken, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount), revertData); + vm.mockCallRevert(destToken, abi.encodeWithSelector(IERC20.approve.selector, s_offRamp, amount), revertData); vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, revertData)); s_offRamp.releaseOrMintToken(amount, originalSender, receiver, sourceTokenData, offchainTokenData); @@ -1595,7 +1599,6 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { function test_releaseOrMintTokens_destDenominatedDecimals_Success() public { Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); - address destToken = s_destFeeToken; uint256 amount = 100; uint256 destinationDenominationMultiplier = 1000; srcTokenAmounts[0].amount = amount; @@ -1605,24 +1608,29 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { bytes[] memory encodedSourceTokenData = _getDefaultSourceTokenData(srcTokenAmounts); Internal.SourceTokenData memory sourceTokenData = abi.decode(encodedSourceTokenData[0], (Internal.SourceTokenData)); - // Since the pool call is mocked, we manually release funds to the offRamp - deal(destToken, address(s_offRamp), amount * destinationDenominationMultiplier); + address pool = s_destPoolBySourceToken[srcTokenAmounts[0].token]; + address destToken = s_destTokenBySourceToken[srcTokenAmounts[0].token]; + + // Since the pool call is mocked, we manually approve funds to the offRamp + deal(destToken, pool, amount * destinationDenominationMultiplier); + vm.startPrank(pool); + IERC20(destToken).approve(address(s_offRamp), amount * destinationDenominationMultiplier); + vm.startPrank(OWNER); + + Pool.ReleaseOrMintInV1 memory releaseOrMintIn = Pool.ReleaseOrMintInV1({ + originalSender: originalSender, + receiver: OWNER, + amount: amount, + localToken: destToken, + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData[0] + }); vm.mockCall( - s_destPoolBySourceToken[srcTokenAmounts[0].token], - abi.encodeWithSelector( - LockReleaseTokenPool.releaseOrMint.selector, - Pool.ReleaseOrMintInV1({ - originalSender: originalSender, - receiver: OWNER, - amount: amount, - localToken: s_destTokenBySourceToken[srcTokenAmounts[0].token], - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - sourcePoolAddress: sourceTokenData.sourcePoolAddress, - sourcePoolData: sourceTokenData.extraData, - offchainTokenData: offchainTokenData[0] - }) - ), + pool, + abi.encodeWithSelector(LockReleaseTokenPool.releaseOrMint.selector, releaseOrMintIn), abi.encode(amount * destinationDenominationMultiplier) ); diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol index 91e47a7e98..d2864a762c 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol @@ -65,7 +65,7 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { minFeeUSDCents: 1_00, // 1 USD maxFeeUSDCents: 1000_00, // 1,000 USD deciBps: 2_5, // 2.5 bps, or 0.025% - destGasOverhead: 100_000, + destGasOverhead: 140_000, destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES), aggregateRateLimitEnabled: true }) @@ -76,7 +76,7 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { minFeeUSDCents: 2_00, // 1 USD maxFeeUSDCents: 500_00, // 500 USD deciBps: 10_0, // 10 bps, or 0.1% - destGasOverhead: 90_000, + destGasOverhead: 130_000, destBytesOverhead: 200, aggregateRateLimitEnabled: true }) diff --git a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol index c628c510d4..71b7819fbf 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol @@ -111,7 +111,7 @@ contract BurnMintTokenPool_releaseOrMint is BurnMintTokenPoolSetup { vm.startPrank(s_burnMintOffRamp); vm.expectEmit(); - emit IERC20.Transfer(address(0), address(s_burnMintOffRamp), amount); + emit IERC20.Approval(address(s_pool), address(s_burnMintOffRamp), amount); s_pool.releaseOrMint( Pool.ReleaseOrMintInV1({ originalSender: bytes(""), @@ -125,7 +125,7 @@ contract BurnMintTokenPool_releaseOrMint is BurnMintTokenPoolSetup { }) ); - assertEq(s_burnMintERC677.balanceOf(s_burnMintOffRamp), amount); + assertEq(s_burnMintERC677.allowance(address(s_pool), s_burnMintOffRamp), amount); } function test_PoolMintNotHealthy_Revert() public { diff --git a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go index e5a9e0be79..89a5cac840 100644 --- a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnFromMintTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620044e0380380620044e08339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161396762000b79600039600081816104dd0152818161174c01526121300152600081816104b70152818161157d0152611a020152600081816102390152818161028e015281816107010152818161149d0152818161192201528181611b1a015281816120c6015261231b01526139676000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612abe565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b1d565b6105f9565b6040516101d29190612b9c565b6101ee6040518060400160405280601f81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e302d6465760081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612bdc565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612bf9565b6106a9565b604051905181526020016101d2565b6103006102fb366004612c81565b610804565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612ced565b61087f565b6103006109f3565b610300610349366004612bdc565b610af0565b6101c661035c366004612b1d565b610b3f565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d70565b610b56565b6040516101d29190612dab565b6103a7610bfd565b6040516101d29190612e0b565b6103c76103c2366004612b1d565b610c0e565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b1d565b610ce3565b610300610462366004612bdc565b610d0e565b61046f610de9565b6040516101d29190612e65565b6103c761048a366004612b1d565b610ea1565b61030061049d366004612fcd565b610f73565b6103006104b0366004613012565b610ffc565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612bdc565b611482565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061062490613054565b80601f016020809104026020016040519081016040528092919081815260200182805461065090613054565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c483613152565b611496565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561075a57600080fd5b505af115801561076e573d6000803e3d6000fd5b50610783925050506060830160408401612bdc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f084606001356040516107e591815260200190565b60405180910390a3506040805160208101909152606090910135815290565b61080c6116c7565b6108798484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061174a92505050565b50505050565b6108876116c7565b61089083610b3f565b6108d7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546108fe90613054565b80601f016020809104026020016040519081016040528092919081815260200182805461092a90613054565b80156109775780601f1061094c57610100808354040283529160200191610977565b820191906000526020600020905b81548152906001019060200180831161095a57829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109a6838583613297565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf8285856040516109e5939291906133b1565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108ce565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610af86116c7565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff8416611900565b6040805180820190915260608082526020820152610b7b610b7683613415565b61191b565b610b888260600135611ae5565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610be284602001602081019061044f9190612b1d565b81526040805160208181019092526000815291015292915050565b6060610c096002611b8e565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611b9b565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061062490613054565b610d166116c7565b73ffffffffffffffffffffffffffffffffffffffff8116610d63576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610df76005611b8e565b90506000815167ffffffffffffffff811115610e1557610e15612ea7565b604051908082528060200260200182016040528015610e3e578160200160208202803683370190505b50905060005b8251811015610e9a57828181518110610e5f57610e5f6134b7565b6020026020010151828281518110610e7957610e796134b7565b67ffffffffffffffff90921660209283029190910190910152600101610e44565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611b9b565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fb3575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610fec576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108ce565b610ff7838383611c4d565b505050565b6110046116c7565b60005b81811015610ff7576000838383818110611023576110236134b7565b905060200281019061103591906134e6565b61103e90613524565b90506110538160800151826020015115611d37565b6110668160a00151826020015115611d37565b8060200151156113625780516110889060059067ffffffffffffffff16611e70565b6110cd5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108ce565b60408101515115806110e25750606081015151155b15611119576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906112fa90826135d8565b506060820151600582019061130f90826135d8565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061135594939291906136f2565b60405180910390a1611479565b805161137a9060059067ffffffffffffffff16611e7c565b6113bf5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108ce565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114286004830182612a70565b611436600583016000612a70565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611007565b61148a6116c7565b61149381611e88565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461152b5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108ce565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156115d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fd919061378b565b15611634576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116418160200151611f7d565b600061165082602001516105f9565b9050805160001480611674575080805190602001208260a001518051906020012014155b156116b1578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108ce9190612b9c565b6116c3826020015183606001516120a3565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108ce565b565b7f00000000000000000000000000000000000000000000000000000000000000006117a1576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118375760008382815181106117c1576117c16134b7565b602002602001015190506117df8160026120ea90919063ffffffff16565b1561182e5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117a4565b5060005b8151811015610ff7576000828281518110611858576118586134b7565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361189c57506118f8565b6118a760028261210c565b156118f65760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161183b565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119b05760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108ce565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a82919061378b565b15611ab9576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ac6816040015161212e565b611ad381602001516121ad565b611493816020015182606001516122fb565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015611b7357600080fd5b505af1158015611b87573d6000803e3d6000fd5b5050505050565b606060006119148361233f565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c2982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c0d91906137d7565b85608001516fffffffffffffffffffffffffffffffff1661239a565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c5683610b3f565b611c98576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108ce565b611ca3826000611d37565b67ffffffffffffffff83166000908152600760205260409020611cc690836123c4565b611cd1816000611d37565b67ffffffffffffffff83166000908152600760205260409020611cf790600201826123c4565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d2a939291906137ea565b60405180910390a1505050565b815115611dfe5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611d8d575060408201516fffffffffffffffffffffffffffffffff16155b15611dc657816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108ce919061386d565b80156116c3576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e37575060208201516fffffffffffffffffffffffffffffffff1615155b156116c357816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108ce919061386d565b60006119148383612566565b600061191483836125b5565b3373ffffffffffffffffffffffffffffffffffffffff821603611f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108ce565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611f8681610b3f565b611fc8576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108ce565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612047573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061206b919061378b565b611493576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108ce565b67ffffffffffffffff821660009081526007602052604090206116c390600201827f00000000000000000000000000000000000000000000000000000000000000006126a8565b60006119148373ffffffffffffffffffffffffffffffffffffffff84166125b5565b60006119148373ffffffffffffffffffffffffffffffffffffffff8416612566565b7f0000000000000000000000000000000000000000000000000000000000000000156114935761215f600282612a2b565b611493576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108ce565b6121b681610b3f565b6121f8576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108ce565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612271573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229591906138a9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611493576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108ce565b67ffffffffffffffff821660009081526007602052604090206116c390827f00000000000000000000000000000000000000000000000000000000000000006126a8565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b81548152602001906001019080831161237b5750505050509050919050565b60006123b9856123aa84866138c6565b6123b490876138dd565b612a5a565b90505b949350505050565b81546000906123ed90700100000000000000000000000000000000900463ffffffff16426137d7565b9050801561248f5760018301548354612435916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661239a565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124b5916fffffffffffffffffffffffffffffffff9081169116612a5a565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d2a90849061386d565b60008181526001830160205260408120546125ad575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b6000818152600183016020526040812054801561269e5760006125d96001836137d7565b85549091506000906125ed906001906137d7565b905081811461265257600086600001828154811061260d5761260d6134b7565b9060005260206000200154905080876000018481548110612630576126306134b7565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612663576126636138f0565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126cf575081155b156126d957505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061271f90700100000000000000000000000000000000900463ffffffff16426137d7565b905080156127df5781831115612761576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461279b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661239a565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128965773ffffffffffffffffffffffffffffffffffffffff841661283e576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108ce565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108ce565b848310156129a95760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128da90826137d7565b6128e4878a6137d7565b6128ee91906138dd565b6128f8919061391f565b905073ffffffffffffffffffffffffffffffffffffffff8616612951576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108ce565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108ce565b6129b385846137d7565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611914565b6000818310612a695781611914565b5090919050565b508054612a7c90613054565b6000825580601f10612a8c575050565b601f01602090049060005260206000209081019061149391905b80821115612aba5760008155600101612aa6565b5090565b600060208284031215612ad057600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461191457600080fd5b803567ffffffffffffffff81168114612b1857600080fd5b919050565b600060208284031215612b2f57600080fd5b61191482612b00565b6000815180845260005b81811015612b5e57602081850181015186830182015201612b42565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119146020830184612b38565b73ffffffffffffffffffffffffffffffffffffffff8116811461149357600080fd5b8035612b1881612baf565b600060208284031215612bee57600080fd5b813561191481612baf565b600060208284031215612c0b57600080fd5b813567ffffffffffffffff811115612c2257600080fd5b8201610100818503121561191457600080fd5b60008083601f840112612c4757600080fd5b50813567ffffffffffffffff811115612c5f57600080fd5b6020830191508360208260051b8501011115612c7a57600080fd5b9250929050565b60008060008060408587031215612c9757600080fd5b843567ffffffffffffffff80821115612caf57600080fd5b612cbb88838901612c35565b90965094506020870135915080821115612cd457600080fd5b50612ce187828801612c35565b95989497509550505050565b600080600060408486031215612d0257600080fd5b612d0b84612b00565b9250602084013567ffffffffffffffff80821115612d2857600080fd5b818601915086601f830112612d3c57600080fd5b813581811115612d4b57600080fd5b876020828501011115612d5d57600080fd5b6020830194508093505050509250925092565b600060208284031215612d8257600080fd5b813567ffffffffffffffff811115612d9957600080fd5b820160a0818503121561191457600080fd5b602081526000825160406020840152612dc76060840182612b38565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e028282612b38565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e5957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e27565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e5957835167ffffffffffffffff1683529284019291840191600101612e81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612efa57612efa612ea7565b60405290565b60405160c0810167ffffffffffffffff81118282101715612efa57612efa612ea7565b801515811461149357600080fd5b8035612b1881612f23565b80356fffffffffffffffffffffffffffffffff81168114612b1857600080fd5b600060608284031215612f6e57600080fd5b6040516060810181811067ffffffffffffffff82111715612f9157612f91612ea7565b6040529050808235612fa281612f23565b8152612fb060208401612f3c565b6020820152612fc160408401612f3c565b60408201525092915050565b600080600060e08486031215612fe257600080fd5b612feb84612b00565b9250612ffa8560208601612f5c565b91506130098560808601612f5c565b90509250925092565b6000806020838503121561302557600080fd5b823567ffffffffffffffff81111561303c57600080fd5b61304885828601612c35565b90969095509350505050565b600181811c9082168061306857607f821691505b6020821081036130a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130b857600080fd5b813567ffffffffffffffff808211156130d3576130d3612ea7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561311957613119612ea7565b8160405283815286602085880101111561313257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561316557600080fd5b61316d612ed6565b823567ffffffffffffffff8082111561318557600080fd5b613191368387016130a7565b835261319f60208601612b00565b60208401526131b060408601612bd1565b6040840152606085013560608401526131cb60808601612bd1565b608084015260a08501359150808211156131e457600080fd5b6131f0368387016130a7565b60a084015260c085013591508082111561320957600080fd5b613215368387016130a7565b60c084015260e085013591508082111561322e57600080fd5b5061323b368286016130a7565b60e08301525092915050565b601f821115610ff7576000816000526020600020601f850160051c810160208610156132705750805b601f850160051c820191505b8181101561328f5782815560010161327c565b505050505050565b67ffffffffffffffff8311156132af576132af612ea7565b6132c3836132bd8354613054565b83613247565b6000601f84116001811461331557600085156132df5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611b87565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156133645786850135825560209485019460019092019101613344565b508682101561339f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133c46040830186612b38565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561342757600080fd5b60405160a0810167ffffffffffffffff828210818311171561344b5761344b612ea7565b81604052843591508082111561346057600080fd5b5061346d368286016130a7565b82525061347c60208401612b00565b6020820152604083013561348f81612baf565b60408201526060838101359082015260808301356134ac81612baf565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261351a57600080fd5b9190910192915050565b6000610140823603121561353757600080fd5b61353f612f00565b61354883612b00565b815261355660208401612f31565b6020820152604083013567ffffffffffffffff8082111561357657600080fd5b613582368387016130a7565b6040840152606085013591508082111561359b57600080fd5b506135a8368286016130a7565b6060830152506135bb3660808501612f5c565b60808201526135cd3660e08501612f5c565b60a082015292915050565b815167ffffffffffffffff8111156135f2576135f2612ea7565b613606816136008454613054565b84613247565b602080601f83116001811461365957600084156136235750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561328f565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136a657888601518255948401946001909101908401613687565b50858210156136e257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261371681840187612b38565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506137549050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e02565b60006020828403121561379d57600080fd5b815161191481612f23565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137a8565b67ffffffffffffffff8416815260e0810161383660208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123bc565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138bb57600080fd5b815161191481612baf565b80820281158282048414176105f3576105f36137a8565b808201808211156105f3576105f36137a8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613955577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b50604051620045a1380380620045a18339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c051613a2162000b80600039600081816104dd0152818161180601526121ea0152600081816104b7015281816116370152611abc0152600081816102390152818161028e01528181610701015281816107a801528181611557015281816119dc01528181611bd40152818161218001526123d50152613a216000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612b78565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612bd7565b6105f9565b6040516101d29190612c56565b6101ee6040518060400160405280601f81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e302d6465760081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c96565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612cb3565b6106a9565b604051905181526020016101d2565b6103006102fb366004612d3b565b6108be565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612da7565b610939565b610300610aad565b610300610349366004612c96565b610baa565b6101c661035c366004612bd7565b610bf9565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612e2a565b610c10565b6040516101d29190612e65565b6103a7610cb7565b6040516101d29190612ec5565b6103c76103c2366004612bd7565b610cc8565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612bd7565b610d9d565b610300610462366004612c96565b610dc8565b61046f610ea3565b6040516101d29190612f1f565b6103c761048a366004612bd7565b610f5b565b61030061049d366004613087565b61102d565b6103006104b03660046130cc565b6110b6565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c96565b61153c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061310e565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061310e565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361320c565b611550565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152306004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561075a57600080fd5b505af115801561076e573d6000803e3d6000fd5b50506040517f095ea7b3000000000000000000000000000000000000000000000000000000008152336004820152606085013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16925063095ea7b391506044016020604051808303816000875af1158015610808573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061082c9190613301565b5061083d6060830160408401612c96565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161089f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108c6611781565b6109338484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061180492505050565b50505050565b610941611781565b61094a83610bf9565b610991576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109b89061310e565b80601f01602080910402602001604051908101604052809291908181526020018280546109e49061310e565b8015610a315780601f10610a0657610100808354040283529160200191610a31565b820191906000526020600020905b815481529060010190602001808311610a1457829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a6083858361336e565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a9f93929190613488565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610988565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610bb2611781565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff84166119ba565b6040805180820190915260608082526020820152610c35610c30836134ec565b6119d5565b610c428260600135611b9f565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c9c84602001602081019061044f9190612bd7565b81526040805160208181019092526000815291015292915050565b6060610cc36002611c48565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611c55565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061310e565b610dd0611781565b73ffffffffffffffffffffffffffffffffffffffff8116610e1d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610eb16005611c48565b90506000815167ffffffffffffffff811115610ecf57610ecf612f61565b604051908082528060200260200182016040528015610ef8578160200160208202803683370190505b50905060005b8251811015610f5457828181518110610f1957610f1961358e565b6020026020010151828281518110610f3357610f3361358e565b67ffffffffffffffff90921660209283029190910190910152600101610efe565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611c55565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061106d575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156110a6576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610988565b6110b1838383611d07565b505050565b6110be611781565b60005b818110156110b15760008383838181106110dd576110dd61358e565b90506020028101906110ef91906135bd565b6110f8906135fb565b905061110d8160800151826020015115611df1565b6111208160a00151826020015115611df1565b80602001511561141c5780516111429060059067ffffffffffffffff16611f2a565b6111875780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610988565b604081015151158061119c5750606081015151155b156111d3576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906113b490826136af565b50606082015160058201906113c990826136af565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061140f94939291906137c9565b60405180910390a1611533565b80516114349060059067ffffffffffffffff16611f36565b6114795780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610988565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114e26004830182612b2a565b6114f0600583016000612b2a565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016110c1565b611544611781565b61154d81611f42565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115e55760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610988565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611693573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b79190613301565b156116ee576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116fb8160200151612037565b600061170a82602001516105f9565b905080516000148061172e575080805190602001208260a001518051906020012014155b1561176b578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109889190612c56565b61177d8260200151836060015161215d565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611802576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610988565b565b7f000000000000000000000000000000000000000000000000000000000000000061185b576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118f157600083828151811061187b5761187b61358e565b602002602001015190506118998160026121a490919063ffffffff16565b156118e85760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010161185e565b5060005b81518110156110b15760008282815181106119125761191261358e565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361195657506119b2565b6119616002826121c6565b156119b05760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016118f5565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611a6a5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610988565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3c9190613301565b15611b73576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b8081604001516121e8565b611b8d8160200151612267565b61154d816020015182606001516123b5565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015611c2d57600080fd5b505af1158015611c41573d6000803e3d6000fd5b5050505050565b606060006119ce836123f9565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611ce382606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611cc79190613891565b85608001516fffffffffffffffffffffffffffffffff16612454565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611d1083610bf9565b611d52576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610988565b611d5d826000611df1565b67ffffffffffffffff83166000908152600760205260409020611d80908361247e565b611d8b816000611df1565b67ffffffffffffffff83166000908152600760205260409020611db1906002018261247e565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611de4939291906138a4565b60405180910390a1505050565b815115611eb85781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611e47575060408201516fffffffffffffffffffffffffffffffff16155b15611e8057816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109889190613927565b801561177d576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611ef1575060208201516fffffffffffffffffffffffffffffffff1615155b1561177d57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109889190613927565b60006119ce8383612620565b60006119ce838361266f565b3373ffffffffffffffffffffffffffffffffffffffff821603611fc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610988565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61204081610bf9565b612082576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610988565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612101573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121259190613301565b61154d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610988565b67ffffffffffffffff8216600090815260076020526040902061177d90600201827f0000000000000000000000000000000000000000000000000000000000000000612762565b60006119ce8373ffffffffffffffffffffffffffffffffffffffff841661266f565b60006119ce8373ffffffffffffffffffffffffffffffffffffffff8416612620565b7f00000000000000000000000000000000000000000000000000000000000000001561154d57612219600282612ae5565b61154d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610988565b61227081610bf9565b6122b2576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610988565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561232b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234f9190613963565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461154d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610988565b67ffffffffffffffff8216600090815260076020526040902061177d90827f0000000000000000000000000000000000000000000000000000000000000000612762565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116124355750505050509050919050565b6000612473856124648486613980565b61246e9087613997565b612b14565b90505b949350505050565b81546000906124a790700100000000000000000000000000000000900463ffffffff1642613891565b9050801561254957600183015483546124ef916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612454565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461256f916fffffffffffffffffffffffffffffffff9081169116612b14565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611de4908490613927565b6000818152600183016020526040812054612667575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b60008181526001830160205260408120548015612758576000612693600183613891565b85549091506000906126a790600190613891565b905081811461270c5760008660000182815481106126c7576126c761358e565b90600052602060002001549050808760000184815481106126ea576126ea61358e565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061271d5761271d6139aa565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff161580612789575081155b1561279357505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906127d990700100000000000000000000000000000000900463ffffffff1642613891565b90508015612899578183111561281b576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546128559083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612454565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156129505773ffffffffffffffffffffffffffffffffffffffff84166128f8576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610988565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610988565b84831015612a635760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906129949082613891565b61299e878a613891565b6129a89190613997565b6129b291906139d9565b905073ffffffffffffffffffffffffffffffffffffffff8616612a0b576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610988565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610988565b612a6d8584613891565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156119ce565b6000818310612b2357816119ce565b5090919050565b508054612b369061310e565b6000825580601f10612b46575050565b601f01602090049060005260206000209081019061154d91905b80821115612b745760008155600101612b60565b5090565b600060208284031215612b8a57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146119ce57600080fd5b803567ffffffffffffffff81168114612bd257600080fd5b919050565b600060208284031215612be957600080fd5b6119ce82612bba565b6000815180845260005b81811015612c1857602081850181015186830182015201612bfc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119ce6020830184612bf2565b73ffffffffffffffffffffffffffffffffffffffff8116811461154d57600080fd5b8035612bd281612c69565b600060208284031215612ca857600080fd5b81356119ce81612c69565b600060208284031215612cc557600080fd5b813567ffffffffffffffff811115612cdc57600080fd5b820161010081850312156119ce57600080fd5b60008083601f840112612d0157600080fd5b50813567ffffffffffffffff811115612d1957600080fd5b6020830191508360208260051b8501011115612d3457600080fd5b9250929050565b60008060008060408587031215612d5157600080fd5b843567ffffffffffffffff80821115612d6957600080fd5b612d7588838901612cef565b90965094506020870135915080821115612d8e57600080fd5b50612d9b87828801612cef565b95989497509550505050565b600080600060408486031215612dbc57600080fd5b612dc584612bba565b9250602084013567ffffffffffffffff80821115612de257600080fd5b818601915086601f830112612df657600080fd5b813581811115612e0557600080fd5b876020828501011115612e1757600080fd5b6020830194508093505050509250925092565b600060208284031215612e3c57600080fd5b813567ffffffffffffffff811115612e5357600080fd5b820160a081850312156119ce57600080fd5b602081526000825160406020840152612e816060840182612bf2565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612ebc8282612bf2565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612f1357835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612ee1565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612f1357835167ffffffffffffffff1683529284019291840191600101612f3b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612fb457612fb4612f61565b60405290565b60405160c0810167ffffffffffffffff81118282101715612fb457612fb4612f61565b801515811461154d57600080fd5b8035612bd281612fdd565b80356fffffffffffffffffffffffffffffffff81168114612bd257600080fd5b60006060828403121561302857600080fd5b6040516060810181811067ffffffffffffffff8211171561304b5761304b612f61565b604052905080823561305c81612fdd565b815261306a60208401612ff6565b602082015261307b60408401612ff6565b60408201525092915050565b600080600060e0848603121561309c57600080fd5b6130a584612bba565b92506130b48560208601613016565b91506130c38560808601613016565b90509250925092565b600080602083850312156130df57600080fd5b823567ffffffffffffffff8111156130f657600080fd5b61310285828601612cef565b90969095509350505050565b600181811c9082168061312257607f821691505b60208210810361315b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f83011261317257600080fd5b813567ffffffffffffffff8082111561318d5761318d612f61565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156131d3576131d3612f61565b816040528381528660208588010111156131ec57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561321f57600080fd5b613227612f90565b823567ffffffffffffffff8082111561323f57600080fd5b61324b36838701613161565b835261325960208601612bba565b602084015261326a60408601612c8b565b60408401526060850135606084015261328560808601612c8b565b608084015260a085013591508082111561329e57600080fd5b6132aa36838701613161565b60a084015260c08501359150808211156132c357600080fd5b6132cf36838701613161565b60c084015260e08501359150808211156132e857600080fd5b506132f536828601613161565b60e08301525092915050565b60006020828403121561331357600080fd5b81516119ce81612fdd565b601f8211156110b1576000816000526020600020601f850160051c810160208610156133475750805b601f850160051c820191505b8181101561336657828155600101613353565b505050505050565b67ffffffffffffffff83111561338657613386612f61565b61339a83613394835461310e565b8361331e565b6000601f8411600181146133ec57600085156133b65750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611c41565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561343b578685013582556020948501946001909201910161341b565b5086821015613476577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b60408152600061349b6040830186612bf2565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a082360312156134fe57600080fd5b60405160a0810167ffffffffffffffff828210818311171561352257613522612f61565b81604052843591508082111561353757600080fd5b5061354436828601613161565b82525061355360208401612bba565b6020820152604083013561356681612c69565b604082015260608381013590820152608083013561358381612c69565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126135f157600080fd5b9190910192915050565b6000610140823603121561360e57600080fd5b613616612fba565b61361f83612bba565b815261362d60208401612feb565b6020820152604083013567ffffffffffffffff8082111561364d57600080fd5b61365936838701613161565b6040840152606085013591508082111561367257600080fd5b5061367f36828601613161565b6060830152506136923660808501613016565b60808201526136a43660e08501613016565b60a082015292915050565b815167ffffffffffffffff8111156136c9576136c9612f61565b6136dd816136d7845461310e565b8461331e565b602080601f83116001811461373057600084156136fa5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613366565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561377d5788860151825594840194600190910190840161375e565b50858210156137b957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526137ed81840187612bf2565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061382b9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612ebc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f3613862565b67ffffffffffffffff8416815260e081016138f060208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612476565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561397557600080fd5b81516119ce81612c69565b80820281158282048414176105f3576105f3613862565b808201808211156105f3576105f3613862565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613a0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var BurnFromMintTokenPoolABI = BurnFromMintTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go index 500b31ec51..6c7cc7083b 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnMintTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620040883803806200408883398101604081905262000034916200054c565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000176565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001685760408051600081526020810190915262000168908462000221565b5050505050505050620006aa565b336001600160a01b03821603620001d05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000242576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002cd5760008382815181106200026657620002666200065c565b60209081029190910101519050620002806002826200037e565b15620002c3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000245565b5060005b815181101562000379576000828281518110620002f257620002f26200065c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200031e575062000370565b6200032b6002826200039e565b156200036e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d1565b505050565b600062000395836001600160a01b038416620003b5565b90505b92915050565b600062000395836001600160a01b038416620004b9565b60008181526001830160205260408120548015620004ae576000620003dc60018362000672565b8554909150600090620003f29060019062000672565b90508181146200045e5760008660000182815481106200041657620004166200065c565b90600052602060002001549050808760000184815481106200043c576200043c6200065c565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000472576200047262000694565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000398565b600091505062000398565b6000818152600183016020526040812054620005025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000398565b50600062000398565b6001600160a01b03811681146200052157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000547816200050b565b919050565b600080600080608085870312156200056357600080fd5b845162000570816200050b565b602086810151919550906001600160401b03808211156200059057600080fd5b818801915088601f830112620005a557600080fd5b815181811115620005ba57620005ba62000524565b8060051b604051601f19603f83011681018181108582111715620005e257620005e262000524565b60405291825284820192508381018501918b8311156200060157600080fd5b938501935b828510156200062a576200061a856200053a565b8452938501939285019262000606565b80985050505050505062000641604086016200053a565b915062000651606086016200053a565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161396162000727600039600081816104dd0152818161174c015261212a0152600081816104b70152818161157d0152611a020152600081816102390152818161028e015281816107010152818161149d0152818161192201528181611b14015281816120c0015261231501526139616000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ab8565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b17565b6105f9565b6040516101d29190612b96565b6101ee6040518060400160405280601b81526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e302d646576000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612bd6565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612bf3565b6106a9565b604051905181526020016101d2565b6103006102fb366004612c7b565b610804565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612ce7565b61087f565b6103006109f3565b610300610349366004612bd6565b610af0565b6101c661035c366004612b17565b610b3f565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d6a565b610b56565b6040516101d29190612da5565b6103a7610bfd565b6040516101d29190612e05565b6103c76103c2366004612b17565b610c0e565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b17565b610ce3565b610300610462366004612bd6565b610d0e565b61046f610de9565b6040516101d29190612e5f565b6103c761048a366004612b17565b610ea1565b61030061049d366004612fc7565b610f73565b6103006104b036600461300c565b610ffc565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612bd6565b611482565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061304e565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061304e565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361314c565b611496565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561075a57600080fd5b505af115801561076e573d6000803e3d6000fd5b50610783925050506060830160408401612bd6565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f084606001356040516107e591815260200190565b60405180910390a3506040805160208101909152606090910135815290565b61080c6116c7565b6108798484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061174a92505050565b50505050565b6108876116c7565b61089083610b3f565b6108d7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546108fe9061304e565b80601f016020809104026020016040519081016040528092919081815260200182805461092a9061304e565b80156109775780601f1061094c57610100808354040283529160200191610977565b820191906000526020600020905b81548152906001019060200180831161095a57829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109a6838583613291565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf8285856040516109e5939291906133ab565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108ce565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610af86116c7565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff8416611900565b6040805180820190915260608082526020820152610b7b610b768361340f565b61191b565b610b888260600135611ae5565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610be284602001602081019061044f9190612b17565b81526040805160208181019092526000815291015292915050565b6060610c096002611b88565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611b95565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061304e565b610d166116c7565b73ffffffffffffffffffffffffffffffffffffffff8116610d63576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610df76005611b88565b90506000815167ffffffffffffffff811115610e1557610e15612ea1565b604051908082528060200260200182016040528015610e3e578160200160208202803683370190505b50905060005b8251811015610e9a57828181518110610e5f57610e5f6134b1565b6020026020010151828281518110610e7957610e796134b1565b67ffffffffffffffff90921660209283029190910190910152600101610e44565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611b95565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fb3575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610fec576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108ce565b610ff7838383611c47565b505050565b6110046116c7565b60005b81811015610ff7576000838383818110611023576110236134b1565b905060200281019061103591906134e0565b61103e9061351e565b90506110538160800151826020015115611d31565b6110668160a00151826020015115611d31565b8060200151156113625780516110889060059067ffffffffffffffff16611e6a565b6110cd5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108ce565b60408101515115806110e25750606081015151155b15611119576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906112fa90826135d2565b506060820151600582019061130f90826135d2565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061135594939291906136ec565b60405180910390a1611479565b805161137a9060059067ffffffffffffffff16611e76565b6113bf5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108ce565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114286004830182612a6a565b611436600583016000612a6a565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611007565b61148a6116c7565b61149381611e82565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461152b5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108ce565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156115d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fd9190613785565b15611634576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116418160200151611f77565b600061165082602001516105f9565b9050805160001480611674575080805190602001208260a001518051906020012014155b156116b1578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108ce9190612b96565b6116c38260200151836060015161209d565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108ce565b565b7f00000000000000000000000000000000000000000000000000000000000000006117a1576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118375760008382815181106117c1576117c16134b1565b602002602001015190506117df8160026120e490919063ffffffff16565b1561182e5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117a4565b5060005b8151811015610ff7576000828281518110611858576118586134b1565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361189c57506118f8565b6118a7600282612106565b156118f65760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161183b565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119b05760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108ce565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a829190613785565b15611ab9576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ac68160400151612128565b611ad381602001516121a7565b611493816020015182606001516122f5565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611b6d57600080fd5b505af1158015611b81573d6000803e3d6000fd5b5050505050565b6060600061191483612339565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c2382606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c0791906137d1565b85608001516fffffffffffffffffffffffffffffffff16612394565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c5083610b3f565b611c92576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108ce565b611c9d826000611d31565b67ffffffffffffffff83166000908152600760205260409020611cc090836123be565b611ccb816000611d31565b67ffffffffffffffff83166000908152600760205260409020611cf190600201826123be565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d24939291906137e4565b60405180910390a1505050565b815115611df85781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611d87575060408201516fffffffffffffffffffffffffffffffff16155b15611dc057816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108ce9190613867565b80156116c3576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e31575060208201516fffffffffffffffffffffffffffffffff1615155b156116c357816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108ce9190613867565b60006119148383612560565b600061191483836125af565b3373ffffffffffffffffffffffffffffffffffffffff821603611f01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108ce565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611f8081610b3f565b611fc2576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108ce565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612041573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120659190613785565b611493576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108ce565b67ffffffffffffffff821660009081526007602052604090206116c390600201827f00000000000000000000000000000000000000000000000000000000000000006126a2565b60006119148373ffffffffffffffffffffffffffffffffffffffff84166125af565b60006119148373ffffffffffffffffffffffffffffffffffffffff8416612560565b7f00000000000000000000000000000000000000000000000000000000000000001561149357612159600282612a25565b611493576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108ce565b6121b081610b3f565b6121f2576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108ce565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561226b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228f91906138a3565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611493576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108ce565b67ffffffffffffffff821660009081526007602052604090206116c390827f00000000000000000000000000000000000000000000000000000000000000006126a2565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123755750505050509050919050565b60006123b3856123a484866138c0565b6123ae90876138d7565b612a54565b90505b949350505050565b81546000906123e790700100000000000000000000000000000000900463ffffffff16426137d1565b90508015612489576001830154835461242f916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612394565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124af916fffffffffffffffffffffffffffffffff9081169116612a54565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d24908490613867565b60008181526001830160205260408120546125a7575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126985760006125d36001836137d1565b85549091506000906125e7906001906137d1565b905081811461264c576000866000018281548110612607576126076134b1565b906000526020600020015490508087600001848154811061262a5761262a6134b1565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061265d5761265d6138ea565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126c9575081155b156126d357505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061271990700100000000000000000000000000000000900463ffffffff16426137d1565b905080156127d9578183111561275b576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127959083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612394565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128905773ffffffffffffffffffffffffffffffffffffffff8416612838576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108ce565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108ce565b848310156129a35760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128d490826137d1565b6128de878a6137d1565b6128e891906138d7565b6128f29190613919565b905073ffffffffffffffffffffffffffffffffffffffff861661294b576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108ce565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108ce565b6129ad85846137d1565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611914565b6000818310612a635781611914565b5090919050565b508054612a769061304e565b6000825580601f10612a86575050565b601f01602090049060005260206000209081019061149391905b80821115612ab45760008155600101612aa0565b5090565b600060208284031215612aca57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461191457600080fd5b803567ffffffffffffffff81168114612b1257600080fd5b919050565b600060208284031215612b2957600080fd5b61191482612afa565b6000815180845260005b81811015612b5857602081850181015186830182015201612b3c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119146020830184612b32565b73ffffffffffffffffffffffffffffffffffffffff8116811461149357600080fd5b8035612b1281612ba9565b600060208284031215612be857600080fd5b813561191481612ba9565b600060208284031215612c0557600080fd5b813567ffffffffffffffff811115612c1c57600080fd5b8201610100818503121561191457600080fd5b60008083601f840112612c4157600080fd5b50813567ffffffffffffffff811115612c5957600080fd5b6020830191508360208260051b8501011115612c7457600080fd5b9250929050565b60008060008060408587031215612c9157600080fd5b843567ffffffffffffffff80821115612ca957600080fd5b612cb588838901612c2f565b90965094506020870135915080821115612cce57600080fd5b50612cdb87828801612c2f565b95989497509550505050565b600080600060408486031215612cfc57600080fd5b612d0584612afa565b9250602084013567ffffffffffffffff80821115612d2257600080fd5b818601915086601f830112612d3657600080fd5b813581811115612d4557600080fd5b876020828501011115612d5757600080fd5b6020830194508093505050509250925092565b600060208284031215612d7c57600080fd5b813567ffffffffffffffff811115612d9357600080fd5b820160a0818503121561191457600080fd5b602081526000825160406020840152612dc16060840182612b32565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612dfc8282612b32565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e5357835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e21565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e5357835167ffffffffffffffff1683529284019291840191600101612e7b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612ef457612ef4612ea1565b60405290565b60405160c0810167ffffffffffffffff81118282101715612ef457612ef4612ea1565b801515811461149357600080fd5b8035612b1281612f1d565b80356fffffffffffffffffffffffffffffffff81168114612b1257600080fd5b600060608284031215612f6857600080fd5b6040516060810181811067ffffffffffffffff82111715612f8b57612f8b612ea1565b6040529050808235612f9c81612f1d565b8152612faa60208401612f36565b6020820152612fbb60408401612f36565b60408201525092915050565b600080600060e08486031215612fdc57600080fd5b612fe584612afa565b9250612ff48560208601612f56565b91506130038560808601612f56565b90509250925092565b6000806020838503121561301f57600080fd5b823567ffffffffffffffff81111561303657600080fd5b61304285828601612c2f565b90969095509350505050565b600181811c9082168061306257607f821691505b60208210810361309b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130b257600080fd5b813567ffffffffffffffff808211156130cd576130cd612ea1565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561311357613113612ea1565b8160405283815286602085880101111561312c57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561315f57600080fd5b613167612ed0565b823567ffffffffffffffff8082111561317f57600080fd5b61318b368387016130a1565b835261319960208601612afa565b60208401526131aa60408601612bcb565b6040840152606085013560608401526131c560808601612bcb565b608084015260a08501359150808211156131de57600080fd5b6131ea368387016130a1565b60a084015260c085013591508082111561320357600080fd5b61320f368387016130a1565b60c084015260e085013591508082111561322857600080fd5b50613235368286016130a1565b60e08301525092915050565b601f821115610ff7576000816000526020600020601f850160051c8101602086101561326a5750805b601f850160051c820191505b8181101561328957828155600101613276565b505050505050565b67ffffffffffffffff8311156132a9576132a9612ea1565b6132bd836132b7835461304e565b83613241565b6000601f84116001811461330f57600085156132d95750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611b81565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561335e578685013582556020948501946001909201910161333e565b5086821015613399577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133be6040830186612b32565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561342157600080fd5b60405160a0810167ffffffffffffffff828210818311171561344557613445612ea1565b81604052843591508082111561345a57600080fd5b50613467368286016130a1565b82525061347660208401612afa565b6020820152604083013561348981612ba9565b60408201526060838101359082015260808301356134a681612ba9565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261351457600080fd5b9190910192915050565b6000610140823603121561353157600080fd5b613539612efa565b61354283612afa565b815261355060208401612f2b565b6020820152604083013567ffffffffffffffff8082111561357057600080fd5b61357c368387016130a1565b6040840152606085013591508082111561359557600080fd5b506135a2368286016130a1565b6060830152506135b53660808501612f56565b60808201526135c73660e08501612f56565b60a082015292915050565b815167ffffffffffffffff8111156135ec576135ec612ea1565b613600816135fa845461304e565b84613241565b602080601f831160018114613653576000841561361d5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613289565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136a057888601518255948401946001909101908401613681565b50858210156136dc57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261371081840187612b32565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061374e9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612dfc565b60006020828403121561379757600080fd5b815161191481612f1d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137a2565b67ffffffffffffffff8416815260e0810161383060208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123b6565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138b557600080fd5b815161191481612ba9565b80820281158282048414176105f3576105f36137a2565b808201808211156105f3576105f36137a2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261394f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b50604051620041493803806200414983398101604081905262000034916200054c565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000176565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001685760408051600081526020810190915262000168908462000221565b5050505050505050620006aa565b336001600160a01b03821603620001d05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000242576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002cd5760008382815181106200026657620002666200065c565b60209081029190910101519050620002806002826200037e565b15620002c3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000245565b5060005b815181101562000379576000828281518110620002f257620002f26200065c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200031e575062000370565b6200032b6002826200039e565b156200036e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d1565b505050565b600062000395836001600160a01b038416620003b5565b90505b92915050565b600062000395836001600160a01b038416620004b9565b60008181526001830160205260408120548015620004ae576000620003dc60018362000672565b8554909150600090620003f29060019062000672565b90508181146200045e5760008660000182815481106200041657620004166200065c565b90600052602060002001549050808760000184815481106200043c576200043c6200065c565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000472576200047262000694565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000398565b600091505062000398565b6000818152600183016020526040812054620005025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000398565b50600062000398565b6001600160a01b03811681146200052157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000547816200050b565b919050565b600080600080608085870312156200056357600080fd5b845162000570816200050b565b602086810151919550906001600160401b03808211156200059057600080fd5b818801915088601f830112620005a557600080fd5b815181811115620005ba57620005ba62000524565b8060051b604051601f19603f83011681018181108582111715620005e257620005e262000524565b60405291825284820192508381018501918b8311156200060157600080fd5b938501935b828510156200062a576200061a856200053a565b8452938501939285019262000606565b80985050505050505062000641604086016200053a565b915062000651606086016200053a565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051613a1b6200072e600039600081816104dd0152818161180601526121e40152600081816104b7015281816116370152611abc0152600081816102390152818161028e01528181610701015281816107a801528181611557015281816119dc01528181611bce0152818161217a01526123cf0152613a1b6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612b72565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612bd1565b6105f9565b6040516101d29190612c50565b6101ee6040518060400160405280601b81526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e302d646576000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c90565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612cad565b6106a9565b604051905181526020016101d2565b6103006102fb366004612d35565b6108be565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612da1565b610939565b610300610aad565b610300610349366004612c90565b610baa565b6101c661035c366004612bd1565b610bf9565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612e24565b610c10565b6040516101d29190612e5f565b6103a7610cb7565b6040516101d29190612ebf565b6103c76103c2366004612bd1565b610cc8565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612bd1565b610d9d565b610300610462366004612c90565b610dc8565b61046f610ea3565b6040516101d29190612f19565b6103c761048a366004612bd1565b610f5b565b61030061049d366004613081565b61102d565b6103006104b03660046130c6565b6110b6565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c90565b61153c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061062490613108565b80601f016020809104026020016040519081016040528092919081815260200182805461065090613108565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c483613206565b611550565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152306004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561075a57600080fd5b505af115801561076e573d6000803e3d6000fd5b50506040517f095ea7b3000000000000000000000000000000000000000000000000000000008152336004820152606085013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16925063095ea7b391506044016020604051808303816000875af1158015610808573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061082c91906132fb565b5061083d6060830160408401612c90565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161089f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108c6611781565b6109338484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061180492505050565b50505050565b610941611781565b61094a83610bf9565b610991576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109b890613108565b80601f01602080910402602001604051908101604052809291908181526020018280546109e490613108565b8015610a315780601f10610a0657610100808354040283529160200191610a31565b820191906000526020600020905b815481529060010190602001808311610a1457829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a60838583613368565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a9f93929190613482565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610988565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610bb2611781565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff84166119ba565b6040805180820190915260608082526020820152610c35610c30836134e6565b6119d5565b610c428260600135611b9f565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c9c84602001602081019061044f9190612bd1565b81526040805160208181019092526000815291015292915050565b6060610cc36002611c42565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611c4f565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061062490613108565b610dd0611781565b73ffffffffffffffffffffffffffffffffffffffff8116610e1d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610eb16005611c42565b90506000815167ffffffffffffffff811115610ecf57610ecf612f5b565b604051908082528060200260200182016040528015610ef8578160200160208202803683370190505b50905060005b8251811015610f5457828181518110610f1957610f19613588565b6020026020010151828281518110610f3357610f33613588565b67ffffffffffffffff90921660209283029190910190910152600101610efe565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611c4f565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061106d575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156110a6576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610988565b6110b1838383611d01565b505050565b6110be611781565b60005b818110156110b15760008383838181106110dd576110dd613588565b90506020028101906110ef91906135b7565b6110f8906135f5565b905061110d8160800151826020015115611deb565b6111208160a00151826020015115611deb565b80602001511561141c5780516111429060059067ffffffffffffffff16611f24565b6111875780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610988565b604081015151158061119c5750606081015151155b156111d3576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906113b490826136a9565b50606082015160058201906113c990826136a9565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061140f94939291906137c3565b60405180910390a1611533565b80516114349060059067ffffffffffffffff16611f30565b6114795780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610988565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114e26004830182612b24565b6114f0600583016000612b24565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016110c1565b611544611781565b61154d81611f3c565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115e55760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610988565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611693573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b791906132fb565b156116ee576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116fb8160200151612031565b600061170a82602001516105f9565b905080516000148061172e575080805190602001208260a001518051906020012014155b1561176b578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109889190612c50565b61177d82602001518360600151612157565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611802576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610988565b565b7f000000000000000000000000000000000000000000000000000000000000000061185b576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118f157600083828151811061187b5761187b613588565b6020026020010151905061189981600261219e90919063ffffffff16565b156118e85760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010161185e565b5060005b81518110156110b157600082828151811061191257611912613588565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361195657506119b2565b6119616002826121c0565b156119b05760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016118f5565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611a6a5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610988565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3c91906132fb565b15611b73576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b8081604001516121e2565b611b8d8160200151612261565b61154d816020015182606001516123af565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611c2757600080fd5b505af1158015611c3b573d6000803e3d6000fd5b5050505050565b606060006119ce836123f3565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611cdd82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611cc1919061388b565b85608001516fffffffffffffffffffffffffffffffff1661244e565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611d0a83610bf9565b611d4c576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610988565b611d57826000611deb565b67ffffffffffffffff83166000908152600760205260409020611d7a9083612478565b611d85816000611deb565b67ffffffffffffffff83166000908152600760205260409020611dab9060020182612478565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611dde9392919061389e565b60405180910390a1505050565b815115611eb25781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611e41575060408201516fffffffffffffffffffffffffffffffff16155b15611e7a57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109889190613921565b801561177d576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611eeb575060208201516fffffffffffffffffffffffffffffffff1615155b1561177d57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109889190613921565b60006119ce838361261a565b60006119ce8383612669565b3373ffffffffffffffffffffffffffffffffffffffff821603611fbb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610988565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61203a81610bf9565b61207c576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610988565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156120fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211f91906132fb565b61154d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610988565b67ffffffffffffffff8216600090815260076020526040902061177d90600201827f000000000000000000000000000000000000000000000000000000000000000061275c565b60006119ce8373ffffffffffffffffffffffffffffffffffffffff8416612669565b60006119ce8373ffffffffffffffffffffffffffffffffffffffff841661261a565b7f00000000000000000000000000000000000000000000000000000000000000001561154d57612213600282612adf565b61154d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610988565b61226a81610bf9565b6122ac576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610988565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612325573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612349919061395d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461154d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610988565b67ffffffffffffffff8216600090815260076020526040902061177d90827f000000000000000000000000000000000000000000000000000000000000000061275c565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b81548152602001906001019080831161242f5750505050509050919050565b600061246d8561245e848661397a565b6124689087613991565b612b0e565b90505b949350505050565b81546000906124a190700100000000000000000000000000000000900463ffffffff164261388b565b9050801561254357600183015483546124e9916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661244e565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612569916fffffffffffffffffffffffffffffffff9081169116612b0e565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611dde908490613921565b6000818152600183016020526040812054612661575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b6000818152600183016020526040812054801561275257600061268d60018361388b565b85549091506000906126a19060019061388b565b90508181146127065760008660000182815481106126c1576126c1613588565b90600052602060002001549050808760000184815481106126e4576126e4613588565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612717576127176139a4565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff161580612783575081155b1561278d57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906127d390700100000000000000000000000000000000900463ffffffff164261388b565b905080156128935781831115612815576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461284f9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661244e565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561294a5773ffffffffffffffffffffffffffffffffffffffff84166128f2576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610988565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610988565b84831015612a5d5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061298e908261388b565b612998878a61388b565b6129a29190613991565b6129ac91906139d3565b905073ffffffffffffffffffffffffffffffffffffffff8616612a05576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610988565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610988565b612a67858461388b565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156119ce565b6000818310612b1d57816119ce565b5090919050565b508054612b3090613108565b6000825580601f10612b40575050565b601f01602090049060005260206000209081019061154d91905b80821115612b6e5760008155600101612b5a565b5090565b600060208284031215612b8457600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146119ce57600080fd5b803567ffffffffffffffff81168114612bcc57600080fd5b919050565b600060208284031215612be357600080fd5b6119ce82612bb4565b6000815180845260005b81811015612c1257602081850181015186830182015201612bf6565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119ce6020830184612bec565b73ffffffffffffffffffffffffffffffffffffffff8116811461154d57600080fd5b8035612bcc81612c63565b600060208284031215612ca257600080fd5b81356119ce81612c63565b600060208284031215612cbf57600080fd5b813567ffffffffffffffff811115612cd657600080fd5b820161010081850312156119ce57600080fd5b60008083601f840112612cfb57600080fd5b50813567ffffffffffffffff811115612d1357600080fd5b6020830191508360208260051b8501011115612d2e57600080fd5b9250929050565b60008060008060408587031215612d4b57600080fd5b843567ffffffffffffffff80821115612d6357600080fd5b612d6f88838901612ce9565b90965094506020870135915080821115612d8857600080fd5b50612d9587828801612ce9565b95989497509550505050565b600080600060408486031215612db657600080fd5b612dbf84612bb4565b9250602084013567ffffffffffffffff80821115612ddc57600080fd5b818601915086601f830112612df057600080fd5b813581811115612dff57600080fd5b876020828501011115612e1157600080fd5b6020830194508093505050509250925092565b600060208284031215612e3657600080fd5b813567ffffffffffffffff811115612e4d57600080fd5b820160a081850312156119ce57600080fd5b602081526000825160406020840152612e7b6060840182612bec565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612eb68282612bec565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612f0d57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612edb565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612f0d57835167ffffffffffffffff1683529284019291840191600101612f35565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612fae57612fae612f5b565b60405290565b60405160c0810167ffffffffffffffff81118282101715612fae57612fae612f5b565b801515811461154d57600080fd5b8035612bcc81612fd7565b80356fffffffffffffffffffffffffffffffff81168114612bcc57600080fd5b60006060828403121561302257600080fd5b6040516060810181811067ffffffffffffffff8211171561304557613045612f5b565b604052905080823561305681612fd7565b815261306460208401612ff0565b602082015261307560408401612ff0565b60408201525092915050565b600080600060e0848603121561309657600080fd5b61309f84612bb4565b92506130ae8560208601613010565b91506130bd8560808601613010565b90509250925092565b600080602083850312156130d957600080fd5b823567ffffffffffffffff8111156130f057600080fd5b6130fc85828601612ce9565b90969095509350505050565b600181811c9082168061311c57607f821691505b602082108103613155577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f83011261316c57600080fd5b813567ffffffffffffffff8082111561318757613187612f5b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156131cd576131cd612f5b565b816040528381528660208588010111156131e657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561321957600080fd5b613221612f8a565b823567ffffffffffffffff8082111561323957600080fd5b6132453683870161315b565b835261325360208601612bb4565b602084015261326460408601612c85565b60408401526060850135606084015261327f60808601612c85565b608084015260a085013591508082111561329857600080fd5b6132a43683870161315b565b60a084015260c08501359150808211156132bd57600080fd5b6132c93683870161315b565b60c084015260e08501359150808211156132e257600080fd5b506132ef3682860161315b565b60e08301525092915050565b60006020828403121561330d57600080fd5b81516119ce81612fd7565b601f8211156110b1576000816000526020600020601f850160051c810160208610156133415750805b601f850160051c820191505b818110156133605782815560010161334d565b505050505050565b67ffffffffffffffff83111561338057613380612f5b565b6133948361338e8354613108565b83613318565b6000601f8411600181146133e657600085156133b05750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611c3b565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156134355786850135825560209485019460019092019101613415565b5086821015613470577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006134956040830186612bec565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a082360312156134f857600080fd5b60405160a0810167ffffffffffffffff828210818311171561351c5761351c612f5b565b81604052843591508082111561353157600080fd5b5061353e3682860161315b565b82525061354d60208401612bb4565b6020820152604083013561356081612c63565b604082015260608381013590820152608083013561357d81612c63565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126135eb57600080fd5b9190910192915050565b6000610140823603121561360857600080fd5b613610612fb4565b61361983612bb4565b815261362760208401612fe5565b6020820152604083013567ffffffffffffffff8082111561364757600080fd5b6136533683870161315b565b6040840152606085013591508082111561366c57600080fd5b506136793682860161315b565b60608301525061368c3660808501613010565b608082015261369e3660e08501613010565b60a082015292915050565b815167ffffffffffffffff8111156136c3576136c3612f5b565b6136d7816136d18454613108565b84613318565b602080601f83116001811461372a57600084156136f45750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613360565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561377757888601518255948401946001909101908401613758565b50858210156137b357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526137e781840187612bec565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506138259050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612eb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f361385c565b67ffffffffffffffff8416815260e081016138ea60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612470565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561396f57600080fd5b81516119ce81612c63565b80820281158282048414176105f3576105f361385c565b808201808211156105f3576105f361385c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613a09577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var BurnMintTokenPoolABI = BurnMintTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go index 2c24ff0c6c..5ad79ab872 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnMintTokenPoolAndProxyMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b506040516200492538038062004925833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050818114620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c0516141ef620007366000396000818161050301528181611a7701526124c90152600081816104dd0152818161180f0152611d2a0152600081816102260152818161027b0152818161076001528181610d9a0152818161172f01528181611c4a01528181611e300152818161245f01526126b401526141ef6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639766b93211610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104c8578063dc0bd971146104db578063e0351e1314610501578063f2fde38b1461052757600080fd5b8063c0d786551461047a578063c4bffe2b1461048d578063c75eea9c146104a2578063cf7401f3146104b557600080fd5b8063a8d87a3b116100de578063a8d87a3b146103c7578063af58d59f146103da578063b0f479a114610449578063b79465801461046757600080fd5b80639766b9321461037f5780639a4575b914610392578063a7cd63b7146103b257600080fd5b80636d3d1a58116101715780637d54534e1161014b5780637d54534e1461032857806383826b2b1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b80636d3d1a58146102ef57806378a010b21461030d57806379ba50971461032057600080fd5b806321df0da7116101ad57806321df0da714610224578063240028e81461026b57806339077537146102b857806354c8a4f3146102da57600080fd5b806301ffc9a7146101d45780630a2fd493146101fc578063181f5a771461021c575b600080fd5b6101e76101e2366004613161565b61053a565b60405190151581526020015b60405180910390f35b61020f61020a3660046131c0565b61061f565b6040516101f39190613249565b61020f6106cf565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e7610279366004613289565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102cb6102c63660046132a6565b6106eb565b604051905181526020016101f3565b6102ed6102e836600461332e565b610878565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61031b36600461339a565b6108f3565b6102ed610a67565b6102ed610336366004613289565b610b64565b6101e761034936600461341d565b610bb3565b6101e761035c3660046131c0565b610c80565b60005473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61038d366004613289565b610c97565b6103a56103a0366004613454565b610d26565b6040516101f3919061348f565b6103ba610e96565b6040516101f391906134ef565b6102466103d53660046131c0565b503090565b6103ed6103e83660046131c0565b610ea7565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610246565b61020f6104753660046131c0565b610f7c565b6102ed610488366004613289565b610fa7565b61049561107b565b6040516101f39190613549565b6103ed6104b03660046131c0565b611133565b6102ed6104c3366004613700565b611205565b6102ed6104d6366004613745565b61128e565b7f0000000000000000000000000000000000000000000000000000000000000000610246565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b6102ed610535366004613289565b611714565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105cd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061061957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061064a90613787565b80601f016020809104026020016040519081016040528092919081815260200182805461067690613787565b80156106c35780601f10610698576101008083540402835291602001916106c3565b820191906000526020600020905b8154815290600101906020018083116106a657829003601f168201915b50505050509050919050565b6040518060600160405280602381526020016141c06023913981565b60408051602081019091526000815261070b61070683613876565b611728565b60095473ffffffffffffffffffffffffffffffffffffffff166107d6576040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b1580156107b957600080fd5b505af11580156107cd573d6000803e3d6000fd5b505050506107e7565b6107e76107e283613876565b611959565b6107f76060830160408401613289565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161085991815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108806119f2565b6108ed84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611a7592505050565b50505050565b6108fb6119f2565b61090483610c80565b61094b576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461097290613787565b80601f016020809104026020016040519081016040528092919081815260200182805461099e90613787565b80156109eb5780601f106109c0576101008083540402835291602001916109eb565b820191906000526020600020905b8154815290600101906020018083116109ce57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a1a8385836139bb565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a5993929190613ad5565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ae8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610942565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b6c6119f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610c795750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c799190613b39565b9392505050565b6000610619600567ffffffffffffffff8416611c2b565b610c9f6119f2565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d4b610d4683613b56565b611c43565b60095473ffffffffffffffffffffffffffffffffffffffff16610e10576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610df357600080fd5b505af1158015610e07573d6000803e3d6000fd5b50505050610e21565b610e21610e1c83613b56565b611e0d565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610e7b84602001602081019061047591906131c0565b81526040805160208181019092526000815291015292915050565b6060610ea26002611f27565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261061990611f34565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061064a90613787565b610faf6119f2565b73ffffffffffffffffffffffffffffffffffffffff8116610ffc576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d1a565b606060006110896005611f27565b90506000815167ffffffffffffffff8111156110a7576110a761358b565b6040519080825280602002602001820160405280156110d0578160200160208202803683370190505b50905060005b825181101561112c578281815181106110f1576110f1613bf8565b602002602001015182828151811061110b5761110b613bf8565b67ffffffffffffffff909216602092830291909101909101526001016110d6565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261061990611f34565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611245575060005473ffffffffffffffffffffffffffffffffffffffff163314155b1561127e576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610942565b611289838383611fe6565b505050565b6112966119f2565b60005b818110156112895760008383838181106112b5576112b5613bf8565b90506020028101906112c79190613c27565b6112d090613c65565b90506112e581608001518260200151156120d0565b6112f88160a001518260200151156120d0565b8060200151156115f457805161131a9060059067ffffffffffffffff16612209565b61135f5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610942565b60408101515115806113745750606081015151155b156113ab576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061158c9082613d19565b50606082015160058201906115a19082613d19565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506115e79493929190613e33565b60405180910390a161170b565b805161160c9060059067ffffffffffffffff16612215565b6116515780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610942565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116ba6004830182613113565b6116c8600583016000613113565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611299565b61171c6119f2565b61172581612221565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146117bd5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610942565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561186b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188f9190613b39565b156118c6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d38160200151612316565b60006118e2826020015161061f565b9050805160001480611906575080805190602001208260a001518051906020012014155b15611943578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109429190613249565b6119558260200151836060015161243c565b5050565b6009548151606083015160208401516040517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90941693638627fad6936119bd9390923392600401613ecc565b600060405180830381600087803b1580156119d757600080fd5b505af11580156119eb573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610942565b565b7f0000000000000000000000000000000000000000000000000000000000000000611acc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611b62576000838281518110611aec57611aec613bf8565b60200260200101519050611b0a81600261248390919063ffffffff16565b15611b595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611acf565b5060005b8151811015611289576000828281518110611b8357611b83613bf8565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bc75750611c23565b611bd26002826124a5565b15611c215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611b66565b60008181526001830160205260408120541515610c79565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611cd85760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610942565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611daa9190613b39565b15611de1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dee81604001516124c7565b611dfb8160200151612546565b61172581602001518260600151612694565b6009546060820151611e5a9173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116929116906126d8565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611ec294939291600401613f2d565b6000604051808303816000875af1158015611ee1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119559190810190613f8d565b60606000610c7983612765565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611fc282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611fa6919061402a565b85608001516fffffffffffffffffffffffffffffffff166127c0565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611fef83610c80565b612031576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610942565b61203c8260006120d0565b67ffffffffffffffff8316600090815260076020526040902061205f90836127ea565b61206a8160006120d0565b67ffffffffffffffff8316600090815260076020526040902061209090600201826127ea565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516120c39392919061403d565b60405180910390a1505050565b8151156121975781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612126575060408201516fffffffffffffffffffffffffffffffff16155b1561215f57816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161094291906140c0565b8015611955576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806121d0575060208201516fffffffffffffffffffffffffffffffff1615155b1561195557816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161094291906140c0565b6000610c79838361298c565b6000610c7983836129db565b3373ffffffffffffffffffffffffffffffffffffffff8216036122a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610942565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61231f81610c80565b612361576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610942565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156123e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124049190613b39565b611725576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610942565b67ffffffffffffffff8216600090815260076020526040902061195590600201827f0000000000000000000000000000000000000000000000000000000000000000612ace565b6000610c798373ffffffffffffffffffffffffffffffffffffffff84166129db565b6000610c798373ffffffffffffffffffffffffffffffffffffffff841661298c565b7f000000000000000000000000000000000000000000000000000000000000000015611725576124f8600282612e51565b611725576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610942565b61254f81610c80565b612591576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610942565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561260a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262e91906140fc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611725576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610942565b67ffffffffffffffff8216600090815260076020526040902061195590827f0000000000000000000000000000000000000000000000000000000000000000612ace565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611289908490612e80565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106c357602002820191906000526020600020905b8154815260200190600101908083116127a15750505050509050919050565b60006127df856127d08486614119565b6127da9087614130565b612f8c565b90505b949350505050565b815460009061281390700100000000000000000000000000000000900463ffffffff164261402a565b905080156128b5576001830154835461285b916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166127c0565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546128db916fffffffffffffffffffffffffffffffff9081169116612f8c565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906120c39084906140c0565b60008181526001830160205260408120546129d357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610619565b506000610619565b60008181526001830160205260408120548015612ac45760006129ff60018361402a565b8554909150600090612a139060019061402a565b9050818114612a78576000866000018281548110612a3357612a33613bf8565b9060005260206000200154905080876000018481548110612a5657612a56613bf8565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612a8957612a89614143565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610619565b6000915050610619565b825474010000000000000000000000000000000000000000900460ff161580612af5575081155b15612aff57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612b4590700100000000000000000000000000000000900463ffffffff164261402a565b90508015612c055781831115612b87576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612bc19083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166127c0565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612cbc5773ffffffffffffffffffffffffffffffffffffffff8416612c64576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610942565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610942565b84831015612dcf5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612d00908261402a565b612d0a878a61402a565b612d149190614130565b612d1e9190614172565b905073ffffffffffffffffffffffffffffffffffffffff8616612d77576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610942565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610942565b612dd9858461402a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610c79565b6000612ee2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612fa29092919063ffffffff16565b8051909150156112895780806020019051810190612f009190613b39565b611289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610942565b6000818310612f9b5781610c79565b5090919050565b60606127e28484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051612fd691906141ad565b60006040518083038185875af1925050503d8060008114613013576040519150601f19603f3d011682016040523d82523d6000602084013e613018565b606091505b509150915061302987838387613034565b979650505050505050565b606083156130ca5782516000036130c35773ffffffffffffffffffffffffffffffffffffffff85163b6130c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610942565b50816127e2565b6127e283838151156130df5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109429190613249565b50805461311f90613787565b6000825580601f1061312f575050565b601f01602090049060005260206000209081019061172591905b8082111561315d5760008155600101613149565b5090565b60006020828403121561317357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610c7957600080fd5b803567ffffffffffffffff811681146131bb57600080fd5b919050565b6000602082840312156131d257600080fd5b610c79826131a3565b60005b838110156131f65781810151838201526020016131de565b50506000910152565b600081518084526132178160208601602086016131db565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610c7960208301846131ff565b73ffffffffffffffffffffffffffffffffffffffff8116811461172557600080fd5b80356131bb8161325c565b60006020828403121561329b57600080fd5b8135610c798161325c565b6000602082840312156132b857600080fd5b813567ffffffffffffffff8111156132cf57600080fd5b82016101008185031215610c7957600080fd5b60008083601f8401126132f457600080fd5b50813567ffffffffffffffff81111561330c57600080fd5b6020830191508360208260051b850101111561332757600080fd5b9250929050565b6000806000806040858703121561334457600080fd5b843567ffffffffffffffff8082111561335c57600080fd5b613368888389016132e2565b9096509450602087013591508082111561338157600080fd5b5061338e878288016132e2565b95989497509550505050565b6000806000604084860312156133af57600080fd5b6133b8846131a3565b9250602084013567ffffffffffffffff808211156133d557600080fd5b818601915086601f8301126133e957600080fd5b8135818111156133f857600080fd5b87602082850101111561340a57600080fd5b6020830194508093505050509250925092565b6000806040838503121561343057600080fd5b613439836131a3565b915060208301356134498161325c565b809150509250929050565b60006020828403121561346657600080fd5b813567ffffffffffffffff81111561347d57600080fd5b820160a08185031215610c7957600080fd5b6020815260008251604060208401526134ab60608401826131ff565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526134e682826131ff565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561353d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161350b565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561353d57835167ffffffffffffffff1683529284019291840191600101613565565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156135de576135de61358b565b60405290565b60405160c0810167ffffffffffffffff811182821017156135de576135de61358b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561364e5761364e61358b565b604052919050565b801515811461172557600080fd5b80356131bb81613656565b80356fffffffffffffffffffffffffffffffff811681146131bb57600080fd5b6000606082840312156136a157600080fd5b6040516060810181811067ffffffffffffffff821117156136c4576136c461358b565b60405290508082356136d581613656565b81526136e36020840161366f565b60208201526136f46040840161366f565b60408201525092915050565b600080600060e0848603121561371557600080fd5b61371e846131a3565b925061372d856020860161368f565b915061373c856080860161368f565b90509250925092565b6000806020838503121561375857600080fd5b823567ffffffffffffffff81111561376f57600080fd5b61377b858286016132e2565b90969095509350505050565b600181811c9082168061379b57607f821691505b6020821081036137d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff8211156137f4576137f461358b565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261383157600080fd5b813561384461383f826137da565b613607565b81815284602083860101111561385957600080fd5b816020850160208301376000918101602001919091529392505050565b6000610100823603121561388957600080fd5b6138916135ba565b823567ffffffffffffffff808211156138a957600080fd5b6138b536838701613820565b83526138c3602086016131a3565b60208401526138d46040860161327e565b6040840152606085013560608401526138ef6080860161327e565b608084015260a085013591508082111561390857600080fd5b61391436838701613820565b60a084015260c085013591508082111561392d57600080fd5b61393936838701613820565b60c084015260e085013591508082111561395257600080fd5b5061395f36828601613820565b60e08301525092915050565b601f821115611289576000816000526020600020601f850160051c810160208610156139945750805b601f850160051c820191505b818110156139b3578281556001016139a0565b505050505050565b67ffffffffffffffff8311156139d3576139d361358b565b6139e7836139e18354613787565b8361396b565b6000601f841160018114613a395760008515613a035750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556119eb565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613a885786850135825560209485019460019092019101613a68565b5086821015613ac3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613ae860408301866131ff565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613b4b57600080fd5b8151610c7981613656565b600060a08236031215613b6857600080fd5b60405160a0810167ffffffffffffffff8282108183111715613b8c57613b8c61358b565b816040528435915080821115613ba157600080fd5b50613bae36828601613820565b825250613bbd602084016131a3565b60208201526040830135613bd08161325c565b6040820152606083810135908201526080830135613bed8161325c565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613c5b57600080fd5b9190910192915050565b60006101408236031215613c7857600080fd5b613c806135e4565b613c89836131a3565b8152613c9760208401613664565b6020820152604083013567ffffffffffffffff80821115613cb757600080fd5b613cc336838701613820565b60408401526060850135915080821115613cdc57600080fd5b50613ce936828601613820565b606083015250613cfc366080850161368f565b6080820152613d0e3660e0850161368f565b60a082015292915050565b815167ffffffffffffffff811115613d3357613d3361358b565b613d4781613d418454613787565b8461396b565b602080601f831160018114613d9a5760008415613d645750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139b3565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613de757888601518255948401946001909101908401613dc8565b5085821015613e2357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613e57818401876131ff565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613e959050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526134e6565b60a081526000613edf60a08301876131ff565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613f5c60a08301866131ff565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613f9f57600080fd5b815167ffffffffffffffff811115613fb657600080fd5b8201601f81018413613fc757600080fd5b8051613fd561383f826137da565b818152856020838501011115613fea57600080fd5b6134e68260208301602086016131db565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561061957610619613ffb565b67ffffffffffffffff8416815260e0810161408960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526127e2565b6060810161061982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561410e57600080fd5b8151610c798161325c565b808202811582820484141761061957610619613ffb565b8082018082111561061957610619613ffb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826141a8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613c5b8184602087016131db56fe4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b50604051620049e7380380620049e7833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050818114620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c0516142aa6200073d6000396000818161050301528181611b3101526125830152600081816104dd0152818161180f0152611de40152600081816102260152818161027b0152818161076001528181610d9a0152818161172f01528181611a2a01528181611d0401528181611eea01528181612519015261276e01526142aa6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639766b93211610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104c8578063dc0bd971146104db578063e0351e1314610501578063f2fde38b1461052757600080fd5b8063c0d786551461047a578063c4bffe2b1461048d578063c75eea9c146104a2578063cf7401f3146104b557600080fd5b8063a8d87a3b116100de578063a8d87a3b146103c7578063af58d59f146103da578063b0f479a114610449578063b79465801461046757600080fd5b80639766b9321461037f5780639a4575b914610392578063a7cd63b7146103b257600080fd5b80636d3d1a58116101715780637d54534e1161014b5780637d54534e1461032857806383826b2b1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b80636d3d1a58146102ef57806378a010b21461030d57806379ba50971461032057600080fd5b806321df0da7116101ad57806321df0da714610224578063240028e81461026b57806339077537146102b857806354c8a4f3146102da57600080fd5b806301ffc9a7146101d45780630a2fd493146101fc578063181f5a771461021c575b600080fd5b6101e76101e236600461321b565b61053a565b60405190151581526020015b60405180910390f35b61020f61020a36600461327a565b61061f565b6040516101f39190613303565b61020f6106cf565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e7610279366004613343565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102cb6102c6366004613360565b6106eb565b604051905181526020016101f3565b6102ed6102e83660046133e8565b610878565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61031b366004613454565b6108f3565b6102ed610a67565b6102ed610336366004613343565b610b64565b6101e76103493660046134d7565b610bb3565b6101e761035c36600461327a565b610c80565b60005473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61038d366004613343565b610c97565b6103a56103a036600461350e565b610d26565b6040516101f39190613549565b6103ba610e96565b6040516101f391906135a9565b6102466103d536600461327a565b503090565b6103ed6103e836600461327a565b610ea7565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610246565b61020f61047536600461327a565b610f7c565b6102ed610488366004613343565b610fa7565b61049561107b565b6040516101f39190613603565b6103ed6104b036600461327a565b611133565b6102ed6104c33660046137ba565b611205565b6102ed6104d63660046137ff565b61128e565b7f0000000000000000000000000000000000000000000000000000000000000000610246565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b6102ed610535366004613343565b611714565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105cd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061061957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061064a90613841565b80601f016020809104026020016040519081016040528092919081815260200182805461067690613841565b80156106c35780601f10610698576101008083540402835291602001916106c3565b820191906000526020600020905b8154815290600101906020018083116106a657829003601f168201915b50505050509050919050565b60405180606001604052806023815260200161427b6023913981565b60408051602081019091526000815261070b61070683613930565b611728565b60095473ffffffffffffffffffffffffffffffffffffffff166107d6576040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b1580156107b957600080fd5b505af11580156107cd573d6000803e3d6000fd5b505050506107e7565b6107e76107e283613930565b611959565b6107f76060830160408401613343565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161085991815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610880611aac565b6108ed84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611b2f92505050565b50505050565b6108fb611aac565b61090483610c80565b61094b576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461097290613841565b80601f016020809104026020016040519081016040528092919081815260200182805461099e90613841565b80156109eb5780601f106109c0576101008083540402835291602001916109eb565b820191906000526020600020905b8154815290600101906020018083116109ce57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a1a838583613a75565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a5993929190613b90565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ae8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610942565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b6c611aac565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610c795750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c799190613bf4565b9392505050565b6000610619600567ffffffffffffffff8416611ce5565b610c9f611aac565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d4b610d4683613c11565b611cfd565b60095473ffffffffffffffffffffffffffffffffffffffff16610e10576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610df357600080fd5b505af1158015610e07573d6000803e3d6000fd5b50505050610e21565b610e21610e1c83613c11565b611ec7565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610e7b846020016020810190610475919061327a565b81526040805160208181019092526000815291015292915050565b6060610ea26002611fe1565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261061990611fee565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061064a90613841565b610faf611aac565b73ffffffffffffffffffffffffffffffffffffffff8116610ffc576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d1a565b606060006110896005611fe1565b90506000815167ffffffffffffffff8111156110a7576110a7613645565b6040519080825280602002602001820160405280156110d0578160200160208202803683370190505b50905060005b825181101561112c578281815181106110f1576110f1613cb3565b602002602001015182828151811061110b5761110b613cb3565b67ffffffffffffffff909216602092830291909101909101526001016110d6565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261061990611fee565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611245575060005473ffffffffffffffffffffffffffffffffffffffff163314155b1561127e576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610942565b6112898383836120a0565b505050565b611296611aac565b60005b818110156112895760008383838181106112b5576112b5613cb3565b90506020028101906112c79190613ce2565b6112d090613d20565b90506112e5816080015182602001511561218a565b6112f88160a0015182602001511561218a565b8060200151156115f457805161131a9060059067ffffffffffffffff166122c3565b61135f5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610942565b60408101515115806113745750606081015151155b156113ab576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061158c9082613dd4565b50606082015160058201906115a19082613dd4565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506115e79493929190613eee565b60405180910390a161170b565b805161160c9060059067ffffffffffffffff166122cf565b6116515780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610942565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116ba60048301826131cd565b6116c86005830160006131cd565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611299565b61171c611aac565b611725816122db565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146117bd5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610942565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561186b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188f9190613bf4565b156118c6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d381602001516123d0565b60006118e2826020015161061f565b9050805160001480611906575080805190602001208260a001518051906020012014155b15611943578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109429190613303565b611955826020015183606001516124f6565b5050565b6009548151606083015160208401516040517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90941693638627fad6936119bd9390923092600401613f87565b600060405180830381600087803b1580156119d757600080fd5b505af11580156119eb573d6000803e3d6000fd5b5050505060608101516040517f095ea7b300000000000000000000000000000000000000000000000000000000815233600482015260248101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063095ea7b3906044016020604051808303816000875af1158015611a88573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119559190613bf4565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610942565b565b7f0000000000000000000000000000000000000000000000000000000000000000611b86576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611c1c576000838281518110611ba657611ba6613cb3565b60200260200101519050611bc481600261253d90919063ffffffff16565b15611c135760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611b89565b5060005b8151811015611289576000828281518110611c3d57611c3d613cb3565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c815750611cdd565b611c8c60028261255f565b15611cdb5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611c20565b60008181526001830160205260408120541515610c79565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611d925760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610942565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611e40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e649190613bf4565b15611e9b576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ea88160400151612581565b611eb58160200151612600565b6117258160200151826060015161274e565b6009546060820151611f149173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690612792565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611f7c94939291600401613fe8565b6000604051808303816000875af1158015611f9b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119559190810190614048565b60606000610c798361281f565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261207c82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261206091906140e5565b85608001516fffffffffffffffffffffffffffffffff1661287a565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6120a983610c80565b6120eb576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610942565b6120f682600061218a565b67ffffffffffffffff8316600090815260076020526040902061211990836128a4565b61212481600061218a565b67ffffffffffffffff8316600090815260076020526040902061214a90600201826128a4565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161217d939291906140f8565b60405180910390a1505050565b8151156122515781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806121e0575060408201516fffffffffffffffffffffffffffffffff16155b1561221957816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610942919061417b565b8015611955576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff1615158061228a575060208201516fffffffffffffffffffffffffffffffff1615155b1561195557816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610942919061417b565b6000610c798383612a46565b6000610c798383612a95565b3373ffffffffffffffffffffffffffffffffffffffff82160361235a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610942565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6123d981610c80565b61241b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610942565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561249a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124be9190613bf4565b611725576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610942565b67ffffffffffffffff8216600090815260076020526040902061195590600201827f0000000000000000000000000000000000000000000000000000000000000000612b88565b6000610c798373ffffffffffffffffffffffffffffffffffffffff8416612a95565b6000610c798373ffffffffffffffffffffffffffffffffffffffff8416612a46565b7f000000000000000000000000000000000000000000000000000000000000000015611725576125b2600282612f0b565b611725576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610942565b61260981610c80565b61264b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610942565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156126c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e891906141b7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611725576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610942565b67ffffffffffffffff8216600090815260076020526040902061195590827f0000000000000000000000000000000000000000000000000000000000000000612b88565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611289908490612f3a565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106c357602002820191906000526020600020905b81548152602001906001019080831161285b5750505050509050919050565b60006128998561288a84866141d4565b61289490876141eb565b613046565b90505b949350505050565b81546000906128cd90700100000000000000000000000000000000900463ffffffff16426140e5565b9050801561296f5760018301548354612915916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661287a565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612995916fffffffffffffffffffffffffffffffff9081169116613046565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061217d90849061417b565b6000818152600183016020526040812054612a8d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610619565b506000610619565b60008181526001830160205260408120548015612b7e576000612ab96001836140e5565b8554909150600090612acd906001906140e5565b9050818114612b32576000866000018281548110612aed57612aed613cb3565b9060005260206000200154905080876000018481548110612b1057612b10613cb3565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612b4357612b436141fe565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610619565b6000915050610619565b825474010000000000000000000000000000000000000000900460ff161580612baf575081155b15612bb957505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612bff90700100000000000000000000000000000000900463ffffffff16426140e5565b90508015612cbf5781831115612c41576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612c7b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661287a565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612d765773ffffffffffffffffffffffffffffffffffffffff8416612d1e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610942565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610942565b84831015612e895760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612dba90826140e5565b612dc4878a6140e5565b612dce91906141eb565b612dd8919061422d565b905073ffffffffffffffffffffffffffffffffffffffff8616612e31576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610942565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610942565b612e9385846140e5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610c79565b6000612f9c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661305c9092919063ffffffff16565b8051909150156112895780806020019051810190612fba9190613bf4565b611289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610942565b60008183106130555781610c79565b5090919050565b606061289c8484600085856000808673ffffffffffffffffffffffffffffffffffffffff1685876040516130909190614268565b60006040518083038185875af1925050503d80600081146130cd576040519150601f19603f3d011682016040523d82523d6000602084013e6130d2565b606091505b50915091506130e3878383876130ee565b979650505050505050565b6060831561318457825160000361317d5773ffffffffffffffffffffffffffffffffffffffff85163b61317d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610942565b508161289c565b61289c83838151156131995781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109429190613303565b5080546131d990613841565b6000825580601f106131e9575050565b601f01602090049060005260206000209081019061172591905b808211156132175760008155600101613203565b5090565b60006020828403121561322d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610c7957600080fd5b803567ffffffffffffffff8116811461327557600080fd5b919050565b60006020828403121561328c57600080fd5b610c798261325d565b60005b838110156132b0578181015183820152602001613298565b50506000910152565b600081518084526132d1816020860160208601613295565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610c7960208301846132b9565b73ffffffffffffffffffffffffffffffffffffffff8116811461172557600080fd5b803561327581613316565b60006020828403121561335557600080fd5b8135610c7981613316565b60006020828403121561337257600080fd5b813567ffffffffffffffff81111561338957600080fd5b82016101008185031215610c7957600080fd5b60008083601f8401126133ae57600080fd5b50813567ffffffffffffffff8111156133c657600080fd5b6020830191508360208260051b85010111156133e157600080fd5b9250929050565b600080600080604085870312156133fe57600080fd5b843567ffffffffffffffff8082111561341657600080fd5b6134228883890161339c565b9096509450602087013591508082111561343b57600080fd5b506134488782880161339c565b95989497509550505050565b60008060006040848603121561346957600080fd5b6134728461325d565b9250602084013567ffffffffffffffff8082111561348f57600080fd5b818601915086601f8301126134a357600080fd5b8135818111156134b257600080fd5b8760208285010111156134c457600080fd5b6020830194508093505050509250925092565b600080604083850312156134ea57600080fd5b6134f38361325d565b9150602083013561350381613316565b809150509250929050565b60006020828403121561352057600080fd5b813567ffffffffffffffff81111561353757600080fd5b820160a08185031215610c7957600080fd5b60208152600082516040602084015261356560608401826132b9565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526135a082826132b9565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156135f757835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016135c5565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156135f757835167ffffffffffffffff168352928401929184019160010161361f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561369857613698613645565b60405290565b60405160c0810167ffffffffffffffff8111828210171561369857613698613645565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561370857613708613645565b604052919050565b801515811461172557600080fd5b803561327581613710565b80356fffffffffffffffffffffffffffffffff8116811461327557600080fd5b60006060828403121561375b57600080fd5b6040516060810181811067ffffffffffffffff8211171561377e5761377e613645565b604052905080823561378f81613710565b815261379d60208401613729565b60208201526137ae60408401613729565b60408201525092915050565b600080600060e084860312156137cf57600080fd5b6137d88461325d565b92506137e78560208601613749565b91506137f68560808601613749565b90509250925092565b6000806020838503121561381257600080fd5b823567ffffffffffffffff81111561382957600080fd5b6138358582860161339c565b90969095509350505050565b600181811c9082168061385557607f821691505b60208210810361388e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff8211156138ae576138ae613645565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126138eb57600080fd5b81356138fe6138f982613894565b6136c1565b81815284602083860101111561391357600080fd5b816020850160208301376000918101602001919091529392505050565b6000610100823603121561394357600080fd5b61394b613674565b823567ffffffffffffffff8082111561396357600080fd5b61396f368387016138da565b835261397d6020860161325d565b602084015261398e60408601613338565b6040840152606085013560608401526139a960808601613338565b608084015260a08501359150808211156139c257600080fd5b6139ce368387016138da565b60a084015260c08501359150808211156139e757600080fd5b6139f3368387016138da565b60c084015260e0850135915080821115613a0c57600080fd5b50613a19368286016138da565b60e08301525092915050565b601f821115611289576000816000526020600020601f850160051c81016020861015613a4e5750805b601f850160051c820191505b81811015613a6d57828155600101613a5a565b505050505050565b67ffffffffffffffff831115613a8d57613a8d613645565b613aa183613a9b8354613841565b83613a25565b6000601f841160018114613af35760008515613abd5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613b89565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613b425786850135825560209485019460019092019101613b22565b5086821015613b7d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613ba360408301866132b9565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613c0657600080fd5b8151610c7981613710565b600060a08236031215613c2357600080fd5b60405160a0810167ffffffffffffffff8282108183111715613c4757613c47613645565b816040528435915080821115613c5c57600080fd5b50613c69368286016138da565b825250613c786020840161325d565b60208201526040830135613c8b81613316565b6040820152606083810135908201526080830135613ca881613316565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613d1657600080fd5b9190910192915050565b60006101408236031215613d3357600080fd5b613d3b61369e565b613d448361325d565b8152613d526020840161371e565b6020820152604083013567ffffffffffffffff80821115613d7257600080fd5b613d7e368387016138da565b60408401526060850135915080821115613d9757600080fd5b50613da4368286016138da565b606083015250613db73660808501613749565b6080820152613dc93660e08501613749565b60a082015292915050565b815167ffffffffffffffff811115613dee57613dee613645565b613e0281613dfc8454613841565b84613a25565b602080601f831160018114613e555760008415613e1f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613a6d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613ea257888601518255948401946001909101908401613e83565b5085821015613ede57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613f12818401876132b9565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613f509050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526135a0565b60a081526000613f9a60a08301876132b9565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a06020820152600061401760a08301866132b9565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561405a57600080fd5b815167ffffffffffffffff81111561407157600080fd5b8201601f8101841361408257600080fd5b80516140906138f982613894565b8181528560208385010111156140a557600080fd5b6135a0826020830160208601613295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610619576106196140b6565b67ffffffffffffffff8416815260e0810161414460208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261289c565b6060810161061982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156141c957600080fd5b8151610c7981613316565b8082028115828204841417610619576106196140b6565b80820180821115610619576106196140b6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614263577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613d1681846020870161329556fe4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", } var BurnMintTokenPoolAndProxyABI = BurnMintTokenPoolAndProxyMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go index 6631733928..dc1e17729b 100644 --- a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnWithFromMintTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620044eb380380620044eb8339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161397262000b79600039600081816104a90152818161173401526121180152600081816104830152818161156501526119ea0152600081816102050152818161025a015281816106e9015281816114850152818161190a01528181611b02015281816120ae015261230301526139726000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc1461046e578063dc0bd97114610481578063e0351e13146104a7578063f2fde38b146104cd57600080fd5b8063c4bffe2b14610433578063c75eea9c14610448578063cf7401f31461045b57600080fd5b8063b0f479a1116100c8578063b0f479a1146103ef578063b79465801461040d578063c0d786551461042057600080fd5b80639a4575b91461034b578063a7cd63b71461036b578063af58d59f1461038057600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146102ff5780637d54534e146103075780638926f54f1461031a5780638da5cb5b1461032d57600080fd5b806354c8a4f3146102b95780636d3d1a58146102ce57806378a010b2146102ec57600080fd5b806321df0da71161018c57806321df0da714610203578063240028e81461024a578063390775371461029757600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612aa6565b6104e0565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b05565b6105c5565b6040516101d29190612b84565b6101ee610675565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c6610258366004612bc4565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102aa6102a5366004612be1565b610691565b604051905181526020016101d2565b6102cc6102c7366004612c69565b6107ec565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610225565b6102cc6102fa366004612cd5565b610867565b6102cc6109db565b6102cc610315366004612bc4565b610ad8565b6101c6610328366004612b05565b610b27565b60005473ffffffffffffffffffffffffffffffffffffffff16610225565b61035e610359366004612d58565b610b3e565b6040516101d29190612d93565b610373610be5565b6040516101d29190612df3565b61039361038e366004612b05565b610bf6565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610225565b6101ee61041b366004612b05565b610ccb565b6102cc61042e366004612bc4565b610cf6565b61043b610dd1565b6040516101d29190612e4d565b610393610456366004612b05565b610e89565b6102cc610469366004612fb5565b610f5b565b6102cc61047c366004612ffa565b610fe4565b7f0000000000000000000000000000000000000000000000000000000000000000610225565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b6102cc6104db366004612bc4565b61146a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061057357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105bf57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906105f09061303c565b80601f016020809104026020016040519081016040528092919081815260200182805461061c9061303c565b80156106695780601f1061063e57610100808354040283529160200191610669565b820191906000526020600020905b81548152906001019060200180831161064c57829003601f168201915b50505050509050919050565b6040518060600160405280602381526020016139436023913981565b6040805160208101909152600081526106b16106ac8361313a565b61147e565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561074257600080fd5b505af1158015610756573d6000803e3d6000fd5b5061076b925050506060830160408401612bc4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f084606001356040516107cd91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6107f46116af565b6108618484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061173292505050565b50505050565b61086f6116af565b61087883610b27565b6108bf576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546108e69061303c565b80601f01602080910402602001604051908101604052809291908181526020018280546109129061303c565b801561095f5780601f106109345761010080835404028352916020019161095f565b820191906000526020600020905b81548152906001019060200180831161094257829003601f168201915b5050505067ffffffffffffffff861660009081526007602052604090209192505060040161098e83858361327f565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf8285856040516109cd93929190613399565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108b6565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ae06116af565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105bf600567ffffffffffffffff84166118e8565b6040805180820190915260608082526020820152610b63610b5e836133fd565b611903565b610b708260600135611acd565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610bca84602001602081019061041b9190612b05565b81526040805160208181019092526000815291015292915050565b6060610bf16002611b76565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105bf90611b83565b67ffffffffffffffff811660009081526007602052604090206005018054606091906105f09061303c565b610cfe6116af565b73ffffffffffffffffffffffffffffffffffffffff8116610d4b576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610ddf6005611b76565b90506000815167ffffffffffffffff811115610dfd57610dfd612e8f565b604051908082528060200260200182016040528015610e26578160200160208202803683370190505b50905060005b8251811015610e8257828181518110610e4757610e4761349f565b6020026020010151828281518110610e6157610e6161349f565b67ffffffffffffffff90921660209283029190910190910152600101610e2c565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105bf90611b83565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610f9b575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610fd4576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108b6565b610fdf838383611c35565b505050565b610fec6116af565b60005b81811015610fdf57600083838381811061100b5761100b61349f565b905060200281019061101d91906134ce565b6110269061350c565b905061103b8160800151826020015115611d1f565b61104e8160a00151826020015115611d1f565b80602001511561134a5780516110709060059067ffffffffffffffff16611e58565b6110b55780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108b6565b60408101515115806110ca5750606081015151155b15611101576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906112e290826135c0565b50606082015160058201906112f790826135c0565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061133d94939291906136da565b60405180910390a1611461565b80516113629060059067ffffffffffffffff16611e64565b6113a75780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108b6565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114106004830182612a58565b61141e600583016000612a58565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101610fef565b6114726116af565b61147b81611e70565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115135760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108b6565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156115c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e59190613773565b1561161c576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116298160200151611f65565b600061163882602001516105c5565b905080516000148061165c575080805190602001208260a001518051906020012014155b15611699578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108b69190612b84565b6116ab8260200151836060015161208b565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611730576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108b6565b565b7f0000000000000000000000000000000000000000000000000000000000000000611789576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561181f5760008382815181106117a9576117a961349f565b602002602001015190506117c78160026120d290919063ffffffff16565b156118165760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010161178c565b5060005b8151811015610fdf5760008282815181106118405761184061349f565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361188457506118e0565b61188f6002826120f4565b156118de5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611823565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119985760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108b6565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6a9190613773565b15611aa1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611aae8160400151612116565b611abb8160200151612195565b61147b816020015182606001516122e3565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b158015611b5b57600080fd5b505af1158015611b6f573d6000803e3d6000fd5b5050505050565b606060006118fc83612327565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c1182606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611bf591906137bf565b85608001516fffffffffffffffffffffffffffffffff16612382565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c3e83610b27565b611c80576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108b6565b611c8b826000611d1f565b67ffffffffffffffff83166000908152600760205260409020611cae90836123ac565b611cb9816000611d1f565b67ffffffffffffffff83166000908152600760205260409020611cdf90600201826123ac565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d12939291906137d2565b60405180910390a1505050565b815115611de65781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611d75575060408201516fffffffffffffffffffffffffffffffff16155b15611dae57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108b69190613855565b80156116ab576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e1f575060208201516fffffffffffffffffffffffffffffffff1615155b156116ab57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108b69190613855565b60006118fc838361254e565b60006118fc838361259d565b3373ffffffffffffffffffffffffffffffffffffffff821603611eef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108b6565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611f6e81610b27565b611fb0576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108b6565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561202f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120539190613773565b61147b576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108b6565b67ffffffffffffffff821660009081526007602052604090206116ab90600201827f0000000000000000000000000000000000000000000000000000000000000000612690565b60006118fc8373ffffffffffffffffffffffffffffffffffffffff841661259d565b60006118fc8373ffffffffffffffffffffffffffffffffffffffff841661254e565b7f00000000000000000000000000000000000000000000000000000000000000001561147b57612147600282612a13565b61147b576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108b6565b61219e81610b27565b6121e0576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108b6565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612259573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227d9190613891565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461147b576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108b6565b67ffffffffffffffff821660009081526007602052604090206116ab90827f0000000000000000000000000000000000000000000000000000000000000000612690565b60608160000180548060200260200160405190810160405280929190818152602001828054801561066957602002820191906000526020600020905b8154815260200190600101908083116123635750505050509050919050565b60006123a18561239284866138ae565b61239c90876138c5565b612a42565b90505b949350505050565b81546000906123d590700100000000000000000000000000000000900463ffffffff16426137bf565b90508015612477576001830154835461241d916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612382565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461249d916fffffffffffffffffffffffffffffffff9081169116612a42565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d12908490613855565b6000818152600183016020526040812054612595575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105bf565b5060006105bf565b600081815260018301602052604081205480156126865760006125c16001836137bf565b85549091506000906125d5906001906137bf565b905081811461263a5760008660000182815481106125f5576125f561349f565b90600052602060002001549050808760000184815481106126185761261861349f565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061264b5761264b6138d8565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105bf565b60009150506105bf565b825474010000000000000000000000000000000000000000900460ff1615806126b7575081155b156126c157505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061270790700100000000000000000000000000000000900463ffffffff16426137bf565b905080156127c75781831115612749576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127839083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612382565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561287e5773ffffffffffffffffffffffffffffffffffffffff8416612826576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108b6565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108b6565b848310156129915760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128c290826137bf565b6128cc878a6137bf565b6128d691906138c5565b6128e09190613907565b905073ffffffffffffffffffffffffffffffffffffffff8616612939576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108b6565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108b6565b61299b85846137bf565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156118fc565b6000818310612a5157816118fc565b5090919050565b508054612a649061303c565b6000825580601f10612a74575050565b601f01602090049060005260206000209081019061147b91905b80821115612aa25760008155600101612a8e565b5090565b600060208284031215612ab857600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146118fc57600080fd5b803567ffffffffffffffff81168114612b0057600080fd5b919050565b600060208284031215612b1757600080fd5b6118fc82612ae8565b6000815180845260005b81811015612b4657602081850181015186830182015201612b2a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006118fc6020830184612b20565b73ffffffffffffffffffffffffffffffffffffffff8116811461147b57600080fd5b8035612b0081612b97565b600060208284031215612bd657600080fd5b81356118fc81612b97565b600060208284031215612bf357600080fd5b813567ffffffffffffffff811115612c0a57600080fd5b820161010081850312156118fc57600080fd5b60008083601f840112612c2f57600080fd5b50813567ffffffffffffffff811115612c4757600080fd5b6020830191508360208260051b8501011115612c6257600080fd5b9250929050565b60008060008060408587031215612c7f57600080fd5b843567ffffffffffffffff80821115612c9757600080fd5b612ca388838901612c1d565b90965094506020870135915080821115612cbc57600080fd5b50612cc987828801612c1d565b95989497509550505050565b600080600060408486031215612cea57600080fd5b612cf384612ae8565b9250602084013567ffffffffffffffff80821115612d1057600080fd5b818601915086601f830112612d2457600080fd5b813581811115612d3357600080fd5b876020828501011115612d4557600080fd5b6020830194508093505050509250925092565b600060208284031215612d6a57600080fd5b813567ffffffffffffffff811115612d8157600080fd5b820160a081850312156118fc57600080fd5b602081526000825160406020840152612daf6060840182612b20565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612dea8282612b20565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e4157835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e0f565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e4157835167ffffffffffffffff1683529284019291840191600101612e69565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612ee257612ee2612e8f565b60405290565b60405160c0810167ffffffffffffffff81118282101715612ee257612ee2612e8f565b801515811461147b57600080fd5b8035612b0081612f0b565b80356fffffffffffffffffffffffffffffffff81168114612b0057600080fd5b600060608284031215612f5657600080fd5b6040516060810181811067ffffffffffffffff82111715612f7957612f79612e8f565b6040529050808235612f8a81612f0b565b8152612f9860208401612f24565b6020820152612fa960408401612f24565b60408201525092915050565b600080600060e08486031215612fca57600080fd5b612fd384612ae8565b9250612fe28560208601612f44565b9150612ff18560808601612f44565b90509250925092565b6000806020838503121561300d57600080fd5b823567ffffffffffffffff81111561302457600080fd5b61303085828601612c1d565b90969095509350505050565b600181811c9082168061305057607f821691505b602082108103613089577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130a057600080fd5b813567ffffffffffffffff808211156130bb576130bb612e8f565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561310157613101612e8f565b8160405283815286602085880101111561311a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561314d57600080fd5b613155612ebe565b823567ffffffffffffffff8082111561316d57600080fd5b6131793683870161308f565b835261318760208601612ae8565b602084015261319860408601612bb9565b6040840152606085013560608401526131b360808601612bb9565b608084015260a08501359150808211156131cc57600080fd5b6131d83683870161308f565b60a084015260c08501359150808211156131f157600080fd5b6131fd3683870161308f565b60c084015260e085013591508082111561321657600080fd5b506132233682860161308f565b60e08301525092915050565b601f821115610fdf576000816000526020600020601f850160051c810160208610156132585750805b601f850160051c820191505b8181101561327757828155600101613264565b505050505050565b67ffffffffffffffff83111561329757613297612e8f565b6132ab836132a5835461303c565b8361322f565b6000601f8411600181146132fd57600085156132c75750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611b6f565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561334c578685013582556020948501946001909201910161332c565b5086821015613387577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133ac6040830186612b20565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561340f57600080fd5b60405160a0810167ffffffffffffffff828210818311171561343357613433612e8f565b81604052843591508082111561344857600080fd5b506134553682860161308f565b82525061346460208401612ae8565b6020820152604083013561347781612b97565b604082015260608381013590820152608083013561349481612b97565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261350257600080fd5b9190910192915050565b6000610140823603121561351f57600080fd5b613527612ee8565b61353083612ae8565b815261353e60208401612f19565b6020820152604083013567ffffffffffffffff8082111561355e57600080fd5b61356a3683870161308f565b6040840152606085013591508082111561358357600080fd5b506135903682860161308f565b6060830152506135a33660808501612f44565b60808201526135b53660e08501612f44565b60a082015292915050565b815167ffffffffffffffff8111156135da576135da612e8f565b6135ee816135e8845461303c565b8461322f565b602080601f831160018114613641576000841561360b5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613277565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561368e5788860151825594840194600190910190840161366f565b50858210156136ca57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526136fe81840187612b20565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061373c9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612dea565b60006020828403121561378557600080fd5b81516118fc81612f0b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105bf576105bf613790565b67ffffffffffffffff8416815260e0810161381e60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123a4565b606081016105bf82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138a357600080fd5b81516118fc81612b97565b80820281158282048414176105bf576105bf613790565b808201808211156105bf576105bf613790565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261393d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fe4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e302d646576a164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b50604051620045ac380380620045ac8339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c051613a2c62000b80600039600081816104a9015281816117ee01526121d20152600081816104830152818161161f0152611aa40152600081816102050152818161025a015281816106e9015281816107900152818161153f015281816119c401528181611bbc0152818161216801526123bd0152613a2c6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc1461046e578063dc0bd97114610481578063e0351e13146104a7578063f2fde38b146104cd57600080fd5b8063c4bffe2b14610433578063c75eea9c14610448578063cf7401f31461045b57600080fd5b8063b0f479a1116100c8578063b0f479a1146103ef578063b79465801461040d578063c0d786551461042057600080fd5b80639a4575b91461034b578063a7cd63b71461036b578063af58d59f1461038057600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146102ff5780637d54534e146103075780638926f54f1461031a5780638da5cb5b1461032d57600080fd5b806354c8a4f3146102b95780636d3d1a58146102ce57806378a010b2146102ec57600080fd5b806321df0da71161018c57806321df0da714610203578063240028e81461024a578063390775371461029757600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612b60565b6104e0565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612bbf565b6105c5565b6040516101d29190612c3e565b6101ee610675565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c6610258366004612c7e565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102aa6102a5366004612c9b565b610691565b604051905181526020016101d2565b6102cc6102c7366004612d23565b6108a6565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610225565b6102cc6102fa366004612d8f565b610921565b6102cc610a95565b6102cc610315366004612c7e565b610b92565b6101c6610328366004612bbf565b610be1565b60005473ffffffffffffffffffffffffffffffffffffffff16610225565b61035e610359366004612e12565b610bf8565b6040516101d29190612e4d565b610373610c9f565b6040516101d29190612ead565b61039361038e366004612bbf565b610cb0565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610225565b6101ee61041b366004612bbf565b610d85565b6102cc61042e366004612c7e565b610db0565b61043b610e8b565b6040516101d29190612f07565b610393610456366004612bbf565b610f43565b6102cc61046936600461306f565b611015565b6102cc61047c3660046130b4565b61109e565b7f0000000000000000000000000000000000000000000000000000000000000000610225565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b6102cc6104db366004612c7e565b611524565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061057357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105bf57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906105f0906130f6565b80601f016020809104026020016040519081016040528092919081815260200182805461061c906130f6565b80156106695780601f1061063e57610100808354040283529160200191610669565b820191906000526020600020905b81548152906001019060200180831161064c57829003601f168201915b50505050509050919050565b6040518060600160405280602381526020016139fd6023913981565b6040805160208101909152600081526106b16106ac836131f4565b611538565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152306004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561074257600080fd5b505af1158015610756573d6000803e3d6000fd5b50506040517f095ea7b3000000000000000000000000000000000000000000000000000000008152336004820152606085013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16925063095ea7b391506044016020604051808303816000875af11580156107f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081491906132e9565b506108256060830160408401612c7e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161088791815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108ae611769565b61091b848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920191909152506117ec92505050565b50505050565b610929611769565b61093283610be1565b610979576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109a0906130f6565b80601f01602080910402602001604051908101604052809291908181526020018280546109cc906130f6565b8015610a195780601f106109ee57610100808354040283529160200191610a19565b820191906000526020600020905b8154815290600101906020018083116109fc57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a48838583613356565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a8793929190613470565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610970565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b9a611769565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105bf600567ffffffffffffffff84166119a2565b6040805180820190915260608082526020820152610c1d610c18836134d4565b6119bd565b610c2a8260600135611b87565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c8484602001602081019061041b9190612bbf565b81526040805160208181019092526000815291015292915050565b6060610cab6002611c30565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105bf90611c3d565b67ffffffffffffffff811660009081526007602052604090206005018054606091906105f0906130f6565b610db8611769565b73ffffffffffffffffffffffffffffffffffffffff8116610e05576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e996005611c30565b90506000815167ffffffffffffffff811115610eb757610eb7612f49565b604051908082528060200260200182016040528015610ee0578160200160208202803683370190505b50905060005b8251811015610f3c57828181518110610f0157610f01613576565b6020026020010151828281518110610f1b57610f1b613576565b67ffffffffffffffff90921660209283029190910190910152600101610ee6565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105bf90611c3d565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611055575060005473ffffffffffffffffffffffffffffffffffffffff163314155b1561108e576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610970565b611099838383611cef565b505050565b6110a6611769565b60005b818110156110995760008383838181106110c5576110c5613576565b90506020028101906110d791906135a5565b6110e0906135e3565b90506110f58160800151826020015115611dd9565b6111088160a00151826020015115611dd9565b80602001511561140457805161112a9060059067ffffffffffffffff16611f12565b61116f5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610970565b60408101515115806111845750606081015151155b156111bb576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061139c9082613697565b50606082015160058201906113b19082613697565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506113f794939291906137b1565b60405180910390a161151b565b805161141c9060059067ffffffffffffffff16611f1e565b6114615780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610970565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114ca6004830182612b12565b6114d8600583016000612b12565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016110a9565b61152c611769565b61153581611f2a565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115cd5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610970565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169f91906132e9565b156116d6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116e3816020015161201f565b60006116f282602001516105c5565b9050805160001480611716575080805190602001208260a001518051906020012014155b15611753578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109709190612c3e565b61176582602001518360600151612145565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146117ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610970565b565b7f0000000000000000000000000000000000000000000000000000000000000000611843576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118d957600083828151811061186357611863613576565b6020026020010151905061188181600261218c90919063ffffffff16565b156118d05760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611846565b5060005b81518110156110995760008282815181106118fa576118fa613576565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361193e575061199a565b6119496002826121ae565b156119985760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016118dd565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611a525760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610970565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2491906132e9565b15611b5b576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b6881604001516121d0565b611b75816020015161224f565b6115358160200151826060015161239d565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b158015611c1557600080fd5b505af1158015611c29573d6000803e3d6000fd5b5050505050565b606060006119b6836123e1565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611ccb82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611caf9190613879565b85608001516fffffffffffffffffffffffffffffffff1661243c565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611cf883610be1565b611d3a576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610970565b611d45826000611dd9565b67ffffffffffffffff83166000908152600760205260409020611d689083612466565b611d73816000611dd9565b67ffffffffffffffff83166000908152600760205260409020611d999060020182612466565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611dcc9392919061388c565b60405180910390a1505050565b815115611ea05781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611e2f575060408201516fffffffffffffffffffffffffffffffff16155b15611e6857816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610970919061390f565b8015611765576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611ed9575060208201516fffffffffffffffffffffffffffffffff1615155b1561176557816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610970919061390f565b60006119b68383612608565b60006119b68383612657565b3373ffffffffffffffffffffffffffffffffffffffff821603611fa9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610970565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61202881610be1565b61206a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610970565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156120e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210d91906132e9565b611535576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610970565b67ffffffffffffffff8216600090815260076020526040902061176590600201827f000000000000000000000000000000000000000000000000000000000000000061274a565b60006119b68373ffffffffffffffffffffffffffffffffffffffff8416612657565b60006119b68373ffffffffffffffffffffffffffffffffffffffff8416612608565b7f00000000000000000000000000000000000000000000000000000000000000001561153557612201600282612acd565b611535576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610970565b61225881610be1565b61229a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610970565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612313573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612337919061394b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611535576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610970565b67ffffffffffffffff8216600090815260076020526040902061176590827f000000000000000000000000000000000000000000000000000000000000000061274a565b60608160000180548060200260200160405190810160405280929190818152602001828054801561066957602002820191906000526020600020905b81548152602001906001019080831161241d5750505050509050919050565b600061245b8561244c8486613968565b612456908761397f565b612afc565b90505b949350505050565b815460009061248f90700100000000000000000000000000000000900463ffffffff1642613879565b9050801561253157600183015483546124d7916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661243c565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612557916fffffffffffffffffffffffffffffffff9081169116612afc565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611dcc90849061390f565b600081815260018301602052604081205461264f575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105bf565b5060006105bf565b6000818152600183016020526040812054801561274057600061267b600183613879565b855490915060009061268f90600190613879565b90508181146126f45760008660000182815481106126af576126af613576565b90600052602060002001549050808760000184815481106126d2576126d2613576565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061270557612705613992565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105bf565b60009150506105bf565b825474010000000000000000000000000000000000000000900460ff161580612771575081155b1561277b57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906127c190700100000000000000000000000000000000900463ffffffff1642613879565b905080156128815781831115612803576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461283d9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661243c565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156129385773ffffffffffffffffffffffffffffffffffffffff84166128e0576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610970565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610970565b84831015612a4b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061297c9082613879565b612986878a613879565b612990919061397f565b61299a91906139c1565b905073ffffffffffffffffffffffffffffffffffffffff86166129f3576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610970565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610970565b612a558584613879565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156119b6565b6000818310612b0b57816119b6565b5090919050565b508054612b1e906130f6565b6000825580601f10612b2e575050565b601f01602090049060005260206000209081019061153591905b80821115612b5c5760008155600101612b48565b5090565b600060208284031215612b7257600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146119b657600080fd5b803567ffffffffffffffff81168114612bba57600080fd5b919050565b600060208284031215612bd157600080fd5b6119b682612ba2565b6000815180845260005b81811015612c0057602081850181015186830182015201612be4565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119b66020830184612bda565b73ffffffffffffffffffffffffffffffffffffffff8116811461153557600080fd5b8035612bba81612c51565b600060208284031215612c9057600080fd5b81356119b681612c51565b600060208284031215612cad57600080fd5b813567ffffffffffffffff811115612cc457600080fd5b820161010081850312156119b657600080fd5b60008083601f840112612ce957600080fd5b50813567ffffffffffffffff811115612d0157600080fd5b6020830191508360208260051b8501011115612d1c57600080fd5b9250929050565b60008060008060408587031215612d3957600080fd5b843567ffffffffffffffff80821115612d5157600080fd5b612d5d88838901612cd7565b90965094506020870135915080821115612d7657600080fd5b50612d8387828801612cd7565b95989497509550505050565b600080600060408486031215612da457600080fd5b612dad84612ba2565b9250602084013567ffffffffffffffff80821115612dca57600080fd5b818601915086601f830112612dde57600080fd5b813581811115612ded57600080fd5b876020828501011115612dff57600080fd5b6020830194508093505050509250925092565b600060208284031215612e2457600080fd5b813567ffffffffffffffff811115612e3b57600080fd5b820160a081850312156119b657600080fd5b602081526000825160406020840152612e696060840182612bda565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612ea48282612bda565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612efb57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612ec9565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612efb57835167ffffffffffffffff1683529284019291840191600101612f23565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f9c57612f9c612f49565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f9c57612f9c612f49565b801515811461153557600080fd5b8035612bba81612fc5565b80356fffffffffffffffffffffffffffffffff81168114612bba57600080fd5b60006060828403121561301057600080fd5b6040516060810181811067ffffffffffffffff8211171561303357613033612f49565b604052905080823561304481612fc5565b815261305260208401612fde565b602082015261306360408401612fde565b60408201525092915050565b600080600060e0848603121561308457600080fd5b61308d84612ba2565b925061309c8560208601612ffe565b91506130ab8560808601612ffe565b90509250925092565b600080602083850312156130c757600080fd5b823567ffffffffffffffff8111156130de57600080fd5b6130ea85828601612cd7565b90969095509350505050565b600181811c9082168061310a57607f821691505b602082108103613143577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f83011261315a57600080fd5b813567ffffffffffffffff8082111561317557613175612f49565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156131bb576131bb612f49565b816040528381528660208588010111156131d457600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561320757600080fd5b61320f612f78565b823567ffffffffffffffff8082111561322757600080fd5b61323336838701613149565b835261324160208601612ba2565b602084015261325260408601612c73565b60408401526060850135606084015261326d60808601612c73565b608084015260a085013591508082111561328657600080fd5b61329236838701613149565b60a084015260c08501359150808211156132ab57600080fd5b6132b736838701613149565b60c084015260e08501359150808211156132d057600080fd5b506132dd36828601613149565b60e08301525092915050565b6000602082840312156132fb57600080fd5b81516119b681612fc5565b601f821115611099576000816000526020600020601f850160051c8101602086101561332f5750805b601f850160051c820191505b8181101561334e5782815560010161333b565b505050505050565b67ffffffffffffffff83111561336e5761336e612f49565b6133828361337c83546130f6565b83613306565b6000601f8411600181146133d4576000851561339e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611c29565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156134235786850135825560209485019460019092019101613403565b508682101561345e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006134836040830186612bda565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a082360312156134e657600080fd5b60405160a0810167ffffffffffffffff828210818311171561350a5761350a612f49565b81604052843591508082111561351f57600080fd5b5061352c36828601613149565b82525061353b60208401612ba2565b6020820152604083013561354e81612c51565b604082015260608381013590820152608083013561356b81612c51565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126135d957600080fd5b9190910192915050565b600061014082360312156135f657600080fd5b6135fe612fa2565b61360783612ba2565b815261361560208401612fd3565b6020820152604083013567ffffffffffffffff8082111561363557600080fd5b61364136838701613149565b6040840152606085013591508082111561365a57600080fd5b5061366736828601613149565b60608301525061367a3660808501612ffe565b608082015261368c3660e08501612ffe565b60a082015292915050565b815167ffffffffffffffff8111156136b1576136b1612f49565b6136c5816136bf84546130f6565b84613306565b602080601f83116001811461371857600084156136e25750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561334e565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561376557888601518255948401946001909101908401613746565b50858210156137a157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526137d581840187612bda565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506138139050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612ea4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105bf576105bf61384a565b67ffffffffffffffff8416815260e081016138d860208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261245e565b606081016105bf82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561395d57600080fd5b81516119b681612c51565b80820281158282048414176105bf576105bf61384a565b808201808211156105bf576105bf61384a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826139f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fe4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e302d646576a164736f6c6343000818000a", } var BurnWithFromMintTokenPoolABI = BurnWithFromMintTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go index a414481a3c..2dea06bd75 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go @@ -164,7 +164,7 @@ type MultiOCR3BaseOCRConfigArgs struct { var EVM2EVMMultiOffRampMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162006bab38038062006bab8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615ed562000cd6600039600081816102530152612cac0152600081816102240152612f860152600081816101f50152818161147b01526118d00152600081816101c501526128a1015260008181611e5e0152611eaa0152615ed56000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b1461059c578063f716f99f146105af578063ff888fb1146105c257600080fd5b8063d2a15d3514610556578063e9d68a8e14610569578063ece670b61461058957600080fd5b8063991a5018116100bd578063991a5018146104de578063c673e584146104f1578063ccd37ba31461051157600080fd5b806385572ffb146104b55780638da5cb5b146104c357600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba50971461049a5780637d4eef60146104a257600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a366004614091565b6105e5565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d19190614200565b61018f6103313660046142ab565b6105f9565b61018f61034436600461435e565b6109fd565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143b2565b610a66565b6040516102d1919061440f565b61043d6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b830481166020850152780100000000000000000000000000000000000000000000000083048116948401949094527c01000000000000000000000000000000000000000000000000000000009091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610abc565b61018f6104b036600461497c565b610b7a565b61018f610177366004614aa7565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104ec366004614af6565b610d1a565b6105046104ff366004614b7b565b610d2b565b6040516102d19190614bdb565b61054861051f366004614c50565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f610564366004614c7a565b610e89565b61057c610577366004614cef565b610f43565b6040516102d19190614d0a565b61018f610597366004614d58565b611062565b61018f6105aa366004614dbc565b6113d2565b61018f6105bd366004614e41565b6113e3565b6105d56105d0366004614f7f565b611425565b60405190151581526020016102d1565b6105ed6114e6565b6105f681611542565b50565b60006106078789018961511d565b8051515190915015158061062057508051602001515115155b156107205760095460208a01359067ffffffffffffffff808316911610156106df576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f926106a8929101615385565b600060405180830381600087803b1580156106c257600080fd5b505af11580156106d6573d6000803e3d6000fd5b5050505061071e565b81602001515160000361071e576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109465760008260200151828151811061074857610748615288565b6020026020010151905060008160000151905061076481611884565b600061076f82611986565b602084015151815491925067ffffffffffffffff9081167501000000000000000000000000000000000000000000909204161415806107c5575060208084015190810151905167ffffffffffffffff9182169116115b1561080e57825160208401516040517feefb0cac000000000000000000000000000000000000000000000000000000008152610805929190600401615398565b60405180910390fd5b60408301518061084a576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108bd5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101829052604401610805565b60208085015101516108d09060016153e3565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000067ffffffffffffffff928316021790925592511660009081526008602090815260408083209483529390529190912042905550600101610723565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610976919061540b565b60405180910390a16109f260008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506119ed915050565b505050505050505050565b610a3d610a0c828401846154a8565b6040805160008082526020820190925290610a37565b6060815260200190600190039081610a225790505b50611d64565b604080516000808252602082019092529050610a606001858585858660006119ed565b50505050565b6000610a74600160046154dd565b6002610a81608085615506565b67ffffffffffffffff16610a95919061552d565b610a9f8585611e14565b901c166003811115610ab357610ab36143e5565b90505b92915050565b6001546001600160a01b03163314610b165760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610805565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b82611e5b565b815181518114610bbe576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d0a576000848281518110610bdd57610bdd615288565b60200260200101519050600081602001515190506000858481518110610c0557610c05615288565b6020026020010151905080518214610c49576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cfb576000828281518110610c6857610c68615288565b6020026020010151905080600014610cf25784602001518281518110610c9057610c90615288565b602002602001015160800151811015610cf25784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024810183905260448101829052606401610805565b50600101610c4c565b50505050806001019050610bc1565b50610d158383611d64565b505050565b610d226114e6565b6105f681611edc565b610d6e6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610e1757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610df9575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e7957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e5b575b5050505050815250509050919050565b610e916114e6565b60005b81811015610d15576000838383818110610eb057610eb0615288565b905060400201803603810190610ec69190615544565b9050610ed58160200151611425565b610f3a57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e94565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff161515938601939093527501000000000000000000000000000000000000000000909204909216948301949094526001840180549394929391840191610fe29061557d565b80601f016020809104026020016040519081016040528092919081815260200182805461100e9061557d565b8015610e795780601f1061103057610100808354040283529160200191610e79565b820191906000526020600020905b81548152906001019060200180831161103e57505050919092525091949350505050565b33301461109b576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600080825260208201909252816110d8565b60408051808201909152600080825260208201528152602001906001900390816110b15790505b5060a0840151519091501561110b576111088360a001518460200151856060015186600001516020015186612089565b90505b6040805160a0810182528451518152845160209081015167ffffffffffffffff1681830152808601518351600094840192611147929101614200565b60408051601f19818403018152918152908252868101516020830152018390526005549091506001600160a01b03168015611254576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a1906111c1908590600401615659565b600060405180830381600087803b1580156111db57600080fd5b505af19250505080156111ec575060015b611254573d80801561121a576040519150601f19603f3d011682016040523d82523d6000602084013e61121f565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016108059190614200565b60408501515115801561126957506080850151155b80611280575060608501516001600160a01b03163b155b806112c0575060608501516112be906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612167565b155b156112cc575050505050565b845160209081015167ffffffffffffffff16600090815260069091526040808220546080880151606089015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf9798392611344928992611388929160040161566c565b6000604051808303816000875af1158015611363573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261138b91908101906156a8565b5091509150816113c957806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016108059190614200565b50505050505050565b6113da6114e6565b6105f681612183565b6113eb6114e6565b60005b81518110156114215761141982828151811061140c5761140c615288565b6020026020010151612239565b6001016113ee565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156114c2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab6919061573e565b6000546001600160a01b031633146115405760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610805565b565b60005b815181101561142157600082828151811061156257611562615288565b602002602001015190506000816020015190508067ffffffffffffffff166000036115b9576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b03166115fa576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916116259061557d565b80601f01602080910402602001604051908101604052809291908181526020018280546116519061557d565b801561169e5780601f106116735761010080835404028352916020019161169e565b820191906000526020600020905b81548152906001019060200180831161168157829003601f168201915b5050505050905060008460600151905081516000036117815780516000036116f2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001830161170082826157a3565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000017835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16117d4565b80805190602001208280519060200120146117d4576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610805565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b9061186c908690615863565b60405180910390a25050505050806001019050611545565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561191f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611943919061573e565b156105f6576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610805565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610ab6576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610805565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611a4c8760a4615931565b9050826060015115611a94578451611a6590602061552d565b8651611a7290602061552d565b611a7d9060a0615931565b611a879190615931565b611a919082615931565b90505b368114611ad6576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610805565b5081518114611b1e5781516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610805565b611b26611e5b565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611b7457611b746143e5565b6002811115611b8557611b856143e5565b9052509050600281602001516002811115611ba257611ba26143e5565b148015611bf65750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611bde57611bde615288565b6000918252602090912001546001600160a01b031633145b611c2c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611d0e576020820151611c47906001615944565b60ff16855114611c83576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611cbe576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611cd092919061595d565b604051908190038120611ce7918b9060200161596d565b604051602081830303815290604052805190602001209050611d0c8a8288888861257d565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d9e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611e0d57611e05858281518110611dd357611dd3615288565b602002602001015184611dff57858381518110611df257611df2615288565b6020026020010151612794565b83612794565b600101611db5565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611e39608085615981565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f000000000000000000000000000000000000000000000000000000000000000014611540576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610805565b80516001600160a01b0316611f1d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16939093177c010000000000000000000000000000000000000000000000000000000093871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060855167ffffffffffffffff8111156120a5576120a5613ea8565b6040519080825280602002602001820160405280156120ea57816020015b60408051808201909152600080825260208201528152602001906001900390816120c35790505b50905060005b865181101561215d5761213887828151811061210e5761210e615288565b602002602001015187878787868151811061212b5761212b615288565b6020026020010151612f25565b82828151811061214a5761214a615288565b60209081029190910101526001016120f0565b5095945050505050565b600061217283613334565b8015610ab35750610ab38383613398565b336001600160a01b038216036121db5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610805565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff16600003612264576000604051631b3fab5160e11b815260040161080591906159a8565b60208082015160ff808216600090815260029093526040832060018101549293909283921690036122d157606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612326565b6060840151600182015460ff6201000090910416151590151514612326576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff84166004820152602401610805565b60a08401518051601f60ff82161115612355576001604051631b3fab5160e11b815260040161080591906159a8565b6123bb85856003018054806020026020016040519081016040528092919081815260200182805480156123b157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612393575b5050505050613467565b8560600151156124ea5761242985856002018054806020026020016040519081016040528092919081815260200182805480156123b1576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311612393575050505050613467565b608086015180516124439060028701906020840190613e02565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f10156124a3576002604051631b3fab5160e11b815260040161080591906159a8565b60408801516124b39060036159c2565b60ff168160ff16116124db576003604051631b3fab5160e11b815260040161080591906159a8565b6124e7878360016134d0565b50505b6124f6858360026134d0565b815161250b9060038601906020850190613e02565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f54793612564938a939260028b019291906159de565b60405180910390a161257585613650565b505050505050565b612585613e74565b835160005b8181101561278a5760006001888684602081106125a9576125a9615288565b6125b691901a601b615944565b8985815181106125c8576125c8615288565b60200260200101518986815181106125e2576125e2615288565b602002602001015160405160008152602001604052604051612620949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612642573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b038516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156126a3576126a36143e5565b60028111156126b4576126b46143e5565b90525090506001816020015160028111156126d1576126d16143e5565b14612708576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061271f5761271f615288565b60200201511561275b576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061277657612776615288565b91151560209092020152505060010161258a565b5050505050505050565b815161279f81611884565b60006127aa82611986565b60208501515190915060008190036127ed576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461282b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561284657612846613ea8565b60405190808252806020026020018201604052801561286f578160200160208202803683370190505b50905060005b828110156129e45760008760200151828151811061289557612895615288565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461292857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610805565b6129be8186600101805461293b9061557d565b80601f01602080910402602001604051908101604052809291908181526020018280546129679061557d565b80156129b45780601f10612989576101008083540402835291602001916129b4565b820191906000526020600020905b81548152906001019060200180831161299757829003601f168201915b505050505061366c565b8383815181106129d0576129d0615288565b602090810291909101015250600101612875565b5060006129fb858389606001518a6080015161378e565b905080600003612a43576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610805565b8551151560005b848110156109f257600089602001518281518110612a6a57612a6a615288565b602002602001015190506000612a8889836000015160600151610a66565b90506000816003811115612a9e57612a9e6143e5565b1480612abb57506003816003811115612ab957612ab96143e5565b145b612b12578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612f1d565b8315612be257600454600090600160a01b900463ffffffff16612b3587426154dd565b1190508080612b5557506003826003811115612b5357612b536143e5565b145b612b97576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b166004820152602401610805565b8a8481518110612ba957612ba9615288565b6020026020010151600014612bdc578a8481518110612bca57612bca615288565b60200260200101518360800181815250505b50612c43565b6000816003811115612bf657612bf66143e5565b14612c43578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612b03565b81516080015167ffffffffffffffff1615612d31576000816003811115612c6c57612c6c6143e5565b03612d315781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612ce3928e929190600401615a90565b6020604051808303816000875af1158015612d02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d26919061573e565b612d31575050612f1d565b60008b604001518481518110612d4957612d49615288565b6020026020010151905080518360a001515114612dad578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d1660048301529091166024820152604401610805565b612dc18a84600001516060015160016137e4565b600080612dce858461388c565b91509150612de58c866000015160600151846137e4565b8615612e55576003826003811115612dff57612dff6143e5565b03612e55576000846003811115612e1857612e186143e5565b14612e55578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261080591908390600401615abd565b6002826003811115612e6957612e696143e5565b14612ec3576003826003811115612e8257612e826143e5565b14612ec3578451606001516040517f926c5a3e000000000000000000000000000000000000000000000000000000008152610805918e918590600401615ad6565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612f0f9087908790615afc565b60405180910390a450505050505b600101612a4a565b60408051808201909152600080825260208201526000612f488760200151613956565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612fcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ff19190615b1c565b90506001600160a01b038116158061303957506130376001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612167565b155b1561307b576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610805565b6000806131816040518061010001604052808b81526020018967ffffffffffffffff1681526020018a6001600160a01b031681526020018c606001518152602001866001600160a01b031681526020018c6000015181526020018c604001518152602001888152506040516024016130f39190615b39565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3907753700000000000000000000000000000000000000000000000000000000179052600454859063ffffffff7c01000000000000000000000000000000000000000000000000000000009091041661138860846139fc565b5091509150816131bf57806040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016108059190614200565b80516020146132075780516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610805565b60008180602001905181019061321d9190615c06565b6040516001600160a01b038b166024820152604481018290529091506132ca9060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600454879063ffffffff78010000000000000000000000000000000000000000000000009091041661138860846139fc565b5090935091508261330957816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016108059190614200565b604080518082019091526001600160a01b039095168552602085015250919250505095945050505050565b6000613360827f01ffc9a700000000000000000000000000000000000000000000000000000000613398565b8015610ab65750613391827fffffffff00000000000000000000000000000000000000000000000000000000613398565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613450575060208210155b801561345c5750600081115b979650505050505050565b60005b8151811015610d155760ff83166000908152600360205260408120835190919084908490811061349c5761349c615288565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161346a565b60005b82518160ff161015610a60576000838260ff16815181106134f6576134f6615288565b6020026020010151905060006002811115613513576135136143e5565b60ff80871660009081526003602090815260408083206001600160a01b03871684529091529020546101009004166002811115613552576135526143e5565b14613573576004604051631b3fab5160e11b815260040161080591906159a8565b6001600160a01b0381166135b3576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156135d9576135d96143e5565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff191617610100836002811115613636576136366143e5565b0217905550905050508061364990615c1f565b90506134d3565b60ff81166105f6576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936136b2937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c3e565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976136fb9794969395929491939101615c71565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016137329190615d68565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061379c858585613b22565b90506137a781611425565b6137b55760009150506137dc565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026137f3608085615506565b67ffffffffffffffff16613807919061552d565b905060006138158585611e14565b905081613824600160046154dd565b901b19168183600381111561383b5761383b6143e5565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161386a608088615981565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906138d09087908790600401615dc8565b600060405180830381600087803b1580156138ea57600080fd5b505af19250505080156138fb575060015b61393a573d808015613929576040519150601f19603f3d011682016040523d82523d6000602084013e61392e565b606091505b5060039250905061394f565b50506040805160208101909152600081526002905b9250929050565b6000815160201461399557816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016108059190614200565b6000828060200190518101906139ab9190615c06565b90506001600160a01b038111806139c3575061040081105b15610ab657826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016108059190614200565b6000606060008361ffff1667ffffffffffffffff811115613a1f57613a1f613ea8565b6040519080825280601f01601f191660200182016040528015613a49576020820181803683370190505b509150863b613a7c577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613aaf577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613ae8577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b0b5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b63576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b7757506101018111155b613b94576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bbe576040516309bde33960e01b815260040160405180910390fd5b80600003613beb5786600081518110613bd957613bd9615288565b60200260200101519350505050613dba565b60008167ffffffffffffffff811115613c0657613c06613ea8565b604051908082528060200260200182016040528015613c2f578160200160208202803683370190505b50905060008080805b85811015613d595760006001821b8b811603613c935788851015613c7c578c5160018601958e918110613c6d57613c6d615288565b60200260200101519050613cb5565b8551600185019487918110613c6d57613c6d615288565b8b5160018401938d918110613caa57613caa615288565b602002602001015190505b600089861015613ce5578d5160018701968f918110613cd657613cd6615288565b60200260200101519050613d07565b8651600186019588918110613cfc57613cfc615288565b602002602001015190505b82851115613d28576040516309bde33960e01b815260040160405180910390fd5b613d328282613dc1565b878481518110613d4457613d44615288565b60209081029190910101525050600101613c38565b506001850382148015613d6b57508683145b8015613d7657508581145b613d93576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613da857613da8615288565b60200260200101519750505050505050505b9392505050565b6000818310613dd957613dd48284613ddf565b610ab3565b610ab383835b604080516001602082015290810183905260608101829052600090608001613770565b828054828255906000526020600020908101928215613e64579160200282015b82811115613e64578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e22565b50613e70929150613e93565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e705760008155600101613e94565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613ee157613ee1613ea8565b60405290565b60405160a0810167ffffffffffffffff81118282101715613ee157613ee1613ea8565b60405160c0810167ffffffffffffffff81118282101715613ee157613ee1613ea8565b6040805190810167ffffffffffffffff81118282101715613ee157613ee1613ea8565b6040516060810167ffffffffffffffff81118282101715613ee157613ee1613ea8565b604051601f8201601f1916810167ffffffffffffffff81118282101715613f9c57613f9c613ea8565b604052919050565b600067ffffffffffffffff821115613fbe57613fbe613ea8565b5060051b60200190565b6001600160a01b03811681146105f657600080fd5b803567ffffffffffffffff81168114613ff557600080fd5b919050565b80151581146105f657600080fd5b8035613ff581613ffa565b600067ffffffffffffffff82111561402d5761402d613ea8565b50601f01601f191660200190565b600082601f83011261404c57600080fd5b813561405f61405a82614013565b613f73565b81815284602083860101111561407457600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140a457600080fd5b823567ffffffffffffffff808211156140bc57600080fd5b818501915085601f8301126140d057600080fd5b81356140de61405a82613fa4565b81815260059190911b830184019084810190888311156140fd57600080fd5b8585015b838110156141a3578035858111156141195760008081fd5b86016080818c03601f19018113156141315760008081fd5b614139613ebe565b8983013561414681613fc8565b81526040614155848201613fdd565b8b83015260608085013561416881613ffa565b8383015292840135928984111561418157600091508182fd5b61418f8f8d8688010161403b565b908301525085525050918601918601614101565b5098975050505050505050565b60005b838110156141cb5781810151838201526020016141b3565b50506000910152565b600081518084526141ec8160208601602086016141b0565b601f01601f19169290920160200192915050565b602081526000610ab360208301846141d4565b8060608101831015610ab657600080fd5b60008083601f84011261423657600080fd5b50813567ffffffffffffffff81111561424e57600080fd5b60208301915083602082850101111561394f57600080fd5b60008083601f84011261427857600080fd5b50813567ffffffffffffffff81111561429057600080fd5b6020830191508360208260051b850101111561394f57600080fd5b60008060008060008060008060e0898b0312156142c757600080fd5b6142d18a8a614213565b9750606089013567ffffffffffffffff808211156142ee57600080fd5b6142fa8c838d01614224565b909950975060808b013591508082111561431357600080fd5b61431f8c838d01614266565b909750955060a08b013591508082111561433857600080fd5b506143458b828c01614266565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561437357600080fd5b61437d8585614213565b9250606084013567ffffffffffffffff81111561439957600080fd5b6143a586828701614224565b9497909650939450505050565b600080604083850312156143c557600080fd5b6143ce83613fdd565b91506143dc60208401613fdd565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061440b5761440b6143e5565b9052565b60208101610ab682846143fb565b600060a0828403121561442f57600080fd5b614437613ee7565b90508135815261444960208301613fdd565b602082015261445a60408301613fdd565b604082015261446b60608301613fdd565b606082015261447c60808301613fdd565b608082015292915050565b8035613ff581613fc8565b600082601f8301126144a357600080fd5b813560206144b361405a83613fa4565b82815260059290921b840181019181810190868411156144d257600080fd5b8286015b848110156145a857803567ffffffffffffffff808211156144f75760008081fd5b8189019150608080601f19848d030112156145125760008081fd5b61451a613ebe565b878401358381111561452c5760008081fd5b61453a8d8a8388010161403b565b825250604080850135848111156145515760008081fd5b61455f8e8b8389010161403b565b8a84015250606080860135858111156145785760008081fd5b6145868f8c838a010161403b565b92840192909252949092013593810193909352505083529183019183016144d6565b509695505050505050565b600061014082840312156145c657600080fd5b6145ce613f0a565b90506145da838361441d565b815260a082013567ffffffffffffffff808211156145f757600080fd5b6146038583860161403b565b602084015260c084013591508082111561461c57600080fd5b6146288583860161403b565b604084015261463960e08501614487565b6060840152610100840135608084015261012084013591508082111561465e57600080fd5b5061466b84828501614492565b60a08301525092915050565b600082601f83011261468857600080fd5b8135602061469861405a83613fa4565b82815260059290921b840181019181810190868411156146b757600080fd5b8286015b848110156145a857803567ffffffffffffffff8111156146db5760008081fd5b6146e98986838b01016145b3565b8452509183019183016146bb565b600082601f83011261470857600080fd5b8135602061471861405a83613fa4565b82815260059290921b8401810191818101908684111561473757600080fd5b8286015b848110156145a857803567ffffffffffffffff81111561475b5760008081fd5b6147698986838b010161403b565b84525091830191830161473b565b600082601f83011261478857600080fd5b8135602061479861405a83613fa4565b82815260059290921b840181019181810190868411156147b757600080fd5b8286015b848110156145a857803567ffffffffffffffff8111156147db5760008081fd5b6147e98986838b01016146f7565b8452509183019183016147bb565b600082601f83011261480857600080fd5b8135602061481861405a83613fa4565b8083825260208201915060208460051b87010193508684111561483a57600080fd5b602086015b848110156145a8578035835291830191830161483f565b600082601f83011261486757600080fd5b8135602061487761405a83613fa4565b82815260059290921b8401810191818101908684111561489657600080fd5b8286015b848110156145a857803567ffffffffffffffff808211156148bb5760008081fd5b818901915060a080601f19848d030112156148d65760008081fd5b6148de613ee7565b6148e9888501613fdd565b8152604080850135848111156148ff5760008081fd5b61490d8e8b83890101614677565b8a84015250606080860135858111156149265760008081fd5b6149348f8c838a0101614777565b838501525060809150818601358581111561494f5760008081fd5b61495d8f8c838a01016147f7565b918401919091525091909301359083015250835291830191830161489a565b600080604080848603121561499057600080fd5b833567ffffffffffffffff808211156149a857600080fd5b6149b487838801614856565b94506020915081860135818111156149cb57600080fd5b8601601f810188136149dc57600080fd5b80356149ea61405a82613fa4565b81815260059190911b8201840190848101908a831115614a0957600080fd5b8584015b83811015614a9557803586811115614a255760008081fd5b8501603f81018d13614a375760008081fd5b87810135614a4761405a82613fa4565b81815260059190911b82018a0190898101908f831115614a675760008081fd5b928b01925b82841015614a855783358252928a0192908a0190614a6c565b8652505050918601918601614a0d565b50809750505050505050509250929050565b600060208284031215614ab957600080fd5b813567ffffffffffffffff811115614ad057600080fd5b820160a08185031215613dba57600080fd5b803563ffffffff81168114613ff557600080fd5b600060a08284031215614b0857600080fd5b614b10613ee7565b8235614b1b81613fc8565b8152614b2960208401614ae2565b6020820152614b3a60408401614ae2565b6040820152614b4b60608401614ae2565b60608201526080830135614b5e81613fc8565b60808201529392505050565b803560ff81168114613ff557600080fd5b600060208284031215614b8d57600080fd5b610ab382614b6a565b60008151808452602080850194506020840160005b83811015614bd05781516001600160a01b031687529582019590820190600101614bab565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c2a60e0840182614b96565b90506040840151601f198483030160c0850152614c478282614b96565b95945050505050565b60008060408385031215614c6357600080fd5b614c6c83613fdd565b946020939093013593505050565b60008060208385031215614c8d57600080fd5b823567ffffffffffffffff80821115614ca557600080fd5b818501915085601f830112614cb957600080fd5b813581811115614cc857600080fd5b8660208260061b8501011115614cdd57600080fd5b60209290920196919550909350505050565b600060208284031215614d0157600080fd5b610ab382613fdd565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526137dc60a08401826141d4565b60008060408385031215614d6b57600080fd5b823567ffffffffffffffff80821115614d8357600080fd5b614d8f868387016145b3565b93506020850135915080821115614da557600080fd5b50614db2858286016146f7565b9150509250929050565b600060208284031215614dce57600080fd5b8135613dba81613fc8565b600082601f830112614dea57600080fd5b81356020614dfa61405a83613fa4565b8083825260208201915060208460051b870101935086841115614e1c57600080fd5b602086015b848110156145a8578035614e3481613fc8565b8352918301918301614e21565b60006020808385031215614e5457600080fd5b823567ffffffffffffffff80821115614e6c57600080fd5b818501915085601f830112614e8057600080fd5b8135614e8e61405a82613fa4565b81815260059190911b83018401908481019088831115614ead57600080fd5b8585015b838110156141a357803585811115614ec857600080fd5b860160c0818c03601f19011215614edf5760008081fd5b614ee7613f0a565b8882013581526040614efa818401614b6a565b8a8301526060614f0b818501614b6a565b8284015260809150614f1e828501614008565b9083015260a08381013589811115614f365760008081fd5b614f448f8d83880101614dd9565b838501525060c0840135915088821115614f5e5760008081fd5b614f6c8e8c84870101614dd9565b9083015250845250918601918601614eb1565b600060208284031215614f9157600080fd5b5035919050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114613ff557600080fd5b600082601f830112614fd557600080fd5b81356020614fe561405a83613fa4565b82815260069290921b8401810191818101908684111561500457600080fd5b8286015b848110156145a857604081890312156150215760008081fd5b615029613f2d565b61503282613fdd565b815261503f858301614f98565b81860152835291830191604001615008565b600082601f83011261506257600080fd5b8135602061507261405a83613fa4565b82815260079290921b8401810191818101908684111561509157600080fd5b8286015b848110156145a85780880360808112156150af5760008081fd5b6150b7613f50565b6150c083613fdd565b8152604080601f19840112156150d65760008081fd5b6150de613f2d565b92506150eb878501613fdd565b83526150f8818501613fdd565b8388015281870192909252606083013591810191909152835291830191608001615095565b6000602080838503121561513057600080fd5b823567ffffffffffffffff8082111561514857600080fd5b8185019150604080838803121561515e57600080fd5b615166613f2d565b83358381111561517557600080fd5b84016040818a03121561518757600080fd5b61518f613f2d565b81358581111561519e57600080fd5b8201601f81018b136151af57600080fd5b80356151bd61405a82613fa4565b81815260069190911b8201890190898101908d8311156151dc57600080fd5b928a01925b8284101561522c5787848f0312156151f95760008081fd5b615201613f2d565b843561520c81613fc8565b8152615219858d01614f98565b818d0152825292870192908a01906151e1565b84525050508187013593508484111561524457600080fd5b6152508a858401614fc4565b818801528252508385013591508282111561526a57600080fd5b61527688838601615051565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561530a57835180516001600160a01b031684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168584015292840192918501916001016152be565b50508583015187820388850152805180835290840192506000918401905b80831015615379578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685830152928401926001929092019190850190615328565b50979650505050505050565b602081526000610ab3602083018461529e565b67ffffffffffffffff8316815260608101613dba6020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff818116838216019080821115615404576154046153cd565b5092915050565b60006020808352606084516040808487015261542a606087018361529e565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141a357845167ffffffffffffffff81511683528781015161548a89850182805167ffffffffffffffff908116835260209182015116910152565b5084015182870152938601936001929092019160809091019061544b565b6000602082840312156154ba57600080fd5b813567ffffffffffffffff8111156154d157600080fd5b6137dc84828501614856565b81810381811115610ab657610ab66153cd565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff80841680615521576155216154f0565b92169190910692915050565b8082028115828204841417610ab657610ab66153cd565b60006040828403121561555657600080fd5b61555e613f2d565b61556783613fdd565b8152602083013560208201528091505092915050565b600181811c9082168061559157607f821691505b6020821081036155b157634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a060408701526155eb60a08701826141d4565b90506060850151868203606088015261560482826141d4565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561537957835180516001600160a01b0316835286015186830152928501926001929092019190840190615627565b602081526000610ab360208301846155b7565b60808152600061567f60808301876155b7565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b6000806000606084860312156156bd57600080fd5b83516156c881613ffa565b602085015190935067ffffffffffffffff8111156156e557600080fd5b8401601f810186136156f657600080fd5b805161570461405a82614013565b81815287602083850101111561571957600080fd5b61572a8260208301602086016141b0565b809450505050604084015190509250925092565b60006020828403121561575057600080fd5b8151613dba81613ffa565b601f821115610d15576000816000526020600020601f850160051c810160208610156157845750805b601f850160051c820191505b8181101561257557828155600101615790565b815167ffffffffffffffff8111156157bd576157bd613ea8565b6157d1816157cb845461557d565b8461575b565b602080601f83116001811461580657600084156157ee5750858301515b600019600386901b1c1916600185901b178555612575565b600085815260208120601f198616915b8281101561583557888601518255948401946001909101908401615816565b50858210156158535787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546158b58161557d565b8060a089015260c060018316600081146158d657600181146158f257615922565b60ff19841660c08b015260c083151560051b8b01019450615922565b85600052602060002060005b848110156159195781548c82018501529088019089016158fe565b8b0160c0019550505b50929998505050505050505050565b80820180821115610ab657610ab66153cd565b60ff8181168382160190811115610ab657610ab66153cd565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061599c5761599c6154f0565b92169190910492915050565b60208101600583106159bc576159bc6143e5565b91905290565b60ff8181168382160290811690818114615404576154046153cd565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a365784546001600160a01b031683526001948501949284019201615a11565b50508481036060860152865180825290820192508187019060005b81811015615a765782516001600160a01b031685529383019391830191600101615a51565b50505060ff851660808501525090505b9695505050505050565b600067ffffffffffffffff808616835280851660208401525060606040830152614c4760608301846141d4565b8281526040602082015260006137dc60408301846141d4565b67ffffffffffffffff848116825283166020820152606081016137dc60408301846143fb565b615b0681846143fb565b6040602082015260006137dc60408301846141d4565b600060208284031215615b2e57600080fd5b8151613dba81613fc8565b6020815260008251610100806020850152615b586101208501836141d4565b91506020850151615b75604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615baf60a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bcc84836141d4565b935060c08701519150808685030160e0870152615be984836141d4565b935060e0870151915080868503018387015250615a8683826141d4565b600060208284031215615c1857600080fd5b5051919050565b600060ff821660ff8103615c3557615c356153cd565b60010192915050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152615a8660808301846141d4565b86815260c060208201526000615c8a60c08301886141d4565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d5b57601f19868403018952815160808151818652615d07828701826141d4565b9150508582015185820387870152615d1f82826141d4565b91505060408083015186830382880152615d3983826141d4565b6060948501519790940196909652505098840198925090830190600101615ce1565b5090979650505050505050565b602081526000610ab36020830184615cc4565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d5b57601f19868403018952615db68383516141d4565b98840198925090830190600101615d9a565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e306101808501836141d4565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e6d84836141d4565b935060608801519150615e8c6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615eb38282615cc4565b9150508281036020840152614c478185615d7b56fea164736f6c6343000818000a", + Bin: "0x6101206040523480156200001257600080fd5b5060405162006bb338038062006bb38339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615edd62000cd6600039600081816102530152612cac0152600081816102240152612f860152600081816101f50152818161147b01526118d00152600081816101c501526128a1015260008181611e5e0152611eaa0152615edd6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b1461059c578063f716f99f146105af578063ff888fb1146105c257600080fd5b8063d2a15d3514610556578063e9d68a8e14610569578063ece670b61461058957600080fd5b8063991a5018116100bd578063991a5018146104de578063c673e584146104f1578063ccd37ba31461051157600080fd5b806385572ffb146104b55780638da5cb5b146104c357600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba50971461049a5780637d4eef60146104a257600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a366004614099565b6105e5565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d19190614208565b61018f6103313660046142b3565b6105f9565b61018f610344366004614366565b6109fd565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143ba565b610a66565b6040516102d19190614417565b61043d6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b830481166020850152780100000000000000000000000000000000000000000000000083048116948401949094527c01000000000000000000000000000000000000000000000000000000009091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610abc565b61018f6104b0366004614984565b610b7a565b61018f610177366004614aaf565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104ec366004614afe565b610d1a565b6105046104ff366004614b83565b610d2b565b6040516102d19190614be3565b61054861051f366004614c58565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f610564366004614c82565b610e89565b61057c610577366004614cf7565b610f43565b6040516102d19190614d12565b61018f610597366004614d60565b611062565b61018f6105aa366004614dc4565b6113d2565b61018f6105bd366004614e49565b6113e3565b6105d56105d0366004614f87565b611425565b60405190151581526020016102d1565b6105ed6114e6565b6105f681611542565b50565b600061060787890189615125565b8051515190915015158061062057508051602001515115155b156107205760095460208a01359067ffffffffffffffff808316911610156106df576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f926106a892910161538d565b600060405180830381600087803b1580156106c257600080fd5b505af11580156106d6573d6000803e3d6000fd5b5050505061071e565b81602001515160000361071e576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109465760008260200151828151811061074857610748615290565b6020026020010151905060008160000151905061076481611884565b600061076f82611986565b602084015151815491925067ffffffffffffffff9081167501000000000000000000000000000000000000000000909204161415806107c5575060208084015190810151905167ffffffffffffffff9182169116115b1561080e57825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526108059291906004016153a0565b60405180910390fd5b60408301518061084a576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108bd5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101829052604401610805565b60208085015101516108d09060016153eb565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000067ffffffffffffffff928316021790925592511660009081526008602090815260408083209483529390529190912042905550600101610723565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d816040516109769190615413565b60405180910390a16109f260008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506119ed915050565b505050505050505050565b610a3d610a0c828401846154b0565b6040805160008082526020820190925290610a37565b6060815260200190600190039081610a225790505b50611d64565b604080516000808252602082019092529050610a606001858585858660006119ed565b50505050565b6000610a74600160046154e5565b6002610a8160808561550e565b67ffffffffffffffff16610a959190615535565b610a9f8585611e14565b901c166003811115610ab357610ab36143ed565b90505b92915050565b6001546001600160a01b03163314610b165760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610805565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b82611e5b565b815181518114610bbe576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d0a576000848281518110610bdd57610bdd615290565b60200260200101519050600081602001515190506000858481518110610c0557610c05615290565b6020026020010151905080518214610c49576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cfb576000828281518110610c6857610c68615290565b6020026020010151905080600014610cf25784602001518281518110610c9057610c90615290565b602002602001015160800151811015610cf25784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024810183905260448101829052606401610805565b50600101610c4c565b50505050806001019050610bc1565b50610d158383611d64565b505050565b610d226114e6565b6105f681611edc565b610d6e6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610e1757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610df9575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e7957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e5b575b5050505050815250509050919050565b610e916114e6565b60005b81811015610d15576000838383818110610eb057610eb0615290565b905060400201803603810190610ec6919061554c565b9050610ed58160200151611425565b610f3a57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e94565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff161515938601939093527501000000000000000000000000000000000000000000909204909216948301949094526001840180549394929391840191610fe290615585565b80601f016020809104026020016040519081016040528092919081815260200182805461100e90615585565b8015610e795780601f1061103057610100808354040283529160200191610e79565b820191906000526020600020905b81548152906001019060200180831161103e57505050919092525091949350505050565b33301461109b576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600080825260208201909252816110d8565b60408051808201909152600080825260208201528152602001906001900390816110b15790505b5060a0840151519091501561110b576111088360a001518460200151856060015186600001516020015186612089565b90505b6040805160a0810182528451518152845160209081015167ffffffffffffffff1681830152808601518351600094840192611147929101614208565b60408051601f19818403018152918152908252868101516020830152018390526005549091506001600160a01b03168015611254576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a1906111c1908590600401615661565b600060405180830381600087803b1580156111db57600080fd5b505af19250505080156111ec575060015b611254573d80801561121a576040519150601f19603f3d011682016040523d82523d6000602084013e61121f565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016108059190614208565b60408501515115801561126957506080850151155b80611280575060608501516001600160a01b03163b155b806112c0575060608501516112be906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612167565b155b156112cc575050505050565b845160209081015167ffffffffffffffff16600090815260069091526040808220546080880151606089015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf97983926113449289926113889291600401615674565b6000604051808303816000875af1158015611363573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261138b91908101906156b0565b5091509150816113c957806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016108059190614208565b50505050505050565b6113da6114e6565b6105f681612183565b6113eb6114e6565b60005b81518110156114215761141982828151811061140c5761140c615290565b6020026020010151612239565b6001016113ee565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156114c2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab69190615746565b6000546001600160a01b031633146115405760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610805565b565b60005b815181101561142157600082828151811061156257611562615290565b602002602001015190506000816020015190508067ffffffffffffffff166000036115b9576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b03166115fa576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260066020526040812060018101805491929161162590615585565b80601f016020809104026020016040519081016040528092919081815260200182805461165190615585565b801561169e5780601f106116735761010080835404028352916020019161169e565b820191906000526020600020905b81548152906001019060200180831161168157829003601f168201915b5050505050905060008460600151905081516000036117815780516000036116f2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001830161170082826157ab565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000017835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16117d4565b80805190602001208280519060200120146117d4576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610805565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b9061186c90869061586b565b60405180910390a25050505050806001019050611545565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561191f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119439190615746565b156105f6576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610805565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610ab6576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610805565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611a4c8760a4615939565b9050826060015115611a94578451611a65906020615535565b8651611a72906020615535565b611a7d9060a0615939565b611a879190615939565b611a919082615939565b90505b368114611ad6576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610805565b5081518114611b1e5781516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610805565b611b26611e5b565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611b7457611b746143ed565b6002811115611b8557611b856143ed565b9052509050600281602001516002811115611ba257611ba26143ed565b148015611bf65750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611bde57611bde615290565b6000918252602090912001546001600160a01b031633145b611c2c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611d0e576020820151611c4790600161594c565b60ff16855114611c83576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611cbe576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611cd0929190615965565b604051908190038120611ce7918b90602001615975565b604051602081830303815290604052805190602001209050611d0c8a8288888861257d565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d9e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611e0d57611e05858281518110611dd357611dd3615290565b602002602001015184611dff57858381518110611df257611df2615290565b6020026020010151612794565b83612794565b600101611db5565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611e39608085615989565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f000000000000000000000000000000000000000000000000000000000000000014611540576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610805565b80516001600160a01b0316611f1d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16939093177c010000000000000000000000000000000000000000000000000000000093871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060855167ffffffffffffffff8111156120a5576120a5613eb0565b6040519080825280602002602001820160405280156120ea57816020015b60408051808201909152600080825260208201528152602001906001900390816120c35790505b50905060005b865181101561215d5761213887828151811061210e5761210e615290565b602002602001015187878787868151811061212b5761212b615290565b6020026020010151612f25565b82828151811061214a5761214a615290565b60209081029190910101526001016120f0565b5095945050505050565b60006121728361333c565b8015610ab35750610ab383836133a0565b336001600160a01b038216036121db5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610805565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff16600003612264576000604051631b3fab5160e11b815260040161080591906159b0565b60208082015160ff808216600090815260029093526040832060018101549293909283921690036122d157606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612326565b6060840151600182015460ff6201000090910416151590151514612326576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff84166004820152602401610805565b60a08401518051601f60ff82161115612355576001604051631b3fab5160e11b815260040161080591906159b0565b6123bb85856003018054806020026020016040519081016040528092919081815260200182805480156123b157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612393575b505050505061346f565b8560600151156124ea5761242985856002018054806020026020016040519081016040528092919081815260200182805480156123b1576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161239357505050505061346f565b608086015180516124439060028701906020840190613e0a565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f10156124a3576002604051631b3fab5160e11b815260040161080591906159b0565b60408801516124b39060036159ca565b60ff168160ff16116124db576003604051631b3fab5160e11b815260040161080591906159b0565b6124e7878360016134d8565b50505b6124f6858360026134d8565b815161250b9060038601906020850190613e0a565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f54793612564938a939260028b019291906159e6565b60405180910390a161257585613658565b505050505050565b612585613e7c565b835160005b8181101561278a5760006001888684602081106125a9576125a9615290565b6125b691901a601b61594c565b8985815181106125c8576125c8615290565b60200260200101518986815181106125e2576125e2615290565b602002602001015160405160008152602001604052604051612620949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612642573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b038516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156126a3576126a36143ed565b60028111156126b4576126b46143ed565b90525090506001816020015160028111156126d1576126d16143ed565b14612708576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061271f5761271f615290565b60200201511561275b576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061277657612776615290565b91151560209092020152505060010161258a565b5050505050505050565b815161279f81611884565b60006127aa82611986565b60208501515190915060008190036127ed576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461282b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561284657612846613eb0565b60405190808252806020026020018201604052801561286f578160200160208202803683370190505b50905060005b828110156129e45760008760200151828151811061289557612895615290565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461292857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610805565b6129be8186600101805461293b90615585565b80601f016020809104026020016040519081016040528092919081815260200182805461296790615585565b80156129b45780601f10612989576101008083540402835291602001916129b4565b820191906000526020600020905b81548152906001019060200180831161299757829003601f168201915b5050505050613674565b8383815181106129d0576129d0615290565b602090810291909101015250600101612875565b5060006129fb858389606001518a60800151613796565b905080600003612a43576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610805565b8551151560005b848110156109f257600089602001518281518110612a6a57612a6a615290565b602002602001015190506000612a8889836000015160600151610a66565b90506000816003811115612a9e57612a9e6143ed565b1480612abb57506003816003811115612ab957612ab96143ed565b145b612b12578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612f1d565b8315612be257600454600090600160a01b900463ffffffff16612b3587426154e5565b1190508080612b5557506003826003811115612b5357612b536143ed565b145b612b97576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b166004820152602401610805565b8a8481518110612ba957612ba9615290565b6020026020010151600014612bdc578a8481518110612bca57612bca615290565b60200260200101518360800181815250505b50612c43565b6000816003811115612bf657612bf66143ed565b14612c43578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612b03565b81516080015167ffffffffffffffff1615612d31576000816003811115612c6c57612c6c6143ed565b03612d315781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612ce3928e929190600401615a98565b6020604051808303816000875af1158015612d02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d269190615746565b612d31575050612f1d565b60008b604001518481518110612d4957612d49615290565b6020026020010151905080518360a001515114612dad578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d1660048301529091166024820152604401610805565b612dc18a84600001516060015160016137ec565b600080612dce8584613894565b91509150612de58c866000015160600151846137ec565b8615612e55576003826003811115612dff57612dff6143ed565b03612e55576000846003811115612e1857612e186143ed565b14612e55578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261080591908390600401615ac5565b6002826003811115612e6957612e696143ed565b14612ec3576003826003811115612e8257612e826143ed565b14612ec3578451606001516040517f926c5a3e000000000000000000000000000000000000000000000000000000008152610805918e918590600401615ade565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612f0f9087908790615b04565b60405180910390a450505050505b600101612a4a565b60408051808201909152600080825260208201526000612f48876020015161395e565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612fcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ff19190615b24565b90506001600160a01b038116158061303957506130376001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612167565b155b1561307b576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610805565b6000806131816040518061010001604052808b81526020018967ffffffffffffffff1681526020018a6001600160a01b031681526020018c606001518152602001866001600160a01b031681526020018c6000015181526020018c604001518152602001888152506040516024016130f39190615b41565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3907753700000000000000000000000000000000000000000000000000000000179052600454859063ffffffff7c0100000000000000000000000000000000000000000000000000000000909104166113886084613a04565b5091509150816131bf57806040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016108059190614208565b80516020146132075780516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610805565b60008180602001905181019061321d9190615c0e565b6040516001600160a01b0380871660248301528b166044820152606481018290529091506132d29060840160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052600454879063ffffffff7801000000000000000000000000000000000000000000000000909104166113886084613a04565b5090935091508261331157816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016108059190614208565b604080518082019091526001600160a01b039095168552602085015250919250505095945050505050565b6000613368827f01ffc9a7000000000000000000000000000000000000000000000000000000006133a0565b8015610ab65750613399827fffffffff000000000000000000000000000000000000000000000000000000006133a0565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613458575060208210155b80156134645750600081115b979650505050505050565b60005b8151811015610d155760ff8316600090815260036020526040812083519091908490849081106134a4576134a4615290565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613472565b60005b82518160ff161015610a60576000838260ff16815181106134fe576134fe615290565b602002602001015190506000600281111561351b5761351b6143ed565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561355a5761355a6143ed565b1461357b576004604051631b3fab5160e11b815260040161080591906159b0565b6001600160a01b0381166135bb576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156135e1576135e16143ed565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561363e5761363e6143ed565b0217905550905050508061365190615c27565b90506134db565b60ff81166105f6576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936136ba937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c46565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976137039794969395929491939101615c79565b604051602081830303815290604052805190602001208560400151805190602001208660a0015160405160200161373a9190615d70565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b6000806137a4858585613b2a565b90506137af81611425565b6137bd5760009150506137e4565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026137fb60808561550e565b67ffffffffffffffff1661380f9190615535565b9050600061381d8585611e14565b90508161382c600160046154e5565b901b191681836003811115613843576138436143ed565b67ffffffffffffffff871660009081526007602052604081209190921b92909217918291613872608088615989565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906138d89087908790600401615dd0565b600060405180830381600087803b1580156138f257600080fd5b505af1925050508015613903575060015b613942573d808015613931576040519150601f19603f3d011682016040523d82523d6000602084013e613936565b606091505b50600392509050613957565b50506040805160208101909152600081526002905b9250929050565b6000815160201461399d57816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016108059190614208565b6000828060200190518101906139b39190615c0e565b90506001600160a01b038111806139cb575061040081105b15610ab657826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016108059190614208565b6000606060008361ffff1667ffffffffffffffff811115613a2757613a27613eb0565b6040519080825280601f01601f191660200182016040528015613a51576020820181803683370190505b509150863b613a84577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613ab7577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613af0577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b135750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b6b576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b7f57506101018111155b613b9c576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bc6576040516309bde33960e01b815260040160405180910390fd5b80600003613bf35786600081518110613be157613be1615290565b60200260200101519350505050613dc2565b60008167ffffffffffffffff811115613c0e57613c0e613eb0565b604051908082528060200260200182016040528015613c37578160200160208202803683370190505b50905060008080805b85811015613d615760006001821b8b811603613c9b5788851015613c84578c5160018601958e918110613c7557613c75615290565b60200260200101519050613cbd565b8551600185019487918110613c7557613c75615290565b8b5160018401938d918110613cb257613cb2615290565b602002602001015190505b600089861015613ced578d5160018701968f918110613cde57613cde615290565b60200260200101519050613d0f565b8651600186019588918110613d0457613d04615290565b602002602001015190505b82851115613d30576040516309bde33960e01b815260040160405180910390fd5b613d3a8282613dc9565b878481518110613d4c57613d4c615290565b60209081029190910101525050600101613c40565b506001850382148015613d7357508683145b8015613d7e57508581145b613d9b576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613db057613db0615290565b60200260200101519750505050505050505b9392505050565b6000818310613de157613ddc8284613de7565b610ab3565b610ab383835b604080516001602082015290810183905260608101829052600090608001613778565b828054828255906000526020600020908101928215613e6c579160200282015b82811115613e6c578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e2a565b50613e78929150613e9b565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e785760008155600101613e9c565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613ee957613ee9613eb0565b60405290565b60405160a0810167ffffffffffffffff81118282101715613ee957613ee9613eb0565b60405160c0810167ffffffffffffffff81118282101715613ee957613ee9613eb0565b6040805190810167ffffffffffffffff81118282101715613ee957613ee9613eb0565b6040516060810167ffffffffffffffff81118282101715613ee957613ee9613eb0565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fa457613fa4613eb0565b604052919050565b600067ffffffffffffffff821115613fc657613fc6613eb0565b5060051b60200190565b6001600160a01b03811681146105f657600080fd5b803567ffffffffffffffff81168114613ffd57600080fd5b919050565b80151581146105f657600080fd5b8035613ffd81614002565b600067ffffffffffffffff82111561403557614035613eb0565b50601f01601f191660200190565b600082601f83011261405457600080fd5b81356140676140628261401b565b613f7b565b81815284602083860101111561407c57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140ac57600080fd5b823567ffffffffffffffff808211156140c457600080fd5b818501915085601f8301126140d857600080fd5b81356140e661406282613fac565b81815260059190911b8301840190848101908883111561410557600080fd5b8585015b838110156141ab578035858111156141215760008081fd5b86016080818c03601f19018113156141395760008081fd5b614141613ec6565b8983013561414e81613fd0565b8152604061415d848201613fe5565b8b83015260608085013561417081614002565b8383015292840135928984111561418957600091508182fd5b6141978f8d86880101614043565b908301525085525050918601918601614109565b5098975050505050505050565b60005b838110156141d35781810151838201526020016141bb565b50506000910152565b600081518084526141f48160208601602086016141b8565b601f01601f19169290920160200192915050565b602081526000610ab360208301846141dc565b8060608101831015610ab657600080fd5b60008083601f84011261423e57600080fd5b50813567ffffffffffffffff81111561425657600080fd5b60208301915083602082850101111561395757600080fd5b60008083601f84011261428057600080fd5b50813567ffffffffffffffff81111561429857600080fd5b6020830191508360208260051b850101111561395757600080fd5b60008060008060008060008060e0898b0312156142cf57600080fd5b6142d98a8a61421b565b9750606089013567ffffffffffffffff808211156142f657600080fd5b6143028c838d0161422c565b909950975060808b013591508082111561431b57600080fd5b6143278c838d0161426e565b909750955060a08b013591508082111561434057600080fd5b5061434d8b828c0161426e565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561437b57600080fd5b614385858561421b565b9250606084013567ffffffffffffffff8111156143a157600080fd5b6143ad8682870161422c565b9497909650939450505050565b600080604083850312156143cd57600080fd5b6143d683613fe5565b91506143e460208401613fe5565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614413576144136143ed565b9052565b60208101610ab68284614403565b600060a0828403121561443757600080fd5b61443f613eef565b90508135815261445160208301613fe5565b602082015261446260408301613fe5565b604082015261447360608301613fe5565b606082015261448460808301613fe5565b608082015292915050565b8035613ffd81613fd0565b600082601f8301126144ab57600080fd5b813560206144bb61406283613fac565b82815260059290921b840181019181810190868411156144da57600080fd5b8286015b848110156145b057803567ffffffffffffffff808211156144ff5760008081fd5b8189019150608080601f19848d0301121561451a5760008081fd5b614522613ec6565b87840135838111156145345760008081fd5b6145428d8a83880101614043565b825250604080850135848111156145595760008081fd5b6145678e8b83890101614043565b8a84015250606080860135858111156145805760008081fd5b61458e8f8c838a0101614043565b92840192909252949092013593810193909352505083529183019183016144de565b509695505050505050565b600061014082840312156145ce57600080fd5b6145d6613f12565b90506145e28383614425565b815260a082013567ffffffffffffffff808211156145ff57600080fd5b61460b85838601614043565b602084015260c084013591508082111561462457600080fd5b61463085838601614043565b604084015261464160e0850161448f565b6060840152610100840135608084015261012084013591508082111561466657600080fd5b506146738482850161449a565b60a08301525092915050565b600082601f83011261469057600080fd5b813560206146a061406283613fac565b82815260059290921b840181019181810190868411156146bf57600080fd5b8286015b848110156145b057803567ffffffffffffffff8111156146e35760008081fd5b6146f18986838b01016145bb565b8452509183019183016146c3565b600082601f83011261471057600080fd5b8135602061472061406283613fac565b82815260059290921b8401810191818101908684111561473f57600080fd5b8286015b848110156145b057803567ffffffffffffffff8111156147635760008081fd5b6147718986838b0101614043565b845250918301918301614743565b600082601f83011261479057600080fd5b813560206147a061406283613fac565b82815260059290921b840181019181810190868411156147bf57600080fd5b8286015b848110156145b057803567ffffffffffffffff8111156147e35760008081fd5b6147f18986838b01016146ff565b8452509183019183016147c3565b600082601f83011261481057600080fd5b8135602061482061406283613fac565b8083825260208201915060208460051b87010193508684111561484257600080fd5b602086015b848110156145b05780358352918301918301614847565b600082601f83011261486f57600080fd5b8135602061487f61406283613fac565b82815260059290921b8401810191818101908684111561489e57600080fd5b8286015b848110156145b057803567ffffffffffffffff808211156148c35760008081fd5b818901915060a080601f19848d030112156148de5760008081fd5b6148e6613eef565b6148f1888501613fe5565b8152604080850135848111156149075760008081fd5b6149158e8b8389010161467f565b8a840152506060808601358581111561492e5760008081fd5b61493c8f8c838a010161477f565b83850152506080915081860135858111156149575760008081fd5b6149658f8c838a01016147ff565b91840191909152509190930135908301525083529183019183016148a2565b600080604080848603121561499857600080fd5b833567ffffffffffffffff808211156149b057600080fd5b6149bc8783880161485e565b94506020915081860135818111156149d357600080fd5b8601601f810188136149e457600080fd5b80356149f261406282613fac565b81815260059190911b8201840190848101908a831115614a1157600080fd5b8584015b83811015614a9d57803586811115614a2d5760008081fd5b8501603f81018d13614a3f5760008081fd5b87810135614a4f61406282613fac565b81815260059190911b82018a0190898101908f831115614a6f5760008081fd5b928b01925b82841015614a8d5783358252928a0192908a0190614a74565b8652505050918601918601614a15565b50809750505050505050509250929050565b600060208284031215614ac157600080fd5b813567ffffffffffffffff811115614ad857600080fd5b820160a08185031215613dc257600080fd5b803563ffffffff81168114613ffd57600080fd5b600060a08284031215614b1057600080fd5b614b18613eef565b8235614b2381613fd0565b8152614b3160208401614aea565b6020820152614b4260408401614aea565b6040820152614b5360608401614aea565b60608201526080830135614b6681613fd0565b60808201529392505050565b803560ff81168114613ffd57600080fd5b600060208284031215614b9557600080fd5b610ab382614b72565b60008151808452602080850194506020840160005b83811015614bd85781516001600160a01b031687529582019590820190600101614bb3565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c3260e0840182614b9e565b90506040840151601f198483030160c0850152614c4f8282614b9e565b95945050505050565b60008060408385031215614c6b57600080fd5b614c7483613fe5565b946020939093013593505050565b60008060208385031215614c9557600080fd5b823567ffffffffffffffff80821115614cad57600080fd5b818501915085601f830112614cc157600080fd5b813581811115614cd057600080fd5b8660208260061b8501011115614ce557600080fd5b60209290920196919550909350505050565b600060208284031215614d0957600080fd5b610ab382613fe5565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526137e460a08401826141dc565b60008060408385031215614d7357600080fd5b823567ffffffffffffffff80821115614d8b57600080fd5b614d97868387016145bb565b93506020850135915080821115614dad57600080fd5b50614dba858286016146ff565b9150509250929050565b600060208284031215614dd657600080fd5b8135613dc281613fd0565b600082601f830112614df257600080fd5b81356020614e0261406283613fac565b8083825260208201915060208460051b870101935086841115614e2457600080fd5b602086015b848110156145b0578035614e3c81613fd0565b8352918301918301614e29565b60006020808385031215614e5c57600080fd5b823567ffffffffffffffff80821115614e7457600080fd5b818501915085601f830112614e8857600080fd5b8135614e9661406282613fac565b81815260059190911b83018401908481019088831115614eb557600080fd5b8585015b838110156141ab57803585811115614ed057600080fd5b860160c0818c03601f19011215614ee75760008081fd5b614eef613f12565b8882013581526040614f02818401614b72565b8a8301526060614f13818501614b72565b8284015260809150614f26828501614010565b9083015260a08381013589811115614f3e5760008081fd5b614f4c8f8d83880101614de1565b838501525060c0840135915088821115614f665760008081fd5b614f748e8c84870101614de1565b9083015250845250918601918601614eb9565b600060208284031215614f9957600080fd5b5035919050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114613ffd57600080fd5b600082601f830112614fdd57600080fd5b81356020614fed61406283613fac565b82815260069290921b8401810191818101908684111561500c57600080fd5b8286015b848110156145b057604081890312156150295760008081fd5b615031613f35565b61503a82613fe5565b8152615047858301614fa0565b81860152835291830191604001615010565b600082601f83011261506a57600080fd5b8135602061507a61406283613fac565b82815260079290921b8401810191818101908684111561509957600080fd5b8286015b848110156145b05780880360808112156150b75760008081fd5b6150bf613f58565b6150c883613fe5565b8152604080601f19840112156150de5760008081fd5b6150e6613f35565b92506150f3878501613fe5565b8352615100818501613fe5565b838801528187019290925260608301359181019190915283529183019160800161509d565b6000602080838503121561513857600080fd5b823567ffffffffffffffff8082111561515057600080fd5b8185019150604080838803121561516657600080fd5b61516e613f35565b83358381111561517d57600080fd5b84016040818a03121561518f57600080fd5b615197613f35565b8135858111156151a657600080fd5b8201601f81018b136151b757600080fd5b80356151c561406282613fac565b81815260069190911b8201890190898101908d8311156151e457600080fd5b928a01925b828410156152345787848f0312156152015760008081fd5b615209613f35565b843561521481613fd0565b8152615221858d01614fa0565b818d0152825292870192908a01906151e9565b84525050508187013593508484111561524c57600080fd5b6152588a858401614fcc565b818801528252508385013591508282111561527257600080fd5b61527e88838601615059565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561531257835180516001600160a01b031684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168584015292840192918501916001016152c6565b50508583015187820388850152805180835290840192506000918401905b80831015615381578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685830152928401926001929092019190850190615330565b50979650505050505050565b602081526000610ab360208301846152a6565b67ffffffffffffffff8316815260608101613dc26020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561540c5761540c6153d5565b5092915050565b60006020808352606084516040808487015261543260608701836152a6565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141ab57845167ffffffffffffffff81511683528781015161549289850182805167ffffffffffffffff908116835260209182015116910152565b50840151828701529386019360019290920191608090910190615453565b6000602082840312156154c257600080fd5b813567ffffffffffffffff8111156154d957600080fd5b6137e48482850161485e565b81810381811115610ab657610ab66153d5565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff80841680615529576155296154f8565b92169190910692915050565b8082028115828204841417610ab657610ab66153d5565b60006040828403121561555e57600080fd5b615566613f35565b61556f83613fe5565b8152602083013560208201528091505092915050565b600181811c9082168061559957607f821691505b6020821081036155b957634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a060408701526155f360a08701826141dc565b90506060850151868203606088015261560c82826141dc565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561538157835180516001600160a01b031683528601518683015292850192600192909201919084019061562f565b602081526000610ab360208301846155bf565b60808152600061568760808301876155bf565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b6000806000606084860312156156c557600080fd5b83516156d081614002565b602085015190935067ffffffffffffffff8111156156ed57600080fd5b8401601f810186136156fe57600080fd5b805161570c6140628261401b565b81815287602083850101111561572157600080fd5b6157328260208301602086016141b8565b809450505050604084015190509250925092565b60006020828403121561575857600080fd5b8151613dc281614002565b601f821115610d15576000816000526020600020601f850160051c8101602086101561578c5750805b601f850160051c820191505b8181101561257557828155600101615798565b815167ffffffffffffffff8111156157c5576157c5613eb0565b6157d9816157d38454615585565b84615763565b602080601f83116001811461580e57600084156157f65750858301515b600019600386901b1c1916600185901b178555612575565b600085815260208120601f198616915b8281101561583d5788860151825594840194600190910190840161581e565b508582101561585b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546158bd81615585565b8060a089015260c060018316600081146158de57600181146158fa5761592a565b60ff19841660c08b015260c083151560051b8b0101945061592a565b85600052602060002060005b848110156159215781548c8201850152908801908901615906565b8b0160c0019550505b50929998505050505050505050565b80820180821115610ab657610ab66153d5565b60ff8181168382160190811115610ab657610ab66153d5565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff808416806159a4576159a46154f8565b92169190910492915050565b60208101600583106159c4576159c46143ed565b91905290565b60ff818116838216029081169081811461540c5761540c6153d5565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a3e5784546001600160a01b031683526001948501949284019201615a19565b50508481036060860152865180825290820192508187019060005b81811015615a7e5782516001600160a01b031685529383019391830191600101615a59565b50505060ff851660808501525090505b9695505050505050565b600067ffffffffffffffff808616835280851660208401525060606040830152614c4f60608301846141dc565b8281526040602082015260006137e460408301846141dc565b67ffffffffffffffff848116825283166020820152606081016137e46040830184614403565b615b0e8184614403565b6040602082015260006137e460408301846141dc565b600060208284031215615b3657600080fd5b8151613dc281613fd0565b6020815260008251610100806020850152615b606101208501836141dc565b91506020850151615b7d604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615bb760a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bd484836141dc565b935060c08701519150808685030160e0870152615bf184836141dc565b935060e0870151915080868503018387015250615a8e83826141dc565b600060208284031215615c2057600080fd5b5051919050565b600060ff821660ff8103615c3d57615c3d6153d5565b60010192915050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152615a8e60808301846141dc565b86815260c060208201526000615c9260c08301886141dc565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d6357601f19868403018952815160808151818652615d0f828701826141dc565b9150508582015185820387870152615d2782826141dc565b91505060408083015186830382880152615d4183826141dc565b6060948501519790940196909652505098840198925090830190600101615ce9565b5090979650505050505050565b602081526000610ab36020830184615ccc565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d6357601f19868403018952615dbe8383516141dc565b98840198925090830190600101615da2565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e386101808501836141dc565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e7584836141dc565b935060608801519150615e946101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615ebb8282615ccc565b9150508281036020840152614c4f8185615d8356fea164736f6c6343000818000a", } var EVM2EVMMultiOffRampABI = EVM2EVMMultiOffRampMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go index 8e2cab8d8f..010953fdf0 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go @@ -105,7 +105,7 @@ type RateLimiterTokenBucket struct { var EVM2EVMOffRampMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101a06040523480156200001257600080fd5b5060405162005e0a38038062005e0a8339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615741620006c9600039600081816102ec01528181611a5201526130470152600081816102bd01528181611a2a0152611cdc01526000818161028e01528181610e7f01528181610ee401528181611a000152818161222d015261229701526000611e7b01526000818161025f01526119d60152600081816101ff015261197a01526000818161022f015281816119ae01528181611c9901528181612ca901526131580152600081816101d0015281816119550152611f5b015260008181611bf30152611c3f01526157416000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806381ff7048116100d8578063afcb95d71161008c578063f077b59211610066578063f077b592146105f3578063f2fde38b14610609578063f52121a51461061c57600080fd5b8063afcb95d7146105ad578063b1dc65a4146105cd578063c92b2832146105e057600080fd5b8063856c8247116100bd578063856c82471461055d578063873504d7146105895780638da5cb5b1461059c57600080fd5b806381ff70481461051f57806385572ffb1461054f57600080fd5b8063599f64311161013a578063740f415011610114578063740f4150146104615780637437ff9f1461047457806379ba50971461051757600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516103299190613e82565b60405180910390f35b610345610340366004613f18565b61062f565b6040516103299190613f78565b61038e6040518060400160405280601881526020017f45564d3245564d4f666652616d7020312e352e302d646576000000000000000081525081565b6040516103299190613fd6565b6103ae6103a93660046141ff565b6106aa565b005b6103b8610a9e565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610b53565b6040516103299190614311565b6103ae61045c366004614324565b610bb5565b6103ae61046f366004614784565b610c7e565b61050a6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a01000000000000000000009091046001600160a01b039081166060830152600b5416608082015290565b604051610329919061483f565b6103ae610d70565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae610182366004614895565b61057061056b366004614324565b610e53565b60405167ffffffffffffffff9091168152602001610329565b6103ae610597366004614961565b610f56565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae6105db366004614a0a565b611124565b6103ae6105ee366004614b0f565b61132f565b6105fb61139a565b604051610329929190614b7d565b6103ae610617366004614324565b6114c0565b6103ae61062a366004614ba2565b6114d1565b600061063d60016004614c2b565b600261064a608085614c6d565b67ffffffffffffffff1661065e9190614c94565b6010600061066d608087614cab565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106a4576106a4613f35565b92915050565b84518460ff16601f8211156106f75760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614cd2565b60405180910390fd5b806000036107345760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614cd2565b61073c611771565b610745856117e7565b60095460005b818110156107bc57600860006009838154811061076a5761076a614cec565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161074b565b5050865160005b8181101561095f5760008982815181106107df576107df614cec565b60200260200101519050600060028111156107fc576107fc613f35565b6001600160a01b038216600090815260086020526040902054610100900460ff16600281111561082e5761082e613f35565b146108685760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614cd2565b6001600160a01b0381166108a8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561094b5761094b613f35565b0217905550905050508060010190506107c3565b5087516109739060099060208b0190613df0565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a1617179055600780546109f99146913091906000906109cb9063ffffffff16614d1b565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611ab1565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610a8a9487949293918316921691909117908f908f908f908f908f908f90614d3e565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610b4e90611b3e565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bab57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8d575b5050505050905090565b6000546001600160a01b03163314801590610bdb57506002546001600160a01b03163314155b15610c12576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b610c86611bf0565b81515181518114610cc3576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d60576000838281518110610ce257610ce2614cec565b6020026020010151905080600014610d57578451805183908110610d0857610d08614cec565b602002602001015160800151811015610d57576040517f085e39cf00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016106ee565b50600101610cc6565b50610d6b8383611c71565b505050565b6001546001600160a01b03163314610de4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106ee565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106a4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106a4576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4f9190614dd4565b9392505050565b610f5e611771565b60005b825181101561103157610f9b838281518110610f7f57610f7f614cec565b602002602001015160200151600c61269d90919063ffffffff16565b15611029577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d58782838281518110610fd357610fd3614cec565b602002602001015160000151848381518110610ff157610ff1614cec565b6020026020010151602001516040516110209291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610f61565b5060005b8151811015610d6b5761108e82828151811061105357611053614cec565b60200260200101516020015183838151811061107157611071614cec565b602002602001015160000151600c6126b29092919063ffffffff16565b1561111c577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a8282815181106110c6576110c6614cec565b6020026020010151600001518383815181106110e4576110e4614cec565b6020026020010151602001516040516111139291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101611035565b61112e87876126d0565b600554883590808214611177576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016106ee565b61117f611bf0565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561120757611207613f35565b600281111561121857611218613f35565b905250905060028160200151600281111561123557611235613f35565b14801561126f57506009816000015160ff168154811061125757611257614cec565b6000918252602090912001546001600160a01b031633145b6112a5576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006112b3856020614c94565b6112be886020614c94565b6112ca8b610144614df1565b6112d49190614df1565b6112de9190614df1565b9050368114611322576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016106ee565b5050505050505050505050565b6000546001600160a01b0316331480159061135557506002546001600160a01b03163314155b1561138c576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113976003826126f7565b50565b60608060006113a9600c6128dc565b90508067ffffffffffffffff8111156113c4576113c4613fe9565b6040519080825280602002602001820160405280156113ed578160200160208202803683370190505b5092508067ffffffffffffffff81111561140957611409613fe9565b604051908082528060200260200182016040528015611432578160200160208202803683370190505b50915060005b818110156114ba5760008061144e600c846128e7565b915091508086848151811061146557611465614cec565b60200260200101906001600160a01b031690816001600160a01b0316815250508185848151811061149857611498614cec565b6001600160a01b03909216602092830291909101909101525050600101611438565b50509091565b6114c8611771565b61139781612905565b33301461150a576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611547565b60408051808201909152600080825260208201528152602001906001900390816115205790505b5061014084015151909150156115a7576115a4836101400151846020015160405160200161158491906001600160a01b0391909116815260200190565b6040516020818303038152906040528560400151866101600151866129e0565b90505b610120830151511580156115bd57506080830151155b806115d4575060408301516001600160a01b03163b155b8061161457506040830151611612906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612b11565b155b1561161e57505050565b600080600a600001600a9054906101000a90046001600160a01b03166001600160a01b0316633cf979836040518060a001604052808861018001518152602001886000015167ffffffffffffffff168152602001886020015160405160200161169691906001600160a01b0391909116815260200190565b6040516020818303038152906040528152602001886101200151815260200186815250611388886080015189604001516040518563ffffffff1660e01b81526004016116e59493929190614e49565b6000604051808303816000875af1158015611704573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261172c9190810190614f53565b50915091508161176a57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016106ee9190613fd6565b5050505050565b6000546001600160a01b031633146117e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106ee565b565b6000818060200190518101906117fd9190614fc1565b60608101519091506001600160a01b0316611844576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a01000000000000000000006001600160a01b039485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611aa591849061505c565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611ad59998979695949392919061511e565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611bcc82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611bb09190614c2b565b85608001516fffffffffffffffffffffffffffffffff16612b2d565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b467f0000000000000000000000000000000000000000000000000000000000000000146117e5576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016106ee565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d4f91906151a6565b15611d86576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151516000819003611dc3576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114611e01576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff811115611e1c57611e1c613fe9565b604051908082528060200260200182016040528015611e45578160200160208202803683370190505b50905060005b82811015611f1d57600085600001518281518110611e6b57611e6b614cec565b60200260200101519050611e9f817f0000000000000000000000000000000000000000000000000000000000000000612b4c565b838381518110611eb157611eb1614cec565b602002602001018181525050806101800151838381518110611ed557611ed5614cec565b602002602001015114611f14576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101611e4b565b50604080850151606086015191517f320488750000000000000000000000000000000000000000000000000000000081526000926001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692633204887592611f91928792916004016151f4565b602060405180830381865afa158015611fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd2919061522a565b90508060000361200e576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b848110156126945760008760000151828151811061203557612035614cec565b60200260200101519050600061204e826060015161062f565b9050600081600381111561206457612064613f35565b14806120815750600381600381111561207f5761207f613f35565b145b6120c757816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a2505061268c565b831561218457600a5460009063ffffffff166120e38742614c2b565b11905080806121035750600382600381111561210157612101613f35565b145b612139576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88848151811061214b5761214b614cec565b602002602001015160001461217e5788848151811061216c5761216c614cec565b60200260200101518360800181815250505b506121e7565b600081600381111561219857612198613f35565b146121e757606082015160405167ffffffffffffffff90911681527f67d9ba0f63d427c482c2736300e6d5a34c6691dbcdea8ad35828a1f1ba47e8729060200160405180910390a1505061268c565b60c082015167ffffffffffffffff1615612466576020808301516001600160a01b03166000908152600f909152604081205467ffffffffffffffff16908190036123d1577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156123d15760208301516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa1580156122e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123049190614dd4565b60c084015190915067ffffffffffffffff16612321826001615243565b67ffffffffffffffff16146123815782602001516001600160a01b03168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a350505061268c565b6020838101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b60008260038111156123e5576123e5613f35565b036124645760c083015167ffffffffffffffff16612404826001615243565b67ffffffffffffffff16146124645782602001516001600160a01b03168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a350505061268c565b505b60008960200151848151811061247e5761247e614cec565b602002602001015190506124aa8360600151846000015185610140015151866101200151518551612ca7565b6124b983606001516001612e21565b6000806124c68584612ecb565b915091506124d8856060015183612e21565b86156125445760038260038111156124f2576124f2613f35565b0361254457600084600381111561250b5761250b613f35565b1461254457806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016106ee9190613fd6565b600282600381111561255857612558613f35565b146125b057600382600381111561257157612571613f35565b146125b0578460600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016106ee929190615264565b60c085015167ffffffffffffffff16156126385760008460038111156125d8576125d8613f35565b03612638576020808601516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff169161261083615282565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b846101800151856060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef65848460405161267e92919061529f565b60405180910390a350505050505b600101612015565b50505050505050565b6000610f4f836001600160a01b038416612f94565b60006126c8846001600160a01b03851684612fa0565b949350505050565b6126f36126df828401846152bf565b604080516000815260208101909152611c71565b5050565b815460009061272090700100000000000000000000000000000000900463ffffffff1642614c2b565b905080156127c25760018301548354612768916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b2d565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546127e8916fffffffffffffffffffffffffffffffff9081169116612fb6565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906128cf9084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106a482612fcc565b60008080806128f68686612fd7565b909450925050505b9250929050565b336001600160a01b03821603612977576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106ee565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b846000805b8751811015612af657612a5d888281518110612a0357612a03614cec565b6020026020010151602001518888888581518110612a2357612a23614cec565b6020026020010151806020019051810190612a3e91906152f4565b888681518110612a5057612a50614cec565b6020026020010151612fe6565b838281518110612a6f57612a6f614cec565b6020026020010181905250612aab838281518110612a8f57612a8f614cec565b602002602001015160000151600c6133e690919063ffffffff16565b15612aee57612ae1838281518110612ac557612ac5614cec565b6020908102919091010151600b546001600160a01b03166133fb565b612aeb9083614df1565b91505b6001016129e5565b508015612b0657612b068161351c565b505b95945050505050565b6000612b1c83613529565b8015610f4f5750610f4f838361358d565b6000612b0885612b3d8486614c94565b612b479087614df1565b612fb6565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612be29897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612c1b91906153ba565b60405160208183030381529060405280519060200120876101600151604051602001612c479190615427565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff1614612d20576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016106ee565b600a5468010000000000000000900461ffff16831115612d78576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b808314612dbd576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b600a54640100000000900463ffffffff1682111561176a57600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff166004820152602481018390526044016106ee565b60006002612e30608085614c6d565b67ffffffffffffffff16612e449190614c94565b90506000601081612e56608087614cab565b67ffffffffffffffff168152602081019190915260400160002054905081612e8060016004614c2b565b901b191681836003811115612e9757612e97613f35565b901b178060106000612eaa608088614cab565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a590612f0f908790879060040161543a565b600060405180830381600087803b158015612f2957600080fd5b505af1925050508015612f3a575060015b612f79573d808015612f68576040519150601f19603f3d011682016040523d82523d6000602084013e612f6d565b606091505b506003925090506128fe565b50506040805160208101909152600081526002909250929050565b6000610f4f838361365c565b60006126c884846001600160a01b038516613679565b6000818310612fc55781610f4f565b5090919050565b60006106a482613696565b60008080806128f686866136a1565b6040805180820190915260008082526020820152600061300984602001516136cc565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa15801561308e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130b2919061559d565b90506001600160a01b03811615806130fa57506130f86001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612b11565b155b1561313c576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016106ee565b60008060006132416040518061010001604052808c81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018b6001600160a01b031681526020018d8152602001876001600160a01b031681526020018a6000015181526020018a604001518152602001898152506040516024016131d291906155ba565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905260608a0151869063ffffffff166113886084613772565b9250925092508261328057816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190613fd6565b81516020146132c85781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b6000828060200190518101906132de919061522a565b6040516001600160a01b038c1660248201526044810182905290915061337b9060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905260608b0151889061337190869063ffffffff16614c2b565b6113886084613772565b509094509250836133ba57826040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190613fd6565b604080518082019091526001600160a01b03909616865260208601525092935050505095945050505050565b6000610f4f836001600160a01b038416613898565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613461573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134859190615691565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036134ee5783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016106ee565b60208401516126c8907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316906138a4565b61139760038260006138e1565b6000613555827f01ffc9a70000000000000000000000000000000000000000000000000000000061358d565b80156106a45750613586827fffffffff0000000000000000000000000000000000000000000000000000000061358d565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613645575060208210155b80156136515750600081115b979650505050505050565b60008181526002830160205260408120819055610f4f8383613c30565b600082815260028401602052604081208290556126c88484613c3c565b60006106a482613c48565b600080806136af8585613c52565b600081815260029690960160205260409095205494959350505050565b6000815160201461370b57816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190613fd6565b600082806020019051810190613721919061522a565b90506001600160a01b03811180613739575061040081105b156106a457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190613fd6565b6000606060008361ffff1667ffffffffffffffff81111561379557613795613fe9565b6040519080825280601f01601f1916602001820160405280156137bf576020820181803683370190505b509150863b6137f2577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613825577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b859003604081048103871061385e577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156138815750835b808352806000602085013e50955095509592505050565b6000610f4f8383613c5e565b6000670de0b6b3a76400006138d7837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616614c94565b610f4f91906156f1565b825474010000000000000000000000000000000000000000900460ff161580613908575081155b1561391257505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061395890700100000000000000000000000000000000900463ffffffff1642614c2b565b90508015613a18578183111561399a576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546139d49083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b2d565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613ab5576001600160a01b038416613a6a576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106ee565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b03851660448201526064016106ee565b84831015613bae5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613af99082614c2b565b613b03878a614c2b565b613b0d9190614df1565b613b1791906156f1565b90506001600160a01b038616613b63576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106ee565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b03871660448201526064016106ee565b613bb88584614c2b565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f4f8383613c7d565b6000610f4f8383613d77565b60006106a4825490565b6000610f4f8383613dc6565b6000610f4f838360008181526001830160205260408120541515610f4f565b60008181526001830160205260408120548015613d66576000613ca1600183614c2b565b8554909150600090613cb590600190614c2b565b9050818114613d1a576000866000018281548110613cd557613cd5614cec565b9060005260206000200154905080876000018481548110613cf857613cf8614cec565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613d2b57613d2b615705565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106a4565b60009150506106a4565b5092915050565b6000818152600183016020526040812054613dbe575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106a4565b5060006106a4565b6000826000018281548110613ddd57613ddd614cec565b9060005260206000200154905092915050565b828054828255906000526020600020908101928215613e5d579160200282015b82811115613e5d57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190613e10565b50613e69929150613e6d565b5090565b5b80821115613e695760008155600101613e6e565b60e081016106a482846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff8116811461139757600080fd5b8035613f1381613ef2565b919050565b600060208284031215613f2a57600080fd5b8135610f4f81613ef2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110613f7457613f74613f35565b9052565b602081016106a48284613f64565b60005b83811015613fa1578181015183820152602001613f89565b50506000910152565b60008151808452613fc2816020860160208601613f86565b601f01601f19169290920160200192915050565b602081526000610f4f6020830184613faa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561403b5761403b613fe9565b60405290565b6040516101a0810167ffffffffffffffff8111828210171561403b5761403b613fe9565b6040516080810167ffffffffffffffff8111828210171561403b5761403b613fe9565b604051601f8201601f1916810167ffffffffffffffff811182821017156140b1576140b1613fe9565b604052919050565b600067ffffffffffffffff8211156140d3576140d3613fe9565b5060051b60200190565b6001600160a01b038116811461139757600080fd5b8035613f13816140dd565b600082601f83011261410e57600080fd5b8135602061412361411e836140b9565b614088565b8083825260208201915060208460051b87010193508684111561414557600080fd5b602086015b8481101561416a57803561415d816140dd565b835291830191830161414a565b509695505050505050565b803560ff81168114613f1357600080fd5b600067ffffffffffffffff8211156141a0576141a0613fe9565b50601f01601f191660200190565b600082601f8301126141bf57600080fd5b81356141cd61411e82614186565b8181528460208386010111156141e257600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561421857600080fd5b863567ffffffffffffffff8082111561423057600080fd5b61423c8a838b016140fd565b9750602089013591508082111561425257600080fd5b61425e8a838b016140fd565b965061426c60408a01614175565b9550606089013591508082111561428257600080fd5b61428e8a838b016141ae565b945061429c60808a01613f08565b935060a08901359150808211156142b257600080fd5b506142bf89828a016141ae565b9150509295509295509295565b60008151808452602080850194506020840160005b838110156143065781516001600160a01b0316875295820195908201906001016142e1565b509495945050505050565b602081526000610f4f60208301846142cc565b60006020828403121561433657600080fd5b8135610f4f816140dd565b801515811461139757600080fd5b8035613f1381614341565b600082601f83011261436b57600080fd5b8135602061437b61411e836140b9565b82815260069290921b8401810191818101908684111561439a57600080fd5b8286015b8481101561416a57604081890312156143b75760008081fd5b6143bf614018565b81356143ca816140dd565b8152818501358582015283529183019160400161439e565b600082601f8301126143f357600080fd5b8135602061440361411e836140b9565b82815260059290921b8401810191818101908684111561442257600080fd5b8286015b8481101561416a57803567ffffffffffffffff8111156144465760008081fd5b6144548986838b01016141ae565b845250918301918301614426565b60006101a0828403121561447557600080fd5b61447d614041565b905061448882613f08565b8152614496602083016140f2565b60208201526144a7604083016140f2565b60408201526144b860608301613f08565b6060820152608082013560808201526144d360a0830161434f565b60a08201526144e460c08301613f08565b60c08201526144f560e083016140f2565b60e082015261010082810135908201526101208083013567ffffffffffffffff8082111561452257600080fd5b61452e868387016141ae565b8385015261014092508285013591508082111561454a57600080fd5b6145568683870161435a565b8385015261016092508285013591508082111561457257600080fd5b5061457f858286016143e2565b82840152505061018080830135818301525092915050565b600082601f8301126145a857600080fd5b813560206145b861411e836140b9565b82815260059290921b840181019181810190868411156145d757600080fd5b8286015b8481101561416a57803567ffffffffffffffff8111156145fb5760008081fd5b6146098986838b01016143e2565b8452509183019183016145db565b600082601f83011261462857600080fd5b8135602061463861411e836140b9565b8083825260208201915060208460051b87010193508684111561465a57600080fd5b602086015b8481101561416a578035835291830191830161465f565b60006080828403121561468857600080fd5b614690614065565b9050813567ffffffffffffffff808211156146aa57600080fd5b818401915084601f8301126146be57600080fd5b813560206146ce61411e836140b9565b82815260059290921b840181019181810190888411156146ed57600080fd5b8286015b84811015614725578035868111156147095760008081fd5b6147178b86838b0101614462565b8452509183019183016146f1565b508652508581013593508284111561473c57600080fd5b61474887858801614597565b9085015250604084013591508082111561476157600080fd5b5061476e84828501614617565b6040830152506060820135606082015292915050565b6000806040838503121561479757600080fd5b823567ffffffffffffffff808211156147af57600080fd5b6147bb86838701614676565b93506020915081850135818111156147d257600080fd5b85019050601f810186136147e557600080fd5b80356147f361411e826140b9565b81815260059190911b8201830190838101908883111561481257600080fd5b928401925b8284101561483057833582529284019290840190614817565b80955050505050509250929050565b60a081016106a4828463ffffffff8082511683528060208301511660208401525061ffff604082015116604083015260608101516001600160a01b03808216606085015280608084015116608085015250505050565b6000602082840312156148a757600080fd5b813567ffffffffffffffff8111156148be57600080fd5b820160a08185031215610f4f57600080fd5b600082601f8301126148e157600080fd5b813560206148f161411e836140b9565b82815260069290921b8401810191818101908684111561491057600080fd5b8286015b8481101561416a576040818903121561492d5760008081fd5b614935614018565b8135614940816140dd565b81528185013561494f816140dd565b81860152835291830191604001614914565b6000806040838503121561497457600080fd5b823567ffffffffffffffff8082111561498c57600080fd5b614998868387016148d0565b935060208501359150808211156149ae57600080fd5b506149bb858286016148d0565b9150509250929050565b60008083601f8401126149d757600080fd5b50813567ffffffffffffffff8111156149ef57600080fd5b6020830191508360208260051b85010111156128fe57600080fd5b60008060008060008060008060e0898b031215614a2657600080fd5b606089018a811115614a3757600080fd5b8998503567ffffffffffffffff80821115614a5157600080fd5b818b0191508b601f830112614a6557600080fd5b813581811115614a7457600080fd5b8c6020828501011115614a8657600080fd5b6020830199508098505060808b0135915080821115614aa457600080fd5b614ab08c838d016149c5565b909750955060a08b0135915080821115614ac957600080fd5b50614ad68b828c016149c5565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff81168114613f1357600080fd5b600060608284031215614b2157600080fd5b6040516060810181811067ffffffffffffffff82111715614b4457614b44613fe9565b6040528235614b5281614341565b8152614b6060208401614aef565b6020820152614b7160408401614aef565b60408201529392505050565b604081526000614b9060408301856142cc565b8281036020840152612b0881856142cc565b60008060408385031215614bb557600080fd5b823567ffffffffffffffff80821115614bcd57600080fd5b614bd986838701614462565b93506020850135915080821115614bef57600080fd5b506149bb858286016143e2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106a4576106a4614bfc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680614c8857614c88614c3e565b92169190910692915050565b80820281158282048414176106a4576106a4614bfc565b600067ffffffffffffffff80841680614cc657614cc6614c3e565b92169190910492915050565b6020810160038310614ce657614ce6613f35565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103614d3457614d34614bfc565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614d6e8184018a6142cc565b90508281036080840152614d8281896142cc565b905060ff871660a084015282810360c0840152614d9f8187613faa565b905067ffffffffffffffff851660e0840152828103610100840152614dc48185613faa565b9c9b505050505050505050505050565b600060208284031215614de657600080fd5b8151610f4f81613ef2565b808201808211156106a4576106a4614bfc565b60008151808452602080850194506020840160005b8381101561430657815180516001600160a01b031688528301518388015260409096019590820190600101614e19565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152614e84610120840182613faa565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e0860152614ec08383613faa565b925060808901519150808584030161010086015250614edf8282614e04565b92505050614ef3602083018661ffff169052565b836040830152612b0860608301846001600160a01b03169052565b600082601f830112614f1f57600080fd5b8151614f2d61411e82614186565b818152846020838601011115614f4257600080fd5b6126c8826020830160208701613f86565b600080600060608486031215614f6857600080fd5b8351614f7381614341565b602085015190935067ffffffffffffffff811115614f9057600080fd5b614f9c86828701614f0e565b925050604084015190509250925092565b805163ffffffff81168114613f1357600080fd5b600060a08284031215614fd357600080fd5b60405160a0810181811067ffffffffffffffff82111715614ff657614ff6613fe9565b60405261500283614fad565b815261501060208401614fad565b6020820152604083015161ffff8116811461502a57600080fd5b6040820152606083015161503d816140dd565b60608201526080830151615050816140dd565b60808201529392505050565b61018081016150cd82856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff1661012083015260608301516001600160a01b03908116610140840152608084015116610160830152610f4f565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526151588285018b6142cc565b9150838203608085015261516c828a6142cc565b915060ff881660a085015283820360c08501526151898288613faa565b90861660e08501528381036101008501529050614dc48185613faa565b6000602082840312156151b857600080fd5b8151610f4f81614341565b60008151808452602080850194506020840160005b83811015614306578151875295820195908201906001016151d8565b60608152600061520760608301866151c3565b828103602084015261521981866151c3565b915050826040830152949350505050565b60006020828403121561523c57600080fd5b5051919050565b67ffffffffffffffff818116838216019080821115613d7057613d70614bfc565b67ffffffffffffffff8316815260408101610f4f6020830184613f64565b600067ffffffffffffffff808316818103614d3457614d34614bfc565b6152a98184613f64565b6040602082015260006126c86040830184613faa565b6000602082840312156152d157600080fd5b813567ffffffffffffffff8111156152e857600080fd5b6126c884828501614676565b60006020828403121561530657600080fd5b815167ffffffffffffffff8082111561531e57600080fd5b908301906080828603121561533257600080fd5b61533a614065565b82518281111561534957600080fd5b61535587828601614f0e565b82525060208301518281111561536a57600080fd5b61537687828601614f0e565b60208301525060408301518281111561538e57600080fd5b61539a87828601614f0e565b6040830152506153ac60608401614fad565b606082015295945050505050565b602081526000610f4f6020830184614e04565b60008282518085526020808601955060208260051b8401016020860160005b8481101561541a57601f19868403018952615408838351613faa565b988401989250908301906001016153ec565b5090979650505050505050565b602081526000610f4f60208301846153cd565b6040815261545560408201845167ffffffffffffffff169052565b6000602084015161547160608401826001600160a01b03169052565b5060408401516001600160a01b038116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c08401516101006154d28185018367ffffffffffffffff169052565b60e086015191506101206154f0818601846001600160a01b03169052565b81870151925061014091508282860152808701519250506101a061016081818701526155206101e0870185613faa565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc061018081888703018189015261555f8686614e04565b9550828a0151945081888703018489015261557a86866153cd565b9550808a01516101c089015250505050508281036020840152612b0881856153cd565b6000602082840312156155af57600080fd5b8151610f4f816140dd565b60208152600082516101008060208501526155d9610120850183613faa565b915060208501516155f6604086018267ffffffffffffffff169052565b5060408501516001600160a01b03811660608601525060608501516080850152608085015161563060a08601826001600160a01b03169052565b5060a0850151601f19808685030160c087015261564d8483613faa565b935060c08701519150808685030160e087015261566a8483613faa565b935060e08701519150808685030183870152506156878382613faa565b9695505050505050565b6000604082840312156156a357600080fd5b6156ab614018565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146156d757600080fd5b81526156e560208401614fad565b60208201529392505050565b60008261570057615700614c3e565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + Bin: "0x6101a06040523480156200001257600080fd5b5060405162005e1238038062005e128339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615749620006c9600039600081816102ec01528181611a5201526130470152600081816102bd01528181611a2a0152611cdc01526000818161028e01528181610e7f01528181610ee401528181611a000152818161222d015261229701526000611e7b01526000818161025f01526119d60152600081816101ff015261197a01526000818161022f015281816119ae01528181611c9901528181612ca901526131580152600081816101d0015281816119550152611f5b015260008181611bf30152611c3f01526157496000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806381ff7048116100d8578063afcb95d71161008c578063f077b59211610066578063f077b592146105f3578063f2fde38b14610609578063f52121a51461061c57600080fd5b8063afcb95d7146105ad578063b1dc65a4146105cd578063c92b2832146105e057600080fd5b8063856c8247116100bd578063856c82471461055d578063873504d7146105895780638da5cb5b1461059c57600080fd5b806381ff70481461051f57806385572ffb1461054f57600080fd5b8063599f64311161013a578063740f415011610114578063740f4150146104615780637437ff9f1461047457806379ba50971461051757600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516103299190613e8a565b60405180910390f35b610345610340366004613f20565b61062f565b6040516103299190613f80565b61038e6040518060400160405280601881526020017f45564d3245564d4f666652616d7020312e352e302d646576000000000000000081525081565b6040516103299190613fde565b6103ae6103a9366004614207565b6106aa565b005b6103b8610a9e565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610b53565b6040516103299190614319565b6103ae61045c36600461432c565b610bb5565b6103ae61046f36600461478c565b610c7e565b61050a6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a01000000000000000000009091046001600160a01b039081166060830152600b5416608082015290565b6040516103299190614847565b6103ae610d70565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae61018236600461489d565b61057061056b36600461432c565b610e53565b60405167ffffffffffffffff9091168152602001610329565b6103ae610597366004614969565b610f56565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae6105db366004614a12565b611124565b6103ae6105ee366004614b17565b61132f565b6105fb61139a565b604051610329929190614b85565b6103ae61061736600461432c565b6114c0565b6103ae61062a366004614baa565b6114d1565b600061063d60016004614c33565b600261064a608085614c75565b67ffffffffffffffff1661065e9190614c9c565b6010600061066d608087614cb3565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106a4576106a4613f3d565b92915050565b84518460ff16601f8211156106f75760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614cda565b60405180910390fd5b806000036107345760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614cda565b61073c611771565b610745856117e7565b60095460005b818110156107bc57600860006009838154811061076a5761076a614cf4565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161074b565b5050865160005b8181101561095f5760008982815181106107df576107df614cf4565b60200260200101519050600060028111156107fc576107fc613f3d565b6001600160a01b038216600090815260086020526040902054610100900460ff16600281111561082e5761082e613f3d565b146108685760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614cda565b6001600160a01b0381166108a8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561094b5761094b613f3d565b0217905550905050508060010190506107c3565b5087516109739060099060208b0190613df8565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a1617179055600780546109f99146913091906000906109cb9063ffffffff16614d23565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611ab1565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610a8a9487949293918316921691909117908f908f908f908f908f908f90614d46565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610b4e90611b3e565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bab57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8d575b5050505050905090565b6000546001600160a01b03163314801590610bdb57506002546001600160a01b03163314155b15610c12576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b610c86611bf0565b81515181518114610cc3576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d60576000838281518110610ce257610ce2614cf4565b6020026020010151905080600014610d57578451805183908110610d0857610d08614cf4565b602002602001015160800151811015610d57576040517f085e39cf00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016106ee565b50600101610cc6565b50610d6b8383611c71565b505050565b6001546001600160a01b03163314610de4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106ee565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106a4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106a4576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4f9190614ddc565b9392505050565b610f5e611771565b60005b825181101561103157610f9b838281518110610f7f57610f7f614cf4565b602002602001015160200151600c61269d90919063ffffffff16565b15611029577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d58782838281518110610fd357610fd3614cf4565b602002602001015160000151848381518110610ff157610ff1614cf4565b6020026020010151602001516040516110209291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610f61565b5060005b8151811015610d6b5761108e82828151811061105357611053614cf4565b60200260200101516020015183838151811061107157611071614cf4565b602002602001015160000151600c6126b29092919063ffffffff16565b1561111c577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a8282815181106110c6576110c6614cf4565b6020026020010151600001518383815181106110e4576110e4614cf4565b6020026020010151602001516040516111139291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101611035565b61112e87876126d0565b600554883590808214611177576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016106ee565b61117f611bf0565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561120757611207613f3d565b600281111561121857611218613f3d565b905250905060028160200151600281111561123557611235613f3d565b14801561126f57506009816000015160ff168154811061125757611257614cf4565b6000918252602090912001546001600160a01b031633145b6112a5576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006112b3856020614c9c565b6112be886020614c9c565b6112ca8b610144614df9565b6112d49190614df9565b6112de9190614df9565b9050368114611322576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016106ee565b5050505050505050505050565b6000546001600160a01b0316331480159061135557506002546001600160a01b03163314155b1561138c576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113976003826126f7565b50565b60608060006113a9600c6128dc565b90508067ffffffffffffffff8111156113c4576113c4613ff1565b6040519080825280602002602001820160405280156113ed578160200160208202803683370190505b5092508067ffffffffffffffff81111561140957611409613ff1565b604051908082528060200260200182016040528015611432578160200160208202803683370190505b50915060005b818110156114ba5760008061144e600c846128e7565b915091508086848151811061146557611465614cf4565b60200260200101906001600160a01b031690816001600160a01b0316815250508185848151811061149857611498614cf4565b6001600160a01b03909216602092830291909101909101525050600101611438565b50509091565b6114c8611771565b61139781612905565b33301461150a576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611547565b60408051808201909152600080825260208201528152602001906001900390816115205790505b5061014084015151909150156115a7576115a4836101400151846020015160405160200161158491906001600160a01b0391909116815260200190565b6040516020818303038152906040528560400151866101600151866129e0565b90505b610120830151511580156115bd57506080830151155b806115d4575060408301516001600160a01b03163b155b8061161457506040830151611612906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612b11565b155b1561161e57505050565b600080600a600001600a9054906101000a90046001600160a01b03166001600160a01b0316633cf979836040518060a001604052808861018001518152602001886000015167ffffffffffffffff168152602001886020015160405160200161169691906001600160a01b0391909116815260200190565b6040516020818303038152906040528152602001886101200151815260200186815250611388886080015189604001516040518563ffffffff1660e01b81526004016116e59493929190614e51565b6000604051808303816000875af1158015611704573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261172c9190810190614f5b565b50915091508161176a57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016106ee9190613fde565b5050505050565b6000546001600160a01b031633146117e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106ee565b565b6000818060200190518101906117fd9190614fc9565b60608101519091506001600160a01b0316611844576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a01000000000000000000006001600160a01b039485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611aa5918490615064565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611ad599989796959493929190615126565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611bcc82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611bb09190614c33565b85608001516fffffffffffffffffffffffffffffffff16612b2d565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b467f0000000000000000000000000000000000000000000000000000000000000000146117e5576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016106ee565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d4f91906151ae565b15611d86576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151516000819003611dc3576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114611e01576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff811115611e1c57611e1c613ff1565b604051908082528060200260200182016040528015611e45578160200160208202803683370190505b50905060005b82811015611f1d57600085600001518281518110611e6b57611e6b614cf4565b60200260200101519050611e9f817f0000000000000000000000000000000000000000000000000000000000000000612b4c565b838381518110611eb157611eb1614cf4565b602002602001018181525050806101800151838381518110611ed557611ed5614cf4565b602002602001015114611f14576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101611e4b565b50604080850151606086015191517f320488750000000000000000000000000000000000000000000000000000000081526000926001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692633204887592611f91928792916004016151fc565b602060405180830381865afa158015611fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd29190615232565b90508060000361200e576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b848110156126945760008760000151828151811061203557612035614cf4565b60200260200101519050600061204e826060015161062f565b9050600081600381111561206457612064613f3d565b14806120815750600381600381111561207f5761207f613f3d565b145b6120c757816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a2505061268c565b831561218457600a5460009063ffffffff166120e38742614c33565b11905080806121035750600382600381111561210157612101613f3d565b145b612139576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88848151811061214b5761214b614cf4565b602002602001015160001461217e5788848151811061216c5761216c614cf4565b60200260200101518360800181815250505b506121e7565b600081600381111561219857612198613f3d565b146121e757606082015160405167ffffffffffffffff90911681527f67d9ba0f63d427c482c2736300e6d5a34c6691dbcdea8ad35828a1f1ba47e8729060200160405180910390a1505061268c565b60c082015167ffffffffffffffff1615612466576020808301516001600160a01b03166000908152600f909152604081205467ffffffffffffffff16908190036123d1577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156123d15760208301516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa1580156122e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123049190614ddc565b60c084015190915067ffffffffffffffff1661232182600161524b565b67ffffffffffffffff16146123815782602001516001600160a01b03168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a350505061268c565b6020838101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b60008260038111156123e5576123e5613f3d565b036124645760c083015167ffffffffffffffff1661240482600161524b565b67ffffffffffffffff16146124645782602001516001600160a01b03168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a350505061268c565b505b60008960200151848151811061247e5761247e614cf4565b602002602001015190506124aa8360600151846000015185610140015151866101200151518551612ca7565b6124b983606001516001612e21565b6000806124c68584612ecb565b915091506124d8856060015183612e21565b86156125445760038260038111156124f2576124f2613f3d565b0361254457600084600381111561250b5761250b613f3d565b1461254457806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016106ee9190613fde565b600282600381111561255857612558613f3d565b146125b057600382600381111561257157612571613f3d565b146125b0578460600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016106ee92919061526c565b60c085015167ffffffffffffffff16156126385760008460038111156125d8576125d8613f3d565b03612638576020808601516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff16916126108361528a565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b846101800151856060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef65848460405161267e9291906152a7565b60405180910390a350505050505b600101612015565b50505050505050565b6000610f4f836001600160a01b038416612f94565b60006126c8846001600160a01b03851684612fa0565b949350505050565b6126f36126df828401846152c7565b604080516000815260208101909152611c71565b5050565b815460009061272090700100000000000000000000000000000000900463ffffffff1642614c33565b905080156127c25760018301548354612768916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b2d565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546127e8916fffffffffffffffffffffffffffffffff9081169116612fb6565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906128cf9084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106a482612fcc565b60008080806128f68686612fd7565b909450925050505b9250929050565b336001600160a01b03821603612977576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106ee565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b846000805b8751811015612af657612a5d888281518110612a0357612a03614cf4565b6020026020010151602001518888888581518110612a2357612a23614cf4565b6020026020010151806020019051810190612a3e91906152fc565b888681518110612a5057612a50614cf4565b6020026020010151612fe6565b838281518110612a6f57612a6f614cf4565b6020026020010181905250612aab838281518110612a8f57612a8f614cf4565b602002602001015160000151600c6133ee90919063ffffffff16565b15612aee57612ae1838281518110612ac557612ac5614cf4565b6020908102919091010151600b546001600160a01b0316613403565b612aeb9083614df9565b91505b6001016129e5565b508015612b0657612b0681613524565b505b95945050505050565b6000612b1c83613531565b8015610f4f5750610f4f8383613595565b6000612b0885612b3d8486614c9c565b612b479087614df9565b612fb6565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612be29897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612c1b91906153c2565b60405160208183030381529060405280519060200120876101600151604051602001612c47919061542f565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff1614612d20576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016106ee565b600a5468010000000000000000900461ffff16831115612d78576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b808314612dbd576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b600a54640100000000900463ffffffff1682111561176a57600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff166004820152602481018390526044016106ee565b60006002612e30608085614c75565b67ffffffffffffffff16612e449190614c9c565b90506000601081612e56608087614cb3565b67ffffffffffffffff168152602081019190915260400160002054905081612e8060016004614c33565b901b191681836003811115612e9757612e97613f3d565b901b178060106000612eaa608088614cb3565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a590612f0f9087908790600401615442565b600060405180830381600087803b158015612f2957600080fd5b505af1925050508015612f3a575060015b612f79573d808015612f68576040519150601f19603f3d011682016040523d82523d6000602084013e612f6d565b606091505b506003925090506128fe565b50506040805160208101909152600081526002909250929050565b6000610f4f8383613664565b60006126c884846001600160a01b038516613681565b6000818310612fc55781610f4f565b5090919050565b60006106a48261369e565b60008080806128f686866136a9565b6040805180820190915260008082526020820152600061300984602001516136d4565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa15801561308e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130b291906155a5565b90506001600160a01b03811615806130fa57506130f86001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612b11565b155b1561313c576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016106ee565b60008060006132416040518061010001604052808c81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018b6001600160a01b031681526020018d8152602001876001600160a01b031681526020018a6000015181526020018a604001518152602001898152506040516024016131d291906155c2565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905260608a0151869063ffffffff16611388608461377a565b9250925092508261328057816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190613fde565b81516020146132c85781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b6000828060200190518101906132de9190615232565b6040516001600160a01b0380881660248301528c166044820152606481018290529091506133839060840160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905260608b0151889061337990869063ffffffff16614c33565b611388608461377a565b509094509250836133c257826040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190613fde565b604080518082019091526001600160a01b03909616865260208601525092935050505095945050505050565b6000610f4f836001600160a01b0384166138a0565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613469573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348d9190615699565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036134f65783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016106ee565b60208401516126c8907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316906138ac565b61139760038260006138e9565b600061355d827f01ffc9a700000000000000000000000000000000000000000000000000000000613595565b80156106a4575061358e827fffffffff00000000000000000000000000000000000000000000000000000000613595565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561364d575060208210155b80156136595750600081115b979650505050505050565b60008181526002830160205260408120819055610f4f8383613c38565b600082815260028401602052604081208290556126c88484613c44565b60006106a482613c50565b600080806136b78585613c5a565b600081815260029690960160205260409095205494959350505050565b6000815160201461371357816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190613fde565b6000828060200190518101906137299190615232565b90506001600160a01b03811180613741575061040081105b156106a457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190613fde565b6000606060008361ffff1667ffffffffffffffff81111561379d5761379d613ff1565b6040519080825280601f01601f1916602001820160405280156137c7576020820181803683370190505b509150863b6137fa577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a8581101561382d577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613866577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156138895750835b808352806000602085013e50955095509592505050565b6000610f4f8383613c66565b6000670de0b6b3a76400006138df837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616614c9c565b610f4f91906156f9565b825474010000000000000000000000000000000000000000900460ff161580613910575081155b1561391a57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061396090700100000000000000000000000000000000900463ffffffff1642614c33565b90508015613a2057818311156139a2576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546139dc9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b2d565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613abd576001600160a01b038416613a72576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106ee565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b03851660448201526064016106ee565b84831015613bb65760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613b019082614c33565b613b0b878a614c33565b613b159190614df9565b613b1f91906156f9565b90506001600160a01b038616613b6b576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106ee565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b03871660448201526064016106ee565b613bc08584614c33565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f4f8383613c85565b6000610f4f8383613d7f565b60006106a4825490565b6000610f4f8383613dce565b6000610f4f838360008181526001830160205260408120541515610f4f565b60008181526001830160205260408120548015613d6e576000613ca9600183614c33565b8554909150600090613cbd90600190614c33565b9050818114613d22576000866000018281548110613cdd57613cdd614cf4565b9060005260206000200154905080876000018481548110613d0057613d00614cf4565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613d3357613d3361570d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106a4565b60009150506106a4565b5092915050565b6000818152600183016020526040812054613dc6575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106a4565b5060006106a4565b6000826000018281548110613de557613de5614cf4565b9060005260206000200154905092915050565b828054828255906000526020600020908101928215613e65579160200282015b82811115613e6557825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190613e18565b50613e71929150613e75565b5090565b5b80821115613e715760008155600101613e76565b60e081016106a482846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff8116811461139757600080fd5b8035613f1b81613efa565b919050565b600060208284031215613f3257600080fd5b8135610f4f81613efa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110613f7c57613f7c613f3d565b9052565b602081016106a48284613f6c565b60005b83811015613fa9578181015183820152602001613f91565b50506000910152565b60008151808452613fca816020860160208601613f8e565b601f01601f19169290920160200192915050565b602081526000610f4f6020830184613fb2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561404357614043613ff1565b60405290565b6040516101a0810167ffffffffffffffff8111828210171561404357614043613ff1565b6040516080810167ffffffffffffffff8111828210171561404357614043613ff1565b604051601f8201601f1916810167ffffffffffffffff811182821017156140b9576140b9613ff1565b604052919050565b600067ffffffffffffffff8211156140db576140db613ff1565b5060051b60200190565b6001600160a01b038116811461139757600080fd5b8035613f1b816140e5565b600082601f83011261411657600080fd5b8135602061412b614126836140c1565b614090565b8083825260208201915060208460051b87010193508684111561414d57600080fd5b602086015b84811015614172578035614165816140e5565b8352918301918301614152565b509695505050505050565b803560ff81168114613f1b57600080fd5b600067ffffffffffffffff8211156141a8576141a8613ff1565b50601f01601f191660200190565b600082601f8301126141c757600080fd5b81356141d56141268261418e565b8181528460208386010111156141ea57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561422057600080fd5b863567ffffffffffffffff8082111561423857600080fd5b6142448a838b01614105565b9750602089013591508082111561425a57600080fd5b6142668a838b01614105565b965061427460408a0161417d565b9550606089013591508082111561428a57600080fd5b6142968a838b016141b6565b94506142a460808a01613f10565b935060a08901359150808211156142ba57600080fd5b506142c789828a016141b6565b9150509295509295509295565b60008151808452602080850194506020840160005b8381101561430e5781516001600160a01b0316875295820195908201906001016142e9565b509495945050505050565b602081526000610f4f60208301846142d4565b60006020828403121561433e57600080fd5b8135610f4f816140e5565b801515811461139757600080fd5b8035613f1b81614349565b600082601f83011261437357600080fd5b81356020614383614126836140c1565b82815260069290921b840181019181810190868411156143a257600080fd5b8286015b8481101561417257604081890312156143bf5760008081fd5b6143c7614020565b81356143d2816140e5565b815281850135858201528352918301916040016143a6565b600082601f8301126143fb57600080fd5b8135602061440b614126836140c1565b82815260059290921b8401810191818101908684111561442a57600080fd5b8286015b8481101561417257803567ffffffffffffffff81111561444e5760008081fd5b61445c8986838b01016141b6565b84525091830191830161442e565b60006101a0828403121561447d57600080fd5b614485614049565b905061449082613f10565b815261449e602083016140fa565b60208201526144af604083016140fa565b60408201526144c060608301613f10565b6060820152608082013560808201526144db60a08301614357565b60a08201526144ec60c08301613f10565b60c08201526144fd60e083016140fa565b60e082015261010082810135908201526101208083013567ffffffffffffffff8082111561452a57600080fd5b614536868387016141b6565b8385015261014092508285013591508082111561455257600080fd5b61455e86838701614362565b8385015261016092508285013591508082111561457a57600080fd5b50614587858286016143ea565b82840152505061018080830135818301525092915050565b600082601f8301126145b057600080fd5b813560206145c0614126836140c1565b82815260059290921b840181019181810190868411156145df57600080fd5b8286015b8481101561417257803567ffffffffffffffff8111156146035760008081fd5b6146118986838b01016143ea565b8452509183019183016145e3565b600082601f83011261463057600080fd5b81356020614640614126836140c1565b8083825260208201915060208460051b87010193508684111561466257600080fd5b602086015b848110156141725780358352918301918301614667565b60006080828403121561469057600080fd5b61469861406d565b9050813567ffffffffffffffff808211156146b257600080fd5b818401915084601f8301126146c657600080fd5b813560206146d6614126836140c1565b82815260059290921b840181019181810190888411156146f557600080fd5b8286015b8481101561472d578035868111156147115760008081fd5b61471f8b86838b010161446a565b8452509183019183016146f9565b508652508581013593508284111561474457600080fd5b6147508785880161459f565b9085015250604084013591508082111561476957600080fd5b506147768482850161461f565b6040830152506060820135606082015292915050565b6000806040838503121561479f57600080fd5b823567ffffffffffffffff808211156147b757600080fd5b6147c38683870161467e565b93506020915081850135818111156147da57600080fd5b85019050601f810186136147ed57600080fd5b80356147fb614126826140c1565b81815260059190911b8201830190838101908883111561481a57600080fd5b928401925b828410156148385783358252928401929084019061481f565b80955050505050509250929050565b60a081016106a4828463ffffffff8082511683528060208301511660208401525061ffff604082015116604083015260608101516001600160a01b03808216606085015280608084015116608085015250505050565b6000602082840312156148af57600080fd5b813567ffffffffffffffff8111156148c657600080fd5b820160a08185031215610f4f57600080fd5b600082601f8301126148e957600080fd5b813560206148f9614126836140c1565b82815260069290921b8401810191818101908684111561491857600080fd5b8286015b8481101561417257604081890312156149355760008081fd5b61493d614020565b8135614948816140e5565b815281850135614957816140e5565b8186015283529183019160400161491c565b6000806040838503121561497c57600080fd5b823567ffffffffffffffff8082111561499457600080fd5b6149a0868387016148d8565b935060208501359150808211156149b657600080fd5b506149c3858286016148d8565b9150509250929050565b60008083601f8401126149df57600080fd5b50813567ffffffffffffffff8111156149f757600080fd5b6020830191508360208260051b85010111156128fe57600080fd5b60008060008060008060008060e0898b031215614a2e57600080fd5b606089018a811115614a3f57600080fd5b8998503567ffffffffffffffff80821115614a5957600080fd5b818b0191508b601f830112614a6d57600080fd5b813581811115614a7c57600080fd5b8c6020828501011115614a8e57600080fd5b6020830199508098505060808b0135915080821115614aac57600080fd5b614ab88c838d016149cd565b909750955060a08b0135915080821115614ad157600080fd5b50614ade8b828c016149cd565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff81168114613f1b57600080fd5b600060608284031215614b2957600080fd5b6040516060810181811067ffffffffffffffff82111715614b4c57614b4c613ff1565b6040528235614b5a81614349565b8152614b6860208401614af7565b6020820152614b7960408401614af7565b60408201529392505050565b604081526000614b9860408301856142d4565b8281036020840152612b0881856142d4565b60008060408385031215614bbd57600080fd5b823567ffffffffffffffff80821115614bd557600080fd5b614be18683870161446a565b93506020850135915080821115614bf757600080fd5b506149c3858286016143ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106a4576106a4614c04565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680614c9057614c90614c46565b92169190910692915050565b80820281158282048414176106a4576106a4614c04565b600067ffffffffffffffff80841680614cce57614cce614c46565b92169190910492915050565b6020810160038310614cee57614cee613f3d565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103614d3c57614d3c614c04565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614d768184018a6142d4565b90508281036080840152614d8a81896142d4565b905060ff871660a084015282810360c0840152614da78187613fb2565b905067ffffffffffffffff851660e0840152828103610100840152614dcc8185613fb2565b9c9b505050505050505050505050565b600060208284031215614dee57600080fd5b8151610f4f81613efa565b808201808211156106a4576106a4614c04565b60008151808452602080850194506020840160005b8381101561430e57815180516001600160a01b031688528301518388015260409096019590820190600101614e21565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152614e8c610120840182613fb2565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e0860152614ec88383613fb2565b925060808901519150808584030161010086015250614ee78282614e0c565b92505050614efb602083018661ffff169052565b836040830152612b0860608301846001600160a01b03169052565b600082601f830112614f2757600080fd5b8151614f356141268261418e565b818152846020838601011115614f4a57600080fd5b6126c8826020830160208701613f8e565b600080600060608486031215614f7057600080fd5b8351614f7b81614349565b602085015190935067ffffffffffffffff811115614f9857600080fd5b614fa486828701614f16565b925050604084015190509250925092565b805163ffffffff81168114613f1b57600080fd5b600060a08284031215614fdb57600080fd5b60405160a0810181811067ffffffffffffffff82111715614ffe57614ffe613ff1565b60405261500a83614fb5565b815261501860208401614fb5565b6020820152604083015161ffff8116811461503257600080fd5b60408201526060830151615045816140e5565b60608201526080830151615058816140e5565b60808201529392505050565b61018081016150d582856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff1661012083015260608301516001600160a01b03908116610140840152608084015116610160830152610f4f565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526151608285018b6142d4565b91508382036080850152615174828a6142d4565b915060ff881660a085015283820360c08501526151918288613fb2565b90861660e08501528381036101008501529050614dcc8185613fb2565b6000602082840312156151c057600080fd5b8151610f4f81614349565b60008151808452602080850194506020840160005b8381101561430e578151875295820195908201906001016151e0565b60608152600061520f60608301866151cb565b828103602084015261522181866151cb565b915050826040830152949350505050565b60006020828403121561524457600080fd5b5051919050565b67ffffffffffffffff818116838216019080821115613d7857613d78614c04565b67ffffffffffffffff8316815260408101610f4f6020830184613f6c565b600067ffffffffffffffff808316818103614d3c57614d3c614c04565b6152b18184613f6c565b6040602082015260006126c86040830184613fb2565b6000602082840312156152d957600080fd5b813567ffffffffffffffff8111156152f057600080fd5b6126c88482850161467e565b60006020828403121561530e57600080fd5b815167ffffffffffffffff8082111561532657600080fd5b908301906080828603121561533a57600080fd5b61534261406d565b82518281111561535157600080fd5b61535d87828601614f16565b82525060208301518281111561537257600080fd5b61537e87828601614f16565b60208301525060408301518281111561539657600080fd5b6153a287828601614f16565b6040830152506153b460608401614fb5565b606082015295945050505050565b602081526000610f4f6020830184614e0c565b60008282518085526020808601955060208260051b8401016020860160005b8481101561542257601f19868403018952615410838351613fb2565b988401989250908301906001016153f4565b5090979650505050505050565b602081526000610f4f60208301846153d5565b6040815261545d60408201845167ffffffffffffffff169052565b6000602084015161547960608401826001600160a01b03169052565b5060408401516001600160a01b038116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c08401516101006154da8185018367ffffffffffffffff169052565b60e086015191506101206154f8818601846001600160a01b03169052565b81870151925061014091508282860152808701519250506101a061016081818701526155286101e0870185613fb2565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc06101808188870301818901526155678686614e0c565b9550828a0151945081888703018489015261558286866153d5565b9550808a01516101c089015250505050508281036020840152612b0881856153d5565b6000602082840312156155b757600080fd5b8151610f4f816140e5565b60208152600082516101008060208501526155e1610120850183613fb2565b915060208501516155fe604086018267ffffffffffffffff169052565b5060408501516001600160a01b03811660608601525060608501516080850152608085015161563860a08601826001600160a01b03169052565b5060a0850151601f19808685030160c08701526156558483613fb2565b935060c08701519150808685030160e08701526156728483613fb2565b935060e087015191508086850301838701525061568f8382613fb2565b9695505050505050565b6000604082840312156156ab57600080fd5b6156b3614020565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146156df57600080fd5b81526156ed60208401614fb5565b60208201529392505050565b60008261570857615708614c46565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var EVM2EVMOffRampABI = EVM2EVMOffRampMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go index b2ee5137da..3e8e53c03f 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var LockReleaseTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b506040516200499e3803806200499e833981016040819052620000359162000565565b848484833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200017e565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001695760408051600081526020810190915262000169908462000229565b5050505090151560e05250620006d692505050565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000688565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000688565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200069e565b8554909150600090620003fa906001906200069e565b9050818114620004665760008660000182815481106200041e576200041e62000688565b906000526020600020015490508087600001848154811062000444576200044462000688565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a620006c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b805180151581146200054f57600080fd5b600080600080600060a086880312156200057e57600080fd5b85516200058b8162000513565b602087810151919650906001600160401b0380821115620005ab57600080fd5b818901915089601f830112620005c057600080fd5b815181811115620005d557620005d56200052c565b8060051b604051601f19603f83011681018181108582111715620005fd57620005fd6200052c565b60405291825284820192508381018501918c8311156200061c57600080fd5b938501935b828510156200064557620006358562000542565b8452938501939285019262000621565b8099505050505050506200065c6040870162000542565b92506200066c6060870162000554565b91506200067c6080870162000542565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161422c62000772600039600081816104ef015261173201526000818161059c01528181611cce015261277301526000818161057601528181611aff0152611f84015260008181610290015281816102e50152818161077a0152818161084c015281816108dd015281816117f401528181611a1f01528181611ea401528181612709015261295e015261422c6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063c4bffe2b116100a2578063dc0bd97111610071578063dc0bd97114610574578063e0351e131461059a578063eb521a4c146105c0578063f2fde38b146105d357600080fd5b8063c4bffe2b14610526578063c75eea9c1461053b578063cf7401f31461054e578063db6327dc1461056157600080fd5b8063b0f479a1116100de578063b0f479a1146104bc578063b7946580146104da578063bb98546b146104ed578063c0d786551461051357600080fd5b80638da5cb5b146103fa5780639a4575b914610418578063a7cd63b714610438578063af58d59f1461044d57600080fd5b806354c8a4f31161018757806378a010b21161015657806378a010b2146103b957806379ba5097146103cc5780637d54534e146103d45780638926f54f146103e757600080fd5b806354c8a4f31461036257806366320087146103755780636cfd1553146103885780636d3d1a581461039b57600080fd5b806321df0da7116101c357806321df0da71461028e578063240028e8146102d55780633907753714610322578063432a6ba31461034457600080fd5b806301ffc9a7146101f55780630a2fd4931461021d5780630a861f2a1461023d578063181f5a7714610252575b600080fd5b610208610203366004613308565b6105e6565b60405190151581526020015b60405180910390f35b61023061022b366004613367565b610642565b60405161021491906133f0565b61025061024b366004613403565b6106f2565b005b6102306040518060400160405280601e81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e302d646576000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b6102086102e3366004613449565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b610335610330366004613466565b6108a3565b60405190518152602001610214565b60095473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103703660046134ee565b610999565b61025061038336600461355a565b610a14565b610250610396366004613449565b610af0565b60085473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103c7366004613586565b610b3f565b610250610cae565b6102506103e2366004613449565b610dab565b6102086103f5366004613367565b610dfa565b60005473ffffffffffffffffffffffffffffffffffffffff166102b0565b61042b610426366004613609565b610e11565b6040516102149190613644565b610440610eab565b60405161021491906136a4565b61046061045b366004613367565b610ebc565b604051610214919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102306104e8366004613367565b610f91565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b610250610521366004613449565b610fbc565b61052e611097565b60405161021491906136fe565b610460610549366004613367565b61114f565b61025061055c366004613866565b611221565b61025061056f3660046138ab565b6112aa565b7f00000000000000000000000000000000000000000000000000000000000000006102b0565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105ce366004613403565b611730565b6102506105e1366004613449565b61184c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061063c575061063c82611860565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061066d906138ed565b80601f0160208091040260200160405190810160405280929190818152602001828054610699906138ed565b80156106e65780601f106106bb576101008083540402835291602001916106e6565b820191906000526020600020905b8154815290600101906020018083116106c957829003601f168201915b50505050509050919050565b60095473ffffffffffffffffffffffffffffffffffffffff16331461074a576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa9190613940565b1015610832576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611944565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c36108be83613a04565b611a18565b61090873ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016336060850135611944565b6109186060830160408401613449565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52846060013560405161097a91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6109a1611c49565b610a0e84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ccc92505050565b50505050565b610a1c611c49565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610a8457600080fd5b505af1158015610a98573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610ae491815260200190565b60405180910390a25050565b610af8611c49565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b47611c49565b610b5083610dfa565b610b92576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b67ffffffffffffffff831660009081526007602052604081206004018054610bb9906138ed565b80601f0160208091040260200160405190810160405280929190818152602001828054610be5906138ed565b8015610c325780601f10610c0757610100808354040283529160200191610c32565b820191906000526020600020905b815481529060010190602001808311610c1557829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610c61838583613b49565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610ca093929190613c64565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610741565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610db3611c49565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061063c600567ffffffffffffffff8416611e82565b6040805180820190915260608082526020820152610e36610e3183613cc8565b611e9d565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610e908460200160208101906104e89190613367565b81526040805160208181019092526000815291015292915050565b6060610eb76002612067565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261063c90612074565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061066d906138ed565b610fc4611c49565b73ffffffffffffffffffffffffffffffffffffffff8116611011576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110a56005612067565b90506000815167ffffffffffffffff8111156110c3576110c3613740565b6040519080825280602002602001820160405280156110ec578160200160208202803683370190505b50905060005b82518110156111485782818151811061110d5761110d613d6a565b602002602001015182828151811061112757611127613d6a565b67ffffffffffffffff909216602092830291909101909101526001016110f2565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261063c90612074565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611261575060005473ffffffffffffffffffffffffffffffffffffffff163314155b1561129a576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b6112a5838383612126565b505050565b6112b2611c49565b60005b818110156112a55760008383838181106112d1576112d1613d6a565b90506020028101906112e39190613d99565b6112ec90613dd7565b90506113018160800151826020015115612210565b6113148160a00151826020015115612210565b8060200151156116105780516113369060059067ffffffffffffffff16612349565b61137b5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b60408101515115806113905750606081015151155b156113c7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115a89082613e8b565b50606082015160058201906115bd9082613e8b565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116039493929190613fa5565b60405180910390a1611727565b80516116289060059067ffffffffffffffff16612355565b61166d5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116d660048301826132ba565b6116e46005830160006132ba565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112b5565b7f0000000000000000000000000000000000000000000000000000000000000000611787576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff1633146117da576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b61181c73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612361565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611854611c49565b61185d816123bf565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806118f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061063c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112a59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526124b4565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611aad5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b7f919061403e565b15611bb6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bc381602001516125c0565b6000611bd28260200151610642565b9050805160001480611bf6575080805190602001208260a001518051906020012014155b15611c33578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161074191906133f0565b611c45826020015183606001516126e6565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611cca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610741565b565b7f0000000000000000000000000000000000000000000000000000000000000000611d23576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611db9576000838281518110611d4357611d43613d6a565b60200260200101519050611d6181600261272d90919063ffffffff16565b15611db05760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611d26565b5060005b81518110156112a5576000828281518110611dda57611dda613d6a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e1e5750611e7a565b611e2960028261274f565b15611e785760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611dbd565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611f325760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611fe0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612004919061403e565b1561203b576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120488160400151612771565b61205581602001516127f0565b61185d8160200151826060015161293e565b60606000611e9683612982565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261210282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426120e6919061408a565b85608001516fffffffffffffffffffffffffffffffff166129dd565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61212f83610dfa565b612171576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b61217c826000612210565b67ffffffffffffffff8316600090815260076020526040902061219f9083612a07565b6121aa816000612210565b67ffffffffffffffff831660009081526007602052604090206121d09060020182612a07565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516122039392919061409d565b60405180910390a1505050565b8151156122d75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612266575060408201516fffffffffffffffffffffffffffffffff16155b1561229f57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107419190614120565b8015611c45576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612310575060208201516fffffffffffffffffffffffffffffffff1615155b15611c4557816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107419190614120565b6000611e968383612ba9565b6000611e968383612bf8565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a0e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611996565b3373ffffffffffffffffffffffffffffffffffffffff82160361243e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610741565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612516826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612ceb9092919063ffffffff16565b8051909150156112a55780806020019051810190612534919061403e565b6112a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610741565b6125c981610dfa565b61260b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561268a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ae919061403e565b61185d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c4590600201827f0000000000000000000000000000000000000000000000000000000000000000612cfa565b6000611e968373ffffffffffffffffffffffffffffffffffffffff8416612bf8565b6000611e968373ffffffffffffffffffffffffffffffffffffffff8416612ba9565b7f00000000000000000000000000000000000000000000000000000000000000001561185d576127a260028261307d565b61185d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610741565b6127f981610dfa565b61283b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156128b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128d8919061415c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461185d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c4590827f0000000000000000000000000000000000000000000000000000000000000000612cfa565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106e657602002820191906000526020600020905b8154815260200190600101908083116129be5750505050509050919050565b60006129fc856129ed8486614179565b6129f79087614190565b6130ac565b90505b949350505050565b8154600090612a3090700100000000000000000000000000000000900463ffffffff164261408a565b90508015612ad25760018301548354612a78916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166129dd565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612af8916fffffffffffffffffffffffffffffffff90811691166130ac565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612203908490614120565b6000818152600183016020526040812054612bf05750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561063c565b50600061063c565b60008181526001830160205260408120548015612ce1576000612c1c60018361408a565b8554909150600090612c309060019061408a565b9050818114612c95576000866000018281548110612c5057612c50613d6a565b9060005260206000200154905080876000018481548110612c7357612c73613d6a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ca657612ca66141a3565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061063c565b600091505061063c565b60606129ff84846000856130c2565b825474010000000000000000000000000000000000000000900460ff161580612d21575081155b15612d2b57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612d7190700100000000000000000000000000000000900463ffffffff164261408a565b90508015612e315781831115612db3576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612ded9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166129dd565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612ee85773ffffffffffffffffffffffffffffffffffffffff8416612e90576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610741565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610741565b84831015612ffb5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f2c908261408a565b612f36878a61408a565b612f409190614190565b612f4a91906141d2565b905073ffffffffffffffffffffffffffffffffffffffff8616612fa3576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610741565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610741565b613005858461408a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611e96565b60008183106130bb5781611e96565b5090919050565b606082471015613154576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610741565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161317d919061420d565b60006040518083038185875af1925050503d80600081146131ba576040519150601f19603f3d011682016040523d82523d6000602084013e6131bf565b606091505b50915091506131d0878383876131db565b979650505050505050565b6060831561327157825160000361326a5773ffffffffffffffffffffffffffffffffffffffff85163b61326a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610741565b50816129ff565b6129ff83838151156132865781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074191906133f0565b5080546132c6906138ed565b6000825580601f106132d6575050565b601f01602090049060005260206000209081019061185d91905b8082111561330457600081556001016132f0565b5090565b60006020828403121561331a57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611e9657600080fd5b803567ffffffffffffffff8116811461336257600080fd5b919050565b60006020828403121561337957600080fd5b611e968261334a565b60005b8381101561339d578181015183820152602001613385565b50506000910152565b600081518084526133be816020860160208601613382565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611e9660208301846133a6565b60006020828403121561341557600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461185d57600080fd5b80356133628161341c565b60006020828403121561345b57600080fd5b8135611e968161341c565b60006020828403121561347857600080fd5b813567ffffffffffffffff81111561348f57600080fd5b82016101008185031215611e9657600080fd5b60008083601f8401126134b457600080fd5b50813567ffffffffffffffff8111156134cc57600080fd5b6020830191508360208260051b85010111156134e757600080fd5b9250929050565b6000806000806040858703121561350457600080fd5b843567ffffffffffffffff8082111561351c57600080fd5b613528888389016134a2565b9096509450602087013591508082111561354157600080fd5b5061354e878288016134a2565b95989497509550505050565b6000806040838503121561356d57600080fd5b82356135788161341c565b946020939093013593505050565b60008060006040848603121561359b57600080fd5b6135a48461334a565b9250602084013567ffffffffffffffff808211156135c157600080fd5b818601915086601f8301126135d557600080fd5b8135818111156135e457600080fd5b8760208285010111156135f657600080fd5b6020830194508093505050509250925092565b60006020828403121561361b57600080fd5b813567ffffffffffffffff81111561363257600080fd5b820160a08185031215611e9657600080fd5b60208152600082516040602084015261366060608401826133a6565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261369b82826133a6565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156136f257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016136c0565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156136f257835167ffffffffffffffff168352928401929184019160010161371a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561379357613793613740565b60405290565b60405160c0810167ffffffffffffffff8111828210171561379357613793613740565b801515811461185d57600080fd5b8035613362816137bc565b80356fffffffffffffffffffffffffffffffff8116811461336257600080fd5b60006060828403121561380757600080fd5b6040516060810181811067ffffffffffffffff8211171561382a5761382a613740565b604052905080823561383b816137bc565b8152613849602084016137d5565b602082015261385a604084016137d5565b60408201525092915050565b600080600060e0848603121561387b57600080fd5b6138848461334a565b925061389385602086016137f5565b91506138a285608086016137f5565b90509250925092565b600080602083850312156138be57600080fd5b823567ffffffffffffffff8111156138d557600080fd5b6138e1858286016134a2565b90969095509350505050565b600181811c9082168061390157607f821691505b60208210810361393a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561395257600080fd5b5051919050565b600082601f83011261396a57600080fd5b813567ffffffffffffffff8082111561398557613985613740565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156139cb576139cb613740565b816040528381528660208588010111156139e457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613a1757600080fd5b613a1f61376f565b823567ffffffffffffffff80821115613a3757600080fd5b613a4336838701613959565b8352613a516020860161334a565b6020840152613a626040860161343e565b604084015260608501356060840152613a7d6080860161343e565b608084015260a0850135915080821115613a9657600080fd5b613aa236838701613959565b60a084015260c0850135915080821115613abb57600080fd5b613ac736838701613959565b60c084015260e0850135915080821115613ae057600080fd5b50613aed36828601613959565b60e08301525092915050565b601f8211156112a5576000816000526020600020601f850160051c81016020861015613b225750805b601f850160051c820191505b81811015613b4157828155600101613b2e565b505050505050565b67ffffffffffffffff831115613b6157613b61613740565b613b7583613b6f83546138ed565b83613af9565b6000601f841160018114613bc75760008515613b915750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613c5d565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613c165786850135825560209485019460019092019101613bf6565b5086821015613c51577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613c7760408301866133a6565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613cda57600080fd5b60405160a0810167ffffffffffffffff8282108183111715613cfe57613cfe613740565b816040528435915080821115613d1357600080fd5b50613d2036828601613959565b825250613d2f6020840161334a565b60208201526040830135613d428161341c565b6040820152606083810135908201526080830135613d5f8161341c565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613dcd57600080fd5b9190910192915050565b60006101408236031215613dea57600080fd5b613df2613799565b613dfb8361334a565b8152613e09602084016137ca565b6020820152604083013567ffffffffffffffff80821115613e2957600080fd5b613e3536838701613959565b60408401526060850135915080821115613e4e57600080fd5b50613e5b36828601613959565b606083015250613e6e36608085016137f5565b6080820152613e803660e085016137f5565b60a082015292915050565b815167ffffffffffffffff811115613ea557613ea5613740565b613eb981613eb384546138ed565b84613af9565b602080601f831160018114613f0c5760008415613ed65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b41565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613f5957888601518255948401946001909101908401613f3a565b5085821015613f9557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613fc9818401876133a6565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506140079050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e083015261369b565b60006020828403121561405057600080fd5b8151611e96816137bc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561063c5761063c61405b565b67ffffffffffffffff8416815260e081016140e960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526129ff565b6060810161063c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561416e57600080fd5b8151611e968161341c565b808202811582820484141761063c5761063c61405b565b8082018082111561063c5761063c61405b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614208577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613dcd81846020870161338256fea164736f6c6343000818000a", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004a1738038062004a17833981016040819052620000359162000565565b848484833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200017e565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001695760408051600081526020810190915262000169908462000229565b5050505090151560e05250620006d692505050565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000688565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000688565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200069e565b8554909150600090620003fa906001906200069e565b9050818114620004665760008660000182815481106200041e576200041e62000688565b906000526020600020015490508087600001848154811062000444576200044462000688565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a620006c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b805180151581146200054f57600080fd5b600080600080600060a086880312156200057e57600080fd5b85516200058b8162000513565b602087810151919650906001600160401b0380821115620005ab57600080fd5b818901915089601f830112620005c057600080fd5b815181811115620005d557620005d56200052c565b8060051b604051601f19603f83011681018181108582111715620005fd57620005fd6200052c565b60405291825284820192508381018501918c8311156200061c57600080fd5b938501935b828510156200064557620006358562000542565b8452938501939285019262000621565b8099505050505050506200065c6040870162000542565b92506200066c6060870162000554565b91506200067c6080870162000542565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516142a562000772600039600081816104ef01526117ab01526000818161059c01528181611d4701526127ec01526000818161057601528181611b780152611ffd015260008181610290015281816102e50152818161077a0152818161084c015281816108c50152818161186d01528181611a9801528181611f1d0152818161278201526129d701526142a56000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063c4bffe2b116100a2578063dc0bd97111610071578063dc0bd97114610574578063e0351e131461059a578063eb521a4c146105c0578063f2fde38b146105d357600080fd5b8063c4bffe2b14610526578063c75eea9c1461053b578063cf7401f31461054e578063db6327dc1461056157600080fd5b8063b0f479a1116100de578063b0f479a1146104bc578063b7946580146104da578063bb98546b146104ed578063c0d786551461051357600080fd5b80638da5cb5b146103fa5780639a4575b914610418578063a7cd63b714610438578063af58d59f1461044d57600080fd5b806354c8a4f31161018757806378a010b21161015657806378a010b2146103b957806379ba5097146103cc5780637d54534e146103d45780638926f54f146103e757600080fd5b806354c8a4f31461036257806366320087146103755780636cfd1553146103885780636d3d1a581461039b57600080fd5b806321df0da7116101c357806321df0da71461028e578063240028e8146102d55780633907753714610322578063432a6ba31461034457600080fd5b806301ffc9a7146101f55780630a2fd4931461021d5780630a861f2a1461023d578063181f5a7714610252575b600080fd5b610208610203366004613381565b6105e6565b60405190151581526020015b60405180910390f35b61023061022b3660046133e0565b610642565b6040516102149190613469565b61025061024b36600461347c565b6106f2565b005b6102306040518060400160405280601e81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e302d646576000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b6102086102e33660046134c2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6103356103303660046134df565b6108a3565b60405190518152602001610214565b60095473ffffffffffffffffffffffffffffffffffffffff166102b0565b610250610370366004613567565b610a12565b6102506103833660046135d3565b610a8d565b6102506103963660046134c2565b610b69565b60085473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103c73660046135ff565b610bb8565b610250610d27565b6102506103e23660046134c2565b610e24565b6102086103f53660046133e0565b610e73565b60005473ffffffffffffffffffffffffffffffffffffffff166102b0565b61042b610426366004613682565b610e8a565b60405161021491906136bd565b610440610f24565b604051610214919061371d565b61046061045b3660046133e0565b610f35565b604051610214919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102306104e83660046133e0565b61100a565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105213660046134c2565b611035565b61052e611110565b6040516102149190613777565b6104606105493660046133e0565b6111c8565b61025061055c3660046138df565b61129a565b61025061056f366004613924565b611323565b7f00000000000000000000000000000000000000000000000000000000000000006102b0565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105ce36600461347c565b6117a9565b6102506105e13660046134c2565b6118c5565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061063c575061063c826118d9565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061066d90613966565b80601f016020809104026020016040519081016040528092919081815260200182805461069990613966565b80156106e65780601f106106bb576101008083540402835291602001916106e6565b820191906000526020600020905b8154815290600101906020018083116106c957829003601f168201915b50505050509050919050565b60095473ffffffffffffffffffffffffffffffffffffffff16331461074a576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa91906139b9565b1015610832576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633836119bd565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c36108be83613a7d565b611a91565b7f00000000000000000000000000000000000000000000000000000000000000006040517f095ea7b30000000000000000000000000000000000000000000000000000000081523360048201526060840135602482015273ffffffffffffffffffffffffffffffffffffffff919091169063095ea7b3906044016020604051808303816000875af115801561095c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109809190613b72565b5061099160608301604084016134c2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f5284606001356040516109f391815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a1a611cc2565b610a8784848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611d4592505050565b50505050565b610a95611cc2565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610afd57600080fd5b505af1158015610b11573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610b5d91815260200190565b60405180910390a25050565b610b71611cc2565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610bc0611cc2565b610bc983610e73565b610c0b576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b67ffffffffffffffff831660009081526007602052604081206004018054610c3290613966565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5e90613966565b8015610cab5780601f10610c8057610100808354040283529160200191610cab565b820191906000526020600020905b815481529060010190602001808311610c8e57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cda838583613bdf565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d1993929190613cfa565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610da8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610741565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e2c611cc2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061063c600567ffffffffffffffff8416611efb565b6040805180820190915260608082526020820152610eaf610eaa83613d5e565b611f16565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610f098460200160208101906104e891906133e0565b81526040805160208181019092526000815291015292915050565b6060610f3060026120e0565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261063c906120ed565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061066d90613966565b61103d611cc2565b73ffffffffffffffffffffffffffffffffffffffff811661108a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b6060600061111e60056120e0565b90506000815167ffffffffffffffff81111561113c5761113c6137b9565b604051908082528060200260200182016040528015611165578160200160208202803683370190505b50905060005b82518110156111c15782818151811061118657611186613e00565b60200260200101518282815181106111a0576111a0613e00565b67ffffffffffffffff9092166020928302919091019091015260010161116b565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261063c906120ed565b60085473ffffffffffffffffffffffffffffffffffffffff1633148015906112da575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611313576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b61131e83838361219f565b505050565b61132b611cc2565b60005b8181101561131e57600083838381811061134a5761134a613e00565b905060200281019061135c9190613e2f565b61136590613e6d565b905061137a8160800151826020015115612289565b61138d8160a00151826020015115612289565b8060200151156116895780516113af9060059067ffffffffffffffff166123c2565b6113f45780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b60408101515115806114095750606081015151155b15611440576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906116219082613f21565b50606082015160058201906116369082613f21565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061167c949392919061403b565b60405180910390a16117a0565b80516116a19060059067ffffffffffffffff166123ce565b6116e65780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600182018390556002820180549091169055600381018290559061174f6004830182613333565b61175d600583016000613333565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161132e565b7f0000000000000000000000000000000000000000000000000000000000000000611800576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff163314611853576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b61189573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846123da565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b6118cd611cc2565b6118d681612438565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061196c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061063c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261131e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261252d565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611b265760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611bd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf89190613b72565b15611c2f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c3c8160200151612639565b6000611c4b8260200151610642565b9050805160001480611c6f575080805190602001208260a001518051906020012014155b15611cac578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107419190613469565b611cbe8260200151836060015161275f565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611d43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610741565b565b7f0000000000000000000000000000000000000000000000000000000000000000611d9c576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611e32576000838281518110611dbc57611dbc613e00565b60200260200101519050611dda8160026127a690919063ffffffff16565b15611e295760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611d9f565b5060005b815181101561131e576000828281518110611e5357611e53613e00565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e975750611ef3565b611ea26002826127c8565b15611ef15760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611e36565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611fab5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207d9190613b72565b156120b4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120c181604001516127ea565b6120ce8160200151612869565b6118d6816020015182606001516129b7565b60606000611f0f836129fb565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261217b82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261215f9190614103565b85608001516fffffffffffffffffffffffffffffffff16612a56565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6121a883610e73565b6121ea576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b6121f5826000612289565b67ffffffffffffffff831660009081526007602052604090206122189083612a80565b612223816000612289565b67ffffffffffffffff831660009081526007602052604090206122499060020182612a80565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161227c93929190614116565b60405180910390a1505050565b8151156123505781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806122df575060408201516fffffffffffffffffffffffffffffffff16155b1561231857816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107419190614199565b8015611cbe576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612389575060208201516fffffffffffffffffffffffffffffffff1615155b15611cbe57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107419190614199565b6000611f0f8383612c22565b6000611f0f8383612c71565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a879085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611a0f565b3373ffffffffffffffffffffffffffffffffffffffff8216036124b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610741565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061258f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612d649092919063ffffffff16565b80519091501561131e57808060200190518101906125ad9190613b72565b61131e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610741565b61264281610e73565b612684576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612703573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127279190613b72565b6118d6576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611cbe90600201827f0000000000000000000000000000000000000000000000000000000000000000612d73565b6000611f0f8373ffffffffffffffffffffffffffffffffffffffff8416612c71565b6000611f0f8373ffffffffffffffffffffffffffffffffffffffff8416612c22565b7f0000000000000000000000000000000000000000000000000000000000000000156118d65761281b6002826130f6565b6118d6576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610741565b61287281610e73565b6128b4576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561292d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295191906141d5565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118d6576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611cbe90827f0000000000000000000000000000000000000000000000000000000000000000612d73565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106e657602002820191906000526020600020905b815481526020019060010190808311612a375750505050509050919050565b6000612a7585612a6684866141f2565b612a709087614209565b613125565b90505b949350505050565b8154600090612aa990700100000000000000000000000000000000900463ffffffff1642614103565b90508015612b4b5760018301548354612af1916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612a56565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612b71916fffffffffffffffffffffffffffffffff9081169116613125565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061227c908490614199565b6000818152600183016020526040812054612c695750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561063c565b50600061063c565b60008181526001830160205260408120548015612d5a576000612c95600183614103565b8554909150600090612ca990600190614103565b9050818114612d0e576000866000018281548110612cc957612cc9613e00565b9060005260206000200154905080876000018481548110612cec57612cec613e00565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612d1f57612d1f61421c565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061063c565b600091505061063c565b6060612a78848460008561313b565b825474010000000000000000000000000000000000000000900460ff161580612d9a575081155b15612da457505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612dea90700100000000000000000000000000000000900463ffffffff1642614103565b90508015612eaa5781831115612e2c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612e669083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612a56565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612f615773ffffffffffffffffffffffffffffffffffffffff8416612f09576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610741565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610741565b848310156130745760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612fa59082614103565b612faf878a614103565b612fb99190614209565b612fc3919061424b565b905073ffffffffffffffffffffffffffffffffffffffff861661301c576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610741565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610741565b61307e8584614103565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611f0f565b60008183106131345781611f0f565b5090919050565b6060824710156131cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610741565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516131f69190614286565b60006040518083038185875af1925050503d8060008114613233576040519150601f19603f3d011682016040523d82523d6000602084013e613238565b606091505b509150915061324987838387613254565b979650505050505050565b606083156132ea5782516000036132e35773ffffffffffffffffffffffffffffffffffffffff85163b6132e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610741565b5081612a78565b612a7883838151156132ff5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107419190613469565b50805461333f90613966565b6000825580601f1061334f575050565b601f0160209004906000526020600020908101906118d691905b8082111561337d5760008155600101613369565b5090565b60006020828403121561339357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611f0f57600080fd5b803567ffffffffffffffff811681146133db57600080fd5b919050565b6000602082840312156133f257600080fd5b611f0f826133c3565b60005b838110156134165781810151838201526020016133fe565b50506000910152565b600081518084526134378160208601602086016133fb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611f0f602083018461341f565b60006020828403121561348e57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146118d657600080fd5b80356133db81613495565b6000602082840312156134d457600080fd5b8135611f0f81613495565b6000602082840312156134f157600080fd5b813567ffffffffffffffff81111561350857600080fd5b82016101008185031215611f0f57600080fd5b60008083601f84011261352d57600080fd5b50813567ffffffffffffffff81111561354557600080fd5b6020830191508360208260051b850101111561356057600080fd5b9250929050565b6000806000806040858703121561357d57600080fd5b843567ffffffffffffffff8082111561359557600080fd5b6135a18883890161351b565b909650945060208701359150808211156135ba57600080fd5b506135c78782880161351b565b95989497509550505050565b600080604083850312156135e657600080fd5b82356135f181613495565b946020939093013593505050565b60008060006040848603121561361457600080fd5b61361d846133c3565b9250602084013567ffffffffffffffff8082111561363a57600080fd5b818601915086601f83011261364e57600080fd5b81358181111561365d57600080fd5b87602082850101111561366f57600080fd5b6020830194508093505050509250925092565b60006020828403121561369457600080fd5b813567ffffffffffffffff8111156136ab57600080fd5b820160a08185031215611f0f57600080fd5b6020815260008251604060208401526136d9606084018261341f565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613714828261341f565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561376b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613739565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561376b57835167ffffffffffffffff1683529284019291840191600101613793565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561380c5761380c6137b9565b60405290565b60405160c0810167ffffffffffffffff8111828210171561380c5761380c6137b9565b80151581146118d657600080fd5b80356133db81613835565b80356fffffffffffffffffffffffffffffffff811681146133db57600080fd5b60006060828403121561388057600080fd5b6040516060810181811067ffffffffffffffff821117156138a3576138a36137b9565b60405290508082356138b481613835565b81526138c26020840161384e565b60208201526138d36040840161384e565b60408201525092915050565b600080600060e084860312156138f457600080fd5b6138fd846133c3565b925061390c856020860161386e565b915061391b856080860161386e565b90509250925092565b6000806020838503121561393757600080fd5b823567ffffffffffffffff81111561394e57600080fd5b61395a8582860161351b565b90969095509350505050565b600181811c9082168061397a57607f821691505b6020821081036139b3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000602082840312156139cb57600080fd5b5051919050565b600082601f8301126139e357600080fd5b813567ffffffffffffffff808211156139fe576139fe6137b9565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613a4457613a446137b9565b81604052838152866020858801011115613a5d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613a9057600080fd5b613a986137e8565b823567ffffffffffffffff80821115613ab057600080fd5b613abc368387016139d2565b8352613aca602086016133c3565b6020840152613adb604086016134b7565b604084015260608501356060840152613af6608086016134b7565b608084015260a0850135915080821115613b0f57600080fd5b613b1b368387016139d2565b60a084015260c0850135915080821115613b3457600080fd5b613b40368387016139d2565b60c084015260e0850135915080821115613b5957600080fd5b50613b66368286016139d2565b60e08301525092915050565b600060208284031215613b8457600080fd5b8151611f0f81613835565b601f82111561131e576000816000526020600020601f850160051c81016020861015613bb85750805b601f850160051c820191505b81811015613bd757828155600101613bc4565b505050505050565b67ffffffffffffffff831115613bf757613bf76137b9565b613c0b83613c058354613966565b83613b8f565b6000601f841160018114613c5d5760008515613c275750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613cf3565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613cac5786850135825560209485019460019092019101613c8c565b5086821015613ce7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613d0d604083018661341f565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613d7057600080fd5b60405160a0810167ffffffffffffffff8282108183111715613d9457613d946137b9565b816040528435915080821115613da957600080fd5b50613db6368286016139d2565b825250613dc5602084016133c3565b60208201526040830135613dd881613495565b6040820152606083810135908201526080830135613df581613495565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613e6357600080fd5b9190910192915050565b60006101408236031215613e8057600080fd5b613e88613812565b613e91836133c3565b8152613e9f60208401613843565b6020820152604083013567ffffffffffffffff80821115613ebf57600080fd5b613ecb368387016139d2565b60408401526060850135915080821115613ee457600080fd5b50613ef1368286016139d2565b606083015250613f04366080850161386e565b6080820152613f163660e0850161386e565b60a082015292915050565b815167ffffffffffffffff811115613f3b57613f3b6137b9565b613f4f81613f498454613966565b84613b8f565b602080601f831160018114613fa25760008415613f6c5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613bd7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613fef57888601518255948401946001909101908401613fd0565b508582101561402b57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261405f8184018761341f565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061409d9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613714565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561063c5761063c6140d4565b67ffffffffffffffff8416815260e0810161416260208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612a78565b6060810161063c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156141e757600080fd5b8151611f0f81613495565b808202811582820484141761063c5761063c6140d4565b8082018082111561063c5761063c6140d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614281577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613e638184602087016133fb56fea164736f6c6343000818000a", } var LockReleaseTokenPoolABI = LockReleaseTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go index 73f2ea6dc4..88018a164b 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var LockReleaseTokenPoolAndProxyMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162004ef938038062004ef983398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508181146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516147786200078160003960008181610545015261190b0152600081816105f201528181611f400152612afc0152600081816105cc01528181611cd801526121f30152600081816102ad01528181610302015281816107d0015281816108a20152818161096c015281816119cd01528181611bf801528181612113015281816122f901528181612a920152612ce701526147786000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e13146105f0578063eb521a4c14610616578063f2fde38b1461062957600080fd5b8063db6327dc146105b7578063dc0bd971146105ca57600080fd5b8063c0d7865514610569578063c4bffe2b1461057c578063c75eea9c14610591578063cf7401f3146105a457600080fd5b8063a8d87a3b11610114578063b0f479a1116100f9578063b0f479a114610512578063b794658014610530578063bb98546b1461054357600080fd5b8063a8d87a3b14610490578063af58d59f146104a357600080fd5b80638da5cb5b1461042a5780639766b932146104485780639a4575b91461045b578063a7cd63b71461047b57600080fd5b806354c8a4f3116101d857806378a010b2116101a75780637d54534e1161018c5780637d54534e146103f157806383826b2b146104045780638926f54f1461041757600080fd5b806378a010b2146103d657806379ba5097146103e957600080fd5b806354c8a4f31461037f57806366320087146103925780636cfd1553146103a55780636d3d1a58146103b857600080fd5b806321df0da71161021457806321df0da7146102ab578063240028e8146102f2578063390775371461033f578063432a6ba31461036157600080fd5b806301ffc9a7146102465780630a2fd4931461026e5780630a861f2a1461028e578063181f5a77146102a3575b600080fd5b610259610254366004613691565b61063c565b60405190151581526020015b60405180910390f35b61028161027c3660046136f0565b610698565b6040516102659190613779565b6102a161029c36600461378c565b610748565b005b6102816108f9565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102596103003660046137d2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61035261034d3660046137ef565b610915565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a161038d366004613877565b610a3e565b6102a16103a03660046138e3565b610ab9565b6102a16103b33660046137d2565b610b45565b60085473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16103e436600461390f565b610b94565b6102a1610d03565b6102a16103ff3660046137d2565b610e00565b610259610412366004613992565b610e4f565b6102596104253660046136f0565b610f1c565b60005473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16104563660046137d2565b610f33565b61046e6104693660046139c9565b610fc2565b6040516102659190613a04565b61048361108b565b6040516102659190613a64565b6102cd61049e3660046136f0565b503090565b6104b66104b13660046136f0565b61109c565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102cd565b61028161053e3660046136f0565b611171565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16105773660046137d2565b61119c565b610584611270565b6040516102659190613abe565b6104b661059f3660046136f0565b611328565b6102a16105b2366004613c75565b6113fa565b6102a16105c5366004613cba565b611483565b7f00000000000000000000000000000000000000000000000000000000000000006102cd565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a161062436600461378c565b611909565b6102a16106373660046137d2565b611a25565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d40566000000000000000000000000000000000000000000000000000000001480610692575061069282611a39565b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106c390613cfc565b80601f01602080910402602001604051908101604052809291908181526020018280546106ef90613cfc565b801561073c5780601f106107115761010080835404028352916020019161073c565b820191906000526020600020905b81548152906001019060200180831161071f57829003601f168201915b50505050509050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146107a0576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190613d4f565b1015610888576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108c973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611b1d565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040518060600160405280602681526020016147466026913981565b60408051602081019091526000815261093561093083613e04565b611bf1565b60095473ffffffffffffffffffffffffffffffffffffffff1661099c5761099773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016336060850135611b1d565b6109ad565b6109ad6109a883613e04565b611e22565b6109bd60608301604084016137d2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f528460600135604051610a1f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a46611ebb565b610ab384848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f3e92505050565b50505050565b610ac1611ebb565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610b2957600080fd5b505af1158015610b3d573d6000803e3d6000fd5b505050505050565b610b4d611ebb565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b9c611ebb565b610ba583610f1c565b610be7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b67ffffffffffffffff831660009081526007602052604081206004018054610c0e90613cfc565b80601f0160208091040260200160405190810160405280929190818152602001828054610c3a90613cfc565b8015610c875780601f10610c5c57610100808354040283529160200191610c87565b820191906000526020600020905b815481529060010190602001808311610c6a57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cb6838583613f41565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610cf59392919061405b565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610797565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e08611ebb565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610f155750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610ef1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1591906140bf565b9392505050565b6000610692600567ffffffffffffffff84166120f4565b610f3b611ebb565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610fe7610fe2836140dc565b61210c565b60095473ffffffffffffffffffffffffffffffffffffffff161561101657611016611011836140dc565b6122d6565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a2604051806040016040528061107084602001602081019061053e91906136f0565b81526040805160208181019092526000815291015292915050565b606061109760026123f0565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610692906123fd565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106c390613cfc565b6111a4611ebb565b73ffffffffffffffffffffffffffffffffffffffff81166111f1576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610fb6565b6060600061127e60056123f0565b90506000815167ffffffffffffffff81111561129c5761129c613b00565b6040519080825280602002602001820160405280156112c5578160200160208202803683370190505b50905060005b8251811015611321578281815181106112e6576112e661417e565b60200260200101518282815181106113005761130061417e565b67ffffffffffffffff909216602092830291909101909101526001016112cb565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610692906123fd565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061143a575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611473576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b61147e8383836124af565b505050565b61148b611ebb565b60005b8181101561147e5760008383838181106114aa576114aa61417e565b90506020028101906114bc91906141ad565b6114c5906141eb565b90506114da8160800151826020015115612599565b6114ed8160a00151826020015115612599565b8060200151156117e957805161150f9060059067ffffffffffffffff166126d2565b6115545780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b60408101515115806115695750606081015151155b156115a0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c17909116961515029590951790985590810151940151938116931690910291909117600382015591519091906004820190611781908261429f565b5060608201516005820190611796908261429f565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506117dc94939291906143b9565b60405180910390a1611900565b80516118019060059067ffffffffffffffff166126de565b6118465780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118af6004830182613643565b6118bd600583016000613643565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161148e565b7f0000000000000000000000000000000000000000000000000000000000000000611960576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff1633146119b3576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b6119f573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846126ea565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611a2d611ebb565b611a3681612748565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611acc57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261147e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261283d565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611c865760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d5891906140bf565b15611d8f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d9c8160200151612949565b6000611dab8260200151610698565b9050805160001480611dcf575080805190602001208260a001518051906020012014155b15611e0c578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107979190613779565b611e1e82602001518360600151612a6f565b5050565b6009548151606083015160208401516040517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90941693638627fad693611e869390923392600401614452565b600060405180830381600087803b158015611ea057600080fd5b505af1158015611eb4573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611f3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610797565b565b7f0000000000000000000000000000000000000000000000000000000000000000611f95576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561202b576000838281518110611fb557611fb561417e565b60200260200101519050611fd3816002612ab690919063ffffffff16565b156120225760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f98565b5060005b815181101561147e57600082828151811061204c5761204c61417e565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361209057506120ec565b61209b600282612ad8565b156120ea5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161202f565b60008181526001830160205260408120541515610f15565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121a15760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561224f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227391906140bf565b156122aa576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122b78160400151612afa565b6122c48160200151612b79565b611a3681602001518260600151612cc7565b60095460608201516123239173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611b1d565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9095169463968754459461238b949392916004016144b3565b6000604051808303816000875af11580156123aa573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e1e9190810190614513565b60606000610f1583612d0b565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261248b82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261246f91906145b0565b85608001516fffffffffffffffffffffffffffffffff16612d66565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6124b883610f1c565b6124fa576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b612505826000612599565b67ffffffffffffffff831660009081526007602052604090206125289083612d90565b612533816000612599565b67ffffffffffffffff831660009081526007602052604090206125599060020182612d90565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161258c939291906145c3565b60405180910390a1505050565b8151156126605781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806125ef575060408201516fffffffffffffffffffffffffffffffff16155b1561262857816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107979190614646565b8015611e1e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612699575060208201516fffffffffffffffffffffffffffffffff1615155b15611e1e57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107979190614646565b6000610f158383612f32565b6000610f158383612f81565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ab39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611b6f565b3373ffffffffffffffffffffffffffffffffffffffff8216036127c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610797565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061289f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130749092919063ffffffff16565b80519091501561147e57808060200190518101906128bd91906140bf565b61147e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610797565b61295281610f1c565b612994576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612a13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a3791906140bf565b611a36576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e1e90600201827f0000000000000000000000000000000000000000000000000000000000000000613083565b6000610f158373ffffffffffffffffffffffffffffffffffffffff8416612f81565b6000610f158373ffffffffffffffffffffffffffffffffffffffff8416612f32565b7f000000000000000000000000000000000000000000000000000000000000000015611a3657612b2b600282613406565b611a36576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610797565b612b8281610f1c565b612bc4576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c619190614682565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a36576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e1e90827f0000000000000000000000000000000000000000000000000000000000000000613083565b60608160000180548060200260200160405190810160405280929190818152602001828054801561073c57602002820191906000526020600020905b815481526020019060010190808311612d475750505050509050919050565b6000612d8585612d76848661469f565b612d8090876146b6565b613435565b90505b949350505050565b8154600090612db990700100000000000000000000000000000000900463ffffffff16426145b0565b90508015612e5b5760018301548354612e01916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612d66565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612e81916fffffffffffffffffffffffffffffffff9081169116613435565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061258c908490614646565b6000818152600183016020526040812054612f7957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610692565b506000610692565b6000818152600183016020526040812054801561306a576000612fa56001836145b0565b8554909150600090612fb9906001906145b0565b905081811461301e576000866000018281548110612fd957612fd961417e565b9060005260206000200154905080876000018481548110612ffc57612ffc61417e565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061302f5761302f6146c9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610692565b6000915050610692565b6060612d88848460008561344b565b825474010000000000000000000000000000000000000000900460ff1615806130aa575081155b156130b457505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906130fa90700100000000000000000000000000000000900463ffffffff16426145b0565b905080156131ba578183111561313c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546131769083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612d66565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156132715773ffffffffffffffffffffffffffffffffffffffff8416613219576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610797565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610797565b848310156133845760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906132b590826145b0565b6132bf878a6145b0565b6132c991906146b6565b6132d391906146f8565b905073ffffffffffffffffffffffffffffffffffffffff861661332c576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610797565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610797565b61338e85846145b0565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610f15565b60008183106134445781610f15565b5090919050565b6060824710156134dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610797565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516135069190614733565b60006040518083038185875af1925050503d8060008114613543576040519150601f19603f3d011682016040523d82523d6000602084013e613548565b606091505b509150915061355987838387613564565b979650505050505050565b606083156135fa5782516000036135f35773ffffffffffffffffffffffffffffffffffffffff85163b6135f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610797565b5081612d88565b612d88838381511561360f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107979190613779565b50805461364f90613cfc565b6000825580601f1061365f575050565b601f016020900490600052602060002090810190611a3691905b8082111561368d5760008155600101613679565b5090565b6000602082840312156136a357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f1557600080fd5b803567ffffffffffffffff811681146136eb57600080fd5b919050565b60006020828403121561370257600080fd5b610f15826136d3565b60005b8381101561372657818101518382015260200161370e565b50506000910152565b6000815180845261374781602086016020860161370b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f15602083018461372f565b60006020828403121561379e57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a3657600080fd5b80356136eb816137a5565b6000602082840312156137e457600080fd5b8135610f15816137a5565b60006020828403121561380157600080fd5b813567ffffffffffffffff81111561381857600080fd5b82016101008185031215610f1557600080fd5b60008083601f84011261383d57600080fd5b50813567ffffffffffffffff81111561385557600080fd5b6020830191508360208260051b850101111561387057600080fd5b9250929050565b6000806000806040858703121561388d57600080fd5b843567ffffffffffffffff808211156138a557600080fd5b6138b18883890161382b565b909650945060208701359150808211156138ca57600080fd5b506138d78782880161382b565b95989497509550505050565b600080604083850312156138f657600080fd5b8235613901816137a5565b946020939093013593505050565b60008060006040848603121561392457600080fd5b61392d846136d3565b9250602084013567ffffffffffffffff8082111561394a57600080fd5b818601915086601f83011261395e57600080fd5b81358181111561396d57600080fd5b87602082850101111561397f57600080fd5b6020830194508093505050509250925092565b600080604083850312156139a557600080fd5b6139ae836136d3565b915060208301356139be816137a5565b809150509250929050565b6000602082840312156139db57600080fd5b813567ffffffffffffffff8111156139f257600080fd5b820160a08185031215610f1557600080fd5b602081526000825160406020840152613a20606084018261372f565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613a5b828261372f565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ab257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613a80565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ab257835167ffffffffffffffff1683529284019291840191600101613ada565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613b5357613b53613b00565b60405290565b60405160c0810167ffffffffffffffff81118282101715613b5357613b53613b00565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bc357613bc3613b00565b604052919050565b8015158114611a3657600080fd5b80356136eb81613bcb565b80356fffffffffffffffffffffffffffffffff811681146136eb57600080fd5b600060608284031215613c1657600080fd5b6040516060810181811067ffffffffffffffff82111715613c3957613c39613b00565b6040529050808235613c4a81613bcb565b8152613c5860208401613be4565b6020820152613c6960408401613be4565b60408201525092915050565b600080600060e08486031215613c8a57600080fd5b613c93846136d3565b9250613ca28560208601613c04565b9150613cb18560808601613c04565b90509250925092565b60008060208385031215613ccd57600080fd5b823567ffffffffffffffff811115613ce457600080fd5b613cf08582860161382b565b90969095509350505050565b600181811c90821680613d1057607f821691505b602082108103613d49577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613d6157600080fd5b5051919050565b600067ffffffffffffffff821115613d8257613d82613b00565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613dbf57600080fd5b8135613dd2613dcd82613d68565b613b7c565b818152846020838601011115613de757600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613e1757600080fd5b613e1f613b2f565b823567ffffffffffffffff80821115613e3757600080fd5b613e4336838701613dae565b8352613e51602086016136d3565b6020840152613e62604086016137c7565b604084015260608501356060840152613e7d608086016137c7565b608084015260a0850135915080821115613e9657600080fd5b613ea236838701613dae565b60a084015260c0850135915080821115613ebb57600080fd5b613ec736838701613dae565b60c084015260e0850135915080821115613ee057600080fd5b50613eed36828601613dae565b60e08301525092915050565b601f82111561147e576000816000526020600020601f850160051c81016020861015613f225750805b601f850160051c820191505b81811015610b3d57828155600101613f2e565b67ffffffffffffffff831115613f5957613f59613b00565b613f6d83613f678354613cfc565b83613ef9565b6000601f841160018114613fbf5760008515613f895750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611eb4565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561400e5786850135825560209485019460019092019101613fee565b5086821015614049577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b60408152600061406e604083018661372f565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b6000602082840312156140d157600080fd5b8151610f1581613bcb565b600060a082360312156140ee57600080fd5b60405160a0810167ffffffffffffffff828210818311171561411257614112613b00565b81604052843591508082111561412757600080fd5b5061413436828601613dae565b825250614143602084016136d3565b60208201526040830135614156816137a5565b6040820152606083810135908201526080830135614173816137a5565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126141e157600080fd5b9190910192915050565b600061014082360312156141fe57600080fd5b614206613b59565b61420f836136d3565b815261421d60208401613bd9565b6020820152604083013567ffffffffffffffff8082111561423d57600080fd5b61424936838701613dae565b6040840152606085013591508082111561426257600080fd5b5061426f36828601613dae565b6060830152506142823660808501613c04565b60808201526142943660e08501613c04565b60a082015292915050565b815167ffffffffffffffff8111156142b9576142b9613b00565b6142cd816142c78454613cfc565b84613ef9565b602080601f83116001811461432057600084156142ea5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610b3d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561436d5788860151825594840194600190910190840161434e565b50858210156143a957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526143dd8184018761372f565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061441b9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613a5b565b60a08152600061446560a083018761372f565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a0602082015260006144e260a083018661372f565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561452557600080fd5b815167ffffffffffffffff81111561453c57600080fd5b8201601f8101841361454d57600080fd5b805161455b613dcd82613d68565b81815285602083850101111561457057600080fd5b613a5b82602083016020860161370b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561069257610692614581565b67ffffffffffffffff8416815260e0810161460f60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612d88565b6060810161069282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561469457600080fd5b8151610f15816137a5565b808202811582820484141761069257610692614581565b8082018082111561069257610692614581565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261472e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082516141e181846020870161370b56fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004fbb38038062004fbb83398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508181146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516148336200078860003960008181610545015261190b0152600081816105f201528181611ffa0152612bb60152600081816105cc01528181611cd801526122ad0152600081816102ad01528181610302015281816107d0015281816108a20152818161096c015281816119cd01528181611bf801528181611ef3015281816121cd015281816123b301528181612b4c0152612da101526148336000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e13146105f0578063eb521a4c14610616578063f2fde38b1461062957600080fd5b8063db6327dc146105b7578063dc0bd971146105ca57600080fd5b8063c0d7865514610569578063c4bffe2b1461057c578063c75eea9c14610591578063cf7401f3146105a457600080fd5b8063a8d87a3b11610114578063b0f479a1116100f9578063b0f479a114610512578063b794658014610530578063bb98546b1461054357600080fd5b8063a8d87a3b14610490578063af58d59f146104a357600080fd5b80638da5cb5b1461042a5780639766b932146104485780639a4575b91461045b578063a7cd63b71461047b57600080fd5b806354c8a4f3116101d857806378a010b2116101a75780637d54534e1161018c5780637d54534e146103f157806383826b2b146104045780638926f54f1461041757600080fd5b806378a010b2146103d657806379ba5097146103e957600080fd5b806354c8a4f31461037f57806366320087146103925780636cfd1553146103a55780636d3d1a58146103b857600080fd5b806321df0da71161021457806321df0da7146102ab578063240028e8146102f2578063390775371461033f578063432a6ba31461036157600080fd5b806301ffc9a7146102465780630a2fd4931461026e5780630a861f2a1461028e578063181f5a77146102a3575b600080fd5b61025961025436600461374b565b61063c565b60405190151581526020015b60405180910390f35b61028161027c3660046137aa565b610698565b6040516102659190613833565b6102a161029c366004613846565b610748565b005b6102816108f9565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b61025961030036600461388c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61035261034d3660046138a9565b610915565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a161038d366004613931565b610a3e565b6102a16103a036600461399d565b610ab9565b6102a16103b336600461388c565b610b45565b60085473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16103e43660046139c9565b610b94565b6102a1610d03565b6102a16103ff36600461388c565b610e00565b610259610412366004613a4c565b610e4f565b6102596104253660046137aa565b610f1c565b60005473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a161045636600461388c565b610f33565b61046e610469366004613a83565b610fc2565b6040516102659190613abe565b61048361108b565b6040516102659190613b1e565b6102cd61049e3660046137aa565b503090565b6104b66104b13660046137aa565b61109c565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102cd565b61028161053e3660046137aa565b611171565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a161057736600461388c565b61119c565b610584611270565b6040516102659190613b78565b6104b661059f3660046137aa565b611328565b6102a16105b2366004613d2f565b6113fa565b6102a16105c5366004613d74565b611483565b7f00000000000000000000000000000000000000000000000000000000000000006102cd565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a1610624366004613846565b611909565b6102a161063736600461388c565b611a25565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d40566000000000000000000000000000000000000000000000000000000001480610692575061069282611a39565b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106c390613db6565b80601f01602080910402602001604051908101604052809291908181526020018280546106ef90613db6565b801561073c5780601f106107115761010080835404028352916020019161073c565b820191906000526020600020905b81548152906001019060200180831161071f57829003601f168201915b50505050509050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146107a0576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190613e09565b1015610888576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108c973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611b1d565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040518060600160405280602681526020016148016026913981565b60408051602081019091526000815261093561093083613ebe565b611bf1565b60095473ffffffffffffffffffffffffffffffffffffffff1661099c5761099773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016336060850135611b1d565b6109ad565b6109ad6109a883613ebe565b611e22565b6109bd606083016040840161388c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f528460600135604051610a1f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a46611f75565b610ab384848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ff892505050565b50505050565b610ac1611f75565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610b2957600080fd5b505af1158015610b3d573d6000803e3d6000fd5b505050505050565b610b4d611f75565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b9c611f75565b610ba583610f1c565b610be7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b67ffffffffffffffff831660009081526007602052604081206004018054610c0e90613db6565b80601f0160208091040260200160405190810160405280929190818152602001828054610c3a90613db6565b8015610c875780601f10610c5c57610100808354040283529160200191610c87565b820191906000526020600020905b815481529060010190602001808311610c6a57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cb6838583613ffb565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610cf593929190614116565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610797565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e08611f75565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610f155750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610ef1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f15919061417a565b9392505050565b6000610692600567ffffffffffffffff84166121ae565b610f3b611f75565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610fe7610fe283614197565b6121c6565b60095473ffffffffffffffffffffffffffffffffffffffff16156110165761101661101183614197565b612390565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a2604051806040016040528061107084602001602081019061053e91906137aa565b81526040805160208181019092526000815291015292915050565b606061109760026124aa565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610692906124b7565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106c390613db6565b6111a4611f75565b73ffffffffffffffffffffffffffffffffffffffff81166111f1576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610fb6565b6060600061127e60056124aa565b90506000815167ffffffffffffffff81111561129c5761129c613bba565b6040519080825280602002602001820160405280156112c5578160200160208202803683370190505b50905060005b8251811015611321578281815181106112e6576112e6614239565b602002602001015182828151811061130057611300614239565b67ffffffffffffffff909216602092830291909101909101526001016112cb565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610692906124b7565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061143a575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611473576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b61147e838383612569565b505050565b61148b611f75565b60005b8181101561147e5760008383838181106114aa576114aa614239565b90506020028101906114bc9190614268565b6114c5906142a6565b90506114da8160800151826020015115612653565b6114ed8160a00151826020015115612653565b8060200151156117e957805161150f9060059067ffffffffffffffff1661278c565b6115545780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b60408101515115806115695750606081015151155b156115a0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c17909116961515029590951790985590810151940151938116931690910291909117600382015591519091906004820190611781908261435a565b5060608201516005820190611796908261435a565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506117dc9493929190614474565b60405180910390a1611900565b80516118019060059067ffffffffffffffff16612798565b6118465780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118af60048301826136fd565b6118bd6005830160006136fd565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161148e565b7f0000000000000000000000000000000000000000000000000000000000000000611960576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff1633146119b3576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b6119f573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846127a4565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611a2d611f75565b611a3681612802565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611acc57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261147e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526128f7565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611c865760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d58919061417a565b15611d8f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d9c8160200151612a03565b6000611dab8260200151610698565b9050805160001480611dcf575080805190602001208260a001518051906020012014155b15611e0c578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107979190613833565b611e1e82602001518360600151612b29565b5050565b6009548151606083015160208401516040517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90941693638627fad693611e86939092309260040161450d565b600060405180830381600087803b158015611ea057600080fd5b505af1158015611eb4573d6000803e3d6000fd5b5050505060608101516040517f095ea7b300000000000000000000000000000000000000000000000000000000815233600482015260248101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063095ea7b3906044016020604051808303816000875af1158015611f51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1e919061417a565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ff6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610797565b565b7f000000000000000000000000000000000000000000000000000000000000000061204f576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156120e557600083828151811061206f5761206f614239565b6020026020010151905061208d816002612b7090919063ffffffff16565b156120dc5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101612052565b5060005b815181101561147e57600082828151811061210657612106614239565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361214a57506121a6565b612155600282612b92565b156121a45760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016120e9565b60008181526001830160205260408120541515610f15565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461225b5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612309573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232d919061417a565b15612364576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123718160400151612bb4565b61237e8160200151612c33565b611a3681602001518260600151612d81565b60095460608201516123dd9173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611b1d565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909516946396875445946124459493929160040161456e565b6000604051808303816000875af1158015612464573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e1e91908101906145ce565b60606000610f1583612dc5565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261254582606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642612529919061466b565b85608001516fffffffffffffffffffffffffffffffff16612e20565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61257283610f1c565b6125b4576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b6125bf826000612653565b67ffffffffffffffff831660009081526007602052604090206125e29083612e4a565b6125ed816000612653565b67ffffffffffffffff831660009081526007602052604090206126139060020182612e4a565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516126469392919061467e565b60405180910390a1505050565b81511561271a5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806126a9575060408201516fffffffffffffffffffffffffffffffff16155b156126e257816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107979190614701565b8015611e1e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612753575060208201516fffffffffffffffffffffffffffffffff1615155b15611e1e57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107979190614701565b6000610f158383612fec565b6000610f15838361303b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ab39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611b6f565b3373ffffffffffffffffffffffffffffffffffffffff821603612881576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610797565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612959826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661312e9092919063ffffffff16565b80519091501561147e5780806020019051810190612977919061417a565b61147e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610797565b612a0c81610f1c565b612a4e576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612acd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612af1919061417a565b611a36576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e1e90600201827f000000000000000000000000000000000000000000000000000000000000000061313d565b6000610f158373ffffffffffffffffffffffffffffffffffffffff841661303b565b6000610f158373ffffffffffffffffffffffffffffffffffffffff8416612fec565b7f000000000000000000000000000000000000000000000000000000000000000015611a3657612be56002826134c0565b611a36576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610797565b612c3c81610f1c565b612c7e576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612cf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1b919061473d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a36576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e1e90827f000000000000000000000000000000000000000000000000000000000000000061313d565b60608160000180548060200260200160405190810160405280929190818152602001828054801561073c57602002820191906000526020600020905b815481526020019060010190808311612e015750505050509050919050565b6000612e3f85612e30848661475a565b612e3a9087614771565b6134ef565b90505b949350505050565b8154600090612e7390700100000000000000000000000000000000900463ffffffff164261466b565b90508015612f155760018301548354612ebb916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e20565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612f3b916fffffffffffffffffffffffffffffffff90811691166134ef565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612646908490614701565b600081815260018301602052604081205461303357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610692565b506000610692565b6000818152600183016020526040812054801561312457600061305f60018361466b565b85549091506000906130739060019061466b565b90508181146130d857600086600001828154811061309357613093614239565b90600052602060002001549050808760000184815481106130b6576130b6614239565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806130e9576130e9614784565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610692565b6000915050610692565b6060612e428484600085613505565b825474010000000000000000000000000000000000000000900460ff161580613164575081155b1561316e57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906131b490700100000000000000000000000000000000900463ffffffff164261466b565b9050801561327457818311156131f6576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546132309083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e20565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561332b5773ffffffffffffffffffffffffffffffffffffffff84166132d3576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610797565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610797565b8483101561343e5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061336f908261466b565b613379878a61466b565b6133839190614771565b61338d91906147b3565b905073ffffffffffffffffffffffffffffffffffffffff86166133e6576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610797565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610797565b613448858461466b565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610f15565b60008183106134fe5781610f15565b5090919050565b606082471015613597576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610797565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516135c091906147ee565b60006040518083038185875af1925050503d80600081146135fd576040519150601f19603f3d011682016040523d82523d6000602084013e613602565b606091505b50915091506136138783838761361e565b979650505050505050565b606083156136b45782516000036136ad5773ffffffffffffffffffffffffffffffffffffffff85163b6136ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610797565b5081612e42565b612e4283838151156136c95781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107979190613833565b50805461370990613db6565b6000825580601f10613719575050565b601f016020900490600052602060002090810190611a3691905b808211156137475760008155600101613733565b5090565b60006020828403121561375d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f1557600080fd5b803567ffffffffffffffff811681146137a557600080fd5b919050565b6000602082840312156137bc57600080fd5b610f158261378d565b60005b838110156137e05781810151838201526020016137c8565b50506000910152565b600081518084526138018160208601602086016137c5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f1560208301846137e9565b60006020828403121561385857600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a3657600080fd5b80356137a58161385f565b60006020828403121561389e57600080fd5b8135610f158161385f565b6000602082840312156138bb57600080fd5b813567ffffffffffffffff8111156138d257600080fd5b82016101008185031215610f1557600080fd5b60008083601f8401126138f757600080fd5b50813567ffffffffffffffff81111561390f57600080fd5b6020830191508360208260051b850101111561392a57600080fd5b9250929050565b6000806000806040858703121561394757600080fd5b843567ffffffffffffffff8082111561395f57600080fd5b61396b888389016138e5565b9096509450602087013591508082111561398457600080fd5b50613991878288016138e5565b95989497509550505050565b600080604083850312156139b057600080fd5b82356139bb8161385f565b946020939093013593505050565b6000806000604084860312156139de57600080fd5b6139e78461378d565b9250602084013567ffffffffffffffff80821115613a0457600080fd5b818601915086601f830112613a1857600080fd5b813581811115613a2757600080fd5b876020828501011115613a3957600080fd5b6020830194508093505050509250925092565b60008060408385031215613a5f57600080fd5b613a688361378d565b91506020830135613a788161385f565b809150509250929050565b600060208284031215613a9557600080fd5b813567ffffffffffffffff811115613aac57600080fd5b820160a08185031215610f1557600080fd5b602081526000825160406020840152613ada60608401826137e9565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613b1582826137e9565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613b6c57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613b3a565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613b6c57835167ffffffffffffffff1683529284019291840191600101613b94565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613c0d57613c0d613bba565b60405290565b60405160c0810167ffffffffffffffff81118282101715613c0d57613c0d613bba565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613c7d57613c7d613bba565b604052919050565b8015158114611a3657600080fd5b80356137a581613c85565b80356fffffffffffffffffffffffffffffffff811681146137a557600080fd5b600060608284031215613cd057600080fd5b6040516060810181811067ffffffffffffffff82111715613cf357613cf3613bba565b6040529050808235613d0481613c85565b8152613d1260208401613c9e565b6020820152613d2360408401613c9e565b60408201525092915050565b600080600060e08486031215613d4457600080fd5b613d4d8461378d565b9250613d5c8560208601613cbe565b9150613d6b8560808601613cbe565b90509250925092565b60008060208385031215613d8757600080fd5b823567ffffffffffffffff811115613d9e57600080fd5b613daa858286016138e5565b90969095509350505050565b600181811c90821680613dca57607f821691505b602082108103613e03577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613e1b57600080fd5b5051919050565b600067ffffffffffffffff821115613e3c57613e3c613bba565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613e7957600080fd5b8135613e8c613e8782613e22565b613c36565b818152846020838601011115613ea157600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613ed157600080fd5b613ed9613be9565b823567ffffffffffffffff80821115613ef157600080fd5b613efd36838701613e68565b8352613f0b6020860161378d565b6020840152613f1c60408601613881565b604084015260608501356060840152613f3760808601613881565b608084015260a0850135915080821115613f5057600080fd5b613f5c36838701613e68565b60a084015260c0850135915080821115613f7557600080fd5b613f8136838701613e68565b60c084015260e0850135915080821115613f9a57600080fd5b50613fa736828601613e68565b60e08301525092915050565b601f82111561147e576000816000526020600020601f850160051c81016020861015613fdc5750805b601f850160051c820191505b81811015610b3d57828155600101613fe8565b67ffffffffffffffff83111561401357614013613bba565b614027836140218354613db6565b83613fb3565b6000601f84116001811461407957600085156140435750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561410f565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140c857868501358255602094850194600190920191016140a8565b5086821015614103577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60408152600061412960408301866137e9565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b60006020828403121561418c57600080fd5b8151610f1581613c85565b600060a082360312156141a957600080fd5b60405160a0810167ffffffffffffffff82821081831117156141cd576141cd613bba565b8160405284359150808211156141e257600080fd5b506141ef36828601613e68565b8252506141fe6020840161378d565b602082015260408301356142118161385f565b604082015260608381013590820152608083013561422e8161385f565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261429c57600080fd5b9190910192915050565b600061014082360312156142b957600080fd5b6142c1613c13565b6142ca8361378d565b81526142d860208401613c93565b6020820152604083013567ffffffffffffffff808211156142f857600080fd5b61430436838701613e68565b6040840152606085013591508082111561431d57600080fd5b5061432a36828601613e68565b60608301525061433d3660808501613cbe565b608082015261434f3660e08501613cbe565b60a082015292915050565b815167ffffffffffffffff81111561437457614374613bba565b614388816143828454613db6565b84613fb3565b602080601f8311600181146143db57600084156143a55750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610b3d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561442857888601518255948401946001909101908401614409565b508582101561446457878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152614498818401876137e9565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506144d69050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613b15565b60a08152600061452060a08301876137e9565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a06020820152600061459d60a08301866137e9565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b6000602082840312156145e057600080fd5b815167ffffffffffffffff8111156145f757600080fd5b8201601f8101841361460857600080fd5b8051614616613e8782613e22565b81815285602083850101111561462b57600080fd5b613b158260208301602086016137c5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106925761069261463c565b67ffffffffffffffff8416815260e081016146ca60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612e42565b6060810161069282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561474f57600080fd5b8151610f158161385f565b80820281158282048414176106925761069261463c565b808201808211156106925761069261463c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826147e9577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000825161429c8184602087016137c556fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", } var LockReleaseTokenPoolAndProxyABI = LockReleaseTokenPoolAndProxyMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go index a4e4f9de70..35747dd583 100644 --- a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go +++ b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go @@ -96,7 +96,7 @@ type USDCTokenPoolDomainUpdate struct { var USDCTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b506040516200562038038062005620833981016040819052620000359162000b4c565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200041b565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016957604080516000815260208101909152620001699084620004c6565b5050506001600160a01b038616905062000196576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fd919062000c72565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000240573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000266919062000c99565b905063ffffffff81161562000297576040516334697c6b60e11b815263ffffffff8216600482015260240162000087565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fe919062000c99565b905063ffffffff8116156200032f576040516316ba39c560e31b815263ffffffff8216600482015260240162000087565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa15801562000381573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a7919062000c99565b63ffffffff166101205260e051608051620003d1916001600160a01b039091169060001962000623565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000de6565b336001600160a01b03821603620004755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620004e7576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005725760008382815181106200050b576200050b62000cc1565b602090810291909101015190506200052560028262000709565b1562000568576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620004ea565b5060005b81518110156200061e57600082828151811062000597576200059762000cc1565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005c3575062000615565b620005d060028262000729565b1562000613576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000576565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200069b919062000cd7565b620006a7919062000d07565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000703918691906200074016565b50505050565b600062000720836001600160a01b03841662000811565b90505b92915050565b600062000720836001600160a01b03841662000915565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200078f906001600160a01b03851690849062000967565b8051909150156200061e5780806020019051810190620007b0919062000d1d565b6200061e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000087565b600081815260018301602052604081205480156200090a5760006200083860018362000d41565b85549091506000906200084e9060019062000d41565b9050818114620008ba57600086600001828154811062000872576200087262000cc1565b906000526020600020015490508087600001848154811062000898576200089862000cc1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620008ce57620008ce62000d57565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000723565b600091505062000723565b60008181526001830160205260408120546200095e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000723565b50600062000723565b606062000978848460008562000980565b949350505050565b606082471015620009e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000087565b600080866001600160a01b0316858760405162000a01919062000d93565b60006040518083038185875af1925050503d806000811462000a40576040519150601f19603f3d011682016040523d82523d6000602084013e62000a45565b606091505b50909250905062000a598783838762000a64565b979650505050505050565b6060831562000ad857825160000362000ad0576001600160a01b0385163b62000ad05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000087565b508162000978565b62000978838381511562000aef5781518083602001fd5b8060405162461bcd60e51b815260040162000087919062000db1565b6001600160a01b038116811462000b2157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b478162000b0b565b919050565b600080600080600060a0868803121562000b6557600080fd5b855162000b728162000b0b565b8095505060208087015162000b878162000b0b565b60408801519095506001600160401b038082111562000ba557600080fd5b818901915089601f83011262000bba57600080fd5b81518181111562000bcf5762000bcf62000b24565b8060051b604051601f19603f8301168101818110858211171562000bf75762000bf762000b24565b60405291825284820192508381018501918c83111562000c1657600080fd5b938501935b8285101562000c3f5762000c2f8562000b3a565b8452938501939285019262000c1b565b80985050505050505062000c566060870162000b3a565b915062000c666080870162000b3a565b90509295509295909350565b60006020828403121562000c8557600080fd5b815162000c928162000b0b565b9392505050565b60006020828403121562000cac57600080fd5b815163ffffffff8116811462000c9257600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000cea57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000723576200072362000cf1565b60006020828403121562000d3057600080fd5b8151801515811462000c9257600080fd5b8181038181111562000723576200072362000cf1565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d8a57818101518382015260200162000d70565b50506000910152565b6000825162000da781846020870162000d6d565b9190910192915050565b602081526000825180602084015262000dd281604085016020870162000d6d565b601f01601f19169190910160400192915050565b60805160a05160c05160e051610100516101205161477a62000ea660003960008181610382015281816111ab01528181611e230152611e810152600081816106760152610a7801526000818161035b01526110bf01526000818161063a01528181611fab01526129f201526000818161057601528181611c21015261226101526000818161028f015281816102e401528181610b3e0152818161108c01528181611b41015281816121810152818161287c0152612bdd015261477a6000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80639a4575b91161010f578063c75eea9c116100a2578063dfadfa3511610071578063dfadfa351461059a578063e0351e1314610638578063f2fde38b1461065e578063fbf84dd71461067157600080fd5b8063c75eea9c1461053b578063cf7401f31461054e578063db6327dc14610561578063dc0bd9711461057457600080fd5b8063b0f479a1116100de578063b0f479a1146104e2578063b794658014610500578063c0d7865514610513578063c4bffe2b1461052657600080fd5b80639a4575b9146104365780639fdf13ff14610456578063a7cd63b71461045e578063af58d59f1461047357600080fd5b80636155cda01161018757806379ba50971161015657806379ba5097146103ea5780637d54534e146103f25780638926f54f146104055780638da5cb5b1461041857600080fd5b80636155cda0146103565780636b716b0d1461037d5780636d3d1a58146103b957806378a010b2146103d757600080fd5b806321df0da7116101c357806321df0da71461028d578063240028e8146102d4578063390775371461032157806354c8a4f31461034357600080fd5b806241d3c1146101f457806301ffc9a7146102095780630a2fd49314610231578063181f5a7714610251575b600080fd5b610207610202366004613587565b610698565b005b61021c6102173660046135fc565b610835565b60405190151581526020015b60405180910390f35b61024461023f366004613664565b61091a565b60405161022891906136ef565b6102446040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e342e300000000000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610228565b61021c6102e236600461372f565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61033461032f36600461374c565b6109ca565b60405190518152602001610228565b6102076103513660046137d4565b610bfc565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6103a47f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610228565b60085473ffffffffffffffffffffffffffffffffffffffff166102af565b6102076103e5366004613840565b610c77565b610207610de6565b61020761040036600461372f565b610ee3565b61021c610413366004613664565b610f32565b60005473ffffffffffffffffffffffffffffffffffffffff166102af565b6104496104443660046138c5565b610f49565b6040516102289190613900565b6103a4600081565b610466611225565b6040516102289190613960565b610486610481366004613664565b611236565b604051610228919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102af565b61024461050e366004613664565b61130b565b61020761052136600461372f565b611336565b61052e61140a565b60405161022891906139ba565b610486610549366004613664565b6114c2565b61020761055c366004613b45565b611594565b61020761056f366004613b8c565b61161d565b7f00000000000000000000000000000000000000000000000000000000000000006102af565b61060e6105a8366004613664565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600982529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610228565b7f000000000000000000000000000000000000000000000000000000000000000061021c565b61020761066c36600461372f565b611aa3565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6106a0611ab7565b60005b818110156107f75760008383838181106106bf576106bf613bce565b9050608002018036038101906106d59190613c11565b805190915015806106f25750604081015167ffffffffffffffff16155b1561076157604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600990925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169190931617929092179055016106a3565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee568282604051610829929190613c8b565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806108c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061091457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061094590613d12565b80601f016020809104026020016040519081016040528092919081815260200182805461097190613d12565b80156109be5780601f10610993576101008083540402835291602001916109be565b820191906000526020600020905b8154815290600101906020018083116109a157829003601f168201915b50505050509050919050565b6040805160208101909152600081526109ea6109e583613e10565b611b3a565b60006109f960c0840184613f05565b810190610a069190613f6a565b90506000610a1760e0850185613f05565b810190610a249190613fa9565b9050610a34816000015183611d6b565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aab9260040161403a565b6020604051808303816000875af1158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee919061405f565b610b24576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b6973ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016336060870135611f1c565b610b79606085016040860161372f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610bdb91815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b610c04611ab7565b610c7184848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611fa992505050565b50505050565b610c7f611ab7565b610c8883610f32565b610cca576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b67ffffffffffffffff831660009081526007602052604081206004018054610cf190613d12565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1d90613d12565b8015610d6a5780601f10610d3f57610100808354040283529160200191610d6a565b820191906000526020600020905b815481529060010190602001808311610d4d57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610d998385836140c4565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610dd8939291906141df565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610758565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610eeb611ab7565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610914600567ffffffffffffffff841661215f565b6040805180820190915260608082526020820152610f6e610f6983614243565b61217a565b6000600981610f836040860160208701613664565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff16151590820181905290915061102a57610feb6040840160208501613664565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b602081015181516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060860135600482015263ffffffff90921660248301526044820181905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091526000917f00000000000000000000000000000000000000000000000000000000000000009091169063f856ddb69060a4016020604051808303816000875af115801561110a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112e91906142e7565b6040516060860135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a2604051806040016040528061118b86602001602081019061050e9190613664565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529052949350505050565b60606112316002612344565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261091490612351565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061094590613d12565b61133e611ab7565b73ffffffffffffffffffffffffffffffffffffffff811661138b576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610829565b606060006114186005612344565b90506000815167ffffffffffffffff811115611436576114366139fc565b60405190808252806020026020018201604052801561145f578160200160208202803683370190505b50905060005b82518110156114bb5782818151811061148057611480613bce565b602002602001015182828151811061149a5761149a613bce565b67ffffffffffffffff90921660209283029190910190910152600101611465565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261091490612351565b60085473ffffffffffffffffffffffffffffffffffffffff1633148015906115d4575060005473ffffffffffffffffffffffffffffffffffffffff163314155b1561160d576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b611618838383612403565b505050565b611625611ab7565b60005b8181101561161857600083838381811061164457611644613bce565b90506020028101906116569190614304565b61165f90614342565b905061167481608001518260200151156124ed565b6116878160a001518260200151156124ed565b8060200151156119835780516116a99060059067ffffffffffffffff16612626565b6116ee5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b60408101515115806117035750606081015151155b1561173a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061191b90826143f6565b506060820151600582019061193090826143f6565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506119769493929190614510565b60405180910390a1611a9a565b805161199b9060059067ffffffffffffffff16612632565b6119e05780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611a496004830182613539565b611a57600583016000613539565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611628565b611aab611ab7565b611ab48161263e565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b38576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610758565b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611bcf5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611c7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca1919061405f565b15611cd8576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ce58160200151612733565b6000611cf4826020015161091a565b9050805160001480611d18575080805190602001208260a001518051906020012014155b15611d55578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161075891906136ef565b611d6782602001518360600151612859565b5050565b600482015163ffffffff811615611db6576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610758565b6008830151600c8401516014850151602085015163ffffffff808516911614611e215760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff91821660048201529084166024820152604401610758565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611eb6576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015283166024820152604401610758565b845167ffffffffffffffff828116911614611f145784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821660048201529082166024820152604401610758565b505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526116189084906128a0565b7f0000000000000000000000000000000000000000000000000000000000000000612000576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561209657600083828151811061202057612020613bce565b6020026020010151905061203e8160026129ac90919063ffffffff16565b1561208d5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101612003565b5060005b81518110156116185760008282815181106120b7576120b7613bce565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120fb5750612157565b6121066002826129ce565b156121555760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161209a565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461220f5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156122bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e1919061405f565b15612318576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61232581604001516129f0565b6123328160200151612a6f565b611ab481602001518260600151612bbd565b6060600061217383612c01565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526123df82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426123c391906145d8565b85608001516fffffffffffffffffffffffffffffffff16612c5c565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61240c83610f32565b61244e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b6124598260006124ed565b67ffffffffffffffff8316600090815260076020526040902061247c9083612c86565b6124878160006124ed565b67ffffffffffffffff831660009081526007602052604090206124ad9060020182612c86565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516124e0939291906145eb565b60405180910390a1505050565b8151156125b45781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612543575060408201516fffffffffffffffffffffffffffffffff16155b1561257c57816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610758919061466e565b8015611d67576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806125ed575060208201516fffffffffffffffffffffffffffffffff1615155b15611d6757816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610758919061466e565b60006121738383612e28565b60006121738383612e77565b3373ffffffffffffffffffffffffffffffffffffffff8216036126bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610758565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61273c81610f32565b61277e576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156127fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612821919061405f565b611ab4576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d6790600201827f0000000000000000000000000000000000000000000000000000000000000000612f6a565b6000612902826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166132ed9092919063ffffffff16565b8051909150156116185780806020019051810190612920919061405f565b611618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610758565b60006121738373ffffffffffffffffffffffffffffffffffffffff8416612e77565b60006121738373ffffffffffffffffffffffffffffffffffffffff8416612e28565b7f000000000000000000000000000000000000000000000000000000000000000015611ab457612a216002826132fc565b611ab4576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610758565b612a7881610f32565b612aba576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612b33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b5791906146aa565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611ab4576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d6790827f0000000000000000000000000000000000000000000000000000000000000000612f6a565b6060816000018054806020026020016040519081016040528092919081815260200182805480156109be57602002820191906000526020600020905b815481526020019060010190808311612c3d5750505050509050919050565b6000612c7b85612c6c84866146c7565b612c7690876146de565b61332b565b90505b949350505050565b8154600090612caf90700100000000000000000000000000000000900463ffffffff16426145d8565b90508015612d515760018301548354612cf7916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612c5c565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612d77916fffffffffffffffffffffffffffffffff908116911661332b565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906124e090849061466e565b6000818152600183016020526040812054612e6f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610914565b506000610914565b60008181526001830160205260408120548015612f60576000612e9b6001836145d8565b8554909150600090612eaf906001906145d8565b9050818114612f14576000866000018281548110612ecf57612ecf613bce565b9060005260206000200154905080876000018481548110612ef257612ef2613bce565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612f2557612f256146f1565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610914565b6000915050610914565b825474010000000000000000000000000000000000000000900460ff161580612f91575081155b15612f9b57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612fe190700100000000000000000000000000000000900463ffffffff16426145d8565b905080156130a15781831115613023576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461305d9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612c5c565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156131585773ffffffffffffffffffffffffffffffffffffffff8416613100576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610758565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610758565b8483101561326b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061319c90826145d8565b6131a6878a6145d8565b6131b091906146de565b6131ba9190614720565b905073ffffffffffffffffffffffffffffffffffffffff8616613213576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610758565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610758565b61327585846145d8565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6060612c7e8484600085613341565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515612173565b600081831061333a5781612173565b5090919050565b6060824710156133d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610758565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516133fc919061475b565b60006040518083038185875af1925050503d8060008114613439576040519150601f19603f3d011682016040523d82523d6000602084013e61343e565b606091505b509150915061344f8783838761345a565b979650505050505050565b606083156134f05782516000036134e95773ffffffffffffffffffffffffffffffffffffffff85163b6134e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610758565b5081612c7e565b612c7e83838151156135055781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075891906136ef565b50805461354590613d12565b6000825580601f10613555575050565b601f016020900490600052602060002090810190611ab491905b80821115613583576000815560010161356f565b5090565b6000806020838503121561359a57600080fd5b823567ffffffffffffffff808211156135b257600080fd5b818501915085601f8301126135c657600080fd5b8135818111156135d557600080fd5b8660208260071b85010111156135ea57600080fd5b60209290920196919550909350505050565b60006020828403121561360e57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461217357600080fd5b67ffffffffffffffff81168114611ab457600080fd5b803561365f8161363e565b919050565b60006020828403121561367657600080fd5b81356121738161363e565b60005b8381101561369c578181015183820152602001613684565b50506000910152565b600081518084526136bd816020860160208601613681565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061217360208301846136a5565b73ffffffffffffffffffffffffffffffffffffffff81168114611ab457600080fd5b803561365f81613702565b60006020828403121561374157600080fd5b813561217381613702565b60006020828403121561375e57600080fd5b813567ffffffffffffffff81111561377557600080fd5b8201610100818503121561217357600080fd5b60008083601f84011261379a57600080fd5b50813567ffffffffffffffff8111156137b257600080fd5b6020830191508360208260051b85010111156137cd57600080fd5b9250929050565b600080600080604085870312156137ea57600080fd5b843567ffffffffffffffff8082111561380257600080fd5b61380e88838901613788565b9096509450602087013591508082111561382757600080fd5b5061383487828801613788565b95989497509550505050565b60008060006040848603121561385557600080fd5b83356138608161363e565b9250602084013567ffffffffffffffff8082111561387d57600080fd5b818601915086601f83011261389157600080fd5b8135818111156138a057600080fd5b8760208285010111156138b257600080fd5b6020830194508093505050509250925092565b6000602082840312156138d757600080fd5b813567ffffffffffffffff8111156138ee57600080fd5b820160a0818503121561217357600080fd5b60208152600082516040602084015261391c60608401826136a5565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261395782826136a5565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156139ae57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161397c565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156139ae57835167ffffffffffffffff16835292840192918401916001016139d6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613a4f57613a4f6139fc565b60405290565b6040805190810167ffffffffffffffff81118282101715613a4f57613a4f6139fc565b60405160c0810167ffffffffffffffff81118282101715613a4f57613a4f6139fc565b8015158114611ab457600080fd5b803561365f81613a9b565b80356fffffffffffffffffffffffffffffffff8116811461365f57600080fd5b600060608284031215613ae657600080fd5b6040516060810181811067ffffffffffffffff82111715613b0957613b096139fc565b6040529050808235613b1a81613a9b565b8152613b2860208401613ab4565b6020820152613b3960408401613ab4565b60408201525092915050565b600080600060e08486031215613b5a57600080fd5b8335613b658161363e565b9250613b748560208601613ad4565b9150613b838560808601613ad4565b90509250925092565b60008060208385031215613b9f57600080fd5b823567ffffffffffffffff811115613bb657600080fd5b613bc285828601613788565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff8116811461365f57600080fd5b600060808284031215613c2357600080fd5b6040516080810181811067ffffffffffffffff82111715613c4657613c466139fc565b60405282358152613c5960208401613bfd565b60208201526040830135613c6c8161363e565b60408201526060830135613c7f81613a9b565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613d05578135835263ffffffff613cbd868401613bfd565b168584015283820135613ccf8161363e565b67ffffffffffffffff1683850152606082810135613cec81613a9b565b1515908401526080928301929190910190600101613ca1565b5090979650505050505050565b600181811c90821680613d2657607f821691505b602082108103613d5f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f830112613d7657600080fd5b813567ffffffffffffffff80821115613d9157613d916139fc565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613dd757613dd76139fc565b81604052838152866020858801011115613df057600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613e2357600080fd5b613e2b613a2b565b823567ffffffffffffffff80821115613e4357600080fd5b613e4f36838701613d65565b8352613e5d60208601613654565b6020840152613e6e60408601613724565b604084015260608501356060840152613e8960808601613724565b608084015260a0850135915080821115613ea257600080fd5b613eae36838701613d65565b60a084015260c0850135915080821115613ec757600080fd5b613ed336838701613d65565b60c084015260e0850135915080821115613eec57600080fd5b50613ef936828601613d65565b60e08301525092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f3a57600080fd5b83018035915067ffffffffffffffff821115613f5557600080fd5b6020019150368190038213156137cd57600080fd5b600060408284031215613f7c57600080fd5b613f84613a55565b8235613f8f8161363e565b8152613f9d60208401613bfd565b60208201529392505050565b600060208284031215613fbb57600080fd5b813567ffffffffffffffff80821115613fd357600080fd5b9083019060408286031215613fe757600080fd5b613fef613a55565b823582811115613ffe57600080fd5b61400a87828601613d65565b82525060208301358281111561401f57600080fd5b61402b87828601613d65565b60208301525095945050505050565b60408152600061404d60408301856136a5565b828103602084015261395781856136a5565b60006020828403121561407157600080fd5b815161217381613a9b565b601f821115611618576000816000526020600020601f850160051c810160208610156140a55750805b601f850160051c820191505b81811015611f14578281556001016140b1565b67ffffffffffffffff8311156140dc576140dc6139fc565b6140f0836140ea8354613d12565b8361407c565b6000601f841160018114614142576000851561410c5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556141d8565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156141915786850135825560209485019460019092019101614171565b50868210156141cc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b6040815260006141f260408301866136a5565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561425557600080fd5b60405160a0810167ffffffffffffffff8282108183111715614279576142796139fc565b81604052843591508082111561428e57600080fd5b5061429b36828601613d65565b82525060208301356142ac8161363e565b602082015260408301356142bf81613702565b60408201526060838101359082015260808301356142dc81613702565b608082015292915050565b6000602082840312156142f957600080fd5b81516121738161363e565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261433857600080fd5b9190910192915050565b6000610140823603121561435557600080fd5b61435d613a78565b61436683613654565b815261437460208401613aa9565b6020820152604083013567ffffffffffffffff8082111561439457600080fd5b6143a036838701613d65565b604084015260608501359150808211156143b957600080fd5b506143c636828601613d65565b6060830152506143d93660808501613ad4565b60808201526143eb3660e08501613ad4565b60a082015292915050565b815167ffffffffffffffff811115614410576144106139fc565b6144248161441e8454613d12565b8461407c565b602080601f83116001811461447757600084156144415750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611f14565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156144c4578886015182559484019460019091019084016144a5565b508582101561450057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152614534818401876136a5565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506145729050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613957565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610914576109146145a9565b67ffffffffffffffff8416815260e0810161463760208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612c7e565b6060810161091482848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156146bc57600080fd5b815161217381613702565b8082028115828204841417610914576109146145a9565b80820180821115610914576109146145a9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614756577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000825161433881846020870161368156fea164736f6c6343000818000a", + Bin: "0x6101406040523480156200001257600080fd5b50604051620052dd380380620052dd833981016040819052620000359162000b4c565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200041b565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016957604080516000815260208101909152620001699084620004c6565b5050506001600160a01b038616905062000196576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fd919062000c72565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000240573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000266919062000c99565b905063ffffffff81161562000297576040516334697c6b60e11b815263ffffffff8216600482015260240162000087565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fe919062000c99565b905063ffffffff8116156200032f576040516316ba39c560e31b815263ffffffff8216600482015260240162000087565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa15801562000381573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a7919062000c99565b63ffffffff166101205260e051608051620003d1916001600160a01b039091169060001962000623565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000de6565b336001600160a01b03821603620004755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620004e7576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005725760008382815181106200050b576200050b62000cc1565b602090810291909101015190506200052560028262000709565b1562000568576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620004ea565b5060005b81518110156200061e57600082828151811062000597576200059762000cc1565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005c3575062000615565b620005d060028262000729565b1562000613576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000576565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200069b919062000cd7565b620006a7919062000d07565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000703918691906200074016565b50505050565b600062000720836001600160a01b03841662000811565b90505b92915050565b600062000720836001600160a01b03841662000915565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200078f906001600160a01b03851690849062000967565b8051909150156200061e5780806020019051810190620007b0919062000d1d565b6200061e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000087565b600081815260018301602052604081205480156200090a5760006200083860018362000d41565b85549091506000906200084e9060019062000d41565b9050818114620008ba57600086600001828154811062000872576200087262000cc1565b906000526020600020015490508087600001848154811062000898576200089862000cc1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620008ce57620008ce62000d57565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000723565b600091505062000723565b60008181526001830160205260408120546200095e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000723565b50600062000723565b606062000978848460008562000980565b949350505050565b606082471015620009e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000087565b600080866001600160a01b0316858760405162000a01919062000d93565b60006040518083038185875af1925050503d806000811462000a40576040519150601f19603f3d011682016040523d82523d6000602084013e62000a45565b606091505b50909250905062000a598783838762000a64565b979650505050505050565b6060831562000ad857825160000362000ad0576001600160a01b0385163b62000ad05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000087565b508162000978565b62000978838381511562000aef5781518083602001fd5b8060405162461bcd60e51b815260040162000087919062000db1565b6001600160a01b038116811462000b2157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b478162000b0b565b919050565b600080600080600060a0868803121562000b6557600080fd5b855162000b728162000b0b565b8095505060208087015162000b878162000b0b565b60408801519095506001600160401b038082111562000ba557600080fd5b818901915089601f83011262000bba57600080fd5b81518181111562000bcf5762000bcf62000b24565b8060051b604051601f19603f8301168101818110858211171562000bf75762000bf762000b24565b60405291825284820192508381018501918c83111562000c1657600080fd5b938501935b8285101562000c3f5762000c2f8562000b3a565b8452938501939285019262000c1b565b80985050505050505062000c566060870162000b3a565b915062000c666080870162000b3a565b90509295509295909350565b60006020828403121562000c8557600080fd5b815162000c928162000b0b565b9392505050565b60006020828403121562000cac57600080fd5b815163ffffffff8116811462000c9257600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000cea57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000723576200072362000cf1565b60006020828403121562000d3057600080fd5b8151801515811462000c9257600080fd5b8181038181111562000723576200072362000cf1565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d8a57818101518382015260200162000d70565b50506000910152565b6000825162000da781846020870162000d6d565b9190910192915050565b602081526000825180602084015262000dd281604085016020870162000d6d565b601f01601f19169190910160400192915050565b60805160a05160c05160e051610100516101205161443762000ea6600039600081816103820152818161122401528181611e9c0152611efa0152600081816106760152610a7801526000818161035b015261113801526000818161063a01528181611f9701526128d201526000818161057601528181611c9a015261224d01526000818161028f015281816102e401528181610b260152818161110501528181611bba0152818161216d015281816128680152612abd01526144376000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80639a4575b91161010f578063c75eea9c116100a2578063dfadfa3511610071578063dfadfa351461059a578063e0351e1314610638578063f2fde38b1461065e578063fbf84dd71461067157600080fd5b8063c75eea9c1461053b578063cf7401f31461054e578063db6327dc14610561578063dc0bd9711461057457600080fd5b8063b0f479a1116100de578063b0f479a1146104e2578063b794658014610500578063c0d7865514610513578063c4bffe2b1461052657600080fd5b80639a4575b9146104365780639fdf13ff14610456578063a7cd63b71461045e578063af58d59f1461047357600080fd5b80636155cda01161018757806379ba50971161015657806379ba5097146103ea5780637d54534e146103f25780638926f54f146104055780638da5cb5b1461041857600080fd5b80636155cda0146103565780636b716b0d1461037d5780636d3d1a58146103b957806378a010b2146103d757600080fd5b806321df0da7116101c357806321df0da71461028d578063240028e8146102d4578063390775371461032157806354c8a4f31461034357600080fd5b806241d3c1146101f457806301ffc9a7146102095780630a2fd49314610231578063181f5a7714610251575b600080fd5b610207610202366004613260565b610698565b005b61021c6102173660046132d5565b610835565b60405190151581526020015b60405180910390f35b61024461023f36600461333d565b61091a565b60405161022891906133be565b6102446040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e342e300000000000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610228565b61021c6102e23660046133fe565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61033461032f36600461341b565b6109ca565b60405190518152602001610228565b6102076103513660046134a3565b610c75565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6103a47f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610228565b60085473ffffffffffffffffffffffffffffffffffffffff166102af565b6102076103e536600461350f565b610cf0565b610207610e5f565b6102076104003660046133fe565b610f5c565b61021c61041336600461333d565b610fab565b60005473ffffffffffffffffffffffffffffffffffffffff166102af565b610449610444366004613594565b610fc2565b60405161022891906135cf565b6103a4600081565b61046661129e565b604051610228919061362f565b61048661048136600461333d565b6112af565b604051610228919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102af565b61024461050e36600461333d565b611384565b6102076105213660046133fe565b6113af565b61052e611483565b6040516102289190613689565b61048661054936600461333d565b61153b565b61020761055c366004613814565b61160d565b61020761056f36600461385b565b611696565b7f00000000000000000000000000000000000000000000000000000000000000006102af565b61060e6105a836600461333d565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600982529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610228565b7f000000000000000000000000000000000000000000000000000000000000000061021c565b61020761066c3660046133fe565b611b1c565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6106a0611b30565b60005b818110156107f75760008383838181106106bf576106bf61389d565b9050608002018036038101906106d591906138e0565b805190915015806106f25750604081015167ffffffffffffffff16155b1561076157604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600990925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169190931617929092179055016106a3565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee56828260405161082992919061395a565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806108c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061091457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff81166000908152600760205260409020600401805460609190610945906139e1565b80601f0160208091040260200160405190810160405280929190818152602001828054610971906139e1565b80156109be5780601f10610993576101008083540402835291602001916109be565b820191906000526020600020905b8154815290600101906020018083116109a157829003601f168201915b50505050509050919050565b6040805160208101909152600081526109ea6109e583613adf565b611bb3565b60006109f960c0840184613bd4565b810190610a069190613c39565b90506000610a1760e0850185613bd4565b810190610a249190613c78565b9050610a34816000015183611de4565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aab92600401613d09565b6020604051808303816000875af1158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190613d2e565b610b24576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006040517f095ea7b30000000000000000000000000000000000000000000000000000000081523360048201526060860135602482015273ffffffffffffffffffffffffffffffffffffffff919091169063095ea7b3906044016020604051808303816000875af1158015610bbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be19190613d2e565b50610bf260608501604086016133fe565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610c5491815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b610c7d611b30565b610cea84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f9592505050565b50505050565b610cf8611b30565b610d0183610fab565b610d43576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b67ffffffffffffffff831660009081526007602052604081206004018054610d6a906139e1565b80601f0160208091040260200160405190810160405280929190818152602001828054610d96906139e1565b8015610de35780601f10610db857610100808354040283529160200191610de3565b820191906000526020600020905b815481529060010190602001808311610dc657829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610e12838583613d93565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610e5193929190613eae565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ee0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610758565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610f64611b30565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610914600567ffffffffffffffff841661214b565b6040805180820190915260608082526020820152610fe7610fe283613f12565b612166565b6000600981610ffc604086016020870161333d565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff1615159082018190529091506110a357611064604084016020850161333d565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b602081015181516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060860135600482015263ffffffff90921660248301526044820181905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091526000917f00000000000000000000000000000000000000000000000000000000000000009091169063f856ddb69060a4016020604051808303816000875af1158015611183573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a79190613fb6565b6040516060860135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a2604051806040016040528061120486602001602081019061050e919061333d565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529052949350505050565b60606112aa6002612330565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526109149061233d565b67ffffffffffffffff81166000908152600760205260409020600501805460609190610945906139e1565b6113b7611b30565b73ffffffffffffffffffffffffffffffffffffffff8116611404576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610829565b606060006114916005612330565b90506000815167ffffffffffffffff8111156114af576114af6136cb565b6040519080825280602002602001820160405280156114d8578160200160208202803683370190505b50905060005b8251811015611534578281815181106114f9576114f961389d565b60200260200101518282815181106115135761151361389d565b67ffffffffffffffff909216602092830291909101909101526001016114de565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526109149061233d565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061164d575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611686576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b6116918383836123ef565b505050565b61169e611b30565b60005b818110156116915760008383838181106116bd576116bd61389d565b90506020028101906116cf9190613fd3565b6116d890614011565b90506116ed81608001518260200151156124d9565b6117008160a001518260200151156124d9565b8060200151156119fc5780516117229060059067ffffffffffffffff16612612565b6117675780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b604081015151158061177c5750606081015151155b156117b3576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061199490826140c5565b50606082015160058201906119a990826140c5565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506119ef94939291906141df565b60405180910390a1611b13565b8051611a149060059067ffffffffffffffff1661261e565b611a595780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611ac26004830182613212565b611ad0600583016000613212565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016116a1565b611b24611b30565b611b2d8161262a565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611bb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610758565b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611c485760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611cf6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d1a9190613d2e565b15611d51576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d5e816020015161271f565b6000611d6d826020015161091a565b9050805160001480611d91575080805190602001208260a001518051906020012014155b15611dce578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161075891906133be565b611de082602001518360600151612845565b5050565b600482015163ffffffff811615611e2f576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610758565b6008830151600c8401516014850151602085015163ffffffff808516911614611e9a5760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff91821660048201529084166024820152604401610758565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611f2f576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015283166024820152604401610758565b845167ffffffffffffffff828116911614611f8d5784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821660048201529082166024820152604401610758565b505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611fec576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561208257600083828151811061200c5761200c61389d565b6020026020010151905061202a81600261288c90919063ffffffff16565b156120795760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611fef565b5060005b81518110156116915760008282815181106120a3576120a361389d565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120e75750612143565b6120f26002826128ae565b156121415760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612086565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121fb5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156122a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122cd9190613d2e565b15612304576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61231181604001516128d0565b61231e816020015161294f565b611b2d81602001518260600151612a9d565b6060600061215f83612ae1565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526123cb82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426123af91906142a7565b85608001516fffffffffffffffffffffffffffffffff16612b3c565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6123f883610fab565b61243a576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b6124458260006124d9565b67ffffffffffffffff831660009081526007602052604090206124689083612b66565b6124738160006124d9565b67ffffffffffffffff831660009081526007602052604090206124999060020182612b66565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516124cc939291906142ba565b60405180910390a1505050565b8151156125a05781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061252f575060408201516fffffffffffffffffffffffffffffffff16155b1561256857816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610758919061433d565b8015611de0576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806125d9575060208201516fffffffffffffffffffffffffffffffff1615155b15611de057816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610758919061433d565b600061215f8383612d08565b600061215f8383612d57565b3373ffffffffffffffffffffffffffffffffffffffff8216036126a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610758565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61272881610fab565b61276a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156127e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280d9190613d2e565b611b2d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611de090600201827f0000000000000000000000000000000000000000000000000000000000000000612e4a565b600061215f8373ffffffffffffffffffffffffffffffffffffffff8416612d57565b600061215f8373ffffffffffffffffffffffffffffffffffffffff8416612d08565b7f000000000000000000000000000000000000000000000000000000000000000015611b2d576129016002826131cd565b611b2d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610758565b61295881610fab565b61299a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612a13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a379190614379565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b2d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611de090827f0000000000000000000000000000000000000000000000000000000000000000612e4a565b6060816000018054806020026020016040519081016040528092919081815260200182805480156109be57602002820191906000526020600020905b815481526020019060010190808311612b1d5750505050509050919050565b6000612b5b85612b4c8486614396565b612b5690876143ad565b6131fc565b90505b949350505050565b8154600090612b8f90700100000000000000000000000000000000900463ffffffff16426142a7565b90508015612c315760018301548354612bd7916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b3c565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c57916fffffffffffffffffffffffffffffffff90811691166131fc565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906124cc90849061433d565b6000818152600183016020526040812054612d4f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610914565b506000610914565b60008181526001830160205260408120548015612e40576000612d7b6001836142a7565b8554909150600090612d8f906001906142a7565b9050818114612df4576000866000018281548110612daf57612daf61389d565b9060005260206000200154905080876000018481548110612dd257612dd261389d565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612e0557612e056143c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610914565b6000915050610914565b825474010000000000000000000000000000000000000000900460ff161580612e71575081155b15612e7b57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612ec190700100000000000000000000000000000000900463ffffffff16426142a7565b90508015612f815781831115612f03576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612f3d9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b3c565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156130385773ffffffffffffffffffffffffffffffffffffffff8416612fe0576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610758565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610758565b8483101561314b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061307c90826142a7565b613086878a6142a7565b61309091906143ad565b61309a91906143ef565b905073ffffffffffffffffffffffffffffffffffffffff86166130f3576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610758565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610758565b61315585846142a7565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561215f565b600081831061320b578161215f565b5090919050565b50805461321e906139e1565b6000825580601f1061322e575050565b601f016020900490600052602060002090810190611b2d91905b8082111561325c5760008155600101613248565b5090565b6000806020838503121561327357600080fd5b823567ffffffffffffffff8082111561328b57600080fd5b818501915085601f83011261329f57600080fd5b8135818111156132ae57600080fd5b8660208260071b85010111156132c357600080fd5b60209290920196919550909350505050565b6000602082840312156132e757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461215f57600080fd5b67ffffffffffffffff81168114611b2d57600080fd5b803561333881613317565b919050565b60006020828403121561334f57600080fd5b813561215f81613317565b6000815180845260005b8181101561338057602081850181015186830182015201613364565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061215f602083018461335a565b73ffffffffffffffffffffffffffffffffffffffff81168114611b2d57600080fd5b8035613338816133d1565b60006020828403121561341057600080fd5b813561215f816133d1565b60006020828403121561342d57600080fd5b813567ffffffffffffffff81111561344457600080fd5b8201610100818503121561215f57600080fd5b60008083601f84011261346957600080fd5b50813567ffffffffffffffff81111561348157600080fd5b6020830191508360208260051b850101111561349c57600080fd5b9250929050565b600080600080604085870312156134b957600080fd5b843567ffffffffffffffff808211156134d157600080fd5b6134dd88838901613457565b909650945060208701359150808211156134f657600080fd5b5061350387828801613457565b95989497509550505050565b60008060006040848603121561352457600080fd5b833561352f81613317565b9250602084013567ffffffffffffffff8082111561354c57600080fd5b818601915086601f83011261356057600080fd5b81358181111561356f57600080fd5b87602082850101111561358157600080fd5b6020830194508093505050509250925092565b6000602082840312156135a657600080fd5b813567ffffffffffffffff8111156135bd57600080fd5b820160a0818503121561215f57600080fd5b6020815260008251604060208401526135eb606084018261335a565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613626828261335a565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561367d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161364b565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561367d57835167ffffffffffffffff16835292840192918401916001016136a5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561371e5761371e6136cb565b60405290565b6040805190810167ffffffffffffffff8111828210171561371e5761371e6136cb565b60405160c0810167ffffffffffffffff8111828210171561371e5761371e6136cb565b8015158114611b2d57600080fd5b80356133388161376a565b80356fffffffffffffffffffffffffffffffff8116811461333857600080fd5b6000606082840312156137b557600080fd5b6040516060810181811067ffffffffffffffff821117156137d8576137d86136cb565b60405290508082356137e98161376a565b81526137f760208401613783565b602082015261380860408401613783565b60408201525092915050565b600080600060e0848603121561382957600080fd5b833561383481613317565b925061384385602086016137a3565b915061385285608086016137a3565b90509250925092565b6000806020838503121561386e57600080fd5b823567ffffffffffffffff81111561388557600080fd5b61389185828601613457565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff8116811461333857600080fd5b6000608082840312156138f257600080fd5b6040516080810181811067ffffffffffffffff82111715613915576139156136cb565b60405282358152613928602084016138cc565b6020820152604083013561393b81613317565b6040820152606083013561394e8161376a565b60608201529392505050565b6020808252818101839052600090604080840186845b878110156139d4578135835263ffffffff61398c8684016138cc565b16858401528382013561399e81613317565b67ffffffffffffffff16838501526060828101356139bb8161376a565b1515908401526080928301929190910190600101613970565b5090979650505050505050565b600181811c908216806139f557607f821691505b602082108103613a2e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f830112613a4557600080fd5b813567ffffffffffffffff80821115613a6057613a606136cb565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613aa657613aa66136cb565b81604052838152866020858801011115613abf57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613af257600080fd5b613afa6136fa565b823567ffffffffffffffff80821115613b1257600080fd5b613b1e36838701613a34565b8352613b2c6020860161332d565b6020840152613b3d604086016133f3565b604084015260608501356060840152613b58608086016133f3565b608084015260a0850135915080821115613b7157600080fd5b613b7d36838701613a34565b60a084015260c0850135915080821115613b9657600080fd5b613ba236838701613a34565b60c084015260e0850135915080821115613bbb57600080fd5b50613bc836828601613a34565b60e08301525092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c0957600080fd5b83018035915067ffffffffffffffff821115613c2457600080fd5b60200191503681900382131561349c57600080fd5b600060408284031215613c4b57600080fd5b613c53613724565b8235613c5e81613317565b8152613c6c602084016138cc565b60208201529392505050565b600060208284031215613c8a57600080fd5b813567ffffffffffffffff80821115613ca257600080fd5b9083019060408286031215613cb657600080fd5b613cbe613724565b823582811115613ccd57600080fd5b613cd987828601613a34565b825250602083013582811115613cee57600080fd5b613cfa87828601613a34565b60208301525095945050505050565b604081526000613d1c604083018561335a565b8281036020840152613626818561335a565b600060208284031215613d4057600080fd5b815161215f8161376a565b601f821115611691576000816000526020600020601f850160051c81016020861015613d745750805b601f850160051c820191505b81811015611f8d57828155600101613d80565b67ffffffffffffffff831115613dab57613dab6136cb565b613dbf83613db983546139e1565b83613d4b565b6000601f841160018114613e115760008515613ddb5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613ea7565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613e605786850135825560209485019460019092019101613e40565b5086821015613e9b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613ec1604083018661335a565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613f2457600080fd5b60405160a0810167ffffffffffffffff8282108183111715613f4857613f486136cb565b816040528435915080821115613f5d57600080fd5b50613f6a36828601613a34565b8252506020830135613f7b81613317565b60208201526040830135613f8e816133d1565b6040820152606083810135908201526080830135613fab816133d1565b608082015292915050565b600060208284031215613fc857600080fd5b815161215f81613317565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261400757600080fd5b9190910192915050565b6000610140823603121561402457600080fd5b61402c613747565b6140358361332d565b815261404360208401613778565b6020820152604083013567ffffffffffffffff8082111561406357600080fd5b61406f36838701613a34565b6040840152606085013591508082111561408857600080fd5b5061409536828601613a34565b6060830152506140a836608085016137a3565b60808201526140ba3660e085016137a3565b60a082015292915050565b815167ffffffffffffffff8111156140df576140df6136cb565b6140f3816140ed84546139e1565b84613d4b565b602080601f83116001811461414657600084156141105750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611f8d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561419357888601518255948401946001909101908401614174565b50858210156141cf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526142038184018761335a565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506142419050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613626565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561091457610914614278565b67ffffffffffffffff8416815260e0810161430660208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612b5e565b6060810161091482848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561438b57600080fd5b815161215f816133d1565b808202811582820484141761091457610914614278565b8082018082111561091457610914614278565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614425577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var USDCTokenPoolABI = USDCTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index ef84a7d75b..034a89f133 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,21 +1,21 @@ GETH_VERSION: 1.13.8 arm_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 1a0abacf84def916519013f713b667f106434a091af8b9f441e12cc90aa2cdf8 arm_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 -burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 62d9963a998b8e5c4b9bfa537e916559c167863329c40e9a75eb4defebceb810 -burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 1bbffb552c3256097fbe61a430de408073816f40e17b17b102b793527d44f046 -burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 5be8832498c8aab49957bfff94fbb1d22373833d1d56f5d8ace259343b27fc24 -burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 9215cb5efe441e9893f871de31b4a5d4171c479f276aac4084046514990f1bd6 +burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 02e37792e25155ab4e7e4b4211002180789d0c1559cad1e38d3bd70efe0fb7d6 +burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 4b1b468de62a7e9adffd4d8ccb3621a7e0658ae453a4bfa72493ae25362e9693 +burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin b1c6188532aacf44b81d833c123131b81e0fd3ee7ef95ba29a9ba1b6ff6b30c9 +burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 94c361ae328eca24b24ce236080ff2e898cc037ee0d4cd1f3802f7ee75d7cc8d ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 970bf6a2a817813eb3302c92ec3ad0bc0fc6c2e693f33c13f57733d003f44d0d ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin fcced2263564f51b5bf086c221e813ec06a71d2bb2e246b4e28cd60098a6de6f commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin ddc26c10c2a52b59624faae9005827b09b98db4566887a736005e8cc37cf8a51 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin ebd8aac686fa28a71d4212bcd25a28f8f640d50dce5e50498b2f6b8534890b69 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de -evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 10a0cbf8290778fce7e9aaf193aaffaa566bc55d0168b8876f94ceb14ff7cd30 +evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin cb1c4d1bd8460181f1545524bc2537a58f6839ee0acad6a068f5e24216a9cee9 evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 15cd5695049ab4be1f396ec1d7b609738b2bcefa3740a7a48316e1f72506a34a -evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin bdafc343d33f1eb753871ea6d215339cd8e087c1a8c7297257791dd1e453be8f +evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin ea2a9622ace941075ea62cd348e9c69c5aa3bf8a7daf298fea51984f80a1d27d evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin bf1a3090a2f8d1632b82a6d45200cf6f3833a1e27303745405c1ed13ffc0cf83 -lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin f049909cfef0aa3b8158c85e7b64516b9d7b32f4930705574090e5b9cab534b1 -lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin d897366aa5c58f426eaf3fc748d9def8f78111d9ac8c122e390952f640de22fc +lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin ee60ad24918c9652ef4b251236dd3390cce651b685e94532bf3bde2a111fe6b9 +lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin e23f4fd063eb3a289d651016ac45fcef72607ce2b571cba134e2bf35590c114d maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin 1d5146d43e1b99cd2d6f9f06475be19087e4349f7cee0fdbbf134ba65e967c93 mock_arm_contract: ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.abi ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.bin e7a3a6c3eda5fb882e16bcc2b4340f78523acb67907bcdcaf3c8ffc51488688e @@ -34,5 +34,5 @@ router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/sol self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 86e169636e5633854ed0b709c804066b615040bceba25aa5137450fbe6f76fa3 token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin fb06d2cf5f7476e512c6fb7aab8eab43545efd7f0f6ca133c64ff4e3963902c4 token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 7c01fd89f5153baa4d7409d14beabb3f861abfbf8880d3c6d06802cc398570f9 -usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin e259cffee304678cfce3632f122cf96ecc06b4ab01905940cd0111f2fd50e4d8 +usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin b92eaf3434896056300f38f4ad0fa8b84879e9dea2e6240a67e48688c09bf06b weth9: ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin 2970d79a0ca6dd6279cde130de45e56c8790ed695eae477fb5ba4c1bb75b720d From cefcf1a4caa53990bb9575d30d2e03477248edec Mon Sep 17 00:00:00 2001 From: Makram Date: Tue, 6 Aug 2024 18:02:27 +0300 Subject: [PATCH 194/432] core/capabilities/ccip: use OCR offchain config (#1264) We want to define and use the appropriate OCR offchain config for each plugin. Requires https://github.com/smartcontractkit/chainlink-ccip/pull/36/ --- core/scripts/go.mod | 101 ++++---- core/scripts/go.sum | 476 +++++++++------------------------- go.mod | 114 ++++---- go.sum | 472 +++++++++------------------------ integration-tests/go.mod | 216 ++++++++------- integration-tests/go.sum | 400 +++++++++++++--------------- integration-tests/load/go.mod | 144 +++++----- integration-tests/load/go.sum | 309 +++++++++++----------- 8 files changed, 862 insertions(+), 1370 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index f106525d2a..52fd0e57f3 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -19,18 +19,21 @@ require ( github.com/montanaflynn/stats v0.7.1 github.com/olekukonko/tablewriter v0.0.5 github.com/pelletier/go-toml/v2 v2.2.0 + github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 + github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 + github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 - github.com/spf13/viper v1.15.0 + github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.9.0 github.com/umbracle/ethgo v0.1.3 github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 github.com/urfave/cli v1.22.14 + go.uber.org/multierr v1.11.0 google.golang.org/protobuf v1.34.2 k8s.io/api v0.30.0 k8s.io/apimachinery v0.30.0 @@ -41,14 +44,14 @@ require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect - cosmossdk.io/depinject v1.0.0-alpha.3 // indirect - cosmossdk.io/errors v1.0.0 // indirect - cosmossdk.io/math v1.0.1 // indirect + cosmossdk.io/depinject v1.0.0-alpha.4 // indirect + cosmossdk.io/errors v1.0.1 // indirect + cosmossdk.io/math v1.3.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect - github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/CosmWasm/wasmd v0.40.1 // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect @@ -77,25 +80,25 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/errors v1.10.0 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.37.2 // indirect - github.com/cometbft/cometbft-db v0.7.0 // indirect + github.com/cometbft/cometbft v0.37.5 // indirect + github.com/cometbft/cometbft-db v0.8.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect - github.com/cosmos/cosmos-sdk v0.47.4 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect + github.com/cosmos/cosmos-sdk v0.47.11 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.11 // indirect - github.com/cosmos/iavl v0.20.0 // indirect - github.com/cosmos/ibc-go/v7 v7.0.1 // indirect - github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect - github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect + github.com/cosmos/iavl v0.20.1 // indirect + github.com/cosmos/ibc-go/v7 v7.5.1 // indirect + github.com/cosmos/ics23/go v0.10.0 // indirect + github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect @@ -117,7 +120,7 @@ require ( github.com/esote/minmaxheap v1.0.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fatih/color v1.16.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gagliardetto/binary v0.7.7 // indirect @@ -126,7 +129,7 @@ require ( github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 // indirect - github.com/getsentry/sentry-go v0.19.0 // indirect + github.com/getsentry/sentry-go v0.23.0 // indirect github.com/gin-contrib/cors v1.5.0 // indirect github.com/gin-contrib/expvar v0.0.1 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect @@ -171,14 +174,14 @@ require ( github.com/gorilla/sessions v1.2.2 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/grafana/pyroscope-go v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect github.com/graph-gophers/dataloader v5.0.0+incompatible // indirect github.com/graph-gophers/graphql-go v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect @@ -213,7 +216,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.3 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -222,6 +225,7 @@ require ( github.com/leodido/go-urn v1.2.4 // indirect github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -250,7 +254,6 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/pressly/goose/v3 v3.21.1 // indirect @@ -263,33 +266,33 @@ require ( github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/scylladb/go-reflectx v1.0.1 // indirect github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect - github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.7.3 // indirect - github.com/spf13/afero v1.9.5 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/subosito/gotenv v1.4.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect - github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect github.com/test-go/testify v1.1.4 // indirect @@ -310,15 +313,15 @@ require ( github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zondax/hid v0.9.1 // indirect - github.com/zondax/ledger-go v0.14.1 // indirect + github.com/zondax/hid v0.9.2 // indirect + github.com/zondax/ledger-go v0.14.3 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect go.etcd.io/bbolt v1.3.7 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect @@ -326,25 +329,24 @@ require ( go.opentelemetry.io/otel/sdk v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.uber.org/multierr v1.11.0 // indirect go.uber.org/ratelimit v0.3.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/arch v0.7.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/term v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/tools v0.23.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/grpc v1.65.0 // indirect gopkg.in/guregu/null.v4 v4.0.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect @@ -355,7 +357,7 @@ require ( k8s.io/klog/v2 v2.120.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect - pgregory.net/rapid v0.5.5 // indirect + pgregory.net/rapid v1.1.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect @@ -371,5 +373,4 @@ replace ( // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f - ) diff --git a/core/scripts/go.sum b/core/scripts/go.sum index fbc83070e4..d32e7ddd71 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -4,52 +4,33 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= -cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= -cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= -cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= -cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= -cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.27.2 h1:5cE5hdrwJV/92ravlwIFRGnyH9CpLGhh4N0ZDVTU+BA= -cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= -cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw= -cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= -cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= +cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= +cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo= @@ -58,14 +39,14 @@ cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= -cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= -cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= -cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= -cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= -cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca h1:msenprh2BLLRwNT7zN56TbBHOGk/7ARQckXHxXyvjoQ= -cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c= -cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= -cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= +cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= +cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= +cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= +cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= +cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= +cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= +cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= +cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -78,7 +59,6 @@ github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo8 github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= @@ -86,10 +66,8 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzS github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= +github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= github.com/CosmWasm/wasmd v0.40.1/go.mod h1:6EOwnv7MpuFaEqxcUOdFV9i4yvrdOciaY6VQ1o7A3yg= github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= @@ -101,7 +79,6 @@ github.com/Depado/ginprom v1.8.0 h1:zaaibRLNI1dMiiuj1MKzatm8qrcHzikMlCc1anqOdyo= github.com/Depado/ginprom v1.8.0/go.mod h1:XBaKzeNBqPF4vxJpNLincSQZeMDnZp1tIbU0FU0UKgg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= @@ -116,7 +93,6 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= @@ -124,10 +100,7 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/ github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= -github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -153,7 +126,6 @@ github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -234,35 +206,29 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= -github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= -github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/errors v1.10.0 h1:lfxS8zZz1+OjtV4MtNWgboi/W5tyLEB6VQZBXN+0VUU= +github.com/cockroachdb/errors v1.10.0/go.mod h1:lknhIsEVQ9Ss/qKDBQS/UqFSvPQjOwNq2qyKAxtHRqE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= -github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= -github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= -github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= -github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= +github.com/cometbft/cometbft v0.37.5 h1:/U/TlgMh4NdnXNo+YU9T2NMCWyhXNDF34Mx582jlvq0= +github.com/cometbft/cometbft v0.37.5/go.mod h1:QC+mU0lBhKn8r9qvmnq53Dmf3DWBt4VtkcKw2C81wxY= +github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= +github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -282,10 +248,10 @@ github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= -github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.47.4 h1:FVUpEprm58nMmBX4xkRdMDaIG5Nr4yy92HZAfGAw9bg= -github.com/cosmos/cosmos-sdk v0.47.4/go.mod h1:R5n+uM7vguVPFap4pgkdvQCT1nVo/OtPwrlAU40rvok= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= +github.com/cosmos/cosmos-sdk v0.47.11 h1:0Qx7eORw0RJqPv+mvDuU8NQ1LV3nJJKJnPoYblWHolc= +github.com/cosmos/cosmos-sdk v0.47.11/go.mod h1:ADjORYzUQqQv/FxDi0H0K5gW/rAk1CiDR3ZKsExfJV0= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -293,14 +259,14 @@ github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiK github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= -github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= -github.com/cosmos/ibc-go/v7 v7.0.1 h1:NIBNRWjlOoFvFQu1ZlgwkaSeHO5avf4C1YQiWegt8jw= -github.com/cosmos/ibc-go/v7 v7.0.1/go.mod h1:vEaapV6nuLPQlS+g8IKmxMo6auPi0i7HMv1PhViht/E= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= -github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= -github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/iavl v0.20.1 h1:rM1kqeG3/HBT85vsZdoSNsehciqUQPWrR4BYmqE2+zg= +github.com/cosmos/iavl v0.20.1/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/ibc-go/v7 v7.5.1 h1:KqS/g7W7EMX1OtOvufS8lWMJibOKpdgtNNZIU6fAgVU= +github.com/cosmos/ibc-go/v7 v7.5.1/go.mod h1:ktFg5GvKOyrGCqTWtW7Grj5uweU4ZapxrNeVS1CLLbo= +github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= +github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= +github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw= +github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M= github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -316,10 +282,6 @@ github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJF github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= -github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= -github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= -github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -344,7 +306,6 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFM github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70/go.mod h1:EoK/8RFbMEteaCaz89uessDTnCWjbbcr+DXcBh4el5o= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= @@ -370,36 +331,24 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo= github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/esote/minmaxheap v1.0.0 h1:rgA7StnXXpZG6qlM0S7pUmEv1KpWe32rYT4x8J8ntaA= github.com/esote/minmaxheap v1.0.0/go.mod h1:Ln8+i7fS1k3PLgZI2JAo0iA1as95QnIYiGCrqSJ5FZk= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= github.com/ethereum/go-ethereum v1.13.8/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -411,8 +360,8 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= @@ -425,16 +374,14 @@ github.com/gagliardetto/solana-go v1.8.4 h1:vmD/JmTlonyXGy39bAo0inMhmbdAwV7rXZtL github.com/gagliardetto/solana-go v1.8.4/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.19.0 h1:BcCH3CN5tXt5aML+gwmbFwVptLLQA+eT866fCO9wVOM= -github.com/getsentry/sentry-go v0.19.0/go.mod h1:y3+lGEFEFexZtpbG1GUE2WD/f9zGyKYwpEqryTOC/nE= +github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE= +github.com/getsentry/sentry-go v0.23.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= @@ -459,8 +406,6 @@ github.com/gkampitakis/go-snaps v0.5.4 h1:GX+dkKmVsRenz7SoTbdIEL4KQARZctkMiZ8ZKp github.com/gkampitakis/go-snaps v0.5.4/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -487,7 +432,6 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= @@ -520,9 +464,6 @@ github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6l github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= @@ -533,12 +474,8 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= @@ -556,9 +493,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -566,7 +501,6 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -586,7 +520,6 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -597,18 +530,14 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= @@ -616,8 +545,6 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -625,11 +552,6 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= @@ -642,13 +564,12 @@ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.1 h1:SBWmZhjUDRorQxrN0nwzf+AHBxnbFjViHQS4P0yVpmQ= -github.com/googleapis/enterprise-certificate-proxy v0.3.1/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= +github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -661,14 +582,13 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= -github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= +github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= +github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= @@ -684,8 +604,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= @@ -728,7 +648,6 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= @@ -762,12 +681,10 @@ github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -775,11 +692,6 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -858,30 +770,20 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= +github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -895,8 +797,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= @@ -910,6 +810,8 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= +github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= @@ -927,12 +829,9 @@ github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -940,7 +839,6 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -953,14 +851,11 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= @@ -1001,7 +896,6 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= @@ -1009,10 +903,6 @@ github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ib github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -1029,7 +919,6 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= @@ -1078,7 +967,6 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -1118,8 +1006,6 @@ github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= -github.com/regen-network/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= @@ -1134,7 +1020,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= @@ -1143,24 +1028,25 @@ github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= -github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= @@ -1184,18 +1070,18 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 h1:KKqMibl8CcKSyrSkVVfgGEOuC6Cn3vFQK8yMQA6FpxA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92/go.mod h1:wl0SRmyJ2ARxz+4Eho6nEXsmWFXxTSYpvcb30AxwKyE= +github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= +github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa/go.mod h1:wZvLHX/Sd9hskN51016cTFcT3G62KXVa6xbVDS7tRjc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= @@ -1213,12 +1099,14 @@ github.com/smartcontractkit/wsrpc v0.7.3/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgq github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= @@ -1227,16 +1115,14 @@ github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= -github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= @@ -1263,15 +1149,13 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= @@ -1306,10 +1190,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2 github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= @@ -1327,14 +1209,10 @@ github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE= github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -1342,31 +1220,23 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= -github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= -github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= +github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= +github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= @@ -1393,10 +1263,10 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/contrib/propagators/b3 v1.24.0 h1:n4xwCdTx3pZqZs2CjS/CUZAs03y3dZcGhC/FepKtEUY= go.opentelemetry.io/contrib/propagators/b3 v1.24.0/go.mod h1:k5wRxKRU2uXx2F8uNJ4TaonuEO/V7/5xoz7kdsDACT8= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= @@ -1409,8 +1279,8 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= -go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= +go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= +go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -1445,8 +1315,8 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= -golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= +golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1456,26 +1326,21 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1486,8 +1351,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1501,7 +1366,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1510,13 +1374,11 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1528,64 +1390,46 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1593,14 +1437,12 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1638,47 +1480,32 @@ golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1686,8 +1513,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1695,8 +1522,8 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1709,22 +1536,19 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1757,33 +1581,16 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1803,27 +1610,16 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= -google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= +google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= +google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1843,37 +1639,18 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= -google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= -google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= -google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1886,15 +1663,9 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1905,7 +1676,6 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -1931,10 +1701,8 @@ gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:a gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1950,21 +1718,19 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= -gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= @@ -1995,8 +1761,8 @@ modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= -pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/go.mod b/go.mod index 3fec96a015..efc4f413d3 100644 --- a/go.mod +++ b/go.mod @@ -11,8 +11,8 @@ require ( github.com/XSAM/otelsql v0.27.0 github.com/avast/retry-go/v4 v4.6.0 github.com/btcsuite/btcd/btcec/v2 v2.3.2 - github.com/cometbft/cometbft v0.37.2 - github.com/cosmos/cosmos-sdk v0.47.4 + github.com/cometbft/cometbft v0.37.5 + github.com/cosmos/cosmos-sdk v0.47.11 github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e github.com/deckarep/golang-set/v2 v2.6.0 github.com/dominikbraun/graph v0.23.0 @@ -21,7 +21,7 @@ require ( github.com/fatih/color v1.16.0 github.com/fxamacker/cbor/v2 v2.5.0 github.com/gagliardetto/solana-go v1.8.4 - github.com/getsentry/sentry-go v0.19.0 + github.com/getsentry/sentry-go v0.23.0 github.com/gin-contrib/cors v1.5.0 github.com/gin-contrib/expvar v0.0.1 github.com/gin-contrib/sessions v0.0.5 @@ -68,18 +68,18 @@ require ( github.com/prometheus/prometheus v0.48.1 github.com/robfig/cron/v3 v3.0.1 github.com/rogpeppe/go-internal v1.12.0 - github.com/rs/zerolog v1.30.0 + github.com/rs/zerolog v1.32.0 github.com/scylladb/go-reflectx v1.0.1 github.com/shirou/gopsutil/v3 v3.24.3 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 + github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 @@ -102,15 +102,15 @@ require ( go.opentelemetry.io/otel v1.28.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.26.0 - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa - golang.org/x/mod v0.20.0 - golang.org/x/net v0.28.0 - golang.org/x/sync v0.8.0 - golang.org/x/term v0.23.0 - golang.org/x/text v0.17.0 + golang.org/x/crypto v0.25.0 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 + golang.org/x/mod v0.19.0 + golang.org/x/net v0.27.0 + golang.org/x/sync v0.7.0 + golang.org/x/term v0.22.0 + golang.org/x/text v0.16.0 golang.org/x/time v0.5.0 - golang.org/x/tools v0.24.0 + golang.org/x/tools v0.23.0 gonum.org/v1/gonum v0.15.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 @@ -120,22 +120,27 @@ require ( ) require ( - cloud.google.com/go/auth v0.7.1 // indirect - cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect - cloud.google.com/go/compute/metadata v0.5.0 // indirect - cloud.google.com/go/iam v1.1.11 // indirect - cloud.google.com/go/storage v1.43.0 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect - cosmossdk.io/depinject v1.0.0-alpha.3 // indirect - cosmossdk.io/errors v1.0.0 // indirect - cosmossdk.io/math v1.0.1 // indirect + cosmossdk.io/depinject v1.0.0-alpha.4 // indirect + cosmossdk.io/errors v1.0.1 // indirect + cosmossdk.io/math v1.3.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect - github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/CosmWasm/wasmd v0.40.1 // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect @@ -143,13 +148,11 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/blendle/zapdriver v1.3.1 // indirect - github.com/buger/jsonparser v1.1.1 // indirect github.com/bytedance/sonic v1.10.1 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -157,23 +160,23 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/errors v1.10.0 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft-db v0.7.0 // indirect + github.com/cometbft/cometbft-db v0.8.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.11 // indirect - github.com/cosmos/iavl v0.20.0 // indirect - github.com/cosmos/ibc-go/v7 v7.0.1 // indirect - github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect - github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect + github.com/cosmos/iavl v0.20.1 // indirect + github.com/cosmos/ibc-go/v7 v7.5.1 // indirect + github.com/cosmos/ics23/go v0.10.0 // indirect + github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect @@ -188,8 +191,7 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect @@ -222,13 +224,14 @@ require ( github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.12.2 // indirect github.com/gorilla/context v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect @@ -255,15 +258,15 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.3 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect @@ -293,18 +296,16 @@ require ( github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cobra v1.8.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.15.0 // indirect + github.com/spf13/viper v1.18.2 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/subosito/gotenv v1.4.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect - github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect github.com/tidwall/btree v1.6.0 // indirect @@ -318,14 +319,13 @@ require ( github.com/valyala/fastjson v1.4.1 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zondax/hid v0.9.1 // indirect - github.com/zondax/ledger-go v0.14.1 // indirect + github.com/zondax/hid v0.9.2 // indirect + github.com/zondax/ledger-go v0.14.3 // indirect go.dedis.ch/protobuf v1.0.11 // indirect go.etcd.io/bbolt v1.3.7 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect @@ -333,17 +333,15 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/ratelimit v0.3.0 // indirect - golang.org/x/arch v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - google.golang.org/api v0.188.0 // indirect - google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect + golang.org/x/arch v0.7.0 // indirect + golang.org/x/sys v0.22.0 // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect gopkg.in/guregu/null.v2 v2.1.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - pgregory.net/rapid v0.5.5 // indirect + pgregory.net/rapid v1.1.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index eeb48f39e6..1c4f247f0e 100644 --- a/go.sum +++ b/go.sum @@ -4,51 +4,33 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= -cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= -cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= -cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= -cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= -cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= -cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw= -cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= -cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= +cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= +cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo= @@ -57,14 +39,14 @@ cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= -cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= -cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= -cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= -cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= -cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca h1:msenprh2BLLRwNT7zN56TbBHOGk/7ARQckXHxXyvjoQ= -cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c= -cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= -cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= +cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= +cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= +cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= +cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= +cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= +cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= +cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= +cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -77,7 +59,6 @@ github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo8 github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= @@ -85,10 +66,8 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzS github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= +github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= github.com/CosmWasm/wasmd v0.40.1/go.mod h1:6EOwnv7MpuFaEqxcUOdFV9i4yvrdOciaY6VQ1o7A3yg= github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= @@ -100,7 +79,6 @@ github.com/Depado/ginprom v1.8.0 h1:zaaibRLNI1dMiiuj1MKzatm8qrcHzikMlCc1anqOdyo= github.com/Depado/ginprom v1.8.0/go.mod h1:XBaKzeNBqPF4vxJpNLincSQZeMDnZp1tIbU0FU0UKgg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= @@ -120,17 +98,13 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= -github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -156,7 +130,6 @@ github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -219,35 +192,29 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= -github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= -github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/errors v1.10.0 h1:lfxS8zZz1+OjtV4MtNWgboi/W5tyLEB6VQZBXN+0VUU= +github.com/cockroachdb/errors v1.10.0/go.mod h1:lknhIsEVQ9Ss/qKDBQS/UqFSvPQjOwNq2qyKAxtHRqE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= -github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= -github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= -github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= -github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= +github.com/cometbft/cometbft v0.37.5 h1:/U/TlgMh4NdnXNo+YU9T2NMCWyhXNDF34Mx582jlvq0= +github.com/cometbft/cometbft v0.37.5/go.mod h1:QC+mU0lBhKn8r9qvmnq53Dmf3DWBt4VtkcKw2C81wxY= +github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= +github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -268,10 +235,10 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= -github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.47.4 h1:FVUpEprm58nMmBX4xkRdMDaIG5Nr4yy92HZAfGAw9bg= -github.com/cosmos/cosmos-sdk v0.47.4/go.mod h1:R5n+uM7vguVPFap4pgkdvQCT1nVo/OtPwrlAU40rvok= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= +github.com/cosmos/cosmos-sdk v0.47.11 h1:0Qx7eORw0RJqPv+mvDuU8NQ1LV3nJJKJnPoYblWHolc= +github.com/cosmos/cosmos-sdk v0.47.11/go.mod h1:ADjORYzUQqQv/FxDi0H0K5gW/rAk1CiDR3ZKsExfJV0= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -279,14 +246,14 @@ github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiK github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= -github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= -github.com/cosmos/ibc-go/v7 v7.0.1 h1:NIBNRWjlOoFvFQu1ZlgwkaSeHO5avf4C1YQiWegt8jw= -github.com/cosmos/ibc-go/v7 v7.0.1/go.mod h1:vEaapV6nuLPQlS+g8IKmxMo6auPi0i7HMv1PhViht/E= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= -github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= -github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/iavl v0.20.1 h1:rM1kqeG3/HBT85vsZdoSNsehciqUQPWrR4BYmqE2+zg= +github.com/cosmos/iavl v0.20.1/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/ibc-go/v7 v7.5.1 h1:KqS/g7W7EMX1OtOvufS8lWMJibOKpdgtNNZIU6fAgVU= +github.com/cosmos/ibc-go/v7 v7.5.1/go.mod h1:ktFg5GvKOyrGCqTWtW7Grj5uweU4ZapxrNeVS1CLLbo= +github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= +github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= +github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw= +github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M= github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -302,10 +269,6 @@ github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJF github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= -github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= -github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= -github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -326,7 +289,6 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFM github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70/go.mod h1:EoK/8RFbMEteaCaz89uessDTnCWjbbcr+DXcBh4el5o= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= @@ -350,34 +312,22 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo= github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/esote/minmaxheap v1.0.0 h1:rgA7StnXXpZG6qlM0S7pUmEv1KpWe32rYT4x8J8ntaA= github.com/esote/minmaxheap v1.0.0/go.mod h1:Ln8+i7fS1k3PLgZI2JAo0iA1as95QnIYiGCrqSJ5FZk= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= github.com/ethereum/go-ethereum v1.13.8/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -389,8 +339,8 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE= github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= @@ -403,16 +353,14 @@ github.com/gagliardetto/solana-go v1.8.4 h1:vmD/JmTlonyXGy39bAo0inMhmbdAwV7rXZtL github.com/gagliardetto/solana-go v1.8.4/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.19.0 h1:BcCH3CN5tXt5aML+gwmbFwVptLLQA+eT866fCO9wVOM= -github.com/getsentry/sentry-go v0.19.0/go.mod h1:y3+lGEFEFexZtpbG1GUE2WD/f9zGyKYwpEqryTOC/nE= +github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE= +github.com/getsentry/sentry-go v0.23.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= @@ -431,8 +379,6 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -459,7 +405,6 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -484,9 +429,6 @@ github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6l github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= @@ -498,12 +440,8 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= @@ -521,9 +459,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -531,7 +467,6 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -551,7 +486,6 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -560,18 +494,14 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= @@ -579,8 +509,6 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -588,11 +516,6 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= @@ -610,9 +533,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA= -github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= +github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -625,14 +547,13 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= -github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= +github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= +github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= @@ -648,8 +569,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= @@ -692,7 +613,6 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= @@ -729,13 +649,11 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -743,11 +661,6 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -823,29 +736,19 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= +github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -859,8 +762,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= @@ -874,6 +775,8 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= +github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= @@ -889,12 +792,9 @@ github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9 github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -902,11 +802,11 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -915,14 +815,11 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= @@ -959,16 +856,11 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -986,7 +878,6 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -1032,7 +923,6 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -1072,8 +962,6 @@ github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= -github.com/regen-network/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= @@ -1088,7 +976,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= @@ -1098,24 +985,25 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= -github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= @@ -1139,18 +1027,18 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 h1:KKqMibl8CcKSyrSkVVfgGEOuC6Cn3vFQK8yMQA6FpxA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92/go.mod h1:wl0SRmyJ2ARxz+4Eho6nEXsmWFXxTSYpvcb30AxwKyE= +github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= +github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa/go.mod h1:wZvLHX/Sd9hskN51016cTFcT3G62KXVa6xbVDS7tRjc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= @@ -1168,12 +1056,14 @@ github.com/smartcontractkit/wsrpc v0.7.3/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgq github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= @@ -1183,16 +1073,14 @@ github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= -github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= @@ -1219,14 +1107,12 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= @@ -1257,10 +1143,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2 github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= @@ -1278,14 +1162,10 @@ github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE= github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -1293,31 +1173,23 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= -github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= -github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= +github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= +github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= @@ -1345,10 +1217,10 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/contrib/propagators/b3 v1.24.0 h1:n4xwCdTx3pZqZs2CjS/CUZAs03y3dZcGhC/FepKtEUY= go.opentelemetry.io/contrib/propagators/b3 v1.24.0/go.mod h1:k5wRxKRU2uXx2F8uNJ4TaonuEO/V7/5xoz7kdsDACT8= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= @@ -1361,8 +1233,8 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= -go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= +go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= +go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -1397,8 +1269,8 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= -golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= +golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1407,27 +1279,22 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1438,8 +1305,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1453,7 +1320,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1462,13 +1328,11 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1479,44 +1343,30 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -1524,19 +1374,15 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1544,14 +1390,12 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1589,45 +1433,30 @@ golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1636,8 +1465,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1646,8 +1475,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1661,22 +1490,19 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1709,33 +1535,16 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1755,27 +1564,16 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= -google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= +google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= +google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1795,37 +1593,18 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= -google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= -google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= -google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1838,15 +1617,9 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1857,7 +1630,6 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -1881,10 +1653,8 @@ gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1900,21 +1670,19 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= -gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= @@ -1935,8 +1703,8 @@ modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= -pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 783be44031..d044255c93 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -1,4 +1,4 @@ -module github.com/smartcontractkit/chainlink/integration-tests +module github.com/smartcontractkit/ccip/integration-tests go 1.22.5 @@ -8,18 +8,16 @@ replace github.com/smartcontractkit/chainlink/v2 => ../ require ( dario.cat/mergo v1.0.0 github.com/AlekSi/pointer v1.1.0 - github.com/Khan/genqlient v0.7.0 github.com/Masterminds/semver/v3 v3.2.1 github.com/avast/retry-go/v4 v4.6.0 github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df - github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a + github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f github.com/cli/go-gh/v2 v2.0.0 github.com/ethereum/go-ethereum v1.13.8 - github.com/fxamacker/cbor/v2 v2.7.0 + github.com/fxamacker/cbor/v2 v2.6.0 github.com/go-resty/resty/v2 v2.11.0 github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 - github.com/hashicorp/consul/sdk v0.16.0 github.com/jmoiron/sqlx v1.4.0 github.com/lib/pq v1.10.9 github.com/manifoldco/promptui v0.9.0 @@ -28,23 +26,23 @@ require ( github.com/pelletier/go-toml/v2 v2.2.2 github.com/pkg/errors v0.9.1 github.com/prometheus/common v0.55.0 - github.com/rs/zerolog v1.33.0 + github.com/rs/zerolog v1.32.0 github.com/scylladb/go-reflectx v1.0.1 github.com/segmentio/ksuid v1.0.4 github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 - github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 - github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe - github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 - github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 - github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 - github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 + github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 + github.com/smartcontractkit/chainlink-testing-framework v1.32.7 + github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 + github.com/smartcontractkit/chainlink/integration-tests v0.0.0-00010101000000-000000000000 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 + github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/spf13/cobra v1.8.1 + github.com/smartcontractkit/seth v1.0.12 + github.com/smartcontractkit/wasp v0.4.5 + github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.9.0 github.com/test-go/testify v1.1.4 github.com/testcontainers/testcontainers-go v0.28.0 @@ -52,15 +50,14 @@ require ( go.uber.org/atomic v1.11.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.26.0 - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa - golang.org/x/sync v0.8.0 - golang.org/x/text v0.17.0 - google.golang.org/grpc v1.65.0 - google.golang.org/protobuf v1.34.2 + golang.org/x/crypto v0.25.0 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 + golang.org/x/sync v0.7.0 + golang.org/x/text v0.16.0 gopkg.in/guregu/null.v4 v4.0.0 - gotest.tools/v3 v3.5.1 - k8s.io/apimachinery v0.31.0 + gopkg.in/yaml.v2 v2.4.0 + gopkg.in/yaml.v3 v3.0.1 + k8s.io/apimachinery v0.28.2 ) // avoids ambigious imports of indirect dependencies @@ -86,46 +83,29 @@ require ( github.com/CosmWasm/wasmd v0.40.1 // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect + github.com/K-Phoen/grabana v0.22.1 // indirect + github.com/K-Phoen/sdk v0.12.4 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/Microsoft/hcsshim v0.11.5 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/hcsshim v0.11.4 // indirect github.com/NethermindEth/juno v0.3.1 // indirect github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/XSAM/otelsql v0.27.0 // indirect - github.com/agnivade/levenshtein v1.1.1 // indirect github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect - github.com/alexflint/go-arg v1.4.2 // indirect - github.com/alexflint/go-scalar v1.0.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/avast/retry-go v3.0.0+incompatible // indirect - github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect github.com/aws/aws-sdk-go v1.45.25 // indirect - github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect - github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.28 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 // indirect github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect github.com/aws/jsii-runtime-go v1.75.0 // indirect - github.com/aws/smithy-go v1.20.4 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect github.com/blendle/zapdriver v1.3.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/buger/jsonparser v1.1.1 // indirect @@ -152,8 +132,7 @@ require ( github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/containerd/containerd v1.7.18 // indirect - github.com/containerd/errdefs v0.1.0 // indirect + github.com/containerd/containerd v1.7.12 // indirect github.com/containerd/log v0.1.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect @@ -179,7 +158,7 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/distribution/reference v0.6.0 // indirect + github.com/distribution/reference v0.5.0 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v25.0.2+incompatible // indirect github.com/docker/go-connections v0.5.0 // indirect @@ -191,6 +170,7 @@ require ( github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/esote/minmaxheap v1.0.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect @@ -198,7 +178,8 @@ require ( github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/fvbommel/sortorder v1.1.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/solana-go v1.8.4 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect @@ -217,7 +198,7 @@ require ( github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.3.0 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.4 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect @@ -229,7 +210,7 @@ require ( github.com/go-openapi/validate v0.22.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.22.0 // indirect + github.com/go-playground/validator/v10 v10.15.5 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect @@ -250,31 +231,34 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect + github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/context v1.1.1 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/sessions v1.2.2 // indirect github.com/gorilla/websocket v1.5.1 // indirect + github.com/gosimple/slug v1.13.1 // indirect + github.com/gosimple/unidecode v1.0.1 // indirect github.com/grafana/dskit v0.0.0-20231120170505-765e343eda4f // indirect github.com/grafana/gomemcache v0.0.0-20231023152154-6947259a0586 // indirect github.com/grafana/grafana-foundation-sdk/go v0.0.0-20240326122733-6f96a993222b // indirect github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 // indirect github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect - github.com/grafana/pyroscope-go v1.1.2 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect + github.com/grafana/pyroscope-go v1.1.1 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect - github.com/hashicorp/consul/api v1.28.2 // indirect + github.com/hashicorp/consul/api v1.25.1 // indirect + github.com/hashicorp/consul/sdk v0.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-envparse v0.1.0 // indirect @@ -319,13 +303,13 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.3 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a // indirect - github.com/leodido/go-urn v1.4.0 // indirect + github.com/leodido/go-urn v1.2.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/linxGnu/grocksdb v1.7.16 // indirect @@ -361,13 +345,11 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/mwitkow/grpc-proxy v0.0.0-20230212185441-f345521cb9c9 // indirect - github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/oklog/run v1.1.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/opencontainers/runc v1.1.7 // indirect + github.com/opencontainers/image-spec v1.1.0-rc5 // indirect github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e // indirect github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect @@ -402,22 +384,22 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect - github.com/smartcontractkit/wsrpc v0.8.1 // indirect + github.com/smartcontractkit/wsrpc v0.7.3 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.19.0 // indirect + github.com/spf13/viper v1.18.2 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect @@ -440,7 +422,6 @@ require ( github.com/ugorji/go/codec v1.2.12 // indirect github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 // indirect github.com/valyala/fastjson v1.4.1 // indirect - github.com/vektah/gqlparser/v2 v2.5.11 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect @@ -449,16 +430,16 @@ require ( github.com/zondax/ledger-go v0.14.3 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect - go.etcd.io/bbolt v1.3.9 // indirect - go.etcd.io/etcd/api/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/v3 v3.5.14 // indirect + go.etcd.io/bbolt v1.3.8 // indirect + go.etcd.io/etcd/api/v3 v3.5.10 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect + go.etcd.io/etcd/client/v3 v3.5.10 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 // indirect go.opentelemetry.io/collector/semconv v0.87.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect @@ -470,47 +451,85 @@ require ( go.uber.org/goleak v1.3.0 // indirect go.uber.org/ratelimit v0.3.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect - golang.org/x/arch v0.8.0 // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/arch v0.7.0 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/term v0.22.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.23.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/grpc v1.65.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.31.0 // indirect - k8s.io/apiextensions-apiserver v0.31.0 // indirect - k8s.io/cli-runtime v0.31.0 // indirect - k8s.io/client-go v0.31.0 // indirect - k8s.io/component-base v0.31.0 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.28.1 // indirect + k8s.io/cli-runtime v0.28.2 // indirect + k8s.io/client-go v0.28.2 // indirect + k8s.io/component-base v0.28.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect - k8s.io/kubectl v0.31.0 // indirect - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect - nhooyr.io/websocket v1.8.10 // indirect + k8s.io/kubectl v0.28.1 // indirect + k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect + nhooyr.io/websocket v1.8.7 // indirect pgregory.net/rapid v1.1.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect - sigs.k8s.io/controller-runtime v0.19.0 // indirect + sigs.k8s.io/controller-runtime v0.16.2 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.17.2 // indirect - sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect + sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) exclude github.com/chaos-mesh/chaos-mesh/api/v1alpha1 v0.0.0-20220226050744-799408773657 +replace ( + github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/common => github.com/prometheus/common v0.42.0 +) + +replace ( + k8s.io/api => k8s.io/api v0.28.2 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.28.2 + k8s.io/apimachinery => k8s.io/apimachinery v0.28.2 + k8s.io/apiserver => k8s.io/apiserver v0.28.2 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.28.2 + k8s.io/client-go => k8s.io/client-go v0.28.2 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.28.2 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.28.2 + k8s.io/code-generator => k8s.io/code-generator v0.28.2 + k8s.io/component-base => k8s.io/component-base v0.28.2 + k8s.io/component-helpers => k8s.io/component-helpers v0.28.2 + k8s.io/controller-manager => k8s.io/controller-manager v0.28.2 + k8s.io/cri-api => k8s.io/cri-api v0.28.2 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.28.2 + k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.28.2 + k8s.io/endpointslice => k8s.io/endpointslice v0.28.2 + k8s.io/kms => k8s.io/kms v0.28.2 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.28.2 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.28.2 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.28.2 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.28.2 + k8s.io/kubectl => k8s.io/kubectl v0.28.2 + k8s.io/kubelet => k8s.io/kubelet v0.28.2 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.28.2 + k8s.io/metrics => k8s.io/metrics v0.28.2 + k8s.io/mount-utils => k8s.io/mount-utils v0.28.2 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.28.2 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.28.2 + k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.28.2 + k8s.io/sample-controller => k8s.io/sample-controller v0.28.2 + sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.16.2 +) + replace ( github.com/go-kit/log => github.com/go-kit/log v0.2.1 @@ -525,9 +544,6 @@ replace ( // type func(a Label, b Label) bool of func(a, b Label) bool {…} does not match inferred type func(a Label, b Label) int for func(a E, b E) int github.com/prometheus/prometheus => github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 -) -replace ( - github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.14.0 - github.com/prometheus/common => github.com/prometheus/common v0.42.0 + github.com/smartcontractkit/chainlink/integration-tests => ../integration-tests ) diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 745644e1bb..ad987028f9 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -14,27 +14,23 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= -cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= -cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= -cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= -cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= -cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.27.2 h1:5cE5hdrwJV/92ravlwIFRGnyH9CpLGhh4N0ZDVTU+BA= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= -cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw= -cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -44,8 +40,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= -cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= +cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= +cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo= @@ -125,8 +121,10 @@ github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= -github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= +github.com/K-Phoen/grabana v0.22.1 h1:b/O+C3H2H6VNYSeMCYUO4X4wYuwFXgBcRkvYa+fjpQA= +github.com/K-Phoen/grabana v0.22.1/go.mod h1:3LTXrTzQzTKTgvKSXdRjlsJbizSOW/V23Q3iX00R5bU= +github.com/K-Phoen/sdk v0.12.4 h1:j2EYuBJm3zDTD0fGKACVFWxAXtkR0q5QzfVqxmHSeGQ= +github.com/K-Phoen/sdk v0.12.4/go.mod h1:qmM0wO23CtoDux528MXPpYvS4XkRWkWX6rvX9Za8EVU= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -137,10 +135,10 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0 github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.11.5 h1:haEcLNpj9Ka1gd3B3tAEs9CpE0c+1IhoL59w/exYU38= -github.com/Microsoft/hcsshim v0.11.5/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= +github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= github.com/NethermindEth/juno v0.3.1 h1:AW72LiAm9gqUeCVJWvepnZcTnpU4Vkl0KzPMxS+42FA= github.com/NethermindEth/juno v0.3.1/go.mod h1:SGbTpgGaCsxhFsKOid7Ylnz//WZ8swtILk+NbHGsk/Q= github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb h1:Mv8SscePPyw2ju4igIJAjFgcq5zCQfjgbz53DwYu5mc= @@ -160,8 +158,6 @@ github.com/Workiva/go-datastructures v1.1.0 h1:hu20UpgZneBhQ3ZvwiOGlqJSKIosin2Rd github.com/Workiva/go-datastructures v1.1.0/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= -github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= -github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -170,10 +166,6 @@ github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrI github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= -github.com/alexflint/go-arg v1.4.2 h1:lDWZAXxpAnZUq4qwb86p/3rIJJ2Li81EoMbTMujhVa0= -github.com/alexflint/go-arg v1.4.2/go.mod h1:9iRbDxne7LcR/GSvEr7ma++GLpdIU1zrghf2y2768kM= -github.com/alexflint/go-scalar v1.0.0 h1:NGupf1XV/Xb04wXskDFzS0KWOLH632W/EO4fAFi+A70= -github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis v2.5.0+incompatible h1:yBHoLpsyjupjz3NL3MhKMVkR41j82Yjf3KFv7ApYzUI= @@ -183,11 +175,7 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= -github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -204,45 +192,15 @@ github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHS github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= -github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= -github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8= -github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= -github.com/aws/aws-sdk-go-v2/config v1.27.28 h1:OTxWGW/91C61QlneCtnD62NLb4W616/NM1jA8LhJqbg= -github.com/aws/aws-sdk-go-v2/config v1.27.28/go.mod h1:uzVRVtJSU5EFv6Fu82AoVFKozJi2ZCY6WRCXj06rbvs= -github.com/aws/aws-sdk-go-v2/credentials v1.17.28 h1:m8+AHY/ND8CMHJnPoH7PJIRakWGa4gbfbxuY9TGTUXM= -github.com/aws/aws-sdk-go-v2/credentials v1.17.28/go.mod h1:6TF7dSc78ehD1SL6KpRIPKMA1GyyWflIkjqg+qmf4+c= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 h1:yjwoSyDZF8Jth+mUk5lSPJCkMC0lMy6FaCD51jm6ayE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12/go.mod h1:fuR57fAgMk7ot3WcNQfb6rSEn+SUffl7ri+aa8uKysI= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 h1:UDXu9dqpCZYonj7poM4kFISjzTdWI0v3WUusM+w+Gfc= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5/go.mod h1:5NPkI3RsTOhwz1CuG7VVSgJCm3CINKkoIaUbUZWQ67w= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.5/go.mod h1:ZeDX1SnKsVlejeuz41GiajjZpRSWR7/42q/EyA/QEiM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 h1:SKvPgvdvmiTWoi0GAJ7AsJfOz3ngVkD/ERbs5pUnHNI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5/go.mod h1:20sz31hv/WsPa3HhU3hfrIet2kxM4Pe0r20eBZ20Tac= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 h1:iAckBT2OeEK/kBDyN/jDtpEExhjeeA/Im2q4X0rJZT8= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.4/go.mod h1:vmSqFK+BVIwVpDAGZB3CoCXHzurt4qBE8lf+I/kRTh0= github.com/aws/constructs-go/constructs/v10 v10.1.255 h1:5hARfEmhBqHSTQf/C3QLA3sWOxO2Dfja0iA1W7ZcI7g= github.com/aws/constructs-go/constructs/v10 v10.1.255/go.mod h1:DCdBSjN04Ck2pajCacTD4RKFqSA7Utya8d62XreYctI= github.com/aws/jsii-runtime-go v1.75.0 h1:NhpUfyiL7/wsRuUekFsz8FFBCYLfPD/l61kKg9kL/a4= github.com/aws/jsii-runtime-go v1.75.0/go.mod h1:TKCyrtM0pygEPo4rDZzbMSDNCDNTSYSN6/mGyHI6O3I= -github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= -github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= @@ -260,12 +218,8 @@ github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsy github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= -github.com/bradleyjkemp/cupaloy/v2 v2.6.0 h1:knToPYa2xtfg42U3I6punFEjaGFKWQRXJwj0JTv4mTs= -github.com/bradleyjkemp/cupaloy/v2 v2.6.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= @@ -305,8 +259,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= -github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a h1:6Pg3a6j/41QDzH/oYcMLwwKsf3x/HXcu9W/dBaf2Hzs= -github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a/go.mod h1:x11iCbZV6hzzSQWMq610B6Wl5Lg1dhwqcVfeiWQQnQQ= +github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f h1:onZ3oc6l1Gz8pVpQ0c1U1Cb11kIMoDb3xtEy/iZbYZM= +github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f/go.mod h1:x11iCbZV6hzzSQWMq610B6Wl5Lg1dhwqcVfeiWQQnQQ= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= @@ -363,12 +317,10 @@ github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/Yj github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao= -github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4= +github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= +github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= -github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= -github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -412,8 +364,8 @@ github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHf github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= @@ -457,12 +409,10 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= -github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E= github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA= -github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= -github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= @@ -527,10 +477,12 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= +github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= +github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= @@ -558,6 +510,7 @@ github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibO github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= @@ -585,11 +538,10 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= -github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= +github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= -github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= @@ -625,14 +577,18 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= -github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= +github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= @@ -676,6 +632,15 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= +github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -782,8 +747,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= @@ -792,6 +757,7 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -799,8 +765,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= -github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= +github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= +github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= github.com/gophercloud/gophercloud v1.5.0 h1:cDN6XFCLKiiqvYpjQLq9AiM7RDRbIC9450WpPH+yvXo= github.com/gophercloud/gophercloud v1.5.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -815,9 +781,14 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gosimple/slug v1.13.1 h1:bQ+kpX9Qa6tHRaK+fZR0A0M2Kd7Pa5eHPPsb1JpHD+Q= +github.com/gosimple/slug v1.13.1/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= +github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= +github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= github.com/grafana/dskit v0.0.0-20231120170505-765e343eda4f h1:gyojr97YeWZ70pKNakWv5/tKwBHuLy3icnIeCo9gQr4= github.com/grafana/dskit v0.0.0-20231120170505-765e343eda4f/go.mod h1:8dsy5tQOkeNQyjXpm5mQsbCu3H5uzeBD35MzRQFznKU= github.com/grafana/gomemcache v0.0.0-20231023152154-6947259a0586 h1:/of8Z8taCPftShATouOrBVy6GaTTjgQd/VfNiZp/VXQ= @@ -828,10 +799,10 @@ github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 h1:gdrsYbmk8822v6qv github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503/go.mod h1:d8seWXCEXkL42mhuIJYcGi6DxfehzoIpLrMQWJojvOo= github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 h1:wQ0FnSeebhJIBkgYOD06Mxk9HV2KhtEG0hp/7R+5RUQ= github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0= -github.com/grafana/pyroscope-go v1.1.2 h1:7vCfdORYQMCxIzI3NlYAs3FcBP760+gWuYWOyiVyYx8= -github.com/grafana/pyroscope-go v1.1.2/go.mod h1:HSSmHo2KRn6FasBA4vK7BMiQqyQq8KSuBKvrhkXxYPU= -github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= -github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= +github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= +github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= +github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= +github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= @@ -851,8 +822,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= @@ -862,8 +833,8 @@ github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/b github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.28.2 h1:mXfkRHrpHN4YY3RqL09nXU1eHKLNiuAN4kHvDQ16k/8= -github.com/hashicorp/consul/api v1.28.2/go.mod h1:KyzqzgMEya+IZPcD65YFoOVAgPpbfERu4I/tzG6/ueE= +github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE= +github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.16.0 h1:SE9m0W6DEfgIVCJX7xU+iv/hUl4m/nxqMTnCdMxDpJ8= github.com/hashicorp/consul/sdk v0.16.0/go.mod h1:7pxqqhqoaPqnBnzXD1StKed62LqJeClzVsUEy85Zr0A= @@ -1042,6 +1013,7 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -1055,11 +1027,12 @@ github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dv github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= +github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -1082,8 +1055,9 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= -github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -1098,8 +1072,6 @@ github.com/linode/linodego v1.19.0 h1:n4WJrcr9+30e9JGZ6DI0nZbm5SdAj1kSwvvt/998YU github.com/linode/linodego v1.19.0/go.mod h1:XZFR+yJ9mm2kwf6itZ6SCpu+6w3KnIevV0Uu5HNWJgQ= github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= -github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= -github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= @@ -1204,6 +1176,7 @@ github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= @@ -1228,8 +1201,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE= @@ -1249,8 +1220,8 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= +github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= @@ -1259,10 +1230,10 @@ github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= -github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= +github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= +github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= +github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo= github.com/opentracing-contrib/go-stdlib v1.0.0 h1:TBS7YuVotp8myLon4Pv7BtCBzOTo1DeZCld0Z63mW2w= @@ -1336,6 +1307,10 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 h1:6ksZ7t1hNOzGPPs8DK7SvXQf6UfWzi+W5Z7PCBl8gx4= github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510/go.mod h1:UC0TwJiF90m2T3iYPQBKnGu8gv3s55dF/EgpTq8gyvo= +github.com/pyroscope-io/client v0.7.1 h1:yFRhj3vbgjBxehvxQmedmUWJQ4CAfCHhn+itPsuWsHw= +github.com/pyroscope-io/client v0.7.1/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU= +github.com/pyroscope-io/godeltaprof v0.1.2 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4= +github.com/pyroscope-io/godeltaprof v0.1.2/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= @@ -1361,8 +1336,8 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= -github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -1413,48 +1388,46 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 h1:jakAsdhDxV4cMgRAcSvHraXjyePi8umG5SEUTGFvuy8= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685/go.mod h1:p7L/xNEQpHDdZtgFA6/FavuZHqvV3kYhQysxBywmq1k= github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1WonwhVOPtOStpqTmLC4E= github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 h1:KKqMibl8CcKSyrSkVVfgGEOuC6Cn3vFQK8yMQA6FpxA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92/go.mod h1:wl0SRmyJ2ARxz+4Eho6nEXsmWFXxTSYpvcb30AxwKyE= +github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= +github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa/go.mod h1:wZvLHX/Sd9hskN51016cTFcT3G62KXVa6xbVDS7tRjc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe h1:5EaoT0jYlmubsDawLVLgPxgEWG7IPxjuxJP3cJ1wRzw= -github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 h1:1/r1wQZ4TOFpZ13w94r7amdF096Z96RuEnkOmrz1BGE= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= -github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= -github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 h1:ItZ75xmt+VHR/lw+GJwSWj9XICpgZ94dJ+I/5jdet7c= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= -github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= -github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= +github.com/smartcontractkit/chainlink-testing-framework v1.32.7 h1:/I6Upq9KdnleWnUF1W3c3mAgMowAgi0yAcn8Vh5Px50= +github.com/smartcontractkit/chainlink-testing-framework v1.32.7/go.mod h1:Y1D6k7KLPZ52kwp3WJxShp4Wzw22jKldIzMT2yosipI= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= +github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1:ZEhn2Yo1jY4hqy8nasDL4k4pNtopT3rS3Ap1GDb7ODc= +github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= +github.com/smartcontractkit/seth v1.0.12 h1:iVdgMx42XWanPPnBaM5StR4c1XsTr/0/B/kKRZL5BsY= +github.com/smartcontractkit/seth v1.0.12/go.mod h1:thWtbLyW4nRHJGzC5heknQDORoJPErE15sF34LHkorg= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= -github.com/smartcontractkit/wsrpc v0.8.1 h1:kk0SXLqWrWaZ3J6c7n8D0NZ2uTMBBBpG5dZZXZX8UGE= -github.com/smartcontractkit/wsrpc v0.8.1/go.mod h1:yfg8v8fPLXkb6Mcnx6Pm/snP6jJ0r5Kf762Yd1a/KpA= +github.com/smartcontractkit/wasp v0.4.5 h1:pgiXwBci2m15eo33AzspzhpNG/gxg+8QGxl+I5LpfsQ= +github.com/smartcontractkit/wasp v0.4.5/go.mod h1:eVhBVLbVv0qORUlN7aR5C4aTN/lTYO3KnN1erO4ROOI= +github.com/smartcontractkit/wsrpc v0.7.3 h1:CKYZfawZShZGfvsQep1F9oBansnFk9ByZPCdTMpLphw= +github.com/smartcontractkit/wsrpc v0.7.3/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1477,8 +1450,8 @@ github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cA github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -1486,8 +1459,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= -github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= @@ -1509,6 +1482,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -1556,7 +1530,9 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= @@ -1577,8 +1553,6 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE= github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= -github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= @@ -1623,14 +1597,14 @@ go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRL go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= -go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= -go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= -go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= -go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= -go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= -go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= -go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= +go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= +go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= +go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= +go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= +go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= +go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= @@ -1652,10 +1626,10 @@ go.opentelemetry.io/collector/semconv v0.87.0 h1:BsG1jdLLRCBRlvUujk4QA86af7r/ZXn go.opentelemetry.io/collector/semconv v0.87.0/go.mod h1:j/8THcqVxFna1FpvA2zYIsUperEtOaRaqoLYIN4doWw= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= @@ -1668,8 +1642,8 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= -go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= +go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= +go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -1702,13 +1676,14 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= -golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= +golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1736,8 +1711,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1748,8 +1723,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1774,8 +1749,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1831,8 +1806,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1840,8 +1815,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1856,8 +1831,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1945,8 +1920,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1958,8 +1933,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1973,14 +1948,14 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -2042,8 +2017,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2072,8 +2047,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= -google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= +google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= +google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2118,12 +2093,12 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= -google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= -google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= -google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -2168,8 +2143,6 @@ gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= @@ -2198,6 +2171,7 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2208,28 +2182,28 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= -k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= -k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= -k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= -k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc= -k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/cli-runtime v0.31.0 h1:V2Q1gj1u3/WfhD475HBQrIYsoryg/LrhhK4RwpN+DhA= -k8s.io/cli-runtime v0.31.0/go.mod h1:vg3H94wsubuvWfSmStDbekvbla5vFGC+zLWqcf+bGDw= -k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8= -k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= -k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs= -k8s.io/component-base v0.31.0/go.mod h1:TYVuzI1QmN4L5ItVdMSXKvH7/DtvIuas5/mm8YT3rTo= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/cli-runtime v0.28.2 h1:64meB2fDj10/ThIMEJLO29a1oujSm0GQmKzh1RtA/uk= +k8s.io/cli-runtime v0.28.2/go.mod h1:bTpGOvpdsPtDKoyfG4EG041WIyFZLV9qq4rPlkyYfDA= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/component-base v0.28.2 h1:Yc1yU+6AQSlpJZyvehm/NkJBII72rzlEsd6MkBQ+G0E= +k8s.io/component-base v0.28.2/go.mod h1:4IuQPQviQCg3du4si8GpMrhAIegxpsgPngPRR/zWpzc= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f h1:2sXuKesAYbRHxL3aE2PN6zX/gcJr22cjrsej+W784Tc= k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= -k8s.io/kubectl v0.31.0 h1:kANwAAPVY02r4U4jARP/C+Q1sssCcN/1p9Nk+7BQKVg= -k8s.io/kubectl v0.31.0/go.mod h1:pB47hhFypGsaHAPjlwrNbvhXgmuAr01ZBvAIIUaI8d4= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= -nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= +k8s.io/kubectl v0.28.2 h1:fOWOtU6S0smdNjG1PB9WFbqEIMlkzU5ahyHkc7ESHgM= +k8s.io/kubectl v0.28.2/go.mod h1:6EQWTPySF1fn7yKoQZHYf9TPwIl2AygHEcJoxFekr64= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= @@ -2239,14 +2213,14 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= -sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= -sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= +sigs.k8s.io/controller-runtime v0.16.2 h1:mwXAVuEk3EQf478PQwQ48zGOXvW27UJc8NHktQVuIPU= +sigs.k8s.io/controller-runtime v0.16.2/go.mod h1:vpMu3LpI5sYWtujJOa2uPK61nB5rbwlN7BAB8aSLvGU= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= -sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0= -sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= -sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= +sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= +sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= +sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= +sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index c887e800ab..2f647a5a6f 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -13,17 +13,17 @@ require ( github.com/go-resty/resty/v2 v2.11.0 github.com/pelletier/go-toml/v2 v2.2.2 github.com/pkg/errors v0.9.1 - github.com/rs/zerolog v1.33.0 + github.com/rs/zerolog v1.32.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 - github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe - github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 - github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 + github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 + github.com/smartcontractkit/chainlink-testing-framework v1.32.7 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 + github.com/smartcontractkit/seth v1.0.12 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 + github.com/smartcontractkit/wasp v0.4.7 github.com/stretchr/testify v1.9.0 github.com/wiremock/go-wiremock v1.9.0 go.uber.org/ratelimit v0.3.0 @@ -35,35 +35,14 @@ require ( cosmossdk.io/depinject v1.0.0-alpha.4 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/math v1.3.0 // indirect - github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect - github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect - github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.28 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 // indirect - github.com/aws/smithy-go v1.20.4 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect - github.com/containerd/errdefs v0.1.0 // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect - github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 // indirect - github.com/sourcegraph/conc v0.3.0 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect - k8s.io/apimachinery v0.31.0 // indirect + k8s.io/apimachinery v0.30.2 // indirect ) // avoids ambigious imports of indirect dependencies @@ -90,8 +69,8 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/Microsoft/hcsshim v0.11.5 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/hcsshim v0.11.4 // indirect github.com/NethermindEth/juno v0.3.1 // indirect github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect @@ -122,7 +101,7 @@ require ( github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a // indirect + github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect github.com/cockroachdb/errors v1.10.0 // indirect @@ -135,7 +114,7 @@ require ( github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/containerd/containerd v1.7.18 // indirect + github.com/containerd/containerd v1.7.12 // indirect github.com/containerd/continuity v0.4.3 // indirect github.com/containerd/log v0.1.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect @@ -162,7 +141,7 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/distribution/reference v0.6.0 // indirect + github.com/distribution/reference v0.5.0 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v25.0.2+incompatible // indirect github.com/docker/go-connections v0.5.0 // indirect @@ -183,8 +162,8 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/fxamacker/cbor/v2 v2.6.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/solana-go v1.8.4 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect @@ -203,7 +182,7 @@ require ( github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.3.0 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.4 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect @@ -215,7 +194,7 @@ require ( github.com/go-openapi/validate v0.22.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.22.0 // indirect + github.com/go-playground/validator/v10 v10.15.5 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect @@ -236,7 +215,7 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect + github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/context v1.1.1 // indirect @@ -251,19 +230,19 @@ require ( github.com/grafana/grafana-foundation-sdk/go v0.0.0-20240326122733-6f96a993222b // indirect github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 // indirect github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect - github.com/grafana/pyroscope-go v1.1.2 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect + github.com/grafana/pyroscope-go v1.1.1 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect - github.com/hashicorp/consul/api v1.28.2 // indirect + github.com/hashicorp/consul/api v1.25.1 // indirect github.com/hashicorp/consul/sdk v0.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -309,16 +288,17 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.3 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a // indirect - github.com/leodido/go-urn v1.4.0 // indirect + github.com/leodido/go-urn v1.2.4 // indirect github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect + github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -355,7 +335,7 @@ require ( github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc5 // indirect github.com/opencontainers/runc v1.1.10 // indirect github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e // indirect github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect @@ -393,20 +373,22 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect - github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a // indirect + github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 // indirect + github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect - github.com/smartcontractkit/wsrpc v0.8.1 // indirect + github.com/smartcontractkit/wsrpc v0.7.3 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.19.0 // indirect + github.com/spf13/viper v1.18.2 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect @@ -440,16 +422,16 @@ require ( github.com/zondax/ledger-go v0.14.3 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect - go.etcd.io/bbolt v1.3.9 // indirect - go.etcd.io/etcd/api/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/v3 v3.5.14 // indirect + go.etcd.io/bbolt v1.3.8 // indirect + go.etcd.io/etcd/api/v3 v3.5.10 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect + go.etcd.io/etcd/client/v3 v3.5.10 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 // indirect go.opentelemetry.io/collector/semconv v0.87.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect @@ -463,23 +445,23 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect - golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/arch v0.7.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/term v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.23.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/guregu/null.v4 v4.0.0 // indirect @@ -488,22 +470,22 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.31.0 // indirect - k8s.io/apiextensions-apiserver v0.31.0 // indirect - k8s.io/cli-runtime v0.31.0 // indirect + k8s.io/api v0.30.2 // indirect + k8s.io/apiextensions-apiserver v0.30.2 // indirect + k8s.io/cli-runtime v0.28.2 // indirect k8s.io/client-go v1.5.2 // indirect - k8s.io/component-base v0.31.0 // indirect + k8s.io/component-base v0.30.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect - k8s.io/kubectl v0.31.0 // indirect - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect - nhooyr.io/websocket v1.8.10 // indirect + k8s.io/kubectl v0.28.1 // indirect + k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect + nhooyr.io/websocket v1.8.7 // indirect pgregory.net/rapid v1.1.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect - sigs.k8s.io/controller-runtime v0.19.0 // indirect + sigs.k8s.io/controller-runtime v0.18.4 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.17.2 // indirect - sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect + sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect; indirect nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 9f2ad9a92c..d3074dba9f 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -14,27 +14,23 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= -cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= -cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= -cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= -cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= -cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.27.2 h1:5cE5hdrwJV/92ravlwIFRGnyH9CpLGhh4N0ZDVTU+BA= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= -cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw= -cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -44,8 +40,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= -cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= +cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= +cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo= @@ -139,10 +135,10 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0 github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.11.5 h1:haEcLNpj9Ka1gd3B3tAEs9CpE0c+1IhoL59w/exYU38= -github.com/Microsoft/hcsshim v0.11.5/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= +github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= github.com/NethermindEth/juno v0.3.1 h1:AW72LiAm9gqUeCVJWvepnZcTnpU4Vkl0KzPMxS+42FA= github.com/NethermindEth/juno v0.3.1/go.mod h1:SGbTpgGaCsxhFsKOid7Ylnz//WZ8swtILk+NbHGsk/Q= github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb h1:Mv8SscePPyw2ju4igIJAjFgcq5zCQfjgbz53DwYu5mc= @@ -196,45 +192,15 @@ github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHS github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= -github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= -github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8= -github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= -github.com/aws/aws-sdk-go-v2/config v1.27.28 h1:OTxWGW/91C61QlneCtnD62NLb4W616/NM1jA8LhJqbg= -github.com/aws/aws-sdk-go-v2/config v1.27.28/go.mod h1:uzVRVtJSU5EFv6Fu82AoVFKozJi2ZCY6WRCXj06rbvs= -github.com/aws/aws-sdk-go-v2/credentials v1.17.28 h1:m8+AHY/ND8CMHJnPoH7PJIRakWGa4gbfbxuY9TGTUXM= -github.com/aws/aws-sdk-go-v2/credentials v1.17.28/go.mod h1:6TF7dSc78ehD1SL6KpRIPKMA1GyyWflIkjqg+qmf4+c= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 h1:yjwoSyDZF8Jth+mUk5lSPJCkMC0lMy6FaCD51jm6ayE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12/go.mod h1:fuR57fAgMk7ot3WcNQfb6rSEn+SUffl7ri+aa8uKysI= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 h1:UDXu9dqpCZYonj7poM4kFISjzTdWI0v3WUusM+w+Gfc= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5/go.mod h1:5NPkI3RsTOhwz1CuG7VVSgJCm3CINKkoIaUbUZWQ67w= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.5/go.mod h1:ZeDX1SnKsVlejeuz41GiajjZpRSWR7/42q/EyA/QEiM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 h1:SKvPgvdvmiTWoi0GAJ7AsJfOz3ngVkD/ERbs5pUnHNI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5/go.mod h1:20sz31hv/WsPa3HhU3hfrIet2kxM4Pe0r20eBZ20Tac= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 h1:iAckBT2OeEK/kBDyN/jDtpEExhjeeA/Im2q4X0rJZT8= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.4/go.mod h1:vmSqFK+BVIwVpDAGZB3CoCXHzurt4qBE8lf+I/kRTh0= github.com/aws/constructs-go/constructs/v10 v10.1.255 h1:5hARfEmhBqHSTQf/C3QLA3sWOxO2Dfja0iA1W7ZcI7g= github.com/aws/constructs-go/constructs/v10 v10.1.255/go.mod h1:DCdBSjN04Ck2pajCacTD4RKFqSA7Utya8d62XreYctI= github.com/aws/jsii-runtime-go v1.75.0 h1:NhpUfyiL7/wsRuUekFsz8FFBCYLfPD/l61kKg9kL/a4= github.com/aws/jsii-runtime-go v1.75.0/go.mod h1:TKCyrtM0pygEPo4rDZzbMSDNCDNTSYSN6/mGyHI6O3I= -github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= -github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= @@ -252,8 +218,6 @@ github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsy github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= @@ -343,12 +307,10 @@ github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/Yj github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao= -github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4= +github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= +github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= -github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= -github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -439,8 +401,8 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E= github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA= -github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= -github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= @@ -507,10 +469,10 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= +github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= @@ -538,6 +500,7 @@ github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibO github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= @@ -567,9 +530,8 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= -github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= @@ -605,14 +567,18 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= -github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= +github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= @@ -656,6 +622,15 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= +github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -762,8 +737,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= @@ -772,6 +747,7 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -779,8 +755,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= -github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= +github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= +github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= github.com/gophercloud/gophercloud v1.5.0 h1:cDN6XFCLKiiqvYpjQLq9AiM7RDRbIC9450WpPH+yvXo= github.com/gophercloud/gophercloud v1.5.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -795,6 +771,7 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= @@ -812,10 +789,10 @@ github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 h1:gdrsYbmk8822v6qv github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503/go.mod h1:d8seWXCEXkL42mhuIJYcGi6DxfehzoIpLrMQWJojvOo= github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 h1:wQ0FnSeebhJIBkgYOD06Mxk9HV2KhtEG0hp/7R+5RUQ= github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0= -github.com/grafana/pyroscope-go v1.1.2 h1:7vCfdORYQMCxIzI3NlYAs3FcBP760+gWuYWOyiVyYx8= -github.com/grafana/pyroscope-go v1.1.2/go.mod h1:HSSmHo2KRn6FasBA4vK7BMiQqyQq8KSuBKvrhkXxYPU= -github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= -github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= +github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= +github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= +github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= +github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= @@ -835,8 +812,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= @@ -846,8 +823,8 @@ github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/b github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.28.2 h1:mXfkRHrpHN4YY3RqL09nXU1eHKLNiuAN4kHvDQ16k/8= -github.com/hashicorp/consul/api v1.28.2/go.mod h1:KyzqzgMEya+IZPcD65YFoOVAgPpbfERu4I/tzG6/ueE= +github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE= +github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.16.0 h1:SE9m0W6DEfgIVCJX7xU+iv/hUl4m/nxqMTnCdMxDpJ8= github.com/hashicorp/consul/sdk v0.16.0/go.mod h1:7pxqqhqoaPqnBnzXD1StKed62LqJeClzVsUEy85Zr0A= @@ -1024,6 +1001,7 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -1037,11 +1015,12 @@ github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dv github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= +github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -1064,8 +1043,9 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= -github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -1182,6 +1162,7 @@ github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= @@ -1231,8 +1212,8 @@ github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= +github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.10 h1:EaL5WeO9lv9wmS6SASjszOeQdSctvpbu0DdBQBizE40= github.com/opencontainers/runc v1.1.10/go.mod h1:+/R6+KmDlh+hOO8NkjmgkG9Qzvypzk0yXxAPYYR65+M= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg= @@ -1308,6 +1289,10 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 h1:6ksZ7t1hNOzGPPs8DK7SvXQf6UfWzi+W5Z7PCBl8gx4= github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510/go.mod h1:UC0TwJiF90m2T3iYPQBKnGu8gv3s55dF/EgpTq8gyvo= +github.com/pyroscope-io/client v0.7.1 h1:yFRhj3vbgjBxehvxQmedmUWJQ4CAfCHhn+itPsuWsHw= +github.com/pyroscope-io/client v0.7.1/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU= +github.com/pyroscope-io/godeltaprof v0.1.2 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4= +github.com/pyroscope-io/godeltaprof v0.1.2/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= @@ -1333,8 +1318,8 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= -github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -1389,42 +1374,42 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 h1:KKqMibl8CcKSyrSkVVfgGEOuC6Cn3vFQK8yMQA6FpxA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92/go.mod h1:wl0SRmyJ2ARxz+4Eho6nEXsmWFXxTSYpvcb30AxwKyE= +github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= +github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa/go.mod h1:wZvLHX/Sd9hskN51016cTFcT3G62KXVa6xbVDS7tRjc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe h1:5EaoT0jYlmubsDawLVLgPxgEWG7IPxjuxJP3cJ1wRzw= -github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a h1:8GtvGJaGyKzx/ar1yX74GxrzIYWTZVTyv4pYB/1ln8w= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= -github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= -github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 h1:ItZ75xmt+VHR/lw+GJwSWj9XICpgZ94dJ+I/5jdet7c= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= -github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= -github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= +github.com/smartcontractkit/chainlink-testing-framework v1.32.7 h1:/I6Upq9KdnleWnUF1W3c3mAgMowAgi0yAcn8Vh5Px50= +github.com/smartcontractkit/chainlink-testing-framework v1.32.7/go.mod h1:Y1D6k7KLPZ52kwp3WJxShp4Wzw22jKldIzMT2yosipI= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= +github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1:ZEhn2Yo1jY4hqy8nasDL4k4pNtopT3rS3Ap1GDb7ODc= +github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= +github.com/smartcontractkit/seth v1.0.12 h1:iVdgMx42XWanPPnBaM5StR4c1XsTr/0/B/kKRZL5BsY= +github.com/smartcontractkit/seth v1.0.12/go.mod h1:thWtbLyW4nRHJGzC5heknQDORoJPErE15sF34LHkorg= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= -github.com/smartcontractkit/wsrpc v0.8.1 h1:kk0SXLqWrWaZ3J6c7n8D0NZ2uTMBBBpG5dZZXZX8UGE= -github.com/smartcontractkit/wsrpc v0.8.1/go.mod h1:yfg8v8fPLXkb6Mcnx6Pm/snP6jJ0r5Kf762Yd1a/KpA= +github.com/smartcontractkit/wasp v0.4.7 h1:7mKJfwzFbuE8xVLUYtLt7Bjw8q/bmVZRW6Ks8kc1LVM= +github.com/smartcontractkit/wasp v0.4.7/go.mod h1:jeabvyXikb2aNoLQwcZGqaz17efrR8NJhpq4seAmdgs= +github.com/smartcontractkit/wsrpc v0.7.3 h1:CKYZfawZShZGfvsQep1F9oBansnFk9ByZPCdTMpLphw= +github.com/smartcontractkit/wsrpc v0.7.3/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1456,8 +1441,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= -github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= @@ -1479,6 +1464,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -1524,7 +1510,9 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= @@ -1591,14 +1579,14 @@ go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRL go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= -go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= -go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= -go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= -go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= -go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= -go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= -go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= +go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= +go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= +go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= +go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= +go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= +go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= @@ -1620,10 +1608,10 @@ go.opentelemetry.io/collector/semconv v0.87.0 h1:BsG1jdLLRCBRlvUujk4QA86af7r/ZXn go.opentelemetry.io/collector/semconv v0.87.0/go.mod h1:j/8THcqVxFna1FpvA2zYIsUperEtOaRaqoLYIN4doWw= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= @@ -1636,8 +1624,8 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= -go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= +go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= +go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -1670,13 +1658,14 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= -golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= +golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1704,8 +1693,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1716,8 +1705,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1742,8 +1731,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1799,8 +1788,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1808,8 +1797,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1824,8 +1813,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1911,8 +1900,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1924,8 +1913,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1939,14 +1928,14 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -2008,8 +1997,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2038,8 +2027,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= -google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= +google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= +google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2084,12 +2073,12 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= -google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= -google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= -google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -2134,8 +2123,6 @@ gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= @@ -2193,10 +2180,10 @@ k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f h1:2sXuKesAYbRHxL3aE2PN6z k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= k8s.io/kubectl v0.28.2 h1:fOWOtU6S0smdNjG1PB9WFbqEIMlkzU5ahyHkc7ESHgM= k8s.io/kubectl v0.28.2/go.mod h1:6EQWTPySF1fn7yKoQZHYf9TPwIl2AygHEcJoxFekr64= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= -nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= @@ -2210,10 +2197,10 @@ sigs.k8s.io/controller-runtime v0.16.2 h1:mwXAVuEk3EQf478PQwQ48zGOXvW27UJc8NHktQ sigs.k8s.io/controller-runtime v0.16.2/go.mod h1:vpMu3LpI5sYWtujJOa2uPK61nB5rbwlN7BAB8aSLvGU= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= -sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0= -sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= -sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= +sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= +sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= +sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= +sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= From ce8d50e60375212df1cab86c0cf184d0adc53918 Mon Sep 17 00:00:00 2001 From: Xueyuan Zhao Date: Thu, 8 Aug 2024 11:16:15 -0400 Subject: [PATCH 195/432] Change RMN contract typeAndVersion (#1233) ## Motivation Change `typeAndVersion`of RMN contract from `RMN 1.5.0-dev` to `RMN 1.5.0` since the contract is finalized. --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> Co-authored-by: Rens Rooimans --- contracts/src/v0.8/ccip/RMN.sol | 2 +- core/gethwrappers/ccip/generated/arm_contract/arm_contract.go | 2 +- .../generated-wrapper-dependency-versions-do-not-edit.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/src/v0.8/ccip/RMN.sol b/contracts/src/v0.8/ccip/RMN.sol index 424aad8fa5..12ba95e0d2 100644 --- a/contracts/src/v0.8/ccip/RMN.sol +++ b/contracts/src/v0.8/ccip/RMN.sol @@ -32,7 +32,7 @@ contract RMN is IRMN, OwnerIsCreator, ITypeAndVersion { using EnumerableSet for EnumerableSet.AddressSet; // STATIC CONFIG - string public constant override typeAndVersion = "RMN 1.5.0-dev"; + string public constant override typeAndVersion = "RMN 1.5.0"; uint256 private constant MAX_NUM_VOTERS = 16; diff --git a/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go b/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go index e5cb17ded0..3a3ee0a3c0 100644 --- a/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go +++ b/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go @@ -70,7 +70,7 @@ type RMNVoter struct { var ARMContractMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"}],\"name\":\"ReusedCurseId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubjectsMustBeStrictlyIncreasing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"}],\"name\":\"UnauthorizedVoter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnvoteToCurseNoop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VoteToBlessForbiddenDuringActiveGlobalCurse\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VoteToBlessNoop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VoteToCurseNoop\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"AlreadyBlessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"AlreadyVotedToBless\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"CurseLifted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"blockTimestamp\",\"type\":\"uint64\"}],\"name\":\"Cursed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"}],\"name\":\"PermaBlessedCommitStoreAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"}],\"name\":\"PermaBlessedCommitStoreRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"onchainCursesHash\",\"type\":\"bytes28\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"}],\"name\":\"SkippedUnvoteToCurse\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"wasBlessed\",\"type\":\"bool\"}],\"name\":\"TaggedRootBlessVotesReset\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"}],\"name\":\"TaggedRootBlessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"weight\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"remainingAccumulatedWeight\",\"type\":\"uint16\"}],\"name\":\"UnvotedToCurse\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"weight\",\"type\":\"uint8\"}],\"name\":\"VotedToBless\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"weight\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"blockTimestamp\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"}],\"name\":\"VotedToCurse\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"getBlessProgress\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"blessVoteAddrs\",\"type\":\"address[]\"},{\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"blessed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"getCurseProgress\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"curseVoteAddrs\",\"type\":\"address[]\"},{\"internalType\":\"bytes28[]\",\"name\":\"cursesHashes\",\"type\":\"bytes28[]\"},{\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"cursed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCursedSubjectsCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPermaBlessedCommitStores\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"getRecordedCurseRelatedOps\",\"outputs\":[{\"components\":[{\"internalType\":\"enumRMN.RecordedCurseRelatedOpTag\",\"name\":\"tag\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"blockTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"cursed\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"}],\"internalType\":\"structRMN.RecordedCurseRelatedOp[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRecordedCurseRelatedOpsCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16[]\",\"name\":\"subjects\",\"type\":\"bytes16[]\"}],\"name\":\"ownerCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"ownerRemoveThenAddPermaBlessedCommitStores\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot[]\",\"name\":\"taggedRoots\",\"type\":\"tuple[]\"}],\"name\":\"ownerResetBlessVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"}],\"internalType\":\"structRMN.UnvoteToCurseRequest\",\"name\":\"unit\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"forceUnvote\",\"type\":\"bool\"}],\"internalType\":\"structRMN.OwnerUnvoteToCurseRequest[]\",\"name\":\"ownerUnvoteToCurseRequests\",\"type\":\"tuple[]\"}],\"name\":\"ownerUnvoteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"}],\"internalType\":\"structRMN.UnvoteToCurseRequest[]\",\"name\":\"unvoteToCurseRequests\",\"type\":\"tuple[]\"}],\"name\":\"unvoteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot[]\",\"name\":\"taggedRoots\",\"type\":\"tuple[]\"}],\"name\":\"voteToBless\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16[]\",\"name\":\"subjects\",\"type\":\"bytes16[]\"}],\"name\":\"voteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b506040516200596238038062005962833981016040819052620000349162000aff565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000138565b505060408051608081018252600080825260208201819052918101919091526001600160c81b03606082015290506001620000fb81601062000c7d565b82606001516001600160c81b0316901c6001600160c81b0316101562000125576200012562000c99565b506200013181620001e3565b5062000e14565b336001600160a01b03821603620001925760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001ee816200071d565b6200020c576040516306b7c75960e31b815260040160405180910390fd5b602081015160038054604084015161ffff908116620100000263ffffffff199092169316929092179190911790555b60025415620003465760028054600091906200025a9060019062000c7d565b815481106200026d576200026d62000caf565b6000918252602080832060408051608081018252600294850290920180546001600160a01b0390811680855260019092015480821685870190815260ff600160a01b8304811687870152600160a81b909204909116606086015291875260058552828720805465ffffffffffff19169055905116855260099092529220805461ffff191690558054919250908062000309576200030962000cc5565b60008281526020902060026000199092019182020180546001600160a01b031916815560010180546001600160b01b03191690559055506200023b565b60005b81515181101562000403578151805160029190839081106200036f576200036f62000caf565b602090810291909101810151825460018181018555600094855293839020825160029092020180546001600160a01b039283166001600160a01b0319909116178155928201519284018054604084015160609094015160ff908116600160a81b0260ff60a81b1991909516600160a01b026001600160a81b0319909216959093169490941793909317161790550162000349565b50600480546000906200041c9063ffffffff1662000cdb565b82546101009290920a63ffffffff8181021990931691831602179091556004541660005b82515160ff821610156200054157600083600001518260ff16815181106200046c576200046c62000caf565b602090810291909101810151604080516060808201835263ffffffff80891683528385015160ff90811684880190815289821685870190815287516001600160a01b03908116600090815260058b5288812097518854945193518616650100000000000260ff60281b199487166401000000000264ffffffffff1990961691909716179390931791909116939093179094558587015190911683526009909552919020805491909201519092166101000261ffff1990921691909117600117905550620005398162000d01565b905062000440565b506001600160a01b0360005260096020527f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a7805461ffff191660011790556004805463ffffffff4381166401000000000263ffffffff60201b1990921691909117909155604051908216907f8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a990620005db90859062000d23565b60405180910390a26040805160c08101825260048082526001600160401b03421660208301526000928201839052606082018390526080820183905260a08201839052600c80546001808201835591909452825160029094027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018054939490939092849260ff19909216919084908111156200067c576200067c62000dce565b021790555060208201518154604084015160608501516001600160a01b03166a010000000000000000000002600160501b600160f01b031991151569010000000000000000000260ff60481b196001600160401b039095166101000294909416610100600160501b031990931692909217929092179190911617815560808083015160a090930151811c600160801b0292901c919091176001909101555050565b80515160009015806200073257508151516010105b80620007445750602082015161ffff16155b80620007565750604082015161ffff16155b156200076457506000919050565b600080600084600001515160026200077d919062000de4565b6001600160401b0381111562000797576200079762000a24565b604051908082528060200260200182016040528015620007c1578160200160208202803683370190505b50905060005b8551518110156200095457600086600001518281518110620007ed57620007ed62000caf565b6020026020010151905060006001600160a01b031681600001516001600160a01b0316148062000828575060208101516001600160a01b0316155b806200083f575060208101516001600160a01b0316155b8062000858575060208101516001600160a01b03908116145b806200087a5750604081015160ff161580156200087a5750606081015160ff16155b156200088d575060009695505050505050565b8051836200089d84600262000de4565b620008aa90600062000dfe565b81518110620008bd57620008bd62000caf565b6001600160a01b0390921660209283029190910182015281015183620008e584600262000de4565b620008f290600162000dfe565b8151811062000905576200090562000caf565b6001600160a01b03909216602092830291909101909101526040810151620009319060ff168662000dfe565b9450806060015160ff168462000948919062000dfe565b935050600101620007c7565b5060005b8151811015620009f957600082828151811062000979576200097962000caf565b60200260200101519050600082600162000994919062000dfe565b90505b8351811015620009ee57838181518110620009b657620009b662000caf565b60200260200101516001600160a01b0316826001600160a01b031603620009e557506000979650505050505050565b60010162000997565b505060010162000958565b50846020015161ffff16831015801562000a1b5750846040015161ffff168210155b95945050505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b038111828210171562000a5f5762000a5f62000a24565b60405290565b604051608081016001600160401b038111828210171562000a5f5762000a5f62000a24565b604051601f8201601f191681016001600160401b038111828210171562000ab55762000ab562000a24565b604052919050565b80516001600160a01b038116811462000ad557600080fd5b919050565b805160ff8116811462000ad557600080fd5b805161ffff8116811462000ad557600080fd5b6000602080838503121562000b1357600080fd5b82516001600160401b038082111562000b2b57600080fd5b8185019150606080838803121562000b4257600080fd5b62000b4c62000a3a565b83518381111562000b5c57600080fd5b8401601f8101891362000b6e57600080fd5b80518481111562000b835762000b8362000a24565b62000b93878260051b0162000a8a565b818152878101955060079190911b82018701908a82111562000bb457600080fd5b918701915b8183101562000c33576080838c03121562000bd45760008081fd5b62000bde62000a65565b62000be98462000abd565b815262000bf889850162000abd565b89820152604062000c0b81860162000ada565b9082015262000c1c84870162000ada565b818701528652948701946080929092019162000bb9565b83525062000c45905084860162000aec565b8582015262000c576040850162000aec565b6040820152979650505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000c935762000c9362000c67565b92915050565b634e487b7160e01b600052600160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600063ffffffff80831681810362000cf75762000cf762000c67565b6001019392505050565b600060ff821660ff810362000d1a5762000d1a62000c67565b60010192915050565b60006020808352608080840185516060808588015282825180855260a0890191508684019450600093505b8084101562000da157845180516001600160a01b03908116845288820151168884015260408082015160ff9081169185019190915290840151168383015293860193600193909301929085019062000d4e565b509488015161ffff8116604089015294604089015161ffff811660608a0152955098975050505050505050565b634e487b7160e01b600052602160045260246000fd5b808202811582820484141762000c935762000c9362000c67565b8082018082111562000c935762000c9362000c67565b614b3e8062000e246000396000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063631ec73e116100d8578063979986111161008c578063d927f26711610066578063d927f26714610354578063f2fde38b14610374578063f33f28951461038757600080fd5b8063979986111461030b578063ba86a1f01461031e578063bd147ef41461033157600080fd5b806379ba5097116100bd57806379ba5097146102d35780638da5cb5b146102db578063970b8fc21461030357600080fd5b8063631ec73e146102ad5780636ba0526d146102c057600080fd5b8063397796f71161013a5780634102e4f4116101145780634102e4f4146102745780634d61677114610287578063586abe3c1461029a57600080fd5b8063397796f7146102425780633d0cf6101461024a5780633f42ab731461025d57600080fd5b8063181f5a771161016b578063181f5a77146101ba5780632cbc26bb14610203578063328d716c1461022657600080fd5b80630b009be21461018757806315c65588146101a5575b600080fd5b61018f6103a9565b60405161019c9190613e3f565b60405180910390f35b6101b86101b3366004613fdd565b6103ba565b005b6101f66040518060400160405280600d81526020017f524d4e20312e352e302d6465760000000000000000000000000000000000000081525081565b60405161019c9190614083565b6102166102113660046140f0565b6104e6565b604051901515815260200161019c565b600b5467ffffffffffffffff165b60405190815260200161019c565b6102166105b1565b6101b86102583660046141a0565b61068b565b6102656107ff565b60405161019c939291906142b3565b6101b86102823660046142ff565b610929565b610216610295366004614439565b61093d565b6101b86102a8366004614451565b6109cd565b6101b86102bb3660046144fc565b610a87565b6101b86102ce366004614451565b610ca0565b6101b8610d13565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019c565b600c54610234565b6101b86103193660046145d0565b610e10565b6101b861032c3660046145d0565b611368565b61034461033f3660046140f0565b61150d565b60405161019c9493929190614645565b6103676103623660046146b6565b611946565b60405161019c9190614707565b6101b8610382366004614800565b611b68565b61039a610395366004614439565b611b79565b60405161019c9392919061481b565b60606103b56007611de1565b905090565b336000818152600960205260409020805460ff16610421576040517f85412e7f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b60045463ffffffff166000805b85518110156104a757600086828151811061044b5761044b614849565b602002602001015190506000610465858360000151611df5565b905060008061047b6001888b8760008d89611fd6565b91509150801561048d5761048d614878565b85806104965750815b95505050505080600101905061042e565b50806104df576040517ffb106b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b600b5460009067ffffffffffffffff16810361050457506000919050565b7f0100000000000000000000000000000100000000000000000000000000000000600052600a6020527fcf943f0e419056430919a3fdfd72276bc0b123ebdd670f4152b82bffbfb8bb385468010000000000000000900460ff16806105a657507fffffffffffffffffffffffffffffffff0000000000000000000000000000000082166000908152600a602052604090205468010000000000000000900460ff165b92915050565b919050565b600b5460009067ffffffffffffffff1681036105cd5750600090565b7f0100000000000000000000000000000100000000000000000000000000000000600052600a6020527fcf943f0e419056430919a3fdfd72276bc0b123ebdd670f4152b82bffbfb8bb385468010000000000000000900460ff16806103b55750507f0100000000000000000000000000000000000000000000000000000000000000600052600a6020527f1d4cd6d2639449a552dbfb463b59316946d78c518b3170daa4a4c217bef019ba5468010000000000000000900460ff1690565b6106936126a4565b60005b8251811015610746576106cc8382815181106106b4576106b4614849565b6020026020010151600761272790919063ffffffff16565b1561073e577fdca892154bbc36d0c05ccd01b3d0411875cb1b841fcdeebb384e5d0d6eb06b4483828151811061070457610704614849565b6020026020010151604051610735919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a15b600101610696565b5060005b81518110156107fa5761078082828151811061076857610768614849565b6020026020010151600761274990919063ffffffff16565b156107f2577f66b4b4752c65ae8cd2f3a0a48c7dc8b2118c60d5ea15514992eb2ddf56c9cb158282815181106107b8576107b8614849565b60200260200101516040516107e9919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a15b60010161074a565b505050565b6040805160608082018352808252600060208084018290528385018290526004548551600280549384028201608090810190985294810183815263ffffffff808416986401000000009094041696959194919385939192859285015b828210156108f95760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff740100000000000000000000000000000000000000008204811693850193909352750100000000000000000000000000000000000000000090049091166060830152908352909201910161085b565b505050908252506001919091015461ffff8082166020840152620100009091041660409091015292939192919050565b6109316126a4565b61093a8161276b565b50565b600060068161099b610954368690038601866148a7565b80516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b815260208101919091526040016000205460ff16806105a657506105a66109c56020840184614800565b600790612eef565b337fffffffffffffffffffffffff000000000000000000000000000000000000000181016109fd576109fd614878565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600960205260409020805460ff16610a75576040517f85412e7f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610418565b610a8182858584612f1e565b50505050565b610a8f6126a4565b600454600090819063ffffffff16815b8451811015610b66576000858281518110610abc57610abc614849565b602002602001015190506000610ada84836020015160000151611df5565b9050600080610b3d600087866000015187602001518860400151600960008b6000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002089611fd6565b915091508680610b4a5750815b96508780610b555750805b975050505050806001019050610a9f565b508215610c615760408051600280546080602082028401810190945260608301818152610c61948492849160009085015b82821015610c355760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff7401000000000000000000000000000000000000000082048116938501939093527501000000000000000000000000000000000000000000900490911660608301529083529092019101610b97565b505050908252506001919091015461ffff8082166020840152620100009091041660409091015261276b565b8180610c6a5750825b610a81576040517ffb106b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca86126a4565b73ffffffffffffffffffffffffffffffffffffffff60005260096020527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a7610a8182858584612f1e565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610418565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e397f01000000000000000000000000000001000000000000000000000000000000006104e6565b15610e70576040517fcde2d97c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454336000908152600560209081526040918290208251606081018452905463ffffffff81811680845260ff64010000000084048116958501959095526501000000000090920490931693820193909352921691908214610f00576040517f85412e7f000000000000000000000000000000000000000000000000000000008152336004820152602401610418565b600160005b8481101561132f576000868683818110610f2157610f21614849565b905060400201803603810190610f3791906148a7565b90506000610f868280516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b6000818152600660209081526040918290208251608081018452905460ff81161580158352610100820463ffffffff169383019390935265010000000000810461ffff169382019390935267010000000000000090920478ffffffffffffffffffffffffffffffffffffffffffffffffff16606083015291925090611062573373ffffffffffffffffffffffffffffffffffffffff168763ffffffff167f274d6d5b916b0a53974b7ab86c844b97a2e03a60f658cd9a4b1c028b604d7bf18560405161105291906148e0565b60405180910390a3505050611327565b8663ffffffff16816020015163ffffffff16146110a8575060408051608081018252600080825263ffffffff89166020830152918101829052606081019190915261110c565b6110ba816060015187604001516136d6565b1561110c573373ffffffffffffffffffffffffffffffffffffffff168763ffffffff167f6dfbb745226fa630aeb1b9557d17d508ddb789a04f0cb873ec16e58beb8beead8560405161105291906148e0565b6000945061112281606001518760400151613718565b78ffffffffffffffffffffffffffffffffffffffffffffffffff166060820152602086015160408201805160ff9092169161115e90839061493c565b61ffff1690525060208681015160408051865173ffffffffffffffffffffffffffffffffffffffff168152868401519381019390935260ff9091168282015251339163ffffffff8a16917f2a08a2bd2798f0aae9a843f0f4ad4de488c1b3d5f04049940cfed736ad69fb979181900360600190a3600354604082015161ffff91821691161061125757600181526040808201518151855173ffffffffffffffffffffffffffffffffffffffff1681526020808701519082015261ffff90911681830152905163ffffffff8916917f8257378aa73bf8e4ada848713526584a3dcee0fd3db3beed7397f7a7f5067cc9919081900360600190a25b60009182526006602090815260409283902082518154928401519484015160609094015178ffffffffffffffffffffffffffffffffffffffffffffffffff166701000000000000000266ffffffffffffff61ffff90951665010000000000029490941664ffffffffff63ffffffff909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090941693909317179390931617179055505b600101610f05565b5080156104df576040517f604c767700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113706126a4565b60045463ffffffff1660005b82811015610a8157600084848381811061139857611398614849565b9050604002018036038101906113ae91906148a7565b905060006113fd8280516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b60008181526006602081815260408084208151608081018352815460ff811615158252610100810463ffffffff90811683870190815265010000000000830461ffff169584019590955267010000000000000090910478ffffffffffffffffffffffffffffffffffffffffffffffffff16606083015287875294909352939093558051925193945092878216911614806114945750805b156114fe5760408051855173ffffffffffffffffffffffffffffffffffffffff1681526020808701519082015282151581830152905163ffffffff8816917f7d15a6eebaa019ea7d5b7d38937c51ebd3befbfdf51bb630a694fd28635bbcba919081900360600190a25b5050505080600101905061137c565b600454604080516002805460806020820284018101909452606083810182815290958695600095869563ffffffff9093169486949193928492918491879085015b828210156115ec5760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff740100000000000000000000000000000000000000008204811693850193909352750100000000000000000000000000000000000000000090049091166060830152908352909201910161154e565b505050908252506001919091015461ffff80821660208085019190915262010000909204166040928301527fffffffffffffffffffffffffffffffff000000000000000000000000000000008a166000908152600a909152908120805460ff6801000000000000000082041696509293509163ffffffff80861691161080156116725750845b6000965090508560015b60028111611939578451515b6000808760000151518310156116e35787518051849081106116ac576116ac614849565b6020026020010151602001519150876000015183815181106116d0576116d0614849565b602002602001015160600151905061170a565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905060005b73ffffffffffffffffffffffffffffffffffffffff82166000908152600188016020908152604080832081518083019092525463ffffffff811682526401000000009004821b63ffffffff19169181019190915290878061177a57508a63ffffffff16826000015163ffffffff16145b8061179a575073ffffffffffffffffffffffffffffffffffffffff848116145b80156117b05750602082015163ffffffff191615155b9050801561186d57856001036117d0576117c987614957565b965061186d565b85600203610182576117e560ff84168e61493c565b9c506117f08761498f565b9650838f888151811061180557611805614849565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505081602001518e888151811061185657611856614849565b63ffffffff19909216602092830291909101909101525b84156118835761187c8561498f565b945061188c565b50505050611895565b50505050611688565b81600103611928578267ffffffffffffffff8111156118b6576118b6613e52565b6040519080825280602002602001820160405280156118df578160200160208202803683370190505b509a508267ffffffffffffffff8111156118fb576118fb613e52565b604051908082528060200260200182016040528015611924578160200160208202803683370190505b5099505b5061193281614957565b905061167c565b5050505050509193509193565b600c5460609060009061195984866149c4565b11611965575081611988565b600c5484101561198457600c5461197d9085906149d7565b9050611988565b5060005b60008167ffffffffffffffff8111156119a3576119a3613e52565b604051908082528060200260200182016040528015611a2157816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816119c15790505b50905060005b82811015611b5f57600c611a3b82886149c4565b81548110611a4b57611a4b614849565b600091825260209091206040805160c081019091526002909202018054829060ff166004811115611a7e57611a7e6146d8565b6004811115611a8f57611a8f6146d8565b81528154610100810467ffffffffffffffff1660208301526901000000000000000000810460ff16151560408301526a0100000000000000000000900473ffffffffffffffffffffffffffffffffffffffff166060820152600190910154608081811b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000090811682850152700100000000000000000000000000000000909204901b1660a0909101528251839083908110611b4c57611b4c614849565b6020908102919091010152600101611a27565b50949350505050565b611b706126a4565b61093a8161373b565b606060008080611b91610954368790038701876148a7565b6000818152600660209081526040918290208251608081018452905460ff81161515808352610100820463ffffffff90811694840185905265010000000000830461ffff169584019590955267010000000000000090910478ffffffffffffffffffffffffffffffffffffffffffffffffff166060830152600454909650939450929091169003611dd85760408101516060820151909450611c3281613830565b60ff1667ffffffffffffffff811115611c4d57611c4d613e52565b604051908082528060200260200182016040528015611c76578160200160208202803683370190505b506002805460408051602080840282018101909252828152939950600093929190849084015b82821015611d3a5760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff7401000000000000000000000000000000000000000082048116938501939093527501000000000000000000000000000000000000000000900490911660608301529083529092019101611c9c565b5050505090506000805b82518160ff161015611dd357611d5a84826136d6565b15611dc357828160ff1681518110611d7457611d74614849565b602002602001015160000151898381518110611d9257611d92614849565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152611dc082614957565b91505b611dcc816149ea565b9050611d44565b505050505b50509193909250565b60606000611dee8361389f565b9392505050565b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166000908152600a60205260408120805463ffffffff858116911614611dee57805463ffffffff19811663ffffffff861690811783556003547fffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000909216176201000090910461ffff1664010000000002177fffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffff1680825568010000000000000000900460ff1615611dee57600260005b8154811015611fcd576000826000018281548110611ee657611ee6614849565b6000918252602080832060016002909302018281015473ffffffffffffffffffffffffffffffffffffffff1684529187019052604090912080549192509063ffffffff808a169116108015611f4d57508054640100000000900460201b63ffffffff191615155b15611fc357805463ffffffff191663ffffffff891617815560018201548554750100000000000000000000000000000000000000000090910460ff16908690600690611fa89084906601000000000000900461ffff1661493c565b92506101000a81548161ffff021916908361ffff1602179055505b5050600101611ec6565b50509392505050565b6000806001896001811115611fed57611fed6146d8565b148061200a57506000896001811115612008576120086146d8565b145b61201657612016614878565b8480612037575073ffffffffffffffffffffffffffffffffffffffff878116145b80612056575073ffffffffffffffffffffffffffffffffffffffff8716155b1561207c57600089600181111561206f5761206f6146d8565b1461207c5761207c614878565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260018401602090815260409182902082518084019093525463ffffffff811683526401000000009004811b63ffffffff191690820152845460ff16801561210d575073ffffffffffffffffffffffffffffffffffffffff888116148061210d57508863ffffffff16816000015163ffffffff16145b80156121235750602081015163ffffffff191615155b801561214b5750866020015163ffffffff1916816020015163ffffffff1916148061214b5750855b156122765773ffffffffffffffffffffffffffffffffffffffff881660009081526001858101602052604082209190915585548554919450610100900460ff169085906006906121aa9084906601000000000000900461ffff16614a09565b825461010092830a61ffff818102199092169282160291909117909255895188546020808d01518a54604080517fffffffffffffffffffffffffffffffff0000000000000000000000000000000090961686529590930460ff169184019190915263ffffffff1916828401526601000000000000900490921660608301525173ffffffffffffffffffffffffffffffffffffffff8b16925063ffffffff8c16917fa96a155bd67c927a6c056befbd979b78465e2b2f1276bf7d4e90a31d4f430aa8919081900360800190a35b6000808b600181111561228b5761228b6146d8565b1480156122b3575083806122b3575073ffffffffffffffffffffffffffffffffffffffff8916155b90508080156122cf5750845468010000000000000000900460ff165b80156122e157506122df856138fb565b155b156123b45784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555600b80546001945060009061232a9067ffffffffffffffff16614a24565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f65d0e78c3625f0956f58610cf0fb157eaf627683258875ef29af2f71d25ac8fd88600001516040516123ab91907fffffffffffffffffffffffffffffffff0000000000000000000000000000000091909116815260200190565b60405180910390a15b83806123bd5750825b15612605576000808c60018111156123d7576123d76146d8565b036123f25787156123ea5750600361240f565b50600261240f565b60018c6001811115612406576124066146d8565b03610182575060015b600c6040518060c0016040528083600481111561242e5761242e6146d8565b81526020014267ffffffffffffffff168152885468010000000000000000900460ff16151560208083019190915273ffffffffffffffffffffffffffffffffffffffff8e1660408301528c517fffffffffffffffffffffffffffffffff00000000000000000000000000000000166060830152600060809092018290528354600180820186559483529120825160029092020180549293909283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911690836004811115612500576125006146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c9190911760019091015550612696565b8751602080840151818b0151604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909516855263ffffffff1992831693850193909352169082015273ffffffffffffffffffffffffffffffffffffffff8a16907fbabb0d7099e6ca14a29fad2a2cfb4fda2bd30f97cb3c27e546174bfb4277c1cc9060600160405180910390a25b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612725576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610418565b565b6000611dee8373ffffffffffffffffffffffffffffffffffffffff841661395c565b6000611dee8373ffffffffffffffffffffffffffffffffffffffff8416613a56565b61277481613aa5565b6127aa576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015160038054604084015161ffff908116620100000263ffffffff199092169316929092179190911790555b6002541561298e5760028054600091906127f5906001906149d7565b8154811061280557612805614849565b60009182526020808320604080516080810182526002948502909201805473ffffffffffffffffffffffffffffffffffffffff90811680855260019092015480821685870190815260ff740100000000000000000000000000000000000000008304811687870152750100000000000000000000000000000000000000000090920490911660608601529187526005855282872080547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000016905590511685526009909252922080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690558054919250908061290457612904614a66565b60008281526020902060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019182020180547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560010180547fffffffffffffffffffff000000000000000000000000000000000000000000001690559055506127d9565b60005b815151811015612ac1578151805160029190839081106129b3576129b3614849565b6020908102919091018101518254600181810185556000948552938390208251600290920201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116178155928201519284018054604084015160609094015160ff9081167501000000000000000000000000000000000000000000027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff9190951674010000000000000000000000000000000000000000027fffffffffffffffffffffff0000000000000000000000000000000000000000009092169590931694909417939093171617905501612991565b5060048054600090612ad89063ffffffff16614a95565b82546101009290920a63ffffffff8181021990931691831602179091556004541660005b82515160ff82161015612c5557600083600001518260ff1681518110612b2457612b24614849565b602090810291909101810151604080516060808201835263ffffffff80891683528385015160ff908116848801908152898216858701908152875173ffffffffffffffffffffffffffffffffffffffff908116600090815260058b528881209751885494519351861665010000000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff948716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009096169190971617939093179190911693909317909455858701519091168352600990955291902080549190920151909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090921691909117600117905550612c4e816149ea565b9050612afc565b5073ffffffffffffffffffffffffffffffffffffffff60005260096020527f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660011790556004805463ffffffff438116640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff90921691909117909155604051908216907f8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a990612d2f908590614ab8565b60405180910390a26040805160c081018252600480825267ffffffffffffffff421660208301526000928201839052606082018390526080820183905260a08201839052600c80546001808201835591909452825160029094027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805493949093909284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090921691908490811115612dec57612dec6146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c919091176001909101555050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611dee565b8151600003612f59576040517f55e9b08b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008316600090815260018201602052604090205460ff1615613007576040517f078f340000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201527fffffffffffffffffffffffffffffffff0000000000000000000000000000000084166024820152604401610418565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008316600090815260018281016020526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905560045463ffffffff16905b83518110156136ce57600181101580156130ed575083818151811061309657613096614849565b60200260200101516fffffffffffffffffffffffffffffffff1916846001836130bf91906149d7565b815181106130cf576130cf614849565b60200260200101516fffffffffffffffffffffffffffffffff191610155b15613124576040517f2432d8ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084828151811061313857613138614849565b60200260200101519050600061314e8483611df5565b73ffffffffffffffffffffffffffffffffffffffff8981166000818152600184016020908152604080832081518083019092525463ffffffff811682526401000000009004821b63ffffffff19169181019190915293945091148015906131be5750815163ffffffff8088169116105b806131d25750602082015163ffffffff1916155b15613225575085548254600091610100900460ff169084906006906132069084906601000000000000900461ffff1661493c565b92506101000a81548161ffff021916908361ffff16021790555061322c565b5060208101515b60408051808201825263ffffffff88168152815163ffffffff1984166020828101919091527fffffffffffffffffffffffffffffffff000000000000000000000000000000008d16828501528351808303850181526060909201909352805190830120909182019063ffffffff1916905273ffffffffffffffffffffffffffffffffffffffff8b166000818152600186016020908152604090912083518285015190921c6401000000000263ffffffff92831617905589549294509091908816907f8137bc8a8d712aaa27bfc6506d5566ac405618bd53f9831b8ca6b6fe5442ee7a9087908d9060ff610100909104166133234290565b6020898101518b54604080517fffffffffffffffffffffffffffffffff000000000000000000000000000000009889168152979096169287019290925260ff9093169385019390935267ffffffffffffffff16606084015263ffffffff191660808301526601000000000000900461ffff1660a082015260c00160405180910390a363ffffffff1981161580156133c85750825468010000000000000000900460ff16155b80156133d857506133d8836138fb565b156134c35782547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff1668010000000000000000178355600b80546000906134289067ffffffffffffffff16614acb565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508563ffffffff167fcfdbfd8ce9a56b5f7c202c0e102184d24f47ca87121dc165063fc4c290957bde8561347e4290565b604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909316835267ffffffffffffffff90911660208301520160405180910390a25b6040805160c081018252600080825267ffffffffffffffff42166020830152855460ff680100000000000000009091041615159282019290925273ffffffffffffffffffffffffffffffffffffffff8c1660608201527fffffffffffffffffffffffffffffffff0000000000000000000000000000000086811660808301528b1660a0820152600c80546001808201835591909352815160029093027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805492939092909183917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908360048111156135c0576135c06146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c9190911760019182015594909401935061306f92505050565b505050505050565b600060108260ff16106136eb576136eb614878565b50600160ff82161b821678ffffffffffffffffffffffffffffffffffffffffffffffffff16151592915050565b600060108260ff161061372d5761372d614878565b50600160ff919091161b1790565b3373ffffffffffffffffffffffffffffffffffffffff8216036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610418565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006201000078ffffffffffffffffffffffffffffffffffffffffffffffffff83161061385f5761385f614878565b78ffffffffffffffffffffffffffffffffffffffffffffffffff8216156105ac5761388b600183614ae8565b90911690613898816149ea565b905061385f565b6060816000018054806020026020016040519081016040528092919081815260200182805480156138ef57602002820191906000526020600020905b8154815260200190600101908083116138db575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff600090815260018201602090815260408220546401000000009004901b63ffffffff19161515806105a65750505461ffff64010000000082048116660100000000000090920416101590565b60008181526001830160205260408120548015613a455760006139806001836149d7565b8554909150600090613994906001906149d7565b90508181146139f95760008660000182815481106139b4576139b4614849565b90600052602060002001549050808760000184815481106139d7576139d7614849565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613a0a57613a0a614a66565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105a6565b60009150506105a6565b5092915050565b6000818152600183016020526040812054613a9d575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105a6565b5060006105a6565b8051516000901580613ab957508151516010105b80613aca5750602082015161ffff16155b80613adb5750604082015161ffff16155b15613ae857506000919050565b60008060008460000151516002613aff9190614b1a565b67ffffffffffffffff811115613b1757613b17613e52565b604051908082528060200260200182016040528015613b40578160200160208202803683370190505b50905060005b855151811015613d1157600086600001518281518110613b6857613b68614849565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161480613bc95750602081015173ffffffffffffffffffffffffffffffffffffffff16155b80613bec5750602081015173ffffffffffffffffffffffffffffffffffffffff16155b80613c115750602081015173ffffffffffffffffffffffffffffffffffffffff908116145b80613c315750604081015160ff16158015613c315750606081015160ff16155b15613c43575060009695505050505050565b805183613c51846002614b1a565b613c5c9060006149c4565b81518110613c6c57613c6c614849565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015281015183613c9f846002614b1a565b613caa9060016149c4565b81518110613cba57613cba614849565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526040810151613cf19060ff16866149c4565b9450806060015160ff1684613d0691906149c4565b935050600101613b46565b5060005b8151811015613dc3576000828281518110613d3257613d32614849565b602002602001015190506000826001613d4b91906149c4565b90505b8351811015613db957838181518110613d6957613d69614849565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613db157506000979650505050505050565b600101613d4e565b5050600101613d15565b50846020015161ffff168310158015613de45750846040015161ffff168210155b95945050505050565b60008151808452602080850194506020840160005b83811015613e3457815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613e02565b509495945050505050565b602081526000611dee6020830184613ded565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613ea457613ea4613e52565b60405290565b6040516060810167ffffffffffffffff81118282101715613ea457613ea4613e52565b6040516080810167ffffffffffffffff81118282101715613ea457613ea4613e52565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613f3757613f37613e52565b604052919050565b600067ffffffffffffffff821115613f5957613f59613e52565b5060051b60200190565b80357fffffffffffffffffffffffffffffffff00000000000000000000000000000000811681146105ac57600080fd5b600060408284031215613fa557600080fd5b613fad613e81565b9050613fb882613f63565b8152602082013563ffffffff1981168114613fd257600080fd5b602082015292915050565b60006020808385031215613ff057600080fd5b823567ffffffffffffffff81111561400757600080fd5b8301601f8101851361401857600080fd5b803561402b61402682613f3f565b613ef0565b8082825260208201915060208360061b85010192508783111561404d57600080fd5b6020840193505b82841015614078576140668885613f93565b82528482019150604084019350614054565b979650505050505050565b60006020808352835180602085015260005b818110156140b157858101830151858201604001528201614095565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561410257600080fd5b611dee82613f63565b803573ffffffffffffffffffffffffffffffffffffffff811681146105ac57600080fd5b600082601f83011261414057600080fd5b8135602061415061402683613f3f565b8083825260208201915060208460051b87010193508684111561417257600080fd5b602086015b84811015614195576141888161410b565b8352918301918301614177565b509695505050505050565b600080604083850312156141b357600080fd5b823567ffffffffffffffff808211156141cb57600080fd5b6141d78683870161412f565b935060208501359150808211156141ed57600080fd5b506141fa8582860161412f565b9150509250929050565b8051606080845281518482018190526000926080916020918201918388019190865b82811015614280578451805173ffffffffffffffffffffffffffffffffffffffff908116865283820151168386015260408082015160ff908116918701919091529088015116878501529381019392850192600101614226565b508781015161ffff81168a83015295505050604086015193506142a9604088018561ffff169052565b9695505050505050565b600063ffffffff808616835280851660208401525060606040830152613de46060830184614204565b803560ff811681146105ac57600080fd5b803561ffff811681146105ac57600080fd5b6000602080838503121561431257600080fd5b823567ffffffffffffffff8082111561432a57600080fd5b8185019150606080838803121561434057600080fd5b614348613eaa565b83358381111561435757600080fd5b84019250601f8301881361436a57600080fd5b823561437861402682613f3f565b81815260079190911b8401860190868101908a83111561439757600080fd5b948701945b82861015614409576080868c0312156143b55760008081fd5b6143bd613ecd565b6143c68761410b565b81526143d389880161410b565b8982015260406143e48189016142dc565b908201526143f38787016142dc565b818701528252608095909501949087019061439c565b83525061441990508486016142ed565b85820152614429604085016142ed565b6040820152979650505050505050565b60006040828403121561444b57600080fd5b50919050565b6000806040838503121561446457600080fd5b61446d83613f63565b915060208084013567ffffffffffffffff81111561448a57600080fd5b8401601f8101861361449b57600080fd5b80356144a961402682613f3f565b81815260059190911b820183019083810190888311156144c857600080fd5b928401925b828410156144ed576144de84613f63565b825292840192908401906144cd565b80955050505050509250929050565b6000602080838503121561450f57600080fd5b823567ffffffffffffffff81111561452657600080fd5b8301601f8101851361453757600080fd5b803561454561402682613f3f565b81815260079190911b8201830190838101908783111561456457600080fd5b928401925b8284101561407857608084890312156145825760008081fd5b61458a613eaa565b6145938561410b565b81526145a189878701613f93565b86820152606085013580151581146145b95760008081fd5b604082015282526080939093019290840190614569565b600080602083850312156145e357600080fd5b823567ffffffffffffffff808211156145fb57600080fd5b818501915085601f83011261460f57600080fd5b81358181111561461e57600080fd5b8660208260061b850101111561463357600080fd5b60209290920196919550909350505050565b6080815260006146586080830187613ded565b82810360208481019190915286518083528782019282019060005b8181101561469657845163ffffffff191683529383019391830191600101614673565b505061ffff96909616604085015250505090151560609091015292915050565b600080604083850312156146c957600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208082528251828201819052600091906040908185019086840185805b838110156147f2578251805160058110614766577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b86528088015167ffffffffffffffff16888701528681015115158787015260608082015173ffffffffffffffffffffffffffffffffffffffff16908701526080808201517fffffffffffffffffffffffffffffffff000000000000000000000000000000009081169188019190915260a091820151169086015260c09094019391860191600101614725565b509298975050505050505050565b60006020828403121561481257600080fd5b611dee8261410b565b60608152600061482e6060830186613ded565b61ffff94909416602083015250901515604090910152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000604082840312156148b957600080fd5b6148c1613e81565b6148ca8361410b565b8152602083013560208201528091505092915050565b815173ffffffffffffffffffffffffffffffffffffffff16815260208083015190820152604081016105a6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff818116838216019080821115613a4f57613a4f61490d565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036149885761498861490d565b5060010190565b60008161499e5761499e61490d565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b808201808211156105a6576105a661490d565b818103818111156105a6576105a661490d565b600060ff821660ff8103614a0057614a0061490d565b60010192915050565b61ffff828116828216039080821115613a4f57613a4f61490d565b600067ffffffffffffffff821680614a3e57614a3e61490d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600063ffffffff808316818103614aae57614aae61490d565b6001019392505050565b602081526000611dee6020830184614204565b600067ffffffffffffffff808316818103614aae57614aae61490d565b78ffffffffffffffffffffffffffffffffffffffffffffffffff828116828216039080821115613a4f57613a4f61490d565b80820281158282048414176105a6576105a661490d56fea164736f6c6343000818000a", + Bin: "0x60806040523480156200001157600080fd5b506040516200596238038062005962833981016040819052620000349162000aff565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000138565b505060408051608081018252600080825260208201819052918101919091526001600160c81b03606082015290506001620000fb81601062000c7d565b82606001516001600160c81b0316901c6001600160c81b0316101562000125576200012562000c99565b506200013181620001e3565b5062000e14565b336001600160a01b03821603620001925760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001ee816200071d565b6200020c576040516306b7c75960e31b815260040160405180910390fd5b602081015160038054604084015161ffff908116620100000263ffffffff199092169316929092179190911790555b60025415620003465760028054600091906200025a9060019062000c7d565b815481106200026d576200026d62000caf565b6000918252602080832060408051608081018252600294850290920180546001600160a01b0390811680855260019092015480821685870190815260ff600160a01b8304811687870152600160a81b909204909116606086015291875260058552828720805465ffffffffffff19169055905116855260099092529220805461ffff191690558054919250908062000309576200030962000cc5565b60008281526020902060026000199092019182020180546001600160a01b031916815560010180546001600160b01b03191690559055506200023b565b60005b81515181101562000403578151805160029190839081106200036f576200036f62000caf565b602090810291909101810151825460018181018555600094855293839020825160029092020180546001600160a01b039283166001600160a01b0319909116178155928201519284018054604084015160609094015160ff908116600160a81b0260ff60a81b1991909516600160a01b026001600160a81b0319909216959093169490941793909317161790550162000349565b50600480546000906200041c9063ffffffff1662000cdb565b82546101009290920a63ffffffff8181021990931691831602179091556004541660005b82515160ff821610156200054157600083600001518260ff16815181106200046c576200046c62000caf565b602090810291909101810151604080516060808201835263ffffffff80891683528385015160ff90811684880190815289821685870190815287516001600160a01b03908116600090815260058b5288812097518854945193518616650100000000000260ff60281b199487166401000000000264ffffffffff1990961691909716179390931791909116939093179094558587015190911683526009909552919020805491909201519092166101000261ffff1990921691909117600117905550620005398162000d01565b905062000440565b506001600160a01b0360005260096020527f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a7805461ffff191660011790556004805463ffffffff4381166401000000000263ffffffff60201b1990921691909117909155604051908216907f8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a990620005db90859062000d23565b60405180910390a26040805160c08101825260048082526001600160401b03421660208301526000928201839052606082018390526080820183905260a08201839052600c80546001808201835591909452825160029094027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018054939490939092849260ff19909216919084908111156200067c576200067c62000dce565b021790555060208201518154604084015160608501516001600160a01b03166a010000000000000000000002600160501b600160f01b031991151569010000000000000000000260ff60481b196001600160401b039095166101000294909416610100600160501b031990931692909217929092179190911617815560808083015160a090930151811c600160801b0292901c919091176001909101555050565b80515160009015806200073257508151516010105b80620007445750602082015161ffff16155b80620007565750604082015161ffff16155b156200076457506000919050565b600080600084600001515160026200077d919062000de4565b6001600160401b0381111562000797576200079762000a24565b604051908082528060200260200182016040528015620007c1578160200160208202803683370190505b50905060005b8551518110156200095457600086600001518281518110620007ed57620007ed62000caf565b6020026020010151905060006001600160a01b031681600001516001600160a01b0316148062000828575060208101516001600160a01b0316155b806200083f575060208101516001600160a01b0316155b8062000858575060208101516001600160a01b03908116145b806200087a5750604081015160ff161580156200087a5750606081015160ff16155b156200088d575060009695505050505050565b8051836200089d84600262000de4565b620008aa90600062000dfe565b81518110620008bd57620008bd62000caf565b6001600160a01b0390921660209283029190910182015281015183620008e584600262000de4565b620008f290600162000dfe565b8151811062000905576200090562000caf565b6001600160a01b03909216602092830291909101909101526040810151620009319060ff168662000dfe565b9450806060015160ff168462000948919062000dfe565b935050600101620007c7565b5060005b8151811015620009f957600082828151811062000979576200097962000caf565b60200260200101519050600082600162000994919062000dfe565b90505b8351811015620009ee57838181518110620009b657620009b662000caf565b60200260200101516001600160a01b0316826001600160a01b031603620009e557506000979650505050505050565b60010162000997565b505060010162000958565b50846020015161ffff16831015801562000a1b5750846040015161ffff168210155b95945050505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b038111828210171562000a5f5762000a5f62000a24565b60405290565b604051608081016001600160401b038111828210171562000a5f5762000a5f62000a24565b604051601f8201601f191681016001600160401b038111828210171562000ab55762000ab562000a24565b604052919050565b80516001600160a01b038116811462000ad557600080fd5b919050565b805160ff8116811462000ad557600080fd5b805161ffff8116811462000ad557600080fd5b6000602080838503121562000b1357600080fd5b82516001600160401b038082111562000b2b57600080fd5b8185019150606080838803121562000b4257600080fd5b62000b4c62000a3a565b83518381111562000b5c57600080fd5b8401601f8101891362000b6e57600080fd5b80518481111562000b835762000b8362000a24565b62000b93878260051b0162000a8a565b818152878101955060079190911b82018701908a82111562000bb457600080fd5b918701915b8183101562000c33576080838c03121562000bd45760008081fd5b62000bde62000a65565b62000be98462000abd565b815262000bf889850162000abd565b89820152604062000c0b81860162000ada565b9082015262000c1c84870162000ada565b818701528652948701946080929092019162000bb9565b83525062000c45905084860162000aec565b8582015262000c576040850162000aec565b6040820152979650505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000c935762000c9362000c67565b92915050565b634e487b7160e01b600052600160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600063ffffffff80831681810362000cf75762000cf762000c67565b6001019392505050565b600060ff821660ff810362000d1a5762000d1a62000c67565b60010192915050565b60006020808352608080840185516060808588015282825180855260a0890191508684019450600093505b8084101562000da157845180516001600160a01b03908116845288820151168884015260408082015160ff9081169185019190915290840151168383015293860193600193909301929085019062000d4e565b509488015161ffff8116604089015294604089015161ffff811660608a0152955098975050505050505050565b634e487b7160e01b600052602160045260246000fd5b808202811582820484141762000c935762000c9362000c67565b8082018082111562000c935762000c9362000c67565b614b3e8062000e246000396000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063631ec73e116100d8578063979986111161008c578063d927f26711610066578063d927f26714610354578063f2fde38b14610374578063f33f28951461038757600080fd5b8063979986111461030b578063ba86a1f01461031e578063bd147ef41461033157600080fd5b806379ba5097116100bd57806379ba5097146102d35780638da5cb5b146102db578063970b8fc21461030357600080fd5b8063631ec73e146102ad5780636ba0526d146102c057600080fd5b8063397796f71161013a5780634102e4f4116101145780634102e4f4146102745780634d61677114610287578063586abe3c1461029a57600080fd5b8063397796f7146102425780633d0cf6101461024a5780633f42ab731461025d57600080fd5b8063181f5a771161016b578063181f5a77146101ba5780632cbc26bb14610203578063328d716c1461022657600080fd5b80630b009be21461018757806315c65588146101a5575b600080fd5b61018f6103a9565b60405161019c9190613e3f565b60405180910390f35b6101b86101b3366004613fdd565b6103ba565b005b6101f66040518060400160405280600981526020017f524d4e20312e352e30000000000000000000000000000000000000000000000081525081565b60405161019c9190614083565b6102166102113660046140f0565b6104e6565b604051901515815260200161019c565b600b5467ffffffffffffffff165b60405190815260200161019c565b6102166105b1565b6101b86102583660046141a0565b61068b565b6102656107ff565b60405161019c939291906142b3565b6101b86102823660046142ff565b610929565b610216610295366004614439565b61093d565b6101b86102a8366004614451565b6109cd565b6101b86102bb3660046144fc565b610a87565b6101b86102ce366004614451565b610ca0565b6101b8610d13565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019c565b600c54610234565b6101b86103193660046145d0565b610e10565b6101b861032c3660046145d0565b611368565b61034461033f3660046140f0565b61150d565b60405161019c9493929190614645565b6103676103623660046146b6565b611946565b60405161019c9190614707565b6101b8610382366004614800565b611b68565b61039a610395366004614439565b611b79565b60405161019c9392919061481b565b60606103b56007611de1565b905090565b336000818152600960205260409020805460ff16610421576040517f85412e7f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b60045463ffffffff166000805b85518110156104a757600086828151811061044b5761044b614849565b602002602001015190506000610465858360000151611df5565b905060008061047b6001888b8760008d89611fd6565b91509150801561048d5761048d614878565b85806104965750815b95505050505080600101905061042e565b50806104df576040517ffb106b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b600b5460009067ffffffffffffffff16810361050457506000919050565b7f0100000000000000000000000000000100000000000000000000000000000000600052600a6020527fcf943f0e419056430919a3fdfd72276bc0b123ebdd670f4152b82bffbfb8bb385468010000000000000000900460ff16806105a657507fffffffffffffffffffffffffffffffff0000000000000000000000000000000082166000908152600a602052604090205468010000000000000000900460ff165b92915050565b919050565b600b5460009067ffffffffffffffff1681036105cd5750600090565b7f0100000000000000000000000000000100000000000000000000000000000000600052600a6020527fcf943f0e419056430919a3fdfd72276bc0b123ebdd670f4152b82bffbfb8bb385468010000000000000000900460ff16806103b55750507f0100000000000000000000000000000000000000000000000000000000000000600052600a6020527f1d4cd6d2639449a552dbfb463b59316946d78c518b3170daa4a4c217bef019ba5468010000000000000000900460ff1690565b6106936126a4565b60005b8251811015610746576106cc8382815181106106b4576106b4614849565b6020026020010151600761272790919063ffffffff16565b1561073e577fdca892154bbc36d0c05ccd01b3d0411875cb1b841fcdeebb384e5d0d6eb06b4483828151811061070457610704614849565b6020026020010151604051610735919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a15b600101610696565b5060005b81518110156107fa5761078082828151811061076857610768614849565b6020026020010151600761274990919063ffffffff16565b156107f2577f66b4b4752c65ae8cd2f3a0a48c7dc8b2118c60d5ea15514992eb2ddf56c9cb158282815181106107b8576107b8614849565b60200260200101516040516107e9919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a15b60010161074a565b505050565b6040805160608082018352808252600060208084018290528385018290526004548551600280549384028201608090810190985294810183815263ffffffff808416986401000000009094041696959194919385939192859285015b828210156108f95760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff740100000000000000000000000000000000000000008204811693850193909352750100000000000000000000000000000000000000000090049091166060830152908352909201910161085b565b505050908252506001919091015461ffff8082166020840152620100009091041660409091015292939192919050565b6109316126a4565b61093a8161276b565b50565b600060068161099b610954368690038601866148a7565b80516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b815260208101919091526040016000205460ff16806105a657506105a66109c56020840184614800565b600790612eef565b337fffffffffffffffffffffffff000000000000000000000000000000000000000181016109fd576109fd614878565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600960205260409020805460ff16610a75576040517f85412e7f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610418565b610a8182858584612f1e565b50505050565b610a8f6126a4565b600454600090819063ffffffff16815b8451811015610b66576000858281518110610abc57610abc614849565b602002602001015190506000610ada84836020015160000151611df5565b9050600080610b3d600087866000015187602001518860400151600960008b6000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002089611fd6565b915091508680610b4a5750815b96508780610b555750805b975050505050806001019050610a9f565b508215610c615760408051600280546080602082028401810190945260608301818152610c61948492849160009085015b82821015610c355760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff7401000000000000000000000000000000000000000082048116938501939093527501000000000000000000000000000000000000000000900490911660608301529083529092019101610b97565b505050908252506001919091015461ffff8082166020840152620100009091041660409091015261276b565b8180610c6a5750825b610a81576040517ffb106b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca86126a4565b73ffffffffffffffffffffffffffffffffffffffff60005260096020527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a7610a8182858584612f1e565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610418565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e397f01000000000000000000000000000001000000000000000000000000000000006104e6565b15610e70576040517fcde2d97c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454336000908152600560209081526040918290208251606081018452905463ffffffff81811680845260ff64010000000084048116958501959095526501000000000090920490931693820193909352921691908214610f00576040517f85412e7f000000000000000000000000000000000000000000000000000000008152336004820152602401610418565b600160005b8481101561132f576000868683818110610f2157610f21614849565b905060400201803603810190610f3791906148a7565b90506000610f868280516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b6000818152600660209081526040918290208251608081018452905460ff81161580158352610100820463ffffffff169383019390935265010000000000810461ffff169382019390935267010000000000000090920478ffffffffffffffffffffffffffffffffffffffffffffffffff16606083015291925090611062573373ffffffffffffffffffffffffffffffffffffffff168763ffffffff167f274d6d5b916b0a53974b7ab86c844b97a2e03a60f658cd9a4b1c028b604d7bf18560405161105291906148e0565b60405180910390a3505050611327565b8663ffffffff16816020015163ffffffff16146110a8575060408051608081018252600080825263ffffffff89166020830152918101829052606081019190915261110c565b6110ba816060015187604001516136d6565b1561110c573373ffffffffffffffffffffffffffffffffffffffff168763ffffffff167f6dfbb745226fa630aeb1b9557d17d508ddb789a04f0cb873ec16e58beb8beead8560405161105291906148e0565b6000945061112281606001518760400151613718565b78ffffffffffffffffffffffffffffffffffffffffffffffffff166060820152602086015160408201805160ff9092169161115e90839061493c565b61ffff1690525060208681015160408051865173ffffffffffffffffffffffffffffffffffffffff168152868401519381019390935260ff9091168282015251339163ffffffff8a16917f2a08a2bd2798f0aae9a843f0f4ad4de488c1b3d5f04049940cfed736ad69fb979181900360600190a3600354604082015161ffff91821691161061125757600181526040808201518151855173ffffffffffffffffffffffffffffffffffffffff1681526020808701519082015261ffff90911681830152905163ffffffff8916917f8257378aa73bf8e4ada848713526584a3dcee0fd3db3beed7397f7a7f5067cc9919081900360600190a25b60009182526006602090815260409283902082518154928401519484015160609094015178ffffffffffffffffffffffffffffffffffffffffffffffffff166701000000000000000266ffffffffffffff61ffff90951665010000000000029490941664ffffffffff63ffffffff909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090941693909317179390931617179055505b600101610f05565b5080156104df576040517f604c767700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113706126a4565b60045463ffffffff1660005b82811015610a8157600084848381811061139857611398614849565b9050604002018036038101906113ae91906148a7565b905060006113fd8280516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b60008181526006602081815260408084208151608081018352815460ff811615158252610100810463ffffffff90811683870190815265010000000000830461ffff169584019590955267010000000000000090910478ffffffffffffffffffffffffffffffffffffffffffffffffff16606083015287875294909352939093558051925193945092878216911614806114945750805b156114fe5760408051855173ffffffffffffffffffffffffffffffffffffffff1681526020808701519082015282151581830152905163ffffffff8816917f7d15a6eebaa019ea7d5b7d38937c51ebd3befbfdf51bb630a694fd28635bbcba919081900360600190a25b5050505080600101905061137c565b600454604080516002805460806020820284018101909452606083810182815290958695600095869563ffffffff9093169486949193928492918491879085015b828210156115ec5760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff740100000000000000000000000000000000000000008204811693850193909352750100000000000000000000000000000000000000000090049091166060830152908352909201910161154e565b505050908252506001919091015461ffff80821660208085019190915262010000909204166040928301527fffffffffffffffffffffffffffffffff000000000000000000000000000000008a166000908152600a909152908120805460ff6801000000000000000082041696509293509163ffffffff80861691161080156116725750845b6000965090508560015b60028111611939578451515b6000808760000151518310156116e35787518051849081106116ac576116ac614849565b6020026020010151602001519150876000015183815181106116d0576116d0614849565b602002602001015160600151905061170a565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905060005b73ffffffffffffffffffffffffffffffffffffffff82166000908152600188016020908152604080832081518083019092525463ffffffff811682526401000000009004821b63ffffffff19169181019190915290878061177a57508a63ffffffff16826000015163ffffffff16145b8061179a575073ffffffffffffffffffffffffffffffffffffffff848116145b80156117b05750602082015163ffffffff191615155b9050801561186d57856001036117d0576117c987614957565b965061186d565b85600203610182576117e560ff84168e61493c565b9c506117f08761498f565b9650838f888151811061180557611805614849565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505081602001518e888151811061185657611856614849565b63ffffffff19909216602092830291909101909101525b84156118835761187c8561498f565b945061188c565b50505050611895565b50505050611688565b81600103611928578267ffffffffffffffff8111156118b6576118b6613e52565b6040519080825280602002602001820160405280156118df578160200160208202803683370190505b509a508267ffffffffffffffff8111156118fb576118fb613e52565b604051908082528060200260200182016040528015611924578160200160208202803683370190505b5099505b5061193281614957565b905061167c565b5050505050509193509193565b600c5460609060009061195984866149c4565b11611965575081611988565b600c5484101561198457600c5461197d9085906149d7565b9050611988565b5060005b60008167ffffffffffffffff8111156119a3576119a3613e52565b604051908082528060200260200182016040528015611a2157816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816119c15790505b50905060005b82811015611b5f57600c611a3b82886149c4565b81548110611a4b57611a4b614849565b600091825260209091206040805160c081019091526002909202018054829060ff166004811115611a7e57611a7e6146d8565b6004811115611a8f57611a8f6146d8565b81528154610100810467ffffffffffffffff1660208301526901000000000000000000810460ff16151560408301526a0100000000000000000000900473ffffffffffffffffffffffffffffffffffffffff166060820152600190910154608081811b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000090811682850152700100000000000000000000000000000000909204901b1660a0909101528251839083908110611b4c57611b4c614849565b6020908102919091010152600101611a27565b50949350505050565b611b706126a4565b61093a8161373b565b606060008080611b91610954368790038701876148a7565b6000818152600660209081526040918290208251608081018452905460ff81161515808352610100820463ffffffff90811694840185905265010000000000830461ffff169584019590955267010000000000000090910478ffffffffffffffffffffffffffffffffffffffffffffffffff166060830152600454909650939450929091169003611dd85760408101516060820151909450611c3281613830565b60ff1667ffffffffffffffff811115611c4d57611c4d613e52565b604051908082528060200260200182016040528015611c76578160200160208202803683370190505b506002805460408051602080840282018101909252828152939950600093929190849084015b82821015611d3a5760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff7401000000000000000000000000000000000000000082048116938501939093527501000000000000000000000000000000000000000000900490911660608301529083529092019101611c9c565b5050505090506000805b82518160ff161015611dd357611d5a84826136d6565b15611dc357828160ff1681518110611d7457611d74614849565b602002602001015160000151898381518110611d9257611d92614849565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152611dc082614957565b91505b611dcc816149ea565b9050611d44565b505050505b50509193909250565b60606000611dee8361389f565b9392505050565b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166000908152600a60205260408120805463ffffffff858116911614611dee57805463ffffffff19811663ffffffff861690811783556003547fffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000909216176201000090910461ffff1664010000000002177fffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffff1680825568010000000000000000900460ff1615611dee57600260005b8154811015611fcd576000826000018281548110611ee657611ee6614849565b6000918252602080832060016002909302018281015473ffffffffffffffffffffffffffffffffffffffff1684529187019052604090912080549192509063ffffffff808a169116108015611f4d57508054640100000000900460201b63ffffffff191615155b15611fc357805463ffffffff191663ffffffff891617815560018201548554750100000000000000000000000000000000000000000090910460ff16908690600690611fa89084906601000000000000900461ffff1661493c565b92506101000a81548161ffff021916908361ffff1602179055505b5050600101611ec6565b50509392505050565b6000806001896001811115611fed57611fed6146d8565b148061200a57506000896001811115612008576120086146d8565b145b61201657612016614878565b8480612037575073ffffffffffffffffffffffffffffffffffffffff878116145b80612056575073ffffffffffffffffffffffffffffffffffffffff8716155b1561207c57600089600181111561206f5761206f6146d8565b1461207c5761207c614878565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260018401602090815260409182902082518084019093525463ffffffff811683526401000000009004811b63ffffffff191690820152845460ff16801561210d575073ffffffffffffffffffffffffffffffffffffffff888116148061210d57508863ffffffff16816000015163ffffffff16145b80156121235750602081015163ffffffff191615155b801561214b5750866020015163ffffffff1916816020015163ffffffff1916148061214b5750855b156122765773ffffffffffffffffffffffffffffffffffffffff881660009081526001858101602052604082209190915585548554919450610100900460ff169085906006906121aa9084906601000000000000900461ffff16614a09565b825461010092830a61ffff818102199092169282160291909117909255895188546020808d01518a54604080517fffffffffffffffffffffffffffffffff0000000000000000000000000000000090961686529590930460ff169184019190915263ffffffff1916828401526601000000000000900490921660608301525173ffffffffffffffffffffffffffffffffffffffff8b16925063ffffffff8c16917fa96a155bd67c927a6c056befbd979b78465e2b2f1276bf7d4e90a31d4f430aa8919081900360800190a35b6000808b600181111561228b5761228b6146d8565b1480156122b3575083806122b3575073ffffffffffffffffffffffffffffffffffffffff8916155b90508080156122cf5750845468010000000000000000900460ff165b80156122e157506122df856138fb565b155b156123b45784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555600b80546001945060009061232a9067ffffffffffffffff16614a24565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f65d0e78c3625f0956f58610cf0fb157eaf627683258875ef29af2f71d25ac8fd88600001516040516123ab91907fffffffffffffffffffffffffffffffff0000000000000000000000000000000091909116815260200190565b60405180910390a15b83806123bd5750825b15612605576000808c60018111156123d7576123d76146d8565b036123f25787156123ea5750600361240f565b50600261240f565b60018c6001811115612406576124066146d8565b03610182575060015b600c6040518060c0016040528083600481111561242e5761242e6146d8565b81526020014267ffffffffffffffff168152885468010000000000000000900460ff16151560208083019190915273ffffffffffffffffffffffffffffffffffffffff8e1660408301528c517fffffffffffffffffffffffffffffffff00000000000000000000000000000000166060830152600060809092018290528354600180820186559483529120825160029092020180549293909283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911690836004811115612500576125006146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c9190911760019091015550612696565b8751602080840151818b0151604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909516855263ffffffff1992831693850193909352169082015273ffffffffffffffffffffffffffffffffffffffff8a16907fbabb0d7099e6ca14a29fad2a2cfb4fda2bd30f97cb3c27e546174bfb4277c1cc9060600160405180910390a25b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612725576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610418565b565b6000611dee8373ffffffffffffffffffffffffffffffffffffffff841661395c565b6000611dee8373ffffffffffffffffffffffffffffffffffffffff8416613a56565b61277481613aa5565b6127aa576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015160038054604084015161ffff908116620100000263ffffffff199092169316929092179190911790555b6002541561298e5760028054600091906127f5906001906149d7565b8154811061280557612805614849565b60009182526020808320604080516080810182526002948502909201805473ffffffffffffffffffffffffffffffffffffffff90811680855260019092015480821685870190815260ff740100000000000000000000000000000000000000008304811687870152750100000000000000000000000000000000000000000090920490911660608601529187526005855282872080547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000016905590511685526009909252922080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690558054919250908061290457612904614a66565b60008281526020902060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019182020180547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560010180547fffffffffffffffffffff000000000000000000000000000000000000000000001690559055506127d9565b60005b815151811015612ac1578151805160029190839081106129b3576129b3614849565b6020908102919091018101518254600181810185556000948552938390208251600290920201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116178155928201519284018054604084015160609094015160ff9081167501000000000000000000000000000000000000000000027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff9190951674010000000000000000000000000000000000000000027fffffffffffffffffffffff0000000000000000000000000000000000000000009092169590931694909417939093171617905501612991565b5060048054600090612ad89063ffffffff16614a95565b82546101009290920a63ffffffff8181021990931691831602179091556004541660005b82515160ff82161015612c5557600083600001518260ff1681518110612b2457612b24614849565b602090810291909101810151604080516060808201835263ffffffff80891683528385015160ff908116848801908152898216858701908152875173ffffffffffffffffffffffffffffffffffffffff908116600090815260058b528881209751885494519351861665010000000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff948716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009096169190971617939093179190911693909317909455858701519091168352600990955291902080549190920151909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090921691909117600117905550612c4e816149ea565b9050612afc565b5073ffffffffffffffffffffffffffffffffffffffff60005260096020527f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660011790556004805463ffffffff438116640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff90921691909117909155604051908216907f8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a990612d2f908590614ab8565b60405180910390a26040805160c081018252600480825267ffffffffffffffff421660208301526000928201839052606082018390526080820183905260a08201839052600c80546001808201835591909452825160029094027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805493949093909284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090921691908490811115612dec57612dec6146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c919091176001909101555050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611dee565b8151600003612f59576040517f55e9b08b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008316600090815260018201602052604090205460ff1615613007576040517f078f340000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201527fffffffffffffffffffffffffffffffff0000000000000000000000000000000084166024820152604401610418565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008316600090815260018281016020526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905560045463ffffffff16905b83518110156136ce57600181101580156130ed575083818151811061309657613096614849565b60200260200101516fffffffffffffffffffffffffffffffff1916846001836130bf91906149d7565b815181106130cf576130cf614849565b60200260200101516fffffffffffffffffffffffffffffffff191610155b15613124576040517f2432d8ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084828151811061313857613138614849565b60200260200101519050600061314e8483611df5565b73ffffffffffffffffffffffffffffffffffffffff8981166000818152600184016020908152604080832081518083019092525463ffffffff811682526401000000009004821b63ffffffff19169181019190915293945091148015906131be5750815163ffffffff8088169116105b806131d25750602082015163ffffffff1916155b15613225575085548254600091610100900460ff169084906006906132069084906601000000000000900461ffff1661493c565b92506101000a81548161ffff021916908361ffff16021790555061322c565b5060208101515b60408051808201825263ffffffff88168152815163ffffffff1984166020828101919091527fffffffffffffffffffffffffffffffff000000000000000000000000000000008d16828501528351808303850181526060909201909352805190830120909182019063ffffffff1916905273ffffffffffffffffffffffffffffffffffffffff8b166000818152600186016020908152604090912083518285015190921c6401000000000263ffffffff92831617905589549294509091908816907f8137bc8a8d712aaa27bfc6506d5566ac405618bd53f9831b8ca6b6fe5442ee7a9087908d9060ff610100909104166133234290565b6020898101518b54604080517fffffffffffffffffffffffffffffffff000000000000000000000000000000009889168152979096169287019290925260ff9093169385019390935267ffffffffffffffff16606084015263ffffffff191660808301526601000000000000900461ffff1660a082015260c00160405180910390a363ffffffff1981161580156133c85750825468010000000000000000900460ff16155b80156133d857506133d8836138fb565b156134c35782547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff1668010000000000000000178355600b80546000906134289067ffffffffffffffff16614acb565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508563ffffffff167fcfdbfd8ce9a56b5f7c202c0e102184d24f47ca87121dc165063fc4c290957bde8561347e4290565b604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909316835267ffffffffffffffff90911660208301520160405180910390a25b6040805160c081018252600080825267ffffffffffffffff42166020830152855460ff680100000000000000009091041615159282019290925273ffffffffffffffffffffffffffffffffffffffff8c1660608201527fffffffffffffffffffffffffffffffff0000000000000000000000000000000086811660808301528b1660a0820152600c80546001808201835591909352815160029093027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805492939092909183917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908360048111156135c0576135c06146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c9190911760019182015594909401935061306f92505050565b505050505050565b600060108260ff16106136eb576136eb614878565b50600160ff82161b821678ffffffffffffffffffffffffffffffffffffffffffffffffff16151592915050565b600060108260ff161061372d5761372d614878565b50600160ff919091161b1790565b3373ffffffffffffffffffffffffffffffffffffffff8216036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610418565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006201000078ffffffffffffffffffffffffffffffffffffffffffffffffff83161061385f5761385f614878565b78ffffffffffffffffffffffffffffffffffffffffffffffffff8216156105ac5761388b600183614ae8565b90911690613898816149ea565b905061385f565b6060816000018054806020026020016040519081016040528092919081815260200182805480156138ef57602002820191906000526020600020905b8154815260200190600101908083116138db575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff600090815260018201602090815260408220546401000000009004901b63ffffffff19161515806105a65750505461ffff64010000000082048116660100000000000090920416101590565b60008181526001830160205260408120548015613a455760006139806001836149d7565b8554909150600090613994906001906149d7565b90508181146139f95760008660000182815481106139b4576139b4614849565b90600052602060002001549050808760000184815481106139d7576139d7614849565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613a0a57613a0a614a66565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105a6565b60009150506105a6565b5092915050565b6000818152600183016020526040812054613a9d575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105a6565b5060006105a6565b8051516000901580613ab957508151516010105b80613aca5750602082015161ffff16155b80613adb5750604082015161ffff16155b15613ae857506000919050565b60008060008460000151516002613aff9190614b1a565b67ffffffffffffffff811115613b1757613b17613e52565b604051908082528060200260200182016040528015613b40578160200160208202803683370190505b50905060005b855151811015613d1157600086600001518281518110613b6857613b68614849565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161480613bc95750602081015173ffffffffffffffffffffffffffffffffffffffff16155b80613bec5750602081015173ffffffffffffffffffffffffffffffffffffffff16155b80613c115750602081015173ffffffffffffffffffffffffffffffffffffffff908116145b80613c315750604081015160ff16158015613c315750606081015160ff16155b15613c43575060009695505050505050565b805183613c51846002614b1a565b613c5c9060006149c4565b81518110613c6c57613c6c614849565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015281015183613c9f846002614b1a565b613caa9060016149c4565b81518110613cba57613cba614849565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526040810151613cf19060ff16866149c4565b9450806060015160ff1684613d0691906149c4565b935050600101613b46565b5060005b8151811015613dc3576000828281518110613d3257613d32614849565b602002602001015190506000826001613d4b91906149c4565b90505b8351811015613db957838181518110613d6957613d69614849565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613db157506000979650505050505050565b600101613d4e565b5050600101613d15565b50846020015161ffff168310158015613de45750846040015161ffff168210155b95945050505050565b60008151808452602080850194506020840160005b83811015613e3457815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613e02565b509495945050505050565b602081526000611dee6020830184613ded565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613ea457613ea4613e52565b60405290565b6040516060810167ffffffffffffffff81118282101715613ea457613ea4613e52565b6040516080810167ffffffffffffffff81118282101715613ea457613ea4613e52565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613f3757613f37613e52565b604052919050565b600067ffffffffffffffff821115613f5957613f59613e52565b5060051b60200190565b80357fffffffffffffffffffffffffffffffff00000000000000000000000000000000811681146105ac57600080fd5b600060408284031215613fa557600080fd5b613fad613e81565b9050613fb882613f63565b8152602082013563ffffffff1981168114613fd257600080fd5b602082015292915050565b60006020808385031215613ff057600080fd5b823567ffffffffffffffff81111561400757600080fd5b8301601f8101851361401857600080fd5b803561402b61402682613f3f565b613ef0565b8082825260208201915060208360061b85010192508783111561404d57600080fd5b6020840193505b82841015614078576140668885613f93565b82528482019150604084019350614054565b979650505050505050565b60006020808352835180602085015260005b818110156140b157858101830151858201604001528201614095565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561410257600080fd5b611dee82613f63565b803573ffffffffffffffffffffffffffffffffffffffff811681146105ac57600080fd5b600082601f83011261414057600080fd5b8135602061415061402683613f3f565b8083825260208201915060208460051b87010193508684111561417257600080fd5b602086015b84811015614195576141888161410b565b8352918301918301614177565b509695505050505050565b600080604083850312156141b357600080fd5b823567ffffffffffffffff808211156141cb57600080fd5b6141d78683870161412f565b935060208501359150808211156141ed57600080fd5b506141fa8582860161412f565b9150509250929050565b8051606080845281518482018190526000926080916020918201918388019190865b82811015614280578451805173ffffffffffffffffffffffffffffffffffffffff908116865283820151168386015260408082015160ff908116918701919091529088015116878501529381019392850192600101614226565b508781015161ffff81168a83015295505050604086015193506142a9604088018561ffff169052565b9695505050505050565b600063ffffffff808616835280851660208401525060606040830152613de46060830184614204565b803560ff811681146105ac57600080fd5b803561ffff811681146105ac57600080fd5b6000602080838503121561431257600080fd5b823567ffffffffffffffff8082111561432a57600080fd5b8185019150606080838803121561434057600080fd5b614348613eaa565b83358381111561435757600080fd5b84019250601f8301881361436a57600080fd5b823561437861402682613f3f565b81815260079190911b8401860190868101908a83111561439757600080fd5b948701945b82861015614409576080868c0312156143b55760008081fd5b6143bd613ecd565b6143c68761410b565b81526143d389880161410b565b8982015260406143e48189016142dc565b908201526143f38787016142dc565b818701528252608095909501949087019061439c565b83525061441990508486016142ed565b85820152614429604085016142ed565b6040820152979650505050505050565b60006040828403121561444b57600080fd5b50919050565b6000806040838503121561446457600080fd5b61446d83613f63565b915060208084013567ffffffffffffffff81111561448a57600080fd5b8401601f8101861361449b57600080fd5b80356144a961402682613f3f565b81815260059190911b820183019083810190888311156144c857600080fd5b928401925b828410156144ed576144de84613f63565b825292840192908401906144cd565b80955050505050509250929050565b6000602080838503121561450f57600080fd5b823567ffffffffffffffff81111561452657600080fd5b8301601f8101851361453757600080fd5b803561454561402682613f3f565b81815260079190911b8201830190838101908783111561456457600080fd5b928401925b8284101561407857608084890312156145825760008081fd5b61458a613eaa565b6145938561410b565b81526145a189878701613f93565b86820152606085013580151581146145b95760008081fd5b604082015282526080939093019290840190614569565b600080602083850312156145e357600080fd5b823567ffffffffffffffff808211156145fb57600080fd5b818501915085601f83011261460f57600080fd5b81358181111561461e57600080fd5b8660208260061b850101111561463357600080fd5b60209290920196919550909350505050565b6080815260006146586080830187613ded565b82810360208481019190915286518083528782019282019060005b8181101561469657845163ffffffff191683529383019391830191600101614673565b505061ffff96909616604085015250505090151560609091015292915050565b600080604083850312156146c957600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208082528251828201819052600091906040908185019086840185805b838110156147f2578251805160058110614766577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b86528088015167ffffffffffffffff16888701528681015115158787015260608082015173ffffffffffffffffffffffffffffffffffffffff16908701526080808201517fffffffffffffffffffffffffffffffff000000000000000000000000000000009081169188019190915260a091820151169086015260c09094019391860191600101614725565b509298975050505050505050565b60006020828403121561481257600080fd5b611dee8261410b565b60608152600061482e6060830186613ded565b61ffff94909416602083015250901515604090910152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000604082840312156148b957600080fd5b6148c1613e81565b6148ca8361410b565b8152602083013560208201528091505092915050565b815173ffffffffffffffffffffffffffffffffffffffff16815260208083015190820152604081016105a6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff818116838216019080821115613a4f57613a4f61490d565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036149885761498861490d565b5060010190565b60008161499e5761499e61490d565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b808201808211156105a6576105a661490d565b818103818111156105a6576105a661490d565b600060ff821660ff8103614a0057614a0061490d565b60010192915050565b61ffff828116828216039080821115613a4f57613a4f61490d565b600067ffffffffffffffff821680614a3e57614a3e61490d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600063ffffffff808316818103614aae57614aae61490d565b6001019392505050565b602081526000611dee6020830184614204565b600067ffffffffffffffff808316818103614aae57614aae61490d565b78ffffffffffffffffffffffffffffffffffffffffffffffffff828116828216039080821115613a4f57613a4f61490d565b80820281158282048414176105a6576105a661490d56fea164736f6c6343000818000a", } var ARMContractABI = ARMContractMetaData.ABI diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 034a89f133..6195708b13 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,5 +1,5 @@ GETH_VERSION: 1.13.8 -arm_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 1a0abacf84def916519013f713b667f106434a091af8b9f441e12cc90aa2cdf8 +arm_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 763c7d81e782d7c286d4a5892aeebe71984a1f999a50a051c87f5b8f9c70cc26 arm_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 02e37792e25155ab4e7e4b4211002180789d0c1559cad1e38d3bd70efe0fb7d6 burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 4b1b468de62a7e9adffd4d8ccb3621a7e0658ae453a4bfa72493ae25362e9693 From 54b8aacf24e024936dd446eaf125eafbc9d7cde5 Mon Sep 17 00:00:00 2001 From: Suryansh <39276431+0xsuryansh@users.noreply.github.com> Date: Thu, 8 Aug 2024 23:19:37 +0530 Subject: [PATCH 196/432] feat: optimise EVM2EVMMultiOffRamp.executeSingleMessage (#1235) ## Motivation `EVM2EVMMultiOffRamp.executeSingleMessage` is optimised by replacing memory to calldata, internal functions `_releaseOrMintSingleTokens` and `_releaseOrMintSingleToken` can be optimised ``` function executeSingleMessage(Internal.Any2EVMRampMessage memory message, bytes[] memory offchainTokenData) external ``` Tradeoff is increased contract size, which is exceeding the limit and thus we have to decrease the optimiser runs ## Findings After replacing memory with call data we have the following findings for gas and contract size | Test | Before | after | delta | | ------------------------------------------------------------------------------------------- | ------ | ------ | ------ | | EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() | 249368 | 247671 | \-1697 | | EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() | 20672 | 19245 | \-1427 | | EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() | 48381 | 47265 | \-1116 | | EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() | 278146 | 276759 | \-1387 | | EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() | 93615 | 92499 | \-1116 | | EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() | 108343 | 107939 | \-404 | | **Optimser Run** | **Size** | **Margin(kB)** | **With call data optimisation** | | ---------------- | --------------------------------- | -------------- | ------------------------------- | | 2500 | 24.113 | 0.463 | No | | 2500 | 24.857 (size increase of 0.744kB) | \-0.281 | Yes | | 2400 | 24.635 | \-0.059 | Yes | | 2200 | 24.635 | \-0.059 | | | 2000 | 24.572 | 0.004 | Yes | --------- Signed-off-by: 0xsuryansh Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/gas-snapshots/ccip.gas-snapshot | 184 +++++++++--------- .../scripts/native_solc_compile_all_ccip | 2 +- .../v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 17 +- .../helpers/EVM2EVMMultiOffRampHelper.sol | 6 +- .../evm_2_evm_multi_offramp.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 6 files changed, 108 insertions(+), 105 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 6d407195a8..d2920bccd6 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -123,9 +123,9 @@ CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424253) E2E:test_E2E_3MessagesSuccess_gas() (gas: 1134031) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38185) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 109684) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 82608) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 35297) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 109266) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 82186) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 468131) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99235) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12399) @@ -134,19 +134,19 @@ EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Succ EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13267) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17992) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15347) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 296705) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 238095) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 157010) -EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187408) -EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 145607) -EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 538299) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 293675) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 235065) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 155958) +EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 185346) +EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 144597) +EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 535800) EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10437) EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15662) EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67352) EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59642) EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58722) -EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6406089) -EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 5989229) +EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6551526) +EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 6134666) EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106187) EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116097) EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106208) @@ -159,95 +159,95 @@ EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225639) EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117474) EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77538) EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 204931) -EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6400412) +EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6545849) EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47718) -EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 5993281) -EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 136870) -EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103588) -EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101459) -EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139444) -EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101358) -EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101403) +EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 6138723) +EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137096) +EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103813) +EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101684) +EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139670) +EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101583) +EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101628) EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17302) -EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1558948) -EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 339903) -EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 258341) -EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6456706) -EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6039587) +EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1528648) +EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 335293) +EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 255311) +EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6601133) +EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6184014) EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 27703) -EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 163239) -EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147217) -EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6818758) +EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 162229) +EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 146207) +EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6963185) EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17154) -EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18413) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 258732) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20672) -EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 203093) -EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48956) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48477) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229787) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86425) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 289629) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92678) -EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35117) +EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 15990) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 257007) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 19245) +EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 200549) +EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47986) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 47509) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 228029) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 84667) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 288361) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 91710) +EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35075) EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23918) -EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 460816) -EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54437) -EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35906) -EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154347) -EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35328) -EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 179411) -EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 190690) -EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48064) -EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 441088) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 249886) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 172078) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 191751) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259610) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 127621) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 401140) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65861) -EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80895) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 552164) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 497122) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35774) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 537135) -EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 534830) -EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 504627) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 126045) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 155268) +EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 455362) +EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54395) +EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35864) +EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154305) +EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35286) +EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 178399) +EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 189636) +EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48022) +EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 440076) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 247866) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 170058) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 189731) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 258294) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 126611) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 399848) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65819) +EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80859) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 549604) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 494562) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35690) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 534868) +EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 532763) +EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 502067) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 124993) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 154216) EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3655340) EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118202) EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87461) -EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75600) -EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26461) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 163139) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205495) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26004) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152867) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 505596) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2286715) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 207749) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 208326) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 659124) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 299687) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 161976) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 24145) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 59111) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 40433) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 76136) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 188337) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 305691) +EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75264) +EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26419) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 162127) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 203471) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 25962) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152111) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 503574) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2285870) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 205727) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 206304) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 649014) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 295645) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 160246) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 21873) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 55762) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 36070) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 72786) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 186613) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 304312) EVM2EVMMultiOffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11379) EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215350) EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14162) EVM2EVMMultiOffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11660) EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49203) EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27169) -EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 239475) -EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 248072) -EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 311122) -EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 292068) +EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 236919) +EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 245516) +EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 299471) +EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 290788) EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176548) EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178616) EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141477) @@ -598,18 +598,18 @@ MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 393335) -MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1413114) +MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1409277) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71847) -NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 250575) -NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 252898) -NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 305952) -NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 288933) +NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 249565) +NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 251888) +NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 303932) +NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 287881) NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 247821) NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 235877) -NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 142832) +NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 141822) NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 167625) NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 218724) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index 1dbb70502d..fd38ae3562 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -10,7 +10,7 @@ SOLC_VERSION="0.8.24" OPTIMIZE_RUNS=26000 OPTIMIZE_RUNS_OFFRAMP=18000 OPTIMIZE_RUNS_ONRAMP=4100 -OPTIMIZE_RUNS_MULTI_OFFRAMP=2500 +OPTIMIZE_RUNS_MULTI_OFFRAMP=2000 SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol index cf2b836a56..969e971633 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -496,7 +496,10 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { /// its execution and enforce atomicity among successful message processing and token transfer. /// @dev We use ERC-165 to check for the ccipReceive interface to permit sending tokens to contracts /// (for example smart contract wallets) without an associated message. - function executeSingleMessage(Internal.Any2EVMRampMessage memory message, bytes[] memory offchainTokenData) external { + function executeSingleMessage( + Internal.Any2EVMRampMessage calldata message, + bytes[] calldata offchainTokenData + ) external { if (msg.sender != address(this)) revert CanOnlySelfCall(); Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](0); if (message.tokenAmounts.length > 0) { @@ -804,11 +807,11 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { /// @param offchainTokenData Data fetched offchain by the DON. /// @return destTokenAmount local token address with amount function _releaseOrMintSingleToken( - Internal.RampTokenAmount memory sourceTokenAmount, - bytes memory originalSender, + Internal.RampTokenAmount calldata sourceTokenAmount, + bytes calldata originalSender, address receiver, uint64 sourceChainSelector, - bytes memory offchainTokenData + bytes calldata offchainTokenData ) internal returns (Client.EVMTokenAmount memory destTokenAmount) { // We need to safely decode the token address from the sourceTokenData, as it could be wrong, // in which case it doesn't have to be a valid EVM address. @@ -883,11 +886,11 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { /// any non-rate limiting errors that may occur. If we encounter a rate limiting related error /// we bubble it up. If we encounter a non-rate limiting error we wrap it in a TokenHandlingError. function _releaseOrMintTokens( - Internal.RampTokenAmount[] memory sourceTokenAmounts, - bytes memory originalSender, + Internal.RampTokenAmount[] calldata sourceTokenAmounts, + bytes calldata originalSender, address receiver, uint64 sourceChainSelector, - bytes[] memory offchainTokenData + bytes[] calldata offchainTokenData ) internal returns (Client.EVMTokenAmount[] memory destTokenAmounts) { destTokenAmounts = new Client.EVMTokenAmount[](sourceTokenAmounts.length); for (uint256 i = 0; i < sourceTokenAmounts.length; ++i) { diff --git a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol index 581d9bd705..f966e04462 100644 --- a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol @@ -28,7 +28,7 @@ contract EVM2EVMMultiOffRampHelper is EVM2EVMMultiOffRamp, IgnoreContractSize { } function releaseOrMintSingleToken( - Internal.RampTokenAmount memory sourceTokenAmount, + Internal.RampTokenAmount calldata sourceTokenAmount, bytes calldata originalSender, address receiver, uint64 sourceChainSelector, @@ -39,8 +39,8 @@ contract EVM2EVMMultiOffRampHelper is EVM2EVMMultiOffRamp, IgnoreContractSize { } function releaseOrMintTokens( - Internal.RampTokenAmount[] memory sourceTokenAmounts, - bytes memory originalSender, + Internal.RampTokenAmount[] calldata sourceTokenAmounts, + bytes calldata originalSender, address receiver, uint64 sourceChainSelector, bytes[] calldata offchainTokenData diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go index 2dea06bd75..b3416214fc 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go @@ -164,7 +164,7 @@ type MultiOCR3BaseOCRConfigArgs struct { var EVM2EVMMultiOffRampMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162006bb338038062006bb38339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615edd62000cd6600039600081816102530152612cac0152600081816102240152612f860152600081816101f50152818161147b01526118d00152600081816101c501526128a1015260008181611e5e0152611eaa0152615edd6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b1461059c578063f716f99f146105af578063ff888fb1146105c257600080fd5b8063d2a15d3514610556578063e9d68a8e14610569578063ece670b61461058957600080fd5b8063991a5018116100bd578063991a5018146104de578063c673e584146104f1578063ccd37ba31461051157600080fd5b806385572ffb146104b55780638da5cb5b146104c357600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba50971461049a5780637d4eef60146104a257600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a366004614099565b6105e5565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d19190614208565b61018f6103313660046142b3565b6105f9565b61018f610344366004614366565b6109fd565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143ba565b610a66565b6040516102d19190614417565b61043d6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b830481166020850152780100000000000000000000000000000000000000000000000083048116948401949094527c01000000000000000000000000000000000000000000000000000000009091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610abc565b61018f6104b0366004614984565b610b7a565b61018f610177366004614aaf565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104ec366004614afe565b610d1a565b6105046104ff366004614b83565b610d2b565b6040516102d19190614be3565b61054861051f366004614c58565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f610564366004614c82565b610e89565b61057c610577366004614cf7565b610f43565b6040516102d19190614d12565b61018f610597366004614d60565b611062565b61018f6105aa366004614dc4565b6113d2565b61018f6105bd366004614e49565b6113e3565b6105d56105d0366004614f87565b611425565b60405190151581526020016102d1565b6105ed6114e6565b6105f681611542565b50565b600061060787890189615125565b8051515190915015158061062057508051602001515115155b156107205760095460208a01359067ffffffffffffffff808316911610156106df576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f926106a892910161538d565b600060405180830381600087803b1580156106c257600080fd5b505af11580156106d6573d6000803e3d6000fd5b5050505061071e565b81602001515160000361071e576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109465760008260200151828151811061074857610748615290565b6020026020010151905060008160000151905061076481611884565b600061076f82611986565b602084015151815491925067ffffffffffffffff9081167501000000000000000000000000000000000000000000909204161415806107c5575060208084015190810151905167ffffffffffffffff9182169116115b1561080e57825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526108059291906004016153a0565b60405180910390fd5b60408301518061084a576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108bd5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101829052604401610805565b60208085015101516108d09060016153eb565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000067ffffffffffffffff928316021790925592511660009081526008602090815260408083209483529390529190912042905550600101610723565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d816040516109769190615413565b60405180910390a16109f260008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506119ed915050565b505050505050505050565b610a3d610a0c828401846154b0565b6040805160008082526020820190925290610a37565b6060815260200190600190039081610a225790505b50611d64565b604080516000808252602082019092529050610a606001858585858660006119ed565b50505050565b6000610a74600160046154e5565b6002610a8160808561550e565b67ffffffffffffffff16610a959190615535565b610a9f8585611e14565b901c166003811115610ab357610ab36143ed565b90505b92915050565b6001546001600160a01b03163314610b165760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610805565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b82611e5b565b815181518114610bbe576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d0a576000848281518110610bdd57610bdd615290565b60200260200101519050600081602001515190506000858481518110610c0557610c05615290565b6020026020010151905080518214610c49576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cfb576000828281518110610c6857610c68615290565b6020026020010151905080600014610cf25784602001518281518110610c9057610c90615290565b602002602001015160800151811015610cf25784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024810183905260448101829052606401610805565b50600101610c4c565b50505050806001019050610bc1565b50610d158383611d64565b505050565b610d226114e6565b6105f681611edc565b610d6e6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610e1757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610df9575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e7957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e5b575b5050505050815250509050919050565b610e916114e6565b60005b81811015610d15576000838383818110610eb057610eb0615290565b905060400201803603810190610ec6919061554c565b9050610ed58160200151611425565b610f3a57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e94565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff161515938601939093527501000000000000000000000000000000000000000000909204909216948301949094526001840180549394929391840191610fe290615585565b80601f016020809104026020016040519081016040528092919081815260200182805461100e90615585565b8015610e795780601f1061103057610100808354040283529160200191610e79565b820191906000526020600020905b81548152906001019060200180831161103e57505050919092525091949350505050565b33301461109b576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600080825260208201909252816110d8565b60408051808201909152600080825260208201528152602001906001900390816110b15790505b5060a0840151519091501561110b576111088360a001518460200151856060015186600001516020015186612089565b90505b6040805160a0810182528451518152845160209081015167ffffffffffffffff1681830152808601518351600094840192611147929101614208565b60408051601f19818403018152918152908252868101516020830152018390526005549091506001600160a01b03168015611254576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a1906111c1908590600401615661565b600060405180830381600087803b1580156111db57600080fd5b505af19250505080156111ec575060015b611254573d80801561121a576040519150601f19603f3d011682016040523d82523d6000602084013e61121f565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016108059190614208565b60408501515115801561126957506080850151155b80611280575060608501516001600160a01b03163b155b806112c0575060608501516112be906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612167565b155b156112cc575050505050565b845160209081015167ffffffffffffffff16600090815260069091526040808220546080880151606089015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf97983926113449289926113889291600401615674565b6000604051808303816000875af1158015611363573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261138b91908101906156b0565b5091509150816113c957806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016108059190614208565b50505050505050565b6113da6114e6565b6105f681612183565b6113eb6114e6565b60005b81518110156114215761141982828151811061140c5761140c615290565b6020026020010151612239565b6001016113ee565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156114c2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab69190615746565b6000546001600160a01b031633146115405760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610805565b565b60005b815181101561142157600082828151811061156257611562615290565b602002602001015190506000816020015190508067ffffffffffffffff166000036115b9576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b03166115fa576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260066020526040812060018101805491929161162590615585565b80601f016020809104026020016040519081016040528092919081815260200182805461165190615585565b801561169e5780601f106116735761010080835404028352916020019161169e565b820191906000526020600020905b81548152906001019060200180831161168157829003601f168201915b5050505050905060008460600151905081516000036117815780516000036116f2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001830161170082826157ab565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000017835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16117d4565b80805190602001208280519060200120146117d4576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610805565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b9061186c90869061586b565b60405180910390a25050505050806001019050611545565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561191f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119439190615746565b156105f6576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610805565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610ab6576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610805565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611a4c8760a4615939565b9050826060015115611a94578451611a65906020615535565b8651611a72906020615535565b611a7d9060a0615939565b611a879190615939565b611a919082615939565b90505b368114611ad6576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610805565b5081518114611b1e5781516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610805565b611b26611e5b565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611b7457611b746143ed565b6002811115611b8557611b856143ed565b9052509050600281602001516002811115611ba257611ba26143ed565b148015611bf65750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611bde57611bde615290565b6000918252602090912001546001600160a01b031633145b611c2c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611d0e576020820151611c4790600161594c565b60ff16855114611c83576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611cbe576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611cd0929190615965565b604051908190038120611ce7918b90602001615975565b604051602081830303815290604052805190602001209050611d0c8a8288888861257d565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d9e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611e0d57611e05858281518110611dd357611dd3615290565b602002602001015184611dff57858381518110611df257611df2615290565b6020026020010151612794565b83612794565b600101611db5565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611e39608085615989565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f000000000000000000000000000000000000000000000000000000000000000014611540576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610805565b80516001600160a01b0316611f1d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16939093177c010000000000000000000000000000000000000000000000000000000093871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060855167ffffffffffffffff8111156120a5576120a5613eb0565b6040519080825280602002602001820160405280156120ea57816020015b60408051808201909152600080825260208201528152602001906001900390816120c35790505b50905060005b865181101561215d5761213887828151811061210e5761210e615290565b602002602001015187878787868151811061212b5761212b615290565b6020026020010151612f25565b82828151811061214a5761214a615290565b60209081029190910101526001016120f0565b5095945050505050565b60006121728361333c565b8015610ab35750610ab383836133a0565b336001600160a01b038216036121db5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610805565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff16600003612264576000604051631b3fab5160e11b815260040161080591906159b0565b60208082015160ff808216600090815260029093526040832060018101549293909283921690036122d157606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612326565b6060840151600182015460ff6201000090910416151590151514612326576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff84166004820152602401610805565b60a08401518051601f60ff82161115612355576001604051631b3fab5160e11b815260040161080591906159b0565b6123bb85856003018054806020026020016040519081016040528092919081815260200182805480156123b157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612393575b505050505061346f565b8560600151156124ea5761242985856002018054806020026020016040519081016040528092919081815260200182805480156123b1576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161239357505050505061346f565b608086015180516124439060028701906020840190613e0a565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f10156124a3576002604051631b3fab5160e11b815260040161080591906159b0565b60408801516124b39060036159ca565b60ff168160ff16116124db576003604051631b3fab5160e11b815260040161080591906159b0565b6124e7878360016134d8565b50505b6124f6858360026134d8565b815161250b9060038601906020850190613e0a565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f54793612564938a939260028b019291906159e6565b60405180910390a161257585613658565b505050505050565b612585613e7c565b835160005b8181101561278a5760006001888684602081106125a9576125a9615290565b6125b691901a601b61594c565b8985815181106125c8576125c8615290565b60200260200101518986815181106125e2576125e2615290565b602002602001015160405160008152602001604052604051612620949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612642573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b038516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156126a3576126a36143ed565b60028111156126b4576126b46143ed565b90525090506001816020015160028111156126d1576126d16143ed565b14612708576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061271f5761271f615290565b60200201511561275b576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061277657612776615290565b91151560209092020152505060010161258a565b5050505050505050565b815161279f81611884565b60006127aa82611986565b60208501515190915060008190036127ed576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461282b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561284657612846613eb0565b60405190808252806020026020018201604052801561286f578160200160208202803683370190505b50905060005b828110156129e45760008760200151828151811061289557612895615290565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461292857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610805565b6129be8186600101805461293b90615585565b80601f016020809104026020016040519081016040528092919081815260200182805461296790615585565b80156129b45780601f10612989576101008083540402835291602001916129b4565b820191906000526020600020905b81548152906001019060200180831161299757829003601f168201915b5050505050613674565b8383815181106129d0576129d0615290565b602090810291909101015250600101612875565b5060006129fb858389606001518a60800151613796565b905080600003612a43576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610805565b8551151560005b848110156109f257600089602001518281518110612a6a57612a6a615290565b602002602001015190506000612a8889836000015160600151610a66565b90506000816003811115612a9e57612a9e6143ed565b1480612abb57506003816003811115612ab957612ab96143ed565b145b612b12578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612f1d565b8315612be257600454600090600160a01b900463ffffffff16612b3587426154e5565b1190508080612b5557506003826003811115612b5357612b536143ed565b145b612b97576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b166004820152602401610805565b8a8481518110612ba957612ba9615290565b6020026020010151600014612bdc578a8481518110612bca57612bca615290565b60200260200101518360800181815250505b50612c43565b6000816003811115612bf657612bf66143ed565b14612c43578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612b03565b81516080015167ffffffffffffffff1615612d31576000816003811115612c6c57612c6c6143ed565b03612d315781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612ce3928e929190600401615a98565b6020604051808303816000875af1158015612d02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d269190615746565b612d31575050612f1d565b60008b604001518481518110612d4957612d49615290565b6020026020010151905080518360a001515114612dad578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d1660048301529091166024820152604401610805565b612dc18a84600001516060015160016137ec565b600080612dce8584613894565b91509150612de58c866000015160600151846137ec565b8615612e55576003826003811115612dff57612dff6143ed565b03612e55576000846003811115612e1857612e186143ed565b14612e55578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261080591908390600401615ac5565b6002826003811115612e6957612e696143ed565b14612ec3576003826003811115612e8257612e826143ed565b14612ec3578451606001516040517f926c5a3e000000000000000000000000000000000000000000000000000000008152610805918e918590600401615ade565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612f0f9087908790615b04565b60405180910390a450505050505b600101612a4a565b60408051808201909152600080825260208201526000612f48876020015161395e565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612fcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ff19190615b24565b90506001600160a01b038116158061303957506130376001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612167565b155b1561307b576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610805565b6000806131816040518061010001604052808b81526020018967ffffffffffffffff1681526020018a6001600160a01b031681526020018c606001518152602001866001600160a01b031681526020018c6000015181526020018c604001518152602001888152506040516024016130f39190615b41565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3907753700000000000000000000000000000000000000000000000000000000179052600454859063ffffffff7c0100000000000000000000000000000000000000000000000000000000909104166113886084613a04565b5091509150816131bf57806040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016108059190614208565b80516020146132075780516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610805565b60008180602001905181019061321d9190615c0e565b6040516001600160a01b0380871660248301528b166044820152606481018290529091506132d29060840160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052600454879063ffffffff7801000000000000000000000000000000000000000000000000909104166113886084613a04565b5090935091508261331157816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016108059190614208565b604080518082019091526001600160a01b039095168552602085015250919250505095945050505050565b6000613368827f01ffc9a7000000000000000000000000000000000000000000000000000000006133a0565b8015610ab65750613399827fffffffff000000000000000000000000000000000000000000000000000000006133a0565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613458575060208210155b80156134645750600081115b979650505050505050565b60005b8151811015610d155760ff8316600090815260036020526040812083519091908490849081106134a4576134a4615290565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613472565b60005b82518160ff161015610a60576000838260ff16815181106134fe576134fe615290565b602002602001015190506000600281111561351b5761351b6143ed565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561355a5761355a6143ed565b1461357b576004604051631b3fab5160e11b815260040161080591906159b0565b6001600160a01b0381166135bb576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156135e1576135e16143ed565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561363e5761363e6143ed565b0217905550905050508061365190615c27565b90506134db565b60ff81166105f6576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936136ba937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c46565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976137039794969395929491939101615c79565b604051602081830303815290604052805190602001208560400151805190602001208660a0015160405160200161373a9190615d70565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b6000806137a4858585613b2a565b90506137af81611425565b6137bd5760009150506137e4565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026137fb60808561550e565b67ffffffffffffffff1661380f9190615535565b9050600061381d8585611e14565b90508161382c600160046154e5565b901b191681836003811115613843576138436143ed565b67ffffffffffffffff871660009081526007602052604081209190921b92909217918291613872608088615989565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906138d89087908790600401615dd0565b600060405180830381600087803b1580156138f257600080fd5b505af1925050508015613903575060015b613942573d808015613931576040519150601f19603f3d011682016040523d82523d6000602084013e613936565b606091505b50600392509050613957565b50506040805160208101909152600081526002905b9250929050565b6000815160201461399d57816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016108059190614208565b6000828060200190518101906139b39190615c0e565b90506001600160a01b038111806139cb575061040081105b15610ab657826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016108059190614208565b6000606060008361ffff1667ffffffffffffffff811115613a2757613a27613eb0565b6040519080825280601f01601f191660200182016040528015613a51576020820181803683370190505b509150863b613a84577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613ab7577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613af0577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b135750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b6b576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b7f57506101018111155b613b9c576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bc6576040516309bde33960e01b815260040160405180910390fd5b80600003613bf35786600081518110613be157613be1615290565b60200260200101519350505050613dc2565b60008167ffffffffffffffff811115613c0e57613c0e613eb0565b604051908082528060200260200182016040528015613c37578160200160208202803683370190505b50905060008080805b85811015613d615760006001821b8b811603613c9b5788851015613c84578c5160018601958e918110613c7557613c75615290565b60200260200101519050613cbd565b8551600185019487918110613c7557613c75615290565b8b5160018401938d918110613cb257613cb2615290565b602002602001015190505b600089861015613ced578d5160018701968f918110613cde57613cde615290565b60200260200101519050613d0f565b8651600186019588918110613d0457613d04615290565b602002602001015190505b82851115613d30576040516309bde33960e01b815260040160405180910390fd5b613d3a8282613dc9565b878481518110613d4c57613d4c615290565b60209081029190910101525050600101613c40565b506001850382148015613d7357508683145b8015613d7e57508581145b613d9b576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613db057613db0615290565b60200260200101519750505050505050505b9392505050565b6000818310613de157613ddc8284613de7565b610ab3565b610ab383835b604080516001602082015290810183905260608101829052600090608001613778565b828054828255906000526020600020908101928215613e6c579160200282015b82811115613e6c578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e2a565b50613e78929150613e9b565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e785760008155600101613e9c565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613ee957613ee9613eb0565b60405290565b60405160a0810167ffffffffffffffff81118282101715613ee957613ee9613eb0565b60405160c0810167ffffffffffffffff81118282101715613ee957613ee9613eb0565b6040805190810167ffffffffffffffff81118282101715613ee957613ee9613eb0565b6040516060810167ffffffffffffffff81118282101715613ee957613ee9613eb0565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fa457613fa4613eb0565b604052919050565b600067ffffffffffffffff821115613fc657613fc6613eb0565b5060051b60200190565b6001600160a01b03811681146105f657600080fd5b803567ffffffffffffffff81168114613ffd57600080fd5b919050565b80151581146105f657600080fd5b8035613ffd81614002565b600067ffffffffffffffff82111561403557614035613eb0565b50601f01601f191660200190565b600082601f83011261405457600080fd5b81356140676140628261401b565b613f7b565b81815284602083860101111561407c57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140ac57600080fd5b823567ffffffffffffffff808211156140c457600080fd5b818501915085601f8301126140d857600080fd5b81356140e661406282613fac565b81815260059190911b8301840190848101908883111561410557600080fd5b8585015b838110156141ab578035858111156141215760008081fd5b86016080818c03601f19018113156141395760008081fd5b614141613ec6565b8983013561414e81613fd0565b8152604061415d848201613fe5565b8b83015260608085013561417081614002565b8383015292840135928984111561418957600091508182fd5b6141978f8d86880101614043565b908301525085525050918601918601614109565b5098975050505050505050565b60005b838110156141d35781810151838201526020016141bb565b50506000910152565b600081518084526141f48160208601602086016141b8565b601f01601f19169290920160200192915050565b602081526000610ab360208301846141dc565b8060608101831015610ab657600080fd5b60008083601f84011261423e57600080fd5b50813567ffffffffffffffff81111561425657600080fd5b60208301915083602082850101111561395757600080fd5b60008083601f84011261428057600080fd5b50813567ffffffffffffffff81111561429857600080fd5b6020830191508360208260051b850101111561395757600080fd5b60008060008060008060008060e0898b0312156142cf57600080fd5b6142d98a8a61421b565b9750606089013567ffffffffffffffff808211156142f657600080fd5b6143028c838d0161422c565b909950975060808b013591508082111561431b57600080fd5b6143278c838d0161426e565b909750955060a08b013591508082111561434057600080fd5b5061434d8b828c0161426e565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561437b57600080fd5b614385858561421b565b9250606084013567ffffffffffffffff8111156143a157600080fd5b6143ad8682870161422c565b9497909650939450505050565b600080604083850312156143cd57600080fd5b6143d683613fe5565b91506143e460208401613fe5565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614413576144136143ed565b9052565b60208101610ab68284614403565b600060a0828403121561443757600080fd5b61443f613eef565b90508135815261445160208301613fe5565b602082015261446260408301613fe5565b604082015261447360608301613fe5565b606082015261448460808301613fe5565b608082015292915050565b8035613ffd81613fd0565b600082601f8301126144ab57600080fd5b813560206144bb61406283613fac565b82815260059290921b840181019181810190868411156144da57600080fd5b8286015b848110156145b057803567ffffffffffffffff808211156144ff5760008081fd5b8189019150608080601f19848d0301121561451a5760008081fd5b614522613ec6565b87840135838111156145345760008081fd5b6145428d8a83880101614043565b825250604080850135848111156145595760008081fd5b6145678e8b83890101614043565b8a84015250606080860135858111156145805760008081fd5b61458e8f8c838a0101614043565b92840192909252949092013593810193909352505083529183019183016144de565b509695505050505050565b600061014082840312156145ce57600080fd5b6145d6613f12565b90506145e28383614425565b815260a082013567ffffffffffffffff808211156145ff57600080fd5b61460b85838601614043565b602084015260c084013591508082111561462457600080fd5b61463085838601614043565b604084015261464160e0850161448f565b6060840152610100840135608084015261012084013591508082111561466657600080fd5b506146738482850161449a565b60a08301525092915050565b600082601f83011261469057600080fd5b813560206146a061406283613fac565b82815260059290921b840181019181810190868411156146bf57600080fd5b8286015b848110156145b057803567ffffffffffffffff8111156146e35760008081fd5b6146f18986838b01016145bb565b8452509183019183016146c3565b600082601f83011261471057600080fd5b8135602061472061406283613fac565b82815260059290921b8401810191818101908684111561473f57600080fd5b8286015b848110156145b057803567ffffffffffffffff8111156147635760008081fd5b6147718986838b0101614043565b845250918301918301614743565b600082601f83011261479057600080fd5b813560206147a061406283613fac565b82815260059290921b840181019181810190868411156147bf57600080fd5b8286015b848110156145b057803567ffffffffffffffff8111156147e35760008081fd5b6147f18986838b01016146ff565b8452509183019183016147c3565b600082601f83011261481057600080fd5b8135602061482061406283613fac565b8083825260208201915060208460051b87010193508684111561484257600080fd5b602086015b848110156145b05780358352918301918301614847565b600082601f83011261486f57600080fd5b8135602061487f61406283613fac565b82815260059290921b8401810191818101908684111561489e57600080fd5b8286015b848110156145b057803567ffffffffffffffff808211156148c35760008081fd5b818901915060a080601f19848d030112156148de5760008081fd5b6148e6613eef565b6148f1888501613fe5565b8152604080850135848111156149075760008081fd5b6149158e8b8389010161467f565b8a840152506060808601358581111561492e5760008081fd5b61493c8f8c838a010161477f565b83850152506080915081860135858111156149575760008081fd5b6149658f8c838a01016147ff565b91840191909152509190930135908301525083529183019183016148a2565b600080604080848603121561499857600080fd5b833567ffffffffffffffff808211156149b057600080fd5b6149bc8783880161485e565b94506020915081860135818111156149d357600080fd5b8601601f810188136149e457600080fd5b80356149f261406282613fac565b81815260059190911b8201840190848101908a831115614a1157600080fd5b8584015b83811015614a9d57803586811115614a2d5760008081fd5b8501603f81018d13614a3f5760008081fd5b87810135614a4f61406282613fac565b81815260059190911b82018a0190898101908f831115614a6f5760008081fd5b928b01925b82841015614a8d5783358252928a0192908a0190614a74565b8652505050918601918601614a15565b50809750505050505050509250929050565b600060208284031215614ac157600080fd5b813567ffffffffffffffff811115614ad857600080fd5b820160a08185031215613dc257600080fd5b803563ffffffff81168114613ffd57600080fd5b600060a08284031215614b1057600080fd5b614b18613eef565b8235614b2381613fd0565b8152614b3160208401614aea565b6020820152614b4260408401614aea565b6040820152614b5360608401614aea565b60608201526080830135614b6681613fd0565b60808201529392505050565b803560ff81168114613ffd57600080fd5b600060208284031215614b9557600080fd5b610ab382614b72565b60008151808452602080850194506020840160005b83811015614bd85781516001600160a01b031687529582019590820190600101614bb3565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c3260e0840182614b9e565b90506040840151601f198483030160c0850152614c4f8282614b9e565b95945050505050565b60008060408385031215614c6b57600080fd5b614c7483613fe5565b946020939093013593505050565b60008060208385031215614c9557600080fd5b823567ffffffffffffffff80821115614cad57600080fd5b818501915085601f830112614cc157600080fd5b813581811115614cd057600080fd5b8660208260061b8501011115614ce557600080fd5b60209290920196919550909350505050565b600060208284031215614d0957600080fd5b610ab382613fe5565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526137e460a08401826141dc565b60008060408385031215614d7357600080fd5b823567ffffffffffffffff80821115614d8b57600080fd5b614d97868387016145bb565b93506020850135915080821115614dad57600080fd5b50614dba858286016146ff565b9150509250929050565b600060208284031215614dd657600080fd5b8135613dc281613fd0565b600082601f830112614df257600080fd5b81356020614e0261406283613fac565b8083825260208201915060208460051b870101935086841115614e2457600080fd5b602086015b848110156145b0578035614e3c81613fd0565b8352918301918301614e29565b60006020808385031215614e5c57600080fd5b823567ffffffffffffffff80821115614e7457600080fd5b818501915085601f830112614e8857600080fd5b8135614e9661406282613fac565b81815260059190911b83018401908481019088831115614eb557600080fd5b8585015b838110156141ab57803585811115614ed057600080fd5b860160c0818c03601f19011215614ee75760008081fd5b614eef613f12565b8882013581526040614f02818401614b72565b8a8301526060614f13818501614b72565b8284015260809150614f26828501614010565b9083015260a08381013589811115614f3e5760008081fd5b614f4c8f8d83880101614de1565b838501525060c0840135915088821115614f665760008081fd5b614f748e8c84870101614de1565b9083015250845250918601918601614eb9565b600060208284031215614f9957600080fd5b5035919050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114613ffd57600080fd5b600082601f830112614fdd57600080fd5b81356020614fed61406283613fac565b82815260069290921b8401810191818101908684111561500c57600080fd5b8286015b848110156145b057604081890312156150295760008081fd5b615031613f35565b61503a82613fe5565b8152615047858301614fa0565b81860152835291830191604001615010565b600082601f83011261506a57600080fd5b8135602061507a61406283613fac565b82815260079290921b8401810191818101908684111561509957600080fd5b8286015b848110156145b05780880360808112156150b75760008081fd5b6150bf613f58565b6150c883613fe5565b8152604080601f19840112156150de5760008081fd5b6150e6613f35565b92506150f3878501613fe5565b8352615100818501613fe5565b838801528187019290925260608301359181019190915283529183019160800161509d565b6000602080838503121561513857600080fd5b823567ffffffffffffffff8082111561515057600080fd5b8185019150604080838803121561516657600080fd5b61516e613f35565b83358381111561517d57600080fd5b84016040818a03121561518f57600080fd5b615197613f35565b8135858111156151a657600080fd5b8201601f81018b136151b757600080fd5b80356151c561406282613fac565b81815260069190911b8201890190898101908d8311156151e457600080fd5b928a01925b828410156152345787848f0312156152015760008081fd5b615209613f35565b843561521481613fd0565b8152615221858d01614fa0565b818d0152825292870192908a01906151e9565b84525050508187013593508484111561524c57600080fd5b6152588a858401614fcc565b818801528252508385013591508282111561527257600080fd5b61527e88838601615059565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561531257835180516001600160a01b031684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168584015292840192918501916001016152c6565b50508583015187820388850152805180835290840192506000918401905b80831015615381578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685830152928401926001929092019190850190615330565b50979650505050505050565b602081526000610ab360208301846152a6565b67ffffffffffffffff8316815260608101613dc26020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561540c5761540c6153d5565b5092915050565b60006020808352606084516040808487015261543260608701836152a6565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141ab57845167ffffffffffffffff81511683528781015161549289850182805167ffffffffffffffff908116835260209182015116910152565b50840151828701529386019360019290920191608090910190615453565b6000602082840312156154c257600080fd5b813567ffffffffffffffff8111156154d957600080fd5b6137e48482850161485e565b81810381811115610ab657610ab66153d5565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff80841680615529576155296154f8565b92169190910692915050565b8082028115828204841417610ab657610ab66153d5565b60006040828403121561555e57600080fd5b615566613f35565b61556f83613fe5565b8152602083013560208201528091505092915050565b600181811c9082168061559957607f821691505b6020821081036155b957634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a060408701526155f360a08701826141dc565b90506060850151868203606088015261560c82826141dc565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561538157835180516001600160a01b031683528601518683015292850192600192909201919084019061562f565b602081526000610ab360208301846155bf565b60808152600061568760808301876155bf565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b6000806000606084860312156156c557600080fd5b83516156d081614002565b602085015190935067ffffffffffffffff8111156156ed57600080fd5b8401601f810186136156fe57600080fd5b805161570c6140628261401b565b81815287602083850101111561572157600080fd5b6157328260208301602086016141b8565b809450505050604084015190509250925092565b60006020828403121561575857600080fd5b8151613dc281614002565b601f821115610d15576000816000526020600020601f850160051c8101602086101561578c5750805b601f850160051c820191505b8181101561257557828155600101615798565b815167ffffffffffffffff8111156157c5576157c5613eb0565b6157d9816157d38454615585565b84615763565b602080601f83116001811461580e57600084156157f65750858301515b600019600386901b1c1916600185901b178555612575565b600085815260208120601f198616915b8281101561583d5788860151825594840194600190910190840161581e565b508582101561585b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546158bd81615585565b8060a089015260c060018316600081146158de57600181146158fa5761592a565b60ff19841660c08b015260c083151560051b8b0101945061592a565b85600052602060002060005b848110156159215781548c8201850152908801908901615906565b8b0160c0019550505b50929998505050505050505050565b80820180821115610ab657610ab66153d5565b60ff8181168382160190811115610ab657610ab66153d5565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff808416806159a4576159a46154f8565b92169190910492915050565b60208101600583106159c4576159c46143ed565b91905290565b60ff818116838216029081169081811461540c5761540c6153d5565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a3e5784546001600160a01b031683526001948501949284019201615a19565b50508481036060860152865180825290820192508187019060005b81811015615a7e5782516001600160a01b031685529383019391830191600101615a59565b50505060ff851660808501525090505b9695505050505050565b600067ffffffffffffffff808616835280851660208401525060606040830152614c4f60608301846141dc565b8281526040602082015260006137e460408301846141dc565b67ffffffffffffffff848116825283166020820152606081016137e46040830184614403565b615b0e8184614403565b6040602082015260006137e460408301846141dc565b600060208284031215615b3657600080fd5b8151613dc281613fd0565b6020815260008251610100806020850152615b606101208501836141dc565b91506020850151615b7d604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615bb760a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bd484836141dc565b935060c08701519150808685030160e0870152615bf184836141dc565b935060e0870151915080868503018387015250615a8e83826141dc565b600060208284031215615c2057600080fd5b5051919050565b600060ff821660ff8103615c3d57615c3d6153d5565b60010192915050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152615a8e60808301846141dc565b86815260c060208201526000615c9260c08301886141dc565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d6357601f19868403018952815160808151818652615d0f828701826141dc565b9150508582015185820387870152615d2782826141dc565b91505060408083015186830382880152615d4183826141dc565b6060948501519790940196909652505098840198925090830190600101615ce9565b5090979650505050505050565b602081526000610ab36020830184615ccc565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d6357601f19868403018952615dbe8383516141dc565b98840198925090830190600101615da2565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e386101808501836141dc565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e7584836141dc565b935060608801519150615e946101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615ebb8282615ccc565b9150508281036020840152614c4f8185615d8356fea164736f6c6343000818000a", + Bin: "0x6101206040523480156200001257600080fd5b5060405162006cd538038062006cd58339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615fff62000cd6600039600081816102530152612c5e0152600081816102240152612f750152600081816101f5015281816114c101526118d20152600081816101c50152612853015260008181611e600152611eac0152615fff6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b1461056e578063f716f99f14610581578063ff888fb11461059457600080fd5b8063d2a15d3514610528578063e9d68a8e1461053b578063ece670b61461055b57600080fd5b8063991a5018116100bd578063991a5018146104b0578063c673e584146104c3578063ccd37ba3146104e357600080fd5b806385572ffb146104875780638da5cb5b1461049557600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba50971461046c5780637d4eef601461047457600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a366004614122565b6105b7565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d19190614284565b61018f61033136600461432f565b6105cb565b61018f6103443660046143e2565b6109ab565b60095460405167ffffffffffffffff90911681526020016102d1565b610378610373366004614436565b610a14565b6040516102d19190614493565b61040f6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b830481166020850152600160c01b8304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610a6a565b61018f6104823660046149e6565b610b28565b61018f610177366004614b11565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104be366004614b60565b610cc8565b6104d66104d1366004614be5565b610cd9565b6040516102d19190614c45565b61051a6104f1366004614cba565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f610536366004614ce4565b610e37565b61054e610549366004614d59565b610ef1565b6040516102d19190614d74565b61018f610569366004614dc2565b610ffe565b61018f61057c366004614e27565b611418565b61018f61058f366004614eac565b611429565b6105a76105a2366004614fea565b61146b565b60405190151581526020016102d1565b6105bf61152c565b6105c881611588565b50565b60006105d987890189615173565b805151519091501515806105f257508051602001515115155b156106f25760095460208a01359067ffffffffffffffff808316911610156106b1576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261067a9291016153b1565b600060405180830381600087803b15801561069457600080fd5b505af11580156106a8573d6000803e3d6000fd5b505050506106f0565b8160200151516000036106f0576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156108f45760008260200151828151811061071a5761071a6152de565b6020026020010151905060008160000151905061073681611886565b600061074182611988565b602084015151815491925067ffffffffffffffff908116600160a81b90920416141580610785575060208084015190810151905167ffffffffffffffff9182169116115b156107ce57825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107c59291906004016153c4565b60405180910390fd5b60408301518061080a576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff1660009081526008602090815260408083208484529091529020541561087d5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016107c5565b602080850151015161089090600161540f565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff9283160217909255925116600090815260086020908152604080832094835293905291909120429055506001016106f5565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d816040516109249190615437565b60405180910390a16109a060008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506119ef915050565b505050505050505050565b6109eb6109ba828401846154d4565b60408051600080825260208201909252906109e5565b60608152602001906001900390816109d05790505b50611d66565b604080516000808252602082019092529050610a0e6001858585858660006119ef565b50505050565b6000610a2260016004615509565b6002610a2f608085615532565b67ffffffffffffffff16610a439190615559565b610a4d8585611e16565b901c166003811115610a6157610a61614469565b90505b92915050565b6001546001600160a01b03163314610ac45760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107c5565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b30611e5d565b815181518114610b6c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610cb8576000848281518110610b8b57610b8b6152de565b60200260200101519050600081602001515190506000858481518110610bb357610bb36152de565b6020026020010151905080518214610bf7576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610ca9576000828281518110610c1657610c166152de565b6020026020010151905080600014610ca05784602001518281518110610c3e57610c3e6152de565b602002602001015160800151811015610ca05784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016107c5565b50600101610bfa565b50505050806001019050610b6f565b50610cc38383611d66565b505050565b610cd061152c565b6105c881611ede565b610d1c6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610dc557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610da7575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e2757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e09575b5050505050815250509050919050565b610e3f61152c565b60005b81811015610cc3576000838383818110610e5e57610e5e6152de565b905060400201803603810190610e749190615570565b9050610e83816020015161146b565b610ee857805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e42565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191610f7e906155a9565b80601f0160208091040260200160405190810160405280929190818152602001828054610faa906155a9565b8015610e275780601f10610fcc57610100808354040283529160200191610e27565b820191906000526020600020905b815481529060010190602001808311610fda57505050919092525091949350505050565b333014611037576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611074565b604080518082019091526000808252602082015281526020019060019003908161104d5790505b50905060006110876101208601866155e3565b905011156110d8576110d56110a06101208601866155e3565b6110ad60a088018861562d565b6110be6101008a0160e08b01614e27565b6110ce60408b0160208c01614d59565b898961202f565b90505b6040805160a081018252853581526000916020808301916110fe91908901908901614d59565b67ffffffffffffffff16815260200161111a60a088018861562d565b60405160200161112b929190615674565b60408051601f19818403018152919052815260200161114d60c088018861562d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050908252506020018390526005549091506001600160a01b03168015611277576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a1906111e4908590600401615745565b600060405180830381600087803b1580156111fe57600080fd5b505af192505050801561120f575060015b611277573d80801561123d576040519150601f19603f3d011682016040523d82523d6000602084013e611242565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016107c59190614284565b61128460c087018761562d565b15905080156112965750610100860135155b806112b957506112ad610100870160e08801614e27565b6001600160a01b03163b155b8061130557506113037f85572ffb000000000000000000000000000000000000000000000000000000006112f4610100890160e08a01614e27565b6001600160a01b031690612123565b155b1561131257505050505050565b60008060068161132860408b0160208c01614d59565b67ffffffffffffffff1681526020810191909152604001600020546001600160a01b0316633cf97983856113886101008c0180359061136a9060e08f01614e27565b6040518563ffffffff1660e01b81526004016113899493929190615758565b6000604051808303816000875af11580156113a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113d09190810190615794565b50915091508161140e57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107c59190614284565b5050505050505050565b61142061152c565b6105c88161213f565b61143161152c565b60005b81518110156114675761145f828281518110611452576114526152de565b60200260200101516121f5565b600101611434565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611508573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a64919061582a565b6000546001600160a01b031633146115865760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107c5565b565b60005b81518110156114675760008282815181106115a8576115a86152de565b602002602001015190506000816020015190508067ffffffffffffffff166000036115ff576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611627576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff81166000908152600660205260408120600181018054919291611652906155a9565b80601f016020809104026020016040519081016040528092919081815260200182805461167e906155a9565b80156116cb5780601f106116a0576101008083540402835291602001916116cb565b820191906000526020600020905b8154815290600101906020018083116116ae57829003601f168201915b505050505090506000846060015190508151600003611783578051600003611706576040516342bcdf7f60e11b815260040160405180910390fd5b60018301611714828261588f565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16117d6565b80805190602001208280519060200120146117d6576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016107c5565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b9061186e90869061594f565b60405180910390a2505050505080600101905061158b565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611921573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611945919061582a565b156105c8576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107c5565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610a64576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107c5565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611a4e8760a4615a1d565b9050826060015115611a96578451611a67906020615559565b8651611a74906020615559565b611a7f9060a0615a1d565b611a899190615a1d565b611a939082615a1d565b90505b368114611ad8576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107c5565b5081518114611b205781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107c5565b611b28611e5d565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611b7657611b76614469565b6002811115611b8757611b87614469565b9052509050600281602001516002811115611ba457611ba4614469565b148015611bf85750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611be057611be06152de565b6000918252602090912001546001600160a01b031633145b611c2e576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611d10576020820151611c49906001615a30565b60ff16855114611c85576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611cc0576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611cd2929190615a49565b604051908190038120611ce9918b90602001615a59565b604051602081830303815290604052805190602001209050611d0e8a82888888612539565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611da0576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611e0f57611e07858281518110611dd557611dd56152de565b602002602001015184611e0157858381518110611df457611df46152de565b6020026020010151612746565b83612746565b600101611db7565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611e3b608085615a6d565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f000000000000000000000000000000000000000000000000000000000000000014611586576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107c5565b80516001600160a01b0316611f06576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60608767ffffffffffffffff81111561204a5761204a613f39565b60405190808252806020026020018201604052801561208f57816020015b60408051808201909152600080825260208201528152602001906001900390816120685790505b50905060005b88811015612116576120f18a8a838181106120b2576120b26152de565b90506020028101906120c49190615a94565b898989898989888181106120da576120da6152de565b90506020028101906120ec919061562d565b612ed7565b828281518110612103576121036152de565b6020908102919091010152600101612095565b5098975050505050505050565b600061212e836133da565b8015610a615750610a61838361343e565b336001600160a01b038216036121975760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107c5565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff16600003612220576000604051631b3fab5160e11b81526004016107c59190615ad2565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361228d57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff9092169190911790556122e2565b6060840151600182015460ff62010000909104161515901515146122e2576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016107c5565b60a08401518051601f60ff82161115612311576001604051631b3fab5160e11b81526004016107c59190615ad2565b612377858560030180548060200260200160405190810160405280929190818152602001828054801561236d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161234f575b50505050506134f8565b8560600151156124a6576123e5858560020180548060200260200160405190810160405280929190818152602001828054801561236d576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161234f5750505050506134f8565b608086015180516123ff9060028701906020840190613e93565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f101561245f576002604051631b3fab5160e11b81526004016107c59190615ad2565b604088015161246f906003615aec565b60ff168160ff1611612497576003604051631b3fab5160e11b81526004016107c59190615ad2565b6124a387836001613561565b50505b6124b285836002613561565b81516124c79060038601906020850190613e93565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f54793612520938a939260028b01929190615b08565b60405180910390a1612531856136e1565b505050505050565b612541613f05565b835160005b8181101561140e576000600188868460208110612565576125656152de565b61257291901a601b615a30565b898581518110612584576125846152de565b602002602001015189868151811061259e5761259e6152de565b6020026020010151604051600081526020016040526040516125dc949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156125fe573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561265f5761265f614469565b600281111561267057612670614469565b905250905060018160200151600281111561268d5761268d614469565b146126c4576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f81106126db576126db6152de565b602002015115612717576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f8110612732576127326152de565b911515602090920201525050600101612546565b815161275181611886565b600061275c82611988565b602085015151909150600081900361279f576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84604001515181146127dd576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156127f8576127f8613f39565b604051908082528060200260200182016040528015612821578160200160208202803683370190505b50905060005b8281101561299657600087602001518281518110612847576128476152de565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff16146128da57805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107c5565b612970818660010180546128ed906155a9565b80601f0160208091040260200160405190810160405280929190818152602001828054612919906155a9565b80156129665780601f1061293b57610100808354040283529160200191612966565b820191906000526020600020905b81548152906001019060200180831161294957829003601f168201915b50505050506136fd565b838381518110612982576129826152de565b602090810291909101015250600101612827565b5060006129ad858389606001518a6080015161381f565b9050806000036129f5576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107c5565b8551151560005b848110156109a057600089602001518281518110612a1c57612a1c6152de565b602002602001015190506000612a3a89836000015160600151610a14565b90506000816003811115612a5057612a50614469565b1480612a6d57506003816003811115612a6b57612a6b614469565b145b612ac4578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612ecf565b8315612b9457600454600090600160a01b900463ffffffff16612ae78742615509565b1190508080612b0757506003826003811115612b0557612b05614469565b145b612b49576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b1660048201526024016107c5565b8a8481518110612b5b57612b5b6152de565b6020026020010151600014612b8e578a8481518110612b7c57612b7c6152de565b60200260200101518360800181815250505b50612bf5565b6000816003811115612ba857612ba8614469565b14612bf5578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612ab5565b81516080015167ffffffffffffffff1615612ce3576000816003811115612c1e57612c1e614469565b03612ce35781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c95928e929190600401615bba565b6020604051808303816000875af1158015612cb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cd8919061582a565b612ce3575050612ecf565b60008b604001518481518110612cfb57612cfb6152de565b6020026020010151905080518360a001515114612d5f578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d16600483015290911660248201526044016107c5565b612d738a8460000151606001516001613875565b600080612d80858461391d565b91509150612d978c86600001516060015184613875565b8615612e07576003826003811115612db157612db1614469565b03612e07576000846003811115612dca57612dca614469565b14612e07578451516040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526107c591908390600401615be7565b6002826003811115612e1b57612e1b614469565b14612e75576003826003811115612e3457612e34614469565b14612e75578451606001516040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526107c5918e918590600401615c00565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612ec19087908790615c26565b60405180910390a450505050505b6001016129fc565b60408051808201909152600080825260208201526000612f37612efd60208b018b61562d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506139e792505050565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612fbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe09190615c46565b90506001600160a01b038116158061302857506130266001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612123565b155b1561306a576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016107c5565b6000806132476040518061010001604052808d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020018a67ffffffffffffffff1681526020018b6001600160a01b031681526020018e606001358152602001866001600160a01b031681526020018e806000019061310e919061562d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020018e8060400190613166919061562d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250604080516020601f8c018190048102820181019092528a815291810191908b908b908190840183828082843760009201919091525050509152506040516131e79190602401615c63565b60408051601f198184030181529190526020810180516001600160e01b03167f3907753700000000000000000000000000000000000000000000000000000000179052600454859063ffffffff600160e01b909104166113886084613a8d565b50915091508161328557806040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107c59190614284565b80516020146132cd5780516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107c5565b6000818060200190518101906132e39190615d30565b6040516001600160a01b0380871660248301528c1660448201526064810182905290915061336e9060840160408051601f198184030181529190526020810180516001600160e01b03167f23b872dd00000000000000000000000000000000000000000000000000000000179052600454879063ffffffff600160c01b909104166113886084613a8d565b509093509150826133ad57816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107c59190614284565b604080518082019091526001600160a01b0390951685526020850152509192505050979650505050505050565b6000613406827f01ffc9a70000000000000000000000000000000000000000000000000000000061343e565b8015610a645750613437827fffffffff0000000000000000000000000000000000000000000000000000000061343e565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156134e1575060208210155b80156134ed5750600081115b979650505050505050565b60005b8151811015610cc35760ff83166000908152600360205260408120835190919084908490811061352d5761352d6152de565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff191690556001016134fb565b60005b82518160ff161015610a0e576000838260ff1681518110613587576135876152de565b60200260200101519050600060028111156135a4576135a4614469565b60ff80871660009081526003602090815260408083206001600160a01b038716845290915290205461010090041660028111156135e3576135e3614469565b14613604576004604051631b3fab5160e11b81526004016107c59190615ad2565b6001600160a01b038116613644576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff16815260200184600281111561366a5761366a614469565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff1916176101008360028111156136c7576136c7614469565b021790555090505050806136da90615d49565b9050613564565b60ff81166105c8576009805467ffffffffffffffff1916905550565b815160208082015160409283015192516000938493613743937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615d68565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d0151950151959761378c9794969395929491939101615d9b565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016137c39190615e92565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061382d858585613bb3565b90506138388161146b565b61384657600091505061386d565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b60006002613884608085615532565b67ffffffffffffffff166138989190615559565b905060006138a68585611e16565b9050816138b560016004615509565b901b1916818360038111156138cc576138cc614469565b67ffffffffffffffff871660009081526007602052604081209190921b929092179182916138fb608088615a6d565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906139619087908790600401615ef2565b600060405180830381600087803b15801561397b57600080fd5b505af192505050801561398c575060015b6139cb573d8080156139ba576040519150601f19603f3d011682016040523d82523d6000602084013e6139bf565b606091505b506003925090506139e0565b50506040805160208101909152600081526002905b9250929050565b60008151602014613a2657816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107c59190614284565b600082806020019051810190613a3c9190615d30565b90506001600160a01b03811180613a54575061040081105b15610a6457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107c59190614284565b6000606060008361ffff1667ffffffffffffffff811115613ab057613ab0613f39565b6040519080825280601f01601f191660200182016040528015613ada576020820181803683370190505b509150863b613b0d577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613b40577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613b79577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b9c5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613bf4576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613c0857506101018111155b613c25576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613c4f576040516309bde33960e01b815260040160405180910390fd5b80600003613c7c5786600081518110613c6a57613c6a6152de565b60200260200101519350505050613e4b565b60008167ffffffffffffffff811115613c9757613c97613f39565b604051908082528060200260200182016040528015613cc0578160200160208202803683370190505b50905060008080805b85811015613dea5760006001821b8b811603613d245788851015613d0d578c5160018601958e918110613cfe57613cfe6152de565b60200260200101519050613d46565b8551600185019487918110613cfe57613cfe6152de565b8b5160018401938d918110613d3b57613d3b6152de565b602002602001015190505b600089861015613d76578d5160018701968f918110613d6757613d676152de565b60200260200101519050613d98565b8651600186019588918110613d8d57613d8d6152de565b602002602001015190505b82851115613db9576040516309bde33960e01b815260040160405180910390fd5b613dc38282613e52565b878481518110613dd557613dd56152de565b60209081029190910101525050600101613cc9565b506001850382148015613dfc57508683145b8015613e0757508581145b613e24576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613e3957613e396152de565b60200260200101519750505050505050505b9392505050565b6000818310613e6a57613e658284613e70565b610a61565b610a6183835b604080516001602082015290810183905260608101829052600090608001613801565b828054828255906000526020600020908101928215613ef5579160200282015b82811115613ef5578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613eb3565b50613f01929150613f24565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613f015760008155600101613f25565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613f7257613f72613f39565b60405290565b60405160a0810167ffffffffffffffff81118282101715613f7257613f72613f39565b60405160c0810167ffffffffffffffff81118282101715613f7257613f72613f39565b6040805190810167ffffffffffffffff81118282101715613f7257613f72613f39565b6040516060810167ffffffffffffffff81118282101715613f7257613f72613f39565b604051601f8201601f1916810167ffffffffffffffff8111828210171561402d5761402d613f39565b604052919050565b600067ffffffffffffffff82111561404f5761404f613f39565b5060051b60200190565b6001600160a01b03811681146105c857600080fd5b803567ffffffffffffffff8116811461408657600080fd5b919050565b80151581146105c857600080fd5b80356140868161408b565b600067ffffffffffffffff8211156140be576140be613f39565b50601f01601f191660200190565b600082601f8301126140dd57600080fd5b81356140f06140eb826140a4565b614004565b81815284602083860101111561410557600080fd5b816020850160208301376000918101602001919091529392505050565b6000602080838503121561413557600080fd5b823567ffffffffffffffff8082111561414d57600080fd5b818501915085601f83011261416157600080fd5b813561416f6140eb82614035565b81815260059190911b8301840190848101908883111561418e57600080fd5b8585015b83811015612116578035858111156141aa5760008081fd5b86016080818c03601f19018113156141c25760008081fd5b6141ca613f4f565b898301356141d781614059565b815260406141e684820161406e565b8b8301526060808501356141f98161408b565b8383015292840135928984111561421257600091508182fd5b6142208f8d868801016140cc565b908301525085525050918601918601614192565b60005b8381101561424f578181015183820152602001614237565b50506000910152565b60008151808452614270816020860160208601614234565b601f01601f19169290920160200192915050565b602081526000610a616020830184614258565b8060608101831015610a6457600080fd5b60008083601f8401126142ba57600080fd5b50813567ffffffffffffffff8111156142d257600080fd5b6020830191508360208285010111156139e057600080fd5b60008083601f8401126142fc57600080fd5b50813567ffffffffffffffff81111561431457600080fd5b6020830191508360208260051b85010111156139e057600080fd5b60008060008060008060008060e0898b03121561434b57600080fd5b6143558a8a614297565b9750606089013567ffffffffffffffff8082111561437257600080fd5b61437e8c838d016142a8565b909950975060808b013591508082111561439757600080fd5b6143a38c838d016142ea565b909750955060a08b01359150808211156143bc57600080fd5b506143c98b828c016142ea565b999c989b50969995989497949560c00135949350505050565b6000806000608084860312156143f757600080fd5b6144018585614297565b9250606084013567ffffffffffffffff81111561441d57600080fd5b614429868287016142a8565b9497909650939450505050565b6000806040838503121561444957600080fd5b6144528361406e565b91506144606020840161406e565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061448f5761448f614469565b9052565b60208101610a64828461447f565b600060a082840312156144b357600080fd5b6144bb613f78565b9050813581526144cd6020830161406e565b60208201526144de6040830161406e565b60408201526144ef6060830161406e565b60608201526145006080830161406e565b608082015292915050565b803561408681614059565b600082601f83011261452757600080fd5b813560206145376140eb83614035565b82815260059290921b8401810191818101908684111561455657600080fd5b8286015b8481101561462c57803567ffffffffffffffff8082111561457b5760008081fd5b8189019150608080601f19848d030112156145965760008081fd5b61459e613f4f565b87840135838111156145b05760008081fd5b6145be8d8a838801016140cc565b825250604080850135848111156145d55760008081fd5b6145e38e8b838901016140cc565b8a84015250606080860135858111156145fc5760008081fd5b61460a8f8c838a01016140cc565b928401929092529490920135938101939093525050835291830191830161455a565b509695505050505050565b600082601f83011261464857600080fd5b813560206146586140eb83614035565b82815260059290921b8401810191818101908684111561467757600080fd5b8286015b8481101561462c57803567ffffffffffffffff8082111561469c5760008081fd5b818901915061014080601f19848d030112156146b85760008081fd5b6146c0613f9b565b6146cc8c8986016144a1565b815260c0840135838111156146e15760008081fd5b6146ef8d8a838801016140cc565b898301525060e0840135838111156147075760008081fd5b6147158d8a838801016140cc565b604083015250614728610100850161450b565b6060820152610120840135608082015290830135908282111561474b5760008081fd5b6147598c8984870101614516565b60a0820152865250505091830191830161467b565b600082601f83011261477f57600080fd5b8135602061478f6140eb83614035565b82815260059290921b840181019181810190868411156147ae57600080fd5b8286015b8481101561462c57803567ffffffffffffffff808211156147d257600080fd5b818901915089603f8301126147e657600080fd5b858201356147f66140eb82614035565b81815260059190911b830160400190878101908c83111561481657600080fd5b604085015b8381101561484f5780358581111561483257600080fd5b6148418f6040838a01016140cc565b84525091890191890161481b565b508752505050928401925083016147b2565b600082601f83011261487257600080fd5b813560206148826140eb83614035565b8083825260208201915060208460051b8701019350868411156148a457600080fd5b602086015b8481101561462c57803583529183019183016148a9565b600082601f8301126148d157600080fd5b813560206148e16140eb83614035565b82815260059290921b8401810191818101908684111561490057600080fd5b8286015b8481101561462c57803567ffffffffffffffff808211156149255760008081fd5b818901915060a080601f19848d030112156149405760008081fd5b614948613f78565b61495388850161406e565b8152604080850135848111156149695760008081fd5b6149778e8b83890101614637565b8a84015250606080860135858111156149905760008081fd5b61499e8f8c838a010161476e565b83850152506080915081860135858111156149b95760008081fd5b6149c78f8c838a0101614861565b9184019190915250919093013590830152508352918301918301614904565b60008060408084860312156149fa57600080fd5b833567ffffffffffffffff80821115614a1257600080fd5b614a1e878388016148c0565b9450602091508186013581811115614a3557600080fd5b8601601f81018813614a4657600080fd5b8035614a546140eb82614035565b81815260059190911b8201840190848101908a831115614a7357600080fd5b8584015b83811015614aff57803586811115614a8f5760008081fd5b8501603f81018d13614aa15760008081fd5b87810135614ab16140eb82614035565b81815260059190911b82018a0190898101908f831115614ad15760008081fd5b928b01925b82841015614aef5783358252928a0192908a0190614ad6565b8652505050918601918601614a77565b50809750505050505050509250929050565b600060208284031215614b2357600080fd5b813567ffffffffffffffff811115614b3a57600080fd5b820160a08185031215613e4b57600080fd5b803563ffffffff8116811461408657600080fd5b600060a08284031215614b7257600080fd5b614b7a613f78565b8235614b8581614059565b8152614b9360208401614b4c565b6020820152614ba460408401614b4c565b6040820152614bb560608401614b4c565b60608201526080830135614bc881614059565b60808201529392505050565b803560ff8116811461408657600080fd5b600060208284031215614bf757600080fd5b610a6182614bd4565b60008151808452602080850194506020840160005b83811015614c3a5781516001600160a01b031687529582019590820190600101614c15565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c9460e0840182614c00565b90506040840151601f198483030160c0850152614cb18282614c00565b95945050505050565b60008060408385031215614ccd57600080fd5b614cd68361406e565b946020939093013593505050565b60008060208385031215614cf757600080fd5b823567ffffffffffffffff80821115614d0f57600080fd5b818501915085601f830112614d2357600080fd5b813581811115614d3257600080fd5b8660208260061b8501011115614d4757600080fd5b60209290920196919550909350505050565b600060208284031215614d6b57600080fd5b610a618261406e565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff60408301511660608201526000606083015160808084015261386d60a0840182614258565b600080600060408486031215614dd757600080fd5b833567ffffffffffffffff80821115614def57600080fd5b908501906101408288031215614e0457600080fd5b90935060208501359080821115614e1a57600080fd5b50614429868287016142ea565b600060208284031215614e3957600080fd5b8135613e4b81614059565b600082601f830112614e5557600080fd5b81356020614e656140eb83614035565b8083825260208201915060208460051b870101935086841115614e8757600080fd5b602086015b8481101561462c578035614e9f81614059565b8352918301918301614e8c565b60006020808385031215614ebf57600080fd5b823567ffffffffffffffff80821115614ed757600080fd5b818501915085601f830112614eeb57600080fd5b8135614ef96140eb82614035565b81815260059190911b83018401908481019088831115614f1857600080fd5b8585015b8381101561211657803585811115614f3357600080fd5b860160c0818c03601f19011215614f4a5760008081fd5b614f52613f9b565b8882013581526040614f65818401614bd4565b8a8301526060614f76818501614bd4565b8284015260809150614f89828501614099565b9083015260a08381013589811115614fa15760008081fd5b614faf8f8d83880101614e44565b838501525060c0840135915088821115614fc95760008081fd5b614fd78e8c84870101614e44565b9083015250845250918601918601614f1c565b600060208284031215614ffc57600080fd5b5035919050565b80356001600160e01b038116811461408657600080fd5b600082601f83011261502b57600080fd5b8135602061503b6140eb83614035565b82815260069290921b8401810191818101908684111561505a57600080fd5b8286015b8481101561462c57604081890312156150775760008081fd5b61507f613fbe565b6150888261406e565b8152615095858301615003565b8186015283529183019160400161505e565b600082601f8301126150b857600080fd5b813560206150c86140eb83614035565b82815260079290921b840181019181810190868411156150e757600080fd5b8286015b8481101561462c5780880360808112156151055760008081fd5b61510d613fe1565b6151168361406e565b8152604080601f198401121561512c5760008081fd5b615134613fbe565b925061514187850161406e565b835261514e81850161406e565b83880152818701929092526060830135918101919091528352918301916080016150eb565b6000602080838503121561518657600080fd5b823567ffffffffffffffff8082111561519e57600080fd5b818501915060408083880312156151b457600080fd5b6151bc613fbe565b8335838111156151cb57600080fd5b84016040818a0312156151dd57600080fd5b6151e5613fbe565b8135858111156151f457600080fd5b8201601f81018b1361520557600080fd5b80356152136140eb82614035565b81815260069190911b8201890190898101908d83111561523257600080fd5b928a01925b828410156152825787848f03121561524f5760008081fd5b615257613fbe565b843561526281614059565b815261526f858d01615003565b818d0152825292870192908a0190615237565b84525050508187013593508484111561529a57600080fd5b6152a68a85840161501a565b81880152825250838501359150828211156152c057600080fd5b6152cc888386016150a7565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561534b57835180516001600160a01b031684528501516001600160e01b0316858401529284019291850191600101615314565b50508583015187820388850152805180835290840192506000918401905b808310156153a5578351805167ffffffffffffffff1683528501516001600160e01b031685830152928401926001929092019190850190615369565b50979650505050505050565b602081526000610a6160208301846152f4565b67ffffffffffffffff8316815260608101613e4b6020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff818116838216019080821115615430576154306153f9565b5092915050565b60006020808352606084516040808487015261545660608701836152f4565b87850151878203601f19016040890152805180835290860193506000918601905b8083101561211657845167ffffffffffffffff8151168352878101516154b689850182805167ffffffffffffffff908116835260209182015116910152565b50840151828701529386019360019290920191608090910190615477565b6000602082840312156154e657600080fd5b813567ffffffffffffffff8111156154fd57600080fd5b61386d848285016148c0565b81810381811115610a6457610a646153f9565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff8084168061554d5761554d61551c565b92169190910692915050565b8082028115828204841417610a6457610a646153f9565b60006040828403121561558257600080fd5b61558a613fbe565b6155938361406e565b8152602083013560208201528091505092915050565b600181811c908216806155bd57607f821691505b6020821081036155dd57634e487b7160e01b600052602260045260246000fd5b50919050565b6000808335601e198436030181126155fa57600080fd5b83018035915067ffffffffffffffff82111561561557600080fd5b6020019150600581901b36038213156139e057600080fd5b6000808335601e1984360301811261564457600080fd5b83018035915067ffffffffffffffff82111561565f57600080fd5b6020019150368190038213156139e057600080fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a060408701526156d760a0870182614258565b9050606085015186820360608801526156f08282614258565b608087810151898303918a01919091528051808352908601935060009250908501905b808310156153a557835180516001600160a01b0316835286015186830152928501926001929092019190840190615713565b602081526000610a6160208301846156a3565b60808152600061576b60808301876156a3565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b6000806000606084860312156157a957600080fd5b83516157b48161408b565b602085015190935067ffffffffffffffff8111156157d157600080fd5b8401601f810186136157e257600080fd5b80516157f06140eb826140a4565b81815287602083850101111561580557600080fd5b615816826020830160208601614234565b809450505050604084015190509250925092565b60006020828403121561583c57600080fd5b8151613e4b8161408b565b601f821115610cc3576000816000526020600020601f850160051c810160208610156158705750805b601f850160051c820191505b818110156125315782815560010161587c565b815167ffffffffffffffff8111156158a9576158a9613f39565b6158bd816158b784546155a9565b84615847565b602080601f8311600181146158f257600084156158da5750858301515b600019600386901b1c1916600185901b178555612531565b600085815260208120601f198616915b8281101561592157888601518255948401946001909101908401615902565b508582101561593f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546159a1816155a9565b8060a089015260c060018316600081146159c257600181146159de57615a0e565b60ff19841660c08b015260c083151560051b8b01019450615a0e565b85600052602060002060005b84811015615a055781548c82018501529088019089016159ea565b8b0160c0019550505b50929998505050505050505050565b80820180821115610a6457610a646153f9565b60ff8181168382160190811115610a6457610a646153f9565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff80841680615a8857615a8861551c565b92169190910492915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112615ac857600080fd5b9190910192915050565b6020810160058310615ae657615ae6614469565b91905290565b60ff8181168382160290811690818114615430576154306153f9565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615b605784546001600160a01b031683526001948501949284019201615b3b565b50508481036060860152865180825290820192508187019060005b81811015615ba05782516001600160a01b031685529383019391830191600101615b7b565b50505060ff851660808501525090505b9695505050505050565b600067ffffffffffffffff808616835280851660208401525060606040830152614cb16060830184614258565b82815260406020820152600061386d6040830184614258565b67ffffffffffffffff8481168252831660208201526060810161386d604083018461447f565b615c30818461447f565b60406020820152600061386d6040830184614258565b600060208284031215615c5857600080fd5b8151613e4b81614059565b6020815260008251610100806020850152615c82610120850183614258565b91506020850151615c9f604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615cd960a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615cf68483614258565b935060c08701519150808685030160e0870152615d138483614258565b935060e0870151915080868503018387015250615bb08382614258565b600060208284031215615d4257600080fd5b5051919050565b600060ff821660ff8103615d5f57615d5f6153f9565b60010192915050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152615bb06080830184614258565b86815260c060208201526000615db460c0830188614258565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615e8557601f19868403018952815160808151818652615e3182870182614258565b9150508582015185820387870152615e498282614258565b91505060408083015186830382880152615e638382614258565b6060948501519790940196909652505098840198925090830190600101615e0b565b5090979650505050505050565b602081526000610a616020830184615dee565b60008282518085526020808601955060208260051b8401016020860160005b84811015615e8557601f19868403018952615ee0838351614258565b98840198925090830190600101615ec4565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615f5a610180850183614258565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615f978483614258565b935060608801519150615fb66101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615fdd8282615dee565b9150508281036020840152614cb18185615ea556fea164736f6c6343000818000a", } var EVM2EVMMultiOffRampABI = EVM2EVMMultiOffRampMetaData.ABI diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 6195708b13..8498d2aabf 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -10,7 +10,7 @@ ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderT commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin ddc26c10c2a52b59624faae9005827b09b98db4566887a736005e8cc37cf8a51 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin ebd8aac686fa28a71d4212bcd25a28f8f640d50dce5e50498b2f6b8534890b69 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de -evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin cb1c4d1bd8460181f1545524bc2537a58f6839ee0acad6a068f5e24216a9cee9 +evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 2b3284f25be1c46ad1c7896fef47d812133e0bdb78cf5e48618c4f3aba5fe3d4 evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 15cd5695049ab4be1f396ec1d7b609738b2bcefa3740a7a48316e1f72506a34a evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin ea2a9622ace941075ea62cd348e9c69c5aa3bf8a7daf298fea51984f80a1d27d evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin bf1a3090a2f8d1632b82a6d45200cf6f3833a1e27303745405c1ed13ffc0cf83 From be239b84d9c3ae64bf00f6664dc7a31215d17a6c Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Fri, 9 Aug 2024 11:02:46 +0200 Subject: [PATCH 197/432] undo transferFrom, assert balance in offRamp (#1273) ## Motivation It is significantly cheaper to assert balances than do the transferFrom ## Solution Undo recent approve changes, add balance assertions had to undo some of the multiOfframp calldata changes to make it fit --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/gas-snapshots/ccip.gas-snapshot | 430 +++++++++--------- .../liquiditymanager.gas-snapshot | 8 +- .../scripts/native_solc_compile_all_ccip | 2 +- contracts/src/v0.8/ccip/interfaces/IPool.sol | 2 + .../src/v0.8/ccip/libraries/Internal.sol | 2 + contracts/src/v0.8/ccip/libraries/Pool.sol | 3 +- .../v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 63 ++- .../src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol | 56 ++- .../ccip/pools/BurnMintTokenPoolAbstract.sol | 5 +- .../ccip/pools/BurnMintTokenPoolAndProxy.sol | 3 +- .../src/v0.8/ccip/pools/LegacyPoolWrapper.sol | 7 +- .../v0.8/ccip/pools/LockReleaseTokenPool.sol | 4 +- .../pools/LockReleaseTokenPoolAndProxy.sol | 4 +- .../v0.8/ccip/pools/USDC/USDCTokenPool.sol | 15 +- contracts/src/v0.8/ccip/test/BaseTest.t.sol | 2 +- contracts/src/v0.8/ccip/test/arm/RMN.t.sol | 2 +- .../ccip/test/capability/CCIPConfig.t.sol | 12 +- .../v0.8/ccip/test/e2e/MultiRampsEnd2End.sol | 2 +- .../test/helpers/BurnMintMultiTokenPool.sol | 2 +- .../test/helpers/EVM2EVMOffRampHelper.sol | 2 +- .../MaybeRevertingBurnMintTokenPool.sol | 13 +- .../ccip/test/legacy/TokenPoolAndProxy.t.sol | 5 +- .../test/mocks/MockE2EUSDCTokenMessenger.sol | 28 +- .../test/mocks/MockE2EUSDCTransmitter.sol | 17 +- .../test/offRamp/EVM2EVMMultiOffRamp.t.sol | 136 ++++-- .../ccip/test/offRamp/EVM2EVMOffRamp.t.sol | 148 ++++-- .../ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol | 4 +- .../ccip/test/pools/BurnMintTokenPool.t.sol | 8 +- .../v0.8/ccip/test/pools/USDCTokenPool.t.sol | 33 +- .../burn_from_mint_token_pool.go | 2 +- .../burn_mint_token_pool.go | 2 +- .../burn_mint_token_pool_and_proxy.go | 2 +- .../burn_with_from_mint_token_pool.go | 2 +- .../evm_2_evm_multi_offramp.go | 4 +- .../evm_2_evm_offramp/evm_2_evm_offramp.go | 4 +- .../lock_release_token_pool.go | 2 +- .../lock_release_token_pool_and_proxy.go | 2 +- .../mock_usdc_token_messenger.go | 2 +- .../mock_usdc_token_transmitter.go | 2 +- .../usdc_token_pool/usdc_token_pool.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 22 +- 41 files changed, 664 insertions(+), 402 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index d2920bccd6..f0239bb13b 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -27,14 +27,14 @@ BurnMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 27522) BurnMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) BurnMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 241381) BurnMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 17677) -BurnMintTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 28623) -BurnMintTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56078) -BurnMintTokenPool_releaseOrMint:test_PoolMint_Success() (gas: 136256) +BurnMintTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 28757) +BurnMintTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56190) +BurnMintTokenPool_releaseOrMint:test_PoolMint_Success() (gas: 112319) BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28761) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243517) BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 24304) -CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2132877) +CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2132747) CCIPConfigSetup:test_getCapabilityConfiguration_Success() (gas: 9517) CCIPConfig_ConfigStateMachine:test__computeConfigDigest_Success() (gas: 70831) CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_InitToRunning_Success() (gas: 363708) @@ -71,8 +71,8 @@ CCIPConfig_constructor:test_constructor_ZeroAddressNotAllowed_Revert() (gas: 617 CCIPConfig_updatePluginConfig:test__updatePluginConfig_InitToRunning_Success() (gas: 1057346) CCIPConfig_updatePluginConfig:test__updatePluginConfig_InvalidConfigLength_Reverts() (gas: 27539) CCIPConfig_updatePluginConfig:test__updatePluginConfig_InvalidConfigStateTransition_Reverts() (gas: 23105) -CCIPConfig_updatePluginConfig:test__updatePluginConfig_RunningToStaging_Success() (gas: 2009267) -CCIPConfig_updatePluginConfig:test__updatePluginConfig_StagingToRunning_Success() (gas: 2616097) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_RunningToStaging_Success() (gas: 2009250) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_StagingToRunning_Success() (gas: 2616080) CCIPConfig_updatePluginConfig:test_getCapabilityConfiguration_Success() (gas: 9605) CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsHasDuplicates_Reverts() (gas: 294893) CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsNotASubsetOfP2PIds_Reverts() (gas: 298325) @@ -122,10 +122,14 @@ CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424253) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1134031) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 35297) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 109266) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() (gas: 82186) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1102244) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38423) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 106249) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 87420) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 38957) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 96514) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 41963) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 88705) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 468131) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99235) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12399) @@ -134,124 +138,124 @@ EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Succ EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13267) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17992) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15347) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 293675) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 235065) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 155958) -EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 185346) -EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 144597) -EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 535800) -EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10437) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 296108) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 237498) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 156818) +EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187013) +EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 145410) +EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 518289) +EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10439) EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15662) -EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67352) -EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59642) -EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58722) -EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6551526) -EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 6134666) -EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106187) -EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116097) -EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106208) -EVM2EVMMultiOffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351415) -EVM2EVMMultiOffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159329) -EVM2EVMMultiOffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136447) -EVM2EVMMultiOffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136719) -EVM2EVMMultiOffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 58990) -EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225639) -EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117474) -EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77538) -EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 204931) -EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6545849) -EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47718) -EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 6138723) -EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137096) -EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103813) -EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101684) -EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139670) -EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101583) -EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101628) +EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67354) +EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59644) +EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58724) +EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6524644) +EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 6107782) +EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106189) +EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116101) +EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106210) +EVM2EVMMultiOffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351423) +EVM2EVMMultiOffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159331) +EVM2EVMMultiOffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136449) +EVM2EVMMultiOffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136723) +EVM2EVMMultiOffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 58992) +EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225643) +EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117476) +EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77540) +EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 204935) +EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6518967) +EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47720) +EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 6111838) +EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137047) +EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103764) +EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101635) +EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139621) +EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101534) +EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101579) EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17302) -EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1528648) -EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 335293) -EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 255311) -EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6601133) -EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6184014) +EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1552919) +EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 339300) +EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 257742) +EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6575061) +EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6157940) EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 27703) -EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 162229) -EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 146207) -EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6963185) -EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17154) -EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 15990) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 257007) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 19245) -EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 200549) -EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47986) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 47509) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 228029) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 84667) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 288361) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 91710) -EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35075) -EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23918) -EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 455362) -EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54395) -EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35864) -EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154305) -EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35286) -EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 178399) -EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 189636) -EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48022) -EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 440076) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 247866) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 170058) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 189731) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 258294) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 126611) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 399848) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65819) -EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80859) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 549604) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 494562) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35690) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 534868) -EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 532763) -EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 502067) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 124993) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 154216) +EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 163041) +EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147019) +EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6937113) +EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17155) +EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18208) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 246620) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20468) +EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 205259) +EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48751) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48274) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229582) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86220) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 277517) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92475) +EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35122) +EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23922) +EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 454148) +EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54442) +EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35911) +EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154354) +EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35333) +EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 179211) +EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 190495) +EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48069) +EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 440888) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 249490) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 171682) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 191355) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259412) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 127423) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 389034) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65866) +EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80906) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 532146) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 477104) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35738) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 517123) +EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 514491) +EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 484609) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 125852) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 155075) EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3655340) EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118202) EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87461) -EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75264) -EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26419) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 162127) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 203471) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 25962) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152111) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 503574) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2285870) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 205727) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 206304) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 649014) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 295645) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 160246) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 21873) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 55762) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 36070) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 72786) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 186613) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 304312) +EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75627) +EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26467) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 162940) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205097) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26010) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152936) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 505200) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2282834) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 207353) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 207930) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 657112) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 298887) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 164096) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 23740) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 64509) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 39546) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 81533) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 176182) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 189384) EVM2EVMMultiOffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11379) -EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215350) +EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215352) EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14162) EVM2EVMMultiOffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11660) EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49203) EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27169) -EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 236919) -EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 245516) -EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 299471) -EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 290788) -EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176548) -EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178616) -EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141477) -EVM2EVMMultiOffRamp_verify:test_TooManyLeaves_Revert() (gas: 51508) +EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 221738) +EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 230339) +EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 297319) +EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 279957) +EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176552) +EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178620) +EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141481) +EVM2EVMMultiOffRamp_verify:test_TooManyLeaves_Revert() (gas: 51510) EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 63649) EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() (gas: 13308) EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94175) @@ -277,7 +281,7 @@ EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Succ EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 205670) EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 121815) EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 143193) -EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3859258) +EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3872608) EVM2EVMMultiOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108546) EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 73975) EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 262685) @@ -293,78 +297,82 @@ EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 1 EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939) EVM2EVMMultiOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 51996) EVM2EVMMultiOnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97214) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 38281) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 107601) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_revert_Revert() (gas: 80501) -EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 410921) -EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 146964) -EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 796129) -EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 177860) -EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 29914) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 61712) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 44959) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 223836) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 333749) -EVM2EVMOffRamp__report:test_Report_Success() (gas: 127410) -EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 256629) -EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 265220) -EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 345584) -EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 324341) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37938) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103821) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85346) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 36874) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 94390) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 39856) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 86647) +EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 383754) +EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 141161) +EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 799482) +EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 178530) +EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 28497) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 65704) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 42547) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 210257) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 221523) +EVM2EVMOffRamp__report:test_Report_Success() (gas: 125920) +EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 236524) +EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 245118) +EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 325971) +EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 311010) EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17009) -EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153130) -EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5259602) -EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 143864) +EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153371) +EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5425677) +EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 144105) EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21323) -EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36486) -EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51652) -EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 482308) -EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 46374) -EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152404) -EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 102702) -EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 164769) -EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Success() (gas: 179100) -EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 41317) -EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 159267) -EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 174480) -EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 248585) -EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114991) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 420095) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54147) -EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 132007) -EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52129) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 578154) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 516730) -EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35486) -EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 565731) -EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 63974) -EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 123206) -EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 143416) -EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 428184) -EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 20582) -EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 291635) -EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20209) -EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 220994) -EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48632) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48098) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 326624) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 72423) -EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 231228) -EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 279720) -EVM2EVMOffRamp_execute_upgrade:test_V2OffRampNonceSkipsIfMsgInFlight_Success() (gas: 260962) -EVM2EVMOffRamp_execute_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 229250) -EVM2EVMOffRamp_execute_upgrade:test_V2_Success() (gas: 131633) +EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36411) +EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51577) +EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 472096) +EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 46299) +EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152329) +EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 102812) +EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 163277) +EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Success() (gas: 177533) +EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 41242) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 156287) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 171500) +EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 246452) +EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 113501) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 406819) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54072) +EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 130517) +EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52060) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 555692) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 494268) +EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35373) +EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 543379) +EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64253) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 121641) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 141851) +EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 426732) +EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 17855) +EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 277453) +EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 17998) +EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 220737) +EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47215) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 46683) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 313238) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 68652) +EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 228248) +EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 275250) +EVM2EVMOffRamp_execute_upgrade:test_V2OffRampNonceSkipsIfMsgInFlight_Success() (gas: 257907) +EVM2EVMOffRamp_execute_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 224780) +EVM2EVMOffRamp_execute_upgrade:test_V2_Success() (gas: 130143) EVM2EVMOffRamp_getAllRateLimitTokens:test_GetAllRateLimitTokens_Success() (gas: 38408) EVM2EVMOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3213556) EVM2EVMOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 83091) -EVM2EVMOffRamp_manuallyExecute:test_LowGasLimitManualExec_Success() (gas: 483152) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 186041) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecForkedChain_Revert() (gas: 25894) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 43519) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 25997) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithGasOverride_Success() (gas: 188342) -EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187789) -EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2029273) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143654) +EVM2EVMOffRamp_manuallyExecute:test_LowGasLimitManualExec_Success() (gas: 480170) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 183057) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecForkedChain_Revert() (gas: 25819) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 43294) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 25922) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithGasOverride_Success() (gas: 185360) +EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 184807) +EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2024509) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 142162) EVM2EVMOffRamp_metadataHash:test_MetadataHash_Success() (gas: 8838) EVM2EVMOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 40131) EVM2EVMOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 38214) @@ -396,14 +404,14 @@ EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59347) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179148) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 177430) EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137322) -EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3809477) +EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3822827) EVM2EVMOnRamp_forwardFromRouter:test_TooManyTokens_Revert() (gas: 30187) EVM2EVMOnRamp_forwardFromRouter:test_Unhealthy_Revert() (gas: 43300) EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109283) EVM2EVMOnRamp_forwardFromRouter:test_ZeroAddressReceiver_Revert() (gas: 312579) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_ShouldStoreLinkFees_Success() (gas: 112322) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 72206) -EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 710661) +EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 710531) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 147664) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 190529) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 121320) @@ -488,21 +496,21 @@ EtherSenderReceiverTest_validatedMessage:test_validatedMessage_tokenOverwrittenT EtherSenderReceiverTest_validatedMessage:test_validatedMessage_validMessage_extraArgs() (gas: 26292) LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Revert() (gas: 10992) LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Success() (gas: 18058) -LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3390790) -LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3387189) +LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3360094) +LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3356493) LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_Unauthorized_Revert() (gas: 11380) LockReleaseTokenPoolPoolAndProxy_supportsInterface:test_SupportsInterface_Success() (gas: 9977) LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60043) LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11355) -LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3145874) +LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3124819) LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29942) LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Success() (gas: 79844) LockReleaseTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 59464) -LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3142317) +LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3121261) LockReleaseTokenPool_provideLiquidity:test_Unauthorized_Revert() (gas: 11380) LockReleaseTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 72644) LockReleaseTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56196) -LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 237556) +LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 225108) LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Revert() (gas: 10992) LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Success() (gas: 18058) LockReleaseTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 9977) @@ -598,18 +606,18 @@ MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 393335) -MultiRampsE2E:test_E2E_3MessagesSuccess_gas() (gas: 1409277) +MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1385041) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71847) -NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 249565) -NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 251888) -NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 303932) -NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 287881) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 247821) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 235877) -NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 141822) +NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 248887) +NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 251210) +NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 304066) +NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 287250) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 243351) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 231407) +NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 142634) NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 167625) NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 218724) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) @@ -831,9 +839,9 @@ Router_applyRampUpdates:test_OffRampUpdatesWithRouting() (gas: 10642128) Router_applyRampUpdates:test_OnRampDisable() (gas: 55913) Router_applyRampUpdates:test_OnlyOwner_Revert() (gas: 12311) Router_ccipSend:test_CCIPSendLinkFeeNoTokenSuccess_gas() (gas: 113886) -Router_ccipSend:test_CCIPSendLinkFeeOneTokenSuccess_gas() (gas: 201407) +Router_ccipSend:test_CCIPSendLinkFeeOneTokenSuccess_gas() (gas: 201342) Router_ccipSend:test_CCIPSendNativeFeeNoTokenSuccess_gas() (gas: 128533) -Router_ccipSend:test_CCIPSendNativeFeeOneTokenSuccess_gas() (gas: 216056) +Router_ccipSend:test_CCIPSendNativeFeeOneTokenSuccess_gas() (gas: 215991) Router_ccipSend:test_FeeTokenAmountTooLow_Revert() (gas: 66275) Router_ccipSend:test_InvalidMsgValue() (gas: 31963) Router_ccipSend:test_NativeFeeTokenInsufficientValue() (gas: 68746) @@ -886,10 +894,10 @@ TokenAdminRegistry_setPool:test_setPool_Success() (gas: 35943) TokenAdminRegistry_setPool:test_setPool_ZeroAddressRemovesPool_Success() (gas: 30617) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_OnlyAdministrator_Revert() (gas: 18043) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_Success() (gas: 49390) -TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6139245) -TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6406966) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6984900) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7168991) +TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6066750) +TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6311731) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6910329) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7094420) TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2209837) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12089) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23324) @@ -920,9 +928,9 @@ TokenPool_setRemotePool:test_setRemotePool_Success() (gas: 281912) TokenProxy_ccipSend:test_CcipSendGasShouldBeZero_Revert() (gas: 17109) TokenProxy_ccipSend:test_CcipSendInsufficientAllowance_Revert() (gas: 136228) TokenProxy_ccipSend:test_CcipSendInvalidToken_Revert() (gas: 15919) -TokenProxy_ccipSend:test_CcipSendNative_Success() (gas: 245256) +TokenProxy_ccipSend:test_CcipSendNative_Success() (gas: 245191) TokenProxy_ccipSend:test_CcipSendNoDataAllowed_Revert() (gas: 16303) -TokenProxy_ccipSend:test_CcipSend_Success() (gas: 261620) +TokenProxy_ccipSend:test_CcipSend_Success() (gas: 261568) TokenProxy_constructor:test_Constructor() (gas: 13812) TokenProxy_getFee:test_GetFeeGasShouldBeZero_Revert() (gas: 16827) TokenProxy_getFee:test_GetFeeInvalidToken_Revert() (gas: 12658) @@ -931,11 +939,11 @@ TokenProxy_getFee:test_GetFee_Success() (gas: 86702) USDCTokenPool__validateMessage:test_ValidateInvalidMessage_Revert() (gas: 25290) USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35322) USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 30073) -USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 132731) +USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 133102) USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 477183) -USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 288285) +USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 268111) USDCTokenPool_releaseOrMint:test_TokenMaxCapacityExceeded_Revert() (gas: 50676) -USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 118967) +USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 98591) USDCTokenPool_setDomains:test_InvalidDomain_Revert() (gas: 66150) USDCTokenPool_setDomains:test_OnlyOwner_Revert() (gas: 11333) USDCTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 9876) \ No newline at end of file diff --git a/contracts/gas-snapshots/liquiditymanager.gas-snapshot b/contracts/gas-snapshots/liquiditymanager.gas-snapshot index 52a99e078d..6f67684cfc 100644 --- a/contracts/gas-snapshots/liquiditymanager.gas-snapshot +++ b/contracts/gas-snapshots/liquiditymanager.gas-snapshot @@ -3,9 +3,9 @@ LiquidityManager_addLiquidity:test_addLiquiditySuccess() (gas: 279154) LiquidityManager_rebalanceLiquidity:test_InsufficientLiquidityReverts() (gas: 206745) LiquidityManager_rebalanceLiquidity:test_InvalidRemoteChainReverts() (gas: 192319) LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess() (gas: 9141768) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 8981838) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 8977044) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 8904842) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 8960797) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 8956003) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 8883801) LiquidityManager_rebalanceLiquidity:test_rebalanceLiquiditySuccess() (gas: 382897) LiquidityManager_receive:test_receive_success() (gas: 21182) LiquidityManager_removeLiquidity:test_InsufficientLiquidityReverts() (gas: 184869) @@ -19,7 +19,7 @@ LiquidityManager_setFinanceRole:test_OnlyOwnerReverts() (gas: 10987) LiquidityManager_setFinanceRole:test_setFinanceRoleSuccess() (gas: 21836) LiquidityManager_setLocalLiquidityContainer:test_OnlyOwnerReverts() (gas: 11052) LiquidityManager_setLocalLiquidityContainer:test_ReverstWhen_CalledWithTheZeroAddress() (gas: 10643) -LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3519863) +LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3498806) LiquidityManager_setMinimumLiquidity:test_OnlyOwnerReverts() (gas: 10925) LiquidityManager_setMinimumLiquidity:test_setMinimumLiquiditySuccess() (gas: 36389) LiquidityManager_withdrawERC20:test_withdrawERC20Reverts() (gas: 180359) diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index fd38ae3562..fbc9fc6608 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -8,7 +8,7 @@ echo " └─────────────────────── SOLC_VERSION="0.8.24" OPTIMIZE_RUNS=26000 -OPTIMIZE_RUNS_OFFRAMP=18000 +OPTIMIZE_RUNS_OFFRAMP=22000 OPTIMIZE_RUNS_ONRAMP=4100 OPTIMIZE_RUNS_MULTI_OFFRAMP=2000 diff --git a/contracts/src/v0.8/ccip/interfaces/IPool.sol b/contracts/src/v0.8/ccip/interfaces/IPool.sol index 5d5c95e03c..fee010173f 100644 --- a/contracts/src/v0.8/ccip/interfaces/IPool.sol +++ b/contracts/src/v0.8/ccip/interfaces/IPool.sol @@ -19,6 +19,8 @@ interface IPoolV1 is IERC165 { /// @param releaseOrMintIn All data required to release or mint tokens. /// @return releaseOrMintOut The amount of tokens released or minted on the local chain, denominated /// in the local token's decimals. + /// @dev The offramp asserts that the balanceOf of the receiver has been incremented by exactly the number + /// of tokens that is returned in ReleaseOrMintOutV1.destinationAmount. If the amounts do not match, the tx reverts. function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) external returns (Pool.ReleaseOrMintOutV1 memory); diff --git a/contracts/src/v0.8/ccip/libraries/Internal.sol b/contracts/src/v0.8/ccip/libraries/Internal.sol index 4aa2f975e4..e13492acc9 100644 --- a/contracts/src/v0.8/ccip/libraries/Internal.sol +++ b/contracts/src/v0.8/ccip/libraries/Internal.sol @@ -16,6 +16,8 @@ library Internal { // malicious contracts from returning large amounts of data and causing // repeated out-of-gas scenarios. uint16 internal constant MAX_RET_BYTES = 4 + 4 * 32; + /// @dev The expected number of bytes returned by the balanceOf function. + uint256 internal constant MAX_BALANCE_OF_RET_BYTES = 32; /// @notice A collection of token price and gas price updates. /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. diff --git a/contracts/src/v0.8/ccip/libraries/Pool.sol b/contracts/src/v0.8/ccip/libraries/Pool.sol index 263ee380e8..391beb00c1 100644 --- a/contracts/src/v0.8/ccip/libraries/Pool.sol +++ b/contracts/src/v0.8/ccip/libraries/Pool.sol @@ -37,8 +37,7 @@ library Pool { struct ReleaseOrMintInV1 { bytes originalSender; // The original sender of the tx on the source chain uint64 remoteChainSelector; // ─╮ The chain ID of the source chain - address receiver; // ───────────╯ The recipient of the tokens on the destination chain. This is *NOT* the address to - // send the tokens to, but the address that will receive the tokens via the offRamp. + address receiver; // ───────────╯ The recipient of the tokens on the destination chain. uint256 amount; // The amount of tokens to release or mint, denominated in the source token's decimals address localToken; // The address on this chain of the token to release or mint /// @dev WARNING: sourcePoolAddress should be checked prior to any processing of funds. Make sure it matches the diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol index 969e971633..7807e3b4d8 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -48,6 +48,7 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { error CanOnlySelfCall(); error ReceiverError(bytes err); error TokenHandlingError(bytes err); + error ReleaseOrMintBalanceMismatch(uint256 amountReleased, uint256 balancePre, uint256 balancePost); error EmptyReport(); error CursedByRMN(uint64 sourceChainSelector); error NotACompatiblePool(address notPool); @@ -497,7 +498,7 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { /// @dev We use ERC-165 to check for the ccipReceive interface to permit sending tokens to contracts /// (for example smart contract wallets) without an associated message. function executeSingleMessage( - Internal.Any2EVMRampMessage calldata message, + Internal.Any2EVMRampMessage memory message, bytes[] calldata offchainTokenData ) external { if (msg.sender != address(this)) revert CanOnlySelfCall(); @@ -807,11 +808,11 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { /// @param offchainTokenData Data fetched offchain by the DON. /// @return destTokenAmount local token address with amount function _releaseOrMintSingleToken( - Internal.RampTokenAmount calldata sourceTokenAmount, - bytes calldata originalSender, + Internal.RampTokenAmount memory sourceTokenAmount, + bytes memory originalSender, address receiver, uint64 sourceChainSelector, - bytes calldata offchainTokenData + bytes memory offchainTokenData ) internal returns (Client.EVMTokenAmount memory destTokenAmount) { // We need to safely decode the token address from the sourceTokenData, as it could be wrong, // in which case it doesn't have to be a valid EVM address. @@ -826,12 +827,17 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { revert NotACompatiblePool(localPoolAddress); } + // We retrieve the local token balance of the receiver before the pool call. + (uint256 balancePre, uint256 gasLeft) = + _getBalanceOfReceiver(receiver, localToken, s_dynamicConfig.maxPoolReleaseOrMintGas); + // We determined that the pool address is a valid EVM address, but that does not mean the code at this // address is a (compatible) pool contract. _callWithExactGasSafeReturnData will check if the location // contains a contract. If it doesn't it reverts with a known error, which we catch gracefully. // We call the pool with exact gas to increase resistance against malicious tokens or token pools. // We protects against return data bombs by capping the return data size at MAX_RET_BYTES. - (bool success, bytes memory returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( + (bool success, bytes memory returnData, uint256 gasUsedReleaseOrMint) = CallWithExactGas + ._callWithExactGasSafeReturnData( abi.encodeCall( IPoolV1.releaseOrMint, Pool.ReleaseOrMintInV1({ @@ -846,7 +852,7 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { }) ), localPoolAddress, - s_dynamicConfig.maxPoolReleaseOrMintGas, + gasLeft, Internal.GAS_FOR_CALL_EXACT_CHECK, Internal.MAX_RET_BYTES ); @@ -858,21 +864,44 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { if (returnData.length != Pool.CCIP_POOL_V1_RET_BYTES) { revert InvalidDataLength(Pool.CCIP_POOL_V1_RET_BYTES, returnData.length); } + uint256 localAmount = abi.decode(returnData, (uint256)); - // Since token pools send the tokens to the msg.sender, which is this offRamp, we need to - // transfer them to the final receiver. We use the _callWithExactGasSafeReturnData function because - // the token contracts are not considered trusted. - (success, returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( - abi.encodeCall(IERC20.transferFrom, (localPoolAddress, receiver, localAmount)), - localToken, - s_dynamicConfig.maxTokenTransferGas, + // We don't need to do balance checks if the pool is the receiver, as they would always fail in the case + // of a lockRelease pool. + if (receiver != localPoolAddress) { + (uint256 balancePost,) = _getBalanceOfReceiver(receiver, localToken, gasLeft - gasUsedReleaseOrMint); + + // First we check if the subtraction would result in an underflow to ensure we revert with a clear error + if (balancePost < balancePre || balancePost - balancePre != localAmount) { + revert ReleaseOrMintBalanceMismatch(localAmount, balancePre, balancePost); + } + } + + return Client.EVMTokenAmount({token: localToken, amount: localAmount}); + } + + function _getBalanceOfReceiver( + address receiver, + address token, + uint256 gasLimit + ) internal returns (uint256 balance, uint256 gasLeft) { + (bool success, bytes memory returnData, uint256 gasUsed) = CallWithExactGas._callWithExactGasSafeReturnData( + abi.encodeCall(IERC20.balanceOf, (receiver)), + token, + gasLimit, Internal.GAS_FOR_CALL_EXACT_CHECK, Internal.MAX_RET_BYTES ); - if (!success) revert TokenHandlingError(returnData); - return Client.EVMTokenAmount({token: localToken, amount: localAmount}); + // If the call was successful, the returnData should contain only the balance. + if (returnData.length != Internal.MAX_BALANCE_OF_RET_BYTES) { + revert InvalidDataLength(Internal.MAX_BALANCE_OF_RET_BYTES, returnData.length); + } + + // Return the decoded balance, which cannot fail as we checked the length, and the gas that is left + // after this call. + return (abi.decode(returnData, (uint256)), gasLimit - gasUsed); } /// @notice Uses pools to release or mint a number of different tokens to a receiver address. @@ -886,8 +915,8 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { /// any non-rate limiting errors that may occur. If we encounter a rate limiting related error /// we bubble it up. If we encounter a non-rate limiting error we wrap it in a TokenHandlingError. function _releaseOrMintTokens( - Internal.RampTokenAmount[] calldata sourceTokenAmounts, - bytes calldata originalSender, + Internal.RampTokenAmount[] memory sourceTokenAmounts, + bytes memory originalSender, address receiver, uint64 sourceChainSelector, bytes[] calldata offchainTokenData diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol index 2d24682609..a7b559ef09 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol @@ -50,6 +50,7 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio error CanOnlySelfCall(); error ReceiverError(bytes err); error TokenHandlingError(bytes err); + error ReleaseOrMintBalanceMismatch(uint256 amountReleased, uint256 balancePre, uint256 balancePost); error EmptyReport(); error CursedByRMN(); error InvalidMessageId(); @@ -459,7 +460,7 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio /// its execution and enforce atomicity among successful message processing and token transfer. /// @dev We use ERC-165 to check for the ccipReceive interface to permit sending tokens to contracts /// (for example smart contract wallets) without an associated message. - function executeSingleMessage(Internal.EVM2EVMMessage memory message, bytes[] memory offchainTokenData) external { + function executeSingleMessage(Internal.EVM2EVMMessage calldata message, bytes[] calldata offchainTokenData) external { if (msg.sender != address(this)) revert CanOnlySelfCall(); Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](0); if (message.tokenAmounts.length > 0) { @@ -620,6 +621,9 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio revert NotACompatiblePool(localPoolAddress); } + // We retrieve the local token balance of the receiver before the pool call. + (uint256 balancePre, uint256 gasLeft) = _getBalanceOfReceiver(receiver, localToken, sourceTokenData.destGasAmount); + // We determined that the pool address is a valid EVM address, but that does not mean the code at this // address is a (compatible) pool contract. _callWithExactGasSafeReturnData will check if the location // contains a contract. If it doesn't it reverts with a known error, which we catch gracefully. @@ -641,33 +645,55 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio }) ), localPoolAddress, - sourceTokenData.destGasAmount, + gasLeft, Internal.GAS_FOR_CALL_EXACT_CHECK, Internal.MAX_RET_BYTES ); // wrap and rethrow the error so we can catch it lower in the stack if (!success) revert TokenHandlingError(returnData); - // If the call was successful, the returnData should contain only the local token amount. if (returnData.length != Pool.CCIP_POOL_V1_RET_BYTES) { revert InvalidDataLength(Pool.CCIP_POOL_V1_RET_BYTES, returnData.length); } + uint256 localAmount = abi.decode(returnData, (uint256)); - // Since token pools send the tokens to the msg.sender, which is this offRamp, we need to - // transfer them to the final receiver. We use the _callWithExactGasSafeReturnData function because - // the token contracts are not considered trusted. - (success, returnData,) = CallWithExactGas._callWithExactGasSafeReturnData( - abi.encodeCall(IERC20.transferFrom, (localPoolAddress, receiver, localAmount)), - localToken, - sourceTokenData.destGasAmount - gasUsedReleaseOrMint, + // We don't need to do balance checks if the pool is the receiver, as they would always fail in the case + // of a lockRelease pool. + if (receiver != localPoolAddress) { + (uint256 balancePost,) = _getBalanceOfReceiver(receiver, localToken, gasLeft - gasUsedReleaseOrMint); + + // First we check if the subtraction would result in an underflow to ensure we revert with a clear error + if (balancePost < balancePre || balancePost - balancePre != localAmount) { + revert ReleaseOrMintBalanceMismatch(localAmount, balancePre, balancePost); + } + } + + return Client.EVMTokenAmount({token: localToken, amount: localAmount}); + } + + function _getBalanceOfReceiver( + address receiver, + address token, + uint256 gasLimit + ) internal returns (uint256 balance, uint256 gasLeft) { + (bool success, bytes memory returnData, uint256 gasUsed) = CallWithExactGas._callWithExactGasSafeReturnData( + abi.encodeCall(IERC20.balanceOf, (receiver)), + token, + gasLimit, Internal.GAS_FOR_CALL_EXACT_CHECK, Internal.MAX_RET_BYTES ); - if (!success) revert TokenHandlingError(returnData); - return Client.EVMTokenAmount({token: localToken, amount: localAmount}); + // If the call was successful, the returnData should contain only the balance. + if (returnData.length != Internal.MAX_BALANCE_OF_RET_BYTES) { + revert InvalidDataLength(Internal.MAX_BALANCE_OF_RET_BYTES, returnData.length); + } + + // Return the decoded balance, which cannot fail as we checked the length, and the gas that is left + // after this call. + return (abi.decode(returnData, (uint256)), gasLimit - gasUsed); } /// @notice Uses pools to release or mint a number of different tokens to a receiver address. @@ -680,11 +706,11 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio /// any non-rate limiting errors that may occur. If we encounter a rate limiting related error /// we bubble it up. If we encounter a non-rate limiting error we wrap it in a TokenHandlingError. function _releaseOrMintTokens( - Client.EVMTokenAmount[] memory sourceTokenAmounts, + Client.EVMTokenAmount[] calldata sourceTokenAmounts, bytes memory originalSender, address receiver, - bytes[] memory encodedSourceTokenData, - bytes[] memory offchainTokenData + bytes[] calldata encodedSourceTokenData, + bytes[] calldata offchainTokenData ) internal returns (Client.EVMTokenAmount[] memory destTokenAmounts) { // Creating a copy is more gas efficient than initializing a new array. destTokenAmounts = sourceTokenAmounts; diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol index 1968b3c03d..a31d4fd219 100644 --- a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol @@ -39,9 +39,8 @@ abstract contract BurnMintTokenPoolAbstract is TokenPool { { _validateReleaseOrMint(releaseOrMintIn); - // Mint to the offRamp, which forwards it to the recipient - IBurnMintERC20(address(i_token)).mint(address(this), releaseOrMintIn.amount); - IBurnMintERC20(address(i_token)).approve(msg.sender, releaseOrMintIn.amount); + // Mint to the receiver + IBurnMintERC20(address(i_token)).mint(releaseOrMintIn.receiver, releaseOrMintIn.amount); emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol index a3a7e082cc..07cb01dc76 100644 --- a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol @@ -49,8 +49,7 @@ contract BurnMintTokenPoolAndProxy is ITypeAndVersion, LegacyPoolWrapper { _validateReleaseOrMint(releaseOrMintIn); if (!_hasLegacyPool()) { - // Mint to the offRamp, which forwards it to the recipient - IBurnMintERC20(address(i_token)).mint(msg.sender, releaseOrMintIn.amount); + IBurnMintERC20(address(i_token)).mint(releaseOrMintIn.receiver, releaseOrMintIn.amount); } else { _releaseOrMintLegacy(releaseOrMintIn); } diff --git a/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol b/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol index 969f0ac1f7..58eac2a57d 100644 --- a/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol +++ b/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol @@ -75,8 +75,11 @@ abstract contract LegacyPoolWrapper is TokenPool { /// @dev Since extraData has never been used in LockRelease or MintBurn token pools, we can safely ignore it. function _releaseOrMintLegacy(Pool.ReleaseOrMintInV1 memory releaseOrMintIn) internal { s_previousPool.releaseOrMint( - releaseOrMintIn.originalSender, address(this), releaseOrMintIn.amount, releaseOrMintIn.remoteChainSelector, "" + releaseOrMintIn.originalSender, + releaseOrMintIn.receiver, + releaseOrMintIn.amount, + releaseOrMintIn.remoteChainSelector, + "" ); - i_token.approve(msg.sender, releaseOrMintIn.amount); } } diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol index be3a599a97..a01173b869 100644 --- a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol @@ -67,8 +67,8 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion { _validateReleaseOrMint(releaseOrMintIn); - // Release to the offRamp, which forwards it to the recipient - getToken().approve(msg.sender, releaseOrMintIn.amount); + // Release to the recipient + getToken().safeTransfer(releaseOrMintIn.receiver, releaseOrMintIn.amount); emit Released(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol index dcd78ee969..45aab70a98 100644 --- a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol @@ -70,8 +70,8 @@ contract LockReleaseTokenPoolAndProxy is LegacyPoolWrapper, ILiquidityContainer, _validateReleaseOrMint(releaseOrMintIn); if (!_hasLegacyPool()) { - // Release to the offRamp, which forwards it to the recipient - getToken().safeTransfer(msg.sender, releaseOrMintIn.amount); + // Release to the recipient + getToken().safeTransfer(releaseOrMintIn.receiver, releaseOrMintIn.amount); } else { _releaseOrMintLegacy(releaseOrMintIn); } diff --git a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol index d46fcbacd6..833411e49d 100644 --- a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol @@ -107,17 +107,16 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { Domain memory domain = s_chainToDomain[lockOrBurnIn.remoteChainSelector]; if (!domain.enabled) revert UnknownDomain(lockOrBurnIn.remoteChainSelector); + if (lockOrBurnIn.receiver.length != 32) { + revert InvalidReceiver(lockOrBurnIn.receiver); + } + bytes32 decodedReceiver = abi.decode(lockOrBurnIn.receiver, (bytes32)); + // Since this pool is the msg sender of the CCTP transaction, only this contract // is able to call replaceDepositForBurn. Since this contract does not implement // replaceDepositForBurn, the tokens cannot be maliciously re-routed to another address. uint64 nonce = i_tokenMessenger.depositForBurnWithCaller( - // We set the domain.allowedCaller as the receiver of the funds, as this is the token pool. Since 1.5 the - // token pools receiver the funds to hop them through the offRamps. - lockOrBurnIn.amount, - domain.domainIdentifier, - domain.allowedCaller, - address(i_token), - domain.allowedCaller + lockOrBurnIn.amount, domain.domainIdentifier, decodedReceiver, address(i_token), domain.allowedCaller ); emit Burned(msg.sender, lockOrBurnIn.amount); @@ -156,8 +155,6 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { if (!i_messageTransmitter.receiveMessage(msgAndAttestation.message, msgAndAttestation.attestation)) { revert UnlockingUSDCFailed(); } - // Since the tokens are minted to the pool, the pool has to approve it for the offRamp - getToken().approve(msg.sender, releaseOrMintIn.amount); emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); diff --git a/contracts/src/v0.8/ccip/test/BaseTest.t.sol b/contracts/src/v0.8/ccip/test/BaseTest.t.sol index 887ffbf616..dba9e286ef 100644 --- a/contracts/src/v0.8/ccip/test/BaseTest.t.sol +++ b/contracts/src/v0.8/ccip/test/BaseTest.t.sol @@ -38,7 +38,7 @@ contract BaseTest is Test { uint16 internal constant DEST_GAS_PER_PAYLOAD_BYTE = 16; uint16 internal constant DEFAULT_TOKEN_FEE_USD_CENTS = 50; - uint32 internal constant DEFAULT_TOKEN_DEST_GAS_OVERHEAD = 144_000; + uint32 internal constant DEFAULT_TOKEN_DEST_GAS_OVERHEAD = 85_000; uint32 internal constant DEFAULT_TOKEN_BYTES_OVERHEAD = 32; bool private s_baseTestInitialized; diff --git a/contracts/src/v0.8/ccip/test/arm/RMN.t.sol b/contracts/src/v0.8/ccip/test/arm/RMN.t.sol index d3237592f2..85501170e3 100644 --- a/contracts/src/v0.8/ccip/test/arm/RMN.t.sol +++ b/contracts/src/v0.8/ccip/test/arm/RMN.t.sol @@ -1058,7 +1058,7 @@ contract RMN_permaBlessing is RMNSetup { } contract RMN_getRecordedCurseRelatedOps is RMNSetup { - function test_OpsPostDeployment() public { + function test_OpsPostDeployment() public view { // The constructor call includes a setConfig, so that's the only thing we should expect to find. assertEq(s_rmn.getRecordedCurseRelatedOpsCount(), 1); RMN.RecordedCurseRelatedOp[] memory recordedCurseRelatedOps = s_rmn.getRecordedCurseRelatedOps(0, type(uint256).max); diff --git a/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol b/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol index 2bb29cd38d..fe2bf75854 100644 --- a/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol +++ b/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol @@ -102,7 +102,7 @@ contract CCIPConfigSetup is Test { return (p2pIds, signers, transmitters); } - function test_getCapabilityConfiguration_Success() public { + function test_getCapabilityConfiguration_Success() public view { bytes memory capConfig = s_ccipCC.getCapabilityConfiguration(42 /* doesn't matter, not used */ ); assertEq(capConfig.length, 0, "capability config length must be 0"); } @@ -703,7 +703,7 @@ contract CCIPConfig_validateConfig is CCIPConfigSetup { contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { // Successful cases. - function test__stateFromConfigLength_Success() public { + function test__stateFromConfigLength_Success() public view { uint256 configLen = 0; CCIPConfigTypes.ConfigState state = s_ccipCC.stateFromConfigLength(configLen); assertEq(uint256(state), uint256(CCIPConfigTypes.ConfigState.Init)); @@ -717,7 +717,7 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { assertEq(uint256(state), uint256(CCIPConfigTypes.ConfigState.Staging)); } - function test__validateConfigStateTransition_Success() public { + function test__validateConfigStateTransition_Success() public view { s_ccipCC.validateConfigStateTransition(CCIPConfigTypes.ConfigState.Init, CCIPConfigTypes.ConfigState.Running); s_ccipCC.validateConfigStateTransition(CCIPConfigTypes.ConfigState.Running, CCIPConfigTypes.ConfigState.Staging); @@ -725,7 +725,7 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { s_ccipCC.validateConfigStateTransition(CCIPConfigTypes.ConfigState.Staging, CCIPConfigTypes.ConfigState.Running); } - function test__computeConfigDigest_Success() public { + function test__computeConfigDigest_Success() public view { // config digest must change upon: // - ocr config change (e.g plugin type, chain selector, etc.) // - don id change @@ -769,7 +769,7 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { assertNotEq(configDigest2, configDigest4, "config digests 2 and 4 must not match"); } - function test_Fuzz__groupByPluginType_Success(uint256 numCommitCfgs, uint256 numExecCfgs) public { + function test_Fuzz__groupByPluginType_Success(uint256 numCommitCfgs, uint256 numExecCfgs) public view { numCommitCfgs = bound(numCommitCfgs, 0, 2); numExecCfgs = bound(numExecCfgs, 0, 2); @@ -1412,7 +1412,6 @@ contract CCIPConfig_updatePluginConfig is CCIPConfigSetup { (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); // add blue config. uint32 donId = 1; - Internal.OCRPluginType pluginType = Internal.OCRPluginType.Commit; CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), @@ -1468,7 +1467,6 @@ contract CCIPConfig_updatePluginConfig is CCIPConfigSetup { (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); // add blue config. uint32 donId = 1; - Internal.OCRPluginType pluginType = Internal.OCRPluginType.Commit; CCIPConfigTypes.OCR3Config memory blueConfig = CCIPConfigTypes.OCR3Config({ pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), diff --git a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol index 52436503d2..68c6f9d5ff 100644 --- a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol +++ b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol @@ -103,7 +103,7 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { _setupMultipleOffRampsFromConfigs(sourceChainConfigs); } - function test_E2E_3MessagesSuccess_gas() public { + function test_E2E_3MessagesMMultiOffRampSuccess_gas() public { vm.pauseGasMetering(); IERC20 token0 = IERC20(s_sourceTokens[0]); IERC20 token1 = IERC20(s_sourceTokens[1]); diff --git a/contracts/src/v0.8/ccip/test/helpers/BurnMintMultiTokenPool.sol b/contracts/src/v0.8/ccip/test/helpers/BurnMintMultiTokenPool.sol index a21fcde835..ec6f1d2047 100644 --- a/contracts/src/v0.8/ccip/test/helpers/BurnMintMultiTokenPool.sol +++ b/contracts/src/v0.8/ccip/test/helpers/BurnMintMultiTokenPool.sol @@ -46,7 +46,7 @@ contract BurnMintMultiTokenPool is MultiTokenPool { { _validateReleaseOrMint(releaseOrMintIn); - // Mint to the offRamp, which forwards it to the recipient + // Mint to the receiver IBurnMintERC20(releaseOrMintIn.localToken).mint(msg.sender, releaseOrMintIn.amount); emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); diff --git a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOffRampHelper.sol b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOffRampHelper.sol index e328f0ade2..f6131b64a5 100644 --- a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOffRampHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOffRampHelper.sol @@ -29,7 +29,7 @@ contract EVM2EVMOffRampHelper is EVM2EVMOffRamp, IgnoreContractSize { } function releaseOrMintTokens( - Client.EVMTokenAmount[] memory sourceTokenAmounts, + Client.EVMTokenAmount[] calldata sourceTokenAmounts, bytes calldata originalSender, address receiver, bytes[] calldata sourceTokenData, diff --git a/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol b/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol index a30c4779dd..b203315bc6 100644 --- a/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol +++ b/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol @@ -9,6 +9,7 @@ import {BurnMintTokenPool} from "../../pools/BurnMintTokenPool.sol"; contract MaybeRevertingBurnMintTokenPool is BurnMintTokenPool { bytes public s_revertReason = ""; bytes public s_sourceTokenData = ""; + uint256 public s_releaseOrMintMultiplier = 1; constructor( IBurnMintERC20 token, @@ -25,6 +26,10 @@ contract MaybeRevertingBurnMintTokenPool is BurnMintTokenPool { s_sourceTokenData = sourceTokenData; } + function setReleaseOrMintMultiplier(uint256 multiplier) external { + s_releaseOrMintMultiplier = multiplier; + } + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) external virtual @@ -63,10 +68,10 @@ contract MaybeRevertingBurnMintTokenPool is BurnMintTokenPool { revert(add(32, revertReason), mload(revertReason)) } } - IBurnMintERC20(address(i_token)).mint(address(this), releaseOrMintIn.amount); - IBurnMintERC20(address(i_token)).approve(msg.sender, releaseOrMintIn.amount); + uint256 amount = releaseOrMintIn.amount * s_releaseOrMintMultiplier; + IBurnMintERC20(address(i_token)).mint(releaseOrMintIn.receiver, amount); - emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); - return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + emit Minted(msg.sender, releaseOrMintIn.receiver, amount); + return Pool.ReleaseOrMintOutV1({destinationAmount: amount}); } } diff --git a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol index a7e6083825..8abb758497 100644 --- a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol +++ b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol @@ -478,10 +478,7 @@ contract TokenPoolAndProxy is EVM2EVMOnRampSetup { vm.startPrank(address(s_fakeOffRamp)); vm.expectEmit(address(s_legacyPool)); - emit Minted(address(s_pool), address(s_pool), amount); - - vm.expectEmit(address(s_token)); - emit IERC20.Approval(address(s_pool), address(s_fakeOffRamp), amount); + emit Minted(address(s_pool), address(OWNER), amount); s_pool.releaseOrMint( Pool.ReleaseOrMintInV1({ diff --git a/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTokenMessenger.sol b/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTokenMessenger.sol index 9fa5cd1a66..1b6c9c750d 100644 --- a/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTokenMessenger.sol +++ b/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTokenMessenger.sol @@ -50,8 +50,13 @@ contract MockE2EUSDCTokenMessenger is ITokenMessenger { IBurnMintERC20(burnToken).transferFrom(msg.sender, address(this), amount); IBurnMintERC20(burnToken).burn(amount); // Format message body - bytes memory _burnMessage = - abi.encodePacked(i_messageBodyVersion, burnToken, mintRecipient, amount, bytes32(uint256(uint160((msg.sender))))); + bytes memory _burnMessage = _formatMessage( + i_messageBodyVersion, + bytes32(uint256(uint160(burnToken))), + mintRecipient, + amount, + bytes32(uint256(uint160(msg.sender))) + ); s_nonce = _sendDepositForBurnMessage(destinationDomain, DESTINATION_TOKEN_MESSENGER, destinationCaller, _burnMessage); emit DepositForBurn( @@ -100,4 +105,23 @@ contract MockE2EUSDCTokenMessenger is ITokenMessenger { ); } } + + /** + * @notice Formats Burn message + * @param _version The message body version + * @param _burnToken The burn token address on source domain as bytes32 + * @param _mintRecipient The mint recipient address as bytes32 + * @param _amount The burn amount + * @param _messageSender The message sender + * @return Burn formatted message. + */ + function _formatMessage( + uint32 _version, + bytes32 _burnToken, + bytes32 _mintRecipient, + uint256 _amount, + bytes32 _messageSender + ) internal pure returns (bytes memory) { + return abi.encodePacked(_version, _burnToken, _mintRecipient, _amount, _messageSender); + } } diff --git a/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTransmitter.sol b/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTransmitter.sol index 8e50bedea9..bbd9c7dcc6 100644 --- a/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTransmitter.sol +++ b/contracts/src/v0.8/ccip/test/mocks/MockE2EUSDCTransmitter.sol @@ -55,10 +55,19 @@ contract MockE2EUSDCTransmitter is IMessageTransmitterWithRelay { /// * destinationCaller 32 bytes32 84 /// * messageBody dynamic bytes 116 function receiveMessage(bytes calldata message, bytes calldata) external returns (bool success) { - address recipient = address(bytes20(message[64:84])); - - // We always mint 1000e18 tokens to not complicate the test. - i_token.mint(recipient, 1000e18); + // The receiver of the funds is the _mintRecipient in the following encoded format + // function _formatMessage( + // uint32 _version, 4 + // bytes32 _burnToken, 32 + // bytes32 _mintRecipient, 32, first 12 empty for EVM addresses + // uint256 _amount, + // bytes32 _messageSender + // ) internal pure returns (bytes memory) { + // return abi.encodePacked(_version, _burnToken, _mintRecipient, _amount, _messageSender); + // } + address recipient = address(bytes20(message[116 + 36 + 12:116 + 36 + 12 + 20])); + // We always mint 1 token to not complicate the test. + i_token.mint(recipient, 1); return s_shouldSucceed; } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol index 603705e00a..0cd46c1e5f 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol @@ -23,7 +23,6 @@ import {EVM2EVMMultiOffRamp} from "../../offRamp/EVM2EVMMultiOffRamp.sol"; import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; import {EVM2EVMMultiOffRampHelper} from "../helpers/EVM2EVMMultiOffRampHelper.sol"; -import {EVM2EVMOffRampHelper} from "../helpers/EVM2EVMOffRampHelper.sol"; import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; import {ConformingReceiver} from "../helpers/receivers/ConformingReceiver.sol"; @@ -2337,6 +2336,103 @@ contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSet assertEq(startingBalance + amount, dstToken1.balanceOf(OWNER)); } + function test_releaseOrMintToken_InvalidDataLength_Revert() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + + Internal.RampTokenAmount memory tokenAmount = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), + extraData: "", + amount: amount + }); + + // Mock the call so returns 2 slots of data + vm.mockCall( + s_destTokenBySourceToken[token], abi.encodeWithSelector(IERC20.balanceOf.selector, OWNER), abi.encode(0, 0) + ); + + vm.expectRevert( + abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidDataLength.selector, Internal.MAX_BALANCE_OF_RET_BYTES, 64) + ); + + s_offRamp.releaseOrMintSingleToken(tokenAmount, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR, ""); + } + + function test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + + Internal.RampTokenAmount memory tokenAmount = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), + extraData: "", + amount: amount + }); + + bytes memory revertData = "failed to balanceOf"; + + // Mock the call so returns 2 slots of data + vm.mockCallRevert( + s_destTokenBySourceToken[token], abi.encodeWithSelector(IERC20.balanceOf.selector, OWNER), revertData + ); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, revertData)); + + s_offRamp.releaseOrMintSingleToken(tokenAmount, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR, ""); + } + + function test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + uint256 mockedStaticBalance = 50000; + + Internal.RampTokenAmount memory tokenAmount = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), + extraData: "", + amount: amount + }); + + vm.mockCall( + s_destTokenBySourceToken[token], + abi.encodeWithSelector(IERC20.balanceOf.selector, OWNER), + abi.encode(mockedStaticBalance) + ); + + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMMultiOffRamp.ReleaseOrMintBalanceMismatch.selector, amount, mockedStaticBalance, mockedStaticBalance + ) + ); + + s_offRamp.releaseOrMintSingleToken(tokenAmount, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR, ""); + } + + function test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + uint256 mockedStaticBalance = 50000; + + Internal.RampTokenAmount memory tokenAmount = Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), + extraData: "", + amount: amount + }); + + // This should make the call fail if it does not skip the check + vm.mockCall( + s_destTokenBySourceToken[token], + abi.encodeWithSelector(IERC20.balanceOf.selector, OWNER), + abi.encode(mockedStaticBalance) + ); + + s_offRamp.releaseOrMintSingleToken( + tokenAmount, abi.encode(OWNER), s_destPoolBySourceToken[token], SOURCE_CHAIN_SELECTOR, "" + ); + } + function test__releaseOrMintSingleToken_NotACompatiblePool_Revert() public { uint256 amount = 123123; address token = s_sourceTokens[0]; @@ -2379,7 +2475,7 @@ contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSet s_offRamp.releaseOrMintSingleToken(tokenAmount, originalSender, OWNER, SOURCE_CHAIN_SELECTOR_1, offchainTokenData); } - function test__releaseOrMintSingleToken_TokenHandlingError_revert_Revert() public { + function test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() public { address receiver = makeAddr("receiver"); uint256 amount = 123123; address token = s_sourceTokens[0]; @@ -2396,7 +2492,7 @@ contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSet bytes memory revertData = "call reverted :o"; - vm.mockCallRevert(destToken, abi.encodeWithSelector(IERC20.approve.selector, s_offRamp, amount), revertData); + vm.mockCallRevert(destToken, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount), revertData); vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, revertData)); s_offRamp.releaseOrMintSingleToken( @@ -2451,44 +2547,22 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); uint256 amount = 100; uint256 destinationDenominationMultiplier = 1000; - srcTokenAmounts[0].amount = amount; + srcTokenAmounts[1].amount = amount; bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); Internal.RampTokenAmount[] memory sourceTokenAmounts = _getDefaultSourceTokenData(srcTokenAmounts); - address pool = s_destPoolBySourceToken[srcTokenAmounts[0].token]; - address destToken = s_destTokenBySourceToken[srcTokenAmounts[0].token]; - - // Since the pool call is mocked, we manually approve funds to the offRamp - deal(destToken, pool, amount * destinationDenominationMultiplier); - vm.startPrank(pool); - IERC20(destToken).approve(address(s_offRamp), amount * destinationDenominationMultiplier); - vm.startPrank(OWNER); - - Pool.ReleaseOrMintInV1 memory releaseOrMintIn = Pool.ReleaseOrMintInV1({ - originalSender: abi.encode(OWNER), - receiver: OWNER, - amount: amount, - localToken: destToken, - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - sourcePoolAddress: sourceTokenAmounts[0].sourcePoolAddress, - sourcePoolData: sourceTokenAmounts[0].extraData, - offchainTokenData: offchainTokenData[0] - }); + address pool = s_destPoolBySourceToken[srcTokenAmounts[1].token]; + address destToken = s_destTokenBySourceToken[srcTokenAmounts[1].token]; - vm.mockCall( - s_destPoolBySourceToken[srcTokenAmounts[0].token], - abi.encodeWithSelector(LockReleaseTokenPool.releaseOrMint.selector, releaseOrMintIn), - abi.encode(amount * destinationDenominationMultiplier) - ); + MaybeRevertingBurnMintTokenPool(pool).setReleaseOrMintMultiplier(destinationDenominationMultiplier); Client.EVMTokenAmount[] memory destTokenAmounts = s_offRamp.releaseOrMintTokens( sourceTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, offchainTokenData ); - - assertEq(destTokenAmounts[0].amount, amount * destinationDenominationMultiplier); - assertEq(destTokenAmounts[0].token, destToken); + assertEq(destTokenAmounts[1].amount, amount * destinationDenominationMultiplier); + assertEq(destTokenAmounts[1].token, destToken); } // Revert diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol index 16358f75ba..b42782718b 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol @@ -240,12 +240,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { IERC20 dstToken0 = IERC20(s_destTokens[0]); uint256 startingBalance = dstToken0.balanceOf(message.receiver); - vm.expectCall( - address(dstToken0), - abi.encodeWithSelector( - IERC20.transferFrom.selector, s_destPoolByToken[address(dstToken0)], address(s_receiver), amounts[0] - ) - ); + vm.expectCall(address(dstToken0), abi.encodeWithSelector(IERC20.transfer.selector, address(s_receiver), amounts[0])); (Internal.MessageExecutionState newState, bytes memory err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); @@ -1459,7 +1454,7 @@ contract EVM2EVMOffRamp__releaseOrMintToken is EVM2EVMOffRampSetup { uint256 amount = 123123; address token = s_sourceTokens[0]; bytes memory originalSender = abi.encode(OWNER); - bytes memory offchainTokenData = abi.encode(keccak256("offchainTokenData")); + bytes memory offchainTokenData = ""; IERC20 dstToken1 = IERC20(s_destTokenBySourceToken[token]); uint256 startingBalance = dstToken1.balanceOf(OWNER); @@ -1493,13 +1488,107 @@ contract EVM2EVMOffRamp__releaseOrMintToken is EVM2EVMOffRampSetup { assertEq(startingBalance + amount, dstToken1.balanceOf(OWNER)); } + function test_releaseOrMintToken_InvalidDataLength_Revert() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD + }); + + // Mock the call so returns 2 slots of data + vm.mockCall( + s_destTokenBySourceToken[token], abi.encodeWithSelector(IERC20.balanceOf.selector, OWNER), abi.encode(0, 0) + ); + + vm.expectRevert( + abi.encodeWithSelector(EVM2EVMOffRamp.InvalidDataLength.selector, Internal.MAX_BALANCE_OF_RET_BYTES, 64) + ); + + s_offRamp.releaseOrMintToken(amount, abi.encode(OWNER), OWNER, sourceTokenData, ""); + } + + function test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD + }); + + bytes memory revertData = "failed to balanceOf"; + + // Mock the call so returns 2 slots of data + vm.mockCallRevert( + s_destTokenBySourceToken[token], abi.encodeWithSelector(IERC20.balanceOf.selector, OWNER), revertData + ); + + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, revertData)); + + s_offRamp.releaseOrMintToken(amount, abi.encode(OWNER), OWNER, sourceTokenData, ""); + } + + function test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + uint256 mockedStaticBalance = 50000; + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD + }); + + vm.mockCall( + s_destTokenBySourceToken[token], + abi.encodeWithSelector(IERC20.balanceOf.selector, OWNER), + abi.encode(mockedStaticBalance) + ); + + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMOffRamp.ReleaseOrMintBalanceMismatch.selector, amount, mockedStaticBalance, mockedStaticBalance + ) + ); + + s_offRamp.releaseOrMintToken(amount, abi.encode(OWNER), OWNER, sourceTokenData, ""); + } + + function test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() public { + uint256 amount = 123123; + address token = s_sourceTokens[0]; + uint256 mockedStaticBalance = 50000; + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), + destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), + extraData: "", + destGasAmount: DEFAULT_TOKEN_DEST_GAS_OVERHEAD + }); + + // This should make the call fail if it does not skip the check + vm.mockCall( + s_destTokenBySourceToken[token], + abi.encodeWithSelector(IERC20.balanceOf.selector, OWNER), + abi.encode(mockedStaticBalance) + ); + + s_offRamp.releaseOrMintToken(amount, abi.encode(OWNER), s_destPoolBySourceToken[token], sourceTokenData, ""); + } + function test__releaseOrMintToken_NotACompatiblePool_Revert() public { uint256 amount = 123123; address token = s_sourceTokens[0]; address destToken = s_destTokenBySourceToken[token]; vm.label(destToken, "destToken"); bytes memory originalSender = abi.encode(OWNER); - bytes memory offchainTokenData = abi.encode(keccak256("offchainTokenData")); Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), @@ -1519,7 +1608,7 @@ contract EVM2EVMOffRamp__releaseOrMintToken is EVM2EVMOffRampSetup { vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.NotACompatiblePool.selector, returnedPool)); - s_offRamp.releaseOrMintToken(amount, originalSender, OWNER, sourceTokenData, offchainTokenData); + s_offRamp.releaseOrMintToken(amount, originalSender, OWNER, sourceTokenData, ""); // A contract that doesn't support the interface should also revert returnedPool = address(s_offRamp); @@ -1532,10 +1621,10 @@ contract EVM2EVMOffRamp__releaseOrMintToken is EVM2EVMOffRampSetup { vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.NotACompatiblePool.selector, returnedPool)); - s_offRamp.releaseOrMintToken(amount, originalSender, OWNER, sourceTokenData, offchainTokenData); + s_offRamp.releaseOrMintToken(amount, originalSender, OWNER, sourceTokenData, ""); } - function test__releaseOrMintToken_TokenHandlingError_revert_Revert() public { + function test__releaseOrMintToken_TokenHandlingError_transfer_Revert() public { address receiver = makeAddr("receiver"); uint256 amount = 123123; address token = s_sourceTokens[0]; @@ -1552,7 +1641,7 @@ contract EVM2EVMOffRamp__releaseOrMintToken is EVM2EVMOffRampSetup { bytes memory revertData = "call reverted :o"; - vm.mockCallRevert(destToken, abi.encodeWithSelector(IERC20.approve.selector, s_offRamp, amount), revertData); + vm.mockCallRevert(destToken, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount), revertData); vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, revertData)); s_offRamp.releaseOrMintToken(amount, originalSender, receiver, sourceTokenData, offchainTokenData); @@ -1601,44 +1690,21 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); uint256 amount = 100; uint256 destinationDenominationMultiplier = 1000; - srcTokenAmounts[0].amount = amount; + srcTokenAmounts[1].amount = amount; bytes memory originalSender = abi.encode(OWNER); bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); bytes[] memory encodedSourceTokenData = _getDefaultSourceTokenData(srcTokenAmounts); - Internal.SourceTokenData memory sourceTokenData = abi.decode(encodedSourceTokenData[0], (Internal.SourceTokenData)); - - address pool = s_destPoolBySourceToken[srcTokenAmounts[0].token]; - address destToken = s_destTokenBySourceToken[srcTokenAmounts[0].token]; - - // Since the pool call is mocked, we manually approve funds to the offRamp - deal(destToken, pool, amount * destinationDenominationMultiplier); - vm.startPrank(pool); - IERC20(destToken).approve(address(s_offRamp), amount * destinationDenominationMultiplier); - vm.startPrank(OWNER); - - Pool.ReleaseOrMintInV1 memory releaseOrMintIn = Pool.ReleaseOrMintInV1({ - originalSender: originalSender, - receiver: OWNER, - amount: amount, - localToken: destToken, - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - sourcePoolAddress: sourceTokenData.sourcePoolAddress, - sourcePoolData: sourceTokenData.extraData, - offchainTokenData: offchainTokenData[0] - }); + address pool = s_destPoolBySourceToken[srcTokenAmounts[1].token]; + address destToken = s_destTokenBySourceToken[srcTokenAmounts[1].token]; - vm.mockCall( - pool, - abi.encodeWithSelector(LockReleaseTokenPool.releaseOrMint.selector, releaseOrMintIn), - abi.encode(amount * destinationDenominationMultiplier) - ); + MaybeRevertingBurnMintTokenPool(pool).setReleaseOrMintMultiplier(destinationDenominationMultiplier); Client.EVMTokenAmount[] memory destTokenAmounts = s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, encodedSourceTokenData, offchainTokenData); - assertEq(destTokenAmounts[0].amount, amount * destinationDenominationMultiplier); - assertEq(destTokenAmounts[0].token, destToken); + assertEq(destTokenAmounts[1].amount, amount * destinationDenominationMultiplier); + assertEq(destTokenAmounts[1].token, destToken); } function test_OverValueWithARLOff_Success() public { diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol index d2864a762c..46a695701f 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol @@ -65,7 +65,7 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { minFeeUSDCents: 1_00, // 1 USD maxFeeUSDCents: 1000_00, // 1,000 USD deciBps: 2_5, // 2.5 bps, or 0.025% - destGasOverhead: 140_000, + destGasOverhead: 84_000, destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES), aggregateRateLimitEnabled: true }) @@ -76,7 +76,7 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { minFeeUSDCents: 2_00, // 1 USD maxFeeUSDCents: 500_00, // 500 USD deciBps: 10_0, // 10 bps, or 0.1% - destGasOverhead: 130_000, + destGasOverhead: 83_000, destBytesOverhead: 200, aggregateRateLimitEnabled: true }) diff --git a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol index 71b7819fbf..a6c4a60dc5 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol @@ -107,15 +107,17 @@ contract BurnMintTokenPool_lockOrBurn is BurnMintTokenPoolSetup { contract BurnMintTokenPool_releaseOrMint is BurnMintTokenPoolSetup { function test_PoolMint_Success() public { uint256 amount = 1e19; + address receiver = makeAddr("receiver_address"); vm.startPrank(s_burnMintOffRamp); vm.expectEmit(); - emit IERC20.Approval(address(s_pool), address(s_burnMintOffRamp), amount); + emit IERC20.Transfer(address(0), receiver, amount); + s_pool.releaseOrMint( Pool.ReleaseOrMintInV1({ originalSender: bytes(""), - receiver: OWNER, + receiver: receiver, amount: amount, localToken: address(s_burnMintERC677), remoteChainSelector: DEST_CHAIN_SELECTOR, @@ -125,7 +127,7 @@ contract BurnMintTokenPool_releaseOrMint is BurnMintTokenPoolSetup { }) ); - assertEq(s_burnMintERC677.allowance(address(s_pool), s_burnMintOffRamp), amount); + assertEq(s_burnMintERC677.balanceOf(receiver), amount); } function test_PoolMintNotHealthy_Revert() public { diff --git a/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol index 564407df5a..2ced91fac3 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol @@ -151,7 +151,7 @@ contract USDCTokenPool_lockOrBurn is USDCTokenPoolSetup { address(s_token), amount, address(s_usdcTokenPool), - expectedDomain.allowedCaller, + receiver, expectedDomain.domainIdentifier, s_mockUSDC.DESTINATION_TOKEN_MESSENGER(), expectedDomain.allowedCaller @@ -191,7 +191,7 @@ contract USDCTokenPool_lockOrBurn is USDCTokenPoolSetup { address(s_token), amount, address(s_usdcTokenPool), - expectedDomain.allowedCaller, + destinationReceiver, expectedDomain.domainIdentifier, s_mockUSDC.DESTINATION_TOKEN_MESSENGER(), expectedDomain.allowedCaller @@ -231,7 +231,7 @@ contract USDCTokenPool_lockOrBurn is USDCTokenPoolSetup { address(s_token), amount, address(s_usdcTokenPoolWithAllowList), - expectedDomain.allowedCaller, + destinationReceiver, expectedDomain.domainIdentifier, s_mockUSDC.DESTINATION_TOKEN_MESSENGER(), expectedDomain.allowedCaller @@ -323,6 +323,17 @@ contract USDCTokenPool_lockOrBurn is USDCTokenPoolSetup { } contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { + // From https://github.com/circlefin/evm-cctp-contracts/blob/377c9bd813fb86a42d900ae4003599d82aef635a/src/messages/BurnMessage.sol#L57 + function _formatMessage( + uint32 _version, + bytes32 _burnToken, + bytes32 _mintRecipient, + uint256 _amount, + bytes32 _messageSender + ) internal pure returns (bytes memory) { + return abi.encodePacked(_version, _burnToken, _mintRecipient, _amount, _messageSender); + } + function test_Fuzz_ReleaseOrMint_Success(address recipient, uint256 amount) public { vm.assume(recipient != address(0) && recipient != address(s_token)); amount = bound(amount, 0, getInboundRateLimiterConfig().capacity); @@ -335,7 +346,13 @@ contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { sender: SOURCE_CHAIN_TOKEN_SENDER, recipient: bytes32(uint256(uint160(recipient))), destinationCaller: bytes32(uint256(uint160(address(s_usdcTokenPool)))), - messageBody: bytes("") + messageBody: _formatMessage( + 0, + bytes32(uint256(uint160(address(s_token)))), + bytes32(uint256(uint160(recipient))), + amount, + bytes32(uint256(uint160(OWNER))) + ) }); bytes memory message = _generateUSDCMessage(usdcMessage); @@ -437,7 +454,13 @@ contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { sender: SOURCE_CHAIN_TOKEN_SENDER, recipient: bytes32(uint256(uint160(address(s_mockUSDC)))), destinationCaller: bytes32(uint256(uint160(address(s_usdcTokenPool)))), - messageBody: bytes("") + messageBody: _formatMessage( + 0, + bytes32(uint256(uint160(address(s_token)))), + bytes32(uint256(uint160(OWNER))), + amount, + bytes32(uint256(uint160(OWNER))) + ) }); Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ diff --git a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go index 89a5cac840..c0e0b87fe7 100644 --- a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnFromMintTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620045a1380380620045a18339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c051613a2162000b80600039600081816104dd0152818161180601526121ea0152600081816104b7015281816116370152611abc0152600081816102390152818161028e01528181610701015281816107a801528181611557015281816119dc01528181611bd40152818161218001526123d50152613a216000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612b78565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612bd7565b6105f9565b6040516101d29190612c56565b6101ee6040518060400160405280601f81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e302d6465760081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c96565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612cb3565b6106a9565b604051905181526020016101d2565b6103006102fb366004612d3b565b6108be565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612da7565b610939565b610300610aad565b610300610349366004612c96565b610baa565b6101c661035c366004612bd7565b610bf9565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612e2a565b610c10565b6040516101d29190612e65565b6103a7610cb7565b6040516101d29190612ec5565b6103c76103c2366004612bd7565b610cc8565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612bd7565b610d9d565b610300610462366004612c96565b610dc8565b61046f610ea3565b6040516101d29190612f1f565b6103c761048a366004612bd7565b610f5b565b61030061049d366004613087565b61102d565b6103006104b03660046130cc565b6110b6565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c96565b61153c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061310e565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061310e565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361320c565b611550565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152306004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561075a57600080fd5b505af115801561076e573d6000803e3d6000fd5b50506040517f095ea7b3000000000000000000000000000000000000000000000000000000008152336004820152606085013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16925063095ea7b391506044016020604051808303816000875af1158015610808573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061082c9190613301565b5061083d6060830160408401612c96565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161089f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108c6611781565b6109338484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061180492505050565b50505050565b610941611781565b61094a83610bf9565b610991576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109b89061310e565b80601f01602080910402602001604051908101604052809291908181526020018280546109e49061310e565b8015610a315780601f10610a0657610100808354040283529160200191610a31565b820191906000526020600020905b815481529060010190602001808311610a1457829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a6083858361336e565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a9f93929190613488565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610988565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610bb2611781565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff84166119ba565b6040805180820190915260608082526020820152610c35610c30836134ec565b6119d5565b610c428260600135611b9f565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c9c84602001602081019061044f9190612bd7565b81526040805160208181019092526000815291015292915050565b6060610cc36002611c48565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611c55565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061310e565b610dd0611781565b73ffffffffffffffffffffffffffffffffffffffff8116610e1d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610eb16005611c48565b90506000815167ffffffffffffffff811115610ecf57610ecf612f61565b604051908082528060200260200182016040528015610ef8578160200160208202803683370190505b50905060005b8251811015610f5457828181518110610f1957610f1961358e565b6020026020010151828281518110610f3357610f3361358e565b67ffffffffffffffff90921660209283029190910190910152600101610efe565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611c55565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061106d575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156110a6576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610988565b6110b1838383611d07565b505050565b6110be611781565b60005b818110156110b15760008383838181106110dd576110dd61358e565b90506020028101906110ef91906135bd565b6110f8906135fb565b905061110d8160800151826020015115611df1565b6111208160a00151826020015115611df1565b80602001511561141c5780516111429060059067ffffffffffffffff16611f2a565b6111875780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610988565b604081015151158061119c5750606081015151155b156111d3576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906113b490826136af565b50606082015160058201906113c990826136af565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061140f94939291906137c9565b60405180910390a1611533565b80516114349060059067ffffffffffffffff16611f36565b6114795780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610988565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114e26004830182612b2a565b6114f0600583016000612b2a565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016110c1565b611544611781565b61154d81611f42565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115e55760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610988565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611693573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b79190613301565b156116ee576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116fb8160200151612037565b600061170a82602001516105f9565b905080516000148061172e575080805190602001208260a001518051906020012014155b1561176b578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109889190612c56565b61177d8260200151836060015161215d565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611802576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610988565b565b7f000000000000000000000000000000000000000000000000000000000000000061185b576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118f157600083828151811061187b5761187b61358e565b602002602001015190506118998160026121a490919063ffffffff16565b156118e85760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010161185e565b5060005b81518110156110b15760008282815181106119125761191261358e565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361195657506119b2565b6119616002826121c6565b156119b05760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016118f5565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611a6a5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610988565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3c9190613301565b15611b73576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b8081604001516121e8565b611b8d8160200151612267565b61154d816020015182606001516123b5565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015611c2d57600080fd5b505af1158015611c41573d6000803e3d6000fd5b5050505050565b606060006119ce836123f9565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611ce382606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611cc79190613891565b85608001516fffffffffffffffffffffffffffffffff16612454565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611d1083610bf9565b611d52576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610988565b611d5d826000611df1565b67ffffffffffffffff83166000908152600760205260409020611d80908361247e565b611d8b816000611df1565b67ffffffffffffffff83166000908152600760205260409020611db1906002018261247e565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611de4939291906138a4565b60405180910390a1505050565b815115611eb85781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611e47575060408201516fffffffffffffffffffffffffffffffff16155b15611e8057816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109889190613927565b801561177d576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611ef1575060208201516fffffffffffffffffffffffffffffffff1615155b1561177d57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109889190613927565b60006119ce8383612620565b60006119ce838361266f565b3373ffffffffffffffffffffffffffffffffffffffff821603611fc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610988565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61204081610bf9565b612082576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610988565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612101573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121259190613301565b61154d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610988565b67ffffffffffffffff8216600090815260076020526040902061177d90600201827f0000000000000000000000000000000000000000000000000000000000000000612762565b60006119ce8373ffffffffffffffffffffffffffffffffffffffff841661266f565b60006119ce8373ffffffffffffffffffffffffffffffffffffffff8416612620565b7f00000000000000000000000000000000000000000000000000000000000000001561154d57612219600282612ae5565b61154d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610988565b61227081610bf9565b6122b2576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610988565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561232b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234f9190613963565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461154d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610988565b67ffffffffffffffff8216600090815260076020526040902061177d90827f0000000000000000000000000000000000000000000000000000000000000000612762565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116124355750505050509050919050565b6000612473856124648486613980565b61246e9087613997565b612b14565b90505b949350505050565b81546000906124a790700100000000000000000000000000000000900463ffffffff1642613891565b9050801561254957600183015483546124ef916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612454565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461256f916fffffffffffffffffffffffffffffffff9081169116612b14565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611de4908490613927565b6000818152600183016020526040812054612667575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b60008181526001830160205260408120548015612758576000612693600183613891565b85549091506000906126a790600190613891565b905081811461270c5760008660000182815481106126c7576126c761358e565b90600052602060002001549050808760000184815481106126ea576126ea61358e565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061271d5761271d6139aa565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff161580612789575081155b1561279357505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906127d990700100000000000000000000000000000000900463ffffffff1642613891565b90508015612899578183111561281b576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546128559083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612454565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156129505773ffffffffffffffffffffffffffffffffffffffff84166128f8576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610988565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610988565b84831015612a635760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906129949082613891565b61299e878a613891565b6129a89190613997565b6129b291906139d9565b905073ffffffffffffffffffffffffffffffffffffffff8616612a0b576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610988565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610988565b612a6d8584613891565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156119ce565b6000818310612b2357816119ce565b5090919050565b508054612b369061310e565b6000825580601f10612b46575050565b601f01602090049060005260206000209081019061154d91905b80821115612b745760008155600101612b60565b5090565b600060208284031215612b8a57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146119ce57600080fd5b803567ffffffffffffffff81168114612bd257600080fd5b919050565b600060208284031215612be957600080fd5b6119ce82612bba565b6000815180845260005b81811015612c1857602081850181015186830182015201612bfc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119ce6020830184612bf2565b73ffffffffffffffffffffffffffffffffffffffff8116811461154d57600080fd5b8035612bd281612c69565b600060208284031215612ca857600080fd5b81356119ce81612c69565b600060208284031215612cc557600080fd5b813567ffffffffffffffff811115612cdc57600080fd5b820161010081850312156119ce57600080fd5b60008083601f840112612d0157600080fd5b50813567ffffffffffffffff811115612d1957600080fd5b6020830191508360208260051b8501011115612d3457600080fd5b9250929050565b60008060008060408587031215612d5157600080fd5b843567ffffffffffffffff80821115612d6957600080fd5b612d7588838901612cef565b90965094506020870135915080821115612d8e57600080fd5b50612d9b87828801612cef565b95989497509550505050565b600080600060408486031215612dbc57600080fd5b612dc584612bba565b9250602084013567ffffffffffffffff80821115612de257600080fd5b818601915086601f830112612df657600080fd5b813581811115612e0557600080fd5b876020828501011115612e1757600080fd5b6020830194508093505050509250925092565b600060208284031215612e3c57600080fd5b813567ffffffffffffffff811115612e5357600080fd5b820160a081850312156119ce57600080fd5b602081526000825160406020840152612e816060840182612bf2565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612ebc8282612bf2565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612f1357835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612ee1565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612f1357835167ffffffffffffffff1683529284019291840191600101612f3b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612fb457612fb4612f61565b60405290565b60405160c0810167ffffffffffffffff81118282101715612fb457612fb4612f61565b801515811461154d57600080fd5b8035612bd281612fdd565b80356fffffffffffffffffffffffffffffffff81168114612bd257600080fd5b60006060828403121561302857600080fd5b6040516060810181811067ffffffffffffffff8211171561304b5761304b612f61565b604052905080823561305c81612fdd565b815261306a60208401612ff6565b602082015261307b60408401612ff6565b60408201525092915050565b600080600060e0848603121561309c57600080fd5b6130a584612bba565b92506130b48560208601613016565b91506130c38560808601613016565b90509250925092565b600080602083850312156130df57600080fd5b823567ffffffffffffffff8111156130f657600080fd5b61310285828601612cef565b90969095509350505050565b600181811c9082168061312257607f821691505b60208210810361315b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f83011261317257600080fd5b813567ffffffffffffffff8082111561318d5761318d612f61565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156131d3576131d3612f61565b816040528381528660208588010111156131ec57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561321f57600080fd5b613227612f90565b823567ffffffffffffffff8082111561323f57600080fd5b61324b36838701613161565b835261325960208601612bba565b602084015261326a60408601612c8b565b60408401526060850135606084015261328560808601612c8b565b608084015260a085013591508082111561329e57600080fd5b6132aa36838701613161565b60a084015260c08501359150808211156132c357600080fd5b6132cf36838701613161565b60c084015260e08501359150808211156132e857600080fd5b506132f536828601613161565b60e08301525092915050565b60006020828403121561331357600080fd5b81516119ce81612fdd565b601f8211156110b1576000816000526020600020601f850160051c810160208610156133475750805b601f850160051c820191505b8181101561336657828155600101613353565b505050505050565b67ffffffffffffffff83111561338657613386612f61565b61339a83613394835461310e565b8361331e565b6000601f8411600181146133ec57600085156133b65750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611c41565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561343b578685013582556020948501946001909201910161341b565b5086821015613476577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b60408152600061349b6040830186612bf2565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a082360312156134fe57600080fd5b60405160a0810167ffffffffffffffff828210818311171561352257613522612f61565b81604052843591508082111561353757600080fd5b5061354436828601613161565b82525061355360208401612bba565b6020820152604083013561356681612c69565b604082015260608381013590820152608083013561358381612c69565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126135f157600080fd5b9190910192915050565b6000610140823603121561360e57600080fd5b613616612fba565b61361f83612bba565b815261362d60208401612feb565b6020820152604083013567ffffffffffffffff8082111561364d57600080fd5b61365936838701613161565b6040840152606085013591508082111561367257600080fd5b5061367f36828601613161565b6060830152506136923660808501613016565b60808201526136a43660e08501613016565b60a082015292915050565b815167ffffffffffffffff8111156136c9576136c9612f61565b6136dd816136d7845461310e565b8461331e565b602080601f83116001811461373057600084156136fa5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613366565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561377d5788860151825594840194600190910190840161375e565b50858210156137b957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526137ed81840187612bf2565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061382b9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612ebc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f3613862565b67ffffffffffffffff8416815260e081016138f060208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612476565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561397557600080fd5b81516119ce81612c69565b80820281158282048414176105f3576105f3613862565b808201808211156105f3576105f3613862565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613a0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b506040516200450b3803806200450b8339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161399262000b79600039600081816104dd01528181611777015261215b0152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b45015281816120f1015261234601526139926000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae9565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b48565b6105f9565b6040516101d29190612bc7565b6101ee6040518060400160405280601f81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e302d6465760081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c07565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c24565b6106a9565b604051905181526020016101d2565b6103006102fb366004612cac565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d18565b6108aa565b610300610a1e565b610300610349366004612c07565b610b1b565b6101c661035c366004612b48565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d9b565b610b81565b6040516101d29190612dd6565b6103a7610c28565b6040516101d29190612e36565b6103c76103c2366004612b48565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b48565b610d0e565b610300610462366004612c07565b610d39565b61046f610e14565b6040516101d29190612e90565b6103c761048a366004612b48565b610ecc565b61030061049d366004612ff8565b610f9e565b6103006104b036600461303d565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c07565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061307f565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361317d565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c07565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c07565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109299061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546109559061307f565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132c2565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133dc565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba183613440565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b48565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb9565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc6565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061307f565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb9565b90506000815167ffffffffffffffff811115610e4057610e40612ed2565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134e2565b6020026020010151828281518110610ea457610ea46134e2565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc6565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c78565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134e2565b90506020028101906110609190613511565b6110699061354f565b905061107e8160800151826020015115611d62565b6110918160a00151826020015115611d62565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e9b565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906113259082613603565b506060820151600582019061133a9082613603565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c29550611380949392919061371d565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea7565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a9b565b611461600583016000612a9b565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611eb3565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b6565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa8565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc7565b6116ee826020015183606001516120ce565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134e2565b6020026020010151905061180a81600261211590919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134e2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612137565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b6565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612159565b611afe81602001516121d8565b6114be81602001518260600151612326565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015611b9e57600080fd5b505af1158015611bb2573d6000803e3d6000fd5b5050505050565b6060600061193f8361236a565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c5482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c389190613802565b85608001516fffffffffffffffffffffffffffffffff166123c5565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c8183610b6a565b611cc3576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cce826000611d62565b67ffffffffffffffff83166000908152600760205260409020611cf190836123ef565b611cfc816000611d62565b67ffffffffffffffff83166000908152600760205260409020611d2290600201826123ef565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d5593929190613815565b60405180910390a1505050565b815115611e295781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db8575060408201516fffffffffffffffffffffffffffffffff16155b15611df157816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e62575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b600061193f8383612591565b600061193f83836125e0565b3373ffffffffffffffffffffffffffffffffffffffff821603611f32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fb181610b6a565b611ff3576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612072573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209691906137b6565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126d3565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125e0565b600061193f8373ffffffffffffffffffffffffffffffffffffffff8416612591565b7f0000000000000000000000000000000000000000000000000000000000000000156114be5761218a600282612a56565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121e181610b6a565b612223576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c091906138d4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126d3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a65750505050509050919050565b60006123e4856123d584866138f1565b6123df9087613908565b612a85565b90505b949350505050565b815460009061241890700100000000000000000000000000000000900463ffffffff1642613802565b905080156124ba5760018301548354612460916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123c5565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124e0916fffffffffffffffffffffffffffffffff9081169116612a85565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d55908490613898565b60008181526001830160205260408120546125d8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c9576000612604600183613802565b855490915060009061261890600190613802565b905081811461267d576000866000018281548110612638576126386134e2565b906000526020600020015490508087600001848154811061265b5761265b6134e2565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268e5761268e61391b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126fa575081155b1561270457505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274a90700100000000000000000000000000000000900463ffffffff1642613802565b9050801561280a578183111561278c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c69083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123c5565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128c15773ffffffffffffffffffffffffffffffffffffffff8416612869576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129d45760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906129059082613802565b61290f878a613802565b6129199190613908565b612923919061394a565b905073ffffffffffffffffffffffffffffffffffffffff861661297c576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129de8584613802565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a94578161193f565b5090919050565b508054612aa79061307f565b6000825580601f10612ab7575050565b601f0160209004906000526020600020908101906114be91905b80821115612ae55760008155600101612ad1565b5090565b600060208284031215612afb57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b4357600080fd5b919050565b600060208284031215612b5a57600080fd5b61193f82612b2b565b6000815180845260005b81811015612b8957602081850181015186830182015201612b6d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b63565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b4381612bda565b600060208284031215612c1957600080fd5b813561193f81612bda565b600060208284031215612c3657600080fd5b813567ffffffffffffffff811115612c4d57600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c7257600080fd5b50813567ffffffffffffffff811115612c8a57600080fd5b6020830191508360208260051b8501011115612ca557600080fd5b9250929050565b60008060008060408587031215612cc257600080fd5b843567ffffffffffffffff80821115612cda57600080fd5b612ce688838901612c60565b90965094506020870135915080821115612cff57600080fd5b50612d0c87828801612c60565b95989497509550505050565b600080600060408486031215612d2d57600080fd5b612d3684612b2b565b9250602084013567ffffffffffffffff80821115612d5357600080fd5b818601915086601f830112612d6757600080fd5b813581811115612d7657600080fd5b876020828501011115612d8857600080fd5b6020830194508093505050509250925092565b600060208284031215612dad57600080fd5b813567ffffffffffffffff811115612dc457600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612df26060840182612b63565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e2d8282612b63565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e52565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835167ffffffffffffffff1683529284019291840191600101612eac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f2557612f25612ed2565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f2557612f25612ed2565b80151581146114be57600080fd5b8035612b4381612f4e565b80356fffffffffffffffffffffffffffffffff81168114612b4357600080fd5b600060608284031215612f9957600080fd5b6040516060810181811067ffffffffffffffff82111715612fbc57612fbc612ed2565b6040529050808235612fcd81612f4e565b8152612fdb60208401612f67565b6020820152612fec60408401612f67565b60408201525092915050565b600080600060e0848603121561300d57600080fd5b61301684612b2b565b92506130258560208601612f87565b91506130348560808601612f87565b90509250925092565b6000806020838503121561305057600080fd5b823567ffffffffffffffff81111561306757600080fd5b61307385828601612c60565b90969095509350505050565b600181811c9082168061309357607f821691505b6020821081036130cc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130e357600080fd5b813567ffffffffffffffff808211156130fe576130fe612ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561314457613144612ed2565b8160405283815286602085880101111561315d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561319057600080fd5b613198612f01565b823567ffffffffffffffff808211156131b057600080fd5b6131bc368387016130d2565b83526131ca60208601612b2b565b60208401526131db60408601612bfc565b6040840152606085013560608401526131f660808601612bfc565b608084015260a085013591508082111561320f57600080fd5b61321b368387016130d2565b60a084015260c085013591508082111561323457600080fd5b613240368387016130d2565b60c084015260e085013591508082111561325957600080fd5b50613266368286016130d2565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c8101602086101561329b5750805b601f850160051c820191505b818110156132ba578281556001016132a7565b505050505050565b67ffffffffffffffff8311156132da576132da612ed2565b6132ee836132e8835461307f565b83613272565b6000601f841160018114613340576000851561330a5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bb2565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561338f578685013582556020948501946001909201910161336f565b50868210156133ca577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133ef6040830186612b63565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561345257600080fd5b60405160a0810167ffffffffffffffff828210818311171561347657613476612ed2565b81604052843591508082111561348b57600080fd5b50613498368286016130d2565b8252506134a760208401612b2b565b602082015260408301356134ba81612bda565b60408201526060838101359082015260808301356134d781612bda565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261354557600080fd5b9190910192915050565b6000610140823603121561356257600080fd5b61356a612f2b565b61357383612b2b565b815261358160208401612f5c565b6020820152604083013567ffffffffffffffff808211156135a157600080fd5b6135ad368387016130d2565b604084015260608501359150808211156135c657600080fd5b506135d3368286016130d2565b6060830152506135e63660808501612f87565b60808201526135f83660e08501612f87565b60a082015292915050565b815167ffffffffffffffff81111561361d5761361d612ed2565b6136318161362b845461307f565b84613272565b602080601f831160018114613684576000841561364e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132ba565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136d1578886015182559484019460019091019084016136b2565b508582101561370d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261374181840187612b63565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061377f9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e2d565b6000602082840312156137c857600080fd5b815161193f81612f4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137d3565b67ffffffffffffffff8416815260e0810161386160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e7565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e657600080fd5b815161193f81612bda565b80820281158282048414176105f3576105f36137d3565b808201808211156105f3576105f36137d3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613980577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var BurnFromMintTokenPoolABI = BurnFromMintTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go index 6c7cc7083b..2a4f18f6fb 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnMintTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620041493803806200414983398101604081905262000034916200054c565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000176565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001685760408051600081526020810190915262000168908462000221565b5050505050505050620006aa565b336001600160a01b03821603620001d05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000242576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002cd5760008382815181106200026657620002666200065c565b60209081029190910101519050620002806002826200037e565b15620002c3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000245565b5060005b815181101562000379576000828281518110620002f257620002f26200065c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200031e575062000370565b6200032b6002826200039e565b156200036e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d1565b505050565b600062000395836001600160a01b038416620003b5565b90505b92915050565b600062000395836001600160a01b038416620004b9565b60008181526001830160205260408120548015620004ae576000620003dc60018362000672565b8554909150600090620003f29060019062000672565b90508181146200045e5760008660000182815481106200041657620004166200065c565b90600052602060002001549050808760000184815481106200043c576200043c6200065c565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000472576200047262000694565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000398565b600091505062000398565b6000818152600183016020526040812054620005025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000398565b50600062000398565b6001600160a01b03811681146200052157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000547816200050b565b919050565b600080600080608085870312156200056357600080fd5b845162000570816200050b565b602086810151919550906001600160401b03808211156200059057600080fd5b818801915088601f830112620005a557600080fd5b815181811115620005ba57620005ba62000524565b8060051b604051601f19603f83011681018181108582111715620005e257620005e262000524565b60405291825284820192508381018501918b8311156200060157600080fd5b938501935b828510156200062a576200061a856200053a565b8452938501939285019262000606565b80985050505050505062000641604086016200053a565b915062000651606086016200053a565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051613a1b6200072e600039600081816104dd0152818161180601526121e40152600081816104b7015281816116370152611abc0152600081816102390152818161028e01528181610701015281816107a801528181611557015281816119dc01528181611bce0152818161217a01526123cf0152613a1b6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612b72565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612bd1565b6105f9565b6040516101d29190612c50565b6101ee6040518060400160405280601b81526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e302d646576000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c90565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612cad565b6106a9565b604051905181526020016101d2565b6103006102fb366004612d35565b6108be565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612da1565b610939565b610300610aad565b610300610349366004612c90565b610baa565b6101c661035c366004612bd1565b610bf9565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612e24565b610c10565b6040516101d29190612e5f565b6103a7610cb7565b6040516101d29190612ebf565b6103c76103c2366004612bd1565b610cc8565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612bd1565b610d9d565b610300610462366004612c90565b610dc8565b61046f610ea3565b6040516101d29190612f19565b6103c761048a366004612bd1565b610f5b565b61030061049d366004613081565b61102d565b6103006104b03660046130c6565b6110b6565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c90565b61153c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061062490613108565b80601f016020809104026020016040519081016040528092919081815260200182805461065090613108565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c483613206565b611550565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152306004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561075a57600080fd5b505af115801561076e573d6000803e3d6000fd5b50506040517f095ea7b3000000000000000000000000000000000000000000000000000000008152336004820152606085013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16925063095ea7b391506044016020604051808303816000875af1158015610808573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061082c91906132fb565b5061083d6060830160408401612c90565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161089f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108c6611781565b6109338484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061180492505050565b50505050565b610941611781565b61094a83610bf9565b610991576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109b890613108565b80601f01602080910402602001604051908101604052809291908181526020018280546109e490613108565b8015610a315780601f10610a0657610100808354040283529160200191610a31565b820191906000526020600020905b815481529060010190602001808311610a1457829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a60838583613368565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a9f93929190613482565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610988565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610bb2611781565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff84166119ba565b6040805180820190915260608082526020820152610c35610c30836134e6565b6119d5565b610c428260600135611b9f565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c9c84602001602081019061044f9190612bd1565b81526040805160208181019092526000815291015292915050565b6060610cc36002611c42565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611c4f565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061062490613108565b610dd0611781565b73ffffffffffffffffffffffffffffffffffffffff8116610e1d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610eb16005611c42565b90506000815167ffffffffffffffff811115610ecf57610ecf612f5b565b604051908082528060200260200182016040528015610ef8578160200160208202803683370190505b50905060005b8251811015610f5457828181518110610f1957610f19613588565b6020026020010151828281518110610f3357610f33613588565b67ffffffffffffffff90921660209283029190910190910152600101610efe565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611c4f565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061106d575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156110a6576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610988565b6110b1838383611d01565b505050565b6110be611781565b60005b818110156110b15760008383838181106110dd576110dd613588565b90506020028101906110ef91906135b7565b6110f8906135f5565b905061110d8160800151826020015115611deb565b6111208160a00151826020015115611deb565b80602001511561141c5780516111429060059067ffffffffffffffff16611f24565b6111875780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610988565b604081015151158061119c5750606081015151155b156111d3576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906113b490826136a9565b50606082015160058201906113c990826136a9565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061140f94939291906137c3565b60405180910390a1611533565b80516114349060059067ffffffffffffffff16611f30565b6114795780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610988565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114e26004830182612b24565b6114f0600583016000612b24565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016110c1565b611544611781565b61154d81611f3c565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115e55760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610988565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611693573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b791906132fb565b156116ee576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116fb8160200151612031565b600061170a82602001516105f9565b905080516000148061172e575080805190602001208260a001518051906020012014155b1561176b578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109889190612c50565b61177d82602001518360600151612157565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611802576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610988565b565b7f000000000000000000000000000000000000000000000000000000000000000061185b576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118f157600083828151811061187b5761187b613588565b6020026020010151905061189981600261219e90919063ffffffff16565b156118e85760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010161185e565b5060005b81518110156110b157600082828151811061191257611912613588565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361195657506119b2565b6119616002826121c0565b156119b05760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016118f5565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611a6a5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610988565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3c91906132fb565b15611b73576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b8081604001516121e2565b611b8d8160200151612261565b61154d816020015182606001516123af565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611c2757600080fd5b505af1158015611c3b573d6000803e3d6000fd5b5050505050565b606060006119ce836123f3565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611cdd82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611cc1919061388b565b85608001516fffffffffffffffffffffffffffffffff1661244e565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611d0a83610bf9565b611d4c576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610988565b611d57826000611deb565b67ffffffffffffffff83166000908152600760205260409020611d7a9083612478565b611d85816000611deb565b67ffffffffffffffff83166000908152600760205260409020611dab9060020182612478565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611dde9392919061389e565b60405180910390a1505050565b815115611eb25781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611e41575060408201516fffffffffffffffffffffffffffffffff16155b15611e7a57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109889190613921565b801561177d576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611eeb575060208201516fffffffffffffffffffffffffffffffff1615155b1561177d57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109889190613921565b60006119ce838361261a565b60006119ce8383612669565b3373ffffffffffffffffffffffffffffffffffffffff821603611fbb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610988565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61203a81610bf9565b61207c576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610988565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156120fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211f91906132fb565b61154d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610988565b67ffffffffffffffff8216600090815260076020526040902061177d90600201827f000000000000000000000000000000000000000000000000000000000000000061275c565b60006119ce8373ffffffffffffffffffffffffffffffffffffffff8416612669565b60006119ce8373ffffffffffffffffffffffffffffffffffffffff841661261a565b7f00000000000000000000000000000000000000000000000000000000000000001561154d57612213600282612adf565b61154d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610988565b61226a81610bf9565b6122ac576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610988565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612325573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612349919061395d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461154d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610988565b67ffffffffffffffff8216600090815260076020526040902061177d90827f000000000000000000000000000000000000000000000000000000000000000061275c565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b81548152602001906001019080831161242f5750505050509050919050565b600061246d8561245e848661397a565b6124689087613991565b612b0e565b90505b949350505050565b81546000906124a190700100000000000000000000000000000000900463ffffffff164261388b565b9050801561254357600183015483546124e9916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661244e565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612569916fffffffffffffffffffffffffffffffff9081169116612b0e565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611dde908490613921565b6000818152600183016020526040812054612661575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b6000818152600183016020526040812054801561275257600061268d60018361388b565b85549091506000906126a19060019061388b565b90508181146127065760008660000182815481106126c1576126c1613588565b90600052602060002001549050808760000184815481106126e4576126e4613588565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612717576127176139a4565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff161580612783575081155b1561278d57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906127d390700100000000000000000000000000000000900463ffffffff164261388b565b905080156128935781831115612815576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461284f9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661244e565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561294a5773ffffffffffffffffffffffffffffffffffffffff84166128f2576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610988565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610988565b84831015612a5d5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061298e908261388b565b612998878a61388b565b6129a29190613991565b6129ac91906139d3565b905073ffffffffffffffffffffffffffffffffffffffff8616612a05576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610988565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610988565b612a67858461388b565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156119ce565b6000818310612b1d57816119ce565b5090919050565b508054612b3090613108565b6000825580601f10612b40575050565b601f01602090049060005260206000209081019061154d91905b80821115612b6e5760008155600101612b5a565b5090565b600060208284031215612b8457600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146119ce57600080fd5b803567ffffffffffffffff81168114612bcc57600080fd5b919050565b600060208284031215612be357600080fd5b6119ce82612bb4565b6000815180845260005b81811015612c1257602081850181015186830182015201612bf6565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119ce6020830184612bec565b73ffffffffffffffffffffffffffffffffffffffff8116811461154d57600080fd5b8035612bcc81612c63565b600060208284031215612ca257600080fd5b81356119ce81612c63565b600060208284031215612cbf57600080fd5b813567ffffffffffffffff811115612cd657600080fd5b820161010081850312156119ce57600080fd5b60008083601f840112612cfb57600080fd5b50813567ffffffffffffffff811115612d1357600080fd5b6020830191508360208260051b8501011115612d2e57600080fd5b9250929050565b60008060008060408587031215612d4b57600080fd5b843567ffffffffffffffff80821115612d6357600080fd5b612d6f88838901612ce9565b90965094506020870135915080821115612d8857600080fd5b50612d9587828801612ce9565b95989497509550505050565b600080600060408486031215612db657600080fd5b612dbf84612bb4565b9250602084013567ffffffffffffffff80821115612ddc57600080fd5b818601915086601f830112612df057600080fd5b813581811115612dff57600080fd5b876020828501011115612e1157600080fd5b6020830194508093505050509250925092565b600060208284031215612e3657600080fd5b813567ffffffffffffffff811115612e4d57600080fd5b820160a081850312156119ce57600080fd5b602081526000825160406020840152612e7b6060840182612bec565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612eb68282612bec565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612f0d57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612edb565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612f0d57835167ffffffffffffffff1683529284019291840191600101612f35565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612fae57612fae612f5b565b60405290565b60405160c0810167ffffffffffffffff81118282101715612fae57612fae612f5b565b801515811461154d57600080fd5b8035612bcc81612fd7565b80356fffffffffffffffffffffffffffffffff81168114612bcc57600080fd5b60006060828403121561302257600080fd5b6040516060810181811067ffffffffffffffff8211171561304557613045612f5b565b604052905080823561305681612fd7565b815261306460208401612ff0565b602082015261307560408401612ff0565b60408201525092915050565b600080600060e0848603121561309657600080fd5b61309f84612bb4565b92506130ae8560208601613010565b91506130bd8560808601613010565b90509250925092565b600080602083850312156130d957600080fd5b823567ffffffffffffffff8111156130f057600080fd5b6130fc85828601612ce9565b90969095509350505050565b600181811c9082168061311c57607f821691505b602082108103613155577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f83011261316c57600080fd5b813567ffffffffffffffff8082111561318757613187612f5b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156131cd576131cd612f5b565b816040528381528660208588010111156131e657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561321957600080fd5b613221612f8a565b823567ffffffffffffffff8082111561323957600080fd5b6132453683870161315b565b835261325360208601612bb4565b602084015261326460408601612c85565b60408401526060850135606084015261327f60808601612c85565b608084015260a085013591508082111561329857600080fd5b6132a43683870161315b565b60a084015260c08501359150808211156132bd57600080fd5b6132c93683870161315b565b60c084015260e08501359150808211156132e257600080fd5b506132ef3682860161315b565b60e08301525092915050565b60006020828403121561330d57600080fd5b81516119ce81612fd7565b601f8211156110b1576000816000526020600020601f850160051c810160208610156133415750805b601f850160051c820191505b818110156133605782815560010161334d565b505050505050565b67ffffffffffffffff83111561338057613380612f5b565b6133948361338e8354613108565b83613318565b6000601f8411600181146133e657600085156133b05750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611c3b565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156134355786850135825560209485019460019092019101613415565b5086821015613470577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006134956040830186612bec565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a082360312156134f857600080fd5b60405160a0810167ffffffffffffffff828210818311171561351c5761351c612f5b565b81604052843591508082111561353157600080fd5b5061353e3682860161315b565b82525061354d60208401612bb4565b6020820152604083013561356081612c63565b604082015260608381013590820152608083013561357d81612c63565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126135eb57600080fd5b9190910192915050565b6000610140823603121561360857600080fd5b613610612fb4565b61361983612bb4565b815261362760208401612fe5565b6020820152604083013567ffffffffffffffff8082111561364757600080fd5b6136533683870161315b565b6040840152606085013591508082111561366c57600080fd5b506136793682860161315b565b60608301525061368c3660808501613010565b608082015261369e3660e08501613010565b60a082015292915050565b815167ffffffffffffffff8111156136c3576136c3612f5b565b6136d7816136d18454613108565b84613318565b602080601f83116001811461372a57600084156136f45750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613360565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561377757888601518255948401946001909101908401613758565b50858210156137b357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526137e781840187612bec565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506138259050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612eb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f361385c565b67ffffffffffffffff8416815260e081016138ea60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612470565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561396f57600080fd5b81516119ce81612c63565b80820281158282048414176105f3576105f361385c565b808201808211156105f3576105f361385c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613a09577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b50604051620040b3380380620040b383398101604081905262000034916200054c565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000176565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001685760408051600081526020810190915262000168908462000221565b5050505050505050620006aa565b336001600160a01b03821603620001d05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000242576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002cd5760008382815181106200026657620002666200065c565b60209081029190910101519050620002806002826200037e565b15620002c3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000245565b5060005b815181101562000379576000828281518110620002f257620002f26200065c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200031e575062000370565b6200032b6002826200039e565b156200036e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d1565b505050565b600062000395836001600160a01b038416620003b5565b90505b92915050565b600062000395836001600160a01b038416620004b9565b60008181526001830160205260408120548015620004ae576000620003dc60018362000672565b8554909150600090620003f29060019062000672565b90508181146200045e5760008660000182815481106200041657620004166200065c565b90600052602060002001549050808760000184815481106200043c576200043c6200065c565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000472576200047262000694565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000398565b600091505062000398565b6000818152600183016020526040812054620005025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000398565b50600062000398565b6001600160a01b03811681146200052157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000547816200050b565b919050565b600080600080608085870312156200056357600080fd5b845162000570816200050b565b602086810151919550906001600160401b03808211156200059057600080fd5b818801915088601f830112620005a557600080fd5b815181811115620005ba57620005ba62000524565b8060051b604051601f19603f83011681018181108582111715620005e257620005e262000524565b60405291825284820192508381018501918b8311156200060157600080fd5b938501935b828510156200062a576200061a856200053a565b8452938501939285019262000606565b80985050505050505062000641604086016200053a565b915062000651606086016200053a565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161398c62000727600039600081816104dd0152818161177701526121550152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b3f015281816120eb0152612340015261398c6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae3565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b42565b6105f9565b6040516101d29190612bc1565b6101ee6040518060400160405280601b81526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e302d646576000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c01565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c1e565b6106a9565b604051905181526020016101d2565b6103006102fb366004612ca6565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d12565b6108aa565b610300610a1e565b610300610349366004612c01565b610b1b565b6101c661035c366004612b42565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d95565b610b81565b6040516101d29190612dd0565b6103a7610c28565b6040516101d29190612e30565b6103c76103c2366004612b42565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b42565b610d0e565b610300610462366004612c01565b610d39565b61046f610e14565b6040516101d29190612e8a565b6103c761048a366004612b42565b610ecc565b61030061049d366004612ff2565b610f9e565b6103006104b0366004613037565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c01565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061062490613079565b80601f016020809104026020016040519081016040528092919081815260200182805461065090613079565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c483613177565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c01565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c01565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461092990613079565b80601f016020809104026020016040519081016040528092919081815260200182805461095590613079565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132bc565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133d6565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba18361343a565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b42565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb3565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc0565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061062490613079565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb3565b90506000815167ffffffffffffffff811115610e4057610e40612ecc565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134dc565b6020026020010151828281518110610ea457610ea46134dc565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc0565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c72565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134dc565b9050602002810190611060919061350b565b61106990613549565b905061107e8160800151826020015115611d5c565b6110918160a00151826020015115611d5c565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e95565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061132590826135fd565b506060820151600582019061133a90826135fd565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506113809493929190613717565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea1565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a95565b611461600583016000612a95565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611ead565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b0565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa2565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc1565b6116ee826020015183606001516120c8565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134dc565b6020026020010151905061180a81600261210f90919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134dc565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612131565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b0565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612153565b611afe81602001516121d2565b6114be81602001518260600151612320565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611b9857600080fd5b505af1158015611bac573d6000803e3d6000fd5b5050505050565b6060600061193f83612364565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c4e82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c3291906137fc565b85608001516fffffffffffffffffffffffffffffffff166123bf565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c7b83610b6a565b611cbd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cc8826000611d5c565b67ffffffffffffffff83166000908152600760205260409020611ceb90836123e9565b611cf6816000611d5c565b67ffffffffffffffff83166000908152600760205260409020611d1c90600201826123e9565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d4f9392919061380f565b60405180910390a1505050565b815115611e235781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db2575060408201516fffffffffffffffffffffffffffffffff16155b15611deb57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613892565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e5c575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613892565b600061193f838361258b565b600061193f83836125da565b3373ffffffffffffffffffffffffffffffffffffffff821603611f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fab81610b6a565b611fed576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561206c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209091906137b0565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126cd565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125da565b600061193f8373ffffffffffffffffffffffffffffffffffffffff841661258b565b7f0000000000000000000000000000000000000000000000000000000000000000156114be57612184600282612a50565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121db81610b6a565b61221d576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ba91906138ce565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126cd565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a05750505050509050919050565b60006123de856123cf84866138eb565b6123d99087613902565b612a7f565b90505b949350505050565b815460009061241290700100000000000000000000000000000000900463ffffffff16426137fc565b905080156124b4576001830154835461245a916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123bf565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124da916fffffffffffffffffffffffffffffffff9081169116612a7f565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d4f908490613892565b60008181526001830160205260408120546125d2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c35760006125fe6001836137fc565b8554909150600090612612906001906137fc565b9050818114612677576000866000018281548110612632576126326134dc565b9060005260206000200154905080876000018481548110612655576126556134dc565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268857612688613915565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126f4575081155b156126fe57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274490700100000000000000000000000000000000900463ffffffff16426137fc565b905080156128045781831115612786576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c09083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123bf565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128bb5773ffffffffffffffffffffffffffffffffffffffff8416612863576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129ce5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128ff90826137fc565b612909878a6137fc565b6129139190613902565b61291d9190613944565b905073ffffffffffffffffffffffffffffffffffffffff8616612976576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129d885846137fc565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a8e578161193f565b5090919050565b508054612aa190613079565b6000825580601f10612ab1575050565b601f0160209004906000526020600020908101906114be91905b80821115612adf5760008155600101612acb565b5090565b600060208284031215612af557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b3d57600080fd5b919050565b600060208284031215612b5457600080fd5b61193f82612b25565b6000815180845260005b81811015612b8357602081850181015186830182015201612b67565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b5d565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b3d81612bd4565b600060208284031215612c1357600080fd5b813561193f81612bd4565b600060208284031215612c3057600080fd5b813567ffffffffffffffff811115612c4757600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c6c57600080fd5b50813567ffffffffffffffff811115612c8457600080fd5b6020830191508360208260051b8501011115612c9f57600080fd5b9250929050565b60008060008060408587031215612cbc57600080fd5b843567ffffffffffffffff80821115612cd457600080fd5b612ce088838901612c5a565b90965094506020870135915080821115612cf957600080fd5b50612d0687828801612c5a565b95989497509550505050565b600080600060408486031215612d2757600080fd5b612d3084612b25565b9250602084013567ffffffffffffffff80821115612d4d57600080fd5b818601915086601f830112612d6157600080fd5b813581811115612d7057600080fd5b876020828501011115612d8257600080fd5b6020830194508093505050509250925092565b600060208284031215612da757600080fd5b813567ffffffffffffffff811115612dbe57600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612dec6060840182612b5d565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e278282612b5d565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e7e57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e4c565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e7e57835167ffffffffffffffff1683529284019291840191600101612ea6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f1f57612f1f612ecc565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f1f57612f1f612ecc565b80151581146114be57600080fd5b8035612b3d81612f48565b80356fffffffffffffffffffffffffffffffff81168114612b3d57600080fd5b600060608284031215612f9357600080fd5b6040516060810181811067ffffffffffffffff82111715612fb657612fb6612ecc565b6040529050808235612fc781612f48565b8152612fd560208401612f61565b6020820152612fe660408401612f61565b60408201525092915050565b600080600060e0848603121561300757600080fd5b61301084612b25565b925061301f8560208601612f81565b915061302e8560808601612f81565b90509250925092565b6000806020838503121561304a57600080fd5b823567ffffffffffffffff81111561306157600080fd5b61306d85828601612c5a565b90969095509350505050565b600181811c9082168061308d57607f821691505b6020821081036130c6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130dd57600080fd5b813567ffffffffffffffff808211156130f8576130f8612ecc565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561313e5761313e612ecc565b8160405283815286602085880101111561315757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561318a57600080fd5b613192612efb565b823567ffffffffffffffff808211156131aa57600080fd5b6131b6368387016130cc565b83526131c460208601612b25565b60208401526131d560408601612bf6565b6040840152606085013560608401526131f060808601612bf6565b608084015260a085013591508082111561320957600080fd5b613215368387016130cc565b60a084015260c085013591508082111561322e57600080fd5b61323a368387016130cc565b60c084015260e085013591508082111561325357600080fd5b50613260368286016130cc565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c810160208610156132955750805b601f850160051c820191505b818110156132b4578281556001016132a1565b505050505050565b67ffffffffffffffff8311156132d4576132d4612ecc565b6132e8836132e28354613079565b8361326c565b6000601f84116001811461333a57600085156133045750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bac565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156133895786850135825560209485019460019092019101613369565b50868210156133c4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133e96040830186612b5d565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561344c57600080fd5b60405160a0810167ffffffffffffffff828210818311171561347057613470612ecc565b81604052843591508082111561348557600080fd5b50613492368286016130cc565b8252506134a160208401612b25565b602082015260408301356134b481612bd4565b60408201526060838101359082015260808301356134d181612bd4565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261353f57600080fd5b9190910192915050565b6000610140823603121561355c57600080fd5b613564612f25565b61356d83612b25565b815261357b60208401612f56565b6020820152604083013567ffffffffffffffff8082111561359b57600080fd5b6135a7368387016130cc565b604084015260608501359150808211156135c057600080fd5b506135cd368286016130cc565b6060830152506135e03660808501612f81565b60808201526135f23660e08501612f81565b60a082015292915050565b815167ffffffffffffffff81111561361757613617612ecc565b61362b816136258454613079565b8461326c565b602080601f83116001811461367e57600084156136485750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132b4565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136cb578886015182559484019460019091019084016136ac565b508582101561370757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261373b81840187612b5d565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506137799050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e27565b6000602082840312156137c257600080fd5b815161193f81612f48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137cd565b67ffffffffffffffff8416815260e0810161385b60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e1565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e057600080fd5b815161193f81612bd4565b80820281158282048414176105f3576105f36137cd565b808201808211156105f3576105f36137cd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261397a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var BurnMintTokenPoolABI = BurnMintTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go index 5ad79ab872..8361ea5c86 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnMintTokenPoolAndProxyMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620049e7380380620049e7833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050818114620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c0516142aa6200073d6000396000818161050301528181611b3101526125830152600081816104dd0152818161180f0152611de40152600081816102260152818161027b0152818161076001528181610d9a0152818161172f01528181611a2a01528181611d0401528181611eea01528181612519015261276e01526142aa6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639766b93211610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104c8578063dc0bd971146104db578063e0351e1314610501578063f2fde38b1461052757600080fd5b8063c0d786551461047a578063c4bffe2b1461048d578063c75eea9c146104a2578063cf7401f3146104b557600080fd5b8063a8d87a3b116100de578063a8d87a3b146103c7578063af58d59f146103da578063b0f479a114610449578063b79465801461046757600080fd5b80639766b9321461037f5780639a4575b914610392578063a7cd63b7146103b257600080fd5b80636d3d1a58116101715780637d54534e1161014b5780637d54534e1461032857806383826b2b1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b80636d3d1a58146102ef57806378a010b21461030d57806379ba50971461032057600080fd5b806321df0da7116101ad57806321df0da714610224578063240028e81461026b57806339077537146102b857806354c8a4f3146102da57600080fd5b806301ffc9a7146101d45780630a2fd493146101fc578063181f5a771461021c575b600080fd5b6101e76101e236600461321b565b61053a565b60405190151581526020015b60405180910390f35b61020f61020a36600461327a565b61061f565b6040516101f39190613303565b61020f6106cf565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e7610279366004613343565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102cb6102c6366004613360565b6106eb565b604051905181526020016101f3565b6102ed6102e83660046133e8565b610878565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61031b366004613454565b6108f3565b6102ed610a67565b6102ed610336366004613343565b610b64565b6101e76103493660046134d7565b610bb3565b6101e761035c36600461327a565b610c80565b60005473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61038d366004613343565b610c97565b6103a56103a036600461350e565b610d26565b6040516101f39190613549565b6103ba610e96565b6040516101f391906135a9565b6102466103d536600461327a565b503090565b6103ed6103e836600461327a565b610ea7565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610246565b61020f61047536600461327a565b610f7c565b6102ed610488366004613343565b610fa7565b61049561107b565b6040516101f39190613603565b6103ed6104b036600461327a565b611133565b6102ed6104c33660046137ba565b611205565b6102ed6104d63660046137ff565b61128e565b7f0000000000000000000000000000000000000000000000000000000000000000610246565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b6102ed610535366004613343565b611714565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105cd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061061957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061064a90613841565b80601f016020809104026020016040519081016040528092919081815260200182805461067690613841565b80156106c35780601f10610698576101008083540402835291602001916106c3565b820191906000526020600020905b8154815290600101906020018083116106a657829003601f168201915b50505050509050919050565b60405180606001604052806023815260200161427b6023913981565b60408051602081019091526000815261070b61070683613930565b611728565b60095473ffffffffffffffffffffffffffffffffffffffff166107d6576040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b1580156107b957600080fd5b505af11580156107cd573d6000803e3d6000fd5b505050506107e7565b6107e76107e283613930565b611959565b6107f76060830160408401613343565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161085991815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610880611aac565b6108ed84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611b2f92505050565b50505050565b6108fb611aac565b61090483610c80565b61094b576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461097290613841565b80601f016020809104026020016040519081016040528092919081815260200182805461099e90613841565b80156109eb5780601f106109c0576101008083540402835291602001916109eb565b820191906000526020600020905b8154815290600101906020018083116109ce57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a1a838583613a75565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a5993929190613b90565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ae8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610942565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b6c611aac565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610c795750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c799190613bf4565b9392505050565b6000610619600567ffffffffffffffff8416611ce5565b610c9f611aac565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d4b610d4683613c11565b611cfd565b60095473ffffffffffffffffffffffffffffffffffffffff16610e10576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610df357600080fd5b505af1158015610e07573d6000803e3d6000fd5b50505050610e21565b610e21610e1c83613c11565b611ec7565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610e7b846020016020810190610475919061327a565b81526040805160208181019092526000815291015292915050565b6060610ea26002611fe1565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261061990611fee565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061064a90613841565b610faf611aac565b73ffffffffffffffffffffffffffffffffffffffff8116610ffc576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d1a565b606060006110896005611fe1565b90506000815167ffffffffffffffff8111156110a7576110a7613645565b6040519080825280602002602001820160405280156110d0578160200160208202803683370190505b50905060005b825181101561112c578281815181106110f1576110f1613cb3565b602002602001015182828151811061110b5761110b613cb3565b67ffffffffffffffff909216602092830291909101909101526001016110d6565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261061990611fee565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611245575060005473ffffffffffffffffffffffffffffffffffffffff163314155b1561127e576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610942565b6112898383836120a0565b505050565b611296611aac565b60005b818110156112895760008383838181106112b5576112b5613cb3565b90506020028101906112c79190613ce2565b6112d090613d20565b90506112e5816080015182602001511561218a565b6112f88160a0015182602001511561218a565b8060200151156115f457805161131a9060059067ffffffffffffffff166122c3565b61135f5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610942565b60408101515115806113745750606081015151155b156113ab576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061158c9082613dd4565b50606082015160058201906115a19082613dd4565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506115e79493929190613eee565b60405180910390a161170b565b805161160c9060059067ffffffffffffffff166122cf565b6116515780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610942565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116ba60048301826131cd565b6116c86005830160006131cd565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611299565b61171c611aac565b611725816122db565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146117bd5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610942565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561186b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188f9190613bf4565b156118c6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d381602001516123d0565b60006118e2826020015161061f565b9050805160001480611906575080805190602001208260a001518051906020012014155b15611943578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109429190613303565b611955826020015183606001516124f6565b5050565b6009548151606083015160208401516040517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90941693638627fad6936119bd9390923092600401613f87565b600060405180830381600087803b1580156119d757600080fd5b505af11580156119eb573d6000803e3d6000fd5b5050505060608101516040517f095ea7b300000000000000000000000000000000000000000000000000000000815233600482015260248101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063095ea7b3906044016020604051808303816000875af1158015611a88573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119559190613bf4565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610942565b565b7f0000000000000000000000000000000000000000000000000000000000000000611b86576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611c1c576000838281518110611ba657611ba6613cb3565b60200260200101519050611bc481600261253d90919063ffffffff16565b15611c135760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611b89565b5060005b8151811015611289576000828281518110611c3d57611c3d613cb3565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c815750611cdd565b611c8c60028261255f565b15611cdb5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611c20565b60008181526001830160205260408120541515610c79565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611d925760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610942565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611e40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e649190613bf4565b15611e9b576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ea88160400151612581565b611eb58160200151612600565b6117258160200151826060015161274e565b6009546060820151611f149173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690612792565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611f7c94939291600401613fe8565b6000604051808303816000875af1158015611f9b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119559190810190614048565b60606000610c798361281f565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261207c82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261206091906140e5565b85608001516fffffffffffffffffffffffffffffffff1661287a565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6120a983610c80565b6120eb576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610942565b6120f682600061218a565b67ffffffffffffffff8316600090815260076020526040902061211990836128a4565b61212481600061218a565b67ffffffffffffffff8316600090815260076020526040902061214a90600201826128a4565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161217d939291906140f8565b60405180910390a1505050565b8151156122515781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806121e0575060408201516fffffffffffffffffffffffffffffffff16155b1561221957816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610942919061417b565b8015611955576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff1615158061228a575060208201516fffffffffffffffffffffffffffffffff1615155b1561195557816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610942919061417b565b6000610c798383612a46565b6000610c798383612a95565b3373ffffffffffffffffffffffffffffffffffffffff82160361235a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610942565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6123d981610c80565b61241b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610942565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561249a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124be9190613bf4565b611725576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610942565b67ffffffffffffffff8216600090815260076020526040902061195590600201827f0000000000000000000000000000000000000000000000000000000000000000612b88565b6000610c798373ffffffffffffffffffffffffffffffffffffffff8416612a95565b6000610c798373ffffffffffffffffffffffffffffffffffffffff8416612a46565b7f000000000000000000000000000000000000000000000000000000000000000015611725576125b2600282612f0b565b611725576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610942565b61260981610c80565b61264b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610942565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156126c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e891906141b7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611725576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610942565b67ffffffffffffffff8216600090815260076020526040902061195590827f0000000000000000000000000000000000000000000000000000000000000000612b88565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611289908490612f3a565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106c357602002820191906000526020600020905b81548152602001906001019080831161285b5750505050509050919050565b60006128998561288a84866141d4565b61289490876141eb565b613046565b90505b949350505050565b81546000906128cd90700100000000000000000000000000000000900463ffffffff16426140e5565b9050801561296f5760018301548354612915916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661287a565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612995916fffffffffffffffffffffffffffffffff9081169116613046565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061217d90849061417b565b6000818152600183016020526040812054612a8d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610619565b506000610619565b60008181526001830160205260408120548015612b7e576000612ab96001836140e5565b8554909150600090612acd906001906140e5565b9050818114612b32576000866000018281548110612aed57612aed613cb3565b9060005260206000200154905080876000018481548110612b1057612b10613cb3565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612b4357612b436141fe565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610619565b6000915050610619565b825474010000000000000000000000000000000000000000900460ff161580612baf575081155b15612bb957505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612bff90700100000000000000000000000000000000900463ffffffff16426140e5565b90508015612cbf5781831115612c41576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612c7b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661287a565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612d765773ffffffffffffffffffffffffffffffffffffffff8416612d1e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610942565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610942565b84831015612e895760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612dba90826140e5565b612dc4878a6140e5565b612dce91906141eb565b612dd8919061422d565b905073ffffffffffffffffffffffffffffffffffffffff8616612e31576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610942565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610942565b612e9385846140e5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610c79565b6000612f9c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661305c9092919063ffffffff16565b8051909150156112895780806020019051810190612fba9190613bf4565b611289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610942565b60008183106130555781610c79565b5090919050565b606061289c8484600085856000808673ffffffffffffffffffffffffffffffffffffffff1685876040516130909190614268565b60006040518083038185875af1925050503d80600081146130cd576040519150601f19603f3d011682016040523d82523d6000602084013e6130d2565b606091505b50915091506130e3878383876130ee565b979650505050505050565b6060831561318457825160000361317d5773ffffffffffffffffffffffffffffffffffffffff85163b61317d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610942565b508161289c565b61289c83838151156131995781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109429190613303565b5080546131d990613841565b6000825580601f106131e9575050565b601f01602090049060005260206000209081019061172591905b808211156132175760008155600101613203565b5090565b60006020828403121561322d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610c7957600080fd5b803567ffffffffffffffff8116811461327557600080fd5b919050565b60006020828403121561328c57600080fd5b610c798261325d565b60005b838110156132b0578181015183820152602001613298565b50506000910152565b600081518084526132d1816020860160208601613295565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610c7960208301846132b9565b73ffffffffffffffffffffffffffffffffffffffff8116811461172557600080fd5b803561327581613316565b60006020828403121561335557600080fd5b8135610c7981613316565b60006020828403121561337257600080fd5b813567ffffffffffffffff81111561338957600080fd5b82016101008185031215610c7957600080fd5b60008083601f8401126133ae57600080fd5b50813567ffffffffffffffff8111156133c657600080fd5b6020830191508360208260051b85010111156133e157600080fd5b9250929050565b600080600080604085870312156133fe57600080fd5b843567ffffffffffffffff8082111561341657600080fd5b6134228883890161339c565b9096509450602087013591508082111561343b57600080fd5b506134488782880161339c565b95989497509550505050565b60008060006040848603121561346957600080fd5b6134728461325d565b9250602084013567ffffffffffffffff8082111561348f57600080fd5b818601915086601f8301126134a357600080fd5b8135818111156134b257600080fd5b8760208285010111156134c457600080fd5b6020830194508093505050509250925092565b600080604083850312156134ea57600080fd5b6134f38361325d565b9150602083013561350381613316565b809150509250929050565b60006020828403121561352057600080fd5b813567ffffffffffffffff81111561353757600080fd5b820160a08185031215610c7957600080fd5b60208152600082516040602084015261356560608401826132b9565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526135a082826132b9565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156135f757835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016135c5565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156135f757835167ffffffffffffffff168352928401929184019160010161361f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561369857613698613645565b60405290565b60405160c0810167ffffffffffffffff8111828210171561369857613698613645565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561370857613708613645565b604052919050565b801515811461172557600080fd5b803561327581613710565b80356fffffffffffffffffffffffffffffffff8116811461327557600080fd5b60006060828403121561375b57600080fd5b6040516060810181811067ffffffffffffffff8211171561377e5761377e613645565b604052905080823561378f81613710565b815261379d60208401613729565b60208201526137ae60408401613729565b60408201525092915050565b600080600060e084860312156137cf57600080fd5b6137d88461325d565b92506137e78560208601613749565b91506137f68560808601613749565b90509250925092565b6000806020838503121561381257600080fd5b823567ffffffffffffffff81111561382957600080fd5b6138358582860161339c565b90969095509350505050565b600181811c9082168061385557607f821691505b60208210810361388e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff8211156138ae576138ae613645565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126138eb57600080fd5b81356138fe6138f982613894565b6136c1565b81815284602083860101111561391357600080fd5b816020850160208301376000918101602001919091529392505050565b6000610100823603121561394357600080fd5b61394b613674565b823567ffffffffffffffff8082111561396357600080fd5b61396f368387016138da565b835261397d6020860161325d565b602084015261398e60408601613338565b6040840152606085013560608401526139a960808601613338565b608084015260a08501359150808211156139c257600080fd5b6139ce368387016138da565b60a084015260c08501359150808211156139e757600080fd5b6139f3368387016138da565b60c084015260e0850135915080821115613a0c57600080fd5b50613a19368286016138da565b60e08301525092915050565b601f821115611289576000816000526020600020601f850160051c81016020861015613a4e5750805b601f850160051c820191505b81811015613a6d57828155600101613a5a565b505050505050565b67ffffffffffffffff831115613a8d57613a8d613645565b613aa183613a9b8354613841565b83613a25565b6000601f841160018114613af35760008515613abd5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613b89565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613b425786850135825560209485019460019092019101613b22565b5086821015613b7d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613ba360408301866132b9565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613c0657600080fd5b8151610c7981613710565b600060a08236031215613c2357600080fd5b60405160a0810167ffffffffffffffff8282108183111715613c4757613c47613645565b816040528435915080821115613c5c57600080fd5b50613c69368286016138da565b825250613c786020840161325d565b60208201526040830135613c8b81613316565b6040820152606083810135908201526080830135613ca881613316565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613d1657600080fd5b9190910192915050565b60006101408236031215613d3357600080fd5b613d3b61369e565b613d448361325d565b8152613d526020840161371e565b6020820152604083013567ffffffffffffffff80821115613d7257600080fd5b613d7e368387016138da565b60408401526060850135915080821115613d9757600080fd5b50613da4368286016138da565b606083015250613db73660808501613749565b6080820152613dc93660e08501613749565b60a082015292915050565b815167ffffffffffffffff811115613dee57613dee613645565b613e0281613dfc8454613841565b84613a25565b602080601f831160018114613e555760008415613e1f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613a6d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613ea257888601518255948401946001909101908401613e83565b5085821015613ede57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613f12818401876132b9565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613f509050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526135a0565b60a081526000613f9a60a08301876132b9565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a06020820152600061401760a08301866132b9565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561405a57600080fd5b815167ffffffffffffffff81111561407157600080fd5b8201601f8101841361408257600080fd5b80516140906138f982613894565b8181528560208385010111156140a557600080fd5b6135a0826020830160208601613295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610619576106196140b6565b67ffffffffffffffff8416815260e0810161414460208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261289c565b6060810161061982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156141c957600080fd5b8151610c7981613316565b8082028115828204841417610619576106196140b6565b80820180821115610619576106196140b6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614263577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613d1681846020870161329556fe4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b506040516200495538038062004955833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050818114620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161421f620007366000396000818161050301528181611aa701526124f90152600081816104dd0152818161183a0152611d5a0152600081816102260152818161027b0152818161073f01528181610dc50152818161175a01528181611c7a01528181611e600152818161248f01526126e4015261421f6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639766b93211610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104c8578063dc0bd971146104db578063e0351e1314610501578063f2fde38b1461052757600080fd5b8063c0d786551461047a578063c4bffe2b1461048d578063c75eea9c146104a2578063cf7401f3146104b557600080fd5b8063a8d87a3b116100de578063a8d87a3b146103c7578063af58d59f146103da578063b0f479a114610449578063b79465801461046757600080fd5b80639766b9321461037f5780639a4575b914610392578063a7cd63b7146103b257600080fd5b80636d3d1a58116101715780637d54534e1161014b5780637d54534e1461032857806383826b2b1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b80636d3d1a58146102ef57806378a010b21461030d57806379ba50971461032057600080fd5b806321df0da7116101ad57806321df0da714610224578063240028e81461026b57806339077537146102b857806354c8a4f3146102da57600080fd5b806301ffc9a7146101d45780630a2fd493146101fc578063181f5a771461021c575b600080fd5b6101e76101e2366004613191565b61053a565b60405190151581526020015b60405180910390f35b61020f61020a3660046131f0565b61061f565b6040516101f39190613279565b61020f6106cf565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e76102793660046132b9565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102cb6102c63660046132d6565b6106eb565b604051905181526020016101f3565b6102ed6102e836600461335e565b6108a3565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61031b3660046133ca565b61091e565b6102ed610a92565b6102ed6103363660046132b9565b610b8f565b6101e761034936600461344d565b610bde565b6101e761035c3660046131f0565b610cab565b60005473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61038d3660046132b9565b610cc2565b6103a56103a0366004613484565b610d51565b6040516101f391906134bf565b6103ba610ec1565b6040516101f3919061351f565b6102466103d53660046131f0565b503090565b6103ed6103e83660046131f0565b610ed2565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610246565b61020f6104753660046131f0565b610fa7565b6102ed6104883660046132b9565b610fd2565b6104956110a6565b6040516101f39190613579565b6103ed6104b03660046131f0565b61115e565b6102ed6104c3366004613730565b611230565b6102ed6104d6366004613775565b6112b9565b7f0000000000000000000000000000000000000000000000000000000000000000610246565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b6102ed6105353660046132b9565b61173f565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105cd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061061957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061064a906137b7565b80601f0160208091040260200160405190810160405280929190818152602001828054610676906137b7565b80156106c35780601f10610698576101008083540402835291602001916106c3565b820191906000526020600020905b8154815290600101906020018083116106a657829003601f168201915b50505050509050919050565b6040518060600160405280602381526020016141f06023913981565b60408051602081019091526000815261070b610706836138a6565b611753565b60095473ffffffffffffffffffffffffffffffffffffffff166108015773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961077460608501604086016132b9565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b1580156107e457600080fd5b505af11580156107f8573d6000803e3d6000fd5b50505050610812565b61081261080d836138a6565b611984565b61082260608301604084016132b9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161088491815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108ab611a22565b61091884848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611aa592505050565b50505050565b610926611a22565b61092f83610cab565b610976576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461099d906137b7565b80601f01602080910402602001604051908101604052809291908181526020018280546109c9906137b7565b8015610a165780601f106109eb57610100808354040283529160200191610a16565b820191906000526020600020905b8154815290600101906020018083116109f957829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a458385836139eb565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a8493929190613b05565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161096d565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b97611a22565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610ca45750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca49190613b69565b9392505050565b6000610619600567ffffffffffffffff8416611c5b565b610cca611a22565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d76610d7183613b86565b611c73565b60095473ffffffffffffffffffffffffffffffffffffffff16610e3b576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610e1e57600080fd5b505af1158015610e32573d6000803e3d6000fd5b50505050610e4c565b610e4c610e4783613b86565b611e3d565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610ea684602001602081019061047591906131f0565b81526040805160208181019092526000815291015292915050565b6060610ecd6002611f57565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261061990611f64565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061064a906137b7565b610fda611a22565b73ffffffffffffffffffffffffffffffffffffffff8116611027576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d45565b606060006110b46005611f57565b90506000815167ffffffffffffffff8111156110d2576110d26135bb565b6040519080825280602002602001820160405280156110fb578160200160208202803683370190505b50905060005b82518110156111575782818151811061111c5761111c613c28565b602002602001015182828151811061113657611136613c28565b67ffffffffffffffff90921660209283029190910190910152600101611101565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261061990611f64565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611270575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112a9576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161096d565b6112b4838383612016565b505050565b6112c1611a22565b60005b818110156112b45760008383838181106112e0576112e0613c28565b90506020028101906112f29190613c57565b6112fb90613c95565b90506113108160800151826020015115612100565b6113238160a00151826020015115612100565b80602001511561161f5780516113459060059067ffffffffffffffff16612239565b61138a5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161096d565b604081015151158061139f5750606081015151155b156113d6576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115b79082613d49565b50606082015160058201906115cc9082613d49565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116129493929190613e63565b60405180910390a1611736565b80516116379060059067ffffffffffffffff16612245565b61167c5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161096d565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116e56004830182613143565b6116f3600583016000613143565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112c4565b611747611a22565b61175081612251565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146117e85760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161096d565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ba9190613b69565b156118f1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118fe8160200151612346565b600061190d826020015161061f565b9050805160001480611931575080805190602001208260a001518051906020012014155b1561196e578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161096d9190613279565b6119808260200151836060015161246c565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad6946119ed9490939291600401613efc565b600060405180830381600087803b158015611a0757600080fd5b505af1158015611a1b573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161096d565b565b7f0000000000000000000000000000000000000000000000000000000000000000611afc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611b92576000838281518110611b1c57611b1c613c28565b60200260200101519050611b3a8160026124b390919063ffffffff16565b15611b895760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611aff565b5060005b81518110156112b4576000828281518110611bb357611bb3613c28565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bf75750611c53565b611c026002826124d5565b15611c515760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611b96565b60008181526001830160205260408120541515610ca4565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611d085760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161096d565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611db6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dda9190613b69565b15611e11576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e1e81604001516124f7565b611e2b8160200151612576565b611750816020015182606001516126c4565b6009546060820151611e8a9173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690612708565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611ef294939291600401613f5d565b6000604051808303816000875af1158015611f11573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119809190810190613fbd565b60606000610ca483612795565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611ff282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611fd6919061405a565b85608001516fffffffffffffffffffffffffffffffff166127f0565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61201f83610cab565b612061576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161096d565b61206c826000612100565b67ffffffffffffffff8316600090815260076020526040902061208f908361281a565b61209a816000612100565b67ffffffffffffffff831660009081526007602052604090206120c0906002018261281a565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516120f39392919061406d565b60405180910390a1505050565b8151156121c75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612156575060408201516fffffffffffffffffffffffffffffffff16155b1561218f57816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161096d91906140f0565b8015611980576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612200575060208201516fffffffffffffffffffffffffffffffff1615155b1561198057816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161096d91906140f0565b6000610ca483836129bc565b6000610ca48383612a0b565b3373ffffffffffffffffffffffffffffffffffffffff8216036122d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161096d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61234f81610cab565b612391576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161096d565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124349190613b69565b611750576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161096d565b67ffffffffffffffff8216600090815260076020526040902061198090600201827f0000000000000000000000000000000000000000000000000000000000000000612afe565b6000610ca48373ffffffffffffffffffffffffffffffffffffffff8416612a0b565b6000610ca48373ffffffffffffffffffffffffffffffffffffffff84166129bc565b7f00000000000000000000000000000000000000000000000000000000000000001561175057612528600282612e81565b611750576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161096d565b61257f81610cab565b6125c1576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161096d565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561263a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061265e919061412c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611750576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161096d565b67ffffffffffffffff8216600090815260076020526040902061198090827f0000000000000000000000000000000000000000000000000000000000000000612afe565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526112b4908490612eb0565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106c357602002820191906000526020600020905b8154815260200190600101908083116127d15750505050509050919050565b600061280f856128008486614149565b61280a9087614160565b612fbc565b90505b949350505050565b815460009061284390700100000000000000000000000000000000900463ffffffff164261405a565b905080156128e5576001830154835461288b916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166127f0565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461290b916fffffffffffffffffffffffffffffffff9081169116612fbc565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906120f39084906140f0565b6000818152600183016020526040812054612a0357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610619565b506000610619565b60008181526001830160205260408120548015612af4576000612a2f60018361405a565b8554909150600090612a439060019061405a565b9050818114612aa8576000866000018281548110612a6357612a63613c28565b9060005260206000200154905080876000018481548110612a8657612a86613c28565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ab957612ab9614173565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610619565b6000915050610619565b825474010000000000000000000000000000000000000000900460ff161580612b25575081155b15612b2f57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612b7590700100000000000000000000000000000000900463ffffffff164261405a565b90508015612c355781831115612bb7576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612bf19083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166127f0565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612cec5773ffffffffffffffffffffffffffffffffffffffff8416612c94576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161096d565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161096d565b84831015612dff5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612d30908261405a565b612d3a878a61405a565b612d449190614160565b612d4e91906141a2565b905073ffffffffffffffffffffffffffffffffffffffff8616612da7576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161096d565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161096d565b612e09858461405a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610ca4565b6000612f12826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612fd29092919063ffffffff16565b8051909150156112b45780806020019051810190612f309190613b69565b6112b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161096d565b6000818310612fcb5781610ca4565b5090919050565b60606128128484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161300691906141dd565b60006040518083038185875af1925050503d8060008114613043576040519150601f19603f3d011682016040523d82523d6000602084013e613048565b606091505b509150915061305987838387613064565b979650505050505050565b606083156130fa5782516000036130f35773ffffffffffffffffffffffffffffffffffffffff85163b6130f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161096d565b5081612812565b612812838381511561310f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096d9190613279565b50805461314f906137b7565b6000825580601f1061315f575050565b601f01602090049060005260206000209081019061175091905b8082111561318d5760008155600101613179565b5090565b6000602082840312156131a357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ca457600080fd5b803567ffffffffffffffff811681146131eb57600080fd5b919050565b60006020828403121561320257600080fd5b610ca4826131d3565b60005b8381101561322657818101518382015260200161320e565b50506000910152565b6000815180845261324781602086016020860161320b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ca4602083018461322f565b73ffffffffffffffffffffffffffffffffffffffff8116811461175057600080fd5b80356131eb8161328c565b6000602082840312156132cb57600080fd5b8135610ca48161328c565b6000602082840312156132e857600080fd5b813567ffffffffffffffff8111156132ff57600080fd5b82016101008185031215610ca457600080fd5b60008083601f84011261332457600080fd5b50813567ffffffffffffffff81111561333c57600080fd5b6020830191508360208260051b850101111561335757600080fd5b9250929050565b6000806000806040858703121561337457600080fd5b843567ffffffffffffffff8082111561338c57600080fd5b61339888838901613312565b909650945060208701359150808211156133b157600080fd5b506133be87828801613312565b95989497509550505050565b6000806000604084860312156133df57600080fd5b6133e8846131d3565b9250602084013567ffffffffffffffff8082111561340557600080fd5b818601915086601f83011261341957600080fd5b81358181111561342857600080fd5b87602082850101111561343a57600080fd5b6020830194508093505050509250925092565b6000806040838503121561346057600080fd5b613469836131d3565b915060208301356134798161328c565b809150509250929050565b60006020828403121561349657600080fd5b813567ffffffffffffffff8111156134ad57600080fd5b820160a08185031215610ca457600080fd5b6020815260008251604060208401526134db606084018261322f565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613516828261322f565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561356d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161353b565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561356d57835167ffffffffffffffff1683529284019291840191600101613595565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561360e5761360e6135bb565b60405290565b60405160c0810167ffffffffffffffff8111828210171561360e5761360e6135bb565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561367e5761367e6135bb565b604052919050565b801515811461175057600080fd5b80356131eb81613686565b80356fffffffffffffffffffffffffffffffff811681146131eb57600080fd5b6000606082840312156136d157600080fd5b6040516060810181811067ffffffffffffffff821117156136f4576136f46135bb565b604052905080823561370581613686565b81526137136020840161369f565b60208201526137246040840161369f565b60408201525092915050565b600080600060e0848603121561374557600080fd5b61374e846131d3565b925061375d85602086016136bf565b915061376c85608086016136bf565b90509250925092565b6000806020838503121561378857600080fd5b823567ffffffffffffffff81111561379f57600080fd5b6137ab85828601613312565b90969095509350505050565b600181811c908216806137cb57607f821691505b602082108103613804577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff821115613824576138246135bb565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261386157600080fd5b813561387461386f8261380a565b613637565b81815284602083860101111561388957600080fd5b816020850160208301376000918101602001919091529392505050565b600061010082360312156138b957600080fd5b6138c16135ea565b823567ffffffffffffffff808211156138d957600080fd5b6138e536838701613850565b83526138f3602086016131d3565b6020840152613904604086016132ae565b60408401526060850135606084015261391f608086016132ae565b608084015260a085013591508082111561393857600080fd5b61394436838701613850565b60a084015260c085013591508082111561395d57600080fd5b61396936838701613850565b60c084015260e085013591508082111561398257600080fd5b5061398f36828601613850565b60e08301525092915050565b601f8211156112b4576000816000526020600020601f850160051c810160208610156139c45750805b601f850160051c820191505b818110156139e3578281556001016139d0565b505050505050565b67ffffffffffffffff831115613a0357613a036135bb565b613a1783613a1183546137b7565b8361399b565b6000601f841160018114613a695760008515613a335750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a1b565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613ab85786850135825560209485019460019092019101613a98565b5086821015613af3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613b18604083018661322f565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613b7b57600080fd5b8151610ca481613686565b600060a08236031215613b9857600080fd5b60405160a0810167ffffffffffffffff8282108183111715613bbc57613bbc6135bb565b816040528435915080821115613bd157600080fd5b50613bde36828601613850565b825250613bed602084016131d3565b60208201526040830135613c008161328c565b6040820152606083810135908201526080830135613c1d8161328c565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613c8b57600080fd5b9190910192915050565b60006101408236031215613ca857600080fd5b613cb0613614565b613cb9836131d3565b8152613cc760208401613694565b6020820152604083013567ffffffffffffffff80821115613ce757600080fd5b613cf336838701613850565b60408401526060850135915080821115613d0c57600080fd5b50613d1936828601613850565b606083015250613d2c36608085016136bf565b6080820152613d3e3660e085016136bf565b60a082015292915050565b815167ffffffffffffffff811115613d6357613d636135bb565b613d7781613d7184546137b7565b8461399b565b602080601f831160018114613dca5760008415613d945750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139e3565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e1757888601518255948401946001909101908401613df8565b5085821015613e5357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613e878184018761322f565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613ec59050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613516565b60a081526000613f0f60a083018761322f565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613f8c60a083018661322f565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613fcf57600080fd5b815167ffffffffffffffff811115613fe657600080fd5b8201601f81018413613ff757600080fd5b805161400561386f8261380a565b81815285602083850101111561401a57600080fd5b61351682602083016020860161320b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106195761061961402b565b67ffffffffffffffff8416815260e081016140b960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612812565b6060810161061982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561413e57600080fd5b8151610ca48161328c565b80820281158282048414176106195761061961402b565b808201808211156106195761061961402b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826141d8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613c8b81846020870161320b56fe4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", } var BurnMintTokenPoolAndProxyABI = BurnMintTokenPoolAndProxyMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go index dc1e17729b..0ee344adbd 100644 --- a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnWithFromMintTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620045ac380380620045ac8339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c051613a2c62000b80600039600081816104a9015281816117ee01526121d20152600081816104830152818161161f0152611aa40152600081816102050152818161025a015281816106e9015281816107900152818161153f015281816119c401528181611bbc0152818161216801526123bd0152613a2c6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc1461046e578063dc0bd97114610481578063e0351e13146104a7578063f2fde38b146104cd57600080fd5b8063c4bffe2b14610433578063c75eea9c14610448578063cf7401f31461045b57600080fd5b8063b0f479a1116100c8578063b0f479a1146103ef578063b79465801461040d578063c0d786551461042057600080fd5b80639a4575b91461034b578063a7cd63b71461036b578063af58d59f1461038057600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146102ff5780637d54534e146103075780638926f54f1461031a5780638da5cb5b1461032d57600080fd5b806354c8a4f3146102b95780636d3d1a58146102ce57806378a010b2146102ec57600080fd5b806321df0da71161018c57806321df0da714610203578063240028e81461024a578063390775371461029757600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612b60565b6104e0565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612bbf565b6105c5565b6040516101d29190612c3e565b6101ee610675565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c6610258366004612c7e565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102aa6102a5366004612c9b565b610691565b604051905181526020016101d2565b6102cc6102c7366004612d23565b6108a6565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610225565b6102cc6102fa366004612d8f565b610921565b6102cc610a95565b6102cc610315366004612c7e565b610b92565b6101c6610328366004612bbf565b610be1565b60005473ffffffffffffffffffffffffffffffffffffffff16610225565b61035e610359366004612e12565b610bf8565b6040516101d29190612e4d565b610373610c9f565b6040516101d29190612ead565b61039361038e366004612bbf565b610cb0565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610225565b6101ee61041b366004612bbf565b610d85565b6102cc61042e366004612c7e565b610db0565b61043b610e8b565b6040516101d29190612f07565b610393610456366004612bbf565b610f43565b6102cc61046936600461306f565b611015565b6102cc61047c3660046130b4565b61109e565b7f0000000000000000000000000000000000000000000000000000000000000000610225565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b6102cc6104db366004612c7e565b611524565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061057357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105bf57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906105f0906130f6565b80601f016020809104026020016040519081016040528092919081815260200182805461061c906130f6565b80156106695780601f1061063e57610100808354040283529160200191610669565b820191906000526020600020905b81548152906001019060200180831161064c57829003601f168201915b50505050509050919050565b6040518060600160405280602381526020016139fd6023913981565b6040805160208101909152600081526106b16106ac836131f4565b611538565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152306004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990604401600060405180830381600087803b15801561074257600080fd5b505af1158015610756573d6000803e3d6000fd5b50506040517f095ea7b3000000000000000000000000000000000000000000000000000000008152336004820152606085013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16925063095ea7b391506044016020604051808303816000875af11580156107f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081491906132e9565b506108256060830160408401612c7e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161088791815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108ae611769565b61091b848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920191909152506117ec92505050565b50505050565b610929611769565b61093283610be1565b610979576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109a0906130f6565b80601f01602080910402602001604051908101604052809291908181526020018280546109cc906130f6565b8015610a195780601f106109ee57610100808354040283529160200191610a19565b820191906000526020600020905b8154815290600101906020018083116109fc57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a48838583613356565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a8793929190613470565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610970565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b9a611769565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105bf600567ffffffffffffffff84166119a2565b6040805180820190915260608082526020820152610c1d610c18836134d4565b6119bd565b610c2a8260600135611b87565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c8484602001602081019061041b9190612bbf565b81526040805160208181019092526000815291015292915050565b6060610cab6002611c30565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105bf90611c3d565b67ffffffffffffffff811660009081526007602052604090206005018054606091906105f0906130f6565b610db8611769565b73ffffffffffffffffffffffffffffffffffffffff8116610e05576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e996005611c30565b90506000815167ffffffffffffffff811115610eb757610eb7612f49565b604051908082528060200260200182016040528015610ee0578160200160208202803683370190505b50905060005b8251811015610f3c57828181518110610f0157610f01613576565b6020026020010151828281518110610f1b57610f1b613576565b67ffffffffffffffff90921660209283029190910190910152600101610ee6565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105bf90611c3d565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611055575060005473ffffffffffffffffffffffffffffffffffffffff163314155b1561108e576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610970565b611099838383611cef565b505050565b6110a6611769565b60005b818110156110995760008383838181106110c5576110c5613576565b90506020028101906110d791906135a5565b6110e0906135e3565b90506110f58160800151826020015115611dd9565b6111088160a00151826020015115611dd9565b80602001511561140457805161112a9060059067ffffffffffffffff16611f12565b61116f5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610970565b60408101515115806111845750606081015151155b156111bb576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061139c9082613697565b50606082015160058201906113b19082613697565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506113f794939291906137b1565b60405180910390a161151b565b805161141c9060059067ffffffffffffffff16611f1e565b6114615780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610970565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114ca6004830182612b12565b6114d8600583016000612b12565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016110a9565b61152c611769565b61153581611f2a565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115cd5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610970565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169f91906132e9565b156116d6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116e3816020015161201f565b60006116f282602001516105c5565b9050805160001480611716575080805190602001208260a001518051906020012014155b15611753578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109709190612c3e565b61176582602001518360600151612145565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146117ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610970565b565b7f0000000000000000000000000000000000000000000000000000000000000000611843576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118d957600083828151811061186357611863613576565b6020026020010151905061188181600261218c90919063ffffffff16565b156118d05760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611846565b5060005b81518110156110995760008282815181106118fa576118fa613576565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361193e575061199a565b6119496002826121ae565b156119985760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016118dd565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611a525760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610970565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2491906132e9565b15611b5b576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b6881604001516121d0565b611b75816020015161224f565b6115358160200151826060015161239d565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b158015611c1557600080fd5b505af1158015611c29573d6000803e3d6000fd5b5050505050565b606060006119b6836123e1565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611ccb82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611caf9190613879565b85608001516fffffffffffffffffffffffffffffffff1661243c565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611cf883610be1565b611d3a576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610970565b611d45826000611dd9565b67ffffffffffffffff83166000908152600760205260409020611d689083612466565b611d73816000611dd9565b67ffffffffffffffff83166000908152600760205260409020611d999060020182612466565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611dcc9392919061388c565b60405180910390a1505050565b815115611ea05781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611e2f575060408201516fffffffffffffffffffffffffffffffff16155b15611e6857816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610970919061390f565b8015611765576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611ed9575060208201516fffffffffffffffffffffffffffffffff1615155b1561176557816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610970919061390f565b60006119b68383612608565b60006119b68383612657565b3373ffffffffffffffffffffffffffffffffffffffff821603611fa9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610970565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61202881610be1565b61206a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610970565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156120e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210d91906132e9565b611535576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610970565b67ffffffffffffffff8216600090815260076020526040902061176590600201827f000000000000000000000000000000000000000000000000000000000000000061274a565b60006119b68373ffffffffffffffffffffffffffffffffffffffff8416612657565b60006119b68373ffffffffffffffffffffffffffffffffffffffff8416612608565b7f00000000000000000000000000000000000000000000000000000000000000001561153557612201600282612acd565b611535576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610970565b61225881610be1565b61229a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610970565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612313573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612337919061394b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611535576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610970565b67ffffffffffffffff8216600090815260076020526040902061176590827f000000000000000000000000000000000000000000000000000000000000000061274a565b60608160000180548060200260200160405190810160405280929190818152602001828054801561066957602002820191906000526020600020905b81548152602001906001019080831161241d5750505050509050919050565b600061245b8561244c8486613968565b612456908761397f565b612afc565b90505b949350505050565b815460009061248f90700100000000000000000000000000000000900463ffffffff1642613879565b9050801561253157600183015483546124d7916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661243c565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612557916fffffffffffffffffffffffffffffffff9081169116612afc565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611dcc90849061390f565b600081815260018301602052604081205461264f575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105bf565b5060006105bf565b6000818152600183016020526040812054801561274057600061267b600183613879565b855490915060009061268f90600190613879565b90508181146126f45760008660000182815481106126af576126af613576565b90600052602060002001549050808760000184815481106126d2576126d2613576565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061270557612705613992565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105bf565b60009150506105bf565b825474010000000000000000000000000000000000000000900460ff161580612771575081155b1561277b57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906127c190700100000000000000000000000000000000900463ffffffff1642613879565b905080156128815781831115612803576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461283d9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661243c565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156129385773ffffffffffffffffffffffffffffffffffffffff84166128e0576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610970565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610970565b84831015612a4b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061297c9082613879565b612986878a613879565b612990919061397f565b61299a91906139c1565b905073ffffffffffffffffffffffffffffffffffffffff86166129f3576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610970565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610970565b612a558584613879565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156119b6565b6000818310612b0b57816119b6565b5090919050565b508054612b1e906130f6565b6000825580601f10612b2e575050565b601f01602090049060005260206000209081019061153591905b80821115612b5c5760008155600101612b48565b5090565b600060208284031215612b7257600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146119b657600080fd5b803567ffffffffffffffff81168114612bba57600080fd5b919050565b600060208284031215612bd157600080fd5b6119b682612ba2565b6000815180845260005b81811015612c0057602081850181015186830182015201612be4565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119b66020830184612bda565b73ffffffffffffffffffffffffffffffffffffffff8116811461153557600080fd5b8035612bba81612c51565b600060208284031215612c9057600080fd5b81356119b681612c51565b600060208284031215612cad57600080fd5b813567ffffffffffffffff811115612cc457600080fd5b820161010081850312156119b657600080fd5b60008083601f840112612ce957600080fd5b50813567ffffffffffffffff811115612d0157600080fd5b6020830191508360208260051b8501011115612d1c57600080fd5b9250929050565b60008060008060408587031215612d3957600080fd5b843567ffffffffffffffff80821115612d5157600080fd5b612d5d88838901612cd7565b90965094506020870135915080821115612d7657600080fd5b50612d8387828801612cd7565b95989497509550505050565b600080600060408486031215612da457600080fd5b612dad84612ba2565b9250602084013567ffffffffffffffff80821115612dca57600080fd5b818601915086601f830112612dde57600080fd5b813581811115612ded57600080fd5b876020828501011115612dff57600080fd5b6020830194508093505050509250925092565b600060208284031215612e2457600080fd5b813567ffffffffffffffff811115612e3b57600080fd5b820160a081850312156119b657600080fd5b602081526000825160406020840152612e696060840182612bda565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612ea48282612bda565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612efb57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612ec9565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612efb57835167ffffffffffffffff1683529284019291840191600101612f23565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f9c57612f9c612f49565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f9c57612f9c612f49565b801515811461153557600080fd5b8035612bba81612fc5565b80356fffffffffffffffffffffffffffffffff81168114612bba57600080fd5b60006060828403121561301057600080fd5b6040516060810181811067ffffffffffffffff8211171561303357613033612f49565b604052905080823561304481612fc5565b815261305260208401612fde565b602082015261306360408401612fde565b60408201525092915050565b600080600060e0848603121561308457600080fd5b61308d84612ba2565b925061309c8560208601612ffe565b91506130ab8560808601612ffe565b90509250925092565b600080602083850312156130c757600080fd5b823567ffffffffffffffff8111156130de57600080fd5b6130ea85828601612cd7565b90969095509350505050565b600181811c9082168061310a57607f821691505b602082108103613143577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f83011261315a57600080fd5b813567ffffffffffffffff8082111561317557613175612f49565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156131bb576131bb612f49565b816040528381528660208588010111156131d457600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561320757600080fd5b61320f612f78565b823567ffffffffffffffff8082111561322757600080fd5b61323336838701613149565b835261324160208601612ba2565b602084015261325260408601612c73565b60408401526060850135606084015261326d60808601612c73565b608084015260a085013591508082111561328657600080fd5b61329236838701613149565b60a084015260c08501359150808211156132ab57600080fd5b6132b736838701613149565b60c084015260e08501359150808211156132d057600080fd5b506132dd36828601613149565b60e08301525092915050565b6000602082840312156132fb57600080fd5b81516119b681612fc5565b601f821115611099576000816000526020600020601f850160051c8101602086101561332f5750805b601f850160051c820191505b8181101561334e5782815560010161333b565b505050505050565b67ffffffffffffffff83111561336e5761336e612f49565b6133828361337c83546130f6565b83613306565b6000601f8411600181146133d4576000851561339e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611c29565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156134235786850135825560209485019460019092019101613403565b508682101561345e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006134836040830186612bda565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a082360312156134e657600080fd5b60405160a0810167ffffffffffffffff828210818311171561350a5761350a612f49565b81604052843591508082111561351f57600080fd5b5061352c36828601613149565b82525061353b60208401612ba2565b6020820152604083013561354e81612c51565b604082015260608381013590820152608083013561356b81612c51565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126135d957600080fd5b9190910192915050565b600061014082360312156135f657600080fd5b6135fe612fa2565b61360783612ba2565b815261361560208401612fd3565b6020820152604083013567ffffffffffffffff8082111561363557600080fd5b61364136838701613149565b6040840152606085013591508082111561365a57600080fd5b5061366736828601613149565b60608301525061367a3660808501612ffe565b608082015261368c3660e08501612ffe565b60a082015292915050565b815167ffffffffffffffff8111156136b1576136b1612f49565b6136c5816136bf84546130f6565b84613306565b602080601f83116001811461371857600084156136e25750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561334e565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561376557888601518255948401946001909101908401613746565b50858210156137a157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526137d581840187612bda565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506138139050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612ea4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105bf576105bf61384a565b67ffffffffffffffff8416815260e081016138d860208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261245e565b606081016105bf82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561395d57600080fd5b81516119b681612c51565b80820281158282048414176105bf576105bf61384a565b808201808211156105bf576105bf61384a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826139f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fe4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e302d646576a164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b5060405162004516380380620045168339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161399d62000b79600039600081816104a90152818161175f0152612143015260008181610483015281816115900152611a150152600081816102050152818161025a015281816106c8015281816114b00152818161193501528181611b2d015281816120d9015261232e015261399d6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc1461046e578063dc0bd97114610481578063e0351e13146104a7578063f2fde38b146104cd57600080fd5b8063c4bffe2b14610433578063c75eea9c14610448578063cf7401f31461045b57600080fd5b8063b0f479a1116100c8578063b0f479a1146103ef578063b79465801461040d578063c0d786551461042057600080fd5b80639a4575b91461034b578063a7cd63b71461036b578063af58d59f1461038057600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146102ff5780637d54534e146103075780638926f54f1461031a5780638da5cb5b1461032d57600080fd5b806354c8a4f3146102b95780636d3d1a58146102ce57806378a010b2146102ec57600080fd5b806321df0da71161018c57806321df0da714610203578063240028e81461024a578063390775371461029757600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ad1565b6104e0565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b30565b6105c5565b6040516101d29190612baf565b6101ee610675565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c6610258366004612bef565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102aa6102a5366004612c0c565b610691565b604051905181526020016101d2565b6102cc6102c7366004612c94565b610817565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610225565b6102cc6102fa366004612d00565b610892565b6102cc610a06565b6102cc610315366004612bef565b610b03565b6101c6610328366004612b30565b610b52565b60005473ffffffffffffffffffffffffffffffffffffffff16610225565b61035e610359366004612d83565b610b69565b6040516101d29190612dbe565b610373610c10565b6040516101d29190612e1e565b61039361038e366004612b30565b610c21565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610225565b6101ee61041b366004612b30565b610cf6565b6102cc61042e366004612bef565b610d21565b61043b610dfc565b6040516101d29190612e78565b610393610456366004612b30565b610eb4565b6102cc610469366004612fe0565b610f86565b6102cc61047c366004613025565b61100f565b7f0000000000000000000000000000000000000000000000000000000000000000610225565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b6102cc6104db366004612bef565b611495565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061057357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105bf57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906105f090613067565b80601f016020809104026020016040519081016040528092919081815260200182805461061c90613067565b80156106695780601f1061063e57610100808354040283529160200191610669565b820191906000526020600020905b81548152906001019060200180831161064c57829003601f168201915b50505050509050919050565b60405180606001604052806023815260200161396e6023913981565b6040805160208101909152600081526106b16106ac83613165565b6114a9565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196106fd6060850160408601612bef565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561076d57600080fd5b505af1158015610781573d6000803e3d6000fd5b50610796925050506060830160408401612bef565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f084606001356040516107f891815260200190565b60405180910390a3506040805160208101909152606090910135815290565b61081f6116da565b61088c8484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061175d92505050565b50505050565b61089a6116da565b6108a383610b52565b6108ea576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461091190613067565b80601f016020809104026020016040519081016040528092919081815260200182805461093d90613067565b801561098a5780601f1061095f5761010080835404028352916020019161098a565b820191906000526020600020905b81548152906001019060200180831161096d57829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109b98385836132aa565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf8285856040516109f8939291906133c4565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a87576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108e1565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b0b6116da565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105bf600567ffffffffffffffff8416611913565b6040805180820190915260608082526020820152610b8e610b8983613428565b61192e565b610b9b8260600135611af8565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610bf584602001602081019061041b9190612b30565b81526040805160208181019092526000815291015292915050565b6060610c1c6002611ba1565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105bf90611bae565b67ffffffffffffffff811660009081526007602052604090206005018054606091906105f090613067565b610d296116da565b73ffffffffffffffffffffffffffffffffffffffff8116610d76576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e0a6005611ba1565b90506000815167ffffffffffffffff811115610e2857610e28612eba565b604051908082528060200260200182016040528015610e51578160200160208202803683370190505b50905060005b8251811015610ead57828181518110610e7257610e726134ca565b6020026020010151828281518110610e8c57610e8c6134ca565b67ffffffffffffffff90921660209283029190910190910152600101610e57565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105bf90611bae565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fc6575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610fff576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108e1565b61100a838383611c60565b505050565b6110176116da565b60005b8181101561100a576000838383818110611036576110366134ca565b905060200281019061104891906134f9565b61105190613537565b90506110668160800151826020015115611d4a565b6110798160a00151826020015115611d4a565b80602001511561137557805161109b9060059067ffffffffffffffff16611e83565b6110e05780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108e1565b60408101515115806110f55750606081015151155b1561112c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061130d90826135eb565b506060820151600582019061132290826135eb565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506113689493929190613705565b60405180910390a161148c565b805161138d9060059067ffffffffffffffff16611e8f565b6113d25780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108e1565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600182018390556002820180549091169055600381018290559061143b6004830182612a83565b611449600583016000612a83565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161101a565b61149d6116da565b6114a681611e9b565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461153e5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108e1565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156115ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611610919061379e565b15611647576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116548160200151611f90565b600061166382602001516105c5565b9050805160001480611687575080805190602001208260a001518051906020012014155b156116c4578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108e19190612baf565b6116d6826020015183606001516120b6565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461175b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108e1565b565b7f00000000000000000000000000000000000000000000000000000000000000006117b4576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561184a5760008382815181106117d4576117d46134ca565b602002602001015190506117f28160026120fd90919063ffffffff16565b156118415760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117b7565b5060005b815181101561100a57600082828151811061186b5761186b6134ca565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118af575061190b565b6118ba60028261211f565b156119095760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161184e565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119c35760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108e1565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a95919061379e565b15611acc576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ad98160400151612141565b611ae681602001516121c0565b6114a68160200151826060015161230e565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b158015611b8657600080fd5b505af1158015611b9a573d6000803e3d6000fd5b5050505050565b6060600061192783612352565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c3c82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c2091906137ea565b85608001516fffffffffffffffffffffffffffffffff166123ad565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c6983610b52565b611cab576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108e1565b611cb6826000611d4a565b67ffffffffffffffff83166000908152600760205260409020611cd990836123d7565b611ce4816000611d4a565b67ffffffffffffffff83166000908152600760205260409020611d0a90600201826123d7565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d3d939291906137fd565b60405180910390a1505050565b815115611e115781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611da0575060408201516fffffffffffffffffffffffffffffffff16155b15611dd957816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108e19190613880565b80156116d6576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e4a575060208201516fffffffffffffffffffffffffffffffff1615155b156116d657816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108e19190613880565b60006119278383612579565b600061192783836125c8565b3373ffffffffffffffffffffffffffffffffffffffff821603611f1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108e1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611f9981610b52565b611fdb576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108e1565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561205a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207e919061379e565b6114a6576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108e1565b67ffffffffffffffff821660009081526007602052604090206116d690600201827f00000000000000000000000000000000000000000000000000000000000000006126bb565b60006119278373ffffffffffffffffffffffffffffffffffffffff84166125c8565b60006119278373ffffffffffffffffffffffffffffffffffffffff8416612579565b7f0000000000000000000000000000000000000000000000000000000000000000156114a657612172600282612a3e565b6114a6576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108e1565b6121c981610b52565b61220b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108e1565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a891906138bc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114a6576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108e1565b67ffffffffffffffff821660009081526007602052604090206116d690827f00000000000000000000000000000000000000000000000000000000000000006126bb565b60608160000180548060200260200160405190810160405280929190818152602001828054801561066957602002820191906000526020600020905b81548152602001906001019080831161238e5750505050509050919050565b60006123cc856123bd84866138d9565b6123c790876138f0565b612a6d565b90505b949350505050565b815460009061240090700100000000000000000000000000000000900463ffffffff16426137ea565b905080156124a25760018301548354612448916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123ad565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124c8916fffffffffffffffffffffffffffffffff9081169116612a6d565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d3d908490613880565b60008181526001830160205260408120546125c0575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105bf565b5060006105bf565b600081815260018301602052604081205480156126b15760006125ec6001836137ea565b8554909150600090612600906001906137ea565b9050818114612665576000866000018281548110612620576126206134ca565b9060005260206000200154905080876000018481548110612643576126436134ca565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061267657612676613903565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105bf565b60009150506105bf565b825474010000000000000000000000000000000000000000900460ff1615806126e2575081155b156126ec57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061273290700100000000000000000000000000000000900463ffffffff16426137ea565b905080156127f25781831115612774576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127ae9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123ad565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128a95773ffffffffffffffffffffffffffffffffffffffff8416612851576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108e1565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108e1565b848310156129bc5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128ed90826137ea565b6128f7878a6137ea565b61290191906138f0565b61290b9190613932565b905073ffffffffffffffffffffffffffffffffffffffff8616612964576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108e1565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108e1565b6129c685846137ea565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611927565b6000818310612a7c5781611927565b5090919050565b508054612a8f90613067565b6000825580601f10612a9f575050565b601f0160209004906000526020600020908101906114a691905b80821115612acd5760008155600101612ab9565b5090565b600060208284031215612ae357600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461192757600080fd5b803567ffffffffffffffff81168114612b2b57600080fd5b919050565b600060208284031215612b4257600080fd5b61192782612b13565b6000815180845260005b81811015612b7157602081850181015186830182015201612b55565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119276020830184612b4b565b73ffffffffffffffffffffffffffffffffffffffff811681146114a657600080fd5b8035612b2b81612bc2565b600060208284031215612c0157600080fd5b813561192781612bc2565b600060208284031215612c1e57600080fd5b813567ffffffffffffffff811115612c3557600080fd5b8201610100818503121561192757600080fd5b60008083601f840112612c5a57600080fd5b50813567ffffffffffffffff811115612c7257600080fd5b6020830191508360208260051b8501011115612c8d57600080fd5b9250929050565b60008060008060408587031215612caa57600080fd5b843567ffffffffffffffff80821115612cc257600080fd5b612cce88838901612c48565b90965094506020870135915080821115612ce757600080fd5b50612cf487828801612c48565b95989497509550505050565b600080600060408486031215612d1557600080fd5b612d1e84612b13565b9250602084013567ffffffffffffffff80821115612d3b57600080fd5b818601915086601f830112612d4f57600080fd5b813581811115612d5e57600080fd5b876020828501011115612d7057600080fd5b6020830194508093505050509250925092565b600060208284031215612d9557600080fd5b813567ffffffffffffffff811115612dac57600080fd5b820160a0818503121561192757600080fd5b602081526000825160406020840152612dda6060840182612b4b565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e158282612b4b565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e6c57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e3a565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e6c57835167ffffffffffffffff1683529284019291840191600101612e94565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f0d57612f0d612eba565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f0d57612f0d612eba565b80151581146114a657600080fd5b8035612b2b81612f36565b80356fffffffffffffffffffffffffffffffff81168114612b2b57600080fd5b600060608284031215612f8157600080fd5b6040516060810181811067ffffffffffffffff82111715612fa457612fa4612eba565b6040529050808235612fb581612f36565b8152612fc360208401612f4f565b6020820152612fd460408401612f4f565b60408201525092915050565b600080600060e08486031215612ff557600080fd5b612ffe84612b13565b925061300d8560208601612f6f565b915061301c8560808601612f6f565b90509250925092565b6000806020838503121561303857600080fd5b823567ffffffffffffffff81111561304f57600080fd5b61305b85828601612c48565b90969095509350505050565b600181811c9082168061307b57607f821691505b6020821081036130b4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130cb57600080fd5b813567ffffffffffffffff808211156130e6576130e6612eba565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561312c5761312c612eba565b8160405283815286602085880101111561314557600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561317857600080fd5b613180612ee9565b823567ffffffffffffffff8082111561319857600080fd5b6131a4368387016130ba565b83526131b260208601612b13565b60208401526131c360408601612be4565b6040840152606085013560608401526131de60808601612be4565b608084015260a08501359150808211156131f757600080fd5b613203368387016130ba565b60a084015260c085013591508082111561321c57600080fd5b613228368387016130ba565b60c084015260e085013591508082111561324157600080fd5b5061324e368286016130ba565b60e08301525092915050565b601f82111561100a576000816000526020600020601f850160051c810160208610156132835750805b601f850160051c820191505b818110156132a25782815560010161328f565b505050505050565b67ffffffffffffffff8311156132c2576132c2612eba565b6132d6836132d08354613067565b8361325a565b6000601f84116001811461332857600085156132f25750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611b9a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156133775786850135825560209485019460019092019101613357565b50868210156133b2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133d76040830186612b4b565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561343a57600080fd5b60405160a0810167ffffffffffffffff828210818311171561345e5761345e612eba565b81604052843591508082111561347357600080fd5b50613480368286016130ba565b82525061348f60208401612b13565b602082015260408301356134a281612bc2565b60408201526060838101359082015260808301356134bf81612bc2565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261352d57600080fd5b9190910192915050565b6000610140823603121561354a57600080fd5b613552612f13565b61355b83612b13565b815261356960208401612f44565b6020820152604083013567ffffffffffffffff8082111561358957600080fd5b613595368387016130ba565b604084015260608501359150808211156135ae57600080fd5b506135bb368286016130ba565b6060830152506135ce3660808501612f6f565b60808201526135e03660e08501612f6f565b60a082015292915050565b815167ffffffffffffffff81111561360557613605612eba565b613619816136138454613067565b8461325a565b602080601f83116001811461366c57600084156136365750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132a2565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136b95788860151825594840194600190910190840161369a565b50858210156136f557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261372981840187612b4b565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506137679050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e15565b6000602082840312156137b057600080fd5b815161192781612f36565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105bf576105bf6137bb565b67ffffffffffffffff8416815260e0810161384960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123cf565b606081016105bf82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138ce57600080fd5b815161192781612bc2565b80820281158282048414176105bf576105bf6137bb565b808201808211156105bf576105bf6137bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613968577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fe4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e302d646576a164736f6c6343000818000a", } var BurnWithFromMintTokenPoolABI = BurnWithFromMintTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go index b3416214fc..68c98e6adc 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go @@ -163,8 +163,8 @@ type MultiOCR3BaseOCRConfigArgs struct { } var EVM2EVMMultiOffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162006cd538038062006cd58339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615fff62000cd6600039600081816102530152612c5e0152600081816102240152612f750152600081816101f5015281816114c101526118d20152600081816101c50152612853015260008181611e600152611eac0152615fff6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b1461056e578063f716f99f14610581578063ff888fb11461059457600080fd5b8063d2a15d3514610528578063e9d68a8e1461053b578063ece670b61461055b57600080fd5b8063991a5018116100bd578063991a5018146104b0578063c673e584146104c3578063ccd37ba3146104e357600080fd5b806385572ffb146104875780638da5cb5b1461049557600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba50971461046c5780637d4eef601461047457600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a366004614122565b6105b7565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d19190614284565b61018f61033136600461432f565b6105cb565b61018f6103443660046143e2565b6109ab565b60095460405167ffffffffffffffff90911681526020016102d1565b610378610373366004614436565b610a14565b6040516102d19190614493565b61040f6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b830481166020850152600160c01b8304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610a6a565b61018f6104823660046149e6565b610b28565b61018f610177366004614b11565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104be366004614b60565b610cc8565b6104d66104d1366004614be5565b610cd9565b6040516102d19190614c45565b61051a6104f1366004614cba565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f610536366004614ce4565b610e37565b61054e610549366004614d59565b610ef1565b6040516102d19190614d74565b61018f610569366004614dc2565b610ffe565b61018f61057c366004614e27565b611418565b61018f61058f366004614eac565b611429565b6105a76105a2366004614fea565b61146b565b60405190151581526020016102d1565b6105bf61152c565b6105c881611588565b50565b60006105d987890189615173565b805151519091501515806105f257508051602001515115155b156106f25760095460208a01359067ffffffffffffffff808316911610156106b1576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261067a9291016153b1565b600060405180830381600087803b15801561069457600080fd5b505af11580156106a8573d6000803e3d6000fd5b505050506106f0565b8160200151516000036106f0576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156108f45760008260200151828151811061071a5761071a6152de565b6020026020010151905060008160000151905061073681611886565b600061074182611988565b602084015151815491925067ffffffffffffffff908116600160a81b90920416141580610785575060208084015190810151905167ffffffffffffffff9182169116115b156107ce57825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107c59291906004016153c4565b60405180910390fd5b60408301518061080a576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff1660009081526008602090815260408083208484529091529020541561087d5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016107c5565b602080850151015161089090600161540f565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff9283160217909255925116600090815260086020908152604080832094835293905291909120429055506001016106f5565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d816040516109249190615437565b60405180910390a16109a060008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b92506119ef915050565b505050505050505050565b6109eb6109ba828401846154d4565b60408051600080825260208201909252906109e5565b60608152602001906001900390816109d05790505b50611d66565b604080516000808252602082019092529050610a0e6001858585858660006119ef565b50505050565b6000610a2260016004615509565b6002610a2f608085615532565b67ffffffffffffffff16610a439190615559565b610a4d8585611e16565b901c166003811115610a6157610a61614469565b90505b92915050565b6001546001600160a01b03163314610ac45760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107c5565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b30611e5d565b815181518114610b6c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610cb8576000848281518110610b8b57610b8b6152de565b60200260200101519050600081602001515190506000858481518110610bb357610bb36152de565b6020026020010151905080518214610bf7576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610ca9576000828281518110610c1657610c166152de565b6020026020010151905080600014610ca05784602001518281518110610c3e57610c3e6152de565b602002602001015160800151811015610ca05784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016107c5565b50600101610bfa565b50505050806001019050610b6f565b50610cc38383611d66565b505050565b610cd061152c565b6105c881611ede565b610d1c6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610dc557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610da7575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e2757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e09575b5050505050815250509050919050565b610e3f61152c565b60005b81811015610cc3576000838383818110610e5e57610e5e6152de565b905060400201803603810190610e749190615570565b9050610e83816020015161146b565b610ee857805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e42565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191610f7e906155a9565b80601f0160208091040260200160405190810160405280929190818152602001828054610faa906155a9565b8015610e275780601f10610fcc57610100808354040283529160200191610e27565b820191906000526020600020905b815481529060010190602001808311610fda57505050919092525091949350505050565b333014611037576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611074565b604080518082019091526000808252602082015281526020019060019003908161104d5790505b50905060006110876101208601866155e3565b905011156110d8576110d56110a06101208601866155e3565b6110ad60a088018861562d565b6110be6101008a0160e08b01614e27565b6110ce60408b0160208c01614d59565b898961202f565b90505b6040805160a081018252853581526000916020808301916110fe91908901908901614d59565b67ffffffffffffffff16815260200161111a60a088018861562d565b60405160200161112b929190615674565b60408051601f19818403018152919052815260200161114d60c088018861562d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050908252506020018390526005549091506001600160a01b03168015611277576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a1906111e4908590600401615745565b600060405180830381600087803b1580156111fe57600080fd5b505af192505050801561120f575060015b611277573d80801561123d576040519150601f19603f3d011682016040523d82523d6000602084013e611242565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016107c59190614284565b61128460c087018761562d565b15905080156112965750610100860135155b806112b957506112ad610100870160e08801614e27565b6001600160a01b03163b155b8061130557506113037f85572ffb000000000000000000000000000000000000000000000000000000006112f4610100890160e08a01614e27565b6001600160a01b031690612123565b155b1561131257505050505050565b60008060068161132860408b0160208c01614d59565b67ffffffffffffffff1681526020810191909152604001600020546001600160a01b0316633cf97983856113886101008c0180359061136a9060e08f01614e27565b6040518563ffffffff1660e01b81526004016113899493929190615758565b6000604051808303816000875af11580156113a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113d09190810190615794565b50915091508161140e57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107c59190614284565b5050505050505050565b61142061152c565b6105c88161213f565b61143161152c565b60005b81518110156114675761145f828281518110611452576114526152de565b60200260200101516121f5565b600101611434565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611508573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a64919061582a565b6000546001600160a01b031633146115865760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107c5565b565b60005b81518110156114675760008282815181106115a8576115a86152de565b602002602001015190506000816020015190508067ffffffffffffffff166000036115ff576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611627576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff81166000908152600660205260408120600181018054919291611652906155a9565b80601f016020809104026020016040519081016040528092919081815260200182805461167e906155a9565b80156116cb5780601f106116a0576101008083540402835291602001916116cb565b820191906000526020600020905b8154815290600101906020018083116116ae57829003601f168201915b505050505090506000846060015190508151600003611783578051600003611706576040516342bcdf7f60e11b815260040160405180910390fd5b60018301611714828261588f565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16117d6565b80805190602001208280519060200120146117d6576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016107c5565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b9061186e90869061594f565b60405180910390a2505050505080600101905061158b565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611921573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611945919061582a565b156105c8576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107c5565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610a64576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107c5565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611a4e8760a4615a1d565b9050826060015115611a96578451611a67906020615559565b8651611a74906020615559565b611a7f9060a0615a1d565b611a899190615a1d565b611a939082615a1d565b90505b368114611ad8576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107c5565b5081518114611b205781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107c5565b611b28611e5d565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611b7657611b76614469565b6002811115611b8757611b87614469565b9052509050600281602001516002811115611ba457611ba4614469565b148015611bf85750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611be057611be06152de565b6000918252602090912001546001600160a01b031633145b611c2e576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611d10576020820151611c49906001615a30565b60ff16855114611c85576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611cc0576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611cd2929190615a49565b604051908190038120611ce9918b90602001615a59565b604051602081830303815290604052805190602001209050611d0e8a82888888612539565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611da0576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611e0f57611e07858281518110611dd557611dd56152de565b602002602001015184611e0157858381518110611df457611df46152de565b6020026020010151612746565b83612746565b600101611db7565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611e3b608085615a6d565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f000000000000000000000000000000000000000000000000000000000000000014611586576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107c5565b80516001600160a01b0316611f06576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60608767ffffffffffffffff81111561204a5761204a613f39565b60405190808252806020026020018201604052801561208f57816020015b60408051808201909152600080825260208201528152602001906001900390816120685790505b50905060005b88811015612116576120f18a8a838181106120b2576120b26152de565b90506020028101906120c49190615a94565b898989898989888181106120da576120da6152de565b90506020028101906120ec919061562d565b612ed7565b828281518110612103576121036152de565b6020908102919091010152600101612095565b5098975050505050505050565b600061212e836133da565b8015610a615750610a61838361343e565b336001600160a01b038216036121975760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107c5565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff16600003612220576000604051631b3fab5160e11b81526004016107c59190615ad2565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361228d57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff9092169190911790556122e2565b6060840151600182015460ff62010000909104161515901515146122e2576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016107c5565b60a08401518051601f60ff82161115612311576001604051631b3fab5160e11b81526004016107c59190615ad2565b612377858560030180548060200260200160405190810160405280929190818152602001828054801561236d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161234f575b50505050506134f8565b8560600151156124a6576123e5858560020180548060200260200160405190810160405280929190818152602001828054801561236d576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161234f5750505050506134f8565b608086015180516123ff9060028701906020840190613e93565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f101561245f576002604051631b3fab5160e11b81526004016107c59190615ad2565b604088015161246f906003615aec565b60ff168160ff1611612497576003604051631b3fab5160e11b81526004016107c59190615ad2565b6124a387836001613561565b50505b6124b285836002613561565b81516124c79060038601906020850190613e93565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f54793612520938a939260028b01929190615b08565b60405180910390a1612531856136e1565b505050505050565b612541613f05565b835160005b8181101561140e576000600188868460208110612565576125656152de565b61257291901a601b615a30565b898581518110612584576125846152de565b602002602001015189868151811061259e5761259e6152de565b6020026020010151604051600081526020016040526040516125dc949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156125fe573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561265f5761265f614469565b600281111561267057612670614469565b905250905060018160200151600281111561268d5761268d614469565b146126c4576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f81106126db576126db6152de565b602002015115612717576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f8110612732576127326152de565b911515602090920201525050600101612546565b815161275181611886565b600061275c82611988565b602085015151909150600081900361279f576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84604001515181146127dd576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156127f8576127f8613f39565b604051908082528060200260200182016040528015612821578160200160208202803683370190505b50905060005b8281101561299657600087602001518281518110612847576128476152de565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff16146128da57805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107c5565b612970818660010180546128ed906155a9565b80601f0160208091040260200160405190810160405280929190818152602001828054612919906155a9565b80156129665780601f1061293b57610100808354040283529160200191612966565b820191906000526020600020905b81548152906001019060200180831161294957829003601f168201915b50505050506136fd565b838381518110612982576129826152de565b602090810291909101015250600101612827565b5060006129ad858389606001518a6080015161381f565b9050806000036129f5576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107c5565b8551151560005b848110156109a057600089602001518281518110612a1c57612a1c6152de565b602002602001015190506000612a3a89836000015160600151610a14565b90506000816003811115612a5057612a50614469565b1480612a6d57506003816003811115612a6b57612a6b614469565b145b612ac4578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612ecf565b8315612b9457600454600090600160a01b900463ffffffff16612ae78742615509565b1190508080612b0757506003826003811115612b0557612b05614469565b145b612b49576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b1660048201526024016107c5565b8a8481518110612b5b57612b5b6152de565b6020026020010151600014612b8e578a8481518110612b7c57612b7c6152de565b60200260200101518360800181815250505b50612bf5565b6000816003811115612ba857612ba8614469565b14612bf5578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612ab5565b81516080015167ffffffffffffffff1615612ce3576000816003811115612c1e57612c1e614469565b03612ce35781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c95928e929190600401615bba565b6020604051808303816000875af1158015612cb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cd8919061582a565b612ce3575050612ecf565b60008b604001518481518110612cfb57612cfb6152de565b6020026020010151905080518360a001515114612d5f578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d16600483015290911660248201526044016107c5565b612d738a8460000151606001516001613875565b600080612d80858461391d565b91509150612d978c86600001516060015184613875565b8615612e07576003826003811115612db157612db1614469565b03612e07576000846003811115612dca57612dca614469565b14612e07578451516040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526107c591908390600401615be7565b6002826003811115612e1b57612e1b614469565b14612e75576003826003811115612e3457612e34614469565b14612e75578451606001516040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526107c5918e918590600401615c00565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612ec19087908790615c26565b60405180910390a450505050505b6001016129fc565b60408051808201909152600080825260208201526000612f37612efd60208b018b61562d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506139e792505050565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612fbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe09190615c46565b90506001600160a01b038116158061302857506130266001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612123565b155b1561306a576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016107c5565b6000806132476040518061010001604052808d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020018a67ffffffffffffffff1681526020018b6001600160a01b031681526020018e606001358152602001866001600160a01b031681526020018e806000019061310e919061562d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020018e8060400190613166919061562d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250604080516020601f8c018190048102820181019092528a815291810191908b908b908190840183828082843760009201919091525050509152506040516131e79190602401615c63565b60408051601f198184030181529190526020810180516001600160e01b03167f3907753700000000000000000000000000000000000000000000000000000000179052600454859063ffffffff600160e01b909104166113886084613a8d565b50915091508161328557806040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107c59190614284565b80516020146132cd5780516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107c5565b6000818060200190518101906132e39190615d30565b6040516001600160a01b0380871660248301528c1660448201526064810182905290915061336e9060840160408051601f198184030181529190526020810180516001600160e01b03167f23b872dd00000000000000000000000000000000000000000000000000000000179052600454879063ffffffff600160c01b909104166113886084613a8d565b509093509150826133ad57816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107c59190614284565b604080518082019091526001600160a01b0390951685526020850152509192505050979650505050505050565b6000613406827f01ffc9a70000000000000000000000000000000000000000000000000000000061343e565b8015610a645750613437827fffffffff0000000000000000000000000000000000000000000000000000000061343e565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156134e1575060208210155b80156134ed5750600081115b979650505050505050565b60005b8151811015610cc35760ff83166000908152600360205260408120835190919084908490811061352d5761352d6152de565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff191690556001016134fb565b60005b82518160ff161015610a0e576000838260ff1681518110613587576135876152de565b60200260200101519050600060028111156135a4576135a4614469565b60ff80871660009081526003602090815260408083206001600160a01b038716845290915290205461010090041660028111156135e3576135e3614469565b14613604576004604051631b3fab5160e11b81526004016107c59190615ad2565b6001600160a01b038116613644576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff16815260200184600281111561366a5761366a614469565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff1916176101008360028111156136c7576136c7614469565b021790555090505050806136da90615d49565b9050613564565b60ff81166105c8576009805467ffffffffffffffff1916905550565b815160208082015160409283015192516000938493613743937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615d68565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d0151950151959761378c9794969395929491939101615d9b565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016137c39190615e92565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061382d858585613bb3565b90506138388161146b565b61384657600091505061386d565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b60006002613884608085615532565b67ffffffffffffffff166138989190615559565b905060006138a68585611e16565b9050816138b560016004615509565b901b1916818360038111156138cc576138cc614469565b67ffffffffffffffff871660009081526007602052604081209190921b929092179182916138fb608088615a6d565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906139619087908790600401615ef2565b600060405180830381600087803b15801561397b57600080fd5b505af192505050801561398c575060015b6139cb573d8080156139ba576040519150601f19603f3d011682016040523d82523d6000602084013e6139bf565b606091505b506003925090506139e0565b50506040805160208101909152600081526002905b9250929050565b60008151602014613a2657816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107c59190614284565b600082806020019051810190613a3c9190615d30565b90506001600160a01b03811180613a54575061040081105b15610a6457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107c59190614284565b6000606060008361ffff1667ffffffffffffffff811115613ab057613ab0613f39565b6040519080825280601f01601f191660200182016040528015613ada576020820181803683370190505b509150863b613b0d577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613b40577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613b79577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b9c5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613bf4576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613c0857506101018111155b613c25576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613c4f576040516309bde33960e01b815260040160405180910390fd5b80600003613c7c5786600081518110613c6a57613c6a6152de565b60200260200101519350505050613e4b565b60008167ffffffffffffffff811115613c9757613c97613f39565b604051908082528060200260200182016040528015613cc0578160200160208202803683370190505b50905060008080805b85811015613dea5760006001821b8b811603613d245788851015613d0d578c5160018601958e918110613cfe57613cfe6152de565b60200260200101519050613d46565b8551600185019487918110613cfe57613cfe6152de565b8b5160018401938d918110613d3b57613d3b6152de565b602002602001015190505b600089861015613d76578d5160018701968f918110613d6757613d676152de565b60200260200101519050613d98565b8651600186019588918110613d8d57613d8d6152de565b602002602001015190505b82851115613db9576040516309bde33960e01b815260040160405180910390fd5b613dc38282613e52565b878481518110613dd557613dd56152de565b60209081029190910101525050600101613cc9565b506001850382148015613dfc57508683145b8015613e0757508581145b613e24576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613e3957613e396152de565b60200260200101519750505050505050505b9392505050565b6000818310613e6a57613e658284613e70565b610a61565b610a6183835b604080516001602082015290810183905260608101829052600090608001613801565b828054828255906000526020600020908101928215613ef5579160200282015b82811115613ef5578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613eb3565b50613f01929150613f24565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613f015760008155600101613f25565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613f7257613f72613f39565b60405290565b60405160a0810167ffffffffffffffff81118282101715613f7257613f72613f39565b60405160c0810167ffffffffffffffff81118282101715613f7257613f72613f39565b6040805190810167ffffffffffffffff81118282101715613f7257613f72613f39565b6040516060810167ffffffffffffffff81118282101715613f7257613f72613f39565b604051601f8201601f1916810167ffffffffffffffff8111828210171561402d5761402d613f39565b604052919050565b600067ffffffffffffffff82111561404f5761404f613f39565b5060051b60200190565b6001600160a01b03811681146105c857600080fd5b803567ffffffffffffffff8116811461408657600080fd5b919050565b80151581146105c857600080fd5b80356140868161408b565b600067ffffffffffffffff8211156140be576140be613f39565b50601f01601f191660200190565b600082601f8301126140dd57600080fd5b81356140f06140eb826140a4565b614004565b81815284602083860101111561410557600080fd5b816020850160208301376000918101602001919091529392505050565b6000602080838503121561413557600080fd5b823567ffffffffffffffff8082111561414d57600080fd5b818501915085601f83011261416157600080fd5b813561416f6140eb82614035565b81815260059190911b8301840190848101908883111561418e57600080fd5b8585015b83811015612116578035858111156141aa5760008081fd5b86016080818c03601f19018113156141c25760008081fd5b6141ca613f4f565b898301356141d781614059565b815260406141e684820161406e565b8b8301526060808501356141f98161408b565b8383015292840135928984111561421257600091508182fd5b6142208f8d868801016140cc565b908301525085525050918601918601614192565b60005b8381101561424f578181015183820152602001614237565b50506000910152565b60008151808452614270816020860160208601614234565b601f01601f19169290920160200192915050565b602081526000610a616020830184614258565b8060608101831015610a6457600080fd5b60008083601f8401126142ba57600080fd5b50813567ffffffffffffffff8111156142d257600080fd5b6020830191508360208285010111156139e057600080fd5b60008083601f8401126142fc57600080fd5b50813567ffffffffffffffff81111561431457600080fd5b6020830191508360208260051b85010111156139e057600080fd5b60008060008060008060008060e0898b03121561434b57600080fd5b6143558a8a614297565b9750606089013567ffffffffffffffff8082111561437257600080fd5b61437e8c838d016142a8565b909950975060808b013591508082111561439757600080fd5b6143a38c838d016142ea565b909750955060a08b01359150808211156143bc57600080fd5b506143c98b828c016142ea565b999c989b50969995989497949560c00135949350505050565b6000806000608084860312156143f757600080fd5b6144018585614297565b9250606084013567ffffffffffffffff81111561441d57600080fd5b614429868287016142a8565b9497909650939450505050565b6000806040838503121561444957600080fd5b6144528361406e565b91506144606020840161406e565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061448f5761448f614469565b9052565b60208101610a64828461447f565b600060a082840312156144b357600080fd5b6144bb613f78565b9050813581526144cd6020830161406e565b60208201526144de6040830161406e565b60408201526144ef6060830161406e565b60608201526145006080830161406e565b608082015292915050565b803561408681614059565b600082601f83011261452757600080fd5b813560206145376140eb83614035565b82815260059290921b8401810191818101908684111561455657600080fd5b8286015b8481101561462c57803567ffffffffffffffff8082111561457b5760008081fd5b8189019150608080601f19848d030112156145965760008081fd5b61459e613f4f565b87840135838111156145b05760008081fd5b6145be8d8a838801016140cc565b825250604080850135848111156145d55760008081fd5b6145e38e8b838901016140cc565b8a84015250606080860135858111156145fc5760008081fd5b61460a8f8c838a01016140cc565b928401929092529490920135938101939093525050835291830191830161455a565b509695505050505050565b600082601f83011261464857600080fd5b813560206146586140eb83614035565b82815260059290921b8401810191818101908684111561467757600080fd5b8286015b8481101561462c57803567ffffffffffffffff8082111561469c5760008081fd5b818901915061014080601f19848d030112156146b85760008081fd5b6146c0613f9b565b6146cc8c8986016144a1565b815260c0840135838111156146e15760008081fd5b6146ef8d8a838801016140cc565b898301525060e0840135838111156147075760008081fd5b6147158d8a838801016140cc565b604083015250614728610100850161450b565b6060820152610120840135608082015290830135908282111561474b5760008081fd5b6147598c8984870101614516565b60a0820152865250505091830191830161467b565b600082601f83011261477f57600080fd5b8135602061478f6140eb83614035565b82815260059290921b840181019181810190868411156147ae57600080fd5b8286015b8481101561462c57803567ffffffffffffffff808211156147d257600080fd5b818901915089603f8301126147e657600080fd5b858201356147f66140eb82614035565b81815260059190911b830160400190878101908c83111561481657600080fd5b604085015b8381101561484f5780358581111561483257600080fd5b6148418f6040838a01016140cc565b84525091890191890161481b565b508752505050928401925083016147b2565b600082601f83011261487257600080fd5b813560206148826140eb83614035565b8083825260208201915060208460051b8701019350868411156148a457600080fd5b602086015b8481101561462c57803583529183019183016148a9565b600082601f8301126148d157600080fd5b813560206148e16140eb83614035565b82815260059290921b8401810191818101908684111561490057600080fd5b8286015b8481101561462c57803567ffffffffffffffff808211156149255760008081fd5b818901915060a080601f19848d030112156149405760008081fd5b614948613f78565b61495388850161406e565b8152604080850135848111156149695760008081fd5b6149778e8b83890101614637565b8a84015250606080860135858111156149905760008081fd5b61499e8f8c838a010161476e565b83850152506080915081860135858111156149b95760008081fd5b6149c78f8c838a0101614861565b9184019190915250919093013590830152508352918301918301614904565b60008060408084860312156149fa57600080fd5b833567ffffffffffffffff80821115614a1257600080fd5b614a1e878388016148c0565b9450602091508186013581811115614a3557600080fd5b8601601f81018813614a4657600080fd5b8035614a546140eb82614035565b81815260059190911b8201840190848101908a831115614a7357600080fd5b8584015b83811015614aff57803586811115614a8f5760008081fd5b8501603f81018d13614aa15760008081fd5b87810135614ab16140eb82614035565b81815260059190911b82018a0190898101908f831115614ad15760008081fd5b928b01925b82841015614aef5783358252928a0192908a0190614ad6565b8652505050918601918601614a77565b50809750505050505050509250929050565b600060208284031215614b2357600080fd5b813567ffffffffffffffff811115614b3a57600080fd5b820160a08185031215613e4b57600080fd5b803563ffffffff8116811461408657600080fd5b600060a08284031215614b7257600080fd5b614b7a613f78565b8235614b8581614059565b8152614b9360208401614b4c565b6020820152614ba460408401614b4c565b6040820152614bb560608401614b4c565b60608201526080830135614bc881614059565b60808201529392505050565b803560ff8116811461408657600080fd5b600060208284031215614bf757600080fd5b610a6182614bd4565b60008151808452602080850194506020840160005b83811015614c3a5781516001600160a01b031687529582019590820190600101614c15565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c9460e0840182614c00565b90506040840151601f198483030160c0850152614cb18282614c00565b95945050505050565b60008060408385031215614ccd57600080fd5b614cd68361406e565b946020939093013593505050565b60008060208385031215614cf757600080fd5b823567ffffffffffffffff80821115614d0f57600080fd5b818501915085601f830112614d2357600080fd5b813581811115614d3257600080fd5b8660208260061b8501011115614d4757600080fd5b60209290920196919550909350505050565b600060208284031215614d6b57600080fd5b610a618261406e565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff60408301511660608201526000606083015160808084015261386d60a0840182614258565b600080600060408486031215614dd757600080fd5b833567ffffffffffffffff80821115614def57600080fd5b908501906101408288031215614e0457600080fd5b90935060208501359080821115614e1a57600080fd5b50614429868287016142ea565b600060208284031215614e3957600080fd5b8135613e4b81614059565b600082601f830112614e5557600080fd5b81356020614e656140eb83614035565b8083825260208201915060208460051b870101935086841115614e8757600080fd5b602086015b8481101561462c578035614e9f81614059565b8352918301918301614e8c565b60006020808385031215614ebf57600080fd5b823567ffffffffffffffff80821115614ed757600080fd5b818501915085601f830112614eeb57600080fd5b8135614ef96140eb82614035565b81815260059190911b83018401908481019088831115614f1857600080fd5b8585015b8381101561211657803585811115614f3357600080fd5b860160c0818c03601f19011215614f4a5760008081fd5b614f52613f9b565b8882013581526040614f65818401614bd4565b8a8301526060614f76818501614bd4565b8284015260809150614f89828501614099565b9083015260a08381013589811115614fa15760008081fd5b614faf8f8d83880101614e44565b838501525060c0840135915088821115614fc95760008081fd5b614fd78e8c84870101614e44565b9083015250845250918601918601614f1c565b600060208284031215614ffc57600080fd5b5035919050565b80356001600160e01b038116811461408657600080fd5b600082601f83011261502b57600080fd5b8135602061503b6140eb83614035565b82815260069290921b8401810191818101908684111561505a57600080fd5b8286015b8481101561462c57604081890312156150775760008081fd5b61507f613fbe565b6150888261406e565b8152615095858301615003565b8186015283529183019160400161505e565b600082601f8301126150b857600080fd5b813560206150c86140eb83614035565b82815260079290921b840181019181810190868411156150e757600080fd5b8286015b8481101561462c5780880360808112156151055760008081fd5b61510d613fe1565b6151168361406e565b8152604080601f198401121561512c5760008081fd5b615134613fbe565b925061514187850161406e565b835261514e81850161406e565b83880152818701929092526060830135918101919091528352918301916080016150eb565b6000602080838503121561518657600080fd5b823567ffffffffffffffff8082111561519e57600080fd5b818501915060408083880312156151b457600080fd5b6151bc613fbe565b8335838111156151cb57600080fd5b84016040818a0312156151dd57600080fd5b6151e5613fbe565b8135858111156151f457600080fd5b8201601f81018b1361520557600080fd5b80356152136140eb82614035565b81815260069190911b8201890190898101908d83111561523257600080fd5b928a01925b828410156152825787848f03121561524f5760008081fd5b615257613fbe565b843561526281614059565b815261526f858d01615003565b818d0152825292870192908a0190615237565b84525050508187013593508484111561529a57600080fd5b6152a68a85840161501a565b81880152825250838501359150828211156152c057600080fd5b6152cc888386016150a7565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b8181101561534b57835180516001600160a01b031684528501516001600160e01b0316858401529284019291850191600101615314565b50508583015187820388850152805180835290840192506000918401905b808310156153a5578351805167ffffffffffffffff1683528501516001600160e01b031685830152928401926001929092019190850190615369565b50979650505050505050565b602081526000610a6160208301846152f4565b67ffffffffffffffff8316815260608101613e4b6020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff818116838216019080821115615430576154306153f9565b5092915050565b60006020808352606084516040808487015261545660608701836152f4565b87850151878203601f19016040890152805180835290860193506000918601905b8083101561211657845167ffffffffffffffff8151168352878101516154b689850182805167ffffffffffffffff908116835260209182015116910152565b50840151828701529386019360019290920191608090910190615477565b6000602082840312156154e657600080fd5b813567ffffffffffffffff8111156154fd57600080fd5b61386d848285016148c0565b81810381811115610a6457610a646153f9565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff8084168061554d5761554d61551c565b92169190910692915050565b8082028115828204841417610a6457610a646153f9565b60006040828403121561558257600080fd5b61558a613fbe565b6155938361406e565b8152602083013560208201528091505092915050565b600181811c908216806155bd57607f821691505b6020821081036155dd57634e487b7160e01b600052602260045260246000fd5b50919050565b6000808335601e198436030181126155fa57600080fd5b83018035915067ffffffffffffffff82111561561557600080fd5b6020019150600581901b36038213156139e057600080fd5b6000808335601e1984360301811261564457600080fd5b83018035915067ffffffffffffffff82111561565f57600080fd5b6020019150368190038213156139e057600080fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a060408701526156d760a0870182614258565b9050606085015186820360608801526156f08282614258565b608087810151898303918a01919091528051808352908601935060009250908501905b808310156153a557835180516001600160a01b0316835286015186830152928501926001929092019190840190615713565b602081526000610a6160208301846156a3565b60808152600061576b60808301876156a3565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b6000806000606084860312156157a957600080fd5b83516157b48161408b565b602085015190935067ffffffffffffffff8111156157d157600080fd5b8401601f810186136157e257600080fd5b80516157f06140eb826140a4565b81815287602083850101111561580557600080fd5b615816826020830160208601614234565b809450505050604084015190509250925092565b60006020828403121561583c57600080fd5b8151613e4b8161408b565b601f821115610cc3576000816000526020600020601f850160051c810160208610156158705750805b601f850160051c820191505b818110156125315782815560010161587c565b815167ffffffffffffffff8111156158a9576158a9613f39565b6158bd816158b784546155a9565b84615847565b602080601f8311600181146158f257600084156158da5750858301515b600019600386901b1c1916600185901b178555612531565b600085815260208120601f198616915b8281101561592157888601518255948401946001909101908401615902565b508582101561593f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546159a1816155a9565b8060a089015260c060018316600081146159c257600181146159de57615a0e565b60ff19841660c08b015260c083151560051b8b01019450615a0e565b85600052602060002060005b84811015615a055781548c82018501529088019089016159ea565b8b0160c0019550505b50929998505050505050505050565b80820180821115610a6457610a646153f9565b60ff8181168382160190811115610a6457610a646153f9565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff80841680615a8857615a8861551c565b92169190910492915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112615ac857600080fd5b9190910192915050565b6020810160058310615ae657615ae6614469565b91905290565b60ff8181168382160290811690818114615430576154306153f9565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615b605784546001600160a01b031683526001948501949284019201615b3b565b50508481036060860152865180825290820192508187019060005b81811015615ba05782516001600160a01b031685529383019391830191600101615b7b565b50505060ff851660808501525090505b9695505050505050565b600067ffffffffffffffff808616835280851660208401525060606040830152614cb16060830184614258565b82815260406020820152600061386d6040830184614258565b67ffffffffffffffff8481168252831660208201526060810161386d604083018461447f565b615c30818461447f565b60406020820152600061386d6040830184614258565b600060208284031215615c5857600080fd5b8151613e4b81614059565b6020815260008251610100806020850152615c82610120850183614258565b91506020850151615c9f604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615cd960a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615cf68483614258565b935060c08701519150808685030160e0870152615d138483614258565b935060e0870151915080868503018387015250615bb08382614258565b600060208284031215615d4257600080fd5b5051919050565b600060ff821660ff8103615d5f57615d5f6153f9565b60010192915050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152615bb06080830184614258565b86815260c060208201526000615db460c0830188614258565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615e8557601f19868403018952815160808151818652615e3182870182614258565b9150508582015185820387870152615e498282614258565b91505060408083015186830382880152615e638382614258565b6060948501519790940196909652505098840198925090830190600101615e0b565b5090979650505050505050565b602081526000610a616020830184615dee565b60008282518085526020808601955060208260051b8401016020860160005b84811015615e8557601f19868403018952615ee0838351614258565b98840198925090830190600101615ec4565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615f5a610180850183614258565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615f978483614258565b935060608801519150615fb66101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615fdd8282615dee565b9150508281036020840152614cb18185615ea556fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162006bba38038062006bba8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615ee462000cd6600039600081816102530152612c0c0152600081816102240152612ee60152600081816101f50152818161142f01526118400152600081816101c50152612801015260008181611dce0152611e1a0152615ee46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063d2a15d351461053d578063e9d68a8e14610550578063ece670b61461057057600080fd5b8063991a5018116100bd578063991a5018146104c5578063c673e584146104d8578063ccd37ba3146104f857600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104815780637d4eef601461048957600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a3660046140a0565b6105cc565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d1919061420f565b61018f6103313660046142ba565b6105e0565b61018f61034436600461436d565b6109c0565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143c1565b610a29565b6040516102d1919061441e565b6104246040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610a7f565b61018f610497366004614973565b610b3d565b61018f610177366004614a9e565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104d3366004614aed565b610cdd565b6104eb6104e6366004614b72565b610cee565b6040516102d19190614bd2565b61052f610506366004614c47565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f61054b366004614c71565b610e4c565b61056361055e366004614ce6565b610f06565b6040516102d19190614d01565b61018f61057e366004614d4f565b611013565b61018f610591366004614dab565b611386565b61018f6105a4366004614e30565b611397565b6105bc6105b7366004614f6e565b6113d9565b60405190151581526020016102d1565b6105d461149a565b6105dd816114f6565b50565b60006105ee878901896150f7565b8051515190915015158061060757508051602001515115155b156107075760095460208a01359067ffffffffffffffff808316911610156106c6576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261068f929101615335565b600060405180830381600087803b1580156106a957600080fd5b505af11580156106bd573d6000803e3d6000fd5b50505050610705565b816020015151600003610705576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109095760008260200151828151811061072f5761072f615262565b6020026020010151905060008160000151905061074b816117f4565b6000610756826118f6565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061079a575060208084015190810151905167ffffffffffffffff9182169116115b156107e357825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107da929190600401615348565b60405180910390fd5b60408301518061081f576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108925783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016107da565b60208085015101516108a5906001615393565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff92831602179092559251166000908152600860209081526040808320948352939052919091204290555060010161070a565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161093991906153bb565b60405180910390a16109b560008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b925061195d915050565b505050505050505050565b610a006109cf82840184615458565b60408051600080825260208201909252906109fa565b60608152602001906001900390816109e55790505b50611cd4565b604080516000808252602082019092529050610a2360018585858586600061195d565b50505050565b6000610a376001600461548d565b6002610a446080856154b6565b67ffffffffffffffff16610a5891906154dd565b610a628585611d84565b901c166003811115610a7657610a766143f4565b90505b92915050565b6001546001600160a01b03163314610ad95760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107da565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b45611dcb565b815181518114610b81576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ccd576000848281518110610ba057610ba0615262565b60200260200101519050600081602001515190506000858481518110610bc857610bc8615262565b6020026020010151905080518214610c0c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cbe576000828281518110610c2b57610c2b615262565b6020026020010151905080600014610cb55784602001518281518110610c5357610c53615262565b602002602001015160800151811015610cb55784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016107da565b50600101610c0f565b50505050806001019050610b84565b50610cd88383611cd4565b505050565b610ce561149a565b6105dd81611e4c565b610d316040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610dda57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dbc575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e1e575b5050505050815250509050919050565b610e5461149a565b60005b81811015610cd8576000838383818110610e7357610e73615262565b905060400201803603810190610e8991906154f4565b9050610e9881602001516113d9565b610efd57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e57565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191610f939061552d565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbf9061552d565b8015610e3c5780601f10610fe157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610fef57505050919092525091949350505050565b33301461104c576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611089565b60408051808201909152600080825260208201528152602001906001900390816110625790505b5060a085015151909150156110bd576110ba8460a00151856020015186606001518760000151602001518787611fb2565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff16818301528087015183516000948401926110f992910161420f565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015611206576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a190611173908590600401615609565b600060405180830381600087803b15801561118d57600080fd5b505af192505050801561119e575060015b611206573d8080156111cc576040519150601f19603f3d011682016040523d82523d6000602084013e6111d1565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b60408601515115801561121b57506080860151155b80611232575060608601516001600160a01b03163b155b8061127257506060860151611270906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120d1565b155b1561127f57505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf97983926112f7928992611388929160040161561c565b6000604051808303816000875af1158015611316573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261133e9190810190615658565b50915091508161137c57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b5050505050505050565b61138e61149a565b6105dd816120ed565b61139f61149a565b60005b81518110156113d5576113cd8282815181106113c0576113c0615262565b60200260200101516121a3565b6001016113a2565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611476573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7991906156ee565b6000546001600160a01b031633146114f45760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107da565b565b60005b81518110156113d557600082828151811061151657611516615262565b602002602001015190506000816020015190508067ffffffffffffffff1660000361156d576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611595576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115c09061552d565b80601f01602080910402602001604051908101604052809291908181526020018280546115ec9061552d565b80156116395780601f1061160e57610100808354040283529160200191611639565b820191906000526020600020905b81548152906001019060200180831161161c57829003601f168201915b5050505050905060008460600151905081516000036116f1578051600003611674576040516342bcdf7f60e11b815260040160405180910390fd5b600183016116828282615753565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611744565b8080519060200120828051906020012014611744576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016107da565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117dc908690615813565b60405180910390a250505050508060010190506114f9565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b391906156ee565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107da565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610a79576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107da565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906119bc8760a46158e1565b9050826060015115611a045784516119d59060206154dd565b86516119e29060206154dd565b6119ed9060a06158e1565b6119f791906158e1565b611a0190826158e1565b90505b368114611a46576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107da565b5081518114611a8e5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107da565b611a96611dcb565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611ae457611ae46143f4565b6002811115611af557611af56143f4565b9052509050600281602001516002811115611b1257611b126143f4565b148015611b665750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611b4e57611b4e615262565b6000918252602090912001546001600160a01b031633145b611b9c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611c7e576020820151611bb79060016158f4565b60ff16855114611bf3576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611c2e576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611c4092919061590d565b604051908190038120611c57918b9060200161591d565b604051602081830303815290604052805190602001209050611c7c8a828888886124e7565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d0e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611d7d57611d75858281518110611d4357611d43615262565b602002602001015184611d6f57858381518110611d6257611d62615262565b60200260200101516126f4565b836126f4565b600101611d25565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611da9608085615931565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f0000000000000000000000000000000000000000000000000000000000000000146114f4576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107da565b80516001600160a01b0316611e74576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fce57611fce613eb7565b60405190808252806020026020018201604052801561201357816020015b6040805180820190915260008082526020820152815260200190600190039081611fec5790505b50905060005b87518110156120c5576120a088828151811061203757612037615262565b602002602001015188888888888781811061205457612054615262565b90506020028101906120669190615958565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e8592505050565b8282815181106120b2576120b2615262565b6020908102919091010152600101612019565b505b9695505050505050565b60006120dc8361322a565b8015610a765750610a76838361328e565b336001600160a01b038216036121455760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107da565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ce576000604051631b3fab5160e11b81526004016107da91906159bd565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223b57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612290565b6060840151600182015460ff6201000090910416151590151514612290576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016107da565b60a08401518051601f60ff821611156122bf576001604051631b3fab5160e11b81526004016107da91906159bd565b612325858560030180548060200260200160405190810160405280929190818152602001828054801561231b57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122fd575b5050505050613348565b85606001511561245457612393858560020180548060200260200160405190810160405280929190818152602001828054801561231b576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122fd575050505050613348565b608086015180516123ad9060028701906020840190613e11565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f101561240d576002604051631b3fab5160e11b81526004016107da91906159bd565b604088015161241d9060036159d7565b60ff168160ff1611612445576003604051631b3fab5160e11b81526004016107da91906159bd565b612451878360016133b1565b50505b612460858360026133b1565b81516124759060038601906020850190613e11565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ce938a939260028b019291906159f3565b60405180910390a16124df85613531565b505050505050565b6124ef613e83565b835160005b8181101561137c57600060018886846020811061251357612513615262565b61252091901a601b6158f4565b89858151811061253257612532615262565b602002602001015189868151811061254c5761254c615262565b60200260200101516040516000815260200160405260405161258a949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156125ac573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561260d5761260d6143f4565b600281111561261e5761261e6143f4565b905250905060018160200151600281111561263b5761263b6143f4565b14612672576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061268957612689615262565b6020020151156126c5576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126e0576126e0615262565b9115156020909202015250506001016124f4565b81516126ff816117f4565b600061270a826118f6565b602085015151909150600081900361274d576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461278b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156127a6576127a6613eb7565b6040519080825280602002602001820160405280156127cf578160200160208202803683370190505b50905060005b82811015612944576000876020015182815181106127f5576127f5615262565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461288857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107da565b61291e8186600101805461289b9061552d565b80601f01602080910402602001604051908101604052809291908181526020018280546128c79061552d565b80156129145780601f106128e957610100808354040283529160200191612914565b820191906000526020600020905b8154815290600101906020018083116128f757829003601f168201915b505050505061354d565b83838151811061293057612930615262565b6020908102919091010152506001016127d5565b50600061295b858389606001518a6080015161366f565b9050806000036129a3576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107da565b8551151560005b848110156109b5576000896020015182815181106129ca576129ca615262565b6020026020010151905060006129e889836000015160600151610a29565b905060008160038111156129fe576129fe6143f4565b1480612a1b57506003816003811115612a1957612a196143f4565b145b612a72578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612e7d565b8315612b4257600454600090600160a01b900463ffffffff16612a95874261548d565b1190508080612ab557506003826003811115612ab357612ab36143f4565b145b612af7576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b1660048201526024016107da565b8a8481518110612b0957612b09615262565b6020026020010151600014612b3c578a8481518110612b2a57612b2a615262565b60200260200101518360800181815250505b50612ba3565b6000816003811115612b5657612b566143f4565b14612ba3578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612a63565b81516080015167ffffffffffffffff1615612c91576000816003811115612bcc57612bcc6143f4565b03612c915781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c43928e929190600401615a9f565b6020604051808303816000875af1158015612c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8691906156ee565b612c91575050612e7d565b60008b604001518481518110612ca957612ca9615262565b6020026020010151905080518360a001515114612d0d578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d16600483015290911660248201526044016107da565b612d218a84600001516060015160016136c5565b600080612d2e858461376d565b91509150612d458c866000015160600151846136c5565b8615612db5576003826003811115612d5f57612d5f6143f4565b03612db5576000846003811115612d7857612d786143f4565b14612db5578451516040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526107da91908390600401615acc565b6002826003811115612dc957612dc96143f4565b14612e23576003826003811115612de257612de26143f4565b14612e23578451606001516040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526107da918e918590600401615ae5565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612e6f9087908790615b0b565b60405180910390a450505050505b6001016129aa565b60408051808201909152600080825260208201526000612ea88760200151613837565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f519190615b2b565b90506001600160a01b0381161580612f995750612f976001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120d1565b155b15612fdb576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016107da565b6004546000908190612ffd9089908690600160e01b900463ffffffff166138dd565b9150915060008060006130ca6040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b81525060405160240161307b9190615b48565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a0b565b9250925092508261310957816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b81516020146131515781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b6000828060200190518101906131679190615c15565b9050866001600160a01b03168c6001600160a01b0316146131fc5760006131988d8a613193868a61548d565b6138dd565b509050868110806131b25750816131af888361548d565b14155b156131fa576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016107da565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613256827f01ffc9a70000000000000000000000000000000000000000000000000000000061328e565b8015610a795750613287827fffffffff0000000000000000000000000000000000000000000000000000000061328e565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613331575060208210155b801561333d5750600081115b979650505050505050565b60005b8151811015610cd85760ff83166000908152600360205260408120835190919084908490811061337d5761337d615262565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161334b565b60005b82518160ff161015610a23576000838260ff16815181106133d7576133d7615262565b60200260200101519050600060028111156133f4576133f46143f4565b60ff80871660009081526003602090815260408083206001600160a01b03871684529091529020546101009004166002811115613433576134336143f4565b14613454576004604051631b3fab5160e11b81526004016107da91906159bd565b6001600160a01b038116613494576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134ba576134ba6143f4565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff191617610100836002811115613517576135176143f4565b0217905550905050508061352a90615c2e565b90506133b4565b60ff81166105dd576009805467ffffffffffffffff1916905550565b815160208082015160409283015192516000938493613593937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c4d565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135dc9794969395929491939101615c80565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136139190615d77565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061367d858585613b31565b9050613688816113d9565b6136965760009150506136bd565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026136d46080856154b6565b67ffffffffffffffff166136e891906154dd565b905060006136f68585611d84565b9050816137056001600461548d565b901b19168183600381111561371c5761371c6143f4565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161374b608088615931565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906137b19087908790600401615dd7565b600060405180830381600087803b1580156137cb57600080fd5b505af19250505080156137dc575060015b61381b573d80801561380a576040519150601f19603f3d011682016040523d82523d6000602084013e61380f565b606091505b50600392509050613830565b50506040805160208101909152600081526002905b9250929050565b6000815160201461387657816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b60008280602001905181019061388c9190615c15565b90506001600160a01b038111806138a4575061040081105b15610a7957826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b60008060008060006139578860405160240161390891906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a0b565b9250925092508261399657816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b60208251146139de5781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b818060200190518101906139f29190615c15565b6139fc828861548d565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a2e57613a2e613eb7565b6040519080825280601f01601f191660200182016040528015613a58576020820181803683370190505b509150863b613a8b577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613abe577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613af7577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b1a5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b72576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b8657506101018111155b613ba3576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bcd576040516309bde33960e01b815260040160405180910390fd5b80600003613bfa5786600081518110613be857613be8615262565b60200260200101519350505050613dc9565b60008167ffffffffffffffff811115613c1557613c15613eb7565b604051908082528060200260200182016040528015613c3e578160200160208202803683370190505b50905060008080805b85811015613d685760006001821b8b811603613ca25788851015613c8b578c5160018601958e918110613c7c57613c7c615262565b60200260200101519050613cc4565b8551600185019487918110613c7c57613c7c615262565b8b5160018401938d918110613cb957613cb9615262565b602002602001015190505b600089861015613cf4578d5160018701968f918110613ce557613ce5615262565b60200260200101519050613d16565b8651600186019588918110613d0b57613d0b615262565b602002602001015190505b82851115613d37576040516309bde33960e01b815260040160405180910390fd5b613d418282613dd0565b878481518110613d5357613d53615262565b60209081029190910101525050600101613c47565b506001850382148015613d7a57508683145b8015613d8557508581145b613da2576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613db757613db7615262565b60200260200101519750505050505050505b9392505050565b6000818310613de857613de38284613dee565b610a76565b610a7683835b604080516001602082015290810183905260608101829052600090608001613651565b828054828255906000526020600020908101928215613e73579160200282015b82811115613e73578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e31565b50613e7f929150613ea2565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e7f5760008155600101613ea3565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b60405290565b60405160a0810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b60405160c0810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b6040805190810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b6040516060810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fab57613fab613eb7565b604052919050565b600067ffffffffffffffff821115613fcd57613fcd613eb7565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461400457600080fd5b919050565b80151581146105dd57600080fd5b803561400481614009565b600067ffffffffffffffff82111561403c5761403c613eb7565b50601f01601f191660200190565b600082601f83011261405b57600080fd5b813561406e61406982614022565b613f82565b81815284602083860101111561408357600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140b357600080fd5b823567ffffffffffffffff808211156140cb57600080fd5b818501915085601f8301126140df57600080fd5b81356140ed61406982613fb3565b81815260059190911b8301840190848101908883111561410c57600080fd5b8585015b838110156141b2578035858111156141285760008081fd5b86016080818c03601f19018113156141405760008081fd5b614148613ecd565b8983013561415581613fd7565b81526040614164848201613fec565b8b83015260608085013561417781614009565b8383015292840135928984111561419057600091508182fd5b61419e8f8d8688010161404a565b908301525085525050918601918601614110565b5098975050505050505050565b60005b838110156141da5781810151838201526020016141c2565b50506000910152565b600081518084526141fb8160208601602086016141bf565b601f01601f19169290920160200192915050565b602081526000610a7660208301846141e3565b8060608101831015610a7957600080fd5b60008083601f84011261424557600080fd5b50813567ffffffffffffffff81111561425d57600080fd5b60208301915083602082850101111561383057600080fd5b60008083601f84011261428757600080fd5b50813567ffffffffffffffff81111561429f57600080fd5b6020830191508360208260051b850101111561383057600080fd5b60008060008060008060008060e0898b0312156142d657600080fd5b6142e08a8a614222565b9750606089013567ffffffffffffffff808211156142fd57600080fd5b6143098c838d01614233565b909950975060808b013591508082111561432257600080fd5b61432e8c838d01614275565b909750955060a08b013591508082111561434757600080fd5b506143548b828c01614275565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561438257600080fd5b61438c8585614222565b9250606084013567ffffffffffffffff8111156143a857600080fd5b6143b486828701614233565b9497909650939450505050565b600080604083850312156143d457600080fd5b6143dd83613fec565b91506143eb60208401613fec565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061441a5761441a6143f4565b9052565b60208101610a79828461440a565b600060a0828403121561443e57600080fd5b614446613ef6565b90508135815261445860208301613fec565b602082015261446960408301613fec565b604082015261447a60608301613fec565b606082015261448b60808301613fec565b608082015292915050565b803561400481613fd7565b600082601f8301126144b257600080fd5b813560206144c261406983613fb3565b82815260059290921b840181019181810190868411156144e157600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156145065760008081fd5b8189019150608080601f19848d030112156145215760008081fd5b614529613ecd565b878401358381111561453b5760008081fd5b6145498d8a8388010161404a565b825250604080850135848111156145605760008081fd5b61456e8e8b8389010161404a565b8a84015250606080860135858111156145875760008081fd5b6145958f8c838a010161404a565b92840192909252949092013593810193909352505083529183019183016144e5565b600061014082840312156145ca57600080fd5b6145d2613f19565b90506145de838361442c565b815260a082013567ffffffffffffffff808211156145fb57600080fd5b6146078583860161404a565b602084015260c084013591508082111561462057600080fd5b61462c8583860161404a565b604084015261463d60e08501614496565b6060840152610100840135608084015261012084013591508082111561466257600080fd5b5061466f848285016144a1565b60a08301525092915050565b600082601f83011261468c57600080fd5b8135602061469c61406983613fb3565b82815260059290921b840181019181810190868411156146bb57600080fd5b8286015b848110156120c557803567ffffffffffffffff8111156146df5760008081fd5b6146ed8986838b01016145b7565b8452509183019183016146bf565b600082601f83011261470c57600080fd5b8135602061471c61406983613fb3565b82815260059290921b8401810191818101908684111561473b57600080fd5b8286015b848110156120c557803567ffffffffffffffff8082111561475f57600080fd5b818901915089603f83011261477357600080fd5b8582013561478361406982613fb3565b81815260059190911b830160400190878101908c8311156147a357600080fd5b604085015b838110156147dc578035858111156147bf57600080fd5b6147ce8f6040838a010161404a565b8452509189019189016147a8565b5087525050509284019250830161473f565b600082601f8301126147ff57600080fd5b8135602061480f61406983613fb3565b8083825260208201915060208460051b87010193508684111561483157600080fd5b602086015b848110156120c55780358352918301918301614836565b600082601f83011261485e57600080fd5b8135602061486e61406983613fb3565b82815260059290921b8401810191818101908684111561488d57600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156148b25760008081fd5b818901915060a080601f19848d030112156148cd5760008081fd5b6148d5613ef6565b6148e0888501613fec565b8152604080850135848111156148f65760008081fd5b6149048e8b8389010161467b565b8a840152506060808601358581111561491d5760008081fd5b61492b8f8c838a01016146fb565b83850152506080915081860135858111156149465760008081fd5b6149548f8c838a01016147ee565b9184019190915250919093013590830152508352918301918301614891565b600080604080848603121561498757600080fd5b833567ffffffffffffffff8082111561499f57600080fd5b6149ab8783880161484d565b94506020915081860135818111156149c257600080fd5b8601601f810188136149d357600080fd5b80356149e161406982613fb3565b81815260059190911b8201840190848101908a831115614a0057600080fd5b8584015b83811015614a8c57803586811115614a1c5760008081fd5b8501603f81018d13614a2e5760008081fd5b87810135614a3e61406982613fb3565b81815260059190911b82018a0190898101908f831115614a5e5760008081fd5b928b01925b82841015614a7c5783358252928a0192908a0190614a63565b8652505050918601918601614a04565b50809750505050505050509250929050565b600060208284031215614ab057600080fd5b813567ffffffffffffffff811115614ac757600080fd5b820160a08185031215613dc957600080fd5b803563ffffffff8116811461400457600080fd5b600060a08284031215614aff57600080fd5b614b07613ef6565b8235614b1281613fd7565b8152614b2060208401614ad9565b6020820152614b3160408401614ad9565b6040820152614b4260608401614ad9565b60608201526080830135614b5581613fd7565b60808201529392505050565b803560ff8116811461400457600080fd5b600060208284031215614b8457600080fd5b610a7682614b61565b60008151808452602080850194506020840160005b83811015614bc75781516001600160a01b031687529582019590820190600101614ba2565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c2160e0840182614b8d565b90506040840151601f198483030160c0850152614c3e8282614b8d565b95945050505050565b60008060408385031215614c5a57600080fd5b614c6383613fec565b946020939093013593505050565b60008060208385031215614c8457600080fd5b823567ffffffffffffffff80821115614c9c57600080fd5b818501915085601f830112614cb057600080fd5b813581811115614cbf57600080fd5b8660208260061b8501011115614cd457600080fd5b60209290920196919550909350505050565b600060208284031215614cf857600080fd5b610a7682613fec565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136bd60a08401826141e3565b600080600060408486031215614d6457600080fd5b833567ffffffffffffffff80821115614d7c57600080fd5b614d88878388016145b7565b94506020860135915080821115614d9e57600080fd5b506143b486828701614275565b600060208284031215614dbd57600080fd5b8135613dc981613fd7565b600082601f830112614dd957600080fd5b81356020614de961406983613fb3565b8083825260208201915060208460051b870101935086841115614e0b57600080fd5b602086015b848110156120c5578035614e2381613fd7565b8352918301918301614e10565b60006020808385031215614e4357600080fd5b823567ffffffffffffffff80821115614e5b57600080fd5b818501915085601f830112614e6f57600080fd5b8135614e7d61406982613fb3565b81815260059190911b83018401908481019088831115614e9c57600080fd5b8585015b838110156141b257803585811115614eb757600080fd5b860160c0818c03601f19011215614ece5760008081fd5b614ed6613f19565b8882013581526040614ee9818401614b61565b8a8301526060614efa818501614b61565b8284015260809150614f0d828501614017565b9083015260a08381013589811115614f255760008081fd5b614f338f8d83880101614dc8565b838501525060c0840135915088821115614f4d5760008081fd5b614f5b8e8c84870101614dc8565b9083015250845250918601918601614ea0565b600060208284031215614f8057600080fd5b5035919050565b80356001600160e01b038116811461400457600080fd5b600082601f830112614faf57600080fd5b81356020614fbf61406983613fb3565b82815260069290921b84018101918181019086841115614fde57600080fd5b8286015b848110156120c55760408189031215614ffb5760008081fd5b615003613f3c565b61500c82613fec565b8152615019858301614f87565b81860152835291830191604001614fe2565b600082601f83011261503c57600080fd5b8135602061504c61406983613fb3565b82815260079290921b8401810191818101908684111561506b57600080fd5b8286015b848110156120c55780880360808112156150895760008081fd5b615091613f5f565b61509a83613fec565b8152604080601f19840112156150b05760008081fd5b6150b8613f3c565b92506150c5878501613fec565b83526150d2818501613fec565b838801528187019290925260608301359181019190915283529183019160800161506f565b6000602080838503121561510a57600080fd5b823567ffffffffffffffff8082111561512257600080fd5b8185019150604080838803121561513857600080fd5b615140613f3c565b83358381111561514f57600080fd5b84016040818a03121561516157600080fd5b615169613f3c565b81358581111561517857600080fd5b8201601f81018b1361518957600080fd5b803561519761406982613fb3565b81815260069190911b8201890190898101908d8311156151b657600080fd5b928a01925b828410156152065787848f0312156151d35760008081fd5b6151db613f3c565b84356151e681613fd7565b81526151f3858d01614f87565b818d0152825292870192908a01906151bb565b84525050508187013593508484111561521e57600080fd5b61522a8a858401614f9e565b818801528252508385013591508282111561524457600080fd5b6152508883860161502b565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b818110156152cf57835180516001600160a01b031684528501516001600160e01b0316858401529284019291850191600101615298565b50508583015187820388850152805180835290840192506000918401905b80831015615329578351805167ffffffffffffffff1683528501516001600160e01b0316858301529284019260019290920191908501906152ed565b50979650505050505050565b602081526000610a766020830184615278565b67ffffffffffffffff8316815260608101613dc96020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153b4576153b461537d565b5092915050565b6000602080835260608451604080848701526153da6060870183615278565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141b257845167ffffffffffffffff81511683528781015161543a89850182805167ffffffffffffffff908116835260209182015116910152565b508401518287015293860193600192909201916080909101906153fb565b60006020828403121561546a57600080fd5b813567ffffffffffffffff81111561548157600080fd5b6136bd8482850161484d565b81810381811115610a7957610a7961537d565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff808416806154d1576154d16154a0565b92169190910692915050565b8082028115828204841417610a7957610a7961537d565b60006040828403121561550657600080fd5b61550e613f3c565b61551783613fec565b8152602083013560208201528091505092915050565b600181811c9082168061554157607f821691505b60208210810361556157634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261559b60a08701826141e3565b9050606085015186820360608801526155b482826141e3565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561532957835180516001600160a01b03168352860151868301529285019260019290920191908401906155d7565b602081526000610a766020830184615567565b60808152600061562f6080830187615567565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561566d57600080fd5b835161567881614009565b602085015190935067ffffffffffffffff81111561569557600080fd5b8401601f810186136156a657600080fd5b80516156b461406982614022565b8181528760208385010111156156c957600080fd5b6156da8260208301602086016141bf565b809450505050604084015190509250925092565b60006020828403121561570057600080fd5b8151613dc981614009565b601f821115610cd8576000816000526020600020601f850160051c810160208610156157345750805b601f850160051c820191505b818110156124df57828155600101615740565b815167ffffffffffffffff81111561576d5761576d613eb7565b6157818161577b845461552d565b8461570b565b602080601f8311600181146157b6576000841561579e5750858301515b600019600386901b1c1916600185901b1785556124df565b600085815260208120601f198616915b828110156157e5578886015182559484019460019091019084016157c6565b50858210156158035787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546158658161552d565b8060a089015260c0600183166000811461588657600181146158a2576158d2565b60ff19841660c08b015260c083151560051b8b010194506158d2565b85600052602060002060005b848110156158c95781548c82018501529088019089016158ae565b8b0160c0019550505b50929998505050505050505050565b80820180821115610a7957610a7961537d565b60ff8181168382160190811115610a7957610a7961537d565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061594c5761594c6154a0565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261598d57600080fd5b83018035915067ffffffffffffffff8211156159a857600080fd5b60200191503681900382131561383057600080fd5b60208101600583106159d1576159d16143f4565b91905290565b60ff81811683821602908116908181146153b4576153b461537d565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a4b5784546001600160a01b031683526001948501949284019201615a26565b50508481036060860152865180825290820192508187019060005b81811015615a8b5782516001600160a01b031685529383019391830191600101615a66565b50505060ff851660808501525090506120c7565b600067ffffffffffffffff808616835280851660208401525060606040830152614c3e60608301846141e3565b8281526040602082015260006136bd60408301846141e3565b67ffffffffffffffff848116825283166020820152606081016136bd604083018461440a565b615b15818461440a565b6040602082015260006136bd60408301846141e3565b600060208284031215615b3d57600080fd5b8151613dc981613fd7565b6020815260008251610100806020850152615b676101208501836141e3565b91506020850151615b84604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615bbe60a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bdb84836141e3565b935060c08701519150808685030160e0870152615bf884836141e3565b935060e08701519150808685030183870152506120c783826141e3565b600060208284031215615c2757600080fd5b5051919050565b600060ff821660ff8103615c4457615c4461537d565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c760808301846141e3565b86815260c060208201526000615c9960c08301886141e3565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d6a57601f19868403018952815160808151818652615d16828701826141e3565b9150508582015185820387870152615d2e82826141e3565b91505060408083015186830382880152615d4883826141e3565b6060948501519790940196909652505098840198925090830190600101615cf0565b5090979650505050505050565b602081526000610a766020830184615cd3565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d6a57601f19868403018952615dc58383516141e3565b98840198925090830190600101615da9565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e3f6101808501836141e3565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e7c84836141e3565b935060608801519150615e9b6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615ec28282615cd3565b9150508281036020840152614c3e8185615d8a56fea164736f6c6343000818000a", } var EVM2EVMMultiOffRampABI = EVM2EVMMultiOffRampMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go index 010953fdf0..313714e306 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go @@ -104,8 +104,8 @@ type RateLimiterTokenBucket struct { } var EVM2EVMOffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101a06040523480156200001257600080fd5b5060405162005e1238038062005e128339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615749620006c9600039600081816102ec01528181611a5201526130470152600081816102bd01528181611a2a0152611cdc01526000818161028e01528181610e7f01528181610ee401528181611a000152818161222d015261229701526000611e7b01526000818161025f01526119d60152600081816101ff015261197a01526000818161022f015281816119ae01528181611c9901528181612ca901526131580152600081816101d0015281816119550152611f5b015260008181611bf30152611c3f01526157496000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806381ff7048116100d8578063afcb95d71161008c578063f077b59211610066578063f077b592146105f3578063f2fde38b14610609578063f52121a51461061c57600080fd5b8063afcb95d7146105ad578063b1dc65a4146105cd578063c92b2832146105e057600080fd5b8063856c8247116100bd578063856c82471461055d578063873504d7146105895780638da5cb5b1461059c57600080fd5b806381ff70481461051f57806385572ffb1461054f57600080fd5b8063599f64311161013a578063740f415011610114578063740f4150146104615780637437ff9f1461047457806379ba50971461051757600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516103299190613e8a565b60405180910390f35b610345610340366004613f20565b61062f565b6040516103299190613f80565b61038e6040518060400160405280601881526020017f45564d3245564d4f666652616d7020312e352e302d646576000000000000000081525081565b6040516103299190613fde565b6103ae6103a9366004614207565b6106aa565b005b6103b8610a9e565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610b53565b6040516103299190614319565b6103ae61045c36600461432c565b610bb5565b6103ae61046f36600461478c565b610c7e565b61050a6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a01000000000000000000009091046001600160a01b039081166060830152600b5416608082015290565b6040516103299190614847565b6103ae610d70565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae61018236600461489d565b61057061056b36600461432c565b610e53565b60405167ffffffffffffffff9091168152602001610329565b6103ae610597366004614969565b610f56565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae6105db366004614a12565b611124565b6103ae6105ee366004614b17565b61132f565b6105fb61139a565b604051610329929190614b85565b6103ae61061736600461432c565b6114c0565b6103ae61062a366004614baa565b6114d1565b600061063d60016004614c33565b600261064a608085614c75565b67ffffffffffffffff1661065e9190614c9c565b6010600061066d608087614cb3565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106a4576106a4613f3d565b92915050565b84518460ff16601f8211156106f75760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614cda565b60405180910390fd5b806000036107345760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614cda565b61073c611771565b610745856117e7565b60095460005b818110156107bc57600860006009838154811061076a5761076a614cf4565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161074b565b5050865160005b8181101561095f5760008982815181106107df576107df614cf4565b60200260200101519050600060028111156107fc576107fc613f3d565b6001600160a01b038216600090815260086020526040902054610100900460ff16600281111561082e5761082e613f3d565b146108685760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190614cda565b6001600160a01b0381166108a8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561094b5761094b613f3d565b0217905550905050508060010190506107c3565b5087516109739060099060208b0190613df8565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a1617179055600780546109f99146913091906000906109cb9063ffffffff16614d23565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611ab1565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610a8a9487949293918316921691909117908f908f908f908f908f908f90614d46565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610b4e90611b3e565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bab57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8d575b5050505050905090565b6000546001600160a01b03163314801590610bdb57506002546001600160a01b03163314155b15610c12576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b610c86611bf0565b81515181518114610cc3576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d60576000838281518110610ce257610ce2614cf4565b6020026020010151905080600014610d57578451805183908110610d0857610d08614cf4565b602002602001015160800151811015610d57576040517f085e39cf00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016106ee565b50600101610cc6565b50610d6b8383611c71565b505050565b6001546001600160a01b03163314610de4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106ee565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106a4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106a4576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4f9190614ddc565b9392505050565b610f5e611771565b60005b825181101561103157610f9b838281518110610f7f57610f7f614cf4565b602002602001015160200151600c61269d90919063ffffffff16565b15611029577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d58782838281518110610fd357610fd3614cf4565b602002602001015160000151848381518110610ff157610ff1614cf4565b6020026020010151602001516040516110209291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610f61565b5060005b8151811015610d6b5761108e82828151811061105357611053614cf4565b60200260200101516020015183838151811061107157611071614cf4565b602002602001015160000151600c6126b29092919063ffffffff16565b1561111c577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a8282815181106110c6576110c6614cf4565b6020026020010151600001518383815181106110e4576110e4614cf4565b6020026020010151602001516040516111139291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101611035565b61112e87876126d0565b600554883590808214611177576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016106ee565b61117f611bf0565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561120757611207613f3d565b600281111561121857611218613f3d565b905250905060028160200151600281111561123557611235613f3d565b14801561126f57506009816000015160ff168154811061125757611257614cf4565b6000918252602090912001546001600160a01b031633145b6112a5576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006112b3856020614c9c565b6112be886020614c9c565b6112ca8b610144614df9565b6112d49190614df9565b6112de9190614df9565b9050368114611322576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016106ee565b5050505050505050505050565b6000546001600160a01b0316331480159061135557506002546001600160a01b03163314155b1561138c576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113976003826126f7565b50565b60608060006113a9600c6128dc565b90508067ffffffffffffffff8111156113c4576113c4613ff1565b6040519080825280602002602001820160405280156113ed578160200160208202803683370190505b5092508067ffffffffffffffff81111561140957611409613ff1565b604051908082528060200260200182016040528015611432578160200160208202803683370190505b50915060005b818110156114ba5760008061144e600c846128e7565b915091508086848151811061146557611465614cf4565b60200260200101906001600160a01b031690816001600160a01b0316815250508185848151811061149857611498614cf4565b6001600160a01b03909216602092830291909101909101525050600101611438565b50509091565b6114c8611771565b61139781612905565b33301461150a576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611547565b60408051808201909152600080825260208201528152602001906001900390816115205790505b5061014084015151909150156115a7576115a4836101400151846020015160405160200161158491906001600160a01b0391909116815260200190565b6040516020818303038152906040528560400151866101600151866129e0565b90505b610120830151511580156115bd57506080830151155b806115d4575060408301516001600160a01b03163b155b8061161457506040830151611612906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000612b11565b155b1561161e57505050565b600080600a600001600a9054906101000a90046001600160a01b03166001600160a01b0316633cf979836040518060a001604052808861018001518152602001886000015167ffffffffffffffff168152602001886020015160405160200161169691906001600160a01b0391909116815260200190565b6040516020818303038152906040528152602001886101200151815260200186815250611388886080015189604001516040518563ffffffff1660e01b81526004016116e59493929190614e51565b6000604051808303816000875af1158015611704573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261172c9190810190614f5b565b50915091508161176a57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016106ee9190613fde565b5050505050565b6000546001600160a01b031633146117e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106ee565b565b6000818060200190518101906117fd9190614fc9565b60608101519091506001600160a01b0316611844576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a01000000000000000000006001600160a01b039485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611aa5918490615064565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611ad599989796959493929190615126565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611bcc82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611bb09190614c33565b85608001516fffffffffffffffffffffffffffffffff16612b2d565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b467f0000000000000000000000000000000000000000000000000000000000000000146117e5576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016106ee565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d4f91906151ae565b15611d86576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151516000819003611dc3576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114611e01576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff811115611e1c57611e1c613ff1565b604051908082528060200260200182016040528015611e45578160200160208202803683370190505b50905060005b82811015611f1d57600085600001518281518110611e6b57611e6b614cf4565b60200260200101519050611e9f817f0000000000000000000000000000000000000000000000000000000000000000612b4c565b838381518110611eb157611eb1614cf4565b602002602001018181525050806101800151838381518110611ed557611ed5614cf4565b602002602001015114611f14576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101611e4b565b50604080850151606086015191517f320488750000000000000000000000000000000000000000000000000000000081526000926001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692633204887592611f91928792916004016151fc565b602060405180830381865afa158015611fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd29190615232565b90508060000361200e576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b848110156126945760008760000151828151811061203557612035614cf4565b60200260200101519050600061204e826060015161062f565b9050600081600381111561206457612064613f3d565b14806120815750600381600381111561207f5761207f613f3d565b145b6120c757816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a2505061268c565b831561218457600a5460009063ffffffff166120e38742614c33565b11905080806121035750600382600381111561210157612101613f3d565b145b612139576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88848151811061214b5761214b614cf4565b602002602001015160001461217e5788848151811061216c5761216c614cf4565b60200260200101518360800181815250505b506121e7565b600081600381111561219857612198613f3d565b146121e757606082015160405167ffffffffffffffff90911681527f67d9ba0f63d427c482c2736300e6d5a34c6691dbcdea8ad35828a1f1ba47e8729060200160405180910390a1505061268c565b60c082015167ffffffffffffffff1615612466576020808301516001600160a01b03166000908152600f909152604081205467ffffffffffffffff16908190036123d1577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156123d15760208301516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa1580156122e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123049190614ddc565b60c084015190915067ffffffffffffffff1661232182600161524b565b67ffffffffffffffff16146123815782602001516001600160a01b03168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a350505061268c565b6020838101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b60008260038111156123e5576123e5613f3d565b036124645760c083015167ffffffffffffffff1661240482600161524b565b67ffffffffffffffff16146124645782602001516001600160a01b03168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a350505061268c565b505b60008960200151848151811061247e5761247e614cf4565b602002602001015190506124aa8360600151846000015185610140015151866101200151518551612ca7565b6124b983606001516001612e21565b6000806124c68584612ecb565b915091506124d8856060015183612e21565b86156125445760038260038111156124f2576124f2613f3d565b0361254457600084600381111561250b5761250b613f3d565b1461254457806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016106ee9190613fde565b600282600381111561255857612558613f3d565b146125b057600382600381111561257157612571613f3d565b146125b0578460600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016106ee92919061526c565b60c085015167ffffffffffffffff16156126385760008460038111156125d8576125d8613f3d565b03612638576020808601516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff16916126108361528a565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b846101800151856060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef65848460405161267e9291906152a7565b60405180910390a350505050505b600101612015565b50505050505050565b6000610f4f836001600160a01b038416612f94565b60006126c8846001600160a01b03851684612fa0565b949350505050565b6126f36126df828401846152c7565b604080516000815260208101909152611c71565b5050565b815460009061272090700100000000000000000000000000000000900463ffffffff1642614c33565b905080156127c25760018301548354612768916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b2d565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546127e8916fffffffffffffffffffffffffffffffff9081169116612fb6565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906128cf9084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106a482612fcc565b60008080806128f68686612fd7565b909450925050505b9250929050565b336001600160a01b03821603612977576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106ee565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b846000805b8751811015612af657612a5d888281518110612a0357612a03614cf4565b6020026020010151602001518888888581518110612a2357612a23614cf4565b6020026020010151806020019051810190612a3e91906152fc565b888681518110612a5057612a50614cf4565b6020026020010151612fe6565b838281518110612a6f57612a6f614cf4565b6020026020010181905250612aab838281518110612a8f57612a8f614cf4565b602002602001015160000151600c6133ee90919063ffffffff16565b15612aee57612ae1838281518110612ac557612ac5614cf4565b6020908102919091010151600b546001600160a01b0316613403565b612aeb9083614df9565b91505b6001016129e5565b508015612b0657612b0681613524565b505b95945050505050565b6000612b1c83613531565b8015610f4f5750610f4f8383613595565b6000612b0885612b3d8486614c9c565b612b479087614df9565b612fb6565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612be29897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612c1b91906153c2565b60405160208183030381529060405280519060200120876101600151604051602001612c47919061542f565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff1614612d20576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016106ee565b600a5468010000000000000000900461ffff16831115612d78576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b808314612dbd576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b600a54640100000000900463ffffffff1682111561176a57600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff166004820152602481018390526044016106ee565b60006002612e30608085614c75565b67ffffffffffffffff16612e449190614c9c565b90506000601081612e56608087614cb3565b67ffffffffffffffff168152602081019190915260400160002054905081612e8060016004614c33565b901b191681836003811115612e9757612e97613f3d565b901b178060106000612eaa608088614cb3565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a590612f0f9087908790600401615442565b600060405180830381600087803b158015612f2957600080fd5b505af1925050508015612f3a575060015b612f79573d808015612f68576040519150601f19603f3d011682016040523d82523d6000602084013e612f6d565b606091505b506003925090506128fe565b50506040805160208101909152600081526002909250929050565b6000610f4f8383613664565b60006126c884846001600160a01b038516613681565b6000818310612fc55781610f4f565b5090919050565b60006106a48261369e565b60008080806128f686866136a9565b6040805180820190915260008082526020820152600061300984602001516136d4565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa15801561308e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130b291906155a5565b90506001600160a01b03811615806130fa57506130f86001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612b11565b155b1561313c576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016106ee565b60008060006132416040518061010001604052808c81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018b6001600160a01b031681526020018d8152602001876001600160a01b031681526020018a6000015181526020018a604001518152602001898152506040516024016131d291906155c2565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905260608a0151869063ffffffff16611388608461377a565b9250925092508261328057816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190613fde565b81516020146132c85781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b6000828060200190518101906132de9190615232565b6040516001600160a01b0380881660248301528c166044820152606481018290529091506133839060840160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905260608b0151889061337990869063ffffffff16614c33565b611388608461377a565b509094509250836133c257826040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190613fde565b604080518082019091526001600160a01b03909616865260208601525092935050505095945050505050565b6000610f4f836001600160a01b0384166138a0565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613469573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348d9190615699565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036134f65783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016106ee565b60208401516126c8907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316906138ac565b61139760038260006138e9565b600061355d827f01ffc9a700000000000000000000000000000000000000000000000000000000613595565b80156106a4575061358e827fffffffff00000000000000000000000000000000000000000000000000000000613595565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561364d575060208210155b80156136595750600081115b979650505050505050565b60008181526002830160205260408120819055610f4f8383613c38565b600082815260028401602052604081208290556126c88484613c44565b60006106a482613c50565b600080806136b78585613c5a565b600081815260029690960160205260409095205494959350505050565b6000815160201461371357816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190613fde565b6000828060200190518101906137299190615232565b90506001600160a01b03811180613741575061040081105b156106a457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190613fde565b6000606060008361ffff1667ffffffffffffffff81111561379d5761379d613ff1565b6040519080825280601f01601f1916602001820160405280156137c7576020820181803683370190505b509150863b6137fa577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a8581101561382d577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613866577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156138895750835b808352806000602085013e50955095509592505050565b6000610f4f8383613c66565b6000670de0b6b3a76400006138df837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616614c9c565b610f4f91906156f9565b825474010000000000000000000000000000000000000000900460ff161580613910575081155b1561391a57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061396090700100000000000000000000000000000000900463ffffffff1642614c33565b90508015613a2057818311156139a2576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546139dc9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b2d565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613abd576001600160a01b038416613a72576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106ee565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b03851660448201526064016106ee565b84831015613bb65760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613b019082614c33565b613b0b878a614c33565b613b159190614df9565b613b1f91906156f9565b90506001600160a01b038616613b6b576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106ee565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b03871660448201526064016106ee565b613bc08584614c33565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f4f8383613c85565b6000610f4f8383613d7f565b60006106a4825490565b6000610f4f8383613dce565b6000610f4f838360008181526001830160205260408120541515610f4f565b60008181526001830160205260408120548015613d6e576000613ca9600183614c33565b8554909150600090613cbd90600190614c33565b9050818114613d22576000866000018281548110613cdd57613cdd614cf4565b9060005260206000200154905080876000018481548110613d0057613d00614cf4565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613d3357613d3361570d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106a4565b60009150506106a4565b5092915050565b6000818152600183016020526040812054613dc6575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106a4565b5060006106a4565b6000826000018281548110613de557613de5614cf4565b9060005260206000200154905092915050565b828054828255906000526020600020908101928215613e65579160200282015b82811115613e6557825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190613e18565b50613e71929150613e75565b5090565b5b80821115613e715760008155600101613e76565b60e081016106a482846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff8116811461139757600080fd5b8035613f1b81613efa565b919050565b600060208284031215613f3257600080fd5b8135610f4f81613efa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110613f7c57613f7c613f3d565b9052565b602081016106a48284613f6c565b60005b83811015613fa9578181015183820152602001613f91565b50506000910152565b60008151808452613fca816020860160208601613f8e565b601f01601f19169290920160200192915050565b602081526000610f4f6020830184613fb2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561404357614043613ff1565b60405290565b6040516101a0810167ffffffffffffffff8111828210171561404357614043613ff1565b6040516080810167ffffffffffffffff8111828210171561404357614043613ff1565b604051601f8201601f1916810167ffffffffffffffff811182821017156140b9576140b9613ff1565b604052919050565b600067ffffffffffffffff8211156140db576140db613ff1565b5060051b60200190565b6001600160a01b038116811461139757600080fd5b8035613f1b816140e5565b600082601f83011261411657600080fd5b8135602061412b614126836140c1565b614090565b8083825260208201915060208460051b87010193508684111561414d57600080fd5b602086015b84811015614172578035614165816140e5565b8352918301918301614152565b509695505050505050565b803560ff81168114613f1b57600080fd5b600067ffffffffffffffff8211156141a8576141a8613ff1565b50601f01601f191660200190565b600082601f8301126141c757600080fd5b81356141d56141268261418e565b8181528460208386010111156141ea57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561422057600080fd5b863567ffffffffffffffff8082111561423857600080fd5b6142448a838b01614105565b9750602089013591508082111561425a57600080fd5b6142668a838b01614105565b965061427460408a0161417d565b9550606089013591508082111561428a57600080fd5b6142968a838b016141b6565b94506142a460808a01613f10565b935060a08901359150808211156142ba57600080fd5b506142c789828a016141b6565b9150509295509295509295565b60008151808452602080850194506020840160005b8381101561430e5781516001600160a01b0316875295820195908201906001016142e9565b509495945050505050565b602081526000610f4f60208301846142d4565b60006020828403121561433e57600080fd5b8135610f4f816140e5565b801515811461139757600080fd5b8035613f1b81614349565b600082601f83011261437357600080fd5b81356020614383614126836140c1565b82815260069290921b840181019181810190868411156143a257600080fd5b8286015b8481101561417257604081890312156143bf5760008081fd5b6143c7614020565b81356143d2816140e5565b815281850135858201528352918301916040016143a6565b600082601f8301126143fb57600080fd5b8135602061440b614126836140c1565b82815260059290921b8401810191818101908684111561442a57600080fd5b8286015b8481101561417257803567ffffffffffffffff81111561444e5760008081fd5b61445c8986838b01016141b6565b84525091830191830161442e565b60006101a0828403121561447d57600080fd5b614485614049565b905061449082613f10565b815261449e602083016140fa565b60208201526144af604083016140fa565b60408201526144c060608301613f10565b6060820152608082013560808201526144db60a08301614357565b60a08201526144ec60c08301613f10565b60c08201526144fd60e083016140fa565b60e082015261010082810135908201526101208083013567ffffffffffffffff8082111561452a57600080fd5b614536868387016141b6565b8385015261014092508285013591508082111561455257600080fd5b61455e86838701614362565b8385015261016092508285013591508082111561457a57600080fd5b50614587858286016143ea565b82840152505061018080830135818301525092915050565b600082601f8301126145b057600080fd5b813560206145c0614126836140c1565b82815260059290921b840181019181810190868411156145df57600080fd5b8286015b8481101561417257803567ffffffffffffffff8111156146035760008081fd5b6146118986838b01016143ea565b8452509183019183016145e3565b600082601f83011261463057600080fd5b81356020614640614126836140c1565b8083825260208201915060208460051b87010193508684111561466257600080fd5b602086015b848110156141725780358352918301918301614667565b60006080828403121561469057600080fd5b61469861406d565b9050813567ffffffffffffffff808211156146b257600080fd5b818401915084601f8301126146c657600080fd5b813560206146d6614126836140c1565b82815260059290921b840181019181810190888411156146f557600080fd5b8286015b8481101561472d578035868111156147115760008081fd5b61471f8b86838b010161446a565b8452509183019183016146f9565b508652508581013593508284111561474457600080fd5b6147508785880161459f565b9085015250604084013591508082111561476957600080fd5b506147768482850161461f565b6040830152506060820135606082015292915050565b6000806040838503121561479f57600080fd5b823567ffffffffffffffff808211156147b757600080fd5b6147c38683870161467e565b93506020915081850135818111156147da57600080fd5b85019050601f810186136147ed57600080fd5b80356147fb614126826140c1565b81815260059190911b8201830190838101908883111561481a57600080fd5b928401925b828410156148385783358252928401929084019061481f565b80955050505050509250929050565b60a081016106a4828463ffffffff8082511683528060208301511660208401525061ffff604082015116604083015260608101516001600160a01b03808216606085015280608084015116608085015250505050565b6000602082840312156148af57600080fd5b813567ffffffffffffffff8111156148c657600080fd5b820160a08185031215610f4f57600080fd5b600082601f8301126148e957600080fd5b813560206148f9614126836140c1565b82815260069290921b8401810191818101908684111561491857600080fd5b8286015b8481101561417257604081890312156149355760008081fd5b61493d614020565b8135614948816140e5565b815281850135614957816140e5565b8186015283529183019160400161491c565b6000806040838503121561497c57600080fd5b823567ffffffffffffffff8082111561499457600080fd5b6149a0868387016148d8565b935060208501359150808211156149b657600080fd5b506149c3858286016148d8565b9150509250929050565b60008083601f8401126149df57600080fd5b50813567ffffffffffffffff8111156149f757600080fd5b6020830191508360208260051b85010111156128fe57600080fd5b60008060008060008060008060e0898b031215614a2e57600080fd5b606089018a811115614a3f57600080fd5b8998503567ffffffffffffffff80821115614a5957600080fd5b818b0191508b601f830112614a6d57600080fd5b813581811115614a7c57600080fd5b8c6020828501011115614a8e57600080fd5b6020830199508098505060808b0135915080821115614aac57600080fd5b614ab88c838d016149cd565b909750955060a08b0135915080821115614ad157600080fd5b50614ade8b828c016149cd565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff81168114613f1b57600080fd5b600060608284031215614b2957600080fd5b6040516060810181811067ffffffffffffffff82111715614b4c57614b4c613ff1565b6040528235614b5a81614349565b8152614b6860208401614af7565b6020820152614b7960408401614af7565b60408201529392505050565b604081526000614b9860408301856142d4565b8281036020840152612b0881856142d4565b60008060408385031215614bbd57600080fd5b823567ffffffffffffffff80821115614bd557600080fd5b614be18683870161446a565b93506020850135915080821115614bf757600080fd5b506149c3858286016143ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106a4576106a4614c04565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680614c9057614c90614c46565b92169190910692915050565b80820281158282048414176106a4576106a4614c04565b600067ffffffffffffffff80841680614cce57614cce614c46565b92169190910492915050565b6020810160038310614cee57614cee613f3d565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103614d3c57614d3c614c04565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614d768184018a6142d4565b90508281036080840152614d8a81896142d4565b905060ff871660a084015282810360c0840152614da78187613fb2565b905067ffffffffffffffff851660e0840152828103610100840152614dcc8185613fb2565b9c9b505050505050505050505050565b600060208284031215614dee57600080fd5b8151610f4f81613efa565b808201808211156106a4576106a4614c04565b60008151808452602080850194506020840160005b8381101561430e57815180516001600160a01b031688528301518388015260409096019590820190600101614e21565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152614e8c610120840182613fb2565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e0860152614ec88383613fb2565b925060808901519150808584030161010086015250614ee78282614e0c565b92505050614efb602083018661ffff169052565b836040830152612b0860608301846001600160a01b03169052565b600082601f830112614f2757600080fd5b8151614f356141268261418e565b818152846020838601011115614f4a57600080fd5b6126c8826020830160208701613f8e565b600080600060608486031215614f7057600080fd5b8351614f7b81614349565b602085015190935067ffffffffffffffff811115614f9857600080fd5b614fa486828701614f16565b925050604084015190509250925092565b805163ffffffff81168114613f1b57600080fd5b600060a08284031215614fdb57600080fd5b60405160a0810181811067ffffffffffffffff82111715614ffe57614ffe613ff1565b60405261500a83614fb5565b815261501860208401614fb5565b6020820152604083015161ffff8116811461503257600080fd5b60408201526060830151615045816140e5565b60608201526080830151615058816140e5565b60808201529392505050565b61018081016150d582856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff1661012083015260608301516001600160a01b03908116610140840152608084015116610160830152610f4f565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526151608285018b6142d4565b91508382036080850152615174828a6142d4565b915060ff881660a085015283820360c08501526151918288613fb2565b90861660e08501528381036101008501529050614dcc8185613fb2565b6000602082840312156151c057600080fd5b8151610f4f81614349565b60008151808452602080850194506020840160005b8381101561430e578151875295820195908201906001016151e0565b60608152600061520f60608301866151cb565b828103602084015261522181866151cb565b915050826040830152949350505050565b60006020828403121561524457600080fd5b5051919050565b67ffffffffffffffff818116838216019080821115613d7857613d78614c04565b67ffffffffffffffff8316815260408101610f4f6020830184613f6c565b600067ffffffffffffffff808316818103614d3c57614d3c614c04565b6152b18184613f6c565b6040602082015260006126c86040830184613fb2565b6000602082840312156152d957600080fd5b813567ffffffffffffffff8111156152f057600080fd5b6126c88482850161467e565b60006020828403121561530e57600080fd5b815167ffffffffffffffff8082111561532657600080fd5b908301906080828603121561533a57600080fd5b61534261406d565b82518281111561535157600080fd5b61535d87828601614f16565b82525060208301518281111561537257600080fd5b61537e87828601614f16565b60208301525060408301518281111561539657600080fd5b6153a287828601614f16565b6040830152506153b460608401614fb5565b606082015295945050505050565b602081526000610f4f6020830184614e0c565b60008282518085526020808601955060208260051b8401016020860160005b8481101561542257601f19868403018952615410838351613fb2565b988401989250908301906001016153f4565b5090979650505050505050565b602081526000610f4f60208301846153d5565b6040815261545d60408201845167ffffffffffffffff169052565b6000602084015161547960608401826001600160a01b03169052565b5060408401516001600160a01b038116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c08401516101006154da8185018367ffffffffffffffff169052565b60e086015191506101206154f8818601846001600160a01b03169052565b81870151925061014091508282860152808701519250506101a061016081818701526155286101e0870185613fb2565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc06101808188870301818901526155678686614e0c565b9550828a0151945081888703018489015261558286866153d5565b9550808a01516101c089015250505050508281036020840152612b0881856153d5565b6000602082840312156155b757600080fd5b8151610f4f816140e5565b60208152600082516101008060208501526155e1610120850183613fb2565b915060208501516155fe604086018267ffffffffffffffff169052565b5060408501516001600160a01b03811660608601525060608501516080850152608085015161563860a08601826001600160a01b03169052565b5060a0850151601f19808685030160c08701526156558483613fb2565b935060c08701519150808685030160e08701526156728483613fb2565b935060e087015191508086850301838701525061568f8382613fb2565b9695505050505050565b6000604082840312156156ab57600080fd5b6156b3614020565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146156df57600080fd5b81526156ed60208401614fb5565b60208201529392505050565b60008261570857615708614c46565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101a06040523480156200001257600080fd5b506040516200663d3803806200663d8339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f74620006c96000396000818161032001528181611cdd01526134570152600081816102e401528181611cb50152611f670152600081816102a801528181610f830152818161100201528181611c8b015281816124df01526125630152600061211301526000818161026c0152611c6101526000818161020c0152611c0501526000818161023c01528181611c3901528181611f240152818161309801526135ab0152600081816101d001528181611be00152612200015260008181611e7e0152611eca0152615f746000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806381ff7048116100d8578063afcb95d71161008c578063f077b59211610066578063f077b59214610668578063f2fde38b1461067e578063f52121a51461069157600080fd5b8063afcb95d714610622578063b1dc65a414610642578063c92b28321461065557600080fd5b8063856c8247116100bd578063856c8247146105c5578063873504d7146105f15780638da5cb5b1461060457600080fd5b806381ff70481461058757806385572ffb146105b757600080fd5b8063599f64311161013a578063740f415011610114578063740f4150146104bc5780637437ff9f146104cf57806379ba50971461057f57600080fd5b8063599f643114610455578063666cab8d14610494578063704b6c02146104a957600080fd5b8063181f5a771161016b578063181f5a77146103935780631ef38174146103dc578063546719cd146103f157600080fd5b806306285c6914610187578063142a98fc14610373575b600080fd5b61035d6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161036a919061448b565b60405180910390f35b61038661038136600461452e565b6106a4565b60405161036a919061458e565b6103cf6040518060400160405280601881526020017f45564d3245564d4f666652616d7020312e352e302d646576000000000000000081525081565b60405161036a91906145ec565b6103ef6103ea366004614822565b61071f565b005b6103f9610b47565b60405161036a919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161036a565b61049c610bfc565b60405161036a9190614941565b6103ef6104b7366004614954565b610c6b565b6103ef6104ca366004614dbe565b610d5b565b6105726040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a010000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff9081166060830152600b5416608082015290565b60405161036a9190614e79565b6103ef610e4d565b6007546005546040805163ffffffff8085168252640100000000909404909316602084015282015260600161036a565b6103ef610182366004614edc565b6105d86105d3366004614954565b610f4a565b60405167ffffffffffffffff909116815260200161036a565b6103ef6105ff366004614fa8565b611074565b60005473ffffffffffffffffffffffffffffffffffffffff1661046f565b60408051600181526000602082018190529181019190915260600161036a565b6103ef610650366004615051565b61125c565b6103ef610663366004615156565b611474565b6106706114f9565b60405161036a9291906151c4565b6103ef61068c366004614954565b611646565b6103ef61069f3660046151e9565b611657565b60006106b26001600461528a565b60026106bf6080856152cc565b67ffffffffffffffff166106d391906152f3565b601060006106e260808761530a565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156107195761071961454b565b92915050565b84518460ff16601f82111561076c5760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016107639190615331565b60405180910390fd5b806000036107a95760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016107639190615331565b6107b16119d5565b6107ba85611a58565b60095460005b8181101561083e5760086000600983815481106107df576107df61534b565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556001016107c0565b5050865160005b81811015610a085760008982815181106108615761086161534b565b602002602001015190506000600281111561087e5761087e61454b565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260086020526040902054610100900460ff1660028111156108bd576108bd61454b565b146108f75760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016107639190615331565b73ffffffffffffffffffffffffffffffffffffffff8116610944576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156109f4576109f461454b565b021790555090505050806001019050610845565b508751610a1c9060099060208b01906143ec565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a161717905560078054610aa2914691309190600090610a749063ffffffff1661537a565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611d3c565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610b339487949293918316921691909117908f908f908f908f908f908f9061539d565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610bf790611dc9565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610c6157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610c36575b5050505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610cab575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610ce2576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b610d63611e7b565b81515181518114610da0576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610e3d576000838281518110610dbf57610dbf61534b565b6020026020010151905080600014610e34578451805183908110610de557610de561534b565b602002602001015160800151811015610e34576040517f085e39cf0000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610763565b50600101610da3565b50610e488383611efc565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610763565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600f602052604081205467ffffffffffffffff16808203610719577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615610719576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190615433565b9392505050565b61107c6119d5565b60005b825181101561115c576110b983828151811061109d5761109d61534b565b602002602001015160200151600c61299d90919063ffffffff16565b15611154577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d587828382815181106110f1576110f161534b565b60200260200101516000015184838151811061110f5761110f61534b565b60200260200101516020015160405161114b92919073ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b60405180910390a15b60010161107f565b5060005b8151811015610e48576111b982828151811061117e5761117e61534b565b60200260200101516020015183838151811061119c5761119c61534b565b602002602001015160000151600c6129bf9092919063ffffffff16565b15611254577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a8282815181106111f1576111f161534b565b60200260200101516000015183838151811061120f5761120f61534b565b60200260200101516020015160405161124b92919073ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b60405180910390a15b600101611160565b61126687876129ea565b6005548835908082146112af576040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610763565b6112b7611e7b565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561133f5761133f61454b565b60028111156113505761135061454b565b905250905060028160200151600281111561136d5761136d61454b565b1480156113b457506009816000015160ff168154811061138f5761138f61534b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6113ea576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006113f88560206152f3565b6114038860206152f3565b61140f8b610144615450565b6114199190615450565b6114239190615450565b9050368114611467576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610763565b5050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906114b4575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156114eb576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114f6600382612a11565b50565b6060806000611508600c612bf6565b90508067ffffffffffffffff811115611523576115236145ff565b60405190808252806020026020018201604052801561154c578160200160208202803683370190505b5092508067ffffffffffffffff811115611568576115686145ff565b604051908082528060200260200182016040528015611591578160200160208202803683370190505b50915060005b81811015611640576000806115ad600c84612c01565b91509150808684815181106115c4576115c461534b565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050818584815181106116115761161161534b565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101525050600101611597565b50509091565b61164e6119d5565b6114f681612c1f565b333014611690576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600080825260208201909252816116cd565b60408051808201909152600080825260208201528152602001906001900390816116a65790505b50905060006116e0610140860186615463565b90501115611763576117606116f9610140860186615463565b6117096040880160208901614954565b6040805173ffffffffffffffffffffffffffffffffffffffff90921660208301520160408051601f1981840301815291815261174b9060608a01908a01614954565b6117596101608a018a6154cb565b8989612d14565b90505b611771610120850185615533565b159050801561178257506080840135155b806117b157506117986060850160408601614954565b73ffffffffffffffffffffffffffffffffffffffff163b155b8061180957506118077f85572ffb000000000000000000000000000000000000000000000000000000006117eb6060870160408801614954565b73ffffffffffffffffffffffffffffffffffffffff1690612eea565b155b156118145750505050565b600a546040805160a08101909152610180860135815260009182916a010000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff1690633cf979839060208082019061186d908b018b61452e565b67ffffffffffffffff16815260200189602001602081019061188f9190614954565b6040805173ffffffffffffffffffffffffffffffffffffffff90921660208301520160408051601f1981840301815291905281526020016118d46101208b018b615533565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200186905261138860808a013561192960608c0160408d01614954565b6040518563ffffffff1660e01b815260040161194894939291906155ea565b6000604051808303816000875af1158015611967573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261198f91908101906156bc565b5091509150816119cd57806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161076391906145ec565b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610763565b565b600081806020019051810190611a6e9190615764565b606081015190915073ffffffffffffffffffffffffffffffffffffffff16611ac2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a010000000000000000000073ffffffffffffffffffffffffffffffffffffffff9485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611d30918490615803565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611d60999897969594939291906158df565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611e5782606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611e3b919061528a565b85608001516fffffffffffffffffffffffffffffffff16612f06565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b467f000000000000000000000000000000000000000000000000000000000000000014611a56576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610763565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe79190615974565b1561201e576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815151600081900361205b576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114612099576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156120b4576120b46145ff565b6040519080825280602002602001820160405280156120dd578160200160208202803683370190505b50905060005b828110156121b5576000856000015182815181106121035761210361534b565b60200260200101519050612137817f0000000000000000000000000000000000000000000000000000000000000000612f2e565b8383815181106121495761214961534b565b60200260200101818152505080610180015183838151811061216d5761216d61534b565b6020026020010151146121ac576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001016120e3565b50604080850151606086015191517f3204887500000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001692633204887592612236928792916004016159c2565b602060405180830381865afa158015612253573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227791906159f8565b9050806000036122b3576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b84811015612994576000876000015182815181106122da576122da61534b565b6020026020010151905060006122f382606001516106a4565b905060008160038111156123095761230961454b565b1480612326575060038160038111156123245761232461454b565b145b61236c57816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a2505061298c565b831561242957600a5460009063ffffffff16612388874261528a565b11905080806123a8575060038260038111156123a6576123a661454b565b145b6123de576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8884815181106123f0576123f061534b565b6020026020010151600014612423578884815181106124115761241161534b565b60200260200101518360800181815250505b5061248c565b600081600381111561243d5761243d61454b565b1461248c57606082015160405167ffffffffffffffff90911681527f67d9ba0f63d427c482c2736300e6d5a34c6691dbcdea8ad35828a1f1ba47e8729060200160405180910390a1505061298c565b60c082015167ffffffffffffffff16156127595760208083015173ffffffffffffffffffffffffffffffffffffffff166000908152600f909152604081205467ffffffffffffffff16908190036126b7577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16156126b75760208301516040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa1580156125ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d09190615433565b60c084015190915067ffffffffffffffff166125ed826001615a11565b67ffffffffffffffff161461265a57826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a350505061298c565b60208381015173ffffffffffffffffffffffffffffffffffffffff166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b60008260038111156126cb576126cb61454b565b036127575760c083015167ffffffffffffffff166126ea826001615a11565b67ffffffffffffffff161461275757826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a350505061298c565b505b6000896020015184815181106127715761277161534b565b6020026020010151905061279d8360600151846000015185610140015151866101200151518551613096565b6127ac83606001516001613217565b6000806127b985846132c1565b915091506127cb856060015183613217565b86156128375760038260038111156127e5576127e561454b565b036128375760008460038111156127fe576127fe61454b565b1461283757806040517fcf19edfd00000000000000000000000000000000000000000000000000000000815260040161076391906145ec565b600282600381111561284b5761284b61454b565b146128a35760038260038111156128645761286461454b565b146128a3578460600151826040517f9e261603000000000000000000000000000000000000000000000000000000008152600401610763929190615a32565b60c085015167ffffffffffffffff16156129385760008460038111156128cb576128cb61454b565b036129385760208086015173ffffffffffffffffffffffffffffffffffffffff166000908152600f90915260408120805467ffffffffffffffff169161291083615a50565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b846101800151856060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef65848460405161297e929190615a6d565b60405180910390a350505050505b6001016122ba565b50505050505050565b600061106d8373ffffffffffffffffffffffffffffffffffffffff841661338a565b60006129e28473ffffffffffffffffffffffffffffffffffffffff851684613396565b949350505050565b612a0d6129f982840184615a8d565b604080516000815260208101909152611efc565b5050565b8154600090612a3a90700100000000000000000000000000000000900463ffffffff164261528a565b90508015612adc5760018301548354612a82916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612f06565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612b02916fffffffffffffffffffffffffffffffff90811691166133b9565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612be99084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b6000610719826133cf565b6000808080612c1086866133da565b909450925050505b9250929050565b3373ffffffffffffffffffffffffffffffffffffffff821603612c9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610763565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60608888808060200260200160405190810160405280939291908181526020016000905b82821015612d6457612d5560408302860136819003810190615ac2565b81526020019060010190612d38565b505050505090506000805b89811015612ecd57612e278b8b83818110612d8c57612d8c61534b565b905060400201602001358a8a8a8a86818110612daa57612daa61534b565b9050602002810190612dbc9190615533565b810190612dc99190615ade565b898987818110612ddb57612ddb61534b565b9050602002810190612ded9190615533565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506133e992505050565b838281518110612e3957612e3961534b565b6020026020010181905250612e75838281518110612e5957612e5961534b565b602002602001015160000151600c61382a90919063ffffffff16565b15612ec557612eb8838281518110612e8f57612e8f61534b565b6020908102919091010151600b5473ffffffffffffffffffffffffffffffffffffffff1661384c565b612ec29083615450565b91505b600101612d6f565b508015612edd57612edd81613987565b5098975050505050505050565b6000612ef583613994565b801561106d575061106d83836139f8565b6000612f2585612f1684866152f3565b612f209087615450565b6133b9565b95945050505050565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612fd198979695949392919073ffffffffffffffffffffffffffffffffffffffff9889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b604051602081830303815290604052805190602001208561012001518051906020012086610140015160405160200161300a9190615baa565b604051602081830303815290604052805190602001208761016001516040516020016130369190615c17565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff161461310f576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610763565b600a5468010000000000000000900461ffff16831115613167576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610763565b8083146131ac576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610763565b600a54640100000000900463ffffffff1682111561321057600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff16600482015260248101839052604401610763565b5050505050565b600060026132266080856152cc565b67ffffffffffffffff1661323a91906152f3565b9050600060108161324c60808761530a565b67ffffffffffffffff1681526020810191909152604001600020549050816132766001600461528a565b901b19168183600381111561328d5761328d61454b565b901b1780601060006132a060808861530a565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a5906133059087908790600401615c2a565b600060405180830381600087803b15801561331f57600080fd5b505af1925050508015613330575060015b61336f573d80801561335e576040519150601f19603f3d011682016040523d82523d6000602084013e613363565b606091505b50600392509050612c18565b50506040805160208101909152600081526002909250929050565b600061106d8383613ac7565b60006129e2848473ffffffffffffffffffffffffffffffffffffffff8516613ae4565b60008183106133c8578161106d565b5090919050565b600061071982613b01565b6000808080612c108686613b0c565b6040805180820190915260008082526020820152600061340c8460200151613b37565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa15801561349e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c29190615db4565b905073ffffffffffffffffffffffffffffffffffffffff81161580613524575061352273ffffffffffffffffffffffffffffffffffffffff82167faff2afbf00000000000000000000000000000000000000000000000000000000612eea565b155b15613573576040517fae9b4ce900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610763565b60008061358b8885896060015163ffffffff16613bea565b9150915060008060006136a36040518061010001604052808e81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff1681526020018f81526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018c6000015181526020018c6040015181526020018b81525060405160240161363f9190615dd1565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613d3a565b925092509250826136e257816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161076391906145ec565b815160201461372a5781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610763565b60008280602001905181019061374091906159f8565b90508673ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff16146137ef57600061378b8d8a613786868a61528a565b613bea565b509050868110806137a55750816137a2888361528a565b14155b156137ed576040517fa966e21f000000000000000000000000000000000000000000000000000000008152600481018390526024810188905260448101829052606401610763565b505b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff9098168852602088015250949550505050505095945050505050565b600061106d8373ffffffffffffffffffffffffffffffffffffffff8416613e60565b81516040517fd02641a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015260009182919084169063d02641a0906024016040805180830381865afa1580156138bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138e39190615ec2565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036139595783516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610763565b60208401516129e2907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690613e6c565b6114f66003826000613ea9565b60006139c0827f01ffc9a7000000000000000000000000000000000000000000000000000000006139f8565b801561071957506139f1827fffffffff000000000000000000000000000000000000000000000000000000006139f8565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613ab0575060208210155b8015613abc5750600081115b979650505050505050565b6000818152600283016020526040812081905561106d838361422c565b600082815260028401602052604081208290556129e28484614238565b600061071982614244565b60008080613b1a858561424e565b600081815260029690960160205260409095205494959350505050565b60008151602014613b7657816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161076391906145ec565b600082806020019051810190613b8c91906159f8565b905073ffffffffffffffffffffffffffffffffffffffff811180613bb1575061040081105b1561071957826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161076391906145ec565b6000806000806000613c8688604051602401613c22919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613d3a565b92509250925082613cc557816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161076391906145ec565b6020825114613d0d5781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610763565b81806020019051810190613d2191906159f8565b613d2b828861528a565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613d5d57613d5d6145ff565b6040519080825280601f01601f191660200182016040528015613d87576020820181803683370190505b509150863b613dba577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613ded577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613e26577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613e495750835b808352806000602085013e50955095509592505050565b600061106d838361425a565b6000670de0b6b3a7640000613e9f837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166152f3565b61106d9190615f24565b825474010000000000000000000000000000000000000000900460ff161580613ed0575081155b15613eda57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090613f2090700100000000000000000000000000000000900463ffffffff164261528a565b90508015613fe05781831115613f62576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613f9c9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612f06565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156140975773ffffffffffffffffffffffffffffffffffffffff841661403f576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610763565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610763565b848310156141aa5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906140db908261528a565b6140e5878a61528a565b6140ef9190615450565b6140f99190615f24565b905073ffffffffffffffffffffffffffffffffffffffff8616614152576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610763565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610763565b6141b4858461528a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600061106d8383614279565b600061106d8383614373565b6000610719825490565b600061106d83836143c2565b600061106d83836000818152600183016020526040812054151561106d565b6000818152600183016020526040812054801561436257600061429d60018361528a565b85549091506000906142b19060019061528a565b90508181146143165760008660000182815481106142d1576142d161534b565b90600052602060002001549050808760000184815481106142f4576142f461534b565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061432757614327615f38565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610719565b6000915050610719565b5092915050565b60008181526001830160205260408120546143ba57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610719565b506000610719565b60008260000182815481106143d9576143d961534b565b9060005260206000200154905092915050565b828054828255906000526020600020908101928215614466579160200282015b8281111561446657825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061440c565b50614472929150614476565b5090565b5b808211156144725760008155600101614477565b60e08101610719828473ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff811681146114f657600080fd5b803561452981614508565b919050565b60006020828403121561454057600080fd5b813561106d81614508565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6004811061458a5761458a61454b565b9052565b60208101610719828461457a565b60005b838110156145b757818101518382015260200161459f565b50506000910152565b600081518084526145d881602086016020860161459c565b601f01601f19169290920160200192915050565b60208152600061106d60208301846145c0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715614651576146516145ff565b60405290565b6040516080810167ffffffffffffffff81118282101715614651576146516145ff565b6040516101a0810167ffffffffffffffff81118282101715614651576146516145ff565b604051601f8201601f1916810167ffffffffffffffff811182821017156146c7576146c76145ff565b604052919050565b600067ffffffffffffffff8211156146e9576146e96145ff565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146114f657600080fd5b8035614529816146f3565b600082601f83011261473157600080fd5b81356020614746614741836146cf565b61469e565b8083825260208201915060208460051b87010193508684111561476857600080fd5b602086015b8481101561478d578035614780816146f3565b835291830191830161476d565b509695505050505050565b803560ff8116811461452957600080fd5b600067ffffffffffffffff8211156147c3576147c36145ff565b50601f01601f191660200190565b600082601f8301126147e257600080fd5b81356147f0614741826147a9565b81815284602083860101111561480557600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561483b57600080fd5b863567ffffffffffffffff8082111561485357600080fd5b61485f8a838b01614720565b9750602089013591508082111561487557600080fd5b6148818a838b01614720565b965061488f60408a01614798565b955060608901359150808211156148a557600080fd5b6148b18a838b016147d1565b94506148bf60808a0161451e565b935060a08901359150808211156148d557600080fd5b506148e289828a016147d1565b9150509295509295509295565b60008151808452602080850194506020840160005b8381101561493657815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614904565b509495945050505050565b60208152600061106d60208301846148ef565b60006020828403121561496657600080fd5b813561106d816146f3565b80151581146114f657600080fd5b803561452981614971565b60006040828403121561499c57600080fd5b6149a461462e565b905081356149b1816146f3565b808252506020820135602082015292915050565b600082601f8301126149d657600080fd5b813560206149e6614741836146cf565b8083825260208201915060208460061b870101935086841115614a0857600080fd5b602086015b8481101561478d57614a1f888261498a565b835291830191604001614a0d565b600082601f830112614a3e57600080fd5b81356020614a4e614741836146cf565b82815260059290921b84018101918181019086841115614a6d57600080fd5b8286015b8481101561478d57803567ffffffffffffffff811115614a915760008081fd5b614a9f8986838b01016147d1565b845250918301918301614a71565b600082601f830112614abe57600080fd5b81356020614ace614741836146cf565b82815260059290921b84018101918181019086841115614aed57600080fd5b8286015b8481101561478d57803567ffffffffffffffff811115614b115760008081fd5b614b1f8986838b0101614a2d565b845250918301918301614af1565b600082601f830112614b3e57600080fd5b81356020614b4e614741836146cf565b8083825260208201915060208460051b870101935086841115614b7057600080fd5b602086015b8481101561478d5780358352918301918301614b75565b600060808284031215614b9e57600080fd5b614ba6614657565b9050813567ffffffffffffffff80821115614bc057600080fd5b818401915084601f830112614bd457600080fd5b81356020614be4614741836146cf565b82815260059290921b84018101918181019088841115614c0357600080fd5b8286015b84811015614d5f57803586811115614c1e57600080fd5b87016101a0818c03601f19011215614c3557600080fd5b614c3d61467a565b614c4886830161451e565b8152614c5660408301614715565b86820152614c6660608301614715565b6040820152614c776080830161451e565b606082015260a08201356080820152614c9260c0830161497f565b60a0820152614ca360e0830161451e565b60c0820152610100614cb6818401614715565b60e083015261012080840135828401526101409150818401358a811115614cdc57600080fd5b614cea8f8a838801016147d1565b828501525050610160808401358a811115614d0457600080fd5b614d128f8a838801016149c5565b83850152506101809150818401358a811115614d2d57600080fd5b614d3b8f8a83880101614a2d565b91840191909152506101a09290920135918101919091528352918301918301614c07565b5086525085810135935082841115614d7657600080fd5b614d8287858801614aad565b90850152506040840135915080821115614d9b57600080fd5b50614da884828501614b2d565b6040830152506060820135606082015292915050565b60008060408385031215614dd157600080fd5b823567ffffffffffffffff80821115614de957600080fd5b614df586838701614b8c565b9350602091508185013581811115614e0c57600080fd5b85019050601f81018613614e1f57600080fd5b8035614e2d614741826146cf565b81815260059190911b82018301908381019088831115614e4c57600080fd5b928401925b82841015614e6a57833582529284019290840190614e51565b80955050505050509250929050565b60a08101610719828463ffffffff8082511683528060208301511660208401525061ffff6040820151166040830152606081015173ffffffffffffffffffffffffffffffffffffffff808216606085015280608084015116608085015250505050565b600060208284031215614eee57600080fd5b813567ffffffffffffffff811115614f0557600080fd5b820160a0818503121561106d57600080fd5b600082601f830112614f2857600080fd5b81356020614f38614741836146cf565b82815260069290921b84018101918181019086841115614f5757600080fd5b8286015b8481101561478d5760408189031215614f745760008081fd5b614f7c61462e565b8135614f87816146f3565b815281850135614f96816146f3565b81860152835291830191604001614f5b565b60008060408385031215614fbb57600080fd5b823567ffffffffffffffff80821115614fd357600080fd5b614fdf86838701614f17565b93506020850135915080821115614ff557600080fd5b5061500285828601614f17565b9150509250929050565b60008083601f84011261501e57600080fd5b50813567ffffffffffffffff81111561503657600080fd5b6020830191508360208260051b8501011115612c1857600080fd5b60008060008060008060008060e0898b03121561506d57600080fd5b606089018a81111561507e57600080fd5b8998503567ffffffffffffffff8082111561509857600080fd5b818b0191508b601f8301126150ac57600080fd5b8135818111156150bb57600080fd5b8c60208285010111156150cd57600080fd5b6020830199508098505060808b01359150808211156150eb57600080fd5b6150f78c838d0161500c565b909750955060a08b013591508082111561511057600080fd5b5061511d8b828c0161500c565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff8116811461452957600080fd5b60006060828403121561516857600080fd5b6040516060810181811067ffffffffffffffff8211171561518b5761518b6145ff565b604052823561519981614971565b81526151a760208401615136565b60208201526151b860408401615136565b60408201529392505050565b6040815260006151d760408301856148ef565b8281036020840152612f2581856148ef565b6000806000604084860312156151fe57600080fd5b833567ffffffffffffffff8082111561521657600080fd5b908501906101a0828803121561522b57600080fd5b9093506020850135908082111561524157600080fd5b5061524e8682870161500c565b9497909650939450505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156107195761071961525b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff808416806152e7576152e761529d565b92169190910692915050565b80820281158282048414176107195761071961525b565b600067ffffffffffffffff808416806153255761532561529d565b92169190910492915050565b60208101600383106153455761534561454b565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff8083168181036153935761539361525b565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153cd8184018a6148ef565b905082810360808401526153e181896148ef565b905060ff871660a084015282810360c08401526153fe81876145c0565b905067ffffffffffffffff851660e084015282810361010084015261542381856145c0565b9c9b505050505050505050505050565b60006020828403121561544557600080fd5b815161106d81614508565b808201808211156107195761071961525b565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261549857600080fd5b83018035915067ffffffffffffffff8211156154b357600080fd5b6020019150600681901b3603821315612c1857600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261550057600080fd5b83018035915067ffffffffffffffff82111561551b57600080fd5b6020019150600581901b3603821315612c1857600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261556857600080fd5b83018035915067ffffffffffffffff82111561558357600080fd5b602001915036819003821315612c1857600080fd5b60008151808452602080850194506020840160005b83811015614936578151805173ffffffffffffffffffffffffffffffffffffffff16885283015183880152604090960195908201906001016155ad565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c08401526156256101208401826145c0565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e086015261566183836145c0565b9250608089015191508085840301610100860152506156808282615598565b92505050615694602083018661ffff169052565b836040830152612f25606083018473ffffffffffffffffffffffffffffffffffffffff169052565b6000806000606084860312156156d157600080fd5b83516156dc81614971565b602085015190935067ffffffffffffffff8111156156f957600080fd5b8401601f8101861361570a57600080fd5b8051615718614741826147a9565b81815287602083850101111561572d57600080fd5b61573e82602083016020860161459c565b809450505050604084015190509250925092565b63ffffffff811681146114f657600080fd5b600060a0828403121561577657600080fd5b60405160a0810181811067ffffffffffffffff82111715615799576157996145ff565b60405282516157a781615752565b815260208301516157b781615752565b6020820152604083015161ffff811681146157d157600080fd5b604082015260608301516157e4816146f3565b606082015260808301516157f7816146f3565b60808201529392505050565b6101808101615881828573ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff16610120830152606083015173ffffffffffffffffffffffffffffffffffffffff90811661014084015260808401511661016083015261106d565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526159268285018b6148ef565b9150838203608085015261593a828a6148ef565b915060ff881660a085015283820360c085015261595782886145c0565b90861660e0850152838103610100850152905061542381856145c0565b60006020828403121561598657600080fd5b815161106d81614971565b60008151808452602080850194506020840160005b83811015614936578151875295820195908201906001016159a6565b6060815260006159d56060830186615991565b82810360208401526159e78186615991565b915050826040830152949350505050565b600060208284031215615a0a57600080fd5b5051919050565b67ffffffffffffffff81811683821601908082111561436c5761436c61525b565b67ffffffffffffffff831681526040810161106d602083018461457a565b600067ffffffffffffffff8083168181036153935761539361525b565b615a77818461457a565b6040602082015260006129e260408301846145c0565b600060208284031215615a9f57600080fd5b813567ffffffffffffffff811115615ab657600080fd5b6129e284828501614b8c565b600060408284031215615ad457600080fd5b61106d838361498a565b600060208284031215615af057600080fd5b813567ffffffffffffffff80821115615b0857600080fd5b9083019060808286031215615b1c57600080fd5b615b24614657565b823582811115615b3357600080fd5b615b3f878286016147d1565b825250602083013582811115615b5457600080fd5b615b60878286016147d1565b602083015250604083013582811115615b7857600080fd5b615b84878286016147d1565b60408301525060608301359250615b9a83615752565b6060810192909252509392505050565b60208152600061106d6020830184615598565b60008282518085526020808601955060208260051b8401016020860160005b84811015615c0a57601f19868403018952615bf88383516145c0565b98840198925090830190600101615bdc565b5090979650505050505050565b60208152600061106d6020830184615bbd565b60408152615c4560408201845167ffffffffffffffff169052565b60006020840151615c6e606084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604084015173ffffffffffffffffffffffffffffffffffffffff8116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c0840151610100615cdc8185018367ffffffffffffffff169052565b60e08601519150610120615d078186018473ffffffffffffffffffffffffffffffffffffffff169052565b81870151925061014091508282860152808701519250506101a06101608181870152615d376101e08701856145c0565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0610180818887030181890152615d768686615598565b9550828a01519450818887030184890152615d918686615bbd565b9550808a01516101c089015250505050508281036020840152612f258185615bbd565b600060208284031215615dc657600080fd5b815161106d816146f3565b6020815260008251610100806020850152615df06101208501836145c0565b91506020850151615e0d604086018267ffffffffffffffff169052565b50604085015173ffffffffffffffffffffffffffffffffffffffff8116606086015250606085015160808501526080850151615e6160a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0850151601f19808685030160c0870152615e7e84836145c0565b935060c08701519150808685030160e0870152615e9b84836145c0565b935060e0870151915080868503018387015250615eb883826145c0565b9695505050505050565b600060408284031215615ed457600080fd5b615edc61462e565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114615f0857600080fd5b81526020830151615f1881615752565b60208201529392505050565b600082615f3357615f3361529d565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var EVM2EVMOffRampABI = EVM2EVMOffRampMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go index 3e8e53c03f..6e695182b8 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var LockReleaseTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162004a1738038062004a17833981016040819052620000359162000565565b848484833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200017e565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001695760408051600081526020810190915262000169908462000229565b5050505090151560e05250620006d692505050565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000688565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000688565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200069e565b8554909150600090620003fa906001906200069e565b9050818114620004665760008660000182815481106200041e576200041e62000688565b906000526020600020015490508087600001848154811062000444576200044462000688565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a620006c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b805180151581146200054f57600080fd5b600080600080600060a086880312156200057e57600080fd5b85516200058b8162000513565b602087810151919650906001600160401b0380821115620005ab57600080fd5b818901915089601f830112620005c057600080fd5b815181811115620005d557620005d56200052c565b8060051b604051601f19603f83011681018181108582111715620005fd57620005fd6200052c565b60405291825284820192508381018501918c8311156200061c57600080fd5b938501935b828510156200064557620006358562000542565b8452938501939285019262000621565b8099505050505050506200065c6040870162000542565b92506200066c6060870162000554565b91506200067c6080870162000542565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516142a562000772600039600081816104ef01526117ab01526000818161059c01528181611d4701526127ec01526000818161057601528181611b780152611ffd015260008181610290015281816102e50152818161077a0152818161084c015281816108c50152818161186d01528181611a9801528181611f1d0152818161278201526129d701526142a56000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063c4bffe2b116100a2578063dc0bd97111610071578063dc0bd97114610574578063e0351e131461059a578063eb521a4c146105c0578063f2fde38b146105d357600080fd5b8063c4bffe2b14610526578063c75eea9c1461053b578063cf7401f31461054e578063db6327dc1461056157600080fd5b8063b0f479a1116100de578063b0f479a1146104bc578063b7946580146104da578063bb98546b146104ed578063c0d786551461051357600080fd5b80638da5cb5b146103fa5780639a4575b914610418578063a7cd63b714610438578063af58d59f1461044d57600080fd5b806354c8a4f31161018757806378a010b21161015657806378a010b2146103b957806379ba5097146103cc5780637d54534e146103d45780638926f54f146103e757600080fd5b806354c8a4f31461036257806366320087146103755780636cfd1553146103885780636d3d1a581461039b57600080fd5b806321df0da7116101c357806321df0da71461028e578063240028e8146102d55780633907753714610322578063432a6ba31461034457600080fd5b806301ffc9a7146101f55780630a2fd4931461021d5780630a861f2a1461023d578063181f5a7714610252575b600080fd5b610208610203366004613381565b6105e6565b60405190151581526020015b60405180910390f35b61023061022b3660046133e0565b610642565b6040516102149190613469565b61025061024b36600461347c565b6106f2565b005b6102306040518060400160405280601e81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e302d646576000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b6102086102e33660046134c2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6103356103303660046134df565b6108a3565b60405190518152602001610214565b60095473ffffffffffffffffffffffffffffffffffffffff166102b0565b610250610370366004613567565b610a12565b6102506103833660046135d3565b610a8d565b6102506103963660046134c2565b610b69565b60085473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103c73660046135ff565b610bb8565b610250610d27565b6102506103e23660046134c2565b610e24565b6102086103f53660046133e0565b610e73565b60005473ffffffffffffffffffffffffffffffffffffffff166102b0565b61042b610426366004613682565b610e8a565b60405161021491906136bd565b610440610f24565b604051610214919061371d565b61046061045b3660046133e0565b610f35565b604051610214919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102306104e83660046133e0565b61100a565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105213660046134c2565b611035565b61052e611110565b6040516102149190613777565b6104606105493660046133e0565b6111c8565b61025061055c3660046138df565b61129a565b61025061056f366004613924565b611323565b7f00000000000000000000000000000000000000000000000000000000000000006102b0565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105ce36600461347c565b6117a9565b6102506105e13660046134c2565b6118c5565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061063c575061063c826118d9565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061066d90613966565b80601f016020809104026020016040519081016040528092919081815260200182805461069990613966565b80156106e65780601f106106bb576101008083540402835291602001916106e6565b820191906000526020600020905b8154815290600101906020018083116106c957829003601f168201915b50505050509050919050565b60095473ffffffffffffffffffffffffffffffffffffffff16331461074a576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa91906139b9565b1015610832576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633836119bd565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c36108be83613a7d565b611a91565b7f00000000000000000000000000000000000000000000000000000000000000006040517f095ea7b30000000000000000000000000000000000000000000000000000000081523360048201526060840135602482015273ffffffffffffffffffffffffffffffffffffffff919091169063095ea7b3906044016020604051808303816000875af115801561095c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109809190613b72565b5061099160608301604084016134c2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f5284606001356040516109f391815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a1a611cc2565b610a8784848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611d4592505050565b50505050565b610a95611cc2565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610afd57600080fd5b505af1158015610b11573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610b5d91815260200190565b60405180910390a25050565b610b71611cc2565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610bc0611cc2565b610bc983610e73565b610c0b576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b67ffffffffffffffff831660009081526007602052604081206004018054610c3290613966565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5e90613966565b8015610cab5780601f10610c8057610100808354040283529160200191610cab565b820191906000526020600020905b815481529060010190602001808311610c8e57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cda838583613bdf565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d1993929190613cfa565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610da8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610741565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e2c611cc2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061063c600567ffffffffffffffff8416611efb565b6040805180820190915260608082526020820152610eaf610eaa83613d5e565b611f16565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610f098460200160208101906104e891906133e0565b81526040805160208181019092526000815291015292915050565b6060610f3060026120e0565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261063c906120ed565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061066d90613966565b61103d611cc2565b73ffffffffffffffffffffffffffffffffffffffff811661108a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b6060600061111e60056120e0565b90506000815167ffffffffffffffff81111561113c5761113c6137b9565b604051908082528060200260200182016040528015611165578160200160208202803683370190505b50905060005b82518110156111c15782818151811061118657611186613e00565b60200260200101518282815181106111a0576111a0613e00565b67ffffffffffffffff9092166020928302919091019091015260010161116b565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261063c906120ed565b60085473ffffffffffffffffffffffffffffffffffffffff1633148015906112da575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611313576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b61131e83838361219f565b505050565b61132b611cc2565b60005b8181101561131e57600083838381811061134a5761134a613e00565b905060200281019061135c9190613e2f565b61136590613e6d565b905061137a8160800151826020015115612289565b61138d8160a00151826020015115612289565b8060200151156116895780516113af9060059067ffffffffffffffff166123c2565b6113f45780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b60408101515115806114095750606081015151155b15611440576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906116219082613f21565b50606082015160058201906116369082613f21565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061167c949392919061403b565b60405180910390a16117a0565b80516116a19060059067ffffffffffffffff166123ce565b6116e65780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600182018390556002820180549091169055600381018290559061174f6004830182613333565b61175d600583016000613333565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161132e565b7f0000000000000000000000000000000000000000000000000000000000000000611800576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff163314611853576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b61189573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846123da565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b6118cd611cc2565b6118d681612438565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061196c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061063c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261131e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261252d565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611b265760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611bd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf89190613b72565b15611c2f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c3c8160200151612639565b6000611c4b8260200151610642565b9050805160001480611c6f575080805190602001208260a001518051906020012014155b15611cac578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107419190613469565b611cbe8260200151836060015161275f565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611d43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610741565b565b7f0000000000000000000000000000000000000000000000000000000000000000611d9c576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611e32576000838281518110611dbc57611dbc613e00565b60200260200101519050611dda8160026127a690919063ffffffff16565b15611e295760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611d9f565b5060005b815181101561131e576000828281518110611e5357611e53613e00565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e975750611ef3565b611ea26002826127c8565b15611ef15760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611e36565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611fab5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207d9190613b72565b156120b4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120c181604001516127ea565b6120ce8160200151612869565b6118d6816020015182606001516129b7565b60606000611f0f836129fb565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261217b82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261215f9190614103565b85608001516fffffffffffffffffffffffffffffffff16612a56565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6121a883610e73565b6121ea576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b6121f5826000612289565b67ffffffffffffffff831660009081526007602052604090206122189083612a80565b612223816000612289565b67ffffffffffffffff831660009081526007602052604090206122499060020182612a80565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161227c93929190614116565b60405180910390a1505050565b8151156123505781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806122df575060408201516fffffffffffffffffffffffffffffffff16155b1561231857816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107419190614199565b8015611cbe576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612389575060208201516fffffffffffffffffffffffffffffffff1615155b15611cbe57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107419190614199565b6000611f0f8383612c22565b6000611f0f8383612c71565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a879085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611a0f565b3373ffffffffffffffffffffffffffffffffffffffff8216036124b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610741565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061258f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612d649092919063ffffffff16565b80519091501561131e57808060200190518101906125ad9190613b72565b61131e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610741565b61264281610e73565b612684576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612703573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127279190613b72565b6118d6576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611cbe90600201827f0000000000000000000000000000000000000000000000000000000000000000612d73565b6000611f0f8373ffffffffffffffffffffffffffffffffffffffff8416612c71565b6000611f0f8373ffffffffffffffffffffffffffffffffffffffff8416612c22565b7f0000000000000000000000000000000000000000000000000000000000000000156118d65761281b6002826130f6565b6118d6576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610741565b61287281610e73565b6128b4576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561292d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295191906141d5565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118d6576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611cbe90827f0000000000000000000000000000000000000000000000000000000000000000612d73565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106e657602002820191906000526020600020905b815481526020019060010190808311612a375750505050509050919050565b6000612a7585612a6684866141f2565b612a709087614209565b613125565b90505b949350505050565b8154600090612aa990700100000000000000000000000000000000900463ffffffff1642614103565b90508015612b4b5760018301548354612af1916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612a56565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612b71916fffffffffffffffffffffffffffffffff9081169116613125565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061227c908490614199565b6000818152600183016020526040812054612c695750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561063c565b50600061063c565b60008181526001830160205260408120548015612d5a576000612c95600183614103565b8554909150600090612ca990600190614103565b9050818114612d0e576000866000018281548110612cc957612cc9613e00565b9060005260206000200154905080876000018481548110612cec57612cec613e00565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612d1f57612d1f61421c565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061063c565b600091505061063c565b6060612a78848460008561313b565b825474010000000000000000000000000000000000000000900460ff161580612d9a575081155b15612da457505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612dea90700100000000000000000000000000000000900463ffffffff1642614103565b90508015612eaa5781831115612e2c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612e669083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612a56565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612f615773ffffffffffffffffffffffffffffffffffffffff8416612f09576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610741565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610741565b848310156130745760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612fa59082614103565b612faf878a614103565b612fb99190614209565b612fc3919061424b565b905073ffffffffffffffffffffffffffffffffffffffff861661301c576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610741565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610741565b61307e8584614103565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611f0f565b60008183106131345781611f0f565b5090919050565b6060824710156131cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610741565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516131f69190614286565b60006040518083038185875af1925050503d8060008114613233576040519150601f19603f3d011682016040523d82523d6000602084013e613238565b606091505b509150915061324987838387613254565b979650505050505050565b606083156132ea5782516000036132e35773ffffffffffffffffffffffffffffffffffffffff85163b6132e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610741565b5081612a78565b612a7883838151156132ff5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107419190613469565b50805461333f90613966565b6000825580601f1061334f575050565b601f0160209004906000526020600020908101906118d691905b8082111561337d5760008155600101613369565b5090565b60006020828403121561339357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611f0f57600080fd5b803567ffffffffffffffff811681146133db57600080fd5b919050565b6000602082840312156133f257600080fd5b611f0f826133c3565b60005b838110156134165781810151838201526020016133fe565b50506000910152565b600081518084526134378160208601602086016133fb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611f0f602083018461341f565b60006020828403121561348e57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146118d657600080fd5b80356133db81613495565b6000602082840312156134d457600080fd5b8135611f0f81613495565b6000602082840312156134f157600080fd5b813567ffffffffffffffff81111561350857600080fd5b82016101008185031215611f0f57600080fd5b60008083601f84011261352d57600080fd5b50813567ffffffffffffffff81111561354557600080fd5b6020830191508360208260051b850101111561356057600080fd5b9250929050565b6000806000806040858703121561357d57600080fd5b843567ffffffffffffffff8082111561359557600080fd5b6135a18883890161351b565b909650945060208701359150808211156135ba57600080fd5b506135c78782880161351b565b95989497509550505050565b600080604083850312156135e657600080fd5b82356135f181613495565b946020939093013593505050565b60008060006040848603121561361457600080fd5b61361d846133c3565b9250602084013567ffffffffffffffff8082111561363a57600080fd5b818601915086601f83011261364e57600080fd5b81358181111561365d57600080fd5b87602082850101111561366f57600080fd5b6020830194508093505050509250925092565b60006020828403121561369457600080fd5b813567ffffffffffffffff8111156136ab57600080fd5b820160a08185031215611f0f57600080fd5b6020815260008251604060208401526136d9606084018261341f565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613714828261341f565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561376b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613739565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561376b57835167ffffffffffffffff1683529284019291840191600101613793565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561380c5761380c6137b9565b60405290565b60405160c0810167ffffffffffffffff8111828210171561380c5761380c6137b9565b80151581146118d657600080fd5b80356133db81613835565b80356fffffffffffffffffffffffffffffffff811681146133db57600080fd5b60006060828403121561388057600080fd5b6040516060810181811067ffffffffffffffff821117156138a3576138a36137b9565b60405290508082356138b481613835565b81526138c26020840161384e565b60208201526138d36040840161384e565b60408201525092915050565b600080600060e084860312156138f457600080fd5b6138fd846133c3565b925061390c856020860161386e565b915061391b856080860161386e565b90509250925092565b6000806020838503121561393757600080fd5b823567ffffffffffffffff81111561394e57600080fd5b61395a8582860161351b565b90969095509350505050565b600181811c9082168061397a57607f821691505b6020821081036139b3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000602082840312156139cb57600080fd5b5051919050565b600082601f8301126139e357600080fd5b813567ffffffffffffffff808211156139fe576139fe6137b9565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613a4457613a446137b9565b81604052838152866020858801011115613a5d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613a9057600080fd5b613a986137e8565b823567ffffffffffffffff80821115613ab057600080fd5b613abc368387016139d2565b8352613aca602086016133c3565b6020840152613adb604086016134b7565b604084015260608501356060840152613af6608086016134b7565b608084015260a0850135915080821115613b0f57600080fd5b613b1b368387016139d2565b60a084015260c0850135915080821115613b3457600080fd5b613b40368387016139d2565b60c084015260e0850135915080821115613b5957600080fd5b50613b66368286016139d2565b60e08301525092915050565b600060208284031215613b8457600080fd5b8151611f0f81613835565b601f82111561131e576000816000526020600020601f850160051c81016020861015613bb85750805b601f850160051c820191505b81811015613bd757828155600101613bc4565b505050505050565b67ffffffffffffffff831115613bf757613bf76137b9565b613c0b83613c058354613966565b83613b8f565b6000601f841160018114613c5d5760008515613c275750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613cf3565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613cac5786850135825560209485019460019092019101613c8c565b5086821015613ce7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613d0d604083018661341f565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613d7057600080fd5b60405160a0810167ffffffffffffffff8282108183111715613d9457613d946137b9565b816040528435915080821115613da957600080fd5b50613db6368286016139d2565b825250613dc5602084016133c3565b60208201526040830135613dd881613495565b6040820152606083810135908201526080830135613df581613495565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613e6357600080fd5b9190910192915050565b60006101408236031215613e8057600080fd5b613e88613812565b613e91836133c3565b8152613e9f60208401613843565b6020820152604083013567ffffffffffffffff80821115613ebf57600080fd5b613ecb368387016139d2565b60408401526060850135915080821115613ee457600080fd5b50613ef1368286016139d2565b606083015250613f04366080850161386e565b6080820152613f163660e0850161386e565b60a082015292915050565b815167ffffffffffffffff811115613f3b57613f3b6137b9565b613f4f81613f498454613966565b84613b8f565b602080601f831160018114613fa25760008415613f6c5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613bd7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613fef57888601518255948401946001909101908401613fd0565b508582101561402b57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261405f8184018761341f565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061409d9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613714565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561063c5761063c6140d4565b67ffffffffffffffff8416815260e0810161416260208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612a78565b6060810161063c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156141e757600080fd5b8151611f0f81613495565b808202811582820484141761063c5761063c6140d4565b8082018082111561063c5761063c6140d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614281577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613e638184602087016133fb56fea164736f6c6343000818000a", + Bin: "0x6101006040523480156200001257600080fd5b50604051620049ae380380620049ae833981016040819052620000359162000565565b848484833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200017e565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001695760408051600081526020810190915262000169908462000229565b5050505090151560e05250620006d692505050565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000688565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000688565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200069e565b8554909150600090620003fa906001906200069e565b9050818114620004665760008660000182815481106200041e576200041e62000688565b906000526020600020015490508087600001848154811062000444576200044462000688565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a620006c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b805180151581146200054f57600080fd5b600080600080600060a086880312156200057e57600080fd5b85516200058b8162000513565b602087810151919650906001600160401b0380821115620005ab57600080fd5b818901915089601f830112620005c057600080fd5b815181811115620005d557620005d56200052c565b8060051b604051601f19603f83011681018181108582111715620005fd57620005fd6200052c565b60405291825284820192508381018501918c8311156200061c57600080fd5b938501935b828510156200064557620006358562000542565b8452938501939285019262000621565b8099505050505050506200065c6040870162000542565b92506200066c6060870162000554565b91506200067c6080870162000542565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161423c62000772600039600081816104ef015261174201526000818161059c01528181611cde015261278301526000818161057601528181611b0f0152611f94015260008181610290015281816102e50152818161077a0152818161084c015281816108ed0152818161180401528181611a2f01528181611eb401528181612719015261296e015261423c6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063c4bffe2b116100a2578063dc0bd97111610071578063dc0bd97114610574578063e0351e131461059a578063eb521a4c146105c0578063f2fde38b146105d357600080fd5b8063c4bffe2b14610526578063c75eea9c1461053b578063cf7401f31461054e578063db6327dc1461056157600080fd5b8063b0f479a1116100de578063b0f479a1146104bc578063b7946580146104da578063bb98546b146104ed578063c0d786551461051357600080fd5b80638da5cb5b146103fa5780639a4575b914610418578063a7cd63b714610438578063af58d59f1461044d57600080fd5b806354c8a4f31161018757806378a010b21161015657806378a010b2146103b957806379ba5097146103cc5780637d54534e146103d45780638926f54f146103e757600080fd5b806354c8a4f31461036257806366320087146103755780636cfd1553146103885780636d3d1a581461039b57600080fd5b806321df0da7116101c357806321df0da71461028e578063240028e8146102d55780633907753714610322578063432a6ba31461034457600080fd5b806301ffc9a7146101f55780630a2fd4931461021d5780630a861f2a1461023d578063181f5a7714610252575b600080fd5b610208610203366004613318565b6105e6565b60405190151581526020015b60405180910390f35b61023061022b366004613377565b610642565b6040516102149190613400565b61025061024b366004613413565b6106f2565b005b6102306040518060400160405280601e81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e302d646576000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b6102086102e3366004613459565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b610335610330366004613476565b6108a3565b60405190518152602001610214565b60095473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103703660046134fe565b6109a9565b61025061038336600461356a565b610a24565b610250610396366004613459565b610b00565b60085473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103c7366004613596565b610b4f565b610250610cbe565b6102506103e2366004613459565b610dbb565b6102086103f5366004613377565b610e0a565b60005473ffffffffffffffffffffffffffffffffffffffff166102b0565b61042b610426366004613619565b610e21565b6040516102149190613654565b610440610ebb565b60405161021491906136b4565b61046061045b366004613377565b610ecc565b604051610214919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102306104e8366004613377565b610fa1565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b610250610521366004613459565b610fcc565b61052e6110a7565b604051610214919061370e565b610460610549366004613377565b61115f565b61025061055c366004613876565b611231565b61025061056f3660046138bb565b6112ba565b7f00000000000000000000000000000000000000000000000000000000000000006102b0565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105ce366004613413565b611740565b6102506105e1366004613459565b61185c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061063c575061063c82611870565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061066d906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610699906138fd565b80156106e65780601f106106bb576101008083540402835291602001916106e6565b820191906000526020600020905b8154815290600101906020018083116106c957829003601f168201915b50505050509050919050565b60095473ffffffffffffffffffffffffffffffffffffffff16331461074a576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa9190613950565b1015610832576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611954565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c36108be83613a14565b611a28565b6109186108d66060840160408501613459565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611954565b6109286060830160408401613459565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52846060013560405161098a91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6109b1611c59565b610a1e84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611cdc92505050565b50505050565b610a2c611c59565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610a9457600080fd5b505af1158015610aa8573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610af491815260200190565b60405180910390a25050565b610b08611c59565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b57611c59565b610b6083610e0a565b610ba2576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b67ffffffffffffffff831660009081526007602052604081206004018054610bc9906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610bf5906138fd565b8015610c425780601f10610c1757610100808354040283529160200191610c42565b820191906000526020600020905b815481529060010190602001808311610c2557829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610c71838583613b59565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610cb093929190613c74565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610741565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610dc3611c59565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061063c600567ffffffffffffffff8416611e92565b6040805180820190915260608082526020820152610e46610e4183613cd8565b611ead565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610ea08460200160208101906104e89190613377565b81526040805160208181019092526000815291015292915050565b6060610ec76002612077565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261063c90612084565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061066d906138fd565b610fd4611c59565b73ffffffffffffffffffffffffffffffffffffffff8116611021576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110b56005612077565b90506000815167ffffffffffffffff8111156110d3576110d3613750565b6040519080825280602002602001820160405280156110fc578160200160208202803683370190505b50905060005b82518110156111585782818151811061111d5761111d613d7a565b602002602001015182828151811061113757611137613d7a565b67ffffffffffffffff90921660209283029190910190910152600101611102565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261063c90612084565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611271575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112aa576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b6112b5838383612136565b505050565b6112c2611c59565b60005b818110156112b55760008383838181106112e1576112e1613d7a565b90506020028101906112f39190613da9565b6112fc90613de7565b90506113118160800151826020015115612220565b6113248160a00151826020015115612220565b8060200151156116205780516113469060059067ffffffffffffffff16612359565b61138b5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b60408101515115806113a05750606081015151155b156113d7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115b89082613e9b565b50606082015160058201906115cd9082613e9b565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116139493929190613fb5565b60405180910390a1611737565b80516116389060059067ffffffffffffffff16612365565b61167d5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116e660048301826132ca565b6116f46005830160006132ca565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112c5565b7f0000000000000000000000000000000000000000000000000000000000000000611797576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff1633146117ea576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b61182c73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612371565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611864611c59565b61186d816123cf565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061190357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061063c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112b59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526124c4565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611abd5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8f919061404e565b15611bc6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bd381602001516125d0565b6000611be28260200151610642565b9050805160001480611c06575080805190602001208260a001518051906020012014155b15611c43578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107419190613400565b611c55826020015183606001516126f6565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611cda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610741565b565b7f0000000000000000000000000000000000000000000000000000000000000000611d33576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611dc9576000838281518110611d5357611d53613d7a565b60200260200101519050611d7181600261273d90919063ffffffff16565b15611dc05760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611d36565b5060005b81518110156112b5576000828281518110611dea57611dea613d7a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e2e5750611e8a565b611e3960028261275f565b15611e885760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611dcd565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611f425760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611ff0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612014919061404e565b1561204b576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120588160400151612781565b6120658160200151612800565b61186d8160200151826060015161294e565b60606000611ea683612992565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261211282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426120f6919061409a565b85608001516fffffffffffffffffffffffffffffffff166129ed565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61213f83610e0a565b612181576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b61218c826000612220565b67ffffffffffffffff831660009081526007602052604090206121af9083612a17565b6121ba816000612220565b67ffffffffffffffff831660009081526007602052604090206121e09060020182612a17565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051612213939291906140ad565b60405180910390a1505050565b8151156122e75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612276575060408201516fffffffffffffffffffffffffffffffff16155b156122af57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107419190614130565b8015611c55576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612320575060208201516fffffffffffffffffffffffffffffffff1615155b15611c5557816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107419190614130565b6000611ea68383612bb9565b6000611ea68383612c08565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a1e9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016119a6565b3373ffffffffffffffffffffffffffffffffffffffff82160361244e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610741565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612526826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612cfb9092919063ffffffff16565b8051909150156112b55780806020019051810190612544919061404e565b6112b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610741565b6125d981610e0a565b61261b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561269a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126be919061404e565b61186d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c5590600201827f0000000000000000000000000000000000000000000000000000000000000000612d0a565b6000611ea68373ffffffffffffffffffffffffffffffffffffffff8416612c08565b6000611ea68373ffffffffffffffffffffffffffffffffffffffff8416612bb9565b7f00000000000000000000000000000000000000000000000000000000000000001561186d576127b260028261308d565b61186d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610741565b61280981610e0a565b61284b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156128c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e8919061416c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461186d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c5590827f0000000000000000000000000000000000000000000000000000000000000000612d0a565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106e657602002820191906000526020600020905b8154815260200190600101908083116129ce5750505050509050919050565b6000612a0c856129fd8486614189565b612a0790876141a0565b6130bc565b90505b949350505050565b8154600090612a4090700100000000000000000000000000000000900463ffffffff164261409a565b90508015612ae25760018301548354612a88916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166129ed565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612b08916fffffffffffffffffffffffffffffffff90811691166130bc565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612213908490614130565b6000818152600183016020526040812054612c005750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561063c565b50600061063c565b60008181526001830160205260408120548015612cf1576000612c2c60018361409a565b8554909150600090612c409060019061409a565b9050818114612ca5576000866000018281548110612c6057612c60613d7a565b9060005260206000200154905080876000018481548110612c8357612c83613d7a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612cb657612cb66141b3565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061063c565b600091505061063c565b6060612a0f84846000856130d2565b825474010000000000000000000000000000000000000000900460ff161580612d31575081155b15612d3b57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612d8190700100000000000000000000000000000000900463ffffffff164261409a565b90508015612e415781831115612dc3576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612dfd9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166129ed565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612ef85773ffffffffffffffffffffffffffffffffffffffff8416612ea0576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610741565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610741565b8483101561300b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f3c908261409a565b612f46878a61409a565b612f5091906141a0565b612f5a91906141e2565b905073ffffffffffffffffffffffffffffffffffffffff8616612fb3576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610741565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610741565b613015858461409a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611ea6565b60008183106130cb5781611ea6565b5090919050565b606082471015613164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610741565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161318d919061421d565b60006040518083038185875af1925050503d80600081146131ca576040519150601f19603f3d011682016040523d82523d6000602084013e6131cf565b606091505b50915091506131e0878383876131eb565b979650505050505050565b6060831561328157825160000361327a5773ffffffffffffffffffffffffffffffffffffffff85163b61327a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610741565b5081612a0f565b612a0f83838151156132965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107419190613400565b5080546132d6906138fd565b6000825580601f106132e6575050565b601f01602090049060005260206000209081019061186d91905b808211156133145760008155600101613300565b5090565b60006020828403121561332a57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611ea657600080fd5b803567ffffffffffffffff8116811461337257600080fd5b919050565b60006020828403121561338957600080fd5b611ea68261335a565b60005b838110156133ad578181015183820152602001613395565b50506000910152565b600081518084526133ce816020860160208601613392565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611ea660208301846133b6565b60006020828403121561342557600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461186d57600080fd5b80356133728161342c565b60006020828403121561346b57600080fd5b8135611ea68161342c565b60006020828403121561348857600080fd5b813567ffffffffffffffff81111561349f57600080fd5b82016101008185031215611ea657600080fd5b60008083601f8401126134c457600080fd5b50813567ffffffffffffffff8111156134dc57600080fd5b6020830191508360208260051b85010111156134f757600080fd5b9250929050565b6000806000806040858703121561351457600080fd5b843567ffffffffffffffff8082111561352c57600080fd5b613538888389016134b2565b9096509450602087013591508082111561355157600080fd5b5061355e878288016134b2565b95989497509550505050565b6000806040838503121561357d57600080fd5b82356135888161342c565b946020939093013593505050565b6000806000604084860312156135ab57600080fd5b6135b48461335a565b9250602084013567ffffffffffffffff808211156135d157600080fd5b818601915086601f8301126135e557600080fd5b8135818111156135f457600080fd5b87602082850101111561360657600080fd5b6020830194508093505050509250925092565b60006020828403121561362b57600080fd5b813567ffffffffffffffff81111561364257600080fd5b820160a08185031215611ea657600080fd5b60208152600082516040602084015261367060608401826133b6565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526136ab82826133b6565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561370257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016136d0565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561370257835167ffffffffffffffff168352928401929184019160010161372a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156137a3576137a3613750565b60405290565b60405160c0810167ffffffffffffffff811182821017156137a3576137a3613750565b801515811461186d57600080fd5b8035613372816137cc565b80356fffffffffffffffffffffffffffffffff8116811461337257600080fd5b60006060828403121561381757600080fd5b6040516060810181811067ffffffffffffffff8211171561383a5761383a613750565b604052905080823561384b816137cc565b8152613859602084016137e5565b602082015261386a604084016137e5565b60408201525092915050565b600080600060e0848603121561388b57600080fd5b6138948461335a565b92506138a38560208601613805565b91506138b28560808601613805565b90509250925092565b600080602083850312156138ce57600080fd5b823567ffffffffffffffff8111156138e557600080fd5b6138f1858286016134b2565b90969095509350505050565b600181811c9082168061391157607f821691505b60208210810361394a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561396257600080fd5b5051919050565b600082601f83011261397a57600080fd5b813567ffffffffffffffff8082111561399557613995613750565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156139db576139db613750565b816040528381528660208588010111156139f457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613a2757600080fd5b613a2f61377f565b823567ffffffffffffffff80821115613a4757600080fd5b613a5336838701613969565b8352613a616020860161335a565b6020840152613a726040860161344e565b604084015260608501356060840152613a8d6080860161344e565b608084015260a0850135915080821115613aa657600080fd5b613ab236838701613969565b60a084015260c0850135915080821115613acb57600080fd5b613ad736838701613969565b60c084015260e0850135915080821115613af057600080fd5b50613afd36828601613969565b60e08301525092915050565b601f8211156112b5576000816000526020600020601f850160051c81016020861015613b325750805b601f850160051c820191505b81811015613b5157828155600101613b3e565b505050505050565b67ffffffffffffffff831115613b7157613b71613750565b613b8583613b7f83546138fd565b83613b09565b6000601f841160018114613bd75760008515613ba15750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613c6d565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613c265786850135825560209485019460019092019101613c06565b5086821015613c61577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613c8760408301866133b6565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613cea57600080fd5b60405160a0810167ffffffffffffffff8282108183111715613d0e57613d0e613750565b816040528435915080821115613d2357600080fd5b50613d3036828601613969565b825250613d3f6020840161335a565b60208201526040830135613d528161342c565b6040820152606083810135908201526080830135613d6f8161342c565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ddd57600080fd5b9190910192915050565b60006101408236031215613dfa57600080fd5b613e026137a9565b613e0b8361335a565b8152613e19602084016137da565b6020820152604083013567ffffffffffffffff80821115613e3957600080fd5b613e4536838701613969565b60408401526060850135915080821115613e5e57600080fd5b50613e6b36828601613969565b606083015250613e7e3660808501613805565b6080820152613e903660e08501613805565b60a082015292915050565b815167ffffffffffffffff811115613eb557613eb5613750565b613ec981613ec384546138fd565b84613b09565b602080601f831160018114613f1c5760008415613ee65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b51565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613f6957888601518255948401946001909101908401613f4a565b5085821015613fa557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613fd9818401876133b6565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506140179050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526136ab565b60006020828403121561406057600080fd5b8151611ea6816137cc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561063c5761063c61406b565b67ffffffffffffffff8416815260e081016140f960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612a0f565b6060810161063c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561417e57600080fd5b8151611ea68161342c565b808202811582820484141761063c5761063c61406b565b8082018082111561063c5761063c61406b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614218577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613ddd81846020870161339256fea164736f6c6343000818000a", } var LockReleaseTokenPoolABI = LockReleaseTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go index 88018a164b..f05a59bc73 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var LockReleaseTokenPoolAndProxyMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162004fbb38038062004fbb83398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508181146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516148336200078860003960008181610545015261190b0152600081816105f201528181611ffa0152612bb60152600081816105cc01528181611cd801526122ad0152600081816102ad01528181610302015281816107d0015281816108a20152818161096c015281816119cd01528181611bf801528181611ef3015281816121cd015281816123b301528181612b4c0152612da101526148336000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e13146105f0578063eb521a4c14610616578063f2fde38b1461062957600080fd5b8063db6327dc146105b7578063dc0bd971146105ca57600080fd5b8063c0d7865514610569578063c4bffe2b1461057c578063c75eea9c14610591578063cf7401f3146105a457600080fd5b8063a8d87a3b11610114578063b0f479a1116100f9578063b0f479a114610512578063b794658014610530578063bb98546b1461054357600080fd5b8063a8d87a3b14610490578063af58d59f146104a357600080fd5b80638da5cb5b1461042a5780639766b932146104485780639a4575b91461045b578063a7cd63b71461047b57600080fd5b806354c8a4f3116101d857806378a010b2116101a75780637d54534e1161018c5780637d54534e146103f157806383826b2b146104045780638926f54f1461041757600080fd5b806378a010b2146103d657806379ba5097146103e957600080fd5b806354c8a4f31461037f57806366320087146103925780636cfd1553146103a55780636d3d1a58146103b857600080fd5b806321df0da71161021457806321df0da7146102ab578063240028e8146102f2578063390775371461033f578063432a6ba31461036157600080fd5b806301ffc9a7146102465780630a2fd4931461026e5780630a861f2a1461028e578063181f5a77146102a3575b600080fd5b61025961025436600461374b565b61063c565b60405190151581526020015b60405180910390f35b61028161027c3660046137aa565b610698565b6040516102659190613833565b6102a161029c366004613846565b610748565b005b6102816108f9565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b61025961030036600461388c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61035261034d3660046138a9565b610915565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a161038d366004613931565b610a3e565b6102a16103a036600461399d565b610ab9565b6102a16103b336600461388c565b610b45565b60085473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16103e43660046139c9565b610b94565b6102a1610d03565b6102a16103ff36600461388c565b610e00565b610259610412366004613a4c565b610e4f565b6102596104253660046137aa565b610f1c565b60005473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a161045636600461388c565b610f33565b61046e610469366004613a83565b610fc2565b6040516102659190613abe565b61048361108b565b6040516102659190613b1e565b6102cd61049e3660046137aa565b503090565b6104b66104b13660046137aa565b61109c565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102cd565b61028161053e3660046137aa565b611171565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a161057736600461388c565b61119c565b610584611270565b6040516102659190613b78565b6104b661059f3660046137aa565b611328565b6102a16105b2366004613d2f565b6113fa565b6102a16105c5366004613d74565b611483565b7f00000000000000000000000000000000000000000000000000000000000000006102cd565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a1610624366004613846565b611909565b6102a161063736600461388c565b611a25565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d40566000000000000000000000000000000000000000000000000000000001480610692575061069282611a39565b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106c390613db6565b80601f01602080910402602001604051908101604052809291908181526020018280546106ef90613db6565b801561073c5780601f106107115761010080835404028352916020019161073c565b820191906000526020600020905b81548152906001019060200180831161071f57829003601f168201915b50505050509050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146107a0576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190613e09565b1015610888576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108c973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611b1d565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040518060600160405280602681526020016148016026913981565b60408051602081019091526000815261093561093083613ebe565b611bf1565b60095473ffffffffffffffffffffffffffffffffffffffff1661099c5761099773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016336060850135611b1d565b6109ad565b6109ad6109a883613ebe565b611e22565b6109bd606083016040840161388c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f528460600135604051610a1f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a46611f75565b610ab384848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ff892505050565b50505050565b610ac1611f75565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610b2957600080fd5b505af1158015610b3d573d6000803e3d6000fd5b505050505050565b610b4d611f75565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b9c611f75565b610ba583610f1c565b610be7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b67ffffffffffffffff831660009081526007602052604081206004018054610c0e90613db6565b80601f0160208091040260200160405190810160405280929190818152602001828054610c3a90613db6565b8015610c875780601f10610c5c57610100808354040283529160200191610c87565b820191906000526020600020905b815481529060010190602001808311610c6a57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cb6838583613ffb565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610cf593929190614116565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610797565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e08611f75565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610f155750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610ef1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f15919061417a565b9392505050565b6000610692600567ffffffffffffffff84166121ae565b610f3b611f75565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610fe7610fe283614197565b6121c6565b60095473ffffffffffffffffffffffffffffffffffffffff16156110165761101661101183614197565b612390565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a2604051806040016040528061107084602001602081019061053e91906137aa565b81526040805160208181019092526000815291015292915050565b606061109760026124aa565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610692906124b7565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106c390613db6565b6111a4611f75565b73ffffffffffffffffffffffffffffffffffffffff81166111f1576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610fb6565b6060600061127e60056124aa565b90506000815167ffffffffffffffff81111561129c5761129c613bba565b6040519080825280602002602001820160405280156112c5578160200160208202803683370190505b50905060005b8251811015611321578281815181106112e6576112e6614239565b602002602001015182828151811061130057611300614239565b67ffffffffffffffff909216602092830291909101909101526001016112cb565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610692906124b7565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061143a575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611473576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b61147e838383612569565b505050565b61148b611f75565b60005b8181101561147e5760008383838181106114aa576114aa614239565b90506020028101906114bc9190614268565b6114c5906142a6565b90506114da8160800151826020015115612653565b6114ed8160a00151826020015115612653565b8060200151156117e957805161150f9060059067ffffffffffffffff1661278c565b6115545780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b60408101515115806115695750606081015151155b156115a0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c17909116961515029590951790985590810151940151938116931690910291909117600382015591519091906004820190611781908261435a565b5060608201516005820190611796908261435a565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506117dc9493929190614474565b60405180910390a1611900565b80516118019060059067ffffffffffffffff16612798565b6118465780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118af60048301826136fd565b6118bd6005830160006136fd565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161148e565b7f0000000000000000000000000000000000000000000000000000000000000000611960576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff1633146119b3576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b6119f573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846127a4565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611a2d611f75565b611a3681612802565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611acc57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261147e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526128f7565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611c865760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d58919061417a565b15611d8f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d9c8160200151612a03565b6000611dab8260200151610698565b9050805160001480611dcf575080805190602001208260a001518051906020012014155b15611e0c578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107979190613833565b611e1e82602001518360600151612b29565b5050565b6009548151606083015160208401516040517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90941693638627fad693611e86939092309260040161450d565b600060405180830381600087803b158015611ea057600080fd5b505af1158015611eb4573d6000803e3d6000fd5b5050505060608101516040517f095ea7b300000000000000000000000000000000000000000000000000000000815233600482015260248101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063095ea7b3906044016020604051808303816000875af1158015611f51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1e919061417a565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ff6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610797565b565b7f000000000000000000000000000000000000000000000000000000000000000061204f576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156120e557600083828151811061206f5761206f614239565b6020026020010151905061208d816002612b7090919063ffffffff16565b156120dc5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101612052565b5060005b815181101561147e57600082828151811061210657612106614239565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361214a57506121a6565b612155600282612b92565b156121a45760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016120e9565b60008181526001830160205260408120541515610f15565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461225b5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612309573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232d919061417a565b15612364576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123718160400151612bb4565b61237e8160200151612c33565b611a3681602001518260600151612d81565b60095460608201516123dd9173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611b1d565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909516946396875445946124459493929160040161456e565b6000604051808303816000875af1158015612464573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e1e91908101906145ce565b60606000610f1583612dc5565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261254582606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642612529919061466b565b85608001516fffffffffffffffffffffffffffffffff16612e20565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61257283610f1c565b6125b4576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b6125bf826000612653565b67ffffffffffffffff831660009081526007602052604090206125e29083612e4a565b6125ed816000612653565b67ffffffffffffffff831660009081526007602052604090206126139060020182612e4a565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516126469392919061467e565b60405180910390a1505050565b81511561271a5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806126a9575060408201516fffffffffffffffffffffffffffffffff16155b156126e257816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107979190614701565b8015611e1e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612753575060208201516fffffffffffffffffffffffffffffffff1615155b15611e1e57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107979190614701565b6000610f158383612fec565b6000610f15838361303b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ab39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611b6f565b3373ffffffffffffffffffffffffffffffffffffffff821603612881576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610797565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612959826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661312e9092919063ffffffff16565b80519091501561147e5780806020019051810190612977919061417a565b61147e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610797565b612a0c81610f1c565b612a4e576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612acd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612af1919061417a565b611a36576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e1e90600201827f000000000000000000000000000000000000000000000000000000000000000061313d565b6000610f158373ffffffffffffffffffffffffffffffffffffffff841661303b565b6000610f158373ffffffffffffffffffffffffffffffffffffffff8416612fec565b7f000000000000000000000000000000000000000000000000000000000000000015611a3657612be56002826134c0565b611a36576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610797565b612c3c81610f1c565b612c7e576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612cf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1b919061473d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a36576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e1e90827f000000000000000000000000000000000000000000000000000000000000000061313d565b60608160000180548060200260200160405190810160405280929190818152602001828054801561073c57602002820191906000526020600020905b815481526020019060010190808311612e015750505050509050919050565b6000612e3f85612e30848661475a565b612e3a9087614771565b6134ef565b90505b949350505050565b8154600090612e7390700100000000000000000000000000000000900463ffffffff164261466b565b90508015612f155760018301548354612ebb916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e20565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612f3b916fffffffffffffffffffffffffffffffff90811691166134ef565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612646908490614701565b600081815260018301602052604081205461303357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610692565b506000610692565b6000818152600183016020526040812054801561312457600061305f60018361466b565b85549091506000906130739060019061466b565b90508181146130d857600086600001828154811061309357613093614239565b90600052602060002001549050808760000184815481106130b6576130b6614239565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806130e9576130e9614784565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610692565b6000915050610692565b6060612e428484600085613505565b825474010000000000000000000000000000000000000000900460ff161580613164575081155b1561316e57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906131b490700100000000000000000000000000000000900463ffffffff164261466b565b9050801561327457818311156131f6576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546132309083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e20565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561332b5773ffffffffffffffffffffffffffffffffffffffff84166132d3576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610797565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610797565b8483101561343e5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061336f908261466b565b613379878a61466b565b6133839190614771565b61338d91906147b3565b905073ffffffffffffffffffffffffffffffffffffffff86166133e6576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610797565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610797565b613448858461466b565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610f15565b60008183106134fe5781610f15565b5090919050565b606082471015613597576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610797565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516135c091906147ee565b60006040518083038185875af1925050503d80600081146135fd576040519150601f19603f3d011682016040523d82523d6000602084013e613602565b606091505b50915091506136138783838761361e565b979650505050505050565b606083156136b45782516000036136ad5773ffffffffffffffffffffffffffffffffffffffff85163b6136ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610797565b5081612e42565b612e4283838151156136c95781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107979190613833565b50805461370990613db6565b6000825580601f10613719575050565b601f016020900490600052602060002090810190611a3691905b808211156137475760008155600101613733565b5090565b60006020828403121561375d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f1557600080fd5b803567ffffffffffffffff811681146137a557600080fd5b919050565b6000602082840312156137bc57600080fd5b610f158261378d565b60005b838110156137e05781810151838201526020016137c8565b50506000910152565b600081518084526138018160208601602086016137c5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f1560208301846137e9565b60006020828403121561385857600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a3657600080fd5b80356137a58161385f565b60006020828403121561389e57600080fd5b8135610f158161385f565b6000602082840312156138bb57600080fd5b813567ffffffffffffffff8111156138d257600080fd5b82016101008185031215610f1557600080fd5b60008083601f8401126138f757600080fd5b50813567ffffffffffffffff81111561390f57600080fd5b6020830191508360208260051b850101111561392a57600080fd5b9250929050565b6000806000806040858703121561394757600080fd5b843567ffffffffffffffff8082111561395f57600080fd5b61396b888389016138e5565b9096509450602087013591508082111561398457600080fd5b50613991878288016138e5565b95989497509550505050565b600080604083850312156139b057600080fd5b82356139bb8161385f565b946020939093013593505050565b6000806000604084860312156139de57600080fd5b6139e78461378d565b9250602084013567ffffffffffffffff80821115613a0457600080fd5b818601915086601f830112613a1857600080fd5b813581811115613a2757600080fd5b876020828501011115613a3957600080fd5b6020830194508093505050509250925092565b60008060408385031215613a5f57600080fd5b613a688361378d565b91506020830135613a788161385f565b809150509250929050565b600060208284031215613a9557600080fd5b813567ffffffffffffffff811115613aac57600080fd5b820160a08185031215610f1557600080fd5b602081526000825160406020840152613ada60608401826137e9565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613b1582826137e9565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613b6c57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613b3a565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613b6c57835167ffffffffffffffff1683529284019291840191600101613b94565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613c0d57613c0d613bba565b60405290565b60405160c0810167ffffffffffffffff81118282101715613c0d57613c0d613bba565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613c7d57613c7d613bba565b604052919050565b8015158114611a3657600080fd5b80356137a581613c85565b80356fffffffffffffffffffffffffffffffff811681146137a557600080fd5b600060608284031215613cd057600080fd5b6040516060810181811067ffffffffffffffff82111715613cf357613cf3613bba565b6040529050808235613d0481613c85565b8152613d1260208401613c9e565b6020820152613d2360408401613c9e565b60408201525092915050565b600080600060e08486031215613d4457600080fd5b613d4d8461378d565b9250613d5c8560208601613cbe565b9150613d6b8560808601613cbe565b90509250925092565b60008060208385031215613d8757600080fd5b823567ffffffffffffffff811115613d9e57600080fd5b613daa858286016138e5565b90969095509350505050565b600181811c90821680613dca57607f821691505b602082108103613e03577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613e1b57600080fd5b5051919050565b600067ffffffffffffffff821115613e3c57613e3c613bba565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613e7957600080fd5b8135613e8c613e8782613e22565b613c36565b818152846020838601011115613ea157600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613ed157600080fd5b613ed9613be9565b823567ffffffffffffffff80821115613ef157600080fd5b613efd36838701613e68565b8352613f0b6020860161378d565b6020840152613f1c60408601613881565b604084015260608501356060840152613f3760808601613881565b608084015260a0850135915080821115613f5057600080fd5b613f5c36838701613e68565b60a084015260c0850135915080821115613f7557600080fd5b613f8136838701613e68565b60c084015260e0850135915080821115613f9a57600080fd5b50613fa736828601613e68565b60e08301525092915050565b601f82111561147e576000816000526020600020601f850160051c81016020861015613fdc5750805b601f850160051c820191505b81811015610b3d57828155600101613fe8565b67ffffffffffffffff83111561401357614013613bba565b614027836140218354613db6565b83613fb3565b6000601f84116001811461407957600085156140435750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561410f565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140c857868501358255602094850194600190920191016140a8565b5086821015614103577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60408152600061412960408301866137e9565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b60006020828403121561418c57600080fd5b8151610f1581613c85565b600060a082360312156141a957600080fd5b60405160a0810167ffffffffffffffff82821081831117156141cd576141cd613bba565b8160405284359150808211156141e257600080fd5b506141ef36828601613e68565b8252506141fe6020840161378d565b602082015260408301356142118161385f565b604082015260608381013590820152608083013561422e8161385f565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261429c57600080fd5b9190910192915050565b600061014082360312156142b957600080fd5b6142c1613c13565b6142ca8361378d565b81526142d860208401613c93565b6020820152604083013567ffffffffffffffff808211156142f857600080fd5b61430436838701613e68565b6040840152606085013591508082111561431d57600080fd5b5061432a36828601613e68565b60608301525061433d3660808501613cbe565b608082015261434f3660e08501613cbe565b60a082015292915050565b815167ffffffffffffffff81111561437457614374613bba565b614388816143828454613db6565b84613fb3565b602080601f8311600181146143db57600084156143a55750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610b3d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561442857888601518255948401946001909101908401614409565b508582101561446457878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152614498818401876137e9565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506144d69050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613b15565b60a08152600061452060a08301876137e9565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a06020820152600061459d60a08301866137e9565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b6000602082840312156145e057600080fd5b815167ffffffffffffffff8111156145f757600080fd5b8201601f8101841361460857600080fd5b8051614616613e8782613e22565b81815285602083850101111561462b57600080fd5b613b158260208301602086016137c5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106925761069261463c565b67ffffffffffffffff8416815260e081016146ca60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612e42565b6060810161069282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561474f57600080fd5b8151610f158161385f565b80820281158282048414176106925761069261463c565b808201808211156106925761069261463c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826147e9577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000825161429c8184602087016137c556fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004f0e38038062004f0e83398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508181146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161478d6200078160003960008181610545015261191b0152600081816105f201528181611f550152612b110152600081816105cc01528181611ce801526122080152600081816102ad01528181610302015281816107d0015281816108a20152818161097c015281816119dd01528181611c08015281816121280152818161230e01528181612aa70152612cfc015261478d6000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e13146105f0578063eb521a4c14610616578063f2fde38b1461062957600080fd5b8063db6327dc146105b7578063dc0bd971146105ca57600080fd5b8063c0d7865514610569578063c4bffe2b1461057c578063c75eea9c14610591578063cf7401f3146105a457600080fd5b8063a8d87a3b11610114578063b0f479a1116100f9578063b0f479a114610512578063b794658014610530578063bb98546b1461054357600080fd5b8063a8d87a3b14610490578063af58d59f146104a357600080fd5b80638da5cb5b1461042a5780639766b932146104485780639a4575b91461045b578063a7cd63b71461047b57600080fd5b806354c8a4f3116101d857806378a010b2116101a75780637d54534e1161018c5780637d54534e146103f157806383826b2b146104045780638926f54f1461041757600080fd5b806378a010b2146103d657806379ba5097146103e957600080fd5b806354c8a4f31461037f57806366320087146103925780636cfd1553146103a55780636d3d1a58146103b857600080fd5b806321df0da71161021457806321df0da7146102ab578063240028e8146102f2578063390775371461033f578063432a6ba31461036157600080fd5b806301ffc9a7146102465780630a2fd4931461026e5780630a861f2a1461028e578063181f5a77146102a3575b600080fd5b6102596102543660046136a6565b61063c565b60405190151581526020015b60405180910390f35b61028161027c366004613705565b610698565b604051610265919061378e565b6102a161029c3660046137a1565b610748565b005b6102816108f9565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102596103003660046137e7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61035261034d366004613804565b610915565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a161038d36600461388c565b610a4e565b6102a16103a03660046138f8565b610ac9565b6102a16103b33660046137e7565b610b55565b60085473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16103e4366004613924565b610ba4565b6102a1610d13565b6102a16103ff3660046137e7565b610e10565b6102596104123660046139a7565b610e5f565b610259610425366004613705565b610f2c565b60005473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16104563660046137e7565b610f43565b61046e6104693660046139de565b610fd2565b6040516102659190613a19565b61048361109b565b6040516102659190613a79565b6102cd61049e366004613705565b503090565b6104b66104b1366004613705565b6110ac565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102cd565b61028161053e366004613705565b611181565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16105773660046137e7565b6111ac565b610584611280565b6040516102659190613ad3565b6104b661059f366004613705565b611338565b6102a16105b2366004613c8a565b61140a565b6102a16105c5366004613ccf565b611493565b7f00000000000000000000000000000000000000000000000000000000000000006102cd565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16106243660046137a1565b611919565b6102a16106373660046137e7565b611a35565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d40566000000000000000000000000000000000000000000000000000000001480610692575061069282611a49565b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106c390613d11565b80601f01602080910402602001604051908101604052809291908181526020018280546106ef90613d11565b801561073c5780601f106107115761010080835404028352916020019161073c565b820191906000526020600020905b81548152906001019060200180831161071f57829003601f168201915b50505050509050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146107a0576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190613d64565b1015610888576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108c973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611b2d565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b60405180606001604052806026815260200161475b6026913981565b60408051602081019091526000815261093561093083613e19565b611c01565b60095473ffffffffffffffffffffffffffffffffffffffff166109ac576109a761096560608401604085016137e7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611b2d565b6109bd565b6109bd6109b883613e19565b611e32565b6109cd60608301604084016137e7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f528460600135604051610a2f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a56611ed0565b610ac384848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f5392505050565b50505050565b610ad1611ed0565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610b3957600080fd5b505af1158015610b4d573d6000803e3d6000fd5b505050505050565b610b5d611ed0565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610bac611ed0565b610bb583610f2c565b610bf7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b67ffffffffffffffff831660009081526007602052604081206004018054610c1e90613d11565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4a90613d11565b8015610c975780601f10610c6c57610100808354040283529160200191610c97565b820191906000526020600020905b815481529060010190602001808311610c7a57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cc6838583613f56565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d0593929190614070565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610797565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e18611ed0565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610f255750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610f01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2591906140d4565b9392505050565b6000610692600567ffffffffffffffff8416612109565b610f4b611ed0565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610ff7610ff2836140f1565b612121565b60095473ffffffffffffffffffffffffffffffffffffffff161561102657611026611021836140f1565b6122eb565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a2604051806040016040528061108084602001602081019061053e9190613705565b81526040805160208181019092526000815291015292915050565b60606110a76002612405565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261069290612412565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106c390613d11565b6111b4611ed0565b73ffffffffffffffffffffffffffffffffffffffff8116611201576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610fc6565b6060600061128e6005612405565b90506000815167ffffffffffffffff8111156112ac576112ac613b15565b6040519080825280602002602001820160405280156112d5578160200160208202803683370190505b50905060005b8251811015611331578281815181106112f6576112f6614193565b602002602001015182828151811061131057611310614193565b67ffffffffffffffff909216602092830291909101909101526001016112db565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261069290612412565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061144a575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611483576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b61148e8383836124c4565b505050565b61149b611ed0565b60005b8181101561148e5760008383838181106114ba576114ba614193565b90506020028101906114cc91906141c2565b6114d590614200565b90506114ea81608001518260200151156125ae565b6114fd8160a001518260200151156125ae565b8060200151156117f957805161151f9060059067ffffffffffffffff166126e7565b6115645780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b60408101515115806115795750606081015151155b156115b0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061179190826142b4565b50606082015160058201906117a690826142b4565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506117ec94939291906143ce565b60405180910390a1611910565b80516118119060059067ffffffffffffffff166126f3565b6118565780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118bf6004830182613658565b6118cd600583016000613658565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161149e565b7f0000000000000000000000000000000000000000000000000000000000000000611970576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff1633146119c3576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b611a0573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846126ff565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611a3d611ed0565b611a468161275d565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611adc57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261148e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612852565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611c965760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6891906140d4565b15611d9f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dac816020015161295e565b6000611dbb8260200151610698565b9050805160001480611ddf575080805190602001208260a001518051906020012014155b15611e1c578160a001516040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610797919061378e565b611e2e82602001518360600151612a84565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611e9b9490939291600401614467565b600060405180830381600087803b158015611eb557600080fd5b505af1158015611ec9573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611f51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610797565b565b7f0000000000000000000000000000000000000000000000000000000000000000611faa576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612040576000838281518110611fca57611fca614193565b60200260200101519050611fe8816002612acb90919063ffffffff16565b156120375760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611fad565b5060005b815181101561148e57600082828151811061206157612061614193565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120a55750612101565b6120b0600282612aed565b156120ff5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612044565b60008181526001830160205260408120541515610f25565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121b65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612264573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228891906140d4565b156122bf576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122cc8160400151612b0f565b6122d98160200151612b8e565b611a4681602001518260600151612cdc565b60095460608201516123389173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611b2d565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909516946396875445946123a0949392916004016144c8565b6000604051808303816000875af11580156123bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e2e9190810190614528565b60606000610f2583612d20565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526124a082606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261248491906145c5565b85608001516fffffffffffffffffffffffffffffffff16612d7b565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6124cd83610f2c565b61250f576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b61251a8260006125ae565b67ffffffffffffffff8316600090815260076020526040902061253d9083612da5565b6125488160006125ae565b67ffffffffffffffff8316600090815260076020526040902061256e9060020182612da5565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516125a1939291906145d8565b60405180910390a1505050565b8151156126755781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612604575060408201516fffffffffffffffffffffffffffffffff16155b1561263d57816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610797919061465b565b8015611e2e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806126ae575060208201516fffffffffffffffffffffffffffffffff1615155b15611e2e57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610797919061465b565b6000610f258383612f47565b6000610f258383612f96565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ac39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611b7f565b3373ffffffffffffffffffffffffffffffffffffffff8216036127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610797565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006128b4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130899092919063ffffffff16565b80519091501561148e57808060200190518101906128d291906140d4565b61148e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610797565b61296781610f2c565b6129a9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612a28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4c91906140d4565b611a46576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e2e90600201827f0000000000000000000000000000000000000000000000000000000000000000613098565b6000610f258373ffffffffffffffffffffffffffffffffffffffff8416612f96565b6000610f258373ffffffffffffffffffffffffffffffffffffffff8416612f47565b7f000000000000000000000000000000000000000000000000000000000000000015611a4657612b4060028261341b565b611a46576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610797565b612b9781610f2c565b612bd9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c769190614697565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a46576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e2e90827f0000000000000000000000000000000000000000000000000000000000000000613098565b60608160000180548060200260200160405190810160405280929190818152602001828054801561073c57602002820191906000526020600020905b815481526020019060010190808311612d5c5750505050509050919050565b6000612d9a85612d8b84866146b4565b612d9590876146cb565b61344a565b90505b949350505050565b8154600090612dce90700100000000000000000000000000000000900463ffffffff16426145c5565b90508015612e705760018301548354612e16916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612d7b565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612e96916fffffffffffffffffffffffffffffffff908116911661344a565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906125a190849061465b565b6000818152600183016020526040812054612f8e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610692565b506000610692565b6000818152600183016020526040812054801561307f576000612fba6001836145c5565b8554909150600090612fce906001906145c5565b9050818114613033576000866000018281548110612fee57612fee614193565b906000526020600020015490508087600001848154811061301157613011614193565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613044576130446146de565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610692565b6000915050610692565b6060612d9d8484600085613460565b825474010000000000000000000000000000000000000000900460ff1615806130bf575081155b156130c957505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061310f90700100000000000000000000000000000000900463ffffffff16426145c5565b905080156131cf5781831115613151576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461318b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612d7b565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156132865773ffffffffffffffffffffffffffffffffffffffff841661322e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610797565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610797565b848310156133995760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906132ca90826145c5565b6132d4878a6145c5565b6132de91906146cb565b6132e8919061470d565b905073ffffffffffffffffffffffffffffffffffffffff8616613341576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610797565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610797565b6133a385846145c5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610f25565b60008183106134595781610f25565b5090919050565b6060824710156134f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610797565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161351b9190614748565b60006040518083038185875af1925050503d8060008114613558576040519150601f19603f3d011682016040523d82523d6000602084013e61355d565b606091505b509150915061356e87838387613579565b979650505050505050565b6060831561360f5782516000036136085773ffffffffffffffffffffffffffffffffffffffff85163b613608576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610797565b5081612d9d565b612d9d83838151156136245781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610797919061378e565b50805461366490613d11565b6000825580601f10613674575050565b601f016020900490600052602060002090810190611a4691905b808211156136a2576000815560010161368e565b5090565b6000602082840312156136b857600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f2557600080fd5b803567ffffffffffffffff8116811461370057600080fd5b919050565b60006020828403121561371757600080fd5b610f25826136e8565b60005b8381101561373b578181015183820152602001613723565b50506000910152565b6000815180845261375c816020860160208601613720565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f256020830184613744565b6000602082840312156137b357600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a4657600080fd5b8035613700816137ba565b6000602082840312156137f957600080fd5b8135610f25816137ba565b60006020828403121561381657600080fd5b813567ffffffffffffffff81111561382d57600080fd5b82016101008185031215610f2557600080fd5b60008083601f84011261385257600080fd5b50813567ffffffffffffffff81111561386a57600080fd5b6020830191508360208260051b850101111561388557600080fd5b9250929050565b600080600080604085870312156138a257600080fd5b843567ffffffffffffffff808211156138ba57600080fd5b6138c688838901613840565b909650945060208701359150808211156138df57600080fd5b506138ec87828801613840565b95989497509550505050565b6000806040838503121561390b57600080fd5b8235613916816137ba565b946020939093013593505050565b60008060006040848603121561393957600080fd5b613942846136e8565b9250602084013567ffffffffffffffff8082111561395f57600080fd5b818601915086601f83011261397357600080fd5b81358181111561398257600080fd5b87602082850101111561399457600080fd5b6020830194508093505050509250925092565b600080604083850312156139ba57600080fd5b6139c3836136e8565b915060208301356139d3816137ba565b809150509250929050565b6000602082840312156139f057600080fd5b813567ffffffffffffffff811115613a0757600080fd5b820160a08185031215610f2557600080fd5b602081526000825160406020840152613a356060840182613744565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613a708282613744565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ac757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613a95565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ac757835167ffffffffffffffff1683529284019291840191600101613aef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613b6857613b68613b15565b60405290565b60405160c0810167ffffffffffffffff81118282101715613b6857613b68613b15565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bd857613bd8613b15565b604052919050565b8015158114611a4657600080fd5b803561370081613be0565b80356fffffffffffffffffffffffffffffffff8116811461370057600080fd5b600060608284031215613c2b57600080fd5b6040516060810181811067ffffffffffffffff82111715613c4e57613c4e613b15565b6040529050808235613c5f81613be0565b8152613c6d60208401613bf9565b6020820152613c7e60408401613bf9565b60408201525092915050565b600080600060e08486031215613c9f57600080fd5b613ca8846136e8565b9250613cb78560208601613c19565b9150613cc68560808601613c19565b90509250925092565b60008060208385031215613ce257600080fd5b823567ffffffffffffffff811115613cf957600080fd5b613d0585828601613840565b90969095509350505050565b600181811c90821680613d2557607f821691505b602082108103613d5e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613d7657600080fd5b5051919050565b600067ffffffffffffffff821115613d9757613d97613b15565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613dd457600080fd5b8135613de7613de282613d7d565b613b91565b818152846020838601011115613dfc57600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613e2c57600080fd5b613e34613b44565b823567ffffffffffffffff80821115613e4c57600080fd5b613e5836838701613dc3565b8352613e66602086016136e8565b6020840152613e77604086016137dc565b604084015260608501356060840152613e92608086016137dc565b608084015260a0850135915080821115613eab57600080fd5b613eb736838701613dc3565b60a084015260c0850135915080821115613ed057600080fd5b613edc36838701613dc3565b60c084015260e0850135915080821115613ef557600080fd5b50613f0236828601613dc3565b60e08301525092915050565b601f82111561148e576000816000526020600020601f850160051c81016020861015613f375750805b601f850160051c820191505b81811015610b4d57828155600101613f43565b67ffffffffffffffff831115613f6e57613f6e613b15565b613f8283613f7c8354613d11565b83613f0e565b6000601f841160018114613fd45760008515613f9e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611ec9565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140235786850135825560209485019460019092019101614003565b508682101561405e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006140836040830186613744565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b6000602082840312156140e657600080fd5b8151610f2581613be0565b600060a0823603121561410357600080fd5b60405160a0810167ffffffffffffffff828210818311171561412757614127613b15565b81604052843591508082111561413c57600080fd5b5061414936828601613dc3565b825250614158602084016136e8565b6020820152604083013561416b816137ba565b6040820152606083810135908201526080830135614188816137ba565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126141f657600080fd5b9190910192915050565b6000610140823603121561421357600080fd5b61421b613b6e565b614224836136e8565b815261423260208401613bee565b6020820152604083013567ffffffffffffffff8082111561425257600080fd5b61425e36838701613dc3565b6040840152606085013591508082111561427757600080fd5b5061428436828601613dc3565b6060830152506142973660808501613c19565b60808201526142a93660e08501613c19565b60a082015292915050565b815167ffffffffffffffff8111156142ce576142ce613b15565b6142e2816142dc8454613d11565b84613f0e565b602080601f83116001811461433557600084156142ff5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610b4d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561438257888601518255948401946001909101908401614363565b50858210156143be57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526143f281840187613744565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506144309050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613a70565b60a08152600061447a60a0830187613744565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a0602082015260006144f760a0830186613744565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561453a57600080fd5b815167ffffffffffffffff81111561455157600080fd5b8201601f8101841361456257600080fd5b8051614570613de282613d7d565b81815285602083850101111561458557600080fd5b613a70826020830160208601613720565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561069257610692614596565b67ffffffffffffffff8416815260e0810161462460208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612d9d565b6060810161069282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156146a957600080fd5b8151610f25816137ba565b808202811582820484141761069257610692614596565b8082018082111561069257610692614596565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614743577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082516141f681846020870161372056fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", } var LockReleaseTokenPoolAndProxyABI = LockReleaseTokenPoolAndProxyMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/mock_usdc_token_messenger/mock_usdc_token_messenger.go b/core/gethwrappers/ccip/generated/mock_usdc_token_messenger/mock_usdc_token_messenger.go index cdd66b76cb..4d095a97da 100644 --- a/core/gethwrappers/ccip/generated/mock_usdc_token_messenger/mock_usdc_token_messenger.go +++ b/core/gethwrappers/ccip/generated/mock_usdc_token_messenger/mock_usdc_token_messenger.go @@ -32,7 +32,7 @@ var ( var MockE2EUSDCTokenMessengerMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burnToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"mintRecipient\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"destinationDomain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"destinationTokenMessenger\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"destinationCaller\",\"type\":\"bytes32\"}],\"name\":\"DepositForBurn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DESTINATION_TOKEN_MESSENGER\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"mintRecipient\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"burnToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationCaller\",\"type\":\"bytes32\"}],\"name\":\"depositForBurnWithCaller\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localMessageTransmitter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localMessageTransmitterWithRelay\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitterWithRelay\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageBodyVersion\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_nonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e060405234801561001057600080fd5b5060405161083c38038061083c83398101604081905261002f91610063565b63ffffffff909116608052600080546001600160401b03191660011790556001600160a01b031660a081905260c0526100b2565b6000806040838503121561007657600080fd5b825163ffffffff8116811461008a57600080fd5b60208401519092506001600160a01b03811681146100a757600080fd5b809150509250929050565b60805160a05160c0516107486100f460003960008181610129015281816104aa015261056a01526000607901526000818160fa01526102d801526107486000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063a250c66a11610050578063a250c66a14610124578063f856ddb61461014b578063fb8406a91461015e57600080fd5b80632c121921146100775780637eccf63e146100c35780639cdbb181146100f0575b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6000546100d79067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100ba565b60405163ffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100ba565b6100997f000000000000000000000000000000000000000000000000000000000000000081565b6100d76101593660046105ad565b610193565b6101857f17c71eed51b181d8ae1908b4743526c6dbf099c201f158a1acd5f6718e82e8f681565b6040519081526020016100ba565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810186905260009073ffffffffffffffffffffffffffffffffffffffff8416906323b872dd906064016020604051808303816000875af115801561020f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102339190610621565b506040517f42966c680000000000000000000000000000000000000000000000000000000081526004810187905273ffffffffffffffffffffffffffffffffffffffff8416906342966c6890602401600060405180830381600087803b15801561029c57600080fd5b505af11580156102b0573d6000803e3d6000fd5b50506040517fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e01b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b16602482015260388101879052605881018990523360788201526000925060980190506040516020818303038152906040529050610386867f17c71eed51b181d8ae1908b4743526c6dbf099c201f158a1acd5f6718e82e8f68584610466565b600080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169182179055604080518981526020810188905263ffffffff8916918101919091527f17c71eed51b181d8ae1908b4743526c6dbf099c201f158a1acd5f6718e82e8f6606082015260808101859052339173ffffffffffffffffffffffffffffffffffffffff8716917f2fa9ca894982930190727e75500a97d8dc500233a5065e0f3126c48fbe0343c09060a00160405180910390a4505060005467ffffffffffffffff1695945050505050565b60008261052d576040517f0ba469bc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690630ba469bc906104e3908890889087906004016106ae565b6020604051808303816000875af1158015610502573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052691906106dc565b90506105a5565b6040517ff7259a7500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f7259a75906104e3908890889088908890600401610706565b949350505050565b600080600080600060a086880312156105c557600080fd5b85359450602086013563ffffffff811681146105e057600080fd5b935060408601359250606086013573ffffffffffffffffffffffffffffffffffffffff8116811461061057600080fd5b949793965091946080013592915050565b60006020828403121561063357600080fd5b8151801515811461064357600080fd5b9392505050565b6000815180845260005b8181101561067057602081850181015186830182015201610654565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b63ffffffff841681528260208201526060604082015260006106d3606083018461064a565b95945050505050565b6000602082840312156106ee57600080fd5b815167ffffffffffffffff8116811461064357600080fd5b63ffffffff85168152836020820152826040820152608060608201526000610731608083018461064a565b969550505050505056fea164736f6c6343000818000a", + Bin: "0x60e060405234801561001057600080fd5b5060405161082d38038061082d83398101604081905261002f91610063565b63ffffffff909116608052600080546001600160401b03191660011790556001600160a01b031660a081905260c0526100b2565b6000806040838503121561007657600080fd5b825163ffffffff8116811461008a57600080fd5b60208401519092506001600160a01b03811681146100a757600080fd5b809150509250929050565b60805160a05160c0516107396100f4600039600081816101290152818161049b015261055b01526000607901526000818160fa01526102b801526107396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063a250c66a11610050578063a250c66a14610124578063f856ddb61461014b578063fb8406a91461015e57600080fd5b80632c121921146100775780637eccf63e146100c35780639cdbb181146100f0575b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6000546100d79067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100ba565b60405163ffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100ba565b6100997f000000000000000000000000000000000000000000000000000000000000000081565b6100d761015936600461059e565b610193565b6101857f17c71eed51b181d8ae1908b4743526c6dbf099c201f158a1acd5f6718e82e8f681565b6040519081526020016100ba565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810186905260009073ffffffffffffffffffffffffffffffffffffffff8416906323b872dd906064016020604051808303816000875af115801561020f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102339190610612565b506040517f42966c680000000000000000000000000000000000000000000000000000000081526004810187905273ffffffffffffffffffffffffffffffffffffffff8416906342966c6890602401600060405180830381600087803b15801561029c57600080fd5b505af11580156102b0573d6000803e3d6000fd5b5050604080517f000000000000000000000000000000000000000000000000000000000000000060e01b7fffffffff0000000000000000000000000000000000000000000000000000000016602082015273ffffffffffffffffffffffffffffffffffffffff8716602482015260448101889052606481018a9052336084808301919091528251808303909101815260a490910190915291506103779050867f17c71eed51b181d8ae1908b4743526c6dbf099c201f158a1acd5f6718e82e8f68584610457565b600080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169182179055604080518981526020810188905263ffffffff8916918101919091527f17c71eed51b181d8ae1908b4743526c6dbf099c201f158a1acd5f6718e82e8f6606082015260808101859052339173ffffffffffffffffffffffffffffffffffffffff8716917f2fa9ca894982930190727e75500a97d8dc500233a5065e0f3126c48fbe0343c09060a00160405180910390a4505060005467ffffffffffffffff1695945050505050565b60008261051e576040517f0ba469bc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690630ba469bc906104d49088908890879060040161069f565b6020604051808303816000875af11580156104f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051791906106cd565b9050610596565b6040517ff7259a7500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f7259a75906104d49088908890889088906004016106f7565b949350505050565b600080600080600060a086880312156105b657600080fd5b85359450602086013563ffffffff811681146105d157600080fd5b935060408601359250606086013573ffffffffffffffffffffffffffffffffffffffff8116811461060157600080fd5b949793965091946080013592915050565b60006020828403121561062457600080fd5b8151801515811461063457600080fd5b9392505050565b6000815180845260005b8181101561066157602081850181015186830182015201610645565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b63ffffffff841681528260208201526060604082015260006106c4606083018461063b565b95945050505050565b6000602082840312156106df57600080fd5b815167ffffffffffffffff8116811461063457600080fd5b63ffffffff85168152836020820152826040820152608060608201526000610722608083018461063b565b969550505050505056fea164736f6c6343000818000a", } var MockE2EUSDCTokenMessengerABI = MockE2EUSDCTokenMessengerMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter/mock_usdc_token_transmitter.go b/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter/mock_usdc_token_transmitter.go index b31a834407..c3f12bab37 100644 --- a/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter/mock_usdc_token_transmitter.go +++ b/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter/mock_usdc_token_transmitter.go @@ -32,7 +32,7 @@ var ( var MockE2EUSDCTransmitterMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_version\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"MessageSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextAvailableNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"receiveMessage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_shouldSucceed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"recipient\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"messageBody\",\"type\":\"bytes\"}],\"name\":\"sendMessage\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"recipient\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"destinationCaller\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"messageBody\",\"type\":\"bytes\"}],\"name\":\"sendMessageWithCaller\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"shouldSucceed\",\"type\":\"bool\"}],\"name\":\"setShouldSucceed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e060405234801561001057600080fd5b5060405161097b38038061097b83398101604081905261002f91610076565b63ffffffff928316608052911660a0526000805460ff191660011790556001600160a01b031660c0526100ca565b805163ffffffff8116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005d565b92506100a26020850161005d565b60408501519092506001600160a01b03811681146100bf57600080fd5b809150509250925092565b60805160a05160c0516108756101066000396000610256015260008181610140015261046001526000818160c0015261043f01526108756000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638371744e1161005b5780638371744e146101255780638d3638f41461013e5780639e31ddb614610164578063f7259a75146101a557600080fd5b80630ba469bc1461008d57806354fd4d50146100be57806357ecfd28146100f55780637a64293514610118575b600080fd5b6100a061009b366004610552565b6101b8565b60405167ffffffffffffffff90911681526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405163ffffffff90911681526020016100b5565b6101086101033660046105ac565b6101e1565b60405190151581526020016100b5565b6000546101089060ff1681565b6000546100a090610100900467ffffffffffffffff1681565b7f00000000000000000000000000000000000000000000000000000000000000006100e0565b6101a361017236600461060c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b005b6100a06101b3366004610635565b6102c2565b600080806101c4610372565b9050336101d688888584868b8b6103d4565b509695505050505050565b6000806101f260546040878961069d565b6101fb916106c7565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815260609190911c60048201819052683635c9adc5dea000006024830152915073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561029a57600080fd5b505af11580156102ae573d6000803e3d6000fd5b505060005460ff1698975050505050505050565b600083610356576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f44657374696e6174696f6e2063616c6c6572206d757374206265206e6f6e7a6560448201527f726f00000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000610360610372565b9050336101d688888884868a8a6103d4565b60008054610100900467ffffffffffffffff1661039081600161070f565b6000805467ffffffffffffffff92909216610100027fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff909216919091179055919050565b8561043b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f526563697069656e74206d757374206265206e6f6e7a65726f00000000000000604482015260640161034d565b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008986888b8b898960405160200161049e9998979695949392919061075e565b60405160208183030381529060405290507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036816040516104de91906107fb565b60405180910390a15050505050505050565b803563ffffffff8116811461050457600080fd5b919050565b60008083601f84011261051b57600080fd5b50813567ffffffffffffffff81111561053357600080fd5b60208301915083602082850101111561054b57600080fd5b9250929050565b6000806000806060858703121561056857600080fd5b610571856104f0565b935060208501359250604085013567ffffffffffffffff81111561059457600080fd5b6105a087828801610509565b95989497509550505050565b600080600080604085870312156105c257600080fd5b843567ffffffffffffffff808211156105da57600080fd5b6105e688838901610509565b909650945060208701359150808211156105ff57600080fd5b506105a087828801610509565b60006020828403121561061e57600080fd5b8135801515811461062e57600080fd5b9392505050565b60008060008060006080868803121561064d57600080fd5b610656866104f0565b94506020860135935060408601359250606086013567ffffffffffffffff81111561068057600080fd5b61068c88828901610509565b969995985093965092949392505050565b600080858511156106ad57600080fd5b838611156106ba57600080fd5b5050820193919092039150565b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000081358181169160148510156107075780818660140360031b1b83161692505b505092915050565b67ffffffffffffffff818116838216019080821115610757577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5092915050565b60007fffffffff00000000000000000000000000000000000000000000000000000000808c60e01b168352808b60e01b166004840152808a60e01b166008840152507fffffffffffffffff0000000000000000000000000000000000000000000000008860c01b16600c83015286601483015285603483015284605483015282846074840137506000910160740190815298975050505050505050565b60006020808352835180602085015260005b818110156108295785810183015185820160400152820161080d565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050509291505056fea164736f6c6343000818000a", + Bin: "0x60e060405234801561001057600080fd5b5060405161097338038061097383398101604081905261002f91610076565b63ffffffff928316608052911660a0526000805460ff191660011790556001600160a01b031660c0526100ca565b805163ffffffff8116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005d565b92506100a26020850161005d565b60408501519092506001600160a01b03811681146100bf57600080fd5b809150509250925092565b60805160a05160c05161086d610106600039600061024e015260008181610140015261045801526000818160c00152610437015261086d6000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638371744e1161005b5780638371744e146101255780638d3638f41461013e5780639e31ddb614610164578063f7259a75146101a557600080fd5b80630ba469bc1461008d57806354fd4d50146100be57806357ecfd28146100f55780637a64293514610118575b600080fd5b6100a061009b36600461054a565b6101b8565b60405167ffffffffffffffff90911681526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405163ffffffff90911681526020016100b5565b6101086101033660046105a4565b6101e1565b60405190151581526020016100b5565b6000546101089060ff1681565b6000546100a090610100900467ffffffffffffffff1681565b7f00000000000000000000000000000000000000000000000000000000000000006100e0565b6101a3610172366004610604565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b005b6100a06101b336600461062d565b6102ba565b600080806101c461036a565b9050336101d688888584868b8b6103cc565b509695505050505050565b6000806101f260b860a48789610695565b6101fb916106bf565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815260609190911c6004820181905260016024830152915073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561029257600080fd5b505af11580156102a6573d6000803e3d6000fd5b505060005460ff1698975050505050505050565b60008361034e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f44657374696e6174696f6e2063616c6c6572206d757374206265206e6f6e7a6560448201527f726f00000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b600061035861036a565b9050336101d688888884868a8a6103cc565b60008054610100900467ffffffffffffffff16610388816001610707565b6000805467ffffffffffffffff92909216610100027fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff909216919091179055919050565b85610433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f526563697069656e74206d757374206265206e6f6e7a65726f000000000000006044820152606401610345565b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008986888b8b898960405160200161049699989796959493929190610756565b60405160208183030381529060405290507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036816040516104d691906107f3565b60405180910390a15050505050505050565b803563ffffffff811681146104fc57600080fd5b919050565b60008083601f84011261051357600080fd5b50813567ffffffffffffffff81111561052b57600080fd5b60208301915083602082850101111561054357600080fd5b9250929050565b6000806000806060858703121561056057600080fd5b610569856104e8565b935060208501359250604085013567ffffffffffffffff81111561058c57600080fd5b61059887828801610501565b95989497509550505050565b600080600080604085870312156105ba57600080fd5b843567ffffffffffffffff808211156105d257600080fd5b6105de88838901610501565b909650945060208701359150808211156105f757600080fd5b5061059887828801610501565b60006020828403121561061657600080fd5b8135801515811461062657600080fd5b9392505050565b60008060008060006080868803121561064557600080fd5b61064e866104e8565b94506020860135935060408601359250606086013567ffffffffffffffff81111561067857600080fd5b61068488828901610501565b969995985093965092949392505050565b600080858511156106a557600080fd5b838611156106b257600080fd5b5050820193919092039150565b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000081358181169160148510156106ff5780818660140360031b1b83161692505b505092915050565b67ffffffffffffffff81811683821601908082111561074f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5092915050565b60007fffffffff00000000000000000000000000000000000000000000000000000000808c60e01b168352808b60e01b166004840152808a60e01b166008840152507fffffffffffffffff0000000000000000000000000000000000000000000000008860c01b16600c83015286601483015285603483015284605483015282846074840137506000910160740190815298975050505050505050565b60006020808352835180602085015260005b8181101561082157858101830151858201604001528201610805565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050509291505056fea164736f6c6343000818000a", } var MockE2EUSDCTransmitterABI = MockE2EUSDCTransmitterMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go index 35747dd583..d6b86fdd42 100644 --- a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go +++ b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go @@ -96,7 +96,7 @@ type USDCTokenPoolDomainUpdate struct { var USDCTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b50604051620052dd380380620052dd833981016040819052620000359162000b4c565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200041b565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016957604080516000815260208101909152620001699084620004c6565b5050506001600160a01b038616905062000196576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fd919062000c72565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000240573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000266919062000c99565b905063ffffffff81161562000297576040516334697c6b60e11b815263ffffffff8216600482015260240162000087565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fe919062000c99565b905063ffffffff8116156200032f576040516316ba39c560e31b815263ffffffff8216600482015260240162000087565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa15801562000381573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a7919062000c99565b63ffffffff166101205260e051608051620003d1916001600160a01b039091169060001962000623565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000de6565b336001600160a01b03821603620004755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620004e7576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005725760008382815181106200050b576200050b62000cc1565b602090810291909101015190506200052560028262000709565b1562000568576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620004ea565b5060005b81518110156200061e57600082828151811062000597576200059762000cc1565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005c3575062000615565b620005d060028262000729565b1562000613576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000576565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200069b919062000cd7565b620006a7919062000d07565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000703918691906200074016565b50505050565b600062000720836001600160a01b03841662000811565b90505b92915050565b600062000720836001600160a01b03841662000915565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200078f906001600160a01b03851690849062000967565b8051909150156200061e5780806020019051810190620007b0919062000d1d565b6200061e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000087565b600081815260018301602052604081205480156200090a5760006200083860018362000d41565b85549091506000906200084e9060019062000d41565b9050818114620008ba57600086600001828154811062000872576200087262000cc1565b906000526020600020015490508087600001848154811062000898576200089862000cc1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620008ce57620008ce62000d57565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000723565b600091505062000723565b60008181526001830160205260408120546200095e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000723565b50600062000723565b606062000978848460008562000980565b949350505050565b606082471015620009e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000087565b600080866001600160a01b0316858760405162000a01919062000d93565b60006040518083038185875af1925050503d806000811462000a40576040519150601f19603f3d011682016040523d82523d6000602084013e62000a45565b606091505b50909250905062000a598783838762000a64565b979650505050505050565b6060831562000ad857825160000362000ad0576001600160a01b0385163b62000ad05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000087565b508162000978565b62000978838381511562000aef5781518083602001fd5b8060405162461bcd60e51b815260040162000087919062000db1565b6001600160a01b038116811462000b2157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b478162000b0b565b919050565b600080600080600060a0868803121562000b6557600080fd5b855162000b728162000b0b565b8095505060208087015162000b878162000b0b565b60408801519095506001600160401b038082111562000ba557600080fd5b818901915089601f83011262000bba57600080fd5b81518181111562000bcf5762000bcf62000b24565b8060051b604051601f19603f8301168101818110858211171562000bf75762000bf762000b24565b60405291825284820192508381018501918c83111562000c1657600080fd5b938501935b8285101562000c3f5762000c2f8562000b3a565b8452938501939285019262000c1b565b80985050505050505062000c566060870162000b3a565b915062000c666080870162000b3a565b90509295509295909350565b60006020828403121562000c8557600080fd5b815162000c928162000b0b565b9392505050565b60006020828403121562000cac57600080fd5b815163ffffffff8116811462000c9257600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000cea57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000723576200072362000cf1565b60006020828403121562000d3057600080fd5b8151801515811462000c9257600080fd5b8181038181111562000723576200072362000cf1565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d8a57818101518382015260200162000d70565b50506000910152565b6000825162000da781846020870162000d6d565b9190910192915050565b602081526000825180602084015262000dd281604085016020870162000d6d565b601f01601f19169190910160400192915050565b60805160a05160c05160e051610100516101205161443762000ea6600039600081816103820152818161122401528181611e9c0152611efa0152600081816106760152610a7801526000818161035b015261113801526000818161063a01528181611f9701526128d201526000818161057601528181611c9a015261224d01526000818161028f015281816102e401528181610b260152818161110501528181611bba0152818161216d015281816128680152612abd01526144376000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80639a4575b91161010f578063c75eea9c116100a2578063dfadfa3511610071578063dfadfa351461059a578063e0351e1314610638578063f2fde38b1461065e578063fbf84dd71461067157600080fd5b8063c75eea9c1461053b578063cf7401f31461054e578063db6327dc14610561578063dc0bd9711461057457600080fd5b8063b0f479a1116100de578063b0f479a1146104e2578063b794658014610500578063c0d7865514610513578063c4bffe2b1461052657600080fd5b80639a4575b9146104365780639fdf13ff14610456578063a7cd63b71461045e578063af58d59f1461047357600080fd5b80636155cda01161018757806379ba50971161015657806379ba5097146103ea5780637d54534e146103f25780638926f54f146104055780638da5cb5b1461041857600080fd5b80636155cda0146103565780636b716b0d1461037d5780636d3d1a58146103b957806378a010b2146103d757600080fd5b806321df0da7116101c357806321df0da71461028d578063240028e8146102d4578063390775371461032157806354c8a4f31461034357600080fd5b806241d3c1146101f457806301ffc9a7146102095780630a2fd49314610231578063181f5a7714610251575b600080fd5b610207610202366004613260565b610698565b005b61021c6102173660046132d5565b610835565b60405190151581526020015b60405180910390f35b61024461023f36600461333d565b61091a565b60405161022891906133be565b6102446040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e342e300000000000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610228565b61021c6102e23660046133fe565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61033461032f36600461341b565b6109ca565b60405190518152602001610228565b6102076103513660046134a3565b610c75565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6103a47f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610228565b60085473ffffffffffffffffffffffffffffffffffffffff166102af565b6102076103e536600461350f565b610cf0565b610207610e5f565b6102076104003660046133fe565b610f5c565b61021c61041336600461333d565b610fab565b60005473ffffffffffffffffffffffffffffffffffffffff166102af565b610449610444366004613594565b610fc2565b60405161022891906135cf565b6103a4600081565b61046661129e565b604051610228919061362f565b61048661048136600461333d565b6112af565b604051610228919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102af565b61024461050e36600461333d565b611384565b6102076105213660046133fe565b6113af565b61052e611483565b6040516102289190613689565b61048661054936600461333d565b61153b565b61020761055c366004613814565b61160d565b61020761056f36600461385b565b611696565b7f00000000000000000000000000000000000000000000000000000000000000006102af565b61060e6105a836600461333d565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600982529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610228565b7f000000000000000000000000000000000000000000000000000000000000000061021c565b61020761066c3660046133fe565b611b1c565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6106a0611b30565b60005b818110156107f75760008383838181106106bf576106bf61389d565b9050608002018036038101906106d591906138e0565b805190915015806106f25750604081015167ffffffffffffffff16155b1561076157604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600990925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169190931617929092179055016106a3565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee56828260405161082992919061395a565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806108c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061091457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff81166000908152600760205260409020600401805460609190610945906139e1565b80601f0160208091040260200160405190810160405280929190818152602001828054610971906139e1565b80156109be5780601f10610993576101008083540402835291602001916109be565b820191906000526020600020905b8154815290600101906020018083116109a157829003601f168201915b50505050509050919050565b6040805160208101909152600081526109ea6109e583613adf565b611bb3565b60006109f960c0840184613bd4565b810190610a069190613c39565b90506000610a1760e0850185613bd4565b810190610a249190613c78565b9050610a34816000015183611de4565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aab92600401613d09565b6020604051808303816000875af1158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190613d2e565b610b24576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006040517f095ea7b30000000000000000000000000000000000000000000000000000000081523360048201526060860135602482015273ffffffffffffffffffffffffffffffffffffffff919091169063095ea7b3906044016020604051808303816000875af1158015610bbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be19190613d2e565b50610bf260608501604086016133fe565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610c5491815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b610c7d611b30565b610cea84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f9592505050565b50505050565b610cf8611b30565b610d0183610fab565b610d43576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b67ffffffffffffffff831660009081526007602052604081206004018054610d6a906139e1565b80601f0160208091040260200160405190810160405280929190818152602001828054610d96906139e1565b8015610de35780601f10610db857610100808354040283529160200191610de3565b820191906000526020600020905b815481529060010190602001808311610dc657829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610e12838583613d93565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610e5193929190613eae565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ee0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610758565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610f64611b30565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610914600567ffffffffffffffff841661214b565b6040805180820190915260608082526020820152610fe7610fe283613f12565b612166565b6000600981610ffc604086016020870161333d565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff1615159082018190529091506110a357611064604084016020850161333d565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b602081015181516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060860135600482015263ffffffff90921660248301526044820181905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091526000917f00000000000000000000000000000000000000000000000000000000000000009091169063f856ddb69060a4016020604051808303816000875af1158015611183573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a79190613fb6565b6040516060860135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a2604051806040016040528061120486602001602081019061050e919061333d565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529052949350505050565b60606112aa6002612330565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526109149061233d565b67ffffffffffffffff81166000908152600760205260409020600501805460609190610945906139e1565b6113b7611b30565b73ffffffffffffffffffffffffffffffffffffffff8116611404576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610829565b606060006114916005612330565b90506000815167ffffffffffffffff8111156114af576114af6136cb565b6040519080825280602002602001820160405280156114d8578160200160208202803683370190505b50905060005b8251811015611534578281815181106114f9576114f961389d565b60200260200101518282815181106115135761151361389d565b67ffffffffffffffff909216602092830291909101909101526001016114de565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526109149061233d565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061164d575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611686576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b6116918383836123ef565b505050565b61169e611b30565b60005b818110156116915760008383838181106116bd576116bd61389d565b90506020028101906116cf9190613fd3565b6116d890614011565b90506116ed81608001518260200151156124d9565b6117008160a001518260200151156124d9565b8060200151156119fc5780516117229060059067ffffffffffffffff16612612565b6117675780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b604081015151158061177c5750606081015151155b156117b3576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061199490826140c5565b50606082015160058201906119a990826140c5565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506119ef94939291906141df565b60405180910390a1611b13565b8051611a149060059067ffffffffffffffff1661261e565b611a595780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611ac26004830182613212565b611ad0600583016000613212565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016116a1565b611b24611b30565b611b2d8161262a565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611bb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610758565b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611c485760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611cf6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d1a9190613d2e565b15611d51576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d5e816020015161271f565b6000611d6d826020015161091a565b9050805160001480611d91575080805190602001208260a001518051906020012014155b15611dce578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161075891906133be565b611de082602001518360600151612845565b5050565b600482015163ffffffff811615611e2f576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610758565b6008830151600c8401516014850151602085015163ffffffff808516911614611e9a5760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff91821660048201529084166024820152604401610758565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611f2f576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015283166024820152604401610758565b845167ffffffffffffffff828116911614611f8d5784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821660048201529082166024820152604401610758565b505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611fec576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561208257600083828151811061200c5761200c61389d565b6020026020010151905061202a81600261288c90919063ffffffff16565b156120795760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611fef565b5060005b81518110156116915760008282815181106120a3576120a361389d565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120e75750612143565b6120f26002826128ae565b156121415760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612086565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121fb5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156122a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122cd9190613d2e565b15612304576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61231181604001516128d0565b61231e816020015161294f565b611b2d81602001518260600151612a9d565b6060600061215f83612ae1565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526123cb82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426123af91906142a7565b85608001516fffffffffffffffffffffffffffffffff16612b3c565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6123f883610fab565b61243a576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b6124458260006124d9565b67ffffffffffffffff831660009081526007602052604090206124689083612b66565b6124738160006124d9565b67ffffffffffffffff831660009081526007602052604090206124999060020182612b66565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516124cc939291906142ba565b60405180910390a1505050565b8151156125a05781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061252f575060408201516fffffffffffffffffffffffffffffffff16155b1561256857816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610758919061433d565b8015611de0576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806125d9575060208201516fffffffffffffffffffffffffffffffff1615155b15611de057816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610758919061433d565b600061215f8383612d08565b600061215f8383612d57565b3373ffffffffffffffffffffffffffffffffffffffff8216036126a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610758565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61272881610fab565b61276a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156127e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280d9190613d2e565b611b2d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611de090600201827f0000000000000000000000000000000000000000000000000000000000000000612e4a565b600061215f8373ffffffffffffffffffffffffffffffffffffffff8416612d57565b600061215f8373ffffffffffffffffffffffffffffffffffffffff8416612d08565b7f000000000000000000000000000000000000000000000000000000000000000015611b2d576129016002826131cd565b611b2d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610758565b61295881610fab565b61299a576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612a13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a379190614379565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b2d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611de090827f0000000000000000000000000000000000000000000000000000000000000000612e4a565b6060816000018054806020026020016040519081016040528092919081815260200182805480156109be57602002820191906000526020600020905b815481526020019060010190808311612b1d5750505050509050919050565b6000612b5b85612b4c8486614396565b612b5690876143ad565b6131fc565b90505b949350505050565b8154600090612b8f90700100000000000000000000000000000000900463ffffffff16426142a7565b90508015612c315760018301548354612bd7916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b3c565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c57916fffffffffffffffffffffffffffffffff90811691166131fc565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906124cc90849061433d565b6000818152600183016020526040812054612d4f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610914565b506000610914565b60008181526001830160205260408120548015612e40576000612d7b6001836142a7565b8554909150600090612d8f906001906142a7565b9050818114612df4576000866000018281548110612daf57612daf61389d565b9060005260206000200154905080876000018481548110612dd257612dd261389d565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612e0557612e056143c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610914565b6000915050610914565b825474010000000000000000000000000000000000000000900460ff161580612e71575081155b15612e7b57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612ec190700100000000000000000000000000000000900463ffffffff16426142a7565b90508015612f815781831115612f03576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612f3d9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b3c565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156130385773ffffffffffffffffffffffffffffffffffffffff8416612fe0576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610758565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610758565b8483101561314b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061307c90826142a7565b613086878a6142a7565b61309091906143ad565b61309a91906143ef565b905073ffffffffffffffffffffffffffffffffffffffff86166130f3576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610758565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610758565b61315585846142a7565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561215f565b600081831061320b578161215f565b5090919050565b50805461321e906139e1565b6000825580601f1061322e575050565b601f016020900490600052602060002090810190611b2d91905b8082111561325c5760008155600101613248565b5090565b6000806020838503121561327357600080fd5b823567ffffffffffffffff8082111561328b57600080fd5b818501915085601f83011261329f57600080fd5b8135818111156132ae57600080fd5b8660208260071b85010111156132c357600080fd5b60209290920196919550909350505050565b6000602082840312156132e757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461215f57600080fd5b67ffffffffffffffff81168114611b2d57600080fd5b803561333881613317565b919050565b60006020828403121561334f57600080fd5b813561215f81613317565b6000815180845260005b8181101561338057602081850181015186830182015201613364565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061215f602083018461335a565b73ffffffffffffffffffffffffffffffffffffffff81168114611b2d57600080fd5b8035613338816133d1565b60006020828403121561341057600080fd5b813561215f816133d1565b60006020828403121561342d57600080fd5b813567ffffffffffffffff81111561344457600080fd5b8201610100818503121561215f57600080fd5b60008083601f84011261346957600080fd5b50813567ffffffffffffffff81111561348157600080fd5b6020830191508360208260051b850101111561349c57600080fd5b9250929050565b600080600080604085870312156134b957600080fd5b843567ffffffffffffffff808211156134d157600080fd5b6134dd88838901613457565b909650945060208701359150808211156134f657600080fd5b5061350387828801613457565b95989497509550505050565b60008060006040848603121561352457600080fd5b833561352f81613317565b9250602084013567ffffffffffffffff8082111561354c57600080fd5b818601915086601f83011261356057600080fd5b81358181111561356f57600080fd5b87602082850101111561358157600080fd5b6020830194508093505050509250925092565b6000602082840312156135a657600080fd5b813567ffffffffffffffff8111156135bd57600080fd5b820160a0818503121561215f57600080fd5b6020815260008251604060208401526135eb606084018261335a565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613626828261335a565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561367d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161364b565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561367d57835167ffffffffffffffff16835292840192918401916001016136a5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561371e5761371e6136cb565b60405290565b6040805190810167ffffffffffffffff8111828210171561371e5761371e6136cb565b60405160c0810167ffffffffffffffff8111828210171561371e5761371e6136cb565b8015158114611b2d57600080fd5b80356133388161376a565b80356fffffffffffffffffffffffffffffffff8116811461333857600080fd5b6000606082840312156137b557600080fd5b6040516060810181811067ffffffffffffffff821117156137d8576137d86136cb565b60405290508082356137e98161376a565b81526137f760208401613783565b602082015261380860408401613783565b60408201525092915050565b600080600060e0848603121561382957600080fd5b833561383481613317565b925061384385602086016137a3565b915061385285608086016137a3565b90509250925092565b6000806020838503121561386e57600080fd5b823567ffffffffffffffff81111561388557600080fd5b61389185828601613457565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff8116811461333857600080fd5b6000608082840312156138f257600080fd5b6040516080810181811067ffffffffffffffff82111715613915576139156136cb565b60405282358152613928602084016138cc565b6020820152604083013561393b81613317565b6040820152606083013561394e8161376a565b60608201529392505050565b6020808252818101839052600090604080840186845b878110156139d4578135835263ffffffff61398c8684016138cc565b16858401528382013561399e81613317565b67ffffffffffffffff16838501526060828101356139bb8161376a565b1515908401526080928301929190910190600101613970565b5090979650505050505050565b600181811c908216806139f557607f821691505b602082108103613a2e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f830112613a4557600080fd5b813567ffffffffffffffff80821115613a6057613a606136cb565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613aa657613aa66136cb565b81604052838152866020858801011115613abf57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613af257600080fd5b613afa6136fa565b823567ffffffffffffffff80821115613b1257600080fd5b613b1e36838701613a34565b8352613b2c6020860161332d565b6020840152613b3d604086016133f3565b604084015260608501356060840152613b58608086016133f3565b608084015260a0850135915080821115613b7157600080fd5b613b7d36838701613a34565b60a084015260c0850135915080821115613b9657600080fd5b613ba236838701613a34565b60c084015260e0850135915080821115613bbb57600080fd5b50613bc836828601613a34565b60e08301525092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c0957600080fd5b83018035915067ffffffffffffffff821115613c2457600080fd5b60200191503681900382131561349c57600080fd5b600060408284031215613c4b57600080fd5b613c53613724565b8235613c5e81613317565b8152613c6c602084016138cc565b60208201529392505050565b600060208284031215613c8a57600080fd5b813567ffffffffffffffff80821115613ca257600080fd5b9083019060408286031215613cb657600080fd5b613cbe613724565b823582811115613ccd57600080fd5b613cd987828601613a34565b825250602083013582811115613cee57600080fd5b613cfa87828601613a34565b60208301525095945050505050565b604081526000613d1c604083018561335a565b8281036020840152613626818561335a565b600060208284031215613d4057600080fd5b815161215f8161376a565b601f821115611691576000816000526020600020601f850160051c81016020861015613d745750805b601f850160051c820191505b81811015611f8d57828155600101613d80565b67ffffffffffffffff831115613dab57613dab6136cb565b613dbf83613db983546139e1565b83613d4b565b6000601f841160018114613e115760008515613ddb5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613ea7565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613e605786850135825560209485019460019092019101613e40565b5086821015613e9b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613ec1604083018661335a565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613f2457600080fd5b60405160a0810167ffffffffffffffff8282108183111715613f4857613f486136cb565b816040528435915080821115613f5d57600080fd5b50613f6a36828601613a34565b8252506020830135613f7b81613317565b60208201526040830135613f8e816133d1565b6040820152606083810135908201526080830135613fab816133d1565b608082015292915050565b600060208284031215613fc857600080fd5b815161215f81613317565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261400757600080fd5b9190910192915050565b6000610140823603121561402457600080fd5b61402c613747565b6140358361332d565b815261404360208401613778565b6020820152604083013567ffffffffffffffff8082111561406357600080fd5b61406f36838701613a34565b6040840152606085013591508082111561408857600080fd5b5061409536828601613a34565b6060830152506140a836608085016137a3565b60808201526140ba3660e085016137a3565b60a082015292915050565b815167ffffffffffffffff8111156140df576140df6136cb565b6140f3816140ed84546139e1565b84613d4b565b602080601f83116001811461414657600084156141105750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611f8d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561419357888601518255948401946001909101908401614174565b50858210156141cf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526142038184018761335a565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506142419050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613626565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561091457610914614278565b67ffffffffffffffff8416815260e0810161430660208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612b5e565b6060810161091482848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561438b57600080fd5b815161215f816133d1565b808202811582820484141761091457610914614278565b8082018082111561091457610914614278565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614425577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + Bin: "0x6101406040523480156200001257600080fd5b50604051620052c6380380620052c6833981016040819052620000359162000b4c565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200041b565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016957604080516000815260208101909152620001699084620004c6565b5050506001600160a01b038616905062000196576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fd919062000c72565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000240573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000266919062000c99565b905063ffffffff81161562000297576040516334697c6b60e11b815263ffffffff8216600482015260240162000087565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fe919062000c99565b905063ffffffff8116156200032f576040516316ba39c560e31b815263ffffffff8216600482015260240162000087565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa15801562000381573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a7919062000c99565b63ffffffff166101205260e051608051620003d1916001600160a01b039091169060001962000623565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000de6565b336001600160a01b03821603620004755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620004e7576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005725760008382815181106200050b576200050b62000cc1565b602090810291909101015190506200052560028262000709565b1562000568576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620004ea565b5060005b81518110156200061e57600082828151811062000597576200059762000cc1565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005c3575062000615565b620005d060028262000729565b1562000613576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000576565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200069b919062000cd7565b620006a7919062000d07565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000703918691906200074016565b50505050565b600062000720836001600160a01b03841662000811565b90505b92915050565b600062000720836001600160a01b03841662000915565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200078f906001600160a01b03851690849062000967565b8051909150156200061e5780806020019051810190620007b0919062000d1d565b6200061e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000087565b600081815260018301602052604081205480156200090a5760006200083860018362000d41565b85549091506000906200084e9060019062000d41565b9050818114620008ba57600086600001828154811062000872576200087262000cc1565b906000526020600020015490508087600001848154811062000898576200089862000cc1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620008ce57620008ce62000d57565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000723565b600091505062000723565b60008181526001830160205260408120546200095e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000723565b50600062000723565b606062000978848460008562000980565b949350505050565b606082471015620009e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000087565b600080866001600160a01b0316858760405162000a01919062000d93565b60006040518083038185875af1925050503d806000811462000a40576040519150601f19603f3d011682016040523d82523d6000602084013e62000a45565b606091505b50909250905062000a598783838762000a64565b979650505050505050565b6060831562000ad857825160000362000ad0576001600160a01b0385163b62000ad05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000087565b508162000978565b62000978838381511562000aef5781518083602001fd5b8060405162461bcd60e51b815260040162000087919062000db1565b6001600160a01b038116811462000b2157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b478162000b0b565b919050565b600080600080600060a0868803121562000b6557600080fd5b855162000b728162000b0b565b8095505060208087015162000b878162000b0b565b60408801519095506001600160401b038082111562000ba557600080fd5b818901915089601f83011262000bba57600080fd5b81518181111562000bcf5762000bcf62000b24565b8060051b604051601f19603f8301168101818110858211171562000bf75762000bf762000b24565b60405291825284820192508381018501918c83111562000c1657600080fd5b938501935b8285101562000c3f5762000c2f8562000b3a565b8452938501939285019262000c1b565b80985050505050505062000c566060870162000b3a565b915062000c666080870162000b3a565b90509295509295909350565b60006020828403121562000c8557600080fd5b815162000c928162000b0b565b9392505050565b60006020828403121562000cac57600080fd5b815163ffffffff8116811462000c9257600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000cea57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000723576200072362000cf1565b60006020828403121562000d3057600080fd5b8151801515811462000c9257600080fd5b8181038181111562000723576200072362000cf1565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d8a57818101518382015260200162000d70565b50506000910152565b6000825162000da781846020870162000d6d565b9190910192915050565b602081526000825180602084015262000dd281604085016020870162000d6d565b601f01601f19169190910160400192915050565b60805160a05160c05160e051610100516101205161442762000e9f60003960008181610382015281816111d101528181611e4a0152611ea80152600081816106760152610a7801526000818161035b01526110e701526000818161063a01528181611f45015261288001526000818161057601528181611c4801526121fb01526000818161028f015281816102e4015281816110b101528181611b680152818161211b015281816128160152612a6b01526144276000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80639a4575b91161010f578063c75eea9c116100a2578063dfadfa3511610071578063dfadfa351461059a578063e0351e1314610638578063f2fde38b1461065e578063fbf84dd71461067157600080fd5b8063c75eea9c1461053b578063cf7401f31461054e578063db6327dc14610561578063dc0bd9711461057457600080fd5b8063b0f479a1116100de578063b0f479a1146104e2578063b794658014610500578063c0d7865514610513578063c4bffe2b1461052657600080fd5b80639a4575b9146104365780639fdf13ff14610456578063a7cd63b71461045e578063af58d59f1461047357600080fd5b80636155cda01161018757806379ba50971161015657806379ba5097146103ea5780637d54534e146103f25780638926f54f146104055780638da5cb5b1461041857600080fd5b80636155cda0146103565780636b716b0d1461037d5780636d3d1a58146103b957806378a010b2146103d757600080fd5b806321df0da7116101c357806321df0da71461028d578063240028e8146102d4578063390775371461032157806354c8a4f31461034357600080fd5b806241d3c1146101f457806301ffc9a7146102095780630a2fd49314610231578063181f5a7714610251575b600080fd5b61020761020236600461320e565b610698565b005b61021c610217366004613283565b610835565b60405190151581526020015b60405180910390f35b61024461023f3660046132eb565b61091a565b604051610228919061336c565b6102446040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e342e300000000000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610228565b61021c6102e23660046133ac565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61033461032f3660046133c9565b6109ca565b60405190518152602001610228565b610207610351366004613451565b610bb7565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6103a47f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610228565b60085473ffffffffffffffffffffffffffffffffffffffff166102af565b6102076103e53660046134bd565b610c32565b610207610da1565b6102076104003660046133ac565b610e9e565b61021c6104133660046132eb565b610eed565b60005473ffffffffffffffffffffffffffffffffffffffff166102af565b610449610444366004613542565b610f04565b604051610228919061357d565b6103a4600081565b61046661124c565b60405161022891906135dd565b6104866104813660046132eb565b61125d565b604051610228919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102af565b61024461050e3660046132eb565b611332565b6102076105213660046133ac565b61135d565b61052e611431565b6040516102289190613637565b6104866105493660046132eb565b6114e9565b61020761055c3660046137c2565b6115bb565b61020761056f366004613809565b611644565b7f00000000000000000000000000000000000000000000000000000000000000006102af565b61060e6105a83660046132eb565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600982529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610228565b7f000000000000000000000000000000000000000000000000000000000000000061021c565b61020761066c3660046133ac565b611aca565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6106a0611ade565b60005b818110156107f75760008383838181106106bf576106bf61384b565b9050608002018036038101906106d5919061388e565b805190915015806106f25750604081015167ffffffffffffffff16155b1561076157604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600990925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169190931617929092179055016106a3565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee568282604051610829929190613908565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806108c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061091457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906109459061398f565b80601f01602080910402602001604051908101604052809291908181526020018280546109719061398f565b80156109be5780601f10610993576101008083540402835291602001916109be565b820191906000526020600020905b8154815290600101906020018083116109a157829003601f168201915b50505050509050919050565b6040805160208101909152600081526109ea6109e583613a8d565b611b61565b60006109f960c0840184613b82565b810190610a069190613be7565b90506000610a1760e0850185613b82565b810190610a249190613c26565b9050610a34816000015183611d92565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aab92600401613cb7565b6020604051808303816000875af1158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190613cdc565b610b24576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3460608501604086016133ac565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610b9691815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b610bbf611ade565b610c2c84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f4392505050565b50505050565b610c3a611ade565b610c4383610eed565b610c85576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b67ffffffffffffffff831660009081526007602052604081206004018054610cac9061398f565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd89061398f565b8015610d255780601f10610cfa57610100808354040283529160200191610d25565b820191906000526020600020905b815481529060010190602001808311610d0857829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610d54838583613d41565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d9393929190613ea5565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610758565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ea6611ade565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610914600567ffffffffffffffff84166120f9565b6040805180820190915260608082526020820152610f29610f2483613ed5565b612114565b6000600981610f3e60408601602087016132eb565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff161515908201819052909150610fe557610fa660408401602085016132eb565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b610fef8380613b82565b9050602014611036576110028380613b82565b6040517fa3c8cf09000000000000000000000000000000000000000000000000000000008152600401610758929190613f79565b60006110428480613b82565b81019061104f9190613f8d565b602083015183516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060880135600482015263ffffffff90921660248301526044820183905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063f856ddb69060a4016020604051808303816000875af1158015611130573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111549190613fa6565b6040516060870135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260405180604001604052806111b187602001602081019061050e91906132eb565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905295945050505050565b606061125860026122de565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610914906122eb565b67ffffffffffffffff811660009081526007602052604090206005018054606091906109459061398f565b611365611ade565b73ffffffffffffffffffffffffffffffffffffffff81166113b2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610829565b6060600061143f60056122de565b90506000815167ffffffffffffffff81111561145d5761145d613679565b604051908082528060200260200182016040528015611486578160200160208202803683370190505b50905060005b82518110156114e2578281815181106114a7576114a761384b565b60200260200101518282815181106114c1576114c161384b565b67ffffffffffffffff9092166020928302919091019091015260010161148c565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610914906122eb565b60085473ffffffffffffffffffffffffffffffffffffffff1633148015906115fb575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611634576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b61163f83838361239d565b505050565b61164c611ade565b60005b8181101561163f57600083838381811061166b5761166b61384b565b905060200281019061167d9190613fc3565b61168690614001565b905061169b8160800151826020015115612487565b6116ae8160a00151826020015115612487565b8060200151156119aa5780516116d09060059067ffffffffffffffff166125c0565b6117155780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b604081015151158061172a5750606081015151155b15611761576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061194290826140b5565b506060820151600582019061195790826140b5565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061199d94939291906141cf565b60405180910390a1611ac1565b80516119c29060059067ffffffffffffffff166125cc565b611a075780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611a7060048301826131c0565b611a7e6005830160006131c0565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161164f565b611ad2611ade565b611adb816125d8565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610758565b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611bf65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc89190613cdc565b15611cff576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d0c81602001516126cd565b6000611d1b826020015161091a565b9050805160001480611d3f575080805190602001208260a001518051906020012014155b15611d7c578160a001516040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610758919061336c565b611d8e826020015183606001516127f3565b5050565b600482015163ffffffff811615611ddd576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610758565b6008830151600c8401516014850151602085015163ffffffff808516911614611e485760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff91821660048201529084166024820152604401610758565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611edd576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015283166024820152604401610758565b845167ffffffffffffffff828116911614611f3b5784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821660048201529082166024820152604401610758565b505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611f9a576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612030576000838281518110611fba57611fba61384b565b60200260200101519050611fd881600261283a90919063ffffffff16565b156120275760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f9d565b5060005b815181101561163f5760008282815181106120515761205161384b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361209557506120f1565b6120a060028261285c565b156120ef5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612034565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121a95760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227b9190613cdc565b156122b2576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122bf816040015161287e565b6122cc81602001516128fd565b611adb81602001518260600151612a4b565b6060600061210d83612a8f565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261237982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261235d9190614297565b85608001516fffffffffffffffffffffffffffffffff16612aea565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6123a683610eed565b6123e8576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b6123f3826000612487565b67ffffffffffffffff831660009081526007602052604090206124169083612b14565b612421816000612487565b67ffffffffffffffff831660009081526007602052604090206124479060020182612b14565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161247a939291906142aa565b60405180910390a1505050565b81511561254e5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806124dd575060408201516fffffffffffffffffffffffffffffffff16155b1561251657816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610758919061432d565b8015611d8e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612587575060208201516fffffffffffffffffffffffffffffffff1615155b15611d8e57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610758919061432d565b600061210d8383612cb6565b600061210d8383612d05565b3373ffffffffffffffffffffffffffffffffffffffff821603612657576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610758565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6126d681610eed565b612718576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612797573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127bb9190613cdc565b611adb576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d8e90600201827f0000000000000000000000000000000000000000000000000000000000000000612df8565b600061210d8373ffffffffffffffffffffffffffffffffffffffff8416612d05565b600061210d8373ffffffffffffffffffffffffffffffffffffffff8416612cb6565b7f000000000000000000000000000000000000000000000000000000000000000015611adb576128af60028261317b565b611adb576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610758565b61290681610eed565b612948576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156129c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e59190614369565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611adb576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d8e90827f0000000000000000000000000000000000000000000000000000000000000000612df8565b6060816000018054806020026020016040519081016040528092919081815260200182805480156109be57602002820191906000526020600020905b815481526020019060010190808311612acb5750505050509050919050565b6000612b0985612afa8486614386565b612b04908761439d565b6131aa565b90505b949350505050565b8154600090612b3d90700100000000000000000000000000000000900463ffffffff1642614297565b90508015612bdf5760018301548354612b85916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612aea565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c05916fffffffffffffffffffffffffffffffff90811691166131aa565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061247a90849061432d565b6000818152600183016020526040812054612cfd57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610914565b506000610914565b60008181526001830160205260408120548015612dee576000612d29600183614297565b8554909150600090612d3d90600190614297565b9050818114612da2576000866000018281548110612d5d57612d5d61384b565b9060005260206000200154905080876000018481548110612d8057612d8061384b565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612db357612db36143b0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610914565b6000915050610914565b825474010000000000000000000000000000000000000000900460ff161580612e1f575081155b15612e2957505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612e6f90700100000000000000000000000000000000900463ffffffff1642614297565b90508015612f2f5781831115612eb1576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612eeb9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612aea565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612fe65773ffffffffffffffffffffffffffffffffffffffff8416612f8e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610758565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610758565b848310156130f95760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061302a9082614297565b613034878a614297565b61303e919061439d565b61304891906143df565b905073ffffffffffffffffffffffffffffffffffffffff86166130a1576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610758565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610758565b6131038584614297565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561210d565b60008183106131b9578161210d565b5090919050565b5080546131cc9061398f565b6000825580601f106131dc575050565b601f016020900490600052602060002090810190611adb91905b8082111561320a57600081556001016131f6565b5090565b6000806020838503121561322157600080fd5b823567ffffffffffffffff8082111561323957600080fd5b818501915085601f83011261324d57600080fd5b81358181111561325c57600080fd5b8660208260071b850101111561327157600080fd5b60209290920196919550909350505050565b60006020828403121561329557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461210d57600080fd5b67ffffffffffffffff81168114611adb57600080fd5b80356132e6816132c5565b919050565b6000602082840312156132fd57600080fd5b813561210d816132c5565b6000815180845260005b8181101561332e57602081850181015186830182015201613312565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061210d6020830184613308565b73ffffffffffffffffffffffffffffffffffffffff81168114611adb57600080fd5b80356132e68161337f565b6000602082840312156133be57600080fd5b813561210d8161337f565b6000602082840312156133db57600080fd5b813567ffffffffffffffff8111156133f257600080fd5b8201610100818503121561210d57600080fd5b60008083601f84011261341757600080fd5b50813567ffffffffffffffff81111561342f57600080fd5b6020830191508360208260051b850101111561344a57600080fd5b9250929050565b6000806000806040858703121561346757600080fd5b843567ffffffffffffffff8082111561347f57600080fd5b61348b88838901613405565b909650945060208701359150808211156134a457600080fd5b506134b187828801613405565b95989497509550505050565b6000806000604084860312156134d257600080fd5b83356134dd816132c5565b9250602084013567ffffffffffffffff808211156134fa57600080fd5b818601915086601f83011261350e57600080fd5b81358181111561351d57600080fd5b87602082850101111561352f57600080fd5b6020830194508093505050509250925092565b60006020828403121561355457600080fd5b813567ffffffffffffffff81111561356b57600080fd5b820160a0818503121561210d57600080fd5b6020815260008251604060208401526135996060840182613308565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526135d48282613308565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561362b57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016135f9565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561362b57835167ffffffffffffffff1683529284019291840191600101613653565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156136cc576136cc613679565b60405290565b6040805190810167ffffffffffffffff811182821017156136cc576136cc613679565b60405160c0810167ffffffffffffffff811182821017156136cc576136cc613679565b8015158114611adb57600080fd5b80356132e681613718565b80356fffffffffffffffffffffffffffffffff811681146132e657600080fd5b60006060828403121561376357600080fd5b6040516060810181811067ffffffffffffffff8211171561378657613786613679565b604052905080823561379781613718565b81526137a560208401613731565b60208201526137b660408401613731565b60408201525092915050565b600080600060e084860312156137d757600080fd5b83356137e2816132c5565b92506137f18560208601613751565b91506138008560808601613751565b90509250925092565b6000806020838503121561381c57600080fd5b823567ffffffffffffffff81111561383357600080fd5b61383f85828601613405565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff811681146132e657600080fd5b6000608082840312156138a057600080fd5b6040516080810181811067ffffffffffffffff821117156138c3576138c3613679565b604052823581526138d66020840161387a565b602082015260408301356138e9816132c5565b604082015260608301356138fc81613718565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613982578135835263ffffffff61393a86840161387a565b16858401528382013561394c816132c5565b67ffffffffffffffff168385015260608281013561396981613718565b151590840152608092830192919091019060010161391e565b5090979650505050505050565b600181811c908216806139a357607f821691505b6020821081036139dc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126139f357600080fd5b813567ffffffffffffffff80821115613a0e57613a0e613679565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613a5457613a54613679565b81604052838152866020858801011115613a6d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613aa057600080fd5b613aa86136a8565b823567ffffffffffffffff80821115613ac057600080fd5b613acc368387016139e2565b8352613ada602086016132db565b6020840152613aeb604086016133a1565b604084015260608501356060840152613b06608086016133a1565b608084015260a0850135915080821115613b1f57600080fd5b613b2b368387016139e2565b60a084015260c0850135915080821115613b4457600080fd5b613b50368387016139e2565b60c084015260e0850135915080821115613b6957600080fd5b50613b76368286016139e2565b60e08301525092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613bb757600080fd5b83018035915067ffffffffffffffff821115613bd257600080fd5b60200191503681900382131561344a57600080fd5b600060408284031215613bf957600080fd5b613c016136d2565b8235613c0c816132c5565b8152613c1a6020840161387a565b60208201529392505050565b600060208284031215613c3857600080fd5b813567ffffffffffffffff80821115613c5057600080fd5b9083019060408286031215613c6457600080fd5b613c6c6136d2565b823582811115613c7b57600080fd5b613c87878286016139e2565b825250602083013582811115613c9c57600080fd5b613ca8878286016139e2565b60208301525095945050505050565b604081526000613cca6040830185613308565b82810360208401526135d48185613308565b600060208284031215613cee57600080fd5b815161210d81613718565b601f82111561163f576000816000526020600020601f850160051c81016020861015613d225750805b601f850160051c820191505b81811015611f3b57828155600101613d2e565b67ffffffffffffffff831115613d5957613d59613679565b613d6d83613d67835461398f565b83613cf9565b6000601f841160018114613dbf5760008515613d895750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613e55565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613e0e5786850135825560209485019460019092019101613dee565b5086821015613e49577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000613eb86040830186613308565b8281036020840152613ecb818587613e5c565b9695505050505050565b600060a08236031215613ee757600080fd5b60405160a0810167ffffffffffffffff8282108183111715613f0b57613f0b613679565b816040528435915080821115613f2057600080fd5b50613f2d368286016139e2565b8252506020830135613f3e816132c5565b60208201526040830135613f518161337f565b6040820152606083810135908201526080830135613f6e8161337f565b608082015292915050565b602081526000612b0c602083018486613e5c565b600060208284031215613f9f57600080fd5b5035919050565b600060208284031215613fb857600080fd5b815161210d816132c5565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ff757600080fd5b9190910192915050565b6000610140823603121561401457600080fd5b61401c6136f5565b614025836132db565b815261403360208401613726565b6020820152604083013567ffffffffffffffff8082111561405357600080fd5b61405f368387016139e2565b6040840152606085013591508082111561407857600080fd5b50614085368286016139e2565b6060830152506140983660808501613751565b60808201526140aa3660e08501613751565b60a082015292915050565b815167ffffffffffffffff8111156140cf576140cf613679565b6140e3816140dd845461398f565b84613cf9565b602080601f83116001811461413657600084156141005750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611f3b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561418357888601518255948401946001909101908401614164565b50858210156141bf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526141f381840187613308565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506142319050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526135d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561091457610914614268565b67ffffffffffffffff8416815260e081016142f660208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612b0c565b6060810161091482848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561437b57600080fd5b815161210d8161337f565b808202811582820484141761091457610914614268565b8082018082111561091457610914614268565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614415577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var USDCTokenPoolABI = USDCTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 8498d2aabf..8be2d0b4dd 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,26 +1,26 @@ GETH_VERSION: 1.13.8 arm_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 763c7d81e782d7c286d4a5892aeebe71984a1f999a50a051c87f5b8f9c70cc26 arm_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 -burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 02e37792e25155ab4e7e4b4211002180789d0c1559cad1e38d3bd70efe0fb7d6 -burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 4b1b468de62a7e9adffd4d8ccb3621a7e0658ae453a4bfa72493ae25362e9693 -burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin b1c6188532aacf44b81d833c123131b81e0fd3ee7ef95ba29a9ba1b6ff6b30c9 -burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 94c361ae328eca24b24ce236080ff2e898cc037ee0d4cd1f3802f7ee75d7cc8d +burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 2ac7ec65a85f4e61299b05c7b8636bbd65c91639a919833b350995f2ca25d831 +burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 65bc164ed57bb04f39cef8fcdf4872607b7fc21850a0d99ffa670e91a69b4b6b +burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 4bcdd2b9332442c3659ffb5bcbd459aede3bcde27af0a72ee4fa198bcade6a1d +burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 0202f23e5691696d5a61ae4bd23f73b1dc2651837d0e477e1ddaf489e63e4466 ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 970bf6a2a817813eb3302c92ec3ad0bc0fc6c2e693f33c13f57733d003f44d0d ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin fcced2263564f51b5bf086c221e813ec06a71d2bb2e246b4e28cd60098a6de6f commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin ddc26c10c2a52b59624faae9005827b09b98db4566887a736005e8cc37cf8a51 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin ebd8aac686fa28a71d4212bcd25a28f8f640d50dce5e50498b2f6b8534890b69 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de -evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 2b3284f25be1c46ad1c7896fef47d812133e0bdb78cf5e48618c4f3aba5fe3d4 +evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 2dbf7d8b03e1802beb9185ff2ea7d160250d1969f976e4f52040138d5416cc86 evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 15cd5695049ab4be1f396ec1d7b609738b2bcefa3740a7a48316e1f72506a34a -evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin ea2a9622ace941075ea62cd348e9c69c5aa3bf8a7daf298fea51984f80a1d27d +evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin 670b36a168a0a7cd721148a6065d019c7af4d8dcc08ba6ab8945789e164dd27b evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin bf1a3090a2f8d1632b82a6d45200cf6f3833a1e27303745405c1ed13ffc0cf83 -lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin ee60ad24918c9652ef4b251236dd3390cce651b685e94532bf3bde2a111fe6b9 -lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin e23f4fd063eb3a289d651016ac45fcef72607ce2b571cba134e2bf35590c114d +lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin eadd37962f8011a86af54383ba3e0ae08c2987e2cda577c993f47b30c5b7672a +lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin 82aaf0c20f2802bce3a831d585b497d2918513c6d72f81684c10f77631932526 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin 1d5146d43e1b99cd2d6f9f06475be19087e4349f7cee0fdbbf134ba65e967c93 mock_arm_contract: ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.abi ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.bin e7a3a6c3eda5fb882e16bcc2b4340f78523acb67907bcdcaf3c8ffc51488688e -mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin e0cf17a38b438239fc6294ddca88f86b6c39e4542aefd9815b2d92987191b8bd -mock_usdc_token_transmitter: ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin 33bdad70822e889de7c720ed20085cf9cd3f8eba8b68f26bd6535197749595fe +mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin d976651d36b33ac2196b32b9d2f4fa6690c6a18d41b621365659fce1c1d1e737 +mock_usdc_token_transmitter: ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin be0dbc3e475741ea0b7a54ec2b935a321b428baa9f4ce18180a87fb38bb87de2 mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin 518e19efa2ff52b0fefd8e597b05765317ee7638189bfe34ca43de2f6599faf4 multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin 44e1f40d928fd0e1f36e1ee5edfb6ab2a54fee0174e5f83c57a06cf79ec0c96c multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin aa299e0c2659d53aad4eace4d66be0e734b1366008593669cf30361ff529da6a @@ -34,5 +34,5 @@ router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/sol self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 86e169636e5633854ed0b709c804066b615040bceba25aa5137450fbe6f76fa3 token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin fb06d2cf5f7476e512c6fb7aab8eab43545efd7f0f6ca133c64ff4e3963902c4 token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 7c01fd89f5153baa4d7409d14beabb3f861abfbf8880d3c6d06802cc398570f9 -usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin b92eaf3434896056300f38f4ad0fa8b84879e9dea2e6240a67e48688c09bf06b +usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin 4ca8b09185820ecfa89c4d87a38a66ccd8c3dadb82652782067a3827ec949aa1 weth9: ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin 2970d79a0ca6dd6279cde130de45e56c8790ed695eae477fb5ba4c1bb75b720d From 2ce22d13c2a0d8cf25e1fc252683dcf940a24942 Mon Sep 17 00:00:00 2001 From: kanth <70688600+defistar@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:57:02 +0530 Subject: [PATCH 198/432] Manual-execute-gas-overrides (#1256) currently, gas amounts are placed in the SourceTokenData. However, for the multi-ramps, the token data should be chain-family agnostic, which will likely require the destGasAmount lift to another field - add a new Struct which holds the receiverExecutionGasLimit and transferGasAmounts ```js struct GasLimitOverride { uint256 receiverExecutionGasLimit; uint256[] tokenGasOverrides; } ``` - `tokenGasOverrides` is an array of GasLimits to be used during the `relaseOrMint` call for the specific tokenPool associated with token --------- Signed-off-by: 0xsuryansh Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> Co-authored-by: 0xsuryansh Co-authored-by: Rens Rooimans --- contracts/gas-snapshots/ccip.gas-snapshot | 186 ++++---- .../scripts/native_solc_compile_all_ccip | 2 +- .../src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol | 95 +++- .../src/v0.8/ccip/test/NonceManager.t.sol | 24 +- .../src/v0.8/ccip/test/e2e/End2End.t.sol | 2 +- .../test/helpers/EVM2EVMOffRampHelper.sol | 16 +- .../helpers/receivers/ReentrancyAbuser.sol | 26 +- .../ccip/test/offRamp/EVM2EVMOffRamp.t.sol | 367 ++++++++++---- .../test/offRamp/EVM2EVMOffRampSetup.t.sol | 23 +- .../evm_2_evm_offramp/evm_2_evm_offramp.go | 31 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- .../ccip/mocks/evm2_evm_off_ramp_interface.go | 47 +- .../helpers/contractmodels.go | 85 ++++ .../helpers/contractwrappers.go | 189 ++++++++ core/scripts/ccip/manual-execution/main.go | 447 ++++++++++++++++++ .../ccip/testhelpers/ccip_contracts.go | 51 +- 16 files changed, 1313 insertions(+), 280 deletions(-) create mode 100644 core/scripts/ccip/manual-execution/helpers/contractmodels.go create mode 100644 core/scripts/ccip/manual-execution/helpers/contractwrappers.go create mode 100644 core/scripts/ccip/manual-execution/main.go diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index f0239bb13b..c734ea9831 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -122,7 +122,7 @@ CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424253) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1102244) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1104493) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38423) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 106249) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 87420) @@ -297,89 +297,95 @@ EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 1 EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939) EVM2EVMMultiOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 51996) EVM2EVMMultiOnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97214) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37938) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103821) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85346) -EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 36874) -EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 94390) -EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 39856) -EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 86647) -EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 383754) -EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 141161) -EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 799482) -EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 178530) -EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 28497) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 65704) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 42547) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 210257) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 221523) -EVM2EVMOffRamp__report:test_Report_Success() (gas: 125920) -EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 236524) -EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 245118) -EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 325971) -EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 311010) -EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17009) -EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153371) -EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5425677) -EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 144105) -EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21323) -EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36411) -EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51577) -EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 472096) -EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 46299) -EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152329) -EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 102812) -EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 163277) -EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Success() (gas: 177533) -EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 41242) -EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 156287) -EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 171500) -EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 246452) -EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 113501) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 406819) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54072) -EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 130517) -EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52060) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 555692) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 494268) -EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35373) -EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 543379) -EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64253) -EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 121641) -EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 141851) -EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 426732) -EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 17855) -EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 277453) -EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 17998) -EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 220737) -EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47215) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 46683) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 313238) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 68652) -EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 228248) -EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 275250) -EVM2EVMOffRamp_execute_upgrade:test_V2OffRampNonceSkipsIfMsgInFlight_Success() (gas: 257907) -EVM2EVMOffRamp_execute_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 224780) -EVM2EVMOffRamp_execute_upgrade:test_V2_Success() (gas: 130143) -EVM2EVMOffRamp_getAllRateLimitTokens:test_GetAllRateLimitTokens_Success() (gas: 38408) -EVM2EVMOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3213556) -EVM2EVMOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 83091) -EVM2EVMOffRamp_manuallyExecute:test_LowGasLimitManualExec_Success() (gas: 480170) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 183057) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecForkedChain_Revert() (gas: 25819) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 43294) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 25922) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithGasOverride_Success() (gas: 185360) -EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 184807) -EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2024509) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 142162) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37804) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103754) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85279) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 36807) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 94323) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 39789) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 86580) +EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 385392) +EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 141923) +EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 803421) +EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 179314) +EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 29240) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 66465) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 43320) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 211066) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 222330) +EVM2EVMOffRamp__report:test_Report_Success() (gas: 126658) +EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 237861) +EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246461) +EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 329947) +EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 312384) +EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17030) +EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153718) +EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5665738) +EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 144451) +EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21318) +EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36432) +EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51598) +EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 473469) +EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 47668) +EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152359) +EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 102842) +EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 163825) +EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Success() (gas: 178226) +EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 42539) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 157389) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 172734) +EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 247076) +EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114174) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 407570) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54096) +EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 131068) +EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52090) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 563623) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 495746) +EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35383) +EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 544879) +EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64326) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 122343) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 142553) +EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 427358) +EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18502) +EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 278195) +EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 18659) +EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 221491) +EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47902) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 47373) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 314036) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 70029) +EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 229361) +EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 276853) +EVM2EVMOffRamp_execute_upgrade:test_V2OffRampNonceSkipsIfMsgInFlight_Success() (gas: 258738) +EVM2EVMOffRamp_execute_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 226316) +EVM2EVMOffRamp_execute_upgrade:test_V2_Success() (gas: 130766) +EVM2EVMOffRamp_getAllRateLimitTokens:test_GetAllRateLimitTokens_Success() (gas: 38446) +EVM2EVMOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3247348) +EVM2EVMOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 83333) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 185871) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecForkedChain_Revert() (gas: 27049) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 45155) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 27468) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithMultipleMessagesAndSourceTokens_Success() (gas: 530389) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithSourceTokens_Success() (gas: 345877) +EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187366) +EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2321976) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DestinationGasAmountCountMismatch_Revert() (gas: 363084) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143921) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_InvalidTokenGasOverride_Revert() (gas: 366223) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimitManualExec_Success() (gas: 482733) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 189769) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithInvalidReceiverExecutionGasOverride_Revert() (gas: 153662) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithInvalidSourceTokenDataCount_Revert() (gas: 59894) EVM2EVMOffRamp_metadataHash:test_MetadataHash_Success() (gas: 8838) -EVM2EVMOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 40131) -EVM2EVMOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 38214) -EVM2EVMOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 142006) -EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_AddsAndRemoves_Success() (gas: 162464) -EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_NonOwner_Revert() (gas: 16667) -EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_Success() (gas: 197660) +EVM2EVMOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 40153) +EVM2EVMOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 38236) +EVM2EVMOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 141962) +EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_AddsAndRemoves_Success() (gas: 162525) +EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_NonOwner_Revert() (gas: 16690) +EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_Success() (gas: 197721) EVM2EVMOnRamp_constructor:test_Constructor_Success() (gas: 5579769) EVM2EVMOnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 35778) EVM2EVMOnRamp_forwardFromRouter:test_EnforceOutOfOrder_Revert() (gas: 98428) @@ -611,13 +617,13 @@ NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71847) -NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 248887) -NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 251210) -NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 304066) -NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 287250) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 243351) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 231407) -NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 142634) +NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 249575) +NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 251766) +NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 304556) +NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 287608) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244887) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 233207) +NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 142568) NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 167625) NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 218724) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index fbc9fc6608..fd38ae3562 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -8,7 +8,7 @@ echo " └─────────────────────── SOLC_VERSION="0.8.24" OPTIMIZE_RUNS=26000 -OPTIMIZE_RUNS_OFFRAMP=22000 +OPTIMIZE_RUNS_OFFRAMP=18000 OPTIMIZE_RUNS_ONRAMP=4100 OPTIMIZE_RUNS_MULTI_OFFRAMP=2000 diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol index a7b559ef09..15b66ae107 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol @@ -45,7 +45,9 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio error UnsupportedNumberOfTokens(uint64 sequenceNumber); error ManualExecutionNotYetEnabled(); error ManualExecutionGasLimitMismatch(); - error InvalidManualExecutionGasLimit(uint256 index, uint256 newLimit); + error DestinationGasAmountCountMismatch(bytes32 messageId, uint64 sequenceNumber); + error InvalidManualExecutionGasLimit(bytes32 messageId, uint256 oldLimit, uint256 newLimit); + error InvalidTokenGasOverride(bytes32 messageId, uint256 tokenIndex, uint256 oldLimit, uint256 tokenGasOverride); error RootNotCommitted(); error CanOnlySelfCall(); error ReceiverError(bytes err); @@ -100,6 +102,15 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio address destToken; } + /// @notice Gas overrides for manual exec, the number of token overrides must match the number of tokens in the msg. + struct GasLimitOverride { + /// @notice Overrides EVM2EVMMessage.gasLimit. A value of zero indicates no override and is valid. + uint256 receiverExecutionGasLimit; + /// @notice Overrides EVM2EVMMessage.sourceTokenData.destGasAmount. Must be same length as tokenAmounts. A value + /// of zero indicates no override and is valid. + uint32[] tokenGasOverrides; + } + // STATIC CONFIG string public constant override typeAndVersion = "EVM2EVMOffRamp 1.5.0-dev"; @@ -218,18 +229,44 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio /// @param gasLimitOverrides New gasLimit for each message in the report. /// @dev We permit gas limit overrides so that users may manually execute messages which failed due to /// insufficient gas provided. - function manuallyExecute(Internal.ExecutionReport memory report, uint256[] memory gasLimitOverrides) external { + function manuallyExecute( + Internal.ExecutionReport memory report, + GasLimitOverride[] memory gasLimitOverrides + ) external { // We do this here because the other _execute path is already covered OCR2BaseXXX. _checkChainForked(); uint256 numMsgs = report.messages.length; if (numMsgs != gasLimitOverrides.length) revert ManualExecutionGasLimitMismatch(); for (uint256 i = 0; i < numMsgs; ++i) { - uint256 newLimit = gasLimitOverrides[i]; + Internal.EVM2EVMMessage memory message = report.messages[i]; + GasLimitOverride memory gasLimitOverride = gasLimitOverrides[i]; + + uint256 newLimit = gasLimitOverride.receiverExecutionGasLimit; // Checks to ensure message cannot be executed with less gas than specified. if (newLimit != 0) { - if (newLimit < report.messages[i].gasLimit) { - revert InvalidManualExecutionGasLimit(i, newLimit); + if (newLimit < message.gasLimit) { + revert InvalidManualExecutionGasLimit(message.messageId, message.gasLimit, newLimit); + } + } + + if (message.tokenAmounts.length != gasLimitOverride.tokenGasOverrides.length) { + revert DestinationGasAmountCountMismatch(message.messageId, message.sequenceNumber); + } + + bytes[] memory encodedSourceTokenData = message.sourceTokenData; + + for (uint256 j = 0; j < message.tokenAmounts.length; ++j) { + Internal.SourceTokenData memory sourceTokenData = + abi.decode(encodedSourceTokenData[i], (Internal.SourceTokenData)); + uint256 tokenGasOverride = gasLimitOverride.tokenGasOverrides[j]; + + // The gas limit can not be lowered as that could cause the message to fail. If manual execution is done + // from an UNTOUCHED state and we would allow lower gas limit, anyone could grief by executing the message with + // lower gas limit than the DON would have used. This results in the message being marked FAILURE and the DON + // would not attempt it with the correct gas limit. + if (tokenGasOverride != 0 && tokenGasOverride < sourceTokenData.destGasAmount) { + revert InvalidTokenGasOverride(message.messageId, j, sourceTokenData.destGasAmount, tokenGasOverride); } } } @@ -239,16 +276,17 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio /// @notice Entrypoint for execution, called by the OCR network /// @dev Expects an encoded ExecutionReport + /// @dev Supplies no GasLimitOverrides as the DON will only execute with the original gas limits. function _report(bytes calldata report) internal override { - _execute(abi.decode(report, (Internal.ExecutionReport)), new uint256[](0)); + _execute(abi.decode(report, (Internal.ExecutionReport)), new GasLimitOverride[](0)); } /// @notice Executes a report, executing each message in order. /// @param report The execution report containing the messages and proofs. - /// @param manualExecGasLimits An array of gas limits to use for manual execution. + /// @param manualExecGasOverrides An array of gas limits to use for manual execution. /// @dev If called from the DON, this array is always empty. /// @dev If called from manual execution, this array is always same length as messages. - function _execute(Internal.ExecutionReport memory report, uint256[] memory manualExecGasLimits) internal { + function _execute(Internal.ExecutionReport memory report, GasLimitOverride[] memory manualExecGasOverrides) internal { if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(i_sourceChainSelector)))) revert CursedByRMN(); uint256 numMsgs = report.messages.length; @@ -267,13 +305,13 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio // a message with an unexpected hash. if (hashedLeaves[i] != message.messageId) revert InvalidMessageId(); } + bool manualExecution = manualExecGasOverrides.length != 0; // SECURITY CRITICAL CHECK uint256 timestampCommitted = ICommitStore(i_commitStore).verify(hashedLeaves, report.proofs, report.proofFlagBits); if (timestampCommitted == 0) revert RootNotCommitted(); // Execute messages - bool manualExecution = manualExecGasLimits.length != 0; for (uint256 i = 0; i < numMsgs; ++i) { Internal.EVM2EVMMessage memory message = report.messages[i]; Internal.MessageExecutionState originalState = getExecutionState(message.sequenceNumber); @@ -292,8 +330,10 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio emit SkippedAlreadyExecutedMessage(message.sequenceNumber); continue; } + uint32[] memory tokenGasOverrides; if (manualExecution) { + tokenGasOverrides = manualExecGasOverrides[i].tokenGasOverrides; bool isOldCommitReport = (block.timestamp - timestampCommitted) > s_dynamicConfig.permissionLessExecutionThresholdSeconds; // Manually execution is fine if we previously failed or if the commit report is just too old @@ -303,8 +343,8 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio } // Manual execution gas limit can override gas limit specified in the message. Value of 0 indicates no override. - if (manualExecGasLimits[i] != 0) { - message.gasLimit = manualExecGasLimits[i]; + if (manualExecGasOverrides[i].receiverExecutionGasLimit != 0) { + message.gasLimit = manualExecGasOverrides[i].receiverExecutionGasLimit; } } else { // DON can only execute a message once @@ -361,7 +401,8 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio ); _setExecutionState(message.sequenceNumber, Internal.MessageExecutionState.IN_PROGRESS); - (Internal.MessageExecutionState newState, bytes memory returnData) = _trialExecute(message, offchainTokenData); + (Internal.MessageExecutionState newState, bytes memory returnData) = + _trialExecute(message, offchainTokenData, tokenGasOverrides); _setExecutionState(message.sequenceNumber, newState); // Since it's hard to estimate whether manual execution will succeed, we @@ -432,9 +473,10 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio /// @return revert data in bytes if CCIP receiver reverted during execution. function _trialExecute( Internal.EVM2EVMMessage memory message, - bytes[] memory offchainTokenData + bytes[] memory offchainTokenData, + uint32[] memory tokenGasOverrides ) internal returns (Internal.MessageExecutionState, bytes memory) { - try this.executeSingleMessage(message, offchainTokenData) {} + try this.executeSingleMessage(message, offchainTokenData, tokenGasOverrides) {} catch (bytes memory err) { if ( ReceiverError.selector == bytes4(err) || TokenHandlingError.selector == bytes4(err) @@ -460,12 +502,21 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio /// its execution and enforce atomicity among successful message processing and token transfer. /// @dev We use ERC-165 to check for the ccipReceive interface to permit sending tokens to contracts /// (for example smart contract wallets) without an associated message. - function executeSingleMessage(Internal.EVM2EVMMessage calldata message, bytes[] calldata offchainTokenData) external { + function executeSingleMessage( + Internal.EVM2EVMMessage calldata message, + bytes[] calldata offchainTokenData, + uint32[] memory tokenGasOverrides + ) external { if (msg.sender != address(this)) revert CanOnlySelfCall(); Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](0); if (message.tokenAmounts.length > 0) { destTokenAmounts = _releaseOrMintTokens( - message.tokenAmounts, abi.encode(message.sender), message.receiver, message.sourceTokenData, offchainTokenData + message.tokenAmounts, + abi.encode(message.sender), + message.receiver, + message.sourceTokenData, + offchainTokenData, + tokenGasOverrides ); } // There are three cases in which we skip calling the receiver: @@ -710,19 +761,27 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio bytes memory originalSender, address receiver, bytes[] calldata encodedSourceTokenData, - bytes[] calldata offchainTokenData + bytes[] calldata offchainTokenData, + uint32[] memory tokenGasOverrides ) internal returns (Client.EVMTokenAmount[] memory destTokenAmounts) { // Creating a copy is more gas efficient than initializing a new array. destTokenAmounts = sourceTokenAmounts; uint256 value = 0; for (uint256 i = 0; i < sourceTokenAmounts.length; ++i) { + Internal.SourceTokenData memory sourceTokenData = + abi.decode(encodedSourceTokenData[i], (Internal.SourceTokenData)); + if (tokenGasOverrides.length != 0) { + if (tokenGasOverrides[i] != 0) { + sourceTokenData.destGasAmount = tokenGasOverrides[i]; + } + } destTokenAmounts[i] = _releaseOrMintToken( sourceTokenAmounts[i].amount, originalSender, receiver, // This should never revert as the onRamp encodes the sourceTokenData struct. Only the inner components from // this struct come from untrusted sources. - abi.decode(encodedSourceTokenData[i], (Internal.SourceTokenData)), + sourceTokenData, offchainTokenData[i] ); diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol index 42285097e1..012a3168c2 100644 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -414,7 +414,9 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { _generateSingleLaneSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, SINGLE_LANE_ON_RAMP_ADDRESS_1); uint64 startNonceChain3 = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, abi.encode(messages[0].sender)); - s_prevOffRamp.execute(_generateSingleLaneRampReportFromMessages(messages), new uint256[](0)); + s_prevOffRamp.execute( + _generateSingleLaneRampReportFromMessages(messages), new EVM2EVMOffRampHelper.GasLimitOverride[](0) + ); // Nonce unchanged for chain 3 assertEq( @@ -446,7 +448,9 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(messages[0].sender)); for (uint64 i = 1; i < 4; ++i) { - s_prevOffRamp.execute(_generateSingleLaneRampReportFromMessages(messages), new uint256[](0)); + s_prevOffRamp.execute( + _generateSingleLaneRampReportFromMessages(messages), new EVM2EVMOffRampHelper.GasLimitOverride[](0) + ); // messages contains a single message - update for the next execution messages[0].nonce++; @@ -465,7 +469,9 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_2, abi.encode(messages[0].sender)); for (uint64 i = 1; i < 4; ++i) { - s_nestedPrevOffRamps[0].execute(_generateSingleLaneRampReportFromMessages(messages), new uint256[](0)); + s_nestedPrevOffRamps[0].execute( + _generateSingleLaneRampReportFromMessages(messages), new EVM2EVMOffRampHelper.GasLimitOverride[](0) + ); // messages contains a single message - update for the next execution messages[0].nonce++; @@ -484,7 +490,9 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { _generateSingleLaneSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, SINGLE_LANE_ON_RAMP_ADDRESS_1); uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(messages[0].sender)); - s_prevOffRamp.execute(_generateSingleLaneRampReportFromMessages(messages), new uint256[](0)); + s_prevOffRamp.execute( + _generateSingleLaneRampReportFromMessages(messages), new EVM2EVMOffRampHelper.GasLimitOverride[](0) + ); assertEq( startNonce + 1, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(messages[0].sender)) @@ -537,7 +545,9 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { Internal.EVM2EVMMessage[] memory messages = _generateSingleLaneSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, SINGLE_LANE_ON_RAMP_ADDRESS_1); - s_prevOffRamp.execute(_generateSingleLaneRampReportFromMessages(messages), new uint256[](0)); + s_prevOffRamp.execute( + _generateSingleLaneRampReportFromMessages(messages), new EVM2EVMOffRampHelper.GasLimitOverride[](0) + ); Internal.Any2EVMRampMessage[] memory messagesMultiRamp = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); @@ -589,7 +599,9 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { messagesSingleLane[0].messageId = Internal._hash(messagesSingleLane[0], s_prevOffRamp.metadataHash()); // previous offramp executes msg and increases nonce - s_prevOffRamp.execute(_generateSingleLaneRampReportFromMessages(messagesSingleLane), new uint256[](0)); + s_prevOffRamp.execute( + _generateSingleLaneRampReportFromMessages(messagesSingleLane), new EVM2EVMOffRampHelper.GasLimitOverride[](0) + ); assertEq( startNonce + 1, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(messagesSingleLane[0].sender)) diff --git a/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol b/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol index 816862cbdf..90df377313 100644 --- a/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol +++ b/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol @@ -90,7 +90,7 @@ contract E2E is EVM2EVMOnRampSetup, CommitStoreSetup, EVM2EVMOffRampSetup { Internal.ExecutionReport memory execReport = _generateReportFromMessages(messages); vm.resumeGasMetering(); - s_offRamp.execute(execReport, new uint256[](0)); + s_offRamp.execute(execReport, new EVM2EVMOffRamp.GasLimitOverride[](0)); } function sendRequest(uint64 expectedSeqNum) public returns (Internal.EVM2EVMMessage memory) { diff --git a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOffRampHelper.sol b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOffRampHelper.sol index f6131b64a5..1b537702be 100644 --- a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOffRampHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOffRampHelper.sol @@ -33,24 +33,28 @@ contract EVM2EVMOffRampHelper is EVM2EVMOffRamp, IgnoreContractSize { bytes calldata originalSender, address receiver, bytes[] calldata sourceTokenData, - bytes[] calldata offchainTokenData + bytes[] calldata offchainTokenData, + uint32[] memory tokenGasOverrides ) external returns (Client.EVMTokenAmount[] memory) { - return _releaseOrMintTokens(sourceTokenAmounts, originalSender, receiver, sourceTokenData, offchainTokenData); + return _releaseOrMintTokens( + sourceTokenAmounts, originalSender, receiver, sourceTokenData, offchainTokenData, tokenGasOverrides + ); } function trialExecute( Internal.EVM2EVMMessage memory message, - bytes[] memory offchainTokenData + bytes[] memory offchainTokenData, + uint32[] memory tokenGasOverrides ) external returns (Internal.MessageExecutionState, bytes memory) { - return _trialExecute(message, offchainTokenData); + return _trialExecute(message, offchainTokenData, tokenGasOverrides); } function report(bytes calldata executableMessages) external { _report(executableMessages); } - function execute(Internal.ExecutionReport memory rep, uint256[] memory manualExecGasLimits) external { - _execute(rep, manualExecGasLimits); + function execute(Internal.ExecutionReport memory rep, GasLimitOverride[] memory gasLimitOverrides) external { + _execute(rep, gasLimitOverrides); } function metadataHash() external view returns (bytes32) { diff --git a/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol b/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol index ae8759099c..68d5407c0f 100644 --- a/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol +++ b/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol @@ -9,6 +9,8 @@ import {EVM2EVMOffRamp} from "../../../offRamp/EVM2EVMOffRamp.sol"; contract ReentrancyAbuser is CCIPReceiver { event ReentrancySucceeded(); + uint32 internal constant DEFAULT_TOKEN_DEST_GAS_OVERHEAD = 144_000; + bool internal s_ReentrancyDone = false; Internal.ExecutionReport internal s_payload; EVM2EVMOffRamp internal s_offRamp; @@ -23,11 +25,7 @@ contract ReentrancyAbuser is CCIPReceiver { function _ccipReceive(Client.Any2EVMMessage memory) internal override { // Use original message gas limits in manual execution - uint256 numMsgs = s_payload.messages.length; - uint256[] memory gasOverrides = new uint256[](numMsgs); - for (uint256 i = 0; i < numMsgs; ++i) { - gasOverrides[i] = 0; - } + EVM2EVMOffRamp.GasLimitOverride[] memory gasOverrides = _getGasLimitsFromMessages(s_payload.messages); if (!s_ReentrancyDone) { // Could do more rounds but a PoC one is enough @@ -37,4 +35,22 @@ contract ReentrancyAbuser is CCIPReceiver { emit ReentrancySucceeded(); } } + + function _getGasLimitsFromMessages(Internal.EVM2EVMMessage[] memory messages) + internal + view + returns (EVM2EVMOffRamp.GasLimitOverride[] memory) + { + EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = new EVM2EVMOffRamp.GasLimitOverride[](messages.length); + for (uint256 i = 0; i < messages.length; ++i) { + gasLimitOverrides[i].receiverExecutionGasLimit = messages[i].gasLimit; + gasLimitOverrides[i].tokenGasOverrides = new uint32[](messages[i].tokenAmounts.length); + + for (uint256 j = 0; j < messages[i].tokenAmounts.length; ++j) { + gasLimitOverrides[i].tokenGasOverrides[j] = DEFAULT_TOKEN_DEST_GAS_OVERHEAD + 1; + } + } + + return gasLimitOverrides; + } } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol index b42782718b..70c7e38bfe 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol @@ -29,6 +29,7 @@ import {MockCommitStore} from "../mocks/MockCommitStore.sol"; import {OCR2Base} from "../ocr/OCR2Base.t.sol"; import {OCR2BaseNoChecks} from "../ocr/OCR2BaseNoChecks.t.sol"; import {EVM2EVMOffRampSetup} from "./EVM2EVMOffRampSetup.t.sol"; +import {stdError} from "forge-std/Test.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; @@ -222,7 +223,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { vm.expectCall(address(s_receiver), expectedCallData); (Internal.MessageExecutionState newState, bytes memory err) = - s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); assertEq("", err); } @@ -243,7 +244,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { vm.expectCall(address(dstToken0), abi.encodeWithSelector(IERC20.transfer.selector, address(s_receiver), amounts[0])); (Internal.MessageExecutionState newState, bytes memory err) = - s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); assertEq("", err); @@ -265,7 +266,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { // Fuzz the number of calls from the sender to ensure that getSenderNonce works for (uint256 i = 1; i < trialExecutions; ++i) { - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); messages[0].nonce++; messages[0].sequenceNumber++; @@ -275,10 +276,10 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { messages[0].nonce = 0; messages[0].sequenceNumber = 0; messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); uint64 nonceBefore = s_offRamp.getSenderNonce(messages[0].sender); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertEq(s_offRamp.getSenderNonce(messages[0].sender), nonceBefore, "sender nonce is not as expected"); } @@ -302,7 +303,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { assertEq(currentSenderNonce, trialExecutions - 1, "Sender Nonce does not match expected trial executions"); Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); currentSenderNonce = s_offRamp.getSenderNonce(OWNER); assertEq(currentSenderNonce, trialExecutions - 1, "Sender Nonce on new offramp does not match expected executions"); @@ -315,7 +316,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); messages[0].nonce++; messages[0].sequenceNumber++; @@ -327,7 +328,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { ); uint64 nonceBefore = s_offRamp.getSenderNonce(messages[0].sender); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertGt(s_offRamp.getSenderNonce(messages[0].sender), nonceBefore); } @@ -343,7 +344,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { // Nonce never increments on unordered messages. uint64 nonceBefore = s_offRamp.getSenderNonce(messages[0].sender); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertEq( s_offRamp.getSenderNonce(messages[0].sender), nonceBefore, "nonce must remain unchanged on unordered messages" ); @@ -358,7 +359,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { // Nonce never increments on unordered messages. nonceBefore = s_offRamp.getSenderNonce(messages[0].sender); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertEq( s_offRamp.getSenderNonce(messages[0].sender), nonceBefore, "nonce must remain unchanged on unordered messages" ); @@ -387,7 +388,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { ); // Nonce should increment on non-strict assertEq(uint64(0), s_offRamp.getSenderNonce(address(OWNER))); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertEq(uint64(1), s_offRamp.getSenderNonce(address(OWNER))); } @@ -404,7 +405,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { ); // Nonce should increment on a strict untouched -> success. assertEq(uint64(0), s_offRamp.getSenderNonce(address(OWNER))); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertEq(uint64(1), s_offRamp.getSenderNonce(address(OWNER))); } @@ -417,7 +418,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { vm.expectEmit(); emit EVM2EVMOffRamp.SkippedIncorrectNonce(messages[0].nonce, messages[0].sender); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test_SkippedIncorrectNonceStillExecutes_Success() public { @@ -434,7 +435,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { vm.expectEmit(); emit EVM2EVMOffRamp.SkippedIncorrectNonce(messages[1].nonce, messages[1].sender); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test__execute_SkippedAlreadyExecutedMessage_Success() public { @@ -445,12 +446,12 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); vm.expectEmit(); emit EVM2EVMOffRamp.SkippedAlreadyExecutedMessage(messages[0].sequenceNumber); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test__execute_SkippedAlreadyExecutedMessageUnordered_Success() public { @@ -463,12 +464,12 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); vm.expectEmit(); emit EVM2EVMOffRamp.SkippedAlreadyExecutedMessage(messages[0].sequenceNumber); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); } // Send a message to a contract that does not implement the CCIPReceiver interface @@ -484,7 +485,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test_SingleMessagesNoTokensSuccess_gas() public { @@ -499,7 +500,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { Internal.ExecutionReport memory report = _generateReportFromMessages(messages); vm.resumeGasMetering(); - s_offRamp.execute(report, new uint256[](0)); + s_offRamp.execute(report, new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test_TwoMessagesWithTokensSuccess_gas() public { @@ -522,7 +523,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { Internal.ExecutionReport memory report = _generateReportFromMessages(messages); vm.resumeGasMetering(); - s_offRamp.execute(report, new uint256[](0)); + s_offRamp.execute(report, new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test_TwoMessagesWithTokensAndGE_Success() public { @@ -608,7 +609,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { ) ); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test_execute_RouterYULCall_Success() public { @@ -629,7 +630,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { abi.encodeWithSelector(CallWithExactGas.NotEnoughGasForCall.selector) ); - s_offRamp.execute(executionReport, new uint256[](0)); + s_offRamp.execute(executionReport, new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test_RetryFailedMessageWithoutManualExecution_Success() public { @@ -653,13 +654,13 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, realError1) ) ); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); // The second time should skip the msg vm.expectEmit(); emit EVM2EVMOffRamp.AlreadyAttempted(messages[0].sequenceNumber); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); } // Reverts @@ -670,22 +671,28 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { // MessageID no longer matches hash. Internal.ExecutionReport memory executionReport = _generateReportFromMessages(messages); vm.expectRevert(EVM2EVMOffRamp.InvalidMessageId.selector); - s_offRamp.execute(executionReport, new uint256[](0)); + s_offRamp.execute(executionReport, new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test_Paused_Revert() public { s_mockCommitStore.pause(); vm.expectRevert(PausedError.selector); - s_offRamp.execute(_generateReportFromMessages(_generateMessagesWithTokens()), new uint256[](0)); + s_offRamp.execute( + _generateReportFromMessages(_generateMessagesWithTokens()), new EVM2EVMOffRamp.GasLimitOverride[](0) + ); } function test_Unhealthy_Revert() public { s_mockRMN.setGlobalCursed(true); vm.expectRevert(EVM2EVMOffRamp.CursedByRMN.selector); - s_offRamp.execute(_generateReportFromMessages(_generateMessagesWithTokens()), new uint256[](0)); + s_offRamp.execute( + _generateReportFromMessages(_generateMessagesWithTokens()), new EVM2EVMOffRamp.GasLimitOverride[](0) + ); // Uncurse should succeed s_mockRMN.setGlobalCursed(false); - s_offRamp.execute(_generateReportFromMessages(_generateMessagesWithTokens()), new uint256[](0)); + s_offRamp.execute( + _generateReportFromMessages(_generateMessagesWithTokens()), new EVM2EVMOffRamp.GasLimitOverride[](0) + ); } function test_UnexpectedTokenData_Revert() public { @@ -694,7 +701,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { vm.expectRevert(EVM2EVMOffRamp.UnexpectedTokenData.selector); - s_offRamp.execute(report, new uint256[](0)); + s_offRamp.execute(report, new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test_EmptyReport_Revert() public { @@ -706,7 +713,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { messages: new Internal.EVM2EVMMessage[](0), offchainTokenData: new bytes[][](0) }), - new uint256[](0) + new EVM2EVMOffRamp.GasLimitOverride[](0) ); } @@ -736,7 +743,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.InvalidSourceChain.selector, SOURCE_CHAIN_SELECTOR + 1)); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test_UnsupportedNumberOfTokens_Revert() public { @@ -749,7 +756,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { vm.expectRevert( abi.encodeWithSelector(EVM2EVMOffRamp.UnsupportedNumberOfTokens.selector, messages[0].sequenceNumber) ); - s_offRamp.execute(report, new uint256[](0)); + s_offRamp.execute(report, new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test_TokenDataMismatch_Revert() public { @@ -759,7 +766,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { report.offchainTokenData[0] = new bytes[](messages[0].tokenAmounts.length + 1); vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.TokenDataMismatch.selector, messages[0].sequenceNumber)); - s_offRamp.execute(report, new uint256[](0)); + s_offRamp.execute(report, new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test_MessageTooLarge_Revert() public { @@ -771,7 +778,7 @@ contract EVM2EVMOffRamp_execute is EVM2EVMOffRampSetup { vm.expectRevert( abi.encodeWithSelector(EVM2EVMOffRamp.MessageTooLarge.selector, MAX_DATA_SIZE, messages[0].data.length) ); - s_offRamp.execute(executionReport, new uint256[](0)); + s_offRamp.execute(executionReport, new EVM2EVMOffRamp.GasLimitOverride[](0)); } } @@ -793,7 +800,7 @@ contract EVM2EVMOffRamp_execute_upgrade is EVM2EVMOffRampSetup { messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); } function test_V2SenderNoncesReadsPreviousRamp_Success() public { @@ -801,7 +808,7 @@ contract EVM2EVMOffRamp_execute_upgrade is EVM2EVMOffRampSetup { uint64 startNonce = s_offRamp.getSenderNonce(messages[0].sender); for (uint64 i = 1; i < 4; ++i) { - s_prevOffRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_prevOffRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); messages[0].nonce++; messages[0].sequenceNumber++; @@ -820,7 +827,7 @@ contract EVM2EVMOffRamp_execute_upgrade is EVM2EVMOffRampSetup { uint64 startNonce = s_offRamp.getSenderNonce(messages[0].sender); - s_prevOffRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_prevOffRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertEq(startNonce + 1, s_offRamp.getSenderNonce(messages[0].sender)); @@ -832,7 +839,7 @@ contract EVM2EVMOffRamp_execute_upgrade is EVM2EVMOffRampSetup { messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertEq(startNonce + 2, s_offRamp.getSenderNonce(messages[0].sender)); messages[0].nonce++; @@ -844,7 +851,7 @@ contract EVM2EVMOffRamp_execute_upgrade is EVM2EVMOffRampSetup { messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertEq(startNonce + 3, s_offRamp.getSenderNonce(messages[0].sender)); } @@ -855,7 +862,7 @@ contract EVM2EVMOffRamp_execute_upgrade is EVM2EVMOffRampSetup { messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_prevOffRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_prevOffRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); address newSender = address(1234567); messages[0].sender = newSender; @@ -868,7 +875,7 @@ contract EVM2EVMOffRamp_execute_upgrade is EVM2EVMOffRampSetup { // new sender nonce in new offramp should go from 0 -> 1 assertEq(s_offRamp.getSenderNonce(newSender), 0); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertEq(s_offRamp.getSenderNonce(newSender), 1); } @@ -886,7 +893,7 @@ contract EVM2EVMOffRamp_execute_upgrade is EVM2EVMOffRampSetup { // it waits for previous offramp to execute vm.expectEmit(); emit EVM2EVMOffRamp.SkippedSenderWithPreviousRampMessageInflight(messages[0].nonce, newSender); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertEq(startNonce, s_offRamp.getSenderNonce(messages[0].sender)); messages[0].nonce = 1; @@ -897,7 +904,7 @@ contract EVM2EVMOffRamp_execute_upgrade is EVM2EVMOffRampSetup { emit EVM2EVMOffRamp.ExecutionStateChanged( messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_prevOffRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_prevOffRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertEq(startNonce + 1, s_offRamp.getSenderNonce(messages[0].sender)); messages[0].nonce = 2; @@ -909,7 +916,7 @@ contract EVM2EVMOffRamp_execute_upgrade is EVM2EVMOffRampSetup { messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); assertEq(startNonce + 2, s_offRamp.getSenderNonce(messages[0].sender)); } } @@ -922,7 +929,7 @@ contract EVM2EVMOffRamp_executeSingleMessage is EVM2EVMOffRampSetup { function test_executeSingleMessage_NoTokens_Success() public { Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageNoTokens(1); - s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); } function test_executeSingleMessage_WithTokens_Success() public { @@ -947,7 +954,7 @@ contract EVM2EVMOffRamp_executeSingleMessage is EVM2EVMOffRampSetup { ) ); - s_offRamp.executeSingleMessage(message, offchainTokenData); + s_offRamp.executeSingleMessage(message, offchainTokenData, new uint32[](0)); } function test_executeSingleMessage_ZeroGasZeroData_Success() public { @@ -962,7 +969,7 @@ contract EVM2EVMOffRamp_executeSingleMessage is EVM2EVMOffRampSetup { 0 ); - s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); // Ensure we encoded it properly, and didn't simply expect the wrong call gasLimit = 200_000; @@ -975,7 +982,7 @@ contract EVM2EVMOffRamp_executeSingleMessage is EVM2EVMOffRampSetup { 1 ); - s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); } function _generateMsgWithoutTokens(uint256 gasLimit) internal view returns (Internal.EVM2EVMMessage memory) { @@ -994,7 +1001,7 @@ contract EVM2EVMOffRamp_executeSingleMessage is EVM2EVMOffRampSetup { function test_NonContract_Success() public { Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageNoTokens(1); message.receiver = STRANGER; - s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); } function test_NonContractWithTokens_Success() public { @@ -1007,7 +1014,7 @@ contract EVM2EVMOffRamp_executeSingleMessage is EVM2EVMOffRampSetup { emit TokenPool.Minted(address(s_offRamp), STRANGER, amounts[1]); Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageWithTokens(1, amounts); message.receiver = STRANGER; - s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); } // Reverts @@ -1024,7 +1031,7 @@ contract EVM2EVMOffRamp_executeSingleMessage is EVM2EVMOffRampSetup { vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, errorMessage)); - s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); } function test_ZeroGasDONExecution_Revert() public { @@ -1033,14 +1040,14 @@ contract EVM2EVMOffRamp_executeSingleMessage is EVM2EVMOffRampSetup { vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.ReceiverError.selector, "")); - s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); } function test_MessageSender_Revert() public { vm.stopPrank(); Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageNoTokens(1); vm.expectRevert(EVM2EVMOffRamp.CanOnlySelfCall.selector); - s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); } } @@ -1063,7 +1070,23 @@ contract EVM2EVMOffRamp_manuallyExecute is EVM2EVMOffRampSetup { Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); messages[0].receiver = address(s_reverting_receiver); messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); + + s_reverting_receiver.setRevert(false); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + s_offRamp.manuallyExecute( + _generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](messages.length) + ); + } + + function test_ManualExecWithSourceTokens_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessageWithTokens(); + messages[0].receiver = address(s_reverting_receiver); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); s_reverting_receiver.setRevert(false); @@ -1071,7 +1094,28 @@ contract EVM2EVMOffRamp_manuallyExecute is EVM2EVMOffRampSetup { emit EVM2EVMOffRamp.ExecutionStateChanged( messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.manuallyExecute(_generateReportFromMessages(messages), new uint256[](messages.length)); + EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = _getGasLimitsFromMessages(messages); + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimitOverrides); + } + + function test_ManualExecWithMultipleMessagesAndSourceTokens_Success() public { + Internal.EVM2EVMMessage[] memory messages = _generateMessagesWithTokens(); + messages[0].receiver = address(s_reverting_receiver); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + messages[1].receiver = address(s_reverting_receiver); + messages[1].messageId = Internal._hash(messages[1], s_offRamp.metadataHash()); + + s_reverting_receiver.setRevert(false); + + vm.expectEmit(); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + emit EVM2EVMOffRamp.ExecutionStateChanged( + messages[1].sequenceNumber, messages[1].messageId, Internal.MessageExecutionState.SUCCESS, "" + ); + EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = _getGasLimitsFromMessages(messages); + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimitOverrides); } function test_manuallyExecute_DoesNotRevertIfUntouched_Success() public { @@ -1094,16 +1138,18 @@ contract EVM2EVMOffRamp_manuallyExecute is EVM2EVMOffRampSetup { ) ); - s_offRamp.manuallyExecute(_generateReportFromMessages(messages), new uint256[](1)); + s_offRamp.manuallyExecute( + _generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](messages.length) + ); assertEq(messages[0].nonce, s_offRamp.getSenderNonce(messages[0].sender)); } - function test_ManualExecWithGasOverride_Success() public { + function test_manuallyExecute_WithGasOverride_Success() public { Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); messages[0].receiver = address(s_reverting_receiver); messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](messages.length)); s_reverting_receiver.setRevert(false); @@ -1112,36 +1158,80 @@ contract EVM2EVMOffRamp_manuallyExecute is EVM2EVMOffRampSetup { messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - uint256[] memory gasLimitOverrides = _getGasLimitsFromMessages(messages); - gasLimitOverrides[0] += 1; + EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = _getGasLimitsFromMessages(messages); + gasLimitOverrides[0].receiverExecutionGasLimit += 1; s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimitOverrides); } - function test_LowGasLimitManualExec_Success() public { + function test_manuallyExecute_WithInvalidSourceTokenDataCount_Revert() public { + uint256 messageIndex = 0; + + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessageWithTokens(); + messages[messageIndex].receiver = address(s_reverting_receiver); + messages[messageIndex].messageId = Internal._hash(messages[messageIndex], s_offRamp.metadataHash()); + + EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = _getGasLimitsFromMessages(messages); + + messages[messageIndex].sourceTokenData = new bytes[](0); + + vm.expectRevert(stdError.indexOOBError); + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimitOverrides); + } + + function test_manuallyExecute_WithInvalidReceiverExecutionGasOverride_Revert() public { + uint256 messageIndex = 0; + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); - messages[0].gasLimit = 1; - messages[0].receiver = address(new ConformingReceiver(address(s_destRouter), s_destFeeToken)); - messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + messages[messageIndex].receiver = address(s_reverting_receiver); + messages[messageIndex].messageId = Internal._hash(messages[messageIndex], s_offRamp.metadataHash()); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](messages.length)); + + s_reverting_receiver.setRevert(false); + EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = _getGasLimitsFromMessages(messages); + gasLimitOverrides[messageIndex].receiverExecutionGasLimit -= 1; + + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMOffRamp.InvalidManualExecutionGasLimit.selector, + messages[messageIndex].messageId, + messages[messageIndex].gasLimit, + gasLimitOverrides[messageIndex].receiverExecutionGasLimit + ) + ); + + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimitOverrides); + } + + function test_manuallyExecute_LowGasLimitManualExec_Success() public { + uint256 messageIndex = 0; + + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + messages[messageIndex].gasLimit = 1; + messages[messageIndex].receiver = address(new ConformingReceiver(address(s_destRouter), s_destFeeToken)); + messages[messageIndex].messageId = Internal._hash(messages[messageIndex], s_offRamp.metadataHash()); vm.expectEmit(); emit EVM2EVMOffRamp.ExecutionStateChanged( - messages[0].sequenceNumber, - messages[0].messageId, + messages[messageIndex].sequenceNumber, + messages[messageIndex].messageId, Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector(EVM2EVMOffRamp.ReceiverError.selector, "") ); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); - uint256[] memory gasLimitOverrides = new uint256[](1); - gasLimitOverrides[0] = 100_000; + EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = new EVM2EVMOffRamp.GasLimitOverride[](1); + gasLimitOverrides[messageIndex].receiverExecutionGasLimit = 100_000; vm.expectEmit(); emit MaybeRevertMessageReceiver.MessageReceived(); vm.expectEmit(); emit EVM2EVMOffRamp.ExecutionStateChanged( - messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" + messages[messageIndex].sequenceNumber, + messages[messageIndex].messageId, + Internal.MessageExecutionState.SUCCESS, + "" ); s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimitOverrides); } @@ -1189,12 +1279,56 @@ contract EVM2EVMOffRamp_manuallyExecute is EVM2EVMOffRampSetup { messages[0].sequenceNumber, messages[0].messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.manuallyExecute(report, _getGasLimitsFromMessages(messages)); + EVM2EVMOffRamp.GasLimitOverride[] memory gasLimits = _getGasLimitsFromMessages(messages); + s_offRamp.manuallyExecute(report, gasLimits); // Assert that they only got the tokens once, not twice assertEq(tokenToAbuse.balanceOf(address(receiver)), balancePre + tokenAmount); } + function test_manuallyExecute_InvalidTokenGasOverride_Revert() public { + uint256 failingMessageIndex = 0; + uint256 failingTokenIndex = 0; + + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessageWithTokens(); + messages[failingMessageIndex].receiver = address(s_reverting_receiver); + messages[failingMessageIndex].messageId = Internal._hash(messages[failingMessageIndex], s_offRamp.metadataHash()); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](messages.length)); + + s_reverting_receiver.setRevert(false); + EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = _getGasLimitsFromMessages(messages); + gasLimitOverrides[failingMessageIndex].tokenGasOverrides[failingTokenIndex] -= 2; + + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMOffRamp.InvalidTokenGasOverride.selector, + messages[failingMessageIndex].messageId, + failingTokenIndex, + DEFAULT_TOKEN_DEST_GAS_OVERHEAD, + gasLimitOverrides[failingMessageIndex].tokenGasOverrides[failingTokenIndex] + ) + ); + + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimitOverrides); + } + + function test_manuallyExecute_DestinationGasAmountCountMismatch_Revert() public { + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessageWithTokens(); + messages[0].receiver = address(s_reverting_receiver); + messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](messages.length)); + + s_reverting_receiver.setRevert(false); + EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = _getGasLimitsFromMessages(messages); + gasLimitOverrides[0].tokenGasOverrides = new uint32[](0); + + vm.expectRevert( + abi.encodeWithSelector(EVM2EVMOffRamp.DestinationGasAmountCountMismatch.selector, messages[0].messageId, 1) + ); + + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimitOverrides); + } + function test_ManualExecForkedChain_Revert() public { Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); @@ -1211,22 +1345,34 @@ contract EVM2EVMOffRamp_manuallyExecute is EVM2EVMOffRampSetup { Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); vm.expectRevert(EVM2EVMOffRamp.ManualExecutionGasLimitMismatch.selector); - s_offRamp.manuallyExecute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.manuallyExecute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); vm.expectRevert(EVM2EVMOffRamp.ManualExecutionGasLimitMismatch.selector); - s_offRamp.manuallyExecute(_generateReportFromMessages(messages), new uint256[](messages.length - 1)); + s_offRamp.manuallyExecute( + _generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](messages.length - 1) + ); vm.expectRevert(EVM2EVMOffRamp.ManualExecutionGasLimitMismatch.selector); - s_offRamp.manuallyExecute(_generateReportFromMessages(messages), new uint256[](messages.length + 1)); + s_offRamp.manuallyExecute( + _generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](messages.length + 1) + ); } function test_ManualExecInvalidGasLimit_Revert() public { - Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + uint256 messageIndex = 0; - uint256[] memory gasLimits = _getGasLimitsFromMessages(messages); - gasLimits[0]--; + Internal.EVM2EVMMessage[] memory messages = _generateSingleBasicMessage(); + EVM2EVMOffRamp.GasLimitOverride[] memory gasLimits = _getGasLimitsFromMessages(messages); + gasLimits[messageIndex].receiverExecutionGasLimit -= 1; - vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.InvalidManualExecutionGasLimit.selector, 0, gasLimits[0])); + vm.expectRevert( + abi.encodeWithSelector( + EVM2EVMOffRamp.InvalidManualExecutionGasLimit.selector, + messages[messageIndex].messageId, + messages[messageIndex].gasLimit, + gasLimits[messageIndex].receiverExecutionGasLimit + ) + ); s_offRamp.manuallyExecute(_generateReportFromMessages(messages), gasLimits); } @@ -1236,7 +1382,7 @@ contract EVM2EVMOffRamp_manuallyExecute is EVM2EVMOffRampSetup { messages[0].receiver = address(s_reverting_receiver); messages[0].messageId = Internal._hash(messages[0], s_offRamp.metadataHash()); - s_offRamp.execute(_generateReportFromMessages(messages), new uint256[](0)); + s_offRamp.execute(_generateReportFromMessages(messages), new EVM2EVMOffRamp.GasLimitOverride[](0)); s_reverting_receiver.setRevert(true); @@ -1342,7 +1488,7 @@ contract EVM2EVMOffRamp__trialExecute is EVM2EVMOffRampSetup { uint256 startingBalance = dstToken0.balanceOf(message.receiver); (Internal.MessageExecutionState newState, bytes memory err) = - s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); assertEq("", err); @@ -1364,8 +1510,8 @@ contract EVM2EVMOffRamp__trialExecute is EVM2EVMOffRampSetup { s_maybeRevertingPool.setShouldRevert(errorMessage); (Internal.MessageExecutionState newState, bytes memory err) = - s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); - assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint32(newState)); assertEq(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, errorMessage), err); // Expect the balance to remain the same @@ -1383,7 +1529,7 @@ contract EVM2EVMOffRamp__trialExecute is EVM2EVMOffRampSetup { s_maybeRevertingPool.setShouldRevert(errorMessage); (Internal.MessageExecutionState newState, bytes memory err) = - s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); assertEq(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, errorMessage), err); } @@ -1395,7 +1541,7 @@ contract EVM2EVMOffRamp__trialExecute is EVM2EVMOffRampSetup { // Happy path, pool is correct (Internal.MessageExecutionState newState, bytes memory err) = - s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); assertEq("", err); @@ -1419,7 +1565,7 @@ contract EVM2EVMOffRamp__trialExecute is EVM2EVMOffRampSetup { ); // Unhappy path, no revert but marked as failed. - (newState, err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + (newState, err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); assertEq(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, abi.encode(address(0))), err); @@ -1442,7 +1588,7 @@ contract EVM2EVMOffRamp__trialExecute is EVM2EVMOffRampSetup { ) ); - (newState, err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + (newState, err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length), new uint32[](0)); assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); assertEq(abi.encodeWithSelector(EVM2EVMOffRamp.NotACompatiblePool.selector, address(0)), err); @@ -1681,7 +1827,9 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { ) ); - s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, encodedSourceTokenData, offchainTokenData); + s_offRamp.releaseOrMintTokens( + srcTokenAmounts, originalSender, OWNER, encodedSourceTokenData, offchainTokenData, new uint32[](0) + ); assertEq(startingBalance + amount1, dstToken1.balanceOf(OWNER)); } @@ -1700,8 +1848,9 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { MaybeRevertingBurnMintTokenPool(pool).setReleaseOrMintMultiplier(destinationDenominationMultiplier); - Client.EVMTokenAmount[] memory destTokenAmounts = - s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, encodedSourceTokenData, offchainTokenData); + Client.EVMTokenAmount[] memory destTokenAmounts = s_offRamp.releaseOrMintTokens( + srcTokenAmounts, originalSender, OWNER, encodedSourceTokenData, offchainTokenData, new uint32[](0) + ); assertEq(destTokenAmounts[1].amount, amount * destinationDenominationMultiplier); assertEq(destTokenAmounts[1].token, destToken); @@ -1733,7 +1882,9 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { ); // // Expect to fail from ARL - s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, sourceTokenData, offchainTokenData); + s_offRamp.releaseOrMintTokens( + srcTokenAmounts, originalSender, OWNER, sourceTokenData, offchainTokenData, new uint32[](0) + ); // Configure ARL off for token EVM2EVMOffRamp.RateLimitToken[] memory removes = new EVM2EVMOffRamp.RateLimitToken[](1); @@ -1741,7 +1892,9 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { s_offRamp.updateRateLimitTokens(removes, new EVM2EVMOffRamp.RateLimitToken[](0)); // Expect the call now succeeds - s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, sourceTokenData, offchainTokenData); + s_offRamp.releaseOrMintTokens( + srcTokenAmounts, originalSender, OWNER, sourceTokenData, offchainTokenData, new uint32[](0) + ); } // Revert @@ -1759,7 +1912,8 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { abi.encode(OWNER), OWNER, _getDefaultSourceTokenData(srcTokenAmounts), - new bytes[](srcTokenAmounts.length) + new bytes[](srcTokenAmounts.length), + new uint32[](0) ); } @@ -1796,7 +1950,9 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { abi.encodeWithSelector(EVM2EVMOffRamp.InvalidDataLength.selector, Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, 64) ); - s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, encodedSourceTokenData, offchainTokenData); + s_offRamp.releaseOrMintTokens( + srcTokenAmounts, originalSender, OWNER, encodedSourceTokenData, offchainTokenData, new uint32[](0) + ); } function test_releaseOrMintTokens_InvalidEVMAddress_Revert() public { @@ -1818,7 +1974,9 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, wrongAddress)); - s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, sourceTokenData, offchainTokenData); + s_offRamp.releaseOrMintTokens( + srcTokenAmounts, originalSender, OWNER, sourceTokenData, offchainTokenData, new uint32[](0) + ); } function test_RateLimitErrors_Reverts() public { @@ -1846,7 +2004,8 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { abi.encode(OWNER), OWNER, _getDefaultSourceTokenData(srcTokenAmounts), - new bytes[](srcTokenAmounts.length) + new bytes[](srcTokenAmounts.length), + new uint32[](0) ); } } @@ -1866,7 +2025,12 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.NotACompatiblePool.selector, address(0))); s_offRamp.releaseOrMintTokens( - new Client.EVMTokenAmount[](1), abi.encode(makeAddr("original_sender")), OWNER, sourceTokenData, new bytes[](1) + new Client.EVMTokenAmount[](1), + abi.encode(makeAddr("original_sender")), + OWNER, + sourceTokenData, + new bytes[](1), + new uint32[](0) ); } @@ -1887,7 +2051,9 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { vm.expectRevert(abi.encodeWithSelector(AggregateRateLimiter.PriceNotFoundForToken.selector, s_destFeeToken)); - s_offRamp.releaseOrMintTokens(srcTokenAmounts, originalSender, OWNER, sourceTokenData, offchainTokenData); + s_offRamp.releaseOrMintTokens( + srcTokenAmounts, originalSender, OWNER, sourceTokenData, offchainTokenData, new uint32[](0) + ); } /// forge-config: default.fuzz.runs = 32 @@ -1908,8 +2074,9 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { }) ); - try s_offRamp.releaseOrMintTokens(new Client.EVMTokenAmount[](1), unusedVar, OWNER, sourceTokenData, new bytes[](1)) - {} catch (bytes memory reason) { + try s_offRamp.releaseOrMintTokens( + new Client.EVMTokenAmount[](1), unusedVar, OWNER, sourceTokenData, new bytes[](1), new uint32[](0) + ) {} catch (bytes memory reason) { // Any revert should be a TokenHandlingError, InvalidEVMAddress, InvalidDataLength or NoContract as those are caught by the offramp assertTrue( bytes4(reason) == EVM2EVMOffRamp.TokenHandlingError.selector diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol index b67adbf37e..ad714791cf 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol @@ -190,6 +190,14 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { return messages; } + function _generateSingleBasicMessageWithTokens() internal view returns (Internal.EVM2EVMMessage[] memory) { + Internal.EVM2EVMMessage[] memory messages = new Internal.EVM2EVMMessage[](1); + Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + tokenAmounts[0].amount = 1e18; + messages[0] = _generateAny2EVMMessage(1, tokenAmounts, false); + return messages; + } + function _generateMessagesWithTokens() internal view returns (Internal.EVM2EVMMessage[] memory) { Internal.EVM2EVMMessage[] memory messages = new Internal.EVM2EVMMessage[](2); Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); @@ -222,15 +230,20 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { function _getGasLimitsFromMessages(Internal.EVM2EVMMessage[] memory messages) internal - pure - returns (uint256[] memory) + view + returns (EVM2EVMOffRamp.GasLimitOverride[] memory) { - uint256[] memory gasLimits = new uint256[](messages.length); + EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = new EVM2EVMOffRamp.GasLimitOverride[](messages.length); for (uint256 i = 0; i < messages.length; ++i) { - gasLimits[i] = messages[i].gasLimit; + gasLimitOverrides[i].receiverExecutionGasLimit = messages[i].gasLimit; + gasLimitOverrides[i].tokenGasOverrides = new uint32[](messages[i].tokenAmounts.length); + + for (uint256 j = 0; j < messages[i].tokenAmounts.length; ++j) { + gasLimitOverrides[i].tokenGasOverrides[j] = DEFAULT_TOKEN_DEST_GAS_OVERHEAD + 1; + } } - return gasLimits; + return gasLimitOverrides; } function _assertSameConfig(EVM2EVMOffRamp.DynamicConfig memory a, EVM2EVMOffRamp.DynamicConfig memory b) public pure { diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go index 313714e306..a906177b7d 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go @@ -51,6 +51,11 @@ type EVM2EVMOffRampDynamicConfig struct { PriceRegistry common.Address } +type EVM2EVMOffRampGasLimitOverride struct { + ReceiverExecutionGasLimit *big.Int + TokenGasOverrides []uint32 +} + type EVM2EVMOffRampRateLimitToken struct { SourceToken common.Address DestToken common.Address @@ -104,8 +109,8 @@ type RateLimiterTokenBucket struct { } var EVM2EVMOffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101a06040523480156200001257600080fd5b506040516200663d3803806200663d8339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f74620006c96000396000818161032001528181611cdd01526134570152600081816102e401528181611cb50152611f670152600081816102a801528181610f830152818161100201528181611c8b015281816124df01526125630152600061211301526000818161026c0152611c6101526000818161020c0152611c0501526000818161023c01528181611c3901528181611f240152818161309801526135ab0152600081816101d001528181611be00152612200015260008181611e7e0152611eca0152615f746000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806381ff7048116100d8578063afcb95d71161008c578063f077b59211610066578063f077b59214610668578063f2fde38b1461067e578063f52121a51461069157600080fd5b8063afcb95d714610622578063b1dc65a414610642578063c92b28321461065557600080fd5b8063856c8247116100bd578063856c8247146105c5578063873504d7146105f15780638da5cb5b1461060457600080fd5b806381ff70481461058757806385572ffb146105b757600080fd5b8063599f64311161013a578063740f415011610114578063740f4150146104bc5780637437ff9f146104cf57806379ba50971461057f57600080fd5b8063599f643114610455578063666cab8d14610494578063704b6c02146104a957600080fd5b8063181f5a771161016b578063181f5a77146103935780631ef38174146103dc578063546719cd146103f157600080fd5b806306285c6914610187578063142a98fc14610373575b600080fd5b61035d6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161036a919061448b565b60405180910390f35b61038661038136600461452e565b6106a4565b60405161036a919061458e565b6103cf6040518060400160405280601881526020017f45564d3245564d4f666652616d7020312e352e302d646576000000000000000081525081565b60405161036a91906145ec565b6103ef6103ea366004614822565b61071f565b005b6103f9610b47565b60405161036a919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161036a565b61049c610bfc565b60405161036a9190614941565b6103ef6104b7366004614954565b610c6b565b6103ef6104ca366004614dbe565b610d5b565b6105726040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a010000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff9081166060830152600b5416608082015290565b60405161036a9190614e79565b6103ef610e4d565b6007546005546040805163ffffffff8085168252640100000000909404909316602084015282015260600161036a565b6103ef610182366004614edc565b6105d86105d3366004614954565b610f4a565b60405167ffffffffffffffff909116815260200161036a565b6103ef6105ff366004614fa8565b611074565b60005473ffffffffffffffffffffffffffffffffffffffff1661046f565b60408051600181526000602082018190529181019190915260600161036a565b6103ef610650366004615051565b61125c565b6103ef610663366004615156565b611474565b6106706114f9565b60405161036a9291906151c4565b6103ef61068c366004614954565b611646565b6103ef61069f3660046151e9565b611657565b60006106b26001600461528a565b60026106bf6080856152cc565b67ffffffffffffffff166106d391906152f3565b601060006106e260808761530a565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156107195761071961454b565b92915050565b84518460ff16601f82111561076c5760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016107639190615331565b60405180910390fd5b806000036107a95760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016107639190615331565b6107b16119d5565b6107ba85611a58565b60095460005b8181101561083e5760086000600983815481106107df576107df61534b565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556001016107c0565b5050865160005b81811015610a085760008982815181106108615761086161534b565b602002602001015190506000600281111561087e5761087e61454b565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260086020526040902054610100900460ff1660028111156108bd576108bd61454b565b146108f75760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016107639190615331565b73ffffffffffffffffffffffffffffffffffffffff8116610944576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156109f4576109f461454b565b021790555090505050806001019050610845565b508751610a1c9060099060208b01906143ec565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a161717905560078054610aa2914691309190600090610a749063ffffffff1661537a565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611d3c565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610b339487949293918316921691909117908f908f908f908f908f908f9061539d565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610bf790611dc9565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610c6157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610c36575b5050505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610cab575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610ce2576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b610d63611e7b565b81515181518114610da0576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610e3d576000838281518110610dbf57610dbf61534b565b6020026020010151905080600014610e34578451805183908110610de557610de561534b565b602002602001015160800151811015610e34576040517f085e39cf0000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610763565b50600101610da3565b50610e488383611efc565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610763565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600f602052604081205467ffffffffffffffff16808203610719577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615610719576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190615433565b9392505050565b61107c6119d5565b60005b825181101561115c576110b983828151811061109d5761109d61534b565b602002602001015160200151600c61299d90919063ffffffff16565b15611154577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d587828382815181106110f1576110f161534b565b60200260200101516000015184838151811061110f5761110f61534b565b60200260200101516020015160405161114b92919073ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b60405180910390a15b60010161107f565b5060005b8151811015610e48576111b982828151811061117e5761117e61534b565b60200260200101516020015183838151811061119c5761119c61534b565b602002602001015160000151600c6129bf9092919063ffffffff16565b15611254577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a8282815181106111f1576111f161534b565b60200260200101516000015183838151811061120f5761120f61534b565b60200260200101516020015160405161124b92919073ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b60405180910390a15b600101611160565b61126687876129ea565b6005548835908082146112af576040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610763565b6112b7611e7b565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561133f5761133f61454b565b60028111156113505761135061454b565b905250905060028160200151600281111561136d5761136d61454b565b1480156113b457506009816000015160ff168154811061138f5761138f61534b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6113ea576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006113f88560206152f3565b6114038860206152f3565b61140f8b610144615450565b6114199190615450565b6114239190615450565b9050368114611467576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610763565b5050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906114b4575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156114eb576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114f6600382612a11565b50565b6060806000611508600c612bf6565b90508067ffffffffffffffff811115611523576115236145ff565b60405190808252806020026020018201604052801561154c578160200160208202803683370190505b5092508067ffffffffffffffff811115611568576115686145ff565b604051908082528060200260200182016040528015611591578160200160208202803683370190505b50915060005b81811015611640576000806115ad600c84612c01565b91509150808684815181106115c4576115c461534b565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050818584815181106116115761161161534b565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101525050600101611597565b50509091565b61164e6119d5565b6114f681612c1f565b333014611690576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600080825260208201909252816116cd565b60408051808201909152600080825260208201528152602001906001900390816116a65790505b50905060006116e0610140860186615463565b90501115611763576117606116f9610140860186615463565b6117096040880160208901614954565b6040805173ffffffffffffffffffffffffffffffffffffffff90921660208301520160408051601f1981840301815291815261174b9060608a01908a01614954565b6117596101608a018a6154cb565b8989612d14565b90505b611771610120850185615533565b159050801561178257506080840135155b806117b157506117986060850160408601614954565b73ffffffffffffffffffffffffffffffffffffffff163b155b8061180957506118077f85572ffb000000000000000000000000000000000000000000000000000000006117eb6060870160408801614954565b73ffffffffffffffffffffffffffffffffffffffff1690612eea565b155b156118145750505050565b600a546040805160a08101909152610180860135815260009182916a010000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff1690633cf979839060208082019061186d908b018b61452e565b67ffffffffffffffff16815260200189602001602081019061188f9190614954565b6040805173ffffffffffffffffffffffffffffffffffffffff90921660208301520160408051601f1981840301815291905281526020016118d46101208b018b615533565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200186905261138860808a013561192960608c0160408d01614954565b6040518563ffffffff1660e01b815260040161194894939291906155ea565b6000604051808303816000875af1158015611967573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261198f91908101906156bc565b5091509150816119cd57806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161076391906145ec565b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610763565b565b600081806020019051810190611a6e9190615764565b606081015190915073ffffffffffffffffffffffffffffffffffffffff16611ac2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a010000000000000000000073ffffffffffffffffffffffffffffffffffffffff9485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611d30918490615803565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611d60999897969594939291906158df565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611e5782606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611e3b919061528a565b85608001516fffffffffffffffffffffffffffffffff16612f06565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b467f000000000000000000000000000000000000000000000000000000000000000014611a56576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610763565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe79190615974565b1561201e576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815151600081900361205b576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114612099576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156120b4576120b46145ff565b6040519080825280602002602001820160405280156120dd578160200160208202803683370190505b50905060005b828110156121b5576000856000015182815181106121035761210361534b565b60200260200101519050612137817f0000000000000000000000000000000000000000000000000000000000000000612f2e565b8383815181106121495761214961534b565b60200260200101818152505080610180015183838151811061216d5761216d61534b565b6020026020010151146121ac576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001016120e3565b50604080850151606086015191517f3204887500000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001692633204887592612236928792916004016159c2565b602060405180830381865afa158015612253573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227791906159f8565b9050806000036122b3576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b84811015612994576000876000015182815181106122da576122da61534b565b6020026020010151905060006122f382606001516106a4565b905060008160038111156123095761230961454b565b1480612326575060038160038111156123245761232461454b565b145b61236c57816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a2505061298c565b831561242957600a5460009063ffffffff16612388874261528a565b11905080806123a8575060038260038111156123a6576123a661454b565b145b6123de576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8884815181106123f0576123f061534b565b6020026020010151600014612423578884815181106124115761241161534b565b60200260200101518360800181815250505b5061248c565b600081600381111561243d5761243d61454b565b1461248c57606082015160405167ffffffffffffffff90911681527f67d9ba0f63d427c482c2736300e6d5a34c6691dbcdea8ad35828a1f1ba47e8729060200160405180910390a1505061298c565b60c082015167ffffffffffffffff16156127595760208083015173ffffffffffffffffffffffffffffffffffffffff166000908152600f909152604081205467ffffffffffffffff16908190036126b7577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16156126b75760208301516040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa1580156125ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d09190615433565b60c084015190915067ffffffffffffffff166125ed826001615a11565b67ffffffffffffffff161461265a57826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a350505061298c565b60208381015173ffffffffffffffffffffffffffffffffffffffff166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b60008260038111156126cb576126cb61454b565b036127575760c083015167ffffffffffffffff166126ea826001615a11565b67ffffffffffffffff161461275757826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a350505061298c565b505b6000896020015184815181106127715761277161534b565b6020026020010151905061279d8360600151846000015185610140015151866101200151518551613096565b6127ac83606001516001613217565b6000806127b985846132c1565b915091506127cb856060015183613217565b86156128375760038260038111156127e5576127e561454b565b036128375760008460038111156127fe576127fe61454b565b1461283757806040517fcf19edfd00000000000000000000000000000000000000000000000000000000815260040161076391906145ec565b600282600381111561284b5761284b61454b565b146128a35760038260038111156128645761286461454b565b146128a3578460600151826040517f9e261603000000000000000000000000000000000000000000000000000000008152600401610763929190615a32565b60c085015167ffffffffffffffff16156129385760008460038111156128cb576128cb61454b565b036129385760208086015173ffffffffffffffffffffffffffffffffffffffff166000908152600f90915260408120805467ffffffffffffffff169161291083615a50565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b846101800151856060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef65848460405161297e929190615a6d565b60405180910390a350505050505b6001016122ba565b50505050505050565b600061106d8373ffffffffffffffffffffffffffffffffffffffff841661338a565b60006129e28473ffffffffffffffffffffffffffffffffffffffff851684613396565b949350505050565b612a0d6129f982840184615a8d565b604080516000815260208101909152611efc565b5050565b8154600090612a3a90700100000000000000000000000000000000900463ffffffff164261528a565b90508015612adc5760018301548354612a82916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612f06565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612b02916fffffffffffffffffffffffffffffffff90811691166133b9565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612be99084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b6000610719826133cf565b6000808080612c1086866133da565b909450925050505b9250929050565b3373ffffffffffffffffffffffffffffffffffffffff821603612c9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610763565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60608888808060200260200160405190810160405280939291908181526020016000905b82821015612d6457612d5560408302860136819003810190615ac2565b81526020019060010190612d38565b505050505090506000805b89811015612ecd57612e278b8b83818110612d8c57612d8c61534b565b905060400201602001358a8a8a8a86818110612daa57612daa61534b565b9050602002810190612dbc9190615533565b810190612dc99190615ade565b898987818110612ddb57612ddb61534b565b9050602002810190612ded9190615533565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506133e992505050565b838281518110612e3957612e3961534b565b6020026020010181905250612e75838281518110612e5957612e5961534b565b602002602001015160000151600c61382a90919063ffffffff16565b15612ec557612eb8838281518110612e8f57612e8f61534b565b6020908102919091010151600b5473ffffffffffffffffffffffffffffffffffffffff1661384c565b612ec29083615450565b91505b600101612d6f565b508015612edd57612edd81613987565b5098975050505050505050565b6000612ef583613994565b801561106d575061106d83836139f8565b6000612f2585612f1684866152f3565b612f209087615450565b6133b9565b95945050505050565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612fd198979695949392919073ffffffffffffffffffffffffffffffffffffffff9889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b604051602081830303815290604052805190602001208561012001518051906020012086610140015160405160200161300a9190615baa565b604051602081830303815290604052805190602001208761016001516040516020016130369190615c17565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff161461310f576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610763565b600a5468010000000000000000900461ffff16831115613167576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610763565b8083146131ac576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610763565b600a54640100000000900463ffffffff1682111561321057600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff16600482015260248101839052604401610763565b5050505050565b600060026132266080856152cc565b67ffffffffffffffff1661323a91906152f3565b9050600060108161324c60808761530a565b67ffffffffffffffff1681526020810191909152604001600020549050816132766001600461528a565b901b19168183600381111561328d5761328d61454b565b901b1780601060006132a060808861530a565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a5906133059087908790600401615c2a565b600060405180830381600087803b15801561331f57600080fd5b505af1925050508015613330575060015b61336f573d80801561335e576040519150601f19603f3d011682016040523d82523d6000602084013e613363565b606091505b50600392509050612c18565b50506040805160208101909152600081526002909250929050565b600061106d8383613ac7565b60006129e2848473ffffffffffffffffffffffffffffffffffffffff8516613ae4565b60008183106133c8578161106d565b5090919050565b600061071982613b01565b6000808080612c108686613b0c565b6040805180820190915260008082526020820152600061340c8460200151613b37565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa15801561349e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c29190615db4565b905073ffffffffffffffffffffffffffffffffffffffff81161580613524575061352273ffffffffffffffffffffffffffffffffffffffff82167faff2afbf00000000000000000000000000000000000000000000000000000000612eea565b155b15613573576040517fae9b4ce900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610763565b60008061358b8885896060015163ffffffff16613bea565b9150915060008060006136a36040518061010001604052808e81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff1681526020018f81526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018c6000015181526020018c6040015181526020018b81525060405160240161363f9190615dd1565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613d3a565b925092509250826136e257816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161076391906145ec565b815160201461372a5781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610763565b60008280602001905181019061374091906159f8565b90508673ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff16146137ef57600061378b8d8a613786868a61528a565b613bea565b509050868110806137a55750816137a2888361528a565b14155b156137ed576040517fa966e21f000000000000000000000000000000000000000000000000000000008152600481018390526024810188905260448101829052606401610763565b505b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff9098168852602088015250949550505050505095945050505050565b600061106d8373ffffffffffffffffffffffffffffffffffffffff8416613e60565b81516040517fd02641a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015260009182919084169063d02641a0906024016040805180830381865afa1580156138bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138e39190615ec2565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036139595783516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610763565b60208401516129e2907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690613e6c565b6114f66003826000613ea9565b60006139c0827f01ffc9a7000000000000000000000000000000000000000000000000000000006139f8565b801561071957506139f1827fffffffff000000000000000000000000000000000000000000000000000000006139f8565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613ab0575060208210155b8015613abc5750600081115b979650505050505050565b6000818152600283016020526040812081905561106d838361422c565b600082815260028401602052604081208290556129e28484614238565b600061071982614244565b60008080613b1a858561424e565b600081815260029690960160205260409095205494959350505050565b60008151602014613b7657816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161076391906145ec565b600082806020019051810190613b8c91906159f8565b905073ffffffffffffffffffffffffffffffffffffffff811180613bb1575061040081105b1561071957826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161076391906145ec565b6000806000806000613c8688604051602401613c22919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613d3a565b92509250925082613cc557816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161076391906145ec565b6020825114613d0d5781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610763565b81806020019051810190613d2191906159f8565b613d2b828861528a565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613d5d57613d5d6145ff565b6040519080825280601f01601f191660200182016040528015613d87576020820181803683370190505b509150863b613dba577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613ded577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613e26577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613e495750835b808352806000602085013e50955095509592505050565b600061106d838361425a565b6000670de0b6b3a7640000613e9f837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166152f3565b61106d9190615f24565b825474010000000000000000000000000000000000000000900460ff161580613ed0575081155b15613eda57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090613f2090700100000000000000000000000000000000900463ffffffff164261528a565b90508015613fe05781831115613f62576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613f9c9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612f06565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156140975773ffffffffffffffffffffffffffffffffffffffff841661403f576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610763565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610763565b848310156141aa5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906140db908261528a565b6140e5878a61528a565b6140ef9190615450565b6140f99190615f24565b905073ffffffffffffffffffffffffffffffffffffffff8616614152576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610763565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610763565b6141b4858461528a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600061106d8383614279565b600061106d8383614373565b6000610719825490565b600061106d83836143c2565b600061106d83836000818152600183016020526040812054151561106d565b6000818152600183016020526040812054801561436257600061429d60018361528a565b85549091506000906142b19060019061528a565b90508181146143165760008660000182815481106142d1576142d161534b565b90600052602060002001549050808760000184815481106142f4576142f461534b565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061432757614327615f38565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610719565b6000915050610719565b5092915050565b60008181526001830160205260408120546143ba57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610719565b506000610719565b60008260000182815481106143d9576143d961534b565b9060005260206000200154905092915050565b828054828255906000526020600020908101928215614466579160200282015b8281111561446657825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061440c565b50614472929150614476565b5090565b5b808211156144725760008155600101614477565b60e08101610719828473ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff811681146114f657600080fd5b803561452981614508565b919050565b60006020828403121561454057600080fd5b813561106d81614508565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6004811061458a5761458a61454b565b9052565b60208101610719828461457a565b60005b838110156145b757818101518382015260200161459f565b50506000910152565b600081518084526145d881602086016020860161459c565b601f01601f19169290920160200192915050565b60208152600061106d60208301846145c0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715614651576146516145ff565b60405290565b6040516080810167ffffffffffffffff81118282101715614651576146516145ff565b6040516101a0810167ffffffffffffffff81118282101715614651576146516145ff565b604051601f8201601f1916810167ffffffffffffffff811182821017156146c7576146c76145ff565b604052919050565b600067ffffffffffffffff8211156146e9576146e96145ff565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146114f657600080fd5b8035614529816146f3565b600082601f83011261473157600080fd5b81356020614746614741836146cf565b61469e565b8083825260208201915060208460051b87010193508684111561476857600080fd5b602086015b8481101561478d578035614780816146f3565b835291830191830161476d565b509695505050505050565b803560ff8116811461452957600080fd5b600067ffffffffffffffff8211156147c3576147c36145ff565b50601f01601f191660200190565b600082601f8301126147e257600080fd5b81356147f0614741826147a9565b81815284602083860101111561480557600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561483b57600080fd5b863567ffffffffffffffff8082111561485357600080fd5b61485f8a838b01614720565b9750602089013591508082111561487557600080fd5b6148818a838b01614720565b965061488f60408a01614798565b955060608901359150808211156148a557600080fd5b6148b18a838b016147d1565b94506148bf60808a0161451e565b935060a08901359150808211156148d557600080fd5b506148e289828a016147d1565b9150509295509295509295565b60008151808452602080850194506020840160005b8381101561493657815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614904565b509495945050505050565b60208152600061106d60208301846148ef565b60006020828403121561496657600080fd5b813561106d816146f3565b80151581146114f657600080fd5b803561452981614971565b60006040828403121561499c57600080fd5b6149a461462e565b905081356149b1816146f3565b808252506020820135602082015292915050565b600082601f8301126149d657600080fd5b813560206149e6614741836146cf565b8083825260208201915060208460061b870101935086841115614a0857600080fd5b602086015b8481101561478d57614a1f888261498a565b835291830191604001614a0d565b600082601f830112614a3e57600080fd5b81356020614a4e614741836146cf565b82815260059290921b84018101918181019086841115614a6d57600080fd5b8286015b8481101561478d57803567ffffffffffffffff811115614a915760008081fd5b614a9f8986838b01016147d1565b845250918301918301614a71565b600082601f830112614abe57600080fd5b81356020614ace614741836146cf565b82815260059290921b84018101918181019086841115614aed57600080fd5b8286015b8481101561478d57803567ffffffffffffffff811115614b115760008081fd5b614b1f8986838b0101614a2d565b845250918301918301614af1565b600082601f830112614b3e57600080fd5b81356020614b4e614741836146cf565b8083825260208201915060208460051b870101935086841115614b7057600080fd5b602086015b8481101561478d5780358352918301918301614b75565b600060808284031215614b9e57600080fd5b614ba6614657565b9050813567ffffffffffffffff80821115614bc057600080fd5b818401915084601f830112614bd457600080fd5b81356020614be4614741836146cf565b82815260059290921b84018101918181019088841115614c0357600080fd5b8286015b84811015614d5f57803586811115614c1e57600080fd5b87016101a0818c03601f19011215614c3557600080fd5b614c3d61467a565b614c4886830161451e565b8152614c5660408301614715565b86820152614c6660608301614715565b6040820152614c776080830161451e565b606082015260a08201356080820152614c9260c0830161497f565b60a0820152614ca360e0830161451e565b60c0820152610100614cb6818401614715565b60e083015261012080840135828401526101409150818401358a811115614cdc57600080fd5b614cea8f8a838801016147d1565b828501525050610160808401358a811115614d0457600080fd5b614d128f8a838801016149c5565b83850152506101809150818401358a811115614d2d57600080fd5b614d3b8f8a83880101614a2d565b91840191909152506101a09290920135918101919091528352918301918301614c07565b5086525085810135935082841115614d7657600080fd5b614d8287858801614aad565b90850152506040840135915080821115614d9b57600080fd5b50614da884828501614b2d565b6040830152506060820135606082015292915050565b60008060408385031215614dd157600080fd5b823567ffffffffffffffff80821115614de957600080fd5b614df586838701614b8c565b9350602091508185013581811115614e0c57600080fd5b85019050601f81018613614e1f57600080fd5b8035614e2d614741826146cf565b81815260059190911b82018301908381019088831115614e4c57600080fd5b928401925b82841015614e6a57833582529284019290840190614e51565b80955050505050509250929050565b60a08101610719828463ffffffff8082511683528060208301511660208401525061ffff6040820151166040830152606081015173ffffffffffffffffffffffffffffffffffffffff808216606085015280608084015116608085015250505050565b600060208284031215614eee57600080fd5b813567ffffffffffffffff811115614f0557600080fd5b820160a0818503121561106d57600080fd5b600082601f830112614f2857600080fd5b81356020614f38614741836146cf565b82815260069290921b84018101918181019086841115614f5757600080fd5b8286015b8481101561478d5760408189031215614f745760008081fd5b614f7c61462e565b8135614f87816146f3565b815281850135614f96816146f3565b81860152835291830191604001614f5b565b60008060408385031215614fbb57600080fd5b823567ffffffffffffffff80821115614fd357600080fd5b614fdf86838701614f17565b93506020850135915080821115614ff557600080fd5b5061500285828601614f17565b9150509250929050565b60008083601f84011261501e57600080fd5b50813567ffffffffffffffff81111561503657600080fd5b6020830191508360208260051b8501011115612c1857600080fd5b60008060008060008060008060e0898b03121561506d57600080fd5b606089018a81111561507e57600080fd5b8998503567ffffffffffffffff8082111561509857600080fd5b818b0191508b601f8301126150ac57600080fd5b8135818111156150bb57600080fd5b8c60208285010111156150cd57600080fd5b6020830199508098505060808b01359150808211156150eb57600080fd5b6150f78c838d0161500c565b909750955060a08b013591508082111561511057600080fd5b5061511d8b828c0161500c565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff8116811461452957600080fd5b60006060828403121561516857600080fd5b6040516060810181811067ffffffffffffffff8211171561518b5761518b6145ff565b604052823561519981614971565b81526151a760208401615136565b60208201526151b860408401615136565b60408201529392505050565b6040815260006151d760408301856148ef565b8281036020840152612f2581856148ef565b6000806000604084860312156151fe57600080fd5b833567ffffffffffffffff8082111561521657600080fd5b908501906101a0828803121561522b57600080fd5b9093506020850135908082111561524157600080fd5b5061524e8682870161500c565b9497909650939450505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156107195761071961525b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff808416806152e7576152e761529d565b92169190910692915050565b80820281158282048414176107195761071961525b565b600067ffffffffffffffff808416806153255761532561529d565b92169190910492915050565b60208101600383106153455761534561454b565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff8083168181036153935761539361525b565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153cd8184018a6148ef565b905082810360808401526153e181896148ef565b905060ff871660a084015282810360c08401526153fe81876145c0565b905067ffffffffffffffff851660e084015282810361010084015261542381856145c0565b9c9b505050505050505050505050565b60006020828403121561544557600080fd5b815161106d81614508565b808201808211156107195761071961525b565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261549857600080fd5b83018035915067ffffffffffffffff8211156154b357600080fd5b6020019150600681901b3603821315612c1857600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261550057600080fd5b83018035915067ffffffffffffffff82111561551b57600080fd5b6020019150600581901b3603821315612c1857600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261556857600080fd5b83018035915067ffffffffffffffff82111561558357600080fd5b602001915036819003821315612c1857600080fd5b60008151808452602080850194506020840160005b83811015614936578151805173ffffffffffffffffffffffffffffffffffffffff16885283015183880152604090960195908201906001016155ad565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c08401526156256101208401826145c0565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e086015261566183836145c0565b9250608089015191508085840301610100860152506156808282615598565b92505050615694602083018661ffff169052565b836040830152612f25606083018473ffffffffffffffffffffffffffffffffffffffff169052565b6000806000606084860312156156d157600080fd5b83516156dc81614971565b602085015190935067ffffffffffffffff8111156156f957600080fd5b8401601f8101861361570a57600080fd5b8051615718614741826147a9565b81815287602083850101111561572d57600080fd5b61573e82602083016020860161459c565b809450505050604084015190509250925092565b63ffffffff811681146114f657600080fd5b600060a0828403121561577657600080fd5b60405160a0810181811067ffffffffffffffff82111715615799576157996145ff565b60405282516157a781615752565b815260208301516157b781615752565b6020820152604083015161ffff811681146157d157600080fd5b604082015260608301516157e4816146f3565b606082015260808301516157f7816146f3565b60808201529392505050565b6101808101615881828573ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff16610120830152606083015173ffffffffffffffffffffffffffffffffffffffff90811661014084015260808401511661016083015261106d565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526159268285018b6148ef565b9150838203608085015261593a828a6148ef565b915060ff881660a085015283820360c085015261595782886145c0565b90861660e0850152838103610100850152905061542381856145c0565b60006020828403121561598657600080fd5b815161106d81614971565b60008151808452602080850194506020840160005b83811015614936578151875295820195908201906001016159a6565b6060815260006159d56060830186615991565b82810360208401526159e78186615991565b915050826040830152949350505050565b600060208284031215615a0a57600080fd5b5051919050565b67ffffffffffffffff81811683821601908082111561436c5761436c61525b565b67ffffffffffffffff831681526040810161106d602083018461457a565b600067ffffffffffffffff8083168181036153935761539361525b565b615a77818461457a565b6040602082015260006129e260408301846145c0565b600060208284031215615a9f57600080fd5b813567ffffffffffffffff811115615ab657600080fd5b6129e284828501614b8c565b600060408284031215615ad457600080fd5b61106d838361498a565b600060208284031215615af057600080fd5b813567ffffffffffffffff80821115615b0857600080fd5b9083019060808286031215615b1c57600080fd5b615b24614657565b823582811115615b3357600080fd5b615b3f878286016147d1565b825250602083013582811115615b5457600080fd5b615b60878286016147d1565b602083015250604083013582811115615b7857600080fd5b615b84878286016147d1565b60408301525060608301359250615b9a83615752565b6060810192909252509392505050565b60208152600061106d6020830184615598565b60008282518085526020808601955060208260051b8401016020860160005b84811015615c0a57601f19868403018952615bf88383516145c0565b98840198925090830190600101615bdc565b5090979650505050505050565b60208152600061106d6020830184615bbd565b60408152615c4560408201845167ffffffffffffffff169052565b60006020840151615c6e606084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604084015173ffffffffffffffffffffffffffffffffffffffff8116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c0840151610100615cdc8185018367ffffffffffffffff169052565b60e08601519150610120615d078186018473ffffffffffffffffffffffffffffffffffffffff169052565b81870151925061014091508282860152808701519250506101a06101608181870152615d376101e08701856145c0565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0610180818887030181890152615d768686615598565b9550828a01519450818887030184890152615d918686615bbd565b9550808a01516101c089015250505050508281036020840152612f258185615bbd565b600060208284031215615dc657600080fd5b815161106d816146f3565b6020815260008251610100806020850152615df06101208501836145c0565b91506020850151615e0d604086018267ffffffffffffffff169052565b50604085015173ffffffffffffffffffffffffffffffffffffffff8116606086015250606085015160808501526080850151615e6160a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0850151601f19808685030160c0870152615e7e84836145c0565b935060c08701519150808685030160e0870152615e9b84836145c0565b935060e0870151915080868503018387015250615eb883826145c0565b9695505050505050565b600060408284031215615ed457600080fd5b615edc61462e565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114615f0857600080fd5b81526020830151615f1881615752565b60208201529392505050565b600082615f3357615f3361529d565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"DestinationGasAmountCountMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"oldLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"tokenIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"oldLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenGasOverride\",\"type\":\"uint256\"}],\"name\":\"InvalidTokenGasOverride\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receiverExecutionGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"internalType\":\"structEVM2EVMOffRamp.GasLimitOverride[]\",\"name\":\"gasLimitOverrides\",\"type\":\"tuple[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101a06040523480156200001257600080fd5b5060405162006609380380620066098339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f40620006c9600039600081816102ec01528181611c6a01526133920152600081816102bd01528181611c420152611f2701526000818161028e01528181610d8d01528181610df201528181611c18015281816124a4015261250e015260006120c601526000818161025f0152611bee0152600081816101ff0152611b9201526000818161022f01528181611bc601528181611ee40152818161303b01526134bf0152600081816101d001528181611b6d01526121ac015260008181611e3e0152611e8a0152615f406000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806385572ffb116100d8578063afcb95d71161008c578063c92b283211610066578063c92b2832146105f3578063f077b59214610606578063f2fde38b1461061c57600080fd5b8063afcb95d7146105ad578063b1dc65a4146105cd578063b6113fce146105e057600080fd5b8063873504d7116100bd578063873504d7146105765780638926c4ee146105895780638da5cb5b1461059c57600080fd5b806385572ffb1461053c578063856c82471461054a57600080fd5b8063599f64311161013a5780637437ff9f116101145780637437ff9f1461046157806379ba50971461050457806381ff70481461050c57600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516103299190614311565b60405180910390f35b6103456103403660046143a7565b61062f565b6040516103299190614407565b61038e6040518060400160405280601881526020017f45564d3245564d4f666652616d7020312e352e302d646576000000000000000081525081565b6040516103299190614465565b6103ae6103a936600461468e565b6106aa565b005b6103b8610a9e565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610b53565b60405161032991906147a0565b6103ae61045c3660046147b3565b610bb5565b6104f76040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a01000000000000000000009091046001600160a01b039081166060830152600b5416608082015290565b60405161032991906147d0565b6103ae610c7e565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae610182366004614826565b61055d6105583660046147b3565b610d61565b60405167ffffffffffffffff9091168152602001610329565b6103ae6105843660046148f2565b610e64565b6103ae610597366004614e1d565b611037565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae6105db366004614f74565b61129c565b6103ae6105ee366004615059565b6114a7565b6103ae610601366004615110565b6117e7565b61060e611852565b60405161032992919061517e565b6103ae61062a3660046147b3565b611978565b600061063d600160046151d2565b600261064a608085615214565b67ffffffffffffffff1661065e919061523b565b6010600061066d608087615252565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106a4576106a46143c4565b92915050565b84518460ff16601f8211156106f75760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190615279565b60405180910390fd5b806000036107345760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190615279565b61073c611989565b610745856119ff565b60095460005b818110156107bc57600860006009838154811061076a5761076a615293565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161074b565b5050865160005b8181101561095f5760008982815181106107df576107df615293565b60200260200101519050600060028111156107fc576107fc6143c4565b6001600160a01b038216600090815260086020526040902054610100900460ff16600281111561082e5761082e6143c4565b146108685760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190615279565b6001600160a01b0381166108a8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561094b5761094b6143c4565b0217905550905050508060010190506107c3565b5087516109739060099060208b019061427f565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a1617179055600780546109f99146913091906000906109cb9063ffffffff166152c2565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611cc9565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610a8a9487949293918316921691909117908f908f908f908f908f908f906152e5565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610b4e90611d56565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bab57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8d575b5050505050905090565b6000546001600160a01b03163314801590610bdb57506002546001600160a01b03163314155b15610c12576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b6001546001600160a01b03163314610cf2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106ee565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106a4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106a4576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5d919061537b565b9392505050565b610e6c611989565b60005b8251811015610f3f57610ea9838281518110610e8d57610e8d615293565b602002602001015160200151600c611e0890919063ffffffff16565b15610f37577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d58782838281518110610ee157610ee1615293565b602002602001015160000151848381518110610eff57610eff615293565b602002602001015160200151604051610f2e9291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610e6f565b5060005b815181101561103257610f9c828281518110610f6157610f61615293565b602002602001015160200151838381518110610f7f57610f7f615293565b602002602001015160000151600c611e1d9092919063ffffffff16565b1561102a577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a828281518110610fd457610fd4615293565b602002602001015160000151838381518110610ff257610ff2615293565b6020026020010151602001516040516110219291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610f43565b505050565b61103f611e3b565b8151518151811461107c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156112915760008460000151828151811061109f5761109f615293565b6020026020010151905060008483815181106110bd576110bd615293565b60209081029190910101518051909150801561112c57826080015181101561112c5761018083015160808401516040517f9c6db58d00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016106ee565b816020015151836101400151511461118e5761018083015160608401516040517f85d2e5bf000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff1660248201526044016106ee565b61016083015160005b846101400151518110156112815760008287815181106111b9576111b9615293565b60200260200101518060200190518101906111d491906153dd565b90506000856020015183815181106111ee576111ee615293565b602002602001015163ffffffff169050806000141580156112185750816060015163ffffffff1681105b156112775761018087015160608301516040517fef0c635200000000000000000000000000000000000000000000000000000000815260048101929092526024820185905263ffffffff166044820152606481018290526084016106ee565b5050600101611197565b505050505080600101905061107f565b506110328383611ebc565b6112a6878761290f565b6005548835908082146112ef576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016106ee565b6112f7611e3b565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561137f5761137f6143c4565b6002811115611390576113906143c4565b90525090506002816020015160028111156113ad576113ad6143c4565b1480156113e757506009816000015160ff16815481106113cf576113cf615293565b6000918252602090912001546001600160a01b031633145b61141d576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061142b85602061523b565b61143688602061523b565b6114428b6101446154a9565b61144c91906154a9565b61145691906154a9565b905036811461149a576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016106ee565b5050505050505050505050565b3330146114e0576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516000808252602082019092528161151d565b60408051808201909152600080825260208201528152602001906001900390816114f65790505b50905060006115306101408701876154bc565b905011156115a7576115a46115496101408701876154bc565b6115596040890160208a016147b3565b604080516001600160a01b0390921660208301520160408051601f1981840301815291815261158e9060608b01908b016147b3565b61159c6101608b018b615524565b8a8a8a612966565b90505b6115b561012086018661558c565b15905080156115c657506080850135155b806115e857506115dc60608601604087016147b3565b6001600160a01b03163b155b8061163357506116317f85572ffb0000000000000000000000000000000000000000000000000000000061162260608801604089016147b3565b6001600160a01b031690612b8f565b155b1561163e57506117e1565b600a546040805160a08101909152610180870135815260009182916a01000000000000000000009091046001600160a01b031690633cf979839060208082019061168a908c018c6143a7565b67ffffffffffffffff1681526020018a60200160208101906116ac91906147b3565b604080516001600160a01b0390921660208301520160408051601f1981840301815291905281526020016116e46101208c018c61558c565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200186905261138860808b013561173960608d0160408e016147b3565b6040518563ffffffff1660e01b81526004016117589493929190615636565b6000604051808303816000875af1158015611777573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261179f91908101906156fb565b5091509150816117dd57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b5050505b50505050565b6000546001600160a01b0316331480159061180d57506002546001600160a01b03163314155b15611844576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61184f600382612bab565b50565b6060806000611861600c612d90565b90508067ffffffffffffffff81111561187c5761187c614478565b6040519080825280602002602001820160405280156118a5578160200160208202803683370190505b5092508067ffffffffffffffff8111156118c1576118c1614478565b6040519080825280602002602001820160405280156118ea578160200160208202803683370190505b50915060005b8181101561197257600080611906600c84612d9b565b915091508086848151811061191d5761191d615293565b60200260200101906001600160a01b031690816001600160a01b0316815250508185848151811061195057611950615293565b6001600160a01b039092166020928302919091019091015250506001016118f0565b50509091565b611980611989565b61184f81612db9565b6000546001600160a01b031633146119fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106ee565b565b600081806020019051810190611a159190615755565b60608101519091506001600160a01b0316611a5c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a01000000000000000000006001600160a01b039485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611cbd9184906157f4565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611ced999897969594939291906158b6565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611de482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611dc891906151d2565b85608001516fffffffffffffffffffffffffffffffff16612e94565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6000610e5d836001600160a01b038416612ebc565b6000611e33846001600160a01b03851684612ec8565b949350505050565b467f0000000000000000000000000000000000000000000000000000000000000000146119fd576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016106ee565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611f76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9a919061593e565b15611fd1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815151600081900361200e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015151811461204c576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561206757612067614478565b604051908082528060200260200182016040528015612090578160200160208202803683370190505b50905060005b82811015612168576000856000015182815181106120b6576120b6615293565b602002602001015190506120ea817f0000000000000000000000000000000000000000000000000000000000000000612ede565b8383815181106120fc576120fc615293565b60200260200101818152505080610180015183838151811061212057612120615293565b60200260200101511461215f576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101612096565b508251604080860151606087015191517f32048875000000000000000000000000000000000000000000000000000000008152921515926000926001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926332048875926121e29288929160040161598c565b602060405180830381865afa1580156121ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222391906159c2565b90508060000361225f576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b848110156117dd5760008760000151828151811061228257612282615293565b60200260200101519050600061229b826060015161062f565b905060008160038111156122b1576122b16143c4565b14806122ce575060038160038111156122cc576122cc6143c4565b145b61231457816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a25050612907565b606085156123fa5788848151811061232e5761232e615293565b6020908102919091018101510151600a5490915060009063ffffffff1661235587426151d2565b119050808061237557506003836003811115612373576123736143c4565b145b6123ab576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8985815181106123bd576123bd615293565b6020026020010151600001516000146123f4578985815181106123e2576123e2615293565b60209081029190910101515160808501525b5061245e565b600082600381111561240e5761240e6143c4565b1461245e57606083015160405167ffffffffffffffff90911681527f67d9ba0f63d427c482c2736300e6d5a34c6691dbcdea8ad35828a1f1ba47e8729060200160405180910390a1505050612907565b60c083015167ffffffffffffffff16156126df576020808401516001600160a01b03166000908152600f909152604081205467ffffffffffffffff1690819003612649577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156126495760208401516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa158015612557573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257b919061537b565b60c085015190915067ffffffffffffffff166125988260016159db565b67ffffffffffffffff16146125f95783602001516001600160a01b03168460c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a350505050612907565b6020848101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b600083600381111561265d5761265d6143c4565b036126dd5760c084015167ffffffffffffffff1661267c8260016159db565b67ffffffffffffffff16146126dd5783602001516001600160a01b03168460c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a350505050612907565b505b60008a6020015185815181106126f7576126f7615293565b602002602001015190506127238460600151856000015186610140015151876101200151518551613039565b612732846060015160016131ba565b600080612740868486613264565b915091506127528660600151836131ba565b88156127be57600382600381111561276c5761276c6143c4565b036127be576000856003811115612785576127856143c4565b146127be57806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b60028260038111156127d2576127d26143c4565b1461282a5760038260038111156127eb576127eb6143c4565b1461282a578560600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016106ee9291906159fc565b60c086015167ffffffffffffffff16156128b2576000856003811115612852576128526143c4565b036128b2576020808701516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff169161288a83615a1a565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b856101800151866060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef6584846040516128f8929190615a37565b60405180910390a35050505050505b600101612262565b61296261291e82840184615a57565b604080516000808252602082019092529061295c565b6040805180820190915260008152606060208201528152602001906001900390816129345790505b50611ebc565b5050565b60608989808060200260200160405190810160405280939291908181526020016000905b828210156129b6576129a760408302860136819003810190615a8c565b8152602001906001019061298a565b505050505090506000805b8a811015612b715760008888838181106129dd576129dd615293565b90506020028101906129ef919061558c565b8101906129fc9190615aa8565b90508451600014612a5757848281518110612a1957612a19615293565b602002602001015163ffffffff16600014612a5757848281518110612a4057612a40615293565b602090810291909101015163ffffffff1660608201525b612ad78d8d84818110612a6c57612a6c615293565b905060400201602001358c8c848b8b88818110612a8b57612a8b615293565b9050602002810190612a9d919061558c565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061333192505050565b848381518110612ae957612ae9615293565b6020026020010181905250612b25848381518110612b0957612b09615293565b602002602001015160000151600c6136fd90919063ffffffff16565b15612b6857612b5b848381518110612b3f57612b3f615293565b6020908102919091010151600b546001600160a01b0316613712565b612b6590846154a9565b92505b506001016129c1565b508015612b8157612b8181613833565b509998505050505050505050565b6000612b9a83613840565b8015610e5d5750610e5d83836138a4565b8154600090612bd490700100000000000000000000000000000000900463ffffffff16426151d2565b90508015612c765760018301548354612c1c916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e94565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c9c916fffffffffffffffffffffffffffffffff9081169116613973565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612d839084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106a482613989565b6000808080612daa8686613994565b909450925050505b9250929050565b336001600160a01b03821603612e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106ee565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612eb385612ea4848661523b565b612eae90876154a9565b613973565b95945050505050565b6000610e5d83836139a3565b6000611e3384846001600160a01b0385166139c0565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612f749897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612fad9190615b64565b60405160208183030381529060405280519060200120876101600151604051602001612fd99190615bd1565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff16146130b2576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016106ee565b600a5468010000000000000000900461ffff1683111561310a576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b80831461314f576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b600a54640100000000900463ffffffff168211156131b357600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff166004820152602481018390526044016106ee565b5050505050565b600060026131c9608085615214565b67ffffffffffffffff166131dd919061523b565b905060006010816131ef608087615252565b67ffffffffffffffff168152602081019190915260400160002054905081613219600160046151d2565b901b191681836003811115613230576132306143c4565b901b178060106000613243608088615252565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517fb6113fce000000000000000000000000000000000000000000000000000000008152600090606090309063b6113fce906132aa90889088908890600401615c1b565b600060405180830381600087803b1580156132c457600080fd5b505af19250505080156132d5575060015b613314573d808015613303576040519150601f19603f3d011682016040523d82523d6000602084013e613308565b606091505b50600392509050613329565b50506040805160208101909152600081526002905b935093915050565b6040805180820190915260008082526020820152600061335484602001516139dd565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa1580156133d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fd9190615da4565b90506001600160a01b038116158061344557506134436001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612b8f565b155b15613487576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016106ee565b60008061349f8885896060015163ffffffff16613a83565b91509150600080600061359d6040518061010001604052808e81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018d6001600160a01b031681526020018f8152602001896001600160a01b031681526020018c6000015181526020018c6040015181526020018b8152506040516024016135399190615dc1565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613bc6565b925092509250826135dc57816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b81516020146136245781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b60008280602001905181019061363a91906159c2565b9050866001600160a01b03168c6001600160a01b0316146136cf57600061366b8d8a613666868a6151d2565b613a83565b5090508681108061368557508161368288836151d2565b14155b156136cd576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016106ee565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000610e5d836001600160a01b038416613cec565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613778573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379c9190615e8e565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036138055783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016106ee565b6020840151611e33907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690613cf8565b61184f6003826000613d35565b600061386c827f01ffc9a7000000000000000000000000000000000000000000000000000000006138a4565b80156106a4575061389d827fffffffff000000000000000000000000000000000000000000000000000000006138a4565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561395c575060208210155b80156139685750600081115b979650505050505050565b60008183106139825781610e5d565b5090919050565b60006106a482614084565b6000808080612daa868661408f565b60008181526002830160205260408120819055610e5d83836140ba565b60008281526002840160205260408120829055611e3384846140c6565b60008151602014613a1c57816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b600082806020019051810190613a3291906159c2565b90506001600160a01b03811180613a4a575061040081105b156106a457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b6000806000806000613b1288604051602401613aae91906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613bc6565b92509250925082613b5157816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b6020825114613b995781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b81806020019051810190613bad91906159c2565b613bb782886151d2565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613be957613be9614478565b6040519080825280601f01601f191660200182016040528015613c13576020820181803683370190505b509150863b613c46577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613c79577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613cb2577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613cd55750835b808352806000602085013e50955095509592505050565b6000610e5d83836140d2565b6000670de0b6b3a7640000613d2b837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff861661523b565b610e5d9190615ef0565b825474010000000000000000000000000000000000000000900460ff161580613d5c575081155b15613d6657505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090613dac90700100000000000000000000000000000000900463ffffffff16426151d2565b90508015613e6c5781831115613dee576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613e289083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e94565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613f09576001600160a01b038416613ebe576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106ee565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b03851660448201526064016106ee565b848310156140025760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613f4d90826151d2565b613f57878a6151d2565b613f6191906154a9565b613f6b9190615ef0565b90506001600160a01b038616613fb7576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106ee565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b03871660448201526064016106ee565b61400c85846151d2565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60006106a4826140de565b6000808061409d85856140e8565b600081815260029690960160205260409095205494959350505050565b6000610e5d83836140f4565b6000610e5d83836141ee565b6000610e5d838361423d565b60006106a4825490565b6000610e5d8383614255565b600081815260018301602052604081205480156141dd5760006141186001836151d2565b855490915060009061412c906001906151d2565b905081811461419157600086600001828154811061414c5761414c615293565b906000526020600020015490508087600001848154811061416f5761416f615293565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806141a2576141a2615f04565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106a4565b60009150506106a4565b5092915050565b6000818152600183016020526040812054614235575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106a4565b5060006106a4565b60008181526001830160205260408120541515610e5d565b600082600001828154811061426c5761426c615293565b9060005260206000200154905092915050565b8280548282559060005260206000209081019282156142ec579160200282015b828111156142ec57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0390911617825560209092019160019091019061429f565b506142f89291506142fc565b5090565b5b808211156142f857600081556001016142fd565b60e081016106a482846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff8116811461184f57600080fd5b80356143a281614381565b919050565b6000602082840312156143b957600080fd5b8135610e5d81614381565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110614403576144036143c4565b9052565b602081016106a482846143f3565b60005b83811015614430578181015183820152602001614418565b50506000910152565b60008151808452614451816020860160208601614415565b601f01601f19169290920160200192915050565b602081526000610e5d6020830184614439565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156144ca576144ca614478565b60405290565b6040516080810167ffffffffffffffff811182821017156144ca576144ca614478565b6040516101a0810167ffffffffffffffff811182821017156144ca576144ca614478565b604051601f8201601f1916810167ffffffffffffffff8111828210171561454057614540614478565b604052919050565b600067ffffffffffffffff82111561456257614562614478565b5060051b60200190565b6001600160a01b038116811461184f57600080fd5b80356143a28161456c565b600082601f83011261459d57600080fd5b813560206145b26145ad83614548565b614517565b8083825260208201915060208460051b8701019350868411156145d457600080fd5b602086015b848110156145f95780356145ec8161456c565b83529183019183016145d9565b509695505050505050565b803560ff811681146143a257600080fd5b600067ffffffffffffffff82111561462f5761462f614478565b50601f01601f191660200190565b600082601f83011261464e57600080fd5b813561465c6145ad82614615565b81815284602083860101111561467157600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156146a757600080fd5b863567ffffffffffffffff808211156146bf57600080fd5b6146cb8a838b0161458c565b975060208901359150808211156146e157600080fd5b6146ed8a838b0161458c565b96506146fb60408a01614604565b9550606089013591508082111561471157600080fd5b61471d8a838b0161463d565b945061472b60808a01614397565b935060a089013591508082111561474157600080fd5b5061474e89828a0161463d565b9150509295509295509295565b60008151808452602080850194506020840160005b838110156147955781516001600160a01b031687529582019590820190600101614770565b509495945050505050565b602081526000610e5d602083018461475b565b6000602082840312156147c557600080fd5b8135610e5d8161456c565b60a081016106a4828463ffffffff8082511683528060208301511660208401525061ffff604082015116604083015260608101516001600160a01b03808216606085015280608084015116608085015250505050565b60006020828403121561483857600080fd5b813567ffffffffffffffff81111561484f57600080fd5b820160a08185031215610e5d57600080fd5b600082601f83011261487257600080fd5b813560206148826145ad83614548565b82815260069290921b840181019181810190868411156148a157600080fd5b8286015b848110156145f957604081890312156148be5760008081fd5b6148c66144a7565b81356148d18161456c565b8152818501356148e08161456c565b818601528352918301916040016148a5565b6000806040838503121561490557600080fd5b823567ffffffffffffffff8082111561491d57600080fd5b61492986838701614861565b9350602085013591508082111561493f57600080fd5b5061494c85828601614861565b9150509250929050565b801515811461184f57600080fd5b80356143a281614956565b60006040828403121561498157600080fd5b6149896144a7565b905081356149968161456c565b808252506020820135602082015292915050565b600082601f8301126149bb57600080fd5b813560206149cb6145ad83614548565b8083825260208201915060208460061b8701019350868411156149ed57600080fd5b602086015b848110156145f957614a04888261496f565b8352918301916040016149f2565b600082601f830112614a2357600080fd5b81356020614a336145ad83614548565b82815260059290921b84018101918181019086841115614a5257600080fd5b8286015b848110156145f957803567ffffffffffffffff811115614a765760008081fd5b614a848986838b010161463d565b845250918301918301614a56565b600082601f830112614aa357600080fd5b81356020614ab36145ad83614548565b82815260059290921b84018101918181019086841115614ad257600080fd5b8286015b848110156145f957803567ffffffffffffffff811115614af65760008081fd5b614b048986838b0101614a12565b845250918301918301614ad6565b600082601f830112614b2357600080fd5b81356020614b336145ad83614548565b8083825260208201915060208460051b870101935086841115614b5557600080fd5b602086015b848110156145f95780358352918301918301614b5a565b600060808284031215614b8357600080fd5b614b8b6144d0565b9050813567ffffffffffffffff80821115614ba557600080fd5b818401915084601f830112614bb957600080fd5b81356020614bc96145ad83614548565b82815260059290921b84018101918181019088841115614be857600080fd5b8286015b84811015614d4457803586811115614c0357600080fd5b87016101a0818c03601f19011215614c1a57600080fd5b614c226144f3565b614c2d868301614397565b8152614c3b60408301614581565b86820152614c4b60608301614581565b6040820152614c5c60808301614397565b606082015260a08201356080820152614c7760c08301614964565b60a0820152614c8860e08301614397565b60c0820152610100614c9b818401614581565b60e083015261012080840135828401526101409150818401358a811115614cc157600080fd5b614ccf8f8a8388010161463d565b828501525050610160808401358a811115614ce957600080fd5b614cf78f8a838801016149aa565b83850152506101809150818401358a811115614d1257600080fd5b614d208f8a83880101614a12565b91840191909152506101a09290920135918101919091528352918301918301614bec565b5086525085810135935082841115614d5b57600080fd5b614d6787858801614a92565b90850152506040840135915080821115614d8057600080fd5b50614d8d84828501614b12565b6040830152506060820135606082015292915050565b63ffffffff8116811461184f57600080fd5b600082601f830112614dc657600080fd5b81356020614dd66145ad83614548565b8083825260208201915060208460051b870101935086841115614df857600080fd5b602086015b848110156145f9578035614e1081614da3565b8352918301918301614dfd565b6000806040808486031215614e3157600080fd5b833567ffffffffffffffff80821115614e4957600080fd5b614e5587838801614b71565b9450602091508186013581811115614e6c57600080fd5b8601601f81018813614e7d57600080fd5b8035614e8b6145ad82614548565b81815260059190911b8201840190848101908a831115614eaa57600080fd5b8584015b83811015614f1d57803586811115614ec65760008081fd5b8501808d03601f1901891315614edc5760008081fd5b614ee46144a7565b8882013581528982013588811115614efc5760008081fd5b614f0a8f8b83860101614db5565b828b015250845250918601918601614eae565b50809750505050505050509250929050565b60008083601f840112614f4157600080fd5b50813567ffffffffffffffff811115614f5957600080fd5b6020830191508360208260051b8501011115612db257600080fd5b60008060008060008060008060e0898b031215614f9057600080fd5b606089018a811115614fa157600080fd5b8998503567ffffffffffffffff80821115614fbb57600080fd5b818b0191508b601f830112614fcf57600080fd5b813581811115614fde57600080fd5b8c6020828501011115614ff057600080fd5b6020830199508098505060808b013591508082111561500e57600080fd5b61501a8c838d01614f2f565b909750955060a08b013591508082111561503357600080fd5b506150408b828c01614f2f565b999c989b50969995989497949560c00135949350505050565b6000806000806060858703121561506f57600080fd5b843567ffffffffffffffff8082111561508757600080fd5b908601906101a0828903121561509c57600080fd5b909450602086013590808211156150b257600080fd5b6150be88838901614f2f565b909550935060408701359150808211156150d757600080fd5b506150e487828801614db5565b91505092959194509250565b80356fffffffffffffffffffffffffffffffff811681146143a257600080fd5b60006060828403121561512257600080fd5b6040516060810181811067ffffffffffffffff8211171561514557615145614478565b604052823561515381614956565b8152615161602084016150f0565b6020820152615172604084016150f0565b60408201529392505050565b604081526000615191604083018561475b565b8281036020840152612eb3818561475b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106a4576106a46151a3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061522f5761522f6151e5565b92169190910692915050565b80820281158282048414176106a4576106a46151a3565b600067ffffffffffffffff8084168061526d5761526d6151e5565b92169190910492915050565b602081016003831061528d5761528d6143c4565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff8083168181036152db576152db6151a3565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153158184018a61475b565b90508281036080840152615329818961475b565b905060ff871660a084015282810360c08401526153468187614439565b905067ffffffffffffffff851660e084015282810361010084015261536b8185614439565b9c9b505050505050505050505050565b60006020828403121561538d57600080fd5b8151610e5d81614381565b600082601f8301126153a957600080fd5b81516153b76145ad82614615565b8181528460208386010111156153cc57600080fd5b611e33826020830160208701614415565b6000602082840312156153ef57600080fd5b815167ffffffffffffffff8082111561540757600080fd5b908301906080828603121561541b57600080fd5b6154236144d0565b82518281111561543257600080fd5b61543e87828601615398565b82525060208301518281111561545357600080fd5b61545f87828601615398565b60208301525060408301518281111561547757600080fd5b61548387828601615398565b6040830152506060830151925061549983614da3565b6060810192909252509392505050565b808201808211156106a4576106a46151a3565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154f157600080fd5b83018035915067ffffffffffffffff82111561550c57600080fd5b6020019150600681901b3603821315612db257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261555957600080fd5b83018035915067ffffffffffffffff82111561557457600080fd5b6020019150600581901b3603821315612db257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155c157600080fd5b83018035915067ffffffffffffffff8211156155dc57600080fd5b602001915036819003821315612db257600080fd5b60008151808452602080850194506020840160005b8381101561479557815180516001600160a01b031688528301518388015260409096019590820190600101615606565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152615671610120840182614439565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e08601526156ad8383614439565b9250608089015191508085840301610100860152506156cc82826155f1565b925050506156e0602083018661ffff169052565b836040830152612eb360608301846001600160a01b03169052565b60008060006060848603121561571057600080fd5b835161571b81614956565b602085015190935067ffffffffffffffff81111561573857600080fd5b61574486828701615398565b925050604084015190509250925092565b600060a0828403121561576757600080fd5b60405160a0810181811067ffffffffffffffff8211171561578a5761578a614478565b604052825161579881614da3565b815260208301516157a881614da3565b6020820152604083015161ffff811681146157c257600080fd5b604082015260608301516157d58161456c565b606082015260808301516157e88161456c565b60808201529392505050565b610180810161586582856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff1661012083015260608301516001600160a01b03908116610140840152608084015116610160830152610e5d565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526158f08285018b61475b565b91508382036080850152615904828a61475b565b915060ff881660a085015283820360c08501526159218288614439565b90861660e0850152838103610100850152905061536b8185614439565b60006020828403121561595057600080fd5b8151610e5d81614956565b60008151808452602080850194506020840160005b8381101561479557815187529582019590820190600101615970565b60608152600061599f606083018661595b565b82810360208401526159b1818661595b565b915050826040830152949350505050565b6000602082840312156159d457600080fd5b5051919050565b67ffffffffffffffff8181168382160190808211156141e7576141e76151a3565b67ffffffffffffffff8316815260408101610e5d60208301846143f3565b600067ffffffffffffffff8083168181036152db576152db6151a3565b615a4181846143f3565b604060208201526000611e336040830184614439565b600060208284031215615a6957600080fd5b813567ffffffffffffffff811115615a8057600080fd5b611e3384828501614b71565b600060408284031215615a9e57600080fd5b610e5d838361496f565b600060208284031215615aba57600080fd5b813567ffffffffffffffff80821115615ad257600080fd5b9083019060808286031215615ae657600080fd5b615aee6144d0565b823582811115615afd57600080fd5b615b098782860161463d565b825250602083013582811115615b1e57600080fd5b615b2a8782860161463d565b602083015250604083013582811115615b4257600080fd5b615b4e8782860161463d565b6040830152506060830135925061549983614da3565b602081526000610e5d60208301846155f1565b60008282518085526020808601955060208260051b8401016020860160005b84811015615bc457601f19868403018952615bb2838351614439565b98840198925090830190600101615b96565b5090979650505050505050565b602081526000610e5d6020830184615b77565b60008151808452602080850194506020840160005b8381101561479557815163ffffffff1687529582019590820190600101615bf9565b60608152615c3660608201855167ffffffffffffffff169052565b60006020850151615c5260808401826001600160a01b03169052565b5060408501516001600160a01b03811660a084015250606085015167ffffffffffffffff811660c084015250608085015160e083015260a0850151610100615c9d8185018315159052565b60c08701519150610120615cbc8186018467ffffffffffffffff169052565b60e08801519250610140615cda818701856001600160a01b03169052565b828901519350610160925083838701528189015193506101a091506101808281880152615d0b610200880186614439565b9450818a015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0808887030184890152615d4786846155f1565b948b01518886039091016101c0890152939450615d648585615b77565b9450808a01516101e0880152505050508281036020840152615d868186615b77565b90508281036040840152615d9a8185615be4565b9695505050505050565b600060208284031215615db657600080fd5b8151610e5d8161456c565b6020815260008251610100806020850152615de0610120850183614439565b91506020850151615dfd604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615e3760a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615e548483614439565b935060c08701519150808685030160e0870152615e718483614439565b935060e0870151915080868503018387015250615d9a8382614439565b600060408284031215615ea057600080fd5b615ea86144a7565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114615ed457600080fd5b81526020830151615ee481614da3565b60208201529392505050565b600082615eff57615eff6151e5565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var EVM2EVMOffRampABI = EVM2EVMOffRampMetaData.ABI @@ -566,27 +571,27 @@ func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) AcceptOwnership() (*type return _EVM2EVMOffRamp.Contract.AcceptOwnership(&_EVM2EVMOffRamp.TransactOpts) } -func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) ExecuteSingleMessage(opts *bind.TransactOpts, message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { - return _EVM2EVMOffRamp.contract.Transact(opts, "executeSingleMessage", message, offchainTokenData) +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) ExecuteSingleMessage(opts *bind.TransactOpts, message InternalEVM2EVMMessage, offchainTokenData [][]byte, tokenGasOverrides []uint32) (*types.Transaction, error) { + return _EVM2EVMOffRamp.contract.Transact(opts, "executeSingleMessage", message, offchainTokenData, tokenGasOverrides) } -func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) ExecuteSingleMessage(message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { - return _EVM2EVMOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMOffRamp.TransactOpts, message, offchainTokenData) +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) ExecuteSingleMessage(message InternalEVM2EVMMessage, offchainTokenData [][]byte, tokenGasOverrides []uint32) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMOffRamp.TransactOpts, message, offchainTokenData, tokenGasOverrides) } -func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) ExecuteSingleMessage(message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { - return _EVM2EVMOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMOffRamp.TransactOpts, message, offchainTokenData) +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) ExecuteSingleMessage(message InternalEVM2EVMMessage, offchainTokenData [][]byte, tokenGasOverrides []uint32) (*types.Transaction, error) { + return _EVM2EVMOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMOffRamp.TransactOpts, message, offchainTokenData, tokenGasOverrides) } -func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) ManuallyExecute(opts *bind.TransactOpts, report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactor) ManuallyExecute(opts *bind.TransactOpts, report InternalExecutionReport, gasLimitOverrides []EVM2EVMOffRampGasLimitOverride) (*types.Transaction, error) { return _EVM2EVMOffRamp.contract.Transact(opts, "manuallyExecute", report, gasLimitOverrides) } -func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) ManuallyExecute(report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { +func (_EVM2EVMOffRamp *EVM2EVMOffRampSession) ManuallyExecute(report InternalExecutionReport, gasLimitOverrides []EVM2EVMOffRampGasLimitOverride) (*types.Transaction, error) { return _EVM2EVMOffRamp.Contract.ManuallyExecute(&_EVM2EVMOffRamp.TransactOpts, report, gasLimitOverrides) } -func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) ManuallyExecute(report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { +func (_EVM2EVMOffRamp *EVM2EVMOffRampTransactorSession) ManuallyExecute(report InternalExecutionReport, gasLimitOverrides []EVM2EVMOffRampGasLimitOverride) (*types.Transaction, error) { return _EVM2EVMOffRamp.Contract.ManuallyExecute(&_EVM2EVMOffRamp.TransactOpts, report, gasLimitOverrides) } @@ -2688,9 +2693,9 @@ type EVM2EVMOffRampInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - ExecuteSingleMessage(opts *bind.TransactOpts, message InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) + ExecuteSingleMessage(opts *bind.TransactOpts, message InternalEVM2EVMMessage, offchainTokenData [][]byte, tokenGasOverrides []uint32) (*types.Transaction, error) - ManuallyExecute(opts *bind.TransactOpts, report InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) + ManuallyExecute(opts *bind.TransactOpts, report InternalExecutionReport, gasLimitOverrides []EVM2EVMOffRampGasLimitOverride) (*types.Transaction, error) SetAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 8be2d0b4dd..9977ebf494 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -12,7 +12,7 @@ commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitSto ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 2dbf7d8b03e1802beb9185ff2ea7d160250d1969f976e4f52040138d5416cc86 evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 15cd5695049ab4be1f396ec1d7b609738b2bcefa3740a7a48316e1f72506a34a -evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin 670b36a168a0a7cd721148a6065d019c7af4d8dcc08ba6ab8945789e164dd27b +evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin 0de6cf0ebf3777684b5867a1cbfe4dbfeabe2c0758151befb1293d5b983ac510 evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin bf1a3090a2f8d1632b82a6d45200cf6f3833a1e27303745405c1ed13ffc0cf83 lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin eadd37962f8011a86af54383ba3e0ae08c2987e2cda577c993f47b30c5b7672a lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin 82aaf0c20f2802bce3a831d585b497d2918513c6d72f81684c10f77631932526 diff --git a/core/gethwrappers/ccip/mocks/evm2_evm_off_ramp_interface.go b/core/gethwrappers/ccip/mocks/evm2_evm_off_ramp_interface.go index 9d63c34b02..29afadefd9 100644 --- a/core/gethwrappers/ccip/mocks/evm2_evm_off_ramp_interface.go +++ b/core/gethwrappers/ccip/mocks/evm2_evm_off_ramp_interface.go @@ -3,8 +3,6 @@ package mock_contracts import ( - big "math/big" - bind "github.com/ethereum/go-ethereum/accounts/abi/bind" common "github.com/ethereum/go-ethereum/common" @@ -240,9 +238,9 @@ func (_c *EVM2EVMOffRampInterface_CurrentRateLimiterState_Call) RunAndReturn(run return _c } -// ExecuteSingleMessage provides a mock function with given fields: opts, message, offchainTokenData -func (_m *EVM2EVMOffRampInterface) ExecuteSingleMessage(opts *bind.TransactOpts, message evm_2_evm_offramp.InternalEVM2EVMMessage, offchainTokenData [][]byte) (*types.Transaction, error) { - ret := _m.Called(opts, message, offchainTokenData) +// ExecuteSingleMessage provides a mock function with given fields: opts, message, offchainTokenData, tokenGasOverrides +func (_m *EVM2EVMOffRampInterface) ExecuteSingleMessage(opts *bind.TransactOpts, message evm_2_evm_offramp.InternalEVM2EVMMessage, offchainTokenData [][]byte, tokenGasOverrides []uint32) (*types.Transaction, error) { + ret := _m.Called(opts, message, offchainTokenData, tokenGasOverrides) if len(ret) == 0 { panic("no return value specified for ExecuteSingleMessage") @@ -250,19 +248,19 @@ func (_m *EVM2EVMOffRampInterface) ExecuteSingleMessage(opts *bind.TransactOpts, var r0 *types.Transaction var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalEVM2EVMMessage, [][]byte) (*types.Transaction, error)); ok { - return rf(opts, message, offchainTokenData) + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalEVM2EVMMessage, [][]byte, []uint32) (*types.Transaction, error)); ok { + return rf(opts, message, offchainTokenData, tokenGasOverrides) } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalEVM2EVMMessage, [][]byte) *types.Transaction); ok { - r0 = rf(opts, message, offchainTokenData) + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalEVM2EVMMessage, [][]byte, []uint32) *types.Transaction); ok { + r0 = rf(opts, message, offchainTokenData, tokenGasOverrides) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.Transaction) } } - if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalEVM2EVMMessage, [][]byte) error); ok { - r1 = rf(opts, message, offchainTokenData) + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalEVM2EVMMessage, [][]byte, []uint32) error); ok { + r1 = rf(opts, message, offchainTokenData, tokenGasOverrides) } else { r1 = ret.Error(1) } @@ -279,13 +277,14 @@ type EVM2EVMOffRampInterface_ExecuteSingleMessage_Call struct { // - opts *bind.TransactOpts // - message evm_2_evm_offramp.InternalEVM2EVMMessage // - offchainTokenData [][]byte -func (_e *EVM2EVMOffRampInterface_Expecter) ExecuteSingleMessage(opts interface{}, message interface{}, offchainTokenData interface{}) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { - return &EVM2EVMOffRampInterface_ExecuteSingleMessage_Call{Call: _e.mock.On("ExecuteSingleMessage", opts, message, offchainTokenData)} +// - tokenGasOverrides []uint32 +func (_e *EVM2EVMOffRampInterface_Expecter) ExecuteSingleMessage(opts interface{}, message interface{}, offchainTokenData interface{}, tokenGasOverrides interface{}) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { + return &EVM2EVMOffRampInterface_ExecuteSingleMessage_Call{Call: _e.mock.On("ExecuteSingleMessage", opts, message, offchainTokenData, tokenGasOverrides)} } -func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) Run(run func(opts *bind.TransactOpts, message evm_2_evm_offramp.InternalEVM2EVMMessage, offchainTokenData [][]byte)) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { +func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) Run(run func(opts *bind.TransactOpts, message evm_2_evm_offramp.InternalEVM2EVMMessage, offchainTokenData [][]byte, tokenGasOverrides []uint32)) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp.InternalEVM2EVMMessage), args[2].([][]byte)) + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp.InternalEVM2EVMMessage), args[2].([][]byte), args[3].([]uint32)) }) return _c } @@ -295,7 +294,7 @@ func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) Return(_a0 *types.T return _c } -func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp.InternalEVM2EVMMessage, [][]byte) (*types.Transaction, error)) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { +func (_c *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp.InternalEVM2EVMMessage, [][]byte, []uint32) (*types.Transaction, error)) *EVM2EVMOffRampInterface_ExecuteSingleMessage_Call { _c.Call.Return(run) return _c } @@ -1692,7 +1691,7 @@ func (_c *EVM2EVMOffRampInterface_LatestConfigDigestAndEpoch_Call) RunAndReturn( } // ManuallyExecute provides a mock function with given fields: opts, report, gasLimitOverrides -func (_m *EVM2EVMOffRampInterface) ManuallyExecute(opts *bind.TransactOpts, report evm_2_evm_offramp.InternalExecutionReport, gasLimitOverrides []*big.Int) (*types.Transaction, error) { +func (_m *EVM2EVMOffRampInterface) ManuallyExecute(opts *bind.TransactOpts, report evm_2_evm_offramp.InternalExecutionReport, gasLimitOverrides []evm_2_evm_offramp.EVM2EVMOffRampGasLimitOverride) (*types.Transaction, error) { ret := _m.Called(opts, report, gasLimitOverrides) if len(ret) == 0 { @@ -1701,10 +1700,10 @@ func (_m *EVM2EVMOffRampInterface) ManuallyExecute(opts *bind.TransactOpts, repo var r0 *types.Transaction var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalExecutionReport, []*big.Int) (*types.Transaction, error)); ok { + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalExecutionReport, []evm_2_evm_offramp.EVM2EVMOffRampGasLimitOverride) (*types.Transaction, error)); ok { return rf(opts, report, gasLimitOverrides) } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalExecutionReport, []*big.Int) *types.Transaction); ok { + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalExecutionReport, []evm_2_evm_offramp.EVM2EVMOffRampGasLimitOverride) *types.Transaction); ok { r0 = rf(opts, report, gasLimitOverrides) } else { if ret.Get(0) != nil { @@ -1712,7 +1711,7 @@ func (_m *EVM2EVMOffRampInterface) ManuallyExecute(opts *bind.TransactOpts, repo } } - if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalExecutionReport, []*big.Int) error); ok { + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, evm_2_evm_offramp.InternalExecutionReport, []evm_2_evm_offramp.EVM2EVMOffRampGasLimitOverride) error); ok { r1 = rf(opts, report, gasLimitOverrides) } else { r1 = ret.Error(1) @@ -1729,14 +1728,14 @@ type EVM2EVMOffRampInterface_ManuallyExecute_Call struct { // ManuallyExecute is a helper method to define mock.On call // - opts *bind.TransactOpts // - report evm_2_evm_offramp.InternalExecutionReport -// - gasLimitOverrides []*big.Int +// - gasLimitOverrides []evm_2_evm_offramp.EVM2EVMOffRampGasLimitOverride func (_e *EVM2EVMOffRampInterface_Expecter) ManuallyExecute(opts interface{}, report interface{}, gasLimitOverrides interface{}) *EVM2EVMOffRampInterface_ManuallyExecute_Call { return &EVM2EVMOffRampInterface_ManuallyExecute_Call{Call: _e.mock.On("ManuallyExecute", opts, report, gasLimitOverrides)} } -func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) Run(run func(opts *bind.TransactOpts, report evm_2_evm_offramp.InternalExecutionReport, gasLimitOverrides []*big.Int)) *EVM2EVMOffRampInterface_ManuallyExecute_Call { +func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) Run(run func(opts *bind.TransactOpts, report evm_2_evm_offramp.InternalExecutionReport, gasLimitOverrides []evm_2_evm_offramp.EVM2EVMOffRampGasLimitOverride)) *EVM2EVMOffRampInterface_ManuallyExecute_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp.InternalExecutionReport), args[2].([]*big.Int)) + run(args[0].(*bind.TransactOpts), args[1].(evm_2_evm_offramp.InternalExecutionReport), args[2].([]evm_2_evm_offramp.EVM2EVMOffRampGasLimitOverride)) }) return _c } @@ -1746,7 +1745,7 @@ func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) Return(_a0 *types.Transa return _c } -func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp.InternalExecutionReport, []*big.Int) (*types.Transaction, error)) *EVM2EVMOffRampInterface_ManuallyExecute_Call { +func (_c *EVM2EVMOffRampInterface_ManuallyExecute_Call) RunAndReturn(run func(*bind.TransactOpts, evm_2_evm_offramp.InternalExecutionReport, []evm_2_evm_offramp.EVM2EVMOffRampGasLimitOverride) (*types.Transaction, error)) *EVM2EVMOffRampInterface_ManuallyExecute_Call { _c.Call.Return(run) return _c } diff --git a/core/scripts/ccip/manual-execution/helpers/contractmodels.go b/core/scripts/ccip/manual-execution/helpers/contractmodels.go new file mode 100644 index 0000000000..000b32dd39 --- /dev/null +++ b/core/scripts/ccip/manual-execution/helpers/contractmodels.go @@ -0,0 +1,85 @@ +package helpers + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +type CommitStoreReportAccepted struct { + Report ICommitStoreCommitReport + Raw types.Log +} + +type ICommitStoreCommitReport struct { + PriceUpdates InternalPriceUpdates + Interval ICommitStoreInterval + MerkleRoot [32]byte +} + +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +type ICommitStoreInterval struct { + Min uint64 + Max uint64 +} + +type InternalEVM2EVMMessage struct { + SourceChainSelector uint64 + Sender common.Address + Receiver common.Address + SequenceNumber uint64 + GasLimit *big.Int + Strict bool + Nonce uint64 + FeeToken common.Address + FeeTokenAmount *big.Int + Data []byte + TokenAmounts []ClientEVMTokenAmount + SourceTokenData [][]byte + MessageId [32]byte +} + +type ClientEVMTokenAmount struct { + Token common.Address + Amount *big.Int +} + +type SendRequestedEvent struct { + Message InternalEVM2EVMMessage + Raw types.Log +} + +type InternalExecutionReport struct { + Messages []InternalEVM2EVMMessage + OffchainTokenData [][][]byte + Proofs [][32]byte + ProofFlagBits *big.Int +} + +type EVM2EVMOffRampExecutionStateChanged struct { + SequenceNumber uint64 + MessageId [32]byte + State uint8 + ReturnData []byte + Raw types.Log +} + +type EVM2EVMOffRampGasLimitOverride struct { + ReceiverExecutionGasLimit *big.Int + TokenGasOverrides []*big.Int +} diff --git a/core/scripts/ccip/manual-execution/helpers/contractwrappers.go b/core/scripts/ccip/manual-execution/helpers/contractwrappers.go new file mode 100644 index 0000000000..027577b912 --- /dev/null +++ b/core/scripts/ccip/manual-execution/helpers/contractwrappers.go @@ -0,0 +1,189 @@ +package helpers + +import ( + "fmt" + "strings" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/event" +) + +const ( + OffRampABI = "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"contractIERC20[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"contractIPool[]\",\"name\":\"pools\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getDestinationToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDestinationTokens\",\"outputs\":[{\"internalType\":\"contractIERC20[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"getPoolByDestToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"contractIERC20[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]" + CommitStoreABI = "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]" + OnRampABI = "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"tokensAndPools\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"}],\"name\":\"InvalidNopAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWithdrawParams\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkBalanceNotSettled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeeBalanceReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoFeesToPay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoNopsToPay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdminOrNop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyNops\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeConfig\",\"type\":\"tuple[]\"}],\"name\":\"FeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NopPaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nopWeightsTotal\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"NopsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"transferFeeConfig\",\"type\":\"tuple[]\"}],\"name\":\"TokenTransferFeeConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getFeeTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfig\",\"name\":\"feeTokenConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNopFeesJuels\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNops\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"weightsTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setFeeTokenConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setTokenTransferFeeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawNonLinkFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" +) + +func DecodeEvents( + ethC *ethclient.Client, + opts *bind.FilterOpts, + address, contractABI, eventName string, + query ...[]interface{}, +) (*bind.BoundContract, chan types.Log, event.Subscription, error) { + contractAddress := common.HexToAddress(address) + abi, err := abi.JSON(strings.NewReader(contractABI)) + if err != nil { + return nil, nil, nil, err + } + boundContract := bind.NewBoundContract(contractAddress, abi, ethC, ethC, ethC) + logs, subs, err := boundContract.FilterLogs(opts, eventName, query...) + if err != nil { + return nil, nil, nil, err + } + return boundContract, logs, subs, err +} + +type logIterator struct { + Raw types.Log + Contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *logIterator) Next() bool { + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *logIterator) Error() error { + return it.fail +} + +func (it *logIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +func FilterCCIPSendRequested(chain *ethclient.Client, opts *bind.FilterOpts, onRampAddr string) (*logIterator, error) { + onRampContract, logs, sub, err := DecodeEvents(chain, opts, onRampAddr, OnRampABI, "CCIPSendRequested") + if err != nil { + return nil, err + } + return &logIterator{ + Contract: onRampContract, + event: "CCIPSendRequested", + logs: logs, + sub: sub, + }, nil +} + +func (it *logIterator) SendRequestedEventFromLog() (*SendRequestedEvent, error) { + event := new(SendRequestedEvent) + err := it.Contract.UnpackLog(event, "CCIPSendRequested", it.Raw) + if err != nil { + return nil, err + } + return event, nil +} + +func (it *logIterator) CommitStoreReportAcceptedFromLog() (*CommitStoreReportAccepted, error) { + event := new(CommitStoreReportAccepted) + err := it.Contract.UnpackLog(event, "ReportAccepted", it.Raw) + if err != nil { + return nil, err + } + return event, nil +} + +func FilterReportAccepted(chain *ethclient.Client, opts *bind.FilterOpts, commitStoreAddr string) (*logIterator, error) { + commitStoreContract, logs, sub, err := DecodeEvents(chain, opts, commitStoreAddr, CommitStoreABI, "ReportAccepted") + if err != nil { + return nil, err + } + return &logIterator{ + Contract: commitStoreContract, + event: "ReportAccepted", + logs: logs, + sub: sub, + }, nil +} + +func FilterExecutionStateChanged( + chain *ethclient.Client, + opts *bind.FilterOpts, + offRampAddr string, + sequenceNumber []uint64, + messageId [][32]byte, +) (int, error) { + var sequenceNumberRule []interface{} + for _, sequenceNumberItem := range sequenceNumber { + sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) + } + var messageIdRule []interface{} + for _, messageIdItem := range messageId { + messageIdRule = append(messageIdRule, messageIdItem) + } + offRamp, logs, sub, err := DecodeEvents(chain, opts, offRampAddr, OffRampABI, "ExecutionStateChanged", sequenceNumberRule, messageIdRule) + if err != nil { + return 0, err + } + it := &logIterator{ + Contract: offRamp, + event: "ExecutionStateChanged", + logs: logs, + sub: sub, + } + + executionState := -1 + for it.Next() && executionState != 2 { + execStateEvent := new(EVM2EVMOffRampExecutionStateChanged) + err = it.Contract.UnpackLog(execStateEvent, "ExecutionStateChanged", it.Raw) + if err != nil { + return 0, err + } + executionState = int(execStateEvent.State) + } + + if executionState == -1 { + return 0, fmt.Errorf("no ExecutionStateChanged found for seq num %v and msg id %v", sequenceNumber, messageId) + } + return executionState, nil +} + +func ManuallyExecute( + ethC *ethclient.Client, + opts *bind.TransactOpts, + address string, + report InternalExecutionReport, + gasLimitOverrides []*EVM2EVMOffRampGasLimitOverride, +) (*types.Transaction, error) { + offRampContract := common.HexToAddress(address) + abi, err := abi.JSON(strings.NewReader(OffRampABI)) + if err != nil { + return nil, err + } + boundContract := bind.NewBoundContract(offRampContract, abi, ethC, ethC, ethC) + return boundContract.Transact(opts, "manuallyExecute", report, gasLimitOverrides) +} diff --git a/core/scripts/ccip/manual-execution/main.go b/core/scripts/ccip/manual-execution/main.go new file mode 100644 index 0000000000..ad86457e6b --- /dev/null +++ b/core/scripts/ccip/manual-execution/main.go @@ -0,0 +1,447 @@ +package main + +import ( + "context" + "encoding/hex" + "encoding/json" + "flag" + "fmt" + "log" + "math" + "math/big" + "os" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + chainselectors "github.com/smartcontractkit/chain-selectors" + "go.uber.org/multierr" + + "manual-execution/helpers" +) + +const NumberOfBlocks = 5000 + +// Config represents configuration fields +type Config struct { + SrcNodeURL string `json:"src_rpc"` + DestNodeURL string `json:"dest_rpc"` + DestOwner string `json:"dest_owner_key"` + CommitStore string `json:"commit_store"` + OffRamp string `json:"off_ramp"` + DestStartBlock uint64 `json:"dest_start_block"` + SourceChainTx string `json:"source_chain_tx"` + CCIPMsgID string `json:"ccip_msg_id"` + DestDeployedAt uint64 `json:"dest_deployed_at"` + GasLimitOverride uint64 `json:"gas_limit_override"` +} + +type execArgs struct { + cfg Config + seqNum uint64 + msgID [32]byte + sourceChain *ethclient.Client + sourceChainId *big.Int + destChain *ethclient.Client + destUser *bind.TransactOpts + destChainId *big.Int + srcStartBlock *big.Int + destStartBlock uint64 + destLatestBlock uint64 + OnRamp common.Address + tokenGasOverrides []*big.Int +} + +func main() { + configPath := flag.String("configFile", "./config.json", "config for manually executing a failed ccip message "+ + "which has been successfully committed but failed to get executed") + flag.Parse() + + if *configPath == "" { + log.Println("config json is required") + os.Exit(1) + } + cData, err := os.ReadFile(*configPath) + if err != nil { + log.Println("unable to read the json at ", *configPath, "error - ", err) + os.Exit(1) + } + var cfg Config + err = json.Unmarshal(cData, &cfg) + if err != nil { + log.Println("unable to marshal the json at ", *configPath, "error - ", err, `sample json +{ + "src_rpc": "", + "dest_rpc": "", + "dest_owner_key": "", + "commit_store": "", + "off_ramp": "", + "dest_start_block": "", + "ccip_send_tx": "", + "source_start_block": "", + "dest_deployed_at": 0, + "gas_limit_override": 0, +}`) + os.Exit(1) + } + // mandatory fields check + err = cfg.verifyConfig() + if err != nil { + log.Println("config validation failed: \n", err) + os.Exit(1) + } + args := &execArgs{cfg: cfg} + err = args.populateValues() + if err != nil { + log.Println("error instantiating manual execution args ", err) + os.Exit(1) + } + err = args.execute() + if err != nil { + log.Println("manual execution was not successful - ", err) + os.Exit(1) + } +} + +func (cfg Config) verifyConfig() error { + var allErr error + if cfg.SrcNodeURL == "" { + allErr = multierr.Append(allErr, fmt.Errorf("must set src_rpc - source chain rpc\n")) + } + if cfg.DestNodeURL == "" { + allErr = multierr.Append(allErr, fmt.Errorf("must set dest_rpc - destination chain rpc\n")) + } + if cfg.DestOwner == "" { + allErr = multierr.Append(allErr, fmt.Errorf("must set dest_owner_key - destination user private key\n")) + } + if cfg.SourceChainTx == "" { + allErr = multierr.Append(allErr, fmt.Errorf("must set source_chain_tx - txHash of ccip-send request\n")) + } + + if cfg.DestStartBlock == 0 && cfg.DestDeployedAt == 0 { + allErr = multierr.Append(allErr, fmt.Errorf(`must set either of - +dest_deployed_at - the block number before destination contracts were deployed; +dest_start_block - the block number from which events will be filtered at destination chain. +`)) + } + if cfg.GasLimitOverride == 0 { + allErr = multierr.Append(allErr, fmt.Errorf("must set gas_limit_override - new value of gas limit for ccip-send request\n")) + } + err := helpers.VerifyAddress(cfg.CommitStore) + if err != nil { + allErr = multierr.Append(allErr, fmt.Errorf("check the commit_store address - %v\n", err)) + } + err = helpers.VerifyAddress(cfg.OffRamp) + if err != nil { + allErr = multierr.Append(allErr, fmt.Errorf("check the off_ramp address - %v\n", err)) + } + + return allErr +} + +func (args *execArgs) populateValues() error { + var err error + cfg := args.cfg + args.sourceChain, err = ethclient.Dial(cfg.SrcNodeURL) + if err != nil { + return err + } + args.sourceChainId, err = args.sourceChain.ChainID(context.Background()) + if err != nil { + return err + } + + args.destChain, err = ethclient.Dial(cfg.DestNodeURL) + if err != nil { + return err + } + args.destChainId, err = args.destChain.ChainID(context.Background()) + if err != nil { + return err + } + ownerKey, err := crypto.HexToECDSA(cfg.DestOwner) + if err != nil { + return err + } + + args.destUser, err = bind.NewKeyedTransactorWithChainID(ownerKey, args.destChainId) + if err != nil { + return err + } + log.Println("--- Owner address---/n", args.destUser.From.Hex()) + + var txReceipt *types.Receipt + txReceipt, err = args.sourceChain.TransactionReceipt(context.Background(), common.HexToHash(cfg.SourceChainTx)) + if err != nil { + return err + } + args.srcStartBlock = big.NewInt(0).Sub(txReceipt.BlockNumber, big.NewInt(NumberOfBlocks)) + args.destLatestBlock, err = args.destChain.BlockNumber(context.Background()) + if err != nil { + return err + } + + err = args.seqNumFromCCIPSendRequested(txReceipt.Logs) + if err != nil { + return err + } + if args.cfg.DestStartBlock < 1 { + err = args.approxDestStartBlock() + if err != nil { + return err + } + } else { + args.destStartBlock = args.cfg.DestStartBlock + } + return nil +} + +func (args *execArgs) execute() error { + iterator, err := helpers.FilterReportAccepted(args.destChain, &bind.FilterOpts{Start: args.destStartBlock}, args.cfg.CommitStore) + if err != nil { + return err + } + + var commitReport *helpers.ICommitStoreCommitReport + for iterator.Next() { + eventReport, err := iterator.CommitStoreReportAcceptedFromLog() + if err != nil { + return err + } + + if eventReport.Report.Interval.Min <= args.seqNum && eventReport.Report.Interval.Max >= args.seqNum { + commitReport = &eventReport.Report + log.Println("Found root") + break + } + } + if commitReport == nil { + return fmt.Errorf("unable to find seq num %d in commit report", args.seqNum) + } + log.Println("Executing request manually") + seqNr := args.seqNum + // Build a merkle tree for the report + mctx := helpers.NewKeccakCtx() + leafHasher := helpers.NewLeafHasher( + GetCCIPChainSelector(args.sourceChainId.Uint64()), + GetCCIPChainSelector(args.destChainId.Uint64()), + args.OnRamp, + mctx, + ) + + var leaves [][32]byte + var curr, prove int + var tokenData [][][]byte + var msgs []helpers.InternalEVM2EVMMessage + + sendRequestedIterator, err := helpers.FilterCCIPSendRequested(args.sourceChain, &bind.FilterOpts{ + Start: args.srcStartBlock.Uint64(), + }, args.OnRamp.Hex()) + if err != nil { + return err + } + + for sendRequestedIterator.Next() { + event, err := sendRequestedIterator.SendRequestedEventFromLog() + if err != nil { + return err + } + if event.Message.SequenceNumber <= commitReport.Interval.Max && + event.Message.SequenceNumber >= commitReport.Interval.Min { + log.Println("Found seq num in commit report", event.Message.SequenceNumber, commitReport.Interval) + hash, err := leafHasher.HashLeaf(sendRequestedIterator.Raw) + if err != nil { + return err + } + leaves = append(leaves, hash) + if event.Message.SequenceNumber == seqNr && event.Message.MessageId == args.msgID { + log.Printf("Found proving %d %+v\n\n", curr, event.Message) + msgs = append(msgs, event.Message) + + var msgTokenData [][]byte + for range event.Message.TokenAmounts { + msgTokenData = append(msgTokenData, []byte{}) + } + + tokenData = append(tokenData, msgTokenData) + prove = curr + } + curr++ + } + } + + sendRequestedIterator.Close() + if len(msgs) == 0 { + return fmt.Errorf("unable to find msg with seqNr %d", seqNr) + } + + expectedNumberOfLeaves := int(commitReport.Interval.Max) - int(commitReport.Interval.Min) + 1 + if len(leaves) != expectedNumberOfLeaves { + return fmt.Errorf("not enough leaves gather to build a commit root - want %d got %d. Please set NumberOfBlocks const to a higher value", expectedNumberOfLeaves, len(leaves)) + } + + tree, err := helpers.NewTree(mctx, leaves) + if err != nil { + return err + } + if tree.Root() != commitReport.MerkleRoot { + return fmt.Errorf("root doesn't match. cannot execute") + } + + proof := tree.Prove([]int{prove}) + offRampProof := helpers.InternalExecutionReport{ + Messages: msgs, + Proofs: proof.Hashes, + OffchainTokenData: tokenData, + ProofFlagBits: helpers.ProofFlagsToBits(proof.SourceFlags), + } + + gasLimitOverrides := make([]*helpers.EVM2EVMOffRampGasLimitOverride, len(offRampProof.Messages)) + + for range offRampProof.Messages { + evm2evmOffRampGasLimitOverride := &helpers.EVM2EVMOffRampGasLimitOverride{ + ReceiverExecutionGasLimit: big.NewInt(int64(args.cfg.GasLimitOverride)), + TokenGasOverrides: args.tokenGasOverrides, + } + gasLimitOverrides = append(gasLimitOverrides, evm2evmOffRampGasLimitOverride) + } + + tx, err := helpers.ManuallyExecute(args.destChain, args.destUser, args.cfg.OffRamp, offRampProof, gasLimitOverrides) + if err != nil { + return err + } + // wait for tx confirmation + err = helpers.WaitForSuccessfulTxReceipt(args.destChain, tx.Hash()) + if err != nil { + return err + } + + // check if the message got successfully delivered + changed, err := helpers.FilterExecutionStateChanged(args.destChain, &bind.FilterOpts{ + Start: args.destStartBlock, + }, args.cfg.OffRamp, []uint64{args.seqNum}, [][32]byte{args.msgID}) + if err != nil { + return err + } + if changed != 2 { + return fmt.Errorf("manual execution did not result in ExecutionStateChanged as success") + } + return nil +} + +func (args *execArgs) seqNumFromCCIPSendRequested(logs []*types.Log) error { + abi, err := abi.JSON(strings.NewReader(helpers.OnRampABI)) + if err != nil { + return err + } + var topic0 common.Hash + for name, abiEvent := range abi.Events { + if name == "CCIPSendRequested" { + topic0 = abiEvent.ID + break + } + } + if topic0 == (common.Hash{}) { + return fmt.Errorf("no CCIPSendRequested event found in ABI") + } + var sendRequestedLogs []types.Log + for _, sendReqLog := range logs { + if sendReqLog.Topics[0] == topic0 && sendReqLog.TxHash == common.HexToHash(args.cfg.SourceChainTx) { + args.OnRamp = sendReqLog.Address + sendRequestedLogs = append(sendRequestedLogs, *sendReqLog) + } + } + + if len(sendRequestedLogs) == 0 { + return fmt.Errorf("no CCIPSendRequested logs found for in txReceipt for txhash %s", args.cfg.SourceChainTx) + } + onRampContract := bind.NewBoundContract(args.OnRamp, abi, args.sourceChain, args.sourceChain, args.sourceChain) + + for _, sendReqLog := range sendRequestedLogs { + var event helpers.SendRequestedEvent + + err = onRampContract.UnpackLog(&event, "CCIPSendRequested", sendReqLog) + if err != nil { + return err + } + + if args.cfg.CCIPMsgID != "" && + "0x"+hex.EncodeToString(event.Message.MessageId[:]) != args.cfg.CCIPMsgID { + continue + } + + args.seqNum = event.Message.SequenceNumber + args.msgID = event.Message.MessageId + return nil + } + + return fmt.Errorf("send request not found in logs") +} + +func (args *execArgs) approxDestStartBlock() error { + sourceBlockHdr, err := args.sourceChain.HeaderByNumber(context.Background(), args.srcStartBlock) + if err != nil { + return err + } + sendTxTime := sourceBlockHdr.Time + maxBlockNum := args.destLatestBlock + // setting this to an approx value of 1000 considering destination chain would have at least 1000 blocks before the transaction started + minBlockNum := args.cfg.DestDeployedAt + closestBlockNum := uint64(math.Floor((float64(maxBlockNum) + float64(minBlockNum)) / 2)) + var closestBlockHdr *types.Header + closestBlockHdr, err = args.destChain.HeaderByNumber(context.Background(), big.NewInt(int64(closestBlockNum))) + if err != nil { + return err + } + // to reduce the number of RPC calls increase the value of blockOffset + blockOffset := uint64(10) + for { + blockNum := closestBlockHdr.Number.Uint64() + if minBlockNum > maxBlockNum { + break + } + timeDiff := math.Abs(float64(closestBlockHdr.Time - sendTxTime)) + // break if the difference in timestamp is lesser than 1 minute + if timeDiff < 60 { + break + } else if closestBlockHdr.Time > sendTxTime { + maxBlockNum = blockNum - 1 + } else { + minBlockNum = blockNum + 1 + } + closestBlockNum = uint64(math.Floor((float64(maxBlockNum) + float64(minBlockNum)) / 2)) + closestBlockHdr, err = args.destChain.HeaderByNumber(context.Background(), big.NewInt(int64(closestBlockNum))) + if err != nil { + return err + } + } + + for { + if closestBlockHdr.Time <= sendTxTime { + break + } + closestBlockNum = closestBlockNum - blockOffset + if closestBlockNum <= 0 { + return fmt.Errorf("approx destination blocknumber not found") + } + closestBlockHdr, err = args.destChain.HeaderByNumber(context.Background(), big.NewInt(int64(closestBlockNum))) + if err != nil { + return err + } + } + args.destStartBlock = closestBlockHdr.Number.Uint64() + log.Printf("using approx destination start block number %d for filtering event", args.destStartBlock) + return nil +} + +func GetCCIPChainSelector(chainId uint64) uint64 { + selector, err := chainselectors.SelectorFromChainId(chainId) + if err != nil { + panic(fmt.Sprintf("no chain selector for %d", chainId)) + } + return selector +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go index 1f745df9d5..194c977ea8 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -1267,13 +1267,14 @@ type ManualExecArgs struct { DestDeployedAt uint64 // destination block number for the initial destination contract deployment. // Can be any number before the tx was reverted in destination chain. Preferably this needs to be set up with // a value greater than zero to avoid performance issue in locating approximate destination block - SendReqLogIndex uint // log index of the CCIPSendRequested log in source chain - SendReqTxHash string // tx hash of the ccip-send transaction for which execution was reverted - CommitStore string - OnRamp string - OffRamp string - SeqNr uint64 - GasLimit *big.Int + SendReqLogIndex uint // log index of the CCIPSendRequested log in source chain + SendReqTxHash string // tx hash of the ccip-send transaction for which execution was reverted + CommitStore string + OnRamp string + OffRamp string + SeqNr uint64 + GasLimit *big.Int + TokenGasOverrides []uint32 } // ApproxDestStartBlock attempts to locate a block in destination chain with timestamp closest to the timestamp of the block @@ -1436,7 +1437,9 @@ func (args *ManualExecArgs) execute(report *commit_store.CommitStoreCommitReport var leaves [][32]byte var curr, prove int var msgs []evm_2_evm_offramp.InternalEVM2EVMMessage - var manualExecGasLimits []*big.Int + + // CCIP-2950 TestHelper for CCIPContracts and initialisation of EVM2EVMOffRampGasLimitOverride + var manualExecGasLimits []*evm_2_evm_offramp.EVM2EVMOffRampGasLimitOverride var tokenData [][][]byte sendRequestedIterator, err := onRampContract.FilterCCIPSendRequested(&bind.FilterOpts{ Start: args.SourceStartBlock.Uint64(), @@ -1481,7 +1484,26 @@ func (args *ManualExecArgs) execute(report *commit_store.CommitStoreCommitReport if args.GasLimit != nil { msg.GasLimit = args.GasLimit } - manualExecGasLimits = append(manualExecGasLimits, msg.GasLimit) + + tokenGasOverrides := make([]uint32, len(msg.TokenAmounts)) + + if args.TokenGasOverrides != nil && len(args.TokenGasOverrides) == len(msg.TokenAmounts) { + copy(tokenGasOverrides, args.TokenGasOverrides) + } else { + // Initialize each element in the slice to a new big.Int value in one line using a loop + for i := range tokenGasOverrides { + tokenGasOverrides[i] = 0 + } + } + + // CCIP-2950 create a new object for evm_2_evm_offramp.EVM2EVMOffRampGasLimitOverride + evm2evmOffRampGasLimitOverride := &evm_2_evm_offramp.EVM2EVMOffRampGasLimitOverride{ + ReceiverExecutionGasLimit: msg.GasLimit, + TokenGasOverrides: tokenGasOverrides, + } + + manualExecGasLimits = append(manualExecGasLimits, evm2evmOffRampGasLimitOverride) + var msgTokenData [][]byte for range sendRequestedIterator.Event.Message.TokenAmounts { msgTokenData = append(msgTokenData, []byte{}) @@ -1520,8 +1542,17 @@ func (args *ManualExecArgs) execute(report *commit_store.CommitStoreCommitReport if err != nil { return nil, err } + + // Convert manualExecGasLimits to a slice of structs before calling ManuallyExecute + manualExecGasLimitOverrides := make([]evm_2_evm_offramp.EVM2EVMOffRampGasLimitOverride, len(manualExecGasLimits)) + for i, limitOverride := range manualExecGasLimits { + if limitOverride != nil { + manualExecGasLimitOverrides[i] = *limitOverride + } + } + // Execute. - return offRamp.ManuallyExecute(args.DestUser, offRampProof, manualExecGasLimits) + return offRamp.ManuallyExecute(args.DestUser, offRampProof, manualExecGasLimitOverrides) } func (c *CCIPContracts) ExecuteMessage( From 9eae858afff7ac3637ee9693ffe2af8dbfbd0a2b Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Fri, 9 Aug 2024 13:12:24 +0200 Subject: [PATCH 199/432] bump version to 1.5 (#1263) Final release of all 1.5 contracts - don't merge before the other PRs are all in TODO - #1258 - #1256 - #1273 --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/gas-snapshots/ccip.gas-snapshot | 18 +- contracts/src/v0.8/ccip/CommitStore.sol | 2 +- .../v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 1 - .../src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol | 3 +- .../src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol | 2 +- .../v0.8/ccip/pools/BurnFromMintTokenPool.sol | 2 +- .../src/v0.8/ccip/pools/BurnMintTokenPool.sol | 2 +- .../ccip/pools/BurnMintTokenPoolAndProxy.sol | 2 +- .../ccip/pools/BurnWithFromMintTokenPool.sol | 2 +- .../v0.8/ccip/pools/LockReleaseTokenPool.sol | 2 +- .../pools/LockReleaseTokenPoolAndProxy.sol | 2 +- .../ccip/test/commitStore/CommitStore.t.sol | 2 +- .../ccip/test/offRamp/EVM2EVMOffRamp.t.sol | 2 +- .../v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol | 2 +- .../test/pools/BurnFromMintTokenPool.t.sol | 2 +- .../ccip/test/pools/BurnMintTokenPool.t.sol | 2 +- .../pools/BurnWithFromMintTokenPool.t.sol | 2 +- .../RegistryModuleOwnerCustom.sol | 2 +- .../tokenAdminRegistry/TokenAdminRegistry.sol | 4 +- .../burn_from_mint_token_pool.go | 2 +- .../burn_mint_token_pool.go | 2 +- .../burn_mint_token_pool_and_proxy.go | 2 +- .../burn_with_from_mint_token_pool.go | 2 +- .../generated/commit_store/commit_store.go | 2 +- .../commit_store_helper.go | 2 +- .../evm_2_evm_multi_offramp.go | 2 +- .../evm_2_evm_offramp/evm_2_evm_offramp.go | 4 +- .../evm_2_evm_onramp/evm_2_evm_onramp.go | 2 +- .../lock_release_token_pool.go | 2 +- .../lock_release_token_pool_and_proxy.go | 2 +- .../registry_module_owner_custom.go | 2 +- .../token_admin_registry.go | 273 +----------------- ...rapper-dependency-versions-do-not-edit.txt | 26 +- .../internal/ccipdata/offramp_reader_test.go | 4 +- .../plugins/ccip/internal/ccipdata/reader.go | 2 +- .../ccip-tests/contracts/contract_deployer.go | 2 +- .../ccip-tests/contracts/contract_models.go | 2 +- 37 files changed, 59 insertions(+), 332 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index c734ea9831..a2a322e545 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -22,7 +22,7 @@ AggregateTokenLimiter_setRateLimiterConfig:test_TokenLimitAdmin_Success() (gas: BurnFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28761) BurnFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) BurnFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243491) -BurnFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 23951) +BurnFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 23947) BurnMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 27522) BurnMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) BurnMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 241381) @@ -33,7 +33,7 @@ BurnMintTokenPool_releaseOrMint:test_PoolMint_Success() (gas: 112319) BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28761) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243517) -BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 24304) +BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 23951) CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2132747) CCIPConfigSetup:test_getCapabilityConfiguration_Success() (gas: 9517) CCIPConfig_ConfigStateMachine:test__computeConfigDigest_Success() (gas: 70831) @@ -502,8 +502,8 @@ EtherSenderReceiverTest_validatedMessage:test_validatedMessage_tokenOverwrittenT EtherSenderReceiverTest_validatedMessage:test_validatedMessage_validMessage_extraArgs() (gas: 26292) LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Revert() (gas: 10992) LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Success() (gas: 18058) -LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3360094) -LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3356493) +LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3359294) +LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3355693) LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_Unauthorized_Revert() (gas: 11380) LockReleaseTokenPoolPoolAndProxy_supportsInterface:test_SupportsInterface_Success() (gas: 9977) LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60043) @@ -835,7 +835,7 @@ RateLimiter_consume:test_TokenRateLimitReached_Revert() (gas: 24706) RateLimiter_currentTokenBucketState:test_CurrentTokenBucketState_Success() (gas: 38647) RateLimiter_currentTokenBucketState:test_Refill_Success() (gas: 46384) RateLimiter_setTokenBucketConfig:test_SetRateLimiterConfig_Success() (gas: 38017) -RegistryModuleOwnerCustom_constructor:test_constructor_Revert() (gas: 36031) +RegistryModuleOwnerCustom_constructor:test_constructor_Revert() (gas: 36028) RegistryModuleOwnerCustom_registerAdminViaGetCCIPAdmin:test_registerAdminViaGetCCIPAdmin_Revert() (gas: 19637) RegistryModuleOwnerCustom_registerAdminViaGetCCIPAdmin:test_registerAdminViaGetCCIPAdmin_Success() (gas: 129918) RegistryModuleOwnerCustom_registerAdminViaOwner:test_registerAdminViaOwner_Revert() (gas: 19451) @@ -900,10 +900,10 @@ TokenAdminRegistry_setPool:test_setPool_Success() (gas: 35943) TokenAdminRegistry_setPool:test_setPool_ZeroAddressRemovesPool_Success() (gas: 30617) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_OnlyAdministrator_Revert() (gas: 18043) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_Success() (gas: 49390) -TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6066750) -TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6311731) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6910329) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7094420) +TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6064542) +TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6310931) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6908121) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7092212) TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2209837) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12089) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23324) diff --git a/contracts/src/v0.8/ccip/CommitStore.sol b/contracts/src/v0.8/ccip/CommitStore.sol index 27388b6dcc..77c2864d4f 100644 --- a/contracts/src/v0.8/ccip/CommitStore.sol +++ b/contracts/src/v0.8/ccip/CommitStore.sol @@ -59,7 +59,7 @@ contract CommitStore is ICommitStore, ITypeAndVersion, OCR2Base { } // STATIC CONFIG - string public constant override typeAndVersion = "CommitStore 1.5.0-dev"; + string public constant override typeAndVersion = "CommitStore 1.5.0"; // Chain ID of this chain uint64 internal immutable i_chainSelector; // Chain ID of the source chain diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol index 7807e3b4d8..250bec4428 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -33,7 +33,6 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { using ERC165Checker for address; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; - error AlreadyExecuted(uint64 sourceChainSelector, uint64 sequenceNumber); error ZeroChainSelectorNotAllowed(); error ExecutionError(bytes32 messageId, bytes err); error SourceChainNotEnabled(uint64 sourceChainSelector); diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol index 15b66ae107..1856cd5423 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol @@ -34,7 +34,6 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio using ERC165Checker for address; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; - error AlreadyExecuted(uint64 sequenceNumber); error ZeroAddressNotAllowed(); error CommitStoreAlreadyInUse(); error ExecutionError(bytes err); @@ -112,7 +111,7 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio } // STATIC CONFIG - string public constant override typeAndVersion = "EVM2EVMOffRamp 1.5.0-dev"; + string public constant override typeAndVersion = "EVM2EVMOffRamp 1.5.0"; /// @dev Commit store address on the destination chain address internal immutable i_commitStore; diff --git a/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol b/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol index 45dfdacd30..50df00712d 100644 --- a/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol @@ -149,7 +149,7 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, } // STATIC CONFIG - string public constant override typeAndVersion = "EVM2EVMOnRamp 1.5.0-dev"; + string public constant override typeAndVersion = "EVM2EVMOnRamp 1.5.0"; /// @dev metadataHash is a lane-specific prefix for a message hash preimage which ensures global uniqueness /// Ensures that 2 identical messages sent to 2 different lanes will have a distinct hash. /// Must match the metadataHash used in computing leaf hashes offchain for the root committed in diff --git a/contracts/src/v0.8/ccip/pools/BurnFromMintTokenPool.sol b/contracts/src/v0.8/ccip/pools/BurnFromMintTokenPool.sol index de68b18a30..4ea6664a5c 100644 --- a/contracts/src/v0.8/ccip/pools/BurnFromMintTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/BurnFromMintTokenPool.sol @@ -18,7 +18,7 @@ import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/tok contract BurnFromMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion { using SafeERC20 for IBurnMintERC20; - string public constant override typeAndVersion = "BurnFromMintTokenPool 1.5.0-dev"; + string public constant override typeAndVersion = "BurnFromMintTokenPool 1.5.0"; constructor( IBurnMintERC20 token, diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol index a8562ae4d3..c48c8e51fb 100644 --- a/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol @@ -14,7 +14,7 @@ import {TokenPool} from "./TokenPool.sol"; /// If that is expected, please make sure the token's burner/minter roles are adjustable. /// @dev This contract is a variant of BurnMintTokenPool that uses `burn(amount)`. contract BurnMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion { - string public constant override typeAndVersion = "BurnMintTokenPool 1.5.0-dev"; + string public constant override typeAndVersion = "BurnMintTokenPool 1.5.0"; constructor( IBurnMintERC20 token, diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol index 07cb01dc76..6ca8b7d6a0 100644 --- a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol @@ -8,7 +8,7 @@ import {Pool} from "../libraries/Pool.sol"; import {LegacyPoolWrapper} from "./LegacyPoolWrapper.sol"; contract BurnMintTokenPoolAndProxy is ITypeAndVersion, LegacyPoolWrapper { - string public constant override typeAndVersion = "BurnMintTokenPoolAndProxy 1.5.0-dev"; + string public constant override typeAndVersion = "BurnMintTokenPoolAndProxy 1.5.0"; constructor( IBurnMintERC20 token, diff --git a/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol b/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol index 33f6c43c5b..56e0ab1b25 100644 --- a/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol @@ -18,7 +18,7 @@ import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/tok contract BurnWithFromMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion { using SafeERC20 for IBurnMintERC20; - string public constant override typeAndVersion = "BurnWithFromMintTokenPool 1.5.0-dev"; + string public constant override typeAndVersion = "BurnWithFromMintTokenPool 1.5.0"; constructor( IBurnMintERC20 token, diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol index a01173b869..bc451f435a 100644 --- a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol @@ -22,7 +22,7 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion event LiquidityTransferred(address indexed from, uint256 amount); - string public constant override typeAndVersion = "LockReleaseTokenPool 1.5.0-dev"; + string public constant override typeAndVersion = "LockReleaseTokenPool 1.5.0"; /// @dev Whether or not the pool accepts liquidity. /// External liquidity is not required when there is one canonical token deployed to a chain, diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol index 45aab70a98..af79e821b8 100644 --- a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol @@ -20,7 +20,7 @@ contract LockReleaseTokenPoolAndProxy is LegacyPoolWrapper, ILiquidityContainer, error InsufficientLiquidity(); error LiquidityNotAccepted(); - string public constant override typeAndVersion = "LockReleaseTokenPoolAndProxy 1.5.0-dev"; + string public constant override typeAndVersion = "LockReleaseTokenPoolAndProxy 1.5.0"; /// @dev Whether or not the pool accepts liquidity. /// External liquidity is not required when there is one canonical token deployed to a chain, diff --git a/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol b/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol index 7598f9ccb6..8c5e745f43 100644 --- a/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol +++ b/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol @@ -113,7 +113,7 @@ contract CommitStore_constructor is PriceRegistrySetup, OCR2BaseSetup { // CommitStore initial values assertEq(0, commitStore.getLatestPriceEpochAndRound()); assertEq(1, commitStore.getExpectedNextSequenceNumber()); - assertEq(commitStore.typeAndVersion(), "CommitStore 1.5.0-dev"); + assertEq(commitStore.typeAndVersion(), "CommitStore 1.5.0"); assertEq(OWNER, commitStore.owner()); assertTrue(commitStore.isUnpausedAndNotCursed()); } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol index 70c7e38bfe..167ac83330 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol @@ -71,7 +71,7 @@ contract EVM2EVMOffRamp_constructor is EVM2EVMOffRampSetup { assertEq(block.number, blockNumber); // OffRamp initial values - assertEq("EVM2EVMOffRamp 1.5.0-dev", s_offRamp.typeAndVersion()); + assertEq("EVM2EVMOffRamp 1.5.0", s_offRamp.typeAndVersion()); assertEq(OWNER, s_offRamp.owner()); } diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol index a30ecc9130..8559122be7 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol @@ -59,7 +59,7 @@ contract EVM2EVMOnRamp_constructor is EVM2EVMOnRampSetup { assertEq(dynamicConfig.maxPerMsgGasLimit, gotDynamicConfig.maxPerMsgGasLimit); // Initial values - assertEq("EVM2EVMOnRamp 1.5.0-dev", s_onRamp.typeAndVersion()); + assertEq("EVM2EVMOnRamp 1.5.0", s_onRamp.typeAndVersion()); assertEq(OWNER, s_onRamp.owner()); assertEq(1, s_onRamp.getExpectedNextSequenceNumber()); } diff --git a/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool.t.sol index 290c4ae153..307cbf21f4 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool.t.sol @@ -29,7 +29,7 @@ contract BurnFromMintTokenPool_lockOrBurn is BurnFromMintTokenPoolSetup { assertEq(address(s_mockRMN), s_pool.getRmnProxy()); assertEq(false, s_pool.getAllowListEnabled()); assertEq(type(uint256).max, s_burnMintERC677.allowance(address(s_pool), address(s_pool))); - assertEq("BurnFromMintTokenPool 1.5.0-dev", s_pool.typeAndVersion()); + assertEq("BurnFromMintTokenPool 1.5.0", s_pool.typeAndVersion()); } function test_PoolBurn_Success() public { diff --git a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol index a6c4a60dc5..5a7644d033 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol @@ -32,7 +32,7 @@ contract BurnMintTokenPool_lockOrBurn is BurnMintTokenPoolSetup { assertEq(address(s_burnMintERC677), address(s_pool.getToken())); assertEq(address(s_mockRMN), s_pool.getRmnProxy()); assertEq(false, s_pool.getAllowListEnabled()); - assertEq("BurnMintTokenPool 1.5.0-dev", s_pool.typeAndVersion()); + assertEq("BurnMintTokenPool 1.5.0", s_pool.typeAndVersion()); } function test_PoolBurn_Success() public { diff --git a/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool.t.sol index 22362ee4a5..568aac6ba1 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool.t.sol @@ -30,7 +30,7 @@ contract BurnWithFromMintTokenPool_lockOrBurn is BurnWithFromMintTokenPoolSetup assertEq(address(s_mockRMN), s_pool.getRmnProxy()); assertEq(false, s_pool.getAllowListEnabled()); assertEq(type(uint256).max, s_burnMintERC677.allowance(address(s_pool), address(s_pool))); - assertEq("BurnWithFromMintTokenPool 1.5.0-dev", s_pool.typeAndVersion()); + assertEq("BurnWithFromMintTokenPool 1.5.0", s_pool.typeAndVersion()); } function test_PoolBurn_Success() public { diff --git a/contracts/src/v0.8/ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol b/contracts/src/v0.8/ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol index 3cd17df05f..a794d68c9e 100644 --- a/contracts/src/v0.8/ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol +++ b/contracts/src/v0.8/ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol @@ -12,7 +12,7 @@ contract RegistryModuleOwnerCustom is ITypeAndVersion { event AdministratorRegistered(address indexed token, address indexed administrator); - string public constant override typeAndVersion = "RegistryModuleOwnerCustom 1.5.0-dev"; + string public constant override typeAndVersion = "RegistryModuleOwnerCustom 1.5.0"; // The TokenAdminRegistry contract ITokenAdminRegistry internal immutable i_tokenAdminRegistry; diff --git a/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenAdminRegistry.sol b/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenAdminRegistry.sol index 32394a396e..2d1a406736 100644 --- a/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenAdminRegistry.sol +++ b/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenAdminRegistry.sol @@ -26,8 +26,6 @@ contract TokenAdminRegistry is ITokenAdminRegistry, ITypeAndVersion, OwnerIsCrea event PoolSet(address indexed token, address indexed previousPool, address indexed newPool); event AdministratorTransferRequested(address indexed token, address indexed currentAdmin, address indexed newAdmin); event AdministratorTransferred(address indexed token, address indexed newAdmin); - event DisableReRegistrationSet(address indexed token, bool disabled); - event RemovedAdministrator(address token); event RegistryModuleAdded(address module); event RegistryModuleRemoved(address indexed module); @@ -39,7 +37,7 @@ contract TokenAdminRegistry is ITokenAdminRegistry, ITypeAndVersion, OwnerIsCrea address tokenPool; // the token pool for this token. Can be address(0) if not deployed or not configured. } - string public constant override typeAndVersion = "TokenAdminRegistry 1.5.0-dev"; + string public constant override typeAndVersion = "TokenAdminRegistry 1.5.0"; // Mapping of token address to token configuration mapping(address token => TokenConfig) internal s_tokenConfig; diff --git a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go index c0e0b87fe7..caea3cec11 100644 --- a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnFromMintTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b506040516200450b3803806200450b8339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161399262000b79600039600081816104dd01528181611777015261215b0152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b45015281816120f1015261234601526139926000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae9565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b48565b6105f9565b6040516101d29190612bc7565b6101ee6040518060400160405280601f81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e302d6465760081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c07565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c24565b6106a9565b604051905181526020016101d2565b6103006102fb366004612cac565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d18565b6108aa565b610300610a1e565b610300610349366004612c07565b610b1b565b6101c661035c366004612b48565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d9b565b610b81565b6040516101d29190612dd6565b6103a7610c28565b6040516101d29190612e36565b6103c76103c2366004612b48565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b48565b610d0e565b610300610462366004612c07565b610d39565b61046f610e14565b6040516101d29190612e90565b6103c761048a366004612b48565b610ecc565b61030061049d366004612ff8565b610f9e565b6103006104b036600461303d565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c07565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061307f565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361317d565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c07565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c07565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109299061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546109559061307f565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132c2565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133dc565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba183613440565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b48565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb9565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc6565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061307f565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb9565b90506000815167ffffffffffffffff811115610e4057610e40612ed2565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134e2565b6020026020010151828281518110610ea457610ea46134e2565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc6565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c78565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134e2565b90506020028101906110609190613511565b6110699061354f565b905061107e8160800151826020015115611d62565b6110918160a00151826020015115611d62565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e9b565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906113259082613603565b506060820151600582019061133a9082613603565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c29550611380949392919061371d565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea7565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a9b565b611461600583016000612a9b565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611eb3565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b6565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa8565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc7565b6116ee826020015183606001516120ce565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134e2565b6020026020010151905061180a81600261211590919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134e2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612137565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b6565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612159565b611afe81602001516121d8565b6114be81602001518260600151612326565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015611b9e57600080fd5b505af1158015611bb2573d6000803e3d6000fd5b5050505050565b6060600061193f8361236a565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c5482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c389190613802565b85608001516fffffffffffffffffffffffffffffffff166123c5565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c8183610b6a565b611cc3576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cce826000611d62565b67ffffffffffffffff83166000908152600760205260409020611cf190836123ef565b611cfc816000611d62565b67ffffffffffffffff83166000908152600760205260409020611d2290600201826123ef565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d5593929190613815565b60405180910390a1505050565b815115611e295781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db8575060408201516fffffffffffffffffffffffffffffffff16155b15611df157816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e62575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b600061193f8383612591565b600061193f83836125e0565b3373ffffffffffffffffffffffffffffffffffffffff821603611f32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fb181610b6a565b611ff3576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612072573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209691906137b6565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126d3565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125e0565b600061193f8373ffffffffffffffffffffffffffffffffffffffff8416612591565b7f0000000000000000000000000000000000000000000000000000000000000000156114be5761218a600282612a56565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121e181610b6a565b612223576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c091906138d4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126d3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a65750505050509050919050565b60006123e4856123d584866138f1565b6123df9087613908565b612a85565b90505b949350505050565b815460009061241890700100000000000000000000000000000000900463ffffffff1642613802565b905080156124ba5760018301548354612460916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123c5565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124e0916fffffffffffffffffffffffffffffffff9081169116612a85565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d55908490613898565b60008181526001830160205260408120546125d8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c9576000612604600183613802565b855490915060009061261890600190613802565b905081811461267d576000866000018281548110612638576126386134e2565b906000526020600020015490508087600001848154811061265b5761265b6134e2565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268e5761268e61391b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126fa575081155b1561270457505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274a90700100000000000000000000000000000000900463ffffffff1642613802565b9050801561280a578183111561278c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c69083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123c5565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128c15773ffffffffffffffffffffffffffffffffffffffff8416612869576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129d45760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906129059082613802565b61290f878a613802565b6129199190613908565b612923919061394a565b905073ffffffffffffffffffffffffffffffffffffffff861661297c576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129de8584613802565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a94578161193f565b5090919050565b508054612aa79061307f565b6000825580601f10612ab7575050565b601f0160209004906000526020600020908101906114be91905b80821115612ae55760008155600101612ad1565b5090565b600060208284031215612afb57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b4357600080fd5b919050565b600060208284031215612b5a57600080fd5b61193f82612b2b565b6000815180845260005b81811015612b8957602081850181015186830182015201612b6d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b63565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b4381612bda565b600060208284031215612c1957600080fd5b813561193f81612bda565b600060208284031215612c3657600080fd5b813567ffffffffffffffff811115612c4d57600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c7257600080fd5b50813567ffffffffffffffff811115612c8a57600080fd5b6020830191508360208260051b8501011115612ca557600080fd5b9250929050565b60008060008060408587031215612cc257600080fd5b843567ffffffffffffffff80821115612cda57600080fd5b612ce688838901612c60565b90965094506020870135915080821115612cff57600080fd5b50612d0c87828801612c60565b95989497509550505050565b600080600060408486031215612d2d57600080fd5b612d3684612b2b565b9250602084013567ffffffffffffffff80821115612d5357600080fd5b818601915086601f830112612d6757600080fd5b813581811115612d7657600080fd5b876020828501011115612d8857600080fd5b6020830194508093505050509250925092565b600060208284031215612dad57600080fd5b813567ffffffffffffffff811115612dc457600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612df26060840182612b63565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e2d8282612b63565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e52565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835167ffffffffffffffff1683529284019291840191600101612eac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f2557612f25612ed2565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f2557612f25612ed2565b80151581146114be57600080fd5b8035612b4381612f4e565b80356fffffffffffffffffffffffffffffffff81168114612b4357600080fd5b600060608284031215612f9957600080fd5b6040516060810181811067ffffffffffffffff82111715612fbc57612fbc612ed2565b6040529050808235612fcd81612f4e565b8152612fdb60208401612f67565b6020820152612fec60408401612f67565b60408201525092915050565b600080600060e0848603121561300d57600080fd5b61301684612b2b565b92506130258560208601612f87565b91506130348560808601612f87565b90509250925092565b6000806020838503121561305057600080fd5b823567ffffffffffffffff81111561306757600080fd5b61307385828601612c60565b90969095509350505050565b600181811c9082168061309357607f821691505b6020821081036130cc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130e357600080fd5b813567ffffffffffffffff808211156130fe576130fe612ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561314457613144612ed2565b8160405283815286602085880101111561315d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561319057600080fd5b613198612f01565b823567ffffffffffffffff808211156131b057600080fd5b6131bc368387016130d2565b83526131ca60208601612b2b565b60208401526131db60408601612bfc565b6040840152606085013560608401526131f660808601612bfc565b608084015260a085013591508082111561320f57600080fd5b61321b368387016130d2565b60a084015260c085013591508082111561323457600080fd5b613240368387016130d2565b60c084015260e085013591508082111561325957600080fd5b50613266368286016130d2565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c8101602086101561329b5750805b601f850160051c820191505b818110156132ba578281556001016132a7565b505050505050565b67ffffffffffffffff8311156132da576132da612ed2565b6132ee836132e8835461307f565b83613272565b6000601f841160018114613340576000851561330a5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bb2565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561338f578685013582556020948501946001909201910161336f565b50868210156133ca577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133ef6040830186612b63565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561345257600080fd5b60405160a0810167ffffffffffffffff828210818311171561347657613476612ed2565b81604052843591508082111561348b57600080fd5b50613498368286016130d2565b8252506134a760208401612b2b565b602082015260408301356134ba81612bda565b60408201526060838101359082015260808301356134d781612bda565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261354557600080fd5b9190910192915050565b6000610140823603121561356257600080fd5b61356a612f2b565b61357383612b2b565b815261358160208401612f5c565b6020820152604083013567ffffffffffffffff808211156135a157600080fd5b6135ad368387016130d2565b604084015260608501359150808211156135c657600080fd5b506135d3368286016130d2565b6060830152506135e63660808501612f87565b60808201526135f83660e08501612f87565b60a082015292915050565b815167ffffffffffffffff81111561361d5761361d612ed2565b6136318161362b845461307f565b84613272565b602080601f831160018114613684576000841561364e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132ba565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136d1578886015182559484019460019091019084016136b2565b508582101561370d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261374181840187612b63565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061377f9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e2d565b6000602082840312156137c857600080fd5b815161193f81612f4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137d3565b67ffffffffffffffff8416815260e0810161386160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e7565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e657600080fd5b815161193f81612bda565b80820281158282048414176105f3576105f36137d3565b808201808211156105f3576105f36137d3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613980577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b506040516200450b3803806200450b8339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161399262000b79600039600081816104dd01528181611777015261215b0152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b45015281816120f1015261234601526139926000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae9565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b48565b6105f9565b6040516101d29190612bc7565b6101ee6040518060400160405280601b81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e30000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c07565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c24565b6106a9565b604051905181526020016101d2565b6103006102fb366004612cac565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d18565b6108aa565b610300610a1e565b610300610349366004612c07565b610b1b565b6101c661035c366004612b48565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d9b565b610b81565b6040516101d29190612dd6565b6103a7610c28565b6040516101d29190612e36565b6103c76103c2366004612b48565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b48565b610d0e565b610300610462366004612c07565b610d39565b61046f610e14565b6040516101d29190612e90565b6103c761048a366004612b48565b610ecc565b61030061049d366004612ff8565b610f9e565b6103006104b036600461303d565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c07565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061307f565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361317d565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c07565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c07565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109299061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546109559061307f565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132c2565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133dc565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba183613440565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b48565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb9565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc6565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061307f565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb9565b90506000815167ffffffffffffffff811115610e4057610e40612ed2565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134e2565b6020026020010151828281518110610ea457610ea46134e2565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc6565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c78565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134e2565b90506020028101906110609190613511565b6110699061354f565b905061107e8160800151826020015115611d62565b6110918160a00151826020015115611d62565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e9b565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906113259082613603565b506060820151600582019061133a9082613603565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c29550611380949392919061371d565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea7565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a9b565b611461600583016000612a9b565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611eb3565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b6565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa8565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc7565b6116ee826020015183606001516120ce565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134e2565b6020026020010151905061180a81600261211590919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134e2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612137565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b6565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612159565b611afe81602001516121d8565b6114be81602001518260600151612326565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015611b9e57600080fd5b505af1158015611bb2573d6000803e3d6000fd5b5050505050565b6060600061193f8361236a565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c5482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c389190613802565b85608001516fffffffffffffffffffffffffffffffff166123c5565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c8183610b6a565b611cc3576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cce826000611d62565b67ffffffffffffffff83166000908152600760205260409020611cf190836123ef565b611cfc816000611d62565b67ffffffffffffffff83166000908152600760205260409020611d2290600201826123ef565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d5593929190613815565b60405180910390a1505050565b815115611e295781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db8575060408201516fffffffffffffffffffffffffffffffff16155b15611df157816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e62575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b600061193f8383612591565b600061193f83836125e0565b3373ffffffffffffffffffffffffffffffffffffffff821603611f32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fb181610b6a565b611ff3576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612072573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209691906137b6565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126d3565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125e0565b600061193f8373ffffffffffffffffffffffffffffffffffffffff8416612591565b7f0000000000000000000000000000000000000000000000000000000000000000156114be5761218a600282612a56565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121e181610b6a565b612223576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c091906138d4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126d3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a65750505050509050919050565b60006123e4856123d584866138f1565b6123df9087613908565b612a85565b90505b949350505050565b815460009061241890700100000000000000000000000000000000900463ffffffff1642613802565b905080156124ba5760018301548354612460916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123c5565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124e0916fffffffffffffffffffffffffffffffff9081169116612a85565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d55908490613898565b60008181526001830160205260408120546125d8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c9576000612604600183613802565b855490915060009061261890600190613802565b905081811461267d576000866000018281548110612638576126386134e2565b906000526020600020015490508087600001848154811061265b5761265b6134e2565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268e5761268e61391b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126fa575081155b1561270457505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274a90700100000000000000000000000000000000900463ffffffff1642613802565b9050801561280a578183111561278c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c69083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123c5565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128c15773ffffffffffffffffffffffffffffffffffffffff8416612869576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129d45760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906129059082613802565b61290f878a613802565b6129199190613908565b612923919061394a565b905073ffffffffffffffffffffffffffffffffffffffff861661297c576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129de8584613802565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a94578161193f565b5090919050565b508054612aa79061307f565b6000825580601f10612ab7575050565b601f0160209004906000526020600020908101906114be91905b80821115612ae55760008155600101612ad1565b5090565b600060208284031215612afb57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b4357600080fd5b919050565b600060208284031215612b5a57600080fd5b61193f82612b2b565b6000815180845260005b81811015612b8957602081850181015186830182015201612b6d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b63565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b4381612bda565b600060208284031215612c1957600080fd5b813561193f81612bda565b600060208284031215612c3657600080fd5b813567ffffffffffffffff811115612c4d57600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c7257600080fd5b50813567ffffffffffffffff811115612c8a57600080fd5b6020830191508360208260051b8501011115612ca557600080fd5b9250929050565b60008060008060408587031215612cc257600080fd5b843567ffffffffffffffff80821115612cda57600080fd5b612ce688838901612c60565b90965094506020870135915080821115612cff57600080fd5b50612d0c87828801612c60565b95989497509550505050565b600080600060408486031215612d2d57600080fd5b612d3684612b2b565b9250602084013567ffffffffffffffff80821115612d5357600080fd5b818601915086601f830112612d6757600080fd5b813581811115612d7657600080fd5b876020828501011115612d8857600080fd5b6020830194508093505050509250925092565b600060208284031215612dad57600080fd5b813567ffffffffffffffff811115612dc457600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612df26060840182612b63565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e2d8282612b63565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e52565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835167ffffffffffffffff1683529284019291840191600101612eac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f2557612f25612ed2565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f2557612f25612ed2565b80151581146114be57600080fd5b8035612b4381612f4e565b80356fffffffffffffffffffffffffffffffff81168114612b4357600080fd5b600060608284031215612f9957600080fd5b6040516060810181811067ffffffffffffffff82111715612fbc57612fbc612ed2565b6040529050808235612fcd81612f4e565b8152612fdb60208401612f67565b6020820152612fec60408401612f67565b60408201525092915050565b600080600060e0848603121561300d57600080fd5b61301684612b2b565b92506130258560208601612f87565b91506130348560808601612f87565b90509250925092565b6000806020838503121561305057600080fd5b823567ffffffffffffffff81111561306757600080fd5b61307385828601612c60565b90969095509350505050565b600181811c9082168061309357607f821691505b6020821081036130cc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130e357600080fd5b813567ffffffffffffffff808211156130fe576130fe612ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561314457613144612ed2565b8160405283815286602085880101111561315d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561319057600080fd5b613198612f01565b823567ffffffffffffffff808211156131b057600080fd5b6131bc368387016130d2565b83526131ca60208601612b2b565b60208401526131db60408601612bfc565b6040840152606085013560608401526131f660808601612bfc565b608084015260a085013591508082111561320f57600080fd5b61321b368387016130d2565b60a084015260c085013591508082111561323457600080fd5b613240368387016130d2565b60c084015260e085013591508082111561325957600080fd5b50613266368286016130d2565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c8101602086101561329b5750805b601f850160051c820191505b818110156132ba578281556001016132a7565b505050505050565b67ffffffffffffffff8311156132da576132da612ed2565b6132ee836132e8835461307f565b83613272565b6000601f841160018114613340576000851561330a5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bb2565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561338f578685013582556020948501946001909201910161336f565b50868210156133ca577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133ef6040830186612b63565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561345257600080fd5b60405160a0810167ffffffffffffffff828210818311171561347657613476612ed2565b81604052843591508082111561348b57600080fd5b50613498368286016130d2565b8252506134a760208401612b2b565b602082015260408301356134ba81612bda565b60408201526060838101359082015260808301356134d781612bda565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261354557600080fd5b9190910192915050565b6000610140823603121561356257600080fd5b61356a612f2b565b61357383612b2b565b815261358160208401612f5c565b6020820152604083013567ffffffffffffffff808211156135a157600080fd5b6135ad368387016130d2565b604084015260608501359150808211156135c657600080fd5b506135d3368286016130d2565b6060830152506135e63660808501612f87565b60808201526135f83660e08501612f87565b60a082015292915050565b815167ffffffffffffffff81111561361d5761361d612ed2565b6136318161362b845461307f565b84613272565b602080601f831160018114613684576000841561364e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132ba565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136d1578886015182559484019460019091019084016136b2565b508582101561370d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261374181840187612b63565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061377f9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e2d565b6000602082840312156137c857600080fd5b815161193f81612f4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137d3565b67ffffffffffffffff8416815260e0810161386160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e7565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e657600080fd5b815161193f81612bda565b80820281158282048414176105f3576105f36137d3565b808201808211156105f3576105f36137d3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613980577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var BurnFromMintTokenPoolABI = BurnFromMintTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go index 2a4f18f6fb..c07e6e059e 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnMintTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620040b3380380620040b383398101604081905262000034916200054c565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000176565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001685760408051600081526020810190915262000168908462000221565b5050505050505050620006aa565b336001600160a01b03821603620001d05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000242576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002cd5760008382815181106200026657620002666200065c565b60209081029190910101519050620002806002826200037e565b15620002c3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000245565b5060005b815181101562000379576000828281518110620002f257620002f26200065c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200031e575062000370565b6200032b6002826200039e565b156200036e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d1565b505050565b600062000395836001600160a01b038416620003b5565b90505b92915050565b600062000395836001600160a01b038416620004b9565b60008181526001830160205260408120548015620004ae576000620003dc60018362000672565b8554909150600090620003f29060019062000672565b90508181146200045e5760008660000182815481106200041657620004166200065c565b90600052602060002001549050808760000184815481106200043c576200043c6200065c565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000472576200047262000694565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000398565b600091505062000398565b6000818152600183016020526040812054620005025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000398565b50600062000398565b6001600160a01b03811681146200052157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000547816200050b565b919050565b600080600080608085870312156200056357600080fd5b845162000570816200050b565b602086810151919550906001600160401b03808211156200059057600080fd5b818801915088601f830112620005a557600080fd5b815181811115620005ba57620005ba62000524565b8060051b604051601f19603f83011681018181108582111715620005e257620005e262000524565b60405291825284820192508381018501918b8311156200060157600080fd5b938501935b828510156200062a576200061a856200053a565b8452938501939285019262000606565b80985050505050505062000641604086016200053a565b915062000651606086016200053a565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161398c62000727600039600081816104dd0152818161177701526121550152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b3f015281816120eb0152612340015261398c6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae3565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b42565b6105f9565b6040516101d29190612bc1565b6101ee6040518060400160405280601b81526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e302d646576000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c01565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c1e565b6106a9565b604051905181526020016101d2565b6103006102fb366004612ca6565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d12565b6108aa565b610300610a1e565b610300610349366004612c01565b610b1b565b6101c661035c366004612b42565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d95565b610b81565b6040516101d29190612dd0565b6103a7610c28565b6040516101d29190612e30565b6103c76103c2366004612b42565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b42565b610d0e565b610300610462366004612c01565b610d39565b61046f610e14565b6040516101d29190612e8a565b6103c761048a366004612b42565b610ecc565b61030061049d366004612ff2565b610f9e565b6103006104b0366004613037565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c01565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061062490613079565b80601f016020809104026020016040519081016040528092919081815260200182805461065090613079565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c483613177565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c01565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c01565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461092990613079565b80601f016020809104026020016040519081016040528092919081815260200182805461095590613079565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132bc565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133d6565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba18361343a565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b42565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb3565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc0565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061062490613079565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb3565b90506000815167ffffffffffffffff811115610e4057610e40612ecc565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134dc565b6020026020010151828281518110610ea457610ea46134dc565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc0565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c72565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134dc565b9050602002810190611060919061350b565b61106990613549565b905061107e8160800151826020015115611d5c565b6110918160a00151826020015115611d5c565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e95565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061132590826135fd565b506060820151600582019061133a90826135fd565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506113809493929190613717565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea1565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a95565b611461600583016000612a95565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611ead565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b0565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa2565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc1565b6116ee826020015183606001516120c8565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134dc565b6020026020010151905061180a81600261210f90919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134dc565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612131565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b0565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612153565b611afe81602001516121d2565b6114be81602001518260600151612320565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611b9857600080fd5b505af1158015611bac573d6000803e3d6000fd5b5050505050565b6060600061193f83612364565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c4e82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c3291906137fc565b85608001516fffffffffffffffffffffffffffffffff166123bf565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c7b83610b6a565b611cbd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cc8826000611d5c565b67ffffffffffffffff83166000908152600760205260409020611ceb90836123e9565b611cf6816000611d5c565b67ffffffffffffffff83166000908152600760205260409020611d1c90600201826123e9565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d4f9392919061380f565b60405180910390a1505050565b815115611e235781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db2575060408201516fffffffffffffffffffffffffffffffff16155b15611deb57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613892565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e5c575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613892565b600061193f838361258b565b600061193f83836125da565b3373ffffffffffffffffffffffffffffffffffffffff821603611f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fab81610b6a565b611fed576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561206c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209091906137b0565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126cd565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125da565b600061193f8373ffffffffffffffffffffffffffffffffffffffff841661258b565b7f0000000000000000000000000000000000000000000000000000000000000000156114be57612184600282612a50565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121db81610b6a565b61221d576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ba91906138ce565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126cd565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a05750505050509050919050565b60006123de856123cf84866138eb565b6123d99087613902565b612a7f565b90505b949350505050565b815460009061241290700100000000000000000000000000000000900463ffffffff16426137fc565b905080156124b4576001830154835461245a916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123bf565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124da916fffffffffffffffffffffffffffffffff9081169116612a7f565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d4f908490613892565b60008181526001830160205260408120546125d2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c35760006125fe6001836137fc565b8554909150600090612612906001906137fc565b9050818114612677576000866000018281548110612632576126326134dc565b9060005260206000200154905080876000018481548110612655576126556134dc565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268857612688613915565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126f4575081155b156126fe57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274490700100000000000000000000000000000000900463ffffffff16426137fc565b905080156128045781831115612786576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c09083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123bf565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128bb5773ffffffffffffffffffffffffffffffffffffffff8416612863576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129ce5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128ff90826137fc565b612909878a6137fc565b6129139190613902565b61291d9190613944565b905073ffffffffffffffffffffffffffffffffffffffff8616612976576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129d885846137fc565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a8e578161193f565b5090919050565b508054612aa190613079565b6000825580601f10612ab1575050565b601f0160209004906000526020600020908101906114be91905b80821115612adf5760008155600101612acb565b5090565b600060208284031215612af557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b3d57600080fd5b919050565b600060208284031215612b5457600080fd5b61193f82612b25565b6000815180845260005b81811015612b8357602081850181015186830182015201612b67565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b5d565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b3d81612bd4565b600060208284031215612c1357600080fd5b813561193f81612bd4565b600060208284031215612c3057600080fd5b813567ffffffffffffffff811115612c4757600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c6c57600080fd5b50813567ffffffffffffffff811115612c8457600080fd5b6020830191508360208260051b8501011115612c9f57600080fd5b9250929050565b60008060008060408587031215612cbc57600080fd5b843567ffffffffffffffff80821115612cd457600080fd5b612ce088838901612c5a565b90965094506020870135915080821115612cf957600080fd5b50612d0687828801612c5a565b95989497509550505050565b600080600060408486031215612d2757600080fd5b612d3084612b25565b9250602084013567ffffffffffffffff80821115612d4d57600080fd5b818601915086601f830112612d6157600080fd5b813581811115612d7057600080fd5b876020828501011115612d8257600080fd5b6020830194508093505050509250925092565b600060208284031215612da757600080fd5b813567ffffffffffffffff811115612dbe57600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612dec6060840182612b5d565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e278282612b5d565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e7e57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e4c565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e7e57835167ffffffffffffffff1683529284019291840191600101612ea6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f1f57612f1f612ecc565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f1f57612f1f612ecc565b80151581146114be57600080fd5b8035612b3d81612f48565b80356fffffffffffffffffffffffffffffffff81168114612b3d57600080fd5b600060608284031215612f9357600080fd5b6040516060810181811067ffffffffffffffff82111715612fb657612fb6612ecc565b6040529050808235612fc781612f48565b8152612fd560208401612f61565b6020820152612fe660408401612f61565b60408201525092915050565b600080600060e0848603121561300757600080fd5b61301084612b25565b925061301f8560208601612f81565b915061302e8560808601612f81565b90509250925092565b6000806020838503121561304a57600080fd5b823567ffffffffffffffff81111561306157600080fd5b61306d85828601612c5a565b90969095509350505050565b600181811c9082168061308d57607f821691505b6020821081036130c6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130dd57600080fd5b813567ffffffffffffffff808211156130f8576130f8612ecc565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561313e5761313e612ecc565b8160405283815286602085880101111561315757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561318a57600080fd5b613192612efb565b823567ffffffffffffffff808211156131aa57600080fd5b6131b6368387016130cc565b83526131c460208601612b25565b60208401526131d560408601612bf6565b6040840152606085013560608401526131f060808601612bf6565b608084015260a085013591508082111561320957600080fd5b613215368387016130cc565b60a084015260c085013591508082111561322e57600080fd5b61323a368387016130cc565b60c084015260e085013591508082111561325357600080fd5b50613260368286016130cc565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c810160208610156132955750805b601f850160051c820191505b818110156132b4578281556001016132a1565b505050505050565b67ffffffffffffffff8311156132d4576132d4612ecc565b6132e8836132e28354613079565b8361326c565b6000601f84116001811461333a57600085156133045750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bac565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156133895786850135825560209485019460019092019101613369565b50868210156133c4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133e96040830186612b5d565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561344c57600080fd5b60405160a0810167ffffffffffffffff828210818311171561347057613470612ecc565b81604052843591508082111561348557600080fd5b50613492368286016130cc565b8252506134a160208401612b25565b602082015260408301356134b481612bd4565b60408201526060838101359082015260808301356134d181612bd4565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261353f57600080fd5b9190910192915050565b6000610140823603121561355c57600080fd5b613564612f25565b61356d83612b25565b815261357b60208401612f56565b6020820152604083013567ffffffffffffffff8082111561359b57600080fd5b6135a7368387016130cc565b604084015260608501359150808211156135c057600080fd5b506135cd368286016130cc565b6060830152506135e03660808501612f81565b60808201526135f23660e08501612f81565b60a082015292915050565b815167ffffffffffffffff81111561361757613617612ecc565b61362b816136258454613079565b8461326c565b602080601f83116001811461367e57600084156136485750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132b4565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136cb578886015182559484019460019091019084016136ac565b508582101561370757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261373b81840187612b5d565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506137799050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e27565b6000602082840312156137c257600080fd5b815161193f81612f48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137cd565b67ffffffffffffffff8416815260e0810161385b60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e1565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e057600080fd5b815161193f81612bd4565b80820281158282048414176105f3576105f36137cd565b808201808211156105f3576105f36137cd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261397a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b50604051620040b3380380620040b383398101604081905262000034916200054c565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000176565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001685760408051600081526020810190915262000168908462000221565b5050505050505050620006aa565b336001600160a01b03821603620001d05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000242576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002cd5760008382815181106200026657620002666200065c565b60209081029190910101519050620002806002826200037e565b15620002c3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000245565b5060005b815181101562000379576000828281518110620002f257620002f26200065c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200031e575062000370565b6200032b6002826200039e565b156200036e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d1565b505050565b600062000395836001600160a01b038416620003b5565b90505b92915050565b600062000395836001600160a01b038416620004b9565b60008181526001830160205260408120548015620004ae576000620003dc60018362000672565b8554909150600090620003f29060019062000672565b90508181146200045e5760008660000182815481106200041657620004166200065c565b90600052602060002001549050808760000184815481106200043c576200043c6200065c565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000472576200047262000694565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000398565b600091505062000398565b6000818152600183016020526040812054620005025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000398565b50600062000398565b6001600160a01b03811681146200052157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000547816200050b565b919050565b600080600080608085870312156200056357600080fd5b845162000570816200050b565b602086810151919550906001600160401b03808211156200059057600080fd5b818801915088601f830112620005a557600080fd5b815181811115620005ba57620005ba62000524565b8060051b604051601f19603f83011681018181108582111715620005e257620005e262000524565b60405291825284820192508381018501918b8311156200060157600080fd5b938501935b828510156200062a576200061a856200053a565b8452938501939285019262000606565b80985050505050505062000641604086016200053a565b915062000651606086016200053a565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161398c62000727600039600081816104dd0152818161177701526121550152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b3f015281816120eb0152612340015261398c6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae3565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b42565b6105f9565b6040516101d29190612bc1565b6101ee6040518060400160405280601781526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e3000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c01565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c1e565b6106a9565b604051905181526020016101d2565b6103006102fb366004612ca6565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d12565b6108aa565b610300610a1e565b610300610349366004612c01565b610b1b565b6101c661035c366004612b42565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d95565b610b81565b6040516101d29190612dd0565b6103a7610c28565b6040516101d29190612e30565b6103c76103c2366004612b42565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b42565b610d0e565b610300610462366004612c01565b610d39565b61046f610e14565b6040516101d29190612e8a565b6103c761048a366004612b42565b610ecc565b61030061049d366004612ff2565b610f9e565b6103006104b0366004613037565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c01565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061062490613079565b80601f016020809104026020016040519081016040528092919081815260200182805461065090613079565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c483613177565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c01565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c01565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461092990613079565b80601f016020809104026020016040519081016040528092919081815260200182805461095590613079565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132bc565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133d6565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba18361343a565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b42565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb3565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc0565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061062490613079565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb3565b90506000815167ffffffffffffffff811115610e4057610e40612ecc565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134dc565b6020026020010151828281518110610ea457610ea46134dc565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc0565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c72565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134dc565b9050602002810190611060919061350b565b61106990613549565b905061107e8160800151826020015115611d5c565b6110918160a00151826020015115611d5c565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e95565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061132590826135fd565b506060820151600582019061133a90826135fd565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506113809493929190613717565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea1565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a95565b611461600583016000612a95565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611ead565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b0565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa2565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc1565b6116ee826020015183606001516120c8565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134dc565b6020026020010151905061180a81600261210f90919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134dc565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612131565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b0565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612153565b611afe81602001516121d2565b6114be81602001518260600151612320565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611b9857600080fd5b505af1158015611bac573d6000803e3d6000fd5b5050505050565b6060600061193f83612364565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c4e82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c3291906137fc565b85608001516fffffffffffffffffffffffffffffffff166123bf565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c7b83610b6a565b611cbd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cc8826000611d5c565b67ffffffffffffffff83166000908152600760205260409020611ceb90836123e9565b611cf6816000611d5c565b67ffffffffffffffff83166000908152600760205260409020611d1c90600201826123e9565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d4f9392919061380f565b60405180910390a1505050565b815115611e235781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db2575060408201516fffffffffffffffffffffffffffffffff16155b15611deb57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613892565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e5c575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613892565b600061193f838361258b565b600061193f83836125da565b3373ffffffffffffffffffffffffffffffffffffffff821603611f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fab81610b6a565b611fed576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561206c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209091906137b0565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126cd565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125da565b600061193f8373ffffffffffffffffffffffffffffffffffffffff841661258b565b7f0000000000000000000000000000000000000000000000000000000000000000156114be57612184600282612a50565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121db81610b6a565b61221d576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ba91906138ce565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126cd565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a05750505050509050919050565b60006123de856123cf84866138eb565b6123d99087613902565b612a7f565b90505b949350505050565b815460009061241290700100000000000000000000000000000000900463ffffffff16426137fc565b905080156124b4576001830154835461245a916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123bf565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124da916fffffffffffffffffffffffffffffffff9081169116612a7f565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d4f908490613892565b60008181526001830160205260408120546125d2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c35760006125fe6001836137fc565b8554909150600090612612906001906137fc565b9050818114612677576000866000018281548110612632576126326134dc565b9060005260206000200154905080876000018481548110612655576126556134dc565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268857612688613915565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126f4575081155b156126fe57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274490700100000000000000000000000000000000900463ffffffff16426137fc565b905080156128045781831115612786576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c09083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123bf565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128bb5773ffffffffffffffffffffffffffffffffffffffff8416612863576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129ce5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128ff90826137fc565b612909878a6137fc565b6129139190613902565b61291d9190613944565b905073ffffffffffffffffffffffffffffffffffffffff8616612976576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129d885846137fc565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a8e578161193f565b5090919050565b508054612aa190613079565b6000825580601f10612ab1575050565b601f0160209004906000526020600020908101906114be91905b80821115612adf5760008155600101612acb565b5090565b600060208284031215612af557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b3d57600080fd5b919050565b600060208284031215612b5457600080fd5b61193f82612b25565b6000815180845260005b81811015612b8357602081850181015186830182015201612b67565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b5d565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b3d81612bd4565b600060208284031215612c1357600080fd5b813561193f81612bd4565b600060208284031215612c3057600080fd5b813567ffffffffffffffff811115612c4757600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c6c57600080fd5b50813567ffffffffffffffff811115612c8457600080fd5b6020830191508360208260051b8501011115612c9f57600080fd5b9250929050565b60008060008060408587031215612cbc57600080fd5b843567ffffffffffffffff80821115612cd457600080fd5b612ce088838901612c5a565b90965094506020870135915080821115612cf957600080fd5b50612d0687828801612c5a565b95989497509550505050565b600080600060408486031215612d2757600080fd5b612d3084612b25565b9250602084013567ffffffffffffffff80821115612d4d57600080fd5b818601915086601f830112612d6157600080fd5b813581811115612d7057600080fd5b876020828501011115612d8257600080fd5b6020830194508093505050509250925092565b600060208284031215612da757600080fd5b813567ffffffffffffffff811115612dbe57600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612dec6060840182612b5d565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e278282612b5d565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e7e57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e4c565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e7e57835167ffffffffffffffff1683529284019291840191600101612ea6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f1f57612f1f612ecc565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f1f57612f1f612ecc565b80151581146114be57600080fd5b8035612b3d81612f48565b80356fffffffffffffffffffffffffffffffff81168114612b3d57600080fd5b600060608284031215612f9357600080fd5b6040516060810181811067ffffffffffffffff82111715612fb657612fb6612ecc565b6040529050808235612fc781612f48565b8152612fd560208401612f61565b6020820152612fe660408401612f61565b60408201525092915050565b600080600060e0848603121561300757600080fd5b61301084612b25565b925061301f8560208601612f81565b915061302e8560808601612f81565b90509250925092565b6000806020838503121561304a57600080fd5b823567ffffffffffffffff81111561306157600080fd5b61306d85828601612c5a565b90969095509350505050565b600181811c9082168061308d57607f821691505b6020821081036130c6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130dd57600080fd5b813567ffffffffffffffff808211156130f8576130f8612ecc565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561313e5761313e612ecc565b8160405283815286602085880101111561315757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561318a57600080fd5b613192612efb565b823567ffffffffffffffff808211156131aa57600080fd5b6131b6368387016130cc565b83526131c460208601612b25565b60208401526131d560408601612bf6565b6040840152606085013560608401526131f060808601612bf6565b608084015260a085013591508082111561320957600080fd5b613215368387016130cc565b60a084015260c085013591508082111561322e57600080fd5b61323a368387016130cc565b60c084015260e085013591508082111561325357600080fd5b50613260368286016130cc565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c810160208610156132955750805b601f850160051c820191505b818110156132b4578281556001016132a1565b505050505050565b67ffffffffffffffff8311156132d4576132d4612ecc565b6132e8836132e28354613079565b8361326c565b6000601f84116001811461333a57600085156133045750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bac565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156133895786850135825560209485019460019092019101613369565b50868210156133c4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133e96040830186612b5d565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561344c57600080fd5b60405160a0810167ffffffffffffffff828210818311171561347057613470612ecc565b81604052843591508082111561348557600080fd5b50613492368286016130cc565b8252506134a160208401612b25565b602082015260408301356134b481612bd4565b60408201526060838101359082015260808301356134d181612bd4565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261353f57600080fd5b9190910192915050565b6000610140823603121561355c57600080fd5b613564612f25565b61356d83612b25565b815261357b60208401612f56565b6020820152604083013567ffffffffffffffff8082111561359b57600080fd5b6135a7368387016130cc565b604084015260608501359150808211156135c057600080fd5b506135cd368286016130cc565b6060830152506135e03660808501612f81565b60808201526135f23660e08501612f81565b60a082015292915050565b815167ffffffffffffffff81111561361757613617612ecc565b61362b816136258454613079565b8461326c565b602080601f83116001811461367e57600084156136485750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132b4565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136cb578886015182559484019460019091019084016136ac565b508582101561370757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261373b81840187612b5d565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506137799050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e27565b6000602082840312156137c257600080fd5b815161193f81612f48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137cd565b67ffffffffffffffff8416815260e0810161385b60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e1565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e057600080fd5b815161193f81612bd4565b80820281158282048414176105f3576105f36137cd565b808201808211156105f3576105f36137cd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261397a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var BurnMintTokenPoolABI = BurnMintTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go index 8361ea5c86..901f745dbb 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnMintTokenPoolAndProxyMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b506040516200495538038062004955833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050818114620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161421f620007366000396000818161050301528181611aa701526124f90152600081816104dd0152818161183a0152611d5a0152600081816102260152818161027b0152818161073f01528181610dc50152818161175a01528181611c7a01528181611e600152818161248f01526126e4015261421f6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639766b93211610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104c8578063dc0bd971146104db578063e0351e1314610501578063f2fde38b1461052757600080fd5b8063c0d786551461047a578063c4bffe2b1461048d578063c75eea9c146104a2578063cf7401f3146104b557600080fd5b8063a8d87a3b116100de578063a8d87a3b146103c7578063af58d59f146103da578063b0f479a114610449578063b79465801461046757600080fd5b80639766b9321461037f5780639a4575b914610392578063a7cd63b7146103b257600080fd5b80636d3d1a58116101715780637d54534e1161014b5780637d54534e1461032857806383826b2b1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b80636d3d1a58146102ef57806378a010b21461030d57806379ba50971461032057600080fd5b806321df0da7116101ad57806321df0da714610224578063240028e81461026b57806339077537146102b857806354c8a4f3146102da57600080fd5b806301ffc9a7146101d45780630a2fd493146101fc578063181f5a771461021c575b600080fd5b6101e76101e2366004613191565b61053a565b60405190151581526020015b60405180910390f35b61020f61020a3660046131f0565b61061f565b6040516101f39190613279565b61020f6106cf565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e76102793660046132b9565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102cb6102c63660046132d6565b6106eb565b604051905181526020016101f3565b6102ed6102e836600461335e565b6108a3565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61031b3660046133ca565b61091e565b6102ed610a92565b6102ed6103363660046132b9565b610b8f565b6101e761034936600461344d565b610bde565b6101e761035c3660046131f0565b610cab565b60005473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61038d3660046132b9565b610cc2565b6103a56103a0366004613484565b610d51565b6040516101f391906134bf565b6103ba610ec1565b6040516101f3919061351f565b6102466103d53660046131f0565b503090565b6103ed6103e83660046131f0565b610ed2565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610246565b61020f6104753660046131f0565b610fa7565b6102ed6104883660046132b9565b610fd2565b6104956110a6565b6040516101f39190613579565b6103ed6104b03660046131f0565b61115e565b6102ed6104c3366004613730565b611230565b6102ed6104d6366004613775565b6112b9565b7f0000000000000000000000000000000000000000000000000000000000000000610246565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b6102ed6105353660046132b9565b61173f565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105cd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061061957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061064a906137b7565b80601f0160208091040260200160405190810160405280929190818152602001828054610676906137b7565b80156106c35780601f10610698576101008083540402835291602001916106c3565b820191906000526020600020905b8154815290600101906020018083116106a657829003601f168201915b50505050509050919050565b6040518060600160405280602381526020016141f06023913981565b60408051602081019091526000815261070b610706836138a6565b611753565b60095473ffffffffffffffffffffffffffffffffffffffff166108015773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961077460608501604086016132b9565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b1580156107e457600080fd5b505af11580156107f8573d6000803e3d6000fd5b50505050610812565b61081261080d836138a6565b611984565b61082260608301604084016132b9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161088491815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108ab611a22565b61091884848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611aa592505050565b50505050565b610926611a22565b61092f83610cab565b610976576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461099d906137b7565b80601f01602080910402602001604051908101604052809291908181526020018280546109c9906137b7565b8015610a165780601f106109eb57610100808354040283529160200191610a16565b820191906000526020600020905b8154815290600101906020018083116109f957829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a458385836139eb565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a8493929190613b05565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161096d565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b97611a22565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610ca45750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca49190613b69565b9392505050565b6000610619600567ffffffffffffffff8416611c5b565b610cca611a22565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d76610d7183613b86565b611c73565b60095473ffffffffffffffffffffffffffffffffffffffff16610e3b576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610e1e57600080fd5b505af1158015610e32573d6000803e3d6000fd5b50505050610e4c565b610e4c610e4783613b86565b611e3d565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610ea684602001602081019061047591906131f0565b81526040805160208181019092526000815291015292915050565b6060610ecd6002611f57565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261061990611f64565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061064a906137b7565b610fda611a22565b73ffffffffffffffffffffffffffffffffffffffff8116611027576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d45565b606060006110b46005611f57565b90506000815167ffffffffffffffff8111156110d2576110d26135bb565b6040519080825280602002602001820160405280156110fb578160200160208202803683370190505b50905060005b82518110156111575782818151811061111c5761111c613c28565b602002602001015182828151811061113657611136613c28565b67ffffffffffffffff90921660209283029190910190910152600101611101565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261061990611f64565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611270575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112a9576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161096d565b6112b4838383612016565b505050565b6112c1611a22565b60005b818110156112b45760008383838181106112e0576112e0613c28565b90506020028101906112f29190613c57565b6112fb90613c95565b90506113108160800151826020015115612100565b6113238160a00151826020015115612100565b80602001511561161f5780516113459060059067ffffffffffffffff16612239565b61138a5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161096d565b604081015151158061139f5750606081015151155b156113d6576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115b79082613d49565b50606082015160058201906115cc9082613d49565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116129493929190613e63565b60405180910390a1611736565b80516116379060059067ffffffffffffffff16612245565b61167c5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161096d565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116e56004830182613143565b6116f3600583016000613143565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112c4565b611747611a22565b61175081612251565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146117e85760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161096d565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ba9190613b69565b156118f1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118fe8160200151612346565b600061190d826020015161061f565b9050805160001480611931575080805190602001208260a001518051906020012014155b1561196e578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161096d9190613279565b6119808260200151836060015161246c565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad6946119ed9490939291600401613efc565b600060405180830381600087803b158015611a0757600080fd5b505af1158015611a1b573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161096d565b565b7f0000000000000000000000000000000000000000000000000000000000000000611afc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611b92576000838281518110611b1c57611b1c613c28565b60200260200101519050611b3a8160026124b390919063ffffffff16565b15611b895760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611aff565b5060005b81518110156112b4576000828281518110611bb357611bb3613c28565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bf75750611c53565b611c026002826124d5565b15611c515760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611b96565b60008181526001830160205260408120541515610ca4565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611d085760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161096d565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611db6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dda9190613b69565b15611e11576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e1e81604001516124f7565b611e2b8160200151612576565b611750816020015182606001516126c4565b6009546060820151611e8a9173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690612708565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611ef294939291600401613f5d565b6000604051808303816000875af1158015611f11573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119809190810190613fbd565b60606000610ca483612795565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611ff282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611fd6919061405a565b85608001516fffffffffffffffffffffffffffffffff166127f0565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61201f83610cab565b612061576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161096d565b61206c826000612100565b67ffffffffffffffff8316600090815260076020526040902061208f908361281a565b61209a816000612100565b67ffffffffffffffff831660009081526007602052604090206120c0906002018261281a565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516120f39392919061406d565b60405180910390a1505050565b8151156121c75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612156575060408201516fffffffffffffffffffffffffffffffff16155b1561218f57816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161096d91906140f0565b8015611980576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612200575060208201516fffffffffffffffffffffffffffffffff1615155b1561198057816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161096d91906140f0565b6000610ca483836129bc565b6000610ca48383612a0b565b3373ffffffffffffffffffffffffffffffffffffffff8216036122d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161096d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61234f81610cab565b612391576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161096d565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124349190613b69565b611750576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161096d565b67ffffffffffffffff8216600090815260076020526040902061198090600201827f0000000000000000000000000000000000000000000000000000000000000000612afe565b6000610ca48373ffffffffffffffffffffffffffffffffffffffff8416612a0b565b6000610ca48373ffffffffffffffffffffffffffffffffffffffff84166129bc565b7f00000000000000000000000000000000000000000000000000000000000000001561175057612528600282612e81565b611750576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161096d565b61257f81610cab565b6125c1576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161096d565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561263a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061265e919061412c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611750576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161096d565b67ffffffffffffffff8216600090815260076020526040902061198090827f0000000000000000000000000000000000000000000000000000000000000000612afe565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526112b4908490612eb0565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106c357602002820191906000526020600020905b8154815260200190600101908083116127d15750505050509050919050565b600061280f856128008486614149565b61280a9087614160565b612fbc565b90505b949350505050565b815460009061284390700100000000000000000000000000000000900463ffffffff164261405a565b905080156128e5576001830154835461288b916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166127f0565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461290b916fffffffffffffffffffffffffffffffff9081169116612fbc565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906120f39084906140f0565b6000818152600183016020526040812054612a0357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610619565b506000610619565b60008181526001830160205260408120548015612af4576000612a2f60018361405a565b8554909150600090612a439060019061405a565b9050818114612aa8576000866000018281548110612a6357612a63613c28565b9060005260206000200154905080876000018481548110612a8657612a86613c28565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ab957612ab9614173565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610619565b6000915050610619565b825474010000000000000000000000000000000000000000900460ff161580612b25575081155b15612b2f57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612b7590700100000000000000000000000000000000900463ffffffff164261405a565b90508015612c355781831115612bb7576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612bf19083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166127f0565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612cec5773ffffffffffffffffffffffffffffffffffffffff8416612c94576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161096d565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161096d565b84831015612dff5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612d30908261405a565b612d3a878a61405a565b612d449190614160565b612d4e91906141a2565b905073ffffffffffffffffffffffffffffffffffffffff8616612da7576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161096d565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161096d565b612e09858461405a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610ca4565b6000612f12826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612fd29092919063ffffffff16565b8051909150156112b45780806020019051810190612f309190613b69565b6112b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161096d565b6000818310612fcb5781610ca4565b5090919050565b60606128128484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161300691906141dd565b60006040518083038185875af1925050503d8060008114613043576040519150601f19603f3d011682016040523d82523d6000602084013e613048565b606091505b509150915061305987838387613064565b979650505050505050565b606083156130fa5782516000036130f35773ffffffffffffffffffffffffffffffffffffffff85163b6130f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161096d565b5081612812565b612812838381511561310f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096d9190613279565b50805461314f906137b7565b6000825580601f1061315f575050565b601f01602090049060005260206000209081019061175091905b8082111561318d5760008155600101613179565b5090565b6000602082840312156131a357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ca457600080fd5b803567ffffffffffffffff811681146131eb57600080fd5b919050565b60006020828403121561320257600080fd5b610ca4826131d3565b60005b8381101561322657818101518382015260200161320e565b50506000910152565b6000815180845261324781602086016020860161320b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ca4602083018461322f565b73ffffffffffffffffffffffffffffffffffffffff8116811461175057600080fd5b80356131eb8161328c565b6000602082840312156132cb57600080fd5b8135610ca48161328c565b6000602082840312156132e857600080fd5b813567ffffffffffffffff8111156132ff57600080fd5b82016101008185031215610ca457600080fd5b60008083601f84011261332457600080fd5b50813567ffffffffffffffff81111561333c57600080fd5b6020830191508360208260051b850101111561335757600080fd5b9250929050565b6000806000806040858703121561337457600080fd5b843567ffffffffffffffff8082111561338c57600080fd5b61339888838901613312565b909650945060208701359150808211156133b157600080fd5b506133be87828801613312565b95989497509550505050565b6000806000604084860312156133df57600080fd5b6133e8846131d3565b9250602084013567ffffffffffffffff8082111561340557600080fd5b818601915086601f83011261341957600080fd5b81358181111561342857600080fd5b87602082850101111561343a57600080fd5b6020830194508093505050509250925092565b6000806040838503121561346057600080fd5b613469836131d3565b915060208301356134798161328c565b809150509250929050565b60006020828403121561349657600080fd5b813567ffffffffffffffff8111156134ad57600080fd5b820160a08185031215610ca457600080fd5b6020815260008251604060208401526134db606084018261322f565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613516828261322f565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561356d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161353b565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561356d57835167ffffffffffffffff1683529284019291840191600101613595565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561360e5761360e6135bb565b60405290565b60405160c0810167ffffffffffffffff8111828210171561360e5761360e6135bb565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561367e5761367e6135bb565b604052919050565b801515811461175057600080fd5b80356131eb81613686565b80356fffffffffffffffffffffffffffffffff811681146131eb57600080fd5b6000606082840312156136d157600080fd5b6040516060810181811067ffffffffffffffff821117156136f4576136f46135bb565b604052905080823561370581613686565b81526137136020840161369f565b60208201526137246040840161369f565b60408201525092915050565b600080600060e0848603121561374557600080fd5b61374e846131d3565b925061375d85602086016136bf565b915061376c85608086016136bf565b90509250925092565b6000806020838503121561378857600080fd5b823567ffffffffffffffff81111561379f57600080fd5b6137ab85828601613312565b90969095509350505050565b600181811c908216806137cb57607f821691505b602082108103613804577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff821115613824576138246135bb565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261386157600080fd5b813561387461386f8261380a565b613637565b81815284602083860101111561388957600080fd5b816020850160208301376000918101602001919091529392505050565b600061010082360312156138b957600080fd5b6138c16135ea565b823567ffffffffffffffff808211156138d957600080fd5b6138e536838701613850565b83526138f3602086016131d3565b6020840152613904604086016132ae565b60408401526060850135606084015261391f608086016132ae565b608084015260a085013591508082111561393857600080fd5b61394436838701613850565b60a084015260c085013591508082111561395d57600080fd5b61396936838701613850565b60c084015260e085013591508082111561398257600080fd5b5061398f36828601613850565b60e08301525092915050565b601f8211156112b4576000816000526020600020601f850160051c810160208610156139c45750805b601f850160051c820191505b818110156139e3578281556001016139d0565b505050505050565b67ffffffffffffffff831115613a0357613a036135bb565b613a1783613a1183546137b7565b8361399b565b6000601f841160018114613a695760008515613a335750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a1b565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613ab85786850135825560209485019460019092019101613a98565b5086821015613af3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613b18604083018661322f565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613b7b57600080fd5b8151610ca481613686565b600060a08236031215613b9857600080fd5b60405160a0810167ffffffffffffffff8282108183111715613bbc57613bbc6135bb565b816040528435915080821115613bd157600080fd5b50613bde36828601613850565b825250613bed602084016131d3565b60208201526040830135613c008161328c565b6040820152606083810135908201526080830135613c1d8161328c565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613c8b57600080fd5b9190910192915050565b60006101408236031215613ca857600080fd5b613cb0613614565b613cb9836131d3565b8152613cc760208401613694565b6020820152604083013567ffffffffffffffff80821115613ce757600080fd5b613cf336838701613850565b60408401526060850135915080821115613d0c57600080fd5b50613d1936828601613850565b606083015250613d2c36608085016136bf565b6080820152613d3e3660e085016136bf565b60a082015292915050565b815167ffffffffffffffff811115613d6357613d636135bb565b613d7781613d7184546137b7565b8461399b565b602080601f831160018114613dca5760008415613d945750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139e3565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e1757888601518255948401946001909101908401613df8565b5085821015613e5357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613e878184018761322f565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613ec59050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613516565b60a081526000613f0f60a083018761322f565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613f8c60a083018661322f565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613fcf57600080fd5b815167ffffffffffffffff811115613fe657600080fd5b8201601f81018413613ff757600080fd5b805161400561386f8261380a565b81815285602083850101111561401a57600080fd5b61351682602083016020860161320b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106195761061961402b565b67ffffffffffffffff8416815260e081016140b960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612812565b6060810161061982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561413e57600080fd5b8151610ca48161328c565b80820281158282048414176106195761061961402b565b808201808211156106195761061961402b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826141d8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613c8b81846020870161320b56fe4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b506040516200494a3803806200494a833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050818114620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051614214620007366000396000818161053701528181611abf0152612511015260008181610511015281816118520152611d7201526000818161025a015281816102af0152818161075701528181610ddd0152818161177201528181611c9201528181611e78015281816124a701526126fc01526142146000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639766b93211610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104fc578063dc0bd9711461050f578063e0351e1314610535578063f2fde38b1461055b57600080fd5b8063c0d78655146104ae578063c4bffe2b146104c1578063c75eea9c146104d6578063cf7401f3146104e957600080fd5b8063a8d87a3b116100de578063a8d87a3b146103fb578063af58d59f1461040e578063b0f479a11461047d578063b79465801461049b57600080fd5b80639766b932146103b35780639a4575b9146103c6578063a7cd63b7146103e657600080fd5b80636d3d1a58116101715780637d54534e1161014b5780637d54534e1461035c57806383826b2b1461036f5780638926f54f146103825780638da5cb5b1461039557600080fd5b80636d3d1a581461032357806378a010b21461034157806379ba50971461035457600080fd5b806321df0da7116101ad57806321df0da714610258578063240028e81461029f57806339077537146102ec57806354c8a4f31461030e57600080fd5b806301ffc9a7146101d45780630a2fd493146101fc578063181f5a771461021c575b600080fd5b6101e76101e23660046131a9565b61056e565b60405190151581526020015b60405180910390f35b61020f61020a366004613208565b610653565b6040516101f39190613291565b61020f6040518060400160405280601f81526020017f4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e300081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e76102ad3660046132d1565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102ff6102fa3660046132ee565b610703565b604051905181526020016101f3565b61032161031c366004613376565b6108bb565b005b60085473ffffffffffffffffffffffffffffffffffffffff1661027a565b61032161034f3660046133e2565b610936565b610321610aaa565b61032161036a3660046132d1565b610ba7565b6101e761037d366004613465565b610bf6565b6101e7610390366004613208565b610cc3565b60005473ffffffffffffffffffffffffffffffffffffffff1661027a565b6103216103c13660046132d1565b610cda565b6103d96103d436600461349c565b610d69565b6040516101f391906134d7565b6103ee610ed9565b6040516101f39190613537565b61027a610409366004613208565b503090565b61042161041c366004613208565b610eea565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff1661027a565b61020f6104a9366004613208565b610fbf565b6103216104bc3660046132d1565b610fea565b6104c96110be565b6040516101f39190613591565b6104216104e4366004613208565b611176565b6103216104f7366004613748565b611248565b61032161050a36600461378d565b6112d1565b7f000000000000000000000000000000000000000000000000000000000000000061027a565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b6103216105693660046132d1565b611757565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061060157507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061064d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061067e906137cf565b80601f01602080910402602001604051908101604052809291908181526020018280546106aa906137cf565b80156106f75780601f106106cc576101008083540402835291602001916106f7565b820191906000526020600020905b8154815290600101906020018083116106da57829003601f168201915b50505050509050919050565b60408051602081019091526000815261072361071e836138be565b61176b565b60095473ffffffffffffffffffffffffffffffffffffffff166108195773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961078c60608501604086016132d1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b1580156107fc57600080fd5b505af1158015610810573d6000803e3d6000fd5b5050505061082a565b61082a610825836138be565b61199c565b61083a60608301604084016132d1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161089c91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108c3611a3a565b61093084848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611abd92505050565b50505050565b61093e611a3a565b61094783610cc3565b61098e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109b5906137cf565b80601f01602080910402602001604051908101604052809291908181526020018280546109e1906137cf565b8015610a2e5780601f10610a0357610100808354040283529160200191610a2e565b820191906000526020600020905b815481529060010190602001808311610a1157829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a5d838583613a03565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a9c93929190613b1d565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610985565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610baf611a3a565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610cbc5750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610c98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbc9190613b81565b9392505050565b600061064d600567ffffffffffffffff8416611c73565b610ce2611a3a565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d8e610d8983613b9e565b611c8b565b60095473ffffffffffffffffffffffffffffffffffffffff16610e53576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610e3657600080fd5b505af1158015610e4a573d6000803e3d6000fd5b50505050610e64565b610e64610e5f83613b9e565b611e55565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610ebe8460200160208101906104a99190613208565b81526040805160208181019092526000815291015292915050565b6060610ee56002611f6f565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261064d90611f7c565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061067e906137cf565b610ff2611a3a565b73ffffffffffffffffffffffffffffffffffffffff811661103f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d5d565b606060006110cc6005611f6f565b90506000815167ffffffffffffffff8111156110ea576110ea6135d3565b604051908082528060200260200182016040528015611113578160200160208202803683370190505b50905060005b825181101561116f5782818151811061113457611134613c40565b602002602001015182828151811061114e5761114e613c40565b67ffffffffffffffff90921660209283029190910190910152600101611119565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261064d90611f7c565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611288575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112c1576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610985565b6112cc83838361202e565b505050565b6112d9611a3a565b60005b818110156112cc5760008383838181106112f8576112f8613c40565b905060200281019061130a9190613c6f565b61131390613cad565b90506113288160800151826020015115612118565b61133b8160a00151826020015115612118565b80602001511561163757805161135d9060059067ffffffffffffffff16612251565b6113a25780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610985565b60408101515115806113b75750606081015151155b156113ee576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115cf9082613d61565b50606082015160058201906115e49082613d61565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061162a9493929190613e7b565b60405180910390a161174e565b805161164f9060059067ffffffffffffffff1661225d565b6116945780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610985565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116fd600483018261315b565b61170b60058301600061315b565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112dc565b61175f611a3a565b61176881612269565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146118005760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610985565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156118ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d29190613b81565b15611909576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611916816020015161235e565b60006119258260200151610653565b9050805160001480611949575080805190602001208260a001518051906020012014155b15611986578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109859190613291565b61199882602001518360600151612484565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611a059490939291600401613f14565b600060405180830381600087803b158015611a1f57600080fd5b505af1158015611a33573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611abb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610985565b565b7f0000000000000000000000000000000000000000000000000000000000000000611b14576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611baa576000838281518110611b3457611b34613c40565b60200260200101519050611b528160026124cb90919063ffffffff16565b15611ba15760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611b17565b5060005b81518110156112cc576000828281518110611bcb57611bcb613c40565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c0f5750611c6b565b611c1a6002826124ed565b15611c695760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611bae565b60008181526001830160205260408120541515610cbc565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611d205760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610985565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611dce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df29190613b81565b15611e29576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e36816040015161250f565b611e43816020015161258e565b611768816020015182606001516126dc565b6009546060820151611ea29173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690612720565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611f0a94939291600401613f75565b6000604051808303816000875af1158015611f29573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119989190810190613fd5565b60606000610cbc836127ad565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261200a82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611fee9190614072565b85608001516fffffffffffffffffffffffffffffffff16612808565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61203783610cc3565b612079576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610985565b612084826000612118565b67ffffffffffffffff831660009081526007602052604090206120a79083612832565b6120b2816000612118565b67ffffffffffffffff831660009081526007602052604090206120d89060020182612832565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161210b93929190614085565b60405180910390a1505050565b8151156121df5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061216e575060408201516fffffffffffffffffffffffffffffffff16155b156121a757816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109859190614108565b8015611998576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612218575060208201516fffffffffffffffffffffffffffffffff1615155b1561199857816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109859190614108565b6000610cbc83836129d4565b6000610cbc8383612a23565b3373ffffffffffffffffffffffffffffffffffffffff8216036122e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610985565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61236781610cc3565b6123a9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610985565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612428573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061244c9190613b81565b611768576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610985565b67ffffffffffffffff8216600090815260076020526040902061199890600201827f0000000000000000000000000000000000000000000000000000000000000000612b16565b6000610cbc8373ffffffffffffffffffffffffffffffffffffffff8416612a23565b6000610cbc8373ffffffffffffffffffffffffffffffffffffffff84166129d4565b7f00000000000000000000000000000000000000000000000000000000000000001561176857612540600282612e99565b611768576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610985565b61259781610cc3565b6125d9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610985565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126769190614144565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611768576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610985565b67ffffffffffffffff8216600090815260076020526040902061199890827f0000000000000000000000000000000000000000000000000000000000000000612b16565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526112cc908490612ec8565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106f757602002820191906000526020600020905b8154815260200190600101908083116127e95750505050509050919050565b6000612827856128188486614161565b6128229087614178565b612fd4565b90505b949350505050565b815460009061285b90700100000000000000000000000000000000900463ffffffff1642614072565b905080156128fd57600183015483546128a3916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612808565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612923916fffffffffffffffffffffffffffffffff9081169116612fd4565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061210b908490614108565b6000818152600183016020526040812054612a1b5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561064d565b50600061064d565b60008181526001830160205260408120548015612b0c576000612a47600183614072565b8554909150600090612a5b90600190614072565b9050818114612ac0576000866000018281548110612a7b57612a7b613c40565b9060005260206000200154905080876000018481548110612a9e57612a9e613c40565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ad157612ad161418b565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061064d565b600091505061064d565b825474010000000000000000000000000000000000000000900460ff161580612b3d575081155b15612b4757505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612b8d90700100000000000000000000000000000000900463ffffffff1642614072565b90508015612c4d5781831115612bcf576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612c099083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612808565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612d045773ffffffffffffffffffffffffffffffffffffffff8416612cac576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610985565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610985565b84831015612e175760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612d489082614072565b612d52878a614072565b612d5c9190614178565b612d6691906141ba565b905073ffffffffffffffffffffffffffffffffffffffff8616612dbf576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610985565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610985565b612e218584614072565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610cbc565b6000612f2a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612fea9092919063ffffffff16565b8051909150156112cc5780806020019051810190612f489190613b81565b6112cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610985565b6000818310612fe35781610cbc565b5090919050565b606061282a8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161301e91906141f5565b60006040518083038185875af1925050503d806000811461305b576040519150601f19603f3d011682016040523d82523d6000602084013e613060565b606091505b50915091506130718783838761307c565b979650505050505050565b6060831561311257825160000361310b5773ffffffffffffffffffffffffffffffffffffffff85163b61310b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610985565b508161282a565b61282a83838151156131275781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109859190613291565b508054613167906137cf565b6000825580601f10613177575050565b601f01602090049060005260206000209081019061176891905b808211156131a55760008155600101613191565b5090565b6000602082840312156131bb57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610cbc57600080fd5b803567ffffffffffffffff8116811461320357600080fd5b919050565b60006020828403121561321a57600080fd5b610cbc826131eb565b60005b8381101561323e578181015183820152602001613226565b50506000910152565b6000815180845261325f816020860160208601613223565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610cbc6020830184613247565b73ffffffffffffffffffffffffffffffffffffffff8116811461176857600080fd5b8035613203816132a4565b6000602082840312156132e357600080fd5b8135610cbc816132a4565b60006020828403121561330057600080fd5b813567ffffffffffffffff81111561331757600080fd5b82016101008185031215610cbc57600080fd5b60008083601f84011261333c57600080fd5b50813567ffffffffffffffff81111561335457600080fd5b6020830191508360208260051b850101111561336f57600080fd5b9250929050565b6000806000806040858703121561338c57600080fd5b843567ffffffffffffffff808211156133a457600080fd5b6133b08883890161332a565b909650945060208701359150808211156133c957600080fd5b506133d68782880161332a565b95989497509550505050565b6000806000604084860312156133f757600080fd5b613400846131eb565b9250602084013567ffffffffffffffff8082111561341d57600080fd5b818601915086601f83011261343157600080fd5b81358181111561344057600080fd5b87602082850101111561345257600080fd5b6020830194508093505050509250925092565b6000806040838503121561347857600080fd5b613481836131eb565b91506020830135613491816132a4565b809150509250929050565b6000602082840312156134ae57600080fd5b813567ffffffffffffffff8111156134c557600080fd5b820160a08185031215610cbc57600080fd5b6020815260008251604060208401526134f36060840182613247565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261352e8282613247565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613553565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358557835167ffffffffffffffff16835292840192918401916001016135ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613626576136266135d3565b60405290565b60405160c0810167ffffffffffffffff81118282101715613626576136266135d3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613696576136966135d3565b604052919050565b801515811461176857600080fd5b80356132038161369e565b80356fffffffffffffffffffffffffffffffff8116811461320357600080fd5b6000606082840312156136e957600080fd5b6040516060810181811067ffffffffffffffff8211171561370c5761370c6135d3565b604052905080823561371d8161369e565b815261372b602084016136b7565b602082015261373c604084016136b7565b60408201525092915050565b600080600060e0848603121561375d57600080fd5b613766846131eb565b925061377585602086016136d7565b915061378485608086016136d7565b90509250925092565b600080602083850312156137a057600080fd5b823567ffffffffffffffff8111156137b757600080fd5b6137c38582860161332a565b90969095509350505050565b600181811c908216806137e357607f821691505b60208210810361381c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff82111561383c5761383c6135d3565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261387957600080fd5b813561388c61388782613822565b61364f565b8181528460208386010111156138a157600080fd5b816020850160208301376000918101602001919091529392505050565b600061010082360312156138d157600080fd5b6138d9613602565b823567ffffffffffffffff808211156138f157600080fd5b6138fd36838701613868565b835261390b602086016131eb565b602084015261391c604086016132c6565b604084015260608501356060840152613937608086016132c6565b608084015260a085013591508082111561395057600080fd5b61395c36838701613868565b60a084015260c085013591508082111561397557600080fd5b61398136838701613868565b60c084015260e085013591508082111561399a57600080fd5b506139a736828601613868565b60e08301525092915050565b601f8211156112cc576000816000526020600020601f850160051c810160208610156139dc5750805b601f850160051c820191505b818110156139fb578281556001016139e8565b505050505050565b67ffffffffffffffff831115613a1b57613a1b6135d3565b613a2f83613a2983546137cf565b836139b3565b6000601f841160018114613a815760008515613a4b5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a33565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613ad05786850135825560209485019460019092019101613ab0565b5086821015613b0b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613b306040830186613247565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613b9357600080fd5b8151610cbc8161369e565b600060a08236031215613bb057600080fd5b60405160a0810167ffffffffffffffff8282108183111715613bd457613bd46135d3565b816040528435915080821115613be957600080fd5b50613bf636828601613868565b825250613c05602084016131eb565b60208201526040830135613c18816132a4565b6040820152606083810135908201526080830135613c35816132a4565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ca357600080fd5b9190910192915050565b60006101408236031215613cc057600080fd5b613cc861362c565b613cd1836131eb565b8152613cdf602084016136ac565b6020820152604083013567ffffffffffffffff80821115613cff57600080fd5b613d0b36838701613868565b60408401526060850135915080821115613d2457600080fd5b50613d3136828601613868565b606083015250613d4436608085016136d7565b6080820152613d563660e085016136d7565b60a082015292915050565b815167ffffffffffffffff811115613d7b57613d7b6135d3565b613d8f81613d8984546137cf565b846139b3565b602080601f831160018114613de25760008415613dac5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139fb565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e2f57888601518255948401946001909101908401613e10565b5085821015613e6b57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613e9f81840187613247565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613edd9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e083015261352e565b60a081526000613f2760a0830187613247565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613fa460a0830186613247565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613fe757600080fd5b815167ffffffffffffffff811115613ffe57600080fd5b8201601f8101841361400f57600080fd5b805161401d61388782613822565b81815285602083850101111561403257600080fd5b61352e826020830160208601613223565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561064d5761064d614043565b67ffffffffffffffff8416815260e081016140d160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261282a565b6060810161064d82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561415657600080fd5b8151610cbc816132a4565b808202811582820484141761064d5761064d614043565b8082018082111561064d5761064d614043565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826141f0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613ca381846020870161322356fea164736f6c6343000818000a", } var BurnMintTokenPoolAndProxyABI = BurnMintTokenPoolAndProxyMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go index 0ee344adbd..e9edaad443 100644 --- a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnWithFromMintTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b5060405162004516380380620045168339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161399d62000b79600039600081816104a90152818161175f0152612143015260008181610483015281816115900152611a150152600081816102050152818161025a015281816106c8015281816114b00152818161193501528181611b2d015281816120d9015261232e015261399d6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc1461046e578063dc0bd97114610481578063e0351e13146104a7578063f2fde38b146104cd57600080fd5b8063c4bffe2b14610433578063c75eea9c14610448578063cf7401f31461045b57600080fd5b8063b0f479a1116100c8578063b0f479a1146103ef578063b79465801461040d578063c0d786551461042057600080fd5b80639a4575b91461034b578063a7cd63b71461036b578063af58d59f1461038057600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146102ff5780637d54534e146103075780638926f54f1461031a5780638da5cb5b1461032d57600080fd5b806354c8a4f3146102b95780636d3d1a58146102ce57806378a010b2146102ec57600080fd5b806321df0da71161018c57806321df0da714610203578063240028e81461024a578063390775371461029757600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ad1565b6104e0565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b30565b6105c5565b6040516101d29190612baf565b6101ee610675565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c6610258366004612bef565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102aa6102a5366004612c0c565b610691565b604051905181526020016101d2565b6102cc6102c7366004612c94565b610817565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610225565b6102cc6102fa366004612d00565b610892565b6102cc610a06565b6102cc610315366004612bef565b610b03565b6101c6610328366004612b30565b610b52565b60005473ffffffffffffffffffffffffffffffffffffffff16610225565b61035e610359366004612d83565b610b69565b6040516101d29190612dbe565b610373610c10565b6040516101d29190612e1e565b61039361038e366004612b30565b610c21565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610225565b6101ee61041b366004612b30565b610cf6565b6102cc61042e366004612bef565b610d21565b61043b610dfc565b6040516101d29190612e78565b610393610456366004612b30565b610eb4565b6102cc610469366004612fe0565b610f86565b6102cc61047c366004613025565b61100f565b7f0000000000000000000000000000000000000000000000000000000000000000610225565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b6102cc6104db366004612bef565b611495565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061057357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105bf57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906105f090613067565b80601f016020809104026020016040519081016040528092919081815260200182805461061c90613067565b80156106695780601f1061063e57610100808354040283529160200191610669565b820191906000526020600020905b81548152906001019060200180831161064c57829003601f168201915b50505050509050919050565b60405180606001604052806023815260200161396e6023913981565b6040805160208101909152600081526106b16106ac83613165565b6114a9565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196106fd6060850160408601612bef565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561076d57600080fd5b505af1158015610781573d6000803e3d6000fd5b50610796925050506060830160408401612bef565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f084606001356040516107f891815260200190565b60405180910390a3506040805160208101909152606090910135815290565b61081f6116da565b61088c8484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061175d92505050565b50505050565b61089a6116da565b6108a383610b52565b6108ea576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461091190613067565b80601f016020809104026020016040519081016040528092919081815260200182805461093d90613067565b801561098a5780601f1061095f5761010080835404028352916020019161098a565b820191906000526020600020905b81548152906001019060200180831161096d57829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109b98385836132aa565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf8285856040516109f8939291906133c4565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a87576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108e1565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b0b6116da565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105bf600567ffffffffffffffff8416611913565b6040805180820190915260608082526020820152610b8e610b8983613428565b61192e565b610b9b8260600135611af8565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610bf584602001602081019061041b9190612b30565b81526040805160208181019092526000815291015292915050565b6060610c1c6002611ba1565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105bf90611bae565b67ffffffffffffffff811660009081526007602052604090206005018054606091906105f090613067565b610d296116da565b73ffffffffffffffffffffffffffffffffffffffff8116610d76576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e0a6005611ba1565b90506000815167ffffffffffffffff811115610e2857610e28612eba565b604051908082528060200260200182016040528015610e51578160200160208202803683370190505b50905060005b8251811015610ead57828181518110610e7257610e726134ca565b6020026020010151828281518110610e8c57610e8c6134ca565b67ffffffffffffffff90921660209283029190910190910152600101610e57565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105bf90611bae565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fc6575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610fff576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108e1565b61100a838383611c60565b505050565b6110176116da565b60005b8181101561100a576000838383818110611036576110366134ca565b905060200281019061104891906134f9565b61105190613537565b90506110668160800151826020015115611d4a565b6110798160a00151826020015115611d4a565b80602001511561137557805161109b9060059067ffffffffffffffff16611e83565b6110e05780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108e1565b60408101515115806110f55750606081015151155b1561112c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061130d90826135eb565b506060820151600582019061132290826135eb565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506113689493929190613705565b60405180910390a161148c565b805161138d9060059067ffffffffffffffff16611e8f565b6113d25780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108e1565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600182018390556002820180549091169055600381018290559061143b6004830182612a83565b611449600583016000612a83565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161101a565b61149d6116da565b6114a681611e9b565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461153e5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108e1565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156115ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611610919061379e565b15611647576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116548160200151611f90565b600061166382602001516105c5565b9050805160001480611687575080805190602001208260a001518051906020012014155b156116c4578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108e19190612baf565b6116d6826020015183606001516120b6565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461175b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108e1565b565b7f00000000000000000000000000000000000000000000000000000000000000006117b4576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561184a5760008382815181106117d4576117d46134ca565b602002602001015190506117f28160026120fd90919063ffffffff16565b156118415760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117b7565b5060005b815181101561100a57600082828151811061186b5761186b6134ca565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118af575061190b565b6118ba60028261211f565b156119095760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161184e565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119c35760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108e1565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a95919061379e565b15611acc576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ad98160400151612141565b611ae681602001516121c0565b6114a68160200151826060015161230e565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b158015611b8657600080fd5b505af1158015611b9a573d6000803e3d6000fd5b5050505050565b6060600061192783612352565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c3c82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c2091906137ea565b85608001516fffffffffffffffffffffffffffffffff166123ad565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c6983610b52565b611cab576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108e1565b611cb6826000611d4a565b67ffffffffffffffff83166000908152600760205260409020611cd990836123d7565b611ce4816000611d4a565b67ffffffffffffffff83166000908152600760205260409020611d0a90600201826123d7565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d3d939291906137fd565b60405180910390a1505050565b815115611e115781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611da0575060408201516fffffffffffffffffffffffffffffffff16155b15611dd957816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108e19190613880565b80156116d6576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e4a575060208201516fffffffffffffffffffffffffffffffff1615155b156116d657816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108e19190613880565b60006119278383612579565b600061192783836125c8565b3373ffffffffffffffffffffffffffffffffffffffff821603611f1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108e1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611f9981610b52565b611fdb576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108e1565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561205a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207e919061379e565b6114a6576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108e1565b67ffffffffffffffff821660009081526007602052604090206116d690600201827f00000000000000000000000000000000000000000000000000000000000000006126bb565b60006119278373ffffffffffffffffffffffffffffffffffffffff84166125c8565b60006119278373ffffffffffffffffffffffffffffffffffffffff8416612579565b7f0000000000000000000000000000000000000000000000000000000000000000156114a657612172600282612a3e565b6114a6576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108e1565b6121c981610b52565b61220b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108e1565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a891906138bc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114a6576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108e1565b67ffffffffffffffff821660009081526007602052604090206116d690827f00000000000000000000000000000000000000000000000000000000000000006126bb565b60608160000180548060200260200160405190810160405280929190818152602001828054801561066957602002820191906000526020600020905b81548152602001906001019080831161238e5750505050509050919050565b60006123cc856123bd84866138d9565b6123c790876138f0565b612a6d565b90505b949350505050565b815460009061240090700100000000000000000000000000000000900463ffffffff16426137ea565b905080156124a25760018301548354612448916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123ad565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124c8916fffffffffffffffffffffffffffffffff9081169116612a6d565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d3d908490613880565b60008181526001830160205260408120546125c0575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105bf565b5060006105bf565b600081815260018301602052604081205480156126b15760006125ec6001836137ea565b8554909150600090612600906001906137ea565b9050818114612665576000866000018281548110612620576126206134ca565b9060005260206000200154905080876000018481548110612643576126436134ca565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061267657612676613903565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105bf565b60009150506105bf565b825474010000000000000000000000000000000000000000900460ff1615806126e2575081155b156126ec57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061273290700100000000000000000000000000000000900463ffffffff16426137ea565b905080156127f25781831115612774576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127ae9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123ad565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128a95773ffffffffffffffffffffffffffffffffffffffff8416612851576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108e1565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108e1565b848310156129bc5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128ed90826137ea565b6128f7878a6137ea565b61290191906138f0565b61290b9190613932565b905073ffffffffffffffffffffffffffffffffffffffff8616612964576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108e1565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108e1565b6129c685846137ea565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611927565b6000818310612a7c5781611927565b5090919050565b508054612a8f90613067565b6000825580601f10612a9f575050565b601f0160209004906000526020600020908101906114a691905b80821115612acd5760008155600101612ab9565b5090565b600060208284031215612ae357600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461192757600080fd5b803567ffffffffffffffff81168114612b2b57600080fd5b919050565b600060208284031215612b4257600080fd5b61192782612b13565b6000815180845260005b81811015612b7157602081850181015186830182015201612b55565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119276020830184612b4b565b73ffffffffffffffffffffffffffffffffffffffff811681146114a657600080fd5b8035612b2b81612bc2565b600060208284031215612c0157600080fd5b813561192781612bc2565b600060208284031215612c1e57600080fd5b813567ffffffffffffffff811115612c3557600080fd5b8201610100818503121561192757600080fd5b60008083601f840112612c5a57600080fd5b50813567ffffffffffffffff811115612c7257600080fd5b6020830191508360208260051b8501011115612c8d57600080fd5b9250929050565b60008060008060408587031215612caa57600080fd5b843567ffffffffffffffff80821115612cc257600080fd5b612cce88838901612c48565b90965094506020870135915080821115612ce757600080fd5b50612cf487828801612c48565b95989497509550505050565b600080600060408486031215612d1557600080fd5b612d1e84612b13565b9250602084013567ffffffffffffffff80821115612d3b57600080fd5b818601915086601f830112612d4f57600080fd5b813581811115612d5e57600080fd5b876020828501011115612d7057600080fd5b6020830194508093505050509250925092565b600060208284031215612d9557600080fd5b813567ffffffffffffffff811115612dac57600080fd5b820160a0818503121561192757600080fd5b602081526000825160406020840152612dda6060840182612b4b565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e158282612b4b565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e6c57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e3a565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e6c57835167ffffffffffffffff1683529284019291840191600101612e94565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f0d57612f0d612eba565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f0d57612f0d612eba565b80151581146114a657600080fd5b8035612b2b81612f36565b80356fffffffffffffffffffffffffffffffff81168114612b2b57600080fd5b600060608284031215612f8157600080fd5b6040516060810181811067ffffffffffffffff82111715612fa457612fa4612eba565b6040529050808235612fb581612f36565b8152612fc360208401612f4f565b6020820152612fd460408401612f4f565b60408201525092915050565b600080600060e08486031215612ff557600080fd5b612ffe84612b13565b925061300d8560208601612f6f565b915061301c8560808601612f6f565b90509250925092565b6000806020838503121561303857600080fd5b823567ffffffffffffffff81111561304f57600080fd5b61305b85828601612c48565b90969095509350505050565b600181811c9082168061307b57607f821691505b6020821081036130b4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130cb57600080fd5b813567ffffffffffffffff808211156130e6576130e6612eba565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561312c5761312c612eba565b8160405283815286602085880101111561314557600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561317857600080fd5b613180612ee9565b823567ffffffffffffffff8082111561319857600080fd5b6131a4368387016130ba565b83526131b260208601612b13565b60208401526131c360408601612be4565b6040840152606085013560608401526131de60808601612be4565b608084015260a08501359150808211156131f757600080fd5b613203368387016130ba565b60a084015260c085013591508082111561321c57600080fd5b613228368387016130ba565b60c084015260e085013591508082111561324157600080fd5b5061324e368286016130ba565b60e08301525092915050565b601f82111561100a576000816000526020600020601f850160051c810160208610156132835750805b601f850160051c820191505b818110156132a25782815560010161328f565b505050505050565b67ffffffffffffffff8311156132c2576132c2612eba565b6132d6836132d08354613067565b8361325a565b6000601f84116001811461332857600085156132f25750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611b9a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156133775786850135825560209485019460019092019101613357565b50868210156133b2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133d76040830186612b4b565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561343a57600080fd5b60405160a0810167ffffffffffffffff828210818311171561345e5761345e612eba565b81604052843591508082111561347357600080fd5b50613480368286016130ba565b82525061348f60208401612b13565b602082015260408301356134a281612bc2565b60408201526060838101359082015260808301356134bf81612bc2565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261352d57600080fd5b9190910192915050565b6000610140823603121561354a57600080fd5b613552612f13565b61355b83612b13565b815261356960208401612f44565b6020820152604083013567ffffffffffffffff8082111561358957600080fd5b613595368387016130ba565b604084015260608501359150808211156135ae57600080fd5b506135bb368286016130ba565b6060830152506135ce3660808501612f6f565b60808201526135e03660e08501612f6f565b60a082015292915050565b815167ffffffffffffffff81111561360557613605612eba565b613619816136138454613067565b8461325a565b602080601f83116001811461366c57600084156136365750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132a2565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136b95788860151825594840194600190910190840161369a565b50858210156136f557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261372981840187612b4b565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506137679050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e15565b6000602082840312156137b057600080fd5b815161192781612f36565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105bf576105bf6137bb565b67ffffffffffffffff8416815260e0810161384960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123cf565b606081016105bf82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138ce57600080fd5b815161192781612bc2565b80820281158282048414176105bf576105bf6137bb565b808201808211156105bf576105bf6137bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613968577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fe4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e302d646576a164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b506040516200450b3803806200450b8339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161399262000b79600039600081816104dd01528181611777015261215b0152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b45015281816120f1015261234601526139926000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae9565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b48565b6105f9565b6040516101d29190612bc7565b6101ee6040518060400160405280601f81526020017f4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e300081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c07565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c24565b6106a9565b604051905181526020016101d2565b6103006102fb366004612cac565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d18565b6108aa565b610300610a1e565b610300610349366004612c07565b610b1b565b6101c661035c366004612b48565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d9b565b610b81565b6040516101d29190612dd6565b6103a7610c28565b6040516101d29190612e36565b6103c76103c2366004612b48565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b48565b610d0e565b610300610462366004612c07565b610d39565b61046f610e14565b6040516101d29190612e90565b6103c761048a366004612b48565b610ecc565b61030061049d366004612ff8565b610f9e565b6103006104b036600461303d565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c07565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061307f565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361317d565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c07565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c07565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109299061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546109559061307f565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132c2565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133dc565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba183613440565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b48565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb9565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc6565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061307f565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb9565b90506000815167ffffffffffffffff811115610e4057610e40612ed2565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134e2565b6020026020010151828281518110610ea457610ea46134e2565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc6565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c78565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134e2565b90506020028101906110609190613511565b6110699061354f565b905061107e8160800151826020015115611d62565b6110918160a00151826020015115611d62565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e9b565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906113259082613603565b506060820151600582019061133a9082613603565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c29550611380949392919061371d565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea7565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a9b565b611461600583016000612a9b565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611eb3565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b6565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa8565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc7565b6116ee826020015183606001516120ce565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134e2565b6020026020010151905061180a81600261211590919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134e2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612137565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b6565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612159565b611afe81602001516121d8565b6114be81602001518260600151612326565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b158015611b9e57600080fd5b505af1158015611bb2573d6000803e3d6000fd5b5050505050565b6060600061193f8361236a565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c5482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c389190613802565b85608001516fffffffffffffffffffffffffffffffff166123c5565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c8183610b6a565b611cc3576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cce826000611d62565b67ffffffffffffffff83166000908152600760205260409020611cf190836123ef565b611cfc816000611d62565b67ffffffffffffffff83166000908152600760205260409020611d2290600201826123ef565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d5593929190613815565b60405180910390a1505050565b815115611e295781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db8575060408201516fffffffffffffffffffffffffffffffff16155b15611df157816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e62575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b600061193f8383612591565b600061193f83836125e0565b3373ffffffffffffffffffffffffffffffffffffffff821603611f32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fb181610b6a565b611ff3576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612072573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209691906137b6565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126d3565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125e0565b600061193f8373ffffffffffffffffffffffffffffffffffffffff8416612591565b7f0000000000000000000000000000000000000000000000000000000000000000156114be5761218a600282612a56565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121e181610b6a565b612223576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c091906138d4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126d3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a65750505050509050919050565b60006123e4856123d584866138f1565b6123df9087613908565b612a85565b90505b949350505050565b815460009061241890700100000000000000000000000000000000900463ffffffff1642613802565b905080156124ba5760018301548354612460916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123c5565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124e0916fffffffffffffffffffffffffffffffff9081169116612a85565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d55908490613898565b60008181526001830160205260408120546125d8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c9576000612604600183613802565b855490915060009061261890600190613802565b905081811461267d576000866000018281548110612638576126386134e2565b906000526020600020015490508087600001848154811061265b5761265b6134e2565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268e5761268e61391b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126fa575081155b1561270457505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274a90700100000000000000000000000000000000900463ffffffff1642613802565b9050801561280a578183111561278c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c69083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123c5565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128c15773ffffffffffffffffffffffffffffffffffffffff8416612869576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129d45760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906129059082613802565b61290f878a613802565b6129199190613908565b612923919061394a565b905073ffffffffffffffffffffffffffffffffffffffff861661297c576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129de8584613802565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a94578161193f565b5090919050565b508054612aa79061307f565b6000825580601f10612ab7575050565b601f0160209004906000526020600020908101906114be91905b80821115612ae55760008155600101612ad1565b5090565b600060208284031215612afb57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b4357600080fd5b919050565b600060208284031215612b5a57600080fd5b61193f82612b2b565b6000815180845260005b81811015612b8957602081850181015186830182015201612b6d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b63565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b4381612bda565b600060208284031215612c1957600080fd5b813561193f81612bda565b600060208284031215612c3657600080fd5b813567ffffffffffffffff811115612c4d57600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c7257600080fd5b50813567ffffffffffffffff811115612c8a57600080fd5b6020830191508360208260051b8501011115612ca557600080fd5b9250929050565b60008060008060408587031215612cc257600080fd5b843567ffffffffffffffff80821115612cda57600080fd5b612ce688838901612c60565b90965094506020870135915080821115612cff57600080fd5b50612d0c87828801612c60565b95989497509550505050565b600080600060408486031215612d2d57600080fd5b612d3684612b2b565b9250602084013567ffffffffffffffff80821115612d5357600080fd5b818601915086601f830112612d6757600080fd5b813581811115612d7657600080fd5b876020828501011115612d8857600080fd5b6020830194508093505050509250925092565b600060208284031215612dad57600080fd5b813567ffffffffffffffff811115612dc457600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612df26060840182612b63565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e2d8282612b63565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e52565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835167ffffffffffffffff1683529284019291840191600101612eac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f2557612f25612ed2565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f2557612f25612ed2565b80151581146114be57600080fd5b8035612b4381612f4e565b80356fffffffffffffffffffffffffffffffff81168114612b4357600080fd5b600060608284031215612f9957600080fd5b6040516060810181811067ffffffffffffffff82111715612fbc57612fbc612ed2565b6040529050808235612fcd81612f4e565b8152612fdb60208401612f67565b6020820152612fec60408401612f67565b60408201525092915050565b600080600060e0848603121561300d57600080fd5b61301684612b2b565b92506130258560208601612f87565b91506130348560808601612f87565b90509250925092565b6000806020838503121561305057600080fd5b823567ffffffffffffffff81111561306757600080fd5b61307385828601612c60565b90969095509350505050565b600181811c9082168061309357607f821691505b6020821081036130cc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130e357600080fd5b813567ffffffffffffffff808211156130fe576130fe612ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561314457613144612ed2565b8160405283815286602085880101111561315d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561319057600080fd5b613198612f01565b823567ffffffffffffffff808211156131b057600080fd5b6131bc368387016130d2565b83526131ca60208601612b2b565b60208401526131db60408601612bfc565b6040840152606085013560608401526131f660808601612bfc565b608084015260a085013591508082111561320f57600080fd5b61321b368387016130d2565b60a084015260c085013591508082111561323457600080fd5b613240368387016130d2565b60c084015260e085013591508082111561325957600080fd5b50613266368286016130d2565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c8101602086101561329b5750805b601f850160051c820191505b818110156132ba578281556001016132a7565b505050505050565b67ffffffffffffffff8311156132da576132da612ed2565b6132ee836132e8835461307f565b83613272565b6000601f841160018114613340576000851561330a5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bb2565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561338f578685013582556020948501946001909201910161336f565b50868210156133ca577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133ef6040830186612b63565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561345257600080fd5b60405160a0810167ffffffffffffffff828210818311171561347657613476612ed2565b81604052843591508082111561348b57600080fd5b50613498368286016130d2565b8252506134a760208401612b2b565b602082015260408301356134ba81612bda565b60408201526060838101359082015260808301356134d781612bda565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261354557600080fd5b9190910192915050565b6000610140823603121561356257600080fd5b61356a612f2b565b61357383612b2b565b815261358160208401612f5c565b6020820152604083013567ffffffffffffffff808211156135a157600080fd5b6135ad368387016130d2565b604084015260608501359150808211156135c657600080fd5b506135d3368286016130d2565b6060830152506135e63660808501612f87565b60808201526135f83660e08501612f87565b60a082015292915050565b815167ffffffffffffffff81111561361d5761361d612ed2565b6136318161362b845461307f565b84613272565b602080601f831160018114613684576000841561364e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132ba565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136d1578886015182559484019460019091019084016136b2565b508582101561370d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261374181840187612b63565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061377f9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e2d565b6000602082840312156137c857600080fd5b815161193f81612f4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137d3565b67ffffffffffffffff8416815260e0810161386160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e7565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e657600080fd5b815161193f81612bda565b80820281158282048414176105f3576105f36137d3565b808201808211156105f3576105f36137d3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613980577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var BurnWithFromMintTokenPoolABI = BurnWithFromMintTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/commit_store/commit_store.go b/core/gethwrappers/ccip/generated/commit_store/commit_store.go index 940f4208d4..b0082a3f0b 100644 --- a/core/gethwrappers/ccip/generated/commit_store/commit_store.go +++ b/core/gethwrappers/ccip/generated/commit_store/commit_store.go @@ -69,7 +69,7 @@ type InternalTokenPriceUpdate struct { var CommitStoreMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"oldEpochAndRound\",\"type\":\"uint40\"},{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"newEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"LatestPriceEpochAndRoundSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"oldSeqNum\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newSeqNum\",\"type\":\"uint64\"}],\"name\":\"SequenceNumberSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndNotCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b506040516200378e3803806200378e8339810160408190526200004d9162000272565b600033808281620000a55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d857620000d88162000192565b50505015156080524660a05260408101516001600160a01b0316158062000107575080516001600160401b0316155b806200011e575060208101516001600160401b0316155b8062000135575060608101516001600160a01b0316155b156200015457604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b0390811661010052606090910151166101205262000306565b336001600160a01b03821603620001ec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025557600080fd5b919050565b80516001600160a01b03811681146200025557600080fd5b6000608082840312156200028557600080fd5b604051608081016001600160401b0381118282101715620002b657634e487b7160e01b600052604160045260246000fd5b604052620002c4836200023d565b8152620002d4602084016200023d565b6020820152620002e7604084016200025a565b6040820152620002fa606084016200025a565b60608201529392505050565b60805160a05160c05160e05161010051610120516133f26200039c60003960008181610262015281816116c80152818161187c01528181611acb0152611fa50152600081816102260152611aa40152600081816101f60152818161168201528181611a7d0152611f620152600081816101c60152611a4e0152600081816110c801526111140152600061118f01526133f26000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806379ba5097116100e3578063afcb95d71161008c578063f2fde38b11610066578063f2fde38b146104e3578063f47a8690146104f6578063ff888fb11461050957600080fd5b8063afcb95d7146104a8578063b1dc65a4146104c8578063e89d039f146104db57600080fd5b80638da5cb5b116100bd5780638da5cb5b1461044d578063a7206cd614610475578063ad7a22f81461049557600080fd5b806379ba50971461040d57806381ff7048146104155780638456cb591461044557600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb14610391578063666cab8d146103b95780637437ff9f146103ce57600080fd5b806332048875146103565780633f4ba83a146103775780634120fccd1461037f57600080fd5b8063181f5a7711610176578063181f5a77146102e55780631ef381741461032e57806329b980e41461034357600080fd5b806306285c691461019257806310c374ed146102b5575b600080fd5b61029f60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102ac9190612583565b60405180910390f35b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102ac565b6103216040518060400160405280601581526020017f436f6d6d697453746f726520312e352e302d646576000000000000000000000081525081565b6040516102ac9190612640565b61034161033c366004612897565b61051c565b005b610341610351366004612964565b610c00565b6103696103643660046129d7565b610c90565b6040519081526020016102ac565b610341610d86565b60095467ffffffffffffffff166102cc565b6009546d0100000000000000000000000000900460ff165b60405190151581526020016102ac565b6103c1610dec565b6040516102ac9190612a9d565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102ac565b610341610e5b565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102ac565b610341610f58565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102ac565b610369610483366004612ab0565b6000908152600a602052604090205490565b6103416104a3366004612ac9565b610fc8565b6040805160018152600060208201819052918101919091526060016102ac565b6103416104d6366004612ae4565b611043565b6103a961165a565b6103416104f1366004612bc9565b61176e565b610341610504366004612be6565b611782565b6103a9610517366004612ab0565b611819565b855185518560ff16601f83111561056b5760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b60405180910390fd5b806000036105a85760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b8183146105e45760046040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b6105ef816003612cc7565b831161062a5760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b6106326118ed565b61063b86611970565b60065460005b8181101561072f57600560006006838154811061066057610660612cde565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600780546005929190849081106106d0576106d0612cde565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600101610641565b50895160005b81811015610aa85760008c828151811061075157610751612cde565b602002602001015190506000600281111561076e5761076e612c28565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff1660028111156107ad576107ad612c28565b146107e75760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b73ffffffffffffffffffffffffffffffffffffffff8116610834576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156108e4576108e4612c28565b021790555090505060008c838151811061090057610900612cde565b602002602001015190506000600281111561091d5761091d612c28565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561095c5761095c612c28565b146109965760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b73ffffffffffffffffffffffffffffffffffffffff81166109e3576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610a9357610a93612c28565b02179055509050505050806001019050610735565b508a51610abc9060069060208e01906124c5565b508951610ad09060079060208d01906124c5565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610b56914691309190600090610b289063ffffffff16612d0d565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611b20565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610bea99989796959493929190612d30565b60405180910390a1505050505050505050505050565b610c086118ed565b6009805464ffffffffff838116680100000000000000008181027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff85161790945560408051949093049091168084526020840191909152917ff0d557bfce33e354b41885eb9264448726cfe51f486ffa69809d2bf56545644491015b60405180910390a15050565b6009546000906d0100000000000000000000000000900460ff1615610ce1576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d5287878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250611bcb915050565b9050610d5d81611819565b610d6b576000915050610d7d565b6000908152600a602052604090205490505b95945050505050565b610d8e6118ed565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610e5157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e26575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314610edc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610562565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610f606118ed565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610de2565b610fd06118ed565b6009805467ffffffffffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168117909355604080519190921680825260208201939093527fea59e8027e41fda1525220008cf2416797405065eb21b0ebd417bfc6d361b8de9101610c84565b611052878760208b0135611eec565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146110c55780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610562565b467f000000000000000000000000000000000000000000000000000000000000000014611146576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610562565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f0000000000000000000000000000000000000000000000000000000000000000156111e8576002826020015183604001516111c99190612dc6565b6111d39190612ddf565b6111de906001612dc6565b60ff1690506111fe565b60208201516111f8906001612dc6565b60ff1690505b868114611237576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514611270576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156112b3576112b3612c28565b60028111156112c4576112c4612c28565b90525090506002816020015160028111156112e1576112e1612c28565b14801561132857506007816000015160ff168154811061130357611303612cde565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b61135e576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061136c866020612cc7565b611377896020612cc7565b6113838c610144612e28565b61138d9190612e28565b6113979190612e28565b90503681146113db576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610562565b5060008a8a6040516113ee929190612e3b565b604051908190038120611405918e90602001612e4b565b60405160208183030381529060405280519060200120905061142561254f565b8860005b818110156116495760006001858a846020811061144857611448612cde565b61145591901a601b612dc6565b8f8f8681811061146757611467612cde565b905060200201358e8e8781811061148057611480612cde565b90506020020135604051600081526020016040526040516114bd949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156114df573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561156257611562612c28565b600281111561157357611573612c28565b905250905060018160200151600281111561159057611590612c28565b146115c7576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f81106115de576115de612cde565b60200201511561161a576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061163557611635612cde565b911515602090920201525050600101611429565b505050505050505050505050505050565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611724573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117489190612e5f565b15801561176957506009546d0100000000000000000000000000900460ff16155b905090565b6117766118ed565b61177f81612355565b50565b61178a6118ed565b60005b818110156118145760008383838181106117a9576117a9612cde565b9050602002013590506117bb81611819565b61180b576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12906118029083815260200190565b60405180910390a15b5060010161178d565b505050565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156118c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e79190612e5f565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461196e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610562565b565b6000818060200190518101906119869190612e81565b805190915073ffffffffffffffffffffffffffffffffffffffff166119d7576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391610c84918490612ecd565b6000808a8a8a8a8a8a8a8a8a604051602001611b4499989796959493929190612f4a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303611c0c576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590611c2057506101018111155b611c56576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115611cb7576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611ce45786600081518110611cd257611cd2612cde565b60200260200101519350505050611ee5565b60008167ffffffffffffffff811115611cff57611cff612653565b604051908082528060200260200182016040528015611d28578160200160208202803683370190505b50905060008080805b85811015611e6b5760006001821b8b811603611d8c5788851015611d75578c5160018601958e918110611d6657611d66612cde565b60200260200101519050611dae565b8551600185019487918110611d6657611d66612cde565b8b5160018401938d918110611da357611da3612cde565b602002602001015190505b600089861015611dde578d5160018701968f918110611dcf57611dcf612cde565b60200260200101519050611e00565b8651600186019588918110611df557611df5612cde565b602002602001015190505b82851115611e3a576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e44828261244a565b878481518110611e5657611e56612cde565b60209081029190910101525050600101611d31565b506001850382148015611e7d57508683145b8015611e8857508581145b611ebe576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836001860381518110611ed357611ed3612cde565b60200260200101519750505050505050505b9392505050565b6009546d0100000000000000000000000000900460ff1615611f3a576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612001573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120259190612e5f565b1561205c576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061206a838501856130d6565b8051515190915015158061208357508051602001515115155b156121bb5760095464ffffffffff8084166801000000000000000090920416101561218057600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f9161213a91600401613329565b600060405180830381600087803b15801561215457600080fd5b505af1158015612168573d6000803e3d6000fd5b50505050604081015161217b5750505050565b6121bb565b60408101516121bb576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff90811691161415806121f6575060208082015190810151905167ffffffffffffffff9182169116115b156122335780602001516040517fbb1ae18d000000000000000000000000000000000000000000000000000000008152600401610562919061333c565b604081015161226e576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a6020522054156122b7576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015101516122ca906001613361565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf590612347908390613389565b60405180910390a150505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036123d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610562565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081831061248c5760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120611ee5565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120611ee5565b82805482825590600052602060002090810192821561253f579160200282015b8281111561253f57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906124e5565b5061254b92915061256e565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561254b576000815560010161256f565b608081016118e7828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b81811015612602576020818501810151868301820152016125e6565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611ee560208301846125dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156126a5576126a5612653565b60405290565b6040516060810167ffffffffffffffff811182821017156126a5576126a5612653565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561271557612715612653565b604052919050565b600067ffffffffffffffff82111561273757612737612653565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461177f57600080fd5b600082601f83011261277457600080fd5b813560206127896127848361271d565b6126ce565b8083825260208201915060208460051b8701019350868411156127ab57600080fd5b602086015b848110156127d05780356127c381612741565b83529183019183016127b0565b509695505050505050565b803560ff811681146127ec57600080fd5b919050565b600082601f83011261280257600080fd5b813567ffffffffffffffff81111561281c5761281c612653565b61284d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016126ce565b81815284602083860101111561286257600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146127ec57600080fd5b60008060008060008060c087890312156128b057600080fd5b863567ffffffffffffffff808211156128c857600080fd5b6128d48a838b01612763565b975060208901359150808211156128ea57600080fd5b6128f68a838b01612763565b965061290460408a016127db565b9550606089013591508082111561291a57600080fd5b6129268a838b016127f1565b945061293460808a0161287f565b935060a089013591508082111561294a57600080fd5b5061295789828a016127f1565b9150509295509295509295565b60006020828403121561297657600080fd5b813564ffffffffff81168114611ee557600080fd5b60008083601f84011261299d57600080fd5b50813567ffffffffffffffff8111156129b557600080fd5b6020830191508360208260051b85010111156129d057600080fd5b9250929050565b6000806000806000606086880312156129ef57600080fd5b853567ffffffffffffffff80821115612a0757600080fd5b612a1389838a0161298b565b90975095506020880135915080821115612a2c57600080fd5b50612a398882890161298b565b96999598509660400135949350505050565b60008151808452602080850194506020840160005b83811015612a9257815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612a60565b509495945050505050565b602081526000611ee56020830184612a4b565b600060208284031215612ac257600080fd5b5035919050565b600060208284031215612adb57600080fd5b611ee58261287f565b60008060008060008060008060e0898b031215612b0057600080fd5b606089018a811115612b1157600080fd5b8998503567ffffffffffffffff80821115612b2b57600080fd5b818b0191508b601f830112612b3f57600080fd5b813581811115612b4e57600080fd5b8c6020828501011115612b6057600080fd5b6020830199508098505060808b0135915080821115612b7e57600080fd5b612b8a8c838d0161298b565b909750955060a08b0135915080821115612ba357600080fd5b50612bb08b828c0161298b565b999c989b50969995989497949560c00135949350505050565b600060208284031215612bdb57600080fd5b8135611ee581612741565b60008060208385031215612bf957600080fd5b823567ffffffffffffffff811115612c1057600080fd5b612c1c8582860161298b565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160058310612c92577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176118e7576118e7612c98565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103612d2657612d26612c98565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612d608184018a612a4b565b90508281036080840152612d748189612a4b565b905060ff871660a084015282810360c0840152612d9181876125dc565b905067ffffffffffffffff851660e0840152828103610100840152612db681856125dc565b9c9b505050505050505050505050565b60ff81811683821601908111156118e7576118e7612c98565b600060ff831680612e19577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b808201808211156118e7576118e7612c98565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612e7157600080fd5b81518015158114611ee557600080fd5b600060208284031215612e9357600080fd5b6040516020810181811067ffffffffffffffff82111715612eb657612eb6612653565b6040528251612ec481612741565b81529392505050565b60a08101612f26828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152612f918285018b612a4b565b91508382036080850152612fa5828a612a4b565b915060ff881660a085015283820360c0850152612fc282886125dc565b90861660e08501528381036101008501529050612db681856125dc565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146127ec57600080fd5b600082601f83011261301c57600080fd5b8135602061302c6127848361271d565b82815260069290921b8401810191818101908684111561304b57600080fd5b8286015b848110156127d057604081890312156130685760008081fd5b613070612682565b6130798261287f565b8152613086858301612fdf565b8186015283529183019160400161304f565b6000604082840312156130aa57600080fd5b6130b2612682565b90506130bd8261287f565b81526130cb6020830161287f565b602082015292915050565b600060208083850312156130e957600080fd5b823567ffffffffffffffff8082111561310157600080fd5b908401906080828703121561311557600080fd5b61311d6126ab565b82358281111561312c57600080fd5b8301604081890381131561313f57600080fd5b613147612682565b82358581111561315657600080fd5b8301601f81018b1361316757600080fd5b80356131756127848261271d565b81815260069190911b8201890190898101908d83111561319457600080fd5b928a01925b828410156131e45785848f0312156131b15760008081fd5b6131b9612682565b84356131c481612741565b81526131d1858d01612fdf565b818d0152825292850192908a0190613199565b8452505050828701359150848211156131fc57600080fd5b6132088a83850161300b565b8188015283525061321d905087848601613098565b93810193909352506060013560408201529392505050565b805160408084528151848201819052600092602091908201906060870190855b818110156132ae578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858401529284019291850191600101613255565b50508583015187820388850152805180835290840192506000918401905b8083101561331d578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858301529284019260019290920191908501906132cc565b50979650505050505050565b602081526000611ee56020830184613235565b604081016118e78284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561338257613382612c98565b5092915050565b6020815260008251608060208401526133a560a0840182613235565b905060208401516133d06040850182805167ffffffffffffffff908116835260209182015116910152565b5060408401516080840152809150509291505056fea164736f6c6343000818000a", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b506040516200378e3803806200378e8339810160408190526200004d9162000272565b600033808281620000a55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d857620000d88162000192565b50505015156080524660a05260408101516001600160a01b0316158062000107575080516001600160401b0316155b806200011e575060208101516001600160401b0316155b8062000135575060608101516001600160a01b0316155b156200015457604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b0390811661010052606090910151166101205262000306565b336001600160a01b03821603620001ec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025557600080fd5b919050565b80516001600160a01b03811681146200025557600080fd5b6000608082840312156200028557600080fd5b604051608081016001600160401b0381118282101715620002b657634e487b7160e01b600052604160045260246000fd5b604052620002c4836200023d565b8152620002d4602084016200023d565b6020820152620002e7604084016200025a565b6040820152620002fa606084016200025a565b60608201529392505050565b60805160a05160c05160e05161010051610120516133f26200039c60003960008181610262015281816116c80152818161187c01528181611acb0152611fa50152600081816102260152611aa40152600081816101f60152818161168201528181611a7d0152611f620152600081816101c60152611a4e0152600081816110c801526111140152600061118f01526133f26000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806379ba5097116100e3578063afcb95d71161008c578063f2fde38b11610066578063f2fde38b146104e3578063f47a8690146104f6578063ff888fb11461050957600080fd5b8063afcb95d7146104a8578063b1dc65a4146104c8578063e89d039f146104db57600080fd5b80638da5cb5b116100bd5780638da5cb5b1461044d578063a7206cd614610475578063ad7a22f81461049557600080fd5b806379ba50971461040d57806381ff7048146104155780638456cb591461044557600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb14610391578063666cab8d146103b95780637437ff9f146103ce57600080fd5b806332048875146103565780633f4ba83a146103775780634120fccd1461037f57600080fd5b8063181f5a7711610176578063181f5a77146102e55780631ef381741461032e57806329b980e41461034357600080fd5b806306285c691461019257806310c374ed146102b5575b600080fd5b61029f60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102ac9190612583565b60405180910390f35b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102ac565b6103216040518060400160405280601181526020017f436f6d6d697453746f726520312e352e3000000000000000000000000000000081525081565b6040516102ac9190612640565b61034161033c366004612897565b61051c565b005b610341610351366004612964565b610c00565b6103696103643660046129d7565b610c90565b6040519081526020016102ac565b610341610d86565b60095467ffffffffffffffff166102cc565b6009546d0100000000000000000000000000900460ff165b60405190151581526020016102ac565b6103c1610dec565b6040516102ac9190612a9d565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102ac565b610341610e5b565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102ac565b610341610f58565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102ac565b610369610483366004612ab0565b6000908152600a602052604090205490565b6103416104a3366004612ac9565b610fc8565b6040805160018152600060208201819052918101919091526060016102ac565b6103416104d6366004612ae4565b611043565b6103a961165a565b6103416104f1366004612bc9565b61176e565b610341610504366004612be6565b611782565b6103a9610517366004612ab0565b611819565b855185518560ff16601f83111561056b5760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b60405180910390fd5b806000036105a85760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b8183146105e45760046040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b6105ef816003612cc7565b831161062a5760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b6106326118ed565b61063b86611970565b60065460005b8181101561072f57600560006006838154811061066057610660612cde565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600780546005929190849081106106d0576106d0612cde565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600101610641565b50895160005b81811015610aa85760008c828151811061075157610751612cde565b602002602001015190506000600281111561076e5761076e612c28565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff1660028111156107ad576107ad612c28565b146107e75760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b73ffffffffffffffffffffffffffffffffffffffff8116610834576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156108e4576108e4612c28565b021790555090505060008c838151811061090057610900612cde565b602002602001015190506000600281111561091d5761091d612c28565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561095c5761095c612c28565b146109965760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105629190612c57565b73ffffffffffffffffffffffffffffffffffffffff81166109e3576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610a9357610a93612c28565b02179055509050505050806001019050610735565b508a51610abc9060069060208e01906124c5565b508951610ad09060079060208d01906124c5565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610b56914691309190600090610b289063ffffffff16612d0d565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611b20565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610bea99989796959493929190612d30565b60405180910390a1505050505050505050505050565b610c086118ed565b6009805464ffffffffff838116680100000000000000008181027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff85161790945560408051949093049091168084526020840191909152917ff0d557bfce33e354b41885eb9264448726cfe51f486ffa69809d2bf56545644491015b60405180910390a15050565b6009546000906d0100000000000000000000000000900460ff1615610ce1576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d5287878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250611bcb915050565b9050610d5d81611819565b610d6b576000915050610d7d565b6000908152600a602052604090205490505b95945050505050565b610d8e6118ed565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610e5157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e26575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314610edc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610562565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610f606118ed565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610de2565b610fd06118ed565b6009805467ffffffffffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168117909355604080519190921680825260208201939093527fea59e8027e41fda1525220008cf2416797405065eb21b0ebd417bfc6d361b8de9101610c84565b611052878760208b0135611eec565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146110c55780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610562565b467f000000000000000000000000000000000000000000000000000000000000000014611146576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610562565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f0000000000000000000000000000000000000000000000000000000000000000156111e8576002826020015183604001516111c99190612dc6565b6111d39190612ddf565b6111de906001612dc6565b60ff1690506111fe565b60208201516111f8906001612dc6565b60ff1690505b868114611237576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514611270576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156112b3576112b3612c28565b60028111156112c4576112c4612c28565b90525090506002816020015160028111156112e1576112e1612c28565b14801561132857506007816000015160ff168154811061130357611303612cde565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b61135e576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061136c866020612cc7565b611377896020612cc7565b6113838c610144612e28565b61138d9190612e28565b6113979190612e28565b90503681146113db576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610562565b5060008a8a6040516113ee929190612e3b565b604051908190038120611405918e90602001612e4b565b60405160208183030381529060405280519060200120905061142561254f565b8860005b818110156116495760006001858a846020811061144857611448612cde565b61145591901a601b612dc6565b8f8f8681811061146757611467612cde565b905060200201358e8e8781811061148057611480612cde565b90506020020135604051600081526020016040526040516114bd949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156114df573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561156257611562612c28565b600281111561157357611573612c28565b905250905060018160200151600281111561159057611590612c28565b146115c7576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f81106115de576115de612cde565b60200201511561161a576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061163557611635612cde565b911515602090920201525050600101611429565b505050505050505050505050505050565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611724573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117489190612e5f565b15801561176957506009546d0100000000000000000000000000900460ff16155b905090565b6117766118ed565b61177f81612355565b50565b61178a6118ed565b60005b818110156118145760008383838181106117a9576117a9612cde565b9050602002013590506117bb81611819565b61180b576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12906118029083815260200190565b60405180910390a15b5060010161178d565b505050565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156118c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e79190612e5f565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461196e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610562565b565b6000818060200190518101906119869190612e81565b805190915073ffffffffffffffffffffffffffffffffffffffff166119d7576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391610c84918490612ecd565b6000808a8a8a8a8a8a8a8a8a604051602001611b4499989796959493929190612f4a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303611c0c576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590611c2057506101018111155b611c56576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115611cb7576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611ce45786600081518110611cd257611cd2612cde565b60200260200101519350505050611ee5565b60008167ffffffffffffffff811115611cff57611cff612653565b604051908082528060200260200182016040528015611d28578160200160208202803683370190505b50905060008080805b85811015611e6b5760006001821b8b811603611d8c5788851015611d75578c5160018601958e918110611d6657611d66612cde565b60200260200101519050611dae565b8551600185019487918110611d6657611d66612cde565b8b5160018401938d918110611da357611da3612cde565b602002602001015190505b600089861015611dde578d5160018701968f918110611dcf57611dcf612cde565b60200260200101519050611e00565b8651600186019588918110611df557611df5612cde565b602002602001015190505b82851115611e3a576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e44828261244a565b878481518110611e5657611e56612cde565b60209081029190910101525050600101611d31565b506001850382148015611e7d57508683145b8015611e8857508581145b611ebe576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836001860381518110611ed357611ed3612cde565b60200260200101519750505050505050505b9392505050565b6009546d0100000000000000000000000000900460ff1615611f3a576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612001573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120259190612e5f565b1561205c576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061206a838501856130d6565b8051515190915015158061208357508051602001515115155b156121bb5760095464ffffffffff8084166801000000000000000090920416101561218057600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f9161213a91600401613329565b600060405180830381600087803b15801561215457600080fd5b505af1158015612168573d6000803e3d6000fd5b50505050604081015161217b5750505050565b6121bb565b60408101516121bb576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff90811691161415806121f6575060208082015190810151905167ffffffffffffffff9182169116115b156122335780602001516040517fbb1ae18d000000000000000000000000000000000000000000000000000000008152600401610562919061333c565b604081015161226e576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a6020522054156122b7576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015101516122ca906001613361565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf590612347908390613389565b60405180910390a150505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036123d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610562565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081831061248c5760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120611ee5565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120611ee5565b82805482825590600052602060002090810192821561253f579160200282015b8281111561253f57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906124e5565b5061254b92915061256e565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561254b576000815560010161256f565b608081016118e7828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b81811015612602576020818501810151868301820152016125e6565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611ee560208301846125dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156126a5576126a5612653565b60405290565b6040516060810167ffffffffffffffff811182821017156126a5576126a5612653565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561271557612715612653565b604052919050565b600067ffffffffffffffff82111561273757612737612653565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461177f57600080fd5b600082601f83011261277457600080fd5b813560206127896127848361271d565b6126ce565b8083825260208201915060208460051b8701019350868411156127ab57600080fd5b602086015b848110156127d05780356127c381612741565b83529183019183016127b0565b509695505050505050565b803560ff811681146127ec57600080fd5b919050565b600082601f83011261280257600080fd5b813567ffffffffffffffff81111561281c5761281c612653565b61284d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016126ce565b81815284602083860101111561286257600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146127ec57600080fd5b60008060008060008060c087890312156128b057600080fd5b863567ffffffffffffffff808211156128c857600080fd5b6128d48a838b01612763565b975060208901359150808211156128ea57600080fd5b6128f68a838b01612763565b965061290460408a016127db565b9550606089013591508082111561291a57600080fd5b6129268a838b016127f1565b945061293460808a0161287f565b935060a089013591508082111561294a57600080fd5b5061295789828a016127f1565b9150509295509295509295565b60006020828403121561297657600080fd5b813564ffffffffff81168114611ee557600080fd5b60008083601f84011261299d57600080fd5b50813567ffffffffffffffff8111156129b557600080fd5b6020830191508360208260051b85010111156129d057600080fd5b9250929050565b6000806000806000606086880312156129ef57600080fd5b853567ffffffffffffffff80821115612a0757600080fd5b612a1389838a0161298b565b90975095506020880135915080821115612a2c57600080fd5b50612a398882890161298b565b96999598509660400135949350505050565b60008151808452602080850194506020840160005b83811015612a9257815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612a60565b509495945050505050565b602081526000611ee56020830184612a4b565b600060208284031215612ac257600080fd5b5035919050565b600060208284031215612adb57600080fd5b611ee58261287f565b60008060008060008060008060e0898b031215612b0057600080fd5b606089018a811115612b1157600080fd5b8998503567ffffffffffffffff80821115612b2b57600080fd5b818b0191508b601f830112612b3f57600080fd5b813581811115612b4e57600080fd5b8c6020828501011115612b6057600080fd5b6020830199508098505060808b0135915080821115612b7e57600080fd5b612b8a8c838d0161298b565b909750955060a08b0135915080821115612ba357600080fd5b50612bb08b828c0161298b565b999c989b50969995989497949560c00135949350505050565b600060208284031215612bdb57600080fd5b8135611ee581612741565b60008060208385031215612bf957600080fd5b823567ffffffffffffffff811115612c1057600080fd5b612c1c8582860161298b565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160058310612c92577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176118e7576118e7612c98565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103612d2657612d26612c98565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612d608184018a612a4b565b90508281036080840152612d748189612a4b565b905060ff871660a084015282810360c0840152612d9181876125dc565b905067ffffffffffffffff851660e0840152828103610100840152612db681856125dc565b9c9b505050505050505050505050565b60ff81811683821601908111156118e7576118e7612c98565b600060ff831680612e19577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b808201808211156118e7576118e7612c98565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612e7157600080fd5b81518015158114611ee557600080fd5b600060208284031215612e9357600080fd5b6040516020810181811067ffffffffffffffff82111715612eb657612eb6612653565b6040528251612ec481612741565b81529392505050565b60a08101612f26828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152612f918285018b612a4b565b91508382036080850152612fa5828a612a4b565b915060ff881660a085015283820360c0850152612fc282886125dc565b90861660e08501528381036101008501529050612db681856125dc565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146127ec57600080fd5b600082601f83011261301c57600080fd5b8135602061302c6127848361271d565b82815260069290921b8401810191818101908684111561304b57600080fd5b8286015b848110156127d057604081890312156130685760008081fd5b613070612682565b6130798261287f565b8152613086858301612fdf565b8186015283529183019160400161304f565b6000604082840312156130aa57600080fd5b6130b2612682565b90506130bd8261287f565b81526130cb6020830161287f565b602082015292915050565b600060208083850312156130e957600080fd5b823567ffffffffffffffff8082111561310157600080fd5b908401906080828703121561311557600080fd5b61311d6126ab565b82358281111561312c57600080fd5b8301604081890381131561313f57600080fd5b613147612682565b82358581111561315657600080fd5b8301601f81018b1361316757600080fd5b80356131756127848261271d565b81815260069190911b8201890190898101908d83111561319457600080fd5b928a01925b828410156131e45785848f0312156131b15760008081fd5b6131b9612682565b84356131c481612741565b81526131d1858d01612fdf565b818d0152825292850192908a0190613199565b8452505050828701359150848211156131fc57600080fd5b6132088a83850161300b565b8188015283525061321d905087848601613098565b93810193909352506060013560408201529392505050565b805160408084528151848201819052600092602091908201906060870190855b818110156132ae578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858401529284019291850191600101613255565b50508583015187820388850152805180835290840192506000918401905b8083101561331d578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858301529284019260019290920191908501906132cc565b50979650505050505050565b602081526000611ee56020830184613235565b604081016118e78284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561338257613382612c98565b5092915050565b6020815260008251608060208401526133a560a0840182613235565b905060208401516133d06040850182805167ffffffffffffffff908116835260209182015116910152565b5060408401516080840152809150509291505056fea164736f6c6343000818000a", } var CommitStoreABI = CommitStoreMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go b/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go index b314d6c75b..3c9b22d67d 100644 --- a/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go +++ b/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go @@ -69,7 +69,7 @@ type InternalTokenPriceUpdate struct { var CommitStoreHelperMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"oldEpochAndRound\",\"type\":\"uint40\"},{\"indexed\":false,\"internalType\":\"uint40\",\"name\":\"newEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"LatestPriceEpochAndRoundSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"oldSeqNum\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newSeqNum\",\"type\":\"uint64\"}],\"name\":\"SequenceNumberSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndNotCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"commitReport\",\"type\":\"bytes\"},{\"internalType\":\"uint40\",\"name\":\"epochAndRound\",\"type\":\"uint40\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b506040516200382a3803806200382a8339810160408190526200004d9162000274565b80600033808281620000a65760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d957620000d98162000194565b50505015156080524660a05260408101516001600160a01b0316158062000108575080516001600160401b0316155b806200011f575060208101516001600160401b0316155b8062000136575060608101516001600160a01b0316155b156200015557604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b039081166101005260609091015116610120525062000308565b336001600160a01b03821603620001ee5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025757600080fd5b919050565b80516001600160a01b03811681146200025757600080fd5b6000608082840312156200028757600080fd5b604051608081016001600160401b0381118282101715620002b857634e487b7160e01b600052604160045260246000fd5b604052620002c6836200023f565b8152620002d6602084016200023f565b6020820152620002e9604084016200025c565b6040820152620002fc606084016200025c565b60608201529392505050565b60805160a05160c05160e051610100516101205161348c6200039e6000396000818161026d015281816116f6015281816118a5015281816119cf0152611f5d0152600081816102310152611f36015260008181610201015281816116b00152818161198c0152611f0f0152600081816101d10152611ee00152600081816110f60152611142015260006111bd015261348c6000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806379ba5097116100e3578063afcb95d71161008c578063f2fde38b11610066578063f2fde38b14610501578063f47a869014610514578063ff888fb11461052757600080fd5b8063afcb95d7146104c6578063b1dc65a4146104e6578063e89d039f146104f957600080fd5b80638da5cb5b116100bd5780638da5cb5b1461046b578063a7206cd614610493578063ad7a22f8146104b357600080fd5b806379ba50971461042b57806381ff7048146104335780638456cb591461046357600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb146103af578063666cab8d146103d75780637437ff9f146103ec57600080fd5b806332048875146103745780633f4ba83a146103955780634120fccd1461039d57600080fd5b80631dc18e56116101765780631dc18e56146103395780631ef381741461034e57806329b980e41461036157600080fd5b806306285c691461019d57806310c374ed146102c0578063181f5a77146102f0575b600080fd5b6102aa60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102b791906125ac565b60405180910390f35b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102b7565b61032c6040518060400160405280601581526020017f436f6d6d697453746f726520312e352e302d646576000000000000000000000081525081565b6040516102b79190612669565b61034c6103473660046126df565b61053a565b005b61034c61035c366004612972565b61054a565b61034c61036f366004612a3f565b610c2e565b610387610382366004612a9f565b610cbe565b6040519081526020016102b7565b61034c610db4565b60095467ffffffffffffffff166102d7565b6009546d0100000000000000000000000000900460ff165b60405190151581526020016102b7565b6103df610e1a565b6040516102b79190612b65565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102b7565b61034c610e89565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102b7565b61034c610f86565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b7565b6103876104a1366004612b78565b6000908152600a602052604090205490565b61034c6104c1366004612b91565b610ff6565b6040805160018152600060208201819052918101919091526060016102b7565b61034c6104f4366004612bac565b611071565b6103c7611688565b61034c61050f366004612c63565b61179c565b61034c610522366004612c80565b6117b0565b6103c7610535366004612b78565b611842565b610545838383611916565b505050565b855185518560ff16601f8311156105995760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b60405180910390fd5b806000036105d65760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b8183146106125760046040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b61061d816003612d61565b83116106585760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b610660611d7f565b61066986611e02565b60065460005b8181101561075d57600560006006838154811061068e5761068e612d78565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600780546005929190849081106106fe576106fe612d78565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161066f565b50895160005b81811015610ad65760008c828151811061077f5761077f612d78565b602002602001015190506000600281111561079c5761079c612cc2565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff1660028111156107db576107db612cc2565b146108155760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b73ffffffffffffffffffffffffffffffffffffffff8116610862576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561091257610912612cc2565b021790555090505060008c838151811061092e5761092e612d78565b602002602001015190506000600281111561094b5761094b612cc2565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561098a5761098a612cc2565b146109c45760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b73ffffffffffffffffffffffffffffffffffffffff8116610a11576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ac157610ac1612cc2565b02179055509050505050806001019050610763565b508a51610aea9060069060208e01906124ee565b508951610afe9060079060208d01906124ee565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610b84914691309190600090610b569063ffffffff16612da7565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611fb2565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610c1899989796959493929190612dca565b60405180910390a1505050505050505050505050565b610c36611d7f565b6009805464ffffffffff838116680100000000000000008181027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff85161790945560408051949093049091168084526020840191909152917ff0d557bfce33e354b41885eb9264448726cfe51f486ffa69809d2bf56545644491015b60405180910390a15050565b6009546000906d0100000000000000000000000000900460ff1615610d0f576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d8087878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a92508991829185019084908082843760009201919091525088925061205d915050565b9050610d8b81611842565b610d99576000915050610dab565b6000908152600a602052604090205490505b95945050505050565b610dbc611d7f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610e7f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e54575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610590565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610f8e611d7f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610e10565b610ffe611d7f565b6009805467ffffffffffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168117909355604080519190921680825260208201939093527fea59e8027e41fda1525220008cf2416797405065eb21b0ebd417bfc6d361b8de9101610cb2565b611080878760208b0135611916565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146110f35780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610590565b467f000000000000000000000000000000000000000000000000000000000000000014611174576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610590565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f000000000000000000000000000000000000000000000000000000000000000015611216576002826020015183604001516111f79190612e60565b6112019190612e79565b61120c906001612e60565b60ff16905061122c565b6020820151611226906001612e60565b60ff1690505b868114611265576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86851461129e576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156112e1576112e1612cc2565b60028111156112f2576112f2612cc2565b905250905060028160200151600281111561130f5761130f612cc2565b14801561135657506007816000015160ff168154811061133157611331612d78565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b61138c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061139a866020612d61565b6113a5896020612d61565b6113b18c610144612ec2565b6113bb9190612ec2565b6113c59190612ec2565b9050368114611409576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610590565b5060008a8a60405161141c929190612ed5565b604051908190038120611433918e90602001612ee5565b604051602081830303815290604052805190602001209050611453612578565b8860005b818110156116775760006001858a846020811061147657611476612d78565b61148391901a601b612e60565b8f8f8681811061149557611495612d78565b905060200201358e8e878181106114ae576114ae612d78565b90506020020135604051600081526020016040526040516114eb949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561150d573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561159057611590612cc2565b60028111156115a1576115a1612cc2565b90525090506001816020015160028111156115be576115be612cc2565b146115f5576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061160c5761160c612d78565b602002015115611648576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061166357611663612d78565b911515602090920201525050600101611457565b505050505050505050505050505050565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611752573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117769190612ef9565b15801561179757506009546d0100000000000000000000000000900460ff16155b905090565b6117a4611d7f565b6117ad8161237e565b50565b6117b8611d7f565b60005b818110156105455760008383838181106117d7576117d7612d78565b9050602002013590506117e981611842565b611839576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12906118309083815260200190565b60405180910390a15b506001016117bb565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156118ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119109190612ef9565b92915050565b6009546d0100000000000000000000000000900460ff1615611964576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4f9190612ef9565b15611a86576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611a9483850185613012565b80515151909150151580611aad57508051602001515115155b15611be55760095464ffffffffff80841668010000000000000000909204161015611baa57600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f91611b6491600401613265565b600060405180830381600087803b158015611b7e57600080fd5b505af1158015611b92573d6000803e3d6000fd5b505050506040810151611ba55750505050565b611be5565b6040810151611be5576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff9081169116141580611c20575060208082015190810151905167ffffffffffffffff9182169116115b15611c5d5780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016105909190613278565b6040810151611c98576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415611ce1576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201510151611cf490600161329d565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf590611d719083906132c5565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611e00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610590565b565b600081806020019051810190611e189190613321565b805190915073ffffffffffffffffffffffffffffffffffffffff16611e69576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391610cb291849061336d565b6000808a8a8a8a8a8a8a8a8a604051602001611fd6999897969594939291906133ea565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b825182516000919081830361209e576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010182118015906120b257506101018111155b6120e8576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115612149576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003612176578660008151811061216457612164612d78565b60200260200101519350505050612377565b60008167ffffffffffffffff81111561219157612191612733565b6040519080825280602002602001820160405280156121ba578160200160208202803683370190505b50905060008080805b858110156122fd5760006001821b8b81160361221e5788851015612207578c5160018601958e9181106121f8576121f8612d78565b60200260200101519050612240565b85516001850194879181106121f8576121f8612d78565b8b5160018401938d91811061223557612235612d78565b602002602001015190505b600089861015612270578d5160018701968f91811061226157612261612d78565b60200260200101519050612292565b865160018601958891811061228757612287612d78565b602002602001015190505b828511156122cc576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122d68282612473565b8784815181106122e8576122e8612d78565b602090810291909101015250506001016121c3565b50600185038214801561230f57508683145b801561231a57508581145b612350576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061236557612365612d78565b60200260200101519750505050505050505b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036123fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610590565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008183106124b55760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612377565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612377565b828054828255906000526020600020908101928215612568579160200282015b8281111561256857825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061250e565b50612574929150612597565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b808211156125745760008155600101612598565b60808101611910828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b8181101561262b5760208185018101518683018201520161260f565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006123776020830184612605565b60008083601f84011261268e57600080fd5b50813567ffffffffffffffff8111156126a657600080fd5b6020830191508360208285010111156126be57600080fd5b9250929050565b803564ffffffffff811681146126da57600080fd5b919050565b6000806000604084860312156126f457600080fd5b833567ffffffffffffffff81111561270b57600080fd5b6127178682870161267c565b909450925061272a9050602085016126c5565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561278557612785612733565b60405290565b6040516060810167ffffffffffffffff8111828210171561278557612785612733565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127f5576127f5612733565b604052919050565b600067ffffffffffffffff82111561281757612817612733565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146117ad57600080fd5b600082601f83011261285457600080fd5b81356020612869612864836127fd565b6127ae565b8083825260208201915060208460051b87010193508684111561288b57600080fd5b602086015b848110156128b05780356128a381612821565b8352918301918301612890565b509695505050505050565b803560ff811681146126da57600080fd5b600082601f8301126128dd57600080fd5b813567ffffffffffffffff8111156128f7576128f7612733565b61292860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127ae565b81815284602083860101111561293d57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146126da57600080fd5b60008060008060008060c0878903121561298b57600080fd5b863567ffffffffffffffff808211156129a357600080fd5b6129af8a838b01612843565b975060208901359150808211156129c557600080fd5b6129d18a838b01612843565b96506129df60408a016128bb565b955060608901359150808211156129f557600080fd5b612a018a838b016128cc565b9450612a0f60808a0161295a565b935060a0890135915080821115612a2557600080fd5b50612a3289828a016128cc565b9150509295509295509295565b600060208284031215612a5157600080fd5b612377826126c5565b60008083601f840112612a6c57600080fd5b50813567ffffffffffffffff811115612a8457600080fd5b6020830191508360208260051b85010111156126be57600080fd5b600080600080600060608688031215612ab757600080fd5b853567ffffffffffffffff80821115612acf57600080fd5b612adb89838a01612a5a565b90975095506020880135915080821115612af457600080fd5b50612b0188828901612a5a565b96999598509660400135949350505050565b60008151808452602080850194506020840160005b83811015612b5a57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612b28565b509495945050505050565b6020815260006123776020830184612b13565b600060208284031215612b8a57600080fd5b5035919050565b600060208284031215612ba357600080fd5b6123778261295a565b60008060008060008060008060e0898b031215612bc857600080fd5b606089018a811115612bd957600080fd5b8998503567ffffffffffffffff80821115612bf357600080fd5b612bff8c838d0161267c565b909950975060808b0135915080821115612c1857600080fd5b612c248c838d01612a5a565b909750955060a08b0135915080821115612c3d57600080fd5b50612c4a8b828c01612a5a565b999c989b50969995989497949560c00135949350505050565b600060208284031215612c7557600080fd5b813561237781612821565b60008060208385031215612c9357600080fd5b823567ffffffffffffffff811115612caa57600080fd5b612cb685828601612a5a565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160058310612d2c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761191057611910612d32565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103612dc057612dc0612d32565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612dfa8184018a612b13565b90508281036080840152612e0e8189612b13565b905060ff871660a084015282810360c0840152612e2b8187612605565b905067ffffffffffffffff851660e0840152828103610100840152612e508185612605565b9c9b505050505050505050505050565b60ff818116838216019081111561191057611910612d32565b600060ff831680612eb3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b8082018082111561191057611910612d32565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612f0b57600080fd5b8151801515811461237757600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146126da57600080fd5b600082601f830112612f5857600080fd5b81356020612f68612864836127fd565b82815260069290921b84018101918181019086841115612f8757600080fd5b8286015b848110156128b05760408189031215612fa45760008081fd5b612fac612762565b612fb58261295a565b8152612fc2858301612f1b565b81860152835291830191604001612f8b565b600060408284031215612fe657600080fd5b612fee612762565b9050612ff98261295a565b81526130076020830161295a565b602082015292915050565b6000602080838503121561302557600080fd5b823567ffffffffffffffff8082111561303d57600080fd5b908401906080828703121561305157600080fd5b61305961278b565b82358281111561306857600080fd5b8301604081890381131561307b57600080fd5b613083612762565b82358581111561309257600080fd5b8301601f81018b136130a357600080fd5b80356130b1612864826127fd565b81815260069190911b8201890190898101908d8311156130d057600080fd5b928a01925b828410156131205785848f0312156130ed5760008081fd5b6130f5612762565b843561310081612821565b815261310d858d01612f1b565b818d0152825292850192908a01906130d5565b84525050508287013591508482111561313857600080fd5b6131448a838501612f47565b81880152835250613159905087848601612fd4565b93810193909352506060013560408201529392505050565b805160408084528151848201819052600092602091908201906060870190855b818110156131ea578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858401529284019291850191600101613191565b50508583015187820388850152805180835290840192506000918401905b80831015613259578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685830152928401926001929092019190850190613208565b50979650505050505050565b6020815260006123776020830184613171565b604081016119108284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff8181168382160190808211156132be576132be612d32565b5092915050565b6020815260008251608060208401526132e160a0840182613171565b9050602084015161330c6040850182805167ffffffffffffffff908116835260209182015116910152565b50604084015160808401528091505092915050565b60006020828403121561333357600080fd5b6040516020810181811067ffffffffffffffff8211171561335657613356612733565b604052825161336481612821565b81529392505050565b60a081016133c6828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526134318285018b612b13565b91508382036080850152613445828a612b13565b915060ff881660a085015283820360c08501526134628288612605565b90861660e08501528381036101008501529050612e50818561260556fea164736f6c6343000818000a", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b506040516200382a3803806200382a8339810160408190526200004d9162000274565b80600033808281620000a65760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d957620000d98162000194565b50505015156080524660a05260408101516001600160a01b0316158062000108575080516001600160401b0316155b806200011f575060208101516001600160401b0316155b8062000136575060608101516001600160a01b0316155b156200015557604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b039081166101005260609091015116610120525062000308565b336001600160a01b03821603620001ee5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025757600080fd5b919050565b80516001600160a01b03811681146200025757600080fd5b6000608082840312156200028757600080fd5b604051608081016001600160401b0381118282101715620002b857634e487b7160e01b600052604160045260246000fd5b604052620002c6836200023f565b8152620002d6602084016200023f565b6020820152620002e9604084016200025c565b6040820152620002fc606084016200025c565b60608201529392505050565b60805160a05160c05160e051610100516101205161348c6200039e6000396000818161026d015281816116f6015281816118a5015281816119cf0152611f5d0152600081816102310152611f36015260008181610201015281816116b00152818161198c0152611f0f0152600081816101d10152611ee00152600081816110f60152611142015260006111bd015261348c6000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806379ba5097116100e3578063afcb95d71161008c578063f2fde38b11610066578063f2fde38b14610501578063f47a869014610514578063ff888fb11461052757600080fd5b8063afcb95d7146104c6578063b1dc65a4146104e6578063e89d039f146104f957600080fd5b80638da5cb5b116100bd5780638da5cb5b1461046b578063a7206cd614610493578063ad7a22f8146104b357600080fd5b806379ba50971461042b57806381ff7048146104335780638456cb591461046357600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb146103af578063666cab8d146103d75780637437ff9f146103ec57600080fd5b806332048875146103745780633f4ba83a146103955780634120fccd1461039d57600080fd5b80631dc18e56116101765780631dc18e56146103395780631ef381741461034e57806329b980e41461036157600080fd5b806306285c691461019d57806310c374ed146102c0578063181f5a77146102f0575b600080fd5b6102aa60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102b791906125ac565b60405180910390f35b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102b7565b61032c6040518060400160405280601181526020017f436f6d6d697453746f726520312e352e3000000000000000000000000000000081525081565b6040516102b79190612669565b61034c6103473660046126df565b61053a565b005b61034c61035c366004612972565b61054a565b61034c61036f366004612a3f565b610c2e565b610387610382366004612a9f565b610cbe565b6040519081526020016102b7565b61034c610db4565b60095467ffffffffffffffff166102d7565b6009546d0100000000000000000000000000900460ff165b60405190151581526020016102b7565b6103df610e1a565b6040516102b79190612b65565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102b7565b61034c610e89565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102b7565b61034c610f86565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b7565b6103876104a1366004612b78565b6000908152600a602052604090205490565b61034c6104c1366004612b91565b610ff6565b6040805160018152600060208201819052918101919091526060016102b7565b61034c6104f4366004612bac565b611071565b6103c7611688565b61034c61050f366004612c63565b61179c565b61034c610522366004612c80565b6117b0565b6103c7610535366004612b78565b611842565b610545838383611916565b505050565b855185518560ff16601f8311156105995760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b60405180910390fd5b806000036105d65760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b8183146106125760046040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b61061d816003612d61565b83116106585760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b610660611d7f565b61066986611e02565b60065460005b8181101561075d57600560006006838154811061068e5761068e612d78565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600780546005929190849081106106fe576106fe612d78565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161066f565b50895160005b81811015610ad65760008c828151811061077f5761077f612d78565b602002602001015190506000600281111561079c5761079c612cc2565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff1660028111156107db576107db612cc2565b146108155760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b73ffffffffffffffffffffffffffffffffffffffff8116610862576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561091257610912612cc2565b021790555090505060008c838151811061092e5761092e612d78565b602002602001015190506000600281111561094b5761094b612cc2565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561098a5761098a612cc2565b146109c45760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016105909190612cf1565b73ffffffffffffffffffffffffffffffffffffffff8116610a11576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ac157610ac1612cc2565b02179055509050505050806001019050610763565b508a51610aea9060069060208e01906124ee565b508951610afe9060079060208d01906124ee565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610b84914691309190600090610b569063ffffffff16612da7565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611fb2565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610c1899989796959493929190612dca565b60405180910390a1505050505050505050505050565b610c36611d7f565b6009805464ffffffffff838116680100000000000000008181027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff85161790945560408051949093049091168084526020840191909152917ff0d557bfce33e354b41885eb9264448726cfe51f486ffa69809d2bf56545644491015b60405180910390a15050565b6009546000906d0100000000000000000000000000900460ff1615610d0f576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d8087878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a92508991829185019084908082843760009201919091525088925061205d915050565b9050610d8b81611842565b610d99576000915050610dab565b6000908152600a602052604090205490505b95945050505050565b610dbc611d7f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610e7f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e54575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610590565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610f8e611d7f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610e10565b610ffe611d7f565b6009805467ffffffffffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168117909355604080519190921680825260208201939093527fea59e8027e41fda1525220008cf2416797405065eb21b0ebd417bfc6d361b8de9101610cb2565b611080878760208b0135611916565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146110f35780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610590565b467f000000000000000000000000000000000000000000000000000000000000000014611174576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610590565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f000000000000000000000000000000000000000000000000000000000000000015611216576002826020015183604001516111f79190612e60565b6112019190612e79565b61120c906001612e60565b60ff16905061122c565b6020820151611226906001612e60565b60ff1690505b868114611265576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86851461129e576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156112e1576112e1612cc2565b60028111156112f2576112f2612cc2565b905250905060028160200151600281111561130f5761130f612cc2565b14801561135657506007816000015160ff168154811061133157611331612d78565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b61138c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061139a866020612d61565b6113a5896020612d61565b6113b18c610144612ec2565b6113bb9190612ec2565b6113c59190612ec2565b9050368114611409576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610590565b5060008a8a60405161141c929190612ed5565b604051908190038120611433918e90602001612ee5565b604051602081830303815290604052805190602001209050611453612578565b8860005b818110156116775760006001858a846020811061147657611476612d78565b61148391901a601b612e60565b8f8f8681811061149557611495612d78565b905060200201358e8e878181106114ae576114ae612d78565b90506020020135604051600081526020016040526040516114eb949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561150d573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561159057611590612cc2565b60028111156115a1576115a1612cc2565b90525090506001816020015160028111156115be576115be612cc2565b146115f5576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061160c5761160c612d78565b602002015115611648576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061166357611663612d78565b911515602090920201525050600101611457565b505050505050505050505050505050565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611752573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117769190612ef9565b15801561179757506009546d0100000000000000000000000000900460ff16155b905090565b6117a4611d7f565b6117ad8161237e565b50565b6117b8611d7f565b60005b818110156105455760008383838181106117d7576117d7612d78565b9050602002013590506117e981611842565b611839576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12906118309083815260200190565b60405180910390a15b506001016117bb565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156118ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119109190612ef9565b92915050565b6009546d0100000000000000000000000000900460ff1615611964576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4f9190612ef9565b15611a86576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611a9483850185613012565b80515151909150151580611aad57508051602001515115155b15611be55760095464ffffffffff80841668010000000000000000909204161015611baa57600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f91611b6491600401613265565b600060405180830381600087803b158015611b7e57600080fd5b505af1158015611b92573d6000803e3d6000fd5b505050506040810151611ba55750505050565b611be5565b6040810151611be5576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff9081169116141580611c20575060208082015190810151905167ffffffffffffffff9182169116115b15611c5d5780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016105909190613278565b6040810151611c98576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415611ce1576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201510151611cf490600161329d565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf590611d719083906132c5565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611e00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610590565b565b600081806020019051810190611e189190613321565b805190915073ffffffffffffffffffffffffffffffffffffffff16611e69576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391610cb291849061336d565b6000808a8a8a8a8a8a8a8a8a604051602001611fd6999897969594939291906133ea565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b825182516000919081830361209e576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010182118015906120b257506101018111155b6120e8576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115612149576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003612176578660008151811061216457612164612d78565b60200260200101519350505050612377565b60008167ffffffffffffffff81111561219157612191612733565b6040519080825280602002602001820160405280156121ba578160200160208202803683370190505b50905060008080805b858110156122fd5760006001821b8b81160361221e5788851015612207578c5160018601958e9181106121f8576121f8612d78565b60200260200101519050612240565b85516001850194879181106121f8576121f8612d78565b8b5160018401938d91811061223557612235612d78565b602002602001015190505b600089861015612270578d5160018701968f91811061226157612261612d78565b60200260200101519050612292565b865160018601958891811061228757612287612d78565b602002602001015190505b828511156122cc576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122d68282612473565b8784815181106122e8576122e8612d78565b602090810291909101015250506001016121c3565b50600185038214801561230f57508683145b801561231a57508581145b612350576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061236557612365612d78565b60200260200101519750505050505050505b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036123fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610590565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008183106124b55760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612377565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612377565b828054828255906000526020600020908101928215612568579160200282015b8281111561256857825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061250e565b50612574929150612597565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b808211156125745760008155600101612598565b60808101611910828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b8181101561262b5760208185018101518683018201520161260f565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006123776020830184612605565b60008083601f84011261268e57600080fd5b50813567ffffffffffffffff8111156126a657600080fd5b6020830191508360208285010111156126be57600080fd5b9250929050565b803564ffffffffff811681146126da57600080fd5b919050565b6000806000604084860312156126f457600080fd5b833567ffffffffffffffff81111561270b57600080fd5b6127178682870161267c565b909450925061272a9050602085016126c5565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561278557612785612733565b60405290565b6040516060810167ffffffffffffffff8111828210171561278557612785612733565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127f5576127f5612733565b604052919050565b600067ffffffffffffffff82111561281757612817612733565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146117ad57600080fd5b600082601f83011261285457600080fd5b81356020612869612864836127fd565b6127ae565b8083825260208201915060208460051b87010193508684111561288b57600080fd5b602086015b848110156128b05780356128a381612821565b8352918301918301612890565b509695505050505050565b803560ff811681146126da57600080fd5b600082601f8301126128dd57600080fd5b813567ffffffffffffffff8111156128f7576128f7612733565b61292860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127ae565b81815284602083860101111561293d57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146126da57600080fd5b60008060008060008060c0878903121561298b57600080fd5b863567ffffffffffffffff808211156129a357600080fd5b6129af8a838b01612843565b975060208901359150808211156129c557600080fd5b6129d18a838b01612843565b96506129df60408a016128bb565b955060608901359150808211156129f557600080fd5b612a018a838b016128cc565b9450612a0f60808a0161295a565b935060a0890135915080821115612a2557600080fd5b50612a3289828a016128cc565b9150509295509295509295565b600060208284031215612a5157600080fd5b612377826126c5565b60008083601f840112612a6c57600080fd5b50813567ffffffffffffffff811115612a8457600080fd5b6020830191508360208260051b85010111156126be57600080fd5b600080600080600060608688031215612ab757600080fd5b853567ffffffffffffffff80821115612acf57600080fd5b612adb89838a01612a5a565b90975095506020880135915080821115612af457600080fd5b50612b0188828901612a5a565b96999598509660400135949350505050565b60008151808452602080850194506020840160005b83811015612b5a57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612b28565b509495945050505050565b6020815260006123776020830184612b13565b600060208284031215612b8a57600080fd5b5035919050565b600060208284031215612ba357600080fd5b6123778261295a565b60008060008060008060008060e0898b031215612bc857600080fd5b606089018a811115612bd957600080fd5b8998503567ffffffffffffffff80821115612bf357600080fd5b612bff8c838d0161267c565b909950975060808b0135915080821115612c1857600080fd5b612c248c838d01612a5a565b909750955060a08b0135915080821115612c3d57600080fd5b50612c4a8b828c01612a5a565b999c989b50969995989497949560c00135949350505050565b600060208284031215612c7557600080fd5b813561237781612821565b60008060208385031215612c9357600080fd5b823567ffffffffffffffff811115612caa57600080fd5b612cb685828601612a5a565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160058310612d2c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761191057611910612d32565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103612dc057612dc0612d32565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612dfa8184018a612b13565b90508281036080840152612e0e8189612b13565b905060ff871660a084015282810360c0840152612e2b8187612605565b905067ffffffffffffffff851660e0840152828103610100840152612e508185612605565b9c9b505050505050505050505050565b60ff818116838216019081111561191057611910612d32565b600060ff831680612eb3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b8082018082111561191057611910612d32565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612f0b57600080fd5b8151801515811461237757600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146126da57600080fd5b600082601f830112612f5857600080fd5b81356020612f68612864836127fd565b82815260069290921b84018101918181019086841115612f8757600080fd5b8286015b848110156128b05760408189031215612fa45760008081fd5b612fac612762565b612fb58261295a565b8152612fc2858301612f1b565b81860152835291830191604001612f8b565b600060408284031215612fe657600080fd5b612fee612762565b9050612ff98261295a565b81526130076020830161295a565b602082015292915050565b6000602080838503121561302557600080fd5b823567ffffffffffffffff8082111561303d57600080fd5b908401906080828703121561305157600080fd5b61305961278b565b82358281111561306857600080fd5b8301604081890381131561307b57600080fd5b613083612762565b82358581111561309257600080fd5b8301601f81018b136130a357600080fd5b80356130b1612864826127fd565b81815260069190911b8201890190898101908d8311156130d057600080fd5b928a01925b828410156131205785848f0312156130ed5760008081fd5b6130f5612762565b843561310081612821565b815261310d858d01612f1b565b818d0152825292850192908a01906130d5565b84525050508287013591508482111561313857600080fd5b6131448a838501612f47565b81880152835250613159905087848601612fd4565b93810193909352506060013560408201529392505050565b805160408084528151848201819052600092602091908201906060870190855b818110156131ea578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858401529284019291850191600101613191565b50508583015187820388850152805180835290840192506000918401905b80831015613259578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685830152928401926001929092019190850190613208565b50979650505050505050565b6020815260006123776020830184613171565b604081016119108284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff8181168382160190808211156132be576132be612d32565b5092915050565b6020815260008251608060208401526132e160a0840182613171565b9050602084015161330c6040850182805167ffffffffffffffff908116835260209182015116910152565b50604084015160808401528091505092915050565b60006020828403121561333357600080fd5b6040516020810181811067ffffffffffffffff8211171561335657613356612733565b604052825161336481612821565b81529392505050565b60a081016133c6828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526134318285018b612b13565b91508382036080850152613445828a612b13565b915060ff881660a085015283820360c08501526134628288612605565b90861660e08501528381036101008501529050612e50818561260556fea164736f6c6343000818000a", } var CommitStoreHelperABI = CommitStoreHelperMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go index 68c98e6adc..a5dde0893e 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go @@ -163,7 +163,7 @@ type MultiOCR3BaseOCRConfigArgs struct { } var EVM2EVMMultiOffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", Bin: "0x6101206040523480156200001257600080fd5b5060405162006bba38038062006bba8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615ee462000cd6600039600081816102530152612c0c0152600081816102240152612ee60152600081816101f50152818161142f01526118400152600081816101c50152612801015260008181611dce0152611e1a0152615ee46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063d2a15d351461053d578063e9d68a8e14610550578063ece670b61461057057600080fd5b8063991a5018116100bd578063991a5018146104c5578063c673e584146104d8578063ccd37ba3146104f857600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104815780637d4eef601461048957600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a3660046140a0565b6105cc565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d1919061420f565b61018f6103313660046142ba565b6105e0565b61018f61034436600461436d565b6109c0565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143c1565b610a29565b6040516102d1919061441e565b6104246040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610a7f565b61018f610497366004614973565b610b3d565b61018f610177366004614a9e565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104d3366004614aed565b610cdd565b6104eb6104e6366004614b72565b610cee565b6040516102d19190614bd2565b61052f610506366004614c47565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f61054b366004614c71565b610e4c565b61056361055e366004614ce6565b610f06565b6040516102d19190614d01565b61018f61057e366004614d4f565b611013565b61018f610591366004614dab565b611386565b61018f6105a4366004614e30565b611397565b6105bc6105b7366004614f6e565b6113d9565b60405190151581526020016102d1565b6105d461149a565b6105dd816114f6565b50565b60006105ee878901896150f7565b8051515190915015158061060757508051602001515115155b156107075760095460208a01359067ffffffffffffffff808316911610156106c6576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261068f929101615335565b600060405180830381600087803b1580156106a957600080fd5b505af11580156106bd573d6000803e3d6000fd5b50505050610705565b816020015151600003610705576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109095760008260200151828151811061072f5761072f615262565b6020026020010151905060008160000151905061074b816117f4565b6000610756826118f6565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061079a575060208084015190810151905167ffffffffffffffff9182169116115b156107e357825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107da929190600401615348565b60405180910390fd5b60408301518061081f576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108925783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016107da565b60208085015101516108a5906001615393565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff92831602179092559251166000908152600860209081526040808320948352939052919091204290555060010161070a565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161093991906153bb565b60405180910390a16109b560008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b925061195d915050565b505050505050505050565b610a006109cf82840184615458565b60408051600080825260208201909252906109fa565b60608152602001906001900390816109e55790505b50611cd4565b604080516000808252602082019092529050610a2360018585858586600061195d565b50505050565b6000610a376001600461548d565b6002610a446080856154b6565b67ffffffffffffffff16610a5891906154dd565b610a628585611d84565b901c166003811115610a7657610a766143f4565b90505b92915050565b6001546001600160a01b03163314610ad95760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107da565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b45611dcb565b815181518114610b81576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ccd576000848281518110610ba057610ba0615262565b60200260200101519050600081602001515190506000858481518110610bc857610bc8615262565b6020026020010151905080518214610c0c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cbe576000828281518110610c2b57610c2b615262565b6020026020010151905080600014610cb55784602001518281518110610c5357610c53615262565b602002602001015160800151811015610cb55784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016107da565b50600101610c0f565b50505050806001019050610b84565b50610cd88383611cd4565b505050565b610ce561149a565b6105dd81611e4c565b610d316040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610dda57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dbc575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e1e575b5050505050815250509050919050565b610e5461149a565b60005b81811015610cd8576000838383818110610e7357610e73615262565b905060400201803603810190610e8991906154f4565b9050610e9881602001516113d9565b610efd57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e57565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191610f939061552d565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbf9061552d565b8015610e3c5780601f10610fe157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610fef57505050919092525091949350505050565b33301461104c576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611089565b60408051808201909152600080825260208201528152602001906001900390816110625790505b5060a085015151909150156110bd576110ba8460a00151856020015186606001518760000151602001518787611fb2565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff16818301528087015183516000948401926110f992910161420f565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015611206576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a190611173908590600401615609565b600060405180830381600087803b15801561118d57600080fd5b505af192505050801561119e575060015b611206573d8080156111cc576040519150601f19603f3d011682016040523d82523d6000602084013e6111d1565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b60408601515115801561121b57506080860151155b80611232575060608601516001600160a01b03163b155b8061127257506060860151611270906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120d1565b155b1561127f57505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf97983926112f7928992611388929160040161561c565b6000604051808303816000875af1158015611316573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261133e9190810190615658565b50915091508161137c57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b5050505050505050565b61138e61149a565b6105dd816120ed565b61139f61149a565b60005b81518110156113d5576113cd8282815181106113c0576113c0615262565b60200260200101516121a3565b6001016113a2565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611476573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7991906156ee565b6000546001600160a01b031633146114f45760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107da565b565b60005b81518110156113d557600082828151811061151657611516615262565b602002602001015190506000816020015190508067ffffffffffffffff1660000361156d576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611595576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115c09061552d565b80601f01602080910402602001604051908101604052809291908181526020018280546115ec9061552d565b80156116395780601f1061160e57610100808354040283529160200191611639565b820191906000526020600020905b81548152906001019060200180831161161c57829003601f168201915b5050505050905060008460600151905081516000036116f1578051600003611674576040516342bcdf7f60e11b815260040160405180910390fd5b600183016116828282615753565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611744565b8080519060200120828051906020012014611744576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016107da565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117dc908690615813565b60405180910390a250505050508060010190506114f9565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b391906156ee565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107da565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610a79576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107da565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906119bc8760a46158e1565b9050826060015115611a045784516119d59060206154dd565b86516119e29060206154dd565b6119ed9060a06158e1565b6119f791906158e1565b611a0190826158e1565b90505b368114611a46576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107da565b5081518114611a8e5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107da565b611a96611dcb565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611ae457611ae46143f4565b6002811115611af557611af56143f4565b9052509050600281602001516002811115611b1257611b126143f4565b148015611b665750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611b4e57611b4e615262565b6000918252602090912001546001600160a01b031633145b611b9c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611c7e576020820151611bb79060016158f4565b60ff16855114611bf3576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611c2e576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611c4092919061590d565b604051908190038120611c57918b9060200161591d565b604051602081830303815290604052805190602001209050611c7c8a828888886124e7565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d0e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611d7d57611d75858281518110611d4357611d43615262565b602002602001015184611d6f57858381518110611d6257611d62615262565b60200260200101516126f4565b836126f4565b600101611d25565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611da9608085615931565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f0000000000000000000000000000000000000000000000000000000000000000146114f4576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107da565b80516001600160a01b0316611e74576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fce57611fce613eb7565b60405190808252806020026020018201604052801561201357816020015b6040805180820190915260008082526020820152815260200190600190039081611fec5790505b50905060005b87518110156120c5576120a088828151811061203757612037615262565b602002602001015188888888888781811061205457612054615262565b90506020028101906120669190615958565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e8592505050565b8282815181106120b2576120b2615262565b6020908102919091010152600101612019565b505b9695505050505050565b60006120dc8361322a565b8015610a765750610a76838361328e565b336001600160a01b038216036121455760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107da565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ce576000604051631b3fab5160e11b81526004016107da91906159bd565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223b57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612290565b6060840151600182015460ff6201000090910416151590151514612290576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016107da565b60a08401518051601f60ff821611156122bf576001604051631b3fab5160e11b81526004016107da91906159bd565b612325858560030180548060200260200160405190810160405280929190818152602001828054801561231b57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122fd575b5050505050613348565b85606001511561245457612393858560020180548060200260200160405190810160405280929190818152602001828054801561231b576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122fd575050505050613348565b608086015180516123ad9060028701906020840190613e11565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f101561240d576002604051631b3fab5160e11b81526004016107da91906159bd565b604088015161241d9060036159d7565b60ff168160ff1611612445576003604051631b3fab5160e11b81526004016107da91906159bd565b612451878360016133b1565b50505b612460858360026133b1565b81516124759060038601906020850190613e11565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ce938a939260028b019291906159f3565b60405180910390a16124df85613531565b505050505050565b6124ef613e83565b835160005b8181101561137c57600060018886846020811061251357612513615262565b61252091901a601b6158f4565b89858151811061253257612532615262565b602002602001015189868151811061254c5761254c615262565b60200260200101516040516000815260200160405260405161258a949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156125ac573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561260d5761260d6143f4565b600281111561261e5761261e6143f4565b905250905060018160200151600281111561263b5761263b6143f4565b14612672576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061268957612689615262565b6020020151156126c5576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126e0576126e0615262565b9115156020909202015250506001016124f4565b81516126ff816117f4565b600061270a826118f6565b602085015151909150600081900361274d576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461278b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156127a6576127a6613eb7565b6040519080825280602002602001820160405280156127cf578160200160208202803683370190505b50905060005b82811015612944576000876020015182815181106127f5576127f5615262565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461288857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107da565b61291e8186600101805461289b9061552d565b80601f01602080910402602001604051908101604052809291908181526020018280546128c79061552d565b80156129145780601f106128e957610100808354040283529160200191612914565b820191906000526020600020905b8154815290600101906020018083116128f757829003601f168201915b505050505061354d565b83838151811061293057612930615262565b6020908102919091010152506001016127d5565b50600061295b858389606001518a6080015161366f565b9050806000036129a3576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107da565b8551151560005b848110156109b5576000896020015182815181106129ca576129ca615262565b6020026020010151905060006129e889836000015160600151610a29565b905060008160038111156129fe576129fe6143f4565b1480612a1b57506003816003811115612a1957612a196143f4565b145b612a72578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612e7d565b8315612b4257600454600090600160a01b900463ffffffff16612a95874261548d565b1190508080612ab557506003826003811115612ab357612ab36143f4565b145b612af7576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b1660048201526024016107da565b8a8481518110612b0957612b09615262565b6020026020010151600014612b3c578a8481518110612b2a57612b2a615262565b60200260200101518360800181815250505b50612ba3565b6000816003811115612b5657612b566143f4565b14612ba3578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612a63565b81516080015167ffffffffffffffff1615612c91576000816003811115612bcc57612bcc6143f4565b03612c915781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c43928e929190600401615a9f565b6020604051808303816000875af1158015612c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8691906156ee565b612c91575050612e7d565b60008b604001518481518110612ca957612ca9615262565b6020026020010151905080518360a001515114612d0d578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d16600483015290911660248201526044016107da565b612d218a84600001516060015160016136c5565b600080612d2e858461376d565b91509150612d458c866000015160600151846136c5565b8615612db5576003826003811115612d5f57612d5f6143f4565b03612db5576000846003811115612d7857612d786143f4565b14612db5578451516040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526107da91908390600401615acc565b6002826003811115612dc957612dc96143f4565b14612e23576003826003811115612de257612de26143f4565b14612e23578451606001516040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526107da918e918590600401615ae5565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612e6f9087908790615b0b565b60405180910390a450505050505b6001016129aa565b60408051808201909152600080825260208201526000612ea88760200151613837565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f519190615b2b565b90506001600160a01b0381161580612f995750612f976001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120d1565b155b15612fdb576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016107da565b6004546000908190612ffd9089908690600160e01b900463ffffffff166138dd565b9150915060008060006130ca6040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b81525060405160240161307b9190615b48565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a0b565b9250925092508261310957816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b81516020146131515781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b6000828060200190518101906131679190615c15565b9050866001600160a01b03168c6001600160a01b0316146131fc5760006131988d8a613193868a61548d565b6138dd565b509050868110806131b25750816131af888361548d565b14155b156131fa576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016107da565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613256827f01ffc9a70000000000000000000000000000000000000000000000000000000061328e565b8015610a795750613287827fffffffff0000000000000000000000000000000000000000000000000000000061328e565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613331575060208210155b801561333d5750600081115b979650505050505050565b60005b8151811015610cd85760ff83166000908152600360205260408120835190919084908490811061337d5761337d615262565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161334b565b60005b82518160ff161015610a23576000838260ff16815181106133d7576133d7615262565b60200260200101519050600060028111156133f4576133f46143f4565b60ff80871660009081526003602090815260408083206001600160a01b03871684529091529020546101009004166002811115613433576134336143f4565b14613454576004604051631b3fab5160e11b81526004016107da91906159bd565b6001600160a01b038116613494576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134ba576134ba6143f4565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff191617610100836002811115613517576135176143f4565b0217905550905050508061352a90615c2e565b90506133b4565b60ff81166105dd576009805467ffffffffffffffff1916905550565b815160208082015160409283015192516000938493613593937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c4d565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135dc9794969395929491939101615c80565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136139190615d77565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061367d858585613b31565b9050613688816113d9565b6136965760009150506136bd565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026136d46080856154b6565b67ffffffffffffffff166136e891906154dd565b905060006136f68585611d84565b9050816137056001600461548d565b901b19168183600381111561371c5761371c6143f4565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161374b608088615931565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906137b19087908790600401615dd7565b600060405180830381600087803b1580156137cb57600080fd5b505af19250505080156137dc575060015b61381b573d80801561380a576040519150601f19603f3d011682016040523d82523d6000602084013e61380f565b606091505b50600392509050613830565b50506040805160208101909152600081526002905b9250929050565b6000815160201461387657816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b60008280602001905181019061388c9190615c15565b90506001600160a01b038111806138a4575061040081105b15610a7957826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b60008060008060006139578860405160240161390891906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a0b565b9250925092508261399657816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b60208251146139de5781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b818060200190518101906139f29190615c15565b6139fc828861548d565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a2e57613a2e613eb7565b6040519080825280601f01601f191660200182016040528015613a58576020820181803683370190505b509150863b613a8b577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613abe577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613af7577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b1a5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b72576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b8657506101018111155b613ba3576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bcd576040516309bde33960e01b815260040160405180910390fd5b80600003613bfa5786600081518110613be857613be8615262565b60200260200101519350505050613dc9565b60008167ffffffffffffffff811115613c1557613c15613eb7565b604051908082528060200260200182016040528015613c3e578160200160208202803683370190505b50905060008080805b85811015613d685760006001821b8b811603613ca25788851015613c8b578c5160018601958e918110613c7c57613c7c615262565b60200260200101519050613cc4565b8551600185019487918110613c7c57613c7c615262565b8b5160018401938d918110613cb957613cb9615262565b602002602001015190505b600089861015613cf4578d5160018701968f918110613ce557613ce5615262565b60200260200101519050613d16565b8651600186019588918110613d0b57613d0b615262565b602002602001015190505b82851115613d37576040516309bde33960e01b815260040160405180910390fd5b613d418282613dd0565b878481518110613d5357613d53615262565b60209081029190910101525050600101613c47565b506001850382148015613d7a57508683145b8015613d8557508581145b613da2576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613db757613db7615262565b60200260200101519750505050505050505b9392505050565b6000818310613de857613de38284613dee565b610a76565b610a7683835b604080516001602082015290810183905260608101829052600090608001613651565b828054828255906000526020600020908101928215613e73579160200282015b82811115613e73578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e31565b50613e7f929150613ea2565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e7f5760008155600101613ea3565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b60405290565b60405160a0810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b60405160c0810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b6040805190810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b6040516060810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fab57613fab613eb7565b604052919050565b600067ffffffffffffffff821115613fcd57613fcd613eb7565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461400457600080fd5b919050565b80151581146105dd57600080fd5b803561400481614009565b600067ffffffffffffffff82111561403c5761403c613eb7565b50601f01601f191660200190565b600082601f83011261405b57600080fd5b813561406e61406982614022565b613f82565b81815284602083860101111561408357600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140b357600080fd5b823567ffffffffffffffff808211156140cb57600080fd5b818501915085601f8301126140df57600080fd5b81356140ed61406982613fb3565b81815260059190911b8301840190848101908883111561410c57600080fd5b8585015b838110156141b2578035858111156141285760008081fd5b86016080818c03601f19018113156141405760008081fd5b614148613ecd565b8983013561415581613fd7565b81526040614164848201613fec565b8b83015260608085013561417781614009565b8383015292840135928984111561419057600091508182fd5b61419e8f8d8688010161404a565b908301525085525050918601918601614110565b5098975050505050505050565b60005b838110156141da5781810151838201526020016141c2565b50506000910152565b600081518084526141fb8160208601602086016141bf565b601f01601f19169290920160200192915050565b602081526000610a7660208301846141e3565b8060608101831015610a7957600080fd5b60008083601f84011261424557600080fd5b50813567ffffffffffffffff81111561425d57600080fd5b60208301915083602082850101111561383057600080fd5b60008083601f84011261428757600080fd5b50813567ffffffffffffffff81111561429f57600080fd5b6020830191508360208260051b850101111561383057600080fd5b60008060008060008060008060e0898b0312156142d657600080fd5b6142e08a8a614222565b9750606089013567ffffffffffffffff808211156142fd57600080fd5b6143098c838d01614233565b909950975060808b013591508082111561432257600080fd5b61432e8c838d01614275565b909750955060a08b013591508082111561434757600080fd5b506143548b828c01614275565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561438257600080fd5b61438c8585614222565b9250606084013567ffffffffffffffff8111156143a857600080fd5b6143b486828701614233565b9497909650939450505050565b600080604083850312156143d457600080fd5b6143dd83613fec565b91506143eb60208401613fec565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061441a5761441a6143f4565b9052565b60208101610a79828461440a565b600060a0828403121561443e57600080fd5b614446613ef6565b90508135815261445860208301613fec565b602082015261446960408301613fec565b604082015261447a60608301613fec565b606082015261448b60808301613fec565b608082015292915050565b803561400481613fd7565b600082601f8301126144b257600080fd5b813560206144c261406983613fb3565b82815260059290921b840181019181810190868411156144e157600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156145065760008081fd5b8189019150608080601f19848d030112156145215760008081fd5b614529613ecd565b878401358381111561453b5760008081fd5b6145498d8a8388010161404a565b825250604080850135848111156145605760008081fd5b61456e8e8b8389010161404a565b8a84015250606080860135858111156145875760008081fd5b6145958f8c838a010161404a565b92840192909252949092013593810193909352505083529183019183016144e5565b600061014082840312156145ca57600080fd5b6145d2613f19565b90506145de838361442c565b815260a082013567ffffffffffffffff808211156145fb57600080fd5b6146078583860161404a565b602084015260c084013591508082111561462057600080fd5b61462c8583860161404a565b604084015261463d60e08501614496565b6060840152610100840135608084015261012084013591508082111561466257600080fd5b5061466f848285016144a1565b60a08301525092915050565b600082601f83011261468c57600080fd5b8135602061469c61406983613fb3565b82815260059290921b840181019181810190868411156146bb57600080fd5b8286015b848110156120c557803567ffffffffffffffff8111156146df5760008081fd5b6146ed8986838b01016145b7565b8452509183019183016146bf565b600082601f83011261470c57600080fd5b8135602061471c61406983613fb3565b82815260059290921b8401810191818101908684111561473b57600080fd5b8286015b848110156120c557803567ffffffffffffffff8082111561475f57600080fd5b818901915089603f83011261477357600080fd5b8582013561478361406982613fb3565b81815260059190911b830160400190878101908c8311156147a357600080fd5b604085015b838110156147dc578035858111156147bf57600080fd5b6147ce8f6040838a010161404a565b8452509189019189016147a8565b5087525050509284019250830161473f565b600082601f8301126147ff57600080fd5b8135602061480f61406983613fb3565b8083825260208201915060208460051b87010193508684111561483157600080fd5b602086015b848110156120c55780358352918301918301614836565b600082601f83011261485e57600080fd5b8135602061486e61406983613fb3565b82815260059290921b8401810191818101908684111561488d57600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156148b25760008081fd5b818901915060a080601f19848d030112156148cd5760008081fd5b6148d5613ef6565b6148e0888501613fec565b8152604080850135848111156148f65760008081fd5b6149048e8b8389010161467b565b8a840152506060808601358581111561491d5760008081fd5b61492b8f8c838a01016146fb565b83850152506080915081860135858111156149465760008081fd5b6149548f8c838a01016147ee565b9184019190915250919093013590830152508352918301918301614891565b600080604080848603121561498757600080fd5b833567ffffffffffffffff8082111561499f57600080fd5b6149ab8783880161484d565b94506020915081860135818111156149c257600080fd5b8601601f810188136149d357600080fd5b80356149e161406982613fb3565b81815260059190911b8201840190848101908a831115614a0057600080fd5b8584015b83811015614a8c57803586811115614a1c5760008081fd5b8501603f81018d13614a2e5760008081fd5b87810135614a3e61406982613fb3565b81815260059190911b82018a0190898101908f831115614a5e5760008081fd5b928b01925b82841015614a7c5783358252928a0192908a0190614a63565b8652505050918601918601614a04565b50809750505050505050509250929050565b600060208284031215614ab057600080fd5b813567ffffffffffffffff811115614ac757600080fd5b820160a08185031215613dc957600080fd5b803563ffffffff8116811461400457600080fd5b600060a08284031215614aff57600080fd5b614b07613ef6565b8235614b1281613fd7565b8152614b2060208401614ad9565b6020820152614b3160408401614ad9565b6040820152614b4260608401614ad9565b60608201526080830135614b5581613fd7565b60808201529392505050565b803560ff8116811461400457600080fd5b600060208284031215614b8457600080fd5b610a7682614b61565b60008151808452602080850194506020840160005b83811015614bc75781516001600160a01b031687529582019590820190600101614ba2565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c2160e0840182614b8d565b90506040840151601f198483030160c0850152614c3e8282614b8d565b95945050505050565b60008060408385031215614c5a57600080fd5b614c6383613fec565b946020939093013593505050565b60008060208385031215614c8457600080fd5b823567ffffffffffffffff80821115614c9c57600080fd5b818501915085601f830112614cb057600080fd5b813581811115614cbf57600080fd5b8660208260061b8501011115614cd457600080fd5b60209290920196919550909350505050565b600060208284031215614cf857600080fd5b610a7682613fec565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136bd60a08401826141e3565b600080600060408486031215614d6457600080fd5b833567ffffffffffffffff80821115614d7c57600080fd5b614d88878388016145b7565b94506020860135915080821115614d9e57600080fd5b506143b486828701614275565b600060208284031215614dbd57600080fd5b8135613dc981613fd7565b600082601f830112614dd957600080fd5b81356020614de961406983613fb3565b8083825260208201915060208460051b870101935086841115614e0b57600080fd5b602086015b848110156120c5578035614e2381613fd7565b8352918301918301614e10565b60006020808385031215614e4357600080fd5b823567ffffffffffffffff80821115614e5b57600080fd5b818501915085601f830112614e6f57600080fd5b8135614e7d61406982613fb3565b81815260059190911b83018401908481019088831115614e9c57600080fd5b8585015b838110156141b257803585811115614eb757600080fd5b860160c0818c03601f19011215614ece5760008081fd5b614ed6613f19565b8882013581526040614ee9818401614b61565b8a8301526060614efa818501614b61565b8284015260809150614f0d828501614017565b9083015260a08381013589811115614f255760008081fd5b614f338f8d83880101614dc8565b838501525060c0840135915088821115614f4d5760008081fd5b614f5b8e8c84870101614dc8565b9083015250845250918601918601614ea0565b600060208284031215614f8057600080fd5b5035919050565b80356001600160e01b038116811461400457600080fd5b600082601f830112614faf57600080fd5b81356020614fbf61406983613fb3565b82815260069290921b84018101918181019086841115614fde57600080fd5b8286015b848110156120c55760408189031215614ffb5760008081fd5b615003613f3c565b61500c82613fec565b8152615019858301614f87565b81860152835291830191604001614fe2565b600082601f83011261503c57600080fd5b8135602061504c61406983613fb3565b82815260079290921b8401810191818101908684111561506b57600080fd5b8286015b848110156120c55780880360808112156150895760008081fd5b615091613f5f565b61509a83613fec565b8152604080601f19840112156150b05760008081fd5b6150b8613f3c565b92506150c5878501613fec565b83526150d2818501613fec565b838801528187019290925260608301359181019190915283529183019160800161506f565b6000602080838503121561510a57600080fd5b823567ffffffffffffffff8082111561512257600080fd5b8185019150604080838803121561513857600080fd5b615140613f3c565b83358381111561514f57600080fd5b84016040818a03121561516157600080fd5b615169613f3c565b81358581111561517857600080fd5b8201601f81018b1361518957600080fd5b803561519761406982613fb3565b81815260069190911b8201890190898101908d8311156151b657600080fd5b928a01925b828410156152065787848f0312156151d35760008081fd5b6151db613f3c565b84356151e681613fd7565b81526151f3858d01614f87565b818d0152825292870192908a01906151bb565b84525050508187013593508484111561521e57600080fd5b61522a8a858401614f9e565b818801528252508385013591508282111561524457600080fd5b6152508883860161502b565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b818110156152cf57835180516001600160a01b031684528501516001600160e01b0316858401529284019291850191600101615298565b50508583015187820388850152805180835290840192506000918401905b80831015615329578351805167ffffffffffffffff1683528501516001600160e01b0316858301529284019260019290920191908501906152ed565b50979650505050505050565b602081526000610a766020830184615278565b67ffffffffffffffff8316815260608101613dc96020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153b4576153b461537d565b5092915050565b6000602080835260608451604080848701526153da6060870183615278565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141b257845167ffffffffffffffff81511683528781015161543a89850182805167ffffffffffffffff908116835260209182015116910152565b508401518287015293860193600192909201916080909101906153fb565b60006020828403121561546a57600080fd5b813567ffffffffffffffff81111561548157600080fd5b6136bd8482850161484d565b81810381811115610a7957610a7961537d565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff808416806154d1576154d16154a0565b92169190910692915050565b8082028115828204841417610a7957610a7961537d565b60006040828403121561550657600080fd5b61550e613f3c565b61551783613fec565b8152602083013560208201528091505092915050565b600181811c9082168061554157607f821691505b60208210810361556157634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261559b60a08701826141e3565b9050606085015186820360608801526155b482826141e3565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561532957835180516001600160a01b03168352860151868301529285019260019290920191908401906155d7565b602081526000610a766020830184615567565b60808152600061562f6080830187615567565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561566d57600080fd5b835161567881614009565b602085015190935067ffffffffffffffff81111561569557600080fd5b8401601f810186136156a657600080fd5b80516156b461406982614022565b8181528760208385010111156156c957600080fd5b6156da8260208301602086016141bf565b809450505050604084015190509250925092565b60006020828403121561570057600080fd5b8151613dc981614009565b601f821115610cd8576000816000526020600020601f850160051c810160208610156157345750805b601f850160051c820191505b818110156124df57828155600101615740565b815167ffffffffffffffff81111561576d5761576d613eb7565b6157818161577b845461552d565b8461570b565b602080601f8311600181146157b6576000841561579e5750858301515b600019600386901b1c1916600185901b1785556124df565b600085815260208120601f198616915b828110156157e5578886015182559484019460019091019084016157c6565b50858210156158035787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546158658161552d565b8060a089015260c0600183166000811461588657600181146158a2576158d2565b60ff19841660c08b015260c083151560051b8b010194506158d2565b85600052602060002060005b848110156158c95781548c82018501529088019089016158ae565b8b0160c0019550505b50929998505050505050505050565b80820180821115610a7957610a7961537d565b60ff8181168382160190811115610a7957610a7961537d565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061594c5761594c6154a0565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261598d57600080fd5b83018035915067ffffffffffffffff8211156159a857600080fd5b60200191503681900382131561383057600080fd5b60208101600583106159d1576159d16143f4565b91905290565b60ff81811683821602908116908181146153b4576153b461537d565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a4b5784546001600160a01b031683526001948501949284019201615a26565b50508481036060860152865180825290820192508187019060005b81811015615a8b5782516001600160a01b031685529383019391830191600101615a66565b50505060ff851660808501525090506120c7565b600067ffffffffffffffff808616835280851660208401525060606040830152614c3e60608301846141e3565b8281526040602082015260006136bd60408301846141e3565b67ffffffffffffffff848116825283166020820152606081016136bd604083018461440a565b615b15818461440a565b6040602082015260006136bd60408301846141e3565b600060208284031215615b3d57600080fd5b8151613dc981613fd7565b6020815260008251610100806020850152615b676101208501836141e3565b91506020850151615b84604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615bbe60a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bdb84836141e3565b935060c08701519150808685030160e0870152615bf884836141e3565b935060e08701519150808685030183870152506120c783826141e3565b600060208284031215615c2757600080fd5b5051919050565b600060ff821660ff8103615c4457615c4461537d565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c760808301846141e3565b86815260c060208201526000615c9960c08301886141e3565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d6a57601f19868403018952815160808151818652615d16828701826141e3565b9150508582015185820387870152615d2e82826141e3565b91505060408083015186830382880152615d4883826141e3565b6060948501519790940196909652505098840198925090830190600101615cf0565b5090979650505050505050565b602081526000610a766020830184615cd3565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d6a57601f19868403018952615dc58383516141e3565b98840198925090830190600101615da9565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e3f6101808501836141e3565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e7c84836141e3565b935060608801519150615e9b6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615ec28282615cd3565b9150508281036020840152614c3e8185615d8a56fea164736f6c6343000818000a", } diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go index a906177b7d..704d95cf96 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go @@ -109,8 +109,8 @@ type RateLimiterTokenBucket struct { } var EVM2EVMOffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"DestinationGasAmountCountMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"oldLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"tokenIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"oldLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenGasOverride\",\"type\":\"uint256\"}],\"name\":\"InvalidTokenGasOverride\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receiverExecutionGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"internalType\":\"structEVM2EVMOffRamp.GasLimitOverride[]\",\"name\":\"gasLimitOverrides\",\"type\":\"tuple[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101a06040523480156200001257600080fd5b5060405162006609380380620066098339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f40620006c9600039600081816102ec01528181611c6a01526133920152600081816102bd01528181611c420152611f2701526000818161028e01528181610d8d01528181610df201528181611c18015281816124a4015261250e015260006120c601526000818161025f0152611bee0152600081816101ff0152611b9201526000818161022f01528181611bc601528181611ee40152818161303b01526134bf0152600081816101d001528181611b6d01526121ac015260008181611e3e0152611e8a0152615f406000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806385572ffb116100d8578063afcb95d71161008c578063c92b283211610066578063c92b2832146105f3578063f077b59214610606578063f2fde38b1461061c57600080fd5b8063afcb95d7146105ad578063b1dc65a4146105cd578063b6113fce146105e057600080fd5b8063873504d7116100bd578063873504d7146105765780638926c4ee146105895780638da5cb5b1461059c57600080fd5b806385572ffb1461053c578063856c82471461054a57600080fd5b8063599f64311161013a5780637437ff9f116101145780637437ff9f1461046157806379ba50971461050457806381ff70481461050c57600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516103299190614311565b60405180910390f35b6103456103403660046143a7565b61062f565b6040516103299190614407565b61038e6040518060400160405280601881526020017f45564d3245564d4f666652616d7020312e352e302d646576000000000000000081525081565b6040516103299190614465565b6103ae6103a936600461468e565b6106aa565b005b6103b8610a9e565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610b53565b60405161032991906147a0565b6103ae61045c3660046147b3565b610bb5565b6104f76040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a01000000000000000000009091046001600160a01b039081166060830152600b5416608082015290565b60405161032991906147d0565b6103ae610c7e565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae610182366004614826565b61055d6105583660046147b3565b610d61565b60405167ffffffffffffffff9091168152602001610329565b6103ae6105843660046148f2565b610e64565b6103ae610597366004614e1d565b611037565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae6105db366004614f74565b61129c565b6103ae6105ee366004615059565b6114a7565b6103ae610601366004615110565b6117e7565b61060e611852565b60405161032992919061517e565b6103ae61062a3660046147b3565b611978565b600061063d600160046151d2565b600261064a608085615214565b67ffffffffffffffff1661065e919061523b565b6010600061066d608087615252565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106a4576106a46143c4565b92915050565b84518460ff16601f8211156106f75760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190615279565b60405180910390fd5b806000036107345760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190615279565b61073c611989565b610745856119ff565b60095460005b818110156107bc57600860006009838154811061076a5761076a615293565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161074b565b5050865160005b8181101561095f5760008982815181106107df576107df615293565b60200260200101519050600060028111156107fc576107fc6143c4565b6001600160a01b038216600090815260086020526040902054610100900460ff16600281111561082e5761082e6143c4565b146108685760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190615279565b6001600160a01b0381166108a8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561094b5761094b6143c4565b0217905550905050508060010190506107c3565b5087516109739060099060208b019061427f565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a1617179055600780546109f99146913091906000906109cb9063ffffffff166152c2565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611cc9565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610a8a9487949293918316921691909117908f908f908f908f908f908f906152e5565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610b4e90611d56565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bab57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8d575b5050505050905090565b6000546001600160a01b03163314801590610bdb57506002546001600160a01b03163314155b15610c12576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b6001546001600160a01b03163314610cf2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106ee565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106a4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106a4576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5d919061537b565b9392505050565b610e6c611989565b60005b8251811015610f3f57610ea9838281518110610e8d57610e8d615293565b602002602001015160200151600c611e0890919063ffffffff16565b15610f37577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d58782838281518110610ee157610ee1615293565b602002602001015160000151848381518110610eff57610eff615293565b602002602001015160200151604051610f2e9291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610e6f565b5060005b815181101561103257610f9c828281518110610f6157610f61615293565b602002602001015160200151838381518110610f7f57610f7f615293565b602002602001015160000151600c611e1d9092919063ffffffff16565b1561102a577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a828281518110610fd457610fd4615293565b602002602001015160000151838381518110610ff257610ff2615293565b6020026020010151602001516040516110219291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610f43565b505050565b61103f611e3b565b8151518151811461107c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156112915760008460000151828151811061109f5761109f615293565b6020026020010151905060008483815181106110bd576110bd615293565b60209081029190910101518051909150801561112c57826080015181101561112c5761018083015160808401516040517f9c6db58d00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016106ee565b816020015151836101400151511461118e5761018083015160608401516040517f85d2e5bf000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff1660248201526044016106ee565b61016083015160005b846101400151518110156112815760008287815181106111b9576111b9615293565b60200260200101518060200190518101906111d491906153dd565b90506000856020015183815181106111ee576111ee615293565b602002602001015163ffffffff169050806000141580156112185750816060015163ffffffff1681105b156112775761018087015160608301516040517fef0c635200000000000000000000000000000000000000000000000000000000815260048101929092526024820185905263ffffffff166044820152606481018290526084016106ee565b5050600101611197565b505050505080600101905061107f565b506110328383611ebc565b6112a6878761290f565b6005548835908082146112ef576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016106ee565b6112f7611e3b565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561137f5761137f6143c4565b6002811115611390576113906143c4565b90525090506002816020015160028111156113ad576113ad6143c4565b1480156113e757506009816000015160ff16815481106113cf576113cf615293565b6000918252602090912001546001600160a01b031633145b61141d576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061142b85602061523b565b61143688602061523b565b6114428b6101446154a9565b61144c91906154a9565b61145691906154a9565b905036811461149a576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016106ee565b5050505050505050505050565b3330146114e0576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516000808252602082019092528161151d565b60408051808201909152600080825260208201528152602001906001900390816114f65790505b50905060006115306101408701876154bc565b905011156115a7576115a46115496101408701876154bc565b6115596040890160208a016147b3565b604080516001600160a01b0390921660208301520160408051601f1981840301815291815261158e9060608b01908b016147b3565b61159c6101608b018b615524565b8a8a8a612966565b90505b6115b561012086018661558c565b15905080156115c657506080850135155b806115e857506115dc60608601604087016147b3565b6001600160a01b03163b155b8061163357506116317f85572ffb0000000000000000000000000000000000000000000000000000000061162260608801604089016147b3565b6001600160a01b031690612b8f565b155b1561163e57506117e1565b600a546040805160a08101909152610180870135815260009182916a01000000000000000000009091046001600160a01b031690633cf979839060208082019061168a908c018c6143a7565b67ffffffffffffffff1681526020018a60200160208101906116ac91906147b3565b604080516001600160a01b0390921660208301520160408051601f1981840301815291905281526020016116e46101208c018c61558c565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200186905261138860808b013561173960608d0160408e016147b3565b6040518563ffffffff1660e01b81526004016117589493929190615636565b6000604051808303816000875af1158015611777573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261179f91908101906156fb565b5091509150816117dd57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b5050505b50505050565b6000546001600160a01b0316331480159061180d57506002546001600160a01b03163314155b15611844576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61184f600382612bab565b50565b6060806000611861600c612d90565b90508067ffffffffffffffff81111561187c5761187c614478565b6040519080825280602002602001820160405280156118a5578160200160208202803683370190505b5092508067ffffffffffffffff8111156118c1576118c1614478565b6040519080825280602002602001820160405280156118ea578160200160208202803683370190505b50915060005b8181101561197257600080611906600c84612d9b565b915091508086848151811061191d5761191d615293565b60200260200101906001600160a01b031690816001600160a01b0316815250508185848151811061195057611950615293565b6001600160a01b039092166020928302919091019091015250506001016118f0565b50509091565b611980611989565b61184f81612db9565b6000546001600160a01b031633146119fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106ee565b565b600081806020019051810190611a159190615755565b60608101519091506001600160a01b0316611a5c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a01000000000000000000006001600160a01b039485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611cbd9184906157f4565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611ced999897969594939291906158b6565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611de482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611dc891906151d2565b85608001516fffffffffffffffffffffffffffffffff16612e94565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6000610e5d836001600160a01b038416612ebc565b6000611e33846001600160a01b03851684612ec8565b949350505050565b467f0000000000000000000000000000000000000000000000000000000000000000146119fd576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016106ee565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611f76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9a919061593e565b15611fd1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815151600081900361200e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015151811461204c576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561206757612067614478565b604051908082528060200260200182016040528015612090578160200160208202803683370190505b50905060005b82811015612168576000856000015182815181106120b6576120b6615293565b602002602001015190506120ea817f0000000000000000000000000000000000000000000000000000000000000000612ede565b8383815181106120fc576120fc615293565b60200260200101818152505080610180015183838151811061212057612120615293565b60200260200101511461215f576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101612096565b508251604080860151606087015191517f32048875000000000000000000000000000000000000000000000000000000008152921515926000926001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926332048875926121e29288929160040161598c565b602060405180830381865afa1580156121ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222391906159c2565b90508060000361225f576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b848110156117dd5760008760000151828151811061228257612282615293565b60200260200101519050600061229b826060015161062f565b905060008160038111156122b1576122b16143c4565b14806122ce575060038160038111156122cc576122cc6143c4565b145b61231457816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a25050612907565b606085156123fa5788848151811061232e5761232e615293565b6020908102919091018101510151600a5490915060009063ffffffff1661235587426151d2565b119050808061237557506003836003811115612373576123736143c4565b145b6123ab576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8985815181106123bd576123bd615293565b6020026020010151600001516000146123f4578985815181106123e2576123e2615293565b60209081029190910101515160808501525b5061245e565b600082600381111561240e5761240e6143c4565b1461245e57606083015160405167ffffffffffffffff90911681527f67d9ba0f63d427c482c2736300e6d5a34c6691dbcdea8ad35828a1f1ba47e8729060200160405180910390a1505050612907565b60c083015167ffffffffffffffff16156126df576020808401516001600160a01b03166000908152600f909152604081205467ffffffffffffffff1690819003612649577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156126495760208401516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa158015612557573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257b919061537b565b60c085015190915067ffffffffffffffff166125988260016159db565b67ffffffffffffffff16146125f95783602001516001600160a01b03168460c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a350505050612907565b6020848101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b600083600381111561265d5761265d6143c4565b036126dd5760c084015167ffffffffffffffff1661267c8260016159db565b67ffffffffffffffff16146126dd5783602001516001600160a01b03168460c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a350505050612907565b505b60008a6020015185815181106126f7576126f7615293565b602002602001015190506127238460600151856000015186610140015151876101200151518551613039565b612732846060015160016131ba565b600080612740868486613264565b915091506127528660600151836131ba565b88156127be57600382600381111561276c5761276c6143c4565b036127be576000856003811115612785576127856143c4565b146127be57806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b60028260038111156127d2576127d26143c4565b1461282a5760038260038111156127eb576127eb6143c4565b1461282a578560600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016106ee9291906159fc565b60c086015167ffffffffffffffff16156128b2576000856003811115612852576128526143c4565b036128b2576020808701516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff169161288a83615a1a565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b856101800151866060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef6584846040516128f8929190615a37565b60405180910390a35050505050505b600101612262565b61296261291e82840184615a57565b604080516000808252602082019092529061295c565b6040805180820190915260008152606060208201528152602001906001900390816129345790505b50611ebc565b5050565b60608989808060200260200160405190810160405280939291908181526020016000905b828210156129b6576129a760408302860136819003810190615a8c565b8152602001906001019061298a565b505050505090506000805b8a811015612b715760008888838181106129dd576129dd615293565b90506020028101906129ef919061558c565b8101906129fc9190615aa8565b90508451600014612a5757848281518110612a1957612a19615293565b602002602001015163ffffffff16600014612a5757848281518110612a4057612a40615293565b602090810291909101015163ffffffff1660608201525b612ad78d8d84818110612a6c57612a6c615293565b905060400201602001358c8c848b8b88818110612a8b57612a8b615293565b9050602002810190612a9d919061558c565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061333192505050565b848381518110612ae957612ae9615293565b6020026020010181905250612b25848381518110612b0957612b09615293565b602002602001015160000151600c6136fd90919063ffffffff16565b15612b6857612b5b848381518110612b3f57612b3f615293565b6020908102919091010151600b546001600160a01b0316613712565b612b6590846154a9565b92505b506001016129c1565b508015612b8157612b8181613833565b509998505050505050505050565b6000612b9a83613840565b8015610e5d5750610e5d83836138a4565b8154600090612bd490700100000000000000000000000000000000900463ffffffff16426151d2565b90508015612c765760018301548354612c1c916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e94565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c9c916fffffffffffffffffffffffffffffffff9081169116613973565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612d839084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106a482613989565b6000808080612daa8686613994565b909450925050505b9250929050565b336001600160a01b03821603612e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106ee565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612eb385612ea4848661523b565b612eae90876154a9565b613973565b95945050505050565b6000610e5d83836139a3565b6000611e3384846001600160a01b0385166139c0565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612f749897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612fad9190615b64565b60405160208183030381529060405280519060200120876101600151604051602001612fd99190615bd1565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff16146130b2576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016106ee565b600a5468010000000000000000900461ffff1683111561310a576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b80831461314f576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b600a54640100000000900463ffffffff168211156131b357600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff166004820152602481018390526044016106ee565b5050505050565b600060026131c9608085615214565b67ffffffffffffffff166131dd919061523b565b905060006010816131ef608087615252565b67ffffffffffffffff168152602081019190915260400160002054905081613219600160046151d2565b901b191681836003811115613230576132306143c4565b901b178060106000613243608088615252565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517fb6113fce000000000000000000000000000000000000000000000000000000008152600090606090309063b6113fce906132aa90889088908890600401615c1b565b600060405180830381600087803b1580156132c457600080fd5b505af19250505080156132d5575060015b613314573d808015613303576040519150601f19603f3d011682016040523d82523d6000602084013e613308565b606091505b50600392509050613329565b50506040805160208101909152600081526002905b935093915050565b6040805180820190915260008082526020820152600061335484602001516139dd565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa1580156133d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fd9190615da4565b90506001600160a01b038116158061344557506134436001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612b8f565b155b15613487576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016106ee565b60008061349f8885896060015163ffffffff16613a83565b91509150600080600061359d6040518061010001604052808e81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018d6001600160a01b031681526020018f8152602001896001600160a01b031681526020018c6000015181526020018c6040015181526020018b8152506040516024016135399190615dc1565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613bc6565b925092509250826135dc57816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b81516020146136245781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b60008280602001905181019061363a91906159c2565b9050866001600160a01b03168c6001600160a01b0316146136cf57600061366b8d8a613666868a6151d2565b613a83565b5090508681108061368557508161368288836151d2565b14155b156136cd576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016106ee565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000610e5d836001600160a01b038416613cec565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613778573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379c9190615e8e565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036138055783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016106ee565b6020840151611e33907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690613cf8565b61184f6003826000613d35565b600061386c827f01ffc9a7000000000000000000000000000000000000000000000000000000006138a4565b80156106a4575061389d827fffffffff000000000000000000000000000000000000000000000000000000006138a4565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561395c575060208210155b80156139685750600081115b979650505050505050565b60008183106139825781610e5d565b5090919050565b60006106a482614084565b6000808080612daa868661408f565b60008181526002830160205260408120819055610e5d83836140ba565b60008281526002840160205260408120829055611e3384846140c6565b60008151602014613a1c57816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b600082806020019051810190613a3291906159c2565b90506001600160a01b03811180613a4a575061040081105b156106a457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b6000806000806000613b1288604051602401613aae91906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613bc6565b92509250925082613b5157816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b6020825114613b995781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b81806020019051810190613bad91906159c2565b613bb782886151d2565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613be957613be9614478565b6040519080825280601f01601f191660200182016040528015613c13576020820181803683370190505b509150863b613c46577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613c79577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613cb2577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613cd55750835b808352806000602085013e50955095509592505050565b6000610e5d83836140d2565b6000670de0b6b3a7640000613d2b837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff861661523b565b610e5d9190615ef0565b825474010000000000000000000000000000000000000000900460ff161580613d5c575081155b15613d6657505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090613dac90700100000000000000000000000000000000900463ffffffff16426151d2565b90508015613e6c5781831115613dee576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613e289083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e94565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613f09576001600160a01b038416613ebe576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106ee565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b03851660448201526064016106ee565b848310156140025760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613f4d90826151d2565b613f57878a6151d2565b613f6191906154a9565b613f6b9190615ef0565b90506001600160a01b038616613fb7576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106ee565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b03871660448201526064016106ee565b61400c85846151d2565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60006106a4826140de565b6000808061409d85856140e8565b600081815260029690960160205260409095205494959350505050565b6000610e5d83836140f4565b6000610e5d83836141ee565b6000610e5d838361423d565b60006106a4825490565b6000610e5d8383614255565b600081815260018301602052604081205480156141dd5760006141186001836151d2565b855490915060009061412c906001906151d2565b905081811461419157600086600001828154811061414c5761414c615293565b906000526020600020015490508087600001848154811061416f5761416f615293565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806141a2576141a2615f04565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106a4565b60009150506106a4565b5092915050565b6000818152600183016020526040812054614235575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106a4565b5060006106a4565b60008181526001830160205260408120541515610e5d565b600082600001828154811061426c5761426c615293565b9060005260206000200154905092915050565b8280548282559060005260206000209081019282156142ec579160200282015b828111156142ec57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0390911617825560209092019160019091019061429f565b506142f89291506142fc565b5090565b5b808211156142f857600081556001016142fd565b60e081016106a482846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff8116811461184f57600080fd5b80356143a281614381565b919050565b6000602082840312156143b957600080fd5b8135610e5d81614381565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110614403576144036143c4565b9052565b602081016106a482846143f3565b60005b83811015614430578181015183820152602001614418565b50506000910152565b60008151808452614451816020860160208601614415565b601f01601f19169290920160200192915050565b602081526000610e5d6020830184614439565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156144ca576144ca614478565b60405290565b6040516080810167ffffffffffffffff811182821017156144ca576144ca614478565b6040516101a0810167ffffffffffffffff811182821017156144ca576144ca614478565b604051601f8201601f1916810167ffffffffffffffff8111828210171561454057614540614478565b604052919050565b600067ffffffffffffffff82111561456257614562614478565b5060051b60200190565b6001600160a01b038116811461184f57600080fd5b80356143a28161456c565b600082601f83011261459d57600080fd5b813560206145b26145ad83614548565b614517565b8083825260208201915060208460051b8701019350868411156145d457600080fd5b602086015b848110156145f95780356145ec8161456c565b83529183019183016145d9565b509695505050505050565b803560ff811681146143a257600080fd5b600067ffffffffffffffff82111561462f5761462f614478565b50601f01601f191660200190565b600082601f83011261464e57600080fd5b813561465c6145ad82614615565b81815284602083860101111561467157600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156146a757600080fd5b863567ffffffffffffffff808211156146bf57600080fd5b6146cb8a838b0161458c565b975060208901359150808211156146e157600080fd5b6146ed8a838b0161458c565b96506146fb60408a01614604565b9550606089013591508082111561471157600080fd5b61471d8a838b0161463d565b945061472b60808a01614397565b935060a089013591508082111561474157600080fd5b5061474e89828a0161463d565b9150509295509295509295565b60008151808452602080850194506020840160005b838110156147955781516001600160a01b031687529582019590820190600101614770565b509495945050505050565b602081526000610e5d602083018461475b565b6000602082840312156147c557600080fd5b8135610e5d8161456c565b60a081016106a4828463ffffffff8082511683528060208301511660208401525061ffff604082015116604083015260608101516001600160a01b03808216606085015280608084015116608085015250505050565b60006020828403121561483857600080fd5b813567ffffffffffffffff81111561484f57600080fd5b820160a08185031215610e5d57600080fd5b600082601f83011261487257600080fd5b813560206148826145ad83614548565b82815260069290921b840181019181810190868411156148a157600080fd5b8286015b848110156145f957604081890312156148be5760008081fd5b6148c66144a7565b81356148d18161456c565b8152818501356148e08161456c565b818601528352918301916040016148a5565b6000806040838503121561490557600080fd5b823567ffffffffffffffff8082111561491d57600080fd5b61492986838701614861565b9350602085013591508082111561493f57600080fd5b5061494c85828601614861565b9150509250929050565b801515811461184f57600080fd5b80356143a281614956565b60006040828403121561498157600080fd5b6149896144a7565b905081356149968161456c565b808252506020820135602082015292915050565b600082601f8301126149bb57600080fd5b813560206149cb6145ad83614548565b8083825260208201915060208460061b8701019350868411156149ed57600080fd5b602086015b848110156145f957614a04888261496f565b8352918301916040016149f2565b600082601f830112614a2357600080fd5b81356020614a336145ad83614548565b82815260059290921b84018101918181019086841115614a5257600080fd5b8286015b848110156145f957803567ffffffffffffffff811115614a765760008081fd5b614a848986838b010161463d565b845250918301918301614a56565b600082601f830112614aa357600080fd5b81356020614ab36145ad83614548565b82815260059290921b84018101918181019086841115614ad257600080fd5b8286015b848110156145f957803567ffffffffffffffff811115614af65760008081fd5b614b048986838b0101614a12565b845250918301918301614ad6565b600082601f830112614b2357600080fd5b81356020614b336145ad83614548565b8083825260208201915060208460051b870101935086841115614b5557600080fd5b602086015b848110156145f95780358352918301918301614b5a565b600060808284031215614b8357600080fd5b614b8b6144d0565b9050813567ffffffffffffffff80821115614ba557600080fd5b818401915084601f830112614bb957600080fd5b81356020614bc96145ad83614548565b82815260059290921b84018101918181019088841115614be857600080fd5b8286015b84811015614d4457803586811115614c0357600080fd5b87016101a0818c03601f19011215614c1a57600080fd5b614c226144f3565b614c2d868301614397565b8152614c3b60408301614581565b86820152614c4b60608301614581565b6040820152614c5c60808301614397565b606082015260a08201356080820152614c7760c08301614964565b60a0820152614c8860e08301614397565b60c0820152610100614c9b818401614581565b60e083015261012080840135828401526101409150818401358a811115614cc157600080fd5b614ccf8f8a8388010161463d565b828501525050610160808401358a811115614ce957600080fd5b614cf78f8a838801016149aa565b83850152506101809150818401358a811115614d1257600080fd5b614d208f8a83880101614a12565b91840191909152506101a09290920135918101919091528352918301918301614bec565b5086525085810135935082841115614d5b57600080fd5b614d6787858801614a92565b90850152506040840135915080821115614d8057600080fd5b50614d8d84828501614b12565b6040830152506060820135606082015292915050565b63ffffffff8116811461184f57600080fd5b600082601f830112614dc657600080fd5b81356020614dd66145ad83614548565b8083825260208201915060208460051b870101935086841115614df857600080fd5b602086015b848110156145f9578035614e1081614da3565b8352918301918301614dfd565b6000806040808486031215614e3157600080fd5b833567ffffffffffffffff80821115614e4957600080fd5b614e5587838801614b71565b9450602091508186013581811115614e6c57600080fd5b8601601f81018813614e7d57600080fd5b8035614e8b6145ad82614548565b81815260059190911b8201840190848101908a831115614eaa57600080fd5b8584015b83811015614f1d57803586811115614ec65760008081fd5b8501808d03601f1901891315614edc5760008081fd5b614ee46144a7565b8882013581528982013588811115614efc5760008081fd5b614f0a8f8b83860101614db5565b828b015250845250918601918601614eae565b50809750505050505050509250929050565b60008083601f840112614f4157600080fd5b50813567ffffffffffffffff811115614f5957600080fd5b6020830191508360208260051b8501011115612db257600080fd5b60008060008060008060008060e0898b031215614f9057600080fd5b606089018a811115614fa157600080fd5b8998503567ffffffffffffffff80821115614fbb57600080fd5b818b0191508b601f830112614fcf57600080fd5b813581811115614fde57600080fd5b8c6020828501011115614ff057600080fd5b6020830199508098505060808b013591508082111561500e57600080fd5b61501a8c838d01614f2f565b909750955060a08b013591508082111561503357600080fd5b506150408b828c01614f2f565b999c989b50969995989497949560c00135949350505050565b6000806000806060858703121561506f57600080fd5b843567ffffffffffffffff8082111561508757600080fd5b908601906101a0828903121561509c57600080fd5b909450602086013590808211156150b257600080fd5b6150be88838901614f2f565b909550935060408701359150808211156150d757600080fd5b506150e487828801614db5565b91505092959194509250565b80356fffffffffffffffffffffffffffffffff811681146143a257600080fd5b60006060828403121561512257600080fd5b6040516060810181811067ffffffffffffffff8211171561514557615145614478565b604052823561515381614956565b8152615161602084016150f0565b6020820152615172604084016150f0565b60408201529392505050565b604081526000615191604083018561475b565b8281036020840152612eb3818561475b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106a4576106a46151a3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061522f5761522f6151e5565b92169190910692915050565b80820281158282048414176106a4576106a46151a3565b600067ffffffffffffffff8084168061526d5761526d6151e5565b92169190910492915050565b602081016003831061528d5761528d6143c4565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff8083168181036152db576152db6151a3565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153158184018a61475b565b90508281036080840152615329818961475b565b905060ff871660a084015282810360c08401526153468187614439565b905067ffffffffffffffff851660e084015282810361010084015261536b8185614439565b9c9b505050505050505050505050565b60006020828403121561538d57600080fd5b8151610e5d81614381565b600082601f8301126153a957600080fd5b81516153b76145ad82614615565b8181528460208386010111156153cc57600080fd5b611e33826020830160208701614415565b6000602082840312156153ef57600080fd5b815167ffffffffffffffff8082111561540757600080fd5b908301906080828603121561541b57600080fd5b6154236144d0565b82518281111561543257600080fd5b61543e87828601615398565b82525060208301518281111561545357600080fd5b61545f87828601615398565b60208301525060408301518281111561547757600080fd5b61548387828601615398565b6040830152506060830151925061549983614da3565b6060810192909252509392505050565b808201808211156106a4576106a46151a3565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154f157600080fd5b83018035915067ffffffffffffffff82111561550c57600080fd5b6020019150600681901b3603821315612db257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261555957600080fd5b83018035915067ffffffffffffffff82111561557457600080fd5b6020019150600581901b3603821315612db257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155c157600080fd5b83018035915067ffffffffffffffff8211156155dc57600080fd5b602001915036819003821315612db257600080fd5b60008151808452602080850194506020840160005b8381101561479557815180516001600160a01b031688528301518388015260409096019590820190600101615606565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152615671610120840182614439565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e08601526156ad8383614439565b9250608089015191508085840301610100860152506156cc82826155f1565b925050506156e0602083018661ffff169052565b836040830152612eb360608301846001600160a01b03169052565b60008060006060848603121561571057600080fd5b835161571b81614956565b602085015190935067ffffffffffffffff81111561573857600080fd5b61574486828701615398565b925050604084015190509250925092565b600060a0828403121561576757600080fd5b60405160a0810181811067ffffffffffffffff8211171561578a5761578a614478565b604052825161579881614da3565b815260208301516157a881614da3565b6020820152604083015161ffff811681146157c257600080fd5b604082015260608301516157d58161456c565b606082015260808301516157e88161456c565b60808201529392505050565b610180810161586582856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff1661012083015260608301516001600160a01b03908116610140840152608084015116610160830152610e5d565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526158f08285018b61475b565b91508382036080850152615904828a61475b565b915060ff881660a085015283820360c08501526159218288614439565b90861660e0850152838103610100850152905061536b8185614439565b60006020828403121561595057600080fd5b8151610e5d81614956565b60008151808452602080850194506020840160005b8381101561479557815187529582019590820190600101615970565b60608152600061599f606083018661595b565b82810360208401526159b1818661595b565b915050826040830152949350505050565b6000602082840312156159d457600080fd5b5051919050565b67ffffffffffffffff8181168382160190808211156141e7576141e76151a3565b67ffffffffffffffff8316815260408101610e5d60208301846143f3565b600067ffffffffffffffff8083168181036152db576152db6151a3565b615a4181846143f3565b604060208201526000611e336040830184614439565b600060208284031215615a6957600080fd5b813567ffffffffffffffff811115615a8057600080fd5b611e3384828501614b71565b600060408284031215615a9e57600080fd5b610e5d838361496f565b600060208284031215615aba57600080fd5b813567ffffffffffffffff80821115615ad257600080fd5b9083019060808286031215615ae657600080fd5b615aee6144d0565b823582811115615afd57600080fd5b615b098782860161463d565b825250602083013582811115615b1e57600080fd5b615b2a8782860161463d565b602083015250604083013582811115615b4257600080fd5b615b4e8782860161463d565b6040830152506060830135925061549983614da3565b602081526000610e5d60208301846155f1565b60008282518085526020808601955060208260051b8401016020860160005b84811015615bc457601f19868403018952615bb2838351614439565b98840198925090830190600101615b96565b5090979650505050505050565b602081526000610e5d6020830184615b77565b60008151808452602080850194506020840160005b8381101561479557815163ffffffff1687529582019590820190600101615bf9565b60608152615c3660608201855167ffffffffffffffff169052565b60006020850151615c5260808401826001600160a01b03169052565b5060408501516001600160a01b03811660a084015250606085015167ffffffffffffffff811660c084015250608085015160e083015260a0850151610100615c9d8185018315159052565b60c08701519150610120615cbc8186018467ffffffffffffffff169052565b60e08801519250610140615cda818701856001600160a01b03169052565b828901519350610160925083838701528189015193506101a091506101808281880152615d0b610200880186614439565b9450818a015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0808887030184890152615d4786846155f1565b948b01518886039091016101c0890152939450615d648585615b77565b9450808a01516101e0880152505050508281036020840152615d868186615b77565b90508281036040840152615d9a8185615be4565b9695505050505050565b600060208284031215615db657600080fd5b8151610e5d8161456c565b6020815260008251610100806020850152615de0610120850183614439565b91506020850151615dfd604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615e3760a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615e548483614439565b935060c08701519150808685030160e0870152615e718483614439565b935060e0870151915080868503018387015250615d9a8382614439565b600060408284031215615ea057600080fd5b615ea86144a7565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114615ed457600080fd5b81526020830151615ee481614da3565b60208201529392505050565b600082615eff57615eff6151e5565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"DestinationGasAmountCountMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"oldLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"tokenIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"oldLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenGasOverride\",\"type\":\"uint256\"}],\"name\":\"InvalidTokenGasOverride\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receiverExecutionGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"internalType\":\"structEVM2EVMOffRamp.GasLimitOverride[]\",\"name\":\"gasLimitOverrides\",\"type\":\"tuple[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101a06040523480156200001257600080fd5b5060405162006609380380620066098339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f40620006c9600039600081816102ec01528181611c6a01526133920152600081816102bd01528181611c420152611f2701526000818161028e01528181610d8d01528181610df201528181611c18015281816124a4015261250e015260006120c601526000818161025f0152611bee0152600081816101ff0152611b9201526000818161022f01528181611bc601528181611ee40152818161303b01526134bf0152600081816101d001528181611b6d01526121ac015260008181611e3e0152611e8a0152615f406000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806385572ffb116100d8578063afcb95d71161008c578063c92b283211610066578063c92b2832146105f3578063f077b59214610606578063f2fde38b1461061c57600080fd5b8063afcb95d7146105ad578063b1dc65a4146105cd578063b6113fce146105e057600080fd5b8063873504d7116100bd578063873504d7146105765780638926c4ee146105895780638da5cb5b1461059c57600080fd5b806385572ffb1461053c578063856c82471461054a57600080fd5b8063599f64311161013a5780637437ff9f116101145780637437ff9f1461046157806379ba50971461050457806381ff70481461050c57600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516103299190614311565b60405180910390f35b6103456103403660046143a7565b61062f565b6040516103299190614407565b61038e6040518060400160405280601481526020017f45564d3245564d4f666652616d7020312e352e3000000000000000000000000081525081565b6040516103299190614465565b6103ae6103a936600461468e565b6106aa565b005b6103b8610a9e565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610b53565b60405161032991906147a0565b6103ae61045c3660046147b3565b610bb5565b6104f76040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a01000000000000000000009091046001600160a01b039081166060830152600b5416608082015290565b60405161032991906147d0565b6103ae610c7e565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae610182366004614826565b61055d6105583660046147b3565b610d61565b60405167ffffffffffffffff9091168152602001610329565b6103ae6105843660046148f2565b610e64565b6103ae610597366004614e1d565b611037565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae6105db366004614f74565b61129c565b6103ae6105ee366004615059565b6114a7565b6103ae610601366004615110565b6117e7565b61060e611852565b60405161032992919061517e565b6103ae61062a3660046147b3565b611978565b600061063d600160046151d2565b600261064a608085615214565b67ffffffffffffffff1661065e919061523b565b6010600061066d608087615252565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106a4576106a46143c4565b92915050565b84518460ff16601f8211156106f75760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190615279565b60405180910390fd5b806000036107345760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190615279565b61073c611989565b610745856119ff565b60095460005b818110156107bc57600860006009838154811061076a5761076a615293565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161074b565b5050865160005b8181101561095f5760008982815181106107df576107df615293565b60200260200101519050600060028111156107fc576107fc6143c4565b6001600160a01b038216600090815260086020526040902054610100900460ff16600281111561082e5761082e6143c4565b146108685760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190615279565b6001600160a01b0381166108a8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561094b5761094b6143c4565b0217905550905050508060010190506107c3565b5087516109739060099060208b019061427f565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a1617179055600780546109f99146913091906000906109cb9063ffffffff166152c2565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611cc9565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610a8a9487949293918316921691909117908f908f908f908f908f908f906152e5565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610b4e90611d56565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bab57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8d575b5050505050905090565b6000546001600160a01b03163314801590610bdb57506002546001600160a01b03163314155b15610c12576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b6001546001600160a01b03163314610cf2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106ee565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106a4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106a4576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5d919061537b565b9392505050565b610e6c611989565b60005b8251811015610f3f57610ea9838281518110610e8d57610e8d615293565b602002602001015160200151600c611e0890919063ffffffff16565b15610f37577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d58782838281518110610ee157610ee1615293565b602002602001015160000151848381518110610eff57610eff615293565b602002602001015160200151604051610f2e9291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610e6f565b5060005b815181101561103257610f9c828281518110610f6157610f61615293565b602002602001015160200151838381518110610f7f57610f7f615293565b602002602001015160000151600c611e1d9092919063ffffffff16565b1561102a577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a828281518110610fd457610fd4615293565b602002602001015160000151838381518110610ff257610ff2615293565b6020026020010151602001516040516110219291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610f43565b505050565b61103f611e3b565b8151518151811461107c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156112915760008460000151828151811061109f5761109f615293565b6020026020010151905060008483815181106110bd576110bd615293565b60209081029190910101518051909150801561112c57826080015181101561112c5761018083015160808401516040517f9c6db58d00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016106ee565b816020015151836101400151511461118e5761018083015160608401516040517f85d2e5bf000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff1660248201526044016106ee565b61016083015160005b846101400151518110156112815760008287815181106111b9576111b9615293565b60200260200101518060200190518101906111d491906153dd565b90506000856020015183815181106111ee576111ee615293565b602002602001015163ffffffff169050806000141580156112185750816060015163ffffffff1681105b156112775761018087015160608301516040517fef0c635200000000000000000000000000000000000000000000000000000000815260048101929092526024820185905263ffffffff166044820152606481018290526084016106ee565b5050600101611197565b505050505080600101905061107f565b506110328383611ebc565b6112a6878761290f565b6005548835908082146112ef576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016106ee565b6112f7611e3b565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561137f5761137f6143c4565b6002811115611390576113906143c4565b90525090506002816020015160028111156113ad576113ad6143c4565b1480156113e757506009816000015160ff16815481106113cf576113cf615293565b6000918252602090912001546001600160a01b031633145b61141d576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061142b85602061523b565b61143688602061523b565b6114428b6101446154a9565b61144c91906154a9565b61145691906154a9565b905036811461149a576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016106ee565b5050505050505050505050565b3330146114e0576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516000808252602082019092528161151d565b60408051808201909152600080825260208201528152602001906001900390816114f65790505b50905060006115306101408701876154bc565b905011156115a7576115a46115496101408701876154bc565b6115596040890160208a016147b3565b604080516001600160a01b0390921660208301520160408051601f1981840301815291815261158e9060608b01908b016147b3565b61159c6101608b018b615524565b8a8a8a612966565b90505b6115b561012086018661558c565b15905080156115c657506080850135155b806115e857506115dc60608601604087016147b3565b6001600160a01b03163b155b8061163357506116317f85572ffb0000000000000000000000000000000000000000000000000000000061162260608801604089016147b3565b6001600160a01b031690612b8f565b155b1561163e57506117e1565b600a546040805160a08101909152610180870135815260009182916a01000000000000000000009091046001600160a01b031690633cf979839060208082019061168a908c018c6143a7565b67ffffffffffffffff1681526020018a60200160208101906116ac91906147b3565b604080516001600160a01b0390921660208301520160408051601f1981840301815291905281526020016116e46101208c018c61558c565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200186905261138860808b013561173960608d0160408e016147b3565b6040518563ffffffff1660e01b81526004016117589493929190615636565b6000604051808303816000875af1158015611777573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261179f91908101906156fb565b5091509150816117dd57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b5050505b50505050565b6000546001600160a01b0316331480159061180d57506002546001600160a01b03163314155b15611844576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61184f600382612bab565b50565b6060806000611861600c612d90565b90508067ffffffffffffffff81111561187c5761187c614478565b6040519080825280602002602001820160405280156118a5578160200160208202803683370190505b5092508067ffffffffffffffff8111156118c1576118c1614478565b6040519080825280602002602001820160405280156118ea578160200160208202803683370190505b50915060005b8181101561197257600080611906600c84612d9b565b915091508086848151811061191d5761191d615293565b60200260200101906001600160a01b031690816001600160a01b0316815250508185848151811061195057611950615293565b6001600160a01b039092166020928302919091019091015250506001016118f0565b50509091565b611980611989565b61184f81612db9565b6000546001600160a01b031633146119fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106ee565b565b600081806020019051810190611a159190615755565b60608101519091506001600160a01b0316611a5c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a01000000000000000000006001600160a01b039485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611cbd9184906157f4565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611ced999897969594939291906158b6565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611de482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611dc891906151d2565b85608001516fffffffffffffffffffffffffffffffff16612e94565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6000610e5d836001600160a01b038416612ebc565b6000611e33846001600160a01b03851684612ec8565b949350505050565b467f0000000000000000000000000000000000000000000000000000000000000000146119fd576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016106ee565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611f76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9a919061593e565b15611fd1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815151600081900361200e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015151811461204c576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561206757612067614478565b604051908082528060200260200182016040528015612090578160200160208202803683370190505b50905060005b82811015612168576000856000015182815181106120b6576120b6615293565b602002602001015190506120ea817f0000000000000000000000000000000000000000000000000000000000000000612ede565b8383815181106120fc576120fc615293565b60200260200101818152505080610180015183838151811061212057612120615293565b60200260200101511461215f576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101612096565b508251604080860151606087015191517f32048875000000000000000000000000000000000000000000000000000000008152921515926000926001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926332048875926121e29288929160040161598c565b602060405180830381865afa1580156121ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222391906159c2565b90508060000361225f576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b848110156117dd5760008760000151828151811061228257612282615293565b60200260200101519050600061229b826060015161062f565b905060008160038111156122b1576122b16143c4565b14806122ce575060038160038111156122cc576122cc6143c4565b145b61231457816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a25050612907565b606085156123fa5788848151811061232e5761232e615293565b6020908102919091018101510151600a5490915060009063ffffffff1661235587426151d2565b119050808061237557506003836003811115612373576123736143c4565b145b6123ab576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8985815181106123bd576123bd615293565b6020026020010151600001516000146123f4578985815181106123e2576123e2615293565b60209081029190910101515160808501525b5061245e565b600082600381111561240e5761240e6143c4565b1461245e57606083015160405167ffffffffffffffff90911681527f67d9ba0f63d427c482c2736300e6d5a34c6691dbcdea8ad35828a1f1ba47e8729060200160405180910390a1505050612907565b60c083015167ffffffffffffffff16156126df576020808401516001600160a01b03166000908152600f909152604081205467ffffffffffffffff1690819003612649577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156126495760208401516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa158015612557573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257b919061537b565b60c085015190915067ffffffffffffffff166125988260016159db565b67ffffffffffffffff16146125f95783602001516001600160a01b03168460c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a350505050612907565b6020848101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b600083600381111561265d5761265d6143c4565b036126dd5760c084015167ffffffffffffffff1661267c8260016159db565b67ffffffffffffffff16146126dd5783602001516001600160a01b03168460c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a350505050612907565b505b60008a6020015185815181106126f7576126f7615293565b602002602001015190506127238460600151856000015186610140015151876101200151518551613039565b612732846060015160016131ba565b600080612740868486613264565b915091506127528660600151836131ba565b88156127be57600382600381111561276c5761276c6143c4565b036127be576000856003811115612785576127856143c4565b146127be57806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b60028260038111156127d2576127d26143c4565b1461282a5760038260038111156127eb576127eb6143c4565b1461282a578560600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016106ee9291906159fc565b60c086015167ffffffffffffffff16156128b2576000856003811115612852576128526143c4565b036128b2576020808701516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff169161288a83615a1a565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b856101800151866060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef6584846040516128f8929190615a37565b60405180910390a35050505050505b600101612262565b61296261291e82840184615a57565b604080516000808252602082019092529061295c565b6040805180820190915260008152606060208201528152602001906001900390816129345790505b50611ebc565b5050565b60608989808060200260200160405190810160405280939291908181526020016000905b828210156129b6576129a760408302860136819003810190615a8c565b8152602001906001019061298a565b505050505090506000805b8a811015612b715760008888838181106129dd576129dd615293565b90506020028101906129ef919061558c565b8101906129fc9190615aa8565b90508451600014612a5757848281518110612a1957612a19615293565b602002602001015163ffffffff16600014612a5757848281518110612a4057612a40615293565b602090810291909101015163ffffffff1660608201525b612ad78d8d84818110612a6c57612a6c615293565b905060400201602001358c8c848b8b88818110612a8b57612a8b615293565b9050602002810190612a9d919061558c565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061333192505050565b848381518110612ae957612ae9615293565b6020026020010181905250612b25848381518110612b0957612b09615293565b602002602001015160000151600c6136fd90919063ffffffff16565b15612b6857612b5b848381518110612b3f57612b3f615293565b6020908102919091010151600b546001600160a01b0316613712565b612b6590846154a9565b92505b506001016129c1565b508015612b8157612b8181613833565b509998505050505050505050565b6000612b9a83613840565b8015610e5d5750610e5d83836138a4565b8154600090612bd490700100000000000000000000000000000000900463ffffffff16426151d2565b90508015612c765760018301548354612c1c916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e94565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c9c916fffffffffffffffffffffffffffffffff9081169116613973565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612d839084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106a482613989565b6000808080612daa8686613994565b909450925050505b9250929050565b336001600160a01b03821603612e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106ee565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612eb385612ea4848661523b565b612eae90876154a9565b613973565b95945050505050565b6000610e5d83836139a3565b6000611e3384846001600160a01b0385166139c0565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612f749897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612fad9190615b64565b60405160208183030381529060405280519060200120876101600151604051602001612fd99190615bd1565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff16146130b2576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016106ee565b600a5468010000000000000000900461ffff1683111561310a576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b80831461314f576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b600a54640100000000900463ffffffff168211156131b357600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff166004820152602481018390526044016106ee565b5050505050565b600060026131c9608085615214565b67ffffffffffffffff166131dd919061523b565b905060006010816131ef608087615252565b67ffffffffffffffff168152602081019190915260400160002054905081613219600160046151d2565b901b191681836003811115613230576132306143c4565b901b178060106000613243608088615252565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517fb6113fce000000000000000000000000000000000000000000000000000000008152600090606090309063b6113fce906132aa90889088908890600401615c1b565b600060405180830381600087803b1580156132c457600080fd5b505af19250505080156132d5575060015b613314573d808015613303576040519150601f19603f3d011682016040523d82523d6000602084013e613308565b606091505b50600392509050613329565b50506040805160208101909152600081526002905b935093915050565b6040805180820190915260008082526020820152600061335484602001516139dd565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa1580156133d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fd9190615da4565b90506001600160a01b038116158061344557506134436001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612b8f565b155b15613487576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016106ee565b60008061349f8885896060015163ffffffff16613a83565b91509150600080600061359d6040518061010001604052808e81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018d6001600160a01b031681526020018f8152602001896001600160a01b031681526020018c6000015181526020018c6040015181526020018b8152506040516024016135399190615dc1565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613bc6565b925092509250826135dc57816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b81516020146136245781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b60008280602001905181019061363a91906159c2565b9050866001600160a01b03168c6001600160a01b0316146136cf57600061366b8d8a613666868a6151d2565b613a83565b5090508681108061368557508161368288836151d2565b14155b156136cd576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016106ee565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000610e5d836001600160a01b038416613cec565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613778573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379c9190615e8e565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036138055783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016106ee565b6020840151611e33907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690613cf8565b61184f6003826000613d35565b600061386c827f01ffc9a7000000000000000000000000000000000000000000000000000000006138a4565b80156106a4575061389d827fffffffff000000000000000000000000000000000000000000000000000000006138a4565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561395c575060208210155b80156139685750600081115b979650505050505050565b60008183106139825781610e5d565b5090919050565b60006106a482614084565b6000808080612daa868661408f565b60008181526002830160205260408120819055610e5d83836140ba565b60008281526002840160205260408120829055611e3384846140c6565b60008151602014613a1c57816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b600082806020019051810190613a3291906159c2565b90506001600160a01b03811180613a4a575061040081105b156106a457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b6000806000806000613b1288604051602401613aae91906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613bc6565b92509250925082613b5157816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b6020825114613b995781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b81806020019051810190613bad91906159c2565b613bb782886151d2565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613be957613be9614478565b6040519080825280601f01601f191660200182016040528015613c13576020820181803683370190505b509150863b613c46577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613c79577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613cb2577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613cd55750835b808352806000602085013e50955095509592505050565b6000610e5d83836140d2565b6000670de0b6b3a7640000613d2b837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff861661523b565b610e5d9190615ef0565b825474010000000000000000000000000000000000000000900460ff161580613d5c575081155b15613d6657505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090613dac90700100000000000000000000000000000000900463ffffffff16426151d2565b90508015613e6c5781831115613dee576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613e289083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e94565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613f09576001600160a01b038416613ebe576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106ee565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b03851660448201526064016106ee565b848310156140025760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613f4d90826151d2565b613f57878a6151d2565b613f6191906154a9565b613f6b9190615ef0565b90506001600160a01b038616613fb7576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106ee565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b03871660448201526064016106ee565b61400c85846151d2565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60006106a4826140de565b6000808061409d85856140e8565b600081815260029690960160205260409095205494959350505050565b6000610e5d83836140f4565b6000610e5d83836141ee565b6000610e5d838361423d565b60006106a4825490565b6000610e5d8383614255565b600081815260018301602052604081205480156141dd5760006141186001836151d2565b855490915060009061412c906001906151d2565b905081811461419157600086600001828154811061414c5761414c615293565b906000526020600020015490508087600001848154811061416f5761416f615293565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806141a2576141a2615f04565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106a4565b60009150506106a4565b5092915050565b6000818152600183016020526040812054614235575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106a4565b5060006106a4565b60008181526001830160205260408120541515610e5d565b600082600001828154811061426c5761426c615293565b9060005260206000200154905092915050565b8280548282559060005260206000209081019282156142ec579160200282015b828111156142ec57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0390911617825560209092019160019091019061429f565b506142f89291506142fc565b5090565b5b808211156142f857600081556001016142fd565b60e081016106a482846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff8116811461184f57600080fd5b80356143a281614381565b919050565b6000602082840312156143b957600080fd5b8135610e5d81614381565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110614403576144036143c4565b9052565b602081016106a482846143f3565b60005b83811015614430578181015183820152602001614418565b50506000910152565b60008151808452614451816020860160208601614415565b601f01601f19169290920160200192915050565b602081526000610e5d6020830184614439565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156144ca576144ca614478565b60405290565b6040516080810167ffffffffffffffff811182821017156144ca576144ca614478565b6040516101a0810167ffffffffffffffff811182821017156144ca576144ca614478565b604051601f8201601f1916810167ffffffffffffffff8111828210171561454057614540614478565b604052919050565b600067ffffffffffffffff82111561456257614562614478565b5060051b60200190565b6001600160a01b038116811461184f57600080fd5b80356143a28161456c565b600082601f83011261459d57600080fd5b813560206145b26145ad83614548565b614517565b8083825260208201915060208460051b8701019350868411156145d457600080fd5b602086015b848110156145f95780356145ec8161456c565b83529183019183016145d9565b509695505050505050565b803560ff811681146143a257600080fd5b600067ffffffffffffffff82111561462f5761462f614478565b50601f01601f191660200190565b600082601f83011261464e57600080fd5b813561465c6145ad82614615565b81815284602083860101111561467157600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156146a757600080fd5b863567ffffffffffffffff808211156146bf57600080fd5b6146cb8a838b0161458c565b975060208901359150808211156146e157600080fd5b6146ed8a838b0161458c565b96506146fb60408a01614604565b9550606089013591508082111561471157600080fd5b61471d8a838b0161463d565b945061472b60808a01614397565b935060a089013591508082111561474157600080fd5b5061474e89828a0161463d565b9150509295509295509295565b60008151808452602080850194506020840160005b838110156147955781516001600160a01b031687529582019590820190600101614770565b509495945050505050565b602081526000610e5d602083018461475b565b6000602082840312156147c557600080fd5b8135610e5d8161456c565b60a081016106a4828463ffffffff8082511683528060208301511660208401525061ffff604082015116604083015260608101516001600160a01b03808216606085015280608084015116608085015250505050565b60006020828403121561483857600080fd5b813567ffffffffffffffff81111561484f57600080fd5b820160a08185031215610e5d57600080fd5b600082601f83011261487257600080fd5b813560206148826145ad83614548565b82815260069290921b840181019181810190868411156148a157600080fd5b8286015b848110156145f957604081890312156148be5760008081fd5b6148c66144a7565b81356148d18161456c565b8152818501356148e08161456c565b818601528352918301916040016148a5565b6000806040838503121561490557600080fd5b823567ffffffffffffffff8082111561491d57600080fd5b61492986838701614861565b9350602085013591508082111561493f57600080fd5b5061494c85828601614861565b9150509250929050565b801515811461184f57600080fd5b80356143a281614956565b60006040828403121561498157600080fd5b6149896144a7565b905081356149968161456c565b808252506020820135602082015292915050565b600082601f8301126149bb57600080fd5b813560206149cb6145ad83614548565b8083825260208201915060208460061b8701019350868411156149ed57600080fd5b602086015b848110156145f957614a04888261496f565b8352918301916040016149f2565b600082601f830112614a2357600080fd5b81356020614a336145ad83614548565b82815260059290921b84018101918181019086841115614a5257600080fd5b8286015b848110156145f957803567ffffffffffffffff811115614a765760008081fd5b614a848986838b010161463d565b845250918301918301614a56565b600082601f830112614aa357600080fd5b81356020614ab36145ad83614548565b82815260059290921b84018101918181019086841115614ad257600080fd5b8286015b848110156145f957803567ffffffffffffffff811115614af65760008081fd5b614b048986838b0101614a12565b845250918301918301614ad6565b600082601f830112614b2357600080fd5b81356020614b336145ad83614548565b8083825260208201915060208460051b870101935086841115614b5557600080fd5b602086015b848110156145f95780358352918301918301614b5a565b600060808284031215614b8357600080fd5b614b8b6144d0565b9050813567ffffffffffffffff80821115614ba557600080fd5b818401915084601f830112614bb957600080fd5b81356020614bc96145ad83614548565b82815260059290921b84018101918181019088841115614be857600080fd5b8286015b84811015614d4457803586811115614c0357600080fd5b87016101a0818c03601f19011215614c1a57600080fd5b614c226144f3565b614c2d868301614397565b8152614c3b60408301614581565b86820152614c4b60608301614581565b6040820152614c5c60808301614397565b606082015260a08201356080820152614c7760c08301614964565b60a0820152614c8860e08301614397565b60c0820152610100614c9b818401614581565b60e083015261012080840135828401526101409150818401358a811115614cc157600080fd5b614ccf8f8a8388010161463d565b828501525050610160808401358a811115614ce957600080fd5b614cf78f8a838801016149aa565b83850152506101809150818401358a811115614d1257600080fd5b614d208f8a83880101614a12565b91840191909152506101a09290920135918101919091528352918301918301614bec565b5086525085810135935082841115614d5b57600080fd5b614d6787858801614a92565b90850152506040840135915080821115614d8057600080fd5b50614d8d84828501614b12565b6040830152506060820135606082015292915050565b63ffffffff8116811461184f57600080fd5b600082601f830112614dc657600080fd5b81356020614dd66145ad83614548565b8083825260208201915060208460051b870101935086841115614df857600080fd5b602086015b848110156145f9578035614e1081614da3565b8352918301918301614dfd565b6000806040808486031215614e3157600080fd5b833567ffffffffffffffff80821115614e4957600080fd5b614e5587838801614b71565b9450602091508186013581811115614e6c57600080fd5b8601601f81018813614e7d57600080fd5b8035614e8b6145ad82614548565b81815260059190911b8201840190848101908a831115614eaa57600080fd5b8584015b83811015614f1d57803586811115614ec65760008081fd5b8501808d03601f1901891315614edc5760008081fd5b614ee46144a7565b8882013581528982013588811115614efc5760008081fd5b614f0a8f8b83860101614db5565b828b015250845250918601918601614eae565b50809750505050505050509250929050565b60008083601f840112614f4157600080fd5b50813567ffffffffffffffff811115614f5957600080fd5b6020830191508360208260051b8501011115612db257600080fd5b60008060008060008060008060e0898b031215614f9057600080fd5b606089018a811115614fa157600080fd5b8998503567ffffffffffffffff80821115614fbb57600080fd5b818b0191508b601f830112614fcf57600080fd5b813581811115614fde57600080fd5b8c6020828501011115614ff057600080fd5b6020830199508098505060808b013591508082111561500e57600080fd5b61501a8c838d01614f2f565b909750955060a08b013591508082111561503357600080fd5b506150408b828c01614f2f565b999c989b50969995989497949560c00135949350505050565b6000806000806060858703121561506f57600080fd5b843567ffffffffffffffff8082111561508757600080fd5b908601906101a0828903121561509c57600080fd5b909450602086013590808211156150b257600080fd5b6150be88838901614f2f565b909550935060408701359150808211156150d757600080fd5b506150e487828801614db5565b91505092959194509250565b80356fffffffffffffffffffffffffffffffff811681146143a257600080fd5b60006060828403121561512257600080fd5b6040516060810181811067ffffffffffffffff8211171561514557615145614478565b604052823561515381614956565b8152615161602084016150f0565b6020820152615172604084016150f0565b60408201529392505050565b604081526000615191604083018561475b565b8281036020840152612eb3818561475b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106a4576106a46151a3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061522f5761522f6151e5565b92169190910692915050565b80820281158282048414176106a4576106a46151a3565b600067ffffffffffffffff8084168061526d5761526d6151e5565b92169190910492915050565b602081016003831061528d5761528d6143c4565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff8083168181036152db576152db6151a3565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153158184018a61475b565b90508281036080840152615329818961475b565b905060ff871660a084015282810360c08401526153468187614439565b905067ffffffffffffffff851660e084015282810361010084015261536b8185614439565b9c9b505050505050505050505050565b60006020828403121561538d57600080fd5b8151610e5d81614381565b600082601f8301126153a957600080fd5b81516153b76145ad82614615565b8181528460208386010111156153cc57600080fd5b611e33826020830160208701614415565b6000602082840312156153ef57600080fd5b815167ffffffffffffffff8082111561540757600080fd5b908301906080828603121561541b57600080fd5b6154236144d0565b82518281111561543257600080fd5b61543e87828601615398565b82525060208301518281111561545357600080fd5b61545f87828601615398565b60208301525060408301518281111561547757600080fd5b61548387828601615398565b6040830152506060830151925061549983614da3565b6060810192909252509392505050565b808201808211156106a4576106a46151a3565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154f157600080fd5b83018035915067ffffffffffffffff82111561550c57600080fd5b6020019150600681901b3603821315612db257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261555957600080fd5b83018035915067ffffffffffffffff82111561557457600080fd5b6020019150600581901b3603821315612db257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155c157600080fd5b83018035915067ffffffffffffffff8211156155dc57600080fd5b602001915036819003821315612db257600080fd5b60008151808452602080850194506020840160005b8381101561479557815180516001600160a01b031688528301518388015260409096019590820190600101615606565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152615671610120840182614439565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e08601526156ad8383614439565b9250608089015191508085840301610100860152506156cc82826155f1565b925050506156e0602083018661ffff169052565b836040830152612eb360608301846001600160a01b03169052565b60008060006060848603121561571057600080fd5b835161571b81614956565b602085015190935067ffffffffffffffff81111561573857600080fd5b61574486828701615398565b925050604084015190509250925092565b600060a0828403121561576757600080fd5b60405160a0810181811067ffffffffffffffff8211171561578a5761578a614478565b604052825161579881614da3565b815260208301516157a881614da3565b6020820152604083015161ffff811681146157c257600080fd5b604082015260608301516157d58161456c565b606082015260808301516157e88161456c565b60808201529392505050565b610180810161586582856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff1661012083015260608301516001600160a01b03908116610140840152608084015116610160830152610e5d565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526158f08285018b61475b565b91508382036080850152615904828a61475b565b915060ff881660a085015283820360c08501526159218288614439565b90861660e0850152838103610100850152905061536b8185614439565b60006020828403121561595057600080fd5b8151610e5d81614956565b60008151808452602080850194506020840160005b8381101561479557815187529582019590820190600101615970565b60608152600061599f606083018661595b565b82810360208401526159b1818661595b565b915050826040830152949350505050565b6000602082840312156159d457600080fd5b5051919050565b67ffffffffffffffff8181168382160190808211156141e7576141e76151a3565b67ffffffffffffffff8316815260408101610e5d60208301846143f3565b600067ffffffffffffffff8083168181036152db576152db6151a3565b615a4181846143f3565b604060208201526000611e336040830184614439565b600060208284031215615a6957600080fd5b813567ffffffffffffffff811115615a8057600080fd5b611e3384828501614b71565b600060408284031215615a9e57600080fd5b610e5d838361496f565b600060208284031215615aba57600080fd5b813567ffffffffffffffff80821115615ad257600080fd5b9083019060808286031215615ae657600080fd5b615aee6144d0565b823582811115615afd57600080fd5b615b098782860161463d565b825250602083013582811115615b1e57600080fd5b615b2a8782860161463d565b602083015250604083013582811115615b4257600080fd5b615b4e8782860161463d565b6040830152506060830135925061549983614da3565b602081526000610e5d60208301846155f1565b60008282518085526020808601955060208260051b8401016020860160005b84811015615bc457601f19868403018952615bb2838351614439565b98840198925090830190600101615b96565b5090979650505050505050565b602081526000610e5d6020830184615b77565b60008151808452602080850194506020840160005b8381101561479557815163ffffffff1687529582019590820190600101615bf9565b60608152615c3660608201855167ffffffffffffffff169052565b60006020850151615c5260808401826001600160a01b03169052565b5060408501516001600160a01b03811660a084015250606085015167ffffffffffffffff811660c084015250608085015160e083015260a0850151610100615c9d8185018315159052565b60c08701519150610120615cbc8186018467ffffffffffffffff169052565b60e08801519250610140615cda818701856001600160a01b03169052565b828901519350610160925083838701528189015193506101a091506101808281880152615d0b610200880186614439565b9450818a015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0808887030184890152615d4786846155f1565b948b01518886039091016101c0890152939450615d648585615b77565b9450808a01516101e0880152505050508281036020840152615d868186615b77565b90508281036040840152615d9a8185615be4565b9695505050505050565b600060208284031215615db657600080fd5b8151610e5d8161456c565b6020815260008251610100806020850152615de0610120850183614439565b91506020850151615dfd604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615e3760a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615e548483614439565b935060c08701519150808685030160e0870152615e718483614439565b935060e0870151915080868503018387015250615d9a8382614439565b600060408284031215615ea057600080fd5b615ea86144a7565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114615ed457600080fd5b81526020830151615ee481614da3565b60208201529392505050565b600082615eff57615eff6151e5565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var EVM2EVMOffRampABI = EVM2EVMOffRampMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go index d186229b59..83302ca08e 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go @@ -142,7 +142,7 @@ type RateLimiterTokenBucket struct { var EVM2EVMOnRampMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidChainSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"}],\"name\":\"InvalidNopAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWithdrawParams\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkBalanceNotSettled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeeBalanceReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoFeesToPay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoNopsToPay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdminOrNop\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyNops\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeConfig\",\"type\":\"tuple[]\"}],\"name\":\"FeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NopPaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nopWeightsTotal\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"NopsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"transferFeeConfig\",\"type\":\"tuple[]\"}],\"name\":\"TokenTransferFeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getFeeTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfig\",\"name\":\"feeTokenConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNopFeesJuels\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNops\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"weightsTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setFeeTokenConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"address[]\"}],\"name\":\"setTokenTransferFeeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawNonLinkFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101a06040523480156200001257600080fd5b506040516200822d3803806200822d833981016040819052620000359162001a93565b8333806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c0816200030b565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555085516001600160a01b0316158062000169575060208601516001600160401b0316155b8062000180575060408601516001600160401b0316155b8062000197575060608601516001600160401b0316155b80620001ae575060c08601516001600160a01b0316155b80620001c5575060e08601516001600160a01b0316155b15620001e4576040516306b7c75960e31b815260040160405180910390fd5b60208087015160408089015181517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3948101949094526001600160401b039283169184019190915216606082015230608082015260a00160408051601f198184030181529181528151602092830120608090815288516001600160a01b0390811660e0908152938a01516001600160401b0390811661010052928a015183166101205260608a015190921660a0908152908901516001600160601b031660c090815290890151821661014052880151811661016052908701511661018052620002cd85620003b6565b620002d883620006ad565b604080516000815260208101909152620002f4908390620007dd565b620002ff8162000a83565b5050505050506200218a565b336001600160a01b03821603620003655760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e08101516001600160a01b0316620003e2576040516306b7c75960e31b815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548160ff0219169083151502179055509050507f45b5ad483aa608464c2c7f278bd413d284d7790cdc836e40652e23a02770822060405180610100016040528060e0516001600160a01b03168152602001610100516001600160401b03168152602001610120516001600160401b0316815260200160a0516001600160401b0316815260200160c0516001600160601b03168152602001610140516001600160a01b03168152602001610160516001600160a01b03168152602001610180516001600160a01b031681525082604051620006a292919062001d1c565b60405180910390a150565b60005b8151811015620007ab576000828281518110620006d157620006d162001de1565b60209081029190910181015160408051608080820183528385015163ffffffff9081168352838501516001600160401b03908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b0260ff60a01b199688166c010000000000000000000000000296909616600160601b600160a81b031993909716640100000000026001600160601b031990951691161792909217919091169290921717905550600101620006b0565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e81604051620006a2919062001df7565b60005b8251811015620009a257600083828151811062000801576200080162001de1565b60200260200101519050602063ffffffff168160a0015163ffffffff1610156200085d57805160a08201516040516312766e0160e11b81526001600160a01b03909216600483015263ffffffff16602482015260440162000084565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087166001600160401b031990961695909517640100000000928716929092029190911765ffffffffffff60401b191668010000000000000000939092169290920263ffffffff60501b1916176a0100000000000000000000918416919091021764ffffffffff60701b1916600160701b939092169290920260ff60901b191617600160901b941515949094029390931760ff60981b1916600160981b931515939093029290921790915501620007e0565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d082604051620009d4919062001e86565b60405180910390a160005b815181101562000a3c57600c600083838151811062000a025762000a0262001de1565b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055600101620009df565b5080511562000a7f577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b8160405162000a76919062001f1b565b60405180910390a15b5050565b8051604081111562000aa857604051635ad0867d60e11b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff161562000afb57600e5463ffffffff6c010000000000000000000000008204166001600160601b039091161062000afb5762000afb62000c9e565b600062000b09600862000e8a565b90505b801562000b5557600062000b2f62000b2660018462001f80565b60089062000e9d565b50905062000b3f60088262000ebb565b50508062000b4d9062001f96565b905062000b0c565b506000805b8281101562000c3557600084828151811062000b7a5762000b7a62001de1565b6020026020010151600001519050600085838151811062000b9f5762000b9f62001de1565b602002602001015160200151905060e0516001600160a01b0316826001600160a01b0316148062000bd757506001600160a01b038216155b1562000c0257604051634de938d160e01b81526001600160a01b038316600482015260240162000084565b62000c1460088361ffff841662000ed9565b5062000c2561ffff82168562001fb0565b9350505080600101905062000b5a565b50600e805463ffffffff60601b19166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249062000c91908390869062001fd0565b60405180910390a1505050565b6000546001600160a01b0316331462000cef576002546001600160a01b0316331462000cef5762000cd160083362000ef9565b62000cef5760405163032bb72b60e31b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff16600081900362000d2b5760405163990e30bf60e01b815260040160405180910390fd5b600e546001600160601b03168181101562000d59576040516311a1ee3b60e31b815260040160405180910390fd5b600062000d6562000f10565b121562000d8557604051631e9acf1760e31b815260040160405180910390fd5b80600062000d94600862000e8a565b905060005b8181101562000e645760008062000db260088462000e9d565b909250905060008762000dcf836001600160601b038a1662002040565b62000ddb91906200205a565b905062000de981876200207d565b60e05190965062000e0e906001600160a01b0316846001600160601b03841662000f9e565b6040516001600160601b03821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a250505080600101905062000d99565b5050600e80546001600160601b0319166001600160601b03929092169190911790555050565b600062000e978262000ffb565b92915050565b600080808062000eae868662001008565b9097909650945050505050565b600062000ed2836001600160a01b03841662001035565b9392505050565b600062000ef1846001600160a01b0385168462001054565b949350505050565b600062000ed2836001600160a01b03841662001073565b600e5460e0516040516370a0823160e01b81523060048201526000926001600160601b0316916001600160a01b0316906370a0823190602401602060405180830381865afa15801562000f67573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f8d9190620020a0565b62000f999190620020ba565b905090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915262000ff69185916200108116565b505050565b600062000e978262001152565b600080806200101885856200115d565b600081815260029690960160205260409095205494959350505050565b6000818152600283016020526040812081905562000ed283836200116b565b6000828152600284016020526040812082905562000ef1848462001179565b600062000ed2838362001187565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620010d0906001600160a01b038516908490620011a0565b80519091501562000ff65780806020019051810190620010f19190620020dd565b62000ff65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000084565b600062000e97825490565b600062000ed28383620011b1565b600062000ed28383620011de565b600062000ed28383620012e9565b6000818152600183016020526040812054151562000ed2565b606062000ef184846000856200133b565b6000826000018281548110620011cb57620011cb62001de1565b9060005260206000200154905092915050565b60008181526001830160205260408120548015620012d75760006200120560018362001f80565b85549091506000906200121b9060019062001f80565b9050818114620012875760008660000182815481106200123f576200123f62001de1565b906000526020600020015490508087600001848154811062001265576200126562001de1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200129b576200129b620020fb565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e97565b600091505062000e97565b5092915050565b6000818152600183016020526040812054620013325750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e97565b50600062000e97565b6060824710156200139e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000084565b600080866001600160a01b03168587604051620013bc919062002137565b60006040518083038185875af1925050503d8060008114620013fb576040519150601f19603f3d011682016040523d82523d6000602084013e62001400565b606091505b50909250905062001414878383876200141f565b979650505050505050565b60608315620014935782516000036200148b576001600160a01b0385163b6200148b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000084565b508162000ef1565b62000ef18383815115620014aa5781518083602001fd5b8060405162461bcd60e51b815260040162000084919062002155565b634e487b7160e01b600052604160045260246000fd5b6040516101a081016001600160401b0381118282101715620015025762001502620014c6565b60405290565b60405160a081016001600160401b0381118282101715620015025762001502620014c6565b60405160e081016001600160401b0381118282101715620015025762001502620014c6565b604080519081016001600160401b0381118282101715620015025762001502620014c6565b60405161010081016001600160401b0381118282101715620015025762001502620014c6565b604051601f8201601f191681016001600160401b0381118282101715620015c857620015c8620014c6565b604052919050565b80516001600160a01b0381168114620015e857600080fd5b919050565b80516001600160401b0381168114620015e857600080fd5b805161ffff81168114620015e857600080fd5b805163ffffffff81168114620015e857600080fd5b80518015158114620015e857600080fd5b60006101a082840312156200165257600080fd5b6200165c620014dc565b90506200166982620015d0565b8152620016796020830162001605565b60208201526200168c6040830162001618565b60408201526200169f6060830162001605565b6060820152620016b26080830162001618565b6080820152620016c560a0830162001605565b60a0820152620016d860c0830162001605565b60c0820152620016eb60e08301620015d0565b60e08201526101006200170081840162001618565b908201526101206200171483820162001618565b908201526101406200172883820162001605565b908201526101606200173c83820162001618565b90820152610180620017508382016200162d565b9082015292915050565b80516001600160801b0381168114620015e857600080fd5b6000606082840312156200178557600080fd5b604051606081016001600160401b0381118282101715620017aa57620017aa620014c6565b604052905080620017bb836200162d565b8152620017cb602084016200175a565b6020820152620017de604084016200175a565b60408201525092915050565b60006001600160401b03821115620018065762001806620014c6565b5060051b60200190565b600082601f8301126200182257600080fd5b815160206200183b6200183583620017ea565b6200159d565b82815260a092830285018201928282019190878511156200185b57600080fd5b8387015b85811015620018e85781818a031215620018795760008081fd5b6200188362001508565b6200188e82620015d0565b81526200189d86830162001618565b868201526040620018b0818401620015ed565b908201526060620018c3838201620015ed565b908201526080620018d68382016200162d565b9082015284529284019281016200185f565b5090979650505050505050565b600082601f8301126200190757600080fd5b815160206200191a6200183583620017ea565b82815260e092830285018201928282019190878511156200193a57600080fd5b8387015b85811015620018e85781818a031215620019585760008081fd5b620019626200152d565b6200196d82620015d0565b81526200197c86830162001618565b8682015260406200198f81840162001618565b908201526060620019a283820162001605565b908201526080620019b583820162001618565b9082015260a0620019c883820162001618565b9082015260c0620019db8382016200162d565b9082015284529284019281016200193e565b600082601f830112620019ff57600080fd5b8151602062001a126200183583620017ea565b82815260069290921b8401810191818101908684111562001a3257600080fd5b8286015b8481101562001a88576040818903121562001a515760008081fd5b62001a5b62001552565b62001a6682620015d0565b815262001a7585830162001605565b8186015283529183019160400162001a36565b509695505050505050565b60008060008060008086880361036081121562001aaf57600080fd5b6101008082121562001ac057600080fd5b62001aca62001577565b915062001ad789620015d0565b825262001ae760208a01620015ed565b602083015262001afa60408a01620015ed565b604083015262001b0d60608a01620015ed565b606083015260808901516001600160601b038116811462001b2d57600080fd5b608083015262001b4060a08a01620015d0565b60a083015262001b5360c08a01620015d0565b60c083015262001b6660e08a01620015d0565b60e083015281975062001b7c8a828b016200163e565b9650505062001b90886102a0890162001772565b6103008801519094506001600160401b038082111562001baf57600080fd5b62001bbd8a838b0162001810565b945061032089015191508082111562001bd557600080fd5b62001be38a838b01620018f5565b935061034089015191508082111562001bfb57600080fd5b5062001c0a89828a01620019ed565b9150509295509295509295565b80516001600160a01b03168252602081015162001c3a602084018261ffff169052565b50604081015162001c53604084018263ffffffff169052565b50606081015162001c6a606084018261ffff169052565b50608081015162001c83608084018263ffffffff169052565b5060a081015162001c9a60a084018261ffff169052565b5060c081015162001cb160c084018261ffff169052565b5060e081015162001ccd60e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015190911690830152610180908101511515910152565b82516001600160a01b031681526020808401516001600160401b0390811691830191909152604080850151821690830152606080850151918216908301526102a082019050608084015162001d7c60808401826001600160601b03169052565b5060a084015162001d9860a08401826001600160a01b03169052565b5060c084015162001db460c08401826001600160a01b03169052565b5060e084015162001dd060e08401826001600160a01b03169052565b5062000ed261010083018462001c17565b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000919060409081850190868401855b8281101562001e7957815180516001600160a01b031685528681015163ffffffff1687860152858101516001600160401b03908116878701526060808301519091169086015260809081015115159085015260a0909301929085019060010162001e14565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b8281101562001e7957815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e0909301929085019060010162001ea3565b6020808252825182820181905260009190848201906040850190845b8181101562001f5e5783516001600160a01b03168352928401929184019160010162001f37565b50909695505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000e975762000e9762001f6a565b60008162001fa85762001fa862001f6a565b506000190190565b63ffffffff818116838216019080821115620012e257620012e262001f6a565b6000604080830163ffffffff8616845260206040602086015281865180845260608701915060208801935060005b818110156200203257845180516001600160a01b0316845284015161ffff1684840152938301939185019160010162001ffe565b509098975050505050505050565b808202811582820484141762000e975762000e9762001f6a565b6000826200207857634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b03828116828216039080821115620012e257620012e262001f6a565b600060208284031215620020b357600080fd5b5051919050565b8181036000831280158383131683831282161715620012e257620012e262001f6a565b600060208284031215620020f057600080fd5b62000ed2826200162d565b634e487b7160e01b600052603160045260246000fd5b60005b838110156200212e57818101518382015260200162002114565b50506000910152565b600082516200214b81846020870162002111565b9190910192915050565b60208152600082518060208401526200217681604085016020870162002111565b601f01601f19169190910160400192915050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f75620022b86000396000818161036101528181610efa0152613786015260008181610332015281816116f80152613757015260008181610303015281816113ae0152818161141301528181611c7401528181611d02015261372801526000818161026f01528181610a30015281816118200152818161222201528181612b42015261369401526000818161023f01528181611dd30152613664015260008181610210015281816110a50152818161162401528181611a4101528181611b42015281816126dd015281816136350152613a240152600081816102cf01528181611c0e01526136f401526000818161029f0152818161283801526136c4015260006124b60152615f756000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80637437ff9f116100f9578063c92b283211610097578063eff7cc4811610071578063eff7cc48146109de578063f25561fd146109e6578063f2fde38b146109f9578063fbca3b7414610a0c57600080fd5b8063c92b2832146109b0578063d09dc339146109c3578063df0aa9e9146109cb57600080fd5b8063856c8247116100d3578063856c8247146108825780638da5cb5b146108955780639a113c36146108a6578063b06d41bc1461099a57600080fd5b80637437ff9f146106c057806376f6ae761461086757806379ba50971461087a57600080fd5b806348a98aa411610166578063549e946f11610140578063549e946f1461066957806354b714681461067c578063599f64311461069c578063704b6c02146106ad57600080fd5b806348a98aa4146105c7578063504bffe0146105f2578063546719cd1461060557600080fd5b806320487ded1161019757806320487ded146105705780634120fccd146105915780634816f4f7146105b257600080fd5b806306285c69146101be5780631772047e146103a7578063181f5a7714610527575b600080fd5b6103916040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091526040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60405161039e9190614b86565b60405180910390f35b6104bb6103b5366004614bba565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152506001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c082015290565b60405161039e9190600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b6105636040518060400160405280601781526020017f45564d3245564d4f6e52616d7020312e352e302d64657600000000000000000081525081565b60405161039e9190614c27565b61058361057e366004614c68565b610a2c565b60405190815260200161039e565b610599610e82565b60405167ffffffffffffffff909116815260200161039e565b6105c56105c0366004614e76565b610ea9565b005b6105da6105d5366004614fb3565b610ebf565b6040516001600160a01b03909116815260200161039e565b6105c5610600366004614fec565b610f6e565b61060d610f82565b60405161039e919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6105c56106773660046150ea565b611014565b600e546040516bffffffffffffffffffffffff909116815260200161039e565b6002546001600160a01b03166105da565b6105c56106bb366004614bba565b61118d565b61085a604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915250604080516101a0810182526005546001600160a01b038082168352600160a01b820461ffff9081166020850152760100000000000000000000000000000000000000000000830463ffffffff908116958501959095527a0100000000000000000000000000000000000000000000000000008304811660608501527c0100000000000000000000000000000000000000000000000000000000928390048516608085015260065480821660a086015262010000808204831660c0870152640100000000820490931660e08601527801000000000000000000000000000000000000000000000000810486166101008601529290920484166101208401526007549182166101408401528104909216610160820152660100000000000090910460ff16151561018082015290565b60405161039e9190615206565b6105c5610875366004615215565b611257565b6105c56112ba565b610599610890366004614bba565b611383565b6000546001600160a01b03166105da565b6109506108b4366004614bba565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b03166000908152600b60209081526040918290208251608081018452905463ffffffff8116825267ffffffffffffffff64010000000082048116938301939093526c0100000000000000000000000081049092169281019290925260ff600160a01b909104161515606082015290565b60408051825163ffffffff16815260208084015167ffffffffffffffff9081169183019190915283830151169181019190915260609182015115159181019190915260800161039e565b6109a261147e565b60405161039e9291906152de565b6105c56109be366004615320565b611579565b6105836115e1565b6105836109d936600461538e565b6116a1565b6105c561252a565b6105c56109f43660046153fa565b6127af565b6105c5610a07366004614bba565b6127c0565b610a1f610a1a3660046154f9565b6127d1565b60405161039e9190615516565b60007f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168367ffffffffffffffff1614610aac576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6000610ac3610abe6080850185615563565b612805565b9050610af3610ad56020850185615563565b8351909150610ae760408701876155c8565b90508460200151612992565b6000600b81610b086080870160608801614bba565b6001600160a01b0316815260208082019290925260409081016000208151608081018352905463ffffffff81168252640100000000810467ffffffffffffffff908116948301949094526c01000000000000000000000000810490931691810191909152600160a01b90910460ff16151560608201819052909150610bd557610b976080850160608601614bba565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b600654600090819064010000000090046001600160a01b031663ffdb4b37610c036080890160608a01614bba565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff8a1660248201526044016040805180830381865afa158015610c6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c92919061565c565b90925090506000808080610ca960408b018b6155c8565b90501115610ce357610cd7610cc460808b0160608c01614bba565b86610cd260408d018d6155c8565b612af7565b91945092509050610cff565b8551610cfc9063ffffffff16662386f26fc100006156a5565b92505b60065460009062010000900461ffff1615610d5357610d506dffffffffffffffffffffffffffff607087901c16610d3960208d018d615563565b9050610d4860408e018e6155c8565b905085612ec6565b90505b60208781015160055460009267ffffffffffffffff9092169163ffffffff8716917a010000000000000000000000000000000000000000000000000000900461ffff1690610da3908f018f615563565b610dae9291506156a5565b6005548c51610ddd91760100000000000000000000000000000000000000000000900463ffffffff16906156bc565b610de791906156bc565b610df191906156bc565b610e0b906dffffffffffffffffffffffffffff89166156a5565b610e1591906156a5565b9050867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1682828a6040015167ffffffffffffffff1688610e5291906156a5565b610e5c91906156bc565b610e6691906156bc565b610e7091906156cf565b99505050505050505050505b92915050565b600e54600090610ea490600160801b900467ffffffffffffffff1660016156f1565b905090565b610eb1612f97565b610ebb8282612fef565b5050565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190615712565b9392505050565b610f76613371565b610f7f816133cb565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff8082168352600160801b80830463ffffffff166020850152600160a01b90920460ff161515938301939093526004548084166060840152049091166080820152610ea4906137c0565b61101c612f97565b6001600160a01b03811661105c576040517f232cb97f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006110666115e1565b905060008112156110a3576040517f02075e0000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316036110f5576110f06001600160a01b0384168383613872565b505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526110f09083906001600160a01b038616906370a0823190602401602060405180830381865afa158015611158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117c919061572f565b6001600160a01b0386169190613872565b6000546001600160a01b031633148015906111b357506002546001600160a01b03163314155b156111ea576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b61125f612f97565b610ebb8282808060200260200160405190810160405280939291908181526020016000905b828210156112b0576112a160408302860136819003810190615748565b81526020019060010190611284565b50505050506138f2565b6001546001600160a01b031633146113145760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610aa3565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b038082166000908152600d6020526040812054909167ffffffffffffffff909116907f00000000000000000000000000000000000000000000000000000000000000001615610e7c5780600003610e7c576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa15801561145a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190615787565b606060008061148d6008613b58565b90508067ffffffffffffffff8111156114a8576114a8614cb8565b6040519080825280602002602001820160405280156114ed57816020015b60408051808201909152600080825260208201528152602001906001900390816114c65790505b50925060005b8181101561155657600080611509600884613b63565b915091506040518060400160405280836001600160a01b031681526020018261ffff16815250868481518110611541576115416157a4565b602090810291909101015250506001016114f3565b5050600e5491926c0100000000000000000000000090920463ffffffff16919050565b6000546001600160a01b0316331480159061159f57506002546001600160a01b03163314155b156115d6576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f7f600382613b81565b600e546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916bffffffffffffffffffffffff16907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611673573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611697919061572f565b610ea491906157ba565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608086901b1660048201526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561173f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176391906157da565b1561179a576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0382166117da576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b0316331461181e576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168567ffffffffffffffff1614611897576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610aa3565b60006118a9610abe6080870187615563565b905060006118ba60408701876155c8565b91506118e090506118ce6020880188615563565b90508360000151838560200151612992565b8015611a37576000805b82811015611a25576118ff60408901896155c8565b8281811061190f5761190f6157a4565b90506040020160200135600003611952576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c600061196360408b018b6155c8565b84818110611973576119736157a4565b6119899260206040909202019081019150614bba565b6001600160a01b031681526020810191909152604001600020547201000000000000000000000000000000000000900460ff1615611a1d57611a106119d160408a018a6155c8565b838181106119e1576119e16157a4565b9050604002018036038101906119f791906157f7565b60065464010000000090046001600160a01b0316613d14565b611a1a90836156bc565b91505b6001016118ea565b508015611a3557611a3581613e35565b505b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016611a716080880160608901614bba565b6001600160a01b031603611ad557600e8054869190600090611aa29084906bffffffffffffffffffffffff16615831565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550611bfc565b60065464010000000090046001600160a01b03166241e5be611afd6080890160608a01614bba565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018990527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa158015611b89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bad919061572f565b600e8054600090611bcd9084906bffffffffffffffffffffffff16615831565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b600e546bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811691161115611c69576040517fe5c7a49100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160200151611dbd577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615611dbd576001600160a01b0384166000908152600d602052604081205467ffffffffffffffff169003611dbd576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611d49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6d9190615787565b6001600160a01b0385166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790555b604080516101a08101825267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526001600160a01b03861660208201526000918101611e50611e168a80615563565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613e4292505050565b6001600160a01b03168152602001600e601081819054906101000a900467ffffffffffffffff16611e8090615856565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff168152602001846000015181526020016000151581526020018460200151611f2a576001600160a01b0387166000908152600d602052604081208054909190611f009067ffffffffffffffff16615856565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055611f2d565b60005b67ffffffffffffffff168152602001611f4c60808a0160608b01614bba565b6001600160a01b03168152602001878152602001888060200190611f709190615563565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001611fb760408a018a6155c8565b808060200260200160405190810160405280939291908181526020016000905b8282101561200357611ff4604083028601368190038101906157f7565b81526020019060010190611fd7565b505050505081526020018367ffffffffffffffff81111561202657612026614cb8565b60405190808252806020026020018201604052801561205957816020015b60608152602001906001900390816120445790505b508152600060209091018190529091505b828110156124af57600061208160408a018a6155c8565b83818110612091576120916157a4565b9050604002018036038101906120a791906157f7565b905060006120b98b8360000151610ebf565b90506001600160a01b038116158061216f57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa158015612149573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216d91906157da565b155b156121b45781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b6000816001600160a01b0316639a4575b96040518060a001604052808e80600001906121e09190615563565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525067ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166020808301919091526001600160a01b03808f16604080850191909152918901516060840152885116608090920191909152517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526122ab919060040161587d565b6000604051808303816000875af11580156122ca573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526122f2919081019061594a565b9050602063ffffffff1681602001515111156123895782516001600160a01b03166000908152600c602090815260409091205490820151516e01000000000000000000000000000090910463ffffffff1610156123895782516040517f36f536ca0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b805161239490613e42565b5060408051608081019091526001600160a01b03831660a08201528060c0810160408051808303601f190181529181529082528351602080840191909152808501518383015286516001600160a01b03166000908152600c9091522054606090910190730100000000000000000000000000000000000000900460ff166124295760075462010000900463ffffffff16612458565b84516001600160a01b03166000908152600c60205260409020546a0100000000000000000000900463ffffffff165b63ffffffff16905260405161247091906020016159db565b6040516020818303038152906040528561016001518581518110612496576124966157a4565b602002602001018190525050505080600101905061206a565b506124da817f0000000000000000000000000000000000000000000000000000000000000000613ee8565b6101808201526040517fd0c3c799bf9e2639de44391e7f524d229b2b55f5b1ea94b2bf7da42f7243dddd90612510908390615aef565b60405180910390a16101800151925050505b949350505050565b6000546001600160a01b0316331461258f576002546001600160a01b0316331461258f57612559600833614043565b61258f576040517f195db95800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff1660008190036125e3576040517f990e30bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546bffffffffffffffffffffffff168181101561262e576040517f8d0f71d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006126386115e1565b1215612670576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600061267d6008613b58565b905060005b8181101561276c57600080612698600884613b63565b90925090506000876126b8836bffffffffffffffffffffffff8a166156a5565b6126c291906156cf565b90506126ce8187615c24565b95506127126001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846bffffffffffffffffffffffff8416613872565b6040516bffffffffffffffffffffffff821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a2505050806001019050612682565b5050600e80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff929092169190911790555050565b6127b7612f97565b610f7f81614058565b6127c8613371565b610f7f816141ca565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260008082526020820152600082900361286657506040805180820190915267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260006020820152610e7c565b60006128728385615c49565b90507fe7e230f0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016128df576128ca8360048187615c91565b8101906128d79190615cbb565b915050610e7c565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016129605760408051808201909152806129408560048189615c91565b81019061294d9190615ce7565b815260006020909101529150610e7c9050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006547801000000000000000000000000000000000000000000000000900463ffffffff16808511156129fb576040517f869337890000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610aa3565b6006547c0100000000000000000000000000000000000000000000000000000000900463ffffffff16841115612a5d576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554600160a01b900461ffff16831115612aa4576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81612af0576007546601000000000000900460ff1615612af0576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000808083815b81811015612eba576000878783818110612b1a57612b1a6157a4565b905060400201803603810190612b3091906157f7565b905060006001600160a01b0316612b6b7f00000000000000000000000000000000000000000000000000000000000000008360000151610ebf565b6001600160a01b031603612bb95780516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b80516001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c08201819052612cde57600754612ca29061ffff16662386f26fc100006156a5565b612cac90886156bc565b600754909750612cc89062010000900463ffffffff1687615d00565b9550612cd5602086615d00565b94505050612eb2565b604081015160009061ffff1615612e025760008c6001600160a01b031684600001516001600160a01b031614612da55760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526401000000009092041690634ab35b0b90602401602060405180830381865afa158015612d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d9e9190615d1d565b9050612da8565b508a5b620186a0836040015161ffff16612dea8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661428b90919063ffffffff16565b612df491906156a5565b612dfe91906156cf565b9150505b6060820151612e119088615d00565b9650816080015186612e239190615d00565b8251909650600090612e429063ffffffff16662386f26fc100006156a5565b905080821015612e6157612e56818a6156bc565b985050505050612eb2565b6000836020015163ffffffff16662386f26fc10000612e8091906156a5565b905080831115612ea057612e94818b6156bc565b99505050505050612eb2565b612eaa838b6156bc565b995050505050505b600101612afe565b50509450945094915050565b60008063ffffffff8316612edc610180866156a5565b612ee8876102206156bc565b612ef291906156bc565b612efc91906156bc565b6005546006549192506000917c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690612f3e9061ffff16846156a5565b612f4891906156bc565b60065490915062010000900461ffff16612f726dffffffffffffffffffffffffffff8916836156a5565b612f7c91906156a5565b612f8c90655af3107a40006156a5565b979650505050505050565b6000546001600160a01b03163314612fed576002546001600160a01b03163314612fed576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60005b825181101561328357600083828151811061300f5761300f6157a4565b60200260200101519050602063ffffffff168160a0015163ffffffff16101561308257805160a08201516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526001600160a01b03909216600483015263ffffffff166024820152604401610aa3565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009096169590951764010000000092871692909202919091177fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff166801000000000000000093909216929092027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff16176a010000000000000000000091841691909102177fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff166e01000000000000000000000000000093909216929092027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1617720100000000000000000000000000000000000094151594909402939093177fffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff16730100000000000000000000000000000000000000931515939093029290921790915501612ff2565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d0826040516132b39190615d38565b60405180910390a160005b815181101561332e57600c60008383815181106132dd576132dd6157a4565b6020908102919091018101516001600160a01b0316825281019190915260400160002080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556001016132be565b50805115610ebb577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b816040516133659190615516565b60405180910390a15050565b6000546001600160a01b03163314612fed5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610aa3565b60e08101516001600160a01b031661340f576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548160ff0219169083151502179055509050507f45b5ad483aa608464c2c7f278bd413d284d7790cdc836e40652e23a0277082206040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152508260405161124c929190615dd8565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261384e82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426138329190615df5565b85608001516fffffffffffffffffffffffffffffffff166142c8565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526110f09084906142f0565b8051604081111561392f576040517fb5a10cfa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff161561398357600e5463ffffffff6c010000000000000000000000008204166bffffffffffffffffffffffff909116106139835761398361252a565b600061398f6008613b58565b90505b80156139d15760006139b06139a8600184615df5565b600890613b63565b5090506139be6008826143d5565b5050806139ca90615e08565b9050613992565b506000805b82811015613ad95760008482815181106139f2576139f26157a4565b60200260200101516000015190506000858381518110613a1457613a146157a4565b60200260200101516020015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480613a6957506001600160a01b038216155b15613aab576040517f4de938d10000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610aa3565b613abb60088361ffff84166143ea565b50613aca61ffff821685615d00565b935050508060010190506139d6565b50600e80547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd2490613b4b9083908690615e3d565b60405180910390a1505050565b6000610e7c82614400565b6000808080613b72868661440b565b909450925050505b9250929050565b8154600090613b9d90600160801b900463ffffffff1642615df5565b90508015613c255760018301548354613bd8916fffffffffffffffffffffffffffffffff808216928116918591600160801b909104166142c8565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617600160801b4263ffffffff16021783555b60208201518354613c4b916fffffffffffffffffffffffffffffffff9081169116614436565b835483511515600160a01b027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff9283161717845560208301516040808501518316600160801b0291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990613b4b9084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d9e9190615e5c565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613e075783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b6020840151612522907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83169061428b565b610f7f600382600061444c565b60008151602014613e8157816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610aa39190614c27565b600082806020019051810190613e97919061572f565b90506001600160a01b03811180613eaf575061040081105b15610e7c57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610aa39190614c27565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001613f7e9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001613fb79190615e8f565b60405160208183030381529060405280519060200120876101600151604051602001613fe39190615ea2565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b6000610f67836001600160a01b038416614756565b60005b815181101561419a576000828281518110614078576140786157a4565b60209081029190910181015160408051608080820183528385015163ffffffff90811683528385015167ffffffffffffffff908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9688166c0100000000000000000000000002969096167fffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009095169116179290921791909116929092171790555060010161405b565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e8160405161124c9190615eb5565b336001600160a01b038216036142225760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610aa3565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a76400006142be837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166156a5565b610f6791906156cf565b60006142e7856142d884866156a5565b6142e290876156bc565b614436565b95945050505050565b6000614345826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166147629092919063ffffffff16565b8051909150156110f0578080602001905181019061436391906157da565b6110f05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa3565b6000610f67836001600160a01b038416614771565b6000612522846001600160a01b0385168461478e565b6000610e7c826147ab565b6000808061441985856147b5565b600081815260029690960160205260409095205494959350505050565b60008183106144455781610f67565b5090919050565b8254600160a01b900460ff161580614462575081155b1561446c57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906144a590600160801b900463ffffffff1642615df5565b9050801561454b57818311156144e7576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461451490839085908490600160801b90046fffffffffffffffffffffffffffffffff166142c8565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff16600160801b4263ffffffff160217875592505b848210156145e8576001600160a01b03841661459d576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610aa3565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610aa3565b848310156146d457600186810154600160801b90046fffffffffffffffffffffffffffffffff1690600090829061461f9082615df5565b614629878a615df5565b61463391906156bc565b61463d91906156cf565b90506001600160a01b038616614689576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610aa3565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610aa3565b6146de8584615df5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f6783836147c1565b606061252284846000856147d9565b60008181526002830160205260408120819055610f6783836148c0565b6000828152600284016020526040812082905561252284846148cc565b6000610e7c825490565b6000610f6783836148d8565b60008181526001830160205260408120541515610f67565b6060824710156148515760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa3565b600080866001600160a01b0316858760405161486d9190615f36565b60006040518083038185875af1925050503d80600081146148aa576040519150601f19603f3d011682016040523d82523d6000602084013e6148af565b606091505b5091509150612f8c87838387614902565b6000610f67838361497b565b6000610f678383614a75565b60008260000182815481106148ef576148ef6157a4565b9060005260206000200154905092915050565b6060831561497157825160000361496a576001600160a01b0385163b61496a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa3565b5081612522565b6125228383614ac4565b60008181526001830160205260408120548015614a6457600061499f600183615df5565b85549091506000906149b390600190615df5565b9050818114614a185760008660000182815481106149d3576149d36157a4565b90600052602060002001549050808760000184815481106149f6576149f66157a4565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614a2957614a29615f52565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610e7c565b6000915050610e7c565b5092915050565b6000818152600183016020526040812054614abc57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e7c565b506000610e7c565b815115614ad45781518083602001fd5b8060405162461bcd60e51b8152600401610aa39190614c27565b6001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401525060c0810151614b6b60c08401826001600160a01b03169052565b5060e08101516110f060e08401826001600160a01b03169052565b6101008101610e7c8284614aee565b6001600160a01b0381168114610f7f57600080fd5b8035614bb581614b95565b919050565b600060208284031215614bcc57600080fd5b8135610f6781614b95565b60005b83811015614bf2578181015183820152602001614bda565b50506000910152565b60008151808452614c13816020860160208601614bd7565b601f01601f19169290920160200192915050565b602081526000610f676020830184614bfb565b67ffffffffffffffff81168114610f7f57600080fd5b600060a08284031215614c6257600080fd5b50919050565b60008060408385031215614c7b57600080fd5b8235614c8681614c3a565b9150602083013567ffffffffffffffff811115614ca257600080fd5b614cae85828601614c50565b9150509250929050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b60405290565b6040516101a0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b60405160a0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b6040805190810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b604051601f8201601f1916810167ffffffffffffffff81118282101715614d8a57614d8a614cb8565b604052919050565b600067ffffffffffffffff821115614dac57614dac614cb8565b5060051b60200190565b63ffffffff81168114610f7f57600080fd5b8035614bb581614db6565b803561ffff81168114614bb557600080fd5b8015158114610f7f57600080fd5b8035614bb581614de5565b600082601f830112614e0f57600080fd5b81356020614e24614e1f83614d92565b614d61565b8083825260208201915060208460051b870101935086841115614e4657600080fd5b602086015b84811015614e6b578035614e5e81614b95565b8352918301918301614e4b565b509695505050505050565b6000806040808486031215614e8a57600080fd5b833567ffffffffffffffff80821115614ea257600080fd5b818601915086601f830112614eb657600080fd5b81356020614ec6614e1f83614d92565b82815260e0928302850182019282820191908b851115614ee557600080fd5b958301955b84871015614f8e5780878d031215614f025760008081fd5b614f0a614cce565b8735614f1581614b95565b815287850135614f2481614db6565b8186015287890135614f3581614db6565b818a01526060614f46898201614dd3565b90820152608088810135614f5981614db6565b9082015260a0614f6a898201614dc8565b9082015260c0614f7b898201614df3565b9082015283529586019591830191614eea565b5097505087013593505080831115614fa557600080fd5b5050614cae85828601614dfe565b60008060408385031215614fc657600080fd5b8235614fd181614c3a565b91506020830135614fe181614b95565b809150509250929050565b60006101a08284031215614fff57600080fd5b615007614cf7565b61501083614baa565b815261501e60208401614dd3565b602082015261502f60408401614dc8565b604082015261504060608401614dd3565b606082015261505160808401614dc8565b608082015261506260a08401614dd3565b60a082015261507360c08401614dd3565b60c082015261508460e08401614baa565b60e0820152610100615097818501614dc8565b908201526101206150a9848201614dc8565b908201526101406150bb848201614dd3565b908201526101606150cd848201614dc8565b908201526101806150df848201614df3565b908201529392505050565b600080604083850312156150fd57600080fd5b8235614fd181614b95565b80516001600160a01b03168252602081015161512a602084018261ffff169052565b506040810151615142604084018263ffffffff169052565b506060810151615158606084018261ffff169052565b506080810151615170608084018263ffffffff169052565b5060a081015161518660a084018261ffff169052565b5060c081015161519c60c084018261ffff169052565b5060e08101516151b760e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015190911690830152610180908101511515910152565b6101a08101610e7c8284615108565b6000806020838503121561522857600080fd5b823567ffffffffffffffff8082111561524057600080fd5b818501915085601f83011261525457600080fd5b81358181111561526357600080fd5b8660208260061b850101111561527857600080fd5b60209290920196919550909350505050565b60008151808452602080850194506020840160005b838110156152d357815180516001600160a01b0316885283015161ffff16838801526040909601959082019060010161529f565b509495945050505050565b6040815260006152f1604083018561528a565b90508260208301529392505050565b80356fffffffffffffffffffffffffffffffff81168114614bb557600080fd5b60006060828403121561533257600080fd5b6040516060810181811067ffffffffffffffff8211171561535557615355614cb8565b604052823561536381614de5565b815261537160208401615300565b602082015261538260408401615300565b60408201529392505050565b600080600080608085870312156153a457600080fd5b84356153af81614c3a565b9350602085013567ffffffffffffffff8111156153cb57600080fd5b6153d787828801614c50565b9350506040850135915060608501356153ef81614b95565b939692955090935050565b6000602080838503121561540d57600080fd5b823567ffffffffffffffff81111561542457600080fd5b8301601f8101851361543557600080fd5b8035615443614e1f82614d92565b81815260a0918202830184019184820191908884111561546257600080fd5b938501935b838510156154ed5780858a03121561547f5760008081fd5b615487614d1b565b853561549281614b95565b8152858701356154a181614db6565b818801526040868101356154b481614c3a565b908201526060868101356154c781614c3a565b908201526080868101356154da81614de5565b9082015283529384019391850191615467565b50979650505050505050565b60006020828403121561550b57600080fd5b8135610f6781614c3a565b6020808252825182820181905260009190848201906040850190845b818110156155575783516001600160a01b031683529284019291840191600101615532565b50909695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261559857600080fd5b83018035915067ffffffffffffffff8211156155b357600080fd5b602001915036819003821315613b7a57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155fd57600080fd5b83018035915067ffffffffffffffff82111561561857600080fd5b6020019150600681901b3603821315613b7a57600080fd5b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114614bb557600080fd5b6000806040838503121561566f57600080fd5b61567883615630565b915061568660208401615630565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e7c57610e7c61568f565b80820180821115610e7c57610e7c61568f565b6000826156ec57634e487b7160e01b600052601260045260246000fd5b500490565b67ffffffffffffffff818116838216019080821115614a6e57614a6e61568f565b60006020828403121561572457600080fd5b8151610f6781614b95565b60006020828403121561574157600080fd5b5051919050565b60006040828403121561575a57600080fd5b615762614d3e565b823561576d81614b95565b815261577b60208401614dd3565b60208201529392505050565b60006020828403121561579957600080fd5b8151610f6781614c3a565b634e487b7160e01b600052603260045260246000fd5b8181036000831280158383131683831282161715614a6e57614a6e61568f565b6000602082840312156157ec57600080fd5b8151610f6781614de5565b60006040828403121561580957600080fd5b615811614d3e565b823561581c81614b95565b81526020928301359281019290925250919050565b6bffffffffffffffffffffffff818116838216019080821115614a6e57614a6e61568f565b600067ffffffffffffffff8083168181036158735761587361568f565b6001019392505050565b602081526000825160a0602084015261589960c0840182614bfb565b905067ffffffffffffffff602085015116604084015260408401516001600160a01b038082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600082601f8301126158f757600080fd5b815167ffffffffffffffff81111561591157615911614cb8565b6159246020601f19601f84011601614d61565b81815284602083860101111561593957600080fd5b612522826020830160208701614bd7565b60006020828403121561595c57600080fd5b815167ffffffffffffffff8082111561597457600080fd5b908301906040828603121561598857600080fd5b615990614d3e565b82518281111561599f57600080fd5b6159ab878286016158e6565b8252506020830151828111156159c057600080fd5b6159cc878286016158e6565b60208301525095945050505050565b6020815260008251608060208401526159f760a0840182614bfb565b90506020840151601f1980858403016040860152615a158383614bfb565b9250604086015191508085840301606086015250615a338282614bfb565b91505063ffffffff60608501511660808401528091505092915050565b60008151808452602080850194506020840160005b838110156152d357815180516001600160a01b031688528301518388015260409096019590820190600101615a65565b60008282518085526020808601955060208260051b8401016020860160005b84811015615ae257601f19868403018952615ad0838351614bfb565b98840198925090830190600101615ab4565b5090979650505050505050565b60208152615b0a60208201835167ffffffffffffffff169052565b60006020830151615b2660408401826001600160a01b03169052565b5060408301516001600160a01b038116606084015250606083015167ffffffffffffffff8116608084015250608083015160a083015260a0830151615b6f60c084018215159052565b5060c083015167ffffffffffffffff811660e08401525060e0830151610100615ba2818501836001600160a01b03169052565b840151610120848101919091528401516101a061014080860182905291925090615bd06101c0860184614bfb565b9250808601519050601f19610160818786030181880152615bf18584615a50565b945080880151925050610180818786030181880152615c108584615a95565b970151959092019490945250929392505050565b6bffffffffffffffffffffffff828116828216039080821115614a6e57614a6e61568f565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015615c895780818660040360031b1b83161692505b505092915050565b60008085851115615ca157600080fd5b83861115615cae57600080fd5b5050820193919092039150565b600060408284031215615ccd57600080fd5b615cd5614d3e565b82358152602083013561577b81614de5565b600060208284031215615cf957600080fd5b5035919050565b63ffffffff818116838216019080821115614a6e57614a6e61568f565b600060208284031215615d2f57600080fd5b610f6782615630565b602080825282518282018190526000919060409081850190868401855b82811015615dcb57815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e09093019290850190600101615d55565b5091979650505050505050565b6102a08101615de78285614aee565b610f67610100830184615108565b81810381811115610e7c57610e7c61568f565b600081615e1757615e1761568f565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b63ffffffff83168152604060208201526000612522604083018461528a565b600060408284031215615e6e57600080fd5b615e76614d3e565b615e7f83615630565b8152602083015161577b81614db6565b602081526000610f676020830184615a50565b602081526000610f676020830184615a95565b602080825282518282018190526000919060409081850190868401855b82811015615dcb57815180516001600160a01b031685528681015163ffffffff16878601528581015167ffffffffffffffff908116878701526060808301519091169086015260809081015115159085015260a09093019290850190600101615ed2565b60008251615f48818460208701614bd7565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfea164736f6c6343000818000a", + Bin: "0x6101a06040523480156200001257600080fd5b506040516200822d3803806200822d833981016040819052620000359162001a93565b8333806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c0816200030b565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555085516001600160a01b0316158062000169575060208601516001600160401b0316155b8062000180575060408601516001600160401b0316155b8062000197575060608601516001600160401b0316155b80620001ae575060c08601516001600160a01b0316155b80620001c5575060e08601516001600160a01b0316155b15620001e4576040516306b7c75960e31b815260040160405180910390fd5b60208087015160408089015181517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3948101949094526001600160401b039283169184019190915216606082015230608082015260a00160408051601f198184030181529181528151602092830120608090815288516001600160a01b0390811660e0908152938a01516001600160401b0390811661010052928a015183166101205260608a015190921660a0908152908901516001600160601b031660c090815290890151821661014052880151811661016052908701511661018052620002cd85620003b6565b620002d883620006ad565b604080516000815260208101909152620002f4908390620007dd565b620002ff8162000a83565b5050505050506200218a565b336001600160a01b03821603620003655760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e08101516001600160a01b0316620003e2576040516306b7c75960e31b815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548160ff0219169083151502179055509050507f45b5ad483aa608464c2c7f278bd413d284d7790cdc836e40652e23a02770822060405180610100016040528060e0516001600160a01b03168152602001610100516001600160401b03168152602001610120516001600160401b0316815260200160a0516001600160401b0316815260200160c0516001600160601b03168152602001610140516001600160a01b03168152602001610160516001600160a01b03168152602001610180516001600160a01b031681525082604051620006a292919062001d1c565b60405180910390a150565b60005b8151811015620007ab576000828281518110620006d157620006d162001de1565b60209081029190910181015160408051608080820183528385015163ffffffff9081168352838501516001600160401b03908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b0260ff60a01b199688166c010000000000000000000000000296909616600160601b600160a81b031993909716640100000000026001600160601b031990951691161792909217919091169290921717905550600101620006b0565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e81604051620006a2919062001df7565b60005b8251811015620009a257600083828151811062000801576200080162001de1565b60200260200101519050602063ffffffff168160a0015163ffffffff1610156200085d57805160a08201516040516312766e0160e11b81526001600160a01b03909216600483015263ffffffff16602482015260440162000084565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087166001600160401b031990961695909517640100000000928716929092029190911765ffffffffffff60401b191668010000000000000000939092169290920263ffffffff60501b1916176a0100000000000000000000918416919091021764ffffffffff60701b1916600160701b939092169290920260ff60901b191617600160901b941515949094029390931760ff60981b1916600160981b931515939093029290921790915501620007e0565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d082604051620009d4919062001e86565b60405180910390a160005b815181101562000a3c57600c600083838151811062000a025762000a0262001de1565b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055600101620009df565b5080511562000a7f577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b8160405162000a76919062001f1b565b60405180910390a15b5050565b8051604081111562000aa857604051635ad0867d60e11b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff161562000afb57600e5463ffffffff6c010000000000000000000000008204166001600160601b039091161062000afb5762000afb62000c9e565b600062000b09600862000e8a565b90505b801562000b5557600062000b2f62000b2660018462001f80565b60089062000e9d565b50905062000b3f60088262000ebb565b50508062000b4d9062001f96565b905062000b0c565b506000805b8281101562000c3557600084828151811062000b7a5762000b7a62001de1565b6020026020010151600001519050600085838151811062000b9f5762000b9f62001de1565b602002602001015160200151905060e0516001600160a01b0316826001600160a01b0316148062000bd757506001600160a01b038216155b1562000c0257604051634de938d160e01b81526001600160a01b038316600482015260240162000084565b62000c1460088361ffff841662000ed9565b5062000c2561ffff82168562001fb0565b9350505080600101905062000b5a565b50600e805463ffffffff60601b19166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249062000c91908390869062001fd0565b60405180910390a1505050565b6000546001600160a01b0316331462000cef576002546001600160a01b0316331462000cef5762000cd160083362000ef9565b62000cef5760405163032bb72b60e31b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff16600081900362000d2b5760405163990e30bf60e01b815260040160405180910390fd5b600e546001600160601b03168181101562000d59576040516311a1ee3b60e31b815260040160405180910390fd5b600062000d6562000f10565b121562000d8557604051631e9acf1760e31b815260040160405180910390fd5b80600062000d94600862000e8a565b905060005b8181101562000e645760008062000db260088462000e9d565b909250905060008762000dcf836001600160601b038a1662002040565b62000ddb91906200205a565b905062000de981876200207d565b60e05190965062000e0e906001600160a01b0316846001600160601b03841662000f9e565b6040516001600160601b03821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a250505080600101905062000d99565b5050600e80546001600160601b0319166001600160601b03929092169190911790555050565b600062000e978262000ffb565b92915050565b600080808062000eae868662001008565b9097909650945050505050565b600062000ed2836001600160a01b03841662001035565b9392505050565b600062000ef1846001600160a01b0385168462001054565b949350505050565b600062000ed2836001600160a01b03841662001073565b600e5460e0516040516370a0823160e01b81523060048201526000926001600160601b0316916001600160a01b0316906370a0823190602401602060405180830381865afa15801562000f67573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f8d9190620020a0565b62000f999190620020ba565b905090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915262000ff69185916200108116565b505050565b600062000e978262001152565b600080806200101885856200115d565b600081815260029690960160205260409095205494959350505050565b6000818152600283016020526040812081905562000ed283836200116b565b6000828152600284016020526040812082905562000ef1848462001179565b600062000ed2838362001187565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620010d0906001600160a01b038516908490620011a0565b80519091501562000ff65780806020019051810190620010f19190620020dd565b62000ff65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000084565b600062000e97825490565b600062000ed28383620011b1565b600062000ed28383620011de565b600062000ed28383620012e9565b6000818152600183016020526040812054151562000ed2565b606062000ef184846000856200133b565b6000826000018281548110620011cb57620011cb62001de1565b9060005260206000200154905092915050565b60008181526001830160205260408120548015620012d75760006200120560018362001f80565b85549091506000906200121b9060019062001f80565b9050818114620012875760008660000182815481106200123f576200123f62001de1565b906000526020600020015490508087600001848154811062001265576200126562001de1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200129b576200129b620020fb565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e97565b600091505062000e97565b5092915050565b6000818152600183016020526040812054620013325750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e97565b50600062000e97565b6060824710156200139e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000084565b600080866001600160a01b03168587604051620013bc919062002137565b60006040518083038185875af1925050503d8060008114620013fb576040519150601f19603f3d011682016040523d82523d6000602084013e62001400565b606091505b50909250905062001414878383876200141f565b979650505050505050565b60608315620014935782516000036200148b576001600160a01b0385163b6200148b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000084565b508162000ef1565b62000ef18383815115620014aa5781518083602001fd5b8060405162461bcd60e51b815260040162000084919062002155565b634e487b7160e01b600052604160045260246000fd5b6040516101a081016001600160401b0381118282101715620015025762001502620014c6565b60405290565b60405160a081016001600160401b0381118282101715620015025762001502620014c6565b60405160e081016001600160401b0381118282101715620015025762001502620014c6565b604080519081016001600160401b0381118282101715620015025762001502620014c6565b60405161010081016001600160401b0381118282101715620015025762001502620014c6565b604051601f8201601f191681016001600160401b0381118282101715620015c857620015c8620014c6565b604052919050565b80516001600160a01b0381168114620015e857600080fd5b919050565b80516001600160401b0381168114620015e857600080fd5b805161ffff81168114620015e857600080fd5b805163ffffffff81168114620015e857600080fd5b80518015158114620015e857600080fd5b60006101a082840312156200165257600080fd5b6200165c620014dc565b90506200166982620015d0565b8152620016796020830162001605565b60208201526200168c6040830162001618565b60408201526200169f6060830162001605565b6060820152620016b26080830162001618565b6080820152620016c560a0830162001605565b60a0820152620016d860c0830162001605565b60c0820152620016eb60e08301620015d0565b60e08201526101006200170081840162001618565b908201526101206200171483820162001618565b908201526101406200172883820162001605565b908201526101606200173c83820162001618565b90820152610180620017508382016200162d565b9082015292915050565b80516001600160801b0381168114620015e857600080fd5b6000606082840312156200178557600080fd5b604051606081016001600160401b0381118282101715620017aa57620017aa620014c6565b604052905080620017bb836200162d565b8152620017cb602084016200175a565b6020820152620017de604084016200175a565b60408201525092915050565b60006001600160401b03821115620018065762001806620014c6565b5060051b60200190565b600082601f8301126200182257600080fd5b815160206200183b6200183583620017ea565b6200159d565b82815260a092830285018201928282019190878511156200185b57600080fd5b8387015b85811015620018e85781818a031215620018795760008081fd5b6200188362001508565b6200188e82620015d0565b81526200189d86830162001618565b868201526040620018b0818401620015ed565b908201526060620018c3838201620015ed565b908201526080620018d68382016200162d565b9082015284529284019281016200185f565b5090979650505050505050565b600082601f8301126200190757600080fd5b815160206200191a6200183583620017ea565b82815260e092830285018201928282019190878511156200193a57600080fd5b8387015b85811015620018e85781818a031215620019585760008081fd5b620019626200152d565b6200196d82620015d0565b81526200197c86830162001618565b8682015260406200198f81840162001618565b908201526060620019a283820162001605565b908201526080620019b583820162001618565b9082015260a0620019c883820162001618565b9082015260c0620019db8382016200162d565b9082015284529284019281016200193e565b600082601f830112620019ff57600080fd5b8151602062001a126200183583620017ea565b82815260069290921b8401810191818101908684111562001a3257600080fd5b8286015b8481101562001a88576040818903121562001a515760008081fd5b62001a5b62001552565b62001a6682620015d0565b815262001a7585830162001605565b8186015283529183019160400162001a36565b509695505050505050565b60008060008060008086880361036081121562001aaf57600080fd5b6101008082121562001ac057600080fd5b62001aca62001577565b915062001ad789620015d0565b825262001ae760208a01620015ed565b602083015262001afa60408a01620015ed565b604083015262001b0d60608a01620015ed565b606083015260808901516001600160601b038116811462001b2d57600080fd5b608083015262001b4060a08a01620015d0565b60a083015262001b5360c08a01620015d0565b60c083015262001b6660e08a01620015d0565b60e083015281975062001b7c8a828b016200163e565b9650505062001b90886102a0890162001772565b6103008801519094506001600160401b038082111562001baf57600080fd5b62001bbd8a838b0162001810565b945061032089015191508082111562001bd557600080fd5b62001be38a838b01620018f5565b935061034089015191508082111562001bfb57600080fd5b5062001c0a89828a01620019ed565b9150509295509295509295565b80516001600160a01b03168252602081015162001c3a602084018261ffff169052565b50604081015162001c53604084018263ffffffff169052565b50606081015162001c6a606084018261ffff169052565b50608081015162001c83608084018263ffffffff169052565b5060a081015162001c9a60a084018261ffff169052565b5060c081015162001cb160c084018261ffff169052565b5060e081015162001ccd60e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015190911690830152610180908101511515910152565b82516001600160a01b031681526020808401516001600160401b0390811691830191909152604080850151821690830152606080850151918216908301526102a082019050608084015162001d7c60808401826001600160601b03169052565b5060a084015162001d9860a08401826001600160a01b03169052565b5060c084015162001db460c08401826001600160a01b03169052565b5060e084015162001dd060e08401826001600160a01b03169052565b5062000ed261010083018462001c17565b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000919060409081850190868401855b8281101562001e7957815180516001600160a01b031685528681015163ffffffff1687860152858101516001600160401b03908116878701526060808301519091169086015260809081015115159085015260a0909301929085019060010162001e14565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b8281101562001e7957815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e0909301929085019060010162001ea3565b6020808252825182820181905260009190848201906040850190845b8181101562001f5e5783516001600160a01b03168352928401929184019160010162001f37565b50909695505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000e975762000e9762001f6a565b60008162001fa85762001fa862001f6a565b506000190190565b63ffffffff818116838216019080821115620012e257620012e262001f6a565b6000604080830163ffffffff8616845260206040602086015281865180845260608701915060208801935060005b818110156200203257845180516001600160a01b0316845284015161ffff1684840152938301939185019160010162001ffe565b509098975050505050505050565b808202811582820484141762000e975762000e9762001f6a565b6000826200207857634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b03828116828216039080821115620012e257620012e262001f6a565b600060208284031215620020b357600080fd5b5051919050565b8181036000831280158383131683831282161715620012e257620012e262001f6a565b600060208284031215620020f057600080fd5b62000ed2826200162d565b634e487b7160e01b600052603160045260246000fd5b60005b838110156200212e57818101518382015260200162002114565b50506000910152565b600082516200214b81846020870162002111565b9190910192915050565b60208152600082518060208401526200217681604085016020870162002111565b601f01601f19169190910160400192915050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f75620022b86000396000818161036101528181610efa0152613786015260008181610332015281816116f80152613757015260008181610303015281816113ae0152818161141301528181611c7401528181611d02015261372801526000818161026f01528181610a30015281816118200152818161222201528181612b42015261369401526000818161023f01528181611dd30152613664015260008181610210015281816110a50152818161162401528181611a4101528181611b42015281816126dd015281816136350152613a240152600081816102cf01528181611c0e01526136f401526000818161029f0152818161283801526136c4015260006124b60152615f756000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80637437ff9f116100f9578063c92b283211610097578063eff7cc4811610071578063eff7cc48146109de578063f25561fd146109e6578063f2fde38b146109f9578063fbca3b7414610a0c57600080fd5b8063c92b2832146109b0578063d09dc339146109c3578063df0aa9e9146109cb57600080fd5b8063856c8247116100d3578063856c8247146108825780638da5cb5b146108955780639a113c36146108a6578063b06d41bc1461099a57600080fd5b80637437ff9f146106c057806376f6ae761461086757806379ba50971461087a57600080fd5b806348a98aa411610166578063549e946f11610140578063549e946f1461066957806354b714681461067c578063599f64311461069c578063704b6c02146106ad57600080fd5b806348a98aa4146105c7578063504bffe0146105f2578063546719cd1461060557600080fd5b806320487ded1161019757806320487ded146105705780634120fccd146105915780634816f4f7146105b257600080fd5b806306285c69146101be5780631772047e146103a7578063181f5a7714610527575b600080fd5b6103916040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091526040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60405161039e9190614b86565b60405180910390f35b6104bb6103b5366004614bba565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152506001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c082015290565b60405161039e9190600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b6105636040518060400160405280601381526020017f45564d3245564d4f6e52616d7020312e352e300000000000000000000000000081525081565b60405161039e9190614c27565b61058361057e366004614c68565b610a2c565b60405190815260200161039e565b610599610e82565b60405167ffffffffffffffff909116815260200161039e565b6105c56105c0366004614e76565b610ea9565b005b6105da6105d5366004614fb3565b610ebf565b6040516001600160a01b03909116815260200161039e565b6105c5610600366004614fec565b610f6e565b61060d610f82565b60405161039e919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6105c56106773660046150ea565b611014565b600e546040516bffffffffffffffffffffffff909116815260200161039e565b6002546001600160a01b03166105da565b6105c56106bb366004614bba565b61118d565b61085a604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915250604080516101a0810182526005546001600160a01b038082168352600160a01b820461ffff9081166020850152760100000000000000000000000000000000000000000000830463ffffffff908116958501959095527a0100000000000000000000000000000000000000000000000000008304811660608501527c0100000000000000000000000000000000000000000000000000000000928390048516608085015260065480821660a086015262010000808204831660c0870152640100000000820490931660e08601527801000000000000000000000000000000000000000000000000810486166101008601529290920484166101208401526007549182166101408401528104909216610160820152660100000000000090910460ff16151561018082015290565b60405161039e9190615206565b6105c5610875366004615215565b611257565b6105c56112ba565b610599610890366004614bba565b611383565b6000546001600160a01b03166105da565b6109506108b4366004614bba565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b03166000908152600b60209081526040918290208251608081018452905463ffffffff8116825267ffffffffffffffff64010000000082048116938301939093526c0100000000000000000000000081049092169281019290925260ff600160a01b909104161515606082015290565b60408051825163ffffffff16815260208084015167ffffffffffffffff9081169183019190915283830151169181019190915260609182015115159181019190915260800161039e565b6109a261147e565b60405161039e9291906152de565b6105c56109be366004615320565b611579565b6105836115e1565b6105836109d936600461538e565b6116a1565b6105c561252a565b6105c56109f43660046153fa565b6127af565b6105c5610a07366004614bba565b6127c0565b610a1f610a1a3660046154f9565b6127d1565b60405161039e9190615516565b60007f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168367ffffffffffffffff1614610aac576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6000610ac3610abe6080850185615563565b612805565b9050610af3610ad56020850185615563565b8351909150610ae760408701876155c8565b90508460200151612992565b6000600b81610b086080870160608801614bba565b6001600160a01b0316815260208082019290925260409081016000208151608081018352905463ffffffff81168252640100000000810467ffffffffffffffff908116948301949094526c01000000000000000000000000810490931691810191909152600160a01b90910460ff16151560608201819052909150610bd557610b976080850160608601614bba565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b600654600090819064010000000090046001600160a01b031663ffdb4b37610c036080890160608a01614bba565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff8a1660248201526044016040805180830381865afa158015610c6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c92919061565c565b90925090506000808080610ca960408b018b6155c8565b90501115610ce357610cd7610cc460808b0160608c01614bba565b86610cd260408d018d6155c8565b612af7565b91945092509050610cff565b8551610cfc9063ffffffff16662386f26fc100006156a5565b92505b60065460009062010000900461ffff1615610d5357610d506dffffffffffffffffffffffffffff607087901c16610d3960208d018d615563565b9050610d4860408e018e6155c8565b905085612ec6565b90505b60208781015160055460009267ffffffffffffffff9092169163ffffffff8716917a010000000000000000000000000000000000000000000000000000900461ffff1690610da3908f018f615563565b610dae9291506156a5565b6005548c51610ddd91760100000000000000000000000000000000000000000000900463ffffffff16906156bc565b610de791906156bc565b610df191906156bc565b610e0b906dffffffffffffffffffffffffffff89166156a5565b610e1591906156a5565b9050867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1682828a6040015167ffffffffffffffff1688610e5291906156a5565b610e5c91906156bc565b610e6691906156bc565b610e7091906156cf565b99505050505050505050505b92915050565b600e54600090610ea490600160801b900467ffffffffffffffff1660016156f1565b905090565b610eb1612f97565b610ebb8282612fef565b5050565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190615712565b9392505050565b610f76613371565b610f7f816133cb565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff8082168352600160801b80830463ffffffff166020850152600160a01b90920460ff161515938301939093526004548084166060840152049091166080820152610ea4906137c0565b61101c612f97565b6001600160a01b03811661105c576040517f232cb97f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006110666115e1565b905060008112156110a3576040517f02075e0000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316036110f5576110f06001600160a01b0384168383613872565b505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526110f09083906001600160a01b038616906370a0823190602401602060405180830381865afa158015611158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117c919061572f565b6001600160a01b0386169190613872565b6000546001600160a01b031633148015906111b357506002546001600160a01b03163314155b156111ea576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b61125f612f97565b610ebb8282808060200260200160405190810160405280939291908181526020016000905b828210156112b0576112a160408302860136819003810190615748565b81526020019060010190611284565b50505050506138f2565b6001546001600160a01b031633146113145760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610aa3565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b038082166000908152600d6020526040812054909167ffffffffffffffff909116907f00000000000000000000000000000000000000000000000000000000000000001615610e7c5780600003610e7c576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa15801561145a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190615787565b606060008061148d6008613b58565b90508067ffffffffffffffff8111156114a8576114a8614cb8565b6040519080825280602002602001820160405280156114ed57816020015b60408051808201909152600080825260208201528152602001906001900390816114c65790505b50925060005b8181101561155657600080611509600884613b63565b915091506040518060400160405280836001600160a01b031681526020018261ffff16815250868481518110611541576115416157a4565b602090810291909101015250506001016114f3565b5050600e5491926c0100000000000000000000000090920463ffffffff16919050565b6000546001600160a01b0316331480159061159f57506002546001600160a01b03163314155b156115d6576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f7f600382613b81565b600e546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916bffffffffffffffffffffffff16907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611673573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611697919061572f565b610ea491906157ba565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608086901b1660048201526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561173f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176391906157da565b1561179a576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0382166117da576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b0316331461181e576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168567ffffffffffffffff1614611897576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610aa3565b60006118a9610abe6080870187615563565b905060006118ba60408701876155c8565b91506118e090506118ce6020880188615563565b90508360000151838560200151612992565b8015611a37576000805b82811015611a25576118ff60408901896155c8565b8281811061190f5761190f6157a4565b90506040020160200135600003611952576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c600061196360408b018b6155c8565b84818110611973576119736157a4565b6119899260206040909202019081019150614bba565b6001600160a01b031681526020810191909152604001600020547201000000000000000000000000000000000000900460ff1615611a1d57611a106119d160408a018a6155c8565b838181106119e1576119e16157a4565b9050604002018036038101906119f791906157f7565b60065464010000000090046001600160a01b0316613d14565b611a1a90836156bc565b91505b6001016118ea565b508015611a3557611a3581613e35565b505b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016611a716080880160608901614bba565b6001600160a01b031603611ad557600e8054869190600090611aa29084906bffffffffffffffffffffffff16615831565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550611bfc565b60065464010000000090046001600160a01b03166241e5be611afd6080890160608a01614bba565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018990527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa158015611b89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bad919061572f565b600e8054600090611bcd9084906bffffffffffffffffffffffff16615831565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b600e546bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811691161115611c69576040517fe5c7a49100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160200151611dbd577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615611dbd576001600160a01b0384166000908152600d602052604081205467ffffffffffffffff169003611dbd576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611d49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6d9190615787565b6001600160a01b0385166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790555b604080516101a08101825267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526001600160a01b03861660208201526000918101611e50611e168a80615563565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613e4292505050565b6001600160a01b03168152602001600e601081819054906101000a900467ffffffffffffffff16611e8090615856565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff168152602001846000015181526020016000151581526020018460200151611f2a576001600160a01b0387166000908152600d602052604081208054909190611f009067ffffffffffffffff16615856565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055611f2d565b60005b67ffffffffffffffff168152602001611f4c60808a0160608b01614bba565b6001600160a01b03168152602001878152602001888060200190611f709190615563565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001611fb760408a018a6155c8565b808060200260200160405190810160405280939291908181526020016000905b8282101561200357611ff4604083028601368190038101906157f7565b81526020019060010190611fd7565b505050505081526020018367ffffffffffffffff81111561202657612026614cb8565b60405190808252806020026020018201604052801561205957816020015b60608152602001906001900390816120445790505b508152600060209091018190529091505b828110156124af57600061208160408a018a6155c8565b83818110612091576120916157a4565b9050604002018036038101906120a791906157f7565b905060006120b98b8360000151610ebf565b90506001600160a01b038116158061216f57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa158015612149573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216d91906157da565b155b156121b45781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b6000816001600160a01b0316639a4575b96040518060a001604052808e80600001906121e09190615563565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525067ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166020808301919091526001600160a01b03808f16604080850191909152918901516060840152885116608090920191909152517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526122ab919060040161587d565b6000604051808303816000875af11580156122ca573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526122f2919081019061594a565b9050602063ffffffff1681602001515111156123895782516001600160a01b03166000908152600c602090815260409091205490820151516e01000000000000000000000000000090910463ffffffff1610156123895782516040517f36f536ca0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b805161239490613e42565b5060408051608081019091526001600160a01b03831660a08201528060c0810160408051808303601f190181529181529082528351602080840191909152808501518383015286516001600160a01b03166000908152600c9091522054606090910190730100000000000000000000000000000000000000900460ff166124295760075462010000900463ffffffff16612458565b84516001600160a01b03166000908152600c60205260409020546a0100000000000000000000900463ffffffff165b63ffffffff16905260405161247091906020016159db565b6040516020818303038152906040528561016001518581518110612496576124966157a4565b602002602001018190525050505080600101905061206a565b506124da817f0000000000000000000000000000000000000000000000000000000000000000613ee8565b6101808201526040517fd0c3c799bf9e2639de44391e7f524d229b2b55f5b1ea94b2bf7da42f7243dddd90612510908390615aef565b60405180910390a16101800151925050505b949350505050565b6000546001600160a01b0316331461258f576002546001600160a01b0316331461258f57612559600833614043565b61258f576040517f195db95800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff1660008190036125e3576040517f990e30bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546bffffffffffffffffffffffff168181101561262e576040517f8d0f71d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006126386115e1565b1215612670576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600061267d6008613b58565b905060005b8181101561276c57600080612698600884613b63565b90925090506000876126b8836bffffffffffffffffffffffff8a166156a5565b6126c291906156cf565b90506126ce8187615c24565b95506127126001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846bffffffffffffffffffffffff8416613872565b6040516bffffffffffffffffffffffff821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a2505050806001019050612682565b5050600e80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff929092169190911790555050565b6127b7612f97565b610f7f81614058565b6127c8613371565b610f7f816141ca565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260008082526020820152600082900361286657506040805180820190915267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260006020820152610e7c565b60006128728385615c49565b90507fe7e230f0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016128df576128ca8360048187615c91565b8101906128d79190615cbb565b915050610e7c565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016129605760408051808201909152806129408560048189615c91565b81019061294d9190615ce7565b815260006020909101529150610e7c9050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006547801000000000000000000000000000000000000000000000000900463ffffffff16808511156129fb576040517f869337890000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610aa3565b6006547c0100000000000000000000000000000000000000000000000000000000900463ffffffff16841115612a5d576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554600160a01b900461ffff16831115612aa4576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81612af0576007546601000000000000900460ff1615612af0576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000808083815b81811015612eba576000878783818110612b1a57612b1a6157a4565b905060400201803603810190612b3091906157f7565b905060006001600160a01b0316612b6b7f00000000000000000000000000000000000000000000000000000000000000008360000151610ebf565b6001600160a01b031603612bb95780516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b80516001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c08201819052612cde57600754612ca29061ffff16662386f26fc100006156a5565b612cac90886156bc565b600754909750612cc89062010000900463ffffffff1687615d00565b9550612cd5602086615d00565b94505050612eb2565b604081015160009061ffff1615612e025760008c6001600160a01b031684600001516001600160a01b031614612da55760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526401000000009092041690634ab35b0b90602401602060405180830381865afa158015612d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d9e9190615d1d565b9050612da8565b508a5b620186a0836040015161ffff16612dea8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661428b90919063ffffffff16565b612df491906156a5565b612dfe91906156cf565b9150505b6060820151612e119088615d00565b9650816080015186612e239190615d00565b8251909650600090612e429063ffffffff16662386f26fc100006156a5565b905080821015612e6157612e56818a6156bc565b985050505050612eb2565b6000836020015163ffffffff16662386f26fc10000612e8091906156a5565b905080831115612ea057612e94818b6156bc565b99505050505050612eb2565b612eaa838b6156bc565b995050505050505b600101612afe565b50509450945094915050565b60008063ffffffff8316612edc610180866156a5565b612ee8876102206156bc565b612ef291906156bc565b612efc91906156bc565b6005546006549192506000917c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690612f3e9061ffff16846156a5565b612f4891906156bc565b60065490915062010000900461ffff16612f726dffffffffffffffffffffffffffff8916836156a5565b612f7c91906156a5565b612f8c90655af3107a40006156a5565b979650505050505050565b6000546001600160a01b03163314612fed576002546001600160a01b03163314612fed576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60005b825181101561328357600083828151811061300f5761300f6157a4565b60200260200101519050602063ffffffff168160a0015163ffffffff16101561308257805160a08201516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526001600160a01b03909216600483015263ffffffff166024820152604401610aa3565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009096169590951764010000000092871692909202919091177fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff166801000000000000000093909216929092027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff16176a010000000000000000000091841691909102177fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff166e01000000000000000000000000000093909216929092027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1617720100000000000000000000000000000000000094151594909402939093177fffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff16730100000000000000000000000000000000000000931515939093029290921790915501612ff2565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d0826040516132b39190615d38565b60405180910390a160005b815181101561332e57600c60008383815181106132dd576132dd6157a4565b6020908102919091018101516001600160a01b0316825281019190915260400160002080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556001016132be565b50805115610ebb577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b816040516133659190615516565b60405180910390a15050565b6000546001600160a01b03163314612fed5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610aa3565b60e08101516001600160a01b031661340f576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548160ff0219169083151502179055509050507f45b5ad483aa608464c2c7f278bd413d284d7790cdc836e40652e23a0277082206040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152508260405161124c929190615dd8565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261384e82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426138329190615df5565b85608001516fffffffffffffffffffffffffffffffff166142c8565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526110f09084906142f0565b8051604081111561392f576040517fb5a10cfa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff161561398357600e5463ffffffff6c010000000000000000000000008204166bffffffffffffffffffffffff909116106139835761398361252a565b600061398f6008613b58565b90505b80156139d15760006139b06139a8600184615df5565b600890613b63565b5090506139be6008826143d5565b5050806139ca90615e08565b9050613992565b506000805b82811015613ad95760008482815181106139f2576139f26157a4565b60200260200101516000015190506000858381518110613a1457613a146157a4565b60200260200101516020015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480613a6957506001600160a01b038216155b15613aab576040517f4de938d10000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610aa3565b613abb60088361ffff84166143ea565b50613aca61ffff821685615d00565b935050508060010190506139d6565b50600e80547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd2490613b4b9083908690615e3d565b60405180910390a1505050565b6000610e7c82614400565b6000808080613b72868661440b565b909450925050505b9250929050565b8154600090613b9d90600160801b900463ffffffff1642615df5565b90508015613c255760018301548354613bd8916fffffffffffffffffffffffffffffffff808216928116918591600160801b909104166142c8565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617600160801b4263ffffffff16021783555b60208201518354613c4b916fffffffffffffffffffffffffffffffff9081169116614436565b835483511515600160a01b027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff9283161717845560208301516040808501518316600160801b0291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990613b4b9084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d9e9190615e5c565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613e075783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b6020840151612522907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83169061428b565b610f7f600382600061444c565b60008151602014613e8157816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610aa39190614c27565b600082806020019051810190613e97919061572f565b90506001600160a01b03811180613eaf575061040081105b15610e7c57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610aa39190614c27565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001613f7e9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001613fb79190615e8f565b60405160208183030381529060405280519060200120876101600151604051602001613fe39190615ea2565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b6000610f67836001600160a01b038416614756565b60005b815181101561419a576000828281518110614078576140786157a4565b60209081029190910181015160408051608080820183528385015163ffffffff90811683528385015167ffffffffffffffff908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9688166c0100000000000000000000000002969096167fffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009095169116179290921791909116929092171790555060010161405b565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e8160405161124c9190615eb5565b336001600160a01b038216036142225760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610aa3565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a76400006142be837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166156a5565b610f6791906156cf565b60006142e7856142d884866156a5565b6142e290876156bc565b614436565b95945050505050565b6000614345826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166147629092919063ffffffff16565b8051909150156110f0578080602001905181019061436391906157da565b6110f05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa3565b6000610f67836001600160a01b038416614771565b6000612522846001600160a01b0385168461478e565b6000610e7c826147ab565b6000808061441985856147b5565b600081815260029690960160205260409095205494959350505050565b60008183106144455781610f67565b5090919050565b8254600160a01b900460ff161580614462575081155b1561446c57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906144a590600160801b900463ffffffff1642615df5565b9050801561454b57818311156144e7576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461451490839085908490600160801b90046fffffffffffffffffffffffffffffffff166142c8565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff16600160801b4263ffffffff160217875592505b848210156145e8576001600160a01b03841661459d576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610aa3565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610aa3565b848310156146d457600186810154600160801b90046fffffffffffffffffffffffffffffffff1690600090829061461f9082615df5565b614629878a615df5565b61463391906156bc565b61463d91906156cf565b90506001600160a01b038616614689576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610aa3565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610aa3565b6146de8584615df5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f6783836147c1565b606061252284846000856147d9565b60008181526002830160205260408120819055610f6783836148c0565b6000828152600284016020526040812082905561252284846148cc565b6000610e7c825490565b6000610f6783836148d8565b60008181526001830160205260408120541515610f67565b6060824710156148515760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa3565b600080866001600160a01b0316858760405161486d9190615f36565b60006040518083038185875af1925050503d80600081146148aa576040519150601f19603f3d011682016040523d82523d6000602084013e6148af565b606091505b5091509150612f8c87838387614902565b6000610f67838361497b565b6000610f678383614a75565b60008260000182815481106148ef576148ef6157a4565b9060005260206000200154905092915050565b6060831561497157825160000361496a576001600160a01b0385163b61496a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa3565b5081612522565b6125228383614ac4565b60008181526001830160205260408120548015614a6457600061499f600183615df5565b85549091506000906149b390600190615df5565b9050818114614a185760008660000182815481106149d3576149d36157a4565b90600052602060002001549050808760000184815481106149f6576149f66157a4565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614a2957614a29615f52565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610e7c565b6000915050610e7c565b5092915050565b6000818152600183016020526040812054614abc57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e7c565b506000610e7c565b815115614ad45781518083602001fd5b8060405162461bcd60e51b8152600401610aa39190614c27565b6001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401525060c0810151614b6b60c08401826001600160a01b03169052565b5060e08101516110f060e08401826001600160a01b03169052565b6101008101610e7c8284614aee565b6001600160a01b0381168114610f7f57600080fd5b8035614bb581614b95565b919050565b600060208284031215614bcc57600080fd5b8135610f6781614b95565b60005b83811015614bf2578181015183820152602001614bda565b50506000910152565b60008151808452614c13816020860160208601614bd7565b601f01601f19169290920160200192915050565b602081526000610f676020830184614bfb565b67ffffffffffffffff81168114610f7f57600080fd5b600060a08284031215614c6257600080fd5b50919050565b60008060408385031215614c7b57600080fd5b8235614c8681614c3a565b9150602083013567ffffffffffffffff811115614ca257600080fd5b614cae85828601614c50565b9150509250929050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b60405290565b6040516101a0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b60405160a0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b6040805190810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b604051601f8201601f1916810167ffffffffffffffff81118282101715614d8a57614d8a614cb8565b604052919050565b600067ffffffffffffffff821115614dac57614dac614cb8565b5060051b60200190565b63ffffffff81168114610f7f57600080fd5b8035614bb581614db6565b803561ffff81168114614bb557600080fd5b8015158114610f7f57600080fd5b8035614bb581614de5565b600082601f830112614e0f57600080fd5b81356020614e24614e1f83614d92565b614d61565b8083825260208201915060208460051b870101935086841115614e4657600080fd5b602086015b84811015614e6b578035614e5e81614b95565b8352918301918301614e4b565b509695505050505050565b6000806040808486031215614e8a57600080fd5b833567ffffffffffffffff80821115614ea257600080fd5b818601915086601f830112614eb657600080fd5b81356020614ec6614e1f83614d92565b82815260e0928302850182019282820191908b851115614ee557600080fd5b958301955b84871015614f8e5780878d031215614f025760008081fd5b614f0a614cce565b8735614f1581614b95565b815287850135614f2481614db6565b8186015287890135614f3581614db6565b818a01526060614f46898201614dd3565b90820152608088810135614f5981614db6565b9082015260a0614f6a898201614dc8565b9082015260c0614f7b898201614df3565b9082015283529586019591830191614eea565b5097505087013593505080831115614fa557600080fd5b5050614cae85828601614dfe565b60008060408385031215614fc657600080fd5b8235614fd181614c3a565b91506020830135614fe181614b95565b809150509250929050565b60006101a08284031215614fff57600080fd5b615007614cf7565b61501083614baa565b815261501e60208401614dd3565b602082015261502f60408401614dc8565b604082015261504060608401614dd3565b606082015261505160808401614dc8565b608082015261506260a08401614dd3565b60a082015261507360c08401614dd3565b60c082015261508460e08401614baa565b60e0820152610100615097818501614dc8565b908201526101206150a9848201614dc8565b908201526101406150bb848201614dd3565b908201526101606150cd848201614dc8565b908201526101806150df848201614df3565b908201529392505050565b600080604083850312156150fd57600080fd5b8235614fd181614b95565b80516001600160a01b03168252602081015161512a602084018261ffff169052565b506040810151615142604084018263ffffffff169052565b506060810151615158606084018261ffff169052565b506080810151615170608084018263ffffffff169052565b5060a081015161518660a084018261ffff169052565b5060c081015161519c60c084018261ffff169052565b5060e08101516151b760e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015190911690830152610180908101511515910152565b6101a08101610e7c8284615108565b6000806020838503121561522857600080fd5b823567ffffffffffffffff8082111561524057600080fd5b818501915085601f83011261525457600080fd5b81358181111561526357600080fd5b8660208260061b850101111561527857600080fd5b60209290920196919550909350505050565b60008151808452602080850194506020840160005b838110156152d357815180516001600160a01b0316885283015161ffff16838801526040909601959082019060010161529f565b509495945050505050565b6040815260006152f1604083018561528a565b90508260208301529392505050565b80356fffffffffffffffffffffffffffffffff81168114614bb557600080fd5b60006060828403121561533257600080fd5b6040516060810181811067ffffffffffffffff8211171561535557615355614cb8565b604052823561536381614de5565b815261537160208401615300565b602082015261538260408401615300565b60408201529392505050565b600080600080608085870312156153a457600080fd5b84356153af81614c3a565b9350602085013567ffffffffffffffff8111156153cb57600080fd5b6153d787828801614c50565b9350506040850135915060608501356153ef81614b95565b939692955090935050565b6000602080838503121561540d57600080fd5b823567ffffffffffffffff81111561542457600080fd5b8301601f8101851361543557600080fd5b8035615443614e1f82614d92565b81815260a0918202830184019184820191908884111561546257600080fd5b938501935b838510156154ed5780858a03121561547f5760008081fd5b615487614d1b565b853561549281614b95565b8152858701356154a181614db6565b818801526040868101356154b481614c3a565b908201526060868101356154c781614c3a565b908201526080868101356154da81614de5565b9082015283529384019391850191615467565b50979650505050505050565b60006020828403121561550b57600080fd5b8135610f6781614c3a565b6020808252825182820181905260009190848201906040850190845b818110156155575783516001600160a01b031683529284019291840191600101615532565b50909695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261559857600080fd5b83018035915067ffffffffffffffff8211156155b357600080fd5b602001915036819003821315613b7a57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155fd57600080fd5b83018035915067ffffffffffffffff82111561561857600080fd5b6020019150600681901b3603821315613b7a57600080fd5b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114614bb557600080fd5b6000806040838503121561566f57600080fd5b61567883615630565b915061568660208401615630565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e7c57610e7c61568f565b80820180821115610e7c57610e7c61568f565b6000826156ec57634e487b7160e01b600052601260045260246000fd5b500490565b67ffffffffffffffff818116838216019080821115614a6e57614a6e61568f565b60006020828403121561572457600080fd5b8151610f6781614b95565b60006020828403121561574157600080fd5b5051919050565b60006040828403121561575a57600080fd5b615762614d3e565b823561576d81614b95565b815261577b60208401614dd3565b60208201529392505050565b60006020828403121561579957600080fd5b8151610f6781614c3a565b634e487b7160e01b600052603260045260246000fd5b8181036000831280158383131683831282161715614a6e57614a6e61568f565b6000602082840312156157ec57600080fd5b8151610f6781614de5565b60006040828403121561580957600080fd5b615811614d3e565b823561581c81614b95565b81526020928301359281019290925250919050565b6bffffffffffffffffffffffff818116838216019080821115614a6e57614a6e61568f565b600067ffffffffffffffff8083168181036158735761587361568f565b6001019392505050565b602081526000825160a0602084015261589960c0840182614bfb565b905067ffffffffffffffff602085015116604084015260408401516001600160a01b038082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600082601f8301126158f757600080fd5b815167ffffffffffffffff81111561591157615911614cb8565b6159246020601f19601f84011601614d61565b81815284602083860101111561593957600080fd5b612522826020830160208701614bd7565b60006020828403121561595c57600080fd5b815167ffffffffffffffff8082111561597457600080fd5b908301906040828603121561598857600080fd5b615990614d3e565b82518281111561599f57600080fd5b6159ab878286016158e6565b8252506020830151828111156159c057600080fd5b6159cc878286016158e6565b60208301525095945050505050565b6020815260008251608060208401526159f760a0840182614bfb565b90506020840151601f1980858403016040860152615a158383614bfb565b9250604086015191508085840301606086015250615a338282614bfb565b91505063ffffffff60608501511660808401528091505092915050565b60008151808452602080850194506020840160005b838110156152d357815180516001600160a01b031688528301518388015260409096019590820190600101615a65565b60008282518085526020808601955060208260051b8401016020860160005b84811015615ae257601f19868403018952615ad0838351614bfb565b98840198925090830190600101615ab4565b5090979650505050505050565b60208152615b0a60208201835167ffffffffffffffff169052565b60006020830151615b2660408401826001600160a01b03169052565b5060408301516001600160a01b038116606084015250606083015167ffffffffffffffff8116608084015250608083015160a083015260a0830151615b6f60c084018215159052565b5060c083015167ffffffffffffffff811660e08401525060e0830151610100615ba2818501836001600160a01b03169052565b840151610120848101919091528401516101a061014080860182905291925090615bd06101c0860184614bfb565b9250808601519050601f19610160818786030181880152615bf18584615a50565b945080880151925050610180818786030181880152615c108584615a95565b970151959092019490945250929392505050565b6bffffffffffffffffffffffff828116828216039080821115614a6e57614a6e61568f565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015615c895780818660040360031b1b83161692505b505092915050565b60008085851115615ca157600080fd5b83861115615cae57600080fd5b5050820193919092039150565b600060408284031215615ccd57600080fd5b615cd5614d3e565b82358152602083013561577b81614de5565b600060208284031215615cf957600080fd5b5035919050565b63ffffffff818116838216019080821115614a6e57614a6e61568f565b600060208284031215615d2f57600080fd5b610f6782615630565b602080825282518282018190526000919060409081850190868401855b82811015615dcb57815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e09093019290850190600101615d55565b5091979650505050505050565b6102a08101615de78285614aee565b610f67610100830184615108565b81810381811115610e7c57610e7c61568f565b600081615e1757615e1761568f565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b63ffffffff83168152604060208201526000612522604083018461528a565b600060408284031215615e6e57600080fd5b615e76614d3e565b615e7f83615630565b8152602083015161577b81614db6565b602081526000610f676020830184615a50565b602081526000610f676020830184615a95565b602080825282518282018190526000919060409081850190868401855b82811015615dcb57815180516001600160a01b031685528681015163ffffffff16878601528581015167ffffffffffffffff908116878701526060808301519091169086015260809081015115159085015260a09093019290850190600101615ed2565b60008251615f48818460208701614bd7565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfea164736f6c6343000818000a", } var EVM2EVMOnRampABI = EVM2EVMOnRampMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go index 6e695182b8..d22c66a435 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var LockReleaseTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b50604051620049ae380380620049ae833981016040819052620000359162000565565b848484833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200017e565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001695760408051600081526020810190915262000169908462000229565b5050505090151560e05250620006d692505050565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000688565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000688565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200069e565b8554909150600090620003fa906001906200069e565b9050818114620004665760008660000182815481106200041e576200041e62000688565b906000526020600020015490508087600001848154811062000444576200044462000688565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a620006c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b805180151581146200054f57600080fd5b600080600080600060a086880312156200057e57600080fd5b85516200058b8162000513565b602087810151919650906001600160401b0380821115620005ab57600080fd5b818901915089601f830112620005c057600080fd5b815181811115620005d557620005d56200052c565b8060051b604051601f19603f83011681018181108582111715620005fd57620005fd6200052c565b60405291825284820192508381018501918c8311156200061c57600080fd5b938501935b828510156200064557620006358562000542565b8452938501939285019262000621565b8099505050505050506200065c6040870162000542565b92506200066c6060870162000554565b91506200067c6080870162000542565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161423c62000772600039600081816104ef015261174201526000818161059c01528181611cde015261278301526000818161057601528181611b0f0152611f94015260008181610290015281816102e50152818161077a0152818161084c015281816108ed0152818161180401528181611a2f01528181611eb401528181612719015261296e015261423c6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063c4bffe2b116100a2578063dc0bd97111610071578063dc0bd97114610574578063e0351e131461059a578063eb521a4c146105c0578063f2fde38b146105d357600080fd5b8063c4bffe2b14610526578063c75eea9c1461053b578063cf7401f31461054e578063db6327dc1461056157600080fd5b8063b0f479a1116100de578063b0f479a1146104bc578063b7946580146104da578063bb98546b146104ed578063c0d786551461051357600080fd5b80638da5cb5b146103fa5780639a4575b914610418578063a7cd63b714610438578063af58d59f1461044d57600080fd5b806354c8a4f31161018757806378a010b21161015657806378a010b2146103b957806379ba5097146103cc5780637d54534e146103d45780638926f54f146103e757600080fd5b806354c8a4f31461036257806366320087146103755780636cfd1553146103885780636d3d1a581461039b57600080fd5b806321df0da7116101c357806321df0da71461028e578063240028e8146102d55780633907753714610322578063432a6ba31461034457600080fd5b806301ffc9a7146101f55780630a2fd4931461021d5780630a861f2a1461023d578063181f5a7714610252575b600080fd5b610208610203366004613318565b6105e6565b60405190151581526020015b60405180910390f35b61023061022b366004613377565b610642565b6040516102149190613400565b61025061024b366004613413565b6106f2565b005b6102306040518060400160405280601e81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e302d646576000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b6102086102e3366004613459565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b610335610330366004613476565b6108a3565b60405190518152602001610214565b60095473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103703660046134fe565b6109a9565b61025061038336600461356a565b610a24565b610250610396366004613459565b610b00565b60085473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103c7366004613596565b610b4f565b610250610cbe565b6102506103e2366004613459565b610dbb565b6102086103f5366004613377565b610e0a565b60005473ffffffffffffffffffffffffffffffffffffffff166102b0565b61042b610426366004613619565b610e21565b6040516102149190613654565b610440610ebb565b60405161021491906136b4565b61046061045b366004613377565b610ecc565b604051610214919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102306104e8366004613377565b610fa1565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b610250610521366004613459565b610fcc565b61052e6110a7565b604051610214919061370e565b610460610549366004613377565b61115f565b61025061055c366004613876565b611231565b61025061056f3660046138bb565b6112ba565b7f00000000000000000000000000000000000000000000000000000000000000006102b0565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105ce366004613413565b611740565b6102506105e1366004613459565b61185c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061063c575061063c82611870565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061066d906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610699906138fd565b80156106e65780601f106106bb576101008083540402835291602001916106e6565b820191906000526020600020905b8154815290600101906020018083116106c957829003601f168201915b50505050509050919050565b60095473ffffffffffffffffffffffffffffffffffffffff16331461074a576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa9190613950565b1015610832576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611954565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c36108be83613a14565b611a28565b6109186108d66060840160408501613459565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611954565b6109286060830160408401613459565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52846060013560405161098a91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6109b1611c59565b610a1e84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611cdc92505050565b50505050565b610a2c611c59565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610a9457600080fd5b505af1158015610aa8573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610af491815260200190565b60405180910390a25050565b610b08611c59565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b57611c59565b610b6083610e0a565b610ba2576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b67ffffffffffffffff831660009081526007602052604081206004018054610bc9906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610bf5906138fd565b8015610c425780601f10610c1757610100808354040283529160200191610c42565b820191906000526020600020905b815481529060010190602001808311610c2557829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610c71838583613b59565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610cb093929190613c74565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610741565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610dc3611c59565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061063c600567ffffffffffffffff8416611e92565b6040805180820190915260608082526020820152610e46610e4183613cd8565b611ead565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610ea08460200160208101906104e89190613377565b81526040805160208181019092526000815291015292915050565b6060610ec76002612077565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261063c90612084565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061066d906138fd565b610fd4611c59565b73ffffffffffffffffffffffffffffffffffffffff8116611021576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110b56005612077565b90506000815167ffffffffffffffff8111156110d3576110d3613750565b6040519080825280602002602001820160405280156110fc578160200160208202803683370190505b50905060005b82518110156111585782818151811061111d5761111d613d7a565b602002602001015182828151811061113757611137613d7a565b67ffffffffffffffff90921660209283029190910190910152600101611102565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261063c90612084565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611271575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112aa576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b6112b5838383612136565b505050565b6112c2611c59565b60005b818110156112b55760008383838181106112e1576112e1613d7a565b90506020028101906112f39190613da9565b6112fc90613de7565b90506113118160800151826020015115612220565b6113248160a00151826020015115612220565b8060200151156116205780516113469060059067ffffffffffffffff16612359565b61138b5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b60408101515115806113a05750606081015151155b156113d7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115b89082613e9b565b50606082015160058201906115cd9082613e9b565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116139493929190613fb5565b60405180910390a1611737565b80516116389060059067ffffffffffffffff16612365565b61167d5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116e660048301826132ca565b6116f46005830160006132ca565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112c5565b7f0000000000000000000000000000000000000000000000000000000000000000611797576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff1633146117ea576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b61182c73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612371565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611864611c59565b61186d816123cf565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061190357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061063c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112b59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526124c4565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611abd5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8f919061404e565b15611bc6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bd381602001516125d0565b6000611be28260200151610642565b9050805160001480611c06575080805190602001208260a001518051906020012014155b15611c43578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107419190613400565b611c55826020015183606001516126f6565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611cda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610741565b565b7f0000000000000000000000000000000000000000000000000000000000000000611d33576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611dc9576000838281518110611d5357611d53613d7a565b60200260200101519050611d7181600261273d90919063ffffffff16565b15611dc05760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611d36565b5060005b81518110156112b5576000828281518110611dea57611dea613d7a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e2e5750611e8a565b611e3960028261275f565b15611e885760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611dcd565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611f425760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611ff0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612014919061404e565b1561204b576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120588160400151612781565b6120658160200151612800565b61186d8160200151826060015161294e565b60606000611ea683612992565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261211282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426120f6919061409a565b85608001516fffffffffffffffffffffffffffffffff166129ed565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61213f83610e0a565b612181576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b61218c826000612220565b67ffffffffffffffff831660009081526007602052604090206121af9083612a17565b6121ba816000612220565b67ffffffffffffffff831660009081526007602052604090206121e09060020182612a17565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051612213939291906140ad565b60405180910390a1505050565b8151156122e75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612276575060408201516fffffffffffffffffffffffffffffffff16155b156122af57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107419190614130565b8015611c55576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612320575060208201516fffffffffffffffffffffffffffffffff1615155b15611c5557816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107419190614130565b6000611ea68383612bb9565b6000611ea68383612c08565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a1e9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016119a6565b3373ffffffffffffffffffffffffffffffffffffffff82160361244e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610741565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612526826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612cfb9092919063ffffffff16565b8051909150156112b55780806020019051810190612544919061404e565b6112b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610741565b6125d981610e0a565b61261b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561269a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126be919061404e565b61186d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c5590600201827f0000000000000000000000000000000000000000000000000000000000000000612d0a565b6000611ea68373ffffffffffffffffffffffffffffffffffffffff8416612c08565b6000611ea68373ffffffffffffffffffffffffffffffffffffffff8416612bb9565b7f00000000000000000000000000000000000000000000000000000000000000001561186d576127b260028261308d565b61186d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610741565b61280981610e0a565b61284b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156128c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e8919061416c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461186d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c5590827f0000000000000000000000000000000000000000000000000000000000000000612d0a565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106e657602002820191906000526020600020905b8154815260200190600101908083116129ce5750505050509050919050565b6000612a0c856129fd8486614189565b612a0790876141a0565b6130bc565b90505b949350505050565b8154600090612a4090700100000000000000000000000000000000900463ffffffff164261409a565b90508015612ae25760018301548354612a88916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166129ed565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612b08916fffffffffffffffffffffffffffffffff90811691166130bc565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612213908490614130565b6000818152600183016020526040812054612c005750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561063c565b50600061063c565b60008181526001830160205260408120548015612cf1576000612c2c60018361409a565b8554909150600090612c409060019061409a565b9050818114612ca5576000866000018281548110612c6057612c60613d7a565b9060005260206000200154905080876000018481548110612c8357612c83613d7a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612cb657612cb66141b3565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061063c565b600091505061063c565b6060612a0f84846000856130d2565b825474010000000000000000000000000000000000000000900460ff161580612d31575081155b15612d3b57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612d8190700100000000000000000000000000000000900463ffffffff164261409a565b90508015612e415781831115612dc3576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612dfd9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166129ed565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612ef85773ffffffffffffffffffffffffffffffffffffffff8416612ea0576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610741565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610741565b8483101561300b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f3c908261409a565b612f46878a61409a565b612f5091906141a0565b612f5a91906141e2565b905073ffffffffffffffffffffffffffffffffffffffff8616612fb3576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610741565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610741565b613015858461409a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611ea6565b60008183106130cb5781611ea6565b5090919050565b606082471015613164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610741565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161318d919061421d565b60006040518083038185875af1925050503d80600081146131ca576040519150601f19603f3d011682016040523d82523d6000602084013e6131cf565b606091505b50915091506131e0878383876131eb565b979650505050505050565b6060831561328157825160000361327a5773ffffffffffffffffffffffffffffffffffffffff85163b61327a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610741565b5081612a0f565b612a0f83838151156132965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107419190613400565b5080546132d6906138fd565b6000825580601f106132e6575050565b601f01602090049060005260206000209081019061186d91905b808211156133145760008155600101613300565b5090565b60006020828403121561332a57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611ea657600080fd5b803567ffffffffffffffff8116811461337257600080fd5b919050565b60006020828403121561338957600080fd5b611ea68261335a565b60005b838110156133ad578181015183820152602001613395565b50506000910152565b600081518084526133ce816020860160208601613392565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611ea660208301846133b6565b60006020828403121561342557600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461186d57600080fd5b80356133728161342c565b60006020828403121561346b57600080fd5b8135611ea68161342c565b60006020828403121561348857600080fd5b813567ffffffffffffffff81111561349f57600080fd5b82016101008185031215611ea657600080fd5b60008083601f8401126134c457600080fd5b50813567ffffffffffffffff8111156134dc57600080fd5b6020830191508360208260051b85010111156134f757600080fd5b9250929050565b6000806000806040858703121561351457600080fd5b843567ffffffffffffffff8082111561352c57600080fd5b613538888389016134b2565b9096509450602087013591508082111561355157600080fd5b5061355e878288016134b2565b95989497509550505050565b6000806040838503121561357d57600080fd5b82356135888161342c565b946020939093013593505050565b6000806000604084860312156135ab57600080fd5b6135b48461335a565b9250602084013567ffffffffffffffff808211156135d157600080fd5b818601915086601f8301126135e557600080fd5b8135818111156135f457600080fd5b87602082850101111561360657600080fd5b6020830194508093505050509250925092565b60006020828403121561362b57600080fd5b813567ffffffffffffffff81111561364257600080fd5b820160a08185031215611ea657600080fd5b60208152600082516040602084015261367060608401826133b6565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526136ab82826133b6565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561370257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016136d0565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561370257835167ffffffffffffffff168352928401929184019160010161372a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156137a3576137a3613750565b60405290565b60405160c0810167ffffffffffffffff811182821017156137a3576137a3613750565b801515811461186d57600080fd5b8035613372816137cc565b80356fffffffffffffffffffffffffffffffff8116811461337257600080fd5b60006060828403121561381757600080fd5b6040516060810181811067ffffffffffffffff8211171561383a5761383a613750565b604052905080823561384b816137cc565b8152613859602084016137e5565b602082015261386a604084016137e5565b60408201525092915050565b600080600060e0848603121561388b57600080fd5b6138948461335a565b92506138a38560208601613805565b91506138b28560808601613805565b90509250925092565b600080602083850312156138ce57600080fd5b823567ffffffffffffffff8111156138e557600080fd5b6138f1858286016134b2565b90969095509350505050565b600181811c9082168061391157607f821691505b60208210810361394a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561396257600080fd5b5051919050565b600082601f83011261397a57600080fd5b813567ffffffffffffffff8082111561399557613995613750565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156139db576139db613750565b816040528381528660208588010111156139f457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613a2757600080fd5b613a2f61377f565b823567ffffffffffffffff80821115613a4757600080fd5b613a5336838701613969565b8352613a616020860161335a565b6020840152613a726040860161344e565b604084015260608501356060840152613a8d6080860161344e565b608084015260a0850135915080821115613aa657600080fd5b613ab236838701613969565b60a084015260c0850135915080821115613acb57600080fd5b613ad736838701613969565b60c084015260e0850135915080821115613af057600080fd5b50613afd36828601613969565b60e08301525092915050565b601f8211156112b5576000816000526020600020601f850160051c81016020861015613b325750805b601f850160051c820191505b81811015613b5157828155600101613b3e565b505050505050565b67ffffffffffffffff831115613b7157613b71613750565b613b8583613b7f83546138fd565b83613b09565b6000601f841160018114613bd75760008515613ba15750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613c6d565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613c265786850135825560209485019460019092019101613c06565b5086821015613c61577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613c8760408301866133b6565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613cea57600080fd5b60405160a0810167ffffffffffffffff8282108183111715613d0e57613d0e613750565b816040528435915080821115613d2357600080fd5b50613d3036828601613969565b825250613d3f6020840161335a565b60208201526040830135613d528161342c565b6040820152606083810135908201526080830135613d6f8161342c565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ddd57600080fd5b9190910192915050565b60006101408236031215613dfa57600080fd5b613e026137a9565b613e0b8361335a565b8152613e19602084016137da565b6020820152604083013567ffffffffffffffff80821115613e3957600080fd5b613e4536838701613969565b60408401526060850135915080821115613e5e57600080fd5b50613e6b36828601613969565b606083015250613e7e3660808501613805565b6080820152613e903660e08501613805565b60a082015292915050565b815167ffffffffffffffff811115613eb557613eb5613750565b613ec981613ec384546138fd565b84613b09565b602080601f831160018114613f1c5760008415613ee65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b51565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613f6957888601518255948401946001909101908401613f4a565b5085821015613fa557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613fd9818401876133b6565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506140179050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526136ab565b60006020828403121561406057600080fd5b8151611ea6816137cc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561063c5761063c61406b565b67ffffffffffffffff8416815260e081016140f960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612a0f565b6060810161063c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561417e57600080fd5b8151611ea68161342c565b808202811582820484141761063c5761063c61406b565b8082018082111561063c5761063c61406b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614218577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613ddd81846020870161339256fea164736f6c6343000818000a", + Bin: "0x6101006040523480156200001257600080fd5b50604051620049ae380380620049ae833981016040819052620000359162000565565b848484833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200017e565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001695760408051600081526020810190915262000169908462000229565b5050505090151560e05250620006d692505050565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000688565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000688565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200069e565b8554909150600090620003fa906001906200069e565b9050818114620004665760008660000182815481106200041e576200041e62000688565b906000526020600020015490508087600001848154811062000444576200044462000688565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a620006c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b805180151581146200054f57600080fd5b600080600080600060a086880312156200057e57600080fd5b85516200058b8162000513565b602087810151919650906001600160401b0380821115620005ab57600080fd5b818901915089601f830112620005c057600080fd5b815181811115620005d557620005d56200052c565b8060051b604051601f19603f83011681018181108582111715620005fd57620005fd6200052c565b60405291825284820192508381018501918c8311156200061c57600080fd5b938501935b828510156200064557620006358562000542565b8452938501939285019262000621565b8099505050505050506200065c6040870162000542565b92506200066c6060870162000554565b91506200067c6080870162000542565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161423c62000772600039600081816104ef015261174201526000818161059c01528181611cde015261278301526000818161057601528181611b0f0152611f94015260008181610290015281816102e50152818161077a0152818161084c015281816108ed0152818161180401528181611a2f01528181611eb401528181612719015261296e015261423c6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063c4bffe2b116100a2578063dc0bd97111610071578063dc0bd97114610574578063e0351e131461059a578063eb521a4c146105c0578063f2fde38b146105d357600080fd5b8063c4bffe2b14610526578063c75eea9c1461053b578063cf7401f31461054e578063db6327dc1461056157600080fd5b8063b0f479a1116100de578063b0f479a1146104bc578063b7946580146104da578063bb98546b146104ed578063c0d786551461051357600080fd5b80638da5cb5b146103fa5780639a4575b914610418578063a7cd63b714610438578063af58d59f1461044d57600080fd5b806354c8a4f31161018757806378a010b21161015657806378a010b2146103b957806379ba5097146103cc5780637d54534e146103d45780638926f54f146103e757600080fd5b806354c8a4f31461036257806366320087146103755780636cfd1553146103885780636d3d1a581461039b57600080fd5b806321df0da7116101c357806321df0da71461028e578063240028e8146102d55780633907753714610322578063432a6ba31461034457600080fd5b806301ffc9a7146101f55780630a2fd4931461021d5780630a861f2a1461023d578063181f5a7714610252575b600080fd5b610208610203366004613318565b6105e6565b60405190151581526020015b60405180910390f35b61023061022b366004613377565b610642565b6040516102149190613400565b61025061024b366004613413565b6106f2565b005b6102306040518060400160405280601a81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e3000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b6102086102e3366004613459565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b610335610330366004613476565b6108a3565b60405190518152602001610214565b60095473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103703660046134fe565b6109a9565b61025061038336600461356a565b610a24565b610250610396366004613459565b610b00565b60085473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103c7366004613596565b610b4f565b610250610cbe565b6102506103e2366004613459565b610dbb565b6102086103f5366004613377565b610e0a565b60005473ffffffffffffffffffffffffffffffffffffffff166102b0565b61042b610426366004613619565b610e21565b6040516102149190613654565b610440610ebb565b60405161021491906136b4565b61046061045b366004613377565b610ecc565b604051610214919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102306104e8366004613377565b610fa1565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b610250610521366004613459565b610fcc565b61052e6110a7565b604051610214919061370e565b610460610549366004613377565b61115f565b61025061055c366004613876565b611231565b61025061056f3660046138bb565b6112ba565b7f00000000000000000000000000000000000000000000000000000000000000006102b0565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105ce366004613413565b611740565b6102506105e1366004613459565b61185c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061063c575061063c82611870565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061066d906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610699906138fd565b80156106e65780601f106106bb576101008083540402835291602001916106e6565b820191906000526020600020905b8154815290600101906020018083116106c957829003601f168201915b50505050509050919050565b60095473ffffffffffffffffffffffffffffffffffffffff16331461074a576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa9190613950565b1015610832576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611954565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c36108be83613a14565b611a28565b6109186108d66060840160408501613459565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611954565b6109286060830160408401613459565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52846060013560405161098a91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6109b1611c59565b610a1e84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611cdc92505050565b50505050565b610a2c611c59565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610a9457600080fd5b505af1158015610aa8573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610af491815260200190565b60405180910390a25050565b610b08611c59565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b57611c59565b610b6083610e0a565b610ba2576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b67ffffffffffffffff831660009081526007602052604081206004018054610bc9906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610bf5906138fd565b8015610c425780601f10610c1757610100808354040283529160200191610c42565b820191906000526020600020905b815481529060010190602001808311610c2557829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610c71838583613b59565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610cb093929190613c74565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610741565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610dc3611c59565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061063c600567ffffffffffffffff8416611e92565b6040805180820190915260608082526020820152610e46610e4183613cd8565b611ead565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610ea08460200160208101906104e89190613377565b81526040805160208181019092526000815291015292915050565b6060610ec76002612077565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261063c90612084565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061066d906138fd565b610fd4611c59565b73ffffffffffffffffffffffffffffffffffffffff8116611021576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110b56005612077565b90506000815167ffffffffffffffff8111156110d3576110d3613750565b6040519080825280602002602001820160405280156110fc578160200160208202803683370190505b50905060005b82518110156111585782818151811061111d5761111d613d7a565b602002602001015182828151811061113757611137613d7a565b67ffffffffffffffff90921660209283029190910190910152600101611102565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261063c90612084565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611271575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112aa576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b6112b5838383612136565b505050565b6112c2611c59565b60005b818110156112b55760008383838181106112e1576112e1613d7a565b90506020028101906112f39190613da9565b6112fc90613de7565b90506113118160800151826020015115612220565b6113248160a00151826020015115612220565b8060200151156116205780516113469060059067ffffffffffffffff16612359565b61138b5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b60408101515115806113a05750606081015151155b156113d7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115b89082613e9b565b50606082015160058201906115cd9082613e9b565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116139493929190613fb5565b60405180910390a1611737565b80516116389060059067ffffffffffffffff16612365565b61167d5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116e660048301826132ca565b6116f46005830160006132ca565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112c5565b7f0000000000000000000000000000000000000000000000000000000000000000611797576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff1633146117ea576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b61182c73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612371565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611864611c59565b61186d816123cf565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061190357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061063c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112b59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526124c4565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611abd5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8f919061404e565b15611bc6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bd381602001516125d0565b6000611be28260200151610642565b9050805160001480611c06575080805190602001208260a001518051906020012014155b15611c43578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107419190613400565b611c55826020015183606001516126f6565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611cda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610741565b565b7f0000000000000000000000000000000000000000000000000000000000000000611d33576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611dc9576000838281518110611d5357611d53613d7a565b60200260200101519050611d7181600261273d90919063ffffffff16565b15611dc05760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611d36565b5060005b81518110156112b5576000828281518110611dea57611dea613d7a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e2e5750611e8a565b611e3960028261275f565b15611e885760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611dcd565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611f425760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611ff0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612014919061404e565b1561204b576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120588160400151612781565b6120658160200151612800565b61186d8160200151826060015161294e565b60606000611ea683612992565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261211282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426120f6919061409a565b85608001516fffffffffffffffffffffffffffffffff166129ed565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61213f83610e0a565b612181576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b61218c826000612220565b67ffffffffffffffff831660009081526007602052604090206121af9083612a17565b6121ba816000612220565b67ffffffffffffffff831660009081526007602052604090206121e09060020182612a17565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051612213939291906140ad565b60405180910390a1505050565b8151156122e75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612276575060408201516fffffffffffffffffffffffffffffffff16155b156122af57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107419190614130565b8015611c55576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612320575060208201516fffffffffffffffffffffffffffffffff1615155b15611c5557816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107419190614130565b6000611ea68383612bb9565b6000611ea68383612c08565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a1e9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016119a6565b3373ffffffffffffffffffffffffffffffffffffffff82160361244e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610741565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612526826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612cfb9092919063ffffffff16565b8051909150156112b55780806020019051810190612544919061404e565b6112b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610741565b6125d981610e0a565b61261b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561269a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126be919061404e565b61186d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c5590600201827f0000000000000000000000000000000000000000000000000000000000000000612d0a565b6000611ea68373ffffffffffffffffffffffffffffffffffffffff8416612c08565b6000611ea68373ffffffffffffffffffffffffffffffffffffffff8416612bb9565b7f00000000000000000000000000000000000000000000000000000000000000001561186d576127b260028261308d565b61186d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610741565b61280981610e0a565b61284b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156128c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e8919061416c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461186d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c5590827f0000000000000000000000000000000000000000000000000000000000000000612d0a565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106e657602002820191906000526020600020905b8154815260200190600101908083116129ce5750505050509050919050565b6000612a0c856129fd8486614189565b612a0790876141a0565b6130bc565b90505b949350505050565b8154600090612a4090700100000000000000000000000000000000900463ffffffff164261409a565b90508015612ae25760018301548354612a88916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166129ed565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612b08916fffffffffffffffffffffffffffffffff90811691166130bc565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612213908490614130565b6000818152600183016020526040812054612c005750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561063c565b50600061063c565b60008181526001830160205260408120548015612cf1576000612c2c60018361409a565b8554909150600090612c409060019061409a565b9050818114612ca5576000866000018281548110612c6057612c60613d7a565b9060005260206000200154905080876000018481548110612c8357612c83613d7a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612cb657612cb66141b3565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061063c565b600091505061063c565b6060612a0f84846000856130d2565b825474010000000000000000000000000000000000000000900460ff161580612d31575081155b15612d3b57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612d8190700100000000000000000000000000000000900463ffffffff164261409a565b90508015612e415781831115612dc3576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612dfd9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166129ed565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612ef85773ffffffffffffffffffffffffffffffffffffffff8416612ea0576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610741565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610741565b8483101561300b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f3c908261409a565b612f46878a61409a565b612f5091906141a0565b612f5a91906141e2565b905073ffffffffffffffffffffffffffffffffffffffff8616612fb3576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610741565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610741565b613015858461409a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611ea6565b60008183106130cb5781611ea6565b5090919050565b606082471015613164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610741565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161318d919061421d565b60006040518083038185875af1925050503d80600081146131ca576040519150601f19603f3d011682016040523d82523d6000602084013e6131cf565b606091505b50915091506131e0878383876131eb565b979650505050505050565b6060831561328157825160000361327a5773ffffffffffffffffffffffffffffffffffffffff85163b61327a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610741565b5081612a0f565b612a0f83838151156132965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107419190613400565b5080546132d6906138fd565b6000825580601f106132e6575050565b601f01602090049060005260206000209081019061186d91905b808211156133145760008155600101613300565b5090565b60006020828403121561332a57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611ea657600080fd5b803567ffffffffffffffff8116811461337257600080fd5b919050565b60006020828403121561338957600080fd5b611ea68261335a565b60005b838110156133ad578181015183820152602001613395565b50506000910152565b600081518084526133ce816020860160208601613392565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611ea660208301846133b6565b60006020828403121561342557600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461186d57600080fd5b80356133728161342c565b60006020828403121561346b57600080fd5b8135611ea68161342c565b60006020828403121561348857600080fd5b813567ffffffffffffffff81111561349f57600080fd5b82016101008185031215611ea657600080fd5b60008083601f8401126134c457600080fd5b50813567ffffffffffffffff8111156134dc57600080fd5b6020830191508360208260051b85010111156134f757600080fd5b9250929050565b6000806000806040858703121561351457600080fd5b843567ffffffffffffffff8082111561352c57600080fd5b613538888389016134b2565b9096509450602087013591508082111561355157600080fd5b5061355e878288016134b2565b95989497509550505050565b6000806040838503121561357d57600080fd5b82356135888161342c565b946020939093013593505050565b6000806000604084860312156135ab57600080fd5b6135b48461335a565b9250602084013567ffffffffffffffff808211156135d157600080fd5b818601915086601f8301126135e557600080fd5b8135818111156135f457600080fd5b87602082850101111561360657600080fd5b6020830194508093505050509250925092565b60006020828403121561362b57600080fd5b813567ffffffffffffffff81111561364257600080fd5b820160a08185031215611ea657600080fd5b60208152600082516040602084015261367060608401826133b6565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526136ab82826133b6565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561370257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016136d0565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561370257835167ffffffffffffffff168352928401929184019160010161372a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156137a3576137a3613750565b60405290565b60405160c0810167ffffffffffffffff811182821017156137a3576137a3613750565b801515811461186d57600080fd5b8035613372816137cc565b80356fffffffffffffffffffffffffffffffff8116811461337257600080fd5b60006060828403121561381757600080fd5b6040516060810181811067ffffffffffffffff8211171561383a5761383a613750565b604052905080823561384b816137cc565b8152613859602084016137e5565b602082015261386a604084016137e5565b60408201525092915050565b600080600060e0848603121561388b57600080fd5b6138948461335a565b92506138a38560208601613805565b91506138b28560808601613805565b90509250925092565b600080602083850312156138ce57600080fd5b823567ffffffffffffffff8111156138e557600080fd5b6138f1858286016134b2565b90969095509350505050565b600181811c9082168061391157607f821691505b60208210810361394a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561396257600080fd5b5051919050565b600082601f83011261397a57600080fd5b813567ffffffffffffffff8082111561399557613995613750565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156139db576139db613750565b816040528381528660208588010111156139f457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613a2757600080fd5b613a2f61377f565b823567ffffffffffffffff80821115613a4757600080fd5b613a5336838701613969565b8352613a616020860161335a565b6020840152613a726040860161344e565b604084015260608501356060840152613a8d6080860161344e565b608084015260a0850135915080821115613aa657600080fd5b613ab236838701613969565b60a084015260c0850135915080821115613acb57600080fd5b613ad736838701613969565b60c084015260e0850135915080821115613af057600080fd5b50613afd36828601613969565b60e08301525092915050565b601f8211156112b5576000816000526020600020601f850160051c81016020861015613b325750805b601f850160051c820191505b81811015613b5157828155600101613b3e565b505050505050565b67ffffffffffffffff831115613b7157613b71613750565b613b8583613b7f83546138fd565b83613b09565b6000601f841160018114613bd75760008515613ba15750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613c6d565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613c265786850135825560209485019460019092019101613c06565b5086821015613c61577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613c8760408301866133b6565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613cea57600080fd5b60405160a0810167ffffffffffffffff8282108183111715613d0e57613d0e613750565b816040528435915080821115613d2357600080fd5b50613d3036828601613969565b825250613d3f6020840161335a565b60208201526040830135613d528161342c565b6040820152606083810135908201526080830135613d6f8161342c565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ddd57600080fd5b9190910192915050565b60006101408236031215613dfa57600080fd5b613e026137a9565b613e0b8361335a565b8152613e19602084016137da565b6020820152604083013567ffffffffffffffff80821115613e3957600080fd5b613e4536838701613969565b60408401526060850135915080821115613e5e57600080fd5b50613e6b36828601613969565b606083015250613e7e3660808501613805565b6080820152613e903660e08501613805565b60a082015292915050565b815167ffffffffffffffff811115613eb557613eb5613750565b613ec981613ec384546138fd565b84613b09565b602080601f831160018114613f1c5760008415613ee65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b51565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613f6957888601518255948401946001909101908401613f4a565b5085821015613fa557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613fd9818401876133b6565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506140179050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526136ab565b60006020828403121561406057600080fd5b8151611ea6816137cc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561063c5761063c61406b565b67ffffffffffffffff8416815260e081016140f960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612a0f565b6060810161063c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561417e57600080fd5b8151611ea68161342c565b808202811582820484141761063c5761063c61406b565b8082018082111561063c5761063c61406b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614218577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613ddd81846020870161339256fea164736f6c6343000818000a", } var LockReleaseTokenPoolABI = LockReleaseTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go index f05a59bc73..0aa2084a82 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var LockReleaseTokenPoolAndProxyMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162004f0e38038062004f0e83398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508181146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161478d6200078160003960008181610545015261191b0152600081816105f201528181611f550152612b110152600081816105cc01528181611ce801526122080152600081816102ad01528181610302015281816107d0015281816108a20152818161097c015281816119dd01528181611c08015281816121280152818161230e01528181612aa70152612cfc015261478d6000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e13146105f0578063eb521a4c14610616578063f2fde38b1461062957600080fd5b8063db6327dc146105b7578063dc0bd971146105ca57600080fd5b8063c0d7865514610569578063c4bffe2b1461057c578063c75eea9c14610591578063cf7401f3146105a457600080fd5b8063a8d87a3b11610114578063b0f479a1116100f9578063b0f479a114610512578063b794658014610530578063bb98546b1461054357600080fd5b8063a8d87a3b14610490578063af58d59f146104a357600080fd5b80638da5cb5b1461042a5780639766b932146104485780639a4575b91461045b578063a7cd63b71461047b57600080fd5b806354c8a4f3116101d857806378a010b2116101a75780637d54534e1161018c5780637d54534e146103f157806383826b2b146104045780638926f54f1461041757600080fd5b806378a010b2146103d657806379ba5097146103e957600080fd5b806354c8a4f31461037f57806366320087146103925780636cfd1553146103a55780636d3d1a58146103b857600080fd5b806321df0da71161021457806321df0da7146102ab578063240028e8146102f2578063390775371461033f578063432a6ba31461036157600080fd5b806301ffc9a7146102465780630a2fd4931461026e5780630a861f2a1461028e578063181f5a77146102a3575b600080fd5b6102596102543660046136a6565b61063c565b60405190151581526020015b60405180910390f35b61028161027c366004613705565b610698565b604051610265919061378e565b6102a161029c3660046137a1565b610748565b005b6102816108f9565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102596103003660046137e7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61035261034d366004613804565b610915565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a161038d36600461388c565b610a4e565b6102a16103a03660046138f8565b610ac9565b6102a16103b33660046137e7565b610b55565b60085473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16103e4366004613924565b610ba4565b6102a1610d13565b6102a16103ff3660046137e7565b610e10565b6102596104123660046139a7565b610e5f565b610259610425366004613705565b610f2c565b60005473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16104563660046137e7565b610f43565b61046e6104693660046139de565b610fd2565b6040516102659190613a19565b61048361109b565b6040516102659190613a79565b6102cd61049e366004613705565b503090565b6104b66104b1366004613705565b6110ac565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102cd565b61028161053e366004613705565b611181565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16105773660046137e7565b6111ac565b610584611280565b6040516102659190613ad3565b6104b661059f366004613705565b611338565b6102a16105b2366004613c8a565b61140a565b6102a16105c5366004613ccf565b611493565b7f00000000000000000000000000000000000000000000000000000000000000006102cd565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16106243660046137a1565b611919565b6102a16106373660046137e7565b611a35565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d40566000000000000000000000000000000000000000000000000000000001480610692575061069282611a49565b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106c390613d11565b80601f01602080910402602001604051908101604052809291908181526020018280546106ef90613d11565b801561073c5780601f106107115761010080835404028352916020019161073c565b820191906000526020600020905b81548152906001019060200180831161071f57829003601f168201915b50505050509050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146107a0576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190613d64565b1015610888576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108c973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611b2d565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b60405180606001604052806026815260200161475b6026913981565b60408051602081019091526000815261093561093083613e19565b611c01565b60095473ffffffffffffffffffffffffffffffffffffffff166109ac576109a761096560608401604085016137e7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611b2d565b6109bd565b6109bd6109b883613e19565b611e32565b6109cd60608301604084016137e7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f528460600135604051610a2f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a56611ed0565b610ac384848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f5392505050565b50505050565b610ad1611ed0565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610b3957600080fd5b505af1158015610b4d573d6000803e3d6000fd5b505050505050565b610b5d611ed0565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610bac611ed0565b610bb583610f2c565b610bf7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b67ffffffffffffffff831660009081526007602052604081206004018054610c1e90613d11565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4a90613d11565b8015610c975780601f10610c6c57610100808354040283529160200191610c97565b820191906000526020600020905b815481529060010190602001808311610c7a57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cc6838583613f56565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d0593929190614070565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610797565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e18611ed0565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610f255750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610f01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2591906140d4565b9392505050565b6000610692600567ffffffffffffffff8416612109565b610f4b611ed0565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610ff7610ff2836140f1565b612121565b60095473ffffffffffffffffffffffffffffffffffffffff161561102657611026611021836140f1565b6122eb565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a2604051806040016040528061108084602001602081019061053e9190613705565b81526040805160208181019092526000815291015292915050565b60606110a76002612405565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261069290612412565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106c390613d11565b6111b4611ed0565b73ffffffffffffffffffffffffffffffffffffffff8116611201576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610fc6565b6060600061128e6005612405565b90506000815167ffffffffffffffff8111156112ac576112ac613b15565b6040519080825280602002602001820160405280156112d5578160200160208202803683370190505b50905060005b8251811015611331578281815181106112f6576112f6614193565b602002602001015182828151811061131057611310614193565b67ffffffffffffffff909216602092830291909101909101526001016112db565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261069290612412565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061144a575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611483576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b61148e8383836124c4565b505050565b61149b611ed0565b60005b8181101561148e5760008383838181106114ba576114ba614193565b90506020028101906114cc91906141c2565b6114d590614200565b90506114ea81608001518260200151156125ae565b6114fd8160a001518260200151156125ae565b8060200151156117f957805161151f9060059067ffffffffffffffff166126e7565b6115645780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b60408101515115806115795750606081015151155b156115b0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061179190826142b4565b50606082015160058201906117a690826142b4565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506117ec94939291906143ce565b60405180910390a1611910565b80516118119060059067ffffffffffffffff166126f3565b6118565780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118bf6004830182613658565b6118cd600583016000613658565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161149e565b7f0000000000000000000000000000000000000000000000000000000000000000611970576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff1633146119c3576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b611a0573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846126ff565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611a3d611ed0565b611a468161275d565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611adc57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261148e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612852565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611c965760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6891906140d4565b15611d9f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dac816020015161295e565b6000611dbb8260200151610698565b9050805160001480611ddf575080805190602001208260a001518051906020012014155b15611e1c578160a001516040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610797919061378e565b611e2e82602001518360600151612a84565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611e9b9490939291600401614467565b600060405180830381600087803b158015611eb557600080fd5b505af1158015611ec9573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611f51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610797565b565b7f0000000000000000000000000000000000000000000000000000000000000000611faa576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612040576000838281518110611fca57611fca614193565b60200260200101519050611fe8816002612acb90919063ffffffff16565b156120375760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611fad565b5060005b815181101561148e57600082828151811061206157612061614193565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120a55750612101565b6120b0600282612aed565b156120ff5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612044565b60008181526001830160205260408120541515610f25565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121b65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612264573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228891906140d4565b156122bf576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122cc8160400151612b0f565b6122d98160200151612b8e565b611a4681602001518260600151612cdc565b60095460608201516123389173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611b2d565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909516946396875445946123a0949392916004016144c8565b6000604051808303816000875af11580156123bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e2e9190810190614528565b60606000610f2583612d20565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526124a082606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261248491906145c5565b85608001516fffffffffffffffffffffffffffffffff16612d7b565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6124cd83610f2c565b61250f576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b61251a8260006125ae565b67ffffffffffffffff8316600090815260076020526040902061253d9083612da5565b6125488160006125ae565b67ffffffffffffffff8316600090815260076020526040902061256e9060020182612da5565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516125a1939291906145d8565b60405180910390a1505050565b8151156126755781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612604575060408201516fffffffffffffffffffffffffffffffff16155b1561263d57816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610797919061465b565b8015611e2e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806126ae575060208201516fffffffffffffffffffffffffffffffff1615155b15611e2e57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610797919061465b565b6000610f258383612f47565b6000610f258383612f96565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ac39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611b7f565b3373ffffffffffffffffffffffffffffffffffffffff8216036127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610797565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006128b4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130899092919063ffffffff16565b80519091501561148e57808060200190518101906128d291906140d4565b61148e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610797565b61296781610f2c565b6129a9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612a28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4c91906140d4565b611a46576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e2e90600201827f0000000000000000000000000000000000000000000000000000000000000000613098565b6000610f258373ffffffffffffffffffffffffffffffffffffffff8416612f96565b6000610f258373ffffffffffffffffffffffffffffffffffffffff8416612f47565b7f000000000000000000000000000000000000000000000000000000000000000015611a4657612b4060028261341b565b611a46576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610797565b612b9781610f2c565b612bd9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c769190614697565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a46576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e2e90827f0000000000000000000000000000000000000000000000000000000000000000613098565b60608160000180548060200260200160405190810160405280929190818152602001828054801561073c57602002820191906000526020600020905b815481526020019060010190808311612d5c5750505050509050919050565b6000612d9a85612d8b84866146b4565b612d9590876146cb565b61344a565b90505b949350505050565b8154600090612dce90700100000000000000000000000000000000900463ffffffff16426145c5565b90508015612e705760018301548354612e16916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612d7b565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612e96916fffffffffffffffffffffffffffffffff908116911661344a565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906125a190849061465b565b6000818152600183016020526040812054612f8e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610692565b506000610692565b6000818152600183016020526040812054801561307f576000612fba6001836145c5565b8554909150600090612fce906001906145c5565b9050818114613033576000866000018281548110612fee57612fee614193565b906000526020600020015490508087600001848154811061301157613011614193565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613044576130446146de565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610692565b6000915050610692565b6060612d9d8484600085613460565b825474010000000000000000000000000000000000000000900460ff1615806130bf575081155b156130c957505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061310f90700100000000000000000000000000000000900463ffffffff16426145c5565b905080156131cf5781831115613151576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461318b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612d7b565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156132865773ffffffffffffffffffffffffffffffffffffffff841661322e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610797565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610797565b848310156133995760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906132ca90826145c5565b6132d4878a6145c5565b6132de91906146cb565b6132e8919061470d565b905073ffffffffffffffffffffffffffffffffffffffff8616613341576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610797565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610797565b6133a385846145c5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610f25565b60008183106134595781610f25565b5090919050565b6060824710156134f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610797565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161351b9190614748565b60006040518083038185875af1925050503d8060008114613558576040519150601f19603f3d011682016040523d82523d6000602084013e61355d565b606091505b509150915061356e87838387613579565b979650505050505050565b6060831561360f5782516000036136085773ffffffffffffffffffffffffffffffffffffffff85163b613608576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610797565b5081612d9d565b612d9d83838151156136245781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610797919061378e565b50805461366490613d11565b6000825580601f10613674575050565b601f016020900490600052602060002090810190611a4691905b808211156136a2576000815560010161368e565b5090565b6000602082840312156136b857600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f2557600080fd5b803567ffffffffffffffff8116811461370057600080fd5b919050565b60006020828403121561371757600080fd5b610f25826136e8565b60005b8381101561373b578181015183820152602001613723565b50506000910152565b6000815180845261375c816020860160208601613720565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f256020830184613744565b6000602082840312156137b357600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a4657600080fd5b8035613700816137ba565b6000602082840312156137f957600080fd5b8135610f25816137ba565b60006020828403121561381657600080fd5b813567ffffffffffffffff81111561382d57600080fd5b82016101008185031215610f2557600080fd5b60008083601f84011261385257600080fd5b50813567ffffffffffffffff81111561386a57600080fd5b6020830191508360208260051b850101111561388557600080fd5b9250929050565b600080600080604085870312156138a257600080fd5b843567ffffffffffffffff808211156138ba57600080fd5b6138c688838901613840565b909650945060208701359150808211156138df57600080fd5b506138ec87828801613840565b95989497509550505050565b6000806040838503121561390b57600080fd5b8235613916816137ba565b946020939093013593505050565b60008060006040848603121561393957600080fd5b613942846136e8565b9250602084013567ffffffffffffffff8082111561395f57600080fd5b818601915086601f83011261397357600080fd5b81358181111561398257600080fd5b87602082850101111561399457600080fd5b6020830194508093505050509250925092565b600080604083850312156139ba57600080fd5b6139c3836136e8565b915060208301356139d3816137ba565b809150509250929050565b6000602082840312156139f057600080fd5b813567ffffffffffffffff811115613a0757600080fd5b820160a08185031215610f2557600080fd5b602081526000825160406020840152613a356060840182613744565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613a708282613744565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ac757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613a95565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ac757835167ffffffffffffffff1683529284019291840191600101613aef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613b6857613b68613b15565b60405290565b60405160c0810167ffffffffffffffff81118282101715613b6857613b68613b15565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bd857613bd8613b15565b604052919050565b8015158114611a4657600080fd5b803561370081613be0565b80356fffffffffffffffffffffffffffffffff8116811461370057600080fd5b600060608284031215613c2b57600080fd5b6040516060810181811067ffffffffffffffff82111715613c4e57613c4e613b15565b6040529050808235613c5f81613be0565b8152613c6d60208401613bf9565b6020820152613c7e60408401613bf9565b60408201525092915050565b600080600060e08486031215613c9f57600080fd5b613ca8846136e8565b9250613cb78560208601613c19565b9150613cc68560808601613c19565b90509250925092565b60008060208385031215613ce257600080fd5b823567ffffffffffffffff811115613cf957600080fd5b613d0585828601613840565b90969095509350505050565b600181811c90821680613d2557607f821691505b602082108103613d5e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613d7657600080fd5b5051919050565b600067ffffffffffffffff821115613d9757613d97613b15565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613dd457600080fd5b8135613de7613de282613d7d565b613b91565b818152846020838601011115613dfc57600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613e2c57600080fd5b613e34613b44565b823567ffffffffffffffff80821115613e4c57600080fd5b613e5836838701613dc3565b8352613e66602086016136e8565b6020840152613e77604086016137dc565b604084015260608501356060840152613e92608086016137dc565b608084015260a0850135915080821115613eab57600080fd5b613eb736838701613dc3565b60a084015260c0850135915080821115613ed057600080fd5b613edc36838701613dc3565b60c084015260e0850135915080821115613ef557600080fd5b50613f0236828601613dc3565b60e08301525092915050565b601f82111561148e576000816000526020600020601f850160051c81016020861015613f375750805b601f850160051c820191505b81811015610b4d57828155600101613f43565b67ffffffffffffffff831115613f6e57613f6e613b15565b613f8283613f7c8354613d11565b83613f0e565b6000601f841160018114613fd45760008515613f9e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611ec9565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140235786850135825560209485019460019092019101614003565b508682101561405e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006140836040830186613744565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b6000602082840312156140e657600080fd5b8151610f2581613be0565b600060a0823603121561410357600080fd5b60405160a0810167ffffffffffffffff828210818311171561412757614127613b15565b81604052843591508082111561413c57600080fd5b5061414936828601613dc3565b825250614158602084016136e8565b6020820152604083013561416b816137ba565b6040820152606083810135908201526080830135614188816137ba565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126141f657600080fd5b9190910192915050565b6000610140823603121561421357600080fd5b61421b613b6e565b614224836136e8565b815261423260208401613bee565b6020820152604083013567ffffffffffffffff8082111561425257600080fd5b61425e36838701613dc3565b6040840152606085013591508082111561427757600080fd5b5061428436828601613dc3565b6060830152506142973660808501613c19565b60808201526142a93660e08501613c19565b60a082015292915050565b815167ffffffffffffffff8111156142ce576142ce613b15565b6142e2816142dc8454613d11565b84613f0e565b602080601f83116001811461433557600084156142ff5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610b4d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561438257888601518255948401946001909101908401614363565b50858210156143be57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526143f281840187613744565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506144309050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613a70565b60a08152600061447a60a0830187613744565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a0602082015260006144f760a0830186613744565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561453a57600080fd5b815167ffffffffffffffff81111561455157600080fd5b8201601f8101841361456257600080fd5b8051614570613de282613d7d565b81815285602083850101111561458557600080fd5b613a70826020830160208601613720565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561069257610692614596565b67ffffffffffffffff8416815260e0810161462460208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612d9d565b6060810161069282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156146a957600080fd5b8151610f25816137ba565b808202811582820484141761069257610692614596565b8082018082111561069257610692614596565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614743577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082516141f681846020870161372056fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e302d646576a164736f6c6343000818000a", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004f0a38038062004f0a83398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508181146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516147896200078160003960008181610545015261191b0152600081816105f201528181611f550152612b110152600081816105cc01528181611ce801526122080152600081816102ad01528181610302015281816107d0015281816108a20152818161097c015281816119dd01528181611c08015281816121280152818161230e01528181612aa70152612cfc01526147896000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e13146105f0578063eb521a4c14610616578063f2fde38b1461062957600080fd5b8063db6327dc146105b7578063dc0bd971146105ca57600080fd5b8063c0d7865514610569578063c4bffe2b1461057c578063c75eea9c14610591578063cf7401f3146105a457600080fd5b8063a8d87a3b11610114578063b0f479a1116100f9578063b0f479a114610512578063b794658014610530578063bb98546b1461054357600080fd5b8063a8d87a3b14610490578063af58d59f146104a357600080fd5b80638da5cb5b1461042a5780639766b932146104485780639a4575b91461045b578063a7cd63b71461047b57600080fd5b806354c8a4f3116101d857806378a010b2116101a75780637d54534e1161018c5780637d54534e146103f157806383826b2b146104045780638926f54f1461041757600080fd5b806378a010b2146103d657806379ba5097146103e957600080fd5b806354c8a4f31461037f57806366320087146103925780636cfd1553146103a55780636d3d1a58146103b857600080fd5b806321df0da71161021457806321df0da7146102ab578063240028e8146102f2578063390775371461033f578063432a6ba31461036157600080fd5b806301ffc9a7146102465780630a2fd4931461026e5780630a861f2a1461028e578063181f5a77146102a3575b600080fd5b6102596102543660046136a6565b61063c565b60405190151581526020015b60405180910390f35b61028161027c366004613705565b610698565b604051610265919061378e565b6102a161029c3660046137a1565b610748565b005b6102816108f9565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102596103003660046137e7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61035261034d366004613804565b610915565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a161038d36600461388c565b610a4e565b6102a16103a03660046138f8565b610ac9565b6102a16103b33660046137e7565b610b55565b60085473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16103e4366004613924565b610ba4565b6102a1610d13565b6102a16103ff3660046137e7565b610e10565b6102596104123660046139a7565b610e5f565b610259610425366004613705565b610f2c565b60005473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16104563660046137e7565b610f43565b61046e6104693660046139de565b610fd2565b6040516102659190613a19565b61048361109b565b6040516102659190613a79565b6102cd61049e366004613705565b503090565b6104b66104b1366004613705565b6110ac565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102cd565b61028161053e366004613705565b611181565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16105773660046137e7565b6111ac565b610584611280565b6040516102659190613ad3565b6104b661059f366004613705565b611338565b6102a16105b2366004613c8a565b61140a565b6102a16105c5366004613ccf565b611493565b7f00000000000000000000000000000000000000000000000000000000000000006102cd565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16106243660046137a1565b611919565b6102a16106373660046137e7565b611a35565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d40566000000000000000000000000000000000000000000000000000000001480610692575061069282611a49565b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106c390613d11565b80601f01602080910402602001604051908101604052809291908181526020018280546106ef90613d11565b801561073c5780601f106107115761010080835404028352916020019161073c565b820191906000526020600020905b81548152906001019060200180831161071f57829003601f168201915b50505050509050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146107a0576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190613d64565b1015610888576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108c973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611b2d565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b60405180606001604052806022815260200161475b6022913981565b60408051602081019091526000815261093561093083613e19565b611c01565b60095473ffffffffffffffffffffffffffffffffffffffff166109ac576109a761096560608401604085016137e7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611b2d565b6109bd565b6109bd6109b883613e19565b611e32565b6109cd60608301604084016137e7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f528460600135604051610a2f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a56611ed0565b610ac384848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f5392505050565b50505050565b610ad1611ed0565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610b3957600080fd5b505af1158015610b4d573d6000803e3d6000fd5b505050505050565b610b5d611ed0565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610bac611ed0565b610bb583610f2c565b610bf7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b67ffffffffffffffff831660009081526007602052604081206004018054610c1e90613d11565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4a90613d11565b8015610c975780601f10610c6c57610100808354040283529160200191610c97565b820191906000526020600020905b815481529060010190602001808311610c7a57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cc6838583613f56565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d0593929190614070565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610797565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e18611ed0565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610f255750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610f01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2591906140d4565b9392505050565b6000610692600567ffffffffffffffff8416612109565b610f4b611ed0565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610ff7610ff2836140f1565b612121565b60095473ffffffffffffffffffffffffffffffffffffffff161561102657611026611021836140f1565b6122eb565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a2604051806040016040528061108084602001602081019061053e9190613705565b81526040805160208181019092526000815291015292915050565b60606110a76002612405565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261069290612412565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106c390613d11565b6111b4611ed0565b73ffffffffffffffffffffffffffffffffffffffff8116611201576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610fc6565b6060600061128e6005612405565b90506000815167ffffffffffffffff8111156112ac576112ac613b15565b6040519080825280602002602001820160405280156112d5578160200160208202803683370190505b50905060005b8251811015611331578281815181106112f6576112f6614193565b602002602001015182828151811061131057611310614193565b67ffffffffffffffff909216602092830291909101909101526001016112db565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261069290612412565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061144a575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611483576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b61148e8383836124c4565b505050565b61149b611ed0565b60005b8181101561148e5760008383838181106114ba576114ba614193565b90506020028101906114cc91906141c2565b6114d590614200565b90506114ea81608001518260200151156125ae565b6114fd8160a001518260200151156125ae565b8060200151156117f957805161151f9060059067ffffffffffffffff166126e7565b6115645780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b60408101515115806115795750606081015151155b156115b0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061179190826142b4565b50606082015160058201906117a690826142b4565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506117ec94939291906143ce565b60405180910390a1611910565b80516118119060059067ffffffffffffffff166126f3565b6118565780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118bf6004830182613658565b6118cd600583016000613658565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161149e565b7f0000000000000000000000000000000000000000000000000000000000000000611970576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff1633146119c3576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b611a0573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846126ff565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611a3d611ed0565b611a468161275d565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611adc57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261148e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612852565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611c965760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6891906140d4565b15611d9f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dac816020015161295e565b6000611dbb8260200151610698565b9050805160001480611ddf575080805190602001208260a001518051906020012014155b15611e1c578160a001516040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610797919061378e565b611e2e82602001518360600151612a84565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611e9b9490939291600401614467565b600060405180830381600087803b158015611eb557600080fd5b505af1158015611ec9573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611f51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610797565b565b7f0000000000000000000000000000000000000000000000000000000000000000611faa576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612040576000838281518110611fca57611fca614193565b60200260200101519050611fe8816002612acb90919063ffffffff16565b156120375760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611fad565b5060005b815181101561148e57600082828151811061206157612061614193565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120a55750612101565b6120b0600282612aed565b156120ff5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612044565b60008181526001830160205260408120541515610f25565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121b65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612264573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228891906140d4565b156122bf576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122cc8160400151612b0f565b6122d98160200151612b8e565b611a4681602001518260600151612cdc565b60095460608201516123389173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611b2d565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909516946396875445946123a0949392916004016144c8565b6000604051808303816000875af11580156123bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e2e9190810190614528565b60606000610f2583612d20565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526124a082606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261248491906145c5565b85608001516fffffffffffffffffffffffffffffffff16612d7b565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6124cd83610f2c565b61250f576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b61251a8260006125ae565b67ffffffffffffffff8316600090815260076020526040902061253d9083612da5565b6125488160006125ae565b67ffffffffffffffff8316600090815260076020526040902061256e9060020182612da5565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516125a1939291906145d8565b60405180910390a1505050565b8151156126755781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612604575060408201516fffffffffffffffffffffffffffffffff16155b1561263d57816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610797919061465b565b8015611e2e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806126ae575060208201516fffffffffffffffffffffffffffffffff1615155b15611e2e57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610797919061465b565b6000610f258383612f47565b6000610f258383612f96565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ac39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611b7f565b3373ffffffffffffffffffffffffffffffffffffffff8216036127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610797565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006128b4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130899092919063ffffffff16565b80519091501561148e57808060200190518101906128d291906140d4565b61148e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610797565b61296781610f2c565b6129a9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612a28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4c91906140d4565b611a46576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e2e90600201827f0000000000000000000000000000000000000000000000000000000000000000613098565b6000610f258373ffffffffffffffffffffffffffffffffffffffff8416612f96565b6000610f258373ffffffffffffffffffffffffffffffffffffffff8416612f47565b7f000000000000000000000000000000000000000000000000000000000000000015611a4657612b4060028261341b565b611a46576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610797565b612b9781610f2c565b612bd9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c769190614697565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a46576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e2e90827f0000000000000000000000000000000000000000000000000000000000000000613098565b60608160000180548060200260200160405190810160405280929190818152602001828054801561073c57602002820191906000526020600020905b815481526020019060010190808311612d5c5750505050509050919050565b6000612d9a85612d8b84866146b4565b612d9590876146cb565b61344a565b90505b949350505050565b8154600090612dce90700100000000000000000000000000000000900463ffffffff16426145c5565b90508015612e705760018301548354612e16916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612d7b565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612e96916fffffffffffffffffffffffffffffffff908116911661344a565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906125a190849061465b565b6000818152600183016020526040812054612f8e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610692565b506000610692565b6000818152600183016020526040812054801561307f576000612fba6001836145c5565b8554909150600090612fce906001906145c5565b9050818114613033576000866000018281548110612fee57612fee614193565b906000526020600020015490508087600001848154811061301157613011614193565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613044576130446146de565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610692565b6000915050610692565b6060612d9d8484600085613460565b825474010000000000000000000000000000000000000000900460ff1615806130bf575081155b156130c957505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061310f90700100000000000000000000000000000000900463ffffffff16426145c5565b905080156131cf5781831115613151576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461318b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612d7b565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156132865773ffffffffffffffffffffffffffffffffffffffff841661322e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610797565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610797565b848310156133995760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906132ca90826145c5565b6132d4878a6145c5565b6132de91906146cb565b6132e8919061470d565b905073ffffffffffffffffffffffffffffffffffffffff8616613341576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610797565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610797565b6133a385846145c5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610f25565b60008183106134595781610f25565b5090919050565b6060824710156134f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610797565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161351b9190614748565b60006040518083038185875af1925050503d8060008114613558576040519150601f19603f3d011682016040523d82523d6000602084013e61355d565b606091505b509150915061356e87838387613579565b979650505050505050565b6060831561360f5782516000036136085773ffffffffffffffffffffffffffffffffffffffff85163b613608576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610797565b5081612d9d565b612d9d83838151156136245781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610797919061378e565b50805461366490613d11565b6000825580601f10613674575050565b601f016020900490600052602060002090810190611a4691905b808211156136a2576000815560010161368e565b5090565b6000602082840312156136b857600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f2557600080fd5b803567ffffffffffffffff8116811461370057600080fd5b919050565b60006020828403121561371757600080fd5b610f25826136e8565b60005b8381101561373b578181015183820152602001613723565b50506000910152565b6000815180845261375c816020860160208601613720565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f256020830184613744565b6000602082840312156137b357600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a4657600080fd5b8035613700816137ba565b6000602082840312156137f957600080fd5b8135610f25816137ba565b60006020828403121561381657600080fd5b813567ffffffffffffffff81111561382d57600080fd5b82016101008185031215610f2557600080fd5b60008083601f84011261385257600080fd5b50813567ffffffffffffffff81111561386a57600080fd5b6020830191508360208260051b850101111561388557600080fd5b9250929050565b600080600080604085870312156138a257600080fd5b843567ffffffffffffffff808211156138ba57600080fd5b6138c688838901613840565b909650945060208701359150808211156138df57600080fd5b506138ec87828801613840565b95989497509550505050565b6000806040838503121561390b57600080fd5b8235613916816137ba565b946020939093013593505050565b60008060006040848603121561393957600080fd5b613942846136e8565b9250602084013567ffffffffffffffff8082111561395f57600080fd5b818601915086601f83011261397357600080fd5b81358181111561398257600080fd5b87602082850101111561399457600080fd5b6020830194508093505050509250925092565b600080604083850312156139ba57600080fd5b6139c3836136e8565b915060208301356139d3816137ba565b809150509250929050565b6000602082840312156139f057600080fd5b813567ffffffffffffffff811115613a0757600080fd5b820160a08185031215610f2557600080fd5b602081526000825160406020840152613a356060840182613744565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613a708282613744565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ac757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613a95565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ac757835167ffffffffffffffff1683529284019291840191600101613aef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613b6857613b68613b15565b60405290565b60405160c0810167ffffffffffffffff81118282101715613b6857613b68613b15565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bd857613bd8613b15565b604052919050565b8015158114611a4657600080fd5b803561370081613be0565b80356fffffffffffffffffffffffffffffffff8116811461370057600080fd5b600060608284031215613c2b57600080fd5b6040516060810181811067ffffffffffffffff82111715613c4e57613c4e613b15565b6040529050808235613c5f81613be0565b8152613c6d60208401613bf9565b6020820152613c7e60408401613bf9565b60408201525092915050565b600080600060e08486031215613c9f57600080fd5b613ca8846136e8565b9250613cb78560208601613c19565b9150613cc68560808601613c19565b90509250925092565b60008060208385031215613ce257600080fd5b823567ffffffffffffffff811115613cf957600080fd5b613d0585828601613840565b90969095509350505050565b600181811c90821680613d2557607f821691505b602082108103613d5e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613d7657600080fd5b5051919050565b600067ffffffffffffffff821115613d9757613d97613b15565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613dd457600080fd5b8135613de7613de282613d7d565b613b91565b818152846020838601011115613dfc57600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613e2c57600080fd5b613e34613b44565b823567ffffffffffffffff80821115613e4c57600080fd5b613e5836838701613dc3565b8352613e66602086016136e8565b6020840152613e77604086016137dc565b604084015260608501356060840152613e92608086016137dc565b608084015260a0850135915080821115613eab57600080fd5b613eb736838701613dc3565b60a084015260c0850135915080821115613ed057600080fd5b613edc36838701613dc3565b60c084015260e0850135915080821115613ef557600080fd5b50613f0236828601613dc3565b60e08301525092915050565b601f82111561148e576000816000526020600020601f850160051c81016020861015613f375750805b601f850160051c820191505b81811015610b4d57828155600101613f43565b67ffffffffffffffff831115613f6e57613f6e613b15565b613f8283613f7c8354613d11565b83613f0e565b6000601f841160018114613fd45760008515613f9e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611ec9565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140235786850135825560209485019460019092019101614003565b508682101561405e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006140836040830186613744565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b6000602082840312156140e657600080fd5b8151610f2581613be0565b600060a0823603121561410357600080fd5b60405160a0810167ffffffffffffffff828210818311171561412757614127613b15565b81604052843591508082111561413c57600080fd5b5061414936828601613dc3565b825250614158602084016136e8565b6020820152604083013561416b816137ba565b6040820152606083810135908201526080830135614188816137ba565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126141f657600080fd5b9190910192915050565b6000610140823603121561421357600080fd5b61421b613b6e565b614224836136e8565b815261423260208401613bee565b6020820152604083013567ffffffffffffffff8082111561425257600080fd5b61425e36838701613dc3565b6040840152606085013591508082111561427757600080fd5b5061428436828601613dc3565b6060830152506142973660808501613c19565b60808201526142a93660e08501613c19565b60a082015292915050565b815167ffffffffffffffff8111156142ce576142ce613b15565b6142e2816142dc8454613d11565b84613f0e565b602080601f83116001811461433557600084156142ff5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610b4d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561438257888601518255948401946001909101908401614363565b50858210156143be57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526143f281840187613744565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506144309050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613a70565b60a08152600061447a60a0830187613744565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a0602082015260006144f760a0830186613744565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561453a57600080fd5b815167ffffffffffffffff81111561455157600080fd5b8201601f8101841361456257600080fd5b8051614570613de282613d7d565b81815285602083850101111561458557600080fd5b613a70826020830160208601613720565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561069257610692614596565b67ffffffffffffffff8416815260e0810161462460208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612d9d565b6060810161069282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156146a957600080fd5b8151610f25816137ba565b808202811582820484141761069257610692614596565b8082018082111561069257610692614596565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614743577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082516141f681846020870161372056fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e30a164736f6c6343000818000a", } var LockReleaseTokenPoolAndProxyABI = LockReleaseTokenPoolAndProxyMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/registry_module_owner_custom/registry_module_owner_custom.go b/core/gethwrappers/ccip/generated/registry_module_owner_custom/registry_module_owner_custom.go index bab8100d6f..121135075d 100644 --- a/core/gethwrappers/ccip/generated/registry_module_owner_custom/registry_module_owner_custom.go +++ b/core/gethwrappers/ccip/generated/registry_module_owner_custom/registry_module_owner_custom.go @@ -32,7 +32,7 @@ var ( var RegistryModuleOwnerCustomMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AddressZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"CanOnlySelfRegister\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"}],\"name\":\"AdministratorRegistered\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"registerAdminViaGetCCIPAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"registerAdminViaOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a060405234801561001057600080fd5b5060405161048938038061048983398101604081905261002f91610067565b6001600160a01b03811661005657604051639fabe1c160e01b815260040160405180910390fd5b6001600160a01b0316608052610097565b60006020828403121561007957600080fd5b81516001600160a01b038116811461009057600080fd5b9392505050565b6080516103d76100b2600039600061023201526103d76000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063181f5a771461004657806396ea2f7a14610064578063ff12c35414610079575b600080fd5b61004e61008c565b60405161005b91906102d7565b60405180910390f35b610077610072366004610366565b6100a8565b005b610077610087366004610366565b610123565b6040518060600160405280602381526020016103a86023913981565b610120818273ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061011b919061038a565b610172565b50565b610120818273ffffffffffffffffffffffffffffffffffffffff16638fd6a6ac6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100f7573d6000803e3d6000fd5b73ffffffffffffffffffffffffffffffffffffffff811633146101e5576040517fc454d18200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80831660048301528316602482015260440160405180910390fd5b6040517fe677ae3700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015282811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063e677ae3790604401600060405180830381600087803b15801561027657600080fd5b505af115801561028a573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff8085169350851691507f09590fb70af4b833346363965e043a9339e8c7d378b8a2b903c75c277faec4f990600090a35050565b60006020808352835180602085015260005b81811015610305578581018301518582016040015282016102e9565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461012057600080fd5b60006020828403121561037857600080fd5b813561038381610344565b9392505050565b60006020828403121561039c57600080fd5b81516103838161034456fe52656769737472794d6f64756c654f776e6572437573746f6d20312e352e302d646576a164736f6c6343000818000a", + Bin: "0x60a060405234801561001057600080fd5b5060405161047e38038061047e83398101604081905261002f91610067565b6001600160a01b03811661005657604051639fabe1c160e01b815260040160405180910390fd5b6001600160a01b0316608052610097565b60006020828403121561007957600080fd5b81516001600160a01b038116811461009057600080fd5b9392505050565b6080516103cc6100b2600039600061024a01526103cc6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063181f5a771461004657806396ea2f7a14610098578063ff12c354146100ad575b600080fd5b6100826040518060400160405280601f81526020017f52656769737472794d6f64756c654f776e6572437573746f6d20312e352e300081525081565b60405161008f91906102ef565b60405180910390f35b6100ab6100a636600461037e565b6100c0565b005b6100ab6100bb36600461037e565b61013b565b610138818273ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561010f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061013391906103a2565b61018a565b50565b610138818273ffffffffffffffffffffffffffffffffffffffff16638fd6a6ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561010f573d6000803e3d6000fd5b73ffffffffffffffffffffffffffffffffffffffff811633146101fd576040517fc454d18200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80831660048301528316602482015260440160405180910390fd5b6040517fe677ae3700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015282811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063e677ae3790604401600060405180830381600087803b15801561028e57600080fd5b505af11580156102a2573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff8085169350851691507f09590fb70af4b833346363965e043a9339e8c7d378b8a2b903c75c277faec4f990600090a35050565b60006020808352835180602085015260005b8181101561031d57858101830151858201604001528201610301565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461013857600080fd5b60006020828403121561039057600080fd5b813561039b8161035c565b9392505050565b6000602082840312156103b457600080fd5b815161039b8161035c56fea164736f6c6343000818000a", } var RegistryModuleOwnerCustomABI = RegistryModuleOwnerCustomMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/token_admin_registry/token_admin_registry.go b/core/gethwrappers/ccip/generated/token_admin_registry/token_admin_registry.go index 189b4b600b..a691fb6b85 100644 --- a/core/gethwrappers/ccip/generated/token_admin_registry/token_admin_registry.go +++ b/core/gethwrappers/ccip/generated/token_admin_registry/token_admin_registry.go @@ -37,8 +37,8 @@ type TokenAdminRegistryTokenConfig struct { } var TokenAdminRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"AlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidTokenPoolToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"OnlyAdministrator\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"OnlyPendingAdministrator\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"OnlyRegistryModuleOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"currentAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdministratorTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdministratorTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"disabled\",\"type\":\"bool\"}],\"name\":\"DisableReRegistrationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousPool\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"PoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"RegistryModuleAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"RegistryModuleRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"RemovedAdministrator\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"acceptAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"addRegistryModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"startIndex\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxCount\",\"type\":\"uint64\"}],\"name\":\"getAllConfiguredTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getPools\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pendingAdministrator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenPool\",\"type\":\"address\"}],\"internalType\":\"structTokenAdminRegistry.TokenConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"}],\"name\":\"isAdministrator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"isRegistryModule\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"}],\"name\":\"proposeAdministrator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"removeRegistryModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"setPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611449806101576000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80637d3f255211610097578063cb67e3b111610066578063cb67e3b1146102bc578063ddadfa8e14610374578063e677ae3714610387578063f2fde38b1461039a57600080fd5b80637d3f2552146101e05780638da5cb5b14610203578063bbe4f6db14610242578063c1af6e031461027f57600080fd5b80634e847fc7116100d35780634e847fc7146101925780635e63547a146101a557806372d64a81146101c557806379ba5097146101d857600080fd5b806310cbcf1814610105578063156194da1461011a578063181f5a771461012d5780633dc457721461017f575b600080fd5b61011861011336600461116c565b6103ad565b005b61011861012836600461116c565b61040a565b6101696040518060400160405280601c81526020017f546f6b656e41646d696e526567697374727920312e352e302d6465760000000081525081565b6040516101769190611187565b60405180910390f35b61011861018d36600461116c565b61050f565b6101186101a03660046111f4565b610573565b6101b86101b3366004611227565b6107d3565b604051610176919061129c565b6101b86101d336600461130e565b6108cc565b6101186109e2565b6101f36101ee36600461116c565b610adf565b6040519015158152602001610176565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610176565b61021d61025036600461116c565b73ffffffffffffffffffffffffffffffffffffffff908116600090815260026020819052604090912001541690565b6101f361028d3660046111f4565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260026020526040902054821691161490565b6103356102ca36600461116c565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff948516815260028084529084902084519283018552805486168352600181015486169383019390935291909101549092169082015290565b60408051825173ffffffffffffffffffffffffffffffffffffffff90811682526020808501518216908301529282015190921690820152606001610176565b6101186103823660046111f4565b610aec565b6101186103953660046111f4565b610bf6565b6101186103a836600461116c565b610dbe565b6103b5610dcf565b6103c0600582610e52565b156104075760405173ffffffffffffffffffffffffffffffffffffffff8216907f93eaa26dcb9275e56bacb1d33fdbf402262da6f0f4baf2a6e2cd154b73f387f890600090a25b50565b73ffffffffffffffffffffffffffffffffffffffff808216600090815260026020526040902060018101549091163314610493576040517f3edffe7500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff831660248201526044015b60405180910390fd5b8054337fffffffffffffffffffffffff00000000000000000000000000000000000000009182168117835560018301805490921690915560405173ffffffffffffffffffffffffffffffffffffffff8416907f399b55200f7f639a63d76efe3dcfa9156ce367058d6b673041b84a628885f5a790600090a35050565b610517610dcf565b610522600582610e7b565b156104075760405173ffffffffffffffffffffffffffffffffffffffff821681527f3cabf004338366bfeaeb610ad827cb58d16b588017c509501f2c97c83caae7b29060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff80831660009081526002602052604090205483911633146105f3576040517fed5d85b500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161048a565b73ffffffffffffffffffffffffffffffffffffffff8216158015906106a557506040517f240028e800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283169063240028e890602401602060405180830381865afa15801561067f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a39190611338565b155b156106f4576040517f962b60e600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240161048a565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020819052604090912090810180548584167fffffffffffffffffffffffff0000000000000000000000000000000000000000821681179092559192919091169081146107cc578373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f754449ec3aff3bd528bfce43ae9319c4a381b67fcd1d20097b3b24dacaecc35d60405160405180910390a45b5050505050565b606060008267ffffffffffffffff8111156107f0576107f061135a565b604051908082528060200260200182016040528015610819578160200160208202803683370190505b50905060005b838110156108c2576002600086868481811061083d5761083d611389565b9050602002016020810190610852919061116c565b73ffffffffffffffffffffffffffffffffffffffff9081168252602082019290925260400160002060020154835191169083908390811061089557610895611389565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015260010161081f565b5090505b92915050565b606060006108da6003610e9d565b9050808467ffffffffffffffff16106108f357506108c6565b67ffffffffffffffff80841690829061090e908716836113e7565b111561092b5761092867ffffffffffffffff8616836113fa565b90505b8067ffffffffffffffff8111156109445761094461135a565b60405190808252806020026020018201604052801561096d578160200160208202803683370190505b50925060005b818110156109d95761099a6109928267ffffffffffffffff89166113e7565b600390610ea7565b8482815181106109ac576109ac611389565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101610973565b50505092915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161048a565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006108c6600583610eb3565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020548391163314610b6c576040517fed5d85b500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161048a565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152600260205260408082206001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001695881695861790559051909392339290917fc54c3051ff16e63bb9203214432372aca006c589e3653619b577a3265675b7169190a450505050565b610bff33610adf565b158015610c24575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610c5d576040517f51ca1ec300000000000000000000000000000000000000000000000000000000815233600482015260240161048a565b73ffffffffffffffffffffffffffffffffffffffff8116610caa576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020805490911615610d24576040517f45ed80e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240161048a565b6001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055610d71600384610e7b565b5060405173ffffffffffffffffffffffffffffffffffffffff808416916000918616907fc54c3051ff16e63bb9203214432372aca006c589e3653619b577a3265675b716908390a4505050565b610dc6610dcf565b61040781610ee2565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161048a565b565b6000610e748373ffffffffffffffffffffffffffffffffffffffff8416610fd7565b9392505050565b6000610e748373ffffffffffffffffffffffffffffffffffffffff84166110ca565b60006108c6825490565b6000610e748383611119565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610e74565b3373ffffffffffffffffffffffffffffffffffffffff821603610f61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161048a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081815260018301602052604081205480156110c0576000610ffb6001836113fa565b855490915060009061100f906001906113fa565b905081811461107457600086600001828154811061102f5761102f611389565b906000526020600020015490508087600001848154811061105257611052611389565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806110855761108561140d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108c6565b60009150506108c6565b6000818152600183016020526040812054611111575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108c6565b5060006108c6565b600082600001828154811061113057611130611389565b9060005260206000200154905092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116757600080fd5b919050565b60006020828403121561117e57600080fd5b610e7482611143565b60006020808352835180602085015260005b818110156111b557858101830151858201604001528201611199565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000806040838503121561120757600080fd5b61121083611143565b915061121e60208401611143565b90509250929050565b6000806020838503121561123a57600080fd5b823567ffffffffffffffff8082111561125257600080fd5b818501915085601f83011261126657600080fd5b81358181111561127557600080fd5b8660208260051b850101111561128a57600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b818110156112ea57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016112b8565b50909695505050505050565b803567ffffffffffffffff8116811461116757600080fd5b6000806040838503121561132157600080fd5b61132a836112f6565b915061121e602084016112f6565b60006020828403121561134a57600080fd5b81518015158114610e7457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156108c6576108c66113b8565b818103818111156108c6576108c66113b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"AlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidTokenPoolToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"OnlyAdministrator\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"OnlyPendingAdministrator\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"OnlyRegistryModuleOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"currentAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdministratorTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdministratorTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousPool\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"PoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"RegistryModuleAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"RegistryModuleRemoved\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"acceptAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"addRegistryModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"startIndex\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxCount\",\"type\":\"uint64\"}],\"name\":\"getAllConfiguredTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getPools\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pendingAdministrator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenPool\",\"type\":\"address\"}],\"internalType\":\"structTokenAdminRegistry.TokenConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"}],\"name\":\"isAdministrator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"isRegistryModule\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"}],\"name\":\"proposeAdministrator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"removeRegistryModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"setPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611449806101576000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80637d3f255211610097578063cb67e3b111610066578063cb67e3b1146102bc578063ddadfa8e14610374578063e677ae3714610387578063f2fde38b1461039a57600080fd5b80637d3f2552146101e05780638da5cb5b14610203578063bbe4f6db14610242578063c1af6e031461027f57600080fd5b80634e847fc7116100d35780634e847fc7146101925780635e63547a146101a557806372d64a81146101c557806379ba5097146101d857600080fd5b806310cbcf1814610105578063156194da1461011a578063181f5a771461012d5780633dc457721461017f575b600080fd5b61011861011336600461116c565b6103ad565b005b61011861012836600461116c565b61040a565b6101696040518060400160405280601881526020017f546f6b656e41646d696e526567697374727920312e352e30000000000000000081525081565b6040516101769190611187565b60405180910390f35b61011861018d36600461116c565b61050f565b6101186101a03660046111f4565b610573565b6101b86101b3366004611227565b6107d3565b604051610176919061129c565b6101b86101d336600461130e565b6108cc565b6101186109e2565b6101f36101ee36600461116c565b610adf565b6040519015158152602001610176565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610176565b61021d61025036600461116c565b73ffffffffffffffffffffffffffffffffffffffff908116600090815260026020819052604090912001541690565b6101f361028d3660046111f4565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260026020526040902054821691161490565b6103356102ca36600461116c565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff948516815260028084529084902084519283018552805486168352600181015486169383019390935291909101549092169082015290565b60408051825173ffffffffffffffffffffffffffffffffffffffff90811682526020808501518216908301529282015190921690820152606001610176565b6101186103823660046111f4565b610aec565b6101186103953660046111f4565b610bf6565b6101186103a836600461116c565b610dbe565b6103b5610dcf565b6103c0600582610e52565b156104075760405173ffffffffffffffffffffffffffffffffffffffff8216907f93eaa26dcb9275e56bacb1d33fdbf402262da6f0f4baf2a6e2cd154b73f387f890600090a25b50565b73ffffffffffffffffffffffffffffffffffffffff808216600090815260026020526040902060018101549091163314610493576040517f3edffe7500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff831660248201526044015b60405180910390fd5b8054337fffffffffffffffffffffffff00000000000000000000000000000000000000009182168117835560018301805490921690915560405173ffffffffffffffffffffffffffffffffffffffff8416907f399b55200f7f639a63d76efe3dcfa9156ce367058d6b673041b84a628885f5a790600090a35050565b610517610dcf565b610522600582610e7b565b156104075760405173ffffffffffffffffffffffffffffffffffffffff821681527f3cabf004338366bfeaeb610ad827cb58d16b588017c509501f2c97c83caae7b29060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff80831660009081526002602052604090205483911633146105f3576040517fed5d85b500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161048a565b73ffffffffffffffffffffffffffffffffffffffff8216158015906106a557506040517f240028e800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283169063240028e890602401602060405180830381865afa15801561067f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a39190611338565b155b156106f4576040517f962b60e600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240161048a565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020819052604090912090810180548584167fffffffffffffffffffffffff0000000000000000000000000000000000000000821681179092559192919091169081146107cc578373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f754449ec3aff3bd528bfce43ae9319c4a381b67fcd1d20097b3b24dacaecc35d60405160405180910390a45b5050505050565b606060008267ffffffffffffffff8111156107f0576107f061135a565b604051908082528060200260200182016040528015610819578160200160208202803683370190505b50905060005b838110156108c2576002600086868481811061083d5761083d611389565b9050602002016020810190610852919061116c565b73ffffffffffffffffffffffffffffffffffffffff9081168252602082019290925260400160002060020154835191169083908390811061089557610895611389565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015260010161081f565b5090505b92915050565b606060006108da6003610e9d565b9050808467ffffffffffffffff16106108f357506108c6565b67ffffffffffffffff80841690829061090e908716836113e7565b111561092b5761092867ffffffffffffffff8616836113fa565b90505b8067ffffffffffffffff8111156109445761094461135a565b60405190808252806020026020018201604052801561096d578160200160208202803683370190505b50925060005b818110156109d95761099a6109928267ffffffffffffffff89166113e7565b600390610ea7565b8482815181106109ac576109ac611389565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101610973565b50505092915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161048a565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006108c6600583610eb3565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020548391163314610b6c576040517fed5d85b500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161048a565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152600260205260408082206001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001695881695861790559051909392339290917fc54c3051ff16e63bb9203214432372aca006c589e3653619b577a3265675b7169190a450505050565b610bff33610adf565b158015610c24575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610c5d576040517f51ca1ec300000000000000000000000000000000000000000000000000000000815233600482015260240161048a565b73ffffffffffffffffffffffffffffffffffffffff8116610caa576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020805490911615610d24576040517f45ed80e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240161048a565b6001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055610d71600384610e7b565b5060405173ffffffffffffffffffffffffffffffffffffffff808416916000918616907fc54c3051ff16e63bb9203214432372aca006c589e3653619b577a3265675b716908390a4505050565b610dc6610dcf565b61040781610ee2565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161048a565b565b6000610e748373ffffffffffffffffffffffffffffffffffffffff8416610fd7565b9392505050565b6000610e748373ffffffffffffffffffffffffffffffffffffffff84166110ca565b60006108c6825490565b6000610e748383611119565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610e74565b3373ffffffffffffffffffffffffffffffffffffffff821603610f61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161048a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081815260018301602052604081205480156110c0576000610ffb6001836113fa565b855490915060009061100f906001906113fa565b905081811461107457600086600001828154811061102f5761102f611389565b906000526020600020015490508087600001848154811061105257611052611389565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806110855761108561140d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108c6565b60009150506108c6565b6000818152600183016020526040812054611111575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108c6565b5060006108c6565b600082600001828154811061113057611130611389565b9060005260206000200154905092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116757600080fd5b919050565b60006020828403121561117e57600080fd5b610e7482611143565b60006020808352835180602085015260005b818110156111b557858101830151858201604001528201611199565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000806040838503121561120757600080fd5b61121083611143565b915061121e60208401611143565b90509250929050565b6000806020838503121561123a57600080fd5b823567ffffffffffffffff8082111561125257600080fd5b818501915085601f83011261126657600080fd5b81358181111561127557600080fd5b8660208260051b850101111561128a57600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b818110156112ea57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016112b8565b50909695505050505050565b803567ffffffffffffffff8116811461116757600080fd5b6000806040838503121561132157600080fd5b61132a836112f6565b915061121e602084016112f6565b60006020828403121561134a57600080fd5b81518015158114610e7457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156108c6576108c66113b8565b818103818111156108c6576108c66113b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var TokenAdminRegistryABI = TokenAdminRegistryMetaData.ABI @@ -730,134 +730,6 @@ func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParseAdministratorTransfe return event, nil } -type TokenAdminRegistryDisableReRegistrationSetIterator struct { - Event *TokenAdminRegistryDisableReRegistrationSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *TokenAdminRegistryDisableReRegistrationSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(TokenAdminRegistryDisableReRegistrationSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(TokenAdminRegistryDisableReRegistrationSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *TokenAdminRegistryDisableReRegistrationSetIterator) Error() error { - return it.fail -} - -func (it *TokenAdminRegistryDisableReRegistrationSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type TokenAdminRegistryDisableReRegistrationSet struct { - Token common.Address - Disabled bool - Raw types.Log -} - -func (_TokenAdminRegistry *TokenAdminRegistryFilterer) FilterDisableReRegistrationSet(opts *bind.FilterOpts, token []common.Address) (*TokenAdminRegistryDisableReRegistrationSetIterator, error) { - - var tokenRule []interface{} - for _, tokenItem := range token { - tokenRule = append(tokenRule, tokenItem) - } - - logs, sub, err := _TokenAdminRegistry.contract.FilterLogs(opts, "DisableReRegistrationSet", tokenRule) - if err != nil { - return nil, err - } - return &TokenAdminRegistryDisableReRegistrationSetIterator{contract: _TokenAdminRegistry.contract, event: "DisableReRegistrationSet", logs: logs, sub: sub}, nil -} - -func (_TokenAdminRegistry *TokenAdminRegistryFilterer) WatchDisableReRegistrationSet(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryDisableReRegistrationSet, token []common.Address) (event.Subscription, error) { - - var tokenRule []interface{} - for _, tokenItem := range token { - tokenRule = append(tokenRule, tokenItem) - } - - logs, sub, err := _TokenAdminRegistry.contract.WatchLogs(opts, "DisableReRegistrationSet", tokenRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(TokenAdminRegistryDisableReRegistrationSet) - if err := _TokenAdminRegistry.contract.UnpackLog(event, "DisableReRegistrationSet", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParseDisableReRegistrationSet(log types.Log) (*TokenAdminRegistryDisableReRegistrationSet, error) { - event := new(TokenAdminRegistryDisableReRegistrationSet) - if err := _TokenAdminRegistry.contract.UnpackLog(event, "DisableReRegistrationSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - type TokenAdminRegistryOwnershipTransferRequestedIterator struct { Event *TokenAdminRegistryOwnershipTransferRequested @@ -1519,131 +1391,12 @@ func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParseRegistryModuleRemove return event, nil } -type TokenAdminRegistryRemovedAdministratorIterator struct { - Event *TokenAdminRegistryRemovedAdministrator - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *TokenAdminRegistryRemovedAdministratorIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(TokenAdminRegistryRemovedAdministrator) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(TokenAdminRegistryRemovedAdministrator) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *TokenAdminRegistryRemovedAdministratorIterator) Error() error { - return it.fail -} - -func (it *TokenAdminRegistryRemovedAdministratorIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type TokenAdminRegistryRemovedAdministrator struct { - Token common.Address - Raw types.Log -} - -func (_TokenAdminRegistry *TokenAdminRegistryFilterer) FilterRemovedAdministrator(opts *bind.FilterOpts) (*TokenAdminRegistryRemovedAdministratorIterator, error) { - - logs, sub, err := _TokenAdminRegistry.contract.FilterLogs(opts, "RemovedAdministrator") - if err != nil { - return nil, err - } - return &TokenAdminRegistryRemovedAdministratorIterator{contract: _TokenAdminRegistry.contract, event: "RemovedAdministrator", logs: logs, sub: sub}, nil -} - -func (_TokenAdminRegistry *TokenAdminRegistryFilterer) WatchRemovedAdministrator(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryRemovedAdministrator) (event.Subscription, error) { - - logs, sub, err := _TokenAdminRegistry.contract.WatchLogs(opts, "RemovedAdministrator") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(TokenAdminRegistryRemovedAdministrator) - if err := _TokenAdminRegistry.contract.UnpackLog(event, "RemovedAdministrator", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_TokenAdminRegistry *TokenAdminRegistryFilterer) ParseRemovedAdministrator(log types.Log) (*TokenAdminRegistryRemovedAdministrator, error) { - event := new(TokenAdminRegistryRemovedAdministrator) - if err := _TokenAdminRegistry.contract.UnpackLog(event, "RemovedAdministrator", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - func (_TokenAdminRegistry *TokenAdminRegistry) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { case _TokenAdminRegistry.abi.Events["AdministratorTransferRequested"].ID: return _TokenAdminRegistry.ParseAdministratorTransferRequested(log) case _TokenAdminRegistry.abi.Events["AdministratorTransferred"].ID: return _TokenAdminRegistry.ParseAdministratorTransferred(log) - case _TokenAdminRegistry.abi.Events["DisableReRegistrationSet"].ID: - return _TokenAdminRegistry.ParseDisableReRegistrationSet(log) case _TokenAdminRegistry.abi.Events["OwnershipTransferRequested"].ID: return _TokenAdminRegistry.ParseOwnershipTransferRequested(log) case _TokenAdminRegistry.abi.Events["OwnershipTransferred"].ID: @@ -1654,8 +1407,6 @@ func (_TokenAdminRegistry *TokenAdminRegistry) ParseLog(log types.Log) (generate return _TokenAdminRegistry.ParseRegistryModuleAdded(log) case _TokenAdminRegistry.abi.Events["RegistryModuleRemoved"].ID: return _TokenAdminRegistry.ParseRegistryModuleRemoved(log) - case _TokenAdminRegistry.abi.Events["RemovedAdministrator"].ID: - return _TokenAdminRegistry.ParseRemovedAdministrator(log) default: return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) @@ -1670,10 +1421,6 @@ func (TokenAdminRegistryAdministratorTransferred) Topic() common.Hash { return common.HexToHash("0x399b55200f7f639a63d76efe3dcfa9156ce367058d6b673041b84a628885f5a7") } -func (TokenAdminRegistryDisableReRegistrationSet) Topic() common.Hash { - return common.HexToHash("0x4f1ce406d38233729d1052ad9f0c2b56bd742cd4fb59781573b51fa1f268a92e") -} - func (TokenAdminRegistryOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } @@ -1694,10 +1441,6 @@ func (TokenAdminRegistryRegistryModuleRemoved) Topic() common.Hash { return common.HexToHash("0x93eaa26dcb9275e56bacb1d33fdbf402262da6f0f4baf2a6e2cd154b73f387f8") } -func (TokenAdminRegistryRemovedAdministrator) Topic() common.Hash { - return common.HexToHash("0x7b309bf0232684e703b0a791653cc857835761a0365ccade0e2aa66ef02ca530") -} - func (_TokenAdminRegistry *TokenAdminRegistry) Address() common.Address { return _TokenAdminRegistry.address } @@ -1747,12 +1490,6 @@ type TokenAdminRegistryInterface interface { ParseAdministratorTransferred(log types.Log) (*TokenAdminRegistryAdministratorTransferred, error) - FilterDisableReRegistrationSet(opts *bind.FilterOpts, token []common.Address) (*TokenAdminRegistryDisableReRegistrationSetIterator, error) - - WatchDisableReRegistrationSet(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryDisableReRegistrationSet, token []common.Address) (event.Subscription, error) - - ParseDisableReRegistrationSet(log types.Log) (*TokenAdminRegistryDisableReRegistrationSet, error) - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenAdminRegistryOwnershipTransferRequestedIterator, error) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) @@ -1783,12 +1520,6 @@ type TokenAdminRegistryInterface interface { ParseRegistryModuleRemoved(log types.Log) (*TokenAdminRegistryRegistryModuleRemoved, error) - FilterRemovedAdministrator(opts *bind.FilterOpts) (*TokenAdminRegistryRemovedAdministratorIterator, error) - - WatchRemovedAdministrator(opts *bind.WatchOpts, sink chan<- *TokenAdminRegistryRemovedAdministrator) (event.Subscription, error) - - ParseRemovedAdministrator(log types.Log) (*TokenAdminRegistryRemovedAdministrator, error) - ParseLog(log types.Log) (generated.AbigenLog, error) Address() common.Address diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 9977ebf494..30645041a0 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,21 +1,21 @@ GETH_VERSION: 1.13.8 arm_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 763c7d81e782d7c286d4a5892aeebe71984a1f999a50a051c87f5b8f9c70cc26 arm_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 -burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 2ac7ec65a85f4e61299b05c7b8636bbd65c91639a919833b350995f2ca25d831 -burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 65bc164ed57bb04f39cef8fcdf4872607b7fc21850a0d99ffa670e91a69b4b6b -burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 4bcdd2b9332442c3659ffb5bcbd459aede3bcde27af0a72ee4fa198bcade6a1d -burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 0202f23e5691696d5a61ae4bd23f73b1dc2651837d0e477e1ddaf489e63e4466 +burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 4bf274f1e24e5cf777c8a49fa878c01d79108927950da9924427056406eb9f98 +burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 6477fba49883ae781b2bea29076e4c391fca8d69e42b91b46d908dec5e6e471e +burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 61bccb6b9bc14ef7f1fe536cec0934799ec4e1b61eb0c32427fdfea509ab8b8e +burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin bdde20554414ad4f1b097c42bf8d06502a44cedadcd0387e4a39628f67e587c5 ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 970bf6a2a817813eb3302c92ec3ad0bc0fc6c2e693f33c13f57733d003f44d0d ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin fcced2263564f51b5bf086c221e813ec06a71d2bb2e246b4e28cd60098a6de6f -commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin ddc26c10c2a52b59624faae9005827b09b98db4566887a736005e8cc37cf8a51 -commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin ebd8aac686fa28a71d4212bcd25a28f8f640d50dce5e50498b2f6b8534890b69 +commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin 274d87db70b643e00ab0a7e7845bb4b791f3b613bfc87708d33fc5a8369e2a41 +commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin f7128dcc2ee6dbcbc976288abcc16970ffb19b59412c5202ef6b259d2007f801 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de -evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 2dbf7d8b03e1802beb9185ff2ea7d160250d1969f976e4f52040138d5416cc86 +evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 9bf9e62a4d2a80f46afc230ea1528add66b6ad4168a0ebd3346972f9c2c9def3 evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 15cd5695049ab4be1f396ec1d7b609738b2bcefa3740a7a48316e1f72506a34a -evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin 0de6cf0ebf3777684b5867a1cbfe4dbfeabe2c0758151befb1293d5b983ac510 -evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin bf1a3090a2f8d1632b82a6d45200cf6f3833a1e27303745405c1ed13ffc0cf83 -lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin eadd37962f8011a86af54383ba3e0ae08c2987e2cda577c993f47b30c5b7672a -lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin 82aaf0c20f2802bce3a831d585b497d2918513c6d72f81684c10f77631932526 +evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin c7e633eb58fdabea223c3a334ba02934f9007a01e12d29a5204ce18f580e019d +evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 40cdc5bcb0ef78fdb539778f0b1bea9bf96126256c779fe68c29e46cee40f20e +lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin ed29f2cde7f4470fbc66ab9d4f94bd0b4ed769448ed63d3a4daac79d8ebe7ad5 +lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin fe36bb2efdceffdd7274d055ed88e57c5ad5d5626fdb2ccce45a99da10399b92 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin 1d5146d43e1b99cd2d6f9f06475be19087e4349f7cee0fdbbf134ba65e967c93 mock_arm_contract: ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.abi ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.bin e7a3a6c3eda5fb882e16bcc2b4340f78523acb67907bcdcaf3c8ffc51488688e @@ -28,11 +28,11 @@ nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../ ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 1588313bb5e781d181a825247d30828f59007700f36b4b9b00391592b06ff4b4 price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 7320907b45fe2bdc3a06f5891dd34b8ab270823a652fec15676ec8a898764273 -registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 7b2a47349d3fdb8d8b4e206d68577219deca7fabd1e893686fa8f118ad980d2d +registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 75be86323c227917a9bbc3f799d7ed02f92db546653a36db30ed0ebe64461353 report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin c07af8433bf8dbc7981725b18922a9c4e2dea068dd204bc62adc0e926cb499c3 router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 42576577e81beea9a069bd9229caaa9a71227fbaef3871a1a2e69fd218216290 self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 86e169636e5633854ed0b709c804066b615040bceba25aa5137450fbe6f76fa3 -token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin fb06d2cf5f7476e512c6fb7aab8eab43545efd7f0f6ca133c64ff4e3963902c4 +token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 479ad5c02997f48f7029b937b1b3e053f731d8db44ecc45441cf7f37111a0c35 token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 7c01fd89f5153baa4d7409d14beabb3f861abfbf8880d3c6d06802cc398570f9 usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin 4ca8b09185820ecfa89c4d87a38a66ccd8c3dadb82652782067a3827ec949aa1 weth9: ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin 2970d79a0ca6dd6279cde130de45e56c8790ed695eae477fb5ba4c1bb75b720d diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go index 7a13e20cba..6ab22ded99 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go @@ -311,7 +311,7 @@ func setupOffRampV1_5_0(t *testing.T, user *bind.TransactOpts, bc *client.Simula Context: testutils.Context(t), }) require.NoError(t, err) - require.Equal(t, "EVM2EVMOffRamp 1.5.0-dev", tav) + require.Equal(t, "EVM2EVMOffRamp 1.5.0", tav) return offRampAddr } @@ -353,7 +353,7 @@ func deployCommitStore( } tav, err := cs.TypeAndVersion(callOpts) require.NoError(t, err) - require.Equal(t, "CommitStore 1.5.0-dev", tav) + require.Equal(t, "CommitStore 1.5.0", tav) return csAddr } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go index 25471d0d65..3c82948b89 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go @@ -18,7 +18,7 @@ const ( V1_1_0 = "1.1.0" V1_2_0 = "1.2.0" V1_4_0 = "1.4.0" - V1_5_0 = "1.5.0-dev" + V1_5_0 = "1.5.0" V1_6_0 = "1.6.0-dev" ) diff --git a/integration-tests/ccip-tests/contracts/contract_deployer.go b/integration-tests/ccip-tests/contracts/contract_deployer.go index 57d96e5cb6..3454fd1579 100644 --- a/integration-tests/ccip-tests/contracts/contract_deployer.go +++ b/integration-tests/ccip-tests/contracts/contract_deployer.go @@ -74,7 +74,7 @@ func MatchContractVersionsOrAbove(requiredContractVersions map[Name]Version) err } // NeedTokenAdminRegistry checks if token admin registry is needed for the current version of ccip -// if the version is less than 1.5.0-dev, then token admin registry is not needed +// if the version is less than 1.5.0, then token admin registry is not needed func NeedTokenAdminRegistry() bool { return MatchContractVersionsOrAbove(map[Name]Version{ TokenPoolContract: V1_5_0_dev, diff --git a/integration-tests/ccip-tests/contracts/contract_models.go b/integration-tests/ccip-tests/contracts/contract_models.go index 7008d51b62..1c2f3651b0 100644 --- a/integration-tests/ccip-tests/contracts/contract_models.go +++ b/integration-tests/ccip-tests/contracts/contract_models.go @@ -112,7 +112,7 @@ const ( var ( V1_2_0 = MustVersion("1.2.0") V1_4_0 = MustVersion("1.4.0") - V1_5_0_dev = MustVersion("1.5.0-dev") + V1_5_0_dev = MustVersion("1.5.0") LatestPoolVersion = V1_5_0_dev Latest = V1_5_0_dev VersionMap = map[Name]Version{ From de645cbd7c92fc72aa34cc9d76ac79ec8fef2cfc Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Fri, 9 Aug 2024 13:45:28 +0200 Subject: [PATCH 200/432] bump version to 1.5 (#1279) Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/package.json | 76 +++++++++++++------ .../v0.8/ccip/pools/USDC/USDCTokenPool.sol | 2 +- .../usdc_token_pool/usdc_token_pool.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- package.json | 11 +-- 5 files changed, 62 insertions(+), 31 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index 26fbd88570..14292e16a5 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -1,9 +1,9 @@ { - "name": "@chainlink/contracts", - "version": "1.2.0", - "description": "Chainlink smart contracts", + "name": "@chainlink/contracts-ccip", + "version": "1.5.0", + "description": "Chainlink CCIP smart contracts", "author": "Chainlink devs", - "license": "MIT", + "license": "BUSL-1.1", "private": false, "scripts": { "test": "hardhat test --parallel", @@ -13,16 +13,39 @@ "size": "hardhat size-contracts", "clean": "hardhat clean", "compile:native": "./scripts/native_solc_compile_all", - "compile": "hardhat compile", + "compile": "hardhat compile --no-typechain", "coverage": "hardhat coverage", + "prepare": "chmod +x .husky/prepare.sh && ./.husky/prepare.sh", "prepublishOnly": "pnpm compile && ./scripts/prepublish_generate_abi_folder", "publish-beta": "pnpm publish --tag beta", - "publish-prod": "pnpm publish --tag latest", + "publish-prod": "npm dist-tag add @chainlink/contracts-ccip@1.2.1 latest", + "solhint:ccip": "solhint --max-warnings 0 \"./src/v0.8/ccip/**/*.sol\"", "solhint": "solhint --max-warnings 0 \"./src/v0.8/**/*.sol\"" }, "files": [ - "src/v0.8", - "abi/v0.8" + "src/v0.8/ccip/**/*.sol", + "!src/v0.8/ccip/test/**/*", + "src/v0.8/ccip/test/mocks/**/*", + "src/v0.8/shared/access/ConfirmedOwner.sol", + "src/v0.8/shared/access/ConfirmedOwnerWithProposal.sol", + "src/v0.8/shared/access/OwnerIsCreator.sol", + "src/v0.8/shared/call/CallWithExactGas.sol", + "src/v0.8/shared/enumerable/EnumerableMapAddresses.sol", + "src/v0.8/shared/interfaces/IOwnable.sol", + "src/v0.8/shared/interfaces/ITypeAndVersion.sol", + "src/v0.8/shared/interfaces/IERC677Receiver.sol", + "src/v0.8/shared/token/ERC20/IBurnMintERC20.sol", + "src/v0.8/shared/token/ERC677/IERC677.sol", + "src/v0.8/shared/token/ERC677/IERC677Receiver.sol", + "src/v0.8/shared/token/ERC677/ERC677.sol", + "src/v0.8/shared/token/ERC677/BurnMintERC677.sol", + "src/v0.8/vendor/openzeppelin-solidity", + "src/v0.8/vendor/Context.sol", + "src/v0.8/vendor/Pausable.sol", + "abi/v0.8/", + "src/v0.8/ccip/LICENSE.md", + "src/v0.8/ccip/LICENSE-MIT.md", + "src/v0.8/ccip/v1.4-CCIP-License-grants.md" ], "pnpm": { "_comment": "See https://github.com/ethers-io/ethers.js/discussions/2849#discussioncomment-2696454", @@ -43,49 +66,56 @@ "@ethersproject/providers": "~5.7.2", "@nomicfoundation/hardhat-chai-matchers": "^1.0.6", "@nomicfoundation/hardhat-ethers": "^3.0.6", - "@nomicfoundation/hardhat-network-helpers": "^1.0.11", - "@nomicfoundation/hardhat-verify": "^2.0.9", + "@nomicfoundation/hardhat-network-helpers": "^1.0.9", + "@nomicfoundation/hardhat-verify": "^2.0.7", "@typechain/ethers-v5": "^7.2.0", "@typechain/hardhat": "^7.0.0", "@types/cbor": "~5.0.1", - "@types/chai": "^4.3.17", + "@types/chai": "^4.3.16", "@types/debug": "^4.1.12", "@types/deep-equal-in-any-order": "^1.0.3", - "@types/mocha": "^10.0.7", - "@types/node": "^20.14.15", - "@typescript-eslint/eslint-plugin": "^7.18.0", - "@typescript-eslint/parser": "^7.18.0", + "@types/mocha": "^10.0.6", + "@types/node": "^20.12.12", + "@typescript-eslint/eslint-plugin": "^7.10.0", + "@typescript-eslint/parser": "^7.10.0", "abi-to-sol": "^0.6.6", "cbor": "^5.2.0", - "chai": "^4.5.0", - "debug": "^4.3.6", + "chai": "^4.3.10", + "debug": "^4.3.4", "deep-equal-in-any-order": "^2.0.6", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-prettier": "^5.1.3", "ethers": "~5.7.2", "hardhat": "~2.20.1", "hardhat-abi-exporter": "^2.10.1", "hardhat-ignore-warnings": "^0.2.6", + "husky": "^9.0.11", + "lint-staged": "^15.2.2", "moment": "^2.30.1", - "prettier": "^3.3.3", + "prettier": "^3.2.5", "prettier-plugin-solidity": "^1.3.1", - "solhint": "^5.0.3", + "solhint": "^5.0.1", "solhint-plugin-chainlink-solidity": "git+https://github.com/smartcontractkit/chainlink-solhint-rules.git#v1.2.1", "solhint-plugin-prettier": "^0.1.0", "ts-node": "^10.9.2", "typechain": "^8.2.1", - "typescript": "^5.5.4" + "typescript": "^5.4.5" }, "dependencies": { "@arbitrum/nitro-contracts": "1.1.1", "@arbitrum/token-bridge-contracts": "1.1.2", "@changesets/changelog-github": "^0.5.0", - "@changesets/cli": "~2.27.7", + "@changesets/cli": "~2.27.3", "@eth-optimism/contracts": "0.6.0", "@openzeppelin/contracts": "4.9.3", "@openzeppelin/contracts-upgradeable": "4.9.3", "@scroll-tech/contracts": "0.1.0", - "semver": "^7.6.3" + "semver": "^7.6.2" + }, + "lint-staged": { + "*.sol": [ + "forge fmt" + ] } } diff --git a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol index 833411e49d..3fd9936e07 100644 --- a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol @@ -50,7 +50,7 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { uint32 sourceDomain; } - string public constant override typeAndVersion = "USDCTokenPool 1.4.0"; + string public constant override typeAndVersion = "USDCTokenPool 1.5.0"; // We restrict to the first version. New pool may be required for subsequent versions. uint32 public constant SUPPORTED_USDC_VERSION = 0; diff --git a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go index d6b86fdd42..c8148b24fe 100644 --- a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go +++ b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go @@ -96,7 +96,7 @@ type USDCTokenPoolDomainUpdate struct { var USDCTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b50604051620052c6380380620052c6833981016040819052620000359162000b4c565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200041b565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016957604080516000815260208101909152620001699084620004c6565b5050506001600160a01b038616905062000196576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fd919062000c72565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000240573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000266919062000c99565b905063ffffffff81161562000297576040516334697c6b60e11b815263ffffffff8216600482015260240162000087565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fe919062000c99565b905063ffffffff8116156200032f576040516316ba39c560e31b815263ffffffff8216600482015260240162000087565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa15801562000381573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a7919062000c99565b63ffffffff166101205260e051608051620003d1916001600160a01b039091169060001962000623565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000de6565b336001600160a01b03821603620004755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620004e7576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005725760008382815181106200050b576200050b62000cc1565b602090810291909101015190506200052560028262000709565b1562000568576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620004ea565b5060005b81518110156200061e57600082828151811062000597576200059762000cc1565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005c3575062000615565b620005d060028262000729565b1562000613576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000576565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200069b919062000cd7565b620006a7919062000d07565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000703918691906200074016565b50505050565b600062000720836001600160a01b03841662000811565b90505b92915050565b600062000720836001600160a01b03841662000915565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200078f906001600160a01b03851690849062000967565b8051909150156200061e5780806020019051810190620007b0919062000d1d565b6200061e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000087565b600081815260018301602052604081205480156200090a5760006200083860018362000d41565b85549091506000906200084e9060019062000d41565b9050818114620008ba57600086600001828154811062000872576200087262000cc1565b906000526020600020015490508087600001848154811062000898576200089862000cc1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620008ce57620008ce62000d57565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000723565b600091505062000723565b60008181526001830160205260408120546200095e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000723565b50600062000723565b606062000978848460008562000980565b949350505050565b606082471015620009e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000087565b600080866001600160a01b0316858760405162000a01919062000d93565b60006040518083038185875af1925050503d806000811462000a40576040519150601f19603f3d011682016040523d82523d6000602084013e62000a45565b606091505b50909250905062000a598783838762000a64565b979650505050505050565b6060831562000ad857825160000362000ad0576001600160a01b0385163b62000ad05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000087565b508162000978565b62000978838381511562000aef5781518083602001fd5b8060405162461bcd60e51b815260040162000087919062000db1565b6001600160a01b038116811462000b2157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b478162000b0b565b919050565b600080600080600060a0868803121562000b6557600080fd5b855162000b728162000b0b565b8095505060208087015162000b878162000b0b565b60408801519095506001600160401b038082111562000ba557600080fd5b818901915089601f83011262000bba57600080fd5b81518181111562000bcf5762000bcf62000b24565b8060051b604051601f19603f8301168101818110858211171562000bf75762000bf762000b24565b60405291825284820192508381018501918c83111562000c1657600080fd5b938501935b8285101562000c3f5762000c2f8562000b3a565b8452938501939285019262000c1b565b80985050505050505062000c566060870162000b3a565b915062000c666080870162000b3a565b90509295509295909350565b60006020828403121562000c8557600080fd5b815162000c928162000b0b565b9392505050565b60006020828403121562000cac57600080fd5b815163ffffffff8116811462000c9257600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000cea57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000723576200072362000cf1565b60006020828403121562000d3057600080fd5b8151801515811462000c9257600080fd5b8181038181111562000723576200072362000cf1565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d8a57818101518382015260200162000d70565b50506000910152565b6000825162000da781846020870162000d6d565b9190910192915050565b602081526000825180602084015262000dd281604085016020870162000d6d565b601f01601f19169190910160400192915050565b60805160a05160c05160e051610100516101205161442762000e9f60003960008181610382015281816111d101528181611e4a0152611ea80152600081816106760152610a7801526000818161035b01526110e701526000818161063a01528181611f45015261288001526000818161057601528181611c4801526121fb01526000818161028f015281816102e4015281816110b101528181611b680152818161211b015281816128160152612a6b01526144276000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80639a4575b91161010f578063c75eea9c116100a2578063dfadfa3511610071578063dfadfa351461059a578063e0351e1314610638578063f2fde38b1461065e578063fbf84dd71461067157600080fd5b8063c75eea9c1461053b578063cf7401f31461054e578063db6327dc14610561578063dc0bd9711461057457600080fd5b8063b0f479a1116100de578063b0f479a1146104e2578063b794658014610500578063c0d7865514610513578063c4bffe2b1461052657600080fd5b80639a4575b9146104365780639fdf13ff14610456578063a7cd63b71461045e578063af58d59f1461047357600080fd5b80636155cda01161018757806379ba50971161015657806379ba5097146103ea5780637d54534e146103f25780638926f54f146104055780638da5cb5b1461041857600080fd5b80636155cda0146103565780636b716b0d1461037d5780636d3d1a58146103b957806378a010b2146103d757600080fd5b806321df0da7116101c357806321df0da71461028d578063240028e8146102d4578063390775371461032157806354c8a4f31461034357600080fd5b806241d3c1146101f457806301ffc9a7146102095780630a2fd49314610231578063181f5a7714610251575b600080fd5b61020761020236600461320e565b610698565b005b61021c610217366004613283565b610835565b60405190151581526020015b60405180910390f35b61024461023f3660046132eb565b61091a565b604051610228919061336c565b6102446040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e342e300000000000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610228565b61021c6102e23660046133ac565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61033461032f3660046133c9565b6109ca565b60405190518152602001610228565b610207610351366004613451565b610bb7565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6103a47f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610228565b60085473ffffffffffffffffffffffffffffffffffffffff166102af565b6102076103e53660046134bd565b610c32565b610207610da1565b6102076104003660046133ac565b610e9e565b61021c6104133660046132eb565b610eed565b60005473ffffffffffffffffffffffffffffffffffffffff166102af565b610449610444366004613542565b610f04565b604051610228919061357d565b6103a4600081565b61046661124c565b60405161022891906135dd565b6104866104813660046132eb565b61125d565b604051610228919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102af565b61024461050e3660046132eb565b611332565b6102076105213660046133ac565b61135d565b61052e611431565b6040516102289190613637565b6104866105493660046132eb565b6114e9565b61020761055c3660046137c2565b6115bb565b61020761056f366004613809565b611644565b7f00000000000000000000000000000000000000000000000000000000000000006102af565b61060e6105a83660046132eb565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600982529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610228565b7f000000000000000000000000000000000000000000000000000000000000000061021c565b61020761066c3660046133ac565b611aca565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6106a0611ade565b60005b818110156107f75760008383838181106106bf576106bf61384b565b9050608002018036038101906106d5919061388e565b805190915015806106f25750604081015167ffffffffffffffff16155b1561076157604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600990925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169190931617929092179055016106a3565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee568282604051610829929190613908565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806108c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061091457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906109459061398f565b80601f01602080910402602001604051908101604052809291908181526020018280546109719061398f565b80156109be5780601f10610993576101008083540402835291602001916109be565b820191906000526020600020905b8154815290600101906020018083116109a157829003601f168201915b50505050509050919050565b6040805160208101909152600081526109ea6109e583613a8d565b611b61565b60006109f960c0840184613b82565b810190610a069190613be7565b90506000610a1760e0850185613b82565b810190610a249190613c26565b9050610a34816000015183611d92565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aab92600401613cb7565b6020604051808303816000875af1158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190613cdc565b610b24576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3460608501604086016133ac565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610b9691815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b610bbf611ade565b610c2c84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f4392505050565b50505050565b610c3a611ade565b610c4383610eed565b610c85576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b67ffffffffffffffff831660009081526007602052604081206004018054610cac9061398f565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd89061398f565b8015610d255780601f10610cfa57610100808354040283529160200191610d25565b820191906000526020600020905b815481529060010190602001808311610d0857829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610d54838583613d41565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d9393929190613ea5565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610758565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ea6611ade565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610914600567ffffffffffffffff84166120f9565b6040805180820190915260608082526020820152610f29610f2483613ed5565b612114565b6000600981610f3e60408601602087016132eb565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff161515908201819052909150610fe557610fa660408401602085016132eb565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b610fef8380613b82565b9050602014611036576110028380613b82565b6040517fa3c8cf09000000000000000000000000000000000000000000000000000000008152600401610758929190613f79565b60006110428480613b82565b81019061104f9190613f8d565b602083015183516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060880135600482015263ffffffff90921660248301526044820183905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063f856ddb69060a4016020604051808303816000875af1158015611130573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111549190613fa6565b6040516060870135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260405180604001604052806111b187602001602081019061050e91906132eb565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905295945050505050565b606061125860026122de565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610914906122eb565b67ffffffffffffffff811660009081526007602052604090206005018054606091906109459061398f565b611365611ade565b73ffffffffffffffffffffffffffffffffffffffff81166113b2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610829565b6060600061143f60056122de565b90506000815167ffffffffffffffff81111561145d5761145d613679565b604051908082528060200260200182016040528015611486578160200160208202803683370190505b50905060005b82518110156114e2578281815181106114a7576114a761384b565b60200260200101518282815181106114c1576114c161384b565b67ffffffffffffffff9092166020928302919091019091015260010161148c565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610914906122eb565b60085473ffffffffffffffffffffffffffffffffffffffff1633148015906115fb575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611634576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b61163f83838361239d565b505050565b61164c611ade565b60005b8181101561163f57600083838381811061166b5761166b61384b565b905060200281019061167d9190613fc3565b61168690614001565b905061169b8160800151826020015115612487565b6116ae8160a00151826020015115612487565b8060200151156119aa5780516116d09060059067ffffffffffffffff166125c0565b6117155780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b604081015151158061172a5750606081015151155b15611761576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061194290826140b5565b506060820151600582019061195790826140b5565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061199d94939291906141cf565b60405180910390a1611ac1565b80516119c29060059067ffffffffffffffff166125cc565b611a075780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611a7060048301826131c0565b611a7e6005830160006131c0565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161164f565b611ad2611ade565b611adb816125d8565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610758565b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611bf65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc89190613cdc565b15611cff576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d0c81602001516126cd565b6000611d1b826020015161091a565b9050805160001480611d3f575080805190602001208260a001518051906020012014155b15611d7c578160a001516040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610758919061336c565b611d8e826020015183606001516127f3565b5050565b600482015163ffffffff811615611ddd576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610758565b6008830151600c8401516014850151602085015163ffffffff808516911614611e485760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff91821660048201529084166024820152604401610758565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611edd576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015283166024820152604401610758565b845167ffffffffffffffff828116911614611f3b5784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821660048201529082166024820152604401610758565b505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611f9a576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612030576000838281518110611fba57611fba61384b565b60200260200101519050611fd881600261283a90919063ffffffff16565b156120275760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f9d565b5060005b815181101561163f5760008282815181106120515761205161384b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361209557506120f1565b6120a060028261285c565b156120ef5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612034565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121a95760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227b9190613cdc565b156122b2576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122bf816040015161287e565b6122cc81602001516128fd565b611adb81602001518260600151612a4b565b6060600061210d83612a8f565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261237982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261235d9190614297565b85608001516fffffffffffffffffffffffffffffffff16612aea565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6123a683610eed565b6123e8576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b6123f3826000612487565b67ffffffffffffffff831660009081526007602052604090206124169083612b14565b612421816000612487565b67ffffffffffffffff831660009081526007602052604090206124479060020182612b14565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161247a939291906142aa565b60405180910390a1505050565b81511561254e5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806124dd575060408201516fffffffffffffffffffffffffffffffff16155b1561251657816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610758919061432d565b8015611d8e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612587575060208201516fffffffffffffffffffffffffffffffff1615155b15611d8e57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610758919061432d565b600061210d8383612cb6565b600061210d8383612d05565b3373ffffffffffffffffffffffffffffffffffffffff821603612657576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610758565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6126d681610eed565b612718576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612797573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127bb9190613cdc565b611adb576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d8e90600201827f0000000000000000000000000000000000000000000000000000000000000000612df8565b600061210d8373ffffffffffffffffffffffffffffffffffffffff8416612d05565b600061210d8373ffffffffffffffffffffffffffffffffffffffff8416612cb6565b7f000000000000000000000000000000000000000000000000000000000000000015611adb576128af60028261317b565b611adb576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610758565b61290681610eed565b612948576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156129c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e59190614369565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611adb576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d8e90827f0000000000000000000000000000000000000000000000000000000000000000612df8565b6060816000018054806020026020016040519081016040528092919081815260200182805480156109be57602002820191906000526020600020905b815481526020019060010190808311612acb5750505050509050919050565b6000612b0985612afa8486614386565b612b04908761439d565b6131aa565b90505b949350505050565b8154600090612b3d90700100000000000000000000000000000000900463ffffffff1642614297565b90508015612bdf5760018301548354612b85916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612aea565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c05916fffffffffffffffffffffffffffffffff90811691166131aa565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061247a90849061432d565b6000818152600183016020526040812054612cfd57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610914565b506000610914565b60008181526001830160205260408120548015612dee576000612d29600183614297565b8554909150600090612d3d90600190614297565b9050818114612da2576000866000018281548110612d5d57612d5d61384b565b9060005260206000200154905080876000018481548110612d8057612d8061384b565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612db357612db36143b0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610914565b6000915050610914565b825474010000000000000000000000000000000000000000900460ff161580612e1f575081155b15612e2957505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612e6f90700100000000000000000000000000000000900463ffffffff1642614297565b90508015612f2f5781831115612eb1576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612eeb9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612aea565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612fe65773ffffffffffffffffffffffffffffffffffffffff8416612f8e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610758565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610758565b848310156130f95760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061302a9082614297565b613034878a614297565b61303e919061439d565b61304891906143df565b905073ffffffffffffffffffffffffffffffffffffffff86166130a1576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610758565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610758565b6131038584614297565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561210d565b60008183106131b9578161210d565b5090919050565b5080546131cc9061398f565b6000825580601f106131dc575050565b601f016020900490600052602060002090810190611adb91905b8082111561320a57600081556001016131f6565b5090565b6000806020838503121561322157600080fd5b823567ffffffffffffffff8082111561323957600080fd5b818501915085601f83011261324d57600080fd5b81358181111561325c57600080fd5b8660208260071b850101111561327157600080fd5b60209290920196919550909350505050565b60006020828403121561329557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461210d57600080fd5b67ffffffffffffffff81168114611adb57600080fd5b80356132e6816132c5565b919050565b6000602082840312156132fd57600080fd5b813561210d816132c5565b6000815180845260005b8181101561332e57602081850181015186830182015201613312565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061210d6020830184613308565b73ffffffffffffffffffffffffffffffffffffffff81168114611adb57600080fd5b80356132e68161337f565b6000602082840312156133be57600080fd5b813561210d8161337f565b6000602082840312156133db57600080fd5b813567ffffffffffffffff8111156133f257600080fd5b8201610100818503121561210d57600080fd5b60008083601f84011261341757600080fd5b50813567ffffffffffffffff81111561342f57600080fd5b6020830191508360208260051b850101111561344a57600080fd5b9250929050565b6000806000806040858703121561346757600080fd5b843567ffffffffffffffff8082111561347f57600080fd5b61348b88838901613405565b909650945060208701359150808211156134a457600080fd5b506134b187828801613405565b95989497509550505050565b6000806000604084860312156134d257600080fd5b83356134dd816132c5565b9250602084013567ffffffffffffffff808211156134fa57600080fd5b818601915086601f83011261350e57600080fd5b81358181111561351d57600080fd5b87602082850101111561352f57600080fd5b6020830194508093505050509250925092565b60006020828403121561355457600080fd5b813567ffffffffffffffff81111561356b57600080fd5b820160a0818503121561210d57600080fd5b6020815260008251604060208401526135996060840182613308565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526135d48282613308565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561362b57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016135f9565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561362b57835167ffffffffffffffff1683529284019291840191600101613653565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156136cc576136cc613679565b60405290565b6040805190810167ffffffffffffffff811182821017156136cc576136cc613679565b60405160c0810167ffffffffffffffff811182821017156136cc576136cc613679565b8015158114611adb57600080fd5b80356132e681613718565b80356fffffffffffffffffffffffffffffffff811681146132e657600080fd5b60006060828403121561376357600080fd5b6040516060810181811067ffffffffffffffff8211171561378657613786613679565b604052905080823561379781613718565b81526137a560208401613731565b60208201526137b660408401613731565b60408201525092915050565b600080600060e084860312156137d757600080fd5b83356137e2816132c5565b92506137f18560208601613751565b91506138008560808601613751565b90509250925092565b6000806020838503121561381c57600080fd5b823567ffffffffffffffff81111561383357600080fd5b61383f85828601613405565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff811681146132e657600080fd5b6000608082840312156138a057600080fd5b6040516080810181811067ffffffffffffffff821117156138c3576138c3613679565b604052823581526138d66020840161387a565b602082015260408301356138e9816132c5565b604082015260608301356138fc81613718565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613982578135835263ffffffff61393a86840161387a565b16858401528382013561394c816132c5565b67ffffffffffffffff168385015260608281013561396981613718565b151590840152608092830192919091019060010161391e565b5090979650505050505050565b600181811c908216806139a357607f821691505b6020821081036139dc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126139f357600080fd5b813567ffffffffffffffff80821115613a0e57613a0e613679565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613a5457613a54613679565b81604052838152866020858801011115613a6d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613aa057600080fd5b613aa86136a8565b823567ffffffffffffffff80821115613ac057600080fd5b613acc368387016139e2565b8352613ada602086016132db565b6020840152613aeb604086016133a1565b604084015260608501356060840152613b06608086016133a1565b608084015260a0850135915080821115613b1f57600080fd5b613b2b368387016139e2565b60a084015260c0850135915080821115613b4457600080fd5b613b50368387016139e2565b60c084015260e0850135915080821115613b6957600080fd5b50613b76368286016139e2565b60e08301525092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613bb757600080fd5b83018035915067ffffffffffffffff821115613bd257600080fd5b60200191503681900382131561344a57600080fd5b600060408284031215613bf957600080fd5b613c016136d2565b8235613c0c816132c5565b8152613c1a6020840161387a565b60208201529392505050565b600060208284031215613c3857600080fd5b813567ffffffffffffffff80821115613c5057600080fd5b9083019060408286031215613c6457600080fd5b613c6c6136d2565b823582811115613c7b57600080fd5b613c87878286016139e2565b825250602083013582811115613c9c57600080fd5b613ca8878286016139e2565b60208301525095945050505050565b604081526000613cca6040830185613308565b82810360208401526135d48185613308565b600060208284031215613cee57600080fd5b815161210d81613718565b601f82111561163f576000816000526020600020601f850160051c81016020861015613d225750805b601f850160051c820191505b81811015611f3b57828155600101613d2e565b67ffffffffffffffff831115613d5957613d59613679565b613d6d83613d67835461398f565b83613cf9565b6000601f841160018114613dbf5760008515613d895750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613e55565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613e0e5786850135825560209485019460019092019101613dee565b5086821015613e49577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000613eb86040830186613308565b8281036020840152613ecb818587613e5c565b9695505050505050565b600060a08236031215613ee757600080fd5b60405160a0810167ffffffffffffffff8282108183111715613f0b57613f0b613679565b816040528435915080821115613f2057600080fd5b50613f2d368286016139e2565b8252506020830135613f3e816132c5565b60208201526040830135613f518161337f565b6040820152606083810135908201526080830135613f6e8161337f565b608082015292915050565b602081526000612b0c602083018486613e5c565b600060208284031215613f9f57600080fd5b5035919050565b600060208284031215613fb857600080fd5b815161210d816132c5565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ff757600080fd5b9190910192915050565b6000610140823603121561401457600080fd5b61401c6136f5565b614025836132db565b815261403360208401613726565b6020820152604083013567ffffffffffffffff8082111561405357600080fd5b61405f368387016139e2565b6040840152606085013591508082111561407857600080fd5b50614085368286016139e2565b6060830152506140983660808501613751565b60808201526140aa3660e08501613751565b60a082015292915050565b815167ffffffffffffffff8111156140cf576140cf613679565b6140e3816140dd845461398f565b84613cf9565b602080601f83116001811461413657600084156141005750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611f3b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561418357888601518255948401946001909101908401614164565b50858210156141bf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526141f381840187613308565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506142319050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526135d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561091457610914614268565b67ffffffffffffffff8416815260e081016142f660208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612b0c565b6060810161091482848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561437b57600080fd5b815161210d8161337f565b808202811582820484141761091457610914614268565b8082018082111561091457610914614268565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614415577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + Bin: "0x6101406040523480156200001257600080fd5b50604051620052c6380380620052c6833981016040819052620000359162000b4c565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200041b565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016957604080516000815260208101909152620001699084620004c6565b5050506001600160a01b038616905062000196576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fd919062000c72565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000240573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000266919062000c99565b905063ffffffff81161562000297576040516334697c6b60e11b815263ffffffff8216600482015260240162000087565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fe919062000c99565b905063ffffffff8116156200032f576040516316ba39c560e31b815263ffffffff8216600482015260240162000087565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa15801562000381573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a7919062000c99565b63ffffffff166101205260e051608051620003d1916001600160a01b039091169060001962000623565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000de6565b336001600160a01b03821603620004755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620004e7576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005725760008382815181106200050b576200050b62000cc1565b602090810291909101015190506200052560028262000709565b1562000568576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620004ea565b5060005b81518110156200061e57600082828151811062000597576200059762000cc1565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005c3575062000615565b620005d060028262000729565b1562000613576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000576565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200069b919062000cd7565b620006a7919062000d07565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000703918691906200074016565b50505050565b600062000720836001600160a01b03841662000811565b90505b92915050565b600062000720836001600160a01b03841662000915565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200078f906001600160a01b03851690849062000967565b8051909150156200061e5780806020019051810190620007b0919062000d1d565b6200061e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000087565b600081815260018301602052604081205480156200090a5760006200083860018362000d41565b85549091506000906200084e9060019062000d41565b9050818114620008ba57600086600001828154811062000872576200087262000cc1565b906000526020600020015490508087600001848154811062000898576200089862000cc1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620008ce57620008ce62000d57565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000723565b600091505062000723565b60008181526001830160205260408120546200095e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000723565b50600062000723565b606062000978848460008562000980565b949350505050565b606082471015620009e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000087565b600080866001600160a01b0316858760405162000a01919062000d93565b60006040518083038185875af1925050503d806000811462000a40576040519150601f19603f3d011682016040523d82523d6000602084013e62000a45565b606091505b50909250905062000a598783838762000a64565b979650505050505050565b6060831562000ad857825160000362000ad0576001600160a01b0385163b62000ad05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000087565b508162000978565b62000978838381511562000aef5781518083602001fd5b8060405162461bcd60e51b815260040162000087919062000db1565b6001600160a01b038116811462000b2157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b478162000b0b565b919050565b600080600080600060a0868803121562000b6557600080fd5b855162000b728162000b0b565b8095505060208087015162000b878162000b0b565b60408801519095506001600160401b038082111562000ba557600080fd5b818901915089601f83011262000bba57600080fd5b81518181111562000bcf5762000bcf62000b24565b8060051b604051601f19603f8301168101818110858211171562000bf75762000bf762000b24565b60405291825284820192508381018501918c83111562000c1657600080fd5b938501935b8285101562000c3f5762000c2f8562000b3a565b8452938501939285019262000c1b565b80985050505050505062000c566060870162000b3a565b915062000c666080870162000b3a565b90509295509295909350565b60006020828403121562000c8557600080fd5b815162000c928162000b0b565b9392505050565b60006020828403121562000cac57600080fd5b815163ffffffff8116811462000c9257600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000cea57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000723576200072362000cf1565b60006020828403121562000d3057600080fd5b8151801515811462000c9257600080fd5b8181038181111562000723576200072362000cf1565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d8a57818101518382015260200162000d70565b50506000910152565b6000825162000da781846020870162000d6d565b9190910192915050565b602081526000825180602084015262000dd281604085016020870162000d6d565b601f01601f19169190910160400192915050565b60805160a05160c05160e051610100516101205161442762000e9f60003960008181610382015281816111d101528181611e4a0152611ea80152600081816106760152610a7801526000818161035b01526110e701526000818161063a01528181611f45015261288001526000818161057601528181611c4801526121fb01526000818161028f015281816102e4015281816110b101528181611b680152818161211b015281816128160152612a6b01526144276000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80639a4575b91161010f578063c75eea9c116100a2578063dfadfa3511610071578063dfadfa351461059a578063e0351e1314610638578063f2fde38b1461065e578063fbf84dd71461067157600080fd5b8063c75eea9c1461053b578063cf7401f31461054e578063db6327dc14610561578063dc0bd9711461057457600080fd5b8063b0f479a1116100de578063b0f479a1146104e2578063b794658014610500578063c0d7865514610513578063c4bffe2b1461052657600080fd5b80639a4575b9146104365780639fdf13ff14610456578063a7cd63b71461045e578063af58d59f1461047357600080fd5b80636155cda01161018757806379ba50971161015657806379ba5097146103ea5780637d54534e146103f25780638926f54f146104055780638da5cb5b1461041857600080fd5b80636155cda0146103565780636b716b0d1461037d5780636d3d1a58146103b957806378a010b2146103d757600080fd5b806321df0da7116101c357806321df0da71461028d578063240028e8146102d4578063390775371461032157806354c8a4f31461034357600080fd5b806241d3c1146101f457806301ffc9a7146102095780630a2fd49314610231578063181f5a7714610251575b600080fd5b61020761020236600461320e565b610698565b005b61021c610217366004613283565b610835565b60405190151581526020015b60405180910390f35b61024461023f3660046132eb565b61091a565b604051610228919061336c565b6102446040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e352e300000000000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610228565b61021c6102e23660046133ac565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61033461032f3660046133c9565b6109ca565b60405190518152602001610228565b610207610351366004613451565b610bb7565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6103a47f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610228565b60085473ffffffffffffffffffffffffffffffffffffffff166102af565b6102076103e53660046134bd565b610c32565b610207610da1565b6102076104003660046133ac565b610e9e565b61021c6104133660046132eb565b610eed565b60005473ffffffffffffffffffffffffffffffffffffffff166102af565b610449610444366004613542565b610f04565b604051610228919061357d565b6103a4600081565b61046661124c565b60405161022891906135dd565b6104866104813660046132eb565b61125d565b604051610228919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102af565b61024461050e3660046132eb565b611332565b6102076105213660046133ac565b61135d565b61052e611431565b6040516102289190613637565b6104866105493660046132eb565b6114e9565b61020761055c3660046137c2565b6115bb565b61020761056f366004613809565b611644565b7f00000000000000000000000000000000000000000000000000000000000000006102af565b61060e6105a83660046132eb565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600982529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610228565b7f000000000000000000000000000000000000000000000000000000000000000061021c565b61020761066c3660046133ac565b611aca565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6106a0611ade565b60005b818110156107f75760008383838181106106bf576106bf61384b565b9050608002018036038101906106d5919061388e565b805190915015806106f25750604081015167ffffffffffffffff16155b1561076157604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600990925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169190931617929092179055016106a3565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee568282604051610829929190613908565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806108c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061091457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906109459061398f565b80601f01602080910402602001604051908101604052809291908181526020018280546109719061398f565b80156109be5780601f10610993576101008083540402835291602001916109be565b820191906000526020600020905b8154815290600101906020018083116109a157829003601f168201915b50505050509050919050565b6040805160208101909152600081526109ea6109e583613a8d565b611b61565b60006109f960c0840184613b82565b810190610a069190613be7565b90506000610a1760e0850185613b82565b810190610a249190613c26565b9050610a34816000015183611d92565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aab92600401613cb7565b6020604051808303816000875af1158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190613cdc565b610b24576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3460608501604086016133ac565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610b9691815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b610bbf611ade565b610c2c84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f4392505050565b50505050565b610c3a611ade565b610c4383610eed565b610c85576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b67ffffffffffffffff831660009081526007602052604081206004018054610cac9061398f565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd89061398f565b8015610d255780601f10610cfa57610100808354040283529160200191610d25565b820191906000526020600020905b815481529060010190602001808311610d0857829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610d54838583613d41565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d9393929190613ea5565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610758565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ea6611ade565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610914600567ffffffffffffffff84166120f9565b6040805180820190915260608082526020820152610f29610f2483613ed5565b612114565b6000600981610f3e60408601602087016132eb565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff161515908201819052909150610fe557610fa660408401602085016132eb565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b610fef8380613b82565b9050602014611036576110028380613b82565b6040517fa3c8cf09000000000000000000000000000000000000000000000000000000008152600401610758929190613f79565b60006110428480613b82565b81019061104f9190613f8d565b602083015183516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060880135600482015263ffffffff90921660248301526044820183905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063f856ddb69060a4016020604051808303816000875af1158015611130573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111549190613fa6565b6040516060870135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260405180604001604052806111b187602001602081019061050e91906132eb565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905295945050505050565b606061125860026122de565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610914906122eb565b67ffffffffffffffff811660009081526007602052604090206005018054606091906109459061398f565b611365611ade565b73ffffffffffffffffffffffffffffffffffffffff81166113b2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610829565b6060600061143f60056122de565b90506000815167ffffffffffffffff81111561145d5761145d613679565b604051908082528060200260200182016040528015611486578160200160208202803683370190505b50905060005b82518110156114e2578281815181106114a7576114a761384b565b60200260200101518282815181106114c1576114c161384b565b67ffffffffffffffff9092166020928302919091019091015260010161148c565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610914906122eb565b60085473ffffffffffffffffffffffffffffffffffffffff1633148015906115fb575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611634576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b61163f83838361239d565b505050565b61164c611ade565b60005b8181101561163f57600083838381811061166b5761166b61384b565b905060200281019061167d9190613fc3565b61168690614001565b905061169b8160800151826020015115612487565b6116ae8160a00151826020015115612487565b8060200151156119aa5780516116d09060059067ffffffffffffffff166125c0565b6117155780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b604081015151158061172a5750606081015151155b15611761576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061194290826140b5565b506060820151600582019061195790826140b5565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061199d94939291906141cf565b60405180910390a1611ac1565b80516119c29060059067ffffffffffffffff166125cc565b611a075780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611a7060048301826131c0565b611a7e6005830160006131c0565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161164f565b611ad2611ade565b611adb816125d8565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610758565b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611bf65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc89190613cdc565b15611cff576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d0c81602001516126cd565b6000611d1b826020015161091a565b9050805160001480611d3f575080805190602001208260a001518051906020012014155b15611d7c578160a001516040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610758919061336c565b611d8e826020015183606001516127f3565b5050565b600482015163ffffffff811615611ddd576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610758565b6008830151600c8401516014850151602085015163ffffffff808516911614611e485760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff91821660048201529084166024820152604401610758565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611edd576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015283166024820152604401610758565b845167ffffffffffffffff828116911614611f3b5784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821660048201529082166024820152604401610758565b505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611f9a576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612030576000838281518110611fba57611fba61384b565b60200260200101519050611fd881600261283a90919063ffffffff16565b156120275760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f9d565b5060005b815181101561163f5760008282815181106120515761205161384b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361209557506120f1565b6120a060028261285c565b156120ef5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612034565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121a95760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227b9190613cdc565b156122b2576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122bf816040015161287e565b6122cc81602001516128fd565b611adb81602001518260600151612a4b565b6060600061210d83612a8f565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261237982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261235d9190614297565b85608001516fffffffffffffffffffffffffffffffff16612aea565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6123a683610eed565b6123e8576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b6123f3826000612487565b67ffffffffffffffff831660009081526007602052604090206124169083612b14565b612421816000612487565b67ffffffffffffffff831660009081526007602052604090206124479060020182612b14565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161247a939291906142aa565b60405180910390a1505050565b81511561254e5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806124dd575060408201516fffffffffffffffffffffffffffffffff16155b1561251657816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610758919061432d565b8015611d8e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612587575060208201516fffffffffffffffffffffffffffffffff1615155b15611d8e57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610758919061432d565b600061210d8383612cb6565b600061210d8383612d05565b3373ffffffffffffffffffffffffffffffffffffffff821603612657576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610758565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6126d681610eed565b612718576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612797573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127bb9190613cdc565b611adb576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d8e90600201827f0000000000000000000000000000000000000000000000000000000000000000612df8565b600061210d8373ffffffffffffffffffffffffffffffffffffffff8416612d05565b600061210d8373ffffffffffffffffffffffffffffffffffffffff8416612cb6565b7f000000000000000000000000000000000000000000000000000000000000000015611adb576128af60028261317b565b611adb576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610758565b61290681610eed565b612948576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156129c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e59190614369565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611adb576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d8e90827f0000000000000000000000000000000000000000000000000000000000000000612df8565b6060816000018054806020026020016040519081016040528092919081815260200182805480156109be57602002820191906000526020600020905b815481526020019060010190808311612acb5750505050509050919050565b6000612b0985612afa8486614386565b612b04908761439d565b6131aa565b90505b949350505050565b8154600090612b3d90700100000000000000000000000000000000900463ffffffff1642614297565b90508015612bdf5760018301548354612b85916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612aea565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c05916fffffffffffffffffffffffffffffffff90811691166131aa565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061247a90849061432d565b6000818152600183016020526040812054612cfd57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610914565b506000610914565b60008181526001830160205260408120548015612dee576000612d29600183614297565b8554909150600090612d3d90600190614297565b9050818114612da2576000866000018281548110612d5d57612d5d61384b565b9060005260206000200154905080876000018481548110612d8057612d8061384b565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612db357612db36143b0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610914565b6000915050610914565b825474010000000000000000000000000000000000000000900460ff161580612e1f575081155b15612e2957505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612e6f90700100000000000000000000000000000000900463ffffffff1642614297565b90508015612f2f5781831115612eb1576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612eeb9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612aea565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612fe65773ffffffffffffffffffffffffffffffffffffffff8416612f8e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610758565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610758565b848310156130f95760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061302a9082614297565b613034878a614297565b61303e919061439d565b61304891906143df565b905073ffffffffffffffffffffffffffffffffffffffff86166130a1576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610758565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610758565b6131038584614297565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561210d565b60008183106131b9578161210d565b5090919050565b5080546131cc9061398f565b6000825580601f106131dc575050565b601f016020900490600052602060002090810190611adb91905b8082111561320a57600081556001016131f6565b5090565b6000806020838503121561322157600080fd5b823567ffffffffffffffff8082111561323957600080fd5b818501915085601f83011261324d57600080fd5b81358181111561325c57600080fd5b8660208260071b850101111561327157600080fd5b60209290920196919550909350505050565b60006020828403121561329557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461210d57600080fd5b67ffffffffffffffff81168114611adb57600080fd5b80356132e6816132c5565b919050565b6000602082840312156132fd57600080fd5b813561210d816132c5565b6000815180845260005b8181101561332e57602081850181015186830182015201613312565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061210d6020830184613308565b73ffffffffffffffffffffffffffffffffffffffff81168114611adb57600080fd5b80356132e68161337f565b6000602082840312156133be57600080fd5b813561210d8161337f565b6000602082840312156133db57600080fd5b813567ffffffffffffffff8111156133f257600080fd5b8201610100818503121561210d57600080fd5b60008083601f84011261341757600080fd5b50813567ffffffffffffffff81111561342f57600080fd5b6020830191508360208260051b850101111561344a57600080fd5b9250929050565b6000806000806040858703121561346757600080fd5b843567ffffffffffffffff8082111561347f57600080fd5b61348b88838901613405565b909650945060208701359150808211156134a457600080fd5b506134b187828801613405565b95989497509550505050565b6000806000604084860312156134d257600080fd5b83356134dd816132c5565b9250602084013567ffffffffffffffff808211156134fa57600080fd5b818601915086601f83011261350e57600080fd5b81358181111561351d57600080fd5b87602082850101111561352f57600080fd5b6020830194508093505050509250925092565b60006020828403121561355457600080fd5b813567ffffffffffffffff81111561356b57600080fd5b820160a0818503121561210d57600080fd5b6020815260008251604060208401526135996060840182613308565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526135d48282613308565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561362b57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016135f9565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561362b57835167ffffffffffffffff1683529284019291840191600101613653565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156136cc576136cc613679565b60405290565b6040805190810167ffffffffffffffff811182821017156136cc576136cc613679565b60405160c0810167ffffffffffffffff811182821017156136cc576136cc613679565b8015158114611adb57600080fd5b80356132e681613718565b80356fffffffffffffffffffffffffffffffff811681146132e657600080fd5b60006060828403121561376357600080fd5b6040516060810181811067ffffffffffffffff8211171561378657613786613679565b604052905080823561379781613718565b81526137a560208401613731565b60208201526137b660408401613731565b60408201525092915050565b600080600060e084860312156137d757600080fd5b83356137e2816132c5565b92506137f18560208601613751565b91506138008560808601613751565b90509250925092565b6000806020838503121561381c57600080fd5b823567ffffffffffffffff81111561383357600080fd5b61383f85828601613405565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff811681146132e657600080fd5b6000608082840312156138a057600080fd5b6040516080810181811067ffffffffffffffff821117156138c3576138c3613679565b604052823581526138d66020840161387a565b602082015260408301356138e9816132c5565b604082015260608301356138fc81613718565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613982578135835263ffffffff61393a86840161387a565b16858401528382013561394c816132c5565b67ffffffffffffffff168385015260608281013561396981613718565b151590840152608092830192919091019060010161391e565b5090979650505050505050565b600181811c908216806139a357607f821691505b6020821081036139dc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126139f357600080fd5b813567ffffffffffffffff80821115613a0e57613a0e613679565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613a5457613a54613679565b81604052838152866020858801011115613a6d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613aa057600080fd5b613aa86136a8565b823567ffffffffffffffff80821115613ac057600080fd5b613acc368387016139e2565b8352613ada602086016132db565b6020840152613aeb604086016133a1565b604084015260608501356060840152613b06608086016133a1565b608084015260a0850135915080821115613b1f57600080fd5b613b2b368387016139e2565b60a084015260c0850135915080821115613b4457600080fd5b613b50368387016139e2565b60c084015260e0850135915080821115613b6957600080fd5b50613b76368286016139e2565b60e08301525092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613bb757600080fd5b83018035915067ffffffffffffffff821115613bd257600080fd5b60200191503681900382131561344a57600080fd5b600060408284031215613bf957600080fd5b613c016136d2565b8235613c0c816132c5565b8152613c1a6020840161387a565b60208201529392505050565b600060208284031215613c3857600080fd5b813567ffffffffffffffff80821115613c5057600080fd5b9083019060408286031215613c6457600080fd5b613c6c6136d2565b823582811115613c7b57600080fd5b613c87878286016139e2565b825250602083013582811115613c9c57600080fd5b613ca8878286016139e2565b60208301525095945050505050565b604081526000613cca6040830185613308565b82810360208401526135d48185613308565b600060208284031215613cee57600080fd5b815161210d81613718565b601f82111561163f576000816000526020600020601f850160051c81016020861015613d225750805b601f850160051c820191505b81811015611f3b57828155600101613d2e565b67ffffffffffffffff831115613d5957613d59613679565b613d6d83613d67835461398f565b83613cf9565b6000601f841160018114613dbf5760008515613d895750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613e55565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613e0e5786850135825560209485019460019092019101613dee565b5086821015613e49577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000613eb86040830186613308565b8281036020840152613ecb818587613e5c565b9695505050505050565b600060a08236031215613ee757600080fd5b60405160a0810167ffffffffffffffff8282108183111715613f0b57613f0b613679565b816040528435915080821115613f2057600080fd5b50613f2d368286016139e2565b8252506020830135613f3e816132c5565b60208201526040830135613f518161337f565b6040820152606083810135908201526080830135613f6e8161337f565b608082015292915050565b602081526000612b0c602083018486613e5c565b600060208284031215613f9f57600080fd5b5035919050565b600060208284031215613fb857600080fd5b815161210d816132c5565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ff757600080fd5b9190910192915050565b6000610140823603121561401457600080fd5b61401c6136f5565b614025836132db565b815261403360208401613726565b6020820152604083013567ffffffffffffffff8082111561405357600080fd5b61405f368387016139e2565b6040840152606085013591508082111561407857600080fd5b50614085368286016139e2565b6060830152506140983660808501613751565b60808201526140aa3660e08501613751565b60a082015292915050565b815167ffffffffffffffff8111156140cf576140cf613679565b6140e3816140dd845461398f565b84613cf9565b602080601f83116001811461413657600084156141005750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611f3b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561418357888601518255948401946001909101908401614164565b50858210156141bf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526141f381840187613308565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506142319050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526135d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561091457610914614268565b67ffffffffffffffff8416815260e081016142f660208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612b0c565b6060810161091482848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561437b57600080fd5b815161210d8161337f565b808202811582820484141761091457610914614268565b8082018082111561091457610914614268565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614415577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var USDCTokenPoolABI = USDCTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 30645041a0..73120459b3 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -34,5 +34,5 @@ router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/sol self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 86e169636e5633854ed0b709c804066b615040bceba25aa5137450fbe6f76fa3 token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 479ad5c02997f48f7029b937b1b3e053f731d8db44ecc45441cf7f37111a0c35 token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 7c01fd89f5153baa4d7409d14beabb3f861abfbf8880d3c6d06802cc398570f9 -usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin 4ca8b09185820ecfa89c4d87a38a66ccd8c3dadb82652782067a3827ec949aa1 +usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin 230d8f375087b236cf60a9cc7b8601f944586e9c1893514a64803a8d98727507 weth9: ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin 2970d79a0ca6dd6279cde130de45e56c8790ed695eae477fb5ba4c1bb75b720d diff --git a/package.json b/package.json index 18171178bc..541cfb1aaf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "chainlink", - "version": "2.15.0", + "name": "ccip", + "version": "2.14.0-ccip1.5.0", "description": "node of the decentralized oracle network, bridging on and off-chain computation", "main": "index.js", "scripts": { @@ -9,14 +9,14 @@ "private": true, "repository": { "type": "git", - "url": "git+ssh://git@github.com/smartcontractkit/chainlink.git" + "url": "git+ssh://git@github.com/smartcontractkit/ccip.git" }, "author": "smartcontractkit", "license": "MIT", "bugs": { - "url": "https://github.com/smartcontractkit/chainlink/issues" + "url": "https://github.com/smartcontractkit/ccip/issues" }, - "homepage": "https://github.com/smartcontractkit/chainlink#readme", + "homepage": "https://github.com/smartcontractkit/ccip#readme", "engines": { "node": ">=18", "pnpm": ">=9" @@ -24,6 +24,7 @@ "devDependencies": { "@changesets/changelog-github": "^0.4.8", "@changesets/cli": "~2.26.2", + "husky": "^9.0.11", "semver": "^7.6.1" } } From bbe27957e03520617007eb9288589aaa15eb82ad Mon Sep 17 00:00:00 2001 From: Chunkai Yang Date: Mon, 12 Aug 2024 11:25:27 -0400 Subject: [PATCH 201/432] update pool func visibility (#1283) ## Motivation ## Solution --- contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol index 3fd9936e07..e58b6374db 100644 --- a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol @@ -97,7 +97,7 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { /// @dev emits ITokenMessenger.DepositForBurn /// @dev Assumes caller has validated destinationReceiver function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - external + public virtual override returns (Pool.LockOrBurnOutV1 memory) @@ -139,7 +139,7 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { /// non-reverting offchainTokenData that can be supplied is a valid attestation for the /// specific message that was sent on source. function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - external + public virtual override returns (Pool.ReleaseOrMintOutV1 memory) From 81e60a5fda3eaf9e912c4deb8a0c5c65b4f4562b Mon Sep 17 00:00:00 2001 From: Makram Date: Mon, 12 Aug 2024 20:28:48 +0300 Subject: [PATCH 202/432] core/capabilities/ccip: bump chainlink-ccip (#1284) ## Motivation Recent merges to chainlink-ccip have caused the integration test to break. ## Solution Include the gas estimator changes required as well as some token data reader changes. Include fixes from https://github.com/smartcontractkit/chainlink-ccip/pull/60 --- core/capabilities/ccip/ccipevm/gas_helpers.go | 89 ++++++++++ .../ccip/ccipevm/gas_helpers_test.go | 157 ++++++++++++++++++ .../ccip/oraclecreator/inprocess.go | 3 + .../ccip/superfakes/token_data_reader.go | 23 +++ core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 12 files changed, 284 insertions(+), 12 deletions(-) create mode 100644 core/capabilities/ccip/ccipevm/gas_helpers.go create mode 100644 core/capabilities/ccip/ccipevm/gas_helpers_test.go create mode 100644 core/capabilities/ccip/superfakes/token_data_reader.go diff --git a/core/capabilities/ccip/ccipevm/gas_helpers.go b/core/capabilities/ccip/ccipevm/gas_helpers.go new file mode 100644 index 0000000000..41acb2a15f --- /dev/null +++ b/core/capabilities/ccip/ccipevm/gas_helpers.go @@ -0,0 +1,89 @@ +package ccipevm + +import ( + "math" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" +) + +const ( + EvmAddressLengthBytes = 20 + EvmWordBytes = 32 + CalldataGasPerByte = 16 + TokenAdminRegistryWarmupCost = 2_500 + TokenAdminRegistryPoolLookupGas = 100 + // WARM_ACCESS_COST TokenAdminRegistry + 700 + // CALL cost for TokenAdminRegistry + 2_100 // COLD_SLOAD_COST loading the pool address + SupportsInterfaceCheck = 2600 + // because the receiver will be untouched initially + 30_000*3 // supportsInterface of ERC165Checker library performs 3 static-calls of 30k gas each + PerTokenOverheadGas = TokenAdminRegistryPoolLookupGas + + SupportsInterfaceCheck + + 200_000 + // releaseOrMint using callWithExactGas + 50_000 // transfer using callWithExactGas + RateLimiterOverheadGas = 2_100 + // COLD_SLOAD_COST for accessing token bucket + 5_000 // SSTORE_RESET_GAS for updating & decreasing token bucket + ConstantMessagePartBytes = 10 * 32 // A message consists of 10 abi encoded fields 32B each (after encoding) + ExecutionStateProcessingOverheadGas = 2_100 + // COLD_SLOAD_COST for first reading the state + 20_000 + // SSTORE_SET_GAS for writing from 0 (untouched) to non-zero (in-progress) + 100 //# SLOAD_GAS = WARM_STORAGE_READ_COST for rewriting from non-zero (in-progress) to non-zero (success/failure) +) + +func NewGasEstimateProvider() EstimateProvider { + return EstimateProvider{} +} + +type EstimateProvider struct { +} + +// CalculateMerkleTreeGas estimates the merkle tree gas based on number of requests +func (gp EstimateProvider) CalculateMerkleTreeGas(numRequests int) uint64 { + if numRequests == 0 { + return 0 + } + merkleProofBytes := (math.Ceil(math.Log2(float64(numRequests))))*32 + (1+2)*32 // only ever one outer root hash + return uint64(merkleProofBytes * CalldataGasPerByte) +} + +// return the size of bytes for msg tokens +func bytesForMsgTokens(numTokens int) int { + // token address (address) + token amount (uint256) + return (EvmAddressLengthBytes + EvmWordBytes) * numTokens +} + +// CalculateMessageMaxGas computes the maximum gas overhead for a message. +func (gp EstimateProvider) CalculateMessageMaxGas(msg cciptypes.Message) uint64 { + numTokens := len(msg.TokenAmounts) + var data []byte = msg.Data + dataLength := len(data) + + // TODO: update interface to return error? + // Although this decoding should never fail. + messageGasLimit, err := decodeExtraArgsV1V2(msg.ExtraArgs) + if err != nil { + panic(err) + } + + messageBytes := ConstantMessagePartBytes + + bytesForMsgTokens(numTokens) + + dataLength + + messageCallDataGas := uint64(messageBytes * CalldataGasPerByte) + + // Rate limiter only limits value in tokens. It's not called if there are no + // tokens in the message. The same goes for the admin registry, it's only loaded + // if there are tokens, and it's only loaded once. + rateLimiterOverhead := uint64(0) + adminRegistryOverhead := uint64(0) + if numTokens >= 1 { + rateLimiterOverhead = RateLimiterOverheadGas + adminRegistryOverhead = TokenAdminRegistryWarmupCost + } + + return messageGasLimit.Uint64() + + messageCallDataGas + + ExecutionStateProcessingOverheadGas + + SupportsInterfaceCheck + + adminRegistryOverhead + + rateLimiterOverhead + + PerTokenOverheadGas*uint64(numTokens) +} diff --git a/core/capabilities/ccip/ccipevm/gas_helpers_test.go b/core/capabilities/ccip/ccipevm/gas_helpers_test.go new file mode 100644 index 0000000000..f7897898fb --- /dev/null +++ b/core/capabilities/ccip/ccipevm/gas_helpers_test.go @@ -0,0 +1,157 @@ +package ccipevm + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" +) + +func Test_calculateMessageMaxGas(t *testing.T) { + type args struct { + dataLen int + numTokens int + extraArgs []byte + } + tests := []struct { + name string + args args + want uint64 + }{ + { + name: "base", + args: args{dataLen: 5, numTokens: 2, extraArgs: makeExtraArgsV1(200_000)}, + want: 1_022_264, + }, + { + name: "large", + args: args{dataLen: 1000, numTokens: 1000, extraArgs: makeExtraArgsV1(200_000)}, + want: 346_677_520, + }, + { + name: "overheadGas test 1", + args: args{dataLen: 0, numTokens: 0, extraArgs: makeExtraArgsV1(200_000)}, + want: 319_920, + }, + { + name: "overheadGas test 2", + args: args{dataLen: len([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}), numTokens: 1, extraArgs: makeExtraArgsV1(200_000)}, + want: 675_948, + }, + { + name: "allowOOO set to true makes no difference to final gas estimate", + args: args{dataLen: 5, numTokens: 2, extraArgs: makeExtraArgsV2(200_000, true)}, + want: 1_022_264, + }, + { + name: "allowOOO set to false makes no difference to final gas estimate", + args: args{dataLen: 5, numTokens: 2, extraArgs: makeExtraArgsV2(200_000, false)}, + want: 1_022_264, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + msg := ccipocr3.Message{ + Data: make([]byte, tt.args.dataLen), + TokenAmounts: make([]ccipocr3.RampTokenAmount, tt.args.numTokens), + ExtraArgs: tt.args.extraArgs, + } + ep := EstimateProvider{} + got := ep.CalculateMessageMaxGas(msg) + t.Log(got) + assert.Equalf(t, tt.want, got, "calculateMessageMaxGas(%v, %v)", tt.args.dataLen, tt.args.numTokens) + }) + } +} + +// TestCalculateMaxGas is taken from the ccip repo where the CalculateMerkleTreeGas and CalculateMessageMaxGas values +// are combined to one function. +func TestCalculateMaxGas(t *testing.T) { + tests := []struct { + name string + numRequests int + dataLength int + numberOfTokens int + extraArgs []byte + want uint64 + }{ + { + name: "maxGasOverheadGas 1", + numRequests: 6, + dataLength: 0, + numberOfTokens: 0, + extraArgs: makeExtraArgsV1(200_000), + want: 322_992, + }, + { + name: "maxGasOverheadGas 2", + numRequests: 3, + dataLength: len([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}), + numberOfTokens: 1, + extraArgs: makeExtraArgsV1(200_000), + want: 678_508, + }, + { + name: "v2 extra args", + numRequests: 3, + dataLength: len([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}), + numberOfTokens: 1, + extraArgs: makeExtraArgsV2(200_000, true), + want: 678_508, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + msg := ccipocr3.Message{ + Data: make([]byte, tt.dataLength), + TokenAmounts: make([]ccipocr3.RampTokenAmount, tt.numberOfTokens), + ExtraArgs: tt.extraArgs, + } + ep := EstimateProvider{} + + gotTree := ep.CalculateMerkleTreeGas(tt.numRequests) + gotMsg := ep.CalculateMessageMaxGas(msg) + t.Log("want", tt.want, "got", gotTree+gotMsg) + assert.Equal(t, tt.want, gotTree+gotMsg) + }) + } +} + +func makeExtraArgsV1(gasLimit uint64) []byte { + // extra args is the tag followed by the gas limit abi-encoded. + var extraArgs []byte + extraArgs = append(extraArgs, evmExtraArgsV1Tag...) + gasLimitBytes := new(big.Int).SetUint64(gasLimit).Bytes() + // pad from the left to 32 bytes + gasLimitBytes = common.LeftPadBytes(gasLimitBytes, 32) + extraArgs = append(extraArgs, gasLimitBytes...) + return extraArgs +} + +func makeExtraArgsV2(gasLimit uint64, allowOOO bool) []byte { + // extra args is the tag followed by the gas limit and allowOOO abi-encoded. + var extraArgs []byte + extraArgs = append(extraArgs, evmExtraArgsV2Tag...) + gasLimitBytes := new(big.Int).SetUint64(gasLimit).Bytes() + // pad from the left to 32 bytes + gasLimitBytes = common.LeftPadBytes(gasLimitBytes, 32) + + // abi-encode allowOOO + var allowOOOBytes []byte + if allowOOO { + allowOOOBytes = append(allowOOOBytes, 1) + } else { + allowOOOBytes = append(allowOOOBytes, 0) + } + // pad from the left to 32 bytes + allowOOOBytes = common.LeftPadBytes(allowOOOBytes, 32) + + extraArgs = append(extraArgs, gasLimitBytes...) + extraArgs = append(extraArgs, allowOOOBytes...) + return extraArgs +} diff --git a/core/capabilities/ccip/oraclecreator/inprocess.go b/core/capabilities/ccip/oraclecreator/inprocess.go index 6616d35675..fa74c1b0ea 100644 --- a/core/capabilities/ccip/oraclecreator/inprocess.go +++ b/core/capabilities/ccip/oraclecreator/inprocess.go @@ -8,6 +8,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccipevm" evmconfig "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/configs/evm" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ocrimpls" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/superfakes" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/ethereum/go-ethereum/common" @@ -310,6 +311,8 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp ccipevm.NewExecutePluginCodecV1(), ccipevm.NewMessageHasherV1(), i.homeChainReader, + superfakes.NewNilTokenDataReader(), + ccipevm.NewGasEstimateProvider(), // TODO: this works for evm only, how about non-evm? contractReaders, chainWriters, ) diff --git a/core/capabilities/ccip/superfakes/token_data_reader.go b/core/capabilities/ccip/superfakes/token_data_reader.go new file mode 100644 index 0000000000..ff6a88076c --- /dev/null +++ b/core/capabilities/ccip/superfakes/token_data_reader.go @@ -0,0 +1,23 @@ +package superfakes + +import ( + "context" + + "github.com/smartcontractkit/chainlink-ccip/execute/exectypes" + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" +) + +// NewNilTokenDataReader returns a new nilTokenDataReader. +// This token data reader always returns nil for the token data. +func NewNilTokenDataReader() exectypes.TokenDataReader { + return &nilTokenDataReader{} +} + +type nilTokenDataReader struct{} + +// ReadTokenData implements exectypes.TokenDataReader. +func (t *nilTokenDataReader) ReadTokenData(ctx context.Context, srcChain ccipocr3.ChainSelector, num ccipocr3.SeqNum) (r [][]byte, err error) { + return nil, nil +} + +var _ exectypes.TokenDataReader = (*nilTokenDataReader)(nil) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 52fd0e57f3..ccf4a2b32b 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -274,7 +274,7 @@ require ( github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index d32e7ddd71..b95551d8b2 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1070,8 +1070,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 h1:KKqMibl8CcKSyrSkVVfgGEOuC6Cn3vFQK8yMQA6FpxA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92/go.mod h1:wl0SRmyJ2ARxz+4Eho6nEXsmWFXxTSYpvcb30AxwKyE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 h1:XKEmg6dOkCsyNcW3R+IhhrUYdVJTKirLL2sCCgzRWjU= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/go.mod b/go.mod index efc4f413d3..fc89fbb06c 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa diff --git a/go.sum b/go.sum index 1c4f247f0e..5aa0189250 100644 --- a/go.sum +++ b/go.sum @@ -1027,8 +1027,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 h1:KKqMibl8CcKSyrSkVVfgGEOuC6Cn3vFQK8yMQA6FpxA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92/go.mod h1:wl0SRmyJ2ARxz+4Eho6nEXsmWFXxTSYpvcb30AxwKyE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 h1:XKEmg6dOkCsyNcW3R+IhhrUYdVJTKirLL2sCCgzRWjU= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index d044255c93..f3dab760f0 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -384,7 +384,7 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index ad987028f9..ad92b237b9 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1392,8 +1392,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 h1:KKqMibl8CcKSyrSkVVfgGEOuC6Cn3vFQK8yMQA6FpxA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92/go.mod h1:wl0SRmyJ2ARxz+4Eho6nEXsmWFXxTSYpvcb30AxwKyE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 h1:XKEmg6dOkCsyNcW3R+IhhrUYdVJTKirLL2sCCgzRWjU= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 2f647a5a6f..26c6dee721 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -40,7 +40,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect k8s.io/apimachinery v0.30.2 // indirect ) diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index d3074dba9f..244b2be8c5 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1374,8 +1374,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92 h1:KKqMibl8CcKSyrSkVVfgGEOuC6Cn3vFQK8yMQA6FpxA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806142433-6ae40054db92/go.mod h1:wl0SRmyJ2ARxz+4Eho6nEXsmWFXxTSYpvcb30AxwKyE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 h1:XKEmg6dOkCsyNcW3R+IhhrUYdVJTKirLL2sCCgzRWjU= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= From 8023fdae4a4f84d0ab5b0acf93f2a9397165c893 Mon Sep 17 00:00:00 2001 From: Ryan Hall Date: Mon, 12 Aug 2024 13:44:49 -0400 Subject: [PATCH 203/432] open zeppelin v 5 migration (#1281) ## Motivation Use the latest version of deps ## Solution Upgrade OZ deps to latest version ## Implementation Notes `IERC20` and `SafeERC20` are kept on `4.8.3` because of the `^0.8.20` requirement OZ imposes on the v5 contracts. We can't upgrade these deps until the rest of the contract codebase upgrades to 0.8.20+ --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/gas-snapshots/ccip.gas-snapshot | 278 +++++++++--------- contracts/src/v0.8/ccip/PriceRegistry.sol | 2 +- contracts/src/v0.8/ccip/RMN.sol | 2 +- contracts/src/v0.8/ccip/Router.sol | 2 +- .../v0.8/ccip/applications/CCIPReceiver.sol | 2 +- .../ccip/applications/DefensiveExample.sol | 2 +- .../src/v0.8/ccip/capability/CCIPConfig.sol | 4 +- contracts/src/v0.8/ccip/interfaces/IPool.sol | 2 +- .../v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 4 +- .../src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol | 2 +- .../src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol | 2 +- contracts/src/v0.8/ccip/pools/TokenPool.sol | 4 +- .../test/applications/ImmutableExample.t.sol | 2 +- .../v0.8/ccip/test/helpers/MultiTokenPool.sol | 4 +- .../receivers/MaybeRevertMessageReceiver.sol | 2 +- .../ccip/test/legacy/BurnMintTokenPool1_2.sol | 4 +- .../ccip/test/legacy/BurnMintTokenPool1_4.sol | 4 +- .../ccip/test/legacy/TokenPoolAndProxy.t.sol | 2 +- .../src/v0.8/ccip/test/mocks/MockRouter.sol | 2 +- .../test/pools/LockReleaseTokenPool.t.sol | 2 +- .../v0.8/ccip/test/pools/USDCTokenPool.t.sol | 2 +- .../tokenAdminRegistry/TokenAdminRegistry.sol | 2 +- .../generated/arm_contract/arm_contract.go | 2 +- .../burn_from_mint_token_pool.go | 2 +- .../burn_mint_token_pool.go | 2 +- .../burn_mint_token_pool_and_proxy.go | 2 +- .../burn_with_from_mint_token_pool.go | 2 +- .../ccip/generated/ccip_config/ccip_config.go | 2 +- .../evm_2_evm_multi_offramp.go | 2 +- .../evm_2_evm_offramp/evm_2_evm_offramp.go | 2 +- .../evm_2_evm_onramp/evm_2_evm_onramp.go | 2 +- .../lock_release_token_pool.go | 2 +- .../lock_release_token_pool_and_proxy.go | 2 +- .../price_registry/price_registry.go | 2 +- .../ccip/generated/router/router.go | 2 +- .../token_admin_registry.go | 2 +- .../usdc_token_pool/usdc_token_pool.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 30 +- 38 files changed, 196 insertions(+), 196 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index a2a322e545..e700bd984d 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -34,7 +34,7 @@ BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28761) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243517) BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 23951) -CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2132747) +CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2132726) CCIPConfigSetup:test_getCapabilityConfiguration_Success() (gas: 9517) CCIPConfig_ConfigStateMachine:test__computeConfigDigest_Success() (gas: 70831) CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_InitToRunning_Success() (gas: 363708) @@ -121,15 +121,15 @@ CommitStore_verify:test_NotBlessed_Success() (gas: 61374) CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) -DefensiveExampleTest:test_Recovery() (gas: 424253) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1104493) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38423) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 106249) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 87420) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 38957) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 96514) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 41963) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 88705) +DefensiveExampleTest:test_Recovery() (gas: 424256) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1104304) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38416) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 106228) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 87399) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 38936) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 96493) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 41942) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 88684) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 468131) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99235) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12399) @@ -138,19 +138,19 @@ EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Succ EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13267) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17992) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15347) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 296108) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 237498) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 156818) -EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187013) -EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 145410) -EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 518289) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 296045) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 237435) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 156797) +EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 186971) +EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 145389) +EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 518163) EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10439) EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15662) EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67354) EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59644) EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58724) -EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6524644) -EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 6107782) +EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6524844) +EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 6107982) EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106189) EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116101) EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106210) @@ -163,9 +163,9 @@ EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225643) EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117476) EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77540) EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 204935) -EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6518967) +EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6519167) EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47720) -EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 6111838) +EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 6112038) EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137047) EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103764) EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101635) @@ -173,85 +173,85 @@ EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139621) EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101534) EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101579) EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17302) -EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1552919) -EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 339300) -EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 257742) -EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6575061) -EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6157940) +EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1552289) +EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 339279) +EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 257679) +EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6575240) +EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6158119) EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 27703) -EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 163041) -EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147019) -EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6937113) +EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 163020) +EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 146998) +EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6937292) EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17155) EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18208) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 246620) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 246578) EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20468) -EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 205259) -EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48751) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48274) +EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 205217) +EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48730) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48253) EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229582) EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86220) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 277517) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92475) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 277454) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92454) EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35122) EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23922) -EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 454148) +EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 454064) EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54442) EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35911) EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154354) EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35333) -EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 179211) -EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 190495) +EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 179190) +EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 190474) EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48069) -EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 440888) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 249490) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 171682) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 191355) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259412) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 127423) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 389034) +EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 440867) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 249448) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 171640) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 191313) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259405) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 127402) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 388971) EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65866) EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80906) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 532146) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 477104) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 532020) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 476978) EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35738) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 517123) -EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 514491) -EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 484609) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 125852) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 155075) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 516997) +EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 514365) +EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 484483) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 125831) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 155054) EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3655340) EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118202) EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87461) EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75627) EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26467) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 162940) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205097) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 162919) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205055) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26010) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152936) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 505200) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2282834) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 207353) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 207930) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 657112) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 298887) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 164096) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 505158) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2282792) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 207311) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 207888) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 656902) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 298803) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 164054) EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 23740) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 64509) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 64488) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 39546) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 81533) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 176182) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 189384) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 81512) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 176140) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 189342) EVM2EVMMultiOffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11379) EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215352) EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14162) EVM2EVMMultiOffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11660) EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49203) EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27169) -EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 221738) -EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 230339) -EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 297319) -EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 279957) +EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 221696) +EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 230297) +EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 297256) +EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 279894) EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176552) EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178620) EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141481) @@ -297,87 +297,87 @@ EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 1 EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939) EVM2EVMMultiOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 51996) EVM2EVMMultiOnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97214) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37804) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103754) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85279) -EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 36807) -EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 94323) -EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 39789) -EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 86580) -EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 385392) -EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 141923) -EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 803421) -EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 179314) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37797) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103733) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85258) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 36786) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 94302) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 39768) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 86559) +EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 385308) +EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 141902) +EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 803211) +EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 179272) EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 29240) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 66465) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 66444) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 43320) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 211066) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 222330) -EVM2EVMOffRamp__report:test_Report_Success() (gas: 126658) -EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 237861) -EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246461) -EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 329947) -EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 312384) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 211024) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 222288) +EVM2EVMOffRamp__report:test_Report_Success() (gas: 126637) +EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 237819) +EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246419) +EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 329884) +EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 312321) EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17030) -EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153718) -EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5665738) -EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 144451) +EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153727) +EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5665947) +EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 144461) EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21318) EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36432) EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51598) -EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 473469) +EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 473385) EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 47668) EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152359) EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 102842) -EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 163825) -EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Success() (gas: 178226) +EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 163804) +EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Success() (gas: 178205) EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 42539) -EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 157389) -EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 172734) -EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 247076) -EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114174) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 407570) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 157347) +EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 172692) +EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 247069) +EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114153) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 407507) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54096) -EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 131068) +EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 131047) EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52090) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 563623) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 495746) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 563497) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 495620) EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35383) -EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 544879) +EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 544753) EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64326) -EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 122343) -EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 142553) -EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 427358) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 122322) +EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 142532) +EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 427337) EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18502) -EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 278195) +EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 278153) EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 18659) -EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 221491) -EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47902) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 47373) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 314036) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 70029) -EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 229361) -EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 276853) -EVM2EVMOffRamp_execute_upgrade:test_V2OffRampNonceSkipsIfMsgInFlight_Success() (gas: 258738) -EVM2EVMOffRamp_execute_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 226316) -EVM2EVMOffRamp_execute_upgrade:test_V2_Success() (gas: 130766) +EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 221449) +EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47881) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 47352) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 313973) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 70008) +EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 229319) +EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 276790) +EVM2EVMOffRamp_execute_upgrade:test_V2OffRampNonceSkipsIfMsgInFlight_Success() (gas: 258696) +EVM2EVMOffRamp_execute_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 226253) +EVM2EVMOffRamp_execute_upgrade:test_V2_Success() (gas: 130745) EVM2EVMOffRamp_getAllRateLimitTokens:test_GetAllRateLimitTokens_Success() (gas: 38446) EVM2EVMOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3247348) EVM2EVMOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 83333) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 185871) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 185829) EVM2EVMOffRamp_manuallyExecute:test_ManualExecForkedChain_Revert() (gas: 27049) EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 45155) EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 27468) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithMultipleMessagesAndSourceTokens_Success() (gas: 530389) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithSourceTokens_Success() (gas: 345877) -EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187366) -EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2321976) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DestinationGasAmountCountMismatch_Revert() (gas: 363084) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143921) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_InvalidTokenGasOverride_Revert() (gas: 366223) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimitManualExec_Success() (gas: 482733) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 189769) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithInvalidReceiverExecutionGasOverride_Revert() (gas: 153662) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithMultipleMessagesAndSourceTokens_Success() (gas: 530263) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithSourceTokens_Success() (gas: 345814) +EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187324) +EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2321934) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DestinationGasAmountCountMismatch_Revert() (gas: 363021) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143900) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_InvalidTokenGasOverride_Revert() (gas: 366160) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimitManualExec_Success() (gas: 482691) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 189727) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithInvalidReceiverExecutionGasOverride_Revert() (gas: 153641) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithInvalidSourceTokenDataCount_Revert() (gas: 59894) EVM2EVMOffRamp_metadataHash:test_MetadataHash_Success() (gas: 8838) EVM2EVMOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 40153) @@ -612,18 +612,18 @@ MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 393335) -MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1385041) +MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1384852) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71847) -NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 249575) -NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 251766) -NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 304556) -NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 287608) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244887) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 233207) -NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 142568) +NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 249533) +NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 251724) +NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 304493) +NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 287566) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244824) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 233144) +NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 142547) NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 167625) NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 218724) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) @@ -681,10 +681,10 @@ PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfi PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeZeroInput() (gas: 13089) PriceRegistry_applyTokenTransferFeeConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 17071) PriceRegistry_applyTokenTransferFeeConfigUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 12240) -PriceRegistry_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 100407) -PriceRegistry_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 104757) -PriceRegistry_constructor:test_InvalidStalenessThreshold_Revert() (gas: 104810) -PriceRegistry_constructor:test_Setup_Success() (gas: 4615196) +PriceRegistry_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 100474) +PriceRegistry_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 104824) +PriceRegistry_constructor:test_InvalidStalenessThreshold_Revert() (gas: 104877) +PriceRegistry_constructor:test_Setup_Success() (gas: 4637091) PriceRegistry_convertTokenAmount:test_ConvertTokenAmount_Success() (gas: 72751) PriceRegistry_convertTokenAmount:test_LinkTokenNotSupported_Revert() (gas: 30981) PriceRegistry_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 95587) diff --git a/contracts/src/v0.8/ccip/PriceRegistry.sol b/contracts/src/v0.8/ccip/PriceRegistry.sol index c6250d7bc9..f40f604e83 100644 --- a/contracts/src/v0.8/ccip/PriceRegistry.sol +++ b/contracts/src/v0.8/ccip/PriceRegistry.sol @@ -11,7 +11,7 @@ import {Internal} from "./libraries/Internal.sol"; import {Pool} from "./libraries/Pool.sol"; import {USDPriceWith18Decimals} from "./libraries/USDPriceWith18Decimals.sol"; -import {EnumerableSet} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; +import {EnumerableSet} from "../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; /// @notice The PriceRegistry contract responsibility is to store the current gas price in USD for a given destination chain, /// and the price of a token in USD allowing the owner or priceUpdater to update this value. diff --git a/contracts/src/v0.8/ccip/RMN.sol b/contracts/src/v0.8/ccip/RMN.sol index 12ba95e0d2..ef672bb7ab 100644 --- a/contracts/src/v0.8/ccip/RMN.sol +++ b/contracts/src/v0.8/ccip/RMN.sol @@ -6,7 +6,7 @@ import {IRMN} from "./interfaces/IRMN.sol"; import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol"; -import {EnumerableSet} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; +import {EnumerableSet} from "../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; // An active curse on this subject will cause isCursed() to return true. Use this subject if there is an issue with a // remote chain, for which there exists a legacy lane contract deployed on the same chain as this RMN contract is diff --git a/contracts/src/v0.8/ccip/Router.sol b/contracts/src/v0.8/ccip/Router.sol index e50651bc5b..a5474fdd04 100644 --- a/contracts/src/v0.8/ccip/Router.sol +++ b/contracts/src/v0.8/ccip/Router.sol @@ -16,7 +16,7 @@ import {Internal} from "./libraries/Internal.sol"; import {IERC20} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; -import {EnumerableSet} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; +import {EnumerableSet} from "../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; /// @title Router /// @notice This is the entry point for the end user wishing to send data across chains. diff --git a/contracts/src/v0.8/ccip/applications/CCIPReceiver.sol b/contracts/src/v0.8/ccip/applications/CCIPReceiver.sol index 7011f814de..1d4937c77a 100644 --- a/contracts/src/v0.8/ccip/applications/CCIPReceiver.sol +++ b/contracts/src/v0.8/ccip/applications/CCIPReceiver.sol @@ -5,7 +5,7 @@ import {IAny2EVMMessageReceiver} from "../interfaces/IAny2EVMMessageReceiver.sol import {Client} from "../libraries/Client.sol"; -import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol"; /// @title CCIPReceiver - Base contract for CCIP applications that can receive messages. abstract contract CCIPReceiver is IAny2EVMMessageReceiver, IERC165 { diff --git a/contracts/src/v0.8/ccip/applications/DefensiveExample.sol b/contracts/src/v0.8/ccip/applications/DefensiveExample.sol index 54e1e80946..30b0972bb3 100644 --- a/contracts/src/v0.8/ccip/applications/DefensiveExample.sol +++ b/contracts/src/v0.8/ccip/applications/DefensiveExample.sol @@ -8,7 +8,7 @@ import {CCIPClientExample} from "./CCIPClientExample.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; -import {EnumerableMap} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableMap.sol"; +import {EnumerableMap} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableMap.sol"; contract DefensiveExample is CCIPClientExample { using EnumerableMap for EnumerableMap.Bytes32ToUintMap; diff --git a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol index 9a88c4bccd..245a9ef737 100644 --- a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol +++ b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol @@ -11,8 +11,8 @@ import {SortedSetValidationUtil} from "../../shared/util/SortedSetValidationUtil import {Internal} from "../libraries/Internal.sol"; import {CCIPConfigTypes} from "./libraries/CCIPConfigTypes.sol"; -import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC165.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; /// @notice CCIPConfig stores the configuration for the CCIP capability. /// We have two classes of configuration: chain configuration and DON (in the CapabilitiesRegistry sense) configuration. diff --git a/contracts/src/v0.8/ccip/interfaces/IPool.sol b/contracts/src/v0.8/ccip/interfaces/IPool.sol index fee010173f..e01f5fe38e 100644 --- a/contracts/src/v0.8/ccip/interfaces/IPool.sol +++ b/contracts/src/v0.8/ccip/interfaces/IPool.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import {Pool} from "../libraries/Pool.sol"; -import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol"; /// @notice Shared public interface for multiple V1 pool types. /// Each pool type handles a different child token model (lock/unlock, mint/burn.) diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol index 250bec4428..7fe7e82ca1 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -19,8 +19,8 @@ import {MerkleMultiProof} from "../libraries/MerkleMultiProof.sol"; import {Pool} from "../libraries/Pool.sol"; import {MultiOCR3Base} from "../ocr/MultiOCR3Base.sol"; -import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -import {ERC165Checker} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/IERC20.sol"; +import {ERC165Checker} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165Checker.sol"; /// @notice EVM2EVMOffRamp enables OCR networks to execute multiple messages /// in an OffRamp in a single transaction. diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol index 1856cd5423..fccec3334f 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol @@ -21,7 +21,7 @@ import {RateLimiter} from "../libraries/RateLimiter.sol"; import {OCR2BaseNoChecks} from "../ocr/OCR2BaseNoChecks.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -import {ERC165Checker} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol"; +import {ERC165Checker} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165Checker.sol"; /// @notice EVM2EVMOffRamp enables OCR networks to execute multiple messages /// in an OffRamp in a single transaction. diff --git a/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol b/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol index 50df00712d..8ccd94b5e9 100644 --- a/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol @@ -19,7 +19,7 @@ import {USDPriceWith18Decimals} from "../libraries/USDPriceWith18Decimals.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; -import {EnumerableMap} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableMap.sol"; +import {EnumerableMap} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableMap.sol"; /// @notice The onRamp is a contract that handles lane-specific fee logic, NOP payments and /// bridgeable token support. diff --git a/contracts/src/v0.8/ccip/pools/TokenPool.sol b/contracts/src/v0.8/ccip/pools/TokenPool.sol index c0c6f2198d..0b87b6dfcb 100644 --- a/contracts/src/v0.8/ccip/pools/TokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/TokenPool.sol @@ -10,8 +10,8 @@ import {Pool} from "../libraries/Pool.sol"; import {RateLimiter} from "../libraries/RateLimiter.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; -import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; /// @notice Base abstract class with common functions for all token pools. /// A token pool serves as isolated place for holding tokens and token specific logic diff --git a/contracts/src/v0.8/ccip/test/applications/ImmutableExample.t.sol b/contracts/src/v0.8/ccip/test/applications/ImmutableExample.t.sol index eb12e6205a..0fb47b1f9b 100644 --- a/contracts/src/v0.8/ccip/test/applications/ImmutableExample.t.sol +++ b/contracts/src/v0.8/ccip/test/applications/ImmutableExample.t.sol @@ -8,7 +8,7 @@ import {EVM2EVMOnRampSetup} from "../onRamp/EVM2EVMOnRampSetup.t.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; import {ERC165Checker} from - "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol"; + "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165Checker.sol"; contract CCIPClientExample_sanity is EVM2EVMOnRampSetup { function test_ImmutableExamples_Success() public { diff --git a/contracts/src/v0.8/ccip/test/helpers/MultiTokenPool.sol b/contracts/src/v0.8/ccip/test/helpers/MultiTokenPool.sol index 0f7c312f71..3aaacfe22a 100644 --- a/contracts/src/v0.8/ccip/test/helpers/MultiTokenPool.sol +++ b/contracts/src/v0.8/ccip/test/helpers/MultiTokenPool.sol @@ -10,8 +10,8 @@ import {Pool} from "../../libraries/Pool.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; -import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol"; +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; /// @notice This contract is a proof of concept and should NOT be used in production. abstract contract MultiTokenPool is IPoolV1, OwnerIsCreator { diff --git a/contracts/src/v0.8/ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol b/contracts/src/v0.8/ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol index dd65f202df..01b9b77d37 100644 --- a/contracts/src/v0.8/ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol +++ b/contracts/src/v0.8/ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.24; import {IAny2EVMMessageReceiver} from "../../../interfaces/IAny2EVMMessageReceiver.sol"; import {Client} from "../../../libraries/Client.sol"; -import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; +import {IERC165} from "../../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol"; contract MaybeRevertMessageReceiver is IAny2EVMMessageReceiver, IERC165 { error ReceiveRevert(); diff --git a/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_2.sol b/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_2.sol index 2e7878730e..444e488b3c 100644 --- a/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_2.sol +++ b/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_2.sol @@ -10,8 +10,8 @@ import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; -import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol"; +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; /// @notice Base abstract class with common functions for all token pools. /// A token pool serves as isolated place for holding tokens and token specific logic diff --git a/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_4.sol b/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_4.sol index 9ac5d66b1c..9e80438239 100644 --- a/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_4.sol +++ b/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_4.sol @@ -11,8 +11,8 @@ import {OwnerIsCreator} from "../../../shared/access/OwnerIsCreator.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; -import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol"; +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; /// @notice Base abstract class with common functions for all token pools. /// A token pool serves as isolated place for holding tokens and token specific logic diff --git a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol index 8abb758497..1df73ff582 100644 --- a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol +++ b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol @@ -21,7 +21,7 @@ import {BurnMintTokenPool1_2, TokenPool1_2} from "./BurnMintTokenPool1_2.sol"; import {BurnMintTokenPool1_4, TokenPool1_4} from "./BurnMintTokenPool1_4.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol"; contract TokenPoolAndProxyMigration is EVM2EVMOnRampSetup { BurnMintTokenPoolAndProxy internal s_newPool; diff --git a/contracts/src/v0.8/ccip/test/mocks/MockRouter.sol b/contracts/src/v0.8/ccip/test/mocks/MockRouter.sol index 87db031951..050cd6d457 100644 --- a/contracts/src/v0.8/ccip/test/mocks/MockRouter.sol +++ b/contracts/src/v0.8/ccip/test/mocks/MockRouter.sol @@ -12,7 +12,7 @@ import {Internal} from "../../libraries/Internal.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; import {ERC165Checker} from - "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol"; + "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165Checker.sol"; contract MockCCIPRouter is IRouter, IRouterClient { using SafeERC20 for IERC20; diff --git a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol index 6af905cfe5..fb5d5e0fd1 100644 --- a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol @@ -14,7 +14,7 @@ import {TokenPool} from "../../pools/TokenPool.sol"; import {BaseTest} from "../BaseTest.t.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol"; import {RouterSetup} from "../router/RouterSetup.t.sol"; contract LockReleaseTokenPoolSetup is RouterSetup { diff --git a/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol index 2ced91fac3..7259e1d17c 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol @@ -17,7 +17,7 @@ import {USDCTokenPoolHelper} from "../helpers/USDCTokenPoolHelper.sol"; import {MockE2EUSDCTransmitter} from "../mocks/MockE2EUSDCTransmitter.sol"; import {MockUSDCTokenMessenger} from "../mocks/MockUSDCTokenMessenger.sol"; -import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol"; contract USDCTokenPoolSetup is BaseTest { IBurnMintERC20 internal s_token; diff --git a/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenAdminRegistry.sol b/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenAdminRegistry.sol index 2d1a406736..fd995ca96a 100644 --- a/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenAdminRegistry.sol +++ b/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenAdminRegistry.sol @@ -7,7 +7,7 @@ import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol"; import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; -import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; /// @notice This contract stores the token pool configuration for all CCIP enabled tokens. It works /// on a self-serve basis, where tokens can be registered without intervention from the CCIP owner. diff --git a/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go b/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go index 3a3ee0a3c0..6e225576c1 100644 --- a/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go +++ b/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go @@ -70,7 +70,7 @@ type RMNVoter struct { var ARMContractMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"}],\"name\":\"ReusedCurseId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubjectsMustBeStrictlyIncreasing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"}],\"name\":\"UnauthorizedVoter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnvoteToCurseNoop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VoteToBlessForbiddenDuringActiveGlobalCurse\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VoteToBlessNoop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VoteToCurseNoop\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"AlreadyBlessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"AlreadyVotedToBless\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"CurseLifted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"blockTimestamp\",\"type\":\"uint64\"}],\"name\":\"Cursed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"}],\"name\":\"PermaBlessedCommitStoreAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"}],\"name\":\"PermaBlessedCommitStoreRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"onchainCursesHash\",\"type\":\"bytes28\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"}],\"name\":\"SkippedUnvoteToCurse\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"wasBlessed\",\"type\":\"bool\"}],\"name\":\"TaggedRootBlessVotesReset\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"}],\"name\":\"TaggedRootBlessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"weight\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"remainingAccumulatedWeight\",\"type\":\"uint16\"}],\"name\":\"UnvotedToCurse\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"weight\",\"type\":\"uint8\"}],\"name\":\"VotedToBless\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"weight\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"blockTimestamp\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"}],\"name\":\"VotedToCurse\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"getBlessProgress\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"blessVoteAddrs\",\"type\":\"address[]\"},{\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"blessed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"getCurseProgress\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"curseVoteAddrs\",\"type\":\"address[]\"},{\"internalType\":\"bytes28[]\",\"name\":\"cursesHashes\",\"type\":\"bytes28[]\"},{\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"cursed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCursedSubjectsCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPermaBlessedCommitStores\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"getRecordedCurseRelatedOps\",\"outputs\":[{\"components\":[{\"internalType\":\"enumRMN.RecordedCurseRelatedOpTag\",\"name\":\"tag\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"blockTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"cursed\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"}],\"internalType\":\"structRMN.RecordedCurseRelatedOp[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRecordedCurseRelatedOpsCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16[]\",\"name\":\"subjects\",\"type\":\"bytes16[]\"}],\"name\":\"ownerCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"ownerRemoveThenAddPermaBlessedCommitStores\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot[]\",\"name\":\"taggedRoots\",\"type\":\"tuple[]\"}],\"name\":\"ownerResetBlessVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"}],\"internalType\":\"structRMN.UnvoteToCurseRequest\",\"name\":\"unit\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"forceUnvote\",\"type\":\"bool\"}],\"internalType\":\"structRMN.OwnerUnvoteToCurseRequest[]\",\"name\":\"ownerUnvoteToCurseRequests\",\"type\":\"tuple[]\"}],\"name\":\"ownerUnvoteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"}],\"internalType\":\"structRMN.UnvoteToCurseRequest[]\",\"name\":\"unvoteToCurseRequests\",\"type\":\"tuple[]\"}],\"name\":\"unvoteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot[]\",\"name\":\"taggedRoots\",\"type\":\"tuple[]\"}],\"name\":\"voteToBless\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16[]\",\"name\":\"subjects\",\"type\":\"bytes16[]\"}],\"name\":\"voteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b506040516200596238038062005962833981016040819052620000349162000aff565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000138565b505060408051608081018252600080825260208201819052918101919091526001600160c81b03606082015290506001620000fb81601062000c7d565b82606001516001600160c81b0316901c6001600160c81b0316101562000125576200012562000c99565b506200013181620001e3565b5062000e14565b336001600160a01b03821603620001925760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001ee816200071d565b6200020c576040516306b7c75960e31b815260040160405180910390fd5b602081015160038054604084015161ffff908116620100000263ffffffff199092169316929092179190911790555b60025415620003465760028054600091906200025a9060019062000c7d565b815481106200026d576200026d62000caf565b6000918252602080832060408051608081018252600294850290920180546001600160a01b0390811680855260019092015480821685870190815260ff600160a01b8304811687870152600160a81b909204909116606086015291875260058552828720805465ffffffffffff19169055905116855260099092529220805461ffff191690558054919250908062000309576200030962000cc5565b60008281526020902060026000199092019182020180546001600160a01b031916815560010180546001600160b01b03191690559055506200023b565b60005b81515181101562000403578151805160029190839081106200036f576200036f62000caf565b602090810291909101810151825460018181018555600094855293839020825160029092020180546001600160a01b039283166001600160a01b0319909116178155928201519284018054604084015160609094015160ff908116600160a81b0260ff60a81b1991909516600160a01b026001600160a81b0319909216959093169490941793909317161790550162000349565b50600480546000906200041c9063ffffffff1662000cdb565b82546101009290920a63ffffffff8181021990931691831602179091556004541660005b82515160ff821610156200054157600083600001518260ff16815181106200046c576200046c62000caf565b602090810291909101810151604080516060808201835263ffffffff80891683528385015160ff90811684880190815289821685870190815287516001600160a01b03908116600090815260058b5288812097518854945193518616650100000000000260ff60281b199487166401000000000264ffffffffff1990961691909716179390931791909116939093179094558587015190911683526009909552919020805491909201519092166101000261ffff1990921691909117600117905550620005398162000d01565b905062000440565b506001600160a01b0360005260096020527f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a7805461ffff191660011790556004805463ffffffff4381166401000000000263ffffffff60201b1990921691909117909155604051908216907f8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a990620005db90859062000d23565b60405180910390a26040805160c08101825260048082526001600160401b03421660208301526000928201839052606082018390526080820183905260a08201839052600c80546001808201835591909452825160029094027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018054939490939092849260ff19909216919084908111156200067c576200067c62000dce565b021790555060208201518154604084015160608501516001600160a01b03166a010000000000000000000002600160501b600160f01b031991151569010000000000000000000260ff60481b196001600160401b039095166101000294909416610100600160501b031990931692909217929092179190911617815560808083015160a090930151811c600160801b0292901c919091176001909101555050565b80515160009015806200073257508151516010105b80620007445750602082015161ffff16155b80620007565750604082015161ffff16155b156200076457506000919050565b600080600084600001515160026200077d919062000de4565b6001600160401b0381111562000797576200079762000a24565b604051908082528060200260200182016040528015620007c1578160200160208202803683370190505b50905060005b8551518110156200095457600086600001518281518110620007ed57620007ed62000caf565b6020026020010151905060006001600160a01b031681600001516001600160a01b0316148062000828575060208101516001600160a01b0316155b806200083f575060208101516001600160a01b0316155b8062000858575060208101516001600160a01b03908116145b806200087a5750604081015160ff161580156200087a5750606081015160ff16155b156200088d575060009695505050505050565b8051836200089d84600262000de4565b620008aa90600062000dfe565b81518110620008bd57620008bd62000caf565b6001600160a01b0390921660209283029190910182015281015183620008e584600262000de4565b620008f290600162000dfe565b8151811062000905576200090562000caf565b6001600160a01b03909216602092830291909101909101526040810151620009319060ff168662000dfe565b9450806060015160ff168462000948919062000dfe565b935050600101620007c7565b5060005b8151811015620009f957600082828151811062000979576200097962000caf565b60200260200101519050600082600162000994919062000dfe565b90505b8351811015620009ee57838181518110620009b657620009b662000caf565b60200260200101516001600160a01b0316826001600160a01b031603620009e557506000979650505050505050565b60010162000997565b505060010162000958565b50846020015161ffff16831015801562000a1b5750846040015161ffff168210155b95945050505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b038111828210171562000a5f5762000a5f62000a24565b60405290565b604051608081016001600160401b038111828210171562000a5f5762000a5f62000a24565b604051601f8201601f191681016001600160401b038111828210171562000ab55762000ab562000a24565b604052919050565b80516001600160a01b038116811462000ad557600080fd5b919050565b805160ff8116811462000ad557600080fd5b805161ffff8116811462000ad557600080fd5b6000602080838503121562000b1357600080fd5b82516001600160401b038082111562000b2b57600080fd5b8185019150606080838803121562000b4257600080fd5b62000b4c62000a3a565b83518381111562000b5c57600080fd5b8401601f8101891362000b6e57600080fd5b80518481111562000b835762000b8362000a24565b62000b93878260051b0162000a8a565b818152878101955060079190911b82018701908a82111562000bb457600080fd5b918701915b8183101562000c33576080838c03121562000bd45760008081fd5b62000bde62000a65565b62000be98462000abd565b815262000bf889850162000abd565b89820152604062000c0b81860162000ada565b9082015262000c1c84870162000ada565b818701528652948701946080929092019162000bb9565b83525062000c45905084860162000aec565b8582015262000c576040850162000aec565b6040820152979650505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000c935762000c9362000c67565b92915050565b634e487b7160e01b600052600160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600063ffffffff80831681810362000cf75762000cf762000c67565b6001019392505050565b600060ff821660ff810362000d1a5762000d1a62000c67565b60010192915050565b60006020808352608080840185516060808588015282825180855260a0890191508684019450600093505b8084101562000da157845180516001600160a01b03908116845288820151168884015260408082015160ff9081169185019190915290840151168383015293860193600193909301929085019062000d4e565b509488015161ffff8116604089015294604089015161ffff811660608a0152955098975050505050505050565b634e487b7160e01b600052602160045260246000fd5b808202811582820484141762000c935762000c9362000c67565b8082018082111562000c935762000c9362000c67565b614b3e8062000e246000396000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063631ec73e116100d8578063979986111161008c578063d927f26711610066578063d927f26714610354578063f2fde38b14610374578063f33f28951461038757600080fd5b8063979986111461030b578063ba86a1f01461031e578063bd147ef41461033157600080fd5b806379ba5097116100bd57806379ba5097146102d35780638da5cb5b146102db578063970b8fc21461030357600080fd5b8063631ec73e146102ad5780636ba0526d146102c057600080fd5b8063397796f71161013a5780634102e4f4116101145780634102e4f4146102745780634d61677114610287578063586abe3c1461029a57600080fd5b8063397796f7146102425780633d0cf6101461024a5780633f42ab731461025d57600080fd5b8063181f5a771161016b578063181f5a77146101ba5780632cbc26bb14610203578063328d716c1461022657600080fd5b80630b009be21461018757806315c65588146101a5575b600080fd5b61018f6103a9565b60405161019c9190613e3f565b60405180910390f35b6101b86101b3366004613fdd565b6103ba565b005b6101f66040518060400160405280600981526020017f524d4e20312e352e30000000000000000000000000000000000000000000000081525081565b60405161019c9190614083565b6102166102113660046140f0565b6104e6565b604051901515815260200161019c565b600b5467ffffffffffffffff165b60405190815260200161019c565b6102166105b1565b6101b86102583660046141a0565b61068b565b6102656107ff565b60405161019c939291906142b3565b6101b86102823660046142ff565b610929565b610216610295366004614439565b61093d565b6101b86102a8366004614451565b6109cd565b6101b86102bb3660046144fc565b610a87565b6101b86102ce366004614451565b610ca0565b6101b8610d13565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019c565b600c54610234565b6101b86103193660046145d0565b610e10565b6101b861032c3660046145d0565b611368565b61034461033f3660046140f0565b61150d565b60405161019c9493929190614645565b6103676103623660046146b6565b611946565b60405161019c9190614707565b6101b8610382366004614800565b611b68565b61039a610395366004614439565b611b79565b60405161019c9392919061481b565b60606103b56007611de1565b905090565b336000818152600960205260409020805460ff16610421576040517f85412e7f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b60045463ffffffff166000805b85518110156104a757600086828151811061044b5761044b614849565b602002602001015190506000610465858360000151611df5565b905060008061047b6001888b8760008d89611fd6565b91509150801561048d5761048d614878565b85806104965750815b95505050505080600101905061042e565b50806104df576040517ffb106b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b600b5460009067ffffffffffffffff16810361050457506000919050565b7f0100000000000000000000000000000100000000000000000000000000000000600052600a6020527fcf943f0e419056430919a3fdfd72276bc0b123ebdd670f4152b82bffbfb8bb385468010000000000000000900460ff16806105a657507fffffffffffffffffffffffffffffffff0000000000000000000000000000000082166000908152600a602052604090205468010000000000000000900460ff165b92915050565b919050565b600b5460009067ffffffffffffffff1681036105cd5750600090565b7f0100000000000000000000000000000100000000000000000000000000000000600052600a6020527fcf943f0e419056430919a3fdfd72276bc0b123ebdd670f4152b82bffbfb8bb385468010000000000000000900460ff16806103b55750507f0100000000000000000000000000000000000000000000000000000000000000600052600a6020527f1d4cd6d2639449a552dbfb463b59316946d78c518b3170daa4a4c217bef019ba5468010000000000000000900460ff1690565b6106936126a4565b60005b8251811015610746576106cc8382815181106106b4576106b4614849565b6020026020010151600761272790919063ffffffff16565b1561073e577fdca892154bbc36d0c05ccd01b3d0411875cb1b841fcdeebb384e5d0d6eb06b4483828151811061070457610704614849565b6020026020010151604051610735919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a15b600101610696565b5060005b81518110156107fa5761078082828151811061076857610768614849565b6020026020010151600761274990919063ffffffff16565b156107f2577f66b4b4752c65ae8cd2f3a0a48c7dc8b2118c60d5ea15514992eb2ddf56c9cb158282815181106107b8576107b8614849565b60200260200101516040516107e9919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a15b60010161074a565b505050565b6040805160608082018352808252600060208084018290528385018290526004548551600280549384028201608090810190985294810183815263ffffffff808416986401000000009094041696959194919385939192859285015b828210156108f95760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff740100000000000000000000000000000000000000008204811693850193909352750100000000000000000000000000000000000000000090049091166060830152908352909201910161085b565b505050908252506001919091015461ffff8082166020840152620100009091041660409091015292939192919050565b6109316126a4565b61093a8161276b565b50565b600060068161099b610954368690038601866148a7565b80516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b815260208101919091526040016000205460ff16806105a657506105a66109c56020840184614800565b600790612eef565b337fffffffffffffffffffffffff000000000000000000000000000000000000000181016109fd576109fd614878565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600960205260409020805460ff16610a75576040517f85412e7f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610418565b610a8182858584612f1e565b50505050565b610a8f6126a4565b600454600090819063ffffffff16815b8451811015610b66576000858281518110610abc57610abc614849565b602002602001015190506000610ada84836020015160000151611df5565b9050600080610b3d600087866000015187602001518860400151600960008b6000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002089611fd6565b915091508680610b4a5750815b96508780610b555750805b975050505050806001019050610a9f565b508215610c615760408051600280546080602082028401810190945260608301818152610c61948492849160009085015b82821015610c355760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff7401000000000000000000000000000000000000000082048116938501939093527501000000000000000000000000000000000000000000900490911660608301529083529092019101610b97565b505050908252506001919091015461ffff8082166020840152620100009091041660409091015261276b565b8180610c6a5750825b610a81576040517ffb106b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca86126a4565b73ffffffffffffffffffffffffffffffffffffffff60005260096020527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a7610a8182858584612f1e565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610418565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e397f01000000000000000000000000000001000000000000000000000000000000006104e6565b15610e70576040517fcde2d97c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454336000908152600560209081526040918290208251606081018452905463ffffffff81811680845260ff64010000000084048116958501959095526501000000000090920490931693820193909352921691908214610f00576040517f85412e7f000000000000000000000000000000000000000000000000000000008152336004820152602401610418565b600160005b8481101561132f576000868683818110610f2157610f21614849565b905060400201803603810190610f3791906148a7565b90506000610f868280516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b6000818152600660209081526040918290208251608081018452905460ff81161580158352610100820463ffffffff169383019390935265010000000000810461ffff169382019390935267010000000000000090920478ffffffffffffffffffffffffffffffffffffffffffffffffff16606083015291925090611062573373ffffffffffffffffffffffffffffffffffffffff168763ffffffff167f274d6d5b916b0a53974b7ab86c844b97a2e03a60f658cd9a4b1c028b604d7bf18560405161105291906148e0565b60405180910390a3505050611327565b8663ffffffff16816020015163ffffffff16146110a8575060408051608081018252600080825263ffffffff89166020830152918101829052606081019190915261110c565b6110ba816060015187604001516136d6565b1561110c573373ffffffffffffffffffffffffffffffffffffffff168763ffffffff167f6dfbb745226fa630aeb1b9557d17d508ddb789a04f0cb873ec16e58beb8beead8560405161105291906148e0565b6000945061112281606001518760400151613718565b78ffffffffffffffffffffffffffffffffffffffffffffffffff166060820152602086015160408201805160ff9092169161115e90839061493c565b61ffff1690525060208681015160408051865173ffffffffffffffffffffffffffffffffffffffff168152868401519381019390935260ff9091168282015251339163ffffffff8a16917f2a08a2bd2798f0aae9a843f0f4ad4de488c1b3d5f04049940cfed736ad69fb979181900360600190a3600354604082015161ffff91821691161061125757600181526040808201518151855173ffffffffffffffffffffffffffffffffffffffff1681526020808701519082015261ffff90911681830152905163ffffffff8916917f8257378aa73bf8e4ada848713526584a3dcee0fd3db3beed7397f7a7f5067cc9919081900360600190a25b60009182526006602090815260409283902082518154928401519484015160609094015178ffffffffffffffffffffffffffffffffffffffffffffffffff166701000000000000000266ffffffffffffff61ffff90951665010000000000029490941664ffffffffff63ffffffff909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090941693909317179390931617179055505b600101610f05565b5080156104df576040517f604c767700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113706126a4565b60045463ffffffff1660005b82811015610a8157600084848381811061139857611398614849565b9050604002018036038101906113ae91906148a7565b905060006113fd8280516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b60008181526006602081815260408084208151608081018352815460ff811615158252610100810463ffffffff90811683870190815265010000000000830461ffff169584019590955267010000000000000090910478ffffffffffffffffffffffffffffffffffffffffffffffffff16606083015287875294909352939093558051925193945092878216911614806114945750805b156114fe5760408051855173ffffffffffffffffffffffffffffffffffffffff1681526020808701519082015282151581830152905163ffffffff8816917f7d15a6eebaa019ea7d5b7d38937c51ebd3befbfdf51bb630a694fd28635bbcba919081900360600190a25b5050505080600101905061137c565b600454604080516002805460806020820284018101909452606083810182815290958695600095869563ffffffff9093169486949193928492918491879085015b828210156115ec5760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff740100000000000000000000000000000000000000008204811693850193909352750100000000000000000000000000000000000000000090049091166060830152908352909201910161154e565b505050908252506001919091015461ffff80821660208085019190915262010000909204166040928301527fffffffffffffffffffffffffffffffff000000000000000000000000000000008a166000908152600a909152908120805460ff6801000000000000000082041696509293509163ffffffff80861691161080156116725750845b6000965090508560015b60028111611939578451515b6000808760000151518310156116e35787518051849081106116ac576116ac614849565b6020026020010151602001519150876000015183815181106116d0576116d0614849565b602002602001015160600151905061170a565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905060005b73ffffffffffffffffffffffffffffffffffffffff82166000908152600188016020908152604080832081518083019092525463ffffffff811682526401000000009004821b63ffffffff19169181019190915290878061177a57508a63ffffffff16826000015163ffffffff16145b8061179a575073ffffffffffffffffffffffffffffffffffffffff848116145b80156117b05750602082015163ffffffff191615155b9050801561186d57856001036117d0576117c987614957565b965061186d565b85600203610182576117e560ff84168e61493c565b9c506117f08761498f565b9650838f888151811061180557611805614849565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505081602001518e888151811061185657611856614849565b63ffffffff19909216602092830291909101909101525b84156118835761187c8561498f565b945061188c565b50505050611895565b50505050611688565b81600103611928578267ffffffffffffffff8111156118b6576118b6613e52565b6040519080825280602002602001820160405280156118df578160200160208202803683370190505b509a508267ffffffffffffffff8111156118fb576118fb613e52565b604051908082528060200260200182016040528015611924578160200160208202803683370190505b5099505b5061193281614957565b905061167c565b5050505050509193509193565b600c5460609060009061195984866149c4565b11611965575081611988565b600c5484101561198457600c5461197d9085906149d7565b9050611988565b5060005b60008167ffffffffffffffff8111156119a3576119a3613e52565b604051908082528060200260200182016040528015611a2157816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816119c15790505b50905060005b82811015611b5f57600c611a3b82886149c4565b81548110611a4b57611a4b614849565b600091825260209091206040805160c081019091526002909202018054829060ff166004811115611a7e57611a7e6146d8565b6004811115611a8f57611a8f6146d8565b81528154610100810467ffffffffffffffff1660208301526901000000000000000000810460ff16151560408301526a0100000000000000000000900473ffffffffffffffffffffffffffffffffffffffff166060820152600190910154608081811b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000090811682850152700100000000000000000000000000000000909204901b1660a0909101528251839083908110611b4c57611b4c614849565b6020908102919091010152600101611a27565b50949350505050565b611b706126a4565b61093a8161373b565b606060008080611b91610954368790038701876148a7565b6000818152600660209081526040918290208251608081018452905460ff81161515808352610100820463ffffffff90811694840185905265010000000000830461ffff169584019590955267010000000000000090910478ffffffffffffffffffffffffffffffffffffffffffffffffff166060830152600454909650939450929091169003611dd85760408101516060820151909450611c3281613830565b60ff1667ffffffffffffffff811115611c4d57611c4d613e52565b604051908082528060200260200182016040528015611c76578160200160208202803683370190505b506002805460408051602080840282018101909252828152939950600093929190849084015b82821015611d3a5760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff7401000000000000000000000000000000000000000082048116938501939093527501000000000000000000000000000000000000000000900490911660608301529083529092019101611c9c565b5050505090506000805b82518160ff161015611dd357611d5a84826136d6565b15611dc357828160ff1681518110611d7457611d74614849565b602002602001015160000151898381518110611d9257611d92614849565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152611dc082614957565b91505b611dcc816149ea565b9050611d44565b505050505b50509193909250565b60606000611dee8361389f565b9392505050565b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166000908152600a60205260408120805463ffffffff858116911614611dee57805463ffffffff19811663ffffffff861690811783556003547fffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000909216176201000090910461ffff1664010000000002177fffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffff1680825568010000000000000000900460ff1615611dee57600260005b8154811015611fcd576000826000018281548110611ee657611ee6614849565b6000918252602080832060016002909302018281015473ffffffffffffffffffffffffffffffffffffffff1684529187019052604090912080549192509063ffffffff808a169116108015611f4d57508054640100000000900460201b63ffffffff191615155b15611fc357805463ffffffff191663ffffffff891617815560018201548554750100000000000000000000000000000000000000000090910460ff16908690600690611fa89084906601000000000000900461ffff1661493c565b92506101000a81548161ffff021916908361ffff1602179055505b5050600101611ec6565b50509392505050565b6000806001896001811115611fed57611fed6146d8565b148061200a57506000896001811115612008576120086146d8565b145b61201657612016614878565b8480612037575073ffffffffffffffffffffffffffffffffffffffff878116145b80612056575073ffffffffffffffffffffffffffffffffffffffff8716155b1561207c57600089600181111561206f5761206f6146d8565b1461207c5761207c614878565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260018401602090815260409182902082518084019093525463ffffffff811683526401000000009004811b63ffffffff191690820152845460ff16801561210d575073ffffffffffffffffffffffffffffffffffffffff888116148061210d57508863ffffffff16816000015163ffffffff16145b80156121235750602081015163ffffffff191615155b801561214b5750866020015163ffffffff1916816020015163ffffffff1916148061214b5750855b156122765773ffffffffffffffffffffffffffffffffffffffff881660009081526001858101602052604082209190915585548554919450610100900460ff169085906006906121aa9084906601000000000000900461ffff16614a09565b825461010092830a61ffff818102199092169282160291909117909255895188546020808d01518a54604080517fffffffffffffffffffffffffffffffff0000000000000000000000000000000090961686529590930460ff169184019190915263ffffffff1916828401526601000000000000900490921660608301525173ffffffffffffffffffffffffffffffffffffffff8b16925063ffffffff8c16917fa96a155bd67c927a6c056befbd979b78465e2b2f1276bf7d4e90a31d4f430aa8919081900360800190a35b6000808b600181111561228b5761228b6146d8565b1480156122b3575083806122b3575073ffffffffffffffffffffffffffffffffffffffff8916155b90508080156122cf5750845468010000000000000000900460ff165b80156122e157506122df856138fb565b155b156123b45784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555600b80546001945060009061232a9067ffffffffffffffff16614a24565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f65d0e78c3625f0956f58610cf0fb157eaf627683258875ef29af2f71d25ac8fd88600001516040516123ab91907fffffffffffffffffffffffffffffffff0000000000000000000000000000000091909116815260200190565b60405180910390a15b83806123bd5750825b15612605576000808c60018111156123d7576123d76146d8565b036123f25787156123ea5750600361240f565b50600261240f565b60018c6001811115612406576124066146d8565b03610182575060015b600c6040518060c0016040528083600481111561242e5761242e6146d8565b81526020014267ffffffffffffffff168152885468010000000000000000900460ff16151560208083019190915273ffffffffffffffffffffffffffffffffffffffff8e1660408301528c517fffffffffffffffffffffffffffffffff00000000000000000000000000000000166060830152600060809092018290528354600180820186559483529120825160029092020180549293909283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911690836004811115612500576125006146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c9190911760019091015550612696565b8751602080840151818b0151604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909516855263ffffffff1992831693850193909352169082015273ffffffffffffffffffffffffffffffffffffffff8a16907fbabb0d7099e6ca14a29fad2a2cfb4fda2bd30f97cb3c27e546174bfb4277c1cc9060600160405180910390a25b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612725576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610418565b565b6000611dee8373ffffffffffffffffffffffffffffffffffffffff841661395c565b6000611dee8373ffffffffffffffffffffffffffffffffffffffff8416613a56565b61277481613aa5565b6127aa576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015160038054604084015161ffff908116620100000263ffffffff199092169316929092179190911790555b6002541561298e5760028054600091906127f5906001906149d7565b8154811061280557612805614849565b60009182526020808320604080516080810182526002948502909201805473ffffffffffffffffffffffffffffffffffffffff90811680855260019092015480821685870190815260ff740100000000000000000000000000000000000000008304811687870152750100000000000000000000000000000000000000000090920490911660608601529187526005855282872080547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000016905590511685526009909252922080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690558054919250908061290457612904614a66565b60008281526020902060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019182020180547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560010180547fffffffffffffffffffff000000000000000000000000000000000000000000001690559055506127d9565b60005b815151811015612ac1578151805160029190839081106129b3576129b3614849565b6020908102919091018101518254600181810185556000948552938390208251600290920201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116178155928201519284018054604084015160609094015160ff9081167501000000000000000000000000000000000000000000027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff9190951674010000000000000000000000000000000000000000027fffffffffffffffffffffff0000000000000000000000000000000000000000009092169590931694909417939093171617905501612991565b5060048054600090612ad89063ffffffff16614a95565b82546101009290920a63ffffffff8181021990931691831602179091556004541660005b82515160ff82161015612c5557600083600001518260ff1681518110612b2457612b24614849565b602090810291909101810151604080516060808201835263ffffffff80891683528385015160ff908116848801908152898216858701908152875173ffffffffffffffffffffffffffffffffffffffff908116600090815260058b528881209751885494519351861665010000000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff948716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009096169190971617939093179190911693909317909455858701519091168352600990955291902080549190920151909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090921691909117600117905550612c4e816149ea565b9050612afc565b5073ffffffffffffffffffffffffffffffffffffffff60005260096020527f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660011790556004805463ffffffff438116640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff90921691909117909155604051908216907f8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a990612d2f908590614ab8565b60405180910390a26040805160c081018252600480825267ffffffffffffffff421660208301526000928201839052606082018390526080820183905260a08201839052600c80546001808201835591909452825160029094027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805493949093909284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090921691908490811115612dec57612dec6146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c919091176001909101555050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611dee565b8151600003612f59576040517f55e9b08b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008316600090815260018201602052604090205460ff1615613007576040517f078f340000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201527fffffffffffffffffffffffffffffffff0000000000000000000000000000000084166024820152604401610418565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008316600090815260018281016020526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905560045463ffffffff16905b83518110156136ce57600181101580156130ed575083818151811061309657613096614849565b60200260200101516fffffffffffffffffffffffffffffffff1916846001836130bf91906149d7565b815181106130cf576130cf614849565b60200260200101516fffffffffffffffffffffffffffffffff191610155b15613124576040517f2432d8ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084828151811061313857613138614849565b60200260200101519050600061314e8483611df5565b73ffffffffffffffffffffffffffffffffffffffff8981166000818152600184016020908152604080832081518083019092525463ffffffff811682526401000000009004821b63ffffffff19169181019190915293945091148015906131be5750815163ffffffff8088169116105b806131d25750602082015163ffffffff1916155b15613225575085548254600091610100900460ff169084906006906132069084906601000000000000900461ffff1661493c565b92506101000a81548161ffff021916908361ffff16021790555061322c565b5060208101515b60408051808201825263ffffffff88168152815163ffffffff1984166020828101919091527fffffffffffffffffffffffffffffffff000000000000000000000000000000008d16828501528351808303850181526060909201909352805190830120909182019063ffffffff1916905273ffffffffffffffffffffffffffffffffffffffff8b166000818152600186016020908152604090912083518285015190921c6401000000000263ffffffff92831617905589549294509091908816907f8137bc8a8d712aaa27bfc6506d5566ac405618bd53f9831b8ca6b6fe5442ee7a9087908d9060ff610100909104166133234290565b6020898101518b54604080517fffffffffffffffffffffffffffffffff000000000000000000000000000000009889168152979096169287019290925260ff9093169385019390935267ffffffffffffffff16606084015263ffffffff191660808301526601000000000000900461ffff1660a082015260c00160405180910390a363ffffffff1981161580156133c85750825468010000000000000000900460ff16155b80156133d857506133d8836138fb565b156134c35782547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff1668010000000000000000178355600b80546000906134289067ffffffffffffffff16614acb565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508563ffffffff167fcfdbfd8ce9a56b5f7c202c0e102184d24f47ca87121dc165063fc4c290957bde8561347e4290565b604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909316835267ffffffffffffffff90911660208301520160405180910390a25b6040805160c081018252600080825267ffffffffffffffff42166020830152855460ff680100000000000000009091041615159282019290925273ffffffffffffffffffffffffffffffffffffffff8c1660608201527fffffffffffffffffffffffffffffffff0000000000000000000000000000000086811660808301528b1660a0820152600c80546001808201835591909352815160029093027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805492939092909183917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908360048111156135c0576135c06146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c9190911760019182015594909401935061306f92505050565b505050505050565b600060108260ff16106136eb576136eb614878565b50600160ff82161b821678ffffffffffffffffffffffffffffffffffffffffffffffffff16151592915050565b600060108260ff161061372d5761372d614878565b50600160ff919091161b1790565b3373ffffffffffffffffffffffffffffffffffffffff8216036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610418565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006201000078ffffffffffffffffffffffffffffffffffffffffffffffffff83161061385f5761385f614878565b78ffffffffffffffffffffffffffffffffffffffffffffffffff8216156105ac5761388b600183614ae8565b90911690613898816149ea565b905061385f565b6060816000018054806020026020016040519081016040528092919081815260200182805480156138ef57602002820191906000526020600020905b8154815260200190600101908083116138db575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff600090815260018201602090815260408220546401000000009004901b63ffffffff19161515806105a65750505461ffff64010000000082048116660100000000000090920416101590565b60008181526001830160205260408120548015613a455760006139806001836149d7565b8554909150600090613994906001906149d7565b90508181146139f95760008660000182815481106139b4576139b4614849565b90600052602060002001549050808760000184815481106139d7576139d7614849565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613a0a57613a0a614a66565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105a6565b60009150506105a6565b5092915050565b6000818152600183016020526040812054613a9d575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105a6565b5060006105a6565b8051516000901580613ab957508151516010105b80613aca5750602082015161ffff16155b80613adb5750604082015161ffff16155b15613ae857506000919050565b60008060008460000151516002613aff9190614b1a565b67ffffffffffffffff811115613b1757613b17613e52565b604051908082528060200260200182016040528015613b40578160200160208202803683370190505b50905060005b855151811015613d1157600086600001518281518110613b6857613b68614849565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161480613bc95750602081015173ffffffffffffffffffffffffffffffffffffffff16155b80613bec5750602081015173ffffffffffffffffffffffffffffffffffffffff16155b80613c115750602081015173ffffffffffffffffffffffffffffffffffffffff908116145b80613c315750604081015160ff16158015613c315750606081015160ff16155b15613c43575060009695505050505050565b805183613c51846002614b1a565b613c5c9060006149c4565b81518110613c6c57613c6c614849565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015281015183613c9f846002614b1a565b613caa9060016149c4565b81518110613cba57613cba614849565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526040810151613cf19060ff16866149c4565b9450806060015160ff1684613d0691906149c4565b935050600101613b46565b5060005b8151811015613dc3576000828281518110613d3257613d32614849565b602002602001015190506000826001613d4b91906149c4565b90505b8351811015613db957838181518110613d6957613d69614849565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613db157506000979650505050505050565b600101613d4e565b5050600101613d15565b50846020015161ffff168310158015613de45750846040015161ffff168210155b95945050505050565b60008151808452602080850194506020840160005b83811015613e3457815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613e02565b509495945050505050565b602081526000611dee6020830184613ded565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613ea457613ea4613e52565b60405290565b6040516060810167ffffffffffffffff81118282101715613ea457613ea4613e52565b6040516080810167ffffffffffffffff81118282101715613ea457613ea4613e52565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613f3757613f37613e52565b604052919050565b600067ffffffffffffffff821115613f5957613f59613e52565b5060051b60200190565b80357fffffffffffffffffffffffffffffffff00000000000000000000000000000000811681146105ac57600080fd5b600060408284031215613fa557600080fd5b613fad613e81565b9050613fb882613f63565b8152602082013563ffffffff1981168114613fd257600080fd5b602082015292915050565b60006020808385031215613ff057600080fd5b823567ffffffffffffffff81111561400757600080fd5b8301601f8101851361401857600080fd5b803561402b61402682613f3f565b613ef0565b8082825260208201915060208360061b85010192508783111561404d57600080fd5b6020840193505b82841015614078576140668885613f93565b82528482019150604084019350614054565b979650505050505050565b60006020808352835180602085015260005b818110156140b157858101830151858201604001528201614095565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561410257600080fd5b611dee82613f63565b803573ffffffffffffffffffffffffffffffffffffffff811681146105ac57600080fd5b600082601f83011261414057600080fd5b8135602061415061402683613f3f565b8083825260208201915060208460051b87010193508684111561417257600080fd5b602086015b84811015614195576141888161410b565b8352918301918301614177565b509695505050505050565b600080604083850312156141b357600080fd5b823567ffffffffffffffff808211156141cb57600080fd5b6141d78683870161412f565b935060208501359150808211156141ed57600080fd5b506141fa8582860161412f565b9150509250929050565b8051606080845281518482018190526000926080916020918201918388019190865b82811015614280578451805173ffffffffffffffffffffffffffffffffffffffff908116865283820151168386015260408082015160ff908116918701919091529088015116878501529381019392850192600101614226565b508781015161ffff81168a83015295505050604086015193506142a9604088018561ffff169052565b9695505050505050565b600063ffffffff808616835280851660208401525060606040830152613de46060830184614204565b803560ff811681146105ac57600080fd5b803561ffff811681146105ac57600080fd5b6000602080838503121561431257600080fd5b823567ffffffffffffffff8082111561432a57600080fd5b8185019150606080838803121561434057600080fd5b614348613eaa565b83358381111561435757600080fd5b84019250601f8301881361436a57600080fd5b823561437861402682613f3f565b81815260079190911b8401860190868101908a83111561439757600080fd5b948701945b82861015614409576080868c0312156143b55760008081fd5b6143bd613ecd565b6143c68761410b565b81526143d389880161410b565b8982015260406143e48189016142dc565b908201526143f38787016142dc565b818701528252608095909501949087019061439c565b83525061441990508486016142ed565b85820152614429604085016142ed565b6040820152979650505050505050565b60006040828403121561444b57600080fd5b50919050565b6000806040838503121561446457600080fd5b61446d83613f63565b915060208084013567ffffffffffffffff81111561448a57600080fd5b8401601f8101861361449b57600080fd5b80356144a961402682613f3f565b81815260059190911b820183019083810190888311156144c857600080fd5b928401925b828410156144ed576144de84613f63565b825292840192908401906144cd565b80955050505050509250929050565b6000602080838503121561450f57600080fd5b823567ffffffffffffffff81111561452657600080fd5b8301601f8101851361453757600080fd5b803561454561402682613f3f565b81815260079190911b8201830190838101908783111561456457600080fd5b928401925b8284101561407857608084890312156145825760008081fd5b61458a613eaa565b6145938561410b565b81526145a189878701613f93565b86820152606085013580151581146145b95760008081fd5b604082015282526080939093019290840190614569565b600080602083850312156145e357600080fd5b823567ffffffffffffffff808211156145fb57600080fd5b818501915085601f83011261460f57600080fd5b81358181111561461e57600080fd5b8660208260061b850101111561463357600080fd5b60209290920196919550909350505050565b6080815260006146586080830187613ded565b82810360208481019190915286518083528782019282019060005b8181101561469657845163ffffffff191683529383019391830191600101614673565b505061ffff96909616604085015250505090151560609091015292915050565b600080604083850312156146c957600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208082528251828201819052600091906040908185019086840185805b838110156147f2578251805160058110614766577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b86528088015167ffffffffffffffff16888701528681015115158787015260608082015173ffffffffffffffffffffffffffffffffffffffff16908701526080808201517fffffffffffffffffffffffffffffffff000000000000000000000000000000009081169188019190915260a091820151169086015260c09094019391860191600101614725565b509298975050505050505050565b60006020828403121561481257600080fd5b611dee8261410b565b60608152600061482e6060830186613ded565b61ffff94909416602083015250901515604090910152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000604082840312156148b957600080fd5b6148c1613e81565b6148ca8361410b565b8152602083013560208201528091505092915050565b815173ffffffffffffffffffffffffffffffffffffffff16815260208083015190820152604081016105a6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff818116838216019080821115613a4f57613a4f61490d565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036149885761498861490d565b5060010190565b60008161499e5761499e61490d565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b808201808211156105a6576105a661490d565b818103818111156105a6576105a661490d565b600060ff821660ff8103614a0057614a0061490d565b60010192915050565b61ffff828116828216039080821115613a4f57613a4f61490d565b600067ffffffffffffffff821680614a3e57614a3e61490d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600063ffffffff808316818103614aae57614aae61490d565b6001019392505050565b602081526000611dee6020830184614204565b600067ffffffffffffffff808316818103614aae57614aae61490d565b78ffffffffffffffffffffffffffffffffffffffffffffffffff828116828216039080821115613a4f57613a4f61490d565b80820281158282048414176105a6576105a661490d56fea164736f6c6343000818000a", + Bin: "0x60806040523480156200001157600080fd5b506040516200596238038062005962833981016040819052620000349162000aff565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000138565b505060408051608081018252600080825260208201819052918101919091526001600160c81b03606082015290506001620000fb81601062000c7d565b82606001516001600160c81b0316901c6001600160c81b0316101562000125576200012562000c99565b506200013181620001e3565b5062000e14565b336001600160a01b03821603620001925760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001ee816200071d565b6200020c576040516306b7c75960e31b815260040160405180910390fd5b602081015160038054604084015161ffff908116620100000263ffffffff199092169316929092179190911790555b60025415620003465760028054600091906200025a9060019062000c7d565b815481106200026d576200026d62000caf565b6000918252602080832060408051608081018252600294850290920180546001600160a01b0390811680855260019092015480821685870190815260ff600160a01b8304811687870152600160a81b909204909116606086015291875260058552828720805465ffffffffffff19169055905116855260099092529220805461ffff191690558054919250908062000309576200030962000cc5565b60008281526020902060026000199092019182020180546001600160a01b031916815560010180546001600160b01b03191690559055506200023b565b60005b81515181101562000403578151805160029190839081106200036f576200036f62000caf565b602090810291909101810151825460018181018555600094855293839020825160029092020180546001600160a01b039283166001600160a01b0319909116178155928201519284018054604084015160609094015160ff908116600160a81b0260ff60a81b1991909516600160a01b026001600160a81b0319909216959093169490941793909317161790550162000349565b50600480546000906200041c9063ffffffff1662000cdb565b82546101009290920a63ffffffff8181021990931691831602179091556004541660005b82515160ff821610156200054157600083600001518260ff16815181106200046c576200046c62000caf565b602090810291909101810151604080516060808201835263ffffffff80891683528385015160ff90811684880190815289821685870190815287516001600160a01b03908116600090815260058b5288812097518854945193518616650100000000000260ff60281b199487166401000000000264ffffffffff1990961691909716179390931791909116939093179094558587015190911683526009909552919020805491909201519092166101000261ffff1990921691909117600117905550620005398162000d01565b905062000440565b506001600160a01b0360005260096020527f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a7805461ffff191660011790556004805463ffffffff4381166401000000000263ffffffff60201b1990921691909117909155604051908216907f8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a990620005db90859062000d23565b60405180910390a26040805160c08101825260048082526001600160401b03421660208301526000928201839052606082018390526080820183905260a08201839052600c80546001808201835591909452825160029094027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018054939490939092849260ff19909216919084908111156200067c576200067c62000dce565b021790555060208201518154604084015160608501516001600160a01b03166a010000000000000000000002600160501b600160f01b031991151569010000000000000000000260ff60481b196001600160401b039095166101000294909416610100600160501b031990931692909217929092179190911617815560808083015160a090930151811c600160801b0292901c919091176001909101555050565b80515160009015806200073257508151516010105b80620007445750602082015161ffff16155b80620007565750604082015161ffff16155b156200076457506000919050565b600080600084600001515160026200077d919062000de4565b6001600160401b0381111562000797576200079762000a24565b604051908082528060200260200182016040528015620007c1578160200160208202803683370190505b50905060005b8551518110156200095457600086600001518281518110620007ed57620007ed62000caf565b6020026020010151905060006001600160a01b031681600001516001600160a01b0316148062000828575060208101516001600160a01b0316155b806200083f575060208101516001600160a01b0316155b8062000858575060208101516001600160a01b03908116145b806200087a5750604081015160ff161580156200087a5750606081015160ff16155b156200088d575060009695505050505050565b8051836200089d84600262000de4565b620008aa90600062000dfe565b81518110620008bd57620008bd62000caf565b6001600160a01b0390921660209283029190910182015281015183620008e584600262000de4565b620008f290600162000dfe565b8151811062000905576200090562000caf565b6001600160a01b03909216602092830291909101909101526040810151620009319060ff168662000dfe565b9450806060015160ff168462000948919062000dfe565b935050600101620007c7565b5060005b8151811015620009f957600082828151811062000979576200097962000caf565b60200260200101519050600082600162000994919062000dfe565b90505b8351811015620009ee57838181518110620009b657620009b662000caf565b60200260200101516001600160a01b0316826001600160a01b031603620009e557506000979650505050505050565b60010162000997565b505060010162000958565b50846020015161ffff16831015801562000a1b5750846040015161ffff168210155b95945050505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b038111828210171562000a5f5762000a5f62000a24565b60405290565b604051608081016001600160401b038111828210171562000a5f5762000a5f62000a24565b604051601f8201601f191681016001600160401b038111828210171562000ab55762000ab562000a24565b604052919050565b80516001600160a01b038116811462000ad557600080fd5b919050565b805160ff8116811462000ad557600080fd5b805161ffff8116811462000ad557600080fd5b6000602080838503121562000b1357600080fd5b82516001600160401b038082111562000b2b57600080fd5b8185019150606080838803121562000b4257600080fd5b62000b4c62000a3a565b83518381111562000b5c57600080fd5b8401601f8101891362000b6e57600080fd5b80518481111562000b835762000b8362000a24565b62000b93878260051b0162000a8a565b818152878101955060079190911b82018701908a82111562000bb457600080fd5b918701915b8183101562000c33576080838c03121562000bd45760008081fd5b62000bde62000a65565b62000be98462000abd565b815262000bf889850162000abd565b89820152604062000c0b81860162000ada565b9082015262000c1c84870162000ada565b818701528652948701946080929092019162000bb9565b83525062000c45905084860162000aec565b8582015262000c576040850162000aec565b6040820152979650505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000c935762000c9362000c67565b92915050565b634e487b7160e01b600052600160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600063ffffffff80831681810362000cf75762000cf762000c67565b6001019392505050565b600060ff821660ff810362000d1a5762000d1a62000c67565b60010192915050565b60006020808352608080840185516060808588015282825180855260a0890191508684019450600093505b8084101562000da157845180516001600160a01b03908116845288820151168884015260408082015160ff9081169185019190915290840151168383015293860193600193909301929085019062000d4e565b509488015161ffff8116604089015294604089015161ffff811660608a0152955098975050505050505050565b634e487b7160e01b600052602160045260246000fd5b808202811582820484141762000c935762000c9362000c67565b8082018082111562000c935762000c9362000c67565b614b3e8062000e246000396000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063631ec73e116100d8578063979986111161008c578063d927f26711610066578063d927f26714610354578063f2fde38b14610374578063f33f28951461038757600080fd5b8063979986111461030b578063ba86a1f01461031e578063bd147ef41461033157600080fd5b806379ba5097116100bd57806379ba5097146102d35780638da5cb5b146102db578063970b8fc21461030357600080fd5b8063631ec73e146102ad5780636ba0526d146102c057600080fd5b8063397796f71161013a5780634102e4f4116101145780634102e4f4146102745780634d61677114610287578063586abe3c1461029a57600080fd5b8063397796f7146102425780633d0cf6101461024a5780633f42ab731461025d57600080fd5b8063181f5a771161016b578063181f5a77146101ba5780632cbc26bb14610203578063328d716c1461022657600080fd5b80630b009be21461018757806315c65588146101a5575b600080fd5b61018f6103a9565b60405161019c9190613e3f565b60405180910390f35b6101b86101b3366004613fdd565b6103ba565b005b6101f66040518060400160405280600981526020017f524d4e20312e352e30000000000000000000000000000000000000000000000081525081565b60405161019c9190614083565b6102166102113660046140f0565b6104e6565b604051901515815260200161019c565b600b5467ffffffffffffffff165b60405190815260200161019c565b6102166105b1565b6101b86102583660046141a0565b61068b565b6102656107ff565b60405161019c939291906142b3565b6101b86102823660046142ff565b610929565b610216610295366004614439565b61093d565b6101b86102a8366004614451565b6109cd565b6101b86102bb3660046144fc565b610a87565b6101b86102ce366004614451565b610ca0565b6101b8610d13565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019c565b600c54610234565b6101b86103193660046145d0565b610e10565b6101b861032c3660046145d0565b611368565b61034461033f3660046140f0565b61150d565b60405161019c9493929190614645565b6103676103623660046146b6565b611946565b60405161019c9190614707565b6101b8610382366004614800565b611b68565b61039a610395366004614439565b611b79565b60405161019c9392919061481b565b60606103b56007611de1565b905090565b336000818152600960205260409020805460ff16610421576040517f85412e7f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b60045463ffffffff166000805b85518110156104a757600086828151811061044b5761044b614849565b602002602001015190506000610465858360000151611df5565b905060008061047b6001888b8760008d89611fd6565b91509150801561048d5761048d614878565b85806104965750815b95505050505080600101905061042e565b50806104df576040517ffb106b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b600b5460009067ffffffffffffffff16810361050457506000919050565b7f0100000000000000000000000000000100000000000000000000000000000000600052600a6020527fcf943f0e419056430919a3fdfd72276bc0b123ebdd670f4152b82bffbfb8bb385468010000000000000000900460ff16806105a657507fffffffffffffffffffffffffffffffff0000000000000000000000000000000082166000908152600a602052604090205468010000000000000000900460ff165b92915050565b919050565b600b5460009067ffffffffffffffff1681036105cd5750600090565b7f0100000000000000000000000000000100000000000000000000000000000000600052600a6020527fcf943f0e419056430919a3fdfd72276bc0b123ebdd670f4152b82bffbfb8bb385468010000000000000000900460ff16806103b55750507f0100000000000000000000000000000000000000000000000000000000000000600052600a6020527f1d4cd6d2639449a552dbfb463b59316946d78c518b3170daa4a4c217bef019ba5468010000000000000000900460ff1690565b6106936126a4565b60005b8251811015610746576106cc8382815181106106b4576106b4614849565b6020026020010151600761272790919063ffffffff16565b1561073e577fdca892154bbc36d0c05ccd01b3d0411875cb1b841fcdeebb384e5d0d6eb06b4483828151811061070457610704614849565b6020026020010151604051610735919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a15b600101610696565b5060005b81518110156107fa5761078082828151811061076857610768614849565b6020026020010151600761274990919063ffffffff16565b156107f2577f66b4b4752c65ae8cd2f3a0a48c7dc8b2118c60d5ea15514992eb2ddf56c9cb158282815181106107b8576107b8614849565b60200260200101516040516107e9919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a15b60010161074a565b505050565b6040805160608082018352808252600060208084018290528385018290526004548551600280549384028201608090810190985294810183815263ffffffff808416986401000000009094041696959194919385939192859285015b828210156108f95760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff740100000000000000000000000000000000000000008204811693850193909352750100000000000000000000000000000000000000000090049091166060830152908352909201910161085b565b505050908252506001919091015461ffff8082166020840152620100009091041660409091015292939192919050565b6109316126a4565b61093a8161276b565b50565b600060068161099b610954368690038601866148a7565b80516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b815260208101919091526040016000205460ff16806105a657506105a66109c56020840184614800565b600790612eef565b337fffffffffffffffffffffffff000000000000000000000000000000000000000181016109fd576109fd614878565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600960205260409020805460ff16610a75576040517f85412e7f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610418565b610a8182858584612f1e565b50505050565b610a8f6126a4565b600454600090819063ffffffff16815b8451811015610b66576000858281518110610abc57610abc614849565b602002602001015190506000610ada84836020015160000151611df5565b9050600080610b3d600087866000015187602001518860400151600960008b6000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002089611fd6565b915091508680610b4a5750815b96508780610b555750805b975050505050806001019050610a9f565b508215610c615760408051600280546080602082028401810190945260608301818152610c61948492849160009085015b82821015610c355760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff7401000000000000000000000000000000000000000082048116938501939093527501000000000000000000000000000000000000000000900490911660608301529083529092019101610b97565b505050908252506001919091015461ffff8082166020840152620100009091041660409091015261276b565b8180610c6a5750825b610a81576040517ffb106b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca86126a4565b73ffffffffffffffffffffffffffffffffffffffff60005260096020527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a7610a8182858584612f1e565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610418565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e397f01000000000000000000000000000001000000000000000000000000000000006104e6565b15610e70576040517fcde2d97c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454336000908152600560209081526040918290208251606081018452905463ffffffff81811680845260ff64010000000084048116958501959095526501000000000090920490931693820193909352921691908214610f00576040517f85412e7f000000000000000000000000000000000000000000000000000000008152336004820152602401610418565b600160005b8481101561132f576000868683818110610f2157610f21614849565b905060400201803603810190610f3791906148a7565b90506000610f868280516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b6000818152600660209081526040918290208251608081018452905460ff81161580158352610100820463ffffffff169383019390935265010000000000810461ffff169382019390935267010000000000000090920478ffffffffffffffffffffffffffffffffffffffffffffffffff16606083015291925090611062573373ffffffffffffffffffffffffffffffffffffffff168763ffffffff167f274d6d5b916b0a53974b7ab86c844b97a2e03a60f658cd9a4b1c028b604d7bf18560405161105291906148e0565b60405180910390a3505050611327565b8663ffffffff16816020015163ffffffff16146110a8575060408051608081018252600080825263ffffffff89166020830152918101829052606081019190915261110c565b6110ba816060015187604001516136d6565b1561110c573373ffffffffffffffffffffffffffffffffffffffff168763ffffffff167f6dfbb745226fa630aeb1b9557d17d508ddb789a04f0cb873ec16e58beb8beead8560405161105291906148e0565b6000945061112281606001518760400151613718565b78ffffffffffffffffffffffffffffffffffffffffffffffffff166060820152602086015160408201805160ff9092169161115e90839061493c565b61ffff1690525060208681015160408051865173ffffffffffffffffffffffffffffffffffffffff168152868401519381019390935260ff9091168282015251339163ffffffff8a16917f2a08a2bd2798f0aae9a843f0f4ad4de488c1b3d5f04049940cfed736ad69fb979181900360600190a3600354604082015161ffff91821691161061125757600181526040808201518151855173ffffffffffffffffffffffffffffffffffffffff1681526020808701519082015261ffff90911681830152905163ffffffff8916917f8257378aa73bf8e4ada848713526584a3dcee0fd3db3beed7397f7a7f5067cc9919081900360600190a25b60009182526006602090815260409283902082518154928401519484015160609094015178ffffffffffffffffffffffffffffffffffffffffffffffffff166701000000000000000266ffffffffffffff61ffff90951665010000000000029490941664ffffffffff63ffffffff909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090941693909317179390931617179055505b600101610f05565b5080156104df576040517f604c767700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113706126a4565b60045463ffffffff1660005b82811015610a8157600084848381811061139857611398614849565b9050604002018036038101906113ae91906148a7565b905060006113fd8280516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b60008181526006602081815260408084208151608081018352815460ff811615158252610100810463ffffffff90811683870190815265010000000000830461ffff169584019590955267010000000000000090910478ffffffffffffffffffffffffffffffffffffffffffffffffff16606083015287875294909352939093558051925193945092878216911614806114945750805b156114fe5760408051855173ffffffffffffffffffffffffffffffffffffffff1681526020808701519082015282151581830152905163ffffffff8816917f7d15a6eebaa019ea7d5b7d38937c51ebd3befbfdf51bb630a694fd28635bbcba919081900360600190a25b5050505080600101905061137c565b600454604080516002805460806020820284018101909452606083810182815290958695600095869563ffffffff9093169486949193928492918491879085015b828210156115ec5760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff740100000000000000000000000000000000000000008204811693850193909352750100000000000000000000000000000000000000000090049091166060830152908352909201910161154e565b505050908252506001919091015461ffff80821660208085019190915262010000909204166040928301527fffffffffffffffffffffffffffffffff000000000000000000000000000000008a166000908152600a909152908120805460ff6801000000000000000082041696509293509163ffffffff80861691161080156116725750845b6000965090508560015b60028111611939578451515b6000808760000151518310156116e35787518051849081106116ac576116ac614849565b6020026020010151602001519150876000015183815181106116d0576116d0614849565b602002602001015160600151905061170a565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905060005b73ffffffffffffffffffffffffffffffffffffffff82166000908152600188016020908152604080832081518083019092525463ffffffff811682526401000000009004821b63ffffffff19169181019190915290878061177a57508a63ffffffff16826000015163ffffffff16145b8061179a575073ffffffffffffffffffffffffffffffffffffffff848116145b80156117b05750602082015163ffffffff191615155b9050801561186d57856001036117d0576117c987614957565b965061186d565b85600203610182576117e560ff84168e61493c565b9c506117f08761498f565b9650838f888151811061180557611805614849565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505081602001518e888151811061185657611856614849565b63ffffffff19909216602092830291909101909101525b84156118835761187c8561498f565b945061188c565b50505050611895565b50505050611688565b81600103611928578267ffffffffffffffff8111156118b6576118b6613e52565b6040519080825280602002602001820160405280156118df578160200160208202803683370190505b509a508267ffffffffffffffff8111156118fb576118fb613e52565b604051908082528060200260200182016040528015611924578160200160208202803683370190505b5099505b5061193281614957565b905061167c565b5050505050509193509193565b600c5460609060009061195984866149c4565b11611965575081611988565b600c5484101561198457600c5461197d9085906149d7565b9050611988565b5060005b60008167ffffffffffffffff8111156119a3576119a3613e52565b604051908082528060200260200182016040528015611a2157816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816119c15790505b50905060005b82811015611b5f57600c611a3b82886149c4565b81548110611a4b57611a4b614849565b600091825260209091206040805160c081019091526002909202018054829060ff166004811115611a7e57611a7e6146d8565b6004811115611a8f57611a8f6146d8565b81528154610100810467ffffffffffffffff1660208301526901000000000000000000810460ff16151560408301526a0100000000000000000000900473ffffffffffffffffffffffffffffffffffffffff166060820152600190910154608081811b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000090811682850152700100000000000000000000000000000000909204901b1660a0909101528251839083908110611b4c57611b4c614849565b6020908102919091010152600101611a27565b50949350505050565b611b706126a4565b61093a8161373b565b606060008080611b91610954368790038701876148a7565b6000818152600660209081526040918290208251608081018452905460ff81161515808352610100820463ffffffff90811694840185905265010000000000830461ffff169584019590955267010000000000000090910478ffffffffffffffffffffffffffffffffffffffffffffffffff166060830152600454909650939450929091169003611dd85760408101516060820151909450611c3281613830565b60ff1667ffffffffffffffff811115611c4d57611c4d613e52565b604051908082528060200260200182016040528015611c76578160200160208202803683370190505b506002805460408051602080840282018101909252828152939950600093929190849084015b82821015611d3a5760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff7401000000000000000000000000000000000000000082048116938501939093527501000000000000000000000000000000000000000000900490911660608301529083529092019101611c9c565b5050505090506000805b82518160ff161015611dd357611d5a84826136d6565b15611dc357828160ff1681518110611d7457611d74614849565b602002602001015160000151898381518110611d9257611d92614849565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152611dc082614957565b91505b611dcc816149ea565b9050611d44565b505050505b50509193909250565b60606000611dee8361389f565b9392505050565b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166000908152600a60205260408120805463ffffffff858116911614611dee57805463ffffffff19811663ffffffff861690811783556003547fffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000909216176201000090910461ffff1664010000000002177fffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffff1680825568010000000000000000900460ff1615611dee57600260005b8154811015611fcd576000826000018281548110611ee657611ee6614849565b6000918252602080832060016002909302018281015473ffffffffffffffffffffffffffffffffffffffff1684529187019052604090912080549192509063ffffffff808a169116108015611f4d57508054640100000000900460201b63ffffffff191615155b15611fc357805463ffffffff191663ffffffff891617815560018201548554750100000000000000000000000000000000000000000090910460ff16908690600690611fa89084906601000000000000900461ffff1661493c565b92506101000a81548161ffff021916908361ffff1602179055505b5050600101611ec6565b50509392505050565b6000806001896001811115611fed57611fed6146d8565b148061200a57506000896001811115612008576120086146d8565b145b61201657612016614878565b8480612037575073ffffffffffffffffffffffffffffffffffffffff878116145b80612056575073ffffffffffffffffffffffffffffffffffffffff8716155b1561207c57600089600181111561206f5761206f6146d8565b1461207c5761207c614878565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260018401602090815260409182902082518084019093525463ffffffff811683526401000000009004811b63ffffffff191690820152845460ff16801561210d575073ffffffffffffffffffffffffffffffffffffffff888116148061210d57508863ffffffff16816000015163ffffffff16145b80156121235750602081015163ffffffff191615155b801561214b5750866020015163ffffffff1916816020015163ffffffff1916148061214b5750855b156122765773ffffffffffffffffffffffffffffffffffffffff881660009081526001858101602052604082209190915585548554919450610100900460ff169085906006906121aa9084906601000000000000900461ffff16614a09565b825461010092830a61ffff818102199092169282160291909117909255895188546020808d01518a54604080517fffffffffffffffffffffffffffffffff0000000000000000000000000000000090961686529590930460ff169184019190915263ffffffff1916828401526601000000000000900490921660608301525173ffffffffffffffffffffffffffffffffffffffff8b16925063ffffffff8c16917fa96a155bd67c927a6c056befbd979b78465e2b2f1276bf7d4e90a31d4f430aa8919081900360800190a35b6000808b600181111561228b5761228b6146d8565b1480156122b3575083806122b3575073ffffffffffffffffffffffffffffffffffffffff8916155b90508080156122cf5750845468010000000000000000900460ff165b80156122e157506122df856138fb565b155b156123b45784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555600b80546001945060009061232a9067ffffffffffffffff16614a24565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f65d0e78c3625f0956f58610cf0fb157eaf627683258875ef29af2f71d25ac8fd88600001516040516123ab91907fffffffffffffffffffffffffffffffff0000000000000000000000000000000091909116815260200190565b60405180910390a15b83806123bd5750825b15612605576000808c60018111156123d7576123d76146d8565b036123f25787156123ea5750600361240f565b50600261240f565b60018c6001811115612406576124066146d8565b03610182575060015b600c6040518060c0016040528083600481111561242e5761242e6146d8565b81526020014267ffffffffffffffff168152885468010000000000000000900460ff16151560208083019190915273ffffffffffffffffffffffffffffffffffffffff8e1660408301528c517fffffffffffffffffffffffffffffffff00000000000000000000000000000000166060830152600060809092018290528354600180820186559483529120825160029092020180549293909283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911690836004811115612500576125006146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c9190911760019091015550612696565b8751602080840151818b0151604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909516855263ffffffff1992831693850193909352169082015273ffffffffffffffffffffffffffffffffffffffff8a16907fbabb0d7099e6ca14a29fad2a2cfb4fda2bd30f97cb3c27e546174bfb4277c1cc9060600160405180910390a25b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612725576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610418565b565b6000611dee8373ffffffffffffffffffffffffffffffffffffffff841661395c565b6000611dee8373ffffffffffffffffffffffffffffffffffffffff8416613a56565b61277481613aa5565b6127aa576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015160038054604084015161ffff908116620100000263ffffffff199092169316929092179190911790555b6002541561298e5760028054600091906127f5906001906149d7565b8154811061280557612805614849565b60009182526020808320604080516080810182526002948502909201805473ffffffffffffffffffffffffffffffffffffffff90811680855260019092015480821685870190815260ff740100000000000000000000000000000000000000008304811687870152750100000000000000000000000000000000000000000090920490911660608601529187526005855282872080547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000016905590511685526009909252922080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690558054919250908061290457612904614a66565b60008281526020902060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019182020180547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560010180547fffffffffffffffffffff000000000000000000000000000000000000000000001690559055506127d9565b60005b815151811015612ac1578151805160029190839081106129b3576129b3614849565b6020908102919091018101518254600181810185556000948552938390208251600290920201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116178155928201519284018054604084015160609094015160ff9081167501000000000000000000000000000000000000000000027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff9190951674010000000000000000000000000000000000000000027fffffffffffffffffffffff0000000000000000000000000000000000000000009092169590931694909417939093171617905501612991565b5060048054600090612ad89063ffffffff16614a95565b82546101009290920a63ffffffff8181021990931691831602179091556004541660005b82515160ff82161015612c5557600083600001518260ff1681518110612b2457612b24614849565b602090810291909101810151604080516060808201835263ffffffff80891683528385015160ff908116848801908152898216858701908152875173ffffffffffffffffffffffffffffffffffffffff908116600090815260058b528881209751885494519351861665010000000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff948716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009096169190971617939093179190911693909317909455858701519091168352600990955291902080549190920151909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090921691909117600117905550612c4e816149ea565b9050612afc565b5073ffffffffffffffffffffffffffffffffffffffff60005260096020527f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660011790556004805463ffffffff438116640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff90921691909117909155604051908216907f8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a990612d2f908590614ab8565b60405180910390a26040805160c081018252600480825267ffffffffffffffff421660208301526000928201839052606082018390526080820183905260a08201839052600c80546001808201835591909452825160029094027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805493949093909284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090921691908490811115612dec57612dec6146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c919091176001909101555050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611dee565b8151600003612f59576040517f55e9b08b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008316600090815260018201602052604090205460ff1615613007576040517f078f340000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201527fffffffffffffffffffffffffffffffff0000000000000000000000000000000084166024820152604401610418565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008316600090815260018281016020526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905560045463ffffffff16905b83518110156136ce57600181101580156130ed575083818151811061309657613096614849565b60200260200101516fffffffffffffffffffffffffffffffff1916846001836130bf91906149d7565b815181106130cf576130cf614849565b60200260200101516fffffffffffffffffffffffffffffffff191610155b15613124576040517f2432d8ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084828151811061313857613138614849565b60200260200101519050600061314e8483611df5565b73ffffffffffffffffffffffffffffffffffffffff8981166000818152600184016020908152604080832081518083019092525463ffffffff811682526401000000009004821b63ffffffff19169181019190915293945091148015906131be5750815163ffffffff8088169116105b806131d25750602082015163ffffffff1916155b15613225575085548254600091610100900460ff169084906006906132069084906601000000000000900461ffff1661493c565b92506101000a81548161ffff021916908361ffff16021790555061322c565b5060208101515b60408051808201825263ffffffff88168152815163ffffffff1984166020828101919091527fffffffffffffffffffffffffffffffff000000000000000000000000000000008d16828501528351808303850181526060909201909352805190830120909182019063ffffffff1916905273ffffffffffffffffffffffffffffffffffffffff8b166000818152600186016020908152604090912083518285015190921c6401000000000263ffffffff92831617905589549294509091908816907f8137bc8a8d712aaa27bfc6506d5566ac405618bd53f9831b8ca6b6fe5442ee7a9087908d9060ff610100909104166133234290565b6020898101518b54604080517fffffffffffffffffffffffffffffffff000000000000000000000000000000009889168152979096169287019290925260ff9093169385019390935267ffffffffffffffff16606084015263ffffffff191660808301526601000000000000900461ffff1660a082015260c00160405180910390a363ffffffff1981161580156133c85750825468010000000000000000900460ff16155b80156133d857506133d8836138fb565b156134c35782547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff1668010000000000000000178355600b80546000906134289067ffffffffffffffff16614acb565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508563ffffffff167fcfdbfd8ce9a56b5f7c202c0e102184d24f47ca87121dc165063fc4c290957bde8561347e4290565b604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909316835267ffffffffffffffff90911660208301520160405180910390a25b6040805160c081018252600080825267ffffffffffffffff42166020830152855460ff680100000000000000009091041615159282019290925273ffffffffffffffffffffffffffffffffffffffff8c1660608201527fffffffffffffffffffffffffffffffff0000000000000000000000000000000086811660808301528b1660a0820152600c80546001808201835591909352815160029093027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805492939092909183917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908360048111156135c0576135c06146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c9190911760019182015594909401935061306f92505050565b505050505050565b600060108260ff16106136eb576136eb614878565b50600160ff82161b821678ffffffffffffffffffffffffffffffffffffffffffffffffff16151592915050565b600060108260ff161061372d5761372d614878565b50600160ff919091161b1790565b3373ffffffffffffffffffffffffffffffffffffffff8216036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610418565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006201000078ffffffffffffffffffffffffffffffffffffffffffffffffff83161061385f5761385f614878565b78ffffffffffffffffffffffffffffffffffffffffffffffffff8216156105ac5761388b600183614ae8565b90911690613898816149ea565b905061385f565b6060816000018054806020026020016040519081016040528092919081815260200182805480156138ef57602002820191906000526020600020905b8154815260200190600101908083116138db575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff600090815260018201602090815260408220546401000000009004901b63ffffffff19161515806105a65750505461ffff64010000000082048116660100000000000090920416101590565b60008181526001830160205260408120548015613a455760006139806001836149d7565b8554909150600090613994906001906149d7565b90508082146139f95760008660000182815481106139b4576139b4614849565b90600052602060002001549050808760000184815481106139d7576139d7614849565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613a0a57613a0a614a66565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105a6565b60009150506105a6565b5092915050565b6000818152600183016020526040812054613a9d575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105a6565b5060006105a6565b8051516000901580613ab957508151516010105b80613aca5750602082015161ffff16155b80613adb5750604082015161ffff16155b15613ae857506000919050565b60008060008460000151516002613aff9190614b1a565b67ffffffffffffffff811115613b1757613b17613e52565b604051908082528060200260200182016040528015613b40578160200160208202803683370190505b50905060005b855151811015613d1157600086600001518281518110613b6857613b68614849565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161480613bc95750602081015173ffffffffffffffffffffffffffffffffffffffff16155b80613bec5750602081015173ffffffffffffffffffffffffffffffffffffffff16155b80613c115750602081015173ffffffffffffffffffffffffffffffffffffffff908116145b80613c315750604081015160ff16158015613c315750606081015160ff16155b15613c43575060009695505050505050565b805183613c51846002614b1a565b613c5c9060006149c4565b81518110613c6c57613c6c614849565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015281015183613c9f846002614b1a565b613caa9060016149c4565b81518110613cba57613cba614849565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526040810151613cf19060ff16866149c4565b9450806060015160ff1684613d0691906149c4565b935050600101613b46565b5060005b8151811015613dc3576000828281518110613d3257613d32614849565b602002602001015190506000826001613d4b91906149c4565b90505b8351811015613db957838181518110613d6957613d69614849565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613db157506000979650505050505050565b600101613d4e565b5050600101613d15565b50846020015161ffff168310158015613de45750846040015161ffff168210155b95945050505050565b60008151808452602080850194506020840160005b83811015613e3457815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613e02565b509495945050505050565b602081526000611dee6020830184613ded565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613ea457613ea4613e52565b60405290565b6040516060810167ffffffffffffffff81118282101715613ea457613ea4613e52565b6040516080810167ffffffffffffffff81118282101715613ea457613ea4613e52565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613f3757613f37613e52565b604052919050565b600067ffffffffffffffff821115613f5957613f59613e52565b5060051b60200190565b80357fffffffffffffffffffffffffffffffff00000000000000000000000000000000811681146105ac57600080fd5b600060408284031215613fa557600080fd5b613fad613e81565b9050613fb882613f63565b8152602082013563ffffffff1981168114613fd257600080fd5b602082015292915050565b60006020808385031215613ff057600080fd5b823567ffffffffffffffff81111561400757600080fd5b8301601f8101851361401857600080fd5b803561402b61402682613f3f565b613ef0565b8082825260208201915060208360061b85010192508783111561404d57600080fd5b6020840193505b82841015614078576140668885613f93565b82528482019150604084019350614054565b979650505050505050565b60006020808352835180602085015260005b818110156140b157858101830151858201604001528201614095565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561410257600080fd5b611dee82613f63565b803573ffffffffffffffffffffffffffffffffffffffff811681146105ac57600080fd5b600082601f83011261414057600080fd5b8135602061415061402683613f3f565b8083825260208201915060208460051b87010193508684111561417257600080fd5b602086015b84811015614195576141888161410b565b8352918301918301614177565b509695505050505050565b600080604083850312156141b357600080fd5b823567ffffffffffffffff808211156141cb57600080fd5b6141d78683870161412f565b935060208501359150808211156141ed57600080fd5b506141fa8582860161412f565b9150509250929050565b8051606080845281518482018190526000926080916020918201918388019190865b82811015614280578451805173ffffffffffffffffffffffffffffffffffffffff908116865283820151168386015260408082015160ff908116918701919091529088015116878501529381019392850192600101614226565b508781015161ffff81168a83015295505050604086015193506142a9604088018561ffff169052565b9695505050505050565b600063ffffffff808616835280851660208401525060606040830152613de46060830184614204565b803560ff811681146105ac57600080fd5b803561ffff811681146105ac57600080fd5b6000602080838503121561431257600080fd5b823567ffffffffffffffff8082111561432a57600080fd5b8185019150606080838803121561434057600080fd5b614348613eaa565b83358381111561435757600080fd5b84019250601f8301881361436a57600080fd5b823561437861402682613f3f565b81815260079190911b8401860190868101908a83111561439757600080fd5b948701945b82861015614409576080868c0312156143b55760008081fd5b6143bd613ecd565b6143c68761410b565b81526143d389880161410b565b8982015260406143e48189016142dc565b908201526143f38787016142dc565b818701528252608095909501949087019061439c565b83525061441990508486016142ed565b85820152614429604085016142ed565b6040820152979650505050505050565b60006040828403121561444b57600080fd5b50919050565b6000806040838503121561446457600080fd5b61446d83613f63565b915060208084013567ffffffffffffffff81111561448a57600080fd5b8401601f8101861361449b57600080fd5b80356144a961402682613f3f565b81815260059190911b820183019083810190888311156144c857600080fd5b928401925b828410156144ed576144de84613f63565b825292840192908401906144cd565b80955050505050509250929050565b6000602080838503121561450f57600080fd5b823567ffffffffffffffff81111561452657600080fd5b8301601f8101851361453757600080fd5b803561454561402682613f3f565b81815260079190911b8201830190838101908783111561456457600080fd5b928401925b8284101561407857608084890312156145825760008081fd5b61458a613eaa565b6145938561410b565b81526145a189878701613f93565b86820152606085013580151581146145b95760008081fd5b604082015282526080939093019290840190614569565b600080602083850312156145e357600080fd5b823567ffffffffffffffff808211156145fb57600080fd5b818501915085601f83011261460f57600080fd5b81358181111561461e57600080fd5b8660208260061b850101111561463357600080fd5b60209290920196919550909350505050565b6080815260006146586080830187613ded565b82810360208481019190915286518083528782019282019060005b8181101561469657845163ffffffff191683529383019391830191600101614673565b505061ffff96909616604085015250505090151560609091015292915050565b600080604083850312156146c957600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208082528251828201819052600091906040908185019086840185805b838110156147f2578251805160058110614766577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b86528088015167ffffffffffffffff16888701528681015115158787015260608082015173ffffffffffffffffffffffffffffffffffffffff16908701526080808201517fffffffffffffffffffffffffffffffff000000000000000000000000000000009081169188019190915260a091820151169086015260c09094019391860191600101614725565b509298975050505050505050565b60006020828403121561481257600080fd5b611dee8261410b565b60608152600061482e6060830186613ded565b61ffff94909416602083015250901515604090910152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000604082840312156148b957600080fd5b6148c1613e81565b6148ca8361410b565b8152602083013560208201528091505092915050565b815173ffffffffffffffffffffffffffffffffffffffff16815260208083015190820152604081016105a6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff818116838216019080821115613a4f57613a4f61490d565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036149885761498861490d565b5060010190565b60008161499e5761499e61490d565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b808201808211156105a6576105a661490d565b818103818111156105a6576105a661490d565b600060ff821660ff8103614a0057614a0061490d565b60010192915050565b61ffff828116828216039080821115613a4f57613a4f61490d565b600067ffffffffffffffff821680614a3e57614a3e61490d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600063ffffffff808316818103614aae57614aae61490d565b6001019392505050565b602081526000611dee6020830184614204565b600067ffffffffffffffff808316818103614aae57614aae61490d565b78ffffffffffffffffffffffffffffffffffffffffffffffffff828116828216039080821115613a4f57613a4f61490d565b80820281158282048414176105a6576105a661490d56fea164736f6c6343000818000a", } var ARMContractABI = ARMContractMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go index caea3cec11..1553ba62b0 100644 --- a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnFromMintTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b506040516200450b3803806200450b8339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161399262000b79600039600081816104dd01528181611777015261215b0152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b45015281816120f1015261234601526139926000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae9565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b48565b6105f9565b6040516101d29190612bc7565b6101ee6040518060400160405280601b81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e30000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c07565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c24565b6106a9565b604051905181526020016101d2565b6103006102fb366004612cac565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d18565b6108aa565b610300610a1e565b610300610349366004612c07565b610b1b565b6101c661035c366004612b48565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d9b565b610b81565b6040516101d29190612dd6565b6103a7610c28565b6040516101d29190612e36565b6103c76103c2366004612b48565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b48565b610d0e565b610300610462366004612c07565b610d39565b61046f610e14565b6040516101d29190612e90565b6103c761048a366004612b48565b610ecc565b61030061049d366004612ff8565b610f9e565b6103006104b036600461303d565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c07565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061307f565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361317d565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c07565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c07565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109299061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546109559061307f565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132c2565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133dc565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba183613440565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b48565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb9565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc6565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061307f565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb9565b90506000815167ffffffffffffffff811115610e4057610e40612ed2565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134e2565b6020026020010151828281518110610ea457610ea46134e2565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc6565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c78565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134e2565b90506020028101906110609190613511565b6110699061354f565b905061107e8160800151826020015115611d62565b6110918160a00151826020015115611d62565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e9b565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906113259082613603565b506060820151600582019061133a9082613603565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c29550611380949392919061371d565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea7565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a9b565b611461600583016000612a9b565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611eb3565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b6565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa8565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc7565b6116ee826020015183606001516120ce565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134e2565b6020026020010151905061180a81600261211590919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134e2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612137565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b6565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612159565b611afe81602001516121d8565b6114be81602001518260600151612326565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015611b9e57600080fd5b505af1158015611bb2573d6000803e3d6000fd5b5050505050565b6060600061193f8361236a565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c5482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c389190613802565b85608001516fffffffffffffffffffffffffffffffff166123c5565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c8183610b6a565b611cc3576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cce826000611d62565b67ffffffffffffffff83166000908152600760205260409020611cf190836123ef565b611cfc816000611d62565b67ffffffffffffffff83166000908152600760205260409020611d2290600201826123ef565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d5593929190613815565b60405180910390a1505050565b815115611e295781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db8575060408201516fffffffffffffffffffffffffffffffff16155b15611df157816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e62575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b600061193f8383612591565b600061193f83836125e0565b3373ffffffffffffffffffffffffffffffffffffffff821603611f32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fb181610b6a565b611ff3576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612072573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209691906137b6565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126d3565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125e0565b600061193f8373ffffffffffffffffffffffffffffffffffffffff8416612591565b7f0000000000000000000000000000000000000000000000000000000000000000156114be5761218a600282612a56565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121e181610b6a565b612223576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c091906138d4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126d3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a65750505050509050919050565b60006123e4856123d584866138f1565b6123df9087613908565b612a85565b90505b949350505050565b815460009061241890700100000000000000000000000000000000900463ffffffff1642613802565b905080156124ba5760018301548354612460916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123c5565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124e0916fffffffffffffffffffffffffffffffff9081169116612a85565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d55908490613898565b60008181526001830160205260408120546125d8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c9576000612604600183613802565b855490915060009061261890600190613802565b905081811461267d576000866000018281548110612638576126386134e2565b906000526020600020015490508087600001848154811061265b5761265b6134e2565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268e5761268e61391b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126fa575081155b1561270457505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274a90700100000000000000000000000000000000900463ffffffff1642613802565b9050801561280a578183111561278c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c69083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123c5565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128c15773ffffffffffffffffffffffffffffffffffffffff8416612869576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129d45760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906129059082613802565b61290f878a613802565b6129199190613908565b612923919061394a565b905073ffffffffffffffffffffffffffffffffffffffff861661297c576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129de8584613802565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a94578161193f565b5090919050565b508054612aa79061307f565b6000825580601f10612ab7575050565b601f0160209004906000526020600020908101906114be91905b80821115612ae55760008155600101612ad1565b5090565b600060208284031215612afb57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b4357600080fd5b919050565b600060208284031215612b5a57600080fd5b61193f82612b2b565b6000815180845260005b81811015612b8957602081850181015186830182015201612b6d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b63565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b4381612bda565b600060208284031215612c1957600080fd5b813561193f81612bda565b600060208284031215612c3657600080fd5b813567ffffffffffffffff811115612c4d57600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c7257600080fd5b50813567ffffffffffffffff811115612c8a57600080fd5b6020830191508360208260051b8501011115612ca557600080fd5b9250929050565b60008060008060408587031215612cc257600080fd5b843567ffffffffffffffff80821115612cda57600080fd5b612ce688838901612c60565b90965094506020870135915080821115612cff57600080fd5b50612d0c87828801612c60565b95989497509550505050565b600080600060408486031215612d2d57600080fd5b612d3684612b2b565b9250602084013567ffffffffffffffff80821115612d5357600080fd5b818601915086601f830112612d6757600080fd5b813581811115612d7657600080fd5b876020828501011115612d8857600080fd5b6020830194508093505050509250925092565b600060208284031215612dad57600080fd5b813567ffffffffffffffff811115612dc457600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612df26060840182612b63565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e2d8282612b63565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e52565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835167ffffffffffffffff1683529284019291840191600101612eac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f2557612f25612ed2565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f2557612f25612ed2565b80151581146114be57600080fd5b8035612b4381612f4e565b80356fffffffffffffffffffffffffffffffff81168114612b4357600080fd5b600060608284031215612f9957600080fd5b6040516060810181811067ffffffffffffffff82111715612fbc57612fbc612ed2565b6040529050808235612fcd81612f4e565b8152612fdb60208401612f67565b6020820152612fec60408401612f67565b60408201525092915050565b600080600060e0848603121561300d57600080fd5b61301684612b2b565b92506130258560208601612f87565b91506130348560808601612f87565b90509250925092565b6000806020838503121561305057600080fd5b823567ffffffffffffffff81111561306757600080fd5b61307385828601612c60565b90969095509350505050565b600181811c9082168061309357607f821691505b6020821081036130cc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130e357600080fd5b813567ffffffffffffffff808211156130fe576130fe612ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561314457613144612ed2565b8160405283815286602085880101111561315d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561319057600080fd5b613198612f01565b823567ffffffffffffffff808211156131b057600080fd5b6131bc368387016130d2565b83526131ca60208601612b2b565b60208401526131db60408601612bfc565b6040840152606085013560608401526131f660808601612bfc565b608084015260a085013591508082111561320f57600080fd5b61321b368387016130d2565b60a084015260c085013591508082111561323457600080fd5b613240368387016130d2565b60c084015260e085013591508082111561325957600080fd5b50613266368286016130d2565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c8101602086101561329b5750805b601f850160051c820191505b818110156132ba578281556001016132a7565b505050505050565b67ffffffffffffffff8311156132da576132da612ed2565b6132ee836132e8835461307f565b83613272565b6000601f841160018114613340576000851561330a5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bb2565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561338f578685013582556020948501946001909201910161336f565b50868210156133ca577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133ef6040830186612b63565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561345257600080fd5b60405160a0810167ffffffffffffffff828210818311171561347657613476612ed2565b81604052843591508082111561348b57600080fd5b50613498368286016130d2565b8252506134a760208401612b2b565b602082015260408301356134ba81612bda565b60408201526060838101359082015260808301356134d781612bda565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261354557600080fd5b9190910192915050565b6000610140823603121561356257600080fd5b61356a612f2b565b61357383612b2b565b815261358160208401612f5c565b6020820152604083013567ffffffffffffffff808211156135a157600080fd5b6135ad368387016130d2565b604084015260608501359150808211156135c657600080fd5b506135d3368286016130d2565b6060830152506135e63660808501612f87565b60808201526135f83660e08501612f87565b60a082015292915050565b815167ffffffffffffffff81111561361d5761361d612ed2565b6136318161362b845461307f565b84613272565b602080601f831160018114613684576000841561364e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132ba565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136d1578886015182559484019460019091019084016136b2565b508582101561370d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261374181840187612b63565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061377f9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e2d565b6000602082840312156137c857600080fd5b815161193f81612f4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137d3565b67ffffffffffffffff8416815260e0810161386160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e7565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e657600080fd5b815161193f81612bda565b80820281158282048414176105f3576105f36137d3565b808201808211156105f3576105f36137d3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613980577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b506040516200450b3803806200450b8339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508082146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161399262000b79600039600081816104dd01528181611777015261215b0152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b45015281816120f1015261234601526139926000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae9565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b48565b6105f9565b6040516101d29190612bc7565b6101ee6040518060400160405280601b81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e30000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c07565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c24565b6106a9565b604051905181526020016101d2565b6103006102fb366004612cac565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d18565b6108aa565b610300610a1e565b610300610349366004612c07565b610b1b565b6101c661035c366004612b48565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d9b565b610b81565b6040516101d29190612dd6565b6103a7610c28565b6040516101d29190612e36565b6103c76103c2366004612b48565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b48565b610d0e565b610300610462366004612c07565b610d39565b61046f610e14565b6040516101d29190612e90565b6103c761048a366004612b48565b610ecc565b61030061049d366004612ff8565b610f9e565b6103006104b036600461303d565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c07565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061307f565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361317d565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c07565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c07565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109299061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546109559061307f565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132c2565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133dc565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba183613440565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b48565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb9565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc6565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061307f565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb9565b90506000815167ffffffffffffffff811115610e4057610e40612ed2565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134e2565b6020026020010151828281518110610ea457610ea46134e2565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc6565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c78565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134e2565b90506020028101906110609190613511565b6110699061354f565b905061107e8160800151826020015115611d62565b6110918160a00151826020015115611d62565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e9b565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906113259082613603565b506060820151600582019061133a9082613603565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c29550611380949392919061371d565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea7565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a9b565b611461600583016000612a9b565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611eb3565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b6565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa8565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc7565b6116ee826020015183606001516120ce565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134e2565b6020026020010151905061180a81600261211590919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134e2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612137565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b6565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612159565b611afe81602001516121d8565b6114be81602001518260600151612326565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015611b9e57600080fd5b505af1158015611bb2573d6000803e3d6000fd5b5050505050565b6060600061193f8361236a565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c5482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c389190613802565b85608001516fffffffffffffffffffffffffffffffff166123c5565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c8183610b6a565b611cc3576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cce826000611d62565b67ffffffffffffffff83166000908152600760205260409020611cf190836123ef565b611cfc816000611d62565b67ffffffffffffffff83166000908152600760205260409020611d2290600201826123ef565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d5593929190613815565b60405180910390a1505050565b815115611e295781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db8575060408201516fffffffffffffffffffffffffffffffff16155b15611df157816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e62575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b600061193f8383612591565b600061193f83836125e0565b3373ffffffffffffffffffffffffffffffffffffffff821603611f32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fb181610b6a565b611ff3576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612072573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209691906137b6565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126d3565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125e0565b600061193f8373ffffffffffffffffffffffffffffffffffffffff8416612591565b7f0000000000000000000000000000000000000000000000000000000000000000156114be5761218a600282612a56565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121e181610b6a565b612223576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c091906138d4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126d3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a65750505050509050919050565b60006123e4856123d584866138f1565b6123df9087613908565b612a85565b90505b949350505050565b815460009061241890700100000000000000000000000000000000900463ffffffff1642613802565b905080156124ba5760018301548354612460916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123c5565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124e0916fffffffffffffffffffffffffffffffff9081169116612a85565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d55908490613898565b60008181526001830160205260408120546125d8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c9576000612604600183613802565b855490915060009061261890600190613802565b905080821461267d576000866000018281548110612638576126386134e2565b906000526020600020015490508087600001848154811061265b5761265b6134e2565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268e5761268e61391b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126fa575081155b1561270457505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274a90700100000000000000000000000000000000900463ffffffff1642613802565b9050801561280a578183111561278c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c69083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123c5565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128c15773ffffffffffffffffffffffffffffffffffffffff8416612869576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129d45760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906129059082613802565b61290f878a613802565b6129199190613908565b612923919061394a565b905073ffffffffffffffffffffffffffffffffffffffff861661297c576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129de8584613802565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a94578161193f565b5090919050565b508054612aa79061307f565b6000825580601f10612ab7575050565b601f0160209004906000526020600020908101906114be91905b80821115612ae55760008155600101612ad1565b5090565b600060208284031215612afb57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b4357600080fd5b919050565b600060208284031215612b5a57600080fd5b61193f82612b2b565b6000815180845260005b81811015612b8957602081850181015186830182015201612b6d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b63565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b4381612bda565b600060208284031215612c1957600080fd5b813561193f81612bda565b600060208284031215612c3657600080fd5b813567ffffffffffffffff811115612c4d57600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c7257600080fd5b50813567ffffffffffffffff811115612c8a57600080fd5b6020830191508360208260051b8501011115612ca557600080fd5b9250929050565b60008060008060408587031215612cc257600080fd5b843567ffffffffffffffff80821115612cda57600080fd5b612ce688838901612c60565b90965094506020870135915080821115612cff57600080fd5b50612d0c87828801612c60565b95989497509550505050565b600080600060408486031215612d2d57600080fd5b612d3684612b2b565b9250602084013567ffffffffffffffff80821115612d5357600080fd5b818601915086601f830112612d6757600080fd5b813581811115612d7657600080fd5b876020828501011115612d8857600080fd5b6020830194508093505050509250925092565b600060208284031215612dad57600080fd5b813567ffffffffffffffff811115612dc457600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612df26060840182612b63565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e2d8282612b63565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e52565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835167ffffffffffffffff1683529284019291840191600101612eac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f2557612f25612ed2565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f2557612f25612ed2565b80151581146114be57600080fd5b8035612b4381612f4e565b80356fffffffffffffffffffffffffffffffff81168114612b4357600080fd5b600060608284031215612f9957600080fd5b6040516060810181811067ffffffffffffffff82111715612fbc57612fbc612ed2565b6040529050808235612fcd81612f4e565b8152612fdb60208401612f67565b6020820152612fec60408401612f67565b60408201525092915050565b600080600060e0848603121561300d57600080fd5b61301684612b2b565b92506130258560208601612f87565b91506130348560808601612f87565b90509250925092565b6000806020838503121561305057600080fd5b823567ffffffffffffffff81111561306757600080fd5b61307385828601612c60565b90969095509350505050565b600181811c9082168061309357607f821691505b6020821081036130cc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130e357600080fd5b813567ffffffffffffffff808211156130fe576130fe612ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561314457613144612ed2565b8160405283815286602085880101111561315d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561319057600080fd5b613198612f01565b823567ffffffffffffffff808211156131b057600080fd5b6131bc368387016130d2565b83526131ca60208601612b2b565b60208401526131db60408601612bfc565b6040840152606085013560608401526131f660808601612bfc565b608084015260a085013591508082111561320f57600080fd5b61321b368387016130d2565b60a084015260c085013591508082111561323457600080fd5b613240368387016130d2565b60c084015260e085013591508082111561325957600080fd5b50613266368286016130d2565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c8101602086101561329b5750805b601f850160051c820191505b818110156132ba578281556001016132a7565b505050505050565b67ffffffffffffffff8311156132da576132da612ed2565b6132ee836132e8835461307f565b83613272565b6000601f841160018114613340576000851561330a5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bb2565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561338f578685013582556020948501946001909201910161336f565b50868210156133ca577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133ef6040830186612b63565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561345257600080fd5b60405160a0810167ffffffffffffffff828210818311171561347657613476612ed2565b81604052843591508082111561348b57600080fd5b50613498368286016130d2565b8252506134a760208401612b2b565b602082015260408301356134ba81612bda565b60408201526060838101359082015260808301356134d781612bda565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261354557600080fd5b9190910192915050565b6000610140823603121561356257600080fd5b61356a612f2b565b61357383612b2b565b815261358160208401612f5c565b6020820152604083013567ffffffffffffffff808211156135a157600080fd5b6135ad368387016130d2565b604084015260608501359150808211156135c657600080fd5b506135d3368286016130d2565b6060830152506135e63660808501612f87565b60808201526135f83660e08501612f87565b60a082015292915050565b815167ffffffffffffffff81111561361d5761361d612ed2565b6136318161362b845461307f565b84613272565b602080601f831160018114613684576000841561364e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132ba565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136d1578886015182559484019460019091019084016136b2565b508582101561370d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261374181840187612b63565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061377f9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e2d565b6000602082840312156137c857600080fd5b815161193f81612f4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137d3565b67ffffffffffffffff8416815260e0810161386160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e7565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e657600080fd5b815161193f81612bda565b80820281158282048414176105f3576105f36137d3565b808201808211156105f3576105f36137d3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613980577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var BurnFromMintTokenPoolABI = BurnFromMintTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go index c07e6e059e..244f04596a 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnMintTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620040b3380380620040b383398101604081905262000034916200054c565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000176565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001685760408051600081526020810190915262000168908462000221565b5050505050505050620006aa565b336001600160a01b03821603620001d05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000242576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002cd5760008382815181106200026657620002666200065c565b60209081029190910101519050620002806002826200037e565b15620002c3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000245565b5060005b815181101562000379576000828281518110620002f257620002f26200065c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200031e575062000370565b6200032b6002826200039e565b156200036e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d1565b505050565b600062000395836001600160a01b038416620003b5565b90505b92915050565b600062000395836001600160a01b038416620004b9565b60008181526001830160205260408120548015620004ae576000620003dc60018362000672565b8554909150600090620003f29060019062000672565b90508181146200045e5760008660000182815481106200041657620004166200065c565b90600052602060002001549050808760000184815481106200043c576200043c6200065c565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000472576200047262000694565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000398565b600091505062000398565b6000818152600183016020526040812054620005025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000398565b50600062000398565b6001600160a01b03811681146200052157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000547816200050b565b919050565b600080600080608085870312156200056357600080fd5b845162000570816200050b565b602086810151919550906001600160401b03808211156200059057600080fd5b818801915088601f830112620005a557600080fd5b815181811115620005ba57620005ba62000524565b8060051b604051601f19603f83011681018181108582111715620005e257620005e262000524565b60405291825284820192508381018501918b8311156200060157600080fd5b938501935b828510156200062a576200061a856200053a565b8452938501939285019262000606565b80985050505050505062000641604086016200053a565b915062000651606086016200053a565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161398c62000727600039600081816104dd0152818161177701526121550152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b3f015281816120eb0152612340015261398c6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae3565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b42565b6105f9565b6040516101d29190612bc1565b6101ee6040518060400160405280601781526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e3000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c01565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c1e565b6106a9565b604051905181526020016101d2565b6103006102fb366004612ca6565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d12565b6108aa565b610300610a1e565b610300610349366004612c01565b610b1b565b6101c661035c366004612b42565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d95565b610b81565b6040516101d29190612dd0565b6103a7610c28565b6040516101d29190612e30565b6103c76103c2366004612b42565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b42565b610d0e565b610300610462366004612c01565b610d39565b61046f610e14565b6040516101d29190612e8a565b6103c761048a366004612b42565b610ecc565b61030061049d366004612ff2565b610f9e565b6103006104b0366004613037565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c01565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061062490613079565b80601f016020809104026020016040519081016040528092919081815260200182805461065090613079565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c483613177565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c01565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c01565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461092990613079565b80601f016020809104026020016040519081016040528092919081815260200182805461095590613079565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132bc565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133d6565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba18361343a565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b42565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb3565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc0565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061062490613079565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb3565b90506000815167ffffffffffffffff811115610e4057610e40612ecc565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134dc565b6020026020010151828281518110610ea457610ea46134dc565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc0565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c72565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134dc565b9050602002810190611060919061350b565b61106990613549565b905061107e8160800151826020015115611d5c565b6110918160a00151826020015115611d5c565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e95565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061132590826135fd565b506060820151600582019061133a90826135fd565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506113809493929190613717565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea1565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a95565b611461600583016000612a95565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611ead565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b0565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa2565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc1565b6116ee826020015183606001516120c8565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134dc565b6020026020010151905061180a81600261210f90919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134dc565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612131565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b0565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612153565b611afe81602001516121d2565b6114be81602001518260600151612320565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611b9857600080fd5b505af1158015611bac573d6000803e3d6000fd5b5050505050565b6060600061193f83612364565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c4e82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c3291906137fc565b85608001516fffffffffffffffffffffffffffffffff166123bf565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c7b83610b6a565b611cbd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cc8826000611d5c565b67ffffffffffffffff83166000908152600760205260409020611ceb90836123e9565b611cf6816000611d5c565b67ffffffffffffffff83166000908152600760205260409020611d1c90600201826123e9565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d4f9392919061380f565b60405180910390a1505050565b815115611e235781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db2575060408201516fffffffffffffffffffffffffffffffff16155b15611deb57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613892565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e5c575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613892565b600061193f838361258b565b600061193f83836125da565b3373ffffffffffffffffffffffffffffffffffffffff821603611f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fab81610b6a565b611fed576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561206c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209091906137b0565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126cd565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125da565b600061193f8373ffffffffffffffffffffffffffffffffffffffff841661258b565b7f0000000000000000000000000000000000000000000000000000000000000000156114be57612184600282612a50565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121db81610b6a565b61221d576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ba91906138ce565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126cd565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a05750505050509050919050565b60006123de856123cf84866138eb565b6123d99087613902565b612a7f565b90505b949350505050565b815460009061241290700100000000000000000000000000000000900463ffffffff16426137fc565b905080156124b4576001830154835461245a916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123bf565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124da916fffffffffffffffffffffffffffffffff9081169116612a7f565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d4f908490613892565b60008181526001830160205260408120546125d2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c35760006125fe6001836137fc565b8554909150600090612612906001906137fc565b9050818114612677576000866000018281548110612632576126326134dc565b9060005260206000200154905080876000018481548110612655576126556134dc565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268857612688613915565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126f4575081155b156126fe57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274490700100000000000000000000000000000000900463ffffffff16426137fc565b905080156128045781831115612786576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c09083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123bf565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128bb5773ffffffffffffffffffffffffffffffffffffffff8416612863576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129ce5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128ff90826137fc565b612909878a6137fc565b6129139190613902565b61291d9190613944565b905073ffffffffffffffffffffffffffffffffffffffff8616612976576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129d885846137fc565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a8e578161193f565b5090919050565b508054612aa190613079565b6000825580601f10612ab1575050565b601f0160209004906000526020600020908101906114be91905b80821115612adf5760008155600101612acb565b5090565b600060208284031215612af557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b3d57600080fd5b919050565b600060208284031215612b5457600080fd5b61193f82612b25565b6000815180845260005b81811015612b8357602081850181015186830182015201612b67565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b5d565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b3d81612bd4565b600060208284031215612c1357600080fd5b813561193f81612bd4565b600060208284031215612c3057600080fd5b813567ffffffffffffffff811115612c4757600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c6c57600080fd5b50813567ffffffffffffffff811115612c8457600080fd5b6020830191508360208260051b8501011115612c9f57600080fd5b9250929050565b60008060008060408587031215612cbc57600080fd5b843567ffffffffffffffff80821115612cd457600080fd5b612ce088838901612c5a565b90965094506020870135915080821115612cf957600080fd5b50612d0687828801612c5a565b95989497509550505050565b600080600060408486031215612d2757600080fd5b612d3084612b25565b9250602084013567ffffffffffffffff80821115612d4d57600080fd5b818601915086601f830112612d6157600080fd5b813581811115612d7057600080fd5b876020828501011115612d8257600080fd5b6020830194508093505050509250925092565b600060208284031215612da757600080fd5b813567ffffffffffffffff811115612dbe57600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612dec6060840182612b5d565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e278282612b5d565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e7e57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e4c565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e7e57835167ffffffffffffffff1683529284019291840191600101612ea6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f1f57612f1f612ecc565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f1f57612f1f612ecc565b80151581146114be57600080fd5b8035612b3d81612f48565b80356fffffffffffffffffffffffffffffffff81168114612b3d57600080fd5b600060608284031215612f9357600080fd5b6040516060810181811067ffffffffffffffff82111715612fb657612fb6612ecc565b6040529050808235612fc781612f48565b8152612fd560208401612f61565b6020820152612fe660408401612f61565b60408201525092915050565b600080600060e0848603121561300757600080fd5b61301084612b25565b925061301f8560208601612f81565b915061302e8560808601612f81565b90509250925092565b6000806020838503121561304a57600080fd5b823567ffffffffffffffff81111561306157600080fd5b61306d85828601612c5a565b90969095509350505050565b600181811c9082168061308d57607f821691505b6020821081036130c6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130dd57600080fd5b813567ffffffffffffffff808211156130f8576130f8612ecc565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561313e5761313e612ecc565b8160405283815286602085880101111561315757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561318a57600080fd5b613192612efb565b823567ffffffffffffffff808211156131aa57600080fd5b6131b6368387016130cc565b83526131c460208601612b25565b60208401526131d560408601612bf6565b6040840152606085013560608401526131f060808601612bf6565b608084015260a085013591508082111561320957600080fd5b613215368387016130cc565b60a084015260c085013591508082111561322e57600080fd5b61323a368387016130cc565b60c084015260e085013591508082111561325357600080fd5b50613260368286016130cc565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c810160208610156132955750805b601f850160051c820191505b818110156132b4578281556001016132a1565b505050505050565b67ffffffffffffffff8311156132d4576132d4612ecc565b6132e8836132e28354613079565b8361326c565b6000601f84116001811461333a57600085156133045750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bac565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156133895786850135825560209485019460019092019101613369565b50868210156133c4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133e96040830186612b5d565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561344c57600080fd5b60405160a0810167ffffffffffffffff828210818311171561347057613470612ecc565b81604052843591508082111561348557600080fd5b50613492368286016130cc565b8252506134a160208401612b25565b602082015260408301356134b481612bd4565b60408201526060838101359082015260808301356134d181612bd4565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261353f57600080fd5b9190910192915050565b6000610140823603121561355c57600080fd5b613564612f25565b61356d83612b25565b815261357b60208401612f56565b6020820152604083013567ffffffffffffffff8082111561359b57600080fd5b6135a7368387016130cc565b604084015260608501359150808211156135c057600080fd5b506135cd368286016130cc565b6060830152506135e03660808501612f81565b60808201526135f23660e08501612f81565b60a082015292915050565b815167ffffffffffffffff81111561361757613617612ecc565b61362b816136258454613079565b8461326c565b602080601f83116001811461367e57600084156136485750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132b4565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136cb578886015182559484019460019091019084016136ac565b508582101561370757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261373b81840187612b5d565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506137799050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e27565b6000602082840312156137c257600080fd5b815161193f81612f48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137cd565b67ffffffffffffffff8416815260e0810161385b60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e1565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e057600080fd5b815161193f81612bd4565b80820281158282048414176105f3576105f36137cd565b808201808211156105f3576105f36137cd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261397a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b50604051620040b3380380620040b383398101604081905262000034916200054c565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000176565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001685760408051600081526020810190915262000168908462000221565b5050505050505050620006aa565b336001600160a01b03821603620001d05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000242576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002cd5760008382815181106200026657620002666200065c565b60209081029190910101519050620002806002826200037e565b15620002c3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000245565b5060005b815181101562000379576000828281518110620002f257620002f26200065c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200031e575062000370565b6200032b6002826200039e565b156200036e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d1565b505050565b600062000395836001600160a01b038416620003b5565b90505b92915050565b600062000395836001600160a01b038416620004b9565b60008181526001830160205260408120548015620004ae576000620003dc60018362000672565b8554909150600090620003f29060019062000672565b90508082146200045e5760008660000182815481106200041657620004166200065c565b90600052602060002001549050808760000184815481106200043c576200043c6200065c565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000472576200047262000694565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000398565b600091505062000398565b6000818152600183016020526040812054620005025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000398565b50600062000398565b6001600160a01b03811681146200052157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000547816200050b565b919050565b600080600080608085870312156200056357600080fd5b845162000570816200050b565b602086810151919550906001600160401b03808211156200059057600080fd5b818801915088601f830112620005a557600080fd5b815181811115620005ba57620005ba62000524565b8060051b604051601f19603f83011681018181108582111715620005e257620005e262000524565b60405291825284820192508381018501918b8311156200060157600080fd5b938501935b828510156200062a576200061a856200053a565b8452938501939285019262000606565b80985050505050505062000641604086016200053a565b915062000651606086016200053a565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161398c62000727600039600081816104dd0152818161177701526121550152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b3f015281816120eb0152612340015261398c6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae3565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b42565b6105f9565b6040516101d29190612bc1565b6101ee6040518060400160405280601781526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e3000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c01565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c1e565b6106a9565b604051905181526020016101d2565b6103006102fb366004612ca6565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d12565b6108aa565b610300610a1e565b610300610349366004612c01565b610b1b565b6101c661035c366004612b42565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d95565b610b81565b6040516101d29190612dd0565b6103a7610c28565b6040516101d29190612e30565b6103c76103c2366004612b42565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b42565b610d0e565b610300610462366004612c01565b610d39565b61046f610e14565b6040516101d29190612e8a565b6103c761048a366004612b42565b610ecc565b61030061049d366004612ff2565b610f9e565b6103006104b0366004613037565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c01565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061062490613079565b80601f016020809104026020016040519081016040528092919081815260200182805461065090613079565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c483613177565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c01565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c01565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461092990613079565b80601f016020809104026020016040519081016040528092919081815260200182805461095590613079565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132bc565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133d6565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba18361343a565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b42565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb3565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc0565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061062490613079565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb3565b90506000815167ffffffffffffffff811115610e4057610e40612ecc565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134dc565b6020026020010151828281518110610ea457610ea46134dc565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc0565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c72565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134dc565b9050602002810190611060919061350b565b61106990613549565b905061107e8160800151826020015115611d5c565b6110918160a00151826020015115611d5c565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e95565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061132590826135fd565b506060820151600582019061133a90826135fd565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506113809493929190613717565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea1565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a95565b611461600583016000612a95565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611ead565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b0565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa2565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc1565b6116ee826020015183606001516120c8565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134dc565b6020026020010151905061180a81600261210f90919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134dc565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612131565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b0565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612153565b611afe81602001516121d2565b6114be81602001518260600151612320565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611b9857600080fd5b505af1158015611bac573d6000803e3d6000fd5b5050505050565b6060600061193f83612364565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c4e82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c3291906137fc565b85608001516fffffffffffffffffffffffffffffffff166123bf565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c7b83610b6a565b611cbd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cc8826000611d5c565b67ffffffffffffffff83166000908152600760205260409020611ceb90836123e9565b611cf6816000611d5c565b67ffffffffffffffff83166000908152600760205260409020611d1c90600201826123e9565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d4f9392919061380f565b60405180910390a1505050565b815115611e235781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db2575060408201516fffffffffffffffffffffffffffffffff16155b15611deb57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613892565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e5c575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613892565b600061193f838361258b565b600061193f83836125da565b3373ffffffffffffffffffffffffffffffffffffffff821603611f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fab81610b6a565b611fed576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561206c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209091906137b0565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126cd565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125da565b600061193f8373ffffffffffffffffffffffffffffffffffffffff841661258b565b7f0000000000000000000000000000000000000000000000000000000000000000156114be57612184600282612a50565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121db81610b6a565b61221d576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ba91906138ce565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126cd565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a05750505050509050919050565b60006123de856123cf84866138eb565b6123d99087613902565b612a7f565b90505b949350505050565b815460009061241290700100000000000000000000000000000000900463ffffffff16426137fc565b905080156124b4576001830154835461245a916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123bf565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124da916fffffffffffffffffffffffffffffffff9081169116612a7f565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d4f908490613892565b60008181526001830160205260408120546125d2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c35760006125fe6001836137fc565b8554909150600090612612906001906137fc565b9050808214612677576000866000018281548110612632576126326134dc565b9060005260206000200154905080876000018481548110612655576126556134dc565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268857612688613915565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126f4575081155b156126fe57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274490700100000000000000000000000000000000900463ffffffff16426137fc565b905080156128045781831115612786576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c09083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123bf565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128bb5773ffffffffffffffffffffffffffffffffffffffff8416612863576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129ce5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128ff90826137fc565b612909878a6137fc565b6129139190613902565b61291d9190613944565b905073ffffffffffffffffffffffffffffffffffffffff8616612976576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129d885846137fc565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a8e578161193f565b5090919050565b508054612aa190613079565b6000825580601f10612ab1575050565b601f0160209004906000526020600020908101906114be91905b80821115612adf5760008155600101612acb565b5090565b600060208284031215612af557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b3d57600080fd5b919050565b600060208284031215612b5457600080fd5b61193f82612b25565b6000815180845260005b81811015612b8357602081850181015186830182015201612b67565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b5d565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b3d81612bd4565b600060208284031215612c1357600080fd5b813561193f81612bd4565b600060208284031215612c3057600080fd5b813567ffffffffffffffff811115612c4757600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c6c57600080fd5b50813567ffffffffffffffff811115612c8457600080fd5b6020830191508360208260051b8501011115612c9f57600080fd5b9250929050565b60008060008060408587031215612cbc57600080fd5b843567ffffffffffffffff80821115612cd457600080fd5b612ce088838901612c5a565b90965094506020870135915080821115612cf957600080fd5b50612d0687828801612c5a565b95989497509550505050565b600080600060408486031215612d2757600080fd5b612d3084612b25565b9250602084013567ffffffffffffffff80821115612d4d57600080fd5b818601915086601f830112612d6157600080fd5b813581811115612d7057600080fd5b876020828501011115612d8257600080fd5b6020830194508093505050509250925092565b600060208284031215612da757600080fd5b813567ffffffffffffffff811115612dbe57600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612dec6060840182612b5d565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e278282612b5d565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e7e57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e4c565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e7e57835167ffffffffffffffff1683529284019291840191600101612ea6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f1f57612f1f612ecc565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f1f57612f1f612ecc565b80151581146114be57600080fd5b8035612b3d81612f48565b80356fffffffffffffffffffffffffffffffff81168114612b3d57600080fd5b600060608284031215612f9357600080fd5b6040516060810181811067ffffffffffffffff82111715612fb657612fb6612ecc565b6040529050808235612fc781612f48565b8152612fd560208401612f61565b6020820152612fe660408401612f61565b60408201525092915050565b600080600060e0848603121561300757600080fd5b61301084612b25565b925061301f8560208601612f81565b915061302e8560808601612f81565b90509250925092565b6000806020838503121561304a57600080fd5b823567ffffffffffffffff81111561306157600080fd5b61306d85828601612c5a565b90969095509350505050565b600181811c9082168061308d57607f821691505b6020821081036130c6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130dd57600080fd5b813567ffffffffffffffff808211156130f8576130f8612ecc565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561313e5761313e612ecc565b8160405283815286602085880101111561315757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561318a57600080fd5b613192612efb565b823567ffffffffffffffff808211156131aa57600080fd5b6131b6368387016130cc565b83526131c460208601612b25565b60208401526131d560408601612bf6565b6040840152606085013560608401526131f060808601612bf6565b608084015260a085013591508082111561320957600080fd5b613215368387016130cc565b60a084015260c085013591508082111561322e57600080fd5b61323a368387016130cc565b60c084015260e085013591508082111561325357600080fd5b50613260368286016130cc565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c810160208610156132955750805b601f850160051c820191505b818110156132b4578281556001016132a1565b505050505050565b67ffffffffffffffff8311156132d4576132d4612ecc565b6132e8836132e28354613079565b8361326c565b6000601f84116001811461333a57600085156133045750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bac565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156133895786850135825560209485019460019092019101613369565b50868210156133c4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133e96040830186612b5d565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561344c57600080fd5b60405160a0810167ffffffffffffffff828210818311171561347057613470612ecc565b81604052843591508082111561348557600080fd5b50613492368286016130cc565b8252506134a160208401612b25565b602082015260408301356134b481612bd4565b60408201526060838101359082015260808301356134d181612bd4565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261353f57600080fd5b9190910192915050565b6000610140823603121561355c57600080fd5b613564612f25565b61356d83612b25565b815261357b60208401612f56565b6020820152604083013567ffffffffffffffff8082111561359b57600080fd5b6135a7368387016130cc565b604084015260608501359150808211156135c057600080fd5b506135cd368286016130cc565b6060830152506135e03660808501612f81565b60808201526135f23660e08501612f81565b60a082015292915050565b815167ffffffffffffffff81111561361757613617612ecc565b61362b816136258454613079565b8461326c565b602080601f83116001811461367e57600084156136485750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132b4565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136cb578886015182559484019460019091019084016136ac565b508582101561370757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261373b81840187612b5d565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506137799050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e27565b6000602082840312156137c257600080fd5b815161193f81612f48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137cd565b67ffffffffffffffff8416815260e0810161385b60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e1565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e057600080fd5b815161193f81612bd4565b80820281158282048414176105f3576105f36137cd565b808201808211156105f3576105f36137cd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261397a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var BurnMintTokenPoolABI = BurnMintTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go index 901f745dbb..0838134fdd 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnMintTokenPoolAndProxyMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b506040516200494a3803806200494a833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050818114620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051614214620007366000396000818161053701528181611abf0152612511015260008181610511015281816118520152611d7201526000818161025a015281816102af0152818161075701528181610ddd0152818161177201528181611c9201528181611e78015281816124a701526126fc01526142146000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639766b93211610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104fc578063dc0bd9711461050f578063e0351e1314610535578063f2fde38b1461055b57600080fd5b8063c0d78655146104ae578063c4bffe2b146104c1578063c75eea9c146104d6578063cf7401f3146104e957600080fd5b8063a8d87a3b116100de578063a8d87a3b146103fb578063af58d59f1461040e578063b0f479a11461047d578063b79465801461049b57600080fd5b80639766b932146103b35780639a4575b9146103c6578063a7cd63b7146103e657600080fd5b80636d3d1a58116101715780637d54534e1161014b5780637d54534e1461035c57806383826b2b1461036f5780638926f54f146103825780638da5cb5b1461039557600080fd5b80636d3d1a581461032357806378a010b21461034157806379ba50971461035457600080fd5b806321df0da7116101ad57806321df0da714610258578063240028e81461029f57806339077537146102ec57806354c8a4f31461030e57600080fd5b806301ffc9a7146101d45780630a2fd493146101fc578063181f5a771461021c575b600080fd5b6101e76101e23660046131a9565b61056e565b60405190151581526020015b60405180910390f35b61020f61020a366004613208565b610653565b6040516101f39190613291565b61020f6040518060400160405280601f81526020017f4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e300081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e76102ad3660046132d1565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102ff6102fa3660046132ee565b610703565b604051905181526020016101f3565b61032161031c366004613376565b6108bb565b005b60085473ffffffffffffffffffffffffffffffffffffffff1661027a565b61032161034f3660046133e2565b610936565b610321610aaa565b61032161036a3660046132d1565b610ba7565b6101e761037d366004613465565b610bf6565b6101e7610390366004613208565b610cc3565b60005473ffffffffffffffffffffffffffffffffffffffff1661027a565b6103216103c13660046132d1565b610cda565b6103d96103d436600461349c565b610d69565b6040516101f391906134d7565b6103ee610ed9565b6040516101f39190613537565b61027a610409366004613208565b503090565b61042161041c366004613208565b610eea565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff1661027a565b61020f6104a9366004613208565b610fbf565b6103216104bc3660046132d1565b610fea565b6104c96110be565b6040516101f39190613591565b6104216104e4366004613208565b611176565b6103216104f7366004613748565b611248565b61032161050a36600461378d565b6112d1565b7f000000000000000000000000000000000000000000000000000000000000000061027a565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b6103216105693660046132d1565b611757565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061060157507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061064d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061067e906137cf565b80601f01602080910402602001604051908101604052809291908181526020018280546106aa906137cf565b80156106f75780601f106106cc576101008083540402835291602001916106f7565b820191906000526020600020905b8154815290600101906020018083116106da57829003601f168201915b50505050509050919050565b60408051602081019091526000815261072361071e836138be565b61176b565b60095473ffffffffffffffffffffffffffffffffffffffff166108195773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961078c60608501604086016132d1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b1580156107fc57600080fd5b505af1158015610810573d6000803e3d6000fd5b5050505061082a565b61082a610825836138be565b61199c565b61083a60608301604084016132d1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161089c91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108c3611a3a565b61093084848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611abd92505050565b50505050565b61093e611a3a565b61094783610cc3565b61098e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109b5906137cf565b80601f01602080910402602001604051908101604052809291908181526020018280546109e1906137cf565b8015610a2e5780601f10610a0357610100808354040283529160200191610a2e565b820191906000526020600020905b815481529060010190602001808311610a1157829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a5d838583613a03565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a9c93929190613b1d565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610985565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610baf611a3a565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610cbc5750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610c98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbc9190613b81565b9392505050565b600061064d600567ffffffffffffffff8416611c73565b610ce2611a3a565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d8e610d8983613b9e565b611c8b565b60095473ffffffffffffffffffffffffffffffffffffffff16610e53576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610e3657600080fd5b505af1158015610e4a573d6000803e3d6000fd5b50505050610e64565b610e64610e5f83613b9e565b611e55565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610ebe8460200160208101906104a99190613208565b81526040805160208181019092526000815291015292915050565b6060610ee56002611f6f565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261064d90611f7c565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061067e906137cf565b610ff2611a3a565b73ffffffffffffffffffffffffffffffffffffffff811661103f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d5d565b606060006110cc6005611f6f565b90506000815167ffffffffffffffff8111156110ea576110ea6135d3565b604051908082528060200260200182016040528015611113578160200160208202803683370190505b50905060005b825181101561116f5782818151811061113457611134613c40565b602002602001015182828151811061114e5761114e613c40565b67ffffffffffffffff90921660209283029190910190910152600101611119565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261064d90611f7c565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611288575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112c1576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610985565b6112cc83838361202e565b505050565b6112d9611a3a565b60005b818110156112cc5760008383838181106112f8576112f8613c40565b905060200281019061130a9190613c6f565b61131390613cad565b90506113288160800151826020015115612118565b61133b8160a00151826020015115612118565b80602001511561163757805161135d9060059067ffffffffffffffff16612251565b6113a25780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610985565b60408101515115806113b75750606081015151155b156113ee576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115cf9082613d61565b50606082015160058201906115e49082613d61565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061162a9493929190613e7b565b60405180910390a161174e565b805161164f9060059067ffffffffffffffff1661225d565b6116945780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610985565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116fd600483018261315b565b61170b60058301600061315b565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112dc565b61175f611a3a565b61176881612269565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146118005760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610985565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156118ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d29190613b81565b15611909576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611916816020015161235e565b60006119258260200151610653565b9050805160001480611949575080805190602001208260a001518051906020012014155b15611986578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109859190613291565b61199882602001518360600151612484565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611a059490939291600401613f14565b600060405180830381600087803b158015611a1f57600080fd5b505af1158015611a33573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611abb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610985565b565b7f0000000000000000000000000000000000000000000000000000000000000000611b14576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611baa576000838281518110611b3457611b34613c40565b60200260200101519050611b528160026124cb90919063ffffffff16565b15611ba15760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611b17565b5060005b81518110156112cc576000828281518110611bcb57611bcb613c40565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c0f5750611c6b565b611c1a6002826124ed565b15611c695760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611bae565b60008181526001830160205260408120541515610cbc565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611d205760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610985565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611dce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df29190613b81565b15611e29576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e36816040015161250f565b611e43816020015161258e565b611768816020015182606001516126dc565b6009546060820151611ea29173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690612720565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611f0a94939291600401613f75565b6000604051808303816000875af1158015611f29573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119989190810190613fd5565b60606000610cbc836127ad565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261200a82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611fee9190614072565b85608001516fffffffffffffffffffffffffffffffff16612808565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61203783610cc3565b612079576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610985565b612084826000612118565b67ffffffffffffffff831660009081526007602052604090206120a79083612832565b6120b2816000612118565b67ffffffffffffffff831660009081526007602052604090206120d89060020182612832565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161210b93929190614085565b60405180910390a1505050565b8151156121df5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061216e575060408201516fffffffffffffffffffffffffffffffff16155b156121a757816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109859190614108565b8015611998576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612218575060208201516fffffffffffffffffffffffffffffffff1615155b1561199857816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109859190614108565b6000610cbc83836129d4565b6000610cbc8383612a23565b3373ffffffffffffffffffffffffffffffffffffffff8216036122e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610985565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61236781610cc3565b6123a9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610985565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612428573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061244c9190613b81565b611768576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610985565b67ffffffffffffffff8216600090815260076020526040902061199890600201827f0000000000000000000000000000000000000000000000000000000000000000612b16565b6000610cbc8373ffffffffffffffffffffffffffffffffffffffff8416612a23565b6000610cbc8373ffffffffffffffffffffffffffffffffffffffff84166129d4565b7f00000000000000000000000000000000000000000000000000000000000000001561176857612540600282612e99565b611768576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610985565b61259781610cc3565b6125d9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610985565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126769190614144565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611768576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610985565b67ffffffffffffffff8216600090815260076020526040902061199890827f0000000000000000000000000000000000000000000000000000000000000000612b16565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526112cc908490612ec8565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106f757602002820191906000526020600020905b8154815260200190600101908083116127e95750505050509050919050565b6000612827856128188486614161565b6128229087614178565b612fd4565b90505b949350505050565b815460009061285b90700100000000000000000000000000000000900463ffffffff1642614072565b905080156128fd57600183015483546128a3916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612808565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612923916fffffffffffffffffffffffffffffffff9081169116612fd4565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061210b908490614108565b6000818152600183016020526040812054612a1b5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561064d565b50600061064d565b60008181526001830160205260408120548015612b0c576000612a47600183614072565b8554909150600090612a5b90600190614072565b9050818114612ac0576000866000018281548110612a7b57612a7b613c40565b9060005260206000200154905080876000018481548110612a9e57612a9e613c40565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ad157612ad161418b565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061064d565b600091505061064d565b825474010000000000000000000000000000000000000000900460ff161580612b3d575081155b15612b4757505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612b8d90700100000000000000000000000000000000900463ffffffff1642614072565b90508015612c4d5781831115612bcf576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612c099083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612808565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612d045773ffffffffffffffffffffffffffffffffffffffff8416612cac576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610985565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610985565b84831015612e175760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612d489082614072565b612d52878a614072565b612d5c9190614178565b612d6691906141ba565b905073ffffffffffffffffffffffffffffffffffffffff8616612dbf576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610985565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610985565b612e218584614072565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610cbc565b6000612f2a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612fea9092919063ffffffff16565b8051909150156112cc5780806020019051810190612f489190613b81565b6112cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610985565b6000818310612fe35781610cbc565b5090919050565b606061282a8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161301e91906141f5565b60006040518083038185875af1925050503d806000811461305b576040519150601f19603f3d011682016040523d82523d6000602084013e613060565b606091505b50915091506130718783838761307c565b979650505050505050565b6060831561311257825160000361310b5773ffffffffffffffffffffffffffffffffffffffff85163b61310b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610985565b508161282a565b61282a83838151156131275781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109859190613291565b508054613167906137cf565b6000825580601f10613177575050565b601f01602090049060005260206000209081019061176891905b808211156131a55760008155600101613191565b5090565b6000602082840312156131bb57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610cbc57600080fd5b803567ffffffffffffffff8116811461320357600080fd5b919050565b60006020828403121561321a57600080fd5b610cbc826131eb565b60005b8381101561323e578181015183820152602001613226565b50506000910152565b6000815180845261325f816020860160208601613223565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610cbc6020830184613247565b73ffffffffffffffffffffffffffffffffffffffff8116811461176857600080fd5b8035613203816132a4565b6000602082840312156132e357600080fd5b8135610cbc816132a4565b60006020828403121561330057600080fd5b813567ffffffffffffffff81111561331757600080fd5b82016101008185031215610cbc57600080fd5b60008083601f84011261333c57600080fd5b50813567ffffffffffffffff81111561335457600080fd5b6020830191508360208260051b850101111561336f57600080fd5b9250929050565b6000806000806040858703121561338c57600080fd5b843567ffffffffffffffff808211156133a457600080fd5b6133b08883890161332a565b909650945060208701359150808211156133c957600080fd5b506133d68782880161332a565b95989497509550505050565b6000806000604084860312156133f757600080fd5b613400846131eb565b9250602084013567ffffffffffffffff8082111561341d57600080fd5b818601915086601f83011261343157600080fd5b81358181111561344057600080fd5b87602082850101111561345257600080fd5b6020830194508093505050509250925092565b6000806040838503121561347857600080fd5b613481836131eb565b91506020830135613491816132a4565b809150509250929050565b6000602082840312156134ae57600080fd5b813567ffffffffffffffff8111156134c557600080fd5b820160a08185031215610cbc57600080fd5b6020815260008251604060208401526134f36060840182613247565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261352e8282613247565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613553565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358557835167ffffffffffffffff16835292840192918401916001016135ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613626576136266135d3565b60405290565b60405160c0810167ffffffffffffffff81118282101715613626576136266135d3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613696576136966135d3565b604052919050565b801515811461176857600080fd5b80356132038161369e565b80356fffffffffffffffffffffffffffffffff8116811461320357600080fd5b6000606082840312156136e957600080fd5b6040516060810181811067ffffffffffffffff8211171561370c5761370c6135d3565b604052905080823561371d8161369e565b815261372b602084016136b7565b602082015261373c604084016136b7565b60408201525092915050565b600080600060e0848603121561375d57600080fd5b613766846131eb565b925061377585602086016136d7565b915061378485608086016136d7565b90509250925092565b600080602083850312156137a057600080fd5b823567ffffffffffffffff8111156137b757600080fd5b6137c38582860161332a565b90969095509350505050565b600181811c908216806137e357607f821691505b60208210810361381c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff82111561383c5761383c6135d3565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261387957600080fd5b813561388c61388782613822565b61364f565b8181528460208386010111156138a157600080fd5b816020850160208301376000918101602001919091529392505050565b600061010082360312156138d157600080fd5b6138d9613602565b823567ffffffffffffffff808211156138f157600080fd5b6138fd36838701613868565b835261390b602086016131eb565b602084015261391c604086016132c6565b604084015260608501356060840152613937608086016132c6565b608084015260a085013591508082111561395057600080fd5b61395c36838701613868565b60a084015260c085013591508082111561397557600080fd5b61398136838701613868565b60c084015260e085013591508082111561399a57600080fd5b506139a736828601613868565b60e08301525092915050565b601f8211156112cc576000816000526020600020601f850160051c810160208610156139dc5750805b601f850160051c820191505b818110156139fb578281556001016139e8565b505050505050565b67ffffffffffffffff831115613a1b57613a1b6135d3565b613a2f83613a2983546137cf565b836139b3565b6000601f841160018114613a815760008515613a4b5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a33565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613ad05786850135825560209485019460019092019101613ab0565b5086821015613b0b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613b306040830186613247565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613b9357600080fd5b8151610cbc8161369e565b600060a08236031215613bb057600080fd5b60405160a0810167ffffffffffffffff8282108183111715613bd457613bd46135d3565b816040528435915080821115613be957600080fd5b50613bf636828601613868565b825250613c05602084016131eb565b60208201526040830135613c18816132a4565b6040820152606083810135908201526080830135613c35816132a4565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ca357600080fd5b9190910192915050565b60006101408236031215613cc057600080fd5b613cc861362c565b613cd1836131eb565b8152613cdf602084016136ac565b6020820152604083013567ffffffffffffffff80821115613cff57600080fd5b613d0b36838701613868565b60408401526060850135915080821115613d2457600080fd5b50613d3136828601613868565b606083015250613d4436608085016136d7565b6080820152613d563660e085016136d7565b60a082015292915050565b815167ffffffffffffffff811115613d7b57613d7b6135d3565b613d8f81613d8984546137cf565b846139b3565b602080601f831160018114613de25760008415613dac5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139fb565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e2f57888601518255948401946001909101908401613e10565b5085821015613e6b57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613e9f81840187613247565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613edd9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e083015261352e565b60a081526000613f2760a0830187613247565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613fa460a0830186613247565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613fe757600080fd5b815167ffffffffffffffff811115613ffe57600080fd5b8201601f8101841361400f57600080fd5b805161401d61388782613822565b81815285602083850101111561403257600080fd5b61352e826020830160208601613223565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561064d5761064d614043565b67ffffffffffffffff8416815260e081016140d160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261282a565b6060810161064d82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561415657600080fd5b8151610cbc816132a4565b808202811582820484141761064d5761064d614043565b8082018082111561064d5761064d614043565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826141f0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613ca381846020870161322356fea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b506040516200494a3803806200494a833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050808214620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051614214620007366000396000818161053701528181611abf0152612511015260008181610511015281816118520152611d7201526000818161025a015281816102af0152818161075701528181610ddd0152818161177201528181611c9201528181611e78015281816124a701526126fc01526142146000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639766b93211610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104fc578063dc0bd9711461050f578063e0351e1314610535578063f2fde38b1461055b57600080fd5b8063c0d78655146104ae578063c4bffe2b146104c1578063c75eea9c146104d6578063cf7401f3146104e957600080fd5b8063a8d87a3b116100de578063a8d87a3b146103fb578063af58d59f1461040e578063b0f479a11461047d578063b79465801461049b57600080fd5b80639766b932146103b35780639a4575b9146103c6578063a7cd63b7146103e657600080fd5b80636d3d1a58116101715780637d54534e1161014b5780637d54534e1461035c57806383826b2b1461036f5780638926f54f146103825780638da5cb5b1461039557600080fd5b80636d3d1a581461032357806378a010b21461034157806379ba50971461035457600080fd5b806321df0da7116101ad57806321df0da714610258578063240028e81461029f57806339077537146102ec57806354c8a4f31461030e57600080fd5b806301ffc9a7146101d45780630a2fd493146101fc578063181f5a771461021c575b600080fd5b6101e76101e23660046131a9565b61056e565b60405190151581526020015b60405180910390f35b61020f61020a366004613208565b610653565b6040516101f39190613291565b61020f6040518060400160405280601f81526020017f4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e300081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e76102ad3660046132d1565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102ff6102fa3660046132ee565b610703565b604051905181526020016101f3565b61032161031c366004613376565b6108bb565b005b60085473ffffffffffffffffffffffffffffffffffffffff1661027a565b61032161034f3660046133e2565b610936565b610321610aaa565b61032161036a3660046132d1565b610ba7565b6101e761037d366004613465565b610bf6565b6101e7610390366004613208565b610cc3565b60005473ffffffffffffffffffffffffffffffffffffffff1661027a565b6103216103c13660046132d1565b610cda565b6103d96103d436600461349c565b610d69565b6040516101f391906134d7565b6103ee610ed9565b6040516101f39190613537565b61027a610409366004613208565b503090565b61042161041c366004613208565b610eea565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff1661027a565b61020f6104a9366004613208565b610fbf565b6103216104bc3660046132d1565b610fea565b6104c96110be565b6040516101f39190613591565b6104216104e4366004613208565b611176565b6103216104f7366004613748565b611248565b61032161050a36600461378d565b6112d1565b7f000000000000000000000000000000000000000000000000000000000000000061027a565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b6103216105693660046132d1565b611757565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061060157507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061064d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061067e906137cf565b80601f01602080910402602001604051908101604052809291908181526020018280546106aa906137cf565b80156106f75780601f106106cc576101008083540402835291602001916106f7565b820191906000526020600020905b8154815290600101906020018083116106da57829003601f168201915b50505050509050919050565b60408051602081019091526000815261072361071e836138be565b61176b565b60095473ffffffffffffffffffffffffffffffffffffffff166108195773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961078c60608501604086016132d1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b1580156107fc57600080fd5b505af1158015610810573d6000803e3d6000fd5b5050505061082a565b61082a610825836138be565b61199c565b61083a60608301604084016132d1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161089c91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108c3611a3a565b61093084848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611abd92505050565b50505050565b61093e611a3a565b61094783610cc3565b61098e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109b5906137cf565b80601f01602080910402602001604051908101604052809291908181526020018280546109e1906137cf565b8015610a2e5780601f10610a0357610100808354040283529160200191610a2e565b820191906000526020600020905b815481529060010190602001808311610a1157829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a5d838583613a03565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a9c93929190613b1d565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610985565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610baf611a3a565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610cbc5750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610c98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbc9190613b81565b9392505050565b600061064d600567ffffffffffffffff8416611c73565b610ce2611a3a565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d8e610d8983613b9e565b611c8b565b60095473ffffffffffffffffffffffffffffffffffffffff16610e53576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610e3657600080fd5b505af1158015610e4a573d6000803e3d6000fd5b50505050610e64565b610e64610e5f83613b9e565b611e55565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610ebe8460200160208101906104a99190613208565b81526040805160208181019092526000815291015292915050565b6060610ee56002611f6f565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261064d90611f7c565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061067e906137cf565b610ff2611a3a565b73ffffffffffffffffffffffffffffffffffffffff811661103f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d5d565b606060006110cc6005611f6f565b90506000815167ffffffffffffffff8111156110ea576110ea6135d3565b604051908082528060200260200182016040528015611113578160200160208202803683370190505b50905060005b825181101561116f5782818151811061113457611134613c40565b602002602001015182828151811061114e5761114e613c40565b67ffffffffffffffff90921660209283029190910190910152600101611119565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261064d90611f7c565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611288575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112c1576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610985565b6112cc83838361202e565b505050565b6112d9611a3a565b60005b818110156112cc5760008383838181106112f8576112f8613c40565b905060200281019061130a9190613c6f565b61131390613cad565b90506113288160800151826020015115612118565b61133b8160a00151826020015115612118565b80602001511561163757805161135d9060059067ffffffffffffffff16612251565b6113a25780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610985565b60408101515115806113b75750606081015151155b156113ee576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115cf9082613d61565b50606082015160058201906115e49082613d61565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061162a9493929190613e7b565b60405180910390a161174e565b805161164f9060059067ffffffffffffffff1661225d565b6116945780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610985565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116fd600483018261315b565b61170b60058301600061315b565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112dc565b61175f611a3a565b61176881612269565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146118005760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610985565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156118ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d29190613b81565b15611909576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611916816020015161235e565b60006119258260200151610653565b9050805160001480611949575080805190602001208260a001518051906020012014155b15611986578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109859190613291565b61199882602001518360600151612484565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611a059490939291600401613f14565b600060405180830381600087803b158015611a1f57600080fd5b505af1158015611a33573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611abb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610985565b565b7f0000000000000000000000000000000000000000000000000000000000000000611b14576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611baa576000838281518110611b3457611b34613c40565b60200260200101519050611b528160026124cb90919063ffffffff16565b15611ba15760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611b17565b5060005b81518110156112cc576000828281518110611bcb57611bcb613c40565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c0f5750611c6b565b611c1a6002826124ed565b15611c695760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611bae565b60008181526001830160205260408120541515610cbc565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611d205760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610985565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611dce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df29190613b81565b15611e29576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e36816040015161250f565b611e43816020015161258e565b611768816020015182606001516126dc565b6009546060820151611ea29173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690612720565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611f0a94939291600401613f75565b6000604051808303816000875af1158015611f29573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119989190810190613fd5565b60606000610cbc836127ad565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261200a82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611fee9190614072565b85608001516fffffffffffffffffffffffffffffffff16612808565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61203783610cc3565b612079576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610985565b612084826000612118565b67ffffffffffffffff831660009081526007602052604090206120a79083612832565b6120b2816000612118565b67ffffffffffffffff831660009081526007602052604090206120d89060020182612832565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161210b93929190614085565b60405180910390a1505050565b8151156121df5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061216e575060408201516fffffffffffffffffffffffffffffffff16155b156121a757816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109859190614108565b8015611998576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612218575060208201516fffffffffffffffffffffffffffffffff1615155b1561199857816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109859190614108565b6000610cbc83836129d4565b6000610cbc8383612a23565b3373ffffffffffffffffffffffffffffffffffffffff8216036122e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610985565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61236781610cc3565b6123a9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610985565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612428573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061244c9190613b81565b611768576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610985565b67ffffffffffffffff8216600090815260076020526040902061199890600201827f0000000000000000000000000000000000000000000000000000000000000000612b16565b6000610cbc8373ffffffffffffffffffffffffffffffffffffffff8416612a23565b6000610cbc8373ffffffffffffffffffffffffffffffffffffffff84166129d4565b7f00000000000000000000000000000000000000000000000000000000000000001561176857612540600282612e99565b611768576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610985565b61259781610cc3565b6125d9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610985565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126769190614144565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611768576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610985565b67ffffffffffffffff8216600090815260076020526040902061199890827f0000000000000000000000000000000000000000000000000000000000000000612b16565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526112cc908490612ec8565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106f757602002820191906000526020600020905b8154815260200190600101908083116127e95750505050509050919050565b6000612827856128188486614161565b6128229087614178565b612fd4565b90505b949350505050565b815460009061285b90700100000000000000000000000000000000900463ffffffff1642614072565b905080156128fd57600183015483546128a3916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612808565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612923916fffffffffffffffffffffffffffffffff9081169116612fd4565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061210b908490614108565b6000818152600183016020526040812054612a1b5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561064d565b50600061064d565b60008181526001830160205260408120548015612b0c576000612a47600183614072565b8554909150600090612a5b90600190614072565b9050808214612ac0576000866000018281548110612a7b57612a7b613c40565b9060005260206000200154905080876000018481548110612a9e57612a9e613c40565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ad157612ad161418b565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061064d565b600091505061064d565b825474010000000000000000000000000000000000000000900460ff161580612b3d575081155b15612b4757505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612b8d90700100000000000000000000000000000000900463ffffffff1642614072565b90508015612c4d5781831115612bcf576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612c099083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612808565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612d045773ffffffffffffffffffffffffffffffffffffffff8416612cac576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610985565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610985565b84831015612e175760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612d489082614072565b612d52878a614072565b612d5c9190614178565b612d6691906141ba565b905073ffffffffffffffffffffffffffffffffffffffff8616612dbf576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610985565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610985565b612e218584614072565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610cbc565b6000612f2a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612fea9092919063ffffffff16565b8051909150156112cc5780806020019051810190612f489190613b81565b6112cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610985565b6000818310612fe35781610cbc565b5090919050565b606061282a8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161301e91906141f5565b60006040518083038185875af1925050503d806000811461305b576040519150601f19603f3d011682016040523d82523d6000602084013e613060565b606091505b50915091506130718783838761307c565b979650505050505050565b6060831561311257825160000361310b5773ffffffffffffffffffffffffffffffffffffffff85163b61310b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610985565b508161282a565b61282a83838151156131275781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109859190613291565b508054613167906137cf565b6000825580601f10613177575050565b601f01602090049060005260206000209081019061176891905b808211156131a55760008155600101613191565b5090565b6000602082840312156131bb57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610cbc57600080fd5b803567ffffffffffffffff8116811461320357600080fd5b919050565b60006020828403121561321a57600080fd5b610cbc826131eb565b60005b8381101561323e578181015183820152602001613226565b50506000910152565b6000815180845261325f816020860160208601613223565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610cbc6020830184613247565b73ffffffffffffffffffffffffffffffffffffffff8116811461176857600080fd5b8035613203816132a4565b6000602082840312156132e357600080fd5b8135610cbc816132a4565b60006020828403121561330057600080fd5b813567ffffffffffffffff81111561331757600080fd5b82016101008185031215610cbc57600080fd5b60008083601f84011261333c57600080fd5b50813567ffffffffffffffff81111561335457600080fd5b6020830191508360208260051b850101111561336f57600080fd5b9250929050565b6000806000806040858703121561338c57600080fd5b843567ffffffffffffffff808211156133a457600080fd5b6133b08883890161332a565b909650945060208701359150808211156133c957600080fd5b506133d68782880161332a565b95989497509550505050565b6000806000604084860312156133f757600080fd5b613400846131eb565b9250602084013567ffffffffffffffff8082111561341d57600080fd5b818601915086601f83011261343157600080fd5b81358181111561344057600080fd5b87602082850101111561345257600080fd5b6020830194508093505050509250925092565b6000806040838503121561347857600080fd5b613481836131eb565b91506020830135613491816132a4565b809150509250929050565b6000602082840312156134ae57600080fd5b813567ffffffffffffffff8111156134c557600080fd5b820160a08185031215610cbc57600080fd5b6020815260008251604060208401526134f36060840182613247565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261352e8282613247565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613553565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358557835167ffffffffffffffff16835292840192918401916001016135ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613626576136266135d3565b60405290565b60405160c0810167ffffffffffffffff81118282101715613626576136266135d3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613696576136966135d3565b604052919050565b801515811461176857600080fd5b80356132038161369e565b80356fffffffffffffffffffffffffffffffff8116811461320357600080fd5b6000606082840312156136e957600080fd5b6040516060810181811067ffffffffffffffff8211171561370c5761370c6135d3565b604052905080823561371d8161369e565b815261372b602084016136b7565b602082015261373c604084016136b7565b60408201525092915050565b600080600060e0848603121561375d57600080fd5b613766846131eb565b925061377585602086016136d7565b915061378485608086016136d7565b90509250925092565b600080602083850312156137a057600080fd5b823567ffffffffffffffff8111156137b757600080fd5b6137c38582860161332a565b90969095509350505050565b600181811c908216806137e357607f821691505b60208210810361381c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff82111561383c5761383c6135d3565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261387957600080fd5b813561388c61388782613822565b61364f565b8181528460208386010111156138a157600080fd5b816020850160208301376000918101602001919091529392505050565b600061010082360312156138d157600080fd5b6138d9613602565b823567ffffffffffffffff808211156138f157600080fd5b6138fd36838701613868565b835261390b602086016131eb565b602084015261391c604086016132c6565b604084015260608501356060840152613937608086016132c6565b608084015260a085013591508082111561395057600080fd5b61395c36838701613868565b60a084015260c085013591508082111561397557600080fd5b61398136838701613868565b60c084015260e085013591508082111561399a57600080fd5b506139a736828601613868565b60e08301525092915050565b601f8211156112cc576000816000526020600020601f850160051c810160208610156139dc5750805b601f850160051c820191505b818110156139fb578281556001016139e8565b505050505050565b67ffffffffffffffff831115613a1b57613a1b6135d3565b613a2f83613a2983546137cf565b836139b3565b6000601f841160018114613a815760008515613a4b5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a33565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613ad05786850135825560209485019460019092019101613ab0565b5086821015613b0b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613b306040830186613247565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613b9357600080fd5b8151610cbc8161369e565b600060a08236031215613bb057600080fd5b60405160a0810167ffffffffffffffff8282108183111715613bd457613bd46135d3565b816040528435915080821115613be957600080fd5b50613bf636828601613868565b825250613c05602084016131eb565b60208201526040830135613c18816132a4565b6040820152606083810135908201526080830135613c35816132a4565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ca357600080fd5b9190910192915050565b60006101408236031215613cc057600080fd5b613cc861362c565b613cd1836131eb565b8152613cdf602084016136ac565b6020820152604083013567ffffffffffffffff80821115613cff57600080fd5b613d0b36838701613868565b60408401526060850135915080821115613d2457600080fd5b50613d3136828601613868565b606083015250613d4436608085016136d7565b6080820152613d563660e085016136d7565b60a082015292915050565b815167ffffffffffffffff811115613d7b57613d7b6135d3565b613d8f81613d8984546137cf565b846139b3565b602080601f831160018114613de25760008415613dac5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139fb565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e2f57888601518255948401946001909101908401613e10565b5085821015613e6b57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613e9f81840187613247565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613edd9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e083015261352e565b60a081526000613f2760a0830187613247565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613fa460a0830186613247565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613fe757600080fd5b815167ffffffffffffffff811115613ffe57600080fd5b8201601f8101841361400f57600080fd5b805161401d61388782613822565b81815285602083850101111561403257600080fd5b61352e826020830160208601613223565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561064d5761064d614043565b67ffffffffffffffff8416815260e081016140d160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261282a565b6060810161064d82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561415657600080fd5b8151610cbc816132a4565b808202811582820484141761064d5761064d614043565b8082018082111561064d5761064d614043565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826141f0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613ca381846020870161322356fea164736f6c6343000818000a", } var BurnMintTokenPoolAndProxyABI = BurnMintTokenPoolAndProxyMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go index e9edaad443..9ba0cacd45 100644 --- a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var BurnWithFromMintTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b506040516200450b3803806200450b8339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508181146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161399262000b79600039600081816104dd01528181611777015261215b0152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b45015281816120f1015261234601526139926000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae9565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b48565b6105f9565b6040516101d29190612bc7565b6101ee6040518060400160405280601f81526020017f4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e300081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c07565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c24565b6106a9565b604051905181526020016101d2565b6103006102fb366004612cac565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d18565b6108aa565b610300610a1e565b610300610349366004612c07565b610b1b565b6101c661035c366004612b48565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d9b565b610b81565b6040516101d29190612dd6565b6103a7610c28565b6040516101d29190612e36565b6103c76103c2366004612b48565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b48565b610d0e565b610300610462366004612c07565b610d39565b61046f610e14565b6040516101d29190612e90565b6103c761048a366004612b48565b610ecc565b61030061049d366004612ff8565b610f9e565b6103006104b036600461303d565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c07565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061307f565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361317d565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c07565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c07565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109299061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546109559061307f565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132c2565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133dc565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba183613440565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b48565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb9565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc6565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061307f565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb9565b90506000815167ffffffffffffffff811115610e4057610e40612ed2565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134e2565b6020026020010151828281518110610ea457610ea46134e2565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc6565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c78565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134e2565b90506020028101906110609190613511565b6110699061354f565b905061107e8160800151826020015115611d62565b6110918160a00151826020015115611d62565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e9b565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906113259082613603565b506060820151600582019061133a9082613603565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c29550611380949392919061371d565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea7565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a9b565b611461600583016000612a9b565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611eb3565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b6565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa8565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc7565b6116ee826020015183606001516120ce565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134e2565b6020026020010151905061180a81600261211590919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134e2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612137565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b6565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612159565b611afe81602001516121d8565b6114be81602001518260600151612326565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b158015611b9e57600080fd5b505af1158015611bb2573d6000803e3d6000fd5b5050505050565b6060600061193f8361236a565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c5482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c389190613802565b85608001516fffffffffffffffffffffffffffffffff166123c5565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c8183610b6a565b611cc3576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cce826000611d62565b67ffffffffffffffff83166000908152600760205260409020611cf190836123ef565b611cfc816000611d62565b67ffffffffffffffff83166000908152600760205260409020611d2290600201826123ef565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d5593929190613815565b60405180910390a1505050565b815115611e295781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db8575060408201516fffffffffffffffffffffffffffffffff16155b15611df157816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e62575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b600061193f8383612591565b600061193f83836125e0565b3373ffffffffffffffffffffffffffffffffffffffff821603611f32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fb181610b6a565b611ff3576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612072573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209691906137b6565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126d3565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125e0565b600061193f8373ffffffffffffffffffffffffffffffffffffffff8416612591565b7f0000000000000000000000000000000000000000000000000000000000000000156114be5761218a600282612a56565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121e181610b6a565b612223576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c091906138d4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126d3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a65750505050509050919050565b60006123e4856123d584866138f1565b6123df9087613908565b612a85565b90505b949350505050565b815460009061241890700100000000000000000000000000000000900463ffffffff1642613802565b905080156124ba5760018301548354612460916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123c5565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124e0916fffffffffffffffffffffffffffffffff9081169116612a85565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d55908490613898565b60008181526001830160205260408120546125d8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c9576000612604600183613802565b855490915060009061261890600190613802565b905081811461267d576000866000018281548110612638576126386134e2565b906000526020600020015490508087600001848154811061265b5761265b6134e2565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268e5761268e61391b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126fa575081155b1561270457505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274a90700100000000000000000000000000000000900463ffffffff1642613802565b9050801561280a578183111561278c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c69083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123c5565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128c15773ffffffffffffffffffffffffffffffffffffffff8416612869576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129d45760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906129059082613802565b61290f878a613802565b6129199190613908565b612923919061394a565b905073ffffffffffffffffffffffffffffffffffffffff861661297c576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129de8584613802565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a94578161193f565b5090919050565b508054612aa79061307f565b6000825580601f10612ab7575050565b601f0160209004906000526020600020908101906114be91905b80821115612ae55760008155600101612ad1565b5090565b600060208284031215612afb57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b4357600080fd5b919050565b600060208284031215612b5a57600080fd5b61193f82612b2b565b6000815180845260005b81811015612b8957602081850181015186830182015201612b6d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b63565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b4381612bda565b600060208284031215612c1957600080fd5b813561193f81612bda565b600060208284031215612c3657600080fd5b813567ffffffffffffffff811115612c4d57600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c7257600080fd5b50813567ffffffffffffffff811115612c8a57600080fd5b6020830191508360208260051b8501011115612ca557600080fd5b9250929050565b60008060008060408587031215612cc257600080fd5b843567ffffffffffffffff80821115612cda57600080fd5b612ce688838901612c60565b90965094506020870135915080821115612cff57600080fd5b50612d0c87828801612c60565b95989497509550505050565b600080600060408486031215612d2d57600080fd5b612d3684612b2b565b9250602084013567ffffffffffffffff80821115612d5357600080fd5b818601915086601f830112612d6757600080fd5b813581811115612d7657600080fd5b876020828501011115612d8857600080fd5b6020830194508093505050509250925092565b600060208284031215612dad57600080fd5b813567ffffffffffffffff811115612dc457600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612df26060840182612b63565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e2d8282612b63565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e52565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835167ffffffffffffffff1683529284019291840191600101612eac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f2557612f25612ed2565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f2557612f25612ed2565b80151581146114be57600080fd5b8035612b4381612f4e565b80356fffffffffffffffffffffffffffffffff81168114612b4357600080fd5b600060608284031215612f9957600080fd5b6040516060810181811067ffffffffffffffff82111715612fbc57612fbc612ed2565b6040529050808235612fcd81612f4e565b8152612fdb60208401612f67565b6020820152612fec60408401612f67565b60408201525092915050565b600080600060e0848603121561300d57600080fd5b61301684612b2b565b92506130258560208601612f87565b91506130348560808601612f87565b90509250925092565b6000806020838503121561305057600080fd5b823567ffffffffffffffff81111561306757600080fd5b61307385828601612c60565b90969095509350505050565b600181811c9082168061309357607f821691505b6020821081036130cc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130e357600080fd5b813567ffffffffffffffff808211156130fe576130fe612ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561314457613144612ed2565b8160405283815286602085880101111561315d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561319057600080fd5b613198612f01565b823567ffffffffffffffff808211156131b057600080fd5b6131bc368387016130d2565b83526131ca60208601612b2b565b60208401526131db60408601612bfc565b6040840152606085013560608401526131f660808601612bfc565b608084015260a085013591508082111561320f57600080fd5b61321b368387016130d2565b60a084015260c085013591508082111561323457600080fd5b613240368387016130d2565b60c084015260e085013591508082111561325957600080fd5b50613266368286016130d2565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c8101602086101561329b5750805b601f850160051c820191505b818110156132ba578281556001016132a7565b505050505050565b67ffffffffffffffff8311156132da576132da612ed2565b6132ee836132e8835461307f565b83613272565b6000601f841160018114613340576000851561330a5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bb2565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561338f578685013582556020948501946001909201910161336f565b50868210156133ca577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133ef6040830186612b63565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561345257600080fd5b60405160a0810167ffffffffffffffff828210818311171561347657613476612ed2565b81604052843591508082111561348b57600080fd5b50613498368286016130d2565b8252506134a760208401612b2b565b602082015260408301356134ba81612bda565b60408201526060838101359082015260808301356134d781612bda565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261354557600080fd5b9190910192915050565b6000610140823603121561356257600080fd5b61356a612f2b565b61357383612b2b565b815261358160208401612f5c565b6020820152604083013567ffffffffffffffff808211156135a157600080fd5b6135ad368387016130d2565b604084015260608501359150808211156135c657600080fd5b506135d3368286016130d2565b6060830152506135e63660808501612f87565b60808201526135f83660e08501612f87565b60a082015292915050565b815167ffffffffffffffff81111561361d5761361d612ed2565b6136318161362b845461307f565b84613272565b602080601f831160018114613684576000841561364e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132ba565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136d1578886015182559484019460019091019084016136b2565b508582101561370d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261374181840187612b63565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061377f9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e2d565b6000602082840312156137c857600080fd5b815161193f81612f4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137d3565b67ffffffffffffffff8416815260e0810161386160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e7565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e657600080fd5b815161193f81612bda565b80820281158282048414176105f3576105f36137d3565b808201808211156105f3576105f36137d3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613980577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b506040516200450b3803806200450b8339810160408190526200003491620008c0565b8383838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200018f565b5050506001600160a01b0384161580620000e357506001600160a01b038116155b80620000f657506001600160a01b038216155b1562000115576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c05262000168576040805160008152602081019091526200016890846200023a565b5062000185925050506001600160a01b0385163060001962000397565b5050505062000afc565b336001600160a01b03821603620001e95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200025b576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002e65760008382815181106200027f576200027f620009d0565b60209081029190910101519050620002996002826200047d565b15620002dc576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200025e565b5060005b8151811015620003925760008282815181106200030b576200030b620009d0565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000337575062000389565b620003446002826200049d565b1562000387576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002ea565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200040f9190620009e6565b6200041b919062000a16565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200047791869190620004b416565b50505050565b600062000494836001600160a01b03841662000585565b90505b92915050565b600062000494836001600160a01b03841662000689565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000503906001600160a01b038516908490620006db565b80519091501562000392578080602001905181019062000524919062000a2c565b620003925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000086565b600081815260018301602052604081205480156200067e576000620005ac60018362000a57565b8554909150600090620005c29060019062000a57565b90508082146200062e576000866000018281548110620005e657620005e6620009d0565b90600052602060002001549050808760000184815481106200060c576200060c620009d0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000642576200064262000a6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000497565b600091505062000497565b6000818152600183016020526040812054620006d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000497565b50600062000497565b6060620006ec8484600085620006f4565b949350505050565b606082471015620007575760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000086565b600080866001600160a01b0316858760405162000775919062000aa9565b60006040518083038185875af1925050503d8060008114620007b4576040519150601f19603f3d011682016040523d82523d6000602084013e620007b9565b606091505b509092509050620007cd87838387620007d8565b979650505050505050565b606083156200084c57825160000362000844576001600160a01b0385163b620008445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000086565b5081620006ec565b620006ec8383815115620008635781518083602001fd5b8060405162461bcd60e51b815260040162000086919062000ac7565b6001600160a01b03811681146200089557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008bb816200087f565b919050565b60008060008060808587031215620008d757600080fd5b8451620008e4816200087f565b602086810151919550906001600160401b03808211156200090457600080fd5b818801915088601f8301126200091957600080fd5b8151818111156200092e576200092e62000898565b8060051b604051601f19603f8301168101818110858211171562000956576200095662000898565b60405291825284820192508381018501918b8311156200097557600080fd5b938501935b828510156200099e576200098e85620008ae565b845293850193928501926200097a565b809850505050505050620009b560408601620008ae565b9150620009c560608601620008ae565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009f957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000497576200049762000a00565b60006020828403121562000a3f57600080fd5b8151801515811462000a5057600080fd5b9392505050565b8181038181111562000497576200049762000a00565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aa057818101518382015260200162000a86565b50506000910152565b6000825162000abd81846020870162000a83565b9190910192915050565b602081526000825180602084015262000ae881604085016020870162000a83565b601f01601f19169190910160400192915050565b60805160a05160c05161399262000b79600039600081816104dd01528181611777015261215b0152600081816104b7015281816115a80152611a2d0152600081816102390152818161028e015281816106e0015281816114c80152818161194d01528181611b45015281816120f1015261234601526139926000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612ae9565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612b48565b6105f9565b6040516101d29190612bc7565b6101ee6040518060400160405280601f81526020017f4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e300081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612c07565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612c24565b6106a9565b604051905181526020016101d2565b6103006102fb366004612cac565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612d18565b6108aa565b610300610a1e565b610300610349366004612c07565b610b1b565b6101c661035c366004612b48565b610b6a565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d9b565b610b81565b6040516101d29190612dd6565b6103a7610c28565b6040516101d29190612e36565b6103c76103c2366004612b48565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612b48565b610d0e565b610300610462366004612c07565b610d39565b61046f610e14565b6040516101d29190612e90565b6103c761048a366004612b48565b610ecc565b61030061049d366004612ff8565b610f9e565b6103006104b036600461303d565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612c07565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061307f565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361317d565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612c07565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612c07565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f2565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061177592505050565b50505050565b6108b26116f2565b6108bb83610b6a565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109299061307f565b80601f01602080910402602001604051908101604052809291908181526020018280546109559061307f565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d18385836132c2565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a10939291906133dc565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b236116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105f3600567ffffffffffffffff841661192b565b6040805180820190915260608082526020820152610ba6610ba183613440565b611946565b610bb38260600135611b10565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044f9190612b48565b81526040805160208181019092526000815291015292915050565b6060610c346002611bb9565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611bc6565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061307f565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611bb9565b90506000815167ffffffffffffffff811115610e4057610e40612ed2565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a6134e2565b6020026020010151828281518110610ea457610ea46134e2565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611bc6565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611022838383611c78565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e6134e2565b90506020028101906110609190613511565b6110699061354f565b905061107e8160800151826020015115611d62565b6110918160a00151826020015115611d62565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e9b565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906113259082613603565b506060820151600582019061133a9082613603565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c29550611380949392919061371d565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611ea7565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a9b565b611461600583016000612a9b565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611eb3565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162891906137b6565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611fa8565b600061167b82602001516105f9565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612bc7565b6116ee826020015183606001516120ce565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f9565b565b7f00000000000000000000000000000000000000000000000000000000000000006117cc576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118625760008382815181106117ec576117ec6134e2565b6020026020010151905061180a81600261211590919063ffffffff16565b156118595760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117cf565b5060005b8151811015611022576000828281518110611883576118836134e2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c75750611923565b6118d2600282612137565b156119215760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611866565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119db5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aad91906137b6565b15611ae4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af18160400151612159565b611afe81602001516121d8565b6114be81602001518260600151612326565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b158015611b9e57600080fd5b505af1158015611bb2573d6000803e3d6000fd5b5050505050565b6060600061193f8361236a565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c5482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c389190613802565b85608001516fffffffffffffffffffffffffffffffff166123c5565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c8183610b6a565b611cc3576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611cce826000611d62565b67ffffffffffffffff83166000908152600760205260409020611cf190836123ef565b611cfc816000611d62565b67ffffffffffffffff83166000908152600760205260409020611d2290600201826123ef565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d5593929190613815565b60405180910390a1505050565b815115611e295781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611db8575060408201516fffffffffffffffffffffffffffffffff16155b15611df157816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e62575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613898565b600061193f8383612591565b600061193f83836125e0565b3373ffffffffffffffffffffffffffffffffffffffff821603611f32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fb181610b6a565b611ff3576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612072573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209691906137b6565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f00000000000000000000000000000000000000000000000000000000000000006126d3565b600061193f8373ffffffffffffffffffffffffffffffffffffffff84166125e0565b600061193f8373ffffffffffffffffffffffffffffffffffffffff8416612591565b7f0000000000000000000000000000000000000000000000000000000000000000156114be5761218a600282612a56565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b6121e181610b6a565b612223576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c091906138d4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116ee90827f00000000000000000000000000000000000000000000000000000000000000006126d3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123a65750505050509050919050565b60006123e4856123d584866138f1565b6123df9087613908565b612a85565b90505b949350505050565b815460009061241890700100000000000000000000000000000000900463ffffffff1642613802565b905080156124ba5760018301548354612460916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166123c5565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546124e0916fffffffffffffffffffffffffffffffff9081169116612a85565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d55908490613898565b60008181526001830160205260408120546125d8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126c9576000612604600183613802565b855490915060009061261890600190613802565b905080821461267d576000866000018281548110612638576126386134e2565b906000526020600020015490508087600001848154811061265b5761265b6134e2565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061268e5761268e61391b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff1615806126fa575081155b1561270457505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061274a90700100000000000000000000000000000000900463ffffffff1642613802565b9050801561280a578183111561278c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127c69083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166123c5565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128c15773ffffffffffffffffffffffffffffffffffffffff8416612869576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129d45760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906129059082613802565b61290f878a613802565b6129199190613908565b612923919061394a565b905073ffffffffffffffffffffffffffffffffffffffff861661297c576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b6129de8584613802565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561193f565b6000818310612a94578161193f565b5090919050565b508054612aa79061307f565b6000825580601f10612ab7575050565b601f0160209004906000526020600020908101906114be91905b80821115612ae55760008155600101612ad1565b5090565b600060208284031215612afb57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461193f57600080fd5b803567ffffffffffffffff81168114612b4357600080fd5b919050565b600060208284031215612b5a57600080fd5b61193f82612b2b565b6000815180845260005b81811015612b8957602081850181015186830182015201612b6d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061193f6020830184612b63565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612b4381612bda565b600060208284031215612c1957600080fd5b813561193f81612bda565b600060208284031215612c3657600080fd5b813567ffffffffffffffff811115612c4d57600080fd5b8201610100818503121561193f57600080fd5b60008083601f840112612c7257600080fd5b50813567ffffffffffffffff811115612c8a57600080fd5b6020830191508360208260051b8501011115612ca557600080fd5b9250929050565b60008060008060408587031215612cc257600080fd5b843567ffffffffffffffff80821115612cda57600080fd5b612ce688838901612c60565b90965094506020870135915080821115612cff57600080fd5b50612d0c87828801612c60565b95989497509550505050565b600080600060408486031215612d2d57600080fd5b612d3684612b2b565b9250602084013567ffffffffffffffff80821115612d5357600080fd5b818601915086601f830112612d6757600080fd5b813581811115612d7657600080fd5b876020828501011115612d8857600080fd5b6020830194508093505050509250925092565b600060208284031215612dad57600080fd5b813567ffffffffffffffff811115612dc457600080fd5b820160a0818503121561193f57600080fd5b602081526000825160406020840152612df26060840182612b63565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e2d8282612b63565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612e52565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e8457835167ffffffffffffffff1683529284019291840191600101612eac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612f2557612f25612ed2565b60405290565b60405160c0810167ffffffffffffffff81118282101715612f2557612f25612ed2565b80151581146114be57600080fd5b8035612b4381612f4e565b80356fffffffffffffffffffffffffffffffff81168114612b4357600080fd5b600060608284031215612f9957600080fd5b6040516060810181811067ffffffffffffffff82111715612fbc57612fbc612ed2565b6040529050808235612fcd81612f4e565b8152612fdb60208401612f67565b6020820152612fec60408401612f67565b60408201525092915050565b600080600060e0848603121561300d57600080fd5b61301684612b2b565b92506130258560208601612f87565b91506130348560808601612f87565b90509250925092565b6000806020838503121561305057600080fd5b823567ffffffffffffffff81111561306757600080fd5b61307385828601612c60565b90969095509350505050565b600181811c9082168061309357607f821691505b6020821081036130cc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126130e357600080fd5b813567ffffffffffffffff808211156130fe576130fe612ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561314457613144612ed2565b8160405283815286602085880101111561315d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561319057600080fd5b613198612f01565b823567ffffffffffffffff808211156131b057600080fd5b6131bc368387016130d2565b83526131ca60208601612b2b565b60208401526131db60408601612bfc565b6040840152606085013560608401526131f660808601612bfc565b608084015260a085013591508082111561320f57600080fd5b61321b368387016130d2565b60a084015260c085013591508082111561323457600080fd5b613240368387016130d2565b60c084015260e085013591508082111561325957600080fd5b50613266368286016130d2565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c8101602086101561329b5750805b601f850160051c820191505b818110156132ba578281556001016132a7565b505050505050565b67ffffffffffffffff8311156132da576132da612ed2565b6132ee836132e8835461307f565b83613272565b6000601f841160018114613340576000851561330a5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611bb2565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561338f578685013582556020948501946001909201910161336f565b50868210156133ca577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133ef6040830186612b63565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a0823603121561345257600080fd5b60405160a0810167ffffffffffffffff828210818311171561347657613476612ed2565b81604052843591508082111561348b57600080fd5b50613498368286016130d2565b8252506134a760208401612b2b565b602082015260408301356134ba81612bda565b60408201526060838101359082015260808301356134d781612bda565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261354557600080fd5b9190910192915050565b6000610140823603121561356257600080fd5b61356a612f2b565b61357383612b2b565b815261358160208401612f5c565b6020820152604083013567ffffffffffffffff808211156135a157600080fd5b6135ad368387016130d2565b604084015260608501359150808211156135c657600080fd5b506135d3368286016130d2565b6060830152506135e63660808501612f87565b60808201526135f83660e08501612f87565b60a082015292915050565b815167ffffffffffffffff81111561361d5761361d612ed2565b6136318161362b845461307f565b84613272565b602080601f831160018114613684576000841561364e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556132ba565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156136d1578886015182559484019460019091019084016136b2565b508582101561370d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261374181840187612b63565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061377f9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e2d565b6000602082840312156137c857600080fd5b815161193f81612f4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f36137d3565b67ffffffffffffffff8416815260e0810161386160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526123e7565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156138e657600080fd5b815161193f81612bda565b80820281158282048414176105f3576105f36137d3565b808201808211156105f3576105f36137d3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613980577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var BurnWithFromMintTokenPoolABI = BurnWithFromMintTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go b/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go index d367872b05..9e03f87fb0 100644 --- a/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go +++ b/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go @@ -62,7 +62,7 @@ type CCIPConfigTypesOCR3ConfigWithMeta struct { var CCIPConfigMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidConfigLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"currentState\",\"type\":\"uint8\"},{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"proposedState\",\"type\":\"uint8\"}],\"name\":\"InvalidConfigStateTransition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeNotInRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonExistentConfigTransition\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"set\",\"type\":\"bytes32[]\"}],\"name\":\"NotASortedSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"subset\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"superset\",\"type\":\"bytes32[]\"}],\"name\":\"NotASubset\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"NotEnoughTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfframpAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p2pIdsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"signersLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transmittersLength\",\"type\":\"uint256\"}],\"name\":\"P2PIdsLengthNotMatching\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyBootstrapP2PIds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOCR3Configs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyTransmitters\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"}],\"name\":\"WrongConfigCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigestBlueGreen\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapabilityConfigurationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"chainSelectorRemoves\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllChainConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilityRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getOCRConfig\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"bootstrapP2PIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"internalType\":\"structCCIPConfigTypes.OCR3ConfigWithMeta[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620043d7380380620043d78339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e9576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b6080516141d6620002016000396000818160f801528181610e96015261112b01526141d66000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638318ed5d11610081578063f2fde38b1161005b578063f2fde38b14610204578063f442c89a14610217578063fba64a7c1461022a57600080fd5b80638318ed5d146101b05780638da5cb5b146101d1578063ddc042a8146101ef57600080fd5b8063181f5a77116100b2578063181f5a771461013d5780634bd0473f1461018657806379ba5097146101a657600080fd5b806301ffc9a7146100ce578063020330e6146100f6575b600080fd5b6100e16100dc366004612fbf565b61023d565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b6101796040518060400160405280601481526020017f43434950436f6e66696720312e362e302d64657600000000000000000000000081525081565b6040516100ed9190613065565b6101996101943660046130a9565b6102d6565b6040516100ed91906131d5565b6101ae6107a6565b005b6101796101be3660046133b2565b5060408051602081019091526000815290565b60005473ffffffffffffffffffffffffffffffffffffffff16610118565b6101f76108a8565b6040516100ed9190613413565b6101ae6102123660046134a3565b610a9a565b6101ae610225366004613525565b610aae565b6101ae6102383660046135a9565b610e7e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea7210000000000000000000000000000000000000000000000000000000014806102d057507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b63ffffffff82166000908152600560205260408120606091836001811115610300576103006130de565b6001811115610311576103116130de565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561079a57600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff166001811115610384576103846130de565b6001811115610395576103956130de565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916103ed90613666565b80601f016020809104026020016040519081016040528092919081815260200182805461041990613666565b80156104665780601f1061043b57610100808354040283529160200191610466565b820191906000526020600020905b81548152906001019060200180831161044957829003601f168201915b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156104be57602002820191906000526020600020905b8154815260200190600101908083116104aa575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561051657602002820191906000526020600020905b815481526020019060010190808311610502575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156105f057838290600052602060002001805461056390613666565b80601f016020809104026020016040519081016040528092919081815260200182805461058f90613666565b80156105dc5780601f106105b1576101008083540402835291602001916105dc565b820191906000526020600020905b8154815290600101906020018083116105bf57829003601f168201915b505050505081526020019060010190610544565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156106c957838290600052602060002001805461063c90613666565b80601f016020809104026020016040519081016040528092919081815260200182805461066890613666565b80156106b55780601f1061068a576101008083540402835291602001916106b5565b820191906000526020600020905b81548152906001019060200180831161069857829003601f168201915b50505050508152602001906001019061061d565b5050505081526020016006820180546106e190613666565b80601f016020809104026020016040519081016040528092919081815260200182805461070d90613666565b801561075a5780601f1061072f5761010080835404028352916020019161075a565b820191906000526020600020905b81548152906001019060200180831161073d57829003601f168201915b505050919092525050508152600782015467ffffffffffffffff16602080830191909152600890920154604090910152908252600192909201910161033f565b50505050905092915050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461082c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b606060006108b66003610f3f565b905060006108c46003610f53565b67ffffffffffffffff8111156108dc576108dc6136b9565b60405190808252806020026020018201604052801561091557816020015b610902612d50565b8152602001906001900390816108fa5790505b50905060005b8251811015610a93576000838281518110610938576109386136e8565b60209081029190910181015160408051808201825267ffffffffffffffff8316808252600090815260028552829020825181546080818802830181019095526060820181815295975092958601949093919284928491908401828280156109be57602002820191906000526020600020905b8154815260200190600101908083116109aa575b5050509183525050600182015460ff1660208201526002820180546040909201916109e890613666565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1490613666565b8015610a615780601f10610a3657610100808354040283529160200191610a61565b820191906000526020600020905b815481529060010190602001808311610a4457829003601f168201915b505050505081525050815250838381518110610a7f57610a7f6136e8565b60209081029190910101525060010161091b565b5092915050565b610aa2610f5d565b610aab81610fe0565b50565b610ab6610f5d565b60005b83811015610c9c57610afd858583818110610ad657610ad66136e8565b9050602002016020810190610aeb9190613717565b60039067ffffffffffffffff166110d5565b610b6757848482818110610b1357610b136136e8565b9050602002016020810190610b289190613717565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610823565b60026000868684818110610b7d57610b7d6136e8565b9050602002016020810190610b929190613717565b67ffffffffffffffff1681526020810191909152604001600090812090610bb98282612d98565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610bf1600283016000612db6565b5050610c2f858583818110610c0857610c086136e8565b9050602002016020810190610c1d9190613717565b60039067ffffffffffffffff166110ed565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110610c6357610c636136e8565b9050602002016020810190610c789190613717565b60405167ffffffffffffffff909116815260200160405180910390a1600101610ab9565b5060005b81811015610e77576000838383818110610cbc57610cbc6136e8565b9050602002810190610cce9190613732565b610cdc906020810190613770565b610ce590613972565b80519091506000858585818110610cfe57610cfe6136e8565b9050602002810190610d109190613732565b610d1e906020810190613717565b905060005b8251811015610d5657610d4e838281518110610d4157610d416136e8565b60200260200101516110f9565b600101610d23565b50826020015160ff16600003610d98576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120845180518693610dc8928492910190612df0565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560408201516002820190610e159082613a59565b50610e2f91506003905067ffffffffffffffff8316611212565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e08184604051610e61929190613b73565b60405180910390a1505050806001019050610ca0565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610eed576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610efb84860186613c1e565b9050600080610f098361121e565b8151919350915015610f2157610f2184600084611477565b805115610f3457610f3484600183611477565b505050505050505050565b60606000610f4c83611c58565b9392505050565b60006102d0825490565b60005473ffffffffffffffffffffffffffffffffffffffff163314610fde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610823565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361105f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610823565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515610f4c565b6000610f4c8383611cb4565b6040517f50c946fe000000000000000000000000000000000000000000000000000000008152600481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906350c946fe90602401600060405180830381865afa158015611187573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111cd9190810190613e8f565b608081015190915061120e576040517f8907a4fa00000000000000000000000000000000000000000000000000000000815260048101839052602401610823565b5050565b6000610f4c8383611da7565b606080600460ff1683511115611260576040517f8854586400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160028082526060820190925290816020015b6112e46040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161127657505060408051600280825260608201909252919350602082015b61137c6040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161130e57905050905060008060005b855181101561146a5760008682815181106113b4576113b46136e8565b60200260200101516000015160018111156113d1576113d16130de565b0361141e578581815181106113e8576113e86136e8565b6020026020010151858481518110611402576114026136e8565b60200260200101819052508261141790613f96565b9250611462565b858181518110611430576114306136e8565b602002602001015184838151811061144a5761144a6136e8565b60200260200101819052508161145f90613f96565b91505b600101611397565b5090835281529092909150565b63ffffffff831660009081526005602052604081208184600181111561149f5761149f6130de565b60018111156114b0576114b06130de565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561193957600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff166001811115611523576115236130de565b6001811115611534576115346130de565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a010000000000000000000090910416606082015260018201805460809092019161158c90613666565b80601f01602080910402602001604051908101604052809291908181526020018280546115b890613666565b80156116055780601f106115da57610100808354040283529160200191611605565b820191906000526020600020905b8154815290600101906020018083116115e857829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561165d57602002820191906000526020600020905b815481526020019060010190808311611649575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156116b557602002820191906000526020600020905b8154815260200190600101908083116116a1575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b8282101561178f57838290600052602060002001805461170290613666565b80601f016020809104026020016040519081016040528092919081815260200182805461172e90613666565b801561177b5780601f106117505761010080835404028352916020019161177b565b820191906000526020600020905b81548152906001019060200180831161175e57829003601f168201915b5050505050815260200190600101906116e3565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156118685783829060005260206000200180546117db90613666565b80601f016020809104026020016040519081016040528092919081815260200182805461180790613666565b80156118545780601f1061182957610100808354040283529160200191611854565b820191906000526020600020905b81548152906001019060200180831161183757829003601f168201915b5050505050815260200190600101906117bc565b50505050815260200160068201805461188090613666565b80601f01602080910402602001604051908101604052809291908181526020018280546118ac90613666565b80156118f95780601f106118ce576101008083540402835291602001916118f9565b820191906000526020600020905b8154815290600101906020018083116118dc57829003601f168201915b505050919092525050508152600782015467ffffffffffffffff1660208083019190915260089092015460409091015290825260019290920191016114de565b505050509050600061194b8251611df6565b905060006119598451611df6565b90506119658282611e48565b60006119748785878686611f04565b905061198084826122f0565b63ffffffff87166000908152600560205260408120908760018111156119a8576119a86130de565b60018111156119b9576119b96130de565b815260200190815260200160002060006119d39190612e3b565b60005b8151811015611c4e5763ffffffff8816600090815260056020526040812090886001811115611a0757611a076130de565b6001811115611a1857611a186130de565b8152602001908152602001600020828281518110611a3857611a386136e8565b6020908102919091018101518254600181810185556000948552929093208151805160099095029091018054929490939192849283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908381811115611aa257611aa26130de565b021790555060208201518154604084015160608501517fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90921661010067ffffffffffffffff948516027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1617690100000000000000000060ff90921691909102177fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a0100000000000000000000929091169190910217815560808201516001820190611b719082613a59565b5060a08201518051611b8d916002840191602090910190612df0565b5060c08201518051611ba9916003840191602090910190612df0565b5060e08201518051611bc5916004840191602090910190612e5c565b506101008201518051611be2916005840191602090910190612e5c565b506101208201516006820190611bf89082613a59565b50505060208201516007820180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9092169190911790556040909101516008909101556001016119d6565b5050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611ca857602002820191906000526020600020905b815481526020019060010190808311611c94575b50505050509050919050565b60008181526001830160205260408120548015611d9d576000611cd8600183613fce565b8554909150600090611cec90600190613fce565b9050818114611d51576000866000018281548110611d0c57611d0c6136e8565b9060005260206000200154905080876000018481548110611d2f57611d2f6136e8565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611d6257611d62613fe1565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506102d0565b60009150506102d0565b6000818152600183016020526040812054611dee575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556102d0565b5060006102d0565b60006002821115611e36576040517f3e47852600000000000000000000000000000000000000000000000000000000815260048101839052602401610823565b8160028111156102d0576102d06130de565b6000826002811115611e5c57611e5c6130de565b826002811115611e6e57611e6e6130de565b611e789190614010565b90508060011480611ec45750807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff148015611ec457506002836002811115611ec257611ec26130de565b145b15611ece57505050565b82826040517f0a6b675b000000000000000000000000000000000000000000000000000000008152600401610823929190614040565b60606000845167ffffffffffffffff811115611f2257611f226136b9565b604051908082528060200260200182016040528015611f4b578160200160208202803683370190505b5090506000846002811115611f6257611f626130de565b148015611f8057506001836002811115611f7e57611f7e6130de565b145b15611fc157600181600081518110611f9a57611f9a6136e8565b602002602001019067ffffffffffffffff16908167ffffffffffffffff1681525050612129565b6001846002811115611fd557611fd56130de565b148015611ff357506002836002811115611ff157611ff16130de565b145b1561208a578560008151811061200b5761200b6136e8565b6020026020010151602001518160008151811061202a5761202a6136e8565b602002602001019067ffffffffffffffff16908167ffffffffffffffff16815250508560008151811061205f5761205f6136e8565b6020026020010151602001516001612077919061405b565b81600181518110611f9a57611f9a6136e8565b600284600281111561209e5761209e6130de565b1480156120bc575060018360028111156120ba576120ba6130de565b145b156120f357856001815181106120d4576120d46136e8565b60200260200101516020015181600081518110611f9a57611f9a6136e8565b83836040517f0a6b675b000000000000000000000000000000000000000000000000000000008152600401610823929190614040565b6000855167ffffffffffffffff811115612145576121456136b9565b6040519080825280602002602001820160405280156121fb57816020015b604080516101a081018252600060608083018281526080840183905260a0840183905260c0840183905260e084018290526101008401829052610120840182905261014084018290526101608401829052610180840191909152825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816121635790505b50905060005b82518110156122e45761222c87828151811061221f5761221f6136e8565b602002602001015161266f565b6040518060600160405280888381518110612249576122496136e8565b60200260200101518152602001848381518110612268576122686136e8565b602002602001015167ffffffffffffffff1681526020016122bc8b868581518110612295576122956136e8565b60200260200101518b86815181106122af576122af6136e8565b6020026020010151612a75565b8152508282815181106122d1576122d16136e8565b6020908102919091010152600101612201565b50979650505050505050565b81518151811580156123025750806001145b156123a4578260008151811061231a5761231a6136e8565b60200260200101516020015167ffffffffffffffff1660011461239e578260008151811061234a5761234a6136e8565b60209081029190910181015101516040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260016024820152604401610823565b50505050565b8160011480156123b45750806002145b1561256a57836000815181106123cc576123cc6136e8565b602002602001015160400151836000815181106123eb576123eb6136e8565b60200260200101516040015114612477578260008151811061240f5761240f6136e8565b6020026020010151604001518460008151811061242e5761242e6136e8565b6020026020010151604001516040517fc7ccdd7f000000000000000000000000000000000000000000000000000000008152600401610823929190918252602082015260400190565b8360008151811061248a5761248a6136e8565b60200260200101516020015160016124a2919061405b565b67ffffffffffffffff16836001815181106124bf576124bf6136e8565b60200260200101516020015167ffffffffffffffff161461239e57826001815181106124ed576124ed6136e8565b6020026020010151602001518460008151811061250c5761250c6136e8565b6020026020010151602001516001612524919061405b565b6040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff928316600482015291166024820152604401610823565b81600214801561257a5750806001145b1561263d5783600181518110612592576125926136e8565b602002602001015160400151836000815181106125b1576125b16136e8565b6020026020010151604001511461239e57826000815181106125d5576125d56136e8565b602002602001015160400151846001815181106125f4576125f46136e8565b6020026020010151604001516040517f9e975670000000000000000000000000000000000000000000000000000000008152600401610823929190918252602082015260400190565b6040517f1f1b2bb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015167ffffffffffffffff166000036126b7576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815160018111156126cc576126cc6130de565b141580156126ed57506001815160018111156126ea576126ea6130de565b14155b15612724576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806080015151600003612763576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015161277e9060039067ffffffffffffffff166110d5565b6127c65760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610823565b60e081015151601f1015612806576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010081015151601f1015612847576040517f645960ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015167ffffffffffffffff166000908152600290915260408120600101546128779060ff16600361407c565b612882906001614098565b60ff169050808261010001515110156128d957610100820151516040517f548dd21f000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610823565b816040015160ff1660000361291a576040517f39d1a4d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604082015161292a90600361407c565b60ff168260e00151511161296a576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160e00151518260c001515114158061298e5750816101000151518260c001515114155b156129e95760c08201515160e083015151610100840151516040517fba900f6d000000000000000000000000000000000000000000000000000000008152600481019390935260248301919091526044820152606401610823565b8160c00151518260a00151511115612a2d576040517f8473d80700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a3f8260a001518360c00151612b4a565b60005b8260e0015151811015612a7057612a688360c001518281518110610d4157610d416136e8565b600101612a42565b505050565b60008082602001518584600001518560800151878760a001518860c001518960e001518a61010001518b604001518c606001518d6101200151604051602001612ac99c9b9a999897969594939291906140b1565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0a000000000000000000000000000000000000000000000000000000000000179150509392505050565b81511580612b5757508051155b15612b8e576040517fe249684100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b9782612cc5565b612ba081612cc5565b6000805b835182108015612bb45750825181105b15612c8657828181518110612bcb57612bcb6136e8565b6020026020010151848381518110612be557612be56136e8565b60200260200101511115612c0357612bfc81613f96565b9050612ba4565b828181518110612c1557612c156136e8565b6020026020010151848381518110612c2f57612c2f6136e8565b602002602001015103612c5057612c4582613f96565b9150612bfc81613f96565b83836040517fd671700c000000000000000000000000000000000000000000000000000000008152600401610823929190614191565b835182101561239e5783836040517fd671700c000000000000000000000000000000000000000000000000000000008152600401610823929190614191565b60015b815181101561120e5781612cdd600183613fce565b81518110612ced57612ced6136e8565b6020026020010151828281518110612d0757612d076136e8565b602002602001015111612d4857816040517f1bc41b4200000000000000000000000000000000000000000000000000000000815260040161082391906141b6565b600101612cc8565b6040518060400160405280600067ffffffffffffffff168152602001612d93604051806060016040528060608152602001600060ff168152602001606081525090565b905290565b5080546000825590600052602060002090810190610aab9190612eae565b508054612dc290613666565b6000825580601f10612dd2575050565b601f016020900490600052602060002090810190610aab9190612eae565b828054828255906000526020600020908101928215612e2b579160200282015b82811115612e2b578251825591602001919060010190612e10565b50612e37929150612eae565b5090565b5080546000825560090290600052602060002090810190610aab9190612ec3565b828054828255906000526020600020908101928215612ea2579160200282015b82811115612ea25782518290612e929082613a59565b5091602001919060010190612e7c565b50612e37929150612f84565b5b80821115612e375760008155600101612eaf565b80821115612e375780547fffffffffffffffffffffffffffff00000000000000000000000000000000000016815560008181612f026001830182612db6565b612f10600283016000612d98565b612f1e600383016000612d98565b612f2c600483016000612fa1565b612f3a600583016000612fa1565b612f48600683016000612db6565b5050506007810180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560006008820155600901612ec3565b80821115612e37576000612f988282612db6565b50600101612f84565b5080546000825590600052602060002090810190610aab9190612f84565b600060208284031215612fd157600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f4c57600080fd5b6000815180845260005b818110156130275760208185018101518683018201520161300b565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610f4c6020830184613001565b63ffffffff81168114610aab57600080fd5b803561309581613078565b919050565b80356002811061309557600080fd5b600080604083850312156130bc57600080fd5b82356130c781613078565b91506130d56020840161309a565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6002811061311d5761311d6130de565b9052565b60008151808452602080850194506020840160005b8381101561315257815187529582019590820190600101613136565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b848110156131c8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189526131b6838351613001565b9884019892509083019060010161317c565b5090979650505050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b838110156133a4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0898403018552815160608151818652613243828701825161310d565b89810151608061325e8189018367ffffffffffffffff169052565b8a830151915060a0613274818a018460ff169052565b938301519360c092506132928984018667ffffffffffffffff169052565b818401519450610140915060e082818b01526132b26101a08b0187613001565b95508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0610100818c890301818d01526132f18885613121565b97508587015195506101209350818c890301848d01526133118887613121565b9750828701519550818c890301858d015261332c888761315d565b975080870151955050808b8803016101608c015261334a878661315d565b9650828601519550808b8803016101808c0152505050505061336c8282613001565b915050888201516133888a87018267ffffffffffffffff169052565b50908701519387019390935293860193908601906001016131fe565b509098975050505050505050565b6000602082840312156133c457600080fd5b8135610f4c81613078565b60008151606084526133e46060850182613121565b905060ff60208401511660208501526040830151848203604086015261340a8282613001565b95945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b838110156133a4578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff168452870151878401879052613490878501826133cf565b958801959350509086019060010161343c565b6000602082840312156134b557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f4c57600080fd5b60008083601f8401126134eb57600080fd5b50813567ffffffffffffffff81111561350357600080fd5b6020830191508360208260051b850101111561351e57600080fd5b9250929050565b6000806000806040858703121561353b57600080fd5b843567ffffffffffffffff8082111561355357600080fd5b61355f888389016134d9565b9096509450602087013591508082111561357857600080fd5b50613585878288016134d9565b95989497509550505050565b803567ffffffffffffffff8116811461309557600080fd5b600080600080600080608087890312156135c257600080fd5b863567ffffffffffffffff808211156135da57600080fd5b6135e68a838b016134d9565b909850965060208901359150808211156135ff57600080fd5b818901915089601f83011261361357600080fd5b81358181111561362257600080fd5b8a602082850101111561363457600080fd5b60208301965080955050505061364c60408801613591565b915061365a6060880161308a565b90509295509295509295565b600181811c9082168061367a57607f821691505b6020821081036136b3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561372957600080fd5b610f4c82613591565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261376657600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261376657600080fd5b604051610140810167ffffffffffffffff811182821017156137c8576137c86136b9565b60405290565b60405160e0810167ffffffffffffffff811182821017156137c8576137c86136b9565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613838576138386136b9565b604052919050565b600067ffffffffffffffff82111561385a5761385a6136b9565b5060051b60200190565b600082601f83011261387557600080fd5b8135602061388a61388583613840565b6137f1565b8083825260208201915060208460051b8701019350868411156138ac57600080fd5b602086015b848110156138c857803583529183019183016138b1565b509695505050505050565b803560ff8116811461309557600080fd5b600082601f8301126138f557600080fd5b813567ffffffffffffffff81111561390f5761390f6136b9565b61394060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016137f1565b81815284602083860101111561395557600080fd5b816020850160208301376000918101602001919091529392505050565b60006060823603121561398457600080fd5b6040516060810167ffffffffffffffff82821081831117156139a8576139a86136b9565b8160405284359150808211156139bd57600080fd5b6139c936838701613864565b83526139d7602086016138d3565b602084015260408501359150808211156139f057600080fd5b506139fd368286016138e4565b60408301525092915050565b601f821115612a70576000816000526020600020601f850160051c81016020861015613a325750805b601f850160051c820191505b81811015613a5157828155600101613a3e565b505050505050565b815167ffffffffffffffff811115613a7357613a736136b9565b613a8781613a818454613666565b84613a09565b602080601f831160018114613ada5760008415613aa45750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613a51565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613b2757888601518255948401946001909101908401613b08565b5085821015613b6357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83168152604060208201526000613b9660408301846133cf565b949350505050565b600082601f830112613baf57600080fd5b81356020613bbf61388583613840565b82815260059290921b84018101918181019086841115613bde57600080fd5b8286015b848110156138c857803567ffffffffffffffff811115613c025760008081fd5b613c108986838b01016138e4565b845250918301918301613be2565b60006020808385031215613c3157600080fd5b823567ffffffffffffffff80821115613c4957600080fd5b818501915085601f830112613c5d57600080fd5b8135613c6b61388582613840565b81815260059190911b83018401908481019088831115613c8a57600080fd5b8585015b83811015613e1857803585811115613ca557600080fd5b8601610140818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215613cda57600080fd5b613ce26137a4565b613ced89830161309a565b8152613cfb60408301613591565b89820152613d0b606083016138d3565b6040820152613d1c60808301613591565b606082015260a082013587811115613d3357600080fd5b613d418d8b838601016138e4565b60808301525060c082013587811115613d5957600080fd5b613d678d8b83860101613864565b60a08301525060e082013587811115613d7f57600080fd5b613d8d8d8b83860101613864565b60c0830152506101008083013588811115613da757600080fd5b613db58e8c83870101613b9e565b60e0840152506101208084013589811115613dcf57600080fd5b613ddd8f8d83880101613b9e565b8385015250610140840135915088821115613df757600080fd5b613e058e8c848701016138e4565b9083015250845250918601918601613c8e565b5098975050505050505050565b805161309581613078565b600082601f830112613e4157600080fd5b81516020613e5161388583613840565b8083825260208201915060208460051b870101935086841115613e7357600080fd5b602086015b848110156138c85780518352918301918301613e78565b600060208284031215613ea157600080fd5b815167ffffffffffffffff80821115613eb957600080fd5b9083019060e08286031215613ecd57600080fd5b613ed56137ce565b613ede83613e25565b8152613eec60208401613e25565b6020820152613efd60408401613e25565b6040820152606083015160608201526080830151608082015260a083015182811115613f2857600080fd5b613f3487828601613e30565b60a08301525060c083015182811115613f4c57600080fd5b613f5887828601613e30565b60c08301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fc757613fc7613f67565b5060010190565b818103818111156102d0576102d0613f67565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8181036000831280158383131683831282161715610a9357610a93613f67565b6003811061311d5761311d6130de565b6040810161404e8285614030565b610f4c6020830184614030565b67ffffffffffffffff818116838216019080821115610a9357610a93613f67565b60ff8181168382160290811690818114610a9357610a93613f67565b60ff81811683821601908111156102d0576102d0613f67565b67ffffffffffffffff8d16815263ffffffff8c1660208201526140d7604082018c61310d565b610180606082015260006140ef61018083018c613001565b67ffffffffffffffff8b16608084015282810360a0840152614111818b613121565b905082810360c0840152614125818a613121565b905082810360e0840152614139818961315d565b905082810361010084015261414e818861315d565b60ff8716610120850152905067ffffffffffffffff851661014084015282810361016084015261417e8185613001565b9f9e505050505050505050505050505050565b6040815260006141a46040830185613121565b828103602084015261340a8185613121565b602081526000610f4c602083018461312156fea164736f6c6343000818000a", + Bin: "0x60a06040523480156200001157600080fd5b50604051620043d7380380620043d78339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e9576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b6080516141d6620002016000396000818160f801528181610e96015261112b01526141d66000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638318ed5d11610081578063f2fde38b1161005b578063f2fde38b14610204578063f442c89a14610217578063fba64a7c1461022a57600080fd5b80638318ed5d146101b05780638da5cb5b146101d1578063ddc042a8146101ef57600080fd5b8063181f5a77116100b2578063181f5a771461013d5780634bd0473f1461018657806379ba5097146101a657600080fd5b806301ffc9a7146100ce578063020330e6146100f6575b600080fd5b6100e16100dc366004612fbf565b61023d565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b6101796040518060400160405280601481526020017f43434950436f6e66696720312e362e302d64657600000000000000000000000081525081565b6040516100ed9190613065565b6101996101943660046130a9565b6102d6565b6040516100ed91906131d5565b6101ae6107a6565b005b6101796101be3660046133b2565b5060408051602081019091526000815290565b60005473ffffffffffffffffffffffffffffffffffffffff16610118565b6101f76108a8565b6040516100ed9190613413565b6101ae6102123660046134a3565b610a9a565b6101ae610225366004613525565b610aae565b6101ae6102383660046135a9565b610e7e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea7210000000000000000000000000000000000000000000000000000000014806102d057507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b63ffffffff82166000908152600560205260408120606091836001811115610300576103006130de565b6001811115610311576103116130de565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561079a57600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff166001811115610384576103846130de565b6001811115610395576103956130de565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916103ed90613666565b80601f016020809104026020016040519081016040528092919081815260200182805461041990613666565b80156104665780601f1061043b57610100808354040283529160200191610466565b820191906000526020600020905b81548152906001019060200180831161044957829003601f168201915b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156104be57602002820191906000526020600020905b8154815260200190600101908083116104aa575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561051657602002820191906000526020600020905b815481526020019060010190808311610502575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156105f057838290600052602060002001805461056390613666565b80601f016020809104026020016040519081016040528092919081815260200182805461058f90613666565b80156105dc5780601f106105b1576101008083540402835291602001916105dc565b820191906000526020600020905b8154815290600101906020018083116105bf57829003601f168201915b505050505081526020019060010190610544565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156106c957838290600052602060002001805461063c90613666565b80601f016020809104026020016040519081016040528092919081815260200182805461066890613666565b80156106b55780601f1061068a576101008083540402835291602001916106b5565b820191906000526020600020905b81548152906001019060200180831161069857829003601f168201915b50505050508152602001906001019061061d565b5050505081526020016006820180546106e190613666565b80601f016020809104026020016040519081016040528092919081815260200182805461070d90613666565b801561075a5780601f1061072f5761010080835404028352916020019161075a565b820191906000526020600020905b81548152906001019060200180831161073d57829003601f168201915b505050919092525050508152600782015467ffffffffffffffff16602080830191909152600890920154604090910152908252600192909201910161033f565b50505050905092915050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461082c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b606060006108b66003610f3f565b905060006108c46003610f53565b67ffffffffffffffff8111156108dc576108dc6136b9565b60405190808252806020026020018201604052801561091557816020015b610902612d50565b8152602001906001900390816108fa5790505b50905060005b8251811015610a93576000838281518110610938576109386136e8565b60209081029190910181015160408051808201825267ffffffffffffffff8316808252600090815260028552829020825181546080818802830181019095526060820181815295975092958601949093919284928491908401828280156109be57602002820191906000526020600020905b8154815260200190600101908083116109aa575b5050509183525050600182015460ff1660208201526002820180546040909201916109e890613666565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1490613666565b8015610a615780601f10610a3657610100808354040283529160200191610a61565b820191906000526020600020905b815481529060010190602001808311610a4457829003601f168201915b505050505081525050815250838381518110610a7f57610a7f6136e8565b60209081029190910101525060010161091b565b5092915050565b610aa2610f5d565b610aab81610fe0565b50565b610ab6610f5d565b60005b83811015610c9c57610afd858583818110610ad657610ad66136e8565b9050602002016020810190610aeb9190613717565b60039067ffffffffffffffff166110d5565b610b6757848482818110610b1357610b136136e8565b9050602002016020810190610b289190613717565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610823565b60026000868684818110610b7d57610b7d6136e8565b9050602002016020810190610b929190613717565b67ffffffffffffffff1681526020810191909152604001600090812090610bb98282612d98565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610bf1600283016000612db6565b5050610c2f858583818110610c0857610c086136e8565b9050602002016020810190610c1d9190613717565b60039067ffffffffffffffff166110ed565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110610c6357610c636136e8565b9050602002016020810190610c789190613717565b60405167ffffffffffffffff909116815260200160405180910390a1600101610ab9565b5060005b81811015610e77576000838383818110610cbc57610cbc6136e8565b9050602002810190610cce9190613732565b610cdc906020810190613770565b610ce590613972565b80519091506000858585818110610cfe57610cfe6136e8565b9050602002810190610d109190613732565b610d1e906020810190613717565b905060005b8251811015610d5657610d4e838281518110610d4157610d416136e8565b60200260200101516110f9565b600101610d23565b50826020015160ff16600003610d98576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120845180518693610dc8928492910190612df0565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560408201516002820190610e159082613a59565b50610e2f91506003905067ffffffffffffffff8316611212565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e08184604051610e61929190613b73565b60405180910390a1505050806001019050610ca0565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610eed576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610efb84860186613c1e565b9050600080610f098361121e565b8151919350915015610f2157610f2184600084611477565b805115610f3457610f3484600183611477565b505050505050505050565b60606000610f4c83611c58565b9392505050565b60006102d0825490565b60005473ffffffffffffffffffffffffffffffffffffffff163314610fde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610823565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361105f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610823565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515610f4c565b6000610f4c8383611cb4565b6040517f50c946fe000000000000000000000000000000000000000000000000000000008152600481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906350c946fe90602401600060405180830381865afa158015611187573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111cd9190810190613e8f565b608081015190915061120e576040517f8907a4fa00000000000000000000000000000000000000000000000000000000815260048101839052602401610823565b5050565b6000610f4c8383611da7565b606080600460ff1683511115611260576040517f8854586400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160028082526060820190925290816020015b6112e46040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161127657505060408051600280825260608201909252919350602082015b61137c6040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161130e57905050905060008060005b855181101561146a5760008682815181106113b4576113b46136e8565b60200260200101516000015160018111156113d1576113d16130de565b0361141e578581815181106113e8576113e86136e8565b6020026020010151858481518110611402576114026136e8565b60200260200101819052508261141790613f96565b9250611462565b858181518110611430576114306136e8565b602002602001015184838151811061144a5761144a6136e8565b60200260200101819052508161145f90613f96565b91505b600101611397565b5090835281529092909150565b63ffffffff831660009081526005602052604081208184600181111561149f5761149f6130de565b60018111156114b0576114b06130de565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561193957600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff166001811115611523576115236130de565b6001811115611534576115346130de565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a010000000000000000000090910416606082015260018201805460809092019161158c90613666565b80601f01602080910402602001604051908101604052809291908181526020018280546115b890613666565b80156116055780601f106115da57610100808354040283529160200191611605565b820191906000526020600020905b8154815290600101906020018083116115e857829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561165d57602002820191906000526020600020905b815481526020019060010190808311611649575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156116b557602002820191906000526020600020905b8154815260200190600101908083116116a1575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b8282101561178f57838290600052602060002001805461170290613666565b80601f016020809104026020016040519081016040528092919081815260200182805461172e90613666565b801561177b5780601f106117505761010080835404028352916020019161177b565b820191906000526020600020905b81548152906001019060200180831161175e57829003601f168201915b5050505050815260200190600101906116e3565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156118685783829060005260206000200180546117db90613666565b80601f016020809104026020016040519081016040528092919081815260200182805461180790613666565b80156118545780601f1061182957610100808354040283529160200191611854565b820191906000526020600020905b81548152906001019060200180831161183757829003601f168201915b5050505050815260200190600101906117bc565b50505050815260200160068201805461188090613666565b80601f01602080910402602001604051908101604052809291908181526020018280546118ac90613666565b80156118f95780601f106118ce576101008083540402835291602001916118f9565b820191906000526020600020905b8154815290600101906020018083116118dc57829003601f168201915b505050919092525050508152600782015467ffffffffffffffff1660208083019190915260089092015460409091015290825260019290920191016114de565b505050509050600061194b8251611df6565b905060006119598451611df6565b90506119658282611e48565b60006119748785878686611f04565b905061198084826122f0565b63ffffffff87166000908152600560205260408120908760018111156119a8576119a86130de565b60018111156119b9576119b96130de565b815260200190815260200160002060006119d39190612e3b565b60005b8151811015611c4e5763ffffffff8816600090815260056020526040812090886001811115611a0757611a076130de565b6001811115611a1857611a186130de565b8152602001908152602001600020828281518110611a3857611a386136e8565b6020908102919091018101518254600181810185556000948552929093208151805160099095029091018054929490939192849283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908381811115611aa257611aa26130de565b021790555060208201518154604084015160608501517fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90921661010067ffffffffffffffff948516027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1617690100000000000000000060ff90921691909102177fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a0100000000000000000000929091169190910217815560808201516001820190611b719082613a59565b5060a08201518051611b8d916002840191602090910190612df0565b5060c08201518051611ba9916003840191602090910190612df0565b5060e08201518051611bc5916004840191602090910190612e5c565b506101008201518051611be2916005840191602090910190612e5c565b506101208201516006820190611bf89082613a59565b50505060208201516007820180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9092169190911790556040909101516008909101556001016119d6565b5050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611ca857602002820191906000526020600020905b815481526020019060010190808311611c94575b50505050509050919050565b60008181526001830160205260408120548015611d9d576000611cd8600183613fce565b8554909150600090611cec90600190613fce565b9050808214611d51576000866000018281548110611d0c57611d0c6136e8565b9060005260206000200154905080876000018481548110611d2f57611d2f6136e8565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611d6257611d62613fe1565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506102d0565b60009150506102d0565b6000818152600183016020526040812054611dee575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556102d0565b5060006102d0565b60006002821115611e36576040517f3e47852600000000000000000000000000000000000000000000000000000000815260048101839052602401610823565b8160028111156102d0576102d06130de565b6000826002811115611e5c57611e5c6130de565b826002811115611e6e57611e6e6130de565b611e789190614010565b90508060011480611ec45750807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff148015611ec457506002836002811115611ec257611ec26130de565b145b15611ece57505050565b82826040517f0a6b675b000000000000000000000000000000000000000000000000000000008152600401610823929190614040565b60606000845167ffffffffffffffff811115611f2257611f226136b9565b604051908082528060200260200182016040528015611f4b578160200160208202803683370190505b5090506000846002811115611f6257611f626130de565b148015611f8057506001836002811115611f7e57611f7e6130de565b145b15611fc157600181600081518110611f9a57611f9a6136e8565b602002602001019067ffffffffffffffff16908167ffffffffffffffff1681525050612129565b6001846002811115611fd557611fd56130de565b148015611ff357506002836002811115611ff157611ff16130de565b145b1561208a578560008151811061200b5761200b6136e8565b6020026020010151602001518160008151811061202a5761202a6136e8565b602002602001019067ffffffffffffffff16908167ffffffffffffffff16815250508560008151811061205f5761205f6136e8565b6020026020010151602001516001612077919061405b565b81600181518110611f9a57611f9a6136e8565b600284600281111561209e5761209e6130de565b1480156120bc575060018360028111156120ba576120ba6130de565b145b156120f357856001815181106120d4576120d46136e8565b60200260200101516020015181600081518110611f9a57611f9a6136e8565b83836040517f0a6b675b000000000000000000000000000000000000000000000000000000008152600401610823929190614040565b6000855167ffffffffffffffff811115612145576121456136b9565b6040519080825280602002602001820160405280156121fb57816020015b604080516101a081018252600060608083018281526080840183905260a0840183905260c0840183905260e084018290526101008401829052610120840182905261014084018290526101608401829052610180840191909152825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816121635790505b50905060005b82518110156122e45761222c87828151811061221f5761221f6136e8565b602002602001015161266f565b6040518060600160405280888381518110612249576122496136e8565b60200260200101518152602001848381518110612268576122686136e8565b602002602001015167ffffffffffffffff1681526020016122bc8b868581518110612295576122956136e8565b60200260200101518b86815181106122af576122af6136e8565b6020026020010151612a75565b8152508282815181106122d1576122d16136e8565b6020908102919091010152600101612201565b50979650505050505050565b81518151811580156123025750806001145b156123a4578260008151811061231a5761231a6136e8565b60200260200101516020015167ffffffffffffffff1660011461239e578260008151811061234a5761234a6136e8565b60209081029190910181015101516040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260016024820152604401610823565b50505050565b8160011480156123b45750806002145b1561256a57836000815181106123cc576123cc6136e8565b602002602001015160400151836000815181106123eb576123eb6136e8565b60200260200101516040015114612477578260008151811061240f5761240f6136e8565b6020026020010151604001518460008151811061242e5761242e6136e8565b6020026020010151604001516040517fc7ccdd7f000000000000000000000000000000000000000000000000000000008152600401610823929190918252602082015260400190565b8360008151811061248a5761248a6136e8565b60200260200101516020015160016124a2919061405b565b67ffffffffffffffff16836001815181106124bf576124bf6136e8565b60200260200101516020015167ffffffffffffffff161461239e57826001815181106124ed576124ed6136e8565b6020026020010151602001518460008151811061250c5761250c6136e8565b6020026020010151602001516001612524919061405b565b6040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff928316600482015291166024820152604401610823565b81600214801561257a5750806001145b1561263d5783600181518110612592576125926136e8565b602002602001015160400151836000815181106125b1576125b16136e8565b6020026020010151604001511461239e57826000815181106125d5576125d56136e8565b602002602001015160400151846001815181106125f4576125f46136e8565b6020026020010151604001516040517f9e975670000000000000000000000000000000000000000000000000000000008152600401610823929190918252602082015260400190565b6040517f1f1b2bb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015167ffffffffffffffff166000036126b7576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815160018111156126cc576126cc6130de565b141580156126ed57506001815160018111156126ea576126ea6130de565b14155b15612724576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806080015151600003612763576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015161277e9060039067ffffffffffffffff166110d5565b6127c65760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610823565b60e081015151601f1015612806576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010081015151601f1015612847576040517f645960ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015167ffffffffffffffff166000908152600290915260408120600101546128779060ff16600361407c565b612882906001614098565b60ff169050808261010001515110156128d957610100820151516040517f548dd21f000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610823565b816040015160ff1660000361291a576040517f39d1a4d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604082015161292a90600361407c565b60ff168260e00151511161296a576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160e00151518260c001515114158061298e5750816101000151518260c001515114155b156129e95760c08201515160e083015151610100840151516040517fba900f6d000000000000000000000000000000000000000000000000000000008152600481019390935260248301919091526044820152606401610823565b8160c00151518260a00151511115612a2d576040517f8473d80700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a3f8260a001518360c00151612b4a565b60005b8260e0015151811015612a7057612a688360c001518281518110610d4157610d416136e8565b600101612a42565b505050565b60008082602001518584600001518560800151878760a001518860c001518960e001518a61010001518b604001518c606001518d6101200151604051602001612ac99c9b9a999897969594939291906140b1565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0a000000000000000000000000000000000000000000000000000000000000179150509392505050565b81511580612b5757508051155b15612b8e576040517fe249684100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b9782612cc5565b612ba081612cc5565b6000805b835182108015612bb45750825181105b15612c8657828181518110612bcb57612bcb6136e8565b6020026020010151848381518110612be557612be56136e8565b60200260200101511115612c0357612bfc81613f96565b9050612ba4565b828181518110612c1557612c156136e8565b6020026020010151848381518110612c2f57612c2f6136e8565b602002602001015103612c5057612c4582613f96565b9150612bfc81613f96565b83836040517fd671700c000000000000000000000000000000000000000000000000000000008152600401610823929190614191565b835182101561239e5783836040517fd671700c000000000000000000000000000000000000000000000000000000008152600401610823929190614191565b60015b815181101561120e5781612cdd600183613fce565b81518110612ced57612ced6136e8565b6020026020010151828281518110612d0757612d076136e8565b602002602001015111612d4857816040517f1bc41b4200000000000000000000000000000000000000000000000000000000815260040161082391906141b6565b600101612cc8565b6040518060400160405280600067ffffffffffffffff168152602001612d93604051806060016040528060608152602001600060ff168152602001606081525090565b905290565b5080546000825590600052602060002090810190610aab9190612eae565b508054612dc290613666565b6000825580601f10612dd2575050565b601f016020900490600052602060002090810190610aab9190612eae565b828054828255906000526020600020908101928215612e2b579160200282015b82811115612e2b578251825591602001919060010190612e10565b50612e37929150612eae565b5090565b5080546000825560090290600052602060002090810190610aab9190612ec3565b828054828255906000526020600020908101928215612ea2579160200282015b82811115612ea25782518290612e929082613a59565b5091602001919060010190612e7c565b50612e37929150612f84565b5b80821115612e375760008155600101612eaf565b80821115612e375780547fffffffffffffffffffffffffffff00000000000000000000000000000000000016815560008181612f026001830182612db6565b612f10600283016000612d98565b612f1e600383016000612d98565b612f2c600483016000612fa1565b612f3a600583016000612fa1565b612f48600683016000612db6565b5050506007810180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560006008820155600901612ec3565b80821115612e37576000612f988282612db6565b50600101612f84565b5080546000825590600052602060002090810190610aab9190612f84565b600060208284031215612fd157600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f4c57600080fd5b6000815180845260005b818110156130275760208185018101518683018201520161300b565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610f4c6020830184613001565b63ffffffff81168114610aab57600080fd5b803561309581613078565b919050565b80356002811061309557600080fd5b600080604083850312156130bc57600080fd5b82356130c781613078565b91506130d56020840161309a565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6002811061311d5761311d6130de565b9052565b60008151808452602080850194506020840160005b8381101561315257815187529582019590820190600101613136565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b848110156131c8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189526131b6838351613001565b9884019892509083019060010161317c565b5090979650505050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b838110156133a4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0898403018552815160608151818652613243828701825161310d565b89810151608061325e8189018367ffffffffffffffff169052565b8a830151915060a0613274818a018460ff169052565b938301519360c092506132928984018667ffffffffffffffff169052565b818401519450610140915060e082818b01526132b26101a08b0187613001565b95508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0610100818c890301818d01526132f18885613121565b97508587015195506101209350818c890301848d01526133118887613121565b9750828701519550818c890301858d015261332c888761315d565b975080870151955050808b8803016101608c015261334a878661315d565b9650828601519550808b8803016101808c0152505050505061336c8282613001565b915050888201516133888a87018267ffffffffffffffff169052565b50908701519387019390935293860193908601906001016131fe565b509098975050505050505050565b6000602082840312156133c457600080fd5b8135610f4c81613078565b60008151606084526133e46060850182613121565b905060ff60208401511660208501526040830151848203604086015261340a8282613001565b95945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b838110156133a4578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff168452870151878401879052613490878501826133cf565b958801959350509086019060010161343c565b6000602082840312156134b557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f4c57600080fd5b60008083601f8401126134eb57600080fd5b50813567ffffffffffffffff81111561350357600080fd5b6020830191508360208260051b850101111561351e57600080fd5b9250929050565b6000806000806040858703121561353b57600080fd5b843567ffffffffffffffff8082111561355357600080fd5b61355f888389016134d9565b9096509450602087013591508082111561357857600080fd5b50613585878288016134d9565b95989497509550505050565b803567ffffffffffffffff8116811461309557600080fd5b600080600080600080608087890312156135c257600080fd5b863567ffffffffffffffff808211156135da57600080fd5b6135e68a838b016134d9565b909850965060208901359150808211156135ff57600080fd5b818901915089601f83011261361357600080fd5b81358181111561362257600080fd5b8a602082850101111561363457600080fd5b60208301965080955050505061364c60408801613591565b915061365a6060880161308a565b90509295509295509295565b600181811c9082168061367a57607f821691505b6020821081036136b3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561372957600080fd5b610f4c82613591565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261376657600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261376657600080fd5b604051610140810167ffffffffffffffff811182821017156137c8576137c86136b9565b60405290565b60405160e0810167ffffffffffffffff811182821017156137c8576137c86136b9565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613838576138386136b9565b604052919050565b600067ffffffffffffffff82111561385a5761385a6136b9565b5060051b60200190565b600082601f83011261387557600080fd5b8135602061388a61388583613840565b6137f1565b8083825260208201915060208460051b8701019350868411156138ac57600080fd5b602086015b848110156138c857803583529183019183016138b1565b509695505050505050565b803560ff8116811461309557600080fd5b600082601f8301126138f557600080fd5b813567ffffffffffffffff81111561390f5761390f6136b9565b61394060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016137f1565b81815284602083860101111561395557600080fd5b816020850160208301376000918101602001919091529392505050565b60006060823603121561398457600080fd5b6040516060810167ffffffffffffffff82821081831117156139a8576139a86136b9565b8160405284359150808211156139bd57600080fd5b6139c936838701613864565b83526139d7602086016138d3565b602084015260408501359150808211156139f057600080fd5b506139fd368286016138e4565b60408301525092915050565b601f821115612a70576000816000526020600020601f850160051c81016020861015613a325750805b601f850160051c820191505b81811015613a5157828155600101613a3e565b505050505050565b815167ffffffffffffffff811115613a7357613a736136b9565b613a8781613a818454613666565b84613a09565b602080601f831160018114613ada5760008415613aa45750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613a51565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613b2757888601518255948401946001909101908401613b08565b5085821015613b6357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83168152604060208201526000613b9660408301846133cf565b949350505050565b600082601f830112613baf57600080fd5b81356020613bbf61388583613840565b82815260059290921b84018101918181019086841115613bde57600080fd5b8286015b848110156138c857803567ffffffffffffffff811115613c025760008081fd5b613c108986838b01016138e4565b845250918301918301613be2565b60006020808385031215613c3157600080fd5b823567ffffffffffffffff80821115613c4957600080fd5b818501915085601f830112613c5d57600080fd5b8135613c6b61388582613840565b81815260059190911b83018401908481019088831115613c8a57600080fd5b8585015b83811015613e1857803585811115613ca557600080fd5b8601610140818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215613cda57600080fd5b613ce26137a4565b613ced89830161309a565b8152613cfb60408301613591565b89820152613d0b606083016138d3565b6040820152613d1c60808301613591565b606082015260a082013587811115613d3357600080fd5b613d418d8b838601016138e4565b60808301525060c082013587811115613d5957600080fd5b613d678d8b83860101613864565b60a08301525060e082013587811115613d7f57600080fd5b613d8d8d8b83860101613864565b60c0830152506101008083013588811115613da757600080fd5b613db58e8c83870101613b9e565b60e0840152506101208084013589811115613dcf57600080fd5b613ddd8f8d83880101613b9e565b8385015250610140840135915088821115613df757600080fd5b613e058e8c848701016138e4565b9083015250845250918601918601613c8e565b5098975050505050505050565b805161309581613078565b600082601f830112613e4157600080fd5b81516020613e5161388583613840565b8083825260208201915060208460051b870101935086841115613e7357600080fd5b602086015b848110156138c85780518352918301918301613e78565b600060208284031215613ea157600080fd5b815167ffffffffffffffff80821115613eb957600080fd5b9083019060e08286031215613ecd57600080fd5b613ed56137ce565b613ede83613e25565b8152613eec60208401613e25565b6020820152613efd60408401613e25565b6040820152606083015160608201526080830151608082015260a083015182811115613f2857600080fd5b613f3487828601613e30565b60a08301525060c083015182811115613f4c57600080fd5b613f5887828601613e30565b60c08301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fc757613fc7613f67565b5060010190565b818103818111156102d0576102d0613f67565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8181036000831280158383131683831282161715610a9357610a93613f67565b6003811061311d5761311d6130de565b6040810161404e8285614030565b610f4c6020830184614030565b67ffffffffffffffff818116838216019080821115610a9357610a93613f67565b60ff8181168382160290811690818114610a9357610a93613f67565b60ff81811683821601908111156102d0576102d0613f67565b67ffffffffffffffff8d16815263ffffffff8c1660208201526140d7604082018c61310d565b610180606082015260006140ef61018083018c613001565b67ffffffffffffffff8b16608084015282810360a0840152614111818b613121565b905082810360c0840152614125818a613121565b905082810360e0840152614139818961315d565b905082810361010084015261414e818861315d565b60ff8716610120850152905067ffffffffffffffff851661014084015282810361016084015261417e8185613001565b9f9e505050505050505050505050505050565b6040815260006141a46040830185613121565b828103602084015261340a8185613121565b602081526000610f4c602083018461312156fea164736f6c6343000818000a", } var CCIPConfigABI = CCIPConfigMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go index a5dde0893e..2b7571d55e 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go @@ -164,7 +164,7 @@ type MultiOCR3BaseOCRConfigArgs struct { var EVM2EVMMultiOffRampMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162006bba38038062006bba8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615ee462000cd6600039600081816102530152612c0c0152600081816102240152612ee60152600081816101f50152818161142f01526118400152600081816101c50152612801015260008181611dce0152611e1a0152615ee46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063d2a15d351461053d578063e9d68a8e14610550578063ece670b61461057057600080fd5b8063991a5018116100bd578063991a5018146104c5578063c673e584146104d8578063ccd37ba3146104f857600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104815780637d4eef601461048957600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a3660046140a0565b6105cc565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d1919061420f565b61018f6103313660046142ba565b6105e0565b61018f61034436600461436d565b6109c0565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143c1565b610a29565b6040516102d1919061441e565b6104246040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610a7f565b61018f610497366004614973565b610b3d565b61018f610177366004614a9e565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104d3366004614aed565b610cdd565b6104eb6104e6366004614b72565b610cee565b6040516102d19190614bd2565b61052f610506366004614c47565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f61054b366004614c71565b610e4c565b61056361055e366004614ce6565b610f06565b6040516102d19190614d01565b61018f61057e366004614d4f565b611013565b61018f610591366004614dab565b611386565b61018f6105a4366004614e30565b611397565b6105bc6105b7366004614f6e565b6113d9565b60405190151581526020016102d1565b6105d461149a565b6105dd816114f6565b50565b60006105ee878901896150f7565b8051515190915015158061060757508051602001515115155b156107075760095460208a01359067ffffffffffffffff808316911610156106c6576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261068f929101615335565b600060405180830381600087803b1580156106a957600080fd5b505af11580156106bd573d6000803e3d6000fd5b50505050610705565b816020015151600003610705576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109095760008260200151828151811061072f5761072f615262565b6020026020010151905060008160000151905061074b816117f4565b6000610756826118f6565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061079a575060208084015190810151905167ffffffffffffffff9182169116115b156107e357825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107da929190600401615348565b60405180910390fd5b60408301518061081f576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108925783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016107da565b60208085015101516108a5906001615393565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff92831602179092559251166000908152600860209081526040808320948352939052919091204290555060010161070a565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161093991906153bb565b60405180910390a16109b560008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b925061195d915050565b505050505050505050565b610a006109cf82840184615458565b60408051600080825260208201909252906109fa565b60608152602001906001900390816109e55790505b50611cd4565b604080516000808252602082019092529050610a2360018585858586600061195d565b50505050565b6000610a376001600461548d565b6002610a446080856154b6565b67ffffffffffffffff16610a5891906154dd565b610a628585611d84565b901c166003811115610a7657610a766143f4565b90505b92915050565b6001546001600160a01b03163314610ad95760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107da565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b45611dcb565b815181518114610b81576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ccd576000848281518110610ba057610ba0615262565b60200260200101519050600081602001515190506000858481518110610bc857610bc8615262565b6020026020010151905080518214610c0c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cbe576000828281518110610c2b57610c2b615262565b6020026020010151905080600014610cb55784602001518281518110610c5357610c53615262565b602002602001015160800151811015610cb55784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016107da565b50600101610c0f565b50505050806001019050610b84565b50610cd88383611cd4565b505050565b610ce561149a565b6105dd81611e4c565b610d316040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610dda57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dbc575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e1e575b5050505050815250509050919050565b610e5461149a565b60005b81811015610cd8576000838383818110610e7357610e73615262565b905060400201803603810190610e8991906154f4565b9050610e9881602001516113d9565b610efd57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e57565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191610f939061552d565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbf9061552d565b8015610e3c5780601f10610fe157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610fef57505050919092525091949350505050565b33301461104c576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611089565b60408051808201909152600080825260208201528152602001906001900390816110625790505b5060a085015151909150156110bd576110ba8460a00151856020015186606001518760000151602001518787611fb2565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff16818301528087015183516000948401926110f992910161420f565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015611206576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a190611173908590600401615609565b600060405180830381600087803b15801561118d57600080fd5b505af192505050801561119e575060015b611206573d8080156111cc576040519150601f19603f3d011682016040523d82523d6000602084013e6111d1565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b60408601515115801561121b57506080860151155b80611232575060608601516001600160a01b03163b155b8061127257506060860151611270906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120d1565b155b1561127f57505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf97983926112f7928992611388929160040161561c565b6000604051808303816000875af1158015611316573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261133e9190810190615658565b50915091508161137c57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b5050505050505050565b61138e61149a565b6105dd816120ed565b61139f61149a565b60005b81518110156113d5576113cd8282815181106113c0576113c0615262565b60200260200101516121a3565b6001016113a2565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611476573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7991906156ee565b6000546001600160a01b031633146114f45760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107da565b565b60005b81518110156113d557600082828151811061151657611516615262565b602002602001015190506000816020015190508067ffffffffffffffff1660000361156d576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611595576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115c09061552d565b80601f01602080910402602001604051908101604052809291908181526020018280546115ec9061552d565b80156116395780601f1061160e57610100808354040283529160200191611639565b820191906000526020600020905b81548152906001019060200180831161161c57829003601f168201915b5050505050905060008460600151905081516000036116f1578051600003611674576040516342bcdf7f60e11b815260040160405180910390fd5b600183016116828282615753565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611744565b8080519060200120828051906020012014611744576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016107da565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117dc908690615813565b60405180910390a250505050508060010190506114f9565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b391906156ee565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107da565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610a79576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107da565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906119bc8760a46158e1565b9050826060015115611a045784516119d59060206154dd565b86516119e29060206154dd565b6119ed9060a06158e1565b6119f791906158e1565b611a0190826158e1565b90505b368114611a46576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107da565b5081518114611a8e5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107da565b611a96611dcb565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611ae457611ae46143f4565b6002811115611af557611af56143f4565b9052509050600281602001516002811115611b1257611b126143f4565b148015611b665750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611b4e57611b4e615262565b6000918252602090912001546001600160a01b031633145b611b9c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611c7e576020820151611bb79060016158f4565b60ff16855114611bf3576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611c2e576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611c4092919061590d565b604051908190038120611c57918b9060200161591d565b604051602081830303815290604052805190602001209050611c7c8a828888886124e7565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d0e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611d7d57611d75858281518110611d4357611d43615262565b602002602001015184611d6f57858381518110611d6257611d62615262565b60200260200101516126f4565b836126f4565b600101611d25565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611da9608085615931565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f0000000000000000000000000000000000000000000000000000000000000000146114f4576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107da565b80516001600160a01b0316611e74576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fce57611fce613eb7565b60405190808252806020026020018201604052801561201357816020015b6040805180820190915260008082526020820152815260200190600190039081611fec5790505b50905060005b87518110156120c5576120a088828151811061203757612037615262565b602002602001015188888888888781811061205457612054615262565b90506020028101906120669190615958565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e8592505050565b8282815181106120b2576120b2615262565b6020908102919091010152600101612019565b505b9695505050505050565b60006120dc8361322a565b8015610a765750610a76838361328e565b336001600160a01b038216036121455760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107da565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ce576000604051631b3fab5160e11b81526004016107da91906159bd565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223b57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612290565b6060840151600182015460ff6201000090910416151590151514612290576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016107da565b60a08401518051601f60ff821611156122bf576001604051631b3fab5160e11b81526004016107da91906159bd565b612325858560030180548060200260200160405190810160405280929190818152602001828054801561231b57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122fd575b5050505050613348565b85606001511561245457612393858560020180548060200260200160405190810160405280929190818152602001828054801561231b576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122fd575050505050613348565b608086015180516123ad9060028701906020840190613e11565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f101561240d576002604051631b3fab5160e11b81526004016107da91906159bd565b604088015161241d9060036159d7565b60ff168160ff1611612445576003604051631b3fab5160e11b81526004016107da91906159bd565b612451878360016133b1565b50505b612460858360026133b1565b81516124759060038601906020850190613e11565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ce938a939260028b019291906159f3565b60405180910390a16124df85613531565b505050505050565b6124ef613e83565b835160005b8181101561137c57600060018886846020811061251357612513615262565b61252091901a601b6158f4565b89858151811061253257612532615262565b602002602001015189868151811061254c5761254c615262565b60200260200101516040516000815260200160405260405161258a949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156125ac573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561260d5761260d6143f4565b600281111561261e5761261e6143f4565b905250905060018160200151600281111561263b5761263b6143f4565b14612672576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061268957612689615262565b6020020151156126c5576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126e0576126e0615262565b9115156020909202015250506001016124f4565b81516126ff816117f4565b600061270a826118f6565b602085015151909150600081900361274d576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461278b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156127a6576127a6613eb7565b6040519080825280602002602001820160405280156127cf578160200160208202803683370190505b50905060005b82811015612944576000876020015182815181106127f5576127f5615262565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461288857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107da565b61291e8186600101805461289b9061552d565b80601f01602080910402602001604051908101604052809291908181526020018280546128c79061552d565b80156129145780601f106128e957610100808354040283529160200191612914565b820191906000526020600020905b8154815290600101906020018083116128f757829003601f168201915b505050505061354d565b83838151811061293057612930615262565b6020908102919091010152506001016127d5565b50600061295b858389606001518a6080015161366f565b9050806000036129a3576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107da565b8551151560005b848110156109b5576000896020015182815181106129ca576129ca615262565b6020026020010151905060006129e889836000015160600151610a29565b905060008160038111156129fe576129fe6143f4565b1480612a1b57506003816003811115612a1957612a196143f4565b145b612a72578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612e7d565b8315612b4257600454600090600160a01b900463ffffffff16612a95874261548d565b1190508080612ab557506003826003811115612ab357612ab36143f4565b145b612af7576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b1660048201526024016107da565b8a8481518110612b0957612b09615262565b6020026020010151600014612b3c578a8481518110612b2a57612b2a615262565b60200260200101518360800181815250505b50612ba3565b6000816003811115612b5657612b566143f4565b14612ba3578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612a63565b81516080015167ffffffffffffffff1615612c91576000816003811115612bcc57612bcc6143f4565b03612c915781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c43928e929190600401615a9f565b6020604051808303816000875af1158015612c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8691906156ee565b612c91575050612e7d565b60008b604001518481518110612ca957612ca9615262565b6020026020010151905080518360a001515114612d0d578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d16600483015290911660248201526044016107da565b612d218a84600001516060015160016136c5565b600080612d2e858461376d565b91509150612d458c866000015160600151846136c5565b8615612db5576003826003811115612d5f57612d5f6143f4565b03612db5576000846003811115612d7857612d786143f4565b14612db5578451516040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526107da91908390600401615acc565b6002826003811115612dc957612dc96143f4565b14612e23576003826003811115612de257612de26143f4565b14612e23578451606001516040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526107da918e918590600401615ae5565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612e6f9087908790615b0b565b60405180910390a450505050505b6001016129aa565b60408051808201909152600080825260208201526000612ea88760200151613837565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f519190615b2b565b90506001600160a01b0381161580612f995750612f976001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120d1565b155b15612fdb576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016107da565b6004546000908190612ffd9089908690600160e01b900463ffffffff166138dd565b9150915060008060006130ca6040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b81525060405160240161307b9190615b48565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a0b565b9250925092508261310957816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b81516020146131515781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b6000828060200190518101906131679190615c15565b9050866001600160a01b03168c6001600160a01b0316146131fc5760006131988d8a613193868a61548d565b6138dd565b509050868110806131b25750816131af888361548d565b14155b156131fa576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016107da565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613256827f01ffc9a70000000000000000000000000000000000000000000000000000000061328e565b8015610a795750613287827fffffffff0000000000000000000000000000000000000000000000000000000061328e565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613331575060208210155b801561333d5750600081115b979650505050505050565b60005b8151811015610cd85760ff83166000908152600360205260408120835190919084908490811061337d5761337d615262565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161334b565b60005b82518160ff161015610a23576000838260ff16815181106133d7576133d7615262565b60200260200101519050600060028111156133f4576133f46143f4565b60ff80871660009081526003602090815260408083206001600160a01b03871684529091529020546101009004166002811115613433576134336143f4565b14613454576004604051631b3fab5160e11b81526004016107da91906159bd565b6001600160a01b038116613494576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134ba576134ba6143f4565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff191617610100836002811115613517576135176143f4565b0217905550905050508061352a90615c2e565b90506133b4565b60ff81166105dd576009805467ffffffffffffffff1916905550565b815160208082015160409283015192516000938493613593937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c4d565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135dc9794969395929491939101615c80565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136139190615d77565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061367d858585613b31565b9050613688816113d9565b6136965760009150506136bd565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026136d46080856154b6565b67ffffffffffffffff166136e891906154dd565b905060006136f68585611d84565b9050816137056001600461548d565b901b19168183600381111561371c5761371c6143f4565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161374b608088615931565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906137b19087908790600401615dd7565b600060405180830381600087803b1580156137cb57600080fd5b505af19250505080156137dc575060015b61381b573d80801561380a576040519150601f19603f3d011682016040523d82523d6000602084013e61380f565b606091505b50600392509050613830565b50506040805160208101909152600081526002905b9250929050565b6000815160201461387657816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b60008280602001905181019061388c9190615c15565b90506001600160a01b038111806138a4575061040081105b15610a7957826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b60008060008060006139578860405160240161390891906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a0b565b9250925092508261399657816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da919061420f565b60208251146139de5781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b818060200190518101906139f29190615c15565b6139fc828861548d565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a2e57613a2e613eb7565b6040519080825280601f01601f191660200182016040528015613a58576020820181803683370190505b509150863b613a8b577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613abe577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613af7577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b1a5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b72576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b8657506101018111155b613ba3576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bcd576040516309bde33960e01b815260040160405180910390fd5b80600003613bfa5786600081518110613be857613be8615262565b60200260200101519350505050613dc9565b60008167ffffffffffffffff811115613c1557613c15613eb7565b604051908082528060200260200182016040528015613c3e578160200160208202803683370190505b50905060008080805b85811015613d685760006001821b8b811603613ca25788851015613c8b578c5160018601958e918110613c7c57613c7c615262565b60200260200101519050613cc4565b8551600185019487918110613c7c57613c7c615262565b8b5160018401938d918110613cb957613cb9615262565b602002602001015190505b600089861015613cf4578d5160018701968f918110613ce557613ce5615262565b60200260200101519050613d16565b8651600186019588918110613d0b57613d0b615262565b602002602001015190505b82851115613d37576040516309bde33960e01b815260040160405180910390fd5b613d418282613dd0565b878481518110613d5357613d53615262565b60209081029190910101525050600101613c47565b506001850382148015613d7a57508683145b8015613d8557508581145b613da2576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613db757613db7615262565b60200260200101519750505050505050505b9392505050565b6000818310613de857613de38284613dee565b610a76565b610a7683835b604080516001602082015290810183905260608101829052600090608001613651565b828054828255906000526020600020908101928215613e73579160200282015b82811115613e73578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e31565b50613e7f929150613ea2565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e7f5760008155600101613ea3565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b60405290565b60405160a0810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b60405160c0810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b6040805190810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b6040516060810167ffffffffffffffff81118282101715613ef057613ef0613eb7565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fab57613fab613eb7565b604052919050565b600067ffffffffffffffff821115613fcd57613fcd613eb7565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461400457600080fd5b919050565b80151581146105dd57600080fd5b803561400481614009565b600067ffffffffffffffff82111561403c5761403c613eb7565b50601f01601f191660200190565b600082601f83011261405b57600080fd5b813561406e61406982614022565b613f82565b81815284602083860101111561408357600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140b357600080fd5b823567ffffffffffffffff808211156140cb57600080fd5b818501915085601f8301126140df57600080fd5b81356140ed61406982613fb3565b81815260059190911b8301840190848101908883111561410c57600080fd5b8585015b838110156141b2578035858111156141285760008081fd5b86016080818c03601f19018113156141405760008081fd5b614148613ecd565b8983013561415581613fd7565b81526040614164848201613fec565b8b83015260608085013561417781614009565b8383015292840135928984111561419057600091508182fd5b61419e8f8d8688010161404a565b908301525085525050918601918601614110565b5098975050505050505050565b60005b838110156141da5781810151838201526020016141c2565b50506000910152565b600081518084526141fb8160208601602086016141bf565b601f01601f19169290920160200192915050565b602081526000610a7660208301846141e3565b8060608101831015610a7957600080fd5b60008083601f84011261424557600080fd5b50813567ffffffffffffffff81111561425d57600080fd5b60208301915083602082850101111561383057600080fd5b60008083601f84011261428757600080fd5b50813567ffffffffffffffff81111561429f57600080fd5b6020830191508360208260051b850101111561383057600080fd5b60008060008060008060008060e0898b0312156142d657600080fd5b6142e08a8a614222565b9750606089013567ffffffffffffffff808211156142fd57600080fd5b6143098c838d01614233565b909950975060808b013591508082111561432257600080fd5b61432e8c838d01614275565b909750955060a08b013591508082111561434757600080fd5b506143548b828c01614275565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561438257600080fd5b61438c8585614222565b9250606084013567ffffffffffffffff8111156143a857600080fd5b6143b486828701614233565b9497909650939450505050565b600080604083850312156143d457600080fd5b6143dd83613fec565b91506143eb60208401613fec565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061441a5761441a6143f4565b9052565b60208101610a79828461440a565b600060a0828403121561443e57600080fd5b614446613ef6565b90508135815261445860208301613fec565b602082015261446960408301613fec565b604082015261447a60608301613fec565b606082015261448b60808301613fec565b608082015292915050565b803561400481613fd7565b600082601f8301126144b257600080fd5b813560206144c261406983613fb3565b82815260059290921b840181019181810190868411156144e157600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156145065760008081fd5b8189019150608080601f19848d030112156145215760008081fd5b614529613ecd565b878401358381111561453b5760008081fd5b6145498d8a8388010161404a565b825250604080850135848111156145605760008081fd5b61456e8e8b8389010161404a565b8a84015250606080860135858111156145875760008081fd5b6145958f8c838a010161404a565b92840192909252949092013593810193909352505083529183019183016144e5565b600061014082840312156145ca57600080fd5b6145d2613f19565b90506145de838361442c565b815260a082013567ffffffffffffffff808211156145fb57600080fd5b6146078583860161404a565b602084015260c084013591508082111561462057600080fd5b61462c8583860161404a565b604084015261463d60e08501614496565b6060840152610100840135608084015261012084013591508082111561466257600080fd5b5061466f848285016144a1565b60a08301525092915050565b600082601f83011261468c57600080fd5b8135602061469c61406983613fb3565b82815260059290921b840181019181810190868411156146bb57600080fd5b8286015b848110156120c557803567ffffffffffffffff8111156146df5760008081fd5b6146ed8986838b01016145b7565b8452509183019183016146bf565b600082601f83011261470c57600080fd5b8135602061471c61406983613fb3565b82815260059290921b8401810191818101908684111561473b57600080fd5b8286015b848110156120c557803567ffffffffffffffff8082111561475f57600080fd5b818901915089603f83011261477357600080fd5b8582013561478361406982613fb3565b81815260059190911b830160400190878101908c8311156147a357600080fd5b604085015b838110156147dc578035858111156147bf57600080fd5b6147ce8f6040838a010161404a565b8452509189019189016147a8565b5087525050509284019250830161473f565b600082601f8301126147ff57600080fd5b8135602061480f61406983613fb3565b8083825260208201915060208460051b87010193508684111561483157600080fd5b602086015b848110156120c55780358352918301918301614836565b600082601f83011261485e57600080fd5b8135602061486e61406983613fb3565b82815260059290921b8401810191818101908684111561488d57600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156148b25760008081fd5b818901915060a080601f19848d030112156148cd5760008081fd5b6148d5613ef6565b6148e0888501613fec565b8152604080850135848111156148f65760008081fd5b6149048e8b8389010161467b565b8a840152506060808601358581111561491d5760008081fd5b61492b8f8c838a01016146fb565b83850152506080915081860135858111156149465760008081fd5b6149548f8c838a01016147ee565b9184019190915250919093013590830152508352918301918301614891565b600080604080848603121561498757600080fd5b833567ffffffffffffffff8082111561499f57600080fd5b6149ab8783880161484d565b94506020915081860135818111156149c257600080fd5b8601601f810188136149d357600080fd5b80356149e161406982613fb3565b81815260059190911b8201840190848101908a831115614a0057600080fd5b8584015b83811015614a8c57803586811115614a1c5760008081fd5b8501603f81018d13614a2e5760008081fd5b87810135614a3e61406982613fb3565b81815260059190911b82018a0190898101908f831115614a5e5760008081fd5b928b01925b82841015614a7c5783358252928a0192908a0190614a63565b8652505050918601918601614a04565b50809750505050505050509250929050565b600060208284031215614ab057600080fd5b813567ffffffffffffffff811115614ac757600080fd5b820160a08185031215613dc957600080fd5b803563ffffffff8116811461400457600080fd5b600060a08284031215614aff57600080fd5b614b07613ef6565b8235614b1281613fd7565b8152614b2060208401614ad9565b6020820152614b3160408401614ad9565b6040820152614b4260608401614ad9565b60608201526080830135614b5581613fd7565b60808201529392505050565b803560ff8116811461400457600080fd5b600060208284031215614b8457600080fd5b610a7682614b61565b60008151808452602080850194506020840160005b83811015614bc75781516001600160a01b031687529582019590820190600101614ba2565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c2160e0840182614b8d565b90506040840151601f198483030160c0850152614c3e8282614b8d565b95945050505050565b60008060408385031215614c5a57600080fd5b614c6383613fec565b946020939093013593505050565b60008060208385031215614c8457600080fd5b823567ffffffffffffffff80821115614c9c57600080fd5b818501915085601f830112614cb057600080fd5b813581811115614cbf57600080fd5b8660208260061b8501011115614cd457600080fd5b60209290920196919550909350505050565b600060208284031215614cf857600080fd5b610a7682613fec565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136bd60a08401826141e3565b600080600060408486031215614d6457600080fd5b833567ffffffffffffffff80821115614d7c57600080fd5b614d88878388016145b7565b94506020860135915080821115614d9e57600080fd5b506143b486828701614275565b600060208284031215614dbd57600080fd5b8135613dc981613fd7565b600082601f830112614dd957600080fd5b81356020614de961406983613fb3565b8083825260208201915060208460051b870101935086841115614e0b57600080fd5b602086015b848110156120c5578035614e2381613fd7565b8352918301918301614e10565b60006020808385031215614e4357600080fd5b823567ffffffffffffffff80821115614e5b57600080fd5b818501915085601f830112614e6f57600080fd5b8135614e7d61406982613fb3565b81815260059190911b83018401908481019088831115614e9c57600080fd5b8585015b838110156141b257803585811115614eb757600080fd5b860160c0818c03601f19011215614ece5760008081fd5b614ed6613f19565b8882013581526040614ee9818401614b61565b8a8301526060614efa818501614b61565b8284015260809150614f0d828501614017565b9083015260a08381013589811115614f255760008081fd5b614f338f8d83880101614dc8565b838501525060c0840135915088821115614f4d5760008081fd5b614f5b8e8c84870101614dc8565b9083015250845250918601918601614ea0565b600060208284031215614f8057600080fd5b5035919050565b80356001600160e01b038116811461400457600080fd5b600082601f830112614faf57600080fd5b81356020614fbf61406983613fb3565b82815260069290921b84018101918181019086841115614fde57600080fd5b8286015b848110156120c55760408189031215614ffb5760008081fd5b615003613f3c565b61500c82613fec565b8152615019858301614f87565b81860152835291830191604001614fe2565b600082601f83011261503c57600080fd5b8135602061504c61406983613fb3565b82815260079290921b8401810191818101908684111561506b57600080fd5b8286015b848110156120c55780880360808112156150895760008081fd5b615091613f5f565b61509a83613fec565b8152604080601f19840112156150b05760008081fd5b6150b8613f3c565b92506150c5878501613fec565b83526150d2818501613fec565b838801528187019290925260608301359181019190915283529183019160800161506f565b6000602080838503121561510a57600080fd5b823567ffffffffffffffff8082111561512257600080fd5b8185019150604080838803121561513857600080fd5b615140613f3c565b83358381111561514f57600080fd5b84016040818a03121561516157600080fd5b615169613f3c565b81358581111561517857600080fd5b8201601f81018b1361518957600080fd5b803561519761406982613fb3565b81815260069190911b8201890190898101908d8311156151b657600080fd5b928a01925b828410156152065787848f0312156151d35760008081fd5b6151db613f3c565b84356151e681613fd7565b81526151f3858d01614f87565b818d0152825292870192908a01906151bb565b84525050508187013593508484111561521e57600080fd5b61522a8a858401614f9e565b818801528252508385013591508282111561524457600080fd5b6152508883860161502b565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b818110156152cf57835180516001600160a01b031684528501516001600160e01b0316858401529284019291850191600101615298565b50508583015187820388850152805180835290840192506000918401905b80831015615329578351805167ffffffffffffffff1683528501516001600160e01b0316858301529284019260019290920191908501906152ed565b50979650505050505050565b602081526000610a766020830184615278565b67ffffffffffffffff8316815260608101613dc96020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153b4576153b461537d565b5092915050565b6000602080835260608451604080848701526153da6060870183615278565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141b257845167ffffffffffffffff81511683528781015161543a89850182805167ffffffffffffffff908116835260209182015116910152565b508401518287015293860193600192909201916080909101906153fb565b60006020828403121561546a57600080fd5b813567ffffffffffffffff81111561548157600080fd5b6136bd8482850161484d565b81810381811115610a7957610a7961537d565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff808416806154d1576154d16154a0565b92169190910692915050565b8082028115828204841417610a7957610a7961537d565b60006040828403121561550657600080fd5b61550e613f3c565b61551783613fec565b8152602083013560208201528091505092915050565b600181811c9082168061554157607f821691505b60208210810361556157634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261559b60a08701826141e3565b9050606085015186820360608801526155b482826141e3565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561532957835180516001600160a01b03168352860151868301529285019260019290920191908401906155d7565b602081526000610a766020830184615567565b60808152600061562f6080830187615567565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561566d57600080fd5b835161567881614009565b602085015190935067ffffffffffffffff81111561569557600080fd5b8401601f810186136156a657600080fd5b80516156b461406982614022565b8181528760208385010111156156c957600080fd5b6156da8260208301602086016141bf565b809450505050604084015190509250925092565b60006020828403121561570057600080fd5b8151613dc981614009565b601f821115610cd8576000816000526020600020601f850160051c810160208610156157345750805b601f850160051c820191505b818110156124df57828155600101615740565b815167ffffffffffffffff81111561576d5761576d613eb7565b6157818161577b845461552d565b8461570b565b602080601f8311600181146157b6576000841561579e5750858301515b600019600386901b1c1916600185901b1785556124df565b600085815260208120601f198616915b828110156157e5578886015182559484019460019091019084016157c6565b50858210156158035787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546158658161552d565b8060a089015260c0600183166000811461588657600181146158a2576158d2565b60ff19841660c08b015260c083151560051b8b010194506158d2565b85600052602060002060005b848110156158c95781548c82018501529088019089016158ae565b8b0160c0019550505b50929998505050505050505050565b80820180821115610a7957610a7961537d565b60ff8181168382160190811115610a7957610a7961537d565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061594c5761594c6154a0565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261598d57600080fd5b83018035915067ffffffffffffffff8211156159a857600080fd5b60200191503681900382131561383057600080fd5b60208101600583106159d1576159d16143f4565b91905290565b60ff81811683821602908116908181146153b4576153b461537d565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a4b5784546001600160a01b031683526001948501949284019201615a26565b50508481036060860152865180825290820192508187019060005b81811015615a8b5782516001600160a01b031685529383019391830191600101615a66565b50505060ff851660808501525090506120c7565b600067ffffffffffffffff808616835280851660208401525060606040830152614c3e60608301846141e3565b8281526040602082015260006136bd60408301846141e3565b67ffffffffffffffff848116825283166020820152606081016136bd604083018461440a565b615b15818461440a565b6040602082015260006136bd60408301846141e3565b600060208284031215615b3d57600080fd5b8151613dc981613fd7565b6020815260008251610100806020850152615b676101208501836141e3565b91506020850151615b84604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615bbe60a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bdb84836141e3565b935060c08701519150808685030160e0870152615bf884836141e3565b935060e08701519150808685030183870152506120c783826141e3565b600060208284031215615c2757600080fd5b5051919050565b600060ff821660ff8103615c4457615c4461537d565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c760808301846141e3565b86815260c060208201526000615c9960c08301886141e3565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d6a57601f19868403018952815160808151818652615d16828701826141e3565b9150508582015185820387870152615d2e82826141e3565b91505060408083015186830382880152615d4883826141e3565b6060948501519790940196909652505098840198925090830190600101615cf0565b5090979650505050505050565b602081526000610a766020830184615cd3565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d6a57601f19868403018952615dc58383516141e3565b98840198925090830190600101615da9565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e3f6101808501836141e3565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e7c84836141e3565b935060608801519150615e9b6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615ec28282615cd3565b9150508281036020840152614c3e8185615d8a56fea164736f6c6343000818000a", + Bin: "0x6101206040523480156200001257600080fd5b5060405162006bbb38038062006bbb8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615ee562000cd6600039600081816102530152612c0c0152600081816102240152612ee60152600081816101f50152818161142f01526118400152600081816101c50152612801015260008181611dce0152611e1a0152615ee56000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063d2a15d351461053d578063e9d68a8e14610550578063ece670b61461057057600080fd5b8063991a5018116100bd578063991a5018146104c5578063c673e584146104d8578063ccd37ba3146104f857600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104815780637d4eef601461048957600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a3660046140a1565b6105cc565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d19190614210565b61018f6103313660046142bb565b6105e0565b61018f61034436600461436e565b6109c0565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143c2565b610a29565b6040516102d1919061441f565b6104246040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610a7f565b61018f610497366004614974565b610b3d565b61018f610177366004614a9f565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104d3366004614aee565b610cdd565b6104eb6104e6366004614b73565b610cee565b6040516102d19190614bd3565b61052f610506366004614c48565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f61054b366004614c72565b610e4c565b61056361055e366004614ce7565b610f06565b6040516102d19190614d02565b61018f61057e366004614d50565b611013565b61018f610591366004614dac565b611386565b61018f6105a4366004614e31565b611397565b6105bc6105b7366004614f6f565b6113d9565b60405190151581526020016102d1565b6105d461149a565b6105dd816114f6565b50565b60006105ee878901896150f8565b8051515190915015158061060757508051602001515115155b156107075760095460208a01359067ffffffffffffffff808316911610156106c6576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261068f929101615336565b600060405180830381600087803b1580156106a957600080fd5b505af11580156106bd573d6000803e3d6000fd5b50505050610705565b816020015151600003610705576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109095760008260200151828151811061072f5761072f615263565b6020026020010151905060008160000151905061074b816117f4565b6000610756826118f6565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061079a575060208084015190810151905167ffffffffffffffff9182169116115b156107e357825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107da929190600401615349565b60405180910390fd5b60408301518061081f576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108925783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016107da565b60208085015101516108a5906001615394565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff92831602179092559251166000908152600860209081526040808320948352939052919091204290555060010161070a565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161093991906153bc565b60405180910390a16109b560008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b925061195d915050565b505050505050505050565b610a006109cf82840184615459565b60408051600080825260208201909252906109fa565b60608152602001906001900390816109e55790505b50611cd4565b604080516000808252602082019092529050610a2360018585858586600061195d565b50505050565b6000610a376001600461548e565b6002610a446080856154b7565b67ffffffffffffffff16610a5891906154de565b610a628585611d84565b901c166003811115610a7657610a766143f5565b90505b92915050565b6001546001600160a01b03163314610ad95760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107da565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b45611dcb565b815181518114610b81576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ccd576000848281518110610ba057610ba0615263565b60200260200101519050600081602001515190506000858481518110610bc857610bc8615263565b6020026020010151905080518214610c0c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cbe576000828281518110610c2b57610c2b615263565b6020026020010151905080600014610cb55784602001518281518110610c5357610c53615263565b602002602001015160800151811015610cb55784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016107da565b50600101610c0f565b50505050806001019050610b84565b50610cd88383611cd4565b505050565b610ce561149a565b6105dd81611e4c565b610d316040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610dda57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dbc575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e1e575b5050505050815250509050919050565b610e5461149a565b60005b81811015610cd8576000838383818110610e7357610e73615263565b905060400201803603810190610e8991906154f5565b9050610e9881602001516113d9565b610efd57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e57565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191610f939061552e565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbf9061552e565b8015610e3c5780601f10610fe157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610fef57505050919092525091949350505050565b33301461104c576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611089565b60408051808201909152600080825260208201528152602001906001900390816110625790505b5060a085015151909150156110bd576110ba8460a00151856020015186606001518760000151602001518787611fb2565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff16818301528087015183516000948401926110f9929101614210565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015611206576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a19061117390859060040161560a565b600060405180830381600087803b15801561118d57600080fd5b505af192505050801561119e575060015b611206573d8080156111cc576040519150601f19603f3d011682016040523d82523d6000602084013e6111d1565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016107da9190614210565b60408601515115801561121b57506080860151155b80611232575060608601516001600160a01b03163b155b8061127257506060860151611270906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120d1565b155b1561127f57505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf97983926112f7928992611388929160040161561d565b6000604051808303816000875af1158015611316573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261133e9190810190615659565b50915091508161137c57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107da9190614210565b5050505050505050565b61138e61149a565b6105dd816120ed565b61139f61149a565b60005b81518110156113d5576113cd8282815181106113c0576113c0615263565b60200260200101516121a3565b6001016113a2565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611476573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7991906156ef565b6000546001600160a01b031633146114f45760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107da565b565b60005b81518110156113d557600082828151811061151657611516615263565b602002602001015190506000816020015190508067ffffffffffffffff1660000361156d576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611595576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115c09061552e565b80601f01602080910402602001604051908101604052809291908181526020018280546115ec9061552e565b80156116395780601f1061160e57610100808354040283529160200191611639565b820191906000526020600020905b81548152906001019060200180831161161c57829003601f168201915b5050505050905060008460600151905081516000036116f1578051600003611674576040516342bcdf7f60e11b815260040160405180910390fd5b600183016116828282615754565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611744565b8080519060200120828051906020012014611744576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016107da565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117dc908690615814565b60405180910390a250505050508060010190506114f9565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b391906156ef565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107da565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610a79576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107da565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906119bc8760a46158e2565b9050826060015115611a045784516119d59060206154de565b86516119e29060206154de565b6119ed9060a06158e2565b6119f791906158e2565b611a0190826158e2565b90505b368114611a46576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107da565b5081518114611a8e5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107da565b611a96611dcb565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611ae457611ae46143f5565b6002811115611af557611af56143f5565b9052509050600281602001516002811115611b1257611b126143f5565b148015611b665750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611b4e57611b4e615263565b6000918252602090912001546001600160a01b031633145b611b9c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611c7e576020820151611bb79060016158f5565b60ff16855114611bf3576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611c2e576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611c4092919061590e565b604051908190038120611c57918b9060200161591e565b604051602081830303815290604052805190602001209050611c7c8a828888886124e7565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d0e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611d7d57611d75858281518110611d4357611d43615263565b602002602001015184611d6f57858381518110611d6257611d62615263565b60200260200101516126f4565b836126f4565b600101611d25565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611da9608085615932565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f0000000000000000000000000000000000000000000000000000000000000000146114f4576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107da565b80516001600160a01b0316611e74576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fce57611fce613eb8565b60405190808252806020026020018201604052801561201357816020015b6040805180820190915260008082526020820152815260200190600190039081611fec5790505b50905060005b87518110156120c5576120a088828151811061203757612037615263565b602002602001015188888888888781811061205457612054615263565b90506020028101906120669190615959565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e8592505050565b8282815181106120b2576120b2615263565b6020908102919091010152600101612019565b505b9695505050505050565b60006120dc8361322a565b8015610a765750610a76838361328e565b336001600160a01b038216036121455760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107da565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ce576000604051631b3fab5160e11b81526004016107da91906159be565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223b57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612290565b6060840151600182015460ff6201000090910416151590151514612290576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016107da565b60a08401518051601f60ff821611156122bf576001604051631b3fab5160e11b81526004016107da91906159be565b612325858560030180548060200260200160405190810160405280929190818152602001828054801561231b57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122fd575b5050505050613349565b85606001511561245457612393858560020180548060200260200160405190810160405280929190818152602001828054801561231b576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122fd575050505050613349565b608086015180516123ad9060028701906020840190613e12565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f101561240d576002604051631b3fab5160e11b81526004016107da91906159be565b604088015161241d9060036159d8565b60ff168160ff1611612445576003604051631b3fab5160e11b81526004016107da91906159be565b612451878360016133b2565b50505b612460858360026133b2565b81516124759060038601906020850190613e12565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ce938a939260028b019291906159f4565b60405180910390a16124df85613532565b505050505050565b6124ef613e84565b835160005b8181101561137c57600060018886846020811061251357612513615263565b61252091901a601b6158f5565b89858151811061253257612532615263565b602002602001015189868151811061254c5761254c615263565b60200260200101516040516000815260200160405260405161258a949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156125ac573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561260d5761260d6143f5565b600281111561261e5761261e6143f5565b905250905060018160200151600281111561263b5761263b6143f5565b14612672576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061268957612689615263565b6020020151156126c5576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126e0576126e0615263565b9115156020909202015250506001016124f4565b81516126ff816117f4565b600061270a826118f6565b602085015151909150600081900361274d576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461278b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156127a6576127a6613eb8565b6040519080825280602002602001820160405280156127cf578160200160208202803683370190505b50905060005b82811015612944576000876020015182815181106127f5576127f5615263565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461288857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107da565b61291e8186600101805461289b9061552e565b80601f01602080910402602001604051908101604052809291908181526020018280546128c79061552e565b80156129145780601f106128e957610100808354040283529160200191612914565b820191906000526020600020905b8154815290600101906020018083116128f757829003601f168201915b505050505061354e565b83838151811061293057612930615263565b6020908102919091010152506001016127d5565b50600061295b858389606001518a60800151613670565b9050806000036129a3576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107da565b8551151560005b848110156109b5576000896020015182815181106129ca576129ca615263565b6020026020010151905060006129e889836000015160600151610a29565b905060008160038111156129fe576129fe6143f5565b1480612a1b57506003816003811115612a1957612a196143f5565b145b612a72578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612e7d565b8315612b4257600454600090600160a01b900463ffffffff16612a95874261548e565b1190508080612ab557506003826003811115612ab357612ab36143f5565b145b612af7576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b1660048201526024016107da565b8a8481518110612b0957612b09615263565b6020026020010151600014612b3c578a8481518110612b2a57612b2a615263565b60200260200101518360800181815250505b50612ba3565b6000816003811115612b5657612b566143f5565b14612ba3578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612a63565b81516080015167ffffffffffffffff1615612c91576000816003811115612bcc57612bcc6143f5565b03612c915781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c43928e929190600401615aa0565b6020604051808303816000875af1158015612c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8691906156ef565b612c91575050612e7d565b60008b604001518481518110612ca957612ca9615263565b6020026020010151905080518360a001515114612d0d578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d16600483015290911660248201526044016107da565b612d218a84600001516060015160016136c6565b600080612d2e858461376e565b91509150612d458c866000015160600151846136c6565b8615612db5576003826003811115612d5f57612d5f6143f5565b03612db5576000846003811115612d7857612d786143f5565b14612db5578451516040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526107da91908390600401615acd565b6002826003811115612dc957612dc96143f5565b14612e23576003826003811115612de257612de26143f5565b14612e23578451606001516040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526107da918e918590600401615ae6565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612e6f9087908790615b0c565b60405180910390a450505050505b6001016129aa565b60408051808201909152600080825260208201526000612ea88760200151613838565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f519190615b2c565b90506001600160a01b0381161580612f995750612f976001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120d1565b155b15612fdb576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016107da565b6004546000908190612ffd9089908690600160e01b900463ffffffff166138de565b9150915060008060006130ca6040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b81525060405160240161307b9190615b49565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a0c565b9250925092508261310957816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da9190614210565b81516020146131515781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b6000828060200190518101906131679190615c16565b9050866001600160a01b03168c6001600160a01b0316146131fc5760006131988d8a613193868a61548e565b6138de565b509050868110806131b25750816131af888361548e565b14155b156131fa576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016107da565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613256827f01ffc9a70000000000000000000000000000000000000000000000000000000061328e565b8015610a795750613287827fffffffff0000000000000000000000000000000000000000000000000000000061328e565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015613332575060208210155b801561333e5750600081115b979650505050505050565b60005b8151811015610cd85760ff83166000908152600360205260408120835190919084908490811061337e5761337e615263565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161334c565b60005b82518160ff161015610a23576000838260ff16815181106133d8576133d8615263565b60200260200101519050600060028111156133f5576133f56143f5565b60ff80871660009081526003602090815260408083206001600160a01b03871684529091529020546101009004166002811115613434576134346143f5565b14613455576004604051631b3fab5160e11b81526004016107da91906159be565b6001600160a01b038116613495576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134bb576134bb6143f5565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff191617610100836002811115613518576135186143f5565b0217905550905050508061352b90615c2f565b90506133b5565b60ff81166105dd576009805467ffffffffffffffff1916905550565b815160208082015160409283015192516000938493613594937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c4e565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135dd9794969395929491939101615c81565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136149190615d78565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061367e858585613b32565b9050613689816113d9565b6136975760009150506136be565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026136d56080856154b7565b67ffffffffffffffff166136e991906154de565b905060006136f78585611d84565b9050816137066001600461548e565b901b19168183600381111561371d5761371d6143f5565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161374c608088615932565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906137b29087908790600401615dd8565b600060405180830381600087803b1580156137cc57600080fd5b505af19250505080156137dd575060015b61381c573d80801561380b576040519150601f19603f3d011682016040523d82523d6000602084013e613810565b606091505b50600392509050613831565b50506040805160208101909152600081526002905b9250929050565b6000815160201461387757816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da9190614210565b60008280602001905181019061388d9190615c16565b90506001600160a01b038111806138a5575061040081105b15610a7957826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da9190614210565b60008060008060006139588860405160240161390991906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a0c565b9250925092508261399757816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da9190614210565b60208251146139df5781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b818060200190518101906139f39190615c16565b6139fd828861548e565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a2f57613a2f613eb8565b6040519080825280601f01601f191660200182016040528015613a59576020820181803683370190505b509150863b613a8c577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613abf577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613af8577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b1b5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b73576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b8757506101018111155b613ba4576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bce576040516309bde33960e01b815260040160405180910390fd5b80600003613bfb5786600081518110613be957613be9615263565b60200260200101519350505050613dca565b60008167ffffffffffffffff811115613c1657613c16613eb8565b604051908082528060200260200182016040528015613c3f578160200160208202803683370190505b50905060008080805b85811015613d695760006001821b8b811603613ca35788851015613c8c578c5160018601958e918110613c7d57613c7d615263565b60200260200101519050613cc5565b8551600185019487918110613c7d57613c7d615263565b8b5160018401938d918110613cba57613cba615263565b602002602001015190505b600089861015613cf5578d5160018701968f918110613ce657613ce6615263565b60200260200101519050613d17565b8651600186019588918110613d0c57613d0c615263565b602002602001015190505b82851115613d38576040516309bde33960e01b815260040160405180910390fd5b613d428282613dd1565b878481518110613d5457613d54615263565b60209081029190910101525050600101613c48565b506001850382148015613d7b57508683145b8015613d8657508581145b613da3576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613db857613db8615263565b60200260200101519750505050505050505b9392505050565b6000818310613de957613de48284613def565b610a76565b610a7683835b604080516001602082015290810183905260608101829052600090608001613652565b828054828255906000526020600020908101928215613e74579160200282015b82811115613e74578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e32565b50613e80929150613ea3565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e805760008155600101613ea4565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613ef157613ef1613eb8565b60405290565b60405160a0810167ffffffffffffffff81118282101715613ef157613ef1613eb8565b60405160c0810167ffffffffffffffff81118282101715613ef157613ef1613eb8565b6040805190810167ffffffffffffffff81118282101715613ef157613ef1613eb8565b6040516060810167ffffffffffffffff81118282101715613ef157613ef1613eb8565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fac57613fac613eb8565b604052919050565b600067ffffffffffffffff821115613fce57613fce613eb8565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461400557600080fd5b919050565b80151581146105dd57600080fd5b80356140058161400a565b600067ffffffffffffffff82111561403d5761403d613eb8565b50601f01601f191660200190565b600082601f83011261405c57600080fd5b813561406f61406a82614023565b613f83565b81815284602083860101111561408457600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140b457600080fd5b823567ffffffffffffffff808211156140cc57600080fd5b818501915085601f8301126140e057600080fd5b81356140ee61406a82613fb4565b81815260059190911b8301840190848101908883111561410d57600080fd5b8585015b838110156141b3578035858111156141295760008081fd5b86016080818c03601f19018113156141415760008081fd5b614149613ece565b8983013561415681613fd8565b81526040614165848201613fed565b8b8301526060808501356141788161400a565b8383015292840135928984111561419157600091508182fd5b61419f8f8d8688010161404b565b908301525085525050918601918601614111565b5098975050505050505050565b60005b838110156141db5781810151838201526020016141c3565b50506000910152565b600081518084526141fc8160208601602086016141c0565b601f01601f19169290920160200192915050565b602081526000610a7660208301846141e4565b8060608101831015610a7957600080fd5b60008083601f84011261424657600080fd5b50813567ffffffffffffffff81111561425e57600080fd5b60208301915083602082850101111561383157600080fd5b60008083601f84011261428857600080fd5b50813567ffffffffffffffff8111156142a057600080fd5b6020830191508360208260051b850101111561383157600080fd5b60008060008060008060008060e0898b0312156142d757600080fd5b6142e18a8a614223565b9750606089013567ffffffffffffffff808211156142fe57600080fd5b61430a8c838d01614234565b909950975060808b013591508082111561432357600080fd5b61432f8c838d01614276565b909750955060a08b013591508082111561434857600080fd5b506143558b828c01614276565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561438357600080fd5b61438d8585614223565b9250606084013567ffffffffffffffff8111156143a957600080fd5b6143b586828701614234565b9497909650939450505050565b600080604083850312156143d557600080fd5b6143de83613fed565b91506143ec60208401613fed565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061441b5761441b6143f5565b9052565b60208101610a79828461440b565b600060a0828403121561443f57600080fd5b614447613ef7565b90508135815261445960208301613fed565b602082015261446a60408301613fed565b604082015261447b60608301613fed565b606082015261448c60808301613fed565b608082015292915050565b803561400581613fd8565b600082601f8301126144b357600080fd5b813560206144c361406a83613fb4565b82815260059290921b840181019181810190868411156144e257600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156145075760008081fd5b8189019150608080601f19848d030112156145225760008081fd5b61452a613ece565b878401358381111561453c5760008081fd5b61454a8d8a8388010161404b565b825250604080850135848111156145615760008081fd5b61456f8e8b8389010161404b565b8a84015250606080860135858111156145885760008081fd5b6145968f8c838a010161404b565b92840192909252949092013593810193909352505083529183019183016144e6565b600061014082840312156145cb57600080fd5b6145d3613f1a565b90506145df838361442d565b815260a082013567ffffffffffffffff808211156145fc57600080fd5b6146088583860161404b565b602084015260c084013591508082111561462157600080fd5b61462d8583860161404b565b604084015261463e60e08501614497565b6060840152610100840135608084015261012084013591508082111561466357600080fd5b50614670848285016144a2565b60a08301525092915050565b600082601f83011261468d57600080fd5b8135602061469d61406a83613fb4565b82815260059290921b840181019181810190868411156146bc57600080fd5b8286015b848110156120c557803567ffffffffffffffff8111156146e05760008081fd5b6146ee8986838b01016145b8565b8452509183019183016146c0565b600082601f83011261470d57600080fd5b8135602061471d61406a83613fb4565b82815260059290921b8401810191818101908684111561473c57600080fd5b8286015b848110156120c557803567ffffffffffffffff8082111561476057600080fd5b818901915089603f83011261477457600080fd5b8582013561478461406a82613fb4565b81815260059190911b830160400190878101908c8311156147a457600080fd5b604085015b838110156147dd578035858111156147c057600080fd5b6147cf8f6040838a010161404b565b8452509189019189016147a9565b50875250505092840192508301614740565b600082601f83011261480057600080fd5b8135602061481061406a83613fb4565b8083825260208201915060208460051b87010193508684111561483257600080fd5b602086015b848110156120c55780358352918301918301614837565b600082601f83011261485f57600080fd5b8135602061486f61406a83613fb4565b82815260059290921b8401810191818101908684111561488e57600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156148b35760008081fd5b818901915060a080601f19848d030112156148ce5760008081fd5b6148d6613ef7565b6148e1888501613fed565b8152604080850135848111156148f75760008081fd5b6149058e8b8389010161467c565b8a840152506060808601358581111561491e5760008081fd5b61492c8f8c838a01016146fc565b83850152506080915081860135858111156149475760008081fd5b6149558f8c838a01016147ef565b9184019190915250919093013590830152508352918301918301614892565b600080604080848603121561498857600080fd5b833567ffffffffffffffff808211156149a057600080fd5b6149ac8783880161484e565b94506020915081860135818111156149c357600080fd5b8601601f810188136149d457600080fd5b80356149e261406a82613fb4565b81815260059190911b8201840190848101908a831115614a0157600080fd5b8584015b83811015614a8d57803586811115614a1d5760008081fd5b8501603f81018d13614a2f5760008081fd5b87810135614a3f61406a82613fb4565b81815260059190911b82018a0190898101908f831115614a5f5760008081fd5b928b01925b82841015614a7d5783358252928a0192908a0190614a64565b8652505050918601918601614a05565b50809750505050505050509250929050565b600060208284031215614ab157600080fd5b813567ffffffffffffffff811115614ac857600080fd5b820160a08185031215613dca57600080fd5b803563ffffffff8116811461400557600080fd5b600060a08284031215614b0057600080fd5b614b08613ef7565b8235614b1381613fd8565b8152614b2160208401614ada565b6020820152614b3260408401614ada565b6040820152614b4360608401614ada565b60608201526080830135614b5681613fd8565b60808201529392505050565b803560ff8116811461400557600080fd5b600060208284031215614b8557600080fd5b610a7682614b62565b60008151808452602080850194506020840160005b83811015614bc85781516001600160a01b031687529582019590820190600101614ba3565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c2260e0840182614b8e565b90506040840151601f198483030160c0850152614c3f8282614b8e565b95945050505050565b60008060408385031215614c5b57600080fd5b614c6483613fed565b946020939093013593505050565b60008060208385031215614c8557600080fd5b823567ffffffffffffffff80821115614c9d57600080fd5b818501915085601f830112614cb157600080fd5b813581811115614cc057600080fd5b8660208260061b8501011115614cd557600080fd5b60209290920196919550909350505050565b600060208284031215614cf957600080fd5b610a7682613fed565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136be60a08401826141e4565b600080600060408486031215614d6557600080fd5b833567ffffffffffffffff80821115614d7d57600080fd5b614d89878388016145b8565b94506020860135915080821115614d9f57600080fd5b506143b586828701614276565b600060208284031215614dbe57600080fd5b8135613dca81613fd8565b600082601f830112614dda57600080fd5b81356020614dea61406a83613fb4565b8083825260208201915060208460051b870101935086841115614e0c57600080fd5b602086015b848110156120c5578035614e2481613fd8565b8352918301918301614e11565b60006020808385031215614e4457600080fd5b823567ffffffffffffffff80821115614e5c57600080fd5b818501915085601f830112614e7057600080fd5b8135614e7e61406a82613fb4565b81815260059190911b83018401908481019088831115614e9d57600080fd5b8585015b838110156141b357803585811115614eb857600080fd5b860160c0818c03601f19011215614ecf5760008081fd5b614ed7613f1a565b8882013581526040614eea818401614b62565b8a8301526060614efb818501614b62565b8284015260809150614f0e828501614018565b9083015260a08381013589811115614f265760008081fd5b614f348f8d83880101614dc9565b838501525060c0840135915088821115614f4e5760008081fd5b614f5c8e8c84870101614dc9565b9083015250845250918601918601614ea1565b600060208284031215614f8157600080fd5b5035919050565b80356001600160e01b038116811461400557600080fd5b600082601f830112614fb057600080fd5b81356020614fc061406a83613fb4565b82815260069290921b84018101918181019086841115614fdf57600080fd5b8286015b848110156120c55760408189031215614ffc5760008081fd5b615004613f3d565b61500d82613fed565b815261501a858301614f88565b81860152835291830191604001614fe3565b600082601f83011261503d57600080fd5b8135602061504d61406a83613fb4565b82815260079290921b8401810191818101908684111561506c57600080fd5b8286015b848110156120c557808803608081121561508a5760008081fd5b615092613f60565b61509b83613fed565b8152604080601f19840112156150b15760008081fd5b6150b9613f3d565b92506150c6878501613fed565b83526150d3818501613fed565b8388015281870192909252606083013591810191909152835291830191608001615070565b6000602080838503121561510b57600080fd5b823567ffffffffffffffff8082111561512357600080fd5b8185019150604080838803121561513957600080fd5b615141613f3d565b83358381111561515057600080fd5b84016040818a03121561516257600080fd5b61516a613f3d565b81358581111561517957600080fd5b8201601f81018b1361518a57600080fd5b803561519861406a82613fb4565b81815260069190911b8201890190898101908d8311156151b757600080fd5b928a01925b828410156152075787848f0312156151d45760008081fd5b6151dc613f3d565b84356151e781613fd8565b81526151f4858d01614f88565b818d0152825292870192908a01906151bc565b84525050508187013593508484111561521f57600080fd5b61522b8a858401614f9f565b818801528252508385013591508282111561524557600080fd5b6152518883860161502c565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b818110156152d057835180516001600160a01b031684528501516001600160e01b0316858401529284019291850191600101615299565b50508583015187820388850152805180835290840192506000918401905b8083101561532a578351805167ffffffffffffffff1683528501516001600160e01b0316858301529284019260019290920191908501906152ee565b50979650505050505050565b602081526000610a766020830184615279565b67ffffffffffffffff8316815260608101613dca6020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153b5576153b561537e565b5092915050565b6000602080835260608451604080848701526153db6060870183615279565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141b357845167ffffffffffffffff81511683528781015161543b89850182805167ffffffffffffffff908116835260209182015116910152565b508401518287015293860193600192909201916080909101906153fc565b60006020828403121561546b57600080fd5b813567ffffffffffffffff81111561548257600080fd5b6136be8482850161484e565b81810381811115610a7957610a7961537e565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff808416806154d2576154d26154a1565b92169190910692915050565b8082028115828204841417610a7957610a7961537e565b60006040828403121561550757600080fd5b61550f613f3d565b61551883613fed565b8152602083013560208201528091505092915050565b600181811c9082168061554257607f821691505b60208210810361556257634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261559c60a08701826141e4565b9050606085015186820360608801526155b582826141e4565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561532a57835180516001600160a01b03168352860151868301529285019260019290920191908401906155d8565b602081526000610a766020830184615568565b6080815260006156306080830187615568565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561566e57600080fd5b83516156798161400a565b602085015190935067ffffffffffffffff81111561569657600080fd5b8401601f810186136156a757600080fd5b80516156b561406a82614023565b8181528760208385010111156156ca57600080fd5b6156db8260208301602086016141c0565b809450505050604084015190509250925092565b60006020828403121561570157600080fd5b8151613dca8161400a565b601f821115610cd8576000816000526020600020601f850160051c810160208610156157355750805b601f850160051c820191505b818110156124df57828155600101615741565b815167ffffffffffffffff81111561576e5761576e613eb8565b6157828161577c845461552e565b8461570c565b602080601f8311600181146157b7576000841561579f5750858301515b600019600386901b1c1916600185901b1785556124df565b600085815260208120601f198616915b828110156157e6578886015182559484019460019091019084016157c7565b50858210156158045787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546158668161552e565b8060a089015260c0600183166000811461588757600181146158a3576158d3565b60ff19841660c08b015260c083151560051b8b010194506158d3565b85600052602060002060005b848110156158ca5781548c82018501529088019089016158af565b8b0160c0019550505b50929998505050505050505050565b80820180821115610a7957610a7961537e565b60ff8181168382160190811115610a7957610a7961537e565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061594d5761594d6154a1565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261598e57600080fd5b83018035915067ffffffffffffffff8211156159a957600080fd5b60200191503681900382131561383157600080fd5b60208101600583106159d2576159d26143f5565b91905290565b60ff81811683821602908116908181146153b5576153b561537e565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a4c5784546001600160a01b031683526001948501949284019201615a27565b50508481036060860152865180825290820192508187019060005b81811015615a8c5782516001600160a01b031685529383019391830191600101615a67565b50505060ff851660808501525090506120c7565b600067ffffffffffffffff808616835280851660208401525060606040830152614c3f60608301846141e4565b8281526040602082015260006136be60408301846141e4565b67ffffffffffffffff848116825283166020820152606081016136be604083018461440b565b615b16818461440b565b6040602082015260006136be60408301846141e4565b600060208284031215615b3e57600080fd5b8151613dca81613fd8565b6020815260008251610100806020850152615b686101208501836141e4565b91506020850151615b85604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615bbf60a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bdc84836141e4565b935060c08701519150808685030160e0870152615bf984836141e4565b935060e08701519150808685030183870152506120c783826141e4565b600060208284031215615c2857600080fd5b5051919050565b600060ff821660ff8103615c4557615c4561537e565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c760808301846141e4565b86815260c060208201526000615c9a60c08301886141e4565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d6b57601f19868403018952815160808151818652615d17828701826141e4565b9150508582015185820387870152615d2f82826141e4565b91505060408083015186830382880152615d4983826141e4565b6060948501519790940196909652505098840198925090830190600101615cf1565b5090979650505050505050565b602081526000610a766020830184615cd4565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d6b57601f19868403018952615dc68383516141e4565b98840198925090830190600101615daa565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e406101808501836141e4565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e7d84836141e4565b935060608801519150615e9c6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615ec38282615cd4565b9150508281036020840152614c3f8185615d8b56fea164736f6c6343000818000a", } var EVM2EVMMultiOffRampABI = EVM2EVMMultiOffRampMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go index 704d95cf96..d1bfc5b47a 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go @@ -110,7 +110,7 @@ type RateLimiterTokenBucket struct { var EVM2EVMOffRampMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"DestinationGasAmountCountMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumOCR2BaseNoChecks.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"oldLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"tokenIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"oldLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenGasOverride\",\"type\":\"uint256\"}],\"name\":\"InvalidTokenGasOverride\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receiverExecutionGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"internalType\":\"structEVM2EVMOffRamp.GasLimitOverride[]\",\"name\":\"gasLimitOverrides\",\"type\":\"tuple[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destToken\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.RateLimitToken[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101a06040523480156200001257600080fd5b5060405162006609380380620066098339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f40620006c9600039600081816102ec01528181611c6a01526133920152600081816102bd01528181611c420152611f2701526000818161028e01528181610d8d01528181610df201528181611c18015281816124a4015261250e015260006120c601526000818161025f0152611bee0152600081816101ff0152611b9201526000818161022f01528181611bc601528181611ee40152818161303b01526134bf0152600081816101d001528181611b6d01526121ac015260008181611e3e0152611e8a0152615f406000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806385572ffb116100d8578063afcb95d71161008c578063c92b283211610066578063c92b2832146105f3578063f077b59214610606578063f2fde38b1461061c57600080fd5b8063afcb95d7146105ad578063b1dc65a4146105cd578063b6113fce146105e057600080fd5b8063873504d7116100bd578063873504d7146105765780638926c4ee146105895780638da5cb5b1461059c57600080fd5b806385572ffb1461053c578063856c82471461054a57600080fd5b8063599f64311161013a5780637437ff9f116101145780637437ff9f1461046157806379ba50971461050457806381ff70481461050c57600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516103299190614311565b60405180910390f35b6103456103403660046143a7565b61062f565b6040516103299190614407565b61038e6040518060400160405280601481526020017f45564d3245564d4f666652616d7020312e352e3000000000000000000000000081525081565b6040516103299190614465565b6103ae6103a936600461468e565b6106aa565b005b6103b8610a9e565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610b53565b60405161032991906147a0565b6103ae61045c3660046147b3565b610bb5565b6104f76040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a01000000000000000000009091046001600160a01b039081166060830152600b5416608082015290565b60405161032991906147d0565b6103ae610c7e565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae610182366004614826565b61055d6105583660046147b3565b610d61565b60405167ffffffffffffffff9091168152602001610329565b6103ae6105843660046148f2565b610e64565b6103ae610597366004614e1d565b611037565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae6105db366004614f74565b61129c565b6103ae6105ee366004615059565b6114a7565b6103ae610601366004615110565b6117e7565b61060e611852565b60405161032992919061517e565b6103ae61062a3660046147b3565b611978565b600061063d600160046151d2565b600261064a608085615214565b67ffffffffffffffff1661065e919061523b565b6010600061066d608087615252565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106a4576106a46143c4565b92915050565b84518460ff16601f8211156106f75760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190615279565b60405180910390fd5b806000036107345760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190615279565b61073c611989565b610745856119ff565b60095460005b818110156107bc57600860006009838154811061076a5761076a615293565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161074b565b5050865160005b8181101561095f5760008982815181106107df576107df615293565b60200260200101519050600060028111156107fc576107fc6143c4565b6001600160a01b038216600090815260086020526040902054610100900460ff16600281111561082e5761082e6143c4565b146108685760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee9190615279565b6001600160a01b0381166108a8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561094b5761094b6143c4565b0217905550905050508060010190506107c3565b5087516109739060099060208b019061427f565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a1617179055600780546109f99146913091906000906109cb9063ffffffff166152c2565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611cc9565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610a8a9487949293918316921691909117908f908f908f908f908f908f906152e5565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610b4e90611d56565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bab57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8d575b5050505050905090565b6000546001600160a01b03163314801590610bdb57506002546001600160a01b03163314155b15610c12576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b6001546001600160a01b03163314610cf2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106ee565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106a4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106a4576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5d919061537b565b9392505050565b610e6c611989565b60005b8251811015610f3f57610ea9838281518110610e8d57610e8d615293565b602002602001015160200151600c611e0890919063ffffffff16565b15610f37577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d58782838281518110610ee157610ee1615293565b602002602001015160000151848381518110610eff57610eff615293565b602002602001015160200151604051610f2e9291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610e6f565b5060005b815181101561103257610f9c828281518110610f6157610f61615293565b602002602001015160200151838381518110610f7f57610f7f615293565b602002602001015160000151600c611e1d9092919063ffffffff16565b1561102a577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a828281518110610fd457610fd4615293565b602002602001015160000151838381518110610ff257610ff2615293565b6020026020010151602001516040516110219291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610f43565b505050565b61103f611e3b565b8151518151811461107c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156112915760008460000151828151811061109f5761109f615293565b6020026020010151905060008483815181106110bd576110bd615293565b60209081029190910101518051909150801561112c57826080015181101561112c5761018083015160808401516040517f9c6db58d00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016106ee565b816020015151836101400151511461118e5761018083015160608401516040517f85d2e5bf000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff1660248201526044016106ee565b61016083015160005b846101400151518110156112815760008287815181106111b9576111b9615293565b60200260200101518060200190518101906111d491906153dd565b90506000856020015183815181106111ee576111ee615293565b602002602001015163ffffffff169050806000141580156112185750816060015163ffffffff1681105b156112775761018087015160608301516040517fef0c635200000000000000000000000000000000000000000000000000000000815260048101929092526024820185905263ffffffff166044820152606481018290526084016106ee565b5050600101611197565b505050505080600101905061107f565b506110328383611ebc565b6112a6878761290f565b6005548835908082146112ef576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016106ee565b6112f7611e3b565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561137f5761137f6143c4565b6002811115611390576113906143c4565b90525090506002816020015160028111156113ad576113ad6143c4565b1480156113e757506009816000015160ff16815481106113cf576113cf615293565b6000918252602090912001546001600160a01b031633145b61141d576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061142b85602061523b565b61143688602061523b565b6114428b6101446154a9565b61144c91906154a9565b61145691906154a9565b905036811461149a576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016106ee565b5050505050505050505050565b3330146114e0576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516000808252602082019092528161151d565b60408051808201909152600080825260208201528152602001906001900390816114f65790505b50905060006115306101408701876154bc565b905011156115a7576115a46115496101408701876154bc565b6115596040890160208a016147b3565b604080516001600160a01b0390921660208301520160408051601f1981840301815291815261158e9060608b01908b016147b3565b61159c6101608b018b615524565b8a8a8a612966565b90505b6115b561012086018661558c565b15905080156115c657506080850135155b806115e857506115dc60608601604087016147b3565b6001600160a01b03163b155b8061163357506116317f85572ffb0000000000000000000000000000000000000000000000000000000061162260608801604089016147b3565b6001600160a01b031690612b8f565b155b1561163e57506117e1565b600a546040805160a08101909152610180870135815260009182916a01000000000000000000009091046001600160a01b031690633cf979839060208082019061168a908c018c6143a7565b67ffffffffffffffff1681526020018a60200160208101906116ac91906147b3565b604080516001600160a01b0390921660208301520160408051601f1981840301815291905281526020016116e46101208c018c61558c565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200186905261138860808b013561173960608d0160408e016147b3565b6040518563ffffffff1660e01b81526004016117589493929190615636565b6000604051808303816000875af1158015611777573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261179f91908101906156fb565b5091509150816117dd57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b5050505b50505050565b6000546001600160a01b0316331480159061180d57506002546001600160a01b03163314155b15611844576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61184f600382612bab565b50565b6060806000611861600c612d90565b90508067ffffffffffffffff81111561187c5761187c614478565b6040519080825280602002602001820160405280156118a5578160200160208202803683370190505b5092508067ffffffffffffffff8111156118c1576118c1614478565b6040519080825280602002602001820160405280156118ea578160200160208202803683370190505b50915060005b8181101561197257600080611906600c84612d9b565b915091508086848151811061191d5761191d615293565b60200260200101906001600160a01b031690816001600160a01b0316815250508185848151811061195057611950615293565b6001600160a01b039092166020928302919091019091015250506001016118f0565b50509091565b611980611989565b61184f81612db9565b6000546001600160a01b031633146119fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106ee565b565b600081806020019051810190611a159190615755565b60608101519091506001600160a01b0316611a5c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a01000000000000000000006001600160a01b039485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611cbd9184906157f4565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611ced999897969594939291906158b6565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611de482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611dc891906151d2565b85608001516fffffffffffffffffffffffffffffffff16612e94565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6000610e5d836001600160a01b038416612ebc565b6000611e33846001600160a01b03851684612ec8565b949350505050565b467f0000000000000000000000000000000000000000000000000000000000000000146119fd576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016106ee565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611f76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9a919061593e565b15611fd1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815151600081900361200e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015151811461204c576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561206757612067614478565b604051908082528060200260200182016040528015612090578160200160208202803683370190505b50905060005b82811015612168576000856000015182815181106120b6576120b6615293565b602002602001015190506120ea817f0000000000000000000000000000000000000000000000000000000000000000612ede565b8383815181106120fc576120fc615293565b60200260200101818152505080610180015183838151811061212057612120615293565b60200260200101511461215f576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101612096565b508251604080860151606087015191517f32048875000000000000000000000000000000000000000000000000000000008152921515926000926001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926332048875926121e29288929160040161598c565b602060405180830381865afa1580156121ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222391906159c2565b90508060000361225f576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b848110156117dd5760008760000151828151811061228257612282615293565b60200260200101519050600061229b826060015161062f565b905060008160038111156122b1576122b16143c4565b14806122ce575060038160038111156122cc576122cc6143c4565b145b61231457816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a25050612907565b606085156123fa5788848151811061232e5761232e615293565b6020908102919091018101510151600a5490915060009063ffffffff1661235587426151d2565b119050808061237557506003836003811115612373576123736143c4565b145b6123ab576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8985815181106123bd576123bd615293565b6020026020010151600001516000146123f4578985815181106123e2576123e2615293565b60209081029190910101515160808501525b5061245e565b600082600381111561240e5761240e6143c4565b1461245e57606083015160405167ffffffffffffffff90911681527f67d9ba0f63d427c482c2736300e6d5a34c6691dbcdea8ad35828a1f1ba47e8729060200160405180910390a1505050612907565b60c083015167ffffffffffffffff16156126df576020808401516001600160a01b03166000908152600f909152604081205467ffffffffffffffff1690819003612649577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156126495760208401516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa158015612557573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257b919061537b565b60c085015190915067ffffffffffffffff166125988260016159db565b67ffffffffffffffff16146125f95783602001516001600160a01b03168460c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a350505050612907565b6020848101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b600083600381111561265d5761265d6143c4565b036126dd5760c084015167ffffffffffffffff1661267c8260016159db565b67ffffffffffffffff16146126dd5783602001516001600160a01b03168460c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a350505050612907565b505b60008a6020015185815181106126f7576126f7615293565b602002602001015190506127238460600151856000015186610140015151876101200151518551613039565b612732846060015160016131ba565b600080612740868486613264565b915091506127528660600151836131ba565b88156127be57600382600381111561276c5761276c6143c4565b036127be576000856003811115612785576127856143c4565b146127be57806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b60028260038111156127d2576127d26143c4565b1461282a5760038260038111156127eb576127eb6143c4565b1461282a578560600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016106ee9291906159fc565b60c086015167ffffffffffffffff16156128b2576000856003811115612852576128526143c4565b036128b2576020808701516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff169161288a83615a1a565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b856101800151866060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef6584846040516128f8929190615a37565b60405180910390a35050505050505b600101612262565b61296261291e82840184615a57565b604080516000808252602082019092529061295c565b6040805180820190915260008152606060208201528152602001906001900390816129345790505b50611ebc565b5050565b60608989808060200260200160405190810160405280939291908181526020016000905b828210156129b6576129a760408302860136819003810190615a8c565b8152602001906001019061298a565b505050505090506000805b8a811015612b715760008888838181106129dd576129dd615293565b90506020028101906129ef919061558c565b8101906129fc9190615aa8565b90508451600014612a5757848281518110612a1957612a19615293565b602002602001015163ffffffff16600014612a5757848281518110612a4057612a40615293565b602090810291909101015163ffffffff1660608201525b612ad78d8d84818110612a6c57612a6c615293565b905060400201602001358c8c848b8b88818110612a8b57612a8b615293565b9050602002810190612a9d919061558c565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061333192505050565b848381518110612ae957612ae9615293565b6020026020010181905250612b25848381518110612b0957612b09615293565b602002602001015160000151600c6136fd90919063ffffffff16565b15612b6857612b5b848381518110612b3f57612b3f615293565b6020908102919091010151600b546001600160a01b0316613712565b612b6590846154a9565b92505b506001016129c1565b508015612b8157612b8181613833565b509998505050505050505050565b6000612b9a83613840565b8015610e5d5750610e5d83836138a4565b8154600090612bd490700100000000000000000000000000000000900463ffffffff16426151d2565b90508015612c765760018301548354612c1c916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e94565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c9c916fffffffffffffffffffffffffffffffff9081169116613973565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612d839084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106a482613989565b6000808080612daa8686613994565b909450925050505b9250929050565b336001600160a01b03821603612e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106ee565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612eb385612ea4848661523b565b612eae90876154a9565b613973565b95945050505050565b6000610e5d83836139a3565b6000611e3384846001600160a01b0385166139c0565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612f749897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612fad9190615b64565b60405160208183030381529060405280519060200120876101600151604051602001612fd99190615bd1565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff16146130b2576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016106ee565b600a5468010000000000000000900461ffff1683111561310a576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b80831461314f576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b600a54640100000000900463ffffffff168211156131b357600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff166004820152602481018390526044016106ee565b5050505050565b600060026131c9608085615214565b67ffffffffffffffff166131dd919061523b565b905060006010816131ef608087615252565b67ffffffffffffffff168152602081019190915260400160002054905081613219600160046151d2565b901b191681836003811115613230576132306143c4565b901b178060106000613243608088615252565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517fb6113fce000000000000000000000000000000000000000000000000000000008152600090606090309063b6113fce906132aa90889088908890600401615c1b565b600060405180830381600087803b1580156132c457600080fd5b505af19250505080156132d5575060015b613314573d808015613303576040519150601f19603f3d011682016040523d82523d6000602084013e613308565b606091505b50600392509050613329565b50506040805160208101909152600081526002905b935093915050565b6040805180820190915260008082526020820152600061335484602001516139dd565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa1580156133d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fd9190615da4565b90506001600160a01b038116158061344557506134436001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612b8f565b155b15613487576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016106ee565b60008061349f8885896060015163ffffffff16613a83565b91509150600080600061359d6040518061010001604052808e81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018d6001600160a01b031681526020018f8152602001896001600160a01b031681526020018c6000015181526020018c6040015181526020018b8152506040516024016135399190615dc1565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613bc6565b925092509250826135dc57816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b81516020146136245781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b60008280602001905181019061363a91906159c2565b9050866001600160a01b03168c6001600160a01b0316146136cf57600061366b8d8a613666868a6151d2565b613a83565b5090508681108061368557508161368288836151d2565b14155b156136cd576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016106ee565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000610e5d836001600160a01b038416613cec565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613778573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379c9190615e8e565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036138055783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016106ee565b6020840151611e33907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690613cf8565b61184f6003826000613d35565b600061386c827f01ffc9a7000000000000000000000000000000000000000000000000000000006138a4565b80156106a4575061389d827fffffffff000000000000000000000000000000000000000000000000000000006138a4565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561395c575060208210155b80156139685750600081115b979650505050505050565b60008183106139825781610e5d565b5090919050565b60006106a482614084565b6000808080612daa868661408f565b60008181526002830160205260408120819055610e5d83836140ba565b60008281526002840160205260408120829055611e3384846140c6565b60008151602014613a1c57816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b600082806020019051810190613a3291906159c2565b90506001600160a01b03811180613a4a575061040081105b156106a457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b6000806000806000613b1288604051602401613aae91906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613bc6565b92509250925082613b5157816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190614465565b6020825114613b995781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b81806020019051810190613bad91906159c2565b613bb782886151d2565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613be957613be9614478565b6040519080825280601f01601f191660200182016040528015613c13576020820181803683370190505b509150863b613c46577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613c79577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613cb2577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613cd55750835b808352806000602085013e50955095509592505050565b6000610e5d83836140d2565b6000670de0b6b3a7640000613d2b837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff861661523b565b610e5d9190615ef0565b825474010000000000000000000000000000000000000000900460ff161580613d5c575081155b15613d6657505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090613dac90700100000000000000000000000000000000900463ffffffff16426151d2565b90508015613e6c5781831115613dee576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613e289083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e94565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613f09576001600160a01b038416613ebe576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106ee565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b03851660448201526064016106ee565b848310156140025760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613f4d90826151d2565b613f57878a6151d2565b613f6191906154a9565b613f6b9190615ef0565b90506001600160a01b038616613fb7576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106ee565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b03871660448201526064016106ee565b61400c85846151d2565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60006106a4826140de565b6000808061409d85856140e8565b600081815260029690960160205260409095205494959350505050565b6000610e5d83836140f4565b6000610e5d83836141ee565b6000610e5d838361423d565b60006106a4825490565b6000610e5d8383614255565b600081815260018301602052604081205480156141dd5760006141186001836151d2565b855490915060009061412c906001906151d2565b905081811461419157600086600001828154811061414c5761414c615293565b906000526020600020015490508087600001848154811061416f5761416f615293565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806141a2576141a2615f04565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106a4565b60009150506106a4565b5092915050565b6000818152600183016020526040812054614235575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106a4565b5060006106a4565b60008181526001830160205260408120541515610e5d565b600082600001828154811061426c5761426c615293565b9060005260206000200154905092915050565b8280548282559060005260206000209081019282156142ec579160200282015b828111156142ec57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0390911617825560209092019160019091019061429f565b506142f89291506142fc565b5090565b5b808211156142f857600081556001016142fd565b60e081016106a482846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff8116811461184f57600080fd5b80356143a281614381565b919050565b6000602082840312156143b957600080fd5b8135610e5d81614381565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110614403576144036143c4565b9052565b602081016106a482846143f3565b60005b83811015614430578181015183820152602001614418565b50506000910152565b60008151808452614451816020860160208601614415565b601f01601f19169290920160200192915050565b602081526000610e5d6020830184614439565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156144ca576144ca614478565b60405290565b6040516080810167ffffffffffffffff811182821017156144ca576144ca614478565b6040516101a0810167ffffffffffffffff811182821017156144ca576144ca614478565b604051601f8201601f1916810167ffffffffffffffff8111828210171561454057614540614478565b604052919050565b600067ffffffffffffffff82111561456257614562614478565b5060051b60200190565b6001600160a01b038116811461184f57600080fd5b80356143a28161456c565b600082601f83011261459d57600080fd5b813560206145b26145ad83614548565b614517565b8083825260208201915060208460051b8701019350868411156145d457600080fd5b602086015b848110156145f95780356145ec8161456c565b83529183019183016145d9565b509695505050505050565b803560ff811681146143a257600080fd5b600067ffffffffffffffff82111561462f5761462f614478565b50601f01601f191660200190565b600082601f83011261464e57600080fd5b813561465c6145ad82614615565b81815284602083860101111561467157600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156146a757600080fd5b863567ffffffffffffffff808211156146bf57600080fd5b6146cb8a838b0161458c565b975060208901359150808211156146e157600080fd5b6146ed8a838b0161458c565b96506146fb60408a01614604565b9550606089013591508082111561471157600080fd5b61471d8a838b0161463d565b945061472b60808a01614397565b935060a089013591508082111561474157600080fd5b5061474e89828a0161463d565b9150509295509295509295565b60008151808452602080850194506020840160005b838110156147955781516001600160a01b031687529582019590820190600101614770565b509495945050505050565b602081526000610e5d602083018461475b565b6000602082840312156147c557600080fd5b8135610e5d8161456c565b60a081016106a4828463ffffffff8082511683528060208301511660208401525061ffff604082015116604083015260608101516001600160a01b03808216606085015280608084015116608085015250505050565b60006020828403121561483857600080fd5b813567ffffffffffffffff81111561484f57600080fd5b820160a08185031215610e5d57600080fd5b600082601f83011261487257600080fd5b813560206148826145ad83614548565b82815260069290921b840181019181810190868411156148a157600080fd5b8286015b848110156145f957604081890312156148be5760008081fd5b6148c66144a7565b81356148d18161456c565b8152818501356148e08161456c565b818601528352918301916040016148a5565b6000806040838503121561490557600080fd5b823567ffffffffffffffff8082111561491d57600080fd5b61492986838701614861565b9350602085013591508082111561493f57600080fd5b5061494c85828601614861565b9150509250929050565b801515811461184f57600080fd5b80356143a281614956565b60006040828403121561498157600080fd5b6149896144a7565b905081356149968161456c565b808252506020820135602082015292915050565b600082601f8301126149bb57600080fd5b813560206149cb6145ad83614548565b8083825260208201915060208460061b8701019350868411156149ed57600080fd5b602086015b848110156145f957614a04888261496f565b8352918301916040016149f2565b600082601f830112614a2357600080fd5b81356020614a336145ad83614548565b82815260059290921b84018101918181019086841115614a5257600080fd5b8286015b848110156145f957803567ffffffffffffffff811115614a765760008081fd5b614a848986838b010161463d565b845250918301918301614a56565b600082601f830112614aa357600080fd5b81356020614ab36145ad83614548565b82815260059290921b84018101918181019086841115614ad257600080fd5b8286015b848110156145f957803567ffffffffffffffff811115614af65760008081fd5b614b048986838b0101614a12565b845250918301918301614ad6565b600082601f830112614b2357600080fd5b81356020614b336145ad83614548565b8083825260208201915060208460051b870101935086841115614b5557600080fd5b602086015b848110156145f95780358352918301918301614b5a565b600060808284031215614b8357600080fd5b614b8b6144d0565b9050813567ffffffffffffffff80821115614ba557600080fd5b818401915084601f830112614bb957600080fd5b81356020614bc96145ad83614548565b82815260059290921b84018101918181019088841115614be857600080fd5b8286015b84811015614d4457803586811115614c0357600080fd5b87016101a0818c03601f19011215614c1a57600080fd5b614c226144f3565b614c2d868301614397565b8152614c3b60408301614581565b86820152614c4b60608301614581565b6040820152614c5c60808301614397565b606082015260a08201356080820152614c7760c08301614964565b60a0820152614c8860e08301614397565b60c0820152610100614c9b818401614581565b60e083015261012080840135828401526101409150818401358a811115614cc157600080fd5b614ccf8f8a8388010161463d565b828501525050610160808401358a811115614ce957600080fd5b614cf78f8a838801016149aa565b83850152506101809150818401358a811115614d1257600080fd5b614d208f8a83880101614a12565b91840191909152506101a09290920135918101919091528352918301918301614bec565b5086525085810135935082841115614d5b57600080fd5b614d6787858801614a92565b90850152506040840135915080821115614d8057600080fd5b50614d8d84828501614b12565b6040830152506060820135606082015292915050565b63ffffffff8116811461184f57600080fd5b600082601f830112614dc657600080fd5b81356020614dd66145ad83614548565b8083825260208201915060208460051b870101935086841115614df857600080fd5b602086015b848110156145f9578035614e1081614da3565b8352918301918301614dfd565b6000806040808486031215614e3157600080fd5b833567ffffffffffffffff80821115614e4957600080fd5b614e5587838801614b71565b9450602091508186013581811115614e6c57600080fd5b8601601f81018813614e7d57600080fd5b8035614e8b6145ad82614548565b81815260059190911b8201840190848101908a831115614eaa57600080fd5b8584015b83811015614f1d57803586811115614ec65760008081fd5b8501808d03601f1901891315614edc5760008081fd5b614ee46144a7565b8882013581528982013588811115614efc5760008081fd5b614f0a8f8b83860101614db5565b828b015250845250918601918601614eae565b50809750505050505050509250929050565b60008083601f840112614f4157600080fd5b50813567ffffffffffffffff811115614f5957600080fd5b6020830191508360208260051b8501011115612db257600080fd5b60008060008060008060008060e0898b031215614f9057600080fd5b606089018a811115614fa157600080fd5b8998503567ffffffffffffffff80821115614fbb57600080fd5b818b0191508b601f830112614fcf57600080fd5b813581811115614fde57600080fd5b8c6020828501011115614ff057600080fd5b6020830199508098505060808b013591508082111561500e57600080fd5b61501a8c838d01614f2f565b909750955060a08b013591508082111561503357600080fd5b506150408b828c01614f2f565b999c989b50969995989497949560c00135949350505050565b6000806000806060858703121561506f57600080fd5b843567ffffffffffffffff8082111561508757600080fd5b908601906101a0828903121561509c57600080fd5b909450602086013590808211156150b257600080fd5b6150be88838901614f2f565b909550935060408701359150808211156150d757600080fd5b506150e487828801614db5565b91505092959194509250565b80356fffffffffffffffffffffffffffffffff811681146143a257600080fd5b60006060828403121561512257600080fd5b6040516060810181811067ffffffffffffffff8211171561514557615145614478565b604052823561515381614956565b8152615161602084016150f0565b6020820152615172604084016150f0565b60408201529392505050565b604081526000615191604083018561475b565b8281036020840152612eb3818561475b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106a4576106a46151a3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061522f5761522f6151e5565b92169190910692915050565b80820281158282048414176106a4576106a46151a3565b600067ffffffffffffffff8084168061526d5761526d6151e5565b92169190910492915050565b602081016003831061528d5761528d6143c4565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff8083168181036152db576152db6151a3565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153158184018a61475b565b90508281036080840152615329818961475b565b905060ff871660a084015282810360c08401526153468187614439565b905067ffffffffffffffff851660e084015282810361010084015261536b8185614439565b9c9b505050505050505050505050565b60006020828403121561538d57600080fd5b8151610e5d81614381565b600082601f8301126153a957600080fd5b81516153b76145ad82614615565b8181528460208386010111156153cc57600080fd5b611e33826020830160208701614415565b6000602082840312156153ef57600080fd5b815167ffffffffffffffff8082111561540757600080fd5b908301906080828603121561541b57600080fd5b6154236144d0565b82518281111561543257600080fd5b61543e87828601615398565b82525060208301518281111561545357600080fd5b61545f87828601615398565b60208301525060408301518281111561547757600080fd5b61548387828601615398565b6040830152506060830151925061549983614da3565b6060810192909252509392505050565b808201808211156106a4576106a46151a3565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154f157600080fd5b83018035915067ffffffffffffffff82111561550c57600080fd5b6020019150600681901b3603821315612db257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261555957600080fd5b83018035915067ffffffffffffffff82111561557457600080fd5b6020019150600581901b3603821315612db257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155c157600080fd5b83018035915067ffffffffffffffff8211156155dc57600080fd5b602001915036819003821315612db257600080fd5b60008151808452602080850194506020840160005b8381101561479557815180516001600160a01b031688528301518388015260409096019590820190600101615606565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152615671610120840182614439565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e08601526156ad8383614439565b9250608089015191508085840301610100860152506156cc82826155f1565b925050506156e0602083018661ffff169052565b836040830152612eb360608301846001600160a01b03169052565b60008060006060848603121561571057600080fd5b835161571b81614956565b602085015190935067ffffffffffffffff81111561573857600080fd5b61574486828701615398565b925050604084015190509250925092565b600060a0828403121561576757600080fd5b60405160a0810181811067ffffffffffffffff8211171561578a5761578a614478565b604052825161579881614da3565b815260208301516157a881614da3565b6020820152604083015161ffff811681146157c257600080fd5b604082015260608301516157d58161456c565b606082015260808301516157e88161456c565b60808201529392505050565b610180810161586582856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff1661012083015260608301516001600160a01b03908116610140840152608084015116610160830152610e5d565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526158f08285018b61475b565b91508382036080850152615904828a61475b565b915060ff881660a085015283820360c08501526159218288614439565b90861660e0850152838103610100850152905061536b8185614439565b60006020828403121561595057600080fd5b8151610e5d81614956565b60008151808452602080850194506020840160005b8381101561479557815187529582019590820190600101615970565b60608152600061599f606083018661595b565b82810360208401526159b1818661595b565b915050826040830152949350505050565b6000602082840312156159d457600080fd5b5051919050565b67ffffffffffffffff8181168382160190808211156141e7576141e76151a3565b67ffffffffffffffff8316815260408101610e5d60208301846143f3565b600067ffffffffffffffff8083168181036152db576152db6151a3565b615a4181846143f3565b604060208201526000611e336040830184614439565b600060208284031215615a6957600080fd5b813567ffffffffffffffff811115615a8057600080fd5b611e3384828501614b71565b600060408284031215615a9e57600080fd5b610e5d838361496f565b600060208284031215615aba57600080fd5b813567ffffffffffffffff80821115615ad257600080fd5b9083019060808286031215615ae657600080fd5b615aee6144d0565b823582811115615afd57600080fd5b615b098782860161463d565b825250602083013582811115615b1e57600080fd5b615b2a8782860161463d565b602083015250604083013582811115615b4257600080fd5b615b4e8782860161463d565b6040830152506060830135925061549983614da3565b602081526000610e5d60208301846155f1565b60008282518085526020808601955060208260051b8401016020860160005b84811015615bc457601f19868403018952615bb2838351614439565b98840198925090830190600101615b96565b5090979650505050505050565b602081526000610e5d6020830184615b77565b60008151808452602080850194506020840160005b8381101561479557815163ffffffff1687529582019590820190600101615bf9565b60608152615c3660608201855167ffffffffffffffff169052565b60006020850151615c5260808401826001600160a01b03169052565b5060408501516001600160a01b03811660a084015250606085015167ffffffffffffffff811660c084015250608085015160e083015260a0850151610100615c9d8185018315159052565b60c08701519150610120615cbc8186018467ffffffffffffffff169052565b60e08801519250610140615cda818701856001600160a01b03169052565b828901519350610160925083838701528189015193506101a091506101808281880152615d0b610200880186614439565b9450818a015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0808887030184890152615d4786846155f1565b948b01518886039091016101c0890152939450615d648585615b77565b9450808a01516101e0880152505050508281036020840152615d868186615b77565b90508281036040840152615d9a8185615be4565b9695505050505050565b600060208284031215615db657600080fd5b8151610e5d8161456c565b6020815260008251610100806020850152615de0610120850183614439565b91506020850151615dfd604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615e3760a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615e548483614439565b935060c08701519150808685030160e0870152615e718483614439565b935060e0870151915080868503018387015250615d9a8382614439565b600060408284031215615ea057600080fd5b615ea86144a7565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114615ed457600080fd5b81526020830151615ee481614da3565b60208201529392505050565b600082615eff57615eff6151e5565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + Bin: "0x6101a06040523480156200001257600080fd5b506040516200660a3803806200660a8339810160408190526200003591620004ec565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c081620002ca565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606080870182905298909601519091166080948501819052600380546001600160a01b031916909217600160801b9485021760ff60a01b1916600160a01b90930292909217905502909117600455469052508201516001600160a01b031615806200016f575081516001600160a01b0316155b8062000186575060c08201516001600160a01b0316155b15620001a5576040516342bcdf7f60e11b815260040160405180910390fd5b81600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e9190620005b5565b6001600160401b03166001146200023857604051636fc2a20760e11b815260040160405180910390fd5b81516001600160a01b0390811660a090815260408401516001600160401b0390811660c0908152602086015190911660e05260608501518316610100526080850151831661014052908401518216610160528301511661018052620002bd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000375565b6101205250620005da9050565b336001600160a01b03821603620003245760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e05161010051604051602001620003bf94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b60405160e081016001600160401b03811182821017156200040d57634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200042b57600080fd5b919050565b80516001600160401b03811681146200042b57600080fd5b80516001600160801b03811681146200042b57600080fd5b6000606082840312156200047357600080fd5b604051606081016001600160401b0381118282101715620004a457634e487b7160e01b600052604160045260246000fd5b806040525080915082518015158114620004bd57600080fd5b8152620004cd6020840162000448565b6020820152620004e06040840162000448565b60408201525092915050565b6000808284036101408112156200050257600080fd5b60e08112156200051157600080fd5b506200051c620003dc565b620005278462000413565b8152620005376020850162000430565b60208201526200054a6040850162000430565b60408201526200055d6060850162000413565b6060820152620005706080850162000413565b60808201526200058360a0850162000413565b60a08201526200059660c0850162000413565b60c08201529150620005ac8460e0850162000460565b90509250929050565b600060208284031215620005c857600080fd5b620005d38262000430565b9392505050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f41620006c9600039600081816102ec01528181611c6a01526133920152600081816102bd01528181611c420152611f2701526000818161028e01528181610d8d01528181610df201528181611c18015281816124a4015261250e015260006120c601526000818161025f0152611bee0152600081816101ff0152611b9201526000818161022f01528181611bc601528181611ee40152818161303b01526134bf0152600081816101d001528181611b6d01526121ac015260008181611e3e0152611e8a0152615f416000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806385572ffb116100d8578063afcb95d71161008c578063c92b283211610066578063c92b2832146105f3578063f077b59214610606578063f2fde38b1461061c57600080fd5b8063afcb95d7146105ad578063b1dc65a4146105cd578063b6113fce146105e057600080fd5b8063873504d7116100bd578063873504d7146105765780638926c4ee146105895780638da5cb5b1461059c57600080fd5b806385572ffb1461053c578063856c82471461054a57600080fd5b8063599f64311161013a5780637437ff9f116101145780637437ff9f1461046157806379ba50971461050457806381ff70481461050c57600080fd5b8063599f643114610414578063666cab8d14610439578063704b6c021461044e57600080fd5b8063181f5a771161016b578063181f5a77146103525780631ef381741461039b578063546719cd146103b057600080fd5b806306285c6914610187578063142a98fc14610332575b600080fd5b61031c6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516103299190614312565b60405180910390f35b6103456103403660046143a8565b61062f565b6040516103299190614408565b61038e6040518060400160405280601481526020017f45564d3245564d4f666652616d7020312e352e3000000000000000000000000081525081565b6040516103299190614466565b6103ae6103a936600461468f565b6106aa565b005b6103b8610a9e565b604051610329919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610329565b610441610b53565b60405161032991906147a1565b6103ae61045c3660046147b4565b610bb5565b6104f76040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff8082168352640100000000820416602083015268010000000000000000810461ffff16928201929092526a01000000000000000000009091046001600160a01b039081166060830152600b5416608082015290565b60405161032991906147d1565b6103ae610c7e565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610329565b6103ae610182366004614827565b61055d6105583660046147b4565b610d61565b60405167ffffffffffffffff9091168152602001610329565b6103ae6105843660046148f3565b610e64565b6103ae610597366004614e1e565b611037565b6000546001600160a01b0316610421565b604080516001815260006020820181905291810191909152606001610329565b6103ae6105db366004614f75565b61129c565b6103ae6105ee36600461505a565b6114a7565b6103ae610601366004615111565b6117e7565b61060e611852565b60405161032992919061517f565b6103ae61062a3660046147b4565b611978565b600061063d600160046151d3565b600261064a608085615215565b67ffffffffffffffff1661065e919061523c565b6010600061066d608087615253565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156106a4576106a46143c5565b92915050565b84518460ff16601f8211156106f75760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee919061527a565b60405180910390fd5b806000036107345760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee919061527a565b61073c611989565b610745856119ff565b60095460005b818110156107bc57600860006009838154811061076a5761076a615294565b60009182526020808320909101546001600160a01b03168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905560010161074b565b5050865160005b8181101561095f5760008982815181106107df576107df615294565b60200260200101519050600060028111156107fc576107fc6143c5565b6001600160a01b038216600090815260086020526040902054610100900460ff16600281111561082e5761082e6143c5565b146108685760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016106ee919061527a565b6001600160a01b0381166108a8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8316815260208101600290526001600160a01b03821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561094b5761094b6143c5565b0217905550905050508060010190506107c3565b5087516109739060099060208b0190614280565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908a1617179055600780546109f99146913091906000906109cb9063ffffffff166152c3565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168c8c8c8c8c8c611cc9565b6005819055600780544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff841681179094556040519083048216947f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0594610a8a9487949293918316921691909117908f908f908f908f908f908f906152e6565b60405180910390a150505050505050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610b4e90611d56565b905090565b60606009805480602002602001604051908101604052809291908181526020018280548015610bab57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8d575b5050505050905090565b6000546001600160a01b03163314801590610bdb57506002546001600160a01b03163314155b15610c12576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b6001546001600160a01b03163314610cf2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106ee565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168082036106a4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156106a4576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5d919061537c565b9392505050565b610e6c611989565b60005b8251811015610f3f57610ea9838281518110610e8d57610e8d615294565b602002602001015160200151600c611e0890919063ffffffff16565b15610f37577fcbf3cbeaed4ac1d605ed30f4af06c35acaeff2379db7f6146c9cceee83d58782838281518110610ee157610ee1615294565b602002602001015160000151848381518110610eff57610eff615294565b602002602001015160200151604051610f2e9291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610e6f565b5060005b815181101561103257610f9c828281518110610f6157610f61615294565b602002602001015160200151838381518110610f7f57610f7f615294565b602002602001015160000151600c611e1d9092919063ffffffff16565b1561102a577ffc23abf7ddbd3c02b1420dafa2355c56c1a06fbb8723862ac14d6bd74177361a828281518110610fd457610fd4615294565b602002602001015160000151838381518110610ff257610ff2615294565b6020026020010151602001516040516110219291906001600160a01b0392831681529116602082015260400190565b60405180910390a15b600101610f43565b505050565b61103f611e3b565b8151518151811461107c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156112915760008460000151828151811061109f5761109f615294565b6020026020010151905060008483815181106110bd576110bd615294565b60209081029190910101518051909150801561112c57826080015181101561112c5761018083015160808401516040517f9c6db58d00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016106ee565b816020015151836101400151511461118e5761018083015160608401516040517f85d2e5bf000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff1660248201526044016106ee565b61016083015160005b846101400151518110156112815760008287815181106111b9576111b9615294565b60200260200101518060200190518101906111d491906153de565b90506000856020015183815181106111ee576111ee615294565b602002602001015163ffffffff169050806000141580156112185750816060015163ffffffff1681105b156112775761018087015160608301516040517fef0c635200000000000000000000000000000000000000000000000000000000815260048101929092526024820185905263ffffffff166044820152606481018290526084016106ee565b5050600101611197565b505050505080600101905061107f565b506110328383611ebc565b6112a6878761290f565b6005548835908082146112ef576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016106ee565b6112f7611e3b565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561137f5761137f6143c5565b6002811115611390576113906143c5565b90525090506002816020015160028111156113ad576113ad6143c5565b1480156113e757506009816000015160ff16815481106113cf576113cf615294565b6000918252602090912001546001600160a01b031633145b61141d576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061142b85602061523c565b61143688602061523c565b6114428b6101446154aa565b61144c91906154aa565b61145691906154aa565b905036811461149a576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016106ee565b5050505050505050505050565b3330146114e0576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516000808252602082019092528161151d565b60408051808201909152600080825260208201528152602001906001900390816114f65790505b50905060006115306101408701876154bd565b905011156115a7576115a46115496101408701876154bd565b6115596040890160208a016147b4565b604080516001600160a01b0390921660208301520160408051601f1981840301815291815261158e9060608b01908b016147b4565b61159c6101608b018b615525565b8a8a8a612966565b90505b6115b561012086018661558d565b15905080156115c657506080850135155b806115e857506115dc60608601604087016147b4565b6001600160a01b03163b155b8061163357506116317f85572ffb0000000000000000000000000000000000000000000000000000000061162260608801604089016147b4565b6001600160a01b031690612b8f565b155b1561163e57506117e1565b600a546040805160a08101909152610180870135815260009182916a01000000000000000000009091046001600160a01b031690633cf979839060208082019061168a908c018c6143a8565b67ffffffffffffffff1681526020018a60200160208101906116ac91906147b4565b604080516001600160a01b0390921660208301520160408051601f1981840301815291905281526020016116e46101208c018c61558d565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200186905261138860808b013561173960608d0160408e016147b4565b6040518563ffffffff1660e01b81526004016117589493929190615637565b6000604051808303816000875af1158015611777573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261179f91908101906156fc565b5091509150816117dd57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016106ee9190614466565b5050505b50505050565b6000546001600160a01b0316331480159061180d57506002546001600160a01b03163314155b15611844576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61184f600382612bab565b50565b6060806000611861600c612d90565b90508067ffffffffffffffff81111561187c5761187c614479565b6040519080825280602002602001820160405280156118a5578160200160208202803683370190505b5092508067ffffffffffffffff8111156118c1576118c1614479565b6040519080825280602002602001820160405280156118ea578160200160208202803683370190505b50915060005b8181101561197257600080611906600c84612d9b565b915091508086848151811061191d5761191d615294565b60200260200101906001600160a01b031690816001600160a01b0316815250508185848151811061195057611950615294565b6001600160a01b039092166020928302919091019091015250506001016118f0565b50509091565b611980611989565b61184f81612db9565b6000546001600160a01b031633146119fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106ee565b565b600081806020019051810190611a159190615756565b60608101519091506001600160a01b0316611a5c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015160408087015160608089015163ffffffff9889167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096176401000000009890941697909702929092177fffff00000000000000000000000000000000000000000000ffffffffffffffff166801000000000000000061ffff909316929092027fffff0000000000000000000000000000000000000000ffffffffffffffffffff16919091176a01000000000000000000006001600160a01b039485160217909355608080860151600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918516919091179055835160e0810185527f0000000000000000000000000000000000000000000000000000000000000000841681527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff908116938201939093527f0000000000000000000000000000000000000000000000000000000000000000909216828501527f00000000000000000000000000000000000000000000000000000000000000008316948201949094527f00000000000000000000000000000000000000000000000000000000000000008216938101939093527f0000000000000000000000000000000000000000000000000000000000000000811660a08401527f00000000000000000000000000000000000000000000000000000000000000001660c0830152517f7879e20bb60a503429de4a2c912b5904f08a39f2af054c10fb46434b5d61126091611cbd9184906157f5565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611ced999897969594939291906158b7565b60408051601f1981840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611de482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611dc891906151d3565b85608001516fffffffffffffffffffffffffffffffff16612e94565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6000610e5d836001600160a01b038416612ebc565b6000611e33846001600160a01b03851684612ec8565b949350505050565b467f0000000000000000000000000000000000000000000000000000000000000000146119fd576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016106ee565b6040517f2cbc26bb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060801b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015611f76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9a919061593f565b15611fd1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815151600081900361200e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015151811461204c576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561206757612067614479565b604051908082528060200260200182016040528015612090578160200160208202803683370190505b50905060005b82811015612168576000856000015182815181106120b6576120b6615294565b602002602001015190506120ea817f0000000000000000000000000000000000000000000000000000000000000000612ede565b8383815181106120fc576120fc615294565b60200260200101818152505080610180015183838151811061212057612120615294565b60200260200101511461215f576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101612096565b508251604080860151606087015191517f32048875000000000000000000000000000000000000000000000000000000008152921515926000926001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926332048875926121e29288929160040161598d565b602060405180830381865afa1580156121ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222391906159c3565b90508060000361225f576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b848110156117dd5760008760000151828151811061228257612282615294565b60200260200101519050600061229b826060015161062f565b905060008160038111156122b1576122b16143c5565b14806122ce575060038160038111156122cc576122cc6143c5565b145b61231457816060015167ffffffffffffffff167fe3dd0bec917c965a133ddb2c84874725ee1e2fd8d763c19efa36d6a11cd82b1f60405160405180910390a25050612907565b606085156123fa5788848151811061232e5761232e615294565b6020908102919091018101510151600a5490915060009063ffffffff1661235587426151d3565b119050808061237557506003836003811115612373576123736143c5565b145b6123ab576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8985815181106123bd576123bd615294565b6020026020010151600001516000146123f4578985815181106123e2576123e2615294565b60209081029190910101515160808501525b5061245e565b600082600381111561240e5761240e6143c5565b1461245e57606083015160405167ffffffffffffffff90911681527f67d9ba0f63d427c482c2736300e6d5a34c6691dbcdea8ad35828a1f1ba47e8729060200160405180910390a1505050612907565b60c083015167ffffffffffffffff16156126df576020808401516001600160a01b03166000908152600f909152604081205467ffffffffffffffff1690819003612649577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156126495760208401516040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa158015612557573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257b919061537c565b60c085015190915067ffffffffffffffff166125988260016159dc565b67ffffffffffffffff16146125f95783602001516001600160a01b03168460c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a350505050612907565b6020848101516001600160a01b03166000908152600f9091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b600083600381111561265d5761265d6143c5565b036126dd5760c084015167ffffffffffffffff1661267c8260016159dc565b67ffffffffffffffff16146126dd5783602001516001600160a01b03168460c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a350505050612907565b505b60008a6020015185815181106126f7576126f7615294565b602002602001015190506127238460600151856000015186610140015151876101200151518551613039565b612732846060015160016131ba565b600080612740868486613264565b915091506127528660600151836131ba565b88156127be57600382600381111561276c5761276c6143c5565b036127be576000856003811115612785576127856143c5565b146127be57806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016106ee9190614466565b60028260038111156127d2576127d26143c5565b1461282a5760038260038111156127eb576127eb6143c5565b1461282a578560600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016106ee9291906159fd565b60c086015167ffffffffffffffff16156128b2576000856003811115612852576128526143c5565b036128b2576020808701516001600160a01b03166000908152600f90915260408120805467ffffffffffffffff169161288a83615a1b565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b856101800151866060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef6584846040516128f8929190615a38565b60405180910390a35050505050505b600101612262565b61296261291e82840184615a58565b604080516000808252602082019092529061295c565b6040805180820190915260008152606060208201528152602001906001900390816129345790505b50611ebc565b5050565b60608989808060200260200160405190810160405280939291908181526020016000905b828210156129b6576129a760408302860136819003810190615a8d565b8152602001906001019061298a565b505050505090506000805b8a811015612b715760008888838181106129dd576129dd615294565b90506020028101906129ef919061558d565b8101906129fc9190615aa9565b90508451600014612a5757848281518110612a1957612a19615294565b602002602001015163ffffffff16600014612a5757848281518110612a4057612a40615294565b602090810291909101015163ffffffff1660608201525b612ad78d8d84818110612a6c57612a6c615294565b905060400201602001358c8c848b8b88818110612a8b57612a8b615294565b9050602002810190612a9d919061558d565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061333192505050565b848381518110612ae957612ae9615294565b6020026020010181905250612b25848381518110612b0957612b09615294565b602002602001015160000151600c6136fd90919063ffffffff16565b15612b6857612b5b848381518110612b3f57612b3f615294565b6020908102919091010151600b546001600160a01b0316613712565b612b6590846154aa565b92505b506001016129c1565b508015612b8157612b8181613833565b509998505050505050505050565b6000612b9a83613840565b8015610e5d5750610e5d83836138a4565b8154600090612bd490700100000000000000000000000000000000900463ffffffff16426151d3565b90508015612c765760018301548354612c1c916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e94565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c9c916fffffffffffffffffffffffffffffffff9081169116613974565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612d839084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b60006106a48261398a565b6000808080612daa8686613995565b909450925050505b9250929050565b336001600160a01b03821603612e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106ee565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612eb385612ea4848661523c565b612eae90876154aa565b613974565b95945050505050565b6000610e5d83836139a4565b6000611e3384846001600160a01b0385166139c1565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001612f749897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001612fad9190615b65565b60405160208183030381529060405280519060200120876101600151604051602001612fd99190615bd2565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168467ffffffffffffffff16146130b2576040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016106ee565b600a5468010000000000000000900461ffff1683111561310a576040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b80831461314f576040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016106ee565b600a54640100000000900463ffffffff168211156131b357600a546040517f8693378900000000000000000000000000000000000000000000000000000000815264010000000090910463ffffffff166004820152602481018390526044016106ee565b5050505050565b600060026131c9608085615215565b67ffffffffffffffff166131dd919061523c565b905060006010816131ef608087615253565b67ffffffffffffffff168152602081019190915260400160002054905081613219600160046151d3565b901b191681836003811115613230576132306143c5565b901b178060106000613243608088615253565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517fb6113fce000000000000000000000000000000000000000000000000000000008152600090606090309063b6113fce906132aa90889088908890600401615c1c565b600060405180830381600087803b1580156132c457600080fd5b505af19250505080156132d5575060015b613314573d808015613303576040519150601f19603f3d011682016040523d82523d6000602084013e613308565b606091505b50600392509050613329565b50506040805160208101909152600081526002905b935093915050565b6040805180820190915260008082526020820152600061335484602001516139de565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa1580156133d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fd9190615da5565b90506001600160a01b038116158061344557506134436001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000612b8f565b155b15613487576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016106ee565b60008061349f8885896060015163ffffffff16613a84565b91509150600080600061359d6040518061010001604052808e81526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020018d6001600160a01b031681526020018f8152602001896001600160a01b031681526020018c6000015181526020018c6040015181526020018b8152506040516024016135399190615dc2565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613bc7565b925092509250826135dc57816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190614466565b81516020146136245781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b60008280602001905181019061363a91906159c3565b9050866001600160a01b03168c6001600160a01b0316146136cf57600061366b8d8a613666868a6151d3565b613a84565b5090508681108061368557508161368288836151d3565b14155b156136cd576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016106ee565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000610e5d836001600160a01b038416613ced565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613778573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379c9190615e8f565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036138055783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016106ee565b6020840151611e33907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690613cf9565b61184f6003826000613d36565b600061386c827f01ffc9a7000000000000000000000000000000000000000000000000000000006138a4565b80156106a4575061389d827fffffffff000000000000000000000000000000000000000000000000000000006138a4565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d9150600051905082801561395d575060208210155b80156139695750600081115b979650505050505050565b60008183106139835781610e5d565b5090919050565b60006106a482614085565b6000808080612daa8686614090565b60008181526002830160205260408120819055610e5d83836140bb565b60008281526002840160205260408120829055611e3384846140c7565b60008151602014613a1d57816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190614466565b600082806020019051810190613a3391906159c3565b90506001600160a01b03811180613a4b575061040081105b156106a457826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106ee9190614466565b6000806000806000613b1388604051602401613aaf91906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613bc7565b92509250925082613b5257816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106ee9190614466565b6020825114613b9a5781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106ee565b81806020019051810190613bae91906159c3565b613bb882886151d3565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613bea57613bea614479565b6040519080825280601f01601f191660200182016040528015613c14576020820181803683370190505b509150863b613c47577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613c7a577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613cb3577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613cd65750835b808352806000602085013e50955095509592505050565b6000610e5d83836140d3565b6000670de0b6b3a7640000613d2c837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff861661523c565b610e5d9190615ef1565b825474010000000000000000000000000000000000000000900460ff161580613d5d575081155b15613d6757505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090613dad90700100000000000000000000000000000000900463ffffffff16426151d3565b90508015613e6d5781831115613def576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154613e299083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e94565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015613f0a576001600160a01b038416613ebf576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106ee565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b03851660448201526064016106ee565b848310156140035760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613f4e90826151d3565b613f58878a6151d3565b613f6291906154aa565b613f6c9190615ef1565b90506001600160a01b038616613fb8576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106ee565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b03871660448201526064016106ee565b61400d85846151d3565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60006106a4826140df565b6000808061409e85856140e9565b600081815260029690960160205260409095205494959350505050565b6000610e5d83836140f5565b6000610e5d83836141ef565b6000610e5d838361423e565b60006106a4825490565b6000610e5d8383614256565b600081815260018301602052604081205480156141de5760006141196001836151d3565b855490915060009061412d906001906151d3565b905081811461419257600086600001828154811061414d5761414d615294565b906000526020600020015490508087600001848154811061417057614170615294565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806141a3576141a3615f05565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106a4565b60009150506106a4565b5092915050565b6000818152600183016020526040812054614236575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106a4565b5060006106a4565b60008181526001830160205260408120541515610e5d565b600082600001828154811061426d5761426d615294565b9060005260206000200154905092915050565b8280548282559060005260206000209081019282156142ed579160200282015b828111156142ed57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039091161782556020909201916001909101906142a0565b506142f99291506142fd565b5090565b5b808211156142f957600081556001016142fe565b60e081016106a482846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b67ffffffffffffffff8116811461184f57600080fd5b80356143a381614382565b919050565b6000602082840312156143ba57600080fd5b8135610e5d81614382565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110614404576144046143c5565b9052565b602081016106a482846143f4565b60005b83811015614431578181015183820152602001614419565b50506000910152565b60008151808452614452816020860160208601614416565b601f01601f19169290920160200192915050565b602081526000610e5d602083018461443a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156144cb576144cb614479565b60405290565b6040516080810167ffffffffffffffff811182821017156144cb576144cb614479565b6040516101a0810167ffffffffffffffff811182821017156144cb576144cb614479565b604051601f8201601f1916810167ffffffffffffffff8111828210171561454157614541614479565b604052919050565b600067ffffffffffffffff82111561456357614563614479565b5060051b60200190565b6001600160a01b038116811461184f57600080fd5b80356143a38161456d565b600082601f83011261459e57600080fd5b813560206145b36145ae83614549565b614518565b8083825260208201915060208460051b8701019350868411156145d557600080fd5b602086015b848110156145fa5780356145ed8161456d565b83529183019183016145da565b509695505050505050565b803560ff811681146143a357600080fd5b600067ffffffffffffffff82111561463057614630614479565b50601f01601f191660200190565b600082601f83011261464f57600080fd5b813561465d6145ae82614616565b81815284602083860101111561467257600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156146a857600080fd5b863567ffffffffffffffff808211156146c057600080fd5b6146cc8a838b0161458d565b975060208901359150808211156146e257600080fd5b6146ee8a838b0161458d565b96506146fc60408a01614605565b9550606089013591508082111561471257600080fd5b61471e8a838b0161463e565b945061472c60808a01614398565b935060a089013591508082111561474257600080fd5b5061474f89828a0161463e565b9150509295509295509295565b60008151808452602080850194506020840160005b838110156147965781516001600160a01b031687529582019590820190600101614771565b509495945050505050565b602081526000610e5d602083018461475c565b6000602082840312156147c657600080fd5b8135610e5d8161456d565b60a081016106a4828463ffffffff8082511683528060208301511660208401525061ffff604082015116604083015260608101516001600160a01b03808216606085015280608084015116608085015250505050565b60006020828403121561483957600080fd5b813567ffffffffffffffff81111561485057600080fd5b820160a08185031215610e5d57600080fd5b600082601f83011261487357600080fd5b813560206148836145ae83614549565b82815260069290921b840181019181810190868411156148a257600080fd5b8286015b848110156145fa57604081890312156148bf5760008081fd5b6148c76144a8565b81356148d28161456d565b8152818501356148e18161456d565b818601528352918301916040016148a6565b6000806040838503121561490657600080fd5b823567ffffffffffffffff8082111561491e57600080fd5b61492a86838701614862565b9350602085013591508082111561494057600080fd5b5061494d85828601614862565b9150509250929050565b801515811461184f57600080fd5b80356143a381614957565b60006040828403121561498257600080fd5b61498a6144a8565b905081356149978161456d565b808252506020820135602082015292915050565b600082601f8301126149bc57600080fd5b813560206149cc6145ae83614549565b8083825260208201915060208460061b8701019350868411156149ee57600080fd5b602086015b848110156145fa57614a058882614970565b8352918301916040016149f3565b600082601f830112614a2457600080fd5b81356020614a346145ae83614549565b82815260059290921b84018101918181019086841115614a5357600080fd5b8286015b848110156145fa57803567ffffffffffffffff811115614a775760008081fd5b614a858986838b010161463e565b845250918301918301614a57565b600082601f830112614aa457600080fd5b81356020614ab46145ae83614549565b82815260059290921b84018101918181019086841115614ad357600080fd5b8286015b848110156145fa57803567ffffffffffffffff811115614af75760008081fd5b614b058986838b0101614a13565b845250918301918301614ad7565b600082601f830112614b2457600080fd5b81356020614b346145ae83614549565b8083825260208201915060208460051b870101935086841115614b5657600080fd5b602086015b848110156145fa5780358352918301918301614b5b565b600060808284031215614b8457600080fd5b614b8c6144d1565b9050813567ffffffffffffffff80821115614ba657600080fd5b818401915084601f830112614bba57600080fd5b81356020614bca6145ae83614549565b82815260059290921b84018101918181019088841115614be957600080fd5b8286015b84811015614d4557803586811115614c0457600080fd5b87016101a0818c03601f19011215614c1b57600080fd5b614c236144f4565b614c2e868301614398565b8152614c3c60408301614582565b86820152614c4c60608301614582565b6040820152614c5d60808301614398565b606082015260a08201356080820152614c7860c08301614965565b60a0820152614c8960e08301614398565b60c0820152610100614c9c818401614582565b60e083015261012080840135828401526101409150818401358a811115614cc257600080fd5b614cd08f8a8388010161463e565b828501525050610160808401358a811115614cea57600080fd5b614cf88f8a838801016149ab565b83850152506101809150818401358a811115614d1357600080fd5b614d218f8a83880101614a13565b91840191909152506101a09290920135918101919091528352918301918301614bed565b5086525085810135935082841115614d5c57600080fd5b614d6887858801614a93565b90850152506040840135915080821115614d8157600080fd5b50614d8e84828501614b13565b6040830152506060820135606082015292915050565b63ffffffff8116811461184f57600080fd5b600082601f830112614dc757600080fd5b81356020614dd76145ae83614549565b8083825260208201915060208460051b870101935086841115614df957600080fd5b602086015b848110156145fa578035614e1181614da4565b8352918301918301614dfe565b6000806040808486031215614e3257600080fd5b833567ffffffffffffffff80821115614e4a57600080fd5b614e5687838801614b72565b9450602091508186013581811115614e6d57600080fd5b8601601f81018813614e7e57600080fd5b8035614e8c6145ae82614549565b81815260059190911b8201840190848101908a831115614eab57600080fd5b8584015b83811015614f1e57803586811115614ec75760008081fd5b8501808d03601f1901891315614edd5760008081fd5b614ee56144a8565b8882013581528982013588811115614efd5760008081fd5b614f0b8f8b83860101614db6565b828b015250845250918601918601614eaf565b50809750505050505050509250929050565b60008083601f840112614f4257600080fd5b50813567ffffffffffffffff811115614f5a57600080fd5b6020830191508360208260051b8501011115612db257600080fd5b60008060008060008060008060e0898b031215614f9157600080fd5b606089018a811115614fa257600080fd5b8998503567ffffffffffffffff80821115614fbc57600080fd5b818b0191508b601f830112614fd057600080fd5b813581811115614fdf57600080fd5b8c6020828501011115614ff157600080fd5b6020830199508098505060808b013591508082111561500f57600080fd5b61501b8c838d01614f30565b909750955060a08b013591508082111561503457600080fd5b506150418b828c01614f30565b999c989b50969995989497949560c00135949350505050565b6000806000806060858703121561507057600080fd5b843567ffffffffffffffff8082111561508857600080fd5b908601906101a0828903121561509d57600080fd5b909450602086013590808211156150b357600080fd5b6150bf88838901614f30565b909550935060408701359150808211156150d857600080fd5b506150e587828801614db6565b91505092959194509250565b80356fffffffffffffffffffffffffffffffff811681146143a357600080fd5b60006060828403121561512357600080fd5b6040516060810181811067ffffffffffffffff8211171561514657615146614479565b604052823561515481614957565b8152615162602084016150f1565b6020820152615173604084016150f1565b60408201529392505050565b604081526000615192604083018561475c565b8281036020840152612eb3818561475c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106a4576106a46151a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680615230576152306151e6565b92169190910692915050565b80820281158282048414176106a4576106a46151a4565b600067ffffffffffffffff8084168061526e5761526e6151e6565b92169190910492915050565b602081016003831061528e5761528e6143c5565b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff8083168181036152dc576152dc6151a4565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153168184018a61475c565b9050828103608084015261532a818961475c565b905060ff871660a084015282810360c0840152615347818761443a565b905067ffffffffffffffff851660e084015282810361010084015261536c818561443a565b9c9b505050505050505050505050565b60006020828403121561538e57600080fd5b8151610e5d81614382565b600082601f8301126153aa57600080fd5b81516153b86145ae82614616565b8181528460208386010111156153cd57600080fd5b611e33826020830160208701614416565b6000602082840312156153f057600080fd5b815167ffffffffffffffff8082111561540857600080fd5b908301906080828603121561541c57600080fd5b6154246144d1565b82518281111561543357600080fd5b61543f87828601615399565b82525060208301518281111561545457600080fd5b61546087828601615399565b60208301525060408301518281111561547857600080fd5b61548487828601615399565b6040830152506060830151925061549a83614da4565b6060810192909252509392505050565b808201808211156106a4576106a46151a4565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154f257600080fd5b83018035915067ffffffffffffffff82111561550d57600080fd5b6020019150600681901b3603821315612db257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261555a57600080fd5b83018035915067ffffffffffffffff82111561557557600080fd5b6020019150600581901b3603821315612db257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155c257600080fd5b83018035915067ffffffffffffffff8211156155dd57600080fd5b602001915036819003821315612db257600080fd5b60008151808452602080850194506020840160005b8381101561479657815180516001600160a01b031688528301518388015260409096019590820190600101615607565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c084015261567261012084018261443a565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e08601526156ae838361443a565b9250608089015191508085840301610100860152506156cd82826155f2565b925050506156e1602083018661ffff169052565b836040830152612eb360608301846001600160a01b03169052565b60008060006060848603121561571157600080fd5b835161571c81614957565b602085015190935067ffffffffffffffff81111561573957600080fd5b61574586828701615399565b925050604084015190509250925092565b600060a0828403121561576857600080fd5b60405160a0810181811067ffffffffffffffff8211171561578b5761578b614479565b604052825161579981614da4565b815260208301516157a981614da4565b6020820152604083015161ffff811681146157c357600080fd5b604082015260608301516157d68161456d565b606082015260808301516157e98161456d565b60808201529392505050565b610180810161586682856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b825163ffffffff90811660e0840152602084015116610100830152604083015161ffff1661012083015260608301516001600160a01b03908116610140840152608084015116610160830152610e5d565b60006101208b83526001600160a01b038b16602084015267ffffffffffffffff808b1660408501528160608501526158f18285018b61475c565b91508382036080850152615905828a61475c565b915060ff881660a085015283820360c0850152615922828861443a565b90861660e0850152838103610100850152905061536c818561443a565b60006020828403121561595157600080fd5b8151610e5d81614957565b60008151808452602080850194506020840160005b8381101561479657815187529582019590820190600101615971565b6060815260006159a0606083018661595c565b82810360208401526159b2818661595c565b915050826040830152949350505050565b6000602082840312156159d557600080fd5b5051919050565b67ffffffffffffffff8181168382160190808211156141e8576141e86151a4565b67ffffffffffffffff8316815260408101610e5d60208301846143f4565b600067ffffffffffffffff8083168181036152dc576152dc6151a4565b615a4281846143f4565b604060208201526000611e33604083018461443a565b600060208284031215615a6a57600080fd5b813567ffffffffffffffff811115615a8157600080fd5b611e3384828501614b72565b600060408284031215615a9f57600080fd5b610e5d8383614970565b600060208284031215615abb57600080fd5b813567ffffffffffffffff80821115615ad357600080fd5b9083019060808286031215615ae757600080fd5b615aef6144d1565b823582811115615afe57600080fd5b615b0a8782860161463e565b825250602083013582811115615b1f57600080fd5b615b2b8782860161463e565b602083015250604083013582811115615b4357600080fd5b615b4f8782860161463e565b6040830152506060830135925061549a83614da4565b602081526000610e5d60208301846155f2565b60008282518085526020808601955060208260051b8401016020860160005b84811015615bc557601f19868403018952615bb383835161443a565b98840198925090830190600101615b97565b5090979650505050505050565b602081526000610e5d6020830184615b78565b60008151808452602080850194506020840160005b8381101561479657815163ffffffff1687529582019590820190600101615bfa565b60608152615c3760608201855167ffffffffffffffff169052565b60006020850151615c5360808401826001600160a01b03169052565b5060408501516001600160a01b03811660a084015250606085015167ffffffffffffffff811660c084015250608085015160e083015260a0850151610100615c9e8185018315159052565b60c08701519150610120615cbd8186018467ffffffffffffffff169052565b60e08801519250610140615cdb818701856001600160a01b03169052565b828901519350610160925083838701528189015193506101a091506101808281880152615d0c61020088018661443a565b9450818a015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0808887030184890152615d4886846155f2565b948b01518886039091016101c0890152939450615d658585615b78565b9450808a01516101e0880152505050508281036020840152615d878186615b78565b90508281036040840152615d9b8185615be5565b9695505050505050565b600060208284031215615db757600080fd5b8151610e5d8161456d565b6020815260008251610100806020850152615de161012085018361443a565b91506020850151615dfe604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615e3860a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615e55848361443a565b935060c08701519150808685030160e0870152615e72848361443a565b935060e0870151915080868503018387015250615d9b838261443a565b600060408284031215615ea157600080fd5b615ea96144a8565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114615ed557600080fd5b81526020830151615ee581614da4565b60208201529392505050565b600082615f0057615f006151e6565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var EVM2EVMOffRampABI = EVM2EVMOffRampMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go index 83302ca08e..38a4152c71 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go @@ -142,7 +142,7 @@ type RateLimiterTokenBucket struct { var EVM2EVMOnRampMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidChainSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"}],\"name\":\"InvalidNopAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWithdrawParams\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkBalanceNotSettled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeeBalanceReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoFeesToPay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoNopsToPay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdminOrNop\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyNops\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeConfig\",\"type\":\"tuple[]\"}],\"name\":\"FeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NopPaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nopWeightsTotal\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"NopsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"transferFeeConfig\",\"type\":\"tuple[]\"}],\"name\":\"TokenTransferFeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getFeeTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfig\",\"name\":\"feeTokenConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNopFeesJuels\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNops\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"weightsTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setFeeTokenConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"aggregateRateLimitEnabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"address[]\"}],\"name\":\"setTokenTransferFeeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawNonLinkFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101a06040523480156200001257600080fd5b506040516200822d3803806200822d833981016040819052620000359162001a93565b8333806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c0816200030b565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555085516001600160a01b0316158062000169575060208601516001600160401b0316155b8062000180575060408601516001600160401b0316155b8062000197575060608601516001600160401b0316155b80620001ae575060c08601516001600160a01b0316155b80620001c5575060e08601516001600160a01b0316155b15620001e4576040516306b7c75960e31b815260040160405180910390fd5b60208087015160408089015181517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3948101949094526001600160401b039283169184019190915216606082015230608082015260a00160408051601f198184030181529181528151602092830120608090815288516001600160a01b0390811660e0908152938a01516001600160401b0390811661010052928a015183166101205260608a015190921660a0908152908901516001600160601b031660c090815290890151821661014052880151811661016052908701511661018052620002cd85620003b6565b620002d883620006ad565b604080516000815260208101909152620002f4908390620007dd565b620002ff8162000a83565b5050505050506200218a565b336001600160a01b03821603620003655760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e08101516001600160a01b0316620003e2576040516306b7c75960e31b815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548160ff0219169083151502179055509050507f45b5ad483aa608464c2c7f278bd413d284d7790cdc836e40652e23a02770822060405180610100016040528060e0516001600160a01b03168152602001610100516001600160401b03168152602001610120516001600160401b0316815260200160a0516001600160401b0316815260200160c0516001600160601b03168152602001610140516001600160a01b03168152602001610160516001600160a01b03168152602001610180516001600160a01b031681525082604051620006a292919062001d1c565b60405180910390a150565b60005b8151811015620007ab576000828281518110620006d157620006d162001de1565b60209081029190910181015160408051608080820183528385015163ffffffff9081168352838501516001600160401b03908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b0260ff60a01b199688166c010000000000000000000000000296909616600160601b600160a81b031993909716640100000000026001600160601b031990951691161792909217919091169290921717905550600101620006b0565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e81604051620006a2919062001df7565b60005b8251811015620009a257600083828151811062000801576200080162001de1565b60200260200101519050602063ffffffff168160a0015163ffffffff1610156200085d57805160a08201516040516312766e0160e11b81526001600160a01b03909216600483015263ffffffff16602482015260440162000084565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087166001600160401b031990961695909517640100000000928716929092029190911765ffffffffffff60401b191668010000000000000000939092169290920263ffffffff60501b1916176a0100000000000000000000918416919091021764ffffffffff60701b1916600160701b939092169290920260ff60901b191617600160901b941515949094029390931760ff60981b1916600160981b931515939093029290921790915501620007e0565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d082604051620009d4919062001e86565b60405180910390a160005b815181101562000a3c57600c600083838151811062000a025762000a0262001de1565b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055600101620009df565b5080511562000a7f577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b8160405162000a76919062001f1b565b60405180910390a15b5050565b8051604081111562000aa857604051635ad0867d60e11b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff161562000afb57600e5463ffffffff6c010000000000000000000000008204166001600160601b039091161062000afb5762000afb62000c9e565b600062000b09600862000e8a565b90505b801562000b5557600062000b2f62000b2660018462001f80565b60089062000e9d565b50905062000b3f60088262000ebb565b50508062000b4d9062001f96565b905062000b0c565b506000805b8281101562000c3557600084828151811062000b7a5762000b7a62001de1565b6020026020010151600001519050600085838151811062000b9f5762000b9f62001de1565b602002602001015160200151905060e0516001600160a01b0316826001600160a01b0316148062000bd757506001600160a01b038216155b1562000c0257604051634de938d160e01b81526001600160a01b038316600482015260240162000084565b62000c1460088361ffff841662000ed9565b5062000c2561ffff82168562001fb0565b9350505080600101905062000b5a565b50600e805463ffffffff60601b19166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249062000c91908390869062001fd0565b60405180910390a1505050565b6000546001600160a01b0316331462000cef576002546001600160a01b0316331462000cef5762000cd160083362000ef9565b62000cef5760405163032bb72b60e31b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff16600081900362000d2b5760405163990e30bf60e01b815260040160405180910390fd5b600e546001600160601b03168181101562000d59576040516311a1ee3b60e31b815260040160405180910390fd5b600062000d6562000f10565b121562000d8557604051631e9acf1760e31b815260040160405180910390fd5b80600062000d94600862000e8a565b905060005b8181101562000e645760008062000db260088462000e9d565b909250905060008762000dcf836001600160601b038a1662002040565b62000ddb91906200205a565b905062000de981876200207d565b60e05190965062000e0e906001600160a01b0316846001600160601b03841662000f9e565b6040516001600160601b03821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a250505080600101905062000d99565b5050600e80546001600160601b0319166001600160601b03929092169190911790555050565b600062000e978262000ffb565b92915050565b600080808062000eae868662001008565b9097909650945050505050565b600062000ed2836001600160a01b03841662001035565b9392505050565b600062000ef1846001600160a01b0385168462001054565b949350505050565b600062000ed2836001600160a01b03841662001073565b600e5460e0516040516370a0823160e01b81523060048201526000926001600160601b0316916001600160a01b0316906370a0823190602401602060405180830381865afa15801562000f67573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f8d9190620020a0565b62000f999190620020ba565b905090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915262000ff69185916200108116565b505050565b600062000e978262001152565b600080806200101885856200115d565b600081815260029690960160205260409095205494959350505050565b6000818152600283016020526040812081905562000ed283836200116b565b6000828152600284016020526040812082905562000ef1848462001179565b600062000ed2838362001187565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620010d0906001600160a01b038516908490620011a0565b80519091501562000ff65780806020019051810190620010f19190620020dd565b62000ff65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000084565b600062000e97825490565b600062000ed28383620011b1565b600062000ed28383620011de565b600062000ed28383620012e9565b6000818152600183016020526040812054151562000ed2565b606062000ef184846000856200133b565b6000826000018281548110620011cb57620011cb62001de1565b9060005260206000200154905092915050565b60008181526001830160205260408120548015620012d75760006200120560018362001f80565b85549091506000906200121b9060019062001f80565b9050818114620012875760008660000182815481106200123f576200123f62001de1565b906000526020600020015490508087600001848154811062001265576200126562001de1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200129b576200129b620020fb565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e97565b600091505062000e97565b5092915050565b6000818152600183016020526040812054620013325750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e97565b50600062000e97565b6060824710156200139e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000084565b600080866001600160a01b03168587604051620013bc919062002137565b60006040518083038185875af1925050503d8060008114620013fb576040519150601f19603f3d011682016040523d82523d6000602084013e62001400565b606091505b50909250905062001414878383876200141f565b979650505050505050565b60608315620014935782516000036200148b576001600160a01b0385163b6200148b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000084565b508162000ef1565b62000ef18383815115620014aa5781518083602001fd5b8060405162461bcd60e51b815260040162000084919062002155565b634e487b7160e01b600052604160045260246000fd5b6040516101a081016001600160401b0381118282101715620015025762001502620014c6565b60405290565b60405160a081016001600160401b0381118282101715620015025762001502620014c6565b60405160e081016001600160401b0381118282101715620015025762001502620014c6565b604080519081016001600160401b0381118282101715620015025762001502620014c6565b60405161010081016001600160401b0381118282101715620015025762001502620014c6565b604051601f8201601f191681016001600160401b0381118282101715620015c857620015c8620014c6565b604052919050565b80516001600160a01b0381168114620015e857600080fd5b919050565b80516001600160401b0381168114620015e857600080fd5b805161ffff81168114620015e857600080fd5b805163ffffffff81168114620015e857600080fd5b80518015158114620015e857600080fd5b60006101a082840312156200165257600080fd5b6200165c620014dc565b90506200166982620015d0565b8152620016796020830162001605565b60208201526200168c6040830162001618565b60408201526200169f6060830162001605565b6060820152620016b26080830162001618565b6080820152620016c560a0830162001605565b60a0820152620016d860c0830162001605565b60c0820152620016eb60e08301620015d0565b60e08201526101006200170081840162001618565b908201526101206200171483820162001618565b908201526101406200172883820162001605565b908201526101606200173c83820162001618565b90820152610180620017508382016200162d565b9082015292915050565b80516001600160801b0381168114620015e857600080fd5b6000606082840312156200178557600080fd5b604051606081016001600160401b0381118282101715620017aa57620017aa620014c6565b604052905080620017bb836200162d565b8152620017cb602084016200175a565b6020820152620017de604084016200175a565b60408201525092915050565b60006001600160401b03821115620018065762001806620014c6565b5060051b60200190565b600082601f8301126200182257600080fd5b815160206200183b6200183583620017ea565b6200159d565b82815260a092830285018201928282019190878511156200185b57600080fd5b8387015b85811015620018e85781818a031215620018795760008081fd5b6200188362001508565b6200188e82620015d0565b81526200189d86830162001618565b868201526040620018b0818401620015ed565b908201526060620018c3838201620015ed565b908201526080620018d68382016200162d565b9082015284529284019281016200185f565b5090979650505050505050565b600082601f8301126200190757600080fd5b815160206200191a6200183583620017ea565b82815260e092830285018201928282019190878511156200193a57600080fd5b8387015b85811015620018e85781818a031215620019585760008081fd5b620019626200152d565b6200196d82620015d0565b81526200197c86830162001618565b8682015260406200198f81840162001618565b908201526060620019a283820162001605565b908201526080620019b583820162001618565b9082015260a0620019c883820162001618565b9082015260c0620019db8382016200162d565b9082015284529284019281016200193e565b600082601f830112620019ff57600080fd5b8151602062001a126200183583620017ea565b82815260069290921b8401810191818101908684111562001a3257600080fd5b8286015b8481101562001a88576040818903121562001a515760008081fd5b62001a5b62001552565b62001a6682620015d0565b815262001a7585830162001605565b8186015283529183019160400162001a36565b509695505050505050565b60008060008060008086880361036081121562001aaf57600080fd5b6101008082121562001ac057600080fd5b62001aca62001577565b915062001ad789620015d0565b825262001ae760208a01620015ed565b602083015262001afa60408a01620015ed565b604083015262001b0d60608a01620015ed565b606083015260808901516001600160601b038116811462001b2d57600080fd5b608083015262001b4060a08a01620015d0565b60a083015262001b5360c08a01620015d0565b60c083015262001b6660e08a01620015d0565b60e083015281975062001b7c8a828b016200163e565b9650505062001b90886102a0890162001772565b6103008801519094506001600160401b038082111562001baf57600080fd5b62001bbd8a838b0162001810565b945061032089015191508082111562001bd557600080fd5b62001be38a838b01620018f5565b935061034089015191508082111562001bfb57600080fd5b5062001c0a89828a01620019ed565b9150509295509295509295565b80516001600160a01b03168252602081015162001c3a602084018261ffff169052565b50604081015162001c53604084018263ffffffff169052565b50606081015162001c6a606084018261ffff169052565b50608081015162001c83608084018263ffffffff169052565b5060a081015162001c9a60a084018261ffff169052565b5060c081015162001cb160c084018261ffff169052565b5060e081015162001ccd60e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015190911690830152610180908101511515910152565b82516001600160a01b031681526020808401516001600160401b0390811691830191909152604080850151821690830152606080850151918216908301526102a082019050608084015162001d7c60808401826001600160601b03169052565b5060a084015162001d9860a08401826001600160a01b03169052565b5060c084015162001db460c08401826001600160a01b03169052565b5060e084015162001dd060e08401826001600160a01b03169052565b5062000ed261010083018462001c17565b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000919060409081850190868401855b8281101562001e7957815180516001600160a01b031685528681015163ffffffff1687860152858101516001600160401b03908116878701526060808301519091169086015260809081015115159085015260a0909301929085019060010162001e14565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b8281101562001e7957815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e0909301929085019060010162001ea3565b6020808252825182820181905260009190848201906040850190845b8181101562001f5e5783516001600160a01b03168352928401929184019160010162001f37565b50909695505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000e975762000e9762001f6a565b60008162001fa85762001fa862001f6a565b506000190190565b63ffffffff818116838216019080821115620012e257620012e262001f6a565b6000604080830163ffffffff8616845260206040602086015281865180845260608701915060208801935060005b818110156200203257845180516001600160a01b0316845284015161ffff1684840152938301939185019160010162001ffe565b509098975050505050505050565b808202811582820484141762000e975762000e9762001f6a565b6000826200207857634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b03828116828216039080821115620012e257620012e262001f6a565b600060208284031215620020b357600080fd5b5051919050565b8181036000831280158383131683831282161715620012e257620012e262001f6a565b600060208284031215620020f057600080fd5b62000ed2826200162d565b634e487b7160e01b600052603160045260246000fd5b60005b838110156200212e57818101518382015260200162002114565b50506000910152565b600082516200214b81846020870162002111565b9190910192915050565b60208152600082518060208401526200217681604085016020870162002111565b601f01601f19169190910160400192915050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f75620022b86000396000818161036101528181610efa0152613786015260008181610332015281816116f80152613757015260008181610303015281816113ae0152818161141301528181611c7401528181611d02015261372801526000818161026f01528181610a30015281816118200152818161222201528181612b42015261369401526000818161023f01528181611dd30152613664015260008181610210015281816110a50152818161162401528181611a4101528181611b42015281816126dd015281816136350152613a240152600081816102cf01528181611c0e01526136f401526000818161029f0152818161283801526136c4015260006124b60152615f756000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80637437ff9f116100f9578063c92b283211610097578063eff7cc4811610071578063eff7cc48146109de578063f25561fd146109e6578063f2fde38b146109f9578063fbca3b7414610a0c57600080fd5b8063c92b2832146109b0578063d09dc339146109c3578063df0aa9e9146109cb57600080fd5b8063856c8247116100d3578063856c8247146108825780638da5cb5b146108955780639a113c36146108a6578063b06d41bc1461099a57600080fd5b80637437ff9f146106c057806376f6ae761461086757806379ba50971461087a57600080fd5b806348a98aa411610166578063549e946f11610140578063549e946f1461066957806354b714681461067c578063599f64311461069c578063704b6c02146106ad57600080fd5b806348a98aa4146105c7578063504bffe0146105f2578063546719cd1461060557600080fd5b806320487ded1161019757806320487ded146105705780634120fccd146105915780634816f4f7146105b257600080fd5b806306285c69146101be5780631772047e146103a7578063181f5a7714610527575b600080fd5b6103916040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091526040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60405161039e9190614b86565b60405180910390f35b6104bb6103b5366004614bba565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152506001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c082015290565b60405161039e9190600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b6105636040518060400160405280601381526020017f45564d3245564d4f6e52616d7020312e352e300000000000000000000000000081525081565b60405161039e9190614c27565b61058361057e366004614c68565b610a2c565b60405190815260200161039e565b610599610e82565b60405167ffffffffffffffff909116815260200161039e565b6105c56105c0366004614e76565b610ea9565b005b6105da6105d5366004614fb3565b610ebf565b6040516001600160a01b03909116815260200161039e565b6105c5610600366004614fec565b610f6e565b61060d610f82565b60405161039e919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6105c56106773660046150ea565b611014565b600e546040516bffffffffffffffffffffffff909116815260200161039e565b6002546001600160a01b03166105da565b6105c56106bb366004614bba565b61118d565b61085a604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915250604080516101a0810182526005546001600160a01b038082168352600160a01b820461ffff9081166020850152760100000000000000000000000000000000000000000000830463ffffffff908116958501959095527a0100000000000000000000000000000000000000000000000000008304811660608501527c0100000000000000000000000000000000000000000000000000000000928390048516608085015260065480821660a086015262010000808204831660c0870152640100000000820490931660e08601527801000000000000000000000000000000000000000000000000810486166101008601529290920484166101208401526007549182166101408401528104909216610160820152660100000000000090910460ff16151561018082015290565b60405161039e9190615206565b6105c5610875366004615215565b611257565b6105c56112ba565b610599610890366004614bba565b611383565b6000546001600160a01b03166105da565b6109506108b4366004614bba565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b03166000908152600b60209081526040918290208251608081018452905463ffffffff8116825267ffffffffffffffff64010000000082048116938301939093526c0100000000000000000000000081049092169281019290925260ff600160a01b909104161515606082015290565b60408051825163ffffffff16815260208084015167ffffffffffffffff9081169183019190915283830151169181019190915260609182015115159181019190915260800161039e565b6109a261147e565b60405161039e9291906152de565b6105c56109be366004615320565b611579565b6105836115e1565b6105836109d936600461538e565b6116a1565b6105c561252a565b6105c56109f43660046153fa565b6127af565b6105c5610a07366004614bba565b6127c0565b610a1f610a1a3660046154f9565b6127d1565b60405161039e9190615516565b60007f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168367ffffffffffffffff1614610aac576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6000610ac3610abe6080850185615563565b612805565b9050610af3610ad56020850185615563565b8351909150610ae760408701876155c8565b90508460200151612992565b6000600b81610b086080870160608801614bba565b6001600160a01b0316815260208082019290925260409081016000208151608081018352905463ffffffff81168252640100000000810467ffffffffffffffff908116948301949094526c01000000000000000000000000810490931691810191909152600160a01b90910460ff16151560608201819052909150610bd557610b976080850160608601614bba565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b600654600090819064010000000090046001600160a01b031663ffdb4b37610c036080890160608a01614bba565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff8a1660248201526044016040805180830381865afa158015610c6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c92919061565c565b90925090506000808080610ca960408b018b6155c8565b90501115610ce357610cd7610cc460808b0160608c01614bba565b86610cd260408d018d6155c8565b612af7565b91945092509050610cff565b8551610cfc9063ffffffff16662386f26fc100006156a5565b92505b60065460009062010000900461ffff1615610d5357610d506dffffffffffffffffffffffffffff607087901c16610d3960208d018d615563565b9050610d4860408e018e6155c8565b905085612ec6565b90505b60208781015160055460009267ffffffffffffffff9092169163ffffffff8716917a010000000000000000000000000000000000000000000000000000900461ffff1690610da3908f018f615563565b610dae9291506156a5565b6005548c51610ddd91760100000000000000000000000000000000000000000000900463ffffffff16906156bc565b610de791906156bc565b610df191906156bc565b610e0b906dffffffffffffffffffffffffffff89166156a5565b610e1591906156a5565b9050867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1682828a6040015167ffffffffffffffff1688610e5291906156a5565b610e5c91906156bc565b610e6691906156bc565b610e7091906156cf565b99505050505050505050505b92915050565b600e54600090610ea490600160801b900467ffffffffffffffff1660016156f1565b905090565b610eb1612f97565b610ebb8282612fef565b5050565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190615712565b9392505050565b610f76613371565b610f7f816133cb565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff8082168352600160801b80830463ffffffff166020850152600160a01b90920460ff161515938301939093526004548084166060840152049091166080820152610ea4906137c0565b61101c612f97565b6001600160a01b03811661105c576040517f232cb97f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006110666115e1565b905060008112156110a3576040517f02075e0000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316036110f5576110f06001600160a01b0384168383613872565b505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526110f09083906001600160a01b038616906370a0823190602401602060405180830381865afa158015611158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117c919061572f565b6001600160a01b0386169190613872565b6000546001600160a01b031633148015906111b357506002546001600160a01b03163314155b156111ea576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b61125f612f97565b610ebb8282808060200260200160405190810160405280939291908181526020016000905b828210156112b0576112a160408302860136819003810190615748565b81526020019060010190611284565b50505050506138f2565b6001546001600160a01b031633146113145760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610aa3565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b038082166000908152600d6020526040812054909167ffffffffffffffff909116907f00000000000000000000000000000000000000000000000000000000000000001615610e7c5780600003610e7c576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa15801561145a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190615787565b606060008061148d6008613b58565b90508067ffffffffffffffff8111156114a8576114a8614cb8565b6040519080825280602002602001820160405280156114ed57816020015b60408051808201909152600080825260208201528152602001906001900390816114c65790505b50925060005b8181101561155657600080611509600884613b63565b915091506040518060400160405280836001600160a01b031681526020018261ffff16815250868481518110611541576115416157a4565b602090810291909101015250506001016114f3565b5050600e5491926c0100000000000000000000000090920463ffffffff16919050565b6000546001600160a01b0316331480159061159f57506002546001600160a01b03163314155b156115d6576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f7f600382613b81565b600e546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916bffffffffffffffffffffffff16907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611673573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611697919061572f565b610ea491906157ba565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608086901b1660048201526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561173f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176391906157da565b1561179a576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0382166117da576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b0316331461181e576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168567ffffffffffffffff1614611897576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610aa3565b60006118a9610abe6080870187615563565b905060006118ba60408701876155c8565b91506118e090506118ce6020880188615563565b90508360000151838560200151612992565b8015611a37576000805b82811015611a25576118ff60408901896155c8565b8281811061190f5761190f6157a4565b90506040020160200135600003611952576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c600061196360408b018b6155c8565b84818110611973576119736157a4565b6119899260206040909202019081019150614bba565b6001600160a01b031681526020810191909152604001600020547201000000000000000000000000000000000000900460ff1615611a1d57611a106119d160408a018a6155c8565b838181106119e1576119e16157a4565b9050604002018036038101906119f791906157f7565b60065464010000000090046001600160a01b0316613d14565b611a1a90836156bc565b91505b6001016118ea565b508015611a3557611a3581613e35565b505b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016611a716080880160608901614bba565b6001600160a01b031603611ad557600e8054869190600090611aa29084906bffffffffffffffffffffffff16615831565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550611bfc565b60065464010000000090046001600160a01b03166241e5be611afd6080890160608a01614bba565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018990527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa158015611b89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bad919061572f565b600e8054600090611bcd9084906bffffffffffffffffffffffff16615831565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b600e546bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811691161115611c69576040517fe5c7a49100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160200151611dbd577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615611dbd576001600160a01b0384166000908152600d602052604081205467ffffffffffffffff169003611dbd576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611d49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6d9190615787565b6001600160a01b0385166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790555b604080516101a08101825267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526001600160a01b03861660208201526000918101611e50611e168a80615563565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613e4292505050565b6001600160a01b03168152602001600e601081819054906101000a900467ffffffffffffffff16611e8090615856565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff168152602001846000015181526020016000151581526020018460200151611f2a576001600160a01b0387166000908152600d602052604081208054909190611f009067ffffffffffffffff16615856565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055611f2d565b60005b67ffffffffffffffff168152602001611f4c60808a0160608b01614bba565b6001600160a01b03168152602001878152602001888060200190611f709190615563565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001611fb760408a018a6155c8565b808060200260200160405190810160405280939291908181526020016000905b8282101561200357611ff4604083028601368190038101906157f7565b81526020019060010190611fd7565b505050505081526020018367ffffffffffffffff81111561202657612026614cb8565b60405190808252806020026020018201604052801561205957816020015b60608152602001906001900390816120445790505b508152600060209091018190529091505b828110156124af57600061208160408a018a6155c8565b83818110612091576120916157a4565b9050604002018036038101906120a791906157f7565b905060006120b98b8360000151610ebf565b90506001600160a01b038116158061216f57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa158015612149573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216d91906157da565b155b156121b45781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b6000816001600160a01b0316639a4575b96040518060a001604052808e80600001906121e09190615563565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525067ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166020808301919091526001600160a01b03808f16604080850191909152918901516060840152885116608090920191909152517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526122ab919060040161587d565b6000604051808303816000875af11580156122ca573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526122f2919081019061594a565b9050602063ffffffff1681602001515111156123895782516001600160a01b03166000908152600c602090815260409091205490820151516e01000000000000000000000000000090910463ffffffff1610156123895782516040517f36f536ca0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b805161239490613e42565b5060408051608081019091526001600160a01b03831660a08201528060c0810160408051808303601f190181529181529082528351602080840191909152808501518383015286516001600160a01b03166000908152600c9091522054606090910190730100000000000000000000000000000000000000900460ff166124295760075462010000900463ffffffff16612458565b84516001600160a01b03166000908152600c60205260409020546a0100000000000000000000900463ffffffff165b63ffffffff16905260405161247091906020016159db565b6040516020818303038152906040528561016001518581518110612496576124966157a4565b602002602001018190525050505080600101905061206a565b506124da817f0000000000000000000000000000000000000000000000000000000000000000613ee8565b6101808201526040517fd0c3c799bf9e2639de44391e7f524d229b2b55f5b1ea94b2bf7da42f7243dddd90612510908390615aef565b60405180910390a16101800151925050505b949350505050565b6000546001600160a01b0316331461258f576002546001600160a01b0316331461258f57612559600833614043565b61258f576040517f195db95800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff1660008190036125e3576040517f990e30bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546bffffffffffffffffffffffff168181101561262e576040517f8d0f71d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006126386115e1565b1215612670576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600061267d6008613b58565b905060005b8181101561276c57600080612698600884613b63565b90925090506000876126b8836bffffffffffffffffffffffff8a166156a5565b6126c291906156cf565b90506126ce8187615c24565b95506127126001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846bffffffffffffffffffffffff8416613872565b6040516bffffffffffffffffffffffff821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a2505050806001019050612682565b5050600e80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff929092169190911790555050565b6127b7612f97565b610f7f81614058565b6127c8613371565b610f7f816141ca565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260008082526020820152600082900361286657506040805180820190915267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260006020820152610e7c565b60006128728385615c49565b90507fe7e230f0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016128df576128ca8360048187615c91565b8101906128d79190615cbb565b915050610e7c565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016129605760408051808201909152806129408560048189615c91565b81019061294d9190615ce7565b815260006020909101529150610e7c9050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006547801000000000000000000000000000000000000000000000000900463ffffffff16808511156129fb576040517f869337890000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610aa3565b6006547c0100000000000000000000000000000000000000000000000000000000900463ffffffff16841115612a5d576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554600160a01b900461ffff16831115612aa4576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81612af0576007546601000000000000900460ff1615612af0576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000808083815b81811015612eba576000878783818110612b1a57612b1a6157a4565b905060400201803603810190612b3091906157f7565b905060006001600160a01b0316612b6b7f00000000000000000000000000000000000000000000000000000000000000008360000151610ebf565b6001600160a01b031603612bb95780516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b80516001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c08201819052612cde57600754612ca29061ffff16662386f26fc100006156a5565b612cac90886156bc565b600754909750612cc89062010000900463ffffffff1687615d00565b9550612cd5602086615d00565b94505050612eb2565b604081015160009061ffff1615612e025760008c6001600160a01b031684600001516001600160a01b031614612da55760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526401000000009092041690634ab35b0b90602401602060405180830381865afa158015612d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d9e9190615d1d565b9050612da8565b508a5b620186a0836040015161ffff16612dea8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661428b90919063ffffffff16565b612df491906156a5565b612dfe91906156cf565b9150505b6060820151612e119088615d00565b9650816080015186612e239190615d00565b8251909650600090612e429063ffffffff16662386f26fc100006156a5565b905080821015612e6157612e56818a6156bc565b985050505050612eb2565b6000836020015163ffffffff16662386f26fc10000612e8091906156a5565b905080831115612ea057612e94818b6156bc565b99505050505050612eb2565b612eaa838b6156bc565b995050505050505b600101612afe565b50509450945094915050565b60008063ffffffff8316612edc610180866156a5565b612ee8876102206156bc565b612ef291906156bc565b612efc91906156bc565b6005546006549192506000917c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690612f3e9061ffff16846156a5565b612f4891906156bc565b60065490915062010000900461ffff16612f726dffffffffffffffffffffffffffff8916836156a5565b612f7c91906156a5565b612f8c90655af3107a40006156a5565b979650505050505050565b6000546001600160a01b03163314612fed576002546001600160a01b03163314612fed576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60005b825181101561328357600083828151811061300f5761300f6157a4565b60200260200101519050602063ffffffff168160a0015163ffffffff16101561308257805160a08201516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526001600160a01b03909216600483015263ffffffff166024820152604401610aa3565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009096169590951764010000000092871692909202919091177fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff166801000000000000000093909216929092027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff16176a010000000000000000000091841691909102177fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff166e01000000000000000000000000000093909216929092027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1617720100000000000000000000000000000000000094151594909402939093177fffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff16730100000000000000000000000000000000000000931515939093029290921790915501612ff2565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d0826040516132b39190615d38565b60405180910390a160005b815181101561332e57600c60008383815181106132dd576132dd6157a4565b6020908102919091018101516001600160a01b0316825281019190915260400160002080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556001016132be565b50805115610ebb577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b816040516133659190615516565b60405180910390a15050565b6000546001600160a01b03163314612fed5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610aa3565b60e08101516001600160a01b031661340f576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548160ff0219169083151502179055509050507f45b5ad483aa608464c2c7f278bd413d284d7790cdc836e40652e23a0277082206040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152508260405161124c929190615dd8565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261384e82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426138329190615df5565b85608001516fffffffffffffffffffffffffffffffff166142c8565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526110f09084906142f0565b8051604081111561392f576040517fb5a10cfa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff161561398357600e5463ffffffff6c010000000000000000000000008204166bffffffffffffffffffffffff909116106139835761398361252a565b600061398f6008613b58565b90505b80156139d15760006139b06139a8600184615df5565b600890613b63565b5090506139be6008826143d5565b5050806139ca90615e08565b9050613992565b506000805b82811015613ad95760008482815181106139f2576139f26157a4565b60200260200101516000015190506000858381518110613a1457613a146157a4565b60200260200101516020015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480613a6957506001600160a01b038216155b15613aab576040517f4de938d10000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610aa3565b613abb60088361ffff84166143ea565b50613aca61ffff821685615d00565b935050508060010190506139d6565b50600e80547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd2490613b4b9083908690615e3d565b60405180910390a1505050565b6000610e7c82614400565b6000808080613b72868661440b565b909450925050505b9250929050565b8154600090613b9d90600160801b900463ffffffff1642615df5565b90508015613c255760018301548354613bd8916fffffffffffffffffffffffffffffffff808216928116918591600160801b909104166142c8565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617600160801b4263ffffffff16021783555b60208201518354613c4b916fffffffffffffffffffffffffffffffff9081169116614436565b835483511515600160a01b027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff9283161717845560208301516040808501518316600160801b0291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990613b4b9084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d9e9190615e5c565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613e075783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b6020840151612522907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83169061428b565b610f7f600382600061444c565b60008151602014613e8157816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610aa39190614c27565b600082806020019051810190613e97919061572f565b90506001600160a01b03811180613eaf575061040081105b15610e7c57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610aa39190614c27565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001613f7e9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001613fb79190615e8f565b60405160208183030381529060405280519060200120876101600151604051602001613fe39190615ea2565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b6000610f67836001600160a01b038416614756565b60005b815181101561419a576000828281518110614078576140786157a4565b60209081029190910181015160408051608080820183528385015163ffffffff90811683528385015167ffffffffffffffff908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9688166c0100000000000000000000000002969096167fffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009095169116179290921791909116929092171790555060010161405b565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e8160405161124c9190615eb5565b336001600160a01b038216036142225760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610aa3565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a76400006142be837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166156a5565b610f6791906156cf565b60006142e7856142d884866156a5565b6142e290876156bc565b614436565b95945050505050565b6000614345826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166147629092919063ffffffff16565b8051909150156110f0578080602001905181019061436391906157da565b6110f05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa3565b6000610f67836001600160a01b038416614771565b6000612522846001600160a01b0385168461478e565b6000610e7c826147ab565b6000808061441985856147b5565b600081815260029690960160205260409095205494959350505050565b60008183106144455781610f67565b5090919050565b8254600160a01b900460ff161580614462575081155b1561446c57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906144a590600160801b900463ffffffff1642615df5565b9050801561454b57818311156144e7576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461451490839085908490600160801b90046fffffffffffffffffffffffffffffffff166142c8565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff16600160801b4263ffffffff160217875592505b848210156145e8576001600160a01b03841661459d576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610aa3565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610aa3565b848310156146d457600186810154600160801b90046fffffffffffffffffffffffffffffffff1690600090829061461f9082615df5565b614629878a615df5565b61463391906156bc565b61463d91906156cf565b90506001600160a01b038616614689576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610aa3565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610aa3565b6146de8584615df5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f6783836147c1565b606061252284846000856147d9565b60008181526002830160205260408120819055610f6783836148c0565b6000828152600284016020526040812082905561252284846148cc565b6000610e7c825490565b6000610f6783836148d8565b60008181526001830160205260408120541515610f67565b6060824710156148515760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa3565b600080866001600160a01b0316858760405161486d9190615f36565b60006040518083038185875af1925050503d80600081146148aa576040519150601f19603f3d011682016040523d82523d6000602084013e6148af565b606091505b5091509150612f8c87838387614902565b6000610f67838361497b565b6000610f678383614a75565b60008260000182815481106148ef576148ef6157a4565b9060005260206000200154905092915050565b6060831561497157825160000361496a576001600160a01b0385163b61496a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa3565b5081612522565b6125228383614ac4565b60008181526001830160205260408120548015614a6457600061499f600183615df5565b85549091506000906149b390600190615df5565b9050818114614a185760008660000182815481106149d3576149d36157a4565b90600052602060002001549050808760000184815481106149f6576149f66157a4565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614a2957614a29615f52565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610e7c565b6000915050610e7c565b5092915050565b6000818152600183016020526040812054614abc57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e7c565b506000610e7c565b815115614ad45781518083602001fd5b8060405162461bcd60e51b8152600401610aa39190614c27565b6001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401525060c0810151614b6b60c08401826001600160a01b03169052565b5060e08101516110f060e08401826001600160a01b03169052565b6101008101610e7c8284614aee565b6001600160a01b0381168114610f7f57600080fd5b8035614bb581614b95565b919050565b600060208284031215614bcc57600080fd5b8135610f6781614b95565b60005b83811015614bf2578181015183820152602001614bda565b50506000910152565b60008151808452614c13816020860160208601614bd7565b601f01601f19169290920160200192915050565b602081526000610f676020830184614bfb565b67ffffffffffffffff81168114610f7f57600080fd5b600060a08284031215614c6257600080fd5b50919050565b60008060408385031215614c7b57600080fd5b8235614c8681614c3a565b9150602083013567ffffffffffffffff811115614ca257600080fd5b614cae85828601614c50565b9150509250929050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b60405290565b6040516101a0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b60405160a0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b6040805190810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b604051601f8201601f1916810167ffffffffffffffff81118282101715614d8a57614d8a614cb8565b604052919050565b600067ffffffffffffffff821115614dac57614dac614cb8565b5060051b60200190565b63ffffffff81168114610f7f57600080fd5b8035614bb581614db6565b803561ffff81168114614bb557600080fd5b8015158114610f7f57600080fd5b8035614bb581614de5565b600082601f830112614e0f57600080fd5b81356020614e24614e1f83614d92565b614d61565b8083825260208201915060208460051b870101935086841115614e4657600080fd5b602086015b84811015614e6b578035614e5e81614b95565b8352918301918301614e4b565b509695505050505050565b6000806040808486031215614e8a57600080fd5b833567ffffffffffffffff80821115614ea257600080fd5b818601915086601f830112614eb657600080fd5b81356020614ec6614e1f83614d92565b82815260e0928302850182019282820191908b851115614ee557600080fd5b958301955b84871015614f8e5780878d031215614f025760008081fd5b614f0a614cce565b8735614f1581614b95565b815287850135614f2481614db6565b8186015287890135614f3581614db6565b818a01526060614f46898201614dd3565b90820152608088810135614f5981614db6565b9082015260a0614f6a898201614dc8565b9082015260c0614f7b898201614df3565b9082015283529586019591830191614eea565b5097505087013593505080831115614fa557600080fd5b5050614cae85828601614dfe565b60008060408385031215614fc657600080fd5b8235614fd181614c3a565b91506020830135614fe181614b95565b809150509250929050565b60006101a08284031215614fff57600080fd5b615007614cf7565b61501083614baa565b815261501e60208401614dd3565b602082015261502f60408401614dc8565b604082015261504060608401614dd3565b606082015261505160808401614dc8565b608082015261506260a08401614dd3565b60a082015261507360c08401614dd3565b60c082015261508460e08401614baa565b60e0820152610100615097818501614dc8565b908201526101206150a9848201614dc8565b908201526101406150bb848201614dd3565b908201526101606150cd848201614dc8565b908201526101806150df848201614df3565b908201529392505050565b600080604083850312156150fd57600080fd5b8235614fd181614b95565b80516001600160a01b03168252602081015161512a602084018261ffff169052565b506040810151615142604084018263ffffffff169052565b506060810151615158606084018261ffff169052565b506080810151615170608084018263ffffffff169052565b5060a081015161518660a084018261ffff169052565b5060c081015161519c60c084018261ffff169052565b5060e08101516151b760e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015190911690830152610180908101511515910152565b6101a08101610e7c8284615108565b6000806020838503121561522857600080fd5b823567ffffffffffffffff8082111561524057600080fd5b818501915085601f83011261525457600080fd5b81358181111561526357600080fd5b8660208260061b850101111561527857600080fd5b60209290920196919550909350505050565b60008151808452602080850194506020840160005b838110156152d357815180516001600160a01b0316885283015161ffff16838801526040909601959082019060010161529f565b509495945050505050565b6040815260006152f1604083018561528a565b90508260208301529392505050565b80356fffffffffffffffffffffffffffffffff81168114614bb557600080fd5b60006060828403121561533257600080fd5b6040516060810181811067ffffffffffffffff8211171561535557615355614cb8565b604052823561536381614de5565b815261537160208401615300565b602082015261538260408401615300565b60408201529392505050565b600080600080608085870312156153a457600080fd5b84356153af81614c3a565b9350602085013567ffffffffffffffff8111156153cb57600080fd5b6153d787828801614c50565b9350506040850135915060608501356153ef81614b95565b939692955090935050565b6000602080838503121561540d57600080fd5b823567ffffffffffffffff81111561542457600080fd5b8301601f8101851361543557600080fd5b8035615443614e1f82614d92565b81815260a0918202830184019184820191908884111561546257600080fd5b938501935b838510156154ed5780858a03121561547f5760008081fd5b615487614d1b565b853561549281614b95565b8152858701356154a181614db6565b818801526040868101356154b481614c3a565b908201526060868101356154c781614c3a565b908201526080868101356154da81614de5565b9082015283529384019391850191615467565b50979650505050505050565b60006020828403121561550b57600080fd5b8135610f6781614c3a565b6020808252825182820181905260009190848201906040850190845b818110156155575783516001600160a01b031683529284019291840191600101615532565b50909695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261559857600080fd5b83018035915067ffffffffffffffff8211156155b357600080fd5b602001915036819003821315613b7a57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155fd57600080fd5b83018035915067ffffffffffffffff82111561561857600080fd5b6020019150600681901b3603821315613b7a57600080fd5b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114614bb557600080fd5b6000806040838503121561566f57600080fd5b61567883615630565b915061568660208401615630565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e7c57610e7c61568f565b80820180821115610e7c57610e7c61568f565b6000826156ec57634e487b7160e01b600052601260045260246000fd5b500490565b67ffffffffffffffff818116838216019080821115614a6e57614a6e61568f565b60006020828403121561572457600080fd5b8151610f6781614b95565b60006020828403121561574157600080fd5b5051919050565b60006040828403121561575a57600080fd5b615762614d3e565b823561576d81614b95565b815261577b60208401614dd3565b60208201529392505050565b60006020828403121561579957600080fd5b8151610f6781614c3a565b634e487b7160e01b600052603260045260246000fd5b8181036000831280158383131683831282161715614a6e57614a6e61568f565b6000602082840312156157ec57600080fd5b8151610f6781614de5565b60006040828403121561580957600080fd5b615811614d3e565b823561581c81614b95565b81526020928301359281019290925250919050565b6bffffffffffffffffffffffff818116838216019080821115614a6e57614a6e61568f565b600067ffffffffffffffff8083168181036158735761587361568f565b6001019392505050565b602081526000825160a0602084015261589960c0840182614bfb565b905067ffffffffffffffff602085015116604084015260408401516001600160a01b038082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600082601f8301126158f757600080fd5b815167ffffffffffffffff81111561591157615911614cb8565b6159246020601f19601f84011601614d61565b81815284602083860101111561593957600080fd5b612522826020830160208701614bd7565b60006020828403121561595c57600080fd5b815167ffffffffffffffff8082111561597457600080fd5b908301906040828603121561598857600080fd5b615990614d3e565b82518281111561599f57600080fd5b6159ab878286016158e6565b8252506020830151828111156159c057600080fd5b6159cc878286016158e6565b60208301525095945050505050565b6020815260008251608060208401526159f760a0840182614bfb565b90506020840151601f1980858403016040860152615a158383614bfb565b9250604086015191508085840301606086015250615a338282614bfb565b91505063ffffffff60608501511660808401528091505092915050565b60008151808452602080850194506020840160005b838110156152d357815180516001600160a01b031688528301518388015260409096019590820190600101615a65565b60008282518085526020808601955060208260051b8401016020860160005b84811015615ae257601f19868403018952615ad0838351614bfb565b98840198925090830190600101615ab4565b5090979650505050505050565b60208152615b0a60208201835167ffffffffffffffff169052565b60006020830151615b2660408401826001600160a01b03169052565b5060408301516001600160a01b038116606084015250606083015167ffffffffffffffff8116608084015250608083015160a083015260a0830151615b6f60c084018215159052565b5060c083015167ffffffffffffffff811660e08401525060e0830151610100615ba2818501836001600160a01b03169052565b840151610120848101919091528401516101a061014080860182905291925090615bd06101c0860184614bfb565b9250808601519050601f19610160818786030181880152615bf18584615a50565b945080880151925050610180818786030181880152615c108584615a95565b970151959092019490945250929392505050565b6bffffffffffffffffffffffff828116828216039080821115614a6e57614a6e61568f565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015615c895780818660040360031b1b83161692505b505092915050565b60008085851115615ca157600080fd5b83861115615cae57600080fd5b5050820193919092039150565b600060408284031215615ccd57600080fd5b615cd5614d3e565b82358152602083013561577b81614de5565b600060208284031215615cf957600080fd5b5035919050565b63ffffffff818116838216019080821115614a6e57614a6e61568f565b600060208284031215615d2f57600080fd5b610f6782615630565b602080825282518282018190526000919060409081850190868401855b82811015615dcb57815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e09093019290850190600101615d55565b5091979650505050505050565b6102a08101615de78285614aee565b610f67610100830184615108565b81810381811115610e7c57610e7c61568f565b600081615e1757615e1761568f565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b63ffffffff83168152604060208201526000612522604083018461528a565b600060408284031215615e6e57600080fd5b615e76614d3e565b615e7f83615630565b8152602083015161577b81614db6565b602081526000610f676020830184615a50565b602081526000610f676020830184615a95565b602080825282518282018190526000919060409081850190868401855b82811015615dcb57815180516001600160a01b031685528681015163ffffffff16878601528581015167ffffffffffffffff908116878701526060808301519091169086015260809081015115159085015260a09093019290850190600101615ed2565b60008251615f48818460208701614bd7565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfea164736f6c6343000818000a", + Bin: "0x6101a06040523480156200001257600080fd5b506040516200822d3803806200822d833981016040819052620000359162001a93565b8333806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c0816200030b565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555085516001600160a01b0316158062000169575060208601516001600160401b0316155b8062000180575060408601516001600160401b0316155b8062000197575060608601516001600160401b0316155b80620001ae575060c08601516001600160a01b0316155b80620001c5575060e08601516001600160a01b0316155b15620001e4576040516306b7c75960e31b815260040160405180910390fd5b60208087015160408089015181517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3948101949094526001600160401b039283169184019190915216606082015230608082015260a00160408051601f198184030181529181528151602092830120608090815288516001600160a01b0390811660e0908152938a01516001600160401b0390811661010052928a015183166101205260608a015190921660a0908152908901516001600160601b031660c090815290890151821661014052880151811661016052908701511661018052620002cd85620003b6565b620002d883620006ad565b604080516000815260208101909152620002f4908390620007dd565b620002ff8162000a83565b5050505050506200218a565b336001600160a01b03821603620003655760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e08101516001600160a01b0316620003e2576040516306b7c75960e31b815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548160ff0219169083151502179055509050507f45b5ad483aa608464c2c7f278bd413d284d7790cdc836e40652e23a02770822060405180610100016040528060e0516001600160a01b03168152602001610100516001600160401b03168152602001610120516001600160401b0316815260200160a0516001600160401b0316815260200160c0516001600160601b03168152602001610140516001600160a01b03168152602001610160516001600160a01b03168152602001610180516001600160a01b031681525082604051620006a292919062001d1c565b60405180910390a150565b60005b8151811015620007ab576000828281518110620006d157620006d162001de1565b60209081029190910181015160408051608080820183528385015163ffffffff9081168352838501516001600160401b03908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b0260ff60a01b199688166c010000000000000000000000000296909616600160601b600160a81b031993909716640100000000026001600160601b031990951691161792909217919091169290921717905550600101620006b0565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e81604051620006a2919062001df7565b60005b8251811015620009a257600083828151811062000801576200080162001de1565b60200260200101519050602063ffffffff168160a0015163ffffffff1610156200085d57805160a08201516040516312766e0160e11b81526001600160a01b03909216600483015263ffffffff16602482015260440162000084565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087166001600160401b031990961695909517640100000000928716929092029190911765ffffffffffff60401b191668010000000000000000939092169290920263ffffffff60501b1916176a0100000000000000000000918416919091021764ffffffffff60701b1916600160701b939092169290920260ff60901b191617600160901b941515949094029390931760ff60981b1916600160981b931515939093029290921790915501620007e0565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d082604051620009d4919062001e86565b60405180910390a160005b815181101562000a3c57600c600083838151811062000a025762000a0262001de1565b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055600101620009df565b5080511562000a7f577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b8160405162000a76919062001f1b565b60405180910390a15b5050565b8051604081111562000aa857604051635ad0867d60e11b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff161562000afb57600e5463ffffffff6c010000000000000000000000008204166001600160601b039091161062000afb5762000afb62000c9e565b600062000b09600862000e8a565b90505b801562000b5557600062000b2f62000b2660018462001f80565b60089062000e9d565b50905062000b3f60088262000ebb565b50508062000b4d9062001f96565b905062000b0c565b506000805b8281101562000c3557600084828151811062000b7a5762000b7a62001de1565b6020026020010151600001519050600085838151811062000b9f5762000b9f62001de1565b602002602001015160200151905060e0516001600160a01b0316826001600160a01b0316148062000bd757506001600160a01b038216155b1562000c0257604051634de938d160e01b81526001600160a01b038316600482015260240162000084565b62000c1460088361ffff841662000ed9565b5062000c2561ffff82168562001fb0565b9350505080600101905062000b5a565b50600e805463ffffffff60601b19166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249062000c91908390869062001fd0565b60405180910390a1505050565b6000546001600160a01b0316331462000cef576002546001600160a01b0316331462000cef5762000cd160083362000ef9565b62000cef5760405163032bb72b60e31b815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff16600081900362000d2b5760405163990e30bf60e01b815260040160405180910390fd5b600e546001600160601b03168181101562000d59576040516311a1ee3b60e31b815260040160405180910390fd5b600062000d6562000f10565b121562000d8557604051631e9acf1760e31b815260040160405180910390fd5b80600062000d94600862000e8a565b905060005b8181101562000e645760008062000db260088462000e9d565b909250905060008762000dcf836001600160601b038a1662002040565b62000ddb91906200205a565b905062000de981876200207d565b60e05190965062000e0e906001600160a01b0316846001600160601b03841662000f9e565b6040516001600160601b03821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a250505080600101905062000d99565b5050600e80546001600160601b0319166001600160601b03929092169190911790555050565b600062000e978262000ffb565b92915050565b600080808062000eae868662001008565b9097909650945050505050565b600062000ed2836001600160a01b03841662001035565b9392505050565b600062000ef1846001600160a01b0385168462001054565b949350505050565b600062000ed2836001600160a01b03841662001073565b600e5460e0516040516370a0823160e01b81523060048201526000926001600160601b0316916001600160a01b0316906370a0823190602401602060405180830381865afa15801562000f67573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f8d9190620020a0565b62000f999190620020ba565b905090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915262000ff69185916200108116565b505050565b600062000e978262001152565b600080806200101885856200115d565b600081815260029690960160205260409095205494959350505050565b6000818152600283016020526040812081905562000ed283836200116b565b6000828152600284016020526040812082905562000ef1848462001179565b600062000ed2838362001187565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620010d0906001600160a01b038516908490620011a0565b80519091501562000ff65780806020019051810190620010f19190620020dd565b62000ff65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000084565b600062000e97825490565b600062000ed28383620011b1565b600062000ed28383620011de565b600062000ed28383620012e9565b6000818152600183016020526040812054151562000ed2565b606062000ef184846000856200133b565b6000826000018281548110620011cb57620011cb62001de1565b9060005260206000200154905092915050565b60008181526001830160205260408120548015620012d75760006200120560018362001f80565b85549091506000906200121b9060019062001f80565b9050808214620012875760008660000182815481106200123f576200123f62001de1565b906000526020600020015490508087600001848154811062001265576200126562001de1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200129b576200129b620020fb565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e97565b600091505062000e97565b5092915050565b6000818152600183016020526040812054620013325750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e97565b50600062000e97565b6060824710156200139e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000084565b600080866001600160a01b03168587604051620013bc919062002137565b60006040518083038185875af1925050503d8060008114620013fb576040519150601f19603f3d011682016040523d82523d6000602084013e62001400565b606091505b50909250905062001414878383876200141f565b979650505050505050565b60608315620014935782516000036200148b576001600160a01b0385163b6200148b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000084565b508162000ef1565b62000ef18383815115620014aa5781518083602001fd5b8060405162461bcd60e51b815260040162000084919062002155565b634e487b7160e01b600052604160045260246000fd5b6040516101a081016001600160401b0381118282101715620015025762001502620014c6565b60405290565b60405160a081016001600160401b0381118282101715620015025762001502620014c6565b60405160e081016001600160401b0381118282101715620015025762001502620014c6565b604080519081016001600160401b0381118282101715620015025762001502620014c6565b60405161010081016001600160401b0381118282101715620015025762001502620014c6565b604051601f8201601f191681016001600160401b0381118282101715620015c857620015c8620014c6565b604052919050565b80516001600160a01b0381168114620015e857600080fd5b919050565b80516001600160401b0381168114620015e857600080fd5b805161ffff81168114620015e857600080fd5b805163ffffffff81168114620015e857600080fd5b80518015158114620015e857600080fd5b60006101a082840312156200165257600080fd5b6200165c620014dc565b90506200166982620015d0565b8152620016796020830162001605565b60208201526200168c6040830162001618565b60408201526200169f6060830162001605565b6060820152620016b26080830162001618565b6080820152620016c560a0830162001605565b60a0820152620016d860c0830162001605565b60c0820152620016eb60e08301620015d0565b60e08201526101006200170081840162001618565b908201526101206200171483820162001618565b908201526101406200172883820162001605565b908201526101606200173c83820162001618565b90820152610180620017508382016200162d565b9082015292915050565b80516001600160801b0381168114620015e857600080fd5b6000606082840312156200178557600080fd5b604051606081016001600160401b0381118282101715620017aa57620017aa620014c6565b604052905080620017bb836200162d565b8152620017cb602084016200175a565b6020820152620017de604084016200175a565b60408201525092915050565b60006001600160401b03821115620018065762001806620014c6565b5060051b60200190565b600082601f8301126200182257600080fd5b815160206200183b6200183583620017ea565b6200159d565b82815260a092830285018201928282019190878511156200185b57600080fd5b8387015b85811015620018e85781818a031215620018795760008081fd5b6200188362001508565b6200188e82620015d0565b81526200189d86830162001618565b868201526040620018b0818401620015ed565b908201526060620018c3838201620015ed565b908201526080620018d68382016200162d565b9082015284529284019281016200185f565b5090979650505050505050565b600082601f8301126200190757600080fd5b815160206200191a6200183583620017ea565b82815260e092830285018201928282019190878511156200193a57600080fd5b8387015b85811015620018e85781818a031215620019585760008081fd5b620019626200152d565b6200196d82620015d0565b81526200197c86830162001618565b8682015260406200198f81840162001618565b908201526060620019a283820162001605565b908201526080620019b583820162001618565b9082015260a0620019c883820162001618565b9082015260c0620019db8382016200162d565b9082015284529284019281016200193e565b600082601f830112620019ff57600080fd5b8151602062001a126200183583620017ea565b82815260069290921b8401810191818101908684111562001a3257600080fd5b8286015b8481101562001a88576040818903121562001a515760008081fd5b62001a5b62001552565b62001a6682620015d0565b815262001a7585830162001605565b8186015283529183019160400162001a36565b509695505050505050565b60008060008060008086880361036081121562001aaf57600080fd5b6101008082121562001ac057600080fd5b62001aca62001577565b915062001ad789620015d0565b825262001ae760208a01620015ed565b602083015262001afa60408a01620015ed565b604083015262001b0d60608a01620015ed565b606083015260808901516001600160601b038116811462001b2d57600080fd5b608083015262001b4060a08a01620015d0565b60a083015262001b5360c08a01620015d0565b60c083015262001b6660e08a01620015d0565b60e083015281975062001b7c8a828b016200163e565b9650505062001b90886102a0890162001772565b6103008801519094506001600160401b038082111562001baf57600080fd5b62001bbd8a838b0162001810565b945061032089015191508082111562001bd557600080fd5b62001be38a838b01620018f5565b935061034089015191508082111562001bfb57600080fd5b5062001c0a89828a01620019ed565b9150509295509295509295565b80516001600160a01b03168252602081015162001c3a602084018261ffff169052565b50604081015162001c53604084018263ffffffff169052565b50606081015162001c6a606084018261ffff169052565b50608081015162001c83608084018263ffffffff169052565b5060a081015162001c9a60a084018261ffff169052565b5060c081015162001cb160c084018261ffff169052565b5060e081015162001ccd60e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015190911690830152610180908101511515910152565b82516001600160a01b031681526020808401516001600160401b0390811691830191909152604080850151821690830152606080850151918216908301526102a082019050608084015162001d7c60808401826001600160601b03169052565b5060a084015162001d9860a08401826001600160a01b03169052565b5060c084015162001db460c08401826001600160a01b03169052565b5060e084015162001dd060e08401826001600160a01b03169052565b5062000ed261010083018462001c17565b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000919060409081850190868401855b8281101562001e7957815180516001600160a01b031685528681015163ffffffff1687860152858101516001600160401b03908116878701526060808301519091169086015260809081015115159085015260a0909301929085019060010162001e14565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b8281101562001e7957815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e0909301929085019060010162001ea3565b6020808252825182820181905260009190848201906040850190845b8181101562001f5e5783516001600160a01b03168352928401929184019160010162001f37565b50909695505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000e975762000e9762001f6a565b60008162001fa85762001fa862001f6a565b506000190190565b63ffffffff818116838216019080821115620012e257620012e262001f6a565b6000604080830163ffffffff8616845260206040602086015281865180845260608701915060208801935060005b818110156200203257845180516001600160a01b0316845284015161ffff1684840152938301939185019160010162001ffe565b509098975050505050505050565b808202811582820484141762000e975762000e9762001f6a565b6000826200207857634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b03828116828216039080821115620012e257620012e262001f6a565b600060208284031215620020b357600080fd5b5051919050565b8181036000831280158383131683831282161715620012e257620012e262001f6a565b600060208284031215620020f057600080fd5b62000ed2826200162d565b634e487b7160e01b600052603160045260246000fd5b60005b838110156200212e57818101518382015260200162002114565b50506000910152565b600082516200214b81846020870162002111565b9190910192915050565b60208152600082518060208401526200217681604085016020870162002111565b601f01601f19169190910160400192915050565b60805160a05160c05160e0516101005161012051610140516101605161018051615f75620022b86000396000818161036101528181610efa0152613786015260008181610332015281816116f80152613757015260008181610303015281816113ae0152818161141301528181611c7401528181611d02015261372801526000818161026f01528181610a30015281816118200152818161222201528181612b42015261369401526000818161023f01528181611dd30152613664015260008181610210015281816110a50152818161162401528181611a4101528181611b42015281816126dd015281816136350152613a240152600081816102cf01528181611c0e01526136f401526000818161029f0152818161283801526136c4015260006124b60152615f756000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80637437ff9f116100f9578063c92b283211610097578063eff7cc4811610071578063eff7cc48146109de578063f25561fd146109e6578063f2fde38b146109f9578063fbca3b7414610a0c57600080fd5b8063c92b2832146109b0578063d09dc339146109c3578063df0aa9e9146109cb57600080fd5b8063856c8247116100d3578063856c8247146108825780638da5cb5b146108955780639a113c36146108a6578063b06d41bc1461099a57600080fd5b80637437ff9f146106c057806376f6ae761461086757806379ba50971461087a57600080fd5b806348a98aa411610166578063549e946f11610140578063549e946f1461066957806354b714681461067c578063599f64311461069c578063704b6c02146106ad57600080fd5b806348a98aa4146105c7578063504bffe0146105f2578063546719cd1461060557600080fd5b806320487ded1161019757806320487ded146105705780634120fccd146105915780634816f4f7146105b257600080fd5b806306285c69146101be5780631772047e146103a7578063181f5a7714610527575b600080fd5b6103916040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091526040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60405161039e9190614b86565b60405180910390f35b6104bb6103b5366004614bba565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152506001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c082015290565b60405161039e9190600060e08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015260c0830151151560c083015292915050565b6105636040518060400160405280601381526020017f45564d3245564d4f6e52616d7020312e352e300000000000000000000000000081525081565b60405161039e9190614c27565b61058361057e366004614c68565b610a2c565b60405190815260200161039e565b610599610e82565b60405167ffffffffffffffff909116815260200161039e565b6105c56105c0366004614e76565b610ea9565b005b6105da6105d5366004614fb3565b610ebf565b6040516001600160a01b03909116815260200161039e565b6105c5610600366004614fec565b610f6e565b61060d610f82565b60405161039e919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6105c56106773660046150ea565b611014565b600e546040516bffffffffffffffffffffffff909116815260200161039e565b6002546001600160a01b03166105da565b6105c56106bb366004614bba565b61118d565b61085a604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915250604080516101a0810182526005546001600160a01b038082168352600160a01b820461ffff9081166020850152760100000000000000000000000000000000000000000000830463ffffffff908116958501959095527a0100000000000000000000000000000000000000000000000000008304811660608501527c0100000000000000000000000000000000000000000000000000000000928390048516608085015260065480821660a086015262010000808204831660c0870152640100000000820490931660e08601527801000000000000000000000000000000000000000000000000810486166101008601529290920484166101208401526007549182166101408401528104909216610160820152660100000000000090910460ff16151561018082015290565b60405161039e9190615206565b6105c5610875366004615215565b611257565b6105c56112ba565b610599610890366004614bba565b611383565b6000546001600160a01b03166105da565b6109506108b4366004614bba565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b03166000908152600b60209081526040918290208251608081018452905463ffffffff8116825267ffffffffffffffff64010000000082048116938301939093526c0100000000000000000000000081049092169281019290925260ff600160a01b909104161515606082015290565b60408051825163ffffffff16815260208084015167ffffffffffffffff9081169183019190915283830151169181019190915260609182015115159181019190915260800161039e565b6109a261147e565b60405161039e9291906152de565b6105c56109be366004615320565b611579565b6105836115e1565b6105836109d936600461538e565b6116a1565b6105c561252a565b6105c56109f43660046153fa565b6127af565b6105c5610a07366004614bba565b6127c0565b610a1f610a1a3660046154f9565b6127d1565b60405161039e9190615516565b60007f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168367ffffffffffffffff1614610aac576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6000610ac3610abe6080850185615563565b612805565b9050610af3610ad56020850185615563565b8351909150610ae760408701876155c8565b90508460200151612992565b6000600b81610b086080870160608801614bba565b6001600160a01b0316815260208082019290925260409081016000208151608081018352905463ffffffff81168252640100000000810467ffffffffffffffff908116948301949094526c01000000000000000000000000810490931691810191909152600160a01b90910460ff16151560608201819052909150610bd557610b976080850160608601614bba565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b600654600090819064010000000090046001600160a01b031663ffdb4b37610c036080890160608a01614bba565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff8a1660248201526044016040805180830381865afa158015610c6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c92919061565c565b90925090506000808080610ca960408b018b6155c8565b90501115610ce357610cd7610cc460808b0160608c01614bba565b86610cd260408d018d6155c8565b612af7565b91945092509050610cff565b8551610cfc9063ffffffff16662386f26fc100006156a5565b92505b60065460009062010000900461ffff1615610d5357610d506dffffffffffffffffffffffffffff607087901c16610d3960208d018d615563565b9050610d4860408e018e6155c8565b905085612ec6565b90505b60208781015160055460009267ffffffffffffffff9092169163ffffffff8716917a010000000000000000000000000000000000000000000000000000900461ffff1690610da3908f018f615563565b610dae9291506156a5565b6005548c51610ddd91760100000000000000000000000000000000000000000000900463ffffffff16906156bc565b610de791906156bc565b610df191906156bc565b610e0b906dffffffffffffffffffffffffffff89166156a5565b610e1591906156a5565b9050867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1682828a6040015167ffffffffffffffff1688610e5291906156a5565b610e5c91906156bc565b610e6691906156bc565b610e7091906156cf565b99505050505050505050505b92915050565b600e54600090610ea490600160801b900467ffffffffffffffff1660016156f1565b905090565b610eb1612f97565b610ebb8282612fef565b5050565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190615712565b9392505050565b610f76613371565b610f7f816133cb565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff8082168352600160801b80830463ffffffff166020850152600160a01b90920460ff161515938301939093526004548084166060840152049091166080820152610ea4906137c0565b61101c612f97565b6001600160a01b03811661105c576040517f232cb97f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006110666115e1565b905060008112156110a3576040517f02075e0000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316036110f5576110f06001600160a01b0384168383613872565b505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526110f09083906001600160a01b038616906370a0823190602401602060405180830381865afa158015611158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117c919061572f565b6001600160a01b0386169190613872565b6000546001600160a01b031633148015906111b357506002546001600160a01b03163314155b156111ea576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b61125f612f97565b610ebb8282808060200260200160405190810160405280939291908181526020016000905b828210156112b0576112a160408302860136819003810190615748565b81526020019060010190611284565b50505050506138f2565b6001546001600160a01b031633146113145760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610aa3565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b038082166000908152600d6020526040812054909167ffffffffffffffff909116907f00000000000000000000000000000000000000000000000000000000000000001615610e7c5780600003610e7c576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa15801561145a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190615787565b606060008061148d6008613b58565b90508067ffffffffffffffff8111156114a8576114a8614cb8565b6040519080825280602002602001820160405280156114ed57816020015b60408051808201909152600080825260208201528152602001906001900390816114c65790505b50925060005b8181101561155657600080611509600884613b63565b915091506040518060400160405280836001600160a01b031681526020018261ffff16815250868481518110611541576115416157a4565b602090810291909101015250506001016114f3565b5050600e5491926c0100000000000000000000000090920463ffffffff16919050565b6000546001600160a01b0316331480159061159f57506002546001600160a01b03163314155b156115d6576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f7f600382613b81565b600e546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916bffffffffffffffffffffffff16907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611673573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611697919061572f565b610ea491906157ba565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608086901b1660048201526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561173f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176391906157da565b1561179a576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0382166117da576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b0316331461181e576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168567ffffffffffffffff1614611897576040517fd9a9cd6800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610aa3565b60006118a9610abe6080870187615563565b905060006118ba60408701876155c8565b91506118e090506118ce6020880188615563565b90508360000151838560200151612992565b8015611a37576000805b82811015611a25576118ff60408901896155c8565b8281811061190f5761190f6157a4565b90506040020160200135600003611952576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c600061196360408b018b6155c8565b84818110611973576119736157a4565b6119899260206040909202019081019150614bba565b6001600160a01b031681526020810191909152604001600020547201000000000000000000000000000000000000900460ff1615611a1d57611a106119d160408a018a6155c8565b838181106119e1576119e16157a4565b9050604002018036038101906119f791906157f7565b60065464010000000090046001600160a01b0316613d14565b611a1a90836156bc565b91505b6001016118ea565b508015611a3557611a3581613e35565b505b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016611a716080880160608901614bba565b6001600160a01b031603611ad557600e8054869190600090611aa29084906bffffffffffffffffffffffff16615831565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550611bfc565b60065464010000000090046001600160a01b03166241e5be611afd6080890160608a01614bba565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018990527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa158015611b89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bad919061572f565b600e8054600090611bcd9084906bffffffffffffffffffffffff16615831565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b600e546bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811691161115611c69576040517fe5c7a49100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160200151611dbd577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615611dbd576001600160a01b0384166000908152600d602052604081205467ffffffffffffffff169003611dbd576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611d49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6d9190615787565b6001600160a01b0385166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790555b604080516101a08101825267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526001600160a01b03861660208201526000918101611e50611e168a80615563565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613e4292505050565b6001600160a01b03168152602001600e601081819054906101000a900467ffffffffffffffff16611e8090615856565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff168152602001846000015181526020016000151581526020018460200151611f2a576001600160a01b0387166000908152600d602052604081208054909190611f009067ffffffffffffffff16615856565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055611f2d565b60005b67ffffffffffffffff168152602001611f4c60808a0160608b01614bba565b6001600160a01b03168152602001878152602001888060200190611f709190615563565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001611fb760408a018a6155c8565b808060200260200160405190810160405280939291908181526020016000905b8282101561200357611ff4604083028601368190038101906157f7565b81526020019060010190611fd7565b505050505081526020018367ffffffffffffffff81111561202657612026614cb8565b60405190808252806020026020018201604052801561205957816020015b60608152602001906001900390816120445790505b508152600060209091018190529091505b828110156124af57600061208160408a018a6155c8565b83818110612091576120916157a4565b9050604002018036038101906120a791906157f7565b905060006120b98b8360000151610ebf565b90506001600160a01b038116158061216f57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa158015612149573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216d91906157da565b155b156121b45781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b6000816001600160a01b0316639a4575b96040518060a001604052808e80600001906121e09190615563565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525067ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166020808301919091526001600160a01b03808f16604080850191909152918901516060840152885116608090920191909152517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526122ab919060040161587d565b6000604051808303816000875af11580156122ca573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526122f2919081019061594a565b9050602063ffffffff1681602001515111156123895782516001600160a01b03166000908152600c602090815260409091205490820151516e01000000000000000000000000000090910463ffffffff1610156123895782516040517f36f536ca0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b805161239490613e42565b5060408051608081019091526001600160a01b03831660a08201528060c0810160408051808303601f190181529181529082528351602080840191909152808501518383015286516001600160a01b03166000908152600c9091522054606090910190730100000000000000000000000000000000000000900460ff166124295760075462010000900463ffffffff16612458565b84516001600160a01b03166000908152600c60205260409020546a0100000000000000000000900463ffffffff165b63ffffffff16905260405161247091906020016159db565b6040516020818303038152906040528561016001518581518110612496576124966157a4565b602002602001018190525050505080600101905061206a565b506124da817f0000000000000000000000000000000000000000000000000000000000000000613ee8565b6101808201526040517fd0c3c799bf9e2639de44391e7f524d229b2b55f5b1ea94b2bf7da42f7243dddd90612510908390615aef565b60405180910390a16101800151925050505b949350505050565b6000546001600160a01b0316331461258f576002546001600160a01b0316331461258f57612559600833614043565b61258f576040517f195db95800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff1660008190036125e3576040517f990e30bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546bffffffffffffffffffffffff168181101561262e576040517f8d0f71d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006126386115e1565b1215612670576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600061267d6008613b58565b905060005b8181101561276c57600080612698600884613b63565b90925090506000876126b8836bffffffffffffffffffffffff8a166156a5565b6126c291906156cf565b90506126ce8187615c24565b95506127126001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846bffffffffffffffffffffffff8416613872565b6040516bffffffffffffffffffffffff821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a2505050806001019050612682565b5050600e80547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff929092169190911790555050565b6127b7612f97565b610f7f81614058565b6127c8613371565b610f7f816141ca565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260008082526020820152600082900361286657506040805180820190915267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260006020820152610e7c565b60006128728385615c49565b90507fe7e230f0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016128df576128ca8360048187615c91565b8101906128d79190615cbb565b915050610e7c565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016129605760408051808201909152806129408560048189615c91565b81019061294d9190615ce7565b815260006020909101529150610e7c9050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006547801000000000000000000000000000000000000000000000000900463ffffffff16808511156129fb576040517f869337890000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610aa3565b6006547c0100000000000000000000000000000000000000000000000000000000900463ffffffff16841115612a5d576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554600160a01b900461ffff16831115612aa4576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81612af0576007546601000000000000900460ff1615612af0576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6000808083815b81811015612eba576000878783818110612b1a57612b1a6157a4565b905060400201803603810190612b3091906157f7565b905060006001600160a01b0316612b6b7f00000000000000000000000000000000000000000000000000000000000000008360000151610ebf565b6001600160a01b031603612bb95780516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b80516001600160a01b03166000908152600c6020908152604091829020825160e081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e0100000000000000000000000000008304909116608082015260ff720100000000000000000000000000000000000083048116151560a0830152730100000000000000000000000000000000000000909204909116151560c08201819052612cde57600754612ca29061ffff16662386f26fc100006156a5565b612cac90886156bc565b600754909750612cc89062010000900463ffffffff1687615d00565b9550612cd5602086615d00565b94505050612eb2565b604081015160009061ffff1615612e025760008c6001600160a01b031684600001516001600160a01b031614612da55760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526401000000009092041690634ab35b0b90602401602060405180830381865afa158015612d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d9e9190615d1d565b9050612da8565b508a5b620186a0836040015161ffff16612dea8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661428b90919063ffffffff16565b612df491906156a5565b612dfe91906156cf565b9150505b6060820151612e119088615d00565b9650816080015186612e239190615d00565b8251909650600090612e429063ffffffff16662386f26fc100006156a5565b905080821015612e6157612e56818a6156bc565b985050505050612eb2565b6000836020015163ffffffff16662386f26fc10000612e8091906156a5565b905080831115612ea057612e94818b6156bc565b99505050505050612eb2565b612eaa838b6156bc565b995050505050505b600101612afe565b50509450945094915050565b60008063ffffffff8316612edc610180866156a5565b612ee8876102206156bc565b612ef291906156bc565b612efc91906156bc565b6005546006549192506000917c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690612f3e9061ffff16846156a5565b612f4891906156bc565b60065490915062010000900461ffff16612f726dffffffffffffffffffffffffffff8916836156a5565b612f7c91906156a5565b612f8c90655af3107a40006156a5565b979650505050505050565b6000546001600160a01b03163314612fed576002546001600160a01b03163314612fed576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60005b825181101561328357600083828151811061300f5761300f6157a4565b60200260200101519050602063ffffffff168160a0015163ffffffff16101561308257805160a08201516040517f24ecdc020000000000000000000000000000000000000000000000000000000081526001600160a01b03909216600483015263ffffffff166024820152604401610aa3565b6040805160e08101825260208381015163ffffffff908116835284840151811682840190815260608087015161ffff9081168688019081526080808a0151861693880193845260a0808b0151871691890191825260c0808c01511515918a019182526001908a018181529b516001600160a01b03166000908152600c9099529990972097518854955192519451915197519a519087167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009096169590951764010000000092871692909202919091177fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff166801000000000000000093909216929092027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff16176a010000000000000000000091841691909102177fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff166e01000000000000000000000000000093909216929092027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff1617720100000000000000000000000000000000000094151594909402939093177fffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff16730100000000000000000000000000000000000000931515939093029290921790915501612ff2565b507ff5791bc457b3bb990493cf5f655db46c25ccf5764c9b99b8969b4c72ea7df9d0826040516132b39190615d38565b60405180910390a160005b815181101561332e57600c60008383815181106132dd576132dd6157a4565b6020908102919091018101516001600160a01b0316825281019190915260400160002080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556001016132be565b50805115610ebb577ffb95a0042158e60a33e7b5bec100f3d95407b1a71bee6633bd54b8887449750b816040516133659190615516565b60405180910390a15050565b6000546001600160a01b03163314612fed5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610aa3565b60e08101516001600160a01b031661340f576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a81548161ffff021916908361ffff1602179055506101608201518160020160026101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160066101000a81548160ff0219169083151502179055509050507f45b5ad483aa608464c2c7f278bd413d284d7790cdc836e40652e23a0277082206040518061010001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152508260405161124c929190615dd8565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261384e82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426138329190615df5565b85608001516fffffffffffffffffffffffffffffffff166142c8565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526110f09084906142f0565b8051604081111561392f576040517fb5a10cfa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e546c01000000000000000000000000900463ffffffff161561398357600e5463ffffffff6c010000000000000000000000008204166bffffffffffffffffffffffff909116106139835761398361252a565b600061398f6008613b58565b90505b80156139d15760006139b06139a8600184615df5565b600890613b63565b5090506139be6008826143d5565b5050806139ca90615e08565b9050613992565b506000805b82811015613ad95760008482815181106139f2576139f26157a4565b60200260200101516000015190506000858381518110613a1457613a146157a4565b60200260200101516020015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480613a6957506001600160a01b038216155b15613aab576040517f4de938d10000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610aa3565b613abb60088361ffff84166143ea565b50613aca61ffff821685615d00565b935050508060010190506139d6565b50600e80547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd2490613b4b9083908690615e3d565b60405180910390a1505050565b6000610e7c82614400565b6000808080613b72868661440b565b909450925050505b9250929050565b8154600090613b9d90600160801b900463ffffffff1642615df5565b90508015613c255760018301548354613bd8916fffffffffffffffffffffffffffffffff808216928116918591600160801b909104166142c8565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617600160801b4263ffffffff16021783555b60208201518354613c4b916fffffffffffffffffffffffffffffffff9081169116614436565b835483511515600160a01b027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff9283161717845560208301516040808501518316600160801b0291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990613b4b9084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b81516040517fd02641a00000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260009182919084169063d02641a0906024016040805180830381865afa158015613d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d9e9190615e5c565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613e075783516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610aa3565b6020840151612522907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83169061428b565b610f7f600382600061444c565b60008151602014613e8157816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610aa39190614c27565b600082806020019051810190613e97919061572f565b90506001600160a01b03811180613eaf575061040081105b15610e7c57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610aa39190614c27565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001613f7e9897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001613fb79190615e8f565b60405160208183030381529060405280519060200120876101600151604051602001613fe39190615ea2565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b6000610f67836001600160a01b038416614756565b60005b815181101561419a576000828281518110614078576140786157a4565b60209081029190910181015160408051608080820183528385015163ffffffff90811683528385015167ffffffffffffffff908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600b90985294909620925183549451925195511515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9688166c0100000000000000000000000002969096167fffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009095169116179290921791909116929092171790555060010161405b565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e8160405161124c9190615eb5565b336001600160a01b038216036142225760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610aa3565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a76400006142be837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166156a5565b610f6791906156cf565b60006142e7856142d884866156a5565b6142e290876156bc565b614436565b95945050505050565b6000614345826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166147629092919063ffffffff16565b8051909150156110f0578080602001905181019061436391906157da565b6110f05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa3565b6000610f67836001600160a01b038416614771565b6000612522846001600160a01b0385168461478e565b6000610e7c826147ab565b6000808061441985856147b5565b600081815260029690960160205260409095205494959350505050565b60008183106144455781610f67565b5090919050565b8254600160a01b900460ff161580614462575081155b1561446c57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906144a590600160801b900463ffffffff1642615df5565b9050801561454b57818311156144e7576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461451490839085908490600160801b90046fffffffffffffffffffffffffffffffff166142c8565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff16600160801b4263ffffffff160217875592505b848210156145e8576001600160a01b03841661459d576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610aa3565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610aa3565b848310156146d457600186810154600160801b90046fffffffffffffffffffffffffffffffff1690600090829061461f9082615df5565b614629878a615df5565b61463391906156bc565b61463d91906156cf565b90506001600160a01b038616614689576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610aa3565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610aa3565b6146de8584615df5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000610f6783836147c1565b606061252284846000856147d9565b60008181526002830160205260408120819055610f6783836148c0565b6000828152600284016020526040812082905561252284846148cc565b6000610e7c825490565b6000610f6783836148d8565b60008181526001830160205260408120541515610f67565b6060824710156148515760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa3565b600080866001600160a01b0316858760405161486d9190615f36565b60006040518083038185875af1925050503d80600081146148aa576040519150601f19603f3d011682016040523d82523d6000602084013e6148af565b606091505b5091509150612f8c87838387614902565b6000610f67838361497b565b6000610f678383614a75565b60008260000182815481106148ef576148ef6157a4565b9060005260206000200154905092915050565b6060831561497157825160000361496a576001600160a01b0385163b61496a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa3565b5081612522565b6125228383614ac4565b60008181526001830160205260408120548015614a6457600061499f600183615df5565b85549091506000906149b390600190615df5565b9050808214614a185760008660000182815481106149d3576149d36157a4565b90600052602060002001549050808760000184815481106149f6576149f66157a4565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614a2957614a29615f52565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610e7c565b6000915050610e7c565b5092915050565b6000818152600183016020526040812054614abc57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e7c565b506000610e7c565b815115614ad45781518083602001fd5b8060405162461bcd60e51b8152600401610aa39190614c27565b6001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401525060c0810151614b6b60c08401826001600160a01b03169052565b5060e08101516110f060e08401826001600160a01b03169052565b6101008101610e7c8284614aee565b6001600160a01b0381168114610f7f57600080fd5b8035614bb581614b95565b919050565b600060208284031215614bcc57600080fd5b8135610f6781614b95565b60005b83811015614bf2578181015183820152602001614bda565b50506000910152565b60008151808452614c13816020860160208601614bd7565b601f01601f19169290920160200192915050565b602081526000610f676020830184614bfb565b67ffffffffffffffff81168114610f7f57600080fd5b600060a08284031215614c6257600080fd5b50919050565b60008060408385031215614c7b57600080fd5b8235614c8681614c3a565b9150602083013567ffffffffffffffff811115614ca257600080fd5b614cae85828601614c50565b9150509250929050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b60405290565b6040516101a0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b60405160a0810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b6040805190810167ffffffffffffffff81118282101715614cf157614cf1614cb8565b604051601f8201601f1916810167ffffffffffffffff81118282101715614d8a57614d8a614cb8565b604052919050565b600067ffffffffffffffff821115614dac57614dac614cb8565b5060051b60200190565b63ffffffff81168114610f7f57600080fd5b8035614bb581614db6565b803561ffff81168114614bb557600080fd5b8015158114610f7f57600080fd5b8035614bb581614de5565b600082601f830112614e0f57600080fd5b81356020614e24614e1f83614d92565b614d61565b8083825260208201915060208460051b870101935086841115614e4657600080fd5b602086015b84811015614e6b578035614e5e81614b95565b8352918301918301614e4b565b509695505050505050565b6000806040808486031215614e8a57600080fd5b833567ffffffffffffffff80821115614ea257600080fd5b818601915086601f830112614eb657600080fd5b81356020614ec6614e1f83614d92565b82815260e0928302850182019282820191908b851115614ee557600080fd5b958301955b84871015614f8e5780878d031215614f025760008081fd5b614f0a614cce565b8735614f1581614b95565b815287850135614f2481614db6565b8186015287890135614f3581614db6565b818a01526060614f46898201614dd3565b90820152608088810135614f5981614db6565b9082015260a0614f6a898201614dc8565b9082015260c0614f7b898201614df3565b9082015283529586019591830191614eea565b5097505087013593505080831115614fa557600080fd5b5050614cae85828601614dfe565b60008060408385031215614fc657600080fd5b8235614fd181614c3a565b91506020830135614fe181614b95565b809150509250929050565b60006101a08284031215614fff57600080fd5b615007614cf7565b61501083614baa565b815261501e60208401614dd3565b602082015261502f60408401614dc8565b604082015261504060608401614dd3565b606082015261505160808401614dc8565b608082015261506260a08401614dd3565b60a082015261507360c08401614dd3565b60c082015261508460e08401614baa565b60e0820152610100615097818501614dc8565b908201526101206150a9848201614dc8565b908201526101406150bb848201614dd3565b908201526101606150cd848201614dc8565b908201526101806150df848201614df3565b908201529392505050565b600080604083850312156150fd57600080fd5b8235614fd181614b95565b80516001600160a01b03168252602081015161512a602084018261ffff169052565b506040810151615142604084018263ffffffff169052565b506060810151615158606084018261ffff169052565b506080810151615170608084018263ffffffff169052565b5060a081015161518660a084018261ffff169052565b5060c081015161519c60c084018261ffff169052565b5060e08101516151b760e08401826001600160a01b03169052565b506101008181015163ffffffff90811691840191909152610120808301518216908401526101408083015161ffff16908401526101608083015190911690830152610180908101511515910152565b6101a08101610e7c8284615108565b6000806020838503121561522857600080fd5b823567ffffffffffffffff8082111561524057600080fd5b818501915085601f83011261525457600080fd5b81358181111561526357600080fd5b8660208260061b850101111561527857600080fd5b60209290920196919550909350505050565b60008151808452602080850194506020840160005b838110156152d357815180516001600160a01b0316885283015161ffff16838801526040909601959082019060010161529f565b509495945050505050565b6040815260006152f1604083018561528a565b90508260208301529392505050565b80356fffffffffffffffffffffffffffffffff81168114614bb557600080fd5b60006060828403121561533257600080fd5b6040516060810181811067ffffffffffffffff8211171561535557615355614cb8565b604052823561536381614de5565b815261537160208401615300565b602082015261538260408401615300565b60408201529392505050565b600080600080608085870312156153a457600080fd5b84356153af81614c3a565b9350602085013567ffffffffffffffff8111156153cb57600080fd5b6153d787828801614c50565b9350506040850135915060608501356153ef81614b95565b939692955090935050565b6000602080838503121561540d57600080fd5b823567ffffffffffffffff81111561542457600080fd5b8301601f8101851361543557600080fd5b8035615443614e1f82614d92565b81815260a0918202830184019184820191908884111561546257600080fd5b938501935b838510156154ed5780858a03121561547f5760008081fd5b615487614d1b565b853561549281614b95565b8152858701356154a181614db6565b818801526040868101356154b481614c3a565b908201526060868101356154c781614c3a565b908201526080868101356154da81614de5565b9082015283529384019391850191615467565b50979650505050505050565b60006020828403121561550b57600080fd5b8135610f6781614c3a565b6020808252825182820181905260009190848201906040850190845b818110156155575783516001600160a01b031683529284019291840191600101615532565b50909695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261559857600080fd5b83018035915067ffffffffffffffff8211156155b357600080fd5b602001915036819003821315613b7a57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126155fd57600080fd5b83018035915067ffffffffffffffff82111561561857600080fd5b6020019150600681901b3603821315613b7a57600080fd5b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114614bb557600080fd5b6000806040838503121561566f57600080fd5b61567883615630565b915061568660208401615630565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e7c57610e7c61568f565b80820180821115610e7c57610e7c61568f565b6000826156ec57634e487b7160e01b600052601260045260246000fd5b500490565b67ffffffffffffffff818116838216019080821115614a6e57614a6e61568f565b60006020828403121561572457600080fd5b8151610f6781614b95565b60006020828403121561574157600080fd5b5051919050565b60006040828403121561575a57600080fd5b615762614d3e565b823561576d81614b95565b815261577b60208401614dd3565b60208201529392505050565b60006020828403121561579957600080fd5b8151610f6781614c3a565b634e487b7160e01b600052603260045260246000fd5b8181036000831280158383131683831282161715614a6e57614a6e61568f565b6000602082840312156157ec57600080fd5b8151610f6781614de5565b60006040828403121561580957600080fd5b615811614d3e565b823561581c81614b95565b81526020928301359281019290925250919050565b6bffffffffffffffffffffffff818116838216019080821115614a6e57614a6e61568f565b600067ffffffffffffffff8083168181036158735761587361568f565b6001019392505050565b602081526000825160a0602084015261589960c0840182614bfb565b905067ffffffffffffffff602085015116604084015260408401516001600160a01b038082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600082601f8301126158f757600080fd5b815167ffffffffffffffff81111561591157615911614cb8565b6159246020601f19601f84011601614d61565b81815284602083860101111561593957600080fd5b612522826020830160208701614bd7565b60006020828403121561595c57600080fd5b815167ffffffffffffffff8082111561597457600080fd5b908301906040828603121561598857600080fd5b615990614d3e565b82518281111561599f57600080fd5b6159ab878286016158e6565b8252506020830151828111156159c057600080fd5b6159cc878286016158e6565b60208301525095945050505050565b6020815260008251608060208401526159f760a0840182614bfb565b90506020840151601f1980858403016040860152615a158383614bfb565b9250604086015191508085840301606086015250615a338282614bfb565b91505063ffffffff60608501511660808401528091505092915050565b60008151808452602080850194506020840160005b838110156152d357815180516001600160a01b031688528301518388015260409096019590820190600101615a65565b60008282518085526020808601955060208260051b8401016020860160005b84811015615ae257601f19868403018952615ad0838351614bfb565b98840198925090830190600101615ab4565b5090979650505050505050565b60208152615b0a60208201835167ffffffffffffffff169052565b60006020830151615b2660408401826001600160a01b03169052565b5060408301516001600160a01b038116606084015250606083015167ffffffffffffffff8116608084015250608083015160a083015260a0830151615b6f60c084018215159052565b5060c083015167ffffffffffffffff811660e08401525060e0830151610100615ba2818501836001600160a01b03169052565b840151610120848101919091528401516101a061014080860182905291925090615bd06101c0860184614bfb565b9250808601519050601f19610160818786030181880152615bf18584615a50565b945080880151925050610180818786030181880152615c108584615a95565b970151959092019490945250929392505050565b6bffffffffffffffffffffffff828116828216039080821115614a6e57614a6e61568f565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015615c895780818660040360031b1b83161692505b505092915050565b60008085851115615ca157600080fd5b83861115615cae57600080fd5b5050820193919092039150565b600060408284031215615ccd57600080fd5b615cd5614d3e565b82358152602083013561577b81614de5565b600060208284031215615cf957600080fd5b5035919050565b63ffffffff818116838216019080821115614a6e57614a6e61568f565b600060208284031215615d2f57600080fd5b610f6782615630565b602080825282518282018190526000919060409081850190868401855b82811015615dcb57815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a0808301519091169086015260c09081015115159085015260e09093019290850190600101615d55565b5091979650505050505050565b6102a08101615de78285614aee565b610f67610100830184615108565b81810381811115610e7c57610e7c61568f565b600081615e1757615e1761568f565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b63ffffffff83168152604060208201526000612522604083018461528a565b600060408284031215615e6e57600080fd5b615e76614d3e565b615e7f83615630565b8152602083015161577b81614db6565b602081526000610f676020830184615a50565b602081526000610f676020830184615a95565b602080825282518282018190526000919060409081850190868401855b82811015615dcb57815180516001600160a01b031685528681015163ffffffff16878601528581015167ffffffffffffffff908116878701526060808301519091169086015260809081015115159085015260a09093019290850190600101615ed2565b60008251615f48818460208701614bd7565b9190910192915050565b634e487b7160e01b600052603160045260246000fdfea164736f6c6343000818000a", } var EVM2EVMOnRampABI = EVM2EVMOnRampMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go index d22c66a435..275f9c7a38 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var LockReleaseTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b50604051620049ae380380620049ae833981016040819052620000359162000565565b848484833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200017e565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001695760408051600081526020810190915262000169908462000229565b5050505090151560e05250620006d692505050565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000688565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000688565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200069e565b8554909150600090620003fa906001906200069e565b9050818114620004665760008660000182815481106200041e576200041e62000688565b906000526020600020015490508087600001848154811062000444576200044462000688565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a620006c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b805180151581146200054f57600080fd5b600080600080600060a086880312156200057e57600080fd5b85516200058b8162000513565b602087810151919650906001600160401b0380821115620005ab57600080fd5b818901915089601f830112620005c057600080fd5b815181811115620005d557620005d56200052c565b8060051b604051601f19603f83011681018181108582111715620005fd57620005fd6200052c565b60405291825284820192508381018501918c8311156200061c57600080fd5b938501935b828510156200064557620006358562000542565b8452938501939285019262000621565b8099505050505050506200065c6040870162000542565b92506200066c6060870162000554565b91506200067c6080870162000542565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161423c62000772600039600081816104ef015261174201526000818161059c01528181611cde015261278301526000818161057601528181611b0f0152611f94015260008181610290015281816102e50152818161077a0152818161084c015281816108ed0152818161180401528181611a2f01528181611eb401528181612719015261296e015261423c6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063c4bffe2b116100a2578063dc0bd97111610071578063dc0bd97114610574578063e0351e131461059a578063eb521a4c146105c0578063f2fde38b146105d357600080fd5b8063c4bffe2b14610526578063c75eea9c1461053b578063cf7401f31461054e578063db6327dc1461056157600080fd5b8063b0f479a1116100de578063b0f479a1146104bc578063b7946580146104da578063bb98546b146104ed578063c0d786551461051357600080fd5b80638da5cb5b146103fa5780639a4575b914610418578063a7cd63b714610438578063af58d59f1461044d57600080fd5b806354c8a4f31161018757806378a010b21161015657806378a010b2146103b957806379ba5097146103cc5780637d54534e146103d45780638926f54f146103e757600080fd5b806354c8a4f31461036257806366320087146103755780636cfd1553146103885780636d3d1a581461039b57600080fd5b806321df0da7116101c357806321df0da71461028e578063240028e8146102d55780633907753714610322578063432a6ba31461034457600080fd5b806301ffc9a7146101f55780630a2fd4931461021d5780630a861f2a1461023d578063181f5a7714610252575b600080fd5b610208610203366004613318565b6105e6565b60405190151581526020015b60405180910390f35b61023061022b366004613377565b610642565b6040516102149190613400565b61025061024b366004613413565b6106f2565b005b6102306040518060400160405280601a81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e3000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b6102086102e3366004613459565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b610335610330366004613476565b6108a3565b60405190518152602001610214565b60095473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103703660046134fe565b6109a9565b61025061038336600461356a565b610a24565b610250610396366004613459565b610b00565b60085473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103c7366004613596565b610b4f565b610250610cbe565b6102506103e2366004613459565b610dbb565b6102086103f5366004613377565b610e0a565b60005473ffffffffffffffffffffffffffffffffffffffff166102b0565b61042b610426366004613619565b610e21565b6040516102149190613654565b610440610ebb565b60405161021491906136b4565b61046061045b366004613377565b610ecc565b604051610214919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102306104e8366004613377565b610fa1565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b610250610521366004613459565b610fcc565b61052e6110a7565b604051610214919061370e565b610460610549366004613377565b61115f565b61025061055c366004613876565b611231565b61025061056f3660046138bb565b6112ba565b7f00000000000000000000000000000000000000000000000000000000000000006102b0565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105ce366004613413565b611740565b6102506105e1366004613459565b61185c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061063c575061063c82611870565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061066d906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610699906138fd565b80156106e65780601f106106bb576101008083540402835291602001916106e6565b820191906000526020600020905b8154815290600101906020018083116106c957829003601f168201915b50505050509050919050565b60095473ffffffffffffffffffffffffffffffffffffffff16331461074a576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa9190613950565b1015610832576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611954565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c36108be83613a14565b611a28565b6109186108d66060840160408501613459565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611954565b6109286060830160408401613459565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52846060013560405161098a91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6109b1611c59565b610a1e84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611cdc92505050565b50505050565b610a2c611c59565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610a9457600080fd5b505af1158015610aa8573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610af491815260200190565b60405180910390a25050565b610b08611c59565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b57611c59565b610b6083610e0a565b610ba2576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b67ffffffffffffffff831660009081526007602052604081206004018054610bc9906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610bf5906138fd565b8015610c425780601f10610c1757610100808354040283529160200191610c42565b820191906000526020600020905b815481529060010190602001808311610c2557829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610c71838583613b59565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610cb093929190613c74565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610741565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610dc3611c59565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061063c600567ffffffffffffffff8416611e92565b6040805180820190915260608082526020820152610e46610e4183613cd8565b611ead565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610ea08460200160208101906104e89190613377565b81526040805160208181019092526000815291015292915050565b6060610ec76002612077565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261063c90612084565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061066d906138fd565b610fd4611c59565b73ffffffffffffffffffffffffffffffffffffffff8116611021576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110b56005612077565b90506000815167ffffffffffffffff8111156110d3576110d3613750565b6040519080825280602002602001820160405280156110fc578160200160208202803683370190505b50905060005b82518110156111585782818151811061111d5761111d613d7a565b602002602001015182828151811061113757611137613d7a565b67ffffffffffffffff90921660209283029190910190910152600101611102565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261063c90612084565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611271575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112aa576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b6112b5838383612136565b505050565b6112c2611c59565b60005b818110156112b55760008383838181106112e1576112e1613d7a565b90506020028101906112f39190613da9565b6112fc90613de7565b90506113118160800151826020015115612220565b6113248160a00151826020015115612220565b8060200151156116205780516113469060059067ffffffffffffffff16612359565b61138b5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b60408101515115806113a05750606081015151155b156113d7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115b89082613e9b565b50606082015160058201906115cd9082613e9b565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116139493929190613fb5565b60405180910390a1611737565b80516116389060059067ffffffffffffffff16612365565b61167d5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116e660048301826132ca565b6116f46005830160006132ca565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112c5565b7f0000000000000000000000000000000000000000000000000000000000000000611797576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff1633146117ea576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b61182c73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612371565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611864611c59565b61186d816123cf565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061190357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061063c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112b59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526124c4565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611abd5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8f919061404e565b15611bc6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bd381602001516125d0565b6000611be28260200151610642565b9050805160001480611c06575080805190602001208260a001518051906020012014155b15611c43578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107419190613400565b611c55826020015183606001516126f6565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611cda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610741565b565b7f0000000000000000000000000000000000000000000000000000000000000000611d33576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611dc9576000838281518110611d5357611d53613d7a565b60200260200101519050611d7181600261273d90919063ffffffff16565b15611dc05760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611d36565b5060005b81518110156112b5576000828281518110611dea57611dea613d7a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e2e5750611e8a565b611e3960028261275f565b15611e885760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611dcd565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611f425760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611ff0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612014919061404e565b1561204b576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120588160400151612781565b6120658160200151612800565b61186d8160200151826060015161294e565b60606000611ea683612992565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261211282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426120f6919061409a565b85608001516fffffffffffffffffffffffffffffffff166129ed565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61213f83610e0a565b612181576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b61218c826000612220565b67ffffffffffffffff831660009081526007602052604090206121af9083612a17565b6121ba816000612220565b67ffffffffffffffff831660009081526007602052604090206121e09060020182612a17565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051612213939291906140ad565b60405180910390a1505050565b8151156122e75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612276575060408201516fffffffffffffffffffffffffffffffff16155b156122af57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107419190614130565b8015611c55576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612320575060208201516fffffffffffffffffffffffffffffffff1615155b15611c5557816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107419190614130565b6000611ea68383612bb9565b6000611ea68383612c08565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a1e9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016119a6565b3373ffffffffffffffffffffffffffffffffffffffff82160361244e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610741565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612526826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612cfb9092919063ffffffff16565b8051909150156112b55780806020019051810190612544919061404e565b6112b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610741565b6125d981610e0a565b61261b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561269a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126be919061404e565b61186d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c5590600201827f0000000000000000000000000000000000000000000000000000000000000000612d0a565b6000611ea68373ffffffffffffffffffffffffffffffffffffffff8416612c08565b6000611ea68373ffffffffffffffffffffffffffffffffffffffff8416612bb9565b7f00000000000000000000000000000000000000000000000000000000000000001561186d576127b260028261308d565b61186d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610741565b61280981610e0a565b61284b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156128c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e8919061416c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461186d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c5590827f0000000000000000000000000000000000000000000000000000000000000000612d0a565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106e657602002820191906000526020600020905b8154815260200190600101908083116129ce5750505050509050919050565b6000612a0c856129fd8486614189565b612a0790876141a0565b6130bc565b90505b949350505050565b8154600090612a4090700100000000000000000000000000000000900463ffffffff164261409a565b90508015612ae25760018301548354612a88916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166129ed565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612b08916fffffffffffffffffffffffffffffffff90811691166130bc565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612213908490614130565b6000818152600183016020526040812054612c005750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561063c565b50600061063c565b60008181526001830160205260408120548015612cf1576000612c2c60018361409a565b8554909150600090612c409060019061409a565b9050818114612ca5576000866000018281548110612c6057612c60613d7a565b9060005260206000200154905080876000018481548110612c8357612c83613d7a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612cb657612cb66141b3565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061063c565b600091505061063c565b6060612a0f84846000856130d2565b825474010000000000000000000000000000000000000000900460ff161580612d31575081155b15612d3b57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612d8190700100000000000000000000000000000000900463ffffffff164261409a565b90508015612e415781831115612dc3576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612dfd9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166129ed565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612ef85773ffffffffffffffffffffffffffffffffffffffff8416612ea0576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610741565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610741565b8483101561300b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f3c908261409a565b612f46878a61409a565b612f5091906141a0565b612f5a91906141e2565b905073ffffffffffffffffffffffffffffffffffffffff8616612fb3576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610741565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610741565b613015858461409a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611ea6565b60008183106130cb5781611ea6565b5090919050565b606082471015613164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610741565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161318d919061421d565b60006040518083038185875af1925050503d80600081146131ca576040519150601f19603f3d011682016040523d82523d6000602084013e6131cf565b606091505b50915091506131e0878383876131eb565b979650505050505050565b6060831561328157825160000361327a5773ffffffffffffffffffffffffffffffffffffffff85163b61327a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610741565b5081612a0f565b612a0f83838151156132965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107419190613400565b5080546132d6906138fd565b6000825580601f106132e6575050565b601f01602090049060005260206000209081019061186d91905b808211156133145760008155600101613300565b5090565b60006020828403121561332a57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611ea657600080fd5b803567ffffffffffffffff8116811461337257600080fd5b919050565b60006020828403121561338957600080fd5b611ea68261335a565b60005b838110156133ad578181015183820152602001613395565b50506000910152565b600081518084526133ce816020860160208601613392565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611ea660208301846133b6565b60006020828403121561342557600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461186d57600080fd5b80356133728161342c565b60006020828403121561346b57600080fd5b8135611ea68161342c565b60006020828403121561348857600080fd5b813567ffffffffffffffff81111561349f57600080fd5b82016101008185031215611ea657600080fd5b60008083601f8401126134c457600080fd5b50813567ffffffffffffffff8111156134dc57600080fd5b6020830191508360208260051b85010111156134f757600080fd5b9250929050565b6000806000806040858703121561351457600080fd5b843567ffffffffffffffff8082111561352c57600080fd5b613538888389016134b2565b9096509450602087013591508082111561355157600080fd5b5061355e878288016134b2565b95989497509550505050565b6000806040838503121561357d57600080fd5b82356135888161342c565b946020939093013593505050565b6000806000604084860312156135ab57600080fd5b6135b48461335a565b9250602084013567ffffffffffffffff808211156135d157600080fd5b818601915086601f8301126135e557600080fd5b8135818111156135f457600080fd5b87602082850101111561360657600080fd5b6020830194508093505050509250925092565b60006020828403121561362b57600080fd5b813567ffffffffffffffff81111561364257600080fd5b820160a08185031215611ea657600080fd5b60208152600082516040602084015261367060608401826133b6565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526136ab82826133b6565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561370257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016136d0565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561370257835167ffffffffffffffff168352928401929184019160010161372a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156137a3576137a3613750565b60405290565b60405160c0810167ffffffffffffffff811182821017156137a3576137a3613750565b801515811461186d57600080fd5b8035613372816137cc565b80356fffffffffffffffffffffffffffffffff8116811461337257600080fd5b60006060828403121561381757600080fd5b6040516060810181811067ffffffffffffffff8211171561383a5761383a613750565b604052905080823561384b816137cc565b8152613859602084016137e5565b602082015261386a604084016137e5565b60408201525092915050565b600080600060e0848603121561388b57600080fd5b6138948461335a565b92506138a38560208601613805565b91506138b28560808601613805565b90509250925092565b600080602083850312156138ce57600080fd5b823567ffffffffffffffff8111156138e557600080fd5b6138f1858286016134b2565b90969095509350505050565b600181811c9082168061391157607f821691505b60208210810361394a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561396257600080fd5b5051919050565b600082601f83011261397a57600080fd5b813567ffffffffffffffff8082111561399557613995613750565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156139db576139db613750565b816040528381528660208588010111156139f457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613a2757600080fd5b613a2f61377f565b823567ffffffffffffffff80821115613a4757600080fd5b613a5336838701613969565b8352613a616020860161335a565b6020840152613a726040860161344e565b604084015260608501356060840152613a8d6080860161344e565b608084015260a0850135915080821115613aa657600080fd5b613ab236838701613969565b60a084015260c0850135915080821115613acb57600080fd5b613ad736838701613969565b60c084015260e0850135915080821115613af057600080fd5b50613afd36828601613969565b60e08301525092915050565b601f8211156112b5576000816000526020600020601f850160051c81016020861015613b325750805b601f850160051c820191505b81811015613b5157828155600101613b3e565b505050505050565b67ffffffffffffffff831115613b7157613b71613750565b613b8583613b7f83546138fd565b83613b09565b6000601f841160018114613bd75760008515613ba15750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613c6d565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613c265786850135825560209485019460019092019101613c06565b5086821015613c61577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613c8760408301866133b6565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613cea57600080fd5b60405160a0810167ffffffffffffffff8282108183111715613d0e57613d0e613750565b816040528435915080821115613d2357600080fd5b50613d3036828601613969565b825250613d3f6020840161335a565b60208201526040830135613d528161342c565b6040820152606083810135908201526080830135613d6f8161342c565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ddd57600080fd5b9190910192915050565b60006101408236031215613dfa57600080fd5b613e026137a9565b613e0b8361335a565b8152613e19602084016137da565b6020820152604083013567ffffffffffffffff80821115613e3957600080fd5b613e4536838701613969565b60408401526060850135915080821115613e5e57600080fd5b50613e6b36828601613969565b606083015250613e7e3660808501613805565b6080820152613e903660e08501613805565b60a082015292915050565b815167ffffffffffffffff811115613eb557613eb5613750565b613ec981613ec384546138fd565b84613b09565b602080601f831160018114613f1c5760008415613ee65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b51565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613f6957888601518255948401946001909101908401613f4a565b5085821015613fa557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613fd9818401876133b6565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506140179050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526136ab565b60006020828403121561406057600080fd5b8151611ea6816137cc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561063c5761063c61406b565b67ffffffffffffffff8416815260e081016140f960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612a0f565b6060810161063c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561417e57600080fd5b8151611ea68161342c565b808202811582820484141761063c5761063c61406b565b8082018082111561063c5761063c61406b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614218577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613ddd81846020870161339256fea164736f6c6343000818000a", + Bin: "0x6101006040523480156200001257600080fd5b50604051620049ae380380620049ae833981016040819052620000359162000565565b848484833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200017e565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001695760408051600081526020810190915262000169908462000229565b5050505090151560e05250620006d692505050565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000688565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000688565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200069e565b8554909150600090620003fa906001906200069e565b9050808214620004665760008660000182815481106200041e576200041e62000688565b906000526020600020015490508087600001848154811062000444576200044462000688565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a620006c0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b805180151581146200054f57600080fd5b600080600080600060a086880312156200057e57600080fd5b85516200058b8162000513565b602087810151919650906001600160401b0380821115620005ab57600080fd5b818901915089601f830112620005c057600080fd5b815181811115620005d557620005d56200052c565b8060051b604051601f19603f83011681018181108582111715620005fd57620005fd6200052c565b60405291825284820192508381018501918c8311156200061c57600080fd5b938501935b828510156200064557620006358562000542565b8452938501939285019262000621565b8099505050505050506200065c6040870162000542565b92506200066c6060870162000554565b91506200067c6080870162000542565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161423c62000772600039600081816104ef015261174201526000818161059c01528181611cde015261278301526000818161057601528181611b0f0152611f94015260008181610290015281816102e50152818161077a0152818161084c015281816108ed0152818161180401528181611a2f01528181611eb401528181612719015261296e015261423c6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063c4bffe2b116100a2578063dc0bd97111610071578063dc0bd97114610574578063e0351e131461059a578063eb521a4c146105c0578063f2fde38b146105d357600080fd5b8063c4bffe2b14610526578063c75eea9c1461053b578063cf7401f31461054e578063db6327dc1461056157600080fd5b8063b0f479a1116100de578063b0f479a1146104bc578063b7946580146104da578063bb98546b146104ed578063c0d786551461051357600080fd5b80638da5cb5b146103fa5780639a4575b914610418578063a7cd63b714610438578063af58d59f1461044d57600080fd5b806354c8a4f31161018757806378a010b21161015657806378a010b2146103b957806379ba5097146103cc5780637d54534e146103d45780638926f54f146103e757600080fd5b806354c8a4f31461036257806366320087146103755780636cfd1553146103885780636d3d1a581461039b57600080fd5b806321df0da7116101c357806321df0da71461028e578063240028e8146102d55780633907753714610322578063432a6ba31461034457600080fd5b806301ffc9a7146101f55780630a2fd4931461021d5780630a861f2a1461023d578063181f5a7714610252575b600080fd5b610208610203366004613318565b6105e6565b60405190151581526020015b60405180910390f35b61023061022b366004613377565b610642565b6040516102149190613400565b61025061024b366004613413565b6106f2565b005b6102306040518060400160405280601a81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e3000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b6102086102e3366004613459565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b610335610330366004613476565b6108a3565b60405190518152602001610214565b60095473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103703660046134fe565b6109a9565b61025061038336600461356a565b610a24565b610250610396366004613459565b610b00565b60085473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103c7366004613596565b610b4f565b610250610cbe565b6102506103e2366004613459565b610dbb565b6102086103f5366004613377565b610e0a565b60005473ffffffffffffffffffffffffffffffffffffffff166102b0565b61042b610426366004613619565b610e21565b6040516102149190613654565b610440610ebb565b60405161021491906136b4565b61046061045b366004613377565b610ecc565b604051610214919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102306104e8366004613377565b610fa1565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b610250610521366004613459565b610fcc565b61052e6110a7565b604051610214919061370e565b610460610549366004613377565b61115f565b61025061055c366004613876565b611231565b61025061056f3660046138bb565b6112ba565b7f00000000000000000000000000000000000000000000000000000000000000006102b0565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105ce366004613413565b611740565b6102506105e1366004613459565b61185c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061063c575061063c82611870565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061066d906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610699906138fd565b80156106e65780601f106106bb576101008083540402835291602001916106e6565b820191906000526020600020905b8154815290600101906020018083116106c957829003601f168201915b50505050509050919050565b60095473ffffffffffffffffffffffffffffffffffffffff16331461074a576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa9190613950565b1015610832576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611954565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c36108be83613a14565b611a28565b6109186108d66060840160408501613459565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611954565b6109286060830160408401613459565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52846060013560405161098a91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6109b1611c59565b610a1e84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611cdc92505050565b50505050565b610a2c611c59565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610a9457600080fd5b505af1158015610aa8573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610af491815260200190565b60405180910390a25050565b610b08611c59565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b57611c59565b610b6083610e0a565b610ba2576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b67ffffffffffffffff831660009081526007602052604081206004018054610bc9906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610bf5906138fd565b8015610c425780601f10610c1757610100808354040283529160200191610c42565b820191906000526020600020905b815481529060010190602001808311610c2557829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610c71838583613b59565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610cb093929190613c74565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610741565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610dc3611c59565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061063c600567ffffffffffffffff8416611e92565b6040805180820190915260608082526020820152610e46610e4183613cd8565b611ead565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610ea08460200160208101906104e89190613377565b81526040805160208181019092526000815291015292915050565b6060610ec76002612077565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261063c90612084565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061066d906138fd565b610fd4611c59565b73ffffffffffffffffffffffffffffffffffffffff8116611021576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110b56005612077565b90506000815167ffffffffffffffff8111156110d3576110d3613750565b6040519080825280602002602001820160405280156110fc578160200160208202803683370190505b50905060005b82518110156111585782818151811061111d5761111d613d7a565b602002602001015182828151811061113757611137613d7a565b67ffffffffffffffff90921660209283029190910190910152600101611102565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261063c90612084565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611271575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112aa576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b6112b5838383612136565b505050565b6112c2611c59565b60005b818110156112b55760008383838181106112e1576112e1613d7a565b90506020028101906112f39190613da9565b6112fc90613de7565b90506113118160800151826020015115612220565b6113248160a00151826020015115612220565b8060200151156116205780516113469060059067ffffffffffffffff16612359565b61138b5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b60408101515115806113a05750606081015151155b156113d7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115b89082613e9b565b50606082015160058201906115cd9082613e9b565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116139493929190613fb5565b60405180910390a1611737565b80516116389060059067ffffffffffffffff16612365565b61167d5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116e660048301826132ca565b6116f46005830160006132ca565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112c5565b7f0000000000000000000000000000000000000000000000000000000000000000611797576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff1633146117ea576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b61182c73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612371565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611864611c59565b61186d816123cf565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061190357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061063c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112b59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526124c4565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611abd5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8f919061404e565b15611bc6576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bd381602001516125d0565b6000611be28260200151610642565b9050805160001480611c06575080805190602001208260a001518051906020012014155b15611c43578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107419190613400565b611c55826020015183606001516126f6565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611cda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610741565b565b7f0000000000000000000000000000000000000000000000000000000000000000611d33576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611dc9576000838281518110611d5357611d53613d7a565b60200260200101519050611d7181600261273d90919063ffffffff16565b15611dc05760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611d36565b5060005b81518110156112b5576000828281518110611dea57611dea613d7a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e2e5750611e8a565b611e3960028261275f565b15611e885760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611dcd565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611f425760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611ff0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612014919061404e565b1561204b576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120588160400151612781565b6120658160200151612800565b61186d8160200151826060015161294e565b60606000611ea683612992565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261211282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426120f6919061409a565b85608001516fffffffffffffffffffffffffffffffff166129ed565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61213f83610e0a565b612181576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b61218c826000612220565b67ffffffffffffffff831660009081526007602052604090206121af9083612a17565b6121ba816000612220565b67ffffffffffffffff831660009081526007602052604090206121e09060020182612a17565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051612213939291906140ad565b60405180910390a1505050565b8151156122e75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612276575060408201516fffffffffffffffffffffffffffffffff16155b156122af57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107419190614130565b8015611c55576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612320575060208201516fffffffffffffffffffffffffffffffff1615155b15611c5557816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107419190614130565b6000611ea68383612bb9565b6000611ea68383612c08565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a1e9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016119a6565b3373ffffffffffffffffffffffffffffffffffffffff82160361244e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610741565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612526826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612cfb9092919063ffffffff16565b8051909150156112b55780806020019051810190612544919061404e565b6112b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610741565b6125d981610e0a565b61261b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561269a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126be919061404e565b61186d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c5590600201827f0000000000000000000000000000000000000000000000000000000000000000612d0a565b6000611ea68373ffffffffffffffffffffffffffffffffffffffff8416612c08565b6000611ea68373ffffffffffffffffffffffffffffffffffffffff8416612bb9565b7f00000000000000000000000000000000000000000000000000000000000000001561186d576127b260028261308d565b61186d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610741565b61280981610e0a565b61284b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156128c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e8919061416c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461186d576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c5590827f0000000000000000000000000000000000000000000000000000000000000000612d0a565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106e657602002820191906000526020600020905b8154815260200190600101908083116129ce5750505050509050919050565b6000612a0c856129fd8486614189565b612a0790876141a0565b6130bc565b90505b949350505050565b8154600090612a4090700100000000000000000000000000000000900463ffffffff164261409a565b90508015612ae25760018301548354612a88916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166129ed565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612b08916fffffffffffffffffffffffffffffffff90811691166130bc565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612213908490614130565b6000818152600183016020526040812054612c005750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561063c565b50600061063c565b60008181526001830160205260408120548015612cf1576000612c2c60018361409a565b8554909150600090612c409060019061409a565b9050808214612ca5576000866000018281548110612c6057612c60613d7a565b9060005260206000200154905080876000018481548110612c8357612c83613d7a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612cb657612cb66141b3565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061063c565b600091505061063c565b6060612a0f84846000856130d2565b825474010000000000000000000000000000000000000000900460ff161580612d31575081155b15612d3b57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612d8190700100000000000000000000000000000000900463ffffffff164261409a565b90508015612e415781831115612dc3576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612dfd9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166129ed565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612ef85773ffffffffffffffffffffffffffffffffffffffff8416612ea0576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610741565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610741565b8483101561300b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f3c908261409a565b612f46878a61409a565b612f5091906141a0565b612f5a91906141e2565b905073ffffffffffffffffffffffffffffffffffffffff8616612fb3576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610741565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610741565b613015858461409a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611ea6565b60008183106130cb5781611ea6565b5090919050565b606082471015613164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610741565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161318d919061421d565b60006040518083038185875af1925050503d80600081146131ca576040519150601f19603f3d011682016040523d82523d6000602084013e6131cf565b606091505b50915091506131e0878383876131eb565b979650505050505050565b6060831561328157825160000361327a5773ffffffffffffffffffffffffffffffffffffffff85163b61327a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610741565b5081612a0f565b612a0f83838151156132965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107419190613400565b5080546132d6906138fd565b6000825580601f106132e6575050565b601f01602090049060005260206000209081019061186d91905b808211156133145760008155600101613300565b5090565b60006020828403121561332a57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611ea657600080fd5b803567ffffffffffffffff8116811461337257600080fd5b919050565b60006020828403121561338957600080fd5b611ea68261335a565b60005b838110156133ad578181015183820152602001613395565b50506000910152565b600081518084526133ce816020860160208601613392565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611ea660208301846133b6565b60006020828403121561342557600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461186d57600080fd5b80356133728161342c565b60006020828403121561346b57600080fd5b8135611ea68161342c565b60006020828403121561348857600080fd5b813567ffffffffffffffff81111561349f57600080fd5b82016101008185031215611ea657600080fd5b60008083601f8401126134c457600080fd5b50813567ffffffffffffffff8111156134dc57600080fd5b6020830191508360208260051b85010111156134f757600080fd5b9250929050565b6000806000806040858703121561351457600080fd5b843567ffffffffffffffff8082111561352c57600080fd5b613538888389016134b2565b9096509450602087013591508082111561355157600080fd5b5061355e878288016134b2565b95989497509550505050565b6000806040838503121561357d57600080fd5b82356135888161342c565b946020939093013593505050565b6000806000604084860312156135ab57600080fd5b6135b48461335a565b9250602084013567ffffffffffffffff808211156135d157600080fd5b818601915086601f8301126135e557600080fd5b8135818111156135f457600080fd5b87602082850101111561360657600080fd5b6020830194508093505050509250925092565b60006020828403121561362b57600080fd5b813567ffffffffffffffff81111561364257600080fd5b820160a08185031215611ea657600080fd5b60208152600082516040602084015261367060608401826133b6565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526136ab82826133b6565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561370257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016136d0565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561370257835167ffffffffffffffff168352928401929184019160010161372a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156137a3576137a3613750565b60405290565b60405160c0810167ffffffffffffffff811182821017156137a3576137a3613750565b801515811461186d57600080fd5b8035613372816137cc565b80356fffffffffffffffffffffffffffffffff8116811461337257600080fd5b60006060828403121561381757600080fd5b6040516060810181811067ffffffffffffffff8211171561383a5761383a613750565b604052905080823561384b816137cc565b8152613859602084016137e5565b602082015261386a604084016137e5565b60408201525092915050565b600080600060e0848603121561388b57600080fd5b6138948461335a565b92506138a38560208601613805565b91506138b28560808601613805565b90509250925092565b600080602083850312156138ce57600080fd5b823567ffffffffffffffff8111156138e557600080fd5b6138f1858286016134b2565b90969095509350505050565b600181811c9082168061391157607f821691505b60208210810361394a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561396257600080fd5b5051919050565b600082601f83011261397a57600080fd5b813567ffffffffffffffff8082111561399557613995613750565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156139db576139db613750565b816040528381528660208588010111156139f457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613a2757600080fd5b613a2f61377f565b823567ffffffffffffffff80821115613a4757600080fd5b613a5336838701613969565b8352613a616020860161335a565b6020840152613a726040860161344e565b604084015260608501356060840152613a8d6080860161344e565b608084015260a0850135915080821115613aa657600080fd5b613ab236838701613969565b60a084015260c0850135915080821115613acb57600080fd5b613ad736838701613969565b60c084015260e0850135915080821115613af057600080fd5b50613afd36828601613969565b60e08301525092915050565b601f8211156112b5576000816000526020600020601f850160051c81016020861015613b325750805b601f850160051c820191505b81811015613b5157828155600101613b3e565b505050505050565b67ffffffffffffffff831115613b7157613b71613750565b613b8583613b7f83546138fd565b83613b09565b6000601f841160018114613bd75760008515613ba15750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613c6d565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613c265786850135825560209485019460019092019101613c06565b5086821015613c61577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613c8760408301866133b6565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613cea57600080fd5b60405160a0810167ffffffffffffffff8282108183111715613d0e57613d0e613750565b816040528435915080821115613d2357600080fd5b50613d3036828601613969565b825250613d3f6020840161335a565b60208201526040830135613d528161342c565b6040820152606083810135908201526080830135613d6f8161342c565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ddd57600080fd5b9190910192915050565b60006101408236031215613dfa57600080fd5b613e026137a9565b613e0b8361335a565b8152613e19602084016137da565b6020820152604083013567ffffffffffffffff80821115613e3957600080fd5b613e4536838701613969565b60408401526060850135915080821115613e5e57600080fd5b50613e6b36828601613969565b606083015250613e7e3660808501613805565b6080820152613e903660e08501613805565b60a082015292915050565b815167ffffffffffffffff811115613eb557613eb5613750565b613ec981613ec384546138fd565b84613b09565b602080601f831160018114613f1c5760008415613ee65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b51565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613f6957888601518255948401946001909101908401613f4a565b5085821015613fa557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613fd9818401876133b6565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506140179050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526136ab565b60006020828403121561406057600080fd5b8151611ea6816137cc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561063c5761063c61406b565b67ffffffffffffffff8416815260e081016140f960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612a0f565b6060810161063c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561417e57600080fd5b8151611ea68161342c565b808202811582820484141761063c5761063c61406b565b8082018082111561063c5761063c61406b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614218577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613ddd81846020870161339256fea164736f6c6343000818000a", } var LockReleaseTokenPoolABI = LockReleaseTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go index 0aa2084a82..6a0a3ac4d8 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go @@ -83,7 +83,7 @@ type TokenPoolChainUpdate struct { var LockReleaseTokenPoolAndProxyMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162004f0a38038062004f0a83398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508181146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516147896200078160003960008181610545015261191b0152600081816105f201528181611f550152612b110152600081816105cc01528181611ce801526122080152600081816102ad01528181610302015281816107d0015281816108a20152818161097c015281816119dd01528181611c08015281816121280152818161230e01528181612aa70152612cfc01526147896000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e13146105f0578063eb521a4c14610616578063f2fde38b1461062957600080fd5b8063db6327dc146105b7578063dc0bd971146105ca57600080fd5b8063c0d7865514610569578063c4bffe2b1461057c578063c75eea9c14610591578063cf7401f3146105a457600080fd5b8063a8d87a3b11610114578063b0f479a1116100f9578063b0f479a114610512578063b794658014610530578063bb98546b1461054357600080fd5b8063a8d87a3b14610490578063af58d59f146104a357600080fd5b80638da5cb5b1461042a5780639766b932146104485780639a4575b91461045b578063a7cd63b71461047b57600080fd5b806354c8a4f3116101d857806378a010b2116101a75780637d54534e1161018c5780637d54534e146103f157806383826b2b146104045780638926f54f1461041757600080fd5b806378a010b2146103d657806379ba5097146103e957600080fd5b806354c8a4f31461037f57806366320087146103925780636cfd1553146103a55780636d3d1a58146103b857600080fd5b806321df0da71161021457806321df0da7146102ab578063240028e8146102f2578063390775371461033f578063432a6ba31461036157600080fd5b806301ffc9a7146102465780630a2fd4931461026e5780630a861f2a1461028e578063181f5a77146102a3575b600080fd5b6102596102543660046136a6565b61063c565b60405190151581526020015b60405180910390f35b61028161027c366004613705565b610698565b604051610265919061378e565b6102a161029c3660046137a1565b610748565b005b6102816108f9565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102596103003660046137e7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61035261034d366004613804565b610915565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a161038d36600461388c565b610a4e565b6102a16103a03660046138f8565b610ac9565b6102a16103b33660046137e7565b610b55565b60085473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16103e4366004613924565b610ba4565b6102a1610d13565b6102a16103ff3660046137e7565b610e10565b6102596104123660046139a7565b610e5f565b610259610425366004613705565b610f2c565b60005473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16104563660046137e7565b610f43565b61046e6104693660046139de565b610fd2565b6040516102659190613a19565b61048361109b565b6040516102659190613a79565b6102cd61049e366004613705565b503090565b6104b66104b1366004613705565b6110ac565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102cd565b61028161053e366004613705565b611181565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16105773660046137e7565b6111ac565b610584611280565b6040516102659190613ad3565b6104b661059f366004613705565b611338565b6102a16105b2366004613c8a565b61140a565b6102a16105c5366004613ccf565b611493565b7f00000000000000000000000000000000000000000000000000000000000000006102cd565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16106243660046137a1565b611919565b6102a16106373660046137e7565b611a35565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d40566000000000000000000000000000000000000000000000000000000001480610692575061069282611a49565b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106c390613d11565b80601f01602080910402602001604051908101604052809291908181526020018280546106ef90613d11565b801561073c5780601f106107115761010080835404028352916020019161073c565b820191906000526020600020905b81548152906001019060200180831161071f57829003601f168201915b50505050509050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146107a0576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190613d64565b1015610888576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108c973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611b2d565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b60405180606001604052806022815260200161475b6022913981565b60408051602081019091526000815261093561093083613e19565b611c01565b60095473ffffffffffffffffffffffffffffffffffffffff166109ac576109a761096560608401604085016137e7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611b2d565b6109bd565b6109bd6109b883613e19565b611e32565b6109cd60608301604084016137e7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f528460600135604051610a2f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a56611ed0565b610ac384848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f5392505050565b50505050565b610ad1611ed0565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610b3957600080fd5b505af1158015610b4d573d6000803e3d6000fd5b505050505050565b610b5d611ed0565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610bac611ed0565b610bb583610f2c565b610bf7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b67ffffffffffffffff831660009081526007602052604081206004018054610c1e90613d11565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4a90613d11565b8015610c975780601f10610c6c57610100808354040283529160200191610c97565b820191906000526020600020905b815481529060010190602001808311610c7a57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cc6838583613f56565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d0593929190614070565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610797565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e18611ed0565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610f255750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610f01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2591906140d4565b9392505050565b6000610692600567ffffffffffffffff8416612109565b610f4b611ed0565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610ff7610ff2836140f1565b612121565b60095473ffffffffffffffffffffffffffffffffffffffff161561102657611026611021836140f1565b6122eb565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a2604051806040016040528061108084602001602081019061053e9190613705565b81526040805160208181019092526000815291015292915050565b60606110a76002612405565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261069290612412565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106c390613d11565b6111b4611ed0565b73ffffffffffffffffffffffffffffffffffffffff8116611201576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610fc6565b6060600061128e6005612405565b90506000815167ffffffffffffffff8111156112ac576112ac613b15565b6040519080825280602002602001820160405280156112d5578160200160208202803683370190505b50905060005b8251811015611331578281815181106112f6576112f6614193565b602002602001015182828151811061131057611310614193565b67ffffffffffffffff909216602092830291909101909101526001016112db565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261069290612412565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061144a575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611483576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b61148e8383836124c4565b505050565b61149b611ed0565b60005b8181101561148e5760008383838181106114ba576114ba614193565b90506020028101906114cc91906141c2565b6114d590614200565b90506114ea81608001518260200151156125ae565b6114fd8160a001518260200151156125ae565b8060200151156117f957805161151f9060059067ffffffffffffffff166126e7565b6115645780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b60408101515115806115795750606081015151155b156115b0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061179190826142b4565b50606082015160058201906117a690826142b4565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506117ec94939291906143ce565b60405180910390a1611910565b80516118119060059067ffffffffffffffff166126f3565b6118565780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118bf6004830182613658565b6118cd600583016000613658565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161149e565b7f0000000000000000000000000000000000000000000000000000000000000000611970576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff1633146119c3576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b611a0573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846126ff565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611a3d611ed0565b611a468161275d565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611adc57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261148e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612852565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611c965760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6891906140d4565b15611d9f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dac816020015161295e565b6000611dbb8260200151610698565b9050805160001480611ddf575080805190602001208260a001518051906020012014155b15611e1c578160a001516040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610797919061378e565b611e2e82602001518360600151612a84565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611e9b9490939291600401614467565b600060405180830381600087803b158015611eb557600080fd5b505af1158015611ec9573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611f51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610797565b565b7f0000000000000000000000000000000000000000000000000000000000000000611faa576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612040576000838281518110611fca57611fca614193565b60200260200101519050611fe8816002612acb90919063ffffffff16565b156120375760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611fad565b5060005b815181101561148e57600082828151811061206157612061614193565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120a55750612101565b6120b0600282612aed565b156120ff5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612044565b60008181526001830160205260408120541515610f25565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121b65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612264573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228891906140d4565b156122bf576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122cc8160400151612b0f565b6122d98160200151612b8e565b611a4681602001518260600151612cdc565b60095460608201516123389173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611b2d565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909516946396875445946123a0949392916004016144c8565b6000604051808303816000875af11580156123bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e2e9190810190614528565b60606000610f2583612d20565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526124a082606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261248491906145c5565b85608001516fffffffffffffffffffffffffffffffff16612d7b565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6124cd83610f2c565b61250f576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b61251a8260006125ae565b67ffffffffffffffff8316600090815260076020526040902061253d9083612da5565b6125488160006125ae565b67ffffffffffffffff8316600090815260076020526040902061256e9060020182612da5565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516125a1939291906145d8565b60405180910390a1505050565b8151156126755781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612604575060408201516fffffffffffffffffffffffffffffffff16155b1561263d57816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610797919061465b565b8015611e2e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806126ae575060208201516fffffffffffffffffffffffffffffffff1615155b15611e2e57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610797919061465b565b6000610f258383612f47565b6000610f258383612f96565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ac39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611b7f565b3373ffffffffffffffffffffffffffffffffffffffff8216036127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610797565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006128b4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130899092919063ffffffff16565b80519091501561148e57808060200190518101906128d291906140d4565b61148e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610797565b61296781610f2c565b6129a9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612a28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4c91906140d4565b611a46576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e2e90600201827f0000000000000000000000000000000000000000000000000000000000000000613098565b6000610f258373ffffffffffffffffffffffffffffffffffffffff8416612f96565b6000610f258373ffffffffffffffffffffffffffffffffffffffff8416612f47565b7f000000000000000000000000000000000000000000000000000000000000000015611a4657612b4060028261341b565b611a46576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610797565b612b9781610f2c565b612bd9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c769190614697565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a46576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e2e90827f0000000000000000000000000000000000000000000000000000000000000000613098565b60608160000180548060200260200160405190810160405280929190818152602001828054801561073c57602002820191906000526020600020905b815481526020019060010190808311612d5c5750505050509050919050565b6000612d9a85612d8b84866146b4565b612d9590876146cb565b61344a565b90505b949350505050565b8154600090612dce90700100000000000000000000000000000000900463ffffffff16426145c5565b90508015612e705760018301548354612e16916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612d7b565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612e96916fffffffffffffffffffffffffffffffff908116911661344a565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906125a190849061465b565b6000818152600183016020526040812054612f8e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610692565b506000610692565b6000818152600183016020526040812054801561307f576000612fba6001836145c5565b8554909150600090612fce906001906145c5565b9050818114613033576000866000018281548110612fee57612fee614193565b906000526020600020015490508087600001848154811061301157613011614193565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613044576130446146de565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610692565b6000915050610692565b6060612d9d8484600085613460565b825474010000000000000000000000000000000000000000900460ff1615806130bf575081155b156130c957505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061310f90700100000000000000000000000000000000900463ffffffff16426145c5565b905080156131cf5781831115613151576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461318b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612d7b565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156132865773ffffffffffffffffffffffffffffffffffffffff841661322e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610797565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610797565b848310156133995760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906132ca90826145c5565b6132d4878a6145c5565b6132de91906146cb565b6132e8919061470d565b905073ffffffffffffffffffffffffffffffffffffffff8616613341576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610797565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610797565b6133a385846145c5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610f25565b60008183106134595781610f25565b5090919050565b6060824710156134f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610797565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161351b9190614748565b60006040518083038185875af1925050503d8060008114613558576040519150601f19603f3d011682016040523d82523d6000602084013e61355d565b606091505b509150915061356e87838387613579565b979650505050505050565b6060831561360f5782516000036136085773ffffffffffffffffffffffffffffffffffffffff85163b613608576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610797565b5081612d9d565b612d9d83838151156136245781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610797919061378e565b50805461366490613d11565b6000825580601f10613674575050565b601f016020900490600052602060002090810190611a4691905b808211156136a2576000815560010161368e565b5090565b6000602082840312156136b857600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f2557600080fd5b803567ffffffffffffffff8116811461370057600080fd5b919050565b60006020828403121561371757600080fd5b610f25826136e8565b60005b8381101561373b578181015183820152602001613723565b50506000910152565b6000815180845261375c816020860160208601613720565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f256020830184613744565b6000602082840312156137b357600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a4657600080fd5b8035613700816137ba565b6000602082840312156137f957600080fd5b8135610f25816137ba565b60006020828403121561381657600080fd5b813567ffffffffffffffff81111561382d57600080fd5b82016101008185031215610f2557600080fd5b60008083601f84011261385257600080fd5b50813567ffffffffffffffff81111561386a57600080fd5b6020830191508360208260051b850101111561388557600080fd5b9250929050565b600080600080604085870312156138a257600080fd5b843567ffffffffffffffff808211156138ba57600080fd5b6138c688838901613840565b909650945060208701359150808211156138df57600080fd5b506138ec87828801613840565b95989497509550505050565b6000806040838503121561390b57600080fd5b8235613916816137ba565b946020939093013593505050565b60008060006040848603121561393957600080fd5b613942846136e8565b9250602084013567ffffffffffffffff8082111561395f57600080fd5b818601915086601f83011261397357600080fd5b81358181111561398257600080fd5b87602082850101111561399457600080fd5b6020830194508093505050509250925092565b600080604083850312156139ba57600080fd5b6139c3836136e8565b915060208301356139d3816137ba565b809150509250929050565b6000602082840312156139f057600080fd5b813567ffffffffffffffff811115613a0757600080fd5b820160a08185031215610f2557600080fd5b602081526000825160406020840152613a356060840182613744565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613a708282613744565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ac757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613a95565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ac757835167ffffffffffffffff1683529284019291840191600101613aef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613b6857613b68613b15565b60405290565b60405160c0810167ffffffffffffffff81118282101715613b6857613b68613b15565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bd857613bd8613b15565b604052919050565b8015158114611a4657600080fd5b803561370081613be0565b80356fffffffffffffffffffffffffffffffff8116811461370057600080fd5b600060608284031215613c2b57600080fd5b6040516060810181811067ffffffffffffffff82111715613c4e57613c4e613b15565b6040529050808235613c5f81613be0565b8152613c6d60208401613bf9565b6020820152613c7e60408401613bf9565b60408201525092915050565b600080600060e08486031215613c9f57600080fd5b613ca8846136e8565b9250613cb78560208601613c19565b9150613cc68560808601613c19565b90509250925092565b60008060208385031215613ce257600080fd5b823567ffffffffffffffff811115613cf957600080fd5b613d0585828601613840565b90969095509350505050565b600181811c90821680613d2557607f821691505b602082108103613d5e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613d7657600080fd5b5051919050565b600067ffffffffffffffff821115613d9757613d97613b15565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613dd457600080fd5b8135613de7613de282613d7d565b613b91565b818152846020838601011115613dfc57600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613e2c57600080fd5b613e34613b44565b823567ffffffffffffffff80821115613e4c57600080fd5b613e5836838701613dc3565b8352613e66602086016136e8565b6020840152613e77604086016137dc565b604084015260608501356060840152613e92608086016137dc565b608084015260a0850135915080821115613eab57600080fd5b613eb736838701613dc3565b60a084015260c0850135915080821115613ed057600080fd5b613edc36838701613dc3565b60c084015260e0850135915080821115613ef557600080fd5b50613f0236828601613dc3565b60e08301525092915050565b601f82111561148e576000816000526020600020601f850160051c81016020861015613f375750805b601f850160051c820191505b81811015610b4d57828155600101613f43565b67ffffffffffffffff831115613f6e57613f6e613b15565b613f8283613f7c8354613d11565b83613f0e565b6000601f841160018114613fd45760008515613f9e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611ec9565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140235786850135825560209485019460019092019101614003565b508682101561405e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006140836040830186613744565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b6000602082840312156140e657600080fd5b8151610f2581613be0565b600060a0823603121561410357600080fd5b60405160a0810167ffffffffffffffff828210818311171561412757614127613b15565b81604052843591508082111561413c57600080fd5b5061414936828601613dc3565b825250614158602084016136e8565b6020820152604083013561416b816137ba565b6040820152606083810135908201526080830135614188816137ba565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126141f657600080fd5b9190910192915050565b6000610140823603121561421357600080fd5b61421b613b6e565b614224836136e8565b815261423260208401613bee565b6020820152604083013567ffffffffffffffff8082111561425257600080fd5b61425e36838701613dc3565b6040840152606085013591508082111561427757600080fd5b5061428436828601613dc3565b6060830152506142973660808501613c19565b60808201526142a93660e08501613c19565b60a082015292915050565b815167ffffffffffffffff8111156142ce576142ce613b15565b6142e2816142dc8454613d11565b84613f0e565b602080601f83116001811461433557600084156142ff5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610b4d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561438257888601518255948401946001909101908401614363565b50858210156143be57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526143f281840187613744565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506144309050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613a70565b60a08152600061447a60a0830187613744565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a0602082015260006144f760a0830186613744565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561453a57600080fd5b815167ffffffffffffffff81111561455157600080fd5b8201601f8101841361456257600080fd5b8051614570613de282613d7d565b81815285602083850101111561458557600080fd5b613a70826020830160208601613720565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561069257610692614596565b67ffffffffffffffff8416815260e0810161462460208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612d9d565b6060810161069282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156146a957600080fd5b8151610f25816137ba565b808202811582820484141761069257610692614596565b8082018082111561069257610692614596565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614743577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082516141f681846020870161372056fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e30a164736f6c6343000818000a", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004f0a38038062004f0a83398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508082146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516147896200078160003960008181610545015261191b0152600081816105f201528181611f550152612b110152600081816105cc01528181611ce801526122080152600081816102ad01528181610302015281816107d0015281816108a20152818161097c015281816119dd01528181611c08015281816121280152818161230e01528181612aa70152612cfc01526147896000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e13146105f0578063eb521a4c14610616578063f2fde38b1461062957600080fd5b8063db6327dc146105b7578063dc0bd971146105ca57600080fd5b8063c0d7865514610569578063c4bffe2b1461057c578063c75eea9c14610591578063cf7401f3146105a457600080fd5b8063a8d87a3b11610114578063b0f479a1116100f9578063b0f479a114610512578063b794658014610530578063bb98546b1461054357600080fd5b8063a8d87a3b14610490578063af58d59f146104a357600080fd5b80638da5cb5b1461042a5780639766b932146104485780639a4575b91461045b578063a7cd63b71461047b57600080fd5b806354c8a4f3116101d857806378a010b2116101a75780637d54534e1161018c5780637d54534e146103f157806383826b2b146104045780638926f54f1461041757600080fd5b806378a010b2146103d657806379ba5097146103e957600080fd5b806354c8a4f31461037f57806366320087146103925780636cfd1553146103a55780636d3d1a58146103b857600080fd5b806321df0da71161021457806321df0da7146102ab578063240028e8146102f2578063390775371461033f578063432a6ba31461036157600080fd5b806301ffc9a7146102465780630a2fd4931461026e5780630a861f2a1461028e578063181f5a77146102a3575b600080fd5b6102596102543660046136a6565b61063c565b60405190151581526020015b60405180910390f35b61028161027c366004613705565b610698565b604051610265919061378e565b6102a161029c3660046137a1565b610748565b005b6102816108f9565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102596103003660046137e7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61035261034d366004613804565b610915565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a161038d36600461388c565b610a4e565b6102a16103a03660046138f8565b610ac9565b6102a16103b33660046137e7565b610b55565b60085473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16103e4366004613924565b610ba4565b6102a1610d13565b6102a16103ff3660046137e7565b610e10565b6102596104123660046139a7565b610e5f565b610259610425366004613705565b610f2c565b60005473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16104563660046137e7565b610f43565b61046e6104693660046139de565b610fd2565b6040516102659190613a19565b61048361109b565b6040516102659190613a79565b6102cd61049e366004613705565b503090565b6104b66104b1366004613705565b6110ac565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102cd565b61028161053e366004613705565b611181565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16105773660046137e7565b6111ac565b610584611280565b6040516102659190613ad3565b6104b661059f366004613705565b611338565b6102a16105b2366004613c8a565b61140a565b6102a16105c5366004613ccf565b611493565b7f00000000000000000000000000000000000000000000000000000000000000006102cd565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16106243660046137a1565b611919565b6102a16106373660046137e7565b611a35565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d40566000000000000000000000000000000000000000000000000000000001480610692575061069282611a49565b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106c390613d11565b80601f01602080910402602001604051908101604052809291908181526020018280546106ef90613d11565b801561073c5780601f106107115761010080835404028352916020019161073c565b820191906000526020600020905b81548152906001019060200180831161071f57829003601f168201915b50505050509050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146107a0576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190613d64565b1015610888576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108c973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611b2d565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b60405180606001604052806022815260200161475b6022913981565b60408051602081019091526000815261093561093083613e19565b611c01565b60095473ffffffffffffffffffffffffffffffffffffffff166109ac576109a761096560608401604085016137e7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611b2d565b6109bd565b6109bd6109b883613e19565b611e32565b6109cd60608301604084016137e7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f528460600135604051610a2f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a56611ed0565b610ac384848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f5392505050565b50505050565b610ad1611ed0565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610b3957600080fd5b505af1158015610b4d573d6000803e3d6000fd5b505050505050565b610b5d611ed0565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610bac611ed0565b610bb583610f2c565b610bf7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b67ffffffffffffffff831660009081526007602052604081206004018054610c1e90613d11565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4a90613d11565b8015610c975780601f10610c6c57610100808354040283529160200191610c97565b820191906000526020600020905b815481529060010190602001808311610c7a57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cc6838583613f56565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d0593929190614070565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610797565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e18611ed0565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610f255750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610f01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2591906140d4565b9392505050565b6000610692600567ffffffffffffffff8416612109565b610f4b611ed0565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610ff7610ff2836140f1565b612121565b60095473ffffffffffffffffffffffffffffffffffffffff161561102657611026611021836140f1565b6122eb565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a2604051806040016040528061108084602001602081019061053e9190613705565b81526040805160208181019092526000815291015292915050565b60606110a76002612405565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261069290612412565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106c390613d11565b6111b4611ed0565b73ffffffffffffffffffffffffffffffffffffffff8116611201576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610fc6565b6060600061128e6005612405565b90506000815167ffffffffffffffff8111156112ac576112ac613b15565b6040519080825280602002602001820160405280156112d5578160200160208202803683370190505b50905060005b8251811015611331578281815181106112f6576112f6614193565b602002602001015182828151811061131057611310614193565b67ffffffffffffffff909216602092830291909101909101526001016112db565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261069290612412565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061144a575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611483576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b61148e8383836124c4565b505050565b61149b611ed0565b60005b8181101561148e5760008383838181106114ba576114ba614193565b90506020028101906114cc91906141c2565b6114d590614200565b90506114ea81608001518260200151156125ae565b6114fd8160a001518260200151156125ae565b8060200151156117f957805161151f9060059067ffffffffffffffff166126e7565b6115645780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b60408101515115806115795750606081015151155b156115b0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061179190826142b4565b50606082015160058201906117a690826142b4565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506117ec94939291906143ce565b60405180910390a1611910565b80516118119060059067ffffffffffffffff166126f3565b6118565780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118bf6004830182613658565b6118cd600583016000613658565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161149e565b7f0000000000000000000000000000000000000000000000000000000000000000611970576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff1633146119c3576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b611a0573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846126ff565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611a3d611ed0565b611a468161275d565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611adc57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261148e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612852565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611c965760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6891906140d4565b15611d9f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dac816020015161295e565b6000611dbb8260200151610698565b9050805160001480611ddf575080805190602001208260a001518051906020012014155b15611e1c578160a001516040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610797919061378e565b611e2e82602001518360600151612a84565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611e9b9490939291600401614467565b600060405180830381600087803b158015611eb557600080fd5b505af1158015611ec9573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611f51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610797565b565b7f0000000000000000000000000000000000000000000000000000000000000000611faa576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612040576000838281518110611fca57611fca614193565b60200260200101519050611fe8816002612acb90919063ffffffff16565b156120375760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611fad565b5060005b815181101561148e57600082828151811061206157612061614193565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120a55750612101565b6120b0600282612aed565b156120ff5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612044565b60008181526001830160205260408120541515610f25565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121b65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612264573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228891906140d4565b156122bf576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122cc8160400151612b0f565b6122d98160200151612b8e565b611a4681602001518260600151612cdc565b60095460608201516123389173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611b2d565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909516946396875445946123a0949392916004016144c8565b6000604051808303816000875af11580156123bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e2e9190810190614528565b60606000610f2583612d20565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526124a082606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261248491906145c5565b85608001516fffffffffffffffffffffffffffffffff16612d7b565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6124cd83610f2c565b61250f576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b61251a8260006125ae565b67ffffffffffffffff8316600090815260076020526040902061253d9083612da5565b6125488160006125ae565b67ffffffffffffffff8316600090815260076020526040902061256e9060020182612da5565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516125a1939291906145d8565b60405180910390a1505050565b8151156126755781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612604575060408201516fffffffffffffffffffffffffffffffff16155b1561263d57816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610797919061465b565b8015611e2e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806126ae575060208201516fffffffffffffffffffffffffffffffff1615155b15611e2e57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610797919061465b565b6000610f258383612f47565b6000610f258383612f96565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ac39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611b7f565b3373ffffffffffffffffffffffffffffffffffffffff8216036127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610797565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006128b4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130899092919063ffffffff16565b80519091501561148e57808060200190518101906128d291906140d4565b61148e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610797565b61296781610f2c565b6129a9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612a28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4c91906140d4565b611a46576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e2e90600201827f0000000000000000000000000000000000000000000000000000000000000000613098565b6000610f258373ffffffffffffffffffffffffffffffffffffffff8416612f96565b6000610f258373ffffffffffffffffffffffffffffffffffffffff8416612f47565b7f000000000000000000000000000000000000000000000000000000000000000015611a4657612b4060028261341b565b611a46576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610797565b612b9781610f2c565b612bd9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c769190614697565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a46576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e2e90827f0000000000000000000000000000000000000000000000000000000000000000613098565b60608160000180548060200260200160405190810160405280929190818152602001828054801561073c57602002820191906000526020600020905b815481526020019060010190808311612d5c5750505050509050919050565b6000612d9a85612d8b84866146b4565b612d9590876146cb565b61344a565b90505b949350505050565b8154600090612dce90700100000000000000000000000000000000900463ffffffff16426145c5565b90508015612e705760018301548354612e16916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612d7b565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612e96916fffffffffffffffffffffffffffffffff908116911661344a565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906125a190849061465b565b6000818152600183016020526040812054612f8e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610692565b506000610692565b6000818152600183016020526040812054801561307f576000612fba6001836145c5565b8554909150600090612fce906001906145c5565b9050808214613033576000866000018281548110612fee57612fee614193565b906000526020600020015490508087600001848154811061301157613011614193565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613044576130446146de565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610692565b6000915050610692565b6060612d9d8484600085613460565b825474010000000000000000000000000000000000000000900460ff1615806130bf575081155b156130c957505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061310f90700100000000000000000000000000000000900463ffffffff16426145c5565b905080156131cf5781831115613151576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461318b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612d7b565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156132865773ffffffffffffffffffffffffffffffffffffffff841661322e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610797565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610797565b848310156133995760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906132ca90826145c5565b6132d4878a6145c5565b6132de91906146cb565b6132e8919061470d565b905073ffffffffffffffffffffffffffffffffffffffff8616613341576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610797565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610797565b6133a385846145c5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610f25565b60008183106134595781610f25565b5090919050565b6060824710156134f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610797565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161351b9190614748565b60006040518083038185875af1925050503d8060008114613558576040519150601f19603f3d011682016040523d82523d6000602084013e61355d565b606091505b509150915061356e87838387613579565b979650505050505050565b6060831561360f5782516000036136085773ffffffffffffffffffffffffffffffffffffffff85163b613608576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610797565b5081612d9d565b612d9d83838151156136245781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610797919061378e565b50805461366490613d11565b6000825580601f10613674575050565b601f016020900490600052602060002090810190611a4691905b808211156136a2576000815560010161368e565b5090565b6000602082840312156136b857600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f2557600080fd5b803567ffffffffffffffff8116811461370057600080fd5b919050565b60006020828403121561371757600080fd5b610f25826136e8565b60005b8381101561373b578181015183820152602001613723565b50506000910152565b6000815180845261375c816020860160208601613720565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f256020830184613744565b6000602082840312156137b357600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a4657600080fd5b8035613700816137ba565b6000602082840312156137f957600080fd5b8135610f25816137ba565b60006020828403121561381657600080fd5b813567ffffffffffffffff81111561382d57600080fd5b82016101008185031215610f2557600080fd5b60008083601f84011261385257600080fd5b50813567ffffffffffffffff81111561386a57600080fd5b6020830191508360208260051b850101111561388557600080fd5b9250929050565b600080600080604085870312156138a257600080fd5b843567ffffffffffffffff808211156138ba57600080fd5b6138c688838901613840565b909650945060208701359150808211156138df57600080fd5b506138ec87828801613840565b95989497509550505050565b6000806040838503121561390b57600080fd5b8235613916816137ba565b946020939093013593505050565b60008060006040848603121561393957600080fd5b613942846136e8565b9250602084013567ffffffffffffffff8082111561395f57600080fd5b818601915086601f83011261397357600080fd5b81358181111561398257600080fd5b87602082850101111561399457600080fd5b6020830194508093505050509250925092565b600080604083850312156139ba57600080fd5b6139c3836136e8565b915060208301356139d3816137ba565b809150509250929050565b6000602082840312156139f057600080fd5b813567ffffffffffffffff811115613a0757600080fd5b820160a08185031215610f2557600080fd5b602081526000825160406020840152613a356060840182613744565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613a708282613744565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ac757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613a95565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ac757835167ffffffffffffffff1683529284019291840191600101613aef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613b6857613b68613b15565b60405290565b60405160c0810167ffffffffffffffff81118282101715613b6857613b68613b15565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bd857613bd8613b15565b604052919050565b8015158114611a4657600080fd5b803561370081613be0565b80356fffffffffffffffffffffffffffffffff8116811461370057600080fd5b600060608284031215613c2b57600080fd5b6040516060810181811067ffffffffffffffff82111715613c4e57613c4e613b15565b6040529050808235613c5f81613be0565b8152613c6d60208401613bf9565b6020820152613c7e60408401613bf9565b60408201525092915050565b600080600060e08486031215613c9f57600080fd5b613ca8846136e8565b9250613cb78560208601613c19565b9150613cc68560808601613c19565b90509250925092565b60008060208385031215613ce257600080fd5b823567ffffffffffffffff811115613cf957600080fd5b613d0585828601613840565b90969095509350505050565b600181811c90821680613d2557607f821691505b602082108103613d5e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613d7657600080fd5b5051919050565b600067ffffffffffffffff821115613d9757613d97613b15565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613dd457600080fd5b8135613de7613de282613d7d565b613b91565b818152846020838601011115613dfc57600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613e2c57600080fd5b613e34613b44565b823567ffffffffffffffff80821115613e4c57600080fd5b613e5836838701613dc3565b8352613e66602086016136e8565b6020840152613e77604086016137dc565b604084015260608501356060840152613e92608086016137dc565b608084015260a0850135915080821115613eab57600080fd5b613eb736838701613dc3565b60a084015260c0850135915080821115613ed057600080fd5b613edc36838701613dc3565b60c084015260e0850135915080821115613ef557600080fd5b50613f0236828601613dc3565b60e08301525092915050565b601f82111561148e576000816000526020600020601f850160051c81016020861015613f375750805b601f850160051c820191505b81811015610b4d57828155600101613f43565b67ffffffffffffffff831115613f6e57613f6e613b15565b613f8283613f7c8354613d11565b83613f0e565b6000601f841160018114613fd45760008515613f9e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611ec9565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140235786850135825560209485019460019092019101614003565b508682101561405e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006140836040830186613744565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b6000602082840312156140e657600080fd5b8151610f2581613be0565b600060a0823603121561410357600080fd5b60405160a0810167ffffffffffffffff828210818311171561412757614127613b15565b81604052843591508082111561413c57600080fd5b5061414936828601613dc3565b825250614158602084016136e8565b6020820152604083013561416b816137ba565b6040820152606083810135908201526080830135614188816137ba565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126141f657600080fd5b9190910192915050565b6000610140823603121561421357600080fd5b61421b613b6e565b614224836136e8565b815261423260208401613bee565b6020820152604083013567ffffffffffffffff8082111561425257600080fd5b61425e36838701613dc3565b6040840152606085013591508082111561427757600080fd5b5061428436828601613dc3565b6060830152506142973660808501613c19565b60808201526142a93660e08501613c19565b60a082015292915050565b815167ffffffffffffffff8111156142ce576142ce613b15565b6142e2816142dc8454613d11565b84613f0e565b602080601f83116001811461433557600084156142ff5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610b4d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561438257888601518255948401946001909101908401614363565b50858210156143be57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526143f281840187613744565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506144309050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613a70565b60a08152600061447a60a0830187613744565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a0602082015260006144f760a0830186613744565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561453a57600080fd5b815167ffffffffffffffff81111561455157600080fd5b8201601f8101841361456257600080fd5b8051614570613de282613d7d565b81815285602083850101111561458557600080fd5b613a70826020830160208601613720565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561069257610692614596565b67ffffffffffffffff8416815260e0810161462460208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612d9d565b6060810161069282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156146a957600080fd5b8151610f25816137ba565b808202811582820484141761069257610692614596565b8082018082111561069257610692614596565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614743577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082516141f681846020870161372056fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e30a164736f6c6343000818000a", } var LockReleaseTokenPoolAndProxyABI = LockReleaseTokenPoolAndProxyMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/price_registry/price_registry.go b/core/gethwrappers/ccip/generated/price_registry/price_registry.go index 6f04601fcb..f7b44ab66b 100644 --- a/core/gethwrappers/ccip/generated/price_registry/price_registry.go +++ b/core/gethwrappers/ccip/generated/price_registry/price_registry.go @@ -147,7 +147,7 @@ type PriceRegistryTokenTransferFeeConfigSingleTokenArgs struct { var PriceRegistryMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"validatePoolReturnData\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b506040516200695038038062006950833981016040819052620000349162001816565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a9f565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b6b565b5050505050505062001ad4565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001935565b60209081029190910101519050620002f560028262000ea4565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001935565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000ec4565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001935565b6020026020010151600a62000ec460201b90919060201c565b1562000499578281815181106200045b576200045b62001935565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001935565b6020026020010151600a62000ea460201b90919060201c565b156200053b57818181518110620004fd57620004fd62001935565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001935565b6020908102919091018101518051818301516001600160a01b0380831660008181526006875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001935565b6020026020010151905060008383815181106200065f576200065f62001935565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061018081015163ffffffff16155b80620006ba57506102008101516001600160e01b031916630a04b54b60e21b14155b80620006d75750602063ffffffff1681610160015163ffffffff16105b80620006f75750806060015163ffffffff1681610180015163ffffffff16115b15620007225760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260086020526040812060010154600160a81b900460e01b6001600160e01b0319169003620007a257816001600160401b03167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516200079491906200194b565b60405180910390a2620007e6565b816001600160401b03167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad9382604051620007dd91906200194b565b60405180910390a25b8060086000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a8154816001600160401b0302191690836001600160401b031602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000ac35762000ac362001935565b6020026020010151600001519050600083838151811062000ae85762000ae862001935565b6020908102919091018101518101516001600160a01b03841660008181526007845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000aa2565b60005b825181101562000dde57600083828151811062000b8f5762000b8f62001935565b6020026020010151905060008160000151905060005b82602001515181101562000dcf5760008360200151828151811062000bce5762000bce62001935565b602002602001015160200151905060008460200151838151811062000bf75762000bf762001935565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c565760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b03841660008181526009602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000dbc908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000ba5565b50505080600101905062000b6e565b5060005b81518110156200054457600082828151811062000e035762000e0362001935565b6020026020010151600001519050600083838151811062000e285762000e2862001935565b6020908102919091018101518101516001600160401b03841660008181526009845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000de2565b600062000ebb836001600160a01b03841662000edb565b90505b92915050565b600062000ebb836001600160a01b03841662000fdf565b6000818152600183016020526040812054801562000fd457600062000f0260018362001a9c565b855490915060009062000f189060019062001a9c565b905081811462000f8457600086600001828154811062000f3c5762000f3c62001935565b906000526020600020015490508087600001848154811062000f625762000f6262001935565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f985762000f9862001abe565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000ebe565b600091505062000ebe565b6000818152600183016020526040812054620010285750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000ebe565b50600062000ebe565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200106c576200106c62001031565b60405290565b60405160c081016001600160401b03811182821017156200106c576200106c62001031565b60405161022081016001600160401b03811182821017156200106c576200106c62001031565b604051601f8201601f191681016001600160401b0381118282101715620010e857620010e862001031565b604052919050565b80516001600160a01b03811681146200110857600080fd5b919050565b805163ffffffff811681146200110857600080fd5b6000606082840312156200113557600080fd5b604051606081016001600160401b03811182821017156200115a576200115a62001031565b604052825190915081906001600160601b03811681146200117a57600080fd5b81526200118a60208401620010f0565b60208201526200119d604084016200110d565b60408201525092915050565b60006001600160401b03821115620011c557620011c562001031565b5060051b60200190565b600082601f830112620011e157600080fd5b81516020620011fa620011f483620011a9565b620010bd565b8083825260208201915060208460051b8701019350868411156200121d57600080fd5b602086015b8481101562001244576200123681620010f0565b835291830191830162001222565b509695505050505050565b600082601f8301126200126157600080fd5b8151602062001274620011f483620011a9565b828152606092830285018201928282019190878511156200129457600080fd5b8387015b85811015620013275780890382811215620012b35760008081fd5b620012bd62001047565b620012c883620010f0565b8152604080601f1984011215620012df5760008081fd5b620012e962001047565b9250620012f8888501620010f0565b835283015160ff811681146200130e5760008081fd5b8288015280870191909152845292840192810162001298565b5090979650505050505050565b80516001600160401b03811681146200110857600080fd5b805161ffff811681146200110857600080fd5b805180151581146200110857600080fd5b600082601f8301126200138257600080fd5b8151602062001395620011f483620011a9565b82815260059290921b84018101918181019086841115620013b557600080fd5b8286015b84811015620012445780516001600160401b0380821115620013da57600080fd5b908801906040601f19838c038101821315620013f557600080fd5b620013ff62001047565b6200140c89860162001334565b815282850151848111156200142057600080fd5b8086019550508c603f8601126200143657600080fd5b8885015193506200144b620011f485620011a9565b84815260e09094028501830193898101908e8611156200146a57600080fd5b958401955b858710156200154357868f0360e08112156200148a57600080fd5b6200149462001047565b6200149f89620010f0565b815260c08683011215620014b257600080fd5b620014bc62001072565b9150620014cb8d8a016200110d565b8252620014da878a016200110d565b8d830152620014ec60608a016200134c565b87830152620014fe60808a016200110d565b60608301526200151160a08a016200110d565b60808301526200152460c08a016200135f565b60a0830152808d0191909152825260e09690960195908a01906200146f565b828b015250875250505092840192508301620013b9565b600082601f8301126200156c57600080fd5b815160206200157f620011f483620011a9565b82815260069290921b840181019181810190868411156200159f57600080fd5b8286015b84811015620012445760408189031215620015be5760008081fd5b620015c862001047565b620015d382620010f0565b8152620015e285830162001334565b81860152835291830191604001620015a3565b80516001600160e01b0319811681146200110857600080fd5b600082601f8301126200162057600080fd5b8151602062001633620011f483620011a9565b82815261024092830285018201928282019190878511156200165457600080fd5b8387015b85811015620013275780890382811215620016735760008081fd5b6200167d62001047565b620016888362001334565b815261022080601f1984011215620016a05760008081fd5b620016aa62001097565b9250620016b98885016200135f565b83526040620016ca8186016200134c565b898501526060620016dd8187016200110d565b8286015260809150620016f28287016200110d565b9085015260a0620017058682016200110d565b8286015260c091506200171a8287016200134c565b9085015260e06200172d8682016200110d565b828601526101009150620017438287016200134c565b90850152610120620017578682016200134c565b8286015261014091506200176d8287016200134c565b90850152610160620017818682016200110d565b828601526101809150620017978287016200110d565b908501526101a0620017ab8682016200110d565b828601526101c09150620017c182870162001334565b908501526101e0620017d58682016200110d565b828601526102009150620017eb8287016200135f565b90850152620017fc858301620015f5565b908401525080870191909152845292840192810162001658565b6000806000806000806000610120888a0312156200183357600080fd5b6200183f898962001122565b60608901519097506001600160401b03808211156200185d57600080fd5b6200186b8b838c01620011cf565b975060808a01519150808211156200188257600080fd5b620018908b838c01620011cf565b965060a08a0151915080821115620018a757600080fd5b620018b58b838c016200124f565b955060c08a0151915080821115620018cc57600080fd5b620018da8b838c0162001370565b945060e08a0151915080821115620018f157600080fd5b620018ff8b838c016200155a565b93506101008a01519150808211156200191757600080fd5b50620019268a828b016200160e565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610220810160208301516200196c602084018261ffff169052565b50604083015162001985604084018263ffffffff169052565b5060608301516200199e606084018263ffffffff169052565b506080830151620019b7608084018263ffffffff169052565b5060a0830151620019ce60a084018261ffff169052565b5060c0830151620019e760c084018263ffffffff169052565b5060e0830151620019fe60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a0808501516001600160401b0316908401526101c080850151909116908301526101e080840151151590830152610200928301516001600160e01b031916929091019190915290565b8181038181111562000ebe57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051614e2262001b2e600039600081816102d901528181611ad30152611b3c01526000818161029d0152818161104e01526110ae015260008181610269015281816110d701526111470152614e226000f3fe608060405234801561001057600080fd5b50600436106101b85760003560e01c80637afac322116100f9578063cc88924c11610097578063d8694ccd11610071578063d8694ccd14610a5c578063f2fde38b14610a6f578063f700042a14610a82578063ffdb4b3714610a9557600080fd5b8063cc88924c14610a2e578063cdc73d5114610a41578063d02641a014610a4957600080fd5b806391a2749a116100d357806391a2749a14610939578063a69c64c01461094c578063bf78e03f1461095f578063c4276bfc14610a0c57600080fd5b80637afac3221461078e57806382b49eb0146107a15780638da5cb5b1461091157600080fd5b8063407e108611610166578063514e8cff11610140578063514e8cff146104385780636def4ce7146104db578063770e2dc41461077357806379ba50971461078657600080fd5b8063407e1086146103c557806345ac924d146103d85780634ab35b0b146103f857600080fd5b8063181f5a7711610197578063181f5a77146103525780632451a6271461039b5780633937306f146103b057600080fd5b806241e5be146101bd578063061877e3146101e357806306285c691461023c575b600080fd5b6101d06101cb36600461380f565b610add565b6040519081526020015b60405180910390f35b6102236101f136600461384b565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101da565b610306604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101da565b61038e6040518060400160405280601781526020017f5072696365526567697374727920312e362e302d64657600000000000000000081525081565b6040516101da91906138ca565b6103a3610b4b565b6040516101da91906138dd565b6103c36103be366004613937565b610b5c565b005b6103c36103d3366004613a93565b610e11565b6103eb6103e6366004613bf1565b610e25565b6040516101da9190613c33565b61040b61040636600461384b565b610ef0565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6104ce610446366004613cc6565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600460209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101da9190613ce1565b6107666104e9366004613cc6565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081018290526102008101919091525067ffffffffffffffff908116600090815260086020908152604091829020825161022081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a0850152710100000000000000000000000000000000008304871660c08501527501000000000000000000000000000000000000000000808404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b010000000000000000000000000000000000000000000000000000009092048616610140840152600190930154808616610160840152640100000000810486166101808401526801000000000000000081049096166101a083015270010000000000000000000000000000000086049094166101c082015274010000000000000000000000000000000000000000850490911615156101e08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b1661020082015290565b6040516101da9190613d1c565b6103c3610781366004613f59565b610efb565b6103c3610f11565b6103c361079c366004614273565b611013565b6108b16107af3660046142d7565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff91909116600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101da9190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6103c3610947366004614301565b611025565b6103c361095a366004614392565b611036565b6109d861096d36600461384b565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526006825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101da565b610a1f610a1a366004614457565b611047565b6040516101da939291906144f2565b6103c3610a3c36600461451c565b611245565b6103a361141b565b6104ce610a5736600461384b565b611427565b6101d0610a6a3660046145b7565b611523565b6103c3610a7d36600461384b565b6119dd565b6103c3610a9036600461463c565b6119ee565b610aa8610aa336600461485c565b6119ff565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101da565b6000610ae882611b8a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b0f85611b8a565b610b37907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16856148b5565b610b4191906148cc565b90505b9392505050565b6060610b576002611c24565b905090565b610b64611c31565b6000610b708280614907565b9050905060005b81811015610cba576000610b8b8480614907565b83818110610b9b57610b9b61496f565b905060400201803603810190610bb191906149ca565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a92610ca99290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610b77565b506000610cca6020840184614907565b9050905060005b81811015610e0b576000610ce86020860186614907565b83818110610cf857610cf861496f565b905060400201803603810190610d0e9190614a07565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600490975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e92610dfa9290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610cd1565b50505050565b610e19611c76565b610e2281611cf7565b50565b60608160008167ffffffffffffffff811115610e4357610e43613972565b604051908082528060200260200182016040528015610e8857816020015b6040805180820190915260008082526020820152815260200190600190039081610e615790505b50905060005b82811015610ee557610ec0868683818110610eab57610eab61496f565b9050602002016020810190610a57919061384b565b828281518110610ed257610ed261496f565b6020908102919091010152600101610e8e565b509150505b92915050565b6000610eea82611b8a565b610f03611c76565b610f0d8282611df5565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61101b611c76565b610f0d8282612207565b61102d611c76565b610e228161234e565b61103e611c76565b610e22816124da565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036110a7578592506110d5565b6110d287877f0000000000000000000000000000000000000000000000000000000000000000610add565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611174576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610f8e565b67ffffffffffffffff8816600090815260086020526040812060010154640100000000900463ffffffff16906111ab8787846125c4565b9050806020015193508484611232836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b67ffffffffffffffff85166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b905b8481101561141257600084848381811061129c5761129c61496f565b6112b2926020604090920201908101915061384b565b905060008787848181106112c8576112c861496f565b90506020028101906112da9190614a2a565b6112e8906040810190614a68565b91505060208111156113985767ffffffffffffffff8916600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115611398576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610f8e565b611408848989868181106113ae576113ae61496f565b90506020028101906113c09190614a2a565b6113ce906020810190614a68565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061276d92505050565b5050600101611280565b50505050505050565b6060610b57600a611c24565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600660209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff16908201529061151a57505073ffffffffffffffffffffffffffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b44816127bf565b67ffffffffffffffff8083166000908152600860209081526040808320815161022081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a0860152710100000000000000000000000000000000008404871660c08601527501000000000000000000000000000000000000000000808504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b010000000000000000000000000000000000000000000000000000009093048616610140850152600190940154808616610160850152640100000000810486166101808501526801000000000000000081049098166101a084015270010000000000000000000000000000000088049094166101c083015274010000000000000000000000000000000000000000870490931615156101e08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b16610200840152909190611759576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b60006117686040850185614907565b91506117c490508261177d6020870187614a68565b90508361178a8880614a68565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a0292505050565b60006007816117d9608088016060890161384b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff169150806118286118226080890160608a0161384b565b896119ff565b909250905060008080861561186e57611862888c61184c60808e0160608f0161384b565b888e806040019061185d9190614907565b612aac565b9194509250905061188e565b6101c088015161188b9063ffffffff16662386f26fc100006148b5565b92505b61010088015160009061ffff16156118d2576118cf896dffffffffffffffffffffffffffff607088901c166118c660208f018f614a68565b90508b86612d8a565b90505b6101a089015160009067ffffffffffffffff166118fb6118f560808f018f614a68565b8d612e3a565b600001518563ffffffff168c60a0015161ffff168f806020019061191f9190614a68565b61192a9291506148b5565b8d6080015163ffffffff1661193f9190614acd565b6119499190614acd565b6119539190614acd565b61196d906dffffffffffffffffffffffffffff89166148b5565b61197791906148b5565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff871682826119ae67ffffffffffffffff8c16896148b5565b6119b89190614acd565b6119c29190614acd565b6119cc91906148cc565b9d9c50505050505050505050505050565b6119e5611c76565b610e2281612efb565b6119f6611c76565b610e2281612ff0565b67ffffffffffffffff811660009081526004602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203611ab7576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b6000816020015163ffffffff1642611acf9190614ae0565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115611b70576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610f8e565b611b7986611b8a565b9151919350909150505b9250929050565b600080611b9683611427565b9050806020015163ffffffff1660001480611bce575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15611c1d576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610f8e565b5192915050565b60606000610b44836134de565b611c3c60023361353a565b611c74576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610f8e565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314611c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610f8e565b60005b8151811015610f0d576000828281518110611d1757611d1761496f565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526006875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a2505050806001019050611cfa565b60005b825181101561211e576000838281518110611e1557611e1561496f565b6020026020010151905060008160000151905060005b82602001515181101561211057600083602001518281518110611e5057611e5061496f565b6020026020010151602001519050600084602001518381518110611e7657611e7661496f565b6020026020010151600001519050602063ffffffff16826080015163ffffffff161015611ef95760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610f8e565b67ffffffffffffffff8416600081815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906120fe908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101611e2b565b505050806001019050611df8565b5060005b815181101561220257600082828151811061213f5761213f61496f565b602002602001015160000151905060008383815181106121615761216161496f565b60209081029190910181015181015167ffffffffffffffff8416600081815260098452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612122565b505050565b60005b82518110156122aa576122408382815181106122285761222861496f565b6020026020010151600a61356990919063ffffffff16565b156122a2578281815181106122575761225761496f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010161220a565b5060005b8151811015612202576122e48282815181106122cc576122cc61496f565b6020026020010151600a61358b90919063ffffffff16565b15612346578181815181106122fb576122fb61496f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6001016122ae565b602081015160005b81518110156123e95760008282815181106123735761237361496f565b6020026020010151905061239181600261358b90919063ffffffff16565b156123e05760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612356565b50815160005b8151811015610e0b57600082828151811061240c5761240c61496f565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361247c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612487600282613569565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016123ef565b60005b8151811015610f0d5760008282815181106124fa576124fa61496f565b6020026020010151600001519050600083838151811061251c5761251c61496f565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526007845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a250506001016124dd565b6040805180820190915260008082526020820152600083900361260557506040805180820190915267ffffffffffffffff8216815260006020820152610b44565b60006126118486614af3565b905060006126228560048189614b39565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f000000000000000000000000000000000000000000000000000000000016126bf57808060200190518101906126b69190614b63565b92505050610b44565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161273b576040518060400160405280828060200190518101906127279190614b8f565b815260006020909101529250610b44915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610f0d57612202816135ad565b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284d9190614bc2565b505050915050600081121561288e576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000819050600085602001518473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129099190614c12565b6129139190614c2f565b905060248160ff1611156129485761292c602482614c48565b61293790600a614d81565b61294190836148cc565b915061296b565b612953816024614c48565b61295e90600a614d81565b61296890836148b5565b91505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8211156129c1576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff42166020820152949350505050565b836040015163ffffffff16831115612a5b5760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610f8e565b836020015161ffff16821115612a9d576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e0b8461020001518261276d565b6000808083815b81811015612d7c576000878783818110612acf57612acf61496f565b905060400201803603810190612ae59190614d90565b67ffffffffffffffff8c166000908152600960209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090612c0b576101208d0151612bd29061ffff16662386f26fc100006148b5565b612bdc9088614acd565b96508c610140015186612bef9190614dc9565b95508c610160015185612c029190614dc9565b94505050612d74565b604081015160009061ffff1615612cc45760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614612c67578351612c6090611b8a565b9050612c6a565b508a5b620186a0836040015161ffff16612cac8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661366090919063ffffffff16565b612cb691906148b5565b612cc091906148cc565b9150505b6060820151612cd39088614dc9565b9650816080015186612ce59190614dc9565b8251909650600090612d049063ffffffff16662386f26fc100006148b5565b905080821015612d2357612d18818a614acd565b985050505050612d74565b6000836020015163ffffffff16662386f26fc10000612d4291906148b5565b905080831115612d6257612d56818b614acd565b99505050505050612d74565b612d6c838b614acd565b995050505050505b600101612ab3565b505096509650969350505050565b60008063ffffffff8316612da0610140866148b5565b612dac876101c0614acd565b612db69190614acd565b612dc09190614acd565b905060008760c0015163ffffffff168860e0015161ffff1683612de391906148b5565b612ded9190614acd565b61010089015190915061ffff16612e146dffffffffffffffffffffffffffff8916836148b5565b612e1e91906148b5565b612e2e90655af3107a40006148b5565b98975050505050505050565b60408051808201909152600080825260208201526000612e66858585610180015163ffffffff166125c4565b9050826060015163ffffffff1681600001511115612eb0576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101e001518015612ec457508060200151155b15610b41576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610f8e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b8151811015610f0d5760008282815181106130105761301061496f565b60200260200101519050600083838151811061302e5761302e61496f565b60200260200101516000015190506000826020015190508167ffffffffffffffff1660001480613067575061018081015163ffffffff16155b806130b957506102008101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130d55750602063ffffffff1681610160015163ffffffff16105b806130f45750806060015163ffffffff1681610180015163ffffffff16115b15613137576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610f8e565b67ffffffffffffffff82166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131df578167ffffffffffffffff167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516131d29190613d1c565b60405180910390a2613222565b8167ffffffffffffffff167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad93826040516132199190613d1c565b60405180910390a25b80600860008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612ff3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561352e57602002820191906000526020600020905b81548152602001906001019080831161351a575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b44565b6000610b448373ffffffffffffffffffffffffffffffffffffffff841661369d565b6000610b448373ffffffffffffffffffffffffffffffffffffffff84166136ec565b600081516020146135ec57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e91906138ca565b6000828060200190518101906136029190614b8f565b905073ffffffffffffffffffffffffffffffffffffffff811180613627575061040081105b15610eea57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e91906138ca565b6000670de0b6b3a7640000613693837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166148b5565b610b4491906148cc565b60008181526001830160205260408120546136e457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610eea565b506000610eea565b600081815260018301602052604081205480156137d5576000613710600183614ae0565b855490915060009061372490600190614ae0565b90508181146137895760008660000182815481106137445761374461496f565b90600052602060002001549050808760000184815481106137675761376761496f565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061379a5761379a614de6565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610eea565b6000915050610eea565b5092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461380a57600080fd5b919050565b60008060006060848603121561382457600080fd5b61382d846137e6565b925060208401359150613842604085016137e6565b90509250925092565b60006020828403121561385d57600080fd5b610b44826137e6565b6000815180845260005b8181101561388c57602081850181015186830182015201613870565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b446020830184613866565b6020808252825182820181905260009190848201906040850190845b8181101561392b57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016138f9565b50909695505050505050565b60006020828403121561394957600080fd5b813567ffffffffffffffff81111561396057600080fd5b820160408185031215610b4457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156139c4576139c4613972565b60405290565b60405160c0810167ffffffffffffffff811182821017156139c4576139c4613972565b604051610220810167ffffffffffffffff811182821017156139c4576139c4613972565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613a5857613a58613972565b604052919050565b600067ffffffffffffffff821115613a7a57613a7a613972565b5060051b60200190565b60ff81168114610e2257600080fd5b60006020808385031215613aa657600080fd5b823567ffffffffffffffff811115613abd57600080fd5b8301601f81018513613ace57600080fd5b8035613ae1613adc82613a60565b613a11565b81815260609182028301840191848201919088841115613b0057600080fd5b938501935b83851015613ba05784890381811215613b1e5760008081fd5b613b266139a1565b613b2f876137e6565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084011215613b635760008081fd5b613b6b6139a1565b9250613b788989016137e6565b8352870135613b8681613a84565b828901528088019190915283529384019391850191613b05565b50979650505050505050565b60008083601f840112613bbe57600080fd5b50813567ffffffffffffffff811115613bd657600080fd5b6020830191508360208260051b8501011115611b8357600080fd5b60008060208385031215613c0457600080fd5b823567ffffffffffffffff811115613c1b57600080fd5b613c2785828601613bac565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b82811015613ca157613c9184835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101613c50565b5091979650505050505050565b803567ffffffffffffffff8116811461380a57600080fd5b600060208284031215613cd857600080fd5b610b4482613cae565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff169082015260408101610eea565b81511515815261022081016020830151613d3c602084018261ffff169052565b506040830151613d54604084018263ffffffff169052565b506060830151613d6c606084018263ffffffff169052565b506080830151613d84608084018263ffffffff169052565b5060a0830151613d9a60a084018261ffff169052565b5060c0830151613db260c084018263ffffffff169052565b5060e0830151613dc860e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a08085015167ffffffffffffffff16908401526101c080850151909116908301526101e080840151151590830152610200808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461380a57600080fd5b803561ffff8116811461380a57600080fd5b8015158114610e2257600080fd5b803561380a81613ea8565b600082601f830112613ed257600080fd5b81356020613ee2613adc83613a60565b82815260069290921b84018101918181019086841115613f0157600080fd5b8286015b84811015613f4e5760408189031215613f1e5760008081fd5b613f266139a1565b613f2f82613cae565b8152613f3c8583016137e6565b81860152835291830191604001613f05565b509695505050505050565b60008060408385031215613f6c57600080fd5b67ffffffffffffffff83351115613f8257600080fd5b83601f843585010112613f9457600080fd5b613fa4613adc8435850135613a60565b8335840180358083526020808401939260059290921b90910101861015613fca57600080fd5b602085358601015b85358601803560051b016020018110156141d75767ffffffffffffffff81351115613ffc57600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a0301121561403557600080fd5b61403d6139a1565b61404960208301613cae565b815267ffffffffffffffff6040830135111561406457600080fd5b88603f60408401358401011261407957600080fd5b61408f613adc6020604085013585010135613a60565b6020604084810135850182810135808552928401939260e00201018b10156140b657600080fd5b6040808501358501015b6040858101358601602081013560e00201018110156141b85760e0818d0312156140e957600080fd5b6140f16139a1565b6140fa826137e6565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f0301121561412e57600080fd5b6141366139ca565b61414260208401613e82565b815261415060408401613e82565b602082015261416160608401613e96565b604082015261417260808401613e82565b606082015261418360a08401613e82565b608082015261419560c0840135613ea8565b60c083013560a0820152602082810191909152908452929092019160e0016140c0565b5080602084015250508085525050602083019250602081019050613fd2565b5092505067ffffffffffffffff602084013511156141f457600080fd5b6142048460208501358501613ec1565b90509250929050565b600082601f83011261421e57600080fd5b8135602061422e613adc83613a60565b8083825260208201915060208460051b87010193508684111561425057600080fd5b602086015b84811015613f4e57614266816137e6565b8352918301918301614255565b6000806040838503121561428657600080fd5b823567ffffffffffffffff8082111561429e57600080fd5b6142aa8683870161420d565b935060208501359150808211156142c057600080fd5b506142cd8582860161420d565b9150509250929050565b600080604083850312156142ea57600080fd5b6142f383613cae565b9150614204602084016137e6565b60006020828403121561431357600080fd5b813567ffffffffffffffff8082111561432b57600080fd5b908301906040828603121561433f57600080fd5b6143476139a1565b82358281111561435657600080fd5b6143628782860161420d565b82525060208301358281111561437757600080fd5b6143838782860161420d565b60208301525095945050505050565b600060208083850312156143a557600080fd5b823567ffffffffffffffff8111156143bc57600080fd5b8301601f810185136143cd57600080fd5b80356143db613adc82613a60565b81815260069190911b820183019083810190878311156143fa57600080fd5b928401925b8284101561444c57604084890312156144185760008081fd5b6144206139a1565b614429856137e6565b8152614436868601613cae565b81870152825260409390930192908401906143ff565b979650505050505050565b60008060008060006080868803121561446f57600080fd5b61447886613cae565b9450614486602087016137e6565b935060408601359250606086013567ffffffffffffffff808211156144aa57600080fd5b818801915088601f8301126144be57600080fd5b8135818111156144cd57600080fd5b8960208285010111156144df57600080fd5b9699959850939650602001949392505050565b83815282151560208201526060604082015260006145136060830184613866565b95945050505050565b60008060008060006060868803121561453457600080fd5b61453d86613cae565b9450602086013567ffffffffffffffff8082111561455a57600080fd5b61456689838a01613bac565b9096509450604088013591508082111561457f57600080fd5b818801915088601f83011261459357600080fd5b8135818111156145a257600080fd5b8960208260061b85010111156144df57600080fd5b600080604083850312156145ca57600080fd5b6145d383613cae565b9150602083013567ffffffffffffffff8111156145ef57600080fd5b830160a0818603121561460157600080fd5b809150509250929050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461380a57600080fd5b6000602080838503121561464f57600080fd5b823567ffffffffffffffff81111561466657600080fd5b8301601f8101851361467757600080fd5b8035614685613adc82613a60565b81815261024091820283018401918482019190888411156146a557600080fd5b938501935b83851015613ba057848903818112156146c35760008081fd5b6146cb6139a1565b6146d487613cae565b8152610220807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147095760008081fd5b6147116139ed565b925061471e898901613eb6565b8352604061472d818a01613e96565b8a850152606061473e818b01613e82565b8286015260809150614751828b01613e82565b9085015260a06147628a8201613e82565b8286015260c09150614775828b01613e96565b9085015260e06147868a8201613e82565b82860152610100915061479a828b01613e96565b908501526101206147ac8a8201613e96565b8286015261014091506147c0828b01613e96565b908501526101606147d28a8201613e82565b8286015261018091506147e6828b01613e82565b908501526101a06147f88a8201613e82565b828601526101c0915061480c828b01613cae565b908501526101e061481e8a8201613e82565b828601526102009150614832828b01613eb6565b9085015261484189830161460c565b908401525080880191909152835293840193918501916146aa565b6000806040838503121561486f57600080fd5b614878836137e6565b915061420460208401613cae565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610eea57610eea614886565b600082614902577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261493c57600080fd5b83018035915067ffffffffffffffff82111561495757600080fd5b6020019150600681901b3603821315611b8357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461380a57600080fd5b6000604082840312156149dc57600080fd5b6149e46139a1565b6149ed836137e6565b81526149fb6020840161499e565b60208201529392505050565b600060408284031215614a1957600080fd5b614a216139a1565b6149ed83613cae565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112614a5e57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614a9d57600080fd5b83018035915067ffffffffffffffff821115614ab857600080fd5b602001915036819003821315611b8357600080fd5b80820180821115610eea57610eea614886565b81810381811115610eea57610eea614886565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015613e7a5760049490940360031b84901b1690921692915050565b60008085851115614b4957600080fd5b83861115614b5657600080fd5b5050820193919092039150565b600060408284031215614b7557600080fd5b614b7d6139a1565b8251815260208301516149fb81613ea8565b600060208284031215614ba157600080fd5b5051919050565b805169ffffffffffffffffffff8116811461380a57600080fd5b600080600080600060a08688031215614bda57600080fd5b614be386614ba8565b9450602086015193506040860151925060608601519150614c0660808701614ba8565b90509295509295909350565b600060208284031215614c2457600080fd5b8151610b4481613a84565b60ff8181168382160190811115610eea57610eea614886565b60ff8281168282160390811115610eea57610eea614886565b600181815b80851115614cba57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614ca057614ca0614886565b80851615614cad57918102915b93841c9390800290614c66565b509250929050565b600082614cd157506001610eea565b81614cde57506000610eea565b8160018114614cf45760028114614cfe57614d1a565b6001915050610eea565b60ff841115614d0f57614d0f614886565b50506001821b610eea565b5060208310610133831016604e8410600b8410161715614d3d575081810a610eea565b614d478383614c61565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614d7957614d79614886565b029392505050565b6000610b4460ff841683614cc2565b600060408284031215614da257600080fd5b614daa6139a1565b614db3836137e6565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156137df576137df614886565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b5060405162006a4238038062006a4283398101604081905262000034916200188e565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a9f565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b6b565b5050505050505062001b4c565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db620019ad565b60209081029190910101519050620002f560028262000ea4565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb576000828281518110620003695762000369620019ad565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000ec4565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a25762000440838281518110620004275762000427620019ad565b6020026020010151600a62000ec460201b90919060201c565b1562000499578281815181106200045b576200045b620019ad565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c9620019ad565b6020026020010151600a62000edb60201b90919060201c565b156200053b57818181518110620004fd57620004fd620019ad565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d620019ad565b6020908102919091018101518051818301516001600160a01b0380831660008181526006875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e620019ad565b6020026020010151905060008383815181106200065f576200065f620019ad565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061018081015163ffffffff16155b80620006ba57506102008101516001600160e01b031916630a04b54b60e21b14155b80620006d75750602063ffffffff1681610160015163ffffffff16105b80620006f75750806060015163ffffffff1681610180015163ffffffff16115b15620007225760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260086020526040812060010154600160a81b900460e01b6001600160e01b0319169003620007a257816001600160401b03167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d1357782604051620007949190620019c3565b60405180910390a2620007e6565b816001600160401b03167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad9382604051620007dd9190620019c3565b60405180910390a25b8060086000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a8154816001600160401b0302191690836001600160401b031602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000ac35762000ac3620019ad565b6020026020010151600001519050600083838151811062000ae85762000ae8620019ad565b6020908102919091018101518101516001600160a01b03841660008181526007845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000aa2565b60005b825181101562000dde57600083828151811062000b8f5762000b8f620019ad565b6020026020010151905060008160000151905060005b82602001515181101562000dcf5760008360200151828151811062000bce5762000bce620019ad565b602002602001015160200151905060008460200151838151811062000bf75762000bf7620019ad565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c565760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b03841660008181526009602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000dbc908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000ba5565b50505080600101905062000b6e565b5060005b81518110156200054457600082828151811062000e035762000e03620019ad565b6020026020010151600001519050600083838151811062000e285762000e28620019ad565b6020908102919091018101518101516001600160401b03841660008181526009845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000de2565b600062000ebb836001600160a01b03841662000ef2565b90505b92915050565b600062000ebb836001600160a01b03841662000ff6565b600062000ebb836001600160a01b03841662001048565b6000818152600183016020526040812054801562000feb57600062000f1960018362001b14565b855490915060009062000f2f9060019062001b14565b905081811462000f9b57600086600001828154811062000f535762000f53620019ad565b906000526020600020015490508087600001848154811062000f795762000f79620019ad565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000faf5762000faf62001b36565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000ebe565b600091505062000ebe565b60008181526001830160205260408120546200103f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000ebe565b50600062000ebe565b6000818152600183016020526040812054801562000feb5760006200106f60018362001b14565b8554909150600090620010859060019062001b14565b905080821462000f9b57600086600001828154811062000f535762000f53620019ad565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620010e457620010e4620010a9565b60405290565b60405160c081016001600160401b0381118282101715620010e457620010e4620010a9565b60405161022081016001600160401b0381118282101715620010e457620010e4620010a9565b604051601f8201601f191681016001600160401b0381118282101715620011605762001160620010a9565b604052919050565b80516001600160a01b03811681146200118057600080fd5b919050565b805163ffffffff811681146200118057600080fd5b600060608284031215620011ad57600080fd5b604051606081016001600160401b0381118282101715620011d257620011d2620010a9565b604052825190915081906001600160601b0381168114620011f257600080fd5b8152620012026020840162001168565b6020820152620012156040840162001185565b60408201525092915050565b60006001600160401b038211156200123d576200123d620010a9565b5060051b60200190565b600082601f8301126200125957600080fd5b81516020620012726200126c8362001221565b62001135565b8083825260208201915060208460051b8701019350868411156200129557600080fd5b602086015b84811015620012bc57620012ae8162001168565b83529183019183016200129a565b509695505050505050565b600082601f830112620012d957600080fd5b81516020620012ec6200126c8362001221565b828152606092830285018201928282019190878511156200130c57600080fd5b8387015b858110156200139f57808903828112156200132b5760008081fd5b62001335620010bf565b620013408362001168565b8152604080601f1984011215620013575760008081fd5b62001361620010bf565b92506200137088850162001168565b835283015160ff81168114620013865760008081fd5b8288015280870191909152845292840192810162001310565b5090979650505050505050565b80516001600160401b03811681146200118057600080fd5b805161ffff811681146200118057600080fd5b805180151581146200118057600080fd5b600082601f830112620013fa57600080fd5b815160206200140d6200126c8362001221565b82815260059290921b840181019181810190868411156200142d57600080fd5b8286015b84811015620012bc5780516001600160401b03808211156200145257600080fd5b908801906040601f19838c0381018213156200146d57600080fd5b62001477620010bf565b62001484898601620013ac565b815282850151848111156200149857600080fd5b8086019550508c603f860112620014ae57600080fd5b888501519350620014c36200126c8562001221565b84815260e09094028501830193898101908e861115620014e257600080fd5b958401955b85871015620015bb57868f0360e08112156200150257600080fd5b6200150c620010bf565b620015178962001168565b815260c086830112156200152a57600080fd5b62001534620010ea565b9150620015438d8a0162001185565b825262001552878a0162001185565b8d8301526200156460608a01620013c4565b878301526200157660808a0162001185565b60608301526200158960a08a0162001185565b60808301526200159c60c08a01620013d7565b60a0830152808d0191909152825260e09690960195908a0190620014e7565b828b01525087525050509284019250830162001431565b600082601f830112620015e457600080fd5b81516020620015f76200126c8362001221565b82815260069290921b840181019181810190868411156200161757600080fd5b8286015b84811015620012bc5760408189031215620016365760008081fd5b62001640620010bf565b6200164b8262001168565b81526200165a858301620013ac565b818601528352918301916040016200161b565b80516001600160e01b0319811681146200118057600080fd5b600082601f8301126200169857600080fd5b81516020620016ab6200126c8362001221565b8281526102409283028501820192828201919087851115620016cc57600080fd5b8387015b858110156200139f5780890382811215620016eb5760008081fd5b620016f5620010bf565b6200170083620013ac565b815261022080601f1984011215620017185760008081fd5b620017226200110f565b925062001731888501620013d7565b8352604062001742818601620013c4565b8985015260606200175581870162001185565b82860152608091506200176a82870162001185565b9085015260a06200177d86820162001185565b8286015260c0915062001792828701620013c4565b9085015260e0620017a586820162001185565b828601526101009150620017bb828701620013c4565b90850152610120620017cf868201620013c4565b828601526101409150620017e5828701620013c4565b90850152610160620017f986820162001185565b8286015261018091506200180f82870162001185565b908501526101a06200182386820162001185565b828601526101c0915062001839828701620013ac565b908501526101e06200184d86820162001185565b82860152610200915062001863828701620013d7565b90850152620018748583016200166d565b9084015250808701919091528452928401928101620016d0565b6000806000806000806000610120888a031215620018ab57600080fd5b620018b789896200119a565b60608901519097506001600160401b0380821115620018d557600080fd5b620018e38b838c0162001247565b975060808a0151915080821115620018fa57600080fd5b620019088b838c0162001247565b965060a08a01519150808211156200191f57600080fd5b6200192d8b838c01620012c7565b955060c08a01519150808211156200194457600080fd5b620019528b838c01620013e8565b945060e08a01519150808211156200196957600080fd5b620019778b838c01620015d2565b93506101008a01519150808211156200198f57600080fd5b506200199e8a828b0162001686565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b81511515815261022081016020830151620019e4602084018261ffff169052565b506040830151620019fd604084018263ffffffff169052565b50606083015162001a16606084018263ffffffff169052565b50608083015162001a2f608084018263ffffffff169052565b5060a083015162001a4660a084018261ffff169052565b5060c083015162001a5f60c084018263ffffffff169052565b5060e083015162001a7660e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a0808501516001600160401b0316908401526101c080850151909116908301526101e080840151151590830152610200928301516001600160e01b031916929091019190915290565b8181038181111562000ebe57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051614e9c62001ba6600039600081816102d901528181611ad30152611b3c01526000818161029d0152818161104e01526110ae015260008181610269015281816110d701526111470152614e9c6000f3fe608060405234801561001057600080fd5b50600436106101b85760003560e01c80637afac322116100f9578063cc88924c11610097578063d8694ccd11610071578063d8694ccd14610a5c578063f2fde38b14610a6f578063f700042a14610a82578063ffdb4b3714610a9557600080fd5b8063cc88924c14610a2e578063cdc73d5114610a41578063d02641a014610a4957600080fd5b806391a2749a116100d357806391a2749a14610939578063a69c64c01461094c578063bf78e03f1461095f578063c4276bfc14610a0c57600080fd5b80637afac3221461078e57806382b49eb0146107a15780638da5cb5b1461091157600080fd5b8063407e108611610166578063514e8cff11610140578063514e8cff146104385780636def4ce7146104db578063770e2dc41461077357806379ba50971461078657600080fd5b8063407e1086146103c557806345ac924d146103d85780634ab35b0b146103f857600080fd5b8063181f5a7711610197578063181f5a77146103525780632451a6271461039b5780633937306f146103b057600080fd5b806241e5be146101bd578063061877e3146101e357806306285c691461023c575b600080fd5b6101d06101cb366004613889565b610add565b6040519081526020015b60405180910390f35b6102236101f13660046138c5565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101da565b610306604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101da565b61038e6040518060400160405280601781526020017f5072696365526567697374727920312e362e302d64657600000000000000000081525081565b6040516101da9190613944565b6103a3610b4b565b6040516101da9190613957565b6103c36103be3660046139b1565b610b5c565b005b6103c36103d3366004613b0d565b610e11565b6103eb6103e6366004613c6b565b610e25565b6040516101da9190613cad565b61040b6104063660046138c5565b610ef0565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6104ce610446366004613d40565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600460209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101da9190613d5b565b6107666104e9366004613d40565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081018290526102008101919091525067ffffffffffffffff908116600090815260086020908152604091829020825161022081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a0850152710100000000000000000000000000000000008304871660c08501527501000000000000000000000000000000000000000000808404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b010000000000000000000000000000000000000000000000000000009092048616610140840152600190930154808616610160840152640100000000810486166101808401526801000000000000000081049096166101a083015270010000000000000000000000000000000086049094166101c082015274010000000000000000000000000000000000000000850490911615156101e08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b1661020082015290565b6040516101da9190613d96565b6103c3610781366004613fd3565b610efb565b6103c3610f11565b6103c361079c3660046142ed565b611013565b6108b16107af366004614351565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff91909116600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101da9190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6103c361094736600461437b565b611025565b6103c361095a36600461440c565b611036565b6109d861096d3660046138c5565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526006825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101da565b610a1f610a1a3660046144d1565b611047565b6040516101da9392919061456c565b6103c3610a3c366004614596565b611245565b6103a361141b565b6104ce610a573660046138c5565b611427565b6101d0610a6a366004614631565b611523565b6103c3610a7d3660046138c5565b6119dd565b6103c3610a903660046146b6565b6119ee565b610aa8610aa33660046148d6565b6119ff565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101da565b6000610ae882611b8a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b0f85611b8a565b610b37907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168561492f565b610b419190614946565b90505b9392505050565b6060610b576002611c24565b905090565b610b64611c31565b6000610b708280614981565b9050905060005b81811015610cba576000610b8b8480614981565b83818110610b9b57610b9b6149e9565b905060400201803603810190610bb19190614a44565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a92610ca99290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610b77565b506000610cca6020840184614981565b9050905060005b81811015610e0b576000610ce86020860186614981565b83818110610cf857610cf86149e9565b905060400201803603810190610d0e9190614a81565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600490975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e92610dfa9290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610cd1565b50505050565b610e19611c76565b610e2281611cf7565b50565b60608160008167ffffffffffffffff811115610e4357610e436139ec565b604051908082528060200260200182016040528015610e8857816020015b6040805180820190915260008082526020820152815260200190600190039081610e615790505b50905060005b82811015610ee557610ec0868683818110610eab57610eab6149e9565b9050602002016020810190610a5791906138c5565b828281518110610ed257610ed26149e9565b6020908102919091010152600101610e8e565b509150505b92915050565b6000610eea82611b8a565b610f03611c76565b610f0d8282611df5565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61101b611c76565b610f0d8282612207565b61102d611c76565b610e228161234e565b61103e611c76565b610e22816124da565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036110a7578592506110d5565b6110d287877f0000000000000000000000000000000000000000000000000000000000000000610add565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611174576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610f8e565b67ffffffffffffffff8816600090815260086020526040812060010154640100000000900463ffffffff16906111ab8787846125c4565b9050806020015193508484611232836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b67ffffffffffffffff85166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b905b8481101561141257600084848381811061129c5761129c6149e9565b6112b292602060409092020190810191506138c5565b905060008787848181106112c8576112c86149e9565b90506020028101906112da9190614aa4565b6112e8906040810190614ae2565b91505060208111156113985767ffffffffffffffff8916600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115611398576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610f8e565b611408848989868181106113ae576113ae6149e9565b90506020028101906113c09190614aa4565b6113ce906020810190614ae2565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061276d92505050565b5050600101611280565b50505050505050565b6060610b57600a611c24565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600660209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff16908201529061151a57505073ffffffffffffffffffffffffffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b44816127bf565b67ffffffffffffffff8083166000908152600860209081526040808320815161022081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a0860152710100000000000000000000000000000000008404871660c08601527501000000000000000000000000000000000000000000808504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b010000000000000000000000000000000000000000000000000000009093048616610140850152600190940154808616610160850152640100000000810486166101808501526801000000000000000081049098166101a084015270010000000000000000000000000000000088049094166101c083015274010000000000000000000000000000000000000000870490931615156101e08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b16610200840152909190611759576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b60006117686040850185614981565b91506117c490508261177d6020870187614ae2565b90508361178a8880614ae2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a0292505050565b60006007816117d960808801606089016138c5565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff169150806118286118226080890160608a016138c5565b896119ff565b909250905060008080861561186e57611862888c61184c60808e0160608f016138c5565b888e806040019061185d9190614981565b612aac565b9194509250905061188e565b6101c088015161188b9063ffffffff16662386f26fc1000061492f565b92505b61010088015160009061ffff16156118d2576118cf896dffffffffffffffffffffffffffff607088901c166118c660208f018f614ae2565b90508b86612d8a565b90505b6101a089015160009067ffffffffffffffff166118fb6118f560808f018f614ae2565b8d612e3a565b600001518563ffffffff168c60a0015161ffff168f806020019061191f9190614ae2565b61192a92915061492f565b8d6080015163ffffffff1661193f9190614b47565b6119499190614b47565b6119539190614b47565b61196d906dffffffffffffffffffffffffffff891661492f565b611977919061492f565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff871682826119ae67ffffffffffffffff8c168961492f565b6119b89190614b47565b6119c29190614b47565b6119cc9190614946565b9d9c50505050505050505050505050565b6119e5611c76565b610e2281612efb565b6119f6611c76565b610e2281612ff0565b67ffffffffffffffff811660009081526004602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203611ab7576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b6000816020015163ffffffff1642611acf9190614b5a565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115611b70576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610f8e565b611b7986611b8a565b9151919350909150505b9250929050565b600080611b9683611427565b9050806020015163ffffffff1660001480611bce575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15611c1d576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610f8e565b5192915050565b60606000610b44836134de565b611c3c60023361353a565b611c74576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610f8e565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314611c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610f8e565b60005b8151811015610f0d576000828281518110611d1757611d176149e9565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526006875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a2505050806001019050611cfa565b60005b825181101561211e576000838281518110611e1557611e156149e9565b6020026020010151905060008160000151905060005b82602001515181101561211057600083602001518281518110611e5057611e506149e9565b6020026020010151602001519050600084602001518381518110611e7657611e766149e9565b6020026020010151600001519050602063ffffffff16826080015163ffffffff161015611ef95760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610f8e565b67ffffffffffffffff8416600081815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906120fe908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101611e2b565b505050806001019050611df8565b5060005b815181101561220257600082828151811061213f5761213f6149e9565b60200260200101516000015190506000838381518110612161576121616149e9565b60209081029190910181015181015167ffffffffffffffff8416600081815260098452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612122565b505050565b60005b82518110156122aa57612240838281518110612228576122286149e9565b6020026020010151600a61356990919063ffffffff16565b156122a257828181518110612257576122576149e9565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010161220a565b5060005b8151811015612202576122e48282815181106122cc576122cc6149e9565b6020026020010151600a61358b90919063ffffffff16565b15612346578181815181106122fb576122fb6149e9565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6001016122ae565b602081015160005b81518110156123e9576000828281518110612373576123736149e9565b602002602001015190506123918160026135ad90919063ffffffff16565b156123e05760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612356565b50815160005b8151811015610e0b57600082828151811061240c5761240c6149e9565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361247c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612487600282613569565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016123ef565b60005b8151811015610f0d5760008282815181106124fa576124fa6149e9565b6020026020010151600001519050600083838151811061251c5761251c6149e9565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526007845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a250506001016124dd565b6040805180820190915260008082526020820152600083900361260557506040805180820190915267ffffffffffffffff8216815260006020820152610b44565b60006126118486614b6d565b905060006126228560048189614bb3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f000000000000000000000000000000000000000000000000000000000016126bf57808060200190518101906126b69190614bdd565b92505050610b44565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161273b576040518060400160405280828060200190518101906127279190614c09565b815260006020909101529250610b44915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610f0d57612202816135cf565b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284d9190614c3c565b505050915050600081121561288e576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000819050600085602001518473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129099190614c8c565b6129139190614ca9565b905060248160ff1611156129485761292c602482614cc2565b61293790600a614dfb565b6129419083614946565b915061296b565b612953816024614cc2565b61295e90600a614dfb565b612968908361492f565b91505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8211156129c1576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff42166020820152949350505050565b836040015163ffffffff16831115612a5b5760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610f8e565b836020015161ffff16821115612a9d576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e0b8461020001518261276d565b6000808083815b81811015612d7c576000878783818110612acf57612acf6149e9565b905060400201803603810190612ae59190614e0a565b67ffffffffffffffff8c166000908152600960209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090612c0b576101208d0151612bd29061ffff16662386f26fc1000061492f565b612bdc9088614b47565b96508c610140015186612bef9190614e43565b95508c610160015185612c029190614e43565b94505050612d74565b604081015160009061ffff1615612cc45760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614612c67578351612c6090611b8a565b9050612c6a565b508a5b620186a0836040015161ffff16612cac8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661368290919063ffffffff16565b612cb6919061492f565b612cc09190614946565b9150505b6060820151612cd39088614e43565b9650816080015186612ce59190614e43565b8251909650600090612d049063ffffffff16662386f26fc1000061492f565b905080821015612d2357612d18818a614b47565b985050505050612d74565b6000836020015163ffffffff16662386f26fc10000612d42919061492f565b905080831115612d6257612d56818b614b47565b99505050505050612d74565b612d6c838b614b47565b995050505050505b600101612ab3565b505096509650969350505050565b60008063ffffffff8316612da06101408661492f565b612dac876101c0614b47565b612db69190614b47565b612dc09190614b47565b905060008760c0015163ffffffff168860e0015161ffff1683612de3919061492f565b612ded9190614b47565b61010089015190915061ffff16612e146dffffffffffffffffffffffffffff89168361492f565b612e1e919061492f565b612e2e90655af3107a400061492f565b98975050505050505050565b60408051808201909152600080825260208201526000612e66858585610180015163ffffffff166125c4565b9050826060015163ffffffff1681600001511115612eb0576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101e001518015612ec457508060200151155b15610b41576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610f8e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b8151811015610f0d576000828281518110613010576130106149e9565b60200260200101519050600083838151811061302e5761302e6149e9565b60200260200101516000015190506000826020015190508167ffffffffffffffff1660001480613067575061018081015163ffffffff16155b806130b957506102008101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130d55750602063ffffffff1681610160015163ffffffff16105b806130f45750806060015163ffffffff1681610180015163ffffffff16115b15613137576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610f8e565b67ffffffffffffffff82166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131df578167ffffffffffffffff167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516131d29190613d96565b60405180910390a2613222565b8167ffffffffffffffff167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad93826040516132199190613d96565b60405180910390a25b80600860008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612ff3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561352e57602002820191906000526020600020905b81548152602001906001019080831161351a575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b44565b6000610b448373ffffffffffffffffffffffffffffffffffffffff84166136bf565b6000610b448373ffffffffffffffffffffffffffffffffffffffff841661370e565b6000610b448373ffffffffffffffffffffffffffffffffffffffff8416613808565b6000815160201461360e57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e9190613944565b6000828060200190518101906136249190614c09565b905073ffffffffffffffffffffffffffffffffffffffff811180613649575061040081105b15610eea57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e9190613944565b6000670de0b6b3a76400006136b5837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff861661492f565b610b449190614946565b600081815260018301602052604081205461370657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610eea565b506000610eea565b600081815260018301602052604081205480156137f7576000613732600183614b5a565b855490915060009061374690600190614b5a565b90508082146137ab576000866000018281548110613766576137666149e9565b9060005260206000200154905080876000018481548110613789576137896149e9565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806137bc576137bc614e60565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610eea565b6000915050610eea565b5092915050565b600081815260018301602052604081205480156137f757600061382c600183614b5a565b855490915060009061384090600190614b5a565b90508181146137ab576000866000018281548110613766576137666149e9565b803573ffffffffffffffffffffffffffffffffffffffff8116811461388457600080fd5b919050565b60008060006060848603121561389e57600080fd5b6138a784613860565b9250602084013591506138bc60408501613860565b90509250925092565b6000602082840312156138d757600080fd5b610b4482613860565b6000815180845260005b81811015613906576020818501810151868301820152016138ea565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b4460208301846138e0565b6020808252825182820181905260009190848201906040850190845b818110156139a557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613973565b50909695505050505050565b6000602082840312156139c357600080fd5b813567ffffffffffffffff8111156139da57600080fd5b820160408185031215610b4457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613a3e57613a3e6139ec565b60405290565b60405160c0810167ffffffffffffffff81118282101715613a3e57613a3e6139ec565b604051610220810167ffffffffffffffff81118282101715613a3e57613a3e6139ec565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613ad257613ad26139ec565b604052919050565b600067ffffffffffffffff821115613af457613af46139ec565b5060051b60200190565b60ff81168114610e2257600080fd5b60006020808385031215613b2057600080fd5b823567ffffffffffffffff811115613b3757600080fd5b8301601f81018513613b4857600080fd5b8035613b5b613b5682613ada565b613a8b565b81815260609182028301840191848201919088841115613b7a57600080fd5b938501935b83851015613c1a5784890381811215613b985760008081fd5b613ba0613a1b565b613ba987613860565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084011215613bdd5760008081fd5b613be5613a1b565b9250613bf2898901613860565b8352870135613c0081613afe565b828901528088019190915283529384019391850191613b7f565b50979650505050505050565b60008083601f840112613c3857600080fd5b50813567ffffffffffffffff811115613c5057600080fd5b6020830191508360208260051b8501011115611b8357600080fd5b60008060208385031215613c7e57600080fd5b823567ffffffffffffffff811115613c9557600080fd5b613ca185828601613c26565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b82811015613d1b57613d0b84835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101613cca565b5091979650505050505050565b803567ffffffffffffffff8116811461388457600080fd5b600060208284031215613d5257600080fd5b610b4482613d28565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff169082015260408101610eea565b81511515815261022081016020830151613db6602084018261ffff169052565b506040830151613dce604084018263ffffffff169052565b506060830151613de6606084018263ffffffff169052565b506080830151613dfe608084018263ffffffff169052565b5060a0830151613e1460a084018261ffff169052565b5060c0830151613e2c60c084018263ffffffff169052565b5060e0830151613e4260e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a08085015167ffffffffffffffff16908401526101c080850151909116908301526101e080840151151590830152610200808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461388457600080fd5b803561ffff8116811461388457600080fd5b8015158114610e2257600080fd5b803561388481613f22565b600082601f830112613f4c57600080fd5b81356020613f5c613b5683613ada565b82815260069290921b84018101918181019086841115613f7b57600080fd5b8286015b84811015613fc85760408189031215613f985760008081fd5b613fa0613a1b565b613fa982613d28565b8152613fb6858301613860565b81860152835291830191604001613f7f565b509695505050505050565b60008060408385031215613fe657600080fd5b67ffffffffffffffff83351115613ffc57600080fd5b83601f84358501011261400e57600080fd5b61401e613b568435850135613ada565b8335840180358083526020808401939260059290921b9091010186101561404457600080fd5b602085358601015b85358601803560051b016020018110156142515767ffffffffffffffff8135111561407657600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a030112156140af57600080fd5b6140b7613a1b565b6140c360208301613d28565b815267ffffffffffffffff604083013511156140de57600080fd5b88603f6040840135840101126140f357600080fd5b614109613b566020604085013585010135613ada565b6020604084810135850182810135808552928401939260e00201018b101561413057600080fd5b6040808501358501015b6040858101358601602081013560e00201018110156142325760e0818d03121561416357600080fd5b61416b613a1b565b61417482613860565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f030112156141a857600080fd5b6141b0613a44565b6141bc60208401613efc565b81526141ca60408401613efc565b60208201526141db60608401613f10565b60408201526141ec60808401613efc565b60608201526141fd60a08401613efc565b608082015261420f60c0840135613f22565b60c083013560a0820152602082810191909152908452929092019160e00161413a565b508060208401525050808552505060208301925060208101905061404c565b5092505067ffffffffffffffff6020840135111561426e57600080fd5b61427e8460208501358501613f3b565b90509250929050565b600082601f83011261429857600080fd5b813560206142a8613b5683613ada565b8083825260208201915060208460051b8701019350868411156142ca57600080fd5b602086015b84811015613fc8576142e081613860565b83529183019183016142cf565b6000806040838503121561430057600080fd5b823567ffffffffffffffff8082111561431857600080fd5b61432486838701614287565b9350602085013591508082111561433a57600080fd5b5061434785828601614287565b9150509250929050565b6000806040838503121561436457600080fd5b61436d83613d28565b915061427e60208401613860565b60006020828403121561438d57600080fd5b813567ffffffffffffffff808211156143a557600080fd5b90830190604082860312156143b957600080fd5b6143c1613a1b565b8235828111156143d057600080fd5b6143dc87828601614287565b8252506020830135828111156143f157600080fd5b6143fd87828601614287565b60208301525095945050505050565b6000602080838503121561441f57600080fd5b823567ffffffffffffffff81111561443657600080fd5b8301601f8101851361444757600080fd5b8035614455613b5682613ada565b81815260069190911b8201830190838101908783111561447457600080fd5b928401925b828410156144c657604084890312156144925760008081fd5b61449a613a1b565b6144a385613860565b81526144b0868601613d28565b8187015282526040939093019290840190614479565b979650505050505050565b6000806000806000608086880312156144e957600080fd5b6144f286613d28565b945061450060208701613860565b935060408601359250606086013567ffffffffffffffff8082111561452457600080fd5b818801915088601f83011261453857600080fd5b81358181111561454757600080fd5b89602082850101111561455957600080fd5b9699959850939650602001949392505050565b838152821515602082015260606040820152600061458d60608301846138e0565b95945050505050565b6000806000806000606086880312156145ae57600080fd5b6145b786613d28565b9450602086013567ffffffffffffffff808211156145d457600080fd5b6145e089838a01613c26565b909650945060408801359150808211156145f957600080fd5b818801915088601f83011261460d57600080fd5b81358181111561461c57600080fd5b8960208260061b850101111561455957600080fd5b6000806040838503121561464457600080fd5b61464d83613d28565b9150602083013567ffffffffffffffff81111561466957600080fd5b830160a0818603121561467b57600080fd5b809150509250929050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461388457600080fd5b600060208083850312156146c957600080fd5b823567ffffffffffffffff8111156146e057600080fd5b8301601f810185136146f157600080fd5b80356146ff613b5682613ada565b818152610240918202830184019184820191908884111561471f57600080fd5b938501935b83851015613c1a578489038181121561473d5760008081fd5b614745613a1b565b61474e87613d28565b8152610220807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147835760008081fd5b61478b613a67565b9250614798898901613f30565b835260406147a7818a01613f10565b8a85015260606147b8818b01613efc565b82860152608091506147cb828b01613efc565b9085015260a06147dc8a8201613efc565b8286015260c091506147ef828b01613f10565b9085015260e06148008a8201613efc565b828601526101009150614814828b01613f10565b908501526101206148268a8201613f10565b82860152610140915061483a828b01613f10565b9085015261016061484c8a8201613efc565b828601526101809150614860828b01613efc565b908501526101a06148728a8201613efc565b828601526101c09150614886828b01613d28565b908501526101e06148988a8201613efc565b8286015261020091506148ac828b01613f30565b908501526148bb898301614686565b90840152508088019190915283529384019391850191614724565b600080604083850312156148e957600080fd5b6148f283613860565b915061427e60208401613d28565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610eea57610eea614900565b60008261497c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126149b657600080fd5b83018035915067ffffffffffffffff8211156149d157600080fd5b6020019150600681901b3603821315611b8357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461388457600080fd5b600060408284031215614a5657600080fd5b614a5e613a1b565b614a6783613860565b8152614a7560208401614a18565b60208201529392505050565b600060408284031215614a9357600080fd5b614a9b613a1b565b614a6783613d28565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112614ad857600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614b1757600080fd5b83018035915067ffffffffffffffff821115614b3257600080fd5b602001915036819003821315611b8357600080fd5b80820180821115610eea57610eea614900565b81810381811115610eea57610eea614900565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015613ef45760049490940360031b84901b1690921692915050565b60008085851115614bc357600080fd5b83861115614bd057600080fd5b5050820193919092039150565b600060408284031215614bef57600080fd5b614bf7613a1b565b825181526020830151614a7581613f22565b600060208284031215614c1b57600080fd5b5051919050565b805169ffffffffffffffffffff8116811461388457600080fd5b600080600080600060a08688031215614c5457600080fd5b614c5d86614c22565b9450602086015193506040860151925060608601519150614c8060808701614c22565b90509295509295909350565b600060208284031215614c9e57600080fd5b8151610b4481613afe565b60ff8181168382160190811115610eea57610eea614900565b60ff8281168282160390811115610eea57610eea614900565b600181815b80851115614d3457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614d1a57614d1a614900565b80851615614d2757918102915b93841c9390800290614ce0565b509250929050565b600082614d4b57506001610eea565b81614d5857506000610eea565b8160018114614d6e5760028114614d7857614d94565b6001915050610eea565b60ff841115614d8957614d89614900565b50506001821b610eea565b5060208310610133831016604e8410600b8410161715614db7575081810a610eea565b614dc18383614cdb565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614df357614df3614900565b029392505050565b6000610b4460ff841683614d3c565b600060408284031215614e1c57600080fd5b614e24613a1b565b614e2d83613860565b8152602083013560208201528091505092915050565b63ffffffff81811683821601908082111561380157613801614900565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var PriceRegistryABI = PriceRegistryMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/router/router.go b/core/gethwrappers/ccip/generated/router/router.go index c53d4824b1..9a0d4a4055 100644 --- a/core/gethwrappers/ccip/generated/router/router.go +++ b/core/gethwrappers/ccip/generated/router/router.go @@ -63,7 +63,7 @@ type RouterOnRamp struct { var RouterMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"wrappedNative\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFeeTokenAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMsgValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"InvalidRecipientAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyOffRamp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"UnsupportedDestinationChain\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"calldataHash\",\"type\":\"bytes32\"}],\"name\":\"MessageExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"OnRampSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_RET_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"internalType\":\"structRouter.OnRamp[]\",\"name\":\"onRampUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"internalType\":\"structRouter.OffRamp[]\",\"name\":\"offRampRemoves\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"internalType\":\"structRouter.OffRamp[]\",\"name\":\"offRampAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyRampUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destinationChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ccipSend\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destinationChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOffRamps\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"internalType\":\"structRouter.OffRamp[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWrappedNative\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"isChainSupported\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"recoverTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"routeMessage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"retData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"wrappedNative\",\"type\":\"address\"}],\"name\":\"setWrappedNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162002d2838038062002d288339810160408190526200003491620001af565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e7565b5050600280546001600160a01b0319166001600160a01b039485161790555016608052620001e7565b336001600160a01b03821603620001415760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001aa57600080fd5b919050565b60008060408385031215620001c357600080fd5b620001ce8362000192565b9150620001de6020840162000192565b90509250929050565b608051612b1762000211600039600081816101f9015281816105e10152610af20152612b176000f3fe6080604052600436106101295760003560e01c80638da5cb5b116100a5578063a8d87a3b11610074578063e861e90711610059578063e861e90714610409578063f2fde38b14610434578063fbca3b741461045457600080fd5b8063a8d87a3b1461039c578063da5fcac8146103e957600080fd5b80638da5cb5b146102ed57806396f4e9f914610318578063a40e69c71461032b578063a48a90581461034d57600080fd5b806352cb60ca116100fc578063787350e3116100e1578063787350e31461028057806379ba5097146102a857806383826b2b146102bd57600080fd5b806352cb60ca1461023e5780635f3e849f1461026057600080fd5b8063181f5a771461012e57806320487ded1461018d5780633cf97983146101bb5780635246492f146101ea575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280600c81526020017f526f7574657220312e322e30000000000000000000000000000000000000000081525081565b6040516101849190611f3c565b60405180910390f35b34801561019957600080fd5b506101ad6101a83660046121ad565b610481565b604051908152602001610184565b3480156101c757600080fd5b506101db6101d63660046122aa565b6105d9565b60405161018493929190612322565b3480156101f657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561024a57600080fd5b5061025e61025936600461234d565b610836565b005b34801561026c57600080fd5b5061025e61027b36600461236a565b610885565b34801561028c57600080fd5b50610295608481565b60405161ffff9091168152602001610184565b3480156102b457600080fd5b5061025e6109d3565b3480156102c957600080fd5b506102dd6102d83660046123ab565b610ad0565b6040519015158152602001610184565b3480156102f957600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610219565b6101ad6103263660046121ad565b610aee565b34801561033757600080fd5b50610340611087565b60405161018491906123e2565b34801561035957600080fd5b506102dd610368366004612451565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b3480156103a857600080fd5b506102196103b7366004612451565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b3480156103f557600080fd5b5061025e6104043660046124b8565b61118b565b34801561041557600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff16610219565b34801561044057600080fd5b5061025e61044f36600461234d565b611490565b34801561046057600080fd5b5061047461046f366004612451565b6114a4565b6040516101849190612552565b606081015160009073ffffffffffffffffffffffffffffffffffffffff166104c25760025473ffffffffffffffffffffffffffffffffffffffff1660608301525b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff168061053a576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024015b60405180910390fd5b6040517f20487ded00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216906320487ded9061058e9087908790600401612689565b602060405180830381865afa1580156105ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105cf91906126ac565b9150505b92915050565b6000606060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e91906126c5565b156106a5576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106be6106b86040890160208a01612451565b33610ad0565b6106f4576040517fd2316ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006385572ffb60e01b8860405160240161070f91906127f4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905061079c8186888a60846115c4565b919550935091507f9b877de93ea9895756e337442c657f95a34fc68e7eb988bdfa693d5be83016b688356107d660408b0160208c01612451565b83516020850120604051610823939291339193845267ffffffffffffffff92909216602084015273ffffffffffffffffffffffffffffffffffffffff166040830152606082015260800190565b60405180910390a1509450945094915050565b61083e6116ea565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61088d6116ea565b73ffffffffffffffffffffffffffffffffffffffff82166108f2576040517f26a78f8f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610531565b73ffffffffffffffffffffffffffffffffffffffff83166109ad5760008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610967576040519150601f19603f3d011682016040523d82523d6000602084013e61096c565b606091505b50509050806109a7576040517fe417b80b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6109ce73ffffffffffffffffffffffffffffffffffffffff8416838361176d565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610531565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000610ae7610adf8484611841565b600490611885565b9392505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7f91906126c5565b15610bb6576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610c29576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610531565b606083015160009073ffffffffffffffffffffffffffffffffffffffff16610dbb5760025473ffffffffffffffffffffffffffffffffffffffff90811660608601526040517f20487ded000000000000000000000000000000000000000000000000000000008152908316906320487ded90610cab9088908890600401612689565b602060405180830381865afa158015610cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cec91906126ac565b905080341015610d28576040517f07da6ee600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b349050836060015173ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610d7757600080fd5b505af1158015610d8b573d6000803e3d6000fd5b505050506060850151610db6915073ffffffffffffffffffffffffffffffffffffffff16838361176d565b610eb2565b3415610df3576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f20487ded00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906320487ded90610e479088908890600401612689565b602060405180830381865afa158015610e64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8891906126ac565b6060850151909150610eb29073ffffffffffffffffffffffffffffffffffffffff1633848461189d565b60005b846040015151811015610fe257600085604001518281518110610eda57610eda612900565b6020908102919091010151516040517f48a98aa400000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8916600482015273ffffffffffffffffffffffffffffffffffffffff8083166024830152919250610fd9913391908716906348a98aa490604401602060405180830381865afa158015610f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f90919061292f565b88604001518581518110610fa657610fa6612900565b6020026020010151602001518473ffffffffffffffffffffffffffffffffffffffff1661189d909392919063ffffffff16565b50600101610eb5565b506040517fdf0aa9e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169063df0aa9e99061103b90889088908690339060040161294c565b6020604051808303816000875af115801561105a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107e91906126ac565b95945050505050565b6060600061109560046118fb565b90506000815167ffffffffffffffff8111156110b3576110b3611f6c565b6040519080825280602002602001820160405280156110f857816020015b60408051808201909152600080825260208201528152602001906001900390816110d15790505b50905060005b825181101561118457600083828151811061111b5761111b612900565b60200260200101519050604051806040016040528060a083901c67ffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681525083838151811061117057611170612900565b6020908102919091010152506001016110fe565b5092915050565b6111936116ea565b60005b8581101561126f5760008787838181106111b2576111b2612900565b9050604002018036038101906111c8919061299c565b60208181018051835167ffffffffffffffff90811660009081526003855260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055855193519051921682529394509216917f1f7d0ec248b80e5c0dde0ee531c4fc8fdb6ce9a2b3d90f560c74acd6a7202f23910160405180910390a250600101611196565b5060005b838110156113a757600085858381811061128f5761128f612900565b6112a59260206040909202019081019150612451565b905060008686848181106112bb576112bb612900565b90506040020160200160208101906112d3919061234d565b90506112ea6112e28383611841565b600490611908565b611348576040517f4964779000000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8316600482015273ffffffffffffffffffffffffffffffffffffffff82166024820152604401610531565b60405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa823809efda3ba66c873364eec120fa0923d9fabda73bc97dd5663341e2d9bcb9060200160405180910390a25050600101611273565b5060005b818110156114875760008383838181106113c7576113c7612900565b6113dd9260206040909202019081019150612451565b905060008484848181106113f3576113f3612900565b905060400201602001602081019061140b919061234d565b905061142261141a8383611841565b600490611914565b1561147d5760405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa4bdf64ebdf3316320601a081916a75aa144bcef6c4beeb0e9fb1982cacc6b949060200160405180910390a25b50506001016113ab565b50505050505050565b6114986116ea565b6114a181611920565b50565b60606114de8267ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b6114f8576040805160008082526020820190925290611184565b67ffffffffffffffff8216600081815260036020526040908190205490517ffbca3b74000000000000000000000000000000000000000000000000000000008152600481019290925273ffffffffffffffffffffffffffffffffffffffff169063fbca3b7490602401600060405180830381865afa15801561157e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d391908101906129db565b6000606060008361ffff1667ffffffffffffffff8111156115e7576115e7611f6c565b6040519080825280601f01601f191660200182016040528015611611576020820181803683370190505b509150863b611644577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015611677577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b85900360408104810387106116b0577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156116d35750835b808352806000602085013e50955095509592505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461176b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610531565b565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109ce9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611a15565b6000610ae773ffffffffffffffffffffffffffffffffffffffff83167bffffffffffffffff000000000000000000000000000000000000000060a086901b16612a99565b60008181526001830160205260408120541515610ae7565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109a79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016117bf565b60606000610ae783611b21565b6000610ae78383611b7d565b6000610ae78383611c70565b3373ffffffffffffffffffffffffffffffffffffffff82160361199f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610531565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611a77826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611cbf9092919063ffffffff16565b8051909150156109ce5780806020019051810190611a9591906126c5565b6109ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610531565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b7157602002820191906000526020600020905b815481526020019060010190808311611b5d575b50505050509050919050565b60008181526001830160205260408120548015611c66576000611ba1600183612aac565b8554909150600090611bb590600190612aac565b9050818114611c1a576000866000018281548110611bd557611bd5612900565b9060005260206000200154905080876000018481548110611bf857611bf8612900565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611c2b57611c2b612abf565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105d3565b60009150506105d3565b6000818152600183016020526040812054611cb7575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105d3565b5060006105d3565b6060611cce8484600085611cd6565b949350505050565b606082471015611d68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610531565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611d919190612aee565b60006040518083038185875af1925050503d8060008114611dce576040519150601f19603f3d011682016040523d82523d6000602084013e611dd3565b606091505b5091509150611de487838387611def565b979650505050505050565b60608315611e85578251600003611e7e5773ffffffffffffffffffffffffffffffffffffffff85163b611e7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610531565b5081611cce565b611cce8383815115611e9a5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105319190611f3c565b60005b83811015611ee9578181015183820152602001611ed1565b50506000910152565b60008151808452611f0a816020860160208601611ece565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ae76020830184611ef2565b803567ffffffffffffffff81168114611f6757600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611fbe57611fbe611f6c565b60405290565b60405160a0810167ffffffffffffffff81118282101715611fbe57611fbe611f6c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561202e5761202e611f6c565b604052919050565b600082601f83011261204757600080fd5b813567ffffffffffffffff81111561206157612061611f6c565b61209260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611fe7565b8181528460208386010111156120a757600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff8211156120de576120de611f6c565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146114a157600080fd5b8035611f67816120e8565b600082601f83011261212657600080fd5b8135602061213b612136836120c4565b611fe7565b82815260069290921b8401810191818101908684111561215a57600080fd5b8286015b848110156121a257604081890312156121775760008081fd5b61217f611f9b565b813561218a816120e8565b8152818501358582015283529183019160400161215e565b509695505050505050565b600080604083850312156121c057600080fd5b6121c983611f4f565b9150602083013567ffffffffffffffff808211156121e657600080fd5b9084019060a082870312156121fa57600080fd5b612202611fc4565b82358281111561221157600080fd5b61221d88828601612036565b82525060208301358281111561223257600080fd5b61223e88828601612036565b60208301525060408301358281111561225657600080fd5b61226288828601612115565b6040830152506122746060840161210a565b606082015260808301358281111561228b57600080fd5b61229788828601612036565b6080830152508093505050509250929050565b600080600080608085870312156122c057600080fd5b843567ffffffffffffffff8111156122d757600080fd5b850160a081880312156122e957600080fd5b9350602085013561ffff8116811461230057600080fd5b9250604085013591506060850135612317816120e8565b939692955090935050565b831515815260606020820152600061233d6060830185611ef2565b9050826040830152949350505050565b60006020828403121561235f57600080fd5b8135610ae7816120e8565b60008060006060848603121561237f57600080fd5b833561238a816120e8565b9250602084013561239a816120e8565b929592945050506040919091013590565b600080604083850312156123be57600080fd5b6123c783611f4f565b915060208301356123d7816120e8565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b82811015612444578151805167ffffffffffffffff16855286015173ffffffffffffffffffffffffffffffffffffffff168685015292840192908501906001016123ff565b5091979650505050505050565b60006020828403121561246357600080fd5b610ae782611f4f565b60008083601f84011261247e57600080fd5b50813567ffffffffffffffff81111561249657600080fd5b6020830191508360208260061b85010111156124b157600080fd5b9250929050565b600080600080600080606087890312156124d157600080fd5b863567ffffffffffffffff808211156124e957600080fd5b6124f58a838b0161246c565b9098509650602089013591508082111561250e57600080fd5b61251a8a838b0161246c565b9096509450604089013591508082111561253357600080fd5b5061254089828a0161246c565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b818110156125a057835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161256e565b50909695505050505050565b6000815160a084526125c160a0850182611ef2565b9050602080840151858303828701526125da8382611ef2565b60408681015188830389830152805180845290850195509092506000918401905b8083101561263a578551805173ffffffffffffffffffffffffffffffffffffffff168352850151858301529484019460019290920191908301906125fb565b5060608701519450612664606089018673ffffffffffffffffffffffffffffffffffffffff169052565b60808701519450878103608089015261267d8186611ef2565b98975050505050505050565b67ffffffffffffffff83168152604060208201526000611cce60408301846125ac565b6000602082840312156126be57600080fd5b5051919050565b6000602082840312156126d757600080fd5b81518015158114610ae757600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261271c57600080fd5b830160208101925035905067ffffffffffffffff81111561273c57600080fd5b8036038213156124b157600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156127e95781356127b7816120e8565b73ffffffffffffffffffffffffffffffffffffffff1687528183013583880152604096870196909101906001016127a4565b509495945050505050565b6020815281356020820152600061280d60208401611f4f565b67ffffffffffffffff808216604085015261282b60408601866126e7565b925060a0606086015261284260c08601848361274b565b92505061285260608601866126e7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08087860301608088015261288885838561274b565b9450608088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030183126128c157600080fd5b602092880192830192359150838211156128da57600080fd5b8160061b36038313156128ec57600080fd5b8685030160a0870152611de4848284612794565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561294157600080fd5b8151610ae7816120e8565b67ffffffffffffffff8516815260806020820152600061296f60808301866125ac565b905083604083015273ffffffffffffffffffffffffffffffffffffffff8316606083015295945050505050565b6000604082840312156129ae57600080fd5b6129b6611f9b565b6129bf83611f4f565b815260208301356129cf816120e8565b60208201529392505050565b600060208083850312156129ee57600080fd5b825167ffffffffffffffff811115612a0557600080fd5b8301601f81018513612a1657600080fd5b8051612a24612136826120c4565b81815260059190911b82018301908381019087831115612a4357600080fd5b928401925b82841015611de4578351612a5b816120e8565b82529284019290840190612a48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156105d3576105d3612a6a565b818103818111156105d3576105d3612a6a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251612b00818460208701611ece565b919091019291505056fea164736f6c6343000818000a", + Bin: "0x60a06040523480156200001157600080fd5b5060405162002d2838038062002d288339810160408190526200003491620001af565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e7565b5050600280546001600160a01b0319166001600160a01b039485161790555016608052620001e7565b336001600160a01b03821603620001415760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001aa57600080fd5b919050565b60008060408385031215620001c357600080fd5b620001ce8362000192565b9150620001de6020840162000192565b90509250929050565b608051612b1762000211600039600081816101f9015281816105e10152610af20152612b176000f3fe6080604052600436106101295760003560e01c80638da5cb5b116100a5578063a8d87a3b11610074578063e861e90711610059578063e861e90714610409578063f2fde38b14610434578063fbca3b741461045457600080fd5b8063a8d87a3b1461039c578063da5fcac8146103e957600080fd5b80638da5cb5b146102ed57806396f4e9f914610318578063a40e69c71461032b578063a48a90581461034d57600080fd5b806352cb60ca116100fc578063787350e3116100e1578063787350e31461028057806379ba5097146102a857806383826b2b146102bd57600080fd5b806352cb60ca1461023e5780635f3e849f1461026057600080fd5b8063181f5a771461012e57806320487ded1461018d5780633cf97983146101bb5780635246492f146101ea575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280600c81526020017f526f7574657220312e322e30000000000000000000000000000000000000000081525081565b6040516101849190611f3c565b60405180910390f35b34801561019957600080fd5b506101ad6101a83660046121ad565b610481565b604051908152602001610184565b3480156101c757600080fd5b506101db6101d63660046122aa565b6105d9565b60405161018493929190612322565b3480156101f657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561024a57600080fd5b5061025e61025936600461234d565b610836565b005b34801561026c57600080fd5b5061025e61027b36600461236a565b610885565b34801561028c57600080fd5b50610295608481565b60405161ffff9091168152602001610184565b3480156102b457600080fd5b5061025e6109d3565b3480156102c957600080fd5b506102dd6102d83660046123ab565b610ad0565b6040519015158152602001610184565b3480156102f957600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610219565b6101ad6103263660046121ad565b610aee565b34801561033757600080fd5b50610340611087565b60405161018491906123e2565b34801561035957600080fd5b506102dd610368366004612451565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b3480156103a857600080fd5b506102196103b7366004612451565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b3480156103f557600080fd5b5061025e6104043660046124b8565b61118b565b34801561041557600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff16610219565b34801561044057600080fd5b5061025e61044f36600461234d565b611490565b34801561046057600080fd5b5061047461046f366004612451565b6114a4565b6040516101849190612552565b606081015160009073ffffffffffffffffffffffffffffffffffffffff166104c25760025473ffffffffffffffffffffffffffffffffffffffff1660608301525b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff168061053a576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024015b60405180910390fd5b6040517f20487ded00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216906320487ded9061058e9087908790600401612689565b602060405180830381865afa1580156105ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105cf91906126ac565b9150505b92915050565b6000606060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e91906126c5565b156106a5576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106be6106b86040890160208a01612451565b33610ad0565b6106f4576040517fd2316ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006385572ffb60e01b8860405160240161070f91906127f4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905061079c8186888a60846115c4565b919550935091507f9b877de93ea9895756e337442c657f95a34fc68e7eb988bdfa693d5be83016b688356107d660408b0160208c01612451565b83516020850120604051610823939291339193845267ffffffffffffffff92909216602084015273ffffffffffffffffffffffffffffffffffffffff166040830152606082015260800190565b60405180910390a1509450945094915050565b61083e6116ea565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61088d6116ea565b73ffffffffffffffffffffffffffffffffffffffff82166108f2576040517f26a78f8f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610531565b73ffffffffffffffffffffffffffffffffffffffff83166109ad5760008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610967576040519150601f19603f3d011682016040523d82523d6000602084013e61096c565b606091505b50509050806109a7576040517fe417b80b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6109ce73ffffffffffffffffffffffffffffffffffffffff8416838361176d565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610531565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000610ae7610adf8484611841565b600490611885565b9392505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7f91906126c5565b15610bb6576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610c29576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610531565b606083015160009073ffffffffffffffffffffffffffffffffffffffff16610dbb5760025473ffffffffffffffffffffffffffffffffffffffff90811660608601526040517f20487ded000000000000000000000000000000000000000000000000000000008152908316906320487ded90610cab9088908890600401612689565b602060405180830381865afa158015610cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cec91906126ac565b905080341015610d28576040517f07da6ee600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b349050836060015173ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610d7757600080fd5b505af1158015610d8b573d6000803e3d6000fd5b505050506060850151610db6915073ffffffffffffffffffffffffffffffffffffffff16838361176d565b610eb2565b3415610df3576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f20487ded00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906320487ded90610e479088908890600401612689565b602060405180830381865afa158015610e64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8891906126ac565b6060850151909150610eb29073ffffffffffffffffffffffffffffffffffffffff1633848461189d565b60005b846040015151811015610fe257600085604001518281518110610eda57610eda612900565b6020908102919091010151516040517f48a98aa400000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8916600482015273ffffffffffffffffffffffffffffffffffffffff8083166024830152919250610fd9913391908716906348a98aa490604401602060405180830381865afa158015610f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f90919061292f565b88604001518581518110610fa657610fa6612900565b6020026020010151602001518473ffffffffffffffffffffffffffffffffffffffff1661189d909392919063ffffffff16565b50600101610eb5565b506040517fdf0aa9e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169063df0aa9e99061103b90889088908690339060040161294c565b6020604051808303816000875af115801561105a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107e91906126ac565b95945050505050565b6060600061109560046118fb565b90506000815167ffffffffffffffff8111156110b3576110b3611f6c565b6040519080825280602002602001820160405280156110f857816020015b60408051808201909152600080825260208201528152602001906001900390816110d15790505b50905060005b825181101561118457600083828151811061111b5761111b612900565b60200260200101519050604051806040016040528060a083901c67ffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681525083838151811061117057611170612900565b6020908102919091010152506001016110fe565b5092915050565b6111936116ea565b60005b8581101561126f5760008787838181106111b2576111b2612900565b9050604002018036038101906111c8919061299c565b60208181018051835167ffffffffffffffff90811660009081526003855260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055855193519051921682529394509216917f1f7d0ec248b80e5c0dde0ee531c4fc8fdb6ce9a2b3d90f560c74acd6a7202f23910160405180910390a250600101611196565b5060005b838110156113a757600085858381811061128f5761128f612900565b6112a59260206040909202019081019150612451565b905060008686848181106112bb576112bb612900565b90506040020160200160208101906112d3919061234d565b90506112ea6112e28383611841565b600490611908565b611348576040517f4964779000000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8316600482015273ffffffffffffffffffffffffffffffffffffffff82166024820152604401610531565b60405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa823809efda3ba66c873364eec120fa0923d9fabda73bc97dd5663341e2d9bcb9060200160405180910390a25050600101611273565b5060005b818110156114875760008383838181106113c7576113c7612900565b6113dd9260206040909202019081019150612451565b905060008484848181106113f3576113f3612900565b905060400201602001602081019061140b919061234d565b905061142261141a8383611841565b600490611914565b1561147d5760405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa4bdf64ebdf3316320601a081916a75aa144bcef6c4beeb0e9fb1982cacc6b949060200160405180910390a25b50506001016113ab565b50505050505050565b6114986116ea565b6114a181611920565b50565b60606114de8267ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b6114f8576040805160008082526020820190925290611184565b67ffffffffffffffff8216600081815260036020526040908190205490517ffbca3b74000000000000000000000000000000000000000000000000000000008152600481019290925273ffffffffffffffffffffffffffffffffffffffff169063fbca3b7490602401600060405180830381865afa15801561157e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d391908101906129db565b6000606060008361ffff1667ffffffffffffffff8111156115e7576115e7611f6c565b6040519080825280601f01601f191660200182016040528015611611576020820181803683370190505b509150863b611644577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015611677577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b85900360408104810387106116b0577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156116d35750835b808352806000602085013e50955095509592505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461176b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610531565b565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109ce9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611a15565b6000610ae773ffffffffffffffffffffffffffffffffffffffff83167bffffffffffffffff000000000000000000000000000000000000000060a086901b16612a99565b60008181526001830160205260408120541515610ae7565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109a79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016117bf565b60606000610ae783611b21565b6000610ae78383611b7d565b6000610ae78383611c70565b3373ffffffffffffffffffffffffffffffffffffffff82160361199f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610531565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611a77826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611cbf9092919063ffffffff16565b8051909150156109ce5780806020019051810190611a9591906126c5565b6109ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610531565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b7157602002820191906000526020600020905b815481526020019060010190808311611b5d575b50505050509050919050565b60008181526001830160205260408120548015611c66576000611ba1600183612aac565b8554909150600090611bb590600190612aac565b9050808214611c1a576000866000018281548110611bd557611bd5612900565b9060005260206000200154905080876000018481548110611bf857611bf8612900565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611c2b57611c2b612abf565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105d3565b60009150506105d3565b6000818152600183016020526040812054611cb7575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105d3565b5060006105d3565b6060611cce8484600085611cd6565b949350505050565b606082471015611d68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610531565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611d919190612aee565b60006040518083038185875af1925050503d8060008114611dce576040519150601f19603f3d011682016040523d82523d6000602084013e611dd3565b606091505b5091509150611de487838387611def565b979650505050505050565b60608315611e85578251600003611e7e5773ffffffffffffffffffffffffffffffffffffffff85163b611e7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610531565b5081611cce565b611cce8383815115611e9a5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105319190611f3c565b60005b83811015611ee9578181015183820152602001611ed1565b50506000910152565b60008151808452611f0a816020860160208601611ece565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ae76020830184611ef2565b803567ffffffffffffffff81168114611f6757600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611fbe57611fbe611f6c565b60405290565b60405160a0810167ffffffffffffffff81118282101715611fbe57611fbe611f6c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561202e5761202e611f6c565b604052919050565b600082601f83011261204757600080fd5b813567ffffffffffffffff81111561206157612061611f6c565b61209260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611fe7565b8181528460208386010111156120a757600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff8211156120de576120de611f6c565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146114a157600080fd5b8035611f67816120e8565b600082601f83011261212657600080fd5b8135602061213b612136836120c4565b611fe7565b82815260069290921b8401810191818101908684111561215a57600080fd5b8286015b848110156121a257604081890312156121775760008081fd5b61217f611f9b565b813561218a816120e8565b8152818501358582015283529183019160400161215e565b509695505050505050565b600080604083850312156121c057600080fd5b6121c983611f4f565b9150602083013567ffffffffffffffff808211156121e657600080fd5b9084019060a082870312156121fa57600080fd5b612202611fc4565b82358281111561221157600080fd5b61221d88828601612036565b82525060208301358281111561223257600080fd5b61223e88828601612036565b60208301525060408301358281111561225657600080fd5b61226288828601612115565b6040830152506122746060840161210a565b606082015260808301358281111561228b57600080fd5b61229788828601612036565b6080830152508093505050509250929050565b600080600080608085870312156122c057600080fd5b843567ffffffffffffffff8111156122d757600080fd5b850160a081880312156122e957600080fd5b9350602085013561ffff8116811461230057600080fd5b9250604085013591506060850135612317816120e8565b939692955090935050565b831515815260606020820152600061233d6060830185611ef2565b9050826040830152949350505050565b60006020828403121561235f57600080fd5b8135610ae7816120e8565b60008060006060848603121561237f57600080fd5b833561238a816120e8565b9250602084013561239a816120e8565b929592945050506040919091013590565b600080604083850312156123be57600080fd5b6123c783611f4f565b915060208301356123d7816120e8565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b82811015612444578151805167ffffffffffffffff16855286015173ffffffffffffffffffffffffffffffffffffffff168685015292840192908501906001016123ff565b5091979650505050505050565b60006020828403121561246357600080fd5b610ae782611f4f565b60008083601f84011261247e57600080fd5b50813567ffffffffffffffff81111561249657600080fd5b6020830191508360208260061b85010111156124b157600080fd5b9250929050565b600080600080600080606087890312156124d157600080fd5b863567ffffffffffffffff808211156124e957600080fd5b6124f58a838b0161246c565b9098509650602089013591508082111561250e57600080fd5b61251a8a838b0161246c565b9096509450604089013591508082111561253357600080fd5b5061254089828a0161246c565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b818110156125a057835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161256e565b50909695505050505050565b6000815160a084526125c160a0850182611ef2565b9050602080840151858303828701526125da8382611ef2565b60408681015188830389830152805180845290850195509092506000918401905b8083101561263a578551805173ffffffffffffffffffffffffffffffffffffffff168352850151858301529484019460019290920191908301906125fb565b5060608701519450612664606089018673ffffffffffffffffffffffffffffffffffffffff169052565b60808701519450878103608089015261267d8186611ef2565b98975050505050505050565b67ffffffffffffffff83168152604060208201526000611cce60408301846125ac565b6000602082840312156126be57600080fd5b5051919050565b6000602082840312156126d757600080fd5b81518015158114610ae757600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261271c57600080fd5b830160208101925035905067ffffffffffffffff81111561273c57600080fd5b8036038213156124b157600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156127e95781356127b7816120e8565b73ffffffffffffffffffffffffffffffffffffffff1687528183013583880152604096870196909101906001016127a4565b509495945050505050565b6020815281356020820152600061280d60208401611f4f565b67ffffffffffffffff808216604085015261282b60408601866126e7565b925060a0606086015261284260c08601848361274b565b92505061285260608601866126e7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08087860301608088015261288885838561274b565b9450608088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030183126128c157600080fd5b602092880192830192359150838211156128da57600080fd5b8160061b36038313156128ec57600080fd5b8685030160a0870152611de4848284612794565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561294157600080fd5b8151610ae7816120e8565b67ffffffffffffffff8516815260806020820152600061296f60808301866125ac565b905083604083015273ffffffffffffffffffffffffffffffffffffffff8316606083015295945050505050565b6000604082840312156129ae57600080fd5b6129b6611f9b565b6129bf83611f4f565b815260208301356129cf816120e8565b60208201529392505050565b600060208083850312156129ee57600080fd5b825167ffffffffffffffff811115612a0557600080fd5b8301601f81018513612a1657600080fd5b8051612a24612136826120c4565b81815260059190911b82018301908381019087831115612a4357600080fd5b928401925b82841015611de4578351612a5b816120e8565b82529284019290840190612a48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156105d3576105d3612a6a565b818103818111156105d3576105d3612a6a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251612b00818460208701611ece565b919091019291505056fea164736f6c6343000818000a", } var RouterABI = RouterMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/token_admin_registry/token_admin_registry.go b/core/gethwrappers/ccip/generated/token_admin_registry/token_admin_registry.go index a691fb6b85..7e81051aa3 100644 --- a/core/gethwrappers/ccip/generated/token_admin_registry/token_admin_registry.go +++ b/core/gethwrappers/ccip/generated/token_admin_registry/token_admin_registry.go @@ -38,7 +38,7 @@ type TokenAdminRegistryTokenConfig struct { var TokenAdminRegistryMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"AlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidTokenPoolToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"OnlyAdministrator\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"OnlyPendingAdministrator\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"OnlyRegistryModuleOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"currentAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdministratorTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdministratorTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousPool\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"PoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"RegistryModuleAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"RegistryModuleRemoved\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"acceptAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"addRegistryModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"startIndex\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxCount\",\"type\":\"uint64\"}],\"name\":\"getAllConfiguredTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getPools\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pendingAdministrator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenPool\",\"type\":\"address\"}],\"internalType\":\"structTokenAdminRegistry.TokenConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"}],\"name\":\"isAdministrator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"isRegistryModule\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"administrator\",\"type\":\"address\"}],\"name\":\"proposeAdministrator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"removeRegistryModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"setPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611449806101576000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80637d3f255211610097578063cb67e3b111610066578063cb67e3b1146102bc578063ddadfa8e14610374578063e677ae3714610387578063f2fde38b1461039a57600080fd5b80637d3f2552146101e05780638da5cb5b14610203578063bbe4f6db14610242578063c1af6e031461027f57600080fd5b80634e847fc7116100d35780634e847fc7146101925780635e63547a146101a557806372d64a81146101c557806379ba5097146101d857600080fd5b806310cbcf1814610105578063156194da1461011a578063181f5a771461012d5780633dc457721461017f575b600080fd5b61011861011336600461116c565b6103ad565b005b61011861012836600461116c565b61040a565b6101696040518060400160405280601881526020017f546f6b656e41646d696e526567697374727920312e352e30000000000000000081525081565b6040516101769190611187565b60405180910390f35b61011861018d36600461116c565b61050f565b6101186101a03660046111f4565b610573565b6101b86101b3366004611227565b6107d3565b604051610176919061129c565b6101b86101d336600461130e565b6108cc565b6101186109e2565b6101f36101ee36600461116c565b610adf565b6040519015158152602001610176565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610176565b61021d61025036600461116c565b73ffffffffffffffffffffffffffffffffffffffff908116600090815260026020819052604090912001541690565b6101f361028d3660046111f4565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260026020526040902054821691161490565b6103356102ca36600461116c565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff948516815260028084529084902084519283018552805486168352600181015486169383019390935291909101549092169082015290565b60408051825173ffffffffffffffffffffffffffffffffffffffff90811682526020808501518216908301529282015190921690820152606001610176565b6101186103823660046111f4565b610aec565b6101186103953660046111f4565b610bf6565b6101186103a836600461116c565b610dbe565b6103b5610dcf565b6103c0600582610e52565b156104075760405173ffffffffffffffffffffffffffffffffffffffff8216907f93eaa26dcb9275e56bacb1d33fdbf402262da6f0f4baf2a6e2cd154b73f387f890600090a25b50565b73ffffffffffffffffffffffffffffffffffffffff808216600090815260026020526040902060018101549091163314610493576040517f3edffe7500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff831660248201526044015b60405180910390fd5b8054337fffffffffffffffffffffffff00000000000000000000000000000000000000009182168117835560018301805490921690915560405173ffffffffffffffffffffffffffffffffffffffff8416907f399b55200f7f639a63d76efe3dcfa9156ce367058d6b673041b84a628885f5a790600090a35050565b610517610dcf565b610522600582610e7b565b156104075760405173ffffffffffffffffffffffffffffffffffffffff821681527f3cabf004338366bfeaeb610ad827cb58d16b588017c509501f2c97c83caae7b29060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff80831660009081526002602052604090205483911633146105f3576040517fed5d85b500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161048a565b73ffffffffffffffffffffffffffffffffffffffff8216158015906106a557506040517f240028e800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283169063240028e890602401602060405180830381865afa15801561067f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a39190611338565b155b156106f4576040517f962b60e600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240161048a565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020819052604090912090810180548584167fffffffffffffffffffffffff0000000000000000000000000000000000000000821681179092559192919091169081146107cc578373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f754449ec3aff3bd528bfce43ae9319c4a381b67fcd1d20097b3b24dacaecc35d60405160405180910390a45b5050505050565b606060008267ffffffffffffffff8111156107f0576107f061135a565b604051908082528060200260200182016040528015610819578160200160208202803683370190505b50905060005b838110156108c2576002600086868481811061083d5761083d611389565b9050602002016020810190610852919061116c565b73ffffffffffffffffffffffffffffffffffffffff9081168252602082019290925260400160002060020154835191169083908390811061089557610895611389565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015260010161081f565b5090505b92915050565b606060006108da6003610e9d565b9050808467ffffffffffffffff16106108f357506108c6565b67ffffffffffffffff80841690829061090e908716836113e7565b111561092b5761092867ffffffffffffffff8616836113fa565b90505b8067ffffffffffffffff8111156109445761094461135a565b60405190808252806020026020018201604052801561096d578160200160208202803683370190505b50925060005b818110156109d95761099a6109928267ffffffffffffffff89166113e7565b600390610ea7565b8482815181106109ac576109ac611389565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101610973565b50505092915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161048a565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006108c6600583610eb3565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020548391163314610b6c576040517fed5d85b500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161048a565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152600260205260408082206001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001695881695861790559051909392339290917fc54c3051ff16e63bb9203214432372aca006c589e3653619b577a3265675b7169190a450505050565b610bff33610adf565b158015610c24575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610c5d576040517f51ca1ec300000000000000000000000000000000000000000000000000000000815233600482015260240161048a565b73ffffffffffffffffffffffffffffffffffffffff8116610caa576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020805490911615610d24576040517f45ed80e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240161048a565b6001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055610d71600384610e7b565b5060405173ffffffffffffffffffffffffffffffffffffffff808416916000918616907fc54c3051ff16e63bb9203214432372aca006c589e3653619b577a3265675b716908390a4505050565b610dc6610dcf565b61040781610ee2565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161048a565b565b6000610e748373ffffffffffffffffffffffffffffffffffffffff8416610fd7565b9392505050565b6000610e748373ffffffffffffffffffffffffffffffffffffffff84166110ca565b60006108c6825490565b6000610e748383611119565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610e74565b3373ffffffffffffffffffffffffffffffffffffffff821603610f61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161048a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081815260018301602052604081205480156110c0576000610ffb6001836113fa565b855490915060009061100f906001906113fa565b905081811461107457600086600001828154811061102f5761102f611389565b906000526020600020015490508087600001848154811061105257611052611389565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806110855761108561140d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108c6565b60009150506108c6565b6000818152600183016020526040812054611111575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108c6565b5060006108c6565b600082600001828154811061113057611130611389565b9060005260206000200154905092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116757600080fd5b919050565b60006020828403121561117e57600080fd5b610e7482611143565b60006020808352835180602085015260005b818110156111b557858101830151858201604001528201611199565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000806040838503121561120757600080fd5b61121083611143565b915061121e60208401611143565b90509250929050565b6000806020838503121561123a57600080fd5b823567ffffffffffffffff8082111561125257600080fd5b818501915085601f83011261126657600080fd5b81358181111561127557600080fd5b8660208260051b850101111561128a57600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b818110156112ea57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016112b8565b50909695505050505050565b803567ffffffffffffffff8116811461116757600080fd5b6000806040838503121561132157600080fd5b61132a836112f6565b915061121e602084016112f6565b60006020828403121561134a57600080fd5b81518015158114610e7457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156108c6576108c66113b8565b818103818111156108c6576108c66113b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611449806101576000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80637d3f255211610097578063cb67e3b111610066578063cb67e3b1146102bc578063ddadfa8e14610374578063e677ae3714610387578063f2fde38b1461039a57600080fd5b80637d3f2552146101e05780638da5cb5b14610203578063bbe4f6db14610242578063c1af6e031461027f57600080fd5b80634e847fc7116100d35780634e847fc7146101925780635e63547a146101a557806372d64a81146101c557806379ba5097146101d857600080fd5b806310cbcf1814610105578063156194da1461011a578063181f5a771461012d5780633dc457721461017f575b600080fd5b61011861011336600461116c565b6103ad565b005b61011861012836600461116c565b61040a565b6101696040518060400160405280601881526020017f546f6b656e41646d696e526567697374727920312e352e30000000000000000081525081565b6040516101769190611187565b60405180910390f35b61011861018d36600461116c565b61050f565b6101186101a03660046111f4565b610573565b6101b86101b3366004611227565b6107d3565b604051610176919061129c565b6101b86101d336600461130e565b6108cc565b6101186109e2565b6101f36101ee36600461116c565b610adf565b6040519015158152602001610176565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610176565b61021d61025036600461116c565b73ffffffffffffffffffffffffffffffffffffffff908116600090815260026020819052604090912001541690565b6101f361028d3660046111f4565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260026020526040902054821691161490565b6103356102ca36600461116c565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff948516815260028084529084902084519283018552805486168352600181015486169383019390935291909101549092169082015290565b60408051825173ffffffffffffffffffffffffffffffffffffffff90811682526020808501518216908301529282015190921690820152606001610176565b6101186103823660046111f4565b610aec565b6101186103953660046111f4565b610bf6565b6101186103a836600461116c565b610dbe565b6103b5610dcf565b6103c0600582610e52565b156104075760405173ffffffffffffffffffffffffffffffffffffffff8216907f93eaa26dcb9275e56bacb1d33fdbf402262da6f0f4baf2a6e2cd154b73f387f890600090a25b50565b73ffffffffffffffffffffffffffffffffffffffff808216600090815260026020526040902060018101549091163314610493576040517f3edffe7500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff831660248201526044015b60405180910390fd5b8054337fffffffffffffffffffffffff00000000000000000000000000000000000000009182168117835560018301805490921690915560405173ffffffffffffffffffffffffffffffffffffffff8416907f399b55200f7f639a63d76efe3dcfa9156ce367058d6b673041b84a628885f5a790600090a35050565b610517610dcf565b610522600582610e7b565b156104075760405173ffffffffffffffffffffffffffffffffffffffff821681527f3cabf004338366bfeaeb610ad827cb58d16b588017c509501f2c97c83caae7b29060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff80831660009081526002602052604090205483911633146105f3576040517fed5d85b500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161048a565b73ffffffffffffffffffffffffffffffffffffffff8216158015906106a557506040517f240028e800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283169063240028e890602401602060405180830381865afa15801561067f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a39190611338565b155b156106f4576040517f962b60e600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240161048a565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020819052604090912090810180548584167fffffffffffffffffffffffff0000000000000000000000000000000000000000821681179092559192919091169081146107cc578373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f754449ec3aff3bd528bfce43ae9319c4a381b67fcd1d20097b3b24dacaecc35d60405160405180910390a45b5050505050565b606060008267ffffffffffffffff8111156107f0576107f061135a565b604051908082528060200260200182016040528015610819578160200160208202803683370190505b50905060005b838110156108c2576002600086868481811061083d5761083d611389565b9050602002016020810190610852919061116c565b73ffffffffffffffffffffffffffffffffffffffff9081168252602082019290925260400160002060020154835191169083908390811061089557610895611389565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015260010161081f565b5090505b92915050565b606060006108da6003610e9d565b9050808467ffffffffffffffff16106108f357506108c6565b67ffffffffffffffff80841690829061090e908716836113e7565b111561092b5761092867ffffffffffffffff8616836113fa565b90505b8067ffffffffffffffff8111156109445761094461135a565b60405190808252806020026020018201604052801561096d578160200160208202803683370190505b50925060005b818110156109d95761099a6109928267ffffffffffffffff89166113e7565b600390610ea7565b8482815181106109ac576109ac611389565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101610973565b50505092915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161048a565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006108c6600583610eb3565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020548391163314610b6c576040517fed5d85b500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161048a565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152600260205260408082206001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001695881695861790559051909392339290917fc54c3051ff16e63bb9203214432372aca006c589e3653619b577a3265675b7169190a450505050565b610bff33610adf565b158015610c24575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610c5d576040517f51ca1ec300000000000000000000000000000000000000000000000000000000815233600482015260240161048a565b73ffffffffffffffffffffffffffffffffffffffff8116610caa576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020805490911615610d24576040517f45ed80e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240161048a565b6001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055610d71600384610e7b565b5060405173ffffffffffffffffffffffffffffffffffffffff808416916000918616907fc54c3051ff16e63bb9203214432372aca006c589e3653619b577a3265675b716908390a4505050565b610dc6610dcf565b61040781610ee2565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161048a565b565b6000610e748373ffffffffffffffffffffffffffffffffffffffff8416610fd7565b9392505050565b6000610e748373ffffffffffffffffffffffffffffffffffffffff84166110ca565b60006108c6825490565b6000610e748383611119565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610e74565b3373ffffffffffffffffffffffffffffffffffffffff821603610f61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161048a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081815260018301602052604081205480156110c0576000610ffb6001836113fa565b855490915060009061100f906001906113fa565b905080821461107457600086600001828154811061102f5761102f611389565b906000526020600020015490508087600001848154811061105257611052611389565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806110855761108561140d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108c6565b60009150506108c6565b6000818152600183016020526040812054611111575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108c6565b5060006108c6565b600082600001828154811061113057611130611389565b9060005260206000200154905092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116757600080fd5b919050565b60006020828403121561117e57600080fd5b610e7482611143565b60006020808352835180602085015260005b818110156111b557858101830151858201604001528201611199565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000806040838503121561120757600080fd5b61121083611143565b915061121e60208401611143565b90509250929050565b6000806020838503121561123a57600080fd5b823567ffffffffffffffff8082111561125257600080fd5b818501915085601f83011261126657600080fd5b81358181111561127557600080fd5b8660208260051b850101111561128a57600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b818110156112ea57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016112b8565b50909695505050505050565b803567ffffffffffffffff8116811461116757600080fd5b6000806040838503121561132157600080fd5b61132a836112f6565b915061121e602084016112f6565b60006020828403121561134a57600080fd5b81518015158114610e7457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156108c6576108c66113b8565b818103818111156108c6576108c66113b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var TokenAdminRegistryABI = TokenAdminRegistryMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go index c8148b24fe..3e754d5cb7 100644 --- a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go +++ b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go @@ -96,7 +96,7 @@ type USDCTokenPoolDomainUpdate struct { var USDCTokenPoolMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b50604051620052c6380380620052c6833981016040819052620000359162000b4c565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200041b565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016957604080516000815260208101909152620001699084620004c6565b5050506001600160a01b038616905062000196576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fd919062000c72565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000240573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000266919062000c99565b905063ffffffff81161562000297576040516334697c6b60e11b815263ffffffff8216600482015260240162000087565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fe919062000c99565b905063ffffffff8116156200032f576040516316ba39c560e31b815263ffffffff8216600482015260240162000087565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa15801562000381573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a7919062000c99565b63ffffffff166101205260e051608051620003d1916001600160a01b039091169060001962000623565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000de6565b336001600160a01b03821603620004755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620004e7576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005725760008382815181106200050b576200050b62000cc1565b602090810291909101015190506200052560028262000709565b1562000568576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620004ea565b5060005b81518110156200061e57600082828151811062000597576200059762000cc1565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005c3575062000615565b620005d060028262000729565b1562000613576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000576565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200069b919062000cd7565b620006a7919062000d07565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000703918691906200074016565b50505050565b600062000720836001600160a01b03841662000811565b90505b92915050565b600062000720836001600160a01b03841662000915565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200078f906001600160a01b03851690849062000967565b8051909150156200061e5780806020019051810190620007b0919062000d1d565b6200061e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000087565b600081815260018301602052604081205480156200090a5760006200083860018362000d41565b85549091506000906200084e9060019062000d41565b9050818114620008ba57600086600001828154811062000872576200087262000cc1565b906000526020600020015490508087600001848154811062000898576200089862000cc1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620008ce57620008ce62000d57565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000723565b600091505062000723565b60008181526001830160205260408120546200095e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000723565b50600062000723565b606062000978848460008562000980565b949350505050565b606082471015620009e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000087565b600080866001600160a01b0316858760405162000a01919062000d93565b60006040518083038185875af1925050503d806000811462000a40576040519150601f19603f3d011682016040523d82523d6000602084013e62000a45565b606091505b50909250905062000a598783838762000a64565b979650505050505050565b6060831562000ad857825160000362000ad0576001600160a01b0385163b62000ad05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000087565b508162000978565b62000978838381511562000aef5781518083602001fd5b8060405162461bcd60e51b815260040162000087919062000db1565b6001600160a01b038116811462000b2157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b478162000b0b565b919050565b600080600080600060a0868803121562000b6557600080fd5b855162000b728162000b0b565b8095505060208087015162000b878162000b0b565b60408801519095506001600160401b038082111562000ba557600080fd5b818901915089601f83011262000bba57600080fd5b81518181111562000bcf5762000bcf62000b24565b8060051b604051601f19603f8301168101818110858211171562000bf75762000bf762000b24565b60405291825284820192508381018501918c83111562000c1657600080fd5b938501935b8285101562000c3f5762000c2f8562000b3a565b8452938501939285019262000c1b565b80985050505050505062000c566060870162000b3a565b915062000c666080870162000b3a565b90509295509295909350565b60006020828403121562000c8557600080fd5b815162000c928162000b0b565b9392505050565b60006020828403121562000cac57600080fd5b815163ffffffff8116811462000c9257600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000cea57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000723576200072362000cf1565b60006020828403121562000d3057600080fd5b8151801515811462000c9257600080fd5b8181038181111562000723576200072362000cf1565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d8a57818101518382015260200162000d70565b50506000910152565b6000825162000da781846020870162000d6d565b9190910192915050565b602081526000825180602084015262000dd281604085016020870162000d6d565b601f01601f19169190910160400192915050565b60805160a05160c05160e051610100516101205161442762000e9f60003960008181610382015281816111d101528181611e4a0152611ea80152600081816106760152610a7801526000818161035b01526110e701526000818161063a01528181611f45015261288001526000818161057601528181611c4801526121fb01526000818161028f015281816102e4015281816110b101528181611b680152818161211b015281816128160152612a6b01526144276000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80639a4575b91161010f578063c75eea9c116100a2578063dfadfa3511610071578063dfadfa351461059a578063e0351e1314610638578063f2fde38b1461065e578063fbf84dd71461067157600080fd5b8063c75eea9c1461053b578063cf7401f31461054e578063db6327dc14610561578063dc0bd9711461057457600080fd5b8063b0f479a1116100de578063b0f479a1146104e2578063b794658014610500578063c0d7865514610513578063c4bffe2b1461052657600080fd5b80639a4575b9146104365780639fdf13ff14610456578063a7cd63b71461045e578063af58d59f1461047357600080fd5b80636155cda01161018757806379ba50971161015657806379ba5097146103ea5780637d54534e146103f25780638926f54f146104055780638da5cb5b1461041857600080fd5b80636155cda0146103565780636b716b0d1461037d5780636d3d1a58146103b957806378a010b2146103d757600080fd5b806321df0da7116101c357806321df0da71461028d578063240028e8146102d4578063390775371461032157806354c8a4f31461034357600080fd5b806241d3c1146101f457806301ffc9a7146102095780630a2fd49314610231578063181f5a7714610251575b600080fd5b61020761020236600461320e565b610698565b005b61021c610217366004613283565b610835565b60405190151581526020015b60405180910390f35b61024461023f3660046132eb565b61091a565b604051610228919061336c565b6102446040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e352e300000000000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610228565b61021c6102e23660046133ac565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61033461032f3660046133c9565b6109ca565b60405190518152602001610228565b610207610351366004613451565b610bb7565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6103a47f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610228565b60085473ffffffffffffffffffffffffffffffffffffffff166102af565b6102076103e53660046134bd565b610c32565b610207610da1565b6102076104003660046133ac565b610e9e565b61021c6104133660046132eb565b610eed565b60005473ffffffffffffffffffffffffffffffffffffffff166102af565b610449610444366004613542565b610f04565b604051610228919061357d565b6103a4600081565b61046661124c565b60405161022891906135dd565b6104866104813660046132eb565b61125d565b604051610228919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102af565b61024461050e3660046132eb565b611332565b6102076105213660046133ac565b61135d565b61052e611431565b6040516102289190613637565b6104866105493660046132eb565b6114e9565b61020761055c3660046137c2565b6115bb565b61020761056f366004613809565b611644565b7f00000000000000000000000000000000000000000000000000000000000000006102af565b61060e6105a83660046132eb565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600982529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610228565b7f000000000000000000000000000000000000000000000000000000000000000061021c565b61020761066c3660046133ac565b611aca565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6106a0611ade565b60005b818110156107f75760008383838181106106bf576106bf61384b565b9050608002018036038101906106d5919061388e565b805190915015806106f25750604081015167ffffffffffffffff16155b1561076157604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600990925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169190931617929092179055016106a3565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee568282604051610829929190613908565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806108c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061091457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906109459061398f565b80601f01602080910402602001604051908101604052809291908181526020018280546109719061398f565b80156109be5780601f10610993576101008083540402835291602001916109be565b820191906000526020600020905b8154815290600101906020018083116109a157829003601f168201915b50505050509050919050565b6040805160208101909152600081526109ea6109e583613a8d565b611b61565b60006109f960c0840184613b82565b810190610a069190613be7565b90506000610a1760e0850185613b82565b810190610a249190613c26565b9050610a34816000015183611d92565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aab92600401613cb7565b6020604051808303816000875af1158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190613cdc565b610b24576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3460608501604086016133ac565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610b9691815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b610bbf611ade565b610c2c84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f4392505050565b50505050565b610c3a611ade565b610c4383610eed565b610c85576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b67ffffffffffffffff831660009081526007602052604081206004018054610cac9061398f565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd89061398f565b8015610d255780601f10610cfa57610100808354040283529160200191610d25565b820191906000526020600020905b815481529060010190602001808311610d0857829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610d54838583613d41565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d9393929190613ea5565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610758565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ea6611ade565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610914600567ffffffffffffffff84166120f9565b6040805180820190915260608082526020820152610f29610f2483613ed5565b612114565b6000600981610f3e60408601602087016132eb565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff161515908201819052909150610fe557610fa660408401602085016132eb565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b610fef8380613b82565b9050602014611036576110028380613b82565b6040517fa3c8cf09000000000000000000000000000000000000000000000000000000008152600401610758929190613f79565b60006110428480613b82565b81019061104f9190613f8d565b602083015183516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060880135600482015263ffffffff90921660248301526044820183905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063f856ddb69060a4016020604051808303816000875af1158015611130573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111549190613fa6565b6040516060870135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260405180604001604052806111b187602001602081019061050e91906132eb565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905295945050505050565b606061125860026122de565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610914906122eb565b67ffffffffffffffff811660009081526007602052604090206005018054606091906109459061398f565b611365611ade565b73ffffffffffffffffffffffffffffffffffffffff81166113b2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610829565b6060600061143f60056122de565b90506000815167ffffffffffffffff81111561145d5761145d613679565b604051908082528060200260200182016040528015611486578160200160208202803683370190505b50905060005b82518110156114e2578281815181106114a7576114a761384b565b60200260200101518282815181106114c1576114c161384b565b67ffffffffffffffff9092166020928302919091019091015260010161148c565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610914906122eb565b60085473ffffffffffffffffffffffffffffffffffffffff1633148015906115fb575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611634576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b61163f83838361239d565b505050565b61164c611ade565b60005b8181101561163f57600083838381811061166b5761166b61384b565b905060200281019061167d9190613fc3565b61168690614001565b905061169b8160800151826020015115612487565b6116ae8160a00151826020015115612487565b8060200151156119aa5780516116d09060059067ffffffffffffffff166125c0565b6117155780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b604081015151158061172a5750606081015151155b15611761576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061194290826140b5565b506060820151600582019061195790826140b5565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061199d94939291906141cf565b60405180910390a1611ac1565b80516119c29060059067ffffffffffffffff166125cc565b611a075780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611a7060048301826131c0565b611a7e6005830160006131c0565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161164f565b611ad2611ade565b611adb816125d8565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610758565b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611bf65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc89190613cdc565b15611cff576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d0c81602001516126cd565b6000611d1b826020015161091a565b9050805160001480611d3f575080805190602001208260a001518051906020012014155b15611d7c578160a001516040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610758919061336c565b611d8e826020015183606001516127f3565b5050565b600482015163ffffffff811615611ddd576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610758565b6008830151600c8401516014850151602085015163ffffffff808516911614611e485760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff91821660048201529084166024820152604401610758565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611edd576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015283166024820152604401610758565b845167ffffffffffffffff828116911614611f3b5784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821660048201529082166024820152604401610758565b505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611f9a576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612030576000838281518110611fba57611fba61384b565b60200260200101519050611fd881600261283a90919063ffffffff16565b156120275760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f9d565b5060005b815181101561163f5760008282815181106120515761205161384b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361209557506120f1565b6120a060028261285c565b156120ef5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612034565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121a95760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227b9190613cdc565b156122b2576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122bf816040015161287e565b6122cc81602001516128fd565b611adb81602001518260600151612a4b565b6060600061210d83612a8f565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261237982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261235d9190614297565b85608001516fffffffffffffffffffffffffffffffff16612aea565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6123a683610eed565b6123e8576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b6123f3826000612487565b67ffffffffffffffff831660009081526007602052604090206124169083612b14565b612421816000612487565b67ffffffffffffffff831660009081526007602052604090206124479060020182612b14565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161247a939291906142aa565b60405180910390a1505050565b81511561254e5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806124dd575060408201516fffffffffffffffffffffffffffffffff16155b1561251657816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610758919061432d565b8015611d8e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612587575060208201516fffffffffffffffffffffffffffffffff1615155b15611d8e57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610758919061432d565b600061210d8383612cb6565b600061210d8383612d05565b3373ffffffffffffffffffffffffffffffffffffffff821603612657576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610758565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6126d681610eed565b612718576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612797573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127bb9190613cdc565b611adb576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d8e90600201827f0000000000000000000000000000000000000000000000000000000000000000612df8565b600061210d8373ffffffffffffffffffffffffffffffffffffffff8416612d05565b600061210d8373ffffffffffffffffffffffffffffffffffffffff8416612cb6565b7f000000000000000000000000000000000000000000000000000000000000000015611adb576128af60028261317b565b611adb576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610758565b61290681610eed565b612948576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156129c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e59190614369565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611adb576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d8e90827f0000000000000000000000000000000000000000000000000000000000000000612df8565b6060816000018054806020026020016040519081016040528092919081815260200182805480156109be57602002820191906000526020600020905b815481526020019060010190808311612acb5750505050509050919050565b6000612b0985612afa8486614386565b612b04908761439d565b6131aa565b90505b949350505050565b8154600090612b3d90700100000000000000000000000000000000900463ffffffff1642614297565b90508015612bdf5760018301548354612b85916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612aea565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c05916fffffffffffffffffffffffffffffffff90811691166131aa565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061247a90849061432d565b6000818152600183016020526040812054612cfd57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610914565b506000610914565b60008181526001830160205260408120548015612dee576000612d29600183614297565b8554909150600090612d3d90600190614297565b9050818114612da2576000866000018281548110612d5d57612d5d61384b565b9060005260206000200154905080876000018481548110612d8057612d8061384b565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612db357612db36143b0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610914565b6000915050610914565b825474010000000000000000000000000000000000000000900460ff161580612e1f575081155b15612e2957505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612e6f90700100000000000000000000000000000000900463ffffffff1642614297565b90508015612f2f5781831115612eb1576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612eeb9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612aea565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612fe65773ffffffffffffffffffffffffffffffffffffffff8416612f8e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610758565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610758565b848310156130f95760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061302a9082614297565b613034878a614297565b61303e919061439d565b61304891906143df565b905073ffffffffffffffffffffffffffffffffffffffff86166130a1576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610758565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610758565b6131038584614297565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561210d565b60008183106131b9578161210d565b5090919050565b5080546131cc9061398f565b6000825580601f106131dc575050565b601f016020900490600052602060002090810190611adb91905b8082111561320a57600081556001016131f6565b5090565b6000806020838503121561322157600080fd5b823567ffffffffffffffff8082111561323957600080fd5b818501915085601f83011261324d57600080fd5b81358181111561325c57600080fd5b8660208260071b850101111561327157600080fd5b60209290920196919550909350505050565b60006020828403121561329557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461210d57600080fd5b67ffffffffffffffff81168114611adb57600080fd5b80356132e6816132c5565b919050565b6000602082840312156132fd57600080fd5b813561210d816132c5565b6000815180845260005b8181101561332e57602081850181015186830182015201613312565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061210d6020830184613308565b73ffffffffffffffffffffffffffffffffffffffff81168114611adb57600080fd5b80356132e68161337f565b6000602082840312156133be57600080fd5b813561210d8161337f565b6000602082840312156133db57600080fd5b813567ffffffffffffffff8111156133f257600080fd5b8201610100818503121561210d57600080fd5b60008083601f84011261341757600080fd5b50813567ffffffffffffffff81111561342f57600080fd5b6020830191508360208260051b850101111561344a57600080fd5b9250929050565b6000806000806040858703121561346757600080fd5b843567ffffffffffffffff8082111561347f57600080fd5b61348b88838901613405565b909650945060208701359150808211156134a457600080fd5b506134b187828801613405565b95989497509550505050565b6000806000604084860312156134d257600080fd5b83356134dd816132c5565b9250602084013567ffffffffffffffff808211156134fa57600080fd5b818601915086601f83011261350e57600080fd5b81358181111561351d57600080fd5b87602082850101111561352f57600080fd5b6020830194508093505050509250925092565b60006020828403121561355457600080fd5b813567ffffffffffffffff81111561356b57600080fd5b820160a0818503121561210d57600080fd5b6020815260008251604060208401526135996060840182613308565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526135d48282613308565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561362b57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016135f9565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561362b57835167ffffffffffffffff1683529284019291840191600101613653565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156136cc576136cc613679565b60405290565b6040805190810167ffffffffffffffff811182821017156136cc576136cc613679565b60405160c0810167ffffffffffffffff811182821017156136cc576136cc613679565b8015158114611adb57600080fd5b80356132e681613718565b80356fffffffffffffffffffffffffffffffff811681146132e657600080fd5b60006060828403121561376357600080fd5b6040516060810181811067ffffffffffffffff8211171561378657613786613679565b604052905080823561379781613718565b81526137a560208401613731565b60208201526137b660408401613731565b60408201525092915050565b600080600060e084860312156137d757600080fd5b83356137e2816132c5565b92506137f18560208601613751565b91506138008560808601613751565b90509250925092565b6000806020838503121561381c57600080fd5b823567ffffffffffffffff81111561383357600080fd5b61383f85828601613405565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff811681146132e657600080fd5b6000608082840312156138a057600080fd5b6040516080810181811067ffffffffffffffff821117156138c3576138c3613679565b604052823581526138d66020840161387a565b602082015260408301356138e9816132c5565b604082015260608301356138fc81613718565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613982578135835263ffffffff61393a86840161387a565b16858401528382013561394c816132c5565b67ffffffffffffffff168385015260608281013561396981613718565b151590840152608092830192919091019060010161391e565b5090979650505050505050565b600181811c908216806139a357607f821691505b6020821081036139dc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126139f357600080fd5b813567ffffffffffffffff80821115613a0e57613a0e613679565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613a5457613a54613679565b81604052838152866020858801011115613a6d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613aa057600080fd5b613aa86136a8565b823567ffffffffffffffff80821115613ac057600080fd5b613acc368387016139e2565b8352613ada602086016132db565b6020840152613aeb604086016133a1565b604084015260608501356060840152613b06608086016133a1565b608084015260a0850135915080821115613b1f57600080fd5b613b2b368387016139e2565b60a084015260c0850135915080821115613b4457600080fd5b613b50368387016139e2565b60c084015260e0850135915080821115613b6957600080fd5b50613b76368286016139e2565b60e08301525092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613bb757600080fd5b83018035915067ffffffffffffffff821115613bd257600080fd5b60200191503681900382131561344a57600080fd5b600060408284031215613bf957600080fd5b613c016136d2565b8235613c0c816132c5565b8152613c1a6020840161387a565b60208201529392505050565b600060208284031215613c3857600080fd5b813567ffffffffffffffff80821115613c5057600080fd5b9083019060408286031215613c6457600080fd5b613c6c6136d2565b823582811115613c7b57600080fd5b613c87878286016139e2565b825250602083013582811115613c9c57600080fd5b613ca8878286016139e2565b60208301525095945050505050565b604081526000613cca6040830185613308565b82810360208401526135d48185613308565b600060208284031215613cee57600080fd5b815161210d81613718565b601f82111561163f576000816000526020600020601f850160051c81016020861015613d225750805b601f850160051c820191505b81811015611f3b57828155600101613d2e565b67ffffffffffffffff831115613d5957613d59613679565b613d6d83613d67835461398f565b83613cf9565b6000601f841160018114613dbf5760008515613d895750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613e55565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613e0e5786850135825560209485019460019092019101613dee565b5086821015613e49577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000613eb86040830186613308565b8281036020840152613ecb818587613e5c565b9695505050505050565b600060a08236031215613ee757600080fd5b60405160a0810167ffffffffffffffff8282108183111715613f0b57613f0b613679565b816040528435915080821115613f2057600080fd5b50613f2d368286016139e2565b8252506020830135613f3e816132c5565b60208201526040830135613f518161337f565b6040820152606083810135908201526080830135613f6e8161337f565b608082015292915050565b602081526000612b0c602083018486613e5c565b600060208284031215613f9f57600080fd5b5035919050565b600060208284031215613fb857600080fd5b815161210d816132c5565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ff757600080fd5b9190910192915050565b6000610140823603121561401457600080fd5b61401c6136f5565b614025836132db565b815261403360208401613726565b6020820152604083013567ffffffffffffffff8082111561405357600080fd5b61405f368387016139e2565b6040840152606085013591508082111561407857600080fd5b50614085368286016139e2565b6060830152506140983660808501613751565b60808201526140aa3660e08501613751565b60a082015292915050565b815167ffffffffffffffff8111156140cf576140cf613679565b6140e3816140dd845461398f565b84613cf9565b602080601f83116001811461413657600084156141005750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611f3b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561418357888601518255948401946001909101908401614164565b50858210156141bf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526141f381840187613308565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506142319050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526135d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561091457610914614268565b67ffffffffffffffff8416815260e081016142f660208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612b0c565b6060810161091482848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561437b57600080fd5b815161210d8161337f565b808202811582820484141761091457610914614268565b8082018082111561091457610914614268565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614415577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + Bin: "0x6101406040523480156200001257600080fd5b50604051620052c6380380620052c6833981016040819052620000359162000b4c565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200041b565b5050506001600160a01b0384161580620000e457506001600160a01b038116155b80620000f757506001600160a01b038216155b1562000116576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016957604080516000815260208101909152620001699084620004c6565b5050506001600160a01b038616905062000196576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fd919062000c72565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000240573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000266919062000c99565b905063ffffffff81161562000297576040516334697c6b60e11b815263ffffffff8216600482015260240162000087565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fe919062000c99565b905063ffffffff8116156200032f576040516316ba39c560e31b815263ffffffff8216600482015260240162000087565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa15801562000381573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a7919062000c99565b63ffffffff166101205260e051608051620003d1916001600160a01b039091169060001962000623565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000de6565b336001600160a01b03821603620004755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620004e7576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005725760008382815181106200050b576200050b62000cc1565b602090810291909101015190506200052560028262000709565b1562000568576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620004ea565b5060005b81518110156200061e57600082828151811062000597576200059762000cc1565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005c3575062000615565b620005d060028262000729565b1562000613576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000576565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200069b919062000cd7565b620006a7919062000d07565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000703918691906200074016565b50505050565b600062000720836001600160a01b03841662000811565b90505b92915050565b600062000720836001600160a01b03841662000915565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200078f906001600160a01b03851690849062000967565b8051909150156200061e5780806020019051810190620007b0919062000d1d565b6200061e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000087565b600081815260018301602052604081205480156200090a5760006200083860018362000d41565b85549091506000906200084e9060019062000d41565b9050808214620008ba57600086600001828154811062000872576200087262000cc1565b906000526020600020015490508087600001848154811062000898576200089862000cc1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620008ce57620008ce62000d57565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000723565b600091505062000723565b60008181526001830160205260408120546200095e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000723565b50600062000723565b606062000978848460008562000980565b949350505050565b606082471015620009e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000087565b600080866001600160a01b0316858760405162000a01919062000d93565b60006040518083038185875af1925050503d806000811462000a40576040519150601f19603f3d011682016040523d82523d6000602084013e62000a45565b606091505b50909250905062000a598783838762000a64565b979650505050505050565b6060831562000ad857825160000362000ad0576001600160a01b0385163b62000ad05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000087565b508162000978565b62000978838381511562000aef5781518083602001fd5b8060405162461bcd60e51b815260040162000087919062000db1565b6001600160a01b038116811462000b2157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b478162000b0b565b919050565b600080600080600060a0868803121562000b6557600080fd5b855162000b728162000b0b565b8095505060208087015162000b878162000b0b565b60408801519095506001600160401b038082111562000ba557600080fd5b818901915089601f83011262000bba57600080fd5b81518181111562000bcf5762000bcf62000b24565b8060051b604051601f19603f8301168101818110858211171562000bf75762000bf762000b24565b60405291825284820192508381018501918c83111562000c1657600080fd5b938501935b8285101562000c3f5762000c2f8562000b3a565b8452938501939285019262000c1b565b80985050505050505062000c566060870162000b3a565b915062000c666080870162000b3a565b90509295509295909350565b60006020828403121562000c8557600080fd5b815162000c928162000b0b565b9392505050565b60006020828403121562000cac57600080fd5b815163ffffffff8116811462000c9257600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000cea57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000723576200072362000cf1565b60006020828403121562000d3057600080fd5b8151801515811462000c9257600080fd5b8181038181111562000723576200072362000cf1565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d8a57818101518382015260200162000d70565b50506000910152565b6000825162000da781846020870162000d6d565b9190910192915050565b602081526000825180602084015262000dd281604085016020870162000d6d565b601f01601f19169190910160400192915050565b60805160a05160c05160e051610100516101205161442762000e9f60003960008181610382015281816111d101528181611e4a0152611ea80152600081816106760152610a7801526000818161035b01526110e701526000818161063a01528181611f45015261288001526000818161057601528181611c4801526121fb01526000818161028f015281816102e4015281816110b101528181611b680152818161211b015281816128160152612a6b01526144276000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80639a4575b91161010f578063c75eea9c116100a2578063dfadfa3511610071578063dfadfa351461059a578063e0351e1314610638578063f2fde38b1461065e578063fbf84dd71461067157600080fd5b8063c75eea9c1461053b578063cf7401f31461054e578063db6327dc14610561578063dc0bd9711461057457600080fd5b8063b0f479a1116100de578063b0f479a1146104e2578063b794658014610500578063c0d7865514610513578063c4bffe2b1461052657600080fd5b80639a4575b9146104365780639fdf13ff14610456578063a7cd63b71461045e578063af58d59f1461047357600080fd5b80636155cda01161018757806379ba50971161015657806379ba5097146103ea5780637d54534e146103f25780638926f54f146104055780638da5cb5b1461041857600080fd5b80636155cda0146103565780636b716b0d1461037d5780636d3d1a58146103b957806378a010b2146103d757600080fd5b806321df0da7116101c357806321df0da71461028d578063240028e8146102d4578063390775371461032157806354c8a4f31461034357600080fd5b806241d3c1146101f457806301ffc9a7146102095780630a2fd49314610231578063181f5a7714610251575b600080fd5b61020761020236600461320e565b610698565b005b61021c610217366004613283565b610835565b60405190151581526020015b60405180910390f35b61024461023f3660046132eb565b61091a565b604051610228919061336c565b6102446040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e352e300000000000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610228565b61021c6102e23660046133ac565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61033461032f3660046133c9565b6109ca565b60405190518152602001610228565b610207610351366004613451565b610bb7565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6103a47f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610228565b60085473ffffffffffffffffffffffffffffffffffffffff166102af565b6102076103e53660046134bd565b610c32565b610207610da1565b6102076104003660046133ac565b610e9e565b61021c6104133660046132eb565b610eed565b60005473ffffffffffffffffffffffffffffffffffffffff166102af565b610449610444366004613542565b610f04565b604051610228919061357d565b6103a4600081565b61046661124c565b60405161022891906135dd565b6104866104813660046132eb565b61125d565b604051610228919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102af565b61024461050e3660046132eb565b611332565b6102076105213660046133ac565b61135d565b61052e611431565b6040516102289190613637565b6104866105493660046132eb565b6114e9565b61020761055c3660046137c2565b6115bb565b61020761056f366004613809565b611644565b7f00000000000000000000000000000000000000000000000000000000000000006102af565b61060e6105a83660046132eb565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600982529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610228565b7f000000000000000000000000000000000000000000000000000000000000000061021c565b61020761066c3660046133ac565b611aca565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6106a0611ade565b60005b818110156107f75760008383838181106106bf576106bf61384b565b9050608002018036038101906106d5919061388e565b805190915015806106f25750604081015167ffffffffffffffff16155b1561076157604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600990925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169190931617929092179055016106a3565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee568282604051610829929190613908565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806108c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061091457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906109459061398f565b80601f01602080910402602001604051908101604052809291908181526020018280546109719061398f565b80156109be5780601f10610993576101008083540402835291602001916109be565b820191906000526020600020905b8154815290600101906020018083116109a157829003601f168201915b50505050509050919050565b6040805160208101909152600081526109ea6109e583613a8d565b611b61565b60006109f960c0840184613b82565b810190610a069190613be7565b90506000610a1760e0850185613b82565b810190610a249190613c26565b9050610a34816000015183611d92565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aab92600401613cb7565b6020604051808303816000875af1158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190613cdc565b610b24576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3460608501604086016133ac565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610b9691815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b610bbf611ade565b610c2c84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f4392505050565b50505050565b610c3a611ade565b610c4383610eed565b610c85576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b67ffffffffffffffff831660009081526007602052604081206004018054610cac9061398f565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd89061398f565b8015610d255780601f10610cfa57610100808354040283529160200191610d25565b820191906000526020600020905b815481529060010190602001808311610d0857829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610d54838583613d41565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d9393929190613ea5565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610758565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ea6611ade565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610914600567ffffffffffffffff84166120f9565b6040805180820190915260608082526020820152610f29610f2483613ed5565b612114565b6000600981610f3e60408601602087016132eb565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff161515908201819052909150610fe557610fa660408401602085016132eb565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b610fef8380613b82565b9050602014611036576110028380613b82565b6040517fa3c8cf09000000000000000000000000000000000000000000000000000000008152600401610758929190613f79565b60006110428480613b82565b81019061104f9190613f8d565b602083015183516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060880135600482015263ffffffff90921660248301526044820183905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063f856ddb69060a4016020604051808303816000875af1158015611130573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111549190613fa6565b6040516060870135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260405180604001604052806111b187602001602081019061050e91906132eb565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905295945050505050565b606061125860026122de565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610914906122eb565b67ffffffffffffffff811660009081526007602052604090206005018054606091906109459061398f565b611365611ade565b73ffffffffffffffffffffffffffffffffffffffff81166113b2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610829565b6060600061143f60056122de565b90506000815167ffffffffffffffff81111561145d5761145d613679565b604051908082528060200260200182016040528015611486578160200160208202803683370190505b50905060005b82518110156114e2578281815181106114a7576114a761384b565b60200260200101518282815181106114c1576114c161384b565b67ffffffffffffffff9092166020928302919091019091015260010161148c565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610914906122eb565b60085473ffffffffffffffffffffffffffffffffffffffff1633148015906115fb575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611634576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b61163f83838361239d565b505050565b61164c611ade565b60005b8181101561163f57600083838381811061166b5761166b61384b565b905060200281019061167d9190613fc3565b61168690614001565b905061169b8160800151826020015115612487565b6116ae8160a00151826020015115612487565b8060200151156119aa5780516116d09060059067ffffffffffffffff166125c0565b6117155780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b604081015151158061172a5750606081015151155b15611761576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061194290826140b5565b506060820151600582019061195790826140b5565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061199d94939291906141cf565b60405180910390a1611ac1565b80516119c29060059067ffffffffffffffff166125cc565b611a075780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611a7060048301826131c0565b611a7e6005830160006131c0565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161164f565b611ad2611ade565b611adb816125d8565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610758565b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611bf65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc89190613cdc565b15611cff576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d0c81602001516126cd565b6000611d1b826020015161091a565b9050805160001480611d3f575080805190602001208260a001518051906020012014155b15611d7c578160a001516040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610758919061336c565b611d8e826020015183606001516127f3565b5050565b600482015163ffffffff811615611ddd576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610758565b6008830151600c8401516014850151602085015163ffffffff808516911614611e485760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff91821660048201529084166024820152604401610758565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611edd576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015283166024820152604401610758565b845167ffffffffffffffff828116911614611f3b5784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821660048201529082166024820152604401610758565b505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611f9a576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612030576000838281518110611fba57611fba61384b565b60200260200101519050611fd881600261283a90919063ffffffff16565b156120275760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f9d565b5060005b815181101561163f5760008282815181106120515761205161384b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361209557506120f1565b6120a060028261285c565b156120ef5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612034565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121a95760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227b9190613cdc565b156122b2576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122bf816040015161287e565b6122cc81602001516128fd565b611adb81602001518260600151612a4b565b6060600061210d83612a8f565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261237982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261235d9190614297565b85608001516fffffffffffffffffffffffffffffffff16612aea565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6123a683610eed565b6123e8576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b6123f3826000612487565b67ffffffffffffffff831660009081526007602052604090206124169083612b14565b612421816000612487565b67ffffffffffffffff831660009081526007602052604090206124479060020182612b14565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161247a939291906142aa565b60405180910390a1505050565b81511561254e5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806124dd575060408201516fffffffffffffffffffffffffffffffff16155b1561251657816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610758919061432d565b8015611d8e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612587575060208201516fffffffffffffffffffffffffffffffff1615155b15611d8e57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610758919061432d565b600061210d8383612cb6565b600061210d8383612d05565b3373ffffffffffffffffffffffffffffffffffffffff821603612657576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610758565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6126d681610eed565b612718576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612797573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127bb9190613cdc565b611adb576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d8e90600201827f0000000000000000000000000000000000000000000000000000000000000000612df8565b600061210d8373ffffffffffffffffffffffffffffffffffffffff8416612d05565b600061210d8373ffffffffffffffffffffffffffffffffffffffff8416612cb6565b7f000000000000000000000000000000000000000000000000000000000000000015611adb576128af60028261317b565b611adb576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610758565b61290681610eed565b612948576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156129c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e59190614369565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611adb576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d8e90827f0000000000000000000000000000000000000000000000000000000000000000612df8565b6060816000018054806020026020016040519081016040528092919081815260200182805480156109be57602002820191906000526020600020905b815481526020019060010190808311612acb5750505050509050919050565b6000612b0985612afa8486614386565b612b04908761439d565b6131aa565b90505b949350505050565b8154600090612b3d90700100000000000000000000000000000000900463ffffffff1642614297565b90508015612bdf5760018301548354612b85916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612aea565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c05916fffffffffffffffffffffffffffffffff90811691166131aa565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061247a90849061432d565b6000818152600183016020526040812054612cfd57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610914565b506000610914565b60008181526001830160205260408120548015612dee576000612d29600183614297565b8554909150600090612d3d90600190614297565b9050808214612da2576000866000018281548110612d5d57612d5d61384b565b9060005260206000200154905080876000018481548110612d8057612d8061384b565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612db357612db36143b0565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610914565b6000915050610914565b825474010000000000000000000000000000000000000000900460ff161580612e1f575081155b15612e2957505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612e6f90700100000000000000000000000000000000900463ffffffff1642614297565b90508015612f2f5781831115612eb1576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612eeb9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612aea565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612fe65773ffffffffffffffffffffffffffffffffffffffff8416612f8e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610758565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610758565b848310156130f95760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061302a9082614297565b613034878a614297565b61303e919061439d565b61304891906143df565b905073ffffffffffffffffffffffffffffffffffffffff86166130a1576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610758565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610758565b6131038584614297565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561210d565b60008183106131b9578161210d565b5090919050565b5080546131cc9061398f565b6000825580601f106131dc575050565b601f016020900490600052602060002090810190611adb91905b8082111561320a57600081556001016131f6565b5090565b6000806020838503121561322157600080fd5b823567ffffffffffffffff8082111561323957600080fd5b818501915085601f83011261324d57600080fd5b81358181111561325c57600080fd5b8660208260071b850101111561327157600080fd5b60209290920196919550909350505050565b60006020828403121561329557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461210d57600080fd5b67ffffffffffffffff81168114611adb57600080fd5b80356132e6816132c5565b919050565b6000602082840312156132fd57600080fd5b813561210d816132c5565b6000815180845260005b8181101561332e57602081850181015186830182015201613312565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061210d6020830184613308565b73ffffffffffffffffffffffffffffffffffffffff81168114611adb57600080fd5b80356132e68161337f565b6000602082840312156133be57600080fd5b813561210d8161337f565b6000602082840312156133db57600080fd5b813567ffffffffffffffff8111156133f257600080fd5b8201610100818503121561210d57600080fd5b60008083601f84011261341757600080fd5b50813567ffffffffffffffff81111561342f57600080fd5b6020830191508360208260051b850101111561344a57600080fd5b9250929050565b6000806000806040858703121561346757600080fd5b843567ffffffffffffffff8082111561347f57600080fd5b61348b88838901613405565b909650945060208701359150808211156134a457600080fd5b506134b187828801613405565b95989497509550505050565b6000806000604084860312156134d257600080fd5b83356134dd816132c5565b9250602084013567ffffffffffffffff808211156134fa57600080fd5b818601915086601f83011261350e57600080fd5b81358181111561351d57600080fd5b87602082850101111561352f57600080fd5b6020830194508093505050509250925092565b60006020828403121561355457600080fd5b813567ffffffffffffffff81111561356b57600080fd5b820160a0818503121561210d57600080fd5b6020815260008251604060208401526135996060840182613308565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526135d48282613308565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561362b57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016135f9565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561362b57835167ffffffffffffffff1683529284019291840191600101613653565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156136cc576136cc613679565b60405290565b6040805190810167ffffffffffffffff811182821017156136cc576136cc613679565b60405160c0810167ffffffffffffffff811182821017156136cc576136cc613679565b8015158114611adb57600080fd5b80356132e681613718565b80356fffffffffffffffffffffffffffffffff811681146132e657600080fd5b60006060828403121561376357600080fd5b6040516060810181811067ffffffffffffffff8211171561378657613786613679565b604052905080823561379781613718565b81526137a560208401613731565b60208201526137b660408401613731565b60408201525092915050565b600080600060e084860312156137d757600080fd5b83356137e2816132c5565b92506137f18560208601613751565b91506138008560808601613751565b90509250925092565b6000806020838503121561381c57600080fd5b823567ffffffffffffffff81111561383357600080fd5b61383f85828601613405565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff811681146132e657600080fd5b6000608082840312156138a057600080fd5b6040516080810181811067ffffffffffffffff821117156138c3576138c3613679565b604052823581526138d66020840161387a565b602082015260408301356138e9816132c5565b604082015260608301356138fc81613718565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613982578135835263ffffffff61393a86840161387a565b16858401528382013561394c816132c5565b67ffffffffffffffff168385015260608281013561396981613718565b151590840152608092830192919091019060010161391e565b5090979650505050505050565b600181811c908216806139a357607f821691505b6020821081036139dc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f8301126139f357600080fd5b813567ffffffffffffffff80821115613a0e57613a0e613679565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613a5457613a54613679565b81604052838152866020858801011115613a6d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613aa057600080fd5b613aa86136a8565b823567ffffffffffffffff80821115613ac057600080fd5b613acc368387016139e2565b8352613ada602086016132db565b6020840152613aeb604086016133a1565b604084015260608501356060840152613b06608086016133a1565b608084015260a0850135915080821115613b1f57600080fd5b613b2b368387016139e2565b60a084015260c0850135915080821115613b4457600080fd5b613b50368387016139e2565b60c084015260e0850135915080821115613b6957600080fd5b50613b76368286016139e2565b60e08301525092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613bb757600080fd5b83018035915067ffffffffffffffff821115613bd257600080fd5b60200191503681900382131561344a57600080fd5b600060408284031215613bf957600080fd5b613c016136d2565b8235613c0c816132c5565b8152613c1a6020840161387a565b60208201529392505050565b600060208284031215613c3857600080fd5b813567ffffffffffffffff80821115613c5057600080fd5b9083019060408286031215613c6457600080fd5b613c6c6136d2565b823582811115613c7b57600080fd5b613c87878286016139e2565b825250602083013582811115613c9c57600080fd5b613ca8878286016139e2565b60208301525095945050505050565b604081526000613cca6040830185613308565b82810360208401526135d48185613308565b600060208284031215613cee57600080fd5b815161210d81613718565b601f82111561163f576000816000526020600020601f850160051c81016020861015613d225750805b601f850160051c820191505b81811015611f3b57828155600101613d2e565b67ffffffffffffffff831115613d5957613d59613679565b613d6d83613d67835461398f565b83613cf9565b6000601f841160018114613dbf5760008515613d895750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613e55565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613e0e5786850135825560209485019460019092019101613dee565b5086821015613e49577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000613eb86040830186613308565b8281036020840152613ecb818587613e5c565b9695505050505050565b600060a08236031215613ee757600080fd5b60405160a0810167ffffffffffffffff8282108183111715613f0b57613f0b613679565b816040528435915080821115613f2057600080fd5b50613f2d368286016139e2565b8252506020830135613f3e816132c5565b60208201526040830135613f518161337f565b6040820152606083810135908201526080830135613f6e8161337f565b608082015292915050565b602081526000612b0c602083018486613e5c565b600060208284031215613f9f57600080fd5b5035919050565b600060208284031215613fb857600080fd5b815161210d816132c5565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ff757600080fd5b9190910192915050565b6000610140823603121561401457600080fd5b61401c6136f5565b614025836132db565b815261403360208401613726565b6020820152604083013567ffffffffffffffff8082111561405357600080fd5b61405f368387016139e2565b6040840152606085013591508082111561407857600080fd5b50614085368286016139e2565b6060830152506140983660808501613751565b60808201526140aa3660e08501613751565b60a082015292915050565b815167ffffffffffffffff8111156140cf576140cf613679565b6140e3816140dd845461398f565b84613cf9565b602080601f83116001811461413657600084156141005750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611f3b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561418357888601518255948401946001909101908401614164565b50858210156141bf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526141f381840187613308565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506142319050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526135d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561091457610914614268565b67ffffffffffffffff8416815260e081016142f660208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612b0c565b6060810161091482848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561437b57600080fd5b815161210d8161337f565b808202811582820484141761091457610914614268565b8082018082111561091457610914614268565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614415577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var USDCTokenPoolABI = USDCTokenPoolMetaData.ABI diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 73120459b3..6bfad5acd7 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,21 +1,21 @@ GETH_VERSION: 1.13.8 -arm_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 763c7d81e782d7c286d4a5892aeebe71984a1f999a50a051c87f5b8f9c70cc26 +arm_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 8b45b0fb08631c6b582fd3c0b4052a79cc2b4e091e6286af1ab131bef63661f9 arm_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 -burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 4bf274f1e24e5cf777c8a49fa878c01d79108927950da9924427056406eb9f98 -burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 6477fba49883ae781b2bea29076e4c391fca8d69e42b91b46d908dec5e6e471e -burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 61bccb6b9bc14ef7f1fe536cec0934799ec4e1b61eb0c32427fdfea509ab8b8e -burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin bdde20554414ad4f1b097c42bf8d06502a44cedadcd0387e4a39628f67e587c5 -ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 970bf6a2a817813eb3302c92ec3ad0bc0fc6c2e693f33c13f57733d003f44d0d +burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 1e60c28ad796a220a38043b369dec8d9bffe23e1c7d9895760e30672872afd06 +burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 3e8e3358f0bb520af069a7d37ea625940a88461a54418b1d5925eabced8c74df +burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 524c72699d2666cf3b3effecfe67441854f62f153baef209258c9a5562680fca +burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6333d0314d0bd29e75ea5e05fe62a4516ade0c6db91c30b6f93645035db52ed8 +ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin a92a9ae55b235f47ac58af942e43a20dc7df31cfba9178c133e5b3e273816503 ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin fcced2263564f51b5bf086c221e813ec06a71d2bb2e246b4e28cd60098a6de6f commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin 274d87db70b643e00ab0a7e7845bb4b791f3b613bfc87708d33fc5a8369e2a41 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin f7128dcc2ee6dbcbc976288abcc16970ffb19b59412c5202ef6b259d2007f801 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de -evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 9bf9e62a4d2a80f46afc230ea1528add66b6ad4168a0ebd3346972f9c2c9def3 +evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin b913487363418c368ca412c4cc4a3b1e411395b3c6b8b982b1c48cdab5c7b10c evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 15cd5695049ab4be1f396ec1d7b609738b2bcefa3740a7a48316e1f72506a34a -evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin c7e633eb58fdabea223c3a334ba02934f9007a01e12d29a5204ce18f580e019d -evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 40cdc5bcb0ef78fdb539778f0b1bea9bf96126256c779fe68c29e46cee40f20e -lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin ed29f2cde7f4470fbc66ab9d4f94bd0b4ed769448ed63d3a4daac79d8ebe7ad5 -lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin fe36bb2efdceffdd7274d055ed88e57c5ad5d5626fdb2ccce45a99da10399b92 +evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin b0d77babbe635cd6ba04c2af049badc9e9d28a4b6ed6bb75f830ad902a618beb +evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 5c02c2b167946b3467636ff2bb58594cb4652fc63d8bdfee2488ed562e2a3e50 +lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin e6a8ec9e8faccb1da7d90e0f702ed72975964f97dc3222b54cfcca0a0ba3fea2 +lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin 9afb4cf8621b5e60ac70c1b95fcc28d735119bdbc8c702bc9931d30e712e29f3 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin 1d5146d43e1b99cd2d6f9f06475be19087e4349f7cee0fdbbf134ba65e967c93 mock_arm_contract: ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.abi ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.bin e7a3a6c3eda5fb882e16bcc2b4340f78523acb67907bcdcaf3c8ffc51488688e @@ -27,12 +27,12 @@ multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Help nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 6f64e1083b356c06ee66b9138e398b9c97a4cd3e8c9ec38cf3010cebc79af536 ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 1588313bb5e781d181a825247d30828f59007700f36b4b9b00391592b06ff4b4 -price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 7320907b45fe2bdc3a06f5891dd34b8ab270823a652fec15676ec8a898764273 +price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 8f4bdaa4d8239429ae4e047ab06d445bad42234a05bb7c99ba6141bd811e1722 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 75be86323c227917a9bbc3f799d7ed02f92db546653a36db30ed0ebe64461353 report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin c07af8433bf8dbc7981725b18922a9c4e2dea068dd204bc62adc0e926cb499c3 -router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 42576577e81beea9a069bd9229caaa9a71227fbaef3871a1a2e69fd218216290 +router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 2e4f0a7826c8abb49d882bb49fc5ff20a186dbd3137624b9097ffed903ae4888 self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 86e169636e5633854ed0b709c804066b615040bceba25aa5137450fbe6f76fa3 -token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 479ad5c02997f48f7029b937b1b3e053f731d8db44ecc45441cf7f37111a0c35 +token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 942be7d1681ac102e0615bee13f76838ebb0b261697cf1270d2bf82c12e57aeb token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 7c01fd89f5153baa4d7409d14beabb3f861abfbf8880d3c6d06802cc398570f9 -usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin 230d8f375087b236cf60a9cc7b8601f944586e9c1893514a64803a8d98727507 +usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin 8e7eae4c7277ce4a0092cca815c046cc49094028c23d2d113de9335fa4358030 weth9: ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin 2970d79a0ca6dd6279cde130de45e56c8790ed695eae477fb5ba4c1bb75b720d From b714905f58fdcedb7df9fdd389330e5480a5ec67 Mon Sep 17 00:00:00 2001 From: kanth <70688600+defistar@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:10:10 +0530 Subject: [PATCH 204/432] feat: rateLimiterConfig mapping of localToRemoteTokens to take bytes instead of bytes32 (#1207) rateLimiterConfig mapping of localToRemoteTokens to take bytes instead of bytes32 - In the MultiAggregateRateLimiter contract, the the following mapping might be simplifiable to - (uint64 remoteChainSelector -> address token) , - since it is only used as an isEnabled check (i.e. the (address token -> bytes32 remoteToken) is never used on-chain) - mapping being necessary off-chain, we need to convert the (address -> bytes32) mapping to (address -> bytes) to be consistent with using bytes for all family-agnostic addresses ```js mapping(uint64 remoteChainSelector => EnumerableMapAddresses.AddressToBytes32Map tokensLocalToRemote) internal s_rateLimitedTokensLocalToRemote; ``` this has to been changed to ```js mapping(uint64 remoteChainSelector => EnumerableMapAddresses.AddressToBytesMap tokensLocalToRemote) internal s_rateLimitedTokensLocalToRemote; ``` 1. New solidity library `EnumerableMapBytes32` which contains `Bytes32ToBytes` Mapping and enumerate it 2. `EnumerableMapAddresses.sol` library has added support for the new library cherrypicked from chainlink repo `EnumerableMapBytes32` 3. `MultiAggregateRateLimiter` with mapping for remoteSelector -> localTokenAddress -> remoteTokenAddress is updated to contain remoteTokenAddress as `bytes` instead of `bytes32` --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/gas-snapshots/ccip.gas-snapshot | 40 +++++++++--------- contracts/gas-snapshots/shared.gas-snapshot | 24 +++++------ .../v0.8/ccip/MultiAggregateRateLimiter.sol | 18 ++++---- .../MultiAggregateRateLimiter.t.sol | 41 +++++++++---------- .../multi_aggregate_rate_limiter.go | 14 +++---- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 6 files changed, 68 insertions(+), 71 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index e700bd984d..75116d10fc 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -545,42 +545,42 @@ MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_UpdateExistingConfi MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_UpdateExistingConfig_Success() (gas: 53092) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_ZeroChainSelector_Revert() (gas: 17019) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_ZeroConfigs_Success() (gas: 12295) -MultiAggregateRateLimiter_constructor:test_ConstructorNoAuthorizedCallers_Success() (gas: 2006714) -MultiAggregateRateLimiter_constructor:test_Constructor_Success() (gas: 2122927) +MultiAggregateRateLimiter_constructor:test_ConstructorNoAuthorizedCallers_Success() (gas: 2149637) +MultiAggregateRateLimiter_constructor:test_Constructor_Success() (gas: 2265894) MultiAggregateRateLimiter_getTokenBucket:test_GetTokenBucket_Success() (gas: 30248) MultiAggregateRateLimiter_getTokenBucket:test_Refill_Success() (gas: 47358) MultiAggregateRateLimiter_getTokenBucket:test_TimeUnderflow_Revert() (gas: 15821) -MultiAggregateRateLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19690) -MultiAggregateRateLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21275) +MultiAggregateRateLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19712) +MultiAggregateRateLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21297) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 14527) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 189472) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 59949) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213744) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 60487) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 17593) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitDisabled_Success() (gas: 44895) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExceeded_Revert() (gas: 50598) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78780) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 263532) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 312061) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54784) MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 9223372036854754743) MultiAggregateRateLimiter_onOutboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 19104) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 15778) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 189460) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 61684) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213732) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 62222) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitDisabled_Success() (gas: 46683) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitExceeded_Revert() (gas: 52371) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitReset_Success() (gas: 79845) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 263746) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 312275) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokens_Success() (gas: 56541) -MultiAggregateRateLimiter_setPriceRegistry:test_OnlyOwner_Revert() (gas: 11358) -MultiAggregateRateLimiter_setPriceRegistry:test_Owner_Success() (gas: 19146) -MultiAggregateRateLimiter_setPriceRegistry:test_ZeroAddress_Revert() (gas: 10630) -MultiAggregateRateLimiter_updateRateLimitTokens:test_NonOwner_Revert() (gas: 16107) -MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensMultipleChains_Success() (gas: 225533) -MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensSingleChain_Success() (gas: 200148) -MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_AddsAndRemoves_Success() (gas: 162036) -MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_RemoveNonExistentToken_Success() (gas: 28465) -MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroDestToken_Revert() (gas: 17452) -MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroSourceToken_Revert() (gas: 17507) +MultiAggregateRateLimiter_setPriceRegistry:test_OnlyOwner_Revert() (gas: 11292) +MultiAggregateRateLimiter_setPriceRegistry:test_Owner_Success() (gas: 19080) +MultiAggregateRateLimiter_setPriceRegistry:test_ZeroAddress_Revert() (gas: 10564) +MultiAggregateRateLimiter_updateRateLimitTokens:test_NonOwner_Revert() (gas: 18872) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensMultipleChains_Success() (gas: 279906) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensSingleChain_Success() (gas: 254501) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_AddsAndRemoves_Success() (gas: 204488) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_RemoveNonExistentToken_Success() (gas: 28681) +MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroDestToken_Revert() (gas: 18309) +MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroSourceToken_Revert() (gas: 18238) MultiOCR3Base_setOCR3Configs:test_FMustBePositive_Revert() (gas: 59331) MultiOCR3Base_setOCR3Configs:test_FTooHigh_Revert() (gas: 44298) MultiOCR3Base_setOCR3Configs:test_RepeatSignerAddress_Revert() (gas: 283711) diff --git a/contracts/gas-snapshots/shared.gas-snapshot b/contracts/gas-snapshots/shared.gas-snapshot index d7a4e21978..c194511ca6 100644 --- a/contracts/gas-snapshots/shared.gas-snapshot +++ b/contracts/gas-snapshots/shared.gas-snapshot @@ -39,41 +39,41 @@ CallWithExactGas__callWithExactGas:test_CallWithExactGasSafeReturnDataExactGas() CallWithExactGas__callWithExactGas:test_NoContractReverts() (gas: 11559) CallWithExactGas__callWithExactGas:test_NoGasForCallExactCheckReverts() (gas: 15788) CallWithExactGas__callWithExactGas:test_NotEnoughGasForCallReverts() (gas: 16241) -CallWithExactGas__callWithExactGas:test_callWithExactGasSuccess(bytes,bytes4) (runs: 257, μ: 15766, ~: 15719) +CallWithExactGas__callWithExactGas:test_callWithExactGasSuccess(bytes,bytes4) (runs: 256, μ: 15812, ~: 15752) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractExactGasSuccess() (gas: 20116) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractReceiverErrorSuccess() (gas: 67721) -CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractSuccess(bytes,bytes4) (runs: 257, μ: 16276, ~: 16229) +CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractSuccess(bytes,bytes4) (runs: 256, μ: 16321, ~: 16262) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoContractSuccess() (gas: 12962) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoGasForCallExactCheckReturnFalseSuccess() (gas: 13005) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NotEnoughGasForCallReturnsFalseSuccess() (gas: 13317) CallWithExactGas__callWithExactGasSafeReturnData:test_CallWithExactGasSafeReturnDataExactGas() (gas: 20331) CallWithExactGas__callWithExactGasSafeReturnData:test_NoContractReverts() (gas: 13917) CallWithExactGas__callWithExactGasSafeReturnData:test_NoGasForCallExactCheckReverts() (gas: 16139) -CallWithExactGas__callWithExactGasSafeReturnData:test_NotEnoughGasForCallReverts() (gas: 16569) -CallWithExactGas__callWithExactGasSafeReturnData:test_callWithExactGasSafeReturnData_ThrowOOGError_Revert() (gas: 36708) +CallWithExactGas__callWithExactGasSafeReturnData:test_NotEnoughGasForCallReverts() (gas: 16547) +CallWithExactGas__callWithExactGasSafeReturnData:test_callWithExactGasSafeReturnData_ThrowOOGError_Revert() (gas: 36752) EnumerableMapAddresses_at:testAtSuccess() (gas: 95086) EnumerableMapAddresses_at:testBytes32AtSuccess() (gas: 94877) -EnumerableMapAddresses_at:testBytesAtSuccess() (gas: 96564) EnumerableMapAddresses_contains:testBytes32ContainsSuccess() (gas: 93518) -EnumerableMapAddresses_contains:testBytesContainsSuccess() (gas: 94012) EnumerableMapAddresses_contains:testContainsSuccess() (gas: 93696) EnumerableMapAddresses_get:testBytes32GetSuccess() (gas: 94278) -EnumerableMapAddresses_get:testBytesGetSuccess() (gas: 95879) EnumerableMapAddresses_get:testGetSuccess() (gas: 94453) -EnumerableMapAddresses_get_errorMessage:testBytesGetErrorMessageSuccess() (gas: 95878) EnumerableMapAddresses_get_errorMessage:testGetErrorMessageSuccess() (gas: 94489) EnumerableMapAddresses_length:testBytes32LengthSuccess() (gas: 72445) -EnumerableMapAddresses_length:testBytesLengthSuccess() (gas: 73011) EnumerableMapAddresses_length:testLengthSuccess() (gas: 72640) EnumerableMapAddresses_remove:testBytes32RemoveSuccess() (gas: 73462) -EnumerableMapAddresses_remove:testBytesRemoveSuccess() (gas: 74249) EnumerableMapAddresses_remove:testRemoveSuccess() (gas: 73686) EnumerableMapAddresses_set:testBytes32SetSuccess() (gas: 94496) -EnumerableMapAddresses_set:testBytesSetSuccess() (gas: 95428) EnumerableMapAddresses_set:testSetSuccess() (gas: 94685) EnumerableMapAddresses_tryGet:testBytes32TryGetSuccess() (gas: 94622) -EnumerableMapAddresses_tryGet:testBytesTryGetSuccess() (gas: 96279) EnumerableMapAddresses_tryGet:testTryGetSuccess() (gas: 94893) +EnumerableMapAddresses_at:testBytesAtSuccess() (gas: 96564) +EnumerableMapAddresses_contains:testBytesContainsSuccess() (gas: 94012) +EnumerableMapAddresses_get:testBytesGetSuccess() (gas: 95879) +EnumerableMapAddresses_get_errorMessage:testBytesGetErrorMessageSuccess() (gas: 95878) +EnumerableMapAddresses_length:testBytesLengthSuccess() (gas: 73011) +EnumerableMapAddresses_remove:testBytesRemoveSuccess() (gas: 74249) +EnumerableMapAddresses_set:testBytesSetSuccess() (gas: 95428) +EnumerableMapAddresses_tryGet:testBytesTryGetSuccess() (gas: 96279) OpStackBurnMintERC677_constructor:testConstructorSuccess() (gas: 1743649) OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 298649) OpStackBurnMintERC677_interfaceCompatibility:testMintCompatibility() (gas: 137957) diff --git a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol index f86bbed2c0..33dee29b12 100644 --- a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol +++ b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol @@ -19,14 +19,14 @@ import {USDPriceWith18Decimals} from "./libraries/USDPriceWith18Decimals.sol"; contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, ITypeAndVersion { using RateLimiter for RateLimiter.TokenBucket; using USDPriceWith18Decimals for uint224; - using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytes32Map; + using EnumerableMapAddresses for EnumerableMapAddresses.AddressToBytesMap; error PriceNotFoundForToken(address token); error ZeroChainSelectorNotAllowed(); event RateLimiterConfigUpdated(uint64 indexed remoteChainSelector, bool isOutboundLane, RateLimiter.Config config); event PriceRegistrySet(address newPriceRegistry); - event TokenAggregateRateLimitAdded(uint64 remoteChainSelector, bytes32 remoteToken, address localToken); + event TokenAggregateRateLimitAdded(uint64 remoteChainSelector, bytes remoteToken, address localToken); event TokenAggregateRateLimitRemoved(uint64 remoteChainSelector, address localToken); /// @notice RemoteRateLimitToken struct containing the local token address with the chain selector @@ -39,7 +39,7 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT /// @notice RateLimitToken struct containing both the local and remote token addresses struct RateLimitTokenArgs { LocalRateLimitToken localTokenArgs; // Local token update args scoped to one remote chain - bytes32 remoteToken; // Token on the remote chain (for OnRamp - dest, of OffRamp - source) + bytes remoteToken; // Token on the remote chain (for OnRamp - dest, of OffRamp - source) } /// @notice Update args for a single rate limiter config update @@ -59,7 +59,7 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT /// @dev Tokens that should be included in Aggregate Rate Limiting (from local chain (this chain) -> remote), /// grouped per-remote chain. - mapping(uint64 remoteChainSelector => EnumerableMapAddresses.AddressToBytes32Map tokensLocalToRemote) internal + mapping(uint64 remoteChainSelector => EnumerableMapAddresses.AddressToBytesMap tokensLocalToRemote) internal s_rateLimitedTokensLocalToRemote; /// @notice The address of the PriceRegistry used to query token values for ratelimiting @@ -198,15 +198,15 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT function getAllRateLimitTokens(uint64 remoteChainSelector) external view - returns (address[] memory localTokens, bytes32[] memory remoteTokens) + returns (address[] memory localTokens, bytes[] memory remoteTokens) { uint256 tokenCount = s_rateLimitedTokensLocalToRemote[remoteChainSelector].length(); localTokens = new address[](tokenCount); - remoteTokens = new bytes32[](tokenCount); + remoteTokens = new bytes[](tokenCount); for (uint256 i = 0; i < tokenCount; ++i) { - (address localToken, bytes32 remoteToken) = s_rateLimitedTokensLocalToRemote[remoteChainSelector].at(i); + (address localToken, bytes memory remoteToken) = s_rateLimitedTokensLocalToRemote[remoteChainSelector].at(i); localTokens[i] = localToken; remoteTokens[i] = remoteToken; } @@ -231,10 +231,10 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT for (uint256 i = 0; i < adds.length; ++i) { LocalRateLimitToken memory localTokenArgs = adds[i].localTokenArgs; - bytes32 remoteToken = adds[i].remoteToken; + bytes memory remoteToken = adds[i].remoteToken; address localToken = localTokenArgs.localToken; - if (localToken == address(0) || remoteToken == bytes32("")) { + if (localToken == address(0) || remoteToken.length == 0) { revert ZeroAddressNotAllowed(); } diff --git a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol index dd1698288b..e30ce02212 100644 --- a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol +++ b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol @@ -483,14 +483,14 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi remoteChainSelector: CHAIN_SELECTOR_1, localToken: s_destTokens[0] }), - remoteToken: bytes32(bytes20(s_sourceTokens[0])) + remoteToken: abi.encode(s_sourceTokens[0]) }); adds[1] = MultiAggregateRateLimiter.RateLimitTokenArgs({ localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ remoteChainSelector: CHAIN_SELECTOR_1, localToken: s_destTokens[1] }), - remoteToken: bytes32(bytes20(s_sourceTokens[1])) + remoteToken: abi.encode(s_sourceTokens[1]) }); for (uint256 i = 0; i < adds.length; ++i) { @@ -502,8 +502,7 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), adds); - (address[] memory localTokens, bytes32[] memory remoteTokens) = - s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_1); + (address[] memory localTokens, bytes[] memory remoteTokens) = s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_1); assertEq(localTokens.length, adds.length); assertEq(localTokens.length, remoteTokens.length); @@ -521,14 +520,14 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi remoteChainSelector: CHAIN_SELECTOR_1, localToken: s_destTokens[0] }), - remoteToken: bytes32(bytes20(s_sourceTokens[0])) + remoteToken: abi.encode(s_sourceTokens[0]) }); adds[1] = MultiAggregateRateLimiter.RateLimitTokenArgs({ localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ remoteChainSelector: CHAIN_SELECTOR_2, localToken: s_destTokens[1] }), - remoteToken: bytes32(bytes20(s_sourceTokens[1])) + remoteToken: abi.encode(s_sourceTokens[1]) }); for (uint256 i = 0; i < adds.length; ++i) { @@ -540,7 +539,7 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), adds); - (address[] memory localTokensChain1, bytes32[] memory remoteTokensChain1) = + (address[] memory localTokensChain1, bytes[] memory remoteTokensChain1) = s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_1); assertEq(localTokensChain1.length, 1); @@ -548,7 +547,7 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi assertEq(localTokensChain1[0], adds[0].localTokenArgs.localToken); assertEq(remoteTokensChain1[0], adds[0].remoteToken); - (address[] memory localTokensChain2, bytes32[] memory remoteTokensChain2) = + (address[] memory localTokensChain2, bytes[] memory remoteTokensChain2) = s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_2); assertEq(localTokensChain2.length, 1); @@ -564,14 +563,14 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi remoteChainSelector: CHAIN_SELECTOR_1, localToken: s_destTokens[0] }), - remoteToken: bytes32(bytes20(s_sourceTokens[0])) + remoteToken: abi.encode(s_sourceTokens[0]) }); adds[1] = MultiAggregateRateLimiter.RateLimitTokenArgs({ localTokenArgs: MultiAggregateRateLimiter.LocalRateLimitToken({ remoteChainSelector: CHAIN_SELECTOR_1, localToken: s_destTokens[1] }), - remoteToken: bytes32(bytes20(s_sourceTokens[1])) + remoteToken: abi.encode(s_sourceTokens[1]) }); MultiAggregateRateLimiter.LocalRateLimitToken[] memory removes = @@ -594,8 +593,7 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi s_rateLimiter.updateRateLimitTokens(removes, new MultiAggregateRateLimiter.RateLimitTokenArgs[](0)); - (address[] memory localTokens, bytes32[] memory remoteTokens) = - s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_1); + (address[] memory localTokens, bytes[] memory remoteTokens) = s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_1); assertEq(1, remoteTokens.length); assertEq(adds[1].remoteToken, remoteTokens[0]); @@ -621,8 +619,7 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi Vm.Log[] memory logEntries = vm.getRecordedLogs(); assertEq(logEntries.length, 0); - (address[] memory localTokens, bytes32[] memory remoteTokens) = - s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_1); + (address[] memory localTokens, bytes[] memory remoteTokens) = s_rateLimiter.getAllRateLimitTokens(CHAIN_SELECTOR_1); assertEq(localTokens.length, 0); assertEq(localTokens.length, remoteTokens.length); @@ -637,7 +634,7 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi remoteChainSelector: CHAIN_SELECTOR_1, localToken: s_destTokens[0] }), - remoteToken: bytes32(bytes20(address(0))) + remoteToken: new bytes(0) }); vm.expectRevert(AuthorizedCallers.ZeroAddressNotAllowed.selector); @@ -651,7 +648,7 @@ contract MultiAggregateRateLimiter_updateRateLimitTokens is MultiAggregateRateLi remoteChainSelector: CHAIN_SELECTOR_1, localToken: address(0) }), - remoteToken: bytes32(bytes20(s_destTokens[0])) + remoteToken: abi.encode(s_destTokens[0]) }); vm.expectRevert(AuthorizedCallers.ZeroAddressNotAllowed.selector); @@ -682,7 +679,7 @@ contract MultiAggregateRateLimiter_onInboundMessage is MultiAggregateRateLimiter remoteChainSelector: CHAIN_SELECTOR_1, localToken: s_destTokens[i] }), - remoteToken: bytes32(bytes20(s_sourceTokens[i])) + remoteToken: abi.encode(s_sourceTokens[i]) }); Internal.PriceUpdates memory priceUpdates = @@ -772,7 +769,7 @@ contract MultiAggregateRateLimiter_onInboundMessage is MultiAggregateRateLimiter localToken: s_destTokens[i] }), // Create a remote token address that is different from CHAIN_SELECTOR_1 - remoteToken: bytes32(uint256(uint160(s_sourceTokens[i])) + type(uint160).max + 1) + remoteToken: abi.encode(uint256(uint160(s_sourceTokens[i])) + type(uint160).max + 1) }); } s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); @@ -821,7 +818,7 @@ contract MultiAggregateRateLimiter_onInboundMessage is MultiAggregateRateLimiter localToken: s_destTokens[0] }), // Create a remote token address that is different from CHAIN_SELECTOR_1 - remoteToken: bytes32(uint256(uint160(s_sourceTokens[0])) + type(uint160).max + 1) + remoteToken: abi.encode(uint256(uint160(s_sourceTokens[0])) + type(uint160).max + 1) }); s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); @@ -918,7 +915,7 @@ contract MultiAggregateRateLimiter_onOutboundMessage is MultiAggregateRateLimite remoteChainSelector: CHAIN_SELECTOR_1, localToken: s_sourceTokens[i] }), - remoteToken: bytes32(bytes20(s_destTokenBySourceToken[s_sourceTokens[i]])) + remoteToken: abi.encode(bytes20(s_destTokenBySourceToken[s_sourceTokens[i]])) }); Internal.PriceUpdates memory priceUpdates = @@ -1006,7 +1003,7 @@ contract MultiAggregateRateLimiter_onOutboundMessage is MultiAggregateRateLimite localToken: s_sourceTokens[i] }), // Create a remote token address that is different from CHAIN_SELECTOR_1 - remoteToken: bytes32(uint256(uint160(s_destTokenBySourceToken[s_sourceTokens[i]])) + type(uint160).max + 1) + remoteToken: abi.encode(uint256(uint160(s_destTokenBySourceToken[s_sourceTokens[i]])) + type(uint160).max + 1) }); } s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); @@ -1055,7 +1052,7 @@ contract MultiAggregateRateLimiter_onOutboundMessage is MultiAggregateRateLimite localToken: s_sourceTokens[0] }), // Create a remote token address that is different from CHAIN_SELECTOR_1 - remoteToken: bytes32(uint256(uint160(s_destTokenBySourceToken[s_sourceTokens[0]])) + type(uint160).max + 1) + remoteToken: abi.encode(uint256(uint160(s_destTokenBySourceToken[s_sourceTokens[0]])) + type(uint160).max + 1) }); s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); diff --git a/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go b/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go index 910fbfb76f..d8a34b9483 100644 --- a/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go +++ b/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go @@ -63,7 +63,7 @@ type MultiAggregateRateLimiterLocalRateLimitToken struct { type MultiAggregateRateLimiterRateLimitTokenArgs struct { LocalTokenArgs MultiAggregateRateLimiterLocalRateLimitToken - RemoteToken [32]byte + RemoteToken []byte } type MultiAggregateRateLimiterRateLimiterConfigArgs struct { @@ -87,8 +87,8 @@ type RateLimiterTokenBucket struct { } var MultiAggregateRateLimiterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"PriceRegistrySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"RateLimiterConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"remoteToken\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimiterConfigArgs[]\",\"name\":\"rateLimiterUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applyRateLimiterConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"}],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"localTokens\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"remoteTokens\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onInboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onOutboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"setPriceRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken\",\"name\":\"localTokenArgs\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"remoteToken\",\"type\":\"bytes32\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimitTokenArgs[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b5060405162002efb38038062002efb833981016040819052620000349162000538565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000102565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001ad565b50620000fa82620002fc565b50506200066f565b336001600160a01b038216036200015c5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b81518110156200023d576000828281518110620001d657620001d662000621565b60209081029190910101519050620001f060028262000378565b1562000233576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001b5565b50815160005b8151811015620002f657600082828151811062000264576200026462000621565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002a2576040516342bcdf7f60e11b815260040160405180910390fd5b620002af60028262000398565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000243565b50505050565b6001600160a01b03811662000324576040516342bcdf7f60e11b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b60006200038f836001600160a01b038416620003af565b90505b92915050565b60006200038f836001600160a01b038416620004b3565b60008181526001830160205260408120548015620004a8576000620003d660018362000637565b8554909150600090620003ec9060019062000637565b90508181146200045857600086600001828154811062000410576200041062000621565b906000526020600020015490508087600001848154811062000436576200043662000621565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200046c576200046c62000659565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000392565b600091505062000392565b6000818152600183016020526040812054620004fc5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000392565b50600062000392565b80516001600160a01b03811681146200051d57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200054c57600080fd5b620005578362000505565b602084810151919350906001600160401b03808211156200057757600080fd5b818601915086601f8301126200058c57600080fd5b815181811115620005a157620005a162000522565b8060051b604051601f19603f83011681018181108582111715620005c957620005c962000522565b604052918252848201925083810185019189831115620005e857600080fd5b938501935b828510156200061157620006018562000505565b84529385019392850192620005ed565b8096505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039257634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b61287c806200067f6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379ba50971161008c57806391a2749a1161006657806391a2749a14610252578063e0a0e50614610265578063f2fde38b14610278578063fe843cd01461028b57600080fd5b806379ba5097146102195780637c8b5e9a146102215780638da5cb5b1461023457600080fd5b8063181f5a77116100c8578063181f5a77146101bb5780632451a627146101d0578063508ee9de146101e5578063537e304e146101f857600080fd5b806308d450a1146100ef5780630a35bcc4146101045780630d6c107e1461017c575b600080fd5b6101026100fd366004611f31565b61029e565b005b610117610112366004612011565b6102bd565b604051610173919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60405180910390f35b60055473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b6101c3610382565b6040516101739190612044565b6101d861039e565b6040516101739190612103565b6101026101f3366004612116565b6103af565b61020b610206366004612131565b6103c0565b60405161017392919061214c565b610102610523565b61010261022f36600461226d565b610625565b60005473ffffffffffffffffffffffffffffffffffffffff16610196565b61010261026036600461239e565b610874565b61010261027336600461242f565b610885565b610102610286366004612116565b6108fa565b6101026102993660046124a4565b61090b565b6102a6610c4a565b6102ba816020015182608001516000610c8f565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526103796102f58484610d66565b6040805160a08101825282546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff16151593830193909352600190930154808316606083015292909204166080820152610d96565b90505b92915050565b60405180606001604052806023815260200161284d6023913981565b60606103aa6002610e48565b905090565b6103b7610e5c565b6102ba81610edd565b67ffffffffffffffff8116600090815260046020526040812060609182916103e790610fa3565b90508067ffffffffffffffff81111561040257610402611ca2565b60405190808252806020026020018201604052801561042b578160200160208202803683370190505b5092508067ffffffffffffffff81111561044757610447611ca2565b604051908082528060200260200182016040528015610470578160200160208202803683370190505b50915060005b8181101561051c5767ffffffffffffffff8516600090815260046020526040812081906104a39084610fae565b91509150818684815181106104ba576104ba6125d8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080858481518110610507576105076125d8565b60209081029190910101525050600101610476565b5050915091565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61062d610e5c565b60005b825181101561070b57600083828151811061064d5761064d6125d8565b6020026020010151602001519050600084838151811061066f5761066f6125d8565b6020908102919091018101515167ffffffffffffffff81166000908152600490925260409091209091506106a39083610fcc565b15610701576040805167ffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff841660208201527f530cabd30786b7235e124a6c0db77e0b685ef22813b1fe87554247f404eb8ed6910160405180910390a15b5050600101610630565b5060005b815181101561086f57600082828151811061072c5761072c6125d8565b6020026020010151600001519050600083838151811061074e5761074e6125d8565b6020026020010151602001519050600082602001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061079e575081155b156107d5576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825167ffffffffffffffff811660009081526004602052604090206107fb908385610fee565b15610860576040805167ffffffffffffffff831681526020810185905273ffffffffffffffffffffffffffffffffffffffff84168183015290517ffd96f5ca8894a9584abba5645131a95480f9340bd5e0046ceff789111ff16c6d9181900360600190a15b5050505080600101905061070f565b505050565b61087c610e5c565b6102ba81611019565b61088d610c4a565b6108f68261089e6040840184612607565b808060200260200160405190810160405280939291908181526020016000905b828210156108ea576108db6040830286013681900381019061266f565b815260200190600101906108be565b50505050506001610c8f565b5050565b610902610e5c565b6102ba816111a5565b610913610e5c565b60005b81518110156108f6576000828281518110610933576109336125d8565b6020908102919091010151604081015181519192509067ffffffffffffffff811660000361098d576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020830151600061099e8383610d66565b8054909150700100000000000000000000000000000000900463ffffffff16600003610bec576040805160a081018252602080870180516fffffffffffffffffffffffffffffffff908116845263ffffffff421692840192909252875115158385015251811660608301529186015190911660808201528215610b055767ffffffffffffffff8416600090815260066020908152604091829020835160028201805493860151948601516fffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009095169490941770010000000000000000000000000000000063ffffffff9096168602177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000941515949094029390931790925560608401516080850151908316921690920217600390910155610be6565b67ffffffffffffffff84166000908152600660209081526040918290208351815492850151938501516fffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff00000000000000000000000000000000000000009094169390931770010000000000000000000000000000000063ffffffff9095168502177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000093151593909302929092178155606084015160808501519083169216909202176001909101555b50610bf6565b610bf6818561129a565b8267ffffffffffffffff167ff14a5415ce6988a9e870a85fff0b9d7b7dd79bbc228cb63cad610daf6f7b6b978386604051610c3292919061268b565b60405180910390a25050505050806001019050610916565b610c55600233611449565b610c8d576040517fd86ad9cf0000000000000000000000000000000000000000000000000000000081523360048201526024016105a0565b565b6000610c9b8483610d66565b805490915074010000000000000000000000000000000000000000900460ff1615610d60576000805b8451811015610d4b57610d0f858281518110610ce257610ce26125d8565b6020908102919091018101515167ffffffffffffffff891660009081526004909252604090912090611478565b15610d4357610d36858281518110610d2957610d296125d8565b602002602001015161149a565b610d4090836126fe565b91505b600101610cc4565b508015610d5e57610d5e828260006115d6565b505b50505050565b67ffffffffffffffff821660009081526006602052604081208215610d8f57600201905061037c565b905061037c565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152610e2482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642610e089190612711565b85608001516fffffffffffffffffffffffffffffffff16611959565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60606000610e5583611981565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105a0565b73ffffffffffffffffffffffffffffffffffffffff8116610f2a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b600061037c826119dd565b6000808080610fbd86866119e8565b909450925050505b9250929050565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611a13565b60006110118473ffffffffffffffffffffffffffffffffffffffff851684611a30565b949350505050565b602081015160005b81518110156110b457600082828151811061103e5761103e6125d8565b6020026020010151905061105c816002611a4d90919063ffffffff16565b156110ab5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101611021565b50815160005b8151811015610d605760008282815181106110d7576110d76125d8565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611147576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611152600282611a6f565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016110ba565b3373ffffffffffffffffffffffffffffffffffffffff821603611224576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105a0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b81546000906112c390700100000000000000000000000000000000900463ffffffff1642612711565b90508015611365576001830154835461130b916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416611959565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461138b916fffffffffffffffffffffffffffffffff9081169116611a91565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061143c908490612724565b60405180910390a1505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610379565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611aa7565b60055481516040517fd02641a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526000928392169063d02641a0906024016040805180830381865afa15801561150e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115329190612760565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036115a85782516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016105a0565b6020830151610e55907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690611ab3565b825474010000000000000000000000000000000000000000900460ff1615806115fd575081155b1561160757505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061164d90700100000000000000000000000000000000900463ffffffff1642612711565b9050801561170d578183111561168f576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546116c99083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16611959565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156117c45773ffffffffffffffffffffffffffffffffffffffff841661176c576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016105a0565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016105a0565b848310156118d75760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906118089082612711565b611812878a612711565b61181c91906126fe565b61182691906127cb565b905073ffffffffffffffffffffffffffffffffffffffff861661187f576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016105a0565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016105a0565b6118e18584612711565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6000611978856119698486612806565b61197390876126fe565b611a91565b95945050505050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156119d157602002820191906000526020600020905b8154815260200190600101908083116119bd575b50505050509050919050565b600061037c82611af0565b600080806119f68585611afa565b600081815260029690960160205260409095205494959350505050565b600081815260028301602052604081208190556103798383611b06565b600082815260028401602052604081208290556110118484611b12565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611b1e565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611c11565b6000818310611aa05781610379565b5090919050565b60006103798383611c60565b6000670de0b6b3a7640000611ae6837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616612806565b61037991906127cb565b600061037c825490565b60006103798383611c78565b60006103798383611b1e565b60006103798383611c11565b60008181526001830160205260408120548015611c07576000611b42600183612711565b8554909150600090611b5690600190612711565b9050818114611bbb576000866000018281548110611b7657611b766125d8565b9060005260206000200154905080876000018481548110611b9957611b996125d8565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611bcc57611bcc61281d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061037c565b600091505061037c565b6000818152600183016020526040812054611c585750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561037c565b50600061037c565b60008181526001830160205260408120541515610379565b6000826000018281548110611c8f57611c8f6125d8565b9060005260206000200154905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611cf457611cf4611ca2565b60405290565b60405160a0810167ffffffffffffffff81118282101715611cf457611cf4611ca2565b6040516060810167ffffffffffffffff81118282101715611cf457611cf4611ca2565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d8757611d87611ca2565b604052919050565b803567ffffffffffffffff81168114611da757600080fd5b919050565b600082601f830112611dbd57600080fd5b813567ffffffffffffffff811115611dd757611dd7611ca2565b611e0860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611d40565b818152846020838601011115611e1d57600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115611e5457611e54611ca2565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff81168114611da757600080fd5b600060408284031215611e9457600080fd5b611e9c611cd1565b9050611ea782611e5e565b81526020820135602082015292915050565b600082601f830112611eca57600080fd5b81356020611edf611eda83611e3a565b611d40565b8083825260208201915060208460061b870101935086841115611f0157600080fd5b602086015b84811015611f2657611f188882611e82565b835291830191604001611f06565b509695505050505050565b600060208284031215611f4357600080fd5b813567ffffffffffffffff80821115611f5b57600080fd5b9083019060a08286031215611f6f57600080fd5b611f77611cfa565b82358152611f8760208401611d8f565b6020820152604083013582811115611f9e57600080fd5b611faa87828601611dac565b604083015250606083013582811115611fc257600080fd5b611fce87828601611dac565b606083015250608083013582811115611fe657600080fd5b611ff287828601611eb9565b60808301525095945050505050565b80358015158114611da757600080fd5b6000806040838503121561202457600080fd5b61202d83611d8f565b915061203b60208401612001565b90509250929050565b60006020808352835180602085015260005b8181101561207257858101830151858201604001528201612056565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60008151808452602080850194506020840160005b838110156120f857815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016120c6565b509495945050505050565b60208152600061037960208301846120b1565b60006020828403121561212857600080fd5b61037982611e5e565b60006020828403121561214357600080fd5b61037982611d8f565b60408152600061215f60408301856120b1565b82810360208481019190915284518083528582019282019060005b818110156121965784518352938301939183019160010161217a565b5090979650505050505050565b6000604082840312156121b557600080fd5b6121bd611cd1565b90506121c882611d8f565b81526121d660208301611e5e565b602082015292915050565b600082601f8301126121f257600080fd5b81356020612202611eda83611e3a565b80838252602082019150606060206060860288010194508785111561222657600080fd5b602087015b858110156121965781818a0312156122435760008081fd5b61224b611cd1565b6122558a836121a3565b8152604082013586820152845292840192810161222b565b600080604080848603121561228157600080fd5b833567ffffffffffffffff8082111561229957600080fd5b818601915086601f8301126122ad57600080fd5b813560206122bd611eda83611e3a565b8083825260208201915060208460061b87010193508a8411156122df57600080fd5b6020860195505b83861015612307576122f88b876121a3565b825294860194908201906122e6565b9750505050602086013592508083111561232057600080fd5b505061232e858286016121e1565b9150509250929050565b600082601f83011261234957600080fd5b81356020612359611eda83611e3a565b8083825260208201915060208460051b87010193508684111561237b57600080fd5b602086015b84811015611f265761239181611e5e565b8352918301918301612380565b6000602082840312156123b057600080fd5b813567ffffffffffffffff808211156123c857600080fd5b90830190604082860312156123dc57600080fd5b6123e4611cd1565b8235828111156123f357600080fd5b6123ff87828601612338565b82525060208301358281111561241457600080fd5b61242087828601612338565b60208301525095945050505050565b6000806040838503121561244257600080fd5b61244b83611d8f565b9150602083013567ffffffffffffffff81111561246757600080fd5b830160a0818603121561247957600080fd5b809150509250929050565b80356fffffffffffffffffffffffffffffffff81168114611da757600080fd5b600060208083850312156124b757600080fd5b823567ffffffffffffffff8111156124ce57600080fd5b8301601f810185136124df57600080fd5b80356124ed611eda82611e3a565b81815260a0918202830184019184820191908884111561250c57600080fd5b938501935b838510156125cc578489038181121561252a5760008081fd5b612532611d1d565b61253b87611d8f565b8152612548888801612001565b8882015260406060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0850112156125805760008081fd5b612588611d1d565b9350612595828a01612001565b84526125a2818a01612484565b8a850152506125b360808901612484565b8382015281019190915283529384019391850191612511565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261263c57600080fd5b83018035915067ffffffffffffffff82111561265757600080fd5b6020019150600681901b3603821315610fc557600080fd5b60006040828403121561268157600080fd5b6103798383611e82565b821515815260808101610e5560208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561037c5761037c6126cf565b8181038181111561037c5761037c6126cf565b6060810161037c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006040828403121561277257600080fd5b61277a611cd1565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146127a657600080fd5b8152602083015163ffffffff811681146127bf57600080fd5b60208201529392505050565b600082612801577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761037c5761037c6126cf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe4d756c7469416767726567617465526174654c696d6974657220312e362e302d646576a164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"PriceRegistrySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"RateLimiterConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimiterConfigArgs[]\",\"name\":\"rateLimiterUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applyRateLimiterConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"}],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"localTokens\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"remoteTokens\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onInboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onOutboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"setPriceRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken\",\"name\":\"localTokenArgs\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimitTokenArgs[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b506040516200327338038062003273833981016040819052620000349162000538565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000102565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001ad565b50620000fa82620002fc565b50506200066f565b336001600160a01b038216036200015c5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b81518110156200023d576000828281518110620001d657620001d662000621565b60209081029190910101519050620001f060028262000378565b1562000233576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001b5565b50815160005b8151811015620002f657600082828151811062000264576200026462000621565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002a2576040516342bcdf7f60e11b815260040160405180910390fd5b620002af60028262000398565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000243565b50505050565b6001600160a01b03811662000324576040516342bcdf7f60e11b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b60006200038f836001600160a01b038416620003af565b90505b92915050565b60006200038f836001600160a01b038416620004b3565b60008181526001830160205260408120548015620004a8576000620003d660018362000637565b8554909150600090620003ec9060019062000637565b90508181146200045857600086600001828154811062000410576200041062000621565b906000526020600020015490508087600001848154811062000436576200043662000621565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200046c576200046c62000659565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000392565b600091505062000392565b6000818152600183016020526040812054620004fc5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000392565b50600062000392565b80516001600160a01b03811681146200051d57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200054c57600080fd5b620005578362000505565b602084810151919350906001600160401b03808211156200057757600080fd5b818601915086601f8301126200058c57600080fd5b815181811115620005a157620005a162000522565b8060051b604051601f19603f83011681018181108582111715620005c957620005c962000522565b604052918252848201925083810185019189831115620005e857600080fd5b938501935b828510156200061157620006018562000505565b84529385019392850192620005ed565b8096505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039257634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b612bf4806200067f6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063537e304e1161008c57806391a2749a1161006657806391a2749a14610252578063e0a0e50614610265578063f2fde38b14610278578063fe843cd01461028b57600080fd5b8063537e304e1461020b57806379ba50971461022c5780638da5cb5b1461023457600080fd5b8063181f5a77116100c8578063181f5a77146101bb5780631af18b7b146101d05780632451a627146101e3578063508ee9de146101f857600080fd5b806308d450a1146100ef5780630a35bcc4146101045780630d6c107e1461017c575b600080fd5b6101026100fd366004612003565b61029e565b005b6101176101123660046120e3565b6102bd565b604051610173919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60405180910390f35b60055473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b6101c3610382565b604051610173919061217a565b6101026101de3660046122b4565b61039e565b6101eb6105ca565b60405161017391906123d1565b6101026102063660046123e4565b6105db565b61021e6102193660046123ff565b6105ec565b60405161017392919061241a565b610102610759565b60005473ffffffffffffffffffffffffffffffffffffffff16610196565b610102610260366004612510565b61085b565b6101026102733660046125a1565b61086c565b6101026102863660046123e4565b6108e1565b610102610299366004612616565b6108f2565b6102a6610c31565b6102ba816020015182608001516000610c76565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526103796102f58484610d4d565b6040805160a08101825282546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff16151593830193909352600190930154808316606083015292909204166080820152610d7d565b90505b92915050565b604051806060016040528060238152602001612bc56023913981565b6103a6610e2f565b60005b82518110156104845760008382815181106103c6576103c661274a565b602002602001015160200151905060008483815181106103e8576103e861274a565b6020908102919091018101515167ffffffffffffffff811660009081526004909252604090912090915061041c9083610eb0565b1561047a576040805167ffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff841660208201527f530cabd30786b7235e124a6c0db77e0b685ef22813b1fe87554247f404eb8ed6910160405180910390a15b50506001016103a9565b5060005b81518110156105c55760008282815181106104a5576104a561274a565b602002602001015160000151905060008383815181106104c7576104c761274a565b6020026020010151602001519050600082602001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061051857508151155b1561054f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825167ffffffffffffffff81166000908152600460205260409020610575908385610ed2565b156105b6577fad72a792d2a307f400c278be7deaeec6964276783304580cdc4e905436b8d5c58184846040516105ad93929190612779565b60405180910390a15b50505050806001019050610488565b505050565b60606105d66002610eff565b905090565b6105e3610e2f565b6102ba81610f0c565b67ffffffffffffffff81166000908152600460205260408120606091829161061390610fd2565b90508067ffffffffffffffff81111561062e5761062e611d74565b604051908082528060200260200182016040528015610657578160200160208202803683370190505b5092508067ffffffffffffffff81111561067357610673611d74565b6040519080825280602002602001820160405280156106a657816020015b60608152602001906001900390816106915790505b50915060005b818110156107525767ffffffffffffffff8516600090815260046020526040812081906106d99084610fdd565b91509150818684815181106106f0576106f061274a565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508085848151811061073d5761073d61274a565b602090810291909101015250506001016106ac565b5050915091565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610863610e2f565b6102ba81610ffc565b610874610c31565b6108dd8261088560408401846127c2565b808060200260200160405190810160405280939291908181526020016000905b828210156108d1576108c26040830286013681900381019061282a565b815260200190600101906108a5565b50505050506001610c76565b5050565b6108e9610e2f565b6102ba81611188565b6108fa610e2f565b60005b81518110156108dd57600082828151811061091a5761091a61274a565b6020908102919091010151604081015181519192509067ffffffffffffffff8116600003610974576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015160006109858383610d4d565b8054909150700100000000000000000000000000000000900463ffffffff16600003610bd3576040805160a081018252602080870180516fffffffffffffffffffffffffffffffff908116845263ffffffff421692840192909252875115158385015251811660608301529186015190911660808201528215610aec5767ffffffffffffffff8416600090815260066020908152604091829020835160028201805493860151948601516fffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009095169490941770010000000000000000000000000000000063ffffffff9096168602177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000941515949094029390931790925560608401516080850151908316921690920217600390910155610bcd565b67ffffffffffffffff84166000908152600660209081526040918290208351815492850151938501516fffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff00000000000000000000000000000000000000009094169390931770010000000000000000000000000000000063ffffffff9095168502177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000093151593909302929092178155606084015160808501519083169216909202176001909101555b50610bdd565b610bdd818561127d565b8267ffffffffffffffff167ff14a5415ce6988a9e870a85fff0b9d7b7dd79bbc228cb63cad610daf6f7b6b978386604051610c19929190612846565b60405180910390a250505050508060010190506108fd565b610c3c60023361142c565b610c74576040517fd86ad9cf0000000000000000000000000000000000000000000000000000000081523360048201526024016107d6565b565b6000610c828483610d4d565b805490915074010000000000000000000000000000000000000000900460ff1615610d47576000805b8451811015610d3257610cf6858281518110610cc957610cc961274a565b6020908102919091018101515167ffffffffffffffff89166000908152600490925260409091209061145b565b15610d2a57610d1d858281518110610d1057610d1061274a565b602002602001015161147d565b610d2790836128b9565b91505b600101610cab565b508015610d4557610d45828260006115b9565b505b50505050565b67ffffffffffffffff821660009081526006602052604081208215610d7657600201905061037c565b905061037c565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152610e0b82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642610def91906128cc565b85608001516fffffffffffffffffffffffffffffffff1661193c565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107d6565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611964565b6000610ef58473ffffffffffffffffffffffffffffffffffffffff851684611988565b90505b9392505050565b60606000610ef8836119ad565b73ffffffffffffffffffffffffffffffffffffffff8116610f59576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b600061037c82611a09565b600060608180610fed8686611a14565b909450925050505b9250929050565b602081015160005b81518110156110975760008282815181106110215761102161274a565b6020026020010151905061103f816002611ad190919063ffffffff16565b1561108e5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101611004565b50815160005b8151811015610d475760008282815181106110ba576110ba61274a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361112a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611135600282611af3565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010161109d565b3373ffffffffffffffffffffffffffffffffffffffff821603611207576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107d6565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b81546000906112a690700100000000000000000000000000000000900463ffffffff16426128cc565b9050801561134857600183015483546112ee916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661193c565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461136e916fffffffffffffffffffffffffffffffff9081169116611b15565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061141f9084906128df565b60405180910390a1505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610379565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611b2b565b60055481516040517fd02641a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526000928392169063d02641a0906024016040805180830381865afa1580156114f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611515919061291b565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660000361158b5782516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016107d6565b6020830151610ef8907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690611b37565b825474010000000000000000000000000000000000000000900460ff1615806115e0575081155b156115ea57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061163090700100000000000000000000000000000000900463ffffffff16426128cc565b905080156116f05781831115611672576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546116ac9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661193c565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156117a75773ffffffffffffffffffffffffffffffffffffffff841661174f576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016107d6565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016107d6565b848310156118ba5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906117eb90826128cc565b6117f5878a6128cc565b6117ff91906128b9565b6118099190612986565b905073ffffffffffffffffffffffffffffffffffffffff8616611862576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016107d6565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016107d6565b6118c485846128cc565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600061195b8561194c84866129c1565b61195690876128b9565b611b15565b95945050505050565b6000818152600283016020526040812061197e9082611d26565b6103798383611b74565b600082815260028401602052604081206119a28382612a7b565b50610ef58484611b80565b6060816000018054806020026020016040519081016040528092919081815260200182805480156119fd57602002820191906000526020600020905b8154815260200190600101908083116119e9575b50505050509050919050565b600061037c82611b8c565b6000606081611a238585611b96565b60008181526002870160205260409020805491925082918190611a45906129d8565b80601f0160208091040260200160405190810160405280929190818152602001828054611a71906129d8565b8015611abe5780601f10611a9357610100808354040283529160200191611abe565b820191906000526020600020905b815481529060010190602001808311611aa157829003601f168201915b5050505050905092509250509250929050565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611ba2565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611c95565b6000818310611b245781610379565b5090919050565b60006103798383611ce4565b6000670de0b6b3a7640000611b6a837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166129c1565b6103799190612986565b60006103798383611ba2565b60006103798383611c95565b600061037c825490565b60006103798383611cfc565b60008181526001830160205260408120548015611c8b576000611bc66001836128cc565b8554909150600090611bda906001906128cc565b9050818114611c3f576000866000018281548110611bfa57611bfa61274a565b9060005260206000200154905080876000018481548110611c1d57611c1d61274a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611c5057611c50612b95565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061037c565b600091505061037c565b6000818152600183016020526040812054611cdc5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561037c565b50600061037c565b60008181526001830160205260408120541515610379565b6000826000018281548110611d1357611d1361274a565b9060005260206000200154905092915050565b508054611d32906129d8565b6000825580601f10611d42575050565b601f0160209004906000526020600020908101906102ba91905b80821115611d705760008155600101611d5c565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611dc657611dc6611d74565b60405290565b60405160a0810167ffffffffffffffff81118282101715611dc657611dc6611d74565b6040516060810167ffffffffffffffff81118282101715611dc657611dc6611d74565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e5957611e59611d74565b604052919050565b803567ffffffffffffffff81168114611e7957600080fd5b919050565b600082601f830112611e8f57600080fd5b813567ffffffffffffffff811115611ea957611ea9611d74565b611eda60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611e12565b818152846020838601011115611eef57600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115611f2657611f26611d74565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff81168114611e7957600080fd5b600060408284031215611f6657600080fd5b611f6e611da3565b9050611f7982611f30565b81526020820135602082015292915050565b600082601f830112611f9c57600080fd5b81356020611fb1611fac83611f0c565b611e12565b8083825260208201915060208460061b870101935086841115611fd357600080fd5b602086015b84811015611ff857611fea8882611f54565b835291830191604001611fd8565b509695505050505050565b60006020828403121561201557600080fd5b813567ffffffffffffffff8082111561202d57600080fd5b9083019060a0828603121561204157600080fd5b612049611dcc565b8235815261205960208401611e61565b602082015260408301358281111561207057600080fd5b61207c87828601611e7e565b60408301525060608301358281111561209457600080fd5b6120a087828601611e7e565b6060830152506080830135828111156120b857600080fd5b6120c487828601611f8b565b60808301525095945050505050565b80358015158114611e7957600080fd5b600080604083850312156120f657600080fd5b6120ff83611e61565b915061210d602084016120d3565b90509250929050565b6000815180845260005b8181101561213c57602081850181015186830182015201612120565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006103796020830184612116565b60006040828403121561219f57600080fd5b6121a7611da3565b90506121b282611e61565b81526121c060208301611f30565b602082015292915050565b600082601f8301126121dc57600080fd5b813560206121ec611fac83611f0c565b82815260059290921b8401810191818101908684111561220b57600080fd5b8286015b84811015611ff857803567ffffffffffffffff808211156122305760008081fd5b81890191506060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d030112156122695760008081fd5b612271611da3565b61227d8c89860161218d565b81529083013590828211156122925760008081fd5b6122a08c8984870101611e7e565b81890152865250505091830191830161220f565b60008060408084860312156122c857600080fd5b833567ffffffffffffffff808211156122e057600080fd5b818601915086601f8301126122f457600080fd5b81356020612304611fac83611f0c565b8083825260208201915060208460061b87010193508a84111561232657600080fd5b6020860195505b8386101561234e5761233f8b8761218d565b8252948601949082019061232d565b9750505050602086013592508083111561236757600080fd5b5050612375858286016121cb565b9150509250929050565b60008151808452602080850194506020840160005b838110156123c657815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612394565b509495945050505050565b602081526000610379602083018461237f565b6000602082840312156123f657600080fd5b61037982611f30565b60006020828403121561241157600080fd5b61037982611e61565b60408152600061242d604083018561237f565b6020838203818501528185518084528284019150828160051b85010183880160005b8381101561249b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0878403018552612489838351612116565b9486019492509085019060010161244f565b50909998505050505050505050565b600082601f8301126124bb57600080fd5b813560206124cb611fac83611f0c565b8083825260208201915060208460051b8701019350868411156124ed57600080fd5b602086015b84811015611ff85761250381611f30565b83529183019183016124f2565b60006020828403121561252257600080fd5b813567ffffffffffffffff8082111561253a57600080fd5b908301906040828603121561254e57600080fd5b612556611da3565b82358281111561256557600080fd5b612571878286016124aa565b82525060208301358281111561258657600080fd5b612592878286016124aa565b60208301525095945050505050565b600080604083850312156125b457600080fd5b6125bd83611e61565b9150602083013567ffffffffffffffff8111156125d957600080fd5b830160a081860312156125eb57600080fd5b809150509250929050565b80356fffffffffffffffffffffffffffffffff81168114611e7957600080fd5b6000602080838503121561262957600080fd5b823567ffffffffffffffff81111561264057600080fd5b8301601f8101851361265157600080fd5b803561265f611fac82611f0c565b81815260a0918202830184019184820191908884111561267e57600080fd5b938501935b8385101561273e578489038181121561269c5760008081fd5b6126a4611def565b6126ad87611e61565b81526126ba8888016120d3565b8882015260406060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0850112156126f25760008081fd5b6126fa611def565b9350612707828a016120d3565b8452612714818a016125f6565b8a85015250612725608089016125f6565b8382015281019190915283529384019391850191612683565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff8416815260606020820152600061279c6060830185612116565b905073ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126127f757600080fd5b83018035915067ffffffffffffffff82111561281257600080fd5b6020019150600681901b3603821315610ff557600080fd5b60006040828403121561283c57600080fd5b6103798383611f54565b821515815260808101610ef860208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561037c5761037c61288a565b8181038181111561037c5761037c61288a565b6060810161037c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006040828403121561292d57600080fd5b612935611da3565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461296157600080fd5b8152602083015163ffffffff8116811461297a57600080fd5b60208201529392505050565b6000826129bc577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761037c5761037c61288a565b600181811c908216806129ec57607f821691505b602082108103612a25577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105c5576000816000526020600020601f850160051c81016020861015612a545750805b601f850160051c820191505b81811015612a7357828155600101612a60565b505050505050565b815167ffffffffffffffff811115612a9557612a95611d74565b612aa981612aa384546129d8565b84612a2b565b602080601f831160018114612afc5760008415612ac65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612a73565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015612b4957888601518255948401946001909101908401612b2a565b5085821015612b8557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe4d756c7469416767726567617465526174654c696d6974657220312e362e302d646576a164736f6c6343000818000a", } var MultiAggregateRateLimiterABI = MultiAggregateRateLimiterMetaData.ABI @@ -283,7 +283,7 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) GetAllRateLim } outstruct.LocalTokens = *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) - outstruct.RemoteTokens = *abi.ConvertType(out[1], new([][32]byte)).(*[][32]byte) + outstruct.RemoteTokens = *abi.ConvertType(out[1], new([][]byte)).(*[][]byte) return *outstruct, err @@ -1394,7 +1394,7 @@ func (it *MultiAggregateRateLimiterTokenAggregateRateLimitAddedIterator) Close() type MultiAggregateRateLimiterTokenAggregateRateLimitAdded struct { RemoteChainSelector uint64 - RemoteToken [32]byte + RemoteToken []byte LocalToken common.Address Raw types.Log } @@ -1688,7 +1688,7 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseTokens type GetAllRateLimitTokens struct { LocalTokens []common.Address - RemoteTokens [][32]byte + RemoteTokens [][]byte } func (_MultiAggregateRateLimiter *MultiAggregateRateLimiter) ParseLog(log types.Log) (generated.AbigenLog, error) { @@ -1748,7 +1748,7 @@ func (MultiAggregateRateLimiterRateLimiterConfigUpdated) Topic() common.Hash { } func (MultiAggregateRateLimiterTokenAggregateRateLimitAdded) Topic() common.Hash { - return common.HexToHash("0xfd96f5ca8894a9584abba5645131a95480f9340bd5e0046ceff789111ff16c6d") + return common.HexToHash("0xad72a792d2a307f400c278be7deaeec6964276783304580cdc4e905436b8d5c5") } func (MultiAggregateRateLimiterTokenAggregateRateLimitRemoved) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 6bfad5acd7..541dd33e27 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -22,7 +22,7 @@ mock_arm_contract: ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.abi ../../ mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin d976651d36b33ac2196b32b9d2f4fa6690c6a18d41b621365659fce1c1d1e737 mock_usdc_token_transmitter: ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin be0dbc3e475741ea0b7a54ec2b935a321b428baa9f4ce18180a87fb38bb87de2 mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin 518e19efa2ff52b0fefd8e597b05765317ee7638189bfe34ca43de2f6599faf4 -multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin 44e1f40d928fd0e1f36e1ee5edfb6ab2a54fee0174e5f83c57a06cf79ec0c96c +multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin 51435ef057455bea49888b81b06ed92f6b82c58f59e3575e4c60833031e23750 multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin aa299e0c2659d53aad4eace4d66be0e734b1366008593669cf30361ff529da6a nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 6f64e1083b356c06ee66b9138e398b9c97a4cd3e8c9ec38cf3010cebc79af536 ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 From 77020b86b1a1df5ff79c0eccd8550eef83b0de15 Mon Sep 17 00:00:00 2001 From: Makram Date: Wed, 14 Aug 2024 12:37:36 +0300 Subject: [PATCH 205/432] core/capabilities/ccip: bump chainlink-ccip, fix tests (#1291) ## Motivation Bump chainlink-ccip to the version from this PR: https://github.com/smartcontractkit/chainlink-ccip/pull/64 ## Solution Bump and fix the tests. --- .../integrationhelpers/integration_helpers.go | 5 ++- core/capabilities/ccip/delegate.go | 41 ++++++++++--------- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 10 files changed, 37 insertions(+), 33 deletions(-) diff --git a/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go b/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go index 7520b12633..821c2bc0f5 100644 --- a/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go @@ -234,7 +234,10 @@ func (t *TestUniverse) AddCapability(p2pIDs [][32]byte) { func NewHomeChainReader(t *testing.T, logPoller logpoller.LogPoller, headTracker logpoller.HeadTracker, client client.Client, ccAddress common.Address) ccipreader.HomeChain { cr := NewReader(t, logPoller, headTracker, client, ccAddress, configsevm.HomeChainReaderConfigRaw()) - hcr := ccipreader.NewHomeChainReader(cr, logger.TestLogger(t), 500*time.Millisecond) + hcr := ccipreader.NewHomeChainReader(cr, logger.TestLogger(t), 500*time.Millisecond, types.BoundContract{ + Address: ccAddress.String(), + Name: consts.ContractNameCCIPConfig, + }) require.NoError(t, hcr.Start(testutils.Context(t))) t.Cleanup(func() { require.NoError(t, hcr.Close()) }) diff --git a/core/capabilities/ccip/delegate.go b/core/capabilities/ccip/delegate.go index 187ae0c581..a7cefd5cd9 100644 --- a/core/capabilities/ccip/delegate.go +++ b/core/capabilities/ccip/delegate.go @@ -145,7 +145,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services // since all queries are scoped by config digest. ocrDB := ocr2.NewDB(d.ds, spec.ID, 0, d.lggr) - homeChainContractReader, err := d.getHomeChainContractReader( + homeChainContractReader, ccipConfigBinding, err := d.getHomeChainContractReader( ctx, d.chains, spec.CCIPSpec.CapabilityLabelledName, @@ -158,6 +158,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services homeChainContractReader, d.lggr.Named("HomeChainReader"), 100*time.Millisecond, + ccipConfigBinding, ) oracleCreator := oraclecreator.New( @@ -251,13 +252,13 @@ func (d *Delegate) getHomeChainContractReader( chains legacyevm.LegacyChainContainer, capabilityLabelledName, capabilityVersion string, -) (types.ContractReader, error) { +) (types.ContractReader, types.BoundContract, error) { // home chain is where the capability registry is deployed, // which should be set correctly in toml config. homeChainRelayID := d.capabilityConfig.ExternalRegistry().RelayID() homeChain, err := chains.Get(homeChainRelayID.ChainID) if err != nil { - return nil, fmt.Errorf("home chain relayer not found, chain id: %s, err: %w", homeChainRelayID.String(), err) + return nil, types.BoundContract{}, fmt.Errorf("home chain relayer not found, chain id: %s, err: %w", homeChainRelayID.String(), err) } reader, err := evm.NewChainReaderService( @@ -269,35 +270,36 @@ func (d *Delegate) getHomeChainContractReader( configsevm.HomeChainReaderConfigRaw(), ) if err != nil { - return nil, fmt.Errorf("failed to create home chain contract reader: %w", err) + return nil, types.BoundContract{}, fmt.Errorf("failed to create home chain contract reader: %w", err) } - reader, err = bindReader(ctx, reader, d.capabilityConfig.ExternalRegistry().Address(), capabilityLabelledName, capabilityVersion) + reader, ccipConfigBinding, err := bindReader(ctx, reader, d.capabilityConfig.ExternalRegistry().Address(), capabilityLabelledName, capabilityVersion) if err != nil { - return nil, fmt.Errorf("failed to bind home chain contract reader: %w", err) + return nil, types.BoundContract{}, fmt.Errorf("failed to bind home chain contract reader: %w", err) } - return reader, nil + return reader, ccipConfigBinding, nil } func bindReader(ctx context.Context, reader types.ContractReader, capRegAddress, capabilityLabelledName, - capabilityVersion string) (types.ContractReader, error) { - err := reader.Bind(ctx, []types.BoundContract{ + capabilityVersion string, +) (boundReader types.ContractReader, ccipConfigBinding types.BoundContract, err error) { + err = reader.Bind(ctx, []types.BoundContract{ { Address: capRegAddress, Name: consts.ContractNameCapabilitiesRegistry, }, }) if err != nil { - return nil, fmt.Errorf("failed to bind home chain contract reader: %w", err) + return nil, types.BoundContract{}, fmt.Errorf("failed to bind home chain contract reader: %w", err) } hid, err := common.HashedCapabilityID(capabilityLabelledName, capabilityVersion) if err != nil { - return nil, fmt.Errorf("failed to hash capability id: %w", err) + return nil, types.BoundContract{}, fmt.Errorf("failed to hash capability id: %w", err) } var ccipCapabilityInfo kcr.CapabilitiesRegistryCapabilityInfo @@ -305,19 +307,18 @@ func bindReader(ctx context.Context, "hashedId": hid, }, &ccipCapabilityInfo) if err != nil { - return nil, fmt.Errorf("failed to get CCIP capability info from chain reader: %w", err) + return nil, types.BoundContract{}, fmt.Errorf("failed to get CCIP capability info from chain reader: %w", err) } // bind the ccip capability configuration contract - err = reader.Bind(ctx, []types.BoundContract{ - { - Address: ccipCapabilityInfo.ConfigurationContract.String(), - Name: consts.ContractNameCCIPConfig, - }, - }) + ccipConfigBinding = types.BoundContract{ + Address: ccipCapabilityInfo.ConfigurationContract.String(), + Name: consts.ContractNameCCIPConfig, + } + err = reader.Bind(ctx, []types.BoundContract{ccipConfigBinding}) if err != nil { - return nil, fmt.Errorf("failed to bind CCIP capability configuration contract: %w", err) + return nil, types.BoundContract{}, fmt.Errorf("failed to bind CCIP capability configuration contract: %w", err) } - return reader, nil + return reader, ccipConfigBinding, nil } diff --git a/core/scripts/go.mod b/core/scripts/go.mod index ccf4a2b32b..7848a1dade 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -274,7 +274,7 @@ require ( github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index b95551d8b2..e3cf65c26a 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1070,8 +1070,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 h1:XKEmg6dOkCsyNcW3R+IhhrUYdVJTKirLL2sCCgzRWjU= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f h1:sxBPgtGeqJ3h3+JgF6N3wwr4xgy9wLbBIjFVVn6mMCs= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/go.mod b/go.mod index fc89fbb06c..8ca696860f 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa diff --git a/go.sum b/go.sum index 5aa0189250..bb7deba816 100644 --- a/go.sum +++ b/go.sum @@ -1027,8 +1027,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 h1:XKEmg6dOkCsyNcW3R+IhhrUYdVJTKirLL2sCCgzRWjU= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f h1:sxBPgtGeqJ3h3+JgF6N3wwr4xgy9wLbBIjFVVn6mMCs= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index f3dab760f0..1a742a373f 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -384,7 +384,7 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index ad92b237b9..a5925ccab7 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1392,8 +1392,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 h1:XKEmg6dOkCsyNcW3R+IhhrUYdVJTKirLL2sCCgzRWjU= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f h1:sxBPgtGeqJ3h3+JgF6N3wwr4xgy9wLbBIjFVVn6mMCs= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 26c6dee721..82924f18c0 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -40,7 +40,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect k8s.io/apimachinery v0.30.2 // indirect ) diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 244b2be8c5..926362ed14 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1374,8 +1374,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422 h1:XKEmg6dOkCsyNcW3R+IhhrUYdVJTKirLL2sCCgzRWjU= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240812165928-f1cc95338422/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f h1:sxBPgtGeqJ3h3+JgF6N3wwr4xgy9wLbBIjFVVn6mMCs= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= From c510f41cdc7608b9bf3aadf4f5ca460cee386eda Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Thu, 15 Aug 2024 13:48:41 +0200 Subject: [PATCH 206/432] Fix stale comment (#1296) - Fix stale comment - remove wrapper gen for the old mockRMN - should no longer be used in offchain tests, use the real RMN instead - Remove naming clash with RMN --- contracts/scripts/native_solc_compile_all_ccip | 1 - .../src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 5 ++--- contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol | 5 ++--- .../ccip/test/helpers/receivers/ReentrancyAbuser.sol | 2 +- contracts/src/v0.8/ccip/test/mocks/MockRMN1_0.sol | 10 +++++----- .../v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol | 2 +- ...nerated-wrapper-dependency-versions-do-not-edit.txt | 1 - core/gethwrappers/ccip/go_generate.go | 1 - 8 files changed, 11 insertions(+), 16 deletions(-) diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index fd38ae3562..7ba49f87dd 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -86,7 +86,6 @@ compileContract ccip/test/helpers/MessageHasher.sol compileContract ccip/test/helpers/ReportCodec.sol compileContract ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol compileContract ccip/test/helpers/MultiOCR3Helper.sol -compileContract ccip/test/mocks/MockRMN1_0.sol compileContract ccip/test/mocks/MockE2EUSDCTokenMessenger.sol compileContract ccip/test/mocks/MockE2EUSDCTransmitter.sol compileContract ccip/test/WETH9.sol diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol index 7fe7e82ca1..8a5cb1fdc2 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -794,9 +794,8 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { // │ Tokens and pools │ // ================================================================ - /// @notice Uses a pool to release or mint a token to a receiver address in two steps. First, the pool is called - /// to release the tokens to the offRamp, then the offRamp calls the token contract to transfer the tokens to the - /// receiver. This is done to ensure the exact number of tokens, the pool claims to release are actually transferred. + /// @notice Uses a pool to release or mint a token to a receiver address, with balance checks before and after the + /// transfer. This is done to ensure the exact number of tokens the pool claims to release are actually transferred. /// @dev The local token address is validated through the TokenAdminRegistry. If, due to some misconfiguration, the /// token is unknown to the registry, the offRamp will revert. The tx, and the tokens, can be retrieved by /// registering the token on this chain, and re-trying the msg. diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol index fccec3334f..97139d0560 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol @@ -639,9 +639,8 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio // │ Tokens and pools │ // ================================================================ - /// @notice Uses a pool to release or mint a token to a receiver address in two steps. First, the pool is called - /// to release the tokens to the offRamp, then the offRamp calls the token contract to transfer the tokens to the - /// receiver. This is done to ensure the exact number of tokens, the pool claims to release are actually transferred. + /// @notice Uses a pool to release or mint a token to a receiver address, with balance checks before and after the + /// transfer. This is done to ensure the exact number of tokens the pool claims to release are actually transferred. /// @dev The local token address is validated through the TokenAdminRegistry. If, due to some misconfiguration, the /// token is unknown to the registry, the offRamp will revert. The tx, and the tokens, can be retrieved by /// registering the token on this chain, and re-trying the msg. diff --git a/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol b/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol index 68d5407c0f..e53df4de1b 100644 --- a/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol +++ b/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol @@ -38,7 +38,7 @@ contract ReentrancyAbuser is CCIPReceiver { function _getGasLimitsFromMessages(Internal.EVM2EVMMessage[] memory messages) internal - view + pure returns (EVM2EVMOffRamp.GasLimitOverride[] memory) { EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = new EVM2EVMOffRamp.GasLimitOverride[](messages.length); diff --git a/contracts/src/v0.8/ccip/test/mocks/MockRMN1_0.sol b/contracts/src/v0.8/ccip/test/mocks/MockRMN1_0.sol index 44ffc23b78..d1a488d557 100644 --- a/contracts/src/v0.8/ccip/test/mocks/MockRMN1_0.sol +++ b/contracts/src/v0.8/ccip/test/mocks/MockRMN1_0.sol @@ -6,7 +6,7 @@ import {OwnerIsCreator} from "./../../../shared/access/OwnerIsCreator.sol"; // Inlined from RMN 1.0 contract. // solhint-disable gas-struct-packing -contract RMN { +contract OldRMN { struct Voter { address blessVoteAddr; address curseVoteAddr; @@ -44,7 +44,7 @@ contract MockRMN is IRMN, OwnerIsCreator { bool private s_curse; bytes private s_err; - RMN.VersionedConfig private s_versionedConfig; + OldRMN.VersionedConfig private s_versionedConfig; mapping(bytes16 subject => bool cursed) private s_curseBySubject; function isCursed() external view override returns (bool) { @@ -69,11 +69,11 @@ contract MockRMN is IRMN, OwnerIsCreator { s_curseBySubject[subject] = true; } - function ownerUnvoteToCurse(RMN.UnvoteToCurseRecord[] memory) external { + function ownerUnvoteToCurse(OldRMN.UnvoteToCurseRecord[] memory) external { s_curse = false; } - function ownerUnvoteToCurse(RMN.UnvoteToCurseRecord[] memory, bytes16 subject) external { + function ownerUnvoteToCurse(OldRMN.UnvoteToCurseRecord[] memory, bytes16 subject) external { s_curseBySubject[subject] = false; } @@ -85,7 +85,7 @@ contract MockRMN is IRMN, OwnerIsCreator { return !s_curse; } - function getConfigDetails() external view returns (uint32 version, uint32 blockNumber, RMN.Config memory config) { + function getConfigDetails() external view returns (uint32 version, uint32 blockNumber, OldRMN.Config memory config) { return (s_versionedConfig.configVersion, s_versionedConfig.blockNumber, s_versionedConfig.config); } } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol index ad714791cf..ccb91a7e72 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol @@ -230,7 +230,7 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { function _getGasLimitsFromMessages(Internal.EVM2EVMMessage[] memory messages) internal - view + pure returns (EVM2EVMOffRamp.GasLimitOverride[] memory) { EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = new EVM2EVMOffRamp.GasLimitOverride[](messages.length); diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 541dd33e27..6fc9d043ff 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -18,7 +18,6 @@ lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/Lo lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin 9afb4cf8621b5e60ac70c1b95fcc28d735119bdbc8c702bc9931d30e712e29f3 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin 1d5146d43e1b99cd2d6f9f06475be19087e4349f7cee0fdbbf134ba65e967c93 -mock_arm_contract: ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.abi ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.bin e7a3a6c3eda5fb882e16bcc2b4340f78523acb67907bcdcaf3c8ffc51488688e mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin d976651d36b33ac2196b32b9d2f4fa6690c6a18d41b621365659fce1c1d1e737 mock_usdc_token_transmitter: ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin be0dbc3e475741ea0b7a54ec2b935a321b428baa9f4ce18180a87fb38bb87de2 mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin 518e19efa2ff52b0fefd8e597b05765317ee7638189bfe34ca43de2f6599faf4 diff --git a/core/gethwrappers/ccip/go_generate.go b/core/gethwrappers/ccip/go_generate.go index 870ac2dd57..b53c6c358c 100644 --- a/core/gethwrappers/ccip/go_generate.go +++ b/core/gethwrappers/ccip/go_generate.go @@ -13,7 +13,6 @@ package ccip //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin TokenPool token_pool //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin ARMContract arm_contract //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin ARMProxyContract arm_proxy_contract -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.abi ../../../contracts/solc/v0.8.24/MockRMN1_0/MockRMN.bin MockARMContract mock_arm_contract //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin TokenAdminRegistry token_admin_registry //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin RegistryModuleOwnerCustom registry_module_owner_custom //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin MockE2EUSDCTokenMessenger mock_usdc_token_messenger From 5a94c90adb41e69988e9c9ea8bf456c47f7b2242 Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Thu, 15 Aug 2024 15:11:20 +0200 Subject: [PATCH 207/432] add BurnWithFromMintTokenPoolAndProxy (#1287) There's already 1.4 pools out there of this type so we need a proxy --- contracts/gas-snapshots/ccip.gas-snapshot | 5 +- .../scripts/native_solc_compile_all_ccip | 21 +- .../BurnWithFromMintTokenPoolAndProxy.sol | 69 + .../ccip/test/legacy/TokenPoolAndProxy.t.sol | 14 + ...urn_with_from_mint_token_pool_and_proxy.go | 3010 +++++++++++++++++ ...rapper-dependency-versions-do-not-edit.txt | 1 + core/gethwrappers/ccip/go_generate.go | 32 +- 7 files changed, 3126 insertions(+), 26 deletions(-) create mode 100644 contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPoolAndProxy.sol create mode 100644 core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool_and_proxy/burn_with_from_mint_token_pool_and_proxy.go diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 75116d10fc..c1d6eff19b 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -900,8 +900,9 @@ TokenAdminRegistry_setPool:test_setPool_Success() (gas: 35943) TokenAdminRegistry_setPool:test_setPool_ZeroAddressRemovesPool_Success() (gas: 30617) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_OnlyAdministrator_Revert() (gas: 18043) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_Success() (gas: 49390) -TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6064542) -TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6310931) +TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6064586) +TokenPoolAndProxy:test_lockOrBurn_burnWithFromMint_Success() (gas: 6096059) +TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6310909) TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6908121) TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7092212) TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2209837) diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index 7ba49f87dd..0af6d84400 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -63,14 +63,6 @@ compileContract ccip/CommitStore.sol compileContract ccip/MultiAggregateRateLimiter.sol compileContract ccip/Router.sol compileContract ccip/PriceRegistry.sol -compileContract ccip/pools/LockReleaseTokenPool.sol -compileContract ccip/pools/BurnMintTokenPool.sol -compileContract ccip/pools/BurnFromMintTokenPool.sol -compileContract ccip/pools/BurnWithFromMintTokenPool.sol -compileContract ccip/pools/LockReleaseTokenPoolAndProxy.sol -compileContract ccip/pools/BurnMintTokenPoolAndProxy.sol -compileContract ccip/pools/TokenPool.sol -compileContract shared/token/ERC677/BurnMintERC677.sol compileContract ccip/RMN.sol compileContract ccip/ARMProxy.sol compileContract ccip/tokenAdminRegistry/TokenAdminRegistry.sol @@ -78,6 +70,19 @@ compileContract ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol compileContract ccip/capability/CCIPConfig.sol compileContract ccip/capability/interfaces/IOCR3ConfigEncoder.sol compileContract ccip/NonceManager.sol +compileContract shared/token/ERC677/BurnMintERC677.sol + + +# Pools +compileContract ccip/pools/LockReleaseTokenPool.sol +compileContract ccip/pools/BurnMintTokenPool.sol +compileContract ccip/pools/BurnFromMintTokenPool.sol +compileContract ccip/pools/BurnWithFromMintTokenPool.sol +compileContract ccip/pools/LockReleaseTokenPoolAndProxy.sol +compileContract ccip/pools/BurnMintTokenPoolAndProxy.sol +compileContract ccip/pools/BurnWithFromMintTokenPoolAndProxy.sol +compileContract ccip/pools/TokenPool.sol + # Test helpers compileContract ccip/test/helpers/BurnMintERC677Helper.sol diff --git a/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPoolAndProxy.sol b/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPoolAndProxy.sol new file mode 100644 index 0000000000..7890d85824 --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPoolAndProxy.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IBurnMintERC20} from "../../shared/token/ERC20/IBurnMintERC20.sol"; + +import {Pool} from "../libraries/Pool.sol"; +import {LegacyPoolWrapper} from "./LegacyPoolWrapper.sol"; + +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +contract BurnWithFromMintTokenPoolAndProxy is ITypeAndVersion, LegacyPoolWrapper { + using SafeERC20 for IBurnMintERC20; + + string public constant override typeAndVersion = "BurnFromMintTokenPoolAndProxy 1.5.0"; + + constructor( + IBurnMintERC20 token, + address[] memory allowlist, + address rmnProxy, + address router + ) LegacyPoolWrapper(token, allowlist, rmnProxy, router) { + // Some tokens allow burning from the sender without approval, but not all do. + // To be safe, we approve the pool to burn from the pool. + token.safeIncreaseAllowance(address(this), type(uint256).max); + } + + /// @notice Burn the token in the pool + /// @dev The _validateLockOrBurn check is an essential security check + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + external + virtual + override + returns (Pool.LockOrBurnOutV1 memory) + { + _validateLockOrBurn(lockOrBurnIn); + + if (!_hasLegacyPool()) { + IBurnMintERC20(address(i_token)).burnFrom(address(this), lockOrBurnIn.amount); + } else { + _lockOrBurnLegacy(lockOrBurnIn); + } + + emit Burned(msg.sender, lockOrBurnIn.amount); + + return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); + } + + /// @notice Mint tokens from the pool to the recipient + /// @dev The _validateReleaseOrMint check is an essential security check + function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + external + virtual + override + returns (Pool.ReleaseOrMintOutV1 memory) + { + _validateReleaseOrMint(releaseOrMintIn); + + if (!_hasLegacyPool()) { + IBurnMintERC20(address(i_token)).mint(releaseOrMintIn.receiver, releaseOrMintIn.amount); + } else { + _releaseOrMintLegacy(releaseOrMintIn); + } + + emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); + + return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + } +} diff --git a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol index 1df73ff582..d743b4c9e1 100644 --- a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol +++ b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol @@ -11,6 +11,7 @@ import {Client} from "../../libraries/Client.sol"; import {Pool} from "../../libraries/Pool.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {BurnMintTokenPoolAndProxy} from "../../pools/BurnMintTokenPoolAndProxy.sol"; +import {BurnWithFromMintTokenPoolAndProxy} from "../../pools/BurnWithFromMintTokenPoolAndProxy.sol"; import {LockReleaseTokenPoolAndProxy} from "../../pools/LockReleaseTokenPoolAndProxy.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; import {TokenSetup} from "../TokenSetup.t.sol"; @@ -362,6 +363,19 @@ contract TokenPoolAndProxy is EVM2EVMOnRampSetup { _assertReleaseOrMintCorrect(); } + function test_lockOrBurn_burnWithFromMint_Success() public { + s_pool = + new BurnWithFromMintTokenPoolAndProxy(s_token, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + _configurePool(); + _deployOldPool(); + _assertLockOrBurnCorrect(); + + vm.startPrank(OWNER); + BurnMintTokenPoolAndProxy(address(s_pool)).setPreviousPool(IPoolPriorTo1_5(address(0))); + + _assertReleaseOrMintCorrect(); + } + function test_lockOrBurn_lockRelease_Success() public { s_pool = new LockReleaseTokenPoolAndProxy(s_token, new address[](0), address(s_mockRMN), false, address(s_sourceRouter)); diff --git a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool_and_proxy/burn_with_from_mint_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool_and_proxy/burn_with_from_mint_token_pool_and_proxy.go new file mode 100644 index 0000000000..19b596a01d --- /dev/null +++ b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool_and_proxy/burn_with_from_mint_token_pool_and_proxy.go @@ -0,0 +1,3010 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package burn_with_from_mint_token_pool_and_proxy + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type PoolLockOrBurnInV1 struct { + Receiver []byte + RemoteChainSelector uint64 + OriginalSender common.Address + Amount *big.Int + LocalToken common.Address +} + +type PoolLockOrBurnOutV1 struct { + DestTokenAddress []byte + DestPoolData []byte +} + +type PoolReleaseOrMintInV1 struct { + OriginalSender []byte + RemoteChainSelector uint64 + Receiver common.Address + Amount *big.Int + LocalToken common.Address + SourcePoolAddress []byte + SourcePoolData []byte + OffchainTokenData []byte +} + +type PoolReleaseOrMintOutV1 struct { + DestinationAmount *big.Int +} + +type RateLimiterConfig struct { + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type RateLimiterTokenBucket struct { + Tokens *big.Int + LastUpdated uint32 + IsEnabled bool + Capacity *big.Int + Rate *big.Int +} + +type TokenPoolChainUpdate struct { + RemoteChainSelector uint64 + Allowed bool + RemotePoolAddress []byte + RemoteTokenAddress []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig +} + +var BurnWithFromMintTokenPoolAndProxyMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b5060405162004db138038062004db18339810160408190526200003491620008cc565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200019b565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000246565b50620001919650506001600160a01b038a169450309350600019925050620003a39050565b5050505062000b08565b336001600160a01b03821603620001f55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000267576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002f25760008382815181106200028b576200028b620009dc565b60209081029190910101519050620002a560028262000489565b15620002e8576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200026a565b5060005b81518110156200039e576000828281518110620003175762000317620009dc565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000343575062000395565b62000350600282620004a9565b1562000393576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002f6565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200041b9190620009f2565b62000427919062000a22565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200048391869190620004c016565b50505050565b6000620004a0836001600160a01b03841662000591565b90505b92915050565b6000620004a0836001600160a01b03841662000695565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200050f906001600160a01b038516908490620006e7565b8051909150156200039e578080602001905181019062000530919062000a38565b6200039e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016200008a565b600081815260018301602052604081205480156200068a576000620005b860018362000a63565b8554909150600090620005ce9060019062000a63565b90508082146200063a576000866000018281548110620005f257620005f2620009dc565b9060005260206000200154905080876000018481548110620006185762000618620009dc565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200064e576200064e62000a79565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004a3565b6000915050620004a3565b6000818152600183016020526040812054620006de57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004a3565b506000620004a3565b6060620006f8848460008562000700565b949350505050565b606082471015620007635760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016200008a565b600080866001600160a01b0316858760405162000781919062000ab5565b60006040518083038185875af1925050503d8060008114620007c0576040519150601f19603f3d011682016040523d82523d6000602084013e620007c5565b606091505b509092509050620007d987838387620007e4565b979650505050505050565b606083156200085857825160000362000850576001600160a01b0385163b620008505760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016200008a565b5081620006f8565b620006f883838151156200086f5781518083602001fd5b8060405162461bcd60e51b81526004016200008a919062000ad3565b6001600160a01b0381168114620008a157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008c7816200088b565b919050565b60008060008060808587031215620008e357600080fd5b8451620008f0816200088b565b602086810151919550906001600160401b03808211156200091057600080fd5b818801915088601f8301126200092557600080fd5b8151818111156200093a576200093a620008a4565b8060051b604051601f19603f83011681018181108582111715620009625762000962620008a4565b60405291825284820192508381018501918b8311156200098157600080fd5b938501935b82851015620009aa576200099a85620008ba565b8452938501939285019262000986565b809850505050505050620009c160408601620008ba565b9150620009d160608601620008ba565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a0557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620004a357620004a362000a0c565b60006020828403121562000a4b57600080fd5b8151801515811462000a5c57600080fd5b9392505050565b81810381811115620004a357620004a362000a0c565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aac57818101518382015260200162000a92565b50506000910152565b6000825162000ac981846020870162000a8f565b9190910192915050565b602081526000825180602084015262000af481604085016020870162000a8f565b601f01601f19169190910160400192915050565b60805160a05160c05161422562000b8c6000396000818161050301528181611aad01526124ff0152600081816104dd015281816118400152611d600152600081816102260152818161027b0152818161073f01528181610dcb0152818161176001528181611c8001528181611e660152818161249501526126ea01526142256000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639766b93211610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104c8578063dc0bd971146104db578063e0351e1314610501578063f2fde38b1461052757600080fd5b8063c0d786551461047a578063c4bffe2b1461048d578063c75eea9c146104a2578063cf7401f3146104b557600080fd5b8063a8d87a3b116100de578063a8d87a3b146103c7578063af58d59f146103da578063b0f479a114610449578063b79465801461046757600080fd5b80639766b9321461037f5780639a4575b914610392578063a7cd63b7146103b257600080fd5b80636d3d1a58116101715780637d54534e1161014b5780637d54534e1461032857806383826b2b1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b80636d3d1a58146102ef57806378a010b21461030d57806379ba50971461032057600080fd5b806321df0da7116101ad57806321df0da714610224578063240028e81461026b57806339077537146102b857806354c8a4f3146102da57600080fd5b806301ffc9a7146101d45780630a2fd493146101fc578063181f5a771461021c575b600080fd5b6101e76101e2366004613197565b61053a565b60405190151581526020015b60405180910390f35b61020f61020a3660046131f6565b61061f565b6040516101f3919061327f565b61020f6106cf565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e76102793660046132bf565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102cb6102c63660046132dc565b6106eb565b604051905181526020016101f3565b6102ed6102e8366004613364565b6108a3565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61031b3660046133d0565b61091e565b6102ed610a92565b6102ed6103363660046132bf565b610b8f565b6101e7610349366004613453565b610bde565b6101e761035c3660046131f6565b610cab565b60005473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61038d3660046132bf565b610cc2565b6103a56103a036600461348a565b610d51565b6040516101f391906134c5565b6103ba610ec7565b6040516101f39190613525565b6102466103d53660046131f6565b503090565b6103ed6103e83660046131f6565b610ed8565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610246565b61020f6104753660046131f6565b610fad565b6102ed6104883660046132bf565b610fd8565b6104956110ac565b6040516101f3919061357f565b6103ed6104b03660046131f6565b611164565b6102ed6104c3366004613736565b611236565b6102ed6104d636600461377b565b6112bf565b7f0000000000000000000000000000000000000000000000000000000000000000610246565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b6102ed6105353660046132bf565b611745565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105cd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061061957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061064a906137bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610676906137bd565b80156106c35780601f10610698576101008083540402835291602001916106c3565b820191906000526020600020905b8154815290600101906020018083116106a657829003601f168201915b50505050509050919050565b6040518060600160405280602381526020016141f66023913981565b60408051602081019091526000815261070b610706836138ac565b611759565b60095473ffffffffffffffffffffffffffffffffffffffff166108015773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961077460608501604086016132bf565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b1580156107e457600080fd5b505af11580156107f8573d6000803e3d6000fd5b50505050610812565b61081261080d836138ac565b61198a565b61082260608301604084016132bf565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161088491815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108ab611a28565b61091884848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611aab92505050565b50505050565b610926611a28565b61092f83610cab565b610976576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461099d906137bd565b80601f01602080910402602001604051908101604052809291908181526020018280546109c9906137bd565b8015610a165780601f106109eb57610100808354040283529160200191610a16565b820191906000526020600020905b8154815290600101906020018083116109f957829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a458385836139f1565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a8493929190613b0b565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161096d565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b97611a28565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610ca45750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca49190613b6f565b9392505050565b6000610619600567ffffffffffffffff8416611c61565b610cca611a28565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d76610d7183613b8c565b611c79565b60095473ffffffffffffffffffffffffffffffffffffffff16610e41576040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015610e2457600080fd5b505af1158015610e38573d6000803e3d6000fd5b50505050610e52565b610e52610e4d83613b8c565b611e43565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610eac84602001602081019061047591906131f6565b81526040805160208181019092526000815291015292915050565b6060610ed36002611f5d565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261061990611f6a565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061064a906137bd565b610fe0611a28565b73ffffffffffffffffffffffffffffffffffffffff811661102d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d45565b606060006110ba6005611f5d565b90506000815167ffffffffffffffff8111156110d8576110d86135c1565b604051908082528060200260200182016040528015611101578160200160208202803683370190505b50905060005b825181101561115d5782818151811061112257611122613c2e565b602002602001015182828151811061113c5761113c613c2e565b67ffffffffffffffff90921660209283029190910190910152600101611107565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261061990611f6a565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611276575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112af576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161096d565b6112ba83838361201c565b505050565b6112c7611a28565b60005b818110156112ba5760008383838181106112e6576112e6613c2e565b90506020028101906112f89190613c5d565b61130190613c9b565b90506113168160800151826020015115612106565b6113298160a00151826020015115612106565b80602001511561162557805161134b9060059067ffffffffffffffff1661223f565b6113905780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161096d565b60408101515115806113a55750606081015151155b156113dc576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115bd9082613d4f565b50606082015160058201906115d29082613d4f565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116189493929190613e69565b60405180910390a161173c565b805161163d9060059067ffffffffffffffff1661224b565b6116825780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161096d565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116eb6004830182613149565b6116f9600583016000613149565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112ca565b61174d611a28565b61175681612257565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146117ee5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161096d565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561189c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118c09190613b6f565b156118f7576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611904816020015161234c565b6000611913826020015161061f565b9050805160001480611937575080805190602001208260a001518051906020012014155b15611974578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161096d919061327f565b61198682602001518360600151612472565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad6946119f39490939291600401613f02565b600060405180830381600087803b158015611a0d57600080fd5b505af1158015611a21573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611aa9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161096d565b565b7f0000000000000000000000000000000000000000000000000000000000000000611b02576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611b98576000838281518110611b2257611b22613c2e565b60200260200101519050611b408160026124b990919063ffffffff16565b15611b8f5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611b05565b5060005b81518110156112ba576000828281518110611bb957611bb9613c2e565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bfd5750611c59565b611c086002826124db565b15611c575760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611b9c565b60008181526001830160205260408120541515610ca4565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611d0e5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161096d565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611dbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de09190613b6f565b15611e17576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e2481604001516124fd565b611e31816020015161257c565b611756816020015182606001516126ca565b6009546060820151611e909173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081169291169061270e565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611ef894939291600401613f63565b6000604051808303816000875af1158015611f17573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119869190810190613fc3565b60606000610ca48361279b565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611ff882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611fdc9190614060565b85608001516fffffffffffffffffffffffffffffffff166127f6565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61202583610cab565b612067576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161096d565b612072826000612106565b67ffffffffffffffff831660009081526007602052604090206120959083612820565b6120a0816000612106565b67ffffffffffffffff831660009081526007602052604090206120c69060020182612820565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516120f993929190614073565b60405180910390a1505050565b8151156121cd5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061215c575060408201516fffffffffffffffffffffffffffffffff16155b1561219557816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161096d91906140f6565b8015611986576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612206575060208201516fffffffffffffffffffffffffffffffff1615155b1561198657816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161096d91906140f6565b6000610ca483836129c2565b6000610ca48383612a11565b3373ffffffffffffffffffffffffffffffffffffffff8216036122d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161096d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61235581610cab565b612397576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161096d565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243a9190613b6f565b611756576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161096d565b67ffffffffffffffff8216600090815260076020526040902061198690600201827f0000000000000000000000000000000000000000000000000000000000000000612b04565b6000610ca48373ffffffffffffffffffffffffffffffffffffffff8416612a11565b6000610ca48373ffffffffffffffffffffffffffffffffffffffff84166129c2565b7f0000000000000000000000000000000000000000000000000000000000000000156117565761252e600282612e87565b611756576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161096d565b61258581610cab565b6125c7576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161096d565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612640573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126649190614132565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611756576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161096d565b67ffffffffffffffff8216600090815260076020526040902061198690827f0000000000000000000000000000000000000000000000000000000000000000612b04565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526112ba908490612eb6565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106c357602002820191906000526020600020905b8154815260200190600101908083116127d75750505050509050919050565b600061281585612806848661414f565b6128109087614166565b612fc2565b90505b949350505050565b815460009061284990700100000000000000000000000000000000900463ffffffff1642614060565b905080156128eb5760018301548354612891916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166127f6565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612911916fffffffffffffffffffffffffffffffff9081169116612fc2565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906120f99084906140f6565b6000818152600183016020526040812054612a0957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610619565b506000610619565b60008181526001830160205260408120548015612afa576000612a35600183614060565b8554909150600090612a4990600190614060565b9050808214612aae576000866000018281548110612a6957612a69613c2e565b9060005260206000200154905080876000018481548110612a8c57612a8c613c2e565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612abf57612abf614179565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610619565b6000915050610619565b825474010000000000000000000000000000000000000000900460ff161580612b2b575081155b15612b3557505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612b7b90700100000000000000000000000000000000900463ffffffff1642614060565b90508015612c3b5781831115612bbd576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612bf79083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166127f6565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612cf25773ffffffffffffffffffffffffffffffffffffffff8416612c9a576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161096d565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161096d565b84831015612e055760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612d369082614060565b612d40878a614060565b612d4a9190614166565b612d5491906141a8565b905073ffffffffffffffffffffffffffffffffffffffff8616612dad576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161096d565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161096d565b612e0f8584614060565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610ca4565b6000612f18826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612fd89092919063ffffffff16565b8051909150156112ba5780806020019051810190612f369190613b6f565b6112ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161096d565b6000818310612fd15781610ca4565b5090919050565b60606128188484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161300c91906141e3565b60006040518083038185875af1925050503d8060008114613049576040519150601f19603f3d011682016040523d82523d6000602084013e61304e565b606091505b509150915061305f8783838761306a565b979650505050505050565b606083156131005782516000036130f95773ffffffffffffffffffffffffffffffffffffffff85163b6130f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161096d565b5081612818565b61281883838151156131155781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096d919061327f565b508054613155906137bd565b6000825580601f10613165575050565b601f01602090049060005260206000209081019061175691905b80821115613193576000815560010161317f565b5090565b6000602082840312156131a957600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ca457600080fd5b803567ffffffffffffffff811681146131f157600080fd5b919050565b60006020828403121561320857600080fd5b610ca4826131d9565b60005b8381101561322c578181015183820152602001613214565b50506000910152565b6000815180845261324d816020860160208601613211565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ca46020830184613235565b73ffffffffffffffffffffffffffffffffffffffff8116811461175657600080fd5b80356131f181613292565b6000602082840312156132d157600080fd5b8135610ca481613292565b6000602082840312156132ee57600080fd5b813567ffffffffffffffff81111561330557600080fd5b82016101008185031215610ca457600080fd5b60008083601f84011261332a57600080fd5b50813567ffffffffffffffff81111561334257600080fd5b6020830191508360208260051b850101111561335d57600080fd5b9250929050565b6000806000806040858703121561337a57600080fd5b843567ffffffffffffffff8082111561339257600080fd5b61339e88838901613318565b909650945060208701359150808211156133b757600080fd5b506133c487828801613318565b95989497509550505050565b6000806000604084860312156133e557600080fd5b6133ee846131d9565b9250602084013567ffffffffffffffff8082111561340b57600080fd5b818601915086601f83011261341f57600080fd5b81358181111561342e57600080fd5b87602082850101111561344057600080fd5b6020830194508093505050509250925092565b6000806040838503121561346657600080fd5b61346f836131d9565b9150602083013561347f81613292565b809150509250929050565b60006020828403121561349c57600080fd5b813567ffffffffffffffff8111156134b357600080fd5b820160a08185031215610ca457600080fd5b6020815260008251604060208401526134e16060840182613235565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261351c8282613235565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561357357835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613541565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561357357835167ffffffffffffffff168352928401929184019160010161359b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613614576136146135c1565b60405290565b60405160c0810167ffffffffffffffff81118282101715613614576136146135c1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613684576136846135c1565b604052919050565b801515811461175657600080fd5b80356131f18161368c565b80356fffffffffffffffffffffffffffffffff811681146131f157600080fd5b6000606082840312156136d757600080fd5b6040516060810181811067ffffffffffffffff821117156136fa576136fa6135c1565b604052905080823561370b8161368c565b8152613719602084016136a5565b602082015261372a604084016136a5565b60408201525092915050565b600080600060e0848603121561374b57600080fd5b613754846131d9565b925061376385602086016136c5565b915061377285608086016136c5565b90509250925092565b6000806020838503121561378e57600080fd5b823567ffffffffffffffff8111156137a557600080fd5b6137b185828601613318565b90969095509350505050565b600181811c908216806137d157607f821691505b60208210810361380a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff82111561382a5761382a6135c1565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261386757600080fd5b813561387a61387582613810565b61363d565b81815284602083860101111561388f57600080fd5b816020850160208301376000918101602001919091529392505050565b600061010082360312156138bf57600080fd5b6138c76135f0565b823567ffffffffffffffff808211156138df57600080fd5b6138eb36838701613856565b83526138f9602086016131d9565b602084015261390a604086016132b4565b604084015260608501356060840152613925608086016132b4565b608084015260a085013591508082111561393e57600080fd5b61394a36838701613856565b60a084015260c085013591508082111561396357600080fd5b61396f36838701613856565b60c084015260e085013591508082111561398857600080fd5b5061399536828601613856565b60e08301525092915050565b601f8211156112ba576000816000526020600020601f850160051c810160208610156139ca5750805b601f850160051c820191505b818110156139e9578281556001016139d6565b505050505050565b67ffffffffffffffff831115613a0957613a096135c1565b613a1d83613a1783546137bd565b836139a1565b6000601f841160018114613a6f5760008515613a395750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a21565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613abe5786850135825560209485019460019092019101613a9e565b5086821015613af9577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613b1e6040830186613235565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613b8157600080fd5b8151610ca48161368c565b600060a08236031215613b9e57600080fd5b60405160a0810167ffffffffffffffff8282108183111715613bc257613bc26135c1565b816040528435915080821115613bd757600080fd5b50613be436828601613856565b825250613bf3602084016131d9565b60208201526040830135613c0681613292565b6040820152606083810135908201526080830135613c2381613292565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613c9157600080fd5b9190910192915050565b60006101408236031215613cae57600080fd5b613cb661361a565b613cbf836131d9565b8152613ccd6020840161369a565b6020820152604083013567ffffffffffffffff80821115613ced57600080fd5b613cf936838701613856565b60408401526060850135915080821115613d1257600080fd5b50613d1f36828601613856565b606083015250613d3236608085016136c5565b6080820152613d443660e085016136c5565b60a082015292915050565b815167ffffffffffffffff811115613d6957613d696135c1565b613d7d81613d7784546137bd565b846139a1565b602080601f831160018114613dd05760008415613d9a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139e9565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e1d57888601518255948401946001909101908401613dfe565b5085821015613e5957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613e8d81840187613235565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613ecb9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e083015261351c565b60a081526000613f1560a0830187613235565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613f9260a0830186613235565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613fd557600080fd5b815167ffffffffffffffff811115613fec57600080fd5b8201601f81018413613ffd57600080fd5b805161400b61387582613810565b81815285602083850101111561402057600080fd5b61351c826020830160208601613211565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561061957610619614031565b67ffffffffffffffff8416815260e081016140bf60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612818565b6060810161061982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561414457600080fd5b8151610ca481613292565b808202811582820484141761061957610619614031565b8082018082111561061957610619614031565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826141de577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613c9181846020870161321156fe4275726e46726f6d4d696e74546f6b656e506f6f6c416e6450726f787920312e352e30a164736f6c6343000818000a", +} + +var BurnWithFromMintTokenPoolAndProxyABI = BurnWithFromMintTokenPoolAndProxyMetaData.ABI + +var BurnWithFromMintTokenPoolAndProxyBin = BurnWithFromMintTokenPoolAndProxyMetaData.Bin + +func DeployBurnWithFromMintTokenPoolAndProxy(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, rmnProxy common.Address, router common.Address) (common.Address, *types.Transaction, *BurnWithFromMintTokenPoolAndProxy, error) { + parsed, err := BurnWithFromMintTokenPoolAndProxyMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnWithFromMintTokenPoolAndProxyBin), backend, token, allowlist, rmnProxy, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &BurnWithFromMintTokenPoolAndProxy{address: address, abi: *parsed, BurnWithFromMintTokenPoolAndProxyCaller: BurnWithFromMintTokenPoolAndProxyCaller{contract: contract}, BurnWithFromMintTokenPoolAndProxyTransactor: BurnWithFromMintTokenPoolAndProxyTransactor{contract: contract}, BurnWithFromMintTokenPoolAndProxyFilterer: BurnWithFromMintTokenPoolAndProxyFilterer{contract: contract}}, nil +} + +type BurnWithFromMintTokenPoolAndProxy struct { + address common.Address + abi abi.ABI + BurnWithFromMintTokenPoolAndProxyCaller + BurnWithFromMintTokenPoolAndProxyTransactor + BurnWithFromMintTokenPoolAndProxyFilterer +} + +type BurnWithFromMintTokenPoolAndProxyCaller struct { + contract *bind.BoundContract +} + +type BurnWithFromMintTokenPoolAndProxyTransactor struct { + contract *bind.BoundContract +} + +type BurnWithFromMintTokenPoolAndProxyFilterer struct { + contract *bind.BoundContract +} + +type BurnWithFromMintTokenPoolAndProxySession struct { + Contract *BurnWithFromMintTokenPoolAndProxy + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type BurnWithFromMintTokenPoolAndProxyCallerSession struct { + Contract *BurnWithFromMintTokenPoolAndProxyCaller + CallOpts bind.CallOpts +} + +type BurnWithFromMintTokenPoolAndProxyTransactorSession struct { + Contract *BurnWithFromMintTokenPoolAndProxyTransactor + TransactOpts bind.TransactOpts +} + +type BurnWithFromMintTokenPoolAndProxyRaw struct { + Contract *BurnWithFromMintTokenPoolAndProxy +} + +type BurnWithFromMintTokenPoolAndProxyCallerRaw struct { + Contract *BurnWithFromMintTokenPoolAndProxyCaller +} + +type BurnWithFromMintTokenPoolAndProxyTransactorRaw struct { + Contract *BurnWithFromMintTokenPoolAndProxyTransactor +} + +func NewBurnWithFromMintTokenPoolAndProxy(address common.Address, backend bind.ContractBackend) (*BurnWithFromMintTokenPoolAndProxy, error) { + abi, err := abi.JSON(strings.NewReader(BurnWithFromMintTokenPoolAndProxyABI)) + if err != nil { + return nil, err + } + contract, err := bindBurnWithFromMintTokenPoolAndProxy(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxy{address: address, abi: abi, BurnWithFromMintTokenPoolAndProxyCaller: BurnWithFromMintTokenPoolAndProxyCaller{contract: contract}, BurnWithFromMintTokenPoolAndProxyTransactor: BurnWithFromMintTokenPoolAndProxyTransactor{contract: contract}, BurnWithFromMintTokenPoolAndProxyFilterer: BurnWithFromMintTokenPoolAndProxyFilterer{contract: contract}}, nil +} + +func NewBurnWithFromMintTokenPoolAndProxyCaller(address common.Address, caller bind.ContractCaller) (*BurnWithFromMintTokenPoolAndProxyCaller, error) { + contract, err := bindBurnWithFromMintTokenPoolAndProxy(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyCaller{contract: contract}, nil +} + +func NewBurnWithFromMintTokenPoolAndProxyTransactor(address common.Address, transactor bind.ContractTransactor) (*BurnWithFromMintTokenPoolAndProxyTransactor, error) { + contract, err := bindBurnWithFromMintTokenPoolAndProxy(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyTransactor{contract: contract}, nil +} + +func NewBurnWithFromMintTokenPoolAndProxyFilterer(address common.Address, filterer bind.ContractFilterer) (*BurnWithFromMintTokenPoolAndProxyFilterer, error) { + contract, err := bindBurnWithFromMintTokenPoolAndProxy(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyFilterer{contract: contract}, nil +} + +func bindBurnWithFromMintTokenPoolAndProxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := BurnWithFromMintTokenPoolAndProxyMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnWithFromMintTokenPoolAndProxy.Contract.BurnWithFromMintTokenPoolAndProxyCaller.contract.Call(opts, result, method, params...) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.BurnWithFromMintTokenPoolAndProxyTransactor.contract.Transfer(opts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.BurnWithFromMintTokenPoolAndProxyTransactor.contract.Transact(opts, method, params...) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnWithFromMintTokenPoolAndProxy.Contract.contract.Call(opts, result, method, params...) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.contract.Transfer(opts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.contract.Transact(opts, method, params...) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetAllowList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getAllowList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetAllowList() ([]common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetAllowList(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetAllowList() ([]common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetAllowList(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetAllowListEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getAllowListEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetAllowListEnabled() (bool, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetAllowListEnabled(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetAllowListEnabled() (bool, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetAllowListEnabled(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getCurrentInboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetCurrentInboundRateLimiterState(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetCurrentInboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetCurrentInboundRateLimiterState(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getCurrentOutboundRateLimiterState", remoteChainSelector) + + if err != nil { + return *new(RateLimiterTokenBucket), err + } + + out0 := *abi.ConvertType(out[0], new(RateLimiterTokenBucket)).(*RateLimiterTokenBucket) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetCurrentOutboundRateLimiterState(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetCurrentOutboundRateLimiterState(remoteChainSelector uint64) (RateLimiterTokenBucket, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetCurrentOutboundRateLimiterState(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetOnRamp(opts *bind.CallOpts, arg0 uint64) (common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getOnRamp", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetOnRamp(arg0 uint64) (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetOnRamp(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, arg0) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetOnRamp(arg0 uint64) (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetOnRamp(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, arg0) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getRateLimitAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetRateLimitAdmin() (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetRateLimitAdmin(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetRateLimitAdmin() (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetRateLimitAdmin(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetRemotePool(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetRemotePool(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getRemoteToken", remoteChainSelector) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetRemoteToken(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetRemoteToken(remoteChainSelector uint64) ([]byte, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetRemoteToken(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetRmnProxy(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getRmnProxy") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetRmnProxy() (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetRmnProxy(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetRmnProxy() (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetRmnProxy(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getRouter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetRouter() (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetRouter(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetRouter() (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetRouter(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getSupportedChains") + + if err != nil { + return *new([]uint64), err + } + + out0 := *abi.ConvertType(out[0], new([]uint64)).(*[]uint64) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetSupportedChains() ([]uint64, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetSupportedChains(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetSupportedChains() ([]uint64, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetSupportedChains(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetToken() (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetToken(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetToken() (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetToken(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) IsOffRamp(opts *bind.CallOpts, sourceChainSelector uint64, offRamp common.Address) (bool, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "isOffRamp", sourceChainSelector, offRamp) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) IsOffRamp(sourceChainSelector uint64, offRamp common.Address) (bool, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.IsOffRamp(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, sourceChainSelector, offRamp) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) IsOffRamp(sourceChainSelector uint64, offRamp common.Address) (bool, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.IsOffRamp(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, sourceChainSelector, offRamp) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.IsSupportedChain(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) IsSupportedChain(remoteChainSelector uint64) (bool, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.IsSupportedChain(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, remoteChainSelector) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "isSupportedToken", token) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) IsSupportedToken(token common.Address) (bool, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.IsSupportedToken(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, token) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) IsSupportedToken(token common.Address) (bool, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.IsSupportedToken(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, token) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) Owner() (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.Owner(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) Owner() (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.Owner(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.SupportsInterface(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, interfaceId) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.SupportsInterface(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, interfaceId) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) TypeAndVersion() (string, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.TypeAndVersion(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) TypeAndVersion() (string, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.TypeAndVersion(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.contract.Transact(opts, "acceptOwnership") +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) AcceptOwnership() (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.AcceptOwnership(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.AcceptOwnership(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.contract.Transact(opts, "applyAllowListUpdates", removes, adds) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.ApplyAllowListUpdates(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, removes, adds) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorSession) ApplyAllowListUpdates(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.ApplyAllowListUpdates(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, removes, adds) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.contract.Transact(opts, "applyChainUpdates", chains) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.ApplyChainUpdates(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, chains) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.ApplyChainUpdates(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, chains) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.contract.Transact(opts, "lockOrBurn", lockOrBurnIn) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.LockOrBurn(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, lockOrBurnIn) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorSession) LockOrBurn(lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.LockOrBurn(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, lockOrBurnIn) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactor) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.contract.Transact(opts, "releaseOrMint", releaseOrMintIn) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.ReleaseOrMint(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, releaseOrMintIn) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorSession) ReleaseOrMint(releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.ReleaseOrMint(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, releaseOrMintIn) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.SetChainRateLimiterConfig(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorSession) SetChainRateLimiterConfig(remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.SetChainRateLimiterConfig(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactor) SetPreviousPool(opts *bind.TransactOpts, prevPool common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.contract.Transact(opts, "setPreviousPool", prevPool) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) SetPreviousPool(prevPool common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.SetPreviousPool(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, prevPool) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorSession) SetPreviousPool(prevPool common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.SetPreviousPool(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, prevPool) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.SetRateLimitAdmin(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, rateLimitAdmin) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorSession) SetRateLimitAdmin(rateLimitAdmin common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.SetRateLimitAdmin(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, rateLimitAdmin) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.SetRemotePool(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.SetRemotePool(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.contract.Transact(opts, "setRouter", newRouter) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.SetRouter(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, newRouter) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorSession) SetRouter(newRouter common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.SetRouter(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, newRouter) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.contract.Transact(opts, "transferOwnership", to) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.TransferOwnership(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, to) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.TransferOwnership(&_BurnWithFromMintTokenPoolAndProxy.TransactOpts, to) +} + +type BurnWithFromMintTokenPoolAndProxyAllowListAddIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyAllowListAdd + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyAllowListAddIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyAllowListAdd) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyAllowListAddIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyAllowListAddIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyAllowListAdd struct { + Sender common.Address + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterAllowListAdd(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyAllowListAddIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyAllowListAddIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "AllowListAdd", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyAllowListAdd) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "AllowListAdd") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyAllowListAdd) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseAllowListAdd(log types.Log) (*BurnWithFromMintTokenPoolAndProxyAllowListAdd, error) { + event := new(BurnWithFromMintTokenPoolAndProxyAllowListAdd) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "AllowListAdd", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyAllowListRemoveIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyAllowListRemove + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyAllowListRemoveIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyAllowListRemove) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyAllowListRemoveIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyAllowListRemoveIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyAllowListRemove struct { + Sender common.Address + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterAllowListRemove(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyAllowListRemoveIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyAllowListRemoveIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "AllowListRemove", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyAllowListRemove) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "AllowListRemove") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyAllowListRemove) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseAllowListRemove(log types.Log) (*BurnWithFromMintTokenPoolAndProxyAllowListRemove, error) { + event := new(BurnWithFromMintTokenPoolAndProxyAllowListRemove) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "AllowListRemove", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyBurnedIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyBurned + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyBurnedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyBurned) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyBurnedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyBurnedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyBurned struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnWithFromMintTokenPoolAndProxyBurnedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyBurnedIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "Burned", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyBurned, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "Burned", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyBurned) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "Burned", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseBurned(log types.Log) (*BurnWithFromMintTokenPoolAndProxyBurned, error) { + event := new(BurnWithFromMintTokenPoolAndProxyBurned) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "Burned", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyChainAddedIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyChainAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyChainAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyChainAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyChainAddedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyChainAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyChainAdded struct { + RemoteChainSelector uint64 + RemoteToken []byte + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterChainAdded(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyChainAddedIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyChainAddedIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "ChainAdded", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchChainAdded(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyChainAdded) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "ChainAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyChainAdded) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseChainAdded(log types.Log) (*BurnWithFromMintTokenPoolAndProxyChainAdded, error) { + event := new(BurnWithFromMintTokenPoolAndProxyChainAdded) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "ChainAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyChainConfiguredIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyChainConfigured + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyChainConfiguredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyChainConfigured) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyChainConfiguredIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyChainConfiguredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyChainConfigured struct { + RemoteChainSelector uint64 + OutboundRateLimiterConfig RateLimiterConfig + InboundRateLimiterConfig RateLimiterConfig + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterChainConfigured(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyChainConfiguredIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyChainConfiguredIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "ChainConfigured", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyChainConfigured) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "ChainConfigured") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyChainConfigured) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseChainConfigured(log types.Log) (*BurnWithFromMintTokenPoolAndProxyChainConfigured, error) { + event := new(BurnWithFromMintTokenPoolAndProxyChainConfigured) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "ChainConfigured", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyChainRemovedIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyChainRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyChainRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyChainRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyChainRemovedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyChainRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyChainRemoved struct { + RemoteChainSelector uint64 + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterChainRemoved(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyChainRemovedIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyChainRemovedIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "ChainRemoved", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyChainRemoved) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "ChainRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyChainRemoved) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseChainRemoved(log types.Log) (*BurnWithFromMintTokenPoolAndProxyChainRemoved, error) { + event := new(BurnWithFromMintTokenPoolAndProxyChainRemoved) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "ChainRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyConfigChangedIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyConfigChangedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyConfigChanged struct { + Config RateLimiterConfig + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyConfigChangedIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyConfigChangedIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyConfigChanged) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyConfigChanged) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseConfigChanged(log types.Log) (*BurnWithFromMintTokenPoolAndProxyConfigChanged, error) { + event := new(BurnWithFromMintTokenPoolAndProxyConfigChanged) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyLegacyPoolChangedIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyLegacyPoolChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyLegacyPoolChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyLegacyPoolChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyLegacyPoolChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyLegacyPoolChangedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyLegacyPoolChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyLegacyPoolChanged struct { + OldPool common.Address + NewPool common.Address + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterLegacyPoolChanged(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyLegacyPoolChangedIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "LegacyPoolChanged") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyLegacyPoolChangedIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "LegacyPoolChanged", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchLegacyPoolChanged(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyLegacyPoolChanged) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "LegacyPoolChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyLegacyPoolChanged) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "LegacyPoolChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseLegacyPoolChanged(log types.Log) (*BurnWithFromMintTokenPoolAndProxyLegacyPoolChanged, error) { + event := new(BurnWithFromMintTokenPoolAndProxyLegacyPoolChanged) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "LegacyPoolChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyLockedIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyLocked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyLockedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyLockedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyLocked struct { + Sender common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnWithFromMintTokenPoolAndProxyLockedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyLockedIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "Locked", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyLocked, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "Locked", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyLocked) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "Locked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseLocked(log types.Log) (*BurnWithFromMintTokenPoolAndProxyLocked, error) { + event := new(BurnWithFromMintTokenPoolAndProxyLocked) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "Locked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyMintedIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyMinted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyMintedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyMintedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnWithFromMintTokenPoolAndProxyMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyMintedIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "Minted", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "Minted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyMinted) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "Minted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseMinted(log types.Log) (*BurnWithFromMintTokenPoolAndProxyMinted, error) { + event := new(BurnWithFromMintTokenPoolAndProxyMinted) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "Minted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequestedIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequestedIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequested) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseOwnershipTransferRequested(log types.Log) (*BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequested, error) { + event := new(BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequested) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyOwnershipTransferredIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnWithFromMintTokenPoolAndProxyOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyOwnershipTransferredIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyOwnershipTransferred) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseOwnershipTransferred(log types.Log) (*BurnWithFromMintTokenPoolAndProxyOwnershipTransferred, error) { + event := new(BurnWithFromMintTokenPoolAndProxyOwnershipTransferred) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyReleasedIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyReleased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyReleasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyReleased) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyReleasedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyReleasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyReleased struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnWithFromMintTokenPoolAndProxyReleasedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyReleasedIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "Released", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "Released", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyReleased) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "Released", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseReleased(log types.Log) (*BurnWithFromMintTokenPoolAndProxyReleased, error) { + event := new(BurnWithFromMintTokenPoolAndProxyReleased) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "Released", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyRemotePoolSetIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyRemotePoolSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyRemotePoolSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyRemotePoolSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyRemotePoolSetIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyRemotePoolSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyRemotePoolSet struct { + RemoteChainSelector uint64 + PreviousPoolAddress []byte + RemotePoolAddress []byte + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnWithFromMintTokenPoolAndProxyRemotePoolSetIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyRemotePoolSetIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyRemotePoolSet) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseRemotePoolSet(log types.Log) (*BurnWithFromMintTokenPoolAndProxyRemotePoolSet, error) { + event := new(BurnWithFromMintTokenPoolAndProxyRemotePoolSet) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyRouterUpdatedIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyRouterUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyRouterUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyRouterUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyRouterUpdatedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyRouterUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyRouterUpdated struct { + OldRouter common.Address + NewRouter common.Address + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterRouterUpdated(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyRouterUpdatedIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyRouterUpdatedIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "RouterUpdated", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyRouterUpdated) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "RouterUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyRouterUpdated) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseRouterUpdated(log types.Log) (*BurnWithFromMintTokenPoolAndProxyRouterUpdated, error) { + event := new(BurnWithFromMintTokenPoolAndProxyRouterUpdated) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "RouterUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolAndProxyTokensConsumedIterator struct { + Event *BurnWithFromMintTokenPoolAndProxyTokensConsumed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolAndProxyTokensConsumedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolAndProxyTokensConsumed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BurnWithFromMintTokenPoolAndProxyTokensConsumedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolAndProxyTokensConsumedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolAndProxyTokensConsumed struct { + Tokens *big.Int + Raw types.Log +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) FilterTokensConsumed(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyTokensConsumedIterator, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.FilterLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolAndProxyTokensConsumedIterator{contract: _BurnWithFromMintTokenPoolAndProxy.contract, event: "TokensConsumed", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyTokensConsumed) (event.Subscription, error) { + + logs, sub, err := _BurnWithFromMintTokenPoolAndProxy.contract.WatchLogs(opts, "TokensConsumed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolAndProxyTokensConsumed) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyFilterer) ParseTokensConsumed(log types.Log) (*BurnWithFromMintTokenPoolAndProxyTokensConsumed, error) { + event := new(BurnWithFromMintTokenPoolAndProxyTokensConsumed) + if err := _BurnWithFromMintTokenPoolAndProxy.contract.UnpackLog(event, "TokensConsumed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxy) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["AllowListAdd"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseAllowListAdd(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["AllowListRemove"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseAllowListRemove(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["Burned"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseBurned(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["ChainAdded"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseChainAdded(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["ChainConfigured"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseChainConfigured(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["ChainRemoved"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseChainRemoved(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["ConfigChanged"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseConfigChanged(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["LegacyPoolChanged"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseLegacyPoolChanged(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["Locked"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseLocked(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["Minted"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseMinted(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["OwnershipTransferRequested"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseOwnershipTransferRequested(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["OwnershipTransferred"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseOwnershipTransferred(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["Released"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseReleased(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["RemotePoolSet"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseRemotePoolSet(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["RouterUpdated"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseRouterUpdated(log) + case _BurnWithFromMintTokenPoolAndProxy.abi.Events["TokensConsumed"].ID: + return _BurnWithFromMintTokenPoolAndProxy.ParseTokensConsumed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (BurnWithFromMintTokenPoolAndProxyAllowListAdd) Topic() common.Hash { + return common.HexToHash("0x2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d8") +} + +func (BurnWithFromMintTokenPoolAndProxyAllowListRemove) Topic() common.Hash { + return common.HexToHash("0x800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf7566") +} + +func (BurnWithFromMintTokenPoolAndProxyBurned) Topic() common.Hash { + return common.HexToHash("0x696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7") +} + +func (BurnWithFromMintTokenPoolAndProxyChainAdded) Topic() common.Hash { + return common.HexToHash("0x8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2") +} + +func (BurnWithFromMintTokenPoolAndProxyChainConfigured) Topic() common.Hash { + return common.HexToHash("0x0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b") +} + +func (BurnWithFromMintTokenPoolAndProxyChainRemoved) Topic() common.Hash { + return common.HexToHash("0x5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916") +} + +func (BurnWithFromMintTokenPoolAndProxyConfigChanged) Topic() common.Hash { + return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") +} + +func (BurnWithFromMintTokenPoolAndProxyLegacyPoolChanged) Topic() common.Hash { + return common.HexToHash("0x81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f228") +} + +func (BurnWithFromMintTokenPoolAndProxyLocked) Topic() common.Hash { + return common.HexToHash("0x9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008") +} + +func (BurnWithFromMintTokenPoolAndProxyMinted) Topic() common.Hash { + return common.HexToHash("0x9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0") +} + +func (BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (BurnWithFromMintTokenPoolAndProxyOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (BurnWithFromMintTokenPoolAndProxyReleased) Topic() common.Hash { + return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") +} + +func (BurnWithFromMintTokenPoolAndProxyRemotePoolSet) Topic() common.Hash { + return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +} + +func (BurnWithFromMintTokenPoolAndProxyRouterUpdated) Topic() common.Hash { + return common.HexToHash("0x02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684") +} + +func (BurnWithFromMintTokenPoolAndProxyTokensConsumed) Topic() common.Hash { + return common.HexToHash("0x1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a") +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxy) Address() common.Address { + return _BurnWithFromMintTokenPoolAndProxy.address +} + +type BurnWithFromMintTokenPoolAndProxyInterface interface { + GetAllowList(opts *bind.CallOpts) ([]common.Address, error) + + GetAllowListEnabled(opts *bind.CallOpts) (bool, error) + + GetCurrentInboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetCurrentOutboundRateLimiterState(opts *bind.CallOpts, remoteChainSelector uint64) (RateLimiterTokenBucket, error) + + GetOnRamp(opts *bind.CallOpts, arg0 uint64) (common.Address, error) + + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) + + GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + + GetRmnProxy(opts *bind.CallOpts) (common.Address, error) + + GetRouter(opts *bind.CallOpts) (common.Address, error) + + GetSupportedChains(opts *bind.CallOpts) ([]uint64, error) + + GetToken(opts *bind.CallOpts) (common.Address, error) + + IsOffRamp(opts *bind.CallOpts, sourceChainSelector uint64, offRamp common.Address) (bool, error) + + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) + + IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) + + ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + + LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) + + ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + + SetPreviousPool(opts *bind.TransactOpts, prevPool common.Address) (*types.Transaction, error) + + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) + + SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + + SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAllowListAdd(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyAllowListAddIterator, error) + + WatchAllowListAdd(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyAllowListAdd) (event.Subscription, error) + + ParseAllowListAdd(log types.Log) (*BurnWithFromMintTokenPoolAndProxyAllowListAdd, error) + + FilterAllowListRemove(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyAllowListRemoveIterator, error) + + WatchAllowListRemove(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyAllowListRemove) (event.Subscription, error) + + ParseAllowListRemove(log types.Log) (*BurnWithFromMintTokenPoolAndProxyAllowListRemove, error) + + FilterBurned(opts *bind.FilterOpts, sender []common.Address) (*BurnWithFromMintTokenPoolAndProxyBurnedIterator, error) + + WatchBurned(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyBurned, sender []common.Address) (event.Subscription, error) + + ParseBurned(log types.Log) (*BurnWithFromMintTokenPoolAndProxyBurned, error) + + FilterChainAdded(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyChainAddedIterator, error) + + WatchChainAdded(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyChainAdded) (event.Subscription, error) + + ParseChainAdded(log types.Log) (*BurnWithFromMintTokenPoolAndProxyChainAdded, error) + + FilterChainConfigured(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyChainConfiguredIterator, error) + + WatchChainConfigured(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyChainConfigured) (event.Subscription, error) + + ParseChainConfigured(log types.Log) (*BurnWithFromMintTokenPoolAndProxyChainConfigured, error) + + FilterChainRemoved(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyChainRemovedIterator, error) + + WatchChainRemoved(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyChainRemoved) (event.Subscription, error) + + ParseChainRemoved(log types.Log) (*BurnWithFromMintTokenPoolAndProxyChainRemoved, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*BurnWithFromMintTokenPoolAndProxyConfigChanged, error) + + FilterLegacyPoolChanged(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyLegacyPoolChangedIterator, error) + + WatchLegacyPoolChanged(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyLegacyPoolChanged) (event.Subscription, error) + + ParseLegacyPoolChanged(log types.Log) (*BurnWithFromMintTokenPoolAndProxyLegacyPoolChanged, error) + + FilterLocked(opts *bind.FilterOpts, sender []common.Address) (*BurnWithFromMintTokenPoolAndProxyLockedIterator, error) + + WatchLocked(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyLocked, sender []common.Address) (event.Subscription, error) + + ParseLocked(log types.Log) (*BurnWithFromMintTokenPoolAndProxyLocked, error) + + FilterMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnWithFromMintTokenPoolAndProxyMintedIterator, error) + + WatchMinted(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseMinted(log types.Log) (*BurnWithFromMintTokenPoolAndProxyMinted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*BurnWithFromMintTokenPoolAndProxyOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnWithFromMintTokenPoolAndProxyOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*BurnWithFromMintTokenPoolAndProxyOwnershipTransferred, error) + + FilterReleased(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*BurnWithFromMintTokenPoolAndProxyReleasedIterator, error) + + WatchReleased(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyReleased, sender []common.Address, recipient []common.Address) (event.Subscription, error) + + ParseReleased(log types.Log) (*BurnWithFromMintTokenPoolAndProxyReleased, error) + + FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnWithFromMintTokenPoolAndProxyRemotePoolSetIterator, error) + + WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolSet(log types.Log) (*BurnWithFromMintTokenPoolAndProxyRemotePoolSet, error) + + FilterRouterUpdated(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyRouterUpdatedIterator, error) + + WatchRouterUpdated(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyRouterUpdated) (event.Subscription, error) + + ParseRouterUpdated(log types.Log) (*BurnWithFromMintTokenPoolAndProxyRouterUpdated, error) + + FilterTokensConsumed(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolAndProxyTokensConsumedIterator, error) + + WatchTokensConsumed(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolAndProxyTokensConsumed) (event.Subscription, error) + + ParseTokensConsumed(log types.Log) (*BurnWithFromMintTokenPoolAndProxyTokensConsumed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 6fc9d043ff..c9562db7d9 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -5,6 +5,7 @@ burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 3e8e3358f0bb520af069a7d37ea625940a88461a54418b1d5925eabced8c74df burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 524c72699d2666cf3b3effecfe67441854f62f153baef209258c9a5562680fca burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6333d0314d0bd29e75ea5e05fe62a4516ade0c6db91c30b6f93645035db52ed8 +burn_with_from_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin 84a4d9f45c51c7ae87b32d42ddc15665c92aaa3de4672227448a9b766b15ef7c ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin a92a9ae55b235f47ac58af942e43a20dc7df31cfba9178c133e5b3e273816503 ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin fcced2263564f51b5bf086c221e813ec06a71d2bb2e246b4e28cd60098a6de6f commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin 274d87db70b643e00ab0a7e7845bb4b791f3b613bfc87708d33fc5a8369e2a41 diff --git a/core/gethwrappers/ccip/go_generate.go b/core/gethwrappers/ccip/go_generate.go index b53c6c358c..92e0c3c19e 100644 --- a/core/gethwrappers/ccip/go_generate.go +++ b/core/gethwrappers/ccip/go_generate.go @@ -4,22 +4,10 @@ package ccip //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin CommitStore commit_store //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin CommitStoreHelper commit_store_helper -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin BurnMintTokenPool burn_mint_token_pool -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin BurnFromMintTokenPool burn_from_mint_token_pool -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin BurnWithFromMintTokenPool burn_with_from_mint_token_pool -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin LockReleaseTokenPool lock_release_token_pool -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin BurnMintTokenPoolAndProxy burn_mint_token_pool_and_proxy -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin LockReleaseTokenPoolAndProxy lock_release_token_pool_and_proxy -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin TokenPool token_pool //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin ARMContract arm_contract //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin ARMProxyContract arm_proxy_contract //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin TokenAdminRegistry token_admin_registry //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin RegistryModuleOwnerCustom registry_module_owner_custom -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin MockE2EUSDCTokenMessenger mock_usdc_token_messenger -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin MockE2EUSDCTransmitter mock_usdc_token_transmitter - -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin MockV3Aggregator mock_v3_aggregator_contract - //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin EVM2EVMOnRamp evm_2_evm_onramp //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin EVM2EVMMultiOnRamp evm_2_evm_multi_onramp //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin EVM2EVMOffRamp evm_2_evm_offramp @@ -28,9 +16,21 @@ package ccip //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin Router router //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin PriceRegistry price_registry //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin CCIPConfig ccip_config -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin IOCR3ConfigEncoder ocr3_config_encoder //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin NonceManager nonce_manager +// Pools +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin BurnMintTokenPool burn_mint_token_pool +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin BurnFromMintTokenPool burn_from_mint_token_pool +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin BurnWithFromMintTokenPool burn_with_from_mint_token_pool +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin BurnMintTokenPoolAndProxy burn_mint_token_pool_and_proxy +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin BurnWithFromMintTokenPoolAndProxy burn_with_from_mint_token_pool_and_proxy +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin LockReleaseTokenPool lock_release_token_pool +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin LockReleaseTokenPoolAndProxy lock_release_token_pool_and_proxy +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin TokenPool token_pool +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin USDCTokenPool usdc_token_pool + +// Helpers +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin MockV3Aggregator mock_v3_aggregator_contract //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin MaybeRevertMessageReceiver maybe_revert_message_receiver //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin PingPongDemo ping_pong_demo //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin SelfFundedPingPong self_funded_ping_pong @@ -39,9 +39,9 @@ package ccip //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin ReportCodec report_codec //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin EtherSenderReceiver ether_sender_receiver //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin WETH9 weth9 - -// Customer contracts -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin USDCTokenPool usdc_token_pool +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin IOCR3ConfigEncoder ocr3_config_encoder +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin MockE2EUSDCTokenMessenger mock_usdc_token_messenger +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin MockE2EUSDCTransmitter mock_usdc_token_transmitter // To run these commands, you must either install docker, or the correct version // of abigen. The latter can be installed with these commands, at least on linux: From bcfccbc893974db392094ab4f66d31e7c7e61e2e Mon Sep 17 00:00:00 2001 From: nogo <110664798+0xnogo@users.noreply.github.com> Date: Thu, 15 Aug 2024 19:05:17 +0200 Subject: [PATCH 208/432] Adding ooo flag to the PingPong (#1239) * setter of a bool representing the `allowOutOfOrderExecution` * creating and passing `extraArgs` to the message --- contracts/gas-snapshots/ccip.gas-snapshot | 14 +- .../v0.8/ccip/applications/PingPongDemo.sol | 22 ++- .../ccip/test/applications/PingPongDemo.t.sol | 63 ++++++- .../ping_pong_demo/ping_pong_demo.go | 171 +++++++++++++++++- .../self_funded_ping_pong.go | 171 +++++++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 4 +- 6 files changed, 423 insertions(+), 22 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index c1d6eff19b..ab6f3c64ec 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -661,9 +661,11 @@ OCR2Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 23484) OCR2Base_transmit:test_UnauthorizedSigner_Revert() (gas: 39665) OCR2Base_transmit:test_WrongNumberOfSignatures_Revert() (gas: 20557) OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 390410) -PingPong_ccipReceive:test_CcipReceive_Success() (gas: 148405) -PingPong_plumbing:test_Pausing_Success() (gas: 17803) -PingPong_startPingPong:test_StartPingPong_Success() (gas: 178365) +PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150175) +PingPong_plumbing:test_OutOfOrderExecution_Success() (gas: 20277) +PingPong_plumbing:test_Pausing_Success() (gas: 17777) +PingPong_startPingPong:test_StartPingPong_With_OOO_Success() (gas: 163199) +PingPong_startPingPong:test_StartPingPong_With_Sequenced_Ordered_Success() (gas: 182611) PriceRegistry_applyDestChainConfigUpdates:test_InvalidChainFamilySelector_Revert() (gas: 16725) PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 16816) PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestChainConfigDestChainSelectorEqZero_Revert() (gas: 16617) @@ -875,9 +877,9 @@ Router_routeMessage:test_ManualExec_Success() (gas: 35381) Router_routeMessage:test_OnlyOffRamp_Revert() (gas: 25116) Router_routeMessage:test_WhenNotHealthy_Revert() (gas: 44724) Router_setWrappedNative:test_OnlyOwner_Revert() (gas: 10985) -SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 53540) -SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 417080) -SelfFundedPingPong_setCountIncrBeforeFunding:test_setCountIncrBeforeFunding() (gas: 20157) +SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 53531) +SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 417002) +SelfFundedPingPong_setCountIncrBeforeFunding:test_setCountIncrBeforeFunding() (gas: 20151) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_OnlyPendingAdministrator_Revert() (gas: 51085) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_Success() (gas: 43947) TokenAdminRegistry_addRegistryModule:test_addRegistryModule_OnlyOwner_Revert() (gas: 12629) diff --git a/contracts/src/v0.8/ccip/applications/PingPongDemo.sol b/contracts/src/v0.8/ccip/applications/PingPongDemo.sol index 423fdc4546..5144b3ed4c 100644 --- a/contracts/src/v0.8/ccip/applications/PingPongDemo.sol +++ b/contracts/src/v0.8/ccip/applications/PingPongDemo.sol @@ -14,6 +14,10 @@ import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ contract PingPongDemo is CCIPReceiver, OwnerIsCreator, ITypeAndVersion { event Ping(uint256 pingPongCount); event Pong(uint256 pingPongCount); + event OutOfOrderExecutionChange(bool isOutOfOrder); + + // Default gas limit used for EVMExtraArgsV2 construction + uint64 private constant DEFAULT_GAS_LIMIT = 200_000; // The chain ID of the counterpart ping pong contract uint64 internal s_counterpartChainSelector; @@ -23,6 +27,8 @@ contract PingPongDemo is CCIPReceiver, OwnerIsCreator, ITypeAndVersion { bool private s_isPaused; // The fee token used to pay for CCIP transactions IERC20 internal s_feeToken; + // Allowing out of order execution + bool private s_outOfOrderExecution; constructor(address router, IERC20 feeToken) CCIPReceiver(router) { s_isPaused = false; @@ -50,12 +56,13 @@ contract PingPongDemo is CCIPReceiver, OwnerIsCreator, ITypeAndVersion { } else { emit Pong(pingPongCount); } - bytes memory data = abi.encode(pingPongCount); Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ receiver: abi.encode(s_counterpartAddress), - data: data, + data: abi.encode(pingPongCount), tokenAmounts: new Client.EVMTokenAmount[](0), - extraArgs: "", + extraArgs: Client._argsToBytes( + Client.EVMExtraArgsV2({gasLimit: uint256(DEFAULT_GAS_LIMIT), allowOutOfOrderExecution: s_outOfOrderExecution}) + ), feeToken: address(s_feeToken) }); IRouterClient(getRouter()).ccipSend(s_counterpartChainSelector, message); @@ -99,4 +106,13 @@ contract PingPongDemo is CCIPReceiver, OwnerIsCreator, ITypeAndVersion { function setPaused(bool pause) external onlyOwner { s_isPaused = pause; } + + function getOutOfOrderExecution() external view returns (bool) { + return s_outOfOrderExecution; + } + + function setOutOfOrderExecution(bool outOfOrderExecution) external onlyOwner { + s_outOfOrderExecution = outOfOrderExecution; + emit OutOfOrderExecutionChange(outOfOrderExecution); + } } diff --git a/contracts/src/v0.8/ccip/test/applications/PingPongDemo.t.sol b/contracts/src/v0.8/ccip/test/applications/PingPongDemo.t.sol index 3297e1f4fb..f253a72fcb 100644 --- a/contracts/src/v0.8/ccip/test/applications/PingPongDemo.t.sol +++ b/contracts/src/v0.8/ccip/test/applications/PingPongDemo.t.sol @@ -27,16 +27,15 @@ contract PingPongDappSetup is EVM2EVMOnRampSetup { } contract PingPong_startPingPong is PingPongDappSetup { - function test_StartPingPong_Success() public { - uint256 pingPongNumber = 1; - bytes memory data = abi.encode(pingPongNumber); + uint256 internal pingPongNumber = 1; + function test_StartPingPong_With_Sequenced_Ordered_Success() public { Client.EVM2AnyMessage memory sentMessage = Client.EVM2AnyMessage({ receiver: abi.encode(i_pongContract), - data: data, + data: abi.encode(pingPongNumber), tokenAmounts: new Client.EVMTokenAmount[](0), feeToken: s_sourceFeeToken, - extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 2e5})) + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000})) }); uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, sentMessage); @@ -48,14 +47,51 @@ contract PingPong_startPingPong is PingPongDappSetup { sender: address(s_pingPong), receiver: i_pongContract, nonce: 1, - data: data, + data: abi.encode(pingPongNumber), tokenAmounts: sentMessage.tokenAmounts, sourceTokenData: new bytes[](sentMessage.tokenAmounts.length), - gasLimit: 2e5, + gasLimit: 200_000, feeToken: sentMessage.feeToken, strict: false, messageId: "" }); + + _assertPingPongSuccess(message); + } + + function test_StartPingPong_With_OOO_Success() public { + s_pingPong.setOutOfOrderExecution(true); + + Client.EVM2AnyMessage memory sentMessage = Client.EVM2AnyMessage({ + receiver: abi.encode(i_pongContract), + data: abi.encode(pingPongNumber), + tokenAmounts: new Client.EVMTokenAmount[](0), + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV2({gasLimit: 200_000, allowOutOfOrderExecution: true})) + }); + + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, sentMessage); + + Internal.EVM2EVMMessage memory message = Internal.EVM2EVMMessage({ + sequenceNumber: 1, + feeTokenAmount: expectedFee, + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + sender: address(s_pingPong), + receiver: i_pongContract, + nonce: 0, + data: abi.encode(pingPongNumber), + tokenAmounts: sentMessage.tokenAmounts, + sourceTokenData: new bytes[](sentMessage.tokenAmounts.length), + gasLimit: 200_000, + feeToken: sentMessage.feeToken, + strict: false, + messageId: "" + }); + + _assertPingPongSuccess(message); + } + + function _assertPingPongSuccess(Internal.EVM2EVMMessage memory message) internal { message.messageId = Internal._hash(message, s_metadataHash); vm.expectEmit(); @@ -105,6 +141,8 @@ contract PingPong_plumbing is PingPongDappSetup { } function test_Fuzz_CounterPartAddress_Success(uint64 chainSelector, address counterpartAddress) public { + s_pingPong.setCounterpartChainSelector(chainSelector); + s_pingPong.setCounterpart(chainSelector, counterpartAddress); assertEq(s_pingPong.getCounterpartAddress(), counterpartAddress); @@ -118,4 +156,15 @@ contract PingPong_plumbing is PingPongDappSetup { assertTrue(s_pingPong.isPaused()); } + + function test_OutOfOrderExecution_Success() public { + assertFalse(s_pingPong.getOutOfOrderExecution()); + + vm.expectEmit(); + emit PingPongDemo.OutOfOrderExecutionChange(true); + + s_pingPong.setOutOfOrderExecution(true); + + assertTrue(s_pingPong.getOutOfOrderExecution()); + } } diff --git a/core/gethwrappers/ccip/generated/ping_pong_demo/ping_pong_demo.go b/core/gethwrappers/ccip/generated/ping_pong_demo/ping_pong_demo.go index 4387dd3080..349d83182c 100644 --- a/core/gethwrappers/ccip/generated/ping_pong_demo/ping_pong_demo.go +++ b/core/gethwrappers/ccip/generated/ping_pong_demo/ping_pong_demo.go @@ -44,8 +44,8 @@ type ClientEVMTokenAmount struct { } var PingPongDemoMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"feeToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"InvalidRouter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Ping\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Pong\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartChainSelector\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"counterpartChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"counterpartAddress\",\"type\":\"address\"}],\"name\":\"setCounterpart\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setCounterpartAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"setCounterpartChainSelector\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pause\",\"type\":\"bool\"}],\"name\":\"setPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startPingPong\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620013d8380380620013d8833981016040819052620000349162000263565b33806000846001600160a01b03811662000069576040516335fdcccd60e21b8152600060048201526024015b60405180910390fd5b6001600160a01b039081166080528216620000c75760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604482015260640162000060565b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000fa57620000fa816200019f565b50506002805460ff60a01b1916905550600380546001600160a01b0319166001600160a01b0383811691821790925560405163095ea7b360e01b8152918416600483015260001960248301529063095ea7b3906044016020604051808303816000875af115801562000170573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001969190620002a2565b505050620002cd565b336001600160a01b03821603620001f95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200026057600080fd5b50565b600080604083850312156200027757600080fd5b825162000284816200024a565b602084015190925062000297816200024a565b809150509250929050565b600060208284031215620002b557600080fd5b81518015158114620002c657600080fd5b9392505050565b6080516110e1620002f7600039600081816102290152818161058e01526108f201526110e16000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80638da5cb5b11610097578063b5a1101111610066578063b5a1101114610270578063bee518a414610283578063ca709a25146102c1578063f2fde38b146102df57600080fd5b80638da5cb5b146101f65780639d2aede514610214578063b0f479a114610227578063b187bd261461024d57600080fd5b80632874d8bf116100d35780632874d8bf146101945780632b6e5d631461019c57806379ba5097146101db57806385572ffb146101e357600080fd5b806301ffc9a71461010557806316c38b3c1461012d578063181f5a77146101425780631892b90614610181575b600080fd5b610118610113366004610af5565b6102f2565b60405190151581526020015b60405180910390f35b61014061013b366004610b3e565b61038b565b005b604080518082018252601281527f50696e67506f6e6744656d6f20312e322e300000000000000000000000000000602082015290516101249190610bc4565b61014061018f366004610bf4565b6103dd565b610140610438565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b610140610474565b6101406101f1366004610c0f565b610576565b60005473ffffffffffffffffffffffffffffffffffffffff166101b6565b610140610222366004610c6e565b6105fb565b7f00000000000000000000000000000000000000000000000000000000000000006101b6565b60025474010000000000000000000000000000000000000000900460ff16610118565b61014061027e366004610c89565b61064a565b60015474010000000000000000000000000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff9091168152602001610124565b60035473ffffffffffffffffffffffffffffffffffffffff166101b6565b6101406102ed366004610c6e565b6106ec565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f85572ffb00000000000000000000000000000000000000000000000000000000148061038557507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6103936106fd565b6002805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6103e56106fd565b6001805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104406106fd565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff169055610472600161077e565b565b60015473ffffffffffffffffffffffffffffffffffffffff1633146104fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146105e7576040517fd7f733340000000000000000000000000000000000000000000000000000000081523360048201526024016104f1565b6105f86105f382610ebf565b6109aa565b50565b6106036106fd565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6106526106fd565b6001805467ffffffffffffffff90931674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909316929092179091556002805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055565b6106f46106fd565b6105f881610a00565b60005473ffffffffffffffffffffffffffffffffffffffff163314610472576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104f1565b806001166001036107c1576040518181527f48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f9060200160405180910390a16107f5565b6040518181527f58b69f57828e6962d216502094c54f6562f3bf082ba758966c3454f9e37b15259060200160405180910390a15b60008160405160200161080a91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a08301825260025473ffffffffffffffffffffffffffffffffffffffff1660c0808501919091528251808503909101815260e084018352835260208084018290528251600080825291810184529194509291820190836108b8565b60408051808201909152600080825260208201528152602001906001900390816108915790505b50815260035473ffffffffffffffffffffffffffffffffffffffff16602080830191909152604080519182018152600082529091015290507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166396f4e9f9600160149054906101000a900467ffffffffffffffff16836040518363ffffffff1660e01b8152600401610961929190610f6c565b6020604051808303816000875af1158015610980573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a49190611081565b50505050565b600081606001518060200190518101906109c49190611081565b60025490915074010000000000000000000000000000000000000000900460ff166109fc576109fc6109f782600161109a565b61077e565b5050565b3373ffffffffffffffffffffffffffffffffffffffff821603610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104f1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610b0757600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610b3757600080fd5b9392505050565b600060208284031215610b5057600080fd5b81358015158114610b3757600080fd5b6000815180845260005b81811015610b8657602081850181015186830182015201610b6a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b376020830184610b60565b803567ffffffffffffffff81168114610bef57600080fd5b919050565b600060208284031215610c0657600080fd5b610b3782610bd7565b600060208284031215610c2157600080fd5b813567ffffffffffffffff811115610c3857600080fd5b820160a08185031215610b3757600080fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610bef57600080fd5b600060208284031215610c8057600080fd5b610b3782610c4a565b60008060408385031215610c9c57600080fd5b610ca583610bd7565b9150610cb360208401610c4a565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610d0e57610d0e610cbc565b60405290565b60405160a0810167ffffffffffffffff81118282101715610d0e57610d0e610cbc565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d7e57610d7e610cbc565b604052919050565b600082601f830112610d9757600080fd5b813567ffffffffffffffff811115610db157610db1610cbc565b610de260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610d37565b818152846020838601011115610df757600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f830112610e2557600080fd5b8135602067ffffffffffffffff821115610e4157610e41610cbc565b610e4f818360051b01610d37565b82815260069290921b84018101918181019086841115610e6e57600080fd5b8286015b84811015610eb45760408189031215610e8b5760008081fd5b610e93610ceb565b610e9c82610c4a565b81528185013585820152835291830191604001610e72565b509695505050505050565b600060a08236031215610ed157600080fd5b610ed9610d14565b82358152610ee960208401610bd7565b6020820152604083013567ffffffffffffffff80821115610f0957600080fd5b610f1536838701610d86565b60408401526060850135915080821115610f2e57600080fd5b610f3a36838701610d86565b60608401526080850135915080821115610f5357600080fd5b50610f6036828601610e14565b60808301525092915050565b6000604067ffffffffffffffff851683526020604081850152845160a06040860152610f9b60e0860182610b60565b9050818601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080878403016060880152610fd68383610b60565b6040890151888203830160808a01528051808352908601945060009350908501905b80841015611037578451805173ffffffffffffffffffffffffffffffffffffffff16835286015186830152938501936001939093019290860190610ff8565b50606089015173ffffffffffffffffffffffffffffffffffffffff1660a08901526080890151888203830160c08a015295506110738187610b60565b9a9950505050505050505050565b60006020828403121561109357600080fd5b5051919050565b80820180821115610385577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"feeToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"InvalidRouter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutOfOrder\",\"type\":\"bool\"}],\"name\":\"OutOfOrderExecutionChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Ping\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Pong\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartChainSelector\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOutOfOrderExecution\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"counterpartChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"counterpartAddress\",\"type\":\"address\"}],\"name\":\"setCounterpart\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setCounterpartAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"setCounterpartChainSelector\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"outOfOrderExecution\",\"type\":\"bool\"}],\"name\":\"setOutOfOrderExecution\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pause\",\"type\":\"bool\"}],\"name\":\"setPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startPingPong\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200159d3803806200159d833981016040819052620000349162000263565b33806000846001600160a01b03811662000069576040516335fdcccd60e21b8152600060048201526024015b60405180910390fd5b6001600160a01b039081166080528216620000c75760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604482015260640162000060565b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000fa57620000fa816200019f565b50506002805460ff60a01b1916905550600380546001600160a01b0319166001600160a01b0383811691821790925560405163095ea7b360e01b8152918416600483015260001960248301529063095ea7b3906044016020604051808303816000875af115801562000170573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001969190620002a2565b505050620002cd565b336001600160a01b03821603620001f95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200026057600080fd5b50565b600080604083850312156200027757600080fd5b825162000284816200024a565b602084015190925062000297816200024a565b809150509250929050565b600060208284031215620002b557600080fd5b81518015158114620002c657600080fd5b9392505050565b6080516112a6620002f760003960008181610295015281816106860152610ab901526112a66000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638da5cb5b116100b2578063b187bd2611610081578063bee518a411610066578063bee518a4146102ef578063ca709a251461032d578063f2fde38b1461034b57600080fd5b8063b187bd26146102b9578063b5a11011146102dc57600080fd5b80638da5cb5b1461023f5780639d2aede51461025d578063ae90de5514610270578063b0f479a11461029357600080fd5b80632874d8bf11610109578063665ed537116100ee578063665ed5371461021157806379ba50971461022457806385572ffb1461022c57600080fd5b80632874d8bf146101ca5780632b6e5d63146101d257600080fd5b806301ffc9a71461013b57806316c38b3c14610163578063181f5a77146101785780631892b906146101b7575b600080fd5b61014e610149366004610cba565b61035e565b60405190151581526020015b60405180910390f35b610176610171366004610d03565b6103f7565b005b604080518082018252601281527f50696e67506f6e6744656d6f20312e322e3000000000000000000000000000006020820152905161015a9190610d89565b6101766101c5366004610db9565b610449565b6101766104a4565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161015a565b61017661021f366004610d03565b6104e0565b61017661056c565b61017661023a366004610dd4565b61066e565b60005473ffffffffffffffffffffffffffffffffffffffff166101ec565b61017661026b366004610e33565b6106f3565b60035474010000000000000000000000000000000000000000900460ff1661014e565b7f00000000000000000000000000000000000000000000000000000000000000006101ec565b60025474010000000000000000000000000000000000000000900460ff1661014e565b6101766102ea366004610e4e565b610742565b60015474010000000000000000000000000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff909116815260200161015a565b60035473ffffffffffffffffffffffffffffffffffffffff166101ec565b610176610359366004610e33565b6107e4565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f85572ffb0000000000000000000000000000000000000000000000000000000014806103f157507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6103ff6107f5565b6002805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104516107f5565b6001805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104ac6107f5565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556104de6001610876565b565b6104e86107f5565b6003805482151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091161790556040517f05a3fef9935c9013a24c6193df2240d34fcf6b0ebf8786b85efe8401d696cdd99061056190831515815260200190565b60405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106df576040517fd7f733340000000000000000000000000000000000000000000000000000000081523360048201526024016105e9565b6106f06106eb82611084565b610b6f565b50565b6106fb6107f5565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61074a6107f5565b6001805467ffffffffffffffff90931674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909316929092179091556002805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055565b6107ec6107f5565b6106f081610bc5565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105e9565b806001166001036108b9576040518181527f48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f9060200160405180910390a16108ed565b6040518181527f58b69f57828e6962d216502094c54f6562f3bf082ba758966c3454f9e37b15259060200160405180910390a15b6040805160a0810190915260025473ffffffffffffffffffffffffffffffffffffffff1660c08201526000908060e0810160405160208183030381529060405281526020018360405160200161094591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052815260200160006040519080825280602002602001820160405280156109bf57816020015b60408051808201909152600080825260208201528152602001906001900390816109985790505b50815260035473ffffffffffffffffffffffffffffffffffffffff811660208084019190915260408051808201825262030d408082527401000000000000000000000000000000000000000090940460ff16151590830190815281516024810194909452511515604480850191909152815180850390910181526064909301815290820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf1000000000000000000000000000000000000000000000000000000000179052909101526001546040517f96f4e9f90000000000000000000000000000000000000000000000000000000081529192507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16916396f4e9f991610b27917401000000000000000000000000000000000000000090910467ffffffffffffffff16908590600401611131565b6020604051808303816000875af1158015610b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6a9190611246565b505050565b60008160600151806020019051810190610b899190611246565b60025490915074010000000000000000000000000000000000000000900460ff16610bc157610bc1610bbc82600161125f565b610876565b5050565b3373ffffffffffffffffffffffffffffffffffffffff821603610c44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105e9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610ccc57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610cfc57600080fd5b9392505050565b600060208284031215610d1557600080fd5b81358015158114610cfc57600080fd5b6000815180845260005b81811015610d4b57602081850181015186830182015201610d2f565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610cfc6020830184610d25565b803567ffffffffffffffff81168114610db457600080fd5b919050565b600060208284031215610dcb57600080fd5b610cfc82610d9c565b600060208284031215610de657600080fd5b813567ffffffffffffffff811115610dfd57600080fd5b820160a08185031215610cfc57600080fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610db457600080fd5b600060208284031215610e4557600080fd5b610cfc82610e0f565b60008060408385031215610e6157600080fd5b610e6a83610d9c565b9150610e7860208401610e0f565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610ed357610ed3610e81565b60405290565b60405160a0810167ffffffffffffffff81118282101715610ed357610ed3610e81565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610f4357610f43610e81565b604052919050565b600082601f830112610f5c57600080fd5b813567ffffffffffffffff811115610f7657610f76610e81565b610fa760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610efc565b818152846020838601011115610fbc57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f830112610fea57600080fd5b8135602067ffffffffffffffff82111561100657611006610e81565b611014818360051b01610efc565b82815260069290921b8401810191818101908684111561103357600080fd5b8286015b8481101561107957604081890312156110505760008081fd5b611058610eb0565b61106182610e0f565b81528185013585820152835291830191604001611037565b509695505050505050565b600060a0823603121561109657600080fd5b61109e610ed9565b823581526110ae60208401610d9c565b6020820152604083013567ffffffffffffffff808211156110ce57600080fd5b6110da36838701610f4b565b604084015260608501359150808211156110f357600080fd5b6110ff36838701610f4b565b6060840152608085013591508082111561111857600080fd5b5061112536828601610fd9565b60808301525092915050565b6000604067ffffffffffffffff851683526020604081850152845160a0604086015261116060e0860182610d25565b9050818601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087840301606088015261119b8383610d25565b6040890151888203830160808a01528051808352908601945060009350908501905b808410156111fc578451805173ffffffffffffffffffffffffffffffffffffffff168352860151868301529385019360019390930192908601906111bd565b50606089015173ffffffffffffffffffffffffffffffffffffffff1660a08901526080890151888203830160c08a015295506112388187610d25565b9a9950505050505050505050565b60006020828403121561125857600080fd5b5051919050565b808201808211156103f1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000818000a", } var PingPongDemoABI = PingPongDemoMetaData.ABI @@ -250,6 +250,28 @@ func (_PingPongDemo *PingPongDemoCallerSession) GetFeeToken() (common.Address, e return _PingPongDemo.Contract.GetFeeToken(&_PingPongDemo.CallOpts) } +func (_PingPongDemo *PingPongDemoCaller) GetOutOfOrderExecution(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _PingPongDemo.contract.Call(opts, &out, "getOutOfOrderExecution") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_PingPongDemo *PingPongDemoSession) GetOutOfOrderExecution() (bool, error) { + return _PingPongDemo.Contract.GetOutOfOrderExecution(&_PingPongDemo.CallOpts) +} + +func (_PingPongDemo *PingPongDemoCallerSession) GetOutOfOrderExecution() (bool, error) { + return _PingPongDemo.Contract.GetOutOfOrderExecution(&_PingPongDemo.CallOpts) +} + func (_PingPongDemo *PingPongDemoCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { var out []interface{} err := _PingPongDemo.contract.Call(opts, &out, "getRouter") @@ -420,6 +442,18 @@ func (_PingPongDemo *PingPongDemoTransactorSession) SetCounterpartChainSelector( return _PingPongDemo.Contract.SetCounterpartChainSelector(&_PingPongDemo.TransactOpts, chainSelector) } +func (_PingPongDemo *PingPongDemoTransactor) SetOutOfOrderExecution(opts *bind.TransactOpts, outOfOrderExecution bool) (*types.Transaction, error) { + return _PingPongDemo.contract.Transact(opts, "setOutOfOrderExecution", outOfOrderExecution) +} + +func (_PingPongDemo *PingPongDemoSession) SetOutOfOrderExecution(outOfOrderExecution bool) (*types.Transaction, error) { + return _PingPongDemo.Contract.SetOutOfOrderExecution(&_PingPongDemo.TransactOpts, outOfOrderExecution) +} + +func (_PingPongDemo *PingPongDemoTransactorSession) SetOutOfOrderExecution(outOfOrderExecution bool) (*types.Transaction, error) { + return _PingPongDemo.Contract.SetOutOfOrderExecution(&_PingPongDemo.TransactOpts, outOfOrderExecution) +} + func (_PingPongDemo *PingPongDemoTransactor) SetPaused(opts *bind.TransactOpts, pause bool) (*types.Transaction, error) { return _PingPongDemo.contract.Transact(opts, "setPaused", pause) } @@ -456,6 +490,123 @@ func (_PingPongDemo *PingPongDemoTransactorSession) TransferOwnership(to common. return _PingPongDemo.Contract.TransferOwnership(&_PingPongDemo.TransactOpts, to) } +type PingPongDemoOutOfOrderExecutionChangeIterator struct { + Event *PingPongDemoOutOfOrderExecutionChange + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PingPongDemoOutOfOrderExecutionChangeIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PingPongDemoOutOfOrderExecutionChange) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PingPongDemoOutOfOrderExecutionChange) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PingPongDemoOutOfOrderExecutionChangeIterator) Error() error { + return it.fail +} + +func (it *PingPongDemoOutOfOrderExecutionChangeIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PingPongDemoOutOfOrderExecutionChange struct { + IsOutOfOrder bool + Raw types.Log +} + +func (_PingPongDemo *PingPongDemoFilterer) FilterOutOfOrderExecutionChange(opts *bind.FilterOpts) (*PingPongDemoOutOfOrderExecutionChangeIterator, error) { + + logs, sub, err := _PingPongDemo.contract.FilterLogs(opts, "OutOfOrderExecutionChange") + if err != nil { + return nil, err + } + return &PingPongDemoOutOfOrderExecutionChangeIterator{contract: _PingPongDemo.contract, event: "OutOfOrderExecutionChange", logs: logs, sub: sub}, nil +} + +func (_PingPongDemo *PingPongDemoFilterer) WatchOutOfOrderExecutionChange(opts *bind.WatchOpts, sink chan<- *PingPongDemoOutOfOrderExecutionChange) (event.Subscription, error) { + + logs, sub, err := _PingPongDemo.contract.WatchLogs(opts, "OutOfOrderExecutionChange") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PingPongDemoOutOfOrderExecutionChange) + if err := _PingPongDemo.contract.UnpackLog(event, "OutOfOrderExecutionChange", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PingPongDemo *PingPongDemoFilterer) ParseOutOfOrderExecutionChange(log types.Log) (*PingPongDemoOutOfOrderExecutionChange, error) { + event := new(PingPongDemoOutOfOrderExecutionChange) + if err := _PingPongDemo.contract.UnpackLog(event, "OutOfOrderExecutionChange", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type PingPongDemoOwnershipTransferRequestedIterator struct { Event *PingPongDemoOwnershipTransferRequested @@ -964,6 +1115,8 @@ func (_PingPongDemo *PingPongDemoFilterer) ParsePong(log types.Log) (*PingPongDe func (_PingPongDemo *PingPongDemo) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { + case _PingPongDemo.abi.Events["OutOfOrderExecutionChange"].ID: + return _PingPongDemo.ParseOutOfOrderExecutionChange(log) case _PingPongDemo.abi.Events["OwnershipTransferRequested"].ID: return _PingPongDemo.ParseOwnershipTransferRequested(log) case _PingPongDemo.abi.Events["OwnershipTransferred"].ID: @@ -978,6 +1131,10 @@ func (_PingPongDemo *PingPongDemo) ParseLog(log types.Log) (generated.AbigenLog, } } +func (PingPongDemoOutOfOrderExecutionChange) Topic() common.Hash { + return common.HexToHash("0x05a3fef9935c9013a24c6193df2240d34fcf6b0ebf8786b85efe8401d696cdd9") +} + func (PingPongDemoOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } @@ -1005,6 +1162,8 @@ type PingPongDemoInterface interface { GetFeeToken(opts *bind.CallOpts) (common.Address, error) + GetOutOfOrderExecution(opts *bind.CallOpts) (bool, error) + GetRouter(opts *bind.CallOpts) (common.Address, error) IsPaused(opts *bind.CallOpts) (bool, error) @@ -1025,12 +1184,20 @@ type PingPongDemoInterface interface { SetCounterpartChainSelector(opts *bind.TransactOpts, chainSelector uint64) (*types.Transaction, error) + SetOutOfOrderExecution(opts *bind.TransactOpts, outOfOrderExecution bool) (*types.Transaction, error) + SetPaused(opts *bind.TransactOpts, pause bool) (*types.Transaction, error) StartPingPong(opts *bind.TransactOpts) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + FilterOutOfOrderExecutionChange(opts *bind.FilterOpts) (*PingPongDemoOutOfOrderExecutionChangeIterator, error) + + WatchOutOfOrderExecutionChange(opts *bind.WatchOpts, sink chan<- *PingPongDemoOutOfOrderExecutionChange) (event.Subscription, error) + + ParseOutOfOrderExecutionChange(log types.Log) (*PingPongDemoOutOfOrderExecutionChange, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PingPongDemoOwnershipTransferRequestedIterator, error) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PingPongDemoOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/ccip/generated/self_funded_ping_pong/self_funded_ping_pong.go b/core/gethwrappers/ccip/generated/self_funded_ping_pong/self_funded_ping_pong.go index d6e2db6bf3..755b4183fe 100644 --- a/core/gethwrappers/ccip/generated/self_funded_ping_pong/self_funded_ping_pong.go +++ b/core/gethwrappers/ccip/generated/self_funded_ping_pong/self_funded_ping_pong.go @@ -44,8 +44,8 @@ type ClientEVMTokenAmount struct { } var SelfFundedPingPongMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"roundTripsBeforeFunding\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"InvalidRouter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"countIncrBeforeFunding\",\"type\":\"uint8\"}],\"name\":\"CountIncrBeforeFundingSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Funded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Ping\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Pong\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"fundPingPong\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCountIncrBeforeFunding\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartChainSelector\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"countIncrBeforeFunding\",\"type\":\"uint8\"}],\"name\":\"setCountIncrBeforeFunding\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"counterpartChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"counterpartAddress\",\"type\":\"address\"}],\"name\":\"setCounterpart\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setCounterpartAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"setCounterpartChainSelector\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pause\",\"type\":\"bool\"}],\"name\":\"setPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startPingPong\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b506040516200182238038062001822833981016040819052620000349162000291565b828233806000846001600160a01b0381166200006b576040516335fdcccd60e21b8152600060048201526024015b60405180910390fd5b6001600160a01b039081166080528216620000c95760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604482015260640162000062565b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000fc57620000fc81620001cd565b50506002805460ff60a01b1916905550600380546001600160a01b0319166001600160a01b0383811691821790925560405163095ea7b360e01b8152918416600483015260001960248301529063095ea7b3906044016020604051808303816000875af115801562000172573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001989190620002ea565b505050806002620001aa919062000315565b600360146101000a81548160ff021916908360ff16021790555050505062000347565b336001600160a01b03821603620002275760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000062565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200028e57600080fd5b50565b600080600060608486031215620002a757600080fd5b8351620002b48162000278565b6020850151909350620002c78162000278565b604085015190925060ff81168114620002df57600080fd5b809150509250925092565b600060208284031215620002fd57600080fd5b815180151581146200030e57600080fd5b9392505050565b60ff81811683821602908116908181146200034057634e487b7160e01b600052601160045260246000fd5b5092915050565b6080516114aa62000378600039600081816102970152818161063f0152818161072c0152610c2201526114aa6000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c80638f491cba116100cd578063bee518a411610081578063e6c725f511610066578063e6c725f51461034d578063ef686d8e1461037d578063f2fde38b1461039057600080fd5b8063bee518a4146102f1578063ca709a251461032f57600080fd5b8063b0f479a1116100b2578063b0f479a114610295578063b187bd26146102bb578063b5a11011146102de57600080fd5b80638f491cba1461026f5780639d2aede51461028257600080fd5b80632874d8bf1161012457806379ba50971161010957806379ba50971461023657806385572ffb1461023e5780638da5cb5b1461025157600080fd5b80632874d8bf146101ef5780632b6e5d63146101f757600080fd5b806301ffc9a71461015657806316c38b3c1461017e578063181f5a77146101935780631892b906146101dc575b600080fd5b610169610164366004610e24565b6103a3565b60405190151581526020015b60405180910390f35b61019161018c366004610e6d565b61043c565b005b6101cf6040518060400160405280601881526020017f53656c6646756e64656450696e67506f6e6720312e322e30000000000000000081525081565b6040516101759190610ef3565b6101916101ea366004610f23565b61048e565b6101916104e9565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610175565b610191610525565b61019161024c366004610f3e565b610627565b60005473ffffffffffffffffffffffffffffffffffffffff16610211565b61019161027d366004610f79565b6106ac565b610191610290366004610fb4565b61088b565b7f0000000000000000000000000000000000000000000000000000000000000000610211565b60025474010000000000000000000000000000000000000000900460ff16610169565b6101916102ec366004610fd1565b6108da565b60015474010000000000000000000000000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff9091168152602001610175565b60035473ffffffffffffffffffffffffffffffffffffffff16610211565b60035474010000000000000000000000000000000000000000900460ff1660405160ff9091168152602001610175565b61019161038b366004611008565b61097c565b61019161039e366004610fb4565b610a04565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f85572ffb00000000000000000000000000000000000000000000000000000000148061043657507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b610444610a15565b6002805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b610496610a15565b6001805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104f1610a15565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556105236001610a96565b565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610698576040517fd7f733340000000000000000000000000000000000000000000000000000000081523360048201526024016105a2565b6106a96106a482611230565b610cd9565b50565b60035474010000000000000000000000000000000000000000900460ff1615806106f2575060035474010000000000000000000000000000000000000000900460ff1681105b156106fa5750565b6003546001906107259074010000000000000000000000000000000000000000900460ff16836112dd565b116106a9577f00000000000000000000000000000000000000000000000000000000000000006001546040517fa8d87a3b0000000000000000000000000000000000000000000000000000000081527401000000000000000000000000000000000000000090910467ffffffffffffffff16600482015273ffffffffffffffffffffffffffffffffffffffff919091169063a8d87a3b90602401602060405180830381865afa1580156107dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108009190611318565b73ffffffffffffffffffffffffffffffffffffffff1663eff7cc486040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561084757600080fd5b505af115801561085b573d6000803e3d6000fd5b50506040517f302777af5d26fab9dd5120c5f1307c65193ebc51daf33244ada4365fab10602c925060009150a150565b610893610a15565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6108e2610a15565b6001805467ffffffffffffffff90931674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909316929092179091556002805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055565b610984610a15565b600380547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000060ff8416908102919091179091556040519081527f4768dbf8645b24c54f2887651545d24f748c0d0d1d4c689eb810fb19f0befcf39060200160405180910390a150565b610a0c610a15565b6106a981610d2f565b60005473ffffffffffffffffffffffffffffffffffffffff163314610523576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105a2565b80600116600103610ad9576040518181527f48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f9060200160405180910390a1610b0d565b6040518181527f58b69f57828e6962d216502094c54f6562f3bf082ba758966c3454f9e37b15259060200160405180910390a15b610b16816106ac565b6040805160a0810190915260025473ffffffffffffffffffffffffffffffffffffffff1660c08201526000908060e08101604051602081830303815290604052815260200183604051602001610b6e91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905281526020016000604051908082528060200260200182016040528015610be857816020015b6040805180820190915260008082526020820152815260200190600190039081610bc15790505b50815260035473ffffffffffffffffffffffffffffffffffffffff16602080830191909152604080519182018152600082529091015290507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166396f4e9f9600160149054906101000a900467ffffffffffffffff16836040518363ffffffff1660e01b8152600401610c91929190611335565b6020604051808303816000875af1158015610cb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd4919061144a565b505050565b60008160600151806020019051810190610cf3919061144a565b60025490915074010000000000000000000000000000000000000000900460ff16610d2b57610d2b610d26826001611463565b610a96565b5050565b3373ffffffffffffffffffffffffffffffffffffffff821603610dae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105a2565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610e3657600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e6657600080fd5b9392505050565b600060208284031215610e7f57600080fd5b81358015158114610e6657600080fd5b6000815180845260005b81811015610eb557602081850181015186830182015201610e99565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610e666020830184610e8f565b803567ffffffffffffffff81168114610f1e57600080fd5b919050565b600060208284031215610f3557600080fd5b610e6682610f06565b600060208284031215610f5057600080fd5b813567ffffffffffffffff811115610f6757600080fd5b820160a08185031215610e6657600080fd5b600060208284031215610f8b57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146106a957600080fd5b600060208284031215610fc657600080fd5b8135610e6681610f92565b60008060408385031215610fe457600080fd5b610fed83610f06565b91506020830135610ffd81610f92565b809150509250929050565b60006020828403121561101a57600080fd5b813560ff81168114610e6657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561107d5761107d61102b565b60405290565b60405160a0810167ffffffffffffffff8111828210171561107d5761107d61102b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156110ed576110ed61102b565b604052919050565b600082601f83011261110657600080fd5b813567ffffffffffffffff8111156111205761112061102b565b61115160207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016110a6565b81815284602083860101111561116657600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261119457600080fd5b8135602067ffffffffffffffff8211156111b0576111b061102b565b6111be818360051b016110a6565b82815260069290921b840181019181810190868411156111dd57600080fd5b8286015b8481101561122557604081890312156111fa5760008081fd5b61120261105a565b813561120d81610f92565b815281850135858201528352918301916040016111e1565b509695505050505050565b600060a0823603121561124257600080fd5b61124a611083565b8235815261125a60208401610f06565b6020820152604083013567ffffffffffffffff8082111561127a57600080fd5b611286368387016110f5565b6040840152606085013591508082111561129f57600080fd5b6112ab368387016110f5565b606084015260808501359150808211156112c457600080fd5b506112d136828601611183565b60808301525092915050565b600082611313577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b60006020828403121561132a57600080fd5b8151610e6681610f92565b6000604067ffffffffffffffff851683526020604081850152845160a0604086015261136460e0860182610e8f565b9050818601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087840301606088015261139f8383610e8f565b6040890151888203830160808a01528051808352908601945060009350908501905b80841015611400578451805173ffffffffffffffffffffffffffffffffffffffff168352860151868301529385019360019390930192908601906113c1565b50606089015173ffffffffffffffffffffffffffffffffffffffff1660a08901526080890151888203830160c08a0152955061143c8187610e8f565b9a9950505050505050505050565b60006020828403121561145c57600080fd5b5051919050565b80820180821115610436577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"roundTripsBeforeFunding\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"InvalidRouter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"countIncrBeforeFunding\",\"type\":\"uint8\"}],\"name\":\"CountIncrBeforeFundingSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Funded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutOfOrder\",\"type\":\"bool\"}],\"name\":\"OutOfOrderExecutionChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Ping\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Pong\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"fundPingPong\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCountIncrBeforeFunding\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartChainSelector\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOutOfOrderExecution\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"countIncrBeforeFunding\",\"type\":\"uint8\"}],\"name\":\"setCountIncrBeforeFunding\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"counterpartChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"counterpartAddress\",\"type\":\"address\"}],\"name\":\"setCounterpart\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setCounterpartAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"setCounterpartChainSelector\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"outOfOrderExecution\",\"type\":\"bool\"}],\"name\":\"setOutOfOrderExecution\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pause\",\"type\":\"bool\"}],\"name\":\"setPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startPingPong\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200190938038062001909833981016040819052620000349162000291565b828233806000846001600160a01b0381166200006b576040516335fdcccd60e21b8152600060048201526024015b60405180910390fd5b6001600160a01b039081166080528216620000c95760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604482015260640162000062565b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000fc57620000fc81620001cd565b50506002805460ff60a01b1916905550600380546001600160a01b0319166001600160a01b0383811691821790925560405163095ea7b360e01b8152918416600483015260001960248301529063095ea7b3906044016020604051808303816000875af115801562000172573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001989190620002ea565b505050806002620001aa919062000315565b600360156101000a81548160ff021916908360ff16021790555050505062000347565b336001600160a01b03821603620002275760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000062565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200028e57600080fd5b50565b600080600060608486031215620002a757600080fd5b8351620002b48162000278565b6020850151909350620002c78162000278565b604085015190925060ff81168114620002df57600080fd5b809150509250925092565b600060208284031215620002fd57600080fd5b815180151581146200030e57600080fd5b9392505050565b60ff81811683821602908116908181146200034057634e487b7160e01b600052601160045260246000fd5b5092915050565b60805161159162000378600039600081816102f301528181610728015281816108180152610d0901526115916000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80638f491cba116100d8578063b5a110111161008c578063e6c725f511610066578063e6c725f5146103a9578063ef686d8e146103da578063f2fde38b146103ed57600080fd5b8063b5a110111461033a578063bee518a41461034d578063ca709a251461038b57600080fd5b8063ae90de55116100bd578063ae90de55146102ce578063b0f479a1146102f1578063b187bd261461031757600080fd5b80638f491cba146102a85780639d2aede5146102bb57600080fd5b80632b6e5d631161012f57806379ba50971161011457806379ba50971461026f57806385572ffb146102775780638da5cb5b1461028a57600080fd5b80632b6e5d631461021d578063665ed5371461025c57600080fd5b8063181f5a7711610160578063181f5a77146101b95780631892b906146102025780632874d8bf1461021557600080fd5b806301ffc9a71461017c57806316c38b3c146101a4575b600080fd5b61018f61018a366004610f0b565b610400565b60405190151581526020015b60405180910390f35b6101b76101b2366004610f54565b610499565b005b6101f56040518060400160405280601881526020017f53656c6646756e64656450696e67506f6e6720312e322e30000000000000000081525081565b60405161019b9190610fda565b6101b761021036600461100a565b6104eb565b6101b7610546565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101b761026a366004610f54565b610582565b6101b761060e565b6101b7610285366004611025565b610710565b60005473ffffffffffffffffffffffffffffffffffffffff16610237565b6101b76102b6366004611060565b610795565b6101b76102c936600461109b565b610977565b60035474010000000000000000000000000000000000000000900460ff1661018f565b7f0000000000000000000000000000000000000000000000000000000000000000610237565b60025474010000000000000000000000000000000000000000900460ff1661018f565b6101b76103483660046110b8565b6109c6565b60015474010000000000000000000000000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff909116815260200161019b565b60035473ffffffffffffffffffffffffffffffffffffffff16610237565b6003547501000000000000000000000000000000000000000000900460ff1660405160ff909116815260200161019b565b6101b76103e83660046110ef565b610a68565b6101b76103fb36600461109b565b610aeb565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f85572ffb00000000000000000000000000000000000000000000000000000000148061049357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6104a1610afc565b6002805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104f3610afc565b6001805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b61054e610afc565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556105806001610b7d565b565b61058a610afc565b6003805482151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091161790556040517f05a3fef9935c9013a24c6193df2240d34fcf6b0ebf8786b85efe8401d696cdd99061060390831515815260200190565b60405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff163314610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610781576040517fd7f7333400000000000000000000000000000000000000000000000000000000815233600482015260240161068b565b61079261078d82611317565b610dc0565b50565b6003547501000000000000000000000000000000000000000000900460ff1615806107dd57506003547501000000000000000000000000000000000000000000900460ff1681105b156107e55750565b600354600190610811907501000000000000000000000000000000000000000000900460ff16836113c4565b11610792577f00000000000000000000000000000000000000000000000000000000000000006001546040517fa8d87a3b0000000000000000000000000000000000000000000000000000000081527401000000000000000000000000000000000000000090910467ffffffffffffffff16600482015273ffffffffffffffffffffffffffffffffffffffff919091169063a8d87a3b90602401602060405180830381865afa1580156108c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ec91906113ff565b73ffffffffffffffffffffffffffffffffffffffff1663eff7cc486040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561093357600080fd5b505af1158015610947573d6000803e3d6000fd5b50506040517f302777af5d26fab9dd5120c5f1307c65193ebc51daf33244ada4365fab10602c925060009150a150565b61097f610afc565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6109ce610afc565b6001805467ffffffffffffffff90931674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909316929092179091556002805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055565b610a70610afc565b600380547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000060ff8416908102919091179091556040519081527f4768dbf8645b24c54f2887651545d24f748c0d0d1d4c689eb810fb19f0befcf390602001610603565b610af3610afc565b61079281610e16565b60005473ffffffffffffffffffffffffffffffffffffffff163314610580576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161068b565b80600116600103610bc0576040518181527f48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f9060200160405180910390a1610bf4565b6040518181527f58b69f57828e6962d216502094c54f6562f3bf082ba758966c3454f9e37b15259060200160405180910390a15b610bfd81610795565b6040805160a0810190915260025473ffffffffffffffffffffffffffffffffffffffff1660c08201526000908060e08101604051602081830303815290604052815260200183604051602001610c5591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905281526020016000604051908082528060200260200182016040528015610ccf57816020015b6040805180820190915260008082526020820152815260200190600190039081610ca85790505b50815260035473ffffffffffffffffffffffffffffffffffffffff16602080830191909152604080519182018152600082529091015290507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166396f4e9f9600160149054906101000a900467ffffffffffffffff16836040518363ffffffff1660e01b8152600401610d7892919061141c565b6020604051808303816000875af1158015610d97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbb9190611531565b505050565b60008160600151806020019051810190610dda9190611531565b60025490915074010000000000000000000000000000000000000000900460ff16610e1257610e12610e0d82600161154a565b610b7d565b5050565b3373ffffffffffffffffffffffffffffffffffffffff821603610e95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161068b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610f1d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f4d57600080fd5b9392505050565b600060208284031215610f6657600080fd5b81358015158114610f4d57600080fd5b6000815180845260005b81811015610f9c57602081850181015186830182015201610f80565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610f4d6020830184610f76565b803567ffffffffffffffff8116811461100557600080fd5b919050565b60006020828403121561101c57600080fd5b610f4d82610fed565b60006020828403121561103757600080fd5b813567ffffffffffffffff81111561104e57600080fd5b820160a08185031215610f4d57600080fd5b60006020828403121561107257600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461079257600080fd5b6000602082840312156110ad57600080fd5b8135610f4d81611079565b600080604083850312156110cb57600080fd5b6110d483610fed565b915060208301356110e481611079565b809150509250929050565b60006020828403121561110157600080fd5b813560ff81168114610f4d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561116457611164611112565b60405290565b60405160a0810167ffffffffffffffff8111828210171561116457611164611112565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156111d4576111d4611112565b604052919050565b600082601f8301126111ed57600080fd5b813567ffffffffffffffff81111561120757611207611112565b61123860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161118d565b81815284602083860101111561124d57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261127b57600080fd5b8135602067ffffffffffffffff82111561129757611297611112565b6112a5818360051b0161118d565b82815260069290921b840181019181810190868411156112c457600080fd5b8286015b8481101561130c57604081890312156112e15760008081fd5b6112e9611141565b81356112f481611079565b815281850135858201528352918301916040016112c8565b509695505050505050565b600060a0823603121561132957600080fd5b61133161116a565b8235815261134160208401610fed565b6020820152604083013567ffffffffffffffff8082111561136157600080fd5b61136d368387016111dc565b6040840152606085013591508082111561138657600080fd5b611392368387016111dc565b606084015260808501359150808211156113ab57600080fd5b506113b83682860161126a565b60808301525092915050565b6000826113fa577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b60006020828403121561141157600080fd5b8151610f4d81611079565b6000604067ffffffffffffffff851683526020604081850152845160a0604086015261144b60e0860182610f76565b9050818601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808784030160608801526114868383610f76565b6040890151888203830160808a01528051808352908601945060009350908501905b808410156114e7578451805173ffffffffffffffffffffffffffffffffffffffff168352860151868301529385019360019390930192908601906114a8565b50606089015173ffffffffffffffffffffffffffffffffffffffff1660a08901526080890151888203830160c08a015295506115238187610f76565b9a9950505050505050505050565b60006020828403121561154357600080fd5b5051919050565b80820180821115610493577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000818000a", } var SelfFundedPingPongABI = SelfFundedPingPongMetaData.ABI @@ -272,6 +272,28 @@ func (_SelfFundedPingPong *SelfFundedPingPongCallerSession) GetFeeToken() (commo return _SelfFundedPingPong.Contract.GetFeeToken(&_SelfFundedPingPong.CallOpts) } +func (_SelfFundedPingPong *SelfFundedPingPongCaller) GetOutOfOrderExecution(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _SelfFundedPingPong.contract.Call(opts, &out, "getOutOfOrderExecution") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) GetOutOfOrderExecution() (bool, error) { + return _SelfFundedPingPong.Contract.GetOutOfOrderExecution(&_SelfFundedPingPong.CallOpts) +} + +func (_SelfFundedPingPong *SelfFundedPingPongCallerSession) GetOutOfOrderExecution() (bool, error) { + return _SelfFundedPingPong.Contract.GetOutOfOrderExecution(&_SelfFundedPingPong.CallOpts) +} + func (_SelfFundedPingPong *SelfFundedPingPongCaller) GetRouter(opts *bind.CallOpts) (common.Address, error) { var out []interface{} err := _SelfFundedPingPong.contract.Call(opts, &out, "getRouter") @@ -466,6 +488,18 @@ func (_SelfFundedPingPong *SelfFundedPingPongTransactorSession) SetCounterpartCh return _SelfFundedPingPong.Contract.SetCounterpartChainSelector(&_SelfFundedPingPong.TransactOpts, chainSelector) } +func (_SelfFundedPingPong *SelfFundedPingPongTransactor) SetOutOfOrderExecution(opts *bind.TransactOpts, outOfOrderExecution bool) (*types.Transaction, error) { + return _SelfFundedPingPong.contract.Transact(opts, "setOutOfOrderExecution", outOfOrderExecution) +} + +func (_SelfFundedPingPong *SelfFundedPingPongSession) SetOutOfOrderExecution(outOfOrderExecution bool) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SetOutOfOrderExecution(&_SelfFundedPingPong.TransactOpts, outOfOrderExecution) +} + +func (_SelfFundedPingPong *SelfFundedPingPongTransactorSession) SetOutOfOrderExecution(outOfOrderExecution bool) (*types.Transaction, error) { + return _SelfFundedPingPong.Contract.SetOutOfOrderExecution(&_SelfFundedPingPong.TransactOpts, outOfOrderExecution) +} + func (_SelfFundedPingPong *SelfFundedPingPongTransactor) SetPaused(opts *bind.TransactOpts, pause bool) (*types.Transaction, error) { return _SelfFundedPingPong.contract.Transact(opts, "setPaused", pause) } @@ -735,6 +769,123 @@ func (_SelfFundedPingPong *SelfFundedPingPongFilterer) ParseFunded(log types.Log return event, nil } +type SelfFundedPingPongOutOfOrderExecutionChangeIterator struct { + Event *SelfFundedPingPongOutOfOrderExecutionChange + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *SelfFundedPingPongOutOfOrderExecutionChangeIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongOutOfOrderExecutionChange) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(SelfFundedPingPongOutOfOrderExecutionChange) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *SelfFundedPingPongOutOfOrderExecutionChangeIterator) Error() error { + return it.fail +} + +func (it *SelfFundedPingPongOutOfOrderExecutionChangeIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type SelfFundedPingPongOutOfOrderExecutionChange struct { + IsOutOfOrder bool + Raw types.Log +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) FilterOutOfOrderExecutionChange(opts *bind.FilterOpts) (*SelfFundedPingPongOutOfOrderExecutionChangeIterator, error) { + + logs, sub, err := _SelfFundedPingPong.contract.FilterLogs(opts, "OutOfOrderExecutionChange") + if err != nil { + return nil, err + } + return &SelfFundedPingPongOutOfOrderExecutionChangeIterator{contract: _SelfFundedPingPong.contract, event: "OutOfOrderExecutionChange", logs: logs, sub: sub}, nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) WatchOutOfOrderExecutionChange(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongOutOfOrderExecutionChange) (event.Subscription, error) { + + logs, sub, err := _SelfFundedPingPong.contract.WatchLogs(opts, "OutOfOrderExecutionChange") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(SelfFundedPingPongOutOfOrderExecutionChange) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "OutOfOrderExecutionChange", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_SelfFundedPingPong *SelfFundedPingPongFilterer) ParseOutOfOrderExecutionChange(log types.Log) (*SelfFundedPingPongOutOfOrderExecutionChange, error) { + event := new(SelfFundedPingPongOutOfOrderExecutionChange) + if err := _SelfFundedPingPong.contract.UnpackLog(event, "OutOfOrderExecutionChange", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type SelfFundedPingPongOwnershipTransferRequestedIterator struct { Event *SelfFundedPingPongOwnershipTransferRequested @@ -1247,6 +1398,8 @@ func (_SelfFundedPingPong *SelfFundedPingPong) ParseLog(log types.Log) (generate return _SelfFundedPingPong.ParseCountIncrBeforeFundingSet(log) case _SelfFundedPingPong.abi.Events["Funded"].ID: return _SelfFundedPingPong.ParseFunded(log) + case _SelfFundedPingPong.abi.Events["OutOfOrderExecutionChange"].ID: + return _SelfFundedPingPong.ParseOutOfOrderExecutionChange(log) case _SelfFundedPingPong.abi.Events["OwnershipTransferRequested"].ID: return _SelfFundedPingPong.ParseOwnershipTransferRequested(log) case _SelfFundedPingPong.abi.Events["OwnershipTransferred"].ID: @@ -1269,6 +1422,10 @@ func (SelfFundedPingPongFunded) Topic() common.Hash { return common.HexToHash("0x302777af5d26fab9dd5120c5f1307c65193ebc51daf33244ada4365fab10602c") } +func (SelfFundedPingPongOutOfOrderExecutionChange) Topic() common.Hash { + return common.HexToHash("0x05a3fef9935c9013a24c6193df2240d34fcf6b0ebf8786b85efe8401d696cdd9") +} + func (SelfFundedPingPongOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } @@ -1298,6 +1455,8 @@ type SelfFundedPingPongInterface interface { GetFeeToken(opts *bind.CallOpts) (common.Address, error) + GetOutOfOrderExecution(opts *bind.CallOpts) (bool, error) + GetRouter(opts *bind.CallOpts) (common.Address, error) IsPaused(opts *bind.CallOpts) (bool, error) @@ -1322,6 +1481,8 @@ type SelfFundedPingPongInterface interface { SetCounterpartChainSelector(opts *bind.TransactOpts, chainSelector uint64) (*types.Transaction, error) + SetOutOfOrderExecution(opts *bind.TransactOpts, outOfOrderExecution bool) (*types.Transaction, error) + SetPaused(opts *bind.TransactOpts, pause bool) (*types.Transaction, error) StartPingPong(opts *bind.TransactOpts) (*types.Transaction, error) @@ -1340,6 +1501,12 @@ type SelfFundedPingPongInterface interface { ParseFunded(log types.Log) (*SelfFundedPingPongFunded, error) + FilterOutOfOrderExecutionChange(opts *bind.FilterOpts) (*SelfFundedPingPongOutOfOrderExecutionChangeIterator, error) + + WatchOutOfOrderExecutionChange(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongOutOfOrderExecutionChange) (event.Subscription, error) + + ParseOutOfOrderExecutionChange(log types.Log) (*SelfFundedPingPongOutOfOrderExecutionChange, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*SelfFundedPingPongOwnershipTransferRequestedIterator, error) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *SelfFundedPingPongOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index c9562db7d9..bb45cb27ce 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -26,12 +26,12 @@ multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRate multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin aa299e0c2659d53aad4eace4d66be0e734b1366008593669cf30361ff529da6a nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 6f64e1083b356c06ee66b9138e398b9c97a4cd3e8c9ec38cf3010cebc79af536 ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 -ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 1588313bb5e781d181a825247d30828f59007700f36b4b9b00391592b06ff4b4 +ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 4e51d70bdb6d951041518a3d7fd3b33ba8d3954bcc3d078318055b833b880324 price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 8f4bdaa4d8239429ae4e047ab06d445bad42234a05bb7c99ba6141bd811e1722 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 75be86323c227917a9bbc3f799d7ed02f92db546653a36db30ed0ebe64461353 report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin c07af8433bf8dbc7981725b18922a9c4e2dea068dd204bc62adc0e926cb499c3 router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 2e4f0a7826c8abb49d882bb49fc5ff20a186dbd3137624b9097ffed903ae4888 -self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 86e169636e5633854ed0b709c804066b615040bceba25aa5137450fbe6f76fa3 +self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 4f339db2b670b88214b738efb7a714be9d50fa32c8008710b607d58670b22074 token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 942be7d1681ac102e0615bee13f76838ebb0b261697cf1270d2bf82c12e57aeb token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 7c01fd89f5153baa4d7409d14beabb3f861abfbf8880d3c6d06802cc398570f9 usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin 8e7eae4c7277ce4a0092cca815c046cc49094028c23d2d113de9335fa4358030 From 5d7951391ad78a63cbb7b9376045bece4263f655 Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Fri, 16 Aug 2024 13:16:41 +0200 Subject: [PATCH 209/432] fix hh compile and bump publish-prod version (#1299) --- contracts/hardhat.config.ts | 10 ++++++---- contracts/package.json | 2 +- contracts/src/v0.8/ccip/test/BaseTest.t.sol | 2 -- .../ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol | 3 +++ 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 73e70081e9..65934d3866 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -21,8 +21,10 @@ subtask(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS).setAction( async (_, __, runSuper) => { const paths = await runSuper() const noTests = paths.filter((p: string) => !p.endsWith('.t.sol')) - const noCCIP = noTests.filter((p: string) => !p.includes('/v0.8/ccip')) - return noCCIP.filter( + const noCCIPTests = noTests.filter( + (p: string) => !p.includes('/v0.8/ccip/test'), + ) + return noCCIPTests.filter( (p: string) => !p.includes('src/v0.8/vendor/forge-std'), ) }, @@ -39,8 +41,8 @@ let config = { paths: { artifacts: './artifacts', cache: './cache', - sources: './src', - tests: './test', + sources: './src/v0.8', + tests: './test/v0.8', }, typechain: { outDir: './typechain', diff --git a/contracts/package.json b/contracts/package.json index 14292e16a5..e9dedf9578 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -18,7 +18,7 @@ "prepare": "chmod +x .husky/prepare.sh && ./.husky/prepare.sh", "prepublishOnly": "pnpm compile && ./scripts/prepublish_generate_abi_folder", "publish-beta": "pnpm publish --tag beta", - "publish-prod": "npm dist-tag add @chainlink/contracts-ccip@1.2.1 latest", + "publish-prod": "npm dist-tag add @chainlink/contracts-ccip@1.5.0 latest", "solhint:ccip": "solhint --max-warnings 0 \"./src/v0.8/ccip/**/*.sol\"", "solhint": "solhint --max-warnings 0 \"./src/v0.8/**/*.sol\"" }, diff --git a/contracts/src/v0.8/ccip/test/BaseTest.t.sol b/contracts/src/v0.8/ccip/test/BaseTest.t.sol index dba9e286ef..7570447cee 100644 --- a/contracts/src/v0.8/ccip/test/BaseTest.t.sol +++ b/contracts/src/v0.8/ccip/test/BaseTest.t.sol @@ -61,8 +61,6 @@ contract BaseTest is Test { // OffRamp uint32 internal constant MAX_DATA_SIZE = 30_000; uint16 internal constant MAX_TOKENS_LENGTH = 5; - uint32 internal constant MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS = 200_000; - uint32 internal constant MAX_TOKEN_POOL_TRANSFER_GAS = 50_000; uint16 internal constant GAS_FOR_CALL_EXACT_CHECK = 5000; uint32 internal constant PERMISSION_LESS_EXECUTION_THRESHOLD_SECONDS = 500; uint32 internal constant MAX_GAS_LIMIT = 4_000_000; diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol index 4aef61f052..a0f3c02708 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol @@ -229,6 +229,9 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba }); } + uint32 internal constant MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS = 200_000; + uint32 internal constant MAX_TOKEN_POOL_TRANSFER_GAS = 50_000; + function _generateDynamicMultiOffRampConfig(address priceRegistry) internal pure From b866aafd27ad78b69539b61e2067b8d0b7322cea Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Fri, 16 Aug 2024 17:30:52 +0200 Subject: [PATCH 210/432] add getPreviousPool (#1312) ## Motivation getPreviousPool was missing ## Solution Add getPreviousPool --- contracts/gas-snapshots/ccip.gas-snapshot | 19 +++++++------ .../src/v0.8/ccip/pools/LegacyPoolWrapper.sol | 5 ++++ .../ccip/test/legacy/TokenPoolAndProxy.t.sol | 13 +++++++++ .../burn_mint_token_pool_and_proxy.go | 28 +++++++++++++++++-- ...urn_with_from_mint_token_pool_and_proxy.go | 28 +++++++++++++++++-- .../lock_release_token_pool_and_proxy.go | 28 +++++++++++++++++-- ...rapper-dependency-versions-do-not-edit.txt | 6 ++-- 7 files changed, 109 insertions(+), 18 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index ab6f3c64ec..2e407f5ebb 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -500,10 +500,10 @@ EtherSenderReceiverTest_validatedMessage:test_validatedMessage_emptyDataOverwrit EtherSenderReceiverTest_validatedMessage:test_validatedMessage_invalidTokenAmounts() (gas: 17895) EtherSenderReceiverTest_validatedMessage:test_validatedMessage_tokenOverwrittenToWeth() (gas: 25287) EtherSenderReceiverTest_validatedMessage:test_validatedMessage_validMessage_extraArgs() (gas: 26292) -LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Revert() (gas: 10992) -LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Success() (gas: 18058) -LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3359294) -LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3355693) +LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Revert() (gas: 10970) +LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Success() (gas: 17992) +LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3368110) +LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3364509) LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_Unauthorized_Revert() (gas: 11380) LockReleaseTokenPoolPoolAndProxy_supportsInterface:test_SupportsInterface_Success() (gas: 9977) LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60043) @@ -902,11 +902,12 @@ TokenAdminRegistry_setPool:test_setPool_Success() (gas: 35943) TokenAdminRegistry_setPool:test_setPool_ZeroAddressRemovesPool_Success() (gas: 30617) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_OnlyAdministrator_Revert() (gas: 18043) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_Success() (gas: 49390) -TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6064586) -TokenPoolAndProxy:test_lockOrBurn_burnWithFromMint_Success() (gas: 6096059) -TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6310909) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6908121) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7092212) +TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6070353) +TokenPoolAndProxy:test_lockOrBurn_burnWithFromMint_Success() (gas: 6101826) +TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6319594) +TokenPoolAndProxy:test_setPreviousPool_Success() (gas: 3387124) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6913796) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7097821) TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2209837) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12089) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23324) diff --git a/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol b/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol index 58eac2a57d..bc5adb0b2d 100644 --- a/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol +++ b/contracts/src/v0.8/ccip/pools/LegacyPoolWrapper.sol @@ -55,6 +55,11 @@ abstract contract LegacyPoolWrapper is TokenPool { emit LegacyPoolChanged(oldPrevPool, prevPool); } + /// @notice Returns the address of the previous pool. + function getPreviousPool() external view returns (address) { + return address(s_previousPool); + } + function _hasLegacyPool() internal view returns (bool) { return address(s_previousPool) != address(0); } diff --git a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol index d743b4c9e1..a69ca0952c 100644 --- a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol +++ b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol @@ -507,6 +507,19 @@ contract TokenPoolAndProxy is EVM2EVMOnRampSetup { }) ); } + + function test_setPreviousPool_Success() public { + LockReleaseTokenPoolAndProxy pool = + new LockReleaseTokenPoolAndProxy(s_token, new address[](0), address(s_mockRMN), true, address(s_sourceRouter)); + + assertEq(pool.getPreviousPool(), address(0)); + + address newLegacyPool = makeAddr("new_legacy_pool"); + + vm.startPrank(OWNER); + pool.setPreviousPool(IPoolPriorTo1_5(newLegacyPool)); + assertEq(pool.getPreviousPool(), address(newLegacyPool)); + } } //// diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go index 0838134fdd..4797421171 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool_and_proxy/burn_mint_token_pool_and_proxy.go @@ -82,8 +82,8 @@ type TokenPoolChainUpdate struct { } var BurnMintTokenPoolAndProxyMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b506040516200494a3803806200494a833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050808214620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051614214620007366000396000818161053701528181611abf0152612511015260008181610511015281816118520152611d7201526000818161025a015281816102af0152818161075701528181610ddd0152818161177201528181611c9201528181611e78015281816124a701526126fc01526142146000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639766b93211610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104fc578063dc0bd9711461050f578063e0351e1314610535578063f2fde38b1461055b57600080fd5b8063c0d78655146104ae578063c4bffe2b146104c1578063c75eea9c146104d6578063cf7401f3146104e957600080fd5b8063a8d87a3b116100de578063a8d87a3b146103fb578063af58d59f1461040e578063b0f479a11461047d578063b79465801461049b57600080fd5b80639766b932146103b35780639a4575b9146103c6578063a7cd63b7146103e657600080fd5b80636d3d1a58116101715780637d54534e1161014b5780637d54534e1461035c57806383826b2b1461036f5780638926f54f146103825780638da5cb5b1461039557600080fd5b80636d3d1a581461032357806378a010b21461034157806379ba50971461035457600080fd5b806321df0da7116101ad57806321df0da714610258578063240028e81461029f57806339077537146102ec57806354c8a4f31461030e57600080fd5b806301ffc9a7146101d45780630a2fd493146101fc578063181f5a771461021c575b600080fd5b6101e76101e23660046131a9565b61056e565b60405190151581526020015b60405180910390f35b61020f61020a366004613208565b610653565b6040516101f39190613291565b61020f6040518060400160405280601f81526020017f4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e300081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e76102ad3660046132d1565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102ff6102fa3660046132ee565b610703565b604051905181526020016101f3565b61032161031c366004613376565b6108bb565b005b60085473ffffffffffffffffffffffffffffffffffffffff1661027a565b61032161034f3660046133e2565b610936565b610321610aaa565b61032161036a3660046132d1565b610ba7565b6101e761037d366004613465565b610bf6565b6101e7610390366004613208565b610cc3565b60005473ffffffffffffffffffffffffffffffffffffffff1661027a565b6103216103c13660046132d1565b610cda565b6103d96103d436600461349c565b610d69565b6040516101f391906134d7565b6103ee610ed9565b6040516101f39190613537565b61027a610409366004613208565b503090565b61042161041c366004613208565b610eea565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff1661027a565b61020f6104a9366004613208565b610fbf565b6103216104bc3660046132d1565b610fea565b6104c96110be565b6040516101f39190613591565b6104216104e4366004613208565b611176565b6103216104f7366004613748565b611248565b61032161050a36600461378d565b6112d1565b7f000000000000000000000000000000000000000000000000000000000000000061027a565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b6103216105693660046132d1565b611757565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061060157507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061064d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061067e906137cf565b80601f01602080910402602001604051908101604052809291908181526020018280546106aa906137cf565b80156106f75780601f106106cc576101008083540402835291602001916106f7565b820191906000526020600020905b8154815290600101906020018083116106da57829003601f168201915b50505050509050919050565b60408051602081019091526000815261072361071e836138be565b61176b565b60095473ffffffffffffffffffffffffffffffffffffffff166108195773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961078c60608501604086016132d1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b1580156107fc57600080fd5b505af1158015610810573d6000803e3d6000fd5b5050505061082a565b61082a610825836138be565b61199c565b61083a60608301604084016132d1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161089c91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108c3611a3a565b61093084848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611abd92505050565b50505050565b61093e611a3a565b61094783610cc3565b61098e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109b5906137cf565b80601f01602080910402602001604051908101604052809291908181526020018280546109e1906137cf565b8015610a2e5780601f10610a0357610100808354040283529160200191610a2e565b820191906000526020600020905b815481529060010190602001808311610a1157829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a5d838583613a03565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a9c93929190613b1d565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610985565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610baf611a3a565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610cbc5750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610c98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbc9190613b81565b9392505050565b600061064d600567ffffffffffffffff8416611c73565b610ce2611a3a565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d8e610d8983613b9e565b611c8b565b60095473ffffffffffffffffffffffffffffffffffffffff16610e53576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610e3657600080fd5b505af1158015610e4a573d6000803e3d6000fd5b50505050610e64565b610e64610e5f83613b9e565b611e55565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610ebe8460200160208101906104a99190613208565b81526040805160208181019092526000815291015292915050565b6060610ee56002611f6f565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261064d90611f7c565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061067e906137cf565b610ff2611a3a565b73ffffffffffffffffffffffffffffffffffffffff811661103f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d5d565b606060006110cc6005611f6f565b90506000815167ffffffffffffffff8111156110ea576110ea6135d3565b604051908082528060200260200182016040528015611113578160200160208202803683370190505b50905060005b825181101561116f5782818151811061113457611134613c40565b602002602001015182828151811061114e5761114e613c40565b67ffffffffffffffff90921660209283029190910190910152600101611119565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261064d90611f7c565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611288575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112c1576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610985565b6112cc83838361202e565b505050565b6112d9611a3a565b60005b818110156112cc5760008383838181106112f8576112f8613c40565b905060200281019061130a9190613c6f565b61131390613cad565b90506113288160800151826020015115612118565b61133b8160a00151826020015115612118565b80602001511561163757805161135d9060059067ffffffffffffffff16612251565b6113a25780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610985565b60408101515115806113b75750606081015151155b156113ee576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115cf9082613d61565b50606082015160058201906115e49082613d61565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061162a9493929190613e7b565b60405180910390a161174e565b805161164f9060059067ffffffffffffffff1661225d565b6116945780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610985565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116fd600483018261315b565b61170b60058301600061315b565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112dc565b61175f611a3a565b61176881612269565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146118005760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610985565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156118ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d29190613b81565b15611909576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611916816020015161235e565b60006119258260200151610653565b9050805160001480611949575080805190602001208260a001518051906020012014155b15611986578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109859190613291565b61199882602001518360600151612484565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611a059490939291600401613f14565b600060405180830381600087803b158015611a1f57600080fd5b505af1158015611a33573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611abb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610985565b565b7f0000000000000000000000000000000000000000000000000000000000000000611b14576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611baa576000838281518110611b3457611b34613c40565b60200260200101519050611b528160026124cb90919063ffffffff16565b15611ba15760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611b17565b5060005b81518110156112cc576000828281518110611bcb57611bcb613c40565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c0f5750611c6b565b611c1a6002826124ed565b15611c695760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611bae565b60008181526001830160205260408120541515610cbc565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611d205760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610985565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611dce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df29190613b81565b15611e29576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e36816040015161250f565b611e43816020015161258e565b611768816020015182606001516126dc565b6009546060820151611ea29173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690612720565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611f0a94939291600401613f75565b6000604051808303816000875af1158015611f29573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119989190810190613fd5565b60606000610cbc836127ad565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261200a82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611fee9190614072565b85608001516fffffffffffffffffffffffffffffffff16612808565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61203783610cc3565b612079576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610985565b612084826000612118565b67ffffffffffffffff831660009081526007602052604090206120a79083612832565b6120b2816000612118565b67ffffffffffffffff831660009081526007602052604090206120d89060020182612832565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161210b93929190614085565b60405180910390a1505050565b8151156121df5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061216e575060408201516fffffffffffffffffffffffffffffffff16155b156121a757816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109859190614108565b8015611998576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612218575060208201516fffffffffffffffffffffffffffffffff1615155b1561199857816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109859190614108565b6000610cbc83836129d4565b6000610cbc8383612a23565b3373ffffffffffffffffffffffffffffffffffffffff8216036122e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610985565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61236781610cc3565b6123a9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610985565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612428573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061244c9190613b81565b611768576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610985565b67ffffffffffffffff8216600090815260076020526040902061199890600201827f0000000000000000000000000000000000000000000000000000000000000000612b16565b6000610cbc8373ffffffffffffffffffffffffffffffffffffffff8416612a23565b6000610cbc8373ffffffffffffffffffffffffffffffffffffffff84166129d4565b7f00000000000000000000000000000000000000000000000000000000000000001561176857612540600282612e99565b611768576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610985565b61259781610cc3565b6125d9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610985565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126769190614144565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611768576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610985565b67ffffffffffffffff8216600090815260076020526040902061199890827f0000000000000000000000000000000000000000000000000000000000000000612b16565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526112cc908490612ec8565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106f757602002820191906000526020600020905b8154815260200190600101908083116127e95750505050509050919050565b6000612827856128188486614161565b6128229087614178565b612fd4565b90505b949350505050565b815460009061285b90700100000000000000000000000000000000900463ffffffff1642614072565b905080156128fd57600183015483546128a3916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612808565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612923916fffffffffffffffffffffffffffffffff9081169116612fd4565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061210b908490614108565b6000818152600183016020526040812054612a1b5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561064d565b50600061064d565b60008181526001830160205260408120548015612b0c576000612a47600183614072565b8554909150600090612a5b90600190614072565b9050808214612ac0576000866000018281548110612a7b57612a7b613c40565b9060005260206000200154905080876000018481548110612a9e57612a9e613c40565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ad157612ad161418b565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061064d565b600091505061064d565b825474010000000000000000000000000000000000000000900460ff161580612b3d575081155b15612b4757505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612b8d90700100000000000000000000000000000000900463ffffffff1642614072565b90508015612c4d5781831115612bcf576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612c099083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612808565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612d045773ffffffffffffffffffffffffffffffffffffffff8416612cac576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610985565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610985565b84831015612e175760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612d489082614072565b612d52878a614072565b612d5c9190614178565b612d6691906141ba565b905073ffffffffffffffffffffffffffffffffffffffff8616612dbf576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610985565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610985565b612e218584614072565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610cbc565b6000612f2a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612fea9092919063ffffffff16565b8051909150156112cc5780806020019051810190612f489190613b81565b6112cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610985565b6000818310612fe35781610cbc565b5090919050565b606061282a8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161301e91906141f5565b60006040518083038185875af1925050503d806000811461305b576040519150601f19603f3d011682016040523d82523d6000602084013e613060565b606091505b50915091506130718783838761307c565b979650505050505050565b6060831561311257825160000361310b5773ffffffffffffffffffffffffffffffffffffffff85163b61310b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610985565b508161282a565b61282a83838151156131275781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109859190613291565b508054613167906137cf565b6000825580601f10613177575050565b601f01602090049060005260206000209081019061176891905b808211156131a55760008155600101613191565b5090565b6000602082840312156131bb57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610cbc57600080fd5b803567ffffffffffffffff8116811461320357600080fd5b919050565b60006020828403121561321a57600080fd5b610cbc826131eb565b60005b8381101561323e578181015183820152602001613226565b50506000910152565b6000815180845261325f816020860160208601613223565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610cbc6020830184613247565b73ffffffffffffffffffffffffffffffffffffffff8116811461176857600080fd5b8035613203816132a4565b6000602082840312156132e357600080fd5b8135610cbc816132a4565b60006020828403121561330057600080fd5b813567ffffffffffffffff81111561331757600080fd5b82016101008185031215610cbc57600080fd5b60008083601f84011261333c57600080fd5b50813567ffffffffffffffff81111561335457600080fd5b6020830191508360208260051b850101111561336f57600080fd5b9250929050565b6000806000806040858703121561338c57600080fd5b843567ffffffffffffffff808211156133a457600080fd5b6133b08883890161332a565b909650945060208701359150808211156133c957600080fd5b506133d68782880161332a565b95989497509550505050565b6000806000604084860312156133f757600080fd5b613400846131eb565b9250602084013567ffffffffffffffff8082111561341d57600080fd5b818601915086601f83011261343157600080fd5b81358181111561344057600080fd5b87602082850101111561345257600080fd5b6020830194508093505050509250925092565b6000806040838503121561347857600080fd5b613481836131eb565b91506020830135613491816132a4565b809150509250929050565b6000602082840312156134ae57600080fd5b813567ffffffffffffffff8111156134c557600080fd5b820160a08185031215610cbc57600080fd5b6020815260008251604060208401526134f36060840182613247565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261352e8282613247565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613553565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358557835167ffffffffffffffff16835292840192918401916001016135ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613626576136266135d3565b60405290565b60405160c0810167ffffffffffffffff81118282101715613626576136266135d3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613696576136966135d3565b604052919050565b801515811461176857600080fd5b80356132038161369e565b80356fffffffffffffffffffffffffffffffff8116811461320357600080fd5b6000606082840312156136e957600080fd5b6040516060810181811067ffffffffffffffff8211171561370c5761370c6135d3565b604052905080823561371d8161369e565b815261372b602084016136b7565b602082015261373c604084016136b7565b60408201525092915050565b600080600060e0848603121561375d57600080fd5b613766846131eb565b925061377585602086016136d7565b915061378485608086016136d7565b90509250925092565b600080602083850312156137a057600080fd5b823567ffffffffffffffff8111156137b757600080fd5b6137c38582860161332a565b90969095509350505050565b600181811c908216806137e357607f821691505b60208210810361381c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff82111561383c5761383c6135d3565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261387957600080fd5b813561388c61388782613822565b61364f565b8181528460208386010111156138a157600080fd5b816020850160208301376000918101602001919091529392505050565b600061010082360312156138d157600080fd5b6138d9613602565b823567ffffffffffffffff808211156138f157600080fd5b6138fd36838701613868565b835261390b602086016131eb565b602084015261391c604086016132c6565b604084015260608501356060840152613937608086016132c6565b608084015260a085013591508082111561395057600080fd5b61395c36838701613868565b60a084015260c085013591508082111561397557600080fd5b61398136838701613868565b60c084015260e085013591508082111561399a57600080fd5b506139a736828601613868565b60e08301525092915050565b601f8211156112cc576000816000526020600020601f850160051c810160208610156139dc5750805b601f850160051c820191505b818110156139fb578281556001016139e8565b505050505050565b67ffffffffffffffff831115613a1b57613a1b6135d3565b613a2f83613a2983546137cf565b836139b3565b6000601f841160018114613a815760008515613a4b5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a33565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613ad05786850135825560209485019460019092019101613ab0565b5086821015613b0b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613b306040830186613247565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613b9357600080fd5b8151610cbc8161369e565b600060a08236031215613bb057600080fd5b60405160a0810167ffffffffffffffff8282108183111715613bd457613bd46135d3565b816040528435915080821115613be957600080fd5b50613bf636828601613868565b825250613c05602084016131eb565b60208201526040830135613c18816132a4565b6040820152606083810135908201526080830135613c35816132a4565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ca357600080fd5b9190910192915050565b60006101408236031215613cc057600080fd5b613cc861362c565b613cd1836131eb565b8152613cdf602084016136ac565b6020820152604083013567ffffffffffffffff80821115613cff57600080fd5b613d0b36838701613868565b60408401526060850135915080821115613d2457600080fd5b50613d3136828601613868565b606083015250613d4436608085016136d7565b6080820152613d563660e085016136d7565b60a082015292915050565b815167ffffffffffffffff811115613d7b57613d7b6135d3565b613d8f81613d8984546137cf565b846139b3565b602080601f831160018114613de25760008415613dac5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139fb565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e2f57888601518255948401946001909101908401613e10565b5085821015613e6b57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613e9f81840187613247565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613edd9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e083015261352e565b60a081526000613f2760a0830187613247565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613fa460a0830186613247565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613fe757600080fd5b815167ffffffffffffffff811115613ffe57600080fd5b8201601f8101841361400f57600080fd5b805161401d61388782613822565b81815285602083850101111561403257600080fd5b61352e826020830160208601613223565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561064d5761064d614043565b67ffffffffffffffff8416815260e081016140d160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261282a565b6060810161064d82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561415657600080fd5b8151610cbc816132a4565b808202811582820484141761064d5761064d614043565b8082018082111561064d5761064d614043565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826141f0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613ca381846020870161322356fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPreviousPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b506040516200497338038062004973833981016040819052620000349162000554565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200017e565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000229565b505050505050505050505050620006b2565b336001600160a01b03821603620001d85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200024a576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002d55760008382815181106200026e576200026e62000664565b602090810291909101015190506200028860028262000386565b15620002cb576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200024d565b5060005b815181101562000381576000828281518110620002fa57620002fa62000664565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000326575062000378565b62000333600282620003a6565b1562000376576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002d9565b505050565b60006200039d836001600160a01b038416620003bd565b90505b92915050565b60006200039d836001600160a01b038416620004c1565b60008181526001830160205260408120548015620004b6576000620003e46001836200067a565b8554909150600090620003fa906001906200067a565b9050808214620004665760008660000182815481106200041e576200041e62000664565b906000526020600020015490508087600001848154811062000444576200044462000664565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200047a576200047a6200069c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a0565b6000915050620003a0565b60008181526001830160205260408120546200050a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a0565b506000620003a0565b6001600160a01b03811681146200052957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200054f8162000513565b919050565b600080600080608085870312156200056b57600080fd5b8451620005788162000513565b602086810151919550906001600160401b03808211156200059857600080fd5b818801915088601f830112620005ad57600080fd5b815181811115620005c257620005c26200052c565b8060051b604051601f19603f83011681018181108582111715620005ea57620005ea6200052c565b60405291825284820192508381018501918b8311156200060957600080fd5b938501935b828510156200063257620006228562000542565b845293850193928501926200060e565b809850505050505050620006496040860162000542565b9150620006596060860162000542565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a057634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161423d620007366000396000818161056001528181611ae8015261253a01526000818161053a0152818161187b0152611d9b015260008181610265015281816102ba0152818161078001528181610e060152818161179b01528181611cbb01528181611ea1015281816124d00152612725015261423d6000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80639a4575b911610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc14610525578063dc0bd97114610538578063e0351e131461055e578063f2fde38b1461058457600080fd5b8063c0d78655146104d7578063c4bffe2b146104ea578063c75eea9c146104ff578063cf7401f31461051257600080fd5b8063a8d87a3b116100de578063a8d87a3b14610424578063af58d59f14610437578063b0f479a1146104a6578063b7946580146104c457600080fd5b80639a4575b9146103d1578063a2b261d8146103f1578063a7cd63b71461040f57600080fd5b80636d3d1a581161017c57806383826b2b1161014b57806383826b2b1461037a5780638926f54f1461038d5780638da5cb5b146103a05780639766b932146103be57600080fd5b80636d3d1a581461032e57806378a010b21461034c57806379ba50971461035f5780637d54534e1461036757600080fd5b806321df0da7116101b857806321df0da714610263578063240028e8146102aa57806339077537146102f757806354c8a4f31461031957600080fd5b806301ffc9a7146101df5780630a2fd49314610207578063181f5a7714610227575b600080fd5b6101f26101ed3660046131d2565b610597565b60405190151581526020015b60405180910390f35b61021a610215366004613231565b61067c565b6040516101fe91906132ba565b61021a6040518060400160405280601f81526020017f4275726e4d696e74546f6b656e506f6f6c416e6450726f787920312e352e300081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fe565b6101f26102b83660046132fa565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61030a610305366004613317565b61072c565b604051905181526020016101fe565b61032c61032736600461339f565b6108e4565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610285565b61032c61035a36600461340b565b61095f565b61032c610ad3565b61032c6103753660046132fa565b610bd0565b6101f261038836600461348e565b610c1f565b6101f261039b366004613231565b610cec565b60005473ffffffffffffffffffffffffffffffffffffffff16610285565b61032c6103cc3660046132fa565b610d03565b6103e46103df3660046134c5565b610d92565b6040516101fe9190613500565b60095473ffffffffffffffffffffffffffffffffffffffff16610285565b610417610f02565b6040516101fe9190613560565b610285610432366004613231565b503090565b61044a610445366004613231565b610f13565b6040516101fe919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610285565b61021a6104d2366004613231565b610fe8565b61032c6104e53660046132fa565b611013565b6104f26110e7565b6040516101fe91906135ba565b61044a61050d366004613231565b61119f565b61032c610520366004613771565b611271565b61032c6105333660046137b6565b6112fa565b7f0000000000000000000000000000000000000000000000000000000000000000610285565b7f00000000000000000000000000000000000000000000000000000000000000006101f2565b61032c6105923660046132fa565b611780565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061062a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061067657507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106a7906137f8565b80601f01602080910402602001604051908101604052809291908181526020018280546106d3906137f8565b80156107205780601f106106f557610100808354040283529160200191610720565b820191906000526020600020905b81548152906001019060200180831161070357829003601f168201915b50505050509050919050565b60408051602081019091526000815261074c610747836138e7565b611794565b60095473ffffffffffffffffffffffffffffffffffffffff166108425773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107b560608501604086016132fa565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561082557600080fd5b505af1158015610839573d6000803e3d6000fd5b50505050610853565b61085361084e836138e7565b6119c5565b61086360608301604084016132fa565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f084606001356040516108c591815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108ec611a63565b61095984848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ae692505050565b50505050565b610967611a63565b61097083610cec565b6109b7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109de906137f8565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0a906137f8565b8015610a575780601f10610a2c57610100808354040283529160200191610a57565b820191906000526020600020905b815481529060010190602001808311610a3a57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a86838583613a2c565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610ac593929190613b46565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016109ae565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610bd8611a63565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610ce55750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610cc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce59190613baa565b9392505050565b6000610676600567ffffffffffffffff8416611c9c565b610d0b611a63565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610db7610db283613bc7565b611cb4565b60095473ffffffffffffffffffffffffffffffffffffffff16610e7c576040517f42966c68000000000000000000000000000000000000000000000000000000008152606083013560048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610e5f57600080fd5b505af1158015610e73573d6000803e3d6000fd5b50505050610e8d565b610e8d610e8883613bc7565b611e7e565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610ee78460200160208101906104d29190613231565b81526040805160208181019092526000815291015292915050565b6060610f0e6002611f98565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261067690611fa5565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106a7906137f8565b61101b611a63565b73ffffffffffffffffffffffffffffffffffffffff8116611068576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d86565b606060006110f56005611f98565b90506000815167ffffffffffffffff811115611113576111136135fc565b60405190808252806020026020018201604052801561113c578160200160208202803683370190505b50905060005b82518110156111985782818151811061115d5761115d613c69565b602002602001015182828151811061117757611177613c69565b67ffffffffffffffff90921660209283029190910190910152600101611142565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261067690611fa5565b60085473ffffffffffffffffffffffffffffffffffffffff1633148015906112b1575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112ea576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016109ae565b6112f5838383612057565b505050565b611302611a63565b60005b818110156112f557600083838381811061132157611321613c69565b90506020028101906113339190613c98565b61133c90613cd6565b90506113518160800151826020015115612141565b6113648160a00151826020015115612141565b8060200151156116605780516113869060059067ffffffffffffffff1661227a565b6113cb5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016109ae565b60408101515115806113e05750606081015151155b15611417576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115f89082613d8a565b506060820151600582019061160d9082613d8a565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116539493929190613ea4565b60405180910390a1611777565b80516116789060059067ffffffffffffffff16612286565b6116bd5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016109ae565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906117266004830182613184565b611734600583016000613184565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611305565b611788611a63565b61179181612292565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146118295760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016109ae565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156118d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fb9190613baa565b15611932576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61193f8160200151612387565b600061194e826020015161067c565b9050805160001480611972575080805190602001208260a001518051906020012014155b156119af578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109ae91906132ba565b6119c1826020015183606001516124ad565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611a2e9490939291600401613f3d565b600060405180830381600087803b158015611a4857600080fd5b505af1158015611a5c573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016109ae565b565b7f0000000000000000000000000000000000000000000000000000000000000000611b3d576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611bd3576000838281518110611b5d57611b5d613c69565b60200260200101519050611b7b8160026124f490919063ffffffff16565b15611bca5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611b40565b5060005b81518110156112f5576000828281518110611bf457611bf4613c69565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c385750611c94565b611c43600282612516565b15611c925760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611bd7565b60008181526001830160205260408120541515610ce5565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611d495760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016109ae565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611df7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1b9190613baa565b15611e52576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e5f8160400151612538565b611e6c81602001516125b7565b61179181602001518260600151612705565b6009546060820151611ecb9173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690612749565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611f3394939291600401613f9e565b6000604051808303816000875af1158015611f52573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119c19190810190613ffe565b60606000610ce5836127d6565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261203382606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642612017919061409b565b85608001516fffffffffffffffffffffffffffffffff16612831565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61206083610cec565b6120a2576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016109ae565b6120ad826000612141565b67ffffffffffffffff831660009081526007602052604090206120d0908361285b565b6120db816000612141565b67ffffffffffffffff83166000908152600760205260409020612101906002018261285b565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051612134939291906140ae565b60405180910390a1505050565b8151156122085781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612197575060408201516fffffffffffffffffffffffffffffffff16155b156121d057816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109ae9190614131565b80156119c1576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612241575060208201516fffffffffffffffffffffffffffffffff1615155b156119c157816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109ae9190614131565b6000610ce583836129fd565b6000610ce58383612a4c565b3373ffffffffffffffffffffffffffffffffffffffff821603612311576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016109ae565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61239081610cec565b6123d2576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016109ae565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612451573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124759190613baa565b611791576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016109ae565b67ffffffffffffffff821660009081526007602052604090206119c190600201827f0000000000000000000000000000000000000000000000000000000000000000612b3f565b6000610ce58373ffffffffffffffffffffffffffffffffffffffff8416612a4c565b6000610ce58373ffffffffffffffffffffffffffffffffffffffff84166129fd565b7f00000000000000000000000000000000000000000000000000000000000000001561179157612569600282612ec2565b611791576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016109ae565b6125c081610cec565b612602576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016109ae565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561267b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269f919061416d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611791576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016109ae565b67ffffffffffffffff821660009081526007602052604090206119c190827f0000000000000000000000000000000000000000000000000000000000000000612b3f565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526112f5908490612ef1565b60608160000180548060200260200160405190810160405280929190818152602001828054801561072057602002820191906000526020600020905b8154815260200190600101908083116128125750505050509050919050565b600061285085612841848661418a565b61284b90876141a1565b612ffd565b90505b949350505050565b815460009061288490700100000000000000000000000000000000900463ffffffff164261409b565b9050801561292657600183015483546128cc916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612831565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461294c916fffffffffffffffffffffffffffffffff9081169116612ffd565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612134908490614131565b6000818152600183016020526040812054612a4457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610676565b506000610676565b60008181526001830160205260408120548015612b35576000612a7060018361409b565b8554909150600090612a849060019061409b565b9050808214612ae9576000866000018281548110612aa457612aa4613c69565b9060005260206000200154905080876000018481548110612ac757612ac7613c69565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612afa57612afa6141b4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610676565b6000915050610676565b825474010000000000000000000000000000000000000000900460ff161580612b66575081155b15612b7057505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612bb690700100000000000000000000000000000000900463ffffffff164261409b565b90508015612c765781831115612bf8576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612c329083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612831565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612d2d5773ffffffffffffffffffffffffffffffffffffffff8416612cd5576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016109ae565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016109ae565b84831015612e405760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612d71908261409b565b612d7b878a61409b565b612d8591906141a1565b612d8f91906141e3565b905073ffffffffffffffffffffffffffffffffffffffff8616612de8576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016109ae565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016109ae565b612e4a858461409b565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610ce5565b6000612f53826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130139092919063ffffffff16565b8051909150156112f55780806020019051810190612f719190613baa565b6112f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016109ae565b600081831061300c5781610ce5565b5090919050565b60606128538484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051613047919061421e565b60006040518083038185875af1925050503d8060008114613084576040519150601f19603f3d011682016040523d82523d6000602084013e613089565b606091505b509150915061309a878383876130a5565b979650505050505050565b6060831561313b5782516000036131345773ffffffffffffffffffffffffffffffffffffffff85163b613134576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109ae565b5081612853565b61285383838151156131505781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ae91906132ba565b508054613190906137f8565b6000825580601f106131a0575050565b601f01602090049060005260206000209081019061179191905b808211156131ce57600081556001016131ba565b5090565b6000602082840312156131e457600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ce557600080fd5b803567ffffffffffffffff8116811461322c57600080fd5b919050565b60006020828403121561324357600080fd5b610ce582613214565b60005b8381101561326757818101518382015260200161324f565b50506000910152565b6000815180845261328881602086016020860161324c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ce56020830184613270565b73ffffffffffffffffffffffffffffffffffffffff8116811461179157600080fd5b803561322c816132cd565b60006020828403121561330c57600080fd5b8135610ce5816132cd565b60006020828403121561332957600080fd5b813567ffffffffffffffff81111561334057600080fd5b82016101008185031215610ce557600080fd5b60008083601f84011261336557600080fd5b50813567ffffffffffffffff81111561337d57600080fd5b6020830191508360208260051b850101111561339857600080fd5b9250929050565b600080600080604085870312156133b557600080fd5b843567ffffffffffffffff808211156133cd57600080fd5b6133d988838901613353565b909650945060208701359150808211156133f257600080fd5b506133ff87828801613353565b95989497509550505050565b60008060006040848603121561342057600080fd5b61342984613214565b9250602084013567ffffffffffffffff8082111561344657600080fd5b818601915086601f83011261345a57600080fd5b81358181111561346957600080fd5b87602082850101111561347b57600080fd5b6020830194508093505050509250925092565b600080604083850312156134a157600080fd5b6134aa83613214565b915060208301356134ba816132cd565b809150509250929050565b6000602082840312156134d757600080fd5b813567ffffffffffffffff8111156134ee57600080fd5b820160a08185031215610ce557600080fd5b60208152600082516040602084015261351c6060840182613270565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526135578282613270565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156135ae57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161357c565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156135ae57835167ffffffffffffffff16835292840192918401916001016135d6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561364f5761364f6135fc565b60405290565b60405160c0810167ffffffffffffffff8111828210171561364f5761364f6135fc565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156136bf576136bf6135fc565b604052919050565b801515811461179157600080fd5b803561322c816136c7565b80356fffffffffffffffffffffffffffffffff8116811461322c57600080fd5b60006060828403121561371257600080fd5b6040516060810181811067ffffffffffffffff82111715613735576137356135fc565b6040529050808235613746816136c7565b8152613754602084016136e0565b6020820152613765604084016136e0565b60408201525092915050565b600080600060e0848603121561378657600080fd5b61378f84613214565b925061379e8560208601613700565b91506137ad8560808601613700565b90509250925092565b600080602083850312156137c957600080fd5b823567ffffffffffffffff8111156137e057600080fd5b6137ec85828601613353565b90969095509350505050565b600181811c9082168061380c57607f821691505b602082108103613845577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff821115613865576138656135fc565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126138a257600080fd5b81356138b56138b08261384b565b613678565b8181528460208386010111156138ca57600080fd5b816020850160208301376000918101602001919091529392505050565b600061010082360312156138fa57600080fd5b61390261362b565b823567ffffffffffffffff8082111561391a57600080fd5b61392636838701613891565b835261393460208601613214565b6020840152613945604086016132ef565b604084015260608501356060840152613960608086016132ef565b608084015260a085013591508082111561397957600080fd5b61398536838701613891565b60a084015260c085013591508082111561399e57600080fd5b6139aa36838701613891565b60c084015260e08501359150808211156139c357600080fd5b506139d036828601613891565b60e08301525092915050565b601f8211156112f5576000816000526020600020601f850160051c81016020861015613a055750805b601f850160051c820191505b81811015613a2457828155600101613a11565b505050505050565b67ffffffffffffffff831115613a4457613a446135fc565b613a5883613a5283546137f8565b836139dc565b6000601f841160018114613aaa5760008515613a745750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a5c565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613af95786850135825560209485019460019092019101613ad9565b5086821015613b34577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613b596040830186613270565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613bbc57600080fd5b8151610ce5816136c7565b600060a08236031215613bd957600080fd5b60405160a0810167ffffffffffffffff8282108183111715613bfd57613bfd6135fc565b816040528435915080821115613c1257600080fd5b50613c1f36828601613891565b825250613c2e60208401613214565b60208201526040830135613c41816132cd565b6040820152606083810135908201526080830135613c5e816132cd565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613ccc57600080fd5b9190910192915050565b60006101408236031215613ce957600080fd5b613cf1613655565b613cfa83613214565b8152613d08602084016136d5565b6020820152604083013567ffffffffffffffff80821115613d2857600080fd5b613d3436838701613891565b60408401526060850135915080821115613d4d57600080fd5b50613d5a36828601613891565b606083015250613d6d3660808501613700565b6080820152613d7f3660e08501613700565b60a082015292915050565b815167ffffffffffffffff811115613da457613da46135fc565b613db881613db284546137f8565b846139dc565b602080601f831160018114613e0b5760008415613dd55750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613a24565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e5857888601518255948401946001909101908401613e39565b5085821015613e9457878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613ec881840187613270565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613f069050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613557565b60a081526000613f5060a0830187613270565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613fcd60a0830186613270565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561401057600080fd5b815167ffffffffffffffff81111561402757600080fd5b8201601f8101841361403857600080fd5b80516140466138b08261384b565b81815285602083850101111561405b57600080fd5b61355782602083016020860161324c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106765761067661406c565b67ffffffffffffffff8416815260e081016140fa60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612853565b6060810161067682848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561417f57600080fd5b8151610ce5816132cd565b80820281158282048414176106765761067661406c565b808201808211156106765761067661406c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614219577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613ccc81846020870161324c56fea164736f6c6343000818000a", } var BurnMintTokenPoolAndProxyABI = BurnMintTokenPoolAndProxyMetaData.ABI @@ -332,6 +332,28 @@ func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetOnR return _BurnMintTokenPoolAndProxy.Contract.GetOnRamp(&_BurnMintTokenPoolAndProxy.CallOpts, arg0) } +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetPreviousPool(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getPreviousPool") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxySession) GetPreviousPool() (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetPreviousPool(&_BurnMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCallerSession) GetPreviousPool() (common.Address, error) { + return _BurnMintTokenPoolAndProxy.Contract.GetPreviousPool(&_BurnMintTokenPoolAndProxy.CallOpts) +} + func (_BurnMintTokenPoolAndProxy *BurnMintTokenPoolAndProxyCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { var out []interface{} err := _BurnMintTokenPoolAndProxy.contract.Call(opts, &out, "getRateLimitAdmin") @@ -2860,6 +2882,8 @@ type BurnMintTokenPoolAndProxyInterface interface { GetOnRamp(opts *bind.CallOpts, arg0 uint64) (common.Address, error) + GetPreviousPool(opts *bind.CallOpts) (common.Address, error) + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) diff --git a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool_and_proxy/burn_with_from_mint_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool_and_proxy/burn_with_from_mint_token_pool_and_proxy.go index 19b596a01d..60de3dcdac 100644 --- a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool_and_proxy/burn_with_from_mint_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool_and_proxy/burn_with_from_mint_token_pool_and_proxy.go @@ -82,8 +82,8 @@ type TokenPoolChainUpdate struct { } var BurnWithFromMintTokenPoolAndProxyMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b5060405162004db138038062004db18339810160408190526200003491620008cc565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200019b565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000246565b50620001919650506001600160a01b038a169450309350600019925050620003a39050565b5050505062000b08565b336001600160a01b03821603620001f55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000267576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002f25760008382815181106200028b576200028b620009dc565b60209081029190910101519050620002a560028262000489565b15620002e8576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200026a565b5060005b81518110156200039e576000828281518110620003175762000317620009dc565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000343575062000395565b62000350600282620004a9565b1562000393576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002f6565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200041b9190620009f2565b62000427919062000a22565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200048391869190620004c016565b50505050565b6000620004a0836001600160a01b03841662000591565b90505b92915050565b6000620004a0836001600160a01b03841662000695565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200050f906001600160a01b038516908490620006e7565b8051909150156200039e578080602001905181019062000530919062000a38565b6200039e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016200008a565b600081815260018301602052604081205480156200068a576000620005b860018362000a63565b8554909150600090620005ce9060019062000a63565b90508082146200063a576000866000018281548110620005f257620005f2620009dc565b9060005260206000200154905080876000018481548110620006185762000618620009dc565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200064e576200064e62000a79565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004a3565b6000915050620004a3565b6000818152600183016020526040812054620006de57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004a3565b506000620004a3565b6060620006f8848460008562000700565b949350505050565b606082471015620007635760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016200008a565b600080866001600160a01b0316858760405162000781919062000ab5565b60006040518083038185875af1925050503d8060008114620007c0576040519150601f19603f3d011682016040523d82523d6000602084013e620007c5565b606091505b509092509050620007d987838387620007e4565b979650505050505050565b606083156200085857825160000362000850576001600160a01b0385163b620008505760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016200008a565b5081620006f8565b620006f883838151156200086f5781518083602001fd5b8060405162461bcd60e51b81526004016200008a919062000ad3565b6001600160a01b0381168114620008a157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008c7816200088b565b919050565b60008060008060808587031215620008e357600080fd5b8451620008f0816200088b565b602086810151919550906001600160401b03808211156200091057600080fd5b818801915088601f8301126200092557600080fd5b8151818111156200093a576200093a620008a4565b8060051b604051601f19603f83011681018181108582111715620009625762000962620008a4565b60405291825284820192508381018501918b8311156200098157600080fd5b938501935b82851015620009aa576200099a85620008ba565b8452938501939285019262000986565b809850505050505050620009c160408601620008ba565b9150620009d160608601620008ba565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a0557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620004a357620004a362000a0c565b60006020828403121562000a4b57600080fd5b8151801515811462000a5c57600080fd5b9392505050565b81810381811115620004a357620004a362000a0c565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aac57818101518382015260200162000a92565b50506000910152565b6000825162000ac981846020870162000a8f565b9190910192915050565b602081526000825180602084015262000af481604085016020870162000a8f565b601f01601f19169190910160400192915050565b60805160a05160c05161422562000b8c6000396000818161050301528181611aad01526124ff0152600081816104dd015281816118400152611d600152600081816102260152818161027b0152818161073f01528181610dcb0152818161176001528181611c8001528181611e660152818161249501526126ea01526142256000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639766b93211610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104c8578063dc0bd971146104db578063e0351e1314610501578063f2fde38b1461052757600080fd5b8063c0d786551461047a578063c4bffe2b1461048d578063c75eea9c146104a2578063cf7401f3146104b557600080fd5b8063a8d87a3b116100de578063a8d87a3b146103c7578063af58d59f146103da578063b0f479a114610449578063b79465801461046757600080fd5b80639766b9321461037f5780639a4575b914610392578063a7cd63b7146103b257600080fd5b80636d3d1a58116101715780637d54534e1161014b5780637d54534e1461032857806383826b2b1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b80636d3d1a58146102ef57806378a010b21461030d57806379ba50971461032057600080fd5b806321df0da7116101ad57806321df0da714610224578063240028e81461026b57806339077537146102b857806354c8a4f3146102da57600080fd5b806301ffc9a7146101d45780630a2fd493146101fc578063181f5a771461021c575b600080fd5b6101e76101e2366004613197565b61053a565b60405190151581526020015b60405180910390f35b61020f61020a3660046131f6565b61061f565b6040516101f3919061327f565b61020f6106cf565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e76102793660046132bf565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102cb6102c63660046132dc565b6106eb565b604051905181526020016101f3565b6102ed6102e8366004613364565b6108a3565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61031b3660046133d0565b61091e565b6102ed610a92565b6102ed6103363660046132bf565b610b8f565b6101e7610349366004613453565b610bde565b6101e761035c3660046131f6565b610cab565b60005473ffffffffffffffffffffffffffffffffffffffff16610246565b6102ed61038d3660046132bf565b610cc2565b6103a56103a036600461348a565b610d51565b6040516101f391906134c5565b6103ba610ec7565b6040516101f39190613525565b6102466103d53660046131f6565b503090565b6103ed6103e83660046131f6565b610ed8565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610246565b61020f6104753660046131f6565b610fad565b6102ed6104883660046132bf565b610fd8565b6104956110ac565b6040516101f3919061357f565b6103ed6104b03660046131f6565b611164565b6102ed6104c3366004613736565b611236565b6102ed6104d636600461377b565b6112bf565b7f0000000000000000000000000000000000000000000000000000000000000000610246565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b6102ed6105353660046132bf565b611745565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105cd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061061957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061064a906137bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610676906137bd565b80156106c35780601f10610698576101008083540402835291602001916106c3565b820191906000526020600020905b8154815290600101906020018083116106a657829003601f168201915b50505050509050919050565b6040518060600160405280602381526020016141f66023913981565b60408051602081019091526000815261070b610706836138ac565b611759565b60095473ffffffffffffffffffffffffffffffffffffffff166108015773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961077460608501604086016132bf565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b1580156107e457600080fd5b505af11580156107f8573d6000803e3d6000fd5b50505050610812565b61081261080d836138ac565b61198a565b61082260608301604084016132bf565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161088491815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108ab611a28565b61091884848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611aab92505050565b50505050565b610926611a28565b61092f83610cab565b610976576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461099d906137bd565b80601f01602080910402602001604051908101604052809291908181526020018280546109c9906137bd565b8015610a165780601f106109eb57610100808354040283529160200191610a16565b820191906000526020600020905b8154815290600101906020018083116109f957829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a458385836139f1565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a8493929190613b0b565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161096d565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b97611a28565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610ca45750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca49190613b6f565b9392505050565b6000610619600567ffffffffffffffff8416611c61565b610cca611a28565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d76610d7183613b8c565b611c79565b60095473ffffffffffffffffffffffffffffffffffffffff16610e41576040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015610e2457600080fd5b505af1158015610e38573d6000803e3d6000fd5b50505050610e52565b610e52610e4d83613b8c565b611e43565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610eac84602001602081019061047591906131f6565b81526040805160208181019092526000815291015292915050565b6060610ed36002611f5d565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261061990611f6a565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061064a906137bd565b610fe0611a28565b73ffffffffffffffffffffffffffffffffffffffff811661102d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d45565b606060006110ba6005611f5d565b90506000815167ffffffffffffffff8111156110d8576110d86135c1565b604051908082528060200260200182016040528015611101578160200160208202803683370190505b50905060005b825181101561115d5782818151811061112257611122613c2e565b602002602001015182828151811061113c5761113c613c2e565b67ffffffffffffffff90921660209283029190910190910152600101611107565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261061990611f6a565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611276575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112af576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161096d565b6112ba83838361201c565b505050565b6112c7611a28565b60005b818110156112ba5760008383838181106112e6576112e6613c2e565b90506020028101906112f89190613c5d565b61130190613c9b565b90506113168160800151826020015115612106565b6113298160a00151826020015115612106565b80602001511561162557805161134b9060059067ffffffffffffffff1661223f565b6113905780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161096d565b60408101515115806113a55750606081015151155b156113dc576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115bd9082613d4f565b50606082015160058201906115d29082613d4f565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116189493929190613e69565b60405180910390a161173c565b805161163d9060059067ffffffffffffffff1661224b565b6116825780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161096d565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116eb6004830182613149565b6116f9600583016000613149565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112ca565b61174d611a28565b61175681612257565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146117ee5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161096d565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561189c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118c09190613b6f565b156118f7576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611904816020015161234c565b6000611913826020015161061f565b9050805160001480611937575080805190602001208260a001518051906020012014155b15611974578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161096d919061327f565b61198682602001518360600151612472565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad6946119f39490939291600401613f02565b600060405180830381600087803b158015611a0d57600080fd5b505af1158015611a21573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611aa9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161096d565b565b7f0000000000000000000000000000000000000000000000000000000000000000611b02576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611b98576000838281518110611b2257611b22613c2e565b60200260200101519050611b408160026124b990919063ffffffff16565b15611b8f5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611b05565b5060005b81518110156112ba576000828281518110611bb957611bb9613c2e565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bfd5750611c59565b611c086002826124db565b15611c575760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611b9c565b60008181526001830160205260408120541515610ca4565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611d0e5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161096d565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611dbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de09190613b6f565b15611e17576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e2481604001516124fd565b611e31816020015161257c565b611756816020015182606001516126ca565b6009546060820151611e909173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081169291169061270e565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611ef894939291600401613f63565b6000604051808303816000875af1158015611f17573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119869190810190613fc3565b60606000610ca48361279b565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611ff882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611fdc9190614060565b85608001516fffffffffffffffffffffffffffffffff166127f6565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61202583610cab565b612067576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161096d565b612072826000612106565b67ffffffffffffffff831660009081526007602052604090206120959083612820565b6120a0816000612106565b67ffffffffffffffff831660009081526007602052604090206120c69060020182612820565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516120f993929190614073565b60405180910390a1505050565b8151156121cd5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061215c575060408201516fffffffffffffffffffffffffffffffff16155b1561219557816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161096d91906140f6565b8015611986576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580612206575060208201516fffffffffffffffffffffffffffffffff1615155b1561198657816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161096d91906140f6565b6000610ca483836129c2565b6000610ca48383612a11565b3373ffffffffffffffffffffffffffffffffffffffff8216036122d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161096d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61235581610cab565b612397576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161096d565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243a9190613b6f565b611756576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161096d565b67ffffffffffffffff8216600090815260076020526040902061198690600201827f0000000000000000000000000000000000000000000000000000000000000000612b04565b6000610ca48373ffffffffffffffffffffffffffffffffffffffff8416612a11565b6000610ca48373ffffffffffffffffffffffffffffffffffffffff84166129c2565b7f0000000000000000000000000000000000000000000000000000000000000000156117565761252e600282612e87565b611756576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161096d565b61258581610cab565b6125c7576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161096d565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612640573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126649190614132565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611756576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161096d565b67ffffffffffffffff8216600090815260076020526040902061198690827f0000000000000000000000000000000000000000000000000000000000000000612b04565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526112ba908490612eb6565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106c357602002820191906000526020600020905b8154815260200190600101908083116127d75750505050509050919050565b600061281585612806848661414f565b6128109087614166565b612fc2565b90505b949350505050565b815460009061284990700100000000000000000000000000000000900463ffffffff1642614060565b905080156128eb5760018301548354612891916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166127f6565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612911916fffffffffffffffffffffffffffffffff9081169116612fc2565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906120f99084906140f6565b6000818152600183016020526040812054612a0957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610619565b506000610619565b60008181526001830160205260408120548015612afa576000612a35600183614060565b8554909150600090612a4990600190614060565b9050808214612aae576000866000018281548110612a6957612a69613c2e565b9060005260206000200154905080876000018481548110612a8c57612a8c613c2e565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612abf57612abf614179565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610619565b6000915050610619565b825474010000000000000000000000000000000000000000900460ff161580612b2b575081155b15612b3557505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612b7b90700100000000000000000000000000000000900463ffffffff1642614060565b90508015612c3b5781831115612bbd576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612bf79083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166127f6565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612cf25773ffffffffffffffffffffffffffffffffffffffff8416612c9a576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161096d565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161096d565b84831015612e055760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612d369082614060565b612d40878a614060565b612d4a9190614166565b612d5491906141a8565b905073ffffffffffffffffffffffffffffffffffffffff8616612dad576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161096d565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161096d565b612e0f8584614060565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610ca4565b6000612f18826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612fd89092919063ffffffff16565b8051909150156112ba5780806020019051810190612f369190613b6f565b6112ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161096d565b6000818310612fd15781610ca4565b5090919050565b60606128188484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161300c91906141e3565b60006040518083038185875af1925050503d8060008114613049576040519150601f19603f3d011682016040523d82523d6000602084013e61304e565b606091505b509150915061305f8783838761306a565b979650505050505050565b606083156131005782516000036130f95773ffffffffffffffffffffffffffffffffffffffff85163b6130f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161096d565b5081612818565b61281883838151156131155781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096d919061327f565b508054613155906137bd565b6000825580601f10613165575050565b601f01602090049060005260206000209081019061175691905b80821115613193576000815560010161317f565b5090565b6000602082840312156131a957600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ca457600080fd5b803567ffffffffffffffff811681146131f157600080fd5b919050565b60006020828403121561320857600080fd5b610ca4826131d9565b60005b8381101561322c578181015183820152602001613214565b50506000910152565b6000815180845261324d816020860160208601613211565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ca46020830184613235565b73ffffffffffffffffffffffffffffffffffffffff8116811461175657600080fd5b80356131f181613292565b6000602082840312156132d157600080fd5b8135610ca481613292565b6000602082840312156132ee57600080fd5b813567ffffffffffffffff81111561330557600080fd5b82016101008185031215610ca457600080fd5b60008083601f84011261332a57600080fd5b50813567ffffffffffffffff81111561334257600080fd5b6020830191508360208260051b850101111561335d57600080fd5b9250929050565b6000806000806040858703121561337a57600080fd5b843567ffffffffffffffff8082111561339257600080fd5b61339e88838901613318565b909650945060208701359150808211156133b757600080fd5b506133c487828801613318565b95989497509550505050565b6000806000604084860312156133e557600080fd5b6133ee846131d9565b9250602084013567ffffffffffffffff8082111561340b57600080fd5b818601915086601f83011261341f57600080fd5b81358181111561342e57600080fd5b87602082850101111561344057600080fd5b6020830194508093505050509250925092565b6000806040838503121561346657600080fd5b61346f836131d9565b9150602083013561347f81613292565b809150509250929050565b60006020828403121561349c57600080fd5b813567ffffffffffffffff8111156134b357600080fd5b820160a08185031215610ca457600080fd5b6020815260008251604060208401526134e16060840182613235565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261351c8282613235565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561357357835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613541565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561357357835167ffffffffffffffff168352928401929184019160010161359b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613614576136146135c1565b60405290565b60405160c0810167ffffffffffffffff81118282101715613614576136146135c1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613684576136846135c1565b604052919050565b801515811461175657600080fd5b80356131f18161368c565b80356fffffffffffffffffffffffffffffffff811681146131f157600080fd5b6000606082840312156136d757600080fd5b6040516060810181811067ffffffffffffffff821117156136fa576136fa6135c1565b604052905080823561370b8161368c565b8152613719602084016136a5565b602082015261372a604084016136a5565b60408201525092915050565b600080600060e0848603121561374b57600080fd5b613754846131d9565b925061376385602086016136c5565b915061377285608086016136c5565b90509250925092565b6000806020838503121561378e57600080fd5b823567ffffffffffffffff8111156137a557600080fd5b6137b185828601613318565b90969095509350505050565b600181811c908216806137d157607f821691505b60208210810361380a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff82111561382a5761382a6135c1565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261386757600080fd5b813561387a61387582613810565b61363d565b81815284602083860101111561388f57600080fd5b816020850160208301376000918101602001919091529392505050565b600061010082360312156138bf57600080fd5b6138c76135f0565b823567ffffffffffffffff808211156138df57600080fd5b6138eb36838701613856565b83526138f9602086016131d9565b602084015261390a604086016132b4565b604084015260608501356060840152613925608086016132b4565b608084015260a085013591508082111561393e57600080fd5b61394a36838701613856565b60a084015260c085013591508082111561396357600080fd5b61396f36838701613856565b60c084015260e085013591508082111561398857600080fd5b5061399536828601613856565b60e08301525092915050565b601f8211156112ba576000816000526020600020601f850160051c810160208610156139ca5750805b601f850160051c820191505b818110156139e9578281556001016139d6565b505050505050565b67ffffffffffffffff831115613a0957613a096135c1565b613a1d83613a1783546137bd565b836139a1565b6000601f841160018114613a6f5760008515613a395750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a21565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613abe5786850135825560209485019460019092019101613a9e565b5086821015613af9577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613b1e6040830186613235565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613b8157600080fd5b8151610ca48161368c565b600060a08236031215613b9e57600080fd5b60405160a0810167ffffffffffffffff8282108183111715613bc257613bc26135c1565b816040528435915080821115613bd757600080fd5b50613be436828601613856565b825250613bf3602084016131d9565b60208201526040830135613c0681613292565b6040820152606083810135908201526080830135613c2381613292565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613c9157600080fd5b9190910192915050565b60006101408236031215613cae57600080fd5b613cb661361a565b613cbf836131d9565b8152613ccd6020840161369a565b6020820152604083013567ffffffffffffffff80821115613ced57600080fd5b613cf936838701613856565b60408401526060850135915080821115613d1257600080fd5b50613d1f36828601613856565b606083015250613d3236608085016136c5565b6080820152613d443660e085016136c5565b60a082015292915050565b815167ffffffffffffffff811115613d6957613d696135c1565b613d7d81613d7784546137bd565b846139a1565b602080601f831160018114613dd05760008415613d9a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139e9565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e1d57888601518255948401946001909101908401613dfe565b5085821015613e5957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613e8d81840187613235565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613ecb9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e083015261351c565b60a081526000613f1560a0830187613235565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613f9260a0830186613235565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613fd557600080fd5b815167ffffffffffffffff811115613fec57600080fd5b8201601f81018413613ffd57600080fd5b805161400b61387582613810565b81815285602083850101111561402057600080fd5b61351c826020830160208601613211565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561061957610619614031565b67ffffffffffffffff8416815260e081016140bf60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612818565b6060810161061982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561414457600080fd5b8151610ca481613292565b808202811582820484141761061957610619614031565b8082018082111561061957610619614031565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826141de577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613c9181846020870161321156fe4275726e46726f6d4d696e74546f6b656e506f6f6c416e6450726f787920312e352e30a164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPreviousPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b5060405162004dda38038062004dda8339810160408190526200003491620008cc565b83838383838383833380600081620000935760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c657620000c6816200019b565b5050506001600160a01b0384161580620000e757506001600160a01b038116155b80620000fa57506001600160a01b038216155b1562000119576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016c576040805160008152602081019091526200016c908462000246565b50620001919650506001600160a01b038a169450309350600019925050620003a39050565b5050505062000b08565b336001600160a01b03821603620001f55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000267576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002f25760008382815181106200028b576200028b620009dc565b60209081029190910101519050620002a560028262000489565b15620002e8576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016200026a565b5060005b81518110156200039e576000828281518110620003175762000317620009dc565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000343575062000395565b62000350600282620004a9565b1562000393576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002f6565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620003f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200041b9190620009f2565b62000427919062000a22565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200048391869190620004c016565b50505050565b6000620004a0836001600160a01b03841662000591565b90505b92915050565b6000620004a0836001600160a01b03841662000695565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200050f906001600160a01b038516908490620006e7565b8051909150156200039e578080602001905181019062000530919062000a38565b6200039e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016200008a565b600081815260018301602052604081205480156200068a576000620005b860018362000a63565b8554909150600090620005ce9060019062000a63565b90508082146200063a576000866000018281548110620005f257620005f2620009dc565b9060005260206000200154905080876000018481548110620006185762000618620009dc565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200064e576200064e62000a79565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004a3565b6000915050620004a3565b6000818152600183016020526040812054620006de57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004a3565b506000620004a3565b6060620006f8848460008562000700565b949350505050565b606082471015620007635760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016200008a565b600080866001600160a01b0316858760405162000781919062000ab5565b60006040518083038185875af1925050503d8060008114620007c0576040519150601f19603f3d011682016040523d82523d6000602084013e620007c5565b606091505b509092509050620007d987838387620007e4565b979650505050505050565b606083156200085857825160000362000850576001600160a01b0385163b620008505760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016200008a565b5081620006f8565b620006f883838151156200086f5781518083602001fd5b8060405162461bcd60e51b81526004016200008a919062000ad3565b6001600160a01b0381168114620008a157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008c7816200088b565b919050565b60008060008060808587031215620008e357600080fd5b8451620008f0816200088b565b602086810151919550906001600160401b03808211156200091057600080fd5b818801915088601f8301126200092557600080fd5b8151818111156200093a576200093a620008a4565b8060051b604051601f19603f83011681018181108582111715620009625762000962620008a4565b60405291825284820192508381018501918b8311156200098157600080fd5b938501935b82851015620009aa576200099a85620008ba565b8452938501939285019262000986565b809850505050505050620009c160408601620008ba565b9150620009d160608601620008ba565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a0557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620004a357620004a362000a0c565b60006020828403121562000a4b57600080fd5b8151801515811462000a5c57600080fd5b9392505050565b81810381811115620004a357620004a362000a0c565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000aac57818101518382015260200162000a92565b50506000910152565b6000825162000ac981846020870162000a8f565b9190910192915050565b602081526000825180602084015262000af481604085016020870162000a8f565b601f01601f19169190910160400192915050565b60805160a05160c05161424e62000b8c6000396000818161052c01528181611ad60152612528015260008181610506015281816118690152611d89015260008181610231015281816102860152818161076801528181610df40152818161178901528181611ca901528181611e8f015281816124be0152612713015261424e6000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80639a4575b911610104578063c0d78655116100a2578063db6327dc11610071578063db6327dc146104f1578063dc0bd97114610504578063e0351e131461052a578063f2fde38b1461055057600080fd5b8063c0d78655146104a3578063c4bffe2b146104b6578063c75eea9c146104cb578063cf7401f3146104de57600080fd5b8063a8d87a3b116100de578063a8d87a3b146103f0578063af58d59f14610403578063b0f479a114610472578063b79465801461049057600080fd5b80639a4575b91461039d578063a2b261d8146103bd578063a7cd63b7146103db57600080fd5b80636d3d1a581161017c57806383826b2b1161014b57806383826b2b146103465780638926f54f146103595780638da5cb5b1461036c5780639766b9321461038a57600080fd5b80636d3d1a58146102fa57806378a010b21461031857806379ba50971461032b5780637d54534e1461033357600080fd5b806321df0da7116101b857806321df0da71461022f578063240028e81461027657806339077537146102c357806354c8a4f3146102e557600080fd5b806301ffc9a7146101df5780630a2fd49314610207578063181f5a7714610227575b600080fd5b6101f26101ed3660046131c0565b610563565b60405190151581526020015b60405180910390f35b61021a61021536600461321f565b610648565b6040516101fe91906132a8565b61021a6106f8565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fe565b6101f26102843660046132e8565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102d66102d1366004613305565b610714565b604051905181526020016101fe565b6102f86102f336600461338d565b6108cc565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610251565b6102f86103263660046133f9565b610947565b6102f8610abb565b6102f86103413660046132e8565b610bb8565b6101f261035436600461347c565b610c07565b6101f261036736600461321f565b610cd4565b60005473ffffffffffffffffffffffffffffffffffffffff16610251565b6102f86103983660046132e8565b610ceb565b6103b06103ab3660046134b3565b610d7a565b6040516101fe91906134ee565b60095473ffffffffffffffffffffffffffffffffffffffff16610251565b6103e3610ef0565b6040516101fe919061354e565b6102516103fe36600461321f565b503090565b61041661041136600461321f565b610f01565b6040516101fe919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610251565b61021a61049e36600461321f565b610fd6565b6102f86104b13660046132e8565b611001565b6104be6110d5565b6040516101fe91906135a8565b6104166104d936600461321f565b61118d565b6102f86104ec36600461375f565b61125f565b6102f86104ff3660046137a4565b6112e8565b7f0000000000000000000000000000000000000000000000000000000000000000610251565b7f00000000000000000000000000000000000000000000000000000000000000006101f2565b6102f861055e3660046132e8565b61176e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105f657507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061064257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff81166000908152600760205260409020600401805460609190610673906137e6565b80601f016020809104026020016040519081016040528092919081815260200182805461069f906137e6565b80156106ec5780601f106106c1576101008083540402835291602001916106ec565b820191906000526020600020905b8154815290600101906020018083116106cf57829003601f168201915b50505050509050919050565b60405180606001604052806023815260200161421f6023913981565b60408051602081019091526000815261073461072f836138d5565b611782565b60095473ffffffffffffffffffffffffffffffffffffffff1661082a5773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961079d60608501604086016132e8565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561080d57600080fd5b505af1158015610821573d6000803e3d6000fd5b5050505061083b565b61083b610836836138d5565b6119b3565b61084b60608301604084016132e8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f084606001356040516108ad91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108d4611a51565b61094184848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ad492505050565b50505050565b61094f611a51565b61095883610cd4565b61099f576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109c6906137e6565b80601f01602080910402602001604051908101604052809291908181526020018280546109f2906137e6565b8015610a3f5780601f10610a1457610100808354040283529160200191610a3f565b820191906000526020600020905b815481529060010190602001808311610a2257829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610a6e838583613a1a565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610aad93929190613b34565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610996565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610bc0611a51565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610ccd5750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610ca9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccd9190613b98565b9392505050565b6000610642600567ffffffffffffffff8416611c8a565b610cf3611a51565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610d9f610d9a83613bb5565b611ca2565b60095473ffffffffffffffffffffffffffffffffffffffff16610e6a576040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152606083013560248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015610e4d57600080fd5b505af1158015610e61573d6000803e3d6000fd5b50505050610e7b565b610e7b610e7683613bb5565b611e6c565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610ed584602001602081019061049e919061321f565b81526040805160208181019092526000815291015292915050565b6060610efc6002611f86565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261064290611f93565b67ffffffffffffffff81166000908152600760205260409020600501805460609190610673906137e6565b611009611a51565b73ffffffffffffffffffffffffffffffffffffffff8116611056576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610d6e565b606060006110e36005611f86565b90506000815167ffffffffffffffff811115611101576111016135ea565b60405190808252806020026020018201604052801561112a578160200160208202803683370190505b50905060005b82518110156111865782818151811061114b5761114b613c57565b602002602001015182828151811061116557611165613c57565b67ffffffffffffffff90921660209283029190910190910152600101611130565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261064290611f93565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061129f575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156112d8576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610996565b6112e3838383612045565b505050565b6112f0611a51565b60005b818110156112e357600083838381811061130f5761130f613c57565b90506020028101906113219190613c86565b61132a90613cc4565b905061133f816080015182602001511561212f565b6113528160a0015182602001511561212f565b80602001511561164e5780516113749060059067ffffffffffffffff16612268565b6113b95780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610996565b60408101515115806113ce5750606081015151155b15611405576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115e69082613d78565b50606082015160058201906115fb9082613d78565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116419493929190613e92565b60405180910390a1611765565b80516116669060059067ffffffffffffffff16612274565b6116ab5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610996565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906117146004830182613172565b611722600583016000613172565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112f3565b611776611a51565b61177f81612280565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146118175760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610996565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa1580156118c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e99190613b98565b15611920576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61192d8160200151612375565b600061193c8260200151610648565b9050805160001480611960575080805190602001208260a001518051906020012014155b1561199d578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161099691906132a8565b6119af8260200151836060015161249b565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611a1c9490939291600401613f2b565b600060405180830381600087803b158015611a3657600080fd5b505af1158015611a4a573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ad2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610996565b565b7f0000000000000000000000000000000000000000000000000000000000000000611b2b576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611bc1576000838281518110611b4b57611b4b613c57565b60200260200101519050611b698160026124e290919063ffffffff16565b15611bb85760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611b2e565b5060005b81518110156112e3576000828281518110611be257611be2613c57565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c265750611c82565b611c31600282612504565b15611c805760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611bc5565b60008181526001830160205260408120541515610ccd565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611d375760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610996565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611de5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e099190613b98565b15611e40576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e4d8160400151612526565b611e5a81602001516125a5565b61177f816020015182606001516126f3565b6009546060820151611eb99173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690612737565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694639687544594611f2194939291600401613f8c565b6000604051808303816000875af1158015611f40573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119af9190810190613fec565b60606000610ccd836127c4565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261202182606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426120059190614089565b85608001516fffffffffffffffffffffffffffffffff1661281f565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61204e83610cd4565b612090576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610996565b61209b82600061212f565b67ffffffffffffffff831660009081526007602052604090206120be9083612849565b6120c981600061212f565b67ffffffffffffffff831660009081526007602052604090206120ef9060020182612849565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516121229392919061409c565b60405180910390a1505050565b8151156121f65781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612185575060408201516fffffffffffffffffffffffffffffffff16155b156121be57816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610996919061411f565b80156119af576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff1615158061222f575060208201516fffffffffffffffffffffffffffffffff1615155b156119af57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610996919061411f565b6000610ccd83836129eb565b6000610ccd8383612a3a565b3373ffffffffffffffffffffffffffffffffffffffff8216036122ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610996565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61237e81610cd4565b6123c0576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610996565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561243f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124639190613b98565b61177f576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610996565b67ffffffffffffffff821660009081526007602052604090206119af90600201827f0000000000000000000000000000000000000000000000000000000000000000612b2d565b6000610ccd8373ffffffffffffffffffffffffffffffffffffffff8416612a3a565b6000610ccd8373ffffffffffffffffffffffffffffffffffffffff84166129eb565b7f00000000000000000000000000000000000000000000000000000000000000001561177f57612557600282612eb0565b61177f576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610996565b6125ae81610cd4565b6125f0576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610996565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612669573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268d919061415b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461177f576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610996565b67ffffffffffffffff821660009081526007602052604090206119af90827f0000000000000000000000000000000000000000000000000000000000000000612b2d565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526112e3908490612edf565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106ec57602002820191906000526020600020905b8154815260200190600101908083116128005750505050509050919050565b600061283e8561282f8486614178565b612839908761418f565b612feb565b90505b949350505050565b815460009061287290700100000000000000000000000000000000900463ffffffff1642614089565b9050801561291457600183015483546128ba916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661281f565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461293a916fffffffffffffffffffffffffffffffff9081169116612feb565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061212290849061411f565b6000818152600183016020526040812054612a3257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610642565b506000610642565b60008181526001830160205260408120548015612b23576000612a5e600183614089565b8554909150600090612a7290600190614089565b9050808214612ad7576000866000018281548110612a9257612a92613c57565b9060005260206000200154905080876000018481548110612ab557612ab5613c57565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ae857612ae86141a2565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610642565b6000915050610642565b825474010000000000000000000000000000000000000000900460ff161580612b54575081155b15612b5e57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612ba490700100000000000000000000000000000000900463ffffffff1642614089565b90508015612c645781831115612be6576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612c209083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661281f565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612d1b5773ffffffffffffffffffffffffffffffffffffffff8416612cc3576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610996565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610996565b84831015612e2e5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612d5f9082614089565b612d69878a614089565b612d73919061418f565b612d7d91906141d1565b905073ffffffffffffffffffffffffffffffffffffffff8616612dd6576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610996565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610996565b612e388584614089565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610ccd565b6000612f41826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130019092919063ffffffff16565b8051909150156112e35780806020019051810190612f5f9190613b98565b6112e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610996565b6000818310612ffa5781610ccd565b5090919050565b60606128418484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051613035919061420c565b60006040518083038185875af1925050503d8060008114613072576040519150601f19603f3d011682016040523d82523d6000602084013e613077565b606091505b509150915061308887838387613093565b979650505050505050565b606083156131295782516000036131225773ffffffffffffffffffffffffffffffffffffffff85163b613122576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610996565b5081612841565b612841838381511561313e5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099691906132a8565b50805461317e906137e6565b6000825580601f1061318e575050565b601f01602090049060005260206000209081019061177f91905b808211156131bc57600081556001016131a8565b5090565b6000602082840312156131d257600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ccd57600080fd5b803567ffffffffffffffff8116811461321a57600080fd5b919050565b60006020828403121561323157600080fd5b610ccd82613202565b60005b8381101561325557818101518382015260200161323d565b50506000910152565b6000815180845261327681602086016020860161323a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ccd602083018461325e565b73ffffffffffffffffffffffffffffffffffffffff8116811461177f57600080fd5b803561321a816132bb565b6000602082840312156132fa57600080fd5b8135610ccd816132bb565b60006020828403121561331757600080fd5b813567ffffffffffffffff81111561332e57600080fd5b82016101008185031215610ccd57600080fd5b60008083601f84011261335357600080fd5b50813567ffffffffffffffff81111561336b57600080fd5b6020830191508360208260051b850101111561338657600080fd5b9250929050565b600080600080604085870312156133a357600080fd5b843567ffffffffffffffff808211156133bb57600080fd5b6133c788838901613341565b909650945060208701359150808211156133e057600080fd5b506133ed87828801613341565b95989497509550505050565b60008060006040848603121561340e57600080fd5b61341784613202565b9250602084013567ffffffffffffffff8082111561343457600080fd5b818601915086601f83011261344857600080fd5b81358181111561345757600080fd5b87602082850101111561346957600080fd5b6020830194508093505050509250925092565b6000806040838503121561348f57600080fd5b61349883613202565b915060208301356134a8816132bb565b809150509250929050565b6000602082840312156134c557600080fd5b813567ffffffffffffffff8111156134dc57600080fd5b820160a08185031215610ccd57600080fd5b60208152600082516040602084015261350a606084018261325e565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613545828261325e565b95945050505050565b6020808252825182820181905260009190848201906040850190845b8181101561359c57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161356a565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561359c57835167ffffffffffffffff16835292840192918401916001016135c4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561363d5761363d6135ea565b60405290565b60405160c0810167ffffffffffffffff8111828210171561363d5761363d6135ea565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156136ad576136ad6135ea565b604052919050565b801515811461177f57600080fd5b803561321a816136b5565b80356fffffffffffffffffffffffffffffffff8116811461321a57600080fd5b60006060828403121561370057600080fd5b6040516060810181811067ffffffffffffffff82111715613723576137236135ea565b6040529050808235613734816136b5565b8152613742602084016136ce565b6020820152613753604084016136ce565b60408201525092915050565b600080600060e0848603121561377457600080fd5b61377d84613202565b925061378c85602086016136ee565b915061379b85608086016136ee565b90509250925092565b600080602083850312156137b757600080fd5b823567ffffffffffffffff8111156137ce57600080fd5b6137da85828601613341565b90969095509350505050565b600181811c908216806137fa57607f821691505b602082108103613833577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600067ffffffffffffffff821115613853576138536135ea565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261389057600080fd5b81356138a361389e82613839565b613666565b8181528460208386010111156138b857600080fd5b816020850160208301376000918101602001919091529392505050565b600061010082360312156138e857600080fd5b6138f0613619565b823567ffffffffffffffff8082111561390857600080fd5b6139143683870161387f565b835261392260208601613202565b6020840152613933604086016132dd565b60408401526060850135606084015261394e608086016132dd565b608084015260a085013591508082111561396757600080fd5b6139733683870161387f565b60a084015260c085013591508082111561398c57600080fd5b6139983683870161387f565b60c084015260e08501359150808211156139b157600080fd5b506139be3682860161387f565b60e08301525092915050565b601f8211156112e3576000816000526020600020601f850160051c810160208610156139f35750805b601f850160051c820191505b81811015613a12578281556001016139ff565b505050505050565b67ffffffffffffffff831115613a3257613a326135ea565b613a4683613a4083546137e6565b836139ca565b6000601f841160018114613a985760008515613a625750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611a4a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613ae75786850135825560209485019460019092019101613ac7565b5086821015613b22577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b604081526000613b47604083018661325e565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060208284031215613baa57600080fd5b8151610ccd816136b5565b600060a08236031215613bc757600080fd5b60405160a0810167ffffffffffffffff8282108183111715613beb57613beb6135ea565b816040528435915080821115613c0057600080fd5b50613c0d3682860161387f565b825250613c1c60208401613202565b60208201526040830135613c2f816132bb565b6040820152606083810135908201526080830135613c4c816132bb565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613cba57600080fd5b9190910192915050565b60006101408236031215613cd757600080fd5b613cdf613643565b613ce883613202565b8152613cf6602084016136c3565b6020820152604083013567ffffffffffffffff80821115613d1657600080fd5b613d223683870161387f565b60408401526060850135915080821115613d3b57600080fd5b50613d483682860161387f565b606083015250613d5b36608085016136ee565b6080820152613d6d3660e085016136ee565b60a082015292915050565b815167ffffffffffffffff811115613d9257613d926135ea565b613da681613da084546137e6565b846139ca565b602080601f831160018114613df95760008415613dc35750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613a12565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e4657888601518255948401946001909101908401613e27565b5085821015613e8257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613eb68184018761325e565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613ef49050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613545565b60a081526000613f3e60a083018761325e565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a060208201526000613fbb60a083018661325e565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b600060208284031215613ffe57600080fd5b815167ffffffffffffffff81111561401557600080fd5b8201601f8101841361402657600080fd5b805161403461389e82613839565b81815285602083850101111561404957600080fd5b61354582602083016020860161323a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106425761064261405a565b67ffffffffffffffff8416815260e081016140e860208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612841565b6060810161064282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561416d57600080fd5b8151610ccd816132bb565b80820281158282048414176106425761064261405a565b808201808211156106425761064261405a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614207577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613cba81846020870161323a56fe4275726e46726f6d4d696e74546f6b656e506f6f6c416e6450726f787920312e352e30a164736f6c6343000818000a", } var BurnWithFromMintTokenPoolAndProxyABI = BurnWithFromMintTokenPoolAndProxyMetaData.ABI @@ -332,6 +332,28 @@ func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCalle return _BurnWithFromMintTokenPoolAndProxy.Contract.GetOnRamp(&_BurnWithFromMintTokenPoolAndProxy.CallOpts, arg0) } +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetPreviousPool(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getPreviousPool") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxySession) GetPreviousPool() (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetPreviousPool(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + +func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCallerSession) GetPreviousPool() (common.Address, error) { + return _BurnWithFromMintTokenPoolAndProxy.Contract.GetPreviousPool(&_BurnWithFromMintTokenPoolAndProxy.CallOpts) +} + func (_BurnWithFromMintTokenPoolAndProxy *BurnWithFromMintTokenPoolAndProxyCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { var out []interface{} err := _BurnWithFromMintTokenPoolAndProxy.contract.Call(opts, &out, "getRateLimitAdmin") @@ -2860,6 +2882,8 @@ type BurnWithFromMintTokenPoolAndProxyInterface interface { GetOnRamp(opts *bind.CallOpts, arg0 uint64) (common.Address, error) + GetPreviousPool(opts *bind.CallOpts) (common.Address, error) + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go index 6a0a3ac4d8..94c80882d4 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool_and_proxy/lock_release_token_pool_and_proxy.go @@ -82,8 +82,8 @@ type TokenPoolChainUpdate struct { } var LockReleaseTokenPoolAndProxyMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162004f0a38038062004f0a83398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508082146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516147896200078160003960008181610545015261191b0152600081816105f201528181611f550152612b110152600081816105cc01528181611ce801526122080152600081816102ad01528181610302015281816107d0015281816108a20152818161097c015281816119dd01528181611c08015281816121280152818161230e01528181612aa70152612cfc01526147896000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e13146105f0578063eb521a4c14610616578063f2fde38b1461062957600080fd5b8063db6327dc146105b7578063dc0bd971146105ca57600080fd5b8063c0d7865514610569578063c4bffe2b1461057c578063c75eea9c14610591578063cf7401f3146105a457600080fd5b8063a8d87a3b11610114578063b0f479a1116100f9578063b0f479a114610512578063b794658014610530578063bb98546b1461054357600080fd5b8063a8d87a3b14610490578063af58d59f146104a357600080fd5b80638da5cb5b1461042a5780639766b932146104485780639a4575b91461045b578063a7cd63b71461047b57600080fd5b806354c8a4f3116101d857806378a010b2116101a75780637d54534e1161018c5780637d54534e146103f157806383826b2b146104045780638926f54f1461041757600080fd5b806378a010b2146103d657806379ba5097146103e957600080fd5b806354c8a4f31461037f57806366320087146103925780636cfd1553146103a55780636d3d1a58146103b857600080fd5b806321df0da71161021457806321df0da7146102ab578063240028e8146102f2578063390775371461033f578063432a6ba31461036157600080fd5b806301ffc9a7146102465780630a2fd4931461026e5780630a861f2a1461028e578063181f5a77146102a3575b600080fd5b6102596102543660046136a6565b61063c565b60405190151581526020015b60405180910390f35b61028161027c366004613705565b610698565b604051610265919061378e565b6102a161029c3660046137a1565b610748565b005b6102816108f9565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102596103003660046137e7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61035261034d366004613804565b610915565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a161038d36600461388c565b610a4e565b6102a16103a03660046138f8565b610ac9565b6102a16103b33660046137e7565b610b55565b60085473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16103e4366004613924565b610ba4565b6102a1610d13565b6102a16103ff3660046137e7565b610e10565b6102596104123660046139a7565b610e5f565b610259610425366004613705565b610f2c565b60005473ffffffffffffffffffffffffffffffffffffffff166102cd565b6102a16104563660046137e7565b610f43565b61046e6104693660046139de565b610fd2565b6040516102659190613a19565b61048361109b565b6040516102659190613a79565b6102cd61049e366004613705565b503090565b6104b66104b1366004613705565b6110ac565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102cd565b61028161053e366004613705565b611181565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16105773660046137e7565b6111ac565b610584611280565b6040516102659190613ad3565b6104b661059f366004613705565b611338565b6102a16105b2366004613c8a565b61140a565b6102a16105c5366004613ccf565b611493565b7f00000000000000000000000000000000000000000000000000000000000000006102cd565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102a16106243660046137a1565b611919565b6102a16106373660046137e7565b611a35565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d40566000000000000000000000000000000000000000000000000000000001480610692575061069282611a49565b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106c390613d11565b80601f01602080910402602001604051908101604052809291908181526020018280546106ef90613d11565b801561073c5780601f106107115761010080835404028352916020019161073c565b820191906000526020600020905b81548152906001019060200180831161071f57829003601f168201915b50505050509050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146107a0576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190613d64565b1015610888576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108c973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611b2d565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b60405180606001604052806022815260200161475b6022913981565b60408051602081019091526000815261093561093083613e19565b611c01565b60095473ffffffffffffffffffffffffffffffffffffffff166109ac576109a761096560608401604085016137e7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611b2d565b6109bd565b6109bd6109b883613e19565b611e32565b6109cd60608301604084016137e7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f528460600135604051610a2f91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a56611ed0565b610ac384848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f5392505050565b50505050565b610ad1611ed0565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610b3957600080fd5b505af1158015610b4d573d6000803e3d6000fd5b505050505050565b610b5d611ed0565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610bac611ed0565b610bb583610f2c565b610bf7576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b67ffffffffffffffff831660009081526007602052604081206004018054610c1e90613d11565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4a90613d11565b8015610c975780601f10610c6c57610100808354040283529160200191610c97565b820191906000526020600020905b815481529060010190602001808311610c7a57829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cc6838583613f56565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d0593929190614070565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610797565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e18611ed0565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610f255750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610f01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2591906140d4565b9392505050565b6000610692600567ffffffffffffffff8416612109565b610f4b611ed0565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b6040805180820190915260608082526020820152610ff7610ff2836140f1565b612121565b60095473ffffffffffffffffffffffffffffffffffffffff161561102657611026611021836140f1565b6122eb565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a2604051806040016040528061108084602001602081019061053e9190613705565b81526040805160208181019092526000815291015292915050565b60606110a76002612405565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261069290612412565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106c390613d11565b6111b4611ed0565b73ffffffffffffffffffffffffffffffffffffffff8116611201576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610fc6565b6060600061128e6005612405565b90506000815167ffffffffffffffff8111156112ac576112ac613b15565b6040519080825280602002602001820160405280156112d5578160200160208202803683370190505b50905060005b8251811015611331578281815181106112f6576112f6614193565b602002602001015182828151811061131057611310614193565b67ffffffffffffffff909216602092830291909101909101526001016112db565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261069290612412565b60085473ffffffffffffffffffffffffffffffffffffffff16331480159061144a575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611483576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b61148e8383836124c4565b505050565b61149b611ed0565b60005b8181101561148e5760008383838181106114ba576114ba614193565b90506020028101906114cc91906141c2565b6114d590614200565b90506114ea81608001518260200151156125ae565b6114fd8160a001518260200151156125ae565b8060200151156117f957805161151f9060059067ffffffffffffffff166126e7565b6115645780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b60408101515115806115795750606081015151155b156115b0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061179190826142b4565b50606082015160058201906117a690826142b4565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506117ec94939291906143ce565b60405180910390a1611910565b80516118119060059067ffffffffffffffff166126f3565b6118565780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610797565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118bf6004830182613658565b6118cd600583016000613658565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b5060010161149e565b7f0000000000000000000000000000000000000000000000000000000000000000611970576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff1633146119c3576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b611a0573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846126ff565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611a3d611ed0565b611a468161275d565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611adc57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261148e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612852565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611c965760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6891906140d4565b15611d9f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dac816020015161295e565b6000611dbb8260200151610698565b9050805160001480611ddf575080805190602001208260a001518051906020012014155b15611e1c578160a001516040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610797919061378e565b611e2e82602001518360600151612a84565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611e9b9490939291600401614467565b600060405180830381600087803b158015611eb557600080fd5b505af1158015611ec9573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611f51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610797565b565b7f0000000000000000000000000000000000000000000000000000000000000000611faa576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612040576000838281518110611fca57611fca614193565b60200260200101519050611fe8816002612acb90919063ffffffff16565b156120375760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611fad565b5060005b815181101561148e57600082828151811061206157612061614193565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120a55750612101565b6120b0600282612aed565b156120ff5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612044565b60008181526001830160205260408120541515610f25565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121b65760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610797565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015612264573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228891906140d4565b156122bf576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122cc8160400151612b0f565b6122d98160200151612b8e565b611a4681602001518260600151612cdc565b60095460608201516123389173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611b2d565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909516946396875445946123a0949392916004016144c8565b6000604051808303816000875af11580156123bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e2e9190810190614528565b60606000610f2583612d20565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526124a082606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261248491906145c5565b85608001516fffffffffffffffffffffffffffffffff16612d7b565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6124cd83610f2c565b61250f576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610797565b61251a8260006125ae565b67ffffffffffffffff8316600090815260076020526040902061253d9083612da5565b6125488160006125ae565b67ffffffffffffffff8316600090815260076020526040902061256e9060020182612da5565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516125a1939291906145d8565b60405180910390a1505050565b8151156126755781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612604575060408201516fffffffffffffffffffffffffffffffff16155b1561263d57816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610797919061465b565b8015611e2e576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806126ae575060208201516fffffffffffffffffffffffffffffffff1615155b15611e2e57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610797919061465b565b6000610f258383612f47565b6000610f258383612f96565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ac39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611b7f565b3373ffffffffffffffffffffffffffffffffffffffff8216036127dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610797565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006128b4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130899092919063ffffffff16565b80519091501561148e57808060200190518101906128d291906140d4565b61148e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610797565b61296781610f2c565b6129a9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612a28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4c91906140d4565b611a46576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e2e90600201827f0000000000000000000000000000000000000000000000000000000000000000613098565b6000610f258373ffffffffffffffffffffffffffffffffffffffff8416612f96565b6000610f258373ffffffffffffffffffffffffffffffffffffffff8416612f47565b7f000000000000000000000000000000000000000000000000000000000000000015611a4657612b4060028261341b565b611a46576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610797565b612b9781610f2c565b612bd9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610797565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c769190614697565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a46576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610797565b67ffffffffffffffff82166000908152600760205260409020611e2e90827f0000000000000000000000000000000000000000000000000000000000000000613098565b60608160000180548060200260200160405190810160405280929190818152602001828054801561073c57602002820191906000526020600020905b815481526020019060010190808311612d5c5750505050509050919050565b6000612d9a85612d8b84866146b4565b612d9590876146cb565b61344a565b90505b949350505050565b8154600090612dce90700100000000000000000000000000000000900463ffffffff16426145c5565b90508015612e705760018301548354612e16916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612d7b565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612e96916fffffffffffffffffffffffffffffffff908116911661344a565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906125a190849061465b565b6000818152600183016020526040812054612f8e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610692565b506000610692565b6000818152600183016020526040812054801561307f576000612fba6001836145c5565b8554909150600090612fce906001906145c5565b9050808214613033576000866000018281548110612fee57612fee614193565b906000526020600020015490508087600001848154811061301157613011614193565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613044576130446146de565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610692565b6000915050610692565b6060612d9d8484600085613460565b825474010000000000000000000000000000000000000000900460ff1615806130bf575081155b156130c957505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061310f90700100000000000000000000000000000000900463ffffffff16426145c5565b905080156131cf5781831115613151576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461318b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612d7b565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156132865773ffffffffffffffffffffffffffffffffffffffff841661322e576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610797565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610797565b848310156133995760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906132ca90826145c5565b6132d4878a6145c5565b6132de91906146cb565b6132e8919061470d565b905073ffffffffffffffffffffffffffffffffffffffff8616613341576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610797565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610797565b6133a385846145c5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610f25565b60008183106134595781610f25565b5090919050565b6060824710156134f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610797565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161351b9190614748565b60006040518083038185875af1925050503d8060008114613558576040519150601f19603f3d011682016040523d82523d6000602084013e61355d565b606091505b509150915061356e87838387613579565b979650505050505050565b6060831561360f5782516000036136085773ffffffffffffffffffffffffffffffffffffffff85163b613608576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610797565b5081612d9d565b612d9d83838151156136245781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610797919061378e565b50805461366490613d11565b6000825580601f10613674575050565b601f016020900490600052602060002090810190611a4691905b808211156136a2576000815560010161368e565b5090565b6000602082840312156136b857600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f2557600080fd5b803567ffffffffffffffff8116811461370057600080fd5b919050565b60006020828403121561371757600080fd5b610f25826136e8565b60005b8381101561373b578181015183820152602001613723565b50506000910152565b6000815180845261375c816020860160208601613720565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f256020830184613744565b6000602082840312156137b357600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a4657600080fd5b8035613700816137ba565b6000602082840312156137f957600080fd5b8135610f25816137ba565b60006020828403121561381657600080fd5b813567ffffffffffffffff81111561382d57600080fd5b82016101008185031215610f2557600080fd5b60008083601f84011261385257600080fd5b50813567ffffffffffffffff81111561386a57600080fd5b6020830191508360208260051b850101111561388557600080fd5b9250929050565b600080600080604085870312156138a257600080fd5b843567ffffffffffffffff808211156138ba57600080fd5b6138c688838901613840565b909650945060208701359150808211156138df57600080fd5b506138ec87828801613840565b95989497509550505050565b6000806040838503121561390b57600080fd5b8235613916816137ba565b946020939093013593505050565b60008060006040848603121561393957600080fd5b613942846136e8565b9250602084013567ffffffffffffffff8082111561395f57600080fd5b818601915086601f83011261397357600080fd5b81358181111561398257600080fd5b87602082850101111561399457600080fd5b6020830194508093505050509250925092565b600080604083850312156139ba57600080fd5b6139c3836136e8565b915060208301356139d3816137ba565b809150509250929050565b6000602082840312156139f057600080fd5b813567ffffffffffffffff811115613a0757600080fd5b820160a08185031215610f2557600080fd5b602081526000825160406020840152613a356060840182613744565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613a708282613744565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ac757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613a95565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613ac757835167ffffffffffffffff1683529284019291840191600101613aef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613b6857613b68613b15565b60405290565b60405160c0810167ffffffffffffffff81118282101715613b6857613b68613b15565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bd857613bd8613b15565b604052919050565b8015158114611a4657600080fd5b803561370081613be0565b80356fffffffffffffffffffffffffffffffff8116811461370057600080fd5b600060608284031215613c2b57600080fd5b6040516060810181811067ffffffffffffffff82111715613c4e57613c4e613b15565b6040529050808235613c5f81613be0565b8152613c6d60208401613bf9565b6020820152613c7e60408401613bf9565b60408201525092915050565b600080600060e08486031215613c9f57600080fd5b613ca8846136e8565b9250613cb78560208601613c19565b9150613cc68560808601613c19565b90509250925092565b60008060208385031215613ce257600080fd5b823567ffffffffffffffff811115613cf957600080fd5b613d0585828601613840565b90969095509350505050565b600181811c90821680613d2557607f821691505b602082108103613d5e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613d7657600080fd5b5051919050565b600067ffffffffffffffff821115613d9757613d97613b15565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613dd457600080fd5b8135613de7613de282613d7d565b613b91565b818152846020838601011115613dfc57600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613e2c57600080fd5b613e34613b44565b823567ffffffffffffffff80821115613e4c57600080fd5b613e5836838701613dc3565b8352613e66602086016136e8565b6020840152613e77604086016137dc565b604084015260608501356060840152613e92608086016137dc565b608084015260a0850135915080821115613eab57600080fd5b613eb736838701613dc3565b60a084015260c0850135915080821115613ed057600080fd5b613edc36838701613dc3565b60c084015260e0850135915080821115613ef557600080fd5b50613f0236828601613dc3565b60e08301525092915050565b601f82111561148e576000816000526020600020601f850160051c81016020861015613f375750805b601f850160051c820191505b81811015610b4d57828155600101613f43565b67ffffffffffffffff831115613f6e57613f6e613b15565b613f8283613f7c8354613d11565b83613f0e565b6000601f841160018114613fd45760008515613f9e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611ec9565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140235786850135825560209485019460019092019101614003565b508682101561405e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006140836040830186613744565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b6000602082840312156140e657600080fd5b8151610f2581613be0565b600060a0823603121561410357600080fd5b60405160a0810167ffffffffffffffff828210818311171561412757614127613b15565b81604052843591508082111561413c57600080fd5b5061414936828601613dc3565b825250614158602084016136e8565b6020820152604083013561416b816137ba565b6040820152606083810135908201526080830135614188816137ba565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126141f657600080fd5b9190910192915050565b6000610140823603121561421357600080fd5b61421b613b6e565b614224836136e8565b815261423260208401613bee565b6020820152604083013567ffffffffffffffff8082111561425257600080fd5b61425e36838701613dc3565b6040840152606085013591508082111561427757600080fd5b5061428436828601613dc3565b6060830152506142973660808501613c19565b60808201526142a93660e08501613c19565b60a082015292915050565b815167ffffffffffffffff8111156142ce576142ce613b15565b6142e2816142dc8454613d11565b84613f0e565b602080601f83116001811461433557600084156142ff5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610b4d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561438257888601518255948401946001909101908401614363565b50858210156143be57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526143f281840187613744565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506144309050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613a70565b60a08152600061447a60a0830187613744565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a0602082015260006144f760a0830186613744565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561453a57600080fd5b815167ffffffffffffffff81111561455157600080fd5b8201601f8101841361456257600080fd5b8051614570613de282613d7d565b81815285602083850101111561458557600080fd5b613a70826020830160208601613720565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561069257610692614596565b67ffffffffffffffff8416815260e0810161462460208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612d9d565b6060810161069282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156146a957600080fd5b8151610f25816137ba565b808202811582820484141761069257610692614596565b8082018082111561069257610692614596565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082614743577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082516141f681846020870161372056fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e30a164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"LegacyPoolChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getOnRamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRampAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPreviousPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIPoolPriorTo1_5\",\"name\":\"prevPool\",\"type\":\"address\"}],\"name\":\"setPreviousPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004f4338038062004f4383398101604081905262000035916200056d565b84848483838383833380600081620000945760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c757620000c78162000186565b5050506001600160a01b0384161580620000e857506001600160a01b038116155b80620000fb57506001600160a01b038216155b156200011a576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200016d576040805160008152602081019091526200016d908462000231565b5050505094151560e05250620006de9650505050505050565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000252576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002dd57600083828151811062000276576200027662000690565b60209081029190910101519050620002906002826200038e565b15620002d3576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000255565b5060005b81518110156200038957600082828151811062000302576200030262000690565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200032e575062000380565b6200033b600282620003ae565b156200037e576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620002e1565b505050565b6000620003a5836001600160a01b038416620003c5565b90505b92915050565b6000620003a5836001600160a01b038416620004c9565b60008181526001830160205260408120548015620004be576000620003ec600183620006a6565b85549091506000906200040290600190620006a6565b90508082146200046e57600086600001828154811062000426576200042662000690565b90600052602060002001549050808760000184815481106200044c576200044c62000690565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004825762000482620006c8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003a8565b6000915050620003a8565b60008181526001830160205260408120546200051257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a8565b506000620003a8565b6001600160a01b03811681146200053157600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000557816200051b565b919050565b805180151581146200055757600080fd5b600080600080600060a086880312156200058657600080fd5b855162000593816200051b565b602087810151919650906001600160401b0380821115620005b357600080fd5b818901915089601f830112620005c857600080fd5b815181811115620005dd57620005dd62000534565b8060051b604051601f19603f8301168101818110858211171562000605576200060562000534565b60405291825284820192508381018501918c8311156200062457600080fd5b938501935b828510156200064d576200063d856200054a565b8452938501939285019262000629565b80995050505050505062000664604087016200054a565b925062000674606087016200055c565b915062000684608087016200054a565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003a857634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516147c2620007816000396000818161057e015261195401526000818161062b01528181611f8e0152612b4a01526000818161060501528181611d2101526122410152600081816102c80152818161031d01528181610809015281816108db015281816109b501528181611a1601528181611c41015281816121610152818161234701528181612ae00152612d3501526147c26000f3fe608060405234801561001057600080fd5b506004361061025c5760003560e01c80639766b93211610145578063c0d78655116100bd578063db6327dc1161008c578063e0351e1311610071578063e0351e1314610629578063eb521a4c1461064f578063f2fde38b1461066257600080fd5b8063db6327dc146105f0578063dc0bd9711461060357600080fd5b8063c0d78655146105a2578063c4bffe2b146105b5578063c75eea9c146105ca578063cf7401f3146105dd57600080fd5b8063a8d87a3b11610114578063b0f479a1116100f9578063b0f479a11461054b578063b794658014610569578063bb98546b1461057c57600080fd5b8063a8d87a3b146104c9578063af58d59f146104dc57600080fd5b80639766b932146104635780639a4575b914610476578063a2b261d814610496578063a7cd63b7146104b457600080fd5b806366320087116101d857806379ba5097116101a757806383826b2b1161018c57806383826b2b1461041f5780638926f54f146104325780638da5cb5b1461044557600080fd5b806379ba5097146104045780637d54534e1461040c57600080fd5b806366320087146103ad5780636cfd1553146103c05780636d3d1a58146103d357806378a010b2146103f157600080fd5b806321df0da71161022f5780633907753711610214578063390775371461035a578063432a6ba31461037c57806354c8a4f31461039a57600080fd5b806321df0da7146102c6578063240028e81461030d57600080fd5b806301ffc9a7146102615780630a2fd493146102895780630a861f2a146102a9578063181f5a77146102be575b600080fd5b61027461026f3660046136df565b610675565b60405190151581526020015b60405180910390f35b61029c61029736600461373e565b6106d1565b60405161028091906137c7565b6102bc6102b73660046137da565b610781565b005b61029c610932565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610280565b61027461031b366004613820565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61036d61036836600461383d565b61094e565b60405190518152602001610280565b600a5473ffffffffffffffffffffffffffffffffffffffff166102e8565b6102bc6103a83660046138c5565b610a87565b6102bc6103bb366004613931565b610b02565b6102bc6103ce366004613820565b610b8e565b60085473ffffffffffffffffffffffffffffffffffffffff166102e8565b6102bc6103ff36600461395d565b610bdd565b6102bc610d4c565b6102bc61041a366004613820565b610e49565b61027461042d3660046139e0565b610e98565b61027461044036600461373e565b610f65565b60005473ffffffffffffffffffffffffffffffffffffffff166102e8565b6102bc610471366004613820565b610f7c565b610489610484366004613a17565b61100b565b6040516102809190613a52565b60095473ffffffffffffffffffffffffffffffffffffffff166102e8565b6104bc6110d4565b6040516102809190613ab2565b6102e86104d736600461373e565b503090565b6104ef6104ea36600461373e565b6110e5565b604051610280919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102e8565b61029c61057736600461373e565b6111ba565b7f0000000000000000000000000000000000000000000000000000000000000000610274565b6102bc6105b0366004613820565b6111e5565b6105bd6112b9565b6040516102809190613b0c565b6104ef6105d836600461373e565b611371565b6102bc6105eb366004613cc3565b611443565b6102bc6105fe366004613d08565b6114cc565b7f00000000000000000000000000000000000000000000000000000000000000006102e8565b7f0000000000000000000000000000000000000000000000000000000000000000610274565b6102bc61065d3660046137da565b611952565b6102bc610670366004613820565b611a6e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d405660000000000000000000000000000000000000000000000000000000014806106cb57506106cb82611a82565b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106fc90613d4a565b80601f016020809104026020016040519081016040528092919081815260200182805461072890613d4a565b80156107755780601f1061074a57610100808354040283529160200191610775565b820191906000526020600020905b81548152906001019060200180831161075857829003601f168201915b50505050509050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146107d9576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610865573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108899190613d9d565b10156108c1576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61090273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611b66565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040518060600160405280602281526020016147946022913981565b60408051602081019091526000815261096e61096983613e52565b611c3a565b60095473ffffffffffffffffffffffffffffffffffffffff166109e5576109e061099e6060840160408501613820565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611b66565b6109f6565b6109f66109f183613e52565b611e6b565b610a066060830160408401613820565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f528460600135604051610a6891815260200190565b60405180910390a3506040805160208101909152606090910135815290565b610a8f611f09565b610afc84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f8c92505050565b50505050565b610b0a611f09565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610b7257600080fd5b505af1158015610b86573d6000803e3d6000fd5b505050505050565b610b96611f09565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610be5611f09565b610bee83610f65565b610c30576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107d0565b67ffffffffffffffff831660009081526007602052604081206004018054610c5790613d4a565b80601f0160208091040260200160405190810160405280929190818152602001828054610c8390613d4a565b8015610cd05780601f10610ca557610100808354040283529160200191610cd0565b820191906000526020600020905b815481529060010190602001808311610cb357829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610cff838583613f8f565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d3e939291906140a9565b60405180910390a250505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107d0565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e51611f09565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff8216301480610f5e5750600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86169281019290925273ffffffffffffffffffffffffffffffffffffffff848116602484015216906383826b2b90604401602060405180830381865afa158015610f3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5e919061410d565b9392505050565b60006106cb600567ffffffffffffffff8416612142565b610f84611f09565b6009805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f81accd0a7023865eaa51b3399dd0eafc488bf3ba238402911e1659cfe860f22891015b60405180910390a15050565b604080518082019091526060808252602082015261103061102b8361412a565b61215a565b60095473ffffffffffffffffffffffffffffffffffffffff161561105f5761105f61105a8361412a565b612324565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a260405180604001604052806110b9846020016020810190610577919061373e565b81526040805160208181019092526000815291015292915050565b60606110e0600261243e565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526106cb9061244b565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106fc90613d4a565b6111ed611f09565b73ffffffffffffffffffffffffffffffffffffffff811661123a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610fff565b606060006112c7600561243e565b90506000815167ffffffffffffffff8111156112e5576112e5613b4e565b60405190808252806020026020018201604052801561130e578160200160208202803683370190505b50905060005b825181101561136a5782818151811061132f5761132f6141cc565b6020026020010151828281518110611349576113496141cc565b67ffffffffffffffff90921660209283029190910190910152600101611314565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526106cb9061244b565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611483575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156114bc576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016107d0565b6114c78383836124fd565b505050565b6114d4611f09565b60005b818110156114c75760008383838181106114f3576114f36141cc565b905060200281019061150591906141fb565b61150e90614239565b905061152381608001518260200151156125e7565b6115368160a001518260200151156125e7565b8060200151156118325780516115589060059067ffffffffffffffff16612720565b61159d5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b60408101515115806115b25750606081015151155b156115e9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906117ca90826142ed565b50606082015160058201906117df90826142ed565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506118259493929190614407565b60405180910390a1611949565b805161184a9060059067ffffffffffffffff1661272c565b61188f5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118f86004830182613691565b611906600583016000613691565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016114d7565b7f00000000000000000000000000000000000000000000000000000000000000006119a9576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff1633146119fc576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016107d0565b611a3e73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612738565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611a76611f09565b611a7f81612796565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611b1557507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806106cb57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526114c79084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261288b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611ccf5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016107d0565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611d7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da1919061410d565b15611dd8576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611de58160200151612997565b6000611df482602001516106d1565b9050805160001480611e18575080805190602001208260a001518051906020012014155b15611e55578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016107d091906137c7565b611e6782602001518360600151612abd565b5050565b60095481516040808401516060850151602086015192517f8627fad600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90951694638627fad694611ed494909392916004016144a0565b600060405180830381600087803b158015611eee57600080fd5b505af1158015611f02573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611f8a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107d0565b565b7f0000000000000000000000000000000000000000000000000000000000000000611fe3576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612079576000838281518110612003576120036141cc565b60200260200101519050612021816002612b0490919063ffffffff16565b156120705760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611fe6565b5060005b81518110156114c757600082828151811061209a5761209a6141cc565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120de575061213a565b6120e9600282612b26565b156121385760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161207d565b60008181526001830160205260408120541515610f5e565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146121ef5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016107d0565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561229d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c1919061410d565b156122f8576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123058160400151612b48565b6123128160200151612bc7565b611a7f81602001518260600151612d15565b60095460608201516123719173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692911690611b66565b60095460408083015183516060850151602086015193517f9687544500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909516946396875445946123d994939291600401614501565b6000604051808303816000875af11580156123f8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e679190810190614561565b60606000610f5e83612d59565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526124d982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426124bd91906145fe565b85608001516fffffffffffffffffffffffffffffffff16612db4565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61250683610f65565b612548576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107d0565b6125538260006125e7565b67ffffffffffffffff831660009081526007602052604090206125769083612dde565b6125818160006125e7565b67ffffffffffffffff831660009081526007602052604090206125a79060020182612dde565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516125da93929190614611565b60405180910390a1505050565b8151156126ae5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061263d575060408201516fffffffffffffffffffffffffffffffff16155b1561267657816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107d09190614694565b8015611e67576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806126e7575060208201516fffffffffffffffffffffffffffffffff1615155b15611e6757816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107d09190614694565b6000610f5e8383612f80565b6000610f5e8383612fcf565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610afc9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611bb8565b3373ffffffffffffffffffffffffffffffffffffffff821603612815576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107d0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006128ed826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166130c29092919063ffffffff16565b8051909150156114c7578080602001905181019061290b919061410d565b6114c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107d0565b6129a081610f65565b6129e2576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107d0565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612a61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a85919061410d565b611a7f576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016107d0565b67ffffffffffffffff82166000908152600760205260409020611e6790600201827f00000000000000000000000000000000000000000000000000000000000000006130d1565b6000610f5e8373ffffffffffffffffffffffffffffffffffffffff8416612fcf565b6000610f5e8373ffffffffffffffffffffffffffffffffffffffff8416612f80565b7f000000000000000000000000000000000000000000000000000000000000000015611a7f57612b79600282613454565b611a7f576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107d0565b612bd081610f65565b612c12576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107d0565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612caf91906146d0565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a7f576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016107d0565b67ffffffffffffffff82166000908152600760205260409020611e6790827f00000000000000000000000000000000000000000000000000000000000000006130d1565b60608160000180548060200260200160405190810160405280929190818152602001828054801561077557602002820191906000526020600020905b815481526020019060010190808311612d955750505050509050919050565b6000612dd385612dc484866146ed565b612dce9087614704565b613483565b90505b949350505050565b8154600090612e0790700100000000000000000000000000000000900463ffffffff16426145fe565b90508015612ea95760018301548354612e4f916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612db4565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612ecf916fffffffffffffffffffffffffffffffff9081169116613483565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906125da908490614694565b6000818152600183016020526040812054612fc7575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106cb565b5060006106cb565b600081815260018301602052604081205480156130b8576000612ff36001836145fe565b8554909150600090613007906001906145fe565b905080821461306c576000866000018281548110613027576130276141cc565b906000526020600020015490508087600001848154811061304a5761304a6141cc565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061307d5761307d614717565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106cb565b60009150506106cb565b6060612dd68484600085613499565b825474010000000000000000000000000000000000000000900460ff1615806130f8575081155b1561310257505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061314890700100000000000000000000000000000000900463ffffffff16426145fe565b90508015613208578183111561318a576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546131c49083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612db4565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156132bf5773ffffffffffffffffffffffffffffffffffffffff8416613267576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016107d0565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016107d0565b848310156133d25760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061330390826145fe565b61330d878a6145fe565b6133179190614704565b6133219190614746565b905073ffffffffffffffffffffffffffffffffffffffff861661337a576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016107d0565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016107d0565b6133dc85846145fe565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610f5e565b60008183106134925781610f5e565b5090919050565b60608247101561352b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107d0565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516135549190614781565b60006040518083038185875af1925050503d8060008114613591576040519150601f19603f3d011682016040523d82523d6000602084013e613596565b606091505b50915091506135a7878383876135b2565b979650505050505050565b606083156136485782516000036136415773ffffffffffffffffffffffffffffffffffffffff85163b613641576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107d0565b5081612dd6565b612dd6838381511561365d5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d091906137c7565b50805461369d90613d4a565b6000825580601f106136ad575050565b601f016020900490600052602060002090810190611a7f91905b808211156136db57600081556001016136c7565b5090565b6000602082840312156136f157600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f5e57600080fd5b803567ffffffffffffffff8116811461373957600080fd5b919050565b60006020828403121561375057600080fd5b610f5e82613721565b60005b8381101561377457818101518382015260200161375c565b50506000910152565b60008151808452613795816020860160208601613759565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f5e602083018461377d565b6000602082840312156137ec57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a7f57600080fd5b8035613739816137f3565b60006020828403121561383257600080fd5b8135610f5e816137f3565b60006020828403121561384f57600080fd5b813567ffffffffffffffff81111561386657600080fd5b82016101008185031215610f5e57600080fd5b60008083601f84011261388b57600080fd5b50813567ffffffffffffffff8111156138a357600080fd5b6020830191508360208260051b85010111156138be57600080fd5b9250929050565b600080600080604085870312156138db57600080fd5b843567ffffffffffffffff808211156138f357600080fd5b6138ff88838901613879565b9096509450602087013591508082111561391857600080fd5b5061392587828801613879565b95989497509550505050565b6000806040838503121561394457600080fd5b823561394f816137f3565b946020939093013593505050565b60008060006040848603121561397257600080fd5b61397b84613721565b9250602084013567ffffffffffffffff8082111561399857600080fd5b818601915086601f8301126139ac57600080fd5b8135818111156139bb57600080fd5b8760208285010111156139cd57600080fd5b6020830194508093505050509250925092565b600080604083850312156139f357600080fd5b6139fc83613721565b91506020830135613a0c816137f3565b809150509250929050565b600060208284031215613a2957600080fd5b813567ffffffffffffffff811115613a4057600080fd5b820160a08185031215610f5e57600080fd5b602081526000825160406020840152613a6e606084018261377d565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613aa9828261377d565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015613b0057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613ace565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613b0057835167ffffffffffffffff1683529284019291840191600101613b28565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613ba157613ba1613b4e565b60405290565b60405160c0810167ffffffffffffffff81118282101715613ba157613ba1613b4e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613c1157613c11613b4e565b604052919050565b8015158114611a7f57600080fd5b803561373981613c19565b80356fffffffffffffffffffffffffffffffff8116811461373957600080fd5b600060608284031215613c6457600080fd5b6040516060810181811067ffffffffffffffff82111715613c8757613c87613b4e565b6040529050808235613c9881613c19565b8152613ca660208401613c32565b6020820152613cb760408401613c32565b60408201525092915050565b600080600060e08486031215613cd857600080fd5b613ce184613721565b9250613cf08560208601613c52565b9150613cff8560808601613c52565b90509250925092565b60008060208385031215613d1b57600080fd5b823567ffffffffffffffff811115613d3257600080fd5b613d3e85828601613879565b90969095509350505050565b600181811c90821680613d5e57607f821691505b602082108103613d97577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613daf57600080fd5b5051919050565b600067ffffffffffffffff821115613dd057613dd0613b4e565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613e0d57600080fd5b8135613e20613e1b82613db6565b613bca565b818152846020838601011115613e3557600080fd5b816020850160208301376000918101602001919091529392505050565b60006101008236031215613e6557600080fd5b613e6d613b7d565b823567ffffffffffffffff80821115613e8557600080fd5b613e9136838701613dfc565b8352613e9f60208601613721565b6020840152613eb060408601613815565b604084015260608501356060840152613ecb60808601613815565b608084015260a0850135915080821115613ee457600080fd5b613ef036838701613dfc565b60a084015260c0850135915080821115613f0957600080fd5b613f1536838701613dfc565b60c084015260e0850135915080821115613f2e57600080fd5b50613f3b36828601613dfc565b60e08301525092915050565b601f8211156114c7576000816000526020600020601f850160051c81016020861015613f705750805b601f850160051c820191505b81811015610b8657828155600101613f7c565b67ffffffffffffffff831115613fa757613fa7613b4e565b613fbb83613fb58354613d4a565b83613f47565b6000601f84116001811461400d5760008515613fd75750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611f02565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561405c578685013582556020948501946001909201910161403c565b5086821015614097577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006140bc604083018661377d565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b60006020828403121561411f57600080fd5b8151610f5e81613c19565b600060a0823603121561413c57600080fd5b60405160a0810167ffffffffffffffff828210818311171561416057614160613b4e565b81604052843591508082111561417557600080fd5b5061418236828601613dfc565b82525061419160208401613721565b602082015260408301356141a4816137f3565b60408201526060838101359082015260808301356141c1816137f3565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261422f57600080fd5b9190910192915050565b6000610140823603121561424c57600080fd5b614254613ba7565b61425d83613721565b815261426b60208401613c27565b6020820152604083013567ffffffffffffffff8082111561428b57600080fd5b61429736838701613dfc565b604084015260608501359150808211156142b057600080fd5b506142bd36828601613dfc565b6060830152506142d03660808501613c52565b60808201526142e23660e08501613c52565b60a082015292915050565b815167ffffffffffffffff81111561430757614307613b4e565b61431b816143158454613d4a565b84613f47565b602080601f83116001811461436e57600084156143385750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610b86565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156143bb5788860151825594840194600190910190840161439c565b50858210156143f757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261442b8184018761377d565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506144699050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613aa9565b60a0815260006144b360a083018761377d565b73ffffffffffffffffffffffffffffffffffffffff8616602084015284604084015267ffffffffffffffff841660608401528281036080840152600081526020810191505095945050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815260a06020820152600061453060a083018661377d565b60408301949094525067ffffffffffffffff9190911660608201528082036080909101526000815260200192915050565b60006020828403121561457357600080fd5b815167ffffffffffffffff81111561458a57600080fd5b8201601f8101841361459b57600080fd5b80516145a9613e1b82613db6565b8181528560208385010111156145be57600080fd5b613aa9826020830160208601613759565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106cb576106cb6145cf565b67ffffffffffffffff8416815260e0810161465d60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612dd6565b606081016106cb82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b6000602082840312156146e257600080fd5b8151610f5e816137f3565b80820281158282048414176106cb576106cb6145cf565b808201808211156106cb576106cb6145cf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261477c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000825161422f81846020870161375956fe4c6f636b52656c65617365546f6b656e506f6f6c416e6450726f787920312e352e30a164736f6c6343000818000a", } var LockReleaseTokenPoolAndProxyABI = LockReleaseTokenPoolAndProxyMetaData.ABI @@ -354,6 +354,28 @@ func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) return _LockReleaseTokenPoolAndProxy.Contract.GetOnRamp(&_LockReleaseTokenPoolAndProxy.CallOpts, arg0) } +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetPreviousPool(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getPreviousPool") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxySession) GetPreviousPool() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetPreviousPool(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + +func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCallerSession) GetPreviousPool() (common.Address, error) { + return _LockReleaseTokenPoolAndProxy.Contract.GetPreviousPool(&_LockReleaseTokenPoolAndProxy.CallOpts) +} + func (_LockReleaseTokenPoolAndProxy *LockReleaseTokenPoolAndProxyCaller) GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) { var out []interface{} err := _LockReleaseTokenPoolAndProxy.contract.Call(opts, &out, "getRateLimitAdmin") @@ -3238,6 +3260,8 @@ type LockReleaseTokenPoolAndProxyInterface interface { GetOnRamp(opts *bind.CallOpts, arg0 uint64) (common.Address, error) + GetPreviousPool(opts *bind.CallOpts) (common.Address, error) + GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) GetRebalancer(opts *bind.CallOpts) (common.Address, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index bb45cb27ce..ce0b93fe4e 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -3,9 +3,9 @@ arm_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/sol arm_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 1e60c28ad796a220a38043b369dec8d9bffe23e1c7d9895760e30672872afd06 burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 3e8e3358f0bb520af069a7d37ea625940a88461a54418b1d5925eabced8c74df -burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 524c72699d2666cf3b3effecfe67441854f62f153baef209258c9a5562680fca +burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 717c079d5d13300cf3c3ee871c6e5bf9af904411f204fb081a9f3b263cca1391 burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6333d0314d0bd29e75ea5e05fe62a4516ade0c6db91c30b6f93645035db52ed8 -burn_with_from_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin 84a4d9f45c51c7ae87b32d42ddc15665c92aaa3de4672227448a9b766b15ef7c +burn_with_from_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin 08ed1235dda921ce8841b26aa18d0c0f36db4884779dd7670857159801b6d597 ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin a92a9ae55b235f47ac58af942e43a20dc7df31cfba9178c133e5b3e273816503 ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin fcced2263564f51b5bf086c221e813ec06a71d2bb2e246b4e28cd60098a6de6f commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin 274d87db70b643e00ab0a7e7845bb4b791f3b613bfc87708d33fc5a8369e2a41 @@ -16,7 +16,7 @@ evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2E evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin b0d77babbe635cd6ba04c2af049badc9e9d28a4b6ed6bb75f830ad902a618beb evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 5c02c2b167946b3467636ff2bb58594cb4652fc63d8bdfee2488ed562e2a3e50 lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin e6a8ec9e8faccb1da7d90e0f702ed72975964f97dc3222b54cfcca0a0ba3fea2 -lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin 9afb4cf8621b5e60ac70c1b95fcc28d735119bdbc8c702bc9931d30e712e29f3 +lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin e632b08be0fbd1d013e8b3a9d75293d0d532b83071c531ff2be1deec1fa48ec1 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin 1d5146d43e1b99cd2d6f9f06475be19087e4349f7cee0fdbbf134ba65e967c93 mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin d976651d36b33ac2196b32b9d2f4fa6690c6a18d41b621365659fce1c1d1e737 From 5b61e17cae108c5218f24617ff2d842d93bd01bc Mon Sep 17 00:00:00 2001 From: Connor Stein Date: Fri, 16 Aug 2024 14:08:09 -0400 Subject: [PATCH 211/432] Tooling deployment scaffolding (#1252) - NOTE ~5k is generated protobuf code to unblock. That will be imported once exposed. - We put the deployment/configuration logic in integration-tests module for a few reasons: - Keeps the chain dependencies out of the core module, in particular helpful for eventual cross family tests - It can become the canonical deployment logic to be used for CRIB envs as well (eventually can replace the actions + contracts dirs) - To accomplish the lightweight tests (chainlink.Application + simulated.Backend) we expose some test utilities in util/testutils/ - integration-tests/deployment holds product agnostic deployment utilities including a general purpose environment structure to write environment abstracted code against and migration output components (address books, proposals etc) - integration-tests/deployment/ccip holds all product specific deployment code including - Top level migrations and migration tests where a "migration" is defined to be a function which operates against an environment and outputs a MigrationOutput structure with one or more artifacts (MCMS proposals, job specs). Notably migration tests can apply those outputs to an ephemeral environment to ensure correctness. These migrations are intended for export and use against real environments (testnet/mainnet). - Re-usable product specific components of top level migrations and associated tests Next steps / follow up PRs: - Port testutils export to chainlink repo - Example solana setup - Once cross family validated, start deeper testing and real CCIP use cases --------- Co-authored-by: Adam Hamrick Co-authored-by: AnieeG --- .../ccip/testhelpers/integration/chainlink.go | 52 +- .../internal/integration_test.go | 843 ++++++++++++++++++ .../multichain_config_tracker_test.go | 323 +++++++ integration-tests/.golangci.yml | 2 +- integration-tests/deployment/address_book.go | 118 +-- .../deployment/address_book_test.go | 117 +-- integration-tests/deployment/ccip/deploy.go | 561 ++++++++++++ .../deployment/ccip/deploy_home_chain.go | 410 +++++++++ .../deployment/ccip/deploy_test.go | 49 + integration-tests/deployment/ccip/jobs.go | 70 ++ .../ccip/migrations/1_initial_deploy.go | 34 + .../ccip/migrations/1_initial_deploy_test.go | 295 ++++++ integration-tests/deployment/ccip/propose.go | 64 ++ integration-tests/deployment/ccip/state.go | 271 ++++++ integration-tests/deployment/environment.go | 8 +- .../deployment/jd/job/v1/job.pb.go | 5 +- .../deployment/jd/job/v1/job_grpc.pb.go | 1 - .../deployment/jd/node/v1/node_grpc.pb.go | 1 - .../deployment/jd/node/v1/shared.pb.go | 5 +- .../deployment/jd/shared/ptypes/label.pb.go | 5 +- .../deployment/memory/environment.go | 4 +- .../deployment/memory/job_client.go | 16 +- integration-tests/deployment/memory/node.go | 12 - integration-tests/deployment/migrations.go | 28 + integration-tests/go.mod | 99 +- integration-tests/go.sum | 135 ++- integration-tests/load/go.mod | 49 +- integration-tests/load/go.sum | 124 ++- 28 files changed, 3191 insertions(+), 510 deletions(-) create mode 100644 core/services/ocr2/plugins/liquiditymanager/internal/integration_test.go create mode 100644 core/services/ocr2/plugins/liquiditymanager/ocr3impls/multichain_config_tracker_test.go create mode 100644 integration-tests/deployment/ccip/deploy.go create mode 100644 integration-tests/deployment/ccip/deploy_home_chain.go create mode 100644 integration-tests/deployment/ccip/deploy_test.go create mode 100644 integration-tests/deployment/ccip/jobs.go create mode 100644 integration-tests/deployment/ccip/migrations/1_initial_deploy.go create mode 100644 integration-tests/deployment/ccip/migrations/1_initial_deploy_test.go create mode 100644 integration-tests/deployment/ccip/propose.go create mode 100644 integration-tests/deployment/ccip/state.go create mode 100644 integration-tests/deployment/migrations.go diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go index 676ae79e35..35401b0316 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go @@ -7,7 +7,6 @@ import ( "math/big" "net/http" "net/http/httptest" - "slices" "strconv" "strings" "testing" @@ -37,7 +36,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" v2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -49,7 +47,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" @@ -381,6 +378,7 @@ func setupNodeCCIP( fmt.Sprintf("127.0.0.1:%d", port), } c.Log.Level = &loglevel + c.Feature.CCIP = &trueRef c.Feature.UICSAKeys = &trueRef c.Feature.FeedsManager = &trueRef c.OCR.Enabled = &falseRef @@ -460,10 +458,9 @@ func setupNodeCCIP( } loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing()) relayerFactory := chainlink.RelayerFactory{ - Logger: lggr, - LoopRegistry: loopRegistry, - GRPCOpts: loop.GRPCOpts{}, - CapabilitiesRegistry: coretypes.NewCapabilitiesRegistry(t), + Logger: lggr, + LoopRegistry: loopRegistry, + GRPCOpts: loop.GRPCOpts{}, } testCtx := testutils.Context(t) // evm alway enabled for backward compatibility @@ -764,47 +761,6 @@ func (c *CCIPIntegrationTestHarness) NoNodesHaveExecutedSeqNum(t *testing.T, seq return log } -func (c *CCIPIntegrationTestHarness) EventuallyPriceRegistryUpdated(t *testing.T, block uint64, srcSelector uint64, tokens []common.Address, sourceNative common.Address, priceRegistryOpts ...common.Address) { - var priceRegistry *price_registry_1_2_0.PriceRegistry - var err error - if len(priceRegistryOpts) > 0 { - priceRegistry, err = price_registry_1_2_0.NewPriceRegistry(priceRegistryOpts[0], c.Dest.Chain) - require.NoError(t, err) - } else { - require.NotNil(t, c.Dest.PriceRegistry, "no priceRegistry configured") - priceRegistry = c.Dest.PriceRegistry - } - - g := gomega.NewGomegaWithT(t) - g.Eventually(func() bool { - it, err := priceRegistry.FilterUsdPerTokenUpdated(&bind.FilterOpts{Start: block}, tokens) - g.Expect(err).NotTo(gomega.HaveOccurred(), "Error filtering UsdPerTokenUpdated event") - - tokensFetched := make([]common.Address, 0, len(tokens)) - for it.Next() { - tokenFetched := it.Event.Token - tokensFetched = append(tokensFetched, tokenFetched) - t.Log("Token price updated", tokenFetched.String(), it.Event.Value.String(), it.Event.Timestamp.String()) - } - - for _, token := range tokens { - if !slices.Contains(tokensFetched, token) { - return false - } - } - - return true - }, testutils.WaitTimeout(t), 10*time.Second).Should(gomega.BeTrue(), "Tokens prices has not been updated") - - g.Eventually(func() bool { - it, err := priceRegistry.FilterUsdPerUnitGasUpdated(&bind.FilterOpts{Start: block}, []uint64{srcSelector}) - g.Expect(err).NotTo(gomega.HaveOccurred(), "Error filtering UsdPerUnitGasUpdated event") - g.Expect(it.Next()).To(gomega.BeTrue(), "No UsdPerUnitGasUpdated event found") - - return true - }, testutils.WaitTimeout(t), 10*time.Second).Should(gomega.BeTrue(), "source gas price has not been updated") -} - func (c *CCIPIntegrationTestHarness) EventuallyCommitReportAccepted(t *testing.T, currentBlock uint64, commitStoreOpts ...common.Address) commit_store.CommitStoreCommitReport { var commitStore *commit_store.CommitStore var err error diff --git a/core/services/ocr2/plugins/liquiditymanager/internal/integration_test.go b/core/services/ocr2/plugins/liquiditymanager/internal/integration_test.go new file mode 100644 index 0000000000..e648781ad1 --- /dev/null +++ b/core/services/ocr2/plugins/liquiditymanager/internal/integration_test.go @@ -0,0 +1,843 @@ +package internal_test + +import ( + "context" + "fmt" + "math/big" + "net/http" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + gethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/hashicorp/consul/sdk/freeport" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/libocr/commontypes" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink-common/pkg/config" + + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + v2toml "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + evmutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/liquiditymanager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/mock_l1_bridge_adapter" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/logger/audit" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/bridge/testonlybridge" + integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/testhelpers/integration" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" + + "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/plugins" +) + +var ( + mainChainID = int64(chainsel.GETH_TESTNET.EvmChainID) +) + +func TestLiquidityManager_Integration(t *testing.T) { + t.Skip("flakey test") + newTestUniverse(t, 2, false) +} + +type ocr3Node struct { + app chainlink.Application + peerID string + transmitters map[int64]common.Address + keybundle ocr2key.KeyBundle +} + +type onchainUniverse struct { + backend *backends.SimulatedBackend + chainID uint64 + wethToken *weth9.WETH9 + lockReleasePool *lock_release_token_pool.LockReleaseTokenPool + liquidityManager *liquiditymanager.LiquidityManager + bridgeAdapter *mock_l1_bridge_adapter.MockL1BridgeAdapter +} + +func setupNodeOCR3( + t *testing.T, + owner *bind.TransactOpts, + port int, + chainIDToBackend map[int64]*backends.SimulatedBackend, + p2pV2Bootstrappers []commontypes.BootstrapperLocator, + useForwarders bool, +) *ocr3Node { + // Do not want to load fixtures as they contain a dummy chainID. + config, db := heavyweight.FullTestDBNoFixturesV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.Insecure.OCRDevelopmentMode = ptr(true) // Disables ocr spec validation so we can have fast polling for the test. + + c.Feature.LogPoller = ptr(true) + + c.P2P.V2.Enabled = ptr(true) + c.P2P.V2.DeltaDial = config.MustNewDuration(500 * time.Millisecond) + c.P2P.V2.DeltaReconcile = config.MustNewDuration(5 * time.Second) + c.P2P.V2.ListenAddresses = &[]string{fmt.Sprintf("127.0.0.1:%d", port)} + if len(p2pV2Bootstrappers) > 0 { + c.P2P.V2.DefaultBootstrappers = &p2pV2Bootstrappers + } + + c.OCR.Enabled = ptr(false) + c.OCR.DefaultTransactionQueueDepth = ptr(uint32(200)) + c.OCR2.Enabled = ptr(true) + + c.EVM[0].LogPollInterval = config.MustNewDuration(500 * time.Millisecond) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](3_500_000) + c.EVM[0].Transactions.ForwardersEnabled = &useForwarders + c.OCR2.ContractPollInterval = config.MustNewDuration(5 * time.Second) + + var chains v2toml.EVMConfigs + for chainID := range chainIDToBackend { + chains = append(chains, createConfigV2Chain(big.NewInt(chainID))) + } + c.EVM = chains + c.OCR2.ContractPollInterval = config.MustNewDuration(5 * time.Second) + }) + + lggr := logger.TestLogger(t) + lggr.SetLogLevel(zapcore.InfoLevel) + ctx := testutils.Context(t) + clients := make(map[int64]client.Client) + + for chainID, backend := range chainIDToBackend { + clients[chainID] = client.NewSimulatedBackendClient(t, backend, big.NewInt(chainID)) + } + + master := keystore.New(db, utils.FastScryptParams, lggr) + + keystore := KeystoreSim{ + eks: &EthKeystoreSim{ + Eth: master.Eth(), + t: t, + }, + csa: master.CSA(), + } + mailMon := mailbox.NewMonitor("LiquidityManager", lggr.Named("mailbox")) + evmOpts := chainlink.EVMFactoryConfig{ + ChainOpts: legacyevm.ChainOpts{ + AppConfig: config, + GenEthClient: func(i *big.Int) client.Client { + t.Log("genning eth client for chain id:", i.String()) + client, ok := clients[i.Int64()] + if !ok { + t.Fatal("no backend for chainID", i) + } + return client + }, + MailMon: mailMon, + DS: db, + }, + CSAETHKeystore: keystore, + } + relayerFactory := chainlink.RelayerFactory{ + Logger: lggr, + LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing()), + GRPCOpts: loop.GRPCOpts{}, + } + initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitEVM(testutils.Context(t), relayerFactory, evmOpts)} + rci, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) + require.NoError(t, err) + + app, err := chainlink.NewApplication(chainlink.ApplicationOpts{ + Config: config, + DS: db, + KeyStore: master, + RelayerChainInteroperators: rci, + Logger: lggr, + ExternalInitiatorManager: nil, + CloseLogger: lggr.Sync, + UnrestrictedHTTPClient: &http.Client{}, + RestrictedHTTPClient: &http.Client{}, + AuditLogger: audit.NoopLogger, + MailMon: mailMon, + LoopRegistry: plugins.NewLoopRegistry(lggr, config.Tracing()), + }) + require.NoError(t, err) + require.NoError(t, app.GetKeyStore().Unlock(ctx, "password")) + _, err = app.GetKeyStore().P2P().Create(ctx) + require.NoError(t, err) + + p2pIDs, err := app.GetKeyStore().P2P().GetAll() + require.NoError(t, err) + require.Len(t, p2pIDs, 1) + peerID := p2pIDs[0].PeerID() + + // create a transmitter for each chain + transmitters := make(map[int64]common.Address) + for chainID, backend := range chainIDToBackend { + addrs, err2 := app.GetKeyStore().Eth().EnabledAddressesForChain(testutils.Context(t), big.NewInt(chainID)) + require.NoError(t, err2) + if len(addrs) == 1 { + // just fund the address + fundAddress(t, owner, addrs[0], assets.Ether(10).ToInt(), backend) + transmitters[chainID] = addrs[0] + } else { + // create key and fund it + _, err3 := app.GetKeyStore().Eth().Create(testutils.Context(t), big.NewInt(chainID)) + require.NoError(t, err3, "failed to create key for chain", chainID) + sendingKeys, err3 := app.GetKeyStore().Eth().EnabledAddressesForChain(testutils.Context(t), big.NewInt(chainID)) + require.NoError(t, err3) + require.Len(t, sendingKeys, 1) + fundAddress(t, owner, sendingKeys[0], assets.Ether(10).ToInt(), backend) + transmitters[chainID] = sendingKeys[0] + } + } + require.Len(t, transmitters, len(chainIDToBackend)) + + keybundle, err := app.GetKeyStore().OCR2().Create(ctx, chaintype.EVM) + require.NoError(t, err) + + return &ocr3Node{ + app: app, + peerID: peerID.Raw(), + transmitters: transmitters, + keybundle: keybundle, + } +} + +func newTestUniverse(t *testing.T, numChains int, adapterHoldNative bool) { + // create chains and deploy contracts + owner, chains := createChains(t, numChains) + universes := deployContracts(t, owner, chains, adapterHoldNative) + createConnectedNetwork(t, owner, chains, universes) + transferBalances(t, owner, universes) + mainContract := universes[mainChainID].liquidityManager.Address() + + t.Log("Creating bootstrap node") + bootstrapNodePort := freeport.GetOne(t) + bootstrapNode := setupNodeOCR3(t, owner, bootstrapNodePort, chains, nil, false) + numNodes := 4 + + t.Log("creating ocr3 nodes") + var ( + oracles = make(map[int64][]confighelper2.OracleIdentityExtra) + transmitters = make(map[int64][]common.Address) + onchainPubKeys []common.Address + kbs []ocr2key.KeyBundle + apps []chainlink.Application + nodes []*ocr3Node + ) + ports := freeport.GetN(t, numNodes) + for i := 0; i < numNodes; i++ { + // Supply the bootstrap IP and port as a V2 peer address + bootstrappers := []commontypes.BootstrapperLocator{ + {PeerID: bootstrapNode.peerID, Addrs: []string{ + fmt.Sprintf("127.0.0.1:%d", bootstrapNodePort), + }}, + } + node := setupNodeOCR3(t, owner, ports[i], chains, bootstrappers, false) + + kbs = append(kbs, node.keybundle) + apps = append(apps, node.app) + for chainID, transmitter := range node.transmitters { + transmitters[chainID] = append(transmitters[chainID], transmitter) + } + onchainPubKeys = append(onchainPubKeys, common.BytesToAddress(node.keybundle.PublicKey())) + for chainID, transmitter := range node.transmitters { + identity := confighelper2.OracleIdentityExtra{ + OracleIdentity: confighelper2.OracleIdentity{ + OnchainPublicKey: node.keybundle.PublicKey(), + TransmitAccount: ocrtypes.Account(transmitter.Hex()), + OffchainPublicKey: node.keybundle.OffchainPublicKey(), + PeerID: node.peerID, + }, + ConfigEncryptionPublicKey: node.keybundle.ConfigEncryptionPublicKey(), + } + oracles[chainID] = append(oracles[chainID], identity) + } + nodes = append(nodes, node) + } + + t.Log("starting ticker to commit blocks") + tick := time.NewTicker(1 * time.Second) + defer tick.Stop() + tickCtx, tickCancel := context.WithCancel(testutils.Context(t)) + defer tickCancel() + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + for { + select { + case <-tick.C: + for _, backend := range chains { + backend.Commit() + } + case <-tickCtx.Done(): + return + } + } + }() + t.Cleanup(func() { + tickCancel() + wg.Wait() + }) + + t.Log("setting config") + blocksBeforeConfig := setLiquidityManagerConfigs( + t, + owner, + universes, + chains, + onchainPubKeys, + transmitters, + oracles) + mainFromBlock := blocksBeforeConfig[mainChainID] + + t.Log("adding bootstrap node job") + err := bootstrapNode.app.Start(testutils.Context(t)) + require.NoError(t, err, "failed to start bootstrap node") + t.Cleanup(func() { + require.NoError(t, bootstrapNode.app.Stop()) + }) + + evmChains := bootstrapNode.app.GetRelayers().LegacyEVMChains() + require.NotNil(t, evmChains) + require.Len(t, evmChains.Slice(), numChains) + bootstrapJobSpec, err := integrationtesthelpers.NewBootsrapJobSpec(&integrationtesthelpers.LMJobSpecParams{ + ChainID: 1337, + ContractID: mainContract.Hex(), + RelayFromBlock: mainFromBlock, + }) + require.NoError(t, err, "failed to create bootstrap job spec") + bootstrapJobSpecStr, err := bootstrapJobSpec.String() + require.NoError(t, err, "failed to convert bootstrap job spec to string") + t.Log("creating bootstrap job with spec:\n", bootstrapJobSpecStr) + ocrJob, err := ocrbootstrap.ValidatedBootstrapSpecToml(bootstrapJobSpecStr) + require.NoError(t, err, "failed to validate bootstrap job") + err = bootstrapNode.app.AddJobV2(testutils.Context(t), &ocrJob) + require.NoError(t, err, "failed to add bootstrap job") + + t.Log("creating ocr3 jobs") + for i := 0; i < numNodes; i++ { + err = apps[i].Start(testutils.Context(t)) + require.NoError(t, err) + tapp := apps[i] + t.Cleanup(func() { + require.NoError(t, tapp.Stop()) + }) + + mainChain := mustGetChainByEvmID(t, testutils.SimulatedChainID.Int64()) + jobSpec, err := integrationtesthelpers.NewJobSpec(&integrationtesthelpers.LMJobSpecParams{ + Name: "liquiditymanager-integration-test", + Type: "ping-pong", + ChainID: 1337, + ContractID: mainContract.Hex(), + OCRKeyBundleID: kbs[i].ID(), + TransmitterID: nodes[i].transmitters[1337].Hex(), + RelayFromBlock: mainFromBlock, + FollowerChains: buildFollowerChainsFromBlocksToml(blocksBeforeConfig), + LiquidityManagerAddress: mainContract, + NetworkSelector: mainChain.Selector, + }) + require.NoError(t, err, "failed to create job spec") + jobSpecStr, err := jobSpec.String() + require.NoError(t, err, "failed to convert job spec to string") + t.Log("Creating liquidityManager job with spec:\n", jobSpecStr) + ocrJob2, err2 := validate.ValidatedOracleSpecToml( + testutils.Context(t), + apps[i].GetConfig().OCR2(), + apps[i].GetConfig().Insecure(), + jobSpecStr, + nil, + ) + require.NoError(t, err2, "failed to validate liquidityManager job") + err2 = apps[i].AddJobV2(testutils.Context(t), &ocrJob2) + require.NoError(t, err2, "failed to add liquidityManager job") + } + + t.Log("waiting for a transmission") + waitForTransmissions(t, universes) +} + +func waitForTransmissions( + t *testing.T, + universes map[int64]onchainUniverse, +) { + start := uint64(1) + liquidityTransferredSink := make(chan *liquiditymanager.LiquidityManagerLiquidityTransferred) + finalizationStepSink := make(chan *liquiditymanager.LiquidityManagerFinalizationStepCompleted) + var subs []event.Subscription + for _, uni := range universes { + sub, err := uni.liquidityManager.WatchLiquidityTransferred(&bind.WatchOpts{ + Start: &start, + }, liquidityTransferredSink, nil, nil, nil) + require.NoError(t, err, "failed to create subscription") + subs = append(subs, sub) + + sub, err = uni.liquidityManager.WatchFinalizationStepCompleted(&bind.WatchOpts{ + Start: &start, + }, finalizationStepSink, nil, nil) + require.NoError(t, err, "failed to create subscription") + subs = append(subs, sub) + } + defer func() { + for _, sub := range subs { + sub.Unsubscribe() + } + }() + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + sentEvents := map[string]struct{}{} + for { + select { + case lt := <-liquidityTransferredSink: + // determine if it's a send or receive event based on the BridgeReturnData field + // if it's a send event, then the BridgeReturnData will not be empty + if len(lt.BridgeReturnData) > 0 { + // for the test bridges, bridge return data is just a nonce + nonce, err := testonlybridge.UnpackBridgeSendReturnData(lt.BridgeReturnData) + require.NoError(t, err) + t.Log("received send event with nonce:", nonce, "tx hash:", lt.Raw.TxHash.String()) + sentEvents[nonce.String()] = struct{}{} + } else { + // for the test bridges, the bridge specific data is an amount and a nonce + amount, nonce, err := testonlybridge.UnpackFinalizeBridgePayload(lt.BridgeSpecificData) + require.NoError(t, err) + t.Log("received receive event with amount:", amount, "nonce:", nonce, "tx hash:", lt.Raw.TxHash.String()) + _, ok := sentEvents[nonce.String()] + if ok { + t.Log("received corresponding receive event") + return + } + t.Fatal("received receive event without corresponding send event") + } + case fsc := <-finalizationStepSink: + nonce, err := testonlybridge.UnpackProveBridgePayload(fsc.BridgeSpecificData) + require.NoError(t, err) + t.Log("received finalization step completed event with seqNr:", fsc.OcrSeqNum, + ", nonce:", nonce.String(), ", tx hash:", fsc.Raw.TxHash.String()) + case <-ticker.C: + t.Log("waiting for transmission or liquidity transferred event") + } + } +} + +func setLiquidityManagerConfig( + t *testing.T, + owner *bind.TransactOpts, + wrapper *liquiditymanager.LiquidityManager, + chain *backends.SimulatedBackend, + onchainPubKeys []common.Address, + transmitters []common.Address, + oracles []confighelper2.OracleIdentityExtra, +) (blockBeforeConfig int64) { + beforeConfig, err := chain.BlockByNumber(testutils.Context(t), nil) + require.NoError(t, err) + + // most of the config on the follower chains does not matter + // except for signers + transmitters + var schedule []int + for range oracles { + schedule = append(schedule, 1) + } + offchainConfig, onchainConfig := []byte{}, []byte{} + f := uint8(1) + _, _, f, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( + 30*time.Second, // deltaProgress + 10*time.Second, // deltaResend + 20*time.Second, // deltaInitial + 2*time.Second, // deltaRound + 20*time.Second, // deltaGrace + 10*time.Second, // deltaCertifiedCommitRequest + 10*time.Second, // deltaStage + 3, // rmax + schedule, + oracles, + offchainConfig, + 50*time.Millisecond, // maxDurationQuery + 5*time.Second, // maxDurationObservation + 10*time.Second, // maxDurationShouldAcceptAttestedReport + 10*time.Second, // maxDurationShouldTransmitAcceptedReport + int(f), + onchainConfig) + require.NoError(t, err, "failed to create contract config") + _, err = wrapper.SetOCR3Config( + owner, + onchainPubKeys, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig) + require.NoError(t, err, "failed to set config") + chain.Commit() + + iter, err := wrapper.FilterConfigSet(&bind.FilterOpts{ + Start: beforeConfig.Number().Uint64(), + }) + require.NoError(t, err, "failed to create ConfigSet filter") + require.True(t, iter.Next()) + e := iter.Event + require.Equal(t, onchainPubKeys, e.Signers, "signers do not match") + require.Equal(t, transmitters, e.Transmitters, "transmitters do not match") + t.Log("config digest for liquidityManager at address: ", wrapper.Address(), ", is:", hexutil.Encode(e.ConfigDigest[:])) + + return beforeConfig.Number().Int64() +} + +func setLiquidityManagerConfigs( + t *testing.T, + owner *bind.TransactOpts, + universes map[int64]onchainUniverse, + chains map[int64]*backends.SimulatedBackend, + onchainPubKeys []common.Address, + transmitters map[int64][]common.Address, + oracles map[int64][]confighelper2.OracleIdentityExtra) (blocksBeforeConfig map[int64]int64) { + blocksBeforeConfig = make(map[int64]int64) + for chainID, uni := range universes { + blocksBeforeConfig[chainID] = setLiquidityManagerConfig( + t, + owner, + uni.liquidityManager, + chains[chainID], + onchainPubKeys, + transmitters[chainID], + oracles[chainID], + ) + } + return +} + +func ptr[T any](v T) *T { return &v } + +func createConfigV2Chain(chainID *big.Int) *v2toml.EVMConfig { + chain := v2toml.Defaults((*evmutils.Big)(chainID)) + chain.GasEstimator.LimitDefault = ptr(uint64(4e6)) + chain.LogPollInterval = config.MustNewDuration(500 * time.Millisecond) + chain.Transactions.ForwardersEnabled = ptr(false) + chain.FinalityDepth = ptr(uint32(2)) + return &v2toml.EVMConfig{ + ChainID: (*evmutils.Big)(chainID), + Enabled: ptr(true), + Chain: chain, + Nodes: v2toml.EVMNodes{&v2toml.Node{}}, + } +} + +var _ keystore.Eth = &EthKeystoreSim{} + +type EthKeystoreSim struct { + keystore.Eth + t *testing.T +} + +// override +func (e *EthKeystoreSim) SignTx(ctx context.Context, address common.Address, tx *gethtypes.Transaction, chainID *big.Int) (*gethtypes.Transaction, error) { + // always sign with chain id 1337 for the simulated backend + e.t.Log("always signing tx for chain id:", chainID.String(), "with chain id 1337, tx hash:", tx.Hash()) + return e.Eth.SignTx(ctx, address, tx, big.NewInt(1337)) +} + +type KeystoreSim struct { + eks keystore.Eth + csa keystore.CSA +} + +func (e KeystoreSim) Eth() keystore.Eth { + return e.eks +} + +func (e KeystoreSim) CSA() keystore.CSA { + return e.csa +} + +func fundAddress(t *testing.T, from *bind.TransactOpts, to common.Address, amount *big.Int, backend *backends.SimulatedBackend) { + nonce, err := backend.PendingNonceAt(testutils.Context(t), from.From) + require.NoError(t, err) + gp, err := backend.SuggestGasPrice(testutils.Context(t)) + require.NoError(t, err) + rawTx := gethtypes.NewTx(&gethtypes.LegacyTx{ + Nonce: nonce, + GasPrice: gp, + Gas: 21000, + To: &to, + Value: amount, + }) + signedTx, err := from.Signer(from.From, rawTx) + require.NoError(t, err) + err = backend.SendTransaction(testutils.Context(t), signedTx) + require.NoError(t, err) + backend.Commit() +} + +func createChains(t *testing.T, numChains int) (owner *bind.TransactOpts, chains map[int64]*backends.SimulatedBackend) { + owner = testutils.MustNewSimTransactor(t) + chains = make(map[int64]*backends.SimulatedBackend) + + chains[mainChainID] = backends.NewSimulatedBackend(core.GenesisAlloc{ + owner.From: core.GenesisAccount{ + Balance: assets.Ether(10_000).ToInt(), + }, + }, 30e6) + + for chainID := int64(chainsel.TEST_90000001.EvmChainID); chainID < int64(chainsel.TEST_90000020.EvmChainID); chainID++ { + chains[chainID] = backends.NewSimulatedBackend(core.GenesisAlloc{ + owner.From: core.GenesisAccount{ + Balance: assets.Ether(10000).ToInt(), + }, + }, 30e6) + + if len(chains) == numChains { + break + } + } + return +} + +func deployContracts( + t *testing.T, + owner *bind.TransactOpts, + chains map[int64]*backends.SimulatedBackend, + adapterHoldNative bool, +) ( + universes map[int64]onchainUniverse, +) { + universes = make(map[int64]onchainUniverse) + for chainID, backend := range chains { + // Deploy wrapped ether contract + // will act as the ERC-20 being bridged + wethAddress, _, _, err := weth9.DeployWETH9(owner, backend) + require.NoError(t, err, "failed to deploy WETH9 contract") + backend.Commit() + wethToken, err := weth9.NewWETH9(wethAddress, backend) + require.NoError(t, err, "failed to create WETH9 wrapper") + + // deposit some eth into the weth contract + _, err = wethToken.Deposit(&bind.TransactOpts{ + From: owner.From, + Signer: owner.Signer, + Value: assets.Ether(100).ToInt(), + Context: testutils.Context(t), + }) + require.NoError(t, err, "failed to deposit eth into weth contract") + + // deploy arm and arm proxy. + // required by the token pool + // otherwise not used by this test. + armAddress, _, _, err := mock_arm_contract.DeployMockARMContract(owner, backend) + require.NoError(t, err, "failed to deploy MockARMContract contract") + backend.Commit() + armProxyAddress, _, _, err := arm_proxy_contract.DeployARMProxyContract(owner, backend, armAddress) + require.NoError(t, err, "failed to deploy ARMProxyContract contract") + backend.Commit() + + routerAddress, _, _, err := router.DeployRouter(owner, backend, wethAddress, armProxyAddress) + require.NoError(t, err, "failed to deploy Router contract") + backend.Commit() + + // deploy lock/release pool targeting the weth9 contract + lockReleasePoolAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( + owner, backend, wethAddress, []common.Address{}, armProxyAddress, true, routerAddress) + require.NoError(t, err, "failed to deploy LockReleaseTokenPool contract") + backend.Commit() + lockReleasePool, err := lock_release_token_pool.NewLockReleaseTokenPool(lockReleasePoolAddress, backend) + require.NoError(t, err) + + // deploy the liquidityManager and set the liquidity container to be the lock release pool + ch := mustGetChainByEvmID(t, chainID) + liquidityManagerAddr, _, _, err := liquiditymanager.DeployLiquidityManager(owner, backend, wethAddress, ch.Selector, lockReleasePoolAddress, big.NewInt(0), common.Address{}) + require.NoError(t, err, "failed to deploy LiquidityManager contract") + liquidityManager, err := liquiditymanager.NewLiquidityManager(liquidityManagerAddr, backend) + require.NoError(t, err, "failed to create LiquidityManager wrapper") + + // set the liquidityManager of the lock release pool to be the just deployed liquidityManager + _, err = lockReleasePool.SetRebalancer(owner, liquidityManagerAddr) + require.NoError(t, err, "failed to set liquidityManager on lock/release pool") + backend.Commit() + actualLiquidityManager, err := lockReleasePool.GetRebalancer(&bind.CallOpts{Context: testutils.Context(t)}) + require.NoError(t, err) + require.Equal(t, liquidityManagerAddr, actualLiquidityManager) + + // deploy the bridge adapter to point to the weth contract address + bridgeAdapterAddress, _, _, err := mock_l1_bridge_adapter.DeployMockL1BridgeAdapter(owner, backend, wethAddress, adapterHoldNative) + require.NoError(t, err, "failed to deploy mock l1 bridge adapter") + backend.Commit() + bridgeAdapter, err := mock_l1_bridge_adapter.NewMockL1BridgeAdapter(bridgeAdapterAddress, backend) + require.NoError(t, err) + + universes[chainID] = onchainUniverse{ + backend: backend, + chainID: uint64(chainID), + wethToken: wethToken, + lockReleasePool: lockReleasePool, + liquidityManager: liquidityManager, + bridgeAdapter: bridgeAdapter, + } + + t.Log("deployed contracts for chain:", chainID, + "weth:", wethAddress.Hex(), + "lockReleasePool:", lockReleasePool.Address().Hex(), + "rebalancer:", liquidityManagerAddr.Hex(), + "bridgeAdapter:", bridgeAdapterAddress.Hex(), + ) + } + return +} + +func buildFollowerChainsFromBlocksToml(fromBlocks map[int64]int64) string { + var s string + for chainID, fromBlock := range fromBlocks { + if chainID == mainChainID { + continue + } + s += fmt.Sprintf("%d = %d\n", chainID, fromBlock) + } + return s +} + +func transferBalances( + t *testing.T, + owner *bind.TransactOpts, + universes map[int64]onchainUniverse, +) { + for _, uni := range universes { + // move some weth to the bridge adapters + // so that they can transfer it to the rebalancer + // when it calls finalizeWithdrawal + _, err := uni.wethToken.Transfer(owner, uni.bridgeAdapter.Address(), assets.Ether(5).ToInt()) + require.NoError(t, err, "failed to transfer weth to bridge adapter") + uni.backend.Commit() + // confirm balance + bal, err := uni.wethToken.BalanceOf(&bind.CallOpts{Context: testutils.Context(t)}, uni.bridgeAdapter.Address()) + require.NoError(t, err) + require.Equal(t, assets.Ether(5).ToInt(), bal) + + // move some weth to the lock/release pool + // the LM will pull from this pool in order to send cross-chain + _, err = uni.wethToken.Transfer(owner, uni.lockReleasePool.Address(), assets.Ether(5).ToInt()) + require.NoError(t, err, "failed to transfer weth to lock/release pool") + uni.backend.Commit() + // confirm balance + bal, err = uni.wethToken.BalanceOf(&bind.CallOpts{Context: testutils.Context(t)}, uni.lockReleasePool.Address()) + require.NoError(t, err) + require.Equal(t, assets.Ether(5).ToInt(), bal) + + // check the balance of the token pool through the rebalancer, + // should be the same as the balance of the lock/release pool + // retrieved above. + bal, err = uni.liquidityManager.GetLiquidity(&bind.CallOpts{Context: testutils.Context(t)}) + require.NoError(t, err) + require.Equal(t, assets.Ether(5).ToInt(), bal) + } +} + +// create a connection from the main chain to all follower chains +// and from all follower chains to the main chain +// this is analogous to the main chain being an L1 and all other +// chains being L2's. +func createConnectedNetwork( + t *testing.T, + owner *bind.TransactOpts, + chains map[int64]*backends.SimulatedBackend, + universes map[int64]onchainUniverse, +) { + for chainID, uni := range universes { + if chainID == mainChainID { + continue + } + // follower -> main connection + remoteChain := mustGetChainByEvmID(t, mainChainID) + + _, err := uni.liquidityManager.SetCrossChainRebalancer( + owner, + liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs{ + RemoteRebalancer: universes[mainChainID].liquidityManager.Address(), + RemoteChainSelector: remoteChain.Selector, + Enabled: true, + LocalBridge: uni.bridgeAdapter.Address(), + RemoteToken: universes[mainChainID].wethToken.Address(), + }) + require.NoError(t, err, "failed to SetCrossChainRebalancer from follower to main chain") + chains[chainID].Commit() + + mgr, err := uni.liquidityManager.GetCrossChainRebalancer(&bind.CallOpts{Context: testutils.Context(t)}, remoteChain.Selector) + require.NoError(t, err) + require.Equal(t, universes[mainChainID].liquidityManager.Address(), mgr.RemoteRebalancer) + require.Equal(t, uni.bridgeAdapter.Address(), mgr.LocalBridge) + require.Equal(t, universes[mainChainID].wethToken.Address(), mgr.RemoteToken) + require.True(t, mgr.Enabled) + + // main -> follower connection + remoteChain = mustGetChainByEvmID(t, chainID) + + _, err = universes[mainChainID].liquidityManager.SetCrossChainRebalancer( + owner, + liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs{ + RemoteRebalancer: uni.liquidityManager.Address(), + RemoteChainSelector: remoteChain.Selector, + Enabled: true, + LocalBridge: universes[mainChainID].bridgeAdapter.Address(), + RemoteToken: uni.wethToken.Address(), + }) + require.NoError(t, err, "failed to add neighbor from main to follower chain") + chains[mainChainID].Commit() + + mgr, err = universes[mainChainID].liquidityManager.GetCrossChainRebalancer( + &bind.CallOpts{Context: testutils.Context(t)}, remoteChain.Selector) + require.NoError(t, err) + require.Equal(t, uni.liquidityManager.Address(), mgr.RemoteRebalancer) + require.Equal(t, universes[mainChainID].bridgeAdapter.Address(), mgr.LocalBridge) + require.Equal(t, uni.wethToken.Address(), mgr.RemoteToken) + require.True(t, mgr.Enabled) + } + + // sanity check connections + for chainID, uni := range universes { + destChains, err := uni.liquidityManager.GetSupportedDestChains(&bind.CallOpts{Context: testutils.Context(t)}) + require.NoError(t, err, "couldn't get supported dest chains") + t.Log("num dest chains:", len(destChains), "dest chains:", destChains) + if chainID == mainChainID { + require.Len(t, destChains, len(universes)-1) + } else { + require.Len(t, destChains, 1) + } + mgrs, err := uni.liquidityManager.GetAllCrossChainRebalancers(&bind.CallOpts{ + Context: testutils.Context(t), + }) + require.NoError(t, err, "couldn't get all cross-chain liquidity managers") + t.Log("chainID:", chainID, "num neighbors:", len(mgrs)) + if chainID == mainChainID { + // should be connected to all follower chains + require.Len(t, mgrs, len(universes)-1, "unexpected number of neighbors on main chain") + } else { + // should be connected to just the main chain + require.Len(t, mgrs, 1, "unexpected number of neighbors on follower chain") + } + } +} + +func mustGetChainByEvmID(t *testing.T, chainID int64) chainsel.Chain { + ch, exists := chainsel.ChainByEvmChainID(uint64(chainID)) + require.True(t, exists) + return ch +} diff --git a/core/services/ocr2/plugins/liquiditymanager/ocr3impls/multichain_config_tracker_test.go b/core/services/ocr2/plugins/liquiditymanager/ocr3impls/multichain_config_tracker_test.go new file mode 100644 index 0000000000..13dd88d1f2 --- /dev/null +++ b/core/services/ocr2/plugins/liquiditymanager/ocr3impls/multichain_config_tracker_test.go @@ -0,0 +1,323 @@ +package ocr3impls_test + +import ( + "encoding/hex" + "math/big" + "strconv" + "testing" + "time" + + "github.com/jmoiron/sqlx" + chainsel "github.com/smartcontractkit/chain-selectors" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/no_op_ocr3" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + discoverermocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/discoverer/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/graph" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/models" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/ocr3impls" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" +) + +func setupLogPoller[RI ocr3impls.MultichainMeta](t *testing.T, db *sqlx.DB, bs *keyringsAndSigners[RI]) (logpoller.LogPoller, testUniverse[RI]) { + lggr := logger.TestLogger(t) + + o := logpoller.NewORM(testutils.SimulatedChainID, db, lggr) + + // create the universe which will deploy the OCR contract and set config + // we will replay on the log poller to get the appropriate ConfigSet log + uni := newTestUniverse[RI](t, bs) + lpOpts := logpoller.Opts{ + PollPeriod: 1 * time.Second, + FinalityDepth: 100, + BackfillBatchSize: 100, + RpcBatchSize: 100, + KeepFinalizedBlocksDepth: 200, + } + headTracker := headtracker.NewSimulatedHeadTracker(uni.simClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + if lpOpts.PollPeriod == 0 { + lpOpts.PollPeriod = 1 * time.Hour + } + lp := logpoller.NewLogPoller(o, uni.simClient, lggr, headTracker, lpOpts) + return lp, uni +} + +func TestConfigSet(t *testing.T) { + require.Equal(t, no_op_ocr3.NoOpOCR3ConfigSet{}.Topic().Hex(), ocr3impls.ConfigSet.Hex()) +} + +func TestMultichainConfigTracker_New(t *testing.T) { + t.Run("master chain not in log pollers", func(t *testing.T) { + db := pgtest.NewSqlxDB(t) + _, uni := setupLogPoller[multichainMeta](t, db, nil) + + masterChain := commontypes.RelayID{ + Network: relay.NetworkEVM, + ChainID: testutils.SimulatedChainID.String(), + } + mockDiscovererFactory := discoverermocks.NewFactory(t) + _, err := ocr3impls.NewMultichainConfigTracker( + masterChain, + logger.TestLogger(t), + map[commontypes.RelayID]logpoller.LogPoller{}, + uni.simClient, + uni.wrapper.Address(), + mockDiscovererFactory, + ocr3impls.TransmitterCombiner, + nil, + ) + require.Error(t, err, "expected error creating multichain config tracker") + }) + + t.Run("combiner is nil", func(t *testing.T) { + db := pgtest.NewSqlxDB(t) + lp, uni := setupLogPoller[multichainMeta](t, db, nil) + + masterChain := commontypes.RelayID{ + Network: relay.NetworkEVM, + ChainID: testutils.SimulatedChainID.String(), + } + mockDiscovererFactory := discoverermocks.NewFactory(t) + _, err := ocr3impls.NewMultichainConfigTracker( + masterChain, + logger.TestLogger(t), + map[commontypes.RelayID]logpoller.LogPoller{masterChain: lp}, + uni.simClient, + uni.wrapper.Address(), + mockDiscovererFactory, + nil, + nil, + ) + require.Error(t, err, "expected error creating multichain config tracker") + }) + + t.Run("factory is nil", func(t *testing.T) { + db := pgtest.NewSqlxDB(t) + lp, uni := setupLogPoller[multichainMeta](t, db, nil) + + masterChain := commontypes.RelayID{ + Network: relay.NetworkEVM, + ChainID: testutils.SimulatedChainID.String(), + } + _, err := ocr3impls.NewMultichainConfigTracker( + masterChain, + logger.TestLogger(t), + map[commontypes.RelayID]logpoller.LogPoller{masterChain: lp}, + uni.simClient, + uni.wrapper.Address(), + nil, + ocr3impls.TransmitterCombiner, + nil, + ) + require.Error(t, err, "expected error creating multichain config tracker") + }) +} + +func TestMultichainConfigTracker_SingleChain(t *testing.T) { + db := pgtest.NewSqlxDB(t) + lp, uni := setupLogPoller[multichainMeta](t, db, nil) + require.NoError(t, lp.Start(testutils.Context(t))) + t.Cleanup(func() { require.NoError(t, lp.Close()) }) + + masterChain := commontypes.RelayID{ + Network: relay.NetworkEVM, + ChainID: testutils.SimulatedChainID.String(), + } + + ch, exists := chainsel.ChainByEvmChainID(uint64(mustStrToI64(t, masterChain.ChainID))) + assert.True(t, exists) + + // for this test only one LM is "deployed" + // so the discovery will return a single LM which is the master LM + g := graph.NewGraph() + g.(graph.GraphTest).AddNetwork(models.NetworkSelector(ch.Selector), graph.Data{ + Liquidity: big.NewInt(1234), // liquidity doesn't matter for this test + LiquidityManagerAddress: models.Address(uni.wrapper.Address()), + }) + mockDiscoverer := discoverermocks.NewDiscoverer(t) + mockDiscoverer.On("Discover", mock.Anything).Return(g, nil) + defer mockDiscoverer.AssertExpectations(t) + mockDiscovererFactory := discoverermocks.NewFactory(t) + mockDiscovererFactory.On("NewDiscoverer", models.NetworkSelector(ch.Selector), models.Address(uni.wrapper.Address())). + Return(mockDiscoverer, nil) + defer mockDiscovererFactory.AssertExpectations(t) + tracker, err := ocr3impls.NewMultichainConfigTracker( + masterChain, + logger.TestLogger(t), + map[commontypes.RelayID]logpoller.LogPoller{masterChain: lp}, + uni.simClient, + uni.wrapper.Address(), + mockDiscovererFactory, + ocr3impls.TransmitterCombiner, + nil, + ) + require.NoError(t, err, "failed to create multichain config tracker") + + // Replay the log poller to get the ConfigSet log + err = tracker.ReplayChain(testutils.Context(t), masterChain, 1) + require.NoError(t, err, "failed to replay log poller") + + // fetch config digest from the tracker + changedInBlock, configDigest, err := tracker.LatestConfigDetails(testutils.Context(t)) + require.NoError(t, err, "failed to get latest config details") + c, err := uni.wrapper.LatestConfigDetails(nil) + require.NoError(t, err, "failed to get latest config digest and epoch") + require.Equal(t, hex.EncodeToString(c.ConfigDigest[:]), configDigest.Hex(), "expected latest config digest to match") + + // fetch config details from the tracker + config, err := tracker.LatestConfig(testutils.Context(t), changedInBlock) + require.NoError(t, err, "failed to get latest config") + require.Equal(t, uint64(1), config.ConfigCount, "expected config count to match") + require.Equal(t, configDigest, config.ConfigDigest, "expected config digest to match") + require.Equal(t, uint8(1), config.F, "expected f to match") + require.Equal(t, []byte{}, config.OnchainConfig, "expected onchain config to match") + require.Equal(t, []byte{}, config.OffchainConfig, "expected offchain config to match") + require.Equal(t, uint64(3), config.OffchainConfigVersion, "expected offchain config version to match") + expectedSigners := func() []ocrtypes.OnchainPublicKey { + var signers []ocrtypes.OnchainPublicKey + for _, b := range uni.keyrings { + signers = append(signers, b.PublicKey()) + } + return signers + }() + expectedTransmitters := func() []ocrtypes.Account { + var accounts []ocrtypes.Account + for _, tm := range uni.transmitters { + accounts = append(accounts, ocrtypes.Account(ocr3impls.EncodeTransmitter(masterChain, ocrtypes.Account(tm.From.Hex())))) + } + return accounts + }() + require.Equal(t, expectedSigners, config.Signers, "expected signers to match") + require.Equal(t, expectedTransmitters, config.Transmitters, "expected transmitters to match") +} + +func TestMultichainConfigTracker_Multichain(t *testing.T) { + // create heavyweight db's because the log pollers need to have separate + // databases to avoid conflicts. + _, db1 := heavyweight.FullTestDBV2(t, nil) + _, db2 := heavyweight.FullTestDBV2(t, nil) + + lp1, uni1 := setupLogPoller[multichainMeta](t, db1, nil) + lp2, uni2 := setupLogPoller[multichainMeta](t, db2, &keyringsAndSigners[multichainMeta]{ + keyrings: uni1.keyrings, + signers: uni1.signers, + }) + t.Cleanup(func() { + require.NoError(t, lp1.Close()) + require.NoError(t, lp2.Close()) + }) + + // finality depth + uni2.backend.Commit() + uni2.backend.Commit() + + // start the log pollers + require.NoError(t, lp1.Start(testutils.Context(t))) + require.NoError(t, lp2.Start(testutils.Context(t))) + + // create the multichain config tracker + // the chain id's we're using in the mappings are different from the + // simulated chain id but that should be fine for this test. + masterChain := commontypes.RelayID{ + Network: relay.NetworkEVM, + ChainID: strconv.FormatUint(chainsel.TEST_90000001.EvmChainID, 10), + } + secondChain := commontypes.RelayID{ + Network: relay.NetworkEVM, + ChainID: strconv.FormatUint(chainsel.TEST_90000002.EvmChainID, 10), + } + + chain1, exists := chainsel.ChainByEvmChainID(uint64(mustStrToI64(t, masterChain.ChainID))) + assert.True(t, exists) + + chain2, exists := chainsel.ChainByEvmChainID(uint64(mustStrToI64(t, secondChain.ChainID))) + assert.True(t, exists) + + // this test doesn't care about the connections, just the vertices themselves + g := graph.NewGraph() + g.(graph.GraphTest).AddNetwork(models.NetworkSelector(chain1.Selector), graph.Data{ + Liquidity: big.NewInt(1234), // liquidity doesn't matter for this test + LiquidityManagerAddress: models.Address(uni1.wrapper.Address()), + }) + g.(graph.GraphTest).AddNetwork(models.NetworkSelector(chain2.Selector), graph.Data{ + Liquidity: big.NewInt(1234), // liquidity doesn't matter for this test + LiquidityManagerAddress: models.Address(uni2.wrapper.Address()), + }) + mockDiscoverer := discoverermocks.NewDiscoverer(t) + mockDiscoverer.On("Discover", mock.Anything).Return(g, nil) + defer mockDiscoverer.AssertExpectations(t) + mockDiscovererFactory := discoverermocks.NewFactory(t) + mockDiscovererFactory.On("NewDiscoverer", models.NetworkSelector(chain1.Selector), models.Address(uni1.wrapper.Address())). + Return(mockDiscoverer, nil) + defer mockDiscovererFactory.AssertExpectations(t) + tracker, err := ocr3impls.NewMultichainConfigTracker( + masterChain, + logger.TestLogger(t), + map[commontypes.RelayID]logpoller.LogPoller{ + masterChain: lp1, + secondChain: lp2, + }, + uni1.simClient, + uni1.wrapper.Address(), + mockDiscovererFactory, + ocr3impls.TransmitterCombiner, + nil, // we call replay explicitly below + ) + require.NoError(t, err, "failed to create multichain config tracker") + + // Replay the log pollers to get the ConfigSet log + // on each respective chain + require.NoError(t, tracker.ReplayChain(testutils.Context(t), masterChain, 1), "failed to replay log poller on master chain") + require.NoError(t, tracker.ReplayChain(testutils.Context(t), secondChain, 1), "failed to replay log poller on second chain") + + // fetch config digest from the tracker + changedInBlock, configDigest, err := tracker.LatestConfigDetails(testutils.Context(t)) + require.NoError(t, err, "failed to get latest config details") + c, err := uni1.wrapper.LatestConfigDetails(nil) + require.NoError(t, err, "failed to get latest config digest and epoch") + require.Equal(t, hex.EncodeToString(c.ConfigDigest[:]), configDigest.Hex(), "expected latest config digest to match") + + // fetch config details from the tracker + config, err := tracker.LatestConfig(testutils.Context(t), changedInBlock) + require.NoError(t, err, "failed to get latest config") + require.Equal(t, uint64(1), config.ConfigCount, "expected config count to match") + require.Equal(t, configDigest, config.ConfigDigest, "expected config digest to match") + require.Equal(t, uint8(1), config.F, "expected f to match") + require.Equal(t, []byte{}, config.OnchainConfig, "expected onchain config to match") + require.Equal(t, []byte{}, config.OffchainConfig, "expected offchain config to match") + require.Equal(t, uint64(3), config.OffchainConfigVersion, "expected offchain config version to match") + expectedSigners := func() []ocrtypes.OnchainPublicKey { + var signers []ocrtypes.OnchainPublicKey + for _, b := range uni1.keyrings { + signers = append(signers, b.PublicKey()) + } + return signers + }() + require.Equal(t, expectedSigners, config.Signers, "expected signers to match") + expectedTransmitters := func() []ocrtypes.Account { + var accounts []ocrtypes.Account + for i := range uni1.transmitters { + t1 := ocr3impls.EncodeTransmitter(masterChain, ocrtypes.Account(uni1.transmitters[i].From.Hex())) + t2 := ocr3impls.EncodeTransmitter(secondChain, ocrtypes.Account(uni2.transmitters[i].From.Hex())) + accounts = append(accounts, ocrtypes.Account(ocr3impls.JoinTransmitters([]string{t1, t2}))) + } + return accounts + }() + require.Equal(t, expectedTransmitters, config.Transmitters, "expected transmitters to match") +} + +func mustStrToI64(t *testing.T, s string) int64 { + i, err := strconv.ParseInt(s, 10, 64) + require.NoError(t, err) + return i +} diff --git a/integration-tests/.golangci.yml b/integration-tests/.golangci.yml index a75f9a5e46..304249d24c 100644 --- a/integration-tests/.golangci.yml +++ b/integration-tests/.golangci.yml @@ -46,7 +46,7 @@ linters-settings: - name: errorf - name: empty-block - name: superfluous-else - - name: unused-parameter + #- name: unused-parameter - name: unreachable-code - name: redefines-builtin-id - name: waitgroup-by-value diff --git a/integration-tests/deployment/address_book.go b/integration-tests/deployment/address_book.go index 4a5916111c..409b3a482c 100644 --- a/integration-tests/deployment/address_book.go +++ b/integration-tests/deployment/address_book.go @@ -1,112 +1,25 @@ package deployment -import ( - "fmt" - "strings" - - "github.com/Masterminds/semver/v3" - "github.com/ethereum/go-ethereum/common" - "github.com/pkg/errors" - chainsel "github.com/smartcontractkit/chain-selectors" -) - -var ( - ErrInvalidChainSelector = fmt.Errorf("invalid chain selector") - ErrInvalidAddress = fmt.Errorf("invalid address") -) - -// ContractType is a simple string type for identifying contract types. -type ContractType string - -var ( - Version1_0_0 = *semver.MustParse("1.0.0") - Version1_1_0 = *semver.MustParse("1.1.0") - Version1_2_0 = *semver.MustParse("1.2.0") - Version1_5_0 = *semver.MustParse("1.5.0") - Version1_6_0_dev = *semver.MustParse("1.6.0-dev") -) - -type TypeAndVersion struct { - Type ContractType - Version semver.Version -} - -func (tv TypeAndVersion) String() string { - return fmt.Sprintf("%s %s", tv.Type, tv.Version.String()) -} - -func (tv TypeAndVersion) Equal(other TypeAndVersion) bool { - return tv.String() == other.String() -} - -func MustTypeAndVersionFromString(s string) TypeAndVersion { - tv, err := TypeAndVersionFromString(s) - if err != nil { - panic(err) - } - return tv -} - -// Note this will become useful for validation. When we want -// to assert an onchain call to typeAndVersion yields whats expected. -func TypeAndVersionFromString(s string) (TypeAndVersion, error) { - parts := strings.Split(s, " ") - if len(parts) != 2 { - return TypeAndVersion{}, fmt.Errorf("invalid type and version string: %s", s) - } - v, err := semver.NewVersion(parts[1]) - if err != nil { - return TypeAndVersion{}, err - } - return TypeAndVersion{ - Type: ContractType(parts[0]), - Version: *v, - }, nil -} - -func NewTypeAndVersion(t ContractType, v semver.Version) TypeAndVersion { - return TypeAndVersion{ - Type: t, - Version: v, - } -} +import "fmt" // AddressBook is a simple interface for storing and retrieving contract addresses across -// chains. It is family agnostic as the keys are chain selectors. -// We store rather than derive typeAndVersion as some contracts do not support it. -// For ethereum addresses are always stored in EIP55 format. +// chains. It is family agnostic. type AddressBook interface { - Save(chainSelector uint64, address string, tv TypeAndVersion) error - Addresses() (map[uint64]map[string]TypeAndVersion, error) - AddressesForChain(chain uint64) (map[string]TypeAndVersion, error) + Save(chainSelector uint64, address string, typeAndVersion string) error + Addresses() (map[uint64]map[string]string, error) + AddressesForChain(chain uint64) (map[string]string, error) // Allows for merging address books (e.g. new deployments with existing ones) Merge(other AddressBook) error } type AddressBookMap struct { - AddressesByChain map[uint64]map[string]TypeAndVersion + AddressesByChain map[uint64]map[string]string } -func (m *AddressBookMap) Save(chainSelector uint64, address string, typeAndVersion TypeAndVersion) error { - _, exists := chainsel.ChainBySelector(chainSelector) - if !exists { - return errors.Wrapf(ErrInvalidChainSelector, "chain selector %d not found", chainSelector) - } - if address == "" || address == common.HexToAddress("0x0").Hex() { - return errors.Wrap(ErrInvalidAddress, "address cannot be empty") - } - if common.IsHexAddress(address) { - // IMPORTANT: WE ALWAYS STANDARDIZE ETHEREUM ADDRESS STRINGS TO EIP55 - address = common.HexToAddress(address).Hex() - } else { - return errors.Wrapf(ErrInvalidAddress, "address %s is not a valid Ethereum address, only Ethereum addresses supported", address) - } - if typeAndVersion.Type == "" { - return fmt.Errorf("type cannot be empty") - } +func (m *AddressBookMap) Save(chainSelector uint64, address string, typeAndVersion string) error { if _, exists := m.AddressesByChain[chainSelector]; !exists { // First time chain add, create map - m.AddressesByChain[chainSelector] = make(map[string]TypeAndVersion) + m.AddressesByChain[chainSelector] = make(map[string]string) } if _, exists := m.AddressesByChain[chainSelector][address]; exists { return fmt.Errorf("address %s already exists for chain %d", address, chainSelector) @@ -115,11 +28,11 @@ func (m *AddressBookMap) Save(chainSelector uint64, address string, typeAndVersi return nil } -func (m *AddressBookMap) Addresses() (map[uint64]map[string]TypeAndVersion, error) { +func (m *AddressBookMap) Addresses() (map[uint64]map[string]string, error) { return m.AddressesByChain, nil } -func (m *AddressBookMap) AddressesForChain(chain uint64) (map[string]TypeAndVersion, error) { +func (m *AddressBookMap) AddressesForChain(chain uint64) (map[string]string, error) { if _, exists := m.AddressesByChain[chain]; !exists { return nil, fmt.Errorf("chain %d not found", chain) } @@ -142,17 +55,8 @@ func (m *AddressBookMap) Merge(ab AddressBook) error { return nil } -// TODO: Maybe could add an environment argument -// which would ensure only mainnet/testnet chain selectors are used -// for further safety? func NewMemoryAddressBook() *AddressBookMap { return &AddressBookMap{ - AddressesByChain: make(map[uint64]map[string]TypeAndVersion), - } -} - -func NewMemoryAddressBookFromMap(addressesByChain map[uint64]map[string]TypeAndVersion) *AddressBookMap { - return &AddressBookMap{ - AddressesByChain: addressesByChain, + AddressesByChain: make(map[uint64]map[string]string), } } diff --git a/integration-tests/deployment/address_book_test.go b/integration-tests/deployment/address_book_test.go index c6967df0ca..d34053e89c 100644 --- a/integration-tests/deployment/address_book_test.go +++ b/integration-tests/deployment/address_book_test.go @@ -1,112 +1,71 @@ package deployment import ( - "errors" "testing" - "github.com/ethereum/go-ethereum/common" - chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" "gotest.tools/v3/assert" ) -func TestAddressBook_Save(t *testing.T) { +func TestAddressBook(t *testing.T) { ab := NewMemoryAddressBook() - onRamp100 := NewTypeAndVersion("OnRamp", Version1_0_0) - onRamp110 := NewTypeAndVersion("OnRamp", Version1_1_0) - addr1 := common.HexToAddress("0x1").String() - addr2 := common.HexToAddress("0x2").String() - - err := ab.Save(chainsel.TEST_90000001.Selector, addr1, onRamp100) + err := ab.Save(1, "0x1", "OnRamp 1.0.0") require.NoError(t, err) - - // Check input validation - err = ab.Save(chainsel.TEST_90000001.Selector, "asdlfkj", onRamp100) - require.Error(t, err) - assert.Equal(t, errors.Is(err, ErrInvalidAddress), true, "err %s", err) - err = ab.Save(0, addr1, onRamp100) - require.Error(t, err) - assert.Equal(t, errors.Is(err, ErrInvalidChainSelector), true) - // Duplicate - err = ab.Save(chainsel.TEST_90000001.Selector, addr1, onRamp100) - require.Error(t, err) - // Zero address - err = ab.Save(chainsel.TEST_90000001.Selector, common.HexToAddress("0x0").Hex(), onRamp100) + // Duplicate address will error + err = ab.Save(1, "0x1", "OnRamp 1.0.0") require.Error(t, err) - // Distinct address same TV will not - err = ab.Save(chainsel.TEST_90000001.Selector, addr2, onRamp100) + err = ab.Save(1, "0x2", "OnRamp 1.0.0") require.NoError(t, err) // Same address different chain will not error - err = ab.Save(chainsel.TEST_90000002.Selector, addr1, onRamp100) + err = ab.Save(2, "0x1", "OnRamp 1.0.0") require.NoError(t, err) // We can save different versions of the same contract - err = ab.Save(chainsel.TEST_90000002.Selector, addr2, onRamp110) + err = ab.Save(2, "0x2", "OnRamp 1.2.0") require.NoError(t, err) addresses, err := ab.Addresses() require.NoError(t, err) - assert.DeepEqual(t, addresses, map[uint64]map[string]TypeAndVersion{ - chainsel.TEST_90000001.Selector: { - addr1: onRamp100, - addr2: onRamp100, + assert.DeepEqual(t, addresses, map[uint64]map[string]string{ + 1: { + "0x1": "OnRamp 1.0.0", + "0x2": "OnRamp 1.0.0", }, - chainsel.TEST_90000002.Selector: { - addr1: onRamp100, - addr2: onRamp110, + 2: { + "0x1": "OnRamp 1.0.0", + "0x2": "OnRamp 1.2.0", }, }) -} -func TestAddressBook_Merge(t *testing.T) { - onRamp100 := NewTypeAndVersion("OnRamp", Version1_0_0) - onRamp110 := NewTypeAndVersion("OnRamp", Version1_1_0) - addr1 := common.HexToAddress("0x1").String() - addr2 := common.HexToAddress("0x2").String() - a1 := NewMemoryAddressBookFromMap(map[uint64]map[string]TypeAndVersion{ - chainsel.TEST_90000001.Selector: { - addr1: onRamp100, - }, - }) - a2 := NewMemoryAddressBookFromMap(map[uint64]map[string]TypeAndVersion{ - chainsel.TEST_90000001.Selector: { - addr2: onRamp100, - }, - chainsel.TEST_90000002.Selector: { - addr1: onRamp110, - }, - }) - require.NoError(t, a1.Merge(a2)) - - addresses, err := a1.Addresses() + // Test merge + ab2 := NewMemoryAddressBook() + require.NoError(t, ab2.Save(3, "0x3", "OnRamp 1.0.0")) + require.NoError(t, ab.Merge(ab2)) + // Other address book should remain unchanged. + addresses, err = ab2.Addresses() require.NoError(t, err) - assert.DeepEqual(t, addresses, map[uint64]map[string]TypeAndVersion{ - chainsel.TEST_90000001.Selector: { - addr1: onRamp100, - addr2: onRamp100, - }, - chainsel.TEST_90000002.Selector: { - addr1: onRamp110, + assert.DeepEqual(t, addresses, map[uint64]map[string]string{ + 3: { + "0x3": "OnRamp 1.0.0", }, }) - - // Merge with conflicting addresses should error - a3 := NewMemoryAddressBookFromMap(map[uint64]map[string]TypeAndVersion{ - chainsel.TEST_90000001.Selector: { - addr1: onRamp100, - }, - }) - require.Error(t, a1.Merge(a3)) - // a1 should not have changed - addresses, err = a1.Addresses() + // Existing addressbook should contain the new elements. + addresses, err = ab.Addresses() require.NoError(t, err) - assert.DeepEqual(t, addresses, map[uint64]map[string]TypeAndVersion{ - chainsel.TEST_90000001.Selector: { - addr1: onRamp100, - addr2: onRamp100, + assert.DeepEqual(t, addresses, map[uint64]map[string]string{ + 1: { + "0x1": "OnRamp 1.0.0", + "0x2": "OnRamp 1.0.0", }, - chainsel.TEST_90000002.Selector: { - addr1: onRamp110, + 2: { + "0x1": "OnRamp 1.0.0", + "0x2": "OnRamp 1.2.0", + }, + 3: { + "0x3": "OnRamp 1.0.0", }, }) + + // Merge to an existing chain. + require.NoError(t, ab2.Save(2, "0x3", "OffRamp 1.0.0")) } diff --git a/integration-tests/deployment/ccip/deploy.go b/integration-tests/deployment/ccip/deploy.go new file mode 100644 index 0000000000..ae3b00de65 --- /dev/null +++ b/integration-tests/deployment/ccip/deploy.go @@ -0,0 +1,561 @@ +package ccipdeployment + +import ( + "encoding/hex" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" + deployment2 "github.com/smartcontractkit/ccip/integration-tests/deployment" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" +) + +var ( + // 1.0 + ARMProxy_1_1_0 = "ARMProxy 1.0.0" + MockARM_1_0_0 = "MockARM 1.0.0" + LinkToken_1_0_0 = "LinkToken 1.0.0" + WETH9_1_0_0 = "WETH9 1.0.0" + MCMS_1_0_0 = "ManyChainMultiSig 1.0.0" + RBAC_Timelock_1_0_0 = "RBACTimelock 1.0.0" + CCIPReceiver_1_0_0 = "CCIPReceiver 1.0.0" + + // 1.2 + Router_1_2_0 = "Router 1.2.0" + // 1.5 + TokenAdminRegistry_1_5_0 = "TokenAdminRegistry 1.5.0-dev" + // 1.6 + CapabilitiesRegistry_1_0_0 = "CapabilitiesRegistry 1.0.0" + CCIPConfig_1_6_0 = "CCIPConfig 1.6.0-dev" + EVM2EVMMultiOnRamp_1_6_0 = "EVM2EVMMultiOnRamp 1.6.0-dev" + EVM2EVMMultiOffRamp_1_6_0 = "EVM2EVMMultiOffRamp 1.6.0-dev" + NonceManager_1_6_0 = "NonceManager 1.6.0-dev" + PriceRegistry_1_6_0 = "PriceRegistry 1.6.0-dev" +) + +type Contracts interface { + *capabilities_registry.CapabilitiesRegistry | + *arm_proxy_contract.ARMProxyContract | + *ccip_config.CCIPConfig | + *nonce_manager.NonceManager | + *price_registry.PriceRegistry | + *router.Router | + *token_admin_registry.TokenAdminRegistry | + *weth9.WETH9 | + *mock_arm_contract.MockARMContract | + *owner_helpers.ManyChainMultiSig | + *owner_helpers.RBACTimelock | + *evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp | + *evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp | + *burn_mint_erc677.BurnMintERC677 | + *maybe_revert_message_receiver.MaybeRevertMessageReceiver +} + +type ContractDeploy[C Contracts] struct { + // We just keep all the deploy return values + // since some will be empty if there's an error. + Address common.Address + Contract C + Tx *types.Transaction + TvStr string + Err error +} + +// TODO: pull up to general deployment pkg +func deployContract[C Contracts]( + lggr logger.Logger, + chain deployment.Chain, + addressBook deployment.AddressBook, + deploy func(chain deployment.Chain) ContractDeploy[C], +) (*ContractDeploy[C], error) { + contractDeploy := deploy(chain) + if contractDeploy.Err != nil { + lggr.Errorw("Failed to deploy contract", "err", contractDeploy.Err) + return nil, contractDeploy.Err + } + err := chain.Confirm(contractDeploy.Tx.Hash()) + if err != nil { + lggr.Errorw("Failed to confirm deployment", "err", err) + return nil, err + } + err = addressBook.Save(chain.Selector, contractDeploy.Address.String(), contractDeploy.TvStr) + if err != nil { + lggr.Errorw("Failed to save contract address", "err", err) + return nil, err + } + return &contractDeploy, nil +} + +type DeployCCIPContractConfig struct { + HomeChainSel uint64 + // Existing contracts which we want to skip deployment + // Leave empty if we want to deploy everything + // TODO: Add skips to deploy function. + CCIPOnChainState +} + +// TODO: Likely we'll want to further parameterize the deployment +// For example a list of contracts to skip deploying if they already exist. +// Or mock vs real RMN. +// Deployment produces an address book of everything it deployed. +func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) (deployment.AddressBook, error) { + ab := deployment.NewMemoryAddressBook() + nodes, err := deployment2.NodeInfo(e.NodeIDs, e.Offchain) + if err != nil { + e.Logger.Errorw("Failed to get node info", "err", err) + return ab, err + } + cr, err := c.CapabilityRegistry[c.HomeChainSel].GetHashedCapabilityId( + &bind.CallOpts{}, CapabilityLabelledName, CapabilityVersion) + if err != nil { + e.Logger.Errorw("Failed to get hashed capability id", "err", err) + return ab, err + } + // Signal to CR that our nodes support CCIP capability. + if err := AddNodes( + c.CapabilityRegistry[c.HomeChainSel], + e.Chains[c.HomeChainSel], + nodes.PeerIDs(c.HomeChainSel), // Doesn't actually matter which sel here + [][32]byte{cr}, + ); err != nil { + return ab, err + } + + for sel, chain := range e.Chains { + ccipReceiver, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver] { + receiverAddr, tx, receiver, err2 := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver( + chain.DeployerKey, + chain.Client, + false, + ) + return ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver]{ + receiverAddr, receiver, tx, CCIPReceiver_1_0_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy receiver", "err", err) + return ab, err + } + e.Logger.Infow("deployed receiver", "addr", ccipReceiver.Address) + + // TODO: Still waiting for RMNRemote/RMNHome contracts etc. + mockARM, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*mock_arm_contract.MockARMContract] { + mockARMAddr, tx, mockARM, err2 := mock_arm_contract.DeployMockARMContract( + chain.DeployerKey, + chain.Client, + ) + return ContractDeploy[*mock_arm_contract.MockARMContract]{ + mockARMAddr, mockARM, tx, MockARM_1_0_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy mockARM", "err", err) + return ab, err + } + e.Logger.Infow("deployed mockARM", "addr", mockARM) + + mcm, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*owner_helpers.ManyChainMultiSig] { + mcmAddr, tx, mcm, err2 := owner_helpers.DeployManyChainMultiSig( + chain.DeployerKey, + chain.Client, + ) + return ContractDeploy[*owner_helpers.ManyChainMultiSig]{ + mcmAddr, mcm, tx, MCMS_1_0_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy mcm", "err", err) + return ab, err + } + // TODO: Address soon + e.Logger.Infow("deployed mcm", "addr", mcm.Address) + + _, err = deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*owner_helpers.RBACTimelock] { + timelock, tx, cc, err2 := owner_helpers.DeployRBACTimelock( + chain.DeployerKey, + chain.Client, + big.NewInt(0), // minDelay + mcm.Address, + []common.Address{mcm.Address}, // proposers + []common.Address{chain.DeployerKey.From}, //executors + []common.Address{mcm.Address}, // cancellers + []common.Address{mcm.Address}, // bypassers + ) + return ContractDeploy[*owner_helpers.RBACTimelock]{ + timelock, cc, tx, RBAC_Timelock_1_0_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy timelock", "err", err) + return ab, err + } + e.Logger.Infow("deployed timelock", "addr", mcm.Address) + + armProxy, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*arm_proxy_contract.ARMProxyContract] { + armProxyAddr, tx, armProxy, err2 := arm_proxy_contract.DeployARMProxyContract( + chain.DeployerKey, + chain.Client, + mockARM.Address, + ) + return ContractDeploy[*arm_proxy_contract.ARMProxyContract]{ + armProxyAddr, armProxy, tx, ARMProxy_1_1_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy armProxy", "err", err) + return ab, err + } + e.Logger.Infow("deployed armProxy", "addr", armProxy.Address) + + weth9, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*weth9.WETH9] { + weth9Addr, tx, weth9c, err2 := weth9.DeployWETH9( + chain.DeployerKey, + chain.Client, + ) + return ContractDeploy[*weth9.WETH9]{ + weth9Addr, weth9c, tx, WETH9_1_0_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy weth9", "err", err) + return ab, err + } + + linkToken, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*burn_mint_erc677.BurnMintERC677] { + linkTokenAddr, tx, linkToken, err2 := burn_mint_erc677.DeployBurnMintERC677( + chain.DeployerKey, + chain.Client, + "Link Token", + "LINK", + uint8(18), + big.NewInt(0).Mul(big.NewInt(1e9), big.NewInt(1e18)), + ) + return ContractDeploy[*burn_mint_erc677.BurnMintERC677]{ + linkTokenAddr, linkToken, tx, LinkToken_1_0_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy linkToken", "err", err) + return ab, err + } + + routerContract, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*router.Router] { + routerAddr, tx, routerC, err2 := router.DeployRouter( + chain.DeployerKey, + chain.Client, + weth9.Address, + armProxy.Address, + ) + return ContractDeploy[*router.Router]{ + routerAddr, routerC, tx, Router_1_2_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy router", "err", err) + return ab, err + } + e.Logger.Infow("deployed router", "addr", routerContract) + + tokenAdminRegistry, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*token_admin_registry.TokenAdminRegistry] { + tokenAdminRegistryAddr, tx, tokenAdminRegistry, err2 := token_admin_registry.DeployTokenAdminRegistry( + chain.DeployerKey, + chain.Client) + return ContractDeploy[*token_admin_registry.TokenAdminRegistry]{ + tokenAdminRegistryAddr, tokenAdminRegistry, tx, TokenAdminRegistry_1_5_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy token admin registry", "err", err) + return ab, err + } + e.Logger.Infow("deployed tokenAdminRegistry", "addr", tokenAdminRegistry) + + nonceManager, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*nonce_manager.NonceManager] { + nonceManagerAddr, tx, nonceManager, err2 := nonce_manager.DeployNonceManager( + chain.DeployerKey, + chain.Client, + []common.Address{}, // Need to add onRamp after + ) + return ContractDeploy[*nonce_manager.NonceManager]{ + nonceManagerAddr, nonceManager, tx, NonceManager_1_6_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy router", "err", err) + return ab, err + } + + priceRegistry, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*price_registry.PriceRegistry] { + prAddr, tx, pr, err2 := price_registry.DeployPriceRegistry( + chain.DeployerKey, + chain.Client, + price_registry.PriceRegistryStaticConfig{ + MaxFeeJuelsPerMsg: big.NewInt(0).Mul(big.NewInt(2e2), big.NewInt(1e18)), + LinkToken: linkToken.Address, + StalenessThreshold: uint32(24 * 60 * 60), + }, + []common.Address{}, // ramps added after + []common.Address{weth9.Address, linkToken.Address}, // fee tokens + []price_registry.PriceRegistryTokenPriceFeedUpdate{}, + []price_registry.PriceRegistryTokenTransferFeeConfigArgs{}, // TODO: tokens + []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs{ + { + PremiumMultiplierWeiPerEth: 9e17, // 0.9 ETH + Token: linkToken.Address, + }, + { + PremiumMultiplierWeiPerEth: 1e18, + Token: weth9.Address, + }, + }, + []price_registry.PriceRegistryDestChainConfigArgs{}, + ) + return ContractDeploy[*price_registry.PriceRegistry]{ + prAddr, pr, tx, PriceRegistry_1_6_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy price registry", "err", err) + return ab, err + } + + onRamp, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp] { + onRampAddr, tx, onRamp, err2 := evm_2_evm_multi_onramp.DeployEVM2EVMMultiOnRamp( + chain.DeployerKey, + chain.Client, + evm_2_evm_multi_onramp.EVM2EVMMultiOnRampStaticConfig{ + ChainSelector: sel, + RmnProxy: armProxy.Address, + NonceManager: nonceManager.Address, + TokenAdminRegistry: tokenAdminRegistry.Address, + }, + evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDynamicConfig{ + PriceRegistry: priceRegistry.Address, + FeeAggregator: common.HexToAddress("0x1"), // TODO real fee aggregator + }, + []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs{}, + ) + return ContractDeploy[*evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp]{ + onRampAddr, onRamp, tx, EVM2EVMMultiOnRamp_1_6_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy onramp", "err", err) + return ab, err + } + e.Logger.Infow("deployed onramp", "addr", onRamp.Address) + + offRamp, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp] { + offRampAddr, tx, offRamp, err2 := evm_2_evm_multi_offramp.DeployEVM2EVMMultiOffRamp( + chain.DeployerKey, + chain.Client, + evm_2_evm_multi_offramp.EVM2EVMMultiOffRampStaticConfig{ + ChainSelector: sel, + RmnProxy: armProxy.Address, + NonceManager: nonceManager.Address, + TokenAdminRegistry: tokenAdminRegistry.Address, + }, + evm_2_evm_multi_offramp.EVM2EVMMultiOffRampDynamicConfig{ + PriceRegistry: priceRegistry.Address, + PermissionLessExecutionThresholdSeconds: uint32(86400), + MaxTokenTransferGas: uint32(200_000), + MaxPoolReleaseOrMintGas: uint32(200_000), + }, + []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{}, + ) + return ContractDeploy[*evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp]{ + offRampAddr, offRamp, tx, EVM2EVMMultiOffRamp_1_6_0, err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy offramp", "err", err) + return ab, err + } + e.Logger.Infow("deployed offramp", "addr", offRamp) + + // Enable ramps on price registry/nonce manager + tx, err := priceRegistry.Contract.ApplyAuthorizedCallerUpdates(chain.DeployerKey, price_registry.AuthorizedCallersAuthorizedCallerArgs{ + // TODO: We enable the deployer initially to set prices + AddedCallers: []common.Address{offRamp.Address, chain.DeployerKey.From}, + }) + if err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { + e.Logger.Errorw("Failed to confirm price registry authorized caller update", "err", err) + return ab, err + } + + tx, err = nonceManager.Contract.ApplyAuthorizedCallerUpdates(chain.DeployerKey, nonce_manager.AuthorizedCallersAuthorizedCallerArgs{ + AddedCallers: []common.Address{offRamp.Address, onRamp.Address}, + }) + if err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { + e.Logger.Errorw("Failed to update nonce manager with ramps", "err", err) + return ab, err + } + + // Add chain config for each chain. + _, err = AddChainConfig(e.Logger, + e.Chains[c.HomeChainSel], + c.CCIPOnChainState.CCIPConfig[c.HomeChainSel], + chain.Selector, + nodes.PeerIDs(chain.Selector), + uint8(len(nodes)/3)) + if err != nil { + return ab, err + } + + // For each chain, we create a DON on the home chain. + if err := AddDON(e.Logger, + cr, + c.CapabilityRegistry[c.HomeChainSel], + c.CCIPConfig[c.HomeChainSel], + offRamp.Contract, + chain, + e.Chains[c.HomeChainSel], + uint8(len(nodes)/3), + nodes.BootstrapPeerIDs(chain.Selector)[0], + nodes.PeerIDs(chain.Selector), + nodes, + ); err != nil { + e.Logger.Errorw("Failed to add DON", "err", err) + return ab, err + } + } + + return ab, nil +} + +func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) error { + // TODO: Batch + tx, err := state.Routers[from].ApplyRampUpdates(e.Chains[from].DeployerKey, []router.RouterOnRamp{ + { + DestChainSelector: to, + OnRamp: state.EvmOnRampsV160[from].Address(), + }, + }, []router.RouterOffRamp{}, []router.RouterOffRamp{}) + if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { + return err + } + tx, err = state.EvmOnRampsV160[from].ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, + []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs{ + { + DestChainSelector: to, + Router: state.Routers[from].Address(), + }, + }) + if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { + return err + } + + _, err = state.PriceRegistries[from].UpdatePrices( + e.Chains[from].DeployerKey, price_registry.InternalPriceUpdates{ + TokenPriceUpdates: []price_registry.InternalTokenPriceUpdate{ + { + SourceToken: state.LinkTokens[from].Address(), + UsdPerToken: deployment2.E18Mult(20), + }, + { + SourceToken: state.Weth9s[from].Address(), + UsdPerToken: deployment2.E18Mult(4000), + }, + }, + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: to, + UsdPerUnitGas: big.NewInt(2e12), + }, + }}) + if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { + return err + } + + // Enable dest in price registry + tx, err = state.PriceRegistries[from].ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, + []price_registry.PriceRegistryDestChainConfigArgs{ + { + DestChainSelector: to, + DestChainConfig: defaultPriceRegistryDestChainConfig(), + }, + }) + if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { + return err + } + + tx, err = state.EvmOffRampsV160[to].ApplySourceChainConfigUpdates(e.Chains[to].DeployerKey, + []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{ + { + Router: state.Routers[to].Address(), + SourceChainSelector: from, + IsEnabled: true, + OnRamp: common.LeftPadBytes(state.EvmOnRampsV160[from].Address().Bytes(), 32), + }, + }) + if err := deployment.ConfirmIfNoError(e.Chains[to], tx, err); err != nil { + return err + } + tx, err = state.Routers[to].ApplyRampUpdates(e.Chains[to].DeployerKey, []router.RouterOnRamp{}, []router.RouterOffRamp{}, []router.RouterOffRamp{ + { + SourceChainSelector: from, + OffRamp: state.EvmOffRampsV160[to].Address(), + }, + }) + return deployment.ConfirmIfNoError(e.Chains[to], tx, err) +} + +func defaultPriceRegistryDestChainConfig() price_registry.PriceRegistryDestChainConfig { + // https://github.com/smartcontractkit/ccip/blob/c4856b64bd766f1ddbaf5d13b42d3c4b12efde3a/contracts/src/v0.8/ccip/libraries/Internal.sol#L337-L337 + /* + ```Solidity + // bytes4(keccak256("CCIP ChainFamilySelector EVM")) + bytes4 public constant CHAIN_FAMILY_SELECTOR_EVM = 0x2812d52c; + ``` + */ + evmFamilySelector, _ := hex.DecodeString("2812d52c") + return price_registry.PriceRegistryDestChainConfig{ + IsEnabled: true, + MaxNumberOfTokensPerMsg: 10, + MaxDataBytes: 256, + MaxPerMsgGasLimit: 3_000_000, + DestGasOverhead: 50_000, + DefaultTokenFeeUSDCents: 1, + DestGasPerPayloadByte: 10, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 100, + DestDataAvailabilityMultiplierBps: 1, + DefaultTokenDestGasOverhead: 125_000, + DefaultTokenDestBytesOverhead: 32, + DefaultTxGasLimit: 200_000, + GasMultiplierWeiPerEth: 1, + NetworkFeeUSDCents: 1, + ChainFamilySelector: [4]byte(evmFamilySelector), + } +} diff --git a/integration-tests/deployment/ccip/deploy_home_chain.go b/integration-tests/deployment/ccip/deploy_home_chain.go new file mode 100644 index 0000000000..ad76dbf892 --- /dev/null +++ b/integration-tests/deployment/ccip/deploy_home_chain.go @@ -0,0 +1,410 @@ +package ccipdeployment + +import ( + "bytes" + "context" + "errors" + "sort" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + + deployment2 "github.com/smartcontractkit/ccip/integration-tests/deployment" + + "github.com/smartcontractkit/chainlink-ccip/chainconfig" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ocr3_config_encoder" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" +) + +const ( + NodeOperatorID = 1 + CapabilityLabelledName = "ccip" + CapabilityVersion = "v1.0.0" + + FirstBlockAge = 8 * time.Hour + RemoteGasPriceBatchWriteFrequency = 30 * time.Minute + BatchGasLimit = 6_500_000 + RelativeBoostPerWaitHour = 1.5 + InflightCacheExpiry = 10 * time.Minute + RootSnoozeTime = 30 * time.Minute + BatchingStrategyID = 0 + DeltaProgress = 30 * time.Second + DeltaResend = 10 * time.Second + DeltaInitial = 20 * time.Second + DeltaRound = 2 * time.Second + DeltaGrace = 2 * time.Second + DeltaCertifiedCommitRequest = 10 * time.Second + DeltaStage = 10 * time.Second + Rmax = 3 + MaxDurationQuery = 50 * time.Millisecond + MaxDurationObservation = 5 * time.Second + MaxDurationShouldAcceptAttestedReport = 10 * time.Second + MaxDurationShouldTransmitAcceptedReport = 10 * time.Second +) + +func DeployCapReg(lggr logger.Logger, chains map[uint64]deployment.Chain, chainSel uint64) (deployment.AddressBook, error) { + ab := deployment.NewMemoryAddressBook() + chain := chains[chainSel] + capReg, err := deployContract(lggr, chain, ab, + func(chain deployment.Chain) ContractDeploy[*capabilities_registry.CapabilitiesRegistry] { + crAddr, tx, cr, err2 := capabilities_registry.DeployCapabilitiesRegistry( + chain.DeployerKey, + chain.Client, + ) + return ContractDeploy[*capabilities_registry.CapabilitiesRegistry]{ + Address: crAddr, Contract: cr, TvStr: CapabilitiesRegistry_1_0_0, Tx: tx, Err: err2, + } + }) + if err != nil { + lggr.Errorw("Failed to deploy capreg", "err", err) + return ab, err + } + lggr.Infow("deployed capreg", "addr", capReg.Address) + ccipConfig, err := deployContract( + lggr, chain, ab, + func(chain deployment.Chain) ContractDeploy[*ccip_config.CCIPConfig] { + ccAddr, tx, cc, err2 := ccip_config.DeployCCIPConfig( + chain.DeployerKey, + chain.Client, + capReg.Address, + ) + return ContractDeploy[*ccip_config.CCIPConfig]{ + Address: ccAddr, TvStr: CCIPConfig_1_6_0, Tx: tx, Err: err2, Contract: cc, + } + }) + if err != nil { + lggr.Errorw("Failed to deploy ccip config", "err", err) + return ab, err + } + lggr.Infow("deployed ccip config", "addr", ccipConfig.Address) + + tx, err := capReg.Contract.AddCapabilities(chain.DeployerKey, []capabilities_registry.CapabilitiesRegistryCapability{ + { + LabelledName: CapabilityLabelledName, + Version: CapabilityVersion, + CapabilityType: 2, // consensus. not used (?) + ResponseType: 0, // report. not used (?) + ConfigurationContract: ccipConfig.Address, + }, + }) + if err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { + lggr.Errorw("Failed to add capabilities", "err", err) + return ab, err + } + // TODO: Just one for testing. + tx, err = capReg.Contract.AddNodeOperators(chain.DeployerKey, []capabilities_registry.CapabilitiesRegistryNodeOperator{ + { + Admin: chain.DeployerKey.From, + Name: "NodeOperator", + }, + }) + if err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { + lggr.Errorw("Failed to add node operators", "err", err) + return ab, err + } + return ab, nil +} + +func sortP2PIDS(p2pIDs [][32]byte) { + sort.Slice(p2pIDs, func(i, j int) bool { + return bytes.Compare(p2pIDs[i][:], p2pIDs[j][:]) < 0 + }) +} + +func AddNodes( + capReg *capabilities_registry.CapabilitiesRegistry, + chain deployment.Chain, + p2pIDs [][32]byte, + capabilityIDs [][32]byte, +) error { + // Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail + sortP2PIDS(p2pIDs) + var nodeParams []capabilities_registry.CapabilitiesRegistryNodeParams + for _, p2pID := range p2pIDs { + nodeParam := capabilities_registry.CapabilitiesRegistryNodeParams{ + NodeOperatorId: NodeOperatorID, + Signer: p2pID, // Not used in tests + P2pId: p2pID, + HashedCapabilityIds: capabilityIDs, + } + nodeParams = append(nodeParams, nodeParam) + } + tx, err := capReg.AddNodes(chain.DeployerKey, nodeParams) + if err != nil { + return err + } + return chain.Confirm(tx.Hash()) +} + +func SetupConfigInfo(chainSelector uint64, readers [][32]byte, fChain uint8, cfg []byte) ccip_config.CCIPConfigTypesChainConfigInfo { + return ccip_config.CCIPConfigTypesChainConfigInfo{ + ChainSelector: chainSelector, + ChainConfig: ccip_config.CCIPConfigTypesChainConfig{ + Readers: readers, + FChain: fChain, + Config: cfg, + }, + } +} + +func AddChainConfig( + lggr logger.Logger, + h deployment.Chain, + ccipConfig *ccip_config.CCIPConfig, + chainSelector uint64, + p2pIDs [][32]byte, + f uint8, +) (ccip_config.CCIPConfigTypesChainConfigInfo, error) { + // Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail + sortP2PIDS(p2pIDs) + // First Add ChainConfig that includes all p2pIDs as readers + encodedExtraChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ + GasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(1000), + DAGasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(0), + FinalityDepth: 10, + OptimisticConfirmations: 1, + }) + if err != nil { + return ccip_config.CCIPConfigTypesChainConfigInfo{}, err + } + chainConfig := SetupConfigInfo(chainSelector, p2pIDs, f, encodedExtraChainConfig) + inputConfig := []ccip_config.CCIPConfigTypesChainConfigInfo{ + chainConfig, + } + tx, err := ccipConfig.ApplyChainConfigUpdates(h.DeployerKey, nil, inputConfig) + if err != nil { + return ccip_config.CCIPConfigTypesChainConfigInfo{}, err + } + if err := h.Confirm(tx.Hash()); err != nil { + return ccip_config.CCIPConfigTypesChainConfigInfo{}, err + } + return chainConfig, nil +} + +func AddDON( + lggr logger.Logger, + ccipCapabilityID [32]byte, + capReg *capabilities_registry.CapabilitiesRegistry, + ccipConfig *ccip_config.CCIPConfig, + offRamp *evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp, + dest deployment.Chain, + home deployment.Chain, + f uint8, + bootstrapP2PID [32]byte, + p2pIDs [][32]byte, + nodes []deployment2.Node, +) error { + sortP2PIDS(p2pIDs) + // Get OCR3 Config from helper + var schedule []int + var oracles []confighelper2.OracleIdentityExtra + for _, node := range nodes { + schedule = append(schedule, 1) + cfg := node.SelToOCRConfig[dest.Selector] + oracles = append(oracles, confighelper2.OracleIdentityExtra{ + OracleIdentity: confighelper2.OracleIdentity{ + OnchainPublicKey: cfg.OnchainPublicKey, + TransmitAccount: cfg.TransmitAccount, + OffchainPublicKey: cfg.OffchainPublicKey, + PeerID: cfg.PeerID.String()[4:], + }, ConfigEncryptionPublicKey: cfg.ConfigEncryptionPublicKey, + }) + } + + tabi, err := ocr3_config_encoder.IOCR3ConfigEncoderMetaData.GetAbi() + if err != nil { + return err + } + + // Add DON on capability registry contract + var ocr3Configs []ocr3_config_encoder.CCIPConfigTypesOCR3Config + for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { + var encodedOffchainConfig []byte + var err2 error + if pluginType == cctypes.PluginTypeCCIPCommit { + encodedOffchainConfig, err2 = pluginconfig.EncodeCommitOffchainConfig(pluginconfig.CommitOffchainConfig{ + RemoteGasPriceBatchWriteFrequency: *commonconfig.MustNewDuration(RemoteGasPriceBatchWriteFrequency), + // TODO: implement token price writes + // TokenPriceBatchWriteFrequency: *commonconfig.MustNewDuration(tokenPriceBatchWriteFrequency), + }) + } else { + encodedOffchainConfig, err2 = pluginconfig.EncodeExecuteOffchainConfig(pluginconfig.ExecuteOffchainConfig{ + BatchGasLimit: BatchGasLimit, + RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, + MessageVisibilityInterval: *commonconfig.MustNewDuration(FirstBlockAge), + InflightCacheExpiry: *commonconfig.MustNewDuration(InflightCacheExpiry), + RootSnoozeTime: *commonconfig.MustNewDuration(RootSnoozeTime), + BatchingStrategyID: BatchingStrategyID, + }) + } + if err2 != nil { + return err2 + } + signers, transmitters, configF, _, offchainConfigVersion, offchainConfig, err2 := ocr3confighelper.ContractSetConfigArgsForTests( + DeltaProgress, + DeltaResend, + DeltaInitial, + DeltaRound, + DeltaGrace, + DeltaCertifiedCommitRequest, + DeltaStage, + Rmax, + schedule, + oracles, + encodedOffchainConfig, + MaxDurationQuery, + MaxDurationObservation, + MaxDurationShouldAcceptAttestedReport, + MaxDurationShouldTransmitAcceptedReport, + int(f), + []byte{}, // empty OnChainConfig + ) + if err2 != nil { + return err2 + } + + signersBytes := make([][]byte, len(signers)) + for i, signer := range signers { + signersBytes[i] = signer + } + + transmittersBytes := make([][]byte, len(transmitters)) + for i, transmitter := range transmitters { + parsed, err2 := common.ParseHexOrString(string(transmitter)) + if err != nil { + return err2 + } + transmittersBytes[i] = parsed + } + + ocr3Configs = append(ocr3Configs, ocr3_config_encoder.CCIPConfigTypesOCR3Config{ + PluginType: uint8(pluginType), + ChainSelector: dest.Selector, + F: configF, + OffchainConfigVersion: offchainConfigVersion, + OfframpAddress: offRamp.Address().Bytes(), + BootstrapP2PIds: [][32]byte{bootstrapP2PID}, + P2pIds: p2pIDs, + Signers: signersBytes, + Transmitters: transmittersBytes, + OffchainConfig: offchainConfig, + }) + } + + encodedCall, err := tabi.Pack("exposeOCR3Config", ocr3Configs) + if err != nil { + return err + } + + // Trim first four bytes to remove function selector. + encodedConfigs := encodedCall[4:] + + // commit so that we have an empty block to filter events from + // TODO: required? + //h.backend.Commit() + + tx, err := capReg.AddDON(home.DeployerKey, p2pIDs, []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: ccipCapabilityID, + Config: encodedConfigs, + }, + }, false, false, f) + if err := deployment.ConfirmIfNoError(home, tx, err); err != nil { + return err + } + + latestBlock, err := home.Client.HeaderByNumber(context.Background(), nil) + if err != nil { + return err + } + endBlock := latestBlock.Number.Uint64() + iter, err := capReg.FilterConfigSet(&bind.FilterOpts{ + Start: endBlock - 1, + End: &endBlock, + }) + if err != nil { + return err + } + var donID uint32 + for iter.Next() { + donID = iter.Event.DonId + break + } + if donID == 0 { + return errors.New("failed to get donID") + } + + var signerAddresses []common.Address + for _, oracle := range oracles { + signerAddresses = append(signerAddresses, common.BytesToAddress(oracle.OnchainPublicKey)) + } + + var transmitterAddresses []common.Address + for _, oracle := range oracles { + transmitterAddresses = append(transmitterAddresses, common.HexToAddress(string(oracle.TransmitAccount))) + } + + // get the config digest from the ccip config contract and set config on the offramp. + var offrampOCR3Configs []evm_2_evm_multi_offramp.MultiOCR3BaseOCRConfigArgs + for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { + ocrConfig, err2 := ccipConfig.GetOCRConfig(&bind.CallOpts{ + Context: context.Background(), + }, donID, uint8(pluginType)) + if err2 != nil { + return err2 + } + if len(ocrConfig) != 1 { + return errors.New("expected exactly one OCR3 config") + } + + offrampOCR3Configs = append(offrampOCR3Configs, evm_2_evm_multi_offramp.MultiOCR3BaseOCRConfigArgs{ + ConfigDigest: ocrConfig[0].ConfigDigest, + OcrPluginType: uint8(pluginType), + F: f, + IsSignatureVerificationEnabled: pluginType == cctypes.PluginTypeCCIPCommit, + Signers: signerAddresses, + Transmitters: transmitterAddresses, + }) + } + + //uni.backend.Commit() + + tx, err = offRamp.SetOCR3Configs(dest.DeployerKey, offrampOCR3Configs) + if err := deployment.ConfirmIfNoError(dest, tx, err); err != nil { + return err + } + + for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { + _, err = offRamp.LatestConfigDetails(&bind.CallOpts{ + Context: context.Background(), + }, uint8(pluginType)) + if err != nil { + //return err + return deployment.MaybeDataErr(err) + } + // TODO: assertions + //require.Equalf(t, offrampOCR3Configs[pluginType].ConfigDigest, ocrConfig.ConfigInfo.ConfigDigest, "%s OCR3 config digest mismatch", pluginType.String()) + //require.Equalf(t, offrampOCR3Configs[pluginType].F, ocrConfig.ConfigInfo.F, "%s OCR3 config F mismatch", pluginType.String()) + //require.Equalf(t, offrampOCR3Configs[pluginType].IsSignatureVerificationEnabled, ocrConfig.ConfigInfo.IsSignatureVerificationEnabled, "%s OCR3 config signature verification mismatch", pluginType.String()) + //if pluginType == cctypes.PluginTypeCCIPCommit { + // // only commit will set signers, exec doesn't need them. + // require.Equalf(t, offrampOCR3Configs[pluginType].Signers, ocrConfig.Signers, "%s OCR3 config signers mismatch", pluginType.String()) + //} + //require.Equalf(t, offrampOCR3Configs[pluginType].TransmittersByEVMChainID, ocrConfig.TransmittersByEVMChainID, "%s OCR3 config transmitters mismatch", pluginType.String()) + } + + lggr.Infof("set ocr3 config on the offramp, signers: %+v, transmitters: %+v", signerAddresses, transmitterAddresses) + return nil +} diff --git a/integration-tests/deployment/ccip/deploy_test.go b/integration-tests/deployment/ccip/deploy_test.go new file mode 100644 index 0000000000..ed2378cef3 --- /dev/null +++ b/integration-tests/deployment/ccip/deploy_test.go @@ -0,0 +1,49 @@ +package ccipdeployment + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestDeployCCIPContracts(t *testing.T) { + lggr := logger.TestLogger(t) + e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Chains: 1, + Nodes: 1, + }) + // Deploy all the CCIP contracts. + ab, err := DeployCCIPContracts(e, DeployCCIPContractConfig{}) + require.NoError(t, err) + state, err := GenerateOnchainState(e, ab) + require.NoError(t, err) + snap, err := state.Snapshot(e.AllChainSelectors()) + require.NoError(t, err) + + // Assert expect every deployed address to be in the address book. + // TODO: Add the rest of CCIPv2 representation + b, err := json.MarshalIndent(snap, "", " ") + require.NoError(t, err) + fmt.Println(string(b)) +} + +func TestJobSpecGeneration(t *testing.T) { + lggr := logger.TestLogger(t) + e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Chains: 1, + Nodes: 1, + }) + js, err := NewCCIPJobSpecs(e.NodeIDs, e.Offchain) + require.NoError(t, err) + for node, jb := range js { + fmt.Println(node, jb) + } + // TODO: Add job assertions +} diff --git a/integration-tests/deployment/ccip/jobs.go b/integration-tests/deployment/ccip/jobs.go new file mode 100644 index 0000000000..f45fe4c553 --- /dev/null +++ b/integration-tests/deployment/ccip/jobs.go @@ -0,0 +1,70 @@ +package ccipdeployment + +import ( + "context" + "fmt" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" +) + +// In our case, the only address needed is the cap registry which is actually an env var. +// and will pre-exist for our deployment. So the job specs only depend on the environment operators. +func NewCCIPJobSpecs(nodeIds []string, oc deployment.OffchainClient) (map[string][]string, error) { + // Generate a set of brand new job specs for CCIP for a specific environment + // (including NOPs) and new addresses. + // We want to assign one CCIP capability job to each node. And node with + // an addr we'll list as bootstrapper. + // Find the bootstrap nodes + bootstrapMp := make(map[string]struct{}) + for _, node := range nodeIds { + // TODO: Filter should accept multiple nodes + nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ + NodeId: node, + }}) + if err != nil { + return nil, err + } + for _, chainConfig := range nodeChainConfigs.ChainConfigs { + if chainConfig.Ocr2Config.IsBootstrap { + bootstrapMp[fmt.Sprintf("%s@%s", + // p2p_12D3... -> 12D3... + chainConfig.Ocr2Config.P2PKeyBundle.PeerId[4:], chainConfig.Ocr2Config.Multiaddr)] = struct{}{} + } + } + } + var bootstraps []string + for b := range bootstrapMp { + bootstraps = append(bootstraps, b) + } + nodesToJobSpecs := make(map[string][]string) + for _, node := range nodeIds { + // TODO: Filter should accept multiple. + nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ + NodeId: node, + }}) + if err != nil { + return nil, err + } + spec, err := validate.NewCCIPSpecToml(validate.SpecArgs{ + P2PV2Bootstrappers: bootstraps, + CapabilityVersion: CapabilityVersion, + CapabilityLabelledName: CapabilityLabelledName, + OCRKeyBundleIDs: map[string]string{ + // TODO: Validate that that all EVM chains are using the same keybundle. + relay.NetworkEVM: nodeChainConfigs.ChainConfigs[0].Ocr2Config.OcrKeyBundle.BundleId, + }, + // TODO: validate that all EVM chains are using the same keybundle + P2PKeyID: nodeChainConfigs.ChainConfigs[0].Ocr2Config.P2PKeyBundle.PeerId, + RelayConfigs: nil, + PluginConfig: map[string]any{}, + }) + if err != nil { + return nil, err + } + nodesToJobSpecs[node] = append(nodesToJobSpecs[node], spec) + } + return nodesToJobSpecs, nil +} diff --git a/integration-tests/deployment/ccip/migrations/1_initial_deploy.go b/integration-tests/deployment/ccip/migrations/1_initial_deploy.go new file mode 100644 index 0000000000..e92d7c0e8b --- /dev/null +++ b/integration-tests/deployment/ccip/migrations/1_initial_deploy.go @@ -0,0 +1,34 @@ +package migrations + +import ( + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + + ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" +) + +// We expect the migration input to be unique per migration. +// TODO: Maybe there's a generics approach here? +// Note if the migration is a deployment and it fails we have 2 options: +// - Just throw away the addresses, fix issue and try again (potentially expensive on mainnet) +// - Roll forward with another migration completing the deployment +func Apply0001(env deployment.Environment, c ccipdeployment.DeployCCIPContractConfig) (deployment.MigrationOutput, error) { + ab, err := ccipdeployment.DeployCCIPContracts(env, c) + if err != nil { + env.Logger.Errorw("Failed to deploy CCIP contracts", "err", err, "addresses", ab) + return deployment.MigrationOutput{}, err + } + js, err := ccipdeployment.NewCCIPJobSpecs(env.NodeIDs, env.Offchain) + if err != nil { + return deployment.MigrationOutput{}, err + } + proposal, err := ccipdeployment.GenerateAcceptOwnershipProposal(env, env.AllChainSelectors(), ab) + if err != nil { + return deployment.MigrationOutput{}, err + } + return deployment.MigrationOutput{ + Proposals: []deployment.Proposal{proposal}, + AddressBook: ab, + // Mapping of which nodes get which jobs. + JobSpecs: js, + }, nil +} diff --git a/integration-tests/deployment/ccip/migrations/1_initial_deploy_test.go b/integration-tests/deployment/ccip/migrations/1_initial_deploy_test.go new file mode 100644 index 0000000000..aa8f244481 --- /dev/null +++ b/integration-tests/deployment/ccip/migrations/1_initial_deploy_test.go @@ -0,0 +1,295 @@ +package migrations + +import ( + "context" + "math/big" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + + ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +// Context returns a context with the test's deadline, if available. +func Context(tb testing.TB) context.Context { + ctx := context.Background() + var cancel func() + switch t := tb.(type) { + case *testing.T: + if d, ok := t.Deadline(); ok { + ctx, cancel = context.WithDeadline(ctx, d) + } + } + if cancel == nil { + ctx, cancel = context.WithCancel(ctx) + } + tb.Cleanup(cancel) + return ctx +} + +func Test0001_InitialDeploy(t *testing.T) { + lggr := logger.TestLogger(t) + ctx := Context(t) + chains := memory.NewMemoryChains(t, 3) + homeChainSel := uint64(0) + homeChainEVM := uint64(0) + // First chain is home chain. + for chainSel := range chains { + homeChainEVM, _ = chainsel.ChainIdFromSelector(chainSel) + homeChainSel = chainSel + break + } + ab, err := ccipdeployment.DeployCapReg(lggr, chains, homeChainSel) + require.NoError(t, err) + + addrs, err := ab.AddressesForChain(homeChainSel) + require.NoError(t, err) + require.Len(t, addrs, 2) + capReg := common.Address{} + for addr := range addrs { + capReg = common.HexToAddress(addr) + break + } + nodes := memory.NewNodes(t, zapcore.InfoLevel, chains, 4, 1, memory.RegistryConfig{ + EVMChainID: homeChainEVM, + Contract: capReg, + }) + for _, node := range nodes { + require.NoError(t, node.App.Start(ctx)) + } + + e := memory.NewMemoryEnvironmentFromChainsNodes(t, lggr, chains, nodes) + state, err := ccipdeployment.GenerateOnchainState(e, ab) + require.NoError(t, err) + + capabilities, err := state.CapabilityRegistry[homeChainSel].GetCapabilities(nil) + require.NoError(t, err) + require.Len(t, capabilities, 1) + ccipCap, err := state.CapabilityRegistry[homeChainSel].GetHashedCapabilityId(nil, + ccipdeployment.CapabilityLabelledName, ccipdeployment.CapabilityVersion) + require.NoError(t, err) + _, err = state.CapabilityRegistry[homeChainSel].GetCapability(nil, ccipCap) + require.NoError(t, err) + + // Apply migration + output, err := Apply0001(e, ccipdeployment.DeployCCIPContractConfig{ + HomeChainSel: homeChainSel, + // Capreg/config already exist. + CCIPOnChainState: state, + }) + require.NoError(t, err) + // Get new state after migration. + state, err = ccipdeployment.GenerateOnchainState(e, output.AddressBook) + require.NoError(t, err) + + // Ensure capreg logs are up to date. + require.NoError(t, ReplayAllLogs(nodes, chains)) + + // Apply the jobs. + for nodeID, jobs := range output.JobSpecs { + for _, job := range jobs { + // Note these auto-accept + _, err := e.Offchain.ProposeJob(ctx, + &jobv1.ProposeJobRequest{ + NodeId: nodeID, + Spec: job, + }) + require.NoError(t, err) + } + } + // Wait for plugins to register filters? + // TODO: Investigate how to avoid. + time.Sleep(30 * time.Second) + + // Ensure job related logs are up to date. + require.NoError(t, ReplayAllLogs(nodes, chains)) + + // Send a request from every router + // Add all lanes + for source := range e.Chains { + for dest := range e.Chains { + if source != dest { + require.NoError(t, ccipdeployment.AddLane(e, state, source, dest)) + } + } + } + + // Send a message from each chain to every other chain. + for src, srcChain := range e.Chains { + for dest := range e.Chains { + if src == dest { + continue + } + msg := router.ClientEVM2AnyMessage{ + Receiver: common.LeftPadBytes(state.Receivers[dest].Address().Bytes(), 32), + Data: []byte("hello"), + TokenAmounts: nil, // TODO: no tokens for now + FeeToken: state.Weth9s[src].Address(), + ExtraArgs: nil, // TODO: no extra args for now, falls back to default + } + fee, err := state.Routers[src].GetFee( + &bind.CallOpts{Context: context.Background()}, dest, msg) + require.NoError(t, err, deployment.MaybeDataErr(err)) + tx, err := state.Weth9s[src].Deposit(&bind.TransactOpts{ + From: e.Chains[src].DeployerKey.From, + Signer: e.Chains[src].DeployerKey.Signer, + Value: fee, + }) + require.NoError(t, err) + require.NoError(t, srcChain.Confirm(tx.Hash())) + + // TODO: should be able to avoid this by using native? + tx, err = state.Weth9s[src].Approve(e.Chains[src].DeployerKey, + state.Routers[src].Address(), fee) + require.NoError(t, err) + require.NoError(t, srcChain.Confirm(tx.Hash())) + + t.Logf("Sending CCIP request from chain selector %d to chain selector %d", + src, dest) + tx, err = state.Routers[src].CcipSend(e.Chains[src].DeployerKey, dest, msg) + require.NoError(t, err) + require.NoError(t, srcChain.Confirm(tx.Hash())) + } + } + + // Wait for all commit reports to land. + var wg sync.WaitGroup + for src, srcChain := range e.Chains { + for dest, dstChain := range e.Chains { + if src == dest { + continue + } + srcChain := srcChain + dstChain := dstChain + wg.Add(1) + go func(src, dest uint64) { + defer wg.Done() + waitForCommitWithInterval(t, srcChain, dstChain, state.EvmOffRampsV160[dest], ccipocr3.SeqNumRange{1, 1}) + }(src, dest) + } + } + wg.Wait() + + // Wait for all exec reports to land + for src, srcChain := range e.Chains { + for dest, dstChain := range e.Chains { + if src == dest { + continue + } + srcChain := srcChain + dstChain := dstChain + wg.Add(1) + go func(src, dest uint64) { + defer wg.Done() + waitForExecWithSeqNr(t, srcChain, dstChain, state.EvmOffRampsV160[dest], 1) + }(src, dest) + } + } + wg.Wait() + + // TODO: Apply the proposal. +} + +func ReplayAllLogs(nodes map[string]memory.Node, chains map[uint64]deployment.Chain) error { + for _, node := range nodes { + for sel := range chains { + chainID, _ := chainsel.ChainIdFromSelector(sel) + if err := node.App.ReplayFromBlock(big.NewInt(int64(chainID)), 1, false); err != nil { + return err + } + } + } + return nil +} + +func waitForCommitWithInterval( + t *testing.T, + src deployment.Chain, + dest deployment.Chain, + offRamp *evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp, + expectedSeqNumRange ccipocr3.SeqNumRange, +) { + sink := make(chan *evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReportAccepted) + subscription, err := offRamp.WatchCommitReportAccepted(&bind.WatchOpts{ + Context: context.Background(), + }, sink) + require.NoError(t, err) + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + + //revive:disable + for { + select { + case <-ticker.C: + src.Client.(*backends.SimulatedBackend).Commit() + dest.Client.(*backends.SimulatedBackend).Commit() + t.Logf("Waiting for commit report on chain selector %d from source selector %d expected seq nr range %s", + dest.Selector, src.Selector, expectedSeqNumRange.String()) + case subErr := <-subscription.Err(): + t.Fatalf("Subscription error: %+v", subErr) + case report := <-sink: + if len(report.Report.MerkleRoots) > 0 { + // Check the interval of sequence numbers and make sure it matches + // the expected range. + for _, mr := range report.Report.MerkleRoots { + if mr.SourceChainSelector == src.Selector && + uint64(expectedSeqNumRange.Start()) == mr.Interval.Min && + uint64(expectedSeqNumRange.End()) == mr.Interval.Max { + t.Logf("Received commit report on selector %d from source selector %d expected seq nr range %s", + dest.Selector, src.Selector, expectedSeqNumRange.String()) + return + } + } + } + } + } +} + +func waitForExecWithSeqNr(t *testing.T, + source, dest deployment.Chain, + offramp *evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp, + expectedSeqNr uint64) { + tick := time.NewTicker(5 * time.Second) + defer tick.Stop() + for range tick.C { + // TODO: Clean this up + source.Client.(*backends.SimulatedBackend).Commit() + dest.Client.(*backends.SimulatedBackend).Commit() + scc, err := offramp.GetSourceChainConfig(nil, source.Selector) + require.NoError(t, err) + t.Logf("Waiting for ExecutionStateChanged on chain %d from chain %d with expected sequence number %d, current onchain minSeqNr: %d", + dest.Selector, source.Selector, expectedSeqNr, scc.MinSeqNr) + iter, err := offramp.FilterExecutionStateChanged(nil, + []uint64{source.Selector}, []uint64{expectedSeqNr}, nil) + require.NoError(t, err) + var count int + for iter.Next() { + if iter.Event.SequenceNumber == expectedSeqNr && iter.Event.SourceChainSelector == source.Selector { + count++ + } + } + if count == 1 { + t.Logf("Received ExecutionStateChanged on chain %d from chain %d with expected sequence number %d", + dest.Selector, source.Selector, expectedSeqNr) + return + } + } +} diff --git a/integration-tests/deployment/ccip/propose.go b/integration-tests/deployment/ccip/propose.go new file mode 100644 index 0000000000..0dc42acc87 --- /dev/null +++ b/integration-tests/deployment/ccip/propose.go @@ -0,0 +1,64 @@ +package ccipdeployment + +import ( + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" + chainsel "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" +) + +// TODO: Pull up to deploy +func SimTransactOpts() *bind.TransactOpts { + return &bind.TransactOpts{Signer: func(address common.Address, transaction *types.Transaction) (*types.Transaction, error) { + return transaction, nil + }, From: common.HexToAddress("0x0"), NoSend: true, GasLimit: 200_000} +} + +func GenerateAcceptOwnershipProposal( + e deployment.Environment, + chains []uint64, + ab deployment.AddressBook, +) (deployment.Proposal, error) { + state, err := GenerateOnchainState(e, ab) + if err != nil { + return deployment.Proposal{}, err + } + // TODO: Just onramp as an example + var ops []owner_helpers.ManyChainMultiSigOp + for _, sel := range chains { + opCount, err := state.Mcms[sel].GetOpCount(nil) + if err != nil { + return deployment.Proposal{}, err + } + + txData, err := state.EvmOnRampsV160[sel].AcceptOwnership(SimTransactOpts()) + if err != nil { + return deployment.Proposal{}, err + } + evmID, err := chainsel.ChainIdFromSelector(sel) + if err != nil { + return deployment.Proposal{}, err + } + ops = append(ops, owner_helpers.ManyChainMultiSigOp{ + ChainId: big.NewInt(int64(evmID)), + MultiSig: state.McmsAddrs[sel], + Nonce: opCount, + To: state.EvmOnRampsV160[sel].Address(), + Value: big.NewInt(0), + Data: txData.Data(), + }) + } + // TODO: Real valid until. + return deployment.Proposal{ValidUntil: uint32(time.Now().Unix()), Ops: ops}, nil +} + +func ApplyProposal(env deployment.Environment, p deployment.Proposal, state CCIPOnChainState) error { + // TODO + return nil +} diff --git a/integration-tests/deployment/ccip/state.go b/integration-tests/deployment/ccip/state.go new file mode 100644 index 0000000000..219e7d442e --- /dev/null +++ b/integration-tests/deployment/ccip/state.go @@ -0,0 +1,271 @@ +package ccipdeployment + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + chainsel "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" + + owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" +) + +// Onchain state always derivable from an address book. +// Offchain state always derivable from a list of nodeIds. +// Note can translate this into Go struct needed for MCMS/Docs/UI. +type CCIPOnChainState struct { + // Populated go bindings for the appropriate version for all contracts. + // We would hold 2 versions of each contract here. Once we upgrade we can phase out the old one. + // When generating bindings, make sure the package name corresponds to the version. + EvmOnRampsV160 map[uint64]*evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp + EvmOffRampsV160 map[uint64]*evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp + PriceRegistries map[uint64]*price_registry.PriceRegistry + ArmProxies map[uint64]*arm_proxy_contract.ARMProxyContract + NonceManagers map[uint64]*nonce_manager.NonceManager + TokenAdminRegistries map[uint64]*token_admin_registry.TokenAdminRegistry + Routers map[uint64]*router.Router + Weth9s map[uint64]*weth9.WETH9 + MockArms map[uint64]*mock_arm_contract.MockARMContract + // TODO: May need to support older link too + LinkTokens map[uint64]*burn_mint_erc677.BurnMintERC677 + // Note we only expect one of these (on the home chain) + CapabilityRegistry map[uint64]*capabilities_registry.CapabilitiesRegistry + CCIPConfig map[uint64]*ccip_config.CCIPConfig + Mcms map[uint64]*owner_wrappers.ManyChainMultiSig + // TODO: remove once we have Address() on wrappers + McmsAddrs map[uint64]common.Address + Timelocks map[uint64]*owner_wrappers.RBACTimelock + + // Test contracts + Receivers map[uint64]*maybe_revert_message_receiver.MaybeRevertMessageReceiver +} + +type CCIPSnapShot struct { + Chains map[string]Chain `json:"chains"` +} + +type Contract struct { + TypeAndVersion string `json:"typeAndVersion"` + Address common.Address `json:"address"` +} + +type TokenAdminRegistry struct { + Contract + Tokens []common.Address `json:"tokens"` +} + +type NonceManager struct { + Contract + AuthorizedCallers []common.Address `json:"authorizedCallers"` +} + +type Chain struct { + // TODO: this will have to be versioned for getting state during upgrades. + TokenAdminRegistry TokenAdminRegistry `json:"tokenAdminRegistry"` + NonceManager NonceManager `json:"nonceManager"` +} + +func (s CCIPOnChainState) Snapshot(chains []uint64) (CCIPSnapShot, error) { + snapshot := CCIPSnapShot{ + Chains: make(map[string]Chain), + } + for _, chainSelector := range chains { + // TODO: Need a utility for this + chainid, err := chainsel.ChainIdFromSelector(chainSelector) + if err != nil { + return snapshot, err + } + chainName, err := chainsel.NameFromChainId(chainid) + if err != nil { + return snapshot, err + } + var c Chain + if ta, ok := s.TokenAdminRegistries[chainSelector]; ok { + tokens, err := ta.GetAllConfiguredTokens(nil, 0, 10) + if err != nil { + return snapshot, err + } + tv, err := ta.TypeAndVersion(nil) + if err != nil { + return snapshot, err + } + c.TokenAdminRegistry = TokenAdminRegistry{ + Contract: Contract{ + TypeAndVersion: tv, + Address: ta.Address(), + }, + Tokens: tokens, + } + } + if nm, ok := s.NonceManagers[chainSelector]; ok { + authorizedCallers, err := nm.GetAllAuthorizedCallers(nil) + if err != nil { + return snapshot, err + } + tv, err := nm.TypeAndVersion(nil) + if err != nil { + return snapshot, err + } + c.NonceManager = NonceManager{ + Contract: Contract{ + TypeAndVersion: tv, + Address: nm.Address(), + }, + // TODO: these can be resolved using an address book + AuthorizedCallers: authorizedCallers, + } + } + snapshot.Chains[chainName] = c + } + return snapshot, nil +} + +func SnapshotState(e deployment.Environment, ab deployment.AddressBook) (CCIPSnapShot, error) { + state, err := GenerateOnchainState(e, ab) + if err != nil { + return CCIPSnapShot{}, err + } + return state.Snapshot(e.AllChainSelectors()) +} + +func GenerateOnchainState(e deployment.Environment, ab deployment.AddressBook) (CCIPOnChainState, error) { + state := CCIPOnChainState{ + EvmOnRampsV160: make(map[uint64]*evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp), + EvmOffRampsV160: make(map[uint64]*evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp), + PriceRegistries: make(map[uint64]*price_registry.PriceRegistry), + ArmProxies: make(map[uint64]*arm_proxy_contract.ARMProxyContract), + NonceManagers: make(map[uint64]*nonce_manager.NonceManager), + TokenAdminRegistries: make(map[uint64]*token_admin_registry.TokenAdminRegistry), + Routers: make(map[uint64]*router.Router), + MockArms: make(map[uint64]*mock_arm_contract.MockARMContract), + LinkTokens: make(map[uint64]*burn_mint_erc677.BurnMintERC677), + Weth9s: make(map[uint64]*weth9.WETH9), + Mcms: make(map[uint64]*owner_wrappers.ManyChainMultiSig), + McmsAddrs: make(map[uint64]common.Address), + Timelocks: make(map[uint64]*owner_wrappers.RBACTimelock), + CapabilityRegistry: make(map[uint64]*capabilities_registry.CapabilitiesRegistry), + CCIPConfig: make(map[uint64]*ccip_config.CCIPConfig), + Receivers: make(map[uint64]*maybe_revert_message_receiver.MaybeRevertMessageReceiver), + } + // Get all the onchain state + addresses, err := ab.Addresses() + if err != nil { + return state, errors.Wrap(err, "could not get addresses") + } + for chainSelector, addresses := range addresses { + for address, tvStr := range addresses { + switch tvStr { + case RBAC_Timelock_1_0_0: + tl, err := owner_wrappers.NewRBACTimelock(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.Timelocks[chainSelector] = tl + case MCMS_1_0_0: + mcms, err := owner_wrappers.NewManyChainMultiSig(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.Mcms[chainSelector] = mcms + state.McmsAddrs[chainSelector] = common.HexToAddress(address) + case CapabilitiesRegistry_1_0_0: + cr, err := capabilities_registry.NewCapabilitiesRegistry(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.CapabilityRegistry[chainSelector] = cr + case EVM2EVMMultiOnRamp_1_6_0: + onRamp, err := evm_2_evm_multi_onramp.NewEVM2EVMMultiOnRamp(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.EvmOnRampsV160[chainSelector] = onRamp + case EVM2EVMMultiOffRamp_1_6_0: + offRamp, err := evm_2_evm_multi_offramp.NewEVM2EVMMultiOffRamp(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.EvmOffRampsV160[chainSelector] = offRamp + case ARMProxy_1_1_0: + armProxy, err := arm_proxy_contract.NewARMProxyContract(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.ArmProxies[chainSelector] = armProxy + case MockARM_1_0_0: + mockARM, err := mock_arm_contract.NewMockARMContract(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.MockArms[chainSelector] = mockARM + case WETH9_1_0_0: + weth9, err := weth9.NewWETH9(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.Weth9s[chainSelector] = weth9 + case NonceManager_1_6_0: + nm, err := nonce_manager.NewNonceManager(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.NonceManagers[chainSelector] = nm + case TokenAdminRegistry_1_5_0: + tm, err := token_admin_registry.NewTokenAdminRegistry(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.TokenAdminRegistries[chainSelector] = tm + case Router_1_2_0: + r, err := router.NewRouter(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.Routers[chainSelector] = r + case PriceRegistry_1_6_0: + pr, err := price_registry.NewPriceRegistry(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.PriceRegistries[chainSelector] = pr + case LinkToken_1_0_0: + lt, err := burn_mint_erc677.NewBurnMintERC677(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.LinkTokens[chainSelector] = lt + case CCIPConfig_1_6_0: + cc, err := ccip_config.NewCCIPConfig(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.CCIPConfig[chainSelector] = cc + case CCIPReceiver_1_0_0: + mr, err := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(common.HexToAddress(address), e.Chains[chainSelector].Client) + if err != nil { + return state, err + } + state.Receivers[chainSelector] = mr + default: + return state, fmt.Errorf("unknown contract %s", tvStr) + } + } + } + return state, nil +} diff --git a/integration-tests/deployment/environment.go b/integration-tests/deployment/environment.go index e06bcb1dda..7d8fb6e631 100644 --- a/integration-tests/deployment/environment.go +++ b/integration-tests/deployment/environment.go @@ -40,7 +40,7 @@ type Chain struct { Client OnchainClient // Note the Sign function can be abstract supporting a variety of key storage mechanisms (e.g. KMS etc). DeployerKey *bind.TransactOpts - Confirm func(tx common.Hash) (uint64, error) + Confirm func(tx common.Hash) error } type Environment struct { @@ -59,15 +59,15 @@ func (e Environment) AllChainSelectors() []uint64 { return selectors } -func ConfirmIfNoError(chain Chain, tx *types.Transaction, err error) (uint64, error) { +func ConfirmIfNoError(chain Chain, tx *types.Transaction, err error) error { if err != nil { //revive:disable var d rpc.DataError ok := errors.As(err, &d) if ok { - return 0, fmt.Errorf("got Data Error: %s", d.ErrorData()) + return fmt.Errorf("got Data Error: %s", d.ErrorData()) } - return 0, err + return err } return chain.Confirm(tx.Hash()) } diff --git a/integration-tests/deployment/jd/job/v1/job.pb.go b/integration-tests/deployment/jd/job/v1/job.pb.go index 788888b4c7..deaf1ccf30 100644 --- a/integration-tests/deployment/jd/job/v1/job.pb.go +++ b/integration-tests/deployment/jd/job/v1/job.pb.go @@ -7,12 +7,11 @@ package v1 import ( - reflect "reflect" - sync "sync" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" ) const ( diff --git a/integration-tests/deployment/jd/job/v1/job_grpc.pb.go b/integration-tests/deployment/jd/job/v1/job_grpc.pb.go index 64c6d285d3..9b9207c020 100644 --- a/integration-tests/deployment/jd/job/v1/job_grpc.pb.go +++ b/integration-tests/deployment/jd/job/v1/job_grpc.pb.go @@ -8,7 +8,6 @@ package v1 import ( context "context" - grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" diff --git a/integration-tests/deployment/jd/node/v1/node_grpc.pb.go b/integration-tests/deployment/jd/node/v1/node_grpc.pb.go index d23741687e..5fc0c505ee 100644 --- a/integration-tests/deployment/jd/node/v1/node_grpc.pb.go +++ b/integration-tests/deployment/jd/node/v1/node_grpc.pb.go @@ -8,7 +8,6 @@ package v1 import ( context "context" - grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" diff --git a/integration-tests/deployment/jd/node/v1/shared.pb.go b/integration-tests/deployment/jd/node/v1/shared.pb.go index 449de98fd8..4099dd6bd7 100644 --- a/integration-tests/deployment/jd/node/v1/shared.pb.go +++ b/integration-tests/deployment/jd/node/v1/shared.pb.go @@ -7,13 +7,12 @@ package v1 import ( - reflect "reflect" - sync "sync" - "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/shared/ptypes" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" ) const ( diff --git a/integration-tests/deployment/jd/shared/ptypes/label.pb.go b/integration-tests/deployment/jd/shared/ptypes/label.pb.go index a7c374c6d9..e8195bd6c3 100644 --- a/integration-tests/deployment/jd/shared/ptypes/label.pb.go +++ b/integration-tests/deployment/jd/shared/ptypes/label.pb.go @@ -7,11 +7,10 @@ package ptypes import ( - reflect "reflect" - sync "sync" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) const ( diff --git a/integration-tests/deployment/memory/environment.go b/integration-tests/deployment/memory/environment.go index 4d5d6a3c27..d496d173c0 100644 --- a/integration-tests/deployment/memory/environment.go +++ b/integration-tests/deployment/memory/environment.go @@ -39,7 +39,7 @@ func NewMemoryChains(t *testing.T, numChains int) map[uint64]deployment.Chain { Selector: sel, Client: chain.Backend, DeployerKey: chain.DeployerKey, - Confirm: func(tx common.Hash) (uint64, error) { + Confirm: func(tx common.Hash) error { for { chain.Backend.Commit() receipt, err := chain.Backend.TransactionReceipt(context.Background(), tx) @@ -50,7 +50,7 @@ func NewMemoryChains(t *testing.T, numChains int) map[uint64]deployment.Chain { if receipt.Status == 0 { t.Logf("Status (reverted) %d for txhash %s\n", receipt.Status, tx.String()) } - return receipt.BlockNumber.Uint64(), nil + return nil } }, } diff --git a/integration-tests/deployment/memory/job_client.go b/integration-tests/deployment/memory/job_client.go index 326ae6093b..a9e837eab2 100644 --- a/integration-tests/deployment/memory/job_client.go +++ b/integration-tests/deployment/memory/job_client.go @@ -17,12 +17,12 @@ type JobClient struct { } func (j JobClient) GetNode(ctx context.Context, in *nodev1.GetNodeRequest, opts ...grpc.CallOption) (*nodev1.GetNodeResponse, error) { - //TODO CCIP-3108 + //TODO implement me panic("implement me") } func (j JobClient) ListNodes(ctx context.Context, in *nodev1.ListNodesRequest, opts ...grpc.CallOption) (*nodev1.ListNodesResponse, error) { - //TODO CCIP-3108 + //TODO implement me panic("implement me") } @@ -66,22 +66,22 @@ func (j JobClient) ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNode } func (j JobClient) GetJob(ctx context.Context, in *jobv1.GetJobRequest, opts ...grpc.CallOption) (*jobv1.GetJobResponse, error) { - //TODO CCIP-3108 + //TODO implement me panic("implement me") } func (j JobClient) GetProposal(ctx context.Context, in *jobv1.GetProposalRequest, opts ...grpc.CallOption) (*jobv1.GetProposalResponse, error) { - //TODO CCIP-3108 + //TODO implement me panic("implement me") } func (j JobClient) ListJobs(ctx context.Context, in *jobv1.ListJobsRequest, opts ...grpc.CallOption) (*jobv1.ListJobsResponse, error) { - //TODO CCIP-3108 + //TODO implement me panic("implement me") } func (j JobClient) ListProposals(ctx context.Context, in *jobv1.ListProposalsRequest, opts ...grpc.CallOption) (*jobv1.ListProposalsResponse, error) { - //TODO CCIP-3108 + //TODO implement me panic("implement me") } @@ -112,12 +112,12 @@ func (j JobClient) ProposeJob(ctx context.Context, in *jobv1.ProposeJobRequest, } func (j JobClient) RevokeJob(ctx context.Context, in *jobv1.RevokeJobRequest, opts ...grpc.CallOption) (*jobv1.RevokeJobResponse, error) { - //TODO CCIP-3108 + //TODO implement me panic("implement me") } func (j JobClient) DeleteJob(ctx context.Context, in *jobv1.DeleteJobRequest, opts ...grpc.CallOption) (*jobv1.DeleteJobResponse, error) { - //TODO CCIP-3108 + //TODO implement me panic("implement me") } diff --git a/integration-tests/deployment/memory/node.go b/integration-tests/deployment/memory/node.go index 55ecd23337..cc800f18bd 100644 --- a/integration-tests/deployment/memory/node.go +++ b/integration-tests/deployment/memory/node.go @@ -12,14 +12,12 @@ import ( "github.com/ethereum/go-ethereum/common" gethtypes "github.com/ethereum/go-ethereum/core/types" - chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" v2toml "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -63,16 +61,6 @@ type Node struct { IsBoostrap bool } -func (n Node) ReplayLogs(chains map[uint64]uint64) error { - for sel, block := range chains { - chainID, _ := chainsel.ChainIdFromSelector(sel) - if err := n.App.ReplayFromBlock(big.NewInt(int64(chainID)), block, false); err != nil { - return err - } - } - return nil -} - type RegistryConfig struct { EVMChainID uint64 Contract common.Address diff --git a/integration-tests/deployment/migrations.go b/integration-tests/deployment/migrations.go new file mode 100644 index 0000000000..5defd56075 --- /dev/null +++ b/integration-tests/deployment/migrations.go @@ -0,0 +1,28 @@ +package deployment + +import ( + owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" +) + +// TODO: Move to real MCM structs once available. +type Proposal struct { + // keccak256(abi.encode(root, validUntil)) is what is signed by MCMS + // signers. + ValidUntil uint32 + // Leaves are the items in the proposal. + // Uses these to generate the root as well as display whats in the root. + // These Ops may be destined for distinct chains. + Ops []owner_wrappers.ManyChainMultiSigOp +} + +func (p Proposal) String() string { + // TODO + return "" +} + +// Services as input to CI/Async tasks +type MigrationOutput struct { + JobSpecs map[string][]string + Proposals []Proposal + AddressBook AddressBook +} diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 1a742a373f..5571e0c2dc 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -18,6 +18,7 @@ require ( github.com/go-resty/resty/v2 v2.11.0 github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 + github.com/hashicorp/consul/sdk v0.16.0 github.com/jmoiron/sqlx v1.4.0 github.com/lib/pq v1.10.9 github.com/manifoldco/promptui v0.9.0 @@ -31,10 +32,12 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 + github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240814100759-a12828c40ddb github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 - github.com/smartcontractkit/chainlink-testing-framework v1.32.7 + github.com/smartcontractkit/chainlink-testing-framework v1.33.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-00010101000000-000000000000 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 @@ -42,7 +45,7 @@ require ( github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/seth v1.0.12 github.com/smartcontractkit/wasp v0.4.5 - github.com/spf13/cobra v1.8.0 + github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 github.com/test-go/testify v1.1.4 github.com/testcontainers/testcontainers-go v0.28.0 @@ -50,13 +53,16 @@ require ( go.uber.org/atomic v1.11.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.25.0 + golang.org/x/crypto v0.26.0 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - golang.org/x/sync v0.7.0 - golang.org/x/text v0.16.0 + golang.org/x/sync v0.8.0 + golang.org/x/text v0.17.0 + google.golang.org/grpc v1.65.0 + google.golang.org/protobuf v1.34.2 gopkg.in/guregu/null.v4 v4.0.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 + gotest.tools/v3 v3.5.1 k8s.io/apimachinery v0.28.2 ) @@ -88,8 +94,8 @@ require ( github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/Microsoft/hcsshim v0.11.5 // indirect github.com/NethermindEth/juno v0.3.1 // indirect github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect @@ -132,7 +138,8 @@ require ( github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/containerd/containerd v1.7.12 // indirect + github.com/containerd/containerd v1.7.18 // indirect + github.com/containerd/errdefs v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect @@ -158,7 +165,7 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/distribution/reference v0.5.0 // indirect + github.com/distribution/reference v0.6.0 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v25.0.2+incompatible // indirect github.com/docker/go-connections v0.5.0 // indirect @@ -179,7 +186,7 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/solana-go v1.8.4 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect @@ -198,7 +205,7 @@ require ( github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.4 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect @@ -210,7 +217,7 @@ require ( github.com/go-openapi/validate v0.22.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.15.5 // indirect + github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect @@ -257,8 +264,7 @@ require ( github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect - github.com/hashicorp/consul/api v1.25.1 // indirect - github.com/hashicorp/consul/sdk v0.16.0 // indirect + github.com/hashicorp/consul/api v1.28.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-envparse v0.1.0 // indirect @@ -303,13 +309,13 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.3 // indirect + github.com/klauspost/compress v1.17.7 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/linxGnu/grocksdb v1.7.16 // indirect @@ -349,7 +355,7 @@ require ( github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc5 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e // indirect github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect @@ -384,7 +390,6 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect @@ -392,14 +397,14 @@ require ( github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect - github.com/smartcontractkit/wsrpc v0.7.3 // indirect + github.com/smartcontractkit/wsrpc v0.8.1 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.18.2 // indirect + github.com/spf13/viper v1.19.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect @@ -431,14 +436,14 @@ require ( go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect go.etcd.io/bbolt v1.3.8 // indirect - go.etcd.io/etcd/api/v3 v3.5.10 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect - go.etcd.io/etcd/client/v3 v3.5.10 // indirect + go.etcd.io/etcd/api/v3 v3.5.12 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.12 // indirect + go.etcd.io/etcd/client/v3 v3.5.12 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 // indirect go.opentelemetry.io/collector/semconv v0.87.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect @@ -455,8 +460,8 @@ require ( golang.org/x/mod v0.19.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/term v0.23.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.23.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect @@ -464,21 +469,19 @@ require ( google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/grpc v1.65.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect k8s.io/api v0.28.2 // indirect - k8s.io/apiextensions-apiserver v0.28.1 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect k8s.io/cli-runtime v0.28.2 // indirect k8s.io/client-go v0.28.2 // indirect k8s.io/component-base v0.28.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect - k8s.io/kubectl v0.28.1 // indirect + k8s.io/kubectl v0.28.2 // indirect k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect - nhooyr.io/websocket v1.8.7 // indirect + nhooyr.io/websocket v1.8.10 // indirect pgregory.net/rapid v1.1.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/controller-runtime v0.16.2 // indirect @@ -496,40 +499,6 @@ replace ( github.com/prometheus/common => github.com/prometheus/common v0.42.0 ) -replace ( - k8s.io/api => k8s.io/api v0.28.2 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.28.2 - k8s.io/apimachinery => k8s.io/apimachinery v0.28.2 - k8s.io/apiserver => k8s.io/apiserver v0.28.2 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.28.2 - k8s.io/client-go => k8s.io/client-go v0.28.2 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.28.2 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.28.2 - k8s.io/code-generator => k8s.io/code-generator v0.28.2 - k8s.io/component-base => k8s.io/component-base v0.28.2 - k8s.io/component-helpers => k8s.io/component-helpers v0.28.2 - k8s.io/controller-manager => k8s.io/controller-manager v0.28.2 - k8s.io/cri-api => k8s.io/cri-api v0.28.2 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.28.2 - k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.28.2 - k8s.io/endpointslice => k8s.io/endpointslice v0.28.2 - k8s.io/kms => k8s.io/kms v0.28.2 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.28.2 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.28.2 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.28.2 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.28.2 - k8s.io/kubectl => k8s.io/kubectl v0.28.2 - k8s.io/kubelet => k8s.io/kubelet v0.28.2 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.28.2 - k8s.io/metrics => k8s.io/metrics v0.28.2 - k8s.io/mount-utils => k8s.io/mount-utils v0.28.2 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.28.2 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.28.2 - k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.28.2 - k8s.io/sample-controller => k8s.io/sample-controller v0.28.2 - sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.16.2 -) - replace ( github.com/go-kit/log => github.com/go-kit/log v0.2.1 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index a5925ccab7..0628afe4e4 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -135,10 +135,10 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0 github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= -github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/Microsoft/hcsshim v0.11.5 h1:haEcLNpj9Ka1gd3B3tAEs9CpE0c+1IhoL59w/exYU38= +github.com/Microsoft/hcsshim v0.11.5/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU= github.com/NethermindEth/juno v0.3.1 h1:AW72LiAm9gqUeCVJWvepnZcTnpU4Vkl0KzPMxS+42FA= github.com/NethermindEth/juno v0.3.1/go.mod h1:SGbTpgGaCsxhFsKOid7Ylnz//WZ8swtILk+NbHGsk/Q= github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb h1:Mv8SscePPyw2ju4igIJAjFgcq5zCQfjgbz53DwYu5mc= @@ -317,10 +317,12 @@ github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/Yj github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= -github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= +github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao= +github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= +github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -364,8 +366,8 @@ github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHf github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= @@ -411,8 +413,8 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E= github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA= -github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= -github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= @@ -481,8 +483,8 @@ github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQ github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= @@ -510,7 +512,6 @@ github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibO github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= @@ -540,8 +541,9 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= @@ -577,18 +579,14 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= -github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= @@ -632,15 +630,6 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= -github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= -github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= -github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -757,7 +746,6 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -765,8 +753,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= -github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/gophercloud/gophercloud v1.5.0 h1:cDN6XFCLKiiqvYpjQLq9AiM7RDRbIC9450WpPH+yvXo= github.com/gophercloud/gophercloud v1.5.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -781,7 +769,6 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= @@ -833,8 +820,8 @@ github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/b github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE= -github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= +github.com/hashicorp/consul/api v1.28.2 h1:mXfkRHrpHN4YY3RqL09nXU1eHKLNiuAN4kHvDQ16k/8= +github.com/hashicorp/consul/api v1.28.2/go.mod h1:KyzqzgMEya+IZPcD65YFoOVAgPpbfERu4I/tzG6/ueE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.16.0 h1:SE9m0W6DEfgIVCJX7xU+iv/hUl4m/nxqMTnCdMxDpJ8= github.com/hashicorp/consul/sdk v0.16.0/go.mod h1:7pxqqhqoaPqnBnzXD1StKed62LqJeClzVsUEy85Zr0A= @@ -1013,7 +1000,6 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -1027,12 +1013,12 @@ github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dv github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= +github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -1055,9 +1041,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -1176,7 +1161,6 @@ github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= @@ -1230,8 +1214,8 @@ github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= -github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg= @@ -1388,6 +1372,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 h1:jakAsdhDxV4cMgRAcSvHraXjyePi8umG5SEUTGFvuy8= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685/go.mod h1:p7L/xNEQpHDdZtgFA6/FavuZHqvV3kYhQysxBywmq1k= github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1WonwhVOPtOStpqTmLC4E= github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= @@ -1426,8 +1412,8 @@ github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:D github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= github.com/smartcontractkit/wasp v0.4.5 h1:pgiXwBci2m15eo33AzspzhpNG/gxg+8QGxl+I5LpfsQ= github.com/smartcontractkit/wasp v0.4.5/go.mod h1:eVhBVLbVv0qORUlN7aR5C4aTN/lTYO3KnN1erO4ROOI= -github.com/smartcontractkit/wsrpc v0.7.3 h1:CKYZfawZShZGfvsQep1F9oBansnFk9ByZPCdTMpLphw= -github.com/smartcontractkit/wsrpc v0.7.3/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= +github.com/smartcontractkit/wsrpc v0.8.1 h1:kk0SXLqWrWaZ3J6c7n8D0NZ2uTMBBBpG5dZZXZX8UGE= +github.com/smartcontractkit/wsrpc v0.8.1/go.mod h1:yfg8v8fPLXkb6Mcnx6Pm/snP6jJ0r5Kf762Yd1a/KpA= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1450,8 +1436,8 @@ github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cA github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -1459,8 +1445,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= @@ -1482,7 +1468,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -1530,9 +1515,7 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= @@ -1599,12 +1582,12 @@ go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYr go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= -go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= -go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= -go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= -go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= -go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= +go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c= +go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= +go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A= +go.etcd.io/etcd/client/pkg/v3 v3.5.12/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4= +go.etcd.io/etcd/client/v3 v3.5.12 h1:v5lCPXn1pf1Uu3M4laUE2hp/geOTc5uPcYYsNe1lDxg= +go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= @@ -1626,8 +1609,8 @@ go.opentelemetry.io/collector/semconv v0.87.0 h1:BsG1jdLLRCBRlvUujk4QA86af7r/ZXn go.opentelemetry.io/collector/semconv v0.87.0/go.mod h1:j/8THcqVxFna1FpvA2zYIsUperEtOaRaqoLYIN4doWw= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= @@ -1676,7 +1659,6 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= @@ -1711,8 +1693,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1831,8 +1813,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1920,8 +1902,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1933,8 +1915,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1948,8 +1930,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2047,8 +2029,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= -google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= +google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= +google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2171,7 +2153,6 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2202,8 +2183,8 @@ k8s.io/kubectl v0.28.2 h1:fOWOtU6S0smdNjG1PB9WFbqEIMlkzU5ahyHkc7ESHgM= k8s.io/kubectl v0.28.2/go.mod h1:6EQWTPySF1fn7yKoQZHYf9TPwIl2AygHEcJoxFekr64= k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= +nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 82924f18c0..d540449f8c 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -35,6 +35,7 @@ require ( cosmossdk.io/depinject v1.0.0-alpha.4 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/math v1.3.0 // indirect + github.com/containerd/errdefs v0.1.0 // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect @@ -42,6 +43,7 @@ require ( github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect + github.com/testcontainers/testcontainers-go v0.28.0 // indirect k8s.io/apimachinery v0.30.2 // indirect ) @@ -69,8 +71,8 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/Microsoft/hcsshim v0.11.5 // indirect github.com/NethermindEth/juno v0.3.1 // indirect github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect @@ -114,7 +116,7 @@ require ( github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/containerd/containerd v1.7.12 // indirect + github.com/containerd/containerd v1.7.18 // indirect github.com/containerd/continuity v0.4.3 // indirect github.com/containerd/log v0.1.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect @@ -141,7 +143,7 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/distribution/reference v0.5.0 // indirect + github.com/distribution/reference v0.6.0 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v25.0.2+incompatible // indirect github.com/docker/go-connections v0.5.0 // indirect @@ -163,7 +165,7 @@ require ( github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect github.com/fxamacker/cbor/v2 v2.6.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/solana-go v1.8.4 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect @@ -182,7 +184,7 @@ require ( github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.4 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect @@ -194,7 +196,7 @@ require ( github.com/go-openapi/validate v0.22.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.15.5 // indirect + github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect @@ -242,7 +244,7 @@ require ( github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect - github.com/hashicorp/consul/api v1.25.1 // indirect + github.com/hashicorp/consul/api v1.28.2 // indirect github.com/hashicorp/consul/sdk v0.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -288,13 +290,13 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.3 // indirect + github.com/klauspost/compress v1.17.7 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect @@ -335,7 +337,7 @@ require ( github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc5 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect github.com/opencontainers/runc v1.1.10 // indirect github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e // indirect github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect @@ -380,7 +382,7 @@ require ( github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 // indirect github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect - github.com/smartcontractkit/wsrpc v0.7.3 // indirect + github.com/smartcontractkit/wsrpc v0.8.1 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -388,7 +390,7 @@ require ( github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.18.2 // indirect + github.com/spf13/viper v1.19.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect @@ -398,7 +400,6 @@ require ( github.com/tendermint/go-amino v0.16.0 // indirect github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect github.com/test-go/testify v1.1.4 // indirect - github.com/testcontainers/testcontainers-go v0.28.0 // indirect github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a // indirect github.com/tidwall/btree v1.6.0 // indirect github.com/tidwall/gjson v1.17.0 // indirect @@ -423,14 +424,14 @@ require ( go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect go.etcd.io/bbolt v1.3.8 // indirect - go.etcd.io/etcd/api/v3 v3.5.10 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect - go.etcd.io/etcd/client/v3 v3.5.10 // indirect + go.etcd.io/etcd/api/v3 v3.5.12 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.12 // indirect + go.etcd.io/etcd/client/v3 v3.5.12 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 // indirect go.opentelemetry.io/collector/semconv v0.87.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect @@ -446,15 +447,15 @@ require ( go.uber.org/zap v1.27.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.7.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.19.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.23.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect @@ -479,7 +480,7 @@ require ( k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect k8s.io/kubectl v0.28.1 // indirect k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect - nhooyr.io/websocket v1.8.7 // indirect + nhooyr.io/websocket v1.8.10 // indirect pgregory.net/rapid v1.1.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/controller-runtime v0.18.4 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 926362ed14..18e05c9047 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -135,10 +135,10 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0 github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= -github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/Microsoft/hcsshim v0.11.5 h1:haEcLNpj9Ka1gd3B3tAEs9CpE0c+1IhoL59w/exYU38= +github.com/Microsoft/hcsshim v0.11.5/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU= github.com/NethermindEth/juno v0.3.1 h1:AW72LiAm9gqUeCVJWvepnZcTnpU4Vkl0KzPMxS+42FA= github.com/NethermindEth/juno v0.3.1/go.mod h1:SGbTpgGaCsxhFsKOid7Ylnz//WZ8swtILk+NbHGsk/Q= github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb h1:Mv8SscePPyw2ju4igIJAjFgcq5zCQfjgbz53DwYu5mc= @@ -307,10 +307,12 @@ github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/Yj github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= -github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= +github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao= +github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4= github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= +github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -401,8 +403,8 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E= github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA= -github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= -github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= @@ -471,8 +473,8 @@ github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQ github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= @@ -500,7 +502,6 @@ github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibO github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= @@ -530,8 +531,9 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= @@ -567,18 +569,14 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= -github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= @@ -622,15 +620,6 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= -github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= -github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= -github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -747,7 +736,6 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -755,8 +743,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= -github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/gophercloud/gophercloud v1.5.0 h1:cDN6XFCLKiiqvYpjQLq9AiM7RDRbIC9450WpPH+yvXo= github.com/gophercloud/gophercloud v1.5.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -771,7 +759,6 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= @@ -823,8 +810,8 @@ github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/b github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE= -github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= +github.com/hashicorp/consul/api v1.28.2 h1:mXfkRHrpHN4YY3RqL09nXU1eHKLNiuAN4kHvDQ16k/8= +github.com/hashicorp/consul/api v1.28.2/go.mod h1:KyzqzgMEya+IZPcD65YFoOVAgPpbfERu4I/tzG6/ueE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.16.0 h1:SE9m0W6DEfgIVCJX7xU+iv/hUl4m/nxqMTnCdMxDpJ8= github.com/hashicorp/consul/sdk v0.16.0/go.mod h1:7pxqqhqoaPqnBnzXD1StKed62LqJeClzVsUEy85Zr0A= @@ -1001,7 +988,6 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -1015,12 +1001,12 @@ github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dv github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= +github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -1043,9 +1029,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -1162,7 +1147,6 @@ github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= @@ -1212,8 +1196,8 @@ github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= -github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opencontainers/runc v1.1.10 h1:EaL5WeO9lv9wmS6SASjszOeQdSctvpbu0DdBQBizE40= github.com/opencontainers/runc v1.1.10/go.mod h1:+/R6+KmDlh+hOO8NkjmgkG9Qzvypzk0yXxAPYYR65+M= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg= @@ -1408,8 +1392,8 @@ github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:D github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= github.com/smartcontractkit/wasp v0.4.7 h1:7mKJfwzFbuE8xVLUYtLt7Bjw8q/bmVZRW6Ks8kc1LVM= github.com/smartcontractkit/wasp v0.4.7/go.mod h1:jeabvyXikb2aNoLQwcZGqaz17efrR8NJhpq4seAmdgs= -github.com/smartcontractkit/wsrpc v0.7.3 h1:CKYZfawZShZGfvsQep1F9oBansnFk9ByZPCdTMpLphw= -github.com/smartcontractkit/wsrpc v0.7.3/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= +github.com/smartcontractkit/wsrpc v0.8.1 h1:kk0SXLqWrWaZ3J6c7n8D0NZ2uTMBBBpG5dZZXZX8UGE= +github.com/smartcontractkit/wsrpc v0.8.1/go.mod h1:yfg8v8fPLXkb6Mcnx6Pm/snP6jJ0r5Kf762Yd1a/KpA= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1441,8 +1425,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= @@ -1464,7 +1448,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -1510,9 +1493,7 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= @@ -1581,12 +1562,12 @@ go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYr go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= -go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= -go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= -go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= -go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= -go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= +go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c= +go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= +go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A= +go.etcd.io/etcd/client/pkg/v3 v3.5.12/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4= +go.etcd.io/etcd/client/v3 v3.5.12 h1:v5lCPXn1pf1Uu3M4laUE2hp/geOTc5uPcYYsNe1lDxg= +go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= @@ -1608,8 +1589,8 @@ go.opentelemetry.io/collector/semconv v0.87.0 h1:BsG1jdLLRCBRlvUujk4QA86af7r/ZXn go.opentelemetry.io/collector/semconv v0.87.0/go.mod h1:j/8THcqVxFna1FpvA2zYIsUperEtOaRaqoLYIN4doWw= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= @@ -1658,7 +1639,6 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= @@ -1693,8 +1673,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1813,8 +1793,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1900,8 +1880,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1913,8 +1893,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1928,8 +1908,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2027,8 +2007,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= -google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= +google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= +google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2182,8 +2162,8 @@ k8s.io/kubectl v0.28.2 h1:fOWOtU6S0smdNjG1PB9WFbqEIMlkzU5ahyHkc7ESHgM= k8s.io/kubectl v0.28.2/go.mod h1:6EQWTPySF1fn7yKoQZHYf9TPwIl2AygHEcJoxFekr64= k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= +nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= From 44dad95cb308f20c8f42e3344c23a430eca5c1ae Mon Sep 17 00:00:00 2001 From: kanth <70688600+defistar@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:46:40 +0530 Subject: [PATCH 212/432] CCIP-2594 Add pagination based query of CCIPConfig (#1136) CCIP Config can go to larger size and any query from offchain components via rpc call can cause timeout issues add pagination to `getAllCCIPConfig` function which takes - pageSize - startIndex --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> Co-authored-by: Makram Kamaleddine --- contracts/gas-snapshots/ccip.gas-snapshot | 31 +++++----- .../src/v0.8/ccip/capability/CCIPConfig.sol | 32 ++++++++--- .../ccip/test/capability/CCIPConfig.t.sol | 56 +++++++++++++++++-- .../ccip_integration_tests/home_chain_test.go | 44 +++++++++------ .../ccip_integration_tests/ocr3_node_test.go | 2 +- .../ccip/generated/ccip_config/ccip_config.go | 18 +++--- ...rapper-dependency-versions-do-not-edit.txt | 2 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 8 +-- go.mod | 3 +- go.sum | 8 +-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 8 +-- integration-tests/load/go.mod | 6 +- integration-tests/load/go.sum | 8 +-- 15 files changed, 152 insertions(+), 78 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 2e407f5ebb..40d9e2e4f3 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -37,12 +37,12 @@ BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 23951) CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2132726) CCIPConfigSetup:test_getCapabilityConfiguration_Success() (gas: 9517) CCIPConfig_ConfigStateMachine:test__computeConfigDigest_Success() (gas: 70831) -CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_InitToRunning_Success() (gas: 363708) -CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_RunningToStaging_Success() (gas: 488870) -CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_StagingToRunning_Success() (gas: 453483) -CCIPConfig_ConfigStateMachine:test__groupByPluginType_TooManyOCR3Configs_Reverts() (gas: 37027) -CCIPConfig_ConfigStateMachine:test__groupByPluginType_threeCommitConfigs_Reverts() (gas: 61043) -CCIPConfig_ConfigStateMachine:test__groupByPluginType_threeExecutionConfigs_Reverts() (gas: 60963) +CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_InitToRunning_Success() (gas: 363664) +CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_RunningToStaging_Success() (gas: 488826) +CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_StagingToRunning_Success() (gas: 453439) +CCIPConfig_ConfigStateMachine:test__groupByPluginType_TooManyOCR3Configs_Reverts() (gas: 37049) +CCIPConfig_ConfigStateMachine:test__groupByPluginType_threeCommitConfigs_Reverts() (gas: 61065) +CCIPConfig_ConfigStateMachine:test__groupByPluginType_threeExecutionConfigs_Reverts() (gas: 60985) CCIPConfig_ConfigStateMachine:test__stateFromConfigLength_Success() (gas: 11635) CCIPConfig_ConfigStateMachine:test__validateConfigStateTransition_Success() (gas: 8831) CCIPConfig_ConfigStateMachine:test__validateConfigTransition_InitToRunning_Success() (gas: 312055) @@ -61,18 +61,19 @@ CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_OnlyCapabili CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_ZeroLengthConfig_Success() (gas: 16070) CCIPConfig_beforeCapabilityConfigSet:test_getCapabilityConfiguration_Success() (gas: 9605) CCIPConfig_chainConfig:test__applyChainConfigUpdates_FChainNotPositive_Reverts() (gas: 184703) -CCIPConfig_chainConfig:test_applyChainConfigUpdates_addChainConfigs_Success() (gas: 344332) +CCIPConfig_chainConfig:test_applyChainConfigUpdates_addChainConfigs_Success() (gas: 344881) CCIPConfig_chainConfig:test_applyChainConfigUpdates_nodeNotInRegistry_Reverts() (gas: 20258) CCIPConfig_chainConfig:test_applyChainConfigUpdates_removeChainConfigs_Success() (gas: 267558) CCIPConfig_chainConfig:test_applyChainConfigUpdates_selectorNotFound_Reverts() (gas: 14829) -CCIPConfig_chainConfig:test_getCapabilityConfiguration_Success() (gas: 9648) -CCIPConfig_constructor:test_constructor_Success() (gas: 3567986) -CCIPConfig_constructor:test_constructor_ZeroAddressNotAllowed_Revert() (gas: 61720) -CCIPConfig_updatePluginConfig:test__updatePluginConfig_InitToRunning_Success() (gas: 1057346) -CCIPConfig_updatePluginConfig:test__updatePluginConfig_InvalidConfigLength_Reverts() (gas: 27539) -CCIPConfig_updatePluginConfig:test__updatePluginConfig_InvalidConfigStateTransition_Reverts() (gas: 23105) -CCIPConfig_updatePluginConfig:test__updatePluginConfig_RunningToStaging_Success() (gas: 2009250) -CCIPConfig_updatePluginConfig:test__updatePluginConfig_StagingToRunning_Success() (gas: 2616080) +CCIPConfig_chainConfig:test_getCapabilityConfiguration_Success() (gas: 9626) +CCIPConfig_chainConfig:test_getPaginatedCCIPConfigs_Success() (gas: 370235) +CCIPConfig_constructor:test_constructor_Success() (gas: 3612901) +CCIPConfig_constructor:test_constructor_ZeroAddressNotAllowed_Revert() (gas: 61777) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_InitToRunning_Success() (gas: 1057368) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_InvalidConfigLength_Reverts() (gas: 27561) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_InvalidConfigStateTransition_Reverts() (gas: 23127) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_RunningToStaging_Success() (gas: 2009285) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_StagingToRunning_Success() (gas: 2616133) CCIPConfig_updatePluginConfig:test_getCapabilityConfiguration_Success() (gas: 9605) CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsHasDuplicates_Reverts() (gas: 294893) CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsNotASubsetOfP2PIds_Reverts() (gas: 298325) diff --git a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol index 245a9ef737..6d310f989b 100644 --- a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol +++ b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol @@ -105,20 +105,36 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator } /// @notice Returns all the chain configurations. - /// @return The chain configurations. - // TODO: will this eventually hit the RPC max response size limit? - function getAllChainConfigs() external view returns (CCIPConfigTypes.ChainConfigInfo[] memory) { + /// @return paginatedChainConfigs chain configurations. + function getAllChainConfigs( + uint256 pageIndex, + uint256 pageSize + ) external view returns (CCIPConfigTypes.ChainConfigInfo[] memory) { + uint256 totalItems = s_remoteChainSelectors.length(); // Total number of chain selectors + uint256 startIndex = pageIndex * pageSize; + + if (pageSize == 0 || startIndex >= totalItems) { + return new CCIPConfigTypes.ChainConfigInfo[](0); // Return an empty array if pageSize is 0 or pageIndex is out of bounds + } + + uint256 endIndex = startIndex + pageSize; + if (endIndex > totalItems) { + endIndex = totalItems; + } + + CCIPConfigTypes.ChainConfigInfo[] memory paginatedChainConfigs = + new CCIPConfigTypes.ChainConfigInfo[](endIndex - startIndex); + uint256[] memory chainSelectors = s_remoteChainSelectors.values(); - CCIPConfigTypes.ChainConfigInfo[] memory chainConfigs = - new CCIPConfigTypes.ChainConfigInfo[](s_remoteChainSelectors.length()); - for (uint256 i = 0; i < chainSelectors.length; ++i) { + for (uint256 i = startIndex; i < endIndex; ++i) { uint64 chainSelector = uint64(chainSelectors[i]); - chainConfigs[i] = CCIPConfigTypes.ChainConfigInfo({ + paginatedChainConfigs[i - startIndex] = CCIPConfigTypes.ChainConfigInfo({ chainSelector: chainSelector, chainConfig: s_chainConfigurations[chainSelector] }); } - return chainConfigs; + + return paginatedChainConfigs; } /// @notice Returns the OCR configuration for the given don ID and plugin type. diff --git a/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol b/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol index fe2bf75854..2ac30b355a 100644 --- a/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol +++ b/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol @@ -128,7 +128,6 @@ contract CCIPConfig_constructor is Test { contract CCIPConfig_chainConfig is CCIPConfigSetup { // Successes. - function test_applyChainConfigUpdates_addChainConfigs_Success() public { bytes32[] memory chainReaders = new bytes32[](1); chainReaders[0] = keccak256(abi.encode(1)); @@ -141,7 +140,6 @@ contract CCIPConfig_chainConfig is CCIPConfigSetup { chainSelector: 2, chainConfig: CCIPConfigTypes.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config2")}) }); - vm.mockCall( CAPABILITIES_REGISTRY, abi.encodeWithSelector(ICapabilitiesRegistry.getNode.selector, chainReaders[0]), @@ -157,19 +155,69 @@ contract CCIPConfig_chainConfig is CCIPConfigSetup { }) ) ); - vm.expectEmit(); emit CCIPConfig.ChainConfigSet(1, adds[0].chainConfig); vm.expectEmit(); emit CCIPConfig.ChainConfigSet(2, adds[1].chainConfig); s_ccipCC.applyChainConfigUpdates(new uint64[](0), adds); - CCIPConfigTypes.ChainConfigInfo[] memory configs = s_ccipCC.getAllChainConfigs(); + CCIPConfigTypes.ChainConfigInfo[] memory configs = s_ccipCC.getAllChainConfigs(0, 2); assertEq(configs.length, 2, "chain configs length must be 2"); assertEq(configs[0].chainSelector, 1, "chain selector must match"); assertEq(configs[1].chainSelector, 2, "chain selector must match"); } + function test_getPaginatedCCIPConfigs_Success() public { + bytes32[] memory chainReaders = new bytes32[](1); + chainReaders[0] = keccak256(abi.encode(1)); + CCIPConfigTypes.ChainConfigInfo[] memory adds = new CCIPConfigTypes.ChainConfigInfo[](2); + adds[0] = CCIPConfigTypes.ChainConfigInfo({ + chainSelector: 1, + chainConfig: CCIPConfigTypes.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config1")}) + }); + adds[1] = CCIPConfigTypes.ChainConfigInfo({ + chainSelector: 2, + chainConfig: CCIPConfigTypes.ChainConfig({readers: chainReaders, fChain: 1, config: bytes("config2")}) + }); + vm.mockCall( + CAPABILITIES_REGISTRY, + abi.encodeWithSelector(ICapabilitiesRegistry.getNode.selector, chainReaders[0]), + abi.encode( + ICapabilitiesRegistry.NodeInfo({ + nodeOperatorId: 1, + signer: bytes32(uint256(1)), + p2pId: chainReaders[0], + hashedCapabilityIds: new bytes32[](0), + configCount: uint32(1), + workflowDONId: uint32(1), + capabilitiesDONIds: new uint256[](0) + }) + ) + ); + + s_ccipCC.applyChainConfigUpdates(new uint64[](0), adds); + + CCIPConfigTypes.ChainConfigInfo[] memory configs = s_ccipCC.getAllChainConfigs(0, 2); + assertEq(configs.length, 2, "chain configs length must be 2"); + assertEq(configs[0].chainSelector, 1, "chain selector must match"); + assertEq(configs[1].chainSelector, 2, "chain selector must match"); + + configs = s_ccipCC.getAllChainConfigs(0, 1); + assertEq(configs.length, 1, "chain configs length must be 1"); + assertEq(configs[0].chainSelector, 1, "chain selector must match"); + + configs = s_ccipCC.getAllChainConfigs(0, 10); + assertEq(configs.length, 2, "chain configs length must be 2"); + assertEq(configs[0].chainSelector, 1, "chain selector must match"); + assertEq(configs[1].chainSelector, 2, "chain selector must match"); + + configs = s_ccipCC.getAllChainConfigs(1, 1); + assertEq(configs.length, 1, "chain configs length must be 1"); + + configs = s_ccipCC.getAllChainConfigs(1, 2); + assertEq(configs.length, 0, "chain configs length must be 0"); + } + function test_applyChainConfigUpdates_removeChainConfigs_Success() public { bytes32[] memory chainReaders = new bytes32[](1); chainReaders[0] = keccak256(abi.encode(1)); diff --git a/core/capabilities/ccip/ccip_integration_tests/home_chain_test.go b/core/capabilities/ccip/ccip_integration_tests/home_chain_test.go index c78fd37b80..c8b261eba1 100644 --- a/core/capabilities/ccip/ccip_integration_tests/home_chain_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/home_chain_test.go @@ -1,6 +1,7 @@ package ccip_integration_tests import ( + "math/big" "testing" "time" @@ -35,6 +36,7 @@ func TestHomeChainReader(t *testing.T) { } p2pIDs := integrationhelpers.P2pIDsFromInts(arr) uni.AddCapability(p2pIDs) + //==============================Apply configs to Capability Contract================================= encodedChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ GasPriceDeviationPPB: cciptypes.NewBigIntFromInt64(1000), @@ -43,28 +45,26 @@ func TestHomeChainReader(t *testing.T) { OptimisticConfirmations: 1, }) require.NoError(t, err) - chainAConf := integrationhelpers.SetupConfigInfo(integrationhelpers.ChainA, p2pIDs, integrationhelpers.FChainA, encodedChainConfig) - chainBConf := integrationhelpers.SetupConfigInfo(integrationhelpers.ChainB, p2pIDs[1:], integrationhelpers.FChainB, encodedChainConfig) - chainCConf := integrationhelpers.SetupConfigInfo(integrationhelpers.ChainC, p2pIDs[2:], integrationhelpers.FChainC, encodedChainConfig) inputConfig := []capcfg.CCIPConfigTypesChainConfigInfo{ - chainAConf, - chainBConf, - chainCConf, + integrationhelpers.SetupConfigInfo(integrationhelpers.ChainA, p2pIDs, integrationhelpers.FChainA, encodedChainConfig), + integrationhelpers.SetupConfigInfo(integrationhelpers.ChainB, p2pIDs[1:], integrationhelpers.FChainB, encodedChainConfig), + integrationhelpers.SetupConfigInfo(integrationhelpers.ChainC, p2pIDs[2:], integrationhelpers.FChainC, encodedChainConfig), } _, err = uni.CcipCfg.ApplyChainConfigUpdates(uni.Transactor, nil, inputConfig) require.NoError(t, err) uni.Backend.Commit() - //================================Setup HomeChainReader=============================== - - pollDuration := time.Second - homeChain := uni.HomeChainReader + chainConfigInfos, err := uni.CcipCfg.GetAllChainConfigs(nil, big.NewInt(0), big.NewInt(100)) + require.NoError(t, err) + require.Len(t, chainConfigInfos, len(inputConfig)) + // Wait for the home chain reader to read the expected amount of chain configs. gomega.NewWithT(t).Eventually(func() bool { - configs, _ := homeChain.GetAllChainConfigs() - return configs != nil - }, testutils.WaitTimeout(t), pollDuration*5).Should(gomega.BeTrue()) + configs, _ := uni.HomeChainReader.GetAllChainConfigs() + return len(configs) == len(inputConfig) + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue()) t.Logf("homchain reader is ready") + //================================Test HomeChain Reader=============================== expectedChainConfigs := map[cciptypes.ChainSelector]ccipreader.ChainConfig{} for _, c := range inputConfig { @@ -74,16 +74,26 @@ func TestHomeChainReader(t *testing.T) { Config: mustDecodeChainConfig(t, c.ChainConfig.Config), } } - configs, err := homeChain.GetAllChainConfigs() + + configs, err := uni.HomeChainReader.GetAllChainConfigs() require.NoError(t, err) + require.Equal(t, expectedChainConfigs, configs) - //=================================Remove ChainC from OnChainConfig========================================= + + // Remove chain C from the chain configs and expect the home chain reader to + // update its state accordingly. _, err = uni.CcipCfg.ApplyChainConfigUpdates(uni.Transactor, []uint64{integrationhelpers.ChainC}, nil) require.NoError(t, err) uni.Backend.Commit() - time.Sleep(pollDuration * 5) // Wait for the chain reader to update - configs, err = homeChain.GetAllChainConfigs() + + // Wait for the home chain reader to read the expected amount of chain configs. + gomega.NewWithT(t).Eventually(func() bool { + chainConfigs, _ := uni.HomeChainReader.GetAllChainConfigs() + return len(chainConfigs) == len(inputConfig)-1 + }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue()) + configs, err = uni.HomeChainReader.GetAllChainConfigs() require.NoError(t, err) + delete(expectedChainConfigs, cciptypes.ChainSelector(integrationhelpers.ChainC)) require.Equal(t, expectedChainConfigs, configs) } diff --git a/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go b/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go index 8cafb90172..ae04da0fc1 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go @@ -111,7 +111,7 @@ func TestIntegration_OCR3Nodes(t *testing.T) { AddChainConfig(t, homeChainUni, getSelector(uni.chainID), p2pIDs, fChain) } - cfgs, err := homeChainUni.ccipConfig.GetAllChainConfigs(callCtx) + cfgs, err := homeChainUni.ccipConfig.GetAllChainConfigs(callCtx, big.NewInt(0), big.NewInt(100)) require.NoError(t, err) require.Len(t, cfgs, numChains) diff --git a/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go b/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go index 9e03f87fb0..19588a8009 100644 --- a/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go +++ b/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go @@ -61,8 +61,8 @@ type CCIPConfigTypesOCR3ConfigWithMeta struct { } var CCIPConfigMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidConfigLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"currentState\",\"type\":\"uint8\"},{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"proposedState\",\"type\":\"uint8\"}],\"name\":\"InvalidConfigStateTransition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeNotInRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonExistentConfigTransition\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"set\",\"type\":\"bytes32[]\"}],\"name\":\"NotASortedSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"subset\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"superset\",\"type\":\"bytes32[]\"}],\"name\":\"NotASubset\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"NotEnoughTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfframpAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p2pIdsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"signersLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transmittersLength\",\"type\":\"uint256\"}],\"name\":\"P2PIdsLengthNotMatching\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyBootstrapP2PIds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOCR3Configs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyTransmitters\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"}],\"name\":\"WrongConfigCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigestBlueGreen\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapabilityConfigurationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"chainSelectorRemoves\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllChainConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilityRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getOCRConfig\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"bootstrapP2PIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"internalType\":\"structCCIPConfigTypes.OCR3ConfigWithMeta[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620043d7380380620043d78339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e9576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b6080516141d6620002016000396000818160f801528181610e96015261112b01526141d66000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638318ed5d11610081578063f2fde38b1161005b578063f2fde38b14610204578063f442c89a14610217578063fba64a7c1461022a57600080fd5b80638318ed5d146101b05780638da5cb5b146101d1578063ddc042a8146101ef57600080fd5b8063181f5a77116100b2578063181f5a771461013d5780634bd0473f1461018657806379ba5097146101a657600080fd5b806301ffc9a7146100ce578063020330e6146100f6575b600080fd5b6100e16100dc366004612fbf565b61023d565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b6101796040518060400160405280601481526020017f43434950436f6e66696720312e362e302d64657600000000000000000000000081525081565b6040516100ed9190613065565b6101996101943660046130a9565b6102d6565b6040516100ed91906131d5565b6101ae6107a6565b005b6101796101be3660046133b2565b5060408051602081019091526000815290565b60005473ffffffffffffffffffffffffffffffffffffffff16610118565b6101f76108a8565b6040516100ed9190613413565b6101ae6102123660046134a3565b610a9a565b6101ae610225366004613525565b610aae565b6101ae6102383660046135a9565b610e7e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea7210000000000000000000000000000000000000000000000000000000014806102d057507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b63ffffffff82166000908152600560205260408120606091836001811115610300576103006130de565b6001811115610311576103116130de565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561079a57600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff166001811115610384576103846130de565b6001811115610395576103956130de565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916103ed90613666565b80601f016020809104026020016040519081016040528092919081815260200182805461041990613666565b80156104665780601f1061043b57610100808354040283529160200191610466565b820191906000526020600020905b81548152906001019060200180831161044957829003601f168201915b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156104be57602002820191906000526020600020905b8154815260200190600101908083116104aa575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561051657602002820191906000526020600020905b815481526020019060010190808311610502575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156105f057838290600052602060002001805461056390613666565b80601f016020809104026020016040519081016040528092919081815260200182805461058f90613666565b80156105dc5780601f106105b1576101008083540402835291602001916105dc565b820191906000526020600020905b8154815290600101906020018083116105bf57829003601f168201915b505050505081526020019060010190610544565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156106c957838290600052602060002001805461063c90613666565b80601f016020809104026020016040519081016040528092919081815260200182805461066890613666565b80156106b55780601f1061068a576101008083540402835291602001916106b5565b820191906000526020600020905b81548152906001019060200180831161069857829003601f168201915b50505050508152602001906001019061061d565b5050505081526020016006820180546106e190613666565b80601f016020809104026020016040519081016040528092919081815260200182805461070d90613666565b801561075a5780601f1061072f5761010080835404028352916020019161075a565b820191906000526020600020905b81548152906001019060200180831161073d57829003601f168201915b505050919092525050508152600782015467ffffffffffffffff16602080830191909152600890920154604090910152908252600192909201910161033f565b50505050905092915050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461082c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b606060006108b66003610f3f565b905060006108c46003610f53565b67ffffffffffffffff8111156108dc576108dc6136b9565b60405190808252806020026020018201604052801561091557816020015b610902612d50565b8152602001906001900390816108fa5790505b50905060005b8251811015610a93576000838281518110610938576109386136e8565b60209081029190910181015160408051808201825267ffffffffffffffff8316808252600090815260028552829020825181546080818802830181019095526060820181815295975092958601949093919284928491908401828280156109be57602002820191906000526020600020905b8154815260200190600101908083116109aa575b5050509183525050600182015460ff1660208201526002820180546040909201916109e890613666565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1490613666565b8015610a615780601f10610a3657610100808354040283529160200191610a61565b820191906000526020600020905b815481529060010190602001808311610a4457829003601f168201915b505050505081525050815250838381518110610a7f57610a7f6136e8565b60209081029190910101525060010161091b565b5092915050565b610aa2610f5d565b610aab81610fe0565b50565b610ab6610f5d565b60005b83811015610c9c57610afd858583818110610ad657610ad66136e8565b9050602002016020810190610aeb9190613717565b60039067ffffffffffffffff166110d5565b610b6757848482818110610b1357610b136136e8565b9050602002016020810190610b289190613717565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610823565b60026000868684818110610b7d57610b7d6136e8565b9050602002016020810190610b929190613717565b67ffffffffffffffff1681526020810191909152604001600090812090610bb98282612d98565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610bf1600283016000612db6565b5050610c2f858583818110610c0857610c086136e8565b9050602002016020810190610c1d9190613717565b60039067ffffffffffffffff166110ed565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110610c6357610c636136e8565b9050602002016020810190610c789190613717565b60405167ffffffffffffffff909116815260200160405180910390a1600101610ab9565b5060005b81811015610e77576000838383818110610cbc57610cbc6136e8565b9050602002810190610cce9190613732565b610cdc906020810190613770565b610ce590613972565b80519091506000858585818110610cfe57610cfe6136e8565b9050602002810190610d109190613732565b610d1e906020810190613717565b905060005b8251811015610d5657610d4e838281518110610d4157610d416136e8565b60200260200101516110f9565b600101610d23565b50826020015160ff16600003610d98576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120845180518693610dc8928492910190612df0565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560408201516002820190610e159082613a59565b50610e2f91506003905067ffffffffffffffff8316611212565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e08184604051610e61929190613b73565b60405180910390a1505050806001019050610ca0565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610eed576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610efb84860186613c1e565b9050600080610f098361121e565b8151919350915015610f2157610f2184600084611477565b805115610f3457610f3484600183611477565b505050505050505050565b60606000610f4c83611c58565b9392505050565b60006102d0825490565b60005473ffffffffffffffffffffffffffffffffffffffff163314610fde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610823565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361105f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610823565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515610f4c565b6000610f4c8383611cb4565b6040517f50c946fe000000000000000000000000000000000000000000000000000000008152600481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906350c946fe90602401600060405180830381865afa158015611187573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111cd9190810190613e8f565b608081015190915061120e576040517f8907a4fa00000000000000000000000000000000000000000000000000000000815260048101839052602401610823565b5050565b6000610f4c8383611da7565b606080600460ff1683511115611260576040517f8854586400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160028082526060820190925290816020015b6112e46040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161127657505060408051600280825260608201909252919350602082015b61137c6040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161130e57905050905060008060005b855181101561146a5760008682815181106113b4576113b46136e8565b60200260200101516000015160018111156113d1576113d16130de565b0361141e578581815181106113e8576113e86136e8565b6020026020010151858481518110611402576114026136e8565b60200260200101819052508261141790613f96565b9250611462565b858181518110611430576114306136e8565b602002602001015184838151811061144a5761144a6136e8565b60200260200101819052508161145f90613f96565b91505b600101611397565b5090835281529092909150565b63ffffffff831660009081526005602052604081208184600181111561149f5761149f6130de565b60018111156114b0576114b06130de565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561193957600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff166001811115611523576115236130de565b6001811115611534576115346130de565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a010000000000000000000090910416606082015260018201805460809092019161158c90613666565b80601f01602080910402602001604051908101604052809291908181526020018280546115b890613666565b80156116055780601f106115da57610100808354040283529160200191611605565b820191906000526020600020905b8154815290600101906020018083116115e857829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561165d57602002820191906000526020600020905b815481526020019060010190808311611649575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156116b557602002820191906000526020600020905b8154815260200190600101908083116116a1575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b8282101561178f57838290600052602060002001805461170290613666565b80601f016020809104026020016040519081016040528092919081815260200182805461172e90613666565b801561177b5780601f106117505761010080835404028352916020019161177b565b820191906000526020600020905b81548152906001019060200180831161175e57829003601f168201915b5050505050815260200190600101906116e3565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156118685783829060005260206000200180546117db90613666565b80601f016020809104026020016040519081016040528092919081815260200182805461180790613666565b80156118545780601f1061182957610100808354040283529160200191611854565b820191906000526020600020905b81548152906001019060200180831161183757829003601f168201915b5050505050815260200190600101906117bc565b50505050815260200160068201805461188090613666565b80601f01602080910402602001604051908101604052809291908181526020018280546118ac90613666565b80156118f95780601f106118ce576101008083540402835291602001916118f9565b820191906000526020600020905b8154815290600101906020018083116118dc57829003601f168201915b505050919092525050508152600782015467ffffffffffffffff1660208083019190915260089092015460409091015290825260019290920191016114de565b505050509050600061194b8251611df6565b905060006119598451611df6565b90506119658282611e48565b60006119748785878686611f04565b905061198084826122f0565b63ffffffff87166000908152600560205260408120908760018111156119a8576119a86130de565b60018111156119b9576119b96130de565b815260200190815260200160002060006119d39190612e3b565b60005b8151811015611c4e5763ffffffff8816600090815260056020526040812090886001811115611a0757611a076130de565b6001811115611a1857611a186130de565b8152602001908152602001600020828281518110611a3857611a386136e8565b6020908102919091018101518254600181810185556000948552929093208151805160099095029091018054929490939192849283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908381811115611aa257611aa26130de565b021790555060208201518154604084015160608501517fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90921661010067ffffffffffffffff948516027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1617690100000000000000000060ff90921691909102177fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a0100000000000000000000929091169190910217815560808201516001820190611b719082613a59565b5060a08201518051611b8d916002840191602090910190612df0565b5060c08201518051611ba9916003840191602090910190612df0565b5060e08201518051611bc5916004840191602090910190612e5c565b506101008201518051611be2916005840191602090910190612e5c565b506101208201516006820190611bf89082613a59565b50505060208201516007820180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9092169190911790556040909101516008909101556001016119d6565b5050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611ca857602002820191906000526020600020905b815481526020019060010190808311611c94575b50505050509050919050565b60008181526001830160205260408120548015611d9d576000611cd8600183613fce565b8554909150600090611cec90600190613fce565b9050808214611d51576000866000018281548110611d0c57611d0c6136e8565b9060005260206000200154905080876000018481548110611d2f57611d2f6136e8565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611d6257611d62613fe1565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506102d0565b60009150506102d0565b6000818152600183016020526040812054611dee575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556102d0565b5060006102d0565b60006002821115611e36576040517f3e47852600000000000000000000000000000000000000000000000000000000815260048101839052602401610823565b8160028111156102d0576102d06130de565b6000826002811115611e5c57611e5c6130de565b826002811115611e6e57611e6e6130de565b611e789190614010565b90508060011480611ec45750807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff148015611ec457506002836002811115611ec257611ec26130de565b145b15611ece57505050565b82826040517f0a6b675b000000000000000000000000000000000000000000000000000000008152600401610823929190614040565b60606000845167ffffffffffffffff811115611f2257611f226136b9565b604051908082528060200260200182016040528015611f4b578160200160208202803683370190505b5090506000846002811115611f6257611f626130de565b148015611f8057506001836002811115611f7e57611f7e6130de565b145b15611fc157600181600081518110611f9a57611f9a6136e8565b602002602001019067ffffffffffffffff16908167ffffffffffffffff1681525050612129565b6001846002811115611fd557611fd56130de565b148015611ff357506002836002811115611ff157611ff16130de565b145b1561208a578560008151811061200b5761200b6136e8565b6020026020010151602001518160008151811061202a5761202a6136e8565b602002602001019067ffffffffffffffff16908167ffffffffffffffff16815250508560008151811061205f5761205f6136e8565b6020026020010151602001516001612077919061405b565b81600181518110611f9a57611f9a6136e8565b600284600281111561209e5761209e6130de565b1480156120bc575060018360028111156120ba576120ba6130de565b145b156120f357856001815181106120d4576120d46136e8565b60200260200101516020015181600081518110611f9a57611f9a6136e8565b83836040517f0a6b675b000000000000000000000000000000000000000000000000000000008152600401610823929190614040565b6000855167ffffffffffffffff811115612145576121456136b9565b6040519080825280602002602001820160405280156121fb57816020015b604080516101a081018252600060608083018281526080840183905260a0840183905260c0840183905260e084018290526101008401829052610120840182905261014084018290526101608401829052610180840191909152825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816121635790505b50905060005b82518110156122e45761222c87828151811061221f5761221f6136e8565b602002602001015161266f565b6040518060600160405280888381518110612249576122496136e8565b60200260200101518152602001848381518110612268576122686136e8565b602002602001015167ffffffffffffffff1681526020016122bc8b868581518110612295576122956136e8565b60200260200101518b86815181106122af576122af6136e8565b6020026020010151612a75565b8152508282815181106122d1576122d16136e8565b6020908102919091010152600101612201565b50979650505050505050565b81518151811580156123025750806001145b156123a4578260008151811061231a5761231a6136e8565b60200260200101516020015167ffffffffffffffff1660011461239e578260008151811061234a5761234a6136e8565b60209081029190910181015101516040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260016024820152604401610823565b50505050565b8160011480156123b45750806002145b1561256a57836000815181106123cc576123cc6136e8565b602002602001015160400151836000815181106123eb576123eb6136e8565b60200260200101516040015114612477578260008151811061240f5761240f6136e8565b6020026020010151604001518460008151811061242e5761242e6136e8565b6020026020010151604001516040517fc7ccdd7f000000000000000000000000000000000000000000000000000000008152600401610823929190918252602082015260400190565b8360008151811061248a5761248a6136e8565b60200260200101516020015160016124a2919061405b565b67ffffffffffffffff16836001815181106124bf576124bf6136e8565b60200260200101516020015167ffffffffffffffff161461239e57826001815181106124ed576124ed6136e8565b6020026020010151602001518460008151811061250c5761250c6136e8565b6020026020010151602001516001612524919061405b565b6040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff928316600482015291166024820152604401610823565b81600214801561257a5750806001145b1561263d5783600181518110612592576125926136e8565b602002602001015160400151836000815181106125b1576125b16136e8565b6020026020010151604001511461239e57826000815181106125d5576125d56136e8565b602002602001015160400151846001815181106125f4576125f46136e8565b6020026020010151604001516040517f9e975670000000000000000000000000000000000000000000000000000000008152600401610823929190918252602082015260400190565b6040517f1f1b2bb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015167ffffffffffffffff166000036126b7576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815160018111156126cc576126cc6130de565b141580156126ed57506001815160018111156126ea576126ea6130de565b14155b15612724576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806080015151600003612763576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015161277e9060039067ffffffffffffffff166110d5565b6127c65760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610823565b60e081015151601f1015612806576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010081015151601f1015612847576040517f645960ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015167ffffffffffffffff166000908152600290915260408120600101546128779060ff16600361407c565b612882906001614098565b60ff169050808261010001515110156128d957610100820151516040517f548dd21f000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610823565b816040015160ff1660000361291a576040517f39d1a4d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604082015161292a90600361407c565b60ff168260e00151511161296a576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160e00151518260c001515114158061298e5750816101000151518260c001515114155b156129e95760c08201515160e083015151610100840151516040517fba900f6d000000000000000000000000000000000000000000000000000000008152600481019390935260248301919091526044820152606401610823565b8160c00151518260a00151511115612a2d576040517f8473d80700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a3f8260a001518360c00151612b4a565b60005b8260e0015151811015612a7057612a688360c001518281518110610d4157610d416136e8565b600101612a42565b505050565b60008082602001518584600001518560800151878760a001518860c001518960e001518a61010001518b604001518c606001518d6101200151604051602001612ac99c9b9a999897969594939291906140b1565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0a000000000000000000000000000000000000000000000000000000000000179150509392505050565b81511580612b5757508051155b15612b8e576040517fe249684100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b9782612cc5565b612ba081612cc5565b6000805b835182108015612bb45750825181105b15612c8657828181518110612bcb57612bcb6136e8565b6020026020010151848381518110612be557612be56136e8565b60200260200101511115612c0357612bfc81613f96565b9050612ba4565b828181518110612c1557612c156136e8565b6020026020010151848381518110612c2f57612c2f6136e8565b602002602001015103612c5057612c4582613f96565b9150612bfc81613f96565b83836040517fd671700c000000000000000000000000000000000000000000000000000000008152600401610823929190614191565b835182101561239e5783836040517fd671700c000000000000000000000000000000000000000000000000000000008152600401610823929190614191565b60015b815181101561120e5781612cdd600183613fce565b81518110612ced57612ced6136e8565b6020026020010151828281518110612d0757612d076136e8565b602002602001015111612d4857816040517f1bc41b4200000000000000000000000000000000000000000000000000000000815260040161082391906141b6565b600101612cc8565b6040518060400160405280600067ffffffffffffffff168152602001612d93604051806060016040528060608152602001600060ff168152602001606081525090565b905290565b5080546000825590600052602060002090810190610aab9190612eae565b508054612dc290613666565b6000825580601f10612dd2575050565b601f016020900490600052602060002090810190610aab9190612eae565b828054828255906000526020600020908101928215612e2b579160200282015b82811115612e2b578251825591602001919060010190612e10565b50612e37929150612eae565b5090565b5080546000825560090290600052602060002090810190610aab9190612ec3565b828054828255906000526020600020908101928215612ea2579160200282015b82811115612ea25782518290612e929082613a59565b5091602001919060010190612e7c565b50612e37929150612f84565b5b80821115612e375760008155600101612eaf565b80821115612e375780547fffffffffffffffffffffffffffff00000000000000000000000000000000000016815560008181612f026001830182612db6565b612f10600283016000612d98565b612f1e600383016000612d98565b612f2c600483016000612fa1565b612f3a600583016000612fa1565b612f48600683016000612db6565b5050506007810180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560006008820155600901612ec3565b80821115612e37576000612f988282612db6565b50600101612f84565b5080546000825590600052602060002090810190610aab9190612f84565b600060208284031215612fd157600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f4c57600080fd5b6000815180845260005b818110156130275760208185018101518683018201520161300b565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610f4c6020830184613001565b63ffffffff81168114610aab57600080fd5b803561309581613078565b919050565b80356002811061309557600080fd5b600080604083850312156130bc57600080fd5b82356130c781613078565b91506130d56020840161309a565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6002811061311d5761311d6130de565b9052565b60008151808452602080850194506020840160005b8381101561315257815187529582019590820190600101613136565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b848110156131c8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189526131b6838351613001565b9884019892509083019060010161317c565b5090979650505050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b838110156133a4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0898403018552815160608151818652613243828701825161310d565b89810151608061325e8189018367ffffffffffffffff169052565b8a830151915060a0613274818a018460ff169052565b938301519360c092506132928984018667ffffffffffffffff169052565b818401519450610140915060e082818b01526132b26101a08b0187613001565b95508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0610100818c890301818d01526132f18885613121565b97508587015195506101209350818c890301848d01526133118887613121565b9750828701519550818c890301858d015261332c888761315d565b975080870151955050808b8803016101608c015261334a878661315d565b9650828601519550808b8803016101808c0152505050505061336c8282613001565b915050888201516133888a87018267ffffffffffffffff169052565b50908701519387019390935293860193908601906001016131fe565b509098975050505050505050565b6000602082840312156133c457600080fd5b8135610f4c81613078565b60008151606084526133e46060850182613121565b905060ff60208401511660208501526040830151848203604086015261340a8282613001565b95945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b838110156133a4578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff168452870151878401879052613490878501826133cf565b958801959350509086019060010161343c565b6000602082840312156134b557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f4c57600080fd5b60008083601f8401126134eb57600080fd5b50813567ffffffffffffffff81111561350357600080fd5b6020830191508360208260051b850101111561351e57600080fd5b9250929050565b6000806000806040858703121561353b57600080fd5b843567ffffffffffffffff8082111561355357600080fd5b61355f888389016134d9565b9096509450602087013591508082111561357857600080fd5b50613585878288016134d9565b95989497509550505050565b803567ffffffffffffffff8116811461309557600080fd5b600080600080600080608087890312156135c257600080fd5b863567ffffffffffffffff808211156135da57600080fd5b6135e68a838b016134d9565b909850965060208901359150808211156135ff57600080fd5b818901915089601f83011261361357600080fd5b81358181111561362257600080fd5b8a602082850101111561363457600080fd5b60208301965080955050505061364c60408801613591565b915061365a6060880161308a565b90509295509295509295565b600181811c9082168061367a57607f821691505b6020821081036136b3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561372957600080fd5b610f4c82613591565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261376657600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261376657600080fd5b604051610140810167ffffffffffffffff811182821017156137c8576137c86136b9565b60405290565b60405160e0810167ffffffffffffffff811182821017156137c8576137c86136b9565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613838576138386136b9565b604052919050565b600067ffffffffffffffff82111561385a5761385a6136b9565b5060051b60200190565b600082601f83011261387557600080fd5b8135602061388a61388583613840565b6137f1565b8083825260208201915060208460051b8701019350868411156138ac57600080fd5b602086015b848110156138c857803583529183019183016138b1565b509695505050505050565b803560ff8116811461309557600080fd5b600082601f8301126138f557600080fd5b813567ffffffffffffffff81111561390f5761390f6136b9565b61394060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016137f1565b81815284602083860101111561395557600080fd5b816020850160208301376000918101602001919091529392505050565b60006060823603121561398457600080fd5b6040516060810167ffffffffffffffff82821081831117156139a8576139a86136b9565b8160405284359150808211156139bd57600080fd5b6139c936838701613864565b83526139d7602086016138d3565b602084015260408501359150808211156139f057600080fd5b506139fd368286016138e4565b60408301525092915050565b601f821115612a70576000816000526020600020601f850160051c81016020861015613a325750805b601f850160051c820191505b81811015613a5157828155600101613a3e565b505050505050565b815167ffffffffffffffff811115613a7357613a736136b9565b613a8781613a818454613666565b84613a09565b602080601f831160018114613ada5760008415613aa45750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613a51565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613b2757888601518255948401946001909101908401613b08565b5085821015613b6357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83168152604060208201526000613b9660408301846133cf565b949350505050565b600082601f830112613baf57600080fd5b81356020613bbf61388583613840565b82815260059290921b84018101918181019086841115613bde57600080fd5b8286015b848110156138c857803567ffffffffffffffff811115613c025760008081fd5b613c108986838b01016138e4565b845250918301918301613be2565b60006020808385031215613c3157600080fd5b823567ffffffffffffffff80821115613c4957600080fd5b818501915085601f830112613c5d57600080fd5b8135613c6b61388582613840565b81815260059190911b83018401908481019088831115613c8a57600080fd5b8585015b83811015613e1857803585811115613ca557600080fd5b8601610140818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215613cda57600080fd5b613ce26137a4565b613ced89830161309a565b8152613cfb60408301613591565b89820152613d0b606083016138d3565b6040820152613d1c60808301613591565b606082015260a082013587811115613d3357600080fd5b613d418d8b838601016138e4565b60808301525060c082013587811115613d5957600080fd5b613d678d8b83860101613864565b60a08301525060e082013587811115613d7f57600080fd5b613d8d8d8b83860101613864565b60c0830152506101008083013588811115613da757600080fd5b613db58e8c83870101613b9e565b60e0840152506101208084013589811115613dcf57600080fd5b613ddd8f8d83880101613b9e565b8385015250610140840135915088821115613df757600080fd5b613e058e8c848701016138e4565b9083015250845250918601918601613c8e565b5098975050505050505050565b805161309581613078565b600082601f830112613e4157600080fd5b81516020613e5161388583613840565b8083825260208201915060208460051b870101935086841115613e7357600080fd5b602086015b848110156138c85780518352918301918301613e78565b600060208284031215613ea157600080fd5b815167ffffffffffffffff80821115613eb957600080fd5b9083019060e08286031215613ecd57600080fd5b613ed56137ce565b613ede83613e25565b8152613eec60208401613e25565b6020820152613efd60408401613e25565b6040820152606083015160608201526080830151608082015260a083015182811115613f2857600080fd5b613f3487828601613e30565b60a08301525060c083015182811115613f4c57600080fd5b613f5887828601613e30565b60c08301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fc757613fc7613f67565b5060010190565b818103818111156102d0576102d0613f67565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8181036000831280158383131683831282161715610a9357610a93613f67565b6003811061311d5761311d6130de565b6040810161404e8285614030565b610f4c6020830184614030565b67ffffffffffffffff818116838216019080821115610a9357610a93613f67565b60ff8181168382160290811690818114610a9357610a93613f67565b60ff81811683821601908111156102d0576102d0613f67565b67ffffffffffffffff8d16815263ffffffff8c1660208201526140d7604082018c61310d565b610180606082015260006140ef61018083018c613001565b67ffffffffffffffff8b16608084015282810360a0840152614111818b613121565b905082810360c0840152614125818a613121565b905082810360e0840152614139818961315d565b905082810361010084015261414e818861315d565b60ff8716610120850152905067ffffffffffffffff851661014084015282810361016084015261417e8185613001565b9f9e505050505050505050505050505050565b6040815260006141a46040830185613121565b828103602084015261340a8185613121565b602081526000610f4c602083018461312156fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidConfigLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"currentState\",\"type\":\"uint8\"},{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"proposedState\",\"type\":\"uint8\"}],\"name\":\"InvalidConfigStateTransition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeNotInRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonExistentConfigTransition\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"set\",\"type\":\"bytes32[]\"}],\"name\":\"NotASortedSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"subset\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"superset\",\"type\":\"bytes32[]\"}],\"name\":\"NotASubset\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"NotEnoughTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfframpAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p2pIdsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"signersLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transmittersLength\",\"type\":\"uint256\"}],\"name\":\"P2PIdsLengthNotMatching\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyBootstrapP2PIds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOCR3Configs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyTransmitters\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"}],\"name\":\"WrongConfigCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigestBlueGreen\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapabilityConfigurationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"chainSelectorRemoves\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pageIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"name\":\"getAllChainConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilityRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getOCRConfig\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"bootstrapP2PIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"internalType\":\"structCCIPConfigTypes.OCR3ConfigWithMeta[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b50604051620044b7380380620044b78339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e9576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b6080516142b6620002016000396000818160f801528181610f3001526111c501526142b66000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638318ed5d11610081578063f2fde38b1161005b578063f2fde38b1461020f578063f442c89a14610222578063fba64a7c1461023557600080fd5b80638318ed5d146101b05780638da5cb5b146101d1578063b74b2356146101ef57600080fd5b8063181f5a77116100b2578063181f5a771461013d5780634bd0473f1461018657806379ba5097146101a657600080fd5b806301ffc9a7146100ce578063020330e6146100f6575b600080fd5b6100e16100dc366004613060565b610248565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b6101796040518060400160405280601481526020017f43434950436f6e66696720312e362e302d64657600000000000000000000000081525081565b6040516100ed9190613106565b61019961019436600461314a565b6102e1565b6040516100ed9190613269565b6101ae6107b1565b005b6101796101be366004613446565b5060408051602081019091526000815290565b60005473ffffffffffffffffffffffffffffffffffffffff16610118565b6102026101fd366004613463565b6108b3565b6040516100ed91906134c9565b6101ae61021d366004613559565b610b34565b6101ae6102303660046135db565b610b48565b6101ae61024336600461365f565b610f18565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea7210000000000000000000000000000000000000000000000000000000014806102db57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b63ffffffff8216600090815260056020526040812060609183600181111561030b5761030b61317f565b600181111561031c5761031c61317f565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156107a557600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff16600181111561038f5761038f61317f565b60018111156103a0576103a061317f565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916103f89061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546104249061371c565b80156104715780601f1061044657610100808354040283529160200191610471565b820191906000526020600020905b81548152906001019060200180831161045457829003601f168201915b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156104c957602002820191906000526020600020905b8154815260200190600101908083116104b5575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561052157602002820191906000526020600020905b81548152602001906001019080831161050d575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156105fb57838290600052602060002001805461056e9061371c565b80601f016020809104026020016040519081016040528092919081815260200182805461059a9061371c565b80156105e75780601f106105bc576101008083540402835291602001916105e7565b820191906000526020600020905b8154815290600101906020018083116105ca57829003601f168201915b50505050508152602001906001019061054f565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156106d45783829060005260206000200180546106479061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546106739061371c565b80156106c05780601f10610695576101008083540402835291602001916106c0565b820191906000526020600020905b8154815290600101906020018083116106a357829003601f168201915b505050505081526020019060010190610628565b5050505081526020016006820180546106ec9061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546107189061371c565b80156107655780601f1061073a57610100808354040283529160200191610765565b820191906000526020600020905b81548152906001019060200180831161074857829003601f168201915b505050919092525050508152600782015467ffffffffffffffff16602080830191909152600890920154604090910152908252600192909201910161034a565b50505050905092915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610837576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b606060006108c16003610fd9565b905060006108cf848661379e565b90508315806108de5750818110155b1561091e576040805160008082526020820190925290610914565b610901612df1565b8152602001906001900390816108f95790505b50925050506102db565b600061092a85836137e4565b9050828111156109375750815b600061094383836137f7565b67ffffffffffffffff81111561095b5761095b6137b5565b60405190808252806020026020018201604052801561099457816020015b610981612df1565b8152602001906001900390816109795790505b50905060006109a36003610fe3565b9050835b83811015610b275760008282815181106109c3576109c361380a565b60209081029190910181015160408051808201825267ffffffffffffffff831680825260009081526002855282902082518154608081880283018101909552606082018181529597509295860194909391928492849190840182828015610a4957602002820191906000526020600020905b815481526020019060010190808311610a35575b5050509183525050600182015460ff166020820152600282018054604090920191610a739061371c565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9f9061371c565b8015610aec5780601f10610ac157610100808354040283529160200191610aec565b820191906000526020600020905b815481529060010190602001808311610acf57829003601f168201915b50505091909252505050905284610b0388856137f7565b81518110610b1357610b1361380a565b6020908102919091010152506001016109a7565b5090979650505050505050565b610b3c610ff7565b610b458161107a565b50565b610b50610ff7565b60005b83811015610d3657610b97858583818110610b7057610b7061380a565b9050602002016020810190610b859190613839565b60039067ffffffffffffffff1661116f565b610c0157848482818110610bad57610bad61380a565b9050602002016020810190610bc29190613839565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161082e565b60026000868684818110610c1757610c1761380a565b9050602002016020810190610c2c9190613839565b67ffffffffffffffff1681526020810191909152604001600090812090610c538282612e39565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610c8b600283016000612e57565b5050610cc9858583818110610ca257610ca261380a565b9050602002016020810190610cb79190613839565b60039067ffffffffffffffff16611187565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110610cfd57610cfd61380a565b9050602002016020810190610d129190613839565b60405167ffffffffffffffff909116815260200160405180910390a1600101610b53565b5060005b81811015610f11576000838383818110610d5657610d5661380a565b9050602002810190610d689190613854565b610d76906020810190613892565b610d7f90613a94565b80519091506000858585818110610d9857610d9861380a565b9050602002810190610daa9190613854565b610db8906020810190613839565b905060005b8251811015610df057610de8838281518110610ddb57610ddb61380a565b6020026020010151611193565b600101610dbd565b50826020015160ff16600003610e32576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120845180518693610e62928492910190612e91565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560408201516002820190610eaf9082613b7b565b50610ec991506003905067ffffffffffffffff83166112ac565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e08184604051610efb929190613c95565b60405180910390a1505050806001019050610d3a565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610f87576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610f9584860186613d40565b9050600080610fa3836112b8565b8151919350915015610fbb57610fbb84600084611511565b805115610fce57610fce84600183611511565b505050505050505050565b60006102db825490565b60606000610ff083611cf2565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611078576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161082e565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036110f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161082e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515610ff0565b6000610ff08383611d4e565b6040517f50c946fe000000000000000000000000000000000000000000000000000000008152600481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906350c946fe90602401600060405180830381865afa158015611221573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526112679190810190613fb1565b60808101519091506112a8576040517f8907a4fa0000000000000000000000000000000000000000000000000000000081526004810183905260240161082e565b5050565b6000610ff08383611e48565b606080600460ff16835111156112fa576040517f8854586400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160028082526060820190925290816020015b61137e6040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161131057505060408051600280825260608201909252919350602082015b6114166040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b8152602001906001900390816113a857905050905060008060005b855181101561150457600086828151811061144e5761144e61380a565b602002602001015160000151600181111561146b5761146b61317f565b036114b8578581815181106114825761148261380a565b602002602001015185848151811061149c5761149c61380a565b6020026020010181905250826114b190614089565b92506114fc565b8581815181106114ca576114ca61380a565b60200260200101518483815181106114e4576114e461380a565b6020026020010181905250816114f990614089565b91505b600101611431565b5090835281529092909150565b63ffffffff83166000908152600560205260408120818460018111156115395761153961317f565b600181111561154a5761154a61317f565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156119d357600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff1660018111156115bd576115bd61317f565b60018111156115ce576115ce61317f565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916116269061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546116529061371c565b801561169f5780601f106116745761010080835404028352916020019161169f565b820191906000526020600020905b81548152906001019060200180831161168257829003601f168201915b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156116f757602002820191906000526020600020905b8154815260200190600101908083116116e3575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561174f57602002820191906000526020600020905b81548152602001906001019080831161173b575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b8282101561182957838290600052602060002001805461179c9061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546117c89061371c565b80156118155780601f106117ea57610100808354040283529160200191611815565b820191906000526020600020905b8154815290600101906020018083116117f857829003601f168201915b50505050508152602001906001019061177d565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156119025783829060005260206000200180546118759061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546118a19061371c565b80156118ee5780601f106118c3576101008083540402835291602001916118ee565b820191906000526020600020905b8154815290600101906020018083116118d157829003601f168201915b505050505081526020019060010190611856565b50505050815260200160068201805461191a9061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546119469061371c565b80156119935780601f1061196857610100808354040283529160200191611993565b820191906000526020600020905b81548152906001019060200180831161197657829003601f168201915b505050919092525050508152600782015467ffffffffffffffff166020808301919091526008909201546040909101529082526001929092019101611578565b50505050905060006119e58251611e97565b905060006119f38451611e97565b90506119ff8282611ee9565b6000611a0e8785878686611fa5565b9050611a1a8482612391565b63ffffffff8716600090815260056020526040812090876001811115611a4257611a4261317f565b6001811115611a5357611a5361317f565b81526020019081526020016000206000611a6d9190612edc565b60005b8151811015611ce85763ffffffff8816600090815260056020526040812090886001811115611aa157611aa161317f565b6001811115611ab257611ab261317f565b8152602001908152602001600020828281518110611ad257611ad261380a565b6020908102919091018101518254600181810185556000948552929093208151805160099095029091018054929490939192849283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908381811115611b3c57611b3c61317f565b021790555060208201518154604084015160608501517fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90921661010067ffffffffffffffff948516027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1617690100000000000000000060ff90921691909102177fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a0100000000000000000000929091169190910217815560808201516001820190611c0b9082613b7b565b5060a08201518051611c27916002840191602090910190612e91565b5060c08201518051611c43916003840191602090910190612e91565b5060e08201518051611c5f916004840191602090910190612efd565b506101008201518051611c7c916005840191602090910190612efd565b506101208201516006820190611c929082613b7b565b50505060208201516007820180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff909216919091179055604090910151600890910155600101611a70565b5050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611d4257602002820191906000526020600020905b815481526020019060010190808311611d2e575b50505050509050919050565b60008181526001830160205260408120548015611e37576000611d726001836137f7565b8554909150600090611d86906001906137f7565b9050808214611deb576000866000018281548110611da657611da661380a565b9060005260206000200154905080876000018481548110611dc957611dc961380a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611dfc57611dfc6140c1565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506102db565b60009150506102db565b5092915050565b6000818152600183016020526040812054611e8f575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556102db565b5060006102db565b60006002821115611ed7576040517f3e4785260000000000000000000000000000000000000000000000000000000081526004810183905260240161082e565b8160028111156102db576102db61317f565b6000826002811115611efd57611efd61317f565b826002811115611f0f57611f0f61317f565b611f1991906140f0565b90508060011480611f655750807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff148015611f6557506002836002811115611f6357611f6361317f565b145b15611f6f57505050565b82826040517f0a6b675b00000000000000000000000000000000000000000000000000000000815260040161082e929190614120565b60606000845167ffffffffffffffff811115611fc357611fc36137b5565b604051908082528060200260200182016040528015611fec578160200160208202803683370190505b50905060008460028111156120035761200361317f565b1480156120215750600183600281111561201f5761201f61317f565b145b156120625760018160008151811061203b5761203b61380a565b602002602001019067ffffffffffffffff16908167ffffffffffffffff16815250506121ca565b60018460028111156120765761207661317f565b148015612094575060028360028111156120925761209261317f565b145b1561212b57856000815181106120ac576120ac61380a565b602002602001015160200151816000815181106120cb576120cb61380a565b602002602001019067ffffffffffffffff16908167ffffffffffffffff1681525050856000815181106121005761210061380a565b6020026020010151602001516001612118919061413b565b8160018151811061203b5761203b61380a565b600284600281111561213f5761213f61317f565b14801561215d5750600183600281111561215b5761215b61317f565b145b1561219457856001815181106121755761217561380a565b6020026020010151602001518160008151811061203b5761203b61380a565b83836040517f0a6b675b00000000000000000000000000000000000000000000000000000000815260040161082e929190614120565b6000855167ffffffffffffffff8111156121e6576121e66137b5565b60405190808252806020026020018201604052801561229c57816020015b604080516101a081018252600060608083018281526080840183905260a0840183905260c0840183905260e084018290526101008401829052610120840182905261014084018290526101608401829052610180840191909152825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816122045790505b50905060005b8251811015612385576122cd8782815181106122c0576122c061380a565b6020026020010151612710565b60405180606001604052808883815181106122ea576122ea61380a565b602002602001015181526020018483815181106123095761230961380a565b602002602001015167ffffffffffffffff16815260200161235d8b8685815181106123365761233661380a565b60200260200101518b86815181106123505761235061380a565b6020026020010151612b16565b8152508282815181106123725761237261380a565b60209081029190910101526001016122a2565b50979650505050505050565b81518151811580156123a35750806001145b1561244557826000815181106123bb576123bb61380a565b60200260200101516020015167ffffffffffffffff1660011461243f57826000815181106123eb576123eb61380a565b60209081029190910181015101516040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526001602482015260440161082e565b50505050565b8160011480156124555750806002145b1561260b578360008151811061246d5761246d61380a565b6020026020010151604001518360008151811061248c5761248c61380a565b6020026020010151604001511461251857826000815181106124b0576124b061380a565b602002602001015160400151846000815181106124cf576124cf61380a565b6020026020010151604001516040517fc7ccdd7f00000000000000000000000000000000000000000000000000000000815260040161082e929190918252602082015260400190565b8360008151811061252b5761252b61380a565b6020026020010151602001516001612543919061413b565b67ffffffffffffffff16836001815181106125605761256061380a565b60200260200101516020015167ffffffffffffffff161461243f578260018151811061258e5761258e61380a565b602002602001015160200151846000815181106125ad576125ad61380a565b60200260200101516020015160016125c5919061413b565b6040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff92831660048201529116602482015260440161082e565b81600214801561261b5750806001145b156126de57836001815181106126335761263361380a565b602002602001015160400151836000815181106126525761265261380a565b6020026020010151604001511461243f57826000815181106126765761267661380a565b602002602001015160400151846001815181106126955761269561380a565b6020026020010151604001516040517f9e97567000000000000000000000000000000000000000000000000000000000815260040161082e929190918252602082015260400190565b6040517f1f1b2bb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015167ffffffffffffffff16600003612758576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008151600181111561276d5761276d61317f565b1415801561278e575060018151600181111561278b5761278b61317f565b14155b156127c5576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806080015151600003612804576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015161281f9060039067ffffffffffffffff1661116f565b6128675760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161082e565b60e081015151601f10156128a7576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010081015151601f10156128e8576040517f645960ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015167ffffffffffffffff166000908152600290915260408120600101546129189060ff16600361415c565b612923906001614178565b60ff1690508082610100015151101561297a57610100820151516040517f548dd21f00000000000000000000000000000000000000000000000000000000815260048101919091526024810182905260440161082e565b816040015160ff166000036129bb576040517f39d1a4d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516129cb90600361415c565b60ff168260e001515111612a0b576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160e00151518260c0015151141580612a2f5750816101000151518260c001515114155b15612a8a5760c08201515160e083015151610100840151516040517fba900f6d00000000000000000000000000000000000000000000000000000000815260048101939093526024830191909152604482015260640161082e565b8160c00151518260a00151511115612ace576040517f8473d80700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612ae08260a001518360c00151612beb565b60005b8260e0015151811015612b1157612b098360c001518281518110610ddb57610ddb61380a565b600101612ae3565b505050565b60008082602001518584600001518560800151878760a001518860c001518960e001518a61010001518b604001518c606001518d6101200151604051602001612b6a9c9b9a99989796959493929190614191565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0a000000000000000000000000000000000000000000000000000000000000179150509392505050565b81511580612bf857508051155b15612c2f576040517fe249684100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c3882612d66565b612c4181612d66565b6000805b835182108015612c555750825181105b15612d2757828181518110612c6c57612c6c61380a565b6020026020010151848381518110612c8657612c8661380a565b60200260200101511115612ca457612c9d81614089565b9050612c45565b828181518110612cb657612cb661380a565b6020026020010151848381518110612cd057612cd061380a565b602002602001015103612cf157612ce682614089565b9150612c9d81614089565b83836040517fd671700c00000000000000000000000000000000000000000000000000000000815260040161082e929190614271565b835182101561243f5783836040517fd671700c00000000000000000000000000000000000000000000000000000000815260040161082e929190614271565b60015b81518110156112a85781612d7e6001836137f7565b81518110612d8e57612d8e61380a565b6020026020010151828281518110612da857612da861380a565b602002602001015111612de957816040517f1bc41b4200000000000000000000000000000000000000000000000000000000815260040161082e9190614296565b600101612d69565b6040518060400160405280600067ffffffffffffffff168152602001612e34604051806060016040528060608152602001600060ff168152602001606081525090565b905290565b5080546000825590600052602060002090810190610b459190612f4f565b508054612e639061371c565b6000825580601f10612e73575050565b601f016020900490600052602060002090810190610b459190612f4f565b828054828255906000526020600020908101928215612ecc579160200282015b82811115612ecc578251825591602001919060010190612eb1565b50612ed8929150612f4f565b5090565b5080546000825560090290600052602060002090810190610b459190612f64565b828054828255906000526020600020908101928215612f43579160200282015b82811115612f435782518290612f339082613b7b565b5091602001919060010190612f1d565b50612ed8929150613025565b5b80821115612ed85760008155600101612f50565b80821115612ed85780547fffffffffffffffffffffffffffff00000000000000000000000000000000000016815560008181612fa36001830182612e57565b612fb1600283016000612e39565b612fbf600383016000612e39565b612fcd600483016000613042565b612fdb600583016000613042565b612fe9600683016000612e57565b5050506007810180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560006008820155600901612f64565b80821115612ed85760006130398282612e57565b50600101613025565b5080546000825590600052602060002090810190610b459190613025565b60006020828403121561307257600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ff057600080fd5b6000815180845260005b818110156130c8576020818501810151868301820152016130ac565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610ff060208301846130a2565b63ffffffff81168114610b4557600080fd5b803561313681613119565b919050565b80356002811061313657600080fd5b6000806040838503121561315d57600080fd5b823561316881613119565b91506131766020840161313b565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106131be576131be61317f565b9052565b60008151808452602080850194506020840160005b838110156131f3578151875295820195908201906001016131d7565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015610b27577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189526132578383516130a2565b9884019892509083019060010161321d565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015613438577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08984030185528151606081518186526132d782870182516131ae565b8981015160806132f28189018367ffffffffffffffff169052565b8a830151915060a0613308818a018460ff169052565b938301519360c092506133268984018667ffffffffffffffff169052565b818401519450610140915060e082818b01526133466101a08b01876130a2565b95508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0610100818c890301818d015261338588856131c2565b97508587015195506101209350818c890301848d01526133a588876131c2565b9750828701519550818c890301858d01526133c088876131fe565b975080870151955050808b8803016101608c01526133de87866131fe565b9650828601519550808b8803016101808c0152505050505061340082826130a2565b9150508882015161341c8a87018267ffffffffffffffff169052565b5090870151938701939093529386019390860190600101613292565b509098975050505050505050565b60006020828403121561345857600080fd5b8135610ff081613119565b6000806040838503121561347657600080fd5b50508035926020909101359150565b600081516060845261349a60608501826131c2565b905060ff6020840151166020850152604083015184820360408601526134c082826130a2565b95945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015613438578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff16845287015187840187905261354687850182613485565b95880195935050908601906001016134f2565b60006020828403121561356b57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610ff057600080fd5b60008083601f8401126135a157600080fd5b50813567ffffffffffffffff8111156135b957600080fd5b6020830191508360208260051b85010111156135d457600080fd5b9250929050565b600080600080604085870312156135f157600080fd5b843567ffffffffffffffff8082111561360957600080fd5b6136158883890161358f565b9096509450602087013591508082111561362e57600080fd5b5061363b8782880161358f565b95989497509550505050565b803567ffffffffffffffff8116811461313657600080fd5b6000806000806000806080878903121561367857600080fd5b863567ffffffffffffffff8082111561369057600080fd5b61369c8a838b0161358f565b909850965060208901359150808211156136b557600080fd5b818901915089601f8301126136c957600080fd5b8135818111156136d857600080fd5b8a60208285010111156136ea57600080fd5b60208301965080955050505061370260408801613647565b91506137106060880161312b565b90509295509295509295565b600181811c9082168061373057607f821691505b602082108103613769577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176102db576102db61376f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b808201808211156102db576102db61376f565b818103818111156102db576102db61376f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561384b57600080fd5b610ff082613647565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261388857600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261388857600080fd5b604051610140810167ffffffffffffffff811182821017156138ea576138ea6137b5565b60405290565b60405160e0810167ffffffffffffffff811182821017156138ea576138ea6137b5565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561395a5761395a6137b5565b604052919050565b600067ffffffffffffffff82111561397c5761397c6137b5565b5060051b60200190565b600082601f83011261399757600080fd5b813560206139ac6139a783613962565b613913565b8083825260208201915060208460051b8701019350868411156139ce57600080fd5b602086015b848110156139ea57803583529183019183016139d3565b509695505050505050565b803560ff8116811461313657600080fd5b600082601f830112613a1757600080fd5b813567ffffffffffffffff811115613a3157613a316137b5565b613a6260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613913565b818152846020838601011115613a7757600080fd5b816020850160208301376000918101602001919091529392505050565b600060608236031215613aa657600080fd5b6040516060810167ffffffffffffffff8282108183111715613aca57613aca6137b5565b816040528435915080821115613adf57600080fd5b613aeb36838701613986565b8352613af9602086016139f5565b60208401526040850135915080821115613b1257600080fd5b50613b1f36828601613a06565b60408301525092915050565b601f821115612b11576000816000526020600020601f850160051c81016020861015613b545750805b601f850160051c820191505b81811015613b7357828155600101613b60565b505050505050565b815167ffffffffffffffff811115613b9557613b956137b5565b613ba981613ba3845461371c565b84613b2b565b602080601f831160018114613bfc5760008415613bc65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b73565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613c4957888601518255948401946001909101908401613c2a565b5085821015613c8557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83168152604060208201526000613cb86040830184613485565b949350505050565b600082601f830112613cd157600080fd5b81356020613ce16139a783613962565b82815260059290921b84018101918181019086841115613d0057600080fd5b8286015b848110156139ea57803567ffffffffffffffff811115613d245760008081fd5b613d328986838b0101613a06565b845250918301918301613d04565b60006020808385031215613d5357600080fd5b823567ffffffffffffffff80821115613d6b57600080fd5b818501915085601f830112613d7f57600080fd5b8135613d8d6139a782613962565b81815260059190911b83018401908481019088831115613dac57600080fd5b8585015b83811015613f3a57803585811115613dc757600080fd5b8601610140818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215613dfc57600080fd5b613e046138c6565b613e0f89830161313b565b8152613e1d60408301613647565b89820152613e2d606083016139f5565b6040820152613e3e60808301613647565b606082015260a082013587811115613e5557600080fd5b613e638d8b83860101613a06565b60808301525060c082013587811115613e7b57600080fd5b613e898d8b83860101613986565b60a08301525060e082013587811115613ea157600080fd5b613eaf8d8b83860101613986565b60c0830152506101008083013588811115613ec957600080fd5b613ed78e8c83870101613cc0565b60e0840152506101208084013589811115613ef157600080fd5b613eff8f8d83880101613cc0565b8385015250610140840135915088821115613f1957600080fd5b613f278e8c84870101613a06565b9083015250845250918601918601613db0565b5098975050505050505050565b805161313681613119565b600082601f830112613f6357600080fd5b81516020613f736139a783613962565b8083825260208201915060208460051b870101935086841115613f9557600080fd5b602086015b848110156139ea5780518352918301918301613f9a565b600060208284031215613fc357600080fd5b815167ffffffffffffffff80821115613fdb57600080fd5b9083019060e08286031215613fef57600080fd5b613ff76138f0565b61400083613f47565b815261400e60208401613f47565b602082015261401f60408401613f47565b6040820152606083015160608201526080830151608082015260a08301518281111561404a57600080fd5b61405687828601613f52565b60a08301525060c08301518281111561406e57600080fd5b61407a87828601613f52565b60c08301525095945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140ba576140ba61376f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8181036000831280158383131683831282161715611e4157611e4161376f565b600381106131be576131be61317f565b6040810161412e8285614110565b610ff06020830184614110565b67ffffffffffffffff818116838216019080821115611e4157611e4161376f565b60ff8181168382160290811690818114611e4157611e4161376f565b60ff81811683821601908111156102db576102db61376f565b67ffffffffffffffff8d16815263ffffffff8c1660208201526141b7604082018c6131ae565b610180606082015260006141cf61018083018c6130a2565b67ffffffffffffffff8b16608084015282810360a08401526141f1818b6131c2565b905082810360c0840152614205818a6131c2565b905082810360e084015261421981896131fe565b905082810361010084015261422e81886131fe565b60ff8716610120850152905067ffffffffffffffff851661014084015282810361016084015261425e81856130a2565b9f9e505050505050505050505050505050565b60408152600061428460408301856131c2565b82810360208401526134c081856131c2565b602081526000610ff060208301846131c256fea164736f6c6343000818000a", } var CCIPConfigABI = CCIPConfigMetaData.ABI @@ -201,9 +201,9 @@ func (_CCIPConfig *CCIPConfigTransactorRaw) Transact(opts *bind.TransactOpts, me return _CCIPConfig.Contract.contract.Transact(opts, method, params...) } -func (_CCIPConfig *CCIPConfigCaller) GetAllChainConfigs(opts *bind.CallOpts) ([]CCIPConfigTypesChainConfigInfo, error) { +func (_CCIPConfig *CCIPConfigCaller) GetAllChainConfigs(opts *bind.CallOpts, pageIndex *big.Int, pageSize *big.Int) ([]CCIPConfigTypesChainConfigInfo, error) { var out []interface{} - err := _CCIPConfig.contract.Call(opts, &out, "getAllChainConfigs") + err := _CCIPConfig.contract.Call(opts, &out, "getAllChainConfigs", pageIndex, pageSize) if err != nil { return *new([]CCIPConfigTypesChainConfigInfo), err @@ -215,12 +215,12 @@ func (_CCIPConfig *CCIPConfigCaller) GetAllChainConfigs(opts *bind.CallOpts) ([] } -func (_CCIPConfig *CCIPConfigSession) GetAllChainConfigs() ([]CCIPConfigTypesChainConfigInfo, error) { - return _CCIPConfig.Contract.GetAllChainConfigs(&_CCIPConfig.CallOpts) +func (_CCIPConfig *CCIPConfigSession) GetAllChainConfigs(pageIndex *big.Int, pageSize *big.Int) ([]CCIPConfigTypesChainConfigInfo, error) { + return _CCIPConfig.Contract.GetAllChainConfigs(&_CCIPConfig.CallOpts, pageIndex, pageSize) } -func (_CCIPConfig *CCIPConfigCallerSession) GetAllChainConfigs() ([]CCIPConfigTypesChainConfigInfo, error) { - return _CCIPConfig.Contract.GetAllChainConfigs(&_CCIPConfig.CallOpts) +func (_CCIPConfig *CCIPConfigCallerSession) GetAllChainConfigs(pageIndex *big.Int, pageSize *big.Int) ([]CCIPConfigTypesChainConfigInfo, error) { + return _CCIPConfig.Contract.GetAllChainConfigs(&_CCIPConfig.CallOpts, pageIndex, pageSize) } func (_CCIPConfig *CCIPConfigCaller) GetCapabilityConfiguration(opts *bind.CallOpts, arg0 uint32) ([]byte, error) { @@ -1069,7 +1069,7 @@ func (_CCIPConfig *CCIPConfig) Address() common.Address { } type CCIPConfigInterface interface { - GetAllChainConfigs(opts *bind.CallOpts) ([]CCIPConfigTypesChainConfigInfo, error) + GetAllChainConfigs(opts *bind.CallOpts, pageIndex *big.Int, pageSize *big.Int) ([]CCIPConfigTypesChainConfigInfo, error) GetCapabilityConfiguration(opts *bind.CallOpts, arg0 uint32) ([]byte, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index ce0b93fe4e..1a3dceeaeb 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -6,7 +6,7 @@ burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMint burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 717c079d5d13300cf3c3ee871c6e5bf9af904411f204fb081a9f3b263cca1391 burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6333d0314d0bd29e75ea5e05fe62a4516ade0c6db91c30b6f93645035db52ed8 burn_with_from_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin 08ed1235dda921ce8841b26aa18d0c0f36db4884779dd7670857159801b6d597 -ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin a92a9ae55b235f47ac58af942e43a20dc7df31cfba9178c133e5b3e273816503 +ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 213d4adc8634671aea16fb4207989375b1aac919b04d608f4767c29592affbf5 ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin fcced2263564f51b5bf086c221e813ec06a71d2bb2e246b4e28cd60098a6de6f commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin 274d87db70b643e00ab0a7e7845bb4b791f3b613bfc87708d33fc5a8369e2a41 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin f7128dcc2ee6dbcbc976288abcc16970ffb19b59412c5202ef6b259d2007f801 diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 7848a1dade..13ed1c4aa9 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -274,7 +274,7 @@ require ( github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index e3cf65c26a..468c13a670 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -568,8 +568,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= -github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -1070,8 +1070,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f h1:sxBPgtGeqJ3h3+JgF6N3wwr4xgy9wLbBIjFVVn6mMCs= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f h1:lQZBOjeYFpCdk0mGQUhbrJipd00tu49xK4zSijC/9Co= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/go.mod b/go.mod index 8ca696860f..683793cb53 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa @@ -224,7 +224,6 @@ require ( github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/googleapis/gax-go/v2 v2.12.2 // indirect github.com/gorilla/context v1.1.1 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect diff --git a/go.sum b/go.sum index bb7deba816..5ad6772ecd 100644 --- a/go.sum +++ b/go.sum @@ -533,8 +533,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= -github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -1027,8 +1027,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f h1:sxBPgtGeqJ3h3+JgF6N3wwr4xgy9wLbBIjFVVn6mMCs= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f h1:lQZBOjeYFpCdk0mGQUhbrJipd00tu49xK4zSijC/9Co= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 5571e0c2dc..fd00d2c7ad 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -35,7 +35,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240814100759-a12828c40ddb + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 github.com/smartcontractkit/chainlink-testing-framework v1.33.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 0628afe4e4..dacfa7764e 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1378,8 +1378,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f h1:sxBPgtGeqJ3h3+JgF6N3wwr4xgy9wLbBIjFVVn6mMCs= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f h1:lQZBOjeYFpCdk0mGQUhbrJipd00tu49xK4zSijC/9Co= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= @@ -1392,8 +1392,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.32.7 h1:/I6Upq9KdnleWnUF1W3c3mAgMowAgi0yAcn8Vh5Px50= -github.com/smartcontractkit/chainlink-testing-framework v1.32.7/go.mod h1:Y1D6k7KLPZ52kwp3WJxShp4Wzw22jKldIzMT2yosipI= +github.com/smartcontractkit/chainlink-testing-framework v1.33.0 h1:vHQODEdsq5AIbRiyZZ30de6uwJUNFXLYvCr+Odr8TIs= +github.com/smartcontractkit/chainlink-testing-framework v1.33.0/go.mod h1:GrhHthZ5AmceF82+Ypw6Fov1EvB05JJbb1T0EKyO1x0= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index d540449f8c..a90826f599 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,7 +17,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 - github.com/smartcontractkit/chainlink-testing-framework v1.32.7 + github.com/smartcontractkit/chainlink-testing-framework v1.33.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 @@ -41,7 +41,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/testcontainers/testcontainers-go v0.28.0 // indirect k8s.io/apimachinery v0.30.2 // indirect @@ -478,7 +478,7 @@ require ( k8s.io/component-base v0.30.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect - k8s.io/kubectl v0.28.1 // indirect + k8s.io/kubectl v0.28.2 // indirect k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect nhooyr.io/websocket v1.8.10 // indirect pgregory.net/rapid v1.1.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 18e05c9047..536b96f8b6 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1358,8 +1358,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f h1:sxBPgtGeqJ3h3+JgF6N3wwr4xgy9wLbBIjFVVn6mMCs= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240813153644-0117f0e6569f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f h1:lQZBOjeYFpCdk0mGQUhbrJipd00tu49xK4zSijC/9Co= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= @@ -1372,8 +1372,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.32.7 h1:/I6Upq9KdnleWnUF1W3c3mAgMowAgi0yAcn8Vh5Px50= -github.com/smartcontractkit/chainlink-testing-framework v1.32.7/go.mod h1:Y1D6k7KLPZ52kwp3WJxShp4Wzw22jKldIzMT2yosipI= +github.com/smartcontractkit/chainlink-testing-framework v1.33.0 h1:vHQODEdsq5AIbRiyZZ30de6uwJUNFXLYvCr+Odr8TIs= +github.com/smartcontractkit/chainlink-testing-framework v1.33.0/go.mod h1:GrhHthZ5AmceF82+Ypw6Fov1EvB05JJbb1T0EKyO1x0= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= From 8f7bfc58bf70c0a8b1156f73108f052abf8cc257 Mon Sep 17 00:00:00 2001 From: kanth <70688600+defistar@users.noreply.github.com> Date: Mon, 19 Aug 2024 18:13:34 +0530 Subject: [PATCH 213/432] =?UTF-8?q?feat:=20CCIP-1451=20gasUsed=20for=20Exe?= =?UTF-8?q?cution=20to=20be=20emitted=20along=20with=20Execut=E2=80=A6=20(?= =?UTF-8?q?#1310)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Motivation gasUsed for Execution to be emitted along with ExecutionStateChangedEvent ## Solution compute `gasUsed` for execution of a message in EVM2EVMMultiOffRamp this change is applicable to only 1.6 version Test Assertion must be added to assert the event body parameters (excluding the gasUsed as it cant be hardcoded in tests) ** This is extension of the closed PR: https://github.com/smartcontractkit/ccip/pull/1297 got signature verification issue with other PR. so moving all changes over here --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> Co-authored-by: Ryan <80392855+RayXpub@users.noreply.github.com> --- contracts/gas-snapshots/ccip.gas-snapshot | 238 +++++------ .../v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol | 11 +- .../src/v0.8/ccip/test/NonceManager.t.sol | 64 +-- .../v0.8/ccip/test/e2e/MultiRampsEnd2End.sol | 24 +- .../test/offRamp/EVM2EVMMultiOffRamp.t.sol | 369 +++++++++--------- .../offRamp/EVM2EVMMultiOffRampSetup.t.sol | 28 ++ .../evm_2_evm_multi_offramp.go | 7 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 8 files changed, 389 insertions(+), 354 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 40d9e2e4f3..e1b2d6d5b3 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -125,11 +125,11 @@ DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424256) E2E:test_E2E_3MessagesSuccess_gas() (gas: 1104304) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38416) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 106228) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 87399) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 38936) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 96493) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 41942) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 106250) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 87421) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 38958) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 96515) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 41964) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 88684) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 468131) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99235) @@ -139,123 +139,123 @@ EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Succ EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13267) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17992) EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15347) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 296045) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 237435) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 156797) -EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 186971) -EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 145389) -EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 518163) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 313594) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 254984) +EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 166123) +EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187729) +EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 153140) +EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 518887) EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10439) -EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15662) -EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67354) -EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59644) -EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58724) -EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6524844) -EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 6107982) -EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106189) -EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116101) -EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106210) -EVM2EVMMultiOffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351423) -EVM2EVMMultiOffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159331) -EVM2EVMMultiOffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136449) -EVM2EVMMultiOffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136723) -EVM2EVMMultiOffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 58992) -EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225643) -EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117476) -EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77540) -EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 204935) -EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6519167) -EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47720) -EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 6112038) -EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137047) -EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103764) -EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101635) -EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139621) -EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101534) -EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101579) -EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17302) -EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1552289) -EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 339279) -EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 257679) -EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6575240) -EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6158119) -EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 27703) -EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 163020) -EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 146998) -EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6937292) -EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17155) -EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18208) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 246578) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20468) -EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 205217) -EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48730) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48253) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229582) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86220) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 277454) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92454) -EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35122) +EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15688) +EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67458) +EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59734) +EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58814) +EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6538150) +EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 6121222) +EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106251) +EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116259) +EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106272) +EVM2EVMMultiOffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351586) +EVM2EVMMultiOffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159364) +EVM2EVMMultiOffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136569) +EVM2EVMMultiOffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136859) +EVM2EVMMultiOffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 59082) +EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225772) +EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117566) +EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77608) +EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 205117) +EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6532473) +EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47788) +EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 6125452) +EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137067) +EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103784) +EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101677) +EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139641) +EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101554) +EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101599) +EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17261) +EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1726826) +EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 349476) +EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 276933) +EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6588848) +EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6171682) +EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 27733) +EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 172458) +EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147390) +EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6950922) +EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17159) +EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18190) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 246556) +EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20472) +EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 205195) +EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48734) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48257) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229631) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86202) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 277436) +EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92436) +EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35126) EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23922) -EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 454064) -EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54442) -EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35911) -EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154354) -EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35333) -EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 179190) -EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 190474) -EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48069) -EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 440867) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 249448) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 171640) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 191313) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259405) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 127402) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 388971) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65866) -EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80906) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 532020) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 476978) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35738) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 516997) -EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 514365) -EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 484483) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 125831) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 155054) -EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3655340) -EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118202) -EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87461) -EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75627) -EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26467) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 162919) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205055) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26010) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152936) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 505158) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2282792) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 207311) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 207888) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 656902) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 298803) +EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 475599) +EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54456) +EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35904) +EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154426) +EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35337) +EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 184865) +EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 196122) +EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48073) +EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 444686) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 250335) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 187191) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 206771) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 263519) +EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 138408) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 409328) +EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65876) +EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80909) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 566299) +EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 517689) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35742) +EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 517721) +EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 515089) +EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 485207) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 133513) +EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 162713) +EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3677612) +EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118399) +EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87606) +EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75635) +EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26471) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 168604) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205435) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26014) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152948) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 518487) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2295740) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 208322) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 208944) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 662979) +EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 301931) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 164054) EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 23740) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 64488) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 39546) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 39524) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 81512) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 176140) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 189342) EVM2EVMMultiOffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11379) -EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215352) -EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14162) +EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215398) +EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14140) EVM2EVMMultiOffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11660) EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49203) -EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27169) -EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 221696) -EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 230297) -EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 297256) -EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 279894) -EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176552) -EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178620) -EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141481) +EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27147) +EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 221780) +EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 230403) +EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 297574) +EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 279978) +EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176620) +EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178688) +EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141549) EVM2EVMMultiOffRamp_verify:test_TooManyLeaves_Revert() (gas: 51510) EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 63649) EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() (gas: 13308) @@ -613,18 +613,18 @@ MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 393335) -MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1384852) +MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1448084) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71847) -NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 249533) -NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 251724) -NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 304493) -NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 287566) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244824) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 233144) -NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 142547) +NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 257252) +NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 259369) +NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 319959) +NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 295278) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244940) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 233260) +NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 150148) NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 167625) NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 218724) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol index 8a5cb1fdc2..6a6fb10be1 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol @@ -68,7 +68,8 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { uint64 indexed sequenceNumber, bytes32 indexed messageId, Internal.MessageExecutionState state, - bytes returnData + bytes returnData, + uint256 gasUsed ); event SourceChainSelectorAdded(uint64 sourceChainSelector); event SourceChainConfigSet(uint64 indexed sourceChainSelector, SourceChainConfig sourceConfig); @@ -372,6 +373,7 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { // Execute messages bool manualExecution = manualExecGasLimits.length != 0; for (uint256 i = 0; i < numMsgs; ++i) { + uint256 gasStart = gasleft(); Internal.Any2EVMRampMessage memory message = report.messages[i]; Internal.MessageExecutionState originalState = @@ -465,7 +467,12 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { } emit ExecutionStateChanged( - sourceChainSelector, message.header.sequenceNumber, message.header.messageId, newState, returnData + sourceChainSelector, + message.header.sequenceNumber, + message.header.messageId, + newState, + returnData, + gasStart - gasleft() ); } } diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol index 012a3168c2..444329220d 100644 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -397,16 +397,16 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { function test_Upgraded_Success() public { Internal.Any2EVMRampMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + + vm.recordLogs(); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); } function test_NoPrevOffRampForChain_Success() public { @@ -425,8 +425,13 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { Internal.Any2EVMRampMessage[] memory messagesChain3 = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_3, ON_RAMP_ADDRESS_3); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + + vm.recordLogs(); + + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messagesChain3), new uint256[](0) + ); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_3, messagesChain3[0].header.sequenceNumber, messagesChain3[0].header.messageId, @@ -434,9 +439,6 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { "" ); - s_offRamp.executeSingleReport( - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messagesChain3), new uint256[](0) - ); assertEq( startNonceChain3 + 1, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, messagesChain3[0].sender) ); @@ -504,8 +506,13 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { messagesMultiRamp[0].header.nonce++; messagesMultiRamp[0].header.messageId = Internal._hash(messagesMultiRamp[0], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + vm.recordLogs(); + + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new uint256[](0) + ); + + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].header.sequenceNumber, messagesMultiRamp[0].header.messageId, @@ -513,9 +520,6 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { "" ); - s_offRamp.executeSingleReport( - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new uint256[](0) - ); assertEq( startNonce + 2, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].sender) ); @@ -524,8 +528,11 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { messagesMultiRamp[0].header.sequenceNumber++; messagesMultiRamp[0].header.messageId = Internal._hash(messagesMultiRamp[0], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + vm.recordLogs(); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new uint256[](0) + ); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].header.sequenceNumber, messagesMultiRamp[0].header.messageId, @@ -533,9 +540,6 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { "" ); - s_offRamp.executeSingleReport( - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new uint256[](0) - ); assertEq( startNonce + 3, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].sender) ); @@ -556,20 +560,19 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { messagesMultiRamp[0].sender = newSender; messagesMultiRamp[0].header.messageId = Internal._hash(messagesMultiRamp[0], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + // new sender nonce in new offramp should go from 0 -> 1 + assertEq(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, newSender), 0); + vm.recordLogs(); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new uint256[](0) + ); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].header.sequenceNumber, messagesMultiRamp[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - // new sender nonce in new offramp should go from 0 -> 1 - assertEq(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, newSender), 0); - s_offRamp.executeSingleReport( - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new uint256[](0) - ); assertEq(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, newSender), 1); } @@ -611,16 +614,15 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); // new offramp is able to execute - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + vm.recordLogs(); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); assertEq(startNonce + 2, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender)); } diff --git a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol index 68c6f9d5ff..806b133371 100644 --- a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol +++ b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol @@ -173,8 +173,15 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { vm.warp(BLOCK_TIME + 2000); // Execute - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); + reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR, messages1); + reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR + 1, messages2); + + vm.resumeGasMetering(); + vm.recordLogs(); + _execute(reports); + + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR, messages1[0].header.sequenceNumber, messages1[0].header.messageId, @@ -182,8 +189,7 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { "" ); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR, messages1[1].header.sequenceNumber, messages1[1].header.messageId, @@ -191,21 +197,13 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { "" ); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR + 1, messages2[0].header.sequenceNumber, messages2[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); - reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR, messages1); - reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR + 1, messages2); - - vm.resumeGasMetering(); - _execute(reports); } function _sendRequest( diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol index 0cd46c1e5f..cfe43a972f 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol @@ -354,8 +354,10 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { function test_SingleMessageNoTokens_Success() public { Internal.Any2EVMRampMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + + vm.recordLogs(); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -363,23 +365,20 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { "" ); - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); - messages[0].header.nonce++; messages[0].header.sequenceNumber++; messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); + vm.recordLogs(); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); assertGt(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender), nonceBefore); } @@ -389,8 +388,11 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[0].header.nonce = 0; messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + // Nonce never increments on unordered messages. + uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); + vm.recordLogs(); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -398,9 +400,6 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { "" ); - // Nonce never increments on unordered messages. - uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); assertEq( s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender), nonceBefore, @@ -410,18 +409,17 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[0].header.sequenceNumber++; messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + // Nonce never increments on unordered messages. + nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); + vm.recordLogs(); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - // Nonce never increments on unordered messages. - nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); assertEq( s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender), nonceBefore, @@ -464,8 +462,11 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[0].receiver = address(s_reverting_receiver); messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + // Nonce should increment on non-strict + assertEq(uint64(0), s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER))); + vm.recordLogs(); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -475,9 +476,6 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, realError1) ) ); - // Nonce should increment on non-strict - assertEq(uint64(0), s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER))); - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); assertEq(uint64(1), s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER))); } @@ -504,35 +502,33 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[1].header.messageId = Internal._hash(messages[1], ON_RAMP_ADDRESS_1); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( - SOURCE_CHAIN_SELECTOR_1, + emit NonceManager.SkippedIncorrectNonce(SOURCE_CHAIN_SELECTOR_1, messages[1].header.nonce, messages[1].sender); + + vm.recordLogs(); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( + messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - vm.expectEmit(); - emit NonceManager.SkippedIncorrectNonce(SOURCE_CHAIN_SELECTOR_1, messages[1].header.nonce, messages[1].sender); - - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); } function test__execute_SkippedAlreadyExecutedMessage_Success() public { Internal.Any2EVMRampMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( - messages[0].header.sourceChainSelector, + vm.recordLogs(); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( + SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); - vm.expectEmit(); emit EVM2EVMMultiOffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); @@ -545,17 +541,16 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[0].header.nonce = 0; messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( - messages[0].header.sourceChainSelector, + vm.recordLogs(); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( + SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); - vm.expectEmit(); emit EVM2EVMMultiOffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); @@ -571,16 +566,15 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[0].receiver = address(newReceiver); messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + vm.recordLogs(); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); } function test_SingleMessagesNoTokensSuccess_gas() public { @@ -588,19 +582,18 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { Internal.Any2EVMRampMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + vm.resumeGasMetering(); + vm.recordLogs(); + s_offRamp.executeSingleReport(report, new uint256[](0)); + assertExecutionStateChangedEventLogs( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); - - vm.resumeGasMetering(); - s_offRamp.executeSingleReport(report, new uint256[](0)); } function test_TwoMessagesWithTokensSuccess_gas() public { @@ -611,8 +604,12 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[1].receiver = address(s_secondary_receiver); messages[1].header.messageId = Internal._hash(messages[1], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); + + vm.resumeGasMetering(); + vm.recordLogs(); + s_offRamp.executeSingleReport(report, new uint256[](0)); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -620,19 +617,13 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { "" ); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[1].header.sequenceNumber, messages[1].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - Internal.ExecutionReportSingleChain memory report = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); - - vm.resumeGasMetering(); - s_offRamp.executeSingleReport(report, new uint256[](0)); } function test_TwoMessagesWithTokensAndGE_Success() public { @@ -642,28 +633,26 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[1].receiver = address(s_secondary_receiver); messages[1].header.messageId = Internal._hash(messages[1], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertEq(uint64(0), s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER))); + + vm.recordLogs(); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), _getGasLimitsFromMessages(messages) + ); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[1].header.sequenceNumber, messages[1].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - assertEq(uint64(0), s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER))); - s_offRamp.executeSingleReport( - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), _getGasLimitsFromMessages(messages) - ); assertEq(uint64(2), s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER))); } @@ -676,6 +665,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { tokenAmounts[i].amount = 1e18; } uint64 expectedNonce = 0; + for (uint256 i = 0; i < orderings.length; ++i) { messages[i] = _generateAny2EVMMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, uint64(i + 1), tokenAmounts, !orderings[i]); @@ -684,13 +674,14 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { } messages[i].header.messageId = Internal._hash(messages[i], ON_RAMP_ADDRESS_1); - vm.expectEmit(); + vm.expectEmit(true, true, true, false); emit EVM2EVMMultiOffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages[i].header.sequenceNumber, messages[i].header.messageId, Internal.MessageExecutionState.SUCCESS, - "" + "", + 0 ); } @@ -721,8 +712,10 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); messages[1].header.messageId = Internal._hash(messages[1], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + vm.recordLogs(); + + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -732,8 +725,6 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { abi.encodeWithSelector(TokenPool.InvalidSourcePoolAddress.selector, abi.encode(fakePoolAddress)) ) ); - - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); } function test_WithCurseOnAnotherSourceChain_Success() public { @@ -915,15 +906,15 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { Internal.ExecutionReportSingleChain memory executionReport = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + vm.recordLogs(); + s_offRamp.executeSingleReport(executionReport, new uint256[](0)); + assertExecutionStateChangedEventLogs( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector(CallWithExactGas.NotEnoughGasForCall.selector) ); - s_offRamp.executeSingleReport(executionReport, new uint256[](0)); } function test_RetryFailedMessageWithoutManualExecution_Revert() public { @@ -938,8 +929,9 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[0].receiver = address(s_reverting_receiver); messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + vm.recordLogs(); + s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); + assertExecutionStateChangedEventLogs( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -949,7 +941,6 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, realError1) ) ); - s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); // The second time should skip the msg vm.expectEmit(); @@ -1131,8 +1122,12 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { function test_SingleReport_Success() public { Internal.Any2EVMRampMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + + uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); + + vm.recordLogs(); + s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); + assertExecutionStateChangedEventLogs( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -1140,9 +1135,6 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { "" ); - uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); - s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); - assertGt(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender), nonceBefore); } @@ -1158,8 +1150,10 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages1); reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages2); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages1[0].sender); + vm.recordLogs(); + s_offRamp.batchExecute(reports, new uint256[][](2)); + assertExecutionStateChangedEventLogs( messages1[0].header.sourceChainSelector, messages1[0].header.sequenceNumber, messages1[0].header.messageId, @@ -1167,8 +1161,7 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { "" ); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( messages1[1].header.sourceChainSelector, messages1[1].header.sequenceNumber, messages1[1].header.messageId, @@ -1176,8 +1169,7 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { "" ); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( messages2[0].header.sourceChainSelector, messages2[0].header.sequenceNumber, messages2[0].header.messageId, @@ -1185,8 +1177,6 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { "" ); - uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages1[0].sender); - s_offRamp.batchExecute(reports, new uint256[][](2)); assertGt(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages1[0].sender), nonceBefore); } @@ -1202,8 +1192,11 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages1); reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messages2); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + vm.recordLogs(); + + s_offRamp.batchExecute(reports, new uint256[][](2)); + + assertExecutionStateChangedEventLogs( messages1[0].header.sourceChainSelector, messages1[0].header.sequenceNumber, messages1[0].header.messageId, @@ -1211,8 +1204,7 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { "" ); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( messages1[1].header.sourceChainSelector, messages1[1].header.sequenceNumber, messages1[1].header.messageId, @@ -1220,8 +1212,7 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { "" ); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( messages2[0].header.sourceChainSelector, messages2[0].header.sequenceNumber, messages2[0].header.messageId, @@ -1229,8 +1220,6 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { "" ); - s_offRamp.batchExecute(reports, new uint256[][](2)); - uint64 nonceChain1 = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages1[0].sender); uint64 nonceChain3 = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, messages2[0].sender); @@ -1248,18 +1237,17 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit EVM2EVMMultiOffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); + + vm.recordLogs(); + s_offRamp.batchExecute(reports, new uint256[][](2)); + assertExecutionStateChangedEventLogs( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); - - s_offRamp.batchExecute(reports, new uint256[][](2)); } // Reverts @@ -1328,7 +1316,8 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, - "" + "", + 30937 ); uint256[][] memory gasLimitOverrides = new uint256[][](1); @@ -1345,13 +1334,14 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { s_reverting_receiver.setRevert(false); - vm.expectEmit(); + vm.expectEmit(true, true, true, true); emit EVM2EVMMultiOffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, - "" + "", + 31011 ); uint256[][] memory gasLimitOverrides = new uint256[][](1); @@ -1373,8 +1363,12 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { s_reverting_receiver.setRevert(true); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + uint256[][] memory gasLimitOverrides = new uint256[][](1); + gasLimitOverrides[0] = _getGasLimitsFromMessages(messages); + + vm.recordLogs(); + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -1385,11 +1379,6 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { ) ); - uint256[][] memory gasLimitOverrides = new uint256[][](1); - gasLimitOverrides[0] = _getGasLimitsFromMessages(messages); - - s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); - assertEq( messages[0].header.nonce, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender) ); @@ -1423,27 +1412,38 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { gasLimitOverrides[0] = _getGasLimitsFromMessages(messages1); gasLimitOverrides[1] = _getGasLimitsFromMessages(messages2); + uint256[] memory expectedGasUsed = new uint256[](3); + expectedGasUsed[0] = 31022; + expectedGasUsed[1] = 22453; + expectedGasUsed[2] = 22453; + for (uint256 i = 0; i < 3; ++i) { - vm.expectEmit(); + vm.expectEmit(true, true, true, true); emit EVM2EVMMultiOffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages1[i].header.sequenceNumber, messages1[i].header.messageId, Internal.MessageExecutionState.SUCCESS, - "" + "", + expectedGasUsed[i] ); gasLimitOverrides[0][i] += 1; } + expectedGasUsed = new uint256[](2); + expectedGasUsed[0] = 24527; + expectedGasUsed[1] = 22454; + for (uint256 i = 0; i < 2; ++i) { - vm.expectEmit(); + vm.expectEmit(true, true, true, false); emit EVM2EVMMultiOffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_3, messages2[i].header.sequenceNumber, messages2[i].header.messageId, Internal.MessageExecutionState.SUCCESS, - "" + "", + expectedGasUsed[i] ); gasLimitOverrides[1][i] += 1; @@ -1461,16 +1461,17 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { messages[1].receiver = address(s_reverting_receiver); messages[1].header.messageId = Internal._hash(messages[1], ON_RAMP_ADDRESS_1); - vm.expectEmit(); + vm.expectEmit(true, true, true, false); emit EVM2EVMMultiOffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, - "" + "", + 86456 ); - vm.expectEmit(); + vm.expectEmit(true, true, true, false); emit EVM2EVMMultiOffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages[1].header.sequenceNumber, @@ -1479,16 +1480,18 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { abi.encodeWithSelector( EVM2EVMMultiOffRamp.ReceiverError.selector, abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, bytes("")) - ) + ), + 32095 ); - vm.expectEmit(); + vm.expectEmit(true, true, true, false); emit EVM2EVMMultiOffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages[2].header.sequenceNumber, messages[2].header.messageId, Internal.MessageExecutionState.SUCCESS, - "" + "", + 24894 ); s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); @@ -1503,15 +1506,17 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { gasLimitOverrides[0] = _getGasLimitsFromMessages(newMessages); gasLimitOverrides[0][0] += 1; - vm.expectEmit(); + vm.expectEmit(true, true, true, false); emit EVM2EVMMultiOffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, newMessages[0].header.sequenceNumber, newMessages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, - "" + "", + 24511 ); + vm.recordLogs(); s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, newMessages), gasLimitOverrides); } @@ -1522,15 +1527,15 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { messages[0].receiver = address(new ConformingReceiver(address(s_destRouter), s_destFeeToken)); messages[0].header.messageId = Internal._hash(messages[0], ON_RAMP_ADDRESS_1); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + vm.recordLogs(); + s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector(EVM2EVMMultiOffRamp.ReceiverError.selector, "") ); - s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); uint256[][] memory gasLimitOverrides = new uint256[][](1); gasLimitOverrides[0] = new uint256[](1); @@ -1539,15 +1544,15 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { vm.expectEmit(); emit ConformingReceiver.MessageReceived(); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + vm.recordLogs(); + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); } // Reverts @@ -1727,17 +1732,16 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber ); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( - messages[0].header.sourceChainSelector, + vm.recordLogs(); + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); + assertExecutionStateChangedEventLogs( + SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); - // Since the tx failed we don't release the tokens assertEq(tokenToAbuse.balanceOf(address(receiver)), balancePre + tokenAmount); } @@ -1758,20 +1762,21 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit MultiOCR3Base.Transmitted( + uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) + ); + + vm.recordLogs(); + + _execute(reports); + + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - vm.expectEmit(); - emit MultiOCR3Base.Transmitted( - uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) - ); - - _execute(reports); } function test_MultipleReports_Success() public { @@ -1787,7 +1792,13 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages2); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit MultiOCR3Base.Transmitted( + uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) + ); + + vm.recordLogs(); + _execute(reports); + assertExecutionStateChangedEventLogs( messages1[0].header.sourceChainSelector, messages1[0].header.sequenceNumber, messages1[0].header.messageId, @@ -1795,8 +1806,7 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { "" ); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( messages1[1].header.sourceChainSelector, messages1[1].header.sequenceNumber, messages1[1].header.messageId, @@ -1804,21 +1814,13 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { "" ); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( messages2[0].header.sourceChainSelector, messages2[0].header.sequenceNumber, messages2[0].header.messageId, Internal.MessageExecutionState.SUCCESS, "" ); - - vm.expectEmit(); - emit MultiOCR3Base.Transmitted( - uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) - ); - - _execute(reports); } function test_LargeBatch_Success() public { @@ -1832,10 +1834,17 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { reports[i] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); } + vm.expectEmit(); + emit MultiOCR3Base.Transmitted( + uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) + ); + + vm.recordLogs(); + _execute(reports); + for (uint64 i = 0; i < reports.length; ++i) { for (uint64 j = 0; j < reports[i].messages.length; ++j) { - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( reports[i].messages[j].header.sourceChainSelector, reports[i].messages[j].header.sequenceNumber, reports[i].messages[j].header.messageId, @@ -1844,13 +1853,6 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { ); } } - - vm.expectEmit(); - emit MultiOCR3Base.Transmitted( - uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) - ); - - _execute(reports); } function test_MultipleReportsWithPartialValidationFailures_Success() public { @@ -1871,7 +1873,13 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { s_inboundMessageValidator.setMessageIdValidationState(messages2[0].header.messageId, true); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit MultiOCR3Base.Transmitted( + uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) + ); + + vm.recordLogs(); + _execute(reports); + assertExecutionStateChangedEventLogs( messages1[0].header.sourceChainSelector, messages1[0].header.sequenceNumber, messages1[0].header.messageId, @@ -1882,8 +1890,7 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { ) ); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( messages1[1].header.sourceChainSelector, messages1[1].header.sequenceNumber, messages1[1].header.messageId, @@ -1891,8 +1898,7 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { "" ); - vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( messages2[0].header.sourceChainSelector, messages2[0].header.sequenceNumber, messages2[0].header.messageId, @@ -1902,13 +1908,6 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { abi.encodeWithSelector(IMessageInterceptor.MessageValidationError.selector, bytes("Invalid message")) ) ); - - vm.expectEmit(); - emit MultiOCR3Base.Transmitted( - uint8(Internal.OCRPluginType.Execution), s_configDigestExec, uint64(uint256(s_configDigestExec)) - ); - - _execute(reports); } // Reverts diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol index a0f3c02708..4813d024af 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol @@ -27,6 +27,7 @@ import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessag import {MockCommitStore} from "../mocks/MockCommitStore.sol"; import {MultiOCR3BaseSetup} from "../ocr/MultiOCR3BaseSetup.t.sol"; import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; +import {Vm} from "forge-std/Test.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; @@ -34,6 +35,8 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba uint64 internal constant SOURCE_CHAIN_SELECTOR_1 = SOURCE_CHAIN_SELECTOR; uint64 internal constant SOURCE_CHAIN_SELECTOR_2 = 6433500567565415381; uint64 internal constant SOURCE_CHAIN_SELECTOR_3 = 4051577828743386545; + bytes32 internal constant EXECUTION_STATE_CHANGE_TOPIC_HASH = + keccak256("ExecutionStateChanged(uint64,uint64,bytes32,uint8,bytes,uint256)"); bytes internal constant ON_RAMP_ADDRESS_1 = abi.encode(ON_RAMP_ADDRESS); bytes internal constant ON_RAMP_ADDRESS_2 = abi.encode(0xaA3f843Cf8E33B1F02dd28303b6bD87B1aBF8AE4); @@ -492,4 +495,29 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba vm.startPrank(s_validTransmitters[0]); s_offRamp.execute(reportContext, abi.encode(reports)); } + + function assertExecutionStateChangedEventLogs( + uint64 sourceChainSelector, + uint64 sequenceNumber, + bytes32 messageId, + Internal.MessageExecutionState state, + bytes memory returnData + ) public { + Vm.Log[] memory logs = vm.getRecordedLogs(); + for (uint256 i = 0; i < logs.length; ++i) { + if (logs[i].topics[0] == EXECUTION_STATE_CHANGE_TOPIC_HASH) { + uint64 logSourceChainSelector = uint64(uint256(logs[i].topics[1])); + uint64 logSequenceNumber = uint64(uint256(logs[i].topics[2])); + bytes32 logMessageId = bytes32(logs[i].topics[3]); + (uint8 logState, bytes memory logReturnData,) = abi.decode(logs[i].data, (uint8, bytes, uint256)); + if (logMessageId == messageId) { + assertEq(logSourceChainSelector, sourceChainSelector); + assertEq(logSequenceNumber, sequenceNumber); + assertEq(logMessageId, messageId); + assertEq(logState, uint8(state)); + assertEq(logReturnData, returnData); + } + } + } + } } diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go index 2b7571d55e..5b09de6687 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go @@ -163,8 +163,8 @@ type MultiOCR3BaseOCRConfigArgs struct { } var EVM2EVMMultiOffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162006bbb38038062006bbb8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615ee562000cd6600039600081816102530152612c0c0152600081816102240152612ee60152600081816101f50152818161142f01526118400152600081816101c50152612801015260008181611dce0152611e1a0152615ee56000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063d2a15d351461053d578063e9d68a8e14610550578063ece670b61461057057600080fd5b8063991a5018116100bd578063991a5018146104c5578063c673e584146104d8578063ccd37ba3146104f857600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104815780637d4eef601461048957600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a3660046140a1565b6105cc565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d19190614210565b61018f6103313660046142bb565b6105e0565b61018f61034436600461436e565b6109c0565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143c2565b610a29565b6040516102d1919061441f565b6104246040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610a7f565b61018f610497366004614974565b610b3d565b61018f610177366004614a9f565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104d3366004614aee565b610cdd565b6104eb6104e6366004614b73565b610cee565b6040516102d19190614bd3565b61052f610506366004614c48565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f61054b366004614c72565b610e4c565b61056361055e366004614ce7565b610f06565b6040516102d19190614d02565b61018f61057e366004614d50565b611013565b61018f610591366004614dac565b611386565b61018f6105a4366004614e31565b611397565b6105bc6105b7366004614f6f565b6113d9565b60405190151581526020016102d1565b6105d461149a565b6105dd816114f6565b50565b60006105ee878901896150f8565b8051515190915015158061060757508051602001515115155b156107075760095460208a01359067ffffffffffffffff808316911610156106c6576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261068f929101615336565b600060405180830381600087803b1580156106a957600080fd5b505af11580156106bd573d6000803e3d6000fd5b50505050610705565b816020015151600003610705576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109095760008260200151828151811061072f5761072f615263565b6020026020010151905060008160000151905061074b816117f4565b6000610756826118f6565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061079a575060208084015190810151905167ffffffffffffffff9182169116115b156107e357825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107da929190600401615349565b60405180910390fd5b60408301518061081f576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108925783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016107da565b60208085015101516108a5906001615394565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff92831602179092559251166000908152600860209081526040808320948352939052919091204290555060010161070a565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161093991906153bc565b60405180910390a16109b560008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b925061195d915050565b505050505050505050565b610a006109cf82840184615459565b60408051600080825260208201909252906109fa565b60608152602001906001900390816109e55790505b50611cd4565b604080516000808252602082019092529050610a2360018585858586600061195d565b50505050565b6000610a376001600461548e565b6002610a446080856154b7565b67ffffffffffffffff16610a5891906154de565b610a628585611d84565b901c166003811115610a7657610a766143f5565b90505b92915050565b6001546001600160a01b03163314610ad95760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107da565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b45611dcb565b815181518114610b81576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ccd576000848281518110610ba057610ba0615263565b60200260200101519050600081602001515190506000858481518110610bc857610bc8615263565b6020026020010151905080518214610c0c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cbe576000828281518110610c2b57610c2b615263565b6020026020010151905080600014610cb55784602001518281518110610c5357610c53615263565b602002602001015160800151811015610cb55784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016107da565b50600101610c0f565b50505050806001019050610b84565b50610cd88383611cd4565b505050565b610ce561149a565b6105dd81611e4c565b610d316040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610dda57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dbc575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e1e575b5050505050815250509050919050565b610e5461149a565b60005b81811015610cd8576000838383818110610e7357610e73615263565b905060400201803603810190610e8991906154f5565b9050610e9881602001516113d9565b610efd57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e57565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191610f939061552e565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbf9061552e565b8015610e3c5780601f10610fe157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610fef57505050919092525091949350505050565b33301461104c576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611089565b60408051808201909152600080825260208201528152602001906001900390816110625790505b5060a085015151909150156110bd576110ba8460a00151856020015186606001518760000151602001518787611fb2565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff16818301528087015183516000948401926110f9929101614210565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015611206576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a19061117390859060040161560a565b600060405180830381600087803b15801561118d57600080fd5b505af192505050801561119e575060015b611206573d8080156111cc576040519150601f19603f3d011682016040523d82523d6000602084013e6111d1565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016107da9190614210565b60408601515115801561121b57506080860151155b80611232575060608601516001600160a01b03163b155b8061127257506060860151611270906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120d1565b155b1561127f57505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf97983926112f7928992611388929160040161561d565b6000604051808303816000875af1158015611316573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261133e9190810190615659565b50915091508161137c57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107da9190614210565b5050505050505050565b61138e61149a565b6105dd816120ed565b61139f61149a565b60005b81518110156113d5576113cd8282815181106113c0576113c0615263565b60200260200101516121a3565b6001016113a2565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611476573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7991906156ef565b6000546001600160a01b031633146114f45760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107da565b565b60005b81518110156113d557600082828151811061151657611516615263565b602002602001015190506000816020015190508067ffffffffffffffff1660000361156d576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611595576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115c09061552e565b80601f01602080910402602001604051908101604052809291908181526020018280546115ec9061552e565b80156116395780601f1061160e57610100808354040283529160200191611639565b820191906000526020600020905b81548152906001019060200180831161161c57829003601f168201915b5050505050905060008460600151905081516000036116f1578051600003611674576040516342bcdf7f60e11b815260040160405180910390fd5b600183016116828282615754565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611744565b8080519060200120828051906020012014611744576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016107da565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117dc908690615814565b60405180910390a250505050508060010190506114f9565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b391906156ef565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107da565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610a79576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107da565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906119bc8760a46158e2565b9050826060015115611a045784516119d59060206154de565b86516119e29060206154de565b6119ed9060a06158e2565b6119f791906158e2565b611a0190826158e2565b90505b368114611a46576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107da565b5081518114611a8e5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107da565b611a96611dcb565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611ae457611ae46143f5565b6002811115611af557611af56143f5565b9052509050600281602001516002811115611b1257611b126143f5565b148015611b665750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611b4e57611b4e615263565b6000918252602090912001546001600160a01b031633145b611b9c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611c7e576020820151611bb79060016158f5565b60ff16855114611bf3576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611c2e576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611c4092919061590e565b604051908190038120611c57918b9060200161591e565b604051602081830303815290604052805190602001209050611c7c8a828888886124e7565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d0e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611d7d57611d75858281518110611d4357611d43615263565b602002602001015184611d6f57858381518110611d6257611d62615263565b60200260200101516126f4565b836126f4565b600101611d25565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611da9608085615932565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f0000000000000000000000000000000000000000000000000000000000000000146114f4576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107da565b80516001600160a01b0316611e74576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fce57611fce613eb8565b60405190808252806020026020018201604052801561201357816020015b6040805180820190915260008082526020820152815260200190600190039081611fec5790505b50905060005b87518110156120c5576120a088828151811061203757612037615263565b602002602001015188888888888781811061205457612054615263565b90506020028101906120669190615959565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e8592505050565b8282815181106120b2576120b2615263565b6020908102919091010152600101612019565b505b9695505050505050565b60006120dc8361322a565b8015610a765750610a76838361328e565b336001600160a01b038216036121455760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107da565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ce576000604051631b3fab5160e11b81526004016107da91906159be565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223b57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612290565b6060840151600182015460ff6201000090910416151590151514612290576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016107da565b60a08401518051601f60ff821611156122bf576001604051631b3fab5160e11b81526004016107da91906159be565b612325858560030180548060200260200160405190810160405280929190818152602001828054801561231b57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122fd575b5050505050613349565b85606001511561245457612393858560020180548060200260200160405190810160405280929190818152602001828054801561231b576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122fd575050505050613349565b608086015180516123ad9060028701906020840190613e12565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f101561240d576002604051631b3fab5160e11b81526004016107da91906159be565b604088015161241d9060036159d8565b60ff168160ff1611612445576003604051631b3fab5160e11b81526004016107da91906159be565b612451878360016133b2565b50505b612460858360026133b2565b81516124759060038601906020850190613e12565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ce938a939260028b019291906159f4565b60405180910390a16124df85613532565b505050505050565b6124ef613e84565b835160005b8181101561137c57600060018886846020811061251357612513615263565b61252091901a601b6158f5565b89858151811061253257612532615263565b602002602001015189868151811061254c5761254c615263565b60200260200101516040516000815260200160405260405161258a949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156125ac573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561260d5761260d6143f5565b600281111561261e5761261e6143f5565b905250905060018160200151600281111561263b5761263b6143f5565b14612672576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061268957612689615263565b6020020151156126c5576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126e0576126e0615263565b9115156020909202015250506001016124f4565b81516126ff816117f4565b600061270a826118f6565b602085015151909150600081900361274d576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461278b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156127a6576127a6613eb8565b6040519080825280602002602001820160405280156127cf578160200160208202803683370190505b50905060005b82811015612944576000876020015182815181106127f5576127f5615263565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461288857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107da565b61291e8186600101805461289b9061552e565b80601f01602080910402602001604051908101604052809291908181526020018280546128c79061552e565b80156129145780601f106128e957610100808354040283529160200191612914565b820191906000526020600020905b8154815290600101906020018083116128f757829003601f168201915b505050505061354e565b83838151811061293057612930615263565b6020908102919091010152506001016127d5565b50600061295b858389606001518a60800151613670565b9050806000036129a3576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107da565b8551151560005b848110156109b5576000896020015182815181106129ca576129ca615263565b6020026020010151905060006129e889836000015160600151610a29565b905060008160038111156129fe576129fe6143f5565b1480612a1b57506003816003811115612a1957612a196143f5565b145b612a72578151606001516040805167ffffffffffffffff808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a15050612e7d565b8315612b4257600454600090600160a01b900463ffffffff16612a95874261548e565b1190508080612ab557506003826003811115612ab357612ab36143f5565b145b612af7576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8b1660048201526024016107da565b8a8481518110612b0957612b09615263565b6020026020010151600014612b3c578a8481518110612b2a57612b2a615263565b60200260200101518360800181815250505b50612ba3565b6000816003811115612b5657612b566143f5565b14612ba3578151606001516040805167ffffffffffffffff808d16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612a63565b81516080015167ffffffffffffffff1615612c91576000816003811115612bcc57612bcc6143f5565b03612c915781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c43928e929190600401615aa0565b6020604051808303816000875af1158015612c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8691906156ef565b612c91575050612e7d565b60008b604001518481518110612ca957612ca9615263565b6020026020010151905080518360a001515114612d0d578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808d16600483015290911660248201526044016107da565b612d218a84600001516060015160016136c6565b600080612d2e858461376e565b91509150612d458c866000015160600151846136c6565b8615612db5576003826003811115612d5f57612d5f6143f5565b03612db5576000846003811115612d7857612d786143f5565b14612db5578451516040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526107da91908390600401615acd565b6002826003811115612dc957612dc96143f5565b14612e23576003826003811115612de257612de26143f5565b14612e23578451606001516040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526107da918e918590600401615ae6565b8451805160609091015160405167ffffffffffffffff918216918f16907f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df290612e6f9087908790615b0c565b60405180910390a450505050505b6001016129aa565b60408051808201909152600080825260208201526000612ea88760200151613838565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f519190615b2c565b90506001600160a01b0381161580612f995750612f976001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120d1565b155b15612fdb576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016107da565b6004546000908190612ffd9089908690600160e01b900463ffffffff166138de565b9150915060008060006130ca6040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b81525060405160240161307b9190615b49565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a0c565b9250925092508261310957816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da9190614210565b81516020146131515781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b6000828060200190518101906131679190615c16565b9050866001600160a01b03168c6001600160a01b0316146131fc5760006131988d8a613193868a61548e565b6138de565b509050868110806131b25750816131af888361548e565b14155b156131fa576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016107da565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613256827f01ffc9a70000000000000000000000000000000000000000000000000000000061328e565b8015610a795750613287827fffffffff0000000000000000000000000000000000000000000000000000000061328e565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015613332575060208210155b801561333e5750600081115b979650505050505050565b60005b8151811015610cd85760ff83166000908152600360205260408120835190919084908490811061337e5761337e615263565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161334c565b60005b82518160ff161015610a23576000838260ff16815181106133d8576133d8615263565b60200260200101519050600060028111156133f5576133f56143f5565b60ff80871660009081526003602090815260408083206001600160a01b03871684529091529020546101009004166002811115613434576134346143f5565b14613455576004604051631b3fab5160e11b81526004016107da91906159be565b6001600160a01b038116613495576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134bb576134bb6143f5565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff191617610100836002811115613518576135186143f5565b0217905550905050508061352b90615c2f565b90506133b5565b60ff81166105dd576009805467ffffffffffffffff1916905550565b815160208082015160409283015192516000938493613594937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c4e565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135dd9794969395929491939101615c81565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136149190615d78565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061367e858585613b32565b9050613689816113d9565b6136975760009150506136be565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026136d56080856154b7565b67ffffffffffffffff166136e991906154de565b905060006136f78585611d84565b9050816137066001600461548e565b901b19168183600381111561371d5761371d6143f5565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161374c608088615932565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906137b29087908790600401615dd8565b600060405180830381600087803b1580156137cc57600080fd5b505af19250505080156137dd575060015b61381c573d80801561380b576040519150601f19603f3d011682016040523d82523d6000602084013e613810565b606091505b50600392509050613831565b50506040805160208101909152600081526002905b9250929050565b6000815160201461387757816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da9190614210565b60008280602001905181019061388d9190615c16565b90506001600160a01b038111806138a5575061040081105b15610a7957826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da9190614210565b60008060008060006139588860405160240161390991906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a0c565b9250925092508261399757816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da9190614210565b60208251146139df5781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b818060200190518101906139f39190615c16565b6139fd828861548e565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a2f57613a2f613eb8565b6040519080825280601f01601f191660200182016040528015613a59576020820181803683370190505b509150863b613a8c577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613abf577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613af8577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b1b5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b73576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b8757506101018111155b613ba4576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bce576040516309bde33960e01b815260040160405180910390fd5b80600003613bfb5786600081518110613be957613be9615263565b60200260200101519350505050613dca565b60008167ffffffffffffffff811115613c1657613c16613eb8565b604051908082528060200260200182016040528015613c3f578160200160208202803683370190505b50905060008080805b85811015613d695760006001821b8b811603613ca35788851015613c8c578c5160018601958e918110613c7d57613c7d615263565b60200260200101519050613cc5565b8551600185019487918110613c7d57613c7d615263565b8b5160018401938d918110613cba57613cba615263565b602002602001015190505b600089861015613cf5578d5160018701968f918110613ce657613ce6615263565b60200260200101519050613d17565b8651600186019588918110613d0c57613d0c615263565b602002602001015190505b82851115613d38576040516309bde33960e01b815260040160405180910390fd5b613d428282613dd1565b878481518110613d5457613d54615263565b60209081029190910101525050600101613c48565b506001850382148015613d7b57508683145b8015613d8657508581145b613da3576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613db857613db8615263565b60200260200101519750505050505050505b9392505050565b6000818310613de957613de48284613def565b610a76565b610a7683835b604080516001602082015290810183905260608101829052600090608001613652565b828054828255906000526020600020908101928215613e74579160200282015b82811115613e74578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e32565b50613e80929150613ea3565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e805760008155600101613ea4565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613ef157613ef1613eb8565b60405290565b60405160a0810167ffffffffffffffff81118282101715613ef157613ef1613eb8565b60405160c0810167ffffffffffffffff81118282101715613ef157613ef1613eb8565b6040805190810167ffffffffffffffff81118282101715613ef157613ef1613eb8565b6040516060810167ffffffffffffffff81118282101715613ef157613ef1613eb8565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fac57613fac613eb8565b604052919050565b600067ffffffffffffffff821115613fce57613fce613eb8565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461400557600080fd5b919050565b80151581146105dd57600080fd5b80356140058161400a565b600067ffffffffffffffff82111561403d5761403d613eb8565b50601f01601f191660200190565b600082601f83011261405c57600080fd5b813561406f61406a82614023565b613f83565b81815284602083860101111561408457600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140b457600080fd5b823567ffffffffffffffff808211156140cc57600080fd5b818501915085601f8301126140e057600080fd5b81356140ee61406a82613fb4565b81815260059190911b8301840190848101908883111561410d57600080fd5b8585015b838110156141b3578035858111156141295760008081fd5b86016080818c03601f19018113156141415760008081fd5b614149613ece565b8983013561415681613fd8565b81526040614165848201613fed565b8b8301526060808501356141788161400a565b8383015292840135928984111561419157600091508182fd5b61419f8f8d8688010161404b565b908301525085525050918601918601614111565b5098975050505050505050565b60005b838110156141db5781810151838201526020016141c3565b50506000910152565b600081518084526141fc8160208601602086016141c0565b601f01601f19169290920160200192915050565b602081526000610a7660208301846141e4565b8060608101831015610a7957600080fd5b60008083601f84011261424657600080fd5b50813567ffffffffffffffff81111561425e57600080fd5b60208301915083602082850101111561383157600080fd5b60008083601f84011261428857600080fd5b50813567ffffffffffffffff8111156142a057600080fd5b6020830191508360208260051b850101111561383157600080fd5b60008060008060008060008060e0898b0312156142d757600080fd5b6142e18a8a614223565b9750606089013567ffffffffffffffff808211156142fe57600080fd5b61430a8c838d01614234565b909950975060808b013591508082111561432357600080fd5b61432f8c838d01614276565b909750955060a08b013591508082111561434857600080fd5b506143558b828c01614276565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561438357600080fd5b61438d8585614223565b9250606084013567ffffffffffffffff8111156143a957600080fd5b6143b586828701614234565b9497909650939450505050565b600080604083850312156143d557600080fd5b6143de83613fed565b91506143ec60208401613fed565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061441b5761441b6143f5565b9052565b60208101610a79828461440b565b600060a0828403121561443f57600080fd5b614447613ef7565b90508135815261445960208301613fed565b602082015261446a60408301613fed565b604082015261447b60608301613fed565b606082015261448c60808301613fed565b608082015292915050565b803561400581613fd8565b600082601f8301126144b357600080fd5b813560206144c361406a83613fb4565b82815260059290921b840181019181810190868411156144e257600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156145075760008081fd5b8189019150608080601f19848d030112156145225760008081fd5b61452a613ece565b878401358381111561453c5760008081fd5b61454a8d8a8388010161404b565b825250604080850135848111156145615760008081fd5b61456f8e8b8389010161404b565b8a84015250606080860135858111156145885760008081fd5b6145968f8c838a010161404b565b92840192909252949092013593810193909352505083529183019183016144e6565b600061014082840312156145cb57600080fd5b6145d3613f1a565b90506145df838361442d565b815260a082013567ffffffffffffffff808211156145fc57600080fd5b6146088583860161404b565b602084015260c084013591508082111561462157600080fd5b61462d8583860161404b565b604084015261463e60e08501614497565b6060840152610100840135608084015261012084013591508082111561466357600080fd5b50614670848285016144a2565b60a08301525092915050565b600082601f83011261468d57600080fd5b8135602061469d61406a83613fb4565b82815260059290921b840181019181810190868411156146bc57600080fd5b8286015b848110156120c557803567ffffffffffffffff8111156146e05760008081fd5b6146ee8986838b01016145b8565b8452509183019183016146c0565b600082601f83011261470d57600080fd5b8135602061471d61406a83613fb4565b82815260059290921b8401810191818101908684111561473c57600080fd5b8286015b848110156120c557803567ffffffffffffffff8082111561476057600080fd5b818901915089603f83011261477457600080fd5b8582013561478461406a82613fb4565b81815260059190911b830160400190878101908c8311156147a457600080fd5b604085015b838110156147dd578035858111156147c057600080fd5b6147cf8f6040838a010161404b565b8452509189019189016147a9565b50875250505092840192508301614740565b600082601f83011261480057600080fd5b8135602061481061406a83613fb4565b8083825260208201915060208460051b87010193508684111561483257600080fd5b602086015b848110156120c55780358352918301918301614837565b600082601f83011261485f57600080fd5b8135602061486f61406a83613fb4565b82815260059290921b8401810191818101908684111561488e57600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156148b35760008081fd5b818901915060a080601f19848d030112156148ce5760008081fd5b6148d6613ef7565b6148e1888501613fed565b8152604080850135848111156148f75760008081fd5b6149058e8b8389010161467c565b8a840152506060808601358581111561491e5760008081fd5b61492c8f8c838a01016146fc565b83850152506080915081860135858111156149475760008081fd5b6149558f8c838a01016147ef565b9184019190915250919093013590830152508352918301918301614892565b600080604080848603121561498857600080fd5b833567ffffffffffffffff808211156149a057600080fd5b6149ac8783880161484e565b94506020915081860135818111156149c357600080fd5b8601601f810188136149d457600080fd5b80356149e261406a82613fb4565b81815260059190911b8201840190848101908a831115614a0157600080fd5b8584015b83811015614a8d57803586811115614a1d5760008081fd5b8501603f81018d13614a2f5760008081fd5b87810135614a3f61406a82613fb4565b81815260059190911b82018a0190898101908f831115614a5f5760008081fd5b928b01925b82841015614a7d5783358252928a0192908a0190614a64565b8652505050918601918601614a05565b50809750505050505050509250929050565b600060208284031215614ab157600080fd5b813567ffffffffffffffff811115614ac857600080fd5b820160a08185031215613dca57600080fd5b803563ffffffff8116811461400557600080fd5b600060a08284031215614b0057600080fd5b614b08613ef7565b8235614b1381613fd8565b8152614b2160208401614ada565b6020820152614b3260408401614ada565b6040820152614b4360608401614ada565b60608201526080830135614b5681613fd8565b60808201529392505050565b803560ff8116811461400557600080fd5b600060208284031215614b8557600080fd5b610a7682614b62565b60008151808452602080850194506020840160005b83811015614bc85781516001600160a01b031687529582019590820190600101614ba3565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c2260e0840182614b8e565b90506040840151601f198483030160c0850152614c3f8282614b8e565b95945050505050565b60008060408385031215614c5b57600080fd5b614c6483613fed565b946020939093013593505050565b60008060208385031215614c8557600080fd5b823567ffffffffffffffff80821115614c9d57600080fd5b818501915085601f830112614cb157600080fd5b813581811115614cc057600080fd5b8660208260061b8501011115614cd557600080fd5b60209290920196919550909350505050565b600060208284031215614cf957600080fd5b610a7682613fed565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136be60a08401826141e4565b600080600060408486031215614d6557600080fd5b833567ffffffffffffffff80821115614d7d57600080fd5b614d89878388016145b8565b94506020860135915080821115614d9f57600080fd5b506143b586828701614276565b600060208284031215614dbe57600080fd5b8135613dca81613fd8565b600082601f830112614dda57600080fd5b81356020614dea61406a83613fb4565b8083825260208201915060208460051b870101935086841115614e0c57600080fd5b602086015b848110156120c5578035614e2481613fd8565b8352918301918301614e11565b60006020808385031215614e4457600080fd5b823567ffffffffffffffff80821115614e5c57600080fd5b818501915085601f830112614e7057600080fd5b8135614e7e61406a82613fb4565b81815260059190911b83018401908481019088831115614e9d57600080fd5b8585015b838110156141b357803585811115614eb857600080fd5b860160c0818c03601f19011215614ecf5760008081fd5b614ed7613f1a565b8882013581526040614eea818401614b62565b8a8301526060614efb818501614b62565b8284015260809150614f0e828501614018565b9083015260a08381013589811115614f265760008081fd5b614f348f8d83880101614dc9565b838501525060c0840135915088821115614f4e5760008081fd5b614f5c8e8c84870101614dc9565b9083015250845250918601918601614ea1565b600060208284031215614f8157600080fd5b5035919050565b80356001600160e01b038116811461400557600080fd5b600082601f830112614fb057600080fd5b81356020614fc061406a83613fb4565b82815260069290921b84018101918181019086841115614fdf57600080fd5b8286015b848110156120c55760408189031215614ffc5760008081fd5b615004613f3d565b61500d82613fed565b815261501a858301614f88565b81860152835291830191604001614fe3565b600082601f83011261503d57600080fd5b8135602061504d61406a83613fb4565b82815260079290921b8401810191818101908684111561506c57600080fd5b8286015b848110156120c557808803608081121561508a5760008081fd5b615092613f60565b61509b83613fed565b8152604080601f19840112156150b15760008081fd5b6150b9613f3d565b92506150c6878501613fed565b83526150d3818501613fed565b8388015281870192909252606083013591810191909152835291830191608001615070565b6000602080838503121561510b57600080fd5b823567ffffffffffffffff8082111561512357600080fd5b8185019150604080838803121561513957600080fd5b615141613f3d565b83358381111561515057600080fd5b84016040818a03121561516257600080fd5b61516a613f3d565b81358581111561517957600080fd5b8201601f81018b1361518a57600080fd5b803561519861406a82613fb4565b81815260069190911b8201890190898101908d8311156151b757600080fd5b928a01925b828410156152075787848f0312156151d45760008081fd5b6151dc613f3d565b84356151e781613fd8565b81526151f4858d01614f88565b818d0152825292870192908a01906151bc565b84525050508187013593508484111561521f57600080fd5b61522b8a858401614f9f565b818801528252508385013591508282111561524557600080fd5b6152518883860161502c565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b818110156152d057835180516001600160a01b031684528501516001600160e01b0316858401529284019291850191600101615299565b50508583015187820388850152805180835290840192506000918401905b8083101561532a578351805167ffffffffffffffff1683528501516001600160e01b0316858301529284019260019290920191908501906152ee565b50979650505050505050565b602081526000610a766020830184615279565b67ffffffffffffffff8316815260608101613dca6020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153b5576153b561537e565b5092915050565b6000602080835260608451604080848701526153db6060870183615279565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141b357845167ffffffffffffffff81511683528781015161543b89850182805167ffffffffffffffff908116835260209182015116910152565b508401518287015293860193600192909201916080909101906153fc565b60006020828403121561546b57600080fd5b813567ffffffffffffffff81111561548257600080fd5b6136be8482850161484e565b81810381811115610a7957610a7961537e565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff808416806154d2576154d26154a1565b92169190910692915050565b8082028115828204841417610a7957610a7961537e565b60006040828403121561550757600080fd5b61550f613f3d565b61551883613fed565b8152602083013560208201528091505092915050565b600181811c9082168061554257607f821691505b60208210810361556257634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261559c60a08701826141e4565b9050606085015186820360608801526155b582826141e4565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561532a57835180516001600160a01b03168352860151868301529285019260019290920191908401906155d8565b602081526000610a766020830184615568565b6080815260006156306080830187615568565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561566e57600080fd5b83516156798161400a565b602085015190935067ffffffffffffffff81111561569657600080fd5b8401601f810186136156a757600080fd5b80516156b561406a82614023565b8181528760208385010111156156ca57600080fd5b6156db8260208301602086016141c0565b809450505050604084015190509250925092565b60006020828403121561570157600080fd5b8151613dca8161400a565b601f821115610cd8576000816000526020600020601f850160051c810160208610156157355750805b601f850160051c820191505b818110156124df57828155600101615741565b815167ffffffffffffffff81111561576e5761576e613eb8565b6157828161577c845461552e565b8461570c565b602080601f8311600181146157b7576000841561579f5750858301515b600019600386901b1c1916600185901b1785556124df565b600085815260208120601f198616915b828110156157e6578886015182559484019460019091019084016157c7565b50858210156158045787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546158668161552e565b8060a089015260c0600183166000811461588757600181146158a3576158d3565b60ff19841660c08b015260c083151560051b8b010194506158d3565b85600052602060002060005b848110156158ca5781548c82018501529088019089016158af565b8b0160c0019550505b50929998505050505050505050565b80820180821115610a7957610a7961537e565b60ff8181168382160190811115610a7957610a7961537e565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061594d5761594d6154a1565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261598e57600080fd5b83018035915067ffffffffffffffff8211156159a957600080fd5b60200191503681900382131561383157600080fd5b60208101600583106159d2576159d26143f5565b91905290565b60ff81811683821602908116908181146153b5576153b561537e565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a4c5784546001600160a01b031683526001948501949284019201615a27565b50508481036060860152865180825290820192508187019060005b81811015615a8c5782516001600160a01b031685529383019391830191600101615a67565b50505060ff851660808501525090506120c7565b600067ffffffffffffffff808616835280851660208401525060606040830152614c3f60608301846141e4565b8281526040602082015260006136be60408301846141e4565b67ffffffffffffffff848116825283166020820152606081016136be604083018461440b565b615b16818461440b565b6040602082015260006136be60408301846141e4565b600060208284031215615b3e57600080fd5b8151613dca81613fd8565b6020815260008251610100806020850152615b686101208501836141e4565b91506020850151615b85604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615bbf60a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bdc84836141e4565b935060c08701519150808685030160e0870152615bf984836141e4565b935060e08701519150808685030183870152506120c783826141e4565b600060208284031215615c2857600080fd5b5051919050565b600060ff821660ff8103615c4557615c4561537e565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c760808301846141e4565b86815260c060208201526000615c9a60c08301886141e4565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d6b57601f19868403018952815160808151818652615d17828701826141e4565b9150508582015185820387870152615d2f82826141e4565b91505060408083015186830382880152615d4983826141e4565b6060948501519790940196909652505098840198925090830190600101615cf1565b5090979650505050505050565b602081526000610a766020830184615cd4565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d6b57601f19868403018952615dc68383516141e4565b98840198925090830190600101615daa565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e406101808501836141e4565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e7d84836141e4565b935060608801519150615e9c6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615ec38282615cd4565b9150508281036020840152614c3f8185615d8b56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162006bdd38038062006bdd8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615f0762000cd6600039600081816102530152612c120152600081816102240152612ef80152600081816101f50152818161142f01526118400152600081816101c50152612801015260008181611dce0152611e1a0152615f076000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063d2a15d351461053d578063e9d68a8e14610550578063ece670b61461057057600080fd5b8063991a5018116100bd578063991a5018146104c5578063c673e584146104d8578063ccd37ba3146104f857600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104815780637d4eef601461048957600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a3660046140b3565b6105cc565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d19190614222565b61018f6103313660046142cd565b6105e0565b61018f610344366004614380565b6109c0565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143d4565b610a29565b6040516102d19190614431565b6104246040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610a7f565b61018f610497366004614986565b610b3d565b61018f610177366004614ab1565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104d3366004614b00565b610cdd565b6104eb6104e6366004614b85565b610cee565b6040516102d19190614be5565b61052f610506366004614c5a565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f61054b366004614c84565b610e4c565b61056361055e366004614cf9565b610f06565b6040516102d19190614d14565b61018f61057e366004614d62565b611013565b61018f610591366004614dbe565b611386565b61018f6105a4366004614e43565b611397565b6105bc6105b7366004614f81565b6113d9565b60405190151581526020016102d1565b6105d461149a565b6105dd816114f6565b50565b60006105ee8789018961510a565b8051515190915015158061060757508051602001515115155b156107075760095460208a01359067ffffffffffffffff808316911610156106c6576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261068f929101615348565b600060405180830381600087803b1580156106a957600080fd5b505af11580156106bd573d6000803e3d6000fd5b50505050610705565b816020015151600003610705576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109095760008260200151828151811061072f5761072f615275565b6020026020010151905060008160000151905061074b816117f4565b6000610756826118f6565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061079a575060208084015190810151905167ffffffffffffffff9182169116115b156107e357825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107da92919060040161535b565b60405180910390fd5b60408301518061081f576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108925783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016107da565b60208085015101516108a59060016153a6565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff92831602179092559251166000908152600860209081526040808320948352939052919091204290555060010161070a565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161093991906153ce565b60405180910390a16109b560008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b925061195d915050565b505050505050505050565b610a006109cf8284018461546b565b60408051600080825260208201909252906109fa565b60608152602001906001900390816109e55790505b50611cd4565b604080516000808252602082019092529050610a2360018585858586600061195d565b50505050565b6000610a37600160046154a0565b6002610a446080856154c9565b67ffffffffffffffff16610a5891906154f0565b610a628585611d84565b901c166003811115610a7657610a76614407565b90505b92915050565b6001546001600160a01b03163314610ad95760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107da565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b45611dcb565b815181518114610b81576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ccd576000848281518110610ba057610ba0615275565b60200260200101519050600081602001515190506000858481518110610bc857610bc8615275565b6020026020010151905080518214610c0c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cbe576000828281518110610c2b57610c2b615275565b6020026020010151905080600014610cb55784602001518281518110610c5357610c53615275565b602002602001015160800151811015610cb55784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016107da565b50600101610c0f565b50505050806001019050610b84565b50610cd88383611cd4565b505050565b610ce561149a565b6105dd81611e4c565b610d316040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610dda57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dbc575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e1e575b5050505050815250509050919050565b610e5461149a565b60005b81811015610cd8576000838383818110610e7357610e73615275565b905060400201803603810190610e899190615507565b9050610e9881602001516113d9565b610efd57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e57565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191610f9390615540565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbf90615540565b8015610e3c5780601f10610fe157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610fef57505050919092525091949350505050565b33301461104c576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611089565b60408051808201909152600080825260208201528152602001906001900390816110625790505b5060a085015151909150156110bd576110ba8460a00151856020015186606001518760000151602001518787611fb2565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff16818301528087015183516000948401926110f9929101614222565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015611206576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a19061117390859060040161561c565b600060405180830381600087803b15801561118d57600080fd5b505af192505050801561119e575060015b611206573d8080156111cc576040519150601f19603f3d011682016040523d82523d6000602084013e6111d1565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b60408601515115801561121b57506080860151155b80611232575060608601516001600160a01b03163b155b8061127257506060860151611270906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120d1565b155b1561127f57505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf97983926112f7928992611388929160040161562f565b6000604051808303816000875af1158015611316573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261133e919081019061566b565b50915091508161137c57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b5050505050505050565b61138e61149a565b6105dd816120ed565b61139f61149a565b60005b81518110156113d5576113cd8282815181106113c0576113c0615275565b60200260200101516121a3565b6001016113a2565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611476573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a799190615701565b6000546001600160a01b031633146114f45760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107da565b565b60005b81518110156113d557600082828151811061151657611516615275565b602002602001015190506000816020015190508067ffffffffffffffff1660000361156d576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611595576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115c090615540565b80601f01602080910402602001604051908101604052809291908181526020018280546115ec90615540565b80156116395780601f1061160e57610100808354040283529160200191611639565b820191906000526020600020905b81548152906001019060200180831161161c57829003601f168201915b5050505050905060008460600151905081516000036116f1578051600003611674576040516342bcdf7f60e11b815260040160405180910390fd5b600183016116828282615766565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611744565b8080519060200120828051906020012014611744576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016107da565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117dc908690615826565b60405180910390a250505050508060010190506114f9565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b39190615701565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107da565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610a79576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107da565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906119bc8760a46158f4565b9050826060015115611a045784516119d59060206154f0565b86516119e29060206154f0565b6119ed9060a06158f4565b6119f791906158f4565b611a0190826158f4565b90505b368114611a46576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107da565b5081518114611a8e5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107da565b611a96611dcb565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611ae457611ae4614407565b6002811115611af557611af5614407565b9052509050600281602001516002811115611b1257611b12614407565b148015611b665750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611b4e57611b4e615275565b6000918252602090912001546001600160a01b031633145b611b9c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611c7e576020820151611bb7906001615907565b60ff16855114611bf3576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611c2e576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611c40929190615920565b604051908190038120611c57918b90602001615930565b604051602081830303815290604052805190602001209050611c7c8a828888886124e7565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d0e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611d7d57611d75858281518110611d4357611d43615275565b602002602001015184611d6f57858381518110611d6257611d62615275565b60200260200101516126f4565b836126f4565b600101611d25565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611da9608085615944565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f0000000000000000000000000000000000000000000000000000000000000000146114f4576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107da565b80516001600160a01b0316611e74576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fce57611fce613eca565b60405190808252806020026020018201604052801561201357816020015b6040805180820190915260008082526020820152815260200190600190039081611fec5790505b50905060005b87518110156120c5576120a088828151811061203757612037615275565b602002602001015188888888888781811061205457612054615275565b9050602002810190612066919061596b565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9792505050565b8282815181106120b2576120b2615275565b6020908102919091010152600101612019565b505b9695505050505050565b60006120dc8361323c565b8015610a765750610a7683836132a0565b336001600160a01b038216036121455760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107da565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ce576000604051631b3fab5160e11b81526004016107da91906159d0565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223b57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612290565b6060840151600182015460ff6201000090910416151590151514612290576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016107da565b60a08401518051601f60ff821611156122bf576001604051631b3fab5160e11b81526004016107da91906159d0565b612325858560030180548060200260200160405190810160405280929190818152602001828054801561231b57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122fd575b505050505061335b565b85606001511561245457612393858560020180548060200260200160405190810160405280929190818152602001828054801561231b576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122fd57505050505061335b565b608086015180516123ad9060028701906020840190613e24565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f101561240d576002604051631b3fab5160e11b81526004016107da91906159d0565b604088015161241d9060036159ea565b60ff168160ff1611612445576003604051631b3fab5160e11b81526004016107da91906159d0565b612451878360016133c4565b50505b612460858360026133c4565b81516124759060038601906020850190613e24565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ce938a939260028b01929190615a06565b60405180910390a16124df85613544565b505050505050565b6124ef613e96565b835160005b8181101561137c57600060018886846020811061251357612513615275565b61252091901a601b615907565b89858151811061253257612532615275565b602002602001015189868151811061254c5761254c615275565b60200260200101516040516000815260200160405260405161258a949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156125ac573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561260d5761260d614407565b600281111561261e5761261e614407565b905250905060018160200151600281111561263b5761263b614407565b14612672576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061268957612689615275565b6020020151156126c5576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126e0576126e0615275565b9115156020909202015250506001016124f4565b81516126ff816117f4565b600061270a826118f6565b602085015151909150600081900361274d576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461278b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156127a6576127a6613eca565b6040519080825280602002602001820160405280156127cf578160200160208202803683370190505b50905060005b82811015612944576000876020015182815181106127f5576127f5615275565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461288857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107da565b61291e8186600101805461289b90615540565b80601f01602080910402602001604051908101604052809291908181526020018280546128c790615540565b80156129145780601f106128e957610100808354040283529160200191612914565b820191906000526020600020905b8154815290600101906020018083116128f757829003601f168201915b5050505050613560565b83838151811061293057612930615275565b6020908102919091010152506001016127d5565b50600061295b858389606001518a60800151613682565b9050806000036129a3576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107da565b8551151560005b848110156109b55760005a905060008a6020015183815181106129cf576129cf615275565b6020026020010151905060006129ed8a836000015160600151610a29565b90506000816003811115612a0357612a03614407565b1480612a2057506003816003811115612a1e57612a1e614407565b145b612a78578151606001516040805167ffffffffffffffff808e16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a1505050612e8f565b8415612b4857600454600090600160a01b900463ffffffff16612a9b88426154a0565b1190508080612abb57506003826003811115612ab957612ab9614407565b145b612afd576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8c1660048201526024016107da565b8b8581518110612b0f57612b0f615275565b6020026020010151600014612b42578b8581518110612b3057612b30615275565b60200260200101518360800181815250505b50612ba9565b6000816003811115612b5c57612b5c614407565b14612ba9578151606001516040805167ffffffffffffffff808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612a68565b81516080015167ffffffffffffffff1615612c98576000816003811115612bd257612bd2614407565b03612c985781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c49928f929190600401615ab2565b6020604051808303816000875af1158015612c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8c9190615701565b612c9857505050612e8f565b60008c604001518581518110612cb057612cb0615275565b6020026020010151905080518360a001515114612d14578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808e16600483015290911660248201526044016107da565b612d288b84600001516060015160016136d8565b600080612d358584613780565b91509150612d4c8d866000015160600151846136d8565b8715612dbc576003826003811115612d6657612d66614407565b03612dbc576000846003811115612d7f57612d7f614407565b14612dbc578451516040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526107da91908390600401615adf565b6002826003811115612dd057612dd0614407565b14612e2a576003826003811115612de957612de9614407565b14612e2a578451606001516040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526107da918f918590600401615af8565b8451805160609091015167ffffffffffffffff908116908f167fdc8ccbc35e0eebd81239bcd1971fcd53c7eb34034880142a0f43c809a458732f85855a612e71908d6154a0565b604051612e8093929190615b1e565b60405180910390a45050505050505b6001016129aa565b60408051808201909152600080825260208201526000612eba876020015161384a565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f639190615b4e565b90506001600160a01b0381161580612fab5750612fa96001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120d1565b155b15612fed576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016107da565b600454600090819061300f9089908690600160e01b900463ffffffff166138f0565b9150915060008060006130dc6040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b81525060405160240161308d9190615b6b565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a1e565b9250925092508261311b57816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b81516020146131635781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b6000828060200190518101906131799190615c38565b9050866001600160a01b03168c6001600160a01b03161461320e5760006131aa8d8a6131a5868a6154a0565b6138f0565b509050868110806131c45750816131c188836154a0565b14155b1561320c576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016107da565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613268827f01ffc9a7000000000000000000000000000000000000000000000000000000006132a0565b8015610a795750613299827fffffffff000000000000000000000000000000000000000000000000000000006132a0565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015613344575060208210155b80156133505750600081115b979650505050505050565b60005b8151811015610cd85760ff83166000908152600360205260408120835190919084908490811061339057613390615275565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161335e565b60005b82518160ff161015610a23576000838260ff16815181106133ea576133ea615275565b602002602001015190506000600281111561340757613407614407565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561344657613446614407565b14613467576004604051631b3fab5160e11b81526004016107da91906159d0565b6001600160a01b0381166134a7576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134cd576134cd614407565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561352a5761352a614407565b0217905550905050508061353d90615c51565b90506133c7565b60ff81166105dd576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936135a6937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c70565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135ef9794969395929491939101615ca3565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136269190615d9a565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b600080613690858585613b44565b905061369b816113d9565b6136a95760009150506136d0565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026136e76080856154c9565b67ffffffffffffffff166136fb91906154f0565b905060006137098585611d84565b905081613718600160046154a0565b901b19168183600381111561372f5761372f614407565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161375e608088615944565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906137c49087908790600401615dfa565b600060405180830381600087803b1580156137de57600080fd5b505af19250505080156137ef575060015b61382e573d80801561381d576040519150601f19603f3d011682016040523d82523d6000602084013e613822565b606091505b50600392509050613843565b50506040805160208101909152600081526002905b9250929050565b6000815160201461388957816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b60008280602001905181019061389f9190615c38565b90506001600160a01b038111806138b7575061040081105b15610a7957826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b600080600080600061396a8860405160240161391b91906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a1e565b925092509250826139a957816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b60208251146139f15781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b81806020019051810190613a059190615c38565b613a0f82886154a0565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a4157613a41613eca565b6040519080825280601f01601f191660200182016040528015613a6b576020820181803683370190505b509150863b613a9e577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613ad1577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613b0a577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b2d5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b85576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b9957506101018111155b613bb6576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613be0576040516309bde33960e01b815260040160405180910390fd5b80600003613c0d5786600081518110613bfb57613bfb615275565b60200260200101519350505050613ddc565b60008167ffffffffffffffff811115613c2857613c28613eca565b604051908082528060200260200182016040528015613c51578160200160208202803683370190505b50905060008080805b85811015613d7b5760006001821b8b811603613cb55788851015613c9e578c5160018601958e918110613c8f57613c8f615275565b60200260200101519050613cd7565b8551600185019487918110613c8f57613c8f615275565b8b5160018401938d918110613ccc57613ccc615275565b602002602001015190505b600089861015613d07578d5160018701968f918110613cf857613cf8615275565b60200260200101519050613d29565b8651600186019588918110613d1e57613d1e615275565b602002602001015190505b82851115613d4a576040516309bde33960e01b815260040160405180910390fd5b613d548282613de3565b878481518110613d6657613d66615275565b60209081029190910101525050600101613c5a565b506001850382148015613d8d57508683145b8015613d9857508581145b613db5576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613dca57613dca615275565b60200260200101519750505050505050505b9392505050565b6000818310613dfb57613df68284613e01565b610a76565b610a7683835b604080516001602082015290810183905260608101829052600090608001613664565b828054828255906000526020600020908101928215613e86579160200282015b82811115613e86578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e44565b50613e92929150613eb5565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e925760008155600101613eb6565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613f0357613f03613eca565b60405290565b60405160a0810167ffffffffffffffff81118282101715613f0357613f03613eca565b60405160c0810167ffffffffffffffff81118282101715613f0357613f03613eca565b6040805190810167ffffffffffffffff81118282101715613f0357613f03613eca565b6040516060810167ffffffffffffffff81118282101715613f0357613f03613eca565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fbe57613fbe613eca565b604052919050565b600067ffffffffffffffff821115613fe057613fe0613eca565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461401757600080fd5b919050565b80151581146105dd57600080fd5b80356140178161401c565b600067ffffffffffffffff82111561404f5761404f613eca565b50601f01601f191660200190565b600082601f83011261406e57600080fd5b813561408161407c82614035565b613f95565b81815284602083860101111561409657600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140c657600080fd5b823567ffffffffffffffff808211156140de57600080fd5b818501915085601f8301126140f257600080fd5b813561410061407c82613fc6565b81815260059190911b8301840190848101908883111561411f57600080fd5b8585015b838110156141c55780358581111561413b5760008081fd5b86016080818c03601f19018113156141535760008081fd5b61415b613ee0565b8983013561416881613fea565b81526040614177848201613fff565b8b83015260608085013561418a8161401c565b838301529284013592898411156141a357600091508182fd5b6141b18f8d8688010161405d565b908301525085525050918601918601614123565b5098975050505050505050565b60005b838110156141ed5781810151838201526020016141d5565b50506000910152565b6000815180845261420e8160208601602086016141d2565b601f01601f19169290920160200192915050565b602081526000610a7660208301846141f6565b8060608101831015610a7957600080fd5b60008083601f84011261425857600080fd5b50813567ffffffffffffffff81111561427057600080fd5b60208301915083602082850101111561384357600080fd5b60008083601f84011261429a57600080fd5b50813567ffffffffffffffff8111156142b257600080fd5b6020830191508360208260051b850101111561384357600080fd5b60008060008060008060008060e0898b0312156142e957600080fd5b6142f38a8a614235565b9750606089013567ffffffffffffffff8082111561431057600080fd5b61431c8c838d01614246565b909950975060808b013591508082111561433557600080fd5b6143418c838d01614288565b909750955060a08b013591508082111561435a57600080fd5b506143678b828c01614288565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561439557600080fd5b61439f8585614235565b9250606084013567ffffffffffffffff8111156143bb57600080fd5b6143c786828701614246565b9497909650939450505050565b600080604083850312156143e757600080fd5b6143f083613fff565b91506143fe60208401613fff565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061442d5761442d614407565b9052565b60208101610a79828461441d565b600060a0828403121561445157600080fd5b614459613f09565b90508135815261446b60208301613fff565b602082015261447c60408301613fff565b604082015261448d60608301613fff565b606082015261449e60808301613fff565b608082015292915050565b803561401781613fea565b600082601f8301126144c557600080fd5b813560206144d561407c83613fc6565b82815260059290921b840181019181810190868411156144f457600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156145195760008081fd5b8189019150608080601f19848d030112156145345760008081fd5b61453c613ee0565b878401358381111561454e5760008081fd5b61455c8d8a8388010161405d565b825250604080850135848111156145735760008081fd5b6145818e8b8389010161405d565b8a840152506060808601358581111561459a5760008081fd5b6145a88f8c838a010161405d565b92840192909252949092013593810193909352505083529183019183016144f8565b600061014082840312156145dd57600080fd5b6145e5613f2c565b90506145f1838361443f565b815260a082013567ffffffffffffffff8082111561460e57600080fd5b61461a8583860161405d565b602084015260c084013591508082111561463357600080fd5b61463f8583860161405d565b604084015261465060e085016144a9565b6060840152610100840135608084015261012084013591508082111561467557600080fd5b50614682848285016144b4565b60a08301525092915050565b600082601f83011261469f57600080fd5b813560206146af61407c83613fc6565b82815260059290921b840181019181810190868411156146ce57600080fd5b8286015b848110156120c557803567ffffffffffffffff8111156146f25760008081fd5b6147008986838b01016145ca565b8452509183019183016146d2565b600082601f83011261471f57600080fd5b8135602061472f61407c83613fc6565b82815260059290921b8401810191818101908684111561474e57600080fd5b8286015b848110156120c557803567ffffffffffffffff8082111561477257600080fd5b818901915089603f83011261478657600080fd5b8582013561479661407c82613fc6565b81815260059190911b830160400190878101908c8311156147b657600080fd5b604085015b838110156147ef578035858111156147d257600080fd5b6147e18f6040838a010161405d565b8452509189019189016147bb565b50875250505092840192508301614752565b600082601f83011261481257600080fd5b8135602061482261407c83613fc6565b8083825260208201915060208460051b87010193508684111561484457600080fd5b602086015b848110156120c55780358352918301918301614849565b600082601f83011261487157600080fd5b8135602061488161407c83613fc6565b82815260059290921b840181019181810190868411156148a057600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156148c55760008081fd5b818901915060a080601f19848d030112156148e05760008081fd5b6148e8613f09565b6148f3888501613fff565b8152604080850135848111156149095760008081fd5b6149178e8b8389010161468e565b8a84015250606080860135858111156149305760008081fd5b61493e8f8c838a010161470e565b83850152506080915081860135858111156149595760008081fd5b6149678f8c838a0101614801565b91840191909152509190930135908301525083529183019183016148a4565b600080604080848603121561499a57600080fd5b833567ffffffffffffffff808211156149b257600080fd5b6149be87838801614860565b94506020915081860135818111156149d557600080fd5b8601601f810188136149e657600080fd5b80356149f461407c82613fc6565b81815260059190911b8201840190848101908a831115614a1357600080fd5b8584015b83811015614a9f57803586811115614a2f5760008081fd5b8501603f81018d13614a415760008081fd5b87810135614a5161407c82613fc6565b81815260059190911b82018a0190898101908f831115614a715760008081fd5b928b01925b82841015614a8f5783358252928a0192908a0190614a76565b8652505050918601918601614a17565b50809750505050505050509250929050565b600060208284031215614ac357600080fd5b813567ffffffffffffffff811115614ada57600080fd5b820160a08185031215613ddc57600080fd5b803563ffffffff8116811461401757600080fd5b600060a08284031215614b1257600080fd5b614b1a613f09565b8235614b2581613fea565b8152614b3360208401614aec565b6020820152614b4460408401614aec565b6040820152614b5560608401614aec565b60608201526080830135614b6881613fea565b60808201529392505050565b803560ff8116811461401757600080fd5b600060208284031215614b9757600080fd5b610a7682614b74565b60008151808452602080850194506020840160005b83811015614bda5781516001600160a01b031687529582019590820190600101614bb5565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c3460e0840182614ba0565b90506040840151601f198483030160c0850152614c518282614ba0565b95945050505050565b60008060408385031215614c6d57600080fd5b614c7683613fff565b946020939093013593505050565b60008060208385031215614c9757600080fd5b823567ffffffffffffffff80821115614caf57600080fd5b818501915085601f830112614cc357600080fd5b813581811115614cd257600080fd5b8660208260061b8501011115614ce757600080fd5b60209290920196919550909350505050565b600060208284031215614d0b57600080fd5b610a7682613fff565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136d060a08401826141f6565b600080600060408486031215614d7757600080fd5b833567ffffffffffffffff80821115614d8f57600080fd5b614d9b878388016145ca565b94506020860135915080821115614db157600080fd5b506143c786828701614288565b600060208284031215614dd057600080fd5b8135613ddc81613fea565b600082601f830112614dec57600080fd5b81356020614dfc61407c83613fc6565b8083825260208201915060208460051b870101935086841115614e1e57600080fd5b602086015b848110156120c5578035614e3681613fea565b8352918301918301614e23565b60006020808385031215614e5657600080fd5b823567ffffffffffffffff80821115614e6e57600080fd5b818501915085601f830112614e8257600080fd5b8135614e9061407c82613fc6565b81815260059190911b83018401908481019088831115614eaf57600080fd5b8585015b838110156141c557803585811115614eca57600080fd5b860160c0818c03601f19011215614ee15760008081fd5b614ee9613f2c565b8882013581526040614efc818401614b74565b8a8301526060614f0d818501614b74565b8284015260809150614f2082850161402a565b9083015260a08381013589811115614f385760008081fd5b614f468f8d83880101614ddb565b838501525060c0840135915088821115614f605760008081fd5b614f6e8e8c84870101614ddb565b9083015250845250918601918601614eb3565b600060208284031215614f9357600080fd5b5035919050565b80356001600160e01b038116811461401757600080fd5b600082601f830112614fc257600080fd5b81356020614fd261407c83613fc6565b82815260069290921b84018101918181019086841115614ff157600080fd5b8286015b848110156120c5576040818903121561500e5760008081fd5b615016613f4f565b61501f82613fff565b815261502c858301614f9a565b81860152835291830191604001614ff5565b600082601f83011261504f57600080fd5b8135602061505f61407c83613fc6565b82815260079290921b8401810191818101908684111561507e57600080fd5b8286015b848110156120c557808803608081121561509c5760008081fd5b6150a4613f72565b6150ad83613fff565b8152604080601f19840112156150c35760008081fd5b6150cb613f4f565b92506150d8878501613fff565b83526150e5818501613fff565b8388015281870192909252606083013591810191909152835291830191608001615082565b6000602080838503121561511d57600080fd5b823567ffffffffffffffff8082111561513557600080fd5b8185019150604080838803121561514b57600080fd5b615153613f4f565b83358381111561516257600080fd5b84016040818a03121561517457600080fd5b61517c613f4f565b81358581111561518b57600080fd5b8201601f81018b1361519c57600080fd5b80356151aa61407c82613fc6565b81815260069190911b8201890190898101908d8311156151c957600080fd5b928a01925b828410156152195787848f0312156151e65760008081fd5b6151ee613f4f565b84356151f981613fea565b8152615206858d01614f9a565b818d0152825292870192908a01906151ce565b84525050508187013593508484111561523157600080fd5b61523d8a858401614fb1565b818801528252508385013591508282111561525757600080fd5b6152638883860161503e565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b818110156152e257835180516001600160a01b031684528501516001600160e01b03168584015292840192918501916001016152ab565b50508583015187820388850152805180835290840192506000918401905b8083101561533c578351805167ffffffffffffffff1683528501516001600160e01b031685830152928401926001929092019190850190615300565b50979650505050505050565b602081526000610a76602083018461528b565b67ffffffffffffffff8316815260608101613ddc6020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153c7576153c7615390565b5092915050565b6000602080835260608451604080848701526153ed606087018361528b565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141c557845167ffffffffffffffff81511683528781015161544d89850182805167ffffffffffffffff908116835260209182015116910152565b5084015182870152938601936001929092019160809091019061540e565b60006020828403121561547d57600080fd5b813567ffffffffffffffff81111561549457600080fd5b6136d084828501614860565b81810381811115610a7957610a79615390565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff808416806154e4576154e46154b3565b92169190910692915050565b8082028115828204841417610a7957610a79615390565b60006040828403121561551957600080fd5b615521613f4f565b61552a83613fff565b8152602083013560208201528091505092915050565b600181811c9082168061555457607f821691505b60208210810361557457634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a060408701526155ae60a08701826141f6565b9050606085015186820360608801526155c782826141f6565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561533c57835180516001600160a01b03168352860151868301529285019260019290920191908401906155ea565b602081526000610a76602083018461557a565b608081526000615642608083018761557a565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561568057600080fd5b835161568b8161401c565b602085015190935067ffffffffffffffff8111156156a857600080fd5b8401601f810186136156b957600080fd5b80516156c761407c82614035565b8181528760208385010111156156dc57600080fd5b6156ed8260208301602086016141d2565b809450505050604084015190509250925092565b60006020828403121561571357600080fd5b8151613ddc8161401c565b601f821115610cd8576000816000526020600020601f850160051c810160208610156157475750805b601f850160051c820191505b818110156124df57828155600101615753565b815167ffffffffffffffff81111561578057615780613eca565b6157948161578e8454615540565b8461571e565b602080601f8311600181146157c957600084156157b15750858301515b600019600386901b1c1916600185901b1785556124df565b600085815260208120601f198616915b828110156157f8578886015182559484019460019091019084016157d9565b50858210156158165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c1660608501525060018085016080808601526000815461587881615540565b8060a089015260c0600183166000811461589957600181146158b5576158e5565b60ff19841660c08b015260c083151560051b8b010194506158e5565b85600052602060002060005b848110156158dc5781548c82018501529088019089016158c1565b8b0160c0019550505b50929998505050505050505050565b80820180821115610a7957610a79615390565b60ff8181168382160190811115610a7957610a79615390565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061595f5761595f6154b3565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126159a057600080fd5b83018035915067ffffffffffffffff8211156159bb57600080fd5b60200191503681900382131561384357600080fd5b60208101600583106159e4576159e4614407565b91905290565b60ff81811683821602908116908181146153c7576153c7615390565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a5e5784546001600160a01b031683526001948501949284019201615a39565b50508481036060860152865180825290820192508187019060005b81811015615a9e5782516001600160a01b031685529383019391830191600101615a79565b50505060ff851660808501525090506120c7565b600067ffffffffffffffff808616835280851660208401525060606040830152614c5160608301846141f6565b8281526040602082015260006136d060408301846141f6565b67ffffffffffffffff848116825283166020820152606081016136d0604083018461441d565b615b28818561441d565b606060208201526000615b3e60608301856141f6565b9050826040830152949350505050565b600060208284031215615b6057600080fd5b8151613ddc81613fea565b6020815260008251610100806020850152615b8a6101208501836141f6565b91506020850151615ba7604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615be160a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bfe84836141f6565b935060c08701519150808685030160e0870152615c1b84836141f6565b935060e08701519150808685030183870152506120c783826141f6565b600060208284031215615c4a57600080fd5b5051919050565b600060ff821660ff8103615c6757615c67615390565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c760808301846141f6565b86815260c060208201526000615cbc60c08301886141f6565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d8d57601f19868403018952815160808151818652615d39828701826141f6565b9150508582015185820387870152615d5182826141f6565b91505060408083015186830382880152615d6b83826141f6565b6060948501519790940196909652505098840198925090830190600101615d13565b5090979650505050505050565b602081526000610a766020830184615cf6565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d8d57601f19868403018952615de88383516141f6565b98840198925090830190600101615dcc565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e626101808501836141f6565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e9f84836141f6565b935060608801519150615ebe6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615ee58282615cf6565b9150508281036020840152614c518185615dad56fea164736f6c6343000818000a", } var EVM2EVMMultiOffRampABI = EVM2EVMMultiOffRampMetaData.ABI @@ -1202,6 +1202,7 @@ type EVM2EVMMultiOffRampExecutionStateChanged struct { MessageId [32]byte State uint8 ReturnData []byte + GasUsed *big.Int Raw types.Log } @@ -2332,7 +2333,7 @@ func (EVM2EVMMultiOffRampDynamicConfigSet) Topic() common.Hash { } func (EVM2EVMMultiOffRampExecutionStateChanged) Topic() common.Hash { - return common.HexToHash("0x8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df2") + return common.HexToHash("0xdc8ccbc35e0eebd81239bcd1971fcd53c7eb34034880142a0f43c809a458732f") } func (EVM2EVMMultiOffRampOwnershipTransferRequested) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 1a3dceeaeb..75d7535931 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -11,7 +11,7 @@ ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderT commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin 274d87db70b643e00ab0a7e7845bb4b791f3b613bfc87708d33fc5a8369e2a41 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin f7128dcc2ee6dbcbc976288abcc16970ffb19b59412c5202ef6b259d2007f801 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de -evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin b913487363418c368ca412c4cc4a3b1e411395b3c6b8b982b1c48cdab5c7b10c +evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 06853f6d87f0c0b1f2cb403e45e32934c043028208f60a0111cde405e1bee1ba evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 15cd5695049ab4be1f396ec1d7b609738b2bcefa3740a7a48316e1f72506a34a evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin b0d77babbe635cd6ba04c2af049badc9e9d28a4b6ed6bb75f830ad902a618beb evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 5c02c2b167946b3467636ff2bb58594cb4652fc63d8bdfee2488ed562e2a3e50 From f2e447975d082c64a0ffef21343f3d8605e5f9ce Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Mon, 19 Aug 2024 16:01:35 +0200 Subject: [PATCH 214/432] bump ccip version in license (#1309) --- contracts/package.json | 2 +- contracts/src/v0.8/ccip/LICENSE.md | 8 ++++---- contracts/src/v0.8/ccip/v1.4-CCIP-License-grants.md | 5 ----- contracts/src/v0.8/ccip/v1.5-CCIP-License-grants.md | 8 ++++++++ core/services/ocr2/plugins/ccip/LICENSE.md | 6 +++--- 5 files changed, 16 insertions(+), 13 deletions(-) delete mode 100644 contracts/src/v0.8/ccip/v1.4-CCIP-License-grants.md create mode 100644 contracts/src/v0.8/ccip/v1.5-CCIP-License-grants.md diff --git a/contracts/package.json b/contracts/package.json index e9dedf9578..200548ac66 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -45,7 +45,7 @@ "abi/v0.8/", "src/v0.8/ccip/LICENSE.md", "src/v0.8/ccip/LICENSE-MIT.md", - "src/v0.8/ccip/v1.4-CCIP-License-grants.md" + "src/v0.8/ccip/v1.5-CCIP-License-grants.md" ], "pnpm": { "_comment": "See https://github.com/ethers-io/ethers.js/discussions/2849#discussioncomment-2696454", diff --git a/contracts/src/v0.8/ccip/LICENSE.md b/contracts/src/v0.8/ccip/LICENSE.md index 5f2783f7a3..b2e82483e9 100644 --- a/contracts/src/v0.8/ccip/LICENSE.md +++ b/contracts/src/v0.8/ccip/LICENSE.md @@ -9,13 +9,13 @@ Parameters Licensor: SmartContract Chainlink Limited SEZC -Licensed Work: Cross-Chain Interoperability Protocol v1.4 +Licensed Work: Cross-Chain Interoperability Protocol v1.5 The Licensed Work is (c) 2023 SmartContract Chainlink Limited SEZC -Additional Use Grant: Any uses listed and defined at [v1.4-CCIP-License-grants]( -./v1.4-CCIP-License-grants) +Additional Use Grant: Any uses listed and defined at [v1.5-CCIP-License-grants]( +./v1.5-CCIP-License-grants.md) -Change Date: May 23, 2027 +Change Date: Aug 16, 2028 Change License: MIT diff --git a/contracts/src/v0.8/ccip/v1.4-CCIP-License-grants.md b/contracts/src/v0.8/ccip/v1.4-CCIP-License-grants.md deleted file mode 100644 index f206b8adcc..0000000000 --- a/contracts/src/v0.8/ccip/v1.4-CCIP-License-grants.md +++ /dev/null @@ -1,5 +0,0 @@ -v1.4-CCIP-License-grants - -Additional Use Grant(s): - -You may make use of the Cross-Chain Interoperability Protocol v1.4 (which is available subject to the license here the “Licensed Work ”) solely for purposes of importing client-side libraries or example clients to facilitate the integration of the Licensed Work into your application. \ No newline at end of file diff --git a/contracts/src/v0.8/ccip/v1.5-CCIP-License-grants.md b/contracts/src/v0.8/ccip/v1.5-CCIP-License-grants.md new file mode 100644 index 0000000000..ef0f55ea92 --- /dev/null +++ b/contracts/src/v0.8/ccip/v1.5-CCIP-License-grants.md @@ -0,0 +1,8 @@ +v1.5-CCIP-License-grants + +Additional Use Grant(s): + +You may make use of the Cross-Chain Interoperability Protocol v1.5 (which is available subject to the license here, the “Licensed Work ”) solely for purposes of + +1. importing client-side libraries or example clients to facilitate the integration of the Licensed Work into your application. +2. Developing, deploying and operating [the token pool contracts](./pools) solely for purposes of the integration and use of CCIP. \ No newline at end of file diff --git a/core/services/ocr2/plugins/ccip/LICENSE.md b/core/services/ocr2/plugins/ccip/LICENSE.md index b127e1a823..96fdb2b139 100644 --- a/core/services/ocr2/plugins/ccip/LICENSE.md +++ b/core/services/ocr2/plugins/ccip/LICENSE.md @@ -9,12 +9,12 @@ Parameters Licensor: SmartContract Chainlink Limited SEZC -Licensed Work: Cross-Chain Interoperability Protocol v1.4 +Licensed Work: Cross-Chain Interoperability Protocol v1.5 The Licensed Work is (c) 2023 SmartContract Chainlink Limited SEZC -Additional Use Grant: Any uses listed and defined at [v1.4-CCIP-License-grants](../../../../../contracts/src/v0.8/ccip/v1.4-CCIP-License-grants) +Additional Use Grant: Any uses listed and defined at [v1.5-CCIP-License-grants](../../../../../contracts/src/v0.8/ccip/v1.5-CCIP-License-grants.md) -Change Date: May 23, 2027 +Change Date: Aug 16, 2028 Change License: MIT From e862492e670f2868751bf4be64f357691fdda435 Mon Sep 17 00:00:00 2001 From: Makram Date: Mon, 19 Aug 2024 17:18:33 +0300 Subject: [PATCH 215/432] core/capabilities/ccip: use commit plugin w/ state machine (#1321) ## Motivation Use the commit plugin state machine implementation. ## Solution Use the commit plugin state machine implementation. --- core/capabilities/ccip/oraclecreator/inprocess.go | 2 +- integration-tests/deployment/ccip/deploy_home_chain.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/capabilities/ccip/oraclecreator/inprocess.go b/core/capabilities/ccip/oraclecreator/inprocess.go index fa74c1b0ea..266ffc2d77 100644 --- a/core/capabilities/ccip/oraclecreator/inprocess.go +++ b/core/capabilities/ccip/oraclecreator/inprocess.go @@ -28,7 +28,7 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" - commitocr3 "github.com/smartcontractkit/chainlink-ccip/commit" + commitocr3 "github.com/smartcontractkit/chainlink-ccip/commitrmnocb" execocr3 "github.com/smartcontractkit/chainlink-ccip/execute" ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" diff --git a/integration-tests/deployment/ccip/deploy_home_chain.go b/integration-tests/deployment/ccip/deploy_home_chain.go index ad76dbf892..a79fee6678 100644 --- a/integration-tests/deployment/ccip/deploy_home_chain.go +++ b/integration-tests/deployment/ccip/deploy_home_chain.go @@ -283,7 +283,7 @@ func AddDON( transmittersBytes := make([][]byte, len(transmitters)) for i, transmitter := range transmitters { parsed, err2 := common.ParseHexOrString(string(transmitter)) - if err != nil { + if err2 != nil { return err2 } transmittersBytes[i] = parsed From e5e5e29fde65f81b11d5caf4de6cc1e57b2f98c7 Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Mon, 19 Aug 2024 17:53:14 +0200 Subject: [PATCH 216/432] set more correct gas overheads (#1319) Cleanup & more realistic values for gas overheads --- contracts/gas-snapshots/ccip.gas-snapshot | 48 +- contracts/package.json | 15 +- contracts/src/v0.8/ccip/test/BaseTest.t.sol | 23 +- .../src/v0.8/ccip/test/NonceManager.t.sol | 3 +- contracts/src/v0.8/ccip/test/TokenSetup.t.sol | 9 +- .../src/v0.8/ccip/test/arm/ARMProxy.t.sol | 3 +- .../MultiOnRampTokenPoolReentrancy.t.sol | 6 +- .../onRamp/OnRampTokenPoolReentrancy.t.sol | 4 +- .../ccip/test/commitStore/CommitStore.t.sol | 42 +- .../src/v0.8/ccip/test/e2e/End2End.t.sol | 2 +- .../v0.8/ccip/test/e2e/MultiRampsEnd2End.sol | 3 +- .../MultiAggregateRateLimiterHelper.sol | 1 - .../ccip/test/legacy/TokenPoolAndProxy.t.sol | 35 +- .../src/v0.8/ccip/test/mocks/MockRMN.sol | 2 - .../ccip/test/mocks/test/MockRouterTest.t.sol | 2 +- .../test/offRamp/EVM2EVMMultiOffRamp.t.sol | 58 +-- .../offRamp/EVM2EVMMultiOffRampSetup.t.sol | 21 +- .../ccip/test/offRamp/EVM2EVMOffRamp.t.sol | 30 +- .../test/offRamp/EVM2EVMOffRampSetup.t.sol | 14 +- .../ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol | 23 +- .../test/onRamp/EVM2EVMMultiOnRampSetup.t.sol | 17 +- .../v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol | 29 +- .../ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol | 13 +- .../test/pools/BurnFromMintTokenPool.t.sol | 5 +- .../v0.8/ccip/test/pools/BurnMintSetup.t.sol | 4 +- .../ccip/test/pools/BurnMintTokenPool.t.sol | 13 +- .../pools/BurnWithFromMintTokenPool.t.sol | 5 +- .../test/pools/LockReleaseTokenPool.t.sol | 19 +- .../src/v0.8/ccip/test/pools/TokenPool.t.sol | 41 +- .../v0.8/ccip/test/pools/USDCTokenPool.t.sol | 24 +- .../test/priceRegistry/PriceRegistry.t.sol | 486 ++---------------- .../priceRegistry/PriceRegistrySetup.t.sol | 418 +++++++++++++++ .../rateLimiter/AggregateRateLimiter.t.sol | 4 +- .../MultiAggregateRateLimiter.t.sol | 8 +- .../src/v0.8/ccip/test/router/Router.t.sol | 67 +-- .../v0.8/ccip/test/router/RouterSetup.t.sol | 4 +- 36 files changed, 726 insertions(+), 775 deletions(-) create mode 100644 contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistrySetup.t.sol diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index e1b2d6d5b3..f9c7b93aa7 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -123,22 +123,22 @@ CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424256) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1104304) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38416) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1104303) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38408) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 106250) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 87421) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 38958) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 96515) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 41964) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 87409) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 38954) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 96511) +EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 41956) EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 88684) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 468131) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99235) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12399) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 93193) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 109906) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13267) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17992) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15347) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 468115) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99227) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12395) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 93181) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 109890) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13263) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17988) +EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15343) EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 313594) EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 254984) EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 166123) @@ -146,7 +146,7 @@ EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 153140) EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 518887) EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10439) -EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15688) +EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15684) EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67458) EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59734) EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58814) @@ -166,7 +166,7 @@ EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77608) EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 205117) EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6532473) EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47788) -EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 6125452) +EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 6125436) EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137067) EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103784) EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101677) @@ -221,9 +221,9 @@ EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 515089) EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 485207) EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 133513) EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 162713) -EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3677612) -EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118399) -EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87606) +EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3674540) +EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118375) +EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87586) EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75635) EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26471) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 168604) @@ -236,10 +236,10 @@ EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 208322) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 208944) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 662979) EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 301931) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 164054) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 23740) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 64488) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 39524) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 164042) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 23736) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 64484) +EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 39516) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 81512) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 176140) EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 189342) @@ -861,7 +861,7 @@ Router_ccipSend:test_NonLinkFeeToken_Success() (gas: 242732) Router_ccipSend:test_UnsupportedDestinationChain_Revert() (gas: 24749) Router_ccipSend:test_WhenNotHealthy_Revert() (gas: 44724) Router_ccipSend:test_WrappedNativeFeeToken_Success() (gas: 174440) -Router_ccipSend:test_ZeroFeeAndGasPrice_Success() (gas: 245146) +Router_ccipSend:test_ZeroFeeAndGasPrice_Success() (gas: 244856) Router_constructor:test_Constructor_Success() (gas: 13074) Router_getArmProxy:test_getArmProxy() (gas: 10561) Router_getFee:test_GetFeeSupportedChain_Success() (gas: 46464) diff --git a/contracts/package.json b/contracts/package.json index 200548ac66..78f4cf36b8 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -24,28 +24,37 @@ }, "files": [ "src/v0.8/ccip/**/*.sol", - "!src/v0.8/ccip/test/**/*", - "src/v0.8/ccip/test/mocks/**/*", "src/v0.8/shared/access/ConfirmedOwner.sol", "src/v0.8/shared/access/ConfirmedOwnerWithProposal.sol", "src/v0.8/shared/access/OwnerIsCreator.sol", + "src/v0.8/shared/access/AuthorizedCallers.sol", "src/v0.8/shared/call/CallWithExactGas.sol", + "src/v0.8/shared/enumerable/EnumerableMapBytes32.sol", "src/v0.8/shared/enumerable/EnumerableMapAddresses.sol", "src/v0.8/shared/interfaces/IOwnable.sol", "src/v0.8/shared/interfaces/ITypeAndVersion.sol", "src/v0.8/shared/interfaces/IERC677Receiver.sol", + "src/v0.8/shared/interfaces/AggregatorV3Interface.sol", "src/v0.8/shared/token/ERC20/IBurnMintERC20.sol", "src/v0.8/shared/token/ERC677/IERC677.sol", "src/v0.8/shared/token/ERC677/IERC677Receiver.sol", "src/v0.8/shared/token/ERC677/ERC677.sol", "src/v0.8/shared/token/ERC677/BurnMintERC677.sol", + "src/v0.8/shared/util/SortedSetValidationUtil.sol", + "src/v0.8/liquiditymanager/interfaces/ILiquidityContainer.sol", + "src/v0.8/keystone/interfaces/ICapabilityConfiguration.sol", "src/v0.8/vendor/openzeppelin-solidity", "src/v0.8/vendor/Context.sol", "src/v0.8/vendor/Pausable.sol", "abi/v0.8/", "src/v0.8/ccip/LICENSE.md", "src/v0.8/ccip/LICENSE-MIT.md", - "src/v0.8/ccip/v1.5-CCIP-License-grants.md" + "src/v0.8/ccip/v1.5-CCIP-License-grants.md", + "!src/v0.8/ccip/test/**/*", + "src/v0.8/ccip/test/mocks/**/*", + "!src/v0.8/ccip/test/mocks/test/*", + "!src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol", + "!src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol" ], "pnpm": { "_comment": "See https://github.com/ethers-io/ethers.js/discussions/2849#discussioncomment-2696454", diff --git a/contracts/src/v0.8/ccip/test/BaseTest.t.sol b/contracts/src/v0.8/ccip/test/BaseTest.t.sol index 7570447cee..2eb44ec485 100644 --- a/contracts/src/v0.8/ccip/test/BaseTest.t.sol +++ b/contracts/src/v0.8/ccip/test/BaseTest.t.sol @@ -34,11 +34,11 @@ contract BaseTest is Test { // Onramp uint96 internal constant MAX_NOP_FEES_JUELS = 1e27; uint96 internal constant MAX_MSG_FEES_JUELS = 1e18; - uint32 internal constant DEST_GAS_OVERHEAD = 350_000; + uint32 internal constant DEST_GAS_OVERHEAD = 300_000; uint16 internal constant DEST_GAS_PER_PAYLOAD_BYTE = 16; uint16 internal constant DEFAULT_TOKEN_FEE_USD_CENTS = 50; - uint32 internal constant DEFAULT_TOKEN_DEST_GAS_OVERHEAD = 85_000; + uint32 internal constant DEFAULT_TOKEN_DEST_GAS_OVERHEAD = 90_000; uint32 internal constant DEFAULT_TOKEN_BYTES_OVERHEAD = 32; bool private s_baseTestInitialized; @@ -87,15 +87,15 @@ contract BaseTest is Test { s_mockRMN = new MockRMN(); } - function getOutboundRateLimiterConfig() internal pure returns (RateLimiter.Config memory) { + function _getOutboundRateLimiterConfig() internal pure returns (RateLimiter.Config memory) { return RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e15}); } - function getInboundRateLimiterConfig() internal pure returns (RateLimiter.Config memory) { + function _getInboundRateLimiterConfig() internal pure returns (RateLimiter.Config memory) { return RateLimiter.Config({isEnabled: true, capacity: 222e30, rate: 1e18}); } - function getSingleTokenPriceUpdateStruct( + function _getSingleTokenPriceUpdateStruct( address token, uint224 price ) internal pure returns (Internal.PriceUpdates memory) { @@ -107,17 +107,4 @@ contract BaseTest is Test { return priceUpdates; } - - function getSingleGasPriceUpdateStruct( - uint64 chainSelector, - uint224 usdPerUnitGas - ) internal pure returns (Internal.PriceUpdates memory) { - Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); - gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: chainSelector, usdPerUnitGas: usdPerUnitGas}); - - Internal.PriceUpdates memory priceUpdates = - Internal.PriceUpdates({tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), gasPriceUpdates: gasPriceUpdates}); - - return priceUpdates; - } } diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol index 444329220d..bcf8c9328b 100644 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -12,7 +12,6 @@ import {EVM2EVMMultiOnRamp} from "../onRamp/EVM2EVMMultiOnRamp.sol"; import {EVM2EVMOnRamp} from "../onRamp/EVM2EVMOnRamp.sol"; import {BaseTest} from "./BaseTest.t.sol"; -import {EVM2EVMMultiOnRampHelper} from "./helpers/EVM2EVMMultiOnRampHelper.sol"; import {EVM2EVMOffRampHelper} from "./helpers/EVM2EVMOffRampHelper.sol"; import {EVM2EVMOnRampHelper} from "./helpers/EVM2EVMOnRampHelper.sol"; import {MockCommitStore} from "./mocks/MockCommitStore.sol"; @@ -214,7 +213,7 @@ contract NonceManager_OnRampUpgrade is EVM2EVMMultiOnRampSetup { minFeeUSDCents: 1_00, // 1 USD maxFeeUSDCents: 1000_00, // 1,000 USD deciBps: 2_5, // 2.5 bps, or 0.025% - destGasOverhead: 40_000, + destGasOverhead: 140_000, destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES), aggregateRateLimitEnabled: true }); diff --git a/contracts/src/v0.8/ccip/test/TokenSetup.t.sol b/contracts/src/v0.8/ccip/test/TokenSetup.t.sol index 182d92c5c9..203145881e 100644 --- a/contracts/src/v0.8/ccip/test/TokenSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/TokenSetup.t.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IPoolV1} from "../interfaces/IPool.sol"; - import {BurnMintERC677} from "../../shared/token/ERC677/BurnMintERC677.sol"; import {Client} from "../libraries/Client.sol"; import {BurnMintTokenPool} from "../pools/BurnMintTokenPool.sol"; @@ -138,7 +136,7 @@ contract TokenSetup is RouterSetup { } } - function getCastedSourceEVMTokenAmountsWithZeroAmounts() + function _getCastedSourceEVMTokenAmountsWithZeroAmounts() internal view returns (Client.EVMTokenAmount[] memory tokenAmounts) @@ -147,6 +145,7 @@ contract TokenSetup is RouterSetup { for (uint256 i = 0; i < tokenAmounts.length; ++i) { tokenAmounts[i].token = s_sourceTokens[i]; } + return tokenAmounts; } function _setPool( @@ -170,8 +169,8 @@ contract TokenSetup is RouterSetup { remotePoolAddress: abi.encode(remotePoolAddress), remoteTokenAddress: abi.encode(remoteToken), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); TokenPool(pool).applyChainUpdates(chainUpdates); diff --git a/contracts/src/v0.8/ccip/test/arm/ARMProxy.t.sol b/contracts/src/v0.8/ccip/test/arm/ARMProxy.t.sol index 24b617c82a..f1889fae75 100644 --- a/contracts/src/v0.8/ccip/test/arm/ARMProxy.t.sol +++ b/contracts/src/v0.8/ccip/test/arm/ARMProxy.t.sol @@ -4,9 +4,8 @@ pragma solidity 0.8.24; import {IRMN} from "../../interfaces/IRMN.sol"; import {ARMProxy} from "../../ARMProxy.sol"; -import {RMN} from "../../RMN.sol"; import {MockRMN} from "../mocks/MockRMN.sol"; -import {RMNSetup, makeSubjects} from "./RMNSetup.t.sol"; +import {RMNSetup} from "./RMNSetup.t.sol"; contract ARMProxyTest is RMNSetup { MockRMN internal s_mockRMN; diff --git a/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol b/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol index 5deeda6406..d31cd35016 100644 --- a/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol +++ b/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol @@ -11,8 +11,6 @@ import {ReentrantMaliciousTokenPool} from "./ReentrantMaliciousTokenPool.sol"; import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -import {console} from "forge-std/console.sol"; - /// @title MultiOnRampTokenPoolReentrancy /// Attempts to perform a reentrancy exploit on Onramp with a malicious TokenPool contract MultiOnRampTokenPoolReentrancy is EVM2EVMMultiOnRampSetup { @@ -41,8 +39,8 @@ contract MultiOnRampTokenPoolReentrancy is EVM2EVMMultiOnRampSetup { remotePoolAddress: abi.encode(s_destPoolBySourceToken[s_sourceTokens[0]]), remoteTokenAddress: abi.encode(s_destTokens[0]), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_maliciousTokenPool.applyChainUpdates(chainUpdates); s_sourcePoolByToken[address(s_sourceToken)] = address(s_maliciousTokenPool); diff --git a/contracts/src/v0.8/ccip/test/attacks/onRamp/OnRampTokenPoolReentrancy.t.sol b/contracts/src/v0.8/ccip/test/attacks/onRamp/OnRampTokenPoolReentrancy.t.sol index 8fc71be857..03db40a293 100644 --- a/contracts/src/v0.8/ccip/test/attacks/onRamp/OnRampTokenPoolReentrancy.t.sol +++ b/contracts/src/v0.8/ccip/test/attacks/onRamp/OnRampTokenPoolReentrancy.t.sol @@ -39,8 +39,8 @@ contract OnRampTokenPoolReentrancy is EVM2EVMOnRampSetup { remotePoolAddress: abi.encode(s_destPoolBySourceToken[s_sourceTokens[0]]), remoteTokenAddress: abi.encode(s_destTokens[0]), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_maliciousTokenPool.applyChainUpdates(chainUpdates); s_sourcePoolByToken[address(s_sourceToken)] = address(s_maliciousTokenPool); diff --git a/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol b/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol index 8c5e745f43..7ea64c9f89 100644 --- a/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol +++ b/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol @@ -12,7 +12,7 @@ import {MerkleMultiProof} from "../../libraries/MerkleMultiProof.sol"; import {OCR2Abstract} from "../../ocr/OCR2Abstract.sol"; import {CommitStoreHelper} from "../helpers/CommitStoreHelper.sol"; import {OCR2BaseSetup} from "../ocr/OCR2Base.t.sol"; -import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; +import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; contract CommitStoreSetup is PriceRegistrySetup, OCR2BaseSetup { CommitStoreHelper internal s_commitStore; @@ -214,7 +214,7 @@ contract CommitStore_resetUnblessedRoots is CommitStoreRealRMNSetup { rootsToReset[2] = "3"; CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getEmptyPriceUpdates(), + priceUpdates: _getEmptyPriceUpdates(), interval: CommitStore.Interval(1, 2), merkleRoot: rootsToReset[0] }); @@ -222,7 +222,7 @@ contract CommitStore_resetUnblessedRoots is CommitStoreRealRMNSetup { s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); report = CommitStore.CommitReport({ - priceUpdates: getEmptyPriceUpdates(), + priceUpdates: _getEmptyPriceUpdates(), interval: CommitStore.Interval(3, 4), merkleRoot: rootsToReset[1] }); @@ -230,7 +230,7 @@ contract CommitStore_resetUnblessedRoots is CommitStoreRealRMNSetup { s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); report = CommitStore.CommitReport({ - priceUpdates: getEmptyPriceUpdates(), + priceUpdates: _getEmptyPriceUpdates(), interval: CommitStore.Interval(5, 5), merkleRoot: rootsToReset[2] }); @@ -273,7 +273,7 @@ contract CommitStore_report is CommitStoreSetup { uint64 max1 = 931; bytes32 root = "Only a single root"; CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getEmptyPriceUpdates(), + priceUpdates: _getEmptyPriceUpdates(), interval: CommitStore.Interval(1, max1), merkleRoot: root }); @@ -296,7 +296,7 @@ contract CommitStore_report is CommitStoreSetup { uint64 max1 = 12; CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(1, max1), merkleRoot: "test #2" }); @@ -316,7 +316,7 @@ contract CommitStore_report is CommitStoreSetup { IPriceRegistry(s_commitStore.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value; CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(1, maxSeq), merkleRoot: "stale report 1" }); @@ -329,7 +329,7 @@ contract CommitStore_report is CommitStoreSetup { assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); report = CommitStore.CommitReport({ - priceUpdates: getEmptyPriceUpdates(), + priceUpdates: _getEmptyPriceUpdates(), interval: CommitStore.Interval(maxSeq + 1, maxSeq * 2), merkleRoot: "stale report 2" }); @@ -348,7 +348,7 @@ contract CommitStore_report is CommitStoreSetup { function test_OnlyTokenPriceUpdates_Success() public { CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(0, 0), merkleRoot: "" }); @@ -362,7 +362,7 @@ contract CommitStore_report is CommitStoreSetup { function test_OnlyGasPriceUpdates_Success() public { CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(0, 0), merkleRoot: "" }); @@ -380,7 +380,7 @@ contract CommitStore_report is CommitStoreSetup { uint224 tokenPrice2 = 5e18; CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice1), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice1), interval: CommitStore.Interval(0, 0), merkleRoot: "" }); @@ -392,7 +392,7 @@ contract CommitStore_report is CommitStoreSetup { assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); report = CommitStore.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice2), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice2), interval: CommitStore.Interval(1, maxSeq), merkleRoot: "stale report" }); @@ -427,7 +427,7 @@ contract CommitStore_report is CommitStoreSetup { function test_InvalidRootRevert() public { CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getEmptyPriceUpdates(), + priceUpdates: _getEmptyPriceUpdates(), interval: CommitStore.Interval(1, 4), merkleRoot: bytes32(0) }); @@ -439,7 +439,7 @@ contract CommitStore_report is CommitStoreSetup { function test_InvalidInterval_Revert() public { CommitStore.Interval memory interval = CommitStore.Interval(2, 2); CommitStore.CommitReport memory report = - CommitStore.CommitReport({priceUpdates: getEmptyPriceUpdates(), interval: interval, merkleRoot: bytes32(0)}); + CommitStore.CommitReport({priceUpdates: _getEmptyPriceUpdates(), interval: interval, merkleRoot: bytes32(0)}); vm.expectRevert(abi.encodeWithSelector(CommitStore.InvalidInterval.selector, interval)); @@ -449,7 +449,7 @@ contract CommitStore_report is CommitStoreSetup { function test_InvalidIntervalMinLargerThanMax_Revert() public { CommitStore.Interval memory interval = CommitStore.Interval(1, 0); CommitStore.CommitReport memory report = - CommitStore.CommitReport({priceUpdates: getEmptyPriceUpdates(), interval: interval, merkleRoot: bytes32(0)}); + CommitStore.CommitReport({priceUpdates: _getEmptyPriceUpdates(), interval: interval, merkleRoot: bytes32(0)}); vm.expectRevert(abi.encodeWithSelector(CommitStore.InvalidInterval.selector, interval)); @@ -458,7 +458,7 @@ contract CommitStore_report is CommitStoreSetup { function test_ZeroEpochAndRound_Revert() public { CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(0, 0), merkleRoot: bytes32(0) }); @@ -470,7 +470,7 @@ contract CommitStore_report is CommitStoreSetup { function test_OnlyPriceUpdateStaleReport_Revert() public { CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(0, 0), merkleRoot: bytes32(0) }); @@ -485,14 +485,14 @@ contract CommitStore_report is CommitStoreSetup { function test_RootAlreadyCommitted_Revert() public { CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getEmptyPriceUpdates(), + priceUpdates: _getEmptyPriceUpdates(), interval: CommitStore.Interval(1, 2), merkleRoot: "Only a single root" }); s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); report = CommitStore.CommitReport({ - priceUpdates: getEmptyPriceUpdates(), + priceUpdates: _getEmptyPriceUpdates(), interval: CommitStore.Interval(3, 3), merkleRoot: "Only a single root" }); @@ -510,7 +510,7 @@ contract CommitStore_verify is CommitStoreRealRMNSetup { s_commitStore.report( abi.encode( CommitStore.CommitReport({ - priceUpdates: getEmptyPriceUpdates(), + priceUpdates: _getEmptyPriceUpdates(), interval: CommitStore.Interval(1, 2), merkleRoot: leaves[0] }) @@ -529,7 +529,7 @@ contract CommitStore_verify is CommitStoreRealRMNSetup { s_commitStore.report( abi.encode( CommitStore.CommitReport({ - priceUpdates: getEmptyPriceUpdates(), + priceUpdates: _getEmptyPriceUpdates(), interval: CommitStore.Interval(1, 2), merkleRoot: leaves[0] }) diff --git a/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol b/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol index 90df377313..114265a248 100644 --- a/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol +++ b/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol @@ -52,7 +52,7 @@ contract E2E is EVM2EVMOnRampSetup, CommitStoreSetup, EVM2EVMOffRampSetup { bytes memory commitReport = abi.encode( CommitStore.CommitReport({ - priceUpdates: getEmptyPriceUpdates(), + priceUpdates: _getEmptyPriceUpdates(), interval: CommitStore.Interval(messages[0].sequenceNumber, messages[2].sequenceNumber), merkleRoot: merkleRoots[0] }) diff --git a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol index 806b133371..9116c79b9e 100644 --- a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol +++ b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; import {NonceManager} from "../../NonceManager.sol"; +import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; import "../helpers/MerkleHelper.sol"; import "../offRamp/EVM2EVMMultiOffRampSetup.t.sol"; @@ -149,7 +150,7 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { }); EVM2EVMMultiOffRamp.CommitReport memory report = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); vm.resumeGasMetering(); _commit(report, ++s_latestSequenceNumber); diff --git a/contracts/src/v0.8/ccip/test/helpers/MultiAggregateRateLimiterHelper.sol b/contracts/src/v0.8/ccip/test/helpers/MultiAggregateRateLimiterHelper.sol index d9386ca7db..2bcaabda33 100644 --- a/contracts/src/v0.8/ccip/test/helpers/MultiAggregateRateLimiterHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/MultiAggregateRateLimiterHelper.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.24; import {MultiAggregateRateLimiter} from "../../MultiAggregateRateLimiter.sol"; -import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; import {Client} from "../../libraries/Client.sol"; contract MultiAggregateRateLimiterHelper is MultiAggregateRateLimiter { diff --git a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol index a69ca0952c..9645d70b7a 100644 --- a/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol +++ b/contracts/src/v0.8/ccip/test/legacy/TokenPoolAndProxy.t.sol @@ -5,7 +5,6 @@ import {IPoolV1} from "../../interfaces/IPool.sol"; import {IPoolPriorTo1_5} from "../../interfaces/IPoolPriorTo1_5.sol"; import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; -import {PriceRegistry} from "../../PriceRegistry.sol"; import {Router} from "../../Router.sol"; import {Client} from "../../libraries/Client.sol"; import {Pool} from "../../libraries/Pool.sol"; @@ -14,8 +13,6 @@ import {BurnMintTokenPoolAndProxy} from "../../pools/BurnMintTokenPoolAndProxy.s import {BurnWithFromMintTokenPoolAndProxy} from "../../pools/BurnWithFromMintTokenPoolAndProxy.sol"; import {LockReleaseTokenPoolAndProxy} from "../../pools/LockReleaseTokenPoolAndProxy.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; -import {TokenSetup} from "../TokenSetup.t.sol"; -import {EVM2EVMOnRampHelper} from "../helpers/EVM2EVMOnRampHelper.sol"; import {EVM2EVMOnRampSetup} from "../onRamp/EVM2EVMOnRampSetup.t.sol"; import {RouterSetup} from "../router/RouterSetup.t.sol"; import {BurnMintTokenPool1_2, TokenPool1_2} from "./BurnMintTokenPool1_2.sol"; @@ -260,13 +257,13 @@ contract TokenPoolAndProxyMigration is EVM2EVMOnRampSetup { onRampUpdates[0] = TokenPool1_2.RampUpdate({ ramp: address(s_onRamp), allowed: true, - rateLimiterConfig: getInboundRateLimiterConfig() + rateLimiterConfig: _getInboundRateLimiterConfig() }); TokenPool1_2.RampUpdate[] memory offRampUpdates = new TokenPool1_2.RampUpdate[](1); offRampUpdates[0] = TokenPool1_2.RampUpdate({ ramp: address(s_offRamp), allowed: true, - rateLimiterConfig: getInboundRateLimiterConfig() + rateLimiterConfig: _getInboundRateLimiterConfig() }); BurnMintTokenPool1_2(address(s_legacyPool)).applyRampUpdates(onRampUpdates, offRampUpdates); } @@ -280,14 +277,14 @@ contract TokenPoolAndProxyMigration is EVM2EVMOnRampSetup { legacyChainUpdates[0] = TokenPool1_4.ChainUpdate({ remoteChainSelector: DEST_CHAIN_SELECTOR, allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); legacyChainUpdates[1] = TokenPool1_4.ChainUpdate({ remoteChainSelector: SOURCE_CHAIN_SELECTOR, allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); BurnMintTokenPool1_4(address(s_legacyPool)).applyChainUpdates(legacyChainUpdates); } @@ -306,16 +303,16 @@ contract TokenPoolAndProxyMigration is EVM2EVMOnRampSetup { remotePoolAddress: abi.encode(s_destTokenPool), remoteTokenAddress: abi.encode(s_destToken), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); chainUpdates[1] = TokenPool.ChainUpdate({ remoteChainSelector: SOURCE_CHAIN_SELECTOR, remotePoolAddress: abi.encode(s_sourcePool), remoteTokenAddress: abi.encode(s_sourceToken), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_newPool.applyChainUpdates(chainUpdates); @@ -395,10 +392,10 @@ contract TokenPoolAndProxy is EVM2EVMOnRampSetup { TokenPool1_2.RampUpdate[] memory onRampUpdates = new TokenPool1_2.RampUpdate[](1); onRampUpdates[0] = - TokenPool1_2.RampUpdate({ramp: address(s_pool), allowed: true, rateLimiterConfig: getInboundRateLimiterConfig()}); + TokenPool1_2.RampUpdate({ramp: address(s_pool), allowed: true, rateLimiterConfig: _getInboundRateLimiterConfig()}); TokenPool1_2.RampUpdate[] memory offRampUpdates = new TokenPool1_2.RampUpdate[](1); offRampUpdates[0] = - TokenPool1_2.RampUpdate({ramp: address(s_pool), allowed: true, rateLimiterConfig: getInboundRateLimiterConfig()}); + TokenPool1_2.RampUpdate({ramp: address(s_pool), allowed: true, rateLimiterConfig: _getInboundRateLimiterConfig()}); BurnMintTokenPool1_2(address(s_legacyPool)).applyRampUpdates(onRampUpdates, offRampUpdates); } @@ -409,8 +406,8 @@ contract TokenPoolAndProxy is EVM2EVMOnRampSetup { remotePoolAddress: abi.encode(s_destPool), remoteTokenAddress: abi.encode(s_destToken), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); BurnMintTokenPoolAndProxy(address(s_pool)).applyChainUpdates(chains); @@ -556,8 +553,8 @@ contract LockReleaseTokenPoolAndProxySetup is RouterSetup { remotePoolAddress: abi.encode(s_destPoolAddress), remoteTokenAddress: abi.encode(address(s_token)), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_lockReleaseTokenPoolAndProxy.applyChainUpdates(chainUpdate); diff --git a/contracts/src/v0.8/ccip/test/mocks/MockRMN.sol b/contracts/src/v0.8/ccip/test/mocks/MockRMN.sol index 3f7b0200e6..343078cc37 100644 --- a/contracts/src/v0.8/ccip/test/mocks/MockRMN.sol +++ b/contracts/src/v0.8/ccip/test/mocks/MockRMN.sol @@ -1,9 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {RMN} from "../../RMN.sol"; import {IRMN} from "../../interfaces/IRMN.sol"; -import {OwnerIsCreator} from "./../../../shared/access/OwnerIsCreator.sol"; /// @notice WARNING: This contract is to be only used for testing, all methods are unprotected. contract MockRMN is IRMN { diff --git a/contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol b/contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol index 91798b494d..6cbe7bf58f 100644 --- a/contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol +++ b/contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import {Client} from "../../../libraries/Client.sol"; import {TokenSetup} from "../../TokenSetup.t.sol"; -import {IRouter, IRouterClient, MockCCIPRouter} from "../MockRouter.sol"; +import {IRouterClient, MockCCIPRouter} from "../MockRouter.sol"; import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol index cfe43a972f..3acc1adae0 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {ICommitStore} from "../../interfaces/ICommitStore.sol"; import {IMessageInterceptor} from "../../interfaces/IMessageInterceptor.sol"; import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; import {IRMN} from "../../interfaces/IRMN.sol"; @@ -11,8 +10,6 @@ import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; import {CallWithExactGas} from "../../../shared/call/CallWithExactGas.sol"; import {NonceManager} from "../../NonceManager.sol"; import {PriceRegistry} from "../../PriceRegistry.sol"; -import {RMN} from "../../RMN.sol"; -import {Router} from "../../Router.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {MerkleMultiProof} from "../../libraries/MerkleMultiProof.sol"; @@ -24,7 +21,6 @@ import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; import {EVM2EVMMultiOffRampHelper} from "../helpers/EVM2EVMMultiOffRampHelper.sol"; import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; -import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; import {ConformingReceiver} from "../helpers/receivers/ConformingReceiver.sol"; import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; import {MaybeRevertMessageReceiverNo165} from "../helpers/receivers/MaybeRevertMessageReceiverNo165.sol"; @@ -958,7 +954,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { }); return EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots }); } @@ -2507,7 +2503,7 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { } function test_releaseOrMintTokens_Success() public { - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); IERC20 dstToken1 = IERC20(s_destFeeToken); uint256 startingBalance = dstToken1.balanceOf(OWNER); uint256 amount1 = 100; @@ -2543,7 +2539,7 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { } function test_releaseOrMintTokens_destDenominatedDecimals_Success() public { - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); uint256 amount = 100; uint256 destinationDenominationMultiplier = 1000; srcTokenAmounts[1].amount = amount; @@ -2567,7 +2563,7 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { // Revert function test_TokenHandlingError_Reverts() public { - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); bytes memory unknownError = bytes("unknown error"); s_maybeRevertingPool.setShouldRevert(unknownError); @@ -2585,7 +2581,7 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { function test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() public { uint256 amount = 100; - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); srcTokenAmounts[0].amount = amount; bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); @@ -2620,7 +2616,7 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { } function test_releaseOrMintTokens_InvalidEVMAddress_Revert() public { - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); Internal.RampTokenAmount[] memory sourceTokenAmounts = _getDefaultSourceTokenData(srcTokenAmounts); @@ -2652,7 +2648,7 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { } function test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() public { - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); uint256 amount1 = 100; srcTokenAmounts[0].amount = amount1; @@ -2995,7 +2991,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { }); EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); vm.expectEmit(); emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); @@ -3022,7 +3018,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { merkleRoot: "stale report 1" }); EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); vm.expectEmit(); emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); @@ -3056,7 +3052,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { function test_OnlyTokenPriceUpdates_Success() public { EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots }); @@ -3074,7 +3070,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { function test_OnlyGasPriceUpdates_Success() public { EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots }); @@ -3091,7 +3087,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { function test_PriceSequenceNumberCleared_Success() public { EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots }); @@ -3142,7 +3138,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { uint224 tokenPrice2 = 5e18; EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice1), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice1), merkleRoots: roots }); @@ -3161,7 +3157,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { interval: EVM2EVMMultiOffRamp.Interval(1, maxSeq), merkleRoot: "stale report" }); - commitReport.priceUpdates = getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice2); + commitReport.priceUpdates = _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice2); commitReport.merkleRoots = roots; vm.expectEmit(); @@ -3263,7 +3259,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { }); EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.CursedByRMN.selector, roots[0].sourceChainSelector)); _commit(commitReport, s_latestSequenceNumber); @@ -3277,7 +3273,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { merkleRoot: bytes32(0) }); EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); vm.expectRevert(EVM2EVMMultiOffRamp.InvalidRoot.selector); _commit(commitReport, s_latestSequenceNumber); @@ -3292,7 +3288,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { merkleRoot: bytes32(0) }); EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); vm.expectRevert( abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, interval) @@ -3310,7 +3306,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { merkleRoot: bytes32(0) }); EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); vm.expectRevert( abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, interval) @@ -3321,7 +3317,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { function test_ZeroEpochAndRound_Revert() public { EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots }); @@ -3332,7 +3328,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { function test_OnlyPriceUpdateStaleReport_Revert() public { EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots }); @@ -3353,7 +3349,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { }); EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.SourceChainNotEnabled.selector, 0)); _commit(commitReport, s_latestSequenceNumber); @@ -3367,7 +3363,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { merkleRoot: "Only a single root" }); EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); _commit(commitReport, s_latestSequenceNumber); commitReport.merkleRoots[0].interval = EVM2EVMMultiOffRamp.Interval(3, 3); @@ -3389,7 +3385,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { }); return EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots }); } @@ -3427,7 +3423,7 @@ contract EVM2EVMMultiOffRamp_resetUnblessedRoots is EVM2EVMMultiOffRampSetup { }); EVM2EVMMultiOffRamp.CommitReport memory report = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); _commit(report, ++s_latestSequenceNumber); @@ -3480,7 +3476,7 @@ contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { merkleRoot: leaves[0] }); EVM2EVMMultiOffRamp.CommitReport memory report = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); _commit(report, ++s_latestSequenceNumber); bytes32[] memory proofs = new bytes32[](0); // We have not blessed this root, should return 0. @@ -3498,7 +3494,7 @@ contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { merkleRoot: leaves[0] }); EVM2EVMMultiOffRamp.CommitReport memory report = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); _commit(report, ++s_latestSequenceNumber); // Bless that root. IRMN.TaggedRoot[] memory taggedRoots = new IRMN.TaggedRoot[](1); @@ -3521,7 +3517,7 @@ contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { }); EVM2EVMMultiOffRamp.CommitReport memory report = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: getEmptyPriceUpdates(), merkleRoots: roots}); + EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); _commit(report, ++s_latestSequenceNumber); // Bless that root. diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol index 4813d024af..29864a7071 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol @@ -2,8 +2,6 @@ pragma solidity 0.8.24; import {IAny2EVMMessageReceiver} from "../../interfaces/IAny2EVMMessageReceiver.sol"; - -import {IAny2EVMOffRamp} from "../../interfaces/IAny2EVMOffRamp.sol"; import {ICommitStore} from "../../interfaces/ICommitStore.sol"; import {IRMN} from "../../interfaces/IRMN.sol"; @@ -16,22 +14,18 @@ import {Internal} from "../../libraries/Internal.sol"; import {MultiOCR3Base} from "../../ocr/MultiOCR3Base.sol"; import {EVM2EVMMultiOffRamp} from "../../offRamp/EVM2EVMMultiOffRamp.sol"; import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; -import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; -import {TokenSetup} from "../TokenSetup.t.sol"; import {EVM2EVMMultiOffRampHelper} from "../helpers/EVM2EVMMultiOffRampHelper.sol"; import {EVM2EVMOffRampHelper} from "../helpers/EVM2EVMOffRampHelper.sol"; import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; -import {MockCommitStore} from "../mocks/MockCommitStore.sol"; import {MultiOCR3BaseSetup} from "../ocr/MultiOCR3BaseSetup.t.sol"; -import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; -import {Vm} from "forge-std/Test.sol"; +import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; -import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {Vm} from "forge-std/Test.sol"; -contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3BaseSetup { +contract EVM2EVMMultiOffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { uint64 internal constant SOURCE_CHAIN_SELECTOR_1 = SOURCE_CHAIN_SELECTOR; uint64 internal constant SOURCE_CHAIN_SELECTOR_2 = 6433500567565415381; uint64 internal constant SOURCE_CHAIN_SELECTOR_3 = 4051577828743386545; @@ -63,8 +57,7 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba uint64 internal s_latestSequenceNumber; - function setUp() public virtual override(TokenSetup, PriceRegistrySetup, MultiOCR3BaseSetup) { - TokenSetup.setUp(); + function setUp() public virtual override(PriceRegistrySetup, MultiOCR3BaseSetup) { PriceRegistrySetup.setUp(); MultiOCR3BaseSetup.setUp(); @@ -149,7 +142,7 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba rmnProxy: address(s_mockRMN), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - getInboundRateLimiterConfig() + _getInboundRateLimiterConfig() ); offRamp.setOCR2Config( s_validSigners, @@ -289,7 +282,7 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba uint64 sequenceNumber, uint256[] memory amounts ) internal view returns (Internal.Any2EVMRampMessage memory) { - Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory tokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); for (uint256 i = 0; i < tokenAmounts.length; ++i) { tokenAmounts[i].amount = amounts[i]; } @@ -351,7 +344,7 @@ contract EVM2EVMMultiOffRampSetup is TokenSetup, PriceRegistrySetup, MultiOCR3Ba bytes memory onRamp ) internal view returns (Internal.Any2EVMRampMessage[] memory) { Internal.Any2EVMRampMessage[] memory messages = new Internal.Any2EVMRampMessage[](2); - Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory tokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); tokenAmounts[0].amount = 1e18; tokenAmounts[1].amount = 5e18; messages[0] = _generateAny2EVMMessage(sourceChainSelector, onRamp, 1, tokenAmounts, false); diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol index 167ac83330..6162419367 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol @@ -2,14 +2,12 @@ pragma solidity 0.8.24; import {ICommitStore} from "../../interfaces/ICommitStore.sol"; -import {IPoolV1} from "../../interfaces/IPool.sol"; import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; import {CallWithExactGas} from "../../../shared/call/CallWithExactGas.sol"; import {GenericReceiver} from "../../../shared/test/testhelpers/GenericReceiver.sol"; import {AggregateRateLimiter} from "../../AggregateRateLimiter.sol"; -import {RMN} from "../../RMN.sol"; import {Router} from "../../Router.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; @@ -25,8 +23,6 @@ import {ConformingReceiver} from "../helpers/receivers/ConformingReceiver.sol"; import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; import {MaybeRevertMessageReceiverNo165} from "../helpers/receivers/MaybeRevertMessageReceiverNo165.sol"; import {ReentrancyAbuser} from "../helpers/receivers/ReentrancyAbuser.sol"; -import {MockCommitStore} from "../mocks/MockCommitStore.sol"; -import {OCR2Base} from "../ocr/OCR2Base.t.sol"; import {OCR2BaseNoChecks} from "../ocr/OCR2BaseNoChecks.t.sol"; import {EVM2EVMOffRampSetup} from "./EVM2EVMOffRampSetup.t.sol"; import {stdError} from "forge-std/Test.sol"; @@ -47,7 +43,7 @@ contract EVM2EVMOffRamp_constructor is EVM2EVMOffRampSetup { EVM2EVMOffRamp.DynamicConfig memory dynamicConfig = generateDynamicOffRampConfig(address(s_destRouter), address(s_priceRegistry)); - s_offRamp = new EVM2EVMOffRampHelper(staticConfig, getInboundRateLimiterConfig()); + s_offRamp = new EVM2EVMOffRampHelper(staticConfig, _getInboundRateLimiterConfig()); s_offRamp.setOCR2Config( s_valid_signers, s_valid_transmitters, s_f, abi.encode(dynamicConfig), s_offchainConfigVersion, abi.encode("") @@ -108,7 +104,7 @@ contract EVM2EVMOffRamp_constructor is EVM2EVMOffRampSetup { rmnProxy: address(s_mockRMN), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - getInboundRateLimiterConfig() + _getInboundRateLimiterConfig() ); } } @@ -1796,7 +1792,7 @@ contract EVM2EVMOffRamp__releaseOrMintToken is EVM2EVMOffRampSetup { contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { function test_releaseOrMintTokens_Success() public { - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); IERC20 dstToken1 = IERC20(s_destFeeToken); uint256 startingBalance = dstToken1.balanceOf(OWNER); uint256 amount1 = 100; @@ -1835,7 +1831,7 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { } function test_releaseOrMintTokens_destDenominatedDecimals_Success() public { - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); uint256 amount = 100; uint256 destinationDenominationMultiplier = 1000; srcTokenAmounts[1].amount = amount; @@ -1859,10 +1855,10 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { function test_OverValueWithARLOff_Success() public { // Set a high price to trip the ARL uint224 tokenPrice = 3 ** 128; - Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(s_destFeeToken, tokenPrice); + Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(s_destFeeToken, tokenPrice); s_priceRegistry.updatePrices(priceUpdates); - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); uint256 amount1 = 100; srcTokenAmounts[0].amount = amount1; @@ -1876,7 +1872,7 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { vm.expectRevert( abi.encodeWithSelector( RateLimiter.AggregateValueMaxCapacityExceeded.selector, - getInboundRateLimiterConfig().capacity, + _getInboundRateLimiterConfig().capacity, (amount1 * tokenPrice) / 1e18 ) ); @@ -1900,7 +1896,7 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { // Revert function test_TokenHandlingError_Reverts() public { - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); bytes memory unknownError = bytes("unknown error"); s_maybeRevertingPool.setShouldRevert(unknownError); @@ -1919,7 +1915,7 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { function test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() public { uint256 amount = 100; - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); srcTokenAmounts[0].amount = amount; bytes memory originalSender = abi.encode(OWNER); @@ -1956,7 +1952,7 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { } function test_releaseOrMintTokens_InvalidEVMAddress_Revert() public { - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); bytes memory originalSender = abi.encode(OWNER); bytes[] memory offchainTokenData = new bytes[](srcTokenAmounts.length); @@ -1980,7 +1976,7 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { } function test_RateLimitErrors_Reverts() public { - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); bytes[] memory rateLimitErrors = new bytes[](5); rateLimitErrors[0] = abi.encodeWithSelector(RateLimiter.BucketOverfilled.selector); @@ -2036,9 +2032,9 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { function test_PriceNotFoundForToken_Reverts() public { // Set token price to 0 - s_priceRegistry.updatePrices(getSingleTokenPriceUpdateStruct(s_destFeeToken, 0)); + s_priceRegistry.updatePrices(_getSingleTokenPriceUpdateStruct(s_destFeeToken, 0)); - Client.EVMTokenAmount[] memory srcTokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); uint256 amount1 = 100; srcTokenAmounts[0].amount = amount1; diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol index ccb91a7e72..a0fa6a4a8e 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol @@ -3,13 +3,11 @@ pragma solidity 0.8.24; import {IAny2EVMMessageReceiver} from "../../interfaces/IAny2EVMMessageReceiver.sol"; import {ICommitStore} from "../../interfaces/ICommitStore.sol"; -import {IPoolV1} from "../../interfaces/IPool.sol"; import {Router} from "../../Router.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; -import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; import {TokenSetup} from "../TokenSetup.t.sol"; import {EVM2EVMOffRampHelper} from "../helpers/EVM2EVMOffRampHelper.sol"; @@ -17,9 +15,7 @@ import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMint import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; import {MockCommitStore} from "../mocks/MockCommitStore.sol"; import {OCR2BaseSetup} from "../ocr/OCR2Base.t.sol"; -import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; - -import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { MockCommitStore internal s_mockCommitStore; @@ -58,7 +54,7 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { rmnProxy: address(s_mockRMN), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - getInboundRateLimiterConfig() + _getInboundRateLimiterConfig() ); s_offRamp.setOCR2Config( s_valid_signers, @@ -133,7 +129,7 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { uint64 sequenceNumber, uint256[] memory amounts ) internal view returns (Internal.EVM2EVMMessage memory) { - Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory tokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); for (uint256 i = 0; i < tokenAmounts.length; ++i) { tokenAmounts[i].amount = amounts[i]; } @@ -192,7 +188,7 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { function _generateSingleBasicMessageWithTokens() internal view returns (Internal.EVM2EVMMessage[] memory) { Internal.EVM2EVMMessage[] memory messages = new Internal.EVM2EVMMessage[](1); - Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory tokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); tokenAmounts[0].amount = 1e18; messages[0] = _generateAny2EVMMessage(1, tokenAmounts, false); return messages; @@ -200,7 +196,7 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { function _generateMessagesWithTokens() internal view returns (Internal.EVM2EVMMessage[] memory) { Internal.EVM2EVMMessage[] memory messages = new Internal.EVM2EVMMessage[](2); - Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory tokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); tokenAmounts[0].amount = 1e18; tokenAmounts[1].amount = 5e18; messages[0] = _generateAny2EVMMessage(1, tokenAmounts, false); diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol index f148177094..cb85896b32 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol @@ -2,20 +2,21 @@ pragma solidity 0.8.24; import {IMessageInterceptor} from "../../interfaces/IMessageInterceptor.sol"; -import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; +import {IRouter} from "../../interfaces/IRouter.sol"; import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; -import {MultiAggregateRateLimiter} from "../../MultiAggregateRateLimiter.sol"; +import {PriceRegistry} from "../../PriceRegistry.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; import {Pool} from "../../libraries/Pool.sol"; -import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {USDPriceWith18Decimals} from "../../libraries/USDPriceWith18Decimals.sol"; import {EVM2EVMMultiOnRamp} from "../../onRamp/EVM2EVMMultiOnRamp.sol"; -import {EVM2EVMOnRamp} from "../../onRamp/EVM2EVMOnRamp.sol"; -import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; -import {EVM2EVMOnRampHelper} from "../helpers/EVM2EVMOnRampHelper.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; +import {EVM2EVMMultiOnRampHelper} from "../helpers/EVM2EVMMultiOnRampHelper.sol"; import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; -import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; -import "./EVM2EVMMultiOnRampSetup.t.sol"; +import {EVM2EVMMultiOnRampSetup} from "./EVM2EVMMultiOnRampSetup.t.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { function test_Constructor_Success() public { @@ -422,7 +423,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { vm.stopPrank(); vm.startPrank(OWNER); - Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(wrongToken, 1); + Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(wrongToken, 1); s_priceRegistry.updatePrices(priceUpdates); // Change back to the router @@ -474,8 +475,8 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { remotePoolAddress: abi.encode(s_destTokenPool), remoteTokenAddress: abi.encode(s_destToken), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); newPool.applyChainUpdates(chainUpdates); diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol index d237a23e8f..66daefedd3 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol @@ -1,27 +1,21 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IPoolV1} from "../../interfaces/IPool.sol"; import {IRouter} from "../../interfaces/IRouter.sol"; import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; import {NonceManager} from "../../NonceManager.sol"; -import {PriceRegistry} from "../../PriceRegistry.sol"; import {Router} from "../../Router.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {EVM2EVMMultiOnRamp} from "../../onRamp/EVM2EVMMultiOnRamp.sol"; -import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; -import {TokenPool} from "../../pools/TokenPool.sol"; -import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; -import {TokenSetup} from "../TokenSetup.t.sol"; import {EVM2EVMMultiOnRampHelper} from "../helpers/EVM2EVMMultiOnRampHelper.sol"; import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; -import {PriceRegistryFeeSetup} from "../priceRegistry/PriceRegistry.t.sol"; +import {PriceRegistryFeeSetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistryFeeSetup { +contract EVM2EVMMultiOnRampSetup is PriceRegistryFeeSetup { uint256 internal immutable i_tokenAmount0 = 9; uint256 internal immutable i_tokenAmount1 = 7; @@ -32,9 +26,8 @@ contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistryFeeSetup { address[] internal s_offRamps; NonceManager internal s_outboundNonceManager; - function setUp() public virtual override(TokenSetup, PriceRegistryFeeSetup) { - TokenSetup.setUp(); - PriceRegistryFeeSetup.setUp(); + function setUp() public virtual override { + super.setUp(); s_outboundMessageValidator = new MessageInterceptorHelper(); s_outboundNonceManager = new NonceManager(new address[](0)); @@ -59,7 +52,7 @@ contract EVM2EVMMultiOnRampSetup is TokenSetup, PriceRegistryFeeSetup { } function _generateTokenMessage() public view returns (Client.EVM2AnyMessage memory) { - Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory tokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); tokenAmounts[0].amount = i_tokenAmount0; tokenAmounts[1].amount = i_tokenAmount1; return Client.EVM2AnyMessage({ diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol index 8559122be7..54054716e6 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol @@ -9,7 +9,8 @@ import {Pool} from "../../libraries/Pool.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {USDPriceWith18Decimals} from "../../libraries/USDPriceWith18Decimals.sol"; import {EVM2EVMOnRamp} from "../../onRamp/EVM2EVMOnRamp.sol"; -import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; +import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; +import {TokenPool} from "../../pools/TokenPool.sol"; import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; import "./EVM2EVMOnRampSetup.t.sol"; @@ -34,7 +35,7 @@ contract EVM2EVMOnRamp_constructor is EVM2EVMOnRampSetup { s_onRamp = new EVM2EVMOnRampHelper( staticConfig, dynamicConfig, - getOutboundRateLimiterConfig(), + _getOutboundRateLimiterConfig(), s_feeTokenConfigArgs, s_tokenTransferFeeConfigArgs, getNopsAndWeights() @@ -485,14 +486,14 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { vm.startPrank(OWNER); // Set a high price to trip the ARL uint224 tokenPrice = 3 ** 128; - Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(s_sourceTokens[0], tokenPrice); + Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(s_sourceTokens[0], tokenPrice); s_priceRegistry.updatePrices(priceUpdates); vm.startPrank(address(s_sourceRouter)); vm.expectRevert( abi.encodeWithSelector( RateLimiter.AggregateValueMaxCapacityExceeded.selector, - getOutboundRateLimiterConfig().capacity, + _getOutboundRateLimiterConfig().capacity, (message.tokenAmounts[0].amount * tokenPrice) / 1e18 ) ); @@ -660,7 +661,7 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { vm.stopPrank(); vm.startPrank(OWNER); - Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(wrongToken, 1); + Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(wrongToken, 1); s_priceRegistry.updatePrices(priceUpdates); // Change back to the router @@ -681,7 +682,7 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { vm.expectRevert( abi.encodeWithSelector( RateLimiter.AggregateValueMaxCapacityExceeded.selector, - getOutboundRateLimiterConfig().capacity, + _getOutboundRateLimiterConfig().capacity, (message.tokenAmounts[0].amount * s_sourceTokenPrices[0]) / 1e18 ) ); @@ -693,7 +694,7 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { // Set token price to 0 vm.stopPrank(); vm.startPrank(OWNER); - s_priceRegistry.updatePrices(getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, 0)); + s_priceRegistry.updatePrices(_getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, 0)); vm.startPrank(address(s_sourceRouter)); @@ -784,8 +785,8 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { remotePoolAddress: abi.encode(s_destTokenPool), remoteTokenAddress: abi.encode(s_destToken), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); newPool.applyChainUpdates(chainUpdates); @@ -905,7 +906,7 @@ contract EVM2EVMOnRamp_forwardFromRouter_upgrade is EVM2EVMOnRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry) }), generateDynamicOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)), - getOutboundRateLimiterConfig(), + _getOutboundRateLimiterConfig(), s_feeTokenConfigArgs, s_tokenTransferFeeConfigArgs, getNopsAndWeights() @@ -1003,8 +1004,8 @@ contract EVM2EVMOnRamp_getFeeSetup is EVM2EVMOnRampSetup { remotePoolAddress: abi.encode(address(111111)), remoteTokenAddress: abi.encode(s_destToken), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); wrappedNativePool.applyChainUpdates(wrappedNativeChainUpdate); s_tokenAdminRegistry.setPool(s_sourceRouter.getWrappedNative(), address(wrappedNativePool)); @@ -1018,8 +1019,8 @@ contract EVM2EVMOnRamp_getFeeSetup is EVM2EVMOnRampSetup { remotePoolAddress: abi.encode(makeAddr("random")), remoteTokenAddress: abi.encode(s_destToken), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); customPool.applyChainUpdates(customChainUpdate); s_tokenAdminRegistry.setPool(CUSTOM_TOKEN, address(customPool)); diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol index 46a695701f..f827bf983c 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol @@ -1,19 +1,14 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IPoolV1} from "../../interfaces/IPool.sol"; - -import {PriceRegistry} from "../../PriceRegistry.sol"; import {Router} from "../../Router.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {Pool} from "../../libraries/Pool.sol"; import {EVM2EVMOnRamp} from "../../onRamp/EVM2EVMOnRamp.sol"; -import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; -import {TokenPool} from "../../pools/TokenPool.sol"; import {TokenSetup} from "../TokenSetup.t.sol"; import {EVM2EVMOnRampHelper} from "../helpers/EVM2EVMOnRampHelper.sol"; -import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; +import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; @@ -36,7 +31,7 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { TokenSetup.setUp(); PriceRegistrySetup.setUp(); - s_priceRegistry.updatePrices(getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); + s_priceRegistry.updatePrices(_getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); address WETH = s_sourceRouter.getWrappedNative(); @@ -94,7 +89,7 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { tokenAdminRegistry: address(s_tokenAdminRegistry) }), generateDynamicOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)), - getOutboundRateLimiterConfig(), + _getOutboundRateLimiterConfig(), s_feeTokenConfigArgs, s_tokenTransferFeeConfigArgs, getNopsAndWeights() @@ -151,7 +146,7 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { } function _generateTokenMessage() public view returns (Client.EVM2AnyMessage memory) { - Client.EVMTokenAmount[] memory tokenAmounts = getCastedSourceEVMTokenAmountsWithZeroAmounts(); + Client.EVMTokenAmount[] memory tokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); tokenAmounts[0].amount = i_tokenAmount0; tokenAmounts[1].amount = i_tokenAmount1; return Client.EVM2AnyMessage({ diff --git a/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool.t.sol index 307cbf21f4..b5967e74d1 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool.t.sol @@ -5,7 +5,6 @@ import {Pool} from "../../libraries/Pool.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {BurnFromMintTokenPool} from "../../pools/BurnFromMintTokenPool.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; -import {BaseTest} from "../BaseTest.t.sol"; import {BurnMintSetup} from "./BurnMintSetup.t.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; @@ -95,8 +94,8 @@ contract BurnFromMintTokenPool_lockOrBurn is BurnFromMintTokenPoolSetup { amount: 1, localToken: address(s_burnMintERC677), remoteChainSelector: wrongChainSelector, - sourcePoolAddress: generateSourceTokenData().sourcePoolAddress, - sourcePoolData: generateSourceTokenData().extraData, + sourcePoolAddress: _generateSourceTokenData().sourcePoolAddress, + sourcePoolData: _generateSourceTokenData().extraData, offchainTokenData: "" }) ); diff --git a/contracts/src/v0.8/ccip/test/pools/BurnMintSetup.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnMintSetup.t.sol index a39fd1bb9f..220f6ca112 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnMintSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnMintSetup.t.sol @@ -28,8 +28,8 @@ contract BurnMintSetup is RouterSetup { remotePoolAddress: abi.encode(s_remoteBurnMintPool), remoteTokenAddress: abi.encode(s_remoteToken), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); BurnMintTokenPool(pool).applyChainUpdates(chains); diff --git a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol index 5a7644d033..8a6d047380 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool.t.sol @@ -1,15 +1,10 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IPoolV1} from "../../interfaces/IPool.sol"; - -import {Internal} from "../../libraries/Internal.sol"; import {Pool} from "../../libraries/Pool.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; -import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; import {BurnMintTokenPool} from "../../pools/BurnMintTokenPool.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; -import {BaseTest} from "../BaseTest.t.sol"; import {BurnMintSetup} from "./BurnMintSetup.t.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; @@ -144,8 +139,8 @@ contract BurnMintTokenPool_releaseOrMint is BurnMintTokenPoolSetup { amount: 1e5, localToken: address(s_burnMintERC677), remoteChainSelector: DEST_CHAIN_SELECTOR, - sourcePoolAddress: generateSourceTokenData().sourcePoolAddress, - sourcePoolData: generateSourceTokenData().extraData, + sourcePoolAddress: _generateSourceTokenData().sourcePoolAddress, + sourcePoolData: _generateSourceTokenData().extraData, offchainTokenData: "" }) ); @@ -164,8 +159,8 @@ contract BurnMintTokenPool_releaseOrMint is BurnMintTokenPoolSetup { amount: 1, localToken: address(s_burnMintERC677), remoteChainSelector: wrongChainSelector, - sourcePoolAddress: generateSourceTokenData().sourcePoolAddress, - sourcePoolData: generateSourceTokenData().extraData, + sourcePoolAddress: _generateSourceTokenData().sourcePoolAddress, + sourcePoolData: _generateSourceTokenData().extraData, offchainTokenData: "" }) ); diff --git a/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool.t.sol index 568aac6ba1..92e871708d 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool.t.sol @@ -5,7 +5,6 @@ import {Pool} from "../../libraries/Pool.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {BurnWithFromMintTokenPool} from "../../pools/BurnWithFromMintTokenPool.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; -import {BaseTest} from "../BaseTest.t.sol"; import {BurnMintSetup} from "./BurnMintSetup.t.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; @@ -96,8 +95,8 @@ contract BurnWithFromMintTokenPool_lockOrBurn is BurnWithFromMintTokenPoolSetup amount: 1, localToken: address(s_burnMintERC677), remoteChainSelector: wrongChainSelector, - sourcePoolAddress: generateSourceTokenData().sourcePoolAddress, - sourcePoolData: generateSourceTokenData().extraData, + sourcePoolAddress: _generateSourceTokenData().sourcePoolAddress, + sourcePoolData: _generateSourceTokenData().extraData, offchainTokenData: "" }) ); diff --git a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol index fb5d5e0fd1..ed8a1cf31f 100644 --- a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool.t.sol @@ -5,13 +5,10 @@ import {IPoolV1} from "../../interfaces/IPool.sol"; import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; import {Router} from "../../Router.sol"; -import {Internal} from "../../libraries/Internal.sol"; import {Pool} from "../../libraries/Pool.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; -import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; -import {BaseTest} from "../BaseTest.t.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; import {IERC165} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol"; @@ -47,8 +44,8 @@ contract LockReleaseTokenPoolSetup is RouterSetup { remotePoolAddress: abi.encode(s_destPoolAddress), remoteTokenAddress: abi.encode(address(2)), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_lockReleaseTokenPool.applyChainUpdates(chainUpdate); @@ -80,7 +77,7 @@ contract LockReleaseTokenPool_setRebalancer is LockReleaseTokenPoolSetup { contract LockReleaseTokenPool_lockOrBurn is LockReleaseTokenPoolSetup { function test_Fuzz_LockOrBurnNoAllowList_Success(uint256 amount) public { - amount = bound(amount, 1, getOutboundRateLimiterConfig().capacity); + amount = bound(amount, 1, _getOutboundRateLimiterConfig().capacity); vm.startPrank(s_allowedOnRamp); vm.expectEmit(); @@ -179,8 +176,8 @@ contract LockReleaseTokenPool_releaseOrMint is LockReleaseTokenPoolSetup { remotePoolAddress: abi.encode(s_sourcePoolAddress), remoteTokenAddress: abi.encode(address(2)), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_lockReleaseTokenPool.applyChainUpdates(chainUpdate); @@ -222,7 +219,7 @@ contract LockReleaseTokenPool_releaseOrMint is LockReleaseTokenPoolSetup { deal(address(s_token), address(s_lockReleaseTokenPool), amount); vm.startPrank(s_allowedOffRamp); - uint256 capacity = getInboundRateLimiterConfig().capacity; + uint256 capacity = _getInboundRateLimiterConfig().capacity; // Determine if we hit the rate limit or the txs should succeed. if (amount > capacity) { vm.expectRevert( @@ -298,8 +295,8 @@ contract LockReleaseTokenPool_releaseOrMint is LockReleaseTokenPoolSetup { amount: 1e5, localToken: address(s_token), remoteChainSelector: SOURCE_CHAIN_SELECTOR, - sourcePoolAddress: generateSourceTokenData().sourcePoolAddress, - sourcePoolData: generateSourceTokenData().extraData, + sourcePoolAddress: _generateSourceTokenData().sourcePoolAddress, + sourcePoolData: _generateSourceTokenData().extraData, offchainTokenData: "" }) ); diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool.t.sol index 2c9eaf6df0..2c1bc0ed57 100644 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool.t.sol @@ -5,7 +5,6 @@ import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; import {Router} from "../../Router.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; -import {BaseTest} from "../BaseTest.t.sol"; import {TokenPoolHelper} from "../helpers/TokenPoolHelper.sol"; import {RouterSetup} from "../router/RouterSetup.t.sol"; @@ -55,8 +54,8 @@ contract TokenPool_getRemotePool is TokenPoolSetup { remotePoolAddress: abi.encode(remotePool), remoteTokenAddress: abi.encode(remoteToken), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_tokenPool.applyChainUpdates(chainUpdates); @@ -78,8 +77,8 @@ contract TokenPool_setRemotePool is TokenPoolSetup { remotePoolAddress: abi.encode(initialPool), remoteTokenAddress: abi.encode(remoteToken), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_tokenPool.applyChainUpdates(chainUpdates); @@ -379,8 +378,8 @@ contract TokenPool_setChainRateLimiterConfig is TokenPoolSetup { remotePoolAddress: abi.encode(address(2)), remoteTokenAddress: abi.encode(address(3)), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_tokenPool.applyChainUpdates(chainUpdates); } @@ -434,7 +433,7 @@ contract TokenPool_setChainRateLimiterConfig is TokenPoolSetup { vm.expectRevert(abi.encodeWithSelector(TokenPool.Unauthorized.selector, STRANGER)); s_tokenPool.setChainRateLimiterConfig( - s_remoteChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() + s_remoteChainSelector, _getOutboundRateLimiterConfig(), _getInboundRateLimiterConfig() ); } @@ -443,7 +442,7 @@ contract TokenPool_setChainRateLimiterConfig is TokenPoolSetup { vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, wrongChainSelector)); s_tokenPool.setChainRateLimiterConfig( - wrongChainSelector, getOutboundRateLimiterConfig(), getInboundRateLimiterConfig() + wrongChainSelector, _getOutboundRateLimiterConfig(), _getInboundRateLimiterConfig() ); } } @@ -476,8 +475,8 @@ contract TokenPool_onlyOnRamp is TokenPoolSetup { remotePoolAddress: abi.encode(address(1)), remoteTokenAddress: abi.encode(address(2)), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_tokenPool.applyChainUpdates(chainUpdate); @@ -507,8 +506,8 @@ contract TokenPool_onlyOnRamp is TokenPoolSetup { remotePoolAddress: abi.encode(address(1)), remoteTokenAddress: abi.encode(address(2)), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_tokenPool.applyChainUpdates(chainUpdate); @@ -548,8 +547,8 @@ contract TokenPool_onlyOnRamp is TokenPoolSetup { remotePoolAddress: abi.encode(address(1)), remoteTokenAddress: abi.encode(address(2)), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_tokenPool.applyChainUpdates(chainUpdate); @@ -572,8 +571,8 @@ contract TokenPool_onlyOffRamp is TokenPoolSetup { remotePoolAddress: abi.encode(address(1)), remoteTokenAddress: abi.encode(address(2)), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_tokenPool.applyChainUpdates(chainUpdate); @@ -603,8 +602,8 @@ contract TokenPool_onlyOffRamp is TokenPoolSetup { remotePoolAddress: abi.encode(address(1)), remoteTokenAddress: abi.encode(address(2)), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_tokenPool.applyChainUpdates(chainUpdate); @@ -644,8 +643,8 @@ contract TokenPool_onlyOffRamp is TokenPoolSetup { remotePoolAddress: abi.encode(address(1)), remoteTokenAddress: abi.encode(address(2)), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_tokenPool.applyChainUpdates(chainUpdate); diff --git a/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol index 7259e1d17c..e60d5542f4 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol @@ -57,7 +57,7 @@ contract USDCTokenPoolSetup is BaseTest { BurnMintERC677 usdcToken = new BurnMintERC677("LINK", "LNK", 18, 0); s_token = usdcToken; deal(address(s_token), OWNER, type(uint256).max); - setUpRamps(); + _setUpRamps(); s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); @@ -78,16 +78,16 @@ contract USDCTokenPoolSetup is BaseTest { remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), remoteTokenAddress: abi.encode(address(s_token)), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); chainUpdates[1] = TokenPool.ChainUpdate({ remoteChainSelector: DEST_CHAIN_SELECTOR, remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_usdcTokenPool.applyChainUpdates(chainUpdates); @@ -105,7 +105,7 @@ contract USDCTokenPoolSetup is BaseTest { s_usdcTokenPoolWithAllowList.setDomains(domains); } - function setUpRamps() internal { + function _setUpRamps() internal { s_router = new Router(address(s_token), address(s_mockRMN)); Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); @@ -176,7 +176,7 @@ contract USDCTokenPool_lockOrBurn is USDCTokenPoolSetup { function test_Fuzz_LockOrBurn_Success(bytes32 destinationReceiver, uint256 amount) public { vm.assume(destinationReceiver != bytes32(0)); - amount = bound(amount, 1, getOutboundRateLimiterConfig().capacity); + amount = bound(amount, 1, _getOutboundRateLimiterConfig().capacity); s_token.transfer(address(s_usdcTokenPool), amount); vm.startPrank(s_routerAllowedOnRamp); @@ -217,7 +217,7 @@ contract USDCTokenPool_lockOrBurn is USDCTokenPoolSetup { function test_Fuzz_LockOrBurnWithAllowList_Success(bytes32 destinationReceiver, uint256 amount) public { vm.assume(destinationReceiver != bytes32(0)); - amount = bound(amount, 1, getOutboundRateLimiterConfig().capacity); + amount = bound(amount, 1, _getOutboundRateLimiterConfig().capacity); s_token.transfer(address(s_usdcTokenPoolWithAllowList), amount); vm.startPrank(s_routerAllowedOnRamp); @@ -267,8 +267,8 @@ contract USDCTokenPool_lockOrBurn is USDCTokenPoolSetup { remotePoolAddress: abi.encode(address(1)), remoteTokenAddress: abi.encode(address(2)), allowed: true, - outboundRateLimiterConfig: getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: getInboundRateLimiterConfig() + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); s_usdcTokenPool.applyChainUpdates(chainUpdates); @@ -336,7 +336,7 @@ contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { function test_Fuzz_ReleaseOrMint_Success(address recipient, uint256 amount) public { vm.assume(recipient != address(0) && recipient != address(s_token)); - amount = bound(amount, 0, getInboundRateLimiterConfig().capacity); + amount = bound(amount, 0, _getInboundRateLimiterConfig().capacity); USDCMessage memory usdcMessage = USDCMessage({ version: 0, @@ -493,7 +493,7 @@ contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { } function test_TokenMaxCapacityExceeded_Revert() public { - uint256 capacity = getInboundRateLimiterConfig().capacity; + uint256 capacity = _getInboundRateLimiterConfig().capacity; uint256 amount = 10 * capacity; address recipient = address(1); vm.startPrank(s_routerAllowedOffRamp); diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol index b26eb56474..f59d27a2cb 100644 --- a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol +++ b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol @@ -1,435 +1,17 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; -import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; - import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; -import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol"; import {PriceRegistry} from "../../PriceRegistry.sol"; - import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {Pool} from "../../libraries/Pool.sol"; import {USDPriceWith18Decimals} from "../../libraries/USDPriceWith18Decimals.sol"; -import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; -import {TokenPool} from "../../pools/TokenPool.sol"; -import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; - -import {TokenSetup} from "../TokenSetup.t.sol"; -import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; import {PriceRegistryHelper} from "../helpers/PriceRegistryHelper.sol"; - -import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {PriceRegistryFeeSetup, PriceRegistrySetup} from "./PriceRegistrySetup.t.sol"; import {Vm} from "forge-std/Vm.sol"; -import {console} from "forge-std/console.sol"; - -contract PriceRegistrySetup is TokenSetup { - uint112 internal constant USD_PER_GAS = 1e6; // 0.001 gwei - uint112 internal constant USD_PER_DATA_AVAILABILITY_GAS = 1e9; // 1 gwei - - address internal constant CUSTOM_TOKEN = address(12345); - uint224 internal constant CUSTOM_TOKEN_PRICE = 1e17; // $0.1 CUSTOM - - // Encode L1 gas price and L2 gas price into a packed price. - // L1 gas price is left-shifted to the higher-order bits. - uint224 internal constant PACKED_USD_PER_GAS = - (uint224(USD_PER_DATA_AVAILABILITY_GAS) << Internal.GAS_PRICE_BITS) + USD_PER_GAS; - - PriceRegistryHelper internal s_priceRegistry; - // Cheat to store the price updates in storage since struct arrays aren't supported. - bytes internal s_encodedInitialPriceUpdates; - address internal s_weth; - - address[] internal s_sourceFeeTokens; - uint224[] internal s_sourceTokenPrices; - address[] internal s_destFeeTokens; - uint224[] internal s_destTokenPrices; - - PriceRegistry.PremiumMultiplierWeiPerEthArgs[] internal s_priceRegistryPremiumMultiplierWeiPerEthArgs; - PriceRegistry.TokenTransferFeeConfigArgs[] internal s_priceRegistryTokenTransferFeeConfigArgs; - - mapping(address token => address dataFeedAddress) internal s_dataFeedByToken; - - function setUp() public virtual override { - TokenSetup.setUp(); - - _deployTokenPriceDataFeed(s_sourceFeeToken, 8, 1e8); - - s_weth = s_sourceRouter.getWrappedNative(); - _deployTokenPriceDataFeed(s_weth, 8, 1e11); - - address[] memory sourceFeeTokens = new address[](3); - sourceFeeTokens[0] = s_sourceTokens[0]; - sourceFeeTokens[1] = s_sourceTokens[1]; - sourceFeeTokens[2] = s_sourceRouter.getWrappedNative(); - s_sourceFeeTokens = sourceFeeTokens; - - uint224[] memory sourceTokenPrices = new uint224[](3); - sourceTokenPrices[0] = 5e18; - sourceTokenPrices[1] = 2000e18; - sourceTokenPrices[2] = 2000e18; - s_sourceTokenPrices = sourceTokenPrices; - - address[] memory destFeeTokens = new address[](3); - destFeeTokens[0] = s_destTokens[0]; - destFeeTokens[1] = s_destTokens[1]; - destFeeTokens[2] = s_destRouter.getWrappedNative(); - s_destFeeTokens = destFeeTokens; - - uint224[] memory destTokenPrices = new uint224[](3); - destTokenPrices[0] = 5e18; - destTokenPrices[1] = 2000e18; - destTokenPrices[2] = 2000e18; - s_destTokenPrices = destTokenPrices; - - uint256 sourceTokenCount = sourceFeeTokens.length; - uint256 destTokenCount = destFeeTokens.length; - address[] memory pricedTokens = new address[](sourceTokenCount + destTokenCount); - uint224[] memory tokenPrices = new uint224[](sourceTokenCount + destTokenCount); - for (uint256 i = 0; i < sourceTokenCount; ++i) { - pricedTokens[i] = sourceFeeTokens[i]; - tokenPrices[i] = sourceTokenPrices[i]; - } - for (uint256 i = 0; i < destTokenCount; ++i) { - pricedTokens[i + sourceTokenCount] = destFeeTokens[i]; - tokenPrices[i + sourceTokenCount] = destTokenPrices[i]; - } - - Internal.PriceUpdates memory priceUpdates = getPriceUpdatesStruct(pricedTokens, tokenPrices); - priceUpdates.gasPriceUpdates = - getSingleGasPriceUpdateStruct(DEST_CHAIN_SELECTOR, PACKED_USD_PER_GAS).gasPriceUpdates; - - s_encodedInitialPriceUpdates = abi.encode(priceUpdates); - - address[] memory priceUpdaters = new address[](1); - priceUpdaters[0] = OWNER; - address[] memory feeTokens = new address[](2); - feeTokens[0] = s_sourceTokens[0]; - feeTokens[1] = s_weth; - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](0); - - s_priceRegistryPremiumMultiplierWeiPerEthArgs.push( - PriceRegistry.PremiumMultiplierWeiPerEthArgs({ - token: s_sourceFeeToken, - premiumMultiplierWeiPerEth: 5e17 // 0.5x - }) - ); - s_priceRegistryPremiumMultiplierWeiPerEthArgs.push( - PriceRegistry.PremiumMultiplierWeiPerEthArgs({ - token: s_sourceRouter.getWrappedNative(), - premiumMultiplierWeiPerEth: 2e18 // 2x - }) - ); - - s_priceRegistryTokenTransferFeeConfigArgs.push(); - s_priceRegistryTokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; - s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( - PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ - token: s_sourceFeeToken, - tokenTransferFeeConfig: PriceRegistry.TokenTransferFeeConfig({ - minFeeUSDCents: 1_00, // 1 USD - maxFeeUSDCents: 1000_00, // 1,000 USD - deciBps: 2_5, // 2.5 bps, or 0.025% - destGasOverhead: 40_000, - destBytesOverhead: 32, - isEnabled: true - }) - }) - ); - s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( - PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ - token: CUSTOM_TOKEN, - tokenTransferFeeConfig: PriceRegistry.TokenTransferFeeConfig({ - minFeeUSDCents: 2_00, // 1 USD - maxFeeUSDCents: 2000_00, // 1,000 USD - deciBps: 10_0, // 10 bps, or 0.1% - destGasOverhead: 1, - destBytesOverhead: 200, - isEnabled: true - }) - }) - ); - - s_priceRegistry = new PriceRegistryHelper( - PriceRegistry.StaticConfig({ - linkToken: s_sourceTokens[0], - maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS, - stalenessThreshold: uint32(TWELVE_HOURS) - }), - priceUpdaters, - feeTokens, - tokenPriceFeedUpdates, - s_priceRegistryTokenTransferFeeConfigArgs, - s_priceRegistryPremiumMultiplierWeiPerEthArgs, - _generatePriceRegistryDestChainConfigArgs() - ); - s_priceRegistry.updatePrices(priceUpdates); - } - - function _deployTokenPriceDataFeed(address token, uint8 decimals, int256 initialAnswer) internal returns (address) { - MockV3Aggregator dataFeed = new MockV3Aggregator(decimals, initialAnswer); - s_dataFeedByToken[token] = address(dataFeed); - return address(dataFeed); - } - - function getPriceUpdatesStruct( - address[] memory tokens, - uint224[] memory prices - ) internal pure returns (Internal.PriceUpdates memory) { - uint256 length = tokens.length; - - Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](length); - for (uint256 i = 0; i < length; ++i) { - tokenPriceUpdates[i] = Internal.TokenPriceUpdate({sourceToken: tokens[i], usdPerToken: prices[i]}); - } - Internal.PriceUpdates memory priceUpdates = - Internal.PriceUpdates({tokenPriceUpdates: tokenPriceUpdates, gasPriceUpdates: new Internal.GasPriceUpdate[](0)}); - - return priceUpdates; - } - - function getEmptyPriceUpdates() internal pure returns (Internal.PriceUpdates memory priceUpdates) { - return Internal.PriceUpdates({ - tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), - gasPriceUpdates: new Internal.GasPriceUpdate[](0) - }); - } - - function getSingleTokenPriceFeedUpdateStruct( - address sourceToken, - address dataFeedAddress, - uint8 tokenDecimals - ) internal pure returns (PriceRegistry.TokenPriceFeedUpdate memory) { - return PriceRegistry.TokenPriceFeedUpdate({ - sourceToken: sourceToken, - feedConfig: IPriceRegistry.TokenPriceFeedConfig({dataFeedAddress: dataFeedAddress, tokenDecimals: tokenDecimals}) - }); - } - - function _initialiseSingleTokenPriceFeed() internal returns (address) { - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); - tokenPriceFeedUpdates[0] = - getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); - return s_sourceTokens[0]; - } - - function _generateTokenTransferFeeConfigArgs( - uint256 destChainSelectorLength, - uint256 tokenLength - ) internal pure returns (PriceRegistry.TokenTransferFeeConfigArgs[] memory) { - PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = - new PriceRegistry.TokenTransferFeeConfigArgs[](destChainSelectorLength); - for (uint256 i = 0; i < destChainSelectorLength; ++i) { - tokenTransferFeeConfigArgs[i].tokenTransferFeeConfigs = - new PriceRegistry.TokenTransferFeeConfigSingleTokenArgs[](tokenLength); - } - return tokenTransferFeeConfigArgs; - } - - function _generatePriceRegistryDestChainConfigArgs() - internal - pure - returns (PriceRegistry.DestChainConfigArgs[] memory) - { - PriceRegistry.DestChainConfigArgs[] memory destChainConfigs = new PriceRegistry.DestChainConfigArgs[](1); - destChainConfigs[0] = PriceRegistry.DestChainConfigArgs({ - destChainSelector: DEST_CHAIN_SELECTOR, - destChainConfig: PriceRegistry.DestChainConfig({ - isEnabled: true, - maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, - destGasOverhead: DEST_GAS_OVERHEAD, - destGasPerPayloadByte: DEST_GAS_PER_PAYLOAD_BYTE, - destDataAvailabilityOverheadGas: DEST_DATA_AVAILABILITY_OVERHEAD_GAS, - destGasPerDataAvailabilityByte: DEST_GAS_PER_DATA_AVAILABILITY_BYTE, - destDataAvailabilityMultiplierBps: DEST_GAS_DATA_AVAILABILITY_MULTIPLIER_BPS, - maxDataBytes: MAX_DATA_SIZE, - maxPerMsgGasLimit: MAX_GAS_LIMIT, - defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, - defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, - defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, - defaultTxGasLimit: GAS_LIMIT, - gasMultiplierWeiPerEth: 5e17, - networkFeeUSDCents: 1_00, - enforceOutOfOrder: false, - chainFamilySelector: Internal.CHAIN_FAMILY_SELECTOR_EVM - }) - }); - return destChainConfigs; - } - - function _assertTokenPriceFeedConfigEquality( - IPriceRegistry.TokenPriceFeedConfig memory config1, - IPriceRegistry.TokenPriceFeedConfig memory config2 - ) internal pure virtual { - assertEq(config1.dataFeedAddress, config2.dataFeedAddress); - assertEq(config1.tokenDecimals, config2.tokenDecimals); - } - - function _assertTokenPriceFeedConfigUnconfigured(IPriceRegistry.TokenPriceFeedConfig memory config) - internal - pure - virtual - { - _assertTokenPriceFeedConfigEquality( - config, IPriceRegistry.TokenPriceFeedConfig({dataFeedAddress: address(0), tokenDecimals: 0}) - ); - } - - function _assertTokenTransferFeeConfigEqual( - PriceRegistry.TokenTransferFeeConfig memory a, - PriceRegistry.TokenTransferFeeConfig memory b - ) internal pure { - assertEq(a.minFeeUSDCents, b.minFeeUSDCents); - assertEq(a.maxFeeUSDCents, b.maxFeeUSDCents); - assertEq(a.deciBps, b.deciBps); - assertEq(a.destGasOverhead, b.destGasOverhead); - assertEq(a.destBytesOverhead, b.destBytesOverhead); - assertEq(a.isEnabled, b.isEnabled); - } - - function _assertPriceRegistryStaticConfigsEqual( - PriceRegistry.StaticConfig memory a, - PriceRegistry.StaticConfig memory b - ) internal pure { - assertEq(a.linkToken, b.linkToken); - assertEq(a.maxFeeJuelsPerMsg, b.maxFeeJuelsPerMsg); - } - - function _assertPriceRegistryDestChainConfigsEqual( - PriceRegistry.DestChainConfig memory a, - PriceRegistry.DestChainConfig memory b - ) internal pure { - assertEq(a.isEnabled, b.isEnabled); - assertEq(a.maxNumberOfTokensPerMsg, b.maxNumberOfTokensPerMsg); - assertEq(a.maxDataBytes, b.maxDataBytes); - assertEq(a.maxPerMsgGasLimit, b.maxPerMsgGasLimit); - assertEq(a.destGasOverhead, b.destGasOverhead); - assertEq(a.destGasPerPayloadByte, b.destGasPerPayloadByte); - assertEq(a.destDataAvailabilityOverheadGas, b.destDataAvailabilityOverheadGas); - assertEq(a.destGasPerDataAvailabilityByte, b.destGasPerDataAvailabilityByte); - assertEq(a.destDataAvailabilityMultiplierBps, b.destDataAvailabilityMultiplierBps); - assertEq(a.defaultTokenFeeUSDCents, b.defaultTokenFeeUSDCents); - assertEq(a.defaultTokenDestGasOverhead, b.defaultTokenDestGasOverhead); - assertEq(a.defaultTokenDestBytesOverhead, b.defaultTokenDestBytesOverhead); - assertEq(a.defaultTxGasLimit, b.defaultTxGasLimit); - } -} - -contract PriceRegistryFeeSetup is PriceRegistrySetup { - uint224 internal s_feeTokenPrice; - uint224 internal s_wrappedTokenPrice; - uint224 internal s_customTokenPrice; - - address internal s_selfServeTokenDefaultPricing = makeAddr("self-serve-token-default-pricing"); - - address internal s_destTokenPool = makeAddr("destTokenPool"); - address internal s_destToken = makeAddr("destToken"); - - function setUp() public virtual override { - super.setUp(); - - s_feeTokenPrice = s_sourceTokenPrices[0]; - s_wrappedTokenPrice = s_sourceTokenPrices[2]; - s_customTokenPrice = CUSTOM_TOKEN_PRICE; - - s_priceRegistry.updatePrices(getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); - } - - function _generateEmptyMessage() public view returns (Client.EVM2AnyMessage memory) { - return Client.EVM2AnyMessage({ - receiver: abi.encode(OWNER), - data: "", - tokenAmounts: new Client.EVMTokenAmount[](0), - feeToken: s_sourceFeeToken, - extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) - }); - } - - function _generateSingleTokenMessage( - address token, - uint256 amount - ) public view returns (Client.EVM2AnyMessage memory) { - Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); - tokenAmounts[0] = Client.EVMTokenAmount({token: token, amount: amount}); - - return Client.EVM2AnyMessage({ - receiver: abi.encode(OWNER), - data: "", - tokenAmounts: tokenAmounts, - feeToken: s_sourceFeeToken, - extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) - }); - } - - function _messageToEvent( - Client.EVM2AnyMessage memory message, - uint64 sourceChainSelector, - uint64 destChainSelector, - uint64 seqNum, - uint64 nonce, - uint256 feeTokenAmount, - address originalSender, - bytes32 metadataHash, - TokenAdminRegistry tokenAdminRegistry - ) internal view returns (Internal.EVM2AnyRampMessage memory) { - Client.EVMExtraArgsV2 memory extraArgs = - s_priceRegistry.parseEVMExtraArgsFromBytes(message.extraArgs, destChainSelector); - - Internal.EVM2AnyRampMessage memory messageEvent = Internal.EVM2AnyRampMessage({ - header: Internal.RampMessageHeader({ - messageId: "", - sourceChainSelector: sourceChainSelector, - destChainSelector: destChainSelector, - sequenceNumber: seqNum, - nonce: extraArgs.allowOutOfOrderExecution ? 0 : nonce - }), - sender: originalSender, - data: message.data, - receiver: message.receiver, - extraArgs: Client._argsToBytes(extraArgs), - feeToken: message.feeToken, - feeTokenAmount: feeTokenAmount, - tokenAmounts: new Internal.RampTokenAmount[](message.tokenAmounts.length) - }); - - for (uint256 i = 0; i < message.tokenAmounts.length; ++i) { - messageEvent.tokenAmounts[i] = _getSourceTokenData(message.tokenAmounts[i], tokenAdminRegistry); - } - - messageEvent.header.messageId = Internal._hash(messageEvent, metadataHash); - return messageEvent; - } - - function _getSourceTokenData( - Client.EVMTokenAmount memory tokenAmount, - TokenAdminRegistry tokenAdminRegistry - ) internal view returns (Internal.RampTokenAmount memory) { - address destToken = s_destTokenBySourceToken[tokenAmount.token]; - - return Internal.RampTokenAmount({ - sourcePoolAddress: abi.encode(tokenAdminRegistry.getTokenConfig(tokenAmount.token).tokenPool), - destTokenAddress: abi.encode(destToken), - extraData: "", - amount: tokenAmount.amount - }); - } - - function calcUSDValueFromTokenAmount(uint224 tokenPrice, uint256 tokenAmount) internal pure returns (uint256) { - return (tokenPrice * tokenAmount) / 1e18; - } - - function applyBpsRatio(uint256 tokenAmount, uint16 ratio) internal pure returns (uint256) { - return (tokenAmount * ratio) / 1e5; - } - - function configUSDCentToWei(uint256 usdCent) internal pure returns (uint256) { - return usdCent * 1e16; - } -} contract PriceRegistry_constructor is PriceRegistrySetup { function test_Setup_Success() public virtual { @@ -441,9 +23,9 @@ contract PriceRegistry_constructor is PriceRegistrySetup { feeTokens[1] = s_sourceTokens[1]; PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](2); tokenPriceFeedUpdates[0] = - getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); + _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); tokenPriceFeedUpdates[1] = - getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[1], s_dataFeedByToken[s_sourceTokens[1]], 6); + _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[1], s_dataFeedByToken[s_sourceTokens[1]], 6); PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); @@ -641,7 +223,7 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 18, int256(uint256(type(uint224).max))); PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); - tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); + tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); @@ -655,7 +237,7 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 8, 1e8); PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); - tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 6); + tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 6); s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); @@ -669,7 +251,7 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 8, 1e8); PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); - tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 24); + tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 24); s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); @@ -683,7 +265,7 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 18, 1e18); PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); - tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); + tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); @@ -697,7 +279,7 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 0, 1e31); PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); - tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 0); + tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 0); s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); @@ -711,7 +293,7 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 20, 1e18); PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); - tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 20); + tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 20); s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); @@ -738,7 +320,7 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 18, int256(uint256(type(uint224).max) + 1)); PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); - tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); + tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); vm.expectRevert(PriceRegistry.DataFeedValueOutOfUint224Range.selector); @@ -750,7 +332,7 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 18, -1); PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); - tokenPriceFeedUpdates[0] = getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); + tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); vm.expectRevert(PriceRegistry.DataFeedValueOutOfUint224Range.selector); @@ -1050,7 +632,7 @@ contract PriceRegistry_updateTokenPriceFeeds is PriceRegistrySetup { function test_SingleFeedUpdate_Success() public { PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = - getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); + _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); _assertTokenPriceFeedConfigUnconfigured( s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken) @@ -1073,7 +655,7 @@ contract PriceRegistry_updateTokenPriceFeeds is PriceRegistrySetup { for (uint256 i = 0; i < 2; ++i) { tokenPriceFeedUpdates[i] = - getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[i], s_dataFeedByToken[s_sourceTokens[i]], 18); + _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[i], s_dataFeedByToken[s_sourceTokens[i]], 18); _assertTokenPriceFeedConfigUnconfigured( s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[i].sourceToken) @@ -1102,7 +684,7 @@ contract PriceRegistry_updateTokenPriceFeeds is PriceRegistrySetup { PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = - getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); + _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); _assertTokenPriceFeedConfigEquality( @@ -1129,7 +711,7 @@ contract PriceRegistry_updateTokenPriceFeeds is PriceRegistrySetup { function test_FeedNotUpdated() public { PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = - getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); + _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); @@ -1144,7 +726,7 @@ contract PriceRegistry_updateTokenPriceFeeds is PriceRegistrySetup { function test_FeedUpdatedByNonOwner_Revert() public { PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = - getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); + _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); vm.startPrank(STRANGER); vm.expectRevert("Only callable by owner"); @@ -1713,7 +1295,7 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); - assertEq(configUSDCentToWei(transferFeeConfig.minFeeUSDCents), feeUSDWei); + assertEq(_configUSDCentToWei(transferFeeConfig.minFeeUSDCents), feeUSDWei); assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); } @@ -1726,7 +1308,7 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); - assertEq(configUSDCentToWei(transferFeeConfig.minFeeUSDCents), feeUSDWei); + assertEq(_configUSDCentToWei(transferFeeConfig.minFeeUSDCents), feeUSDWei); assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); } @@ -1739,7 +1321,7 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); - assertEq(configUSDCentToWei(transferFeeConfig.maxFeeUSDCents), feeUSDWei); + assertEq(_configUSDCentToWei(transferFeeConfig.maxFeeUSDCents), feeUSDWei); assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); } @@ -1754,8 +1336,8 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); - uint256 usdWei = calcUSDValueFromTokenAmount(s_feeTokenPrice, tokenAmount); - uint256 bpsUSDWei = applyBpsRatio( + uint256 usdWei = _calcUSDValueFromTokenAmount(s_feeTokenPrice, tokenAmount); + uint256 bpsUSDWei = _applyBpsRatio( usdWei, s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig.deciBps ); @@ -1782,8 +1364,8 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); - uint256 usdWei = calcUSDValueFromTokenAmount(s_customTokenPrice, tokenAmount); - uint256 bpsUSDWei = applyBpsRatio( + uint256 usdWei = _calcUSDValueFromTokenAmount(s_customTokenPrice, tokenAmount); + uint256 bpsUSDWei = _applyBpsRatio( usdWei, s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig.deciBps ); @@ -1816,7 +1398,9 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { // if token charges 0 bps, it should cost minFee to transfer assertEq( - configUSDCentToWei(tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig.minFeeUSDCents), + _configUSDCentToWei( + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig.minFeeUSDCents + ), feeUSDWei ); assertEq(0, destGasOverhead); @@ -1888,7 +1472,7 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { uint256 expectedFeeUSDWei = 0; for (uint256 i = 0; i < testTokens.length; ++i) { - expectedFeeUSDWei += configUSDCentToWei( + expectedFeeUSDWei += _configUSDCentToWei( tokenTransferFeeConfigs[i].minFeeUSDCents == 0 ? DEFAULT_TOKEN_FEE_USD_CENTS : tokenTransferFeeConfigs[i].minFeeUSDCents @@ -1902,15 +1486,15 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { // Set 1st token transfer to a meaningful amount so its bps fee is now between min and max fee message.tokenAmounts[0] = Client.EVMTokenAmount({token: testTokens[0], amount: 10000e18}); - uint256 token0USDWei = applyBpsRatio( - calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), tokenTransferFeeConfigs[0].deciBps + uint256 token0USDWei = _applyBpsRatio( + _calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), tokenTransferFeeConfigs[0].deciBps ); - uint256 token1USDWei = configUSDCentToWei(DEFAULT_TOKEN_FEE_USD_CENTS); + uint256 token1USDWei = _configUSDCentToWei(DEFAULT_TOKEN_FEE_USD_CENTS); (feeUSDWei, destGasOverhead, destBytesOverhead) = s_priceRegistry.getTokenTransferCost( DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts ); - expectedFeeUSDWei = token0USDWei + token1USDWei + configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); + expectedFeeUSDWei = token0USDWei + token1USDWei + _configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); assertEq(expectedFeeUSDWei, feeUSDWei, "wrong feeUSDWei 2"); assertEq(expectedTotalGas, destGasOverhead, "wrong destGasOverhead 2"); @@ -1922,7 +1506,7 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { (feeUSDWei, destGasOverhead, destBytesOverhead) = s_priceRegistry.getTokenTransferCost( DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts ); - expectedFeeUSDWei = token0USDWei + token1USDWei + configUSDCentToWei(tokenTransferFeeConfigs[2].maxFeeUSDCents); + expectedFeeUSDWei = token0USDWei + token1USDWei + _configUSDCentToWei(tokenTransferFeeConfigs[2].maxFeeUSDCents); assertEq(expectedFeeUSDWei, feeUSDWei, "wrong feeUSDWei 3"); assertEq(expectedTotalGas, destGasOverhead, "wrong destGasOverhead 3"); @@ -1947,7 +1531,7 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { uint256 gasUsed = GAS_LIMIT + DEST_GAS_OVERHEAD; uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); - uint256 messageFeeUSD = (configUSDCentToWei(destChainConfig.networkFeeUSDCents) * premiumMultiplierWeiPerEth); + uint256 messageFeeUSD = (_configUSDCentToWei(destChainConfig.networkFeeUSDCents) * premiumMultiplierWeiPerEth); uint256 dataAvailabilityFeeUSD = s_priceRegistry.getDataAvailabilityCost( DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, message.data.length, message.tokenAmounts.length, 0 ); @@ -1972,7 +1556,7 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { uint256 gasUsed = GAS_LIMIT + DEST_GAS_OVERHEAD; uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); - uint256 messageFeeUSD = (configUSDCentToWei(destChainConfig.networkFeeUSDCents) * premiumMultiplierWeiPerEth); + uint256 messageFeeUSD = (_configUSDCentToWei(destChainConfig.networkFeeUSDCents) * premiumMultiplierWeiPerEth); uint256 totalPriceInFeeToken = (gasFeeUSD + messageFeeUSD) / s_feeTokenPrice; assertEq(totalPriceInFeeToken, feeAmount); @@ -1999,7 +1583,7 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { uint256 feeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); uint256 gasUsed = customGasLimit + DEST_GAS_OVERHEAD + customDataSize * DEST_GAS_PER_PAYLOAD_BYTE; uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); - uint256 messageFeeUSD = (configUSDCentToWei(destChainConfig.networkFeeUSDCents) * premiumMultiplierWeiPerEth); + uint256 messageFeeUSD = (_configUSDCentToWei(destChainConfig.networkFeeUSDCents) * premiumMultiplierWeiPerEth); uint256 dataAvailabilityFeeUSD = s_priceRegistry.getDataAvailabilityCost( DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, message.data.length, message.tokenAmounts.length, 0 ); diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistrySetup.t.sol b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistrySetup.t.sol new file mode 100644 index 0000000000..6a4a1e3205 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistrySetup.t.sol @@ -0,0 +1,418 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; + +import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol"; +import {PriceRegistry} from "../../PriceRegistry.sol"; +import {Client} from "../../libraries/Client.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; +import {TokenSetup} from "../TokenSetup.t.sol"; +import {PriceRegistryHelper} from "../helpers/PriceRegistryHelper.sol"; + +contract PriceRegistrySetup is TokenSetup { + uint112 internal constant USD_PER_GAS = 1e6; // 0.001 gwei + uint112 internal constant USD_PER_DATA_AVAILABILITY_GAS = 1e9; // 1 gwei + + address internal constant CUSTOM_TOKEN = address(12345); + uint224 internal constant CUSTOM_TOKEN_PRICE = 1e17; // $0.1 CUSTOM + + // Encode L1 gas price and L2 gas price into a packed price. + // L1 gas price is left-shifted to the higher-order bits. + uint224 internal constant PACKED_USD_PER_GAS = + (uint224(USD_PER_DATA_AVAILABILITY_GAS) << Internal.GAS_PRICE_BITS) + USD_PER_GAS; + + PriceRegistryHelper internal s_priceRegistry; + // Cheat to store the price updates in storage since struct arrays aren't supported. + bytes internal s_encodedInitialPriceUpdates; + address internal s_weth; + + address[] internal s_sourceFeeTokens; + uint224[] internal s_sourceTokenPrices; + address[] internal s_destFeeTokens; + uint224[] internal s_destTokenPrices; + + PriceRegistry.PremiumMultiplierWeiPerEthArgs[] internal s_priceRegistryPremiumMultiplierWeiPerEthArgs; + PriceRegistry.TokenTransferFeeConfigArgs[] internal s_priceRegistryTokenTransferFeeConfigArgs; + + mapping(address token => address dataFeedAddress) internal s_dataFeedByToken; + + function setUp() public virtual override { + TokenSetup.setUp(); + + _deployTokenPriceDataFeed(s_sourceFeeToken, 8, 1e8); + + s_weth = s_sourceRouter.getWrappedNative(); + _deployTokenPriceDataFeed(s_weth, 8, 1e11); + + address[] memory sourceFeeTokens = new address[](3); + sourceFeeTokens[0] = s_sourceTokens[0]; + sourceFeeTokens[1] = s_sourceTokens[1]; + sourceFeeTokens[2] = s_sourceRouter.getWrappedNative(); + s_sourceFeeTokens = sourceFeeTokens; + + uint224[] memory sourceTokenPrices = new uint224[](3); + sourceTokenPrices[0] = 5e18; + sourceTokenPrices[1] = 2000e18; + sourceTokenPrices[2] = 2000e18; + s_sourceTokenPrices = sourceTokenPrices; + + address[] memory destFeeTokens = new address[](3); + destFeeTokens[0] = s_destTokens[0]; + destFeeTokens[1] = s_destTokens[1]; + destFeeTokens[2] = s_destRouter.getWrappedNative(); + s_destFeeTokens = destFeeTokens; + + uint224[] memory destTokenPrices = new uint224[](3); + destTokenPrices[0] = 5e18; + destTokenPrices[1] = 2000e18; + destTokenPrices[2] = 2000e18; + s_destTokenPrices = destTokenPrices; + + uint256 sourceTokenCount = sourceFeeTokens.length; + uint256 destTokenCount = destFeeTokens.length; + address[] memory pricedTokens = new address[](sourceTokenCount + destTokenCount); + uint224[] memory tokenPrices = new uint224[](sourceTokenCount + destTokenCount); + for (uint256 i = 0; i < sourceTokenCount; ++i) { + pricedTokens[i] = sourceFeeTokens[i]; + tokenPrices[i] = sourceTokenPrices[i]; + } + for (uint256 i = 0; i < destTokenCount; ++i) { + pricedTokens[i + sourceTokenCount] = destFeeTokens[i]; + tokenPrices[i + sourceTokenCount] = destTokenPrices[i]; + } + + Internal.PriceUpdates memory priceUpdates = _getPriceUpdatesStruct(pricedTokens, tokenPrices); + priceUpdates.gasPriceUpdates = new Internal.GasPriceUpdate[](1); + priceUpdates.gasPriceUpdates[0] = + Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_SELECTOR, usdPerUnitGas: PACKED_USD_PER_GAS}); + + s_encodedInitialPriceUpdates = abi.encode(priceUpdates); + + address[] memory priceUpdaters = new address[](1); + priceUpdaters[0] = OWNER; + address[] memory feeTokens = new address[](2); + feeTokens[0] = s_sourceTokens[0]; + feeTokens[1] = s_weth; + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](0); + + s_priceRegistryPremiumMultiplierWeiPerEthArgs.push( + PriceRegistry.PremiumMultiplierWeiPerEthArgs({ + token: s_sourceFeeToken, + premiumMultiplierWeiPerEth: 5e17 // 0.5x + }) + ); + s_priceRegistryPremiumMultiplierWeiPerEthArgs.push( + PriceRegistry.PremiumMultiplierWeiPerEthArgs({ + token: s_sourceRouter.getWrappedNative(), + premiumMultiplierWeiPerEth: 2e18 // 2x + }) + ); + + s_priceRegistryTokenTransferFeeConfigArgs.push(); + s_priceRegistryTokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; + s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( + PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ + token: s_sourceFeeToken, + tokenTransferFeeConfig: PriceRegistry.TokenTransferFeeConfig({ + minFeeUSDCents: 1_00, // 1 USD + maxFeeUSDCents: 1000_00, // 1,000 USD + deciBps: 2_5, // 2.5 bps, or 0.025% + destGasOverhead: 40_000, + destBytesOverhead: 32, + isEnabled: true + }) + }) + ); + s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( + PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ + token: CUSTOM_TOKEN, + tokenTransferFeeConfig: PriceRegistry.TokenTransferFeeConfig({ + minFeeUSDCents: 2_00, // 1 USD + maxFeeUSDCents: 2000_00, // 1,000 USD + deciBps: 10_0, // 10 bps, or 0.1% + destGasOverhead: 1, + destBytesOverhead: 200, + isEnabled: true + }) + }) + ); + + s_priceRegistry = new PriceRegistryHelper( + PriceRegistry.StaticConfig({ + linkToken: s_sourceTokens[0], + maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS, + stalenessThreshold: uint32(TWELVE_HOURS) + }), + priceUpdaters, + feeTokens, + tokenPriceFeedUpdates, + s_priceRegistryTokenTransferFeeConfigArgs, + s_priceRegistryPremiumMultiplierWeiPerEthArgs, + _generatePriceRegistryDestChainConfigArgs() + ); + s_priceRegistry.updatePrices(priceUpdates); + } + + function _deployTokenPriceDataFeed(address token, uint8 decimals, int256 initialAnswer) internal returns (address) { + MockV3Aggregator dataFeed = new MockV3Aggregator(decimals, initialAnswer); + s_dataFeedByToken[token] = address(dataFeed); + return address(dataFeed); + } + + function _getPriceUpdatesStruct( + address[] memory tokens, + uint224[] memory prices + ) internal pure returns (Internal.PriceUpdates memory) { + uint256 length = tokens.length; + + Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](length); + for (uint256 i = 0; i < length; ++i) { + tokenPriceUpdates[i] = Internal.TokenPriceUpdate({sourceToken: tokens[i], usdPerToken: prices[i]}); + } + Internal.PriceUpdates memory priceUpdates = + Internal.PriceUpdates({tokenPriceUpdates: tokenPriceUpdates, gasPriceUpdates: new Internal.GasPriceUpdate[](0)}); + + return priceUpdates; + } + + function _getEmptyPriceUpdates() internal pure returns (Internal.PriceUpdates memory priceUpdates) { + return Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + gasPriceUpdates: new Internal.GasPriceUpdate[](0) + }); + } + + function _getSingleTokenPriceFeedUpdateStruct( + address sourceToken, + address dataFeedAddress, + uint8 tokenDecimals + ) internal pure returns (PriceRegistry.TokenPriceFeedUpdate memory) { + return PriceRegistry.TokenPriceFeedUpdate({ + sourceToken: sourceToken, + feedConfig: IPriceRegistry.TokenPriceFeedConfig({dataFeedAddress: dataFeedAddress, tokenDecimals: tokenDecimals}) + }); + } + + function _initialiseSingleTokenPriceFeed() internal returns (address) { + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + tokenPriceFeedUpdates[0] = + _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + return s_sourceTokens[0]; + } + + function _generateTokenTransferFeeConfigArgs( + uint256 destChainSelectorLength, + uint256 tokenLength + ) internal pure returns (PriceRegistry.TokenTransferFeeConfigArgs[] memory) { + PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + new PriceRegistry.TokenTransferFeeConfigArgs[](destChainSelectorLength); + for (uint256 i = 0; i < destChainSelectorLength; ++i) { + tokenTransferFeeConfigArgs[i].tokenTransferFeeConfigs = + new PriceRegistry.TokenTransferFeeConfigSingleTokenArgs[](tokenLength); + } + return tokenTransferFeeConfigArgs; + } + + function _generatePriceRegistryDestChainConfigArgs() + internal + pure + returns (PriceRegistry.DestChainConfigArgs[] memory) + { + PriceRegistry.DestChainConfigArgs[] memory destChainConfigs = new PriceRegistry.DestChainConfigArgs[](1); + destChainConfigs[0] = PriceRegistry.DestChainConfigArgs({ + destChainSelector: DEST_CHAIN_SELECTOR, + destChainConfig: PriceRegistry.DestChainConfig({ + isEnabled: true, + maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, + destGasOverhead: DEST_GAS_OVERHEAD, + destGasPerPayloadByte: DEST_GAS_PER_PAYLOAD_BYTE, + destDataAvailabilityOverheadGas: DEST_DATA_AVAILABILITY_OVERHEAD_GAS, + destGasPerDataAvailabilityByte: DEST_GAS_PER_DATA_AVAILABILITY_BYTE, + destDataAvailabilityMultiplierBps: DEST_GAS_DATA_AVAILABILITY_MULTIPLIER_BPS, + maxDataBytes: MAX_DATA_SIZE, + maxPerMsgGasLimit: MAX_GAS_LIMIT, + defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, + defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, + defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, + defaultTxGasLimit: GAS_LIMIT, + gasMultiplierWeiPerEth: 5e17, + networkFeeUSDCents: 1_00, + enforceOutOfOrder: false, + chainFamilySelector: Internal.CHAIN_FAMILY_SELECTOR_EVM + }) + }); + return destChainConfigs; + } + + function _assertTokenPriceFeedConfigEquality( + IPriceRegistry.TokenPriceFeedConfig memory config1, + IPriceRegistry.TokenPriceFeedConfig memory config2 + ) internal pure virtual { + assertEq(config1.dataFeedAddress, config2.dataFeedAddress); + assertEq(config1.tokenDecimals, config2.tokenDecimals); + } + + function _assertTokenPriceFeedConfigUnconfigured(IPriceRegistry.TokenPriceFeedConfig memory config) + internal + pure + virtual + { + _assertTokenPriceFeedConfigEquality( + config, IPriceRegistry.TokenPriceFeedConfig({dataFeedAddress: address(0), tokenDecimals: 0}) + ); + } + + function _assertTokenTransferFeeConfigEqual( + PriceRegistry.TokenTransferFeeConfig memory a, + PriceRegistry.TokenTransferFeeConfig memory b + ) internal pure { + assertEq(a.minFeeUSDCents, b.minFeeUSDCents); + assertEq(a.maxFeeUSDCents, b.maxFeeUSDCents); + assertEq(a.deciBps, b.deciBps); + assertEq(a.destGasOverhead, b.destGasOverhead); + assertEq(a.destBytesOverhead, b.destBytesOverhead); + assertEq(a.isEnabled, b.isEnabled); + } + + function _assertPriceRegistryStaticConfigsEqual( + PriceRegistry.StaticConfig memory a, + PriceRegistry.StaticConfig memory b + ) internal pure { + assertEq(a.linkToken, b.linkToken); + assertEq(a.maxFeeJuelsPerMsg, b.maxFeeJuelsPerMsg); + } + + function _assertPriceRegistryDestChainConfigsEqual( + PriceRegistry.DestChainConfig memory a, + PriceRegistry.DestChainConfig memory b + ) internal pure { + assertEq(a.isEnabled, b.isEnabled); + assertEq(a.maxNumberOfTokensPerMsg, b.maxNumberOfTokensPerMsg); + assertEq(a.maxDataBytes, b.maxDataBytes); + assertEq(a.maxPerMsgGasLimit, b.maxPerMsgGasLimit); + assertEq(a.destGasOverhead, b.destGasOverhead); + assertEq(a.destGasPerPayloadByte, b.destGasPerPayloadByte); + assertEq(a.destDataAvailabilityOverheadGas, b.destDataAvailabilityOverheadGas); + assertEq(a.destGasPerDataAvailabilityByte, b.destGasPerDataAvailabilityByte); + assertEq(a.destDataAvailabilityMultiplierBps, b.destDataAvailabilityMultiplierBps); + assertEq(a.defaultTokenFeeUSDCents, b.defaultTokenFeeUSDCents); + assertEq(a.defaultTokenDestGasOverhead, b.defaultTokenDestGasOverhead); + assertEq(a.defaultTokenDestBytesOverhead, b.defaultTokenDestBytesOverhead); + assertEq(a.defaultTxGasLimit, b.defaultTxGasLimit); + } +} + +contract PriceRegistryFeeSetup is PriceRegistrySetup { + uint224 internal s_feeTokenPrice; + uint224 internal s_wrappedTokenPrice; + uint224 internal s_customTokenPrice; + + address internal s_selfServeTokenDefaultPricing = makeAddr("self-serve-token-default-pricing"); + + address internal s_destTokenPool = makeAddr("destTokenPool"); + address internal s_destToken = makeAddr("destToken"); + + function setUp() public virtual override { + super.setUp(); + + s_feeTokenPrice = s_sourceTokenPrices[0]; + s_wrappedTokenPrice = s_sourceTokenPrices[2]; + s_customTokenPrice = CUSTOM_TOKEN_PRICE; + + s_priceRegistry.updatePrices(_getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); + } + + function _generateEmptyMessage() public view returns (Client.EVM2AnyMessage memory) { + return Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: new Client.EVMTokenAmount[](0), + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + } + + function _generateSingleTokenMessage( + address token, + uint256 amount + ) public view returns (Client.EVM2AnyMessage memory) { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({token: token, amount: amount}); + + return Client.EVM2AnyMessage({ + receiver: abi.encode(OWNER), + data: "", + tokenAmounts: tokenAmounts, + feeToken: s_sourceFeeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) + }); + } + + function _messageToEvent( + Client.EVM2AnyMessage memory message, + uint64 sourceChainSelector, + uint64 destChainSelector, + uint64 seqNum, + uint64 nonce, + uint256 feeTokenAmount, + address originalSender, + bytes32 metadataHash, + TokenAdminRegistry tokenAdminRegistry + ) internal view returns (Internal.EVM2AnyRampMessage memory) { + Client.EVMExtraArgsV2 memory extraArgs = + s_priceRegistry.parseEVMExtraArgsFromBytes(message.extraArgs, destChainSelector); + + Internal.EVM2AnyRampMessage memory messageEvent = Internal.EVM2AnyRampMessage({ + header: Internal.RampMessageHeader({ + messageId: "", + sourceChainSelector: sourceChainSelector, + destChainSelector: destChainSelector, + sequenceNumber: seqNum, + nonce: extraArgs.allowOutOfOrderExecution ? 0 : nonce + }), + sender: originalSender, + data: message.data, + receiver: message.receiver, + extraArgs: Client._argsToBytes(extraArgs), + feeToken: message.feeToken, + feeTokenAmount: feeTokenAmount, + tokenAmounts: new Internal.RampTokenAmount[](message.tokenAmounts.length) + }); + + for (uint256 i = 0; i < message.tokenAmounts.length; ++i) { + messageEvent.tokenAmounts[i] = _getSourceTokenData(message.tokenAmounts[i], tokenAdminRegistry); + } + + messageEvent.header.messageId = Internal._hash(messageEvent, metadataHash); + return messageEvent; + } + + function _getSourceTokenData( + Client.EVMTokenAmount memory tokenAmount, + TokenAdminRegistry tokenAdminRegistry + ) internal view returns (Internal.RampTokenAmount memory) { + address destToken = s_destTokenBySourceToken[tokenAmount.token]; + + return Internal.RampTokenAmount({ + sourcePoolAddress: abi.encode(tokenAdminRegistry.getTokenConfig(tokenAmount.token).tokenPool), + destTokenAddress: abi.encode(destToken), + extraData: "", + amount: tokenAmount.amount + }); + } + + function _calcUSDValueFromTokenAmount(uint224 tokenPrice, uint256 tokenAmount) internal pure returns (uint256) { + return (tokenPrice * tokenAmount) / 1e18; + } + + function _applyBpsRatio(uint256 tokenAmount, uint16 ratio) internal pure returns (uint256) { + return (tokenAmount * ratio) / 1e5; + } + + function _configUSDCentToWei(uint256 usdCent) internal pure returns (uint256) { + return usdCent * 1e16; + } +} diff --git a/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol b/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol index d3a07ef11e..af970b0f92 100644 --- a/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol +++ b/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol @@ -6,7 +6,7 @@ import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {AggregateRateLimiterHelper} from "../helpers/AggregateRateLimiterHelper.sol"; -import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; +import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; import {stdError} from "forge-std/Test.sol"; @@ -20,7 +20,7 @@ contract AggregateTokenLimiterSetup is PriceRegistrySetup { function setUp() public virtual override { PriceRegistrySetup.setUp(); - Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(TOKEN, TOKEN_PRICE); + Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(TOKEN, TOKEN_PRICE); s_priceRegistry.updatePrices(priceUpdates); s_config = RateLimiter.Config({isEnabled: true, rate: 5, capacity: 100}); diff --git a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol index e30ce02212..292c4533e4 100644 --- a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol +++ b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol @@ -8,7 +8,7 @@ import {Internal} from "../../libraries/Internal.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {BaseTest} from "../BaseTest.t.sol"; import {MultiAggregateRateLimiterHelper} from "../helpers/MultiAggregateRateLimiterHelper.sol"; -import {PriceRegistrySetup} from "../priceRegistry/PriceRegistry.t.sol"; +import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; import {stdError} from "forge-std/Test.sol"; import {Vm} from "forge-std/Vm.sol"; @@ -33,7 +33,7 @@ contract MultiAggregateRateLimiterSetup is BaseTest, PriceRegistrySetup { BaseTest.setUp(); PriceRegistrySetup.setUp(); - Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(TOKEN, TOKEN_PRICE); + Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(TOKEN, TOKEN_PRICE); s_priceRegistry.updatePrices(priceUpdates); MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = @@ -683,7 +683,7 @@ contract MultiAggregateRateLimiter_onInboundMessage is MultiAggregateRateLimiter }); Internal.PriceUpdates memory priceUpdates = - getSingleTokenPriceUpdateStruct(s_destTokens[i], TOKEN_PRICE * (i + 1)); + _getSingleTokenPriceUpdateStruct(s_destTokens[i], TOKEN_PRICE * (i + 1)); s_priceRegistry.updatePrices(priceUpdates); } s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); @@ -919,7 +919,7 @@ contract MultiAggregateRateLimiter_onOutboundMessage is MultiAggregateRateLimite }); Internal.PriceUpdates memory priceUpdates = - getSingleTokenPriceUpdateStruct(s_sourceTokens[i], TOKEN_PRICE * (i + 1)); + _getSingleTokenPriceUpdateStruct(s_sourceTokens[i], TOKEN_PRICE * (i + 1)); s_priceRegistry.updatePrices(priceUpdates); } s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); diff --git a/contracts/src/v0.8/ccip/test/router/Router.t.sol b/contracts/src/v0.8/ccip/test/router/Router.t.sol index cfe01e3c41..5f3a3a66ab 100644 --- a/contracts/src/v0.8/ccip/test/router/Router.t.sol +++ b/contracts/src/v0.8/ccip/test/router/Router.t.sol @@ -265,8 +265,11 @@ contract Router_ccipSend is EVM2EVMOnRampSetup { s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); // Update the price of the newly set feeToken - Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(feeTokenWithZeroFeeAndGas, 2_000 ether); - priceUpdates.gasPriceUpdates = getSingleGasPriceUpdateStruct(DEST_CHAIN_SELECTOR, 0).gasPriceUpdates; + Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(feeTokenWithZeroFeeAndGas, 2_000 ether); + priceUpdates.gasPriceUpdates = new Internal.GasPriceUpdate[](1); + priceUpdates.gasPriceUpdates[0] = + Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_SELECTOR, usdPerUnitGas: 0}); + s_priceRegistry.updatePrices(priceUpdates); // Set the feeToken args on the onRamp @@ -396,20 +399,20 @@ contract Router_applyRampUpdates is RouterSetup { s_receiver = new MaybeRevertMessageReceiver(false); } - function assertOffRampRouteSucceeds(Router.OffRamp memory offRamp) internal { + function _assertOffRampRouteSucceeds(Router.OffRamp memory offRamp) internal { vm.startPrank(offRamp.offRamp); - Client.Any2EVMMessage memory message = generateReceiverMessage(offRamp.sourceChainSelector); + Client.Any2EVMMessage memory message = _generateReceiverMessage(offRamp.sourceChainSelector); vm.expectCall(address(s_receiver), abi.encodeWithSelector(IAny2EVMMessageReceiver.ccipReceive.selector, message)); s_sourceRouter.routeMessage(message, GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver)); } - function assertOffRampRouteReverts(Router.OffRamp memory offRamp) internal { + function _assertOffRampRouteReverts(Router.OffRamp memory offRamp) internal { vm.startPrank(offRamp.offRamp); vm.expectRevert(IRouter.OnlyOffRamp.selector); s_sourceRouter.routeMessage( - generateReceiverMessage(offRamp.sourceChainSelector), GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver) + _generateReceiverMessage(offRamp.sourceChainSelector), GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver) ); } @@ -483,7 +486,7 @@ contract Router_applyRampUpdates is RouterSetup { for (uint256 i = 0; i < offRampUpdates.length; ++i) { assertEq(offRampUpdates[i].offRamp, gotOffRamps[i].offRamp); assertTrue(s_sourceRouter.isOffRamp(offRampUpdates[i].sourceChainSelector, offRampUpdates[i].offRamp)); - assertOffRampRouteSucceeds(offRampUpdates[i]); + _assertOffRampRouteSucceeds(offRampUpdates[i]); } vm.startPrank(OWNER); @@ -520,14 +523,14 @@ contract Router_applyRampUpdates is RouterSetup { assertFalse( s_sourceRouter.isOffRamp(partialOffRampRemoves[i].sourceChainSelector, partialOffRampRemoves[i].offRamp) ); - assertOffRampRouteReverts(partialOffRampRemoves[i]); + _assertOffRampRouteReverts(partialOffRampRemoves[i]); assertTrue(s_sourceRouter.isOffRamp(partialOffRampAdds[i].sourceChainSelector, partialOffRampAdds[i].offRamp)); - assertOffRampRouteSucceeds(partialOffRampAdds[i]); + _assertOffRampRouteSucceeds(partialOffRampAdds[i]); } for (uint256 i = numberOfPartialUpdates; i < offRampUpdates.length; ++i) { assertTrue(s_sourceRouter.isOffRamp(offRampUpdates[i].sourceChainSelector, offRampUpdates[i].offRamp)); - assertOffRampRouteSucceeds(offRampUpdates[i]); + _assertOffRampRouteSucceeds(offRampUpdates[i]); } vm.startPrank(OWNER); @@ -557,11 +560,11 @@ contract Router_applyRampUpdates is RouterSetup { for (uint256 i = 0; i < numberOfPartialUpdates; ++i) { assertFalse(s_sourceRouter.isOffRamp(partialOffRampAdds[i].sourceChainSelector, partialOffRampAdds[i].offRamp)); - assertOffRampRouteReverts(partialOffRampAdds[i]); + _assertOffRampRouteReverts(partialOffRampAdds[i]); } for (uint256 i = 0; i < offRampUpdates.length; ++i) { assertFalse(s_sourceRouter.isOffRamp(offRampUpdates[i].sourceChainSelector, offRampUpdates[i].offRamp)); - assertOffRampRouteReverts(offRampUpdates[i]); + _assertOffRampRouteReverts(offRampUpdates[i]); } vm.startPrank(OWNER); @@ -582,13 +585,13 @@ contract Router_applyRampUpdates is RouterSetup { for (uint256 i = 0; i < offRampUpdates.length; ++i) { assertEq(offRampUpdates[i].offRamp, gotOffRamps[i].offRamp); assertTrue(s_sourceRouter.isOffRamp(offRampUpdates[i].sourceChainSelector, offRampUpdates[i].offRamp)); - assertOffRampRouteSucceeds(offRampUpdates[i]); + _assertOffRampRouteSucceeds(offRampUpdates[i]); } // Check offramps that were not added back remain unset. for (uint256 i = 0; i < numberOfPartialUpdates; ++i) { assertFalse(s_sourceRouter.isOffRamp(partialOffRampAdds[i].sourceChainSelector, partialOffRampAdds[i].offRamp)); - assertOffRampRouteReverts(partialOffRampAdds[i]); + _assertOffRampRouteReverts(partialOffRampAdds[i]); } } @@ -691,18 +694,18 @@ contract Router_routeMessage is EVM2EVMOffRampSetup { vm.startPrank(address(s_offRamp)); } - function generateManualGasLimit(uint256 callDataLength) internal view returns (uint256) { + function _generateManualGasLimit(uint256 callDataLength) internal view returns (uint256) { return ((gasleft() - 2 * (16 * callDataLength + GAS_FOR_CALL_EXACT_CHECK)) * 62) / 64; } function test_ManualExec_Success() public { - Client.Any2EVMMessage memory message = generateReceiverMessage(SOURCE_CHAIN_SELECTOR); + Client.Any2EVMMessage memory message = _generateReceiverMessage(SOURCE_CHAIN_SELECTOR); // Manuel execution cannot run out of gas (bool success, bytes memory retData, uint256 gasUsed) = s_destRouter.routeMessage( - generateReceiverMessage(SOURCE_CHAIN_SELECTOR), + _generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, - generateManualGasLimit(message.data.length), + _generateManualGasLimit(message.data.length), address(s_receiver) ); assertTrue(success); @@ -711,7 +714,7 @@ contract Router_routeMessage is EVM2EVMOffRampSetup { } function test_ExecutionEvent_Success() public { - Client.Any2EVMMessage memory message = generateReceiverMessage(SOURCE_CHAIN_SELECTOR); + Client.Any2EVMMessage memory message = _generateReceiverMessage(SOURCE_CHAIN_SELECTOR); // Should revert with reason bytes memory realError1 = new bytes(2); realError1[0] = 0xbe; @@ -727,9 +730,9 @@ contract Router_routeMessage is EVM2EVMOffRampSetup { ); (bool success, bytes memory retData, uint256 gasUsed) = s_destRouter.routeMessage( - generateReceiverMessage(SOURCE_CHAIN_SELECTOR), + _generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, - generateManualGasLimit(message.data.length), + _generateManualGasLimit(message.data.length), address(s_reverting_receiver) ); @@ -753,9 +756,9 @@ contract Router_routeMessage is EVM2EVMOffRampSetup { ); (success, retData, gasUsed) = s_destRouter.routeMessage( - generateReceiverMessage(SOURCE_CHAIN_SELECTOR), + _generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, - generateManualGasLimit(message.data.length), + _generateManualGasLimit(message.data.length), address(s_reverting_receiver) ); @@ -782,9 +785,9 @@ contract Router_routeMessage is EVM2EVMOffRampSetup { ); (success, retData, gasUsed) = s_destRouter.routeMessage( - generateReceiverMessage(SOURCE_CHAIN_SELECTOR), + _generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, - generateManualGasLimit(message.data.length), + _generateManualGasLimit(message.data.length), address(s_receiver) ); @@ -794,7 +797,7 @@ contract Router_routeMessage is EVM2EVMOffRampSetup { } function test_Fuzz_ExecutionEvent_Success(bytes calldata error) public { - Client.Any2EVMMessage memory message = generateReceiverMessage(SOURCE_CHAIN_SELECTOR); + Client.Any2EVMMessage memory message = _generateReceiverMessage(SOURCE_CHAIN_SELECTOR); s_reverting_receiver.setErr(error); bytes memory expectedRetData; @@ -827,9 +830,9 @@ contract Router_routeMessage is EVM2EVMOffRampSetup { } (bool success, bytes memory retData,) = s_destRouter.routeMessage( - generateReceiverMessage(SOURCE_CHAIN_SELECTOR), + _generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, - generateManualGasLimit(message.data.length), + _generateManualGasLimit(message.data.length), address(s_reverting_receiver) ); @@ -839,13 +842,13 @@ contract Router_routeMessage is EVM2EVMOffRampSetup { function test_AutoExec_Success() public { (bool success,,) = s_destRouter.routeMessage( - generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver) + _generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver) ); assertTrue(success); (success,,) = s_destRouter.routeMessage( - generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, 1, address(s_receiver) + _generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, 1, address(s_receiver) ); // Can run out of gas, should return false @@ -859,7 +862,7 @@ contract Router_routeMessage is EVM2EVMOffRampSetup { vm.expectRevert(IRouter.OnlyOffRamp.selector); s_destRouter.routeMessage( - generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver) + _generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver) ); } @@ -867,7 +870,7 @@ contract Router_routeMessage is EVM2EVMOffRampSetup { s_mockRMN.setGlobalCursed(true); vm.expectRevert(Router.BadARMSignal.selector); s_destRouter.routeMessage( - generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver) + _generateReceiverMessage(SOURCE_CHAIN_SELECTOR), GAS_FOR_CALL_EXACT_CHECK, 100_000, address(s_receiver) ); } } diff --git a/contracts/src/v0.8/ccip/test/router/RouterSetup.t.sol b/contracts/src/v0.8/ccip/test/router/RouterSetup.t.sol index 423a47951d..7297721baa 100644 --- a/contracts/src/v0.8/ccip/test/router/RouterSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/router/RouterSetup.t.sol @@ -26,7 +26,7 @@ contract RouterSetup is BaseTest { } } - function generateReceiverMessage(uint64 chainSelector) internal pure returns (Client.Any2EVMMessage memory) { + function _generateReceiverMessage(uint64 chainSelector) internal pure returns (Client.Any2EVMMessage memory) { Client.EVMTokenAmount[] memory ta = new Client.EVMTokenAmount[](0); return Client.Any2EVMMessage({ messageId: bytes32("a"), @@ -37,7 +37,7 @@ contract RouterSetup is BaseTest { }); } - function generateSourceTokenData() internal pure returns (Internal.SourceTokenData memory) { + function _generateSourceTokenData() internal pure returns (Internal.SourceTokenData memory) { return Internal.SourceTokenData({ sourcePoolAddress: abi.encode(address(12312412312)), destTokenAddress: abi.encode(address(9809808909)), From 08cd77ded6a5204e75ce8c07209098ece79df4f0 Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Tue, 20 Aug 2024 11:59:54 +0200 Subject: [PATCH 217/432] fix stale comment (#1327) --- contracts/src/v0.8/ccip/libraries/Internal.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/src/v0.8/ccip/libraries/Internal.sol b/contracts/src/v0.8/ccip/libraries/Internal.sol index e13492acc9..bd1ee48d9a 100644 --- a/contracts/src/v0.8/ccip/libraries/Internal.sol +++ b/contracts/src/v0.8/ccip/libraries/Internal.sol @@ -67,7 +67,7 @@ library Internal { // CCIP_LOCK_OR_BURN_V1_RET_BYTES bytes. If more data is required, the TokenTransferFeeConfig.destBytesOverhead // has to be set for the specific token. bytes extraData; - uint32 destGasAmount; // The amount of gas available for the releaseOrMint and transfer calls on the offRamp + uint32 destGasAmount; // The amount of gas available for the releaseOrMint and balanceOf calls on the offRamp } /// @notice Report that is submitted by the execution DON at the execution phase. (including chain selector data) From e7341e0fc6ebb06b1671d2c4e86b36585197e47e Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Tue, 20 Aug 2024 17:19:14 +0200 Subject: [PATCH 218/432] Rename ramps and rmn (#1323) --- contracts/gas-snapshots/ccip.gas-snapshot | 348 ++--- contracts/package.json | 8 +- .../scripts/native_solc_compile_all_ccip | 6 +- .../{EVM2EVMMultiOffRamp.sol => OffRamp.sol} | 8 +- .../{EVM2EVMMultiOnRamp.sol => OnRamp.sol} | 8 +- .../src/v0.8/ccip/test/NonceManager.t.sol | 38 +- .../MultiOnRampTokenPoolReentrancy.t.sol | 12 +- .../v0.8/ccip/test/e2e/MultiRampsEnd2End.sol | 39 +- .../ccip/test/helpers/CCIPReaderTester.sol | 50 + ...ltiOffRampHelper.sol => OffRampHelper.sol} | 6 +- ...MultiOnRampHelper.sol => OnRampHelper.sol} | 6 +- .../v0.8/ccip/test/helpers/ReportCodec.sol | 8 +- .../receivers/ReentrancyAbuserMultiRamp.sol | 6 +- ...VM2EVMMultiOffRamp.t.sol => OffRamp.t.sol} | 690 +++++----- ...iOffRampSetup.t.sol => OffRampSetup.t.sol} | 62 +- ...{EVM2EVMMultiOnRamp.t.sol => OnRamp.t.sol} | 178 ++- ...ltiOnRampSetup.t.sol => OnRampSetup.t.sol} | 54 +- .../ccipreader/ccipreader_test.go | 8 +- .../ccip/ccip_integration_tests/helpers.go | 70 +- .../ccip_integration_tests/ocr3_node_test.go | 4 +- core/capabilities/ccip/ccipevm/commitcodec.go | 30 +- .../capabilities/ccip/ccipevm/executecodec.go | 24 +- core/capabilities/ccip/ccipevm/msghasher.go | 2 +- .../ccip/configs/evm/chain_writer.go | 6 +- .../ccip/configs/evm/contract_reader.go | 10 +- .../ccip_reader_tester/ccip_reader_tester.go | 78 +- .../mock_rmn_contract.go} | 356 +++--- .../offramp.go} | 1128 ++++++++--------- .../onramp.go} | 704 +++++----- .../generated/report_codec/report_codec.go | 48 +- .../rmn_contract.go} | 1100 ++++++++-------- .../rmn_proxy_contract.go} | 344 ++--- ...rapper-dependency-versions-do-not-edit.txt | 12 +- core/gethwrappers/ccip/go_generate.go | 8 +- core/scripts/ccip/liquiditymanager/util.go | 433 +++++++ .../ccip/revert-reason/handler/reason.go | 208 +++ .../ccipdata/commit_store_reader_test.go | 4 +- .../internal/ccipdata/offramp_reader_test.go | 4 +- .../ccip/internal/ccipdata/v1_0_0/onramp.go | 11 +- .../ccip/internal/ccipdata/v1_2_0/onramp.go | 11 +- .../ccip/internal/ccipdata/v1_5_0/onramp.go | 10 +- .../internal/ccipdata/v1_5_0/onramp_test.go | 8 +- .../ccip/testhelpers/ccip_contracts.go | 24 +- .../testhelpers_1_4_0/ccip_contracts_1_4_0.go | 24 +- .../internal/integration_test.go | 12 +- .../ccip-tests/actions/ccip_helpers.go | 46 +- .../ccip-tests/contracts/contract_deployer.go | 12 +- .../ccip-tests/contracts/contract_models.go | 8 +- .../ccip-tests/contracts/lm_contracts.go | 320 +++++ .../ccip-tests/testsetups/lm_setup.go | 845 ++++++++++++ integration-tests/deployment/ccip/deploy.go | 140 +- .../deployment/ccip/deploy_home_chain.go | 8 +- .../ccip/migrations/1_initial_deploy_test.go | 8 +- integration-tests/deployment/ccip/state.go | 76 +- 54 files changed, 4703 insertions(+), 2968 deletions(-) rename contracts/src/v0.8/ccip/offRamp/{EVM2EVMMultiOffRamp.sol => OffRamp.sol} (99%) rename contracts/src/v0.8/ccip/onRamp/{EVM2EVMMultiOnRamp.sol => OnRamp.sol} (97%) create mode 100644 contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol rename contracts/src/v0.8/ccip/test/helpers/{EVM2EVMMultiOffRampHelper.sol => OffRampHelper.sol} (93%) rename contracts/src/v0.8/ccip/test/helpers/{EVM2EVMMultiOnRampHelper.sol => OnRampHelper.sol} (57%) rename contracts/src/v0.8/ccip/test/offRamp/{EVM2EVMMultiOffRamp.t.sol => OffRamp.t.sol} (81%) rename contracts/src/v0.8/ccip/test/offRamp/{EVM2EVMMultiOffRampSetup.t.sol => OffRampSetup.t.sol} (90%) rename contracts/src/v0.8/ccip/test/onRamp/{EVM2EVMMultiOnRamp.t.sol => OnRamp.t.sol} (79%) rename contracts/src/v0.8/ccip/test/onRamp/{EVM2EVMMultiOnRampSetup.t.sol => OnRampSetup.t.sol} (75%) rename core/gethwrappers/ccip/generated/{mock_arm_contract/mock_arm_contract.go => mock_rmn_contract/mock_rmn_contract.go} (68%) rename core/gethwrappers/ccip/generated/{evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go => offramp/offramp.go} (54%) rename core/gethwrappers/ccip/generated/{evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go => onramp/onramp.go} (52%) rename core/gethwrappers/ccip/generated/{arm_contract/arm_contract.go => rmn_contract/rmn_contract.go} (75%) rename core/gethwrappers/ccip/generated/{arm_proxy_contract/arm_proxy_contract.go => rmn_proxy_contract/rmn_proxy_contract.go} (60%) create mode 100644 core/scripts/ccip/liquiditymanager/util.go create mode 100644 core/scripts/ccip/revert-reason/handler/reason.go create mode 100644 integration-tests/ccip-tests/contracts/lm_contracts.go create mode 100644 integration-tests/ccip-tests/testsetups/lm_setup.go diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index f9c7b93aa7..7e79a922d3 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -124,180 +124,6 @@ CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424256) E2E:test_E2E_3MessagesSuccess_gas() (gas: 1104303) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38408) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 106250) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 87409) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 38954) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 96511) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 41956) -EVM2EVMMultiOffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 88684) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 468115) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99227) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12395) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 93181) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 109890) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13263) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17988) -EVM2EVMMultiOffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15343) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 313594) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 254984) -EVM2EVMMultiOffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 166123) -EVM2EVMMultiOffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187729) -EVM2EVMMultiOffRamp_batchExecute:test_SingleReport_Success() (gas: 153140) -EVM2EVMMultiOffRamp_batchExecute:test_Unhealthy_Revert() (gas: 518887) -EVM2EVMMultiOffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10439) -EVM2EVMMultiOffRamp_ccipReceive:test_Reverts() (gas: 15684) -EVM2EVMMultiOffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67458) -EVM2EVMMultiOffRamp_commit:test_InvalidInterval_Revert() (gas: 59734) -EVM2EVMMultiOffRamp_commit:test_InvalidRootRevert() (gas: 58814) -EVM2EVMMultiOffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6538150) -EVM2EVMMultiOffRamp_commit:test_NoConfig_Revert() (gas: 6121222) -EVM2EVMMultiOffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106251) -EVM2EVMMultiOffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116259) -EVM2EVMMultiOffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106272) -EVM2EVMMultiOffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351586) -EVM2EVMMultiOffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159364) -EVM2EVMMultiOffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136569) -EVM2EVMMultiOffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136859) -EVM2EVMMultiOffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 59082) -EVM2EVMMultiOffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225772) -EVM2EVMMultiOffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117566) -EVM2EVMMultiOffRamp_commit:test_Unhealthy_Revert() (gas: 77608) -EVM2EVMMultiOffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 205117) -EVM2EVMMultiOffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6532473) -EVM2EVMMultiOffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47788) -EVM2EVMMultiOffRamp_constructor:test_Constructor_Success() (gas: 6125436) -EVM2EVMMultiOffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137067) -EVM2EVMMultiOffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103784) -EVM2EVMMultiOffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101677) -EVM2EVMMultiOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139641) -EVM2EVMMultiOffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101554) -EVM2EVMMultiOffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101599) -EVM2EVMMultiOffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17261) -EVM2EVMMultiOffRamp_execute:test_LargeBatch_Success() (gas: 1726826) -EVM2EVMMultiOffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 349476) -EVM2EVMMultiOffRamp_execute:test_MultipleReports_Success() (gas: 276933) -EVM2EVMMultiOffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6588848) -EVM2EVMMultiOffRamp_execute:test_NoConfig_Revert() (gas: 6171682) -EVM2EVMMultiOffRamp_execute:test_NonArray_Revert() (gas: 27733) -EVM2EVMMultiOffRamp_execute:test_SingleReport_Success() (gas: 172458) -EVM2EVMMultiOffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147390) -EVM2EVMMultiOffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6950922) -EVM2EVMMultiOffRamp_execute:test_ZeroReports_Revert() (gas: 17159) -EVM2EVMMultiOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18190) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 246556) -EVM2EVMMultiOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20472) -EVM2EVMMultiOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 205195) -EVM2EVMMultiOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48734) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48257) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229631) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86202) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 277436) -EVM2EVMMultiOffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92436) -EVM2EVMMultiOffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35126) -EVM2EVMMultiOffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23922) -EVM2EVMMultiOffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 475599) -EVM2EVMMultiOffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54456) -EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35904) -EVM2EVMMultiOffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154426) -EVM2EVMMultiOffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35337) -EVM2EVMMultiOffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 184865) -EVM2EVMMultiOffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 196122) -EVM2EVMMultiOffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48073) -EVM2EVMMultiOffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 444686) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 250335) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 187191) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 206771) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 263519) -EVM2EVMMultiOffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 138408) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 409328) -EVM2EVMMultiOffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65876) -EVM2EVMMultiOffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80909) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 566299) -EVM2EVMMultiOffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 517689) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35742) -EVM2EVMMultiOffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 517721) -EVM2EVMMultiOffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 515089) -EVM2EVMMultiOffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 485207) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 133513) -EVM2EVMMultiOffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 162713) -EVM2EVMMultiOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3674540) -EVM2EVMMultiOffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118375) -EVM2EVMMultiOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87586) -EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75635) -EVM2EVMMultiOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26471) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 168604) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205435) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26014) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152948) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 518487) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2295740) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 208322) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 208944) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 662979) -EVM2EVMMultiOffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 301931) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 164042) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 23736) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 64484) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 39516) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 81512) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 176140) -EVM2EVMMultiOffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 189342) -EVM2EVMMultiOffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11379) -EVM2EVMMultiOffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215398) -EVM2EVMMultiOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14140) -EVM2EVMMultiOffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11660) -EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49203) -EVM2EVMMultiOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27147) -EVM2EVMMultiOffRamp_trialExecute:test_RateLimitError_Success() (gas: 221780) -EVM2EVMMultiOffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 230403) -EVM2EVMMultiOffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 297574) -EVM2EVMMultiOffRamp_trialExecute:test_trialExecute_Success() (gas: 279978) -EVM2EVMMultiOffRamp_verify:test_Blessed_Success() (gas: 176620) -EVM2EVMMultiOffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178688) -EVM2EVMMultiOffRamp_verify:test_NotBlessed_Success() (gas: 141549) -EVM2EVMMultiOffRamp_verify:test_TooManyLeaves_Revert() (gas: 51510) -EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 63649) -EVM2EVMMultiOnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() (gas: 13308) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94175) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92092) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97113) -EVM2EVMMultiOnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92150) -EVM2EVMMultiOnRamp_constructor:test_Constructor_Success() (gas: 2384439) -EVM2EVMMultiOnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 71918) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 111914) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 142684) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 142260) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 140437) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 142490) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 141859) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 134347) -EVM2EVMMultiOnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 26294) -EVM2EVMMultiOnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 133253) -EVM2EVMMultiOnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 24360) -EVM2EVMMultiOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12872) -EVM2EVMMultiOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 32033) -EVM2EVMMultiOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 15762) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179401) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 205670) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 121815) -EVM2EVMMultiOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 143193) -EVM2EVMMultiOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3872608) -EVM2EVMMultiOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108546) -EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 73975) -EVM2EVMMultiOnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 262685) -EVM2EVMMultiOnRamp_getFee:test_EmptyMessage_Success() (gas: 104467) -EVM2EVMMultiOnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 74075) -EVM2EVMMultiOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119799) -EVM2EVMMultiOnRamp_getFee:test_Unhealthy_Revert() (gas: 43679) -EVM2EVMMultiOnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10438) -EVM2EVMMultiOnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35270) -EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11155) -EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() (gas: 12740) -EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11112) -EVM2EVMMultiOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939) -EVM2EVMMultiOnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 51996) -EVM2EVMMultiOnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97214) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37797) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103733) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85258) @@ -661,7 +487,181 @@ OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51686) OCR2Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 23484) OCR2Base_transmit:test_UnauthorizedSigner_Revert() (gas: 39665) OCR2Base_transmit:test_WrongNumberOfSignatures_Revert() (gas: 20557) +OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38408) +OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 106250) +OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 87409) +OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 38954) +OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 96511) +OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 41956) +OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 88684) +OffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 468115) +OffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99227) +OffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12395) +OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 93181) +OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 109890) +OffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13263) +OffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17988) +OffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15343) +OffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 313594) +OffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 254984) +OffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 166123) +OffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187729) +OffRamp_batchExecute:test_SingleReport_Success() (gas: 153140) +OffRamp_batchExecute:test_Unhealthy_Revert() (gas: 518887) +OffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10439) +OffRamp_ccipReceive:test_Reverts() (gas: 15684) +OffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67458) +OffRamp_commit:test_InvalidInterval_Revert() (gas: 59734) +OffRamp_commit:test_InvalidRootRevert() (gas: 58814) +OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6538150) +OffRamp_commit:test_NoConfig_Revert() (gas: 6121222) +OffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106251) +OffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116259) +OffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106272) +OffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351586) +OffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159364) +OffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136569) +OffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136859) +OffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 59082) +OffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225772) +OffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117566) +OffRamp_commit:test_Unhealthy_Revert() (gas: 77608) +OffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 205117) +OffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6532473) +OffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47788) +OffRamp_constructor:test_Constructor_Success() (gas: 6125436) +OffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137067) +OffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103784) +OffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101677) +OffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139641) +OffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101554) +OffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101599) +OffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17261) +OffRamp_execute:test_LargeBatch_Success() (gas: 1726826) +OffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 349476) +OffRamp_execute:test_MultipleReports_Success() (gas: 276933) +OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6588848) +OffRamp_execute:test_NoConfig_Revert() (gas: 6171682) +OffRamp_execute:test_NonArray_Revert() (gas: 27733) +OffRamp_execute:test_SingleReport_Success() (gas: 172458) +OffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147390) +OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6950922) +OffRamp_execute:test_ZeroReports_Revert() (gas: 17159) +OffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18190) +OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 246556) +OffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20472) +OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 205195) +OffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48734) +OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48257) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229631) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86202) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 277436) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92436) +OffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35126) +OffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23922) +OffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 475599) +OffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54456) +OffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35904) +OffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154426) +OffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35337) +OffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 184865) +OffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 196122) +OffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48073) +OffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 444686) +OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 250335) +OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 187191) +OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 206771) +OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 263519) +OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 138408) +OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 409328) +OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65876) +OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80909) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 566299) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 517689) +OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35742) +OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 517721) +OffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 515089) +OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 485207) +OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 133513) +OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 162713) +OffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3674540) +OffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118375) +OffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87586) +OffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75635) +OffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26471) +OffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 168604) +OffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205435) +OffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26014) +OffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152948) +OffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 518487) +OffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2295740) +OffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 208322) +OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 208944) +OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 662979) +OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 301931) +OffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 164042) +OffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 23736) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 64484) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 39516) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 81512) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 176140) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 189342) +OffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11379) +OffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215398) +OffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14140) +OffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11660) +OffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49203) +OffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27147) +OffRamp_trialExecute:test_RateLimitError_Success() (gas: 221780) +OffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 230403) +OffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 297574) +OffRamp_trialExecute:test_trialExecute_Success() (gas: 279978) +OffRamp_verify:test_Blessed_Success() (gas: 176620) +OffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178688) +OffRamp_verify:test_NotBlessed_Success() (gas: 141549) +OffRamp_verify:test_TooManyLeaves_Revert() (gas: 51510) OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 390410) +OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 63649) +OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() (gas: 13308) +OnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94175) +OnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92092) +OnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97113) +OnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92150) +OnRamp_constructor:test_Constructor_Success() (gas: 2384439) +OnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 71918) +OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 111914) +OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 142684) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 142260) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 140437) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 142490) +OnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 141859) +OnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 134347) +OnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 26294) +OnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 133253) +OnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 24360) +OnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12872) +OnRamp_forwardFromRouter:test_Paused_Revert() (gas: 32033) +OnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 15762) +OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179401) +OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 205670) +OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 121815) +OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 143193) +OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3872608) +OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108546) +OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 73975) +OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 262685) +OnRamp_getFee:test_EmptyMessage_Success() (gas: 104467) +OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 74075) +OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119799) +OnRamp_getFee:test_Unhealthy_Revert() (gas: 43679) +OnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10438) +OnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35270) +OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11155) +OnRamp_setDynamicConfig:test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() (gas: 12740) +OnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11112) +OnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939) +OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 51996) +OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97214) PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150175) PingPong_plumbing:test_OutOfOrderExecution_Success() (gas: 20277) PingPong_plumbing:test_Pausing_Success() (gas: 17777) diff --git a/contracts/package.json b/contracts/package.json index 78f4cf36b8..334b75701c 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -53,8 +53,12 @@ "!src/v0.8/ccip/test/**/*", "src/v0.8/ccip/test/mocks/**/*", "!src/v0.8/ccip/test/mocks/test/*", - "!src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol", - "!src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol" + "!src/v0.8/ccip/onRamp/OnRamp.sol", + "!src/v0.8/ccip/offRamp/OffRamp.sol", + "!src/v0.8/ccip/ocr/MultiOCR3Base.sol", + "!src/v0.8/ccip/NonceManager.sol", + "!src/v0.8/ccip/MultiAggregateRateLimiter.sol", + "!src/v0.8/ccip/capability" ], "pnpm": { "_comment": "See https://github.com/ethers-io/ethers.js/discussions/2849#discussioncomment-2696454", diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index 0af6d84400..885b701279 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -32,7 +32,7 @@ compileContract () { echo "OffRamp uses $OPTIMIZE_RUNS_OFFRAMP optimizer runs." optimize_runs=$OPTIMIZE_RUNS_OFFRAMP ;; - "ccip/offRamp/EVM2EVMMultiOffRamp.sol") + "ccip/offRamp/OffRamp.sol") echo "MultiOffRamp uses $OPTIMIZE_RUNS_MULTI_OFFRAMP optimizer runs." optimize_runs=$OPTIMIZE_RUNS_MULTI_OFFRAMP ;; @@ -53,11 +53,11 @@ compileContract () { # Solc produces and overwrites intermediary contracts. # Contracts should be ordered in reverse-import-complexity-order to minimize overwrite risks. compileContract ccip/offRamp/EVM2EVMOffRamp.sol -compileContract ccip/offRamp/EVM2EVMMultiOffRamp.sol +compileContract ccip/offRamp/OffRamp.sol compileContract ccip/applications/PingPongDemo.sol compileContract ccip/applications/SelfFundedPingPong.sol compileContract ccip/applications/EtherSenderReceiver.sol -compileContract ccip/onRamp/EVM2EVMMultiOnRamp.sol +compileContract ccip/onRamp/OnRamp.sol compileContract ccip/onRamp/EVM2EVMOnRamp.sol compileContract ccip/CommitStore.sol compileContract ccip/MultiAggregateRateLimiter.sol diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol similarity index 99% rename from contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol rename to contracts/src/v0.8/ccip/offRamp/OffRamp.sol index 6a6fb10be1..de03e5fac7 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMMultiOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol @@ -22,14 +22,14 @@ import {MultiOCR3Base} from "../ocr/MultiOCR3Base.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/IERC20.sol"; import {ERC165Checker} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/ERC165Checker.sol"; -/// @notice EVM2EVMOffRamp enables OCR networks to execute multiple messages +/// @notice OffRamp enables OCR networks to execute multiple messages /// in an OffRamp in a single transaction. -/// @dev The EVM2EVMMultiOnRamp and EVM2EVMMultiOffRamp form an xchain upgradeable unit. Any change to one of them +/// @dev The OnRamp and OffRamp form an xchain upgradeable unit. Any change to one of them /// results an onchain upgrade of both contracts. /// @dev MultiOCR3Base is used to store multiple OCR configs for both the OffRamp and the CommitStore. /// The execution plugin type has to be configured without signature verification, and the commit /// plugin type with verification. -contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { +contract OffRamp is ITypeAndVersion, MultiOCR3Base { using ERC165Checker for address; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; @@ -142,7 +142,7 @@ contract EVM2EVMMultiOffRamp is ITypeAndVersion, MultiOCR3Base { } // STATIC CONFIG - string public constant override typeAndVersion = "EVM2EVMMultiOffRamp 1.6.0-dev"; + string public constant override typeAndVersion = "OffRamp 1.6.0-dev"; /// @dev ChainSelector of this chain uint64 internal immutable i_chainSelector; /// @dev The address of the RMN proxy diff --git a/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol similarity index 97% rename from contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol rename to contracts/src/v0.8/ccip/onRamp/OnRamp.sol index 10a5c5876e..60d41894fa 100644 --- a/contracts/src/v0.8/ccip/onRamp/EVM2EVMMultiOnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol @@ -20,10 +20,10 @@ import {USDPriceWith18Decimals} from "../libraries/USDPriceWith18Decimals.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; -/// @notice The EVM2EVMMultiOnRamp is a contract that handles lane-specific fee logic -/// @dev The EVM2EVMMultiOnRamp, MultiCommitStore and EVM2EVMMultiOffRamp form an xchain upgradeable unit. Any change to one of them +/// @notice The OnRamp is a contract that handles lane-specific fee logic +/// @dev The OnRamp, MultiCommitStore and OffRamp form an xchain upgradeable unit. Any change to one of them /// results an onchain upgrade of all 3. -contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { +contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { using SafeERC20 for IERC20; using USDPriceWith18Decimals for uint224; @@ -80,7 +80,7 @@ contract EVM2EVMMultiOnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCre } // STATIC CONFIG - string public constant override typeAndVersion = "EVM2EVMMultiOnRamp 1.6.0-dev"; + string public constant override typeAndVersion = "OnRamp 1.6.0-dev"; /// @dev The chain ID of the source chain that this contract is deployed to uint64 internal immutable i_chainSelector; /// @dev The address of the rmn proxy diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol index bcf8c9328b..3811f0d3c6 100644 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -7,16 +7,15 @@ import {Client} from "../libraries/Client.sol"; import {Internal} from "../libraries/Internal.sol"; import {Pool} from "../libraries/Pool.sol"; import {RateLimiter} from "../libraries/RateLimiter.sol"; -import {EVM2EVMMultiOffRamp} from "../offRamp/EVM2EVMMultiOffRamp.sol"; -import {EVM2EVMMultiOnRamp} from "../onRamp/EVM2EVMMultiOnRamp.sol"; +import {OffRamp} from "../offRamp/OffRamp.sol"; import {EVM2EVMOnRamp} from "../onRamp/EVM2EVMOnRamp.sol"; - +import {OnRamp} from "../onRamp/OnRamp.sol"; import {BaseTest} from "./BaseTest.t.sol"; import {EVM2EVMOffRampHelper} from "./helpers/EVM2EVMOffRampHelper.sol"; import {EVM2EVMOnRampHelper} from "./helpers/EVM2EVMOnRampHelper.sol"; import {MockCommitStore} from "./mocks/MockCommitStore.sol"; -import {EVM2EVMMultiOffRampSetup} from "./offRamp/EVM2EVMMultiOffRampSetup.t.sol"; -import {EVM2EVMMultiOnRampSetup} from "./onRamp/EVM2EVMMultiOnRampSetup.t.sol"; +import {OffRampSetup} from "./offRamp/OffRampSetup.t.sol"; +import {OnRampSetup} from "./onRamp/OnRampSetup.t.sol"; import {Test} from "forge-std/Test.sol"; contract NonceManager_typeAndVersion is Test { @@ -87,7 +86,7 @@ contract NonceManager_NonceIncrementation is BaseTest { } } -contract NonceManager_applyPreviousRampsUpdates is EVM2EVMMultiOnRampSetup { +contract NonceManager_applyPreviousRampsUpdates is OnRampSetup { function test_SingleRampUpdate() public { address prevOnRamp = makeAddr("prevOnRamp"); address prevOffRamp = makeAddr("prevOffRamp"); @@ -189,7 +188,7 @@ contract NonceManager_applyPreviousRampsUpdates is EVM2EVMMultiOnRampSetup { } } -contract NonceManager_OnRampUpgrade is EVM2EVMMultiOnRampSetup { +contract NonceManager_OnRampUpgrade is OnRampSetup { uint256 internal constant FEE_AMOUNT = 1234567890; EVM2EVMOnRampHelper internal s_prevOnRamp; @@ -266,7 +265,7 @@ contract NonceManager_OnRampUpgrade is EVM2EVMMultiOnRampSetup { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, OWNER)); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); } @@ -293,18 +292,14 @@ contract NonceManager_OnRampUpgrade is EVM2EVMMultiOnRampSetup { // new onramp nonce should start from 2, while sequence number start from 1 vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested( - DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, startNonce + 2, FEE_AMOUNT, OWNER) - ); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, startNonce + 2, FEE_AMOUNT, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); assertEq(startNonce + 2, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); // after another send, nonce should be 3, and sequence number be 2 vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested( - DEST_CHAIN_SELECTOR, _messageToEvent(message, 2, startNonce + 3, FEE_AMOUNT, OWNER) - ); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 2, startNonce + 3, FEE_AMOUNT, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); assertEq(startNonce + 3, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); @@ -319,14 +314,12 @@ contract NonceManager_OnRampUpgrade is EVM2EVMMultiOnRampSetup { address newSender = address(1234567); // new onramp nonce should start from 1 for new sender vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested( - DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, newSender) - ); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, newSender)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, newSender); } } -contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { +contract NonceManager_OffRampUpgrade is OffRampSetup { EVM2EVMOffRampHelper internal s_prevOffRamp; EVM2EVMOffRampHelper[] internal s_nestedPrevOffRamps; @@ -366,21 +359,20 @@ contract NonceManager_OffRampUpgrade is EVM2EVMMultiOffRampSetup { ); s_inboundNonceManager.applyPreviousRampsUpdates(previousRamps); - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](3); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](3); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, isEnabled: true, onRamp: ON_RAMP_ADDRESS_1 }); - sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainConfigs[1] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_2, isEnabled: true, onRamp: ON_RAMP_ADDRESS_2 }); - sourceChainConfigs[2] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainConfigs[2] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_3, isEnabled: true, diff --git a/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol b/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol index d31cd35016..0eea71eacc 100644 --- a/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol +++ b/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol @@ -3,9 +3,9 @@ pragma solidity 0.8.24; import {Client} from "../../../libraries/Client.sol"; import {Internal} from "../../../libraries/Internal.sol"; -import {EVM2EVMMultiOnRamp} from "../../../onRamp/EVM2EVMMultiOnRamp.sol"; +import {OnRamp} from "../../../onRamp/OnRamp.sol"; import {TokenPool} from "../../../pools/TokenPool.sol"; -import {EVM2EVMMultiOnRampSetup} from "../../onRamp/EVM2EVMMultiOnRampSetup.t.sol"; +import {OnRampSetup} from "../../onRamp/OnRampSetup.t.sol"; import {FacadeClient} from "./FacadeClient.sol"; import {ReentrantMaliciousTokenPool} from "./ReentrantMaliciousTokenPool.sol"; @@ -13,7 +13,7 @@ import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/ /// @title MultiOnRampTokenPoolReentrancy /// Attempts to perform a reentrancy exploit on Onramp with a malicious TokenPool -contract MultiOnRampTokenPoolReentrancy is EVM2EVMMultiOnRampSetup { +contract MultiOnRampTokenPoolReentrancy is OnRampSetup { FacadeClient internal s_facadeClient; ReentrantMaliciousTokenPool internal s_maliciousTokenPool; IERC20 internal s_sourceToken; @@ -21,7 +21,7 @@ contract MultiOnRampTokenPoolReentrancy is EVM2EVMMultiOnRampSetup { address internal immutable i_receiver = makeAddr("receiver"); function setUp() public virtual override { - EVM2EVMMultiOnRampSetup.setUp(); + OnRampSetup.setUp(); s_sourceToken = IERC20(s_sourceTokens[0]); s_feeToken = IERC20(s_sourceTokens[0]); @@ -107,9 +107,9 @@ contract MultiOnRampTokenPoolReentrancy is EVM2EVMMultiOnRampSetup { Internal.EVM2AnyRampMessage memory msgEvent2 = _messageToEvent(message2, 2, 2, expectedFee, address(s_facadeClient)); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, msgEvent2); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, msgEvent2); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, msgEvent1); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, msgEvent1); s_facadeClient.send(amount); } diff --git a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol index 9116c79b9e..5ad0091734 100644 --- a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol +++ b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol @@ -6,19 +6,19 @@ import {NonceManager} from "../../NonceManager.sol"; import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; import "../helpers/MerkleHelper.sol"; -import "../offRamp/EVM2EVMMultiOffRampSetup.t.sol"; -import "../onRamp/EVM2EVMMultiOnRampSetup.t.sol"; +import "../offRamp/OffRampSetup.t.sol"; +import "../onRamp/OnRampSetup.t.sol"; /// @notice This E2E test implements the following scenario: /// 1. Send multiple messages from multiple source chains to a single destination chain (2 messages from source chain 1 and 1 from /// source chain 2). /// 2. Commit multiple merkle roots (1 for each source chain). /// 3. Batch execute all the committed messages. -contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { +contract MultiRampsE2E is OnRampSetup, OffRampSetup { using Internal for Internal.Any2EVMRampMessage; Router internal s_sourceRouter2; - EVM2EVMMultiOnRampHelper internal s_onRamp2; + OnRampHelper internal s_onRamp2; TokenAdminRegistry internal s_tokenAdminRegistry2; NonceManager internal s_nonceManager2; @@ -26,9 +26,9 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { mapping(address destPool => address sourcePool) internal s_sourcePoolByDestPool; - function setUp() public virtual override(EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup) { - EVM2EVMMultiOnRampSetup.setUp(); - EVM2EVMMultiOffRampSetup.setUp(); + function setUp() public virtual override(OnRampSetup, OffRampSetup) { + OnRampSetup.setUp(); + OffRampSetup.setUp(); // Deploy new source router for the new source chain s_sourceRouter2 = new Router(s_sourceRouter.getWrappedNative(), address(s_mockRMN)); @@ -63,7 +63,7 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { ( // Deploy the new source chain onramp - // Outsource to shared helper function with EVM2EVMMultiOnRampSetup + // Outsource to shared helper function with OnRampSetup s_onRamp2, s_metadataHash2 ) = _deployOnRamp( @@ -85,16 +85,15 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { _deployOffRamp(s_mockRMN, s_inboundNonceManager); // Enable source chains on offramp - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](2); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](2); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR, isEnabled: true, // Must match OnRamp address onRamp: abi.encode(address(s_onRamp)) }); - sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainConfigs[1] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR + 1, isEnabled: true, @@ -137,20 +136,20 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { merkleRoots[0] = MerkleHelper.getMerkleRoot(hashedMessages1); merkleRoots[1] = MerkleHelper.getMerkleRoot(hashedMessages2); - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](2); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](2); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: EVM2EVMMultiOffRamp.Interval(messages1[0].header.sequenceNumber, messages1[1].header.sequenceNumber), + interval: OffRamp.Interval(messages1[0].header.sequenceNumber, messages1[1].header.sequenceNumber), merkleRoot: merkleRoots[0] }); - roots[1] = EVM2EVMMultiOffRamp.MerkleRoot({ + roots[1] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR + 1, - interval: EVM2EVMMultiOffRamp.Interval(messages2[0].header.sequenceNumber, messages2[0].header.sequenceNumber), + interval: OffRamp.Interval(messages2[0].header.sequenceNumber, messages2[0].header.sequenceNumber), merkleRoot: merkleRoots[1] }); - EVM2EVMMultiOffRamp.CommitReport memory report = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport memory report = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); vm.resumeGasMetering(); _commit(report, ++s_latestSequenceNumber); @@ -235,7 +234,7 @@ contract MultiRampsE2E is EVM2EVMMultiOnRampSetup, EVM2EVMMultiOffRampSetup { ); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, msgEvent); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, msgEvent); vm.resumeGasMetering(); router.ccipSend(DEST_CHAIN_SELECTOR, message); diff --git a/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol b/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol new file mode 100644 index 0000000000..707d38ddf2 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {Internal} from "../../libraries/Internal.sol"; +import {OffRamp} from "../../offRamp/OffRamp.sol"; + +contract CCIPReaderTester { + event CCIPSendRequested(uint64 indexed destChainSelector, Internal.EVM2AnyRampMessage message); + + mapping(uint64 sourceChainSelector => OffRamp.SourceChainConfig sourceChainConfig) internal s_sourceChainConfigs; + + function getSourceChainConfig(uint64 sourceChainSelector) external view returns (OffRamp.SourceChainConfig memory) { + return s_sourceChainConfigs[sourceChainSelector]; + } + + function setSourceChainConfig( + uint64 sourceChainSelector, + OffRamp.SourceChainConfig memory sourceChainConfig + ) external { + s_sourceChainConfigs[sourceChainSelector] = sourceChainConfig; + } + + function emitCCIPSendRequested(uint64 destChainSelector, Internal.EVM2AnyRampMessage memory message) external { + emit CCIPSendRequested(destChainSelector, message); + } + + event ExecutionStateChanged( + uint64 indexed sourceChainSelector, + uint64 indexed sequenceNumber, + bytes32 indexed messageId, + Internal.MessageExecutionState state, + bytes returnData + ); + + function emitExecutionStateChanged( + uint64 sourceChainSelector, + uint64 sequenceNumber, + bytes32 messageId, + Internal.MessageExecutionState state, + bytes memory returnData + ) external { + emit ExecutionStateChanged(sourceChainSelector, sequenceNumber, messageId, state, returnData); + } + + event CommitReportAccepted(OffRamp.CommitReport report); + + function emitCommitReportAccepted(OffRamp.CommitReport memory report) external { + emit CommitReportAccepted(report); + } +} diff --git a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol b/contracts/src/v0.8/ccip/test/helpers/OffRampHelper.sol similarity index 93% rename from contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol rename to contracts/src/v0.8/ccip/test/helpers/OffRampHelper.sol index f966e04462..e5cf6332d9 100644 --- a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOffRampHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/OffRampHelper.sol @@ -3,17 +3,17 @@ pragma solidity 0.8.24; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; -import {EVM2EVMMultiOffRamp} from "../../offRamp/EVM2EVMMultiOffRamp.sol"; +import {OffRamp} from "../../offRamp/OffRamp.sol"; import {IgnoreContractSize} from "./IgnoreContractSize.sol"; -contract EVM2EVMMultiOffRampHelper is EVM2EVMMultiOffRamp, IgnoreContractSize { +contract OffRampHelper is OffRamp, IgnoreContractSize { mapping(uint64 sourceChainSelector => uint256 overrideTimestamp) private s_sourceChainVerificationOverride; constructor( StaticConfig memory staticConfig, DynamicConfig memory dynamicConfig, SourceChainConfigArgs[] memory sourceChainConfigs - ) EVM2EVMMultiOffRamp(staticConfig, dynamicConfig, sourceChainConfigs) {} + ) OffRamp(staticConfig, dynamicConfig, sourceChainConfigs) {} function setExecutionStateHelper( uint64 sourceChainSelector, diff --git a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOnRampHelper.sol b/contracts/src/v0.8/ccip/test/helpers/OnRampHelper.sol similarity index 57% rename from contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOnRampHelper.sol rename to contracts/src/v0.8/ccip/test/helpers/OnRampHelper.sol index 88992a8749..57397f040a 100644 --- a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMMultiOnRampHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/OnRampHelper.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import "../../onRamp/EVM2EVMMultiOnRamp.sol"; +import "../../onRamp/OnRamp.sol"; import {IgnoreContractSize} from "./IgnoreContractSize.sol"; -contract EVM2EVMMultiOnRampHelper is EVM2EVMMultiOnRamp, IgnoreContractSize { +contract OnRampHelper is OnRamp, IgnoreContractSize { constructor( StaticConfig memory staticConfig, DynamicConfig memory dynamicConfig, DestChainConfigArgs[] memory destChainConfigArgs - ) EVM2EVMMultiOnRamp(staticConfig, dynamicConfig, destChainConfigArgs) {} + ) OnRamp(staticConfig, dynamicConfig, destChainConfigArgs) {} } diff --git a/contracts/src/v0.8/ccip/test/helpers/ReportCodec.sol b/contracts/src/v0.8/ccip/test/helpers/ReportCodec.sol index ca53d512c0..73962fb91f 100644 --- a/contracts/src/v0.8/ccip/test/helpers/ReportCodec.sol +++ b/contracts/src/v0.8/ccip/test/helpers/ReportCodec.sol @@ -2,17 +2,17 @@ pragma solidity ^0.8.0; import {Internal} from "../../libraries/Internal.sol"; -import {EVM2EVMMultiOffRamp} from "../../offRamp/EVM2EVMMultiOffRamp.sol"; +import {OffRamp} from "../../offRamp/OffRamp.sol"; contract ReportCodec { event ExecuteReportDecoded(Internal.ExecutionReportSingleChain[] report); - event CommitReportDecoded(EVM2EVMMultiOffRamp.CommitReport report); + event CommitReportDecoded(OffRamp.CommitReport report); function decodeExecuteReport(bytes memory report) public pure returns (Internal.ExecutionReportSingleChain[] memory) { return abi.decode(report, (Internal.ExecutionReportSingleChain[])); } - function decodeCommitReport(bytes memory report) public pure returns (EVM2EVMMultiOffRamp.CommitReport memory) { - return abi.decode(report, (EVM2EVMMultiOffRamp.CommitReport)); + function decodeCommitReport(bytes memory report) public pure returns (OffRamp.CommitReport memory) { + return abi.decode(report, (OffRamp.CommitReport)); } } diff --git a/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuserMultiRamp.sol b/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuserMultiRamp.sol index c9e7d7e8ad..667fbc13e5 100644 --- a/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuserMultiRamp.sol +++ b/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuserMultiRamp.sol @@ -4,16 +4,16 @@ pragma solidity ^0.8.19; import {CCIPReceiver} from "../../../applications/CCIPReceiver.sol"; import {Client} from "../../../libraries/Client.sol"; import {Internal} from "../../../libraries/Internal.sol"; -import {EVM2EVMMultiOffRamp} from "../../../offRamp/EVM2EVMMultiOffRamp.sol"; +import {OffRamp} from "../../../offRamp/OffRamp.sol"; contract ReentrancyAbuserMultiRamp is CCIPReceiver { event ReentrancySucceeded(); bool internal s_ReentrancyDone = false; Internal.ExecutionReportSingleChain internal s_payload; - EVM2EVMMultiOffRamp internal s_offRamp; + OffRamp internal s_offRamp; - constructor(address router, EVM2EVMMultiOffRamp offRamp) CCIPReceiver(router) { + constructor(address router, OffRamp offRamp) CCIPReceiver(router) { s_offRamp = offRamp; } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol similarity index 81% rename from contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol rename to contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol index 3acc1adae0..0df9859269 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol @@ -16,54 +16,52 @@ import {MerkleMultiProof} from "../../libraries/MerkleMultiProof.sol"; import {Pool} from "../../libraries/Pool.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {MultiOCR3Base} from "../../ocr/MultiOCR3Base.sol"; -import {EVM2EVMMultiOffRamp} from "../../offRamp/EVM2EVMMultiOffRamp.sol"; +import {OffRamp} from "../../offRamp/OffRamp.sol"; import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; -import {EVM2EVMMultiOffRampHelper} from "../helpers/EVM2EVMMultiOffRampHelper.sol"; import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; +import {OffRampHelper} from "../helpers/OffRampHelper.sol"; import {ConformingReceiver} from "../helpers/receivers/ConformingReceiver.sol"; import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; import {MaybeRevertMessageReceiverNo165} from "../helpers/receivers/MaybeRevertMessageReceiverNo165.sol"; import {ReentrancyAbuserMultiRamp} from "../helpers/receivers/ReentrancyAbuserMultiRamp.sol"; -import {EVM2EVMMultiOffRampSetup} from "./EVM2EVMMultiOffRampSetup.t.sol"; +import {OffRampSetup} from "./OffRampSetup.t.sol"; import {Vm} from "forge-std/Vm.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { +contract OffRamp_constructor is OffRampSetup { function test_Constructor_Success() public { - EVM2EVMMultiOffRamp.StaticConfig memory staticConfig = EVM2EVMMultiOffRamp.StaticConfig({ + OffRamp.StaticConfig memory staticConfig = OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, rmnProxy: address(s_mockRMN), tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }); - EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = - _generateDynamicMultiOffRampConfig(address(s_priceRegistry)); + OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(address(s_priceRegistry)); - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](2); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](2); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true }); - sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainConfigs[1] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1 + 1, onRamp: ON_RAMP_ADDRESS_2, isEnabled: true }); - EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig1 = EVM2EVMMultiOffRamp.SourceChainConfig({ + OffRamp.SourceChainConfig memory expectedSourceChainConfig1 = OffRamp.SourceChainConfig({ router: s_destRouter, isEnabled: true, minSeqNr: 1, onRamp: sourceChainConfigs[0].onRamp }); - EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig2 = EVM2EVMMultiOffRamp.SourceChainConfig({ + OffRamp.SourceChainConfig memory expectedSourceChainConfig2 = OffRamp.SourceChainConfig({ router: s_destRouter, isEnabled: true, minSeqNr: 1, @@ -71,24 +69,24 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { }); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.StaticConfigSet(staticConfig); + emit OffRamp.StaticConfigSet(staticConfig); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.DynamicConfigSet(dynamicConfig); + emit OffRamp.DynamicConfigSet(dynamicConfig); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SourceChainSelectorAdded(SOURCE_CHAIN_SELECTOR_1); + emit OffRamp.SourceChainSelectorAdded(SOURCE_CHAIN_SELECTOR_1); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1, expectedSourceChainConfig1); + emit OffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1, expectedSourceChainConfig1); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SourceChainSelectorAdded(SOURCE_CHAIN_SELECTOR_1 + 1); + emit OffRamp.SourceChainSelectorAdded(SOURCE_CHAIN_SELECTOR_1 + 1); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1 + 1, expectedSourceChainConfig2); + emit OffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1 + 1, expectedSourceChainConfig2); - s_offRamp = new EVM2EVMMultiOffRampHelper(staticConfig, dynamicConfig, sourceChainConfigs); + s_offRamp = new OffRampHelper(staticConfig, dynamicConfig, sourceChainConfigs); MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ @@ -103,13 +101,13 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { s_offRamp.setOCR3Configs(ocrConfigs); // Static config - EVM2EVMMultiOffRamp.StaticConfig memory gotStaticConfig = s_offRamp.getStaticConfig(); + OffRamp.StaticConfig memory gotStaticConfig = s_offRamp.getStaticConfig(); assertEq(staticConfig.chainSelector, gotStaticConfig.chainSelector); assertEq(staticConfig.rmnProxy, gotStaticConfig.rmnProxy); assertEq(staticConfig.tokenAdminRegistry, gotStaticConfig.tokenAdminRegistry); // Dynamic config - EVM2EVMMultiOffRamp.DynamicConfig memory gotDynamicConfig = s_offRamp.getDynamicConfig(); + OffRamp.DynamicConfig memory gotDynamicConfig = s_offRamp.getDynamicConfig(); _assertSameConfig(dynamicConfig, gotDynamicConfig); // OCR Config @@ -134,7 +132,7 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { ); // OffRamp initial values - assertEq("EVM2EVMMultiOffRamp 1.6.0-dev", s_offRamp.typeAndVersion()); + assertEq("OffRamp 1.6.0-dev", s_offRamp.typeAndVersion()); assertEq(OWNER, s_offRamp.owner()); assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); } @@ -144,25 +142,24 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { uint64[] memory sourceChainSelectors = new uint64[](1); sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: new bytes(0), isEnabled: true }); - vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + vm.expectRevert(OffRamp.ZeroAddressNotAllowed.selector); - s_offRamp = new EVM2EVMMultiOffRampHelper( - EVM2EVMMultiOffRamp.StaticConfig({ + s_offRamp = new OffRampHelper( + OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, rmnProxy: address(s_mockRMN), tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); } @@ -171,25 +168,24 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { uint64[] memory sourceChainSelectors = new uint64[](1); sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: 0, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true }); - vm.expectRevert(EVM2EVMMultiOffRamp.ZeroChainSelectorNotAllowed.selector); + vm.expectRevert(OffRamp.ZeroChainSelectorNotAllowed.selector); - s_offRamp = new EVM2EVMMultiOffRampHelper( - EVM2EVMMultiOffRamp.StaticConfig({ + s_offRamp = new OffRampHelper( + OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, rmnProxy: address(s_mockRMN), tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); } @@ -198,19 +194,18 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { uint64[] memory sourceChainSelectors = new uint64[](1); sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](0); - vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + vm.expectRevert(OffRamp.ZeroAddressNotAllowed.selector); - s_offRamp = new EVM2EVMMultiOffRampHelper( - EVM2EVMMultiOffRamp.StaticConfig({ + s_offRamp = new OffRampHelper( + OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, rmnProxy: ZERO_ADDRESS, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); } @@ -219,19 +214,18 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { uint64[] memory sourceChainSelectors = new uint64[](1); sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](0); - vm.expectRevert(EVM2EVMMultiOffRamp.ZeroChainSelectorNotAllowed.selector); + vm.expectRevert(OffRamp.ZeroChainSelectorNotAllowed.selector); - s_offRamp = new EVM2EVMMultiOffRampHelper( - EVM2EVMMultiOffRamp.StaticConfig({ + s_offRamp = new OffRampHelper( + OffRamp.StaticConfig({ chainSelector: 0, rmnProxy: address(s_mockRMN), tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); } @@ -240,19 +234,18 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { uint64[] memory sourceChainSelectors = new uint64[](1); sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](0); - vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + vm.expectRevert(OffRamp.ZeroAddressNotAllowed.selector); - s_offRamp = new EVM2EVMMultiOffRampHelper( - EVM2EVMMultiOffRamp.StaticConfig({ + s_offRamp = new OffRampHelper( + OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, rmnProxy: address(s_mockRMN), tokenAdminRegistry: ZERO_ADDRESS, nonceManager: address(s_inboundNonceManager) }), - _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); } @@ -261,49 +254,46 @@ contract EVM2EVMMultiOffRamp_constructor is EVM2EVMMultiOffRampSetup { uint64[] memory sourceChainSelectors = new uint64[](1); sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](0); - vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + vm.expectRevert(OffRamp.ZeroAddressNotAllowed.selector); - s_offRamp = new EVM2EVMMultiOffRampHelper( - EVM2EVMMultiOffRamp.StaticConfig({ + s_offRamp = new OffRampHelper( + OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, rmnProxy: address(s_mockRMN), tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: ZERO_ADDRESS }), - _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); } } -contract EVM2EVMMultiOffRamp_setDynamicConfig is EVM2EVMMultiOffRampSetup { +contract OffRamp_setDynamicConfig is OffRampSetup { function test_SetDynamicConfig_Success() public { - EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = - _generateDynamicMultiOffRampConfig(address(s_priceRegistry)); + OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(address(s_priceRegistry)); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.DynamicConfigSet(dynamicConfig); + emit OffRamp.DynamicConfigSet(dynamicConfig); s_offRamp.setDynamicConfig(dynamicConfig); - EVM2EVMMultiOffRamp.DynamicConfig memory newConfig = s_offRamp.getDynamicConfig(); + OffRamp.DynamicConfig memory newConfig = s_offRamp.getDynamicConfig(); _assertSameConfig(dynamicConfig, newConfig); } function test_SetDynamicConfigWithValidator_Success() public { - EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = - _generateDynamicMultiOffRampConfig(address(s_priceRegistry)); + OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(address(s_priceRegistry)); dynamicConfig.messageValidator = address(s_inboundMessageValidator); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.DynamicConfigSet(dynamicConfig); + emit OffRamp.DynamicConfigSet(dynamicConfig); s_offRamp.setDynamicConfig(dynamicConfig); - EVM2EVMMultiOffRamp.DynamicConfig memory newConfig = s_offRamp.getDynamicConfig(); + OffRamp.DynamicConfig memory newConfig = s_offRamp.getDynamicConfig(); _assertSameConfig(dynamicConfig, newConfig); } @@ -311,8 +301,7 @@ contract EVM2EVMMultiOffRamp_setDynamicConfig is EVM2EVMMultiOffRampSetup { function test_NonOwner_Revert() public { vm.startPrank(STRANGER); - EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = - _generateDynamicMultiOffRampConfig(address(s_priceRegistry)); + OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(address(s_priceRegistry)); vm.expectRevert("Only callable by owner"); @@ -320,15 +309,15 @@ contract EVM2EVMMultiOffRamp_setDynamicConfig is EVM2EVMMultiOffRampSetup { } function test_PriceRegistryZeroAddress_Revert() public { - EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = _generateDynamicMultiOffRampConfig(ZERO_ADDRESS); + OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(ZERO_ADDRESS); - vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + vm.expectRevert(OffRamp.ZeroAddressNotAllowed.selector); s_offRamp.setDynamicConfig(dynamicConfig); } } -contract EVM2EVMMultiOffRamp_ccipReceive is EVM2EVMMultiOffRampSetup { +contract OffRamp_ccipReceive is OffRampSetup { // Reverts function test_Reverts() public { @@ -339,7 +328,7 @@ contract EVM2EVMMultiOffRamp_ccipReceive is EVM2EVMMultiOffRampSetup { } } -contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { +contract OffRamp_executeSingleReport is OffRampSetup { function setUp() public virtual override { super.setUp(); _setupMultipleOffRamps(); @@ -468,7 +457,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[0].header.messageId, Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector( - EVM2EVMMultiOffRamp.ReceiverError.selector, + OffRamp.ReceiverError.selector, abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, realError1) ) ); @@ -526,7 +515,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { ); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); + emit OffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); } @@ -548,7 +537,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { ); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); + emit OffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); } @@ -671,7 +660,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[i].header.messageId = Internal._hash(messages[i], ON_RAMP_ADDRESS_1); vm.expectEmit(true, true, true, false); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit OffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages[i].header.sequenceNumber, messages[i].header.messageId, @@ -717,7 +706,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[0].header.messageId, Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector( - EVM2EVMMultiOffRamp.TokenHandlingError.selector, + OffRamp.TokenHandlingError.selector, abi.encodeWithSelector(TokenPool.InvalidSourcePoolAddress.selector, abi.encode(fakePoolAddress)) ) ); @@ -744,9 +733,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); vm.expectRevert( - abi.encodeWithSelector( - EVM2EVMMultiOffRamp.InvalidMessageDestChainSelector.selector, messages[0].header.destChainSelector - ) + abi.encodeWithSelector(OffRamp.InvalidMessageDestChainSelector.selector, messages[0].header.destChainSelector) ); s_offRamp.executeSingleReport(executionReport, new uint256[](0)); } @@ -757,7 +744,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { Internal.Any2EVMRampMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport( + OffRamp.CommitReport memory commitReport = _constructCommitReport( // Root against mismatching on ramp Internal._hash(messages[0], ON_RAMP_ADDRESS_3) ); @@ -765,13 +752,13 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { Internal.ExecutionReportSingleChain memory executionReport = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.RootNotCommitted.selector, SOURCE_CHAIN_SELECTOR_1)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.RootNotCommitted.selector, SOURCE_CHAIN_SELECTOR_1)); s_offRamp.executeSingleReport(executionReport, new uint256[](0)); } function test_Unhealthy_Revert() public { s_mockRMN.setGlobalCursed(true); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_1)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_1)); s_offRamp.executeSingleReport( _generateReportFromMessages( SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) @@ -790,7 +777,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { function test_UnhealthySingleChainCurse_Revert() public { s_mockRMN.setChainCursed(SOURCE_CHAIN_SELECTOR_1, true); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_1)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_1)); s_offRamp.executeSingleReport( _generateReportFromMessages( SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) @@ -813,13 +800,13 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { ); report.offchainTokenData = new bytes[][](report.messages.length + 1); - vm.expectRevert(EVM2EVMMultiOffRamp.UnexpectedTokenData.selector); + vm.expectRevert(OffRamp.UnexpectedTokenData.selector); s_offRamp.executeSingleReport(report, new uint256[](0)); } function test_EmptyReport_Revert() public { - vm.expectRevert(EVM2EVMMultiOffRamp.EmptyReport.selector); + vm.expectRevert(OffRamp.EmptyReport.selector); s_offRamp.executeSingleReport( Internal.ExecutionReportSingleChain({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, @@ -834,7 +821,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { function test_RootNotCommitted_Revert() public { s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 0); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.RootNotCommitted.selector, SOURCE_CHAIN_SELECTOR_1)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.RootNotCommitted.selector, SOURCE_CHAIN_SELECTOR_1)); Internal.Any2EVMRampMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); @@ -846,9 +833,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { function test_ManualExecutionNotYetEnabled_Revert() public { s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, BLOCK_TIME); - vm.expectRevert( - abi.encodeWithSelector(EVM2EVMMultiOffRamp.ManualExecutionNotYetEnabled.selector, SOURCE_CHAIN_SELECTOR_1) - ); + vm.expectRevert(abi.encodeWithSelector(OffRamp.ManualExecutionNotYetEnabled.selector, SOURCE_CHAIN_SELECTOR_1)); Internal.Any2EVMRampMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); @@ -863,7 +848,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { Internal.Any2EVMRampMessage[] memory messages = _generateSingleBasicMessage(newSourceChainSelector, newOnRamp); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.SourceChainNotEnabled.selector, newSourceChainSelector)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.SourceChainNotEnabled.selector, newSourceChainSelector)); s_offRamp.executeSingleReport(_generateReportFromMessages(newSourceChainSelector, messages), new uint256[](0)); } @@ -871,7 +856,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { Internal.Any2EVMRampMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_2, ON_RAMP_ADDRESS_2); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.SourceChainNotEnabled.selector, SOURCE_CHAIN_SELECTOR_2)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.SourceChainNotEnabled.selector, SOURCE_CHAIN_SELECTOR_2)); s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_2, messages), new uint256[](0)); } @@ -884,7 +869,7 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { vm.expectRevert( abi.encodeWithSelector( - EVM2EVMMultiOffRamp.TokenDataMismatch.selector, SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber + OffRamp.TokenDataMismatch.selector, SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber ) ); s_offRamp.executeSingleReport(report, new uint256[](0)); @@ -933,34 +918,32 @@ contract EVM2EVMMultiOffRamp_executeSingleReport is EVM2EVMMultiOffRampSetup { messages[0].header.messageId, Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector( - EVM2EVMMultiOffRamp.ReceiverError.selector, + OffRamp.ReceiverError.selector, abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, realError1) ) ); // The second time should skip the msg vm.expectEmit(); - emit EVM2EVMMultiOffRamp.AlreadyAttempted(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); + emit OffRamp.AlreadyAttempted(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); s_offRamp.executeSingleReport(_generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[](0)); } - function _constructCommitReport(bytes32 merkleRoot) internal view returns (EVM2EVMMultiOffRamp.CommitReport memory) { - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + function _constructCommitReport(bytes32 merkleRoot) internal view returns (OffRamp.CommitReport memory) { + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: EVM2EVMMultiOffRamp.Interval(1, 2), + interval: OffRamp.Interval(1, 2), merkleRoot: merkleRoot }); - return EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), - merkleRoots: roots - }); + return + OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); } } -contract EVM2EVMMultiOffRamp_executeSingleMessage is EVM2EVMMultiOffRampSetup { +contract OffRamp_executeSingleMessage is OffRampSetup { function setUp() public virtual override { super.setUp(); _setupMultipleOffRamps(); @@ -1042,7 +1025,7 @@ contract EVM2EVMMultiOffRamp_executeSingleMessage is EVM2EVMMultiOffRampSetup { _generateAny2EVMMessageWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1, amounts); s_maybeRevertingPool.setShouldRevert(errorMessage); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, errorMessage)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.TokenHandlingError.selector, errorMessage)); s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); } @@ -1052,7 +1035,7 @@ contract EVM2EVMMultiOffRamp_executeSingleMessage is EVM2EVMMultiOffRampSetup { _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); message.gasLimit = 0; - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.ReceiverError.selector, "")); + vm.expectRevert(abi.encodeWithSelector(OffRamp.ReceiverError.selector, "")); s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); } @@ -1061,7 +1044,7 @@ contract EVM2EVMMultiOffRamp_executeSingleMessage is EVM2EVMMultiOffRampSetup { vm.stopPrank(); Internal.Any2EVMRampMessage memory message = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); - vm.expectRevert(EVM2EVMMultiOffRamp.CanOnlySelfCall.selector); + vm.expectRevert(OffRamp.CanOnlySelfCall.selector); s_offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length)); } @@ -1107,7 +1090,7 @@ contract EVM2EVMMultiOffRamp_executeSingleMessage is EVM2EVMMultiOffRampSetup { } } -contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { +contract OffRamp_batchExecute is OffRampSetup { function setUp() public virtual override { super.setUp(); _setupMultipleOffRamps(); @@ -1233,7 +1216,7 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); + emit OffRamp.SkippedAlreadyExecutedMessage(SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber); vm.recordLogs(); s_offRamp.batchExecute(reports, new uint256[][](2)); @@ -1248,13 +1231,13 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { // Reverts function test_ZeroReports_Revert() public { - vm.expectRevert(EVM2EVMMultiOffRamp.EmptyReport.selector); + vm.expectRevert(OffRamp.EmptyReport.selector); s_offRamp.batchExecute(new Internal.ExecutionReportSingleChain[](0), new uint256[][](1)); } function test_Unhealthy_Revert() public { s_mockRMN.setGlobalCursed(true); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_1)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_1)); s_offRamp.batchExecute( _generateBatchReportFromMessages( SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) @@ -1288,7 +1271,7 @@ contract EVM2EVMMultiOffRamp_batchExecute is EVM2EVMMultiOffRampSetup { } } -contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { +contract OffRamp_manuallyExecute is OffRampSetup { function setUp() public virtual override { super.setUp(); _setupMultipleOffRamps(); @@ -1307,7 +1290,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { s_reverting_receiver.setRevert(false); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit OffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -1331,7 +1314,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { s_reverting_receiver.setRevert(false); vm.expectEmit(true, true, true, true); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit OffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -1370,8 +1353,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { messages[0].header.messageId, Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector( - EVM2EVMMultiOffRamp.ReceiverError.selector, - abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, "") + OffRamp.ReceiverError.selector, abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, "") ) ); @@ -1415,7 +1397,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { for (uint256 i = 0; i < 3; ++i) { vm.expectEmit(true, true, true, true); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit OffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages1[i].header.sequenceNumber, messages1[i].header.messageId, @@ -1433,7 +1415,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { for (uint256 i = 0; i < 2; ++i) { vm.expectEmit(true, true, true, false); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit OffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_3, messages2[i].header.sequenceNumber, messages2[i].header.messageId, @@ -1458,7 +1440,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { messages[1].header.messageId = Internal._hash(messages[1], ON_RAMP_ADDRESS_1); vm.expectEmit(true, true, true, false); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit OffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -1468,20 +1450,20 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { ); vm.expectEmit(true, true, true, false); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit OffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages[1].header.sequenceNumber, messages[1].header.messageId, Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector( - EVM2EVMMultiOffRamp.ReceiverError.selector, + OffRamp.ReceiverError.selector, abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, bytes("")) ), 32095 ); vm.expectEmit(true, true, true, false); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit OffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, messages[2].header.sequenceNumber, messages[2].header.messageId, @@ -1503,7 +1485,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { gasLimitOverrides[0][0] += 1; vm.expectEmit(true, true, true, false); - emit EVM2EVMMultiOffRamp.ExecutionStateChanged( + emit OffRamp.ExecutionStateChanged( SOURCE_CHAIN_SELECTOR_1, newMessages[0].header.sequenceNumber, newMessages[0].header.messageId, @@ -1530,7 +1512,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.FAILURE, - abi.encodeWithSelector(EVM2EVMMultiOffRamp.ReceiverError.selector, "") + abi.encodeWithSelector(OffRamp.ReceiverError.selector, "") ); uint256[][] memory gasLimitOverrides = new uint256[][](1); @@ -1579,25 +1561,25 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { _generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages); // No overrides for report - vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + vm.expectRevert(OffRamp.ManualExecutionGasLimitMismatch.selector); s_offRamp.manuallyExecute(reports, new uint256[][](0)); // No messages uint256[][] memory gasLimitOverrides = new uint256[][](1); - vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + vm.expectRevert(OffRamp.ManualExecutionGasLimitMismatch.selector); s_offRamp.manuallyExecute(reports, gasLimitOverrides); // 1 message missing gasLimitOverrides[0] = new uint256[](1); - vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + vm.expectRevert(OffRamp.ManualExecutionGasLimitMismatch.selector); s_offRamp.manuallyExecute(reports, gasLimitOverrides); // 1 message in excess gasLimitOverrides[0] = new uint256[](3); - vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + vm.expectRevert(OffRamp.ManualExecutionGasLimitMismatch.selector); s_offRamp.manuallyExecute(reports, gasLimitOverrides); } @@ -1613,34 +1595,34 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages1); reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messages2); - vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + vm.expectRevert(OffRamp.ManualExecutionGasLimitMismatch.selector); s_offRamp.manuallyExecute(reports, new uint256[][](0)); - vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + vm.expectRevert(OffRamp.ManualExecutionGasLimitMismatch.selector); s_offRamp.manuallyExecute(reports, new uint256[][](1)); uint256[][] memory gasLimitOverrides = new uint256[][](2); - vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + vm.expectRevert(OffRamp.ManualExecutionGasLimitMismatch.selector); s_offRamp.manuallyExecute(reports, gasLimitOverrides); // 2nd report empty gasLimitOverrides[0] = new uint256[](2); - vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + vm.expectRevert(OffRamp.ManualExecutionGasLimitMismatch.selector); s_offRamp.manuallyExecute(reports, gasLimitOverrides); // 1st report empty gasLimitOverrides[0] = new uint256[](0); gasLimitOverrides[1] = new uint256[](1); - vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + vm.expectRevert(OffRamp.ManualExecutionGasLimitMismatch.selector); s_offRamp.manuallyExecute(reports, gasLimitOverrides); // 1st report oversized gasLimitOverrides[0] = new uint256[](3); - vm.expectRevert(EVM2EVMMultiOffRamp.ManualExecutionGasLimitMismatch.selector); + vm.expectRevert(OffRamp.ManualExecutionGasLimitMismatch.selector); s_offRamp.manuallyExecute(reports, gasLimitOverrides); } @@ -1654,7 +1636,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { vm.expectRevert( abi.encodeWithSelector( - EVM2EVMMultiOffRamp.InvalidManualExecutionGasLimit.selector, SOURCE_CHAIN_SELECTOR_1, 0, gasLimitOverrides[0][0] + OffRamp.InvalidManualExecutionGasLimit.selector, SOURCE_CHAIN_SELECTOR_1, 0, gasLimitOverrides[0][0] ) ); s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); @@ -1676,10 +1658,10 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { vm.expectRevert( abi.encodeWithSelector( - EVM2EVMMultiOffRamp.ExecutionError.selector, + OffRamp.ExecutionError.selector, messages[0].header.messageId, abi.encodeWithSelector( - EVM2EVMMultiOffRamp.ReceiverError.selector, + OffRamp.ReceiverError.selector, abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, bytes("")) ) ) @@ -1724,7 +1706,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { // The first entry should be fine and triggers the second entry which is skipped. Due to the reentrancy // the second completes first, so we expect the skip event before the success event. vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SkippedAlreadyExecutedMessage( + emit OffRamp.SkippedAlreadyExecutedMessage( messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber ); @@ -1743,7 +1725,7 @@ contract EVM2EVMMultiOffRamp_manuallyExecute is EVM2EVMMultiOffRampSetup { } } -contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { +contract OffRamp_execute is OffRampSetup { function setUp() public virtual override { super.setUp(); _setupMultipleOffRamps(); @@ -1992,7 +1974,7 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { function test_ZeroReports_Revert() public { Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](0); - vm.expectRevert(EVM2EVMMultiOffRamp.EmptyReport.selector); + vm.expectRevert(OffRamp.EmptyReport.selector); _execute(reports); } @@ -2020,7 +2002,7 @@ contract EVM2EVMMultiOffRamp_execute is EVM2EVMMultiOffRampSetup { } } -contract EVM2EVMMultiOffRamp_getExecutionState is EVM2EVMMultiOffRampSetup { +contract OffRamp_getExecutionState is OffRampSetup { mapping(uint64 sourceChainSelector => mapping(uint64 seqNum => Internal.MessageExecutionState state)) internal s_differentialExecutionState; @@ -2172,7 +2154,7 @@ contract EVM2EVMMultiOffRamp_getExecutionState is EVM2EVMMultiOffRampSetup { } } -contract EVM2EVMMultiOffRamp_trialExecute is EVM2EVMMultiOffRampSetup { +contract OffRamp_trialExecute is OffRampSetup { function setUp() public virtual override { super.setUp(); _setupMultipleOffRamps(); @@ -2214,7 +2196,7 @@ contract EVM2EVMMultiOffRamp_trialExecute is EVM2EVMMultiOffRampSetup { (Internal.MessageExecutionState newState, bytes memory err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); - assertEq(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, errorMessage), err); + assertEq(abi.encodeWithSelector(OffRamp.TokenHandlingError.selector, errorMessage), err); // Expect the balance to remain the same assertEq(startingBalance, dstToken0.balanceOf(OWNER)); @@ -2234,7 +2216,7 @@ contract EVM2EVMMultiOffRamp_trialExecute is EVM2EVMMultiOffRampSetup { (Internal.MessageExecutionState newState, bytes memory err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); - assertEq(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, errorMessage), err); + assertEq(abi.encodeWithSelector(OffRamp.TokenHandlingError.selector, errorMessage), err); } // TODO test actual pool exists but isn't compatible instead of just no pool @@ -2283,11 +2265,11 @@ contract EVM2EVMMultiOffRamp_trialExecute is EVM2EVMMultiOffRampSetup { (newState, err) = s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); - assertEq(abi.encodeWithSelector(EVM2EVMMultiOffRamp.NotACompatiblePool.selector, address(0)), err); + assertEq(abi.encodeWithSelector(OffRamp.NotACompatiblePool.selector, address(0)), err); } } -contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSetup { +contract OffRamp__releaseOrMintSingleToken is OffRampSetup { function setUp() public virtual override { super.setUp(); _setupMultipleOffRamps(); @@ -2347,9 +2329,7 @@ contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSet s_destTokenBySourceToken[token], abi.encodeWithSelector(IERC20.balanceOf.selector, OWNER), abi.encode(0, 0) ); - vm.expectRevert( - abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidDataLength.selector, Internal.MAX_BALANCE_OF_RET_BYTES, 64) - ); + vm.expectRevert(abi.encodeWithSelector(OffRamp.InvalidDataLength.selector, Internal.MAX_BALANCE_OF_RET_BYTES, 64)); s_offRamp.releaseOrMintSingleToken(tokenAmount, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR, ""); } @@ -2372,7 +2352,7 @@ contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSet s_destTokenBySourceToken[token], abi.encodeWithSelector(IERC20.balanceOf.selector, OWNER), revertData ); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, revertData)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.TokenHandlingError.selector, revertData)); s_offRamp.releaseOrMintSingleToken(tokenAmount, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR, ""); } @@ -2397,7 +2377,7 @@ contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSet vm.expectRevert( abi.encodeWithSelector( - EVM2EVMMultiOffRamp.ReleaseOrMintBalanceMismatch.selector, amount, mockedStaticBalance, mockedStaticBalance + OffRamp.ReleaseOrMintBalanceMismatch.selector, amount, mockedStaticBalance, mockedStaticBalance ) ); @@ -2452,7 +2432,7 @@ contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSet abi.encode(returnedPool) ); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.NotACompatiblePool.selector, returnedPool)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.NotACompatiblePool.selector, returnedPool)); s_offRamp.releaseOrMintSingleToken(tokenAmount, originalSender, OWNER, SOURCE_CHAIN_SELECTOR_1, offchainTokenData); @@ -2465,7 +2445,7 @@ contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSet abi.encode(returnedPool) ); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.NotACompatiblePool.selector, returnedPool)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.NotACompatiblePool.selector, returnedPool)); s_offRamp.releaseOrMintSingleToken(tokenAmount, originalSender, OWNER, SOURCE_CHAIN_SELECTOR_1, offchainTokenData); } @@ -2489,14 +2469,14 @@ contract EVM2EVMMultiOffRamp__releaseOrMintSingleToken is EVM2EVMMultiOffRampSet vm.mockCallRevert(destToken, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount), revertData); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, revertData)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.TokenHandlingError.selector, revertData)); s_offRamp.releaseOrMintSingleToken( tokenAmount, originalSender, receiver, SOURCE_CHAIN_SELECTOR_1, offchainTokenData ); } } -contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { +contract OffRamp_releaseOrMintTokens is OffRampSetup { function setUp() public virtual override { super.setUp(); _setupMultipleOffRamps(); @@ -2568,7 +2548,7 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { bytes memory unknownError = bytes("unknown error"); s_maybeRevertingPool.setShouldRevert(unknownError); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.TokenHandlingError.selector, unknownError)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.TokenHandlingError.selector, unknownError)); s_offRamp.releaseOrMintTokens( _getDefaultSourceTokenData(srcTokenAmounts), @@ -2606,9 +2586,7 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { abi.encode(amount, amount) ); - vm.expectRevert( - abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidDataLength.selector, Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, 64) - ); + vm.expectRevert(abi.encodeWithSelector(OffRamp.InvalidDataLength.selector, Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, 64)); s_offRamp.releaseOrMintTokens( sourceTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, offchainTokenData @@ -2643,7 +2621,7 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { amount: 1 }); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.NotACompatiblePool.selector, address(0))); + vm.expectRevert(abi.encodeWithSelector(OffRamp.NotACompatiblePool.selector, address(0))); s_offRamp.releaseOrMintTokens(sourceTokenAmounts, abi.encode(OWNER), OWNER, SOURCE_CHAIN_SELECTOR_1, new bytes[](1)); } @@ -2700,11 +2678,10 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { ) {} catch (bytes memory reason) { // Any revert should be a TokenHandlingError, InvalidEVMAddress, InvalidDataLength or NoContract as those are caught by the offramp assertTrue( - bytes4(reason) == EVM2EVMMultiOffRamp.TokenHandlingError.selector - || bytes4(reason) == Internal.InvalidEVMAddress.selector - || bytes4(reason) == EVM2EVMMultiOffRamp.InvalidDataLength.selector + bytes4(reason) == OffRamp.TokenHandlingError.selector || bytes4(reason) == Internal.InvalidEVMAddress.selector + || bytes4(reason) == OffRamp.InvalidDataLength.selector || bytes4(reason) == CallWithExactGas.NoContract.selector - || bytes4(reason) == EVM2EVMMultiOffRamp.NotACompatiblePool.selector, + || bytes4(reason) == OffRamp.NotACompatiblePool.selector, "Expected TokenHandlingError or InvalidEVMAddress" ); @@ -2715,10 +2692,9 @@ contract EVM2EVMMultiOffRamp_releaseOrMintTokens is EVM2EVMMultiOffRampSetup { } } -contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRampSetup { +contract OffRamp_applySourceChainConfigUpdates is OffRampSetup { function test_ApplyZeroUpdates_Success() public { - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](0); vm.recordLogs(); s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); @@ -2731,27 +2707,22 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam } function test_AddNewChain_Success() public { - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true }); - EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig = EVM2EVMMultiOffRamp.SourceChainConfig({ - router: s_destRouter, - isEnabled: true, - minSeqNr: 1, - onRamp: ON_RAMP_ADDRESS_1 - }); + OffRamp.SourceChainConfig memory expectedSourceChainConfig = + OffRamp.SourceChainConfig({router: s_destRouter, isEnabled: true, minSeqNr: 1, onRamp: ON_RAMP_ADDRESS_1}); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SourceChainSelectorAdded(SOURCE_CHAIN_SELECTOR_1); + emit OffRamp.SourceChainSelectorAdded(SOURCE_CHAIN_SELECTOR_1); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1, expectedSourceChainConfig); + emit OffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1, expectedSourceChainConfig); s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); @@ -2759,9 +2730,8 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam } function test_ReplaceExistingChain_Success() public { - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, @@ -2771,15 +2741,11 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); sourceChainConfigs[0].isEnabled = false; - EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig = EVM2EVMMultiOffRamp.SourceChainConfig({ - router: s_destRouter, - isEnabled: false, - minSeqNr: 1, - onRamp: ON_RAMP_ADDRESS_1 - }); + OffRamp.SourceChainConfig memory expectedSourceChainConfig = + OffRamp.SourceChainConfig({router: s_destRouter, isEnabled: false, minSeqNr: 1, onRamp: ON_RAMP_ADDRESS_1}); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1, expectedSourceChainConfig); + emit OffRamp.SourceChainConfigSet(SOURCE_CHAIN_SELECTOR_1, expectedSourceChainConfig); vm.recordLogs(); s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); @@ -2796,31 +2762,29 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam } function test_AddMultipleChains_Success() public { - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](3); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](3); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: abi.encode(ON_RAMP_ADDRESS_1, 0), isEnabled: true }); - sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainConfigs[1] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1 + 1, onRamp: abi.encode(ON_RAMP_ADDRESS_1, 1), isEnabled: false }); - sourceChainConfigs[2] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainConfigs[2] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1 + 2, onRamp: abi.encode(ON_RAMP_ADDRESS_1, 2), isEnabled: true }); - EVM2EVMMultiOffRamp.SourceChainConfig[] memory expectedSourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfig[](3); + OffRamp.SourceChainConfig[] memory expectedSourceChainConfigs = new OffRamp.SourceChainConfig[](3); for (uint256 i = 0; i < 3; ++i) { - expectedSourceChainConfigs[i] = EVM2EVMMultiOffRamp.SourceChainConfig({ + expectedSourceChainConfigs[i] = OffRamp.SourceChainConfig({ router: s_destRouter, isEnabled: sourceChainConfigs[i].isEnabled, minSeqNr: 1, @@ -2828,12 +2792,10 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam }); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SourceChainSelectorAdded(sourceChainConfigs[i].sourceChainSelector); + emit OffRamp.SourceChainSelectorAdded(sourceChainConfigs[i].sourceChainSelector); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SourceChainConfigSet( - sourceChainConfigs[i].sourceChainSelector, expectedSourceChainConfigs[i] - ); + emit OffRamp.SourceChainConfigSet(sourceChainConfigs[i].sourceChainSelector, expectedSourceChainConfigs[i]); } s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); @@ -2845,17 +2807,16 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam } } - function test_Fuzz_applySourceChainConfigUpdate_Success( - EVM2EVMMultiOffRamp.SourceChainConfigArgs memory sourceChainConfigArgs - ) public { + function test_Fuzz_applySourceChainConfigUpdate_Success(OffRamp.SourceChainConfigArgs memory sourceChainConfigArgs) + public + { // Skip invalid inputs vm.assume(sourceChainConfigArgs.sourceChainSelector != 0); vm.assume(sourceChainConfigArgs.onRamp.length != 0); vm.assume(address(sourceChainConfigArgs.router) != address(0)); - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](2); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](2); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, @@ -2869,7 +2830,7 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam sourceChainConfigs[1].onRamp = sourceChainConfigs[0].onRamp; } - EVM2EVMMultiOffRamp.SourceChainConfig memory expectedSourceChainConfig = EVM2EVMMultiOffRamp.SourceChainConfig({ + OffRamp.SourceChainConfig memory expectedSourceChainConfig = OffRamp.SourceChainConfig({ router: sourceChainConfigArgs.router, isEnabled: sourceChainConfigArgs.isEnabled, minSeqNr: 1, @@ -2878,11 +2839,11 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam if (isNewChain) { vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SourceChainSelectorAdded(sourceChainConfigArgs.sourceChainSelector); + emit OffRamp.SourceChainSelectorAdded(sourceChainConfigArgs.sourceChainSelector); } vm.expectEmit(); - emit EVM2EVMMultiOffRamp.SourceChainConfigSet(sourceChainConfigArgs.sourceChainSelector, expectedSourceChainConfig); + emit OffRamp.SourceChainConfigSet(sourceChainConfigArgs.sourceChainSelector, expectedSourceChainConfig); s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); @@ -2894,51 +2855,47 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam // Reverts function test_ZeroOnRampAddress_Revert() public { - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: new bytes(0), isEnabled: true }); - vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + vm.expectRevert(OffRamp.ZeroAddressNotAllowed.selector); s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); } function test_RouterAddress_Revert() public { - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: IRouter(address(0)), sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true }); - vm.expectRevert(EVM2EVMMultiOffRamp.ZeroAddressNotAllowed.selector); + vm.expectRevert(OffRamp.ZeroAddressNotAllowed.selector); s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); } function test_ZeroSourceChainSelector_Revert() public { - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: 0, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true }); - vm.expectRevert(EVM2EVMMultiOffRamp.ZeroChainSelectorNotAllowed.selector); + vm.expectRevert(OffRamp.ZeroChainSelectorNotAllowed.selector); s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); } function test_ReplaceExistingChainOnRamp_Revert() public { - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](1); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](1); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, @@ -2949,12 +2906,12 @@ contract EVM2EVMMultiOffRamp_applySourceChainConfigUpdates is EVM2EVMMultiOffRam sourceChainConfigs[0].onRamp = ON_RAMP_ADDRESS_2; - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidStaticConfig.selector, SOURCE_CHAIN_SELECTOR_1)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.InvalidStaticConfig.selector, SOURCE_CHAIN_SELECTOR_1)); s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); } } -contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { +contract OffRamp_commit is OffRampSetup { uint64 internal s_maxInterval = 12; function setUp() public virtual override { @@ -2965,10 +2922,10 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { } function test_ReportAndPriceUpdate_Success() public { - EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + OffRamp.CommitReport memory commitReport = _constructCommitReport(); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + emit OffRamp.CommitReportAccepted(commitReport); vm.expectEmit(); emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); @@ -2983,18 +2940,18 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { uint64 max1 = 931; bytes32 root = "Only a single root"; - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: EVM2EVMMultiOffRamp.Interval(1, max1), + interval: OffRamp.Interval(1, max1), merkleRoot: root }); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + emit OffRamp.CommitReportAccepted(commitReport); vm.expectEmit(); emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); @@ -3011,17 +2968,17 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { uint224 tokenStartPrice = IPriceRegistry(s_offRamp.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value; - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: EVM2EVMMultiOffRamp.Interval(1, maxSeq), + interval: OffRamp.Interval(1, maxSeq), merkleRoot: "stale report 1" }); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); vm.expectEmit(); - emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + emit OffRamp.CommitReportAccepted(commitReport); vm.expectEmit(); emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); @@ -3031,11 +2988,11 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { assertEq(maxSeq + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); - commitReport.merkleRoots[0].interval = EVM2EVMMultiOffRamp.Interval(maxSeq + 1, maxSeq * 2); + commitReport.merkleRoots[0].interval = OffRamp.Interval(maxSeq + 1, maxSeq * 2); commitReport.merkleRoots[0].merkleRoot = "stale report 2"; vm.expectEmit(); - emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + emit OffRamp.CommitReportAccepted(commitReport); vm.expectEmit(); emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); @@ -3050,11 +3007,9 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { } function test_OnlyTokenPriceUpdates_Success() public { - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), - merkleRoots: roots - }); + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](0); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); vm.expectEmit(); emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); @@ -3068,11 +3023,9 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { } function test_OnlyGasPriceUpdates_Success() public { - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), - merkleRoots: roots - }); + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](0); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); vm.expectEmit(); emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); @@ -3085,11 +3038,9 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { } function test_PriceSequenceNumberCleared_Success() public { - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), - merkleRoots: roots - }); + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](0); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); vm.expectEmit(); emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); @@ -3136,8 +3087,8 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { uint64 maxSeq = 12; uint224 tokenPrice1 = 4e18; uint224 tokenPrice2 = 5e18; - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](0); + OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({ priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice1), merkleRoots: roots }); @@ -3151,17 +3102,17 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { _commit(commitReport, s_latestSequenceNumber); assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); - roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + roots = new OffRamp.MerkleRoot[](1); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: EVM2EVMMultiOffRamp.Interval(1, maxSeq), + interval: OffRamp.Interval(1, maxSeq), merkleRoot: "stale report" }); commitReport.priceUpdates = _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice2); commitReport.merkleRoots = roots; vm.expectEmit(); - emit EVM2EVMMultiOffRamp.CommitReportAccepted(commitReport); + emit OffRamp.CommitReportAccepted(commitReport); vm.expectEmit(); emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); @@ -3178,7 +3129,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { // Reverts function test_UnauthorizedTransmitter_Revert() public { - EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + OffRamp.CommitReport memory commitReport = _constructCommitReport(); bytes32[3] memory reportContext = [s_configDigestCommit, bytes32(uint256(s_latestSequenceNumber)), s_configDigestCommit]; @@ -3193,7 +3144,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { function test_NoConfig_Revert() public { _redeployOffRampWithNoOCRConfigs(); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + OffRamp.CommitReport memory commitReport = _constructCommitReport(); bytes32[3] memory reportContext = [bytes32(""), s_configDigestCommit, s_configDigestCommit]; (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = @@ -3218,7 +3169,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { }); s_offRamp.setOCR3Configs(ocrConfigs); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + OffRamp.CommitReport memory commitReport = _constructCommitReport(); bytes32[3] memory reportContext = [bytes32(""), s_configDigestCommit, s_configDigestCommit]; (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = @@ -3232,7 +3183,7 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { function test_WrongConfigWithoutSigners_Revert() public { _redeployOffRampWithNoOCRConfigs(); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = _constructCommitReport(); + OffRamp.CommitReport memory commitReport = _constructCommitReport(); MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ @@ -3251,147 +3202,126 @@ contract EVM2EVMMultiOffRamp_commit is EVM2EVMMultiOffRampSetup { function test_Unhealthy_Revert() public { s_mockRMN.setGlobalCursed(true); - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: EVM2EVMMultiOffRamp.Interval(1, 2), + interval: OffRamp.Interval(1, 2), merkleRoot: "Only a single root" }); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.CursedByRMN.selector, roots[0].sourceChainSelector)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.CursedByRMN.selector, roots[0].sourceChainSelector)); _commit(commitReport, s_latestSequenceNumber); } function test_InvalidRootRevert() public { - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: EVM2EVMMultiOffRamp.Interval(1, 4), + interval: OffRamp.Interval(1, 4), merkleRoot: bytes32(0) }); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); - vm.expectRevert(EVM2EVMMultiOffRamp.InvalidRoot.selector); + vm.expectRevert(OffRamp.InvalidRoot.selector); _commit(commitReport, s_latestSequenceNumber); } function test_InvalidInterval_Revert() public { - EVM2EVMMultiOffRamp.Interval memory interval = EVM2EVMMultiOffRamp.Interval(2, 2); - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ - sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: interval, - merkleRoot: bytes32(0) - }); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); - - vm.expectRevert( - abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, interval) - ); + OffRamp.Interval memory interval = OffRamp.Interval(2, 2); + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = + OffRamp.MerkleRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, interval: interval, merkleRoot: bytes32(0)}); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + + vm.expectRevert(abi.encodeWithSelector(OffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, interval)); _commit(commitReport, s_latestSequenceNumber); } function test_InvalidIntervalMinLargerThanMax_Revert() public { s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR); - EVM2EVMMultiOffRamp.Interval memory interval = EVM2EVMMultiOffRamp.Interval(1, 0); - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ - sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: interval, - merkleRoot: bytes32(0) - }); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); - - vm.expectRevert( - abi.encodeWithSelector(EVM2EVMMultiOffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, interval) - ); + OffRamp.Interval memory interval = OffRamp.Interval(1, 0); + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = + OffRamp.MerkleRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, interval: interval, merkleRoot: bytes32(0)}); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + + vm.expectRevert(abi.encodeWithSelector(OffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, interval)); _commit(commitReport, s_latestSequenceNumber); } function test_ZeroEpochAndRound_Revert() public { - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), - merkleRoots: roots - }); + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](0); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); - vm.expectRevert(EVM2EVMMultiOffRamp.StaleCommitReport.selector); + vm.expectRevert(OffRamp.StaleCommitReport.selector); _commit(commitReport, 0); } function test_OnlyPriceUpdateStaleReport_Revert() public { - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](0); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), - merkleRoots: roots - }); + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](0); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); vm.expectEmit(); emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); _commit(commitReport, s_latestSequenceNumber); - vm.expectRevert(EVM2EVMMultiOffRamp.StaleCommitReport.selector); + vm.expectRevert(OffRamp.StaleCommitReport.selector); _commit(commitReport, s_latestSequenceNumber); } function test_SourceChainNotEnabled_Revert() public { - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ - sourceChainSelector: 0, - interval: EVM2EVMMultiOffRamp.Interval(1, 2), - merkleRoot: "Only a single root" - }); + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = + OffRamp.MerkleRoot({sourceChainSelector: 0, interval: OffRamp.Interval(1, 2), merkleRoot: "Only a single root"}); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOffRamp.SourceChainNotEnabled.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(OffRamp.SourceChainNotEnabled.selector, 0)); _commit(commitReport, s_latestSequenceNumber); } function test_RootAlreadyCommitted_Revert() public { - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: EVM2EVMMultiOffRamp.Interval(1, 2), + interval: OffRamp.Interval(1, 2), merkleRoot: "Only a single root" }); - EVM2EVMMultiOffRamp.CommitReport memory commitReport = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport memory commitReport = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); _commit(commitReport, s_latestSequenceNumber); - commitReport.merkleRoots[0].interval = EVM2EVMMultiOffRamp.Interval(3, 3); + commitReport.merkleRoots[0].interval = OffRamp.Interval(3, 3); vm.expectRevert( - abi.encodeWithSelector( - EVM2EVMMultiOffRamp.RootAlreadyCommitted.selector, roots[0].sourceChainSelector, roots[0].merkleRoot - ) + abi.encodeWithSelector(OffRamp.RootAlreadyCommitted.selector, roots[0].sourceChainSelector, roots[0].merkleRoot) ); _commit(commitReport, ++s_latestSequenceNumber); } - function _constructCommitReport() internal view returns (EVM2EVMMultiOffRamp.CommitReport memory) { - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + function _constructCommitReport() internal view returns (OffRamp.CommitReport memory) { + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: EVM2EVMMultiOffRamp.Interval(1, s_maxInterval), + interval: OffRamp.Interval(1, s_maxInterval), merkleRoot: "test #2" }); - return EVM2EVMMultiOffRamp.CommitReport({ - priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), - merkleRoots: roots - }); + return + OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); } } -contract EVM2EVMMultiOffRamp_resetUnblessedRoots is EVM2EVMMultiOffRampSetup { +contract OffRamp_resetUnblessedRoots is OffRampSetup { function setUp() public virtual override { super.setUp(); _setupRealRMN(); @@ -3400,30 +3330,30 @@ contract EVM2EVMMultiOffRamp_resetUnblessedRoots is EVM2EVMMultiOffRampSetup { } function test_ResetUnblessedRoots_Success() public { - EVM2EVMMultiOffRamp.UnblessedRoot[] memory rootsToReset = new EVM2EVMMultiOffRamp.UnblessedRoot[](3); - rootsToReset[0] = EVM2EVMMultiOffRamp.UnblessedRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR, merkleRoot: "1"}); - rootsToReset[1] = EVM2EVMMultiOffRamp.UnblessedRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR, merkleRoot: "2"}); - rootsToReset[2] = EVM2EVMMultiOffRamp.UnblessedRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR, merkleRoot: "3"}); + OffRamp.UnblessedRoot[] memory rootsToReset = new OffRamp.UnblessedRoot[](3); + rootsToReset[0] = OffRamp.UnblessedRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR, merkleRoot: "1"}); + rootsToReset[1] = OffRamp.UnblessedRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR, merkleRoot: "2"}); + rootsToReset[2] = OffRamp.UnblessedRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR, merkleRoot: "3"}); - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](3); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](3); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: EVM2EVMMultiOffRamp.Interval(1, 2), + interval: OffRamp.Interval(1, 2), merkleRoot: rootsToReset[0].merkleRoot }); - roots[1] = EVM2EVMMultiOffRamp.MerkleRoot({ + roots[1] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: EVM2EVMMultiOffRamp.Interval(3, 4), + interval: OffRamp.Interval(3, 4), merkleRoot: rootsToReset[1].merkleRoot }); - roots[2] = EVM2EVMMultiOffRamp.MerkleRoot({ + roots[2] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: EVM2EVMMultiOffRamp.Interval(5, 5), + interval: OffRamp.Interval(5, 5), merkleRoot: rootsToReset[2].merkleRoot }); - EVM2EVMMultiOffRamp.CommitReport memory report = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport memory report = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); _commit(report, ++s_latestSequenceNumber); @@ -3434,10 +3364,10 @@ contract EVM2EVMMultiOffRamp_resetUnblessedRoots is EVM2EVMMultiOffRampSetup { s_realRMN.voteToBless(blessedTaggedRoots); vm.expectEmit(false, false, false, true); - emit EVM2EVMMultiOffRamp.RootRemoved(rootsToReset[0].merkleRoot); + emit OffRamp.RootRemoved(rootsToReset[0].merkleRoot); vm.expectEmit(false, false, false, true); - emit EVM2EVMMultiOffRamp.RootRemoved(rootsToReset[2].merkleRoot); + emit OffRamp.RootRemoved(rootsToReset[2].merkleRoot); vm.startPrank(OWNER); s_offRamp.resetUnblessedRoots(rootsToReset); @@ -3452,12 +3382,12 @@ contract EVM2EVMMultiOffRamp_resetUnblessedRoots is EVM2EVMMultiOffRampSetup { function test_OnlyOwner_Revert() public { vm.stopPrank(); vm.expectRevert("Only callable by owner"); - EVM2EVMMultiOffRamp.UnblessedRoot[] memory rootsToReset = new EVM2EVMMultiOffRamp.UnblessedRoot[](0); + OffRamp.UnblessedRoot[] memory rootsToReset = new OffRamp.UnblessedRoot[](0); s_offRamp.resetUnblessedRoots(rootsToReset); } } -contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { +contract OffRamp_verify is OffRampSetup { function setUp() public virtual override { super.setUp(); _setupRealRMN(); @@ -3469,14 +3399,14 @@ contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { bytes32[] memory leaves = new bytes32[](1); leaves[0] = "root"; - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: EVM2EVMMultiOffRamp.Interval(1, 2), + interval: OffRamp.Interval(1, 2), merkleRoot: leaves[0] }); - EVM2EVMMultiOffRamp.CommitReport memory report = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport memory report = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); _commit(report, ++s_latestSequenceNumber); bytes32[] memory proofs = new bytes32[](0); // We have not blessed this root, should return 0. @@ -3487,14 +3417,14 @@ contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { function test_Blessed_Success() public { bytes32[] memory leaves = new bytes32[](1); leaves[0] = "root"; - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: EVM2EVMMultiOffRamp.Interval(1, 2), + interval: OffRamp.Interval(1, 2), merkleRoot: leaves[0] }); - EVM2EVMMultiOffRamp.CommitReport memory report = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport memory report = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); _commit(report, ++s_latestSequenceNumber); // Bless that root. IRMN.TaggedRoot[] memory taggedRoots = new IRMN.TaggedRoot[](1); @@ -3509,15 +3439,15 @@ contract EVM2EVMMultiOffRamp_verify is EVM2EVMMultiOffRampSetup { function test_NotBlessedWrongChainSelector_Success() public { bytes32[] memory leaves = new bytes32[](1); leaves[0] = "root"; - EVM2EVMMultiOffRamp.MerkleRoot[] memory roots = new EVM2EVMMultiOffRamp.MerkleRoot[](1); - roots[0] = EVM2EVMMultiOffRamp.MerkleRoot({ + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); + roots[0] = OffRamp.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: EVM2EVMMultiOffRamp.Interval(1, 2), + interval: OffRamp.Interval(1, 2), merkleRoot: leaves[0] }); - EVM2EVMMultiOffRamp.CommitReport memory report = - EVM2EVMMultiOffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport memory report = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); _commit(report, ++s_latestSequenceNumber); // Bless that root. diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol similarity index 90% rename from contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol rename to contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol index 29864a7071..8156c8c14a 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMMultiOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol @@ -12,20 +12,19 @@ import {Router} from "../../Router.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {MultiOCR3Base} from "../../ocr/MultiOCR3Base.sol"; -import {EVM2EVMMultiOffRamp} from "../../offRamp/EVM2EVMMultiOffRamp.sol"; import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; +import {OffRamp} from "../../offRamp/OffRamp.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; -import {EVM2EVMMultiOffRampHelper} from "../helpers/EVM2EVMMultiOffRampHelper.sol"; import {EVM2EVMOffRampHelper} from "../helpers/EVM2EVMOffRampHelper.sol"; import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; +import {OffRampHelper} from "../helpers/OffRampHelper.sol"; import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; import {MultiOCR3BaseSetup} from "../ocr/MultiOCR3BaseSetup.t.sol"; import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; - import {Vm} from "forge-std/Test.sol"; -contract EVM2EVMMultiOffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { +contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { uint64 internal constant SOURCE_CHAIN_SELECTOR_1 = SOURCE_CHAIN_SELECTOR; uint64 internal constant SOURCE_CHAIN_SELECTOR_2 = 6433500567565415381; uint64 internal constant SOURCE_CHAIN_SELECTOR_3 = 4051577828743386545; @@ -44,7 +43,7 @@ contract EVM2EVMMultiOffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { MaybeRevertingBurnMintTokenPool internal s_maybeRevertingPool; - EVM2EVMMultiOffRampHelper internal s_offRamp; + OffRampHelper internal s_offRamp; MessageInterceptorHelper internal s_inboundMessageValidator; NonceManager internal s_inboundNonceManager; RMN internal s_realRMN; @@ -73,17 +72,16 @@ contract EVM2EVMMultiOffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { } function _deployOffRamp(IRMN rmnProxy, NonceManager nonceManager) internal { - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0); + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](0); - s_offRamp = new EVM2EVMMultiOffRampHelper( - EVM2EVMMultiOffRamp.StaticConfig({ + s_offRamp = new OffRampHelper( + OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, rmnProxy: address(rmnProxy), tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(nonceManager) }), - _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_priceRegistry)), sourceChainConfigs ); @@ -108,7 +106,7 @@ contract EVM2EVMMultiOffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { transmitters: s_validTransmitters }); - s_offRamp.setDynamicConfig(_generateDynamicMultiOffRampConfig(address(s_priceRegistry))); + s_offRamp.setDynamicConfig(_generateDynamicOffRampConfig(address(s_priceRegistry))); s_offRamp.setOCR3Configs(ocrConfigs); address[] memory authorizedCallers = new address[](1); @@ -168,21 +166,20 @@ contract EVM2EVMMultiOffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { } function _setupMultipleOffRamps() internal { - EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](3); - sourceChainConfigs[0] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](3); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, onRamp: ON_RAMP_ADDRESS_1, isEnabled: true }); - sourceChainConfigs[1] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainConfigs[1] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_2, onRamp: ON_RAMP_ADDRESS_2, isEnabled: false }); - sourceChainConfigs[2] = EVM2EVMMultiOffRamp.SourceChainConfigArgs({ + sourceChainConfigs[2] = OffRamp.SourceChainConfigArgs({ router: s_destRouter, sourceChainSelector: SOURCE_CHAIN_SELECTOR_3, onRamp: ON_RAMP_ADDRESS_3, @@ -191,9 +188,7 @@ contract EVM2EVMMultiOffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { _setupMultipleOffRampsFromConfigs(sourceChainConfigs); } - function _setupMultipleOffRampsFromConfigs(EVM2EVMMultiOffRamp.SourceChainConfigArgs[] memory sourceChainConfigs) - internal - { + function _setupMultipleOffRampsFromConfigs(OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs) internal { s_offRamp.applySourceChainConfigUpdates(sourceChainConfigs); Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](0); @@ -228,12 +223,8 @@ contract EVM2EVMMultiOffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { uint32 internal constant MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS = 200_000; uint32 internal constant MAX_TOKEN_POOL_TRANSFER_GAS = 50_000; - function _generateDynamicMultiOffRampConfig(address priceRegistry) - internal - pure - returns (EVM2EVMMultiOffRamp.DynamicConfig memory) - { - return EVM2EVMMultiOffRamp.DynamicConfig({ + function _generateDynamicOffRampConfig(address priceRegistry) internal pure returns (OffRamp.DynamicConfig memory) { + return OffRamp.DynamicConfig({ permissionLessExecutionThresholdSeconds: PERMISSION_LESS_EXECUTION_THRESHOLD_SECONDS, priceRegistry: priceRegistry, messageValidator: address(0), @@ -394,10 +385,7 @@ contract EVM2EVMMultiOffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { return gasLimits; } - function _assertSameConfig( - EVM2EVMMultiOffRamp.DynamicConfig memory a, - EVM2EVMMultiOffRamp.DynamicConfig memory b - ) public pure { + function _assertSameConfig(OffRamp.DynamicConfig memory a, OffRamp.DynamicConfig memory b) public pure { assertEq(a.permissionLessExecutionThresholdSeconds, b.permissionLessExecutionThresholdSeconds); assertEq(a.maxPoolReleaseOrMintGas, b.maxPoolReleaseOrMintGas); assertEq(a.maxTokenTransferGas, b.maxTokenTransferGas); @@ -406,8 +394,8 @@ contract EVM2EVMMultiOffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { } function _assertSourceChainConfigEquality( - EVM2EVMMultiOffRamp.SourceChainConfig memory config1, - EVM2EVMMultiOffRamp.SourceChainConfig memory config2 + OffRamp.SourceChainConfig memory config1, + OffRamp.SourceChainConfig memory config2 ) internal pure { assertEq(config1.isEnabled, config2.isEnabled); assertEq(config1.minSeqNr, config2.minSeqNr); @@ -433,21 +421,21 @@ contract EVM2EVMMultiOffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { } function _enableInboundMessageValidator() internal { - EVM2EVMMultiOffRamp.DynamicConfig memory dynamicConfig = s_offRamp.getDynamicConfig(); + OffRamp.DynamicConfig memory dynamicConfig = s_offRamp.getDynamicConfig(); dynamicConfig.messageValidator = address(s_inboundMessageValidator); s_offRamp.setDynamicConfig(dynamicConfig); } function _redeployOffRampWithNoOCRConfigs() internal { - s_offRamp = new EVM2EVMMultiOffRampHelper( - EVM2EVMMultiOffRamp.StaticConfig({ + s_offRamp = new OffRampHelper( + OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, rmnProxy: address(s_mockRMN), tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicMultiOffRampConfig(address(s_priceRegistry)), - new EVM2EVMMultiOffRamp.SourceChainConfigArgs[](0) + _generateDynamicOffRampConfig(address(s_priceRegistry)), + new OffRamp.SourceChainConfigArgs[](0) ); address[] memory authorizedCallers = new address[](1); @@ -472,7 +460,7 @@ contract EVM2EVMMultiOffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { s_realRMN = new RMN(RMN.Config({voters: voters, blessWeightThreshold: 1, curseWeightThreshold: 1})); } - function _commit(EVM2EVMMultiOffRamp.CommitReport memory commitReport, uint64 sequenceNumber) internal { + function _commit(OffRamp.CommitReport memory commitReport, uint64 sequenceNumber) internal { bytes32[3] memory reportContext = [s_configDigestCommit, bytes32(uint256(sequenceNumber)), s_configDigestCommit]; (bytes32[] memory rs, bytes32[] memory ss,, bytes32 rawVs) = diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol similarity index 79% rename from contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol rename to contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol index cb85896b32..10c0a9f0db 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol @@ -10,104 +10,101 @@ import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {Pool} from "../../libraries/Pool.sol"; import {USDPriceWith18Decimals} from "../../libraries/USDPriceWith18Decimals.sol"; -import {EVM2EVMMultiOnRamp} from "../../onRamp/EVM2EVMMultiOnRamp.sol"; +import {OnRamp} from "../../onRamp/OnRamp.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; -import {EVM2EVMMultiOnRampHelper} from "../helpers/EVM2EVMMultiOnRampHelper.sol"; import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; -import {EVM2EVMMultiOnRampSetup} from "./EVM2EVMMultiOnRampSetup.t.sol"; +import "./OnRampSetup.t.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -contract EVM2EVMMultiOnRamp_constructor is EVM2EVMMultiOnRampSetup { +contract OnRamp_constructor is OnRampSetup { function test_Constructor_Success() public { - EVM2EVMMultiOnRamp.StaticConfig memory staticConfig = EVM2EVMMultiOnRamp.StaticConfig({ + OnRamp.StaticConfig memory staticConfig = OnRamp.StaticConfig({ chainSelector: SOURCE_CHAIN_SELECTOR, rmnProxy: address(s_mockRMN), nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }); - EVM2EVMMultiOnRamp.DynamicConfig memory dynamicConfig = _generateDynamicMultiOnRampConfig(address(s_priceRegistry)); + OnRamp.DynamicConfig memory dynamicConfig = _generateDynamicOnRampConfig(address(s_priceRegistry)); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.ConfigSet(staticConfig, dynamicConfig); + emit OnRamp.ConfigSet(staticConfig, dynamicConfig); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.DestChainConfigSet( - DEST_CHAIN_SELECTOR, EVM2EVMMultiOnRamp.DestChainConfig(0, s_sourceRouter) - ); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, OnRamp.DestChainConfig(0, s_sourceRouter)); _deployOnRamp(SOURCE_CHAIN_SELECTOR, s_sourceRouter, address(s_outboundNonceManager), address(s_tokenAdminRegistry)); - EVM2EVMMultiOnRamp.StaticConfig memory gotStaticConfig = s_onRamp.getStaticConfig(); + OnRamp.StaticConfig memory gotStaticConfig = s_onRamp.getStaticConfig(); _assertStaticConfigsEqual(staticConfig, gotStaticConfig); - EVM2EVMMultiOnRamp.DynamicConfig memory gotDynamicConfig = s_onRamp.getDynamicConfig(); + OnRamp.DynamicConfig memory gotDynamicConfig = s_onRamp.getDynamicConfig(); _assertDynamicConfigsEqual(dynamicConfig, gotDynamicConfig); // Initial values - assertEq("EVM2EVMMultiOnRamp 1.6.0-dev", s_onRamp.typeAndVersion()); + assertEq("OnRamp 1.6.0-dev", s_onRamp.typeAndVersion()); assertEq(OWNER, s_onRamp.owner()); assertEq(1, s_onRamp.getExpectedNextSequenceNumber(DEST_CHAIN_SELECTOR)); assertEq(address(s_sourceRouter), address(s_onRamp.getRouter(DEST_CHAIN_SELECTOR))); } function test_Constructor_InvalidConfigChainSelectorEqZero_Revert() public { - vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); - new EVM2EVMMultiOnRampHelper( - EVM2EVMMultiOnRamp.StaticConfig({ + vm.expectRevert(OnRamp.InvalidConfig.selector); + new OnRampHelper( + OnRamp.StaticConfig({ chainSelector: 0, rmnProxy: address(s_mockRMN), nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - _generateDynamicMultiOnRampConfig(address(s_priceRegistry)), + _generateDynamicOnRampConfig(address(s_priceRegistry)), _generateDestChainConfigArgs(IRouter(address(0))) ); } function test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() public { - vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); - s_onRamp = new EVM2EVMMultiOnRampHelper( - EVM2EVMMultiOnRamp.StaticConfig({ + vm.expectRevert(OnRamp.InvalidConfig.selector); + s_onRamp = new OnRampHelper( + OnRamp.StaticConfig({ chainSelector: SOURCE_CHAIN_SELECTOR, rmnProxy: address(0), nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - _generateDynamicMultiOnRampConfig(address(s_priceRegistry)), + _generateDynamicOnRampConfig(address(s_priceRegistry)), _generateDestChainConfigArgs(IRouter(address(0))) ); } function test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() public { - vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); - new EVM2EVMMultiOnRampHelper( - EVM2EVMMultiOnRamp.StaticConfig({ + vm.expectRevert(OnRamp.InvalidConfig.selector); + new OnRampHelper( + OnRamp.StaticConfig({ chainSelector: SOURCE_CHAIN_SELECTOR, rmnProxy: address(s_mockRMN), nonceManager: address(0), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - _generateDynamicMultiOnRampConfig(address(s_priceRegistry)), + _generateDynamicOnRampConfig(address(s_priceRegistry)), _generateDestChainConfigArgs(IRouter(address(0))) ); } function test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() public { - vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); - new EVM2EVMMultiOnRampHelper( - EVM2EVMMultiOnRamp.StaticConfig({ + vm.expectRevert(OnRamp.InvalidConfig.selector); + new OnRampHelper( + OnRamp.StaticConfig({ chainSelector: SOURCE_CHAIN_SELECTOR, rmnProxy: address(s_mockRMN), nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(0) }), - _generateDynamicMultiOnRampConfig(address(s_priceRegistry)), + _generateDynamicOnRampConfig(address(s_priceRegistry)), _generateDestChainConfigArgs(IRouter(address(0))) ); } } -contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { +contract OnRamp_forwardFromRouter is OnRampSetup { struct LegacyExtraArgs { uint256 gasLimit; bool strict; @@ -133,7 +130,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -152,7 +149,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { // forward fails from wrong router vm.prank(address(s_sourceRouter)); - vm.expectRevert(EVM2EVMMultiOnRamp.MustBeCalledByRouter.selector); + vm.expectRevert(OnRamp.MustBeCalledByRouter.selector); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); // forward succeeds from correct router @@ -169,7 +166,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { vm.expectEmit(); // We expect the message to be emitted with strict = false. - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -182,7 +179,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { vm.expectEmit(); // We expect the message to be emitted with strict = false. - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -194,7 +191,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -208,7 +205,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -222,7 +219,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -235,7 +232,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { uint64 sequenceNumberBefore = s_onRamp.getExpectedNextSequenceNumber(DEST_CHAIN_SELECTOR) - 1; vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, i, i, 0, OWNER)); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, i, i, 0, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); @@ -257,7 +254,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { uint64 sequenceNumberBefore = s_onRamp.getExpectedNextSequenceNumber(DEST_CHAIN_SELECTOR) - 1; vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, i, i, 0, OWNER)); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, i, i, 0, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); @@ -275,7 +272,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.FeePaid(s_sourceFeeToken, feeAmount); + emit OnRamp.FeePaid(s_sourceFeeToken, feeAmount); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); assertEq(IERC20(s_sourceFeeToken).balanceOf(address(s_onRamp)), feeAmount); @@ -295,7 +292,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { uint256 expectedJuels = (feeAmount * conversionRate) / 1e18; vm.expectEmit(); - emit EVM2EVMMultiOnRamp.FeePaid(s_sourceTokens[1], expectedJuels); + emit OnRamp.FeePaid(s_sourceTokens[1], expectedJuels); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); assertEq(IERC20(s_sourceTokens[1]).balanceOf(address(s_onRamp)), feeAmount); @@ -321,9 +318,9 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { Internal.EVM2AnyRampMessage memory expectedEvent = _messageToEvent(message, 1, 1, feeTokenAmount, originalSender); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.FeePaid(s_sourceFeeToken, feeTokenAmount); + emit OnRamp.FeePaid(s_sourceFeeToken, feeTokenAmount); vm.expectEmit(false, false, false, true); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, expectedEvent); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, expectedEvent); // Assert the message Id is correct assertEq( @@ -345,7 +342,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { s_outboundMessageValidator.setMessageIdValidationState(keccak256(abi.encode(message)), false); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -356,8 +353,8 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { // We pause by disabling the whitelist vm.stopPrank(); vm.startPrank(OWNER); - s_onRamp.setDynamicConfig(_generateDynamicMultiOnRampConfig(address(2))); - vm.expectRevert(EVM2EVMMultiOnRamp.MustBeCalledByRouter.selector); + s_onRamp.setDynamicConfig(_generateDynamicOnRampConfig(address(2))); + vm.expectRevert(OnRamp.MustBeCalledByRouter.selector); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, OWNER); } @@ -373,12 +370,12 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { function test_Permissions_Revert() public { vm.stopPrank(); vm.startPrank(OWNER); - vm.expectRevert(EVM2EVMMultiOnRamp.MustBeCalledByRouter.selector); + vm.expectRevert(OnRamp.MustBeCalledByRouter.selector); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, OWNER); } function test_OriginalSender_Revert() public { - vm.expectRevert(EVM2EVMMultiOnRamp.RouterMustSetOriginalSender.selector); + vm.expectRevert(OnRamp.RouterMustSetOriginalSender.selector); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, address(0)); } @@ -406,7 +403,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { message.tokenAmounts = new Client.EVMTokenAmount[](1); message.tokenAmounts[0].amount = 0; message.tokenAmounts[0].token = s_sourceTokens[0]; - vm.expectRevert(EVM2EVMMultiOnRamp.CannotSendZeroTokens.selector); + vm.expectRevert(OnRamp.CannotSendZeroTokens.selector); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, STRANGER); } @@ -428,7 +425,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { // Change back to the router vm.startPrank(address(s_sourceRouter)); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOnRamp.UnsupportedToken.selector, wrongToken)); + vm.expectRevert(abi.encodeWithSelector(OnRamp.UnsupportedToken.selector, wrongToken)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); } @@ -439,7 +436,7 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { message.tokenAmounts[0].amount = 1; message.tokenAmounts[0].token = address(1); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOnRamp.UnsupportedToken.selector, message.tokenAmounts[0].token)); + vm.expectRevert(abi.encodeWithSelector(OnRamp.UnsupportedToken.selector, message.tokenAmounts[0].token)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); } @@ -533,14 +530,14 @@ contract EVM2EVMMultiOnRamp_forwardFromRouter is EVM2EVMMultiOnRampSetup { } } -contract EVM2EVMMultiOnRamp_getSupportedTokens is EVM2EVMMultiOnRampSetup { +contract OnRamp_getSupportedTokens is OnRampSetup { function test_GetSupportedTokens_Revert() public { - vm.expectRevert(EVM2EVMMultiOnRamp.GetSupportedTokensFunctionalityRemovedCheckAdminRegistry.selector); + vm.expectRevert(OnRamp.GetSupportedTokensFunctionalityRemovedCheckAdminRegistry.selector); s_onRamp.getSupportedTokens(DEST_CHAIN_SELECTOR); } } -contract EVM2EVMMultiOnRamp_getFee is EVM2EVMMultiOnRampSetup { +contract OnRamp_getFee is OnRampSetup { using USDPriceWith18Decimals for uint224; function test_EmptyMessage_Success() public view { @@ -578,7 +575,7 @@ contract EVM2EVMMultiOnRamp_getFee is EVM2EVMMultiOnRampSetup { function test_Unhealthy_Revert() public { s_mockRMN.setGlobalCursed(true); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOnRamp.CursedByRMN.selector, DEST_CHAIN_SELECTOR)); + vm.expectRevert(abi.encodeWithSelector(OnRamp.CursedByRMN.selector, DEST_CHAIN_SELECTOR)); s_onRamp.getFee(DEST_CHAIN_SELECTOR, _generateEmptyMessage()); } @@ -601,71 +598,65 @@ contract EVM2EVMMultiOnRamp_getFee is EVM2EVMMultiOnRampSetup { } } -contract EVM2EVMMultiOnRamp_setDynamicConfig is EVM2EVMMultiOnRampSetup { +contract OnRamp_setDynamicConfig is OnRampSetup { function test_SetDynamicConfig_Success() public { - EVM2EVMMultiOnRamp.StaticConfig memory staticConfig = s_onRamp.getStaticConfig(); - EVM2EVMMultiOnRamp.DynamicConfig memory newConfig = EVM2EVMMultiOnRamp.DynamicConfig({ + OnRamp.StaticConfig memory staticConfig = s_onRamp.getStaticConfig(); + OnRamp.DynamicConfig memory newConfig = OnRamp.DynamicConfig({ priceRegistry: address(23423), messageValidator: makeAddr("messageValidator"), feeAggregator: FEE_AGGREGATOR }); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.ConfigSet(staticConfig, newConfig); + emit OnRamp.ConfigSet(staticConfig, newConfig); s_onRamp.setDynamicConfig(newConfig); - EVM2EVMMultiOnRamp.DynamicConfig memory gotDynamicConfig = s_onRamp.getDynamicConfig(); + OnRamp.DynamicConfig memory gotDynamicConfig = s_onRamp.getDynamicConfig(); assertEq(newConfig.priceRegistry, gotDynamicConfig.priceRegistry); } // Reverts function test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() public { - EVM2EVMMultiOnRamp.DynamicConfig memory newConfig = EVM2EVMMultiOnRamp.DynamicConfig({ + OnRamp.DynamicConfig memory newConfig = OnRamp.DynamicConfig({ priceRegistry: address(0), feeAggregator: FEE_AGGREGATOR, messageValidator: makeAddr("messageValidator") }); - vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); + vm.expectRevert(OnRamp.InvalidConfig.selector); s_onRamp.setDynamicConfig(newConfig); } function test_SetConfigInvalidConfig_Revert() public { - EVM2EVMMultiOnRamp.DynamicConfig memory newConfig = EVM2EVMMultiOnRamp.DynamicConfig({ - priceRegistry: address(23423), - messageValidator: address(0), - feeAggregator: FEE_AGGREGATOR - }); + OnRamp.DynamicConfig memory newConfig = + OnRamp.DynamicConfig({priceRegistry: address(23423), messageValidator: address(0), feeAggregator: FEE_AGGREGATOR}); // Invalid price reg reverts. newConfig.priceRegistry = address(0); - vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); + vm.expectRevert(OnRamp.InvalidConfig.selector); s_onRamp.setDynamicConfig(newConfig); } function test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() public { - EVM2EVMMultiOnRamp.DynamicConfig memory newConfig = EVM2EVMMultiOnRamp.DynamicConfig({ - priceRegistry: address(23423), - messageValidator: address(0), - feeAggregator: address(0) - }); - vm.expectRevert(EVM2EVMMultiOnRamp.InvalidConfig.selector); + OnRamp.DynamicConfig memory newConfig = + OnRamp.DynamicConfig({priceRegistry: address(23423), messageValidator: address(0), feeAggregator: address(0)}); + vm.expectRevert(OnRamp.InvalidConfig.selector); s_onRamp.setDynamicConfig(newConfig); } function test_SetConfigOnlyOwner_Revert() public { vm.startPrank(STRANGER); vm.expectRevert("Only callable by owner"); - s_onRamp.setDynamicConfig(_generateDynamicMultiOnRampConfig(address(2))); + s_onRamp.setDynamicConfig(_generateDynamicOnRampConfig(address(2))); vm.startPrank(ADMIN); vm.expectRevert("Only callable by owner"); - s_onRamp.setDynamicConfig(_generateDynamicMultiOnRampConfig(address(2))); + s_onRamp.setDynamicConfig(_generateDynamicOnRampConfig(address(2))); } } -contract EVM2EVMMultiOnRamp_withdrawFeeTokens is EVM2EVMMultiOnRampSetup { +contract OnRamp_withdrawFeeTokens is OnRampSetup { mapping(address => uint256) internal s_nopFees; function setUp() public virtual override { @@ -702,7 +693,7 @@ contract EVM2EVMMultiOnRamp_withdrawFeeTokens is EVM2EVMMultiOnRampSetup { for (uint256 i = 0; i < feeTokens.length; ++i) { vm.expectEmit(); - emit EVM2EVMMultiOnRamp.FeeTokenWithdrawn(FEE_AGGREGATOR, feeTokens[i], amounts[i]); + emit OnRamp.FeeTokenWithdrawn(FEE_AGGREGATOR, feeTokens[i], amounts[i]); } s_onRamp.withdrawFeeTokens(); @@ -715,7 +706,7 @@ contract EVM2EVMMultiOnRamp_withdrawFeeTokens is EVM2EVMMultiOnRampSetup { function test_WithdrawFeeTokens_Success() public { vm.expectEmit(); - emit EVM2EVMMultiOnRamp.FeeTokenWithdrawn(FEE_AGGREGATOR, s_sourceFeeToken, s_nopFees[s_sourceFeeToken]); + emit OnRamp.FeeTokenWithdrawn(FEE_AGGREGATOR, s_sourceFeeToken, s_nopFees[s_sourceFeeToken]); s_onRamp.withdrawFeeTokens(); @@ -724,7 +715,7 @@ contract EVM2EVMMultiOnRamp_withdrawFeeTokens is EVM2EVMMultiOnRampSetup { } } -contract EVM2EVMMultiOnRamp_getTokenPool is EVM2EVMMultiOnRampSetup { +contract OnRamp_getTokenPool is OnRampSetup { function test_GetTokenPool_Success() public view { assertEq( s_sourcePoolByToken[s_sourceTokens[0]], @@ -742,39 +733,34 @@ contract EVM2EVMMultiOnRamp_getTokenPool is EVM2EVMMultiOnRampSetup { } } -contract EVM2EVMMultiOnRamp_applyDestChainConfigUpdates is EVM2EVMMultiOnRampSetup { +contract OnRamp_applyDestChainConfigUpdates is OnRampSetup { function test_ApplyDestChainConfigUpdates_Success() external { vm.stopPrank(); vm.startPrank(OWNER); - EVM2EVMMultiOnRamp.DestChainConfigArgs[] memory configArgs = new EVM2EVMMultiOnRamp.DestChainConfigArgs[](1); + OnRamp.DestChainConfigArgs[] memory configArgs = new OnRamp.DestChainConfigArgs[](1); configArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; // supports disabling a lane by setting a router to zero vm.expectEmit(); - emit EVM2EVMMultiOnRamp.DestChainConfigSet( - DEST_CHAIN_SELECTOR, EVM2EVMMultiOnRamp.DestChainConfig(0, IRouter(address(0))) - ); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, OnRamp.DestChainConfig(0, IRouter(address(0)))); s_onRamp.applyDestChainConfigUpdates(configArgs); assertEq(address(0), address(s_onRamp.getRouter(DEST_CHAIN_SELECTOR))); // supports updating and adding lanes simultaneously - configArgs = new EVM2EVMMultiOnRamp.DestChainConfigArgs[](2); - configArgs[0] = - EVM2EVMMultiOnRamp.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, router: s_sourceRouter}); - configArgs[1] = EVM2EVMMultiOnRamp.DestChainConfigArgs({destChainSelector: 9999, router: IRouter(address(9999))}); + configArgs = new OnRamp.DestChainConfigArgs[](2); + configArgs[0] = OnRamp.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, router: s_sourceRouter}); + configArgs[1] = OnRamp.DestChainConfigArgs({destChainSelector: 9999, router: IRouter(address(9999))}); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.DestChainConfigSet( - DEST_CHAIN_SELECTOR, EVM2EVMMultiOnRamp.DestChainConfig(0, s_sourceRouter) - ); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, OnRamp.DestChainConfig(0, s_sourceRouter)); vm.expectEmit(); - emit EVM2EVMMultiOnRamp.DestChainConfigSet(9999, EVM2EVMMultiOnRamp.DestChainConfig(0, IRouter(address(9999)))); + emit OnRamp.DestChainConfigSet(9999, OnRamp.DestChainConfig(0, IRouter(address(9999)))); s_onRamp.applyDestChainConfigUpdates(configArgs); assertEq(address(s_sourceRouter), address(s_onRamp.getRouter(DEST_CHAIN_SELECTOR))); assertEq(address(9999), address(s_onRamp.getRouter(9999))); // handles empty list uint256 numLogs = vm.getRecordedLogs().length; - configArgs = new EVM2EVMMultiOnRamp.DestChainConfigArgs[](0); + configArgs = new OnRamp.DestChainConfigArgs[](0); s_onRamp.applyDestChainConfigUpdates(configArgs); assertEq(numLogs, vm.getRecordedLogs().length); // indicates no changes made } @@ -782,9 +768,9 @@ contract EVM2EVMMultiOnRamp_applyDestChainConfigUpdates is EVM2EVMMultiOnRampSet function test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() external { vm.stopPrank(); vm.startPrank(OWNER); - EVM2EVMMultiOnRamp.DestChainConfigArgs[] memory configArgs = new EVM2EVMMultiOnRamp.DestChainConfigArgs[](1); + OnRamp.DestChainConfigArgs[] memory configArgs = new OnRamp.DestChainConfigArgs[](1); configArgs[0].destChainSelector = 0; // invalid - vm.expectRevert(abi.encodeWithSelector(EVM2EVMMultiOnRamp.InvalidDestChainConfig.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(OnRamp.InvalidDestChainConfig.selector, 0)); s_onRamp.applyDestChainConfigUpdates(configArgs); } } diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol similarity index 75% rename from contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol rename to contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol index 66daefedd3..a8d1919948 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMMultiOnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol @@ -8,20 +8,20 @@ import {NonceManager} from "../../NonceManager.sol"; import {Router} from "../../Router.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; -import {EVM2EVMMultiOnRamp} from "../../onRamp/EVM2EVMMultiOnRamp.sol"; -import {EVM2EVMMultiOnRampHelper} from "../helpers/EVM2EVMMultiOnRampHelper.sol"; +import {OnRamp} from "../../onRamp/OnRamp.sol"; import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; -import {PriceRegistryFeeSetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; +import {OnRampHelper} from "../helpers/OnRampHelper.sol"; +import {PriceRegistryFeeSetup} from "../priceRegistry/PriceRegistry.t.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -contract EVM2EVMMultiOnRampSetup is PriceRegistryFeeSetup { +contract OnRampSetup is PriceRegistryFeeSetup { uint256 internal immutable i_tokenAmount0 = 9; uint256 internal immutable i_tokenAmount1 = 7; bytes32 internal s_metadataHash; - EVM2EVMMultiOnRampHelper internal s_onRamp; + OnRampHelper internal s_onRamp; MessageInterceptorHelper internal s_outboundMessageValidator; address[] internal s_offRamps; NonceManager internal s_outboundNonceManager; @@ -84,16 +84,9 @@ contract EVM2EVMMultiOnRampSetup is PriceRegistryFeeSetup { ); } - function _generateDynamicMultiOnRampConfig(address priceRegistry) - internal - pure - returns (EVM2EVMMultiOnRamp.DynamicConfig memory) - { - return EVM2EVMMultiOnRamp.DynamicConfig({ - priceRegistry: priceRegistry, - messageValidator: address(0), - feeAggregator: FEE_AGGREGATOR - }); + function _generateDynamicOnRampConfig(address priceRegistry) internal pure returns (OnRamp.DynamicConfig memory) { + return + OnRamp.DynamicConfig({priceRegistry: priceRegistry, messageValidator: address(0), feeAggregator: FEE_AGGREGATOR}); } // Slicing is only available for calldata. So we have to build a new bytes array. @@ -105,14 +98,9 @@ contract EVM2EVMMultiOnRampSetup is PriceRegistryFeeSetup { return result; } - function _generateDestChainConfigArgs(IRouter router) - internal - pure - returns (EVM2EVMMultiOnRamp.DestChainConfigArgs[] memory) - { - EVM2EVMMultiOnRamp.DestChainConfigArgs[] memory destChainConfigs = new EVM2EVMMultiOnRamp.DestChainConfigArgs[](1); - destChainConfigs[0] = - EVM2EVMMultiOnRamp.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, router: router}); + function _generateDestChainConfigArgs(IRouter router) internal pure returns (OnRamp.DestChainConfigArgs[] memory) { + OnRamp.DestChainConfigArgs[] memory destChainConfigs = new OnRamp.DestChainConfigArgs[](1); + destChainConfigs[0] = OnRamp.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, router: router}); return destChainConfigs; } @@ -121,15 +109,15 @@ contract EVM2EVMMultiOnRampSetup is PriceRegistryFeeSetup { IRouter router, address nonceManager, address tokenAdminRegistry - ) internal returns (EVM2EVMMultiOnRampHelper, bytes32 metadataHash) { - EVM2EVMMultiOnRampHelper onRamp = new EVM2EVMMultiOnRampHelper( - EVM2EVMMultiOnRamp.StaticConfig({ + ) internal returns (OnRampHelper, bytes32 metadataHash) { + OnRampHelper onRamp = new OnRampHelper( + OnRamp.StaticConfig({ chainSelector: sourceChainSelector, rmnProxy: address(s_mockRMN), nonceManager: nonceManager, tokenAdminRegistry: tokenAdminRegistry }), - _generateDynamicMultiOnRampConfig(address(s_priceRegistry)), + _generateDynamicOnRampConfig(address(s_priceRegistry)), _generateDestChainConfigArgs(router) ); @@ -157,7 +145,7 @@ contract EVM2EVMMultiOnRampSetup is PriceRegistryFeeSetup { resetPrank = true; } - EVM2EVMMultiOnRamp.DynamicConfig memory dynamicConfig = s_onRamp.getDynamicConfig(); + OnRamp.DynamicConfig memory dynamicConfig = s_onRamp.getDynamicConfig(); dynamicConfig.messageValidator = address(s_outboundMessageValidator); s_onRamp.setDynamicConfig(dynamicConfig); @@ -167,19 +155,13 @@ contract EVM2EVMMultiOnRampSetup is PriceRegistryFeeSetup { } } - function _assertStaticConfigsEqual( - EVM2EVMMultiOnRamp.StaticConfig memory a, - EVM2EVMMultiOnRamp.StaticConfig memory b - ) internal pure { + function _assertStaticConfigsEqual(OnRamp.StaticConfig memory a, OnRamp.StaticConfig memory b) internal pure { assertEq(a.chainSelector, b.chainSelector); assertEq(a.rmnProxy, b.rmnProxy); assertEq(a.tokenAdminRegistry, b.tokenAdminRegistry); } - function _assertDynamicConfigsEqual( - EVM2EVMMultiOnRamp.DynamicConfig memory a, - EVM2EVMMultiOnRamp.DynamicConfig memory b - ) internal pure { + function _assertDynamicConfigsEqual(OnRamp.DynamicConfig memory a, OnRamp.DynamicConfig memory b) internal pure { assertEq(a.priceRegistry, b.priceRegistry); } } diff --git a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go index e0de0b801d..03c1416b4b 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go @@ -70,7 +70,7 @@ func TestCCIPReader_CommitReportsGTETimestamp(t *testing.T) { const numReports = 5 for i := uint8(0); i < numReports; i++ { - _, err := s.contract.EmitCommitReportAccepted(s.auth, ccip_reader_tester.EVM2EVMMultiOffRampCommitReport{ + _, err := s.contract.EmitCommitReportAccepted(s.auth, ccip_reader_tester.OffRampCommitReport{ PriceUpdates: ccip_reader_tester.InternalPriceUpdates{ TokenPriceUpdates: []ccip_reader_tester.InternalTokenPriceUpdate{ { @@ -85,10 +85,10 @@ func TestCCIPReader_CommitReportsGTETimestamp(t *testing.T) { }, }, }, - MerkleRoots: []ccip_reader_tester.EVM2EVMMultiOffRampMerkleRoot{ + MerkleRoots: []ccip_reader_tester.OffRampMerkleRoot{ { SourceChainSelector: uint64(chainS1), - Interval: ccip_reader_tester.EVM2EVMMultiOffRampInterval{ + Interval: ccip_reader_tester.OffRampInterval{ Min: 10, Max: 20, }, @@ -359,7 +359,7 @@ func testSetup(ctx context.Context, t *testing.T, readerChain, destChain cciptyp assert.NoError(t, lp.Start(ctx)) for sourceChain, seqNum := range onChainSeqNums { - _, err1 := contract.SetSourceChainConfig(auth, uint64(sourceChain), ccip_reader_tester.EVM2EVMMultiOffRampSourceChainConfig{ + _, err1 := contract.SetSourceChainConfig(auth, uint64(sourceChain), ccip_reader_tester.OffRampSourceChainConfig{ IsEnabled: true, MinSeqNr: uint64(seqNum), }) diff --git a/core/capabilities/ccip/ccip_integration_tests/helpers.go b/core/capabilities/ccip/ccip_integration_tests/helpers.go index 7792dfd361..11c8d96800 100644 --- a/core/capabilities/ccip/ccip_integration_tests/helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/helpers.go @@ -24,15 +24,15 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ocr3_config_encoder" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" @@ -47,9 +47,9 @@ import ( var ( homeChainID = chainsel.GETH_TESTNET.EvmChainID - ccipSendRequestedTopic = evm_2_evm_multi_onramp.EVM2EVMMultiOnRampCCIPSendRequested{}.Topic() - commitReportAcceptedTopic = evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReportAccepted{}.Topic() - executionStateChangedTopic = evm_2_evm_multi_offramp.EVM2EVMMultiOffRampExecutionStateChanged{}.Topic() + ccipSendRequestedTopic = onramp.OnRampCCIPSendRequested{}.Topic() + commitReportAcceptedTopic = offramp.OffRampCommitReportAccepted{}.Topic() + executionStateChangedTopic = offramp.OffRampExecutionStateChanged{}.Topic() ) const ( @@ -102,10 +102,10 @@ type onchainUniverse struct { linkToken *link_token.LinkToken weth *weth9.WETH9 router *router.Router - rmnProxy *arm_proxy_contract.ARMProxyContract - rmn *mock_arm_contract.MockARMContract - onramp *evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp - offramp *evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp + rmnProxy *rmn_proxy_contract.RMNProxyContract + rmn *mock_rmn_contract.MockRMNContract + onramp *onramp.OnRamp + offramp *offramp.OffRamp priceRegistry *price_registry.PriceRegistry tokenAdminRegistry *token_admin_registry.TokenAdminRegistry nonceManager *nonce_manager.NonceManager @@ -179,8 +179,8 @@ func createUniverses( backend := base.backend // deploy the CCIP contracts linkToken := deployLinkToken(t, owner, backend, chainID) - rmn := deployMockARMContract(t, owner, backend, chainID) - rmnProxy := deployARMProxyContract(t, owner, backend, rmn.Address(), chainID) + rmn := deployMockRMNContract(t, owner, backend, chainID) + rmnProxy := deployRMNProxyContract(t, owner, backend, rmn.Address(), chainID) weth := deployWETHContract(t, owner, backend, chainID) rout := deployRouter(t, owner, backend, weth.Address(), rmnProxy.Address(), chainID) priceRegistry := deployPriceRegistry(t, owner, backend, linkToken.Address(), weth.Address(), big.NewInt(1e18), chainID) @@ -190,50 +190,50 @@ func createUniverses( // ====================================================================== // OnRamp // ====================================================================== - onRampAddr, _, _, err := evm_2_evm_multi_onramp.DeployEVM2EVMMultiOnRamp( + onRampAddr, _, _, err := onramp.DeployOnRamp( owner, backend, - evm_2_evm_multi_onramp.EVM2EVMMultiOnRampStaticConfig{ + onramp.OnRampStaticConfig{ ChainSelector: getSelector(chainID), RmnProxy: rmnProxy.Address(), NonceManager: nonceManager.Address(), TokenAdminRegistry: tokenAdminRegistry.Address(), }, - evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDynamicConfig{ + onramp.OnRampDynamicConfig{ PriceRegistry: priceRegistry.Address(), // `withdrawFeeTokens` onRamp function is not part of the message flow // so we can set this to any address FeeAggregator: testutils.NewAddress(), }, // Destination chain configs will be set up later once we have all chains - []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs{}, + []onramp.OnRampDestChainConfigArgs{}, ) require.NoErrorf(t, err, "failed to deploy onramp on chain id %d", chainID) backend.Commit() - onramp, err := evm_2_evm_multi_onramp.NewEVM2EVMMultiOnRamp(onRampAddr, backend) + onramp, err := onramp.NewOnRamp(onRampAddr, backend) require.NoError(t, err) // ====================================================================== // OffRamp // ====================================================================== - offrampAddr, _, _, err := evm_2_evm_multi_offramp.DeployEVM2EVMMultiOffRamp( + offrampAddr, _, _, err := offramp.DeployOffRamp( owner, backend, - evm_2_evm_multi_offramp.EVM2EVMMultiOffRampStaticConfig{ + offramp.OffRampStaticConfig{ ChainSelector: getSelector(chainID), RmnProxy: rmnProxy.Address(), TokenAdminRegistry: tokenAdminRegistry.Address(), NonceManager: nonceManager.Address(), }, - evm_2_evm_multi_offramp.EVM2EVMMultiOffRampDynamicConfig{ + offramp.OffRampDynamicConfig{ PriceRegistry: priceRegistry.Address(), }, // Source chain configs will be set up later once we have all chains - []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{}, + []offramp.OffRampSourceChainConfigArgs{}, ) require.NoErrorf(t, err, "failed to deploy offramp on chain id %d", chainID) backend.Commit() - offramp, err := evm_2_evm_multi_offramp.NewEVM2EVMMultiOffRamp(offrampAddr, backend) + offramp, err := offramp.NewOffRamp(offrampAddr, backend) require.NoError(t, err) receiverAddress, _, _, err := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver( @@ -582,14 +582,14 @@ func (h *homeChain) AddDON( } // get the config digest from the ccip config contract and set config on the offramp. - var offrampOCR3Configs []evm_2_evm_multi_offramp.MultiOCR3BaseOCRConfigArgs + var offrampOCR3Configs []offramp.MultiOCR3BaseOCRConfigArgs for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { ocrConfig, err1 := h.ccipConfig.GetOCRConfig(&bind.CallOpts{ Context: testutils.Context(t), }, donID, uint8(pluginType)) require.NoError(t, err1, "failed to get OCR3 config from ccip config contract") require.Len(t, ocrConfig, 1, "expected exactly one OCR3 config") - offrampOCR3Configs = append(offrampOCR3Configs, evm_2_evm_multi_offramp.MultiOCR3BaseOCRConfigArgs{ + offrampOCR3Configs = append(offrampOCR3Configs, offramp.MultiOCR3BaseOCRConfigArgs{ ConfigDigest: ocrConfig[0].ConfigDigest, OcrPluginType: uint8(pluginType), F: f, @@ -747,12 +747,12 @@ func wirePriceRegistry(t *testing.T, uni onchainUniverse, universes map[uint64]o // Setting OnRampDestChainConfigs func wireOnRamp(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { owner := uni.owner - var onrampSourceChainConfigArgs []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs + var onrampSourceChainConfigArgs []onramp.OnRampDestChainConfigArgs for remoteChainID := range universes { if remoteChainID == uni.chainID { continue } - onrampSourceChainConfigArgs = append(onrampSourceChainConfigArgs, evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs{ + onrampSourceChainConfigArgs = append(onrampSourceChainConfigArgs, onramp.OnRampDestChainConfigArgs{ DestChainSelector: getSelector(remoteChainID), Router: uni.router.Address(), }) @@ -765,12 +765,12 @@ func wireOnRamp(t *testing.T, uni onchainUniverse, universes map[uint64]onchainU // Setting OffRampSourceChainConfigs func wireOffRamp(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { owner := uni.owner - var offrampSourceChainConfigArgs []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs + var offrampSourceChainConfigArgs []offramp.OffRampSourceChainConfigArgs for remoteChainID, remoteUniverse := range universes { if remoteChainID == uni.chainID { continue } - offrampSourceChainConfigArgs = append(offrampSourceChainConfigArgs, evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{ + offrampSourceChainConfigArgs = append(offrampSourceChainConfigArgs, offramp.OffRampSourceChainConfigArgs{ SourceChainSelector: getSelector(remoteChainID), IsEnabled: true, Router: uni.router.Address(), @@ -858,20 +858,20 @@ func deployLinkToken(t *testing.T, owner *bind.TransactOpts, backend *backends.S return linkToken } -func deployMockARMContract(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, chainID uint64) *mock_arm_contract.MockARMContract { - rmnAddr, _, _, err := mock_arm_contract.DeployMockARMContract(owner, backend) +func deployMockRMNContract(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, chainID uint64) *mock_rmn_contract.MockRMNContract { + rmnAddr, _, _, err := mock_rmn_contract.DeployMockRMNContract(owner, backend) require.NoErrorf(t, err, "failed to deploy mock arm on chain id %d", chainID) backend.Commit() - rmn, err := mock_arm_contract.NewMockARMContract(rmnAddr, backend) + rmn, err := mock_rmn_contract.NewMockRMNContract(rmnAddr, backend) require.NoError(t, err) return rmn } -func deployARMProxyContract(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, rmnAddr common.Address, chainID uint64) *arm_proxy_contract.ARMProxyContract { - rmnProxyAddr, _, _, err := arm_proxy_contract.DeployARMProxyContract(owner, backend, rmnAddr) +func deployRMNProxyContract(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, rmnAddr common.Address, chainID uint64) *rmn_proxy_contract.RMNProxyContract { + rmnProxyAddr, _, _, err := rmn_proxy_contract.DeployRMNProxyContract(owner, backend, rmnAddr) require.NoErrorf(t, err, "failed to deploy arm proxy on chain id %d", chainID) backend.Commit() - rmnProxy, err := arm_proxy_contract.NewARMProxyContract(rmnProxyAddr, backend) + rmnProxy, err := rmn_proxy_contract.NewRMNProxyContract(rmnProxyAddr, backend) require.NoError(t, err) return rmnProxy } diff --git a/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go b/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go index ae04da0fc1..5914db8082 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go @@ -12,7 +12,7 @@ import ( "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" @@ -226,7 +226,7 @@ func waitForCommitWithInterval( expectedSourceChainSelector uint64, expectedSeqNumRange ccipocr3.SeqNumRange, ) { - sink := make(chan *evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReportAccepted) + sink := make(chan *offramp.OffRampCommitReportAccepted) subscription, err := uni.offramp.WatchCommitReportAccepted(&bind.WatchOpts{ Context: testutils.Context(t), }, sink) diff --git a/core/capabilities/ccip/ccipevm/commitcodec.go b/core/capabilities/ccip/ccipevm/commitcodec.go index 928cecd0a4..2346c9f141 100644 --- a/core/capabilities/ccip/ccipevm/commitcodec.go +++ b/core/capabilities/ccip/ccipevm/commitcodec.go @@ -11,19 +11,19 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/types" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ) // CommitPluginCodecV1 is a codec for encoding and decoding commit plugin reports. // Compatible with: -// - "EVM2EVMMultiOffRamp 1.6.0-dev" +// - "OffRamp 1.6.0-dev" type CommitPluginCodecV1 struct { commitReportAcceptedEventInputs abi.Arguments } func NewCommitPluginCodecV1() *CommitPluginCodecV1 { - abiParsed, err := abi.JSON(strings.NewReader(evm_2_evm_multi_offramp.EVM2EVMMultiOffRampABI)) + abiParsed, err := abi.JSON(strings.NewReader(offramp.OffRampABI)) if err != nil { panic(fmt.Errorf("parse multi offramp abi: %s", err)) } @@ -32,11 +32,11 @@ func NewCommitPluginCodecV1() *CommitPluginCodecV1 { } func (c *CommitPluginCodecV1) Encode(ctx context.Context, report cciptypes.CommitPluginReport) ([]byte, error) { - merkleRoots := make([]evm_2_evm_multi_offramp.EVM2EVMMultiOffRampMerkleRoot, 0, len(report.MerkleRoots)) + merkleRoots := make([]offramp.OffRampMerkleRoot, 0, len(report.MerkleRoots)) for _, root := range report.MerkleRoots { - merkleRoots = append(merkleRoots, evm_2_evm_multi_offramp.EVM2EVMMultiOffRampMerkleRoot{ + merkleRoots = append(merkleRoots, offramp.OffRampMerkleRoot{ SourceChainSelector: uint64(root.ChainSel), - Interval: evm_2_evm_multi_offramp.EVM2EVMMultiOffRampInterval{ + Interval: offramp.OffRampInterval{ Min: uint64(root.SeqNumsRange.Start()), Max: uint64(root.SeqNumsRange.End()), }, @@ -44,7 +44,7 @@ func (c *CommitPluginCodecV1) Encode(ctx context.Context, report cciptypes.Commi }) } - tokenPriceUpdates := make([]evm_2_evm_multi_offramp.InternalTokenPriceUpdate, 0, len(report.PriceUpdates.TokenPriceUpdates)) + tokenPriceUpdates := make([]offramp.InternalTokenPriceUpdate, 0, len(report.PriceUpdates.TokenPriceUpdates)) for _, update := range report.PriceUpdates.TokenPriceUpdates { if !common.IsHexAddress(string(update.TokenID)) { return nil, fmt.Errorf("invalid token address: %s", update.TokenID) @@ -52,26 +52,26 @@ func (c *CommitPluginCodecV1) Encode(ctx context.Context, report cciptypes.Commi if update.Price.IsEmpty() { return nil, fmt.Errorf("empty price for token: %s", update.TokenID) } - tokenPriceUpdates = append(tokenPriceUpdates, evm_2_evm_multi_offramp.InternalTokenPriceUpdate{ + tokenPriceUpdates = append(tokenPriceUpdates, offramp.InternalTokenPriceUpdate{ SourceToken: common.HexToAddress(string(update.TokenID)), UsdPerToken: update.Price.Int, }) } - gasPriceUpdates := make([]evm_2_evm_multi_offramp.InternalGasPriceUpdate, 0, len(report.PriceUpdates.GasPriceUpdates)) + gasPriceUpdates := make([]offramp.InternalGasPriceUpdate, 0, len(report.PriceUpdates.GasPriceUpdates)) for _, update := range report.PriceUpdates.GasPriceUpdates { if update.GasPrice.IsEmpty() { return nil, fmt.Errorf("empty gas price for chain: %d", update.ChainSel) } - gasPriceUpdates = append(gasPriceUpdates, evm_2_evm_multi_offramp.InternalGasPriceUpdate{ + gasPriceUpdates = append(gasPriceUpdates, offramp.InternalGasPriceUpdate{ DestChainSelector: uint64(update.ChainSel), UsdPerUnitGas: update.GasPrice.Int, }) } - evmReport := evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReport{ - PriceUpdates: evm_2_evm_multi_offramp.InternalPriceUpdates{ + evmReport := offramp.OffRampCommitReport{ + PriceUpdates: offramp.InternalPriceUpdates{ TokenPriceUpdates: tokenPriceUpdates, GasPriceUpdates: gasPriceUpdates, }, @@ -90,11 +90,11 @@ func (c *CommitPluginCodecV1) Decode(ctx context.Context, bytes []byte) (cciptyp return cciptypes.CommitPluginReport{}, fmt.Errorf("expected 1 argument, got %d", len(unpacked)) } - commitReportRaw := abi.ConvertType(unpacked[0], new(evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReport)) - commitReport, is := commitReportRaw.(*evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReport) + commitReportRaw := abi.ConvertType(unpacked[0], new(offramp.OffRampCommitReport)) + commitReport, is := commitReportRaw.(*offramp.OffRampCommitReport) if !is { return cciptypes.CommitPluginReport{}, - fmt.Errorf("expected EVM2EVMMultiOffRampCommitReport, got %T", unpacked[0]) + fmt.Errorf("expected OffRampCommitReport, got %T", unpacked[0]) } merkleRoots := make([]cciptypes.MerkleRootChain, 0, len(commitReport.MerkleRoots)) diff --git a/core/capabilities/ccip/ccipevm/executecodec.go b/core/capabilities/ccip/ccipevm/executecodec.go index a64c775112..2349beb390 100644 --- a/core/capabilities/ccip/ccipevm/executecodec.go +++ b/core/capabilities/ccip/ccipevm/executecodec.go @@ -10,19 +10,19 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ) // ExecutePluginCodecV1 is a codec for encoding and decoding execute plugin reports. // Compatible with: -// - "EVM2EVMMultiOffRamp 1.6.0-dev" +// - "OffRamp 1.6.0-dev" type ExecutePluginCodecV1 struct { executeReportMethodInputs abi.Arguments } func NewExecutePluginCodecV1() *ExecutePluginCodecV1 { - abiParsed, err := abi.JSON(strings.NewReader(evm_2_evm_multi_offramp.EVM2EVMMultiOffRampABI)) + abiParsed, err := abi.JSON(strings.NewReader(offramp.OffRampABI)) if err != nil { panic(fmt.Errorf("parse multi offramp abi: %s", err)) } @@ -37,7 +37,7 @@ func NewExecutePluginCodecV1() *ExecutePluginCodecV1 { } func (e *ExecutePluginCodecV1) Encode(ctx context.Context, report cciptypes.ExecutePluginReport) ([]byte, error) { - evmReport := make([]evm_2_evm_multi_offramp.InternalExecutionReportSingleChain, 0, len(report.ChainReports)) + evmReport := make([]offramp.InternalExecutionReportSingleChain, 0, len(report.ChainReports)) for _, chainReport := range report.ChainReports { if chainReport.ProofFlagBits.IsEmpty() { @@ -49,17 +49,17 @@ func (e *ExecutePluginCodecV1) Encode(ctx context.Context, report cciptypes.Exec evmProofs = append(evmProofs, proof) } - evmMessages := make([]evm_2_evm_multi_offramp.InternalAny2EVMRampMessage, 0, len(chainReport.Messages)) + evmMessages := make([]offramp.InternalAny2EVMRampMessage, 0, len(chainReport.Messages)) for _, message := range chainReport.Messages { receiver := common.BytesToAddress(message.Receiver) - tokenAmounts := make([]evm_2_evm_multi_offramp.InternalRampTokenAmount, 0, len(message.TokenAmounts)) + tokenAmounts := make([]offramp.InternalRampTokenAmount, 0, len(message.TokenAmounts)) for _, tokenAmount := range message.TokenAmounts { if tokenAmount.Amount.IsEmpty() { return nil, fmt.Errorf("empty amount for token: %s", tokenAmount.DestTokenAddress) } - tokenAmounts = append(tokenAmounts, evm_2_evm_multi_offramp.InternalRampTokenAmount{ + tokenAmounts = append(tokenAmounts, offramp.InternalRampTokenAmount{ SourcePoolAddress: tokenAmount.SourcePoolAddress, DestTokenAddress: tokenAmount.DestTokenAddress, ExtraData: tokenAmount.ExtraData, @@ -72,8 +72,8 @@ func (e *ExecutePluginCodecV1) Encode(ctx context.Context, report cciptypes.Exec return nil, fmt.Errorf("decode extra args to get gas limit: %w", err) } - evmMessages = append(evmMessages, evm_2_evm_multi_offramp.InternalAny2EVMRampMessage{ - Header: evm_2_evm_multi_offramp.InternalRampMessageHeader{ + evmMessages = append(evmMessages, offramp.InternalAny2EVMRampMessage{ + Header: offramp.InternalRampMessageHeader{ MessageId: message.Header.MessageID, SourceChainSelector: uint64(message.Header.SourceChainSelector), DestChainSelector: uint64(message.Header.DestChainSelector), @@ -88,7 +88,7 @@ func (e *ExecutePluginCodecV1) Encode(ctx context.Context, report cciptypes.Exec }) } - evmChainReport := evm_2_evm_multi_offramp.InternalExecutionReportSingleChain{ + evmChainReport := offramp.InternalExecutionReportSingleChain{ SourceChainSelector: uint64(chainReport.SourceChainSelector), Messages: evmMessages, OffchainTokenData: chainReport.OffchainTokenData, @@ -110,8 +110,8 @@ func (e *ExecutePluginCodecV1) Decode(ctx context.Context, encodedReport []byte) return cciptypes.ExecutePluginReport{}, fmt.Errorf("unpacked report is empty") } - evmReportRaw := abi.ConvertType(unpacked[0], new([]evm_2_evm_multi_offramp.InternalExecutionReportSingleChain)) - evmReportPtr, is := evmReportRaw.(*[]evm_2_evm_multi_offramp.InternalExecutionReportSingleChain) + evmReportRaw := abi.ConvertType(unpacked[0], new([]offramp.InternalExecutionReportSingleChain)) + evmReportPtr, is := evmReportRaw.(*[]offramp.InternalExecutionReportSingleChain) if !is { return cciptypes.ExecutePluginReport{}, fmt.Errorf("got an unexpected report type %T", unpacked[0]) } diff --git a/core/capabilities/ccip/ccipevm/msghasher.go b/core/capabilities/ccip/ccipevm/msghasher.go index 0df0a8254a..e620d96a43 100644 --- a/core/capabilities/ccip/ccipevm/msghasher.go +++ b/core/capabilities/ccip/ccipevm/msghasher.go @@ -32,7 +32,7 @@ var ( // MessageHasherV1 implements the MessageHasher interface. // Compatible with: -// - "EVM2EVMMultiOnRamp 1.6.0-dev" +// - "OnRamp 1.6.0-dev" type MessageHasherV1 struct{} func NewMessageHasherV1() *MessageHasherV1 { diff --git a/core/capabilities/ccip/configs/evm/chain_writer.go b/core/capabilities/ccip/configs/evm/chain_writer.go index 6d3b73c6f5..6f8c4a1570 100644 --- a/core/capabilities/ccip/configs/evm/chain_writer.go +++ b/core/capabilities/ccip/configs/evm/chain_writer.go @@ -12,12 +12,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) var ( - offrampABI = evmtypes.MustGetABI(evm_2_evm_multi_offramp.EVM2EVMMultiOffRampABI) + offrampABI = evmtypes.MustGetABI(offramp.OffRampABI) ) func MustChainWriterConfig( @@ -45,7 +45,7 @@ func ChainWriterConfigRaw( return evmrelaytypes.ChainWriterConfig{ Contracts: map[string]*evmrelaytypes.ContractConfig{ consts.ContractNameOffRamp: { - ContractABI: evm_2_evm_multi_offramp.EVM2EVMMultiOffRampABI, + ContractABI: offramp.OffRampABI, Configs: map[string]*evmrelaytypes.ChainWriterDefinition{ consts.MethodCommit: { ChainSpecificName: mustGetMethodName("commit", offrampABI), diff --git a/core/capabilities/ccip/configs/evm/contract_reader.go b/core/capabilities/ccip/configs/evm/contract_reader.go index 085729690d..6774c8c1fe 100644 --- a/core/capabilities/ccip/configs/evm/contract_reader.go +++ b/core/capabilities/ccip/configs/evm/contract_reader.go @@ -10,15 +10,15 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) var ( - onrampABI = evmtypes.MustGetABI(evm_2_evm_multi_onramp.EVM2EVMMultiOnRampABI) + onrampABI = evmtypes.MustGetABI(onramp.OnRampABI) capabilitiesRegsitryABI = evmtypes.MustGetABI(kcr.CapabilitiesRegistryABI) ccipConfigABI = evmtypes.MustGetABI(ccip_config.CCIPConfigABI) priceRegistryABI = evmtypes.MustGetABI(price_registry.PriceRegistryABI) @@ -53,7 +53,7 @@ func DestReaderConfig() evmrelaytypes.ChainReaderConfig { return evmrelaytypes.ChainReaderConfig{ Contracts: map[string]evmrelaytypes.ChainContractReader{ consts.ContractNameOffRamp: { - ContractABI: evm_2_evm_multi_offramp.EVM2EVMMultiOffRampABI, + ContractABI: offramp.OffRampABI, ContractPollingFilter: evmrelaytypes.ContractPollingFilter{ GenericEventNames: []string{ mustGetEventName(consts.EventNameExecutionStateChanged, offrampABI), @@ -108,7 +108,7 @@ func SourceReaderConfig() evmrelaytypes.ChainReaderConfig { return evmrelaytypes.ChainReaderConfig{ Contracts: map[string]evmrelaytypes.ChainContractReader{ consts.ContractNameOnRamp: { - ContractABI: evm_2_evm_multi_onramp.EVM2EVMMultiOnRampABI, + ContractABI: onramp.OnRampABI, ContractPollingFilter: evmrelaytypes.ContractPollingFilter{ GenericEventNames: []string{ mustGetEventName(consts.EventNameCCIPSendRequested, onrampABI), diff --git a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go index 9c49b3f882..164c066e23 100644 --- a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go +++ b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go @@ -30,29 +30,6 @@ var ( _ = abi.ConvertType ) -type EVM2EVMMultiOffRampCommitReport struct { - PriceUpdates InternalPriceUpdates - MerkleRoots []EVM2EVMMultiOffRampMerkleRoot -} - -type EVM2EVMMultiOffRampInterval struct { - Min uint64 - Max uint64 -} - -type EVM2EVMMultiOffRampMerkleRoot struct { - SourceChainSelector uint64 - Interval EVM2EVMMultiOffRampInterval - MerkleRoot [32]byte -} - -type EVM2EVMMultiOffRampSourceChainConfig struct { - Router common.Address - IsEnabled bool - MinSeqNr uint64 - OnRamp []byte -} - type InternalEVM2AnyRampMessage struct { Header InternalRampMessageHeader Sender common.Address @@ -94,8 +71,31 @@ type InternalTokenPriceUpdate struct { UsdPerToken *big.Int } +type OffRampCommitReport struct { + PriceUpdates InternalPriceUpdates + MerkleRoots []OffRampMerkleRoot +} + +type OffRampInterval struct { + Min uint64 + Max uint64 +} + +type OffRampMerkleRoot struct { + SourceChainSelector uint64 + Interval OffRampInterval + MerkleRoot [32]byte +} + +type OffRampSourceChainConfig struct { + Router common.Address + IsEnabled bool + MinSeqNr uint64 + OnRamp []byte +} + var CCIPReaderTesterMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPSendRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPSendRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Bin: "0x608060405234801561001057600080fd5b50611149806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80634cf66e361461005c578063a65558f614610071578063e44302b714610084578063e83eabba14610097578063e9d68a8e146100aa575b600080fd5b61006f61006a3660046104a7565b6100d3565b005b61006f61007f366004610718565b610128565b61006f6100923660046109b6565b61016d565b61006f6100a5366004610b20565b6101a7565b6100bd6100b8366004610bdb565b610233565b6040516100ca9190610c43565b60405180910390f35b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051610119929190610c9b565b60405180910390a45050505050565b816001600160401b03167f0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab29826040516101619190610d83565b60405180910390a25050565b7f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161019c9190610f3d565b60405180910390a150565b6001600160401b0380831660009081526020818152604091829020845181549286015193860151909416600160a81b02600160a81b600160e81b0319931515600160a01b026001600160a81b03199093166001600160a01b039095169490941791909117919091169190911781556060820151829190600182019061022c908261107d565b5050505050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b038781168452838352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b9092049092169483019490945260018401805493949293918401916102be90610ff2565b80601f01602080910402602001604051908101604052809291908181526020018280546102ea90610ff2565b80156103375780601f1061030c57610100808354040283529160200191610337565b820191906000526020600020905b81548152906001019060200180831161031a57829003601f168201915b5050505050815250509050919050565b80356001600160401b038116811461035e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b038111828210171561039b5761039b610363565b60405290565b60405161010081016001600160401b038111828210171561039b5761039b610363565b604080519081016001600160401b038111828210171561039b5761039b610363565b604051606081016001600160401b038111828210171561039b5761039b610363565b604051601f8201601f191681016001600160401b038111828210171561043057610430610363565b604052919050565b600082601f83011261044957600080fd5b81356001600160401b0381111561046257610462610363565b610475601f8201601f1916602001610408565b81815284602083860101111561048a57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a086880312156104bf57600080fd5b6104c886610347565b94506104d660208701610347565b9350604086013592506060860135600481106104f157600080fd5b915060808601356001600160401b0381111561050c57600080fd5b61051888828901610438565b9150509295509295909350565b600060a0828403121561053757600080fd5b60405160a081016001600160401b038111828210171561055957610559610363565b6040528235815290508061056f60208401610347565b602082015261058060408401610347565b604082015261059160608401610347565b60608201526105a260808401610347565b60808201525092915050565b6001600160a01b03811681146105c357600080fd5b50565b803561035e816105ae565b60006001600160401b038211156105ea576105ea610363565b5060051b60200190565b600082601f83011261060557600080fd5b8135602061061a610615836105d1565b610408565b82815260059290921b8401810191818101908684111561063957600080fd5b8286015b8481101561070d5780356001600160401b038082111561065d5760008081fd5b908801906080828b03601f19018113156106775760008081fd5b61067f610379565b87840135838111156106915760008081fd5b61069f8d8a83880101610438565b825250604080850135848111156106b65760008081fd5b6106c48e8b83890101610438565b8a84015250606080860135858111156106dd5760008081fd5b6106eb8f8c838a0101610438565b928401929092529490920135938101939093525050835291830191830161063d565b509695505050505050565b6000806040838503121561072b57600080fd5b61073483610347565b915060208301356001600160401b038082111561075057600080fd5b90840190610180828703121561076557600080fd5b61076d6103a1565b6107778784610525565b815261078560a084016105c6565b602082015260c08301358281111561079c57600080fd5b6107a888828601610438565b60408301525060e0830135828111156107c057600080fd5b6107cc88828601610438565b606083015250610100830135828111156107e557600080fd5b6107f188828601610438565b60808301525061080461012084016105c6565b60a082015261014083013560c08201526101608301358281111561082757600080fd5b610833888286016105f4565b60e0830152508093505050509250929050565b80356001600160e01b038116811461035e57600080fd5b600082601f83011261086e57600080fd5b8135602061087e610615836105d1565b82815260069290921b8401810191818101908684111561089d57600080fd5b8286015b8481101561070d57604081890312156108ba5760008081fd5b6108c26103c4565b6108cb82610347565b81526108d8858301610846565b818601528352918301916040016108a1565b600082601f8301126108fb57600080fd5b8135602061090b610615836105d1565b82815260079290921b8401810191818101908684111561092a57600080fd5b8286015b8481101561070d5780880360808112156109485760008081fd5b6109506103e6565b61095983610347565b8152604080601f198401121561096f5760008081fd5b6109776103c4565b9250610984878501610347565b8352610991818501610347565b838801528187019290925260608301359181019190915283529183019160800161092e565b600060208083850312156109c957600080fd5b82356001600160401b03808211156109e057600080fd5b818501915060408083880312156109f657600080fd5b6109fe6103c4565b833583811115610a0d57600080fd5b84016040818a031215610a1f57600080fd5b610a276103c4565b813585811115610a3657600080fd5b8201601f81018b13610a4757600080fd5b8035610a55610615826105d1565b81815260069190911b8201890190898101908d831115610a7457600080fd5b928a01925b82841015610ac45787848f031215610a915760008081fd5b610a996103c4565b8435610aa4816105ae565b8152610ab1858d01610846565b818d0152825292870192908a0190610a79565b845250505081870135935084841115610adc57600080fd5b610ae88a85840161085d565b8188015282525083850135915082821115610b0257600080fd5b610b0e888386016108ea565b85820152809550505050505092915050565b60008060408385031215610b3357600080fd5b610b3c83610347565b915060208301356001600160401b0380821115610b5857600080fd5b9084019060808287031215610b6c57600080fd5b610b74610379565b8235610b7f816105ae565b815260208301358015158114610b9457600080fd5b6020820152610ba560408401610347565b6040820152606083013582811115610bbc57600080fd5b610bc888828601610438565b6060830152508093505050509250929050565b600060208284031215610bed57600080fd5b610bf682610347565b9392505050565b6000815180845260005b81811015610c2357602081850181015186830182015201610c07565b506000602082860101526020601f19601f83011685010191505092915050565b602080825282516001600160a01b03168282015282015115156040808301919091528201516001600160401b0316606080830191909152820151608080830152600090610c9360a0840182610bfd565b949350505050565b600060048410610cbb57634e487b7160e01b600052602160045260246000fd5b83825260406020830152610c936040830184610bfd565b6001600160a01b03169052565b600082825180855260208086019550808260051b84010181860160005b84811015610d7657601f19868403018952815160808151818652610d2282870182610bfd565b9150508582015185820387870152610d3a8282610bfd565b91505060408083015186830382880152610d548382610bfd565b6060948501519790940196909652505098840198925090830190600101610cfc565b5090979650505050505050565b60208152610dd0602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b60006020830151610de460c0840182610cd2565b5060408301516101808060e0850152610e016101a0850183610bfd565b91506060850151601f198086850301610100870152610e208483610bfd565b9350608087015191508086850301610120870152610e3e8483610bfd565b935060a08701519150610e55610140870183610cd2565b60c087015161016087015260e0870151915080868503018387015250610e7b8382610cdf565b9695505050505050565b60008151808452602080850194506020840160005b83811015610ed357815180516001600160401b031688528301516001600160e01b03168388015260409096019590820190600101610e9a565b509495945050505050565b600081518084526020808501945080840160005b83811015610ed357815180516001600160401b0390811689528482015180518216868b0152850151166040898101919091520151606088015260809096019590820190600101610ef2565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b80831015610fab57835180516001600160a01b031683528701516001600160e01b031687830152928601926001929092019190840190610f70565b5093850151878503605f1901608089015293610fc78186610e85565b945050505050818501519150601f19848203016040850152610fe98183610ede565b95945050505050565b600181811c9082168061100657607f821691505b60208210810361102657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115611078576000816000526020600020601f850160051c810160208610156110555750805b601f850160051c820191505b8181101561107457828155600101611061565b5050505b505050565b81516001600160401b0381111561109657611096610363565b6110aa816110a48454610ff2565b8461102c565b602080601f8311600181146110df57600084156110c75750858301515b600019600386901b1c1916600185901b178555611074565b600085815260208120601f198616915b8281101561110e578886015182559484019460019091019084016110ef565b508582101561112c5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", } @@ -235,25 +235,25 @@ func (_CCIPReaderTester *CCIPReaderTesterTransactorRaw) Transact(opts *bind.Tran return _CCIPReaderTester.Contract.contract.Transact(opts, method, params...) } -func (_CCIPReaderTester *CCIPReaderTesterCaller) GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) { +func (_CCIPReaderTester *CCIPReaderTesterCaller) GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (OffRampSourceChainConfig, error) { var out []interface{} err := _CCIPReaderTester.contract.Call(opts, &out, "getSourceChainConfig", sourceChainSelector) if err != nil { - return *new(EVM2EVMMultiOffRampSourceChainConfig), err + return *new(OffRampSourceChainConfig), err } - out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOffRampSourceChainConfig)).(*EVM2EVMMultiOffRampSourceChainConfig) + out0 := *abi.ConvertType(out[0], new(OffRampSourceChainConfig)).(*OffRampSourceChainConfig) return out0, err } -func (_CCIPReaderTester *CCIPReaderTesterSession) GetSourceChainConfig(sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) { +func (_CCIPReaderTester *CCIPReaderTesterSession) GetSourceChainConfig(sourceChainSelector uint64) (OffRampSourceChainConfig, error) { return _CCIPReaderTester.Contract.GetSourceChainConfig(&_CCIPReaderTester.CallOpts, sourceChainSelector) } -func (_CCIPReaderTester *CCIPReaderTesterCallerSession) GetSourceChainConfig(sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) { +func (_CCIPReaderTester *CCIPReaderTesterCallerSession) GetSourceChainConfig(sourceChainSelector uint64) (OffRampSourceChainConfig, error) { return _CCIPReaderTester.Contract.GetSourceChainConfig(&_CCIPReaderTester.CallOpts, sourceChainSelector) } @@ -269,15 +269,15 @@ func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) EmitCCIPSendRequeste return _CCIPReaderTester.Contract.EmitCCIPSendRequested(&_CCIPReaderTester.TransactOpts, destChainSelector, message) } -func (_CCIPReaderTester *CCIPReaderTesterTransactor) EmitCommitReportAccepted(opts *bind.TransactOpts, report EVM2EVMMultiOffRampCommitReport) (*types.Transaction, error) { +func (_CCIPReaderTester *CCIPReaderTesterTransactor) EmitCommitReportAccepted(opts *bind.TransactOpts, report OffRampCommitReport) (*types.Transaction, error) { return _CCIPReaderTester.contract.Transact(opts, "emitCommitReportAccepted", report) } -func (_CCIPReaderTester *CCIPReaderTesterSession) EmitCommitReportAccepted(report EVM2EVMMultiOffRampCommitReport) (*types.Transaction, error) { +func (_CCIPReaderTester *CCIPReaderTesterSession) EmitCommitReportAccepted(report OffRampCommitReport) (*types.Transaction, error) { return _CCIPReaderTester.Contract.EmitCommitReportAccepted(&_CCIPReaderTester.TransactOpts, report) } -func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) EmitCommitReportAccepted(report EVM2EVMMultiOffRampCommitReport) (*types.Transaction, error) { +func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) EmitCommitReportAccepted(report OffRampCommitReport) (*types.Transaction, error) { return _CCIPReaderTester.Contract.EmitCommitReportAccepted(&_CCIPReaderTester.TransactOpts, report) } @@ -293,15 +293,15 @@ func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) EmitExecutionStateCh return _CCIPReaderTester.Contract.EmitExecutionStateChanged(&_CCIPReaderTester.TransactOpts, sourceChainSelector, sequenceNumber, messageId, state, returnData) } -func (_CCIPReaderTester *CCIPReaderTesterTransactor) SetSourceChainConfig(opts *bind.TransactOpts, sourceChainSelector uint64, sourceChainConfig EVM2EVMMultiOffRampSourceChainConfig) (*types.Transaction, error) { +func (_CCIPReaderTester *CCIPReaderTesterTransactor) SetSourceChainConfig(opts *bind.TransactOpts, sourceChainSelector uint64, sourceChainConfig OffRampSourceChainConfig) (*types.Transaction, error) { return _CCIPReaderTester.contract.Transact(opts, "setSourceChainConfig", sourceChainSelector, sourceChainConfig) } -func (_CCIPReaderTester *CCIPReaderTesterSession) SetSourceChainConfig(sourceChainSelector uint64, sourceChainConfig EVM2EVMMultiOffRampSourceChainConfig) (*types.Transaction, error) { +func (_CCIPReaderTester *CCIPReaderTesterSession) SetSourceChainConfig(sourceChainSelector uint64, sourceChainConfig OffRampSourceChainConfig) (*types.Transaction, error) { return _CCIPReaderTester.Contract.SetSourceChainConfig(&_CCIPReaderTester.TransactOpts, sourceChainSelector, sourceChainConfig) } -func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) SetSourceChainConfig(sourceChainSelector uint64, sourceChainConfig EVM2EVMMultiOffRampSourceChainConfig) (*types.Transaction, error) { +func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) SetSourceChainConfig(sourceChainSelector uint64, sourceChainConfig OffRampSourceChainConfig) (*types.Transaction, error) { return _CCIPReaderTester.Contract.SetSourceChainConfig(&_CCIPReaderTester.TransactOpts, sourceChainSelector, sourceChainConfig) } @@ -494,7 +494,7 @@ func (it *CCIPReaderTesterCommitReportAcceptedIterator) Close() error { } type CCIPReaderTesterCommitReportAccepted struct { - Report EVM2EVMMultiOffRampCommitReport + Report OffRampCommitReport Raw types.Log } @@ -728,15 +728,15 @@ func (_CCIPReaderTester *CCIPReaderTester) Address() common.Address { } type CCIPReaderTesterInterface interface { - GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) + GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (OffRampSourceChainConfig, error) EmitCCIPSendRequested(opts *bind.TransactOpts, destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) - EmitCommitReportAccepted(opts *bind.TransactOpts, report EVM2EVMMultiOffRampCommitReport) (*types.Transaction, error) + EmitCommitReportAccepted(opts *bind.TransactOpts, report OffRampCommitReport) (*types.Transaction, error) EmitExecutionStateChanged(opts *bind.TransactOpts, sourceChainSelector uint64, sequenceNumber uint64, messageId [32]byte, state uint8, returnData []byte) (*types.Transaction, error) - SetSourceChainConfig(opts *bind.TransactOpts, sourceChainSelector uint64, sourceChainConfig EVM2EVMMultiOffRampSourceChainConfig) (*types.Transaction, error) + SetSourceChainConfig(opts *bind.TransactOpts, sourceChainSelector uint64, sourceChainConfig OffRampSourceChainConfig) (*types.Transaction, error) FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*CCIPReaderTesterCCIPSendRequestedIterator, error) diff --git a/core/gethwrappers/ccip/generated/mock_arm_contract/mock_arm_contract.go b/core/gethwrappers/ccip/generated/mock_rmn_contract/mock_rmn_contract.go similarity index 68% rename from core/gethwrappers/ccip/generated/mock_arm_contract/mock_arm_contract.go rename to core/gethwrappers/ccip/generated/mock_rmn_contract/mock_rmn_contract.go index fff63bef80..21aa223e75 100644 --- a/core/gethwrappers/ccip/generated/mock_arm_contract/mock_arm_contract.go +++ b/core/gethwrappers/ccip/generated/mock_rmn_contract/mock_rmn_contract.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package mock_arm_contract +package mock_rmn_contract import ( "errors" @@ -55,17 +55,17 @@ type RMNVoter struct { CurseWeight uint8 } -var MockARMContractMetaData = &bind.MetaData{ +var MockRMNContractMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"CustomError\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseUnvoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"cursesHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"forceUnvote\",\"type\":\"bool\"}],\"internalType\":\"structRMN.UnvoteToCurseRecord[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"ownerUnvoteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"cursesHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"forceUnvote\",\"type\":\"bool\"}],\"internalType\":\"structRMN.UnvoteToCurseRecord[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"ownerUnvoteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"setRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"voteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"voteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610ed7806101576000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063618af128116100815780637a7c27491161005b5780637a7c2749146102b55780638da5cb5b146102c8578063f2fde38b146102f057600080fd5b8063618af1281461020a578063794860871461024357806379ba5097146102ad57600080fd5b8063397796f7116100b2578063397796f7146101ba5780633f42ab73146101c25780634d616771146101d957600080fd5b8063119a3527146100d9578063257174dc1461012b5780632cbc26bb14610192575b600080fd5b6101296100e73660046107fe565b50600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055565b005b6101296101393660046109db565b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550565b6101a56101a0366004610a29565b610303565b60405190151581526020015b60405180910390f35b6101a56103b7565b6101ca610424565b6040516101b193929190610a4b565b6101a56101e7366004610b1e565b5060015474010000000000000000000000000000000000000000900460ff161590565b610129610218366004610b36565b50600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff169055565b610129610251366004610b73565b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905550565b610129610565565b6101296102c3366004610b96565b610662565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101b1565b6101296102fe366004610c49565b610672565b60006002805461031290610c64565b1590506103575760026040517f5a4ff67100000000000000000000000000000000000000000000000000000000815260040161034e9190610cb1565b60405180910390fd5b60015474010000000000000000000000000000000000000000900460ff16806103b157507fffffffffffffffffffffffffffffffff00000000000000000000000000000000821660009081526006602052604090205460ff165b92915050565b6000600280546103c690610c64565b1590506104025760026040517f5a4ff67100000000000000000000000000000000000000000000000000000000815260040161034e9190610cb1565b5060015474010000000000000000000000000000000000000000900460ff1690565b6040805160608082018352815260006020820181905291810182905281906005546040805160038054608060208202840181019094526060830181815263ffffffff8087169664010000000090041694929392849284929184919060009085015b828210156105315760008481526020908190206040805160a08101825260038602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001808301548216858701526002909201549081169284019290925260ff74010000000000000000000000000000000000000000830481166060850152750100000000000000000000000000000000000000000090920490911660808301529083529092019101610485565b505050908252506001919091015461ffff808216602084015262010000909104166040909101529296919550919350915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161034e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600261066e8282610db0565b5050565b61067a610686565b61068381610709565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610707576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161034e565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161034e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561081057600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561086957610869610817565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156108b6576108b6610817565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146108e257600080fd5b919050565b600082601f8301126108f857600080fd5b8135602067ffffffffffffffff82111561091457610914610817565b610922818360051b0161086f565b8281526060928302850182019282820191908785111561094157600080fd5b8387015b8581101561099e5781818a03121561095d5760008081fd5b610965610846565b61096e826108be565b81528582013586820152604080830135801515811461098d5760008081fd5b908201528452928401928101610945565b5090979650505050505050565b80357fffffffffffffffffffffffffffffffff00000000000000000000000000000000811681146108e257600080fd5b600080604083850312156109ee57600080fd5b823567ffffffffffffffff811115610a0557600080fd5b610a11858286016108e7565b925050610a20602084016109ab565b90509250929050565b600060208284031215610a3b57600080fd5b610a44826109ab565b9392505050565b63ffffffff84811682528316602080830191909152606060408084018290528451848301839052805160c0860181905260009491820190859060e08801905b80831015610af1578351805173ffffffffffffffffffffffffffffffffffffffff9081168452868201518116878501528782015116878401528781015160ff908116898501526080918201511690830152928401926001929092019160a090910190610a8a565b509288015161ffff908116608089015260409098015190971660a090960195909552979650505050505050565b600060408284031215610b3057600080fd5b50919050565b600060208284031215610b4857600080fd5b813567ffffffffffffffff811115610b5f57600080fd5b610b6b848285016108e7565b949350505050565b60008060408385031215610b8657600080fd5b82359150610a20602084016109ab565b60006020808385031215610ba957600080fd5b823567ffffffffffffffff80821115610bc157600080fd5b818501915085601f830112610bd557600080fd5b813581811115610be757610be7610817565b610c17847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161086f565b91508082528684828501011115610c2d57600080fd5b8084840185840137600090820190930192909252509392505050565b600060208284031215610c5b57600080fd5b610a44826108be565b600181811c90821680610c7857607f821691505b602082108103610b30577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454610cc581610c64565b8060208701526040600180841660008114610ce75760018114610d2157610d51565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550610d51565b89600052602060002060005b85811015610d485781548b8201860152908301908801610d2d565b8a016040019650505b509398975050505050505050565b601f821115610dab576000816000526020600020601f850160051c81016020861015610d885750805b601f850160051c820191505b81811015610da757828155600101610d94565b5050505b505050565b815167ffffffffffffffff811115610dca57610dca610817565b610dde81610dd88454610c64565b84610d5f565b602080601f831160018114610e315760008415610dfb5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610da7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015610e7e57888601518255948401946001909101908401610e5f565b5085821015610eba57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", } -var MockARMContractABI = MockARMContractMetaData.ABI +var MockRMNContractABI = MockRMNContractMetaData.ABI -var MockARMContractBin = MockARMContractMetaData.Bin +var MockRMNContractBin = MockRMNContractMetaData.Bin -func DeployMockARMContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MockARMContract, error) { - parsed, err := MockARMContractMetaData.GetAbi() +func DeployMockRMNContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MockRMNContract, error) { + parsed, err := MockRMNContractMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -73,134 +73,134 @@ func DeployMockARMContract(auth *bind.TransactOpts, backend bind.ContractBackend return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MockARMContractBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MockRMNContractBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &MockARMContract{address: address, abi: *parsed, MockARMContractCaller: MockARMContractCaller{contract: contract}, MockARMContractTransactor: MockARMContractTransactor{contract: contract}, MockARMContractFilterer: MockARMContractFilterer{contract: contract}}, nil + return address, tx, &MockRMNContract{address: address, abi: *parsed, MockRMNContractCaller: MockRMNContractCaller{contract: contract}, MockRMNContractTransactor: MockRMNContractTransactor{contract: contract}, MockRMNContractFilterer: MockRMNContractFilterer{contract: contract}}, nil } -type MockARMContract struct { +type MockRMNContract struct { address common.Address abi abi.ABI - MockARMContractCaller - MockARMContractTransactor - MockARMContractFilterer + MockRMNContractCaller + MockRMNContractTransactor + MockRMNContractFilterer } -type MockARMContractCaller struct { +type MockRMNContractCaller struct { contract *bind.BoundContract } -type MockARMContractTransactor struct { +type MockRMNContractTransactor struct { contract *bind.BoundContract } -type MockARMContractFilterer struct { +type MockRMNContractFilterer struct { contract *bind.BoundContract } -type MockARMContractSession struct { - Contract *MockARMContract +type MockRMNContractSession struct { + Contract *MockRMNContract CallOpts bind.CallOpts TransactOpts bind.TransactOpts } -type MockARMContractCallerSession struct { - Contract *MockARMContractCaller +type MockRMNContractCallerSession struct { + Contract *MockRMNContractCaller CallOpts bind.CallOpts } -type MockARMContractTransactorSession struct { - Contract *MockARMContractTransactor +type MockRMNContractTransactorSession struct { + Contract *MockRMNContractTransactor TransactOpts bind.TransactOpts } -type MockARMContractRaw struct { - Contract *MockARMContract +type MockRMNContractRaw struct { + Contract *MockRMNContract } -type MockARMContractCallerRaw struct { - Contract *MockARMContractCaller +type MockRMNContractCallerRaw struct { + Contract *MockRMNContractCaller } -type MockARMContractTransactorRaw struct { - Contract *MockARMContractTransactor +type MockRMNContractTransactorRaw struct { + Contract *MockRMNContractTransactor } -func NewMockARMContract(address common.Address, backend bind.ContractBackend) (*MockARMContract, error) { - abi, err := abi.JSON(strings.NewReader(MockARMContractABI)) +func NewMockRMNContract(address common.Address, backend bind.ContractBackend) (*MockRMNContract, error) { + abi, err := abi.JSON(strings.NewReader(MockRMNContractABI)) if err != nil { return nil, err } - contract, err := bindMockARMContract(address, backend, backend, backend) + contract, err := bindMockRMNContract(address, backend, backend, backend) if err != nil { return nil, err } - return &MockARMContract{address: address, abi: abi, MockARMContractCaller: MockARMContractCaller{contract: contract}, MockARMContractTransactor: MockARMContractTransactor{contract: contract}, MockARMContractFilterer: MockARMContractFilterer{contract: contract}}, nil + return &MockRMNContract{address: address, abi: abi, MockRMNContractCaller: MockRMNContractCaller{contract: contract}, MockRMNContractTransactor: MockRMNContractTransactor{contract: contract}, MockRMNContractFilterer: MockRMNContractFilterer{contract: contract}}, nil } -func NewMockARMContractCaller(address common.Address, caller bind.ContractCaller) (*MockARMContractCaller, error) { - contract, err := bindMockARMContract(address, caller, nil, nil) +func NewMockRMNContractCaller(address common.Address, caller bind.ContractCaller) (*MockRMNContractCaller, error) { + contract, err := bindMockRMNContract(address, caller, nil, nil) if err != nil { return nil, err } - return &MockARMContractCaller{contract: contract}, nil + return &MockRMNContractCaller{contract: contract}, nil } -func NewMockARMContractTransactor(address common.Address, transactor bind.ContractTransactor) (*MockARMContractTransactor, error) { - contract, err := bindMockARMContract(address, nil, transactor, nil) +func NewMockRMNContractTransactor(address common.Address, transactor bind.ContractTransactor) (*MockRMNContractTransactor, error) { + contract, err := bindMockRMNContract(address, nil, transactor, nil) if err != nil { return nil, err } - return &MockARMContractTransactor{contract: contract}, nil + return &MockRMNContractTransactor{contract: contract}, nil } -func NewMockARMContractFilterer(address common.Address, filterer bind.ContractFilterer) (*MockARMContractFilterer, error) { - contract, err := bindMockARMContract(address, nil, nil, filterer) +func NewMockRMNContractFilterer(address common.Address, filterer bind.ContractFilterer) (*MockRMNContractFilterer, error) { + contract, err := bindMockRMNContract(address, nil, nil, filterer) if err != nil { return nil, err } - return &MockARMContractFilterer{contract: contract}, nil + return &MockRMNContractFilterer{contract: contract}, nil } -func bindMockARMContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := MockARMContractMetaData.GetAbi() +func bindMockRMNContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MockRMNContractMetaData.GetAbi() if err != nil { return nil, err } return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } -func (_MockARMContract *MockARMContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MockARMContract.Contract.MockARMContractCaller.contract.Call(opts, result, method, params...) +func (_MockRMNContract *MockRMNContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockRMNContract.Contract.MockRMNContractCaller.contract.Call(opts, result, method, params...) } -func (_MockARMContract *MockARMContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MockARMContract.Contract.MockARMContractTransactor.contract.Transfer(opts) +func (_MockRMNContract *MockRMNContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockRMNContract.Contract.MockRMNContractTransactor.contract.Transfer(opts) } -func (_MockARMContract *MockARMContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MockARMContract.Contract.MockARMContractTransactor.contract.Transact(opts, method, params...) +func (_MockRMNContract *MockRMNContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockRMNContract.Contract.MockRMNContractTransactor.contract.Transact(opts, method, params...) } -func (_MockARMContract *MockARMContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MockARMContract.Contract.contract.Call(opts, result, method, params...) +func (_MockRMNContract *MockRMNContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockRMNContract.Contract.contract.Call(opts, result, method, params...) } -func (_MockARMContract *MockARMContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MockARMContract.Contract.contract.Transfer(opts) +func (_MockRMNContract *MockRMNContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockRMNContract.Contract.contract.Transfer(opts) } -func (_MockARMContract *MockARMContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MockARMContract.Contract.contract.Transact(opts, method, params...) +func (_MockRMNContract *MockRMNContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockRMNContract.Contract.contract.Transact(opts, method, params...) } -func (_MockARMContract *MockARMContractCaller) GetConfigDetails(opts *bind.CallOpts) (GetConfigDetails, +func (_MockRMNContract *MockRMNContractCaller) GetConfigDetails(opts *bind.CallOpts) (GetConfigDetails, error) { var out []interface{} - err := _MockARMContract.contract.Call(opts, &out, "getConfigDetails") + err := _MockRMNContract.contract.Call(opts, &out, "getConfigDetails") outstruct := new(GetConfigDetails) if err != nil { @@ -215,21 +215,21 @@ func (_MockARMContract *MockARMContractCaller) GetConfigDetails(opts *bind.CallO } -func (_MockARMContract *MockARMContractSession) GetConfigDetails() (GetConfigDetails, +func (_MockRMNContract *MockRMNContractSession) GetConfigDetails() (GetConfigDetails, error) { - return _MockARMContract.Contract.GetConfigDetails(&_MockARMContract.CallOpts) + return _MockRMNContract.Contract.GetConfigDetails(&_MockRMNContract.CallOpts) } -func (_MockARMContract *MockARMContractCallerSession) GetConfigDetails() (GetConfigDetails, +func (_MockRMNContract *MockRMNContractCallerSession) GetConfigDetails() (GetConfigDetails, error) { - return _MockARMContract.Contract.GetConfigDetails(&_MockARMContract.CallOpts) + return _MockRMNContract.Contract.GetConfigDetails(&_MockRMNContract.CallOpts) } -func (_MockARMContract *MockARMContractCaller) IsBlessed(opts *bind.CallOpts, arg0 IRMNTaggedRoot) (bool, error) { +func (_MockRMNContract *MockRMNContractCaller) IsBlessed(opts *bind.CallOpts, arg0 IRMNTaggedRoot) (bool, error) { var out []interface{} - err := _MockARMContract.contract.Call(opts, &out, "isBlessed", arg0) + err := _MockRMNContract.contract.Call(opts, &out, "isBlessed", arg0) if err != nil { return *new(bool), err @@ -241,17 +241,17 @@ func (_MockARMContract *MockARMContractCaller) IsBlessed(opts *bind.CallOpts, ar } -func (_MockARMContract *MockARMContractSession) IsBlessed(arg0 IRMNTaggedRoot) (bool, error) { - return _MockARMContract.Contract.IsBlessed(&_MockARMContract.CallOpts, arg0) +func (_MockRMNContract *MockRMNContractSession) IsBlessed(arg0 IRMNTaggedRoot) (bool, error) { + return _MockRMNContract.Contract.IsBlessed(&_MockRMNContract.CallOpts, arg0) } -func (_MockARMContract *MockARMContractCallerSession) IsBlessed(arg0 IRMNTaggedRoot) (bool, error) { - return _MockARMContract.Contract.IsBlessed(&_MockARMContract.CallOpts, arg0) +func (_MockRMNContract *MockRMNContractCallerSession) IsBlessed(arg0 IRMNTaggedRoot) (bool, error) { + return _MockRMNContract.Contract.IsBlessed(&_MockRMNContract.CallOpts, arg0) } -func (_MockARMContract *MockARMContractCaller) IsCursed(opts *bind.CallOpts, subject [16]byte) (bool, error) { +func (_MockRMNContract *MockRMNContractCaller) IsCursed(opts *bind.CallOpts, subject [16]byte) (bool, error) { var out []interface{} - err := _MockARMContract.contract.Call(opts, &out, "isCursed", subject) + err := _MockRMNContract.contract.Call(opts, &out, "isCursed", subject) if err != nil { return *new(bool), err @@ -263,17 +263,17 @@ func (_MockARMContract *MockARMContractCaller) IsCursed(opts *bind.CallOpts, sub } -func (_MockARMContract *MockARMContractSession) IsCursed(subject [16]byte) (bool, error) { - return _MockARMContract.Contract.IsCursed(&_MockARMContract.CallOpts, subject) +func (_MockRMNContract *MockRMNContractSession) IsCursed(subject [16]byte) (bool, error) { + return _MockRMNContract.Contract.IsCursed(&_MockRMNContract.CallOpts, subject) } -func (_MockARMContract *MockARMContractCallerSession) IsCursed(subject [16]byte) (bool, error) { - return _MockARMContract.Contract.IsCursed(&_MockARMContract.CallOpts, subject) +func (_MockRMNContract *MockRMNContractCallerSession) IsCursed(subject [16]byte) (bool, error) { + return _MockRMNContract.Contract.IsCursed(&_MockRMNContract.CallOpts, subject) } -func (_MockARMContract *MockARMContractCaller) IsCursed0(opts *bind.CallOpts) (bool, error) { +func (_MockRMNContract *MockRMNContractCaller) IsCursed0(opts *bind.CallOpts) (bool, error) { var out []interface{} - err := _MockARMContract.contract.Call(opts, &out, "isCursed0") + err := _MockRMNContract.contract.Call(opts, &out, "isCursed0") if err != nil { return *new(bool), err @@ -285,17 +285,17 @@ func (_MockARMContract *MockARMContractCaller) IsCursed0(opts *bind.CallOpts) (b } -func (_MockARMContract *MockARMContractSession) IsCursed0() (bool, error) { - return _MockARMContract.Contract.IsCursed0(&_MockARMContract.CallOpts) +func (_MockRMNContract *MockRMNContractSession) IsCursed0() (bool, error) { + return _MockRMNContract.Contract.IsCursed0(&_MockRMNContract.CallOpts) } -func (_MockARMContract *MockARMContractCallerSession) IsCursed0() (bool, error) { - return _MockARMContract.Contract.IsCursed0(&_MockARMContract.CallOpts) +func (_MockRMNContract *MockRMNContractCallerSession) IsCursed0() (bool, error) { + return _MockRMNContract.Contract.IsCursed0(&_MockRMNContract.CallOpts) } -func (_MockARMContract *MockARMContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { +func (_MockRMNContract *MockRMNContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _MockARMContract.contract.Call(opts, &out, "owner") + err := _MockRMNContract.contract.Call(opts, &out, "owner") if err != nil { return *new(common.Address), err @@ -307,100 +307,100 @@ func (_MockARMContract *MockARMContractCaller) Owner(opts *bind.CallOpts) (commo } -func (_MockARMContract *MockARMContractSession) Owner() (common.Address, error) { - return _MockARMContract.Contract.Owner(&_MockARMContract.CallOpts) +func (_MockRMNContract *MockRMNContractSession) Owner() (common.Address, error) { + return _MockRMNContract.Contract.Owner(&_MockRMNContract.CallOpts) } -func (_MockARMContract *MockARMContractCallerSession) Owner() (common.Address, error) { - return _MockARMContract.Contract.Owner(&_MockARMContract.CallOpts) +func (_MockRMNContract *MockRMNContractCallerSession) Owner() (common.Address, error) { + return _MockRMNContract.Contract.Owner(&_MockRMNContract.CallOpts) } -func (_MockARMContract *MockARMContractTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MockARMContract.contract.Transact(opts, "acceptOwnership") +func (_MockRMNContract *MockRMNContractTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockRMNContract.contract.Transact(opts, "acceptOwnership") } -func (_MockARMContract *MockARMContractSession) AcceptOwnership() (*types.Transaction, error) { - return _MockARMContract.Contract.AcceptOwnership(&_MockARMContract.TransactOpts) +func (_MockRMNContract *MockRMNContractSession) AcceptOwnership() (*types.Transaction, error) { + return _MockRMNContract.Contract.AcceptOwnership(&_MockRMNContract.TransactOpts) } -func (_MockARMContract *MockARMContractTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _MockARMContract.Contract.AcceptOwnership(&_MockARMContract.TransactOpts) +func (_MockRMNContract *MockRMNContractTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _MockRMNContract.Contract.AcceptOwnership(&_MockRMNContract.TransactOpts) } -func (_MockARMContract *MockARMContractTransactor) OwnerUnvoteToCurse(opts *bind.TransactOpts, arg0 []RMNUnvoteToCurseRecord, subject [16]byte) (*types.Transaction, error) { - return _MockARMContract.contract.Transact(opts, "ownerUnvoteToCurse", arg0, subject) +func (_MockRMNContract *MockRMNContractTransactor) OwnerUnvoteToCurse(opts *bind.TransactOpts, arg0 []RMNUnvoteToCurseRecord, subject [16]byte) (*types.Transaction, error) { + return _MockRMNContract.contract.Transact(opts, "ownerUnvoteToCurse", arg0, subject) } -func (_MockARMContract *MockARMContractSession) OwnerUnvoteToCurse(arg0 []RMNUnvoteToCurseRecord, subject [16]byte) (*types.Transaction, error) { - return _MockARMContract.Contract.OwnerUnvoteToCurse(&_MockARMContract.TransactOpts, arg0, subject) +func (_MockRMNContract *MockRMNContractSession) OwnerUnvoteToCurse(arg0 []RMNUnvoteToCurseRecord, subject [16]byte) (*types.Transaction, error) { + return _MockRMNContract.Contract.OwnerUnvoteToCurse(&_MockRMNContract.TransactOpts, arg0, subject) } -func (_MockARMContract *MockARMContractTransactorSession) OwnerUnvoteToCurse(arg0 []RMNUnvoteToCurseRecord, subject [16]byte) (*types.Transaction, error) { - return _MockARMContract.Contract.OwnerUnvoteToCurse(&_MockARMContract.TransactOpts, arg0, subject) +func (_MockRMNContract *MockRMNContractTransactorSession) OwnerUnvoteToCurse(arg0 []RMNUnvoteToCurseRecord, subject [16]byte) (*types.Transaction, error) { + return _MockRMNContract.Contract.OwnerUnvoteToCurse(&_MockRMNContract.TransactOpts, arg0, subject) } -func (_MockARMContract *MockARMContractTransactor) OwnerUnvoteToCurse0(opts *bind.TransactOpts, arg0 []RMNUnvoteToCurseRecord) (*types.Transaction, error) { - return _MockARMContract.contract.Transact(opts, "ownerUnvoteToCurse0", arg0) +func (_MockRMNContract *MockRMNContractTransactor) OwnerUnvoteToCurse0(opts *bind.TransactOpts, arg0 []RMNUnvoteToCurseRecord) (*types.Transaction, error) { + return _MockRMNContract.contract.Transact(opts, "ownerUnvoteToCurse0", arg0) } -func (_MockARMContract *MockARMContractSession) OwnerUnvoteToCurse0(arg0 []RMNUnvoteToCurseRecord) (*types.Transaction, error) { - return _MockARMContract.Contract.OwnerUnvoteToCurse0(&_MockARMContract.TransactOpts, arg0) +func (_MockRMNContract *MockRMNContractSession) OwnerUnvoteToCurse0(arg0 []RMNUnvoteToCurseRecord) (*types.Transaction, error) { + return _MockRMNContract.Contract.OwnerUnvoteToCurse0(&_MockRMNContract.TransactOpts, arg0) } -func (_MockARMContract *MockARMContractTransactorSession) OwnerUnvoteToCurse0(arg0 []RMNUnvoteToCurseRecord) (*types.Transaction, error) { - return _MockARMContract.Contract.OwnerUnvoteToCurse0(&_MockARMContract.TransactOpts, arg0) +func (_MockRMNContract *MockRMNContractTransactorSession) OwnerUnvoteToCurse0(arg0 []RMNUnvoteToCurseRecord) (*types.Transaction, error) { + return _MockRMNContract.Contract.OwnerUnvoteToCurse0(&_MockRMNContract.TransactOpts, arg0) } -func (_MockARMContract *MockARMContractTransactor) SetRevert(opts *bind.TransactOpts, err []byte) (*types.Transaction, error) { - return _MockARMContract.contract.Transact(opts, "setRevert", err) +func (_MockRMNContract *MockRMNContractTransactor) SetRevert(opts *bind.TransactOpts, err []byte) (*types.Transaction, error) { + return _MockRMNContract.contract.Transact(opts, "setRevert", err) } -func (_MockARMContract *MockARMContractSession) SetRevert(err []byte) (*types.Transaction, error) { - return _MockARMContract.Contract.SetRevert(&_MockARMContract.TransactOpts, err) +func (_MockRMNContract *MockRMNContractSession) SetRevert(err []byte) (*types.Transaction, error) { + return _MockRMNContract.Contract.SetRevert(&_MockRMNContract.TransactOpts, err) } -func (_MockARMContract *MockARMContractTransactorSession) SetRevert(err []byte) (*types.Transaction, error) { - return _MockARMContract.Contract.SetRevert(&_MockARMContract.TransactOpts, err) +func (_MockRMNContract *MockRMNContractTransactorSession) SetRevert(err []byte) (*types.Transaction, error) { + return _MockRMNContract.Contract.SetRevert(&_MockRMNContract.TransactOpts, err) } -func (_MockARMContract *MockARMContractTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _MockARMContract.contract.Transact(opts, "transferOwnership", to) +func (_MockRMNContract *MockRMNContractTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _MockRMNContract.contract.Transact(opts, "transferOwnership", to) } -func (_MockARMContract *MockARMContractSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _MockARMContract.Contract.TransferOwnership(&_MockARMContract.TransactOpts, to) +func (_MockRMNContract *MockRMNContractSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _MockRMNContract.Contract.TransferOwnership(&_MockRMNContract.TransactOpts, to) } -func (_MockARMContract *MockARMContractTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _MockARMContract.Contract.TransferOwnership(&_MockARMContract.TransactOpts, to) +func (_MockRMNContract *MockRMNContractTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _MockRMNContract.Contract.TransferOwnership(&_MockRMNContract.TransactOpts, to) } -func (_MockARMContract *MockARMContractTransactor) VoteToCurse(opts *bind.TransactOpts, arg0 [32]byte) (*types.Transaction, error) { - return _MockARMContract.contract.Transact(opts, "voteToCurse", arg0) +func (_MockRMNContract *MockRMNContractTransactor) VoteToCurse(opts *bind.TransactOpts, arg0 [32]byte) (*types.Transaction, error) { + return _MockRMNContract.contract.Transact(opts, "voteToCurse", arg0) } -func (_MockARMContract *MockARMContractSession) VoteToCurse(arg0 [32]byte) (*types.Transaction, error) { - return _MockARMContract.Contract.VoteToCurse(&_MockARMContract.TransactOpts, arg0) +func (_MockRMNContract *MockRMNContractSession) VoteToCurse(arg0 [32]byte) (*types.Transaction, error) { + return _MockRMNContract.Contract.VoteToCurse(&_MockRMNContract.TransactOpts, arg0) } -func (_MockARMContract *MockARMContractTransactorSession) VoteToCurse(arg0 [32]byte) (*types.Transaction, error) { - return _MockARMContract.Contract.VoteToCurse(&_MockARMContract.TransactOpts, arg0) +func (_MockRMNContract *MockRMNContractTransactorSession) VoteToCurse(arg0 [32]byte) (*types.Transaction, error) { + return _MockRMNContract.Contract.VoteToCurse(&_MockRMNContract.TransactOpts, arg0) } -func (_MockARMContract *MockARMContractTransactor) VoteToCurse0(opts *bind.TransactOpts, arg0 [32]byte, subject [16]byte) (*types.Transaction, error) { - return _MockARMContract.contract.Transact(opts, "voteToCurse0", arg0, subject) +func (_MockRMNContract *MockRMNContractTransactor) VoteToCurse0(opts *bind.TransactOpts, arg0 [32]byte, subject [16]byte) (*types.Transaction, error) { + return _MockRMNContract.contract.Transact(opts, "voteToCurse0", arg0, subject) } -func (_MockARMContract *MockARMContractSession) VoteToCurse0(arg0 [32]byte, subject [16]byte) (*types.Transaction, error) { - return _MockARMContract.Contract.VoteToCurse0(&_MockARMContract.TransactOpts, arg0, subject) +func (_MockRMNContract *MockRMNContractSession) VoteToCurse0(arg0 [32]byte, subject [16]byte) (*types.Transaction, error) { + return _MockRMNContract.Contract.VoteToCurse0(&_MockRMNContract.TransactOpts, arg0, subject) } -func (_MockARMContract *MockARMContractTransactorSession) VoteToCurse0(arg0 [32]byte, subject [16]byte) (*types.Transaction, error) { - return _MockARMContract.Contract.VoteToCurse0(&_MockARMContract.TransactOpts, arg0, subject) +func (_MockRMNContract *MockRMNContractTransactorSession) VoteToCurse0(arg0 [32]byte, subject [16]byte) (*types.Transaction, error) { + return _MockRMNContract.Contract.VoteToCurse0(&_MockRMNContract.TransactOpts, arg0, subject) } -type MockARMContractOwnershipTransferRequestedIterator struct { - Event *MockARMContractOwnershipTransferRequested +type MockRMNContractOwnershipTransferRequestedIterator struct { + Event *MockRMNContractOwnershipTransferRequested contract *bind.BoundContract event string @@ -411,7 +411,7 @@ type MockARMContractOwnershipTransferRequestedIterator struct { fail error } -func (it *MockARMContractOwnershipTransferRequestedIterator) Next() bool { +func (it *MockRMNContractOwnershipTransferRequestedIterator) Next() bool { if it.fail != nil { return false @@ -420,7 +420,7 @@ func (it *MockARMContractOwnershipTransferRequestedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(MockARMContractOwnershipTransferRequested) + it.Event = new(MockRMNContractOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -435,7 +435,7 @@ func (it *MockARMContractOwnershipTransferRequestedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(MockARMContractOwnershipTransferRequested) + it.Event = new(MockRMNContractOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -450,22 +450,22 @@ func (it *MockARMContractOwnershipTransferRequestedIterator) Next() bool { } } -func (it *MockARMContractOwnershipTransferRequestedIterator) Error() error { +func (it *MockRMNContractOwnershipTransferRequestedIterator) Error() error { return it.fail } -func (it *MockARMContractOwnershipTransferRequestedIterator) Close() error { +func (it *MockRMNContractOwnershipTransferRequestedIterator) Close() error { it.sub.Unsubscribe() return nil } -type MockARMContractOwnershipTransferRequested struct { +type MockRMNContractOwnershipTransferRequested struct { From common.Address To common.Address Raw types.Log } -func (_MockARMContract *MockARMContractFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MockARMContractOwnershipTransferRequestedIterator, error) { +func (_MockRMNContract *MockRMNContractFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MockRMNContractOwnershipTransferRequestedIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -476,14 +476,14 @@ func (_MockARMContract *MockARMContractFilterer) FilterOwnershipTransferRequeste toRule = append(toRule, toItem) } - logs, sub, err := _MockARMContract.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _MockRMNContract.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } - return &MockARMContractOwnershipTransferRequestedIterator{contract: _MockARMContract.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil + return &MockRMNContractOwnershipTransferRequestedIterator{contract: _MockRMNContract.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil } -func (_MockARMContract *MockARMContractFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MockARMContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_MockRMNContract *MockRMNContractFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MockRMNContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -494,7 +494,7 @@ func (_MockARMContract *MockARMContractFilterer) WatchOwnershipTransferRequested toRule = append(toRule, toItem) } - logs, sub, err := _MockARMContract.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _MockRMNContract.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } @@ -504,8 +504,8 @@ func (_MockARMContract *MockARMContractFilterer) WatchOwnershipTransferRequested select { case log := <-logs: - event := new(MockARMContractOwnershipTransferRequested) - if err := _MockARMContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + event := new(MockRMNContractOwnershipTransferRequested) + if err := _MockRMNContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return err } event.Raw = log @@ -526,17 +526,17 @@ func (_MockARMContract *MockARMContractFilterer) WatchOwnershipTransferRequested }), nil } -func (_MockARMContract *MockARMContractFilterer) ParseOwnershipTransferRequested(log types.Log) (*MockARMContractOwnershipTransferRequested, error) { - event := new(MockARMContractOwnershipTransferRequested) - if err := _MockARMContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { +func (_MockRMNContract *MockRMNContractFilterer) ParseOwnershipTransferRequested(log types.Log) (*MockRMNContractOwnershipTransferRequested, error) { + event := new(MockRMNContractOwnershipTransferRequested) + if err := _MockRMNContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return nil, err } event.Raw = log return event, nil } -type MockARMContractOwnershipTransferredIterator struct { - Event *MockARMContractOwnershipTransferred +type MockRMNContractOwnershipTransferredIterator struct { + Event *MockRMNContractOwnershipTransferred contract *bind.BoundContract event string @@ -547,7 +547,7 @@ type MockARMContractOwnershipTransferredIterator struct { fail error } -func (it *MockARMContractOwnershipTransferredIterator) Next() bool { +func (it *MockRMNContractOwnershipTransferredIterator) Next() bool { if it.fail != nil { return false @@ -556,7 +556,7 @@ func (it *MockARMContractOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(MockARMContractOwnershipTransferred) + it.Event = new(MockRMNContractOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -571,7 +571,7 @@ func (it *MockARMContractOwnershipTransferredIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(MockARMContractOwnershipTransferred) + it.Event = new(MockRMNContractOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -586,22 +586,22 @@ func (it *MockARMContractOwnershipTransferredIterator) Next() bool { } } -func (it *MockARMContractOwnershipTransferredIterator) Error() error { +func (it *MockRMNContractOwnershipTransferredIterator) Error() error { return it.fail } -func (it *MockARMContractOwnershipTransferredIterator) Close() error { +func (it *MockRMNContractOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -type MockARMContractOwnershipTransferred struct { +type MockRMNContractOwnershipTransferred struct { From common.Address To common.Address Raw types.Log } -func (_MockARMContract *MockARMContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MockARMContractOwnershipTransferredIterator, error) { +func (_MockRMNContract *MockRMNContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MockRMNContractOwnershipTransferredIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -612,14 +612,14 @@ func (_MockARMContract *MockARMContractFilterer) FilterOwnershipTransferred(opts toRule = append(toRule, toItem) } - logs, sub, err := _MockARMContract.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _MockRMNContract.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } - return &MockARMContractOwnershipTransferredIterator{contract: _MockARMContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &MockRMNContractOwnershipTransferredIterator{contract: _MockRMNContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -func (_MockARMContract *MockARMContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MockARMContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_MockRMNContract *MockRMNContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MockRMNContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -630,7 +630,7 @@ func (_MockARMContract *MockARMContractFilterer) WatchOwnershipTransferred(opts toRule = append(toRule, toItem) } - logs, sub, err := _MockARMContract.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _MockRMNContract.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } @@ -640,8 +640,8 @@ func (_MockARMContract *MockARMContractFilterer) WatchOwnershipTransferred(opts select { case log := <-logs: - event := new(MockARMContractOwnershipTransferred) - if err := _MockARMContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(MockRMNContractOwnershipTransferred) + if err := _MockRMNContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -662,9 +662,9 @@ func (_MockARMContract *MockARMContractFilterer) WatchOwnershipTransferred(opts }), nil } -func (_MockARMContract *MockARMContractFilterer) ParseOwnershipTransferred(log types.Log) (*MockARMContractOwnershipTransferred, error) { - event := new(MockARMContractOwnershipTransferred) - if err := _MockARMContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +func (_MockRMNContract *MockRMNContractFilterer) ParseOwnershipTransferred(log types.Log) (*MockRMNContractOwnershipTransferred, error) { + event := new(MockRMNContractOwnershipTransferred) + if err := _MockRMNContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log @@ -677,31 +677,31 @@ type GetConfigDetails struct { Config RMNConfig } -func (_MockARMContract *MockARMContract) ParseLog(log types.Log) (generated.AbigenLog, error) { +func (_MockRMNContract *MockRMNContract) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _MockARMContract.abi.Events["OwnershipTransferRequested"].ID: - return _MockARMContract.ParseOwnershipTransferRequested(log) - case _MockARMContract.abi.Events["OwnershipTransferred"].ID: - return _MockARMContract.ParseOwnershipTransferred(log) + case _MockRMNContract.abi.Events["OwnershipTransferRequested"].ID: + return _MockRMNContract.ParseOwnershipTransferRequested(log) + case _MockRMNContract.abi.Events["OwnershipTransferred"].ID: + return _MockRMNContract.ParseOwnershipTransferred(log) default: return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) } } -func (MockARMContractOwnershipTransferRequested) Topic() common.Hash { +func (MockRMNContractOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } -func (MockARMContractOwnershipTransferred) Topic() common.Hash { +func (MockRMNContractOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (_MockARMContract *MockARMContract) Address() common.Address { - return _MockARMContract.address +func (_MockRMNContract *MockRMNContract) Address() common.Address { + return _MockRMNContract.address } -type MockARMContractInterface interface { +type MockRMNContractInterface interface { GetConfigDetails(opts *bind.CallOpts) (GetConfigDetails, error) @@ -728,17 +728,17 @@ type MockARMContractInterface interface { VoteToCurse0(opts *bind.TransactOpts, arg0 [32]byte, subject [16]byte) (*types.Transaction, error) - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MockARMContractOwnershipTransferRequestedIterator, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MockRMNContractOwnershipTransferRequestedIterator, error) - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MockARMContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MockRMNContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - ParseOwnershipTransferRequested(log types.Log) (*MockARMContractOwnershipTransferRequested, error) + ParseOwnershipTransferRequested(log types.Log) (*MockRMNContractOwnershipTransferRequested, error) - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MockARMContractOwnershipTransferredIterator, error) + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MockRMNContractOwnershipTransferredIterator, error) - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MockARMContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MockRMNContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - ParseOwnershipTransferred(log types.Log) (*MockARMContractOwnershipTransferred, error) + ParseOwnershipTransferred(log types.Log) (*MockRMNContractOwnershipTransferred, error) ParseLog(log types.Log) (generated.AbigenLog, error) diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go b/core/gethwrappers/ccip/generated/offramp/offramp.go similarity index 54% rename from core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go rename to core/gethwrappers/ccip/generated/offramp/offramp.go index 5b09de6687..72917cf943 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp/evm_2_evm_multi_offramp.go +++ b/core/gethwrappers/ccip/generated/offramp/offramp.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package evm_2_evm_multi_offramp +package offramp import ( "errors" @@ -43,56 +43,6 @@ type ClientEVMTokenAmount struct { Amount *big.Int } -type EVM2EVMMultiOffRampCommitReport struct { - PriceUpdates InternalPriceUpdates - MerkleRoots []EVM2EVMMultiOffRampMerkleRoot -} - -type EVM2EVMMultiOffRampDynamicConfig struct { - PriceRegistry common.Address - PermissionLessExecutionThresholdSeconds uint32 - MaxTokenTransferGas uint32 - MaxPoolReleaseOrMintGas uint32 - MessageValidator common.Address -} - -type EVM2EVMMultiOffRampInterval struct { - Min uint64 - Max uint64 -} - -type EVM2EVMMultiOffRampMerkleRoot struct { - SourceChainSelector uint64 - Interval EVM2EVMMultiOffRampInterval - MerkleRoot [32]byte -} - -type EVM2EVMMultiOffRampSourceChainConfig struct { - Router common.Address - IsEnabled bool - MinSeqNr uint64 - OnRamp []byte -} - -type EVM2EVMMultiOffRampSourceChainConfigArgs struct { - Router common.Address - SourceChainSelector uint64 - IsEnabled bool - OnRamp []byte -} - -type EVM2EVMMultiOffRampStaticConfig struct { - ChainSelector uint64 - RmnProxy common.Address - TokenAdminRegistry common.Address - NonceManager common.Address -} - -type EVM2EVMMultiOffRampUnblessedRoot struct { - SourceChainSelector uint64 - MerkleRoot [32]byte -} - type InternalAny2EVMRampMessage struct { Header InternalRampMessageHeader Sender []byte @@ -162,17 +112,67 @@ type MultiOCR3BaseOCRConfigArgs struct { Transmitters []common.Address } -var EVM2EVMMultiOffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162006bdd38038062006bdd8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615f0762000cd6600039600081816102530152612c120152600081816102240152612ef80152600081816101f50152818161142f01526118400152600081816101c50152612801015260008181611dce0152611e1a0152615f076000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063d2a15d351461053d578063e9d68a8e14610550578063ece670b61461057057600080fd5b8063991a5018116100bd578063991a5018146104c5578063c673e584146104d8578063ccd37ba3146104f857600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104815780637d4eef601461048957600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a3660046140b3565b6105cc565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601d81526020017f45564d3245564d4d756c74694f666652616d7020312e362e302d64657600000081525081565b6040516102d19190614222565b61018f6103313660046142cd565b6105e0565b61018f610344366004614380565b6109c0565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143d4565b610a29565b6040516102d19190614431565b6104246040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610a7f565b61018f610497366004614986565b610b3d565b61018f610177366004614ab1565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104d3366004614b00565b610cdd565b6104eb6104e6366004614b85565b610cee565b6040516102d19190614be5565b61052f610506366004614c5a565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f61054b366004614c84565b610e4c565b61056361055e366004614cf9565b610f06565b6040516102d19190614d14565b61018f61057e366004614d62565b611013565b61018f610591366004614dbe565b611386565b61018f6105a4366004614e43565b611397565b6105bc6105b7366004614f81565b6113d9565b60405190151581526020016102d1565b6105d461149a565b6105dd816114f6565b50565b60006105ee8789018961510a565b8051515190915015158061060757508051602001515115155b156107075760095460208a01359067ffffffffffffffff808316911610156106c6576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261068f929101615348565b600060405180830381600087803b1580156106a957600080fd5b505af11580156106bd573d6000803e3d6000fd5b50505050610705565b816020015151600003610705576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109095760008260200151828151811061072f5761072f615275565b6020026020010151905060008160000151905061074b816117f4565b6000610756826118f6565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061079a575060208084015190810151905167ffffffffffffffff9182169116115b156107e357825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107da92919060040161535b565b60405180910390fd5b60408301518061081f576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108925783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016107da565b60208085015101516108a59060016153a6565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff92831602179092559251166000908152600860209081526040808320948352939052919091204290555060010161070a565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161093991906153ce565b60405180910390a16109b560008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b925061195d915050565b505050505050505050565b610a006109cf8284018461546b565b60408051600080825260208201909252906109fa565b60608152602001906001900390816109e55790505b50611cd4565b604080516000808252602082019092529050610a2360018585858586600061195d565b50505050565b6000610a37600160046154a0565b6002610a446080856154c9565b67ffffffffffffffff16610a5891906154f0565b610a628585611d84565b901c166003811115610a7657610a76614407565b90505b92915050565b6001546001600160a01b03163314610ad95760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107da565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b45611dcb565b815181518114610b81576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ccd576000848281518110610ba057610ba0615275565b60200260200101519050600081602001515190506000858481518110610bc857610bc8615275565b6020026020010151905080518214610c0c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cbe576000828281518110610c2b57610c2b615275565b6020026020010151905080600014610cb55784602001518281518110610c5357610c53615275565b602002602001015160800151811015610cb55784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016107da565b50600101610c0f565b50505050806001019050610b84565b50610cd88383611cd4565b505050565b610ce561149a565b6105dd81611e4c565b610d316040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610dda57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dbc575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e1e575b5050505050815250509050919050565b610e5461149a565b60005b81811015610cd8576000838383818110610e7357610e73615275565b905060400201803603810190610e899190615507565b9050610e9881602001516113d9565b610efd57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e57565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191610f9390615540565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbf90615540565b8015610e3c5780601f10610fe157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610fef57505050919092525091949350505050565b33301461104c576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611089565b60408051808201909152600080825260208201528152602001906001900390816110625790505b5060a085015151909150156110bd576110ba8460a00151856020015186606001518760000151602001518787611fb2565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff16818301528087015183516000948401926110f9929101614222565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015611206576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a19061117390859060040161561c565b600060405180830381600087803b15801561118d57600080fd5b505af192505050801561119e575060015b611206573d8080156111cc576040519150601f19603f3d011682016040523d82523d6000602084013e6111d1565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b60408601515115801561121b57506080860151155b80611232575060608601516001600160a01b03163b155b8061127257506060860151611270906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120d1565b155b1561127f57505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf97983926112f7928992611388929160040161562f565b6000604051808303816000875af1158015611316573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261133e919081019061566b565b50915091508161137c57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b5050505050505050565b61138e61149a565b6105dd816120ed565b61139f61149a565b60005b81518110156113d5576113cd8282815181106113c0576113c0615275565b60200260200101516121a3565b6001016113a2565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611476573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a799190615701565b6000546001600160a01b031633146114f45760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107da565b565b60005b81518110156113d557600082828151811061151657611516615275565b602002602001015190506000816020015190508067ffffffffffffffff1660000361156d576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611595576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115c090615540565b80601f01602080910402602001604051908101604052809291908181526020018280546115ec90615540565b80156116395780601f1061160e57610100808354040283529160200191611639565b820191906000526020600020905b81548152906001019060200180831161161c57829003601f168201915b5050505050905060008460600151905081516000036116f1578051600003611674576040516342bcdf7f60e11b815260040160405180910390fd5b600183016116828282615766565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611744565b8080519060200120828051906020012014611744576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016107da565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117dc908690615826565b60405180910390a250505050508060010190506114f9565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b39190615701565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107da565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610a79576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107da565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906119bc8760a46158f4565b9050826060015115611a045784516119d59060206154f0565b86516119e29060206154f0565b6119ed9060a06158f4565b6119f791906158f4565b611a0190826158f4565b90505b368114611a46576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107da565b5081518114611a8e5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107da565b611a96611dcb565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611ae457611ae4614407565b6002811115611af557611af5614407565b9052509050600281602001516002811115611b1257611b12614407565b148015611b665750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611b4e57611b4e615275565b6000918252602090912001546001600160a01b031633145b611b9c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611c7e576020820151611bb7906001615907565b60ff16855114611bf3576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611c2e576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611c40929190615920565b604051908190038120611c57918b90602001615930565b604051602081830303815290604052805190602001209050611c7c8a828888886124e7565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d0e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611d7d57611d75858281518110611d4357611d43615275565b602002602001015184611d6f57858381518110611d6257611d62615275565b60200260200101516126f4565b836126f4565b600101611d25565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611da9608085615944565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f0000000000000000000000000000000000000000000000000000000000000000146114f4576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107da565b80516001600160a01b0316611e74576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fce57611fce613eca565b60405190808252806020026020018201604052801561201357816020015b6040805180820190915260008082526020820152815260200190600190039081611fec5790505b50905060005b87518110156120c5576120a088828151811061203757612037615275565b602002602001015188888888888781811061205457612054615275565b9050602002810190612066919061596b565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9792505050565b8282815181106120b2576120b2615275565b6020908102919091010152600101612019565b505b9695505050505050565b60006120dc8361323c565b8015610a765750610a7683836132a0565b336001600160a01b038216036121455760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107da565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ce576000604051631b3fab5160e11b81526004016107da91906159d0565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223b57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612290565b6060840151600182015460ff6201000090910416151590151514612290576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016107da565b60a08401518051601f60ff821611156122bf576001604051631b3fab5160e11b81526004016107da91906159d0565b612325858560030180548060200260200160405190810160405280929190818152602001828054801561231b57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122fd575b505050505061335b565b85606001511561245457612393858560020180548060200260200160405190810160405280929190818152602001828054801561231b576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122fd57505050505061335b565b608086015180516123ad9060028701906020840190613e24565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f101561240d576002604051631b3fab5160e11b81526004016107da91906159d0565b604088015161241d9060036159ea565b60ff168160ff1611612445576003604051631b3fab5160e11b81526004016107da91906159d0565b612451878360016133c4565b50505b612460858360026133c4565b81516124759060038601906020850190613e24565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ce938a939260028b01929190615a06565b60405180910390a16124df85613544565b505050505050565b6124ef613e96565b835160005b8181101561137c57600060018886846020811061251357612513615275565b61252091901a601b615907565b89858151811061253257612532615275565b602002602001015189868151811061254c5761254c615275565b60200260200101516040516000815260200160405260405161258a949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156125ac573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561260d5761260d614407565b600281111561261e5761261e614407565b905250905060018160200151600281111561263b5761263b614407565b14612672576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061268957612689615275565b6020020151156126c5576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126e0576126e0615275565b9115156020909202015250506001016124f4565b81516126ff816117f4565b600061270a826118f6565b602085015151909150600081900361274d576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461278b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156127a6576127a6613eca565b6040519080825280602002602001820160405280156127cf578160200160208202803683370190505b50905060005b82811015612944576000876020015182815181106127f5576127f5615275565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461288857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107da565b61291e8186600101805461289b90615540565b80601f01602080910402602001604051908101604052809291908181526020018280546128c790615540565b80156129145780601f106128e957610100808354040283529160200191612914565b820191906000526020600020905b8154815290600101906020018083116128f757829003601f168201915b5050505050613560565b83838151811061293057612930615275565b6020908102919091010152506001016127d5565b50600061295b858389606001518a60800151613682565b9050806000036129a3576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107da565b8551151560005b848110156109b55760005a905060008a6020015183815181106129cf576129cf615275565b6020026020010151905060006129ed8a836000015160600151610a29565b90506000816003811115612a0357612a03614407565b1480612a2057506003816003811115612a1e57612a1e614407565b145b612a78578151606001516040805167ffffffffffffffff808e16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a1505050612e8f565b8415612b4857600454600090600160a01b900463ffffffff16612a9b88426154a0565b1190508080612abb57506003826003811115612ab957612ab9614407565b145b612afd576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8c1660048201526024016107da565b8b8581518110612b0f57612b0f615275565b6020026020010151600014612b42578b8581518110612b3057612b30615275565b60200260200101518360800181815250505b50612ba9565b6000816003811115612b5c57612b5c614407565b14612ba9578151606001516040805167ffffffffffffffff808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612a68565b81516080015167ffffffffffffffff1615612c98576000816003811115612bd257612bd2614407565b03612c985781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c49928f929190600401615ab2565b6020604051808303816000875af1158015612c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8c9190615701565b612c9857505050612e8f565b60008c604001518581518110612cb057612cb0615275565b6020026020010151905080518360a001515114612d14578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808e16600483015290911660248201526044016107da565b612d288b84600001516060015160016136d8565b600080612d358584613780565b91509150612d4c8d866000015160600151846136d8565b8715612dbc576003826003811115612d6657612d66614407565b03612dbc576000846003811115612d7f57612d7f614407565b14612dbc578451516040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526107da91908390600401615adf565b6002826003811115612dd057612dd0614407565b14612e2a576003826003811115612de957612de9614407565b14612e2a578451606001516040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526107da918f918590600401615af8565b8451805160609091015167ffffffffffffffff908116908f167fdc8ccbc35e0eebd81239bcd1971fcd53c7eb34034880142a0f43c809a458732f85855a612e71908d6154a0565b604051612e8093929190615b1e565b60405180910390a45050505050505b6001016129aa565b60408051808201909152600080825260208201526000612eba876020015161384a565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f639190615b4e565b90506001600160a01b0381161580612fab5750612fa96001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120d1565b155b15612fed576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016107da565b600454600090819061300f9089908690600160e01b900463ffffffff166138f0565b9150915060008060006130dc6040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b81525060405160240161308d9190615b6b565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a1e565b9250925092508261311b57816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b81516020146131635781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b6000828060200190518101906131799190615c38565b9050866001600160a01b03168c6001600160a01b03161461320e5760006131aa8d8a6131a5868a6154a0565b6138f0565b509050868110806131c45750816131c188836154a0565b14155b1561320c576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016107da565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613268827f01ffc9a7000000000000000000000000000000000000000000000000000000006132a0565b8015610a795750613299827fffffffff000000000000000000000000000000000000000000000000000000006132a0565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015613344575060208210155b80156133505750600081115b979650505050505050565b60005b8151811015610cd85760ff83166000908152600360205260408120835190919084908490811061339057613390615275565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161335e565b60005b82518160ff161015610a23576000838260ff16815181106133ea576133ea615275565b602002602001015190506000600281111561340757613407614407565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561344657613446614407565b14613467576004604051631b3fab5160e11b81526004016107da91906159d0565b6001600160a01b0381166134a7576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134cd576134cd614407565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561352a5761352a614407565b0217905550905050508061353d90615c51565b90506133c7565b60ff81166105dd576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936135a6937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c70565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135ef9794969395929491939101615ca3565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136269190615d9a565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b600080613690858585613b44565b905061369b816113d9565b6136a95760009150506136d0565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026136e76080856154c9565b67ffffffffffffffff166136fb91906154f0565b905060006137098585611d84565b905081613718600160046154a0565b901b19168183600381111561372f5761372f614407565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161375e608088615944565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906137c49087908790600401615dfa565b600060405180830381600087803b1580156137de57600080fd5b505af19250505080156137ef575060015b61382e573d80801561381d576040519150601f19603f3d011682016040523d82523d6000602084013e613822565b606091505b50600392509050613843565b50506040805160208101909152600081526002905b9250929050565b6000815160201461388957816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b60008280602001905181019061389f9190615c38565b90506001600160a01b038111806138b7575061040081105b15610a7957826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b600080600080600061396a8860405160240161391b91906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a1e565b925092509250826139a957816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b60208251146139f15781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b81806020019051810190613a059190615c38565b613a0f82886154a0565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a4157613a41613eca565b6040519080825280601f01601f191660200182016040528015613a6b576020820181803683370190505b509150863b613a9e577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613ad1577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613b0a577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b2d5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b85576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b9957506101018111155b613bb6576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613be0576040516309bde33960e01b815260040160405180910390fd5b80600003613c0d5786600081518110613bfb57613bfb615275565b60200260200101519350505050613ddc565b60008167ffffffffffffffff811115613c2857613c28613eca565b604051908082528060200260200182016040528015613c51578160200160208202803683370190505b50905060008080805b85811015613d7b5760006001821b8b811603613cb55788851015613c9e578c5160018601958e918110613c8f57613c8f615275565b60200260200101519050613cd7565b8551600185019487918110613c8f57613c8f615275565b8b5160018401938d918110613ccc57613ccc615275565b602002602001015190505b600089861015613d07578d5160018701968f918110613cf857613cf8615275565b60200260200101519050613d29565b8651600186019588918110613d1e57613d1e615275565b602002602001015190505b82851115613d4a576040516309bde33960e01b815260040160405180910390fd5b613d548282613de3565b878481518110613d6657613d66615275565b60209081029190910101525050600101613c5a565b506001850382148015613d8d57508683145b8015613d9857508581145b613db5576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613dca57613dca615275565b60200260200101519750505050505050505b9392505050565b6000818310613dfb57613df68284613e01565b610a76565b610a7683835b604080516001602082015290810183905260608101829052600090608001613664565b828054828255906000526020600020908101928215613e86579160200282015b82811115613e86578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e44565b50613e92929150613eb5565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e925760008155600101613eb6565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613f0357613f03613eca565b60405290565b60405160a0810167ffffffffffffffff81118282101715613f0357613f03613eca565b60405160c0810167ffffffffffffffff81118282101715613f0357613f03613eca565b6040805190810167ffffffffffffffff81118282101715613f0357613f03613eca565b6040516060810167ffffffffffffffff81118282101715613f0357613f03613eca565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fbe57613fbe613eca565b604052919050565b600067ffffffffffffffff821115613fe057613fe0613eca565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461401757600080fd5b919050565b80151581146105dd57600080fd5b80356140178161401c565b600067ffffffffffffffff82111561404f5761404f613eca565b50601f01601f191660200190565b600082601f83011261406e57600080fd5b813561408161407c82614035565b613f95565b81815284602083860101111561409657600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140c657600080fd5b823567ffffffffffffffff808211156140de57600080fd5b818501915085601f8301126140f257600080fd5b813561410061407c82613fc6565b81815260059190911b8301840190848101908883111561411f57600080fd5b8585015b838110156141c55780358581111561413b5760008081fd5b86016080818c03601f19018113156141535760008081fd5b61415b613ee0565b8983013561416881613fea565b81526040614177848201613fff565b8b83015260608085013561418a8161401c565b838301529284013592898411156141a357600091508182fd5b6141b18f8d8688010161405d565b908301525085525050918601918601614123565b5098975050505050505050565b60005b838110156141ed5781810151838201526020016141d5565b50506000910152565b6000815180845261420e8160208601602086016141d2565b601f01601f19169290920160200192915050565b602081526000610a7660208301846141f6565b8060608101831015610a7957600080fd5b60008083601f84011261425857600080fd5b50813567ffffffffffffffff81111561427057600080fd5b60208301915083602082850101111561384357600080fd5b60008083601f84011261429a57600080fd5b50813567ffffffffffffffff8111156142b257600080fd5b6020830191508360208260051b850101111561384357600080fd5b60008060008060008060008060e0898b0312156142e957600080fd5b6142f38a8a614235565b9750606089013567ffffffffffffffff8082111561431057600080fd5b61431c8c838d01614246565b909950975060808b013591508082111561433557600080fd5b6143418c838d01614288565b909750955060a08b013591508082111561435a57600080fd5b506143678b828c01614288565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561439557600080fd5b61439f8585614235565b9250606084013567ffffffffffffffff8111156143bb57600080fd5b6143c786828701614246565b9497909650939450505050565b600080604083850312156143e757600080fd5b6143f083613fff565b91506143fe60208401613fff565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061442d5761442d614407565b9052565b60208101610a79828461441d565b600060a0828403121561445157600080fd5b614459613f09565b90508135815261446b60208301613fff565b602082015261447c60408301613fff565b604082015261448d60608301613fff565b606082015261449e60808301613fff565b608082015292915050565b803561401781613fea565b600082601f8301126144c557600080fd5b813560206144d561407c83613fc6565b82815260059290921b840181019181810190868411156144f457600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156145195760008081fd5b8189019150608080601f19848d030112156145345760008081fd5b61453c613ee0565b878401358381111561454e5760008081fd5b61455c8d8a8388010161405d565b825250604080850135848111156145735760008081fd5b6145818e8b8389010161405d565b8a840152506060808601358581111561459a5760008081fd5b6145a88f8c838a010161405d565b92840192909252949092013593810193909352505083529183019183016144f8565b600061014082840312156145dd57600080fd5b6145e5613f2c565b90506145f1838361443f565b815260a082013567ffffffffffffffff8082111561460e57600080fd5b61461a8583860161405d565b602084015260c084013591508082111561463357600080fd5b61463f8583860161405d565b604084015261465060e085016144a9565b6060840152610100840135608084015261012084013591508082111561467557600080fd5b50614682848285016144b4565b60a08301525092915050565b600082601f83011261469f57600080fd5b813560206146af61407c83613fc6565b82815260059290921b840181019181810190868411156146ce57600080fd5b8286015b848110156120c557803567ffffffffffffffff8111156146f25760008081fd5b6147008986838b01016145ca565b8452509183019183016146d2565b600082601f83011261471f57600080fd5b8135602061472f61407c83613fc6565b82815260059290921b8401810191818101908684111561474e57600080fd5b8286015b848110156120c557803567ffffffffffffffff8082111561477257600080fd5b818901915089603f83011261478657600080fd5b8582013561479661407c82613fc6565b81815260059190911b830160400190878101908c8311156147b657600080fd5b604085015b838110156147ef578035858111156147d257600080fd5b6147e18f6040838a010161405d565b8452509189019189016147bb565b50875250505092840192508301614752565b600082601f83011261481257600080fd5b8135602061482261407c83613fc6565b8083825260208201915060208460051b87010193508684111561484457600080fd5b602086015b848110156120c55780358352918301918301614849565b600082601f83011261487157600080fd5b8135602061488161407c83613fc6565b82815260059290921b840181019181810190868411156148a057600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156148c55760008081fd5b818901915060a080601f19848d030112156148e05760008081fd5b6148e8613f09565b6148f3888501613fff565b8152604080850135848111156149095760008081fd5b6149178e8b8389010161468e565b8a84015250606080860135858111156149305760008081fd5b61493e8f8c838a010161470e565b83850152506080915081860135858111156149595760008081fd5b6149678f8c838a0101614801565b91840191909152509190930135908301525083529183019183016148a4565b600080604080848603121561499a57600080fd5b833567ffffffffffffffff808211156149b257600080fd5b6149be87838801614860565b94506020915081860135818111156149d557600080fd5b8601601f810188136149e657600080fd5b80356149f461407c82613fc6565b81815260059190911b8201840190848101908a831115614a1357600080fd5b8584015b83811015614a9f57803586811115614a2f5760008081fd5b8501603f81018d13614a415760008081fd5b87810135614a5161407c82613fc6565b81815260059190911b82018a0190898101908f831115614a715760008081fd5b928b01925b82841015614a8f5783358252928a0192908a0190614a76565b8652505050918601918601614a17565b50809750505050505050509250929050565b600060208284031215614ac357600080fd5b813567ffffffffffffffff811115614ada57600080fd5b820160a08185031215613ddc57600080fd5b803563ffffffff8116811461401757600080fd5b600060a08284031215614b1257600080fd5b614b1a613f09565b8235614b2581613fea565b8152614b3360208401614aec565b6020820152614b4460408401614aec565b6040820152614b5560608401614aec565b60608201526080830135614b6881613fea565b60808201529392505050565b803560ff8116811461401757600080fd5b600060208284031215614b9757600080fd5b610a7682614b74565b60008151808452602080850194506020840160005b83811015614bda5781516001600160a01b031687529582019590820190600101614bb5565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c3460e0840182614ba0565b90506040840151601f198483030160c0850152614c518282614ba0565b95945050505050565b60008060408385031215614c6d57600080fd5b614c7683613fff565b946020939093013593505050565b60008060208385031215614c9757600080fd5b823567ffffffffffffffff80821115614caf57600080fd5b818501915085601f830112614cc357600080fd5b813581811115614cd257600080fd5b8660208260061b8501011115614ce757600080fd5b60209290920196919550909350505050565b600060208284031215614d0b57600080fd5b610a7682613fff565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136d060a08401826141f6565b600080600060408486031215614d7757600080fd5b833567ffffffffffffffff80821115614d8f57600080fd5b614d9b878388016145ca565b94506020860135915080821115614db157600080fd5b506143c786828701614288565b600060208284031215614dd057600080fd5b8135613ddc81613fea565b600082601f830112614dec57600080fd5b81356020614dfc61407c83613fc6565b8083825260208201915060208460051b870101935086841115614e1e57600080fd5b602086015b848110156120c5578035614e3681613fea565b8352918301918301614e23565b60006020808385031215614e5657600080fd5b823567ffffffffffffffff80821115614e6e57600080fd5b818501915085601f830112614e8257600080fd5b8135614e9061407c82613fc6565b81815260059190911b83018401908481019088831115614eaf57600080fd5b8585015b838110156141c557803585811115614eca57600080fd5b860160c0818c03601f19011215614ee15760008081fd5b614ee9613f2c565b8882013581526040614efc818401614b74565b8a8301526060614f0d818501614b74565b8284015260809150614f2082850161402a565b9083015260a08381013589811115614f385760008081fd5b614f468f8d83880101614ddb565b838501525060c0840135915088821115614f605760008081fd5b614f6e8e8c84870101614ddb565b9083015250845250918601918601614eb3565b600060208284031215614f9357600080fd5b5035919050565b80356001600160e01b038116811461401757600080fd5b600082601f830112614fc257600080fd5b81356020614fd261407c83613fc6565b82815260069290921b84018101918181019086841115614ff157600080fd5b8286015b848110156120c5576040818903121561500e5760008081fd5b615016613f4f565b61501f82613fff565b815261502c858301614f9a565b81860152835291830191604001614ff5565b600082601f83011261504f57600080fd5b8135602061505f61407c83613fc6565b82815260079290921b8401810191818101908684111561507e57600080fd5b8286015b848110156120c557808803608081121561509c5760008081fd5b6150a4613f72565b6150ad83613fff565b8152604080601f19840112156150c35760008081fd5b6150cb613f4f565b92506150d8878501613fff565b83526150e5818501613fff565b8388015281870192909252606083013591810191909152835291830191608001615082565b6000602080838503121561511d57600080fd5b823567ffffffffffffffff8082111561513557600080fd5b8185019150604080838803121561514b57600080fd5b615153613f4f565b83358381111561516257600080fd5b84016040818a03121561517457600080fd5b61517c613f4f565b81358581111561518b57600080fd5b8201601f81018b1361519c57600080fd5b80356151aa61407c82613fc6565b81815260069190911b8201890190898101908d8311156151c957600080fd5b928a01925b828410156152195787848f0312156151e65760008081fd5b6151ee613f4f565b84356151f981613fea565b8152615206858d01614f9a565b818d0152825292870192908a01906151ce565b84525050508187013593508484111561523157600080fd5b61523d8a858401614fb1565b818801528252508385013591508282111561525757600080fd5b6152638883860161503e565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b818110156152e257835180516001600160a01b031684528501516001600160e01b03168584015292840192918501916001016152ab565b50508583015187820388850152805180835290840192506000918401905b8083101561533c578351805167ffffffffffffffff1683528501516001600160e01b031685830152928401926001929092019190850190615300565b50979650505050505050565b602081526000610a76602083018461528b565b67ffffffffffffffff8316815260608101613ddc6020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153c7576153c7615390565b5092915050565b6000602080835260608451604080848701526153ed606087018361528b565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141c557845167ffffffffffffffff81511683528781015161544d89850182805167ffffffffffffffff908116835260209182015116910152565b5084015182870152938601936001929092019160809091019061540e565b60006020828403121561547d57600080fd5b813567ffffffffffffffff81111561549457600080fd5b6136d084828501614860565b81810381811115610a7957610a79615390565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff808416806154e4576154e46154b3565b92169190910692915050565b8082028115828204841417610a7957610a79615390565b60006040828403121561551957600080fd5b615521613f4f565b61552a83613fff565b8152602083013560208201528091505092915050565b600181811c9082168061555457607f821691505b60208210810361557457634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a060408701526155ae60a08701826141f6565b9050606085015186820360608801526155c782826141f6565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561533c57835180516001600160a01b03168352860151868301529285019260019290920191908401906155ea565b602081526000610a76602083018461557a565b608081526000615642608083018761557a565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561568057600080fd5b835161568b8161401c565b602085015190935067ffffffffffffffff8111156156a857600080fd5b8401601f810186136156b957600080fd5b80516156c761407c82614035565b8181528760208385010111156156dc57600080fd5b6156ed8260208301602086016141d2565b809450505050604084015190509250925092565b60006020828403121561571357600080fd5b8151613ddc8161401c565b601f821115610cd8576000816000526020600020601f850160051c810160208610156157475750805b601f850160051c820191505b818110156124df57828155600101615753565b815167ffffffffffffffff81111561578057615780613eca565b6157948161578e8454615540565b8461571e565b602080601f8311600181146157c957600084156157b15750858301515b600019600386901b1c1916600185901b1785556124df565b600085815260208120601f198616915b828110156157f8578886015182559484019460019091019084016157d9565b50858210156158165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c1660608501525060018085016080808601526000815461587881615540565b8060a089015260c0600183166000811461589957600181146158b5576158e5565b60ff19841660c08b015260c083151560051b8b010194506158e5565b85600052602060002060005b848110156158dc5781548c82018501529088019089016158c1565b8b0160c0019550505b50929998505050505050505050565b80820180821115610a7957610a79615390565b60ff8181168382160190811115610a7957610a79615390565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061595f5761595f6154b3565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126159a057600080fd5b83018035915067ffffffffffffffff8211156159bb57600080fd5b60200191503681900382131561384357600080fd5b60208101600583106159e4576159e4614407565b91905290565b60ff81811683821602908116908181146153c7576153c7615390565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a5e5784546001600160a01b031683526001948501949284019201615a39565b50508481036060860152865180825290820192508187019060005b81811015615a9e5782516001600160a01b031685529383019391830191600101615a79565b50505060ff851660808501525090506120c7565b600067ffffffffffffffff808616835280851660208401525060606040830152614c5160608301846141f6565b8281526040602082015260006136d060408301846141f6565b67ffffffffffffffff848116825283166020820152606081016136d0604083018461441d565b615b28818561441d565b606060208201526000615b3e60608301856141f6565b9050826040830152949350505050565b600060208284031215615b6057600080fd5b8151613ddc81613fea565b6020815260008251610100806020850152615b8a6101208501836141f6565b91506020850151615ba7604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615be160a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bfe84836141f6565b935060c08701519150808685030160e0870152615c1b84836141f6565b935060e08701519150808685030183870152506120c783826141f6565b600060208284031215615c4a57600080fd5b5051919050565b600060ff821660ff8103615c6757615c67615390565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c760808301846141f6565b86815260c060208201526000615cbc60c08301886141f6565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d8d57601f19868403018952815160808151818652615d39828701826141f6565b9150508582015185820387870152615d5182826141f6565b91505060408083015186830382880152615d6b83826141f6565b6060948501519790940196909652505098840198925090830190600101615d13565b5090979650505050505050565b602081526000610a766020830184615cf6565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d8d57601f19868403018952615de88383516141f6565b98840198925090830190600101615dcc565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e626101808501836141f6565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e9f84836141f6565b935060608801519150615ebe6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615ee58282615cf6565b9150508281036020840152614c518185615dad56fea164736f6c6343000818000a", +type OffRampCommitReport struct { + PriceUpdates InternalPriceUpdates + MerkleRoots []OffRampMerkleRoot +} + +type OffRampDynamicConfig struct { + PriceRegistry common.Address + PermissionLessExecutionThresholdSeconds uint32 + MaxTokenTransferGas uint32 + MaxPoolReleaseOrMintGas uint32 + MessageValidator common.Address +} + +type OffRampInterval struct { + Min uint64 + Max uint64 +} + +type OffRampMerkleRoot struct { + SourceChainSelector uint64 + Interval OffRampInterval + MerkleRoot [32]byte +} + +type OffRampSourceChainConfig struct { + Router common.Address + IsEnabled bool + MinSeqNr uint64 + OnRamp []byte +} + +type OffRampSourceChainConfigArgs struct { + Router common.Address + SourceChainSelector uint64 + IsEnabled bool + OnRamp []byte +} + +type OffRampStaticConfig struct { + ChainSelector uint64 + RmnProxy common.Address + TokenAdminRegistry common.Address + NonceManager common.Address +} + +type OffRampUnblessedRoot struct { + SourceChainSelector uint64 + MerkleRoot [32]byte +} + +var OffRampMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162006bdd38038062006bdd8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615f0762000cd6600039600081816102530152612c120152600081816102240152612ef80152600081816101f50152818161142f01526118400152600081816101c50152612801015260008181611dce0152611e1a0152615f076000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063d2a15d351461053d578063e9d68a8e14610550578063ece670b61461057057600080fd5b8063991a5018116100bd578063991a5018146104c5578063c673e584146104d8578063ccd37ba3146104f857600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104815780637d4eef601461048957600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a3660046140b3565b6105cc565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601181526020017f4f666652616d7020312e362e302d64657600000000000000000000000000000081525081565b6040516102d19190614222565b61018f6103313660046142cd565b6105e0565b61018f610344366004614380565b6109c0565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143d4565b610a29565b6040516102d19190614431565b6104246040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610a7f565b61018f610497366004614986565b610b3d565b61018f610177366004614ab1565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104d3366004614b00565b610cdd565b6104eb6104e6366004614b85565b610cee565b6040516102d19190614be5565b61052f610506366004614c5a565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f61054b366004614c84565b610e4c565b61056361055e366004614cf9565b610f06565b6040516102d19190614d14565b61018f61057e366004614d62565b611013565b61018f610591366004614dbe565b611386565b61018f6105a4366004614e43565b611397565b6105bc6105b7366004614f81565b6113d9565b60405190151581526020016102d1565b6105d461149a565b6105dd816114f6565b50565b60006105ee8789018961510a565b8051515190915015158061060757508051602001515115155b156107075760095460208a01359067ffffffffffffffff808316911610156106c6576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261068f929101615348565b600060405180830381600087803b1580156106a957600080fd5b505af11580156106bd573d6000803e3d6000fd5b50505050610705565b816020015151600003610705576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109095760008260200151828151811061072f5761072f615275565b6020026020010151905060008160000151905061074b816117f4565b6000610756826118f6565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061079a575060208084015190810151905167ffffffffffffffff9182169116115b156107e357825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107da92919060040161535b565b60405180910390fd5b60408301518061081f576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108925783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016107da565b60208085015101516108a59060016153a6565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff92831602179092559251166000908152600860209081526040808320948352939052919091204290555060010161070a565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161093991906153ce565b60405180910390a16109b560008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b925061195d915050565b505050505050505050565b610a006109cf8284018461546b565b60408051600080825260208201909252906109fa565b60608152602001906001900390816109e55790505b50611cd4565b604080516000808252602082019092529050610a2360018585858586600061195d565b50505050565b6000610a37600160046154a0565b6002610a446080856154c9565b67ffffffffffffffff16610a5891906154f0565b610a628585611d84565b901c166003811115610a7657610a76614407565b90505b92915050565b6001546001600160a01b03163314610ad95760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107da565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b45611dcb565b815181518114610b81576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ccd576000848281518110610ba057610ba0615275565b60200260200101519050600081602001515190506000858481518110610bc857610bc8615275565b6020026020010151905080518214610c0c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cbe576000828281518110610c2b57610c2b615275565b6020026020010151905080600014610cb55784602001518281518110610c5357610c53615275565b602002602001015160800151811015610cb55784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016107da565b50600101610c0f565b50505050806001019050610b84565b50610cd88383611cd4565b505050565b610ce561149a565b6105dd81611e4c565b610d316040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610dda57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dbc575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e1e575b5050505050815250509050919050565b610e5461149a565b60005b81811015610cd8576000838383818110610e7357610e73615275565b905060400201803603810190610e899190615507565b9050610e9881602001516113d9565b610efd57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e57565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191610f9390615540565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbf90615540565b8015610e3c5780601f10610fe157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610fef57505050919092525091949350505050565b33301461104c576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611089565b60408051808201909152600080825260208201528152602001906001900390816110625790505b5060a085015151909150156110bd576110ba8460a00151856020015186606001518760000151602001518787611fb2565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff16818301528087015183516000948401926110f9929101614222565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015611206576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a19061117390859060040161561c565b600060405180830381600087803b15801561118d57600080fd5b505af192505050801561119e575060015b611206573d8080156111cc576040519150601f19603f3d011682016040523d82523d6000602084013e6111d1565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b60408601515115801561121b57506080860151155b80611232575060608601516001600160a01b03163b155b8061127257506060860151611270906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120d1565b155b1561127f57505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf97983926112f7928992611388929160040161562f565b6000604051808303816000875af1158015611316573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261133e919081019061566b565b50915091508161137c57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b5050505050505050565b61138e61149a565b6105dd816120ed565b61139f61149a565b60005b81518110156113d5576113cd8282815181106113c0576113c0615275565b60200260200101516121a3565b6001016113a2565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611476573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a799190615701565b6000546001600160a01b031633146114f45760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107da565b565b60005b81518110156113d557600082828151811061151657611516615275565b602002602001015190506000816020015190508067ffffffffffffffff1660000361156d576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611595576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115c090615540565b80601f01602080910402602001604051908101604052809291908181526020018280546115ec90615540565b80156116395780601f1061160e57610100808354040283529160200191611639565b820191906000526020600020905b81548152906001019060200180831161161c57829003601f168201915b5050505050905060008460600151905081516000036116f1578051600003611674576040516342bcdf7f60e11b815260040160405180910390fd5b600183016116828282615766565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611744565b8080519060200120828051906020012014611744576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016107da565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117dc908690615826565b60405180910390a250505050508060010190506114f9565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b39190615701565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107da565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610a79576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107da565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906119bc8760a46158f4565b9050826060015115611a045784516119d59060206154f0565b86516119e29060206154f0565b6119ed9060a06158f4565b6119f791906158f4565b611a0190826158f4565b90505b368114611a46576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107da565b5081518114611a8e5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107da565b611a96611dcb565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611ae457611ae4614407565b6002811115611af557611af5614407565b9052509050600281602001516002811115611b1257611b12614407565b148015611b665750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611b4e57611b4e615275565b6000918252602090912001546001600160a01b031633145b611b9c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611c7e576020820151611bb7906001615907565b60ff16855114611bf3576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611c2e576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611c40929190615920565b604051908190038120611c57918b90602001615930565b604051602081830303815290604052805190602001209050611c7c8a828888886124e7565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d0e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611d7d57611d75858281518110611d4357611d43615275565b602002602001015184611d6f57858381518110611d6257611d62615275565b60200260200101516126f4565b836126f4565b600101611d25565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611da9608085615944565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f0000000000000000000000000000000000000000000000000000000000000000146114f4576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107da565b80516001600160a01b0316611e74576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fce57611fce613eca565b60405190808252806020026020018201604052801561201357816020015b6040805180820190915260008082526020820152815260200190600190039081611fec5790505b50905060005b87518110156120c5576120a088828151811061203757612037615275565b602002602001015188888888888781811061205457612054615275565b9050602002810190612066919061596b565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9792505050565b8282815181106120b2576120b2615275565b6020908102919091010152600101612019565b505b9695505050505050565b60006120dc8361323c565b8015610a765750610a7683836132a0565b336001600160a01b038216036121455760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107da565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ce576000604051631b3fab5160e11b81526004016107da91906159d0565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223b57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612290565b6060840151600182015460ff6201000090910416151590151514612290576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016107da565b60a08401518051601f60ff821611156122bf576001604051631b3fab5160e11b81526004016107da91906159d0565b612325858560030180548060200260200160405190810160405280929190818152602001828054801561231b57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122fd575b505050505061335b565b85606001511561245457612393858560020180548060200260200160405190810160405280929190818152602001828054801561231b576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122fd57505050505061335b565b608086015180516123ad9060028701906020840190613e24565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f101561240d576002604051631b3fab5160e11b81526004016107da91906159d0565b604088015161241d9060036159ea565b60ff168160ff1611612445576003604051631b3fab5160e11b81526004016107da91906159d0565b612451878360016133c4565b50505b612460858360026133c4565b81516124759060038601906020850190613e24565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ce938a939260028b01929190615a06565b60405180910390a16124df85613544565b505050505050565b6124ef613e96565b835160005b8181101561137c57600060018886846020811061251357612513615275565b61252091901a601b615907565b89858151811061253257612532615275565b602002602001015189868151811061254c5761254c615275565b60200260200101516040516000815260200160405260405161258a949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156125ac573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561260d5761260d614407565b600281111561261e5761261e614407565b905250905060018160200151600281111561263b5761263b614407565b14612672576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061268957612689615275565b6020020151156126c5576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126e0576126e0615275565b9115156020909202015250506001016124f4565b81516126ff816117f4565b600061270a826118f6565b602085015151909150600081900361274d576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461278b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156127a6576127a6613eca565b6040519080825280602002602001820160405280156127cf578160200160208202803683370190505b50905060005b82811015612944576000876020015182815181106127f5576127f5615275565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461288857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107da565b61291e8186600101805461289b90615540565b80601f01602080910402602001604051908101604052809291908181526020018280546128c790615540565b80156129145780601f106128e957610100808354040283529160200191612914565b820191906000526020600020905b8154815290600101906020018083116128f757829003601f168201915b5050505050613560565b83838151811061293057612930615275565b6020908102919091010152506001016127d5565b50600061295b858389606001518a60800151613682565b9050806000036129a3576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107da565b8551151560005b848110156109b55760005a905060008a6020015183815181106129cf576129cf615275565b6020026020010151905060006129ed8a836000015160600151610a29565b90506000816003811115612a0357612a03614407565b1480612a2057506003816003811115612a1e57612a1e614407565b145b612a78578151606001516040805167ffffffffffffffff808e16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a1505050612e8f565b8415612b4857600454600090600160a01b900463ffffffff16612a9b88426154a0565b1190508080612abb57506003826003811115612ab957612ab9614407565b145b612afd576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8c1660048201526024016107da565b8b8581518110612b0f57612b0f615275565b6020026020010151600014612b42578b8581518110612b3057612b30615275565b60200260200101518360800181815250505b50612ba9565b6000816003811115612b5c57612b5c614407565b14612ba9578151606001516040805167ffffffffffffffff808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612a68565b81516080015167ffffffffffffffff1615612c98576000816003811115612bd257612bd2614407565b03612c985781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c49928f929190600401615ab2565b6020604051808303816000875af1158015612c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8c9190615701565b612c9857505050612e8f565b60008c604001518581518110612cb057612cb0615275565b6020026020010151905080518360a001515114612d14578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808e16600483015290911660248201526044016107da565b612d288b84600001516060015160016136d8565b600080612d358584613780565b91509150612d4c8d866000015160600151846136d8565b8715612dbc576003826003811115612d6657612d66614407565b03612dbc576000846003811115612d7f57612d7f614407565b14612dbc578451516040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526107da91908390600401615adf565b6002826003811115612dd057612dd0614407565b14612e2a576003826003811115612de957612de9614407565b14612e2a578451606001516040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526107da918f918590600401615af8565b8451805160609091015167ffffffffffffffff908116908f167fdc8ccbc35e0eebd81239bcd1971fcd53c7eb34034880142a0f43c809a458732f85855a612e71908d6154a0565b604051612e8093929190615b1e565b60405180910390a45050505050505b6001016129aa565b60408051808201909152600080825260208201526000612eba876020015161384a565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f639190615b4e565b90506001600160a01b0381161580612fab5750612fa96001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120d1565b155b15612fed576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016107da565b600454600090819061300f9089908690600160e01b900463ffffffff166138f0565b9150915060008060006130dc6040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b81525060405160240161308d9190615b6b565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a1e565b9250925092508261311b57816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b81516020146131635781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b6000828060200190518101906131799190615c38565b9050866001600160a01b03168c6001600160a01b03161461320e5760006131aa8d8a6131a5868a6154a0565b6138f0565b509050868110806131c45750816131c188836154a0565b14155b1561320c576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016107da565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613268827f01ffc9a7000000000000000000000000000000000000000000000000000000006132a0565b8015610a795750613299827fffffffff000000000000000000000000000000000000000000000000000000006132a0565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015613344575060208210155b80156133505750600081115b979650505050505050565b60005b8151811015610cd85760ff83166000908152600360205260408120835190919084908490811061339057613390615275565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161335e565b60005b82518160ff161015610a23576000838260ff16815181106133ea576133ea615275565b602002602001015190506000600281111561340757613407614407565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561344657613446614407565b14613467576004604051631b3fab5160e11b81526004016107da91906159d0565b6001600160a01b0381166134a7576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134cd576134cd614407565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561352a5761352a614407565b0217905550905050508061353d90615c51565b90506133c7565b60ff81166105dd576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936135a6937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c70565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135ef9794969395929491939101615ca3565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136269190615d9a565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b600080613690858585613b44565b905061369b816113d9565b6136a95760009150506136d0565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026136e76080856154c9565b67ffffffffffffffff166136fb91906154f0565b905060006137098585611d84565b905081613718600160046154a0565b901b19168183600381111561372f5761372f614407565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161375e608088615944565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906137c49087908790600401615dfa565b600060405180830381600087803b1580156137de57600080fd5b505af19250505080156137ef575060015b61382e573d80801561381d576040519150601f19603f3d011682016040523d82523d6000602084013e613822565b606091505b50600392509050613843565b50506040805160208101909152600081526002905b9250929050565b6000815160201461388957816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b60008280602001905181019061389f9190615c38565b90506001600160a01b038111806138b7575061040081105b15610a7957826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b600080600080600061396a8860405160240161391b91906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a1e565b925092509250826139a957816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b60208251146139f15781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b81806020019051810190613a059190615c38565b613a0f82886154a0565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a4157613a41613eca565b6040519080825280601f01601f191660200182016040528015613a6b576020820181803683370190505b509150863b613a9e577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613ad1577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613b0a577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b2d5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b85576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b9957506101018111155b613bb6576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613be0576040516309bde33960e01b815260040160405180910390fd5b80600003613c0d5786600081518110613bfb57613bfb615275565b60200260200101519350505050613ddc565b60008167ffffffffffffffff811115613c2857613c28613eca565b604051908082528060200260200182016040528015613c51578160200160208202803683370190505b50905060008080805b85811015613d7b5760006001821b8b811603613cb55788851015613c9e578c5160018601958e918110613c8f57613c8f615275565b60200260200101519050613cd7565b8551600185019487918110613c8f57613c8f615275565b8b5160018401938d918110613ccc57613ccc615275565b602002602001015190505b600089861015613d07578d5160018701968f918110613cf857613cf8615275565b60200260200101519050613d29565b8651600186019588918110613d1e57613d1e615275565b602002602001015190505b82851115613d4a576040516309bde33960e01b815260040160405180910390fd5b613d548282613de3565b878481518110613d6657613d66615275565b60209081029190910101525050600101613c5a565b506001850382148015613d8d57508683145b8015613d9857508581145b613db5576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613dca57613dca615275565b60200260200101519750505050505050505b9392505050565b6000818310613dfb57613df68284613e01565b610a76565b610a7683835b604080516001602082015290810183905260608101829052600090608001613664565b828054828255906000526020600020908101928215613e86579160200282015b82811115613e86578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e44565b50613e92929150613eb5565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e925760008155600101613eb6565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613f0357613f03613eca565b60405290565b60405160a0810167ffffffffffffffff81118282101715613f0357613f03613eca565b60405160c0810167ffffffffffffffff81118282101715613f0357613f03613eca565b6040805190810167ffffffffffffffff81118282101715613f0357613f03613eca565b6040516060810167ffffffffffffffff81118282101715613f0357613f03613eca565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fbe57613fbe613eca565b604052919050565b600067ffffffffffffffff821115613fe057613fe0613eca565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461401757600080fd5b919050565b80151581146105dd57600080fd5b80356140178161401c565b600067ffffffffffffffff82111561404f5761404f613eca565b50601f01601f191660200190565b600082601f83011261406e57600080fd5b813561408161407c82614035565b613f95565b81815284602083860101111561409657600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140c657600080fd5b823567ffffffffffffffff808211156140de57600080fd5b818501915085601f8301126140f257600080fd5b813561410061407c82613fc6565b81815260059190911b8301840190848101908883111561411f57600080fd5b8585015b838110156141c55780358581111561413b5760008081fd5b86016080818c03601f19018113156141535760008081fd5b61415b613ee0565b8983013561416881613fea565b81526040614177848201613fff565b8b83015260608085013561418a8161401c565b838301529284013592898411156141a357600091508182fd5b6141b18f8d8688010161405d565b908301525085525050918601918601614123565b5098975050505050505050565b60005b838110156141ed5781810151838201526020016141d5565b50506000910152565b6000815180845261420e8160208601602086016141d2565b601f01601f19169290920160200192915050565b602081526000610a7660208301846141f6565b8060608101831015610a7957600080fd5b60008083601f84011261425857600080fd5b50813567ffffffffffffffff81111561427057600080fd5b60208301915083602082850101111561384357600080fd5b60008083601f84011261429a57600080fd5b50813567ffffffffffffffff8111156142b257600080fd5b6020830191508360208260051b850101111561384357600080fd5b60008060008060008060008060e0898b0312156142e957600080fd5b6142f38a8a614235565b9750606089013567ffffffffffffffff8082111561431057600080fd5b61431c8c838d01614246565b909950975060808b013591508082111561433557600080fd5b6143418c838d01614288565b909750955060a08b013591508082111561435a57600080fd5b506143678b828c01614288565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561439557600080fd5b61439f8585614235565b9250606084013567ffffffffffffffff8111156143bb57600080fd5b6143c786828701614246565b9497909650939450505050565b600080604083850312156143e757600080fd5b6143f083613fff565b91506143fe60208401613fff565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061442d5761442d614407565b9052565b60208101610a79828461441d565b600060a0828403121561445157600080fd5b614459613f09565b90508135815261446b60208301613fff565b602082015261447c60408301613fff565b604082015261448d60608301613fff565b606082015261449e60808301613fff565b608082015292915050565b803561401781613fea565b600082601f8301126144c557600080fd5b813560206144d561407c83613fc6565b82815260059290921b840181019181810190868411156144f457600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156145195760008081fd5b8189019150608080601f19848d030112156145345760008081fd5b61453c613ee0565b878401358381111561454e5760008081fd5b61455c8d8a8388010161405d565b825250604080850135848111156145735760008081fd5b6145818e8b8389010161405d565b8a840152506060808601358581111561459a5760008081fd5b6145a88f8c838a010161405d565b92840192909252949092013593810193909352505083529183019183016144f8565b600061014082840312156145dd57600080fd5b6145e5613f2c565b90506145f1838361443f565b815260a082013567ffffffffffffffff8082111561460e57600080fd5b61461a8583860161405d565b602084015260c084013591508082111561463357600080fd5b61463f8583860161405d565b604084015261465060e085016144a9565b6060840152610100840135608084015261012084013591508082111561467557600080fd5b50614682848285016144b4565b60a08301525092915050565b600082601f83011261469f57600080fd5b813560206146af61407c83613fc6565b82815260059290921b840181019181810190868411156146ce57600080fd5b8286015b848110156120c557803567ffffffffffffffff8111156146f25760008081fd5b6147008986838b01016145ca565b8452509183019183016146d2565b600082601f83011261471f57600080fd5b8135602061472f61407c83613fc6565b82815260059290921b8401810191818101908684111561474e57600080fd5b8286015b848110156120c557803567ffffffffffffffff8082111561477257600080fd5b818901915089603f83011261478657600080fd5b8582013561479661407c82613fc6565b81815260059190911b830160400190878101908c8311156147b657600080fd5b604085015b838110156147ef578035858111156147d257600080fd5b6147e18f6040838a010161405d565b8452509189019189016147bb565b50875250505092840192508301614752565b600082601f83011261481257600080fd5b8135602061482261407c83613fc6565b8083825260208201915060208460051b87010193508684111561484457600080fd5b602086015b848110156120c55780358352918301918301614849565b600082601f83011261487157600080fd5b8135602061488161407c83613fc6565b82815260059290921b840181019181810190868411156148a057600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156148c55760008081fd5b818901915060a080601f19848d030112156148e05760008081fd5b6148e8613f09565b6148f3888501613fff565b8152604080850135848111156149095760008081fd5b6149178e8b8389010161468e565b8a84015250606080860135858111156149305760008081fd5b61493e8f8c838a010161470e565b83850152506080915081860135858111156149595760008081fd5b6149678f8c838a0101614801565b91840191909152509190930135908301525083529183019183016148a4565b600080604080848603121561499a57600080fd5b833567ffffffffffffffff808211156149b257600080fd5b6149be87838801614860565b94506020915081860135818111156149d557600080fd5b8601601f810188136149e657600080fd5b80356149f461407c82613fc6565b81815260059190911b8201840190848101908a831115614a1357600080fd5b8584015b83811015614a9f57803586811115614a2f5760008081fd5b8501603f81018d13614a415760008081fd5b87810135614a5161407c82613fc6565b81815260059190911b82018a0190898101908f831115614a715760008081fd5b928b01925b82841015614a8f5783358252928a0192908a0190614a76565b8652505050918601918601614a17565b50809750505050505050509250929050565b600060208284031215614ac357600080fd5b813567ffffffffffffffff811115614ada57600080fd5b820160a08185031215613ddc57600080fd5b803563ffffffff8116811461401757600080fd5b600060a08284031215614b1257600080fd5b614b1a613f09565b8235614b2581613fea565b8152614b3360208401614aec565b6020820152614b4460408401614aec565b6040820152614b5560608401614aec565b60608201526080830135614b6881613fea565b60808201529392505050565b803560ff8116811461401757600080fd5b600060208284031215614b9757600080fd5b610a7682614b74565b60008151808452602080850194506020840160005b83811015614bda5781516001600160a01b031687529582019590820190600101614bb5565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c3460e0840182614ba0565b90506040840151601f198483030160c0850152614c518282614ba0565b95945050505050565b60008060408385031215614c6d57600080fd5b614c7683613fff565b946020939093013593505050565b60008060208385031215614c9757600080fd5b823567ffffffffffffffff80821115614caf57600080fd5b818501915085601f830112614cc357600080fd5b813581811115614cd257600080fd5b8660208260061b8501011115614ce757600080fd5b60209290920196919550909350505050565b600060208284031215614d0b57600080fd5b610a7682613fff565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136d060a08401826141f6565b600080600060408486031215614d7757600080fd5b833567ffffffffffffffff80821115614d8f57600080fd5b614d9b878388016145ca565b94506020860135915080821115614db157600080fd5b506143c786828701614288565b600060208284031215614dd057600080fd5b8135613ddc81613fea565b600082601f830112614dec57600080fd5b81356020614dfc61407c83613fc6565b8083825260208201915060208460051b870101935086841115614e1e57600080fd5b602086015b848110156120c5578035614e3681613fea565b8352918301918301614e23565b60006020808385031215614e5657600080fd5b823567ffffffffffffffff80821115614e6e57600080fd5b818501915085601f830112614e8257600080fd5b8135614e9061407c82613fc6565b81815260059190911b83018401908481019088831115614eaf57600080fd5b8585015b838110156141c557803585811115614eca57600080fd5b860160c0818c03601f19011215614ee15760008081fd5b614ee9613f2c565b8882013581526040614efc818401614b74565b8a8301526060614f0d818501614b74565b8284015260809150614f2082850161402a565b9083015260a08381013589811115614f385760008081fd5b614f468f8d83880101614ddb565b838501525060c0840135915088821115614f605760008081fd5b614f6e8e8c84870101614ddb565b9083015250845250918601918601614eb3565b600060208284031215614f9357600080fd5b5035919050565b80356001600160e01b038116811461401757600080fd5b600082601f830112614fc257600080fd5b81356020614fd261407c83613fc6565b82815260069290921b84018101918181019086841115614ff157600080fd5b8286015b848110156120c5576040818903121561500e5760008081fd5b615016613f4f565b61501f82613fff565b815261502c858301614f9a565b81860152835291830191604001614ff5565b600082601f83011261504f57600080fd5b8135602061505f61407c83613fc6565b82815260079290921b8401810191818101908684111561507e57600080fd5b8286015b848110156120c557808803608081121561509c5760008081fd5b6150a4613f72565b6150ad83613fff565b8152604080601f19840112156150c35760008081fd5b6150cb613f4f565b92506150d8878501613fff565b83526150e5818501613fff565b8388015281870192909252606083013591810191909152835291830191608001615082565b6000602080838503121561511d57600080fd5b823567ffffffffffffffff8082111561513557600080fd5b8185019150604080838803121561514b57600080fd5b615153613f4f565b83358381111561516257600080fd5b84016040818a03121561517457600080fd5b61517c613f4f565b81358581111561518b57600080fd5b8201601f81018b1361519c57600080fd5b80356151aa61407c82613fc6565b81815260069190911b8201890190898101908d8311156151c957600080fd5b928a01925b828410156152195787848f0312156151e65760008081fd5b6151ee613f4f565b84356151f981613fea565b8152615206858d01614f9a565b818d0152825292870192908a01906151ce565b84525050508187013593508484111561523157600080fd5b61523d8a858401614fb1565b818801528252508385013591508282111561525757600080fd5b6152638883860161503e565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b818110156152e257835180516001600160a01b031684528501516001600160e01b03168584015292840192918501916001016152ab565b50508583015187820388850152805180835290840192506000918401905b8083101561533c578351805167ffffffffffffffff1683528501516001600160e01b031685830152928401926001929092019190850190615300565b50979650505050505050565b602081526000610a76602083018461528b565b67ffffffffffffffff8316815260608101613ddc6020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153c7576153c7615390565b5092915050565b6000602080835260608451604080848701526153ed606087018361528b565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141c557845167ffffffffffffffff81511683528781015161544d89850182805167ffffffffffffffff908116835260209182015116910152565b5084015182870152938601936001929092019160809091019061540e565b60006020828403121561547d57600080fd5b813567ffffffffffffffff81111561549457600080fd5b6136d084828501614860565b81810381811115610a7957610a79615390565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff808416806154e4576154e46154b3565b92169190910692915050565b8082028115828204841417610a7957610a79615390565b60006040828403121561551957600080fd5b615521613f4f565b61552a83613fff565b8152602083013560208201528091505092915050565b600181811c9082168061555457607f821691505b60208210810361557457634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a060408701526155ae60a08701826141f6565b9050606085015186820360608801526155c782826141f6565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561533c57835180516001600160a01b03168352860151868301529285019260019290920191908401906155ea565b602081526000610a76602083018461557a565b608081526000615642608083018761557a565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561568057600080fd5b835161568b8161401c565b602085015190935067ffffffffffffffff8111156156a857600080fd5b8401601f810186136156b957600080fd5b80516156c761407c82614035565b8181528760208385010111156156dc57600080fd5b6156ed8260208301602086016141d2565b809450505050604084015190509250925092565b60006020828403121561571357600080fd5b8151613ddc8161401c565b601f821115610cd8576000816000526020600020601f850160051c810160208610156157475750805b601f850160051c820191505b818110156124df57828155600101615753565b815167ffffffffffffffff81111561578057615780613eca565b6157948161578e8454615540565b8461571e565b602080601f8311600181146157c957600084156157b15750858301515b600019600386901b1c1916600185901b1785556124df565b600085815260208120601f198616915b828110156157f8578886015182559484019460019091019084016157d9565b50858210156158165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c1660608501525060018085016080808601526000815461587881615540565b8060a089015260c0600183166000811461589957600181146158b5576158e5565b60ff19841660c08b015260c083151560051b8b010194506158e5565b85600052602060002060005b848110156158dc5781548c82018501529088019089016158c1565b8b0160c0019550505b50929998505050505050505050565b80820180821115610a7957610a79615390565b60ff8181168382160190811115610a7957610a79615390565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061595f5761595f6154b3565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126159a057600080fd5b83018035915067ffffffffffffffff8211156159bb57600080fd5b60200191503681900382131561384357600080fd5b60208101600583106159e4576159e4614407565b91905290565b60ff81811683821602908116908181146153c7576153c7615390565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a5e5784546001600160a01b031683526001948501949284019201615a39565b50508481036060860152865180825290820192508187019060005b81811015615a9e5782516001600160a01b031685529383019391830191600101615a79565b50505060ff851660808501525090506120c7565b600067ffffffffffffffff808616835280851660208401525060606040830152614c5160608301846141f6565b8281526040602082015260006136d060408301846141f6565b67ffffffffffffffff848116825283166020820152606081016136d0604083018461441d565b615b28818561441d565b606060208201526000615b3e60608301856141f6565b9050826040830152949350505050565b600060208284031215615b6057600080fd5b8151613ddc81613fea565b6020815260008251610100806020850152615b8a6101208501836141f6565b91506020850151615ba7604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615be160a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bfe84836141f6565b935060c08701519150808685030160e0870152615c1b84836141f6565b935060e08701519150808685030183870152506120c783826141f6565b600060208284031215615c4a57600080fd5b5051919050565b600060ff821660ff8103615c6757615c67615390565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c760808301846141f6565b86815260c060208201526000615cbc60c08301886141f6565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d8d57601f19868403018952815160808151818652615d39828701826141f6565b9150508582015185820387870152615d5182826141f6565b91505060408083015186830382880152615d6b83826141f6565b6060948501519790940196909652505098840198925090830190600101615d13565b5090979650505050505050565b602081526000610a766020830184615cf6565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d8d57601f19868403018952615de88383516141f6565b98840198925090830190600101615dcc565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e626101808501836141f6565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e9f84836141f6565b935060608801519150615ebe6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615ee58282615cf6565b9150508281036020840152614c518185615dad56fea164736f6c6343000818000a", } -var EVM2EVMMultiOffRampABI = EVM2EVMMultiOffRampMetaData.ABI +var OffRampABI = OffRampMetaData.ABI -var EVM2EVMMultiOffRampBin = EVM2EVMMultiOffRampMetaData.Bin +var OffRampBin = OffRampMetaData.Bin -func DeployEVM2EVMMultiOffRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMMultiOffRampStaticConfig, dynamicConfig EVM2EVMMultiOffRampDynamicConfig, sourceChainConfigs []EVM2EVMMultiOffRampSourceChainConfigArgs) (common.Address, *types.Transaction, *EVM2EVMMultiOffRamp, error) { - parsed, err := EVM2EVMMultiOffRampMetaData.GetAbi() +func DeployOffRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig OffRampStaticConfig, dynamicConfig OffRampDynamicConfig, sourceChainConfigs []OffRampSourceChainConfigArgs) (common.Address, *types.Transaction, *OffRamp, error) { + parsed, err := OffRampMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -180,132 +180,132 @@ func DeployEVM2EVMMultiOffRamp(auth *bind.TransactOpts, backend bind.ContractBac return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMMultiOffRampBin), backend, staticConfig, dynamicConfig, sourceChainConfigs) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(OffRampBin), backend, staticConfig, dynamicConfig, sourceChainConfigs) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &EVM2EVMMultiOffRamp{address: address, abi: *parsed, EVM2EVMMultiOffRampCaller: EVM2EVMMultiOffRampCaller{contract: contract}, EVM2EVMMultiOffRampTransactor: EVM2EVMMultiOffRampTransactor{contract: contract}, EVM2EVMMultiOffRampFilterer: EVM2EVMMultiOffRampFilterer{contract: contract}}, nil + return address, tx, &OffRamp{address: address, abi: *parsed, OffRampCaller: OffRampCaller{contract: contract}, OffRampTransactor: OffRampTransactor{contract: contract}, OffRampFilterer: OffRampFilterer{contract: contract}}, nil } -type EVM2EVMMultiOffRamp struct { +type OffRamp struct { address common.Address abi abi.ABI - EVM2EVMMultiOffRampCaller - EVM2EVMMultiOffRampTransactor - EVM2EVMMultiOffRampFilterer + OffRampCaller + OffRampTransactor + OffRampFilterer } -type EVM2EVMMultiOffRampCaller struct { +type OffRampCaller struct { contract *bind.BoundContract } -type EVM2EVMMultiOffRampTransactor struct { +type OffRampTransactor struct { contract *bind.BoundContract } -type EVM2EVMMultiOffRampFilterer struct { +type OffRampFilterer struct { contract *bind.BoundContract } -type EVM2EVMMultiOffRampSession struct { - Contract *EVM2EVMMultiOffRamp +type OffRampSession struct { + Contract *OffRamp CallOpts bind.CallOpts TransactOpts bind.TransactOpts } -type EVM2EVMMultiOffRampCallerSession struct { - Contract *EVM2EVMMultiOffRampCaller +type OffRampCallerSession struct { + Contract *OffRampCaller CallOpts bind.CallOpts } -type EVM2EVMMultiOffRampTransactorSession struct { - Contract *EVM2EVMMultiOffRampTransactor +type OffRampTransactorSession struct { + Contract *OffRampTransactor TransactOpts bind.TransactOpts } -type EVM2EVMMultiOffRampRaw struct { - Contract *EVM2EVMMultiOffRamp +type OffRampRaw struct { + Contract *OffRamp } -type EVM2EVMMultiOffRampCallerRaw struct { - Contract *EVM2EVMMultiOffRampCaller +type OffRampCallerRaw struct { + Contract *OffRampCaller } -type EVM2EVMMultiOffRampTransactorRaw struct { - Contract *EVM2EVMMultiOffRampTransactor +type OffRampTransactorRaw struct { + Contract *OffRampTransactor } -func NewEVM2EVMMultiOffRamp(address common.Address, backend bind.ContractBackend) (*EVM2EVMMultiOffRamp, error) { - abi, err := abi.JSON(strings.NewReader(EVM2EVMMultiOffRampABI)) +func NewOffRamp(address common.Address, backend bind.ContractBackend) (*OffRamp, error) { + abi, err := abi.JSON(strings.NewReader(OffRampABI)) if err != nil { return nil, err } - contract, err := bindEVM2EVMMultiOffRamp(address, backend, backend, backend) + contract, err := bindOffRamp(address, backend, backend, backend) if err != nil { return nil, err } - return &EVM2EVMMultiOffRamp{address: address, abi: abi, EVM2EVMMultiOffRampCaller: EVM2EVMMultiOffRampCaller{contract: contract}, EVM2EVMMultiOffRampTransactor: EVM2EVMMultiOffRampTransactor{contract: contract}, EVM2EVMMultiOffRampFilterer: EVM2EVMMultiOffRampFilterer{contract: contract}}, nil + return &OffRamp{address: address, abi: abi, OffRampCaller: OffRampCaller{contract: contract}, OffRampTransactor: OffRampTransactor{contract: contract}, OffRampFilterer: OffRampFilterer{contract: contract}}, nil } -func NewEVM2EVMMultiOffRampCaller(address common.Address, caller bind.ContractCaller) (*EVM2EVMMultiOffRampCaller, error) { - contract, err := bindEVM2EVMMultiOffRamp(address, caller, nil, nil) +func NewOffRampCaller(address common.Address, caller bind.ContractCaller) (*OffRampCaller, error) { + contract, err := bindOffRamp(address, caller, nil, nil) if err != nil { return nil, err } - return &EVM2EVMMultiOffRampCaller{contract: contract}, nil + return &OffRampCaller{contract: contract}, nil } -func NewEVM2EVMMultiOffRampTransactor(address common.Address, transactor bind.ContractTransactor) (*EVM2EVMMultiOffRampTransactor, error) { - contract, err := bindEVM2EVMMultiOffRamp(address, nil, transactor, nil) +func NewOffRampTransactor(address common.Address, transactor bind.ContractTransactor) (*OffRampTransactor, error) { + contract, err := bindOffRamp(address, nil, transactor, nil) if err != nil { return nil, err } - return &EVM2EVMMultiOffRampTransactor{contract: contract}, nil + return &OffRampTransactor{contract: contract}, nil } -func NewEVM2EVMMultiOffRampFilterer(address common.Address, filterer bind.ContractFilterer) (*EVM2EVMMultiOffRampFilterer, error) { - contract, err := bindEVM2EVMMultiOffRamp(address, nil, nil, filterer) +func NewOffRampFilterer(address common.Address, filterer bind.ContractFilterer) (*OffRampFilterer, error) { + contract, err := bindOffRamp(address, nil, nil, filterer) if err != nil { return nil, err } - return &EVM2EVMMultiOffRampFilterer{contract: contract}, nil + return &OffRampFilterer{contract: contract}, nil } -func bindEVM2EVMMultiOffRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := EVM2EVMMultiOffRampMetaData.GetAbi() +func bindOffRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OffRampMetaData.GetAbi() if err != nil { return nil, err } return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _EVM2EVMMultiOffRamp.Contract.EVM2EVMMultiOffRampCaller.contract.Call(opts, result, method, params...) +func (_OffRamp *OffRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OffRamp.Contract.OffRampCaller.contract.Call(opts, result, method, params...) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.EVM2EVMMultiOffRampTransactor.contract.Transfer(opts) +func (_OffRamp *OffRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OffRamp.Contract.OffRampTransactor.contract.Transfer(opts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.EVM2EVMMultiOffRampTransactor.contract.Transact(opts, method, params...) +func (_OffRamp *OffRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OffRamp.Contract.OffRampTransactor.contract.Transact(opts, method, params...) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _EVM2EVMMultiOffRamp.Contract.contract.Call(opts, result, method, params...) +func (_OffRamp *OffRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OffRamp.Contract.contract.Call(opts, result, method, params...) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.contract.Transfer(opts) +func (_OffRamp *OffRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OffRamp.Contract.contract.Transfer(opts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.contract.Transact(opts, method, params...) +func (_OffRamp *OffRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OffRamp.Contract.contract.Transact(opts, method, params...) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) CcipReceive(opts *bind.CallOpts, arg0 ClientAny2EVMMessage) error { +func (_OffRamp *OffRampCaller) CcipReceive(opts *bind.CallOpts, arg0 ClientAny2EVMMessage) error { var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "ccipReceive", arg0) + err := _OffRamp.contract.Call(opts, &out, "ccipReceive", arg0) if err != nil { return err @@ -315,39 +315,39 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) CcipReceive(opts *bind.Ca } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) CcipReceive(arg0 ClientAny2EVMMessage) error { - return _EVM2EVMMultiOffRamp.Contract.CcipReceive(&_EVM2EVMMultiOffRamp.CallOpts, arg0) +func (_OffRamp *OffRampSession) CcipReceive(arg0 ClientAny2EVMMessage) error { + return _OffRamp.Contract.CcipReceive(&_OffRamp.CallOpts, arg0) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) CcipReceive(arg0 ClientAny2EVMMessage) error { - return _EVM2EVMMultiOffRamp.Contract.CcipReceive(&_EVM2EVMMultiOffRamp.CallOpts, arg0) +func (_OffRamp *OffRampCallerSession) CcipReceive(arg0 ClientAny2EVMMessage) error { + return _OffRamp.Contract.CcipReceive(&_OffRamp.CallOpts, arg0) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMMultiOffRampDynamicConfig, error) { +func (_OffRamp *OffRampCaller) GetDynamicConfig(opts *bind.CallOpts) (OffRampDynamicConfig, error) { var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getDynamicConfig") + err := _OffRamp.contract.Call(opts, &out, "getDynamicConfig") if err != nil { - return *new(EVM2EVMMultiOffRampDynamicConfig), err + return *new(OffRampDynamicConfig), err } - out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOffRampDynamicConfig)).(*EVM2EVMMultiOffRampDynamicConfig) + out0 := *abi.ConvertType(out[0], new(OffRampDynamicConfig)).(*OffRampDynamicConfig) return out0, err } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetDynamicConfig() (EVM2EVMMultiOffRampDynamicConfig, error) { - return _EVM2EVMMultiOffRamp.Contract.GetDynamicConfig(&_EVM2EVMMultiOffRamp.CallOpts) +func (_OffRamp *OffRampSession) GetDynamicConfig() (OffRampDynamicConfig, error) { + return _OffRamp.Contract.GetDynamicConfig(&_OffRamp.CallOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetDynamicConfig() (EVM2EVMMultiOffRampDynamicConfig, error) { - return _EVM2EVMMultiOffRamp.Contract.GetDynamicConfig(&_EVM2EVMMultiOffRamp.CallOpts) +func (_OffRamp *OffRampCallerSession) GetDynamicConfig() (OffRampDynamicConfig, error) { + return _OffRamp.Contract.GetDynamicConfig(&_OffRamp.CallOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetExecutionState(opts *bind.CallOpts, sourceChainSelector uint64, sequenceNumber uint64) (uint8, error) { +func (_OffRamp *OffRampCaller) GetExecutionState(opts *bind.CallOpts, sourceChainSelector uint64, sequenceNumber uint64) (uint8, error) { var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getExecutionState", sourceChainSelector, sequenceNumber) + err := _OffRamp.contract.Call(opts, &out, "getExecutionState", sourceChainSelector, sequenceNumber) if err != nil { return *new(uint8), err @@ -359,17 +359,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetExecutionState(opts *b } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetExecutionState(sourceChainSelector uint64, sequenceNumber uint64) (uint8, error) { - return _EVM2EVMMultiOffRamp.Contract.GetExecutionState(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector, sequenceNumber) +func (_OffRamp *OffRampSession) GetExecutionState(sourceChainSelector uint64, sequenceNumber uint64) (uint8, error) { + return _OffRamp.Contract.GetExecutionState(&_OffRamp.CallOpts, sourceChainSelector, sequenceNumber) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetExecutionState(sourceChainSelector uint64, sequenceNumber uint64) (uint8, error) { - return _EVM2EVMMultiOffRamp.Contract.GetExecutionState(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector, sequenceNumber) +func (_OffRamp *OffRampCallerSession) GetExecutionState(sourceChainSelector uint64, sequenceNumber uint64) (uint8, error) { + return _OffRamp.Contract.GetExecutionState(&_OffRamp.CallOpts, sourceChainSelector, sequenceNumber) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetLatestPriceSequenceNumber(opts *bind.CallOpts) (uint64, error) { +func (_OffRamp *OffRampCaller) GetLatestPriceSequenceNumber(opts *bind.CallOpts) (uint64, error) { var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getLatestPriceSequenceNumber") + err := _OffRamp.contract.Call(opts, &out, "getLatestPriceSequenceNumber") if err != nil { return *new(uint64), err @@ -381,17 +381,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetLatestPriceSequenceNum } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetLatestPriceSequenceNumber() (uint64, error) { - return _EVM2EVMMultiOffRamp.Contract.GetLatestPriceSequenceNumber(&_EVM2EVMMultiOffRamp.CallOpts) +func (_OffRamp *OffRampSession) GetLatestPriceSequenceNumber() (uint64, error) { + return _OffRamp.Contract.GetLatestPriceSequenceNumber(&_OffRamp.CallOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetLatestPriceSequenceNumber() (uint64, error) { - return _EVM2EVMMultiOffRamp.Contract.GetLatestPriceSequenceNumber(&_EVM2EVMMultiOffRamp.CallOpts) +func (_OffRamp *OffRampCallerSession) GetLatestPriceSequenceNumber() (uint64, error) { + return _OffRamp.Contract.GetLatestPriceSequenceNumber(&_OffRamp.CallOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetMerkleRoot(opts *bind.CallOpts, sourceChainSelector uint64, root [32]byte) (*big.Int, error) { +func (_OffRamp *OffRampCaller) GetMerkleRoot(opts *bind.CallOpts, sourceChainSelector uint64, root [32]byte) (*big.Int, error) { var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getMerkleRoot", sourceChainSelector, root) + err := _OffRamp.contract.Call(opts, &out, "getMerkleRoot", sourceChainSelector, root) if err != nil { return *new(*big.Int), err @@ -403,61 +403,61 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetMerkleRoot(opts *bind. } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetMerkleRoot(sourceChainSelector uint64, root [32]byte) (*big.Int, error) { - return _EVM2EVMMultiOffRamp.Contract.GetMerkleRoot(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector, root) +func (_OffRamp *OffRampSession) GetMerkleRoot(sourceChainSelector uint64, root [32]byte) (*big.Int, error) { + return _OffRamp.Contract.GetMerkleRoot(&_OffRamp.CallOpts, sourceChainSelector, root) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetMerkleRoot(sourceChainSelector uint64, root [32]byte) (*big.Int, error) { - return _EVM2EVMMultiOffRamp.Contract.GetMerkleRoot(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector, root) +func (_OffRamp *OffRampCallerSession) GetMerkleRoot(sourceChainSelector uint64, root [32]byte) (*big.Int, error) { + return _OffRamp.Contract.GetMerkleRoot(&_OffRamp.CallOpts, sourceChainSelector, root) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) { +func (_OffRamp *OffRampCaller) GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (OffRampSourceChainConfig, error) { var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getSourceChainConfig", sourceChainSelector) + err := _OffRamp.contract.Call(opts, &out, "getSourceChainConfig", sourceChainSelector) if err != nil { - return *new(EVM2EVMMultiOffRampSourceChainConfig), err + return *new(OffRampSourceChainConfig), err } - out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOffRampSourceChainConfig)).(*EVM2EVMMultiOffRampSourceChainConfig) + out0 := *abi.ConvertType(out[0], new(OffRampSourceChainConfig)).(*OffRampSourceChainConfig) return out0, err } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetSourceChainConfig(sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) { - return _EVM2EVMMultiOffRamp.Contract.GetSourceChainConfig(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector) +func (_OffRamp *OffRampSession) GetSourceChainConfig(sourceChainSelector uint64) (OffRampSourceChainConfig, error) { + return _OffRamp.Contract.GetSourceChainConfig(&_OffRamp.CallOpts, sourceChainSelector) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetSourceChainConfig(sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) { - return _EVM2EVMMultiOffRamp.Contract.GetSourceChainConfig(&_EVM2EVMMultiOffRamp.CallOpts, sourceChainSelector) +func (_OffRamp *OffRampCallerSession) GetSourceChainConfig(sourceChainSelector uint64) (OffRampSourceChainConfig, error) { + return _OffRamp.Contract.GetSourceChainConfig(&_OffRamp.CallOpts, sourceChainSelector) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMMultiOffRampStaticConfig, error) { +func (_OffRamp *OffRampCaller) GetStaticConfig(opts *bind.CallOpts) (OffRampStaticConfig, error) { var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "getStaticConfig") + err := _OffRamp.contract.Call(opts, &out, "getStaticConfig") if err != nil { - return *new(EVM2EVMMultiOffRampStaticConfig), err + return *new(OffRampStaticConfig), err } - out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOffRampStaticConfig)).(*EVM2EVMMultiOffRampStaticConfig) + out0 := *abi.ConvertType(out[0], new(OffRampStaticConfig)).(*OffRampStaticConfig) return out0, err } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) GetStaticConfig() (EVM2EVMMultiOffRampStaticConfig, error) { - return _EVM2EVMMultiOffRamp.Contract.GetStaticConfig(&_EVM2EVMMultiOffRamp.CallOpts) +func (_OffRamp *OffRampSession) GetStaticConfig() (OffRampStaticConfig, error) { + return _OffRamp.Contract.GetStaticConfig(&_OffRamp.CallOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) GetStaticConfig() (EVM2EVMMultiOffRampStaticConfig, error) { - return _EVM2EVMMultiOffRamp.Contract.GetStaticConfig(&_EVM2EVMMultiOffRamp.CallOpts) +func (_OffRamp *OffRampCallerSession) GetStaticConfig() (OffRampStaticConfig, error) { + return _OffRamp.Contract.GetStaticConfig(&_OffRamp.CallOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { +func (_OffRamp *OffRampCaller) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "isBlessed", root) + err := _OffRamp.contract.Call(opts, &out, "isBlessed", root) if err != nil { return *new(bool), err @@ -469,17 +469,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) IsBlessed(opts *bind.Call } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) IsBlessed(root [32]byte) (bool, error) { - return _EVM2EVMMultiOffRamp.Contract.IsBlessed(&_EVM2EVMMultiOffRamp.CallOpts, root) +func (_OffRamp *OffRampSession) IsBlessed(root [32]byte) (bool, error) { + return _OffRamp.Contract.IsBlessed(&_OffRamp.CallOpts, root) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) IsBlessed(root [32]byte) (bool, error) { - return _EVM2EVMMultiOffRamp.Contract.IsBlessed(&_EVM2EVMMultiOffRamp.CallOpts, root) +func (_OffRamp *OffRampCallerSession) IsBlessed(root [32]byte) (bool, error) { + return _OffRamp.Contract.IsBlessed(&_OffRamp.CallOpts, root) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) LatestConfigDetails(opts *bind.CallOpts, ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { +func (_OffRamp *OffRampCaller) LatestConfigDetails(opts *bind.CallOpts, ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "latestConfigDetails", ocrPluginType) + err := _OffRamp.contract.Call(opts, &out, "latestConfigDetails", ocrPluginType) if err != nil { return *new(MultiOCR3BaseOCRConfig), err @@ -491,17 +491,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) LatestConfigDetails(opts } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) LatestConfigDetails(ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { - return _EVM2EVMMultiOffRamp.Contract.LatestConfigDetails(&_EVM2EVMMultiOffRamp.CallOpts, ocrPluginType) +func (_OffRamp *OffRampSession) LatestConfigDetails(ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { + return _OffRamp.Contract.LatestConfigDetails(&_OffRamp.CallOpts, ocrPluginType) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) LatestConfigDetails(ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { - return _EVM2EVMMultiOffRamp.Contract.LatestConfigDetails(&_EVM2EVMMultiOffRamp.CallOpts, ocrPluginType) +func (_OffRamp *OffRampCallerSession) LatestConfigDetails(ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { + return _OffRamp.Contract.LatestConfigDetails(&_OffRamp.CallOpts, ocrPluginType) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { +func (_OffRamp *OffRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "owner") + err := _OffRamp.contract.Call(opts, &out, "owner") if err != nil { return *new(common.Address), err @@ -513,17 +513,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) Owner(opts *bind.CallOpts } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) Owner() (common.Address, error) { - return _EVM2EVMMultiOffRamp.Contract.Owner(&_EVM2EVMMultiOffRamp.CallOpts) +func (_OffRamp *OffRampSession) Owner() (common.Address, error) { + return _OffRamp.Contract.Owner(&_OffRamp.CallOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) Owner() (common.Address, error) { - return _EVM2EVMMultiOffRamp.Contract.Owner(&_EVM2EVMMultiOffRamp.CallOpts) +func (_OffRamp *OffRampCallerSession) Owner() (common.Address, error) { + return _OffRamp.Contract.Owner(&_OffRamp.CallOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { +func (_OffRamp *OffRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { var out []interface{} - err := _EVM2EVMMultiOffRamp.contract.Call(opts, &out, "typeAndVersion") + err := _OffRamp.contract.Call(opts, &out, "typeAndVersion") if err != nil { return *new(string), err @@ -535,136 +535,136 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCaller) TypeAndVersion(opts *bind } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) TypeAndVersion() (string, error) { - return _EVM2EVMMultiOffRamp.Contract.TypeAndVersion(&_EVM2EVMMultiOffRamp.CallOpts) +func (_OffRamp *OffRampSession) TypeAndVersion() (string, error) { + return _OffRamp.Contract.TypeAndVersion(&_OffRamp.CallOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampCallerSession) TypeAndVersion() (string, error) { - return _EVM2EVMMultiOffRamp.Contract.TypeAndVersion(&_EVM2EVMMultiOffRamp.CallOpts) +func (_OffRamp *OffRampCallerSession) TypeAndVersion() (string, error) { + return _OffRamp.Contract.TypeAndVersion(&_OffRamp.CallOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "acceptOwnership") +func (_OffRamp *OffRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OffRamp.contract.Transact(opts, "acceptOwnership") } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) AcceptOwnership() (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.AcceptOwnership(&_EVM2EVMMultiOffRamp.TransactOpts) +func (_OffRamp *OffRampSession) AcceptOwnership() (*types.Transaction, error) { + return _OffRamp.Contract.AcceptOwnership(&_OffRamp.TransactOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.AcceptOwnership(&_EVM2EVMMultiOffRamp.TransactOpts) +func (_OffRamp *OffRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _OffRamp.Contract.AcceptOwnership(&_OffRamp.TransactOpts) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) ApplySourceChainConfigUpdates(opts *bind.TransactOpts, sourceChainConfigUpdates []EVM2EVMMultiOffRampSourceChainConfigArgs) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "applySourceChainConfigUpdates", sourceChainConfigUpdates) +func (_OffRamp *OffRampTransactor) ApplySourceChainConfigUpdates(opts *bind.TransactOpts, sourceChainConfigUpdates []OffRampSourceChainConfigArgs) (*types.Transaction, error) { + return _OffRamp.contract.Transact(opts, "applySourceChainConfigUpdates", sourceChainConfigUpdates) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) ApplySourceChainConfigUpdates(sourceChainConfigUpdates []EVM2EVMMultiOffRampSourceChainConfigArgs) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.ApplySourceChainConfigUpdates(&_EVM2EVMMultiOffRamp.TransactOpts, sourceChainConfigUpdates) +func (_OffRamp *OffRampSession) ApplySourceChainConfigUpdates(sourceChainConfigUpdates []OffRampSourceChainConfigArgs) (*types.Transaction, error) { + return _OffRamp.Contract.ApplySourceChainConfigUpdates(&_OffRamp.TransactOpts, sourceChainConfigUpdates) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) ApplySourceChainConfigUpdates(sourceChainConfigUpdates []EVM2EVMMultiOffRampSourceChainConfigArgs) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.ApplySourceChainConfigUpdates(&_EVM2EVMMultiOffRamp.TransactOpts, sourceChainConfigUpdates) +func (_OffRamp *OffRampTransactorSession) ApplySourceChainConfigUpdates(sourceChainConfigUpdates []OffRampSourceChainConfigArgs) (*types.Transaction, error) { + return _OffRamp.Contract.ApplySourceChainConfigUpdates(&_OffRamp.TransactOpts, sourceChainConfigUpdates) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) Commit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "commit", reportContext, report, rs, ss, rawVs) +func (_OffRamp *OffRampTransactor) Commit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _OffRamp.contract.Transact(opts, "commit", reportContext, report, rs, ss, rawVs) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) Commit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.Commit(&_EVM2EVMMultiOffRamp.TransactOpts, reportContext, report, rs, ss, rawVs) +func (_OffRamp *OffRampSession) Commit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _OffRamp.Contract.Commit(&_OffRamp.TransactOpts, reportContext, report, rs, ss, rawVs) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) Commit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.Commit(&_EVM2EVMMultiOffRamp.TransactOpts, reportContext, report, rs, ss, rawVs) +func (_OffRamp *OffRampTransactorSession) Commit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _OffRamp.Contract.Commit(&_OffRamp.TransactOpts, reportContext, report, rs, ss, rawVs) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) Execute(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "execute", reportContext, report) +func (_OffRamp *OffRampTransactor) Execute(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte) (*types.Transaction, error) { + return _OffRamp.contract.Transact(opts, "execute", reportContext, report) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) Execute(reportContext [3][32]byte, report []byte) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.Execute(&_EVM2EVMMultiOffRamp.TransactOpts, reportContext, report) +func (_OffRamp *OffRampSession) Execute(reportContext [3][32]byte, report []byte) (*types.Transaction, error) { + return _OffRamp.Contract.Execute(&_OffRamp.TransactOpts, reportContext, report) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) Execute(reportContext [3][32]byte, report []byte) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.Execute(&_EVM2EVMMultiOffRamp.TransactOpts, reportContext, report) +func (_OffRamp *OffRampTransactorSession) Execute(reportContext [3][32]byte, report []byte) (*types.Transaction, error) { + return _OffRamp.Contract.Execute(&_OffRamp.TransactOpts, reportContext, report) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) ExecuteSingleMessage(opts *bind.TransactOpts, message InternalAny2EVMRampMessage, offchainTokenData [][]byte) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "executeSingleMessage", message, offchainTokenData) +func (_OffRamp *OffRampTransactor) ExecuteSingleMessage(opts *bind.TransactOpts, message InternalAny2EVMRampMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _OffRamp.contract.Transact(opts, "executeSingleMessage", message, offchainTokenData) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) ExecuteSingleMessage(message InternalAny2EVMRampMessage, offchainTokenData [][]byte) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMMultiOffRamp.TransactOpts, message, offchainTokenData) +func (_OffRamp *OffRampSession) ExecuteSingleMessage(message InternalAny2EVMRampMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _OffRamp.Contract.ExecuteSingleMessage(&_OffRamp.TransactOpts, message, offchainTokenData) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) ExecuteSingleMessage(message InternalAny2EVMRampMessage, offchainTokenData [][]byte) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.ExecuteSingleMessage(&_EVM2EVMMultiOffRamp.TransactOpts, message, offchainTokenData) +func (_OffRamp *OffRampTransactorSession) ExecuteSingleMessage(message InternalAny2EVMRampMessage, offchainTokenData [][]byte) (*types.Transaction, error) { + return _OffRamp.Contract.ExecuteSingleMessage(&_OffRamp.TransactOpts, message, offchainTokenData) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) ManuallyExecute(opts *bind.TransactOpts, reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "manuallyExecute", reports, gasLimitOverrides) +func (_OffRamp *OffRampTransactor) ManuallyExecute(opts *bind.TransactOpts, reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) { + return _OffRamp.contract.Transact(opts, "manuallyExecute", reports, gasLimitOverrides) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) ManuallyExecute(reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.ManuallyExecute(&_EVM2EVMMultiOffRamp.TransactOpts, reports, gasLimitOverrides) +func (_OffRamp *OffRampSession) ManuallyExecute(reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) { + return _OffRamp.Contract.ManuallyExecute(&_OffRamp.TransactOpts, reports, gasLimitOverrides) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) ManuallyExecute(reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.ManuallyExecute(&_EVM2EVMMultiOffRamp.TransactOpts, reports, gasLimitOverrides) +func (_OffRamp *OffRampTransactorSession) ManuallyExecute(reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) { + return _OffRamp.Contract.ManuallyExecute(&_OffRamp.TransactOpts, reports, gasLimitOverrides) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset []EVM2EVMMultiOffRampUnblessedRoot) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "resetUnblessedRoots", rootToReset) +func (_OffRamp *OffRampTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset []OffRampUnblessedRoot) (*types.Transaction, error) { + return _OffRamp.contract.Transact(opts, "resetUnblessedRoots", rootToReset) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) ResetUnblessedRoots(rootToReset []EVM2EVMMultiOffRampUnblessedRoot) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.ResetUnblessedRoots(&_EVM2EVMMultiOffRamp.TransactOpts, rootToReset) +func (_OffRamp *OffRampSession) ResetUnblessedRoots(rootToReset []OffRampUnblessedRoot) (*types.Transaction, error) { + return _OffRamp.Contract.ResetUnblessedRoots(&_OffRamp.TransactOpts, rootToReset) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) ResetUnblessedRoots(rootToReset []EVM2EVMMultiOffRampUnblessedRoot) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.ResetUnblessedRoots(&_EVM2EVMMultiOffRamp.TransactOpts, rootToReset) +func (_OffRamp *OffRampTransactorSession) ResetUnblessedRoots(rootToReset []OffRampUnblessedRoot) (*types.Transaction, error) { + return _OffRamp.Contract.ResetUnblessedRoots(&_OffRamp.TransactOpts, rootToReset) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMMultiOffRampDynamicConfig) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "setDynamicConfig", dynamicConfig) +func (_OffRamp *OffRampTransactor) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig OffRampDynamicConfig) (*types.Transaction, error) { + return _OffRamp.contract.Transact(opts, "setDynamicConfig", dynamicConfig) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) SetDynamicConfig(dynamicConfig EVM2EVMMultiOffRampDynamicConfig) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.SetDynamicConfig(&_EVM2EVMMultiOffRamp.TransactOpts, dynamicConfig) +func (_OffRamp *OffRampSession) SetDynamicConfig(dynamicConfig OffRampDynamicConfig) (*types.Transaction, error) { + return _OffRamp.Contract.SetDynamicConfig(&_OffRamp.TransactOpts, dynamicConfig) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) SetDynamicConfig(dynamicConfig EVM2EVMMultiOffRampDynamicConfig) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.SetDynamicConfig(&_EVM2EVMMultiOffRamp.TransactOpts, dynamicConfig) +func (_OffRamp *OffRampTransactorSession) SetDynamicConfig(dynamicConfig OffRampDynamicConfig) (*types.Transaction, error) { + return _OffRamp.Contract.SetDynamicConfig(&_OffRamp.TransactOpts, dynamicConfig) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) SetOCR3Configs(opts *bind.TransactOpts, ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "setOCR3Configs", ocrConfigArgs) +func (_OffRamp *OffRampTransactor) SetOCR3Configs(opts *bind.TransactOpts, ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { + return _OffRamp.contract.Transact(opts, "setOCR3Configs", ocrConfigArgs) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) SetOCR3Configs(ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.SetOCR3Configs(&_EVM2EVMMultiOffRamp.TransactOpts, ocrConfigArgs) +func (_OffRamp *OffRampSession) SetOCR3Configs(ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { + return _OffRamp.Contract.SetOCR3Configs(&_OffRamp.TransactOpts, ocrConfigArgs) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) SetOCR3Configs(ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.SetOCR3Configs(&_EVM2EVMMultiOffRamp.TransactOpts, ocrConfigArgs) +func (_OffRamp *OffRampTransactorSession) SetOCR3Configs(ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) { + return _OffRamp.Contract.SetOCR3Configs(&_OffRamp.TransactOpts, ocrConfigArgs) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.contract.Transact(opts, "transferOwnership", to) +func (_OffRamp *OffRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _OffRamp.contract.Transact(opts, "transferOwnership", to) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.TransferOwnership(&_EVM2EVMMultiOffRamp.TransactOpts, to) +func (_OffRamp *OffRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _OffRamp.Contract.TransferOwnership(&_OffRamp.TransactOpts, to) } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _EVM2EVMMultiOffRamp.Contract.TransferOwnership(&_EVM2EVMMultiOffRamp.TransactOpts, to) +func (_OffRamp *OffRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _OffRamp.Contract.TransferOwnership(&_OffRamp.TransactOpts, to) } -type EVM2EVMMultiOffRampAlreadyAttemptedIterator struct { - Event *EVM2EVMMultiOffRampAlreadyAttempted +type OffRampAlreadyAttemptedIterator struct { + Event *OffRampAlreadyAttempted contract *bind.BoundContract event string @@ -675,7 +675,7 @@ type EVM2EVMMultiOffRampAlreadyAttemptedIterator struct { fail error } -func (it *EVM2EVMMultiOffRampAlreadyAttemptedIterator) Next() bool { +func (it *OffRampAlreadyAttemptedIterator) Next() bool { if it.fail != nil { return false @@ -684,7 +684,7 @@ func (it *EVM2EVMMultiOffRampAlreadyAttemptedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampAlreadyAttempted) + it.Event = new(OffRampAlreadyAttempted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -699,7 +699,7 @@ func (it *EVM2EVMMultiOffRampAlreadyAttemptedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampAlreadyAttempted) + it.Event = new(OffRampAlreadyAttempted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -714,33 +714,33 @@ func (it *EVM2EVMMultiOffRampAlreadyAttemptedIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampAlreadyAttemptedIterator) Error() error { +func (it *OffRampAlreadyAttemptedIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampAlreadyAttemptedIterator) Close() error { +func (it *OffRampAlreadyAttemptedIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampAlreadyAttempted struct { +type OffRampAlreadyAttempted struct { SourceChainSelector uint64 SequenceNumber uint64 Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterAlreadyAttempted(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampAlreadyAttemptedIterator, error) { +func (_OffRamp *OffRampFilterer) FilterAlreadyAttempted(opts *bind.FilterOpts) (*OffRampAlreadyAttemptedIterator, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "AlreadyAttempted") + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "AlreadyAttempted") if err != nil { return nil, err } - return &EVM2EVMMultiOffRampAlreadyAttemptedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "AlreadyAttempted", logs: logs, sub: sub}, nil + return &OffRampAlreadyAttemptedIterator{contract: _OffRamp.contract, event: "AlreadyAttempted", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchAlreadyAttempted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampAlreadyAttempted) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchAlreadyAttempted(opts *bind.WatchOpts, sink chan<- *OffRampAlreadyAttempted) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "AlreadyAttempted") + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "AlreadyAttempted") if err != nil { return nil, err } @@ -750,8 +750,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchAlreadyAttempted(o select { case log := <-logs: - event := new(EVM2EVMMultiOffRampAlreadyAttempted) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "AlreadyAttempted", log); err != nil { + event := new(OffRampAlreadyAttempted) + if err := _OffRamp.contract.UnpackLog(event, "AlreadyAttempted", log); err != nil { return err } event.Raw = log @@ -772,17 +772,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchAlreadyAttempted(o }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseAlreadyAttempted(log types.Log) (*EVM2EVMMultiOffRampAlreadyAttempted, error) { - event := new(EVM2EVMMultiOffRampAlreadyAttempted) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "AlreadyAttempted", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseAlreadyAttempted(log types.Log) (*OffRampAlreadyAttempted, error) { + event := new(OffRampAlreadyAttempted) + if err := _OffRamp.contract.UnpackLog(event, "AlreadyAttempted", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampCommitReportAcceptedIterator struct { - Event *EVM2EVMMultiOffRampCommitReportAccepted +type OffRampCommitReportAcceptedIterator struct { + Event *OffRampCommitReportAccepted contract *bind.BoundContract event string @@ -793,7 +793,7 @@ type EVM2EVMMultiOffRampCommitReportAcceptedIterator struct { fail error } -func (it *EVM2EVMMultiOffRampCommitReportAcceptedIterator) Next() bool { +func (it *OffRampCommitReportAcceptedIterator) Next() bool { if it.fail != nil { return false @@ -802,7 +802,7 @@ func (it *EVM2EVMMultiOffRampCommitReportAcceptedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampCommitReportAccepted) + it.Event = new(OffRampCommitReportAccepted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -817,7 +817,7 @@ func (it *EVM2EVMMultiOffRampCommitReportAcceptedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampCommitReportAccepted) + it.Event = new(OffRampCommitReportAccepted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -832,32 +832,32 @@ func (it *EVM2EVMMultiOffRampCommitReportAcceptedIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampCommitReportAcceptedIterator) Error() error { +func (it *OffRampCommitReportAcceptedIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampCommitReportAcceptedIterator) Close() error { +func (it *OffRampCommitReportAcceptedIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampCommitReportAccepted struct { - Report EVM2EVMMultiOffRampCommitReport +type OffRampCommitReportAccepted struct { + Report OffRampCommitReport Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterCommitReportAccepted(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampCommitReportAcceptedIterator, error) { +func (_OffRamp *OffRampFilterer) FilterCommitReportAccepted(opts *bind.FilterOpts) (*OffRampCommitReportAcceptedIterator, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "CommitReportAccepted") + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "CommitReportAccepted") if err != nil { return nil, err } - return &EVM2EVMMultiOffRampCommitReportAcceptedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "CommitReportAccepted", logs: logs, sub: sub}, nil + return &OffRampCommitReportAcceptedIterator{contract: _OffRamp.contract, event: "CommitReportAccepted", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchCommitReportAccepted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampCommitReportAccepted) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchCommitReportAccepted(opts *bind.WatchOpts, sink chan<- *OffRampCommitReportAccepted) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "CommitReportAccepted") + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "CommitReportAccepted") if err != nil { return nil, err } @@ -867,8 +867,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchCommitReportAccept select { case log := <-logs: - event := new(EVM2EVMMultiOffRampCommitReportAccepted) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "CommitReportAccepted", log); err != nil { + event := new(OffRampCommitReportAccepted) + if err := _OffRamp.contract.UnpackLog(event, "CommitReportAccepted", log); err != nil { return err } event.Raw = log @@ -889,17 +889,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchCommitReportAccept }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseCommitReportAccepted(log types.Log) (*EVM2EVMMultiOffRampCommitReportAccepted, error) { - event := new(EVM2EVMMultiOffRampCommitReportAccepted) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "CommitReportAccepted", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseCommitReportAccepted(log types.Log) (*OffRampCommitReportAccepted, error) { + event := new(OffRampCommitReportAccepted) + if err := _OffRamp.contract.UnpackLog(event, "CommitReportAccepted", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampConfigSetIterator struct { - Event *EVM2EVMMultiOffRampConfigSet +type OffRampConfigSetIterator struct { + Event *OffRampConfigSet contract *bind.BoundContract event string @@ -910,7 +910,7 @@ type EVM2EVMMultiOffRampConfigSetIterator struct { fail error } -func (it *EVM2EVMMultiOffRampConfigSetIterator) Next() bool { +func (it *OffRampConfigSetIterator) Next() bool { if it.fail != nil { return false @@ -919,7 +919,7 @@ func (it *EVM2EVMMultiOffRampConfigSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampConfigSet) + it.Event = new(OffRampConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -934,7 +934,7 @@ func (it *EVM2EVMMultiOffRampConfigSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampConfigSet) + it.Event = new(OffRampConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -949,16 +949,16 @@ func (it *EVM2EVMMultiOffRampConfigSetIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampConfigSetIterator) Error() error { +func (it *OffRampConfigSetIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampConfigSetIterator) Close() error { +func (it *OffRampConfigSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampConfigSet struct { +type OffRampConfigSet struct { OcrPluginType uint8 ConfigDigest [32]byte Signers []common.Address @@ -967,18 +967,18 @@ type EVM2EVMMultiOffRampConfigSet struct { Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampConfigSetIterator, error) { +func (_OffRamp *OffRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*OffRampConfigSetIterator, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "ConfigSet") + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "ConfigSet") if err != nil { return nil, err } - return &EVM2EVMMultiOffRampConfigSetIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil + return &OffRampConfigSetIterator{contract: _OffRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampConfigSet) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *OffRampConfigSet) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "ConfigSet") + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "ConfigSet") if err != nil { return nil, err } @@ -988,8 +988,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchConfigSet(opts *bi select { case log := <-logs: - event := new(EVM2EVMMultiOffRampConfigSet) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + event := new(OffRampConfigSet) + if err := _OffRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { return err } event.Raw = log @@ -1010,17 +1010,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchConfigSet(opts *bi }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseConfigSet(log types.Log) (*EVM2EVMMultiOffRampConfigSet, error) { - event := new(EVM2EVMMultiOffRampConfigSet) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseConfigSet(log types.Log) (*OffRampConfigSet, error) { + event := new(OffRampConfigSet) + if err := _OffRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampDynamicConfigSetIterator struct { - Event *EVM2EVMMultiOffRampDynamicConfigSet +type OffRampDynamicConfigSetIterator struct { + Event *OffRampDynamicConfigSet contract *bind.BoundContract event string @@ -1031,7 +1031,7 @@ type EVM2EVMMultiOffRampDynamicConfigSetIterator struct { fail error } -func (it *EVM2EVMMultiOffRampDynamicConfigSetIterator) Next() bool { +func (it *OffRampDynamicConfigSetIterator) Next() bool { if it.fail != nil { return false @@ -1040,7 +1040,7 @@ func (it *EVM2EVMMultiOffRampDynamicConfigSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampDynamicConfigSet) + it.Event = new(OffRampDynamicConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1055,7 +1055,7 @@ func (it *EVM2EVMMultiOffRampDynamicConfigSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampDynamicConfigSet) + it.Event = new(OffRampDynamicConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1070,32 +1070,32 @@ func (it *EVM2EVMMultiOffRampDynamicConfigSetIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampDynamicConfigSetIterator) Error() error { +func (it *OffRampDynamicConfigSetIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampDynamicConfigSetIterator) Close() error { +func (it *OffRampDynamicConfigSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampDynamicConfigSet struct { - DynamicConfig EVM2EVMMultiOffRampDynamicConfig +type OffRampDynamicConfigSet struct { + DynamicConfig OffRampDynamicConfig Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterDynamicConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampDynamicConfigSetIterator, error) { +func (_OffRamp *OffRampFilterer) FilterDynamicConfigSet(opts *bind.FilterOpts) (*OffRampDynamicConfigSetIterator, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "DynamicConfigSet") + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "DynamicConfigSet") if err != nil { return nil, err } - return &EVM2EVMMultiOffRampDynamicConfigSetIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "DynamicConfigSet", logs: logs, sub: sub}, nil + return &OffRampDynamicConfigSetIterator{contract: _OffRamp.contract, event: "DynamicConfigSet", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchDynamicConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampDynamicConfigSet) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchDynamicConfigSet(opts *bind.WatchOpts, sink chan<- *OffRampDynamicConfigSet) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "DynamicConfigSet") + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "DynamicConfigSet") if err != nil { return nil, err } @@ -1105,8 +1105,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchDynamicConfigSet(o select { case log := <-logs: - event := new(EVM2EVMMultiOffRampDynamicConfigSet) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "DynamicConfigSet", log); err != nil { + event := new(OffRampDynamicConfigSet) + if err := _OffRamp.contract.UnpackLog(event, "DynamicConfigSet", log); err != nil { return err } event.Raw = log @@ -1127,17 +1127,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchDynamicConfigSet(o }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseDynamicConfigSet(log types.Log) (*EVM2EVMMultiOffRampDynamicConfigSet, error) { - event := new(EVM2EVMMultiOffRampDynamicConfigSet) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "DynamicConfigSet", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseDynamicConfigSet(log types.Log) (*OffRampDynamicConfigSet, error) { + event := new(OffRampDynamicConfigSet) + if err := _OffRamp.contract.UnpackLog(event, "DynamicConfigSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampExecutionStateChangedIterator struct { - Event *EVM2EVMMultiOffRampExecutionStateChanged +type OffRampExecutionStateChangedIterator struct { + Event *OffRampExecutionStateChanged contract *bind.BoundContract event string @@ -1148,7 +1148,7 @@ type EVM2EVMMultiOffRampExecutionStateChangedIterator struct { fail error } -func (it *EVM2EVMMultiOffRampExecutionStateChangedIterator) Next() bool { +func (it *OffRampExecutionStateChangedIterator) Next() bool { if it.fail != nil { return false @@ -1157,7 +1157,7 @@ func (it *EVM2EVMMultiOffRampExecutionStateChangedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampExecutionStateChanged) + it.Event = new(OffRampExecutionStateChanged) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1172,7 +1172,7 @@ func (it *EVM2EVMMultiOffRampExecutionStateChangedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampExecutionStateChanged) + it.Event = new(OffRampExecutionStateChanged) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1187,16 +1187,16 @@ func (it *EVM2EVMMultiOffRampExecutionStateChangedIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampExecutionStateChangedIterator) Error() error { +func (it *OffRampExecutionStateChangedIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampExecutionStateChangedIterator) Close() error { +func (it *OffRampExecutionStateChangedIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampExecutionStateChanged struct { +type OffRampExecutionStateChanged struct { SourceChainSelector uint64 SequenceNumber uint64 MessageId [32]byte @@ -1206,7 +1206,7 @@ type EVM2EVMMultiOffRampExecutionStateChanged struct { Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterExecutionStateChanged(opts *bind.FilterOpts, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (*EVM2EVMMultiOffRampExecutionStateChangedIterator, error) { +func (_OffRamp *OffRampFilterer) FilterExecutionStateChanged(opts *bind.FilterOpts, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (*OffRampExecutionStateChangedIterator, error) { var sourceChainSelectorRule []interface{} for _, sourceChainSelectorItem := range sourceChainSelector { @@ -1221,14 +1221,14 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterExecutionStateCha messageIdRule = append(messageIdRule, messageIdItem) } - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "ExecutionStateChanged", sourceChainSelectorRule, sequenceNumberRule, messageIdRule) + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "ExecutionStateChanged", sourceChainSelectorRule, sequenceNumberRule, messageIdRule) if err != nil { return nil, err } - return &EVM2EVMMultiOffRampExecutionStateChangedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "ExecutionStateChanged", logs: logs, sub: sub}, nil + return &OffRampExecutionStateChangedIterator{contract: _OffRamp.contract, event: "ExecutionStateChanged", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampExecutionStateChanged, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *OffRampExecutionStateChanged, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) { var sourceChainSelectorRule []interface{} for _, sourceChainSelectorItem := range sourceChainSelector { @@ -1243,7 +1243,7 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchExecutionStateChan messageIdRule = append(messageIdRule, messageIdItem) } - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "ExecutionStateChanged", sourceChainSelectorRule, sequenceNumberRule, messageIdRule) + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "ExecutionStateChanged", sourceChainSelectorRule, sequenceNumberRule, messageIdRule) if err != nil { return nil, err } @@ -1253,8 +1253,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchExecutionStateChan select { case log := <-logs: - event := new(EVM2EVMMultiOffRampExecutionStateChanged) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { + event := new(OffRampExecutionStateChanged) + if err := _OffRamp.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { return err } event.Raw = log @@ -1275,17 +1275,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchExecutionStateChan }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseExecutionStateChanged(log types.Log) (*EVM2EVMMultiOffRampExecutionStateChanged, error) { - event := new(EVM2EVMMultiOffRampExecutionStateChanged) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseExecutionStateChanged(log types.Log) (*OffRampExecutionStateChanged, error) { + event := new(OffRampExecutionStateChanged) + if err := _OffRamp.contract.UnpackLog(event, "ExecutionStateChanged", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampOwnershipTransferRequestedIterator struct { - Event *EVM2EVMMultiOffRampOwnershipTransferRequested +type OffRampOwnershipTransferRequestedIterator struct { + Event *OffRampOwnershipTransferRequested contract *bind.BoundContract event string @@ -1296,7 +1296,7 @@ type EVM2EVMMultiOffRampOwnershipTransferRequestedIterator struct { fail error } -func (it *EVM2EVMMultiOffRampOwnershipTransferRequestedIterator) Next() bool { +func (it *OffRampOwnershipTransferRequestedIterator) Next() bool { if it.fail != nil { return false @@ -1305,7 +1305,7 @@ func (it *EVM2EVMMultiOffRampOwnershipTransferRequestedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampOwnershipTransferRequested) + it.Event = new(OffRampOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1320,7 +1320,7 @@ func (it *EVM2EVMMultiOffRampOwnershipTransferRequestedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampOwnershipTransferRequested) + it.Event = new(OffRampOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1335,22 +1335,22 @@ func (it *EVM2EVMMultiOffRampOwnershipTransferRequestedIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampOwnershipTransferRequestedIterator) Error() error { +func (it *OffRampOwnershipTransferRequestedIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampOwnershipTransferRequestedIterator) Close() error { +func (it *OffRampOwnershipTransferRequestedIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampOwnershipTransferRequested struct { +type OffRampOwnershipTransferRequested struct { From common.Address To common.Address Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOffRampOwnershipTransferRequestedIterator, error) { +func (_OffRamp *OffRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OffRampOwnershipTransferRequestedIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1361,14 +1361,14 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterOwnershipTransfer toRule = append(toRule, toItem) } - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } - return &EVM2EVMMultiOffRampOwnershipTransferRequestedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil + return &OffRampOwnershipTransferRequestedIterator{contract: _OffRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *OffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1379,7 +1379,7 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchOwnershipTransferR toRule = append(toRule, toItem) } - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } @@ -1389,8 +1389,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchOwnershipTransferR select { case log := <-logs: - event := new(EVM2EVMMultiOffRampOwnershipTransferRequested) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + event := new(OffRampOwnershipTransferRequested) + if err := _OffRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return err } event.Raw = log @@ -1411,17 +1411,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchOwnershipTransferR }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMMultiOffRampOwnershipTransferRequested, error) { - event := new(EVM2EVMMultiOffRampOwnershipTransferRequested) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*OffRampOwnershipTransferRequested, error) { + event := new(OffRampOwnershipTransferRequested) + if err := _OffRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampOwnershipTransferredIterator struct { - Event *EVM2EVMMultiOffRampOwnershipTransferred +type OffRampOwnershipTransferredIterator struct { + Event *OffRampOwnershipTransferred contract *bind.BoundContract event string @@ -1432,7 +1432,7 @@ type EVM2EVMMultiOffRampOwnershipTransferredIterator struct { fail error } -func (it *EVM2EVMMultiOffRampOwnershipTransferredIterator) Next() bool { +func (it *OffRampOwnershipTransferredIterator) Next() bool { if it.fail != nil { return false @@ -1441,7 +1441,7 @@ func (it *EVM2EVMMultiOffRampOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampOwnershipTransferred) + it.Event = new(OffRampOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1456,7 +1456,7 @@ func (it *EVM2EVMMultiOffRampOwnershipTransferredIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampOwnershipTransferred) + it.Event = new(OffRampOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1471,22 +1471,22 @@ func (it *EVM2EVMMultiOffRampOwnershipTransferredIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampOwnershipTransferredIterator) Error() error { +func (it *OffRampOwnershipTransferredIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampOwnershipTransferredIterator) Close() error { +func (it *OffRampOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampOwnershipTransferred struct { +type OffRampOwnershipTransferred struct { From common.Address To common.Address Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOffRampOwnershipTransferredIterator, error) { +func (_OffRamp *OffRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OffRampOwnershipTransferredIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1497,14 +1497,14 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterOwnershipTransfer toRule = append(toRule, toItem) } - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } - return &EVM2EVMMultiOffRampOwnershipTransferredIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &OffRampOwnershipTransferredIterator{contract: _OffRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1515,7 +1515,7 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchOwnershipTransferr toRule = append(toRule, toItem) } - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } @@ -1525,8 +1525,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchOwnershipTransferr select { case log := <-logs: - event := new(EVM2EVMMultiOffRampOwnershipTransferred) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(OffRampOwnershipTransferred) + if err := _OffRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -1547,17 +1547,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchOwnershipTransferr }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseOwnershipTransferred(log types.Log) (*EVM2EVMMultiOffRampOwnershipTransferred, error) { - event := new(EVM2EVMMultiOffRampOwnershipTransferred) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseOwnershipTransferred(log types.Log) (*OffRampOwnershipTransferred, error) { + event := new(OffRampOwnershipTransferred) + if err := _OffRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampRootRemovedIterator struct { - Event *EVM2EVMMultiOffRampRootRemoved +type OffRampRootRemovedIterator struct { + Event *OffRampRootRemoved contract *bind.BoundContract event string @@ -1568,7 +1568,7 @@ type EVM2EVMMultiOffRampRootRemovedIterator struct { fail error } -func (it *EVM2EVMMultiOffRampRootRemovedIterator) Next() bool { +func (it *OffRampRootRemovedIterator) Next() bool { if it.fail != nil { return false @@ -1577,7 +1577,7 @@ func (it *EVM2EVMMultiOffRampRootRemovedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampRootRemoved) + it.Event = new(OffRampRootRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1592,7 +1592,7 @@ func (it *EVM2EVMMultiOffRampRootRemovedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampRootRemoved) + it.Event = new(OffRampRootRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1607,32 +1607,32 @@ func (it *EVM2EVMMultiOffRampRootRemovedIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampRootRemovedIterator) Error() error { +func (it *OffRampRootRemovedIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampRootRemovedIterator) Close() error { +func (it *OffRampRootRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampRootRemoved struct { +type OffRampRootRemoved struct { Root [32]byte Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterRootRemoved(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampRootRemovedIterator, error) { +func (_OffRamp *OffRampFilterer) FilterRootRemoved(opts *bind.FilterOpts) (*OffRampRootRemovedIterator, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "RootRemoved") + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "RootRemoved") if err != nil { return nil, err } - return &EVM2EVMMultiOffRampRootRemovedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "RootRemoved", logs: logs, sub: sub}, nil + return &OffRampRootRemovedIterator{contract: _OffRamp.contract, event: "RootRemoved", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampRootRemoved) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *OffRampRootRemoved) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "RootRemoved") + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "RootRemoved") if err != nil { return nil, err } @@ -1642,8 +1642,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchRootRemoved(opts * select { case log := <-logs: - event := new(EVM2EVMMultiOffRampRootRemoved) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "RootRemoved", log); err != nil { + event := new(OffRampRootRemoved) + if err := _OffRamp.contract.UnpackLog(event, "RootRemoved", log); err != nil { return err } event.Raw = log @@ -1664,17 +1664,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchRootRemoved(opts * }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseRootRemoved(log types.Log) (*EVM2EVMMultiOffRampRootRemoved, error) { - event := new(EVM2EVMMultiOffRampRootRemoved) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "RootRemoved", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseRootRemoved(log types.Log) (*OffRampRootRemoved, error) { + event := new(OffRampRootRemoved) + if err := _OffRamp.contract.UnpackLog(event, "RootRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator struct { - Event *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage +type OffRampSkippedAlreadyExecutedMessageIterator struct { + Event *OffRampSkippedAlreadyExecutedMessage contract *bind.BoundContract event string @@ -1685,7 +1685,7 @@ type EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator struct { fail error } -func (it *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator) Next() bool { +func (it *OffRampSkippedAlreadyExecutedMessageIterator) Next() bool { if it.fail != nil { return false @@ -1694,7 +1694,7 @@ func (it *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator) Next() bool if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) + it.Event = new(OffRampSkippedAlreadyExecutedMessage) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1709,7 +1709,7 @@ func (it *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator) Next() bool select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) + it.Event = new(OffRampSkippedAlreadyExecutedMessage) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1724,33 +1724,33 @@ func (it *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator) Next() bool } } -func (it *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator) Error() error { +func (it *OffRampSkippedAlreadyExecutedMessageIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator) Close() error { +func (it *OffRampSkippedAlreadyExecutedMessageIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage struct { +type OffRampSkippedAlreadyExecutedMessage struct { SourceChainSelector uint64 SequenceNumber uint64 Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterSkippedAlreadyExecutedMessage(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator, error) { +func (_OffRamp *OffRampFilterer) FilterSkippedAlreadyExecutedMessage(opts *bind.FilterOpts) (*OffRampSkippedAlreadyExecutedMessageIterator, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "SkippedAlreadyExecutedMessage") + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "SkippedAlreadyExecutedMessage") if err != nil { return nil, err } - return &EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "SkippedAlreadyExecutedMessage", logs: logs, sub: sub}, nil + return &OffRampSkippedAlreadyExecutedMessageIterator{contract: _OffRamp.contract, event: "SkippedAlreadyExecutedMessage", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchSkippedAlreadyExecutedMessage(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchSkippedAlreadyExecutedMessage(opts *bind.WatchOpts, sink chan<- *OffRampSkippedAlreadyExecutedMessage) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "SkippedAlreadyExecutedMessage") + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "SkippedAlreadyExecutedMessage") if err != nil { return nil, err } @@ -1760,8 +1760,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchSkippedAlreadyExec select { case log := <-logs: - event := new(EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "SkippedAlreadyExecutedMessage", log); err != nil { + event := new(OffRampSkippedAlreadyExecutedMessage) + if err := _OffRamp.contract.UnpackLog(event, "SkippedAlreadyExecutedMessage", log); err != nil { return err } event.Raw = log @@ -1782,17 +1782,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchSkippedAlreadyExec }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseSkippedAlreadyExecutedMessage(log types.Log) (*EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage, error) { - event := new(EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "SkippedAlreadyExecutedMessage", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseSkippedAlreadyExecutedMessage(log types.Log) (*OffRampSkippedAlreadyExecutedMessage, error) { + event := new(OffRampSkippedAlreadyExecutedMessage) + if err := _OffRamp.contract.UnpackLog(event, "SkippedAlreadyExecutedMessage", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampSourceChainConfigSetIterator struct { - Event *EVM2EVMMultiOffRampSourceChainConfigSet +type OffRampSourceChainConfigSetIterator struct { + Event *OffRampSourceChainConfigSet contract *bind.BoundContract event string @@ -1803,7 +1803,7 @@ type EVM2EVMMultiOffRampSourceChainConfigSetIterator struct { fail error } -func (it *EVM2EVMMultiOffRampSourceChainConfigSetIterator) Next() bool { +func (it *OffRampSourceChainConfigSetIterator) Next() bool { if it.fail != nil { return false @@ -1812,7 +1812,7 @@ func (it *EVM2EVMMultiOffRampSourceChainConfigSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampSourceChainConfigSet) + it.Event = new(OffRampSourceChainConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1827,7 +1827,7 @@ func (it *EVM2EVMMultiOffRampSourceChainConfigSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampSourceChainConfigSet) + it.Event = new(OffRampSourceChainConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1842,43 +1842,43 @@ func (it *EVM2EVMMultiOffRampSourceChainConfigSetIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampSourceChainConfigSetIterator) Error() error { +func (it *OffRampSourceChainConfigSetIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampSourceChainConfigSetIterator) Close() error { +func (it *OffRampSourceChainConfigSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampSourceChainConfigSet struct { +type OffRampSourceChainConfigSet struct { SourceChainSelector uint64 - SourceConfig EVM2EVMMultiOffRampSourceChainConfig + SourceConfig OffRampSourceChainConfig Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterSourceChainConfigSet(opts *bind.FilterOpts, sourceChainSelector []uint64) (*EVM2EVMMultiOffRampSourceChainConfigSetIterator, error) { +func (_OffRamp *OffRampFilterer) FilterSourceChainConfigSet(opts *bind.FilterOpts, sourceChainSelector []uint64) (*OffRampSourceChainConfigSetIterator, error) { var sourceChainSelectorRule []interface{} for _, sourceChainSelectorItem := range sourceChainSelector { sourceChainSelectorRule = append(sourceChainSelectorRule, sourceChainSelectorItem) } - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "SourceChainConfigSet", sourceChainSelectorRule) + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "SourceChainConfigSet", sourceChainSelectorRule) if err != nil { return nil, err } - return &EVM2EVMMultiOffRampSourceChainConfigSetIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "SourceChainConfigSet", logs: logs, sub: sub}, nil + return &OffRampSourceChainConfigSetIterator{contract: _OffRamp.contract, event: "SourceChainConfigSet", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchSourceChainConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampSourceChainConfigSet, sourceChainSelector []uint64) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchSourceChainConfigSet(opts *bind.WatchOpts, sink chan<- *OffRampSourceChainConfigSet, sourceChainSelector []uint64) (event.Subscription, error) { var sourceChainSelectorRule []interface{} for _, sourceChainSelectorItem := range sourceChainSelector { sourceChainSelectorRule = append(sourceChainSelectorRule, sourceChainSelectorItem) } - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "SourceChainConfigSet", sourceChainSelectorRule) + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "SourceChainConfigSet", sourceChainSelectorRule) if err != nil { return nil, err } @@ -1888,8 +1888,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchSourceChainConfigS select { case log := <-logs: - event := new(EVM2EVMMultiOffRampSourceChainConfigSet) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "SourceChainConfigSet", log); err != nil { + event := new(OffRampSourceChainConfigSet) + if err := _OffRamp.contract.UnpackLog(event, "SourceChainConfigSet", log); err != nil { return err } event.Raw = log @@ -1910,17 +1910,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchSourceChainConfigS }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseSourceChainConfigSet(log types.Log) (*EVM2EVMMultiOffRampSourceChainConfigSet, error) { - event := new(EVM2EVMMultiOffRampSourceChainConfigSet) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "SourceChainConfigSet", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseSourceChainConfigSet(log types.Log) (*OffRampSourceChainConfigSet, error) { + event := new(OffRampSourceChainConfigSet) + if err := _OffRamp.contract.UnpackLog(event, "SourceChainConfigSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampSourceChainSelectorAddedIterator struct { - Event *EVM2EVMMultiOffRampSourceChainSelectorAdded +type OffRampSourceChainSelectorAddedIterator struct { + Event *OffRampSourceChainSelectorAdded contract *bind.BoundContract event string @@ -1931,7 +1931,7 @@ type EVM2EVMMultiOffRampSourceChainSelectorAddedIterator struct { fail error } -func (it *EVM2EVMMultiOffRampSourceChainSelectorAddedIterator) Next() bool { +func (it *OffRampSourceChainSelectorAddedIterator) Next() bool { if it.fail != nil { return false @@ -1940,7 +1940,7 @@ func (it *EVM2EVMMultiOffRampSourceChainSelectorAddedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampSourceChainSelectorAdded) + it.Event = new(OffRampSourceChainSelectorAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1955,7 +1955,7 @@ func (it *EVM2EVMMultiOffRampSourceChainSelectorAddedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampSourceChainSelectorAdded) + it.Event = new(OffRampSourceChainSelectorAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1970,32 +1970,32 @@ func (it *EVM2EVMMultiOffRampSourceChainSelectorAddedIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampSourceChainSelectorAddedIterator) Error() error { +func (it *OffRampSourceChainSelectorAddedIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampSourceChainSelectorAddedIterator) Close() error { +func (it *OffRampSourceChainSelectorAddedIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampSourceChainSelectorAdded struct { +type OffRampSourceChainSelectorAdded struct { SourceChainSelector uint64 Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterSourceChainSelectorAdded(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampSourceChainSelectorAddedIterator, error) { +func (_OffRamp *OffRampFilterer) FilterSourceChainSelectorAdded(opts *bind.FilterOpts) (*OffRampSourceChainSelectorAddedIterator, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "SourceChainSelectorAdded") + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "SourceChainSelectorAdded") if err != nil { return nil, err } - return &EVM2EVMMultiOffRampSourceChainSelectorAddedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "SourceChainSelectorAdded", logs: logs, sub: sub}, nil + return &OffRampSourceChainSelectorAddedIterator{contract: _OffRamp.contract, event: "SourceChainSelectorAdded", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchSourceChainSelectorAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampSourceChainSelectorAdded) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchSourceChainSelectorAdded(opts *bind.WatchOpts, sink chan<- *OffRampSourceChainSelectorAdded) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "SourceChainSelectorAdded") + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "SourceChainSelectorAdded") if err != nil { return nil, err } @@ -2005,8 +2005,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchSourceChainSelecto select { case log := <-logs: - event := new(EVM2EVMMultiOffRampSourceChainSelectorAdded) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "SourceChainSelectorAdded", log); err != nil { + event := new(OffRampSourceChainSelectorAdded) + if err := _OffRamp.contract.UnpackLog(event, "SourceChainSelectorAdded", log); err != nil { return err } event.Raw = log @@ -2027,17 +2027,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchSourceChainSelecto }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseSourceChainSelectorAdded(log types.Log) (*EVM2EVMMultiOffRampSourceChainSelectorAdded, error) { - event := new(EVM2EVMMultiOffRampSourceChainSelectorAdded) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "SourceChainSelectorAdded", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseSourceChainSelectorAdded(log types.Log) (*OffRampSourceChainSelectorAdded, error) { + event := new(OffRampSourceChainSelectorAdded) + if err := _OffRamp.contract.UnpackLog(event, "SourceChainSelectorAdded", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampStaticConfigSetIterator struct { - Event *EVM2EVMMultiOffRampStaticConfigSet +type OffRampStaticConfigSetIterator struct { + Event *OffRampStaticConfigSet contract *bind.BoundContract event string @@ -2048,7 +2048,7 @@ type EVM2EVMMultiOffRampStaticConfigSetIterator struct { fail error } -func (it *EVM2EVMMultiOffRampStaticConfigSetIterator) Next() bool { +func (it *OffRampStaticConfigSetIterator) Next() bool { if it.fail != nil { return false @@ -2057,7 +2057,7 @@ func (it *EVM2EVMMultiOffRampStaticConfigSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampStaticConfigSet) + it.Event = new(OffRampStaticConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2072,7 +2072,7 @@ func (it *EVM2EVMMultiOffRampStaticConfigSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampStaticConfigSet) + it.Event = new(OffRampStaticConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2087,32 +2087,32 @@ func (it *EVM2EVMMultiOffRampStaticConfigSetIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampStaticConfigSetIterator) Error() error { +func (it *OffRampStaticConfigSetIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampStaticConfigSetIterator) Close() error { +func (it *OffRampStaticConfigSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampStaticConfigSet struct { - StaticConfig EVM2EVMMultiOffRampStaticConfig +type OffRampStaticConfigSet struct { + StaticConfig OffRampStaticConfig Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterStaticConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampStaticConfigSetIterator, error) { +func (_OffRamp *OffRampFilterer) FilterStaticConfigSet(opts *bind.FilterOpts) (*OffRampStaticConfigSetIterator, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "StaticConfigSet") + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "StaticConfigSet") if err != nil { return nil, err } - return &EVM2EVMMultiOffRampStaticConfigSetIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "StaticConfigSet", logs: logs, sub: sub}, nil + return &OffRampStaticConfigSetIterator{contract: _OffRamp.contract, event: "StaticConfigSet", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchStaticConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampStaticConfigSet) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchStaticConfigSet(opts *bind.WatchOpts, sink chan<- *OffRampStaticConfigSet) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "StaticConfigSet") + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "StaticConfigSet") if err != nil { return nil, err } @@ -2122,8 +2122,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchStaticConfigSet(op select { case log := <-logs: - event := new(EVM2EVMMultiOffRampStaticConfigSet) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "StaticConfigSet", log); err != nil { + event := new(OffRampStaticConfigSet) + if err := _OffRamp.contract.UnpackLog(event, "StaticConfigSet", log); err != nil { return err } event.Raw = log @@ -2144,17 +2144,17 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchStaticConfigSet(op }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseStaticConfigSet(log types.Log) (*EVM2EVMMultiOffRampStaticConfigSet, error) { - event := new(EVM2EVMMultiOffRampStaticConfigSet) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "StaticConfigSet", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseStaticConfigSet(log types.Log) (*OffRampStaticConfigSet, error) { + event := new(OffRampStaticConfigSet) + if err := _OffRamp.contract.UnpackLog(event, "StaticConfigSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOffRampTransmittedIterator struct { - Event *EVM2EVMMultiOffRampTransmitted +type OffRampTransmittedIterator struct { + Event *OffRampTransmitted contract *bind.BoundContract event string @@ -2165,7 +2165,7 @@ type EVM2EVMMultiOffRampTransmittedIterator struct { fail error } -func (it *EVM2EVMMultiOffRampTransmittedIterator) Next() bool { +func (it *OffRampTransmittedIterator) Next() bool { if it.fail != nil { return false @@ -2174,7 +2174,7 @@ func (it *EVM2EVMMultiOffRampTransmittedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampTransmitted) + it.Event = new(OffRampTransmitted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2189,7 +2189,7 @@ func (it *EVM2EVMMultiOffRampTransmittedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOffRampTransmitted) + it.Event = new(OffRampTransmitted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2204,44 +2204,44 @@ func (it *EVM2EVMMultiOffRampTransmittedIterator) Next() bool { } } -func (it *EVM2EVMMultiOffRampTransmittedIterator) Error() error { +func (it *OffRampTransmittedIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOffRampTransmittedIterator) Close() error { +func (it *OffRampTransmittedIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOffRampTransmitted struct { +type OffRampTransmitted struct { OcrPluginType uint8 ConfigDigest [32]byte SequenceNumber uint64 Raw types.Log } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) FilterTransmitted(opts *bind.FilterOpts, ocrPluginType []uint8) (*EVM2EVMMultiOffRampTransmittedIterator, error) { +func (_OffRamp *OffRampFilterer) FilterTransmitted(opts *bind.FilterOpts, ocrPluginType []uint8) (*OffRampTransmittedIterator, error) { var ocrPluginTypeRule []interface{} for _, ocrPluginTypeItem := range ocrPluginType { ocrPluginTypeRule = append(ocrPluginTypeRule, ocrPluginTypeItem) } - logs, sub, err := _EVM2EVMMultiOffRamp.contract.FilterLogs(opts, "Transmitted", ocrPluginTypeRule) + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "Transmitted", ocrPluginTypeRule) if err != nil { return nil, err } - return &EVM2EVMMultiOffRampTransmittedIterator{contract: _EVM2EVMMultiOffRamp.contract, event: "Transmitted", logs: logs, sub: sub}, nil + return &OffRampTransmittedIterator{contract: _OffRamp.contract, event: "Transmitted", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampTransmitted, ocrPluginType []uint8) (event.Subscription, error) { +func (_OffRamp *OffRampFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *OffRampTransmitted, ocrPluginType []uint8) (event.Subscription, error) { var ocrPluginTypeRule []interface{} for _, ocrPluginTypeItem := range ocrPluginType { ocrPluginTypeRule = append(ocrPluginTypeRule, ocrPluginTypeItem) } - logs, sub, err := _EVM2EVMMultiOffRamp.contract.WatchLogs(opts, "Transmitted", ocrPluginTypeRule) + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "Transmitted", ocrPluginTypeRule) if err != nil { return nil, err } @@ -2251,8 +2251,8 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchTransmitted(opts * select { case log := <-logs: - event := new(EVM2EVMMultiOffRampTransmitted) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { + event := new(OffRampTransmitted) + if err := _OffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { return err } event.Raw = log @@ -2273,109 +2273,109 @@ func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) WatchTransmitted(opts * }), nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRampFilterer) ParseTransmitted(log types.Log) (*EVM2EVMMultiOffRampTransmitted, error) { - event := new(EVM2EVMMultiOffRampTransmitted) - if err := _EVM2EVMMultiOffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { +func (_OffRamp *OffRampFilterer) ParseTransmitted(log types.Log) (*OffRampTransmitted, error) { + event := new(OffRampTransmitted) + if err := _OffRamp.contract.UnpackLog(event, "Transmitted", log); err != nil { return nil, err } event.Raw = log return event, nil } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { +func (_OffRamp *OffRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _EVM2EVMMultiOffRamp.abi.Events["AlreadyAttempted"].ID: - return _EVM2EVMMultiOffRamp.ParseAlreadyAttempted(log) - case _EVM2EVMMultiOffRamp.abi.Events["CommitReportAccepted"].ID: - return _EVM2EVMMultiOffRamp.ParseCommitReportAccepted(log) - case _EVM2EVMMultiOffRamp.abi.Events["ConfigSet"].ID: - return _EVM2EVMMultiOffRamp.ParseConfigSet(log) - case _EVM2EVMMultiOffRamp.abi.Events["DynamicConfigSet"].ID: - return _EVM2EVMMultiOffRamp.ParseDynamicConfigSet(log) - case _EVM2EVMMultiOffRamp.abi.Events["ExecutionStateChanged"].ID: - return _EVM2EVMMultiOffRamp.ParseExecutionStateChanged(log) - case _EVM2EVMMultiOffRamp.abi.Events["OwnershipTransferRequested"].ID: - return _EVM2EVMMultiOffRamp.ParseOwnershipTransferRequested(log) - case _EVM2EVMMultiOffRamp.abi.Events["OwnershipTransferred"].ID: - return _EVM2EVMMultiOffRamp.ParseOwnershipTransferred(log) - case _EVM2EVMMultiOffRamp.abi.Events["RootRemoved"].ID: - return _EVM2EVMMultiOffRamp.ParseRootRemoved(log) - case _EVM2EVMMultiOffRamp.abi.Events["SkippedAlreadyExecutedMessage"].ID: - return _EVM2EVMMultiOffRamp.ParseSkippedAlreadyExecutedMessage(log) - case _EVM2EVMMultiOffRamp.abi.Events["SourceChainConfigSet"].ID: - return _EVM2EVMMultiOffRamp.ParseSourceChainConfigSet(log) - case _EVM2EVMMultiOffRamp.abi.Events["SourceChainSelectorAdded"].ID: - return _EVM2EVMMultiOffRamp.ParseSourceChainSelectorAdded(log) - case _EVM2EVMMultiOffRamp.abi.Events["StaticConfigSet"].ID: - return _EVM2EVMMultiOffRamp.ParseStaticConfigSet(log) - case _EVM2EVMMultiOffRamp.abi.Events["Transmitted"].ID: - return _EVM2EVMMultiOffRamp.ParseTransmitted(log) + case _OffRamp.abi.Events["AlreadyAttempted"].ID: + return _OffRamp.ParseAlreadyAttempted(log) + case _OffRamp.abi.Events["CommitReportAccepted"].ID: + return _OffRamp.ParseCommitReportAccepted(log) + case _OffRamp.abi.Events["ConfigSet"].ID: + return _OffRamp.ParseConfigSet(log) + case _OffRamp.abi.Events["DynamicConfigSet"].ID: + return _OffRamp.ParseDynamicConfigSet(log) + case _OffRamp.abi.Events["ExecutionStateChanged"].ID: + return _OffRamp.ParseExecutionStateChanged(log) + case _OffRamp.abi.Events["OwnershipTransferRequested"].ID: + return _OffRamp.ParseOwnershipTransferRequested(log) + case _OffRamp.abi.Events["OwnershipTransferred"].ID: + return _OffRamp.ParseOwnershipTransferred(log) + case _OffRamp.abi.Events["RootRemoved"].ID: + return _OffRamp.ParseRootRemoved(log) + case _OffRamp.abi.Events["SkippedAlreadyExecutedMessage"].ID: + return _OffRamp.ParseSkippedAlreadyExecutedMessage(log) + case _OffRamp.abi.Events["SourceChainConfigSet"].ID: + return _OffRamp.ParseSourceChainConfigSet(log) + case _OffRamp.abi.Events["SourceChainSelectorAdded"].ID: + return _OffRamp.ParseSourceChainSelectorAdded(log) + case _OffRamp.abi.Events["StaticConfigSet"].ID: + return _OffRamp.ParseStaticConfigSet(log) + case _OffRamp.abi.Events["Transmitted"].ID: + return _OffRamp.ParseTransmitted(log) default: return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) } } -func (EVM2EVMMultiOffRampAlreadyAttempted) Topic() common.Hash { +func (OffRampAlreadyAttempted) Topic() common.Hash { return common.HexToHash("0x3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe65120") } -func (EVM2EVMMultiOffRampCommitReportAccepted) Topic() common.Hash { +func (OffRampCommitReportAccepted) Topic() common.Hash { return common.HexToHash("0x3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d") } -func (EVM2EVMMultiOffRampConfigSet) Topic() common.Hash { +func (OffRampConfigSet) Topic() common.Hash { return common.HexToHash("0xab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547") } -func (EVM2EVMMultiOffRampDynamicConfigSet) Topic() common.Hash { +func (OffRampDynamicConfigSet) Topic() common.Hash { return common.HexToHash("0xa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d") } -func (EVM2EVMMultiOffRampExecutionStateChanged) Topic() common.Hash { +func (OffRampExecutionStateChanged) Topic() common.Hash { return common.HexToHash("0xdc8ccbc35e0eebd81239bcd1971fcd53c7eb34034880142a0f43c809a458732f") } -func (EVM2EVMMultiOffRampOwnershipTransferRequested) Topic() common.Hash { +func (OffRampOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } -func (EVM2EVMMultiOffRampOwnershipTransferred) Topic() common.Hash { +func (OffRampOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (EVM2EVMMultiOffRampRootRemoved) Topic() common.Hash { +func (OffRampRootRemoved) Topic() common.Hash { return common.HexToHash("0x202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12") } -func (EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) Topic() common.Hash { +func (OffRampSkippedAlreadyExecutedMessage) Topic() common.Hash { return common.HexToHash("0x3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c") } -func (EVM2EVMMultiOffRampSourceChainConfigSet) Topic() common.Hash { +func (OffRampSourceChainConfigSet) Topic() common.Hash { return common.HexToHash("0x49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b") } -func (EVM2EVMMultiOffRampSourceChainSelectorAdded) Topic() common.Hash { +func (OffRampSourceChainSelectorAdded) Topic() common.Hash { return common.HexToHash("0xf4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb9") } -func (EVM2EVMMultiOffRampStaticConfigSet) Topic() common.Hash { +func (OffRampStaticConfigSet) Topic() common.Hash { return common.HexToHash("0x683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d8") } -func (EVM2EVMMultiOffRampTransmitted) Topic() common.Hash { +func (OffRampTransmitted) Topic() common.Hash { return common.HexToHash("0x198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0") } -func (_EVM2EVMMultiOffRamp *EVM2EVMMultiOffRamp) Address() common.Address { - return _EVM2EVMMultiOffRamp.address +func (_OffRamp *OffRamp) Address() common.Address { + return _OffRamp.address } -type EVM2EVMMultiOffRampInterface interface { +type OffRampInterface interface { CcipReceive(opts *bind.CallOpts, arg0 ClientAny2EVMMessage) error - GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMMultiOffRampDynamicConfig, error) + GetDynamicConfig(opts *bind.CallOpts) (OffRampDynamicConfig, error) GetExecutionState(opts *bind.CallOpts, sourceChainSelector uint64, sequenceNumber uint64) (uint8, error) @@ -2383,9 +2383,9 @@ type EVM2EVMMultiOffRampInterface interface { GetMerkleRoot(opts *bind.CallOpts, sourceChainSelector uint64, root [32]byte) (*big.Int, error) - GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (EVM2EVMMultiOffRampSourceChainConfig, error) + GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (OffRampSourceChainConfig, error) - GetStaticConfig(opts *bind.CallOpts) (EVM2EVMMultiOffRampStaticConfig, error) + GetStaticConfig(opts *bind.CallOpts) (OffRampStaticConfig, error) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) @@ -2397,7 +2397,7 @@ type EVM2EVMMultiOffRampInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - ApplySourceChainConfigUpdates(opts *bind.TransactOpts, sourceChainConfigUpdates []EVM2EVMMultiOffRampSourceChainConfigArgs) (*types.Transaction, error) + ApplySourceChainConfigUpdates(opts *bind.TransactOpts, sourceChainConfigUpdates []OffRampSourceChainConfigArgs) (*types.Transaction, error) Commit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) @@ -2407,91 +2407,91 @@ type EVM2EVMMultiOffRampInterface interface { ManuallyExecute(opts *bind.TransactOpts, reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) - ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset []EVM2EVMMultiOffRampUnblessedRoot) (*types.Transaction, error) + ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset []OffRampUnblessedRoot) (*types.Transaction, error) - SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMMultiOffRampDynamicConfig) (*types.Transaction, error) + SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig OffRampDynamicConfig) (*types.Transaction, error) SetOCR3Configs(opts *bind.TransactOpts, ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - FilterAlreadyAttempted(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampAlreadyAttemptedIterator, error) + FilterAlreadyAttempted(opts *bind.FilterOpts) (*OffRampAlreadyAttemptedIterator, error) - WatchAlreadyAttempted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampAlreadyAttempted) (event.Subscription, error) + WatchAlreadyAttempted(opts *bind.WatchOpts, sink chan<- *OffRampAlreadyAttempted) (event.Subscription, error) - ParseAlreadyAttempted(log types.Log) (*EVM2EVMMultiOffRampAlreadyAttempted, error) + ParseAlreadyAttempted(log types.Log) (*OffRampAlreadyAttempted, error) - FilterCommitReportAccepted(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampCommitReportAcceptedIterator, error) + FilterCommitReportAccepted(opts *bind.FilterOpts) (*OffRampCommitReportAcceptedIterator, error) - WatchCommitReportAccepted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampCommitReportAccepted) (event.Subscription, error) + WatchCommitReportAccepted(opts *bind.WatchOpts, sink chan<- *OffRampCommitReportAccepted) (event.Subscription, error) - ParseCommitReportAccepted(log types.Log) (*EVM2EVMMultiOffRampCommitReportAccepted, error) + ParseCommitReportAccepted(log types.Log) (*OffRampCommitReportAccepted, error) - FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampConfigSetIterator, error) + FilterConfigSet(opts *bind.FilterOpts) (*OffRampConfigSetIterator, error) - WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampConfigSet) (event.Subscription, error) + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *OffRampConfigSet) (event.Subscription, error) - ParseConfigSet(log types.Log) (*EVM2EVMMultiOffRampConfigSet, error) + ParseConfigSet(log types.Log) (*OffRampConfigSet, error) - FilterDynamicConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampDynamicConfigSetIterator, error) + FilterDynamicConfigSet(opts *bind.FilterOpts) (*OffRampDynamicConfigSetIterator, error) - WatchDynamicConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampDynamicConfigSet) (event.Subscription, error) + WatchDynamicConfigSet(opts *bind.WatchOpts, sink chan<- *OffRampDynamicConfigSet) (event.Subscription, error) - ParseDynamicConfigSet(log types.Log) (*EVM2EVMMultiOffRampDynamicConfigSet, error) + ParseDynamicConfigSet(log types.Log) (*OffRampDynamicConfigSet, error) - FilterExecutionStateChanged(opts *bind.FilterOpts, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (*EVM2EVMMultiOffRampExecutionStateChangedIterator, error) + FilterExecutionStateChanged(opts *bind.FilterOpts, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (*OffRampExecutionStateChangedIterator, error) - WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampExecutionStateChanged, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) + WatchExecutionStateChanged(opts *bind.WatchOpts, sink chan<- *OffRampExecutionStateChanged, sourceChainSelector []uint64, sequenceNumber []uint64, messageId [][32]byte) (event.Subscription, error) - ParseExecutionStateChanged(log types.Log) (*EVM2EVMMultiOffRampExecutionStateChanged, error) + ParseExecutionStateChanged(log types.Log) (*OffRampExecutionStateChanged, error) - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOffRampOwnershipTransferRequestedIterator, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OffRampOwnershipTransferRequestedIterator, error) - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *OffRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMMultiOffRampOwnershipTransferRequested, error) + ParseOwnershipTransferRequested(log types.Log) (*OffRampOwnershipTransferRequested, error) - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOffRampOwnershipTransferredIterator, error) + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OffRampOwnershipTransferredIterator, error) - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OffRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - ParseOwnershipTransferred(log types.Log) (*EVM2EVMMultiOffRampOwnershipTransferred, error) + ParseOwnershipTransferred(log types.Log) (*OffRampOwnershipTransferred, error) - FilterRootRemoved(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampRootRemovedIterator, error) + FilterRootRemoved(opts *bind.FilterOpts) (*OffRampRootRemovedIterator, error) - WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampRootRemoved) (event.Subscription, error) + WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *OffRampRootRemoved) (event.Subscription, error) - ParseRootRemoved(log types.Log) (*EVM2EVMMultiOffRampRootRemoved, error) + ParseRootRemoved(log types.Log) (*OffRampRootRemoved, error) - FilterSkippedAlreadyExecutedMessage(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampSkippedAlreadyExecutedMessageIterator, error) + FilterSkippedAlreadyExecutedMessage(opts *bind.FilterOpts) (*OffRampSkippedAlreadyExecutedMessageIterator, error) - WatchSkippedAlreadyExecutedMessage(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage) (event.Subscription, error) + WatchSkippedAlreadyExecutedMessage(opts *bind.WatchOpts, sink chan<- *OffRampSkippedAlreadyExecutedMessage) (event.Subscription, error) - ParseSkippedAlreadyExecutedMessage(log types.Log) (*EVM2EVMMultiOffRampSkippedAlreadyExecutedMessage, error) + ParseSkippedAlreadyExecutedMessage(log types.Log) (*OffRampSkippedAlreadyExecutedMessage, error) - FilterSourceChainConfigSet(opts *bind.FilterOpts, sourceChainSelector []uint64) (*EVM2EVMMultiOffRampSourceChainConfigSetIterator, error) + FilterSourceChainConfigSet(opts *bind.FilterOpts, sourceChainSelector []uint64) (*OffRampSourceChainConfigSetIterator, error) - WatchSourceChainConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampSourceChainConfigSet, sourceChainSelector []uint64) (event.Subscription, error) + WatchSourceChainConfigSet(opts *bind.WatchOpts, sink chan<- *OffRampSourceChainConfigSet, sourceChainSelector []uint64) (event.Subscription, error) - ParseSourceChainConfigSet(log types.Log) (*EVM2EVMMultiOffRampSourceChainConfigSet, error) + ParseSourceChainConfigSet(log types.Log) (*OffRampSourceChainConfigSet, error) - FilterSourceChainSelectorAdded(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampSourceChainSelectorAddedIterator, error) + FilterSourceChainSelectorAdded(opts *bind.FilterOpts) (*OffRampSourceChainSelectorAddedIterator, error) - WatchSourceChainSelectorAdded(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampSourceChainSelectorAdded) (event.Subscription, error) + WatchSourceChainSelectorAdded(opts *bind.WatchOpts, sink chan<- *OffRampSourceChainSelectorAdded) (event.Subscription, error) - ParseSourceChainSelectorAdded(log types.Log) (*EVM2EVMMultiOffRampSourceChainSelectorAdded, error) + ParseSourceChainSelectorAdded(log types.Log) (*OffRampSourceChainSelectorAdded, error) - FilterStaticConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOffRampStaticConfigSetIterator, error) + FilterStaticConfigSet(opts *bind.FilterOpts) (*OffRampStaticConfigSetIterator, error) - WatchStaticConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampStaticConfigSet) (event.Subscription, error) + WatchStaticConfigSet(opts *bind.WatchOpts, sink chan<- *OffRampStaticConfigSet) (event.Subscription, error) - ParseStaticConfigSet(log types.Log) (*EVM2EVMMultiOffRampStaticConfigSet, error) + ParseStaticConfigSet(log types.Log) (*OffRampStaticConfigSet, error) - FilterTransmitted(opts *bind.FilterOpts, ocrPluginType []uint8) (*EVM2EVMMultiOffRampTransmittedIterator, error) + FilterTransmitted(opts *bind.FilterOpts, ocrPluginType []uint8) (*OffRampTransmittedIterator, error) - WatchTransmitted(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOffRampTransmitted, ocrPluginType []uint8) (event.Subscription, error) + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *OffRampTransmitted, ocrPluginType []uint8) (event.Subscription, error) - ParseTransmitted(log types.Log) (*EVM2EVMMultiOffRampTransmitted, error) + ParseTransmitted(log types.Log) (*OffRampTransmitted, error) ParseLog(log types.Log) (generated.AbigenLog, error) diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go b/core/gethwrappers/ccip/generated/onramp/onramp.go similarity index 52% rename from core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go rename to core/gethwrappers/ccip/generated/onramp/onramp.go index b3cbed0be5..5a77d6854f 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp/evm_2_evm_multi_onramp.go +++ b/core/gethwrappers/ccip/generated/onramp/onramp.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package evm_2_evm_multi_onramp +package onramp import ( "errors" @@ -43,29 +43,6 @@ type ClientEVMTokenAmount struct { Amount *big.Int } -type EVM2EVMMultiOnRampDestChainConfig struct { - SequenceNumber uint64 - Router common.Address -} - -type EVM2EVMMultiOnRampDestChainConfigArgs struct { - DestChainSelector uint64 - Router common.Address -} - -type EVM2EVMMultiOnRampDynamicConfig struct { - PriceRegistry common.Address - MessageValidator common.Address - FeeAggregator common.Address -} - -type EVM2EVMMultiOnRampStaticConfig struct { - ChainSelector uint64 - RmnProxy common.Address - NonceManager common.Address - TokenAdminRegistry common.Address -} - type InternalEVM2AnyRampMessage struct { Header InternalRampMessageHeader Sender common.Address @@ -92,17 +69,40 @@ type InternalRampTokenAmount struct { Amount *big.Int } -var EVM2EVMMultiOnRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMMultiOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b50604051620036af380380620036af83398101604081905262000035916200069c565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000186565b505083516001600160401b031615905080620000e6575060208301516001600160a01b0316155b80620000fd575060408301516001600160a01b0316155b8062000114575060608301516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b82516001600160401b031660805260208301516001600160a01b0390811660a0526040840151811660c05260608401511660e052620001728262000231565b6200017d816200036d565b5050506200079c565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316158062000254575060408101516001600160a01b0316155b1562000273576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b03938416179091556020808401805160038054851691861691909117905560408086018051600480549096169087161790945580516080808201835280516001600160401b031680835260a08051891684880190815260c080518b1686880190815260e080518d166060988901908152895196875293518d169a86019a909a52518b169684019690965251891693820193909352885188169181019190915292518616908301529251909316918301919091527f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558910160405180910390a150565b60005b8151811015620004aa57600082828151811062000391576200039162000786565b602002602001015190506000838381518110620003b257620003b262000786565b6020026020010151600001519050806001600160401b0316600003620003f75760405163c35aa79d60e01b81526001600160401b038216600482015260240162000083565b6040805180820182526001600160401b03838116600081815260056020818152868320805480871688528a8301516001600160a01b03908116848a019081529587905293835287518551851668010000000000000000026001600160e01b0319909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a250505080600101905062000370565b5050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620004e957620004e9620004ae565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200051a576200051a620004ae565b604052919050565b80516001600160401b03811681146200053a57600080fd5b919050565b6001600160a01b03811681146200055557600080fd5b50565b6000606082840312156200056b57600080fd5b604051606081016001600160401b0381118282101715620005905762000590620004ae565b80604052508091508251620005a5816200053f565b81526020830151620005b7816200053f565b60208201526040830151620005cc816200053f565b6040919091015292915050565b600082601f830112620005eb57600080fd5b815160206001600160401b03821115620006095762000609620004ae565b62000619818360051b01620004ef565b82815260069290921b840181019181810190868411156200063957600080fd5b8286015b84811015620006915760408189031215620006585760008081fd5b62000662620004c4565b6200066d8262000522565b8152848201516200067e816200053f565b818601528352918301916040016200063d565b509695505050505050565b6000806000838503610100811215620006b457600080fd5b6080811215620006c357600080fd5b50604051608081016001600160401b038082118383101715620006ea57620006ea620004ae565b81604052620006f98762000522565b8352602087015191506200070d826200053f565b8160208401526040870151915062000725826200053f565b816040840152606087015191506200073d826200053f565b81606084015282955062000755886080890162000558565b945060e08701519250808311156200076c57600080fd5b50506200077c86828701620005d9565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e051612e9a62000815600039600081816101eb015281816108a201526115da0152600081816101af01528181610dc601526115b3015260008181610173015281816104c4015261158901526000818161014301528181610cec0152818161117c015261155c0152612e9a6000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637437ff9f11610097578063d77d5ed011610066578063d77d5ed0146103ba578063df0aa9e914610406578063f2fde38b14610419578063fbca3b741461042c57600080fd5b80637437ff9f146102fb57806379ba5097146103685780638da5cb5b146103705780639041be3d1461038e57600080fd5b806320487ded116100d357806320487ded1461028757806334d560e4146102a85780633a019940146102bb57806348a98aa4146102c357600080fd5b80630242cf60146100fa57806306285c691461010f578063181f5a771461023e575b600080fd5b61010d610108366004611fe6565b61044c565b005b61022860408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161023591906120a9565b60405180910390f35b61027a6040518060400160405280601c81526020017f45564d3245564d4d756c74694f6e52616d7020312e362e302d6465760000000081525081565b604051610235919061216e565b61029a610295366004612199565b610460565b604051908152602001610235565b61010d6102b63660046121f9565b610619565b61010d61062a565b6102d66102d136600461226b565b61085a565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610235565b61035b6040805160608101825260008082526020820181905291810191909152506040805160608101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454169181019190915290565b60405161023591906122a4565b61010d61090f565b60005473ffffffffffffffffffffffffffffffffffffffff166102d6565b6103a161039c3660046122e1565b610a0c565b60405167ffffffffffffffff9091168152602001610235565b6102d66103c83660046122e1565b67ffffffffffffffff1660009081526005602052604090205468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b61029a6104143660046122fe565b610a35565b61010d61042736600461236a565b611230565b61043f61043a3660046122e1565b611241565b6040516102359190612387565b610454611275565b61045d816112f8565b50565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561050b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052f91906123f1565b15610577576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6002546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd906105cf9086908690600401612520565b602060405180830381865afa1580156105ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106109190612669565b90505b92915050565b610621611275565b61045d81611470565b600254604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610699573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106df9190810190612682565b60045490915073ffffffffffffffffffffffffffffffffffffffff1660005b825181101561085557600083828151811061071b5761071b612711565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610796573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ba9190612669565b9050801561084b576107e373ffffffffffffffffffffffffffffffffffffffff8316858361163a565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e8360405161084291815260200190565b60405180910390a35b50506001016106fe565b505050565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa1580156108eb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106109190612740565b60015473ffffffffffffffffffffffffffffffffffffffff163314610990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161056e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff80821660009081526005602052604081205490916106139116600161278c565b67ffffffffffffffff8416600090815260056020526040812073ffffffffffffffffffffffffffffffffffffffff8316610a9b576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610af7576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035473ffffffffffffffffffffffffffffffffffffffff168015610b9d576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610b6a908a908a90600401612520565b600060405180830381600087803b158015610b8457600080fd5b505af1158015610b98573d6000803e3d6000fd5b505050505b506002546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a610bd460808c0160608d0161236a565b8a610be260808e018e6127b4565b6040518663ffffffff1660e01b8152600401610c02959493929190612819565b600060405180830381865afa158015610c1f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c6591908101906128e1565b91945092509050610c7c6080890160608a0161236a565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f84604051610cc391815260200190565b60405180910390a2604080516101a081019091526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528c811661014085015287549293928392916101608401918a918791610d389116612938565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200186610e38576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e33919061295f565b610e3b565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a8060200190610e7991906127b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610ebd8b806127b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f0460808c018c6127b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f4e60808c0160608d0161236a565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190610f7f919061297c565b905067ffffffffffffffff811115610f9957610f99611ee3565b604051908082528060200260200182016040528015610ff557816020015b610fe26040518060800160405280606081526020016060815260200160608152602001600081525090565b815260200190600190039081610fb75790505b509052905060005b61100a60408b018b61297c565b90508110156110b95761109061102360408c018c61297c565b8381811061103357611033612711565b90506040020180360381019061104991906129e4565b8c6110548d806127b4565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92506116c7915050565b8260e0015182815181106110a6576110a6612711565b6020908102919091010152600101610ffd565b5060025460e082015173ffffffffffffffffffffffffffffffffffffffff9091169063cc88924c908c906110f060408e018e61297c565b6040518563ffffffff1660e01b815260040161110f9493929190612ae0565b60006040518083038186803b15801561112757600080fd5b505afa15801561113b573d6000803e3d6000fd5b505050506080808201839052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908c16606082015230918101919091526111d890829060a001604051602081830303815290604052805190602001206119d1565b81515260405167ffffffffffffffff8b16907f0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab2990611217908490612b16565b60405180910390a251519450505050505b949350505050565b611238611275565b61045d81611ad1565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff1633146112f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161056e565b565b60005b815181101561146c57600082828151811061131857611318612711565b60200260200101519050600083838151811061133657611336612711565b60200260200101516000015190508067ffffffffffffffff16600003611394576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161056e565b60408051808201825267ffffffffffffffff838116600081815260056020818152868320805480871688528a83015173ffffffffffffffffffffffffffffffffffffffff908116848a019081529587905293835287518551851668010000000000000000027fffffffff00000000000000000000000000000000000000000000000000000000909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a25050508060010190506112fb565b5050565b805173ffffffffffffffffffffffffffffffffffffffff1615806114ac5750604081015173ffffffffffffffffffffffffffffffffffffffff16155b156114e3576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480549094169085161790925581516080810183527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008416918101919091527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea45589161162f918490612c64565b60405180910390a150565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610855908490611bc6565b6116f26040518060800160405280606081526020016060815260200160608152602001600081525090565b8460200151600003611730576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061174085876000015161085a565b905073ffffffffffffffffffffffffffffffffffffffff8116158061181057506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156117ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180e91906123f1565b155b156118625785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161056e565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b81526004016119019190612cf6565b6000604051808303816000875af1158015611920573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119669190810190612d6c565b604080516080810190915273ffffffffffffffffffffffffffffffffffffffff841660a08201529091508060c0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c00151604051602001611a1396959493929190612dfd565b604051602081830303815290604052805190602001208560400151805190602001208660e00151604051602001611a4a9190612e5e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611b50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161056e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611c28826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611cd29092919063ffffffff16565b8051909150156108555780806020019051810190611c4691906123f1565b610855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161056e565b6060611ce18484600085611ceb565b90505b9392505050565b606082471015611d7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161056e565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611da69190612e71565b60006040518083038185875af1925050503d8060008114611de3576040519150601f19603f3d011682016040523d82523d6000602084013e611de8565b606091505b5091509150611df987838387611e04565b979650505050505050565b60608315611e9a578251600003611e935773ffffffffffffffffffffffffffffffffffffffff85163b611e93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161056e565b5081611228565b6112288383815115611eaf5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056e919061216e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611f3557611f35611ee3565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611f8257611f82611ee3565b604052919050565b600067ffffffffffffffff821115611fa457611fa4611ee3565b5060051b60200190565b67ffffffffffffffff8116811461045d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461045d57600080fd5b60006020808385031215611ff957600080fd5b823567ffffffffffffffff81111561201057600080fd5b8301601f8101851361202157600080fd5b803561203461202f82611f8a565b611f3b565b81815260069190911b8201830190838101908783111561205357600080fd5b928401925b82841015611df957604084890312156120715760008081fd5b612079611f12565b843561208481611fae565b81528486013561209381611fc4565b8187015282526040939093019290840190612058565b60808101610613828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b8381101561211b578181015183820152602001612103565b50506000910152565b6000815180845261213c816020860160208601612100565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106106020830184612124565b600060a0828403121561219357600080fd5b50919050565b600080604083850312156121ac57600080fd5b82356121b781611fae565b9150602083013567ffffffffffffffff8111156121d357600080fd5b6121df85828601612181565b9150509250929050565b80356121f481611fc4565b919050565b60006060828403121561220b57600080fd5b6040516060810181811067ffffffffffffffff8211171561222e5761222e611ee3565b604052823561223c81611fc4565b8152602083013561224c81611fc4565b6020820152604083013561225f81611fc4565b60408201529392505050565b6000806040838503121561227e57600080fd5b823561228981611fae565b9150602083013561229981611fc4565b809150509250929050565b606081016106138284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260409182015116910152565b6000602082840312156122f357600080fd5b8135611ce481611fae565b6000806000806080858703121561231457600080fd5b843561231f81611fae565b9350602085013567ffffffffffffffff81111561233b57600080fd5b61234787828801612181565b93505060408501359150606085013561235f81611fc4565b939692955090935050565b60006020828403121561237c57600080fd5b8135611ce481611fc4565b6020808252825182820181905260009190848201906040850190845b818110156123d557835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016123a3565b50909695505050505050565b805180151581146121f457600080fd5b60006020828403121561240357600080fd5b610610826123e1565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261244157600080fd5b830160208101925035905067ffffffffffffffff81111561246157600080fd5b80360382131561247057600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156125155781356124e381611fc4565b73ffffffffffffffffffffffffffffffffffffffff1687528183013583880152604096870196909101906001016124d0565b509495945050505050565b600067ffffffffffffffff808516835260406020840152612541848561240c565b60a0604086015261255660e086018284612477565b915050612566602086018661240c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087850301606088015261259c848385612477565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030183126125d557600080fd5b602092880192830192359150848211156125ee57600080fd5b8160061b360383131561260057600080fd5b808785030160808801526126158483856124c0565b9450612623606089016121e9565b73ffffffffffffffffffffffffffffffffffffffff811660a0890152935061264e608089018961240c565b94509250808786030160c08801525050611df9838383612477565b60006020828403121561267b57600080fd5b5051919050565b6000602080838503121561269557600080fd5b825167ffffffffffffffff8111156126ac57600080fd5b8301601f810185136126bd57600080fd5b80516126cb61202f82611f8a565b81815260059190911b820183019083810190878311156126ea57600080fd5b928401925b82841015611df957835161270281611fc4565b825292840192908401906126ef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561275257600080fd5b8151611ce481611fc4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156127ad576127ad61275d565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126127e957600080fd5b83018035915067ffffffffffffffff82111561280457600080fd5b60200191503681900382131561247057600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152608060608201526000611df9608083018486612477565b600082601f83011261287057600080fd5b815167ffffffffffffffff81111561288a5761288a611ee3565b6128bb60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611f3b565b8181528460208386010111156128d057600080fd5b611228826020830160208701612100565b6000806000606084860312156128f657600080fd5b83519250612906602085016123e1565b9150604084015167ffffffffffffffff81111561292257600080fd5b61292e8682870161285f565b9150509250925092565b600067ffffffffffffffff8083168181036129555761295561275d565b6001019392505050565b60006020828403121561297157600080fd5b8151611ce481611fae565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126129b157600080fd5b83018035915067ffffffffffffffff8211156129cc57600080fd5b6020019150600681901b360382131561247057600080fd5b6000604082840312156129f657600080fd5b6129fe611f12565b8235612a0981611fc4565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b84811015612ad3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160808151818652612a7f82870182612124565b9150508582015185820387870152612a978282612124565b91505060408083015186830382880152612ab18382612124565b6060948501519790940196909652505098840198925090830190600101612a3b565b5090979650505050505050565b67ffffffffffffffff85168152606060208201526000612b036060830186612a1e565b8281036040840152611df98185876124c0565b60208152612b6760208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b60006020830151612b9060c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e0850152612bad6101a0850183612124565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301610100870152612bea8483612124565b9350608087015191508086850301610120870152612c088483612124565b935060a08701519150612c3461014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e0870151915080868503018387015250612c5a8382612a1e565b9695505050505050565b60e08101612cbb828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a084015260408401511660c0830152611ce4565b602081526000825160a06020840152612d1260c0840182612124565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600060208284031215612d7e57600080fd5b815167ffffffffffffffff80821115612d9657600080fd5b9083019060408286031215612daa57600080fd5b612db2611f12565b825182811115612dc157600080fd5b612dcd8782860161285f565b825250602083015182811115612de257600080fd5b612dee8782860161285f565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c06020840152612e2d60c0840189612124565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b6020815260006106106020830184612a1e565b60008251612e83818460208701612100565b919091019291505056fea164736f6c6343000818000a", +type OnRampDestChainConfig struct { + SequenceNumber uint64 + Router common.Address +} + +type OnRampDestChainConfigArgs struct { + DestChainSelector uint64 + Router common.Address +} + +type OnRampDynamicConfig struct { + PriceRegistry common.Address + MessageValidator common.Address + FeeAggregator common.Address +} + +type OnRampStaticConfig struct { + ChainSelector uint64 + RmnProxy common.Address + NonceManager common.Address + TokenAdminRegistry common.Address +} + +var OnRampMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b50604051620036af380380620036af83398101604081905262000035916200069c565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000186565b505083516001600160401b031615905080620000e6575060208301516001600160a01b0316155b80620000fd575060408301516001600160a01b0316155b8062000114575060608301516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b82516001600160401b031660805260208301516001600160a01b0390811660a0526040840151811660c05260608401511660e052620001728262000231565b6200017d816200036d565b5050506200079c565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316158062000254575060408101516001600160a01b0316155b1562000273576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b03938416179091556020808401805160038054851691861691909117905560408086018051600480549096169087161790945580516080808201835280516001600160401b031680835260a08051891684880190815260c080518b1686880190815260e080518d166060988901908152895196875293518d169a86019a909a52518b169684019690965251891693820193909352885188169181019190915292518616908301529251909316918301919091527f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558910160405180910390a150565b60005b8151811015620004aa57600082828151811062000391576200039162000786565b602002602001015190506000838381518110620003b257620003b262000786565b6020026020010151600001519050806001600160401b0316600003620003f75760405163c35aa79d60e01b81526001600160401b038216600482015260240162000083565b6040805180820182526001600160401b03838116600081815260056020818152868320805480871688528a8301516001600160a01b03908116848a019081529587905293835287518551851668010000000000000000026001600160e01b0319909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a250505080600101905062000370565b5050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620004e957620004e9620004ae565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200051a576200051a620004ae565b604052919050565b80516001600160401b03811681146200053a57600080fd5b919050565b6001600160a01b03811681146200055557600080fd5b50565b6000606082840312156200056b57600080fd5b604051606081016001600160401b0381118282101715620005905762000590620004ae565b80604052508091508251620005a5816200053f565b81526020830151620005b7816200053f565b60208201526040830151620005cc816200053f565b6040919091015292915050565b600082601f830112620005eb57600080fd5b815160206001600160401b03821115620006095762000609620004ae565b62000619818360051b01620004ef565b82815260069290921b840181019181810190868411156200063957600080fd5b8286015b84811015620006915760408189031215620006585760008081fd5b62000662620004c4565b6200066d8262000522565b8152848201516200067e816200053f565b818601528352918301916040016200063d565b509695505050505050565b6000806000838503610100811215620006b457600080fd5b6080811215620006c357600080fd5b50604051608081016001600160401b038082118383101715620006ea57620006ea620004ae565b81604052620006f98762000522565b8352602087015191506200070d826200053f565b8160208401526040870151915062000725826200053f565b816040840152606087015191506200073d826200053f565b81606084015282955062000755886080890162000558565b945060e08701519250808311156200076c57600080fd5b50506200077c86828701620005d9565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e051612e9a62000815600039600081816101eb015281816108a201526115da0152600081816101af01528181610dc601526115b3015260008181610173015281816104c4015261158901526000818161014301528181610cec0152818161117c015261155c0152612e9a6000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637437ff9f11610097578063d77d5ed011610066578063d77d5ed0146103ba578063df0aa9e914610406578063f2fde38b14610419578063fbca3b741461042c57600080fd5b80637437ff9f146102fb57806379ba5097146103685780638da5cb5b146103705780639041be3d1461038e57600080fd5b806320487ded116100d357806320487ded1461028757806334d560e4146102a85780633a019940146102bb57806348a98aa4146102c357600080fd5b80630242cf60146100fa57806306285c691461010f578063181f5a771461023e575b600080fd5b61010d610108366004611fe6565b61044c565b005b61022860408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161023591906120a9565b60405180910390f35b61027a6040518060400160405280601081526020017f4f6e52616d7020312e362e302d6465760000000000000000000000000000000081525081565b604051610235919061216e565b61029a610295366004612199565b610460565b604051908152602001610235565b61010d6102b63660046121f9565b610619565b61010d61062a565b6102d66102d136600461226b565b61085a565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610235565b61035b6040805160608101825260008082526020820181905291810191909152506040805160608101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454169181019190915290565b60405161023591906122a4565b61010d61090f565b60005473ffffffffffffffffffffffffffffffffffffffff166102d6565b6103a161039c3660046122e1565b610a0c565b60405167ffffffffffffffff9091168152602001610235565b6102d66103c83660046122e1565b67ffffffffffffffff1660009081526005602052604090205468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b61029a6104143660046122fe565b610a35565b61010d61042736600461236a565b611230565b61043f61043a3660046122e1565b611241565b6040516102359190612387565b610454611275565b61045d816112f8565b50565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561050b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052f91906123f1565b15610577576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6002546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd906105cf9086908690600401612520565b602060405180830381865afa1580156105ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106109190612669565b90505b92915050565b610621611275565b61045d81611470565b600254604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610699573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106df9190810190612682565b60045490915073ffffffffffffffffffffffffffffffffffffffff1660005b825181101561085557600083828151811061071b5761071b612711565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610796573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ba9190612669565b9050801561084b576107e373ffffffffffffffffffffffffffffffffffffffff8316858361163a565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e8360405161084291815260200190565b60405180910390a35b50506001016106fe565b505050565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa1580156108eb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106109190612740565b60015473ffffffffffffffffffffffffffffffffffffffff163314610990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161056e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff80821660009081526005602052604081205490916106139116600161278c565b67ffffffffffffffff8416600090815260056020526040812073ffffffffffffffffffffffffffffffffffffffff8316610a9b576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610af7576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035473ffffffffffffffffffffffffffffffffffffffff168015610b9d576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610b6a908a908a90600401612520565b600060405180830381600087803b158015610b8457600080fd5b505af1158015610b98573d6000803e3d6000fd5b505050505b506002546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a610bd460808c0160608d0161236a565b8a610be260808e018e6127b4565b6040518663ffffffff1660e01b8152600401610c02959493929190612819565b600060405180830381865afa158015610c1f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c6591908101906128e1565b91945092509050610c7c6080890160608a0161236a565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f84604051610cc391815260200190565b60405180910390a2604080516101a081019091526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528c811661014085015287549293928392916101608401918a918791610d389116612938565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200186610e38576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e33919061295f565b610e3b565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a8060200190610e7991906127b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610ebd8b806127b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f0460808c018c6127b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f4e60808c0160608d0161236a565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190610f7f919061297c565b905067ffffffffffffffff811115610f9957610f99611ee3565b604051908082528060200260200182016040528015610ff557816020015b610fe26040518060800160405280606081526020016060815260200160608152602001600081525090565b815260200190600190039081610fb75790505b509052905060005b61100a60408b018b61297c565b90508110156110b95761109061102360408c018c61297c565b8381811061103357611033612711565b90506040020180360381019061104991906129e4565b8c6110548d806127b4565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92506116c7915050565b8260e0015182815181106110a6576110a6612711565b6020908102919091010152600101610ffd565b5060025460e082015173ffffffffffffffffffffffffffffffffffffffff9091169063cc88924c908c906110f060408e018e61297c565b6040518563ffffffff1660e01b815260040161110f9493929190612ae0565b60006040518083038186803b15801561112757600080fd5b505afa15801561113b573d6000803e3d6000fd5b505050506080808201839052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908c16606082015230918101919091526111d890829060a001604051602081830303815290604052805190602001206119d1565b81515260405167ffffffffffffffff8b16907f0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab2990611217908490612b16565b60405180910390a251519450505050505b949350505050565b611238611275565b61045d81611ad1565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff1633146112f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161056e565b565b60005b815181101561146c57600082828151811061131857611318612711565b60200260200101519050600083838151811061133657611336612711565b60200260200101516000015190508067ffffffffffffffff16600003611394576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161056e565b60408051808201825267ffffffffffffffff838116600081815260056020818152868320805480871688528a83015173ffffffffffffffffffffffffffffffffffffffff908116848a019081529587905293835287518551851668010000000000000000027fffffffff00000000000000000000000000000000000000000000000000000000909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a25050508060010190506112fb565b5050565b805173ffffffffffffffffffffffffffffffffffffffff1615806114ac5750604081015173ffffffffffffffffffffffffffffffffffffffff16155b156114e3576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480549094169085161790925581516080810183527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008416918101919091527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea45589161162f918490612c64565b60405180910390a150565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610855908490611bc6565b6116f26040518060800160405280606081526020016060815260200160608152602001600081525090565b8460200151600003611730576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061174085876000015161085a565b905073ffffffffffffffffffffffffffffffffffffffff8116158061181057506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156117ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180e91906123f1565b155b156118625785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161056e565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b81526004016119019190612cf6565b6000604051808303816000875af1158015611920573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119669190810190612d6c565b604080516080810190915273ffffffffffffffffffffffffffffffffffffffff841660a08201529091508060c0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c00151604051602001611a1396959493929190612dfd565b604051602081830303815290604052805190602001208560400151805190602001208660e00151604051602001611a4a9190612e5e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611b50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161056e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611c28826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611cd29092919063ffffffff16565b8051909150156108555780806020019051810190611c4691906123f1565b610855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161056e565b6060611ce18484600085611ceb565b90505b9392505050565b606082471015611d7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161056e565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611da69190612e71565b60006040518083038185875af1925050503d8060008114611de3576040519150601f19603f3d011682016040523d82523d6000602084013e611de8565b606091505b5091509150611df987838387611e04565b979650505050505050565b60608315611e9a578251600003611e935773ffffffffffffffffffffffffffffffffffffffff85163b611e93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161056e565b5081611228565b6112288383815115611eaf5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056e919061216e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611f3557611f35611ee3565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611f8257611f82611ee3565b604052919050565b600067ffffffffffffffff821115611fa457611fa4611ee3565b5060051b60200190565b67ffffffffffffffff8116811461045d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461045d57600080fd5b60006020808385031215611ff957600080fd5b823567ffffffffffffffff81111561201057600080fd5b8301601f8101851361202157600080fd5b803561203461202f82611f8a565b611f3b565b81815260069190911b8201830190838101908783111561205357600080fd5b928401925b82841015611df957604084890312156120715760008081fd5b612079611f12565b843561208481611fae565b81528486013561209381611fc4565b8187015282526040939093019290840190612058565b60808101610613828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b8381101561211b578181015183820152602001612103565b50506000910152565b6000815180845261213c816020860160208601612100565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106106020830184612124565b600060a0828403121561219357600080fd5b50919050565b600080604083850312156121ac57600080fd5b82356121b781611fae565b9150602083013567ffffffffffffffff8111156121d357600080fd5b6121df85828601612181565b9150509250929050565b80356121f481611fc4565b919050565b60006060828403121561220b57600080fd5b6040516060810181811067ffffffffffffffff8211171561222e5761222e611ee3565b604052823561223c81611fc4565b8152602083013561224c81611fc4565b6020820152604083013561225f81611fc4565b60408201529392505050565b6000806040838503121561227e57600080fd5b823561228981611fae565b9150602083013561229981611fc4565b809150509250929050565b606081016106138284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260409182015116910152565b6000602082840312156122f357600080fd5b8135611ce481611fae565b6000806000806080858703121561231457600080fd5b843561231f81611fae565b9350602085013567ffffffffffffffff81111561233b57600080fd5b61234787828801612181565b93505060408501359150606085013561235f81611fc4565b939692955090935050565b60006020828403121561237c57600080fd5b8135611ce481611fc4565b6020808252825182820181905260009190848201906040850190845b818110156123d557835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016123a3565b50909695505050505050565b805180151581146121f457600080fd5b60006020828403121561240357600080fd5b610610826123e1565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261244157600080fd5b830160208101925035905067ffffffffffffffff81111561246157600080fd5b80360382131561247057600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156125155781356124e381611fc4565b73ffffffffffffffffffffffffffffffffffffffff1687528183013583880152604096870196909101906001016124d0565b509495945050505050565b600067ffffffffffffffff808516835260406020840152612541848561240c565b60a0604086015261255660e086018284612477565b915050612566602086018661240c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087850301606088015261259c848385612477565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030183126125d557600080fd5b602092880192830192359150848211156125ee57600080fd5b8160061b360383131561260057600080fd5b808785030160808801526126158483856124c0565b9450612623606089016121e9565b73ffffffffffffffffffffffffffffffffffffffff811660a0890152935061264e608089018961240c565b94509250808786030160c08801525050611df9838383612477565b60006020828403121561267b57600080fd5b5051919050565b6000602080838503121561269557600080fd5b825167ffffffffffffffff8111156126ac57600080fd5b8301601f810185136126bd57600080fd5b80516126cb61202f82611f8a565b81815260059190911b820183019083810190878311156126ea57600080fd5b928401925b82841015611df957835161270281611fc4565b825292840192908401906126ef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561275257600080fd5b8151611ce481611fc4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156127ad576127ad61275d565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126127e957600080fd5b83018035915067ffffffffffffffff82111561280457600080fd5b60200191503681900382131561247057600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152608060608201526000611df9608083018486612477565b600082601f83011261287057600080fd5b815167ffffffffffffffff81111561288a5761288a611ee3565b6128bb60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611f3b565b8181528460208386010111156128d057600080fd5b611228826020830160208701612100565b6000806000606084860312156128f657600080fd5b83519250612906602085016123e1565b9150604084015167ffffffffffffffff81111561292257600080fd5b61292e8682870161285f565b9150509250925092565b600067ffffffffffffffff8083168181036129555761295561275d565b6001019392505050565b60006020828403121561297157600080fd5b8151611ce481611fae565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126129b157600080fd5b83018035915067ffffffffffffffff8211156129cc57600080fd5b6020019150600681901b360382131561247057600080fd5b6000604082840312156129f657600080fd5b6129fe611f12565b8235612a0981611fc4565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b84811015612ad3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160808151818652612a7f82870182612124565b9150508582015185820387870152612a978282612124565b91505060408083015186830382880152612ab18382612124565b6060948501519790940196909652505098840198925090830190600101612a3b565b5090979650505050505050565b67ffffffffffffffff85168152606060208201526000612b036060830186612a1e565b8281036040840152611df98185876124c0565b60208152612b6760208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b60006020830151612b9060c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e0850152612bad6101a0850183612124565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301610100870152612bea8483612124565b9350608087015191508086850301610120870152612c088483612124565b935060a08701519150612c3461014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e0870151915080868503018387015250612c5a8382612a1e565b9695505050505050565b60e08101612cbb828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a084015260408401511660c0830152611ce4565b602081526000825160a06020840152612d1260c0840182612124565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600060208284031215612d7e57600080fd5b815167ffffffffffffffff80821115612d9657600080fd5b9083019060408286031215612daa57600080fd5b612db2611f12565b825182811115612dc157600080fd5b612dcd8782860161285f565b825250602083015182811115612de257600080fd5b612dee8782860161285f565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c06020840152612e2d60c0840189612124565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b6020815260006106106020830184612a1e565b60008251612e83818460208701612100565b919091019291505056fea164736f6c6343000818000a", } -var EVM2EVMMultiOnRampABI = EVM2EVMMultiOnRampMetaData.ABI +var OnRampABI = OnRampMetaData.ABI -var EVM2EVMMultiOnRampBin = EVM2EVMMultiOnRampMetaData.Bin +var OnRampBin = OnRampMetaData.Bin -func DeployEVM2EVMMultiOnRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig EVM2EVMMultiOnRampStaticConfig, dynamicConfig EVM2EVMMultiOnRampDynamicConfig, destChainConfigArgs []EVM2EVMMultiOnRampDestChainConfigArgs) (common.Address, *types.Transaction, *EVM2EVMMultiOnRamp, error) { - parsed, err := EVM2EVMMultiOnRampMetaData.GetAbi() +func DeployOnRamp(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig OnRampStaticConfig, dynamicConfig OnRampDynamicConfig, destChainConfigArgs []OnRampDestChainConfigArgs) (common.Address, *types.Transaction, *OnRamp, error) { + parsed, err := OnRampMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -110,154 +110,154 @@ func DeployEVM2EVMMultiOnRamp(auth *bind.TransactOpts, backend bind.ContractBack return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EVM2EVMMultiOnRampBin), backend, staticConfig, dynamicConfig, destChainConfigArgs) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(OnRampBin), backend, staticConfig, dynamicConfig, destChainConfigArgs) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &EVM2EVMMultiOnRamp{address: address, abi: *parsed, EVM2EVMMultiOnRampCaller: EVM2EVMMultiOnRampCaller{contract: contract}, EVM2EVMMultiOnRampTransactor: EVM2EVMMultiOnRampTransactor{contract: contract}, EVM2EVMMultiOnRampFilterer: EVM2EVMMultiOnRampFilterer{contract: contract}}, nil + return address, tx, &OnRamp{address: address, abi: *parsed, OnRampCaller: OnRampCaller{contract: contract}, OnRampTransactor: OnRampTransactor{contract: contract}, OnRampFilterer: OnRampFilterer{contract: contract}}, nil } -type EVM2EVMMultiOnRamp struct { +type OnRamp struct { address common.Address abi abi.ABI - EVM2EVMMultiOnRampCaller - EVM2EVMMultiOnRampTransactor - EVM2EVMMultiOnRampFilterer + OnRampCaller + OnRampTransactor + OnRampFilterer } -type EVM2EVMMultiOnRampCaller struct { +type OnRampCaller struct { contract *bind.BoundContract } -type EVM2EVMMultiOnRampTransactor struct { +type OnRampTransactor struct { contract *bind.BoundContract } -type EVM2EVMMultiOnRampFilterer struct { +type OnRampFilterer struct { contract *bind.BoundContract } -type EVM2EVMMultiOnRampSession struct { - Contract *EVM2EVMMultiOnRamp +type OnRampSession struct { + Contract *OnRamp CallOpts bind.CallOpts TransactOpts bind.TransactOpts } -type EVM2EVMMultiOnRampCallerSession struct { - Contract *EVM2EVMMultiOnRampCaller +type OnRampCallerSession struct { + Contract *OnRampCaller CallOpts bind.CallOpts } -type EVM2EVMMultiOnRampTransactorSession struct { - Contract *EVM2EVMMultiOnRampTransactor +type OnRampTransactorSession struct { + Contract *OnRampTransactor TransactOpts bind.TransactOpts } -type EVM2EVMMultiOnRampRaw struct { - Contract *EVM2EVMMultiOnRamp +type OnRampRaw struct { + Contract *OnRamp } -type EVM2EVMMultiOnRampCallerRaw struct { - Contract *EVM2EVMMultiOnRampCaller +type OnRampCallerRaw struct { + Contract *OnRampCaller } -type EVM2EVMMultiOnRampTransactorRaw struct { - Contract *EVM2EVMMultiOnRampTransactor +type OnRampTransactorRaw struct { + Contract *OnRampTransactor } -func NewEVM2EVMMultiOnRamp(address common.Address, backend bind.ContractBackend) (*EVM2EVMMultiOnRamp, error) { - abi, err := abi.JSON(strings.NewReader(EVM2EVMMultiOnRampABI)) +func NewOnRamp(address common.Address, backend bind.ContractBackend) (*OnRamp, error) { + abi, err := abi.JSON(strings.NewReader(OnRampABI)) if err != nil { return nil, err } - contract, err := bindEVM2EVMMultiOnRamp(address, backend, backend, backend) + contract, err := bindOnRamp(address, backend, backend, backend) if err != nil { return nil, err } - return &EVM2EVMMultiOnRamp{address: address, abi: abi, EVM2EVMMultiOnRampCaller: EVM2EVMMultiOnRampCaller{contract: contract}, EVM2EVMMultiOnRampTransactor: EVM2EVMMultiOnRampTransactor{contract: contract}, EVM2EVMMultiOnRampFilterer: EVM2EVMMultiOnRampFilterer{contract: contract}}, nil + return &OnRamp{address: address, abi: abi, OnRampCaller: OnRampCaller{contract: contract}, OnRampTransactor: OnRampTransactor{contract: contract}, OnRampFilterer: OnRampFilterer{contract: contract}}, nil } -func NewEVM2EVMMultiOnRampCaller(address common.Address, caller bind.ContractCaller) (*EVM2EVMMultiOnRampCaller, error) { - contract, err := bindEVM2EVMMultiOnRamp(address, caller, nil, nil) +func NewOnRampCaller(address common.Address, caller bind.ContractCaller) (*OnRampCaller, error) { + contract, err := bindOnRamp(address, caller, nil, nil) if err != nil { return nil, err } - return &EVM2EVMMultiOnRampCaller{contract: contract}, nil + return &OnRampCaller{contract: contract}, nil } -func NewEVM2EVMMultiOnRampTransactor(address common.Address, transactor bind.ContractTransactor) (*EVM2EVMMultiOnRampTransactor, error) { - contract, err := bindEVM2EVMMultiOnRamp(address, nil, transactor, nil) +func NewOnRampTransactor(address common.Address, transactor bind.ContractTransactor) (*OnRampTransactor, error) { + contract, err := bindOnRamp(address, nil, transactor, nil) if err != nil { return nil, err } - return &EVM2EVMMultiOnRampTransactor{contract: contract}, nil + return &OnRampTransactor{contract: contract}, nil } -func NewEVM2EVMMultiOnRampFilterer(address common.Address, filterer bind.ContractFilterer) (*EVM2EVMMultiOnRampFilterer, error) { - contract, err := bindEVM2EVMMultiOnRamp(address, nil, nil, filterer) +func NewOnRampFilterer(address common.Address, filterer bind.ContractFilterer) (*OnRampFilterer, error) { + contract, err := bindOnRamp(address, nil, nil, filterer) if err != nil { return nil, err } - return &EVM2EVMMultiOnRampFilterer{contract: contract}, nil + return &OnRampFilterer{contract: contract}, nil } -func bindEVM2EVMMultiOnRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := EVM2EVMMultiOnRampMetaData.GetAbi() +func bindOnRamp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OnRampMetaData.GetAbi() if err != nil { return nil, err } return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _EVM2EVMMultiOnRamp.Contract.EVM2EVMMultiOnRampCaller.contract.Call(opts, result, method, params...) +func (_OnRamp *OnRampRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OnRamp.Contract.OnRampCaller.contract.Call(opts, result, method, params...) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.EVM2EVMMultiOnRampTransactor.contract.Transfer(opts) +func (_OnRamp *OnRampRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OnRamp.Contract.OnRampTransactor.contract.Transfer(opts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.EVM2EVMMultiOnRampTransactor.contract.Transact(opts, method, params...) +func (_OnRamp *OnRampRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OnRamp.Contract.OnRampTransactor.contract.Transact(opts, method, params...) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _EVM2EVMMultiOnRamp.Contract.contract.Call(opts, result, method, params...) +func (_OnRamp *OnRampCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OnRamp.Contract.contract.Call(opts, result, method, params...) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.contract.Transfer(opts) +func (_OnRamp *OnRampTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OnRamp.Contract.contract.Transfer(opts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.contract.Transact(opts, method, params...) +func (_OnRamp *OnRampTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OnRamp.Contract.contract.Transact(opts, method, params...) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMMultiOnRampDynamicConfig, error) { +func (_OnRamp *OnRampCaller) GetDynamicConfig(opts *bind.CallOpts) (OnRampDynamicConfig, error) { var out []interface{} - err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getDynamicConfig") + err := _OnRamp.contract.Call(opts, &out, "getDynamicConfig") if err != nil { - return *new(EVM2EVMMultiOnRampDynamicConfig), err + return *new(OnRampDynamicConfig), err } - out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOnRampDynamicConfig)).(*EVM2EVMMultiOnRampDynamicConfig) + out0 := *abi.ConvertType(out[0], new(OnRampDynamicConfig)).(*OnRampDynamicConfig) return out0, err } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetDynamicConfig() (EVM2EVMMultiOnRampDynamicConfig, error) { - return _EVM2EVMMultiOnRamp.Contract.GetDynamicConfig(&_EVM2EVMMultiOnRamp.CallOpts) +func (_OnRamp *OnRampSession) GetDynamicConfig() (OnRampDynamicConfig, error) { + return _OnRamp.Contract.GetDynamicConfig(&_OnRamp.CallOpts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetDynamicConfig() (EVM2EVMMultiOnRampDynamicConfig, error) { - return _EVM2EVMMultiOnRamp.Contract.GetDynamicConfig(&_EVM2EVMMultiOnRamp.CallOpts) +func (_OnRamp *OnRampCallerSession) GetDynamicConfig() (OnRampDynamicConfig, error) { + return _OnRamp.Contract.GetDynamicConfig(&_OnRamp.CallOpts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts, destChainSelector uint64) (uint64, error) { +func (_OnRamp *OnRampCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts, destChainSelector uint64) (uint64, error) { var out []interface{} - err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getExpectedNextSequenceNumber", destChainSelector) + err := _OnRamp.contract.Call(opts, &out, "getExpectedNextSequenceNumber", destChainSelector) if err != nil { return *new(uint64), err @@ -269,17 +269,17 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetExpectedNextSequenceNumb } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetExpectedNextSequenceNumber(destChainSelector uint64) (uint64, error) { - return _EVM2EVMMultiOnRamp.Contract.GetExpectedNextSequenceNumber(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector) +func (_OnRamp *OnRampSession) GetExpectedNextSequenceNumber(destChainSelector uint64) (uint64, error) { + return _OnRamp.Contract.GetExpectedNextSequenceNumber(&_OnRamp.CallOpts, destChainSelector) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetExpectedNextSequenceNumber(destChainSelector uint64) (uint64, error) { - return _EVM2EVMMultiOnRamp.Contract.GetExpectedNextSequenceNumber(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector) +func (_OnRamp *OnRampCallerSession) GetExpectedNextSequenceNumber(destChainSelector uint64) (uint64, error) { + return _OnRamp.Contract.GetExpectedNextSequenceNumber(&_OnRamp.CallOpts, destChainSelector) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { +func (_OnRamp *OnRampCaller) GetFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { var out []interface{} - err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getFee", destChainSelector, message) + err := _OnRamp.contract.Call(opts, &out, "getFee", destChainSelector, message) if err != nil { return *new(*big.Int), err @@ -291,17 +291,17 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetFee(opts *bind.CallOpts, } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { - return _EVM2EVMMultiOnRamp.Contract.GetFee(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector, message) +func (_OnRamp *OnRampSession) GetFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _OnRamp.Contract.GetFee(&_OnRamp.CallOpts, destChainSelector, message) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { - return _EVM2EVMMultiOnRamp.Contract.GetFee(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector, message) +func (_OnRamp *OnRampCallerSession) GetFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _OnRamp.Contract.GetFee(&_OnRamp.CallOpts, destChainSelector, message) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetPoolBySourceToken(opts *bind.CallOpts, arg0 uint64, sourceToken common.Address) (common.Address, error) { +func (_OnRamp *OnRampCaller) GetPoolBySourceToken(opts *bind.CallOpts, arg0 uint64, sourceToken common.Address) (common.Address, error) { var out []interface{} - err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getPoolBySourceToken", arg0, sourceToken) + err := _OnRamp.contract.Call(opts, &out, "getPoolBySourceToken", arg0, sourceToken) if err != nil { return *new(common.Address), err @@ -313,17 +313,17 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetPoolBySourceToken(opts * } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetPoolBySourceToken(arg0 uint64, sourceToken common.Address) (common.Address, error) { - return _EVM2EVMMultiOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMMultiOnRamp.CallOpts, arg0, sourceToken) +func (_OnRamp *OnRampSession) GetPoolBySourceToken(arg0 uint64, sourceToken common.Address) (common.Address, error) { + return _OnRamp.Contract.GetPoolBySourceToken(&_OnRamp.CallOpts, arg0, sourceToken) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetPoolBySourceToken(arg0 uint64, sourceToken common.Address) (common.Address, error) { - return _EVM2EVMMultiOnRamp.Contract.GetPoolBySourceToken(&_EVM2EVMMultiOnRamp.CallOpts, arg0, sourceToken) +func (_OnRamp *OnRampCallerSession) GetPoolBySourceToken(arg0 uint64, sourceToken common.Address) (common.Address, error) { + return _OnRamp.Contract.GetPoolBySourceToken(&_OnRamp.CallOpts, arg0, sourceToken) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetRouter(opts *bind.CallOpts, destChainSelector uint64) (common.Address, error) { +func (_OnRamp *OnRampCaller) GetRouter(opts *bind.CallOpts, destChainSelector uint64) (common.Address, error) { var out []interface{} - err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getRouter", destChainSelector) + err := _OnRamp.contract.Call(opts, &out, "getRouter", destChainSelector) if err != nil { return *new(common.Address), err @@ -335,39 +335,39 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetRouter(opts *bind.CallOp } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetRouter(destChainSelector uint64) (common.Address, error) { - return _EVM2EVMMultiOnRamp.Contract.GetRouter(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector) +func (_OnRamp *OnRampSession) GetRouter(destChainSelector uint64) (common.Address, error) { + return _OnRamp.Contract.GetRouter(&_OnRamp.CallOpts, destChainSelector) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetRouter(destChainSelector uint64) (common.Address, error) { - return _EVM2EVMMultiOnRamp.Contract.GetRouter(&_EVM2EVMMultiOnRamp.CallOpts, destChainSelector) +func (_OnRamp *OnRampCallerSession) GetRouter(destChainSelector uint64) (common.Address, error) { + return _OnRamp.Contract.GetRouter(&_OnRamp.CallOpts, destChainSelector) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetStaticConfig(opts *bind.CallOpts) (EVM2EVMMultiOnRampStaticConfig, error) { +func (_OnRamp *OnRampCaller) GetStaticConfig(opts *bind.CallOpts) (OnRampStaticConfig, error) { var out []interface{} - err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getStaticConfig") + err := _OnRamp.contract.Call(opts, &out, "getStaticConfig") if err != nil { - return *new(EVM2EVMMultiOnRampStaticConfig), err + return *new(OnRampStaticConfig), err } - out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOnRampStaticConfig)).(*EVM2EVMMultiOnRampStaticConfig) + out0 := *abi.ConvertType(out[0], new(OnRampStaticConfig)).(*OnRampStaticConfig) return out0, err } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetStaticConfig() (EVM2EVMMultiOnRampStaticConfig, error) { - return _EVM2EVMMultiOnRamp.Contract.GetStaticConfig(&_EVM2EVMMultiOnRamp.CallOpts) +func (_OnRamp *OnRampSession) GetStaticConfig() (OnRampStaticConfig, error) { + return _OnRamp.Contract.GetStaticConfig(&_OnRamp.CallOpts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetStaticConfig() (EVM2EVMMultiOnRampStaticConfig, error) { - return _EVM2EVMMultiOnRamp.Contract.GetStaticConfig(&_EVM2EVMMultiOnRamp.CallOpts) +func (_OnRamp *OnRampCallerSession) GetStaticConfig() (OnRampStaticConfig, error) { + return _OnRamp.Contract.GetStaticConfig(&_OnRamp.CallOpts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetSupportedTokens(opts *bind.CallOpts, arg0 uint64) ([]common.Address, error) { +func (_OnRamp *OnRampCaller) GetSupportedTokens(opts *bind.CallOpts, arg0 uint64) ([]common.Address, error) { var out []interface{} - err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "getSupportedTokens", arg0) + err := _OnRamp.contract.Call(opts, &out, "getSupportedTokens", arg0) if err != nil { return *new([]common.Address), err @@ -379,17 +379,17 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) GetSupportedTokens(opts *bi } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) GetSupportedTokens(arg0 uint64) ([]common.Address, error) { - return _EVM2EVMMultiOnRamp.Contract.GetSupportedTokens(&_EVM2EVMMultiOnRamp.CallOpts, arg0) +func (_OnRamp *OnRampSession) GetSupportedTokens(arg0 uint64) ([]common.Address, error) { + return _OnRamp.Contract.GetSupportedTokens(&_OnRamp.CallOpts, arg0) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) GetSupportedTokens(arg0 uint64) ([]common.Address, error) { - return _EVM2EVMMultiOnRamp.Contract.GetSupportedTokens(&_EVM2EVMMultiOnRamp.CallOpts, arg0) +func (_OnRamp *OnRampCallerSession) GetSupportedTokens(arg0 uint64) ([]common.Address, error) { + return _OnRamp.Contract.GetSupportedTokens(&_OnRamp.CallOpts, arg0) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { +func (_OnRamp *OnRampCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "owner") + err := _OnRamp.contract.Call(opts, &out, "owner") if err != nil { return *new(common.Address), err @@ -401,17 +401,17 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) Owner(opts *bind.CallOpts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) Owner() (common.Address, error) { - return _EVM2EVMMultiOnRamp.Contract.Owner(&_EVM2EVMMultiOnRamp.CallOpts) +func (_OnRamp *OnRampSession) Owner() (common.Address, error) { + return _OnRamp.Contract.Owner(&_OnRamp.CallOpts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) Owner() (common.Address, error) { - return _EVM2EVMMultiOnRamp.Contract.Owner(&_EVM2EVMMultiOnRamp.CallOpts) +func (_OnRamp *OnRampCallerSession) Owner() (common.Address, error) { + return _OnRamp.Contract.Owner(&_OnRamp.CallOpts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { +func (_OnRamp *OnRampCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { var out []interface{} - err := _EVM2EVMMultiOnRamp.contract.Call(opts, &out, "typeAndVersion") + err := _OnRamp.contract.Call(opts, &out, "typeAndVersion") if err != nil { return *new(string), err @@ -423,88 +423,88 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCaller) TypeAndVersion(opts *bind.C } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) TypeAndVersion() (string, error) { - return _EVM2EVMMultiOnRamp.Contract.TypeAndVersion(&_EVM2EVMMultiOnRamp.CallOpts) +func (_OnRamp *OnRampSession) TypeAndVersion() (string, error) { + return _OnRamp.Contract.TypeAndVersion(&_OnRamp.CallOpts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampCallerSession) TypeAndVersion() (string, error) { - return _EVM2EVMMultiOnRamp.Contract.TypeAndVersion(&_EVM2EVMMultiOnRamp.CallOpts) +func (_OnRamp *OnRampCallerSession) TypeAndVersion() (string, error) { + return _OnRamp.Contract.TypeAndVersion(&_OnRamp.CallOpts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.contract.Transact(opts, "acceptOwnership") +func (_OnRamp *OnRampTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OnRamp.contract.Transact(opts, "acceptOwnership") } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) AcceptOwnership() (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.AcceptOwnership(&_EVM2EVMMultiOnRamp.TransactOpts) +func (_OnRamp *OnRampSession) AcceptOwnership() (*types.Transaction, error) { + return _OnRamp.Contract.AcceptOwnership(&_OnRamp.TransactOpts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.AcceptOwnership(&_EVM2EVMMultiOnRamp.TransactOpts) +func (_OnRamp *OnRampTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _OnRamp.Contract.AcceptOwnership(&_OnRamp.TransactOpts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []EVM2EVMMultiOnRampDestChainConfigArgs) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.contract.Transact(opts, "applyDestChainConfigUpdates", destChainConfigArgs) +func (_OnRamp *OnRampTransactor) ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []OnRampDestChainConfigArgs) (*types.Transaction, error) { + return _OnRamp.contract.Transact(opts, "applyDestChainConfigUpdates", destChainConfigArgs) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) ApplyDestChainConfigUpdates(destChainConfigArgs []EVM2EVMMultiOnRampDestChainConfigArgs) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.ApplyDestChainConfigUpdates(&_EVM2EVMMultiOnRamp.TransactOpts, destChainConfigArgs) +func (_OnRamp *OnRampSession) ApplyDestChainConfigUpdates(destChainConfigArgs []OnRampDestChainConfigArgs) (*types.Transaction, error) { + return _OnRamp.Contract.ApplyDestChainConfigUpdates(&_OnRamp.TransactOpts, destChainConfigArgs) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) ApplyDestChainConfigUpdates(destChainConfigArgs []EVM2EVMMultiOnRampDestChainConfigArgs) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.ApplyDestChainConfigUpdates(&_EVM2EVMMultiOnRamp.TransactOpts, destChainConfigArgs) +func (_OnRamp *OnRampTransactorSession) ApplyDestChainConfigUpdates(destChainConfigArgs []OnRampDestChainConfigArgs) (*types.Transaction, error) { + return _OnRamp.Contract.ApplyDestChainConfigUpdates(&_OnRamp.TransactOpts, destChainConfigArgs) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.contract.Transact(opts, "forwardFromRouter", destChainSelector, message, feeTokenAmount, originalSender) +func (_OnRamp *OnRampTransactor) ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _OnRamp.contract.Transact(opts, "forwardFromRouter", destChainSelector, message, feeTokenAmount, originalSender) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) ForwardFromRouter(destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.ForwardFromRouter(&_EVM2EVMMultiOnRamp.TransactOpts, destChainSelector, message, feeTokenAmount, originalSender) +func (_OnRamp *OnRampSession) ForwardFromRouter(destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _OnRamp.Contract.ForwardFromRouter(&_OnRamp.TransactOpts, destChainSelector, message, feeTokenAmount, originalSender) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) ForwardFromRouter(destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.ForwardFromRouter(&_EVM2EVMMultiOnRamp.TransactOpts, destChainSelector, message, feeTokenAmount, originalSender) +func (_OnRamp *OnRampTransactorSession) ForwardFromRouter(destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) { + return _OnRamp.Contract.ForwardFromRouter(&_OnRamp.TransactOpts, destChainSelector, message, feeTokenAmount, originalSender) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMMultiOnRampDynamicConfig) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.contract.Transact(opts, "setDynamicConfig", dynamicConfig) +func (_OnRamp *OnRampTransactor) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig OnRampDynamicConfig) (*types.Transaction, error) { + return _OnRamp.contract.Transact(opts, "setDynamicConfig", dynamicConfig) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) SetDynamicConfig(dynamicConfig EVM2EVMMultiOnRampDynamicConfig) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.SetDynamicConfig(&_EVM2EVMMultiOnRamp.TransactOpts, dynamicConfig) +func (_OnRamp *OnRampSession) SetDynamicConfig(dynamicConfig OnRampDynamicConfig) (*types.Transaction, error) { + return _OnRamp.Contract.SetDynamicConfig(&_OnRamp.TransactOpts, dynamicConfig) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) SetDynamicConfig(dynamicConfig EVM2EVMMultiOnRampDynamicConfig) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.SetDynamicConfig(&_EVM2EVMMultiOnRamp.TransactOpts, dynamicConfig) +func (_OnRamp *OnRampTransactorSession) SetDynamicConfig(dynamicConfig OnRampDynamicConfig) (*types.Transaction, error) { + return _OnRamp.Contract.SetDynamicConfig(&_OnRamp.TransactOpts, dynamicConfig) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.contract.Transact(opts, "transferOwnership", to) +func (_OnRamp *OnRampTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _OnRamp.contract.Transact(opts, "transferOwnership", to) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.TransferOwnership(&_EVM2EVMMultiOnRamp.TransactOpts, to) +func (_OnRamp *OnRampSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _OnRamp.Contract.TransferOwnership(&_OnRamp.TransactOpts, to) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.TransferOwnership(&_EVM2EVMMultiOnRamp.TransactOpts, to) +func (_OnRamp *OnRampTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _OnRamp.Contract.TransferOwnership(&_OnRamp.TransactOpts, to) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactor) WithdrawFeeTokens(opts *bind.TransactOpts) (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.contract.Transact(opts, "withdrawFeeTokens") +func (_OnRamp *OnRampTransactor) WithdrawFeeTokens(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OnRamp.contract.Transact(opts, "withdrawFeeTokens") } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampSession) WithdrawFeeTokens() (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.WithdrawFeeTokens(&_EVM2EVMMultiOnRamp.TransactOpts) +func (_OnRamp *OnRampSession) WithdrawFeeTokens() (*types.Transaction, error) { + return _OnRamp.Contract.WithdrawFeeTokens(&_OnRamp.TransactOpts) } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampTransactorSession) WithdrawFeeTokens() (*types.Transaction, error) { - return _EVM2EVMMultiOnRamp.Contract.WithdrawFeeTokens(&_EVM2EVMMultiOnRamp.TransactOpts) +func (_OnRamp *OnRampTransactorSession) WithdrawFeeTokens() (*types.Transaction, error) { + return _OnRamp.Contract.WithdrawFeeTokens(&_OnRamp.TransactOpts) } -type EVM2EVMMultiOnRampCCIPSendRequestedIterator struct { - Event *EVM2EVMMultiOnRampCCIPSendRequested +type OnRampCCIPSendRequestedIterator struct { + Event *OnRampCCIPSendRequested contract *bind.BoundContract event string @@ -515,7 +515,7 @@ type EVM2EVMMultiOnRampCCIPSendRequestedIterator struct { fail error } -func (it *EVM2EVMMultiOnRampCCIPSendRequestedIterator) Next() bool { +func (it *OnRampCCIPSendRequestedIterator) Next() bool { if it.fail != nil { return false @@ -524,7 +524,7 @@ func (it *EVM2EVMMultiOnRampCCIPSendRequestedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampCCIPSendRequested) + it.Event = new(OnRampCCIPSendRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -539,7 +539,7 @@ func (it *EVM2EVMMultiOnRampCCIPSendRequestedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampCCIPSendRequested) + it.Event = new(OnRampCCIPSendRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -554,43 +554,43 @@ func (it *EVM2EVMMultiOnRampCCIPSendRequestedIterator) Next() bool { } } -func (it *EVM2EVMMultiOnRampCCIPSendRequestedIterator) Error() error { +func (it *OnRampCCIPSendRequestedIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOnRampCCIPSendRequestedIterator) Close() error { +func (it *OnRampCCIPSendRequestedIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOnRampCCIPSendRequested struct { +type OnRampCCIPSendRequested struct { DestChainSelector uint64 Message InternalEVM2AnyRampMessage Raw types.Log } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*EVM2EVMMultiOnRampCCIPSendRequestedIterator, error) { +func (_OnRamp *OnRampFilterer) FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampCCIPSendRequestedIterator, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) } - logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "CCIPSendRequested", destChainSelectorRule) + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "CCIPSendRequested", destChainSelectorRule) if err != nil { return nil, err } - return &EVM2EVMMultiOnRampCCIPSendRequestedIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "CCIPSendRequested", logs: logs, sub: sub}, nil + return &OnRampCCIPSendRequestedIterator{contract: _OnRamp.contract, event: "CCIPSendRequested", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) { +func (_OnRamp *OnRampFilterer) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *OnRampCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) } - logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "CCIPSendRequested", destChainSelectorRule) + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "CCIPSendRequested", destChainSelectorRule) if err != nil { return nil, err } @@ -600,8 +600,8 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchCCIPSendRequested(op select { case log := <-logs: - event := new(EVM2EVMMultiOnRampCCIPSendRequested) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + event := new(OnRampCCIPSendRequested) + if err := _OnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { return err } event.Raw = log @@ -622,17 +622,17 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchCCIPSendRequested(op }), nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseCCIPSendRequested(log types.Log) (*EVM2EVMMultiOnRampCCIPSendRequested, error) { - event := new(EVM2EVMMultiOnRampCCIPSendRequested) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { +func (_OnRamp *OnRampFilterer) ParseCCIPSendRequested(log types.Log) (*OnRampCCIPSendRequested, error) { + event := new(OnRampCCIPSendRequested) + if err := _OnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOnRampConfigSetIterator struct { - Event *EVM2EVMMultiOnRampConfigSet +type OnRampConfigSetIterator struct { + Event *OnRampConfigSet contract *bind.BoundContract event string @@ -643,7 +643,7 @@ type EVM2EVMMultiOnRampConfigSetIterator struct { fail error } -func (it *EVM2EVMMultiOnRampConfigSetIterator) Next() bool { +func (it *OnRampConfigSetIterator) Next() bool { if it.fail != nil { return false @@ -652,7 +652,7 @@ func (it *EVM2EVMMultiOnRampConfigSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampConfigSet) + it.Event = new(OnRampConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -667,7 +667,7 @@ func (it *EVM2EVMMultiOnRampConfigSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampConfigSet) + it.Event = new(OnRampConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -682,33 +682,33 @@ func (it *EVM2EVMMultiOnRampConfigSetIterator) Next() bool { } } -func (it *EVM2EVMMultiOnRampConfigSetIterator) Error() error { +func (it *OnRampConfigSetIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOnRampConfigSetIterator) Close() error { +func (it *OnRampConfigSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOnRampConfigSet struct { - StaticConfig EVM2EVMMultiOnRampStaticConfig - DynamicConfig EVM2EVMMultiOnRampDynamicConfig +type OnRampConfigSet struct { + StaticConfig OnRampStaticConfig + DynamicConfig OnRampDynamicConfig Raw types.Log } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOnRampConfigSetIterator, error) { +func (_OnRamp *OnRampFilterer) FilterConfigSet(opts *bind.FilterOpts) (*OnRampConfigSetIterator, error) { - logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "ConfigSet") + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "ConfigSet") if err != nil { return nil, err } - return &EVM2EVMMultiOnRampConfigSetIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil + return &OnRampConfigSetIterator{contract: _OnRamp.contract, event: "ConfigSet", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampConfigSet) (event.Subscription, error) { +func (_OnRamp *OnRampFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *OnRampConfigSet) (event.Subscription, error) { - logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "ConfigSet") + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "ConfigSet") if err != nil { return nil, err } @@ -718,8 +718,8 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchConfigSet(opts *bind select { case log := <-logs: - event := new(EVM2EVMMultiOnRampConfigSet) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { + event := new(OnRampConfigSet) + if err := _OnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { return err } event.Raw = log @@ -740,17 +740,17 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchConfigSet(opts *bind }), nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseConfigSet(log types.Log) (*EVM2EVMMultiOnRampConfigSet, error) { - event := new(EVM2EVMMultiOnRampConfigSet) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { +func (_OnRamp *OnRampFilterer) ParseConfigSet(log types.Log) (*OnRampConfigSet, error) { + event := new(OnRampConfigSet) + if err := _OnRamp.contract.UnpackLog(event, "ConfigSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOnRampDestChainConfigSetIterator struct { - Event *EVM2EVMMultiOnRampDestChainConfigSet +type OnRampDestChainConfigSetIterator struct { + Event *OnRampDestChainConfigSet contract *bind.BoundContract event string @@ -761,7 +761,7 @@ type EVM2EVMMultiOnRampDestChainConfigSetIterator struct { fail error } -func (it *EVM2EVMMultiOnRampDestChainConfigSetIterator) Next() bool { +func (it *OnRampDestChainConfigSetIterator) Next() bool { if it.fail != nil { return false @@ -770,7 +770,7 @@ func (it *EVM2EVMMultiOnRampDestChainConfigSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampDestChainConfigSet) + it.Event = new(OnRampDestChainConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -785,7 +785,7 @@ func (it *EVM2EVMMultiOnRampDestChainConfigSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampDestChainConfigSet) + it.Event = new(OnRampDestChainConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -800,43 +800,43 @@ func (it *EVM2EVMMultiOnRampDestChainConfigSetIterator) Next() bool { } } -func (it *EVM2EVMMultiOnRampDestChainConfigSetIterator) Error() error { +func (it *OnRampDestChainConfigSetIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOnRampDestChainConfigSetIterator) Close() error { +func (it *OnRampDestChainConfigSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOnRampDestChainConfigSet struct { +type OnRampDestChainConfigSet struct { DestChainSelector uint64 - DestChainConfig EVM2EVMMultiOnRampDestChainConfig + DestChainConfig OnRampDestChainConfig Raw types.Log } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterDestChainConfigSet(opts *bind.FilterOpts, destChainSelector []uint64) (*EVM2EVMMultiOnRampDestChainConfigSetIterator, error) { +func (_OnRamp *OnRampFilterer) FilterDestChainConfigSet(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampDestChainConfigSetIterator, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) } - logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "DestChainConfigSet", destChainSelectorRule) + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "DestChainConfigSet", destChainSelectorRule) if err != nil { return nil, err } - return &EVM2EVMMultiOnRampDestChainConfigSetIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "DestChainConfigSet", logs: logs, sub: sub}, nil + return &OnRampDestChainConfigSetIterator{contract: _OnRamp.contract, event: "DestChainConfigSet", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchDestChainConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampDestChainConfigSet, destChainSelector []uint64) (event.Subscription, error) { +func (_OnRamp *OnRampFilterer) WatchDestChainConfigSet(opts *bind.WatchOpts, sink chan<- *OnRampDestChainConfigSet, destChainSelector []uint64) (event.Subscription, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) } - logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "DestChainConfigSet", destChainSelectorRule) + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "DestChainConfigSet", destChainSelectorRule) if err != nil { return nil, err } @@ -846,8 +846,8 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchDestChainConfigSet(o select { case log := <-logs: - event := new(EVM2EVMMultiOnRampDestChainConfigSet) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "DestChainConfigSet", log); err != nil { + event := new(OnRampDestChainConfigSet) + if err := _OnRamp.contract.UnpackLog(event, "DestChainConfigSet", log); err != nil { return err } event.Raw = log @@ -868,17 +868,17 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchDestChainConfigSet(o }), nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseDestChainConfigSet(log types.Log) (*EVM2EVMMultiOnRampDestChainConfigSet, error) { - event := new(EVM2EVMMultiOnRampDestChainConfigSet) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "DestChainConfigSet", log); err != nil { +func (_OnRamp *OnRampFilterer) ParseDestChainConfigSet(log types.Log) (*OnRampDestChainConfigSet, error) { + event := new(OnRampDestChainConfigSet) + if err := _OnRamp.contract.UnpackLog(event, "DestChainConfigSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOnRampFeePaidIterator struct { - Event *EVM2EVMMultiOnRampFeePaid +type OnRampFeePaidIterator struct { + Event *OnRampFeePaid contract *bind.BoundContract event string @@ -889,7 +889,7 @@ type EVM2EVMMultiOnRampFeePaidIterator struct { fail error } -func (it *EVM2EVMMultiOnRampFeePaidIterator) Next() bool { +func (it *OnRampFeePaidIterator) Next() bool { if it.fail != nil { return false @@ -898,7 +898,7 @@ func (it *EVM2EVMMultiOnRampFeePaidIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampFeePaid) + it.Event = new(OnRampFeePaid) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -913,7 +913,7 @@ func (it *EVM2EVMMultiOnRampFeePaidIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampFeePaid) + it.Event = new(OnRampFeePaid) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -928,43 +928,43 @@ func (it *EVM2EVMMultiOnRampFeePaidIterator) Next() bool { } } -func (it *EVM2EVMMultiOnRampFeePaidIterator) Error() error { +func (it *OnRampFeePaidIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOnRampFeePaidIterator) Close() error { +func (it *OnRampFeePaidIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOnRampFeePaid struct { +type OnRampFeePaid struct { FeeToken common.Address FeeValueJuels *big.Int Raw types.Log } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterFeePaid(opts *bind.FilterOpts, feeToken []common.Address) (*EVM2EVMMultiOnRampFeePaidIterator, error) { +func (_OnRamp *OnRampFilterer) FilterFeePaid(opts *bind.FilterOpts, feeToken []common.Address) (*OnRampFeePaidIterator, error) { var feeTokenRule []interface{} for _, feeTokenItem := range feeToken { feeTokenRule = append(feeTokenRule, feeTokenItem) } - logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "FeePaid", feeTokenRule) + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "FeePaid", feeTokenRule) if err != nil { return nil, err } - return &EVM2EVMMultiOnRampFeePaidIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "FeePaid", logs: logs, sub: sub}, nil + return &OnRampFeePaidIterator{contract: _OnRamp.contract, event: "FeePaid", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchFeePaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampFeePaid, feeToken []common.Address) (event.Subscription, error) { +func (_OnRamp *OnRampFilterer) WatchFeePaid(opts *bind.WatchOpts, sink chan<- *OnRampFeePaid, feeToken []common.Address) (event.Subscription, error) { var feeTokenRule []interface{} for _, feeTokenItem := range feeToken { feeTokenRule = append(feeTokenRule, feeTokenItem) } - logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "FeePaid", feeTokenRule) + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "FeePaid", feeTokenRule) if err != nil { return nil, err } @@ -974,8 +974,8 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchFeePaid(opts *bind.W select { case log := <-logs: - event := new(EVM2EVMMultiOnRampFeePaid) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "FeePaid", log); err != nil { + event := new(OnRampFeePaid) + if err := _OnRamp.contract.UnpackLog(event, "FeePaid", log); err != nil { return err } event.Raw = log @@ -996,17 +996,17 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchFeePaid(opts *bind.W }), nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseFeePaid(log types.Log) (*EVM2EVMMultiOnRampFeePaid, error) { - event := new(EVM2EVMMultiOnRampFeePaid) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "FeePaid", log); err != nil { +func (_OnRamp *OnRampFilterer) ParseFeePaid(log types.Log) (*OnRampFeePaid, error) { + event := new(OnRampFeePaid) + if err := _OnRamp.contract.UnpackLog(event, "FeePaid", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOnRampFeeTokenWithdrawnIterator struct { - Event *EVM2EVMMultiOnRampFeeTokenWithdrawn +type OnRampFeeTokenWithdrawnIterator struct { + Event *OnRampFeeTokenWithdrawn contract *bind.BoundContract event string @@ -1017,7 +1017,7 @@ type EVM2EVMMultiOnRampFeeTokenWithdrawnIterator struct { fail error } -func (it *EVM2EVMMultiOnRampFeeTokenWithdrawnIterator) Next() bool { +func (it *OnRampFeeTokenWithdrawnIterator) Next() bool { if it.fail != nil { return false @@ -1026,7 +1026,7 @@ func (it *EVM2EVMMultiOnRampFeeTokenWithdrawnIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampFeeTokenWithdrawn) + it.Event = new(OnRampFeeTokenWithdrawn) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1041,7 +1041,7 @@ func (it *EVM2EVMMultiOnRampFeeTokenWithdrawnIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampFeeTokenWithdrawn) + it.Event = new(OnRampFeeTokenWithdrawn) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1056,23 +1056,23 @@ func (it *EVM2EVMMultiOnRampFeeTokenWithdrawnIterator) Next() bool { } } -func (it *EVM2EVMMultiOnRampFeeTokenWithdrawnIterator) Error() error { +func (it *OnRampFeeTokenWithdrawnIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOnRampFeeTokenWithdrawnIterator) Close() error { +func (it *OnRampFeeTokenWithdrawnIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOnRampFeeTokenWithdrawn struct { +type OnRampFeeTokenWithdrawn struct { FeeAggregator common.Address FeeToken common.Address Amount *big.Int Raw types.Log } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterFeeTokenWithdrawn(opts *bind.FilterOpts, feeAggregator []common.Address, feeToken []common.Address) (*EVM2EVMMultiOnRampFeeTokenWithdrawnIterator, error) { +func (_OnRamp *OnRampFilterer) FilterFeeTokenWithdrawn(opts *bind.FilterOpts, feeAggregator []common.Address, feeToken []common.Address) (*OnRampFeeTokenWithdrawnIterator, error) { var feeAggregatorRule []interface{} for _, feeAggregatorItem := range feeAggregator { @@ -1083,14 +1083,14 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterFeeTokenWithdrawn(o feeTokenRule = append(feeTokenRule, feeTokenItem) } - logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "FeeTokenWithdrawn", feeAggregatorRule, feeTokenRule) + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "FeeTokenWithdrawn", feeAggregatorRule, feeTokenRule) if err != nil { return nil, err } - return &EVM2EVMMultiOnRampFeeTokenWithdrawnIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "FeeTokenWithdrawn", logs: logs, sub: sub}, nil + return &OnRampFeeTokenWithdrawnIterator{contract: _OnRamp.contract, event: "FeeTokenWithdrawn", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchFeeTokenWithdrawn(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampFeeTokenWithdrawn, feeAggregator []common.Address, feeToken []common.Address) (event.Subscription, error) { +func (_OnRamp *OnRampFilterer) WatchFeeTokenWithdrawn(opts *bind.WatchOpts, sink chan<- *OnRampFeeTokenWithdrawn, feeAggregator []common.Address, feeToken []common.Address) (event.Subscription, error) { var feeAggregatorRule []interface{} for _, feeAggregatorItem := range feeAggregator { @@ -1101,7 +1101,7 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchFeeTokenWithdrawn(op feeTokenRule = append(feeTokenRule, feeTokenItem) } - logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "FeeTokenWithdrawn", feeAggregatorRule, feeTokenRule) + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "FeeTokenWithdrawn", feeAggregatorRule, feeTokenRule) if err != nil { return nil, err } @@ -1111,8 +1111,8 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchFeeTokenWithdrawn(op select { case log := <-logs: - event := new(EVM2EVMMultiOnRampFeeTokenWithdrawn) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "FeeTokenWithdrawn", log); err != nil { + event := new(OnRampFeeTokenWithdrawn) + if err := _OnRamp.contract.UnpackLog(event, "FeeTokenWithdrawn", log); err != nil { return err } event.Raw = log @@ -1133,17 +1133,17 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchFeeTokenWithdrawn(op }), nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseFeeTokenWithdrawn(log types.Log) (*EVM2EVMMultiOnRampFeeTokenWithdrawn, error) { - event := new(EVM2EVMMultiOnRampFeeTokenWithdrawn) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "FeeTokenWithdrawn", log); err != nil { +func (_OnRamp *OnRampFilterer) ParseFeeTokenWithdrawn(log types.Log) (*OnRampFeeTokenWithdrawn, error) { + event := new(OnRampFeeTokenWithdrawn) + if err := _OnRamp.contract.UnpackLog(event, "FeeTokenWithdrawn", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOnRampOwnershipTransferRequestedIterator struct { - Event *EVM2EVMMultiOnRampOwnershipTransferRequested +type OnRampOwnershipTransferRequestedIterator struct { + Event *OnRampOwnershipTransferRequested contract *bind.BoundContract event string @@ -1154,7 +1154,7 @@ type EVM2EVMMultiOnRampOwnershipTransferRequestedIterator struct { fail error } -func (it *EVM2EVMMultiOnRampOwnershipTransferRequestedIterator) Next() bool { +func (it *OnRampOwnershipTransferRequestedIterator) Next() bool { if it.fail != nil { return false @@ -1163,7 +1163,7 @@ func (it *EVM2EVMMultiOnRampOwnershipTransferRequestedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampOwnershipTransferRequested) + it.Event = new(OnRampOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1178,7 +1178,7 @@ func (it *EVM2EVMMultiOnRampOwnershipTransferRequestedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampOwnershipTransferRequested) + it.Event = new(OnRampOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1193,22 +1193,22 @@ func (it *EVM2EVMMultiOnRampOwnershipTransferRequestedIterator) Next() bool { } } -func (it *EVM2EVMMultiOnRampOwnershipTransferRequestedIterator) Error() error { +func (it *OnRampOwnershipTransferRequestedIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOnRampOwnershipTransferRequestedIterator) Close() error { +func (it *OnRampOwnershipTransferRequestedIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOnRampOwnershipTransferRequested struct { +type OnRampOwnershipTransferRequested struct { From common.Address To common.Address Raw types.Log } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOnRampOwnershipTransferRequestedIterator, error) { +func (_OnRamp *OnRampFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OnRampOwnershipTransferRequestedIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1219,14 +1219,14 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterOwnershipTransferRe toRule = append(toRule, toItem) } - logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } - return &EVM2EVMMultiOnRampOwnershipTransferRequestedIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil + return &OnRampOwnershipTransferRequestedIterator{contract: _OnRamp.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_OnRamp *OnRampFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *OnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1237,7 +1237,7 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchOwnershipTransferReq toRule = append(toRule, toItem) } - logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } @@ -1247,8 +1247,8 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchOwnershipTransferReq select { case log := <-logs: - event := new(EVM2EVMMultiOnRampOwnershipTransferRequested) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + event := new(OnRampOwnershipTransferRequested) + if err := _OnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return err } event.Raw = log @@ -1269,17 +1269,17 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchOwnershipTransferReq }), nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMMultiOnRampOwnershipTransferRequested, error) { - event := new(EVM2EVMMultiOnRampOwnershipTransferRequested) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { +func (_OnRamp *OnRampFilterer) ParseOwnershipTransferRequested(log types.Log) (*OnRampOwnershipTransferRequested, error) { + event := new(OnRampOwnershipTransferRequested) + if err := _OnRamp.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return nil, err } event.Raw = log return event, nil } -type EVM2EVMMultiOnRampOwnershipTransferredIterator struct { - Event *EVM2EVMMultiOnRampOwnershipTransferred +type OnRampOwnershipTransferredIterator struct { + Event *OnRampOwnershipTransferred contract *bind.BoundContract event string @@ -1290,7 +1290,7 @@ type EVM2EVMMultiOnRampOwnershipTransferredIterator struct { fail error } -func (it *EVM2EVMMultiOnRampOwnershipTransferredIterator) Next() bool { +func (it *OnRampOwnershipTransferredIterator) Next() bool { if it.fail != nil { return false @@ -1299,7 +1299,7 @@ func (it *EVM2EVMMultiOnRampOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampOwnershipTransferred) + it.Event = new(OnRampOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1314,7 +1314,7 @@ func (it *EVM2EVMMultiOnRampOwnershipTransferredIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(EVM2EVMMultiOnRampOwnershipTransferred) + it.Event = new(OnRampOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1329,22 +1329,22 @@ func (it *EVM2EVMMultiOnRampOwnershipTransferredIterator) Next() bool { } } -func (it *EVM2EVMMultiOnRampOwnershipTransferredIterator) Error() error { +func (it *OnRampOwnershipTransferredIterator) Error() error { return it.fail } -func (it *EVM2EVMMultiOnRampOwnershipTransferredIterator) Close() error { +func (it *OnRampOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -type EVM2EVMMultiOnRampOwnershipTransferred struct { +type OnRampOwnershipTransferred struct { From common.Address To common.Address Raw types.Log } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOnRampOwnershipTransferredIterator, error) { +func (_OnRamp *OnRampFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OnRampOwnershipTransferredIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1355,14 +1355,14 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) FilterOwnershipTransferre toRule = append(toRule, toItem) } - logs, sub, err := _EVM2EVMMultiOnRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } - return &EVM2EVMMultiOnRampOwnershipTransferredIterator{contract: _EVM2EVMMultiOnRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &OnRampOwnershipTransferredIterator{contract: _OnRamp.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_OnRamp *OnRampFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1373,7 +1373,7 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchOwnershipTransferred toRule = append(toRule, toItem) } - logs, sub, err := _EVM2EVMMultiOnRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } @@ -1383,8 +1383,8 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchOwnershipTransferred select { case log := <-logs: - event := new(EVM2EVMMultiOnRampOwnershipTransferred) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(OnRampOwnershipTransferred) + if err := _OnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -1405,71 +1405,71 @@ func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) WatchOwnershipTransferred }), nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRampFilterer) ParseOwnershipTransferred(log types.Log) (*EVM2EVMMultiOnRampOwnershipTransferred, error) { - event := new(EVM2EVMMultiOnRampOwnershipTransferred) - if err := _EVM2EVMMultiOnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +func (_OnRamp *OnRampFilterer) ParseOwnershipTransferred(log types.Log) (*OnRampOwnershipTransferred, error) { + event := new(OnRampOwnershipTransferred) + if err := _OnRamp.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log return event, nil } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { +func (_OnRamp *OnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _EVM2EVMMultiOnRamp.abi.Events["CCIPSendRequested"].ID: - return _EVM2EVMMultiOnRamp.ParseCCIPSendRequested(log) - case _EVM2EVMMultiOnRamp.abi.Events["ConfigSet"].ID: - return _EVM2EVMMultiOnRamp.ParseConfigSet(log) - case _EVM2EVMMultiOnRamp.abi.Events["DestChainConfigSet"].ID: - return _EVM2EVMMultiOnRamp.ParseDestChainConfigSet(log) - case _EVM2EVMMultiOnRamp.abi.Events["FeePaid"].ID: - return _EVM2EVMMultiOnRamp.ParseFeePaid(log) - case _EVM2EVMMultiOnRamp.abi.Events["FeeTokenWithdrawn"].ID: - return _EVM2EVMMultiOnRamp.ParseFeeTokenWithdrawn(log) - case _EVM2EVMMultiOnRamp.abi.Events["OwnershipTransferRequested"].ID: - return _EVM2EVMMultiOnRamp.ParseOwnershipTransferRequested(log) - case _EVM2EVMMultiOnRamp.abi.Events["OwnershipTransferred"].ID: - return _EVM2EVMMultiOnRamp.ParseOwnershipTransferred(log) + case _OnRamp.abi.Events["CCIPSendRequested"].ID: + return _OnRamp.ParseCCIPSendRequested(log) + case _OnRamp.abi.Events["ConfigSet"].ID: + return _OnRamp.ParseConfigSet(log) + case _OnRamp.abi.Events["DestChainConfigSet"].ID: + return _OnRamp.ParseDestChainConfigSet(log) + case _OnRamp.abi.Events["FeePaid"].ID: + return _OnRamp.ParseFeePaid(log) + case _OnRamp.abi.Events["FeeTokenWithdrawn"].ID: + return _OnRamp.ParseFeeTokenWithdrawn(log) + case _OnRamp.abi.Events["OwnershipTransferRequested"].ID: + return _OnRamp.ParseOwnershipTransferRequested(log) + case _OnRamp.abi.Events["OwnershipTransferred"].ID: + return _OnRamp.ParseOwnershipTransferred(log) default: return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) } } -func (EVM2EVMMultiOnRampCCIPSendRequested) Topic() common.Hash { +func (OnRampCCIPSendRequested) Topic() common.Hash { return common.HexToHash("0x0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab29") } -func (EVM2EVMMultiOnRampConfigSet) Topic() common.Hash { +func (OnRampConfigSet) Topic() common.Hash { return common.HexToHash("0x2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558") } -func (EVM2EVMMultiOnRampDestChainConfigSet) Topic() common.Hash { +func (OnRampDestChainConfigSet) Topic() common.Hash { return common.HexToHash("0x324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6") } -func (EVM2EVMMultiOnRampFeePaid) Topic() common.Hash { +func (OnRampFeePaid) Topic() common.Hash { return common.HexToHash("0x075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f") } -func (EVM2EVMMultiOnRampFeeTokenWithdrawn) Topic() common.Hash { +func (OnRampFeeTokenWithdrawn) Topic() common.Hash { return common.HexToHash("0x508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e") } -func (EVM2EVMMultiOnRampOwnershipTransferRequested) Topic() common.Hash { +func (OnRampOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } -func (EVM2EVMMultiOnRampOwnershipTransferred) Topic() common.Hash { +func (OnRampOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (_EVM2EVMMultiOnRamp *EVM2EVMMultiOnRamp) Address() common.Address { - return _EVM2EVMMultiOnRamp.address +func (_OnRamp *OnRamp) Address() common.Address { + return _OnRamp.address } -type EVM2EVMMultiOnRampInterface interface { - GetDynamicConfig(opts *bind.CallOpts) (EVM2EVMMultiOnRampDynamicConfig, error) +type OnRampInterface interface { + GetDynamicConfig(opts *bind.CallOpts) (OnRampDynamicConfig, error) GetExpectedNextSequenceNumber(opts *bind.CallOpts, destChainSelector uint64) (uint64, error) @@ -1479,7 +1479,7 @@ type EVM2EVMMultiOnRampInterface interface { GetRouter(opts *bind.CallOpts, destChainSelector uint64) (common.Address, error) - GetStaticConfig(opts *bind.CallOpts) (EVM2EVMMultiOnRampStaticConfig, error) + GetStaticConfig(opts *bind.CallOpts) (OnRampStaticConfig, error) GetSupportedTokens(opts *bind.CallOpts, arg0 uint64) ([]common.Address, error) @@ -1489,57 +1489,57 @@ type EVM2EVMMultiOnRampInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []EVM2EVMMultiOnRampDestChainConfigArgs) (*types.Transaction, error) + ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []OnRampDestChainConfigArgs) (*types.Transaction, error) ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) - SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig EVM2EVMMultiOnRampDynamicConfig) (*types.Transaction, error) + SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig OnRampDynamicConfig) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) WithdrawFeeTokens(opts *bind.TransactOpts) (*types.Transaction, error) - FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*EVM2EVMMultiOnRampCCIPSendRequestedIterator, error) + FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampCCIPSendRequestedIterator, error) - WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) + WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *OnRampCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) - ParseCCIPSendRequested(log types.Log) (*EVM2EVMMultiOnRampCCIPSendRequested, error) + ParseCCIPSendRequested(log types.Log) (*OnRampCCIPSendRequested, error) - FilterConfigSet(opts *bind.FilterOpts) (*EVM2EVMMultiOnRampConfigSetIterator, error) + FilterConfigSet(opts *bind.FilterOpts) (*OnRampConfigSetIterator, error) - WatchConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampConfigSet) (event.Subscription, error) + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *OnRampConfigSet) (event.Subscription, error) - ParseConfigSet(log types.Log) (*EVM2EVMMultiOnRampConfigSet, error) + ParseConfigSet(log types.Log) (*OnRampConfigSet, error) - FilterDestChainConfigSet(opts *bind.FilterOpts, destChainSelector []uint64) (*EVM2EVMMultiOnRampDestChainConfigSetIterator, error) + FilterDestChainConfigSet(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampDestChainConfigSetIterator, error) - WatchDestChainConfigSet(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampDestChainConfigSet, destChainSelector []uint64) (event.Subscription, error) + WatchDestChainConfigSet(opts *bind.WatchOpts, sink chan<- *OnRampDestChainConfigSet, destChainSelector []uint64) (event.Subscription, error) - ParseDestChainConfigSet(log types.Log) (*EVM2EVMMultiOnRampDestChainConfigSet, error) + ParseDestChainConfigSet(log types.Log) (*OnRampDestChainConfigSet, error) - FilterFeePaid(opts *bind.FilterOpts, feeToken []common.Address) (*EVM2EVMMultiOnRampFeePaidIterator, error) + FilterFeePaid(opts *bind.FilterOpts, feeToken []common.Address) (*OnRampFeePaidIterator, error) - WatchFeePaid(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampFeePaid, feeToken []common.Address) (event.Subscription, error) + WatchFeePaid(opts *bind.WatchOpts, sink chan<- *OnRampFeePaid, feeToken []common.Address) (event.Subscription, error) - ParseFeePaid(log types.Log) (*EVM2EVMMultiOnRampFeePaid, error) + ParseFeePaid(log types.Log) (*OnRampFeePaid, error) - FilterFeeTokenWithdrawn(opts *bind.FilterOpts, feeAggregator []common.Address, feeToken []common.Address) (*EVM2EVMMultiOnRampFeeTokenWithdrawnIterator, error) + FilterFeeTokenWithdrawn(opts *bind.FilterOpts, feeAggregator []common.Address, feeToken []common.Address) (*OnRampFeeTokenWithdrawnIterator, error) - WatchFeeTokenWithdrawn(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampFeeTokenWithdrawn, feeAggregator []common.Address, feeToken []common.Address) (event.Subscription, error) + WatchFeeTokenWithdrawn(opts *bind.WatchOpts, sink chan<- *OnRampFeeTokenWithdrawn, feeAggregator []common.Address, feeToken []common.Address) (event.Subscription, error) - ParseFeeTokenWithdrawn(log types.Log) (*EVM2EVMMultiOnRampFeeTokenWithdrawn, error) + ParseFeeTokenWithdrawn(log types.Log) (*OnRampFeeTokenWithdrawn, error) - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOnRampOwnershipTransferRequestedIterator, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OnRampOwnershipTransferRequestedIterator, error) - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *OnRampOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - ParseOwnershipTransferRequested(log types.Log) (*EVM2EVMMultiOnRampOwnershipTransferRequested, error) + ParseOwnershipTransferRequested(log types.Log) (*OnRampOwnershipTransferRequested, error) - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*EVM2EVMMultiOnRampOwnershipTransferredIterator, error) + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OnRampOwnershipTransferredIterator, error) - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *EVM2EVMMultiOnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OnRampOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - ParseOwnershipTransferred(log types.Log) (*EVM2EVMMultiOnRampOwnershipTransferred, error) + ParseOwnershipTransferred(log types.Log) (*OnRampOwnershipTransferred, error) ParseLog(log types.Log) (generated.AbigenLog, error) diff --git a/core/gethwrappers/ccip/generated/report_codec/report_codec.go b/core/gethwrappers/ccip/generated/report_codec/report_codec.go index 1648ea9ba5..7afd3d9bba 100644 --- a/core/gethwrappers/ccip/generated/report_codec/report_codec.go +++ b/core/gethwrappers/ccip/generated/report_codec/report_codec.go @@ -30,22 +30,6 @@ var ( _ = abi.ConvertType ) -type EVM2EVMMultiOffRampCommitReport struct { - PriceUpdates InternalPriceUpdates - MerkleRoots []EVM2EVMMultiOffRampMerkleRoot -} - -type EVM2EVMMultiOffRampInterval struct { - Min uint64 - Max uint64 -} - -type EVM2EVMMultiOffRampMerkleRoot struct { - SourceChainSelector uint64 - Interval EVM2EVMMultiOffRampInterval - MerkleRoot [32]byte -} - type InternalAny2EVMRampMessage struct { Header InternalRampMessageHeader Sender []byte @@ -93,8 +77,24 @@ type InternalTokenPriceUpdate struct { UsdPerToken *big.Int } +type OffRampCommitReport struct { + PriceUpdates InternalPriceUpdates + MerkleRoots []OffRampMerkleRoot +} + +type OffRampInterval struct { + Min uint64 + Max uint64 +} + +type OffRampMerkleRoot struct { + SourceChainSelector uint64 + Interval OffRampInterval + MerkleRoot [32]byte +} + var ReportCodecMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportDecoded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"report\",\"type\":\"tuple[]\"}],\"name\":\"ExecuteReportDecoded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeCommitReport\",\"outputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structEVM2EVMMultiOffRamp.CommitReport\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeExecuteReport\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportDecoded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"report\",\"type\":\"tuple[]\"}],\"name\":\"ExecuteReportDecoded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeCommitReport\",\"outputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeExecuteReport\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", Bin: "0x608060405234801561001057600080fd5b5061124f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636fb349561461003b578063f816ec6014610064575b600080fd5b61004e61004936600461024f565b610084565b60405161005b91906104f5565b60405180910390f35b61007761007236600461024f565b6100a0565b60405161005b91906107ae565b60608180602001905181019061009a9190610dc3565b92915050565b604080516080810182526060918101828152828201839052815260208101919091528180602001905181019061009a91906110d9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715610128576101286100d6565b60405290565b6040516080810167ffffffffffffffff81118282101715610128576101286100d6565b60405160c0810167ffffffffffffffff81118282101715610128576101286100d6565b6040805190810167ffffffffffffffff81118282101715610128576101286100d6565b6040516060810167ffffffffffffffff81118282101715610128576101286100d6565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610201576102016100d6565b604052919050565b600067ffffffffffffffff821115610223576102236100d6565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006020828403121561026157600080fd5b813567ffffffffffffffff81111561027857600080fd5b8201601f8101841361028957600080fd5b803561029c61029782610209565b6101ba565b8181528560208385010111156102b157600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b838110156102ea5781810151838201526020016102d2565b50506000910152565b6000815180845261030b8160208601602086016102cf565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b848110156103f2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086840301895281516080815181865261039e828701826102f3565b91505085820151858203878701526103b682826102f3565b915050604080830151868303828801526103d083826102f3565b606094850151979094019690965250509884019892509083019060010161035a565b5090979650505050505050565b6000828251808552602080860195506005818360051b8501018287016000805b868110156104aa577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe088850381018c5283518051808752908801908887019080891b88018a01865b8281101561049357858a83030184526104818286516102f3565b948c0194938c01939150600101610467565b509e8a019e9750505093870193505060010161041f565b50919998505050505050505050565b60008151808452602080850194506020840160005b838110156104ea578151875295820195908201906001016104ce565b509495945050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156106dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452815160a0860167ffffffffffffffff8083511688528883015160a08a8a015282815180855260c08b01915060c08160051b8c010194508b8301925060005b81811015610686577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408c87030183528351805180518852868f820151168f890152866040820151166040890152866060820151166060890152866080820151166080890152508d81015161014060a08901526106096101408901826102f3565b9050604082015188820360c08a015261062282826102f3565b915050606082015161064c60e08a018273ffffffffffffffffffffffffffffffffffffffff169052565b50608082015161010089015260a08201519150878103610120890152610672818361033d565b97505050928c0192918c0191600101610589565b5050505050604082015187820360408901526106a282826103ff565b915050606082015187820360608901526106bc82826104b9565b6080938401519890930197909752509450928501929085019060010161051c565b5092979650505050505050565b60008151808452602080850194506020840160005b838110156104ea578151805167ffffffffffffffff1688528301517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683880152604090960195908201906001016106ff565b600081518084526020808501945080840160005b838110156104ea578151805167ffffffffffffffff90811689528482015180518216868b0152850151166040808a01919091520151606088015260809096019590820190600101610762565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b8083101561083e578351805173ffffffffffffffffffffffffffffffffffffffff1683528701517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16878301529286019260019290920191908401906107e1565b50938501518785037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa00160808901529361087881866106ea565b9450505050508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08482030160408501526108b8818361074e565b95945050505050565b600067ffffffffffffffff8211156108db576108db6100d6565b5060051b60200190565b805167ffffffffffffffff811681146108fd57600080fd5b919050565b600060a0828403121561091457600080fd5b61091c610105565b90508151815261092e602083016108e5565b602082015261093f604083016108e5565b6040820152610950606083016108e5565b6060820152610961608083016108e5565b608082015292915050565b600082601f83011261097d57600080fd5b815161098b61029782610209565b8181528460208386010111156109a057600080fd5b6109b18260208301602087016102cf565b949350505050565b805173ffffffffffffffffffffffffffffffffffffffff811681146108fd57600080fd5b600082601f8301126109ee57600080fd5b815160206109fe610297836108c1565b82815260059290921b84018101918181019086841115610a1d57600080fd5b8286015b84811015610b1157805167ffffffffffffffff80821115610a425760008081fd5b81890191506080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610a7b5760008081fd5b610a8361012e565b8784015183811115610a955760008081fd5b610aa38d8a8388010161096c565b82525060408085015184811115610aba5760008081fd5b610ac88e8b8389010161096c565b8a8401525060608086015185811115610ae15760008081fd5b610aef8f8c838a010161096c565b9284019290925294909201519381019390935250508352918301918301610a21565b509695505050505050565b600082601f830112610b2d57600080fd5b81516020610b3d610297836108c1565b82815260059290921b84018101918181019086841115610b5c57600080fd5b8286015b84811015610b1157805167ffffffffffffffff80821115610b815760008081fd5b8189019150610140807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610bbb5760008081fd5b610bc3610151565b610bcf8c898601610902565b815260c084015183811115610be45760008081fd5b610bf28d8a8388010161096c565b898301525060e084015183811115610c0a5760008081fd5b610c188d8a8388010161096c565b604083015250610c2b61010085016109b9565b60608201526101208401516080820152908301519082821115610c4e5760008081fd5b610c5c8c89848701016109dd565b60a08201528652505050918301918301610b60565b600082601f830112610c8257600080fd5b81516020610c92610297836108c1565b82815260059290921b84018101918181019086841115610cb157600080fd5b8286015b84811015610b1157805167ffffffffffffffff80821115610cd557600080fd5b818901915089603f830112610ce957600080fd5b85820151610cf9610297826108c1565b81815260059190911b830160400190878101908c831115610d1957600080fd5b604085015b83811015610d5257805185811115610d3557600080fd5b610d448f6040838a010161096c565b845250918901918901610d1e565b50875250505092840192508301610cb5565b600082601f830112610d7557600080fd5b81516020610d85610297836108c1565b8083825260208201915060208460051b870101935086841115610da757600080fd5b602086015b84811015610b115780518352918301918301610dac565b60006020808385031215610dd657600080fd5b825167ffffffffffffffff80821115610dee57600080fd5b818501915085601f830112610e0257600080fd5b8151610e10610297826108c1565b81815260059190911b83018401908481019088831115610e2f57600080fd5b8585015b83811015610f2957805185811115610e4a57600080fd5b860160a0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215610e7f5760008081fd5b610e87610105565b610e928983016108e5565b815260408083015188811115610ea85760008081fd5b610eb68e8c83870101610b1c565b8b8401525060608084015189811115610ecf5760008081fd5b610edd8f8d83880101610c71565b8385015250608091508184015189811115610ef85760008081fd5b610f068f8d83880101610d64565b918401919091525060a09290920151918101919091528352918601918601610e33565b5098975050505050505050565b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146108fd57600080fd5b600082601f830112610f7357600080fd5b81516020610f83610297836108c1565b82815260069290921b84018101918181019086841115610fa257600080fd5b8286015b84811015610b115760408189031215610fbf5760008081fd5b610fc7610174565b610fd0826108e5565b8152610fdd858301610f36565b81860152835291830191604001610fa6565b600082601f83011261100057600080fd5b81516020611010610297836108c1565b82815260079290921b8401810191818101908684111561102f57600080fd5b8286015b84811015610b1157808803608081121561104d5760008081fd5b611055610197565b61105e836108e5565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156110925760008081fd5b61109a610174565b92506110a78785016108e5565b83526110b48185016108e5565b8388015281870192909252606083015191810191909152835291830191608001611033565b600060208083850312156110ec57600080fd5b825167ffffffffffffffff8082111561110457600080fd5b8185019150604080838803121561111a57600080fd5b611122610174565b83518381111561113157600080fd5b84016040818a03121561114357600080fd5b61114b610174565b81518581111561115a57600080fd5b8201601f81018b1361116b57600080fd5b8051611179610297826108c1565b81815260069190911b8201890190898101908d83111561119857600080fd5b928a01925b828410156111e65787848f0312156111b55760008081fd5b6111bd610174565b6111c6856109b9565b81526111d38c8601610f36565b818d0152825292870192908a019061119d565b8452505050818701519350848411156111fe57600080fd5b61120a8a858401610f62565b818801528252508385015191508282111561122457600080fd5b61123088838601610fef565b8582015280955050505050509291505056fea164736f6c6343000818000a", } @@ -234,25 +234,25 @@ func (_ReportCodec *ReportCodecTransactorRaw) Transact(opts *bind.TransactOpts, return _ReportCodec.Contract.contract.Transact(opts, method, params...) } -func (_ReportCodec *ReportCodecCaller) DecodeCommitReport(opts *bind.CallOpts, report []byte) (EVM2EVMMultiOffRampCommitReport, error) { +func (_ReportCodec *ReportCodecCaller) DecodeCommitReport(opts *bind.CallOpts, report []byte) (OffRampCommitReport, error) { var out []interface{} err := _ReportCodec.contract.Call(opts, &out, "decodeCommitReport", report) if err != nil { - return *new(EVM2EVMMultiOffRampCommitReport), err + return *new(OffRampCommitReport), err } - out0 := *abi.ConvertType(out[0], new(EVM2EVMMultiOffRampCommitReport)).(*EVM2EVMMultiOffRampCommitReport) + out0 := *abi.ConvertType(out[0], new(OffRampCommitReport)).(*OffRampCommitReport) return out0, err } -func (_ReportCodec *ReportCodecSession) DecodeCommitReport(report []byte) (EVM2EVMMultiOffRampCommitReport, error) { +func (_ReportCodec *ReportCodecSession) DecodeCommitReport(report []byte) (OffRampCommitReport, error) { return _ReportCodec.Contract.DecodeCommitReport(&_ReportCodec.CallOpts, report) } -func (_ReportCodec *ReportCodecCallerSession) DecodeCommitReport(report []byte) (EVM2EVMMultiOffRampCommitReport, error) { +func (_ReportCodec *ReportCodecCallerSession) DecodeCommitReport(report []byte) (OffRampCommitReport, error) { return _ReportCodec.Contract.DecodeCommitReport(&_ReportCodec.CallOpts, report) } @@ -339,7 +339,7 @@ func (it *ReportCodecCommitReportDecodedIterator) Close() error { } type ReportCodecCommitReportDecoded struct { - Report EVM2EVMMultiOffRampCommitReport + Report OffRampCommitReport Raw types.Log } @@ -537,7 +537,7 @@ func (_ReportCodec *ReportCodec) Address() common.Address { } type ReportCodecInterface interface { - DecodeCommitReport(opts *bind.CallOpts, report []byte) (EVM2EVMMultiOffRampCommitReport, error) + DecodeCommitReport(opts *bind.CallOpts, report []byte) (OffRampCommitReport, error) DecodeExecuteReport(opts *bind.CallOpts, report []byte) ([]InternalExecutionReportSingleChain, error) diff --git a/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go b/core/gethwrappers/ccip/generated/rmn_contract/rmn_contract.go similarity index 75% rename from core/gethwrappers/ccip/generated/arm_contract/arm_contract.go rename to core/gethwrappers/ccip/generated/rmn_contract/rmn_contract.go index 6e225576c1..e314f0243a 100644 --- a/core/gethwrappers/ccip/generated/arm_contract/arm_contract.go +++ b/core/gethwrappers/ccip/generated/rmn_contract/rmn_contract.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package arm_contract +package rmn_contract import ( "errors" @@ -68,17 +68,17 @@ type RMNVoter struct { CurseWeight uint8 } -var ARMContractMetaData = &bind.MetaData{ +var RMNContractMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"}],\"name\":\"ReusedCurseId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubjectsMustBeStrictlyIncreasing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"}],\"name\":\"UnauthorizedVoter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnvoteToCurseNoop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VoteToBlessForbiddenDuringActiveGlobalCurse\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VoteToBlessNoop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VoteToCurseNoop\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"AlreadyBlessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"AlreadyVotedToBless\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"CurseLifted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"blockTimestamp\",\"type\":\"uint64\"}],\"name\":\"Cursed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"}],\"name\":\"PermaBlessedCommitStoreAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"}],\"name\":\"PermaBlessedCommitStoreRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"onchainCursesHash\",\"type\":\"bytes28\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"}],\"name\":\"SkippedUnvoteToCurse\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"wasBlessed\",\"type\":\"bool\"}],\"name\":\"TaggedRootBlessVotesReset\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"}],\"name\":\"TaggedRootBlessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"weight\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"remainingAccumulatedWeight\",\"type\":\"uint16\"}],\"name\":\"UnvotedToCurse\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"weight\",\"type\":\"uint8\"}],\"name\":\"VotedToBless\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"weight\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"blockTimestamp\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"}],\"name\":\"VotedToCurse\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"getBlessProgress\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"blessVoteAddrs\",\"type\":\"address[]\"},{\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"blessed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"getCurseProgress\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"curseVoteAddrs\",\"type\":\"address[]\"},{\"internalType\":\"bytes28[]\",\"name\":\"cursesHashes\",\"type\":\"bytes28[]\"},{\"internalType\":\"uint16\",\"name\":\"accumulatedWeight\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"cursed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCursedSubjectsCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPermaBlessedCommitStores\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"getRecordedCurseRelatedOps\",\"outputs\":[{\"components\":[{\"internalType\":\"enumRMN.RecordedCurseRelatedOpTag\",\"name\":\"tag\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"blockTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"cursed\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"}],\"internalType\":\"structRMN.RecordedCurseRelatedOp[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRecordedCurseRelatedOpsCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot\",\"name\":\"taggedRoot\",\"type\":\"tuple\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16[]\",\"name\":\"subjects\",\"type\":\"bytes16[]\"}],\"name\":\"ownerCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"ownerRemoveThenAddPermaBlessedCommitStores\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot[]\",\"name\":\"taggedRoots\",\"type\":\"tuple[]\"}],\"name\":\"ownerResetBlessVotes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"}],\"internalType\":\"structRMN.UnvoteToCurseRequest\",\"name\":\"unit\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"forceUnvote\",\"type\":\"bool\"}],\"internalType\":\"structRMN.OwnerUnvoteToCurseRequest[]\",\"name\":\"ownerUnvoteToCurseRequests\",\"type\":\"tuple[]\"}],\"name\":\"ownerUnvoteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"blessVoteAddr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curseVoteAddr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"blessWeight\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"curseWeight\",\"type\":\"uint8\"}],\"internalType\":\"structRMN.Voter[]\",\"name\":\"voters\",\"type\":\"tuple[]\"},{\"internalType\":\"uint16\",\"name\":\"blessWeightThreshold\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"curseWeightThreshold\",\"type\":\"uint16\"}],\"internalType\":\"structRMN.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"},{\"internalType\":\"bytes28\",\"name\":\"cursesHash\",\"type\":\"bytes28\"}],\"internalType\":\"structRMN.UnvoteToCurseRequest[]\",\"name\":\"unvoteToCurseRequests\",\"type\":\"tuple[]\"}],\"name\":\"unvoteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMN.TaggedRoot[]\",\"name\":\"taggedRoots\",\"type\":\"tuple[]\"}],\"name\":\"voteToBless\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"curseId\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16[]\",\"name\":\"subjects\",\"type\":\"bytes16[]\"}],\"name\":\"voteToCurse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Bin: "0x60806040523480156200001157600080fd5b506040516200596238038062005962833981016040819052620000349162000aff565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000138565b505060408051608081018252600080825260208201819052918101919091526001600160c81b03606082015290506001620000fb81601062000c7d565b82606001516001600160c81b0316901c6001600160c81b0316101562000125576200012562000c99565b506200013181620001e3565b5062000e14565b336001600160a01b03821603620001925760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001ee816200071d565b6200020c576040516306b7c75960e31b815260040160405180910390fd5b602081015160038054604084015161ffff908116620100000263ffffffff199092169316929092179190911790555b60025415620003465760028054600091906200025a9060019062000c7d565b815481106200026d576200026d62000caf565b6000918252602080832060408051608081018252600294850290920180546001600160a01b0390811680855260019092015480821685870190815260ff600160a01b8304811687870152600160a81b909204909116606086015291875260058552828720805465ffffffffffff19169055905116855260099092529220805461ffff191690558054919250908062000309576200030962000cc5565b60008281526020902060026000199092019182020180546001600160a01b031916815560010180546001600160b01b03191690559055506200023b565b60005b81515181101562000403578151805160029190839081106200036f576200036f62000caf565b602090810291909101810151825460018181018555600094855293839020825160029092020180546001600160a01b039283166001600160a01b0319909116178155928201519284018054604084015160609094015160ff908116600160a81b0260ff60a81b1991909516600160a01b026001600160a81b0319909216959093169490941793909317161790550162000349565b50600480546000906200041c9063ffffffff1662000cdb565b82546101009290920a63ffffffff8181021990931691831602179091556004541660005b82515160ff821610156200054157600083600001518260ff16815181106200046c576200046c62000caf565b602090810291909101810151604080516060808201835263ffffffff80891683528385015160ff90811684880190815289821685870190815287516001600160a01b03908116600090815260058b5288812097518854945193518616650100000000000260ff60281b199487166401000000000264ffffffffff1990961691909716179390931791909116939093179094558587015190911683526009909552919020805491909201519092166101000261ffff1990921691909117600117905550620005398162000d01565b905062000440565b506001600160a01b0360005260096020527f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a7805461ffff191660011790556004805463ffffffff4381166401000000000263ffffffff60201b1990921691909117909155604051908216907f8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a990620005db90859062000d23565b60405180910390a26040805160c08101825260048082526001600160401b03421660208301526000928201839052606082018390526080820183905260a08201839052600c80546001808201835591909452825160029094027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018054939490939092849260ff19909216919084908111156200067c576200067c62000dce565b021790555060208201518154604084015160608501516001600160a01b03166a010000000000000000000002600160501b600160f01b031991151569010000000000000000000260ff60481b196001600160401b039095166101000294909416610100600160501b031990931692909217929092179190911617815560808083015160a090930151811c600160801b0292901c919091176001909101555050565b80515160009015806200073257508151516010105b80620007445750602082015161ffff16155b80620007565750604082015161ffff16155b156200076457506000919050565b600080600084600001515160026200077d919062000de4565b6001600160401b0381111562000797576200079762000a24565b604051908082528060200260200182016040528015620007c1578160200160208202803683370190505b50905060005b8551518110156200095457600086600001518281518110620007ed57620007ed62000caf565b6020026020010151905060006001600160a01b031681600001516001600160a01b0316148062000828575060208101516001600160a01b0316155b806200083f575060208101516001600160a01b0316155b8062000858575060208101516001600160a01b03908116145b806200087a5750604081015160ff161580156200087a5750606081015160ff16155b156200088d575060009695505050505050565b8051836200089d84600262000de4565b620008aa90600062000dfe565b81518110620008bd57620008bd62000caf565b6001600160a01b0390921660209283029190910182015281015183620008e584600262000de4565b620008f290600162000dfe565b8151811062000905576200090562000caf565b6001600160a01b03909216602092830291909101909101526040810151620009319060ff168662000dfe565b9450806060015160ff168462000948919062000dfe565b935050600101620007c7565b5060005b8151811015620009f957600082828151811062000979576200097962000caf565b60200260200101519050600082600162000994919062000dfe565b90505b8351811015620009ee57838181518110620009b657620009b662000caf565b60200260200101516001600160a01b0316826001600160a01b031603620009e557506000979650505050505050565b60010162000997565b505060010162000958565b50846020015161ffff16831015801562000a1b5750846040015161ffff168210155b95945050505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b038111828210171562000a5f5762000a5f62000a24565b60405290565b604051608081016001600160401b038111828210171562000a5f5762000a5f62000a24565b604051601f8201601f191681016001600160401b038111828210171562000ab55762000ab562000a24565b604052919050565b80516001600160a01b038116811462000ad557600080fd5b919050565b805160ff8116811462000ad557600080fd5b805161ffff8116811462000ad557600080fd5b6000602080838503121562000b1357600080fd5b82516001600160401b038082111562000b2b57600080fd5b8185019150606080838803121562000b4257600080fd5b62000b4c62000a3a565b83518381111562000b5c57600080fd5b8401601f8101891362000b6e57600080fd5b80518481111562000b835762000b8362000a24565b62000b93878260051b0162000a8a565b818152878101955060079190911b82018701908a82111562000bb457600080fd5b918701915b8183101562000c33576080838c03121562000bd45760008081fd5b62000bde62000a65565b62000be98462000abd565b815262000bf889850162000abd565b89820152604062000c0b81860162000ada565b9082015262000c1c84870162000ada565b818701528652948701946080929092019162000bb9565b83525062000c45905084860162000aec565b8582015262000c576040850162000aec565b6040820152979650505050505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000c935762000c9362000c67565b92915050565b634e487b7160e01b600052600160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600063ffffffff80831681810362000cf75762000cf762000c67565b6001019392505050565b600060ff821660ff810362000d1a5762000d1a62000c67565b60010192915050565b60006020808352608080840185516060808588015282825180855260a0890191508684019450600093505b8084101562000da157845180516001600160a01b03908116845288820151168884015260408082015160ff9081169185019190915290840151168383015293860193600193909301929085019062000d4e565b509488015161ffff8116604089015294604089015161ffff811660608a0152955098975050505050505050565b634e487b7160e01b600052602160045260246000fd5b808202811582820484141762000c935762000c9362000c67565b8082018082111562000c935762000c9362000c67565b614b3e8062000e246000396000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063631ec73e116100d8578063979986111161008c578063d927f26711610066578063d927f26714610354578063f2fde38b14610374578063f33f28951461038757600080fd5b8063979986111461030b578063ba86a1f01461031e578063bd147ef41461033157600080fd5b806379ba5097116100bd57806379ba5097146102d35780638da5cb5b146102db578063970b8fc21461030357600080fd5b8063631ec73e146102ad5780636ba0526d146102c057600080fd5b8063397796f71161013a5780634102e4f4116101145780634102e4f4146102745780634d61677114610287578063586abe3c1461029a57600080fd5b8063397796f7146102425780633d0cf6101461024a5780633f42ab731461025d57600080fd5b8063181f5a771161016b578063181f5a77146101ba5780632cbc26bb14610203578063328d716c1461022657600080fd5b80630b009be21461018757806315c65588146101a5575b600080fd5b61018f6103a9565b60405161019c9190613e3f565b60405180910390f35b6101b86101b3366004613fdd565b6103ba565b005b6101f66040518060400160405280600981526020017f524d4e20312e352e30000000000000000000000000000000000000000000000081525081565b60405161019c9190614083565b6102166102113660046140f0565b6104e6565b604051901515815260200161019c565b600b5467ffffffffffffffff165b60405190815260200161019c565b6102166105b1565b6101b86102583660046141a0565b61068b565b6102656107ff565b60405161019c939291906142b3565b6101b86102823660046142ff565b610929565b610216610295366004614439565b61093d565b6101b86102a8366004614451565b6109cd565b6101b86102bb3660046144fc565b610a87565b6101b86102ce366004614451565b610ca0565b6101b8610d13565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019c565b600c54610234565b6101b86103193660046145d0565b610e10565b6101b861032c3660046145d0565b611368565b61034461033f3660046140f0565b61150d565b60405161019c9493929190614645565b6103676103623660046146b6565b611946565b60405161019c9190614707565b6101b8610382366004614800565b611b68565b61039a610395366004614439565b611b79565b60405161019c9392919061481b565b60606103b56007611de1565b905090565b336000818152600960205260409020805460ff16610421576040517f85412e7f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b60045463ffffffff166000805b85518110156104a757600086828151811061044b5761044b614849565b602002602001015190506000610465858360000151611df5565b905060008061047b6001888b8760008d89611fd6565b91509150801561048d5761048d614878565b85806104965750815b95505050505080600101905061042e565b50806104df576040517ffb106b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b600b5460009067ffffffffffffffff16810361050457506000919050565b7f0100000000000000000000000000000100000000000000000000000000000000600052600a6020527fcf943f0e419056430919a3fdfd72276bc0b123ebdd670f4152b82bffbfb8bb385468010000000000000000900460ff16806105a657507fffffffffffffffffffffffffffffffff0000000000000000000000000000000082166000908152600a602052604090205468010000000000000000900460ff165b92915050565b919050565b600b5460009067ffffffffffffffff1681036105cd5750600090565b7f0100000000000000000000000000000100000000000000000000000000000000600052600a6020527fcf943f0e419056430919a3fdfd72276bc0b123ebdd670f4152b82bffbfb8bb385468010000000000000000900460ff16806103b55750507f0100000000000000000000000000000000000000000000000000000000000000600052600a6020527f1d4cd6d2639449a552dbfb463b59316946d78c518b3170daa4a4c217bef019ba5468010000000000000000900460ff1690565b6106936126a4565b60005b8251811015610746576106cc8382815181106106b4576106b4614849565b6020026020010151600761272790919063ffffffff16565b1561073e577fdca892154bbc36d0c05ccd01b3d0411875cb1b841fcdeebb384e5d0d6eb06b4483828151811061070457610704614849565b6020026020010151604051610735919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a15b600101610696565b5060005b81518110156107fa5761078082828151811061076857610768614849565b6020026020010151600761274990919063ffffffff16565b156107f2577f66b4b4752c65ae8cd2f3a0a48c7dc8b2118c60d5ea15514992eb2ddf56c9cb158282815181106107b8576107b8614849565b60200260200101516040516107e9919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a15b60010161074a565b505050565b6040805160608082018352808252600060208084018290528385018290526004548551600280549384028201608090810190985294810183815263ffffffff808416986401000000009094041696959194919385939192859285015b828210156108f95760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff740100000000000000000000000000000000000000008204811693850193909352750100000000000000000000000000000000000000000090049091166060830152908352909201910161085b565b505050908252506001919091015461ffff8082166020840152620100009091041660409091015292939192919050565b6109316126a4565b61093a8161276b565b50565b600060068161099b610954368690038601866148a7565b80516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b815260208101919091526040016000205460ff16806105a657506105a66109c56020840184614800565b600790612eef565b337fffffffffffffffffffffffff000000000000000000000000000000000000000181016109fd576109fd614878565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600960205260409020805460ff16610a75576040517f85412e7f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610418565b610a8182858584612f1e565b50505050565b610a8f6126a4565b600454600090819063ffffffff16815b8451811015610b66576000858281518110610abc57610abc614849565b602002602001015190506000610ada84836020015160000151611df5565b9050600080610b3d600087866000015187602001518860400151600960008b6000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002089611fd6565b915091508680610b4a5750815b96508780610b555750805b975050505050806001019050610a9f565b508215610c615760408051600280546080602082028401810190945260608301818152610c61948492849160009085015b82821015610c355760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff7401000000000000000000000000000000000000000082048116938501939093527501000000000000000000000000000000000000000000900490911660608301529083529092019101610b97565b505050908252506001919091015461ffff8082166020840152620100009091041660409091015261276b565b8180610c6a5750825b610a81576040517ffb106b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca86126a4565b73ffffffffffffffffffffffffffffffffffffffff60005260096020527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a7610a8182858584612f1e565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610418565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e397f01000000000000000000000000000001000000000000000000000000000000006104e6565b15610e70576040517fcde2d97c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454336000908152600560209081526040918290208251606081018452905463ffffffff81811680845260ff64010000000084048116958501959095526501000000000090920490931693820193909352921691908214610f00576040517f85412e7f000000000000000000000000000000000000000000000000000000008152336004820152602401610418565b600160005b8481101561132f576000868683818110610f2157610f21614849565b905060400201803603810190610f3791906148a7565b90506000610f868280516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b6000818152600660209081526040918290208251608081018452905460ff81161580158352610100820463ffffffff169383019390935265010000000000810461ffff169382019390935267010000000000000090920478ffffffffffffffffffffffffffffffffffffffffffffffffff16606083015291925090611062573373ffffffffffffffffffffffffffffffffffffffff168763ffffffff167f274d6d5b916b0a53974b7ab86c844b97a2e03a60f658cd9a4b1c028b604d7bf18560405161105291906148e0565b60405180910390a3505050611327565b8663ffffffff16816020015163ffffffff16146110a8575060408051608081018252600080825263ffffffff89166020830152918101829052606081019190915261110c565b6110ba816060015187604001516136d6565b1561110c573373ffffffffffffffffffffffffffffffffffffffff168763ffffffff167f6dfbb745226fa630aeb1b9557d17d508ddb789a04f0cb873ec16e58beb8beead8560405161105291906148e0565b6000945061112281606001518760400151613718565b78ffffffffffffffffffffffffffffffffffffffffffffffffff166060820152602086015160408201805160ff9092169161115e90839061493c565b61ffff1690525060208681015160408051865173ffffffffffffffffffffffffffffffffffffffff168152868401519381019390935260ff9091168282015251339163ffffffff8a16917f2a08a2bd2798f0aae9a843f0f4ad4de488c1b3d5f04049940cfed736ad69fb979181900360600190a3600354604082015161ffff91821691161061125757600181526040808201518151855173ffffffffffffffffffffffffffffffffffffffff1681526020808701519082015261ffff90911681830152905163ffffffff8916917f8257378aa73bf8e4ada848713526584a3dcee0fd3db3beed7397f7a7f5067cc9919081900360600190a25b60009182526006602090815260409283902082518154928401519484015160609094015178ffffffffffffffffffffffffffffffffffffffffffffffffff166701000000000000000266ffffffffffffff61ffff90951665010000000000029490941664ffffffffff63ffffffff909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090941693909317179390931617179055505b600101610f05565b5080156104df576040517f604c767700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113706126a4565b60045463ffffffff1660005b82811015610a8157600084848381811061139857611398614849565b9050604002018036038101906113ae91906148a7565b905060006113fd8280516020918201516040805173ffffffffffffffffffffffffffffffffffffffff909316838501528281019190915280518083038201815260609092019052805191012090565b60008181526006602081815260408084208151608081018352815460ff811615158252610100810463ffffffff90811683870190815265010000000000830461ffff169584019590955267010000000000000090910478ffffffffffffffffffffffffffffffffffffffffffffffffff16606083015287875294909352939093558051925193945092878216911614806114945750805b156114fe5760408051855173ffffffffffffffffffffffffffffffffffffffff1681526020808701519082015282151581830152905163ffffffff8816917f7d15a6eebaa019ea7d5b7d38937c51ebd3befbfdf51bb630a694fd28635bbcba919081900360600190a25b5050505080600101905061137c565b600454604080516002805460806020820284018101909452606083810182815290958695600095869563ffffffff9093169486949193928492918491879085015b828210156115ec5760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff740100000000000000000000000000000000000000008204811693850193909352750100000000000000000000000000000000000000000090049091166060830152908352909201910161154e565b505050908252506001919091015461ffff80821660208085019190915262010000909204166040928301527fffffffffffffffffffffffffffffffff000000000000000000000000000000008a166000908152600a909152908120805460ff6801000000000000000082041696509293509163ffffffff80861691161080156116725750845b6000965090508560015b60028111611939578451515b6000808760000151518310156116e35787518051849081106116ac576116ac614849565b6020026020010151602001519150876000015183815181106116d0576116d0614849565b602002602001015160600151905061170a565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905060005b73ffffffffffffffffffffffffffffffffffffffff82166000908152600188016020908152604080832081518083019092525463ffffffff811682526401000000009004821b63ffffffff19169181019190915290878061177a57508a63ffffffff16826000015163ffffffff16145b8061179a575073ffffffffffffffffffffffffffffffffffffffff848116145b80156117b05750602082015163ffffffff191615155b9050801561186d57856001036117d0576117c987614957565b965061186d565b85600203610182576117e560ff84168e61493c565b9c506117f08761498f565b9650838f888151811061180557611805614849565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505081602001518e888151811061185657611856614849565b63ffffffff19909216602092830291909101909101525b84156118835761187c8561498f565b945061188c565b50505050611895565b50505050611688565b81600103611928578267ffffffffffffffff8111156118b6576118b6613e52565b6040519080825280602002602001820160405280156118df578160200160208202803683370190505b509a508267ffffffffffffffff8111156118fb576118fb613e52565b604051908082528060200260200182016040528015611924578160200160208202803683370190505b5099505b5061193281614957565b905061167c565b5050505050509193509193565b600c5460609060009061195984866149c4565b11611965575081611988565b600c5484101561198457600c5461197d9085906149d7565b9050611988565b5060005b60008167ffffffffffffffff8111156119a3576119a3613e52565b604051908082528060200260200182016040528015611a2157816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816119c15790505b50905060005b82811015611b5f57600c611a3b82886149c4565b81548110611a4b57611a4b614849565b600091825260209091206040805160c081019091526002909202018054829060ff166004811115611a7e57611a7e6146d8565b6004811115611a8f57611a8f6146d8565b81528154610100810467ffffffffffffffff1660208301526901000000000000000000810460ff16151560408301526a0100000000000000000000900473ffffffffffffffffffffffffffffffffffffffff166060820152600190910154608081811b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000090811682850152700100000000000000000000000000000000909204901b1660a0909101528251839083908110611b4c57611b4c614849565b6020908102919091010152600101611a27565b50949350505050565b611b706126a4565b61093a8161373b565b606060008080611b91610954368790038701876148a7565b6000818152600660209081526040918290208251608081018452905460ff81161515808352610100820463ffffffff90811694840185905265010000000000830461ffff169584019590955267010000000000000090910478ffffffffffffffffffffffffffffffffffffffffffffffffff166060830152600454909650939450929091169003611dd85760408101516060820151909450611c3281613830565b60ff1667ffffffffffffffff811115611c4d57611c4d613e52565b604051908082528060200260200182016040528015611c76578160200160208202803683370190505b506002805460408051602080840282018101909252828152939950600093929190849084015b82821015611d3a5760008481526020908190206040805160808101825260028602909201805473ffffffffffffffffffffffffffffffffffffffff90811684526001918201549081168486015260ff7401000000000000000000000000000000000000000082048116938501939093527501000000000000000000000000000000000000000000900490911660608301529083529092019101611c9c565b5050505090506000805b82518160ff161015611dd357611d5a84826136d6565b15611dc357828160ff1681518110611d7457611d74614849565b602002602001015160000151898381518110611d9257611d92614849565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152611dc082614957565b91505b611dcc816149ea565b9050611d44565b505050505b50509193909250565b60606000611dee8361389f565b9392505050565b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166000908152600a60205260408120805463ffffffff858116911614611dee57805463ffffffff19811663ffffffff861690811783556003547fffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000909216176201000090910461ffff1664010000000002177fffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffff1680825568010000000000000000900460ff1615611dee57600260005b8154811015611fcd576000826000018281548110611ee657611ee6614849565b6000918252602080832060016002909302018281015473ffffffffffffffffffffffffffffffffffffffff1684529187019052604090912080549192509063ffffffff808a169116108015611f4d57508054640100000000900460201b63ffffffff191615155b15611fc357805463ffffffff191663ffffffff891617815560018201548554750100000000000000000000000000000000000000000090910460ff16908690600690611fa89084906601000000000000900461ffff1661493c565b92506101000a81548161ffff021916908361ffff1602179055505b5050600101611ec6565b50509392505050565b6000806001896001811115611fed57611fed6146d8565b148061200a57506000896001811115612008576120086146d8565b145b61201657612016614878565b8480612037575073ffffffffffffffffffffffffffffffffffffffff878116145b80612056575073ffffffffffffffffffffffffffffffffffffffff8716155b1561207c57600089600181111561206f5761206f6146d8565b1461207c5761207c614878565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260018401602090815260409182902082518084019093525463ffffffff811683526401000000009004811b63ffffffff191690820152845460ff16801561210d575073ffffffffffffffffffffffffffffffffffffffff888116148061210d57508863ffffffff16816000015163ffffffff16145b80156121235750602081015163ffffffff191615155b801561214b5750866020015163ffffffff1916816020015163ffffffff1916148061214b5750855b156122765773ffffffffffffffffffffffffffffffffffffffff881660009081526001858101602052604082209190915585548554919450610100900460ff169085906006906121aa9084906601000000000000900461ffff16614a09565b825461010092830a61ffff818102199092169282160291909117909255895188546020808d01518a54604080517fffffffffffffffffffffffffffffffff0000000000000000000000000000000090961686529590930460ff169184019190915263ffffffff1916828401526601000000000000900490921660608301525173ffffffffffffffffffffffffffffffffffffffff8b16925063ffffffff8c16917fa96a155bd67c927a6c056befbd979b78465e2b2f1276bf7d4e90a31d4f430aa8919081900360800190a35b6000808b600181111561228b5761228b6146d8565b1480156122b3575083806122b3575073ffffffffffffffffffffffffffffffffffffffff8916155b90508080156122cf5750845468010000000000000000900460ff165b80156122e157506122df856138fb565b155b156123b45784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555600b80546001945060009061232a9067ffffffffffffffff16614a24565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f65d0e78c3625f0956f58610cf0fb157eaf627683258875ef29af2f71d25ac8fd88600001516040516123ab91907fffffffffffffffffffffffffffffffff0000000000000000000000000000000091909116815260200190565b60405180910390a15b83806123bd5750825b15612605576000808c60018111156123d7576123d76146d8565b036123f25787156123ea5750600361240f565b50600261240f565b60018c6001811115612406576124066146d8565b03610182575060015b600c6040518060c0016040528083600481111561242e5761242e6146d8565b81526020014267ffffffffffffffff168152885468010000000000000000900460ff16151560208083019190915273ffffffffffffffffffffffffffffffffffffffff8e1660408301528c517fffffffffffffffffffffffffffffffff00000000000000000000000000000000166060830152600060809092018290528354600180820186559483529120825160029092020180549293909283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911690836004811115612500576125006146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c9190911760019091015550612696565b8751602080840151818b0151604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909516855263ffffffff1992831693850193909352169082015273ffffffffffffffffffffffffffffffffffffffff8a16907fbabb0d7099e6ca14a29fad2a2cfb4fda2bd30f97cb3c27e546174bfb4277c1cc9060600160405180910390a25b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612725576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610418565b565b6000611dee8373ffffffffffffffffffffffffffffffffffffffff841661395c565b6000611dee8373ffffffffffffffffffffffffffffffffffffffff8416613a56565b61277481613aa5565b6127aa576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015160038054604084015161ffff908116620100000263ffffffff199092169316929092179190911790555b6002541561298e5760028054600091906127f5906001906149d7565b8154811061280557612805614849565b60009182526020808320604080516080810182526002948502909201805473ffffffffffffffffffffffffffffffffffffffff90811680855260019092015480821685870190815260ff740100000000000000000000000000000000000000008304811687870152750100000000000000000000000000000000000000000090920490911660608601529187526005855282872080547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000016905590511685526009909252922080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690558054919250908061290457612904614a66565b60008281526020902060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019182020180547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560010180547fffffffffffffffffffff000000000000000000000000000000000000000000001690559055506127d9565b60005b815151811015612ac1578151805160029190839081106129b3576129b3614849565b6020908102919091018101518254600181810185556000948552938390208251600290920201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116178155928201519284018054604084015160609094015160ff9081167501000000000000000000000000000000000000000000027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff9190951674010000000000000000000000000000000000000000027fffffffffffffffffffffff0000000000000000000000000000000000000000009092169590931694909417939093171617905501612991565b5060048054600090612ad89063ffffffff16614a95565b82546101009290920a63ffffffff8181021990931691831602179091556004541660005b82515160ff82161015612c5557600083600001518260ff1681518110612b2457612b24614849565b602090810291909101810151604080516060808201835263ffffffff80891683528385015160ff908116848801908152898216858701908152875173ffffffffffffffffffffffffffffffffffffffff908116600090815260058b528881209751885494519351861665010000000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff948716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009096169190971617939093179190911693909317909455858701519091168352600990955291902080549190920151909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090921691909117600117905550612c4e816149ea565b9050612afc565b5073ffffffffffffffffffffffffffffffffffffffff60005260096020527f3bddde647ecb7992f4c710d4e1d59d07614508581f7c22c879a79d28544538a780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660011790556004805463ffffffff438116640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff90921691909117909155604051908216907f8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a990612d2f908590614ab8565b60405180910390a26040805160c081018252600480825267ffffffffffffffff421660208301526000928201839052606082018390526080820183905260a08201839052600c80546001808201835591909452825160029094027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805493949093909284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090921691908490811115612dec57612dec6146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c919091176001909101555050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611dee565b8151600003612f59576040517f55e9b08b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008316600090815260018201602052604090205460ff1615613007576040517f078f340000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201527fffffffffffffffffffffffffffffffff0000000000000000000000000000000084166024820152604401610418565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008316600090815260018281016020526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905560045463ffffffff16905b83518110156136ce57600181101580156130ed575083818151811061309657613096614849565b60200260200101516fffffffffffffffffffffffffffffffff1916846001836130bf91906149d7565b815181106130cf576130cf614849565b60200260200101516fffffffffffffffffffffffffffffffff191610155b15613124576040517f2432d8ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084828151811061313857613138614849565b60200260200101519050600061314e8483611df5565b73ffffffffffffffffffffffffffffffffffffffff8981166000818152600184016020908152604080832081518083019092525463ffffffff811682526401000000009004821b63ffffffff19169181019190915293945091148015906131be5750815163ffffffff8088169116105b806131d25750602082015163ffffffff1916155b15613225575085548254600091610100900460ff169084906006906132069084906601000000000000900461ffff1661493c565b92506101000a81548161ffff021916908361ffff16021790555061322c565b5060208101515b60408051808201825263ffffffff88168152815163ffffffff1984166020828101919091527fffffffffffffffffffffffffffffffff000000000000000000000000000000008d16828501528351808303850181526060909201909352805190830120909182019063ffffffff1916905273ffffffffffffffffffffffffffffffffffffffff8b166000818152600186016020908152604090912083518285015190921c6401000000000263ffffffff92831617905589549294509091908816907f8137bc8a8d712aaa27bfc6506d5566ac405618bd53f9831b8ca6b6fe5442ee7a9087908d9060ff610100909104166133234290565b6020898101518b54604080517fffffffffffffffffffffffffffffffff000000000000000000000000000000009889168152979096169287019290925260ff9093169385019390935267ffffffffffffffff16606084015263ffffffff191660808301526601000000000000900461ffff1660a082015260c00160405180910390a363ffffffff1981161580156133c85750825468010000000000000000900460ff16155b80156133d857506133d8836138fb565b156134c35782547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff1668010000000000000000178355600b80546000906134289067ffffffffffffffff16614acb565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508563ffffffff167fcfdbfd8ce9a56b5f7c202c0e102184d24f47ca87121dc165063fc4c290957bde8561347e4290565b604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909316835267ffffffffffffffff90911660208301520160405180910390a25b6040805160c081018252600080825267ffffffffffffffff42166020830152855460ff680100000000000000009091041615159282019290925273ffffffffffffffffffffffffffffffffffffffff8c1660608201527fffffffffffffffffffffffffffffffff0000000000000000000000000000000086811660808301528b1660a0820152600c80546001808201835591909352815160029093027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805492939092909183917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908360048111156135c0576135c06146d8565b0217905550602082015181546040840151606085015173ffffffffffffffffffffffffffffffffffffffff166a0100000000000000000000027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff67ffffffffffffffff90951661010002949094167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90931692909217929092179190911617815560808083015160a090930151811c7001000000000000000000000000000000000292901c9190911760019182015594909401935061306f92505050565b505050505050565b600060108260ff16106136eb576136eb614878565b50600160ff82161b821678ffffffffffffffffffffffffffffffffffffffffffffffffff16151592915050565b600060108260ff161061372d5761372d614878565b50600160ff919091161b1790565b3373ffffffffffffffffffffffffffffffffffffffff8216036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610418565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006201000078ffffffffffffffffffffffffffffffffffffffffffffffffff83161061385f5761385f614878565b78ffffffffffffffffffffffffffffffffffffffffffffffffff8216156105ac5761388b600183614ae8565b90911690613898816149ea565b905061385f565b6060816000018054806020026020016040519081016040528092919081815260200182805480156138ef57602002820191906000526020600020905b8154815260200190600101908083116138db575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff600090815260018201602090815260408220546401000000009004901b63ffffffff19161515806105a65750505461ffff64010000000082048116660100000000000090920416101590565b60008181526001830160205260408120548015613a455760006139806001836149d7565b8554909150600090613994906001906149d7565b90508082146139f95760008660000182815481106139b4576139b4614849565b90600052602060002001549050808760000184815481106139d7576139d7614849565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613a0a57613a0a614a66565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105a6565b60009150506105a6565b5092915050565b6000818152600183016020526040812054613a9d575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105a6565b5060006105a6565b8051516000901580613ab957508151516010105b80613aca5750602082015161ffff16155b80613adb5750604082015161ffff16155b15613ae857506000919050565b60008060008460000151516002613aff9190614b1a565b67ffffffffffffffff811115613b1757613b17613e52565b604051908082528060200260200182016040528015613b40578160200160208202803683370190505b50905060005b855151811015613d1157600086600001518281518110613b6857613b68614849565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161480613bc95750602081015173ffffffffffffffffffffffffffffffffffffffff16155b80613bec5750602081015173ffffffffffffffffffffffffffffffffffffffff16155b80613c115750602081015173ffffffffffffffffffffffffffffffffffffffff908116145b80613c315750604081015160ff16158015613c315750606081015160ff16155b15613c43575060009695505050505050565b805183613c51846002614b1a565b613c5c9060006149c4565b81518110613c6c57613c6c614849565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015281015183613c9f846002614b1a565b613caa9060016149c4565b81518110613cba57613cba614849565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526040810151613cf19060ff16866149c4565b9450806060015160ff1684613d0691906149c4565b935050600101613b46565b5060005b8151811015613dc3576000828281518110613d3257613d32614849565b602002602001015190506000826001613d4b91906149c4565b90505b8351811015613db957838181518110613d6957613d69614849565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613db157506000979650505050505050565b600101613d4e565b5050600101613d15565b50846020015161ffff168310158015613de45750846040015161ffff168210155b95945050505050565b60008151808452602080850194506020840160005b83811015613e3457815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613e02565b509495945050505050565b602081526000611dee6020830184613ded565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613ea457613ea4613e52565b60405290565b6040516060810167ffffffffffffffff81118282101715613ea457613ea4613e52565b6040516080810167ffffffffffffffff81118282101715613ea457613ea4613e52565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613f3757613f37613e52565b604052919050565b600067ffffffffffffffff821115613f5957613f59613e52565b5060051b60200190565b80357fffffffffffffffffffffffffffffffff00000000000000000000000000000000811681146105ac57600080fd5b600060408284031215613fa557600080fd5b613fad613e81565b9050613fb882613f63565b8152602082013563ffffffff1981168114613fd257600080fd5b602082015292915050565b60006020808385031215613ff057600080fd5b823567ffffffffffffffff81111561400757600080fd5b8301601f8101851361401857600080fd5b803561402b61402682613f3f565b613ef0565b8082825260208201915060208360061b85010192508783111561404d57600080fd5b6020840193505b82841015614078576140668885613f93565b82528482019150604084019350614054565b979650505050505050565b60006020808352835180602085015260005b818110156140b157858101830151858201604001528201614095565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561410257600080fd5b611dee82613f63565b803573ffffffffffffffffffffffffffffffffffffffff811681146105ac57600080fd5b600082601f83011261414057600080fd5b8135602061415061402683613f3f565b8083825260208201915060208460051b87010193508684111561417257600080fd5b602086015b84811015614195576141888161410b565b8352918301918301614177565b509695505050505050565b600080604083850312156141b357600080fd5b823567ffffffffffffffff808211156141cb57600080fd5b6141d78683870161412f565b935060208501359150808211156141ed57600080fd5b506141fa8582860161412f565b9150509250929050565b8051606080845281518482018190526000926080916020918201918388019190865b82811015614280578451805173ffffffffffffffffffffffffffffffffffffffff908116865283820151168386015260408082015160ff908116918701919091529088015116878501529381019392850192600101614226565b508781015161ffff81168a83015295505050604086015193506142a9604088018561ffff169052565b9695505050505050565b600063ffffffff808616835280851660208401525060606040830152613de46060830184614204565b803560ff811681146105ac57600080fd5b803561ffff811681146105ac57600080fd5b6000602080838503121561431257600080fd5b823567ffffffffffffffff8082111561432a57600080fd5b8185019150606080838803121561434057600080fd5b614348613eaa565b83358381111561435757600080fd5b84019250601f8301881361436a57600080fd5b823561437861402682613f3f565b81815260079190911b8401860190868101908a83111561439757600080fd5b948701945b82861015614409576080868c0312156143b55760008081fd5b6143bd613ecd565b6143c68761410b565b81526143d389880161410b565b8982015260406143e48189016142dc565b908201526143f38787016142dc565b818701528252608095909501949087019061439c565b83525061441990508486016142ed565b85820152614429604085016142ed565b6040820152979650505050505050565b60006040828403121561444b57600080fd5b50919050565b6000806040838503121561446457600080fd5b61446d83613f63565b915060208084013567ffffffffffffffff81111561448a57600080fd5b8401601f8101861361449b57600080fd5b80356144a961402682613f3f565b81815260059190911b820183019083810190888311156144c857600080fd5b928401925b828410156144ed576144de84613f63565b825292840192908401906144cd565b80955050505050509250929050565b6000602080838503121561450f57600080fd5b823567ffffffffffffffff81111561452657600080fd5b8301601f8101851361453757600080fd5b803561454561402682613f3f565b81815260079190911b8201830190838101908783111561456457600080fd5b928401925b8284101561407857608084890312156145825760008081fd5b61458a613eaa565b6145938561410b565b81526145a189878701613f93565b86820152606085013580151581146145b95760008081fd5b604082015282526080939093019290840190614569565b600080602083850312156145e357600080fd5b823567ffffffffffffffff808211156145fb57600080fd5b818501915085601f83011261460f57600080fd5b81358181111561461e57600080fd5b8660208260061b850101111561463357600080fd5b60209290920196919550909350505050565b6080815260006146586080830187613ded565b82810360208481019190915286518083528782019282019060005b8181101561469657845163ffffffff191683529383019391830191600101614673565b505061ffff96909616604085015250505090151560609091015292915050565b600080604083850312156146c957600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208082528251828201819052600091906040908185019086840185805b838110156147f2578251805160058110614766577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b86528088015167ffffffffffffffff16888701528681015115158787015260608082015173ffffffffffffffffffffffffffffffffffffffff16908701526080808201517fffffffffffffffffffffffffffffffff000000000000000000000000000000009081169188019190915260a091820151169086015260c09094019391860191600101614725565b509298975050505050505050565b60006020828403121561481257600080fd5b611dee8261410b565b60608152600061482e6060830186613ded565b61ffff94909416602083015250901515604090910152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000604082840312156148b957600080fd5b6148c1613e81565b6148ca8361410b565b8152602083013560208201528091505092915050565b815173ffffffffffffffffffffffffffffffffffffffff16815260208083015190820152604081016105a6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff818116838216019080821115613a4f57613a4f61490d565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036149885761498861490d565b5060010190565b60008161499e5761499e61490d565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b808201808211156105a6576105a661490d565b818103818111156105a6576105a661490d565b600060ff821660ff8103614a0057614a0061490d565b60010192915050565b61ffff828116828216039080821115613a4f57613a4f61490d565b600067ffffffffffffffff821680614a3e57614a3e61490d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600063ffffffff808316818103614aae57614aae61490d565b6001019392505050565b602081526000611dee6020830184614204565b600067ffffffffffffffff808316818103614aae57614aae61490d565b78ffffffffffffffffffffffffffffffffffffffffffffffffff828116828216039080821115613a4f57613a4f61490d565b80820281158282048414176105a6576105a661490d56fea164736f6c6343000818000a", } -var ARMContractABI = ARMContractMetaData.ABI +var RMNContractABI = RMNContractMetaData.ABI -var ARMContractBin = ARMContractMetaData.Bin +var RMNContractBin = RMNContractMetaData.Bin -func DeployARMContract(auth *bind.TransactOpts, backend bind.ContractBackend, config RMNConfig) (common.Address, *types.Transaction, *ARMContract, error) { - parsed, err := ARMContractMetaData.GetAbi() +func DeployRMNContract(auth *bind.TransactOpts, backend bind.ContractBackend, config RMNConfig) (common.Address, *types.Transaction, *RMNContract, error) { + parsed, err := RMNContractMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -86,134 +86,134 @@ func DeployARMContract(auth *bind.TransactOpts, backend bind.ContractBackend, co return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ARMContractBin), backend, config) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(RMNContractBin), backend, config) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &ARMContract{address: address, abi: *parsed, ARMContractCaller: ARMContractCaller{contract: contract}, ARMContractTransactor: ARMContractTransactor{contract: contract}, ARMContractFilterer: ARMContractFilterer{contract: contract}}, nil + return address, tx, &RMNContract{address: address, abi: *parsed, RMNContractCaller: RMNContractCaller{contract: contract}, RMNContractTransactor: RMNContractTransactor{contract: contract}, RMNContractFilterer: RMNContractFilterer{contract: contract}}, nil } -type ARMContract struct { +type RMNContract struct { address common.Address abi abi.ABI - ARMContractCaller - ARMContractTransactor - ARMContractFilterer + RMNContractCaller + RMNContractTransactor + RMNContractFilterer } -type ARMContractCaller struct { +type RMNContractCaller struct { contract *bind.BoundContract } -type ARMContractTransactor struct { +type RMNContractTransactor struct { contract *bind.BoundContract } -type ARMContractFilterer struct { +type RMNContractFilterer struct { contract *bind.BoundContract } -type ARMContractSession struct { - Contract *ARMContract +type RMNContractSession struct { + Contract *RMNContract CallOpts bind.CallOpts TransactOpts bind.TransactOpts } -type ARMContractCallerSession struct { - Contract *ARMContractCaller +type RMNContractCallerSession struct { + Contract *RMNContractCaller CallOpts bind.CallOpts } -type ARMContractTransactorSession struct { - Contract *ARMContractTransactor +type RMNContractTransactorSession struct { + Contract *RMNContractTransactor TransactOpts bind.TransactOpts } -type ARMContractRaw struct { - Contract *ARMContract +type RMNContractRaw struct { + Contract *RMNContract } -type ARMContractCallerRaw struct { - Contract *ARMContractCaller +type RMNContractCallerRaw struct { + Contract *RMNContractCaller } -type ARMContractTransactorRaw struct { - Contract *ARMContractTransactor +type RMNContractTransactorRaw struct { + Contract *RMNContractTransactor } -func NewARMContract(address common.Address, backend bind.ContractBackend) (*ARMContract, error) { - abi, err := abi.JSON(strings.NewReader(ARMContractABI)) +func NewRMNContract(address common.Address, backend bind.ContractBackend) (*RMNContract, error) { + abi, err := abi.JSON(strings.NewReader(RMNContractABI)) if err != nil { return nil, err } - contract, err := bindARMContract(address, backend, backend, backend) + contract, err := bindRMNContract(address, backend, backend, backend) if err != nil { return nil, err } - return &ARMContract{address: address, abi: abi, ARMContractCaller: ARMContractCaller{contract: contract}, ARMContractTransactor: ARMContractTransactor{contract: contract}, ARMContractFilterer: ARMContractFilterer{contract: contract}}, nil + return &RMNContract{address: address, abi: abi, RMNContractCaller: RMNContractCaller{contract: contract}, RMNContractTransactor: RMNContractTransactor{contract: contract}, RMNContractFilterer: RMNContractFilterer{contract: contract}}, nil } -func NewARMContractCaller(address common.Address, caller bind.ContractCaller) (*ARMContractCaller, error) { - contract, err := bindARMContract(address, caller, nil, nil) +func NewRMNContractCaller(address common.Address, caller bind.ContractCaller) (*RMNContractCaller, error) { + contract, err := bindRMNContract(address, caller, nil, nil) if err != nil { return nil, err } - return &ARMContractCaller{contract: contract}, nil + return &RMNContractCaller{contract: contract}, nil } -func NewARMContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ARMContractTransactor, error) { - contract, err := bindARMContract(address, nil, transactor, nil) +func NewRMNContractTransactor(address common.Address, transactor bind.ContractTransactor) (*RMNContractTransactor, error) { + contract, err := bindRMNContract(address, nil, transactor, nil) if err != nil { return nil, err } - return &ARMContractTransactor{contract: contract}, nil + return &RMNContractTransactor{contract: contract}, nil } -func NewARMContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ARMContractFilterer, error) { - contract, err := bindARMContract(address, nil, nil, filterer) +func NewRMNContractFilterer(address common.Address, filterer bind.ContractFilterer) (*RMNContractFilterer, error) { + contract, err := bindRMNContract(address, nil, nil, filterer) if err != nil { return nil, err } - return &ARMContractFilterer{contract: contract}, nil + return &RMNContractFilterer{contract: contract}, nil } -func bindARMContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := ARMContractMetaData.GetAbi() +func bindRMNContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := RMNContractMetaData.GetAbi() if err != nil { return nil, err } return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } -func (_ARMContract *ARMContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ARMContract.Contract.ARMContractCaller.contract.Call(opts, result, method, params...) +func (_RMNContract *RMNContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RMNContract.Contract.RMNContractCaller.contract.Call(opts, result, method, params...) } -func (_ARMContract *ARMContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ARMContract.Contract.ARMContractTransactor.contract.Transfer(opts) +func (_RMNContract *RMNContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RMNContract.Contract.RMNContractTransactor.contract.Transfer(opts) } -func (_ARMContract *ARMContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ARMContract.Contract.ARMContractTransactor.contract.Transact(opts, method, params...) +func (_RMNContract *RMNContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RMNContract.Contract.RMNContractTransactor.contract.Transact(opts, method, params...) } -func (_ARMContract *ARMContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ARMContract.Contract.contract.Call(opts, result, method, params...) +func (_RMNContract *RMNContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RMNContract.Contract.contract.Call(opts, result, method, params...) } -func (_ARMContract *ARMContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ARMContract.Contract.contract.Transfer(opts) +func (_RMNContract *RMNContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RMNContract.Contract.contract.Transfer(opts) } -func (_ARMContract *ARMContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ARMContract.Contract.contract.Transact(opts, method, params...) +func (_RMNContract *RMNContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RMNContract.Contract.contract.Transact(opts, method, params...) } -func (_ARMContract *ARMContractCaller) GetBlessProgress(opts *bind.CallOpts, taggedRoot IRMNTaggedRoot) (GetBlessProgress, +func (_RMNContract *RMNContractCaller) GetBlessProgress(opts *bind.CallOpts, taggedRoot IRMNTaggedRoot) (GetBlessProgress, error) { var out []interface{} - err := _ARMContract.contract.Call(opts, &out, "getBlessProgress", taggedRoot) + err := _RMNContract.contract.Call(opts, &out, "getBlessProgress", taggedRoot) outstruct := new(GetBlessProgress) if err != nil { @@ -228,23 +228,23 @@ func (_ARMContract *ARMContractCaller) GetBlessProgress(opts *bind.CallOpts, tag } -func (_ARMContract *ARMContractSession) GetBlessProgress(taggedRoot IRMNTaggedRoot) (GetBlessProgress, +func (_RMNContract *RMNContractSession) GetBlessProgress(taggedRoot IRMNTaggedRoot) (GetBlessProgress, error) { - return _ARMContract.Contract.GetBlessProgress(&_ARMContract.CallOpts, taggedRoot) + return _RMNContract.Contract.GetBlessProgress(&_RMNContract.CallOpts, taggedRoot) } -func (_ARMContract *ARMContractCallerSession) GetBlessProgress(taggedRoot IRMNTaggedRoot) (GetBlessProgress, +func (_RMNContract *RMNContractCallerSession) GetBlessProgress(taggedRoot IRMNTaggedRoot) (GetBlessProgress, error) { - return _ARMContract.Contract.GetBlessProgress(&_ARMContract.CallOpts, taggedRoot) + return _RMNContract.Contract.GetBlessProgress(&_RMNContract.CallOpts, taggedRoot) } -func (_ARMContract *ARMContractCaller) GetConfigDetails(opts *bind.CallOpts) (GetConfigDetails, +func (_RMNContract *RMNContractCaller) GetConfigDetails(opts *bind.CallOpts) (GetConfigDetails, error) { var out []interface{} - err := _ARMContract.contract.Call(opts, &out, "getConfigDetails") + err := _RMNContract.contract.Call(opts, &out, "getConfigDetails") outstruct := new(GetConfigDetails) if err != nil { @@ -259,23 +259,23 @@ func (_ARMContract *ARMContractCaller) GetConfigDetails(opts *bind.CallOpts) (Ge } -func (_ARMContract *ARMContractSession) GetConfigDetails() (GetConfigDetails, +func (_RMNContract *RMNContractSession) GetConfigDetails() (GetConfigDetails, error) { - return _ARMContract.Contract.GetConfigDetails(&_ARMContract.CallOpts) + return _RMNContract.Contract.GetConfigDetails(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCallerSession) GetConfigDetails() (GetConfigDetails, +func (_RMNContract *RMNContractCallerSession) GetConfigDetails() (GetConfigDetails, error) { - return _ARMContract.Contract.GetConfigDetails(&_ARMContract.CallOpts) + return _RMNContract.Contract.GetConfigDetails(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCaller) GetCurseProgress(opts *bind.CallOpts, subject [16]byte) (GetCurseProgress, +func (_RMNContract *RMNContractCaller) GetCurseProgress(opts *bind.CallOpts, subject [16]byte) (GetCurseProgress, error) { var out []interface{} - err := _ARMContract.contract.Call(opts, &out, "getCurseProgress", subject) + err := _RMNContract.contract.Call(opts, &out, "getCurseProgress", subject) outstruct := new(GetCurseProgress) if err != nil { @@ -291,21 +291,21 @@ func (_ARMContract *ARMContractCaller) GetCurseProgress(opts *bind.CallOpts, sub } -func (_ARMContract *ARMContractSession) GetCurseProgress(subject [16]byte) (GetCurseProgress, +func (_RMNContract *RMNContractSession) GetCurseProgress(subject [16]byte) (GetCurseProgress, error) { - return _ARMContract.Contract.GetCurseProgress(&_ARMContract.CallOpts, subject) + return _RMNContract.Contract.GetCurseProgress(&_RMNContract.CallOpts, subject) } -func (_ARMContract *ARMContractCallerSession) GetCurseProgress(subject [16]byte) (GetCurseProgress, +func (_RMNContract *RMNContractCallerSession) GetCurseProgress(subject [16]byte) (GetCurseProgress, error) { - return _ARMContract.Contract.GetCurseProgress(&_ARMContract.CallOpts, subject) + return _RMNContract.Contract.GetCurseProgress(&_RMNContract.CallOpts, subject) } -func (_ARMContract *ARMContractCaller) GetCursedSubjectsCount(opts *bind.CallOpts) (*big.Int, error) { +func (_RMNContract *RMNContractCaller) GetCursedSubjectsCount(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _ARMContract.contract.Call(opts, &out, "getCursedSubjectsCount") + err := _RMNContract.contract.Call(opts, &out, "getCursedSubjectsCount") if err != nil { return *new(*big.Int), err @@ -317,17 +317,17 @@ func (_ARMContract *ARMContractCaller) GetCursedSubjectsCount(opts *bind.CallOpt } -func (_ARMContract *ARMContractSession) GetCursedSubjectsCount() (*big.Int, error) { - return _ARMContract.Contract.GetCursedSubjectsCount(&_ARMContract.CallOpts) +func (_RMNContract *RMNContractSession) GetCursedSubjectsCount() (*big.Int, error) { + return _RMNContract.Contract.GetCursedSubjectsCount(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCallerSession) GetCursedSubjectsCount() (*big.Int, error) { - return _ARMContract.Contract.GetCursedSubjectsCount(&_ARMContract.CallOpts) +func (_RMNContract *RMNContractCallerSession) GetCursedSubjectsCount() (*big.Int, error) { + return _RMNContract.Contract.GetCursedSubjectsCount(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCaller) GetPermaBlessedCommitStores(opts *bind.CallOpts) ([]common.Address, error) { +func (_RMNContract *RMNContractCaller) GetPermaBlessedCommitStores(opts *bind.CallOpts) ([]common.Address, error) { var out []interface{} - err := _ARMContract.contract.Call(opts, &out, "getPermaBlessedCommitStores") + err := _RMNContract.contract.Call(opts, &out, "getPermaBlessedCommitStores") if err != nil { return *new([]common.Address), err @@ -339,17 +339,17 @@ func (_ARMContract *ARMContractCaller) GetPermaBlessedCommitStores(opts *bind.Ca } -func (_ARMContract *ARMContractSession) GetPermaBlessedCommitStores() ([]common.Address, error) { - return _ARMContract.Contract.GetPermaBlessedCommitStores(&_ARMContract.CallOpts) +func (_RMNContract *RMNContractSession) GetPermaBlessedCommitStores() ([]common.Address, error) { + return _RMNContract.Contract.GetPermaBlessedCommitStores(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCallerSession) GetPermaBlessedCommitStores() ([]common.Address, error) { - return _ARMContract.Contract.GetPermaBlessedCommitStores(&_ARMContract.CallOpts) +func (_RMNContract *RMNContractCallerSession) GetPermaBlessedCommitStores() ([]common.Address, error) { + return _RMNContract.Contract.GetPermaBlessedCommitStores(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCaller) GetRecordedCurseRelatedOps(opts *bind.CallOpts, offset *big.Int, limit *big.Int) ([]RMNRecordedCurseRelatedOp, error) { +func (_RMNContract *RMNContractCaller) GetRecordedCurseRelatedOps(opts *bind.CallOpts, offset *big.Int, limit *big.Int) ([]RMNRecordedCurseRelatedOp, error) { var out []interface{} - err := _ARMContract.contract.Call(opts, &out, "getRecordedCurseRelatedOps", offset, limit) + err := _RMNContract.contract.Call(opts, &out, "getRecordedCurseRelatedOps", offset, limit) if err != nil { return *new([]RMNRecordedCurseRelatedOp), err @@ -361,17 +361,17 @@ func (_ARMContract *ARMContractCaller) GetRecordedCurseRelatedOps(opts *bind.Cal } -func (_ARMContract *ARMContractSession) GetRecordedCurseRelatedOps(offset *big.Int, limit *big.Int) ([]RMNRecordedCurseRelatedOp, error) { - return _ARMContract.Contract.GetRecordedCurseRelatedOps(&_ARMContract.CallOpts, offset, limit) +func (_RMNContract *RMNContractSession) GetRecordedCurseRelatedOps(offset *big.Int, limit *big.Int) ([]RMNRecordedCurseRelatedOp, error) { + return _RMNContract.Contract.GetRecordedCurseRelatedOps(&_RMNContract.CallOpts, offset, limit) } -func (_ARMContract *ARMContractCallerSession) GetRecordedCurseRelatedOps(offset *big.Int, limit *big.Int) ([]RMNRecordedCurseRelatedOp, error) { - return _ARMContract.Contract.GetRecordedCurseRelatedOps(&_ARMContract.CallOpts, offset, limit) +func (_RMNContract *RMNContractCallerSession) GetRecordedCurseRelatedOps(offset *big.Int, limit *big.Int) ([]RMNRecordedCurseRelatedOp, error) { + return _RMNContract.Contract.GetRecordedCurseRelatedOps(&_RMNContract.CallOpts, offset, limit) } -func (_ARMContract *ARMContractCaller) GetRecordedCurseRelatedOpsCount(opts *bind.CallOpts) (*big.Int, error) { +func (_RMNContract *RMNContractCaller) GetRecordedCurseRelatedOpsCount(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _ARMContract.contract.Call(opts, &out, "getRecordedCurseRelatedOpsCount") + err := _RMNContract.contract.Call(opts, &out, "getRecordedCurseRelatedOpsCount") if err != nil { return *new(*big.Int), err @@ -383,17 +383,17 @@ func (_ARMContract *ARMContractCaller) GetRecordedCurseRelatedOpsCount(opts *bin } -func (_ARMContract *ARMContractSession) GetRecordedCurseRelatedOpsCount() (*big.Int, error) { - return _ARMContract.Contract.GetRecordedCurseRelatedOpsCount(&_ARMContract.CallOpts) +func (_RMNContract *RMNContractSession) GetRecordedCurseRelatedOpsCount() (*big.Int, error) { + return _RMNContract.Contract.GetRecordedCurseRelatedOpsCount(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCallerSession) GetRecordedCurseRelatedOpsCount() (*big.Int, error) { - return _ARMContract.Contract.GetRecordedCurseRelatedOpsCount(&_ARMContract.CallOpts) +func (_RMNContract *RMNContractCallerSession) GetRecordedCurseRelatedOpsCount() (*big.Int, error) { + return _RMNContract.Contract.GetRecordedCurseRelatedOpsCount(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCaller) IsBlessed(opts *bind.CallOpts, taggedRoot IRMNTaggedRoot) (bool, error) { +func (_RMNContract *RMNContractCaller) IsBlessed(opts *bind.CallOpts, taggedRoot IRMNTaggedRoot) (bool, error) { var out []interface{} - err := _ARMContract.contract.Call(opts, &out, "isBlessed", taggedRoot) + err := _RMNContract.contract.Call(opts, &out, "isBlessed", taggedRoot) if err != nil { return *new(bool), err @@ -405,17 +405,17 @@ func (_ARMContract *ARMContractCaller) IsBlessed(opts *bind.CallOpts, taggedRoot } -func (_ARMContract *ARMContractSession) IsBlessed(taggedRoot IRMNTaggedRoot) (bool, error) { - return _ARMContract.Contract.IsBlessed(&_ARMContract.CallOpts, taggedRoot) +func (_RMNContract *RMNContractSession) IsBlessed(taggedRoot IRMNTaggedRoot) (bool, error) { + return _RMNContract.Contract.IsBlessed(&_RMNContract.CallOpts, taggedRoot) } -func (_ARMContract *ARMContractCallerSession) IsBlessed(taggedRoot IRMNTaggedRoot) (bool, error) { - return _ARMContract.Contract.IsBlessed(&_ARMContract.CallOpts, taggedRoot) +func (_RMNContract *RMNContractCallerSession) IsBlessed(taggedRoot IRMNTaggedRoot) (bool, error) { + return _RMNContract.Contract.IsBlessed(&_RMNContract.CallOpts, taggedRoot) } -func (_ARMContract *ARMContractCaller) IsCursed(opts *bind.CallOpts, subject [16]byte) (bool, error) { +func (_RMNContract *RMNContractCaller) IsCursed(opts *bind.CallOpts, subject [16]byte) (bool, error) { var out []interface{} - err := _ARMContract.contract.Call(opts, &out, "isCursed", subject) + err := _RMNContract.contract.Call(opts, &out, "isCursed", subject) if err != nil { return *new(bool), err @@ -427,17 +427,17 @@ func (_ARMContract *ARMContractCaller) IsCursed(opts *bind.CallOpts, subject [16 } -func (_ARMContract *ARMContractSession) IsCursed(subject [16]byte) (bool, error) { - return _ARMContract.Contract.IsCursed(&_ARMContract.CallOpts, subject) +func (_RMNContract *RMNContractSession) IsCursed(subject [16]byte) (bool, error) { + return _RMNContract.Contract.IsCursed(&_RMNContract.CallOpts, subject) } -func (_ARMContract *ARMContractCallerSession) IsCursed(subject [16]byte) (bool, error) { - return _ARMContract.Contract.IsCursed(&_ARMContract.CallOpts, subject) +func (_RMNContract *RMNContractCallerSession) IsCursed(subject [16]byte) (bool, error) { + return _RMNContract.Contract.IsCursed(&_RMNContract.CallOpts, subject) } -func (_ARMContract *ARMContractCaller) IsCursed0(opts *bind.CallOpts) (bool, error) { +func (_RMNContract *RMNContractCaller) IsCursed0(opts *bind.CallOpts) (bool, error) { var out []interface{} - err := _ARMContract.contract.Call(opts, &out, "isCursed0") + err := _RMNContract.contract.Call(opts, &out, "isCursed0") if err != nil { return *new(bool), err @@ -449,17 +449,17 @@ func (_ARMContract *ARMContractCaller) IsCursed0(opts *bind.CallOpts) (bool, err } -func (_ARMContract *ARMContractSession) IsCursed0() (bool, error) { - return _ARMContract.Contract.IsCursed0(&_ARMContract.CallOpts) +func (_RMNContract *RMNContractSession) IsCursed0() (bool, error) { + return _RMNContract.Contract.IsCursed0(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCallerSession) IsCursed0() (bool, error) { - return _ARMContract.Contract.IsCursed0(&_ARMContract.CallOpts) +func (_RMNContract *RMNContractCallerSession) IsCursed0() (bool, error) { + return _RMNContract.Contract.IsCursed0(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { +func (_RMNContract *RMNContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _ARMContract.contract.Call(opts, &out, "owner") + err := _RMNContract.contract.Call(opts, &out, "owner") if err != nil { return *new(common.Address), err @@ -471,17 +471,17 @@ func (_ARMContract *ARMContractCaller) Owner(opts *bind.CallOpts) (common.Addres } -func (_ARMContract *ARMContractSession) Owner() (common.Address, error) { - return _ARMContract.Contract.Owner(&_ARMContract.CallOpts) +func (_RMNContract *RMNContractSession) Owner() (common.Address, error) { + return _RMNContract.Contract.Owner(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCallerSession) Owner() (common.Address, error) { - return _ARMContract.Contract.Owner(&_ARMContract.CallOpts) +func (_RMNContract *RMNContractCallerSession) Owner() (common.Address, error) { + return _RMNContract.Contract.Owner(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { +func (_RMNContract *RMNContractCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { var out []interface{} - err := _ARMContract.contract.Call(opts, &out, "typeAndVersion") + err := _RMNContract.contract.Call(opts, &out, "typeAndVersion") if err != nil { return *new(string), err @@ -493,136 +493,136 @@ func (_ARMContract *ARMContractCaller) TypeAndVersion(opts *bind.CallOpts) (stri } -func (_ARMContract *ARMContractSession) TypeAndVersion() (string, error) { - return _ARMContract.Contract.TypeAndVersion(&_ARMContract.CallOpts) +func (_RMNContract *RMNContractSession) TypeAndVersion() (string, error) { + return _RMNContract.Contract.TypeAndVersion(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractCallerSession) TypeAndVersion() (string, error) { - return _ARMContract.Contract.TypeAndVersion(&_ARMContract.CallOpts) +func (_RMNContract *RMNContractCallerSession) TypeAndVersion() (string, error) { + return _RMNContract.Contract.TypeAndVersion(&_RMNContract.CallOpts) } -func (_ARMContract *ARMContractTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ARMContract.contract.Transact(opts, "acceptOwnership") +func (_RMNContract *RMNContractTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RMNContract.contract.Transact(opts, "acceptOwnership") } -func (_ARMContract *ARMContractSession) AcceptOwnership() (*types.Transaction, error) { - return _ARMContract.Contract.AcceptOwnership(&_ARMContract.TransactOpts) +func (_RMNContract *RMNContractSession) AcceptOwnership() (*types.Transaction, error) { + return _RMNContract.Contract.AcceptOwnership(&_RMNContract.TransactOpts) } -func (_ARMContract *ARMContractTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _ARMContract.Contract.AcceptOwnership(&_ARMContract.TransactOpts) +func (_RMNContract *RMNContractTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _RMNContract.Contract.AcceptOwnership(&_RMNContract.TransactOpts) } -func (_ARMContract *ARMContractTransactor) OwnerCurse(opts *bind.TransactOpts, curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { - return _ARMContract.contract.Transact(opts, "ownerCurse", curseId, subjects) +func (_RMNContract *RMNContractTransactor) OwnerCurse(opts *bind.TransactOpts, curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { + return _RMNContract.contract.Transact(opts, "ownerCurse", curseId, subjects) } -func (_ARMContract *ARMContractSession) OwnerCurse(curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { - return _ARMContract.Contract.OwnerCurse(&_ARMContract.TransactOpts, curseId, subjects) +func (_RMNContract *RMNContractSession) OwnerCurse(curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { + return _RMNContract.Contract.OwnerCurse(&_RMNContract.TransactOpts, curseId, subjects) } -func (_ARMContract *ARMContractTransactorSession) OwnerCurse(curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { - return _ARMContract.Contract.OwnerCurse(&_ARMContract.TransactOpts, curseId, subjects) +func (_RMNContract *RMNContractTransactorSession) OwnerCurse(curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { + return _RMNContract.Contract.OwnerCurse(&_RMNContract.TransactOpts, curseId, subjects) } -func (_ARMContract *ARMContractTransactor) OwnerRemoveThenAddPermaBlessedCommitStores(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { - return _ARMContract.contract.Transact(opts, "ownerRemoveThenAddPermaBlessedCommitStores", removes, adds) +func (_RMNContract *RMNContractTransactor) OwnerRemoveThenAddPermaBlessedCommitStores(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _RMNContract.contract.Transact(opts, "ownerRemoveThenAddPermaBlessedCommitStores", removes, adds) } -func (_ARMContract *ARMContractSession) OwnerRemoveThenAddPermaBlessedCommitStores(removes []common.Address, adds []common.Address) (*types.Transaction, error) { - return _ARMContract.Contract.OwnerRemoveThenAddPermaBlessedCommitStores(&_ARMContract.TransactOpts, removes, adds) +func (_RMNContract *RMNContractSession) OwnerRemoveThenAddPermaBlessedCommitStores(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _RMNContract.Contract.OwnerRemoveThenAddPermaBlessedCommitStores(&_RMNContract.TransactOpts, removes, adds) } -func (_ARMContract *ARMContractTransactorSession) OwnerRemoveThenAddPermaBlessedCommitStores(removes []common.Address, adds []common.Address) (*types.Transaction, error) { - return _ARMContract.Contract.OwnerRemoveThenAddPermaBlessedCommitStores(&_ARMContract.TransactOpts, removes, adds) +func (_RMNContract *RMNContractTransactorSession) OwnerRemoveThenAddPermaBlessedCommitStores(removes []common.Address, adds []common.Address) (*types.Transaction, error) { + return _RMNContract.Contract.OwnerRemoveThenAddPermaBlessedCommitStores(&_RMNContract.TransactOpts, removes, adds) } -func (_ARMContract *ARMContractTransactor) OwnerResetBlessVotes(opts *bind.TransactOpts, taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { - return _ARMContract.contract.Transact(opts, "ownerResetBlessVotes", taggedRoots) +func (_RMNContract *RMNContractTransactor) OwnerResetBlessVotes(opts *bind.TransactOpts, taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { + return _RMNContract.contract.Transact(opts, "ownerResetBlessVotes", taggedRoots) } -func (_ARMContract *ARMContractSession) OwnerResetBlessVotes(taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { - return _ARMContract.Contract.OwnerResetBlessVotes(&_ARMContract.TransactOpts, taggedRoots) +func (_RMNContract *RMNContractSession) OwnerResetBlessVotes(taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { + return _RMNContract.Contract.OwnerResetBlessVotes(&_RMNContract.TransactOpts, taggedRoots) } -func (_ARMContract *ARMContractTransactorSession) OwnerResetBlessVotes(taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { - return _ARMContract.Contract.OwnerResetBlessVotes(&_ARMContract.TransactOpts, taggedRoots) +func (_RMNContract *RMNContractTransactorSession) OwnerResetBlessVotes(taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { + return _RMNContract.Contract.OwnerResetBlessVotes(&_RMNContract.TransactOpts, taggedRoots) } -func (_ARMContract *ARMContractTransactor) OwnerUnvoteToCurse(opts *bind.TransactOpts, ownerUnvoteToCurseRequests []RMNOwnerUnvoteToCurseRequest) (*types.Transaction, error) { - return _ARMContract.contract.Transact(opts, "ownerUnvoteToCurse", ownerUnvoteToCurseRequests) +func (_RMNContract *RMNContractTransactor) OwnerUnvoteToCurse(opts *bind.TransactOpts, ownerUnvoteToCurseRequests []RMNOwnerUnvoteToCurseRequest) (*types.Transaction, error) { + return _RMNContract.contract.Transact(opts, "ownerUnvoteToCurse", ownerUnvoteToCurseRequests) } -func (_ARMContract *ARMContractSession) OwnerUnvoteToCurse(ownerUnvoteToCurseRequests []RMNOwnerUnvoteToCurseRequest) (*types.Transaction, error) { - return _ARMContract.Contract.OwnerUnvoteToCurse(&_ARMContract.TransactOpts, ownerUnvoteToCurseRequests) +func (_RMNContract *RMNContractSession) OwnerUnvoteToCurse(ownerUnvoteToCurseRequests []RMNOwnerUnvoteToCurseRequest) (*types.Transaction, error) { + return _RMNContract.Contract.OwnerUnvoteToCurse(&_RMNContract.TransactOpts, ownerUnvoteToCurseRequests) } -func (_ARMContract *ARMContractTransactorSession) OwnerUnvoteToCurse(ownerUnvoteToCurseRequests []RMNOwnerUnvoteToCurseRequest) (*types.Transaction, error) { - return _ARMContract.Contract.OwnerUnvoteToCurse(&_ARMContract.TransactOpts, ownerUnvoteToCurseRequests) +func (_RMNContract *RMNContractTransactorSession) OwnerUnvoteToCurse(ownerUnvoteToCurseRequests []RMNOwnerUnvoteToCurseRequest) (*types.Transaction, error) { + return _RMNContract.Contract.OwnerUnvoteToCurse(&_RMNContract.TransactOpts, ownerUnvoteToCurseRequests) } -func (_ARMContract *ARMContractTransactor) SetConfig(opts *bind.TransactOpts, config RMNConfig) (*types.Transaction, error) { - return _ARMContract.contract.Transact(opts, "setConfig", config) +func (_RMNContract *RMNContractTransactor) SetConfig(opts *bind.TransactOpts, config RMNConfig) (*types.Transaction, error) { + return _RMNContract.contract.Transact(opts, "setConfig", config) } -func (_ARMContract *ARMContractSession) SetConfig(config RMNConfig) (*types.Transaction, error) { - return _ARMContract.Contract.SetConfig(&_ARMContract.TransactOpts, config) +func (_RMNContract *RMNContractSession) SetConfig(config RMNConfig) (*types.Transaction, error) { + return _RMNContract.Contract.SetConfig(&_RMNContract.TransactOpts, config) } -func (_ARMContract *ARMContractTransactorSession) SetConfig(config RMNConfig) (*types.Transaction, error) { - return _ARMContract.Contract.SetConfig(&_ARMContract.TransactOpts, config) +func (_RMNContract *RMNContractTransactorSession) SetConfig(config RMNConfig) (*types.Transaction, error) { + return _RMNContract.Contract.SetConfig(&_RMNContract.TransactOpts, config) } -func (_ARMContract *ARMContractTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _ARMContract.contract.Transact(opts, "transferOwnership", to) +func (_RMNContract *RMNContractTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _RMNContract.contract.Transact(opts, "transferOwnership", to) } -func (_ARMContract *ARMContractSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _ARMContract.Contract.TransferOwnership(&_ARMContract.TransactOpts, to) +func (_RMNContract *RMNContractSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _RMNContract.Contract.TransferOwnership(&_RMNContract.TransactOpts, to) } -func (_ARMContract *ARMContractTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _ARMContract.Contract.TransferOwnership(&_ARMContract.TransactOpts, to) +func (_RMNContract *RMNContractTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _RMNContract.Contract.TransferOwnership(&_RMNContract.TransactOpts, to) } -func (_ARMContract *ARMContractTransactor) UnvoteToCurse(opts *bind.TransactOpts, unvoteToCurseRequests []RMNUnvoteToCurseRequest) (*types.Transaction, error) { - return _ARMContract.contract.Transact(opts, "unvoteToCurse", unvoteToCurseRequests) +func (_RMNContract *RMNContractTransactor) UnvoteToCurse(opts *bind.TransactOpts, unvoteToCurseRequests []RMNUnvoteToCurseRequest) (*types.Transaction, error) { + return _RMNContract.contract.Transact(opts, "unvoteToCurse", unvoteToCurseRequests) } -func (_ARMContract *ARMContractSession) UnvoteToCurse(unvoteToCurseRequests []RMNUnvoteToCurseRequest) (*types.Transaction, error) { - return _ARMContract.Contract.UnvoteToCurse(&_ARMContract.TransactOpts, unvoteToCurseRequests) +func (_RMNContract *RMNContractSession) UnvoteToCurse(unvoteToCurseRequests []RMNUnvoteToCurseRequest) (*types.Transaction, error) { + return _RMNContract.Contract.UnvoteToCurse(&_RMNContract.TransactOpts, unvoteToCurseRequests) } -func (_ARMContract *ARMContractTransactorSession) UnvoteToCurse(unvoteToCurseRequests []RMNUnvoteToCurseRequest) (*types.Transaction, error) { - return _ARMContract.Contract.UnvoteToCurse(&_ARMContract.TransactOpts, unvoteToCurseRequests) +func (_RMNContract *RMNContractTransactorSession) UnvoteToCurse(unvoteToCurseRequests []RMNUnvoteToCurseRequest) (*types.Transaction, error) { + return _RMNContract.Contract.UnvoteToCurse(&_RMNContract.TransactOpts, unvoteToCurseRequests) } -func (_ARMContract *ARMContractTransactor) VoteToBless(opts *bind.TransactOpts, taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { - return _ARMContract.contract.Transact(opts, "voteToBless", taggedRoots) +func (_RMNContract *RMNContractTransactor) VoteToBless(opts *bind.TransactOpts, taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { + return _RMNContract.contract.Transact(opts, "voteToBless", taggedRoots) } -func (_ARMContract *ARMContractSession) VoteToBless(taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { - return _ARMContract.Contract.VoteToBless(&_ARMContract.TransactOpts, taggedRoots) +func (_RMNContract *RMNContractSession) VoteToBless(taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { + return _RMNContract.Contract.VoteToBless(&_RMNContract.TransactOpts, taggedRoots) } -func (_ARMContract *ARMContractTransactorSession) VoteToBless(taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { - return _ARMContract.Contract.VoteToBless(&_ARMContract.TransactOpts, taggedRoots) +func (_RMNContract *RMNContractTransactorSession) VoteToBless(taggedRoots []IRMNTaggedRoot) (*types.Transaction, error) { + return _RMNContract.Contract.VoteToBless(&_RMNContract.TransactOpts, taggedRoots) } -func (_ARMContract *ARMContractTransactor) VoteToCurse(opts *bind.TransactOpts, curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { - return _ARMContract.contract.Transact(opts, "voteToCurse", curseId, subjects) +func (_RMNContract *RMNContractTransactor) VoteToCurse(opts *bind.TransactOpts, curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { + return _RMNContract.contract.Transact(opts, "voteToCurse", curseId, subjects) } -func (_ARMContract *ARMContractSession) VoteToCurse(curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { - return _ARMContract.Contract.VoteToCurse(&_ARMContract.TransactOpts, curseId, subjects) +func (_RMNContract *RMNContractSession) VoteToCurse(curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { + return _RMNContract.Contract.VoteToCurse(&_RMNContract.TransactOpts, curseId, subjects) } -func (_ARMContract *ARMContractTransactorSession) VoteToCurse(curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { - return _ARMContract.Contract.VoteToCurse(&_ARMContract.TransactOpts, curseId, subjects) +func (_RMNContract *RMNContractTransactorSession) VoteToCurse(curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) { + return _RMNContract.Contract.VoteToCurse(&_RMNContract.TransactOpts, curseId, subjects) } -type ARMContractAlreadyBlessedIterator struct { - Event *ARMContractAlreadyBlessed +type RMNContractAlreadyBlessedIterator struct { + Event *RMNContractAlreadyBlessed contract *bind.BoundContract event string @@ -633,7 +633,7 @@ type ARMContractAlreadyBlessedIterator struct { fail error } -func (it *ARMContractAlreadyBlessedIterator) Next() bool { +func (it *RMNContractAlreadyBlessedIterator) Next() bool { if it.fail != nil { return false @@ -642,7 +642,7 @@ func (it *ARMContractAlreadyBlessedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractAlreadyBlessed) + it.Event = new(RMNContractAlreadyBlessed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -657,7 +657,7 @@ func (it *ARMContractAlreadyBlessedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractAlreadyBlessed) + it.Event = new(RMNContractAlreadyBlessed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -672,23 +672,23 @@ func (it *ARMContractAlreadyBlessedIterator) Next() bool { } } -func (it *ARMContractAlreadyBlessedIterator) Error() error { +func (it *RMNContractAlreadyBlessedIterator) Error() error { return it.fail } -func (it *ARMContractAlreadyBlessedIterator) Close() error { +func (it *RMNContractAlreadyBlessedIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractAlreadyBlessed struct { +type RMNContractAlreadyBlessed struct { ConfigVersion uint32 Voter common.Address TaggedRoot IRMNTaggedRoot Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterAlreadyBlessed(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractAlreadyBlessedIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterAlreadyBlessed(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*RMNContractAlreadyBlessedIterator, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { @@ -699,14 +699,14 @@ func (_ARMContract *ARMContractFilterer) FilterAlreadyBlessed(opts *bind.FilterO voterRule = append(voterRule, voterItem) } - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "AlreadyBlessed", configVersionRule, voterRule) + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "AlreadyBlessed", configVersionRule, voterRule) if err != nil { return nil, err } - return &ARMContractAlreadyBlessedIterator{contract: _ARMContract.contract, event: "AlreadyBlessed", logs: logs, sub: sub}, nil + return &RMNContractAlreadyBlessedIterator{contract: _RMNContract.contract, event: "AlreadyBlessed", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchAlreadyBlessed(opts *bind.WatchOpts, sink chan<- *ARMContractAlreadyBlessed, configVersion []uint32, voter []common.Address) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchAlreadyBlessed(opts *bind.WatchOpts, sink chan<- *RMNContractAlreadyBlessed, configVersion []uint32, voter []common.Address) (event.Subscription, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { @@ -717,7 +717,7 @@ func (_ARMContract *ARMContractFilterer) WatchAlreadyBlessed(opts *bind.WatchOpt voterRule = append(voterRule, voterItem) } - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "AlreadyBlessed", configVersionRule, voterRule) + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "AlreadyBlessed", configVersionRule, voterRule) if err != nil { return nil, err } @@ -727,8 +727,8 @@ func (_ARMContract *ARMContractFilterer) WatchAlreadyBlessed(opts *bind.WatchOpt select { case log := <-logs: - event := new(ARMContractAlreadyBlessed) - if err := _ARMContract.contract.UnpackLog(event, "AlreadyBlessed", log); err != nil { + event := new(RMNContractAlreadyBlessed) + if err := _RMNContract.contract.UnpackLog(event, "AlreadyBlessed", log); err != nil { return err } event.Raw = log @@ -749,17 +749,17 @@ func (_ARMContract *ARMContractFilterer) WatchAlreadyBlessed(opts *bind.WatchOpt }), nil } -func (_ARMContract *ARMContractFilterer) ParseAlreadyBlessed(log types.Log) (*ARMContractAlreadyBlessed, error) { - event := new(ARMContractAlreadyBlessed) - if err := _ARMContract.contract.UnpackLog(event, "AlreadyBlessed", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseAlreadyBlessed(log types.Log) (*RMNContractAlreadyBlessed, error) { + event := new(RMNContractAlreadyBlessed) + if err := _RMNContract.contract.UnpackLog(event, "AlreadyBlessed", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractAlreadyVotedToBlessIterator struct { - Event *ARMContractAlreadyVotedToBless +type RMNContractAlreadyVotedToBlessIterator struct { + Event *RMNContractAlreadyVotedToBless contract *bind.BoundContract event string @@ -770,7 +770,7 @@ type ARMContractAlreadyVotedToBlessIterator struct { fail error } -func (it *ARMContractAlreadyVotedToBlessIterator) Next() bool { +func (it *RMNContractAlreadyVotedToBlessIterator) Next() bool { if it.fail != nil { return false @@ -779,7 +779,7 @@ func (it *ARMContractAlreadyVotedToBlessIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractAlreadyVotedToBless) + it.Event = new(RMNContractAlreadyVotedToBless) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -794,7 +794,7 @@ func (it *ARMContractAlreadyVotedToBlessIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractAlreadyVotedToBless) + it.Event = new(RMNContractAlreadyVotedToBless) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -809,23 +809,23 @@ func (it *ARMContractAlreadyVotedToBlessIterator) Next() bool { } } -func (it *ARMContractAlreadyVotedToBlessIterator) Error() error { +func (it *RMNContractAlreadyVotedToBlessIterator) Error() error { return it.fail } -func (it *ARMContractAlreadyVotedToBlessIterator) Close() error { +func (it *RMNContractAlreadyVotedToBlessIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractAlreadyVotedToBless struct { +type RMNContractAlreadyVotedToBless struct { ConfigVersion uint32 Voter common.Address TaggedRoot IRMNTaggedRoot Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterAlreadyVotedToBless(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractAlreadyVotedToBlessIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterAlreadyVotedToBless(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*RMNContractAlreadyVotedToBlessIterator, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { @@ -836,14 +836,14 @@ func (_ARMContract *ARMContractFilterer) FilterAlreadyVotedToBless(opts *bind.Fi voterRule = append(voterRule, voterItem) } - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "AlreadyVotedToBless", configVersionRule, voterRule) + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "AlreadyVotedToBless", configVersionRule, voterRule) if err != nil { return nil, err } - return &ARMContractAlreadyVotedToBlessIterator{contract: _ARMContract.contract, event: "AlreadyVotedToBless", logs: logs, sub: sub}, nil + return &RMNContractAlreadyVotedToBlessIterator{contract: _RMNContract.contract, event: "AlreadyVotedToBless", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchAlreadyVotedToBless(opts *bind.WatchOpts, sink chan<- *ARMContractAlreadyVotedToBless, configVersion []uint32, voter []common.Address) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchAlreadyVotedToBless(opts *bind.WatchOpts, sink chan<- *RMNContractAlreadyVotedToBless, configVersion []uint32, voter []common.Address) (event.Subscription, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { @@ -854,7 +854,7 @@ func (_ARMContract *ARMContractFilterer) WatchAlreadyVotedToBless(opts *bind.Wat voterRule = append(voterRule, voterItem) } - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "AlreadyVotedToBless", configVersionRule, voterRule) + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "AlreadyVotedToBless", configVersionRule, voterRule) if err != nil { return nil, err } @@ -864,8 +864,8 @@ func (_ARMContract *ARMContractFilterer) WatchAlreadyVotedToBless(opts *bind.Wat select { case log := <-logs: - event := new(ARMContractAlreadyVotedToBless) - if err := _ARMContract.contract.UnpackLog(event, "AlreadyVotedToBless", log); err != nil { + event := new(RMNContractAlreadyVotedToBless) + if err := _RMNContract.contract.UnpackLog(event, "AlreadyVotedToBless", log); err != nil { return err } event.Raw = log @@ -886,17 +886,17 @@ func (_ARMContract *ARMContractFilterer) WatchAlreadyVotedToBless(opts *bind.Wat }), nil } -func (_ARMContract *ARMContractFilterer) ParseAlreadyVotedToBless(log types.Log) (*ARMContractAlreadyVotedToBless, error) { - event := new(ARMContractAlreadyVotedToBless) - if err := _ARMContract.contract.UnpackLog(event, "AlreadyVotedToBless", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseAlreadyVotedToBless(log types.Log) (*RMNContractAlreadyVotedToBless, error) { + event := new(RMNContractAlreadyVotedToBless) + if err := _RMNContract.contract.UnpackLog(event, "AlreadyVotedToBless", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractConfigSetIterator struct { - Event *ARMContractConfigSet +type RMNContractConfigSetIterator struct { + Event *RMNContractConfigSet contract *bind.BoundContract event string @@ -907,7 +907,7 @@ type ARMContractConfigSetIterator struct { fail error } -func (it *ARMContractConfigSetIterator) Next() bool { +func (it *RMNContractConfigSetIterator) Next() bool { if it.fail != nil { return false @@ -916,7 +916,7 @@ func (it *ARMContractConfigSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractConfigSet) + it.Event = new(RMNContractConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -931,7 +931,7 @@ func (it *ARMContractConfigSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractConfigSet) + it.Event = new(RMNContractConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -946,43 +946,43 @@ func (it *ARMContractConfigSetIterator) Next() bool { } } -func (it *ARMContractConfigSetIterator) Error() error { +func (it *RMNContractConfigSetIterator) Error() error { return it.fail } -func (it *ARMContractConfigSetIterator) Close() error { +func (it *RMNContractConfigSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractConfigSet struct { +type RMNContractConfigSet struct { ConfigVersion uint32 Config RMNConfig Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterConfigSet(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractConfigSetIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterConfigSet(opts *bind.FilterOpts, configVersion []uint32) (*RMNContractConfigSetIterator, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { configVersionRule = append(configVersionRule, configVersionItem) } - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "ConfigSet", configVersionRule) + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "ConfigSet", configVersionRule) if err != nil { return nil, err } - return &ARMContractConfigSetIterator{contract: _ARMContract.contract, event: "ConfigSet", logs: logs, sub: sub}, nil + return &RMNContractConfigSetIterator{contract: _RMNContract.contract, event: "ConfigSet", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *ARMContractConfigSet, configVersion []uint32) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *RMNContractConfigSet, configVersion []uint32) (event.Subscription, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { configVersionRule = append(configVersionRule, configVersionItem) } - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "ConfigSet", configVersionRule) + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "ConfigSet", configVersionRule) if err != nil { return nil, err } @@ -992,8 +992,8 @@ func (_ARMContract *ARMContractFilterer) WatchConfigSet(opts *bind.WatchOpts, si select { case log := <-logs: - event := new(ARMContractConfigSet) - if err := _ARMContract.contract.UnpackLog(event, "ConfigSet", log); err != nil { + event := new(RMNContractConfigSet) + if err := _RMNContract.contract.UnpackLog(event, "ConfigSet", log); err != nil { return err } event.Raw = log @@ -1014,17 +1014,17 @@ func (_ARMContract *ARMContractFilterer) WatchConfigSet(opts *bind.WatchOpts, si }), nil } -func (_ARMContract *ARMContractFilterer) ParseConfigSet(log types.Log) (*ARMContractConfigSet, error) { - event := new(ARMContractConfigSet) - if err := _ARMContract.contract.UnpackLog(event, "ConfigSet", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseConfigSet(log types.Log) (*RMNContractConfigSet, error) { + event := new(RMNContractConfigSet) + if err := _RMNContract.contract.UnpackLog(event, "ConfigSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractCurseLiftedIterator struct { - Event *ARMContractCurseLifted +type RMNContractCurseLiftedIterator struct { + Event *RMNContractCurseLifted contract *bind.BoundContract event string @@ -1035,7 +1035,7 @@ type ARMContractCurseLiftedIterator struct { fail error } -func (it *ARMContractCurseLiftedIterator) Next() bool { +func (it *RMNContractCurseLiftedIterator) Next() bool { if it.fail != nil { return false @@ -1044,7 +1044,7 @@ func (it *ARMContractCurseLiftedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractCurseLifted) + it.Event = new(RMNContractCurseLifted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1059,7 +1059,7 @@ func (it *ARMContractCurseLiftedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractCurseLifted) + it.Event = new(RMNContractCurseLifted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1074,32 +1074,32 @@ func (it *ARMContractCurseLiftedIterator) Next() bool { } } -func (it *ARMContractCurseLiftedIterator) Error() error { +func (it *RMNContractCurseLiftedIterator) Error() error { return it.fail } -func (it *ARMContractCurseLiftedIterator) Close() error { +func (it *RMNContractCurseLiftedIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractCurseLifted struct { +type RMNContractCurseLifted struct { Subject [16]byte Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterCurseLifted(opts *bind.FilterOpts) (*ARMContractCurseLiftedIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterCurseLifted(opts *bind.FilterOpts) (*RMNContractCurseLiftedIterator, error) { - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "CurseLifted") + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "CurseLifted") if err != nil { return nil, err } - return &ARMContractCurseLiftedIterator{contract: _ARMContract.contract, event: "CurseLifted", logs: logs, sub: sub}, nil + return &RMNContractCurseLiftedIterator{contract: _RMNContract.contract, event: "CurseLifted", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchCurseLifted(opts *bind.WatchOpts, sink chan<- *ARMContractCurseLifted) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchCurseLifted(opts *bind.WatchOpts, sink chan<- *RMNContractCurseLifted) (event.Subscription, error) { - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "CurseLifted") + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "CurseLifted") if err != nil { return nil, err } @@ -1109,8 +1109,8 @@ func (_ARMContract *ARMContractFilterer) WatchCurseLifted(opts *bind.WatchOpts, select { case log := <-logs: - event := new(ARMContractCurseLifted) - if err := _ARMContract.contract.UnpackLog(event, "CurseLifted", log); err != nil { + event := new(RMNContractCurseLifted) + if err := _RMNContract.contract.UnpackLog(event, "CurseLifted", log); err != nil { return err } event.Raw = log @@ -1131,17 +1131,17 @@ func (_ARMContract *ARMContractFilterer) WatchCurseLifted(opts *bind.WatchOpts, }), nil } -func (_ARMContract *ARMContractFilterer) ParseCurseLifted(log types.Log) (*ARMContractCurseLifted, error) { - event := new(ARMContractCurseLifted) - if err := _ARMContract.contract.UnpackLog(event, "CurseLifted", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseCurseLifted(log types.Log) (*RMNContractCurseLifted, error) { + event := new(RMNContractCurseLifted) + if err := _RMNContract.contract.UnpackLog(event, "CurseLifted", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractCursedIterator struct { - Event *ARMContractCursed +type RMNContractCursedIterator struct { + Event *RMNContractCursed contract *bind.BoundContract event string @@ -1152,7 +1152,7 @@ type ARMContractCursedIterator struct { fail error } -func (it *ARMContractCursedIterator) Next() bool { +func (it *RMNContractCursedIterator) Next() bool { if it.fail != nil { return false @@ -1161,7 +1161,7 @@ func (it *ARMContractCursedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractCursed) + it.Event = new(RMNContractCursed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1176,7 +1176,7 @@ func (it *ARMContractCursedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractCursed) + it.Event = new(RMNContractCursed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1191,44 +1191,44 @@ func (it *ARMContractCursedIterator) Next() bool { } } -func (it *ARMContractCursedIterator) Error() error { +func (it *RMNContractCursedIterator) Error() error { return it.fail } -func (it *ARMContractCursedIterator) Close() error { +func (it *RMNContractCursedIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractCursed struct { +type RMNContractCursed struct { ConfigVersion uint32 Subject [16]byte BlockTimestamp uint64 Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterCursed(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractCursedIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterCursed(opts *bind.FilterOpts, configVersion []uint32) (*RMNContractCursedIterator, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { configVersionRule = append(configVersionRule, configVersionItem) } - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "Cursed", configVersionRule) + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "Cursed", configVersionRule) if err != nil { return nil, err } - return &ARMContractCursedIterator{contract: _ARMContract.contract, event: "Cursed", logs: logs, sub: sub}, nil + return &RMNContractCursedIterator{contract: _RMNContract.contract, event: "Cursed", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchCursed(opts *bind.WatchOpts, sink chan<- *ARMContractCursed, configVersion []uint32) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchCursed(opts *bind.WatchOpts, sink chan<- *RMNContractCursed, configVersion []uint32) (event.Subscription, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { configVersionRule = append(configVersionRule, configVersionItem) } - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "Cursed", configVersionRule) + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "Cursed", configVersionRule) if err != nil { return nil, err } @@ -1238,8 +1238,8 @@ func (_ARMContract *ARMContractFilterer) WatchCursed(opts *bind.WatchOpts, sink select { case log := <-logs: - event := new(ARMContractCursed) - if err := _ARMContract.contract.UnpackLog(event, "Cursed", log); err != nil { + event := new(RMNContractCursed) + if err := _RMNContract.contract.UnpackLog(event, "Cursed", log); err != nil { return err } event.Raw = log @@ -1260,17 +1260,17 @@ func (_ARMContract *ARMContractFilterer) WatchCursed(opts *bind.WatchOpts, sink }), nil } -func (_ARMContract *ARMContractFilterer) ParseCursed(log types.Log) (*ARMContractCursed, error) { - event := new(ARMContractCursed) - if err := _ARMContract.contract.UnpackLog(event, "Cursed", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseCursed(log types.Log) (*RMNContractCursed, error) { + event := new(RMNContractCursed) + if err := _RMNContract.contract.UnpackLog(event, "Cursed", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractOwnershipTransferRequestedIterator struct { - Event *ARMContractOwnershipTransferRequested +type RMNContractOwnershipTransferRequestedIterator struct { + Event *RMNContractOwnershipTransferRequested contract *bind.BoundContract event string @@ -1281,7 +1281,7 @@ type ARMContractOwnershipTransferRequestedIterator struct { fail error } -func (it *ARMContractOwnershipTransferRequestedIterator) Next() bool { +func (it *RMNContractOwnershipTransferRequestedIterator) Next() bool { if it.fail != nil { return false @@ -1290,7 +1290,7 @@ func (it *ARMContractOwnershipTransferRequestedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractOwnershipTransferRequested) + it.Event = new(RMNContractOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1305,7 +1305,7 @@ func (it *ARMContractOwnershipTransferRequestedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractOwnershipTransferRequested) + it.Event = new(RMNContractOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1320,22 +1320,22 @@ func (it *ARMContractOwnershipTransferRequestedIterator) Next() bool { } } -func (it *ARMContractOwnershipTransferRequestedIterator) Error() error { +func (it *RMNContractOwnershipTransferRequestedIterator) Error() error { return it.fail } -func (it *ARMContractOwnershipTransferRequestedIterator) Close() error { +func (it *RMNContractOwnershipTransferRequestedIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractOwnershipTransferRequested struct { +type RMNContractOwnershipTransferRequested struct { From common.Address To common.Address Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMContractOwnershipTransferRequestedIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RMNContractOwnershipTransferRequestedIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1346,14 +1346,14 @@ func (_ARMContract *ARMContractFilterer) FilterOwnershipTransferRequested(opts * toRule = append(toRule, toItem) } - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } - return &ARMContractOwnershipTransferRequestedIterator{contract: _ARMContract.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil + return &RMNContractOwnershipTransferRequestedIterator{contract: _RMNContract.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ARMContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *RMNContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1364,7 +1364,7 @@ func (_ARMContract *ARMContractFilterer) WatchOwnershipTransferRequested(opts *b toRule = append(toRule, toItem) } - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } @@ -1374,8 +1374,8 @@ func (_ARMContract *ARMContractFilterer) WatchOwnershipTransferRequested(opts *b select { case log := <-logs: - event := new(ARMContractOwnershipTransferRequested) - if err := _ARMContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + event := new(RMNContractOwnershipTransferRequested) + if err := _RMNContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return err } event.Raw = log @@ -1396,17 +1396,17 @@ func (_ARMContract *ARMContractFilterer) WatchOwnershipTransferRequested(opts *b }), nil } -func (_ARMContract *ARMContractFilterer) ParseOwnershipTransferRequested(log types.Log) (*ARMContractOwnershipTransferRequested, error) { - event := new(ARMContractOwnershipTransferRequested) - if err := _ARMContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseOwnershipTransferRequested(log types.Log) (*RMNContractOwnershipTransferRequested, error) { + event := new(RMNContractOwnershipTransferRequested) + if err := _RMNContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractOwnershipTransferredIterator struct { - Event *ARMContractOwnershipTransferred +type RMNContractOwnershipTransferredIterator struct { + Event *RMNContractOwnershipTransferred contract *bind.BoundContract event string @@ -1417,7 +1417,7 @@ type ARMContractOwnershipTransferredIterator struct { fail error } -func (it *ARMContractOwnershipTransferredIterator) Next() bool { +func (it *RMNContractOwnershipTransferredIterator) Next() bool { if it.fail != nil { return false @@ -1426,7 +1426,7 @@ func (it *ARMContractOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractOwnershipTransferred) + it.Event = new(RMNContractOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1441,7 +1441,7 @@ func (it *ARMContractOwnershipTransferredIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractOwnershipTransferred) + it.Event = new(RMNContractOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1456,22 +1456,22 @@ func (it *ARMContractOwnershipTransferredIterator) Next() bool { } } -func (it *ARMContractOwnershipTransferredIterator) Error() error { +func (it *RMNContractOwnershipTransferredIterator) Error() error { return it.fail } -func (it *ARMContractOwnershipTransferredIterator) Close() error { +func (it *RMNContractOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractOwnershipTransferred struct { +type RMNContractOwnershipTransferred struct { From common.Address To common.Address Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMContractOwnershipTransferredIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RMNContractOwnershipTransferredIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1482,14 +1482,14 @@ func (_ARMContract *ARMContractFilterer) FilterOwnershipTransferred(opts *bind.F toRule = append(toRule, toItem) } - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } - return &ARMContractOwnershipTransferredIterator{contract: _ARMContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &RMNContractOwnershipTransferredIterator{contract: _RMNContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ARMContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *RMNContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1500,7 +1500,7 @@ func (_ARMContract *ARMContractFilterer) WatchOwnershipTransferred(opts *bind.Wa toRule = append(toRule, toItem) } - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } @@ -1510,8 +1510,8 @@ func (_ARMContract *ARMContractFilterer) WatchOwnershipTransferred(opts *bind.Wa select { case log := <-logs: - event := new(ARMContractOwnershipTransferred) - if err := _ARMContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(RMNContractOwnershipTransferred) + if err := _RMNContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -1532,17 +1532,17 @@ func (_ARMContract *ARMContractFilterer) WatchOwnershipTransferred(opts *bind.Wa }), nil } -func (_ARMContract *ARMContractFilterer) ParseOwnershipTransferred(log types.Log) (*ARMContractOwnershipTransferred, error) { - event := new(ARMContractOwnershipTransferred) - if err := _ARMContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseOwnershipTransferred(log types.Log) (*RMNContractOwnershipTransferred, error) { + event := new(RMNContractOwnershipTransferred) + if err := _RMNContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractPermaBlessedCommitStoreAddedIterator struct { - Event *ARMContractPermaBlessedCommitStoreAdded +type RMNContractPermaBlessedCommitStoreAddedIterator struct { + Event *RMNContractPermaBlessedCommitStoreAdded contract *bind.BoundContract event string @@ -1553,7 +1553,7 @@ type ARMContractPermaBlessedCommitStoreAddedIterator struct { fail error } -func (it *ARMContractPermaBlessedCommitStoreAddedIterator) Next() bool { +func (it *RMNContractPermaBlessedCommitStoreAddedIterator) Next() bool { if it.fail != nil { return false @@ -1562,7 +1562,7 @@ func (it *ARMContractPermaBlessedCommitStoreAddedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractPermaBlessedCommitStoreAdded) + it.Event = new(RMNContractPermaBlessedCommitStoreAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1577,7 +1577,7 @@ func (it *ARMContractPermaBlessedCommitStoreAddedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractPermaBlessedCommitStoreAdded) + it.Event = new(RMNContractPermaBlessedCommitStoreAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1592,32 +1592,32 @@ func (it *ARMContractPermaBlessedCommitStoreAddedIterator) Next() bool { } } -func (it *ARMContractPermaBlessedCommitStoreAddedIterator) Error() error { +func (it *RMNContractPermaBlessedCommitStoreAddedIterator) Error() error { return it.fail } -func (it *ARMContractPermaBlessedCommitStoreAddedIterator) Close() error { +func (it *RMNContractPermaBlessedCommitStoreAddedIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractPermaBlessedCommitStoreAdded struct { +type RMNContractPermaBlessedCommitStoreAdded struct { CommitStore common.Address Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterPermaBlessedCommitStoreAdded(opts *bind.FilterOpts) (*ARMContractPermaBlessedCommitStoreAddedIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterPermaBlessedCommitStoreAdded(opts *bind.FilterOpts) (*RMNContractPermaBlessedCommitStoreAddedIterator, error) { - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "PermaBlessedCommitStoreAdded") + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "PermaBlessedCommitStoreAdded") if err != nil { return nil, err } - return &ARMContractPermaBlessedCommitStoreAddedIterator{contract: _ARMContract.contract, event: "PermaBlessedCommitStoreAdded", logs: logs, sub: sub}, nil + return &RMNContractPermaBlessedCommitStoreAddedIterator{contract: _RMNContract.contract, event: "PermaBlessedCommitStoreAdded", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchPermaBlessedCommitStoreAdded(opts *bind.WatchOpts, sink chan<- *ARMContractPermaBlessedCommitStoreAdded) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchPermaBlessedCommitStoreAdded(opts *bind.WatchOpts, sink chan<- *RMNContractPermaBlessedCommitStoreAdded) (event.Subscription, error) { - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "PermaBlessedCommitStoreAdded") + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "PermaBlessedCommitStoreAdded") if err != nil { return nil, err } @@ -1627,8 +1627,8 @@ func (_ARMContract *ARMContractFilterer) WatchPermaBlessedCommitStoreAdded(opts select { case log := <-logs: - event := new(ARMContractPermaBlessedCommitStoreAdded) - if err := _ARMContract.contract.UnpackLog(event, "PermaBlessedCommitStoreAdded", log); err != nil { + event := new(RMNContractPermaBlessedCommitStoreAdded) + if err := _RMNContract.contract.UnpackLog(event, "PermaBlessedCommitStoreAdded", log); err != nil { return err } event.Raw = log @@ -1649,17 +1649,17 @@ func (_ARMContract *ARMContractFilterer) WatchPermaBlessedCommitStoreAdded(opts }), nil } -func (_ARMContract *ARMContractFilterer) ParsePermaBlessedCommitStoreAdded(log types.Log) (*ARMContractPermaBlessedCommitStoreAdded, error) { - event := new(ARMContractPermaBlessedCommitStoreAdded) - if err := _ARMContract.contract.UnpackLog(event, "PermaBlessedCommitStoreAdded", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParsePermaBlessedCommitStoreAdded(log types.Log) (*RMNContractPermaBlessedCommitStoreAdded, error) { + event := new(RMNContractPermaBlessedCommitStoreAdded) + if err := _RMNContract.contract.UnpackLog(event, "PermaBlessedCommitStoreAdded", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractPermaBlessedCommitStoreRemovedIterator struct { - Event *ARMContractPermaBlessedCommitStoreRemoved +type RMNContractPermaBlessedCommitStoreRemovedIterator struct { + Event *RMNContractPermaBlessedCommitStoreRemoved contract *bind.BoundContract event string @@ -1670,7 +1670,7 @@ type ARMContractPermaBlessedCommitStoreRemovedIterator struct { fail error } -func (it *ARMContractPermaBlessedCommitStoreRemovedIterator) Next() bool { +func (it *RMNContractPermaBlessedCommitStoreRemovedIterator) Next() bool { if it.fail != nil { return false @@ -1679,7 +1679,7 @@ func (it *ARMContractPermaBlessedCommitStoreRemovedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractPermaBlessedCommitStoreRemoved) + it.Event = new(RMNContractPermaBlessedCommitStoreRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1694,7 +1694,7 @@ func (it *ARMContractPermaBlessedCommitStoreRemovedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractPermaBlessedCommitStoreRemoved) + it.Event = new(RMNContractPermaBlessedCommitStoreRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1709,32 +1709,32 @@ func (it *ARMContractPermaBlessedCommitStoreRemovedIterator) Next() bool { } } -func (it *ARMContractPermaBlessedCommitStoreRemovedIterator) Error() error { +func (it *RMNContractPermaBlessedCommitStoreRemovedIterator) Error() error { return it.fail } -func (it *ARMContractPermaBlessedCommitStoreRemovedIterator) Close() error { +func (it *RMNContractPermaBlessedCommitStoreRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractPermaBlessedCommitStoreRemoved struct { +type RMNContractPermaBlessedCommitStoreRemoved struct { CommitStore common.Address Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterPermaBlessedCommitStoreRemoved(opts *bind.FilterOpts) (*ARMContractPermaBlessedCommitStoreRemovedIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterPermaBlessedCommitStoreRemoved(opts *bind.FilterOpts) (*RMNContractPermaBlessedCommitStoreRemovedIterator, error) { - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "PermaBlessedCommitStoreRemoved") + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "PermaBlessedCommitStoreRemoved") if err != nil { return nil, err } - return &ARMContractPermaBlessedCommitStoreRemovedIterator{contract: _ARMContract.contract, event: "PermaBlessedCommitStoreRemoved", logs: logs, sub: sub}, nil + return &RMNContractPermaBlessedCommitStoreRemovedIterator{contract: _RMNContract.contract, event: "PermaBlessedCommitStoreRemoved", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchPermaBlessedCommitStoreRemoved(opts *bind.WatchOpts, sink chan<- *ARMContractPermaBlessedCommitStoreRemoved) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchPermaBlessedCommitStoreRemoved(opts *bind.WatchOpts, sink chan<- *RMNContractPermaBlessedCommitStoreRemoved) (event.Subscription, error) { - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "PermaBlessedCommitStoreRemoved") + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "PermaBlessedCommitStoreRemoved") if err != nil { return nil, err } @@ -1744,8 +1744,8 @@ func (_ARMContract *ARMContractFilterer) WatchPermaBlessedCommitStoreRemoved(opt select { case log := <-logs: - event := new(ARMContractPermaBlessedCommitStoreRemoved) - if err := _ARMContract.contract.UnpackLog(event, "PermaBlessedCommitStoreRemoved", log); err != nil { + event := new(RMNContractPermaBlessedCommitStoreRemoved) + if err := _RMNContract.contract.UnpackLog(event, "PermaBlessedCommitStoreRemoved", log); err != nil { return err } event.Raw = log @@ -1766,17 +1766,17 @@ func (_ARMContract *ARMContractFilterer) WatchPermaBlessedCommitStoreRemoved(opt }), nil } -func (_ARMContract *ARMContractFilterer) ParsePermaBlessedCommitStoreRemoved(log types.Log) (*ARMContractPermaBlessedCommitStoreRemoved, error) { - event := new(ARMContractPermaBlessedCommitStoreRemoved) - if err := _ARMContract.contract.UnpackLog(event, "PermaBlessedCommitStoreRemoved", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParsePermaBlessedCommitStoreRemoved(log types.Log) (*RMNContractPermaBlessedCommitStoreRemoved, error) { + event := new(RMNContractPermaBlessedCommitStoreRemoved) + if err := _RMNContract.contract.UnpackLog(event, "PermaBlessedCommitStoreRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractSkippedUnvoteToCurseIterator struct { - Event *ARMContractSkippedUnvoteToCurse +type RMNContractSkippedUnvoteToCurseIterator struct { + Event *RMNContractSkippedUnvoteToCurse contract *bind.BoundContract event string @@ -1787,7 +1787,7 @@ type ARMContractSkippedUnvoteToCurseIterator struct { fail error } -func (it *ARMContractSkippedUnvoteToCurseIterator) Next() bool { +func (it *RMNContractSkippedUnvoteToCurseIterator) Next() bool { if it.fail != nil { return false @@ -1796,7 +1796,7 @@ func (it *ARMContractSkippedUnvoteToCurseIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractSkippedUnvoteToCurse) + it.Event = new(RMNContractSkippedUnvoteToCurse) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1811,7 +1811,7 @@ func (it *ARMContractSkippedUnvoteToCurseIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractSkippedUnvoteToCurse) + it.Event = new(RMNContractSkippedUnvoteToCurse) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1826,16 +1826,16 @@ func (it *ARMContractSkippedUnvoteToCurseIterator) Next() bool { } } -func (it *ARMContractSkippedUnvoteToCurseIterator) Error() error { +func (it *RMNContractSkippedUnvoteToCurseIterator) Error() error { return it.fail } -func (it *ARMContractSkippedUnvoteToCurseIterator) Close() error { +func (it *RMNContractSkippedUnvoteToCurseIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractSkippedUnvoteToCurse struct { +type RMNContractSkippedUnvoteToCurse struct { Voter common.Address Subject [16]byte OnchainCursesHash [28]byte @@ -1843,28 +1843,28 @@ type ARMContractSkippedUnvoteToCurse struct { Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterSkippedUnvoteToCurse(opts *bind.FilterOpts, voter []common.Address) (*ARMContractSkippedUnvoteToCurseIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterSkippedUnvoteToCurse(opts *bind.FilterOpts, voter []common.Address) (*RMNContractSkippedUnvoteToCurseIterator, error) { var voterRule []interface{} for _, voterItem := range voter { voterRule = append(voterRule, voterItem) } - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "SkippedUnvoteToCurse", voterRule) + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "SkippedUnvoteToCurse", voterRule) if err != nil { return nil, err } - return &ARMContractSkippedUnvoteToCurseIterator{contract: _ARMContract.contract, event: "SkippedUnvoteToCurse", logs: logs, sub: sub}, nil + return &RMNContractSkippedUnvoteToCurseIterator{contract: _RMNContract.contract, event: "SkippedUnvoteToCurse", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchSkippedUnvoteToCurse(opts *bind.WatchOpts, sink chan<- *ARMContractSkippedUnvoteToCurse, voter []common.Address) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchSkippedUnvoteToCurse(opts *bind.WatchOpts, sink chan<- *RMNContractSkippedUnvoteToCurse, voter []common.Address) (event.Subscription, error) { var voterRule []interface{} for _, voterItem := range voter { voterRule = append(voterRule, voterItem) } - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "SkippedUnvoteToCurse", voterRule) + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "SkippedUnvoteToCurse", voterRule) if err != nil { return nil, err } @@ -1874,8 +1874,8 @@ func (_ARMContract *ARMContractFilterer) WatchSkippedUnvoteToCurse(opts *bind.Wa select { case log := <-logs: - event := new(ARMContractSkippedUnvoteToCurse) - if err := _ARMContract.contract.UnpackLog(event, "SkippedUnvoteToCurse", log); err != nil { + event := new(RMNContractSkippedUnvoteToCurse) + if err := _RMNContract.contract.UnpackLog(event, "SkippedUnvoteToCurse", log); err != nil { return err } event.Raw = log @@ -1896,17 +1896,17 @@ func (_ARMContract *ARMContractFilterer) WatchSkippedUnvoteToCurse(opts *bind.Wa }), nil } -func (_ARMContract *ARMContractFilterer) ParseSkippedUnvoteToCurse(log types.Log) (*ARMContractSkippedUnvoteToCurse, error) { - event := new(ARMContractSkippedUnvoteToCurse) - if err := _ARMContract.contract.UnpackLog(event, "SkippedUnvoteToCurse", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseSkippedUnvoteToCurse(log types.Log) (*RMNContractSkippedUnvoteToCurse, error) { + event := new(RMNContractSkippedUnvoteToCurse) + if err := _RMNContract.contract.UnpackLog(event, "SkippedUnvoteToCurse", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractTaggedRootBlessVotesResetIterator struct { - Event *ARMContractTaggedRootBlessVotesReset +type RMNContractTaggedRootBlessVotesResetIterator struct { + Event *RMNContractTaggedRootBlessVotesReset contract *bind.BoundContract event string @@ -1917,7 +1917,7 @@ type ARMContractTaggedRootBlessVotesResetIterator struct { fail error } -func (it *ARMContractTaggedRootBlessVotesResetIterator) Next() bool { +func (it *RMNContractTaggedRootBlessVotesResetIterator) Next() bool { if it.fail != nil { return false @@ -1926,7 +1926,7 @@ func (it *ARMContractTaggedRootBlessVotesResetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractTaggedRootBlessVotesReset) + it.Event = new(RMNContractTaggedRootBlessVotesReset) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1941,7 +1941,7 @@ func (it *ARMContractTaggedRootBlessVotesResetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractTaggedRootBlessVotesReset) + it.Event = new(RMNContractTaggedRootBlessVotesReset) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1956,44 +1956,44 @@ func (it *ARMContractTaggedRootBlessVotesResetIterator) Next() bool { } } -func (it *ARMContractTaggedRootBlessVotesResetIterator) Error() error { +func (it *RMNContractTaggedRootBlessVotesResetIterator) Error() error { return it.fail } -func (it *ARMContractTaggedRootBlessVotesResetIterator) Close() error { +func (it *RMNContractTaggedRootBlessVotesResetIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractTaggedRootBlessVotesReset struct { +type RMNContractTaggedRootBlessVotesReset struct { ConfigVersion uint32 TaggedRoot IRMNTaggedRoot WasBlessed bool Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterTaggedRootBlessVotesReset(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractTaggedRootBlessVotesResetIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterTaggedRootBlessVotesReset(opts *bind.FilterOpts, configVersion []uint32) (*RMNContractTaggedRootBlessVotesResetIterator, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { configVersionRule = append(configVersionRule, configVersionItem) } - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "TaggedRootBlessVotesReset", configVersionRule) + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "TaggedRootBlessVotesReset", configVersionRule) if err != nil { return nil, err } - return &ARMContractTaggedRootBlessVotesResetIterator{contract: _ARMContract.contract, event: "TaggedRootBlessVotesReset", logs: logs, sub: sub}, nil + return &RMNContractTaggedRootBlessVotesResetIterator{contract: _RMNContract.contract, event: "TaggedRootBlessVotesReset", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchTaggedRootBlessVotesReset(opts *bind.WatchOpts, sink chan<- *ARMContractTaggedRootBlessVotesReset, configVersion []uint32) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchTaggedRootBlessVotesReset(opts *bind.WatchOpts, sink chan<- *RMNContractTaggedRootBlessVotesReset, configVersion []uint32) (event.Subscription, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { configVersionRule = append(configVersionRule, configVersionItem) } - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "TaggedRootBlessVotesReset", configVersionRule) + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "TaggedRootBlessVotesReset", configVersionRule) if err != nil { return nil, err } @@ -2003,8 +2003,8 @@ func (_ARMContract *ARMContractFilterer) WatchTaggedRootBlessVotesReset(opts *bi select { case log := <-logs: - event := new(ARMContractTaggedRootBlessVotesReset) - if err := _ARMContract.contract.UnpackLog(event, "TaggedRootBlessVotesReset", log); err != nil { + event := new(RMNContractTaggedRootBlessVotesReset) + if err := _RMNContract.contract.UnpackLog(event, "TaggedRootBlessVotesReset", log); err != nil { return err } event.Raw = log @@ -2025,17 +2025,17 @@ func (_ARMContract *ARMContractFilterer) WatchTaggedRootBlessVotesReset(opts *bi }), nil } -func (_ARMContract *ARMContractFilterer) ParseTaggedRootBlessVotesReset(log types.Log) (*ARMContractTaggedRootBlessVotesReset, error) { - event := new(ARMContractTaggedRootBlessVotesReset) - if err := _ARMContract.contract.UnpackLog(event, "TaggedRootBlessVotesReset", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseTaggedRootBlessVotesReset(log types.Log) (*RMNContractTaggedRootBlessVotesReset, error) { + event := new(RMNContractTaggedRootBlessVotesReset) + if err := _RMNContract.contract.UnpackLog(event, "TaggedRootBlessVotesReset", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractTaggedRootBlessedIterator struct { - Event *ARMContractTaggedRootBlessed +type RMNContractTaggedRootBlessedIterator struct { + Event *RMNContractTaggedRootBlessed contract *bind.BoundContract event string @@ -2046,7 +2046,7 @@ type ARMContractTaggedRootBlessedIterator struct { fail error } -func (it *ARMContractTaggedRootBlessedIterator) Next() bool { +func (it *RMNContractTaggedRootBlessedIterator) Next() bool { if it.fail != nil { return false @@ -2055,7 +2055,7 @@ func (it *ARMContractTaggedRootBlessedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractTaggedRootBlessed) + it.Event = new(RMNContractTaggedRootBlessed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2070,7 +2070,7 @@ func (it *ARMContractTaggedRootBlessedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractTaggedRootBlessed) + it.Event = new(RMNContractTaggedRootBlessed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2085,44 +2085,44 @@ func (it *ARMContractTaggedRootBlessedIterator) Next() bool { } } -func (it *ARMContractTaggedRootBlessedIterator) Error() error { +func (it *RMNContractTaggedRootBlessedIterator) Error() error { return it.fail } -func (it *ARMContractTaggedRootBlessedIterator) Close() error { +func (it *RMNContractTaggedRootBlessedIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractTaggedRootBlessed struct { +type RMNContractTaggedRootBlessed struct { ConfigVersion uint32 TaggedRoot IRMNTaggedRoot AccumulatedWeight uint16 Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterTaggedRootBlessed(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractTaggedRootBlessedIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterTaggedRootBlessed(opts *bind.FilterOpts, configVersion []uint32) (*RMNContractTaggedRootBlessedIterator, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { configVersionRule = append(configVersionRule, configVersionItem) } - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "TaggedRootBlessed", configVersionRule) + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "TaggedRootBlessed", configVersionRule) if err != nil { return nil, err } - return &ARMContractTaggedRootBlessedIterator{contract: _ARMContract.contract, event: "TaggedRootBlessed", logs: logs, sub: sub}, nil + return &RMNContractTaggedRootBlessedIterator{contract: _RMNContract.contract, event: "TaggedRootBlessed", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchTaggedRootBlessed(opts *bind.WatchOpts, sink chan<- *ARMContractTaggedRootBlessed, configVersion []uint32) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchTaggedRootBlessed(opts *bind.WatchOpts, sink chan<- *RMNContractTaggedRootBlessed, configVersion []uint32) (event.Subscription, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { configVersionRule = append(configVersionRule, configVersionItem) } - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "TaggedRootBlessed", configVersionRule) + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "TaggedRootBlessed", configVersionRule) if err != nil { return nil, err } @@ -2132,8 +2132,8 @@ func (_ARMContract *ARMContractFilterer) WatchTaggedRootBlessed(opts *bind.Watch select { case log := <-logs: - event := new(ARMContractTaggedRootBlessed) - if err := _ARMContract.contract.UnpackLog(event, "TaggedRootBlessed", log); err != nil { + event := new(RMNContractTaggedRootBlessed) + if err := _RMNContract.contract.UnpackLog(event, "TaggedRootBlessed", log); err != nil { return err } event.Raw = log @@ -2154,17 +2154,17 @@ func (_ARMContract *ARMContractFilterer) WatchTaggedRootBlessed(opts *bind.Watch }), nil } -func (_ARMContract *ARMContractFilterer) ParseTaggedRootBlessed(log types.Log) (*ARMContractTaggedRootBlessed, error) { - event := new(ARMContractTaggedRootBlessed) - if err := _ARMContract.contract.UnpackLog(event, "TaggedRootBlessed", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseTaggedRootBlessed(log types.Log) (*RMNContractTaggedRootBlessed, error) { + event := new(RMNContractTaggedRootBlessed) + if err := _RMNContract.contract.UnpackLog(event, "TaggedRootBlessed", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractUnvotedToCurseIterator struct { - Event *ARMContractUnvotedToCurse +type RMNContractUnvotedToCurseIterator struct { + Event *RMNContractUnvotedToCurse contract *bind.BoundContract event string @@ -2175,7 +2175,7 @@ type ARMContractUnvotedToCurseIterator struct { fail error } -func (it *ARMContractUnvotedToCurseIterator) Next() bool { +func (it *RMNContractUnvotedToCurseIterator) Next() bool { if it.fail != nil { return false @@ -2184,7 +2184,7 @@ func (it *ARMContractUnvotedToCurseIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractUnvotedToCurse) + it.Event = new(RMNContractUnvotedToCurse) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2199,7 +2199,7 @@ func (it *ARMContractUnvotedToCurseIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractUnvotedToCurse) + it.Event = new(RMNContractUnvotedToCurse) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2214,16 +2214,16 @@ func (it *ARMContractUnvotedToCurseIterator) Next() bool { } } -func (it *ARMContractUnvotedToCurseIterator) Error() error { +func (it *RMNContractUnvotedToCurseIterator) Error() error { return it.fail } -func (it *ARMContractUnvotedToCurseIterator) Close() error { +func (it *RMNContractUnvotedToCurseIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractUnvotedToCurse struct { +type RMNContractUnvotedToCurse struct { ConfigVersion uint32 Voter common.Address Subject [16]byte @@ -2233,7 +2233,7 @@ type ARMContractUnvotedToCurse struct { Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterUnvotedToCurse(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractUnvotedToCurseIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterUnvotedToCurse(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*RMNContractUnvotedToCurseIterator, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { @@ -2244,14 +2244,14 @@ func (_ARMContract *ARMContractFilterer) FilterUnvotedToCurse(opts *bind.FilterO voterRule = append(voterRule, voterItem) } - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "UnvotedToCurse", configVersionRule, voterRule) + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "UnvotedToCurse", configVersionRule, voterRule) if err != nil { return nil, err } - return &ARMContractUnvotedToCurseIterator{contract: _ARMContract.contract, event: "UnvotedToCurse", logs: logs, sub: sub}, nil + return &RMNContractUnvotedToCurseIterator{contract: _RMNContract.contract, event: "UnvotedToCurse", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchUnvotedToCurse(opts *bind.WatchOpts, sink chan<- *ARMContractUnvotedToCurse, configVersion []uint32, voter []common.Address) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchUnvotedToCurse(opts *bind.WatchOpts, sink chan<- *RMNContractUnvotedToCurse, configVersion []uint32, voter []common.Address) (event.Subscription, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { @@ -2262,7 +2262,7 @@ func (_ARMContract *ARMContractFilterer) WatchUnvotedToCurse(opts *bind.WatchOpt voterRule = append(voterRule, voterItem) } - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "UnvotedToCurse", configVersionRule, voterRule) + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "UnvotedToCurse", configVersionRule, voterRule) if err != nil { return nil, err } @@ -2272,8 +2272,8 @@ func (_ARMContract *ARMContractFilterer) WatchUnvotedToCurse(opts *bind.WatchOpt select { case log := <-logs: - event := new(ARMContractUnvotedToCurse) - if err := _ARMContract.contract.UnpackLog(event, "UnvotedToCurse", log); err != nil { + event := new(RMNContractUnvotedToCurse) + if err := _RMNContract.contract.UnpackLog(event, "UnvotedToCurse", log); err != nil { return err } event.Raw = log @@ -2294,17 +2294,17 @@ func (_ARMContract *ARMContractFilterer) WatchUnvotedToCurse(opts *bind.WatchOpt }), nil } -func (_ARMContract *ARMContractFilterer) ParseUnvotedToCurse(log types.Log) (*ARMContractUnvotedToCurse, error) { - event := new(ARMContractUnvotedToCurse) - if err := _ARMContract.contract.UnpackLog(event, "UnvotedToCurse", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseUnvotedToCurse(log types.Log) (*RMNContractUnvotedToCurse, error) { + event := new(RMNContractUnvotedToCurse) + if err := _RMNContract.contract.UnpackLog(event, "UnvotedToCurse", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractVotedToBlessIterator struct { - Event *ARMContractVotedToBless +type RMNContractVotedToBlessIterator struct { + Event *RMNContractVotedToBless contract *bind.BoundContract event string @@ -2315,7 +2315,7 @@ type ARMContractVotedToBlessIterator struct { fail error } -func (it *ARMContractVotedToBlessIterator) Next() bool { +func (it *RMNContractVotedToBlessIterator) Next() bool { if it.fail != nil { return false @@ -2324,7 +2324,7 @@ func (it *ARMContractVotedToBlessIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractVotedToBless) + it.Event = new(RMNContractVotedToBless) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2339,7 +2339,7 @@ func (it *ARMContractVotedToBlessIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractVotedToBless) + it.Event = new(RMNContractVotedToBless) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2354,16 +2354,16 @@ func (it *ARMContractVotedToBlessIterator) Next() bool { } } -func (it *ARMContractVotedToBlessIterator) Error() error { +func (it *RMNContractVotedToBlessIterator) Error() error { return it.fail } -func (it *ARMContractVotedToBlessIterator) Close() error { +func (it *RMNContractVotedToBlessIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractVotedToBless struct { +type RMNContractVotedToBless struct { ConfigVersion uint32 Voter common.Address TaggedRoot IRMNTaggedRoot @@ -2371,7 +2371,7 @@ type ARMContractVotedToBless struct { Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterVotedToBless(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractVotedToBlessIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterVotedToBless(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*RMNContractVotedToBlessIterator, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { @@ -2382,14 +2382,14 @@ func (_ARMContract *ARMContractFilterer) FilterVotedToBless(opts *bind.FilterOpt voterRule = append(voterRule, voterItem) } - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "VotedToBless", configVersionRule, voterRule) + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "VotedToBless", configVersionRule, voterRule) if err != nil { return nil, err } - return &ARMContractVotedToBlessIterator{contract: _ARMContract.contract, event: "VotedToBless", logs: logs, sub: sub}, nil + return &RMNContractVotedToBlessIterator{contract: _RMNContract.contract, event: "VotedToBless", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchVotedToBless(opts *bind.WatchOpts, sink chan<- *ARMContractVotedToBless, configVersion []uint32, voter []common.Address) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchVotedToBless(opts *bind.WatchOpts, sink chan<- *RMNContractVotedToBless, configVersion []uint32, voter []common.Address) (event.Subscription, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { @@ -2400,7 +2400,7 @@ func (_ARMContract *ARMContractFilterer) WatchVotedToBless(opts *bind.WatchOpts, voterRule = append(voterRule, voterItem) } - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "VotedToBless", configVersionRule, voterRule) + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "VotedToBless", configVersionRule, voterRule) if err != nil { return nil, err } @@ -2410,8 +2410,8 @@ func (_ARMContract *ARMContractFilterer) WatchVotedToBless(opts *bind.WatchOpts, select { case log := <-logs: - event := new(ARMContractVotedToBless) - if err := _ARMContract.contract.UnpackLog(event, "VotedToBless", log); err != nil { + event := new(RMNContractVotedToBless) + if err := _RMNContract.contract.UnpackLog(event, "VotedToBless", log); err != nil { return err } event.Raw = log @@ -2432,17 +2432,17 @@ func (_ARMContract *ARMContractFilterer) WatchVotedToBless(opts *bind.WatchOpts, }), nil } -func (_ARMContract *ARMContractFilterer) ParseVotedToBless(log types.Log) (*ARMContractVotedToBless, error) { - event := new(ARMContractVotedToBless) - if err := _ARMContract.contract.UnpackLog(event, "VotedToBless", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseVotedToBless(log types.Log) (*RMNContractVotedToBless, error) { + event := new(RMNContractVotedToBless) + if err := _RMNContract.contract.UnpackLog(event, "VotedToBless", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMContractVotedToCurseIterator struct { - Event *ARMContractVotedToCurse +type RMNContractVotedToCurseIterator struct { + Event *RMNContractVotedToCurse contract *bind.BoundContract event string @@ -2453,7 +2453,7 @@ type ARMContractVotedToCurseIterator struct { fail error } -func (it *ARMContractVotedToCurseIterator) Next() bool { +func (it *RMNContractVotedToCurseIterator) Next() bool { if it.fail != nil { return false @@ -2462,7 +2462,7 @@ func (it *ARMContractVotedToCurseIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMContractVotedToCurse) + it.Event = new(RMNContractVotedToCurse) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2477,7 +2477,7 @@ func (it *ARMContractVotedToCurseIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMContractVotedToCurse) + it.Event = new(RMNContractVotedToCurse) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2492,16 +2492,16 @@ func (it *ARMContractVotedToCurseIterator) Next() bool { } } -func (it *ARMContractVotedToCurseIterator) Error() error { +func (it *RMNContractVotedToCurseIterator) Error() error { return it.fail } -func (it *ARMContractVotedToCurseIterator) Close() error { +func (it *RMNContractVotedToCurseIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMContractVotedToCurse struct { +type RMNContractVotedToCurse struct { ConfigVersion uint32 Voter common.Address Subject [16]byte @@ -2513,7 +2513,7 @@ type ARMContractVotedToCurse struct { Raw types.Log } -func (_ARMContract *ARMContractFilterer) FilterVotedToCurse(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractVotedToCurseIterator, error) { +func (_RMNContract *RMNContractFilterer) FilterVotedToCurse(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*RMNContractVotedToCurseIterator, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { @@ -2524,14 +2524,14 @@ func (_ARMContract *ARMContractFilterer) FilterVotedToCurse(opts *bind.FilterOpt voterRule = append(voterRule, voterItem) } - logs, sub, err := _ARMContract.contract.FilterLogs(opts, "VotedToCurse", configVersionRule, voterRule) + logs, sub, err := _RMNContract.contract.FilterLogs(opts, "VotedToCurse", configVersionRule, voterRule) if err != nil { return nil, err } - return &ARMContractVotedToCurseIterator{contract: _ARMContract.contract, event: "VotedToCurse", logs: logs, sub: sub}, nil + return &RMNContractVotedToCurseIterator{contract: _RMNContract.contract, event: "VotedToCurse", logs: logs, sub: sub}, nil } -func (_ARMContract *ARMContractFilterer) WatchVotedToCurse(opts *bind.WatchOpts, sink chan<- *ARMContractVotedToCurse, configVersion []uint32, voter []common.Address) (event.Subscription, error) { +func (_RMNContract *RMNContractFilterer) WatchVotedToCurse(opts *bind.WatchOpts, sink chan<- *RMNContractVotedToCurse, configVersion []uint32, voter []common.Address) (event.Subscription, error) { var configVersionRule []interface{} for _, configVersionItem := range configVersion { @@ -2542,7 +2542,7 @@ func (_ARMContract *ARMContractFilterer) WatchVotedToCurse(opts *bind.WatchOpts, voterRule = append(voterRule, voterItem) } - logs, sub, err := _ARMContract.contract.WatchLogs(opts, "VotedToCurse", configVersionRule, voterRule) + logs, sub, err := _RMNContract.contract.WatchLogs(opts, "VotedToCurse", configVersionRule, voterRule) if err != nil { return nil, err } @@ -2552,8 +2552,8 @@ func (_ARMContract *ARMContractFilterer) WatchVotedToCurse(opts *bind.WatchOpts, select { case log := <-logs: - event := new(ARMContractVotedToCurse) - if err := _ARMContract.contract.UnpackLog(event, "VotedToCurse", log); err != nil { + event := new(RMNContractVotedToCurse) + if err := _RMNContract.contract.UnpackLog(event, "VotedToCurse", log); err != nil { return err } event.Raw = log @@ -2574,9 +2574,9 @@ func (_ARMContract *ARMContractFilterer) WatchVotedToCurse(opts *bind.WatchOpts, }), nil } -func (_ARMContract *ARMContractFilterer) ParseVotedToCurse(log types.Log) (*ARMContractVotedToCurse, error) { - event := new(ARMContractVotedToCurse) - if err := _ARMContract.contract.UnpackLog(event, "VotedToCurse", log); err != nil { +func (_RMNContract *RMNContractFilterer) ParseVotedToCurse(log types.Log) (*RMNContractVotedToCurse, error) { + event := new(RMNContractVotedToCurse) + if err := _RMNContract.contract.UnpackLog(event, "VotedToCurse", log); err != nil { return nil, err } event.Raw = log @@ -2600,109 +2600,109 @@ type GetCurseProgress struct { Cursed bool } -func (_ARMContract *ARMContract) ParseLog(log types.Log) (generated.AbigenLog, error) { +func (_RMNContract *RMNContract) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _ARMContract.abi.Events["AlreadyBlessed"].ID: - return _ARMContract.ParseAlreadyBlessed(log) - case _ARMContract.abi.Events["AlreadyVotedToBless"].ID: - return _ARMContract.ParseAlreadyVotedToBless(log) - case _ARMContract.abi.Events["ConfigSet"].ID: - return _ARMContract.ParseConfigSet(log) - case _ARMContract.abi.Events["CurseLifted"].ID: - return _ARMContract.ParseCurseLifted(log) - case _ARMContract.abi.Events["Cursed"].ID: - return _ARMContract.ParseCursed(log) - case _ARMContract.abi.Events["OwnershipTransferRequested"].ID: - return _ARMContract.ParseOwnershipTransferRequested(log) - case _ARMContract.abi.Events["OwnershipTransferred"].ID: - return _ARMContract.ParseOwnershipTransferred(log) - case _ARMContract.abi.Events["PermaBlessedCommitStoreAdded"].ID: - return _ARMContract.ParsePermaBlessedCommitStoreAdded(log) - case _ARMContract.abi.Events["PermaBlessedCommitStoreRemoved"].ID: - return _ARMContract.ParsePermaBlessedCommitStoreRemoved(log) - case _ARMContract.abi.Events["SkippedUnvoteToCurse"].ID: - return _ARMContract.ParseSkippedUnvoteToCurse(log) - case _ARMContract.abi.Events["TaggedRootBlessVotesReset"].ID: - return _ARMContract.ParseTaggedRootBlessVotesReset(log) - case _ARMContract.abi.Events["TaggedRootBlessed"].ID: - return _ARMContract.ParseTaggedRootBlessed(log) - case _ARMContract.abi.Events["UnvotedToCurse"].ID: - return _ARMContract.ParseUnvotedToCurse(log) - case _ARMContract.abi.Events["VotedToBless"].ID: - return _ARMContract.ParseVotedToBless(log) - case _ARMContract.abi.Events["VotedToCurse"].ID: - return _ARMContract.ParseVotedToCurse(log) + case _RMNContract.abi.Events["AlreadyBlessed"].ID: + return _RMNContract.ParseAlreadyBlessed(log) + case _RMNContract.abi.Events["AlreadyVotedToBless"].ID: + return _RMNContract.ParseAlreadyVotedToBless(log) + case _RMNContract.abi.Events["ConfigSet"].ID: + return _RMNContract.ParseConfigSet(log) + case _RMNContract.abi.Events["CurseLifted"].ID: + return _RMNContract.ParseCurseLifted(log) + case _RMNContract.abi.Events["Cursed"].ID: + return _RMNContract.ParseCursed(log) + case _RMNContract.abi.Events["OwnershipTransferRequested"].ID: + return _RMNContract.ParseOwnershipTransferRequested(log) + case _RMNContract.abi.Events["OwnershipTransferred"].ID: + return _RMNContract.ParseOwnershipTransferred(log) + case _RMNContract.abi.Events["PermaBlessedCommitStoreAdded"].ID: + return _RMNContract.ParsePermaBlessedCommitStoreAdded(log) + case _RMNContract.abi.Events["PermaBlessedCommitStoreRemoved"].ID: + return _RMNContract.ParsePermaBlessedCommitStoreRemoved(log) + case _RMNContract.abi.Events["SkippedUnvoteToCurse"].ID: + return _RMNContract.ParseSkippedUnvoteToCurse(log) + case _RMNContract.abi.Events["TaggedRootBlessVotesReset"].ID: + return _RMNContract.ParseTaggedRootBlessVotesReset(log) + case _RMNContract.abi.Events["TaggedRootBlessed"].ID: + return _RMNContract.ParseTaggedRootBlessed(log) + case _RMNContract.abi.Events["UnvotedToCurse"].ID: + return _RMNContract.ParseUnvotedToCurse(log) + case _RMNContract.abi.Events["VotedToBless"].ID: + return _RMNContract.ParseVotedToBless(log) + case _RMNContract.abi.Events["VotedToCurse"].ID: + return _RMNContract.ParseVotedToCurse(log) default: return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) } } -func (ARMContractAlreadyBlessed) Topic() common.Hash { +func (RMNContractAlreadyBlessed) Topic() common.Hash { return common.HexToHash("0x274d6d5b916b0a53974b7ab86c844b97a2e03a60f658cd9a4b1c028b604d7bf1") } -func (ARMContractAlreadyVotedToBless) Topic() common.Hash { +func (RMNContractAlreadyVotedToBless) Topic() common.Hash { return common.HexToHash("0x6dfbb745226fa630aeb1b9557d17d508ddb789a04f0cb873ec16e58beb8beead") } -func (ARMContractConfigSet) Topic() common.Hash { +func (RMNContractConfigSet) Topic() common.Hash { return common.HexToHash("0x8c49fda8177c5c8c768eb39634bc6773695c7181711537b822451c12b2efd2a9") } -func (ARMContractCurseLifted) Topic() common.Hash { +func (RMNContractCurseLifted) Topic() common.Hash { return common.HexToHash("0x65d0e78c3625f0956f58610cf0fb157eaf627683258875ef29af2f71d25ac8fd") } -func (ARMContractCursed) Topic() common.Hash { +func (RMNContractCursed) Topic() common.Hash { return common.HexToHash("0xcfdbfd8ce9a56b5f7c202c0e102184d24f47ca87121dc165063fc4c290957bde") } -func (ARMContractOwnershipTransferRequested) Topic() common.Hash { +func (RMNContractOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } -func (ARMContractOwnershipTransferred) Topic() common.Hash { +func (RMNContractOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (ARMContractPermaBlessedCommitStoreAdded) Topic() common.Hash { +func (RMNContractPermaBlessedCommitStoreAdded) Topic() common.Hash { return common.HexToHash("0x66b4b4752c65ae8cd2f3a0a48c7dc8b2118c60d5ea15514992eb2ddf56c9cb15") } -func (ARMContractPermaBlessedCommitStoreRemoved) Topic() common.Hash { +func (RMNContractPermaBlessedCommitStoreRemoved) Topic() common.Hash { return common.HexToHash("0xdca892154bbc36d0c05ccd01b3d0411875cb1b841fcdeebb384e5d0d6eb06b44") } -func (ARMContractSkippedUnvoteToCurse) Topic() common.Hash { +func (RMNContractSkippedUnvoteToCurse) Topic() common.Hash { return common.HexToHash("0xbabb0d7099e6ca14a29fad2a2cfb4fda2bd30f97cb3c27e546174bfb4277c1cc") } -func (ARMContractTaggedRootBlessVotesReset) Topic() common.Hash { +func (RMNContractTaggedRootBlessVotesReset) Topic() common.Hash { return common.HexToHash("0x7d15a6eebaa019ea7d5b7d38937c51ebd3befbfdf51bb630a694fd28635bbcba") } -func (ARMContractTaggedRootBlessed) Topic() common.Hash { +func (RMNContractTaggedRootBlessed) Topic() common.Hash { return common.HexToHash("0x8257378aa73bf8e4ada848713526584a3dcee0fd3db3beed7397f7a7f5067cc9") } -func (ARMContractUnvotedToCurse) Topic() common.Hash { +func (RMNContractUnvotedToCurse) Topic() common.Hash { return common.HexToHash("0xa96a155bd67c927a6c056befbd979b78465e2b2f1276bf7d4e90a31d4f430aa8") } -func (ARMContractVotedToBless) Topic() common.Hash { +func (RMNContractVotedToBless) Topic() common.Hash { return common.HexToHash("0x2a08a2bd2798f0aae9a843f0f4ad4de488c1b3d5f04049940cfed736ad69fb97") } -func (ARMContractVotedToCurse) Topic() common.Hash { +func (RMNContractVotedToCurse) Topic() common.Hash { return common.HexToHash("0x8137bc8a8d712aaa27bfc6506d5566ac405618bd53f9831b8ca6b6fe5442ee7a") } -func (_ARMContract *ARMContract) Address() common.Address { - return _ARMContract.address +func (_RMNContract *RMNContract) Address() common.Address { + return _RMNContract.address } -type ARMContractInterface interface { +type RMNContractInterface interface { GetBlessProgress(opts *bind.CallOpts, taggedRoot IRMNTaggedRoot) (GetBlessProgress, error) @@ -2753,95 +2753,95 @@ type ARMContractInterface interface { VoteToCurse(opts *bind.TransactOpts, curseId [16]byte, subjects [][16]byte) (*types.Transaction, error) - FilterAlreadyBlessed(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractAlreadyBlessedIterator, error) + FilterAlreadyBlessed(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*RMNContractAlreadyBlessedIterator, error) - WatchAlreadyBlessed(opts *bind.WatchOpts, sink chan<- *ARMContractAlreadyBlessed, configVersion []uint32, voter []common.Address) (event.Subscription, error) + WatchAlreadyBlessed(opts *bind.WatchOpts, sink chan<- *RMNContractAlreadyBlessed, configVersion []uint32, voter []common.Address) (event.Subscription, error) - ParseAlreadyBlessed(log types.Log) (*ARMContractAlreadyBlessed, error) + ParseAlreadyBlessed(log types.Log) (*RMNContractAlreadyBlessed, error) - FilterAlreadyVotedToBless(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractAlreadyVotedToBlessIterator, error) + FilterAlreadyVotedToBless(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*RMNContractAlreadyVotedToBlessIterator, error) - WatchAlreadyVotedToBless(opts *bind.WatchOpts, sink chan<- *ARMContractAlreadyVotedToBless, configVersion []uint32, voter []common.Address) (event.Subscription, error) + WatchAlreadyVotedToBless(opts *bind.WatchOpts, sink chan<- *RMNContractAlreadyVotedToBless, configVersion []uint32, voter []common.Address) (event.Subscription, error) - ParseAlreadyVotedToBless(log types.Log) (*ARMContractAlreadyVotedToBless, error) + ParseAlreadyVotedToBless(log types.Log) (*RMNContractAlreadyVotedToBless, error) - FilterConfigSet(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractConfigSetIterator, error) + FilterConfigSet(opts *bind.FilterOpts, configVersion []uint32) (*RMNContractConfigSetIterator, error) - WatchConfigSet(opts *bind.WatchOpts, sink chan<- *ARMContractConfigSet, configVersion []uint32) (event.Subscription, error) + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *RMNContractConfigSet, configVersion []uint32) (event.Subscription, error) - ParseConfigSet(log types.Log) (*ARMContractConfigSet, error) + ParseConfigSet(log types.Log) (*RMNContractConfigSet, error) - FilterCurseLifted(opts *bind.FilterOpts) (*ARMContractCurseLiftedIterator, error) + FilterCurseLifted(opts *bind.FilterOpts) (*RMNContractCurseLiftedIterator, error) - WatchCurseLifted(opts *bind.WatchOpts, sink chan<- *ARMContractCurseLifted) (event.Subscription, error) + WatchCurseLifted(opts *bind.WatchOpts, sink chan<- *RMNContractCurseLifted) (event.Subscription, error) - ParseCurseLifted(log types.Log) (*ARMContractCurseLifted, error) + ParseCurseLifted(log types.Log) (*RMNContractCurseLifted, error) - FilterCursed(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractCursedIterator, error) + FilterCursed(opts *bind.FilterOpts, configVersion []uint32) (*RMNContractCursedIterator, error) - WatchCursed(opts *bind.WatchOpts, sink chan<- *ARMContractCursed, configVersion []uint32) (event.Subscription, error) + WatchCursed(opts *bind.WatchOpts, sink chan<- *RMNContractCursed, configVersion []uint32) (event.Subscription, error) - ParseCursed(log types.Log) (*ARMContractCursed, error) + ParseCursed(log types.Log) (*RMNContractCursed, error) - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMContractOwnershipTransferRequestedIterator, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RMNContractOwnershipTransferRequestedIterator, error) - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ARMContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *RMNContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - ParseOwnershipTransferRequested(log types.Log) (*ARMContractOwnershipTransferRequested, error) + ParseOwnershipTransferRequested(log types.Log) (*RMNContractOwnershipTransferRequested, error) - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMContractOwnershipTransferredIterator, error) + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RMNContractOwnershipTransferredIterator, error) - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ARMContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *RMNContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - ParseOwnershipTransferred(log types.Log) (*ARMContractOwnershipTransferred, error) + ParseOwnershipTransferred(log types.Log) (*RMNContractOwnershipTransferred, error) - FilterPermaBlessedCommitStoreAdded(opts *bind.FilterOpts) (*ARMContractPermaBlessedCommitStoreAddedIterator, error) + FilterPermaBlessedCommitStoreAdded(opts *bind.FilterOpts) (*RMNContractPermaBlessedCommitStoreAddedIterator, error) - WatchPermaBlessedCommitStoreAdded(opts *bind.WatchOpts, sink chan<- *ARMContractPermaBlessedCommitStoreAdded) (event.Subscription, error) + WatchPermaBlessedCommitStoreAdded(opts *bind.WatchOpts, sink chan<- *RMNContractPermaBlessedCommitStoreAdded) (event.Subscription, error) - ParsePermaBlessedCommitStoreAdded(log types.Log) (*ARMContractPermaBlessedCommitStoreAdded, error) + ParsePermaBlessedCommitStoreAdded(log types.Log) (*RMNContractPermaBlessedCommitStoreAdded, error) - FilterPermaBlessedCommitStoreRemoved(opts *bind.FilterOpts) (*ARMContractPermaBlessedCommitStoreRemovedIterator, error) + FilterPermaBlessedCommitStoreRemoved(opts *bind.FilterOpts) (*RMNContractPermaBlessedCommitStoreRemovedIterator, error) - WatchPermaBlessedCommitStoreRemoved(opts *bind.WatchOpts, sink chan<- *ARMContractPermaBlessedCommitStoreRemoved) (event.Subscription, error) + WatchPermaBlessedCommitStoreRemoved(opts *bind.WatchOpts, sink chan<- *RMNContractPermaBlessedCommitStoreRemoved) (event.Subscription, error) - ParsePermaBlessedCommitStoreRemoved(log types.Log) (*ARMContractPermaBlessedCommitStoreRemoved, error) + ParsePermaBlessedCommitStoreRemoved(log types.Log) (*RMNContractPermaBlessedCommitStoreRemoved, error) - FilterSkippedUnvoteToCurse(opts *bind.FilterOpts, voter []common.Address) (*ARMContractSkippedUnvoteToCurseIterator, error) + FilterSkippedUnvoteToCurse(opts *bind.FilterOpts, voter []common.Address) (*RMNContractSkippedUnvoteToCurseIterator, error) - WatchSkippedUnvoteToCurse(opts *bind.WatchOpts, sink chan<- *ARMContractSkippedUnvoteToCurse, voter []common.Address) (event.Subscription, error) + WatchSkippedUnvoteToCurse(opts *bind.WatchOpts, sink chan<- *RMNContractSkippedUnvoteToCurse, voter []common.Address) (event.Subscription, error) - ParseSkippedUnvoteToCurse(log types.Log) (*ARMContractSkippedUnvoteToCurse, error) + ParseSkippedUnvoteToCurse(log types.Log) (*RMNContractSkippedUnvoteToCurse, error) - FilterTaggedRootBlessVotesReset(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractTaggedRootBlessVotesResetIterator, error) + FilterTaggedRootBlessVotesReset(opts *bind.FilterOpts, configVersion []uint32) (*RMNContractTaggedRootBlessVotesResetIterator, error) - WatchTaggedRootBlessVotesReset(opts *bind.WatchOpts, sink chan<- *ARMContractTaggedRootBlessVotesReset, configVersion []uint32) (event.Subscription, error) + WatchTaggedRootBlessVotesReset(opts *bind.WatchOpts, sink chan<- *RMNContractTaggedRootBlessVotesReset, configVersion []uint32) (event.Subscription, error) - ParseTaggedRootBlessVotesReset(log types.Log) (*ARMContractTaggedRootBlessVotesReset, error) + ParseTaggedRootBlessVotesReset(log types.Log) (*RMNContractTaggedRootBlessVotesReset, error) - FilterTaggedRootBlessed(opts *bind.FilterOpts, configVersion []uint32) (*ARMContractTaggedRootBlessedIterator, error) + FilterTaggedRootBlessed(opts *bind.FilterOpts, configVersion []uint32) (*RMNContractTaggedRootBlessedIterator, error) - WatchTaggedRootBlessed(opts *bind.WatchOpts, sink chan<- *ARMContractTaggedRootBlessed, configVersion []uint32) (event.Subscription, error) + WatchTaggedRootBlessed(opts *bind.WatchOpts, sink chan<- *RMNContractTaggedRootBlessed, configVersion []uint32) (event.Subscription, error) - ParseTaggedRootBlessed(log types.Log) (*ARMContractTaggedRootBlessed, error) + ParseTaggedRootBlessed(log types.Log) (*RMNContractTaggedRootBlessed, error) - FilterUnvotedToCurse(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractUnvotedToCurseIterator, error) + FilterUnvotedToCurse(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*RMNContractUnvotedToCurseIterator, error) - WatchUnvotedToCurse(opts *bind.WatchOpts, sink chan<- *ARMContractUnvotedToCurse, configVersion []uint32, voter []common.Address) (event.Subscription, error) + WatchUnvotedToCurse(opts *bind.WatchOpts, sink chan<- *RMNContractUnvotedToCurse, configVersion []uint32, voter []common.Address) (event.Subscription, error) - ParseUnvotedToCurse(log types.Log) (*ARMContractUnvotedToCurse, error) + ParseUnvotedToCurse(log types.Log) (*RMNContractUnvotedToCurse, error) - FilterVotedToBless(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractVotedToBlessIterator, error) + FilterVotedToBless(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*RMNContractVotedToBlessIterator, error) - WatchVotedToBless(opts *bind.WatchOpts, sink chan<- *ARMContractVotedToBless, configVersion []uint32, voter []common.Address) (event.Subscription, error) + WatchVotedToBless(opts *bind.WatchOpts, sink chan<- *RMNContractVotedToBless, configVersion []uint32, voter []common.Address) (event.Subscription, error) - ParseVotedToBless(log types.Log) (*ARMContractVotedToBless, error) + ParseVotedToBless(log types.Log) (*RMNContractVotedToBless, error) - FilterVotedToCurse(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*ARMContractVotedToCurseIterator, error) + FilterVotedToCurse(opts *bind.FilterOpts, configVersion []uint32, voter []common.Address) (*RMNContractVotedToCurseIterator, error) - WatchVotedToCurse(opts *bind.WatchOpts, sink chan<- *ARMContractVotedToCurse, configVersion []uint32, voter []common.Address) (event.Subscription, error) + WatchVotedToCurse(opts *bind.WatchOpts, sink chan<- *RMNContractVotedToCurse, configVersion []uint32, voter []common.Address) (event.Subscription, error) - ParseVotedToCurse(log types.Log) (*ARMContractVotedToCurse, error) + ParseVotedToCurse(log types.Log) (*RMNContractVotedToCurse, error) ParseLog(log types.Log) (generated.AbigenLog, error) diff --git a/core/gethwrappers/ccip/generated/arm_proxy_contract/arm_proxy_contract.go b/core/gethwrappers/ccip/generated/rmn_proxy_contract/rmn_proxy_contract.go similarity index 60% rename from core/gethwrappers/ccip/generated/arm_proxy_contract/arm_proxy_contract.go rename to core/gethwrappers/ccip/generated/rmn_proxy_contract/rmn_proxy_contract.go index e2ba924621..18fd9898d8 100644 --- a/core/gethwrappers/ccip/generated/arm_proxy_contract/arm_proxy_contract.go +++ b/core/gethwrappers/ccip/generated/rmn_proxy_contract/rmn_proxy_contract.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package arm_proxy_contract +package rmn_proxy_contract import ( "errors" @@ -30,17 +30,17 @@ var ( _ = abi.ConvertType ) -var ARMProxyContractMetaData = &bind.MetaData{ +var RMNProxyContractMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"arm\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"arm\",\"type\":\"address\"}],\"name\":\"ARMSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getARM\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"arm\",\"type\":\"address\"}],\"name\":\"setARM\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", Bin: "0x608060405234801561001057600080fd5b5060405161084138038061084183398101604081905261002f91610255565b33806000816100855760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100b5576100b5816100cd565b5050506100c78161017660201b60201c565b50610285565b336001600160a01b038216036101255760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161007c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61017e6101f9565b6001600160a01b0381166101a5576040516342bcdf7f60e11b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fef31f568d741a833c6a9dc85a6e1c65e06fa772740d5dc94d1da21827a4e0cab9060200160405180910390a150565b6000546001600160a01b031633146102535760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161007c565b565b60006020828403121561026757600080fd5b81516001600160a01b038116811461027e57600080fd5b9392505050565b6105ad806102946000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c806379ba50971161005057806379ba5097146101615780638da5cb5b14610169578063f2fde38b1461018757610072565b8063181f5a77146100bb5780632e90aa211461010d578063458fec3b1461014c575b60025473ffffffffffffffffffffffffffffffffffffffff16803b61009657600080fd5b366000803760008036600080855af13d6000803e80156100b5573d6000f35b503d6000fd5b6100f76040518060400160405280600e81526020017f41524d50726f787920312e302e3000000000000000000000000000000000000081525081565b60405161010491906104f6565b60405180910390f35b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610104565b61015f61015a366004610563565b61019a565b005b61015f610268565b60005473ffffffffffffffffffffffffffffffffffffffff16610127565b61015f610195366004610563565b61036a565b6101a261037e565b73ffffffffffffffffffffffffffffffffffffffff81166101ef576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fef31f568d741a833c6a9dc85a6e1c65e06fa772740d5dc94d1da21827a4e0cab9060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff1633146102ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61037261037e565b61037b81610401565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102e5565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102e5565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020808352835180602085015260005b8181101561052457858101830151858201604001528201610508565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561057557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461059957600080fd5b939250505056fea164736f6c6343000818000a", } -var ARMProxyContractABI = ARMProxyContractMetaData.ABI +var RMNProxyContractABI = RMNProxyContractMetaData.ABI -var ARMProxyContractBin = ARMProxyContractMetaData.Bin +var RMNProxyContractBin = RMNProxyContractMetaData.Bin -func DeployARMProxyContract(auth *bind.TransactOpts, backend bind.ContractBackend, arm common.Address) (common.Address, *types.Transaction, *ARMProxyContract, error) { - parsed, err := ARMProxyContractMetaData.GetAbi() +func DeployRMNProxyContract(auth *bind.TransactOpts, backend bind.ContractBackend, arm common.Address) (common.Address, *types.Transaction, *RMNProxyContract, error) { + parsed, err := RMNProxyContractMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -48,132 +48,132 @@ func DeployARMProxyContract(auth *bind.TransactOpts, backend bind.ContractBacken return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ARMProxyContractBin), backend, arm) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(RMNProxyContractBin), backend, arm) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &ARMProxyContract{address: address, abi: *parsed, ARMProxyContractCaller: ARMProxyContractCaller{contract: contract}, ARMProxyContractTransactor: ARMProxyContractTransactor{contract: contract}, ARMProxyContractFilterer: ARMProxyContractFilterer{contract: contract}}, nil + return address, tx, &RMNProxyContract{address: address, abi: *parsed, RMNProxyContractCaller: RMNProxyContractCaller{contract: contract}, RMNProxyContractTransactor: RMNProxyContractTransactor{contract: contract}, RMNProxyContractFilterer: RMNProxyContractFilterer{contract: contract}}, nil } -type ARMProxyContract struct { +type RMNProxyContract struct { address common.Address abi abi.ABI - ARMProxyContractCaller - ARMProxyContractTransactor - ARMProxyContractFilterer + RMNProxyContractCaller + RMNProxyContractTransactor + RMNProxyContractFilterer } -type ARMProxyContractCaller struct { +type RMNProxyContractCaller struct { contract *bind.BoundContract } -type ARMProxyContractTransactor struct { +type RMNProxyContractTransactor struct { contract *bind.BoundContract } -type ARMProxyContractFilterer struct { +type RMNProxyContractFilterer struct { contract *bind.BoundContract } -type ARMProxyContractSession struct { - Contract *ARMProxyContract +type RMNProxyContractSession struct { + Contract *RMNProxyContract CallOpts bind.CallOpts TransactOpts bind.TransactOpts } -type ARMProxyContractCallerSession struct { - Contract *ARMProxyContractCaller +type RMNProxyContractCallerSession struct { + Contract *RMNProxyContractCaller CallOpts bind.CallOpts } -type ARMProxyContractTransactorSession struct { - Contract *ARMProxyContractTransactor +type RMNProxyContractTransactorSession struct { + Contract *RMNProxyContractTransactor TransactOpts bind.TransactOpts } -type ARMProxyContractRaw struct { - Contract *ARMProxyContract +type RMNProxyContractRaw struct { + Contract *RMNProxyContract } -type ARMProxyContractCallerRaw struct { - Contract *ARMProxyContractCaller +type RMNProxyContractCallerRaw struct { + Contract *RMNProxyContractCaller } -type ARMProxyContractTransactorRaw struct { - Contract *ARMProxyContractTransactor +type RMNProxyContractTransactorRaw struct { + Contract *RMNProxyContractTransactor } -func NewARMProxyContract(address common.Address, backend bind.ContractBackend) (*ARMProxyContract, error) { - abi, err := abi.JSON(strings.NewReader(ARMProxyContractABI)) +func NewRMNProxyContract(address common.Address, backend bind.ContractBackend) (*RMNProxyContract, error) { + abi, err := abi.JSON(strings.NewReader(RMNProxyContractABI)) if err != nil { return nil, err } - contract, err := bindARMProxyContract(address, backend, backend, backend) + contract, err := bindRMNProxyContract(address, backend, backend, backend) if err != nil { return nil, err } - return &ARMProxyContract{address: address, abi: abi, ARMProxyContractCaller: ARMProxyContractCaller{contract: contract}, ARMProxyContractTransactor: ARMProxyContractTransactor{contract: contract}, ARMProxyContractFilterer: ARMProxyContractFilterer{contract: contract}}, nil + return &RMNProxyContract{address: address, abi: abi, RMNProxyContractCaller: RMNProxyContractCaller{contract: contract}, RMNProxyContractTransactor: RMNProxyContractTransactor{contract: contract}, RMNProxyContractFilterer: RMNProxyContractFilterer{contract: contract}}, nil } -func NewARMProxyContractCaller(address common.Address, caller bind.ContractCaller) (*ARMProxyContractCaller, error) { - contract, err := bindARMProxyContract(address, caller, nil, nil) +func NewRMNProxyContractCaller(address common.Address, caller bind.ContractCaller) (*RMNProxyContractCaller, error) { + contract, err := bindRMNProxyContract(address, caller, nil, nil) if err != nil { return nil, err } - return &ARMProxyContractCaller{contract: contract}, nil + return &RMNProxyContractCaller{contract: contract}, nil } -func NewARMProxyContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ARMProxyContractTransactor, error) { - contract, err := bindARMProxyContract(address, nil, transactor, nil) +func NewRMNProxyContractTransactor(address common.Address, transactor bind.ContractTransactor) (*RMNProxyContractTransactor, error) { + contract, err := bindRMNProxyContract(address, nil, transactor, nil) if err != nil { return nil, err } - return &ARMProxyContractTransactor{contract: contract}, nil + return &RMNProxyContractTransactor{contract: contract}, nil } -func NewARMProxyContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ARMProxyContractFilterer, error) { - contract, err := bindARMProxyContract(address, nil, nil, filterer) +func NewRMNProxyContractFilterer(address common.Address, filterer bind.ContractFilterer) (*RMNProxyContractFilterer, error) { + contract, err := bindRMNProxyContract(address, nil, nil, filterer) if err != nil { return nil, err } - return &ARMProxyContractFilterer{contract: contract}, nil + return &RMNProxyContractFilterer{contract: contract}, nil } -func bindARMProxyContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := ARMProxyContractMetaData.GetAbi() +func bindRMNProxyContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := RMNProxyContractMetaData.GetAbi() if err != nil { return nil, err } return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } -func (_ARMProxyContract *ARMProxyContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ARMProxyContract.Contract.ARMProxyContractCaller.contract.Call(opts, result, method, params...) +func (_RMNProxyContract *RMNProxyContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RMNProxyContract.Contract.RMNProxyContractCaller.contract.Call(opts, result, method, params...) } -func (_ARMProxyContract *ARMProxyContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ARMProxyContract.Contract.ARMProxyContractTransactor.contract.Transfer(opts) +func (_RMNProxyContract *RMNProxyContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RMNProxyContract.Contract.RMNProxyContractTransactor.contract.Transfer(opts) } -func (_ARMProxyContract *ARMProxyContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ARMProxyContract.Contract.ARMProxyContractTransactor.contract.Transact(opts, method, params...) +func (_RMNProxyContract *RMNProxyContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RMNProxyContract.Contract.RMNProxyContractTransactor.contract.Transact(opts, method, params...) } -func (_ARMProxyContract *ARMProxyContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ARMProxyContract.Contract.contract.Call(opts, result, method, params...) +func (_RMNProxyContract *RMNProxyContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RMNProxyContract.Contract.contract.Call(opts, result, method, params...) } -func (_ARMProxyContract *ARMProxyContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ARMProxyContract.Contract.contract.Transfer(opts) +func (_RMNProxyContract *RMNProxyContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RMNProxyContract.Contract.contract.Transfer(opts) } -func (_ARMProxyContract *ARMProxyContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ARMProxyContract.Contract.contract.Transact(opts, method, params...) +func (_RMNProxyContract *RMNProxyContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RMNProxyContract.Contract.contract.Transact(opts, method, params...) } -func (_ARMProxyContract *ARMProxyContractCaller) GetARM(opts *bind.CallOpts) (common.Address, error) { +func (_RMNProxyContract *RMNProxyContractCaller) GetARM(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _ARMProxyContract.contract.Call(opts, &out, "getARM") + err := _RMNProxyContract.contract.Call(opts, &out, "getARM") if err != nil { return *new(common.Address), err @@ -185,17 +185,17 @@ func (_ARMProxyContract *ARMProxyContractCaller) GetARM(opts *bind.CallOpts) (co } -func (_ARMProxyContract *ARMProxyContractSession) GetARM() (common.Address, error) { - return _ARMProxyContract.Contract.GetARM(&_ARMProxyContract.CallOpts) +func (_RMNProxyContract *RMNProxyContractSession) GetARM() (common.Address, error) { + return _RMNProxyContract.Contract.GetARM(&_RMNProxyContract.CallOpts) } -func (_ARMProxyContract *ARMProxyContractCallerSession) GetARM() (common.Address, error) { - return _ARMProxyContract.Contract.GetARM(&_ARMProxyContract.CallOpts) +func (_RMNProxyContract *RMNProxyContractCallerSession) GetARM() (common.Address, error) { + return _RMNProxyContract.Contract.GetARM(&_RMNProxyContract.CallOpts) } -func (_ARMProxyContract *ARMProxyContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { +func (_RMNProxyContract *RMNProxyContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _ARMProxyContract.contract.Call(opts, &out, "owner") + err := _RMNProxyContract.contract.Call(opts, &out, "owner") if err != nil { return *new(common.Address), err @@ -207,17 +207,17 @@ func (_ARMProxyContract *ARMProxyContractCaller) Owner(opts *bind.CallOpts) (com } -func (_ARMProxyContract *ARMProxyContractSession) Owner() (common.Address, error) { - return _ARMProxyContract.Contract.Owner(&_ARMProxyContract.CallOpts) +func (_RMNProxyContract *RMNProxyContractSession) Owner() (common.Address, error) { + return _RMNProxyContract.Contract.Owner(&_RMNProxyContract.CallOpts) } -func (_ARMProxyContract *ARMProxyContractCallerSession) Owner() (common.Address, error) { - return _ARMProxyContract.Contract.Owner(&_ARMProxyContract.CallOpts) +func (_RMNProxyContract *RMNProxyContractCallerSession) Owner() (common.Address, error) { + return _RMNProxyContract.Contract.Owner(&_RMNProxyContract.CallOpts) } -func (_ARMProxyContract *ARMProxyContractCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { +func (_RMNProxyContract *RMNProxyContractCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { var out []interface{} - err := _ARMProxyContract.contract.Call(opts, &out, "typeAndVersion") + err := _RMNProxyContract.contract.Call(opts, &out, "typeAndVersion") if err != nil { return *new(string), err @@ -229,64 +229,64 @@ func (_ARMProxyContract *ARMProxyContractCaller) TypeAndVersion(opts *bind.CallO } -func (_ARMProxyContract *ARMProxyContractSession) TypeAndVersion() (string, error) { - return _ARMProxyContract.Contract.TypeAndVersion(&_ARMProxyContract.CallOpts) +func (_RMNProxyContract *RMNProxyContractSession) TypeAndVersion() (string, error) { + return _RMNProxyContract.Contract.TypeAndVersion(&_RMNProxyContract.CallOpts) } -func (_ARMProxyContract *ARMProxyContractCallerSession) TypeAndVersion() (string, error) { - return _ARMProxyContract.Contract.TypeAndVersion(&_ARMProxyContract.CallOpts) +func (_RMNProxyContract *RMNProxyContractCallerSession) TypeAndVersion() (string, error) { + return _RMNProxyContract.Contract.TypeAndVersion(&_RMNProxyContract.CallOpts) } -func (_ARMProxyContract *ARMProxyContractTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ARMProxyContract.contract.Transact(opts, "acceptOwnership") +func (_RMNProxyContract *RMNProxyContractTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RMNProxyContract.contract.Transact(opts, "acceptOwnership") } -func (_ARMProxyContract *ARMProxyContractSession) AcceptOwnership() (*types.Transaction, error) { - return _ARMProxyContract.Contract.AcceptOwnership(&_ARMProxyContract.TransactOpts) +func (_RMNProxyContract *RMNProxyContractSession) AcceptOwnership() (*types.Transaction, error) { + return _RMNProxyContract.Contract.AcceptOwnership(&_RMNProxyContract.TransactOpts) } -func (_ARMProxyContract *ARMProxyContractTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _ARMProxyContract.Contract.AcceptOwnership(&_ARMProxyContract.TransactOpts) +func (_RMNProxyContract *RMNProxyContractTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _RMNProxyContract.Contract.AcceptOwnership(&_RMNProxyContract.TransactOpts) } -func (_ARMProxyContract *ARMProxyContractTransactor) SetARM(opts *bind.TransactOpts, arm common.Address) (*types.Transaction, error) { - return _ARMProxyContract.contract.Transact(opts, "setARM", arm) +func (_RMNProxyContract *RMNProxyContractTransactor) SetARM(opts *bind.TransactOpts, arm common.Address) (*types.Transaction, error) { + return _RMNProxyContract.contract.Transact(opts, "setARM", arm) } -func (_ARMProxyContract *ARMProxyContractSession) SetARM(arm common.Address) (*types.Transaction, error) { - return _ARMProxyContract.Contract.SetARM(&_ARMProxyContract.TransactOpts, arm) +func (_RMNProxyContract *RMNProxyContractSession) SetARM(arm common.Address) (*types.Transaction, error) { + return _RMNProxyContract.Contract.SetARM(&_RMNProxyContract.TransactOpts, arm) } -func (_ARMProxyContract *ARMProxyContractTransactorSession) SetARM(arm common.Address) (*types.Transaction, error) { - return _ARMProxyContract.Contract.SetARM(&_ARMProxyContract.TransactOpts, arm) +func (_RMNProxyContract *RMNProxyContractTransactorSession) SetARM(arm common.Address) (*types.Transaction, error) { + return _RMNProxyContract.Contract.SetARM(&_RMNProxyContract.TransactOpts, arm) } -func (_ARMProxyContract *ARMProxyContractTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _ARMProxyContract.contract.Transact(opts, "transferOwnership", to) +func (_RMNProxyContract *RMNProxyContractTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _RMNProxyContract.contract.Transact(opts, "transferOwnership", to) } -func (_ARMProxyContract *ARMProxyContractSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _ARMProxyContract.Contract.TransferOwnership(&_ARMProxyContract.TransactOpts, to) +func (_RMNProxyContract *RMNProxyContractSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _RMNProxyContract.Contract.TransferOwnership(&_RMNProxyContract.TransactOpts, to) } -func (_ARMProxyContract *ARMProxyContractTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _ARMProxyContract.Contract.TransferOwnership(&_ARMProxyContract.TransactOpts, to) +func (_RMNProxyContract *RMNProxyContractTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _RMNProxyContract.Contract.TransferOwnership(&_RMNProxyContract.TransactOpts, to) } -func (_ARMProxyContract *ARMProxyContractTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { - return _ARMProxyContract.contract.RawTransact(opts, calldata) +func (_RMNProxyContract *RMNProxyContractTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _RMNProxyContract.contract.RawTransact(opts, calldata) } -func (_ARMProxyContract *ARMProxyContractSession) Fallback(calldata []byte) (*types.Transaction, error) { - return _ARMProxyContract.Contract.Fallback(&_ARMProxyContract.TransactOpts, calldata) +func (_RMNProxyContract *RMNProxyContractSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _RMNProxyContract.Contract.Fallback(&_RMNProxyContract.TransactOpts, calldata) } -func (_ARMProxyContract *ARMProxyContractTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { - return _ARMProxyContract.Contract.Fallback(&_ARMProxyContract.TransactOpts, calldata) +func (_RMNProxyContract *RMNProxyContractTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _RMNProxyContract.Contract.Fallback(&_RMNProxyContract.TransactOpts, calldata) } -type ARMProxyContractARMSetIterator struct { - Event *ARMProxyContractARMSet +type RMNProxyContractARMSetIterator struct { + Event *RMNProxyContractARMSet contract *bind.BoundContract event string @@ -297,7 +297,7 @@ type ARMProxyContractARMSetIterator struct { fail error } -func (it *ARMProxyContractARMSetIterator) Next() bool { +func (it *RMNProxyContractARMSetIterator) Next() bool { if it.fail != nil { return false @@ -306,7 +306,7 @@ func (it *ARMProxyContractARMSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMProxyContractARMSet) + it.Event = new(RMNProxyContractARMSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -321,7 +321,7 @@ func (it *ARMProxyContractARMSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMProxyContractARMSet) + it.Event = new(RMNProxyContractARMSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -336,32 +336,32 @@ func (it *ARMProxyContractARMSetIterator) Next() bool { } } -func (it *ARMProxyContractARMSetIterator) Error() error { +func (it *RMNProxyContractARMSetIterator) Error() error { return it.fail } -func (it *ARMProxyContractARMSetIterator) Close() error { +func (it *RMNProxyContractARMSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMProxyContractARMSet struct { +type RMNProxyContractARMSet struct { Arm common.Address Raw types.Log } -func (_ARMProxyContract *ARMProxyContractFilterer) FilterARMSet(opts *bind.FilterOpts) (*ARMProxyContractARMSetIterator, error) { +func (_RMNProxyContract *RMNProxyContractFilterer) FilterARMSet(opts *bind.FilterOpts) (*RMNProxyContractARMSetIterator, error) { - logs, sub, err := _ARMProxyContract.contract.FilterLogs(opts, "ARMSet") + logs, sub, err := _RMNProxyContract.contract.FilterLogs(opts, "ARMSet") if err != nil { return nil, err } - return &ARMProxyContractARMSetIterator{contract: _ARMProxyContract.contract, event: "ARMSet", logs: logs, sub: sub}, nil + return &RMNProxyContractARMSetIterator{contract: _RMNProxyContract.contract, event: "ARMSet", logs: logs, sub: sub}, nil } -func (_ARMProxyContract *ARMProxyContractFilterer) WatchARMSet(opts *bind.WatchOpts, sink chan<- *ARMProxyContractARMSet) (event.Subscription, error) { +func (_RMNProxyContract *RMNProxyContractFilterer) WatchARMSet(opts *bind.WatchOpts, sink chan<- *RMNProxyContractARMSet) (event.Subscription, error) { - logs, sub, err := _ARMProxyContract.contract.WatchLogs(opts, "ARMSet") + logs, sub, err := _RMNProxyContract.contract.WatchLogs(opts, "ARMSet") if err != nil { return nil, err } @@ -371,8 +371,8 @@ func (_ARMProxyContract *ARMProxyContractFilterer) WatchARMSet(opts *bind.WatchO select { case log := <-logs: - event := new(ARMProxyContractARMSet) - if err := _ARMProxyContract.contract.UnpackLog(event, "ARMSet", log); err != nil { + event := new(RMNProxyContractARMSet) + if err := _RMNProxyContract.contract.UnpackLog(event, "ARMSet", log); err != nil { return err } event.Raw = log @@ -393,17 +393,17 @@ func (_ARMProxyContract *ARMProxyContractFilterer) WatchARMSet(opts *bind.WatchO }), nil } -func (_ARMProxyContract *ARMProxyContractFilterer) ParseARMSet(log types.Log) (*ARMProxyContractARMSet, error) { - event := new(ARMProxyContractARMSet) - if err := _ARMProxyContract.contract.UnpackLog(event, "ARMSet", log); err != nil { +func (_RMNProxyContract *RMNProxyContractFilterer) ParseARMSet(log types.Log) (*RMNProxyContractARMSet, error) { + event := new(RMNProxyContractARMSet) + if err := _RMNProxyContract.contract.UnpackLog(event, "ARMSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMProxyContractOwnershipTransferRequestedIterator struct { - Event *ARMProxyContractOwnershipTransferRequested +type RMNProxyContractOwnershipTransferRequestedIterator struct { + Event *RMNProxyContractOwnershipTransferRequested contract *bind.BoundContract event string @@ -414,7 +414,7 @@ type ARMProxyContractOwnershipTransferRequestedIterator struct { fail error } -func (it *ARMProxyContractOwnershipTransferRequestedIterator) Next() bool { +func (it *RMNProxyContractOwnershipTransferRequestedIterator) Next() bool { if it.fail != nil { return false @@ -423,7 +423,7 @@ func (it *ARMProxyContractOwnershipTransferRequestedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMProxyContractOwnershipTransferRequested) + it.Event = new(RMNProxyContractOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -438,7 +438,7 @@ func (it *ARMProxyContractOwnershipTransferRequestedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMProxyContractOwnershipTransferRequested) + it.Event = new(RMNProxyContractOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -453,22 +453,22 @@ func (it *ARMProxyContractOwnershipTransferRequestedIterator) Next() bool { } } -func (it *ARMProxyContractOwnershipTransferRequestedIterator) Error() error { +func (it *RMNProxyContractOwnershipTransferRequestedIterator) Error() error { return it.fail } -func (it *ARMProxyContractOwnershipTransferRequestedIterator) Close() error { +func (it *RMNProxyContractOwnershipTransferRequestedIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMProxyContractOwnershipTransferRequested struct { +type RMNProxyContractOwnershipTransferRequested struct { From common.Address To common.Address Raw types.Log } -func (_ARMProxyContract *ARMProxyContractFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMProxyContractOwnershipTransferRequestedIterator, error) { +func (_RMNProxyContract *RMNProxyContractFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RMNProxyContractOwnershipTransferRequestedIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -479,14 +479,14 @@ func (_ARMProxyContract *ARMProxyContractFilterer) FilterOwnershipTransferReques toRule = append(toRule, toItem) } - logs, sub, err := _ARMProxyContract.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _RMNProxyContract.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } - return &ARMProxyContractOwnershipTransferRequestedIterator{contract: _ARMProxyContract.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil + return &RMNProxyContractOwnershipTransferRequestedIterator{contract: _RMNProxyContract.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil } -func (_ARMProxyContract *ARMProxyContractFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ARMProxyContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_RMNProxyContract *RMNProxyContractFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *RMNProxyContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -497,7 +497,7 @@ func (_ARMProxyContract *ARMProxyContractFilterer) WatchOwnershipTransferRequest toRule = append(toRule, toItem) } - logs, sub, err := _ARMProxyContract.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _RMNProxyContract.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } @@ -507,8 +507,8 @@ func (_ARMProxyContract *ARMProxyContractFilterer) WatchOwnershipTransferRequest select { case log := <-logs: - event := new(ARMProxyContractOwnershipTransferRequested) - if err := _ARMProxyContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + event := new(RMNProxyContractOwnershipTransferRequested) + if err := _RMNProxyContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return err } event.Raw = log @@ -529,17 +529,17 @@ func (_ARMProxyContract *ARMProxyContractFilterer) WatchOwnershipTransferRequest }), nil } -func (_ARMProxyContract *ARMProxyContractFilterer) ParseOwnershipTransferRequested(log types.Log) (*ARMProxyContractOwnershipTransferRequested, error) { - event := new(ARMProxyContractOwnershipTransferRequested) - if err := _ARMProxyContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { +func (_RMNProxyContract *RMNProxyContractFilterer) ParseOwnershipTransferRequested(log types.Log) (*RMNProxyContractOwnershipTransferRequested, error) { + event := new(RMNProxyContractOwnershipTransferRequested) + if err := _RMNProxyContract.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return nil, err } event.Raw = log return event, nil } -type ARMProxyContractOwnershipTransferredIterator struct { - Event *ARMProxyContractOwnershipTransferred +type RMNProxyContractOwnershipTransferredIterator struct { + Event *RMNProxyContractOwnershipTransferred contract *bind.BoundContract event string @@ -550,7 +550,7 @@ type ARMProxyContractOwnershipTransferredIterator struct { fail error } -func (it *ARMProxyContractOwnershipTransferredIterator) Next() bool { +func (it *RMNProxyContractOwnershipTransferredIterator) Next() bool { if it.fail != nil { return false @@ -559,7 +559,7 @@ func (it *ARMProxyContractOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ARMProxyContractOwnershipTransferred) + it.Event = new(RMNProxyContractOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -574,7 +574,7 @@ func (it *ARMProxyContractOwnershipTransferredIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(ARMProxyContractOwnershipTransferred) + it.Event = new(RMNProxyContractOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -589,22 +589,22 @@ func (it *ARMProxyContractOwnershipTransferredIterator) Next() bool { } } -func (it *ARMProxyContractOwnershipTransferredIterator) Error() error { +func (it *RMNProxyContractOwnershipTransferredIterator) Error() error { return it.fail } -func (it *ARMProxyContractOwnershipTransferredIterator) Close() error { +func (it *RMNProxyContractOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -type ARMProxyContractOwnershipTransferred struct { +type RMNProxyContractOwnershipTransferred struct { From common.Address To common.Address Raw types.Log } -func (_ARMProxyContract *ARMProxyContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMProxyContractOwnershipTransferredIterator, error) { +func (_RMNProxyContract *RMNProxyContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RMNProxyContractOwnershipTransferredIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -615,14 +615,14 @@ func (_ARMProxyContract *ARMProxyContractFilterer) FilterOwnershipTransferred(op toRule = append(toRule, toItem) } - logs, sub, err := _ARMProxyContract.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _RMNProxyContract.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } - return &ARMProxyContractOwnershipTransferredIterator{contract: _ARMProxyContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &RMNProxyContractOwnershipTransferredIterator{contract: _RMNProxyContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -func (_ARMProxyContract *ARMProxyContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ARMProxyContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_RMNProxyContract *RMNProxyContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *RMNProxyContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -633,7 +633,7 @@ func (_ARMProxyContract *ARMProxyContractFilterer) WatchOwnershipTransferred(opt toRule = append(toRule, toItem) } - logs, sub, err := _ARMProxyContract.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _RMNProxyContract.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } @@ -643,8 +643,8 @@ func (_ARMProxyContract *ARMProxyContractFilterer) WatchOwnershipTransferred(opt select { case log := <-logs: - event := new(ARMProxyContractOwnershipTransferred) - if err := _ARMProxyContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(RMNProxyContractOwnershipTransferred) + if err := _RMNProxyContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -665,46 +665,46 @@ func (_ARMProxyContract *ARMProxyContractFilterer) WatchOwnershipTransferred(opt }), nil } -func (_ARMProxyContract *ARMProxyContractFilterer) ParseOwnershipTransferred(log types.Log) (*ARMProxyContractOwnershipTransferred, error) { - event := new(ARMProxyContractOwnershipTransferred) - if err := _ARMProxyContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +func (_RMNProxyContract *RMNProxyContractFilterer) ParseOwnershipTransferred(log types.Log) (*RMNProxyContractOwnershipTransferred, error) { + event := new(RMNProxyContractOwnershipTransferred) + if err := _RMNProxyContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log return event, nil } -func (_ARMProxyContract *ARMProxyContract) ParseLog(log types.Log) (generated.AbigenLog, error) { +func (_RMNProxyContract *RMNProxyContract) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _ARMProxyContract.abi.Events["ARMSet"].ID: - return _ARMProxyContract.ParseARMSet(log) - case _ARMProxyContract.abi.Events["OwnershipTransferRequested"].ID: - return _ARMProxyContract.ParseOwnershipTransferRequested(log) - case _ARMProxyContract.abi.Events["OwnershipTransferred"].ID: - return _ARMProxyContract.ParseOwnershipTransferred(log) + case _RMNProxyContract.abi.Events["ARMSet"].ID: + return _RMNProxyContract.ParseARMSet(log) + case _RMNProxyContract.abi.Events["OwnershipTransferRequested"].ID: + return _RMNProxyContract.ParseOwnershipTransferRequested(log) + case _RMNProxyContract.abi.Events["OwnershipTransferred"].ID: + return _RMNProxyContract.ParseOwnershipTransferred(log) default: return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) } } -func (ARMProxyContractARMSet) Topic() common.Hash { +func (RMNProxyContractARMSet) Topic() common.Hash { return common.HexToHash("0xef31f568d741a833c6a9dc85a6e1c65e06fa772740d5dc94d1da21827a4e0cab") } -func (ARMProxyContractOwnershipTransferRequested) Topic() common.Hash { +func (RMNProxyContractOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } -func (ARMProxyContractOwnershipTransferred) Topic() common.Hash { +func (RMNProxyContractOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (_ARMProxyContract *ARMProxyContract) Address() common.Address { - return _ARMProxyContract.address +func (_RMNProxyContract *RMNProxyContract) Address() common.Address { + return _RMNProxyContract.address } -type ARMProxyContractInterface interface { +type RMNProxyContractInterface interface { GetARM(opts *bind.CallOpts) (common.Address, error) Owner(opts *bind.CallOpts) (common.Address, error) @@ -719,23 +719,23 @@ type ARMProxyContractInterface interface { Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) - FilterARMSet(opts *bind.FilterOpts) (*ARMProxyContractARMSetIterator, error) + FilterARMSet(opts *bind.FilterOpts) (*RMNProxyContractARMSetIterator, error) - WatchARMSet(opts *bind.WatchOpts, sink chan<- *ARMProxyContractARMSet) (event.Subscription, error) + WatchARMSet(opts *bind.WatchOpts, sink chan<- *RMNProxyContractARMSet) (event.Subscription, error) - ParseARMSet(log types.Log) (*ARMProxyContractARMSet, error) + ParseARMSet(log types.Log) (*RMNProxyContractARMSet, error) - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMProxyContractOwnershipTransferRequestedIterator, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RMNProxyContractOwnershipTransferRequestedIterator, error) - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ARMProxyContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *RMNProxyContractOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - ParseOwnershipTransferRequested(log types.Log) (*ARMProxyContractOwnershipTransferRequested, error) + ParseOwnershipTransferRequested(log types.Log) (*RMNProxyContractOwnershipTransferRequested, error) - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ARMProxyContractOwnershipTransferredIterator, error) + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RMNProxyContractOwnershipTransferredIterator, error) - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ARMProxyContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *RMNProxyContractOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - ParseOwnershipTransferred(log types.Log) (*ARMProxyContractOwnershipTransferred, error) + ParseOwnershipTransferred(log types.Log) (*RMNProxyContractOwnershipTransferred, error) ParseLog(log types.Log) (generated.AbigenLog, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 75d7535931..13c88b9c51 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,18 +1,14 @@ GETH_VERSION: 1.13.8 -arm_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 8b45b0fb08631c6b582fd3c0b4052a79cc2b4e091e6286af1ab131bef63661f9 -arm_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 1e60c28ad796a220a38043b369dec8d9bffe23e1c7d9895760e30672872afd06 burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 3e8e3358f0bb520af069a7d37ea625940a88461a54418b1d5925eabced8c74df burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 717c079d5d13300cf3c3ee871c6e5bf9af904411f204fb081a9f3b263cca1391 burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6333d0314d0bd29e75ea5e05fe62a4516ade0c6db91c30b6f93645035db52ed8 burn_with_from_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin 08ed1235dda921ce8841b26aa18d0c0f36db4884779dd7670857159801b6d597 ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 213d4adc8634671aea16fb4207989375b1aac919b04d608f4767c29592affbf5 -ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin fcced2263564f51b5bf086c221e813ec06a71d2bb2e246b4e28cd60098a6de6f +ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin a5b0275dcf502f73d72f6bc53bff774e25fcca01a74cc019536bdee6a42ac655 commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin 274d87db70b643e00ab0a7e7845bb4b791f3b613bfc87708d33fc5a8369e2a41 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin f7128dcc2ee6dbcbc976288abcc16970ffb19b59412c5202ef6b259d2007f801 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de -evm_2_evm_multi_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin 06853f6d87f0c0b1f2cb403e45e32934c043028208f60a0111cde405e1bee1ba -evm_2_evm_multi_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin 15cd5695049ab4be1f396ec1d7b609738b2bcefa3740a7a48316e1f72506a34a evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin b0d77babbe635cd6ba04c2af049badc9e9d28a4b6ed6bb75f830ad902a618beb evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 5c02c2b167946b3467636ff2bb58594cb4652fc63d8bdfee2488ed562e2a3e50 lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin e6a8ec9e8faccb1da7d90e0f702ed72975964f97dc3222b54cfcca0a0ba3fea2 @@ -26,10 +22,14 @@ multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRate multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin aa299e0c2659d53aad4eace4d66be0e734b1366008593669cf30361ff529da6a nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 6f64e1083b356c06ee66b9138e398b9c97a4cd3e8c9ec38cf3010cebc79af536 ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 +offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin 76ec9676116368ab7c7c7ed45191698a12e4d975633caea32d821a1125633589 +onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 123e949bc9607289382534c4432ecebe5b1da5ca92c1c6c8cc6b9be56c3352c6 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 4e51d70bdb6d951041518a3d7fd3b33ba8d3954bcc3d078318055b833b880324 price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 8f4bdaa4d8239429ae4e047ab06d445bad42234a05bb7c99ba6141bd811e1722 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 75be86323c227917a9bbc3f799d7ed02f92db546653a36db30ed0ebe64461353 -report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin c07af8433bf8dbc7981725b18922a9c4e2dea068dd204bc62adc0e926cb499c3 +report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin 20292ddaba15096fe8060567cf56cda673b947df27241d0c49d2debc838feb24 +rmn_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 8b45b0fb08631c6b582fd3c0b4052a79cc2b4e091e6286af1ab131bef63661f9 +rmn_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 2e4f0a7826c8abb49d882bb49fc5ff20a186dbd3137624b9097ffed903ae4888 self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 4f339db2b670b88214b738efb7a714be9d50fa32c8008710b607d58670b22074 token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 942be7d1681ac102e0615bee13f76838ebb0b261697cf1270d2bf82c12e57aeb diff --git a/core/gethwrappers/ccip/go_generate.go b/core/gethwrappers/ccip/go_generate.go index 92e0c3c19e..f57226b3e3 100644 --- a/core/gethwrappers/ccip/go_generate.go +++ b/core/gethwrappers/ccip/go_generate.go @@ -4,14 +4,14 @@ package ccip //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin CommitStore commit_store //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin CommitStoreHelper commit_store_helper -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin ARMContract arm_contract -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin ARMProxyContract arm_proxy_contract +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin RMNContract rmn_contract +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin RMNProxyContract rmn_proxy_contract //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin TokenAdminRegistry token_admin_registry //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin RegistryModuleOwnerCustom registry_module_owner_custom //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin EVM2EVMOnRamp evm_2_evm_onramp -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOnRamp/EVM2EVMMultiOnRamp.bin EVM2EVMMultiOnRamp evm_2_evm_multi_onramp +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin OnRamp onramp //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin EVM2EVMOffRamp evm_2_evm_offramp -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMMultiOffRamp/EVM2EVMMultiOffRamp.bin EVM2EVMMultiOffRamp evm_2_evm_multi_offramp +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin OffRamp offramp //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin MultiAggregateRateLimiter multi_aggregate_rate_limiter //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin Router router //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin PriceRegistry price_registry diff --git a/core/scripts/ccip/liquiditymanager/util.go b/core/scripts/ccip/liquiditymanager/util.go new file mode 100644 index 0000000000..45aa69ddb8 --- /dev/null +++ b/core/scripts/ccip/liquiditymanager/util.go @@ -0,0 +1,433 @@ +package main + +import ( + "context" + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + chainsel "github.com/smartcontractkit/chain-selectors" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + + "github.com/smartcontractkit/chainlink/core/scripts/ccip/liquiditymanager/arb" + "github.com/smartcontractkit/chainlink/core/scripts/ccip/liquiditymanager/multienv" + "github.com/smartcontractkit/chainlink/core/scripts/ccip/liquiditymanager/opstack" + helpers "github.com/smartcontractkit/chainlink/core/scripts/common" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" + cciprouter "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_l1_bridge_adapter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_l2_bridge_adapter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/liquiditymanager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_l1_bridge_adapter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_l2_bridge_adapter" +) + +type universe struct { + L1 struct { + Arm common.Address + ArmProxy common.Address + TokenPool common.Address + LiquidityManager common.Address + BridgeAdapterAddress common.Address + } + L2 struct { + Arm common.Address + ArmProxy common.Address + TokenPool common.Address + LiquidityManager common.Address + BridgeAdapterAddress common.Address + } +} + +func deployUniverse( + env multienv.Env, + l1ChainID, l2ChainID uint64, + l1TokenAddress, l2TokenAddress common.Address, +) universe { + validateEnv(env, l1ChainID, l2ChainID, false) + + l1Client, l2Client := env.Clients[l1ChainID], env.Clients[l2ChainID] + l1Transactor, l2Transactor := env.Transactors[l1ChainID], env.Transactors[l2ChainID] + l1ChainSelector, l2ChainSelector := mustGetChainByEvmID(l1ChainID).Selector, mustGetChainByEvmID(l2ChainID).Selector + + // L1 deploys + // deploy arm and arm proxy. + // required by the token pool. + l1Arm, l1ArmProxy := deployArm(l1Transactor, l1Client, l1ChainID) + + _, tx, _, err := cciprouter.DeployRouter(l1Transactor, l1Client, common.Address{}, l1ArmProxy.Address()) + helpers.PanicErr(err) + l1RouterAddress := helpers.ConfirmContractDeployed(context.Background(), l1Client, tx, int64(l1ChainID)) + + // deploy token pool targeting l1TokenAddress. + l1TokenPool, l1Rebalancer := deployTokenPoolAndRebalancer(l1Transactor, l1Client, l1TokenAddress, l1ArmProxy.Address(), l1ChainSelector, l1RouterAddress) + + // deploy the appropriate L1 bridge adapter depending on the chain. + l1BridgeAdapterAddress := deployL1BridgeAdapter(l1Transactor, l1Client, l1ChainID, l2ChainID) + + // L2 deploys + // deploy arm and arm proxy. + // required by the token pool. + l2Arm, l2ArmProxy := deployArm(l2Transactor, l2Client, l2ChainID) + + _, tx, _, err = cciprouter.DeployRouter(l2Transactor, l2Client, common.Address{}, l2ArmProxy.Address()) + helpers.PanicErr(err) + l2RouterAddress := helpers.ConfirmContractDeployed(context.Background(), l2Client, tx, int64(l2ChainID)) + + // deploy token pool targeting l2TokenAddress + l2TokenPool, l2Rebalancer := deployTokenPoolAndRebalancer(l2Transactor, l2Client, l2TokenAddress, l2ArmProxy.Address(), l2ChainSelector, l2RouterAddress) + + // deploy the L2 bridge adapter to point to the token address + l2BridgeAdapterAddress := deployL2BridgeAdapter(l2Transactor, l2Client, l2ChainID) + + // link the l1 and l2 rebalancers together via the SetCrossChainRebalancer function + tx, err = l1Rebalancer.SetCrossChainRebalancer(l1Transactor, liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs{ + RemoteRebalancer: l2Rebalancer.Address(), + LocalBridge: l1BridgeAdapterAddress, + RemoteToken: l2TokenAddress, + RemoteChainSelector: l2ChainSelector, + Enabled: true, + }) + helpers.PanicErr(err) + helpers.ConfirmTXMined(context.Background(), l1Client, tx, int64(l1ChainID), "setting cross chain liquidityManager on L1 liquidityManager") + // assertion + onchainRebalancer, err := l1Rebalancer.GetCrossChainRebalancer(nil, l2ChainSelector) + helpers.PanicErr(err) + if onchainRebalancer.RemoteRebalancer != l2Rebalancer.Address() || + onchainRebalancer.LocalBridge != l1BridgeAdapterAddress { + panic(fmt.Sprintf("onchain liquidityManager address does not match, expected %s got %s, or local bridge does not match, expected %s got %s", + l2Rebalancer.Address().Hex(), + onchainRebalancer.RemoteRebalancer.Hex(), + l1BridgeAdapterAddress.Hex(), + onchainRebalancer.LocalBridge.Hex())) + } + + tx, err = l2Rebalancer.SetCrossChainRebalancer(l2Transactor, liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs{ + RemoteRebalancer: l1Rebalancer.Address(), + LocalBridge: l2BridgeAdapterAddress, + RemoteToken: l1TokenAddress, + RemoteChainSelector: l1ChainSelector, + Enabled: true, + }) + helpers.PanicErr(err) + helpers.ConfirmTXMined(context.Background(), l2Client, tx, int64(l2ChainID), "setting cross chain liquidityManager on L2 liquidityManager") + // assertion + onchainRebalancer, err = l2Rebalancer.GetCrossChainRebalancer(nil, l1ChainSelector) + helpers.PanicErr(err) + if onchainRebalancer.RemoteRebalancer != l1Rebalancer.Address() || + onchainRebalancer.LocalBridge != l2BridgeAdapterAddress { + panic(fmt.Sprintf("onchain liquidityManager address does not match, expected %s got %s, or local bridge does not match, expected %s got %s", + l1Rebalancer.Address().Hex(), + onchainRebalancer.RemoteRebalancer.Hex(), + l2BridgeAdapterAddress.Hex(), + onchainRebalancer.LocalBridge.Hex())) + } + + fmt.Println("Deployments complete\n", + "L1 Chain ID:", l1ChainID, "\n", + "L1 Chain Selector:", l1ChainSelector, "\n", + "L1 Arm:", helpers.ContractExplorerLink(int64(l1ChainID), l1Arm.Address()), "(", l1Arm.Address().Hex(), ")\n", + "L1 Arm Proxy:", helpers.ContractExplorerLink(int64(l1ChainID), l1ArmProxy.Address()), "(", l1ArmProxy.Address().Hex(), ")\n", + "L1 Token Pool:", helpers.ContractExplorerLink(int64(l1ChainID), l1TokenPool.Address()), "(", l1TokenPool.Address().Hex(), ")\n", + "L1 LiquidityManager:", helpers.ContractExplorerLink(int64(l1ChainID), l1Rebalancer.Address()), "(", l1Rebalancer.Address().Hex(), ")\n", + "L1 Bridge Adapter:", helpers.ContractExplorerLink(int64(l1ChainID), l1BridgeAdapterAddress), "(", l1BridgeAdapterAddress.Hex(), ")\n", + "L2 Chain ID:", l2ChainID, "\n", + "L2 Chain Selector:", l2ChainSelector, "\n", + "L2 Arm:", helpers.ContractExplorerLink(int64(l2ChainID), l2Arm.Address()), "(", l2Arm.Address().Hex(), ")\n", + "L2 Arm Proxy:", helpers.ContractExplorerLink(int64(l2ChainID), l2ArmProxy.Address()), "(", l2ArmProxy.Address().Hex(), ")\n", + "L2 Token Pool:", helpers.ContractExplorerLink(int64(l2ChainID), l2TokenPool.Address()), "(", l2TokenPool.Address().Hex(), ")\n", + "L2 LiquidityManager:", helpers.ContractExplorerLink(int64(l2ChainID), l2Rebalancer.Address()), "(", l2Rebalancer.Address().Hex(), ")\n", + "L2 Bridge Adapter:", helpers.ContractExplorerLink(int64(l2ChainID), l2BridgeAdapterAddress), "(", l2BridgeAdapterAddress.Hex(), ")", + ) + + return universe{ + L1: struct { + Arm common.Address + ArmProxy common.Address + TokenPool common.Address + LiquidityManager common.Address + BridgeAdapterAddress common.Address + }{ + Arm: l1Arm.Address(), + ArmProxy: l1ArmProxy.Address(), + TokenPool: l1TokenPool.Address(), + LiquidityManager: l1Rebalancer.Address(), + BridgeAdapterAddress: l1BridgeAdapterAddress, + }, + L2: struct { + Arm common.Address + ArmProxy common.Address + TokenPool common.Address + LiquidityManager common.Address + BridgeAdapterAddress common.Address + }{ + Arm: l2Arm.Address(), + ArmProxy: l2ArmProxy.Address(), + TokenPool: l2TokenPool.Address(), + LiquidityManager: l2Rebalancer.Address(), + BridgeAdapterAddress: l2BridgeAdapterAddress, + }, + } +} + +func deployL1BridgeAdapter( + l1Transactor *bind.TransactOpts, + l1Client *ethclient.Client, + l1ChainID, l2ChainID uint64, +) common.Address { + if l2ChainID == chainsel.ETHEREUM_MAINNET_ARBITRUM_1.EvmChainID || l2ChainID == chainsel.ETHEREUM_TESTNET_SEPOLIA_ARBITRUM_1.EvmChainID { + _, tx, _, err := arbitrum_l1_bridge_adapter.DeployArbitrumL1BridgeAdapter( + l1Transactor, + l1Client, + arb.ArbitrumContracts[l1ChainID]["L1GatewayRouter"], + arb.ArbitrumContracts[l1ChainID]["L1Outbox"], + ) + helpers.PanicErr(err) + return helpers.ConfirmContractDeployed(context.Background(), l1Client, tx, int64(l1ChainID)) + } else if l2ChainID == chainsel.ETHEREUM_MAINNET_OPTIMISM_1.EvmChainID || l2ChainID == chainsel.ETHEREUM_TESTNET_SEPOLIA_OPTIMISM_1.EvmChainID { + _, tx, _, err := optimism_l1_bridge_adapter.DeployOptimismL1BridgeAdapter( + l1Transactor, + l1Client, + opstack.OptimismContractsByChainID[l1ChainID]["L1StandardBridge"], + opstack.OptimismContractsByChainID[l1ChainID]["WETH"], + opstack.OptimismContractsByChainID[l1ChainID]["OptimismPortalProxy"], + ) + helpers.PanicErr(err) + return helpers.ConfirmContractDeployed(context.Background(), l1Client, tx, int64(l1ChainID)) + } + panic(fmt.Sprintf("unsupported chain id %d", l1ChainID)) +} + +func deployL2BridgeAdapter( + l2Transactor *bind.TransactOpts, + l2Client *ethclient.Client, + l2ChainID uint64, +) common.Address { + if l2ChainID == chainsel.ETHEREUM_MAINNET_ARBITRUM_1.EvmChainID || l2ChainID == chainsel.ETHEREUM_TESTNET_SEPOLIA_ARBITRUM_1.EvmChainID { + _, tx, _, err := arbitrum_l2_bridge_adapter.DeployArbitrumL2BridgeAdapter( + l2Transactor, + l2Client, + arb.ArbitrumContracts[l2ChainID]["L2GatewayRouter"], + ) + helpers.PanicErr(err) + return helpers.ConfirmContractDeployed(context.Background(), l2Client, tx, int64(l2ChainID)) + } else if l2ChainID == chainsel.ETHEREUM_MAINNET_OPTIMISM_1.EvmChainID || l2ChainID == chainsel.ETHEREUM_TESTNET_SEPOLIA_OPTIMISM_1.EvmChainID { + _, tx, _, err := optimism_l2_bridge_adapter.DeployOptimismL2BridgeAdapter( + l2Transactor, + l2Client, + opstack.OptimismContractsByChainID[l2ChainID]["WETH"], + ) + helpers.PanicErr(err) + return helpers.ConfirmContractDeployed(context.Background(), l2Client, tx, int64(l2ChainID)) + } + panic(fmt.Sprintf("unsupported l2 chain id %d", l2ChainID)) +} + +func deployTokenPoolAndRebalancer( + transactor *bind.TransactOpts, + client *ethclient.Client, + tokenAddress, + armProxyAddress common.Address, + chainID uint64, + router common.Address, +) (*lock_release_token_pool.LockReleaseTokenPool, *liquiditymanager.LiquidityManager) { + _, tx, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( + transactor, + client, + tokenAddress, + []common.Address{}, + armProxyAddress, + true, + router, + ) + helpers.PanicErr(err) + tokenPoolAddress := helpers.ConfirmContractDeployed(context.Background(), client, tx, int64(chainID)) + tokenPool, err := lock_release_token_pool.NewLockReleaseTokenPool(tokenPoolAddress, client) + helpers.PanicErr(err) + + _, tx, _, err = liquiditymanager.DeployLiquidityManager( + transactor, + client, + tokenAddress, + chainID, + tokenPoolAddress, + big.NewInt(0), + common.Address{}, + ) + helpers.PanicErr(err) + rebalancerAddress := helpers.ConfirmContractDeployed(context.Background(), client, tx, int64(chainID)) + liquidityManager, err := liquiditymanager.NewLiquidityManager(rebalancerAddress, client) + helpers.PanicErr(err) + tx, err = tokenPool.SetRebalancer(transactor, rebalancerAddress) + helpers.PanicErr(err) + helpers.ConfirmTXMined(context.Background(), client, tx, int64(chainID), + "setting liquidityManager on token pool") + onchainRebalancer, err := tokenPool.GetRebalancer(nil) + helpers.PanicErr(err) + if onchainRebalancer != rebalancerAddress { + panic(fmt.Sprintf("onchain liquidityManager address does not match, expected %s got %s", + rebalancerAddress.Hex(), onchainRebalancer.Hex())) + } + return tokenPool, liquidityManager +} + +func deployArm( + transactor *bind.TransactOpts, + client *ethclient.Client, + chainID uint64) (*mock_rmn_contract.MockRMNContract, *rmn_proxy_contract.RMNProxyContract) { + _, tx, _, err := mock_rmn_contract.DeployMockRMNContract(transactor, client) + helpers.PanicErr(err) + armAddress := helpers.ConfirmContractDeployed(context.Background(), client, tx, int64(chainID)) + arm, err := mock_rmn_contract.NewMockRMNContract(armAddress, client) + helpers.PanicErr(err) + + _, tx, _, err = rmn_proxy_contract.DeployRMNProxyContract(transactor, client, arm.Address()) + helpers.PanicErr(err) + armProxyAddress := helpers.ConfirmContractDeployed(context.Background(), client, tx, int64(chainID)) + armProxy, err := rmn_proxy_contract.NewRMNProxyContract(armProxyAddress, client) + helpers.PanicErr(err) + + return arm, armProxy +} + +// sum of MaxDurationQuery/MaxDurationObservation/DeltaGrace must be less than DeltaProgress +func setConfig( + e multienv.Env, + args setConfigArgs, +) { + validateEnv(e, args.l1ChainID, args.l2ChainID, false) + + l1Transactor, l2Transactor := e.Transactors[args.l1ChainID], e.Transactors[args.l2ChainID] + + // lengths of all the arrays must be equal + if len(args.signers) != len(args.offchainPubKeys) || + len(args.signers) != len(args.configPubKeys) || + len(args.signers) != len(args.l1Transmitters) || + len(args.signers) != len(args.l2Transmitters) { + panic("lengths of all the arrays must be equal") + } + + l1Rebalancer, err := liquiditymanager.NewLiquidityManager(args.l1LiquidityManagerAddress, e.Clients[args.l1ChainID]) + helpers.PanicErr(err) + l2Rebalancer, err := liquiditymanager.NewLiquidityManager(args.l2LiquidityManagerAddress, e.Clients[args.l2ChainID]) + helpers.PanicErr(err) + + // set config on L2 first then L1 + var ( + l1Oracles []confighelper2.OracleIdentityExtra + l2Oracles []confighelper2.OracleIdentityExtra + ) + for i := 0; i < len(args.signers); i++ { + l1Oracles = append(l1Oracles, confighelper2.OracleIdentityExtra{ + OracleIdentity: confighelper2.OracleIdentity{ + OffchainPublicKey: args.offchainPubKeys[i], + OnchainPublicKey: args.signers[i].Bytes(), + PeerID: args.peerIDs[i], + TransmitAccount: types.Account(args.l1Transmitters[i].Hex()), + }, + ConfigEncryptionPublicKey: args.configPubKeys[i], + }) + l2Oracles = append(l2Oracles, confighelper2.OracleIdentityExtra{ + OracleIdentity: confighelper2.OracleIdentity{ + OffchainPublicKey: args.offchainPubKeys[i], + OnchainPublicKey: args.signers[i].Bytes(), + PeerID: args.peerIDs[i], + TransmitAccount: types.Account(args.l2Transmitters[i].Hex()), + }, + ConfigEncryptionPublicKey: args.configPubKeys[i], + }) + } + var schedule []int + for range l1Oracles { + schedule = append(schedule, 1) + } + offchainConfig, onchainConfig := []byte{}, []byte{} + f := uint8(1) + _, _, f, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( + args.deltaProgress, + args.deltaResend, + args.deltaInitial, + args.deltaRound, + args.deltaGrace, + args.deltaCertifiedCommitRequest, + args.deltaStage, + args.rMax, + schedule, + l2Oracles, + offchainConfig, + args.maxDurationQuery, + args.maxDurationObservation, + args.maxDurationShouldAcceptAttestedReport, + args.maxDurationShouldTransmitAcceptedReport, + int(f), + onchainConfig) + helpers.PanicErr(err) + tx, err := l2Rebalancer.SetOCR3Config(l2Transactor, args.signers, args.l2Transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + helpers.PanicErr(err) + helpers.ConfirmTXMined(context.Background(), e.Clients[args.l2ChainID], tx, int64(args.l2ChainID), "setting OCR3 config on L2 liquidityManager") + + fmt.Println("sleeping a bit before setting config on L1") + time.Sleep(1 * time.Minute) + + // set config on L1 + offchainConfig, onchainConfig = []byte{}, []byte{} + _, _, f, onchainConfig, offchainConfigVersion, offchainConfig, err = ocr3confighelper.ContractSetConfigArgsForTests( + args.deltaProgress, + args.deltaResend, + args.deltaInitial, + args.deltaRound, + args.deltaGrace, + args.deltaCertifiedCommitRequest, + args.deltaStage, + args.rMax, + schedule, + l1Oracles, + offchainConfig, + args.maxDurationQuery, + args.maxDurationObservation, + args.maxDurationShouldAcceptAttestedReport, + args.maxDurationShouldTransmitAcceptedReport, + int(f), + onchainConfig) + helpers.PanicErr(err) + tx, err = l1Rebalancer.SetOCR3Config(l1Transactor, args.signers, args.l1Transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + helpers.PanicErr(err) + helpers.ConfirmTXMined(context.Background(), e.Clients[args.l1ChainID], tx, int64(args.l1ChainID), "setting OCR3 config on L1 liquidityManager") +} + +func validateEnv(env multienv.Env, l1ChainID, l2ChainID uint64, websocket bool) { + _, ok := env.Clients[l1ChainID] + if !ok { + panic("L1 client not found") + } + _, ok = env.Clients[l2ChainID] + if !ok { + panic("L2 client not found") + } + _, ok = env.Transactors[l1ChainID] + if !ok { + panic("L1 transactor not found") + } + _, ok = env.Transactors[l2ChainID] + if !ok { + panic("L2 transactor not found") + } + if websocket { + _, ok = env.WSURLs[l1ChainID] + if !ok { + panic("L1 websocket URL not found") + } + _, ok = env.WSURLs[l2ChainID] + if !ok { + panic("L2 websocket URL not found") + } + } +} diff --git a/core/scripts/ccip/revert-reason/handler/reason.go b/core/scripts/ccip/revert-reason/handler/reason.go new file mode 100644 index 0000000000..2e41935ffa --- /dev/null +++ b/core/scripts/ccip/revert-reason/handler/reason.go @@ -0,0 +1,208 @@ +package handler + +import ( + "bytes" + "context" + "encoding/hex" + "encoding/json" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/usdc_token_pool" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/usdc_token_pool_1_4_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/burn_mint_erc677" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/erc20" +) + +// RevertReasonFromErrorCodeString attempts to decode an error code string +func (h *BaseHandler) RevertReasonFromErrorCodeString(errorCodeString string) (string, error) { + errorCodeString = strings.TrimPrefix(errorCodeString, "0x") + return DecodeErrorStringFromABI(errorCodeString) +} + +// RevertReasonFromTx attempts to fetch more info on failed TX +func (h *BaseHandler) RevertReasonFromTx(txHash string) (string, error) { + // Need a node URL + // NOTE: this node needs to run in archive mode + ethUrl := h.cfg.NodeURL + if ethUrl == "" { + panicErr(errors.New("you must define ETH_NODE env variable")) + } + requester := h.cfg.FromAddress + + ec, err := ethclient.Dial(ethUrl) + panicErr(err) + errorString, _ := GetErrorForTx(ec, txHash, requester) + + return DecodeErrorStringFromABI(errorString) +} + +func DecodeErrorStringFromABI(errorString string) (string, error) { + contractABIs := getAllABIs() + + // Sanitize error string + errorString = strings.TrimPrefix(errorString, "Reverted ") + errorString = strings.TrimPrefix(errorString, "0x") + + data, err := hex.DecodeString(errorString) + if err != nil { + return "", errors.Wrap(err, "error decoding error string") + } + + for _, contractABI := range contractABIs { + parsedAbi, err2 := abi.JSON(strings.NewReader(contractABI)) + if err2 != nil { + return "", errors.Wrap(err2, "error loading ABI") + } + + for errorName, abiError := range parsedAbi.Errors { + if bytes.Equal(data[:4], abiError.ID.Bytes()[:4]) { + // Found a matching error + v, err3 := abiError.Unpack(data) + if err3 != nil { + return "", errors.Wrap(err3, "error unpacking data") + } + + // If exec error, the actual error is within the revert reason + if errorName == "ExecutionError" || errorName == "TokenRateLimitError" || errorName == "TokenHandlingError" || errorName == "ReceiverError" { + // Get the inner type, which is `bytes` + fmt.Printf("Error is \"%v\" \ninner error: ", errorName) + errorBytes := v.([]interface{})[0].([]byte) + if len(errorBytes) < 4 { + return "[reverted without error code]", nil + } + return DecodeErrorStringFromABI(hex.EncodeToString(errorBytes)) + } + return fmt.Sprintf("error is \"%v\" args %v\n", errorName, v), nil + } + } + } + + if len(errorString) > 8 && errorString[:8] == "4e487b71" { + fmt.Println("Assertion failure") + indicator := errorString[len(errorString)-2:] + switch indicator { + case "01": + return "If you call assert with an argument that evaluates to false.", nil + case "11": + return "If an arithmetic operation results in underflow or overflow outside of an unchecked { ... } block.", nil + case "12": + return "If you divide or modulo by zero (e.g. 5 / 0 or 23 modulo 0).", nil + case "21": + return "If you convert a value that is too big or negative into an enum type.", nil + case "31": + return "If you call .pop() on an empty array.", nil + case "32": + return "If you access an array, bytesN or an array slice at an out-of-bounds or negative index (i.e. x[i] where i >= x.length or i < 0).", nil + case "41": + return "If you allocate too much memory or create an array that is too large.", nil + case "51": + return "If you call a zero-initialized variable of internal function type.", nil + default: + return fmt.Sprintf("This is a revert produced by an assertion failure. Exact code not found \"%s\"", indicator), nil + } + } + + stringErr, err := abi.UnpackRevert(data) + if err == nil { + return fmt.Sprintf("string error: %s", stringErr), nil + } + + return "", errors.Errorf(`cannot match error with contract ABI. Error code "%s"`, errorString) +} + +func getAllABIs() []string { + return []string{ + rmn_contract.RMNContractABI, + lock_release_token_pool_1_4_0.LockReleaseTokenPoolABI, + burn_mint_token_pool_1_2_0.BurnMintTokenPoolABI, + usdc_token_pool_1_4_0.USDCTokenPoolABI, + burn_mint_erc677.BurnMintERC677ABI, + erc20.ERC20ABI, + lock_release_token_pool.LockReleaseTokenPoolABI, + burn_mint_token_pool.BurnMintTokenPoolABI, + usdc_token_pool.USDCTokenPoolABI, + commit_store.CommitStoreABI, + token_admin_registry.TokenAdminRegistryABI, + price_registry.PriceRegistryABI, + evm_2_evm_onramp.EVM2EVMOnRampABI, + evm_2_evm_offramp.EVM2EVMOffRampABI, + router.RouterABI, + onramp.OnRampABI, + offramp.OffRampABI, + maybe_revert_message_receiver.MaybeRevertMessageReceiverABI, + } +} + +func GetErrorForTx(client *ethclient.Client, txHash string, requester string) (string, error) { + tx, _, err := client.TransactionByHash(context.Background(), common.HexToHash(txHash)) + if err != nil { + return "", errors.Wrap(err, "error getting transaction from hash") + } + re, err := client.TransactionReceipt(context.Background(), common.HexToHash(txHash)) + if err != nil { + return "", errors.Wrap(err, "error getting transaction receipt") + } + + call := ethereum.CallMsg{ + From: common.HexToAddress(requester), + To: tx.To(), + Data: tx.Data(), + Value: tx.Value(), + Gas: tx.Gas(), + GasPrice: tx.GasPrice(), + } + _, err = client.CallContract(context.Background(), call, re.BlockNumber) + if err == nil { + panic("no error calling contract") + } + + return parseError(err) +} + +func parseError(txError error) (string, error) { + b, err := json.Marshal(txError) + if err != nil { + return "", err + } + var callErr struct { + Code int + Data string `json:"data"` + Message string `json:"message"` + } + if json.Unmarshal(b, &callErr) != nil { + return "", err + } + + if callErr.Data == "" && strings.Contains(callErr.Message, "missing trie node") { + return "", errors.Errorf("please use an archive node") + } + + return callErr.Data, nil +} + +func panicErr(err error) { + if err != nil { + panic(err) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go index b571ce6f70..0cf876b0fe 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -27,7 +27,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper_1_0_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_0_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" @@ -166,7 +166,7 @@ func TestCommitStoreReaders(t *testing.T) { MerkleRoot: common.HexToHash("0x1"), } er := big.NewInt(1) - armAddr, _, arm, err := mock_arm_contract.DeployMockARMContract(user, ec) + armAddr, _, arm, err := mock_rmn_contract.DeployMockRMNContract(user, ec) require.NoError(t, err) addr, _, ch, err := commit_store_helper_1_0_0.DeployCommitStoreHelper(user, ec, commit_store_helper_1_0_0.CommitStoreStaticConfig{ ChainSelector: testutils.SimulatedChainID.Uint64(), diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go index 6ab22ded99..f131039320 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go @@ -25,7 +25,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_0_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" @@ -320,7 +320,7 @@ func deployMockArm( user *bind.TransactOpts, bc *client.SimulatedBackendClient, ) common.Address { - armAddr, tx, _, err := mock_arm_contract.DeployMockARMContract(user, bc) + armAddr, tx, _, err := mock_rmn_contract.DeployMockRMNContract(user, bc) require.NoError(t, err) bc.Commit() ccipdata.AssertNonRevert(t, tx, bc, user) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go index 969b1fa48f..6737abe64c 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go @@ -10,13 +10,12 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/smartcontractkit/chainlink-common/pkg/hashutil" - "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" @@ -44,7 +43,7 @@ type OnRamp struct { // Static config can be cached, because it's never expected to change. // The only way to change that is through the contract's constructor (redeployment) cachedStaticConfig cache.OnceCtxFunction[evm_2_evm_onramp_1_0_0.EVM2EVMOnRampStaticConfig] - cachedRmnContract cache.OnceCtxFunction[*arm_contract.ARMContract] + cachedRmnContract cache.OnceCtxFunction[*rmn_contract.RMNContract] } func NewOnRamp(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAddress common.Address, sourceLP logpoller.LogPoller, source client.Client) (*OnRamp, error) { @@ -72,13 +71,13 @@ func NewOnRamp(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAd cachedStaticConfig := cache.OnceCtxFunction[evm_2_evm_onramp_1_0_0.EVM2EVMOnRampStaticConfig](func(ctx context.Context) (evm_2_evm_onramp_1_0_0.EVM2EVMOnRampStaticConfig, error) { return onRamp.GetStaticConfig(&bind.CallOpts{Context: ctx}) }) - cachedRmnContract := cache.OnceCtxFunction[*arm_contract.ARMContract](func(ctx context.Context) (*arm_contract.ARMContract, error) { + cachedRmnContract := cache.OnceCtxFunction[*rmn_contract.RMNContract](func(ctx context.Context) (*rmn_contract.RMNContract, error) { staticConfig, err := cachedStaticConfig(ctx) if err != nil { return nil, err } - return arm_contract.NewARMContract(staticConfig.ArmProxy, source) + return rmn_contract.NewRMNContract(staticConfig.ArmProxy, source) }) return &OnRamp{ lggr: lggr, diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go index 9579286470..2939682347 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go @@ -11,13 +11,12 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/smartcontractkit/chainlink-common/pkg/hashutil" - "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" @@ -63,7 +62,7 @@ type OnRamp struct { // Static config can be cached, because it's never expected to change. // The only way to change that is through the contract's constructor (redeployment) cachedStaticConfig cache.OnceCtxFunction[evm_2_evm_onramp_1_2_0.EVM2EVMOnRampStaticConfig] - cachedRmnContract cache.OnceCtxFunction[*arm_contract.ARMContract] + cachedRmnContract cache.OnceCtxFunction[*rmn_contract.RMNContract] } func NewOnRamp(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAddress common.Address, sourceLP logpoller.LogPoller, source client.Client) (*OnRamp, error) { @@ -90,13 +89,13 @@ func NewOnRamp(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAd cachedStaticConfig := cache.OnceCtxFunction[evm_2_evm_onramp_1_2_0.EVM2EVMOnRampStaticConfig](func(ctx context.Context) (evm_2_evm_onramp_1_2_0.EVM2EVMOnRampStaticConfig, error) { return onRamp.GetStaticConfig(&bind.CallOpts{Context: ctx}) }) - cachedRmnContract := cache.OnceCtxFunction[*arm_contract.ARMContract](func(ctx context.Context) (*arm_contract.ARMContract, error) { + cachedRmnContract := cache.OnceCtxFunction[*rmn_contract.RMNContract](func(ctx context.Context) (*rmn_contract.RMNContract, error) { staticConfig, err := cachedStaticConfig(ctx) if err != nil { return nil, err } - return arm_contract.NewARMContract(staticConfig.ArmProxy, source) + return rmn_contract.NewRMNContract(staticConfig.ArmProxy, source) }) return &OnRamp{ lggr: lggr, diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go index d07fa7bb61..354a5defdd 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go @@ -13,11 +13,11 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/hashutil" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" @@ -64,7 +64,7 @@ type OnRamp struct { // Static config can be cached, because it's never expected to change. // The only way to change that is through the contract's constructor (redeployment) cachedStaticConfig cache.OnceCtxFunction[evm_2_evm_onramp.EVM2EVMOnRampStaticConfig] - cachedRmnContract cache.OnceCtxFunction[*arm_contract.ARMContract] + cachedRmnContract cache.OnceCtxFunction[*rmn_contract.RMNContract] } func NewOnRamp(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAddress common.Address, sourceLP logpoller.LogPoller, source client.Client) (*OnRamp, error) { @@ -92,13 +92,13 @@ func NewOnRamp(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAd cachedStaticConfig := cache.OnceCtxFunction[evm_2_evm_onramp.EVM2EVMOnRampStaticConfig](func(ctx context.Context) (evm_2_evm_onramp.EVM2EVMOnRampStaticConfig, error) { return onRamp.GetStaticConfig(&bind.CallOpts{Context: ctx}) }) - cachedRmnContract := cache.OnceCtxFunction[*arm_contract.ARMContract](func(ctx context.Context) (*arm_contract.ARMContract, error) { + cachedRmnContract := cache.OnceCtxFunction[*rmn_contract.RMNContract](func(ctx context.Context) (*rmn_contract.RMNContract, error) { staticConfig, err := cachedStaticConfig(ctx) if err != nil { return nil, err } - return arm_contract.NewARMContract(staticConfig.RmnProxy, source) + return rmn_contract.NewRMNContract(staticConfig.RmnProxy, source) }) return &OnRamp{ diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go index 3009718301..277b8fd900 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp_test.go @@ -18,7 +18,7 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcommon" @@ -105,7 +105,7 @@ func Test_ProperlyRecognizesPerLaneCurses(t *testing.T) { assert.True(t, isCursed) // Uncursing the chain selector - _, err = mockRMN.OwnerUnvoteToCurse(user, []mock_arm_contract.RMNUnvoteToCurseRecord{}, ccipcommon.SelectorToBytes(destChainSelector)) + _, err = mockRMN.OwnerUnvoteToCurse(user, []mock_rmn_contract.RMNUnvoteToCurseRecord{}, ccipcommon.SelectorToBytes(destChainSelector)) require.NoError(t, err) bc.Commit() @@ -129,8 +129,8 @@ func BenchmarkIsSourceCursedWithCache(b *testing.B) { } } -func setupOnRampV1_5_0(t testing.TB, user *bind.TransactOpts, bc *client.SimulatedBackendClient) (common.Address, *mock_arm_contract.MockARMContract, common.Address) { - rmnAddress, transaction, rmnContract, err := mock_arm_contract.DeployMockARMContract(user, bc) +func setupOnRampV1_5_0(t testing.TB, user *bind.TransactOpts, bc *client.SimulatedBackendClient) (common.Address, *mock_rmn_contract.MockRMNContract, common.Address) { + rmnAddress, transaction, rmnContract, err := mock_rmn_contract.DeployMockRMNContract(user, bc) bc.Commit() require.NoError(t, err) ccipdata.AssertNonRevert(t, transaction, bc, user) diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go index 194c977ea8..08bfa37c4c 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -29,7 +29,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper_1_2_0" @@ -38,8 +37,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" @@ -173,8 +173,8 @@ type Common struct { CustomToken *link_token_interface.LinkToken WrappedNative *weth9.WETH9 WrappedNativePool *lock_release_token_pool.LockReleaseTokenPool - ARM *mock_arm_contract.MockARMContract - ARMProxy *arm_proxy_contract.ARMProxyContract + ARM *mock_rmn_contract.MockRMNContract + ARMProxy *rmn_proxy_contract.RMNProxyContract PriceRegistry *price_registry_1_2_0.PriceRegistry TokenAdminRegistry *token_admin_registry.TokenAdminRegistry } @@ -658,38 +658,38 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh // │ Deploy RMN │ // ================================================================ - armSourceAddress, _, _, err := mock_arm_contract.DeployMockARMContract( + armSourceAddress, _, _, err := mock_rmn_contract.DeployMockRMNContract( sourceUser, sourceChain, ) require.NoError(t, err) - sourceARM, err := mock_arm_contract.NewMockARMContract(armSourceAddress, sourceChain) + sourceARM, err := mock_rmn_contract.NewMockRMNContract(armSourceAddress, sourceChain) require.NoError(t, err) - armProxySourceAddress, _, _, err := arm_proxy_contract.DeployARMProxyContract( + armProxySourceAddress, _, _, err := rmn_proxy_contract.DeployRMNProxyContract( sourceUser, sourceChain, armSourceAddress, ) require.NoError(t, err) - sourceARMProxy, err := arm_proxy_contract.NewARMProxyContract(armProxySourceAddress, sourceChain) + sourceARMProxy, err := rmn_proxy_contract.NewRMNProxyContract(armProxySourceAddress, sourceChain) require.NoError(t, err) sourceChain.Commit() - armDestAddress, _, _, err := mock_arm_contract.DeployMockARMContract( + armDestAddress, _, _, err := mock_rmn_contract.DeployMockRMNContract( destUser, destChain, ) require.NoError(t, err) - armProxyDestAddress, _, _, err := arm_proxy_contract.DeployARMProxyContract( + armProxyDestAddress, _, _, err := rmn_proxy_contract.DeployRMNProxyContract( destUser, destChain, armDestAddress, ) require.NoError(t, err) destChain.Commit() - destARM, err := mock_arm_contract.NewMockARMContract(armDestAddress, destChain) + destARM, err := mock_rmn_contract.NewMockRMNContract(armDestAddress, destChain) require.NoError(t, err) - destARMProxy, err := arm_proxy_contract.NewARMProxyContract(armProxyDestAddress, destChain) + destARMProxy, err := rmn_proxy_contract.NewRMNProxyContract(armProxyDestAddress, destChain) require.NoError(t, err) // ================================================================ diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go index 4ea5bb18d7..ceb96d4c15 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go @@ -28,7 +28,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" burn_mint_token_pool "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_4_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" evm_2_evm_offramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" @@ -37,8 +36,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_0_0" lock_release_token_pool "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" @@ -180,8 +180,8 @@ type Common struct { CustomToken *link_token_interface.LinkToken WrappedNative *weth9.WETH9 WrappedNativePool *lock_release_token_pool_1_0_0.LockReleaseTokenPool - ARM *mock_arm_contract.MockARMContract - ARMProxy *arm_proxy_contract.ARMProxyContract + ARM *mock_rmn_contract.MockRMNContract + ARMProxy *rmn_proxy_contract.RMNProxyContract PriceRegistry *price_registry_1_2_0.PriceRegistry } @@ -787,38 +787,38 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh sourceChain, sourceUser := testhelpers.SetupChain(t) destChain, destUser := testhelpers.SetupChain(t) - armSourceAddress, _, _, err := mock_arm_contract.DeployMockARMContract( + armSourceAddress, _, _, err := mock_rmn_contract.DeployMockRMNContract( sourceUser, sourceChain, ) require.NoError(t, err) - sourceARM, err := mock_arm_contract.NewMockARMContract(armSourceAddress, sourceChain) + sourceARM, err := mock_rmn_contract.NewMockRMNContract(armSourceAddress, sourceChain) require.NoError(t, err) - armProxySourceAddress, _, _, err := arm_proxy_contract.DeployARMProxyContract( + armProxySourceAddress, _, _, err := rmn_proxy_contract.DeployRMNProxyContract( sourceUser, sourceChain, armSourceAddress, ) require.NoError(t, err) - sourceARMProxy, err := arm_proxy_contract.NewARMProxyContract(armProxySourceAddress, sourceChain) + sourceARMProxy, err := rmn_proxy_contract.NewRMNProxyContract(armProxySourceAddress, sourceChain) require.NoError(t, err) sourceChain.Commit() - armDestAddress, _, _, err := mock_arm_contract.DeployMockARMContract( + armDestAddress, _, _, err := mock_rmn_contract.DeployMockRMNContract( destUser, destChain, ) require.NoError(t, err) - armProxyDestAddress, _, _, err := arm_proxy_contract.DeployARMProxyContract( + armProxyDestAddress, _, _, err := rmn_proxy_contract.DeployRMNProxyContract( destUser, destChain, armDestAddress, ) require.NoError(t, err) destChain.Commit() - destARM, err := mock_arm_contract.NewMockARMContract(armDestAddress, destChain) + destARM, err := mock_rmn_contract.NewMockRMNContract(armDestAddress, destChain) require.NoError(t, err) - destARMProxy, err := arm_proxy_contract.NewARMProxyContract(armProxyDestAddress, destChain) + destARMProxy, err := rmn_proxy_contract.NewRMNProxyContract(armProxyDestAddress, destChain) require.NoError(t, err) // Deploy link token and pool on source chain diff --git a/core/services/ocr2/plugins/liquiditymanager/internal/integration_test.go b/core/services/ocr2/plugins/liquiditymanager/internal/integration_test.go index e648781ad1..765366a5c3 100644 --- a/core/services/ocr2/plugins/liquiditymanager/internal/integration_test.go +++ b/core/services/ocr2/plugins/liquiditymanager/internal/integration_test.go @@ -35,9 +35,9 @@ import ( v2toml "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" evmutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/liquiditymanager" @@ -644,11 +644,11 @@ func deployContracts( // deploy arm and arm proxy. // required by the token pool // otherwise not used by this test. - armAddress, _, _, err := mock_arm_contract.DeployMockARMContract(owner, backend) - require.NoError(t, err, "failed to deploy MockARMContract contract") + armAddress, _, _, err := mock_rmn_contract.DeployMockRMNContract(owner, backend) + require.NoError(t, err, "failed to deploy MockRMNContract contract") backend.Commit() - armProxyAddress, _, _, err := arm_proxy_contract.DeployARMProxyContract(owner, backend, armAddress) - require.NoError(t, err, "failed to deploy ARMProxyContract contract") + armProxyAddress, _, _, err := rmn_proxy_contract.DeployRMNProxyContract(owner, backend, armAddress) + require.NoError(t, err, "failed to deploy RMNProxyContract contract") backend.Commit() routerAddress, _, _, err := router.DeployRouter(owner, backend, wethAddress, armProxyAddress) diff --git a/integration-tests/ccip-tests/actions/ccip_helpers.go b/integration-tests/ccip-tests/actions/ccip_helpers.go index 7594a9dc44..ff8bfa2c9a 100644 --- a/integration-tests/ccip-tests/actions/ccip_helpers.go +++ b/integration-tests/ccip-tests/actions/ccip_helpers.go @@ -52,13 +52,13 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_pool" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" @@ -165,7 +165,7 @@ type CCIPCommon struct { NoOfTokensNeedingDynamicPrice int BridgeTokenPools []*contracts.TokenPool RateLimiterConfig contracts.RateLimiterConfig - ARMContract *common.Address + RMNContract *common.Address ARM *contracts.ARM // populate only if the ARM contracts is not a mock and can be used to verify various ARM events; keep this nil for mock ARM Router *contracts.Router PriceRegistry *contracts.PriceRegistry @@ -202,10 +202,10 @@ func (ccipModule *CCIPCommon) UnvoteToCurseARM() error { if ccipModule.ARM != nil { return fmt.Errorf("real ARM deployed. cannot curse through test") } - if ccipModule.ARMContract == nil { + if ccipModule.RMNContract == nil { return fmt.Errorf("no ARM contract is set") } - arm, err := mock_arm_contract.NewMockARMContract(*ccipModule.ARMContract, ccipModule.ChainClient.Backend()) + arm, err := mock_rmn_contract.NewMockRMNContract(*ccipModule.RMNContract, ccipModule.ChainClient.Backend()) if err != nil { return fmt.Errorf("error instantiating arm %w", err) } @@ -213,7 +213,7 @@ func (ccipModule *CCIPCommon) UnvoteToCurseARM() error { if err != nil { return fmt.Errorf("error getting owners for ARM OwnerUnvoteToCurse %w", err) } - tx, err := arm.OwnerUnvoteToCurse0(opts, []mock_arm_contract.RMNUnvoteToCurseRecord{}) + tx, err := arm.OwnerUnvoteToCurse0(opts, []mock_rmn_contract.RMNUnvoteToCurseRecord{}) if err != nil { return fmt.Errorf("error in calling OwnerUnvoteToCurse %w", err) } @@ -231,10 +231,10 @@ func (ccipModule *CCIPCommon) IsCursed() (bool, error) { if ccipModule.ARM != nil { return false, fmt.Errorf("real ARM deployed. cannot validate cursing") } - if ccipModule.ARMContract == nil { + if ccipModule.RMNContract == nil { return false, fmt.Errorf("no ARM contract is set") } - arm, err := mock_arm_contract.NewMockARMContract(*ccipModule.ARMContract, ccipModule.ChainClient.Backend()) + arm, err := mock_rmn_contract.NewMockRMNContract(*ccipModule.RMNContract, ccipModule.ChainClient.Backend()) if err != nil { return false, fmt.Errorf("error instantiating arm %w", err) } @@ -245,10 +245,10 @@ func (ccipModule *CCIPCommon) CurseARM() (*types.Transaction, error) { if ccipModule.ARM != nil { return nil, fmt.Errorf("real ARM deployed. cannot curse through test") } - if ccipModule.ARMContract == nil { + if ccipModule.RMNContract == nil { return nil, fmt.Errorf("no ARM contract is set") } - arm, err := mock_arm_contract.NewMockARMContract(*ccipModule.ARMContract, ccipModule.ChainClient.Backend()) + arm, err := mock_rmn_contract.NewMockRMNContract(*ccipModule.RMNContract, ccipModule.ChainClient.Backend()) if err != nil { return nil, fmt.Errorf("error instantiating arm %w", err) } @@ -291,7 +291,7 @@ func (ccipModule *CCIPCommon) LoadContractAddresses(conf *laneconfig.LaneConfig, } if common.IsHexAddress(conf.ARM) { addr := common.HexToAddress(conf.ARM) - ccipModule.ARMContract = &addr + ccipModule.RMNContract = &addr if !conf.IsMockARM { ccipModule.ARM = &contracts.ARM{ EthAddress: addr, @@ -729,7 +729,7 @@ func (ccipModule *CCIPCommon) WriteLaneConfig(conf *laneconfig.LaneConfig) { FeeToken: ccipModule.FeeToken.Address(), BridgeTokens: btAddresses, BridgeTokenPools: btpAddresses, - ARM: ccipModule.ARMContract.Hex(), + ARM: ccipModule.RMNContract.Hex(), Router: ccipModule.Router.Address(), PriceRegistry: ccipModule.PriceRegistry.Address(), PriceAggregators: priceAggrs, @@ -783,18 +783,18 @@ func (ccipModule *CCIPCommon) DeployContracts( ccipModule.LoadContractAddresses(conf, &noOfTokens) if ccipModule.ARM != nil { - arm, err := cd.NewARMContract(ccipModule.ARM.EthAddress) + arm, err := cd.NewRMNContract(ccipModule.ARM.EthAddress) if err != nil { return fmt.Errorf("getting new ARM contract shouldn't fail %w", err) } ccipModule.ARM = arm } else { // deploy a mock ARM contract - if ccipModule.ARMContract == nil { + if ccipModule.RMNContract == nil { if ccipModule.ExistingDeployment { return fmt.Errorf("ARM contract address is not provided in lane config") } - ccipModule.ARMContract, err = cd.DeployMockARMContract() + ccipModule.RMNContract, err = cd.DeployMockRMNContract() if err != nil { return fmt.Errorf("deploying mock ARM contract shouldn't fail %w", err) } @@ -827,7 +827,7 @@ func (ccipModule *CCIPCommon) DeployContracts( if ccipModule.ExistingDeployment { return fmt.Errorf("router contract address is not provided in lane config") } - ccipModule.Router, err = cd.DeployRouter(ccipModule.WrappedNative, *ccipModule.ARMContract) + ccipModule.Router, err = cd.DeployRouter(ccipModule.WrappedNative, *ccipModule.RMNContract) if err != nil { return fmt.Errorf("deploying router shouldn't fail %w", err) } @@ -979,7 +979,7 @@ func (ccipModule *CCIPCommon) DeployContracts( if ccipModule.TokenTransmitter == nil { return fmt.Errorf("TokenTransmitter contract address is not provided") } - usdcPool, err := ccipModule.tokenDeployer.DeployUSDCTokenPoolContract(token.Address(), *ccipModule.TokenMessenger, *ccipModule.ARMContract, ccipModule.Router.Instance.Address()) + usdcPool, err := ccipModule.tokenDeployer.DeployUSDCTokenPoolContract(token.Address(), *ccipModule.TokenMessenger, *ccipModule.RMNContract, ccipModule.Router.Instance.Address()) if err != nil { return fmt.Errorf("deploying bridge Token pool(usdc) shouldn't fail %w", err) } @@ -987,7 +987,7 @@ func (ccipModule *CCIPCommon) DeployContracts( ccipModule.BridgeTokenPools = append(ccipModule.BridgeTokenPools, usdcPool) } else { // deploy lock release token pool in case of non-usdc deployment - btp, err := ccipModule.tokenDeployer.DeployLockReleaseTokenPoolContract(token.Address(), *ccipModule.ARMContract, ccipModule.Router.Instance.Address()) + btp, err := ccipModule.tokenDeployer.DeployLockReleaseTokenPoolContract(token.Address(), *ccipModule.RMNContract, ccipModule.Router.Instance.Address()) if err != nil { return fmt.Errorf("deploying bridge Token pool(lock&release) shouldn't fail %w", err) } @@ -1178,7 +1178,7 @@ func NewCCIPCommonFromConfig( } var arm *contracts.ARM if newCCIPModule.ARM != nil { - arm, err = newCD.NewARMContract(*newCCIPModule.ARMContract) + arm, err = newCD.NewRMNContract(*newCCIPModule.RMNContract) if err != nil { return nil, err } @@ -1414,7 +1414,7 @@ func (sourceCCIP *SourceCCIPModule) DeployContracts(lane *laneconfig.LaneConfig) sourceChainSelector, sourceCCIP.DestChainSelector, tokensAndPools, - *sourceCCIP.Common.ARMContract, + *sourceCCIP.Common.RMNContract, sourceCCIP.Common.Router.EthAddress, sourceCCIP.Common.PriceRegistry.EthAddress, tokenAdminReg, @@ -2025,7 +2025,7 @@ func (destCCIP *DestCCIPModule) DeployContracts( destCCIP.SourceChainSelector, destChainSelector, sourceCCIP.OnRamp.EthAddress, - *destCCIP.Common.ARMContract, + *destCCIP.Common.RMNContract, ) if err != nil { return fmt.Errorf("deploying commitstore shouldn't fail %w", err) @@ -2070,7 +2070,7 @@ func (destCCIP *DestCCIPModule) DeployContracts( destCCIP.Common.RateLimiterConfig, []common.Address{}, []common.Address{}, - *destCCIP.Common.ARMContract, + *destCCIP.Common.RMNContract, tokenAdminReg, ) if err != nil { @@ -3394,7 +3394,7 @@ func (lane *CCIPLane) StartEventWatchers() error { }(reportAccSub) if lane.Dest.Common.ARM != nil { - reportBlessedEvent := make(chan *arm_contract.ARMContractTaggedRootBlessed) + reportBlessedEvent := make(chan *rmn_contract.RMNContractTaggedRootBlessed) blessedSub := event.Resubscribe(DefaultResubscriptionTimeout, func(_ context.Context) (event.Subscription, error) { sub, err := lane.Dest.Common.ARM.Instance.WatchTaggedRootBlessed(nil, reportBlessedEvent, nil) if err != nil { diff --git a/integration-tests/ccip-tests/contracts/contract_deployer.go b/integration-tests/ccip-tests/contracts/contract_deployer.go index 3454fd1579..bc797ad5da 100644 --- a/integration-tests/ccip-tests/contracts/contract_deployer.go +++ b/integration-tests/ccip-tests/contracts/contract_deployer.go @@ -27,7 +27,6 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/wrappers" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" @@ -37,11 +36,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_messenger" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_v3_aggregator_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_pool" @@ -541,18 +541,18 @@ func (e *CCIPContractsDeployer) DeployLockReleaseTokenPoolContract(tokenAddr str } } -func (e *CCIPContractsDeployer) DeployMockARMContract() (*common.Address, error) { +func (e *CCIPContractsDeployer) DeployMockRMNContract() (*common.Address, error) { address, _, _, err := e.evmClient.DeployContract("Mock ARM Contract", func( auth *bind.TransactOpts, _ bind.ContractBackend, ) (common.Address, *types.Transaction, interface{}, error) { - return mock_arm_contract.DeployMockARMContract(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) + return mock_rmn_contract.DeployMockRMNContract(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) }) return address, err } -func (e *CCIPContractsDeployer) NewARMContract(addr common.Address) (*ARM, error) { - arm, err := arm_contract.NewARMContract(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) +func (e *CCIPContractsDeployer) NewRMNContract(addr common.Address) (*ARM, error) { + arm, err := rmn_contract.NewRMNContract(addr, wrappers.MustNewWrappedContractBackend(e.evmClient, nil)) if err != nil { return nil, err } diff --git a/integration-tests/ccip-tests/contracts/contract_models.go b/integration-tests/ccip-tests/contracts/contract_models.go index 1c2f3651b0..26794816dd 100644 --- a/integration-tests/ccip-tests/contracts/contract_models.go +++ b/integration-tests/ccip-tests/contracts/contract_models.go @@ -21,7 +21,6 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/wrappers" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" @@ -31,11 +30,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_v3_aggregator_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_pool" @@ -944,7 +944,7 @@ func (pool *TokenPool) GetRebalancer() (common.Address, error) { type ARM struct { client blockchain.EVMClient - Instance *arm_contract.ARMContract + Instance *rmn_contract.RMNContract EthAddress common.Address } @@ -954,7 +954,7 @@ func (arm *ARM) Address() string { type MockARM struct { client blockchain.EVMClient - Instance *mock_arm_contract.MockARMContract + Instance *mock_rmn_contract.MockRMNContract EthAddress common.Address } diff --git a/integration-tests/ccip-tests/contracts/lm_contracts.go b/integration-tests/ccip-tests/contracts/lm_contracts.go new file mode 100644 index 0000000000..2ee5078aa7 --- /dev/null +++ b/integration-tests/ccip-tests/contracts/lm_contracts.go @@ -0,0 +1,320 @@ +package contracts + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/rs/zerolog" + + "github.com/smartcontractkit/chainlink/integration-tests/wrappers" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_l1_bridge_adapter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_l2_bridge_adapter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/liquiditymanager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/mock_l1_bridge_adapter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/mock_l2_bridge_adapter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_l1_bridge_adapter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_l2_bridge_adapter" +) + +type ArmProxy struct { + client blockchain.EVMClient + Instance *rmn_proxy_contract.RMNProxyContract + EthAddress *common.Address +} + +func (e *CCIPContractsDeployer) DeployArmProxy(arm common.Address) (*ArmProxy, error) { + address, _, instance, err := e.evmClient.DeployContract("ARMProxy", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return rmn_proxy_contract.DeployRMNProxyContract( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + arm, + ) + }) + if err != nil { + return nil, err + } + return &ArmProxy{ + client: e.evmClient, + Instance: instance.(*rmn_proxy_contract.RMNProxyContract), + EthAddress: address, + }, err +} + +type LiquidityManager struct { + client blockchain.EVMClient + logger *zerolog.Logger + Instance *liquiditymanager.LiquidityManager + EthAddress *common.Address +} + +func (e *CCIPContractsDeployer) DeployLiquidityManager( + token common.Address, + localChainSelector uint64, + localLiquidityContainer common.Address, + minimumLiquidity *big.Int, +) (*LiquidityManager, error) { + address, _, instance, err := e.evmClient.DeployContract("LiquidityManager", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return liquiditymanager.DeployLiquidityManager( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + token, + localChainSelector, + localLiquidityContainer, + minimumLiquidity, + common.Address{}, + ) + }) + if err != nil { + return nil, err + } + return &LiquidityManager{ + client: e.evmClient, + logger: e.logger, + Instance: instance.(*liquiditymanager.LiquidityManager), + EthAddress: address, + }, err +} + +func (v *LiquidityManager) GetLiquidity() (*big.Int, error) { + return v.Instance.GetLiquidity(nil) +} + +func (v *LiquidityManager) SetCrossChainRebalancer( + crossChainRebalancerArgs liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs, +) error { + v.logger.Info(). + Str("Liquidity Manager", v.EthAddress.String()). + Msg("Setting crosschain rebalancer on liquidity manager") + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + tx, err := v.Instance.SetCrossChainRebalancer(opts, crossChainRebalancerArgs) + if err != nil { + return fmt.Errorf("failed to set cross chain rebalancer: %w", err) + + } + v.logger.Info(). + Str("Liquidity Manager", v.EthAddress.String()). + Interface("Rebalance Argsr", crossChainRebalancerArgs). + Msg("Crosschain Rebalancer set on liquidity manager") + return v.client.ProcessTransaction(tx) +} + +func (v *LiquidityManager) SetOCR3Config( + signers []common.Address, + transmitters []common.Address, + f uint8, + onchainConfig []byte, + offchainConfigVersion uint64, + offchainConfig []byte, +) error { + v.logger.Info(). + Str("Liquidity Manager", v.EthAddress.String()). + Msg("Setting ocr3 config on liquidity manager") + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return fmt.Errorf("failed to get transaction opts: %w", err) + } + tx, err := v.Instance.SetOCR3Config( + opts, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig) + if err != nil { + return fmt.Errorf("failed to set cross chain rebalancer: %w", err) + + } + v.logger.Info(). + Str("Liquidity Manager", v.EthAddress.String()). + Msg("Set OCR3Config on LM") + return v.client.ProcessTransaction(tx) +} + +type ArbitrumL1BridgeAdapter struct { + client blockchain.EVMClient + Instance *arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapter + EthAddress *common.Address +} + +func (e *CCIPContractsDeployer) DeployArbitrumL1BridgeAdapter( + l1GatewayRouter common.Address, + l1Outbox common.Address, +) (*ArbitrumL1BridgeAdapter, error) { + address, _, instance, err := e.evmClient.DeployContract("ArbitrumL1BridgeAdapter", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return arbitrum_l1_bridge_adapter.DeployArbitrumL1BridgeAdapter( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + l1GatewayRouter, + l1Outbox, + ) + }) + if err != nil { + return nil, err + } + return &ArbitrumL1BridgeAdapter{ + client: e.evmClient, + Instance: instance.(*arbitrum_l1_bridge_adapter.ArbitrumL1BridgeAdapter), + EthAddress: address, + }, err +} + +type ArbitrumL2BridgeAdapter struct { + client blockchain.EVMClient + Instance *arbitrum_l2_bridge_adapter.ArbitrumL2BridgeAdapter + EthAddress *common.Address +} + +func (e *CCIPContractsDeployer) DeployArbitrumL2BridgeAdapter(l2GatewayRouter common.Address) (*ArbitrumL2BridgeAdapter, error) { + address, _, instance, err := e.evmClient.DeployContract("ArbitrumL2BridgeAdapter", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return arbitrum_l2_bridge_adapter.DeployArbitrumL2BridgeAdapter( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + l2GatewayRouter, + ) + }) + if err != nil { + return nil, err + } + return &ArbitrumL2BridgeAdapter{ + client: e.evmClient, + Instance: instance.(*arbitrum_l2_bridge_adapter.ArbitrumL2BridgeAdapter), + EthAddress: address, + }, err +} + +type OptimismL1BridgeAdapter struct { + client blockchain.EVMClient + Instance *optimism_l1_bridge_adapter.OptimismL1BridgeAdapter + EthAddress *common.Address +} + +func (e *CCIPContractsDeployer) DeployOptimismL1BridgeAdapter( + l1Bridge common.Address, + wrappedNative common.Address, + optimismPortal common.Address, +) (*OptimismL1BridgeAdapter, error) { + address, _, instance, err := e.evmClient.DeployContract("OptimismL1BridgeAdapter", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return optimism_l1_bridge_adapter.DeployOptimismL1BridgeAdapter( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + l1Bridge, + wrappedNative, + optimismPortal, + ) + }) + if err != nil { + return nil, err + } + return &OptimismL1BridgeAdapter{ + client: e.evmClient, + Instance: instance.(*optimism_l1_bridge_adapter.OptimismL1BridgeAdapter), + EthAddress: address, + }, err +} + +type OptimismL2BridgeAdapter struct { + client blockchain.EVMClient + Instance *optimism_l2_bridge_adapter.OptimismL2BridgeAdapter + EthAddress *common.Address +} + +func (e *CCIPContractsDeployer) DeployOptimismL2BridgeAdapter(wrappedNative common.Address) (*OptimismL2BridgeAdapter, error) { + address, _, instance, err := e.evmClient.DeployContract("OptimismL2BridgeAdapter", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return optimism_l2_bridge_adapter.DeployOptimismL2BridgeAdapter( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + wrappedNative, + ) + }) + if err != nil { + return nil, err + } + return &OptimismL2BridgeAdapter{ + client: e.evmClient, + Instance: instance.(*optimism_l2_bridge_adapter.OptimismL2BridgeAdapter), + EthAddress: address, + }, err +} + +type MockL1BridgeAdapter struct { + client blockchain.EVMClient + Instance *mock_l1_bridge_adapter.MockL1BridgeAdapter + EthAddress *common.Address +} + +func (e *CCIPContractsDeployer) DeployMockL1BridgeAdapter(tokenAddr common.Address, holdNative bool) (*MockL1BridgeAdapter, error) { + address, _, instance, err := e.evmClient.DeployContract("MockL1BridgeAdapter", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return mock_l1_bridge_adapter.DeployMockL1BridgeAdapter( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + tokenAddr, + holdNative, + ) + }) + if err != nil { + return nil, err + } + return &MockL1BridgeAdapter{ + client: e.evmClient, + Instance: instance.(*mock_l1_bridge_adapter.MockL1BridgeAdapter), + EthAddress: address, + }, err +} + +type MockL2BridgeAdapter struct { + client blockchain.EVMClient + Instance *mock_l2_bridge_adapter.MockL2BridgeAdapter + EthAddress *common.Address +} + +func (e *CCIPContractsDeployer) DeployMockL2BridgeAdapter() (*MockL2BridgeAdapter, error) { + address, _, instance, err := e.evmClient.DeployContract("MockL2BridgeAdapter", func( + auth *bind.TransactOpts, + _ bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return mock_l2_bridge_adapter.DeployMockL2BridgeAdapter( + auth, + wrappers.MustNewWrappedContractBackend(e.evmClient, nil), + ) + }) + if err != nil { + return nil, err + } + return &MockL2BridgeAdapter{ + client: e.evmClient, + Instance: instance.(*mock_l2_bridge_adapter.MockL2BridgeAdapter), + EthAddress: address, + }, err +} diff --git a/integration-tests/ccip-tests/testsetups/lm_setup.go b/integration-tests/ccip-tests/testsetups/lm_setup.go new file mode 100644 index 0000000000..9884d9661c --- /dev/null +++ b/integration-tests/ccip-tests/testsetups/lm_setup.go @@ -0,0 +1,845 @@ +package testsetups + +import ( + "context" + "crypto/ed25519" + "encoding/hex" + "fmt" + "math/big" + "os" + "strconv" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/erc20" + + ocrconfighelper2 "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" + ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + "golang.org/x/crypto/curve25519" + + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + + "github.com/ethereum/go-ethereum/common" + "github.com/lib/pq" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/liquiditymanager" + + "github.com/AlekSi/pointer" + "github.com/pkg/errors" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + chainselectors "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + "golang.org/x/sync/errgroup" + + integrationactions "github.com/smartcontractkit/chainlink/integration-tests/actions" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" + "github.com/smartcontractkit/chainlink-testing-framework/k8s/config" + "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" + + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + + integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/testhelpers/integration" +) + +type LMTestSetupOutputs struct { + CCIPTestSetUpOutputs + LMModules map[int64]*actions.LMCommon +} + +// TODO - Copied over from ccip tests as such. Refactor and remove unused code +func (o *LMTestSetupOutputs) CreateLMEnvironment( + lggr *zerolog.Logger, + envName string, + reportPath string, +) map[int64]blockchain.EVMClient { + t := o.Cfg.Test + testConfig := o.Cfg + var ( + ccipEnv *actions.CCIPTestEnv + k8Env *environment.Environment + err error + chains []blockchain.EVMClient + local *test_env.CLClusterTestEnv + deployCL func() error + ) + + envConfig := createEnvironmentConfig(t, envName, testConfig, reportPath) + + configureCLNode := !testConfig.useExistingDeployment() || pointer.GetString(testConfig.EnvInput.EnvToConnect) != "" + namespace := "" + if testConfig.TestGroupInput.LoadProfile != nil { + namespace = testConfig.TestGroupInput.LoadProfile.TestRunName + } + require.False(t, testConfig.localCluster() && testConfig.ExistingCLCluster(), + "local cluster and existing cluster cannot be true at the same time") + // if it's a new deployment, deploy the env + // Or if EnvToConnect is given connect to that k8 environment + if configureCLNode { + if !testConfig.ExistingCLCluster() { + // if it's a local cluster, deploy the local cluster in docker + if testConfig.localCluster() { + local, deployCL = DeployLocalCluster(t, testConfig) + ccipEnv = &actions.CCIPTestEnv{ + LocalCluster: local, + } + namespace = "local-docker-deployment" + } else { + // Otherwise, deploy the k8s env + lggr.Info().Msg("Deploying test environment") + // deploy the env if configureCLNode is true + k8Env = DeployEnvironments(t, envConfig, testConfig) + ccipEnv = &actions.CCIPTestEnv{K8Env: k8Env} + namespace = ccipEnv.K8Env.Cfg.Namespace + } + } else { + // if there is already a cluster, use the existing cluster to connect to the nodes + ccipEnv = &actions.CCIPTestEnv{} + mockserverURL := pointer.GetString(testConfig.EnvInput.Mockserver) + require.NotEmpty(t, mockserverURL, "mockserver URL cannot be nil") + ccipEnv.MockServer = ctfClient.NewMockserverClient(&ctfClient.MockserverConfig{ + LocalURL: mockserverURL, + ClusterURL: mockserverURL, + }) + } + ccipEnv.CLNodeWithKeyReady, _ = errgroup.WithContext(o.SetUpContext) + o.Env = ccipEnv + if ccipEnv.K8Env != nil && ccipEnv.K8Env.WillUseRemoteRunner() { + return nil + } + } else { + // if configureCLNode is false it means we don't need to deploy any additional pods, + // use a placeholder env to create just the remote runner in it. + if value, set := os.LookupEnv(config.EnvVarJobImage); set && value != "" { + k8Env = environment.New(envConfig) + err = k8Env.Run() + require.NoErrorf(t, err, "error creating environment remote runner") + o.Env = &actions.CCIPTestEnv{K8Env: k8Env} + if k8Env.WillUseRemoteRunner() { + return nil + } + } + } + chainByChainID := make(map[int64]blockchain.EVMClient) + if pointer.GetBool(testConfig.TestGroupInput.LocalCluster) { + require.NotNil(t, ccipEnv.LocalCluster, "Local cluster shouldn't be nil") + for _, n := range ccipEnv.LocalCluster.EVMNetworks { + if evmClient, err := blockchain.NewEVMClientFromNetwork(*n, *lggr); err == nil { + chainByChainID[evmClient.GetChainID().Int64()] = evmClient + chains = append(chains, evmClient) + } else { + lggr.Error().Err(err).Msgf("EVMClient for chainID %d not found", n.ChainID) + } + } + } else { + for _, n := range testConfig.SelectedNetworks { + if _, ok := chainByChainID[n.ChainID]; ok { + continue + } + var ec blockchain.EVMClient + if k8Env == nil { + ec, err = blockchain.ConnectEVMClient(n, *lggr) + } else { + log.Info().Interface("urls", k8Env.URLs).Msg("URLs") + ec, err = blockchain.NewEVMClient(n, k8Env, *lggr) + } + require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail") + chains = append(chains, ec) + chainByChainID[n.ChainID] = ec + } + } + if configureCLNode { + ccipEnv.CLNodeWithKeyReady.Go(func() error { + var totalNodes int + if !o.Cfg.ExistingCLCluster() { + if ccipEnv.LocalCluster != nil { + err = deployCL() + if err != nil { + return err + } + } + err = ccipEnv.ConnectToDeployedNodes() + if err != nil { + return fmt.Errorf("error connecting to chainlink nodes: %w", err) + } + totalNodes = pointer.GetInt(testConfig.EnvInput.NewCLCluster.NoOfNodes) + } else { + totalNodes = pointer.GetInt(testConfig.EnvInput.ExistingCLCluster.NoOfNodes) + err = ccipEnv.ConnectToExistingNodes(o.Cfg.EnvInput) + if err != nil { + return fmt.Errorf("error deploying and connecting to chainlink nodes: %w", err) + } + } + err = ccipEnv.SetUpNodeKeysAndFund(lggr, big.NewFloat(testConfig.TestGroupInput.NodeFunding), chains) + if err != nil { + return fmt.Errorf("error setting up nodes and keys %w", err) + } + // first node is the bootstrapper + ccipEnv.CommitNodeStartIndex = 1 + ccipEnv.ExecNodeStartIndex = 1 + ccipEnv.NumOfCommitNodes = testConfig.TestGroupInput.NoOfCommitNodes + ccipEnv.NumOfExecNodes = ccipEnv.NumOfCommitNodes + if !pointer.GetBool(testConfig.TestGroupInput.CommitAndExecuteOnSameDON) { + if len(ccipEnv.CLNodesWithKeys) < 11 { + return fmt.Errorf("not enough CL nodes for separate commit and execution nodes") + } + if testConfig.TestGroupInput.NoOfCommitNodes >= totalNodes { + return fmt.Errorf("number of commit nodes can not be greater than total number of nodes in DON") + } + // first two nodes are reserved for bootstrap commit and bootstrap exec + ccipEnv.CommitNodeStartIndex = 2 + ccipEnv.ExecNodeStartIndex = 2 + testConfig.TestGroupInput.NoOfCommitNodes + ccipEnv.NumOfExecNodes = totalNodes - (2 + testConfig.TestGroupInput.NoOfCommitNodes) + if ccipEnv.NumOfExecNodes < 4 { + return fmt.Errorf("insufficient number of exec nodes") + } + } + ccipEnv.NumOfAllowedFaultyExec = (ccipEnv.NumOfExecNodes - 1) / 3 + ccipEnv.NumOfAllowedFaultyCommit = (ccipEnv.NumOfCommitNodes - 1) / 3 + return nil + }) + } + + t.Cleanup(func() { + if configureCLNode { + if ccipEnv.LocalCluster != nil { + err := ccipEnv.LocalCluster.Terminate() + require.NoError(t, err, "Local cluster termination shouldn't fail") + //require.NoError(t, o.Reporter.SendReport(t, namespace, false), "Aggregating and sending report shouldn't fail") + return + } + if pointer.GetBool(testConfig.TestGroupInput.KeepEnvAlive) || testConfig.ExistingCLCluster() { + //require.NoError(t, o.Reporter.SendReport(t, namespace, true), "Aggregating and sending report shouldn't fail") + return + } + lggr.Info().Msg("Tearing down the environment") + err = integrationactions.TeardownSuite(t, nil, ccipEnv.K8Env, ccipEnv.CLNodes, o.Reporter, zapcore.DPanicLevel, o.Cfg.EnvInput) + require.NoError(t, err, "Environment teardown shouldn't fail") + } else { + //just send the report + require.NoError(t, o.Reporter.SendReport(t, namespace, true), "Aggregating and sending report shouldn't fail") + } + }) + return chainByChainID +} + +func (o *LMTestSetupOutputs) DeployLMChainContracts( + lggr *zerolog.Logger, + networkCfg blockchain.EVMNetwork, + lmCommon actions.LMCommon, + l2ChainID int64, +) error { + var k8Env *environment.Environment + ccipEnv := o.Env + chainClient := lmCommon.ChainClient + if ccipEnv != nil { + k8Env = ccipEnv.K8Env + } + if k8Env != nil && chainClient.NetworkSimulated() { + networkCfg.URLs = k8Env.URLs[chainClient.GetNetworkConfig().Name] + } + + chain, err := blockchain.ConcurrentEVMClient(networkCfg, k8Env, chainClient, *lggr) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create chain client for %s: %w", networkCfg.Name, err)) + } + + chain.ParallelTransactions(true) + //defer chain.Close() + + cd, err := contracts.NewCCIPContractsDeployer(lggr, chain) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create contract deployer: %w", err)) + } + + // Deploy Wrapped Native contract only on private geth networks + if lmCommon.ChainSelectror == chainselectors.GETH_TESTNET.Selector || + lmCommon.ChainSelectror == chainselectors.GETH_DEVNET_2.Selector { + lggr.Info().Msg("Deploying Wrapped Native contract") + wrapperNative, err := cd.DeployWrappedNative() + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy Wrapped Native contract: %w", err)) + } + lggr.Info().Str("Address", wrapperNative.String()).Msg("Deployed Wrapped Native contract") + lmCommon.WrapperNative = wrapperNative + } + + // Deploy Bridge Adapter contracts + switch lmCommon.ChainSelectror { + case chainselectors.GETH_TESTNET.Selector: + lggr.Info().Msg("Deploying Mock L1 Bridge Adapter contract") + bridgeAdapter, err := cd.DeployMockL1BridgeAdapter(*lmCommon.WrapperNative, true) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy Mock L1 Bridge Adapter contract: %w", err)) + } + lggr.Info().Str("Address", bridgeAdapter.EthAddress.String()).Msg("Deployed Mock L1 Bridge Adapter contract") + lmCommon.BridgeAdapterAddr = bridgeAdapter.EthAddress + case chainselectors.GETH_DEVNET_2.Selector: + lggr.Info().Msg("Deploying Mock L2 Bridge Adapter contract") + bridgeAdapter, err := cd.DeployMockL2BridgeAdapter() + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy Mock L2 Bridge Adapter contract: %w", err)) + } + lggr.Info().Str("Address", bridgeAdapter.EthAddress.String()).Msg("Deployed Mock L2 Bridge Adapter contract") + lmCommon.BridgeAdapterAddr = bridgeAdapter.EthAddress + case chainselectors.ETHEREUM_TESTNET_SEPOLIA.Selector: + if l2ChainID == int64(chainselectors.ETHEREUM_TESTNET_SEPOLIA_ARBITRUM_1.EvmChainID) { + wethAddress := common.HexToAddress("0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9") + lmCommon.WrapperNative = &wethAddress + lggr.Info().Msg("Deploying Arbitrum L1 Bridge Adapter contract") + bridgeAdapter, err := cd.DeployArbitrumL1BridgeAdapter( + common.HexToAddress("0xcE18836b233C83325Cc8848CA4487e94C6288264"), + common.HexToAddress("0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F"), + ) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy Arbitrum L1 Bridge Adapter contract: %w", err)) + } + lggr.Info().Str("Address", bridgeAdapter.EthAddress.String()).Msg("Deployed Arbitrum L1 Bridge Adapter contract") + lmCommon.BridgeAdapterAddr = bridgeAdapter.EthAddress + } + if l2ChainID == int64(chainselectors.ETHEREUM_TESTNET_SEPOLIA_OPTIMISM_1.EvmChainID) { + wethAddress := common.HexToAddress("0x7b79995e5f793a07bc00c21412e50ecae098e7f9") + lmCommon.WrapperNative = &wethAddress + lggr.Info().Msg("Deploying Optimism L1 Bridge Adapter contract") + bridgeAdapter, err := cd.DeployOptimismL1BridgeAdapter( + common.HexToAddress("0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1"), + *lmCommon.WrapperNative, + common.HexToAddress("0x16Fc5058F25648194471939df75CF27A2fdC48BC"), + ) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy Optimism L1 Bridge Adapter contract: %w", err)) + } + lggr.Info().Str("Address", bridgeAdapter.EthAddress.String()).Msg("Deployed Optimism L1 Bridge Adapter contract") + lmCommon.BridgeAdapterAddr = bridgeAdapter.EthAddress + } + case chainselectors.ETHEREUM_TESTNET_SEPOLIA_ARBITRUM_1.Selector: + wethAddress := common.HexToAddress("0x980B62Da83eFf3D4576C647993b0c1D7faf17c73") + lmCommon.WrapperNative = &wethAddress + lggr.Info().Msg("Deploying Arbitrum L2 Bridge Adapter contract") + bridgeAdapter, err := cd.DeployArbitrumL2BridgeAdapter(common.HexToAddress("0x9fDD1C4E4AA24EEc1d913FABea925594a20d43C7")) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy Arbitrum L2 Bridge Adapter contract: %w", err)) + } + lggr.Info().Str("Address", bridgeAdapter.EthAddress.String()).Msg("Deployed Arbitrum L2 Bridge Adapter contract") + lmCommon.BridgeAdapterAddr = bridgeAdapter.EthAddress + case chainselectors.ETHEREUM_TESTNET_SEPOLIA_OPTIMISM_1.Selector: + wethAddress := common.HexToAddress("0x4200000000000000000000000000000000000006") + lmCommon.WrapperNative = &wethAddress + lggr.Info().Msg("Deploying Optimism L2 Bridge Adapter contract") + bridgeAdapter, err := cd.DeployOptimismL2BridgeAdapter(*lmCommon.WrapperNative) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy Optimism L2 Bridge Adapter contract: %w", err)) + } + lggr.Info().Str("Address", bridgeAdapter.EthAddress.String()).Msg("Deployed Optimism L2 Bridge Adapter contract") + lmCommon.BridgeAdapterAddr = bridgeAdapter.EthAddress + } + + // Deploy Mock ARM contract + lggr.Info().Msg("Deploying Mock ARM contract") + mockRMNContract, err := cd.DeployMockRMNContract() + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy Mock ARM contract: %w", err)) + } + lggr.Info().Str("Address", mockRMNContract.String()).Msg("Deployed Mock ARM contract") + lmCommon.MockArm = mockRMNContract + + // Deploy ARM Proxy contract + lggr.Info().Msg("Deploying ARM Proxy contract") + RMNProxyContract, err := cd.DeployArmProxy(*mockRMNContract) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy ARM Proxy contract: %w", err)) + } + lggr.Info().Str("Address", RMNProxyContract.EthAddress.String()).Msg("Deployed ARM Proxy contract") + lmCommon.ArmProxy = RMNProxyContract + + // Deploy CCIP Router contract + lggr.Info().Msg("Deploying CCIP Router contract") + ccipRouterContract, err := cd.DeployRouter(common.Address{}, *lmCommon.ArmProxy.EthAddress) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy CCIP Router contract: %w", err)) + } + lggr.Info().Str("Address", ccipRouterContract.EthAddress.String()).Msg("Deployed CCIP Router contract") + lmCommon.CcipRouter = ccipRouterContract + + // Deploy Lock Release Token contract + lggr.Info().Msg("Deploying Lock Release Token contract") + lockReleaseTokenPool, err := cd.DeployLockReleaseTokenPoolContract(lmCommon.WrapperNative.String(), *lmCommon.MockArm, lmCommon.CcipRouter.EthAddress) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy Lock Release Token contract: %w", err)) + } + lggr.Info().Str("Address", lockReleaseTokenPool.EthAddress.String()).Msg("Deployed Lock Release Token contract") + lmCommon.TokenPool = lockReleaseTokenPool + + // Deploy Liquidity Manager contract + lggr.Info().Msg("Deploying Liquidity Manager contract") + liquidityManager, err := cd.DeployLiquidityManager(*lmCommon.WrapperNative, lmCommon.ChainSelectror, lmCommon.TokenPool.EthAddress, lmCommon.MinimumLiquidity) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deploy Liquidity Manager contract: %w", err)) + } + lggr.Info().Str("Address", liquidityManager.EthAddress.String()).Msg("Deployed Liquidity Manager contract") + lmCommon.LM = liquidityManager + + // Set Liquidity Manager on Token Pool + lggr.Info().Msg("Setting Liquidity Manager on Token Pool") + err = lockReleaseTokenPool.SetRebalancer(*liquidityManager.EthAddress) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to set Liquidity Manager on Token Pool: %w", err)) + } + lggr.Info().Msg("Set Liquidity Manager on Token Pool") + + err = chain.WaitForEvents() + if err != nil { + return errors.WithStack(fmt.Errorf("failed to wait for events: %w", err)) + } + + // Verify on chain rebalancer from token pool matches deployed Liquidity Manager + onchainRebalancer, err := lockReleaseTokenPool.GetRebalancer() + if err != nil { + return errors.WithStack(fmt.Errorf("failed to get rebalancer from Token Pool: %w", err)) + } + if onchainRebalancer != *liquidityManager.EthAddress { + return errors.WithStack(fmt.Errorf("onchainRebalancer doesn not match the deployed Liquidity Manager")) + } + + lggr.Debug().Interface("lmCommon", lmCommon).Msg("lmCommon") + o.LMModules[chainClient.GetChainID().Int64()] = &lmCommon + + return nil +} + +func stripKeyPrefix(key string) string { + chunks := strings.Split(key, "_") + if len(chunks) == 3 { + return chunks[2] + } + return key +} + +func (o *LMTestSetupOutputs) SetOCR3Config(chainId int64) error { + clNodesWithKeys := o.Env.CLNodesWithKeys[strconv.FormatInt(chainId, 10)] + donNodes := clNodesWithKeys[1:] + oracleIdentities := make([]ocrconfighelper2.OracleIdentityExtra, 0) + var onChainKeys []ocrtypes2.OnchainPublicKey + var transmitters []common.Address + var schedule []int + + for i, nodeWithKeys := range donNodes { + ocr2Key := nodeWithKeys.KeysBundle.OCR2Key.Data + offChainPubKeyTemp, err := hex.DecodeString(stripKeyPrefix(ocr2Key.Attributes.OffChainPublicKey)) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to decode offchain public key: %w", err)) + } + formattedOnChainPubKey := stripKeyPrefix(ocr2Key.Attributes.OnChainPublicKey) + cfgPubKeyTemp, err := hex.DecodeString(stripKeyPrefix(ocr2Key.Attributes.ConfigPublicKey)) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to decode config public key: %w", err)) + } + cfgPubKeyBytes := [ed25519.PublicKeySize]byte{} + copy(cfgPubKeyBytes[:], cfgPubKeyTemp) + offChainPubKey := [curve25519.PointSize]byte{} + copy(offChainPubKey[:], offChainPubKeyTemp) + ethAddress := nodeWithKeys.KeysBundle.EthAddress + p2pKeys := nodeWithKeys.KeysBundle.P2PKeys + peerID := p2pKeys.Data[0].Attributes.PeerID + oracleIdentities = append(oracleIdentities, ocrconfighelper2.OracleIdentityExtra{ + OracleIdentity: ocrconfighelper2.OracleIdentity{ + OffchainPublicKey: offChainPubKey, + OnchainPublicKey: common.HexToAddress(formattedOnChainPubKey).Bytes(), + PeerID: peerID, + TransmitAccount: ocrtypes2.Account(ethAddress), + }, + ConfigEncryptionPublicKey: cfgPubKeyBytes, + }) + onChainKeys = append(onChainKeys, oracleIdentities[i].OnchainPublicKey) + transmitters = append(transmitters, common.HexToAddress(ethAddress)) + schedule = append(schedule, 1) + + } + signers, err := evm.OnchainPublicKeyToAddress(onChainKeys) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to convert onchain public keys to addresses: %w", err)) + } + + offchainConfig, onchainConfig := []byte{}, []byte{} + f := uint8(1) + _, _, f, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( + 2*time.Minute, + 2*time.Minute, + 20*time.Second, + 2*time.Second, + 20*time.Second, + 10*time.Second, + 40*time.Second, + 3, + schedule, + oracleIdentities, + offchainConfig, + 50*time.Millisecond, + 1*time.Minute, + 1*time.Minute, + 1*time.Second, + int(f), + onchainConfig, + ) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to set OCR3 config args for tests: %w", err)) + } + err = o.LMModules[chainId].LM.SetOCR3Config(signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to set OCR3 config: %w", err)) + } + return nil +} + +func (o *LMTestSetupOutputs) FundPool(chainId int64, lggr *zerolog.Logger, fundingAmount *big.Int) error { + token, err := erc20.NewERC20(*o.LMModules[chainId].WrapperNative, o.LMModules[chainId].ChainClient.Backend()) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create ERC20 contract instance: %w", err)) + } + balance, err := token.BalanceOf(nil, common.HexToAddress(o.LMModules[chainId].ChainClient.GetDefaultWallet().Address())) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to get token pool balance: %w", err)) + } + lggr.Debug().Str("balance", balance.String()).Msg("weth balance of transactor") + symbol, err := token.Symbol(nil) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to get token symbol: %w", err)) + } + if symbol == "WETH" { + weth, err := weth9.NewWETH9(*o.LMModules[chainId].WrapperNative, o.LMModules[chainId].ChainClient.Backend()) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create WETH contract instance: %w", err)) + } + nativeBalance, err := o.LMModules[chainId].ChainClient.BalanceAt(context.Background(), common.HexToAddress(o.LMModules[chainId].ChainClient.GetDefaultWallet().Address())) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to get native balance: %w", err)) + } + lggr.Debug().Str("nativeBalance", nativeBalance.String()).Msg("nativeBalance") + if nativeBalance.Cmp(fundingAmount) < 0 { + return errors.WithStack(fmt.Errorf("not enough native balance")) + } + lggr.Info().Msg("Depositing tokenpool funding to WETH contract") + txOpts, err := o.LMModules[chainId].ChainClient.TransactionOpts(o.LMModules[chainId].ChainClient.GetDefaultWallet()) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to get transaction options: %w", err)) + } + txOpts.Value = fundingAmount + tx, err := weth.Deposit(txOpts) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to deposit to WETH contract: %w", err)) + } + receipt, err := bind.WaitMined(context.Background(), o.LMModules[chainId].ChainClient.DeployBackend(), tx) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to wait for transaction receipt: %w", err)) + } + + lggr.Info().Str("tx hash", receipt.TxHash.String()).Msg("Deposited tokenpool funding to WETH contract") + } + lggr.Info().Msg("Funding token pool") + txOpts, err := o.LMModules[chainId].ChainClient.TransactionOpts(o.LMModules[chainId].ChainClient.GetDefaultWallet()) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to get transaction options: %w", err)) + + } + tx, err := token.Transfer(txOpts, o.LMModules[chainId].TokenPool.EthAddress, fundingAmount) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to transfer to token pool: %w", err)) + } + receipt, err := bind.WaitMined(context.Background(), o.LMModules[chainId].ChainClient.DeployBackend(), tx) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to wait for transaction receipt: %w", err)) + } + lggr.Info().Str("tx hash", receipt.TxHash.String()).Msg("Funded token pool") + + balance, err = token.BalanceOf(nil, o.LMModules[chainId].TokenPool.EthAddress) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to get token pool balance: %w", err)) + } + lggr.Debug().Str("balance", balance.String()).Msg("weth balance of token pool") + + return nil +} + +func (o *LMTestSetupOutputs) FundLM(chainId int64, lggr *zerolog.Logger, fundingAmount *big.Int) error { + transactor, err := o.LMModules[chainId].ChainClient.TransactionOpts(o.LMModules[chainId].ChainClient.GetDefaultWallet()) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to get transaction options: %w", err)) + } + cl := o.LMModules[chainId].ChainClient.Backend() + + nonce, err := cl.PendingNonceAt(context.Background(), transactor.From) + if err != nil { + return err + } + + gasPrice, err := cl.SuggestGasPrice(context.Background()) + if err != nil { + return err + } + + gasEstimate, err := cl.EstimateGas(context.Background(), ethereum.CallMsg{ + From: transactor.From, + To: o.LMModules[chainId].LM.EthAddress, + Value: fundingAmount, + }) + if err != nil { + return err + } + + tx := types.NewTx( + &types.LegacyTx{ + Nonce: nonce, + GasPrice: gasPrice, + Gas: gasEstimate, + To: o.LMModules[chainId].LM.EthAddress, + Value: fundingAmount, + }, + ) + signedTx, err := transactor.Signer(transactor.From, tx) + if err != nil { + return err + } + lggr.Info().Msg("Funding Liquidity Manager") + err = cl.SendTransaction(context.Background(), signedTx) + if err != nil { + return err + } + receipt, err := bind.WaitMined(context.Background(), o.LMModules[chainId].ChainClient.DeployBackend(), signedTx) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to wait for transaction receipt: %w", err)) + } + lggr.Info().Str("tx hash", receipt.TxHash.String()).Msg("Funded Liquidity Manager") + return nil +} + +func (o *LMTestSetupOutputs) AddJobs(chainId int64, lggr *zerolog.Logger) error { + // Add bootstrap job + clNodesWithKeys := o.Env.CLNodesWithKeys[strconv.FormatInt(chainId, 10)] + bootstrapNode := clNodesWithKeys[0] + bootstrapSpec, err := integrationtesthelpers.NewBootsrapJobSpec(&integrationtesthelpers.LMJobSpecParams{ + ChainID: uint64(chainId), + ContractID: o.LMModules[chainId].LM.EthAddress.String(), + CfgTrackerInterval: 15 * time.Second, + }) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create bootstrap job spec: %w", err)) + } + lggr.Info().Msg("Adding bootstrap job") + j, err := bootstrapNode.Node.MustCreateJob(bootstrapSpec) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create bootstrap job: %w", err)) + } + lggr.Info().Str("jobId", j.Data.ID).Msg("Bootstrap job added") + + P2Pv2Bootstrapper := fmt.Sprintf("%s@%s:%d", bootstrapNode.KeysBundle.P2PKeys.Data[0].Attributes.PeerID, bootstrapNode.Node.InternalIP(), 6690) + + // Add LM jobs + donNodes := clNodesWithKeys[1:] + + for _, node := range donNodes { + lmJobSpec, err := integrationtesthelpers.NewJobSpec(&integrationtesthelpers.LMJobSpecParams{ + ChainID: uint64(chainId), + ContractID: o.LMModules[chainId].LM.EthAddress.String(), + OCRKeyBundleID: node.KeysBundle.OCR2Key.Data.ID, + TransmitterID: node.KeysBundle.EthAddress, + P2PV2Bootstrappers: pq.StringArray{P2Pv2Bootstrapper}, + CfgTrackerInterval: 15 * time.Second, + LiquidityManagerAddress: *o.LMModules[chainId].LM.EthAddress, + NetworkSelector: o.LMModules[chainId].ChainSelectror, + Type: "ping-pong", + }) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create LM job spec: %w", err)) + } + lggr.Debug().Interface("lmJobSpec", lmJobSpec).Msg("lmJobSpec") + lggr.Info().Str("Node URL", node.Node.URL()).Msg("Adding LM job") + j, err := node.Node.MustCreateJob(lmJobSpec) + if err != nil { + return errors.WithStack(fmt.Errorf("failed to create LM job: %w", err)) + } + lggr.Info().Str("jobId", j.Data.ID).Msg("LM job added") + + } + return nil +} + +func LMDefaultTestSetup( + t *testing.T, + lggr *zerolog.Logger, + envName string, + testConfig *CCIPTestConfig, +) *LMTestSetupOutputs { + var ( + err error + ) + reportPath := "tmp_laneconfig" + parent, cancel := context.WithCancel(context.Background()) + defer cancel() + lmModules := make(map[int64]*actions.LMCommon) + setUpArgs := &LMTestSetupOutputs{ + CCIPTestSetUpOutputs{ + SetUpContext: parent, + Cfg: testConfig, + }, + lmModules, + } + + chainByChainID := setUpArgs.CreateLMEnvironment(lggr, envName, reportPath) + + chainAddGrp, _ := errgroup.WithContext(setUpArgs.SetUpContext) + lggr.Info().Msg("Deploying common contracts") + chainSelectors := make(map[int64]uint64) + + testConfig.SelectedNetworks, _, err = testConfig.EnvInput.EVMNetworks() + require.NoError(t, err) + + testConfig.AllNetworks = make(map[string]blockchain.EVMNetwork) + for _, net := range testConfig.SelectedNetworks { + testConfig.AllNetworks[net.Name] = net + if _, exists := chainSelectors[net.ChainID]; !exists { + chainSelectors[net.ChainID], err = chainselectors.SelectorFromChainId(uint64(net.ChainID)) + require.NoError(t, err) + } + } + + l1ChainId := testConfig.SelectedNetworks[0].ChainID + l2ChainId := testConfig.SelectedNetworks[1].ChainID + + for _, net := range testConfig.AllNetworks { + chain := chainByChainID[net.ChainID] + net := net + net.HTTPURLs = chain.GetNetworkConfig().HTTPURLs + net.URLs = chain.GetNetworkConfig().URLs + var selectors []uint64 + for chainId, selector := range chainSelectors { + if chainId == net.ChainID { + selectors = append(selectors, selector) + } + } + lmCommon, err := actions.DefaultLMModule( + chain, + big.NewInt(0), + selectors[0], + ) + require.NoError(t, err) + chainAddGrp.Go(func() error { + return setUpArgs.DeployLMChainContracts(lggr, net, *lmCommon, l2ChainId) + }) + } + require.NoError(t, chainAddGrp.Wait(), "Deploying common contracts shouldn't fail") + + lggr.Debug().Interface("lmModules", lmModules).Msg("lmModules") + + //Set Cross Chain Rebalancer on L1 Rebalancer + err = lmModules[l1ChainId].LM.SetCrossChainRebalancer( + liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs{ + RemoteRebalancer: *lmModules[l2ChainId].LM.EthAddress, + LocalBridge: *lmModules[l1ChainId].BridgeAdapterAddr, + RemoteToken: *lmModules[l2ChainId].WrapperNative, + RemoteChainSelector: lmModules[l2ChainId].ChainSelectror, + Enabled: true, + }) + require.NoError(t, err, "Setting Cross Chain Rebalancer on L1 Rebalancer shouldn't fail") + + //Set Cross Chain Rebalancer on L2 Rebalancer + err = lmModules[l2ChainId].LM.SetCrossChainRebalancer( + liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs{ + RemoteRebalancer: *lmModules[l1ChainId].LM.EthAddress, + LocalBridge: *lmModules[l2ChainId].BridgeAdapterAddr, + RemoteToken: *lmModules[l1ChainId].WrapperNative, + RemoteChainSelector: lmModules[l1ChainId].ChainSelectror, + Enabled: true, + }) + require.NoError(t, err, "Setting Cross Chain Rebalancer on L1 Rebalancer shouldn't fail") + + // Wait for setting cross chain balancers on both chains to confirm + err = lmModules[l1ChainId].ChainClient.WaitForEvents() + require.NoError(t, err, "Waiting for events to confirm on L1 chain shouldn't fail") + + err = lmModules[l2ChainId].ChainClient.WaitForEvents() + require.NoError(t, err, "Waiting for events to confirm on L2 chain shouldn't fail") + + // Verify that onchain rebalancer matches the deployed Liquidity Manager + onchainRebalancerL1, err := lmModules[l1ChainId].TokenPool.GetRebalancer() + require.NoError(t, err, "Getting rebalancer from Token Pool shouldn't fail") + + onchainRebalancerL2, err := lmModules[l2ChainId].TokenPool.GetRebalancer() + require.NoError(t, err, "Getting rebalancer from Token Pool shouldn't fail") + + if onchainRebalancerL1.String() != lmModules[l1ChainId].LM.EthAddress.String() || + onchainRebalancerL2.String() != lmModules[l2ChainId].LM.EthAddress.String() { + lggr.Debug(). + Str("onchainRebalancerL1", onchainRebalancerL1.String()). + Str("onchainRebalancerL2", onchainRebalancerL2.String()). + Str("L2 LM", lmModules[l2ChainId].LM.EthAddress.String()). + Str("L1 LM", lmModules[l1ChainId].LM.EthAddress.String()). + Msg("Onchain rebalancer mismatch") + t.Fatalf("Onchain rebalancer mismatch") + } + + // Fund L1 Token Pool + err = setUpArgs.FundPool(l1ChainId, lggr, big.NewInt(1000000000)) + require.NoError(t, err, "Funding L1 Token Pool shouldn't fail") + + //Fund L1 LM + err = setUpArgs.FundLM(l1ChainId, lggr, big.NewInt(1000000000)) + require.NoError(t, err, "Funding L1 LM shouldn't fail") + + err = lmModules[l1ChainId].ChainClient.WaitForEvents() + require.NoError(t, err, "Waiting for events to confirm on L1 chain shouldn't fail") + + // Fund L2 Token Pool + err = setUpArgs.FundPool(l2ChainId, lggr, big.NewInt(1000000000)) + require.NoError(t, err, "Funding L2 Token Pool shouldn't fail") + + //Fund L2 LM + err = setUpArgs.FundLM(l2ChainId, lggr, big.NewInt(1000000000)) + require.NoError(t, err, "Funding L2 LM shouldn't fail") + + err = lmModules[l2ChainId].ChainClient.WaitForEvents() + require.NoError(t, err, "Waiting for events to confirm on L2 chain shouldn't fail") + + liquidity, err := setUpArgs.LMModules[l1ChainId].LM.GetLiquidity() + require.NoError(t, err, "Getting liquidity from L1 LM shouldn't fail") + lggr.Debug().Interface("liquidity", liquidity).Msg("Liquidity") + require.Equal(t, big.NewInt(1000000000), liquidity, "Liquidity should match") + + liquidity, err = setUpArgs.LMModules[l2ChainId].LM.GetLiquidity() + require.NoError(t, err, "Getting liquidity from L1 LM shouldn't fail") + lggr.Debug().Interface("liquidity", liquidity).Msg("Liquidity") + require.Equal(t, big.NewInt(1000000000), liquidity, "Liquidity should match") + + err = setUpArgs.Env.CLNodeWithKeyReady.Wait() + require.NoError(t, err, "Waiting for CL nodes to be ready shouldn't fail") + + err = setUpArgs.AddJobs(l1ChainId, lggr) + require.NoError(t, err, "Adding jobs on L1 chain shouldn't fail") + + // Set Config on L2 Chain + err = setUpArgs.SetOCR3Config(l2ChainId) + require.NoError(t, err, "Setting OCR3 config on L2 chain shouldn't fail") + + // TODO: Remove this sleep when it is no longer needed + time.Sleep(30 * time.Second) + + // Set Config on L1 Chain + err = setUpArgs.SetOCR3Config(l1ChainId) + require.NoError(t, err, "Setting OCR3 config on L1 chain shouldn't fail") + + defer lmModules[l1ChainId].ChainClient.Close() + defer lmModules[l2ChainId].ChainClient.Close() + + return setUpArgs +} diff --git a/integration-tests/deployment/ccip/deploy.go b/integration-tests/deployment/ccip/deploy.go index ae3b00de65..3385551a22 100644 --- a/integration-tests/deployment/ccip/deploy.go +++ b/integration-tests/deployment/ccip/deploy.go @@ -2,25 +2,26 @@ package ccipdeployment import ( "encoding/hex" + "fmt" "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" - deployment2 "github.com/smartcontractkit/ccip/integration-tests/deployment" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink/integration-tests/deployment" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" @@ -29,42 +30,37 @@ import ( ) var ( - // 1.0 - ARMProxy_1_1_0 = "ARMProxy 1.0.0" - MockARM_1_0_0 = "MockARM 1.0.0" - LinkToken_1_0_0 = "LinkToken 1.0.0" - WETH9_1_0_0 = "WETH9 1.0.0" - MCMS_1_0_0 = "ManyChainMultiSig 1.0.0" - RBAC_Timelock_1_0_0 = "RBACTimelock 1.0.0" - CCIPReceiver_1_0_0 = "CCIPReceiver 1.0.0" - - // 1.2 - Router_1_2_0 = "Router 1.2.0" - // 1.5 - TokenAdminRegistry_1_5_0 = "TokenAdminRegistry 1.5.0-dev" - // 1.6 - CapabilitiesRegistry_1_0_0 = "CapabilitiesRegistry 1.0.0" - CCIPConfig_1_6_0 = "CCIPConfig 1.6.0-dev" - EVM2EVMMultiOnRamp_1_6_0 = "EVM2EVMMultiOnRamp 1.6.0-dev" - EVM2EVMMultiOffRamp_1_6_0 = "EVM2EVMMultiOffRamp 1.6.0-dev" - NonceManager_1_6_0 = "NonceManager 1.6.0-dev" - PriceRegistry_1_6_0 = "PriceRegistry 1.6.0-dev" + MockARM deployment.ContractType = "MockRMN" + LinkToken deployment.ContractType = "LinkToken" + ARMProxy deployment.ContractType = "ARMProxy" + WETH9 deployment.ContractType = "WETH9" + Router deployment.ContractType = "Router" + TokenAdminRegistry deployment.ContractType = "TokenAdminRegistry" + NonceManager deployment.ContractType = "NonceManager" + PriceRegistry deployment.ContractType = "PriceRegistry" + ManyChainMultisig deployment.ContractType = "ManyChainMultiSig" + CCIPConfig deployment.ContractType = "CCIPConfig" + RBACTimelock deployment.ContractType = "RBACTimelock" + OnRamp deployment.ContractType = "OnRamp" + OffRamp deployment.ContractType = "OffRamp" + CCIPReceiver deployment.ContractType = "CCIPReceiver" + CapabilitiesRegistry deployment.ContractType = "CapabilitiesRegistry" ) type Contracts interface { *capabilities_registry.CapabilitiesRegistry | - *arm_proxy_contract.ARMProxyContract | + *rmn_proxy_contract.RMNProxyContract | *ccip_config.CCIPConfig | *nonce_manager.NonceManager | *price_registry.PriceRegistry | *router.Router | *token_admin_registry.TokenAdminRegistry | *weth9.WETH9 | - *mock_arm_contract.MockARMContract | + *mock_rmn_contract.MockRMNContract | *owner_helpers.ManyChainMultiSig | *owner_helpers.RBACTimelock | - *evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp | - *evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp | + *offramp.OffRamp | + *onramp.OnRamp | *burn_mint_erc677.BurnMintERC677 | *maybe_revert_message_receiver.MaybeRevertMessageReceiver } @@ -75,11 +71,12 @@ type ContractDeploy[C Contracts] struct { Address common.Address Contract C Tx *types.Transaction - TvStr string + Tv deployment.TypeAndVersion Err error } -// TODO: pull up to general deployment pkg +// TODO: pull up to general deployment pkg somehow +// without exposing all product specific contracts? func deployContract[C Contracts]( lggr logger.Logger, chain deployment.Chain, @@ -96,7 +93,7 @@ func deployContract[C Contracts]( lggr.Errorw("Failed to confirm deployment", "err", err) return nil, err } - err = addressBook.Save(chain.Selector, contractDeploy.Address.String(), contractDeploy.TvStr) + err = addressBook.Save(chain.Selector, contractDeploy.Address.String(), contractDeploy.Tv) if err != nil { lggr.Errorw("Failed to save contract address", "err", err) return nil, err @@ -118,11 +115,14 @@ type DeployCCIPContractConfig struct { // Deployment produces an address book of everything it deployed. func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) (deployment.AddressBook, error) { ab := deployment.NewMemoryAddressBook() - nodes, err := deployment2.NodeInfo(e.NodeIDs, e.Offchain) - if err != nil { + nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) + if err != nil || len(nodes) == 0 { e.Logger.Errorw("Failed to get node info", "err", err) return ab, err } + if _, ok := c.CapabilityRegistry[c.HomeChainSel]; !ok { + return ab, fmt.Errorf("Capability registry not found for home chain %d, needs to be deployed first", c.HomeChainSel) + } cr, err := c.CapabilityRegistry[c.HomeChainSel].GetHashedCapabilityId( &bind.CallOpts{}, CapabilityLabelledName, CapabilityVersion) if err != nil { @@ -148,7 +148,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( false, ) return ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver]{ - receiverAddr, receiver, tx, CCIPReceiver_1_0_0, err2, + receiverAddr, receiver, tx, deployment.NewTypeAndVersion(CCIPReceiver, deployment.Version1_0_0), err2, } }) if err != nil { @@ -159,13 +159,13 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( // TODO: Still waiting for RMNRemote/RMNHome contracts etc. mockARM, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*mock_arm_contract.MockARMContract] { - mockARMAddr, tx, mockARM, err2 := mock_arm_contract.DeployMockARMContract( + func(chain deployment.Chain) ContractDeploy[*mock_rmn_contract.MockRMNContract] { + mockARMAddr, tx, mockARM, err2 := mock_rmn_contract.DeployMockRMNContract( chain.DeployerKey, chain.Client, ) - return ContractDeploy[*mock_arm_contract.MockARMContract]{ - mockARMAddr, mockARM, tx, MockARM_1_0_0, err2, + return ContractDeploy[*mock_rmn_contract.MockRMNContract]{ + mockARMAddr, mockARM, tx, deployment.NewTypeAndVersion(MockARM, deployment.Version1_0_0), err2, } }) if err != nil { @@ -181,7 +181,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( chain.Client, ) return ContractDeploy[*owner_helpers.ManyChainMultiSig]{ - mcmAddr, mcm, tx, MCMS_1_0_0, err2, + mcmAddr, mcm, tx, deployment.NewTypeAndVersion(ManyChainMultisig, deployment.Version1_0_0), err2, } }) if err != nil { @@ -204,7 +204,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( []common.Address{mcm.Address}, // bypassers ) return ContractDeploy[*owner_helpers.RBACTimelock]{ - timelock, cc, tx, RBAC_Timelock_1_0_0, err2, + timelock, cc, tx, deployment.NewTypeAndVersion(RBACTimelock, deployment.Version1_0_0), err2, } }) if err != nil { @@ -214,14 +214,14 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( e.Logger.Infow("deployed timelock", "addr", mcm.Address) armProxy, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*arm_proxy_contract.ARMProxyContract] { - armProxyAddr, tx, armProxy, err2 := arm_proxy_contract.DeployARMProxyContract( + func(chain deployment.Chain) ContractDeploy[*rmn_proxy_contract.RMNProxyContract] { + armProxyAddr, tx, armProxy, err2 := rmn_proxy_contract.DeployRMNProxyContract( chain.DeployerKey, chain.Client, mockARM.Address, ) - return ContractDeploy[*arm_proxy_contract.ARMProxyContract]{ - armProxyAddr, armProxy, tx, ARMProxy_1_1_0, err2, + return ContractDeploy[*rmn_proxy_contract.RMNProxyContract]{ + armProxyAddr, armProxy, tx, deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0), err2, } }) if err != nil { @@ -237,7 +237,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( chain.Client, ) return ContractDeploy[*weth9.WETH9]{ - weth9Addr, weth9c, tx, WETH9_1_0_0, err2, + weth9Addr, weth9c, tx, deployment.NewTypeAndVersion(WETH9, deployment.Version1_0_0), err2, } }) if err != nil { @@ -256,7 +256,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( big.NewInt(0).Mul(big.NewInt(1e9), big.NewInt(1e18)), ) return ContractDeploy[*burn_mint_erc677.BurnMintERC677]{ - linkTokenAddr, linkToken, tx, LinkToken_1_0_0, err2, + linkTokenAddr, linkToken, tx, deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0), err2, } }) if err != nil { @@ -273,7 +273,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( armProxy.Address, ) return ContractDeploy[*router.Router]{ - routerAddr, routerC, tx, Router_1_2_0, err2, + routerAddr, routerC, tx, deployment.NewTypeAndVersion(Router, deployment.Version1_2_0), err2, } }) if err != nil { @@ -288,7 +288,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( chain.DeployerKey, chain.Client) return ContractDeploy[*token_admin_registry.TokenAdminRegistry]{ - tokenAdminRegistryAddr, tokenAdminRegistry, tx, TokenAdminRegistry_1_5_0, err2, + tokenAdminRegistryAddr, tokenAdminRegistry, tx, deployment.NewTypeAndVersion(TokenAdminRegistry, deployment.Version1_5_0), err2, } }) if err != nil { @@ -305,7 +305,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( []common.Address{}, // Need to add onRamp after ) return ContractDeploy[*nonce_manager.NonceManager]{ - nonceManagerAddr, nonceManager, tx, NonceManager_1_6_0, err2, + nonceManagerAddr, nonceManager, tx, deployment.NewTypeAndVersion(NonceManager, deployment.Version1_6_0_dev), err2, } }) if err != nil { @@ -340,7 +340,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( []price_registry.PriceRegistryDestChainConfigArgs{}, ) return ContractDeploy[*price_registry.PriceRegistry]{ - prAddr, pr, tx, PriceRegistry_1_6_0, err2, + prAddr, pr, tx, deployment.NewTypeAndVersion(PriceRegistry, deployment.Version1_6_0_dev), err2, } }) if err != nil { @@ -349,24 +349,24 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( } onRamp, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp] { - onRampAddr, tx, onRamp, err2 := evm_2_evm_multi_onramp.DeployEVM2EVMMultiOnRamp( + func(chain deployment.Chain) ContractDeploy[*onramp.OnRamp] { + onRampAddr, tx, onRamp, err2 := onramp.DeployOnRamp( chain.DeployerKey, chain.Client, - evm_2_evm_multi_onramp.EVM2EVMMultiOnRampStaticConfig{ + onramp.OnRampStaticConfig{ ChainSelector: sel, RmnProxy: armProxy.Address, NonceManager: nonceManager.Address, TokenAdminRegistry: tokenAdminRegistry.Address, }, - evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDynamicConfig{ + onramp.OnRampDynamicConfig{ PriceRegistry: priceRegistry.Address, FeeAggregator: common.HexToAddress("0x1"), // TODO real fee aggregator }, - []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs{}, + []onramp.OnRampDestChainConfigArgs{}, ) - return ContractDeploy[*evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp]{ - onRampAddr, onRamp, tx, EVM2EVMMultiOnRamp_1_6_0, err2, + return ContractDeploy[*onramp.OnRamp]{ + onRampAddr, onRamp, tx, deployment.NewTypeAndVersion(OnRamp, deployment.Version1_6_0_dev), err2, } }) if err != nil { @@ -376,26 +376,26 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( e.Logger.Infow("deployed onramp", "addr", onRamp.Address) offRamp, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp] { - offRampAddr, tx, offRamp, err2 := evm_2_evm_multi_offramp.DeployEVM2EVMMultiOffRamp( + func(chain deployment.Chain) ContractDeploy[*offramp.OffRamp] { + offRampAddr, tx, offRamp, err2 := offramp.DeployOffRamp( chain.DeployerKey, chain.Client, - evm_2_evm_multi_offramp.EVM2EVMMultiOffRampStaticConfig{ + offramp.OffRampStaticConfig{ ChainSelector: sel, RmnProxy: armProxy.Address, NonceManager: nonceManager.Address, TokenAdminRegistry: tokenAdminRegistry.Address, }, - evm_2_evm_multi_offramp.EVM2EVMMultiOffRampDynamicConfig{ + offramp.OffRampDynamicConfig{ PriceRegistry: priceRegistry.Address, PermissionLessExecutionThresholdSeconds: uint32(86400), MaxTokenTransferGas: uint32(200_000), MaxPoolReleaseOrMintGas: uint32(200_000), }, - []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{}, + []offramp.OffRampSourceChainConfigArgs{}, ) - return ContractDeploy[*evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp]{ - offRampAddr, offRamp, tx, EVM2EVMMultiOffRamp_1_6_0, err2, + return ContractDeploy[*offramp.OffRamp]{ + offRampAddr, offRamp, tx, deployment.NewTypeAndVersion(OffRamp, deployment.Version1_6_0_dev), err2, } }) if err != nil { @@ -466,7 +466,7 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) return err } tx, err = state.EvmOnRampsV160[from].ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, - []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs{ + []onramp.OnRampDestChainConfigArgs{ { DestChainSelector: to, Router: state.Routers[from].Address(), @@ -481,11 +481,11 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) TokenPriceUpdates: []price_registry.InternalTokenPriceUpdate{ { SourceToken: state.LinkTokens[from].Address(), - UsdPerToken: deployment2.E18Mult(20), + UsdPerToken: deployment.E18Mult(20), }, { SourceToken: state.Weth9s[from].Address(), - UsdPerToken: deployment2.E18Mult(4000), + UsdPerToken: deployment.E18Mult(4000), }, }, GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ @@ -511,7 +511,7 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) } tx, err = state.EvmOffRampsV160[to].ApplySourceChainConfigUpdates(e.Chains[to].DeployerKey, - []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{ + []offramp.OffRampSourceChainConfigArgs{ { Router: state.Routers[to].Address(), SourceChainSelector: from, diff --git a/integration-tests/deployment/ccip/deploy_home_chain.go b/integration-tests/deployment/ccip/deploy_home_chain.go index a79fee6678..315ebfb413 100644 --- a/integration-tests/deployment/ccip/deploy_home_chain.go +++ b/integration-tests/deployment/ccip/deploy_home_chain.go @@ -23,8 +23,8 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/deployment" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ocr3_config_encoder" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) @@ -198,7 +198,7 @@ func AddDON( ccipCapabilityID [32]byte, capReg *capabilities_registry.CapabilitiesRegistry, ccipConfig *ccip_config.CCIPConfig, - offRamp *evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp, + offRamp *offramp.OffRamp, dest deployment.Chain, home deployment.Chain, f uint8, @@ -357,7 +357,7 @@ func AddDON( } // get the config digest from the ccip config contract and set config on the offramp. - var offrampOCR3Configs []evm_2_evm_multi_offramp.MultiOCR3BaseOCRConfigArgs + var offrampOCR3Configs []offramp.MultiOCR3BaseOCRConfigArgs for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { ocrConfig, err2 := ccipConfig.GetOCRConfig(&bind.CallOpts{ Context: context.Background(), @@ -369,7 +369,7 @@ func AddDON( return errors.New("expected exactly one OCR3 config") } - offrampOCR3Configs = append(offrampOCR3Configs, evm_2_evm_multi_offramp.MultiOCR3BaseOCRConfigArgs{ + offrampOCR3Configs = append(offrampOCR3Configs, offramp.MultiOCR3BaseOCRConfigArgs{ ConfigDigest: ocrConfig[0].ConfigDigest, OcrPluginType: uint8(pluginType), F: f, diff --git a/integration-tests/deployment/ccip/migrations/1_initial_deploy_test.go b/integration-tests/deployment/ccip/migrations/1_initial_deploy_test.go index aa8f244481..d75f5cbc2b 100644 --- a/integration-tests/deployment/ccip/migrations/1_initial_deploy_test.go +++ b/integration-tests/deployment/ccip/migrations/1_initial_deploy_test.go @@ -19,7 +19,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" @@ -224,10 +224,10 @@ func waitForCommitWithInterval( t *testing.T, src deployment.Chain, dest deployment.Chain, - offRamp *evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp, + offRamp *offramp.OffRamp, expectedSeqNumRange ccipocr3.SeqNumRange, ) { - sink := make(chan *evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReportAccepted) + sink := make(chan *offramp.OffRampCommitReportAccepted) subscription, err := offRamp.WatchCommitReportAccepted(&bind.WatchOpts{ Context: context.Background(), }, sink) @@ -265,7 +265,7 @@ func waitForCommitWithInterval( func waitForExecWithSeqNr(t *testing.T, source, dest deployment.Chain, - offramp *evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp, + offramp *offramp.OffRamp, expectedSeqNr uint64) { tick := time.NewTicker(5 * time.Second) defer tick.Stop() diff --git a/integration-tests/deployment/ccip/state.go b/integration-tests/deployment/ccip/state.go index 219e7d442e..1e9c904726 100644 --- a/integration-tests/deployment/ccip/state.go +++ b/integration-tests/deployment/ccip/state.go @@ -15,12 +15,12 @@ import ( owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" @@ -33,15 +33,15 @@ type CCIPOnChainState struct { // Populated go bindings for the appropriate version for all contracts. // We would hold 2 versions of each contract here. Once we upgrade we can phase out the old one. // When generating bindings, make sure the package name corresponds to the version. - EvmOnRampsV160 map[uint64]*evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp - EvmOffRampsV160 map[uint64]*evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp + EvmOnRampsV160 map[uint64]*onramp.OnRamp + EvmOffRampsV160 map[uint64]*offramp.OffRamp PriceRegistries map[uint64]*price_registry.PriceRegistry - ArmProxies map[uint64]*arm_proxy_contract.ARMProxyContract + ArmProxies map[uint64]*rmn_proxy_contract.RMNProxyContract NonceManagers map[uint64]*nonce_manager.NonceManager TokenAdminRegistries map[uint64]*token_admin_registry.TokenAdminRegistry Routers map[uint64]*router.Router Weth9s map[uint64]*weth9.WETH9 - MockArms map[uint64]*mock_arm_contract.MockARMContract + MockArms map[uint64]*mock_rmn_contract.MockRMNContract // TODO: May need to support older link too LinkTokens map[uint64]*burn_mint_erc677.BurnMintERC677 // Note we only expect one of these (on the home chain) @@ -65,20 +65,20 @@ type Contract struct { Address common.Address `json:"address"` } -type TokenAdminRegistry struct { +type TokenAdminRegistryView struct { Contract Tokens []common.Address `json:"tokens"` } -type NonceManager struct { +type NonceManagerView struct { Contract AuthorizedCallers []common.Address `json:"authorizedCallers"` } type Chain struct { // TODO: this will have to be versioned for getting state during upgrades. - TokenAdminRegistry TokenAdminRegistry `json:"tokenAdminRegistry"` - NonceManager NonceManager `json:"nonceManager"` + TokenAdminRegistry TokenAdminRegistryView `json:"tokenAdminRegistry"` + NonceManager NonceManagerView `json:"nonceManager"` } func (s CCIPOnChainState) Snapshot(chains []uint64) (CCIPSnapShot, error) { @@ -105,7 +105,7 @@ func (s CCIPOnChainState) Snapshot(chains []uint64) (CCIPSnapShot, error) { if err != nil { return snapshot, err } - c.TokenAdminRegistry = TokenAdminRegistry{ + c.TokenAdminRegistry = TokenAdminRegistryView{ Contract: Contract{ TypeAndVersion: tv, Address: ta.Address(), @@ -122,7 +122,7 @@ func (s CCIPOnChainState) Snapshot(chains []uint64) (CCIPSnapShot, error) { if err != nil { return snapshot, err } - c.NonceManager = NonceManager{ + c.NonceManager = NonceManagerView{ Contract: Contract{ TypeAndVersion: tv, Address: nm.Address(), @@ -146,14 +146,14 @@ func SnapshotState(e deployment.Environment, ab deployment.AddressBook) (CCIPSna func GenerateOnchainState(e deployment.Environment, ab deployment.AddressBook) (CCIPOnChainState, error) { state := CCIPOnChainState{ - EvmOnRampsV160: make(map[uint64]*evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp), - EvmOffRampsV160: make(map[uint64]*evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp), + EvmOnRampsV160: make(map[uint64]*onramp.OnRamp), + EvmOffRampsV160: make(map[uint64]*offramp.OffRamp), PriceRegistries: make(map[uint64]*price_registry.PriceRegistry), - ArmProxies: make(map[uint64]*arm_proxy_contract.ARMProxyContract), + ArmProxies: make(map[uint64]*rmn_proxy_contract.RMNProxyContract), NonceManagers: make(map[uint64]*nonce_manager.NonceManager), TokenAdminRegistries: make(map[uint64]*token_admin_registry.TokenAdminRegistry), Routers: make(map[uint64]*router.Router), - MockArms: make(map[uint64]*mock_arm_contract.MockARMContract), + MockArms: make(map[uint64]*mock_rmn_contract.MockRMNContract), LinkTokens: make(map[uint64]*burn_mint_erc677.BurnMintERC677), Weth9s: make(map[uint64]*weth9.WETH9), Mcms: make(map[uint64]*owner_wrappers.ManyChainMultiSig), @@ -170,93 +170,93 @@ func GenerateOnchainState(e deployment.Environment, ab deployment.AddressBook) ( } for chainSelector, addresses := range addresses { for address, tvStr := range addresses { - switch tvStr { - case RBAC_Timelock_1_0_0: + switch tvStr.String() { + case deployment.NewTypeAndVersion(RBACTimelock, deployment.Version1_0_0).String(): tl, err := owner_wrappers.NewRBACTimelock(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.Timelocks[chainSelector] = tl - case MCMS_1_0_0: + case deployment.NewTypeAndVersion(ManyChainMultisig, deployment.Version1_0_0).String(): mcms, err := owner_wrappers.NewManyChainMultiSig(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.Mcms[chainSelector] = mcms state.McmsAddrs[chainSelector] = common.HexToAddress(address) - case CapabilitiesRegistry_1_0_0: + case deployment.NewTypeAndVersion(CapabilitiesRegistry, deployment.Version1_0_0).String(): cr, err := capabilities_registry.NewCapabilitiesRegistry(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.CapabilityRegistry[chainSelector] = cr - case EVM2EVMMultiOnRamp_1_6_0: - onRamp, err := evm_2_evm_multi_onramp.NewEVM2EVMMultiOnRamp(common.HexToAddress(address), e.Chains[chainSelector].Client) + case deployment.NewTypeAndVersion(OnRamp, deployment.Version1_6_0_dev).String(): + onRamp, err := onramp.NewOnRamp(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.EvmOnRampsV160[chainSelector] = onRamp - case EVM2EVMMultiOffRamp_1_6_0: - offRamp, err := evm_2_evm_multi_offramp.NewEVM2EVMMultiOffRamp(common.HexToAddress(address), e.Chains[chainSelector].Client) + case deployment.NewTypeAndVersion(OffRamp, deployment.Version1_6_0_dev).String(): + offRamp, err := offramp.NewOffRamp(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.EvmOffRampsV160[chainSelector] = offRamp - case ARMProxy_1_1_0: - armProxy, err := arm_proxy_contract.NewARMProxyContract(common.HexToAddress(address), e.Chains[chainSelector].Client) + case deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0).String(): + armProxy, err := rmn_proxy_contract.NewRMNProxyContract(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.ArmProxies[chainSelector] = armProxy - case MockARM_1_0_0: - mockARM, err := mock_arm_contract.NewMockARMContract(common.HexToAddress(address), e.Chains[chainSelector].Client) + case deployment.NewTypeAndVersion(MockARM, deployment.Version1_0_0).String(): + mockARM, err := mock_rmn_contract.NewMockRMNContract(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.MockArms[chainSelector] = mockARM - case WETH9_1_0_0: + case deployment.NewTypeAndVersion(WETH9, deployment.Version1_0_0).String(): weth9, err := weth9.NewWETH9(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.Weth9s[chainSelector] = weth9 - case NonceManager_1_6_0: + case deployment.NewTypeAndVersion(NonceManager, deployment.Version1_6_0_dev).String(): nm, err := nonce_manager.NewNonceManager(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.NonceManagers[chainSelector] = nm - case TokenAdminRegistry_1_5_0: + case deployment.NewTypeAndVersion(TokenAdminRegistry, deployment.Version1_5_0).String(): tm, err := token_admin_registry.NewTokenAdminRegistry(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.TokenAdminRegistries[chainSelector] = tm - case Router_1_2_0: + case deployment.NewTypeAndVersion(Router, deployment.Version1_2_0).String(): r, err := router.NewRouter(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.Routers[chainSelector] = r - case PriceRegistry_1_6_0: + case deployment.NewTypeAndVersion(PriceRegistry, deployment.Version1_6_0_dev).String(): pr, err := price_registry.NewPriceRegistry(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.PriceRegistries[chainSelector] = pr - case LinkToken_1_0_0: + case deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0).String(): lt, err := burn_mint_erc677.NewBurnMintERC677(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.LinkTokens[chainSelector] = lt - case CCIPConfig_1_6_0: + case deployment.NewTypeAndVersion(CCIPConfig, deployment.Version1_6_0_dev).String(): cc, err := ccip_config.NewCCIPConfig(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err } state.CCIPConfig[chainSelector] = cc - case CCIPReceiver_1_0_0: + case deployment.NewTypeAndVersion(CCIPReceiver, deployment.Version1_0_0).String(): mr, err := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(common.HexToAddress(address), e.Chains[chainSelector].Client) if err != nil { return state, err From 49346e452b07a53ae4d5365fee55fd32b41f9b85 Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Wed, 21 Aug 2024 06:47:52 -0700 Subject: [PATCH 219/432] Add deployment tests in ci (#1337) Use new ccip tests designed with deployment in CI --------- Co-authored-by: Makram --- .github/workflows/ci-core.yml | 11 ++- .../ccipreader/ccipreader_test.go | 4 + .../deployment/ccip/test_helpers.go | 75 +++++++++++++++++++ tools/bin/go_core_ccip_deployment_tests | 43 +++++++++++ 4 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 integration-tests/deployment/ccip/test_helpers.go create mode 100755 tools/bin/go_core_ccip_deployment_tests diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index ba89ab4045..7a4f70ef3c 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -89,6 +89,11 @@ jobs: - cmd: go_core_tests id: core_unit os: ubuntu22.04-32cores-128GB + printResults: true + - cmd: go_core_ccip_deployment_tests + id: core_unit + os: ubuntu22.04-32cores-128GB + printResults: true - cmd: go_core_race_tests id: core_race # use 64cores for overnight runs only due to massive number of runs from PRs @@ -177,9 +182,11 @@ jobs: CL_DATABASE_URL: ${{ env.DB_URL }} run: ./tools/bin/${{ matrix.type.cmd }} ./... - name: Print Filtered Test Results - if: ${{ failure() && matrix.type.cmd == 'go_core_tests' && needs.filter.outputs.changes == 'true' && steps.run-tests.conclusion == 'failure' }} + if: ${{ failure() && needs.filter.outputs.changes == 'true' && steps.run-tests.conclusion == 'failure' }} run: | - cat output.txt | gotestloghelper -ci + if [[ "${{ matrix.type.printResults }}" == "true" ]]; then + cat output.txt | gotestloghelper -ci + fi - name: Print Races id: print-races if: ${{ failure() && matrix.type.cmd == 'go_core_race_tests' && needs.filter.outputs.changes == 'true' }} diff --git a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go index 03c1416b4b..a179949d93 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go @@ -100,6 +100,10 @@ func TestCCIPReader_CommitReportsGTETimestamp(t *testing.T) { s.sb.Commit() } + // Need to replay as sometimes the logs are not picked up by the log poller (?) + // Maybe another situation where chain reader doesn't register filters as expected. + require.NoError(t, s.lp.Replay(ctx, 1)) + var reports []plugintypes.CommitPluginReportWithMeta var err error require.Eventually(t, func() bool { diff --git a/integration-tests/deployment/ccip/test_helpers.go b/integration-tests/deployment/ccip/test_helpers.go new file mode 100644 index 0000000000..2ec837c9ee --- /dev/null +++ b/integration-tests/deployment/ccip/test_helpers.go @@ -0,0 +1,75 @@ +package ccipdeployment + +import ( + "context" + "testing" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" +) + +// Context returns a context with the test's deadline, if available. +func Context(tb testing.TB) context.Context { + ctx := context.Background() + var cancel func() + switch t := tb.(type) { + case *testing.T: + if d, ok := t.Deadline(); ok { + ctx, cancel = context.WithDeadline(ctx, d) + } + } + if cancel == nil { + ctx, cancel = context.WithCancel(ctx) + } + tb.Cleanup(cancel) + return ctx +} + +type DeployedTestEnvironment struct { + Ab deployment.AddressBook + Env deployment.Environment + HomeChainSel uint64 + Nodes map[string]memory.Node +} + +// NewDeployedEnvironment creates a new CCIP environment +// with capreg and nodes set up. +func NewDeployedTestEnvironment(t *testing.T, lggr logger.Logger) DeployedTestEnvironment { + ctx := Context(t) + chains := memory.NewMemoryChains(t, 3) + homeChainSel := uint64(0) + homeChainEVM := uint64(0) + // Say first chain is home chain. + for chainSel := range chains { + homeChainEVM, _ = chainsel.ChainIdFromSelector(chainSel) + homeChainSel = chainSel + break + } + ab, capReg, err := DeployCapReg(lggr, chains, homeChainSel) + require.NoError(t, err) + + nodes := memory.NewNodes(t, zapcore.InfoLevel, chains, 4, 1, memory.RegistryConfig{ + EVMChainID: homeChainEVM, + Contract: capReg, + }) + for _, node := range nodes { + require.NoError(t, node.App.Start(ctx)) + t.Cleanup(func() { + require.NoError(t, node.App.Stop()) + }) + } + + e := memory.NewMemoryEnvironmentFromChainsNodes(t, lggr, chains, nodes) + return DeployedTestEnvironment{ + Ab: ab, + Env: e, + HomeChainSel: homeChainSel, + Nodes: nodes, + } +} diff --git a/tools/bin/go_core_ccip_deployment_tests b/tools/bin/go_core_ccip_deployment_tests new file mode 100755 index 0000000000..54f9b70d26 --- /dev/null +++ b/tools/bin/go_core_ccip_deployment_tests @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +set -o pipefail +set +e + +SCRIPT_PATH=`dirname "$0"`; SCRIPT_PATH=`eval "cd \"$SCRIPT_PATH\" && pwd"` +OUTPUT_FILE="../output.txt" +USE_TEE="${USE_TEE:-true}" + +# To allow reuse in CI from other repositories +TOOLS_PATH=${TOOLS_PATH:-"./tools"} + +echo "Failed tests and panics: ---------------------" +echo "" +use_tee() { + if [ "$USE_TEE" = "true" ]; then + tee "$@" + else + cat > "$@" + fi +} + +cd ./integration-tests || exit +go mod download +go test -json ./deployment/... -covermode=atomic -coverpkg=./... -coverprofile=coverage.txt | use_tee $OUTPUT_FILE +EXITCODE=${PIPESTATUS[0]} + +# Assert no known sensitive strings present in test logger output +printf "\n----------------------------------------------\n\n" +echo "Beginning check of output logs for sensitive strings" +$SCRIPT_PATH/scrub_logs $OUTPUT_FILE +cd .. +if [[ $? != 0 ]]; then + exit 1 +fi + +echo "Exit code: $EXITCODE" +if [[ $EXITCODE != 0 ]]; then + echo "Encountered test failures." +else + echo "All tests passed!" +fi +echo "go_core_ccip_deployment_tests exiting with code $EXITCODE" +exit $EXITCODE From 1bc98ba49774a9602905e6788b0589fece03e5b4 Mon Sep 17 00:00:00 2001 From: "Abdelrahman Soliman (Boda)" <2677789+asoliman92@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:49:35 +0400 Subject: [PATCH 220/432] Remove old integration tests for v1.6 (#1346) To fully rely on integration-tests/deployment/ccip --- .../ccip_integration_tests/ocr3_node_test.go | 281 ------------------ 1 file changed, 281 deletions(-) delete mode 100644 core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go diff --git a/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go b/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go deleted file mode 100644 index 5914db8082..0000000000 --- a/core/capabilities/ccip/ccip_integration_tests/ocr3_node_test.go +++ /dev/null @@ -1,281 +0,0 @@ -package ccip_integration_tests - -import ( - "fmt" - "math/big" - "sync" - "testing" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/hashicorp/consul/sdk/freeport" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" - - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - - "github.com/stretchr/testify/require" -) - -const STATE_SUCCESS = uint8(2) - -/* -* If you want to debug, set log level to info and use the following commands for easier logs filtering. -* -* // Run the test and redirect logs to logs.txt -* go test -v -run "^TestIntegration_OCR3Nodes" ./core/capabilities/ccip/ccip_integration_tests 2>&1 > logs.txt -* -* // Reads logs.txt as a stream and apply filters using grep -* tail -fn0 logs.txt | grep "CCIPExecPlugin" - */ -func TestIntegration_OCR3Nodes(t *testing.T) { - const ( - numChains = 3 // number of chains that this test will run on - numNodes = 4 // number of OCR3 nodes, test assumes that every node supports every chain - - simulatedBackendBlockTime = 900 * time.Millisecond // Simulated backend blocks committing interval - oraclesBootWaitTime = 30 * time.Second // Time to wait for oracles to come up (HACK) - fChain = 1 // fChain value for all the chains - oracleLogLevel = zapcore.InfoLevel // Log level for the oracle / plugins. - ) - - t.Logf("creating %d universes", numChains) - homeChainUni, universes := createUniverses(t, numChains) - - var ( - oracles = make(map[uint64][]confighelper2.OracleIdentityExtra) - apps []chainlink.Application - nodes []*ocr3Node - p2pIDs [][32]byte - - // The bootstrap node will be: nodes[0] - bootstrapPort int - bootstrapP2PID p2pkey.PeerID - ) - - ports := freeport.GetN(t, numNodes) - ctx := testutils.Context(t) - callCtx := &bind.CallOpts{Context: ctx} - - for i := 0; i < numNodes; i++ { - t.Logf("Setting up ocr3 node:%d at port:%d", i, ports[i]) - node := setupNodeOCR3(t, ports[i], universes, homeChainUni, oracleLogLevel) - - for chainID, transmitter := range node.transmitters { - identity := confighelper2.OracleIdentityExtra{ - OracleIdentity: confighelper2.OracleIdentity{ - OnchainPublicKey: node.keybundle.PublicKey(), // Different for each chain - TransmitAccount: ocrtypes.Account(transmitter.Hex()), - OffchainPublicKey: node.keybundle.OffchainPublicKey(), // Same for each family - PeerID: node.peerID, - }, - ConfigEncryptionPublicKey: node.keybundle.ConfigEncryptionPublicKey(), // Different for each chain - } - oracles[chainID] = append(oracles[chainID], identity) - } - - apps = append(apps, node.app) - nodes = append(nodes, node) - - peerID, err := p2pkey.MakePeerID(node.peerID) - require.NoError(t, err) - p2pIDs = append(p2pIDs, peerID) - } - - bootstrapPort = ports[0] - bootstrapP2PID = p2pIDs[0] - bootstrapAddr := fmt.Sprintf("127.0.0.1:%d", bootstrapPort) - t.Logf("[bootstrap node] peerID:%s p2pID:%d address:%s", nodes[0].peerID, bootstrapP2PID, bootstrapAddr) - - // Start committing periodically in the background for all the chains - tick := time.NewTicker(simulatedBackendBlockTime) - defer tick.Stop() - commitBlocksBackground(t, universes, tick) - - ccipCapabilityID, err := homeChainUni.capabilityRegistry.GetHashedCapabilityId( - callCtx, CapabilityLabelledName, CapabilityVersion) - require.NoError(t, err, "failed to get hashed capability id for ccip") - require.NotEqual(t, [32]byte{}, ccipCapabilityID, "ccip capability id is empty") - - // Need to Add nodes and assign capabilities to them before creating DONS - homeChainUni.AddNodes(t, p2pIDs, [][32]byte{ccipCapabilityID}) - - for _, uni := range universes { - t.Logf("Adding chainconfig for chain %d", uni.chainID) - AddChainConfig(t, homeChainUni, getSelector(uni.chainID), p2pIDs, fChain) - } - - cfgs, err := homeChainUni.ccipConfig.GetAllChainConfigs(callCtx, big.NewInt(0), big.NewInt(100)) - require.NoError(t, err) - require.Len(t, cfgs, numChains) - - // Create a DON for each chain - for _, uni := range universes { - // Add nodes and give them the capability - t.Log("Adding DON for universe: ", uni.chainID) - chainSelector := getSelector(uni.chainID) - homeChainUni.AddDON( - t, - ccipCapabilityID, - chainSelector, - uni, - fChain, - bootstrapP2PID, - p2pIDs, - oracles[uni.chainID], - ) - } - - t.Log("Creating ocr3 jobs, starting oracles") - for i := 0; i < len(nodes); i++ { - err1 := nodes[i].app.Start(ctx) - require.NoError(t, err1) - tApp := apps[i] - t.Cleanup(func() { require.NoError(t, tApp.Stop()) }) - - jb := mustGetJobSpec(t, bootstrapP2PID, bootstrapPort, nodes[i].peerID, nodes[i].keybundle.ID()) - require.NoErrorf(t, tApp.AddJobV2(ctx, &jb), "Wasn't able to create ccip job for node %d", i) - } - - t.Logf("Sending ccip requests from each chain to all other chains") - for _, uni := range universes { - requests := genRequestData(uni.chainID, universes) - uni.SendCCIPRequests(t, requests) - } - - // Wait for the oracles to come up. - // TODO: We need some data driven way to do this e.g. wait until LP filters to be registered. - time.Sleep(oraclesBootWaitTime) - - // Replay the log poller on all the chains so that the logs are in the db. - // otherwise the plugins won't pick them up. - for _, node := range nodes { - for chainID := range universes { - t.Logf("Replaying logs for chain %d from block %d", chainID, 1) - require.NoError(t, node.app.ReplayFromBlock(big.NewInt(int64(chainID)), 1, false), "failed to replay logs") - } - } - - // with only one request sent from each chain to each other chain, - // and with sequence numbers on incrementing by 1 on a per-dest chain - // basis, we expect the min sequence number to be 1 on all chains. - expectedSeqNrRange := ccipocr3.NewSeqNumRange(1, 1) - var wg sync.WaitGroup - for _, uni := range universes { - for remoteSelector := range universes { - if remoteSelector == uni.chainID { - continue - } - wg.Add(1) - go func(uni onchainUniverse, remoteSelector uint64) { - defer wg.Done() - waitForCommitWithInterval(t, uni, getSelector(remoteSelector), expectedSeqNrRange) - }(uni, remoteSelector) - } - } - - start := time.Now() - wg.Wait() - t.Logf("All chains received the expected commit report in %s", time.Since(start)) - - // with only one request sent from each chain to each other chain, - // all ExecutionStateChanged events should have the sequence number 1. - expectedSeqNr := uint64(1) - for _, uni := range universes { - for remoteSelector := range universes { - if remoteSelector == uni.chainID { - continue - } - wg.Add(1) - go func(uni onchainUniverse, remoteSelector uint64) { - defer wg.Done() - waitForExecWithSeqNr(t, uni, getSelector(remoteSelector), expectedSeqNr) - }(uni, remoteSelector) - } - } - - start = time.Now() - wg.Wait() - t.Logf("All chains received the expected ExecutionStateChanged event in %s", time.Since(start)) -} - -func genRequestData(chainID uint64, universes map[uint64]onchainUniverse) []requestData { - var res []requestData - for destChainID, destUni := range universes { - if destChainID == chainID { - continue - } - res = append(res, requestData{ - destChainSelector: getSelector(destChainID), - receiverAddress: destUni.receiver.Address(), - data: []byte(fmt.Sprintf("msg from chain %d to chain %d", chainID, destChainID)), - }) - } - return res -} - -func waitForCommitWithInterval( - t *testing.T, - uni onchainUniverse, - expectedSourceChainSelector uint64, - expectedSeqNumRange ccipocr3.SeqNumRange, -) { - sink := make(chan *offramp.OffRampCommitReportAccepted) - subscription, err := uni.offramp.WatchCommitReportAccepted(&bind.WatchOpts{ - Context: testutils.Context(t), - }, sink) - require.NoError(t, err) - - for { - select { - case <-time.After(10 * time.Second): - t.Logf("Waiting for commit report on chain id %d (selector %d) from source selector %d expected seq nr range %s", - uni.chainID, getSelector(uni.chainID), expectedSourceChainSelector, expectedSeqNumRange.String()) - case subErr := <-subscription.Err(): - t.Fatalf("Subscription error: %+v", subErr) - case report := <-sink: - if len(report.Report.MerkleRoots) > 0 { - // Check the interval of sequence numbers and make sure it matches - // the expected range. - for _, mr := range report.Report.MerkleRoots { - if mr.SourceChainSelector == expectedSourceChainSelector && - uint64(expectedSeqNumRange.Start()) == mr.Interval.Min && - uint64(expectedSeqNumRange.End()) == mr.Interval.Max { - t.Logf("Received commit report on chain id %d (selector %d) from source selector %d expected seq nr range %s", - uni.chainID, getSelector(uni.chainID), expectedSourceChainSelector, expectedSeqNumRange.String()) - return - } - } - } - } - } -} - -func waitForExecWithSeqNr(t *testing.T, uni onchainUniverse, expectedSourceChainSelector, expectedSeqNr uint64) { - for { - scc, err := uni.offramp.GetSourceChainConfig(nil, expectedSourceChainSelector) - require.NoError(t, err) - t.Logf("Waiting for ExecutionStateChanged on chain %d (selector %d) from chain %d with expected sequence number %d, current onchain minSeqNr: %d", - uni.chainID, getSelector(uni.chainID), expectedSourceChainSelector, expectedSeqNr, scc.MinSeqNr) - iter, err := uni.offramp.FilterExecutionStateChanged(nil, []uint64{expectedSourceChainSelector}, []uint64{expectedSeqNr}, nil) - require.NoError(t, err) - var count int - for iter.Next() { - if iter.Event.SequenceNumber == expectedSeqNr && iter.Event.SourceChainSelector == expectedSourceChainSelector { - count++ - } - } - if count == 1 { - t.Logf("Received ExecutionStateChanged on chain %d (selector %d) from chain %d with expected sequence number %d", - uni.chainID, getSelector(uni.chainID), expectedSourceChainSelector, expectedSeqNr) - return - } - time.Sleep(5 * time.Second) - } -} From e2e7e4f99141eab57160f027708f41f489db21a0 Mon Sep 17 00:00:00 2001 From: Suryansh <39276431+0xsuryansh@users.noreply.github.com> Date: Thu, 22 Aug 2024 20:30:39 +0530 Subject: [PATCH 221/432] feat: PriceRegistry conforms to keystone interface (#1208) Depends on : https://github.com/smartcontractkit/chainlink/pull/13878 The price registry needs to conform to the KeystoneFeedsConsumer interface in order to receive keystone price feed updates. Implemented Keystones `IReciever` interface `onReport` function to handle the following report type ``` struct ReceivedFeedReport { address Token; uint224 Price; uint32 Timestamp; } ``` and storing the reported fee in `Internal.TimestampedPackedUint224` for `s_usdPerToken` mapping --------- Signed-off-by: 0xsuryansh --- contracts/gas-snapshots/ccip.gas-snapshot | 318 +++++++++--------- contracts/src/v0.8/ccip/PriceRegistry.sol | 109 ++++-- .../ccip/test/helpers/PriceRegistryHelper.sol | 8 + .../test/priceRegistry/PriceRegistry.t.sol | 138 ++++++++ .../v0.8/keystone/KeystoneFeedsConsumer.sol | 77 +---- .../KeystoneFeedsPermissionHandler.sol | 85 +++++ .../lib/KeystoneFeedDefaultMetadataLib.sol | 35 ++ .../price_registry/price_registry.go | 180 +++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- .../ccip/mocks/price_registry_interface.go | 296 ++++++++++++++++ 10 files changed, 995 insertions(+), 253 deletions(-) create mode 100644 contracts/src/v0.8/keystone/KeystoneFeedsPermissionHandler.sol create mode 100644 contracts/src/v0.8/keystone/lib/KeystoneFeedDefaultMetadataLib.sol diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 7e79a922d3..98503798b9 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -10,8 +10,8 @@ AggregateTokenLimiter_getTokenBucket:test_GetTokenBucket_Success() (gas: 19691) AggregateTokenLimiter_getTokenBucket:test_Refill_Success() (gas: 40911) AggregateTokenLimiter_getTokenBucket:test_TimeUnderflow_Revert() (gas: 15368) AggregateTokenLimiter_getTokenLimitAdmin:test_GetTokenLimitAdmin_Success() (gas: 10531) -AggregateTokenLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19696) -AggregateTokenLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21281) +AggregateTokenLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19652) +AggregateTokenLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21237) AggregateTokenLimiter_rateLimitValue:test_AggregateValueMaxCapacityExceeded_Revert() (gas: 16418) AggregateTokenLimiter_rateLimitValue:test_RateLimitValueSuccess_gas() (gas: 18306) AggregateTokenLimiter_setAdmin:test_OnlyOwnerOrAdmin_Revert() (gas: 13047) @@ -105,9 +105,9 @@ CommitStore_report:test_Paused_Revert() (gas: 21259) CommitStore_report:test_ReportAndPriceUpdate_Success() (gas: 84242) CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56313) CommitStore_report:test_RootAlreadyCommitted_Revert() (gas: 63969) -CommitStore_report:test_StaleReportWithRoot_Success() (gas: 119420) +CommitStore_report:test_StaleReportWithRoot_Success() (gas: 119332) CommitStore_report:test_Unhealthy_Revert() (gas: 44751) -CommitStore_report:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 100758) +CommitStore_report:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 100714) CommitStore_report:test_ZeroEpochAndRound_Revert() (gas: 27626) CommitStore_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11325) CommitStore_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 143718) @@ -123,7 +123,7 @@ CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424256) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1104303) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1103907) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37797) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103733) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85258) @@ -131,20 +131,20 @@ EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_InvalidDataLength_Rev EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 94302) EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 39768) EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 86559) -EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 385308) -EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 141902) -EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 803211) -EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 179272) +EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 385176) +EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 141858) +EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 802991) +EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 179228) EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 29240) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 66444) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 43320) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 211024) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 222288) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 210936) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 222200) EVM2EVMOffRamp__report:test_Report_Success() (gas: 126637) -EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 237819) -EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246419) -EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 329884) -EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 312321) +EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 237775) +EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246375) +EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 329796) +EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 312233) EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17030) EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153727) EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5665947) @@ -152,7 +152,7 @@ EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 144461) EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21318) EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36432) EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51598) -EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 473385) +EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 473297) EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 47668) EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152359) EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 102842) @@ -163,25 +163,25 @@ EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 15734 EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 172692) EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 247069) EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114153) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 407507) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 407419) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54096) EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 131047) EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52090) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 563497) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 495620) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 563321) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 495444) EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35383) -EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 544753) +EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 544577) EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64326) EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 122322) EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 142532) EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 427337) EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18502) -EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 278153) +EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 278065) EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 18659) -EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 221449) +EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 221405) EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47881) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 47352) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 313973) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 313885) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 70008) EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 229319) EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 276790) @@ -195,13 +195,13 @@ EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 185829) EVM2EVMOffRamp_manuallyExecute:test_ManualExecForkedChain_Revert() (gas: 27049) EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 45155) EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 27468) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithMultipleMessagesAndSourceTokens_Success() (gas: 530263) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithSourceTokens_Success() (gas: 345814) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithMultipleMessagesAndSourceTokens_Success() (gas: 530087) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithSourceTokens_Success() (gas: 345726) EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187324) -EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2321934) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DestinationGasAmountCountMismatch_Revert() (gas: 363021) +EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2321890) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DestinationGasAmountCountMismatch_Revert() (gas: 362933) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143900) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_InvalidTokenGasOverride_Revert() (gas: 366160) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_InvalidTokenGasOverride_Revert() (gas: 366072) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimitManualExec_Success() (gas: 482691) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 189727) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithInvalidReceiverExecutionGasOverride_Revert() (gas: 153641) @@ -225,18 +225,18 @@ EVM2EVMOnRamp_forwardFromRouter:test_InvalidAddressEncodePacked_Revert() (gas: 3 EVM2EVMOnRamp_forwardFromRouter:test_InvalidAddress_Revert() (gas: 38440) EVM2EVMOnRamp_forwardFromRouter:test_InvalidChainSelector_Revert() (gas: 25489) EVM2EVMOnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 25275) -EVM2EVMOnRamp_forwardFromRouter:test_MaxCapacityExceeded_Revert() (gas: 86041) +EVM2EVMOnRamp_forwardFromRouter:test_MaxCapacityExceeded_Revert() (gas: 85997) EVM2EVMOnRamp_forwardFromRouter:test_MaxFeeBalanceReached_Revert() (gas: 36457) EVM2EVMOnRamp_forwardFromRouter:test_MessageGasLimitTooHigh_Revert() (gas: 29015) EVM2EVMOnRamp_forwardFromRouter:test_MessageTooLarge_Revert() (gas: 107571) EVM2EVMOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 22679) -EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 224625) +EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 224581) EVM2EVMOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 53072) EVM2EVMOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 25481) -EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59347) +EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59303) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179148) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 177430) -EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137322) +EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137234) EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3822827) EVM2EVMOnRamp_forwardFromRouter:test_TooManyTokens_Revert() (gas: 30187) EVM2EVMOnRamp_forwardFromRouter:test_Unhealthy_Revert() (gas: 43300) @@ -244,7 +244,7 @@ EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109283) EVM2EVMOnRamp_forwardFromRouter:test_ZeroAddressReceiver_Revert() (gas: 312579) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_ShouldStoreLinkFees_Success() (gas: 112322) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 72206) -EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 710531) +EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 710443) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 147664) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 190529) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 121320) @@ -255,17 +255,17 @@ EVM2EVMOnRamp_getFee:test_EmptyMessage_Success() (gas: 78242) EVM2EVMOnRamp_getFee:test_HighGasMessage_Success() (gas: 234090) EVM2EVMOnRamp_getFee:test_MessageGasLimitTooHigh_Revert() (gas: 16715) EVM2EVMOnRamp_getFee:test_MessageTooLarge_Revert() (gas: 95271) -EVM2EVMOnRamp_getFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 159220) +EVM2EVMOnRamp_getFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 159352) EVM2EVMOnRamp_getFee:test_NotAFeeToken_Revert() (gas: 24089) -EVM2EVMOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 117858) +EVM2EVMOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 117902) EVM2EVMOnRamp_getFee:test_TooManyTokens_Revert() (gas: 19902) EVM2EVMOnRamp_getFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 64654) EVM2EVMOnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10460) EVM2EVMOnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35195) -EVM2EVMOnRamp_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 45082) +EVM2EVMOnRamp_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 45104) EVM2EVMOnRamp_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 33019) EVM2EVMOnRamp_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 28296) -EVM2EVMOnRamp_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 126225) +EVM2EVMOnRamp_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 126357) EVM2EVMOnRamp_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 15238) EVM2EVMOnRamp_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 28104) EVM2EVMOnRamp_getTokenTransferCost:test_UnsupportedToken_Revert() (gas: 21248) @@ -377,27 +377,27 @@ MultiAggregateRateLimiter_constructor:test_Constructor_Success() (gas: 2265894) MultiAggregateRateLimiter_getTokenBucket:test_GetTokenBucket_Success() (gas: 30248) MultiAggregateRateLimiter_getTokenBucket:test_Refill_Success() (gas: 47358) MultiAggregateRateLimiter_getTokenBucket:test_TimeUnderflow_Revert() (gas: 15821) -MultiAggregateRateLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19712) -MultiAggregateRateLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21297) +MultiAggregateRateLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19668) +MultiAggregateRateLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21253) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 14527) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213744) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 60487) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213612) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 60443) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 17593) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitDisabled_Success() (gas: 44895) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExceeded_Revert() (gas: 50598) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78780) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 312061) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54784) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExceeded_Revert() (gas: 50510) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78604) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 311885) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54696) MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 9223372036854754743) MultiAggregateRateLimiter_onOutboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 19104) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 15778) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213732) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 62222) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213600) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 62178) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitDisabled_Success() (gas: 46683) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitExceeded_Revert() (gas: 52371) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitReset_Success() (gas: 79845) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 312275) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokens_Success() (gas: 56541) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitExceeded_Revert() (gas: 52283) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitReset_Success() (gas: 79669) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 312099) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokens_Success() (gas: 56453) MultiAggregateRateLimiter_setPriceRegistry:test_OnlyOwner_Revert() (gas: 11292) MultiAggregateRateLimiter_setPriceRegistry:test_Owner_Success() (gas: 19080) MultiAggregateRateLimiter_setPriceRegistry:test_ZeroAddress_Revert() (gas: 10564) @@ -438,8 +438,8 @@ MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) -MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 393335) -MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1448084) +MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 393648) +MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1448351) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) @@ -451,10 +451,10 @@ NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success( NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244940) NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 233260) NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 150148) -NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 167625) -NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 218724) +NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 167714) +NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 218902) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) -NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 106854) +NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 106943) NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 122943) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOffRamp_Revert() (gas: 42959) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRampAndOffRamp_Revert() (gas: 64282) @@ -513,8 +513,8 @@ OffRamp_ccipReceive:test_Reverts() (gas: 15684) OffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67458) OffRamp_commit:test_InvalidInterval_Revert() (gas: 59734) OffRamp_commit:test_InvalidRootRevert() (gas: 58814) -OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6538150) -OffRamp_commit:test_NoConfig_Revert() (gas: 6121222) +OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6538106) +OffRamp_commit:test_NoConfig_Revert() (gas: 6121178) OffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106251) OffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116259) OffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106272) @@ -523,11 +523,11 @@ OffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159364) OffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136569) OffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136859) OffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 59082) -OffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225772) +OffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225684) OffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117566) OffRamp_commit:test_Unhealthy_Revert() (gas: 77608) -OffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 205117) -OffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6532473) +OffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 205073) +OffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6532429) OffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47788) OffRamp_constructor:test_Constructor_Success() (gas: 6125436) OffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137067) @@ -540,12 +540,12 @@ OffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17261) OffRamp_execute:test_LargeBatch_Success() (gas: 1726826) OffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 349476) OffRamp_execute:test_MultipleReports_Success() (gas: 276933) -OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6588848) -OffRamp_execute:test_NoConfig_Revert() (gas: 6171682) +OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6588804) +OffRamp_execute:test_NoConfig_Revert() (gas: 6171638) OffRamp_execute:test_NonArray_Revert() (gas: 27733) OffRamp_execute:test_SingleReport_Success() (gas: 172458) OffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147390) -OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6950922) +OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6950878) OffRamp_execute:test_ZeroReports_Revert() (gas: 17159) OffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18190) OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 246556) @@ -620,7 +620,7 @@ OffRamp_verify:test_Blessed_Success() (gas: 176620) OffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178688) OffRamp_verify:test_NotBlessed_Success() (gas: 141549) OffRamp_verify:test_TooManyLeaves_Revert() (gas: 51510) -OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 390410) +OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 390322) OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 63649) OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() (gas: 13308) OnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94175) @@ -628,31 +628,31 @@ OnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Rever OnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97113) OnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92150) OnRamp_constructor:test_Constructor_Success() (gas: 2384439) -OnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 71918) -OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 111914) -OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 142684) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 142260) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 140437) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 142490) -OnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 141859) -OnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 134347) -OnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 26294) +OnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 71940) +OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 112003) +OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 142773) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 142349) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 140526) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 142579) +OnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 141948) +OnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 134391) +OnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 26316) OnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 133253) -OnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 24360) +OnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 24382) OnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12872) OnRamp_forwardFromRouter:test_Paused_Revert() (gas: 32033) OnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 15762) -OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179401) -OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 205670) -OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 121815) -OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 143193) -OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3872608) -OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108546) -OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 73975) -OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 262685) -OnRamp_getFee:test_EmptyMessage_Success() (gas: 104467) -OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 74075) -OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119799) +OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179668) +OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 205937) +OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 121859) +OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 143149) +OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3872828) +OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108568) +OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 73997) +OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 262774) +OnRamp_getFee:test_EmptyMessage_Success() (gas: 104647) +OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 74120) +OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119979) OnRamp_getFee:test_Unhealthy_Revert() (gas: 43679) OnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10438) OnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35270) @@ -661,7 +661,7 @@ OnRamp_setDynamicConfig:test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Re OnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11112) OnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939) OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 51996) -OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97214) +OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97236) PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150175) PingPong_plumbing:test_OutOfOrderExecution_Success() (gas: 20277) PingPong_plumbing:test_Pausing_Success() (gas: 17777) @@ -673,101 +673,105 @@ PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestChainConfigDestChainSe PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitEqZero_Revert() (gas: 16681) PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitGtMaxPerMessageGasLimit_Revert() (gas: 40971) PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesZeroIntput_Success() (gas: 12341) -PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdates_Success() (gas: 139588) -PriceRegistry_applyFeeTokensUpdates:test_ApplyFeeTokensUpdates_Success() (gas: 80002) +PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdates_Success() (gas: 139678) +PriceRegistry_applyFeeTokensUpdates:test_ApplyFeeTokensUpdates_Success() (gas: 80108) PriceRegistry_applyFeeTokensUpdates:test_OnlyCallableByOwner_Revert() (gas: 12603) PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 11465) PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesMultipleTokens_Success() (gas: 54149) PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesSingleToken_Success() (gas: 44835) PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesZeroInput() (gas: 12301) -PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfig_Success() (gas: 86838) +PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfig_Success() (gas: 86926) PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeZeroInput() (gas: 13089) PriceRegistry_applyTokenTransferFeeConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 17071) PriceRegistry_applyTokenTransferFeeConfigUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 12240) -PriceRegistry_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 100474) -PriceRegistry_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 104824) -PriceRegistry_constructor:test_InvalidStalenessThreshold_Revert() (gas: 104877) -PriceRegistry_constructor:test_Setup_Success() (gas: 4637091) +PriceRegistry_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 101316) +PriceRegistry_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 105666) +PriceRegistry_constructor:test_InvalidStalenessThreshold_Revert() (gas: 105719) +PriceRegistry_constructor:test_Setup_Success() (gas: 5194297) PriceRegistry_convertTokenAmount:test_ConvertTokenAmount_Success() (gas: 72751) PriceRegistry_convertTokenAmount:test_LinkTokenNotSupported_Revert() (gas: 30981) -PriceRegistry_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 95587) +PriceRegistry_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 95677) PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCostUnsupportedDestChainSelector_Success() (gas: 14636) -PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20614) +PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20659) PriceRegistry_getTokenAndGasPrices:test_GetFeeTokenAndGasPrices_Success() (gas: 70449) PriceRegistry_getTokenAndGasPrices:test_StaleGasPrice_Revert() (gas: 16838) PriceRegistry_getTokenAndGasPrices:test_UnsupportedChain_Revert() (gas: 16140) PriceRegistry_getTokenAndGasPrices:test_ZeroGasPrice_Success() (gas: 45734) -PriceRegistry_getTokenPrice:test_GetTokenPriceFromFeed_Success() (gas: 62311) -PriceRegistry_getTokenPrices:test_GetTokenPrices_Success() (gas: 84774) -PriceRegistry_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 41255) -PriceRegistry_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 34705) -PriceRegistry_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 27779) -PriceRegistry_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 101708) +PriceRegistry_getTokenPrice:test_GetTokenPriceFromFeed_Success() (gas: 62308) +PriceRegistry_getTokenPrices:test_GetTokenPrices_Success() (gas: 84796) +PriceRegistry_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 41277) +PriceRegistry_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 34727) +PriceRegistry_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 27801) +PriceRegistry_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 101840) PriceRegistry_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 20398) -PriceRegistry_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 27654) -PriceRegistry_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 27610) +PriceRegistry_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 27676) +PriceRegistry_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 27632) PriceRegistry_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 40058) -PriceRegistry_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29337) -PriceRegistry_getValidatedFee:test_DestinationChainNotEnabled_Revert() (gas: 18203) -PriceRegistry_getValidatedFee:test_EmptyMessage_Success() (gas: 81464) -PriceRegistry_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 55196) -PriceRegistry_getValidatedFee:test_HighGasMessage_Success() (gas: 237926) -PriceRegistry_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 19971) -PriceRegistry_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 31775) -PriceRegistry_getValidatedFee:test_MessageTooLarge_Revert() (gas: 97714) -PriceRegistry_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 143193) -PriceRegistry_getValidatedFee:test_NotAFeeToken_Revert() (gas: 29435) -PriceRegistry_getValidatedFee:test_SingleTokenMessage_Success() (gas: 112283) -PriceRegistry_getValidatedFee:test_TooManyTokens_Revert() (gas: 20107) -PriceRegistry_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 62962) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Above18Decimals_Success() (gas: 2094532) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Below18Decimals_Success() (gas: 2094490) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt0Decimals_Success() (gas: 2074609) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt18Decimals_Success() (gas: 2094264) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFlippedDecimals_Success() (gas: 2094468) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedMaxInt224Value_Success() (gas: 2094280) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedOverStalenessPeriod_Success() (gas: 61997) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeed_Success() (gas: 61877) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPrice_Success() (gas: 60998) -PriceRegistry_getValidatedTokenPrice:test_OverflowFeedPrice_Revert() (gas: 2093992) -PriceRegistry_getValidatedTokenPrice:test_StaleFeeToken_Success() (gas: 61525) -PriceRegistry_getValidatedTokenPrice:test_TokenNotSupportedFeed_Revert() (gas: 109113) -PriceRegistry_getValidatedTokenPrice:test_TokenNotSupported_Revert() (gas: 13819) -PriceRegistry_getValidatedTokenPrice:test_UnderflowFeedPrice_Revert() (gas: 2092670) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsDefault_Success() (gas: 17360) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsEnforceOutOfOrder_Revert() (gas: 21454) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsGasLimitTooHigh_Revert() (gas: 18551) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsInvalidExtraArgsTag_Revert() (gas: 18075) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV1_Success() (gas: 18452) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV2_Success() (gas: 18569) -PriceRegistry_processMessageArgs:test_InvalidExtraArgs_Revert() (gas: 18306) -PriceRegistry_processMessageArgs:test_MalformedEVMExtraArgs_Revert() (gas: 18852) -PriceRegistry_processMessageArgs:test_MessageFeeTooHigh_Revert() (gas: 16360) -PriceRegistry_processMessageArgs:test_WitEVMExtraArgsV2_Success() (gas: 26236) -PriceRegistry_processMessageArgs:test_WithConvertedTokenAmount_Success() (gas: 32410) -PriceRegistry_processMessageArgs:test_WithEVMExtraArgsV1_Success() (gas: 25848) -PriceRegistry_processMessageArgs:test_WithEmptyEVMExtraArgs_Success() (gas: 23663) -PriceRegistry_processMessageArgs:test_WithLinkTokenAmount_Success() (gas: 17320) +PriceRegistry_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29359) +PriceRegistry_getValidatedFee:test_DestinationChainNotEnabled_Revert() (gas: 18248) +PriceRegistry_getValidatedFee:test_EmptyMessage_Success() (gas: 81644) +PriceRegistry_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 55241) +PriceRegistry_getValidatedFee:test_HighGasMessage_Success() (gas: 238106) +PriceRegistry_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 20016) +PriceRegistry_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 31820) +PriceRegistry_getValidatedFee:test_MessageTooLarge_Revert() (gas: 97759) +PriceRegistry_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 143549) +PriceRegistry_getValidatedFee:test_NotAFeeToken_Revert() (gas: 29480) +PriceRegistry_getValidatedFee:test_SingleTokenMessage_Success() (gas: 112551) +PriceRegistry_getValidatedFee:test_TooManyTokens_Revert() (gas: 20152) +PriceRegistry_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 63052) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Above18Decimals_Success() (gas: 2094595) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Below18Decimals_Success() (gas: 2094553) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt0Decimals_Success() (gas: 2074672) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt18Decimals_Success() (gas: 2094327) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFlippedDecimals_Success() (gas: 2094531) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedMaxInt224Value_Success() (gas: 2094343) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedOverStalenessPeriod_Success() (gas: 62060) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeed_Success() (gas: 61940) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPrice_Success() (gas: 61020) +PriceRegistry_getValidatedTokenPrice:test_OverflowFeedPrice_Revert() (gas: 2094030) +PriceRegistry_getValidatedTokenPrice:test_StaleFeeToken_Success() (gas: 61547) +PriceRegistry_getValidatedTokenPrice:test_TokenNotSupportedFeed_Revert() (gas: 109176) +PriceRegistry_getValidatedTokenPrice:test_TokenNotSupported_Revert() (gas: 13841) +PriceRegistry_getValidatedTokenPrice:test_UnderflowFeedPrice_Revert() (gas: 2092692) +PriceRegistry_onReport:test_OnReport_StaleUpdate_Revert() (gas: 43415) +PriceRegistry_onReport:test_onReport_InvalidForwarder_Reverts() (gas: 23261) +PriceRegistry_onReport:test_onReport_Success() (gas: 80702) +PriceRegistry_onReport:test_onReport_UnsupportedToken_Reverts() (gas: 26681) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsDefault_Success() (gas: 17316) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsEnforceOutOfOrder_Revert() (gas: 21410) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsGasLimitTooHigh_Revert() (gas: 18507) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsInvalidExtraArgsTag_Revert() (gas: 18031) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV1_Success() (gas: 18408) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV2_Success() (gas: 18525) +PriceRegistry_processMessageArgs:test_InvalidExtraArgs_Revert() (gas: 18328) +PriceRegistry_processMessageArgs:test_MalformedEVMExtraArgs_Revert() (gas: 18874) +PriceRegistry_processMessageArgs:test_MessageFeeTooHigh_Revert() (gas: 16382) +PriceRegistry_processMessageArgs:test_WitEVMExtraArgsV2_Success() (gas: 26303) +PriceRegistry_processMessageArgs:test_WithConvertedTokenAmount_Success() (gas: 32432) +PriceRegistry_processMessageArgs:test_WithEVMExtraArgsV1_Success() (gas: 25915) +PriceRegistry_processMessageArgs:test_WithEmptyEVMExtraArgs_Success() (gas: 23730) +PriceRegistry_processMessageArgs:test_WithLinkTokenAmount_Success() (gas: 17342) PriceRegistry_updatePrices:test_OnlyCallableByUpdater_Revert() (gas: 12080) -PriceRegistry_updatePrices:test_OnlyGasPrice_Success() (gas: 23599) -PriceRegistry_updatePrices:test_OnlyTokenPrice_Success() (gas: 30637) -PriceRegistry_updatePrices:test_UpdatableByAuthorizedCaller_Success() (gas: 76043) -PriceRegistry_updatePrices:test_UpdateMultiplePrices_Success() (gas: 151521) -PriceRegistry_updateTokenPriceFeeds:test_FeedNotUpdated() (gas: 50699) -PriceRegistry_updateTokenPriceFeeds:test_FeedUnset_Success() (gas: 63882) +PriceRegistry_updatePrices:test_OnlyGasPrice_Success() (gas: 23621) +PriceRegistry_updatePrices:test_OnlyTokenPrice_Success() (gas: 30593) +PriceRegistry_updatePrices:test_UpdatableByAuthorizedCaller_Success() (gas: 75937) +PriceRegistry_updatePrices:test_UpdateMultiplePrices_Success() (gas: 151455) +PriceRegistry_updateTokenPriceFeeds:test_FeedNotUpdated() (gas: 50633) +PriceRegistry_updateTokenPriceFeeds:test_FeedUnset_Success() (gas: 63662) PriceRegistry_updateTokenPriceFeeds:test_FeedUpdatedByNonOwner_Revert() (gas: 19998) -PriceRegistry_updateTokenPriceFeeds:test_MultipleFeedUpdate_Success() (gas: 89162) -PriceRegistry_updateTokenPriceFeeds:test_SingleFeedUpdate_Success() (gas: 50949) +PriceRegistry_updateTokenPriceFeeds:test_MultipleFeedUpdate_Success() (gas: 88898) +PriceRegistry_updateTokenPriceFeeds:test_SingleFeedUpdate_Success() (gas: 50817) PriceRegistry_updateTokenPriceFeeds:test_ZeroFeeds_Success() (gas: 12362) PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddressEncodePacked_Revert() (gas: 10572) PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddressPrecompiles_Revert() (gas: 3916546) PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddress_Revert() (gas: 10756) PriceRegistry_validateDestFamilyAddress:test_ValidEVMAddress_Success() (gas: 6660) PriceRegistry_validateDestFamilyAddress:test_ValidNonEVMAddress_Success() (gas: 6440) -PriceRegistry_validatePoolReturnData:test_InvalidEVMAddressDestToken_Revert() (gas: 35457) -PriceRegistry_validatePoolReturnData:test_SourceTokenDataTooLarge_Revert() (gas: 90709) -PriceRegistry_validatePoolReturnData:test_TokenAmountArraysMismatching_Revert() (gas: 32749) -PriceRegistry_validatePoolReturnData:test_WithSingleToken_Success() (gas: 31293) +PriceRegistry_validatePoolReturnData:test_InvalidEVMAddressDestToken_Revert() (gas: 35479) +PriceRegistry_validatePoolReturnData:test_SourceTokenDataTooLarge_Revert() (gas: 90819) +PriceRegistry_validatePoolReturnData:test_TokenAmountArraysMismatching_Revert() (gas: 32771) +PriceRegistry_validatePoolReturnData:test_WithSingleToken_Success() (gas: 31315) RMN_constructor:test_Constructor_Success() (gas: 48838) RMN_getRecordedCurseRelatedOps:test_OpsPostDeployment() (gas: 19666) RMN_lazyVoteToCurseUpdate_Benchmark:test_VoteToCurseLazilyRetain3VotersUponConfigChange_gas() (gas: 152152) diff --git a/contracts/src/v0.8/ccip/PriceRegistry.sol b/contracts/src/v0.8/ccip/PriceRegistry.sol index f40f604e83..8551971753 100644 --- a/contracts/src/v0.8/ccip/PriceRegistry.sol +++ b/contracts/src/v0.8/ccip/PriceRegistry.sol @@ -11,14 +11,24 @@ import {Internal} from "./libraries/Internal.sol"; import {Pool} from "./libraries/Pool.sol"; import {USDPriceWith18Decimals} from "./libraries/USDPriceWith18Decimals.sol"; +import {KeystoneFeedsPermissionHandler} from "../keystone/KeystoneFeedsPermissionHandler.sol"; +import {IReceiver} from "../keystone/interfaces/IReceiver.sol"; +import {KeystoneFeedDefaultMetadataLib} from "../keystone/lib/KeystoneFeedDefaultMetadataLib.sol"; import {EnumerableSet} from "../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; /// @notice The PriceRegistry contract responsibility is to store the current gas price in USD for a given destination chain, /// and the price of a token in USD allowing the owner or priceUpdater to update this value. /// The authorized callers in the contract represent the fee price updaters. -contract PriceRegistry is AuthorizedCallers, IPriceRegistry, ITypeAndVersion { +contract PriceRegistry is + AuthorizedCallers, + IPriceRegistry, + ITypeAndVersion, + IReceiver, + KeystoneFeedsPermissionHandler +{ using EnumerableSet for EnumerableSet.AddressSet; using USDPriceWith18Decimals for uint224; + using KeystoneFeedDefaultMetadataLib for bytes; /// @notice Token price data feed update struct TokenPriceFeedUpdate { @@ -35,9 +45,17 @@ contract PriceRegistry is AuthorizedCallers, IPriceRegistry, ITypeAndVersion { uint32 stalenessThreshold; // The amount of time a gas price can be stale before it is considered invalid. } + /// @notice The struct representing the received CCIP feed report from keystone IReceiver.onReport() + struct ReceivedCCIPFeedReport { + address token; // Token address + uint224 price; // ─────────╮ Price of the token in USD with 18 decimals + uint32 timestamp; // ──────╯ Timestamp of the price update + } + error TokenNotSupported(address token); error ChainNotSupported(uint64 chain); error StaleGasPrice(uint64 destChainSelector, uint256 threshold, uint256 timePassed); + error StaleKeystoneUpdate(address token, uint256 feedTimestamp, uint256 storedTimeStamp); error DataFeedValueOutOfUint224Range(); error InvalidDestBytesOverhead(address token, uint32 destBytesOverhead); error MessageGasLimitTooHigh(); @@ -325,30 +343,11 @@ contract PriceRegistry is AuthorizedCallers, IPriceRegistry, ITypeAndVersion { if (dataFeedAnswer < 0) { revert DataFeedValueOutOfUint224Range(); } - uint256 rebasedValue = uint256(dataFeedAnswer); - - // Rebase formula for units in smallest token denomination: usdValue * (1e18 * 1e18) / 1eTokenDecimals - // feedValue * (10 ** (18 - feedDecimals)) * (10 ** (18 - erc20Decimals)) - // feedValue * (10 ** ((18 - feedDecimals) + (18 - erc20Decimals))) - // feedValue * (10 ** (36 - feedDecimals - erc20Decimals)) - // feedValue * (10 ** (36 - (feedDecimals + erc20Decimals))) - // feedValue * (10 ** (36 - excessDecimals)) - // If excessDecimals > 36 => flip it to feedValue / (10 ** (excessDecimals - 36)) - - uint8 excessDecimals = dataFeedContract.decimals() + priceFeedConfig.tokenDecimals; - - if (excessDecimals > 36) { - rebasedValue /= 10 ** (excessDecimals - 36); - } else { - rebasedValue *= 10 ** (36 - excessDecimals); - } - - if (rebasedValue > type(uint224).max) { - revert DataFeedValueOutOfUint224Range(); - } + uint224 rebasedValue = + _calculateRebasedValue(dataFeedContract.decimals(), priceFeedConfig.tokenDecimals, uint256(dataFeedAnswer)); // Data feed staleness is unchecked to decouple the PriceRegistry from data feed delay issues - return Internal.TimestampedPackedUint224({value: uint224(rebasedValue), timestamp: uint32(block.timestamp)}); + return Internal.TimestampedPackedUint224({value: rebasedValue, timestamp: uint32(block.timestamp)}); } // ================================================================ @@ -435,6 +434,37 @@ contract PriceRegistry is AuthorizedCallers, IPriceRegistry, ITypeAndVersion { } } + /// @notice Handles the report containing price feeds and updates the internal price storage + /// @inheritdoc IReceiver + /// @dev This function is called to process incoming price feed data. + /// @param metadata Arbitrary metadata associated with the report (not used in this implementation). + /// @param report Encoded report containing an array of `ReceivedCCIPFeedReport` structs. + function onReport(bytes calldata metadata, bytes calldata report) external { + (bytes10 workflowName, address workflowOwner, bytes2 reportName) = metadata._extractMetadataInfo(); + + _validateReportPermission(msg.sender, workflowOwner, workflowName, reportName); + + ReceivedCCIPFeedReport[] memory feeds = abi.decode(report, (ReceivedCCIPFeedReport[])); + + for (uint256 i = 0; i < feeds.length; ++i) { + uint8 tokenDecimals = s_usdPriceFeedsPerToken[feeds[i].token].tokenDecimals; + if (tokenDecimals == 0) { + revert TokenNotSupported(feeds[i].token); + } + // Keystone reports prices in USD with 18 decimals, so we passing it as 18 in the _calculateRebasedValue function + uint224 rebasedValue = _calculateRebasedValue(18, tokenDecimals, feeds[i].price); + + //if stale update then revert + if (feeds[i].timestamp < s_usdPerToken[feeds[i].token].timestamp) { + revert StaleKeystoneUpdate(feeds[i].token, feeds[i].timestamp, s_usdPerToken[feeds[i].token].timestamp); + } + + s_usdPerToken[feeds[i].token] = + Internal.TimestampedPackedUint224({value: rebasedValue, timestamp: feeds[i].timestamp}); + emit UsdPerTokenUpdated(feeds[i].token, rebasedValue, feeds[i].timestamp); + } + } + // ================================================================ // │ Fee quoting │ // ================================================================ @@ -612,6 +642,39 @@ contract PriceRegistry is AuthorizedCallers, IPriceRegistry, ITypeAndVersion { return (tokenTransferFeeUSDWei, tokenTransferGas, tokenTransferBytesOverhead); } + /// @notice calculates the rebased value for 1e18 smallest token denomination + /// @param dataFeedDecimal decimal of the data feed + /// @param tokenDecimal decimal of the token + /// @param feedValue value of the data feed + /// @return rebasedValue rebased value + function _calculateRebasedValue( + uint8 dataFeedDecimal, + uint8 tokenDecimal, + uint256 feedValue + ) internal pure returns (uint224 rebasedValue) { + // Rebase formula for units in smallest token denomination: usdValue * (1e18 * 1e18) / 1eTokenDecimals + // feedValue * (10 ** (18 - feedDecimals)) * (10 ** (18 - erc20Decimals)) + // feedValue * (10 ** ((18 - feedDecimals) + (18 - erc20Decimals))) + // feedValue * (10 ** (36 - feedDecimals - erc20Decimals)) + // feedValue * (10 ** (36 - (feedDecimals + erc20Decimals))) + // feedValue * (10 ** (36 - excessDecimals)) + // If excessDecimals > 36 => flip it to feedValue / (10 ** (excessDecimals - 36)) + uint8 excessDecimals = dataFeedDecimal + tokenDecimal; + uint256 rebasedVal; + + if (excessDecimals > 36) { + rebasedVal = feedValue / (10 ** (excessDecimals - 36)); + } else { + rebasedVal = feedValue * (10 ** (36 - excessDecimals)); + } + + if (rebasedVal > type(uint224).max) { + revert DataFeedValueOutOfUint224Range(); + } + + return uint224(rebasedVal); + } + /// @notice Returns the estimated data availability cost of the message. /// @dev To save on gas, we use a single destGasPerDataAvailabilityByte value for both zero and non-zero bytes. /// @param destChainConfig the config configured for the destination chain selector. diff --git a/contracts/src/v0.8/ccip/test/helpers/PriceRegistryHelper.sol b/contracts/src/v0.8/ccip/test/helpers/PriceRegistryHelper.sol index 8524df12cc..f939cd3c1f 100644 --- a/contracts/src/v0.8/ccip/test/helpers/PriceRegistryHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/PriceRegistryHelper.sol @@ -69,4 +69,12 @@ contract PriceRegistryHelper is PriceRegistry { function validateDestFamilyAddress(bytes4 chainFamilySelector, bytes memory destAddress) external pure { _validateDestFamilyAddress(chainFamilySelector, destAddress); } + + function calculateRebasedValue( + uint8 dataFeedDecimal, + uint8 tokenDecimal, + uint256 feedValue + ) external pure returns (uint224) { + return _calculateRebasedValue(dataFeedDecimal, tokenDecimal, feedValue); + } } diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol index f59d27a2cb..bc7b3159b6 100644 --- a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol +++ b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol @@ -1,9 +1,11 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; +import {KeystoneFeedsPermissionHandler} from "../../../keystone/KeystoneFeedsPermissionHandler.sol"; import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol"; import {PriceRegistry} from "../../PriceRegistry.sol"; +import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {Pool} from "../../libraries/Pool.sol"; @@ -2089,3 +2091,139 @@ contract PriceRegistry_parseEVMExtraArgsFromBytes is PriceRegistrySetup { s_priceRegistry.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig); } } + +contract PriceRegistry_KeystoneSetup is PriceRegistrySetup { + address constant FORWARDER_1 = address(0x1); + address constant WORKFLOW_OWNER_1 = address(0x3); + bytes10 constant WORKFLOW_NAME_1 = "workflow1"; + bytes2 constant REPORT_NAME_1 = "01"; + address onReportTestToken1; + address onReportTestToken2; + + function setUp() public virtual override { + super.setUp(); + onReportTestToken1 = s_sourceTokens[0]; + onReportTestToken2 = _deploySourceToken("onReportTestToken2", 0, 20); + + KeystoneFeedsPermissionHandler.Permission[] memory permissions = new KeystoneFeedsPermissionHandler.Permission[](1); + permissions[0] = KeystoneFeedsPermissionHandler.Permission({ + forwarder: FORWARDER_1, + workflowOwner: WORKFLOW_OWNER_1, + workflowName: WORKFLOW_NAME_1, + reportName: REPORT_NAME_1, + isAllowed: true + }); + PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeeds = new PriceRegistry.TokenPriceFeedUpdate[](2); + tokenPriceFeeds[0] = PriceRegistry.TokenPriceFeedUpdate({ + sourceToken: onReportTestToken1, + feedConfig: IPriceRegistry.TokenPriceFeedConfig({dataFeedAddress: address(0x0), tokenDecimals: 18}) + }); + tokenPriceFeeds[1] = PriceRegistry.TokenPriceFeedUpdate({ + sourceToken: onReportTestToken2, + feedConfig: IPriceRegistry.TokenPriceFeedConfig({dataFeedAddress: address(0x0), tokenDecimals: 20}) + }); + s_priceRegistry.setReportPermissions(permissions); + s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeeds); + } +} + +contract PriceRegistry_onReport is PriceRegistry_KeystoneSetup { + function test_onReport_Success() public { + bytes memory encodedPermissionsMetadata = + abi.encodePacked(keccak256(abi.encode("workflowCID")), WORKFLOW_NAME_1, WORKFLOW_OWNER_1, REPORT_NAME_1); + + PriceRegistry.ReceivedCCIPFeedReport[] memory report = new PriceRegistry.ReceivedCCIPFeedReport[](2); + report[0] = + PriceRegistry.ReceivedCCIPFeedReport({token: onReportTestToken1, price: 4e18, timestamp: uint32(block.timestamp)}); + report[1] = + PriceRegistry.ReceivedCCIPFeedReport({token: onReportTestToken2, price: 4e18, timestamp: uint32(block.timestamp)}); + + bytes memory encodedReport = abi.encode(report); + uint224 expectedStoredToken1Price = s_priceRegistry.calculateRebasedValue(18, 18, report[0].price); + uint224 expectedStoredToken2Price = s_priceRegistry.calculateRebasedValue(18, 20, report[1].price); + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(onReportTestToken1, expectedStoredToken1Price, block.timestamp); + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(onReportTestToken2, expectedStoredToken2Price, block.timestamp); + + changePrank(FORWARDER_1); + s_priceRegistry.onReport(encodedPermissionsMetadata, encodedReport); + + vm.assertEq(s_priceRegistry.getTokenPrice(report[0].token).value, expectedStoredToken1Price); + vm.assertEq(s_priceRegistry.getTokenPrice(report[0].token).timestamp, report[0].timestamp); + + vm.assertEq(s_priceRegistry.getTokenPrice(report[1].token).value, expectedStoredToken2Price); + vm.assertEq(s_priceRegistry.getTokenPrice(report[1].token).timestamp, report[1].timestamp); + } + + function test_onReport_InvalidForwarder_Reverts() public { + bytes memory encodedPermissionsMetadata = + abi.encodePacked(keccak256(abi.encode("workflowCID")), WORKFLOW_NAME_1, WORKFLOW_OWNER_1, REPORT_NAME_1); + PriceRegistry.ReceivedCCIPFeedReport[] memory report = new PriceRegistry.ReceivedCCIPFeedReport[](1); + report[0] = + PriceRegistry.ReceivedCCIPFeedReport({token: s_sourceTokens[0], price: 4e18, timestamp: uint32(block.timestamp)}); + + bytes memory encodedReport = abi.encode(report); + + vm.expectRevert( + abi.encodeWithSelector( + KeystoneFeedsPermissionHandler.ReportForwarderUnauthorized.selector, + STRANGER, + WORKFLOW_OWNER_1, + WORKFLOW_NAME_1, + REPORT_NAME_1 + ) + ); + changePrank(STRANGER); + s_priceRegistry.onReport(encodedPermissionsMetadata, encodedReport); + } + + function test_onReport_UnsupportedToken_Reverts() public { + bytes memory encodedPermissionsMetadata = + abi.encodePacked(keccak256(abi.encode("workflowCID")), WORKFLOW_NAME_1, WORKFLOW_OWNER_1, REPORT_NAME_1); + PriceRegistry.ReceivedCCIPFeedReport[] memory report = new PriceRegistry.ReceivedCCIPFeedReport[](1); + report[0] = + PriceRegistry.ReceivedCCIPFeedReport({token: s_sourceTokens[1], price: 4e18, timestamp: uint32(block.timestamp)}); + + bytes memory encodedReport = abi.encode(report); + + vm.expectRevert(abi.encodeWithSelector(PriceRegistry.TokenNotSupported.selector, s_sourceTokens[1])); + changePrank(FORWARDER_1); + s_priceRegistry.onReport(encodedPermissionsMetadata, encodedReport); + } + + function test_OnReport_StaleUpdate_Revert() public { + //Creating a correct report + bytes memory encodedPermissionsMetadata = + abi.encodePacked(keccak256(abi.encode("workflowCID")), WORKFLOW_NAME_1, WORKFLOW_OWNER_1, REPORT_NAME_1); + + PriceRegistry.ReceivedCCIPFeedReport[] memory report = new PriceRegistry.ReceivedCCIPFeedReport[](1); + report[0] = + PriceRegistry.ReceivedCCIPFeedReport({token: onReportTestToken1, price: 4e18, timestamp: uint32(block.timestamp)}); + + bytes memory encodedReport = abi.encode(report); + uint224 expectedStoredTokenPrice = s_priceRegistry.calculateRebasedValue(18, 18, report[0].price); + + vm.expectEmit(); + emit PriceRegistry.UsdPerTokenUpdated(onReportTestToken1, expectedStoredTokenPrice, block.timestamp); + + changePrank(FORWARDER_1); + //setting the correct price and time with the correct report + s_priceRegistry.onReport(encodedPermissionsMetadata, encodedReport); + + //create a stale report + report[0] = PriceRegistry.ReceivedCCIPFeedReport({ + token: onReportTestToken1, + price: 4e18, + timestamp: uint32(block.timestamp - 1) + }); + encodedReport = abi.encode(report); + //expecting a revert + vm.expectRevert( + abi.encodeWithSelector( + PriceRegistry.StaleKeystoneUpdate.selector, onReportTestToken1, block.timestamp - 1, block.timestamp + ) + ); + s_priceRegistry.onReport(encodedPermissionsMetadata, encodedReport); + } +} diff --git a/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol b/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol index ba1a7c6a8c..bc722eff29 100644 --- a/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol +++ b/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol @@ -1,16 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol"; import {IReceiver} from "./interfaces/IReceiver.sol"; +import {KeystoneFeedsPermissionHandler} from "./KeystoneFeedsPermissionHandler.sol"; +import {KeystoneFeedDefaultMetadataLib} from "./lib/KeystoneFeedDefaultMetadataLib.sol"; -contract KeystoneFeedsConsumer is IReceiver, OwnerIsCreator, IERC165 { - event FeedReceived(bytes32 indexed feedId, uint224 price, uint32 timestamp); +contract KeystoneFeedsConsumer is IReceiver, KeystoneFeedsPermissionHandler { + using KeystoneFeedDefaultMetadataLib for bytes; - error UnauthorizedSender(address sender); - error UnauthorizedWorkflowOwner(address workflowOwner); - error UnauthorizedWorkflowName(bytes10 workflowName); + event FeedReceived(bytes32 indexed feedId, uint224 price, uint32 timestamp); struct ReceivedFeedReport { bytes32 FeedId; @@ -24,53 +22,11 @@ contract KeystoneFeedsConsumer is IReceiver, OwnerIsCreator, IERC165 { } mapping(bytes32 feedId => StoredFeedReport feedReport) internal s_feedReports; - address[] internal s_allowedSendersList; - mapping(address sender => bool) internal s_allowedSenders; - address[] internal s_allowedWorkflowOwnersList; - mapping(address owner => bool) internal s_allowedWorkflowOwners; - bytes10[] internal s_allowedWorkflowNamesList; - mapping(bytes10 workflowName => bool) internal s_allowedWorkflowNames; - - function setConfig( - address[] calldata _allowedSendersList, - address[] calldata _allowedWorkflowOwnersList, - bytes10[] calldata _allowedWorkflowNamesList - ) external onlyOwner { - for (uint32 i = 0; i < s_allowedSendersList.length; ++i) { - s_allowedSenders[s_allowedSendersList[i]] = false; - } - for (uint32 i = 0; i < _allowedSendersList.length; ++i) { - s_allowedSenders[_allowedSendersList[i]] = true; - } - s_allowedSendersList = _allowedSendersList; - for (uint32 i = 0; i < s_allowedWorkflowOwnersList.length; ++i) { - s_allowedWorkflowOwners[s_allowedWorkflowOwnersList[i]] = false; - } - for (uint32 i = 0; i < _allowedWorkflowOwnersList.length; ++i) { - s_allowedWorkflowOwners[_allowedWorkflowOwnersList[i]] = true; - } - s_allowedWorkflowOwnersList = _allowedWorkflowOwnersList; - for (uint32 i = 0; i < s_allowedWorkflowNamesList.length; ++i) { - s_allowedWorkflowNames[s_allowedWorkflowNamesList[i]] = false; - } - for (uint32 i = 0; i < _allowedWorkflowNamesList.length; ++i) { - s_allowedWorkflowNames[_allowedWorkflowNamesList[i]] = true; - } - s_allowedWorkflowNamesList = _allowedWorkflowNamesList; - } function onReport(bytes calldata metadata, bytes calldata rawReport) external { - if (!s_allowedSenders[msg.sender]) { - revert UnauthorizedSender(msg.sender); - } + (bytes10 workflowName, address workflowOwner, bytes2 reportName) = metadata._extractMetadataInfo(); - (bytes10 workflowName, address workflowOwner) = _getInfo(metadata); - if (!s_allowedWorkflowNames[workflowName]) { - revert UnauthorizedWorkflowName(workflowName); - } - if (!s_allowedWorkflowOwners[workflowOwner]) { - revert UnauthorizedWorkflowOwner(workflowOwner); - } + _validateReportPermission(msg.sender, workflowOwner, workflowName, reportName); ReceivedFeedReport[] memory feeds = abi.decode(rawReport, (ReceivedFeedReport[])); for (uint256 i = 0; i < feeds.length; ++i) { @@ -79,27 +35,8 @@ contract KeystoneFeedsConsumer is IReceiver, OwnerIsCreator, IERC165 { } } - // solhint-disable-next-line chainlink-solidity/explicit-returns - function _getInfo(bytes memory metadata) internal pure returns (bytes10 workflowName, address workflowOwner) { - // (first 32 bytes contain length of the byte array) - // workflow_cid // offset 32, size 32 - // workflow_name // offset 64, size 10 - // workflow_owner // offset 74, size 20 - // report_name // offset 94, size 2 - assembly { - // no shifting needed for bytes10 type - workflowName := mload(add(metadata, 64)) - // shift right by 12 bytes to get the actual value - workflowOwner := shr(mul(12, 8), mload(add(metadata, 74))) - } - } - function getPrice(bytes32 feedId) external view returns (uint224, uint32) { StoredFeedReport memory report = s_feedReports[feedId]; return (report.Price, report.Timestamp); } - - function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { - return interfaceId == this.onReport.selector; - } } diff --git a/contracts/src/v0.8/keystone/KeystoneFeedsPermissionHandler.sol b/contracts/src/v0.8/keystone/KeystoneFeedsPermissionHandler.sol new file mode 100644 index 0000000000..3223deeebe --- /dev/null +++ b/contracts/src/v0.8/keystone/KeystoneFeedsPermissionHandler.sol @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol"; + +/// @title Keystone Feeds Permission Handler +/// @notice This contract is designed to manage and validate permissions for accessing specific reports within a decentralized system. +/// @dev The contract uses mappings to keep track of report permissions associated with a unique report ID. +abstract contract KeystoneFeedsPermissionHandler is OwnerIsCreator { + /// @notice Holds the details for permissions of a report + /// @dev Workflow names and report names are stored as bytes to optimize for gas efficiency. + struct Permission { + address forwarder; //───────────────╮ The address of the forwarder (20 bytes) + bytes10 workflowName; // │ The name of the workflow in bytes10 + bytes2 reportName; //───────────────╯ The name of the report in bytes2 + address workflowOwner; //──────────────╮ // The address of the workflow owner (20 bytes) + bool isAllowed; //─────────────────────╯// Whether the report is allowed or not (1 byte) + } + + /// @notice Event emitted when report permissions are set + event ReportPermissionSet(bytes32 indexed reportId, Permission permission); + + /// @notice Error to be thrown when an unauthorized access attempt is made + error ReportForwarderUnauthorized(address forwarder, address workflowOwner, bytes10 workflowName, bytes2 reportName); + + /// @dev Mapping from a report ID to a boolean indicating whether the report is allowed or not + mapping(bytes32 reportId => bool isAllowed) internal s_allowedReports; + + /// @notice Sets permissions for multiple reports + /// @param permissions An array of Permission structs for which to set permissions + /// @dev Emits a ReportPermissionSet event for each permission set + function setReportPermissions(Permission[] memory permissions) external onlyOwner { + for (uint256 i; i < permissions.length; ++i) { + _setReportPermission(permissions[i]); + } + } + + /// @dev Internal function to set a single report permission + /// @param permission The Permission struct containing details about the permission to set + /// @dev Emits a ReportPermissionSet event + function _setReportPermission(Permission memory permission) internal { + bytes32 reportId = _createReportId( + permission.forwarder, + permission.workflowOwner, + permission.workflowName, + permission.reportName + ); + s_allowedReports[reportId] = permission.isAllowed; + emit ReportPermissionSet(reportId, permission); + } + + /// @dev Internal view function to validate if a report is allowed for a given set of details + /// @param forwarder The address of the forwarder + /// @param workflowOwner The address of the workflow owner + /// @param workflowName The name of the workflow in bytes10 + /// @param reportName The name of the report in bytes2 + /// @dev Reverts with Unauthorized if the report is not allowed + function _validateReportPermission( + address forwarder, + address workflowOwner, + bytes10 workflowName, + bytes2 reportName + ) internal view { + bytes32 reportId = _createReportId(forwarder, workflowOwner, workflowName, reportName); + if (!s_allowedReports[reportId]) { + revert ReportForwarderUnauthorized(forwarder, workflowOwner, workflowName, reportName); + } + } + + /// @notice Generates a unique report ID based on the provided parameters. + /// @dev The report ID is computed using the Keccak-256 hash function over the encoded parameters. + /// @param forwarder The address of the forwarder associated with the report. + /// @param workflowOwner The address of the owner of the workflow. + /// @param workflowName The name of the workflow, represented as a 10-byte value. + /// @param reportName The name of the report, represented as a 2-byte value. + /// @return reportId The computed unique report ID as a bytes32 value. + function _createReportId( + address forwarder, + address workflowOwner, + bytes10 workflowName, + bytes2 reportName + ) internal pure returns (bytes32 reportId) { + return keccak256(abi.encode(forwarder, workflowOwner, workflowName, reportName)); + } +} diff --git a/contracts/src/v0.8/keystone/lib/KeystoneFeedDefaultMetadataLib.sol b/contracts/src/v0.8/keystone/lib/KeystoneFeedDefaultMetadataLib.sol new file mode 100644 index 0000000000..061789be5c --- /dev/null +++ b/contracts/src/v0.8/keystone/lib/KeystoneFeedDefaultMetadataLib.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +library KeystoneFeedDefaultMetadataLib { + /** + * Metadata Layout: + * + * +-------------------------------+--------------------+---------------------+---------------+ + * | 32 bytes (length prefix) | 32 bytes | 10 bytes | 20 bytes | 2 bytes | + * | (Not used in function) | workflow_cid | workflow_name | workflow_owner| report_name | + * +-------------------------------+--------------------+---------------------+---------------+----------------+ + * | | | | | | + * | (Offset 0) | (Offset 32) | (Offset 64) | (Offset 74) | (Offset 94) | + * +-------------------------------+--------------------+---------------------+---------------+----------------+ + * @dev used to slice metadata bytes into workflowName, workflowOwner and report name + */ + function _extractMetadataInfo( + bytes memory metadata + ) internal pure returns (bytes10 workflowName, address workflowOwner, bytes2 reportName) { + // (first 32 bytes contain length of the byte array) + // workflow_cid // offset 32, size 32 + // workflow_name // offset 64, size 10 + // workflow_owner // offset 74, size 20 + // report_name // offset 94, size 2 + assembly { + // no shifting needed for bytes10 type + workflowName := mload(add(metadata, 64)) + // shift right by 12 bytes to get the actual value + workflowOwner := shr(mul(12, 8), mload(add(metadata, 74))) + // no shifting needed for bytes2 type + reportName := mload(add(metadata, 94)) + } + return (workflowName, workflowOwner, reportName); + } +} diff --git a/core/gethwrappers/ccip/generated/price_registry/price_registry.go b/core/gethwrappers/ccip/generated/price_registry/price_registry.go index f7b44ab66b..fd50287f53 100644 --- a/core/gethwrappers/ccip/generated/price_registry/price_registry.go +++ b/core/gethwrappers/ccip/generated/price_registry/price_registry.go @@ -80,6 +80,14 @@ type InternalTokenPriceUpdate struct { UsdPerToken *big.Int } +type KeystoneFeedsPermissionHandlerPermission struct { + Forwarder common.Address + WorkflowName [10]byte + ReportName [2]byte + WorkflowOwner common.Address + IsAllowed bool +} + type PriceRegistryDestChainConfig struct { IsEnabled bool MaxNumberOfTokensPerMsg uint16 @@ -146,8 +154,8 @@ type PriceRegistryTokenTransferFeeConfigSingleTokenArgs struct { } var PriceRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"validatePoolReturnData\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b5060405162006a4238038062006a4283398101604081905262000034916200188e565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a9f565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b6b565b5050505050505062001b4c565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db620019ad565b60209081029190910101519050620002f560028262000ea4565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb576000828281518110620003695762000369620019ad565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000ec4565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a25762000440838281518110620004275762000427620019ad565b6020026020010151600a62000ec460201b90919060201c565b1562000499578281815181106200045b576200045b620019ad565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c9620019ad565b6020026020010151600a62000edb60201b90919060201c565b156200053b57818181518110620004fd57620004fd620019ad565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d620019ad565b6020908102919091018101518051818301516001600160a01b0380831660008181526006875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e620019ad565b6020026020010151905060008383815181106200065f576200065f620019ad565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061018081015163ffffffff16155b80620006ba57506102008101516001600160e01b031916630a04b54b60e21b14155b80620006d75750602063ffffffff1681610160015163ffffffff16105b80620006f75750806060015163ffffffff1681610180015163ffffffff16115b15620007225760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260086020526040812060010154600160a81b900460e01b6001600160e01b0319169003620007a257816001600160401b03167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d1357782604051620007949190620019c3565b60405180910390a2620007e6565b816001600160401b03167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad9382604051620007dd9190620019c3565b60405180910390a25b8060086000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a8154816001600160401b0302191690836001600160401b031602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000ac35762000ac3620019ad565b6020026020010151600001519050600083838151811062000ae85762000ae8620019ad565b6020908102919091018101518101516001600160a01b03841660008181526007845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000aa2565b60005b825181101562000dde57600083828151811062000b8f5762000b8f620019ad565b6020026020010151905060008160000151905060005b82602001515181101562000dcf5760008360200151828151811062000bce5762000bce620019ad565b602002602001015160200151905060008460200151838151811062000bf75762000bf7620019ad565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c565760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b03841660008181526009602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000dbc908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000ba5565b50505080600101905062000b6e565b5060005b81518110156200054457600082828151811062000e035762000e03620019ad565b6020026020010151600001519050600083838151811062000e285762000e28620019ad565b6020908102919091018101518101516001600160401b03841660008181526009845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000de2565b600062000ebb836001600160a01b03841662000ef2565b90505b92915050565b600062000ebb836001600160a01b03841662000ff6565b600062000ebb836001600160a01b03841662001048565b6000818152600183016020526040812054801562000feb57600062000f1960018362001b14565b855490915060009062000f2f9060019062001b14565b905081811462000f9b57600086600001828154811062000f535762000f53620019ad565b906000526020600020015490508087600001848154811062000f795762000f79620019ad565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000faf5762000faf62001b36565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000ebe565b600091505062000ebe565b60008181526001830160205260408120546200103f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000ebe565b50600062000ebe565b6000818152600183016020526040812054801562000feb5760006200106f60018362001b14565b8554909150600090620010859060019062001b14565b905080821462000f9b57600086600001828154811062000f535762000f53620019ad565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620010e457620010e4620010a9565b60405290565b60405160c081016001600160401b0381118282101715620010e457620010e4620010a9565b60405161022081016001600160401b0381118282101715620010e457620010e4620010a9565b604051601f8201601f191681016001600160401b0381118282101715620011605762001160620010a9565b604052919050565b80516001600160a01b03811681146200118057600080fd5b919050565b805163ffffffff811681146200118057600080fd5b600060608284031215620011ad57600080fd5b604051606081016001600160401b0381118282101715620011d257620011d2620010a9565b604052825190915081906001600160601b0381168114620011f257600080fd5b8152620012026020840162001168565b6020820152620012156040840162001185565b60408201525092915050565b60006001600160401b038211156200123d576200123d620010a9565b5060051b60200190565b600082601f8301126200125957600080fd5b81516020620012726200126c8362001221565b62001135565b8083825260208201915060208460051b8701019350868411156200129557600080fd5b602086015b84811015620012bc57620012ae8162001168565b83529183019183016200129a565b509695505050505050565b600082601f830112620012d957600080fd5b81516020620012ec6200126c8362001221565b828152606092830285018201928282019190878511156200130c57600080fd5b8387015b858110156200139f57808903828112156200132b5760008081fd5b62001335620010bf565b620013408362001168565b8152604080601f1984011215620013575760008081fd5b62001361620010bf565b92506200137088850162001168565b835283015160ff81168114620013865760008081fd5b8288015280870191909152845292840192810162001310565b5090979650505050505050565b80516001600160401b03811681146200118057600080fd5b805161ffff811681146200118057600080fd5b805180151581146200118057600080fd5b600082601f830112620013fa57600080fd5b815160206200140d6200126c8362001221565b82815260059290921b840181019181810190868411156200142d57600080fd5b8286015b84811015620012bc5780516001600160401b03808211156200145257600080fd5b908801906040601f19838c0381018213156200146d57600080fd5b62001477620010bf565b62001484898601620013ac565b815282850151848111156200149857600080fd5b8086019550508c603f860112620014ae57600080fd5b888501519350620014c36200126c8562001221565b84815260e09094028501830193898101908e861115620014e257600080fd5b958401955b85871015620015bb57868f0360e08112156200150257600080fd5b6200150c620010bf565b620015178962001168565b815260c086830112156200152a57600080fd5b62001534620010ea565b9150620015438d8a0162001185565b825262001552878a0162001185565b8d8301526200156460608a01620013c4565b878301526200157660808a0162001185565b60608301526200158960a08a0162001185565b60808301526200159c60c08a01620013d7565b60a0830152808d0191909152825260e09690960195908a0190620014e7565b828b01525087525050509284019250830162001431565b600082601f830112620015e457600080fd5b81516020620015f76200126c8362001221565b82815260069290921b840181019181810190868411156200161757600080fd5b8286015b84811015620012bc5760408189031215620016365760008081fd5b62001640620010bf565b6200164b8262001168565b81526200165a858301620013ac565b818601528352918301916040016200161b565b80516001600160e01b0319811681146200118057600080fd5b600082601f8301126200169857600080fd5b81516020620016ab6200126c8362001221565b8281526102409283028501820192828201919087851115620016cc57600080fd5b8387015b858110156200139f5780890382811215620016eb5760008081fd5b620016f5620010bf565b6200170083620013ac565b815261022080601f1984011215620017185760008081fd5b620017226200110f565b925062001731888501620013d7565b8352604062001742818601620013c4565b8985015260606200175581870162001185565b82860152608091506200176a82870162001185565b9085015260a06200177d86820162001185565b8286015260c0915062001792828701620013c4565b9085015260e0620017a586820162001185565b828601526101009150620017bb828701620013c4565b90850152610120620017cf868201620013c4565b828601526101409150620017e5828701620013c4565b90850152610160620017f986820162001185565b8286015261018091506200180f82870162001185565b908501526101a06200182386820162001185565b828601526101c0915062001839828701620013ac565b908501526101e06200184d86820162001185565b82860152610200915062001863828701620013d7565b90850152620018748583016200166d565b9084015250808701919091528452928401928101620016d0565b6000806000806000806000610120888a031215620018ab57600080fd5b620018b789896200119a565b60608901519097506001600160401b0380821115620018d557600080fd5b620018e38b838c0162001247565b975060808a0151915080821115620018fa57600080fd5b620019088b838c0162001247565b965060a08a01519150808211156200191f57600080fd5b6200192d8b838c01620012c7565b955060c08a01519150808211156200194457600080fd5b620019528b838c01620013e8565b945060e08a01519150808211156200196957600080fd5b620019778b838c01620015d2565b93506101008a01519150808211156200198f57600080fd5b506200199e8a828b0162001686565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b81511515815261022081016020830151620019e4602084018261ffff169052565b506040830151620019fd604084018263ffffffff169052565b50606083015162001a16606084018263ffffffff169052565b50608083015162001a2f608084018263ffffffff169052565b5060a083015162001a4660a084018261ffff169052565b5060c083015162001a5f60c084018263ffffffff169052565b5060e083015162001a7660e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a0808501516001600160401b0316908401526101c080850151909116908301526101e080840151151590830152610200928301516001600160e01b031916929091019190915290565b8181038181111562000ebe57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051614e9c62001ba6600039600081816102d901528181611ad30152611b3c01526000818161029d0152818161104e01526110ae015260008181610269015281816110d701526111470152614e9c6000f3fe608060405234801561001057600080fd5b50600436106101b85760003560e01c80637afac322116100f9578063cc88924c11610097578063d8694ccd11610071578063d8694ccd14610a5c578063f2fde38b14610a6f578063f700042a14610a82578063ffdb4b3714610a9557600080fd5b8063cc88924c14610a2e578063cdc73d5114610a41578063d02641a014610a4957600080fd5b806391a2749a116100d357806391a2749a14610939578063a69c64c01461094c578063bf78e03f1461095f578063c4276bfc14610a0c57600080fd5b80637afac3221461078e57806382b49eb0146107a15780638da5cb5b1461091157600080fd5b8063407e108611610166578063514e8cff11610140578063514e8cff146104385780636def4ce7146104db578063770e2dc41461077357806379ba50971461078657600080fd5b8063407e1086146103c557806345ac924d146103d85780634ab35b0b146103f857600080fd5b8063181f5a7711610197578063181f5a77146103525780632451a6271461039b5780633937306f146103b057600080fd5b806241e5be146101bd578063061877e3146101e357806306285c691461023c575b600080fd5b6101d06101cb366004613889565b610add565b6040519081526020015b60405180910390f35b6102236101f13660046138c5565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101da565b610306604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101da565b61038e6040518060400160405280601781526020017f5072696365526567697374727920312e362e302d64657600000000000000000081525081565b6040516101da9190613944565b6103a3610b4b565b6040516101da9190613957565b6103c36103be3660046139b1565b610b5c565b005b6103c36103d3366004613b0d565b610e11565b6103eb6103e6366004613c6b565b610e25565b6040516101da9190613cad565b61040b6104063660046138c5565b610ef0565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6104ce610446366004613d40565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600460209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101da9190613d5b565b6107666104e9366004613d40565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081018290526102008101919091525067ffffffffffffffff908116600090815260086020908152604091829020825161022081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a0850152710100000000000000000000000000000000008304871660c08501527501000000000000000000000000000000000000000000808404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b010000000000000000000000000000000000000000000000000000009092048616610140840152600190930154808616610160840152640100000000810486166101808401526801000000000000000081049096166101a083015270010000000000000000000000000000000086049094166101c082015274010000000000000000000000000000000000000000850490911615156101e08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b1661020082015290565b6040516101da9190613d96565b6103c3610781366004613fd3565b610efb565b6103c3610f11565b6103c361079c3660046142ed565b611013565b6108b16107af366004614351565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff91909116600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101da9190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6103c361094736600461437b565b611025565b6103c361095a36600461440c565b611036565b6109d861096d3660046138c5565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526006825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101da565b610a1f610a1a3660046144d1565b611047565b6040516101da9392919061456c565b6103c3610a3c366004614596565b611245565b6103a361141b565b6104ce610a573660046138c5565b611427565b6101d0610a6a366004614631565b611523565b6103c3610a7d3660046138c5565b6119dd565b6103c3610a903660046146b6565b6119ee565b610aa8610aa33660046148d6565b6119ff565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101da565b6000610ae882611b8a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b0f85611b8a565b610b37907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168561492f565b610b419190614946565b90505b9392505050565b6060610b576002611c24565b905090565b610b64611c31565b6000610b708280614981565b9050905060005b81811015610cba576000610b8b8480614981565b83818110610b9b57610b9b6149e9565b905060400201803603810190610bb19190614a44565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a92610ca99290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610b77565b506000610cca6020840184614981565b9050905060005b81811015610e0b576000610ce86020860186614981565b83818110610cf857610cf86149e9565b905060400201803603810190610d0e9190614a81565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600490975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e92610dfa9290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610cd1565b50505050565b610e19611c76565b610e2281611cf7565b50565b60608160008167ffffffffffffffff811115610e4357610e436139ec565b604051908082528060200260200182016040528015610e8857816020015b6040805180820190915260008082526020820152815260200190600190039081610e615790505b50905060005b82811015610ee557610ec0868683818110610eab57610eab6149e9565b9050602002016020810190610a5791906138c5565b828281518110610ed257610ed26149e9565b6020908102919091010152600101610e8e565b509150505b92915050565b6000610eea82611b8a565b610f03611c76565b610f0d8282611df5565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61101b611c76565b610f0d8282612207565b61102d611c76565b610e228161234e565b61103e611c76565b610e22816124da565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036110a7578592506110d5565b6110d287877f0000000000000000000000000000000000000000000000000000000000000000610add565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611174576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610f8e565b67ffffffffffffffff8816600090815260086020526040812060010154640100000000900463ffffffff16906111ab8787846125c4565b9050806020015193508484611232836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b67ffffffffffffffff85166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b905b8481101561141257600084848381811061129c5761129c6149e9565b6112b292602060409092020190810191506138c5565b905060008787848181106112c8576112c86149e9565b90506020028101906112da9190614aa4565b6112e8906040810190614ae2565b91505060208111156113985767ffffffffffffffff8916600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115611398576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610f8e565b611408848989868181106113ae576113ae6149e9565b90506020028101906113c09190614aa4565b6113ce906020810190614ae2565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061276d92505050565b5050600101611280565b50505050505050565b6060610b57600a611c24565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600660209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff16908201529061151a57505073ffffffffffffffffffffffffffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b44816127bf565b67ffffffffffffffff8083166000908152600860209081526040808320815161022081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a0860152710100000000000000000000000000000000008404871660c08601527501000000000000000000000000000000000000000000808504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b010000000000000000000000000000000000000000000000000000009093048616610140850152600190940154808616610160850152640100000000810486166101808501526801000000000000000081049098166101a084015270010000000000000000000000000000000088049094166101c083015274010000000000000000000000000000000000000000870490931615156101e08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b16610200840152909190611759576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b60006117686040850185614981565b91506117c490508261177d6020870187614ae2565b90508361178a8880614ae2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a0292505050565b60006007816117d960808801606089016138c5565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff169150806118286118226080890160608a016138c5565b896119ff565b909250905060008080861561186e57611862888c61184c60808e0160608f016138c5565b888e806040019061185d9190614981565b612aac565b9194509250905061188e565b6101c088015161188b9063ffffffff16662386f26fc1000061492f565b92505b61010088015160009061ffff16156118d2576118cf896dffffffffffffffffffffffffffff607088901c166118c660208f018f614ae2565b90508b86612d8a565b90505b6101a089015160009067ffffffffffffffff166118fb6118f560808f018f614ae2565b8d612e3a565b600001518563ffffffff168c60a0015161ffff168f806020019061191f9190614ae2565b61192a92915061492f565b8d6080015163ffffffff1661193f9190614b47565b6119499190614b47565b6119539190614b47565b61196d906dffffffffffffffffffffffffffff891661492f565b611977919061492f565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff871682826119ae67ffffffffffffffff8c168961492f565b6119b89190614b47565b6119c29190614b47565b6119cc9190614946565b9d9c50505050505050505050505050565b6119e5611c76565b610e2281612efb565b6119f6611c76565b610e2281612ff0565b67ffffffffffffffff811660009081526004602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203611ab7576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610f8e565b6000816020015163ffffffff1642611acf9190614b5a565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115611b70576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610f8e565b611b7986611b8a565b9151919350909150505b9250929050565b600080611b9683611427565b9050806020015163ffffffff1660001480611bce575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15611c1d576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610f8e565b5192915050565b60606000610b44836134de565b611c3c60023361353a565b611c74576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610f8e565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314611c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610f8e565b60005b8151811015610f0d576000828281518110611d1757611d176149e9565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526006875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a2505050806001019050611cfa565b60005b825181101561211e576000838281518110611e1557611e156149e9565b6020026020010151905060008160000151905060005b82602001515181101561211057600083602001518281518110611e5057611e506149e9565b6020026020010151602001519050600084602001518381518110611e7657611e766149e9565b6020026020010151600001519050602063ffffffff16826080015163ffffffff161015611ef95760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610f8e565b67ffffffffffffffff8416600081815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906120fe908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101611e2b565b505050806001019050611df8565b5060005b815181101561220257600082828151811061213f5761213f6149e9565b60200260200101516000015190506000838381518110612161576121616149e9565b60209081029190910181015181015167ffffffffffffffff8416600081815260098452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612122565b505050565b60005b82518110156122aa57612240838281518110612228576122286149e9565b6020026020010151600a61356990919063ffffffff16565b156122a257828181518110612257576122576149e9565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010161220a565b5060005b8151811015612202576122e48282815181106122cc576122cc6149e9565b6020026020010151600a61358b90919063ffffffff16565b15612346578181815181106122fb576122fb6149e9565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6001016122ae565b602081015160005b81518110156123e9576000828281518110612373576123736149e9565b602002602001015190506123918160026135ad90919063ffffffff16565b156123e05760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612356565b50815160005b8151811015610e0b57600082828151811061240c5761240c6149e9565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361247c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612487600282613569565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016123ef565b60005b8151811015610f0d5760008282815181106124fa576124fa6149e9565b6020026020010151600001519050600083838151811061251c5761251c6149e9565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526007845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a250506001016124dd565b6040805180820190915260008082526020820152600083900361260557506040805180820190915267ffffffffffffffff8216815260006020820152610b44565b60006126118486614b6d565b905060006126228560048189614bb3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f000000000000000000000000000000000000000000000000000000000016126bf57808060200190518101906126b69190614bdd565b92505050610b44565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161273b576040518060400160405280828060200190518101906127279190614c09565b815260006020909101529250610b44915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610f0d57612202816135cf565b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284d9190614c3c565b505050915050600081121561288e576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000819050600085602001518473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129099190614c8c565b6129139190614ca9565b905060248160ff1611156129485761292c602482614cc2565b61293790600a614dfb565b6129419083614946565b915061296b565b612953816024614cc2565b61295e90600a614dfb565b612968908361492f565b91505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8211156129c1576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff42166020820152949350505050565b836040015163ffffffff16831115612a5b5760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610f8e565b836020015161ffff16821115612a9d576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e0b8461020001518261276d565b6000808083815b81811015612d7c576000878783818110612acf57612acf6149e9565b905060400201803603810190612ae59190614e0a565b67ffffffffffffffff8c166000908152600960209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090612c0b576101208d0151612bd29061ffff16662386f26fc1000061492f565b612bdc9088614b47565b96508c610140015186612bef9190614e43565b95508c610160015185612c029190614e43565b94505050612d74565b604081015160009061ffff1615612cc45760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614612c67578351612c6090611b8a565b9050612c6a565b508a5b620186a0836040015161ffff16612cac8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661368290919063ffffffff16565b612cb6919061492f565b612cc09190614946565b9150505b6060820151612cd39088614e43565b9650816080015186612ce59190614e43565b8251909650600090612d049063ffffffff16662386f26fc1000061492f565b905080821015612d2357612d18818a614b47565b985050505050612d74565b6000836020015163ffffffff16662386f26fc10000612d42919061492f565b905080831115612d6257612d56818b614b47565b99505050505050612d74565b612d6c838b614b47565b995050505050505b600101612ab3565b505096509650969350505050565b60008063ffffffff8316612da06101408661492f565b612dac876101c0614b47565b612db69190614b47565b612dc09190614b47565b905060008760c0015163ffffffff168860e0015161ffff1683612de3919061492f565b612ded9190614b47565b61010089015190915061ffff16612e146dffffffffffffffffffffffffffff89168361492f565b612e1e919061492f565b612e2e90655af3107a400061492f565b98975050505050505050565b60408051808201909152600080825260208201526000612e66858585610180015163ffffffff166125c4565b9050826060015163ffffffff1681600001511115612eb0576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101e001518015612ec457508060200151155b15610b41576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610f8e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b8151811015610f0d576000828281518110613010576130106149e9565b60200260200101519050600083838151811061302e5761302e6149e9565b60200260200101516000015190506000826020015190508167ffffffffffffffff1660001480613067575061018081015163ffffffff16155b806130b957506102008101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130d55750602063ffffffff1681610160015163ffffffff16105b806130f45750806060015163ffffffff1681610180015163ffffffff16115b15613137576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610f8e565b67ffffffffffffffff82166000908152600860205260408120600101547501000000000000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131df578167ffffffffffffffff167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577826040516131d29190613d96565b60405180910390a2613222565b8167ffffffffffffffff167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad93826040516132199190613d96565b60405180910390a25b80600860008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612ff3565b60608160000180548060200260200160405190810160405280929190818152602001828054801561352e57602002820191906000526020600020905b81548152602001906001019080831161351a575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b44565b6000610b448373ffffffffffffffffffffffffffffffffffffffff84166136bf565b6000610b448373ffffffffffffffffffffffffffffffffffffffff841661370e565b6000610b448373ffffffffffffffffffffffffffffffffffffffff8416613808565b6000815160201461360e57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e9190613944565b6000828060200190518101906136249190614c09565b905073ffffffffffffffffffffffffffffffffffffffff811180613649575061040081105b15610eea57826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610f8e9190613944565b6000670de0b6b3a76400006136b5837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff861661492f565b610b449190614946565b600081815260018301602052604081205461370657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610eea565b506000610eea565b600081815260018301602052604081205480156137f7576000613732600183614b5a565b855490915060009061374690600190614b5a565b90508082146137ab576000866000018281548110613766576137666149e9565b9060005260206000200154905080876000018481548110613789576137896149e9565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806137bc576137bc614e60565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610eea565b6000915050610eea565b5092915050565b600081815260018301602052604081205480156137f757600061382c600183614b5a565b855490915060009061384090600190614b5a565b90508181146137ab576000866000018281548110613766576137666149e9565b803573ffffffffffffffffffffffffffffffffffffffff8116811461388457600080fd5b919050565b60008060006060848603121561389e57600080fd5b6138a784613860565b9250602084013591506138bc60408501613860565b90509250925092565b6000602082840312156138d757600080fd5b610b4482613860565b6000815180845260005b81811015613906576020818501810151868301820152016138ea565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b4460208301846138e0565b6020808252825182820181905260009190848201906040850190845b818110156139a557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613973565b50909695505050505050565b6000602082840312156139c357600080fd5b813567ffffffffffffffff8111156139da57600080fd5b820160408185031215610b4457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613a3e57613a3e6139ec565b60405290565b60405160c0810167ffffffffffffffff81118282101715613a3e57613a3e6139ec565b604051610220810167ffffffffffffffff81118282101715613a3e57613a3e6139ec565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613ad257613ad26139ec565b604052919050565b600067ffffffffffffffff821115613af457613af46139ec565b5060051b60200190565b60ff81168114610e2257600080fd5b60006020808385031215613b2057600080fd5b823567ffffffffffffffff811115613b3757600080fd5b8301601f81018513613b4857600080fd5b8035613b5b613b5682613ada565b613a8b565b81815260609182028301840191848201919088841115613b7a57600080fd5b938501935b83851015613c1a5784890381811215613b985760008081fd5b613ba0613a1b565b613ba987613860565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084011215613bdd5760008081fd5b613be5613a1b565b9250613bf2898901613860565b8352870135613c0081613afe565b828901528088019190915283529384019391850191613b7f565b50979650505050505050565b60008083601f840112613c3857600080fd5b50813567ffffffffffffffff811115613c5057600080fd5b6020830191508360208260051b8501011115611b8357600080fd5b60008060208385031215613c7e57600080fd5b823567ffffffffffffffff811115613c9557600080fd5b613ca185828601613c26565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b82811015613d1b57613d0b84835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101613cca565b5091979650505050505050565b803567ffffffffffffffff8116811461388457600080fd5b600060208284031215613d5257600080fd5b610b4482613d28565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff169082015260408101610eea565b81511515815261022081016020830151613db6602084018261ffff169052565b506040830151613dce604084018263ffffffff169052565b506060830151613de6606084018263ffffffff169052565b506080830151613dfe608084018263ffffffff169052565b5060a0830151613e1460a084018261ffff169052565b5060c0830151613e2c60c084018263ffffffff169052565b5060e0830151613e4260e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a08085015167ffffffffffffffff16908401526101c080850151909116908301526101e080840151151590830152610200808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461388457600080fd5b803561ffff8116811461388457600080fd5b8015158114610e2257600080fd5b803561388481613f22565b600082601f830112613f4c57600080fd5b81356020613f5c613b5683613ada565b82815260069290921b84018101918181019086841115613f7b57600080fd5b8286015b84811015613fc85760408189031215613f985760008081fd5b613fa0613a1b565b613fa982613d28565b8152613fb6858301613860565b81860152835291830191604001613f7f565b509695505050505050565b60008060408385031215613fe657600080fd5b67ffffffffffffffff83351115613ffc57600080fd5b83601f84358501011261400e57600080fd5b61401e613b568435850135613ada565b8335840180358083526020808401939260059290921b9091010186101561404457600080fd5b602085358601015b85358601803560051b016020018110156142515767ffffffffffffffff8135111561407657600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a030112156140af57600080fd5b6140b7613a1b565b6140c360208301613d28565b815267ffffffffffffffff604083013511156140de57600080fd5b88603f6040840135840101126140f357600080fd5b614109613b566020604085013585010135613ada565b6020604084810135850182810135808552928401939260e00201018b101561413057600080fd5b6040808501358501015b6040858101358601602081013560e00201018110156142325760e0818d03121561416357600080fd5b61416b613a1b565b61417482613860565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f030112156141a857600080fd5b6141b0613a44565b6141bc60208401613efc565b81526141ca60408401613efc565b60208201526141db60608401613f10565b60408201526141ec60808401613efc565b60608201526141fd60a08401613efc565b608082015261420f60c0840135613f22565b60c083013560a0820152602082810191909152908452929092019160e00161413a565b508060208401525050808552505060208301925060208101905061404c565b5092505067ffffffffffffffff6020840135111561426e57600080fd5b61427e8460208501358501613f3b565b90509250929050565b600082601f83011261429857600080fd5b813560206142a8613b5683613ada565b8083825260208201915060208460051b8701019350868411156142ca57600080fd5b602086015b84811015613fc8576142e081613860565b83529183019183016142cf565b6000806040838503121561430057600080fd5b823567ffffffffffffffff8082111561431857600080fd5b61432486838701614287565b9350602085013591508082111561433a57600080fd5b5061434785828601614287565b9150509250929050565b6000806040838503121561436457600080fd5b61436d83613d28565b915061427e60208401613860565b60006020828403121561438d57600080fd5b813567ffffffffffffffff808211156143a557600080fd5b90830190604082860312156143b957600080fd5b6143c1613a1b565b8235828111156143d057600080fd5b6143dc87828601614287565b8252506020830135828111156143f157600080fd5b6143fd87828601614287565b60208301525095945050505050565b6000602080838503121561441f57600080fd5b823567ffffffffffffffff81111561443657600080fd5b8301601f8101851361444757600080fd5b8035614455613b5682613ada565b81815260069190911b8201830190838101908783111561447457600080fd5b928401925b828410156144c657604084890312156144925760008081fd5b61449a613a1b565b6144a385613860565b81526144b0868601613d28565b8187015282526040939093019290840190614479565b979650505050505050565b6000806000806000608086880312156144e957600080fd5b6144f286613d28565b945061450060208701613860565b935060408601359250606086013567ffffffffffffffff8082111561452457600080fd5b818801915088601f83011261453857600080fd5b81358181111561454757600080fd5b89602082850101111561455957600080fd5b9699959850939650602001949392505050565b838152821515602082015260606040820152600061458d60608301846138e0565b95945050505050565b6000806000806000606086880312156145ae57600080fd5b6145b786613d28565b9450602086013567ffffffffffffffff808211156145d457600080fd5b6145e089838a01613c26565b909650945060408801359150808211156145f957600080fd5b818801915088601f83011261460d57600080fd5b81358181111561461c57600080fd5b8960208260061b850101111561455957600080fd5b6000806040838503121561464457600080fd5b61464d83613d28565b9150602083013567ffffffffffffffff81111561466957600080fd5b830160a0818603121561467b57600080fd5b809150509250929050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461388457600080fd5b600060208083850312156146c957600080fd5b823567ffffffffffffffff8111156146e057600080fd5b8301601f810185136146f157600080fd5b80356146ff613b5682613ada565b818152610240918202830184019184820191908884111561471f57600080fd5b938501935b83851015613c1a578489038181121561473d5760008081fd5b614745613a1b565b61474e87613d28565b8152610220807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147835760008081fd5b61478b613a67565b9250614798898901613f30565b835260406147a7818a01613f10565b8a85015260606147b8818b01613efc565b82860152608091506147cb828b01613efc565b9085015260a06147dc8a8201613efc565b8286015260c091506147ef828b01613f10565b9085015260e06148008a8201613efc565b828601526101009150614814828b01613f10565b908501526101206148268a8201613f10565b82860152610140915061483a828b01613f10565b9085015261016061484c8a8201613efc565b828601526101809150614860828b01613efc565b908501526101a06148728a8201613efc565b828601526101c09150614886828b01613d28565b908501526101e06148988a8201613efc565b8286015261020091506148ac828b01613f30565b908501526148bb898301614686565b90840152508088019190915283529384019391850191614724565b600080604083850312156148e957600080fd5b6148f283613860565b915061427e60208401613d28565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610eea57610eea614900565b60008261497c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126149b657600080fd5b83018035915067ffffffffffffffff8211156149d157600080fd5b6020019150600681901b3603821315611b8357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461388457600080fd5b600060408284031215614a5657600080fd5b614a5e613a1b565b614a6783613860565b8152614a7560208401614a18565b60208201529392505050565b600060408284031215614a9357600080fd5b614a9b613a1b565b614a6783613d28565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112614ad857600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614b1757600080fd5b83018035915067ffffffffffffffff821115614b3257600080fd5b602001915036819003821315611b8357600080fd5b80820180821115610eea57610eea614900565b81810381811115610eea57610eea614900565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015613ef45760049490940360031b84901b1690921692915050565b60008085851115614bc357600080fd5b83861115614bd057600080fd5b5050820193919092039150565b600060408284031215614bef57600080fd5b614bf7613a1b565b825181526020830151614a7581613f22565b600060208284031215614c1b57600080fd5b5051919050565b805169ffffffffffffffffffff8116811461388457600080fd5b600080600080600060a08688031215614c5457600080fd5b614c5d86614c22565b9450602086015193506040860151925060608601519150614c8060808701614c22565b90509295509295909350565b600060208284031215614c9e57600080fd5b8151610b4481613afe565b60ff8181168382160190811115610eea57610eea614900565b60ff8281168282160390811115610eea57610eea614900565b600181815b80851115614d3457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614d1a57614d1a614900565b80851615614d2757918102915b93841c9390800290614ce0565b509250929050565b600082614d4b57506001610eea565b81614d5857506000610eea565b8160018114614d6e5760028114614d7857614d94565b6001915050610eea565b60ff841115614d8957614d89614900565b50506001821b610eea565b5060208310610133831016604e8410600b8410161715614db7575081810a610eea565b614dc18383614cdb565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614df357614df3614900565b029392505050565b6000610b4460ff841683614d3c565b600060408284031215614e1c57600080fd5b614e24613a1b565b614e2d83613860565b8152602083013560208201528091505092915050565b63ffffffff81811683821601908082111561380157613801614900565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"}],\"name\":\"ReportForwarderUnauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feedTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"storedTimeStamp\",\"type\":\"uint256\"}],\"name\":\"StaleKeystoneUpdate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"reportId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission\",\"name\":\"permission\",\"type\":\"tuple\"}],\"name\":\"ReportPermissionSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission[]\",\"name\":\"permissions\",\"type\":\"tuple[]\"}],\"name\":\"setReportPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"validatePoolReturnData\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b50604051620075cf380380620075cf83398101604081905262000034916200188e565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a9f565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b6b565b5050505050505062001b4c565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db620019ad565b60209081029190910101519050620002f560028262000ea4565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb576000828281518110620003695762000369620019ad565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000ec4565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a25762000440838281518110620004275762000427620019ad565b6020026020010151600b62000ec460201b90919060201c565b1562000499578281815181106200045b576200045b620019ad565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c9620019ad565b6020026020010151600b62000edb60201b90919060201c565b156200053b57818181518110620004fd57620004fd620019ad565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d620019ad565b6020908102919091018101518051818301516001600160a01b0380831660008181526007875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e620019ad565b6020026020010151905060008383815181106200065f576200065f620019ad565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061018081015163ffffffff16155b80620006ba57506102008101516001600160e01b031916630a04b54b60e21b14155b80620006d75750602063ffffffff1681610160015163ffffffff16105b80620006f75750806060015163ffffffff1681610180015163ffffffff16115b15620007225760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260096020526040812060010154600160a81b900460e01b6001600160e01b0319169003620007a257816001600160401b03167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d1357782604051620007949190620019c3565b60405180910390a2620007e6565b816001600160401b03167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad9382604051620007dd9190620019c3565b60405180910390a25b8060096000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a8154816001600160401b0302191690836001600160401b031602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000ac35762000ac3620019ad565b6020026020010151600001519050600083838151811062000ae85762000ae8620019ad565b6020908102919091018101518101516001600160a01b03841660008181526008845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000aa2565b60005b825181101562000dde57600083828151811062000b8f5762000b8f620019ad565b6020026020010151905060008160000151905060005b82602001515181101562000dcf5760008360200151828151811062000bce5762000bce620019ad565b602002602001015160200151905060008460200151838151811062000bf75762000bf7620019ad565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c565760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000dbc908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000ba5565b50505080600101905062000b6e565b5060005b81518110156200054457600082828151811062000e035762000e03620019ad565b6020026020010151600001519050600083838151811062000e285762000e28620019ad565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000de2565b600062000ebb836001600160a01b03841662000ef2565b90505b92915050565b600062000ebb836001600160a01b03841662000ff6565b600062000ebb836001600160a01b03841662001048565b6000818152600183016020526040812054801562000feb57600062000f1960018362001b14565b855490915060009062000f2f9060019062001b14565b905081811462000f9b57600086600001828154811062000f535762000f53620019ad565b906000526020600020015490508087600001848154811062000f795762000f79620019ad565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000faf5762000faf62001b36565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000ebe565b600091505062000ebe565b60008181526001830160205260408120546200103f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000ebe565b50600062000ebe565b6000818152600183016020526040812054801562000feb5760006200106f60018362001b14565b8554909150600090620010859060019062001b14565b905080821462000f9b57600086600001828154811062000f535762000f53620019ad565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620010e457620010e4620010a9565b60405290565b60405160c081016001600160401b0381118282101715620010e457620010e4620010a9565b60405161022081016001600160401b0381118282101715620010e457620010e4620010a9565b604051601f8201601f191681016001600160401b0381118282101715620011605762001160620010a9565b604052919050565b80516001600160a01b03811681146200118057600080fd5b919050565b805163ffffffff811681146200118057600080fd5b600060608284031215620011ad57600080fd5b604051606081016001600160401b0381118282101715620011d257620011d2620010a9565b604052825190915081906001600160601b0381168114620011f257600080fd5b8152620012026020840162001168565b6020820152620012156040840162001185565b60408201525092915050565b60006001600160401b038211156200123d576200123d620010a9565b5060051b60200190565b600082601f8301126200125957600080fd5b81516020620012726200126c8362001221565b62001135565b8083825260208201915060208460051b8701019350868411156200129557600080fd5b602086015b84811015620012bc57620012ae8162001168565b83529183019183016200129a565b509695505050505050565b600082601f830112620012d957600080fd5b81516020620012ec6200126c8362001221565b828152606092830285018201928282019190878511156200130c57600080fd5b8387015b858110156200139f57808903828112156200132b5760008081fd5b62001335620010bf565b620013408362001168565b8152604080601f1984011215620013575760008081fd5b62001361620010bf565b92506200137088850162001168565b835283015160ff81168114620013865760008081fd5b8288015280870191909152845292840192810162001310565b5090979650505050505050565b80516001600160401b03811681146200118057600080fd5b805161ffff811681146200118057600080fd5b805180151581146200118057600080fd5b600082601f830112620013fa57600080fd5b815160206200140d6200126c8362001221565b82815260059290921b840181019181810190868411156200142d57600080fd5b8286015b84811015620012bc5780516001600160401b03808211156200145257600080fd5b908801906040601f19838c0381018213156200146d57600080fd5b62001477620010bf565b62001484898601620013ac565b815282850151848111156200149857600080fd5b8086019550508c603f860112620014ae57600080fd5b888501519350620014c36200126c8562001221565b84815260e09094028501830193898101908e861115620014e257600080fd5b958401955b85871015620015bb57868f0360e08112156200150257600080fd5b6200150c620010bf565b620015178962001168565b815260c086830112156200152a57600080fd5b62001534620010ea565b9150620015438d8a0162001185565b825262001552878a0162001185565b8d8301526200156460608a01620013c4565b878301526200157660808a0162001185565b60608301526200158960a08a0162001185565b60808301526200159c60c08a01620013d7565b60a0830152808d0191909152825260e09690960195908a0190620014e7565b828b01525087525050509284019250830162001431565b600082601f830112620015e457600080fd5b81516020620015f76200126c8362001221565b82815260069290921b840181019181810190868411156200161757600080fd5b8286015b84811015620012bc5760408189031215620016365760008081fd5b62001640620010bf565b6200164b8262001168565b81526200165a858301620013ac565b818601528352918301916040016200161b565b80516001600160e01b0319811681146200118057600080fd5b600082601f8301126200169857600080fd5b81516020620016ab6200126c8362001221565b8281526102409283028501820192828201919087851115620016cc57600080fd5b8387015b858110156200139f5780890382811215620016eb5760008081fd5b620016f5620010bf565b6200170083620013ac565b815261022080601f1984011215620017185760008081fd5b620017226200110f565b925062001731888501620013d7565b8352604062001742818601620013c4565b8985015260606200175581870162001185565b82860152608091506200176a82870162001185565b9085015260a06200177d86820162001185565b8286015260c0915062001792828701620013c4565b9085015260e0620017a586820162001185565b828601526101009150620017bb828701620013c4565b90850152610120620017cf868201620013c4565b828601526101409150620017e5828701620013c4565b90850152610160620017f986820162001185565b8286015261018091506200180f82870162001185565b908501526101a06200182386820162001185565b828601526101c0915062001839828701620013ac565b908501526101e06200184d86820162001185565b82860152610200915062001863828701620013d7565b90850152620018748583016200166d565b9084015250808701919091528452928401928101620016d0565b6000806000806000806000610120888a031215620018ab57600080fd5b620018b789896200119a565b60608901519097506001600160401b0380821115620018d557600080fd5b620018e38b838c0162001247565b975060808a0151915080821115620018fa57600080fd5b620019088b838c0162001247565b965060a08a01519150808211156200191f57600080fd5b6200192d8b838c01620012c7565b955060c08a01519150808211156200194457600080fd5b620019528b838c01620013e8565b945060e08a01519150808211156200196957600080fd5b620019778b838c01620015d2565b93506101008a01519150808211156200198f57600080fd5b506200199e8a828b0162001686565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b81511515815261022081016020830151620019e4602084018261ffff169052565b506040830151620019fd604084018263ffffffff169052565b50606083015162001a16606084018263ffffffff169052565b50608083015162001a2f608084018263ffffffff169052565b5060a083015162001a4660a084018261ffff169052565b5060c083015162001a5f60c084018263ffffffff169052565b5060e083015162001a7660e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a0808501516001600160401b0316908401526101c080850151909116908301526101e080840151151590830152610200928301516001600160e01b031916929091019190915290565b8181038181111562000ebe57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051615a2962001ba6600039600081816102ef01528181612035015261209e0152600081816102b3015281816115b0015261161001526000818161027f0152818161163901526116a90152615a296000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c80637afac32211610104578063c4276bfc116100a2578063d8694ccd11610071578063d8694ccd14610a98578063f2fde38b14610aab578063f700042a14610abe578063ffdb4b3714610ad157600080fd5b8063c4276bfc14610a48578063cc88924c14610a6a578063cdc73d5114610a7d578063d02641a014610a8557600080fd5b80638da5cb5b116100de5780638da5cb5b1461094d57806391a2749a14610975578063a69c64c014610988578063bf78e03f1461099b57600080fd5b80637afac322146107b7578063805f2132146107ca57806382b49eb0146107dd57600080fd5b806341ed29e711610171578063514e8cff1161014b578063514e8cff146104615780636def4ce714610504578063770e2dc41461079c57806379ba5097146107af57600080fd5b806341ed29e7146103ee57806345ac924d146104015780634ab35b0b1461042157600080fd5b8063181f5a77116101ad578063181f5a77146103685780632451a627146103b15780633937306f146103c6578063407e1086146103db57600080fd5b806241e5be146101d3578063061877e3146101f957806306285c6914610252575b600080fd5b6101e66101e1366004614142565b610b19565b6040519081526020015b60405180910390f35b61023961020736600461417e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101f0565b61031c604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101f0565b6103a46040518060400160405280601781526020017f5072696365526567697374727920312e362e302d64657600000000000000000081525081565b6040516101f091906141fd565b6103b9610b87565b6040516101f09190614210565b6103d96103d436600461426a565b610b98565b005b6103d96103e936600461440c565b610e4d565b6103d96103fc36600461453e565b610e61565b61041461040f3660046146be565b610ea3565b6040516101f09190614700565b61043461042f36600461417e565b610f6e565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6104f761046f366004614793565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101f091906147ae565b61078f610512366004614793565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081018290526102008101919091525067ffffffffffffffff908116600090815260096020908152604091829020825161022081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a0850152710100000000000000000000000000000000008304871660c08501527501000000000000000000000000000000000000000000808404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b010000000000000000000000000000000000000000000000000000009092048616610140840152600190930154808616610160840152640100000000810486166101808401526801000000000000000081049096166101a083015270010000000000000000000000000000000086049094166101c082015274010000000000000000000000000000000000000000850490911615156101e08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b1661020082015290565b6040516101f091906147e9565b6103d96107aa366004614a0d565b610f79565b6103d9610f8b565b6103d96107c5366004614d27565b61108d565b6103d96107d8366004614dcd565b61109f565b6108ed6107eb366004614e39565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff919091166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101f09190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6103d9610983366004614e63565b611587565b6103d9610996366004614ef4565b611598565b610a146109a936600461417e565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526007825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101f0565b610a5b610a56366004614fb9565b6115a9565b6040516101f093929190615028565b6103d9610a78366004615049565b6117a7565b6103b961197d565b6104f7610a9336600461417e565b611989565b6101e6610aa63660046150f7565b611a85565b6103d9610ab936600461417e565b611f3f565b6103d9610acc36600461517c565b611f50565b610ae4610adf36600461539c565b611f61565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101f0565b6000610b24826120ec565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b4b856120ec565b610b73907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16856153f5565b610b7d919061540c565b90505b9392505050565b6060610b936002612186565b905090565b610ba0612193565b6000610bac8280615447565b9050905060005b81811015610cf6576000610bc78480615447565b83818110610bd757610bd76154af565b905060400201803603810190610bed919061550a565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600690975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a92610ce59290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610bb3565b506000610d066020840184615447565b9050905060005b81811015610e47576000610d246020860186615447565b83818110610d3457610d346154af565b905060400201803603810190610d4a9190615547565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e92610e369290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610d0d565b50505050565b610e556121d8565b610e5e81612259565b50565b610e696121d8565b60005b8151811015610e9f57610e97828281518110610e8a57610e8a6154af565b6020026020010151612357565b600101610e6c565b5050565b60608160008167ffffffffffffffff811115610ec157610ec16142a5565b604051908082528060200260200182016040528015610f0657816020015b6040805180820190915260008082526020820152815260200190600190039081610edf5790505b50905060005b82811015610f6357610f3e868683818110610f2957610f296154af565b9050602002016020810190610a93919061417e565b828281518110610f5057610f506154af565b6020908102919091010152600101610f0c565b509150505b92915050565b6000610f68826120ec565b610f816121d8565b610e9f8282612529565b60015473ffffffffffffffffffffffffffffffffffffffff163314611011576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6110956121d8565b610e9f828261293b565b60008060006110e387878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a8292505050565b9250925092506110f533838584612a9d565b60006111038587018761556a565b905060005b815181101561157c57600060076000848481518110611129576111296154af565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160009081205474010000000000000000000000000000000000000000900460ff1691508190036111ea57828281518110611193576111936154af565b6020908102919091010151516040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401611008565b6000611233601283868681518110611204576112046154af565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612bf5565b90506006600085858151811061124b5761124b6154af565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff168484815181106112bd576112bd6154af565b60200260200101516040015163ffffffff1610156113c7578383815181106112e7576112e76154af565b602002602001015160000151848481518110611305576113056154af565b60200260200101516040015160066000878781518110611327576113276154af565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260409081016000205490517f191ec70600000000000000000000000000000000000000000000000000000000815293909116600484015263ffffffff91821660248401527c01000000000000000000000000000000000000000000000000000000009004166044820152606401611008565b6040518060400160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152602001858581518110611408576114086154af565b60200260200101516040015163ffffffff1681525060066000868681518110611433576114336154af565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117905583518490849081106114cb576114cb6154af565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff167f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a82868681518110611521576115216154af565b60200260200101516040015160405161156a9291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a25050600101611108565b505050505050505050565b61158f6121d8565b610e5e81612cbb565b6115a06121d8565b610e5e81612e47565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff160361160957859250611637565b61163487877f0000000000000000000000000000000000000000000000000000000000000000610b19565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff168311156116d6576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401611008565b67ffffffffffffffff8816600090815260096020526040812060010154640100000000900463ffffffff169061170d878784612f31565b9050806020015193508484611794836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b67ffffffffffffffff85166000908152600960205260408120600101547501000000000000000000000000000000000000000000900460e01b905b848110156119745760008484838181106117fe576117fe6154af565b611814926020604090920201908101915061417e565b9050600087878481811061182a5761182a6154af565b905060200281019061183c9190615631565b61184a90604081019061566f565b91505060208111156118fa5767ffffffffffffffff89166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff168111156118fa576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401611008565b61196a84898986818110611910576119106154af565b90506020028101906119229190615631565b61193090602081019061566f565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506130da92505050565b50506001016117e2565b50505050505050565b6060610b93600b612186565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600760209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff169082015290611a7c57505073ffffffffffffffffffffffffffffffffffffffff166000908152600660209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b808161312c565b67ffffffffffffffff8083166000908152600960209081526040808320815161022081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a0860152710100000000000000000000000000000000008404871660c08601527501000000000000000000000000000000000000000000808504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b010000000000000000000000000000000000000000000000000000009093048616610140850152600190940154808616610160850152640100000000810486166101808501526801000000000000000081049098166101a084015270010000000000000000000000000000000088049094166101c083015274010000000000000000000000000000000000000000870490931615156101e08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b16610200840152909190611cbb576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401611008565b6000611cca6040850185615447565b9150611d26905082611cdf602087018761566f565b905083611cec888061566f565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506132bb92505050565b6000600881611d3b608088016060890161417e565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff16915080611d8a611d846080890160608a0161417e565b89611f61565b9092509050600080808615611dd057611dc4888c611dae60808e0160608f0161417e565b888e8060400190611dbf9190615447565b613365565b91945092509050611df0565b6101c0880151611ded9063ffffffff16662386f26fc100006153f5565b92505b61010088015160009061ffff1615611e3457611e31896dffffffffffffffffffffffffffff607088901c16611e2860208f018f61566f565b90508b86613643565b90505b6101a089015160009067ffffffffffffffff16611e5d611e5760808f018f61566f565b8d6136f3565b600001518563ffffffff168c60a0015161ffff168f8060200190611e81919061566f565b611e8c9291506153f5565b8d6080015163ffffffff16611ea191906156d4565b611eab91906156d4565b611eb591906156d4565b611ecf906dffffffffffffffffffffffffffff89166153f5565b611ed991906153f5565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff87168282611f1067ffffffffffffffff8c16896153f5565b611f1a91906156d4565b611f2491906156d4565b611f2e919061540c565b9d9c50505050505050505050505050565b611f476121d8565b610e5e816137b4565b611f586121d8565b610e5e816138a9565b67ffffffffffffffff811660009081526005602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203612019576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401611008565b6000816020015163ffffffff164261203191906156e7565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168111156120d2576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401611008565b6120db866120ec565b9151919350909150505b9250929050565b6000806120f883611989565b9050806020015163ffffffff1660001480612130575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b1561217f576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401611008565b5192915050565b60606000610b8083613d97565b61219e600233613df3565b6121d6576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401611008565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146121d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611008565b60005b8151811015610e9f576000828281518110612279576122796154af565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526007875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a250505080600101905061225c565b600061241082600001518360600151846020015185604001516040805173ffffffffffffffffffffffffffffffffffffffff80871660208301528516918101919091527fffffffffffffffffffff00000000000000000000000000000000000000000000831660608201527fffff0000000000000000000000000000000000000000000000000000000000008216608082015260009060a001604051602081830303815290604052805190602001209050949350505050565b60808301516000828152600460205260409081902080549215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316929092179091555190915081907f32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a39061251d908590600060a08201905073ffffffffffffffffffffffffffffffffffffffff8084511683527fffffffffffffffffffff0000000000000000000000000000000000000000000060208501511660208401527fffff00000000000000000000000000000000000000000000000000000000000060408501511660408401528060608501511660608401525060808301511515608083015292915050565b60405180910390a25050565b60005b8251811015612852576000838281518110612549576125496154af565b6020026020010151905060008160000151905060005b82602001515181101561284457600083602001518281518110612584576125846154af565b60200260200101516020015190506000846020015183815181106125aa576125aa6154af565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101561262d5760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401611008565b67ffffffffffffffff84166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b590612832908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010161255f565b50505080600101905061252c565b5060005b8151811015612936576000828281518110612873576128736154af565b60200260200101516000015190506000838381518110612895576128956154af565b60209081029190910181015181015167ffffffffffffffff84166000818152600a8452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612856565b505050565b60005b82518110156129de5761297483828151811061295c5761295c6154af565b6020026020010151600b613e2290919063ffffffff16565b156129d65782818151811061298b5761298b6154af565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010161293e565b5060005b815181101561293657612a18828281518110612a0057612a006154af565b6020026020010151600b613e4490919063ffffffff16565b15612a7a57818181518110612a2f57612a2f6154af565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6001016129e2565b6040810151604a820151605e90920151909260609290921c91565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602080840191909152908616828401527fffffffffffffffffffff00000000000000000000000000000000000000000000851660608301527fffff00000000000000000000000000000000000000000000000000000000000084166080808401919091528351808403909101815260a09092018352815191810191909120600081815260049092529190205460ff16612bee576040517f097e17ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8087166004830152851660248201527fffffffffffffffffffff00000000000000000000000000000000000000000000841660448201527fffff00000000000000000000000000000000000000000000000000000000000083166064820152608401611008565b5050505050565b600080612c0284866156fa565b9050600060248260ff161115612c3957612c1d602483615713565b612c2890600a61584c565b612c32908561540c565b9050612c5c565b612c44826024615713565b612c4f90600a61584c565b612c5990856153f5565b90505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612cb2576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b95945050505050565b602081015160005b8151811015612d56576000828281518110612ce057612ce06154af565b60200260200101519050612cfe816002613e6690919063ffffffff16565b15612d4d5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612cc3565b50815160005b8151811015610e47576000828281518110612d7957612d796154af565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612de9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612df4600282613e22565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101612d5c565b60005b8151811015610e9f576000828281518110612e6757612e676154af565b60200260200101516000015190506000838381518110612e8957612e896154af565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526008845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a25050600101612e4a565b60408051808201909152600080825260208201526000839003612f7257506040805180820190915267ffffffffffffffff8216815260006020820152610b80565b6000612f7e848661585b565b90506000612f8f85600481896158a1565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f0000000000000000000000000000000000000000000000000000000000161302c578080602001905181019061302391906158cb565b92505050610b80565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016130a85760405180604001604052808280602001905181019061309491906158f7565b815260006020909101529250610b80915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610e9f5761293681613e88565b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613196573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131ba919061592a565b50505091505060008112156131fb576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061327a8373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561324b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061326f919061597a565b866020015184612bf5565b604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff4216602082015295945050505050565b836040015163ffffffff168311156133145760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401611008565b836020015161ffff16821115613356576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e47846102000151826130da565b6000808083815b81811015613635576000878783818110613388576133886154af565b90506040020180360381019061339e9190615997565b67ffffffffffffffff8c166000908152600a60209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a08201819052919250906134c4576101208d015161348b9061ffff16662386f26fc100006153f5565b61349590886156d4565b96508c6101400151866134a891906159d0565b95508c6101600151856134bb91906159d0565b9450505061362d565b604081015160009061ffff161561357d5760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614613520578351613519906120ec565b9050613523565b508a5b620186a0836040015161ffff166135658660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16613f3b90919063ffffffff16565b61356f91906153f5565b613579919061540c565b9150505b606082015161358c90886159d0565b965081608001518661359e91906159d0565b82519096506000906135bd9063ffffffff16662386f26fc100006153f5565b9050808210156135dc576135d1818a6156d4565b98505050505061362d565b6000836020015163ffffffff16662386f26fc100006135fb91906153f5565b90508083111561361b5761360f818b6156d4565b9950505050505061362d565b613625838b6156d4565b995050505050505b60010161336c565b505096509650969350505050565b60008063ffffffff8316613659610140866153f5565b613665876101c06156d4565b61366f91906156d4565b61367991906156d4565b905060008760c0015163ffffffff168860e0015161ffff168361369c91906153f5565b6136a691906156d4565b61010089015190915061ffff166136cd6dffffffffffffffffffffffffffff8916836153f5565b6136d791906153f5565b6136e790655af3107a40006153f5565b98975050505050505050565b6040805180820190915260008082526020820152600061371f858585610180015163ffffffff16612f31565b9050826060015163ffffffff1681600001511115613769576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101e00151801561377d57508060200151155b15610b7d576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603613833576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611008565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b8151811015610e9f5760008282815181106138c9576138c96154af565b6020026020010151905060008383815181106138e7576138e76154af565b60200260200101516000015190506000826020015190508167ffffffffffffffff1660001480613920575061018081015163ffffffff16155b8061397257506102008101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b8061398e5750602063ffffffff1681610160015163ffffffff16105b806139ad5750806060015163ffffffff1681610180015163ffffffff16115b156139f0576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401611008565b67ffffffffffffffff82166000908152600960205260408120600101547501000000000000000000000000000000000000000000900460e01b7fffffffff00000000000000000000000000000000000000000000000000000000169003613a98578167ffffffffffffffff167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d1357782604051613a8b91906147e9565b60405180910390a2613adb565b8167ffffffffffffffff167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad9382604051613ad291906147e9565b60405180910390a25b80600960008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506138ac565b606081600001805480602002602001604051908101604052809291908181526020018280548015613de757602002820191906000526020600020905b815481526020019060010190808311613dd3575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b80565b6000610b808373ffffffffffffffffffffffffffffffffffffffff8416613f78565b6000610b808373ffffffffffffffffffffffffffffffffffffffff8416613fc7565b6000610b808373ffffffffffffffffffffffffffffffffffffffff84166140c1565b60008151602014613ec757816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161100891906141fd565b600082806020019051810190613edd91906158f7565b905073ffffffffffffffffffffffffffffffffffffffff811180613f02575061040081105b15610f6857826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161100891906141fd565b6000670de0b6b3a7640000613f6e837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166153f5565b610b80919061540c565b6000818152600183016020526040812054613fbf57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610f68565b506000610f68565b600081815260018301602052604081205480156140b0576000613feb6001836156e7565b8554909150600090613fff906001906156e7565b905080821461406457600086600001828154811061401f5761401f6154af565b9060005260206000200154905080876000018481548110614042576140426154af565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614075576140756159ed565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610f68565b6000915050610f68565b5092915050565b600081815260018301602052604081205480156140b05760006140e56001836156e7565b85549091506000906140f9906001906156e7565b905081811461406457600086600001828154811061401f5761401f6154af565b803573ffffffffffffffffffffffffffffffffffffffff8116811461413d57600080fd5b919050565b60008060006060848603121561415757600080fd5b61416084614119565b92506020840135915061417560408501614119565b90509250925092565b60006020828403121561419057600080fd5b610b8082614119565b6000815180845260005b818110156141bf576020818501810151868301820152016141a3565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b806020830184614199565b6020808252825182820181905260009190848201906040850190845b8181101561425e57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161422c565b50909695505050505050565b60006020828403121561427c57600080fd5b813567ffffffffffffffff81111561429357600080fd5b820160408185031215610b8057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156142f7576142f76142a5565b60405290565b60405160a0810167ffffffffffffffff811182821017156142f7576142f76142a5565b60405160c0810167ffffffffffffffff811182821017156142f7576142f76142a5565b604051610220810167ffffffffffffffff811182821017156142f7576142f76142a5565b6040516060810167ffffffffffffffff811182821017156142f7576142f76142a5565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156143d1576143d16142a5565b604052919050565b600067ffffffffffffffff8211156143f3576143f36142a5565b5060051b60200190565b60ff81168114610e5e57600080fd5b6000602080838503121561441f57600080fd5b823567ffffffffffffffff81111561443657600080fd5b8301601f8101851361444757600080fd5b803561445a614455826143d9565b61438a565b8181526060918202830184019184820191908884111561447957600080fd5b938501935b8385101561451957848903818112156144975760008081fd5b61449f6142d4565b6144a887614119565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156144dc5760008081fd5b6144e46142d4565b92506144f1898901614119565b83528701356144ff816143fd565b82890152808801919091528352938401939185019161447e565b50979650505050505050565b8015158114610e5e57600080fd5b803561413d81614525565b6000602080838503121561455157600080fd5b823567ffffffffffffffff81111561456857600080fd5b8301601f8101851361457957600080fd5b8035614587614455826143d9565b81815260a091820283018401918482019190888411156145a657600080fd5b938501935b838510156145195780858a0312156145c35760008081fd5b6145cb6142fd565b6145d486614119565b8152868601357fffffffffffffffffffff00000000000000000000000000000000000000000000811681146146095760008081fd5b818801526040868101357fffff000000000000000000000000000000000000000000000000000000000000811681146146425760008081fd5b908201526060614653878201614119565b9082015260808681013561466681614525565b90820152835293840193918501916145ab565b60008083601f84011261468b57600080fd5b50813567ffffffffffffffff8111156146a357600080fd5b6020830191508360208260051b85010111156120e557600080fd5b600080602083850312156146d157600080fd5b823567ffffffffffffffff8111156146e857600080fd5b6146f485828601614679565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b8281101561476e5761475e84835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b928401929085019060010161471d565b5091979650505050505050565b803567ffffffffffffffff8116811461413d57600080fd5b6000602082840312156147a557600080fd5b610b808261477b565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff169082015260408101610f68565b81511515815261022081016020830151614809602084018261ffff169052565b506040830151614821604084018263ffffffff169052565b506060830151614839606084018263ffffffff169052565b506080830151614851608084018263ffffffff169052565b5060a083015161486760a084018261ffff169052565b5060c083015161487f60c084018263ffffffff169052565b5060e083015161489560e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a08085015167ffffffffffffffff16908401526101c080850151909116908301526101e080840151151590830152610200808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461413d57600080fd5b803561ffff8116811461413d57600080fd5b600082601f83011261498657600080fd5b81356020614996614455836143d9565b82815260069290921b840181019181810190868411156149b557600080fd5b8286015b84811015614a0257604081890312156149d25760008081fd5b6149da6142d4565b6149e38261477b565b81526149f0858301614119565b818601528352918301916040016149b9565b509695505050505050565b60008060408385031215614a2057600080fd5b67ffffffffffffffff83351115614a3657600080fd5b83601f843585010112614a4857600080fd5b614a5861445584358501356143d9565b8335840180358083526020808401939260059290921b90910101861015614a7e57600080fd5b602085358601015b85358601803560051b01602001811015614c8b5767ffffffffffffffff81351115614ab057600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a03011215614ae957600080fd5b614af16142d4565b614afd6020830161477b565b815267ffffffffffffffff60408301351115614b1857600080fd5b88603f604084013584010112614b2d57600080fd5b614b4361445560206040850135850101356143d9565b6020604084810135850182810135808552928401939260e00201018b1015614b6a57600080fd5b6040808501358501015b6040858101358601602081013560e0020101811015614c6c5760e0818d031215614b9d57600080fd5b614ba56142d4565b614bae82614119565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215614be257600080fd5b614bea614320565b614bf66020840161494f565b8152614c046040840161494f565b6020820152614c1560608401614963565b6040820152614c266080840161494f565b6060820152614c3760a0840161494f565b6080820152614c4960c0840135614525565b60c083013560a0820152602082810191909152908452929092019160e001614b74565b5080602084015250508085525050602083019250602081019050614a86565b5092505067ffffffffffffffff60208401351115614ca857600080fd5b614cb88460208501358501614975565b90509250929050565b600082601f830112614cd257600080fd5b81356020614ce2614455836143d9565b8083825260208201915060208460051b870101935086841115614d0457600080fd5b602086015b84811015614a0257614d1a81614119565b8352918301918301614d09565b60008060408385031215614d3a57600080fd5b823567ffffffffffffffff80821115614d5257600080fd5b614d5e86838701614cc1565b93506020850135915080821115614d7457600080fd5b50614d8185828601614cc1565b9150509250929050565b60008083601f840112614d9d57600080fd5b50813567ffffffffffffffff811115614db557600080fd5b6020830191508360208285010111156120e557600080fd5b60008060008060408587031215614de357600080fd5b843567ffffffffffffffff80821115614dfb57600080fd5b614e0788838901614d8b565b90965094506020870135915080821115614e2057600080fd5b50614e2d87828801614d8b565b95989497509550505050565b60008060408385031215614e4c57600080fd5b614e558361477b565b9150614cb860208401614119565b600060208284031215614e7557600080fd5b813567ffffffffffffffff80821115614e8d57600080fd5b9083019060408286031215614ea157600080fd5b614ea96142d4565b823582811115614eb857600080fd5b614ec487828601614cc1565b825250602083013582811115614ed957600080fd5b614ee587828601614cc1565b60208301525095945050505050565b60006020808385031215614f0757600080fd5b823567ffffffffffffffff811115614f1e57600080fd5b8301601f81018513614f2f57600080fd5b8035614f3d614455826143d9565b81815260069190911b82018301908381019087831115614f5c57600080fd5b928401925b82841015614fae5760408489031215614f7a5760008081fd5b614f826142d4565b614f8b85614119565b8152614f9886860161477b565b8187015282526040939093019290840190614f61565b979650505050505050565b600080600080600060808688031215614fd157600080fd5b614fda8661477b565b9450614fe860208701614119565b935060408601359250606086013567ffffffffffffffff81111561500b57600080fd5b61501788828901614d8b565b969995985093965092949392505050565b8381528215156020820152606060408201526000612cb26060830184614199565b60008060008060006060868803121561506157600080fd5b61506a8661477b565b9450602086013567ffffffffffffffff8082111561508757600080fd5b61509389838a01614679565b909650945060408801359150808211156150ac57600080fd5b818801915088601f8301126150c057600080fd5b8135818111156150cf57600080fd5b8960208260061b85010111156150e457600080fd5b9699959850939650602001949392505050565b6000806040838503121561510a57600080fd5b6151138361477b565b9150602083013567ffffffffffffffff81111561512f57600080fd5b830160a0818603121561514157600080fd5b809150509250929050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461413d57600080fd5b6000602080838503121561518f57600080fd5b823567ffffffffffffffff8111156151a657600080fd5b8301601f810185136151b757600080fd5b80356151c5614455826143d9565b81815261024091820283018401918482019190888411156151e557600080fd5b938501935b8385101561451957848903818112156152035760008081fd5b61520b6142d4565b6152148761477b565b8152610220807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156152495760008081fd5b615251614343565b925061525e898901614533565b8352604061526d818a01614963565b8a850152606061527e818b0161494f565b8286015260809150615291828b0161494f565b9085015260a06152a28a820161494f565b8286015260c091506152b5828b01614963565b9085015260e06152c68a820161494f565b8286015261010091506152da828b01614963565b908501526101206152ec8a8201614963565b828601526101409150615300828b01614963565b908501526101606153128a820161494f565b828601526101809150615326828b0161494f565b908501526101a06153388a820161494f565b828601526101c0915061534c828b0161477b565b908501526101e061535e8a820161494f565b828601526102009150615372828b01614533565b9085015261538189830161514c565b908401525080880191909152835293840193918501916151ea565b600080604083850312156153af57600080fd5b6153b883614119565b9150614cb86020840161477b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610f6857610f686153c6565b600082615442577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261547c57600080fd5b83018035915067ffffffffffffffff82111561549757600080fd5b6020019150600681901b36038213156120e557600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461413d57600080fd5b60006040828403121561551c57600080fd5b6155246142d4565b61552d83614119565b815261553b602084016154de565b60208201529392505050565b60006040828403121561555957600080fd5b6155616142d4565b61552d8361477b565b6000602080838503121561557d57600080fd5b823567ffffffffffffffff81111561559457600080fd5b8301601f810185136155a557600080fd5b80356155b3614455826143d9565b818152606091820283018401918482019190888411156155d257600080fd5b938501935b838510156145195780858a0312156155ef5760008081fd5b6155f7614367565b61560086614119565b815261560d8787016154de565b87820152604061561e81880161494f565b90820152835293840193918501916155d7565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183360301811261566557600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126156a457600080fd5b83018035915067ffffffffffffffff8211156156bf57600080fd5b6020019150368190038213156120e557600080fd5b80820180821115610f6857610f686153c6565b81810381811115610f6857610f686153c6565b60ff8181168382160190811115610f6857610f686153c6565b60ff8281168282160390811115610f6857610f686153c6565b600181815b8085111561578557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561576b5761576b6153c6565b8085161561577857918102915b93841c9390800290615731565b509250929050565b60008261579c57506001610f68565b816157a957506000610f68565b81600181146157bf57600281146157c9576157e5565b6001915050610f68565b60ff8411156157da576157da6153c6565b50506001821b610f68565b5060208310610133831016604e8410600b8410161715615808575081810a610f68565b615812838361572c565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615844576158446153c6565b029392505050565b6000610b8060ff84168361578d565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156149475760049490940360031b84901b1690921692915050565b600080858511156158b157600080fd5b838611156158be57600080fd5b5050820193919092039150565b6000604082840312156158dd57600080fd5b6158e56142d4565b82518152602083015161553b81614525565b60006020828403121561590957600080fd5b5051919050565b805169ffffffffffffffffffff8116811461413d57600080fd5b600080600080600060a0868803121561594257600080fd5b61594b86615910565b945060208601519350604086015192506060860151915061596e60808701615910565b90509295509295909350565b60006020828403121561598c57600080fd5b8151610b80816143fd565b6000604082840312156159a957600080fd5b6159b16142d4565b6159ba83614119565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156140ba576140ba6153c6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var PriceRegistryABI = PriceRegistryMetaData.ABI @@ -769,6 +777,30 @@ func (_PriceRegistry *PriceRegistryTransactorSession) ApplyTokenTransferFeeConfi return _PriceRegistry.Contract.ApplyTokenTransferFeeConfigUpdates(&_PriceRegistry.TransactOpts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) } +func (_PriceRegistry *PriceRegistryTransactor) OnReport(opts *bind.TransactOpts, metadata []byte, report []byte) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "onReport", metadata, report) +} + +func (_PriceRegistry *PriceRegistrySession) OnReport(metadata []byte, report []byte) (*types.Transaction, error) { + return _PriceRegistry.Contract.OnReport(&_PriceRegistry.TransactOpts, metadata, report) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) OnReport(metadata []byte, report []byte) (*types.Transaction, error) { + return _PriceRegistry.Contract.OnReport(&_PriceRegistry.TransactOpts, metadata, report) +} + +func (_PriceRegistry *PriceRegistryTransactor) SetReportPermissions(opts *bind.TransactOpts, permissions []KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "setReportPermissions", permissions) +} + +func (_PriceRegistry *PriceRegistrySession) SetReportPermissions(permissions []KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { + return _PriceRegistry.Contract.SetReportPermissions(&_PriceRegistry.TransactOpts, permissions) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) SetReportPermissions(permissions []KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { + return _PriceRegistry.Contract.SetReportPermissions(&_PriceRegistry.TransactOpts, permissions) +} + func (_PriceRegistry *PriceRegistryTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return _PriceRegistry.contract.Transact(opts, "transferOwnership", to) } @@ -2077,6 +2109,134 @@ func (_PriceRegistry *PriceRegistryFilterer) ParsePriceFeedPerTokenUpdated(log t return event, nil } +type PriceRegistryReportPermissionSetIterator struct { + Event *PriceRegistryReportPermissionSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryReportPermissionSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryReportPermissionSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryReportPermissionSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryReportPermissionSetIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryReportPermissionSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryReportPermissionSet struct { + ReportId [32]byte + Permission KeystoneFeedsPermissionHandlerPermission + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterReportPermissionSet(opts *bind.FilterOpts, reportId [][32]byte) (*PriceRegistryReportPermissionSetIterator, error) { + + var reportIdRule []interface{} + for _, reportIdItem := range reportId { + reportIdRule = append(reportIdRule, reportIdItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "ReportPermissionSet", reportIdRule) + if err != nil { + return nil, err + } + return &PriceRegistryReportPermissionSetIterator{contract: _PriceRegistry.contract, event: "ReportPermissionSet", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchReportPermissionSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryReportPermissionSet, reportId [][32]byte) (event.Subscription, error) { + + var reportIdRule []interface{} + for _, reportIdItem := range reportId { + reportIdRule = append(reportIdRule, reportIdItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "ReportPermissionSet", reportIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryReportPermissionSet) + if err := _PriceRegistry.contract.UnpackLog(event, "ReportPermissionSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseReportPermissionSet(log types.Log) (*PriceRegistryReportPermissionSet, error) { + event := new(PriceRegistryReportPermissionSet) + if err := _PriceRegistry.contract.UnpackLog(event, "ReportPermissionSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type PriceRegistryTokenTransferFeeConfigDeletedIterator struct { Event *PriceRegistryTokenTransferFeeConfigDeleted @@ -2640,6 +2800,8 @@ func (_PriceRegistry *PriceRegistry) ParseLog(log types.Log) (generated.AbigenLo return _PriceRegistry.ParsePremiumMultiplierWeiPerEthUpdated(log) case _PriceRegistry.abi.Events["PriceFeedPerTokenUpdated"].ID: return _PriceRegistry.ParsePriceFeedPerTokenUpdated(log) + case _PriceRegistry.abi.Events["ReportPermissionSet"].ID: + return _PriceRegistry.ParseReportPermissionSet(log) case _PriceRegistry.abi.Events["TokenTransferFeeConfigDeleted"].ID: return _PriceRegistry.ParseTokenTransferFeeConfigDeleted(log) case _PriceRegistry.abi.Events["TokenTransferFeeConfigUpdated"].ID: @@ -2694,6 +2856,10 @@ func (PriceRegistryPriceFeedPerTokenUpdated) Topic() common.Hash { return common.HexToHash("0x08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464") } +func (PriceRegistryReportPermissionSet) Topic() common.Hash { + return common.HexToHash("0x32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a3") +} + func (PriceRegistryTokenTransferFeeConfigDeleted) Topic() common.Hash { return common.HexToHash("0x4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b") } @@ -2767,6 +2933,10 @@ type PriceRegistryInterface interface { ApplyTokenTransferFeeConfigUpdates(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) + OnReport(opts *bind.TransactOpts, metadata []byte, report []byte) (*types.Transaction, error) + + SetReportPermissions(opts *bind.TransactOpts, permissions []KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) UpdatePrices(opts *bind.TransactOpts, priceUpdates InternalPriceUpdates) (*types.Transaction, error) @@ -2833,6 +3003,12 @@ type PriceRegistryInterface interface { ParsePriceFeedPerTokenUpdated(log types.Log) (*PriceRegistryPriceFeedPerTokenUpdated, error) + FilterReportPermissionSet(opts *bind.FilterOpts, reportId [][32]byte) (*PriceRegistryReportPermissionSetIterator, error) + + WatchReportPermissionSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryReportPermissionSet, reportId [][32]byte) (event.Subscription, error) + + ParseReportPermissionSet(log types.Log) (*PriceRegistryReportPermissionSet, error) + FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*PriceRegistryTokenTransferFeeConfigDeletedIterator, error) WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *PriceRegistryTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 13c88b9c51..5c3a85cb32 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -25,7 +25,7 @@ ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3Con offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin 76ec9676116368ab7c7c7ed45191698a12e4d975633caea32d821a1125633589 onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 123e949bc9607289382534c4432ecebe5b1da5ca92c1c6c8cc6b9be56c3352c6 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 4e51d70bdb6d951041518a3d7fd3b33ba8d3954bcc3d078318055b833b880324 -price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 8f4bdaa4d8239429ae4e047ab06d445bad42234a05bb7c99ba6141bd811e1722 +price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 8931609776700a2a8121c9fdd757dbf9207d8b97583e70c84ec2d88c839d4a30 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 75be86323c227917a9bbc3f799d7ed02f92db546653a36db30ed0ebe64461353 report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin 20292ddaba15096fe8060567cf56cda673b947df27241d0c49d2debc838feb24 rmn_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 8b45b0fb08631c6b582fd3c0b4052a79cc2b4e091e6286af1ab131bef63661f9 diff --git a/core/gethwrappers/ccip/mocks/price_registry_interface.go b/core/gethwrappers/ccip/mocks/price_registry_interface.go index b8b90b1293..01d435d05a 100644 --- a/core/gethwrappers/ccip/mocks/price_registry_interface.go +++ b/core/gethwrappers/ccip/mocks/price_registry_interface.go @@ -1085,6 +1085,65 @@ func (_c *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call) RunAndRetu return _c } +// FilterReportPermissionSet provides a mock function with given fields: opts, reportId +func (_m *PriceRegistryInterface) FilterReportPermissionSet(opts *bind.FilterOpts, reportId [][32]byte) (*price_registry.PriceRegistryReportPermissionSetIterator, error) { + ret := _m.Called(opts, reportId) + + if len(ret) == 0 { + panic("no return value specified for FilterReportPermissionSet") + } + + var r0 *price_registry.PriceRegistryReportPermissionSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, [][32]byte) (*price_registry.PriceRegistryReportPermissionSetIterator, error)); ok { + return rf(opts, reportId) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, [][32]byte) *price_registry.PriceRegistryReportPermissionSetIterator); ok { + r0 = rf(opts, reportId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryReportPermissionSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, [][32]byte) error); ok { + r1 = rf(opts, reportId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_FilterReportPermissionSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterReportPermissionSet' +type PriceRegistryInterface_FilterReportPermissionSet_Call struct { + *mock.Call +} + +// FilterReportPermissionSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - reportId [][32]byte +func (_e *PriceRegistryInterface_Expecter) FilterReportPermissionSet(opts interface{}, reportId interface{}) *PriceRegistryInterface_FilterReportPermissionSet_Call { + return &PriceRegistryInterface_FilterReportPermissionSet_Call{Call: _e.mock.On("FilterReportPermissionSet", opts, reportId)} +} + +func (_c *PriceRegistryInterface_FilterReportPermissionSet_Call) Run(run func(opts *bind.FilterOpts, reportId [][32]byte)) *PriceRegistryInterface_FilterReportPermissionSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([][32]byte)) + }) + return _c +} + +func (_c *PriceRegistryInterface_FilterReportPermissionSet_Call) Return(_a0 *price_registry.PriceRegistryReportPermissionSetIterator, _a1 error) *PriceRegistryInterface_FilterReportPermissionSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_FilterReportPermissionSet_Call) RunAndReturn(run func(*bind.FilterOpts, [][32]byte) (*price_registry.PriceRegistryReportPermissionSetIterator, error)) *PriceRegistryInterface_FilterReportPermissionSet_Call { + _c.Call.Return(run) + return _c +} + // FilterTokenTransferFeeConfigDeleted provides a mock function with given fields: opts, destChainSelector, token func (_m *PriceRegistryInterface) FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator, error) { ret := _m.Called(opts, destChainSelector, token) @@ -2074,6 +2133,66 @@ func (_c *PriceRegistryInterface_GetValidatedTokenPrice_Call) RunAndReturn(run f return _c } +// OnReport provides a mock function with given fields: opts, metadata, report +func (_m *PriceRegistryInterface) OnReport(opts *bind.TransactOpts, metadata []byte, report []byte) (*types.Transaction, error) { + ret := _m.Called(opts, metadata, report) + + if len(ret) == 0 { + panic("no return value specified for OnReport") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []byte, []byte) (*types.Transaction, error)); ok { + return rf(opts, metadata, report) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []byte, []byte) *types.Transaction); ok { + r0 = rf(opts, metadata, report) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []byte, []byte) error); ok { + r1 = rf(opts, metadata, report) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_OnReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OnReport' +type PriceRegistryInterface_OnReport_Call struct { + *mock.Call +} + +// OnReport is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - metadata []byte +// - report []byte +func (_e *PriceRegistryInterface_Expecter) OnReport(opts interface{}, metadata interface{}, report interface{}) *PriceRegistryInterface_OnReport_Call { + return &PriceRegistryInterface_OnReport_Call{Call: _e.mock.On("OnReport", opts, metadata, report)} +} + +func (_c *PriceRegistryInterface_OnReport_Call) Run(run func(opts *bind.TransactOpts, metadata []byte, report []byte)) *PriceRegistryInterface_OnReport_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]byte), args[2].([]byte)) + }) + return _c +} + +func (_c *PriceRegistryInterface_OnReport_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_OnReport_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_OnReport_Call) RunAndReturn(run func(*bind.TransactOpts, []byte, []byte) (*types.Transaction, error)) *PriceRegistryInterface_OnReport_Call { + _c.Call.Return(run) + return _c +} + // Owner provides a mock function with given fields: opts func (_m *PriceRegistryInterface) Owner(opts *bind.CallOpts) (common.Address, error) { ret := _m.Called(opts) @@ -2770,6 +2889,64 @@ func (_c *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call) RunAndRetur return _c } +// ParseReportPermissionSet provides a mock function with given fields: log +func (_m *PriceRegistryInterface) ParseReportPermissionSet(log types.Log) (*price_registry.PriceRegistryReportPermissionSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseReportPermissionSet") + } + + var r0 *price_registry.PriceRegistryReportPermissionSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryReportPermissionSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryReportPermissionSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*price_registry.PriceRegistryReportPermissionSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ParseReportPermissionSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseReportPermissionSet' +type PriceRegistryInterface_ParseReportPermissionSet_Call struct { + *mock.Call +} + +// ParseReportPermissionSet is a helper method to define mock.On call +// - log types.Log +func (_e *PriceRegistryInterface_Expecter) ParseReportPermissionSet(log interface{}) *PriceRegistryInterface_ParseReportPermissionSet_Call { + return &PriceRegistryInterface_ParseReportPermissionSet_Call{Call: _e.mock.On("ParseReportPermissionSet", log)} +} + +func (_c *PriceRegistryInterface_ParseReportPermissionSet_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseReportPermissionSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ParseReportPermissionSet_Call) Return(_a0 *price_registry.PriceRegistryReportPermissionSet, _a1 error) *PriceRegistryInterface_ParseReportPermissionSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ParseReportPermissionSet_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryReportPermissionSet, error)) *PriceRegistryInterface_ParseReportPermissionSet_Call { + _c.Call.Return(run) + return _c +} + // ParseTokenTransferFeeConfigDeleted provides a mock function with given fields: log func (_m *PriceRegistryInterface) ParseTokenTransferFeeConfigDeleted(log types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigDeleted, error) { ret := _m.Called(log) @@ -3062,6 +3239,65 @@ func (_c *PriceRegistryInterface_ProcessMessageArgs_Call) RunAndReturn(run func( return _c } +// SetReportPermissions provides a mock function with given fields: opts, permissions +func (_m *PriceRegistryInterface) SetReportPermissions(opts *bind.TransactOpts, permissions []price_registry.KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { + ret := _m.Called(opts, permissions) + + if len(ret) == 0 { + panic("no return value specified for SetReportPermissions") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error)); ok { + return rf(opts, permissions) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.KeystoneFeedsPermissionHandlerPermission) *types.Transaction); ok { + r0 = rf(opts, permissions) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []price_registry.KeystoneFeedsPermissionHandlerPermission) error); ok { + r1 = rf(opts, permissions) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_SetReportPermissions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetReportPermissions' +type PriceRegistryInterface_SetReportPermissions_Call struct { + *mock.Call +} + +// SetReportPermissions is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - permissions []price_registry.KeystoneFeedsPermissionHandlerPermission +func (_e *PriceRegistryInterface_Expecter) SetReportPermissions(opts interface{}, permissions interface{}) *PriceRegistryInterface_SetReportPermissions_Call { + return &PriceRegistryInterface_SetReportPermissions_Call{Call: _e.mock.On("SetReportPermissions", opts, permissions)} +} + +func (_c *PriceRegistryInterface_SetReportPermissions_Call) Run(run func(opts *bind.TransactOpts, permissions []price_registry.KeystoneFeedsPermissionHandlerPermission)) *PriceRegistryInterface_SetReportPermissions_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]price_registry.KeystoneFeedsPermissionHandlerPermission)) + }) + return _c +} + +func (_c *PriceRegistryInterface_SetReportPermissions_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_SetReportPermissions_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_SetReportPermissions_Call) RunAndReturn(run func(*bind.TransactOpts, []price_registry.KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error)) *PriceRegistryInterface_SetReportPermissions_Call { + _c.Call.Return(run) + return _c +} + // TransferOwnership provides a mock function with given fields: opts, to func (_m *PriceRegistryInterface) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { ret := _m.Called(opts, to) @@ -3944,6 +4180,66 @@ func (_c *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call) RunAndRetur return _c } +// WatchReportPermissionSet provides a mock function with given fields: opts, sink, reportId +func (_m *PriceRegistryInterface) WatchReportPermissionSet(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryReportPermissionSet, reportId [][32]byte) (event.Subscription, error) { + ret := _m.Called(opts, sink, reportId) + + if len(ret) == 0 { + panic("no return value specified for WatchReportPermissionSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryReportPermissionSet, [][32]byte) (event.Subscription, error)); ok { + return rf(opts, sink, reportId) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryReportPermissionSet, [][32]byte) event.Subscription); ok { + r0 = rf(opts, sink, reportId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryReportPermissionSet, [][32]byte) error); ok { + r1 = rf(opts, sink, reportId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_WatchReportPermissionSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchReportPermissionSet' +type PriceRegistryInterface_WatchReportPermissionSet_Call struct { + *mock.Call +} + +// WatchReportPermissionSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *price_registry.PriceRegistryReportPermissionSet +// - reportId [][32]byte +func (_e *PriceRegistryInterface_Expecter) WatchReportPermissionSet(opts interface{}, sink interface{}, reportId interface{}) *PriceRegistryInterface_WatchReportPermissionSet_Call { + return &PriceRegistryInterface_WatchReportPermissionSet_Call{Call: _e.mock.On("WatchReportPermissionSet", opts, sink, reportId)} +} + +func (_c *PriceRegistryInterface_WatchReportPermissionSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryReportPermissionSet, reportId [][32]byte)) *PriceRegistryInterface_WatchReportPermissionSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryReportPermissionSet), args[2].([][32]byte)) + }) + return _c +} + +func (_c *PriceRegistryInterface_WatchReportPermissionSet_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchReportPermissionSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_WatchReportPermissionSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryReportPermissionSet, [][32]byte) (event.Subscription, error)) *PriceRegistryInterface_WatchReportPermissionSet_Call { + _c.Call.Return(run) + return _c +} + // WatchTokenTransferFeeConfigDeleted provides a mock function with given fields: opts, sink, destChainSelector, token func (_m *PriceRegistryInterface) WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { ret := _m.Called(opts, sink, destChainSelector, token) From 50c25eddc25b220a2f9660f3c6283aa0e9891c6a Mon Sep 17 00:00:00 2001 From: kanth <70688600+defistar@users.noreply.github.com> Date: Fri, 23 Aug 2024 17:41:19 +0530 Subject: [PATCH 222/432] fix: CCIP-3095 fix flaky test assertions in offramp tests (#1357) ## Motivation fix: CCIP-3095 fix flaky test assertions in offramp tests Few unit tests were still asserting on `gasUsed` in `ExecutionStateChanged` event emitted by offramp contract while executing messages in the report. ## Solution use assertion helper function to assert the ExecutionStateChanged Event indexed topics and chosen fields of event data --- contracts/gas-snapshots/ccip.gas-snapshot | 8 +- .../src/v0.8/ccip/test/offRamp/OffRamp.t.sol | 136 ++++++++---------- 2 files changed, 60 insertions(+), 84 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 98503798b9..3c9bbec852 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -595,10 +595,10 @@ OffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26014) OffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152948) OffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 518487) OffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2295740) -OffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 208322) -OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 208944) -OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 662979) -OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 301931) +OffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 205788) +OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 206365) +OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 649321) +OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 318903) OffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 164042) OffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 23736) OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 64484) diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol index 0df9859269..70e5689679 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol @@ -658,16 +658,6 @@ contract OffRamp_executeSingleReport is OffRampSetup { messages[i].header.nonce = ++expectedNonce; } messages[i].header.messageId = Internal._hash(messages[i], ON_RAMP_ADDRESS_1); - - vm.expectEmit(true, true, true, false); - emit OffRamp.ExecutionStateChanged( - SOURCE_CHAIN_SELECTOR_1, - messages[i].header.sequenceNumber, - messages[i].header.messageId, - Internal.MessageExecutionState.SUCCESS, - "", - 0 - ); } uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER)); @@ -681,6 +671,14 @@ contract OffRamp_executeSingleReport is OffRampSetup { uint256(s_offRamp.getExecutionState(SOURCE_CHAIN_SELECTOR_1, messages[i].header.sequenceNumber)), uint256(Internal.MessageExecutionState.SUCCESS) ); + + assertExecutionStateChangedEventLogs( + SOURCE_CHAIN_SELECTOR_1, + messages[i].header.sequenceNumber, + messages[i].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); } assertEq( nonceBefore + expectedNonce, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(OWNER)) @@ -1289,19 +1287,16 @@ contract OffRamp_manuallyExecute is OffRampSetup { s_reverting_receiver.setRevert(false); - vm.expectEmit(); - emit OffRamp.ExecutionStateChanged( + uint256[][] memory gasLimitOverrides = new uint256[][](1); + gasLimitOverrides[0] = new uint256[](messages.length); + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, - "", - 30937 + "" ); - - uint256[][] memory gasLimitOverrides = new uint256[][](1); - gasLimitOverrides[0] = new uint256[](messages.length); - s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); } function test_manuallyExecute_WithGasOverride_Success() public { @@ -1312,22 +1307,19 @@ contract OffRamp_manuallyExecute is OffRampSetup { s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); s_reverting_receiver.setRevert(false); + uint256[][] memory gasLimitOverrides = new uint256[][](1); + gasLimitOverrides[0] = _getGasLimitsFromMessages(messages); + gasLimitOverrides[0][0] += 1; + + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); - vm.expectEmit(true, true, true, true); - emit OffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, - "", - 31011 + "" ); - - uint256[][] memory gasLimitOverrides = new uint256[][](1); - gasLimitOverrides[0] = _getGasLimitsFromMessages(messages); - gasLimitOverrides[0][0] += 1; - - s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); } function test_manuallyExecute_DoesNotRevertIfUntouched_Success() public { @@ -1390,44 +1382,35 @@ contract OffRamp_manuallyExecute is OffRampSetup { gasLimitOverrides[0] = _getGasLimitsFromMessages(messages1); gasLimitOverrides[1] = _getGasLimitsFromMessages(messages2); - uint256[] memory expectedGasUsed = new uint256[](3); - expectedGasUsed[0] = 31022; - expectedGasUsed[1] = 22453; - expectedGasUsed[2] = 22453; - for (uint256 i = 0; i < 3; ++i) { - vm.expectEmit(true, true, true, true); - emit OffRamp.ExecutionStateChanged( - SOURCE_CHAIN_SELECTOR_1, - messages1[i].header.sequenceNumber, - messages1[i].header.messageId, - Internal.MessageExecutionState.SUCCESS, - "", - expectedGasUsed[i] - ); - gasLimitOverrides[0][i] += 1; } - expectedGasUsed = new uint256[](2); - expectedGasUsed[0] = 24527; - expectedGasUsed[1] = 22454; - for (uint256 i = 0; i < 2; ++i) { - vm.expectEmit(true, true, true, false); - emit OffRamp.ExecutionStateChanged( - SOURCE_CHAIN_SELECTOR_3, - messages2[i].header.sequenceNumber, - messages2[i].header.messageId, - Internal.MessageExecutionState.SUCCESS, - "", - expectedGasUsed[i] - ); - gasLimitOverrides[1][i] += 1; } s_offRamp.manuallyExecute(reports, gasLimitOverrides); + + for (uint256 j = 0; j < 3; ++j) { + assertExecutionStateChangedEventLogs( + SOURCE_CHAIN_SELECTOR_1, + messages1[j].header.sequenceNumber, + messages1[j].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + } + + for (uint256 k = 0; k < 2; ++k) { + assertExecutionStateChangedEventLogs( + SOURCE_CHAIN_SELECTOR_1, + messages2[k].header.sequenceNumber, + messages2[k].header.messageId, + Internal.MessageExecutionState.SUCCESS, + "" + ); + } } function test_manuallyExecute_WithPartialMessages_Success() public { @@ -1436,21 +1419,22 @@ contract OffRamp_manuallyExecute is OffRampSetup { for (uint64 i = 0; i < 3; ++i) { messages[i] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, i + 1); } + messages[1].receiver = address(s_reverting_receiver); messages[1].header.messageId = Internal._hash(messages[1], ON_RAMP_ADDRESS_1); - vm.expectEmit(true, true, true, false); - emit OffRamp.ExecutionStateChanged( + vm.recordLogs(); + s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); + + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, - "", - 86456 + "" ); - vm.expectEmit(true, true, true, false); - emit OffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[1].header.sequenceNumber, messages[1].header.messageId, @@ -1458,22 +1442,17 @@ contract OffRamp_manuallyExecute is OffRampSetup { abi.encodeWithSelector( OffRamp.ReceiverError.selector, abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, bytes("")) - ), - 32095 + ) ); - vm.expectEmit(true, true, true, false); - emit OffRamp.ExecutionStateChanged( + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[2].header.sequenceNumber, messages[2].header.messageId, Internal.MessageExecutionState.SUCCESS, - "", - 24894 + "" ); - s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); - s_reverting_receiver.setRevert(false); // Only the 2nd message reverted @@ -1484,18 +1463,15 @@ contract OffRamp_manuallyExecute is OffRampSetup { gasLimitOverrides[0] = _getGasLimitsFromMessages(newMessages); gasLimitOverrides[0][0] += 1; - vm.expectEmit(true, true, true, false); - emit OffRamp.ExecutionStateChanged( + vm.recordLogs(); + s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, newMessages), gasLimitOverrides); + assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, - newMessages[0].header.sequenceNumber, - newMessages[0].header.messageId, + messages[0].header.sequenceNumber, + messages[0].header.messageId, Internal.MessageExecutionState.SUCCESS, - "", - 24511 + "" ); - - vm.recordLogs(); - s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, newMessages), gasLimitOverrides); } function test_manuallyExecute_LowGasLimit_Success() public { From dca57f8fabb4ad28347313917ab2ce054d5dee99 Mon Sep 17 00:00:00 2001 From: Ryan <80392855+RayXpub@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:11:09 +0400 Subject: [PATCH 223/432] Comments cleanup (#1343) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Motivation The goal of this PR is to cleanup comments. ## Solution Update/remove stale comments, fix typos and standardize comments style. Additional fixes: - Consistent use of named return variables - ~~Reordering of add/remove operations (add + remove -> remove + add) for the following functions in the `PriceRegistry`:~~ - ~~`applyTokenTransferFeeConfigUpdates`~~ - ~~`applyFeeTokensUpdates`~~ --------- Co-authored-by: Evaldas Latoškinas <34982762+elatoskinas@users.noreply.github.com> --- .../v0.8/ccip/MultiAggregateRateLimiter.sol | 61 +++++----- contracts/src/v0.8/ccip/NonceManager.sol | 24 ++-- contracts/src/v0.8/ccip/PriceRegistry.sol | 105 +++++++++--------- .../src/v0.8/ccip/capability/CCIPConfig.sol | 26 ++++- .../ccip/interfaces/IEVM2AnyOnRampClient.sol | 1 + .../v0.8/ccip/interfaces/INonceManager.sol | 20 ++-- .../v0.8/ccip/interfaces/IPriceRegistry.sol | 4 +- contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol | 68 ++++++------ contracts/src/v0.8/ccip/offRamp/OffRamp.sol | 70 +++++++----- contracts/src/v0.8/ccip/onRamp/OnRamp.sol | 35 +++--- 10 files changed, 222 insertions(+), 192 deletions(-) diff --git a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol index 33dee29b12..13ba582a2b 100644 --- a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol +++ b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol @@ -29,27 +29,27 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT event TokenAggregateRateLimitAdded(uint64 remoteChainSelector, bytes remoteToken, address localToken); event TokenAggregateRateLimitRemoved(uint64 remoteChainSelector, address localToken); - /// @notice RemoteRateLimitToken struct containing the local token address with the chain selector - /// The struct is used for removals and updates, since the local -> remote token mappings are scoped per-chain + /// @notice LocalRateLimitToken struct containing the local token address with the remote chain selector. + /// The struct is used for removals and updates, since the local -> remote token mappings are scoped per-chain. struct LocalRateLimitToken { uint64 remoteChainSelector; // ────╮ Remote chain selector for which to update the rate limit token mapping address localToken; // ────────────╯ Token on the chain on which the multi-ARL is deployed } - /// @notice RateLimitToken struct containing both the local and remote token addresses + /// @notice RateLimitTokenArgs struct containing both the local and remote token addresses. struct RateLimitTokenArgs { LocalRateLimitToken localTokenArgs; // Local token update args scoped to one remote chain bytes remoteToken; // Token on the remote chain (for OnRamp - dest, of OffRamp - source) } - /// @notice Update args for a single rate limiter config update + /// @notice Update args for a single rate limiter config update. struct RateLimiterConfigArgs { - uint64 remoteChainSelector; // ────╮ Chain selector to set config for + uint64 remoteChainSelector; // ────╮ Remote chain selector to set config for bool isOutboundLane; // ───────────╯ If set to true, represents the outbound message lane (OnRamp), and the inbound message lane otherwise (OffRamp) RateLimiter.Config rateLimiterConfig; // Rate limiter config to set } - /// @notice Struct to store rate limit token buckets for both lane directions + /// @notice Struct to store rate limit token buckets for both lane directions. struct RateLimiterBuckets { RateLimiter.TokenBucket inboundLaneBucket; // Bucket for the inbound lane (remote -> local) RateLimiter.TokenBucket outboundLaneBucket; // Bucket for the outbound lane (local -> remote) @@ -62,14 +62,14 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT mapping(uint64 remoteChainSelector => EnumerableMapAddresses.AddressToBytesMap tokensLocalToRemote) internal s_rateLimitedTokensLocalToRemote; - /// @notice The address of the PriceRegistry used to query token values for ratelimiting + /// @notice The address of the PriceRegistry used to query token values for ratelimiting. address internal s_priceRegistry; /// @notice Rate limiter token bucket states per chain, with separate buckets for inbound and outbound lanes. mapping(uint64 remoteChainSelector => RateLimiterBuckets buckets) internal s_rateLimitersByChainSelector; - /// @param priceRegistry the price registry to set - /// @param authorizedCallers the authorized callers to set + /// @param priceRegistry the price registry to set. + /// @param authorizedCallers the authorized callers to set. constructor(address priceRegistry, address[] memory authorizedCallers) AuthorizedCallers(authorizedCallers) { _setPriceRegistry(priceRegistry); } @@ -87,9 +87,9 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT _applyRateLimit(destChainSelector, message.tokenAmounts, true); } - /// @notice Applies the rate limit to the token bucket if enabled - /// @param remoteChainSelector The remote chain selector - /// @param tokenAmounts The tokens and amounts to rate limit + /// @notice Applies the rate limit to the token bucket if enabled. + /// @param remoteChainSelector The remote chain selector. + /// @param tokenAmounts The tokens and amounts to rate limit. /// @param isOutgoingLane if set to true, fetches the bucket for the outgoing message lane (OnRamp). function _applyRateLimit( uint64 remoteChainSelector, @@ -111,10 +111,10 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT } } - /// @param remoteChainSelector chain selector to retrieve token bucket for + /// @param remoteChainSelector chain selector to retrieve token bucket for. /// @param isOutboundLane if set to true, fetches the bucket for the outbound message lane (OnRamp). /// Otherwise fetches for the inbound message lane (OffRamp). - /// @return bucket Storage pointer to the token bucket representing a specific lane + /// @return bucket Storage pointer to the token bucket representing a specific lane. function _getTokenBucket( uint64 remoteChainSelector, bool isOutboundLane @@ -127,8 +127,9 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT } } - /// @notice Retrieves the token value for a token using the PriceRegistry - /// @return tokenValue USD value in 18 decimals + /// @notice Retrieves the token value for a token using the PriceRegistry. + /// @param tokenAmount The token and amount to get the value for. + /// @return tokenValue USD value in 18 decimals. function _getTokenValue(Client.EVMTokenAmount memory tokenAmount) internal view returns (uint256) { // not fetching validated price, as price staleness is not important for value-based rate limiting // we only need to verify the price is not 0 @@ -142,7 +143,7 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT /// @param isOutboundLane if set to true, fetches the rate limit state for the outbound message lane (OnRamp). /// Otherwise fetches for the inbound message lane (OffRamp). /// The outbound and inbound message rate limit state is completely separated. - /// @return The token bucket. + /// @return tokenBucket The token bucket. function currentRateLimiterState( uint64 remoteChainSelector, bool isOutboundLane @@ -151,8 +152,8 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT } /// @notice Applies the provided rate limiter config updates. - /// @param rateLimiterUpdates Rate limiter updates - /// @dev should only be callable by the owner + /// @param rateLimiterUpdates Rate limiter updates. + /// @dev Only callable by the owner. function applyRateLimiterConfigUpdates(RateLimiterConfigArgs[] memory rateLimiterUpdates) external onlyOwner { for (uint256 i = 0; i < rateLimiterUpdates.length; ++i) { RateLimiterConfigArgs memory updateArgs = rateLimiterUpdates[i]; @@ -189,12 +190,12 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT } } - /// @notice Get all tokens which are included in Aggregate Rate Limiting. - /// @param remoteChainSelector chain selector to get rate limit tokens for - /// @return localTokens The local chain representation of the tokens that are rate limited. - /// @return remoteTokens The remote representation of the tokens that are rate limited. + /// @notice Gets all tokens which are included in Aggregate Rate Limiting. /// @dev the order of IDs in the list is **not guaranteed**, therefore, if ordering matters when /// making successive calls, one should keep the block height constant to ensure a consistent result. + /// @param remoteChainSelector chain selector to get rate limit tokens for. + /// @return localTokens The local chain representation of the tokens that are rate limited. + /// @return remoteTokens The remote representation of the tokens that are rate limited. function getAllRateLimitTokens(uint64 remoteChainSelector) external view @@ -246,21 +247,21 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT } } - /// @return priceRegistry The configured PriceRegistry address + /// @return priceRegistry The configured PriceRegistry address. function getPriceRegistry() external view returns (address) { return s_priceRegistry; } - /// @notice Sets the Price Registry address - /// @param newPriceRegistry the address of the new PriceRegistry - /// @dev precondition The address must be a non-zero address + /// @notice Sets the Price Registry address. + /// @param newPriceRegistry the address of the new PriceRegistry. + /// @dev precondition The address must be a non-zero address. function setPriceRegistry(address newPriceRegistry) external onlyOwner { _setPriceRegistry(newPriceRegistry); } - /// @notice Sets the Price Registry address - /// @param newPriceRegistry the address of the new PriceRegistry - /// @dev precondition The address must be a non-zero address + /// @notice Sets the Price Registry address. + /// @param newPriceRegistry the address of the new PriceRegistry. + /// @dev precondition The address must be a non-zero address. function _setPriceRegistry(address newPriceRegistry) internal { if (newPriceRegistry == address(0)) { revert ZeroAddressNotAllowed(); diff --git a/contracts/src/v0.8/ccip/NonceManager.sol b/contracts/src/v0.8/ccip/NonceManager.sol index de9b9ce4a3..38212e1d5f 100644 --- a/contracts/src/v0.8/ccip/NonceManager.sol +++ b/contracts/src/v0.8/ccip/NonceManager.sol @@ -30,7 +30,7 @@ contract NonceManager is INonceManager, AuthorizedCallers, ITypeAndVersion { string public constant override typeAndVersion = "NonceManager 1.6.0-dev"; - /// @dev previous ramps + /// @dev The previous on/off ramps per chain selector mapping(uint64 chainSelector => PreviousRamps previousRamps) private s_previousRamps; /// @dev The current outbound nonce per sender used on the onramp mapping(uint64 destChainSelector => mapping(address sender => uint64 outboundNonce)) private s_outboundNonces; @@ -52,10 +52,10 @@ contract NonceManager is INonceManager, AuthorizedCallers, ITypeAndVersion { return outboundNonce; } - /// @notice Returns the outbound nonce for a given sender on a given destination chain - /// @param destChainSelector The destination chain selector - /// @param sender The sender address - /// @return The outbound nonce + /// @notice Returns the outbound nonce for a given sender on a given destination chain. + /// @param destChainSelector The destination chain selector. + /// @param sender The sender address. + /// @return outboundNonce The outbound nonce. function getOutboundNonce(uint64 destChainSelector, address sender) external view returns (uint64) { return _getOutboundNonce(destChainSelector, sender); } @@ -95,10 +95,10 @@ contract NonceManager is INonceManager, AuthorizedCallers, ITypeAndVersion { return true; } - /// @notice Returns the inbound nonce for a given sender on a given source chain - /// @param sourceChainSelector The source chain selector - /// @param sender The encoded sender address - /// @return The inbound nonce + /// @notice Returns the inbound nonce for a given sender on a given source chain. + /// @param sourceChainSelector The source chain selector. + /// @param sender The encoded sender address. + /// @return inboundNonce The inbound nonce. function getInboundNonce(uint64 sourceChainSelector, bytes calldata sender) external view returns (uint64) { return _getInboundNonce(sourceChainSelector, sender); } @@ -121,8 +121,8 @@ contract NonceManager is INonceManager, AuthorizedCallers, ITypeAndVersion { return inboundNonce; } - /// @notice Updates the previous ramps addresses - /// @param previousRampsArgs The previous on/off ramps addresses + /// @notice Updates the previous ramps addresses. + /// @param previousRampsArgs The previous on/off ramps addresses. function applyPreviousRampsUpdates(PreviousRampsArgs[] calldata previousRampsArgs) external onlyOwner { for (uint256 i = 0; i < previousRampsArgs.length; ++i) { PreviousRampsArgs calldata previousRampsArg = previousRampsArgs[i]; @@ -143,7 +143,7 @@ contract NonceManager is INonceManager, AuthorizedCallers, ITypeAndVersion { /// @notice Gets the previous onRamp address for the given chain selector /// @param chainSelector The chain selector - /// @return The previous onRamp address + /// @return previousRamps The previous on/offRamp addresses function getPreviousRamps(uint64 chainSelector) external view returns (PreviousRamps memory) { return s_previousRamps[chainSelector]; } diff --git a/contracts/src/v0.8/ccip/PriceRegistry.sol b/contracts/src/v0.8/ccip/PriceRegistry.sol index 8551971753..f9989f9363 100644 --- a/contracts/src/v0.8/ccip/PriceRegistry.sol +++ b/contracts/src/v0.8/ccip/PriceRegistry.sol @@ -16,8 +16,10 @@ import {IReceiver} from "../keystone/interfaces/IReceiver.sol"; import {KeystoneFeedDefaultMetadataLib} from "../keystone/lib/KeystoneFeedDefaultMetadataLib.sol"; import {EnumerableSet} from "../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; -/// @notice The PriceRegistry contract responsibility is to store the current gas price in USD for a given destination chain, -/// and the price of a token in USD allowing the owner or priceUpdater to update this value. +/// @notice The PriceRegistry contract responsibility is to: +/// - Store the current gas price in USD for a given destination chain, +/// - Store the price of a token in USD allowing the owner or priceUpdater to update this value. +/// - Manage chain specific fee calculations. /// The authorized callers in the contract represent the fee price updaters. contract PriceRegistry is AuthorizedCallers, @@ -30,28 +32,6 @@ contract PriceRegistry is using USDPriceWith18Decimals for uint224; using KeystoneFeedDefaultMetadataLib for bytes; - /// @notice Token price data feed update - struct TokenPriceFeedUpdate { - address sourceToken; // Source token to update feed for - IPriceRegistry.TokenPriceFeedConfig feedConfig; // Feed config update data - } - - /// @dev Struct that contains the static configuration - /// RMN depends on this struct, if changing, please notify the RMN maintainers. - // solhint-disable-next-line gas-struct-packing - struct StaticConfig { - uint96 maxFeeJuelsPerMsg; // ─╮ Maximum fee that can be charged for a message - address linkToken; // ────────╯ LINK token address - uint32 stalenessThreshold; // The amount of time a gas price can be stale before it is considered invalid. - } - - /// @notice The struct representing the received CCIP feed report from keystone IReceiver.onReport() - struct ReceivedCCIPFeedReport { - address token; // Token address - uint224 price; // ─────────╮ Price of the token in USD with 18 decimals - uint32 timestamp; // ──────╯ Timestamp of the price update - } - error TokenNotSupported(address token); error ChainNotSupported(uint64 chain); error StaleGasPrice(uint64 destChainSelector, uint256 threshold, uint256 timePassed); @@ -82,6 +62,28 @@ contract PriceRegistry is event DestChainConfigUpdated(uint64 indexed destChainSelector, DestChainConfig destChainConfig); event DestChainAdded(uint64 indexed destChainSelector, DestChainConfig destChainConfig); + /// @notice Token price data feed update + struct TokenPriceFeedUpdate { + address sourceToken; // Source token to update feed for + IPriceRegistry.TokenPriceFeedConfig feedConfig; // Feed config update data + } + + /// @dev Struct that contains the static configuration + /// RMN depends on this struct, if changing, please notify the RMN maintainers. + // solhint-disable-next-line gas-struct-packing + struct StaticConfig { + uint96 maxFeeJuelsPerMsg; // ─╮ Maximum fee that can be charged for a message + address linkToken; // ────────╯ LINK token address + uint32 stalenessThreshold; // The amount of time a gas price can be stale before it is considered invalid. + } + + /// @notice The struct representing the received CCIP feed report from keystone IReceiver.onReport() + struct ReceivedCCIPFeedReport { + address token; // Token address + uint224 price; // ─────────╮ Price of the token in USD with 18 decimals + uint32 timestamp; // ──────╯ Timestamp of the price update + } + /// @dev Struct to hold the fee & validation configs for a destination chain struct DestChainConfig { bool isEnabled; // ──────────────────────────╮ Whether this destination chain is enabled @@ -99,7 +101,7 @@ contract PriceRegistry is uint32 defaultTokenDestBytesOverhead; // ────╮ Default extra data availability bytes charged per token transfer uint32 defaultTxGasLimit; // │ Default gas limit for a tx uint64 gasMultiplierWeiPerEth; // │ Multiplier for gas costs, 1e18 based so 11e17 = 10% extra cost. - uint32 networkFeeUSDCents; // │ Flat network fee to charge for messages, multiples of 0.01 USD + uint32 networkFeeUSDCents; // │ Flat network fee to charge for messages, multiples of 0.01 USD bool enforceOutOfOrder; // │ Whether to enforce the allowOutOfOrderExecution extraArg value to be true. bytes4 chainFamilySelector; // ──────────────╯ Selector that identifies the destination chain's family. Used to determine the correct validations to perform for the dest chain. } @@ -128,7 +130,7 @@ contract PriceRegistry is /// that an array of these can be passed in the TokenTransferFeeConfigArgs struct to set the mapping struct TokenTransferFeeConfigSingleTokenArgs { address token; // Token address - TokenTransferFeeConfig tokenTransferFeeConfig; // struct to hold the transfer fee configuration for token transfers + TokenTransferFeeConfig tokenTransferFeeConfig; // Struct to hold the transfer fee configuration for token transfers } /// @dev Struct to hold the token transfer fee configurations for a destination chain and a set of tokens. Same as TokenTransferFeeConfigSingleTokenArgs @@ -193,9 +195,9 @@ contract PriceRegistry is /// @dev The link token address address internal immutable i_linkToken; - // Subset of tokens which prices tracked by this registry which are fee tokens. + /// @dev Subset of tokens which prices tracked by this registry which are fee tokens. EnumerableSet.AddressSet private s_feeTokens; - // The amount of time a gas price can be stale before it is considered invalid. + /// @dev The amount of time a gas price can be stale before it is considered invalid. uint32 private immutable i_stalenessThreshold; constructor( @@ -310,9 +312,9 @@ contract PriceRegistry is return (fromTokenAmount * _getValidatedTokenPrice(fromToken)) / _getValidatedTokenPrice(toToken); } - /// @notice Gets the token price for a given token and revert if the token is not supported + /// @notice Gets the token price for a given token and reverts if the token is not supported /// @param token The address of the token to get the price for - /// @return the token price + /// @return tokenPriceValue The token price function _getValidatedTokenPrice(address token) internal view returns (uint224) { Internal.TimestampedPackedUint224 memory tokenPrice = getTokenPrice(token); // Token price must be set at least once @@ -360,9 +362,9 @@ contract PriceRegistry is } /// @notice Add and remove tokens from feeTokens set. + /// @param feeTokensToRemove The addresses of the tokens which are no longer considered feeTokens. /// @param feeTokensToAdd The addresses of the tokens which are now considered fee tokens /// and can be used to calculate fees. - /// @param feeTokensToRemove The addresses of the tokens which are no longer considered feeTokens. function applyFeeTokensUpdates( address[] memory feeTokensToAdd, address[] memory feeTokensToRemove @@ -371,9 +373,9 @@ contract PriceRegistry is } /// @notice Add and remove tokens from feeTokens set. + /// @param feeTokensToRemove The addresses of the tokens which are no longer considered feeTokens. /// @param feeTokensToAdd The addresses of the tokens which are now considered fee tokens /// and can be used to calculate fees. - /// @param feeTokensToRemove The addresses of the tokens which are no longer considered feeTokens. function _applyFeeTokensUpdates(address[] memory feeTokensToAdd, address[] memory feeTokensToRemove) private { for (uint256 i = 0; i < feeTokensToAdd.length; ++i) { if (s_feeTokens.add(feeTokensToAdd[i])) { @@ -538,7 +540,7 @@ contract PriceRegistry is return ((premiumFee * premiumMultiplierWeiPerEth) + executionCost + dataAvailabilityCost) / feeTokenPrice; } - /// @notice Sets the fee configuration for a token + /// @notice Sets the fee configuration for a token. /// @param premiumMultiplierWeiPerEthArgs Array of PremiumMultiplierWeiPerEthArgs structs. function applyPremiumMultiplierWeiPerEthUpdates( PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs @@ -708,6 +710,7 @@ contract PriceRegistry is /// @notice Gets the transfer fee config for a given token. /// @param destChainSelector The destination chain selector. /// @param token The token address. + /// @return tokenTransferFeeConfig The transfer fee config for the token. function getTokenTransferFeeConfig( uint64 destChainSelector, address token @@ -762,19 +765,19 @@ contract PriceRegistry is // ================================================================ /// @notice Validates that the destAddress matches the expected format of the family. - /// @param chainFamilySelector Tag to identify the target family - /// @param destAddress Dest address to validate - /// @dev precondition - assumes the family tag is correct and validated + /// @param chainFamilySelector Tag to identify the target family. + /// @param destAddress Dest address to validate. + /// @dev precondition - assumes the family tag is correct and validated. function _validateDestFamilyAddress(bytes4 chainFamilySelector, bytes memory destAddress) internal pure { if (chainFamilySelector == Internal.CHAIN_FAMILY_SELECTOR_EVM) { Internal._validateEVMAddress(destAddress); } } - /// @dev Convert the extra args bytes into a struct with validations against the dest chain config - /// @param extraArgs The extra args bytes - /// @param destChainConfig Dest chain config to validate against - /// @return EVMExtraArgs the extra args struct (latest version) + /// @dev Convert the extra args bytes into a struct with validations against the dest chain config. + /// @param extraArgs The extra args bytes. + /// @param destChainConfig Dest chain config to validate against. + /// @return evmExtraArgs The EVMExtraArgs struct (latest version). function _parseEVMExtraArgsFromBytes( bytes calldata extraArgs, DestChainConfig memory destChainConfig @@ -790,9 +793,9 @@ contract PriceRegistry is return evmExtraArgs; } - /// @dev Convert the extra args bytes into a struct - /// @param extraArgs The extra args bytes - /// @param defaultTxGasLimit default tx gas limit to use in the absence of extra args + /// @dev Convert the extra args bytes into a struct. + /// @param extraArgs The extra args bytes. + /// @param defaultTxGasLimit default tx gas limit to use in the absence of extra args. /// @return EVMExtraArgs the extra args struct (latest version) function _parseUnvalidatedEVMExtraArgsFromBytes( bytes calldata extraArgs, @@ -818,11 +821,11 @@ contract PriceRegistry is } /// @notice Validate the forwarded message to ensure it matches the configuration limits (message length, number of tokens) - /// and family-specific expectations (address format) - /// @param destChainConfig Dest chain config + /// and family-specific expectations (address format). + /// @param destChainConfig The destination chain config. /// @param dataLength The length of the data field of the message. /// @param numberOfTokens The number of tokens to be sent. - /// @param receiver Message receiver on the dest chain + /// @param receiver Message receiver on the dest chain. function _validateMessage( DestChainConfig memory destChainConfig, uint256 dataLength, @@ -892,9 +895,9 @@ contract PriceRegistry is // │ Configs │ // ================================================================ - /// @notice Returns the configured config for the dest chain selector - /// @param destChainSelector destination chain selector to fetch config for - /// @return destChainConfig config for the dest chain + /// @notice Returns the configured config for the dest chain selector. + /// @param destChainSelector Destination chain selector to fetch config for. + /// @return destChainConfig Config for the destination chain. function getDestChainConfig(uint64 destChainSelector) external view returns (DestChainConfig memory) { return s_destChainConfigs[destChainSelector]; } @@ -934,8 +937,8 @@ contract PriceRegistry is } /// @notice Returns the static PriceRegistry config. - /// @dev RMN depends on this function, if changing, please notify the RMN maintainers. - /// @return the configuration. + /// @dev RMN depends on this function, if updated, please notify the RMN maintainers. + /// @return staticConfig The static configuration. function getStaticConfig() external view returns (StaticConfig memory) { return StaticConfig({ maxFeeJuelsPerMsg: i_maxFeeJuelsPerMsg, diff --git a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol index 6d310f989b..9e43f23f66 100644 --- a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol +++ b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol @@ -105,6 +105,8 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator } /// @notice Returns all the chain configurations. + /// @param pageIndex The page index. + /// @param pageSize The page size. /// @return paginatedChainConfigs chain configurations. function getAllChainConfigs( uint256 pageIndex, @@ -181,6 +183,10 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator } } + /// @notice Sets a new OCR3 config for a specific plugin type for a DON. + /// @param donId The DON ID. + /// @param pluginType The plugin type. + /// @param newConfig The new configuration. function _updatePluginConfig( uint32 donId, Internal.OCRPluginType pluginType, @@ -221,11 +227,14 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator return CCIPConfigTypes.ConfigState(configLen); } - // the only valid state transitions are the following: - // init -> running (first ever config) - // running -> staging (blue/green proposal) - // staging -> running (promotion) - // everything else is invalid and should revert. + /// @notice Validates the state transition between two config states. + /// The only valid state transitions are the following: + /// Init -> Running (first ever config) + /// Running -> Staging (blue/green proposal) + /// Staging -> Running (promotion) + /// Everything else is invalid and should revert. + /// @param currentState The current state. + /// @param newState The new state. function _validateConfigStateTransition( CCIPConfigTypes.ConfigState currentState, CCIPConfigTypes.ConfigState newState @@ -244,6 +253,9 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator revert InvalidConfigStateTransition(currentState, newState); } + /// @notice Validates the transition between two OCR3 configurations. + /// @param currentConfig The current configuration with metadata. + /// @param newConfigWithMeta The new configuration with metadata. function _validateConfigTransition( CCIPConfigTypes.OCR3ConfigWithMeta[] memory currentConfig, CCIPConfigTypes.OCR3ConfigWithMeta[] memory newConfigWithMeta @@ -332,6 +344,8 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator /// @notice Group the OCR3 configurations by plugin type for further processing. /// @param ocr3Configs The OCR3 configurations to group. + /// @return commitConfigs The commit configurations. + /// @return execConfigs The execution configurations. function _groupByPluginType(CCIPConfigTypes.OCR3Config[] memory ocr3Configs) internal pure @@ -368,6 +382,8 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator return (commitConfigs, execConfigs); } + /// @notice Validates an OCR3 configuration. + /// @param cfg The OCR3 configuration. function _validateConfig(CCIPConfigTypes.OCR3Config memory cfg) internal view { if (cfg.chainSelector == 0) revert ChainSelectorNotSet(); if (cfg.pluginType != Internal.OCRPluginType.Commit && cfg.pluginType != Internal.OCRPluginType.Execution) { diff --git a/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRampClient.sol b/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRampClient.sol index 1744d6c229..1dfae1abbc 100644 --- a/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRampClient.sol +++ b/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRampClient.sol @@ -33,6 +33,7 @@ interface IEVM2AnyOnRampClient { /// @param message Message struct to send /// @param feeTokenAmount Amount of fee tokens for payment /// @param originalSender The original initiator of the CCIP request + /// @return messageId The message id function forwardFromRouter( uint64 destChainSelector, Client.EVM2AnyMessage memory message, diff --git a/contracts/src/v0.8/ccip/interfaces/INonceManager.sol b/contracts/src/v0.8/ccip/interfaces/INonceManager.sol index 52408ae4f5..3a6eff65c7 100644 --- a/contracts/src/v0.8/ccip/interfaces/INonceManager.sol +++ b/contracts/src/v0.8/ccip/interfaces/INonceManager.sol @@ -3,18 +3,18 @@ pragma solidity ^0.8.0; /// @notice Contract interface that allows managing sender nonces interface INonceManager { - /// @notice Increments the outbound nonce for a given sender on a given destination chain - /// @param destChainSelector The destination chain selector - /// @param sender The sender address - /// @return The new outbound nonce + /// @notice Increments the outbound nonce for a given sender on a given destination chain. + /// @param destChainSelector The destination chain selector. + /// @param sender The sender address. + /// @return incrementedOutboundNonce The new outbound nonce. function getIncrementedOutboundNonce(uint64 destChainSelector, address sender) external returns (uint64); - /// @notice Increments the inbound nonce for a given sender on a given source chain - /// @notice The increment is only applied if the resulting nonce matches the expectedNonce - /// @param sourceChainSelector The destination chain selector - /// @param expectedNonce The expected inbound nonce - /// @param sender The encoded sender address - /// @return True if the nonce was incremented, false otherwise + /// @notice Increments the inbound nonce for a given sender on a given source chain. + /// @notice The increment is only applied if the resulting nonce matches the expectedNonce. + /// @param sourceChainSelector The destination chain selector. + /// @param expectedNonce The expected inbound nonce. + /// @param sender The encoded sender address. + /// @return incremented True if the nonce was incremented, false otherwise. function incrementInboundNonce( uint64 sourceChainSelector, uint64 expectedNonce, diff --git a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol index 8a20299371..a29db78e04 100644 --- a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol +++ b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol @@ -32,7 +32,7 @@ interface IPriceRegistry { /// @notice Returns the token price data feed configuration /// @param token The token to retrieve the feed config for - /// @return dataFeedAddress The token price data feed config (if feed address is 0, the feed config is disabled) + /// @return tokenPriceFeedConfig The token price data feed config (if feed address is 0, the feed config is disabled) function getTokenPriceFeedConfig(address token) external view returns (TokenPriceFeedConfig memory); /// @notice Get an encoded `gasPrice` for a given destination chain ID. @@ -70,7 +70,7 @@ interface IPriceRegistry { ) external view returns (uint256 toTokenAmount); /// @notice Get the list of fee tokens. - /// @return The tokens set as fee tokens. + /// @return feeTokens The tokens set as fee tokens. function getFeeTokens() external view returns (address[] memory); /// @notice Validates the ccip message & returns the fee diff --git a/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol b/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol index 1872ae276c..0b90f88c11 100644 --- a/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol +++ b/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol @@ -10,7 +10,7 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { // Maximum number of oracles the offchain reporting protocol is designed for uint256 internal constant MAX_NUM_ORACLES = 31; - /// @notice triggers a new run of the offchain reporting protocol + /// @notice Triggers a new run of the offchain reporting protocol /// @param ocrPluginType OCR plugin type for which the config was set /// @param configDigest configDigest of this configuration /// @param signers ith element is address ith oracle uses to sign a report @@ -18,7 +18,7 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { /// @param F maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly event ConfigSet(uint8 ocrPluginType, bytes32 configDigest, address[] signers, address[] transmitters, uint8 F); - /// @notice optionally emitted to indicate the latest configDigest and sequence number + /// @notice Optionally emitted to indicate the latest configDigest and sequence number /// for which a report was successfully transmitted. Alternatively, the contract may /// use latestConfigDigestAndEpoch with scanLogs set to false. event Transmitted(uint8 indexed ocrPluginType, bytes32 configDigest, uint64 sequenceNumber); @@ -71,14 +71,14 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { Role role; // ─────╯ Role of the address which mapped to this struct } - /// @notice OCR configuration for a single OCR plugin within a DON + /// @notice OCR configuration for a single OCR plugin within a DON. struct OCRConfig { ConfigInfo configInfo; // latest OCR config address[] signers; // addresses oracles use to sign the reports address[] transmitters; // addresses oracles use to transmit the reports } - /// @notice Args to update an OCR Config + /// @notice Args to update an OCR Config. struct OCRConfigArgs { bytes32 configDigest; // Config digest to update to uint8 ocrPluginType; // ──────────────────╮ OCR plugin type to update config for @@ -98,15 +98,15 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { // See the "If we wanted to call sam" example on for example reasoning // https://solidity.readthedocs.io/en/v0.7.2/abi-spec.html - /// @notice constant length component for transmit functions with no signatures. - /// The signatures are expected to match transmitPlugin(reportContext, report) + /// @notice Constant length component for transmit functions with no signatures. + /// The signatures are expected to match transmitPlugin(reportContext, report). uint16 private constant TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT_NO_SIGNATURES = 4 // function selector + 3 * 32 // 3 words containing reportContext + 32 // word containing start location of abiencoded report value + 32; // word containing length of report - /// @notice extra constant length component for transmit functions with signatures (relative to no signatures) - /// The signatures are expected to match transmitPlugin(reportContext, report, rs, ss, rawVs) + /// @notice Extra constant length component for transmit functions with signatures (relative to no signatures). + /// The signatures are expected to match transmitPlugin(reportContext, report, rs, ss, rawVs). uint16 private constant TRANSMIT_MSGDATA_EXTRA_CONSTANT_LENGTH_COMPONENT_FOR_SIGNATURES = 32 // word containing location start of abiencoded rs value + 32 // word containing start location of abiencoded ss value + 32 // rawVs value @@ -119,18 +119,18 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { i_chainID = block.chainid; } - /// @notice sets offchain reporting protocol configuration incl. participating oracles + /// @notice Sets offchain reporting protocol configuration incl. participating oracles. /// NOTE: The OCR3 config must be sanity-checked against the home-chain registry configuration, to ensure /// home-chain and remote-chain parity! - /// @param ocrConfigArgs OCR config update args + /// @param ocrConfigArgs OCR config update args. function setOCR3Configs(OCRConfigArgs[] memory ocrConfigArgs) external onlyOwner { for (uint256 i; i < ocrConfigArgs.length; ++i) { _setOCR3Config(ocrConfigArgs[i]); } } - /// @notice sets offchain reporting protocol configuration incl. participating oracles for a single OCR plugin type - /// @param ocrConfigArgs OCR config update args + /// @notice Sets offchain reporting protocol configuration incl. participating oracles for a single OCR plugin type. + /// @param ocrConfigArgs OCR config update args. function _setOCR3Config(OCRConfigArgs memory ocrConfigArgs) internal { if (ocrConfigArgs.F == 0) revert InvalidConfig(InvalidConfigErrorType.F_MUST_BE_POSITIVE); @@ -180,23 +180,23 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { _afterOCR3ConfigSet(ocrPluginType); } - /// @notice Hook that is called after a plugin's OCR3 config changes - /// @param ocrPluginType Plugin type for which the config changed + /// @notice Hook that is called after a plugin's OCR3 config changes. + /// @param ocrPluginType Plugin type for which the config changed. function _afterOCR3ConfigSet(uint8 ocrPluginType) internal virtual; - /// @notice Clears oracle roles for the provided oracle addresses - /// @param ocrPluginType OCR plugin type to clear roles for - /// @param oracleAddresses Oracle addresses to clear roles for + /// @notice Clears oracle roles for the provided oracle addresses. + /// @param ocrPluginType OCR plugin type to clear roles for. + /// @param oracleAddresses Oracle addresses to clear roles for. function _clearOracleRoles(uint8 ocrPluginType, address[] memory oracleAddresses) internal { for (uint256 i = 0; i < oracleAddresses.length; ++i) { delete s_oracles[ocrPluginType][oracleAddresses[i]]; } } - /// @notice Assigns oracles roles for the provided oracle addresses with uniqueness verification - /// @param ocrPluginType OCR plugin type to assign roles for - /// @param oracleAddresses Oracle addresses to assign roles to - /// @param role Role to assign + /// @notice Assigns oracles roles for the provided oracle addresses with uniqueness verification. + /// @param ocrPluginType OCR plugin type to assign roles for. + /// @param oracleAddresses Oracle addresses to assign roles to. + /// @param role Role to assign. function _assignOracleRoles(uint8 ocrPluginType, address[] memory oracleAddresses, Role role) internal { for (uint8 i = 0; i < oracleAddresses.length; ++i) { address oracle = oracleAddresses[i]; @@ -212,9 +212,9 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { /// The function should be called after the per-DON reporting logic is completed. /// @param ocrPluginType OCR plugin type to transmit report for /// @param report serialized report, which the signatures are signing. - /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries - /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries - /// @param rawVs ith element is the the V component of the ith signature + /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries. + /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries. + /// @param rawVs ith element is the the V component of the ith signature. function _transmit( uint8 ocrPluginType, // NOTE: If these parameters are changed, expectedMsgDataLength and/or @@ -280,12 +280,12 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { emit Transmitted(ocrPluginType, configDigest, uint64(uint256(reportContext[1]))); } - /// @notice verifies the signatures of a hashed report value for one OCR plugin type - /// @param ocrPluginType OCR plugin type to transmit report for - /// @param hashedReport hashed encoded packing of report + reportContext - /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries - /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries - /// @param rawVs ith element is the the V component of the ith signature + /// @notice Verifies the signatures of a hashed report value for one OCR plugin type. + /// @param ocrPluginType OCR plugin type to transmit report for. + /// @param hashedReport hashed encoded packing of report + reportContext. + /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries. + /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries. + /// @param rawVs ith element is the the V component of the ith signature. function _verifySignatures( uint8 ocrPluginType, bytes32 hashedReport, @@ -309,14 +309,14 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { } } - /// @notice Validates that the chain ID has not diverged after deployment. Reverts if the chain IDs do not match + /// @notice Validates that the chain ID has not diverged after deployment. Reverts if the chain IDs do not match. function _whenChainNotForked() internal view { if (i_chainID != block.chainid) revert ForkedChain(i_chainID, block.chainid); } - /// @notice information about current offchain reporting protocol configuration - /// @param ocrPluginType OCR plugin type to return config details for - /// @return ocrConfig OCR config for the plugin type + /// @notice Information about current offchain reporting protocol configuration. + /// @param ocrPluginType OCR plugin type to return config details for. + /// @return ocrConfig OCR config for the plugin type. function latestConfigDetails(uint8 ocrPluginType) external view returns (OCRConfig memory ocrConfig) { return s_ocrConfigs[ocrPluginType]; } diff --git a/contracts/src/v0.8/ccip/offRamp/OffRamp.sol b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol index de03e5fac7..3f98d55e81 100644 --- a/contracts/src/v0.8/ccip/offRamp/OffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol @@ -26,7 +26,7 @@ import {ERC165Checker} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts /// in an OffRamp in a single transaction. /// @dev The OnRamp and OffRamp form an xchain upgradeable unit. Any change to one of them /// results an onchain upgrade of both contracts. -/// @dev MultiOCR3Base is used to store multiple OCR configs for both the OffRamp and the CommitStore. +/// @dev MultiOCR3Base is used to store multiple OCR configs for the OffRamp. /// The execution plugin type has to be configured without signature verification, and the commit /// plugin type with verification. contract OffRamp is ITypeAndVersion, MultiOCR3Base { @@ -79,13 +79,13 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { event CommitReportAccepted(CommitReport report); event RootRemoved(bytes32 root); - /// @notice Static offRamp config + /// @notice Struct that contains the static configuration /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. struct StaticConfig { uint64 chainSelector; // ───╮ Destination chainSelector address rmnProxy; // ───────╯ RMN proxy address address tokenAdminRegistry; // Token admin registry address - address nonceManager; // Address of the nonce manager + address nonceManager; // Nonce manager address } /// @notice Per-chain source config (defining a lane from a Source Chain -> Dest OffRamp) @@ -96,7 +96,8 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { bytes onRamp; // OnRamp address on the source chain } - /// @notice SourceChainConfig update args scoped to one source chain + /// @notice Same as SourceChainConfig but with source chain selector so that an array of these + /// can be passed in the constructor and the applySourceChainConfigUpdates function. struct SourceChainConfigArgs { IRouter router; // ────────────────╮ Local router to use for messages coming from this source chain uint64 sourceChainSelector; // | Source chain selector of the config to update @@ -105,7 +106,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { } /// @notice Dynamic offRamp config - /// @dev since OffRampConfig is part of OffRampConfigChanged event, if changing it, we should update the ABI on Atlas + /// @dev Since DynamicConfig is part of DynamicConfigSet event, if changing it, we should update the ABI on Atlas struct DynamicConfig { address priceRegistry; // ──────────────────────────╮ Price registry address on the local chain uint32 permissionLessExecutionThresholdSeconds; // │ Waiting time before manual execution is enabled @@ -155,7 +156,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { // DYNAMIC CONFIG DynamicConfig internal s_dynamicConfig; - /// @notice SourceConfig per chain + /// @notice SourceChainConfig per chain /// (forms lane configurations from sourceChainSelector => StaticConfig.chainSelector) mapping(uint64 sourceChainSelector => SourceChainConfig sourceChainConfig) internal s_sourceChainConfigs; @@ -166,7 +167,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { mapping(uint64 sourceChainSelector => mapping(uint64 seqNum => uint256 executionStateBitmap)) internal s_executionStates; - // sourceChainSelector => merkleRoot => timestamp when received + /// @notice Commit timestamp of merkle roots per source chain mapping(uint64 sourceChainSelector => mapping(bytes32 merkleRoot => uint256 timestamp)) internal s_roots; /// @dev The sequence number of the last price update uint64 private s_latestPriceSequenceNumber; @@ -213,8 +214,8 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @notice Returns the current execution state of a message based on its sequenceNumber. /// @param sourceChainSelector The source chain to get the execution state for /// @param sequenceNumber The sequence number of the message to get the execution state for. - /// @return The current execution state of the message. - /// @dev we use the literal number 128 because using a constant increased gas usage. + /// @return executionState The current execution state of the message. + /// @dev We use the literal number 128 because using a constant increased gas usage. function getExecutionState( uint64 sourceChainSelector, uint64 sequenceNumber @@ -231,7 +232,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @param sourceChainSelector The source chain to set the execution state for /// @param sequenceNumber The sequence number for which the state will be saved. /// @param newState The new value the state will be in after this function is called. - /// @dev we use the literal number 128 because using a constant increased gas usage. + /// @dev We use the literal number 128 because using a constant increased gas usage. function _setExecutionState( uint64 sourceChainSelector, uint64 sequenceNumber, @@ -239,7 +240,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { ) internal { uint256 offset = (sequenceNumber % 128) * MESSAGE_EXECUTION_STATE_BIT_WIDTH; uint256 bitmap = _getSequenceNumberBitmap(sourceChainSelector, sequenceNumber); - // to unset any potential existing state we zero the bits of the section the state occupies, + // To unset any potential existing state we zero the bits of the section the state occupies, // then we do an AND operation to blank out any existing state for the section. bitmap &= ~(MESSAGE_EXECUTION_STATE_MASK << offset); // Set the new state @@ -358,7 +359,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { revert InvalidMessageDestChainSelector(message.header.destChainSelector); } - // We do this hash here instead of in _verifyMessages to avoid two separate loops + // We do this hash here instead of in _verify to avoid two separate loops // over the same data, which increases gas cost. // Hashing all of the message fields ensures that the message being executed is correct and not tampered with. // Including the known OnRamp ensures that the message originates from the correct on ramp version @@ -422,6 +423,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { // FAILURE -> FAILURE no nonce bump // FAILURE -> SUCCESS no nonce bump // UNTOUCHED messages MUST be executed in order always + // If nonce == 0 then out of order execution is allowed if (message.header.nonce != 0) { if (originalState == Internal.MessageExecutionState.UNTOUCHED) { // If a nonce is not incremented, that means it was skipped, and we can ignore the message @@ -480,12 +482,12 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @notice Try executing a message. /// @param message Internal.Any2EVMRampMessage memory message. /// @param offchainTokenData Data provided by the DON for token transfers. - /// @return the new state of the message, being either SUCCESS or FAILURE. - /// @return revert data in bytes if CCIP receiver reverted during execution. + /// @return executionState The new state of the message, being either SUCCESS or FAILURE. + /// @return errData Revert data in bytes if CCIP receiver reverted during execution. function _trialExecute( Internal.Any2EVMRampMessage memory message, bytes[] memory offchainTokenData - ) internal returns (Internal.MessageExecutionState, bytes memory) { + ) internal returns (Internal.MessageExecutionState executionState, bytes memory) { try this.executeSingleMessage(message, offchainTokenData) {} catch (bytes memory err) { // return the message execution state as FAILURE and the revert data @@ -496,7 +498,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { return (Internal.MessageExecutionState.SUCCESS, ""); } - /// @notice Execute a single message. + /// @notice Executes a single message. /// @param message The message that will be executed. /// @param offchainTokenData Token transfer data to be passed to TokenPool. /// @dev We make this external and callable by the contract itself, in order to try/catch @@ -563,12 +565,12 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// 1. Price updates /// 2. A batch of merkle root and sequence number intervals (per-source) /// Both have their own, separate, staleness checks, with price updates using the epoch and round - /// number of the latest price update. The merkle root checks for staleness based on the seqNums. + /// number of the latest price update. The merkle root checks for staleness are based on the seqNums. /// They need to be separate because a price report for round t+2 might be included before a report /// containing a merkle root for round t+1. This merkle root report for round t+1 is still valid /// and should not be rejected. When a report with a stale root but valid price updates is submitted, /// we are OK to revert to preserve the invariant that we always revert on invalid sequence number ranges. - /// If that happens, prices will be updates in later rounds. + /// If that happens, prices will be updated in later rounds. function commit( bytes32[3] calldata reportContext, bytes calldata report, @@ -604,7 +606,6 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { _whenNotCursed(sourceChainSelector); SourceChainConfig storage sourceChainConfig = _getEnabledSourceChainConfig(sourceChainSelector); - // If we reached this section, the report should contain a valid root if (sourceChainConfig.minSeqNr != root.interval.min || root.interval.min > root.interval.max) { revert InvalidInterval(root.sourceChainSelector, root.interval); } @@ -612,7 +613,8 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { // TODO: confirm how RMN offchain blessing impacts commit report bytes32 merkleRoot = root.merkleRoot; if (merkleRoot == bytes32(0)) revert InvalidRoot(); - // Disallow duplicate roots as that would reset the timestamp and + // If we reached this section, the report should contain a valid root + // We disallow duplicate roots as that would reset the timestamp and // delay potential manual execution. if (s_roots[root.sourceChainSelector][merkleRoot] != 0) { revert RootAlreadyCommitted(root.sourceChainSelector, merkleRoot); @@ -628,7 +630,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { } /// @notice Returns the sequence number of the last price update. - /// @return the latest price update sequence number. + /// @return sequenceNumber The latest price update sequence number. function getLatestPriceSequenceNumber() external view returns (uint64) { return s_latestPriceSequenceNumber; } @@ -637,7 +639,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// If the root was never committed 0 will be returned. /// @param sourceChainSelector The source chain selector. /// @param root The merkle root to check the commit status for. - /// @return the timestamp of the committed root or zero in the case that it was never + /// @return timestamp The timestamp of the committed root or zero in the case that it was never /// committed. function getMerkleRoot(uint64 sourceChainSelector, bytes32 root) external view returns (uint256) { return s_roots[sourceChainSelector][root]; @@ -645,7 +647,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @notice Returns if a root is blessed or not. /// @param root The merkle root to check the blessing status for. - /// @return whether the root is blessed or not. + /// @return blessed Whether the root is blessed or not. function isBlessed(bytes32 root) public view returns (bool) { // TODO: update RMN to also consider the source chain selector for blessing return IRMN(i_rmnProxy).isBlessed(IRMN.TaggedRoot({commitStore: address(this), root: root})); @@ -669,6 +671,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @dev This method uses a merkle tree within a merkle tree, with the hashedLeaves, /// proofs and proofFlagBits being used to get the root of the inner tree. /// This root is then used as the singular leaf of the outer tree. + /// @return timestamp The commit timestamp of the root function _verify( uint64 sourceChainSelector, bytes32[] memory hashedLeaves, @@ -701,6 +704,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @notice Returns the static config. /// @dev This function will always return the same struct as the contents is static and can never change. /// RMN depends on this function, if changing, please notify the RMN maintainers. + /// @return staticConfig The static config. function getStaticConfig() external view returns (StaticConfig memory) { return StaticConfig({ chainSelector: i_chainSelector, @@ -711,14 +715,14 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { } /// @notice Returns the current dynamic config. - /// @return The current config. + /// @return dynamicConfig The current dynamic config. function getDynamicConfig() external view returns (DynamicConfig memory) { return s_dynamicConfig; } /// @notice Returns the source chain config for the provided source chain selector /// @param sourceChainSelector chain to retrieve configuration for - /// @return SourceChainConfig config for the source chain + /// @return sourceChainConfig The config for the source chain function getSourceChainConfig(uint64 sourceChainSelector) external view returns (SourceChainConfig memory) { return s_sourceChainConfigs[sourceChainSelector]; } @@ -787,7 +791,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @notice Returns a source chain config with a check that the config is enabled /// @param sourceChainSelector Source chain selector to check for cursing - /// @return sourceChainConfig Source chain config + /// @return sourceChainConfig The source chain config storage pointer function _getEnabledSourceChainConfig(uint64 sourceChainSelector) internal view returns (SourceChainConfig storage) { SourceChainConfig storage sourceChainConfig = s_sourceChainConfigs[sourceChainSelector]; if (!sourceChainConfig.isEnabled) { @@ -840,7 +844,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { // address is a (compatible) pool contract. _callWithExactGasSafeReturnData will check if the location // contains a contract. If it doesn't it reverts with a known error, which we catch gracefully. // We call the pool with exact gas to increase resistance against malicious tokens or token pools. - // We protects against return data bombs by capping the return data size at MAX_RET_BYTES. + // We protect against return data bombs by capping the return data size at MAX_RET_BYTES. (bool success, bytes memory returnData, uint256 gasUsedReleaseOrMint) = CallWithExactGas ._callWithExactGasSafeReturnData( abi.encodeCall( @@ -862,7 +866,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { Internal.MAX_RET_BYTES ); - // wrap and rethrow the error so we can catch it lower in the stack + // Wrap and rethrow the error so we can catch it lower in the stack if (!success) revert TokenHandlingError(returnData); // If the call was successful, the returnData should be the local token address. @@ -885,6 +889,12 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { return Client.EVMTokenAmount({token: localToken, amount: localAmount}); } + /// @notice Retrieves the balance of a receiver address for a given token. + /// @param receiver The address to check the balance of. + /// @param token The token address. + /// @param gasLimit The gas limit to use for the call. + /// @return balance The balance of the receiver. + /// @return gasLeft The gas left after the call. function _getBalanceOfReceiver( address receiver, address token, @@ -913,10 +923,10 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @param sourceTokenAmounts List of token amounts with source data of the tokens to be released/minted. /// @param originalSender The message sender on the source chain. /// @param receiver The address that will receive the tokens. - /// @param sourceChainSelector The remote source chain selector + /// @param sourceChainSelector The remote source chain selector. /// @param offchainTokenData Array of token data fetched offchain by the DON. /// @return destTokenAmounts local token addresses with amounts - /// @dev This function wrappes the token pool call in a try catch block to gracefully handle + /// @dev This function wraps the token pool call in a try catch block to gracefully handle /// any non-rate limiting errors that may occur. If we encounter a rate limiting related error /// we bubble it up. If we encounter a non-rate limiting error we wrap it in a TokenHandlingError. function _releaseOrMintTokens( diff --git a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol index 60d41894fa..dc25354668 100644 --- a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol @@ -21,8 +21,8 @@ import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; /// @notice The OnRamp is a contract that handles lane-specific fee logic -/// @dev The OnRamp, MultiCommitStore and OffRamp form an xchain upgradeable unit. Any change to one of them -/// results an onchain upgrade of all 3. +/// @dev The OnRamp and OffRamp form an xchain upgradeable unit. Any change to one of them +/// results in an onchain upgrade of all 3. contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { using SafeERC20 for IERC20; using USDPriceWith18Decimals for uint224; @@ -47,13 +47,13 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { /// RMN depends on this struct, if changing, please notify the RMN maintainers. // solhint-disable-next-line gas-struct-packing struct StaticConfig { - uint64 chainSelector; // ─────╮ Source chainSelector - address rmnProxy; // ─────────╯ Address of RMN proxy - address nonceManager; // Address of the nonce manager + uint64 chainSelector; // ─────╮ Source chain selector + address rmnProxy; // ─────────╯ RMN proxy address + address nonceManager; // Nonce manager address address tokenAdminRegistry; // Token admin registry address } - /// @dev Struct to contains the dynamic configuration + /// @dev Struct that contains the dynamic configuration // solhint-disable-next-line gas-struct-packing struct DynamicConfig { address priceRegistry; // Price registry address @@ -63,7 +63,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { /// @dev Struct to hold the configs for a destination chain struct DestChainConfig { - // The last used sequence number. This is zero in the case where no messages has been sent yet. + // The last used sequence number. This is zero in the case where no messages have yet been sent. // 0 is not a valid sequence number for any real transaction. uint64 sequenceNumber; // This is the local router address that is allowed to send messages to the destination chain. @@ -89,10 +89,9 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { address internal immutable i_nonceManager; /// @dev The address of the token admin registry address internal immutable i_tokenAdminRegistry; - /// @dev the maximum number of nops that can be configured at the same time. // DYNAMIC CONFIG - /// @dev The config for the onRamp + /// @dev The dynamic config for the onRamp DynamicConfig internal s_dynamicConfig; /// @dev The destination chain specific configs @@ -125,7 +124,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { /// @notice Gets the next sequence number to be used in the onRamp /// @param destChainSelector The destination chain selector - /// @return the next sequence number to be used + /// @return nextSequenceNumber The next sequence number to be used function getExpectedNextSequenceNumber(uint64 destChainSelector) external view returns (uint64) { return s_destChainConfigs[destChainSelector].sequenceNumber + 1; } @@ -184,7 +183,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { tokenAmounts: new Internal.RampTokenAmount[](message.tokenAmounts.length) }); - // Lock the tokens as last step. TokenPools may not always be trusted. + // Lock / burn the tokens as last step. TokenPools may not always be trusted. // There should be no state changes after external call to TokenPools. for (uint256 i = 0; i < message.tokenAmounts.length; ++i) { newMessage.tokenAmounts[i] = @@ -216,10 +215,10 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { /// @notice Uses a pool to lock or burn a token /// @param tokenAndAmount Token address and amount to lock or burn - /// @param destChainSelector Target dest chain selector of the message + /// @param destChainSelector Target destination chain selector of the message /// @param receiver Message receiver /// @param originalSender Message sender - /// @return rampTokenAndAmount Ramp token and amount data + /// @return rampTokenAmount Ramp token and amount data function _lockOrBurnSingleToken( Client.EVMTokenAmount memory tokenAndAmount, uint64 destChainSelector, @@ -261,8 +260,8 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { // ================================================================ /// @notice Returns the static onRamp config. - /// @dev RMN depends on this function, if changing, please notify the RMN maintainers. - /// @return the configuration. + /// @dev RMN depends on this function, if modified, please notify the RMN maintainers. + /// @return staticConfig the static configuration. function getStaticConfig() external view returns (StaticConfig memory) { return StaticConfig({ chainSelector: i_chainSelector, @@ -273,7 +272,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { } /// @notice Returns the dynamic onRamp config. - /// @return dynamicConfig the configuration. + /// @return dynamicConfig the dynamic configuration. function getDynamicConfig() external view returns (DynamicConfig memory dynamicConfig) { return s_dynamicConfig; } @@ -308,8 +307,8 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { ); } - /// @notice Updates the destination chain specific config. - /// @param destChainConfigArgs Array of source chain specific configs. + /// @notice Updates destination chains specific configs. + /// @param destChainConfigArgs Array of destination chain specific configs. function applyDestChainConfigUpdates(DestChainConfigArgs[] memory destChainConfigArgs) external onlyOwner { _applyDestChainConfigUpdates(destChainConfigArgs); } From 290ccda8859689fcdb45b6b3a96ce59fcb404999 Mon Sep 17 00:00:00 2001 From: Kostis Karantias <732062+gtklocker@users.noreply.github.com> Date: Fri, 23 Aug 2024 19:28:49 +0300 Subject: [PATCH 224/432] RMN home & remote contracts (#1308) Co-authored-by: Ryan Hall --- contracts/.solhintignore | 4 + contracts/gas-snapshots/ccip.gas-snapshot | 1 + contracts/src/v0.8/ccip/RMNHome.sol | 164 +++++++++++++++++++++ contracts/src/v0.8/ccip/RMNRemote.sol | 167 ++++++++++++++++++++++ 4 files changed, 336 insertions(+) create mode 100644 contracts/src/v0.8/ccip/RMNHome.sol create mode 100644 contracts/src/v0.8/ccip/RMNRemote.sol diff --git a/contracts/.solhintignore b/contracts/.solhintignore index bad1935442..446f91f84f 100644 --- a/contracts/.solhintignore +++ b/contracts/.solhintignore @@ -41,3 +41,7 @@ # Always ignore vendor ./src/v0.8/vendor ./node_modules/ + +# Ignore RMN contracts temporarily +./src/v0.8/ccip/RMNRemote.sol +./src/v0.8/ccip/RMNHome.sol \ No newline at end of file diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 3c9bbec852..9680750a88 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -772,6 +772,7 @@ PriceRegistry_validatePoolReturnData:test_InvalidEVMAddressDestToken_Revert() (g PriceRegistry_validatePoolReturnData:test_SourceTokenDataTooLarge_Revert() (gas: 90819) PriceRegistry_validatePoolReturnData:test_TokenAmountArraysMismatching_Revert() (gas: 32771) PriceRegistry_validatePoolReturnData:test_WithSingleToken_Success() (gas: 31315) +RMNHome:test() (gas: 186) RMN_constructor:test_Constructor_Success() (gas: 48838) RMN_getRecordedCurseRelatedOps:test_OpsPostDeployment() (gas: 19666) RMN_lazyVoteToCurseUpdate_Benchmark:test_VoteToCurseLazilyRetain3VotersUponConfigChange_gas() (gas: 152152) diff --git a/contracts/src/v0.8/ccip/RMNHome.sol b/contracts/src/v0.8/ccip/RMNHome.sol new file mode 100644 index 0000000000..f28a5da95b --- /dev/null +++ b/contracts/src/v0.8/ccip/RMNHome.sol @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.24; + +import "@openzeppelin/contracts/access/Ownable2Step.sol"; + +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; + +/// @notice Stores the home configuration for RMN, that is referenced by CCIP oracles, RMN nodes, and the RMNRemote +/// contracts. +contract RMNHome is Ownable2Step, ITypeAndVersion { + /// @dev temp placeholder to exclude this contract from coverage + function test() public {} + + string public constant override typeAndVersion = "RMNHome 1.6.0-dev"; + uint256 public constant CONFIG_RING_BUFFER_SIZE = 2; + + struct Node { + string peerId; // used for p2p communication, base58 encoded + bytes32 offchainPublicKey; // observations are signed with this public key, and are only verified offchain + } + + struct SourceChain { + uint64 chainSelector; + uint64[] observerNodeIndices; // indices into Config.nodes, strictly increasing + uint64 minObservers; // required to agree on an observation for this source chain + } + + struct Config { + // No sorting requirement for nodes, but ensure that SourceChain.observerNodeIndices in the home chain config & + // Signer.nodeIndex in the remote chain configs are appropriately updated when changing this field + Node[] nodes; + // Should be in ascending order of chainSelector + SourceChain[] sourceChains; + } + + struct VersionedConfig { + uint32 version; + Config config; + } + + function _configDigest(VersionedConfig memory versionedConfig) internal pure returns (bytes32) { + uint256 h = uint256(keccak256(abi.encode(versionedConfig))); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + uint256 prefix = 0x000b << (256 - 16); // 0x000b00..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + // if we were to have VersionedConfig instead of Config in the ring buffer, we couldn't assign directly to it in + // setConfig without via-ir + uint32[CONFIG_RING_BUFFER_SIZE] s_configCounts; // s_configCounts[i] == 0 iff s_configs[i] is unusable + Config[CONFIG_RING_BUFFER_SIZE] s_configs; + uint256 s_latestConfigIndex; + bytes32 s_latestConfigDigest; + + /// @param revokePastConfigs if one wants to revoke all past configs, because some past config is faulty + function setConfig(Config calldata newConfig, bool revokePastConfigs) external onlyOwner { + // sanity checks + { + // no peerId or offchainPublicKey is duplicated + for (uint256 i = 0; i < newConfig.nodes.length; ++i) { + for (uint256 j = i + 1; j < newConfig.nodes.length; ++j) { + if (keccak256(abi.encode(newConfig.nodes[i].peerId)) == keccak256(abi.encode(newConfig.nodes[j].peerId))) { + revert DuplicatePeerId(); + } + if (newConfig.nodes[i].offchainPublicKey == newConfig.nodes[j].offchainPublicKey) { + revert DuplicateOffchainPublicKey(); + } + } + } + + for (uint256 i = 0; i < newConfig.sourceChains.length; ++i) { + // source chains are in strictly increasing order of chain selectors + if (i > 0 && !(newConfig.sourceChains[i - 1].chainSelector < newConfig.sourceChains[i].chainSelector)) { + revert OutOfOrderSourceChains(); + } + + // all observerNodeIndices are valid + for (uint256 j = 0; j < newConfig.sourceChains[i].observerNodeIndices.length; ++j) { + if ( + j > 0 + && !(newConfig.sourceChains[i].observerNodeIndices[j - 1] < newConfig.sourceChains[i].observerNodeIndices[j]) + ) { + revert OutOfOrderObserverNodeIndices(); + } + if (!(newConfig.sourceChains[i].observerNodeIndices[j] < newConfig.nodes.length)) { + revert OutOfBoundsObserverNodeIndex(); + } + } + + // minObservers are tenable + if (!(newConfig.sourceChains[i].minObservers <= newConfig.sourceChains[i].observerNodeIndices.length)) { + revert MinObserversTooHigh(); + } + } + } + + uint256 oldConfigIndex = s_latestConfigIndex; + uint32 oldConfigCount = s_configCounts[oldConfigIndex]; + uint256 newConfigIndex = (oldConfigIndex + 1) % CONFIG_RING_BUFFER_SIZE; + + for (uint256 i = 0; i < CONFIG_RING_BUFFER_SIZE; ++i) { + if ((i == newConfigIndex || revokePastConfigs) && s_configCounts[i] > 0) { + emit ConfigRevoked(_configDigest(VersionedConfig({version: s_configCounts[i], config: s_configs[i]}))); + delete s_configCounts[i]; + } + } + + uint32 newConfigCount = oldConfigCount + 1; + VersionedConfig memory newVersionedConfig = VersionedConfig({version: newConfigCount, config: newConfig}); + bytes32 newConfigDigest = _configDigest(newVersionedConfig); + s_configs[newConfigIndex] = newConfig; + s_configCounts[newConfigIndex] = newConfigCount; + s_latestConfigIndex = newConfigIndex; + s_latestConfigDigest = newConfigDigest; + emit ConfigSet(newConfigDigest, newVersionedConfig); + } + + /// @return configDigest will be zero in case no config has been set + function getLatestConfigDigestAndVersionedConfig() + external + view + returns (bytes32 configDigest, VersionedConfig memory) + { + return ( + s_latestConfigDigest, + VersionedConfig({version: s_configCounts[s_latestConfigIndex], config: s_configs[s_latestConfigIndex]}) + ); + } + + /// @notice The offchain code can use this to fetch an old config which might still be in use by some remotes + /// @dev Only to be called by offchain code, efficiency is not a concern + function getConfig(bytes32 configDigest) external view returns (VersionedConfig memory versionedConfig, bool ok) { + for (uint256 i = 0; i < CONFIG_RING_BUFFER_SIZE; ++i) { + if (s_configCounts[i] == 0) { + // unset config + continue; + } + VersionedConfig memory vc = VersionedConfig({version: s_configCounts[i], config: s_configs[i]}); + if (_configDigest(vc) == configDigest) { + versionedConfig = vc; + ok = true; + break; + } + } + } + + /// + /// Events + /// + + event ConfigSet(bytes32 configDigest, VersionedConfig versionedConfig); + event ConfigRevoked(bytes32 configDigest); + + /// + /// Errors + /// + + error DuplicatePeerId(); + error DuplicateOffchainPublicKey(); + error OutOfOrderSourceChains(); + error OutOfOrderObserverNodeIndices(); + error OutOfBoundsObserverNodeIndex(); + error MinObserversTooHigh(); +} diff --git a/contracts/src/v0.8/ccip/RMNRemote.sol b/contracts/src/v0.8/ccip/RMNRemote.sol new file mode 100644 index 0000000000..19b7f89e1b --- /dev/null +++ b/contracts/src/v0.8/ccip/RMNRemote.sol @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.24; + +import "@openzeppelin/contracts/access/Ownable2Step.sol"; + +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; + +bytes32 constant RMN_V1_6_ANY2EVM_REPORT = keccak256("RMN_V1_6_ANY2EVM_REPORT"); + +/// @notice This contract supports verification of RMN reports for any Any2EVM OffRamp. +contract RMNRemote is Ownable2Step, ITypeAndVersion { + /// @dev temp placeholder to exclude this contract from coverage + function test() public {} + + string public constant override typeAndVersion = "RMNRemote 1.6.0-dev"; + + uint64 internal immutable i_chainSelector; + + constructor(uint64 chainSelector) { + i_chainSelector = chainSelector; + } + + struct Signer { + address onchainPublicKey; // for signing reports + uint64 nodeIndex; // maps to nodes in home chain config, should be strictly increasing + } + + struct Config { + bytes32 rmnHomeContractConfigDigest; + Signer[] signers; + uint64 minSigners; + } + + struct VersionedConfig { + uint32 version; + Config config; + } + + Config s_config; + uint32 s_configCount; + + mapping(address signer => bool exists) s_signers; // for more gas efficient verify + + function setConfig(Config calldata newConfig) external onlyOwner { + // sanity checks + { + // signers are in ascending order of nodeIndex + for (uint256 i = 1; i < newConfig.signers.length; ++i) { + if (!(newConfig.signers[i - 1].nodeIndex < newConfig.signers[i].nodeIndex)) { + revert InvalidSignerOrder(); + } + } + + // minSigners is tenable + if (!(newConfig.minSigners <= newConfig.signers.length)) { + revert MinSignersTooHigh(); + } + } + + // clear the old signers + { + Config storage oldConfig = s_config; + while (oldConfig.signers.length > 0) { + delete s_signers[oldConfig.signers[oldConfig.signers.length - 1].onchainPublicKey]; + oldConfig.signers.pop(); + } + } + + // set the new signers + { + for (uint256 i = 0; i < newConfig.signers.length; ++i) { + if (s_signers[newConfig.signers[i].onchainPublicKey]) { + revert DuplicateOnchainPublicKey(); + } + s_signers[newConfig.signers[i].onchainPublicKey] = true; + } + } + + s_config = newConfig; + uint32 newConfigCount = ++s_configCount; + emit ConfigSet(VersionedConfig({version: newConfigCount, config: newConfig})); + } + + function getVersionedConfig() external view returns (VersionedConfig memory) { + return VersionedConfig({version: s_configCount, config: s_config}); + } + + /// @notice The part of the LaneUpdate for a fixed destination chain and OffRamp, to avoid verbosity in Report + struct DestLaneUpdate { + uint64 sourceChainSelector; + bytes onrampAddress; // generic, to support arbitrary sources; for EVM2EVM, use abi.encodePacked + uint64 minMsgNr; + uint64 maxMsgNr; + bytes32 root; + } + + struct Report { + uint256 destChainId; // to guard against chain selector misconfiguration + uint64 destChainSelector; + address rmnRemoteContractAddress; + address offrampAddress; + bytes32 rmnHomeContractConfigDigest; + DestLaneUpdate[] destLaneUpdates; + } + + struct Signature { + bytes32 r; + bytes32 s; + } + + /// @notice Verifies signatures of RMN nodes, on dest lane updates as provided in the CommitReport + /// @param destLaneUpdates must be well formed, and is a representation of the CommitReport received from the oracles + /// @param signatures must be sorted in ascending order by signer address + /// @dev Will revert if verification fails. Needs to be called by the OffRamp for which the signatures are produced, + /// otherwise verification will fail. + function verify(DestLaneUpdate[] memory destLaneUpdates, Signature[] memory signatures) external view { + if (s_configCount == 0) { + revert ConfigNotSet(); + } + + bytes32 signedHash = keccak256( + abi.encode( + RMN_V1_6_ANY2EVM_REPORT, + Report({ + destChainId: block.chainid, + destChainSelector: i_chainSelector, + rmnRemoteContractAddress: address(this), + offrampAddress: msg.sender, + rmnHomeContractConfigDigest: s_config.rmnHomeContractConfigDigest, + destLaneUpdates: destLaneUpdates + }) + ) + ); + + uint256 numSigners = 0; + address prevAddress = address(0); + for (uint256 i = 0; i < signatures.length; ++i) { + Signature memory sig = signatures[i]; + address signerAddress = ecrecover(signedHash, 27, sig.r, sig.s); + if (signerAddress == address(0)) revert InvalidSignature(); + if (!(prevAddress < signerAddress)) revert OutOfOrderSignatures(); + if (!s_signers[signerAddress]) revert UnexpectedSigner(); + prevAddress = signerAddress; + ++numSigners; + } + if (numSigners < s_config.minSigners) revert ThresholdNotMet(); + } + + /// + /// Events + /// + + event ConfigSet(VersionedConfig versionedConfig); + + /// + /// Errors + /// + + error InvalidSignature(); + error OutOfOrderSignatures(); + error UnexpectedSigner(); + error ThresholdNotMet(); + error ConfigNotSet(); + error InvalidSignerOrder(); + error MinSignersTooHigh(); + error DuplicateOnchainPublicKey(); +} From 0968c5d1d036bdc3eef848358db6a459276d5fe4 Mon Sep 17 00:00:00 2001 From: Will Winder Date: Fri, 23 Aug 2024 14:29:20 -0400 Subject: [PATCH 225/432] Initialize reader configs when module loads. (#1353) ## Motivation Ensure the `mustGetMethodName` and `mustGetEventName` functions are called as early as possible. ## Solution Change config functions to be variables, this way they should evaluate as the module loads rather than when the CCIP Reader object is initialized. --- .../integrationhelpers/integration_helpers.go | 2 +- .../ccip/configs/evm/contract_reader.go | 270 +++++++++--------- core/capabilities/ccip/delegate.go | 2 +- .../ccip/oraclecreator/inprocess.go | 4 +- 4 files changed, 136 insertions(+), 142 deletions(-) diff --git a/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go b/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go index 821c2bc0f5..9d2edad28c 100644 --- a/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go @@ -232,7 +232,7 @@ func (t *TestUniverse) AddCapability(p2pIDs [][32]byte) { } func NewHomeChainReader(t *testing.T, logPoller logpoller.LogPoller, headTracker logpoller.HeadTracker, client client.Client, ccAddress common.Address) ccipreader.HomeChain { - cr := NewReader(t, logPoller, headTracker, client, ccAddress, configsevm.HomeChainReaderConfigRaw()) + cr := NewReader(t, logPoller, headTracker, client, ccAddress, configsevm.HomeChainReaderConfigRaw) hcr := ccipreader.NewHomeChainReader(cr, logger.TestLogger(t), 500*time.Millisecond, types.BoundContract{ Address: ccAddress.String(), diff --git a/core/capabilities/ccip/configs/evm/contract_reader.go b/core/capabilities/ccip/configs/evm/contract_reader.go index 6774c8c1fe..fd5cc49fa3 100644 --- a/core/capabilities/ccip/configs/evm/contract_reader.go +++ b/core/capabilities/ccip/configs/evm/contract_reader.go @@ -27,7 +27,7 @@ var ( // MustSourceReaderConfig returns a ChainReaderConfig that can be used to read from the onramp. // The configuration is marshaled into JSON so that it can be passed to the relayer NewContractReader() method. func MustSourceReaderConfig() []byte { - rawConfig := SourceReaderConfig() + rawConfig := SourceReaderConfig encoded, err := json.Marshal(rawConfig) if err != nil { panic(fmt.Errorf("failed to marshal ChainReaderConfig into JSON: %w", err)) @@ -39,7 +39,7 @@ func MustSourceReaderConfig() []byte { // MustDestReaderConfig returns a ChainReaderConfig that can be used to read from the offramp. // The configuration is marshaled into JSON so that it can be passed to the relayer NewContractReader() method. func MustDestReaderConfig() []byte { - rawConfig := DestReaderConfig() + rawConfig := DestReaderConfig encoded, err := json.Marshal(rawConfig) if err != nil { panic(fmt.Errorf("failed to marshal ChainReaderConfig into JSON: %w", err)) @@ -49,165 +49,159 @@ func MustDestReaderConfig() []byte { } // DestReaderConfig returns a ChainReaderConfig that can be used to read from the offramp. -func DestReaderConfig() evmrelaytypes.ChainReaderConfig { - return evmrelaytypes.ChainReaderConfig{ - Contracts: map[string]evmrelaytypes.ChainContractReader{ - consts.ContractNameOffRamp: { - ContractABI: offramp.OffRampABI, - ContractPollingFilter: evmrelaytypes.ContractPollingFilter{ - GenericEventNames: []string{ - mustGetEventName(consts.EventNameExecutionStateChanged, offrampABI), - mustGetEventName(consts.EventNameCommitReportAccepted, offrampABI), - }, +var DestReaderConfig = evmrelaytypes.ChainReaderConfig{ + Contracts: map[string]evmrelaytypes.ChainContractReader{ + consts.ContractNameOffRamp: { + ContractABI: offramp.OffRampABI, + ContractPollingFilter: evmrelaytypes.ContractPollingFilter{ + GenericEventNames: []string{ + mustGetEventName(consts.EventNameExecutionStateChanged, offrampABI), + mustGetEventName(consts.EventNameCommitReportAccepted, offrampABI), }, - Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ - consts.MethodNameGetExecutionState: { - ChainSpecificName: mustGetMethodName("getExecutionState", offrampABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameGetMerkleRoot: { - ChainSpecificName: mustGetMethodName("getMerkleRoot", offrampABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameIsBlessed: { - ChainSpecificName: mustGetMethodName("isBlessed", offrampABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameGetLatestPriceSequenceNumber: { - ChainSpecificName: mustGetMethodName("getLatestPriceSequenceNumber", offrampABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameOfframpGetStaticConfig: { - ChainSpecificName: mustGetMethodName("getStaticConfig", offrampABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameOfframpGetDynamicConfig: { - ChainSpecificName: mustGetMethodName("getDynamicConfig", offrampABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameGetSourceChainConfig: { - ChainSpecificName: mustGetMethodName("getSourceChainConfig", offrampABI), - ReadType: evmrelaytypes.Method, - }, - consts.EventNameCommitReportAccepted: { - ChainSpecificName: mustGetEventName(consts.EventNameCommitReportAccepted, offrampABI), - ReadType: evmrelaytypes.Event, - }, - consts.EventNameExecutionStateChanged: { - ChainSpecificName: mustGetEventName(consts.EventNameExecutionStateChanged, offrampABI), - ReadType: evmrelaytypes.Event, - }, + }, + Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ + consts.MethodNameGetExecutionState: { + ChainSpecificName: mustGetMethodName("getExecutionState", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameGetMerkleRoot: { + ChainSpecificName: mustGetMethodName("getMerkleRoot", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameIsBlessed: { + ChainSpecificName: mustGetMethodName("isBlessed", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameGetLatestPriceSequenceNumber: { + ChainSpecificName: mustGetMethodName("getLatestPriceSequenceNumber", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameOfframpGetStaticConfig: { + ChainSpecificName: mustGetMethodName("getStaticConfig", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameOfframpGetDynamicConfig: { + ChainSpecificName: mustGetMethodName("getDynamicConfig", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameGetSourceChainConfig: { + ChainSpecificName: mustGetMethodName("getSourceChainConfig", offrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.EventNameCommitReportAccepted: { + ChainSpecificName: mustGetEventName(consts.EventNameCommitReportAccepted, offrampABI), + ReadType: evmrelaytypes.Event, + }, + consts.EventNameExecutionStateChanged: { + ChainSpecificName: mustGetEventName(consts.EventNameExecutionStateChanged, offrampABI), + ReadType: evmrelaytypes.Event, }, }, }, - } + }, } // SourceReaderConfig returns a ChainReaderConfig that can be used to read from the onramp. -func SourceReaderConfig() evmrelaytypes.ChainReaderConfig { - return evmrelaytypes.ChainReaderConfig{ - Contracts: map[string]evmrelaytypes.ChainContractReader{ - consts.ContractNameOnRamp: { - ContractABI: onramp.OnRampABI, - ContractPollingFilter: evmrelaytypes.ContractPollingFilter{ - GenericEventNames: []string{ - mustGetEventName(consts.EventNameCCIPSendRequested, onrampABI), - }, +var SourceReaderConfig = evmrelaytypes.ChainReaderConfig{ + Contracts: map[string]evmrelaytypes.ChainContractReader{ + consts.ContractNameOnRamp: { + ContractABI: onramp.OnRampABI, + ContractPollingFilter: evmrelaytypes.ContractPollingFilter{ + GenericEventNames: []string{ + mustGetEventName(consts.EventNameCCIPSendRequested, onrampABI), }, - Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ - // all "{external|public} view" functions in the onramp except for getFee and getPoolBySourceToken are here. - // getFee is not expected to get called offchain and is only called by end-user contracts. - consts.MethodNameGetExpectedNextSequenceNumber: { - ChainSpecificName: mustGetMethodName("getExpectedNextSequenceNumber", onrampABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameOnrampGetStaticConfig: { - ChainSpecificName: mustGetMethodName("getStaticConfig", onrampABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameOnrampGetDynamicConfig: { - ChainSpecificName: mustGetMethodName("getDynamicConfig", onrampABI), - ReadType: evmrelaytypes.Method, - }, - consts.EventNameCCIPSendRequested: { - ChainSpecificName: mustGetEventName(consts.EventNameCCIPSendRequested, onrampABI), - ReadType: evmrelaytypes.Event, - EventDefinitions: &evmrelaytypes.EventDefinitions{ - GenericDataWordNames: map[string]uint8{ - consts.EventAttributeSequenceNumber: 5, - }, + }, + Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ + // all "{external|public} view" functions in the onramp except for getFee and getPoolBySourceToken are here. + // getFee is not expected to get called offchain and is only called by end-user contracts. + consts.MethodNameGetExpectedNextSequenceNumber: { + ChainSpecificName: mustGetMethodName("getExpectedNextSequenceNumber", onrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameOnrampGetStaticConfig: { + ChainSpecificName: mustGetMethodName("getStaticConfig", onrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameOnrampGetDynamicConfig: { + ChainSpecificName: mustGetMethodName("getDynamicConfig", onrampABI), + ReadType: evmrelaytypes.Method, + }, + consts.EventNameCCIPSendRequested: { + ChainSpecificName: mustGetEventName(consts.EventNameCCIPSendRequested, onrampABI), + ReadType: evmrelaytypes.Event, + EventDefinitions: &evmrelaytypes.EventDefinitions{ + GenericDataWordNames: map[string]uint8{ + consts.EventAttributeSequenceNumber: 5, }, }, }, }, - consts.ContractNamePriceRegistry: { - ContractABI: price_registry.PriceRegistryABI, - Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ - // TODO: update with the consts from https://github.com/smartcontractkit/chainlink-ccip/pull/39 - // in a followup. - "GetStaticConfig": { - ChainSpecificName: mustGetMethodName("getStaticConfig", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - "GetDestChainConfig": { - ChainSpecificName: mustGetMethodName("getDestChainConfig", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - "GetPremiumMultiplierWeiPerEth": { - ChainSpecificName: mustGetMethodName("getPremiumMultiplierWeiPerEth", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - "GetTokenTransferFeeConfig": { - ChainSpecificName: mustGetMethodName("getTokenTransferFeeConfig", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - "ProcessMessageArgs": { - ChainSpecificName: mustGetMethodName("processMessageArgs", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - "ValidatePoolReturnData": { - ChainSpecificName: mustGetMethodName("validatePoolReturnData", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - "GetValidatedTokenPrice": { - ChainSpecificName: mustGetMethodName("getValidatedTokenPrice", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - "GetFeeTokens": { - ChainSpecificName: mustGetMethodName("getFeeTokens", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, + }, + consts.ContractNamePriceRegistry: { + ContractABI: price_registry.PriceRegistryABI, + Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ + // TODO: update with the consts from https://github.com/smartcontractkit/chainlink-ccip/pull/39 + // in a followup. + "GetStaticConfig": { + ChainSpecificName: mustGetMethodName("getStaticConfig", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "GetDestChainConfig": { + ChainSpecificName: mustGetMethodName("getDestChainConfig", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "GetPremiumMultiplierWeiPerEth": { + ChainSpecificName: mustGetMethodName("getPremiumMultiplierWeiPerEth", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "GetTokenTransferFeeConfig": { + ChainSpecificName: mustGetMethodName("getTokenTransferFeeConfig", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "ProcessMessageArgs": { + ChainSpecificName: mustGetMethodName("processMessageArgs", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "ValidatePoolReturnData": { + ChainSpecificName: mustGetMethodName("validatePoolReturnData", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "GetValidatedTokenPrice": { + ChainSpecificName: mustGetMethodName("getValidatedTokenPrice", priceRegistryABI), + ReadType: evmrelaytypes.Method, + }, + "GetFeeTokens": { + ChainSpecificName: mustGetMethodName("getFeeTokens", priceRegistryABI), + ReadType: evmrelaytypes.Method, }, }, }, - } + }, } // HomeChainReaderConfigRaw returns a ChainReaderConfig that can be used to read from the home chain. -func HomeChainReaderConfigRaw() evmrelaytypes.ChainReaderConfig { - return evmrelaytypes.ChainReaderConfig{ - Contracts: map[string]evmrelaytypes.ChainContractReader{ - consts.ContractNameCapabilitiesRegistry: { - ContractABI: kcr.CapabilitiesRegistryABI, - Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ - consts.MethodNameGetCapability: { - ChainSpecificName: mustGetMethodName("getCapability", capabilitiesRegsitryABI), - }, +var HomeChainReaderConfigRaw = evmrelaytypes.ChainReaderConfig{ + Contracts: map[string]evmrelaytypes.ChainContractReader{ + consts.ContractNameCapabilitiesRegistry: { + ContractABI: kcr.CapabilitiesRegistryABI, + Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ + consts.MethodNameGetCapability: { + ChainSpecificName: mustGetMethodName("getCapability", capabilitiesRegsitryABI), }, }, - consts.ContractNameCCIPConfig: { - ContractABI: ccip_config.CCIPConfigABI, - Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ - consts.MethodNameGetAllChainConfigs: { - ChainSpecificName: mustGetMethodName("getAllChainConfigs", ccipConfigABI), - }, - consts.MethodNameGetOCRConfig: { - ChainSpecificName: mustGetMethodName("getOCRConfig", ccipConfigABI), - }, + }, + consts.ContractNameCCIPConfig: { + ContractABI: ccip_config.CCIPConfigABI, + Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ + consts.MethodNameGetAllChainConfigs: { + ChainSpecificName: mustGetMethodName("getAllChainConfigs", ccipConfigABI), + }, + consts.MethodNameGetOCRConfig: { + ChainSpecificName: mustGetMethodName("getOCRConfig", ccipConfigABI), }, }, }, - } + }, } func mustGetEventName(event string, tabi abi.ABI) string { diff --git a/core/capabilities/ccip/delegate.go b/core/capabilities/ccip/delegate.go index a7cefd5cd9..6dd30b1507 100644 --- a/core/capabilities/ccip/delegate.go +++ b/core/capabilities/ccip/delegate.go @@ -267,7 +267,7 @@ func (d *Delegate) getHomeChainContractReader( homeChain.LogPoller(), homeChain.HeadTracker(), homeChain.Client(), - configsevm.HomeChainReaderConfigRaw(), + configsevm.HomeChainReaderConfigRaw, ) if err != nil { return nil, types.BoundContract{}, fmt.Errorf("failed to create home chain contract reader: %w", err) diff --git a/core/capabilities/ccip/oraclecreator/inprocess.go b/core/capabilities/ccip/oraclecreator/inprocess.go index 266ffc2d77..d705367d57 100644 --- a/core/capabilities/ccip/oraclecreator/inprocess.go +++ b/core/capabilities/ccip/oraclecreator/inprocess.go @@ -178,9 +178,9 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp for _, chain := range i.chains.Slice() { var chainReaderConfig evmrelaytypes.ChainReaderConfig if chain.ID().Uint64() == destChainID { - chainReaderConfig = evmconfig.DestReaderConfig() + chainReaderConfig = evmconfig.DestReaderConfig } else { - chainReaderConfig = evmconfig.SourceReaderConfig() + chainReaderConfig = evmconfig.SourceReaderConfig } cr, err2 := evm.NewChainReaderService( context.Background(), From 6f9bbe6ffa882edcc848ca1d7f5ab5471f593836 Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Mon, 26 Aug 2024 13:19:12 +0200 Subject: [PATCH 226/432] fix ping pong version (#1363) ## Motivation The version should have been bumped to 1.5.0 with the previous release as changes had been made since 1.2.0 ## Solution Bump the version --- contracts/src/v0.8/ccip/applications/PingPongDemo.sol | 2 +- contracts/src/v0.8/ccip/applications/SelfFundedPingPong.sol | 2 +- .../ccip/generated/ping_pong_demo/ping_pong_demo.go | 2 +- .../generated/self_funded_ping_pong/self_funded_ping_pong.go | 2 +- .../generated-wrapper-dependency-versions-do-not-edit.txt | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/src/v0.8/ccip/applications/PingPongDemo.sol b/contracts/src/v0.8/ccip/applications/PingPongDemo.sol index 5144b3ed4c..3697c7ff5a 100644 --- a/contracts/src/v0.8/ccip/applications/PingPongDemo.sol +++ b/contracts/src/v0.8/ccip/applications/PingPongDemo.sol @@ -37,7 +37,7 @@ contract PingPongDemo is CCIPReceiver, OwnerIsCreator, ITypeAndVersion { } function typeAndVersion() external pure virtual returns (string memory) { - return "PingPongDemo 1.2.0"; + return "PingPongDemo 1.5.0"; } function setCounterpart(uint64 counterpartChainSelector, address counterpartAddress) external onlyOwner { diff --git a/contracts/src/v0.8/ccip/applications/SelfFundedPingPong.sol b/contracts/src/v0.8/ccip/applications/SelfFundedPingPong.sol index 80bc7bb24a..f9e4fd0aa6 100644 --- a/contracts/src/v0.8/ccip/applications/SelfFundedPingPong.sol +++ b/contracts/src/v0.8/ccip/applications/SelfFundedPingPong.sol @@ -9,7 +9,7 @@ import {PingPongDemo} from "./PingPongDemo.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; contract SelfFundedPingPong is PingPongDemo { - string public constant override typeAndVersion = "SelfFundedPingPong 1.2.0"; + string public constant override typeAndVersion = "SelfFundedPingPong 1.5.0"; event Funded(); event CountIncrBeforeFundingSet(uint8 countIncrBeforeFunding); diff --git a/core/gethwrappers/ccip/generated/ping_pong_demo/ping_pong_demo.go b/core/gethwrappers/ccip/generated/ping_pong_demo/ping_pong_demo.go index 349d83182c..08ae9cc0cc 100644 --- a/core/gethwrappers/ccip/generated/ping_pong_demo/ping_pong_demo.go +++ b/core/gethwrappers/ccip/generated/ping_pong_demo/ping_pong_demo.go @@ -45,7 +45,7 @@ type ClientEVMTokenAmount struct { var PingPongDemoMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"feeToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"InvalidRouter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutOfOrder\",\"type\":\"bool\"}],\"name\":\"OutOfOrderExecutionChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Ping\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Pong\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartChainSelector\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOutOfOrderExecution\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"counterpartChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"counterpartAddress\",\"type\":\"address\"}],\"name\":\"setCounterpart\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setCounterpartAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"setCounterpartChainSelector\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"outOfOrderExecution\",\"type\":\"bool\"}],\"name\":\"setOutOfOrderExecution\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pause\",\"type\":\"bool\"}],\"name\":\"setPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startPingPong\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b506040516200159d3803806200159d833981016040819052620000349162000263565b33806000846001600160a01b03811662000069576040516335fdcccd60e21b8152600060048201526024015b60405180910390fd5b6001600160a01b039081166080528216620000c75760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604482015260640162000060565b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000fa57620000fa816200019f565b50506002805460ff60a01b1916905550600380546001600160a01b0319166001600160a01b0383811691821790925560405163095ea7b360e01b8152918416600483015260001960248301529063095ea7b3906044016020604051808303816000875af115801562000170573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001969190620002a2565b505050620002cd565b336001600160a01b03821603620001f95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200026057600080fd5b50565b600080604083850312156200027757600080fd5b825162000284816200024a565b602084015190925062000297816200024a565b809150509250929050565b600060208284031215620002b557600080fd5b81518015158114620002c657600080fd5b9392505050565b6080516112a6620002f760003960008181610295015281816106860152610ab901526112a66000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638da5cb5b116100b2578063b187bd2611610081578063bee518a411610066578063bee518a4146102ef578063ca709a251461032d578063f2fde38b1461034b57600080fd5b8063b187bd26146102b9578063b5a11011146102dc57600080fd5b80638da5cb5b1461023f5780639d2aede51461025d578063ae90de5514610270578063b0f479a11461029357600080fd5b80632874d8bf11610109578063665ed537116100ee578063665ed5371461021157806379ba50971461022457806385572ffb1461022c57600080fd5b80632874d8bf146101ca5780632b6e5d63146101d257600080fd5b806301ffc9a71461013b57806316c38b3c14610163578063181f5a77146101785780631892b906146101b7575b600080fd5b61014e610149366004610cba565b61035e565b60405190151581526020015b60405180910390f35b610176610171366004610d03565b6103f7565b005b604080518082018252601281527f50696e67506f6e6744656d6f20312e322e3000000000000000000000000000006020820152905161015a9190610d89565b6101766101c5366004610db9565b610449565b6101766104a4565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161015a565b61017661021f366004610d03565b6104e0565b61017661056c565b61017661023a366004610dd4565b61066e565b60005473ffffffffffffffffffffffffffffffffffffffff166101ec565b61017661026b366004610e33565b6106f3565b60035474010000000000000000000000000000000000000000900460ff1661014e565b7f00000000000000000000000000000000000000000000000000000000000000006101ec565b60025474010000000000000000000000000000000000000000900460ff1661014e565b6101766102ea366004610e4e565b610742565b60015474010000000000000000000000000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff909116815260200161015a565b60035473ffffffffffffffffffffffffffffffffffffffff166101ec565b610176610359366004610e33565b6107e4565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f85572ffb0000000000000000000000000000000000000000000000000000000014806103f157507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6103ff6107f5565b6002805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104516107f5565b6001805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104ac6107f5565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556104de6001610876565b565b6104e86107f5565b6003805482151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091161790556040517f05a3fef9935c9013a24c6193df2240d34fcf6b0ebf8786b85efe8401d696cdd99061056190831515815260200190565b60405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106df576040517fd7f733340000000000000000000000000000000000000000000000000000000081523360048201526024016105e9565b6106f06106eb82611084565b610b6f565b50565b6106fb6107f5565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61074a6107f5565b6001805467ffffffffffffffff90931674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909316929092179091556002805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055565b6107ec6107f5565b6106f081610bc5565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105e9565b806001166001036108b9576040518181527f48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f9060200160405180910390a16108ed565b6040518181527f58b69f57828e6962d216502094c54f6562f3bf082ba758966c3454f9e37b15259060200160405180910390a15b6040805160a0810190915260025473ffffffffffffffffffffffffffffffffffffffff1660c08201526000908060e0810160405160208183030381529060405281526020018360405160200161094591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052815260200160006040519080825280602002602001820160405280156109bf57816020015b60408051808201909152600080825260208201528152602001906001900390816109985790505b50815260035473ffffffffffffffffffffffffffffffffffffffff811660208084019190915260408051808201825262030d408082527401000000000000000000000000000000000000000090940460ff16151590830190815281516024810194909452511515604480850191909152815180850390910181526064909301815290820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf1000000000000000000000000000000000000000000000000000000000179052909101526001546040517f96f4e9f90000000000000000000000000000000000000000000000000000000081529192507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16916396f4e9f991610b27917401000000000000000000000000000000000000000090910467ffffffffffffffff16908590600401611131565b6020604051808303816000875af1158015610b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6a9190611246565b505050565b60008160600151806020019051810190610b899190611246565b60025490915074010000000000000000000000000000000000000000900460ff16610bc157610bc1610bbc82600161125f565b610876565b5050565b3373ffffffffffffffffffffffffffffffffffffffff821603610c44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105e9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610ccc57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610cfc57600080fd5b9392505050565b600060208284031215610d1557600080fd5b81358015158114610cfc57600080fd5b6000815180845260005b81811015610d4b57602081850181015186830182015201610d2f565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610cfc6020830184610d25565b803567ffffffffffffffff81168114610db457600080fd5b919050565b600060208284031215610dcb57600080fd5b610cfc82610d9c565b600060208284031215610de657600080fd5b813567ffffffffffffffff811115610dfd57600080fd5b820160a08185031215610cfc57600080fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610db457600080fd5b600060208284031215610e4557600080fd5b610cfc82610e0f565b60008060408385031215610e6157600080fd5b610e6a83610d9c565b9150610e7860208401610e0f565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610ed357610ed3610e81565b60405290565b60405160a0810167ffffffffffffffff81118282101715610ed357610ed3610e81565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610f4357610f43610e81565b604052919050565b600082601f830112610f5c57600080fd5b813567ffffffffffffffff811115610f7657610f76610e81565b610fa760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610efc565b818152846020838601011115610fbc57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f830112610fea57600080fd5b8135602067ffffffffffffffff82111561100657611006610e81565b611014818360051b01610efc565b82815260069290921b8401810191818101908684111561103357600080fd5b8286015b8481101561107957604081890312156110505760008081fd5b611058610eb0565b61106182610e0f565b81528185013585820152835291830191604001611037565b509695505050505050565b600060a0823603121561109657600080fd5b61109e610ed9565b823581526110ae60208401610d9c565b6020820152604083013567ffffffffffffffff808211156110ce57600080fd5b6110da36838701610f4b565b604084015260608501359150808211156110f357600080fd5b6110ff36838701610f4b565b6060840152608085013591508082111561111857600080fd5b5061112536828601610fd9565b60808301525092915050565b6000604067ffffffffffffffff851683526020604081850152845160a0604086015261116060e0860182610d25565b9050818601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087840301606088015261119b8383610d25565b6040890151888203830160808a01528051808352908601945060009350908501905b808410156111fc578451805173ffffffffffffffffffffffffffffffffffffffff168352860151868301529385019360019390930192908601906111bd565b50606089015173ffffffffffffffffffffffffffffffffffffffff1660a08901526080890151888203830160c08a015295506112388187610d25565b9a9950505050505050505050565b60006020828403121561125857600080fd5b5051919050565b808201808211156103f1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000818000a", + Bin: "0x60a06040523480156200001157600080fd5b506040516200159d3803806200159d833981016040819052620000349162000263565b33806000846001600160a01b03811662000069576040516335fdcccd60e21b8152600060048201526024015b60405180910390fd5b6001600160a01b039081166080528216620000c75760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604482015260640162000060565b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000fa57620000fa816200019f565b50506002805460ff60a01b1916905550600380546001600160a01b0319166001600160a01b0383811691821790925560405163095ea7b360e01b8152918416600483015260001960248301529063095ea7b3906044016020604051808303816000875af115801562000170573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001969190620002a2565b505050620002cd565b336001600160a01b03821603620001f95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200026057600080fd5b50565b600080604083850312156200027757600080fd5b825162000284816200024a565b602084015190925062000297816200024a565b809150509250929050565b600060208284031215620002b557600080fd5b81518015158114620002c657600080fd5b9392505050565b6080516112a6620002f760003960008181610295015281816106860152610ab901526112a66000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638da5cb5b116100b2578063b187bd2611610081578063bee518a411610066578063bee518a4146102ef578063ca709a251461032d578063f2fde38b1461034b57600080fd5b8063b187bd26146102b9578063b5a11011146102dc57600080fd5b80638da5cb5b1461023f5780639d2aede51461025d578063ae90de5514610270578063b0f479a11461029357600080fd5b80632874d8bf11610109578063665ed537116100ee578063665ed5371461021157806379ba50971461022457806385572ffb1461022c57600080fd5b80632874d8bf146101ca5780632b6e5d63146101d257600080fd5b806301ffc9a71461013b57806316c38b3c14610163578063181f5a77146101785780631892b906146101b7575b600080fd5b61014e610149366004610cba565b61035e565b60405190151581526020015b60405180910390f35b610176610171366004610d03565b6103f7565b005b604080518082018252601281527f50696e67506f6e6744656d6f20312e352e3000000000000000000000000000006020820152905161015a9190610d89565b6101766101c5366004610db9565b610449565b6101766104a4565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161015a565b61017661021f366004610d03565b6104e0565b61017661056c565b61017661023a366004610dd4565b61066e565b60005473ffffffffffffffffffffffffffffffffffffffff166101ec565b61017661026b366004610e33565b6106f3565b60035474010000000000000000000000000000000000000000900460ff1661014e565b7f00000000000000000000000000000000000000000000000000000000000000006101ec565b60025474010000000000000000000000000000000000000000900460ff1661014e565b6101766102ea366004610e4e565b610742565b60015474010000000000000000000000000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff909116815260200161015a565b60035473ffffffffffffffffffffffffffffffffffffffff166101ec565b610176610359366004610e33565b6107e4565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f85572ffb0000000000000000000000000000000000000000000000000000000014806103f157507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6103ff6107f5565b6002805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104516107f5565b6001805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104ac6107f5565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556104de6001610876565b565b6104e86107f5565b6003805482151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091161790556040517f05a3fef9935c9013a24c6193df2240d34fcf6b0ebf8786b85efe8401d696cdd99061056190831515815260200190565b60405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106df576040517fd7f733340000000000000000000000000000000000000000000000000000000081523360048201526024016105e9565b6106f06106eb82611084565b610b6f565b50565b6106fb6107f5565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61074a6107f5565b6001805467ffffffffffffffff90931674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909316929092179091556002805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055565b6107ec6107f5565b6106f081610bc5565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105e9565b806001166001036108b9576040518181527f48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f9060200160405180910390a16108ed565b6040518181527f58b69f57828e6962d216502094c54f6562f3bf082ba758966c3454f9e37b15259060200160405180910390a15b6040805160a0810190915260025473ffffffffffffffffffffffffffffffffffffffff1660c08201526000908060e0810160405160208183030381529060405281526020018360405160200161094591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052815260200160006040519080825280602002602001820160405280156109bf57816020015b60408051808201909152600080825260208201528152602001906001900390816109985790505b50815260035473ffffffffffffffffffffffffffffffffffffffff811660208084019190915260408051808201825262030d408082527401000000000000000000000000000000000000000090940460ff16151590830190815281516024810194909452511515604480850191909152815180850390910181526064909301815290820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf1000000000000000000000000000000000000000000000000000000000179052909101526001546040517f96f4e9f90000000000000000000000000000000000000000000000000000000081529192507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16916396f4e9f991610b27917401000000000000000000000000000000000000000090910467ffffffffffffffff16908590600401611131565b6020604051808303816000875af1158015610b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6a9190611246565b505050565b60008160600151806020019051810190610b899190611246565b60025490915074010000000000000000000000000000000000000000900460ff16610bc157610bc1610bbc82600161125f565b610876565b5050565b3373ffffffffffffffffffffffffffffffffffffffff821603610c44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105e9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610ccc57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610cfc57600080fd5b9392505050565b600060208284031215610d1557600080fd5b81358015158114610cfc57600080fd5b6000815180845260005b81811015610d4b57602081850181015186830182015201610d2f565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610cfc6020830184610d25565b803567ffffffffffffffff81168114610db457600080fd5b919050565b600060208284031215610dcb57600080fd5b610cfc82610d9c565b600060208284031215610de657600080fd5b813567ffffffffffffffff811115610dfd57600080fd5b820160a08185031215610cfc57600080fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610db457600080fd5b600060208284031215610e4557600080fd5b610cfc82610e0f565b60008060408385031215610e6157600080fd5b610e6a83610d9c565b9150610e7860208401610e0f565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610ed357610ed3610e81565b60405290565b60405160a0810167ffffffffffffffff81118282101715610ed357610ed3610e81565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610f4357610f43610e81565b604052919050565b600082601f830112610f5c57600080fd5b813567ffffffffffffffff811115610f7657610f76610e81565b610fa760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610efc565b818152846020838601011115610fbc57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f830112610fea57600080fd5b8135602067ffffffffffffffff82111561100657611006610e81565b611014818360051b01610efc565b82815260069290921b8401810191818101908684111561103357600080fd5b8286015b8481101561107957604081890312156110505760008081fd5b611058610eb0565b61106182610e0f565b81528185013585820152835291830191604001611037565b509695505050505050565b600060a0823603121561109657600080fd5b61109e610ed9565b823581526110ae60208401610d9c565b6020820152604083013567ffffffffffffffff808211156110ce57600080fd5b6110da36838701610f4b565b604084015260608501359150808211156110f357600080fd5b6110ff36838701610f4b565b6060840152608085013591508082111561111857600080fd5b5061112536828601610fd9565b60808301525092915050565b6000604067ffffffffffffffff851683526020604081850152845160a0604086015261116060e0860182610d25565b9050818601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087840301606088015261119b8383610d25565b6040890151888203830160808a01528051808352908601945060009350908501905b808410156111fc578451805173ffffffffffffffffffffffffffffffffffffffff168352860151868301529385019360019390930192908601906111bd565b50606089015173ffffffffffffffffffffffffffffffffffffffff1660a08901526080890151888203830160c08a015295506112388187610d25565b9a9950505050505050505050565b60006020828403121561125857600080fd5b5051919050565b808201808211156103f1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000818000a", } var PingPongDemoABI = PingPongDemoMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/self_funded_ping_pong/self_funded_ping_pong.go b/core/gethwrappers/ccip/generated/self_funded_ping_pong/self_funded_ping_pong.go index 755b4183fe..274f72bae3 100644 --- a/core/gethwrappers/ccip/generated/self_funded_ping_pong/self_funded_ping_pong.go +++ b/core/gethwrappers/ccip/generated/self_funded_ping_pong/self_funded_ping_pong.go @@ -45,7 +45,7 @@ type ClientEVMTokenAmount struct { var SelfFundedPingPongMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"roundTripsBeforeFunding\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"InvalidRouter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"countIncrBeforeFunding\",\"type\":\"uint8\"}],\"name\":\"CountIncrBeforeFundingSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Funded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutOfOrder\",\"type\":\"bool\"}],\"name\":\"OutOfOrderExecutionChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Ping\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"Pong\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pingPongCount\",\"type\":\"uint256\"}],\"name\":\"fundPingPong\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCountIncrBeforeFunding\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCounterpartChainSelector\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOutOfOrderExecution\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"countIncrBeforeFunding\",\"type\":\"uint8\"}],\"name\":\"setCountIncrBeforeFunding\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"counterpartChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"counterpartAddress\",\"type\":\"address\"}],\"name\":\"setCounterpart\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setCounterpartAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"setCounterpartChainSelector\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"outOfOrderExecution\",\"type\":\"bool\"}],\"name\":\"setOutOfOrderExecution\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pause\",\"type\":\"bool\"}],\"name\":\"setPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startPingPong\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b506040516200190938038062001909833981016040819052620000349162000291565b828233806000846001600160a01b0381166200006b576040516335fdcccd60e21b8152600060048201526024015b60405180910390fd5b6001600160a01b039081166080528216620000c95760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604482015260640162000062565b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000fc57620000fc81620001cd565b50506002805460ff60a01b1916905550600380546001600160a01b0319166001600160a01b0383811691821790925560405163095ea7b360e01b8152918416600483015260001960248301529063095ea7b3906044016020604051808303816000875af115801562000172573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001989190620002ea565b505050806002620001aa919062000315565b600360156101000a81548160ff021916908360ff16021790555050505062000347565b336001600160a01b03821603620002275760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000062565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200028e57600080fd5b50565b600080600060608486031215620002a757600080fd5b8351620002b48162000278565b6020850151909350620002c78162000278565b604085015190925060ff81168114620002df57600080fd5b809150509250925092565b600060208284031215620002fd57600080fd5b815180151581146200030e57600080fd5b9392505050565b60ff81811683821602908116908181146200034057634e487b7160e01b600052601160045260246000fd5b5092915050565b60805161159162000378600039600081816102f301528181610728015281816108180152610d0901526115916000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80638f491cba116100d8578063b5a110111161008c578063e6c725f511610066578063e6c725f5146103a9578063ef686d8e146103da578063f2fde38b146103ed57600080fd5b8063b5a110111461033a578063bee518a41461034d578063ca709a251461038b57600080fd5b8063ae90de55116100bd578063ae90de55146102ce578063b0f479a1146102f1578063b187bd261461031757600080fd5b80638f491cba146102a85780639d2aede5146102bb57600080fd5b80632b6e5d631161012f57806379ba50971161011457806379ba50971461026f57806385572ffb146102775780638da5cb5b1461028a57600080fd5b80632b6e5d631461021d578063665ed5371461025c57600080fd5b8063181f5a7711610160578063181f5a77146101b95780631892b906146102025780632874d8bf1461021557600080fd5b806301ffc9a71461017c57806316c38b3c146101a4575b600080fd5b61018f61018a366004610f0b565b610400565b60405190151581526020015b60405180910390f35b6101b76101b2366004610f54565b610499565b005b6101f56040518060400160405280601881526020017f53656c6646756e64656450696e67506f6e6720312e322e30000000000000000081525081565b60405161019b9190610fda565b6101b761021036600461100a565b6104eb565b6101b7610546565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101b761026a366004610f54565b610582565b6101b761060e565b6101b7610285366004611025565b610710565b60005473ffffffffffffffffffffffffffffffffffffffff16610237565b6101b76102b6366004611060565b610795565b6101b76102c936600461109b565b610977565b60035474010000000000000000000000000000000000000000900460ff1661018f565b7f0000000000000000000000000000000000000000000000000000000000000000610237565b60025474010000000000000000000000000000000000000000900460ff1661018f565b6101b76103483660046110b8565b6109c6565b60015474010000000000000000000000000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff909116815260200161019b565b60035473ffffffffffffffffffffffffffffffffffffffff16610237565b6003547501000000000000000000000000000000000000000000900460ff1660405160ff909116815260200161019b565b6101b76103e83660046110ef565b610a68565b6101b76103fb36600461109b565b610aeb565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f85572ffb00000000000000000000000000000000000000000000000000000000148061049357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6104a1610afc565b6002805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104f3610afc565b6001805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b61054e610afc565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556105806001610b7d565b565b61058a610afc565b6003805482151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091161790556040517f05a3fef9935c9013a24c6193df2240d34fcf6b0ebf8786b85efe8401d696cdd99061060390831515815260200190565b60405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff163314610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610781576040517fd7f7333400000000000000000000000000000000000000000000000000000000815233600482015260240161068b565b61079261078d82611317565b610dc0565b50565b6003547501000000000000000000000000000000000000000000900460ff1615806107dd57506003547501000000000000000000000000000000000000000000900460ff1681105b156107e55750565b600354600190610811907501000000000000000000000000000000000000000000900460ff16836113c4565b11610792577f00000000000000000000000000000000000000000000000000000000000000006001546040517fa8d87a3b0000000000000000000000000000000000000000000000000000000081527401000000000000000000000000000000000000000090910467ffffffffffffffff16600482015273ffffffffffffffffffffffffffffffffffffffff919091169063a8d87a3b90602401602060405180830381865afa1580156108c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ec91906113ff565b73ffffffffffffffffffffffffffffffffffffffff1663eff7cc486040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561093357600080fd5b505af1158015610947573d6000803e3d6000fd5b50506040517f302777af5d26fab9dd5120c5f1307c65193ebc51daf33244ada4365fab10602c925060009150a150565b61097f610afc565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6109ce610afc565b6001805467ffffffffffffffff90931674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909316929092179091556002805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055565b610a70610afc565b600380547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000060ff8416908102919091179091556040519081527f4768dbf8645b24c54f2887651545d24f748c0d0d1d4c689eb810fb19f0befcf390602001610603565b610af3610afc565b61079281610e16565b60005473ffffffffffffffffffffffffffffffffffffffff163314610580576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161068b565b80600116600103610bc0576040518181527f48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f9060200160405180910390a1610bf4565b6040518181527f58b69f57828e6962d216502094c54f6562f3bf082ba758966c3454f9e37b15259060200160405180910390a15b610bfd81610795565b6040805160a0810190915260025473ffffffffffffffffffffffffffffffffffffffff1660c08201526000908060e08101604051602081830303815290604052815260200183604051602001610c5591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905281526020016000604051908082528060200260200182016040528015610ccf57816020015b6040805180820190915260008082526020820152815260200190600190039081610ca85790505b50815260035473ffffffffffffffffffffffffffffffffffffffff16602080830191909152604080519182018152600082529091015290507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166396f4e9f9600160149054906101000a900467ffffffffffffffff16836040518363ffffffff1660e01b8152600401610d7892919061141c565b6020604051808303816000875af1158015610d97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbb9190611531565b505050565b60008160600151806020019051810190610dda9190611531565b60025490915074010000000000000000000000000000000000000000900460ff16610e1257610e12610e0d82600161154a565b610b7d565b5050565b3373ffffffffffffffffffffffffffffffffffffffff821603610e95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161068b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610f1d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f4d57600080fd5b9392505050565b600060208284031215610f6657600080fd5b81358015158114610f4d57600080fd5b6000815180845260005b81811015610f9c57602081850181015186830182015201610f80565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610f4d6020830184610f76565b803567ffffffffffffffff8116811461100557600080fd5b919050565b60006020828403121561101c57600080fd5b610f4d82610fed565b60006020828403121561103757600080fd5b813567ffffffffffffffff81111561104e57600080fd5b820160a08185031215610f4d57600080fd5b60006020828403121561107257600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461079257600080fd5b6000602082840312156110ad57600080fd5b8135610f4d81611079565b600080604083850312156110cb57600080fd5b6110d483610fed565b915060208301356110e481611079565b809150509250929050565b60006020828403121561110157600080fd5b813560ff81168114610f4d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561116457611164611112565b60405290565b60405160a0810167ffffffffffffffff8111828210171561116457611164611112565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156111d4576111d4611112565b604052919050565b600082601f8301126111ed57600080fd5b813567ffffffffffffffff81111561120757611207611112565b61123860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161118d565b81815284602083860101111561124d57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261127b57600080fd5b8135602067ffffffffffffffff82111561129757611297611112565b6112a5818360051b0161118d565b82815260069290921b840181019181810190868411156112c457600080fd5b8286015b8481101561130c57604081890312156112e15760008081fd5b6112e9611141565b81356112f481611079565b815281850135858201528352918301916040016112c8565b509695505050505050565b600060a0823603121561132957600080fd5b61133161116a565b8235815261134160208401610fed565b6020820152604083013567ffffffffffffffff8082111561136157600080fd5b61136d368387016111dc565b6040840152606085013591508082111561138657600080fd5b611392368387016111dc565b606084015260808501359150808211156113ab57600080fd5b506113b83682860161126a565b60808301525092915050565b6000826113fa577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b60006020828403121561141157600080fd5b8151610f4d81611079565b6000604067ffffffffffffffff851683526020604081850152845160a0604086015261144b60e0860182610f76565b9050818601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808784030160608801526114868383610f76565b6040890151888203830160808a01528051808352908601945060009350908501905b808410156114e7578451805173ffffffffffffffffffffffffffffffffffffffff168352860151868301529385019360019390930192908601906114a8565b50606089015173ffffffffffffffffffffffffffffffffffffffff1660a08901526080890151888203830160c08a015295506115238187610f76565b9a9950505050505050505050565b60006020828403121561154357600080fd5b5051919050565b80820180821115610493577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000818000a", + Bin: "0x60a06040523480156200001157600080fd5b506040516200190938038062001909833981016040819052620000349162000291565b828233806000846001600160a01b0381166200006b576040516335fdcccd60e21b8152600060048201526024015b60405180910390fd5b6001600160a01b039081166080528216620000c95760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604482015260640162000062565b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000fc57620000fc81620001cd565b50506002805460ff60a01b1916905550600380546001600160a01b0319166001600160a01b0383811691821790925560405163095ea7b360e01b8152918416600483015260001960248301529063095ea7b3906044016020604051808303816000875af115801562000172573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001989190620002ea565b505050806002620001aa919062000315565b600360156101000a81548160ff021916908360ff16021790555050505062000347565b336001600160a01b03821603620002275760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000062565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200028e57600080fd5b50565b600080600060608486031215620002a757600080fd5b8351620002b48162000278565b6020850151909350620002c78162000278565b604085015190925060ff81168114620002df57600080fd5b809150509250925092565b600060208284031215620002fd57600080fd5b815180151581146200030e57600080fd5b9392505050565b60ff81811683821602908116908181146200034057634e487b7160e01b600052601160045260246000fd5b5092915050565b60805161159162000378600039600081816102f301528181610728015281816108180152610d0901526115916000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80638f491cba116100d8578063b5a110111161008c578063e6c725f511610066578063e6c725f5146103a9578063ef686d8e146103da578063f2fde38b146103ed57600080fd5b8063b5a110111461033a578063bee518a41461034d578063ca709a251461038b57600080fd5b8063ae90de55116100bd578063ae90de55146102ce578063b0f479a1146102f1578063b187bd261461031757600080fd5b80638f491cba146102a85780639d2aede5146102bb57600080fd5b80632b6e5d631161012f57806379ba50971161011457806379ba50971461026f57806385572ffb146102775780638da5cb5b1461028a57600080fd5b80632b6e5d631461021d578063665ed5371461025c57600080fd5b8063181f5a7711610160578063181f5a77146101b95780631892b906146102025780632874d8bf1461021557600080fd5b806301ffc9a71461017c57806316c38b3c146101a4575b600080fd5b61018f61018a366004610f0b565b610400565b60405190151581526020015b60405180910390f35b6101b76101b2366004610f54565b610499565b005b6101f56040518060400160405280601881526020017f53656c6646756e64656450696e67506f6e6720312e352e30000000000000000081525081565b60405161019b9190610fda565b6101b761021036600461100a565b6104eb565b6101b7610546565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101b761026a366004610f54565b610582565b6101b761060e565b6101b7610285366004611025565b610710565b60005473ffffffffffffffffffffffffffffffffffffffff16610237565b6101b76102b6366004611060565b610795565b6101b76102c936600461109b565b610977565b60035474010000000000000000000000000000000000000000900460ff1661018f565b7f0000000000000000000000000000000000000000000000000000000000000000610237565b60025474010000000000000000000000000000000000000000900460ff1661018f565b6101b76103483660046110b8565b6109c6565b60015474010000000000000000000000000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff909116815260200161019b565b60035473ffffffffffffffffffffffffffffffffffffffff16610237565b6003547501000000000000000000000000000000000000000000900460ff1660405160ff909116815260200161019b565b6101b76103e83660046110ef565b610a68565b6101b76103fb36600461109b565b610aeb565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f85572ffb00000000000000000000000000000000000000000000000000000000148061049357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6104a1610afc565b6002805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6104f3610afc565b6001805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b61054e610afc565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556105806001610b7d565b565b61058a610afc565b6003805482151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091161790556040517f05a3fef9935c9013a24c6193df2240d34fcf6b0ebf8786b85efe8401d696cdd99061060390831515815260200190565b60405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff163314610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610781576040517fd7f7333400000000000000000000000000000000000000000000000000000000815233600482015260240161068b565b61079261078d82611317565b610dc0565b50565b6003547501000000000000000000000000000000000000000000900460ff1615806107dd57506003547501000000000000000000000000000000000000000000900460ff1681105b156107e55750565b600354600190610811907501000000000000000000000000000000000000000000900460ff16836113c4565b11610792577f00000000000000000000000000000000000000000000000000000000000000006001546040517fa8d87a3b0000000000000000000000000000000000000000000000000000000081527401000000000000000000000000000000000000000090910467ffffffffffffffff16600482015273ffffffffffffffffffffffffffffffffffffffff919091169063a8d87a3b90602401602060405180830381865afa1580156108c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ec91906113ff565b73ffffffffffffffffffffffffffffffffffffffff1663eff7cc486040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561093357600080fd5b505af1158015610947573d6000803e3d6000fd5b50506040517f302777af5d26fab9dd5120c5f1307c65193ebc51daf33244ada4365fab10602c925060009150a150565b61097f610afc565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6109ce610afc565b6001805467ffffffffffffffff90931674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909316929092179091556002805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055565b610a70610afc565b600380547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000060ff8416908102919091179091556040519081527f4768dbf8645b24c54f2887651545d24f748c0d0d1d4c689eb810fb19f0befcf390602001610603565b610af3610afc565b61079281610e16565b60005473ffffffffffffffffffffffffffffffffffffffff163314610580576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161068b565b80600116600103610bc0576040518181527f48257dc961b6f792c2b78a080dacfed693b660960a702de21cee364e20270e2f9060200160405180910390a1610bf4565b6040518181527f58b69f57828e6962d216502094c54f6562f3bf082ba758966c3454f9e37b15259060200160405180910390a15b610bfd81610795565b6040805160a0810190915260025473ffffffffffffffffffffffffffffffffffffffff1660c08201526000908060e08101604051602081830303815290604052815260200183604051602001610c5591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905281526020016000604051908082528060200260200182016040528015610ccf57816020015b6040805180820190915260008082526020820152815260200190600190039081610ca85790505b50815260035473ffffffffffffffffffffffffffffffffffffffff16602080830191909152604080519182018152600082529091015290507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166396f4e9f9600160149054906101000a900467ffffffffffffffff16836040518363ffffffff1660e01b8152600401610d7892919061141c565b6020604051808303816000875af1158015610d97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbb9190611531565b505050565b60008160600151806020019051810190610dda9190611531565b60025490915074010000000000000000000000000000000000000000900460ff16610e1257610e12610e0d82600161154a565b610b7d565b5050565b3373ffffffffffffffffffffffffffffffffffffffff821603610e95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161068b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610f1d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f4d57600080fd5b9392505050565b600060208284031215610f6657600080fd5b81358015158114610f4d57600080fd5b6000815180845260005b81811015610f9c57602081850181015186830182015201610f80565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610f4d6020830184610f76565b803567ffffffffffffffff8116811461100557600080fd5b919050565b60006020828403121561101c57600080fd5b610f4d82610fed565b60006020828403121561103757600080fd5b813567ffffffffffffffff81111561104e57600080fd5b820160a08185031215610f4d57600080fd5b60006020828403121561107257600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461079257600080fd5b6000602082840312156110ad57600080fd5b8135610f4d81611079565b600080604083850312156110cb57600080fd5b6110d483610fed565b915060208301356110e481611079565b809150509250929050565b60006020828403121561110157600080fd5b813560ff81168114610f4d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561116457611164611112565b60405290565b60405160a0810167ffffffffffffffff8111828210171561116457611164611112565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156111d4576111d4611112565b604052919050565b600082601f8301126111ed57600080fd5b813567ffffffffffffffff81111561120757611207611112565b61123860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161118d565b81815284602083860101111561124d57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261127b57600080fd5b8135602067ffffffffffffffff82111561129757611297611112565b6112a5818360051b0161118d565b82815260069290921b840181019181810190868411156112c457600080fd5b8286015b8481101561130c57604081890312156112e15760008081fd5b6112e9611141565b81356112f481611079565b815281850135858201528352918301916040016112c8565b509695505050505050565b600060a0823603121561132957600080fd5b61133161116a565b8235815261134160208401610fed565b6020820152604083013567ffffffffffffffff8082111561136157600080fd5b61136d368387016111dc565b6040840152606085013591508082111561138657600080fd5b611392368387016111dc565b606084015260808501359150808211156113ab57600080fd5b506113b83682860161126a565b60808301525092915050565b6000826113fa577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b60006020828403121561141157600080fd5b8151610f4d81611079565b6000604067ffffffffffffffff851683526020604081850152845160a0604086015261144b60e0860182610f76565b9050818601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808784030160608801526114868383610f76565b6040890151888203830160808a01528051808352908601945060009350908501905b808410156114e7578451805173ffffffffffffffffffffffffffffffffffffffff168352860151868301529385019360019390930192908601906114a8565b50606089015173ffffffffffffffffffffffffffffffffffffffff1660a08901526080890151888203830160c08a015295506115238187610f76565b9a9950505050505050505050565b60006020828403121561154357600080fd5b5051919050565b80820180821115610493577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000818000a", } var SelfFundedPingPongABI = SelfFundedPingPongMetaData.ABI diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 5c3a85cb32..16dc444b43 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -24,14 +24,14 @@ nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../ ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin 76ec9676116368ab7c7c7ed45191698a12e4d975633caea32d821a1125633589 onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 123e949bc9607289382534c4432ecebe5b1da5ca92c1c6c8cc6b9be56c3352c6 -ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 4e51d70bdb6d951041518a3d7fd3b33ba8d3954bcc3d078318055b833b880324 +ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin c1c2f8a65c7ffd971899cae7fe62f2da57d09e936151e2b92163c4bebe699d6b price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 8931609776700a2a8121c9fdd757dbf9207d8b97583e70c84ec2d88c839d4a30 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 75be86323c227917a9bbc3f799d7ed02f92db546653a36db30ed0ebe64461353 report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin 20292ddaba15096fe8060567cf56cda673b947df27241d0c49d2debc838feb24 rmn_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 8b45b0fb08631c6b582fd3c0b4052a79cc2b4e091e6286af1ab131bef63661f9 rmn_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 2e4f0a7826c8abb49d882bb49fc5ff20a186dbd3137624b9097ffed903ae4888 -self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 4f339db2b670b88214b738efb7a714be9d50fa32c8008710b607d58670b22074 +self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 8ea5d75dbc3f8afd90d22c4a665a94e02892259cd16520c1c6b4cf0dc80c9148 token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 942be7d1681ac102e0615bee13f76838ebb0b261697cf1270d2bf82c12e57aeb token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 7c01fd89f5153baa4d7409d14beabb3f861abfbf8880d3c6d06802cc398570f9 usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin 8e7eae4c7277ce4a0092cca815c046cc49094028c23d2d113de9335fa4358030 From ed9aa462e79d1cadb60247e3f7e95eed7bdbb536 Mon Sep 17 00:00:00 2001 From: Suryansh <39276431+0xsuryansh@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:25:01 +0530 Subject: [PATCH 227/432] Port v1.5 fixes to v1.6 (#1286) Porting the fixes done in https://github.com/smartcontractkit/ccip/pull/1212 1. Add ~~uint32~~ `bytes destExecData` to the `struct RampTokenAmount` to allow us to send the amount we billed on source to dest 2. removed `defaultTokenDestBytesOverhead` and used `CCIP_LOCK_OR_BURN_V1_RET_BYTES` as default value --------- Signed-off-by: 0xsuryansh Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/gas-snapshots/ccip.gas-snapshot | 686 +++++++++--------- contracts/src/v0.8/ccip/PriceRegistry.sol | 23 +- .../v0.8/ccip/interfaces/IPriceRegistry.sol | 7 +- .../src/v0.8/ccip/libraries/Internal.sol | 12 +- contracts/src/v0.8/ccip/onRamp/OnRamp.sol | 9 +- .../src/v0.8/ccip/test/offRamp/OffRamp.t.sol | 40 +- .../v0.8/ccip/test/offRamp/OffRampSetup.t.sol | 6 +- .../test/priceRegistry/PriceRegistry.t.sol | 67 +- .../priceRegistry/PriceRegistrySetup.t.sol | 39 +- .../ccip/ccip_integration_tests/helpers.go | 1 - .../ccip/configs/evm/contract_reader.go | 4 +- .../ccip_reader_tester/ccip_reader_tester.go | 7 +- .../message_hasher/message_hasher.go | 5 +- .../ccip/generated/offramp/offramp.go | 5 +- .../ccip/generated/onramp/onramp.go | 7 +- .../price_registry/price_registry.go | 48 +- .../generated/report_codec/report_codec.go | 7 +- ...rapper-dependency-versions-do-not-edit.txt | 12 +- .../ccip/mocks/price_registry_interface.go | 110 +-- integration-tests/deployment/ccip/add_lane.go | 120 +++ 20 files changed, 703 insertions(+), 512 deletions(-) create mode 100644 integration-tests/deployment/ccip/add_lane.go diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 9680750a88..a573668aa9 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -10,8 +10,8 @@ AggregateTokenLimiter_getTokenBucket:test_GetTokenBucket_Success() (gas: 19691) AggregateTokenLimiter_getTokenBucket:test_Refill_Success() (gas: 40911) AggregateTokenLimiter_getTokenBucket:test_TimeUnderflow_Revert() (gas: 15368) AggregateTokenLimiter_getTokenLimitAdmin:test_GetTokenLimitAdmin_Success() (gas: 10531) -AggregateTokenLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19652) -AggregateTokenLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21237) +AggregateTokenLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19668) +AggregateTokenLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21253) AggregateTokenLimiter_rateLimitValue:test_AggregateValueMaxCapacityExceeded_Revert() (gas: 16418) AggregateTokenLimiter_rateLimitValue:test_RateLimitValueSuccess_gas() (gas: 18306) AggregateTokenLimiter_setAdmin:test_OnlyOwnerOrAdmin_Revert() (gas: 13047) @@ -34,7 +34,7 @@ BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28761) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243517) BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 23951) -CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2132726) +CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2132684) CCIPConfigSetup:test_getCapabilityConfiguration_Success() (gas: 9517) CCIPConfig_ConfigStateMachine:test__computeConfigDigest_Success() (gas: 70831) CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_InitToRunning_Success() (gas: 363664) @@ -98,16 +98,16 @@ CommitStore_isUnpausedAndRMNHealthy:test_RMN_Success() (gas: 73420) CommitStore_report:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 28670) CommitStore_report:test_InvalidInterval_Revert() (gas: 28610) CommitStore_report:test_InvalidRootRevert() (gas: 27843) -CommitStore_report:test_OnlyGasPriceUpdates_Success() (gas: 53253) -CommitStore_report:test_OnlyPriceUpdateStaleReport_Revert() (gas: 59049) -CommitStore_report:test_OnlyTokenPriceUpdates_Success() (gas: 53251) +CommitStore_report:test_OnlyGasPriceUpdates_Success() (gas: 53275) +CommitStore_report:test_OnlyPriceUpdateStaleReport_Revert() (gas: 59071) +CommitStore_report:test_OnlyTokenPriceUpdates_Success() (gas: 53273) CommitStore_report:test_Paused_Revert() (gas: 21259) -CommitStore_report:test_ReportAndPriceUpdate_Success() (gas: 84242) +CommitStore_report:test_ReportAndPriceUpdate_Success() (gas: 84264) CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56313) CommitStore_report:test_RootAlreadyCommitted_Revert() (gas: 63969) -CommitStore_report:test_StaleReportWithRoot_Success() (gas: 119332) +CommitStore_report:test_StaleReportWithRoot_Success() (gas: 119364) CommitStore_report:test_Unhealthy_Revert() (gas: 44751) -CommitStore_report:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 100714) +CommitStore_report:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 100752) CommitStore_report:test_ZeroEpochAndRound_Revert() (gas: 27626) CommitStore_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11325) CommitStore_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 143718) @@ -123,7 +123,7 @@ CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424256) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1103907) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1104033) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37797) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103733) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85258) @@ -131,20 +131,20 @@ EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_InvalidDataLength_Rev EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 94302) EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 39768) EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 86559) -EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 385176) -EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 141858) -EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 802991) -EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 179228) +EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 385246) +EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 141896) +EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 803071) +EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 179244) EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 29240) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 66444) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 43320) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 210936) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 222200) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 210968) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 222232) EVM2EVMOffRamp__report:test_Report_Success() (gas: 126637) -EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 237775) -EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246375) -EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 329796) -EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 312233) +EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 237791) +EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246391) +EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 329828) +EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 312265) EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17030) EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153727) EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5665947) @@ -152,7 +152,7 @@ EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 144461) EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21318) EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36432) EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51598) -EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 473297) +EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 473329) EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 47668) EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152359) EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 102842) @@ -163,25 +163,25 @@ EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 15734 EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 172692) EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 247069) EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114153) -EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 407419) +EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 407451) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54096) EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 131047) EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52090) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 563321) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 495444) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 563385) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 495508) EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35383) -EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 544577) +EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 544641) EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64326) EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 122322) EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 142532) EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 427337) EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18502) -EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 278065) +EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 278097) EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 18659) -EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 221405) +EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 221421) EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47881) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 47352) -EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 313885) +EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 313917) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 70008) EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 229319) EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 276790) @@ -195,13 +195,13 @@ EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 185829) EVM2EVMOffRamp_manuallyExecute:test_ManualExecForkedChain_Revert() (gas: 27049) EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 45155) EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 27468) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithMultipleMessagesAndSourceTokens_Success() (gas: 530087) -EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithSourceTokens_Success() (gas: 345726) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithMultipleMessagesAndSourceTokens_Success() (gas: 530151) +EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithSourceTokens_Success() (gas: 345758) EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187324) -EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2321890) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DestinationGasAmountCountMismatch_Revert() (gas: 362933) +EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2321906) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DestinationGasAmountCountMismatch_Revert() (gas: 362965) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143900) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_InvalidTokenGasOverride_Revert() (gas: 366072) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_InvalidTokenGasOverride_Revert() (gas: 366104) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimitManualExec_Success() (gas: 482691) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 189727) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithInvalidReceiverExecutionGasOverride_Revert() (gas: 153641) @@ -225,47 +225,47 @@ EVM2EVMOnRamp_forwardFromRouter:test_InvalidAddressEncodePacked_Revert() (gas: 3 EVM2EVMOnRamp_forwardFromRouter:test_InvalidAddress_Revert() (gas: 38440) EVM2EVMOnRamp_forwardFromRouter:test_InvalidChainSelector_Revert() (gas: 25489) EVM2EVMOnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 25275) -EVM2EVMOnRamp_forwardFromRouter:test_MaxCapacityExceeded_Revert() (gas: 85997) +EVM2EVMOnRamp_forwardFromRouter:test_MaxCapacityExceeded_Revert() (gas: 86013) EVM2EVMOnRamp_forwardFromRouter:test_MaxFeeBalanceReached_Revert() (gas: 36457) EVM2EVMOnRamp_forwardFromRouter:test_MessageGasLimitTooHigh_Revert() (gas: 29015) EVM2EVMOnRamp_forwardFromRouter:test_MessageTooLarge_Revert() (gas: 107571) EVM2EVMOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 22679) -EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 224581) +EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 224619) EVM2EVMOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 53072) EVM2EVMOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 25481) -EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59303) +EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59341) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179148) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 177430) -EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137234) +EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137254) EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3822827) EVM2EVMOnRamp_forwardFromRouter:test_TooManyTokens_Revert() (gas: 30187) EVM2EVMOnRamp_forwardFromRouter:test_Unhealthy_Revert() (gas: 43300) -EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109283) +EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109305) EVM2EVMOnRamp_forwardFromRouter:test_ZeroAddressReceiver_Revert() (gas: 312579) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_ShouldStoreLinkFees_Success() (gas: 112322) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 72206) -EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 710443) +EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 710475) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 147664) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 190529) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 121320) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2_Success() (gas: 95349) EVM2EVMOnRamp_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 20544) EVM2EVMOnRamp_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20912) -EVM2EVMOnRamp_getFee:test_EmptyMessage_Success() (gas: 78242) -EVM2EVMOnRamp_getFee:test_HighGasMessage_Success() (gas: 234090) +EVM2EVMOnRamp_getFee:test_EmptyMessage_Success() (gas: 78230) +EVM2EVMOnRamp_getFee:test_HighGasMessage_Success() (gas: 234078) EVM2EVMOnRamp_getFee:test_MessageGasLimitTooHigh_Revert() (gas: 16715) EVM2EVMOnRamp_getFee:test_MessageTooLarge_Revert() (gas: 95271) -EVM2EVMOnRamp_getFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 159352) +EVM2EVMOnRamp_getFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 159436) EVM2EVMOnRamp_getFee:test_NotAFeeToken_Revert() (gas: 24089) -EVM2EVMOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 117902) +EVM2EVMOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 117922) EVM2EVMOnRamp_getFee:test_TooManyTokens_Revert() (gas: 19902) -EVM2EVMOnRamp_getFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 64654) +EVM2EVMOnRamp_getFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 64648) EVM2EVMOnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10460) EVM2EVMOnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35195) -EVM2EVMOnRamp_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 45104) +EVM2EVMOnRamp_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 45120) EVM2EVMOnRamp_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 33019) EVM2EVMOnRamp_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 28296) -EVM2EVMOnRamp_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 126357) +EVM2EVMOnRamp_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 126453) EVM2EVMOnRamp_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 15238) EVM2EVMOnRamp_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 28104) EVM2EVMOnRamp_getTokenTransferCost:test_UnsupportedToken_Revert() (gas: 21248) @@ -377,27 +377,27 @@ MultiAggregateRateLimiter_constructor:test_Constructor_Success() (gas: 2265894) MultiAggregateRateLimiter_getTokenBucket:test_GetTokenBucket_Success() (gas: 30248) MultiAggregateRateLimiter_getTokenBucket:test_Refill_Success() (gas: 47358) MultiAggregateRateLimiter_getTokenBucket:test_TimeUnderflow_Revert() (gas: 15821) -MultiAggregateRateLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19668) -MultiAggregateRateLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21253) +MultiAggregateRateLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19684) +MultiAggregateRateLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21269) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 14527) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213612) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 60443) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213660) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 60459) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 17593) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitDisabled_Success() (gas: 44895) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExceeded_Revert() (gas: 50510) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78604) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 311885) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54696) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExceeded_Revert() (gas: 50542) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78668) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 311949) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54728) MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 9223372036854754743) MultiAggregateRateLimiter_onOutboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 19104) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 15778) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213600) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 62178) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213648) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 62194) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitDisabled_Success() (gas: 46683) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitExceeded_Revert() (gas: 52283) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitReset_Success() (gas: 79669) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 312099) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokens_Success() (gas: 56453) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitExceeded_Revert() (gas: 52315) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitReset_Success() (gas: 79733) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 312163) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokens_Success() (gas: 56485) MultiAggregateRateLimiter_setPriceRegistry:test_OnlyOwner_Revert() (gas: 11292) MultiAggregateRateLimiter_setPriceRegistry:test_Owner_Success() (gas: 19080) MultiAggregateRateLimiter_setPriceRegistry:test_ZeroAddress_Revert() (gas: 10564) @@ -438,23 +438,23 @@ MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) -MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 393648) -MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1448351) +MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 410740) +MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1486877) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71847) -NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 257252) -NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 259369) -NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 319959) -NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 295278) +NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 257298) +NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 259415) +NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 320051) +NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 295325) NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244940) NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 233260) -NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 150148) -NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 167714) -NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 218902) +NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 150194) +NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 168502) +NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 220478) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) -NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 106943) +NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 107731) NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 122943) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOffRamp_Revert() (gas: 42959) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRampAndOffRamp_Revert() (gas: 64282) @@ -487,172 +487,172 @@ OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51686) OCR2Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 23484) OCR2Base_transmit:test_UnauthorizedSigner_Revert() (gas: 39665) OCR2Base_transmit:test_WrongNumberOfSignatures_Revert() (gas: 20557) -OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 38408) -OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 106250) -OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 87409) -OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 38954) -OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 96511) -OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 41956) -OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 88684) -OffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 468115) -OffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99227) +OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 40127) +OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 107130) +OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 88331) +OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 39848) +OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 97399) +OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 42843) +OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 89579) +OffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 467917) +OffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99161) OffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12395) OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 93181) -OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 109890) +OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 109824) OffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13263) OffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17988) OffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15343) -OffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 313594) -OffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 254984) -OffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 166123) -OffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187729) -OffRamp_batchExecute:test_SingleReport_Success() (gas: 153140) -OffRamp_batchExecute:test_Unhealthy_Revert() (gas: 518887) +OffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 313729) +OffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 255119) +OffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 166168) +OffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187819) +OffRamp_batchExecute:test_SingleReport_Success() (gas: 153185) +OffRamp_batchExecute:test_Unhealthy_Revert() (gas: 532970) OffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10439) -OffRamp_ccipReceive:test_Reverts() (gas: 15684) -OffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67458) -OffRamp_commit:test_InvalidInterval_Revert() (gas: 59734) -OffRamp_commit:test_InvalidRootRevert() (gas: 58814) -OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6538106) -OffRamp_commit:test_NoConfig_Revert() (gas: 6121178) -OffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106251) -OffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116259) -OffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106272) -OffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351586) -OffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159364) -OffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136569) -OffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136859) -OffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 59082) -OffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225684) -OffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117566) -OffRamp_commit:test_Unhealthy_Revert() (gas: 77608) -OffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 205073) -OffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6532429) -OffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47788) -OffRamp_constructor:test_Constructor_Success() (gas: 6125436) -OffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137067) -OffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103784) -OffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101677) -OffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139641) -OffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101554) -OffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101599) -OffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17261) -OffRamp_execute:test_LargeBatch_Success() (gas: 1726826) -OffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 349476) -OffRamp_execute:test_MultipleReports_Success() (gas: 276933) -OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6588804) -OffRamp_execute:test_NoConfig_Revert() (gas: 6171638) -OffRamp_execute:test_NonArray_Revert() (gas: 27733) -OffRamp_execute:test_SingleReport_Success() (gas: 172458) -OffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147390) -OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6950878) -OffRamp_execute:test_ZeroReports_Revert() (gas: 17159) -OffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18190) -OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 246556) -OffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20472) -OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 205195) -OffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48734) -OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48257) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229631) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86202) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 277436) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92436) -OffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35126) -OffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23922) -OffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 475599) -OffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54456) -OffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35904) -OffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154426) -OffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35337) -OffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 184865) -OffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 196122) -OffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48073) -OffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 444686) -OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 250335) -OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 187191) -OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 206771) -OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 263519) -OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 138408) -OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 409328) -OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65876) -OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80909) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 566299) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 517689) -OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35742) -OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 517721) -OffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 515089) -OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 485207) -OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 133513) -OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 162713) -OffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3674540) -OffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118375) -OffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87586) -OffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75635) -OffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26471) -OffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 168604) -OffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205435) -OffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 26014) -OffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152948) -OffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 518487) -OffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2295740) -OffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 205788) -OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 206365) -OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 649321) -OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 318903) -OffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 164042) -OffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 23736) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 64484) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 39516) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 81512) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 176140) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 189342) -OffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11379) -OffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215398) -OffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14140) -OffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11660) -OffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49203) -OffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27147) -OffRamp_trialExecute:test_RateLimitError_Success() (gas: 221780) -OffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 230403) -OffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 297574) -OffRamp_trialExecute:test_trialExecute_Success() (gas: 279978) -OffRamp_verify:test_Blessed_Success() (gas: 176620) -OffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178688) -OffRamp_verify:test_NotBlessed_Success() (gas: 141549) +OffRamp_ccipReceive:test_Reverts() (gas: 15773) +OffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67436) +OffRamp_commit:test_InvalidInterval_Revert() (gas: 59778) +OffRamp_commit:test_InvalidRootRevert() (gas: 58858) +OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6551011) +OffRamp_commit:test_NoConfig_Revert() (gas: 6134083) +OffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106295) +OffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116369) +OffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106316) +OffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351652) +OffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159342) +OffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136480) +OffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136947) +OffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 59126) +OffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225582) +OffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117632) +OffRamp_commit:test_Unhealthy_Revert() (gas: 77652) +OffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 205066) +OffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6545334) +OffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47832) +OffRamp_constructor:test_Constructor_Success() (gas: 6137987) +OffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137086) +OffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103803) +OffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101696) +OffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139661) +OffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101573) +OffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101618) +OffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17305) +OffRamp_execute:test_LargeBatch_Success() (gas: 1728220) +OffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 349589) +OffRamp_execute:test_MultipleReports_Success() (gas: 277112) +OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6601732) +OffRamp_execute:test_NoConfig_Revert() (gas: 6184566) +OffRamp_execute:test_NonArray_Revert() (gas: 27777) +OffRamp_execute:test_SingleReport_Success() (gas: 172547) +OffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147479) +OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6963806) +OffRamp_execute:test_ZeroReports_Revert() (gas: 17203) +OffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18235) +OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249015) +OffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20517) +OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 207654) +OffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48779) +OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48302) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229610) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86181) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 280837) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92415) +OffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35127) +OffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23923) +OffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 486078) +OffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54457) +OffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35905) +OffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154471) +OffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35338) +OffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 184911) +OffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 196169) +OffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48074) +OffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 444732) +OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 250427) +OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 187283) +OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 206863) +OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 263565) +OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 138454) +OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 417627) +OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65877) +OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80910) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 576137) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 525167) +OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35743) +OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 531800) +OffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 529168) +OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 494410) +OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 133560) +OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 162760) +OffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3742124) +OffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118859) +OffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 88048) +OffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75551) +OffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26439) +OffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 168628) +OffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205504) +OffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 25993) +OffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152822) +OffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 518556) +OffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2384534) +OffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 205857) +OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 215965) +OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 649750) +OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 319062) +OffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 165822) +OffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 24603) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 66263) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 41294) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 83291) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 177934) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 191136) +OffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11423) +OffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215351) +OffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14097) +OffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11617) +OffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49137) +OffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27081) +OffRamp_trialExecute:test_RateLimitError_Success() (gas: 225773) +OffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 234394) +OffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 309206) +OffRamp_trialExecute:test_trialExecute_Success() (gas: 283972) +OffRamp_verify:test_Blessed_Success() (gas: 176664) +OffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178732) +OffRamp_verify:test_NotBlessed_Success() (gas: 141593) OffRamp_verify:test_TooManyLeaves_Revert() (gas: 51510) -OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 390322) +OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 390336) OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 63649) OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() (gas: 13308) -OnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94175) -OnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92092) -OnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97113) -OnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92150) -OnRamp_constructor:test_Constructor_Success() (gas: 2384439) -OnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 71940) -OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 112003) -OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 142773) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 142349) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 140526) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 142579) -OnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 141948) -OnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 134391) -OnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 26316) +OnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94260) +OnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92177) +OnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97198) +OnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92235) +OnRamp_constructor:test_Constructor_Success() (gas: 2455004) +OnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 72010) +OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 112791) +OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 143561) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 143137) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 141314) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 143367) +OnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 142736) +OnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 135246) +OnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 26349) OnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 133253) -OnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 24382) +OnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 24426) OnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12872) OnRamp_forwardFromRouter:test_Paused_Revert() (gas: 32033) OnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 15762) -OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179668) -OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 205937) -OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 121859) -OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 143149) -OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3872828) -OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108568) -OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 73997) -OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 262774) -OnRamp_getFee:test_EmptyMessage_Success() (gas: 104647) -OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 74120) -OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119979) +OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 182032) +OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 208301) +OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 122714) +OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 144094) +OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3887491) +OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108659) +OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 74066) +OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 273429) +OnRamp_getFee:test_EmptyMessage_Success() (gas: 104351) +OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 73173) +OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119675) OnRamp_getFee:test_Unhealthy_Revert() (gas: 43679) OnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10438) OnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35270) @@ -661,117 +661,115 @@ OnRamp_setDynamicConfig:test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Re OnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11112) OnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939) OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 51996) -OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97236) -PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150175) +OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97192) +PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150169) PingPong_plumbing:test_OutOfOrderExecution_Success() (gas: 20277) PingPong_plumbing:test_Pausing_Success() (gas: 17777) -PingPong_startPingPong:test_StartPingPong_With_OOO_Success() (gas: 163199) -PingPong_startPingPong:test_StartPingPong_With_Sequenced_Ordered_Success() (gas: 182611) -PriceRegistry_applyDestChainConfigUpdates:test_InvalidChainFamilySelector_Revert() (gas: 16725) -PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 16816) -PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestChainConfigDestChainSelectorEqZero_Revert() (gas: 16617) -PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitEqZero_Revert() (gas: 16681) -PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitGtMaxPerMessageGasLimit_Revert() (gas: 40971) -PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesZeroIntput_Success() (gas: 12341) -PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdates_Success() (gas: 139678) -PriceRegistry_applyFeeTokensUpdates:test_ApplyFeeTokensUpdates_Success() (gas: 80108) +PingPong_startPingPong:test_StartPingPong_With_OOO_Success() (gas: 163187) +PingPong_startPingPong:test_StartPingPong_With_Sequenced_Ordered_Success() (gas: 182599) +PriceRegistry_applyDestChainConfigUpdates:test_InvalidChainFamilySelector_Revert() (gas: 16503) +PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestChainConfigDestChainSelectorEqZero_Revert() (gas: 16417) +PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitEqZero_Revert() (gas: 16459) +PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitGtMaxPerMessageGasLimit_Revert() (gas: 39957) +PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesZeroIntput_Success() (gas: 12342) +PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdates_Success() (gas: 135870) +PriceRegistry_applyFeeTokensUpdates:test_ApplyFeeTokensUpdates_Success() (gas: 79896) PriceRegistry_applyFeeTokensUpdates:test_OnlyCallableByOwner_Revert() (gas: 12603) -PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 11465) -PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesMultipleTokens_Success() (gas: 54149) -PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesSingleToken_Success() (gas: 44835) -PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesZeroInput() (gas: 12301) +PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 11421) +PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesMultipleTokens_Success() (gas: 54105) +PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesSingleToken_Success() (gas: 44791) +PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesZeroInput() (gas: 12257) PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfig_Success() (gas: 86926) PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeZeroInput() (gas: 13089) PriceRegistry_applyTokenTransferFeeConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 17071) PriceRegistry_applyTokenTransferFeeConfigUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 12240) -PriceRegistry_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 101316) -PriceRegistry_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 105666) -PriceRegistry_constructor:test_InvalidStalenessThreshold_Revert() (gas: 105719) -PriceRegistry_constructor:test_Setup_Success() (gas: 5194297) -PriceRegistry_convertTokenAmount:test_ConvertTokenAmount_Success() (gas: 72751) -PriceRegistry_convertTokenAmount:test_LinkTokenNotSupported_Revert() (gas: 30981) -PriceRegistry_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 95677) -PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCostUnsupportedDestChainSelector_Success() (gas: 14636) -PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20659) -PriceRegistry_getTokenAndGasPrices:test_GetFeeTokenAndGasPrices_Success() (gas: 70449) +PriceRegistry_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 107016) +PriceRegistry_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 111366) +PriceRegistry_constructor:test_InvalidStalenessThreshold_Revert() (gas: 111419) +PriceRegistry_constructor:test_Setup_Success() (gas: 5336824) +PriceRegistry_convertTokenAmount:test_ConvertTokenAmount_Success() (gas: 72739) +PriceRegistry_convertTokenAmount:test_LinkTokenNotSupported_Revert() (gas: 30963) +PriceRegistry_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 94303) +PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCostUnsupportedDestChainSelector_Success() (gas: 14614) +PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20410) +PriceRegistry_getTokenAndGasPrices:test_GetFeeTokenAndGasPrices_Success() (gas: 70443) PriceRegistry_getTokenAndGasPrices:test_StaleGasPrice_Revert() (gas: 16838) PriceRegistry_getTokenAndGasPrices:test_UnsupportedChain_Revert() (gas: 16140) -PriceRegistry_getTokenAndGasPrices:test_ZeroGasPrice_Success() (gas: 45734) -PriceRegistry_getTokenPrice:test_GetTokenPriceFromFeed_Success() (gas: 62308) -PriceRegistry_getTokenPrices:test_GetTokenPrices_Success() (gas: 84796) -PriceRegistry_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 41277) -PriceRegistry_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 34727) -PriceRegistry_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 27801) -PriceRegistry_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 101840) -PriceRegistry_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 20398) -PriceRegistry_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 27676) -PriceRegistry_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 27632) -PriceRegistry_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 40058) -PriceRegistry_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29359) -PriceRegistry_getValidatedFee:test_DestinationChainNotEnabled_Revert() (gas: 18248) -PriceRegistry_getValidatedFee:test_EmptyMessage_Success() (gas: 81644) -PriceRegistry_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 55241) -PriceRegistry_getValidatedFee:test_HighGasMessage_Success() (gas: 238106) -PriceRegistry_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 20016) -PriceRegistry_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 31820) -PriceRegistry_getValidatedFee:test_MessageTooLarge_Revert() (gas: 97759) -PriceRegistry_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 143549) -PriceRegistry_getValidatedFee:test_NotAFeeToken_Revert() (gas: 29480) -PriceRegistry_getValidatedFee:test_SingleTokenMessage_Success() (gas: 112551) -PriceRegistry_getValidatedFee:test_TooManyTokens_Revert() (gas: 20152) -PriceRegistry_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 63052) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Above18Decimals_Success() (gas: 2094595) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Below18Decimals_Success() (gas: 2094553) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt0Decimals_Success() (gas: 2074672) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt18Decimals_Success() (gas: 2094327) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFlippedDecimals_Success() (gas: 2094531) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedMaxInt224Value_Success() (gas: 2094343) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedOverStalenessPeriod_Success() (gas: 62060) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeed_Success() (gas: 61940) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPrice_Success() (gas: 61020) -PriceRegistry_getValidatedTokenPrice:test_OverflowFeedPrice_Revert() (gas: 2094030) -PriceRegistry_getValidatedTokenPrice:test_StaleFeeToken_Success() (gas: 61547) -PriceRegistry_getValidatedTokenPrice:test_TokenNotSupportedFeed_Revert() (gas: 109176) -PriceRegistry_getValidatedTokenPrice:test_TokenNotSupported_Revert() (gas: 13841) -PriceRegistry_getValidatedTokenPrice:test_UnderflowFeedPrice_Revert() (gas: 2092692) -PriceRegistry_onReport:test_OnReport_StaleUpdate_Revert() (gas: 43415) +PriceRegistry_getTokenAndGasPrices:test_ZeroGasPrice_Success() (gas: 45750) +PriceRegistry_getTokenPrice:test_GetTokenPriceFromFeed_Success() (gas: 62252) +PriceRegistry_getTokenPrices:test_GetTokenPrices_Success() (gas: 84800) +PriceRegistry_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 41227) +PriceRegistry_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 34682) +PriceRegistry_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 27756) +PriceRegistry_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 101624) +PriceRegistry_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 20354) +PriceRegistry_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 27631) +PriceRegistry_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 27587) +PriceRegistry_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 40013) +PriceRegistry_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29299) +PriceRegistry_getValidatedFee:test_DestinationChainNotEnabled_Revert() (gas: 18180) +PriceRegistry_getValidatedFee:test_EmptyMessage_Success() (gas: 81054) +PriceRegistry_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 54294) +PriceRegistry_getValidatedFee:test_HighGasMessage_Success() (gas: 237472) +PriceRegistry_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 19949) +PriceRegistry_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 31746) +PriceRegistry_getValidatedFee:test_MessageTooLarge_Revert() (gas: 97692) +PriceRegistry_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 142833) +PriceRegistry_getValidatedFee:test_NotAFeeToken_Revert() (gas: 29407) +PriceRegistry_getValidatedFee:test_SingleTokenMessage_Success() (gas: 111861) +PriceRegistry_getValidatedFee:test_TooManyTokens_Revert() (gas: 20085) +PriceRegistry_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 61933) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Above18Decimals_Success() (gas: 2094539) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Below18Decimals_Success() (gas: 2094497) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt0Decimals_Success() (gas: 2074616) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt18Decimals_Success() (gas: 2094271) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFlippedDecimals_Success() (gas: 2094475) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedMaxInt224Value_Success() (gas: 2094287) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedOverStalenessPeriod_Success() (gas: 62004) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeed_Success() (gas: 61884) +PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPrice_Success() (gas: 61036) +PriceRegistry_getValidatedTokenPrice:test_OverflowFeedPrice_Revert() (gas: 2093974) +PriceRegistry_getValidatedTokenPrice:test_StaleFeeToken_Success() (gas: 61563) +PriceRegistry_getValidatedTokenPrice:test_TokenNotSupportedFeed_Revert() (gas: 109120) +PriceRegistry_getValidatedTokenPrice:test_TokenNotSupported_Revert() (gas: 13857) +PriceRegistry_getValidatedTokenPrice:test_UnderflowFeedPrice_Revert() (gas: 2092636) +PriceRegistry_onReport:test_OnReport_StaleUpdate_Revert() (gas: 43359) PriceRegistry_onReport:test_onReport_InvalidForwarder_Reverts() (gas: 23261) -PriceRegistry_onReport:test_onReport_Success() (gas: 80702) -PriceRegistry_onReport:test_onReport_UnsupportedToken_Reverts() (gas: 26681) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsDefault_Success() (gas: 17316) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsEnforceOutOfOrder_Revert() (gas: 21410) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsGasLimitTooHigh_Revert() (gas: 18507) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsInvalidExtraArgsTag_Revert() (gas: 18031) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV1_Success() (gas: 18408) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV2_Success() (gas: 18525) -PriceRegistry_processMessageArgs:test_InvalidExtraArgs_Revert() (gas: 18328) -PriceRegistry_processMessageArgs:test_MalformedEVMExtraArgs_Revert() (gas: 18874) -PriceRegistry_processMessageArgs:test_MessageFeeTooHigh_Revert() (gas: 16382) -PriceRegistry_processMessageArgs:test_WitEVMExtraArgsV2_Success() (gas: 26303) -PriceRegistry_processMessageArgs:test_WithConvertedTokenAmount_Success() (gas: 32432) -PriceRegistry_processMessageArgs:test_WithEVMExtraArgsV1_Success() (gas: 25915) -PriceRegistry_processMessageArgs:test_WithEmptyEVMExtraArgs_Success() (gas: 23730) -PriceRegistry_processMessageArgs:test_WithLinkTokenAmount_Success() (gas: 17342) -PriceRegistry_updatePrices:test_OnlyCallableByUpdater_Revert() (gas: 12080) -PriceRegistry_updatePrices:test_OnlyGasPrice_Success() (gas: 23621) -PriceRegistry_updatePrices:test_OnlyTokenPrice_Success() (gas: 30593) -PriceRegistry_updatePrices:test_UpdatableByAuthorizedCaller_Success() (gas: 75937) -PriceRegistry_updatePrices:test_UpdateMultiplePrices_Success() (gas: 151455) -PriceRegistry_updateTokenPriceFeeds:test_FeedNotUpdated() (gas: 50633) -PriceRegistry_updateTokenPriceFeeds:test_FeedUnset_Success() (gas: 63662) -PriceRegistry_updateTokenPriceFeeds:test_FeedUpdatedByNonOwner_Revert() (gas: 19998) -PriceRegistry_updateTokenPriceFeeds:test_MultipleFeedUpdate_Success() (gas: 88898) -PriceRegistry_updateTokenPriceFeeds:test_SingleFeedUpdate_Success() (gas: 50817) -PriceRegistry_updateTokenPriceFeeds:test_ZeroFeeds_Success() (gas: 12362) -PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddressEncodePacked_Revert() (gas: 10572) -PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddressPrecompiles_Revert() (gas: 3916546) -PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddress_Revert() (gas: 10756) -PriceRegistry_validateDestFamilyAddress:test_ValidEVMAddress_Success() (gas: 6660) -PriceRegistry_validateDestFamilyAddress:test_ValidNonEVMAddress_Success() (gas: 6440) -PriceRegistry_validatePoolReturnData:test_InvalidEVMAddressDestToken_Revert() (gas: 35479) -PriceRegistry_validatePoolReturnData:test_SourceTokenDataTooLarge_Revert() (gas: 90819) -PriceRegistry_validatePoolReturnData:test_TokenAmountArraysMismatching_Revert() (gas: 32771) -PriceRegistry_validatePoolReturnData:test_WithSingleToken_Success() (gas: 31315) +PriceRegistry_onReport:test_onReport_Success() (gas: 80666) +PriceRegistry_onReport:test_onReport_UnsupportedToken_Reverts() (gas: 26675) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsDefault_Success() (gas: 17185) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsEnforceOutOfOrder_Revert() (gas: 21290) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsGasLimitTooHigh_Revert() (gas: 18387) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsInvalidExtraArgsTag_Revert() (gas: 17911) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV1_Success() (gas: 18285) +PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV2_Success() (gas: 18401) +PriceRegistry_processMessageArgs:test_InvalidExtraArgs_Revert() (gas: 18361) +PriceRegistry_processMessageArgs:test_MalformedEVMExtraArgs_Revert() (gas: 18907) +PriceRegistry_processMessageArgs:test_MessageFeeTooHigh_Revert() (gas: 16426) +PriceRegistry_processMessageArgs:test_WitEVMExtraArgsV2_Success() (gas: 26269) +PriceRegistry_processMessageArgs:test_WithConvertedTokenAmount_Success() (gas: 32441) +PriceRegistry_processMessageArgs:test_WithEVMExtraArgsV1_Success() (gas: 25881) +PriceRegistry_processMessageArgs:test_WithEmptyEVMExtraArgs_Success() (gas: 23696) +PriceRegistry_processMessageArgs:test_WithLinkTokenAmount_Success() (gas: 17375) +PriceRegistry_processPoolReturnData:test_InvalidEVMAddressDestToken_Revert() (gas: 42784) +PriceRegistry_processPoolReturnData:test_SourceTokenDataTooLarge_Revert() (gas: 107735) +PriceRegistry_processPoolReturnData:test_TokenAmountArraysMismatching_Revert() (gas: 40104) +PriceRegistry_updatePrices:test_OnlyCallableByUpdater_Revert() (gas: 12102) +PriceRegistry_updatePrices:test_OnlyGasPrice_Success() (gas: 23599) +PriceRegistry_updatePrices:test_OnlyTokenPrice_Success() (gas: 30631) +PriceRegistry_updatePrices:test_UpdatableByAuthorizedCaller_Success() (gas: 76003) +PriceRegistry_updatePrices:test_UpdateMultiplePrices_Success() (gas: 151393) +PriceRegistry_updateTokenPriceFeeds:test_FeedNotUpdated() (gas: 50527) +PriceRegistry_updateTokenPriceFeeds:test_FeedUnset_Success() (gas: 63626) +PriceRegistry_updateTokenPriceFeeds:test_FeedUpdatedByNonOwner_Revert() (gas: 19932) +PriceRegistry_updateTokenPriceFeeds:test_MultipleFeedUpdate_Success() (gas: 88972) +PriceRegistry_updateTokenPriceFeeds:test_SingleFeedUpdate_Success() (gas: 50821) +PriceRegistry_updateTokenPriceFeeds:test_ZeroFeeds_Success() (gas: 12296) +PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddressEncodePacked_Revert() (gas: 10616) +PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddressPrecompiles_Revert() (gas: 3961646) +PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddress_Revert() (gas: 10800) +PriceRegistry_validateDestFamilyAddress:test_ValidEVMAddress_Success() (gas: 6704) +PriceRegistry_validateDestFamilyAddress:test_ValidNonEVMAddress_Success() (gas: 6484) RMNHome:test() (gas: 186) RMN_constructor:test_Constructor_Success() (gas: 48838) RMN_getRecordedCurseRelatedOps:test_OpsPostDeployment() (gas: 19666) @@ -852,24 +850,24 @@ Router_applyRampUpdates:test_OffRampMismatch_Revert() (gas: 89288) Router_applyRampUpdates:test_OffRampUpdatesWithRouting() (gas: 10642128) Router_applyRampUpdates:test_OnRampDisable() (gas: 55913) Router_applyRampUpdates:test_OnlyOwner_Revert() (gas: 12311) -Router_ccipSend:test_CCIPSendLinkFeeNoTokenSuccess_gas() (gas: 113886) -Router_ccipSend:test_CCIPSendLinkFeeOneTokenSuccess_gas() (gas: 201342) -Router_ccipSend:test_CCIPSendNativeFeeNoTokenSuccess_gas() (gas: 128533) -Router_ccipSend:test_CCIPSendNativeFeeOneTokenSuccess_gas() (gas: 215991) -Router_ccipSend:test_FeeTokenAmountTooLow_Revert() (gas: 66275) +Router_ccipSend:test_CCIPSendLinkFeeNoTokenSuccess_gas() (gas: 113880) +Router_ccipSend:test_CCIPSendLinkFeeOneTokenSuccess_gas() (gas: 201336) +Router_ccipSend:test_CCIPSendNativeFeeNoTokenSuccess_gas() (gas: 128515) +Router_ccipSend:test_CCIPSendNativeFeeOneTokenSuccess_gas() (gas: 215973) +Router_ccipSend:test_FeeTokenAmountTooLow_Revert() (gas: 66269) Router_ccipSend:test_InvalidMsgValue() (gas: 31963) -Router_ccipSend:test_NativeFeeTokenInsufficientValue() (gas: 68746) -Router_ccipSend:test_NativeFeeTokenOverpay_Success() (gas: 173630) -Router_ccipSend:test_NativeFeeTokenZeroValue() (gas: 56037) -Router_ccipSend:test_NativeFeeToken_Success() (gas: 172224) -Router_ccipSend:test_NonLinkFeeToken_Success() (gas: 242732) +Router_ccipSend:test_NativeFeeTokenInsufficientValue() (gas: 68740) +Router_ccipSend:test_NativeFeeTokenOverpay_Success() (gas: 173606) +Router_ccipSend:test_NativeFeeTokenZeroValue() (gas: 56031) +Router_ccipSend:test_NativeFeeToken_Success() (gas: 172200) +Router_ccipSend:test_NonLinkFeeToken_Success() (gas: 242714) Router_ccipSend:test_UnsupportedDestinationChain_Revert() (gas: 24749) Router_ccipSend:test_WhenNotHealthy_Revert() (gas: 44724) -Router_ccipSend:test_WrappedNativeFeeToken_Success() (gas: 174440) -Router_ccipSend:test_ZeroFeeAndGasPrice_Success() (gas: 244856) +Router_ccipSend:test_WrappedNativeFeeToken_Success() (gas: 174416) +Router_ccipSend:test_ZeroFeeAndGasPrice_Success() (gas: 244854) Router_constructor:test_Constructor_Success() (gas: 13074) Router_getArmProxy:test_getArmProxy() (gas: 10561) -Router_getFee:test_GetFeeSupportedChain_Success() (gas: 46464) +Router_getFee:test_GetFeeSupportedChain_Success() (gas: 46458) Router_getFee:test_UnsupportedDestinationChain_Revert() (gas: 17138) Router_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10460) Router_recoverTokens:test_RecoverTokensInvalidRecipient_Revert() (gas: 11316) @@ -884,7 +882,7 @@ Router_routeMessage:test_OnlyOffRamp_Revert() (gas: 25116) Router_routeMessage:test_WhenNotHealthy_Revert() (gas: 44724) Router_setWrappedNative:test_OnlyOwner_Revert() (gas: 10985) SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 53531) -SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 417002) +SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 416966) SelfFundedPingPong_setCountIncrBeforeFunding:test_setCountIncrBeforeFunding() (gas: 20151) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_OnlyPendingAdministrator_Revert() (gas: 51085) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_Success() (gas: 43947) @@ -912,8 +910,8 @@ TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6070353) TokenPoolAndProxy:test_lockOrBurn_burnWithFromMint_Success() (gas: 6101826) TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6319594) TokenPoolAndProxy:test_setPreviousPool_Success() (gas: 3387124) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6913796) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7097821) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6913778) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7097803) TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2209837) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12089) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23324) @@ -942,16 +940,16 @@ TokenPool_setRemotePool:test_setRemotePool_NonExistentChain_Reverts() (gas: 1562 TokenPool_setRemotePool:test_setRemotePool_OnlyOwner_Reverts() (gas: 13195) TokenPool_setRemotePool:test_setRemotePool_Success() (gas: 281912) TokenProxy_ccipSend:test_CcipSendGasShouldBeZero_Revert() (gas: 17109) -TokenProxy_ccipSend:test_CcipSendInsufficientAllowance_Revert() (gas: 136228) +TokenProxy_ccipSend:test_CcipSendInsufficientAllowance_Revert() (gas: 136222) TokenProxy_ccipSend:test_CcipSendInvalidToken_Revert() (gas: 15919) -TokenProxy_ccipSend:test_CcipSendNative_Success() (gas: 245191) +TokenProxy_ccipSend:test_CcipSendNative_Success() (gas: 245173) TokenProxy_ccipSend:test_CcipSendNoDataAllowed_Revert() (gas: 16303) -TokenProxy_ccipSend:test_CcipSend_Success() (gas: 261568) +TokenProxy_ccipSend:test_CcipSend_Success() (gas: 261558) TokenProxy_constructor:test_Constructor() (gas: 13812) TokenProxy_getFee:test_GetFeeGasShouldBeZero_Revert() (gas: 16827) TokenProxy_getFee:test_GetFeeInvalidToken_Revert() (gas: 12658) TokenProxy_getFee:test_GetFeeNoDataAllowed_Revert() (gas: 15849) -TokenProxy_getFee:test_GetFee_Success() (gas: 86702) +TokenProxy_getFee:test_GetFee_Success() (gas: 86690) USDCTokenPool__validateMessage:test_ValidateInvalidMessage_Revert() (gas: 25290) USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35322) USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 30073) diff --git a/contracts/src/v0.8/ccip/PriceRegistry.sol b/contracts/src/v0.8/ccip/PriceRegistry.sol index f9989f9363..8593568371 100644 --- a/contracts/src/v0.8/ccip/PriceRegistry.sol +++ b/contracts/src/v0.8/ccip/PriceRegistry.sol @@ -98,8 +98,7 @@ contract PriceRegistry is // The following three properties are defaults, they can be overridden by setting the TokenTransferFeeConfig for a token uint16 defaultTokenFeeUSDCents; // │ Default token fee charged per token transfer uint32 defaultTokenDestGasOverhead; // ──────╯ Default gas charged to execute the token transfer on the destination chain - uint32 defaultTokenDestBytesOverhead; // ────╮ Default extra data availability bytes charged per token transfer - uint32 defaultTxGasLimit; // │ Default gas limit for a tx + uint32 defaultTxGasLimit; //─────────────────╮ Default gas limit for a tx uint64 gasMultiplierWeiPerEth; // │ Multiplier for gas costs, 1e18 based so 11e17 = 10% extra cost. uint32 networkFeeUSDCents; // │ Flat network fee to charge for messages, multiples of 0.01 USD bool enforceOutOfOrder; // │ Whether to enforce the allowOutOfOrderExecution extraArg value to be true. @@ -601,7 +600,7 @@ contract PriceRegistry is if (!transferFeeConfig.isEnabled) { tokenTransferFeeUSDWei += uint256(destChainConfig.defaultTokenFeeUSDCents) * 1e16; tokenTransferGas += destChainConfig.defaultTokenDestGasOverhead; - tokenTransferBytesOverhead += destChainConfig.defaultTokenDestBytesOverhead; + tokenTransferBytesOverhead += Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES; continue; } @@ -867,13 +866,13 @@ contract PriceRegistry is /// @inheritdoc IPriceRegistry /// @dev precondition - rampTokenAmounts and sourceTokenAmounts lengths must be equal - function validatePoolReturnData( + function processPoolReturnData( uint64 destChainSelector, Internal.RampTokenAmount[] calldata rampTokenAmounts, Client.EVMTokenAmount[] calldata sourceTokenAmounts - ) external view { + ) external view returns (bytes[] memory destExecDataPerToken) { bytes4 chainFamilySelector = s_destChainConfigs[destChainSelector].chainFamilySelector; - + destExecDataPerToken = new bytes[](rampTokenAmounts.length); for (uint256 i = 0; i < rampTokenAmounts.length; ++i) { address sourceToken = sourceTokenAmounts[i].token; @@ -888,7 +887,18 @@ contract PriceRegistry is } _validateDestFamilyAddress(chainFamilySelector, rampTokenAmounts[i].destTokenAddress); + PriceRegistry.TokenTransferFeeConfig memory tokenTransferFeeConfig = + s_tokenTransferFeeConfig[destChainSelector][sourceToken]; + uint32 defaultGasOverhead = s_destChainConfigs[destChainSelector].defaultTokenDestGasOverhead; + // NOTE: Revisit this when adding new non-EVM chain family selector support + uint32 destGasAmount = + tokenTransferFeeConfig.isEnabled ? tokenTransferFeeConfig.destGasOverhead : defaultGasOverhead; + + // The user will be billed either the default or the override, so we send the exact amount that we billed for + // to the destination chain to be used for the token releaseOrMint and transfer. + destExecDataPerToken[i] = abi.encode(destGasAmount); } + return destExecDataPerToken; } // ================================================================ @@ -919,7 +929,6 @@ contract PriceRegistry is if ( destChainSelector == 0 || destChainConfig.defaultTxGasLimit == 0 || destChainConfig.chainFamilySelector != Internal.CHAIN_FAMILY_SELECTOR_EVM - || destChainConfig.defaultTokenDestBytesOverhead < Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES || destChainConfig.defaultTxGasLimit > destChainConfig.maxPerMsgGasLimit ) { revert InvalidDestChainConfig(destChainSelector); diff --git a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol index a29db78e04..05d68b3183 100644 --- a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol +++ b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol @@ -101,9 +101,10 @@ interface IPriceRegistry { /// @param destChainSelector Destination chain selector to which the token amounts are sent to /// @param rampTokenAmounts Token amounts with populated pool return data /// @param sourceTokenAmounts Token amounts originally sent in a Client.EVM2AnyMessage message - function validatePoolReturnData( + /// @return destExecData Destination chain execution data + function processPoolReturnData( uint64 destChainSelector, - Internal.RampTokenAmount[] calldata rampTokenAmounts, + Internal.RampTokenAmount[] memory rampTokenAmounts, Client.EVMTokenAmount[] calldata sourceTokenAmounts - ) external view; + ) external view returns (bytes[] memory); } diff --git a/contracts/src/v0.8/ccip/libraries/Internal.sol b/contracts/src/v0.8/ccip/libraries/Internal.sol index bd1ee48d9a..9b251eedcf 100644 --- a/contracts/src/v0.8/ccip/libraries/Internal.sol +++ b/contracts/src/v0.8/ccip/libraries/Internal.sol @@ -140,10 +140,11 @@ library Internal { uint256 public constant ANY_2_EVM_MESSAGE_FIXED_BYTES = 32 * 14; /// @dev Each token transfer adds 1 RampTokenAmount - /// RampTokenAmount has 4 fields, including 3 bytes. - /// Each bytes takes 1 more slot to store its length, and one slot to store the offset. - /// When abi encoded, each token transfer takes up 10 slots, excl bytes contents. - uint256 public constant ANY_2_EVM_MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * 10; + /// RampTokenAmount has 5 fields, 3 of which are bytes type, 1 uint256 and 1 uint32. + /// Each bytes type takes 1 slot for length, 1 slot for data and 1 slot for the offset. + /// uint256 amount takes 1 slot. + /// uint32 destGasAmount takes 1 slot. + uint256 public constant ANY_2_EVM_MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * ((3 * 3) + 2); bytes32 internal constant EVM_2_EVM_MESSAGE_HASH = keccak256("EVM2EVMMessageHashV2"); @@ -294,6 +295,9 @@ library Internal { // has to be set for the specific token. bytes extraData; uint256 amount; // Amount of tokens. + // Destination chain specific execution data encoded in bytes + //(for EVM destination it consists of the amount of gas available for the releaseOrMint and transfer calls on the offRamp + bytes destExecData; } /// @notice Family-agnostic header for OnRamp & OffRamp messages. diff --git a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol index dc25354668..6de57bf548 100644 --- a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol @@ -191,10 +191,14 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { } // Validate pool return data after it is populated (view function - no state changes) - IPriceRegistry(s_dynamicConfig.priceRegistry).validatePoolReturnData( + bytes[] memory destExecDataPerToken = IPriceRegistry(s_dynamicConfig.priceRegistry).processPoolReturnData( destChainSelector, newMessage.tokenAmounts, message.tokenAmounts ); + for (uint256 i = 0; i < newMessage.tokenAmounts.length; ++i) { + newMessage.tokenAmounts[i].destExecData = destExecDataPerToken[i]; + } + // Override extraArgs with latest version newMessage.extraArgs = convertedExtraArgs; @@ -251,7 +255,8 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { sourcePoolAddress: abi.encode(sourcePool), destTokenAddress: poolReturnData.destTokenAddress, extraData: poolReturnData.destPoolData, - amount: tokenAndAmount.amount + amount: tokenAndAmount.amount, + destExecData: "" // This is set in the processPoolReturnData function }); } diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol index 70e5689679..04c7b0b63b 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol @@ -1307,12 +1307,12 @@ contract OffRamp_manuallyExecute is OffRampSetup { s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); s_reverting_receiver.setRevert(false); + uint256[][] memory gasLimitOverrides = new uint256[][](1); gasLimitOverrides[0] = _getGasLimitsFromMessages(messages); gasLimitOverrides[0][0] += 1; - + vm.recordLogs(); s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); - assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, @@ -1664,7 +1664,8 @@ contract OffRamp_manuallyExecute is OffRampSetup { sourcePoolAddress: abi.encode(s_sourcePoolByToken[s_sourceFeeToken]), destTokenAddress: abi.encode(s_destTokenBySourceToken[s_sourceFeeToken]), extraData: "", - amount: tokenAmount + amount: tokenAmount, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); messages[0].receiver = address(receiver); @@ -2216,7 +2217,8 @@ contract OffRamp_trialExecute is OffRampSetup { sourcePoolAddress: abi.encode(address(0)), destTokenAddress: abi.encode(address(0)), extraData: "", - amount: message.tokenAmounts[0].amount + amount: message.tokenAmounts[0].amount, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); message.header.messageId = Internal._hash(message, ON_RAMP_ADDRESS_1); @@ -2233,7 +2235,8 @@ contract OffRamp_trialExecute is OffRampSetup { sourcePoolAddress: abi.encode(address(0)), destTokenAddress: abi.encode(notAContract), extraData: "", - amount: message.tokenAmounts[0].amount + amount: message.tokenAmounts[0].amount, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); message.header.messageId = Internal._hash(message, ON_RAMP_ADDRESS_1); @@ -2264,7 +2267,8 @@ contract OffRamp__releaseOrMintSingleToken is OffRampSetup { sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), extraData: "", - amount: amount + amount: amount, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); vm.expectCall( @@ -2297,7 +2301,8 @@ contract OffRamp__releaseOrMintSingleToken is OffRampSetup { sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), extraData: "", - amount: amount + amount: amount, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); // Mock the call so returns 2 slots of data @@ -2318,7 +2323,8 @@ contract OffRamp__releaseOrMintSingleToken is OffRampSetup { sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), extraData: "", - amount: amount + amount: amount, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); bytes memory revertData = "failed to balanceOf"; @@ -2342,7 +2348,8 @@ contract OffRamp__releaseOrMintSingleToken is OffRampSetup { sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), extraData: "", - amount: amount + amount: amount, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); vm.mockCall( @@ -2369,7 +2376,8 @@ contract OffRamp__releaseOrMintSingleToken is OffRampSetup { sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), destTokenAddress: abi.encode(s_destTokenBySourceToken[token]), extraData: "", - amount: amount + amount: amount, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); // This should make the call fail if it does not skip the check @@ -2396,7 +2404,8 @@ contract OffRamp__releaseOrMintSingleToken is OffRampSetup { sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), destTokenAddress: abi.encode(destToken), extraData: "", - amount: amount + amount: amount, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); // Address(0) should always revert @@ -2438,7 +2447,8 @@ contract OffRamp__releaseOrMintSingleToken is OffRampSetup { sourcePoolAddress: abi.encode(s_sourcePoolByToken[token]), destTokenAddress: abi.encode(destToken), extraData: "", - amount: amount + amount: amount, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); bytes memory revertData = "call reverted :o"; @@ -2594,7 +2604,8 @@ contract OffRamp_releaseOrMintTokens is OffRampSetup { sourcePoolAddress: abi.encode(fakePoolAddress), destTokenAddress: abi.encode(s_offRamp), extraData: "", - amount: 1 + amount: 1, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); vm.expectRevert(abi.encodeWithSelector(OffRamp.NotACompatiblePool.selector, address(0))); @@ -2646,7 +2657,8 @@ contract OffRamp_releaseOrMintTokens is OffRampSetup { sourcePoolAddress: unusedVar, destTokenAddress: abi.encode(destPool), extraData: unusedVar, - amount: 1 + amount: 1, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); try s_offRamp.releaseOrMintTokens( diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol index 8156c8c14a..fb61fbfc7d 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol @@ -297,7 +297,8 @@ contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { sourcePoolAddress: abi.encode(s_sourcePoolByToken[tokenAmounts[i].token]), destTokenAddress: abi.encode(s_destTokenBySourceToken[tokenAmounts[i].token]), extraData: "", - amount: tokenAmounts[i].amount + amount: tokenAmounts[i].amount, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); } @@ -414,7 +415,8 @@ contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { sourcePoolAddress: abi.encode(s_sourcePoolByToken[srcTokenAmounts[i].token]), destTokenAddress: abi.encode(s_destTokenBySourceToken[srcTokenAmounts[i].token]), extraData: "", - amount: srcTokenAmounts[i].amount + amount: srcTokenAmounts[i].amount, + destExecData: abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD) }); } return sourceTokenData; diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol index bc7b3159b6..dbbc4b32cd 100644 --- a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol +++ b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol @@ -748,13 +748,6 @@ contract PriceRegistry_applyDestChainConfigUpdates is PriceRegistrySetup { destChainConfigArgs.destChainConfig.defaultTxGasLimit, 1, destChainConfigArgs.destChainConfig.maxPerMsgGasLimit ) ); - destChainConfigArgs.destChainConfig.defaultTokenDestBytesOverhead = uint32( - bound( - destChainConfigArgs.destChainConfig.defaultTokenDestBytesOverhead, - Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES, - type(uint32).max - ) - ); destChainConfigArgs.destChainConfig.chainFamilySelector = Internal.CHAIN_FAMILY_SELECTOR_EVM; bool isNewChain = destChainConfigArgs.destChainSelector != DEST_CHAIN_SELECTOR; @@ -852,17 +845,6 @@ contract PriceRegistry_applyDestChainConfigUpdates is PriceRegistrySetup { s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); } - function test_InvalidDestBytesOverhead_Revert() public { - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); - PriceRegistry.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; - - destChainConfigArg.destChainConfig.defaultTokenDestBytesOverhead = uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES - 1); - - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.InvalidDestChainConfig.selector, DEST_CHAIN_SELECTOR)); - - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); - } - function test_InvalidChainFamilySelector_Revert() public { PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); PriceRegistry.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; @@ -969,8 +951,6 @@ contract PriceRegistry_getDataAvailabilityCost is PriceRegistrySetup { destChainConfigArgs[0].destChainConfig.defaultTxGasLimit = GAS_LIMIT; destChainConfigArgs[0].destChainConfig.maxPerMsgGasLimit = GAS_LIMIT; destChainConfigArgs[0].destChainConfig.chainFamilySelector = Internal.CHAIN_FAMILY_SELECTOR_EVM; - destChainConfigArgs[0].destChainConfig.defaultTokenDestBytesOverhead = DEFAULT_TOKEN_BYTES_OVERHEAD; - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); uint256 dataAvailabilityCostUSD = s_priceRegistry.getDataAvailabilityCost( @@ -1889,31 +1869,44 @@ contract PriceRegistry_processMessageArgs is PriceRegistryFeeSetup { } } -contract PriceRegistry_validatePoolReturnData is PriceRegistryFeeSetup { - function test_WithSingleToken_Success() public view { - Client.EVMTokenAmount[] memory sourceTokenAmounts = new Client.EVMTokenAmount[](1); +contract PriceRegistry_processPoolReturnData is PriceRegistryFeeSetup { + function Test_ProcessPoolReturnData_Success() public view { + Client.EVMTokenAmount[] memory sourceTokenAmounts = new Client.EVMTokenAmount[](2); sourceTokenAmounts[0].amount = 1e18; sourceTokenAmounts[0].token = s_sourceTokens[0]; + sourceTokenAmounts[1].amount = 1e18; + sourceTokenAmounts[1].token = CUSTOM_TOKEN_2; - Internal.RampTokenAmount[] memory rampTokenAmounts = new Internal.RampTokenAmount[](1); - rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry); + Internal.RampTokenAmount[] memory rampTokenAmounts = new Internal.RampTokenAmount[](2); + rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry, DEST_CHAIN_SELECTOR); + rampTokenAmounts[1] = _getSourceTokenData(sourceTokenAmounts[1], s_tokenAdminRegistry, DEST_CHAIN_SELECTOR); + bytes[] memory expectedDestExecData = new bytes[](2); + expectedDestExecData[0] = abi.encode( + s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig.destGasOverhead + ); + expectedDestExecData[1] = abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD); //expected return data should be abi.encoded default as isEnabled is false // No revert - successful - s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + bytes[] memory destExecData = + s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + + for (uint256 i = 0; i < destExecData.length; ++i) { + assertEq(destExecData[i], expectedDestExecData[i]); + } } function test_TokenAmountArraysMismatching_Revert() public { - Client.EVMTokenAmount[] memory sourceTokenAmounts = new Client.EVMTokenAmount[](1); + Client.EVMTokenAmount[] memory sourceTokenAmounts = new Client.EVMTokenAmount[](2); sourceTokenAmounts[0].amount = 1e18; sourceTokenAmounts[0].token = s_sourceTokens[0]; Internal.RampTokenAmount[] memory rampTokenAmounts = new Internal.RampTokenAmount[](1); - rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry); + rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry, DEST_CHAIN_SELECTOR); // Revert due to index out of bounds access vm.expectRevert(); - s_priceRegistry.validatePoolReturnData( + s_priceRegistry.processPoolReturnData( DEST_CHAIN_SELECTOR, new Internal.RampTokenAmount[](1), new Client.EVMTokenAmount[](0) ); } @@ -1926,19 +1919,19 @@ contract PriceRegistry_validatePoolReturnData is PriceRegistryFeeSetup { sourceTokenAmounts[0].token = sourceETH; Internal.RampTokenAmount[] memory rampTokenAmounts = new Internal.RampTokenAmount[](1); - rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry); + rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry, DEST_CHAIN_SELECTOR); // No data set, should succeed - s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); // Set max data length, should succeed rampTokenAmounts[0].extraData = new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES); - s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); // Set data to max length +1, should revert rampTokenAmounts[0].extraData = new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + 1); vm.expectRevert(abi.encodeWithSelector(PriceRegistry.SourceTokenDataTooLarge.selector, sourceETH)); - s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); // Set token config to allow larger data PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = @@ -1958,13 +1951,13 @@ contract PriceRegistry_validatePoolReturnData is PriceRegistryFeeSetup { tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) ); - s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); // Set the token data larger than the configured token data, should revert rampTokenAmounts[0].extraData = new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + 32 + 1); vm.expectRevert(abi.encodeWithSelector(PriceRegistry.SourceTokenDataTooLarge.selector, sourceETH)); - s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); } function test_InvalidEVMAddressDestToken_Revert() public { @@ -1975,11 +1968,11 @@ contract PriceRegistry_validatePoolReturnData is PriceRegistryFeeSetup { sourceTokenAmounts[0].token = s_sourceTokens[0]; Internal.RampTokenAmount[] memory rampTokenAmounts = new Internal.RampTokenAmount[](1); - rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry); + rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry, DEST_CHAIN_SELECTOR); rampTokenAmounts[0].destTokenAddress = nonEvmAddress; vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, nonEvmAddress)); - s_priceRegistry.validatePoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); } } diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistrySetup.t.sol b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistrySetup.t.sol index 6a4a1e3205..ee76c51c53 100644 --- a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistrySetup.t.sol +++ b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistrySetup.t.sol @@ -16,7 +16,10 @@ contract PriceRegistrySetup is TokenSetup { uint112 internal constant USD_PER_DATA_AVAILABILITY_GAS = 1e9; // 1 gwei address internal constant CUSTOM_TOKEN = address(12345); + address internal constant CUSTOM_TOKEN_2 = address(bytes20(keccak256("CUSTOM_TOKEN_2"))); + uint224 internal constant CUSTOM_TOKEN_PRICE = 1e17; // $0.1 CUSTOM + uint224 internal constant CUSTOM_TOKEN_PRICE_2 = 1e18; // $1 CUSTOM // Encode L1 gas price and L2 gas price into a packed price. // L1 gas price is left-shifted to the higher-order bits. @@ -138,6 +141,22 @@ contract PriceRegistrySetup is TokenSetup { }) }) ); + s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( + PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ + token: CUSTOM_TOKEN_2, + tokenTransferFeeConfig: PriceRegistry.TokenTransferFeeConfig({ + minFeeUSDCents: 2_00, // 1 USD + maxFeeUSDCents: 2000_00, // 1,000 USD + deciBps: 10_0, // 10 bps, or 0.1% + destGasOverhead: 1, + destBytesOverhead: 200, + isEnabled: false + }) + }) + ); + + //setting up the destination token for CUSTOM_TOKEN_2 here as it is specific to these tests + s_destTokenBySourceToken[CUSTOM_TOKEN_2] = address(bytes20(keccak256("CUSTOM_TOKEN_2_DEST"))); s_priceRegistry = new PriceRegistryHelper( PriceRegistry.StaticConfig({ @@ -236,7 +255,6 @@ contract PriceRegistrySetup is TokenSetup { maxPerMsgGasLimit: MAX_GAS_LIMIT, defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, defaultTokenDestGasOverhead: DEFAULT_TOKEN_DEST_GAS_OVERHEAD, - defaultTokenDestBytesOverhead: DEFAULT_TOKEN_BYTES_OVERHEAD, defaultTxGasLimit: GAS_LIMIT, gasMultiplierWeiPerEth: 5e17, networkFeeUSDCents: 1_00, @@ -300,7 +318,6 @@ contract PriceRegistrySetup is TokenSetup { assertEq(a.destDataAvailabilityMultiplierBps, b.destDataAvailabilityMultiplierBps); assertEq(a.defaultTokenFeeUSDCents, b.defaultTokenFeeUSDCents); assertEq(a.defaultTokenDestGasOverhead, b.defaultTokenDestGasOverhead); - assertEq(a.defaultTokenDestBytesOverhead, b.defaultTokenDestBytesOverhead); assertEq(a.defaultTxGasLimit, b.defaultTxGasLimit); } } @@ -383,7 +400,8 @@ contract PriceRegistryFeeSetup is PriceRegistrySetup { }); for (uint256 i = 0; i < message.tokenAmounts.length; ++i) { - messageEvent.tokenAmounts[i] = _getSourceTokenData(message.tokenAmounts[i], tokenAdminRegistry); + messageEvent.tokenAmounts[i] = + _getSourceTokenData(message.tokenAmounts[i], tokenAdminRegistry, DEST_CHAIN_SELECTOR); } messageEvent.header.messageId = Internal._hash(messageEvent, metadataHash); @@ -392,15 +410,26 @@ contract PriceRegistryFeeSetup is PriceRegistrySetup { function _getSourceTokenData( Client.EVMTokenAmount memory tokenAmount, - TokenAdminRegistry tokenAdminRegistry + TokenAdminRegistry tokenAdminRegistry, + uint64 destChainSelector ) internal view returns (Internal.RampTokenAmount memory) { address destToken = s_destTokenBySourceToken[tokenAmount.token]; + uint256 tokenTransferFeeConfigArgIndex; + uint256 tokenTransferFeeConfigsIndex; + + uint32 expectedDestGasAmount; + PriceRegistry.TokenTransferFeeConfig memory tokenTransferFeeConfig = + PriceRegistry(s_priceRegistry).getTokenTransferFeeConfig(destChainSelector, tokenAmount.token); + expectedDestGasAmount = + tokenTransferFeeConfig.isEnabled ? tokenTransferFeeConfig.destGasOverhead : DEFAULT_TOKEN_DEST_GAS_OVERHEAD; + return Internal.RampTokenAmount({ sourcePoolAddress: abi.encode(tokenAdminRegistry.getTokenConfig(tokenAmount.token).tokenPool), destTokenAddress: abi.encode(destToken), extraData: "", - amount: tokenAmount.amount + amount: tokenAmount.amount, + destExecData: abi.encode(expectedDestGasAmount) }); } diff --git a/core/capabilities/ccip/ccip_integration_tests/helpers.go b/core/capabilities/ccip/ccip_integration_tests/helpers.go index 11c8d96800..a98a8ce1cd 100644 --- a/core/capabilities/ccip/ccip_integration_tests/helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/helpers.go @@ -841,7 +841,6 @@ func defaultPriceRegistryDestChainConfig(t *testing.T) price_registry.PriceRegis DestGasPerDataAvailabilityByte: 100, DestDataAvailabilityMultiplierBps: 1, DefaultTokenDestGasOverhead: 125_000, - DefaultTokenDestBytesOverhead: 32, DefaultTxGasLimit: 200_000, GasMultiplierWeiPerEth: 1, NetworkFeeUSDCents: 1, diff --git a/core/capabilities/ccip/configs/evm/contract_reader.go b/core/capabilities/ccip/configs/evm/contract_reader.go index fd5cc49fa3..e395013cc9 100644 --- a/core/capabilities/ccip/configs/evm/contract_reader.go +++ b/core/capabilities/ccip/configs/evm/contract_reader.go @@ -162,8 +162,8 @@ var SourceReaderConfig = evmrelaytypes.ChainReaderConfig{ ChainSpecificName: mustGetMethodName("processMessageArgs", priceRegistryABI), ReadType: evmrelaytypes.Method, }, - "ValidatePoolReturnData": { - ChainSpecificName: mustGetMethodName("validatePoolReturnData", priceRegistryABI), + "ProcessPoolReturnData": { + ChainSpecificName: mustGetMethodName("processPoolReturnData", priceRegistryABI), ReadType: evmrelaytypes.Method, }, "GetValidatedTokenPrice": { diff --git a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go index 164c066e23..915a045c10 100644 --- a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go +++ b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go @@ -64,6 +64,7 @@ type InternalRampTokenAmount struct { DestTokenAddress []byte ExtraData []byte Amount *big.Int + DestExecData []byte } type InternalTokenPriceUpdate struct { @@ -95,8 +96,8 @@ type OffRampSourceChainConfig struct { } var CCIPReaderTesterMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPSendRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50611149806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80634cf66e361461005c578063a65558f614610071578063e44302b714610084578063e83eabba14610097578063e9d68a8e146100aa575b600080fd5b61006f61006a3660046104a7565b6100d3565b005b61006f61007f366004610718565b610128565b61006f6100923660046109b6565b61016d565b61006f6100a5366004610b20565b6101a7565b6100bd6100b8366004610bdb565b610233565b6040516100ca9190610c43565b60405180910390f35b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051610119929190610c9b565b60405180910390a45050505050565b816001600160401b03167f0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab29826040516101619190610d83565b60405180910390a25050565b7f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161019c9190610f3d565b60405180910390a150565b6001600160401b0380831660009081526020818152604091829020845181549286015193860151909416600160a81b02600160a81b600160e81b0319931515600160a01b026001600160a81b03199093166001600160a01b039095169490941791909117919091169190911781556060820151829190600182019061022c908261107d565b5050505050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b038781168452838352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b9092049092169483019490945260018401805493949293918401916102be90610ff2565b80601f01602080910402602001604051908101604052809291908181526020018280546102ea90610ff2565b80156103375780601f1061030c57610100808354040283529160200191610337565b820191906000526020600020905b81548152906001019060200180831161031a57829003601f168201915b5050505050815250509050919050565b80356001600160401b038116811461035e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b038111828210171561039b5761039b610363565b60405290565b60405161010081016001600160401b038111828210171561039b5761039b610363565b604080519081016001600160401b038111828210171561039b5761039b610363565b604051606081016001600160401b038111828210171561039b5761039b610363565b604051601f8201601f191681016001600160401b038111828210171561043057610430610363565b604052919050565b600082601f83011261044957600080fd5b81356001600160401b0381111561046257610462610363565b610475601f8201601f1916602001610408565b81815284602083860101111561048a57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a086880312156104bf57600080fd5b6104c886610347565b94506104d660208701610347565b9350604086013592506060860135600481106104f157600080fd5b915060808601356001600160401b0381111561050c57600080fd5b61051888828901610438565b9150509295509295909350565b600060a0828403121561053757600080fd5b60405160a081016001600160401b038111828210171561055957610559610363565b6040528235815290508061056f60208401610347565b602082015261058060408401610347565b604082015261059160608401610347565b60608201526105a260808401610347565b60808201525092915050565b6001600160a01b03811681146105c357600080fd5b50565b803561035e816105ae565b60006001600160401b038211156105ea576105ea610363565b5060051b60200190565b600082601f83011261060557600080fd5b8135602061061a610615836105d1565b610408565b82815260059290921b8401810191818101908684111561063957600080fd5b8286015b8481101561070d5780356001600160401b038082111561065d5760008081fd5b908801906080828b03601f19018113156106775760008081fd5b61067f610379565b87840135838111156106915760008081fd5b61069f8d8a83880101610438565b825250604080850135848111156106b65760008081fd5b6106c48e8b83890101610438565b8a84015250606080860135858111156106dd5760008081fd5b6106eb8f8c838a0101610438565b928401929092529490920135938101939093525050835291830191830161063d565b509695505050505050565b6000806040838503121561072b57600080fd5b61073483610347565b915060208301356001600160401b038082111561075057600080fd5b90840190610180828703121561076557600080fd5b61076d6103a1565b6107778784610525565b815261078560a084016105c6565b602082015260c08301358281111561079c57600080fd5b6107a888828601610438565b60408301525060e0830135828111156107c057600080fd5b6107cc88828601610438565b606083015250610100830135828111156107e557600080fd5b6107f188828601610438565b60808301525061080461012084016105c6565b60a082015261014083013560c08201526101608301358281111561082757600080fd5b610833888286016105f4565b60e0830152508093505050509250929050565b80356001600160e01b038116811461035e57600080fd5b600082601f83011261086e57600080fd5b8135602061087e610615836105d1565b82815260069290921b8401810191818101908684111561089d57600080fd5b8286015b8481101561070d57604081890312156108ba5760008081fd5b6108c26103c4565b6108cb82610347565b81526108d8858301610846565b818601528352918301916040016108a1565b600082601f8301126108fb57600080fd5b8135602061090b610615836105d1565b82815260079290921b8401810191818101908684111561092a57600080fd5b8286015b8481101561070d5780880360808112156109485760008081fd5b6109506103e6565b61095983610347565b8152604080601f198401121561096f5760008081fd5b6109776103c4565b9250610984878501610347565b8352610991818501610347565b838801528187019290925260608301359181019190915283529183019160800161092e565b600060208083850312156109c957600080fd5b82356001600160401b03808211156109e057600080fd5b818501915060408083880312156109f657600080fd5b6109fe6103c4565b833583811115610a0d57600080fd5b84016040818a031215610a1f57600080fd5b610a276103c4565b813585811115610a3657600080fd5b8201601f81018b13610a4757600080fd5b8035610a55610615826105d1565b81815260069190911b8201890190898101908d831115610a7457600080fd5b928a01925b82841015610ac45787848f031215610a915760008081fd5b610a996103c4565b8435610aa4816105ae565b8152610ab1858d01610846565b818d0152825292870192908a0190610a79565b845250505081870135935084841115610adc57600080fd5b610ae88a85840161085d565b8188015282525083850135915082821115610b0257600080fd5b610b0e888386016108ea565b85820152809550505050505092915050565b60008060408385031215610b3357600080fd5b610b3c83610347565b915060208301356001600160401b0380821115610b5857600080fd5b9084019060808287031215610b6c57600080fd5b610b74610379565b8235610b7f816105ae565b815260208301358015158114610b9457600080fd5b6020820152610ba560408401610347565b6040820152606083013582811115610bbc57600080fd5b610bc888828601610438565b6060830152508093505050509250929050565b600060208284031215610bed57600080fd5b610bf682610347565b9392505050565b6000815180845260005b81811015610c2357602081850181015186830182015201610c07565b506000602082860101526020601f19601f83011685010191505092915050565b602080825282516001600160a01b03168282015282015115156040808301919091528201516001600160401b0316606080830191909152820151608080830152600090610c9360a0840182610bfd565b949350505050565b600060048410610cbb57634e487b7160e01b600052602160045260246000fd5b83825260406020830152610c936040830184610bfd565b6001600160a01b03169052565b600082825180855260208086019550808260051b84010181860160005b84811015610d7657601f19868403018952815160808151818652610d2282870182610bfd565b9150508582015185820387870152610d3a8282610bfd565b91505060408083015186830382880152610d548382610bfd565b6060948501519790940196909652505098840198925090830190600101610cfc565b5090979650505050505050565b60208152610dd0602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b60006020830151610de460c0840182610cd2565b5060408301516101808060e0850152610e016101a0850183610bfd565b91506060850151601f198086850301610100870152610e208483610bfd565b9350608087015191508086850301610120870152610e3e8483610bfd565b935060a08701519150610e55610140870183610cd2565b60c087015161016087015260e0870151915080868503018387015250610e7b8382610cdf565b9695505050505050565b60008151808452602080850194506020840160005b83811015610ed357815180516001600160401b031688528301516001600160e01b03168388015260409096019590820190600101610e9a565b509495945050505050565b600081518084526020808501945080840160005b83811015610ed357815180516001600160401b0390811689528482015180518216868b0152850151166040898101919091520151606088015260809096019590820190600101610ef2565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b80831015610fab57835180516001600160a01b031683528701516001600160e01b031687830152928601926001929092019190840190610f70565b5093850151878503605f1901608089015293610fc78186610e85565b945050505050818501519150601f19848203016040850152610fe98183610ede565b95945050505050565b600181811c9082168061100657607f821691505b60208210810361102657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115611078576000816000526020600020601f850160051c810160208610156110555750805b601f850160051c820191505b8181101561107457828155600101611061565b5050505b505050565b81516001600160401b0381111561109657611096610363565b6110aa816110a48454610ff2565b8461102c565b602080601f8311600181146110df57600084156110c75750858301515b600019600386901b1c1916600185901b178555611074565b600085815260208120601f198616915b8281101561110e578886015182559484019460019091019084016110ef565b508582101561112c5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPSendRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061118d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80634cf66e361461005c57806385096da914610071578063e44302b714610084578063e83eabba14610097578063e9d68a8e146100aa575b600080fd5b61006f61006a3660046104c9565b6100d3565b005b61006f61007f366004610741565b610128565b61006f6100923660046109df565b61016d565b61006f6100a5366004610b49565b6101a7565b6100bd6100b8366004610c04565b610233565b6040516100ca9190610c6c565b60405180910390f35b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051610119929190610cc4565b60405180910390a45050505050565b816001600160401b03167fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140826040516101619190610dc7565b60405180910390a25050565b7f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161019c9190610f81565b60405180910390a150565b6001600160401b0380831660009081526020818152604091829020845181549286015193860151909416600160a81b02600160a81b600160e81b0319931515600160a01b026001600160a81b03199093166001600160a01b039095169490941791909117919091169190911781556060820151829190600182019061022c90826110c1565b5050505050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b038781168452838352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b9092049092169483019490945260018401805493949293918401916102be90611036565b80601f01602080910402602001604051908101604052809291908181526020018280546102ea90611036565b80156103375780601f1061030c57610100808354040283529160200191610337565b820191906000526020600020905b81548152906001019060200180831161031a57829003601f168201915b5050505050815250509050919050565b80356001600160401b038116811461035e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b038111828210171561039b5761039b610363565b60405290565b60405161010081016001600160401b038111828210171561039b5761039b610363565b604080519081016001600160401b038111828210171561039b5761039b610363565b604051606081016001600160401b038111828210171561039b5761039b610363565b604051608081016001600160401b038111828210171561039b5761039b610363565b604051601f8201601f191681016001600160401b038111828210171561045257610452610363565b604052919050565b600082601f83011261046b57600080fd5b81356001600160401b0381111561048457610484610363565b610497601f8201601f191660200161042a565b8181528460208386010111156104ac57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a086880312156104e157600080fd5b6104ea86610347565b94506104f860208701610347565b93506040860135925060608601356004811061051357600080fd5b915060808601356001600160401b0381111561052e57600080fd5b61053a8882890161045a565b9150509295509295909350565b600060a0828403121561055957600080fd5b610561610379565b90508135815261057360208301610347565b602082015261058460408301610347565b604082015261059560608301610347565b60608201526105a660808301610347565b608082015292915050565b6001600160a01b03811681146105c657600080fd5b50565b803561035e816105b1565b60006001600160401b038211156105ed576105ed610363565b5060051b60200190565b600082601f83011261060857600080fd5b8135602061061d610618836105d4565b61042a565b82815260059290921b8401810191818101908684111561063c57600080fd5b8286015b848110156107365780356001600160401b03808211156106605760008081fd5b9088019060a0828b03601f190181131561067a5760008081fd5b610682610379565b87840135838111156106945760008081fd5b6106a28d8a8388010161045a565b825250604080850135848111156106b95760008081fd5b6106c78e8b8389010161045a565b8a84015250606080860135858111156106e05760008081fd5b6106ee8f8c838a010161045a565b838501525060809150818601358184015250828501359250838311156107145760008081fd5b6107228d8a8588010161045a565b908201528652505050918301918301610640565b509695505050505050565b6000806040838503121561075457600080fd5b61075d83610347565b915060208301356001600160401b038082111561077957600080fd5b90840190610180828703121561078e57600080fd5b6107966103a1565b6107a08784610547565b81526107ae60a084016105c9565b602082015260c0830135828111156107c557600080fd5b6107d18882860161045a565b60408301525060e0830135828111156107e957600080fd5b6107f58882860161045a565b6060830152506101008301358281111561080e57600080fd5b61081a8882860161045a565b60808301525061082d61012084016105c9565b60a082015261014083013560c08201526101608301358281111561085057600080fd5b61085c888286016105f7565b60e0830152508093505050509250929050565b80356001600160e01b038116811461035e57600080fd5b600082601f83011261089757600080fd5b813560206108a7610618836105d4565b82815260069290921b840181019181810190868411156108c657600080fd5b8286015b8481101561073657604081890312156108e35760008081fd5b6108eb6103c4565b6108f482610347565b815261090185830161086f565b818601528352918301916040016108ca565b600082601f83011261092457600080fd5b81356020610934610618836105d4565b82815260079290921b8401810191818101908684111561095357600080fd5b8286015b848110156107365780880360808112156109715760008081fd5b6109796103e6565b61098283610347565b8152604080601f19840112156109985760008081fd5b6109a06103c4565b92506109ad878501610347565b83526109ba818501610347565b8388015281870192909252606083013591810191909152835291830191608001610957565b600060208083850312156109f257600080fd5b82356001600160401b0380821115610a0957600080fd5b81850191506040808388031215610a1f57600080fd5b610a276103c4565b833583811115610a3657600080fd5b84016040818a031215610a4857600080fd5b610a506103c4565b813585811115610a5f57600080fd5b8201601f81018b13610a7057600080fd5b8035610a7e610618826105d4565b81815260069190911b8201890190898101908d831115610a9d57600080fd5b928a01925b82841015610aed5787848f031215610aba5760008081fd5b610ac26103c4565b8435610acd816105b1565b8152610ada858d0161086f565b818d0152825292870192908a0190610aa2565b845250505081870135935084841115610b0557600080fd5b610b118a858401610886565b8188015282525083850135915082821115610b2b57600080fd5b610b3788838601610913565b85820152809550505050505092915050565b60008060408385031215610b5c57600080fd5b610b6583610347565b915060208301356001600160401b0380821115610b8157600080fd5b9084019060808287031215610b9557600080fd5b610b9d610408565b8235610ba8816105b1565b815260208301358015158114610bbd57600080fd5b6020820152610bce60408401610347565b6040820152606083013582811115610be557600080fd5b610bf18882860161045a565b6060830152508093505050509250929050565b600060208284031215610c1657600080fd5b610c1f82610347565b9392505050565b6000815180845260005b81811015610c4c57602081850181015186830182015201610c30565b506000602082860101526020601f19601f83011685010191505092915050565b602080825282516001600160a01b03168282015282015115156040808301919091528201516001600160401b0316606080830191909152820151608080830152600090610cbc60a0840182610c26565b949350505050565b600060048410610ce457634e487b7160e01b600052602160045260246000fd5b83825260406020830152610cbc6040830184610c26565b6001600160a01b03169052565b600082825180855260208086019550808260051b84010181860160005b84811015610dba57601f19868403018952815160a08151818652610d4b82870182610c26565b9150508582015185820387870152610d638282610c26565b91505060408083015186830382880152610d7d8382610c26565b92505050606080830151818701525060808083015192508582038187015250610da68183610c26565b9a86019a9450505090830190600101610d25565b5090979650505050505050565b60208152610e14602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b60006020830151610e2860c0840182610cfb565b5060408301516101808060e0850152610e456101a0850183610c26565b91506060850151601f198086850301610100870152610e648483610c26565b9350608087015191508086850301610120870152610e828483610c26565b935060a08701519150610e99610140870183610cfb565b60c087015161016087015260e0870151915080868503018387015250610ebf8382610d08565b9695505050505050565b60008151808452602080850194506020840160005b83811015610f1757815180516001600160401b031688528301516001600160e01b03168388015260409096019590820190600101610ede565b509495945050505050565b600081518084526020808501945080840160005b83811015610f1757815180516001600160401b0390811689528482015180518216868b0152850151166040898101919091520151606088015260809096019590820190600101610f36565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b80831015610fef57835180516001600160a01b031683528701516001600160e01b031687830152928601926001929092019190840190610fb4565b5093850151878503605f190160808901529361100b8186610ec9565b945050505050818501519150601f1984820301604085015261102d8183610f22565b95945050505050565b600181811c9082168061104a57607f821691505b60208210810361106a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156110bc576000816000526020600020601f850160051c810160208610156110995750805b601f850160051c820191505b818110156110b8578281556001016110a5565b5050505b505050565b81516001600160401b038111156110da576110da610363565b6110ee816110e88454611036565b84611070565b602080601f831160018114611123576000841561110b5750858301515b600019600386901b1c1916600185901b1785556110b8565b600085815260208120601f198616915b8281101561115257888601518255948401946001909101908401611133565b50858210156111705787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", } var CCIPReaderTesterABI = CCIPReaderTesterMetaData.ABI @@ -712,7 +713,7 @@ func (_CCIPReaderTester *CCIPReaderTester) ParseLog(log types.Log) (generated.Ab } func (CCIPReaderTesterCCIPSendRequested) Topic() common.Hash { - return common.HexToHash("0x0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab29") + return common.HexToHash("0xcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140") } func (CCIPReaderTesterCommitReportAccepted) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generated/message_hasher/message_hasher.go b/core/gethwrappers/ccip/generated/message_hasher/message_hasher.go index 52434b5049..1d95e75778 100644 --- a/core/gethwrappers/ccip/generated/message_hasher/message_hasher.go +++ b/core/gethwrappers/ccip/generated/message_hasher/message_hasher.go @@ -59,11 +59,12 @@ type InternalRampTokenAmount struct { DestTokenAddress []byte ExtraData []byte Amount *big.Int + DestExecData []byte } var MessageHasherMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"decodeEVMExtraArgsV1\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMExtraArgsV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"allowOutOfOrderExecution\",\"type\":\"bool\"}],\"name\":\"decodeEVMExtraArgsV2\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"allowOutOfOrderExecution\",\"type\":\"bool\"}],\"internalType\":\"structClient.EVMExtraArgsV2\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMExtraArgsV1\",\"name\":\"extraArgs\",\"type\":\"tuple\"}],\"name\":\"encodeEVMExtraArgsV1\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"allowOutOfOrderExecution\",\"type\":\"bool\"}],\"internalType\":\"structClient.EVMExtraArgsV2\",\"name\":\"extraArgs\",\"type\":\"tuple\"}],\"name\":\"encodeEVMExtraArgsV2\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"leafDomainSeparator\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"implicitMetadataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"fixedSizeFieldsHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"dataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"tokenAmountsHash\",\"type\":\"bytes32\"}],\"name\":\"encodeFinalHashPreimage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"name\":\"encodeFixedSizeFieldsHashPreimage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"any2EVMMessageHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"name\":\"encodeMetadataHashPreimage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"encodeTokenAmountsHashPreimage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50610de7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063a91d3aeb11610076578063c63641bd1161005b578063c63641bd1461019e578063c7ca9a18146101f5578063e733d2091461020857600080fd5b8063a91d3aeb14610150578063b17df7141461016357600080fd5b8063902e94a0146100a85780639511afaa146100d157806399df8d05146100f2578063a1e747df1461013d575b600080fd5b6100bb6100b63660046107d9565b61021b565b6040516100c8919061087a565b60405180910390f35b6100e46100df366004610958565b610244565b6040519081526020016100c8565b6100bb610100366004610a62565b604080516020810196909652858101949094526060850192909252608084015260a0808401919091528151808403909101815260c0909201905290565b6100bb61014b366004610a9d565b610257565b6100bb61015e366004610b05565b610289565b61018f610171366004610b86565b60408051602080820183526000909152815190810190915290815290565b604051905181526020016100c8565b6101d86101ac366004610baf565b604080518082019091526000808252602082015250604080518082019091529182521515602082015290565b6040805182518152602092830151151592810192909252016100c8565b6100bb610203366004610bdb565b6102c1565b6100bb610216366004610c2f565b6102d2565b60608160405160200161022e9190610c71565b6040516020818303038152906040529050919050565b600061025083836102dd565b9392505050565b6060848484846040516020016102709493929190610d3d565b6040516020818303038152906040529050949350505050565b60608686868686866040516020016102a696959493929190610d7a565b60405160208183030381529060405290509695505050505050565b60606102cc8261043a565b92915050565b60606102cc826104fc565b815160208082015160409283015192516000938493610323937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101610d3d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052805160209182012086518051888401516060808b0151908401516080808d0151950151959761038a9794969395929491939101610d7a565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016103c19190610c71565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c00160405160208183030381529060405280519060200120905092915050565b604051815160248201526020820151151560448201526060907f181dcf1000000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b604051815160248201526060907f97a657c90000000000000000000000000000000000000000000000000000000090604401610479565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561058557610585610533565b60405290565b60405160c0810167ffffffffffffffff8111828210171561058557610585610533565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156105f5576105f5610533565b604052919050565b600082601f83011261060e57600080fd5b813567ffffffffffffffff81111561062857610628610533565b61065960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016105ae565b81815284602083860101111561066e57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261069c57600080fd5b8135602067ffffffffffffffff808311156106b9576106b9610533565b8260051b6106c88382016105ae565b93845285810183019383810190888611156106e257600080fd5b84880192505b858310156107cd578235848111156107005760008081fd5b88016080818b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018113156107365760008081fd5b61073e610562565b87830135878111156107505760008081fd5b61075e8d8a838701016105fd565b825250604080840135888111156107755760008081fd5b6107838e8b838801016105fd565b8a840152506060808501358981111561079c5760008081fd5b6107aa8f8c838901016105fd565b9284019290925293909201359281019290925250825291840191908401906106e8565b98975050505050505050565b6000602082840312156107eb57600080fd5b813567ffffffffffffffff81111561080257600080fd5b61080e8482850161068b565b949350505050565b6000815180845260005b8181101561083c57602081850181015186830182015201610820565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006102506020830184610816565b803567ffffffffffffffff811681146108a557600080fd5b919050565b600060a082840312156108bc57600080fd5b60405160a0810181811067ffffffffffffffff821117156108df576108df610533565b604052823581529050806108f56020840161088d565b60208201526109066040840161088d565b60408201526109176060840161088d565b60608201526109286080840161088d565b60808201525092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146108a557600080fd5b6000806040838503121561096b57600080fd5b823567ffffffffffffffff8082111561098357600080fd5b90840190610140828703121561099857600080fd5b6109a061058b565b6109aa87846108aa565b815260a0830135828111156109be57600080fd5b6109ca888286016105fd565b60208301525060c0830135828111156109e257600080fd5b6109ee888286016105fd565b604083015250610a0060e08401610934565b6060820152610100830135608082015261012083013582811115610a2357600080fd5b610a2f8882860161068b565b60a08301525093506020850135915080821115610a4b57600080fd5b50610a58858286016105fd565b9150509250929050565b600080600080600060a08688031215610a7a57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060008060808587031215610ab357600080fd5b84359350610ac36020860161088d565b9250610ad16040860161088d565b9150606085013567ffffffffffffffff811115610aed57600080fd5b610af9878288016105fd565b91505092959194509250565b60008060008060008060c08789031215610b1e57600080fd5b86359550602087013567ffffffffffffffff811115610b3c57600080fd5b610b4889828a016105fd565b955050610b5760408801610934565b9350610b656060880161088d565b925060808701359150610b7a60a0880161088d565b90509295509295509295565b600060208284031215610b9857600080fd5b5035919050565b803580151581146108a557600080fd5b60008060408385031215610bc257600080fd5b82359150610bd260208401610b9f565b90509250929050565b600060408284031215610bed57600080fd5b6040516040810181811067ffffffffffffffff82111715610c1057610c10610533565b60405282358152610c2360208401610b9f565b60208201529392505050565b600060208284031215610c4157600080fd5b6040516020810181811067ffffffffffffffff82111715610c6457610c64610533565b6040529135825250919050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015610d2f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0898403018552815160808151818652610cde82870182610816565b915050888201518582038a870152610cf68282610816565b9150508782015185820389870152610d0e8282610816565b60609384015196909301959095525094870194925090860190600101610c9a565b509098975050505050505050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152610d706080830184610816565b9695505050505050565b86815260c060208201526000610d9360c0830188610816565b73ffffffffffffffffffffffffffffffffffffffff9690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a0909101529291505056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"decodeEVMExtraArgsV1\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMExtraArgsV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"allowOutOfOrderExecution\",\"type\":\"bool\"}],\"name\":\"decodeEVMExtraArgsV2\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"allowOutOfOrderExecution\",\"type\":\"bool\"}],\"internalType\":\"structClient.EVMExtraArgsV2\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMExtraArgsV1\",\"name\":\"extraArgs\",\"type\":\"tuple\"}],\"name\":\"encodeEVMExtraArgsV1\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"allowOutOfOrderExecution\",\"type\":\"bool\"}],\"internalType\":\"structClient.EVMExtraArgsV2\",\"name\":\"extraArgs\",\"type\":\"tuple\"}],\"name\":\"encodeEVMExtraArgsV2\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"leafDomainSeparator\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"implicitMetadataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"fixedSizeFieldsHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"dataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"tokenAmountsHash\",\"type\":\"bytes32\"}],\"name\":\"encodeFinalHashPreimage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"name\":\"encodeFixedSizeFieldsHashPreimage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"any2EVMMessageHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"name\":\"encodeMetadataHashPreimage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"encodeTokenAmountsHashPreimage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610e08806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063a91d3aeb11610076578063c63641bd1161005b578063c63641bd1461019e578063c7ca9a18146101f5578063e733d2091461020857600080fd5b8063a91d3aeb14610150578063b17df7141461016357600080fd5b80632d6d4c5e146100a85780632efb5ac2146100d157806399df8d05146100f2578063a1e747df1461013d575b600080fd5b6100bb6100b63660046107ff565b61021b565b6040516100c891906108a0565b60405180910390f35b6100e46100df36600461095e565b610244565b6040519081526020016100c8565b6100bb610100366004610a68565b604080516020810196909652858101949094526060850192909252608084015260a0808401919091528151808403909101815260c0909201905290565b6100bb61014b366004610aa3565b610257565b6100bb61015e366004610b0b565b610289565b61018f610171366004610b8c565b60408051602080820183526000909152815190810190915290815290565b604051905181526020016100c8565b6101d86101ac366004610bb5565b604080518082019091526000808252602082015250604080518082019091529182521515602082015290565b6040805182518152602092830151151592810192909252016100c8565b6100bb610203366004610be1565b6102c1565b6100bb610216366004610c35565b6102d2565b60608160405160200161022e9190610c77565b6040516020818303038152906040529050919050565b600061025083836102dd565b9392505050565b6060848484846040516020016102709493929190610d5e565b6040516020818303038152906040529050949350505050565b60608686868686866040516020016102a696959493929190610d9b565b60405160208183030381529060405290509695505050505050565b60606102cc8261043a565b92915050565b60606102cc826104fc565b815160208082015160409283015192516000938493610323937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101610d5e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052805160209182012086518051888401516060808b0151908401516080808d0151950151959761038a9794969395929491939101610d9b565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016103c19190610c77565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c00160405160208183030381529060405280519060200120905092915050565b604051815160248201526020820151151560448201526060907f181dcf1000000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b604051815160248201526060907f97a657c90000000000000000000000000000000000000000000000000000000090604401610479565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561058557610585610533565b60405290565b60405160c0810167ffffffffffffffff8111828210171561058557610585610533565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156105f5576105f5610533565b604052919050565b600082601f83011261060e57600080fd5b813567ffffffffffffffff81111561062857610628610533565b61065960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016105ae565b81815284602083860101111561066e57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261069c57600080fd5b8135602067ffffffffffffffff808311156106b9576106b9610533565b8260051b6106c88382016105ae565b93845285810183019383810190888611156106e257600080fd5b84880192505b858310156107f3578235848111156107005760008081fd5b880160a0818b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018113156107365760008081fd5b61073e610562565b87830135878111156107505760008081fd5b61075e8d8a838701016105fd565b825250604080840135888111156107755760008081fd5b6107838e8b838801016105fd565b8a840152506060808501358981111561079c5760008081fd5b6107aa8f8c838901016105fd565b838501525060809150818501358184015250828401359250878311156107d05760008081fd5b6107de8d8a858701016105fd565b908201528452505091840191908401906106e8565b98975050505050505050565b60006020828403121561081157600080fd5b813567ffffffffffffffff81111561082857600080fd5b6108348482850161068b565b949350505050565b6000815180845260005b8181101561086257602081850181015186830182015201610846565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610250602083018461083c565b803567ffffffffffffffff811681146108cb57600080fd5b919050565b600060a082840312156108e257600080fd5b6108ea610562565b9050813581526108fc602083016108b3565b602082015261090d604083016108b3565b604082015261091e606083016108b3565b606082015261092f608083016108b3565b608082015292915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146108cb57600080fd5b6000806040838503121561097157600080fd5b823567ffffffffffffffff8082111561098957600080fd5b90840190610140828703121561099e57600080fd5b6109a661058b565b6109b087846108d0565b815260a0830135828111156109c457600080fd5b6109d0888286016105fd565b60208301525060c0830135828111156109e857600080fd5b6109f4888286016105fd565b604083015250610a0660e0840161093a565b6060820152610100830135608082015261012083013582811115610a2957600080fd5b610a358882860161068b565b60a08301525093506020850135915080821115610a5157600080fd5b50610a5e858286016105fd565b9150509250929050565b600080600080600060a08688031215610a8057600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060008060808587031215610ab957600080fd5b84359350610ac9602086016108b3565b9250610ad7604086016108b3565b9150606085013567ffffffffffffffff811115610af357600080fd5b610aff878288016105fd565b91505092959194509250565b60008060008060008060c08789031215610b2457600080fd5b86359550602087013567ffffffffffffffff811115610b4257600080fd5b610b4e89828a016105fd565b955050610b5d6040880161093a565b9350610b6b606088016108b3565b925060808701359150610b8060a088016108b3565b90509295509295509295565b600060208284031215610b9e57600080fd5b5035919050565b803580151581146108cb57600080fd5b60008060408385031215610bc857600080fd5b82359150610bd860208401610ba5565b90509250929050565b600060408284031215610bf357600080fd5b6040516040810181811067ffffffffffffffff82111715610c1657610c16610533565b60405282358152610c2960208401610ba5565b60208201529392505050565b600060208284031215610c4757600080fd5b6040516020810181811067ffffffffffffffff82111715610c6a57610c6a610533565b6040529135825250919050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015610d50577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0898403018552815160a08151818652610ce48287018261083c565b915050888201518582038a870152610cfc828261083c565b9150508782015185820389870152610d14828261083c565b915050606080830151818701525060808083015192508582038187015250610d3c818361083c565b968901969450505090860190600101610ca0565b509098975050505050505050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152610d91608083018461083c565b9695505050505050565b86815260c060208201526000610db460c083018861083c565b73ffffffffffffffffffffffffffffffffffffffff9690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a0909101529291505056fea164736f6c6343000818000a", } var MessageHasherABI = MessageHasherMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/offramp/offramp.go b/core/gethwrappers/ccip/generated/offramp/offramp.go index 72917cf943..0dd7280074 100644 --- a/core/gethwrappers/ccip/generated/offramp/offramp.go +++ b/core/gethwrappers/ccip/generated/offramp/offramp.go @@ -83,6 +83,7 @@ type InternalRampTokenAmount struct { DestTokenAddress []byte ExtraData []byte Amount *big.Int + DestExecData []byte } type InternalTokenPriceUpdate struct { @@ -163,8 +164,8 @@ type OffRampUnblessedRoot struct { } var OffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162006bdd38038062006bdd8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615f0762000cd6600039600081816102530152612c120152600081816102240152612ef80152600081816101f50152818161142f01526118400152600081816101c50152612801015260008181611dce0152611e1a0152615f076000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063d2a15d351161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063d2a15d351461053d578063e9d68a8e14610550578063ece670b61461057057600080fd5b8063991a5018116100bd578063991a5018146104c5578063c673e584146104d8578063ccd37ba3146104f857600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b80633f4b04aa1161012f5780637437ff9f116101145780637437ff9f1461038557806379ba5097146104815780637d4eef601461048957600080fd5b80633f4b04aa146103495780635e36480c1461036557600080fd5b8063181f5a7711610160578063181f5a77146102da5780632d04ab7614610323578063311cd5131461033657600080fd5b806304666f9c1461017c57806306285c6914610191575b600080fd5b61018f61018a3660046140b3565b6105cc565b005b61028360408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102d19190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103166040518060400160405280601181526020017f4f666652616d7020312e362e302d64657600000000000000000000000000000081525081565b6040516102d19190614222565b61018f6103313660046142cd565b6105e0565b61018f610344366004614380565b6109c0565b60095460405167ffffffffffffffff90911681526020016102d1565b6103786103733660046143d4565b610a29565b6040516102d19190614431565b6104246040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102d19190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610a7f565b61018f610497366004614986565b610b3d565b61018f610177366004614ab1565b6000546040516001600160a01b0390911681526020016102d1565b61018f6104d3366004614b00565b610cdd565b6104eb6104e6366004614b85565b610cee565b6040516102d19190614be5565b61052f610506366004614c5a565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102d1565b61018f61054b366004614c84565b610e4c565b61056361055e366004614cf9565b610f06565b6040516102d19190614d14565b61018f61057e366004614d62565b611013565b61018f610591366004614dbe565b611386565b61018f6105a4366004614e43565b611397565b6105bc6105b7366004614f81565b6113d9565b60405190151581526020016102d1565b6105d461149a565b6105dd816114f6565b50565b60006105ee8789018961510a565b8051515190915015158061060757508051602001515115155b156107075760095460208a01359067ffffffffffffffff808316911610156106c6576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261068f929101615348565b600060405180830381600087803b1580156106a957600080fd5b505af11580156106bd573d6000803e3d6000fd5b50505050610705565b816020015151600003610705576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b8160200151518110156109095760008260200151828151811061072f5761072f615275565b6020026020010151905060008160000151905061074b816117f4565b6000610756826118f6565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061079a575060208084015190810151905167ffffffffffffffff9182169116115b156107e357825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107da92919060040161535b565b60405180910390fd5b60408301518061081f576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff166000908152600860209081526040808320848452909152902054156108925783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016107da565b60208085015101516108a59060016153a6565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff92831602179092559251166000908152600860209081526040808320948352939052919091204290555060010161070a565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161093991906153ce565b60405180910390a16109b560008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b925061195d915050565b505050505050505050565b610a006109cf8284018461546b565b60408051600080825260208201909252906109fa565b60608152602001906001900390816109e55790505b50611cd4565b604080516000808252602082019092529050610a2360018585858586600061195d565b50505050565b6000610a37600160046154a0565b6002610a446080856154c9565b67ffffffffffffffff16610a5891906154f0565b610a628585611d84565b901c166003811115610a7657610a76614407565b90505b92915050565b6001546001600160a01b03163314610ad95760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107da565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b45611dcb565b815181518114610b81576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ccd576000848281518110610ba057610ba0615275565b60200260200101519050600081602001515190506000858481518110610bc857610bc8615275565b6020026020010151905080518214610c0c576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82811015610cbe576000828281518110610c2b57610c2b615275565b6020026020010151905080600014610cb55784602001518281518110610c5357610c53615275565b602002602001015160800151811015610cb55784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064016107da565b50600101610c0f565b50505050806001019050610b84565b50610cd88383611cd4565b505050565b610ce561149a565b6105dd81611e4c565b610d316040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610dda57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dbc575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610e3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e1e575b5050505050815250509050919050565b610e5461149a565b60005b81811015610cd8576000838383818110610e7357610e73615275565b905060400201803603810190610e899190615507565b9050610e9881602001516113d9565b610efd57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b50600101610e57565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191610f9390615540565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbf90615540565b8015610e3c5780601f10610fe157610100808354040283529160200191610e3c565b820191906000526020600020905b815481529060010190602001808311610fef57505050919092525091949350505050565b33301461104c576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611089565b60408051808201909152600080825260208201528152602001906001900390816110625790505b5060a085015151909150156110bd576110ba8460a00151856020015186606001518760000151602001518787611fb2565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff16818301528087015183516000948401926110f9929101614222565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015611206576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a19061117390859060040161561c565b600060405180830381600087803b15801561118d57600080fd5b505af192505050801561119e575060015b611206573d8080156111cc576040519150601f19603f3d011682016040523d82523d6000602084013e6111d1565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b60408601515115801561121b57506080860151155b80611232575060608601516001600160a01b03163b155b8061127257506060860151611270906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120d1565b155b1561127f57505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf97983926112f7928992611388929160040161562f565b6000604051808303816000875af1158015611316573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261133e919081019061566b565b50915091508161137c57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b5050505050505050565b61138e61149a565b6105dd816120ed565b61139f61149a565b60005b81518110156113d5576113cd8282815181106113c0576113c0615275565b60200260200101516121a3565b6001016113a2565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611476573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a799190615701565b6000546001600160a01b031633146114f45760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107da565b565b60005b81518110156113d557600082828151811061151657611516615275565b602002602001015190506000816020015190508067ffffffffffffffff1660000361156d576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611595576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115c090615540565b80601f01602080910402602001604051908101604052809291908181526020018280546115ec90615540565b80156116395780601f1061160e57610100808354040283529160200191611639565b820191906000526020600020905b81548152906001019060200180831161161c57829003601f168201915b5050505050905060008460600151905081516000036116f1578051600003611674576040516342bcdf7f60e11b815260040160405180910390fd5b600183016116828282615766565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611744565b8080519060200120828051906020012014611744576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016107da565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117dc908690615826565b60405180910390a250505050508060010190506114f9565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b39190615701565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016107da565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610a79576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016107da565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906119bc8760a46158f4565b9050826060015115611a045784516119d59060206154f0565b86516119e29060206154f0565b6119ed9060a06158f4565b6119f791906158f4565b611a0190826158f4565b90505b368114611a46576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107da565b5081518114611a8e5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107da565b611a96611dcb565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611ae457611ae4614407565b6002811115611af557611af5614407565b9052509050600281602001516002811115611b1257611b12614407565b148015611b665750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611b4e57611b4e615275565b6000918252602090912001546001600160a01b031633145b611b9c576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611c7e576020820151611bb7906001615907565b60ff16855114611bf3576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611c2e576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611c40929190615920565b604051908190038120611c57918b90602001615930565b604051602081830303815290604052805190602001209050611c7c8a828888886124e7565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b8151600003611d0e576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611d7d57611d75858281518110611d4357611d43615275565b602002602001015184611d6f57858381518110611d6257611d62615275565b60200260200101516126f4565b836126f4565b600101611d25565b5050505050565b67ffffffffffffffff8216600090815260076020526040812081611da9608085615944565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b467f0000000000000000000000000000000000000000000000000000000000000000146114f4576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107da565b80516001600160a01b0316611e74576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fce57611fce613eca565b60405190808252806020026020018201604052801561201357816020015b6040805180820190915260008082526020820152815260200190600190039081611fec5790505b50905060005b87518110156120c5576120a088828151811061203757612037615275565b602002602001015188888888888781811061205457612054615275565b9050602002810190612066919061596b565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9792505050565b8282815181106120b2576120b2615275565b6020908102919091010152600101612019565b505b9695505050505050565b60006120dc8361323c565b8015610a765750610a7683836132a0565b336001600160a01b038216036121455760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107da565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ce576000604051631b3fab5160e11b81526004016107da91906159d0565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223b57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612290565b6060840151600182015460ff6201000090910416151590151514612290576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016107da565b60a08401518051601f60ff821611156122bf576001604051631b3fab5160e11b81526004016107da91906159d0565b612325858560030180548060200260200160405190810160405280929190818152602001828054801561231b57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122fd575b505050505061335b565b85606001511561245457612393858560020180548060200260200160405190810160405280929190818152602001828054801561231b576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122fd57505050505061335b565b608086015180516123ad9060028701906020840190613e24565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f101561240d576002604051631b3fab5160e11b81526004016107da91906159d0565b604088015161241d9060036159ea565b60ff168160ff1611612445576003604051631b3fab5160e11b81526004016107da91906159d0565b612451878360016133c4565b50505b612460858360026133c4565b81516124759060038601906020850190613e24565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ce938a939260028b01929190615a06565b60405180910390a16124df85613544565b505050505050565b6124ef613e96565b835160005b8181101561137c57600060018886846020811061251357612513615275565b61252091901a601b615907565b89858151811061253257612532615275565b602002602001015189868151811061254c5761254c615275565b60200260200101516040516000815260200160405260405161258a949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156125ac573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b0385168352815285822085870190965285548084168652939750909550929392840191610100900416600281111561260d5761260d614407565b600281111561261e5761261e614407565b905250905060018160200151600281111561263b5761263b614407565b14612672576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061268957612689615275565b6020020151156126c5576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f81106126e0576126e0615275565b9115156020909202015250506001016124f4565b81516126ff816117f4565b600061270a826118f6565b602085015151909150600081900361274d576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461278b576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156127a6576127a6613eca565b6040519080825280602002602001820160405280156127cf578160200160208202803683370190505b50905060005b82811015612944576000876020015182815181106127f5576127f5615275565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461288857805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107da565b61291e8186600101805461289b90615540565b80601f01602080910402602001604051908101604052809291908181526020018280546128c790615540565b80156129145780601f106128e957610100808354040283529160200191612914565b820191906000526020600020905b8154815290600101906020018083116128f757829003601f168201915b5050505050613560565b83838151811061293057612930615275565b6020908102919091010152506001016127d5565b50600061295b858389606001518a60800151613682565b9050806000036129a3576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff861660048201526024016107da565b8551151560005b848110156109b55760005a905060008a6020015183815181106129cf576129cf615275565b6020026020010151905060006129ed8a836000015160600151610a29565b90506000816003811115612a0357612a03614407565b1480612a2057506003816003811115612a1e57612a1e614407565b145b612a78578151606001516040805167ffffffffffffffff808e16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a1505050612e8f565b8415612b4857600454600090600160a01b900463ffffffff16612a9b88426154a0565b1190508080612abb57506003826003811115612ab957612ab9614407565b145b612afd576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8c1660048201526024016107da565b8b8581518110612b0f57612b0f615275565b6020026020010151600014612b42578b8581518110612b3057612b30615275565b60200260200101518360800181815250505b50612ba9565b6000816003811115612b5c57612b5c614407565b14612ba9578151606001516040805167ffffffffffffffff808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612a68565b81516080015167ffffffffffffffff1615612c98576000816003811115612bd257612bd2614407565b03612c985781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612c49928f929190600401615ab2565b6020604051808303816000875af1158015612c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8c9190615701565b612c9857505050612e8f565b60008c604001518581518110612cb057612cb0615275565b6020026020010151905080518360a001515114612d14578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808e16600483015290911660248201526044016107da565b612d288b84600001516060015160016136d8565b600080612d358584613780565b91509150612d4c8d866000015160600151846136d8565b8715612dbc576003826003811115612d6657612d66614407565b03612dbc576000846003811115612d7f57612d7f614407565b14612dbc578451516040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526107da91908390600401615adf565b6002826003811115612dd057612dd0614407565b14612e2a576003826003811115612de957612de9614407565b14612e2a578451606001516040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526107da918f918590600401615af8565b8451805160609091015167ffffffffffffffff908116908f167fdc8ccbc35e0eebd81239bcd1971fcd53c7eb34034880142a0f43c809a458732f85855a612e71908d6154a0565b604051612e8093929190615b1e565b60405180910390a45050505050505b6001016129aa565b60408051808201909152600080825260208201526000612eba876020015161384a565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f639190615b4e565b90506001600160a01b0381161580612fab5750612fa96001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120d1565b155b15612fed576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016107da565b600454600090819061300f9089908690600160e01b900463ffffffff166138f0565b9150915060008060006130dc6040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b81525060405160240161308d9190615b6b565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a1e565b9250925092508261311b57816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b81516020146131635781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b6000828060200190518101906131799190615c38565b9050866001600160a01b03168c6001600160a01b03161461320e5760006131aa8d8a6131a5868a6154a0565b6138f0565b509050868110806131c45750816131c188836154a0565b14155b1561320c576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016107da565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613268827f01ffc9a7000000000000000000000000000000000000000000000000000000006132a0565b8015610a795750613299827fffffffff000000000000000000000000000000000000000000000000000000006132a0565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015613344575060208210155b80156133505750600081115b979650505050505050565b60005b8151811015610cd85760ff83166000908152600360205260408120835190919084908490811061339057613390615275565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161335e565b60005b82518160ff161015610a23576000838260ff16815181106133ea576133ea615275565b602002602001015190506000600281111561340757613407614407565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561344657613446614407565b14613467576004604051631b3fab5160e11b81526004016107da91906159d0565b6001600160a01b0381166134a7576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134cd576134cd614407565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561352a5761352a614407565b0217905550905050508061353d90615c51565b90506133c7565b60ff81166105dd576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936135a6937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c70565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135ef9794969395929491939101615ca3565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136269190615d9a565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b600080613690858585613b44565b905061369b816113d9565b6136a95760009150506136d0565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026136e76080856154c9565b67ffffffffffffffff166136fb91906154f0565b905060006137098585611d84565b905081613718600160046154a0565b901b19168183600381111561372f5761372f614407565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161375e608088615944565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fece670b6000000000000000000000000000000000000000000000000000000008152600090606090309063ece670b6906137c49087908790600401615dfa565b600060405180830381600087803b1580156137de57600080fd5b505af19250505080156137ef575060015b61382e573d80801561381d576040519150601f19603f3d011682016040523d82523d6000602084013e613822565b606091505b50600392509050613843565b50506040805160208101909152600081526002905b9250929050565b6000815160201461388957816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b60008280602001905181019061389f9190615c38565b90506001600160a01b038111806138b7575061040081105b15610a7957826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b600080600080600061396a8860405160240161391b91906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a1e565b925092509250826139a957816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107da9190614222565b60208251146139f15781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016107da565b81806020019051810190613a059190615c38565b613a0f82886154a0565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a4157613a41613eca565b6040519080825280601f01601f191660200182016040528015613a6b576020820181803683370190505b509150863b613a9e577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613ad1577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613b0a577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b2d5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b85576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b9957506101018111155b613bb6576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613be0576040516309bde33960e01b815260040160405180910390fd5b80600003613c0d5786600081518110613bfb57613bfb615275565b60200260200101519350505050613ddc565b60008167ffffffffffffffff811115613c2857613c28613eca565b604051908082528060200260200182016040528015613c51578160200160208202803683370190505b50905060008080805b85811015613d7b5760006001821b8b811603613cb55788851015613c9e578c5160018601958e918110613c8f57613c8f615275565b60200260200101519050613cd7565b8551600185019487918110613c8f57613c8f615275565b8b5160018401938d918110613ccc57613ccc615275565b602002602001015190505b600089861015613d07578d5160018701968f918110613cf857613cf8615275565b60200260200101519050613d29565b8651600186019588918110613d1e57613d1e615275565b602002602001015190505b82851115613d4a576040516309bde33960e01b815260040160405180910390fd5b613d548282613de3565b878481518110613d6657613d66615275565b60209081029190910101525050600101613c5a565b506001850382148015613d8d57508683145b8015613d9857508581145b613db5576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613dca57613dca615275565b60200260200101519750505050505050505b9392505050565b6000818310613dfb57613df68284613e01565b610a76565b610a7683835b604080516001602082015290810183905260608101829052600090608001613664565b828054828255906000526020600020908101928215613e86579160200282015b82811115613e86578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e44565b50613e92929150613eb5565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e925760008155600101613eb6565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613f0357613f03613eca565b60405290565b60405160a0810167ffffffffffffffff81118282101715613f0357613f03613eca565b60405160c0810167ffffffffffffffff81118282101715613f0357613f03613eca565b6040805190810167ffffffffffffffff81118282101715613f0357613f03613eca565b6040516060810167ffffffffffffffff81118282101715613f0357613f03613eca565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fbe57613fbe613eca565b604052919050565b600067ffffffffffffffff821115613fe057613fe0613eca565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461401757600080fd5b919050565b80151581146105dd57600080fd5b80356140178161401c565b600067ffffffffffffffff82111561404f5761404f613eca565b50601f01601f191660200190565b600082601f83011261406e57600080fd5b813561408161407c82614035565b613f95565b81815284602083860101111561409657600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140c657600080fd5b823567ffffffffffffffff808211156140de57600080fd5b818501915085601f8301126140f257600080fd5b813561410061407c82613fc6565b81815260059190911b8301840190848101908883111561411f57600080fd5b8585015b838110156141c55780358581111561413b5760008081fd5b86016080818c03601f19018113156141535760008081fd5b61415b613ee0565b8983013561416881613fea565b81526040614177848201613fff565b8b83015260608085013561418a8161401c565b838301529284013592898411156141a357600091508182fd5b6141b18f8d8688010161405d565b908301525085525050918601918601614123565b5098975050505050505050565b60005b838110156141ed5781810151838201526020016141d5565b50506000910152565b6000815180845261420e8160208601602086016141d2565b601f01601f19169290920160200192915050565b602081526000610a7660208301846141f6565b8060608101831015610a7957600080fd5b60008083601f84011261425857600080fd5b50813567ffffffffffffffff81111561427057600080fd5b60208301915083602082850101111561384357600080fd5b60008083601f84011261429a57600080fd5b50813567ffffffffffffffff8111156142b257600080fd5b6020830191508360208260051b850101111561384357600080fd5b60008060008060008060008060e0898b0312156142e957600080fd5b6142f38a8a614235565b9750606089013567ffffffffffffffff8082111561431057600080fd5b61431c8c838d01614246565b909950975060808b013591508082111561433557600080fd5b6143418c838d01614288565b909750955060a08b013591508082111561435a57600080fd5b506143678b828c01614288565b999c989b50969995989497949560c00135949350505050565b60008060006080848603121561439557600080fd5b61439f8585614235565b9250606084013567ffffffffffffffff8111156143bb57600080fd5b6143c786828701614246565b9497909650939450505050565b600080604083850312156143e757600080fd5b6143f083613fff565b91506143fe60208401613fff565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b6004811061442d5761442d614407565b9052565b60208101610a79828461441d565b600060a0828403121561445157600080fd5b614459613f09565b90508135815261446b60208301613fff565b602082015261447c60408301613fff565b604082015261448d60608301613fff565b606082015261449e60808301613fff565b608082015292915050565b803561401781613fea565b600082601f8301126144c557600080fd5b813560206144d561407c83613fc6565b82815260059290921b840181019181810190868411156144f457600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156145195760008081fd5b8189019150608080601f19848d030112156145345760008081fd5b61453c613ee0565b878401358381111561454e5760008081fd5b61455c8d8a8388010161405d565b825250604080850135848111156145735760008081fd5b6145818e8b8389010161405d565b8a840152506060808601358581111561459a5760008081fd5b6145a88f8c838a010161405d565b92840192909252949092013593810193909352505083529183019183016144f8565b600061014082840312156145dd57600080fd5b6145e5613f2c565b90506145f1838361443f565b815260a082013567ffffffffffffffff8082111561460e57600080fd5b61461a8583860161405d565b602084015260c084013591508082111561463357600080fd5b61463f8583860161405d565b604084015261465060e085016144a9565b6060840152610100840135608084015261012084013591508082111561467557600080fd5b50614682848285016144b4565b60a08301525092915050565b600082601f83011261469f57600080fd5b813560206146af61407c83613fc6565b82815260059290921b840181019181810190868411156146ce57600080fd5b8286015b848110156120c557803567ffffffffffffffff8111156146f25760008081fd5b6147008986838b01016145ca565b8452509183019183016146d2565b600082601f83011261471f57600080fd5b8135602061472f61407c83613fc6565b82815260059290921b8401810191818101908684111561474e57600080fd5b8286015b848110156120c557803567ffffffffffffffff8082111561477257600080fd5b818901915089603f83011261478657600080fd5b8582013561479661407c82613fc6565b81815260059190911b830160400190878101908c8311156147b657600080fd5b604085015b838110156147ef578035858111156147d257600080fd5b6147e18f6040838a010161405d565b8452509189019189016147bb565b50875250505092840192508301614752565b600082601f83011261481257600080fd5b8135602061482261407c83613fc6565b8083825260208201915060208460051b87010193508684111561484457600080fd5b602086015b848110156120c55780358352918301918301614849565b600082601f83011261487157600080fd5b8135602061488161407c83613fc6565b82815260059290921b840181019181810190868411156148a057600080fd5b8286015b848110156120c557803567ffffffffffffffff808211156148c55760008081fd5b818901915060a080601f19848d030112156148e05760008081fd5b6148e8613f09565b6148f3888501613fff565b8152604080850135848111156149095760008081fd5b6149178e8b8389010161468e565b8a84015250606080860135858111156149305760008081fd5b61493e8f8c838a010161470e565b83850152506080915081860135858111156149595760008081fd5b6149678f8c838a0101614801565b91840191909152509190930135908301525083529183019183016148a4565b600080604080848603121561499a57600080fd5b833567ffffffffffffffff808211156149b257600080fd5b6149be87838801614860565b94506020915081860135818111156149d557600080fd5b8601601f810188136149e657600080fd5b80356149f461407c82613fc6565b81815260059190911b8201840190848101908a831115614a1357600080fd5b8584015b83811015614a9f57803586811115614a2f5760008081fd5b8501603f81018d13614a415760008081fd5b87810135614a5161407c82613fc6565b81815260059190911b82018a0190898101908f831115614a715760008081fd5b928b01925b82841015614a8f5783358252928a0192908a0190614a76565b8652505050918601918601614a17565b50809750505050505050509250929050565b600060208284031215614ac357600080fd5b813567ffffffffffffffff811115614ada57600080fd5b820160a08185031215613ddc57600080fd5b803563ffffffff8116811461401757600080fd5b600060a08284031215614b1257600080fd5b614b1a613f09565b8235614b2581613fea565b8152614b3360208401614aec565b6020820152614b4460408401614aec565b6040820152614b5560608401614aec565b60608201526080830135614b6881613fea565b60808201529392505050565b803560ff8116811461401757600080fd5b600060208284031215614b9757600080fd5b610a7682614b74565b60008151808452602080850194506020840160005b83811015614bda5781516001600160a01b031687529582019590820190600101614bb5565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c3460e0840182614ba0565b90506040840151601f198483030160c0850152614c518282614ba0565b95945050505050565b60008060408385031215614c6d57600080fd5b614c7683613fff565b946020939093013593505050565b60008060208385031215614c9757600080fd5b823567ffffffffffffffff80821115614caf57600080fd5b818501915085601f830112614cc357600080fd5b813581811115614cd257600080fd5b8660208260061b8501011115614ce757600080fd5b60209290920196919550909350505050565b600060208284031215614d0b57600080fd5b610a7682613fff565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136d060a08401826141f6565b600080600060408486031215614d7757600080fd5b833567ffffffffffffffff80821115614d8f57600080fd5b614d9b878388016145ca565b94506020860135915080821115614db157600080fd5b506143c786828701614288565b600060208284031215614dd057600080fd5b8135613ddc81613fea565b600082601f830112614dec57600080fd5b81356020614dfc61407c83613fc6565b8083825260208201915060208460051b870101935086841115614e1e57600080fd5b602086015b848110156120c5578035614e3681613fea565b8352918301918301614e23565b60006020808385031215614e5657600080fd5b823567ffffffffffffffff80821115614e6e57600080fd5b818501915085601f830112614e8257600080fd5b8135614e9061407c82613fc6565b81815260059190911b83018401908481019088831115614eaf57600080fd5b8585015b838110156141c557803585811115614eca57600080fd5b860160c0818c03601f19011215614ee15760008081fd5b614ee9613f2c565b8882013581526040614efc818401614b74565b8a8301526060614f0d818501614b74565b8284015260809150614f2082850161402a565b9083015260a08381013589811115614f385760008081fd5b614f468f8d83880101614ddb565b838501525060c0840135915088821115614f605760008081fd5b614f6e8e8c84870101614ddb565b9083015250845250918601918601614eb3565b600060208284031215614f9357600080fd5b5035919050565b80356001600160e01b038116811461401757600080fd5b600082601f830112614fc257600080fd5b81356020614fd261407c83613fc6565b82815260069290921b84018101918181019086841115614ff157600080fd5b8286015b848110156120c5576040818903121561500e5760008081fd5b615016613f4f565b61501f82613fff565b815261502c858301614f9a565b81860152835291830191604001614ff5565b600082601f83011261504f57600080fd5b8135602061505f61407c83613fc6565b82815260079290921b8401810191818101908684111561507e57600080fd5b8286015b848110156120c557808803608081121561509c5760008081fd5b6150a4613f72565b6150ad83613fff565b8152604080601f19840112156150c35760008081fd5b6150cb613f4f565b92506150d8878501613fff565b83526150e5818501613fff565b8388015281870192909252606083013591810191909152835291830191608001615082565b6000602080838503121561511d57600080fd5b823567ffffffffffffffff8082111561513557600080fd5b8185019150604080838803121561514b57600080fd5b615153613f4f565b83358381111561516257600080fd5b84016040818a03121561517457600080fd5b61517c613f4f565b81358581111561518b57600080fd5b8201601f81018b1361519c57600080fd5b80356151aa61407c82613fc6565b81815260069190911b8201890190898101908d8311156151c957600080fd5b928a01925b828410156152195787848f0312156151e65760008081fd5b6151ee613f4f565b84356151f981613fea565b8152615206858d01614f9a565b818d0152825292870192908a01906151ce565b84525050508187013593508484111561523157600080fd5b61523d8a858401614fb1565b818801528252508385013591508282111561525757600080fd5b6152638883860161503e565b85820152809550505050505092915050565b634e487b7160e01b600052603260045260246000fd5b805160408084528151848201819052600092602091908201906060870190855b818110156152e257835180516001600160a01b031684528501516001600160e01b03168584015292840192918501916001016152ab565b50508583015187820388850152805180835290840192506000918401905b8083101561533c578351805167ffffffffffffffff1683528501516001600160e01b031685830152928401926001929092019190850190615300565b50979650505050505050565b602081526000610a76602083018461528b565b67ffffffffffffffff8316815260608101613ddc6020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153c7576153c7615390565b5092915050565b6000602080835260608451604080848701526153ed606087018361528b565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141c557845167ffffffffffffffff81511683528781015161544d89850182805167ffffffffffffffff908116835260209182015116910152565b5084015182870152938601936001929092019160809091019061540e565b60006020828403121561547d57600080fd5b813567ffffffffffffffff81111561549457600080fd5b6136d084828501614860565b81810381811115610a7957610a79615390565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff808416806154e4576154e46154b3565b92169190910692915050565b8082028115828204841417610a7957610a79615390565b60006040828403121561551957600080fd5b615521613f4f565b61552a83613fff565b8152602083013560208201528091505092915050565b600181811c9082168061555457607f821691505b60208210810361557457634e487b7160e01b600052602260045260246000fd5b50919050565b805182526000602067ffffffffffffffff81840151168185015260408084015160a060408701526155ae60a08701826141f6565b9050606085015186820360608801526155c782826141f6565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561533c57835180516001600160a01b03168352860151868301529285019260019290920191908401906155ea565b602081526000610a76602083018461557a565b608081526000615642608083018761557a565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561568057600080fd5b835161568b8161401c565b602085015190935067ffffffffffffffff8111156156a857600080fd5b8401601f810186136156b957600080fd5b80516156c761407c82614035565b8181528760208385010111156156dc57600080fd5b6156ed8260208301602086016141d2565b809450505050604084015190509250925092565b60006020828403121561571357600080fd5b8151613ddc8161401c565b601f821115610cd8576000816000526020600020601f850160051c810160208610156157475750805b601f850160051c820191505b818110156124df57828155600101615753565b815167ffffffffffffffff81111561578057615780613eca565b6157948161578e8454615540565b8461571e565b602080601f8311600181146157c957600084156157b15750858301515b600019600386901b1c1916600185901b1785556124df565b600085815260208120601f198616915b828110156157f8578886015182559484019460019091019084016157d9565b50858210156158165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c1660608501525060018085016080808601526000815461587881615540565b8060a089015260c0600183166000811461589957600181146158b5576158e5565b60ff19841660c08b015260c083151560051b8b010194506158e5565b85600052602060002060005b848110156158dc5781548c82018501529088019089016158c1565b8b0160c0019550505b50929998505050505050505050565b80820180821115610a7957610a79615390565b60ff8181168382160190811115610a7957610a79615390565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff8084168061595f5761595f6154b3565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126159a057600080fd5b83018035915067ffffffffffffffff8211156159bb57600080fd5b60200191503681900382131561384357600080fd5b60208101600583106159e4576159e4614407565b91905290565b60ff81811683821602908116908181146153c7576153c7615390565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a5e5784546001600160a01b031683526001948501949284019201615a39565b50508481036060860152865180825290820192508187019060005b81811015615a9e5782516001600160a01b031685529383019391830191600101615a79565b50505060ff851660808501525090506120c7565b600067ffffffffffffffff808616835280851660208401525060606040830152614c5160608301846141f6565b8281526040602082015260006136d060408301846141f6565b67ffffffffffffffff848116825283166020820152606081016136d0604083018461441d565b615b28818561441d565b606060208201526000615b3e60608301856141f6565b9050826040830152949350505050565b600060208284031215615b6057600080fd5b8151613ddc81613fea565b6020815260008251610100806020850152615b8a6101208501836141f6565b91506020850151615ba7604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615be160a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615bfe84836141f6565b935060c08701519150808685030160e0870152615c1b84836141f6565b935060e08701519150808685030183870152506120c783826141f6565b600060208284031215615c4a57600080fd5b5051919050565b600060ff821660ff8103615c6757615c67615390565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c760808301846141f6565b86815260c060208201526000615cbc60c08301886141f6565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615d8d57601f19868403018952815160808151818652615d39828701826141f6565b9150508582015185820387870152615d5182826141f6565b91505060408083015186830382880152615d6b83826141f6565b6060948501519790940196909652505098840198925090830190600101615d13565b5090979650505050505050565b602081526000610a766020830184615cf6565b60008282518085526020808601955060208260051b8401016020860160005b84811015615d8d57601f19868403018952615de88383516141f6565b98840198925090830190600101615dcc565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e626101808501836141f6565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615e9f84836141f6565b935060608801519150615ebe6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615ee58282615cf6565b9150508281036020840152614c518185615dad56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162006c1a38038062006c1a8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615f4462000cd6600039600081816102660152612a010152600081816102370152612ef40152600081816102080152818161142b015261196d0152600081816101d801526125f00152600081816117f3015261183f0152615f446000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063ccd37ba31161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063ccd37ba31461050b578063d2a15d3514610550578063e9d68a8e1461056357600080fd5b8063991a5018116100bd578063991a5018146104c5578063a80036b4146104d8578063c673e584146104eb57600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b8063311cd5131161012f5780635e36480c116101145780635e36480c146103785780637437ff9f1461039857806379ba50971461049457600080fd5b8063311cd513146103495780633f4b04aa1461035c57600080fd5b806306285c691161016057806306285c69146101a4578063181f5a77146102ed5780632d04ab761461033657600080fd5b806304666f9c1461017c57806305d938b514610191575b600080fd5b61018f61018a3660046140af565b6105cc565b005b61018f61019f36600461473b565b6105e0565b61029660408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102e49190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103296040518060400160405280601181526020017f4f666652616d7020312e362e302d64657600000000000000000000000000000081525081565b6040516102e491906148b6565b61018f610344366004614961565b610785565b61018f610357366004614a14565b610b5c565b60095460405167ffffffffffffffff90911681526020016102e4565b61038b610386366004614a68565b610bc5565b6040516102e49190614ac5565b6104376040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102e49190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610c1b565b61018f610177366004614ad3565b6000546040516001600160a01b0390911681526020016102e4565b61018f6104d3366004614b22565b610cd9565b61018f6104e6366004614b96565b610cea565b6104fe6104f9366004614c03565b61105d565b6040516102e49190614c63565b610542610519366004614cd8565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102e4565b61018f61055e366004614d02565b6111bb565b610576610571366004614d77565b611275565b6040516102e49190614d92565b61018f610591366004614de0565b611382565b61018f6105a4366004614e65565b611393565b6105bc6105b7366004614fa3565b6113d5565b60405190151581526020016102e4565b6105d4611496565b6105dd816114f2565b50565b6105e86117f0565b815181518114610624576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8181101561077557600084828151811061064357610643614fbc565b6020026020010151905060008160200151519050600085848151811061066b5761066b614fbc565b60200260200101519050805182146106af576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b828110156107665760008282815181106106ce576106ce614fbc565b602002602001015190508060001461075d57846020015182815181106106f6576106f6614fbc565b60200260200101516080015181101561075d5784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064015b60405180910390fd5b506001016106b2565b50505050806001019050610627565b506107808383611871565b505050565b600061079387890189615142565b805151519091501515806107ac57508051602001515115155b156108ac5760095460208a01359067ffffffffffffffff8083169116101561086b576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261083492910161536a565b600060405180830381600087803b15801561084e57600080fd5b505af1158015610862573d6000803e3d6000fd5b505050506108aa565b8160200151516000036108aa576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b816020015151811015610aa5576000826020015182815181106108d4576108d4614fbc565b602002602001015190506000816000015190506108f081611921565b60006108fb82611a23565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061093f575060208084015190810151905167ffffffffffffffff9182169116115b1561097f57825160208401516040517feefb0cac00000000000000000000000000000000000000000000000000000000815261075492919060040161537d565b6040830151806109bb576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff16600090815260086020908152604080832084845290915290205415610a2e5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101829052604401610754565b6020808501510151610a419060016153c8565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff9283160217909255925116600090815260086020908152604080832094835293905291909120429055506001016108af565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610ad591906153f0565b60405180910390a1610b5160008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b9250611a8a915050565b505050505050505050565b610b9c610b6b8284018461548d565b6040805160008082526020820190925290610b96565b6060815260200190600190039081610b815790505b50611871565b604080516000808252602082019092529050610bbf600185858585866000611a8a565b50505050565b6000610bd3600160046154c2565b6002610be06080856154eb565b67ffffffffffffffff16610bf49190615512565b610bfe8585611e01565b901c166003811115610c1257610c12614a9b565b90505b92915050565b6001546001600160a01b03163314610c755760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610754565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ce1611496565b6105dd81611e48565b333014610d23576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281610d60565b6040805180820190915260008082526020820152815260200190600190039081610d395790505b5060a08501515190915015610d9457610d918460a00151856020015186606001518760000151602001518787611fae565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff1681830152808701518351600094840192610dd09291016148b6565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015610edd576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a190610e4a9085906004016155cb565b600060405180830381600087803b158015610e6457600080fd5b505af1925050508015610e75575060015b610edd573d808015610ea3576040519150601f19603f3d011682016040523d82523d6000602084013e610ea8565b606091505b50806040517f09c2532500000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b604086015151158015610ef257506080860151155b80610f09575060608601516001600160a01b03163b155b80610f4957506060860151610f47906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120cd565b155b15610f5657505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf9798392610fce92899261138892916004016155de565b6000604051808303816000875af1158015610fed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611015919081019061561a565b50915091508161105357806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b5050505050505050565b6110a06040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c08201529485529182018054845181840281018401909552808552929385830193909283018282801561114957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161112b575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156111ab57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161118d575b5050505050815250509050919050565b6111c3611496565b60005b818110156107805760008383838181106111e2576111e2614fbc565b9050604002018036038101906111f891906156b0565b905061120781602001516113d5565b61126c57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b506001016111c6565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191611302906156e9565b80601f016020809104026020016040519081016040528092919081815260200182805461132e906156e9565b80156111ab5780601f10611350576101008083540402835291602001916111ab565b820191906000526020600020905b81548152906001019060200180831161135e57505050919092525091949350505050565b61138a611496565b6105dd816120e9565b61139b611496565b60005b81518110156113d1576113c98282815181106113bc576113bc614fbc565b602002602001015161219f565b60010161139e565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611472573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c159190615723565b6000546001600160a01b031633146114f05760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610754565b565b60005b81518110156113d157600082828151811061151257611512614fbc565b602002602001015190506000816020015190508067ffffffffffffffff16600003611569576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611591576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115bc906156e9565b80601f01602080910402602001604051908101604052809291908181526020018280546115e8906156e9565b80156116355780601f1061160a57610100808354040283529160200191611635565b820191906000526020600020905b81548152906001019060200180831161161857829003601f168201915b5050505050905060008460600151905081516000036116ed578051600003611670576040516342bcdf7f60e11b815260040160405180910390fd5b6001830161167e8282615788565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611740565b8080519060200120828051906020012014611740576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610754565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117d8908690615848565b60405180910390a250505050508060010190506114f5565b467f0000000000000000000000000000000000000000000000000000000000000000146114f0576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610754565b81516000036118ab576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b845181101561191a576119128582815181106118e0576118e0614fbc565b60200260200101518461190c578583815181106118ff576118ff614fbc565b60200260200101516124e3565b836124e3565b6001016118c2565b5050505050565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa1580156119bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e09190615723565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610754565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610c15576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610754565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611ae98760a4615916565b9050826060015115611b31578451611b02906020615512565b8651611b0f906020615512565b611b1a9060a0615916565b611b249190615916565b611b2e9082615916565b90505b368114611b73576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610754565b5081518114611bbb5781516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610754565b611bc36117f0565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611c1157611c11614a9b565b6002811115611c2257611c22614a9b565b9052509050600281602001516002811115611c3f57611c3f614a9b565b148015611c935750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611c7b57611c7b614fbc565b6000918252602090912001546001600160a01b031633145b611cc9576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611dab576020820151611ce4906001615929565b60ff16855114611d20576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611d5b576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611d6d929190615942565b604051908190038120611d84918b90602001615952565b604051602081830303815290604052805190602001209050611da98a82888888612c86565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b67ffffffffffffffff8216600090815260076020526040812081611e26608085615966565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b80516001600160a01b0316611e70576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fca57611fca613ec6565b60405190808252806020026020018201604052801561200f57816020015b6040805180820190915260008082526020820152815260200190600190039081611fe85790505b50905060005b87518110156120c15761209c88828151811061203357612033614fbc565b602002602001015188888888888781811061205057612050614fbc565b9050602002810190612062919061598d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9392505050565b8282815181106120ae576120ae614fbc565b6020908102919091010152600101612015565b505b9695505050505050565b60006120d883613238565b8015610c125750610c12838361329c565b336001600160a01b038216036121415760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610754565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ca576000604051631b3fab5160e11b815260040161075491906159f2565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223757606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff90921691909117905561228c565b6060840151600182015460ff620100009091041615159015151461228c576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff84166004820152602401610754565b60a08401518051601f60ff821611156122bb576001604051631b3fab5160e11b815260040161075491906159f2565b612321858560030180548060200260200160405190810160405280929190818152602001828054801561231757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122f9575b5050505050613357565b8560600151156124505761238f8585600201805480602002602001604051908101604052809291908181526020018280548015612317576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122f9575050505050613357565b608086015180516123a99060028701906020840190613e20565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f1015612409576002604051631b3fab5160e11b815260040161075491906159f2565b6040880151612419906003615a0c565b60ff168160ff1611612441576003604051631b3fab5160e11b815260040161075491906159f2565b61244d878360016133c0565b50505b61245c858360026133c0565b81516124719060038601906020850190613e20565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ca938a939260028b01929190615a28565b60405180910390a16124db85613540565b505050505050565b81516124ee81611921565b60006124f982611a23565b602085015151909150600081900361253c576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461257a576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561259557612595613ec6565b6040519080825280602002602001820160405280156125be578160200160208202803683370190505b50905060005b82811015612733576000876020015182815181106125e4576125e4614fbc565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461267757805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610754565b61270d8186600101805461268a906156e9565b80601f01602080910402602001604051908101604052809291908181526020018280546126b6906156e9565b80156127035780601f106126d857610100808354040283529160200191612703565b820191906000526020600020905b8154815290600101906020018083116126e657829003601f168201915b505050505061355c565b83838151811061271f5761271f614fbc565b6020908102919091010152506001016125c4565b50600061274a858389606001518a6080015161367e565b905080600003612792576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610754565b8551151560005b84811015610b515760005a905060008a6020015183815181106127be576127be614fbc565b6020026020010151905060006127dc8a836000015160600151610bc5565b905060008160038111156127f2576127f2614a9b565b148061280f5750600381600381111561280d5761280d614a9b565b145b612867578151606001516040805167ffffffffffffffff808e16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a1505050612c7e565b841561293757600454600090600160a01b900463ffffffff1661288a88426154c2565b11905080806128aa575060038260038111156128a8576128a8614a9b565b145b6128ec576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8c166004820152602401610754565b8b85815181106128fe576128fe614fbc565b6020026020010151600014612931578b858151811061291f5761291f614fbc565b60200260200101518360800181815250505b50612998565b600081600381111561294b5761294b614a9b565b14612998578151606001516040805167ffffffffffffffff808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612857565b81516080015167ffffffffffffffff1615612a875760008160038111156129c1576129c1614a9b565b03612a875781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612a38928f929190600401615ad4565b6020604051808303816000875af1158015612a57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7b9190615723565b612a8757505050612c7e565b60008c604001518581518110612a9f57612a9f614fbc565b6020026020010151905080518360a001515114612b03578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808e1660048301529091166024820152604401610754565b612b178b84600001516060015160016136d4565b600080612b24858461377c565b91509150612b3b8d866000015160600151846136d4565b8715612bab576003826003811115612b5557612b55614a9b565b03612bab576000846003811115612b6e57612b6e614a9b565b14612bab578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261075491908390600401615b01565b6002826003811115612bbf57612bbf614a9b565b14612c19576003826003811115612bd857612bd8614a9b565b14612c19578451606001516040517f926c5a3e000000000000000000000000000000000000000000000000000000008152610754918f918590600401615b1a565b8451805160609091015167ffffffffffffffff908116908f167fdc8ccbc35e0eebd81239bcd1971fcd53c7eb34034880142a0f43c809a458732f85855a612c60908d6154c2565b604051612c6f93929190615b40565b60405180910390a45050505050505b600101612799565b612c8e613e92565b835160005b81811015611053576000600188868460208110612cb257612cb2614fbc565b612cbf91901a601b615929565b898581518110612cd157612cd1614fbc565b6020026020010151898681518110612ceb57612ceb614fbc565b602002602001015160405160008152602001604052604051612d29949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612d4b573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b03851683528152858220858701909652855480841686529397509095509293928401916101009004166002811115612dac57612dac614a9b565b6002811115612dbd57612dbd614a9b565b9052509050600181602001516002811115612dda57612dda614a9b565b14612e11576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f8110612e2857612e28614fbc565b602002015115612e64576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f8110612e7f57612e7f614fbc565b911515602090920201525050600101612c93565b60408051808201909152600080825260208201526000612eb68760200151613846565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5f9190615b70565b90506001600160a01b0381161580612fa75750612fa56001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120cd565b155b15612fe9576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610754565b600454600090819061300b9089908690600160e01b900463ffffffff166138ec565b9150915060008060006130d86040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b8152506040516024016130899190615b8d565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a1a565b9250925092508261311757816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b815160201461315f5781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610754565b6000828060200190518101906131759190615c5a565b9050866001600160a01b03168c6001600160a01b03161461320a5760006131a68d8a6131a1868a6154c2565b6138ec565b509050868110806131c05750816131bd88836154c2565b14155b15613208576040517fa966e21f000000000000000000000000000000000000000000000000000000008152600481018390526024810188905260448101829052606401610754565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613264827f01ffc9a70000000000000000000000000000000000000000000000000000000061329c565b8015610c155750613295827fffffffff0000000000000000000000000000000000000000000000000000000061329c565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015613340575060208210155b801561334c5750600081115b979650505050505050565b60005b81518110156107805760ff83166000908152600360205260408120835190919084908490811061338c5761338c614fbc565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161335a565b60005b82518160ff161015610bbf576000838260ff16815181106133e6576133e6614fbc565b602002602001015190506000600281111561340357613403614a9b565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561344257613442614a9b565b14613463576004604051631b3fab5160e11b815260040161075491906159f2565b6001600160a01b0381166134a3576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134c9576134c9614a9b565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561352657613526614a9b565b0217905550905050508061353990615c73565b90506133c3565b60ff81166105dd576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936135a2937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c92565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135eb9794969395929491939101615cc5565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136229190615dd7565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061368c858585613b40565b9050613697816113d5565b6136a55760009150506136cc565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026136e36080856154eb565b67ffffffffffffffff166136f79190615512565b905060006137058585611e01565b905081613714600160046154c2565b901b19168183600381111561372b5761372b614a9b565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161375a608088615966565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fa80036b4000000000000000000000000000000000000000000000000000000008152600090606090309063a80036b4906137c09087908790600401615e37565b600060405180830381600087803b1580156137da57600080fd5b505af19250505080156137eb575060015b61382a573d808015613819576040519150601f19603f3d011682016040523d82523d6000602084013e61381e565b606091505b5060039250905061383f565b50506040805160208101909152600081526002905b9250929050565b6000815160201461388557816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b60008280602001905181019061389b9190615c5a565b90506001600160a01b038111806138b3575061040081105b15610c1557826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b60008060008060006139668860405160240161391791906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a1a565b925092509250826139a557816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b60208251146139ed5781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610754565b81806020019051810190613a019190615c5a565b613a0b82886154c2565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a3d57613a3d613ec6565b6040519080825280601f01601f191660200182016040528015613a67576020820181803683370190505b509150863b613a9a577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613acd577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613b06577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b295750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b81576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b9557506101018111155b613bb2576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bdc576040516309bde33960e01b815260040160405180910390fd5b80600003613c095786600081518110613bf757613bf7614fbc565b60200260200101519350505050613dd8565b60008167ffffffffffffffff811115613c2457613c24613ec6565b604051908082528060200260200182016040528015613c4d578160200160208202803683370190505b50905060008080805b85811015613d775760006001821b8b811603613cb15788851015613c9a578c5160018601958e918110613c8b57613c8b614fbc565b60200260200101519050613cd3565b8551600185019487918110613c8b57613c8b614fbc565b8b5160018401938d918110613cc857613cc8614fbc565b602002602001015190505b600089861015613d03578d5160018701968f918110613cf457613cf4614fbc565b60200260200101519050613d25565b8651600186019588918110613d1a57613d1a614fbc565b602002602001015190505b82851115613d46576040516309bde33960e01b815260040160405180910390fd5b613d508282613ddf565b878481518110613d6257613d62614fbc565b60209081029190910101525050600101613c56565b506001850382148015613d8957508683145b8015613d9457508581145b613db1576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613dc657613dc6614fbc565b60200260200101519750505050505050505b9392505050565b6000818310613df757613df28284613dfd565b610c12565b610c1283835b604080516001602082015290810183905260608101829052600090608001613660565b828054828255906000526020600020908101928215613e82579160200282015b82811115613e82578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e40565b50613e8e929150613eb1565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e8e5760008155600101613eb2565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613eff57613eff613ec6565b60405290565b60405160a0810167ffffffffffffffff81118282101715613eff57613eff613ec6565b60405160c0810167ffffffffffffffff81118282101715613eff57613eff613ec6565b6040805190810167ffffffffffffffff81118282101715613eff57613eff613ec6565b6040516060810167ffffffffffffffff81118282101715613eff57613eff613ec6565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fba57613fba613ec6565b604052919050565b600067ffffffffffffffff821115613fdc57613fdc613ec6565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461401357600080fd5b919050565b80151581146105dd57600080fd5b803561401381614018565b600067ffffffffffffffff82111561404b5761404b613ec6565b50601f01601f191660200190565b600082601f83011261406a57600080fd5b813561407d61407882614031565b613f91565b81815284602083860101111561409257600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140c257600080fd5b823567ffffffffffffffff808211156140da57600080fd5b818501915085601f8301126140ee57600080fd5b81356140fc61407882613fc2565b81815260059190911b8301840190848101908883111561411b57600080fd5b8585015b838110156141c1578035858111156141375760008081fd5b86016080818c03601f190181131561414f5760008081fd5b614157613edc565b8983013561416481613fe6565b81526040614173848201613ffb565b8b83015260608085013561418681614018565b8383015292840135928984111561419f57600091508182fd5b6141ad8f8d86880101614059565b90830152508552505091860191860161411f565b5098975050505050505050565b600060a082840312156141e057600080fd5b6141e8613f05565b9050813581526141fa60208301613ffb565b602082015261420b60408301613ffb565b604082015261421c60608301613ffb565b606082015261422d60808301613ffb565b608082015292915050565b803561401381613fe6565b600082601f83011261425457600080fd5b8135602061426461407883613fc2565b82815260059290921b8401810191818101908684111561428357600080fd5b8286015b848110156120c157803567ffffffffffffffff808211156142a85760008081fd5b818901915060a080601f19848d030112156142c35760008081fd5b6142cb613f05565b87840135838111156142dd5760008081fd5b6142eb8d8a83880101614059565b825250604080850135848111156143025760008081fd5b6143108e8b83890101614059565b8a84015250606080860135858111156143295760008081fd5b6143378f8c838a0101614059565b8385015250608091508186013581840152508285013592508383111561435d5760008081fd5b61436b8d8a85880101614059565b908201528652505050918301918301614287565b6000610140828403121561439257600080fd5b61439a613f28565b90506143a683836141ce565b815260a082013567ffffffffffffffff808211156143c357600080fd5b6143cf85838601614059565b602084015260c08401359150808211156143e857600080fd5b6143f485838601614059565b604084015261440560e08501614238565b6060840152610100840135608084015261012084013591508082111561442a57600080fd5b5061443784828501614243565b60a08301525092915050565b600082601f83011261445457600080fd5b8135602061446461407883613fc2565b82815260059290921b8401810191818101908684111561448357600080fd5b8286015b848110156120c157803567ffffffffffffffff8111156144a75760008081fd5b6144b58986838b010161437f565b845250918301918301614487565b600082601f8301126144d457600080fd5b813560206144e461407883613fc2565b82815260059290921b8401810191818101908684111561450357600080fd5b8286015b848110156120c157803567ffffffffffffffff8082111561452757600080fd5b818901915089603f83011261453b57600080fd5b8582013561454b61407882613fc2565b81815260059190911b830160400190878101908c83111561456b57600080fd5b604085015b838110156145a45780358581111561458757600080fd5b6145968f6040838a0101614059565b845250918901918901614570565b50875250505092840192508301614507565b600082601f8301126145c757600080fd5b813560206145d761407883613fc2565b8083825260208201915060208460051b8701019350868411156145f957600080fd5b602086015b848110156120c157803583529183019183016145fe565b600082601f83011261462657600080fd5b8135602061463661407883613fc2565b82815260059290921b8401810191818101908684111561465557600080fd5b8286015b848110156120c157803567ffffffffffffffff8082111561467a5760008081fd5b818901915060a080601f19848d030112156146955760008081fd5b61469d613f05565b6146a8888501613ffb565b8152604080850135848111156146be5760008081fd5b6146cc8e8b83890101614443565b8a84015250606080860135858111156146e55760008081fd5b6146f38f8c838a01016144c3565b838501525060809150818601358581111561470e5760008081fd5b61471c8f8c838a01016145b6565b9184019190915250919093013590830152508352918301918301614659565b600080604080848603121561474f57600080fd5b833567ffffffffffffffff8082111561476757600080fd5b61477387838801614615565b945060209150818601358181111561478a57600080fd5b8601601f8101881361479b57600080fd5b80356147a961407882613fc2565b81815260059190911b8201840190848101908a8311156147c857600080fd5b8584015b83811015614854578035868111156147e45760008081fd5b8501603f81018d136147f65760008081fd5b8781013561480661407882613fc2565b81815260059190911b82018a0190898101908f8311156148265760008081fd5b928b01925b828410156148445783358252928a0192908a019061482b565b86525050509186019186016147cc565b50809750505050505050509250929050565b60005b83811015614881578181015183820152602001614869565b50506000910152565b600081518084526148a2816020860160208601614866565b601f01601f19169290920160200192915050565b602081526000610c12602083018461488a565b8060608101831015610c1557600080fd5b60008083601f8401126148ec57600080fd5b50813567ffffffffffffffff81111561490457600080fd5b60208301915083602082850101111561383f57600080fd5b60008083601f84011261492e57600080fd5b50813567ffffffffffffffff81111561494657600080fd5b6020830191508360208260051b850101111561383f57600080fd5b60008060008060008060008060e0898b03121561497d57600080fd5b6149878a8a6148c9565b9750606089013567ffffffffffffffff808211156149a457600080fd5b6149b08c838d016148da565b909950975060808b01359150808211156149c957600080fd5b6149d58c838d0161491c565b909750955060a08b01359150808211156149ee57600080fd5b506149fb8b828c0161491c565b999c989b50969995989497949560c00135949350505050565b600080600060808486031215614a2957600080fd5b614a3385856148c9565b9250606084013567ffffffffffffffff811115614a4f57600080fd5b614a5b868287016148da565b9497909650939450505050565b60008060408385031215614a7b57600080fd5b614a8483613ffb565b9150614a9260208401613ffb565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614ac157614ac1614a9b565b9052565b60208101610c158284614ab1565b600060208284031215614ae557600080fd5b813567ffffffffffffffff811115614afc57600080fd5b820160a08185031215613dd857600080fd5b803563ffffffff8116811461401357600080fd5b600060a08284031215614b3457600080fd5b614b3c613f05565b8235614b4781613fe6565b8152614b5560208401614b0e565b6020820152614b6660408401614b0e565b6040820152614b7760608401614b0e565b60608201526080830135614b8a81613fe6565b60808201529392505050565b600080600060408486031215614bab57600080fd5b833567ffffffffffffffff80821115614bc357600080fd5b614bcf8783880161437f565b94506020860135915080821115614be557600080fd5b50614a5b8682870161491c565b803560ff8116811461401357600080fd5b600060208284031215614c1557600080fd5b610c1282614bf2565b60008151808452602080850194506020840160005b83811015614c585781516001600160a01b031687529582019590820190600101614c33565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614cb260e0840182614c1e565b90506040840151601f198483030160c0850152614ccf8282614c1e565b95945050505050565b60008060408385031215614ceb57600080fd5b614cf483613ffb565b946020939093013593505050565b60008060208385031215614d1557600080fd5b823567ffffffffffffffff80821115614d2d57600080fd5b818501915085601f830112614d4157600080fd5b813581811115614d5057600080fd5b8660208260061b8501011115614d6557600080fd5b60209290920196919550909350505050565b600060208284031215614d8957600080fd5b610c1282613ffb565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136cc60a084018261488a565b600060208284031215614df257600080fd5b8135613dd881613fe6565b600082601f830112614e0e57600080fd5b81356020614e1e61407883613fc2565b8083825260208201915060208460051b870101935086841115614e4057600080fd5b602086015b848110156120c1578035614e5881613fe6565b8352918301918301614e45565b60006020808385031215614e7857600080fd5b823567ffffffffffffffff80821115614e9057600080fd5b818501915085601f830112614ea457600080fd5b8135614eb261407882613fc2565b81815260059190911b83018401908481019088831115614ed157600080fd5b8585015b838110156141c157803585811115614eec57600080fd5b860160c0818c03601f19011215614f035760008081fd5b614f0b613f28565b8882013581526040614f1e818401614bf2565b8a8301526060614f2f818501614bf2565b8284015260809150614f42828501614026565b9083015260a08381013589811115614f5a5760008081fd5b614f688f8d83880101614dfd565b838501525060c0840135915088821115614f825760008081fd5b614f908e8c84870101614dfd565b9083015250845250918601918601614ed5565b600060208284031215614fb557600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b80356001600160e01b038116811461401357600080fd5b600082601f830112614ffa57600080fd5b8135602061500a61407883613fc2565b82815260069290921b8401810191818101908684111561502957600080fd5b8286015b848110156120c157604081890312156150465760008081fd5b61504e613f4b565b61505782613ffb565b8152615064858301614fd2565b8186015283529183019160400161502d565b600082601f83011261508757600080fd5b8135602061509761407883613fc2565b82815260079290921b840181019181810190868411156150b657600080fd5b8286015b848110156120c15780880360808112156150d45760008081fd5b6150dc613f6e565b6150e583613ffb565b8152604080601f19840112156150fb5760008081fd5b615103613f4b565b9250615110878501613ffb565b835261511d818501613ffb565b83880152818701929092526060830135918101919091528352918301916080016150ba565b6000602080838503121561515557600080fd5b823567ffffffffffffffff8082111561516d57600080fd5b8185019150604080838803121561518357600080fd5b61518b613f4b565b83358381111561519a57600080fd5b84016040818a0312156151ac57600080fd5b6151b4613f4b565b8135858111156151c357600080fd5b8201601f81018b136151d457600080fd5b80356151e261407882613fc2565b81815260069190911b8201890190898101908d83111561520157600080fd5b928a01925b828410156152515787848f03121561521e5760008081fd5b615226613f4b565b843561523181613fe6565b815261523e858d01614fd2565b818d0152825292870192908a0190615206565b84525050508187013593508484111561526957600080fd5b6152758a858401614fe9565b818801528252508385013591508282111561528f57600080fd5b61529b88838601615076565b85820152809550505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b8181101561530457835180516001600160a01b031684528501516001600160e01b03168584015292840192918501916001016152cd565b50508583015187820388850152805180835290840192506000918401905b8083101561535e578351805167ffffffffffffffff1683528501516001600160e01b031685830152928401926001929092019190850190615322565b50979650505050505050565b602081526000610c1260208301846152ad565b67ffffffffffffffff8316815260608101613dd86020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153e9576153e96153b2565b5092915050565b60006020808352606084516040808487015261540f60608701836152ad565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141c157845167ffffffffffffffff81511683528781015161546f89850182805167ffffffffffffffff908116835260209182015116910152565b50840151828701529386019360019290920191608090910190615430565b60006020828403121561549f57600080fd5b813567ffffffffffffffff8111156154b657600080fd5b6136cc84828501614615565b81810381811115610c1557610c156153b2565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff80841680615506576155066154d5565b92169190910692915050565b8082028115828204841417610c1557610c156153b2565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261555d60a087018261488a565b905060608501518682036060880152615576828261488a565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561535e57835180516001600160a01b0316835286015186830152928501926001929092019190840190615599565b602081526000610c126020830184615529565b6080815260006155f16080830187615529565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561562f57600080fd5b835161563a81614018565b602085015190935067ffffffffffffffff81111561565757600080fd5b8401601f8101861361566857600080fd5b805161567661407882614031565b81815287602083850101111561568b57600080fd5b61569c826020830160208601614866565b809450505050604084015190509250925092565b6000604082840312156156c257600080fd5b6156ca613f4b565b6156d383613ffb565b8152602083013560208201528091505092915050565b600181811c908216806156fd57607f821691505b60208210810361571d57634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561573557600080fd5b8151613dd881614018565b601f821115610780576000816000526020600020601f850160051c810160208610156157695750805b601f850160051c820191505b818110156124db57828155600101615775565b815167ffffffffffffffff8111156157a2576157a2613ec6565b6157b6816157b084546156e9565b84615740565b602080601f8311600181146157eb57600084156157d35750858301515b600019600386901b1c1916600185901b1785556124db565b600085815260208120601f198616915b8281101561581a578886015182559484019460019091019084016157fb565b50858210156158385787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c1660608501525060018085016080808601526000815461589a816156e9565b8060a089015260c060018316600081146158bb57600181146158d757615907565b60ff19841660c08b015260c083151560051b8b01019450615907565b85600052602060002060005b848110156158fe5781548c82018501529088019089016158e3565b8b0160c0019550505b50929998505050505050505050565b80820180821115610c1557610c156153b2565b60ff8181168382160190811115610c1557610c156153b2565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff80841680615981576159816154d5565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126159c257600080fd5b83018035915067ffffffffffffffff8211156159dd57600080fd5b60200191503681900382131561383f57600080fd5b6020810160058310615a0657615a06614a9b565b91905290565b60ff81811683821602908116908181146153e9576153e96153b2565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a805784546001600160a01b031683526001948501949284019201615a5b565b50508481036060860152865180825290820192508187019060005b81811015615ac05782516001600160a01b031685529383019391830191600101615a9b565b50505060ff851660808501525090506120c3565b600067ffffffffffffffff808616835280851660208401525060606040830152614ccf606083018461488a565b8281526040602082015260006136cc604083018461488a565b67ffffffffffffffff848116825283166020820152606081016136cc6040830184614ab1565b615b4a8185614ab1565b606060208201526000615b60606083018561488a565b9050826040830152949350505050565b600060208284031215615b8257600080fd5b8151613dd881613fe6565b6020815260008251610100806020850152615bac61012085018361488a565b91506020850151615bc9604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615c0360a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615c20848361488a565b935060c08701519150808685030160e0870152615c3d848361488a565b935060e08701519150808685030183870152506120c3838261488a565b600060208284031215615c6c57600080fd5b5051919050565b600060ff821660ff8103615c8957615c896153b2565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c3608083018461488a565b86815260c060208201526000615cde60c083018861488a565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615dca57601f19868403018952815160a08151818652615d5b8287018261488a565b9150508582015185820387870152615d73828261488a565b91505060408083015186830382880152615d8d838261488a565b92505050606080830151818701525060808083015192508582038187015250615db6818361488a565b9a86019a9450505090830190600101615d35565b5090979650505050505050565b602081526000610c126020830184615d18565b60008282518085526020808601955060208260051b8401016020860160005b84811015615dca57601f19868403018952615e2583835161488a565b98840198925090830190600101615e09565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e9f61018085018361488a565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615edc848361488a565b935060608801519150615efb6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615f228282615d18565b9150508281036020840152614ccf8185615dea56fea164736f6c6343000818000a", } var OffRampABI = OffRampMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/onramp/onramp.go b/core/gethwrappers/ccip/generated/onramp/onramp.go index 5a77d6854f..46804a0e47 100644 --- a/core/gethwrappers/ccip/generated/onramp/onramp.go +++ b/core/gethwrappers/ccip/generated/onramp/onramp.go @@ -67,6 +67,7 @@ type InternalRampTokenAmount struct { DestTokenAddress []byte ExtraData []byte Amount *big.Int + DestExecData []byte } type OnRampDestChainConfig struct { @@ -93,8 +94,8 @@ type OnRampStaticConfig struct { } var OnRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b50604051620036af380380620036af83398101604081905262000035916200069c565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000186565b505083516001600160401b031615905080620000e6575060208301516001600160a01b0316155b80620000fd575060408301516001600160a01b0316155b8062000114575060608301516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b82516001600160401b031660805260208301516001600160a01b0390811660a0526040840151811660c05260608401511660e052620001728262000231565b6200017d816200036d565b5050506200079c565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316158062000254575060408101516001600160a01b0316155b1562000273576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b03938416179091556020808401805160038054851691861691909117905560408086018051600480549096169087161790945580516080808201835280516001600160401b031680835260a08051891684880190815260c080518b1686880190815260e080518d166060988901908152895196875293518d169a86019a909a52518b169684019690965251891693820193909352885188169181019190915292518616908301529251909316918301919091527f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558910160405180910390a150565b60005b8151811015620004aa57600082828151811062000391576200039162000786565b602002602001015190506000838381518110620003b257620003b262000786565b6020026020010151600001519050806001600160401b0316600003620003f75760405163c35aa79d60e01b81526001600160401b038216600482015260240162000083565b6040805180820182526001600160401b03838116600081815260056020818152868320805480871688528a8301516001600160a01b03908116848a019081529587905293835287518551851668010000000000000000026001600160e01b0319909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a250505080600101905062000370565b5050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620004e957620004e9620004ae565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200051a576200051a620004ae565b604052919050565b80516001600160401b03811681146200053a57600080fd5b919050565b6001600160a01b03811681146200055557600080fd5b50565b6000606082840312156200056b57600080fd5b604051606081016001600160401b0381118282101715620005905762000590620004ae565b80604052508091508251620005a5816200053f565b81526020830151620005b7816200053f565b60208201526040830151620005cc816200053f565b6040919091015292915050565b600082601f830112620005eb57600080fd5b815160206001600160401b03821115620006095762000609620004ae565b62000619818360051b01620004ef565b82815260069290921b840181019181810190868411156200063957600080fd5b8286015b84811015620006915760408189031215620006585760008081fd5b62000662620004c4565b6200066d8262000522565b8152848201516200067e816200053f565b818601528352918301916040016200063d565b509695505050505050565b6000806000838503610100811215620006b457600080fd5b6080811215620006c357600080fd5b50604051608081016001600160401b038082118383101715620006ea57620006ea620004ae565b81604052620006f98762000522565b8352602087015191506200070d826200053f565b8160208401526040870151915062000725826200053f565b816040840152606087015191506200073d826200053f565b81606084015282955062000755886080890162000558565b945060e08701519250808311156200076c57600080fd5b50506200077c86828701620005d9565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e051612e9a62000815600039600081816101eb015281816108a201526115da0152600081816101af01528181610dc601526115b3015260008181610173015281816104c4015261158901526000818161014301528181610cec0152818161117c015261155c0152612e9a6000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637437ff9f11610097578063d77d5ed011610066578063d77d5ed0146103ba578063df0aa9e914610406578063f2fde38b14610419578063fbca3b741461042c57600080fd5b80637437ff9f146102fb57806379ba5097146103685780638da5cb5b146103705780639041be3d1461038e57600080fd5b806320487ded116100d357806320487ded1461028757806334d560e4146102a85780633a019940146102bb57806348a98aa4146102c357600080fd5b80630242cf60146100fa57806306285c691461010f578063181f5a771461023e575b600080fd5b61010d610108366004611fe6565b61044c565b005b61022860408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161023591906120a9565b60405180910390f35b61027a6040518060400160405280601081526020017f4f6e52616d7020312e362e302d6465760000000000000000000000000000000081525081565b604051610235919061216e565b61029a610295366004612199565b610460565b604051908152602001610235565b61010d6102b63660046121f9565b610619565b61010d61062a565b6102d66102d136600461226b565b61085a565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610235565b61035b6040805160608101825260008082526020820181905291810191909152506040805160608101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454169181019190915290565b60405161023591906122a4565b61010d61090f565b60005473ffffffffffffffffffffffffffffffffffffffff166102d6565b6103a161039c3660046122e1565b610a0c565b60405167ffffffffffffffff9091168152602001610235565b6102d66103c83660046122e1565b67ffffffffffffffff1660009081526005602052604090205468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b61029a6104143660046122fe565b610a35565b61010d61042736600461236a565b611230565b61043f61043a3660046122e1565b611241565b6040516102359190612387565b610454611275565b61045d816112f8565b50565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561050b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052f91906123f1565b15610577576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6002546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd906105cf9086908690600401612520565b602060405180830381865afa1580156105ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106109190612669565b90505b92915050565b610621611275565b61045d81611470565b600254604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610699573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106df9190810190612682565b60045490915073ffffffffffffffffffffffffffffffffffffffff1660005b825181101561085557600083828151811061071b5761071b612711565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610796573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ba9190612669565b9050801561084b576107e373ffffffffffffffffffffffffffffffffffffffff8316858361163a565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e8360405161084291815260200190565b60405180910390a35b50506001016106fe565b505050565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa1580156108eb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106109190612740565b60015473ffffffffffffffffffffffffffffffffffffffff163314610990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161056e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff80821660009081526005602052604081205490916106139116600161278c565b67ffffffffffffffff8416600090815260056020526040812073ffffffffffffffffffffffffffffffffffffffff8316610a9b576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610af7576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035473ffffffffffffffffffffffffffffffffffffffff168015610b9d576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610b6a908a908a90600401612520565b600060405180830381600087803b158015610b8457600080fd5b505af1158015610b98573d6000803e3d6000fd5b505050505b506002546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a610bd460808c0160608d0161236a565b8a610be260808e018e6127b4565b6040518663ffffffff1660e01b8152600401610c02959493929190612819565b600060405180830381865afa158015610c1f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c6591908101906128e1565b91945092509050610c7c6080890160608a0161236a565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f84604051610cc391815260200190565b60405180910390a2604080516101a081019091526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528c811661014085015287549293928392916101608401918a918791610d389116612938565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200186610e38576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e33919061295f565b610e3b565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a8060200190610e7991906127b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610ebd8b806127b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f0460808c018c6127b4565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f4e60808c0160608d0161236a565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190610f7f919061297c565b905067ffffffffffffffff811115610f9957610f99611ee3565b604051908082528060200260200182016040528015610ff557816020015b610fe26040518060800160405280606081526020016060815260200160608152602001600081525090565b815260200190600190039081610fb75790505b509052905060005b61100a60408b018b61297c565b90508110156110b95761109061102360408c018c61297c565b8381811061103357611033612711565b90506040020180360381019061104991906129e4565b8c6110548d806127b4565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92506116c7915050565b8260e0015182815181106110a6576110a6612711565b6020908102919091010152600101610ffd565b5060025460e082015173ffffffffffffffffffffffffffffffffffffffff9091169063cc88924c908c906110f060408e018e61297c565b6040518563ffffffff1660e01b815260040161110f9493929190612ae0565b60006040518083038186803b15801561112757600080fd5b505afa15801561113b573d6000803e3d6000fd5b505050506080808201839052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908c16606082015230918101919091526111d890829060a001604051602081830303815290604052805190602001206119d1565b81515260405167ffffffffffffffff8b16907f0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab2990611217908490612b16565b60405180910390a251519450505050505b949350505050565b611238611275565b61045d81611ad1565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff1633146112f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161056e565b565b60005b815181101561146c57600082828151811061131857611318612711565b60200260200101519050600083838151811061133657611336612711565b60200260200101516000015190508067ffffffffffffffff16600003611394576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161056e565b60408051808201825267ffffffffffffffff838116600081815260056020818152868320805480871688528a83015173ffffffffffffffffffffffffffffffffffffffff908116848a019081529587905293835287518551851668010000000000000000027fffffffff00000000000000000000000000000000000000000000000000000000909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a25050508060010190506112fb565b5050565b805173ffffffffffffffffffffffffffffffffffffffff1615806114ac5750604081015173ffffffffffffffffffffffffffffffffffffffff16155b156114e3576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480549094169085161790925581516080810183527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008416918101919091527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea45589161162f918490612c64565b60405180910390a150565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610855908490611bc6565b6116f26040518060800160405280606081526020016060815260200160608152602001600081525090565b8460200151600003611730576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061174085876000015161085a565b905073ffffffffffffffffffffffffffffffffffffffff8116158061181057506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156117ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180e91906123f1565b155b156118625785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161056e565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b81526004016119019190612cf6565b6000604051808303816000875af1158015611920573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119669190810190612d6c565b604080516080810190915273ffffffffffffffffffffffffffffffffffffffff841660a08201529091508060c0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c00151604051602001611a1396959493929190612dfd565b604051602081830303815290604052805190602001208560400151805190602001208660e00151604051602001611a4a9190612e5e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611b50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161056e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611c28826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611cd29092919063ffffffff16565b8051909150156108555780806020019051810190611c4691906123f1565b610855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161056e565b6060611ce18484600085611ceb565b90505b9392505050565b606082471015611d7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161056e565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611da69190612e71565b60006040518083038185875af1925050503d8060008114611de3576040519150601f19603f3d011682016040523d82523d6000602084013e611de8565b606091505b5091509150611df987838387611e04565b979650505050505050565b60608315611e9a578251600003611e935773ffffffffffffffffffffffffffffffffffffffff85163b611e93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161056e565b5081611228565b6112288383815115611eaf5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056e919061216e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611f3557611f35611ee3565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611f8257611f82611ee3565b604052919050565b600067ffffffffffffffff821115611fa457611fa4611ee3565b5060051b60200190565b67ffffffffffffffff8116811461045d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461045d57600080fd5b60006020808385031215611ff957600080fd5b823567ffffffffffffffff81111561201057600080fd5b8301601f8101851361202157600080fd5b803561203461202f82611f8a565b611f3b565b81815260069190911b8201830190838101908783111561205357600080fd5b928401925b82841015611df957604084890312156120715760008081fd5b612079611f12565b843561208481611fae565b81528486013561209381611fc4565b8187015282526040939093019290840190612058565b60808101610613828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b8381101561211b578181015183820152602001612103565b50506000910152565b6000815180845261213c816020860160208601612100565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106106020830184612124565b600060a0828403121561219357600080fd5b50919050565b600080604083850312156121ac57600080fd5b82356121b781611fae565b9150602083013567ffffffffffffffff8111156121d357600080fd5b6121df85828601612181565b9150509250929050565b80356121f481611fc4565b919050565b60006060828403121561220b57600080fd5b6040516060810181811067ffffffffffffffff8211171561222e5761222e611ee3565b604052823561223c81611fc4565b8152602083013561224c81611fc4565b6020820152604083013561225f81611fc4565b60408201529392505050565b6000806040838503121561227e57600080fd5b823561228981611fae565b9150602083013561229981611fc4565b809150509250929050565b606081016106138284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260409182015116910152565b6000602082840312156122f357600080fd5b8135611ce481611fae565b6000806000806080858703121561231457600080fd5b843561231f81611fae565b9350602085013567ffffffffffffffff81111561233b57600080fd5b61234787828801612181565b93505060408501359150606085013561235f81611fc4565b939692955090935050565b60006020828403121561237c57600080fd5b8135611ce481611fc4565b6020808252825182820181905260009190848201906040850190845b818110156123d557835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016123a3565b50909695505050505050565b805180151581146121f457600080fd5b60006020828403121561240357600080fd5b610610826123e1565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261244157600080fd5b830160208101925035905067ffffffffffffffff81111561246157600080fd5b80360382131561247057600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156125155781356124e381611fc4565b73ffffffffffffffffffffffffffffffffffffffff1687528183013583880152604096870196909101906001016124d0565b509495945050505050565b600067ffffffffffffffff808516835260406020840152612541848561240c565b60a0604086015261255660e086018284612477565b915050612566602086018661240c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087850301606088015261259c848385612477565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030183126125d557600080fd5b602092880192830192359150848211156125ee57600080fd5b8160061b360383131561260057600080fd5b808785030160808801526126158483856124c0565b9450612623606089016121e9565b73ffffffffffffffffffffffffffffffffffffffff811660a0890152935061264e608089018961240c565b94509250808786030160c08801525050611df9838383612477565b60006020828403121561267b57600080fd5b5051919050565b6000602080838503121561269557600080fd5b825167ffffffffffffffff8111156126ac57600080fd5b8301601f810185136126bd57600080fd5b80516126cb61202f82611f8a565b81815260059190911b820183019083810190878311156126ea57600080fd5b928401925b82841015611df957835161270281611fc4565b825292840192908401906126ef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561275257600080fd5b8151611ce481611fc4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156127ad576127ad61275d565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126127e957600080fd5b83018035915067ffffffffffffffff82111561280457600080fd5b60200191503681900382131561247057600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152608060608201526000611df9608083018486612477565b600082601f83011261287057600080fd5b815167ffffffffffffffff81111561288a5761288a611ee3565b6128bb60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611f3b565b8181528460208386010111156128d057600080fd5b611228826020830160208701612100565b6000806000606084860312156128f657600080fd5b83519250612906602085016123e1565b9150604084015167ffffffffffffffff81111561292257600080fd5b61292e8682870161285f565b9150509250925092565b600067ffffffffffffffff8083168181036129555761295561275d565b6001019392505050565b60006020828403121561297157600080fd5b8151611ce481611fae565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126129b157600080fd5b83018035915067ffffffffffffffff8211156129cc57600080fd5b6020019150600681901b360382131561247057600080fd5b6000604082840312156129f657600080fd5b6129fe611f12565b8235612a0981611fc4565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b84811015612ad3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160808151818652612a7f82870182612124565b9150508582015185820387870152612a978282612124565b91505060408083015186830382880152612ab18382612124565b6060948501519790940196909652505098840198925090830190600101612a3b565b5090979650505050505050565b67ffffffffffffffff85168152606060208201526000612b036060830186612a1e565b8281036040840152611df98185876124c0565b60208152612b6760208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b60006020830151612b9060c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e0850152612bad6101a0850183612124565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301610100870152612bea8483612124565b9350608087015191508086850301610120870152612c088483612124565b935060a08701519150612c3461014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e0870151915080868503018387015250612c5a8382612a1e565b9695505050505050565b60e08101612cbb828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a084015260408401511660c0830152611ce4565b602081526000825160a06020840152612d1260c0840182612124565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600060208284031215612d7e57600080fd5b815167ffffffffffffffff80821115612d9657600080fd5b9083019060408286031215612daa57600080fd5b612db2611f12565b825182811115612dc157600080fd5b612dcd8782860161285f565b825250602083015182811115612de257600080fd5b612dee8782860161285f565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c06020840152612e2d60c0840189612124565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b6020815260006106106020830184612a1e565b60008251612e83818460208701612100565b919091019291505056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b506040516200382d3803806200382d83398101604081905262000035916200069c565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000186565b505083516001600160401b031615905080620000e6575060208301516001600160a01b0316155b80620000fd575060408301516001600160a01b0316155b8062000114575060608301516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b82516001600160401b031660805260208301516001600160a01b0390811660a0526040840151811660c05260608401511660e052620001728262000231565b6200017d816200036d565b5050506200079c565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316158062000254575060408101516001600160a01b0316155b1562000273576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b03938416179091556020808401805160038054851691861691909117905560408086018051600480549096169087161790945580516080808201835280516001600160401b031680835260a08051891684880190815260c080518b1686880190815260e080518d166060988901908152895196875293518d169a86019a909a52518b169684019690965251891693820193909352885188169181019190915292518616908301529251909316918301919091527f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558910160405180910390a150565b60005b8151811015620004aa57600082828151811062000391576200039162000786565b602002602001015190506000838381518110620003b257620003b262000786565b6020026020010151600001519050806001600160401b0316600003620003f75760405163c35aa79d60e01b81526001600160401b038216600482015260240162000083565b6040805180820182526001600160401b03838116600081815260056020818152868320805480871688528a8301516001600160a01b03908116848a019081529587905293835287518551851668010000000000000000026001600160e01b0319909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a250505080600101905062000370565b5050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620004e957620004e9620004ae565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200051a576200051a620004ae565b604052919050565b80516001600160401b03811681146200053a57600080fd5b919050565b6001600160a01b03811681146200055557600080fd5b50565b6000606082840312156200056b57600080fd5b604051606081016001600160401b0381118282101715620005905762000590620004ae565b80604052508091508251620005a5816200053f565b81526020830151620005b7816200053f565b60208201526040830151620005cc816200053f565b6040919091015292915050565b600082601f830112620005eb57600080fd5b815160206001600160401b03821115620006095762000609620004ae565b62000619818360051b01620004ef565b82815260069290921b840181019181810190868411156200063957600080fd5b8286015b84811015620006915760408189031215620006585760008081fd5b62000662620004c4565b6200066d8262000522565b8152848201516200067e816200053f565b818601528352918301916040016200063d565b509695505050505050565b6000806000838503610100811215620006b457600080fd5b6080811215620006c357600080fd5b50604051608081016001600160401b038082118383101715620006ea57620006ea620004ae565b81604052620006f98762000522565b8352602087015191506200070d826200053f565b8160208401526040870151915062000725826200053f565b816040840152606087015191506200073d826200053f565b81606084015282955062000755886080890162000558565b945060e08701519250808311156200076c57600080fd5b50506200077c86828701620005d9565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e05161301862000815600039600081816101eb015281816108a201526116700152600081816101af01528181610dc60152611649015260008181610173015281816104c4015261161f01526000818161014301528181610cec0152818161121101526115f201526130186000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637437ff9f11610097578063d77d5ed011610066578063d77d5ed0146103ba578063df0aa9e914610406578063f2fde38b14610419578063fbca3b741461042c57600080fd5b80637437ff9f146102fb57806379ba5097146103685780638da5cb5b146103705780639041be3d1461038e57600080fd5b806320487ded116100d357806320487ded1461028757806334d560e4146102a85780633a019940146102bb57806348a98aa4146102c357600080fd5b80630242cf60146100fa57806306285c691461010f578063181f5a771461023e575b600080fd5b61010d610108366004612098565b61044c565b005b61022860408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b604051610235919061215b565b60405180910390f35b61027a6040518060400160405280601081526020017f4f6e52616d7020312e362e302d6465760000000000000000000000000000000081525081565b6040516102359190612220565b61029a61029536600461224b565b610460565b604051908152602001610235565b61010d6102b63660046122ab565b610619565b61010d61062a565b6102d66102d136600461231d565b61085a565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610235565b61035b6040805160608101825260008082526020820181905291810191909152506040805160608101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454169181019190915290565b6040516102359190612356565b61010d61090f565b60005473ffffffffffffffffffffffffffffffffffffffff166102d6565b6103a161039c366004612393565b610a0c565b60405167ffffffffffffffff9091168152602001610235565b6102d66103c8366004612393565b67ffffffffffffffff1660009081526005602052604090205468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b61029a6104143660046123b0565b610a35565b61010d61042736600461241c565b6112c6565b61043f61043a366004612393565b6112d7565b6040516102359190612439565b61045461130b565b61045d8161138e565b50565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561050b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052f91906124a3565b15610577576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6002546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd906105cf90869086906004016125d2565b602060405180830381865afa1580156105ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610610919061271b565b90505b92915050565b61062161130b565b61045d81611506565b600254604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610699573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106df9190810190612734565b60045490915073ffffffffffffffffffffffffffffffffffffffff1660005b825181101561085557600083828151811061071b5761071b6127c3565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610796573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ba919061271b565b9050801561084b576107e373ffffffffffffffffffffffffffffffffffffffff831685836116d0565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e8360405161084291815260200190565b60405180910390a35b50506001016106fe565b505050565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa1580156108eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061091906127f2565b60015473ffffffffffffffffffffffffffffffffffffffff163314610990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161056e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff80821660009081526005602052604081205490916106139116600161283e565b67ffffffffffffffff8416600090815260056020526040812073ffffffffffffffffffffffffffffffffffffffff8316610a9b576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610af7576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035473ffffffffffffffffffffffffffffffffffffffff168015610b9d576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610b6a908a908a906004016125d2565b600060405180830381600087803b158015610b8457600080fd5b505af1158015610b98573d6000803e3d6000fd5b505050505b506002546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a610bd460808c0160608d0161241c565b8a610be260808e018e612866565b6040518663ffffffff1660e01b8152600401610c029594939291906128cb565b600060405180830381865afa158015610c1f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c659190810190612993565b91945092509050610c7c6080890160608a0161241c565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f84604051610cc391815260200190565b60405180910390a2604080516101a081019091526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528c811661014085015287549293928392916101608401918a918791610d3891166129ea565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200186610e38576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e339190612a11565b610e3b565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a8060200190610e799190612866565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610ebd8b80612866565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f0460808c018c612866565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f4e60808c0160608d0161241c565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190610f7f9190612a2e565b905067ffffffffffffffff811115610f9957610f99611f95565b604051908082528060200260200182016040528015610ffc57816020015b610fe96040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b815260200190600190039081610fb75790505b509052905060005b61101160408b018b612a2e565b90508110156110c05761109761102a60408c018c612a2e565b8381811061103a5761103a6127c3565b9050604002018036038101906110509190612a96565b8c61105b8d80612866565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e925061175d915050565b8260e0015182815181106110ad576110ad6127c3565b6020908102919091010152600101611004565b5060025460e082015160009173ffffffffffffffffffffffffffffffffffffffff169063085318f8908d906110f860408f018f612a2e565b6040518563ffffffff1660e01b81526004016111179493929190612bad565b600060405180830381865afa158015611134573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261117a9190810190612be3565b905060005b8260e00151518110156111d35781818151811061119e5761119e6127c3565b60200260200101518360e0015182815181106111bc576111bc6127c3565b60209081029190910101516080015260010161117f565b506080808301849052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908d166060820152309181019190915261126d90839060a00160405160208183030381529060405280519060200120611a83565b82515260405167ffffffffffffffff8c16907fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140906112ac908590612c94565b60405180910390a25051519450505050505b949350505050565b6112ce61130b565b61045d81611b83565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461138c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161056e565b565b60005b81518110156115025760008282815181106113ae576113ae6127c3565b6020026020010151905060008383815181106113cc576113cc6127c3565b60200260200101516000015190508067ffffffffffffffff1660000361142a576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161056e565b60408051808201825267ffffffffffffffff838116600081815260056020818152868320805480871688528a83015173ffffffffffffffffffffffffffffffffffffffff908116848a019081529587905293835287518551851668010000000000000000027fffffffff00000000000000000000000000000000000000000000000000000000909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a2505050806001019050611391565b5050565b805173ffffffffffffffffffffffffffffffffffffffff1615806115425750604081015173ffffffffffffffffffffffffffffffffffffffff16155b15611579576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480549094169085161790925581516080810183527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008416918101919091527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558916116c5918490612de2565b60405180910390a150565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610855908490611c78565b61178f6040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b84602001516000036117cd576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006117dd85876000015161085a565b905073ffffffffffffffffffffffffffffffffffffffff811615806118ad57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015611887573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ab91906124a3565b155b156118ff5785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161056e565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b815260040161199e9190612e74565b6000604051808303816000875af11580156119bd573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611a039190810190612eea565b6040805160a0810190915273ffffffffffffffffffffffffffffffffffffffff841660c08201529091508060e0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181526020016040518060200160405280600081525081525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c00151604051602001611ac596959493929190612f7b565b604051602081830303815290604052805190602001208560400151805190602001208660e00151604051602001611afc9190612fdc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611c02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161056e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611cda826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611d849092919063ffffffff16565b8051909150156108555780806020019051810190611cf891906124a3565b610855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161056e565b6060611d938484600085611d9d565b90505b9392505050565b606082471015611e2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161056e565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611e589190612fef565b60006040518083038185875af1925050503d8060008114611e95576040519150601f19603f3d011682016040523d82523d6000602084013e611e9a565b606091505b5091509150611eab87838387611eb6565b979650505050505050565b60608315611f4c578251600003611f455773ffffffffffffffffffffffffffffffffffffffff85163b611f45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161056e565b50816112be565b6112be8383815115611f615781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056e9190612220565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611fe757611fe7611f95565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561203457612034611f95565b604052919050565b600067ffffffffffffffff82111561205657612056611f95565b5060051b60200190565b67ffffffffffffffff8116811461045d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461045d57600080fd5b600060208083850312156120ab57600080fd5b823567ffffffffffffffff8111156120c257600080fd5b8301601f810185136120d357600080fd5b80356120e66120e18261203c565b611fed565b81815260069190911b8201830190838101908783111561210557600080fd5b928401925b82841015611eab57604084890312156121235760008081fd5b61212b611fc4565b843561213681612060565b81528486013561214581612076565b818701528252604093909301929084019061210a565b60808101610613828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b838110156121cd5781810151838201526020016121b5565b50506000910152565b600081518084526121ee8160208601602086016121b2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061061060208301846121d6565b600060a0828403121561224557600080fd5b50919050565b6000806040838503121561225e57600080fd5b823561226981612060565b9150602083013567ffffffffffffffff81111561228557600080fd5b61229185828601612233565b9150509250929050565b80356122a681612076565b919050565b6000606082840312156122bd57600080fd5b6040516060810181811067ffffffffffffffff821117156122e0576122e0611f95565b60405282356122ee81612076565b815260208301356122fe81612076565b6020820152604083013561231181612076565b60408201529392505050565b6000806040838503121561233057600080fd5b823561233b81612060565b9150602083013561234b81612076565b809150509250929050565b606081016106138284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260409182015116910152565b6000602082840312156123a557600080fd5b8135611d9681612060565b600080600080608085870312156123c657600080fd5b84356123d181612060565b9350602085013567ffffffffffffffff8111156123ed57600080fd5b6123f987828801612233565b93505060408501359150606085013561241181612076565b939692955090935050565b60006020828403121561242e57600080fd5b8135611d9681612076565b6020808252825182820181905260009190848201906040850190845b8181101561248757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612455565b50909695505050505050565b805180151581146122a657600080fd5b6000602082840312156124b557600080fd5b61061082612493565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126124f357600080fd5b830160208101925035905067ffffffffffffffff81111561251357600080fd5b80360382131561252257600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156125c757813561259581612076565b73ffffffffffffffffffffffffffffffffffffffff168752818301358388015260409687019690910190600101612582565b509495945050505050565b600067ffffffffffffffff8085168352604060208401526125f384856124be565b60a0604086015261260860e086018284612529565b91505061261860208601866124be565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087850301606088015261264e848385612529565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe188360301831261268757600080fd5b602092880192830192359150848211156126a057600080fd5b8160061b36038313156126b257600080fd5b808785030160808801526126c7848385612572565b94506126d56060890161229b565b73ffffffffffffffffffffffffffffffffffffffff811660a0890152935061270060808901896124be565b94509250808786030160c08801525050611eab838383612529565b60006020828403121561272d57600080fd5b5051919050565b6000602080838503121561274757600080fd5b825167ffffffffffffffff81111561275e57600080fd5b8301601f8101851361276f57600080fd5b805161277d6120e18261203c565b81815260059190911b8201830190838101908783111561279c57600080fd5b928401925b82841015611eab5783516127b481612076565b825292840192908401906127a1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561280457600080fd5b8151611d9681612076565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561285f5761285f61280f565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261289b57600080fd5b83018035915067ffffffffffffffff8211156128b657600080fd5b60200191503681900382131561252257600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152608060608201526000611eab608083018486612529565b600082601f83011261292257600080fd5b815167ffffffffffffffff81111561293c5761293c611f95565b61296d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611fed565b81815284602083860101111561298257600080fd5b6112be8260208301602087016121b2565b6000806000606084860312156129a857600080fd5b835192506129b860208501612493565b9150604084015167ffffffffffffffff8111156129d457600080fd5b6129e086828701612911565b9150509250925092565b600067ffffffffffffffff808316818103612a0757612a0761280f565b6001019392505050565b600060208284031215612a2357600080fd5b8151611d9681612060565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612a6357600080fd5b83018035915067ffffffffffffffff821115612a7e57600080fd5b6020019150600681901b360382131561252257600080fd5b600060408284031215612aa857600080fd5b612ab0611fc4565b8235612abb81612076565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b84811015612ba0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160a08151818652612b31828701826121d6565b9150508582015185820387870152612b4982826121d6565b91505060408083015186830382880152612b6383826121d6565b92505050606080830151818701525060808083015192508582038187015250612b8c81836121d6565b9a86019a9450505090830190600101612aed565b5090979650505050505050565b67ffffffffffffffff85168152606060208201526000612bd06060830186612ad0565b8281036040840152611eab818587612572565b60006020808385031215612bf657600080fd5b825167ffffffffffffffff80821115612c0e57600080fd5b818501915085601f830112612c2257600080fd5b8151612c306120e18261203c565b81815260059190911b83018401908481019088831115612c4f57600080fd5b8585015b83811015612c8757805185811115612c6b5760008081fd5b612c798b89838a0101612911565b845250918601918601612c53565b5098975050505050505050565b60208152612ce560208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b60006020830151612d0e60c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e0850152612d2b6101a08501836121d6565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301610100870152612d6884836121d6565b9350608087015191508086850301610120870152612d8684836121d6565b935060a08701519150612db261014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e0870151915080868503018387015250612dd88382612ad0565b9695505050505050565b60e08101612e39828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a084015260408401511660c0830152611d96565b602081526000825160a06020840152612e9060c08401826121d6565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600060208284031215612efc57600080fd5b815167ffffffffffffffff80821115612f1457600080fd5b9083019060408286031215612f2857600080fd5b612f30611fc4565b825182811115612f3f57600080fd5b612f4b87828601612911565b825250602083015182811115612f6057600080fd5b612f6c87828601612911565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c06020840152612fab60c08401896121d6565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b6020815260006106106020830184612ad0565b600082516130018184602087016121b2565b919091019291505056fea164736f6c6343000818000a", } var OnRampABI = OnRampMetaData.ABI @@ -1437,7 +1438,7 @@ func (_OnRamp *OnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { } func (OnRampCCIPSendRequested) Topic() common.Hash { - return common.HexToHash("0x0f07cd31e53232da9125e517f09550fdde74bf43d6a0a76ebd41674dafe2ab29") + return common.HexToHash("0xcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140") } func (OnRampConfigSet) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generated/price_registry/price_registry.go b/core/gethwrappers/ccip/generated/price_registry/price_registry.go index fd50287f53..a4839d7ac3 100644 --- a/core/gethwrappers/ccip/generated/price_registry/price_registry.go +++ b/core/gethwrappers/ccip/generated/price_registry/price_registry.go @@ -68,6 +68,7 @@ type InternalRampTokenAmount struct { DestTokenAddress []byte ExtraData []byte Amount *big.Int + DestExecData []byte } type InternalTimestampedPackedUint224 struct { @@ -100,7 +101,6 @@ type PriceRegistryDestChainConfig struct { DestDataAvailabilityMultiplierBps uint16 DefaultTokenFeeUSDCents uint16 DefaultTokenDestGasOverhead uint32 - DefaultTokenDestBytesOverhead uint32 DefaultTxGasLimit uint32 GasMultiplierWeiPerEth uint64 NetworkFeeUSDCents uint32 @@ -154,8 +154,8 @@ type PriceRegistryTokenTransferFeeConfigSingleTokenArgs struct { } var PriceRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"}],\"name\":\"ReportForwarderUnauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feedTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"storedTimeStamp\",\"type\":\"uint256\"}],\"name\":\"StaleKeystoneUpdate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"reportId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission\",\"name\":\"permission\",\"type\":\"tuple\"}],\"name\":\"ReportPermissionSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission[]\",\"name\":\"permissions\",\"type\":\"tuple[]\"}],\"name\":\"setReportPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"validatePoolReturnData\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620075cf380380620075cf83398101604081905262000034916200188e565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a9f565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b6b565b5050505050505062001b4c565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db620019ad565b60209081029190910101519050620002f560028262000ea4565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb576000828281518110620003695762000369620019ad565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000ec4565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a25762000440838281518110620004275762000427620019ad565b6020026020010151600b62000ec460201b90919060201c565b1562000499578281815181106200045b576200045b620019ad565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c9620019ad565b6020026020010151600b62000edb60201b90919060201c565b156200053b57818181518110620004fd57620004fd620019ad565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d620019ad565b6020908102919091018101518051818301516001600160a01b0380831660008181526007875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e620019ad565b6020026020010151905060008383815181106200065f576200065f620019ad565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061018081015163ffffffff16155b80620006ba57506102008101516001600160e01b031916630a04b54b60e21b14155b80620006d75750602063ffffffff1681610160015163ffffffff16105b80620006f75750806060015163ffffffff1681610180015163ffffffff16115b15620007225760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260096020526040812060010154600160a81b900460e01b6001600160e01b0319169003620007a257816001600160401b03167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d1357782604051620007949190620019c3565b60405180910390a2620007e6565b816001600160401b03167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad9382604051620007dd9190620019c3565b60405180910390a25b8060096000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a8154816001600160401b0302191690836001600160401b031602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000ac35762000ac3620019ad565b6020026020010151600001519050600083838151811062000ae85762000ae8620019ad565b6020908102919091018101518101516001600160a01b03841660008181526008845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000aa2565b60005b825181101562000dde57600083828151811062000b8f5762000b8f620019ad565b6020026020010151905060008160000151905060005b82602001515181101562000dcf5760008360200151828151811062000bce5762000bce620019ad565b602002602001015160200151905060008460200151838151811062000bf75762000bf7620019ad565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c565760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000dbc908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000ba5565b50505080600101905062000b6e565b5060005b81518110156200054457600082828151811062000e035762000e03620019ad565b6020026020010151600001519050600083838151811062000e285762000e28620019ad565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000de2565b600062000ebb836001600160a01b03841662000ef2565b90505b92915050565b600062000ebb836001600160a01b03841662000ff6565b600062000ebb836001600160a01b03841662001048565b6000818152600183016020526040812054801562000feb57600062000f1960018362001b14565b855490915060009062000f2f9060019062001b14565b905081811462000f9b57600086600001828154811062000f535762000f53620019ad565b906000526020600020015490508087600001848154811062000f795762000f79620019ad565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000faf5762000faf62001b36565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000ebe565b600091505062000ebe565b60008181526001830160205260408120546200103f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000ebe565b50600062000ebe565b6000818152600183016020526040812054801562000feb5760006200106f60018362001b14565b8554909150600090620010859060019062001b14565b905080821462000f9b57600086600001828154811062000f535762000f53620019ad565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620010e457620010e4620010a9565b60405290565b60405160c081016001600160401b0381118282101715620010e457620010e4620010a9565b60405161022081016001600160401b0381118282101715620010e457620010e4620010a9565b604051601f8201601f191681016001600160401b0381118282101715620011605762001160620010a9565b604052919050565b80516001600160a01b03811681146200118057600080fd5b919050565b805163ffffffff811681146200118057600080fd5b600060608284031215620011ad57600080fd5b604051606081016001600160401b0381118282101715620011d257620011d2620010a9565b604052825190915081906001600160601b0381168114620011f257600080fd5b8152620012026020840162001168565b6020820152620012156040840162001185565b60408201525092915050565b60006001600160401b038211156200123d576200123d620010a9565b5060051b60200190565b600082601f8301126200125957600080fd5b81516020620012726200126c8362001221565b62001135565b8083825260208201915060208460051b8701019350868411156200129557600080fd5b602086015b84811015620012bc57620012ae8162001168565b83529183019183016200129a565b509695505050505050565b600082601f830112620012d957600080fd5b81516020620012ec6200126c8362001221565b828152606092830285018201928282019190878511156200130c57600080fd5b8387015b858110156200139f57808903828112156200132b5760008081fd5b62001335620010bf565b620013408362001168565b8152604080601f1984011215620013575760008081fd5b62001361620010bf565b92506200137088850162001168565b835283015160ff81168114620013865760008081fd5b8288015280870191909152845292840192810162001310565b5090979650505050505050565b80516001600160401b03811681146200118057600080fd5b805161ffff811681146200118057600080fd5b805180151581146200118057600080fd5b600082601f830112620013fa57600080fd5b815160206200140d6200126c8362001221565b82815260059290921b840181019181810190868411156200142d57600080fd5b8286015b84811015620012bc5780516001600160401b03808211156200145257600080fd5b908801906040601f19838c0381018213156200146d57600080fd5b62001477620010bf565b62001484898601620013ac565b815282850151848111156200149857600080fd5b8086019550508c603f860112620014ae57600080fd5b888501519350620014c36200126c8562001221565b84815260e09094028501830193898101908e861115620014e257600080fd5b958401955b85871015620015bb57868f0360e08112156200150257600080fd5b6200150c620010bf565b620015178962001168565b815260c086830112156200152a57600080fd5b62001534620010ea565b9150620015438d8a0162001185565b825262001552878a0162001185565b8d8301526200156460608a01620013c4565b878301526200157660808a0162001185565b60608301526200158960a08a0162001185565b60808301526200159c60c08a01620013d7565b60a0830152808d0191909152825260e09690960195908a0190620014e7565b828b01525087525050509284019250830162001431565b600082601f830112620015e457600080fd5b81516020620015f76200126c8362001221565b82815260069290921b840181019181810190868411156200161757600080fd5b8286015b84811015620012bc5760408189031215620016365760008081fd5b62001640620010bf565b6200164b8262001168565b81526200165a858301620013ac565b818601528352918301916040016200161b565b80516001600160e01b0319811681146200118057600080fd5b600082601f8301126200169857600080fd5b81516020620016ab6200126c8362001221565b8281526102409283028501820192828201919087851115620016cc57600080fd5b8387015b858110156200139f5780890382811215620016eb5760008081fd5b620016f5620010bf565b6200170083620013ac565b815261022080601f1984011215620017185760008081fd5b620017226200110f565b925062001731888501620013d7565b8352604062001742818601620013c4565b8985015260606200175581870162001185565b82860152608091506200176a82870162001185565b9085015260a06200177d86820162001185565b8286015260c0915062001792828701620013c4565b9085015260e0620017a586820162001185565b828601526101009150620017bb828701620013c4565b90850152610120620017cf868201620013c4565b828601526101409150620017e5828701620013c4565b90850152610160620017f986820162001185565b8286015261018091506200180f82870162001185565b908501526101a06200182386820162001185565b828601526101c0915062001839828701620013ac565b908501526101e06200184d86820162001185565b82860152610200915062001863828701620013d7565b90850152620018748583016200166d565b9084015250808701919091528452928401928101620016d0565b6000806000806000806000610120888a031215620018ab57600080fd5b620018b789896200119a565b60608901519097506001600160401b0380821115620018d557600080fd5b620018e38b838c0162001247565b975060808a0151915080821115620018fa57600080fd5b620019088b838c0162001247565b965060a08a01519150808211156200191f57600080fd5b6200192d8b838c01620012c7565b955060c08a01519150808211156200194457600080fd5b620019528b838c01620013e8565b945060e08a01519150808211156200196957600080fd5b620019778b838c01620015d2565b93506101008a01519150808211156200198f57600080fd5b506200199e8a828b0162001686565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b81511515815261022081016020830151620019e4602084018261ffff169052565b506040830151620019fd604084018263ffffffff169052565b50606083015162001a16606084018263ffffffff169052565b50608083015162001a2f608084018263ffffffff169052565b5060a083015162001a4660a084018261ffff169052565b5060c083015162001a5f60c084018263ffffffff169052565b5060e083015162001a7660e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a0808501516001600160401b0316908401526101c080850151909116908301526101e080840151151590830152610200928301516001600160e01b031916929091019190915290565b8181038181111562000ebe57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051615a2962001ba6600039600081816102ef01528181612035015261209e0152600081816102b3015281816115b0015261161001526000818161027f0152818161163901526116a90152615a296000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c80637afac32211610104578063c4276bfc116100a2578063d8694ccd11610071578063d8694ccd14610a98578063f2fde38b14610aab578063f700042a14610abe578063ffdb4b3714610ad157600080fd5b8063c4276bfc14610a48578063cc88924c14610a6a578063cdc73d5114610a7d578063d02641a014610a8557600080fd5b80638da5cb5b116100de5780638da5cb5b1461094d57806391a2749a14610975578063a69c64c014610988578063bf78e03f1461099b57600080fd5b80637afac322146107b7578063805f2132146107ca57806382b49eb0146107dd57600080fd5b806341ed29e711610171578063514e8cff1161014b578063514e8cff146104615780636def4ce714610504578063770e2dc41461079c57806379ba5097146107af57600080fd5b806341ed29e7146103ee57806345ac924d146104015780634ab35b0b1461042157600080fd5b8063181f5a77116101ad578063181f5a77146103685780632451a627146103b15780633937306f146103c6578063407e1086146103db57600080fd5b806241e5be146101d3578063061877e3146101f957806306285c6914610252575b600080fd5b6101e66101e1366004614142565b610b19565b6040519081526020015b60405180910390f35b61023961020736600461417e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101f0565b61031c604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101f0565b6103a46040518060400160405280601781526020017f5072696365526567697374727920312e362e302d64657600000000000000000081525081565b6040516101f091906141fd565b6103b9610b87565b6040516101f09190614210565b6103d96103d436600461426a565b610b98565b005b6103d96103e936600461440c565b610e4d565b6103d96103fc36600461453e565b610e61565b61041461040f3660046146be565b610ea3565b6040516101f09190614700565b61043461042f36600461417e565b610f6e565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6104f761046f366004614793565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101f091906147ae565b61078f610512366004614793565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081018290526102008101919091525067ffffffffffffffff908116600090815260096020908152604091829020825161022081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a0850152710100000000000000000000000000000000008304871660c08501527501000000000000000000000000000000000000000000808404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b010000000000000000000000000000000000000000000000000000009092048616610140840152600190930154808616610160840152640100000000810486166101808401526801000000000000000081049096166101a083015270010000000000000000000000000000000086049094166101c082015274010000000000000000000000000000000000000000850490911615156101e08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b1661020082015290565b6040516101f091906147e9565b6103d96107aa366004614a0d565b610f79565b6103d9610f8b565b6103d96107c5366004614d27565b61108d565b6103d96107d8366004614dcd565b61109f565b6108ed6107eb366004614e39565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff919091166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101f09190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6103d9610983366004614e63565b611587565b6103d9610996366004614ef4565b611598565b610a146109a936600461417e565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526007825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101f0565b610a5b610a56366004614fb9565b6115a9565b6040516101f093929190615028565b6103d9610a78366004615049565b6117a7565b6103b961197d565b6104f7610a9336600461417e565b611989565b6101e6610aa63660046150f7565b611a85565b6103d9610ab936600461417e565b611f3f565b6103d9610acc36600461517c565b611f50565b610ae4610adf36600461539c565b611f61565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101f0565b6000610b24826120ec565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b4b856120ec565b610b73907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16856153f5565b610b7d919061540c565b90505b9392505050565b6060610b936002612186565b905090565b610ba0612193565b6000610bac8280615447565b9050905060005b81811015610cf6576000610bc78480615447565b83818110610bd757610bd76154af565b905060400201803603810190610bed919061550a565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600690975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a92610ce59290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610bb3565b506000610d066020840184615447565b9050905060005b81811015610e47576000610d246020860186615447565b83818110610d3457610d346154af565b905060400201803603810190610d4a9190615547565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e92610e369290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610d0d565b50505050565b610e556121d8565b610e5e81612259565b50565b610e696121d8565b60005b8151811015610e9f57610e97828281518110610e8a57610e8a6154af565b6020026020010151612357565b600101610e6c565b5050565b60608160008167ffffffffffffffff811115610ec157610ec16142a5565b604051908082528060200260200182016040528015610f0657816020015b6040805180820190915260008082526020820152815260200190600190039081610edf5790505b50905060005b82811015610f6357610f3e868683818110610f2957610f296154af565b9050602002016020810190610a93919061417e565b828281518110610f5057610f506154af565b6020908102919091010152600101610f0c565b509150505b92915050565b6000610f68826120ec565b610f816121d8565b610e9f8282612529565b60015473ffffffffffffffffffffffffffffffffffffffff163314611011576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6110956121d8565b610e9f828261293b565b60008060006110e387878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a8292505050565b9250925092506110f533838584612a9d565b60006111038587018761556a565b905060005b815181101561157c57600060076000848481518110611129576111296154af565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160009081205474010000000000000000000000000000000000000000900460ff1691508190036111ea57828281518110611193576111936154af565b6020908102919091010151516040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401611008565b6000611233601283868681518110611204576112046154af565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612bf5565b90506006600085858151811061124b5761124b6154af565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff168484815181106112bd576112bd6154af565b60200260200101516040015163ffffffff1610156113c7578383815181106112e7576112e76154af565b602002602001015160000151848481518110611305576113056154af565b60200260200101516040015160066000878781518110611327576113276154af565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260409081016000205490517f191ec70600000000000000000000000000000000000000000000000000000000815293909116600484015263ffffffff91821660248401527c01000000000000000000000000000000000000000000000000000000009004166044820152606401611008565b6040518060400160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152602001858581518110611408576114086154af565b60200260200101516040015163ffffffff1681525060066000868681518110611433576114336154af565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117905583518490849081106114cb576114cb6154af565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff167f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a82868681518110611521576115216154af565b60200260200101516040015160405161156a9291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a25050600101611108565b505050505050505050565b61158f6121d8565b610e5e81612cbb565b6115a06121d8565b610e5e81612e47565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff160361160957859250611637565b61163487877f0000000000000000000000000000000000000000000000000000000000000000610b19565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff168311156116d6576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401611008565b67ffffffffffffffff8816600090815260096020526040812060010154640100000000900463ffffffff169061170d878784612f31565b9050806020015193508484611794836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b67ffffffffffffffff85166000908152600960205260408120600101547501000000000000000000000000000000000000000000900460e01b905b848110156119745760008484838181106117fe576117fe6154af565b611814926020604090920201908101915061417e565b9050600087878481811061182a5761182a6154af565b905060200281019061183c9190615631565b61184a90604081019061566f565b91505060208111156118fa5767ffffffffffffffff89166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff168111156118fa576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401611008565b61196a84898986818110611910576119106154af565b90506020028101906119229190615631565b61193090602081019061566f565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506130da92505050565b50506001016117e2565b50505050505050565b6060610b93600b612186565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600760209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff169082015290611a7c57505073ffffffffffffffffffffffffffffffffffffffff166000908152600660209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b808161312c565b67ffffffffffffffff8083166000908152600960209081526040808320815161022081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a0860152710100000000000000000000000000000000008404871660c08601527501000000000000000000000000000000000000000000808504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b010000000000000000000000000000000000000000000000000000009093048616610140850152600190940154808616610160850152640100000000810486166101808501526801000000000000000081049098166101a084015270010000000000000000000000000000000088049094166101c083015274010000000000000000000000000000000000000000870490931615156101e08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b16610200840152909190611cbb576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401611008565b6000611cca6040850185615447565b9150611d26905082611cdf602087018761566f565b905083611cec888061566f565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506132bb92505050565b6000600881611d3b608088016060890161417e565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff16915080611d8a611d846080890160608a0161417e565b89611f61565b9092509050600080808615611dd057611dc4888c611dae60808e0160608f0161417e565b888e8060400190611dbf9190615447565b613365565b91945092509050611df0565b6101c0880151611ded9063ffffffff16662386f26fc100006153f5565b92505b61010088015160009061ffff1615611e3457611e31896dffffffffffffffffffffffffffff607088901c16611e2860208f018f61566f565b90508b86613643565b90505b6101a089015160009067ffffffffffffffff16611e5d611e5760808f018f61566f565b8d6136f3565b600001518563ffffffff168c60a0015161ffff168f8060200190611e81919061566f565b611e8c9291506153f5565b8d6080015163ffffffff16611ea191906156d4565b611eab91906156d4565b611eb591906156d4565b611ecf906dffffffffffffffffffffffffffff89166153f5565b611ed991906153f5565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff87168282611f1067ffffffffffffffff8c16896153f5565b611f1a91906156d4565b611f2491906156d4565b611f2e919061540c565b9d9c50505050505050505050505050565b611f476121d8565b610e5e816137b4565b611f586121d8565b610e5e816138a9565b67ffffffffffffffff811660009081526005602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203612019576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401611008565b6000816020015163ffffffff164261203191906156e7565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168111156120d2576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401611008565b6120db866120ec565b9151919350909150505b9250929050565b6000806120f883611989565b9050806020015163ffffffff1660001480612130575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b1561217f576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401611008565b5192915050565b60606000610b8083613d97565b61219e600233613df3565b6121d6576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401611008565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146121d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611008565b60005b8151811015610e9f576000828281518110612279576122796154af565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526007875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a250505080600101905061225c565b600061241082600001518360600151846020015185604001516040805173ffffffffffffffffffffffffffffffffffffffff80871660208301528516918101919091527fffffffffffffffffffff00000000000000000000000000000000000000000000831660608201527fffff0000000000000000000000000000000000000000000000000000000000008216608082015260009060a001604051602081830303815290604052805190602001209050949350505050565b60808301516000828152600460205260409081902080549215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316929092179091555190915081907f32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a39061251d908590600060a08201905073ffffffffffffffffffffffffffffffffffffffff8084511683527fffffffffffffffffffff0000000000000000000000000000000000000000000060208501511660208401527fffff00000000000000000000000000000000000000000000000000000000000060408501511660408401528060608501511660608401525060808301511515608083015292915050565b60405180910390a25050565b60005b8251811015612852576000838281518110612549576125496154af565b6020026020010151905060008160000151905060005b82602001515181101561284457600083602001518281518110612584576125846154af565b60200260200101516020015190506000846020015183815181106125aa576125aa6154af565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101561262d5760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401611008565b67ffffffffffffffff84166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b590612832908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010161255f565b50505080600101905061252c565b5060005b8151811015612936576000828281518110612873576128736154af565b60200260200101516000015190506000838381518110612895576128956154af565b60209081029190910181015181015167ffffffffffffffff84166000818152600a8452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612856565b505050565b60005b82518110156129de5761297483828151811061295c5761295c6154af565b6020026020010151600b613e2290919063ffffffff16565b156129d65782818151811061298b5761298b6154af565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010161293e565b5060005b815181101561293657612a18828281518110612a0057612a006154af565b6020026020010151600b613e4490919063ffffffff16565b15612a7a57818181518110612a2f57612a2f6154af565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6001016129e2565b6040810151604a820151605e90920151909260609290921c91565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602080840191909152908616828401527fffffffffffffffffffff00000000000000000000000000000000000000000000851660608301527fffff00000000000000000000000000000000000000000000000000000000000084166080808401919091528351808403909101815260a09092018352815191810191909120600081815260049092529190205460ff16612bee576040517f097e17ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8087166004830152851660248201527fffffffffffffffffffff00000000000000000000000000000000000000000000841660448201527fffff00000000000000000000000000000000000000000000000000000000000083166064820152608401611008565b5050505050565b600080612c0284866156fa565b9050600060248260ff161115612c3957612c1d602483615713565b612c2890600a61584c565b612c32908561540c565b9050612c5c565b612c44826024615713565b612c4f90600a61584c565b612c5990856153f5565b90505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612cb2576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b95945050505050565b602081015160005b8151811015612d56576000828281518110612ce057612ce06154af565b60200260200101519050612cfe816002613e6690919063ffffffff16565b15612d4d5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612cc3565b50815160005b8151811015610e47576000828281518110612d7957612d796154af565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612de9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612df4600282613e22565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101612d5c565b60005b8151811015610e9f576000828281518110612e6757612e676154af565b60200260200101516000015190506000838381518110612e8957612e896154af565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526008845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a25050600101612e4a565b60408051808201909152600080825260208201526000839003612f7257506040805180820190915267ffffffffffffffff8216815260006020820152610b80565b6000612f7e848661585b565b90506000612f8f85600481896158a1565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f0000000000000000000000000000000000000000000000000000000000161302c578080602001905181019061302391906158cb565b92505050610b80565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016130a85760405180604001604052808280602001905181019061309491906158f7565b815260006020909101529250610b80915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610e9f5761293681613e88565b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613196573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131ba919061592a565b50505091505060008112156131fb576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061327a8373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561324b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061326f919061597a565b866020015184612bf5565b604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff4216602082015295945050505050565b836040015163ffffffff168311156133145760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401611008565b836020015161ffff16821115613356576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e47846102000151826130da565b6000808083815b81811015613635576000878783818110613388576133886154af565b90506040020180360381019061339e9190615997565b67ffffffffffffffff8c166000908152600a60209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a08201819052919250906134c4576101208d015161348b9061ffff16662386f26fc100006153f5565b61349590886156d4565b96508c6101400151866134a891906159d0565b95508c6101600151856134bb91906159d0565b9450505061362d565b604081015160009061ffff161561357d5760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614613520578351613519906120ec565b9050613523565b508a5b620186a0836040015161ffff166135658660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16613f3b90919063ffffffff16565b61356f91906153f5565b613579919061540c565b9150505b606082015161358c90886159d0565b965081608001518661359e91906159d0565b82519096506000906135bd9063ffffffff16662386f26fc100006153f5565b9050808210156135dc576135d1818a6156d4565b98505050505061362d565b6000836020015163ffffffff16662386f26fc100006135fb91906153f5565b90508083111561361b5761360f818b6156d4565b9950505050505061362d565b613625838b6156d4565b995050505050505b60010161336c565b505096509650969350505050565b60008063ffffffff8316613659610140866153f5565b613665876101c06156d4565b61366f91906156d4565b61367991906156d4565b905060008760c0015163ffffffff168860e0015161ffff168361369c91906153f5565b6136a691906156d4565b61010089015190915061ffff166136cd6dffffffffffffffffffffffffffff8916836153f5565b6136d791906153f5565b6136e790655af3107a40006153f5565b98975050505050505050565b6040805180820190915260008082526020820152600061371f858585610180015163ffffffff16612f31565b9050826060015163ffffffff1681600001511115613769576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101e00151801561377d57508060200151155b15610b7d576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603613833576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611008565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b8151811015610e9f5760008282815181106138c9576138c96154af565b6020026020010151905060008383815181106138e7576138e76154af565b60200260200101516000015190506000826020015190508167ffffffffffffffff1660001480613920575061018081015163ffffffff16155b8061397257506102008101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b8061398e5750602063ffffffff1681610160015163ffffffff16105b806139ad5750806060015163ffffffff1681610180015163ffffffff16115b156139f0576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401611008565b67ffffffffffffffff82166000908152600960205260408120600101547501000000000000000000000000000000000000000000900460e01b7fffffffff00000000000000000000000000000000000000000000000000000000169003613a98578167ffffffffffffffff167fa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d1357782604051613a8b91906147e9565b60405180910390a2613adb565b8167ffffffffffffffff167fa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad9382604051613ad291906147e9565b60405180910390a25b80600960008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055506101a08201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101c08201518160010160106101000a81548163ffffffff021916908363ffffffff1602179055506101e08201518160010160146101000a81548160ff0219169083151502179055506102008201518160010160156101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506138ac565b606081600001805480602002602001604051908101604052809291908181526020018280548015613de757602002820191906000526020600020905b815481526020019060010190808311613dd3575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b80565b6000610b808373ffffffffffffffffffffffffffffffffffffffff8416613f78565b6000610b808373ffffffffffffffffffffffffffffffffffffffff8416613fc7565b6000610b808373ffffffffffffffffffffffffffffffffffffffff84166140c1565b60008151602014613ec757816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161100891906141fd565b600082806020019051810190613edd91906158f7565b905073ffffffffffffffffffffffffffffffffffffffff811180613f02575061040081105b15610f6857826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161100891906141fd565b6000670de0b6b3a7640000613f6e837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166153f5565b610b80919061540c565b6000818152600183016020526040812054613fbf57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610f68565b506000610f68565b600081815260018301602052604081205480156140b0576000613feb6001836156e7565b8554909150600090613fff906001906156e7565b905080821461406457600086600001828154811061401f5761401f6154af565b9060005260206000200154905080876000018481548110614042576140426154af565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614075576140756159ed565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610f68565b6000915050610f68565b5092915050565b600081815260018301602052604081205480156140b05760006140e56001836156e7565b85549091506000906140f9906001906156e7565b905081811461406457600086600001828154811061401f5761401f6154af565b803573ffffffffffffffffffffffffffffffffffffffff8116811461413d57600080fd5b919050565b60008060006060848603121561415757600080fd5b61416084614119565b92506020840135915061417560408501614119565b90509250925092565b60006020828403121561419057600080fd5b610b8082614119565b6000815180845260005b818110156141bf576020818501810151868301820152016141a3565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b806020830184614199565b6020808252825182820181905260009190848201906040850190845b8181101561425e57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161422c565b50909695505050505050565b60006020828403121561427c57600080fd5b813567ffffffffffffffff81111561429357600080fd5b820160408185031215610b8057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156142f7576142f76142a5565b60405290565b60405160a0810167ffffffffffffffff811182821017156142f7576142f76142a5565b60405160c0810167ffffffffffffffff811182821017156142f7576142f76142a5565b604051610220810167ffffffffffffffff811182821017156142f7576142f76142a5565b6040516060810167ffffffffffffffff811182821017156142f7576142f76142a5565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156143d1576143d16142a5565b604052919050565b600067ffffffffffffffff8211156143f3576143f36142a5565b5060051b60200190565b60ff81168114610e5e57600080fd5b6000602080838503121561441f57600080fd5b823567ffffffffffffffff81111561443657600080fd5b8301601f8101851361444757600080fd5b803561445a614455826143d9565b61438a565b8181526060918202830184019184820191908884111561447957600080fd5b938501935b8385101561451957848903818112156144975760008081fd5b61449f6142d4565b6144a887614119565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156144dc5760008081fd5b6144e46142d4565b92506144f1898901614119565b83528701356144ff816143fd565b82890152808801919091528352938401939185019161447e565b50979650505050505050565b8015158114610e5e57600080fd5b803561413d81614525565b6000602080838503121561455157600080fd5b823567ffffffffffffffff81111561456857600080fd5b8301601f8101851361457957600080fd5b8035614587614455826143d9565b81815260a091820283018401918482019190888411156145a657600080fd5b938501935b838510156145195780858a0312156145c35760008081fd5b6145cb6142fd565b6145d486614119565b8152868601357fffffffffffffffffffff00000000000000000000000000000000000000000000811681146146095760008081fd5b818801526040868101357fffff000000000000000000000000000000000000000000000000000000000000811681146146425760008081fd5b908201526060614653878201614119565b9082015260808681013561466681614525565b90820152835293840193918501916145ab565b60008083601f84011261468b57600080fd5b50813567ffffffffffffffff8111156146a357600080fd5b6020830191508360208260051b85010111156120e557600080fd5b600080602083850312156146d157600080fd5b823567ffffffffffffffff8111156146e857600080fd5b6146f485828601614679565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b8281101561476e5761475e84835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b928401929085019060010161471d565b5091979650505050505050565b803567ffffffffffffffff8116811461413d57600080fd5b6000602082840312156147a557600080fd5b610b808261477b565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff169082015260408101610f68565b81511515815261022081016020830151614809602084018261ffff169052565b506040830151614821604084018263ffffffff169052565b506060830151614839606084018263ffffffff169052565b506080830151614851608084018263ffffffff169052565b5060a083015161486760a084018261ffff169052565b5060c083015161487f60c084018263ffffffff169052565b5060e083015161489560e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501518216908401526101a08085015167ffffffffffffffff16908401526101c080850151909116908301526101e080840151151590830152610200808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461413d57600080fd5b803561ffff8116811461413d57600080fd5b600082601f83011261498657600080fd5b81356020614996614455836143d9565b82815260069290921b840181019181810190868411156149b557600080fd5b8286015b84811015614a0257604081890312156149d25760008081fd5b6149da6142d4565b6149e38261477b565b81526149f0858301614119565b818601528352918301916040016149b9565b509695505050505050565b60008060408385031215614a2057600080fd5b67ffffffffffffffff83351115614a3657600080fd5b83601f843585010112614a4857600080fd5b614a5861445584358501356143d9565b8335840180358083526020808401939260059290921b90910101861015614a7e57600080fd5b602085358601015b85358601803560051b01602001811015614c8b5767ffffffffffffffff81351115614ab057600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a03011215614ae957600080fd5b614af16142d4565b614afd6020830161477b565b815267ffffffffffffffff60408301351115614b1857600080fd5b88603f604084013584010112614b2d57600080fd5b614b4361445560206040850135850101356143d9565b6020604084810135850182810135808552928401939260e00201018b1015614b6a57600080fd5b6040808501358501015b6040858101358601602081013560e0020101811015614c6c5760e0818d031215614b9d57600080fd5b614ba56142d4565b614bae82614119565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215614be257600080fd5b614bea614320565b614bf66020840161494f565b8152614c046040840161494f565b6020820152614c1560608401614963565b6040820152614c266080840161494f565b6060820152614c3760a0840161494f565b6080820152614c4960c0840135614525565b60c083013560a0820152602082810191909152908452929092019160e001614b74565b5080602084015250508085525050602083019250602081019050614a86565b5092505067ffffffffffffffff60208401351115614ca857600080fd5b614cb88460208501358501614975565b90509250929050565b600082601f830112614cd257600080fd5b81356020614ce2614455836143d9565b8083825260208201915060208460051b870101935086841115614d0457600080fd5b602086015b84811015614a0257614d1a81614119565b8352918301918301614d09565b60008060408385031215614d3a57600080fd5b823567ffffffffffffffff80821115614d5257600080fd5b614d5e86838701614cc1565b93506020850135915080821115614d7457600080fd5b50614d8185828601614cc1565b9150509250929050565b60008083601f840112614d9d57600080fd5b50813567ffffffffffffffff811115614db557600080fd5b6020830191508360208285010111156120e557600080fd5b60008060008060408587031215614de357600080fd5b843567ffffffffffffffff80821115614dfb57600080fd5b614e0788838901614d8b565b90965094506020870135915080821115614e2057600080fd5b50614e2d87828801614d8b565b95989497509550505050565b60008060408385031215614e4c57600080fd5b614e558361477b565b9150614cb860208401614119565b600060208284031215614e7557600080fd5b813567ffffffffffffffff80821115614e8d57600080fd5b9083019060408286031215614ea157600080fd5b614ea96142d4565b823582811115614eb857600080fd5b614ec487828601614cc1565b825250602083013582811115614ed957600080fd5b614ee587828601614cc1565b60208301525095945050505050565b60006020808385031215614f0757600080fd5b823567ffffffffffffffff811115614f1e57600080fd5b8301601f81018513614f2f57600080fd5b8035614f3d614455826143d9565b81815260069190911b82018301908381019087831115614f5c57600080fd5b928401925b82841015614fae5760408489031215614f7a5760008081fd5b614f826142d4565b614f8b85614119565b8152614f9886860161477b565b8187015282526040939093019290840190614f61565b979650505050505050565b600080600080600060808688031215614fd157600080fd5b614fda8661477b565b9450614fe860208701614119565b935060408601359250606086013567ffffffffffffffff81111561500b57600080fd5b61501788828901614d8b565b969995985093965092949392505050565b8381528215156020820152606060408201526000612cb26060830184614199565b60008060008060006060868803121561506157600080fd5b61506a8661477b565b9450602086013567ffffffffffffffff8082111561508757600080fd5b61509389838a01614679565b909650945060408801359150808211156150ac57600080fd5b818801915088601f8301126150c057600080fd5b8135818111156150cf57600080fd5b8960208260061b85010111156150e457600080fd5b9699959850939650602001949392505050565b6000806040838503121561510a57600080fd5b6151138361477b565b9150602083013567ffffffffffffffff81111561512f57600080fd5b830160a0818603121561514157600080fd5b809150509250929050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461413d57600080fd5b6000602080838503121561518f57600080fd5b823567ffffffffffffffff8111156151a657600080fd5b8301601f810185136151b757600080fd5b80356151c5614455826143d9565b81815261024091820283018401918482019190888411156151e557600080fd5b938501935b8385101561451957848903818112156152035760008081fd5b61520b6142d4565b6152148761477b565b8152610220807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156152495760008081fd5b615251614343565b925061525e898901614533565b8352604061526d818a01614963565b8a850152606061527e818b0161494f565b8286015260809150615291828b0161494f565b9085015260a06152a28a820161494f565b8286015260c091506152b5828b01614963565b9085015260e06152c68a820161494f565b8286015261010091506152da828b01614963565b908501526101206152ec8a8201614963565b828601526101409150615300828b01614963565b908501526101606153128a820161494f565b828601526101809150615326828b0161494f565b908501526101a06153388a820161494f565b828601526101c0915061534c828b0161477b565b908501526101e061535e8a820161494f565b828601526102009150615372828b01614533565b9085015261538189830161514c565b908401525080880191909152835293840193918501916151ea565b600080604083850312156153af57600080fd5b6153b883614119565b9150614cb86020840161477b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610f6857610f686153c6565b600082615442577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261547c57600080fd5b83018035915067ffffffffffffffff82111561549757600080fd5b6020019150600681901b36038213156120e557600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461413d57600080fd5b60006040828403121561551c57600080fd5b6155246142d4565b61552d83614119565b815261553b602084016154de565b60208201529392505050565b60006040828403121561555957600080fd5b6155616142d4565b61552d8361477b565b6000602080838503121561557d57600080fd5b823567ffffffffffffffff81111561559457600080fd5b8301601f810185136155a557600080fd5b80356155b3614455826143d9565b818152606091820283018401918482019190888411156155d257600080fd5b938501935b838510156145195780858a0312156155ef5760008081fd5b6155f7614367565b61560086614119565b815261560d8787016154de565b87820152604061561e81880161494f565b90820152835293840193918501916155d7565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183360301811261566557600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126156a457600080fd5b83018035915067ffffffffffffffff8211156156bf57600080fd5b6020019150368190038213156120e557600080fd5b80820180821115610f6857610f686153c6565b81810381811115610f6857610f686153c6565b60ff8181168382160190811115610f6857610f686153c6565b60ff8281168282160390811115610f6857610f686153c6565b600181815b8085111561578557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561576b5761576b6153c6565b8085161561577857918102915b93841c9390800290615731565b509250929050565b60008261579c57506001610f68565b816157a957506000610f68565b81600181146157bf57600281146157c9576157e5565b6001915050610f68565b60ff8411156157da576157da6153c6565b50506001821b610f68565b5060208310610133831016604e8410600b8410161715615808575081810a610f68565b615812838361572c565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615844576158446153c6565b029392505050565b6000610b8060ff84168361578d565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156149475760049490940360031b84901b1690921692915050565b600080858511156158b157600080fd5b838611156158be57600080fd5b5050820193919092039150565b6000604082840312156158dd57600080fd5b6158e56142d4565b82518152602083015161553b81614525565b60006020828403121561590957600080fd5b5051919050565b805169ffffffffffffffffffff8116811461413d57600080fd5b600080600080600060a0868803121561594257600080fd5b61594b86615910565b945060208601519350604086015192506060860151915061596e60808701615910565b90509295509295909350565b60006020828403121561598c57600080fd5b8151610b80816143fd565b6000604082840312156159a957600080fd5b6159b16142d4565b6159ba83614119565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156140ba576140ba6153c6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"}],\"name\":\"ReportForwarderUnauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feedTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"storedTimeStamp\",\"type\":\"uint256\"}],\"name\":\"StaleKeystoneUpdate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"reportId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission\",\"name\":\"permission\",\"type\":\"tuple\"}],\"name\":\"ReportPermissionSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"processPoolReturnData\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"destExecDataPerToken\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission[]\",\"name\":\"permissions\",\"type\":\"tuple[]\"}],\"name\":\"setReportPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b50604051620076d8380380620076d8833981016040819052620000349162001834565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a5a565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b26565b5050505050505062001ae5565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001953565b60209081029190910101519050620002f560028262000e5f565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001953565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000e7f565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001953565b6020026020010151600b62000e7f60201b90919060201c565b1562000499578281815181106200045b576200045b62001953565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001953565b6020026020010151600b62000e9660201b90919060201c565b156200053b57818181518110620004fd57620004fd62001953565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001953565b6020908102919091018101518051818301516001600160a01b0380831660008181526007875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001953565b6020026020010151905060008383815181106200065f576200065f62001953565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061016081015163ffffffff16155b80620006ba57506101e08101516001600160e01b031916630a04b54b60e21b14155b80620006da5750806060015163ffffffff1681610160015163ffffffff16115b15620007055760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260096020526040812060010154600160881b900460e01b6001600160e01b03191690036200078557816001600160401b03167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb7248260405162000777919062001969565b60405180910390a2620007c9565b816001600160401b03167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab2082604051620007c0919062001969565b60405180910390a25b8060096000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a8154816001600160401b0302191690836001600160401b031602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000a7e5762000a7e62001953565b6020026020010151600001519050600083838151811062000aa35762000aa362001953565b6020908102919091018101518101516001600160a01b03841660008181526008845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a5d565b60005b825181101562000d9957600083828151811062000b4a5762000b4a62001953565b6020026020010151905060008160000151905060005b82602001515181101562000d8a5760008360200151828151811062000b895762000b8962001953565b602002602001015160200151905060008460200151838151811062000bb25762000bb262001953565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c115760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000d77908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000b60565b50505080600101905062000b29565b5060005b81518110156200054457600082828151811062000dbe5762000dbe62001953565b6020026020010151600001519050600083838151811062000de35762000de362001953565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000d9d565b600062000e76836001600160a01b03841662000ead565b90505b92915050565b600062000e76836001600160a01b03841662000fb1565b600062000e76836001600160a01b03841662001003565b6000818152600183016020526040812054801562000fa657600062000ed460018362001aad565b855490915060009062000eea9060019062001aad565b905081811462000f5657600086600001828154811062000f0e5762000f0e62001953565b906000526020600020015490508087600001848154811062000f345762000f3462001953565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f6a5762000f6a62001acf565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e79565b600091505062000e79565b600081815260018301602052604081205462000ffa5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e79565b50600062000e79565b6000818152600183016020526040812054801562000fa65760006200102a60018362001aad565b8554909150600090620010409060019062001aad565b905080821462000f5657600086600001828154811062000f0e5762000f0e62001953565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200109f576200109f62001064565b60405290565b60405160c081016001600160401b03811182821017156200109f576200109f62001064565b60405161020081016001600160401b03811182821017156200109f576200109f62001064565b604051601f8201601f191681016001600160401b03811182821017156200111b576200111b62001064565b604052919050565b80516001600160a01b03811681146200113b57600080fd5b919050565b805163ffffffff811681146200113b57600080fd5b6000606082840312156200116857600080fd5b604051606081016001600160401b03811182821017156200118d576200118d62001064565b604052825190915081906001600160601b0381168114620011ad57600080fd5b8152620011bd6020840162001123565b6020820152620011d06040840162001140565b60408201525092915050565b60006001600160401b03821115620011f857620011f862001064565b5060051b60200190565b600082601f8301126200121457600080fd5b815160206200122d6200122783620011dc565b620010f0565b8083825260208201915060208460051b8701019350868411156200125057600080fd5b602086015b848110156200127757620012698162001123565b835291830191830162001255565b509695505050505050565b600082601f8301126200129457600080fd5b81516020620012a76200122783620011dc565b82815260609283028501820192828201919087851115620012c757600080fd5b8387015b858110156200135a5780890382811215620012e65760008081fd5b620012f06200107a565b620012fb8362001123565b8152604080601f1984011215620013125760008081fd5b6200131c6200107a565b92506200132b88850162001123565b835283015160ff81168114620013415760008081fd5b82880152808701919091528452928401928101620012cb565b5090979650505050505050565b80516001600160401b03811681146200113b57600080fd5b805161ffff811681146200113b57600080fd5b805180151581146200113b57600080fd5b600082601f830112620013b557600080fd5b81516020620013c86200122783620011dc565b82815260059290921b84018101918181019086841115620013e857600080fd5b8286015b84811015620012775780516001600160401b03808211156200140d57600080fd5b908801906040601f19838c0381018213156200142857600080fd5b620014326200107a565b6200143f89860162001367565b815282850151848111156200145357600080fd5b8086019550508c603f8601126200146957600080fd5b8885015193506200147e6200122785620011dc565b84815260e09094028501830193898101908e8611156200149d57600080fd5b958401955b858710156200157657868f0360e0811215620014bd57600080fd5b620014c76200107a565b620014d28962001123565b815260c08683011215620014e557600080fd5b620014ef620010a5565b9150620014fe8d8a0162001140565b82526200150d878a0162001140565b8d8301526200151f60608a016200137f565b878301526200153160808a0162001140565b60608301526200154460a08a0162001140565b60808301526200155760c08a0162001392565b60a0830152808d0191909152825260e09690960195908a0190620014a2565b828b015250875250505092840192508301620013ec565b600082601f8301126200159f57600080fd5b81516020620015b26200122783620011dc565b82815260069290921b84018101918181019086841115620015d257600080fd5b8286015b84811015620012775760408189031215620015f15760008081fd5b620015fb6200107a565b620016068262001123565b81526200161585830162001367565b81860152835291830191604001620015d6565b80516001600160e01b0319811681146200113b57600080fd5b600082601f8301126200165357600080fd5b81516020620016666200122783620011dc565b82815261022092830285018201928282019190878511156200168757600080fd5b8387015b858110156200135a5780890382811215620016a65760008081fd5b620016b06200107a565b620016bb8362001367565b815261020080601f1984011215620016d35760008081fd5b620016dd620010ca565b9250620016ec88850162001392565b83526040620016fd8186016200137f565b8985015260606200171081870162001140565b82860152608091506200172582870162001140565b9085015260a06200173886820162001140565b8286015260c091506200174d8287016200137f565b9085015260e06200176086820162001140565b828601526101009150620017768287016200137f565b908501526101206200178a8682016200137f565b828601526101409150620017a08287016200137f565b90850152610160620017b486820162001140565b828601526101809150620017ca82870162001140565b908501526101a0620017de86820162001367565b828601526101c09150620017f482870162001140565b908501526101e06200180886820162001392565b828601526200181983870162001628565b9085015250508087019190915284529284019281016200168b565b6000806000806000806000610120888a0312156200185157600080fd5b6200185d898962001155565b60608901519097506001600160401b03808211156200187b57600080fd5b620018898b838c0162001202565b975060808a0151915080821115620018a057600080fd5b620018ae8b838c0162001202565b965060a08a0151915080821115620018c557600080fd5b620018d38b838c0162001282565b955060c08a0151915080821115620018ea57600080fd5b620018f88b838c01620013a3565b945060e08a01519150808211156200190f57600080fd5b6200191d8b838c016200158d565b93506101008a01519150808211156200193557600080fd5b50620019448a828b0162001641565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610200810160208301516200198a602084018261ffff169052565b506040830151620019a3604084018263ffffffff169052565b506060830151620019bc606084018263ffffffff169052565b506080830151620019d5608084018263ffffffff169052565b5060a0830151620019ec60a084018261ffff169052565b5060c083015162001a0560c084018263ffffffff169052565b5060e083015162001a1c60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501516001600160401b0316908401526101a080850151909116908301526101c0808401511515908301526101e0928301516001600160e01b031916929091019190915290565b8181038181111562000e7957634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051615b9962001b3f600039600081816102ef0152818161219101526121fa0152600081816102b301528181611917015261197701526000818161027f015281816119a00152611a100152615b996000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c806379ba509711610104578063a69c64c0116100a2578063d02641a011610071578063d02641a014610a81578063d8694ccd14610a94578063f2fde38b14610aa7578063ffdb4b3714610aba57600080fd5b8063a69c64c014610997578063bf78e03f146109aa578063c4276bfc14610a57578063cdc73d5114610a7957600080fd5b806382b49eb0116100de57806382b49eb0146107d95780638da5cb5b1461094957806391a2749a146109715780639ea600261461098457600080fd5b806379ba5097146107ab5780637afac322146107b3578063805f2132146107c657600080fd5b8063407e1086116101715780634ab35b0b1161014b5780634ab35b0b14610441578063514e8cff146104815780636def4ce714610524578063770e2dc41461079857600080fd5b8063407e1086146103fb57806341ed29e71461040e57806345ac924d1461042157600080fd5b8063085318f8116101ad578063085318f814610368578063181f5a77146103885780632451a627146103d15780633937306f146103e657600080fd5b806241e5be146101d3578063061877e3146101f957806306285c6914610252575b600080fd5b6101e66101e1366004614250565b610b02565b6040519081526020015b60405180910390f35b61023961020736600461428c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101f0565b61031c604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101f0565b61037b610376366004614304565b610b70565b6040516101f09190614416565b6103c46040518060400160405280601781526020017f5072696365526567697374727920312e362e302d64657600000000000000000081525081565b6040516101f09190614498565b6103d9610ee2565b6040516101f091906144ab565b6103f96103f4366004614505565b610ef3565b005b6103f96104093660046146a7565b6111a8565b6103f961041c3660046147d9565b6111bc565b61043461042f366004614914565b6111fe565b6040516101f09190614956565b61045461044f36600461428c565b6112c9565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b61051761048f3660046149d1565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101f091906149ec565b61078b6105323660046149d1565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101919091525067ffffffffffffffff908116600090815260096020908152604091829020825161020081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a085015271010000000000000000000000000000000000808404881660c086015275010000000000000000000000000000000000000000008404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b01000000000000000000000000000000000000000000000000000000909204861661014084015260019093015480861661016084015264010000000081049096166101808301526c0100000000000000000000000086049094166101a0820152700100000000000000000000000000000000850490911615156101c08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b166101e082015290565b6040516101f09190614a27565b6103f96107a6366004614c3e565b6112d4565b6103f96112e6565b6103f96107c1366004614f58565b6113e3565b6103f96107d4366004614ffe565b6113f5565b6108e96107e736600461506a565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff919091166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101f09190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6103f961097f366004615094565b6118dd565b6103f9610992366004615155565b6118ee565b6103f96109a5366004615362565b6118ff565b610a236109b836600461428c565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526007825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101f0565b610a6a610a65366004615427565b611910565b6040516101f093929190615496565b6103d9611b06565b610517610a8f36600461428c565b611b12565b6101e6610aa23660046154b7565b611c0e565b6103f9610ab536600461428c565b6120ac565b610acd610ac836600461550c565b6120bd565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101f0565b6000610b0d82612248565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b3485612248565b610b5c907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685615565565b610b66919061557c565b90505b9392505050565b67ffffffffffffffff8086166000908152600960205260409020600101546060917101000000000000000000000000000000000090910460e01b908590811115610bbc57610bbc614540565b604051908082528060200260200182016040528015610bef57816020015b6060815260200190600190039081610bda5790505b50915060005b85811015610ed7576000858583818110610c1157610c116155b7565b610c27926020604090920201908101915061428c565b90506000888884818110610c3d57610c3d6155b7565b9050602002810190610c4f91906155e6565b610c5d906040810190615624565b9150506020811115610d125767ffffffffffffffff8a166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115610d12576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b610d82848a8a86818110610d2857610d286155b7565b9050602002810190610d3a91906155e6565b610d48906020810190615624565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122e292505050565b67ffffffffffffffff8a166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320815160c081018352905463ffffffff8082168352640100000000820481168386015268010000000000000000820461ffff16838501526a01000000000000000000008204811660608401526e010000000000000000000000000000820481166080840152720100000000000000000000000000000000000090910460ff16151560a08301908152958552600990935290832054935190937b0100000000000000000000000000000000000000000000000000000090049091169190610e815781610e87565b82606001515b6040805163ffffffff8316602082015291925001604051602081830303815290604052888781518110610ebc57610ebc6155b7565b60200260200101819052505050505050806001019050610bf5565b505095945050505050565b6060610eee6002612339565b905090565b610efb612346565b6000610f078280615689565b9050905060005b81811015611051576000610f228480615689565b83818110610f3257610f326155b7565b905060400201803603810190610f48919061571d565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600690975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926110409290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610f0e565b5060006110616020840184615689565b9050905060005b818110156111a257600061107f6020860186615689565b8381811061108f5761108f6155b7565b9050604002018036038101906110a5919061575a565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e926111919290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101611068565b50505050565b6111b061238b565b6111b98161240c565b50565b6111c461238b565b60005b81518110156111fa576111f28282815181106111e5576111e56155b7565b602002602001015161250a565b6001016111c7565b5050565b60608160008167ffffffffffffffff81111561121c5761121c614540565b60405190808252806020026020018201604052801561126157816020015b604080518082019091526000808252602082015281526020019060019003908161123a5790505b50905060005b828110156112be57611299868683818110611284576112846155b7565b9050602002016020810190610a8f919061428c565b8282815181106112ab576112ab6155b7565b6020908102919091010152600101611267565b509150505b92915050565b60006112c382612248565b6112dc61238b565b6111fa82826126dc565b60015473ffffffffffffffffffffffffffffffffffffffff163314611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610d09565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6113eb61238b565b6111fa8282612ae9565b600080600061143987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c3092505050565b92509250925061144b33838584612c4b565b60006114598587018761577d565b905060005b81518110156118d25760006007600084848151811061147f5761147f6155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160009081205474010000000000000000000000000000000000000000900460ff169150819003611540578282815181106114e9576114e96155b7565b6020908102919091010151516040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b600061158960128386868151811061155a5761155a6155b7565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612da3565b9050600660008585815181106115a1576115a16155b7565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff16848481518110611613576116136155b7565b60200260200101516040015163ffffffff16101561171d5783838151811061163d5761163d6155b7565b60200260200101516000015184848151811061165b5761165b6155b7565b6020026020010151604001516006600087878151811061167d5761167d6155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260409081016000205490517f191ec70600000000000000000000000000000000000000000000000000000000815293909116600484015263ffffffff91821660248401527c01000000000000000000000000000000000000000000000000000000009004166044820152606401610d09565b6040518060400160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260200185858151811061175e5761175e6155b7565b60200260200101516040015163ffffffff1681525060066000868681518110611789576117896155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790558351849084908110611821576118216155b7565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff167f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a82868681518110611877576118776155b7565b6020026020010151604001516040516118c09291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a2505060010161145e565b505050505050505050565b6118e561238b565b6111b981612e69565b6118f661238b565b6111b981612ff5565b61190761238b565b6111b98161349b565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036119705785925061199e565b61199b87877f0000000000000000000000000000000000000000000000000000000000000000610b02565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611a3d576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610d09565b67ffffffffffffffff881660009081526009602052604081206001015463ffffffff1690611a6c878784613585565b9050806020015193508484611af3836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b6060610eee600b612339565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600760209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff169082015290611c0557505073ffffffffffffffffffffffffffffffffffffffff166000908152600660209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b698161372e565b67ffffffffffffffff8083166000908152600960209081526040808320815161020081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a086015271010000000000000000000000000000000000808504881660c087015275010000000000000000000000000000000000000000008504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b01000000000000000000000000000000000000000000000000000000909304861661014085015260019094015480861661016085015264010000000081049098166101808401526c0100000000000000000000000088049094166101a0830152700100000000000000000000000000000000870490931615156101c08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b166101e0840152909190611e28576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000611e376040850185615689565b9150611e93905082611e4c6020870187615624565b905083611e598880615624565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506138bd92505050565b6000600881611ea8608088016060890161428c565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff16915080611ef7611ef16080890160608a0161428c565b896120bd565b9092509050600080808615611f3d57611f31888c611f1b60808e0160608f0161428c565b888e8060400190611f2c9190615689565b613967565b91945092509050611f5d565b6101a0880151611f5a9063ffffffff16662386f26fc10000615565565b92505b61010088015160009061ffff1615611fa157611f9e896dffffffffffffffffffffffffffff607088901c16611f9560208f018f615624565b90508b86613c3f565b90505b61018089015160009067ffffffffffffffff16611fca611fc460808f018f615624565b8d613cef565b600001518563ffffffff168c60a0015161ffff168f8060200190611fee9190615624565b611ff9929150615565565b8d6080015163ffffffff1661200e9190615844565b6120189190615844565b6120229190615844565b61203c906dffffffffffffffffffffffffffff8916615565565b6120469190615565565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8716828261207d67ffffffffffffffff8c1689615565565b6120879190615844565b6120919190615844565b61209b919061557c565b9d9c50505050505050505050505050565b6120b461238b565b6111b981613db0565b67ffffffffffffffff811660009081526005602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203612175576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000816020015163ffffffff164261218d9190615857565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff1681111561222e576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610d09565b61223786612248565b9151919350909150505b9250929050565b60008061225483611b12565b9050806020015163ffffffff166000148061228c575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b156122db576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610d09565b5192915050565b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016111fa5761233481613ea5565b505050565b60606000610b6983613f58565b612351600233613fb4565b612389576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610d09565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314612389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d09565b60005b81518110156111fa57600082828151811061242c5761242c6155b7565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526007875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a250505080600101905061240f565b60006125c382600001518360600151846020015185604001516040805173ffffffffffffffffffffffffffffffffffffffff80871660208301528516918101919091527fffffffffffffffffffff00000000000000000000000000000000000000000000831660608201527fffff0000000000000000000000000000000000000000000000000000000000008216608082015260009060a001604051602081830303815290604052805190602001209050949350505050565b60808301516000828152600460205260409081902080549215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316929092179091555190915081907f32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a3906126d0908590600060a08201905073ffffffffffffffffffffffffffffffffffffffff8084511683527fffffffffffffffffffff0000000000000000000000000000000000000000000060208501511660208401527fffff00000000000000000000000000000000000000000000000000000000000060408501511660408401528060608501511660608401525060808301511515608083015292915050565b60405180910390a25050565b60005b8251811015612a055760008382815181106126fc576126fc6155b7565b6020026020010151905060008160000151905060005b8260200151518110156129f757600083602001518281518110612737576127376155b7565b602002602001015160200151905060008460200151838151811061275d5761275d6155b7565b6020026020010151600001519050602063ffffffff16826080015163ffffffff1610156127e05760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610d09565b67ffffffffffffffff84166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906129e5908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101612712565b5050508060010190506126df565b5060005b8151811015612334576000828281518110612a2657612a266155b7565b60200260200101516000015190506000838381518110612a4857612a486155b7565b60209081029190910181015181015167ffffffffffffffff84166000818152600a8452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612a09565b60005b8251811015612b8c57612b22838281518110612b0a57612b0a6155b7565b6020026020010151600b613fe390919063ffffffff16565b15612b8457828181518110612b3957612b396155b7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b600101612aec565b5060005b815181101561233457612bc6828281518110612bae57612bae6155b7565b6020026020010151600b61400590919063ffffffff16565b15612c2857818181518110612bdd57612bdd6155b7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101612b90565b6040810151604a820151605e90920151909260609290921c91565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602080840191909152908616828401527fffffffffffffffffffff00000000000000000000000000000000000000000000851660608301527fffff00000000000000000000000000000000000000000000000000000000000084166080808401919091528351808403909101815260a09092018352815191810191909120600081815260049092529190205460ff16612d9c576040517f097e17ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8087166004830152851660248201527fffffffffffffffffffff00000000000000000000000000000000000000000000841660448201527fffff00000000000000000000000000000000000000000000000000000000000083166064820152608401610d09565b5050505050565b600080612db0848661586a565b9050600060248260ff161115612de757612dcb602483615883565b612dd690600a6159bc565b612de0908561557c565b9050612e0a565b612df2826024615883565b612dfd90600a6159bc565b612e079085615565565b90505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612e60576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b95945050505050565b602081015160005b8151811015612f04576000828281518110612e8e57612e8e6155b7565b60200260200101519050612eac81600261402790919063ffffffff16565b15612efb5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612e71565b50815160005b81518110156111a2576000828281518110612f2757612f276155b7565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612f97576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fa2600282613fe3565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101612f0a565b60005b81518110156111fa576000828281518110613015576130156155b7565b602002602001015190506000838381518110613033576130336155b7565b60200260200101516000015190506000826020015190508167ffffffffffffffff166000148061306c575061016081015163ffffffff16155b806130be57506101e08101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130dd5750806060015163ffffffff1681610160015163ffffffff16115b15613120576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610d09565b67ffffffffffffffff821660009081526009602052604081206001015471010000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131c4578167ffffffffffffffff167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb724826040516131b79190614a27565b60405180910390a2613207565b8167ffffffffffffffff167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab20826040516131fe9190614a27565b60405180910390a25b80600960008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612ff8565b60005b81518110156111fa5760008282815181106134bb576134bb6155b7565b602002602001015160000151905060008383815181106134dd576134dd6155b7565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526008845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010161349e565b604080518082019091526000808252602082015260008390036135c657506040805180820190915267ffffffffffffffff8216815260006020820152610b69565b60006135d284866159cb565b905060006135e38560048189615a11565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f0000000000000000000000000000000000000000000000000000000000161368057808060200190518101906136779190615a3b565b92505050610b69565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016136fc576040518060400160405280828060200190518101906136e89190615a67565b815260006020909101529250610b69915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137bc9190615a9a565b50505091505060008112156137fd576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061387c8373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561384d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138719190615aea565b866020015184612da3565b604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff4216602082015295945050505050565b836040015163ffffffff168311156139165760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610d09565b836020015161ffff16821115613958576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111a2846101e00151826122e2565b6000808083815b81811015613c3157600087878381811061398a5761398a6155b7565b9050604002018036038101906139a09190615b07565b67ffffffffffffffff8c166000908152600a60209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090613ac0576101208d0151613a8d9061ffff16662386f26fc10000615565565b613a979088615844565b96508c610140015186613aaa9190615b40565b9550613ab7602086615b40565b94505050613c29565b604081015160009061ffff1615613b795760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614613b1c578351613b1590612248565b9050613b1f565b508a5b620186a0836040015161ffff16613b618660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661404990919063ffffffff16565b613b6b9190615565565b613b75919061557c565b9150505b6060820151613b889088615b40565b9650816080015186613b9a9190615b40565b8251909650600090613bb99063ffffffff16662386f26fc10000615565565b905080821015613bd857613bcd818a615844565b985050505050613c29565b6000836020015163ffffffff16662386f26fc10000613bf79190615565565b905080831115613c1757613c0b818b615844565b99505050505050613c29565b613c21838b615844565b995050505050505b60010161396e565b505096509650969350505050565b60008063ffffffff8316613c5561016086615565565b613c61876101c0615844565b613c6b9190615844565b613c759190615844565b905060008760c0015163ffffffff168860e0015161ffff1683613c989190615565565b613ca29190615844565b61010089015190915061ffff16613cc96dffffffffffffffffffffffffffff891683615565565b613cd39190615565565b613ce390655af3107a4000615565565b98975050505050505050565b60408051808201909152600080825260208201526000613d1b858585610160015163ffffffff16613585565b9050826060015163ffffffff1681600001511115613d65576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101c001518015613d7957508060200151155b15610b66576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603613e2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d09565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008151602014613ee457816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614498565b600082806020019051810190613efa9190615a67565b905073ffffffffffffffffffffffffffffffffffffffff811180613f1f575061040081105b156112c357826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614498565b606081600001805480602002602001604051908101604052809291908181526020018280548015613fa857602002820191906000526020600020905b815481526020019060010190808311613f94575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b69565b6000610b698373ffffffffffffffffffffffffffffffffffffffff8416614086565b6000610b698373ffffffffffffffffffffffffffffffffffffffff84166140d5565b6000610b698373ffffffffffffffffffffffffffffffffffffffff84166141cf565b6000670de0b6b3a764000061407c837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616615565565b610b69919061557c565b60008181526001830160205260408120546140cd575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112c3565b5060006112c3565b600081815260018301602052604081205480156141be5760006140f9600183615857565b855490915060009061410d90600190615857565b905080821461417257600086600001828154811061412d5761412d6155b7565b9060005260206000200154905080876000018481548110614150576141506155b7565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061418357614183615b5d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112c3565b60009150506112c3565b5092915050565b600081815260018301602052604081205480156141be5760006141f3600183615857565b855490915060009061420790600190615857565b905081811461417257600086600001828154811061412d5761412d6155b7565b803573ffffffffffffffffffffffffffffffffffffffff8116811461424b57600080fd5b919050565b60008060006060848603121561426557600080fd5b61426e84614227565b92506020840135915061428360408501614227565b90509250925092565b60006020828403121561429e57600080fd5b610b6982614227565b803567ffffffffffffffff8116811461424b57600080fd5b60008083601f8401126142d157600080fd5b50813567ffffffffffffffff8111156142e957600080fd5b6020830191508360208260051b850101111561224157600080fd5b60008060008060006060868803121561431c57600080fd5b614325866142a7565b9450602086013567ffffffffffffffff8082111561434257600080fd5b61434e89838a016142bf565b9096509450604088013591508082111561436757600080fd5b818801915088601f83011261437b57600080fd5b81358181111561438a57600080fd5b8960208260061b850101111561439f57600080fd5b9699959850939650602001949392505050565b6000815180845260005b818110156143d8576020818501810151868301820152016143bc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561448b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526144798583516143b2565b9450928501929085019060010161443f565b5092979650505050505050565b602081526000610b6960208301846143b2565b6020808252825182820181905260009190848201906040850190845b818110156144f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016144c7565b50909695505050505050565b60006020828403121561451757600080fd5b813567ffffffffffffffff81111561452e57600080fd5b820160408185031215610b6957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561459257614592614540565b60405290565b60405160a0810167ffffffffffffffff8111828210171561459257614592614540565b60405160c0810167ffffffffffffffff8111828210171561459257614592614540565b604051610200810167ffffffffffffffff8111828210171561459257614592614540565b6040516060810167ffffffffffffffff8111828210171561459257614592614540565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561466c5761466c614540565b604052919050565b600067ffffffffffffffff82111561468e5761468e614540565b5060051b60200190565b60ff811681146111b957600080fd5b600060208083850312156146ba57600080fd5b823567ffffffffffffffff8111156146d157600080fd5b8301601f810185136146e257600080fd5b80356146f56146f082614674565b614625565b8181526060918202830184019184820191908884111561471457600080fd5b938501935b838510156147b457848903818112156147325760008081fd5b61473a61456f565b61474387614227565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147775760008081fd5b61477f61456f565b925061478c898901614227565b835287013561479a81614698565b828901528088019190915283529384019391850191614719565b50979650505050505050565b80151581146111b957600080fd5b803561424b816147c0565b600060208083850312156147ec57600080fd5b823567ffffffffffffffff81111561480357600080fd5b8301601f8101851361481457600080fd5b80356148226146f082614674565b81815260a0918202830184019184820191908884111561484157600080fd5b938501935b838510156147b45780858a03121561485e5760008081fd5b614866614598565b61486f86614227565b8152868601357fffffffffffffffffffff00000000000000000000000000000000000000000000811681146148a45760008081fd5b818801526040868101357fffff000000000000000000000000000000000000000000000000000000000000811681146148dd5760008081fd5b9082015260606148ee878201614227565b90820152608086810135614901816147c0565b9082015283529384019391850191614846565b6000806020838503121561492757600080fd5b823567ffffffffffffffff81111561493e57600080fd5b61494a858286016142bf565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b828110156149c4576149b484835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101614973565b5091979650505050505050565b6000602082840312156149e357600080fd5b610b69826142a7565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff1690820152604081016112c3565b81511515815261020081016020830151614a47602084018261ffff169052565b506040830151614a5f604084018263ffffffff169052565b506060830151614a77606084018263ffffffff169052565b506080830151614a8f608084018263ffffffff169052565b5060a0830151614aa560a084018261ffff169052565b5060c0830151614abd60c084018263ffffffff169052565b5060e0830151614ad360e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff90811691840191909152610160808501518216908401526101808085015167ffffffffffffffff16908401526101a080850151909116908301526101c0808401511515908301526101e0808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461424b57600080fd5b803561ffff8116811461424b57600080fd5b600082601f830112614bb757600080fd5b81356020614bc76146f083614674565b82815260069290921b84018101918181019086841115614be657600080fd5b8286015b84811015614c335760408189031215614c035760008081fd5b614c0b61456f565b614c14826142a7565b8152614c21858301614227565b81860152835291830191604001614bea565b509695505050505050565b60008060408385031215614c5157600080fd5b67ffffffffffffffff83351115614c6757600080fd5b83601f843585010112614c7957600080fd5b614c896146f08435850135614674565b8335840180358083526020808401939260059290921b90910101861015614caf57600080fd5b602085358601015b85358601803560051b01602001811015614ebc5767ffffffffffffffff81351115614ce157600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a03011215614d1a57600080fd5b614d2261456f565b614d2e602083016142a7565b815267ffffffffffffffff60408301351115614d4957600080fd5b88603f604084013584010112614d5e57600080fd5b614d746146f06020604085013585010135614674565b6020604084810135850182810135808552928401939260e00201018b1015614d9b57600080fd5b6040808501358501015b6040858101358601602081013560e0020101811015614e9d5760e0818d031215614dce57600080fd5b614dd661456f565b614ddf82614227565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215614e1357600080fd5b614e1b6145bb565b614e2760208401614b80565b8152614e3560408401614b80565b6020820152614e4660608401614b94565b6040820152614e5760808401614b80565b6060820152614e6860a08401614b80565b6080820152614e7a60c08401356147c0565b60c083013560a0820152602082810191909152908452929092019160e001614da5565b5080602084015250508085525050602083019250602081019050614cb7565b5092505067ffffffffffffffff60208401351115614ed957600080fd5b614ee98460208501358501614ba6565b90509250929050565b600082601f830112614f0357600080fd5b81356020614f136146f083614674565b8083825260208201915060208460051b870101935086841115614f3557600080fd5b602086015b84811015614c3357614f4b81614227565b8352918301918301614f3a565b60008060408385031215614f6b57600080fd5b823567ffffffffffffffff80821115614f8357600080fd5b614f8f86838701614ef2565b93506020850135915080821115614fa557600080fd5b50614fb285828601614ef2565b9150509250929050565b60008083601f840112614fce57600080fd5b50813567ffffffffffffffff811115614fe657600080fd5b60208301915083602082850101111561224157600080fd5b6000806000806040858703121561501457600080fd5b843567ffffffffffffffff8082111561502c57600080fd5b61503888838901614fbc565b9096509450602087013591508082111561505157600080fd5b5061505e87828801614fbc565b95989497509550505050565b6000806040838503121561507d57600080fd5b615086836142a7565b9150614ee960208401614227565b6000602082840312156150a657600080fd5b813567ffffffffffffffff808211156150be57600080fd5b90830190604082860312156150d257600080fd5b6150da61456f565b8235828111156150e957600080fd5b6150f587828601614ef2565b82525060208301358281111561510a57600080fd5b61511687828601614ef2565b60208301525095945050505050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461424b57600080fd5b6000602080838503121561516857600080fd5b823567ffffffffffffffff81111561517f57600080fd5b8301601f8101851361519057600080fd5b803561519e6146f082614674565b81815261022091820283018401918482019190888411156151be57600080fd5b938501935b838510156147b457848903818112156151dc5760008081fd5b6151e461456f565b6151ed876142a7565b8152610200807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156152225760008081fd5b61522a6145de565b92506152378989016147ce565b83526040615246818a01614b94565b8a8501526060615257818b01614b80565b828601526080915061526a828b01614b80565b9085015260a061527b8a8201614b80565b8286015260c0915061528e828b01614b94565b9085015260e061529f8a8201614b80565b8286015261010091506152b3828b01614b94565b908501526101206152c58a8201614b94565b8286015261014091506152d9828b01614b94565b908501526101606152eb8a8201614b80565b8286015261018091506152ff828b01614b80565b908501526101a06153118a82016142a7565b828601526101c09150615325828b01614b80565b908501526101e06153378a82016147ce565b82860152615346838b01615125565b90850152505080880191909152835293840193918501916151c3565b6000602080838503121561537557600080fd5b823567ffffffffffffffff81111561538c57600080fd5b8301601f8101851361539d57600080fd5b80356153ab6146f082614674565b81815260069190911b820183019083810190878311156153ca57600080fd5b928401925b8284101561541c57604084890312156153e85760008081fd5b6153f061456f565b6153f985614227565b81526154068686016142a7565b81870152825260409390930192908401906153cf565b979650505050505050565b60008060008060006080868803121561543f57600080fd5b615448866142a7565b945061545660208701614227565b935060408601359250606086013567ffffffffffffffff81111561547957600080fd5b61548588828901614fbc565b969995985093965092949392505050565b8381528215156020820152606060408201526000612e6060608301846143b2565b600080604083850312156154ca57600080fd5b6154d3836142a7565b9150602083013567ffffffffffffffff8111156154ef57600080fd5b830160a0818603121561550157600080fd5b809150509250929050565b6000806040838503121561551f57600080fd5b61552883614227565b9150614ee9602084016142a7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176112c3576112c3615536565b6000826155b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261561a57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261565957600080fd5b83018035915067ffffffffffffffff82111561567457600080fd5b60200191503681900382131561224157600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126156be57600080fd5b83018035915067ffffffffffffffff8211156156d957600080fd5b6020019150600681901b360382131561224157600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461424b57600080fd5b60006040828403121561572f57600080fd5b61573761456f565b61574083614227565b815261574e602084016156f1565b60208201529392505050565b60006040828403121561576c57600080fd5b61577461456f565b615740836142a7565b6000602080838503121561579057600080fd5b823567ffffffffffffffff8111156157a757600080fd5b8301601f810185136157b857600080fd5b80356157c66146f082614674565b818152606091820283018401918482019190888411156157e557600080fd5b938501935b838510156147b45780858a0312156158025760008081fd5b61580a614602565b61581386614227565b81526158208787016156f1565b878201526040615831818801614b80565b90820152835293840193918501916157ea565b808201808211156112c3576112c3615536565b818103818111156112c3576112c3615536565b60ff81811683821601908111156112c3576112c3615536565b60ff82811682821603908111156112c3576112c3615536565b600181815b808511156158f557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156158db576158db615536565b808516156158e857918102915b93841c93908002906158a1565b509250929050565b60008261590c575060016112c3565b81615919575060006112c3565b816001811461592f576002811461593957615955565b60019150506112c3565b60ff84111561594a5761594a615536565b50506001821b6112c3565b5060208310610133831016604e8410600b8410161715615978575081810a6112c3565b615982838361589c565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156159b4576159b4615536565b029392505050565b6000610b6960ff8416836158fd565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015614b785760049490940360031b84901b1690921692915050565b60008085851115615a2157600080fd5b83861115615a2e57600080fd5b5050820193919092039150565b600060408284031215615a4d57600080fd5b615a5561456f565b82518152602083015161574e816147c0565b600060208284031215615a7957600080fd5b5051919050565b805169ffffffffffffffffffff8116811461424b57600080fd5b600080600080600060a08688031215615ab257600080fd5b615abb86615a80565b9450602086015193506040860151925060608601519150615ade60808701615a80565b90509295509295909350565b600060208284031215615afc57600080fd5b8151610b6981614698565b600060408284031215615b1957600080fd5b615b2161456f565b615b2a83614227565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156141c8576141c8615536565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var PriceRegistryABI = PriceRegistryMetaData.ABI @@ -663,46 +663,48 @@ func (_PriceRegistry *PriceRegistryCallerSession) ProcessMessageArgs(destChainSe return _PriceRegistry.Contract.ProcessMessageArgs(&_PriceRegistry.CallOpts, destChainSelector, feeToken, feeTokenAmount, extraArgs) } -func (_PriceRegistry *PriceRegistryCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { +func (_PriceRegistry *PriceRegistryCaller) ProcessPoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) ([][]byte, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "typeAndVersion") + err := _PriceRegistry.contract.Call(opts, &out, "processPoolReturnData", destChainSelector, rampTokenAmounts, sourceTokenAmounts) if err != nil { - return *new(string), err + return *new([][]byte), err } - out0 := *abi.ConvertType(out[0], new(string)).(*string) + out0 := *abi.ConvertType(out[0], new([][]byte)).(*[][]byte) return out0, err } -func (_PriceRegistry *PriceRegistrySession) TypeAndVersion() (string, error) { - return _PriceRegistry.Contract.TypeAndVersion(&_PriceRegistry.CallOpts) +func (_PriceRegistry *PriceRegistrySession) ProcessPoolReturnData(destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) ([][]byte, error) { + return _PriceRegistry.Contract.ProcessPoolReturnData(&_PriceRegistry.CallOpts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) } -func (_PriceRegistry *PriceRegistryCallerSession) TypeAndVersion() (string, error) { - return _PriceRegistry.Contract.TypeAndVersion(&_PriceRegistry.CallOpts) +func (_PriceRegistry *PriceRegistryCallerSession) ProcessPoolReturnData(destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) ([][]byte, error) { + return _PriceRegistry.Contract.ProcessPoolReturnData(&_PriceRegistry.CallOpts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) } -func (_PriceRegistry *PriceRegistryCaller) ValidatePoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) error { +func (_PriceRegistry *PriceRegistryCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "validatePoolReturnData", destChainSelector, rampTokenAmounts, sourceTokenAmounts) + err := _PriceRegistry.contract.Call(opts, &out, "typeAndVersion") if err != nil { - return err + return *new(string), err } - return err + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err } -func (_PriceRegistry *PriceRegistrySession) ValidatePoolReturnData(destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) error { - return _PriceRegistry.Contract.ValidatePoolReturnData(&_PriceRegistry.CallOpts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) +func (_PriceRegistry *PriceRegistrySession) TypeAndVersion() (string, error) { + return _PriceRegistry.Contract.TypeAndVersion(&_PriceRegistry.CallOpts) } -func (_PriceRegistry *PriceRegistryCallerSession) ValidatePoolReturnData(destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) error { - return _PriceRegistry.Contract.ValidatePoolReturnData(&_PriceRegistry.CallOpts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) +func (_PriceRegistry *PriceRegistryCallerSession) TypeAndVersion() (string, error) { + return _PriceRegistry.Contract.TypeAndVersion(&_PriceRegistry.CallOpts) } func (_PriceRegistry *PriceRegistryTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { @@ -2825,11 +2827,11 @@ func (PriceRegistryAuthorizedCallerRemoved) Topic() common.Hash { } func (PriceRegistryDestChainAdded) Topic() common.Hash { - return common.HexToHash("0xa937382a486d993de71c220bc8b559242deb4e286a353fa732330b4aa7d13577") + return common.HexToHash("0xd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb724") } func (PriceRegistryDestChainConfigUpdated) Topic() common.Hash { - return common.HexToHash("0xa7b607fc10d28a1caf39ab7d27f4c94945db708a576d572781a455c5894fad93") + return common.HexToHash("0x1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab20") } func (PriceRegistryFeeTokenAdded) Topic() common.Hash { @@ -2917,9 +2919,9 @@ type PriceRegistryInterface interface { error) - TypeAndVersion(opts *bind.CallOpts) (string, error) + ProcessPoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) ([][]byte, error) - ValidatePoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) error + TypeAndVersion(opts *bind.CallOpts) (string, error) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/report_codec/report_codec.go b/core/gethwrappers/ccip/generated/report_codec/report_codec.go index 7afd3d9bba..0080cfc419 100644 --- a/core/gethwrappers/ccip/generated/report_codec/report_codec.go +++ b/core/gethwrappers/ccip/generated/report_codec/report_codec.go @@ -70,6 +70,7 @@ type InternalRampTokenAmount struct { DestTokenAddress []byte ExtraData []byte Amount *big.Int + DestExecData []byte } type InternalTokenPriceUpdate struct { @@ -94,8 +95,8 @@ type OffRampMerkleRoot struct { } var ReportCodecMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportDecoded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"report\",\"type\":\"tuple[]\"}],\"name\":\"ExecuteReportDecoded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeCommitReport\",\"outputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeExecuteReport\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061124f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636fb349561461003b578063f816ec6014610064575b600080fd5b61004e61004936600461024f565b610084565b60405161005b91906104f5565b60405180910390f35b61007761007236600461024f565b6100a0565b60405161005b91906107ae565b60608180602001905181019061009a9190610dc3565b92915050565b604080516080810182526060918101828152828201839052815260208101919091528180602001905181019061009a91906110d9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715610128576101286100d6565b60405290565b6040516080810167ffffffffffffffff81118282101715610128576101286100d6565b60405160c0810167ffffffffffffffff81118282101715610128576101286100d6565b6040805190810167ffffffffffffffff81118282101715610128576101286100d6565b6040516060810167ffffffffffffffff81118282101715610128576101286100d6565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610201576102016100d6565b604052919050565b600067ffffffffffffffff821115610223576102236100d6565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006020828403121561026157600080fd5b813567ffffffffffffffff81111561027857600080fd5b8201601f8101841361028957600080fd5b803561029c61029782610209565b6101ba565b8181528560208385010111156102b157600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b838110156102ea5781810151838201526020016102d2565b50506000910152565b6000815180845261030b8160208601602086016102cf565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b848110156103f2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086840301895281516080815181865261039e828701826102f3565b91505085820151858203878701526103b682826102f3565b915050604080830151868303828801526103d083826102f3565b606094850151979094019690965250509884019892509083019060010161035a565b5090979650505050505050565b6000828251808552602080860195506005818360051b8501018287016000805b868110156104aa577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe088850381018c5283518051808752908801908887019080891b88018a01865b8281101561049357858a83030184526104818286516102f3565b948c0194938c01939150600101610467565b509e8a019e9750505093870193505060010161041f565b50919998505050505050505050565b60008151808452602080850194506020840160005b838110156104ea578151875295820195908201906001016104ce565b509495945050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156106dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452815160a0860167ffffffffffffffff8083511688528883015160a08a8a015282815180855260c08b01915060c08160051b8c010194508b8301925060005b81811015610686577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408c87030183528351805180518852868f820151168f890152866040820151166040890152866060820151166060890152866080820151166080890152508d81015161014060a08901526106096101408901826102f3565b9050604082015188820360c08a015261062282826102f3565b915050606082015161064c60e08a018273ffffffffffffffffffffffffffffffffffffffff169052565b50608082015161010089015260a08201519150878103610120890152610672818361033d565b97505050928c0192918c0191600101610589565b5050505050604082015187820360408901526106a282826103ff565b915050606082015187820360608901526106bc82826104b9565b6080938401519890930197909752509450928501929085019060010161051c565b5092979650505050505050565b60008151808452602080850194506020840160005b838110156104ea578151805167ffffffffffffffff1688528301517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683880152604090960195908201906001016106ff565b600081518084526020808501945080840160005b838110156104ea578151805167ffffffffffffffff90811689528482015180518216868b0152850151166040808a01919091520151606088015260809096019590820190600101610762565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b8083101561083e578351805173ffffffffffffffffffffffffffffffffffffffff1683528701517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16878301529286019260019290920191908401906107e1565b50938501518785037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa00160808901529361087881866106ea565b9450505050508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08482030160408501526108b8818361074e565b95945050505050565b600067ffffffffffffffff8211156108db576108db6100d6565b5060051b60200190565b805167ffffffffffffffff811681146108fd57600080fd5b919050565b600060a0828403121561091457600080fd5b61091c610105565b90508151815261092e602083016108e5565b602082015261093f604083016108e5565b6040820152610950606083016108e5565b6060820152610961608083016108e5565b608082015292915050565b600082601f83011261097d57600080fd5b815161098b61029782610209565b8181528460208386010111156109a057600080fd5b6109b18260208301602087016102cf565b949350505050565b805173ffffffffffffffffffffffffffffffffffffffff811681146108fd57600080fd5b600082601f8301126109ee57600080fd5b815160206109fe610297836108c1565b82815260059290921b84018101918181019086841115610a1d57600080fd5b8286015b84811015610b1157805167ffffffffffffffff80821115610a425760008081fd5b81890191506080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610a7b5760008081fd5b610a8361012e565b8784015183811115610a955760008081fd5b610aa38d8a8388010161096c565b82525060408085015184811115610aba5760008081fd5b610ac88e8b8389010161096c565b8a8401525060608086015185811115610ae15760008081fd5b610aef8f8c838a010161096c565b9284019290925294909201519381019390935250508352918301918301610a21565b509695505050505050565b600082601f830112610b2d57600080fd5b81516020610b3d610297836108c1565b82815260059290921b84018101918181019086841115610b5c57600080fd5b8286015b84811015610b1157805167ffffffffffffffff80821115610b815760008081fd5b8189019150610140807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610bbb5760008081fd5b610bc3610151565b610bcf8c898601610902565b815260c084015183811115610be45760008081fd5b610bf28d8a8388010161096c565b898301525060e084015183811115610c0a5760008081fd5b610c188d8a8388010161096c565b604083015250610c2b61010085016109b9565b60608201526101208401516080820152908301519082821115610c4e5760008081fd5b610c5c8c89848701016109dd565b60a08201528652505050918301918301610b60565b600082601f830112610c8257600080fd5b81516020610c92610297836108c1565b82815260059290921b84018101918181019086841115610cb157600080fd5b8286015b84811015610b1157805167ffffffffffffffff80821115610cd557600080fd5b818901915089603f830112610ce957600080fd5b85820151610cf9610297826108c1565b81815260059190911b830160400190878101908c831115610d1957600080fd5b604085015b83811015610d5257805185811115610d3557600080fd5b610d448f6040838a010161096c565b845250918901918901610d1e565b50875250505092840192508301610cb5565b600082601f830112610d7557600080fd5b81516020610d85610297836108c1565b8083825260208201915060208460051b870101935086841115610da757600080fd5b602086015b84811015610b115780518352918301918301610dac565b60006020808385031215610dd657600080fd5b825167ffffffffffffffff80821115610dee57600080fd5b818501915085601f830112610e0257600080fd5b8151610e10610297826108c1565b81815260059190911b83018401908481019088831115610e2f57600080fd5b8585015b83811015610f2957805185811115610e4a57600080fd5b860160a0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215610e7f5760008081fd5b610e87610105565b610e928983016108e5565b815260408083015188811115610ea85760008081fd5b610eb68e8c83870101610b1c565b8b8401525060608084015189811115610ecf5760008081fd5b610edd8f8d83880101610c71565b8385015250608091508184015189811115610ef85760008081fd5b610f068f8d83880101610d64565b918401919091525060a09290920151918101919091528352918601918601610e33565b5098975050505050505050565b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146108fd57600080fd5b600082601f830112610f7357600080fd5b81516020610f83610297836108c1565b82815260069290921b84018101918181019086841115610fa257600080fd5b8286015b84811015610b115760408189031215610fbf5760008081fd5b610fc7610174565b610fd0826108e5565b8152610fdd858301610f36565b81860152835291830191604001610fa6565b600082601f83011261100057600080fd5b81516020611010610297836108c1565b82815260079290921b8401810191818101908684111561102f57600080fd5b8286015b84811015610b1157808803608081121561104d5760008081fd5b611055610197565b61105e836108e5565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156110925760008081fd5b61109a610174565b92506110a78785016108e5565b83526110b48185016108e5565b8388015281870192909252606083015191810191909152835291830191608001611033565b600060208083850312156110ec57600080fd5b825167ffffffffffffffff8082111561110457600080fd5b8185019150604080838803121561111a57600080fd5b611122610174565b83518381111561113157600080fd5b84016040818a03121561114357600080fd5b61114b610174565b81518581111561115a57600080fd5b8201601f81018b1361116b57600080fd5b8051611179610297826108c1565b81815260069190911b8201890190898101908d83111561119857600080fd5b928a01925b828410156111e65787848f0312156111b55760008081fd5b6111bd610174565b6111c6856109b9565b81526111d38c8601610f36565b818d0152825292870192908a019061119d565b8452505050818701519350848411156111fe57600080fd5b61120a8a858401610f62565b818801528252508385015191508282111561122457600080fd5b61123088838601610fef565b8582015280955050505050509291505056fea164736f6c6343000818000a", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportDecoded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"report\",\"type\":\"tuple[]\"}],\"name\":\"ExecuteReportDecoded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeCommitReport\",\"outputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeExecuteReport\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061126d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636fb349561461003b578063f816ec6014610064575b600080fd5b61004e61004936600461022c565b610084565b60405161005b91906104ed565b60405180910390f35b61007761007236600461022c565b6100a0565b60405161005b91906107a6565b60608180602001905181019061009a9190610de1565b92915050565b604080516080810182526060918101828152828201839052815260208101919091528180602001905181019061009a91906110f7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715610128576101286100d6565b60405290565b60405160c0810167ffffffffffffffff81118282101715610128576101286100d6565b6040805190810167ffffffffffffffff81118282101715610128576101286100d6565b6040516060810167ffffffffffffffff81118282101715610128576101286100d6565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156101de576101de6100d6565b604052919050565b600067ffffffffffffffff821115610200576102006100d6565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006020828403121561023e57600080fd5b813567ffffffffffffffff81111561025557600080fd5b8201601f8101841361026657600080fd5b8035610279610274826101e6565b610197565b81815285602083850101111561028e57600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b838110156102c75781810151838201526020016102af565b50506000910152565b600081518084526102e88160208601602086016102ac565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b848110156103ea577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160a0815181865261037b828701826102d0565b915050858201518582038787015261039382826102d0565b915050604080830151868303828801526103ad83826102d0565b925050506060808301518187015250608080830151925085820381870152506103d681836102d0565b9a86019a9450505090830190600101610337565b5090979650505050505050565b6000828251808552602080860195506005818360051b8501018287016000805b868110156104a2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe088850381018c5283518051808752908801908887019080891b88018a01865b8281101561048b57858a83030184526104798286516102d0565b948c0194938c0193915060010161045f565b509e8a019e97505050938701935050600101610417565b50919998505050505050505050565b60008151808452602080850194506020840160005b838110156104e2578151875295820195908201906001016104c6565b509495945050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156106d5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452815160a0860167ffffffffffffffff8083511688528883015160a08a8a015282815180855260c08b01915060c08160051b8c010194508b8301925060005b8181101561067e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408c87030183528351805180518852868f820151168f890152866040820151166040890152866060820151166060890152866080820151166080890152508d81015161014060a08901526106016101408901826102d0565b9050604082015188820360c08a015261061a82826102d0565b915050606082015161064460e08a018273ffffffffffffffffffffffffffffffffffffffff169052565b50608082015161010089015260a0820151915087810361012089015261066a818361031a565b97505050928c0192918c0191600101610581565b50505050506040820151878203604089015261069a82826103f7565b915050606082015187820360608901526106b482826104b1565b60809384015198909301979097525094509285019290850190600101610514565b5092979650505050505050565b60008151808452602080850194506020840160005b838110156104e2578151805167ffffffffffffffff1688528301517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683880152604090960195908201906001016106f7565b600081518084526020808501945080840160005b838110156104e2578151805167ffffffffffffffff90811689528482015180518216868b0152850151166040808a0191909152015160608801526080909601959082019060010161075a565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b80831015610836578351805173ffffffffffffffffffffffffffffffffffffffff1683528701517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16878301529286019260019290920191908401906107d9565b50938501518785037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa00160808901529361087081866106e2565b9450505050508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08482030160408501526108b08183610746565b95945050505050565b600067ffffffffffffffff8211156108d3576108d36100d6565b5060051b60200190565b805167ffffffffffffffff811681146108f557600080fd5b919050565b600060a0828403121561090c57600080fd5b610914610105565b905081518152610926602083016108dd565b6020820152610937604083016108dd565b6040820152610948606083016108dd565b6060820152610959608083016108dd565b608082015292915050565b600082601f83011261097557600080fd5b8151610983610274826101e6565b81815284602083860101111561099857600080fd5b6109a98260208301602087016102ac565b949350505050565b805173ffffffffffffffffffffffffffffffffffffffff811681146108f557600080fd5b600082601f8301126109e657600080fd5b815160206109f6610274836108b9565b82815260059290921b84018101918181019086841115610a1557600080fd5b8286015b84811015610b2f57805167ffffffffffffffff80821115610a3a5760008081fd5b818901915060a0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610a735760008081fd5b610a7b610105565b8784015183811115610a8d5760008081fd5b610a9b8d8a83880101610964565b82525060408085015184811115610ab25760008081fd5b610ac08e8b83890101610964565b8a8401525060608086015185811115610ad95760008081fd5b610ae78f8c838a0101610964565b83850152506080915081860151818401525082850151925083831115610b0d5760008081fd5b610b1b8d8a85880101610964565b908201528652505050918301918301610a19565b509695505050505050565b600082601f830112610b4b57600080fd5b81516020610b5b610274836108b9565b82815260059290921b84018101918181019086841115610b7a57600080fd5b8286015b84811015610b2f57805167ffffffffffffffff80821115610b9f5760008081fd5b8189019150610140807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610bd95760008081fd5b610be161012e565b610bed8c8986016108fa565b815260c084015183811115610c025760008081fd5b610c108d8a83880101610964565b898301525060e084015183811115610c285760008081fd5b610c368d8a83880101610964565b604083015250610c4961010085016109b1565b60608201526101208401516080820152908301519082821115610c6c5760008081fd5b610c7a8c89848701016109d5565b60a08201528652505050918301918301610b7e565b600082601f830112610ca057600080fd5b81516020610cb0610274836108b9565b82815260059290921b84018101918181019086841115610ccf57600080fd5b8286015b84811015610b2f57805167ffffffffffffffff80821115610cf357600080fd5b818901915089603f830112610d0757600080fd5b85820151610d17610274826108b9565b81815260059190911b830160400190878101908c831115610d3757600080fd5b604085015b83811015610d7057805185811115610d5357600080fd5b610d628f6040838a0101610964565b845250918901918901610d3c565b50875250505092840192508301610cd3565b600082601f830112610d9357600080fd5b81516020610da3610274836108b9565b8083825260208201915060208460051b870101935086841115610dc557600080fd5b602086015b84811015610b2f5780518352918301918301610dca565b60006020808385031215610df457600080fd5b825167ffffffffffffffff80821115610e0c57600080fd5b818501915085601f830112610e2057600080fd5b8151610e2e610274826108b9565b81815260059190911b83018401908481019088831115610e4d57600080fd5b8585015b83811015610f4757805185811115610e6857600080fd5b860160a0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215610e9d5760008081fd5b610ea5610105565b610eb08983016108dd565b815260408083015188811115610ec65760008081fd5b610ed48e8c83870101610b3a565b8b8401525060608084015189811115610eed5760008081fd5b610efb8f8d83880101610c8f565b8385015250608091508184015189811115610f165760008081fd5b610f248f8d83880101610d82565b918401919091525060a09290920151918101919091528352918601918601610e51565b5098975050505050505050565b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146108f557600080fd5b600082601f830112610f9157600080fd5b81516020610fa1610274836108b9565b82815260069290921b84018101918181019086841115610fc057600080fd5b8286015b84811015610b2f5760408189031215610fdd5760008081fd5b610fe5610151565b610fee826108dd565b8152610ffb858301610f54565b81860152835291830191604001610fc4565b600082601f83011261101e57600080fd5b8151602061102e610274836108b9565b82815260079290921b8401810191818101908684111561104d57600080fd5b8286015b84811015610b2f57808803608081121561106b5760008081fd5b611073610174565b61107c836108dd565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156110b05760008081fd5b6110b8610151565b92506110c58785016108dd565b83526110d28185016108dd565b8388015281870192909252606083015191810191909152835291830191608001611051565b6000602080838503121561110a57600080fd5b825167ffffffffffffffff8082111561112257600080fd5b8185019150604080838803121561113857600080fd5b611140610151565b83518381111561114f57600080fd5b84016040818a03121561116157600080fd5b611169610151565b81518581111561117857600080fd5b8201601f81018b1361118957600080fd5b8051611197610274826108b9565b81815260069190911b8201890190898101908d8311156111b657600080fd5b928a01925b828410156112045787848f0312156111d35760008081fd5b6111db610151565b6111e4856109b1565b81526111f18c8601610f54565b818d0152825292870192908a01906111bb565b84525050508187015193508484111561121c57600080fd5b6112288a858401610f80565b818801528252508385015191508282111561124257600080fd5b61124e8883860161100d565b8582015280955050505050509291505056fea164736f6c6343000818000a", } var ReportCodecABI = ReportCodecMetaData.ABI @@ -529,7 +530,7 @@ func (ReportCodecCommitReportDecoded) Topic() common.Hash { } func (ReportCodecExecuteReportDecoded) Topic() common.Hash { - return common.HexToHash("0x7f4f1032eaaa1f5c3fc02d56071d69a09a2595d9a5fa4704f0eb298792908abb") + return common.HexToHash("0x70d042e9d8463eeac7e835e7172c08846ad327fc4eb6fc89f3bb5226e17ad618") } func (_ReportCodec *ReportCodec) Address() common.Address { diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 16dc444b43..4ebdb09e02 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -5,7 +5,7 @@ burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoo burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6333d0314d0bd29e75ea5e05fe62a4516ade0c6db91c30b6f93645035db52ed8 burn_with_from_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin 08ed1235dda921ce8841b26aa18d0c0f36db4884779dd7670857159801b6d597 ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 213d4adc8634671aea16fb4207989375b1aac919b04d608f4767c29592affbf5 -ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin a5b0275dcf502f73d72f6bc53bff774e25fcca01a74cc019536bdee6a42ac655 +ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin 459ae9c785343bd032856baaacdfc8bf4f6b0d9f5d9082e1580b5846c2be80e5 commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin 274d87db70b643e00ab0a7e7845bb4b791f3b613bfc87708d33fc5a8369e2a41 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin f7128dcc2ee6dbcbc976288abcc16970ffb19b59412c5202ef6b259d2007f801 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de @@ -14,7 +14,7 @@ evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.ab lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin e6a8ec9e8faccb1da7d90e0f702ed72975964f97dc3222b54cfcca0a0ba3fea2 lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin e632b08be0fbd1d013e8b3a9d75293d0d532b83071c531ff2be1deec1fa48ec1 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 -message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin 1d5146d43e1b99cd2d6f9f06475be19087e4349f7cee0fdbbf134ba65e967c93 +message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin 5712fbc30cf826c0cf38c68f54f744741b553d98c60e66696b7a845778cb2b3d mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin d976651d36b33ac2196b32b9d2f4fa6690c6a18d41b621365659fce1c1d1e737 mock_usdc_token_transmitter: ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin be0dbc3e475741ea0b7a54ec2b935a321b428baa9f4ce18180a87fb38bb87de2 mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin 518e19efa2ff52b0fefd8e597b05765317ee7638189bfe34ca43de2f6599faf4 @@ -22,12 +22,12 @@ multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRate multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin aa299e0c2659d53aad4eace4d66be0e734b1366008593669cf30361ff529da6a nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 6f64e1083b356c06ee66b9138e398b9c97a4cd3e8c9ec38cf3010cebc79af536 ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 -offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin 76ec9676116368ab7c7c7ed45191698a12e4d975633caea32d821a1125633589 -onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 123e949bc9607289382534c4432ecebe5b1da5ca92c1c6c8cc6b9be56c3352c6 +offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin e47ad9f887ace1741af3147cbd82c89e10deb3c68d8ffcd7fcbca33dc017e35a +onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 5b00bebfbf22003a13a2bce78e35c90869ca1dc2ebd3febd9bdf8151d8fa11e0 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin c1c2f8a65c7ffd971899cae7fe62f2da57d09e936151e2b92163c4bebe699d6b -price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 8931609776700a2a8121c9fdd757dbf9207d8b97583e70c84ec2d88c839d4a30 +price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin e7781d600c1bb7aa4620106af7f6e146a109b97f4cb6a7d06c9e15773340ecb2 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 75be86323c227917a9bbc3f799d7ed02f92db546653a36db30ed0ebe64461353 -report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin 20292ddaba15096fe8060567cf56cda673b947df27241d0c49d2debc838feb24 +report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin 3d7ebd8d4563b63cec83b141fe9f9ef5d8ab12a7c23ccd5e7e3434aba3cab66a rmn_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 8b45b0fb08631c6b582fd3c0b4052a79cc2b4e091e6286af1ab131bef63661f9 rmn_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 2e4f0a7826c8abb49d882bb49fc5ff20a186dbd3137624b9097ffed903ae4888 diff --git a/core/gethwrappers/ccip/mocks/price_registry_interface.go b/core/gethwrappers/ccip/mocks/price_registry_interface.go index 01d435d05a..04104ce835 100644 --- a/core/gethwrappers/ccip/mocks/price_registry_interface.go +++ b/core/gethwrappers/ccip/mocks/price_registry_interface.go @@ -3239,6 +3239,67 @@ func (_c *PriceRegistryInterface_ProcessMessageArgs_Call) RunAndReturn(run func( return _c } +// ProcessPoolReturnData provides a mock function with given fields: opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts +func (_m *PriceRegistryInterface) ProcessPoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []price_registry.InternalRampTokenAmount, sourceTokenAmounts []price_registry.ClientEVMTokenAmount) ([][]byte, error) { + ret := _m.Called(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) + + if len(ret) == 0 { + panic("no return value specified for ProcessPoolReturnData") + } + + var r0 [][]byte + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, []price_registry.InternalRampTokenAmount, []price_registry.ClientEVMTokenAmount) ([][]byte, error)); ok { + return rf(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, []price_registry.InternalRampTokenAmount, []price_registry.ClientEVMTokenAmount) [][]byte); ok { + r0 = rf(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([][]byte) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, []price_registry.InternalRampTokenAmount, []price_registry.ClientEVMTokenAmount) error); ok { + r1 = rf(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PriceRegistryInterface_ProcessPoolReturnData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ProcessPoolReturnData' +type PriceRegistryInterface_ProcessPoolReturnData_Call struct { + *mock.Call +} + +// ProcessPoolReturnData is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +// - rampTokenAmounts []price_registry.InternalRampTokenAmount +// - sourceTokenAmounts []price_registry.ClientEVMTokenAmount +func (_e *PriceRegistryInterface_Expecter) ProcessPoolReturnData(opts interface{}, destChainSelector interface{}, rampTokenAmounts interface{}, sourceTokenAmounts interface{}) *PriceRegistryInterface_ProcessPoolReturnData_Call { + return &PriceRegistryInterface_ProcessPoolReturnData_Call{Call: _e.mock.On("ProcessPoolReturnData", opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts)} +} + +func (_c *PriceRegistryInterface_ProcessPoolReturnData_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []price_registry.InternalRampTokenAmount, sourceTokenAmounts []price_registry.ClientEVMTokenAmount)) *PriceRegistryInterface_ProcessPoolReturnData_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].([]price_registry.InternalRampTokenAmount), args[3].([]price_registry.ClientEVMTokenAmount)) + }) + return _c +} + +func (_c *PriceRegistryInterface_ProcessPoolReturnData_Call) Return(_a0 [][]byte, _a1 error) *PriceRegistryInterface_ProcessPoolReturnData_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PriceRegistryInterface_ProcessPoolReturnData_Call) RunAndReturn(run func(*bind.CallOpts, uint64, []price_registry.InternalRampTokenAmount, []price_registry.ClientEVMTokenAmount) ([][]byte, error)) *PriceRegistryInterface_ProcessPoolReturnData_Call { + _c.Call.Return(run) + return _c +} + // SetReportPermissions provides a mock function with given fields: opts, permissions func (_m *PriceRegistryInterface) SetReportPermissions(opts *bind.TransactOpts, permissions []price_registry.KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { ret := _m.Called(opts, permissions) @@ -3531,55 +3592,6 @@ func (_c *PriceRegistryInterface_UpdateTokenPriceFeeds_Call) RunAndReturn(run fu return _c } -// ValidatePoolReturnData provides a mock function with given fields: opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts -func (_m *PriceRegistryInterface) ValidatePoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []price_registry.InternalRampTokenAmount, sourceTokenAmounts []price_registry.ClientEVMTokenAmount) error { - ret := _m.Called(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) - - if len(ret) == 0 { - panic("no return value specified for ValidatePoolReturnData") - } - - var r0 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, []price_registry.InternalRampTokenAmount, []price_registry.ClientEVMTokenAmount) error); ok { - r0 = rf(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// PriceRegistryInterface_ValidatePoolReturnData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ValidatePoolReturnData' -type PriceRegistryInterface_ValidatePoolReturnData_Call struct { - *mock.Call -} - -// ValidatePoolReturnData is a helper method to define mock.On call -// - opts *bind.CallOpts -// - destChainSelector uint64 -// - rampTokenAmounts []price_registry.InternalRampTokenAmount -// - sourceTokenAmounts []price_registry.ClientEVMTokenAmount -func (_e *PriceRegistryInterface_Expecter) ValidatePoolReturnData(opts interface{}, destChainSelector interface{}, rampTokenAmounts interface{}, sourceTokenAmounts interface{}) *PriceRegistryInterface_ValidatePoolReturnData_Call { - return &PriceRegistryInterface_ValidatePoolReturnData_Call{Call: _e.mock.On("ValidatePoolReturnData", opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts)} -} - -func (_c *PriceRegistryInterface_ValidatePoolReturnData_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []price_registry.InternalRampTokenAmount, sourceTokenAmounts []price_registry.ClientEVMTokenAmount)) *PriceRegistryInterface_ValidatePoolReturnData_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].([]price_registry.InternalRampTokenAmount), args[3].([]price_registry.ClientEVMTokenAmount)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ValidatePoolReturnData_Call) Return(_a0 error) *PriceRegistryInterface_ValidatePoolReturnData_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *PriceRegistryInterface_ValidatePoolReturnData_Call) RunAndReturn(run func(*bind.CallOpts, uint64, []price_registry.InternalRampTokenAmount, []price_registry.ClientEVMTokenAmount) error) *PriceRegistryInterface_ValidatePoolReturnData_Call { - _c.Call.Return(run) - return _c -} - // WatchAuthorizedCallerAdded provides a mock function with given fields: opts, sink func (_m *PriceRegistryInterface) WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryAuthorizedCallerAdded) (event.Subscription, error) { ret := _m.Called(opts, sink) diff --git a/integration-tests/deployment/ccip/add_lane.go b/integration-tests/deployment/ccip/add_lane.go new file mode 100644 index 0000000000..1f8dcd43f9 --- /dev/null +++ b/integration-tests/deployment/ccip/add_lane.go @@ -0,0 +1,120 @@ +package ccipdeployment + +import ( + "encoding/hex" + "math/big" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" +) + +func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) error { + // TODO: Batch + tx, err := state.Chains[from].Router.ApplyRampUpdates(e.Chains[from].DeployerKey, []router.RouterOnRamp{ + { + DestChainSelector: to, + OnRamp: state.Chains[from].EvmOnRampV160.Address(), + }, + }, []router.RouterOffRamp{}, []router.RouterOffRamp{}) + if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { + return err + } + tx, err = state.Chains[from].EvmOnRampV160.ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, + []onramp.OnRampDestChainConfigArgs{ + { + DestChainSelector: to, + Router: state.Chains[from].Router.Address(), + }, + }) + if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { + return err + } + + _, err = state.Chains[from].PriceRegistry.UpdatePrices( + e.Chains[from].DeployerKey, price_registry.InternalPriceUpdates{ + TokenPriceUpdates: []price_registry.InternalTokenPriceUpdate{ + { + SourceToken: state.Chains[from].LinkToken.Address(), + UsdPerToken: deployment.E18Mult(20), + }, + { + SourceToken: state.Chains[from].Weth9.Address(), + UsdPerToken: deployment.E18Mult(4000), + }, + }, + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: to, + UsdPerUnitGas: big.NewInt(2e12), + }, + }}) + if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { + return err + } + + // Enable dest in price registry + tx, err = state.Chains[from].PriceRegistry.ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, + []price_registry.PriceRegistryDestChainConfigArgs{ + { + DestChainSelector: to, + DestChainConfig: defaultPriceRegistryDestChainConfig(), + }, + }) + if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { + return err + } + + tx, err = state.Chains[to].EvmOffRampV160.ApplySourceChainConfigUpdates(e.Chains[to].DeployerKey, + []offramp.OffRampSourceChainConfigArgs{ + { + Router: state.Chains[to].Router.Address(), + SourceChainSelector: from, + IsEnabled: true, + OnRamp: common.LeftPadBytes(state.Chains[from].EvmOnRampV160.Address().Bytes(), 32), + }, + }) + if err := deployment.ConfirmIfNoError(e.Chains[to], tx, err); err != nil { + return err + } + tx, err = state.Chains[to].Router.ApplyRampUpdates(e.Chains[to].DeployerKey, []router.RouterOnRamp{}, []router.RouterOffRamp{}, []router.RouterOffRamp{ + { + SourceChainSelector: from, + OffRamp: state.Chains[to].EvmOffRampV160.Address(), + }, + }) + return deployment.ConfirmIfNoError(e.Chains[to], tx, err) +} + +func defaultPriceRegistryDestChainConfig() price_registry.PriceRegistryDestChainConfig { + // https://github.com/smartcontractkit/ccip/blob/c4856b64bd766f1ddbaf5d13b42d3c4b12efde3a/contracts/src/v0.8/ccip/libraries/Internal.sol#L337-L337 + /* + ```Solidity + // bytes4(keccak256("CCIP ChainFamilySelector EVM")) + bytes4 public constant CHAIN_FAMILY_SELECTOR_EVM = 0x2812d52c; + ``` + */ + evmFamilySelector, _ := hex.DecodeString("2812d52c") + return price_registry.PriceRegistryDestChainConfig{ + IsEnabled: true, + MaxNumberOfTokensPerMsg: 10, + MaxDataBytes: 256, + MaxPerMsgGasLimit: 3_000_000, + DestGasOverhead: 50_000, + DefaultTokenFeeUSDCents: 1, + DestGasPerPayloadByte: 10, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 100, + DestDataAvailabilityMultiplierBps: 1, + DefaultTokenDestGasOverhead: 125_000, + DefaultTxGasLimit: 200_000, + GasMultiplierWeiPerEth: 1, + NetworkFeeUSDCents: 1, + ChainFamilySelector: [4]byte(evmFamilySelector), + } +} From 0785c96fb65fdd016394fd9fd2f56cada1191317 Mon Sep 17 00:00:00 2001 From: dimitris Date: Tue, 27 Aug 2024 10:50:48 +0300 Subject: [PATCH 228/432] Bump chainlink-ccip to dev branch (#1365) Ref: https://github.com/smartcontractkit/chainlink-ccip/pull/78 --- core/capabilities/ccip/oraclecreator/inprocess.go | 2 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/capabilities/ccip/oraclecreator/inprocess.go b/core/capabilities/ccip/oraclecreator/inprocess.go index d705367d57..21e9bcec6d 100644 --- a/core/capabilities/ccip/oraclecreator/inprocess.go +++ b/core/capabilities/ccip/oraclecreator/inprocess.go @@ -28,7 +28,7 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" - commitocr3 "github.com/smartcontractkit/chainlink-ccip/commitrmnocb" + commitocr3 "github.com/smartcontractkit/chainlink-ccip/commit" execocr3 "github.com/smartcontractkit/chainlink-ccip/execute" ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 13ed1c4aa9..368cee79d9 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -274,7 +274,7 @@ require ( github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 468c13a670..7e684e245d 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1070,8 +1070,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f h1:lQZBOjeYFpCdk0mGQUhbrJipd00tu49xK4zSijC/9Co= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 h1:+Km1o8ApEv/DofxAa5MIPbkxXkKo4BG5u3GKLKB5FSI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/go.mod b/go.mod index 683793cb53..8a75274125 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa diff --git a/go.sum b/go.sum index 5ad6772ecd..d25f3d297a 100644 --- a/go.sum +++ b/go.sum @@ -1027,8 +1027,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f h1:lQZBOjeYFpCdk0mGQUhbrJipd00tu49xK4zSijC/9Co= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 h1:+Km1o8ApEv/DofxAa5MIPbkxXkKo4BG5u3GKLKB5FSI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index fd00d2c7ad..7e6b10aae4 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -35,7 +35,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 github.com/smartcontractkit/chainlink-testing-framework v1.33.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index dacfa7764e..c2ec1e83f4 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1378,8 +1378,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f h1:lQZBOjeYFpCdk0mGQUhbrJipd00tu49xK4zSijC/9Co= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 h1:+Km1o8ApEv/DofxAa5MIPbkxXkKo4BG5u3GKLKB5FSI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index a90826f599..2d81105f99 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -41,7 +41,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/testcontainers/testcontainers-go v0.28.0 // indirect k8s.io/apimachinery v0.30.2 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 536b96f8b6..f74595e42e 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1358,8 +1358,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f h1:lQZBOjeYFpCdk0mGQUhbrJipd00tu49xK4zSijC/9Co= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240816163757-48726fd8165f/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 h1:+Km1o8ApEv/DofxAa5MIPbkxXkKo4BG5u3GKLKB5FSI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= From 95c98d33b32d2aef82bd81a85b1a49c871101ee2 Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Tue, 27 Aug 2024 13:24:22 +0200 Subject: [PATCH 229/432] Rename PriceRegistry -> FeeQuoter (#1350) Rename the PriceRegistry to FeeQuoter. This PR restores the 1.2 PriceRegistry interface which is still used for CCIP 1.5. The FeeQuoter is a superset of that interface, which is why all tests can use the feeQuoter, even in 1.5. This PR does NOT claim to rename all offchain instances. It only handles onchain and wrapper/mock based references --- .mockery.yaml | 6 +- contracts/gas-snapshots/ccip.gas-snapshot | 273 +- .../scripts/native_solc_compile_all_ccip | 2 +- .../ccip/{PriceRegistry.sol => FeeQuoter.sol} | 43 +- .../v0.8/ccip/MultiAggregateRateLimiter.sol | 46 +- .../src/v0.8/ccip/interfaces/IFeeQuoter.sol | 54 + .../v0.8/ccip/interfaces/IPriceRegistry.sol | 11 - contracts/src/v0.8/ccip/offRamp/OffRamp.sol | 11 +- contracts/src/v0.8/ccip/onRamp/OnRamp.sol | 19 +- .../src/v0.8/ccip/test/NonceManager.t.sol | 2 +- .../ccip/test/commitStore/CommitStore.t.sol | 41 +- .../v0.8/ccip/test/e2e/MultiRampsEnd2End.sol | 2 +- .../FeeQuoter.t.sol} | 982 ++-- .../FeeQuoterSetup.t.sol} | 129 +- ...RegistryHelper.sol => FeeQuoterHelper.sol} | 6 +- .../MultiAggregateRateLimiterHelper.sol | 4 +- .../ccip/test/offRamp/EVM2EVMOffRamp.t.sol | 10 +- .../test/offRamp/EVM2EVMOffRampSetup.t.sol | 11 +- .../src/v0.8/ccip/test/offRamp/OffRamp.t.sol | 49 +- .../v0.8/ccip/test/offRamp/OffRampSetup.t.sol | 27 +- .../v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol | 16 +- .../ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol | 13 +- .../src/v0.8/ccip/test/onRamp/OnRamp.t.sol | 64 +- .../v0.8/ccip/test/onRamp/OnRampSetup.t.sol | 13 +- .../rateLimiter/AggregateRateLimiter.t.sol | 13 +- .../MultiAggregateRateLimiter.t.sol | 41 +- .../src/v0.8/ccip/test/router/Router.t.sol | 6 +- .../ccip/ccip_integration_tests/helpers.go | 44 +- .../ccip/configs/evm/contract_reader.go | 8 +- .../fee_quoter.go} | 1336 ++--- .../multi_aggregate_rate_limiter.go | 214 +- .../ccip/generated/offramp/offramp.go | 4 +- .../ccip/generated/onramp/onramp.go | 4 +- ...rapper-dependency-versions-do-not-edit.txt | 7 +- core/gethwrappers/ccip/go_generate.go | 2 +- .../ccip/mocks/fee_quoter_interface.go | 4509 +++++++++++++++++ .../ccip/mocks/price_registry_interface.go | 4509 ----------------- .../ccip/revert-reason/handler/reason.go | 4 +- .../internal/ccipdata/v1_2_0/test_helpers.go | 14 +- .../ccip-tests/actions/ccip_helpers.go | 6 +- .../ccip-tests/contracts/contract_models.go | 24 +- integration-tests/deployment/ccip/add_lane.go | 15 +- integration-tests/deployment/ccip/deploy.go | 637 +-- integration-tests/deployment/ccip/state.go | 291 +- 44 files changed, 6705 insertions(+), 6817 deletions(-) rename contracts/src/v0.8/ccip/{PriceRegistry.sol => FeeQuoter.sol} (97%) create mode 100644 contracts/src/v0.8/ccip/interfaces/IFeeQuoter.sol rename contracts/src/v0.8/ccip/test/{priceRegistry/PriceRegistry.t.sol => feeQuoter/FeeQuoter.t.sol} (60%) rename contracts/src/v0.8/ccip/test/{priceRegistry/PriceRegistrySetup.t.sol => feeQuoter/FeeQuoterSetup.t.sol} (76%) rename contracts/src/v0.8/ccip/test/helpers/{PriceRegistryHelper.sol => FeeQuoterHelper.sol} (95%) rename core/gethwrappers/ccip/generated/{price_registry/price_registry.go => fee_quoter/fee_quoter.go} (54%) create mode 100644 core/gethwrappers/ccip/mocks/fee_quoter_interface.go delete mode 100644 core/gethwrappers/ccip/mocks/price_registry_interface.go diff --git a/.mockery.yaml b/.mockery.yaml index 5cba66f3da..d21fbb467f 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -375,13 +375,13 @@ packages: outpkg: mock_contracts interfaces: CommitStoreInterface: - github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry: + github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter: config: dir: core/gethwrappers/ccip/mocks/ - filename: price_registry_interface.go + filename: fee_quoter_interface.go outpkg: mock_contracts interfaces: - PriceRegistryInterface: + FeeQuoterInterface: github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface: config: dir: core/gethwrappers/ccip/mocks/ diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index a573668aa9..af1f296236 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -327,6 +327,110 @@ EtherSenderReceiverTest_validatedMessage:test_validatedMessage_emptyDataOverwrit EtherSenderReceiverTest_validatedMessage:test_validatedMessage_invalidTokenAmounts() (gas: 17895) EtherSenderReceiverTest_validatedMessage:test_validatedMessage_tokenOverwrittenToWeth() (gas: 25287) EtherSenderReceiverTest_validatedMessage:test_validatedMessage_validMessage_extraArgs() (gas: 26292) +FeeQuoter_applyDestChainConfigUpdates:test_InvalidChainFamilySelector_Revert() (gas: 16503) +FeeQuoter_applyDestChainConfigUpdates:test_InvalidDestChainConfigDestChainSelectorEqZero_Revert() (gas: 16417) +FeeQuoter_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitEqZero_Revert() (gas: 16459) +FeeQuoter_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitGtMaxPerMessageGasLimit_Revert() (gas: 39957) +FeeQuoter_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesZeroIntput_Success() (gas: 12342) +FeeQuoter_applyDestChainConfigUpdates:test_applyDestChainConfigUpdates_Success() (gas: 135870) +FeeQuoter_applyFeeTokensUpdates:test_ApplyFeeTokensUpdates_Success() (gas: 79896) +FeeQuoter_applyFeeTokensUpdates:test_OnlyCallableByOwner_Revert() (gas: 12603) +FeeQuoter_applyPremiumMultiplierWeiPerEthUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 11421) +FeeQuoter_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesMultipleTokens_Success() (gas: 54105) +FeeQuoter_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesSingleToken_Success() (gas: 44791) +FeeQuoter_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesZeroInput() (gas: 12257) +FeeQuoter_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfig_Success() (gas: 86926) +FeeQuoter_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeZeroInput() (gas: 13089) +FeeQuoter_applyTokenTransferFeeConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 17071) +FeeQuoter_applyTokenTransferFeeConfigUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 12240) +FeeQuoter_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 107016) +FeeQuoter_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 111366) +FeeQuoter_constructor:test_InvalidStalenessThreshold_Revert() (gas: 111419) +FeeQuoter_constructor:test_Setup_Success() (gas: 5336824) +FeeQuoter_convertTokenAmount:test_ConvertTokenAmount_Success() (gas: 72739) +FeeQuoter_convertTokenAmount:test_LinkTokenNotSupported_Revert() (gas: 30963) +FeeQuoter_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 94303) +FeeQuoter_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCostUnsupportedDestChainSelector_Success() (gas: 14614) +FeeQuoter_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20410) +FeeQuoter_getTokenAndGasPrices:test_GetFeeTokenAndGasPrices_Success() (gas: 70443) +FeeQuoter_getTokenAndGasPrices:test_StaleGasPrice_Revert() (gas: 16838) +FeeQuoter_getTokenAndGasPrices:test_UnsupportedChain_Revert() (gas: 16140) +FeeQuoter_getTokenAndGasPrices:test_ZeroGasPrice_Success() (gas: 45750) +FeeQuoter_getTokenPrice:test_GetTokenPriceFromFeed_Success() (gas: 62252) +FeeQuoter_getTokenPrices:test_GetTokenPrices_Success() (gas: 84800) +FeeQuoter_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 41227) +FeeQuoter_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 34682) +FeeQuoter_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 27756) +FeeQuoter_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 101624) +FeeQuoter_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 20354) +FeeQuoter_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 27631) +FeeQuoter_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 27587) +FeeQuoter_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 40013) +FeeQuoter_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29299) +FeeQuoter_getValidatedFee:test_DestinationChainNotEnabled_Revert() (gas: 18180) +FeeQuoter_getValidatedFee:test_EmptyMessage_Success() (gas: 81054) +FeeQuoter_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 54294) +FeeQuoter_getValidatedFee:test_HighGasMessage_Success() (gas: 237472) +FeeQuoter_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 19949) +FeeQuoter_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 31746) +FeeQuoter_getValidatedFee:test_MessageTooLarge_Revert() (gas: 97692) +FeeQuoter_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 142833) +FeeQuoter_getValidatedFee:test_NotAFeeToken_Revert() (gas: 29407) +FeeQuoter_getValidatedFee:test_SingleTokenMessage_Success() (gas: 111861) +FeeQuoter_getValidatedFee:test_TooManyTokens_Revert() (gas: 20085) +FeeQuoter_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 61933) +FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Above18Decimals_Success() (gas: 2094539) +FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Below18Decimals_Success() (gas: 2094497) +FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt0Decimals_Success() (gas: 2074616) +FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt18Decimals_Success() (gas: 2094271) +FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFlippedDecimals_Success() (gas: 2094475) +FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedMaxInt224Value_Success() (gas: 2094287) +FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedOverStalenessPeriod_Success() (gas: 62004) +FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeed_Success() (gas: 61884) +FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPrice_Success() (gas: 61036) +FeeQuoter_getValidatedTokenPrice:test_OverflowFeedPrice_Revert() (gas: 2093974) +FeeQuoter_getValidatedTokenPrice:test_StaleFeeToken_Success() (gas: 61563) +FeeQuoter_getValidatedTokenPrice:test_TokenNotSupportedFeed_Revert() (gas: 109120) +FeeQuoter_getValidatedTokenPrice:test_TokenNotSupported_Revert() (gas: 13857) +FeeQuoter_getValidatedTokenPrice:test_UnderflowFeedPrice_Revert() (gas: 2092636) +FeeQuoter_onReport:test_OnReport_StaleUpdate_Revert() (gas: 43334) +FeeQuoter_onReport:test_onReport_InvalidForwarder_Reverts() (gas: 23294) +FeeQuoter_onReport:test_onReport_Success() (gas: 80639) +FeeQuoter_onReport:test_onReport_UnsupportedToken_Reverts() (gas: 26677) +FeeQuoter_parseEVMExtraArgsFromBytes:test_EVMExtraArgsDefault_Success() (gas: 17185) +FeeQuoter_parseEVMExtraArgsFromBytes:test_EVMExtraArgsEnforceOutOfOrder_Revert() (gas: 21290) +FeeQuoter_parseEVMExtraArgsFromBytes:test_EVMExtraArgsGasLimitTooHigh_Revert() (gas: 18387) +FeeQuoter_parseEVMExtraArgsFromBytes:test_EVMExtraArgsInvalidExtraArgsTag_Revert() (gas: 17911) +FeeQuoter_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV1_Success() (gas: 18285) +FeeQuoter_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV2_Success() (gas: 18401) +FeeQuoter_processMessageArgs:test_InvalidExtraArgs_Revert() (gas: 18361) +FeeQuoter_processMessageArgs:test_MalformedEVMExtraArgs_Revert() (gas: 18907) +FeeQuoter_processMessageArgs:test_MessageFeeTooHigh_Revert() (gas: 16426) +FeeQuoter_processMessageArgs:test_WitEVMExtraArgsV2_Success() (gas: 26269) +FeeQuoter_processMessageArgs:test_WithConvertedTokenAmount_Success() (gas: 32441) +FeeQuoter_processMessageArgs:test_WithEVMExtraArgsV1_Success() (gas: 25881) +FeeQuoter_processMessageArgs:test_WithEmptyEVMExtraArgs_Success() (gas: 23696) +FeeQuoter_processMessageArgs:test_WithLinkTokenAmount_Success() (gas: 17375) +FeeQuoter_updatePrices:test_OnlyCallableByUpdater_Revert() (gas: 12102) +FeeQuoter_updatePrices:test_OnlyGasPrice_Success() (gas: 23599) +FeeQuoter_updatePrices:test_OnlyTokenPrice_Success() (gas: 30631) +FeeQuoter_updatePrices:test_UpdatableByAuthorizedCaller_Success() (gas: 76003) +FeeQuoter_updatePrices:test_UpdateMultiplePrices_Success() (gas: 151393) +FeeQuoter_updateTokenPriceFeeds:test_FeedNotUpdated() (gas: 50527) +FeeQuoter_updateTokenPriceFeeds:test_FeedUnset_Success() (gas: 63626) +FeeQuoter_updateTokenPriceFeeds:test_FeedUpdatedByNonOwner_Revert() (gas: 19932) +FeeQuoter_updateTokenPriceFeeds:test_MultipleFeedUpdate_Success() (gas: 88972) +FeeQuoter_updateTokenPriceFeeds:test_SingleFeedUpdate_Success() (gas: 50821) +FeeQuoter_updateTokenPriceFeeds:test_ZeroFeeds_Success() (gas: 12296) +FeeQuoter_validateDestFamilyAddress:test_InvalidEVMAddressEncodePacked_Revert() (gas: 10616) +FeeQuoter_validateDestFamilyAddress:test_InvalidEVMAddressPrecompiles_Revert() (gas: 3961646) +FeeQuoter_validateDestFamilyAddress:test_InvalidEVMAddress_Revert() (gas: 10800) +FeeQuoter_validateDestFamilyAddress:test_ValidEVMAddress_Success() (gas: 6704) +FeeQuoter_validateDestFamilyAddress:test_ValidNonEVMAddress_Success() (gas: 6484) +FeeQuoter_validatePoolReturnData:test_InvalidEVMAddressDestToken_Revert() (gas: 42748) +FeeQuoter_validatePoolReturnData:test_ProcessPoolReturnData_Success() (gas: 73252) +FeeQuoter_validatePoolReturnData:test_SourceTokenDataTooLarge_Revert() (gas: 107744) +FeeQuoter_validatePoolReturnData:test_TokenAmountArraysMismatching_Revert() (gas: 40091) LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Revert() (gas: 10970) LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Success() (gas: 17992) LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3368110) @@ -372,42 +476,42 @@ MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_UpdateExistingConfi MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_UpdateExistingConfig_Success() (gas: 53092) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_ZeroChainSelector_Revert() (gas: 17019) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_ZeroConfigs_Success() (gas: 12295) -MultiAggregateRateLimiter_constructor:test_ConstructorNoAuthorizedCallers_Success() (gas: 2149637) -MultiAggregateRateLimiter_constructor:test_Constructor_Success() (gas: 2265894) +MultiAggregateRateLimiter_constructor:test_ConstructorNoAuthorizedCallers_Success() (gas: 2149547) +MultiAggregateRateLimiter_constructor:test_Constructor_Success() (gas: 2265849) MultiAggregateRateLimiter_getTokenBucket:test_GetTokenBucket_Success() (gas: 30248) MultiAggregateRateLimiter_getTokenBucket:test_Refill_Success() (gas: 47358) MultiAggregateRateLimiter_getTokenBucket:test_TimeUnderflow_Revert() (gas: 15821) -MultiAggregateRateLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19684) -MultiAggregateRateLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21269) +MultiAggregateRateLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19662) +MultiAggregateRateLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21247) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 14527) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213660) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 60459) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213638) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 60437) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 17593) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitDisabled_Success() (gas: 44895) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExceeded_Revert() (gas: 50542) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78668) -MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 311949) +MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 311927) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54728) MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 9223372036854754743) -MultiAggregateRateLimiter_onOutboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 19104) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 15778) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213648) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 62194) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitDisabled_Success() (gas: 46683) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitExceeded_Revert() (gas: 52315) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitReset_Success() (gas: 79733) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 312163) -MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokens_Success() (gas: 56485) -MultiAggregateRateLimiter_setPriceRegistry:test_OnlyOwner_Revert() (gas: 11292) -MultiAggregateRateLimiter_setPriceRegistry:test_Owner_Success() (gas: 19080) -MultiAggregateRateLimiter_setPriceRegistry:test_ZeroAddress_Revert() (gas: 10564) -MultiAggregateRateLimiter_updateRateLimitTokens:test_NonOwner_Revert() (gas: 18872) -MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensMultipleChains_Success() (gas: 279906) -MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensSingleChain_Success() (gas: 254501) +MultiAggregateRateLimiter_onOutboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 19149) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 15823) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213716) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDisabledRateLimitToken_Success() (gas: 62217) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitDisabled_Success() (gas: 46728) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitExceeded_Revert() (gas: 52360) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithRateLimitReset_Success() (gas: 79913) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 312231) +MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithTokens_Success() (gas: 56530) +MultiAggregateRateLimiter_setFeeQuoter:test_OnlyOwner_Revert() (gas: 11313) +MultiAggregateRateLimiter_setFeeQuoter:test_Owner_Success() (gas: 19066) +MultiAggregateRateLimiter_setFeeQuoter:test_ZeroAddress_Revert() (gas: 10585) +MultiAggregateRateLimiter_updateRateLimitTokens:test_NonOwner_Revert() (gas: 18850) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensMultipleChains_Success() (gas: 279972) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokensSingleChain_Success() (gas: 254523) MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_AddsAndRemoves_Success() (gas: 204488) -MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_RemoveNonExistentToken_Success() (gas: 28681) -MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroDestToken_Revert() (gas: 18309) -MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroSourceToken_Revert() (gas: 18238) +MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_RemoveNonExistentToken_Success() (gas: 28703) +MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroDestToken_Revert() (gas: 18287) +MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroSourceToken_Revert() (gas: 18216) MultiOCR3Base_setOCR3Configs:test_FMustBePositive_Revert() (gas: 59331) MultiOCR3Base_setOCR3Configs:test_FTooHigh_Revert() (gas: 44298) MultiOCR3Base_setOCR3Configs:test_RepeatSignerAddress_Revert() (gas: 283711) @@ -438,7 +542,7 @@ MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) -MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 410740) +MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 410714) MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1486877) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) @@ -608,10 +712,10 @@ OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 177934) OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 191136) OffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11423) OffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215351) -OffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14097) -OffRamp_setDynamicConfig:test_PriceRegistryZeroAddress_Revert() (gas: 11617) -OffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49137) -OffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27081) +OffRamp_setDynamicConfig:test_FeeQuoterZeroAddress_Revert() (gas: 11585) +OffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14130) +OffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49093) +OffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27103) OffRamp_trialExecute:test_RateLimitError_Success() (gas: 225773) OffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 234394) OffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 309206) @@ -649,7 +753,7 @@ OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 144094) OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3887491) OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108659) OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 74066) -OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 273429) +OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 273416) OnRamp_getFee:test_EmptyMessage_Success() (gas: 104351) OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 73173) OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119675) @@ -657,119 +761,16 @@ OnRamp_getFee:test_Unhealthy_Revert() (gas: 43679) OnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10438) OnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35270) OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11155) -OnRamp_setDynamicConfig:test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() (gas: 12740) +OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeQuoterEqAddressZero_Revert() (gas: 12763) OnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11112) OnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939) -OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 51996) +OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 52018) OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97192) PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150169) PingPong_plumbing:test_OutOfOrderExecution_Success() (gas: 20277) PingPong_plumbing:test_Pausing_Success() (gas: 17777) PingPong_startPingPong:test_StartPingPong_With_OOO_Success() (gas: 163187) PingPong_startPingPong:test_StartPingPong_With_Sequenced_Ordered_Success() (gas: 182599) -PriceRegistry_applyDestChainConfigUpdates:test_InvalidChainFamilySelector_Revert() (gas: 16503) -PriceRegistry_applyDestChainConfigUpdates:test_InvalidDestChainConfigDestChainSelectorEqZero_Revert() (gas: 16417) -PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitEqZero_Revert() (gas: 16459) -PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesDefaultTxGasLimitGtMaxPerMessageGasLimit_Revert() (gas: 39957) -PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdatesZeroIntput_Success() (gas: 12342) -PriceRegistry_applyDestChainConfigUpdates:test_applyDestChainConfigUpdates_Success() (gas: 135870) -PriceRegistry_applyFeeTokensUpdates:test_ApplyFeeTokensUpdates_Success() (gas: 79896) -PriceRegistry_applyFeeTokensUpdates:test_OnlyCallableByOwner_Revert() (gas: 12603) -PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 11421) -PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesMultipleTokens_Success() (gas: 54105) -PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesSingleToken_Success() (gas: 44791) -PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates:test_applyPremiumMultiplierWeiPerEthUpdatesZeroInput() (gas: 12257) -PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfig_Success() (gas: 86926) -PriceRegistry_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeZeroInput() (gas: 13089) -PriceRegistry_applyTokenTransferFeeConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 17071) -PriceRegistry_applyTokenTransferFeeConfigUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 12240) -PriceRegistry_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 107016) -PriceRegistry_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 111366) -PriceRegistry_constructor:test_InvalidStalenessThreshold_Revert() (gas: 111419) -PriceRegistry_constructor:test_Setup_Success() (gas: 5336824) -PriceRegistry_convertTokenAmount:test_ConvertTokenAmount_Success() (gas: 72739) -PriceRegistry_convertTokenAmount:test_LinkTokenNotSupported_Revert() (gas: 30963) -PriceRegistry_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 94303) -PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCostUnsupportedDestChainSelector_Success() (gas: 14614) -PriceRegistry_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20410) -PriceRegistry_getTokenAndGasPrices:test_GetFeeTokenAndGasPrices_Success() (gas: 70443) -PriceRegistry_getTokenAndGasPrices:test_StaleGasPrice_Revert() (gas: 16838) -PriceRegistry_getTokenAndGasPrices:test_UnsupportedChain_Revert() (gas: 16140) -PriceRegistry_getTokenAndGasPrices:test_ZeroGasPrice_Success() (gas: 45750) -PriceRegistry_getTokenPrice:test_GetTokenPriceFromFeed_Success() (gas: 62252) -PriceRegistry_getTokenPrices:test_GetTokenPrices_Success() (gas: 84800) -PriceRegistry_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 41227) -PriceRegistry_getTokenTransferCost:test_FeeTokenBpsFee_Success() (gas: 34682) -PriceRegistry_getTokenTransferCost:test_LargeTokenTransferChargesMaxFeeAndGas_Success() (gas: 27756) -PriceRegistry_getTokenTransferCost:test_MixedTokenTransferFee_Success() (gas: 101624) -PriceRegistry_getTokenTransferCost:test_NoTokenTransferChargesZeroFee_Success() (gas: 20354) -PriceRegistry_getTokenTransferCost:test_SmallTokenTransferChargesMinFeeAndGas_Success() (gas: 27631) -PriceRegistry_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() (gas: 27587) -PriceRegistry_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 40013) -PriceRegistry_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29299) -PriceRegistry_getValidatedFee:test_DestinationChainNotEnabled_Revert() (gas: 18180) -PriceRegistry_getValidatedFee:test_EmptyMessage_Success() (gas: 81054) -PriceRegistry_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 54294) -PriceRegistry_getValidatedFee:test_HighGasMessage_Success() (gas: 237472) -PriceRegistry_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 19949) -PriceRegistry_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 31746) -PriceRegistry_getValidatedFee:test_MessageTooLarge_Revert() (gas: 97692) -PriceRegistry_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 142833) -PriceRegistry_getValidatedFee:test_NotAFeeToken_Revert() (gas: 29407) -PriceRegistry_getValidatedFee:test_SingleTokenMessage_Success() (gas: 111861) -PriceRegistry_getValidatedFee:test_TooManyTokens_Revert() (gas: 20085) -PriceRegistry_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 61933) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Above18Decimals_Success() (gas: 2094539) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Below18Decimals_Success() (gas: 2094497) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt0Decimals_Success() (gas: 2074616) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt18Decimals_Success() (gas: 2094271) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFlippedDecimals_Success() (gas: 2094475) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedMaxInt224Value_Success() (gas: 2094287) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedOverStalenessPeriod_Success() (gas: 62004) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeed_Success() (gas: 61884) -PriceRegistry_getValidatedTokenPrice:test_GetValidatedTokenPrice_Success() (gas: 61036) -PriceRegistry_getValidatedTokenPrice:test_OverflowFeedPrice_Revert() (gas: 2093974) -PriceRegistry_getValidatedTokenPrice:test_StaleFeeToken_Success() (gas: 61563) -PriceRegistry_getValidatedTokenPrice:test_TokenNotSupportedFeed_Revert() (gas: 109120) -PriceRegistry_getValidatedTokenPrice:test_TokenNotSupported_Revert() (gas: 13857) -PriceRegistry_getValidatedTokenPrice:test_UnderflowFeedPrice_Revert() (gas: 2092636) -PriceRegistry_onReport:test_OnReport_StaleUpdate_Revert() (gas: 43359) -PriceRegistry_onReport:test_onReport_InvalidForwarder_Reverts() (gas: 23261) -PriceRegistry_onReport:test_onReport_Success() (gas: 80666) -PriceRegistry_onReport:test_onReport_UnsupportedToken_Reverts() (gas: 26675) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsDefault_Success() (gas: 17185) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsEnforceOutOfOrder_Revert() (gas: 21290) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsGasLimitTooHigh_Revert() (gas: 18387) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsInvalidExtraArgsTag_Revert() (gas: 17911) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV1_Success() (gas: 18285) -PriceRegistry_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV2_Success() (gas: 18401) -PriceRegistry_processMessageArgs:test_InvalidExtraArgs_Revert() (gas: 18361) -PriceRegistry_processMessageArgs:test_MalformedEVMExtraArgs_Revert() (gas: 18907) -PriceRegistry_processMessageArgs:test_MessageFeeTooHigh_Revert() (gas: 16426) -PriceRegistry_processMessageArgs:test_WitEVMExtraArgsV2_Success() (gas: 26269) -PriceRegistry_processMessageArgs:test_WithConvertedTokenAmount_Success() (gas: 32441) -PriceRegistry_processMessageArgs:test_WithEVMExtraArgsV1_Success() (gas: 25881) -PriceRegistry_processMessageArgs:test_WithEmptyEVMExtraArgs_Success() (gas: 23696) -PriceRegistry_processMessageArgs:test_WithLinkTokenAmount_Success() (gas: 17375) -PriceRegistry_processPoolReturnData:test_InvalidEVMAddressDestToken_Revert() (gas: 42784) -PriceRegistry_processPoolReturnData:test_SourceTokenDataTooLarge_Revert() (gas: 107735) -PriceRegistry_processPoolReturnData:test_TokenAmountArraysMismatching_Revert() (gas: 40104) -PriceRegistry_updatePrices:test_OnlyCallableByUpdater_Revert() (gas: 12102) -PriceRegistry_updatePrices:test_OnlyGasPrice_Success() (gas: 23599) -PriceRegistry_updatePrices:test_OnlyTokenPrice_Success() (gas: 30631) -PriceRegistry_updatePrices:test_UpdatableByAuthorizedCaller_Success() (gas: 76003) -PriceRegistry_updatePrices:test_UpdateMultiplePrices_Success() (gas: 151393) -PriceRegistry_updateTokenPriceFeeds:test_FeedNotUpdated() (gas: 50527) -PriceRegistry_updateTokenPriceFeeds:test_FeedUnset_Success() (gas: 63626) -PriceRegistry_updateTokenPriceFeeds:test_FeedUpdatedByNonOwner_Revert() (gas: 19932) -PriceRegistry_updateTokenPriceFeeds:test_MultipleFeedUpdate_Success() (gas: 88972) -PriceRegistry_updateTokenPriceFeeds:test_SingleFeedUpdate_Success() (gas: 50821) -PriceRegistry_updateTokenPriceFeeds:test_ZeroFeeds_Success() (gas: 12296) -PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddressEncodePacked_Revert() (gas: 10616) -PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddressPrecompiles_Revert() (gas: 3961646) -PriceRegistry_validateDestFamilyAddress:test_InvalidEVMAddress_Revert() (gas: 10800) -PriceRegistry_validateDestFamilyAddress:test_ValidEVMAddress_Success() (gas: 6704) -PriceRegistry_validateDestFamilyAddress:test_ValidNonEVMAddress_Success() (gas: 6484) RMNHome:test() (gas: 186) RMN_constructor:test_Constructor_Success() (gas: 48838) RMN_getRecordedCurseRelatedOps:test_OpsPostDeployment() (gas: 19666) diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index 885b701279..21f4014cf7 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -62,7 +62,7 @@ compileContract ccip/onRamp/EVM2EVMOnRamp.sol compileContract ccip/CommitStore.sol compileContract ccip/MultiAggregateRateLimiter.sol compileContract ccip/Router.sol -compileContract ccip/PriceRegistry.sol +compileContract ccip/FeeQuoter.sol compileContract ccip/RMN.sol compileContract ccip/ARMProxy.sol compileContract ccip/tokenAdminRegistry/TokenAdminRegistry.sol diff --git a/contracts/src/v0.8/ccip/PriceRegistry.sol b/contracts/src/v0.8/ccip/FeeQuoter.sol similarity index 97% rename from contracts/src/v0.8/ccip/PriceRegistry.sol rename to contracts/src/v0.8/ccip/FeeQuoter.sol index 8593568371..c2a7231d96 100644 --- a/contracts/src/v0.8/ccip/PriceRegistry.sol +++ b/contracts/src/v0.8/ccip/FeeQuoter.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.24; import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; +import {IFeeQuoter} from "./interfaces/IFeeQuoter.sol"; import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol"; import {AuthorizedCallers} from "../shared/access/AuthorizedCallers.sol"; @@ -16,18 +17,12 @@ import {IReceiver} from "../keystone/interfaces/IReceiver.sol"; import {KeystoneFeedDefaultMetadataLib} from "../keystone/lib/KeystoneFeedDefaultMetadataLib.sol"; import {EnumerableSet} from "../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; -/// @notice The PriceRegistry contract responsibility is to: +/// @notice The FeeQuoter contract responsibility is to: /// - Store the current gas price in USD for a given destination chain, /// - Store the price of a token in USD allowing the owner or priceUpdater to update this value. /// - Manage chain specific fee calculations. /// The authorized callers in the contract represent the fee price updaters. -contract PriceRegistry is - AuthorizedCallers, - IPriceRegistry, - ITypeAndVersion, - IReceiver, - KeystoneFeedsPermissionHandler -{ +contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, KeystoneFeedsPermissionHandler { using EnumerableSet for EnumerableSet.AddressSet; using USDPriceWith18Decimals for uint224; using KeystoneFeedDefaultMetadataLib for bytes; @@ -53,7 +48,7 @@ contract PriceRegistry is event FeeTokenRemoved(address indexed feeToken); event UsdPerUnitGasUpdated(uint64 indexed destChain, uint256 value, uint256 timestamp); event UsdPerTokenUpdated(address indexed token, uint256 value, uint256 timestamp); - event PriceFeedPerTokenUpdated(address indexed token, IPriceRegistry.TokenPriceFeedConfig priceFeedConfig); + event PriceFeedPerTokenUpdated(address indexed token, IFeeQuoter.TokenPriceFeedConfig priceFeedConfig); event TokenTransferFeeConfigUpdated( uint64 indexed destChainSelector, address indexed token, TokenTransferFeeConfig tokenTransferFeeConfig ); @@ -65,7 +60,7 @@ contract PriceRegistry is /// @notice Token price data feed update struct TokenPriceFeedUpdate { address sourceToken; // Source token to update feed for - IPriceRegistry.TokenPriceFeedConfig feedConfig; // Feed config update data + IFeeQuoter.TokenPriceFeedConfig feedConfig; // Feed config update data } /// @dev Struct that contains the static configuration @@ -155,7 +150,7 @@ contract PriceRegistry is uint64 premiumMultiplierWeiPerEth; // ──╯ Multiplier for destination chain specific premiums. Should never be 0 so can be used as an isEnabled flag } - string public constant override typeAndVersion = "PriceRegistry 1.6.0-dev"; + string public constant override typeAndVersion = "FeeQuoter 1.6.0-dev"; /// @dev The gas price per unit of gas for a given destination chain, in USD with 18 decimals. /// Multiple gas prices can be encoded into the same value. Each price takes {Internal.GAS_PRICE_BITS} bits. @@ -176,7 +171,7 @@ contract PriceRegistry is mapping(address token => Internal.TimestampedPackedUint224 price) private s_usdPerToken; /// @dev Stores the price data feed configurations per token. - mapping(address token => IPriceRegistry.TokenPriceFeedConfig dataFeedAddress) private s_usdPriceFeedsPerToken; + mapping(address token => IFeeQuoter.TokenPriceFeedConfig dataFeedAddress) private s_usdPriceFeedsPerToken; /// @dev The multiplier for destination chain specific premiums that can be set by the owner or fee admin /// This should never be 0 once set, so it can be used as an isEnabled flag @@ -232,7 +227,7 @@ contract PriceRegistry is /// @inheritdoc IPriceRegistry function getTokenPrice(address token) public view override returns (Internal.TimestampedPackedUint224 memory) { - IPriceRegistry.TokenPriceFeedConfig memory priceFeedConfig = s_usdPriceFeedsPerToken[token]; + IFeeQuoter.TokenPriceFeedConfig memory priceFeedConfig = s_usdPriceFeedsPerToken[token]; if (priceFeedConfig.dataFeedAddress == address(0)) { return s_usdPerToken[token]; } @@ -260,12 +255,12 @@ contract PriceRegistry is return tokenPrices; } - /// @inheritdoc IPriceRegistry + /// @inheritdoc IFeeQuoter function getTokenPriceFeedConfig(address token) external view override - returns (IPriceRegistry.TokenPriceFeedConfig memory) + returns (IFeeQuoter.TokenPriceFeedConfig memory) { return s_usdPriceFeedsPerToken[token]; } @@ -324,7 +319,7 @@ contract PriceRegistry is /// @notice Gets the token price from a data feed address, rebased to the same units as s_usdPerToken /// @param priceFeedConfig token data feed configuration with valid data feed address (used to retrieve price & timestamp) /// @return tokenPrice data feed price answer rebased to s_usdPerToken units, with latest block timestamp - function _getTokenPriceFromDataFeed(IPriceRegistry.TokenPriceFeedConfig memory priceFeedConfig) + function _getTokenPriceFromDataFeed(IFeeQuoter.TokenPriceFeedConfig memory priceFeedConfig) internal view returns (Internal.TimestampedPackedUint224 memory tokenPrice) @@ -347,7 +342,7 @@ contract PriceRegistry is uint224 rebasedValue = _calculateRebasedValue(dataFeedContract.decimals(), priceFeedConfig.tokenDecimals, uint256(dataFeedAnswer)); - // Data feed staleness is unchecked to decouple the PriceRegistry from data feed delay issues + // Data feed staleness is unchecked to decouple the FeeQuoter from data feed delay issues return Internal.TimestampedPackedUint224({value: rebasedValue, timestamp: uint32(block.timestamp)}); } @@ -428,7 +423,7 @@ contract PriceRegistry is for (uint256 i; i < tokenPriceFeedUpdates.length; ++i) { TokenPriceFeedUpdate memory update = tokenPriceFeedUpdates[i]; address sourceToken = update.sourceToken; - IPriceRegistry.TokenPriceFeedConfig memory tokenPriceFeedConfig = update.feedConfig; + IFeeQuoter.TokenPriceFeedConfig memory tokenPriceFeedConfig = update.feedConfig; s_usdPriceFeedsPerToken[sourceToken] = tokenPriceFeedConfig; emit PriceFeedPerTokenUpdated(sourceToken, tokenPriceFeedConfig); @@ -470,7 +465,7 @@ contract PriceRegistry is // │ Fee quoting │ // ================================================================ - /// @inheritdoc IPriceRegistry + /// @inheritdoc IFeeQuoter /// @dev The function should always validate message.extraArgs, message.receiver and family-specific configs function getValidatedFee( uint64 destChainSelector, @@ -606,7 +601,7 @@ contract PriceRegistry is uint256 bpsFeeUSDWei = 0; // Only calculate bps fee if ratio is greater than 0. Ratio of 0 means no bps fee for a token. - // Useful for when the PriceRegistry cannot return a valid price for the token. + // Useful for when the FeeQuoter cannot return a valid price for the token. if (transferFeeConfig.deciBps > 0) { uint224 tokenPrice = 0; if (tokenAmount.token != feeToken) { @@ -839,7 +834,7 @@ contract PriceRegistry is _validateDestFamilyAddress(destChainConfig.chainFamilySelector, receiver); } - /// @inheritdoc IPriceRegistry + /// @inheritdoc IFeeQuoter function processMessageArgs( uint64 destChainSelector, address feeToken, @@ -864,7 +859,7 @@ contract PriceRegistry is return (msgFeeJuels, isOutOfOrderExecution, Client._argsToBytes(parsedExtraArgs)); } - /// @inheritdoc IPriceRegistry + /// @inheritdoc IFeeQuoter /// @dev precondition - rampTokenAmounts and sourceTokenAmounts lengths must be equal function processPoolReturnData( uint64 destChainSelector, @@ -887,7 +882,7 @@ contract PriceRegistry is } _validateDestFamilyAddress(chainFamilySelector, rampTokenAmounts[i].destTokenAddress); - PriceRegistry.TokenTransferFeeConfig memory tokenTransferFeeConfig = + FeeQuoter.TokenTransferFeeConfig memory tokenTransferFeeConfig = s_tokenTransferFeeConfig[destChainSelector][sourceToken]; uint32 defaultGasOverhead = s_destChainConfigs[destChainSelector].defaultTokenDestGasOverhead; // NOTE: Revisit this when adding new non-EVM chain family selector support @@ -945,7 +940,7 @@ contract PriceRegistry is } } - /// @notice Returns the static PriceRegistry config. + /// @notice Returns the static FeeQuoter config. /// @dev RMN depends on this function, if updated, please notify the RMN maintainers. /// @return staticConfig The static configuration. function getStaticConfig() external view returns (StaticConfig memory) { diff --git a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol index 13ba582a2b..0f1e9b9702 100644 --- a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol +++ b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.24; import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; +import {IFeeQuoter} from "./interfaces/IFeeQuoter.sol"; import {IMessageInterceptor} from "./interfaces/IMessageInterceptor.sol"; -import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol"; import {AuthorizedCallers} from "../shared/access/AuthorizedCallers.sol"; import {EnumerableMapAddresses} from "./../shared/enumerable/EnumerableMapAddresses.sol"; @@ -13,7 +13,7 @@ import {USDPriceWith18Decimals} from "./libraries/USDPriceWith18Decimals.sol"; /// @notice The aggregate rate limiter is a wrapper of the token bucket rate limiter /// which permits rate limiting based on the aggregate value of a group of -/// token transfers, using a price registry to convert to a numeraire asset (e.g. USD). +/// token transfers, using a fee quoter to convert to a numeraire asset (e.g. USD). /// The contract is a standalone multi-lane message validator contract, which can be called by authorized /// ramp contracts to apply rate limit changes to lanes, and revert when the rate limits get breached. contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, ITypeAndVersion { @@ -25,7 +25,7 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT error ZeroChainSelectorNotAllowed(); event RateLimiterConfigUpdated(uint64 indexed remoteChainSelector, bool isOutboundLane, RateLimiter.Config config); - event PriceRegistrySet(address newPriceRegistry); + event FeeQuoterSet(address newFeeQuoter); event TokenAggregateRateLimitAdded(uint64 remoteChainSelector, bytes remoteToken, address localToken); event TokenAggregateRateLimitRemoved(uint64 remoteChainSelector, address localToken); @@ -62,16 +62,16 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT mapping(uint64 remoteChainSelector => EnumerableMapAddresses.AddressToBytesMap tokensLocalToRemote) internal s_rateLimitedTokensLocalToRemote; - /// @notice The address of the PriceRegistry used to query token values for ratelimiting. - address internal s_priceRegistry; + /// @notice The address of the FeeQuoter used to query token values for ratelimiting. + address internal s_feeQuoter; /// @notice Rate limiter token bucket states per chain, with separate buckets for inbound and outbound lanes. mapping(uint64 remoteChainSelector => RateLimiterBuckets buckets) internal s_rateLimitersByChainSelector; - /// @param priceRegistry the price registry to set. + /// @param feeQuoter the fee quoter to set. /// @param authorizedCallers the authorized callers to set. - constructor(address priceRegistry, address[] memory authorizedCallers) AuthorizedCallers(authorizedCallers) { - _setPriceRegistry(priceRegistry); + constructor(address feeQuoter, address[] memory authorizedCallers) AuthorizedCallers(authorizedCallers) { + _setFeeQuoter(feeQuoter); } /// @inheritdoc IMessageInterceptor @@ -127,13 +127,13 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT } } - /// @notice Retrieves the token value for a token using the PriceRegistry. + /// @notice Retrieves the token value for a token using the FeeQuoter. /// @param tokenAmount The token and amount to get the value for. /// @return tokenValue USD value in 18 decimals. function _getTokenValue(Client.EVMTokenAmount memory tokenAmount) internal view returns (uint256) { // not fetching validated price, as price staleness is not important for value-based rate limiting // we only need to verify the price is not 0 - uint224 pricePerToken = IPriceRegistry(s_priceRegistry).getTokenPrice(tokenAmount.token).value; + uint224 pricePerToken = IFeeQuoter(s_feeQuoter).getTokenPrice(tokenAmount.token).value; if (pricePerToken == 0) revert PriceNotFoundForToken(tokenAmount.token); return pricePerToken._calcUSDValueFromTokenAmount(tokenAmount.amount); } @@ -247,27 +247,27 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT } } - /// @return priceRegistry The configured PriceRegistry address. - function getPriceRegistry() external view returns (address) { - return s_priceRegistry; + /// @return feeQuoter The configured FeeQuoter address. + function getFeeQuoter() external view returns (address feeQuoter) { + return s_feeQuoter; } - /// @notice Sets the Price Registry address. - /// @param newPriceRegistry the address of the new PriceRegistry. + /// @notice Sets the FeeQuoter address. + /// @param newFeeQuoter the address of the new FeeQuoter. /// @dev precondition The address must be a non-zero address. - function setPriceRegistry(address newPriceRegistry) external onlyOwner { - _setPriceRegistry(newPriceRegistry); + function setFeeQuoter(address newFeeQuoter) external onlyOwner { + _setFeeQuoter(newFeeQuoter); } - /// @notice Sets the Price Registry address. - /// @param newPriceRegistry the address of the new PriceRegistry. + /// @notice Sets the FeeQuoter address. + /// @param newFeeQuoter the address of the new FeeQuoter. /// @dev precondition The address must be a non-zero address. - function _setPriceRegistry(address newPriceRegistry) internal { - if (newPriceRegistry == address(0)) { + function _setFeeQuoter(address newFeeQuoter) internal { + if (newFeeQuoter == address(0)) { revert ZeroAddressNotAllowed(); } - s_priceRegistry = newPriceRegistry; - emit PriceRegistrySet(newPriceRegistry); + s_feeQuoter = newFeeQuoter; + emit FeeQuoterSet(newFeeQuoter); } } diff --git a/contracts/src/v0.8/ccip/interfaces/IFeeQuoter.sol b/contracts/src/v0.8/ccip/interfaces/IFeeQuoter.sol new file mode 100644 index 0000000000..fdea4538b6 --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IFeeQuoter.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Client} from "../libraries/Client.sol"; +import {Internal} from "../libraries/Internal.sol"; +import {IPriceRegistry} from "./IPriceRegistry.sol"; + +interface IFeeQuoter is IPriceRegistry { + /// @notice Token price data feed configuration + struct TokenPriceFeedConfig { + address dataFeedAddress; // ──╮ AggregatorV3Interface contract (0 - feed is unset) + uint8 tokenDecimals; // ──────╯ Decimals of the token that the feed represents + } + + /// @notice Returns the token price data feed configuration + /// @param token The token to retrieve the feed config for + /// @return tokenPriceFeedConfig The token price data feed config (if feed address is 0, the feed config is disabled) + function getTokenPriceFeedConfig(address token) external view returns (TokenPriceFeedConfig memory); + + /// @notice Validates the ccip message & returns the fee + /// @param destChainSelector The destination chain selector. + /// @param message The message to get quote for. + /// @return feeTokenAmount The amount of fee token needed for the fee, in smallest denomination of the fee token. + function getValidatedFee( + uint64 destChainSelector, + Client.EVM2AnyMessage calldata message + ) external view returns (uint256 feeTokenAmount); + + /// @notice Converts the extraArgs to the latest version and returns the converted message fee in juels + /// @param destChainSelector destination chain selector to process + /// @param feeToken Fee token address used to pay for message fees + /// @param feeTokenAmount Fee token amount + /// @param extraArgs Message extra args that were passed in by the client + /// @return msgFeeJuels message fee in juels + /// @return isOutOfOrderExecution true if the message should be executed out of order + /// @return convertedExtraArgs extra args converted to the latest family-specific args version + function processMessageArgs( + uint64 destChainSelector, + address feeToken, + uint256 feeTokenAmount, + bytes memory extraArgs + ) external view returns (uint256 msgFeeJuels, bool isOutOfOrderExecution, bytes memory convertedExtraArgs); + + /// @notice Validates pool return data + /// @param destChainSelector Destination chain selector to which the token amounts are sent to + /// @param rampTokenAmounts Token amounts with populated pool return data + /// @param sourceTokenAmounts Token amounts originally sent in a Client.EVM2AnyMessage message + /// @return destExecData Destination chain execution data + function processPoolReturnData( + uint64 destChainSelector, + Internal.RampTokenAmount[] memory rampTokenAmounts, + Client.EVMTokenAmount[] calldata sourceTokenAmounts + ) external view returns (bytes[] memory); +} diff --git a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol index 05d68b3183..a2c7bc1880 100644 --- a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol +++ b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol @@ -5,12 +5,6 @@ import {Client} from "../libraries/Client.sol"; import {Internal} from "../libraries/Internal.sol"; interface IPriceRegistry { - /// @notice Token price data feed configuration - struct TokenPriceFeedConfig { - address dataFeedAddress; // ──╮ AggregatorV3Interface contract (0 - feed is unset) - uint8 tokenDecimals; // ──────╯ Decimals of the token that the feed represents - } - /// @notice Update the price for given tokens and gas prices for given chains. /// @param priceUpdates The price updates to apply. function updatePrices(Internal.PriceUpdates memory priceUpdates) external; @@ -30,11 +24,6 @@ interface IPriceRegistry { /// @return tokenPrices The tokenPrices for the given tokens. function getTokenPrices(address[] calldata tokens) external view returns (Internal.TimestampedPackedUint224[] memory); - /// @notice Returns the token price data feed configuration - /// @param token The token to retrieve the feed config for - /// @return tokenPriceFeedConfig The token price data feed config (if feed address is 0, the feed config is disabled) - function getTokenPriceFeedConfig(address token) external view returns (TokenPriceFeedConfig memory); - /// @notice Get an encoded `gasPrice` for a given destination chain ID. /// The 224-bit result encodes necessary gas price components. /// On L1 chains like Ethereum or Avax, the only component is the gas price. diff --git a/contracts/src/v0.8/ccip/offRamp/OffRamp.sol b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol index 3f98d55e81..20ce6115dc 100644 --- a/contracts/src/v0.8/ccip/offRamp/OffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol @@ -3,10 +3,11 @@ pragma solidity 0.8.24; import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; import {IAny2EVMMessageReceiver} from "../interfaces/IAny2EVMMessageReceiver.sol"; + +import {IFeeQuoter} from "../interfaces/IFeeQuoter.sol"; import {IMessageInterceptor} from "../interfaces/IMessageInterceptor.sol"; import {INonceManager} from "../interfaces/INonceManager.sol"; import {IPoolV1} from "../interfaces/IPool.sol"; -import {IPriceRegistry} from "../interfaces/IPriceRegistry.sol"; import {IRMN} from "../interfaces/IRMN.sol"; import {IRouter} from "../interfaces/IRouter.sol"; import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol"; @@ -108,7 +109,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @notice Dynamic offRamp config /// @dev Since DynamicConfig is part of DynamicConfigSet event, if changing it, we should update the ABI on Atlas struct DynamicConfig { - address priceRegistry; // ──────────────────────────╮ Price registry address on the local chain + address feeQuoter; // ──────────────────────────────╮ FeeQuoter address on the local chain uint32 permissionLessExecutionThresholdSeconds; // │ Waiting time before manual execution is enabled uint32 maxTokenTransferGas; // │ Maximum amount of gas passed on to token `transfer` call uint32 maxPoolReleaseOrMintGas; // ─────────────────╯ Maximum amount of gas passed on to token pool when calling releaseOrMint @@ -589,8 +590,8 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { if (s_latestPriceSequenceNumber < sequenceNumber) { // If prices are not stale, update the latest epoch and round s_latestPriceSequenceNumber = sequenceNumber; - // And update the prices in the price registry - IPriceRegistry(s_dynamicConfig.priceRegistry).updatePrices(commitReport.priceUpdates); + // And update the prices in the fee quoter + IFeeQuoter(s_dynamicConfig.feeQuoter).updatePrices(commitReport.priceUpdates); } else { // If prices are stale and the report doesn't contain a root, this report // does not have any valid information and we revert. @@ -780,7 +781,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @notice Sets the dynamic config. /// @param dynamicConfig The dynamic config. function _setDynamicConfig(DynamicConfig memory dynamicConfig) internal { - if (dynamicConfig.priceRegistry == address(0)) { + if (dynamicConfig.feeQuoter == address(0)) { revert ZeroAddressNotAllowed(); } diff --git a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol index 6de57bf548..aa4edba3ac 100644 --- a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol @@ -3,10 +3,10 @@ pragma solidity 0.8.24; import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; import {IEVM2AnyOnRampClient} from "../interfaces/IEVM2AnyOnRampClient.sol"; +import {IFeeQuoter} from "../interfaces/IFeeQuoter.sol"; import {IMessageInterceptor} from "../interfaces/IMessageInterceptor.sol"; import {INonceManager} from "../interfaces/INonceManager.sol"; import {IPoolV1} from "../interfaces/IPool.sol"; -import {IPriceRegistry} from "../interfaces/IPriceRegistry.sol"; import {IRMN} from "../interfaces/IRMN.sol"; import {IRouter} from "../interfaces/IRouter.sol"; import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol"; @@ -56,7 +56,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { /// @dev Struct that contains the dynamic configuration // solhint-disable-next-line gas-struct-packing struct DynamicConfig { - address priceRegistry; // Price registry address + address feeQuoter; // FeeQuoter address address messageValidator; // Optional message validator to validate outbound messages (zero address = no validator) address feeAggregator; // Fee aggregator address } @@ -153,8 +153,8 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { } // Convert message fee to juels and retrieve converted args - (uint256 msgFeeJuels, bool isOutOfOrderExecution, bytes memory convertedExtraArgs) = IPriceRegistry( - s_dynamicConfig.priceRegistry + (uint256 msgFeeJuels, bool isOutOfOrderExecution, bytes memory convertedExtraArgs) = IFeeQuoter( + s_dynamicConfig.feeQuoter ).processMessageArgs(destChainSelector, message.feeToken, feeTokenAmount, message.extraArgs); emit FeePaid(message.feeToken, msgFeeJuels); @@ -191,7 +191,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { } // Validate pool return data after it is populated (view function - no state changes) - bytes[] memory destExecDataPerToken = IPriceRegistry(s_dynamicConfig.priceRegistry).processPoolReturnData( + bytes[] memory destExecDataPerToken = IFeeQuoter(s_dynamicConfig.feeQuoter).processPoolReturnData( destChainSelector, newMessage.tokenAmounts, message.tokenAmounts ); @@ -249,8 +249,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { }) ); - // NOTE: pool data validations are outsourced to the PriceRegistry to handle family-specific logic handling - + // NOTE: pool data validations are outsourced to the FeeQuoter to handle family-specific logic handling return Internal.RampTokenAmount({ sourcePoolAddress: abi.encode(sourcePool), destTokenAddress: poolReturnData.destTokenAddress, @@ -297,7 +296,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { /// @notice Internal version of setDynamicConfig to allow for reuse in the constructor. function _setDynamicConfig(DynamicConfig memory dynamicConfig) internal { - if (dynamicConfig.priceRegistry == address(0) || dynamicConfig.feeAggregator == address(0)) revert InvalidConfig(); + if (dynamicConfig.feeQuoter == address(0) || dynamicConfig.feeAggregator == address(0)) revert InvalidConfig(); s_dynamicConfig = dynamicConfig; @@ -367,13 +366,13 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { ) external view returns (uint256 feeTokenAmount) { if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(destChainSelector)))) revert CursedByRMN(destChainSelector); - return IPriceRegistry(s_dynamicConfig.priceRegistry).getValidatedFee(destChainSelector, message); + return IFeeQuoter(s_dynamicConfig.feeQuoter).getValidatedFee(destChainSelector, message); } /// @notice Withdraws the outstanding fee token balances to the fee aggregator. /// @dev This function can be permissionless as it only transfers accepted fee tokens to the fee aggregator which is a trusted address. function withdrawFeeTokens() external { - address[] memory feeTokens = IPriceRegistry(s_dynamicConfig.priceRegistry).getFeeTokens(); + address[] memory feeTokens = IFeeQuoter(s_dynamicConfig.feeQuoter).getFeeTokens(); address feeAggregator = s_dynamicConfig.feeAggregator; for (uint256 i = 0; i < feeTokens.length; ++i) { diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol index 3811f0d3c6..81da419253 100644 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -236,7 +236,7 @@ contract NonceManager_OnRampUpgrade is OnRampSetup { destDataAvailabilityOverheadGas: DEST_DATA_AVAILABILITY_OVERHEAD_GAS, destGasPerDataAvailabilityByte: DEST_GAS_PER_DATA_AVAILABILITY_BYTE, destDataAvailabilityMultiplierBps: DEST_GAS_DATA_AVAILABILITY_MULTIPLIER_BPS, - priceRegistry: address(s_priceRegistry), + priceRegistry: address(s_feeQuoter), maxDataBytes: MAX_DATA_SIZE, maxPerMsgGasLimit: MAX_GAS_LIMIT, defaultTokenFeeUSDCents: DEFAULT_TOKEN_FEE_USD_CENTS, diff --git a/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol b/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol index 7ea64c9f89..0976ab96c5 100644 --- a/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol +++ b/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol @@ -6,19 +6,19 @@ import {IRMN} from "../../interfaces/IRMN.sol"; import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; import {CommitStore} from "../../CommitStore.sol"; -import {PriceRegistry} from "../../PriceRegistry.sol"; +import {FeeQuoter} from "../../FeeQuoter.sol"; import {RMN} from "../../RMN.sol"; import {MerkleMultiProof} from "../../libraries/MerkleMultiProof.sol"; import {OCR2Abstract} from "../../ocr/OCR2Abstract.sol"; +import {FeeQuoterSetup} from "../feeQuoter/FeeQuoterSetup.t.sol"; import {CommitStoreHelper} from "../helpers/CommitStoreHelper.sol"; import {OCR2BaseSetup} from "../ocr/OCR2Base.t.sol"; -import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; -contract CommitStoreSetup is PriceRegistrySetup, OCR2BaseSetup { +contract CommitStoreSetup is FeeQuoterSetup, OCR2BaseSetup { CommitStoreHelper internal s_commitStore; - function setUp() public virtual override(PriceRegistrySetup, OCR2BaseSetup) { - PriceRegistrySetup.setUp(); + function setUp() public virtual override(FeeQuoterSetup, OCR2BaseSetup) { + FeeQuoterSetup.setUp(); OCR2BaseSetup.setUp(); s_commitStore = new CommitStoreHelper( @@ -29,29 +29,28 @@ contract CommitStoreSetup is PriceRegistrySetup, OCR2BaseSetup { rmnProxy: address(s_mockRMN) }) ); - CommitStore.DynamicConfig memory dynamicConfig = - CommitStore.DynamicConfig({priceRegistry: address(s_priceRegistry)}); + CommitStore.DynamicConfig memory dynamicConfig = CommitStore.DynamicConfig({priceRegistry: address(s_feeQuoter)}); s_commitStore.setOCR2Config( s_valid_signers, s_valid_transmitters, s_f, abi.encode(dynamicConfig), s_offchainConfigVersion, abi.encode("") ); address[] memory priceUpdaters = new address[](1); priceUpdaters[0] = address(s_commitStore); - s_priceRegistry.applyAuthorizedCallerUpdates( + s_feeQuoter.applyAuthorizedCallerUpdates( AuthorizedCallers.AuthorizedCallerArgs({addedCallers: priceUpdaters, removedCallers: new address[](0)}) ); } } -contract CommitStoreRealRMNSetup is PriceRegistrySetup, OCR2BaseSetup { +contract CommitStoreRealRMNSetup is FeeQuoterSetup, OCR2BaseSetup { CommitStoreHelper internal s_commitStore; RMN internal s_rmn; address internal constant BLESS_VOTE_ADDR = address(8888); - function setUp() public virtual override(PriceRegistrySetup, OCR2BaseSetup) { - PriceRegistrySetup.setUp(); + function setUp() public virtual override(FeeQuoterSetup, OCR2BaseSetup) { + FeeQuoterSetup.setUp(); OCR2BaseSetup.setUp(); RMN.Voter[] memory voters = new RMN.Voter[](1); @@ -67,17 +66,16 @@ contract CommitStoreRealRMNSetup is PriceRegistrySetup, OCR2BaseSetup { rmnProxy: address(s_rmn) }) ); - CommitStore.DynamicConfig memory dynamicConfig = - CommitStore.DynamicConfig({priceRegistry: address(s_priceRegistry)}); + CommitStore.DynamicConfig memory dynamicConfig = CommitStore.DynamicConfig({priceRegistry: address(s_feeQuoter)}); s_commitStore.setOCR2Config( s_valid_signers, s_valid_transmitters, s_f, abi.encode(dynamicConfig), s_offchainConfigVersion, abi.encode("") ); } } -contract CommitStore_constructor is PriceRegistrySetup, OCR2BaseSetup { - function setUp() public virtual override(PriceRegistrySetup, OCR2BaseSetup) { - PriceRegistrySetup.setUp(); +contract CommitStore_constructor is FeeQuoterSetup, OCR2BaseSetup { + function setUp() public virtual override(FeeQuoterSetup, OCR2BaseSetup) { + FeeQuoterSetup.setUp(); OCR2BaseSetup.setUp(); } @@ -88,8 +86,7 @@ contract CommitStore_constructor is PriceRegistrySetup, OCR2BaseSetup { onRamp: 0x2C44CDDdB6a900Fa2B585dd299E03D12Fa4293Bc, rmnProxy: address(s_mockRMN) }); - CommitStore.DynamicConfig memory dynamicConfig = - CommitStore.DynamicConfig({priceRegistry: address(s_priceRegistry)}); + CommitStore.DynamicConfig memory dynamicConfig = CommitStore.DynamicConfig({priceRegistry: address(s_feeQuoter)}); vm.expectEmit(); emit CommitStore.ConfigSet(staticConfig, dynamicConfig); @@ -354,7 +351,7 @@ contract CommitStore_report is CommitStoreSetup { }); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); @@ -368,7 +365,7 @@ contract CommitStore_report is CommitStoreSetup { }); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); @@ -386,7 +383,7 @@ contract CommitStore_report is CommitStoreSetup { }); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, tokenPrice1, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, tokenPrice1, block.timestamp); s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); @@ -476,7 +473,7 @@ contract CommitStore_report is CommitStoreSetup { }); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); vm.expectRevert(CommitStore.StaleReport.selector); diff --git a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol index 5ad0091734..4f9d0ac2c7 100644 --- a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol +++ b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol @@ -240,7 +240,7 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup { router.ccipSend(DEST_CHAIN_SELECTOR, message); vm.pauseGasMetering(); - uint256 gasLimit = s_priceRegistry.parseEVMExtraArgsFromBytes(msgEvent.extraArgs, DEST_CHAIN_SELECTOR).gasLimit; + uint256 gasLimit = s_feeQuoter.parseEVMExtraArgsFromBytes(msgEvent.extraArgs, DEST_CHAIN_SELECTOR).gasLimit; return Internal.Any2EVMRampMessage({ header: Internal.RampMessageHeader({ diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol b/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol similarity index 60% rename from contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol rename to contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol index dbbc4b32cd..11836b3d7b 100644 --- a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol +++ b/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol @@ -1,21 +1,22 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; +import {IFeeQuoter} from "../../interfaces/IFeeQuoter.sol"; + import {KeystoneFeedsPermissionHandler} from "../../../keystone/KeystoneFeedsPermissionHandler.sol"; import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol"; -import {PriceRegistry} from "../../PriceRegistry.sol"; -import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; +import {FeeQuoter} from "../../FeeQuoter.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {Pool} from "../../libraries/Pool.sol"; import {USDPriceWith18Decimals} from "../../libraries/USDPriceWith18Decimals.sol"; -import {PriceRegistryHelper} from "../helpers/PriceRegistryHelper.sol"; -import {PriceRegistryFeeSetup, PriceRegistrySetup} from "./PriceRegistrySetup.t.sol"; +import {FeeQuoterHelper} from "../helpers/FeeQuoterHelper.sol"; +import {FeeQuoterFeeSetup, FeeQuoterSetup} from "./FeeQuoterSetup.t.sol"; import {Vm} from "forge-std/Vm.sol"; -contract PriceRegistry_constructor is PriceRegistrySetup { +contract FeeQuoter_constructor is FeeQuoterSetup { function test_Setup_Success() public virtual { address[] memory priceUpdaters = new address[](2); priceUpdaters[0] = STRANGER; @@ -23,134 +24,133 @@ contract PriceRegistry_constructor is PriceRegistrySetup { address[] memory feeTokens = new address[](2); feeTokens[0] = s_sourceTokens[0]; feeTokens[1] = s_sourceTokens[1]; - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](2); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](2); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); tokenPriceFeedUpdates[1] = _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[1], s_dataFeedByToken[s_sourceTokens[1]], 6); - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs(); - PriceRegistry.StaticConfig memory staticConfig = PriceRegistry.StaticConfig({ + FeeQuoter.StaticConfig memory staticConfig = FeeQuoter.StaticConfig({ linkToken: s_sourceTokens[0], maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS, stalenessThreshold: uint32(TWELVE_HOURS) }); - s_priceRegistry = new PriceRegistryHelper( + s_feeQuoter = new FeeQuoterHelper( staticConfig, priceUpdaters, feeTokens, tokenPriceFeedUpdates, - s_priceRegistryTokenTransferFeeConfigArgs, - s_priceRegistryPremiumMultiplierWeiPerEthArgs, + s_feeQuoterTokenTransferFeeConfigArgs, + s_feeQuoterPremiumMultiplierWeiPerEthArgs, destChainConfigArgs ); - _assertPriceRegistryStaticConfigsEqual(s_priceRegistry.getStaticConfig(), staticConfig); - assertEq(feeTokens, s_priceRegistry.getFeeTokens()); - assertEq(priceUpdaters, s_priceRegistry.getAllAuthorizedCallers()); - assertEq(s_priceRegistry.typeAndVersion(), "PriceRegistry 1.6.0-dev"); + _assertFeeQuoterStaticConfigsEqual(s_feeQuoter.getStaticConfig(), staticConfig); + assertEq(feeTokens, s_feeQuoter.getFeeTokens()); + assertEq(priceUpdaters, s_feeQuoter.getAllAuthorizedCallers()); + assertEq(s_feeQuoter.typeAndVersion(), "FeeQuoter 1.6.0-dev"); _assertTokenPriceFeedConfigEquality( - tokenPriceFeedUpdates[0].feedConfig, s_priceRegistry.getTokenPriceFeedConfig(s_sourceTokens[0]) + tokenPriceFeedUpdates[0].feedConfig, s_feeQuoter.getTokenPriceFeedConfig(s_sourceTokens[0]) ); _assertTokenPriceFeedConfigEquality( - tokenPriceFeedUpdates[1].feedConfig, s_priceRegistry.getTokenPriceFeedConfig(s_sourceTokens[1]) + tokenPriceFeedUpdates[1].feedConfig, s_feeQuoter.getTokenPriceFeedConfig(s_sourceTokens[1]) ); assertEq( - s_priceRegistryPremiumMultiplierWeiPerEthArgs[0].premiumMultiplierWeiPerEth, - s_priceRegistry.getPremiumMultiplierWeiPerEth(s_priceRegistryPremiumMultiplierWeiPerEthArgs[0].token) + s_feeQuoterPremiumMultiplierWeiPerEthArgs[0].premiumMultiplierWeiPerEth, + s_feeQuoter.getPremiumMultiplierWeiPerEth(s_feeQuoterPremiumMultiplierWeiPerEthArgs[0].token) ); assertEq( - s_priceRegistryPremiumMultiplierWeiPerEthArgs[1].premiumMultiplierWeiPerEth, - s_priceRegistry.getPremiumMultiplierWeiPerEth(s_priceRegistryPremiumMultiplierWeiPerEthArgs[1].token) + s_feeQuoterPremiumMultiplierWeiPerEthArgs[1].premiumMultiplierWeiPerEth, + s_feeQuoter.getPremiumMultiplierWeiPerEth(s_feeQuoterPremiumMultiplierWeiPerEthArgs[1].token) ); - PriceRegistry.TokenTransferFeeConfigArgs memory tokenTransferFeeConfigArg = - s_priceRegistryTokenTransferFeeConfigArgs[0]; + FeeQuoter.TokenTransferFeeConfigArgs memory tokenTransferFeeConfigArg = s_feeQuoterTokenTransferFeeConfigArgs[0]; for (uint256 i = 0; i < tokenTransferFeeConfigArg.tokenTransferFeeConfigs.length; ++i) { - PriceRegistry.TokenTransferFeeConfigSingleTokenArgs memory tokenFeeArgs = - s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[i]; + FeeQuoter.TokenTransferFeeConfigSingleTokenArgs memory tokenFeeArgs = + s_feeQuoterTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[i]; _assertTokenTransferFeeConfigEqual( tokenFeeArgs.tokenTransferFeeConfig, - s_priceRegistry.getTokenTransferFeeConfig(tokenTransferFeeConfigArg.destChainSelector, tokenFeeArgs.token) + s_feeQuoter.getTokenTransferFeeConfig(tokenTransferFeeConfigArg.destChainSelector, tokenFeeArgs.token) ); } for (uint256 i = 0; i < destChainConfigArgs.length; ++i) { - PriceRegistry.DestChainConfig memory expectedConfig = destChainConfigArgs[i].destChainConfig; + FeeQuoter.DestChainConfig memory expectedConfig = destChainConfigArgs[i].destChainConfig; uint64 destChainSelector = destChainConfigArgs[i].destChainSelector; - _assertPriceRegistryDestChainConfigsEqual(expectedConfig, s_priceRegistry.getDestChainConfig(destChainSelector)); + _assertFeeQuoterDestChainConfigsEqual(expectedConfig, s_feeQuoter.getDestChainConfig(destChainSelector)); } } function test_InvalidStalenessThreshold_Revert() public { - PriceRegistry.StaticConfig memory staticConfig = PriceRegistry.StaticConfig({ + FeeQuoter.StaticConfig memory staticConfig = FeeQuoter.StaticConfig({ linkToken: s_sourceTokens[0], maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS, stalenessThreshold: 0 }); - vm.expectRevert(PriceRegistry.InvalidStaticConfig.selector); + vm.expectRevert(FeeQuoter.InvalidStaticConfig.selector); - s_priceRegistry = new PriceRegistryHelper( + s_feeQuoter = new FeeQuoterHelper( staticConfig, new address[](0), new address[](0), - new PriceRegistry.TokenPriceFeedUpdate[](0), - s_priceRegistryTokenTransferFeeConfigArgs, - s_priceRegistryPremiumMultiplierWeiPerEthArgs, - new PriceRegistry.DestChainConfigArgs[](0) + new FeeQuoter.TokenPriceFeedUpdate[](0), + s_feeQuoterTokenTransferFeeConfigArgs, + s_feeQuoterPremiumMultiplierWeiPerEthArgs, + new FeeQuoter.DestChainConfigArgs[](0) ); } function test_InvalidLinkTokenEqZeroAddress_Revert() public { - PriceRegistry.StaticConfig memory staticConfig = PriceRegistry.StaticConfig({ + FeeQuoter.StaticConfig memory staticConfig = FeeQuoter.StaticConfig({ linkToken: address(0), maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS, stalenessThreshold: uint32(TWELVE_HOURS) }); - vm.expectRevert(PriceRegistry.InvalidStaticConfig.selector); + vm.expectRevert(FeeQuoter.InvalidStaticConfig.selector); - s_priceRegistry = new PriceRegistryHelper( + s_feeQuoter = new FeeQuoterHelper( staticConfig, new address[](0), new address[](0), - new PriceRegistry.TokenPriceFeedUpdate[](0), - s_priceRegistryTokenTransferFeeConfigArgs, - s_priceRegistryPremiumMultiplierWeiPerEthArgs, - new PriceRegistry.DestChainConfigArgs[](0) + new FeeQuoter.TokenPriceFeedUpdate[](0), + s_feeQuoterTokenTransferFeeConfigArgs, + s_feeQuoterPremiumMultiplierWeiPerEthArgs, + new FeeQuoter.DestChainConfigArgs[](0) ); } function test_InvalidMaxFeeJuelsPerMsg_Revert() public { - PriceRegistry.StaticConfig memory staticConfig = PriceRegistry.StaticConfig({ + FeeQuoter.StaticConfig memory staticConfig = FeeQuoter.StaticConfig({ linkToken: s_sourceTokens[0], maxFeeJuelsPerMsg: 0, stalenessThreshold: uint32(TWELVE_HOURS) }); - vm.expectRevert(PriceRegistry.InvalidStaticConfig.selector); + vm.expectRevert(FeeQuoter.InvalidStaticConfig.selector); - s_priceRegistry = new PriceRegistryHelper( + s_feeQuoter = new FeeQuoterHelper( staticConfig, new address[](0), new address[](0), - new PriceRegistry.TokenPriceFeedUpdate[](0), - s_priceRegistryTokenTransferFeeConfigArgs, - s_priceRegistryPremiumMultiplierWeiPerEthArgs, - new PriceRegistry.DestChainConfigArgs[](0) + new FeeQuoter.TokenPriceFeedUpdate[](0), + s_feeQuoterTokenTransferFeeConfigArgs, + s_feeQuoterPremiumMultiplierWeiPerEthArgs, + new FeeQuoter.DestChainConfigArgs[](0) ); } } -contract PriceRegistry_getTokenPrices is PriceRegistrySetup { +contract FeeQuoter_getTokenPrices is FeeQuoterSetup { function test_GetTokenPrices_Success() public view { Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedInitialPriceUpdates, (Internal.PriceUpdates)); @@ -159,7 +159,7 @@ contract PriceRegistry_getTokenPrices is PriceRegistrySetup { tokens[1] = s_sourceTokens[1]; tokens[2] = s_weth; - Internal.TimestampedPackedUint224[] memory tokenPrices = s_priceRegistry.getTokenPrices(tokens); + Internal.TimestampedPackedUint224[] memory tokenPrices = s_feeQuoter.getTokenPrices(tokens); assertEq(tokenPrices.length, 3); assertEq(tokenPrices[0].value, priceUpdates.tokenPriceUpdates[0].usdPerToken); @@ -168,7 +168,7 @@ contract PriceRegistry_getTokenPrices is PriceRegistrySetup { } } -contract PriceRegistry_getTokenPrice is PriceRegistrySetup { +contract FeeQuoter_getTokenPrice is FeeQuoterSetup { function test_GetTokenPriceFromFeed_Success() public { uint256 originalTimestampValue = block.timestamp; @@ -176,7 +176,7 @@ contract PriceRegistry_getTokenPrice is PriceRegistrySetup { vm.warp(originalTimestampValue + 1 hours); address sourceToken = _initialiseSingleTokenPriceFeed(); - Internal.TimestampedPackedUint224 memory tokenPriceAnswer = s_priceRegistry.getTokenPrice(sourceToken); + Internal.TimestampedPackedUint224 memory tokenPriceAnswer = s_feeQuoter.getTokenPrice(sourceToken); // Price answer is 1e8 (18 decimal token) - unit is (1e18 * 1e18 / 1e18) -> expected 1e18 assertEq(tokenPriceAnswer.value, uint224(1e18)); @@ -184,12 +184,12 @@ contract PriceRegistry_getTokenPrice is PriceRegistrySetup { } } -contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { +contract FeeQuoter_getValidatedTokenPrice is FeeQuoterSetup { function test_GetValidatedTokenPrice_Success() public view { Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedInitialPriceUpdates, (Internal.PriceUpdates)); address token = priceUpdates.tokenPriceUpdates[0].sourceToken; - uint224 tokenPrice = s_priceRegistry.getValidatedTokenPrice(token); + uint224 tokenPrice = s_feeQuoter.getValidatedTokenPrice(token); assertEq(priceUpdates.tokenPriceUpdates[0].usdPerToken, tokenPrice); } @@ -201,7 +201,7 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { vm.warp(originalTimestampValue + TWELVE_HOURS); address sourceToken = _initialiseSingleTokenPriceFeed(); - uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(sourceToken); + uint224 tokenPriceAnswer = s_feeQuoter.getValidatedTokenPrice(sourceToken); // Price answer is 1e8 (18 decimal token) - unit is (1e18 * 1e18 / 1e18) -> expected 1e18 assertEq(tokenPriceAnswer, uint224(1e18)); @@ -214,7 +214,7 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { vm.warp(originalTimestampValue + TWELVE_HOURS + 1); address sourceToken = _initialiseSingleTokenPriceFeed(); - uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(sourceToken); + uint224 tokenPriceAnswer = s_feeQuoter.getValidatedTokenPrice(sourceToken); // Price answer is 1e8 (18 decimal token) - unit is (1e18 * 1e18 / 1e18) -> expected 1e18 assertEq(tokenPriceAnswer, uint224(1e18)); @@ -224,11 +224,11 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address tokenAddress = _deploySourceToken("testToken", 0, 18); address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 18, int256(uint256(type(uint224).max))); - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); - uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); + uint224 tokenPriceAnswer = s_feeQuoter.getValidatedTokenPrice(tokenAddress); // Price answer is: uint224.MAX_VALUE * (10 ** (36 - 18 - 18)) assertEq(tokenPriceAnswer, uint224(type(uint224).max)); @@ -238,11 +238,11 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address tokenAddress = _deploySourceToken("testToken", 0, 6); address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 8, 1e8); - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 6); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); - uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); + uint224 tokenPriceAnswer = s_feeQuoter.getValidatedTokenPrice(tokenAddress); // Price answer is 1e8 (6 decimal token) - unit is (1e18 * 1e18 / 1e6) -> expected 1e30 assertEq(tokenPriceAnswer, uint224(1e30)); @@ -252,11 +252,11 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address tokenAddress = _deploySourceToken("testToken", 0, 24); address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 8, 1e8); - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 24); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); - uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); + uint224 tokenPriceAnswer = s_feeQuoter.getValidatedTokenPrice(tokenAddress); // Price answer is 1e8 (6 decimal token) - unit is (1e18 * 1e18 / 1e24) -> expected 1e12 assertEq(tokenPriceAnswer, uint224(1e12)); @@ -266,11 +266,11 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address tokenAddress = _deploySourceToken("testToken", 0, 18); address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 18, 1e18); - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); - uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); + uint224 tokenPriceAnswer = s_feeQuoter.getValidatedTokenPrice(tokenAddress); // Price answer is 1e8 (6 decimal token) - unit is (1e18 * 1e18 / 1e18) -> expected 1e18 assertEq(tokenPriceAnswer, uint224(1e18)); @@ -280,11 +280,11 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address tokenAddress = _deploySourceToken("testToken", 0, 0); address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 0, 1e31); - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 0); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); - uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); + uint224 tokenPriceAnswer = s_feeQuoter.getValidatedTokenPrice(tokenAddress); // Price answer is 1e31 (0 decimal token) - unit is (1e18 * 1e18 / 1e0) -> expected 1e36 assertEq(tokenPriceAnswer, uint224(1e67)); @@ -294,11 +294,11 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address tokenAddress = _deploySourceToken("testToken", 0, 20); address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 20, 1e18); - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 20); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); - uint224 tokenPriceAnswer = s_priceRegistry.getValidatedTokenPrice(tokenAddress); + uint224 tokenPriceAnswer = s_feeQuoter.getValidatedTokenPrice(tokenAddress); // Price answer is 1e8 (6 decimal token) - unit is (1e18 * 1e18 / 1e20) -> expected 1e14 assertEq(tokenPriceAnswer, uint224(1e14)); @@ -310,7 +310,7 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedInitialPriceUpdates, (Internal.PriceUpdates)); address token = priceUpdates.tokenPriceUpdates[0].sourceToken; - uint224 tokenPrice = s_priceRegistry.getValidatedTokenPrice(token); + uint224 tokenPrice = s_feeQuoter.getValidatedTokenPrice(token); assertEq(priceUpdates.tokenPriceUpdates[0].usdPerToken, tokenPrice); } @@ -321,66 +321,66 @@ contract PriceRegistry_getValidatedTokenPrice is PriceRegistrySetup { address tokenAddress = _deploySourceToken("testToken", 0, 18); address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 18, int256(uint256(type(uint224).max) + 1)); - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); - vm.expectRevert(PriceRegistry.DataFeedValueOutOfUint224Range.selector); - s_priceRegistry.getValidatedTokenPrice(tokenAddress); + vm.expectRevert(FeeQuoter.DataFeedValueOutOfUint224Range.selector); + s_feeQuoter.getValidatedTokenPrice(tokenAddress); } function test_UnderflowFeedPrice_Revert() public { address tokenAddress = _deploySourceToken("testToken", 0, 18); address feedAddress = _deployTokenPriceDataFeed(tokenAddress, 18, -1); - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(tokenAddress, feedAddress, 18); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); - vm.expectRevert(PriceRegistry.DataFeedValueOutOfUint224Range.selector); - s_priceRegistry.getValidatedTokenPrice(tokenAddress); + vm.expectRevert(FeeQuoter.DataFeedValueOutOfUint224Range.selector); + s_feeQuoter.getValidatedTokenPrice(tokenAddress); } function test_TokenNotSupported_Revert() public { - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.TokenNotSupported.selector, DUMMY_CONTRACT_ADDRESS)); - s_priceRegistry.getValidatedTokenPrice(DUMMY_CONTRACT_ADDRESS); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.TokenNotSupported.selector, DUMMY_CONTRACT_ADDRESS)); + s_feeQuoter.getValidatedTokenPrice(DUMMY_CONTRACT_ADDRESS); } function test_TokenNotSupportedFeed_Revert() public { address sourceToken = _initialiseSingleTokenPriceFeed(); MockV3Aggregator(s_dataFeedByToken[sourceToken]).updateAnswer(0); - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.TokenNotSupported.selector, sourceToken)); - s_priceRegistry.getValidatedTokenPrice(sourceToken); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.TokenNotSupported.selector, sourceToken)); + s_feeQuoter.getValidatedTokenPrice(sourceToken); } } -contract PriceRegistry_applyFeeTokensUpdates is PriceRegistrySetup { +contract FeeQuoter_applyFeeTokensUpdates is FeeQuoterSetup { function test_ApplyFeeTokensUpdates_Success() public { address[] memory feeTokens = new address[](1); feeTokens[0] = s_sourceTokens[1]; vm.expectEmit(); - emit PriceRegistry.FeeTokenAdded(feeTokens[0]); + emit FeeQuoter.FeeTokenAdded(feeTokens[0]); - s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); - assertEq(s_priceRegistry.getFeeTokens().length, 3); - assertEq(s_priceRegistry.getFeeTokens()[2], feeTokens[0]); + s_feeQuoter.applyFeeTokensUpdates(feeTokens, new address[](0)); + assertEq(s_feeQuoter.getFeeTokens().length, 3); + assertEq(s_feeQuoter.getFeeTokens()[2], feeTokens[0]); // add same feeToken is no-op - s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); - assertEq(s_priceRegistry.getFeeTokens().length, 3); - assertEq(s_priceRegistry.getFeeTokens()[2], feeTokens[0]); + s_feeQuoter.applyFeeTokensUpdates(feeTokens, new address[](0)); + assertEq(s_feeQuoter.getFeeTokens().length, 3); + assertEq(s_feeQuoter.getFeeTokens()[2], feeTokens[0]); vm.expectEmit(); - emit PriceRegistry.FeeTokenRemoved(feeTokens[0]); + emit FeeQuoter.FeeTokenRemoved(feeTokens[0]); - s_priceRegistry.applyFeeTokensUpdates(new address[](0), feeTokens); - assertEq(s_priceRegistry.getFeeTokens().length, 2); + s_feeQuoter.applyFeeTokensUpdates(new address[](0), feeTokens); + assertEq(s_feeQuoter.getFeeTokens().length, 2); // removing already removed feeToken is no-op - s_priceRegistry.applyFeeTokensUpdates(new address[](0), feeTokens); - assertEq(s_priceRegistry.getFeeTokens().length, 2); + s_feeQuoter.applyFeeTokensUpdates(new address[](0), feeTokens); + assertEq(s_feeQuoter.getFeeTokens().length, 2); } function test_OnlyCallableByOwner_Revert() public { @@ -388,11 +388,11 @@ contract PriceRegistry_applyFeeTokensUpdates is PriceRegistrySetup { feeTokens[0] = STRANGER; vm.startPrank(STRANGER); vm.expectRevert("Only callable by owner"); - s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + s_feeQuoter.applyFeeTokensUpdates(feeTokens, new address[](0)); } } -contract PriceRegistry_updatePrices is PriceRegistrySetup { +contract FeeQuoter_updatePrices is FeeQuoterSetup { function test_OnlyTokenPrice_Success() public { Internal.PriceUpdates memory update = Internal.PriceUpdates({ tokenPriceUpdates: new Internal.TokenPriceUpdate[](1), @@ -401,13 +401,13 @@ contract PriceRegistry_updatePrices is PriceRegistrySetup { update.tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[0], usdPerToken: 4e18}); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated( + emit FeeQuoter.UsdPerTokenUpdated( update.tokenPriceUpdates[0].sourceToken, update.tokenPriceUpdates[0].usdPerToken, block.timestamp ); - s_priceRegistry.updatePrices(update); + s_feeQuoter.updatePrices(update); - assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[0]).value, update.tokenPriceUpdates[0].usdPerToken); + assertEq(s_feeQuoter.getTokenPrice(s_sourceTokens[0]).value, update.tokenPriceUpdates[0].usdPerToken); } function test_OnlyGasPrice_Success() public { @@ -419,14 +419,14 @@ contract PriceRegistry_updatePrices is PriceRegistrySetup { Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_SELECTOR, usdPerUnitGas: 2000e18}); vm.expectEmit(); - emit PriceRegistry.UsdPerUnitGasUpdated( + emit FeeQuoter.UsdPerUnitGasUpdated( update.gasPriceUpdates[0].destChainSelector, update.gasPriceUpdates[0].usdPerUnitGas, block.timestamp ); - s_priceRegistry.updatePrices(update); + s_feeQuoter.updatePrices(update); assertEq( - s_priceRegistry.getDestinationChainGasPrice(DEST_CHAIN_SELECTOR).value, update.gasPriceUpdates[0].usdPerUnitGas + s_feeQuoter.getDestinationChainGasPrice(DEST_CHAIN_SELECTOR).value, update.gasPriceUpdates[0].usdPerUnitGas ); } @@ -446,27 +446,27 @@ contract PriceRegistry_updatePrices is PriceRegistrySetup { for (uint256 i = 0; i < tokenPriceUpdates.length; ++i) { vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated( + emit FeeQuoter.UsdPerTokenUpdated( update.tokenPriceUpdates[i].sourceToken, update.tokenPriceUpdates[i].usdPerToken, block.timestamp ); } for (uint256 i = 0; i < gasPriceUpdates.length; ++i) { vm.expectEmit(); - emit PriceRegistry.UsdPerUnitGasUpdated( + emit FeeQuoter.UsdPerUnitGasUpdated( update.gasPriceUpdates[i].destChainSelector, update.gasPriceUpdates[i].usdPerUnitGas, block.timestamp ); } - s_priceRegistry.updatePrices(update); + s_feeQuoter.updatePrices(update); for (uint256 i = 0; i < tokenPriceUpdates.length; ++i) { assertEq( - s_priceRegistry.getTokenPrice(update.tokenPriceUpdates[i].sourceToken).value, tokenPriceUpdates[i].usdPerToken + s_feeQuoter.getTokenPrice(update.tokenPriceUpdates[i].sourceToken).value, tokenPriceUpdates[i].usdPerToken ); } for (uint256 i = 0; i < gasPriceUpdates.length; ++i) { assertEq( - s_priceRegistry.getDestinationChainGasPrice(update.gasPriceUpdates[i].destChainSelector).value, + s_feeQuoter.getDestinationChainGasPrice(update.gasPriceUpdates[i].destChainSelector).value, gasPriceUpdates[i].usdPerUnitGas ); } @@ -482,33 +482,33 @@ contract PriceRegistry_updatePrices is PriceRegistrySetup { // Revert when caller is not authorized vm.startPrank(STRANGER); vm.expectRevert(abi.encodeWithSelector(AuthorizedCallers.UnauthorizedCaller.selector, STRANGER)); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); address[] memory priceUpdaters = new address[](1); priceUpdaters[0] = STRANGER; vm.startPrank(OWNER); - s_priceRegistry.applyAuthorizedCallerUpdates( + s_feeQuoter.applyAuthorizedCallerUpdates( AuthorizedCallers.AuthorizedCallerArgs({addedCallers: priceUpdaters, removedCallers: new address[](0)}) ); // Stranger is now an authorized caller to update prices vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated( + emit FeeQuoter.UsdPerTokenUpdated( priceUpdates.tokenPriceUpdates[0].sourceToken, priceUpdates.tokenPriceUpdates[0].usdPerToken, block.timestamp ); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); - assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[0]).value, priceUpdates.tokenPriceUpdates[0].usdPerToken); + assertEq(s_feeQuoter.getTokenPrice(s_sourceTokens[0]).value, priceUpdates.tokenPriceUpdates[0].usdPerToken); vm.startPrank(OWNER); - s_priceRegistry.applyAuthorizedCallerUpdates( + s_feeQuoter.applyAuthorizedCallerUpdates( AuthorizedCallers.AuthorizedCallerArgs({addedCallers: new address[](0), removedCallers: priceUpdaters}) ); // Revert when authorized caller is removed vm.startPrank(STRANGER); vm.expectRevert(abi.encodeWithSelector(AuthorizedCallers.UnauthorizedCaller.selector, STRANGER)); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); } // Reverts @@ -521,18 +521,18 @@ contract PriceRegistry_updatePrices is PriceRegistrySetup { vm.startPrank(STRANGER); vm.expectRevert(abi.encodeWithSelector(AuthorizedCallers.UnauthorizedCaller.selector, STRANGER)); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); } } -contract PriceRegistry_convertTokenAmount is PriceRegistrySetup { +contract FeeQuoter_convertTokenAmount is FeeQuoterSetup { function test_ConvertTokenAmount_Success() public view { Internal.PriceUpdates memory initialPriceUpdates = abi.decode(s_encodedInitialPriceUpdates, (Internal.PriceUpdates)); uint256 amount = 3e16; uint256 conversionRate = (uint256(initialPriceUpdates.tokenPriceUpdates[2].usdPerToken) * 1e18) / uint256(initialPriceUpdates.tokenPriceUpdates[0].usdPerToken); uint256 expected = (amount * conversionRate) / 1e18; - assertEq(s_priceRegistry.convertTokenAmount(s_weth, amount, s_sourceTokens[0]), expected); + assertEq(s_feeQuoter.convertTokenAmount(s_weth, amount, s_sourceTokens[0]), expected); } function test_Fuzz_ConvertTokenAmount_Success( @@ -550,7 +550,7 @@ contract PriceRegistry_convertTokenAmount is PriceRegistrySetup { address linkToken = address(2); address[] memory feeTokens = new address[](1); feeTokens[0] = feeToken; - s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + s_feeQuoter.applyFeeTokensUpdates(feeTokens, new address[](0)); Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](2); tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: feeToken, usdPerToken: usdPerFeeToken}); @@ -562,27 +562,26 @@ contract PriceRegistry_convertTokenAmount is PriceRegistrySetup { Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({tokenPriceUpdates: tokenPriceUpdates, gasPriceUpdates: gasPriceUpdates}); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); - uint256 linkFee = s_priceRegistry.convertTokenAmount(feeToken, feeTokenAmount, linkToken); + uint256 linkFee = s_feeQuoter.convertTokenAmount(feeToken, feeTokenAmount, linkToken); assertEq(linkFee, (feeTokenAmount * usdPerFeeToken) / usdPerLinkToken); } // Reverts function test_LinkTokenNotSupported_Revert() public { - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.TokenNotSupported.selector, DUMMY_CONTRACT_ADDRESS)); - s_priceRegistry.convertTokenAmount(DUMMY_CONTRACT_ADDRESS, 3e16, s_sourceTokens[0]); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.TokenNotSupported.selector, DUMMY_CONTRACT_ADDRESS)); + s_feeQuoter.convertTokenAmount(DUMMY_CONTRACT_ADDRESS, 3e16, s_sourceTokens[0]); - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.TokenNotSupported.selector, DUMMY_CONTRACT_ADDRESS)); - s_priceRegistry.convertTokenAmount(s_sourceTokens[0], 3e16, DUMMY_CONTRACT_ADDRESS); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.TokenNotSupported.selector, DUMMY_CONTRACT_ADDRESS)); + s_feeQuoter.convertTokenAmount(s_sourceTokens[0], 3e16, DUMMY_CONTRACT_ADDRESS); } } -contract PriceRegistry_getTokenAndGasPrices is PriceRegistrySetup { +contract FeeQuoter_getTokenAndGasPrices is FeeQuoterSetup { function test_GetFeeTokenAndGasPrices_Success() public view { - (uint224 feeTokenPrice, uint224 gasPrice) = - s_priceRegistry.getTokenAndGasPrices(s_sourceFeeToken, DEST_CHAIN_SELECTOR); + (uint224 feeTokenPrice, uint224 gasPrice) = s_feeQuoter.getTokenAndGasPrices(s_sourceFeeToken, DEST_CHAIN_SELECTOR); Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedInitialPriceUpdates, (Internal.PriceUpdates)); @@ -597,148 +596,136 @@ contract PriceRegistry_getTokenAndGasPrices is PriceRegistrySetup { Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), gasPriceUpdates: gasPriceUpdates}); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); - (, uint224 gasPrice) = s_priceRegistry.getTokenAndGasPrices(s_sourceFeeToken, zeroGasDestChainSelector); + (, uint224 gasPrice) = s_feeQuoter.getTokenAndGasPrices(s_sourceFeeToken, zeroGasDestChainSelector); assertEq(gasPrice, priceUpdates.gasPriceUpdates[0].usdPerUnitGas); } function test_UnsupportedChain_Revert() public { - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.ChainNotSupported.selector, DEST_CHAIN_SELECTOR + 1)); - s_priceRegistry.getTokenAndGasPrices(s_sourceTokens[0], DEST_CHAIN_SELECTOR + 1); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.ChainNotSupported.selector, DEST_CHAIN_SELECTOR + 1)); + s_feeQuoter.getTokenAndGasPrices(s_sourceTokens[0], DEST_CHAIN_SELECTOR + 1); } function test_StaleGasPrice_Revert() public { uint256 diff = TWELVE_HOURS + 1; vm.warp(block.timestamp + diff); - vm.expectRevert( - abi.encodeWithSelector(PriceRegistry.StaleGasPrice.selector, DEST_CHAIN_SELECTOR, TWELVE_HOURS, diff) - ); - s_priceRegistry.getTokenAndGasPrices(s_sourceTokens[0], DEST_CHAIN_SELECTOR); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.StaleGasPrice.selector, DEST_CHAIN_SELECTOR, TWELVE_HOURS, diff)); + s_feeQuoter.getTokenAndGasPrices(s_sourceTokens[0], DEST_CHAIN_SELECTOR); } } -contract PriceRegistry_updateTokenPriceFeeds is PriceRegistrySetup { +contract FeeQuoter_updateTokenPriceFeeds is FeeQuoterSetup { function test_ZeroFeeds_Success() public { Vm.Log[] memory logEntries = vm.getRecordedLogs(); - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](0); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](0); vm.recordLogs(); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); // Verify no log emissions assertEq(logEntries.length, 0); } function test_SingleFeedUpdate_Success() public { - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); - _assertTokenPriceFeedConfigUnconfigured( - s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken) - ); + _assertTokenPriceFeedConfigUnconfigured(s_feeQuoter.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken)); vm.expectEmit(); - emit PriceRegistry.PriceFeedPerTokenUpdated( - tokenPriceFeedUpdates[0].sourceToken, tokenPriceFeedUpdates[0].feedConfig - ); + emit FeeQuoter.PriceFeedPerTokenUpdated(tokenPriceFeedUpdates[0].sourceToken, tokenPriceFeedUpdates[0].feedConfig); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); _assertTokenPriceFeedConfigEquality( - s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig + s_feeQuoter.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig ); } function test_MultipleFeedUpdate_Success() public { - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](2); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](2); for (uint256 i = 0; i < 2; ++i) { tokenPriceFeedUpdates[i] = _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[i], s_dataFeedByToken[s_sourceTokens[i]], 18); - _assertTokenPriceFeedConfigUnconfigured( - s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[i].sourceToken) - ); + _assertTokenPriceFeedConfigUnconfigured(s_feeQuoter.getTokenPriceFeedConfig(tokenPriceFeedUpdates[i].sourceToken)); vm.expectEmit(); - emit PriceRegistry.PriceFeedPerTokenUpdated( - tokenPriceFeedUpdates[i].sourceToken, tokenPriceFeedUpdates[i].feedConfig - ); + emit FeeQuoter.PriceFeedPerTokenUpdated(tokenPriceFeedUpdates[i].sourceToken, tokenPriceFeedUpdates[i].feedConfig); } - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); _assertTokenPriceFeedConfigEquality( - s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig + s_feeQuoter.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig ); _assertTokenPriceFeedConfigEquality( - s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[1].sourceToken), tokenPriceFeedUpdates[1].feedConfig + s_feeQuoter.getTokenPriceFeedConfig(tokenPriceFeedUpdates[1].sourceToken), tokenPriceFeedUpdates[1].feedConfig ); } function test_FeedUnset_Success() public { - Internal.TimestampedPackedUint224 memory priceQueryInitial = s_priceRegistry.getTokenPrice(s_sourceTokens[0]); + Internal.TimestampedPackedUint224 memory priceQueryInitial = s_feeQuoter.getTokenPrice(s_sourceTokens[0]); assertFalse(priceQueryInitial.value == 0); assertFalse(priceQueryInitial.timestamp == 0); - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); _assertTokenPriceFeedConfigEquality( - s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig + s_feeQuoter.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig ); tokenPriceFeedUpdates[0].feedConfig.dataFeedAddress = address(0); vm.expectEmit(); - emit PriceRegistry.PriceFeedPerTokenUpdated( - tokenPriceFeedUpdates[0].sourceToken, tokenPriceFeedUpdates[0].feedConfig - ); + emit FeeQuoter.PriceFeedPerTokenUpdated(tokenPriceFeedUpdates[0].sourceToken, tokenPriceFeedUpdates[0].feedConfig); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); _assertTokenPriceFeedConfigEquality( - s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig + s_feeQuoter.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig ); // Price data should remain after a feed has been set->unset - Internal.TimestampedPackedUint224 memory priceQueryPostUnsetFeed = s_priceRegistry.getTokenPrice(s_sourceTokens[0]); + Internal.TimestampedPackedUint224 memory priceQueryPostUnsetFeed = s_feeQuoter.getTokenPrice(s_sourceTokens[0]); assertEq(priceQueryPostUnsetFeed.value, priceQueryInitial.value); assertEq(priceQueryPostUnsetFeed.timestamp, priceQueryInitial.timestamp); } function test_FeedNotUpdated() public { - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); _assertTokenPriceFeedConfigEquality( - s_priceRegistry.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig + s_feeQuoter.getTokenPriceFeedConfig(tokenPriceFeedUpdates[0].sourceToken), tokenPriceFeedUpdates[0].feedConfig ); } // Reverts function test_FeedUpdatedByNonOwner_Revert() public { - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); vm.startPrank(STRANGER); vm.expectRevert("Only callable by owner"); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); } } -contract PriceRegistry_applyDestChainConfigUpdates is PriceRegistrySetup { - function test_Fuzz_applyDestChainConfigUpdates_Success(PriceRegistry.DestChainConfigArgs memory destChainConfigArgs) +contract FeeQuoter_applyDestChainConfigUpdates is FeeQuoterSetup { + function test_Fuzz_applyDestChainConfigUpdates_Success(FeeQuoter.DestChainConfigArgs memory destChainConfigArgs) public { vm.assume(destChainConfigArgs.destChainSelector != 0); @@ -752,55 +739,52 @@ contract PriceRegistry_applyDestChainConfigUpdates is PriceRegistrySetup { bool isNewChain = destChainConfigArgs.destChainSelector != DEST_CHAIN_SELECTOR; - PriceRegistry.DestChainConfigArgs[] memory newDestChainConfigArgs = new PriceRegistry.DestChainConfigArgs[](1); + FeeQuoter.DestChainConfigArgs[] memory newDestChainConfigArgs = new FeeQuoter.DestChainConfigArgs[](1); newDestChainConfigArgs[0] = destChainConfigArgs; if (isNewChain) { vm.expectEmit(); - emit PriceRegistry.DestChainAdded(destChainConfigArgs.destChainSelector, destChainConfigArgs.destChainConfig); + emit FeeQuoter.DestChainAdded(destChainConfigArgs.destChainSelector, destChainConfigArgs.destChainConfig); } else { vm.expectEmit(); - emit PriceRegistry.DestChainConfigUpdated( - destChainConfigArgs.destChainSelector, destChainConfigArgs.destChainConfig - ); + emit FeeQuoter.DestChainConfigUpdated(destChainConfigArgs.destChainSelector, destChainConfigArgs.destChainConfig); } - s_priceRegistry.applyDestChainConfigUpdates(newDestChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(newDestChainConfigArgs); - _assertPriceRegistryDestChainConfigsEqual( - destChainConfigArgs.destChainConfig, s_priceRegistry.getDestChainConfig(destChainConfigArgs.destChainSelector) + _assertFeeQuoterDestChainConfigsEqual( + destChainConfigArgs.destChainConfig, s_feeQuoter.getDestChainConfig(destChainConfigArgs.destChainSelector) ); } function test_applyDestChainConfigUpdates_Success() public { - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = new PriceRegistry.DestChainConfigArgs[](2); - destChainConfigArgs[0] = _generatePriceRegistryDestChainConfigArgs()[0]; + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = new FeeQuoter.DestChainConfigArgs[](2); + destChainConfigArgs[0] = _generateFeeQuoterDestChainConfigArgs()[0]; destChainConfigArgs[0].destChainConfig.isEnabled = false; - destChainConfigArgs[1] = _generatePriceRegistryDestChainConfigArgs()[0]; + destChainConfigArgs[1] = _generateFeeQuoterDestChainConfigArgs()[0]; destChainConfigArgs[1].destChainSelector = DEST_CHAIN_SELECTOR + 1; vm.expectEmit(); - emit PriceRegistry.DestChainConfigUpdated(DEST_CHAIN_SELECTOR, destChainConfigArgs[0].destChainConfig); + emit FeeQuoter.DestChainConfigUpdated(DEST_CHAIN_SELECTOR, destChainConfigArgs[0].destChainConfig); vm.expectEmit(); - emit PriceRegistry.DestChainAdded(DEST_CHAIN_SELECTOR + 1, destChainConfigArgs[1].destChainConfig); + emit FeeQuoter.DestChainAdded(DEST_CHAIN_SELECTOR + 1, destChainConfigArgs[1].destChainConfig); vm.recordLogs(); - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); - PriceRegistry.DestChainConfig memory gotDestChainConfig0 = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); - PriceRegistry.DestChainConfig memory gotDestChainConfig1 = - s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR + 1); + FeeQuoter.DestChainConfig memory gotDestChainConfig0 = s_feeQuoter.getDestChainConfig(DEST_CHAIN_SELECTOR); + FeeQuoter.DestChainConfig memory gotDestChainConfig1 = s_feeQuoter.getDestChainConfig(DEST_CHAIN_SELECTOR + 1); assertEq(vm.getRecordedLogs().length, 2); - _assertPriceRegistryDestChainConfigsEqual(destChainConfigArgs[0].destChainConfig, gotDestChainConfig0); - _assertPriceRegistryDestChainConfigsEqual(destChainConfigArgs[1].destChainConfig, gotDestChainConfig1); + _assertFeeQuoterDestChainConfigsEqual(destChainConfigArgs[0].destChainConfig, gotDestChainConfig0); + _assertFeeQuoterDestChainConfigsEqual(destChainConfigArgs[1].destChainConfig, gotDestChainConfig1); } function test_applyDestChainConfigUpdatesZeroIntput_Success() public { - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = new PriceRegistry.DestChainConfigArgs[](0); + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = new FeeQuoter.DestChainConfigArgs[](0); vm.recordLogs(); - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); assertEq(vm.getRecordedLogs().length, 0); } @@ -808,62 +792,62 @@ contract PriceRegistry_applyDestChainConfigUpdates is PriceRegistrySetup { // Reverts function test_applyDestChainConfigUpdatesDefaultTxGasLimitEqZero_Revert() public { - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); - PriceRegistry.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs(); + FeeQuoter.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; destChainConfigArg.destChainConfig.defaultTxGasLimit = 0; vm.expectRevert( - abi.encodeWithSelector(PriceRegistry.InvalidDestChainConfig.selector, destChainConfigArg.destChainSelector) + abi.encodeWithSelector(FeeQuoter.InvalidDestChainConfig.selector, destChainConfigArg.destChainSelector) ); - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); } function test_applyDestChainConfigUpdatesDefaultTxGasLimitGtMaxPerMessageGasLimit_Revert() public { - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); - PriceRegistry.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs(); + FeeQuoter.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; // Allow setting to the max value destChainConfigArg.destChainConfig.defaultTxGasLimit = destChainConfigArg.destChainConfig.maxPerMsgGasLimit; - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); // Revert when exceeding max value destChainConfigArg.destChainConfig.defaultTxGasLimit = destChainConfigArg.destChainConfig.maxPerMsgGasLimit + 1; vm.expectRevert( - abi.encodeWithSelector(PriceRegistry.InvalidDestChainConfig.selector, destChainConfigArg.destChainSelector) + abi.encodeWithSelector(FeeQuoter.InvalidDestChainConfig.selector, destChainConfigArg.destChainSelector) ); - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); } function test_InvalidDestChainConfigDestChainSelectorEqZero_Revert() public { - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); - PriceRegistry.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs(); + FeeQuoter.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; destChainConfigArg.destChainSelector = 0; vm.expectRevert( - abi.encodeWithSelector(PriceRegistry.InvalidDestChainConfig.selector, destChainConfigArg.destChainSelector) + abi.encodeWithSelector(FeeQuoter.InvalidDestChainConfig.selector, destChainConfigArg.destChainSelector) ); - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); } function test_InvalidChainFamilySelector_Revert() public { - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); - PriceRegistry.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs(); + FeeQuoter.DestChainConfigArgs memory destChainConfigArg = destChainConfigArgs[0]; destChainConfigArg.destChainConfig.chainFamilySelector = bytes4(uint32(1)); vm.expectRevert( - abi.encodeWithSelector(PriceRegistry.InvalidDestChainConfig.selector, destChainConfigArg.destChainSelector) + abi.encodeWithSelector(FeeQuoter.InvalidDestChainConfig.selector, destChainConfigArg.destChainSelector) ); - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); } } -contract PriceRegistry_getDataAvailabilityCost is PriceRegistrySetup { +contract FeeQuoter_getDataAvailabilityCost is FeeQuoterSetup { function test_EmptyMessageCalculatesDataAvailabilityCost_Success() public { uint256 dataAvailabilityCostUSD = - s_priceRegistry.getDataAvailabilityCost(DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, 0, 0, 0); + s_feeQuoter.getDataAvailabilityCost(DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, 0, 0, 0); - PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + FeeQuoter.DestChainConfig memory destChainConfig = s_feeQuoter.getDestChainConfig(DEST_CHAIN_SELECTOR); uint256 dataAvailabilityGas = destChainConfig.destDataAvailabilityOverheadGas + destChainConfig.destGasPerDataAvailabilityByte * Internal.ANY_2_EVM_MESSAGE_FIXED_BYTES; @@ -873,7 +857,7 @@ contract PriceRegistry_getDataAvailabilityCost is PriceRegistrySetup { assertEq(expectedDataAvailabilityCostUSD, dataAvailabilityCostUSD); // Test that the cost is destnation chain specific - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs(); destChainConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR + 1; destChainConfigArgs[0].destChainConfig.destDataAvailabilityOverheadGas = destChainConfig.destDataAvailabilityOverheadGas * 2; @@ -881,11 +865,11 @@ contract PriceRegistry_getDataAvailabilityCost is PriceRegistrySetup { destChainConfig.destGasPerDataAvailabilityByte * 2; destChainConfigArgs[0].destChainConfig.destDataAvailabilityMultiplierBps = destChainConfig.destDataAvailabilityMultiplierBps * 2; - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); - destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR + 1); + destChainConfig = s_feeQuoter.getDestChainConfig(DEST_CHAIN_SELECTOR + 1); uint256 dataAvailabilityCostUSD2 = - s_priceRegistry.getDataAvailabilityCost(DEST_CHAIN_SELECTOR + 1, USD_PER_DATA_AVAILABILITY_GAS, 0, 0, 0); + s_feeQuoter.getDataAvailabilityCost(DEST_CHAIN_SELECTOR + 1, USD_PER_DATA_AVAILABILITY_GAS, 0, 0, 0); dataAvailabilityGas = destChainConfig.destDataAvailabilityOverheadGas + destChainConfig.destGasPerDataAvailabilityByte * Internal.ANY_2_EVM_MESSAGE_FIXED_BYTES; expectedDataAvailabilityCostUSD = @@ -897,9 +881,9 @@ contract PriceRegistry_getDataAvailabilityCost is PriceRegistrySetup { function test_SimpleMessageCalculatesDataAvailabilityCost_Success() public view { uint256 dataAvailabilityCostUSD = - s_priceRegistry.getDataAvailabilityCost(DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, 100, 5, 50); + s_feeQuoter.getDataAvailabilityCost(DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, 100, 5, 50); - PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + FeeQuoter.DestChainConfig memory destChainConfig = s_feeQuoter.getDestChainConfig(DEST_CHAIN_SELECTOR); uint256 dataAvailabilityLengthBytes = Internal.ANY_2_EVM_MESSAGE_FIXED_BYTES + 100 + (5 * Internal.ANY_2_EVM_MESSAGE_FIXED_BYTES_PER_TOKEN) + 50; @@ -912,8 +896,7 @@ contract PriceRegistry_getDataAvailabilityCost is PriceRegistrySetup { } function test_SimpleMessageCalculatesDataAvailabilityCostUnsupportedDestChainSelector_Success() public view { - uint256 dataAvailabilityCostUSD = - s_priceRegistry.getDataAvailabilityCost(0, USD_PER_DATA_AVAILABILITY_GAS, 100, 5, 50); + uint256 dataAvailabilityCostUSD = s_feeQuoter.getDataAvailabilityCost(0, USD_PER_DATA_AVAILABILITY_GAS, 100, 5, 50); assertEq(dataAvailabilityCostUSD, 0); } @@ -923,7 +906,7 @@ contract PriceRegistry_getDataAvailabilityCost is PriceRegistrySetup { uint32 numberOfTokens, uint32 tokenTransferBytesOverhead ) public view { - uint256 dataAvailabilityCostUSD = s_priceRegistry.getDataAvailabilityCost( + uint256 dataAvailabilityCostUSD = s_feeQuoter.getDataAvailabilityCost( DEST_CHAIN_SELECTOR, 0, messageDataLength, numberOfTokens, tokenTransferBytesOverhead ); @@ -941,19 +924,20 @@ contract PriceRegistry_getDataAvailabilityCost is PriceRegistrySetup { uint32 tokenTransferBytesOverhead ) public { vm.assume(destChainSelector != 0); - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = new PriceRegistry.DestChainConfigArgs[](1); - PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(destChainSelector); + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = new FeeQuoter.DestChainConfigArgs[](1); + FeeQuoter.DestChainConfig memory destChainConfig = s_feeQuoter.getDestChainConfig(destChainSelector); destChainConfigArgs[0] = - PriceRegistry.DestChainConfigArgs({destChainSelector: destChainSelector, destChainConfig: destChainConfig}); + FeeQuoter.DestChainConfigArgs({destChainSelector: destChainSelector, destChainConfig: destChainConfig}); destChainConfigArgs[0].destChainConfig.destDataAvailabilityOverheadGas = destDataAvailabilityOverheadGas; destChainConfigArgs[0].destChainConfig.destGasPerDataAvailabilityByte = destGasPerDataAvailabilityByte; destChainConfigArgs[0].destChainConfig.destDataAvailabilityMultiplierBps = destDataAvailabilityMultiplierBps; destChainConfigArgs[0].destChainConfig.defaultTxGasLimit = GAS_LIMIT; destChainConfigArgs[0].destChainConfig.maxPerMsgGasLimit = GAS_LIMIT; destChainConfigArgs[0].destChainConfig.chainFamilySelector = Internal.CHAIN_FAMILY_SELECTOR_EVM; - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); - uint256 dataAvailabilityCostUSD = s_priceRegistry.getDataAvailabilityCost( + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); + + uint256 dataAvailabilityCostUSD = s_feeQuoter.getDataAvailabilityCost( destChainConfigArgs[0].destChainSelector, dataAvailabilityGasPrice, messageDataLength, @@ -973,77 +957,77 @@ contract PriceRegistry_getDataAvailabilityCost is PriceRegistrySetup { } } -contract PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates is PriceRegistrySetup { +contract FeeQuoter_applyPremiumMultiplierWeiPerEthUpdates is FeeQuoterSetup { function test_Fuzz_applyPremiumMultiplierWeiPerEthUpdates_Success( - PriceRegistry.PremiumMultiplierWeiPerEthArgs memory premiumMultiplierWeiPerEthArg + FeeQuoter.PremiumMultiplierWeiPerEthArgs memory premiumMultiplierWeiPerEthArg ) public { - PriceRegistry.PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs = - new PriceRegistry.PremiumMultiplierWeiPerEthArgs[](1); + FeeQuoter.PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs = + new FeeQuoter.PremiumMultiplierWeiPerEthArgs[](1); premiumMultiplierWeiPerEthArgs[0] = premiumMultiplierWeiPerEthArg; vm.expectEmit(); - emit PriceRegistry.PremiumMultiplierWeiPerEthUpdated( + emit FeeQuoter.PremiumMultiplierWeiPerEthUpdated( premiumMultiplierWeiPerEthArg.token, premiumMultiplierWeiPerEthArg.premiumMultiplierWeiPerEth ); - s_priceRegistry.applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); + s_feeQuoter.applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); assertEq( premiumMultiplierWeiPerEthArg.premiumMultiplierWeiPerEth, - s_priceRegistry.getPremiumMultiplierWeiPerEth(premiumMultiplierWeiPerEthArg.token) + s_feeQuoter.getPremiumMultiplierWeiPerEth(premiumMultiplierWeiPerEthArg.token) ); } function test_applyPremiumMultiplierWeiPerEthUpdatesSingleToken_Success() public { - PriceRegistry.PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs = - new PriceRegistry.PremiumMultiplierWeiPerEthArgs[](1); - premiumMultiplierWeiPerEthArgs[0] = s_priceRegistryPremiumMultiplierWeiPerEthArgs[0]; + FeeQuoter.PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs = + new FeeQuoter.PremiumMultiplierWeiPerEthArgs[](1); + premiumMultiplierWeiPerEthArgs[0] = s_feeQuoterPremiumMultiplierWeiPerEthArgs[0]; premiumMultiplierWeiPerEthArgs[0].token = vm.addr(1); vm.expectEmit(); - emit PriceRegistry.PremiumMultiplierWeiPerEthUpdated( + emit FeeQuoter.PremiumMultiplierWeiPerEthUpdated( vm.addr(1), premiumMultiplierWeiPerEthArgs[0].premiumMultiplierWeiPerEth ); - s_priceRegistry.applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); + s_feeQuoter.applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); assertEq( - s_priceRegistryPremiumMultiplierWeiPerEthArgs[0].premiumMultiplierWeiPerEth, - s_priceRegistry.getPremiumMultiplierWeiPerEth(vm.addr(1)) + s_feeQuoterPremiumMultiplierWeiPerEthArgs[0].premiumMultiplierWeiPerEth, + s_feeQuoter.getPremiumMultiplierWeiPerEth(vm.addr(1)) ); } function test_applyPremiumMultiplierWeiPerEthUpdatesMultipleTokens_Success() public { - PriceRegistry.PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs = - new PriceRegistry.PremiumMultiplierWeiPerEthArgs[](2); - premiumMultiplierWeiPerEthArgs[0] = s_priceRegistryPremiumMultiplierWeiPerEthArgs[0]; + FeeQuoter.PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs = + new FeeQuoter.PremiumMultiplierWeiPerEthArgs[](2); + premiumMultiplierWeiPerEthArgs[0] = s_feeQuoterPremiumMultiplierWeiPerEthArgs[0]; premiumMultiplierWeiPerEthArgs[0].token = vm.addr(1); premiumMultiplierWeiPerEthArgs[1].token = vm.addr(2); vm.expectEmit(); - emit PriceRegistry.PremiumMultiplierWeiPerEthUpdated( + emit FeeQuoter.PremiumMultiplierWeiPerEthUpdated( vm.addr(1), premiumMultiplierWeiPerEthArgs[0].premiumMultiplierWeiPerEth ); vm.expectEmit(); - emit PriceRegistry.PremiumMultiplierWeiPerEthUpdated( + emit FeeQuoter.PremiumMultiplierWeiPerEthUpdated( vm.addr(2), premiumMultiplierWeiPerEthArgs[1].premiumMultiplierWeiPerEth ); - s_priceRegistry.applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); + s_feeQuoter.applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); assertEq( premiumMultiplierWeiPerEthArgs[0].premiumMultiplierWeiPerEth, - s_priceRegistry.getPremiumMultiplierWeiPerEth(vm.addr(1)) + s_feeQuoter.getPremiumMultiplierWeiPerEth(vm.addr(1)) ); assertEq( premiumMultiplierWeiPerEthArgs[1].premiumMultiplierWeiPerEth, - s_priceRegistry.getPremiumMultiplierWeiPerEth(vm.addr(2)) + s_feeQuoter.getPremiumMultiplierWeiPerEth(vm.addr(2)) ); } function test_applyPremiumMultiplierWeiPerEthUpdatesZeroInput() public { vm.recordLogs(); - s_priceRegistry.applyPremiumMultiplierWeiPerEthUpdates(new PriceRegistry.PremiumMultiplierWeiPerEthArgs[](0)); + s_feeQuoter.applyPremiumMultiplierWeiPerEthUpdates(new FeeQuoter.PremiumMultiplierWeiPerEthArgs[](0)); assertEq(vm.getRecordedLogs().length, 0); } @@ -1051,21 +1035,20 @@ contract PriceRegistry_applyPremiumMultiplierWeiPerEthUpdates is PriceRegistrySe // Reverts function test_OnlyCallableByOwnerOrAdmin_Revert() public { - PriceRegistry.PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs; + FeeQuoter.PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs; vm.startPrank(STRANGER); vm.expectRevert("Only callable by owner"); - s_priceRegistry.applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); + s_feeQuoter.applyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs); } } -contract PriceRegistry_applyTokenTransferFeeConfigUpdates is PriceRegistrySetup { +contract FeeQuoter_applyTokenTransferFeeConfigUpdates is FeeQuoterSetup { function test_Fuzz_ApplyTokenTransferFeeConfig_Success( - PriceRegistry.TokenTransferFeeConfig[2] memory tokenTransferFeeConfigs + FeeQuoter.TokenTransferFeeConfig[2] memory tokenTransferFeeConfigs ) public { - PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = - _generateTokenTransferFeeConfigArgs(2, 2); + FeeQuoter.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = _generateTokenTransferFeeConfigArgs(2, 2); tokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; tokenTransferFeeConfigArgs[1].destChainSelector = DEST_CHAIN_SELECTOR + 1; @@ -1079,20 +1062,20 @@ contract PriceRegistry_applyTokenTransferFeeConfigUpdates is PriceRegistrySetup tokenTransferFeeConfigArgs[i].tokenTransferFeeConfigs[j].tokenTransferFeeConfig = tokenTransferFeeConfigs[j]; vm.expectEmit(); - emit PriceRegistry.TokenTransferFeeConfigUpdated( + emit FeeQuoter.TokenTransferFeeConfigUpdated( tokenTransferFeeConfigArgs[i].destChainSelector, feeToken, tokenTransferFeeConfigs[j] ); } } - s_priceRegistry.applyTokenTransferFeeConfigUpdates( - tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + s_feeQuoter.applyTokenTransferFeeConfigUpdates( + tokenTransferFeeConfigArgs, new FeeQuoter.TokenTransferFeeConfigRemoveArgs[](0) ); for (uint256 i = 0; i < tokenTransferFeeConfigs.length; ++i) { _assertTokenTransferFeeConfigEqual( tokenTransferFeeConfigs[i], - s_priceRegistry.getTokenTransferFeeConfig( + s_feeQuoter.getTokenTransferFeeConfig( tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[i].token ) @@ -1101,12 +1084,10 @@ contract PriceRegistry_applyTokenTransferFeeConfigUpdates is PriceRegistrySetup } function test_ApplyTokenTransferFeeConfig_Success() public { - PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = - _generateTokenTransferFeeConfigArgs(1, 2); + FeeQuoter.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = _generateTokenTransferFeeConfigArgs(1, 2); tokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token = address(5); - tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = PriceRegistry - .TokenTransferFeeConfig({ + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = FeeQuoter.TokenTransferFeeConfig({ minFeeUSDCents: 6, maxFeeUSDCents: 7, deciBps: 8, @@ -1115,8 +1096,7 @@ contract PriceRegistry_applyTokenTransferFeeConfigUpdates is PriceRegistrySetup isEnabled: true }); tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].token = address(11); - tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig = PriceRegistry - .TokenTransferFeeConfig({ + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig = FeeQuoter.TokenTransferFeeConfig({ minFeeUSDCents: 12, maxFeeUSDCents: 13, deciBps: 14, @@ -1126,26 +1106,26 @@ contract PriceRegistry_applyTokenTransferFeeConfigUpdates is PriceRegistrySetup }); vm.expectEmit(); - emit PriceRegistry.TokenTransferFeeConfigUpdated( + emit FeeQuoter.TokenTransferFeeConfigUpdated( tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig ); vm.expectEmit(); - emit PriceRegistry.TokenTransferFeeConfigUpdated( + emit FeeQuoter.TokenTransferFeeConfigUpdated( tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].token, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig ); - PriceRegistry.TokenTransferFeeConfigRemoveArgs[] memory tokensToRemove = - new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0); - s_priceRegistry.applyTokenTransferFeeConfigUpdates(tokenTransferFeeConfigArgs, tokensToRemove); + FeeQuoter.TokenTransferFeeConfigRemoveArgs[] memory tokensToRemove = + new FeeQuoter.TokenTransferFeeConfigRemoveArgs[](0); + s_feeQuoter.applyTokenTransferFeeConfigUpdates(tokenTransferFeeConfigArgs, tokensToRemove); - PriceRegistry.TokenTransferFeeConfig memory config0 = s_priceRegistry.getTokenTransferFeeConfig( + FeeQuoter.TokenTransferFeeConfig memory config0 = s_feeQuoter.getTokenTransferFeeConfig( tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token ); - PriceRegistry.TokenTransferFeeConfig memory config1 = s_priceRegistry.getTokenTransferFeeConfig( + FeeQuoter.TokenTransferFeeConfig memory config1 = s_feeQuoter.getTokenTransferFeeConfig( tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].token ); @@ -1157,29 +1137,27 @@ contract PriceRegistry_applyTokenTransferFeeConfigUpdates is PriceRegistrySetup ); // Remove only the first token and validate only the first token is removed - tokensToRemove = new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](1); - tokensToRemove[0] = PriceRegistry.TokenTransferFeeConfigRemoveArgs({ + tokensToRemove = new FeeQuoter.TokenTransferFeeConfigRemoveArgs[](1); + tokensToRemove[0] = FeeQuoter.TokenTransferFeeConfigRemoveArgs({ destChainSelector: tokenTransferFeeConfigArgs[0].destChainSelector, token: tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token }); vm.expectEmit(); - emit PriceRegistry.TokenTransferFeeConfigDeleted( + emit FeeQuoter.TokenTransferFeeConfigDeleted( tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token ); - s_priceRegistry.applyTokenTransferFeeConfigUpdates( - new PriceRegistry.TokenTransferFeeConfigArgs[](0), tokensToRemove - ); + s_feeQuoter.applyTokenTransferFeeConfigUpdates(new FeeQuoter.TokenTransferFeeConfigArgs[](0), tokensToRemove); - config0 = s_priceRegistry.getTokenTransferFeeConfig( + config0 = s_feeQuoter.getTokenTransferFeeConfig( tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token ); - config1 = s_priceRegistry.getTokenTransferFeeConfig( + config1 = s_feeQuoter.getTokenTransferFeeConfig( tokenTransferFeeConfigArgs[0].destChainSelector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].token ); - PriceRegistry.TokenTransferFeeConfig memory emptyConfig; + FeeQuoter.TokenTransferFeeConfig memory emptyConfig; _assertTokenTransferFeeConfigEqual(emptyConfig, config0); _assertTokenTransferFeeConfigEqual( @@ -1189,8 +1167,8 @@ contract PriceRegistry_applyTokenTransferFeeConfigUpdates is PriceRegistrySetup function test_ApplyTokenTransferFeeZeroInput() public { vm.recordLogs(); - s_priceRegistry.applyTokenTransferFeeConfigUpdates( - new PriceRegistry.TokenTransferFeeConfigArgs[](0), new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + s_feeQuoter.applyTokenTransferFeeConfigUpdates( + new FeeQuoter.TokenTransferFeeConfigArgs[](0), new FeeQuoter.TokenTransferFeeConfigRemoveArgs[](0) ); assertEq(vm.getRecordedLogs().length, 0); @@ -1200,22 +1178,20 @@ contract PriceRegistry_applyTokenTransferFeeConfigUpdates is PriceRegistrySetup function test_OnlyCallableByOwnerOrAdmin_Revert() public { vm.startPrank(STRANGER); - PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs; + FeeQuoter.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs; vm.expectRevert("Only callable by owner"); - s_priceRegistry.applyTokenTransferFeeConfigUpdates( - tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + s_feeQuoter.applyTokenTransferFeeConfigUpdates( + tokenTransferFeeConfigArgs, new FeeQuoter.TokenTransferFeeConfigRemoveArgs[](0) ); } function test_InvalidDestBytesOverhead_Revert() public { - PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = - _generateTokenTransferFeeConfigArgs(1, 1); + FeeQuoter.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = _generateTokenTransferFeeConfigArgs(1, 1); tokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token = address(5); - tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = PriceRegistry - .TokenTransferFeeConfig({ + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = FeeQuoter.TokenTransferFeeConfig({ minFeeUSDCents: 6, maxFeeUSDCents: 7, deciBps: 8, @@ -1226,25 +1202,25 @@ contract PriceRegistry_applyTokenTransferFeeConfigUpdates is PriceRegistrySetup vm.expectRevert( abi.encodeWithSelector( - PriceRegistry.InvalidDestBytesOverhead.selector, + FeeQuoter.InvalidDestBytesOverhead.selector, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token, tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig.destBytesOverhead ) ); - s_priceRegistry.applyTokenTransferFeeConfigUpdates( - tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + s_feeQuoter.applyTokenTransferFeeConfigUpdates( + tokenTransferFeeConfigArgs, new FeeQuoter.TokenTransferFeeConfigRemoveArgs[](0) ); } } -contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { +contract FeeQuoter_getTokenTransferCost is FeeQuoterFeeSetup { using USDPriceWith18Decimals for uint224; function test_NoTokenTransferChargesZeroFee_Success() public view { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = - s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); assertEq(0, feeUSDWei); assertEq(0, destGasOverhead); @@ -1255,13 +1231,13 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_selfServeTokenDefaultPricing, 1000); // Get config to assert it isn't set - PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + FeeQuoter.TokenTransferFeeConfig memory transferFeeConfig = + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); assertFalse(transferFeeConfig.isEnabled); (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = - s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); // Assert that the default values are used assertEq(uint256(DEFAULT_TOKEN_FEE_USD_CENTS) * 1e16, feeUSDWei); @@ -1271,11 +1247,11 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { function test_SmallTokenTransferChargesMinFeeAndGas_Success() public view { Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1000); - PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + FeeQuoter.TokenTransferFeeConfig memory transferFeeConfig = + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = - s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); assertEq(_configUSDCentToWei(transferFeeConfig.minFeeUSDCents), feeUSDWei); assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); @@ -1284,11 +1260,11 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { function test_ZeroAmountTokenTransferChargesMinFeeAndGas_Success() public view { Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 0); - PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + FeeQuoter.TokenTransferFeeConfig memory transferFeeConfig = + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = - s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); assertEq(_configUSDCentToWei(transferFeeConfig.minFeeUSDCents), feeUSDWei); assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); @@ -1297,11 +1273,11 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { function test_LargeTokenTransferChargesMaxFeeAndGas_Success() public view { Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1e36); - PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + FeeQuoter.TokenTransferFeeConfig memory transferFeeConfig = + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = - s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); assertEq(_configUSDCentToWei(transferFeeConfig.maxFeeUSDCents), feeUSDWei); assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); @@ -1312,15 +1288,15 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { uint256 tokenAmount = 10000e18; Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, tokenAmount); - PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + FeeQuoter.TokenTransferFeeConfig memory transferFeeConfig = + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = - s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); uint256 usdWei = _calcUSDValueFromTokenAmount(s_feeTokenPrice, tokenAmount); uint256 bpsUSDWei = _applyBpsRatio( - usdWei, s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig.deciBps + usdWei, s_feeQuoterTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig.deciBps ); assertEq(bpsUSDWei, feeUSDWei); @@ -1340,15 +1316,15 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { }); message.tokenAmounts[0] = Client.EVMTokenAmount({token: CUSTOM_TOKEN, amount: tokenAmount}); - PriceRegistry.TokenTransferFeeConfig memory transferFeeConfig = - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); + FeeQuoter.TokenTransferFeeConfig memory transferFeeConfig = + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token); (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = - s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); uint256 usdWei = _calcUSDValueFromTokenAmount(s_customTokenPrice, tokenAmount); uint256 bpsUSDWei = _applyBpsRatio( - usdWei, s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig.deciBps + usdWei, s_feeQuoterTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[1].tokenTransferFeeConfig.deciBps ); assertEq(bpsUSDWei, feeUSDWei); @@ -1357,12 +1333,10 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { } function test_ZeroFeeConfigChargesMinFee_Success() public { - PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = - _generateTokenTransferFeeConfigArgs(1, 1); + FeeQuoter.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = _generateTokenTransferFeeConfigArgs(1, 1); tokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token = s_sourceFeeToken; - tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = PriceRegistry - .TokenTransferFeeConfig({ + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = FeeQuoter.TokenTransferFeeConfig({ minFeeUSDCents: 1, maxFeeUSDCents: 0, deciBps: 0, @@ -1370,13 +1344,13 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES), isEnabled: true }); - s_priceRegistry.applyTokenTransferFeeConfigUpdates( - tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + s_feeQuoter.applyTokenTransferFeeConfigUpdates( + tokenTransferFeeConfigArgs, new FeeQuoter.TokenTransferFeeConfigRemoveArgs[](0) ); Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1e36); (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = - s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_feeTokenPrice, message.tokenAmounts); // if token charges 0 bps, it should cost minFee to transfer assertEq( @@ -1392,7 +1366,7 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { function test_Fuzz_TokenTransferFeeDuplicateTokens_Success(uint256 transfers, uint256 amount) public view { // It shouldn't be possible to pay materially lower fees by splitting up the transfers. // Note it is possible to pay higher fees since the minimum fees are added. - PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + FeeQuoter.DestChainConfig memory destChainConfig = s_feeQuoter.getDestChainConfig(DEST_CHAIN_SELECTOR); transfers = bound(transfers, 1, destChainConfig.maxNumberOfTokensPerMsg); // Cap amount to avoid overflow amount = bound(amount, 0, 1e36); @@ -1406,9 +1380,9 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { address feeToken = s_sourceRouter.getWrappedNative(); (uint256 feeSingleUSDWei, uint32 gasOverheadSingle, uint32 bytesOverheadSingle) = - s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, feeToken, s_wrappedTokenPrice, single); + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, feeToken, s_wrappedTokenPrice, single); (uint256 feeMultipleUSDWei, uint32 gasOverheadMultiple, uint32 bytesOverheadMultiple) = - s_priceRegistry.getTokenTransferCost(DEST_CHAIN_SELECTOR, feeToken, s_wrappedTokenPrice, multiple); + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, feeToken, s_wrappedTokenPrice, multiple); // Note that there can be a rounding error once per split. assertGe(feeMultipleUSDWei, (feeSingleUSDWei - destChainConfig.maxNumberOfTokensPerMsg)); @@ -1419,10 +1393,10 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { function test_MixedTokenTransferFee_Success() public view { address[3] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative(), CUSTOM_TOKEN]; uint224[3] memory tokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice, s_customTokenPrice]; - PriceRegistry.TokenTransferFeeConfig[3] memory tokenTransferFeeConfigs = [ - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[0]), - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[1]), - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[2]) + FeeQuoter.TokenTransferFeeConfig[3] memory tokenTransferFeeConfigs = [ + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[0]), + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[1]), + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[2]) ]; Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ @@ -1438,8 +1412,8 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { // Start with small token transfers, total bps fee is lower than min token transfer fee for (uint256 i = 0; i < testTokens.length; ++i) { message.tokenAmounts[i] = Client.EVMTokenAmount({token: testTokens[i], amount: 1e14}); - PriceRegistry.TokenTransferFeeConfig memory tokenTransferFeeConfig = - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[i]); + FeeQuoter.TokenTransferFeeConfig memory tokenTransferFeeConfig = + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, testTokens[i]); expectedTotalGas += tokenTransferFeeConfig.destGasOverhead == 0 ? DEFAULT_TOKEN_DEST_GAS_OVERHEAD @@ -1448,9 +1422,8 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { ? DEFAULT_TOKEN_BYTES_OVERHEAD : tokenTransferFeeConfig.destBytesOverhead; } - (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = s_priceRegistry.getTokenTransferCost( - DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts - ); + (uint256 feeUSDWei, uint32 destGasOverhead, uint32 destBytesOverhead) = + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts); uint256 expectedFeeUSDWei = 0; for (uint256 i = 0; i < testTokens.length; ++i) { @@ -1473,9 +1446,8 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { ); uint256 token1USDWei = _configUSDCentToWei(DEFAULT_TOKEN_FEE_USD_CENTS); - (feeUSDWei, destGasOverhead, destBytesOverhead) = s_priceRegistry.getTokenTransferCost( - DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts - ); + (feeUSDWei, destGasOverhead, destBytesOverhead) = + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts); expectedFeeUSDWei = token0USDWei + token1USDWei + _configUSDCentToWei(tokenTransferFeeConfigs[2].minFeeUSDCents); assertEq(expectedFeeUSDWei, feeUSDWei, "wrong feeUSDWei 2"); @@ -1485,9 +1457,8 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { // Set 2nd token transfer to a large amount that is higher than maxFeeUSD message.tokenAmounts[2] = Client.EVMTokenAmount({token: testTokens[2], amount: 1e36}); - (feeUSDWei, destGasOverhead, destBytesOverhead) = s_priceRegistry.getTokenTransferCost( - DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts - ); + (feeUSDWei, destGasOverhead, destBytesOverhead) = + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, s_wrappedTokenPrice, message.tokenAmounts); expectedFeeUSDWei = token0USDWei + token1USDWei + _configUSDCentToWei(tokenTransferFeeConfigs[2].maxFeeUSDCents); assertEq(expectedFeeUSDWei, feeUSDWei, "wrong feeUSDWei 3"); @@ -1496,7 +1467,7 @@ contract PriceRegistry_getTokenTransferCost is PriceRegistryFeeSetup { } } -contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { +contract FeeQuoter_getValidatedFee is FeeQuoterFeeSetup { using USDPriceWith18Decimals for uint224; function test_EmptyMessage_Success() public view { @@ -1506,15 +1477,15 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { for (uint256 i = 0; i < feeTokenPrices.length; ++i) { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); message.feeToken = testTokens[i]; - uint64 premiumMultiplierWeiPerEth = s_priceRegistry.getPremiumMultiplierWeiPerEth(message.feeToken); - PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + uint64 premiumMultiplierWeiPerEth = s_feeQuoter.getPremiumMultiplierWeiPerEth(message.feeToken); + FeeQuoter.DestChainConfig memory destChainConfig = s_feeQuoter.getDestChainConfig(DEST_CHAIN_SELECTOR); - uint256 feeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + uint256 feeAmount = s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); uint256 gasUsed = GAS_LIMIT + DEST_GAS_OVERHEAD; uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); uint256 messageFeeUSD = (_configUSDCentToWei(destChainConfig.networkFeeUSDCents) * premiumMultiplierWeiPerEth); - uint256 dataAvailabilityFeeUSD = s_priceRegistry.getDataAvailabilityCost( + uint256 dataAvailabilityFeeUSD = s_feeQuoter.getDataAvailabilityCost( DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, message.data.length, message.tokenAmounts.length, 0 ); @@ -1524,17 +1495,17 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { } function test_ZeroDataAvailabilityMultiplier_Success() public { - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = new PriceRegistry.DestChainConfigArgs[](1); - PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = new FeeQuoter.DestChainConfigArgs[](1); + FeeQuoter.DestChainConfig memory destChainConfig = s_feeQuoter.getDestChainConfig(DEST_CHAIN_SELECTOR); destChainConfigArgs[0] = - PriceRegistry.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, destChainConfig: destChainConfig}); + FeeQuoter.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, destChainConfig: destChainConfig}); destChainConfigArgs[0].destChainConfig.destDataAvailabilityMultiplierBps = 0; - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); Client.EVM2AnyMessage memory message = _generateEmptyMessage(); - uint64 premiumMultiplierWeiPerEth = s_priceRegistry.getPremiumMultiplierWeiPerEth(message.feeToken); + uint64 premiumMultiplierWeiPerEth = s_feeQuoter.getPremiumMultiplierWeiPerEth(message.feeToken); - uint256 feeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + uint256 feeAmount = s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); uint256 gasUsed = GAS_LIMIT + DEST_GAS_OVERHEAD; uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); @@ -1559,14 +1530,14 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: customGasLimit})) }); - uint64 premiumMultiplierWeiPerEth = s_priceRegistry.getPremiumMultiplierWeiPerEth(message.feeToken); - PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + uint64 premiumMultiplierWeiPerEth = s_feeQuoter.getPremiumMultiplierWeiPerEth(message.feeToken); + FeeQuoter.DestChainConfig memory destChainConfig = s_feeQuoter.getDestChainConfig(DEST_CHAIN_SELECTOR); - uint256 feeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + uint256 feeAmount = s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); uint256 gasUsed = customGasLimit + DEST_GAS_OVERHEAD + customDataSize * DEST_GAS_PER_PAYLOAD_BYTE; uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); uint256 messageFeeUSD = (_configUSDCentToWei(destChainConfig.networkFeeUSDCents) * premiumMultiplierWeiPerEth); - uint256 dataAvailabilityFeeUSD = s_priceRegistry.getDataAvailabilityCost( + uint256 dataAvailabilityFeeUSD = s_feeQuoter.getDataAvailabilityCost( DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, message.data.length, message.tokenAmounts.length, 0 ); @@ -1583,22 +1554,21 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { for (uint256 i = 0; i < feeTokenPrices.length; ++i) { Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, tokenAmount); message.feeToken = testTokens[i]; - PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + FeeQuoter.DestChainConfig memory destChainConfig = s_feeQuoter.getDestChainConfig(DEST_CHAIN_SELECTOR); uint32 destBytesOverhead = - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token).destBytesOverhead; + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token).destBytesOverhead; uint32 tokenBytesOverhead = destBytesOverhead == 0 ? uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) : destBytesOverhead; - uint256 feeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + uint256 feeAmount = s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); uint256 gasUsed = GAS_LIMIT + DEST_GAS_OVERHEAD - + s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token).destGasOverhead; + + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[0].token).destGasOverhead; uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); - (uint256 transferFeeUSD,,) = s_priceRegistry.getTokenTransferCost( - DEST_CHAIN_SELECTOR, message.feeToken, feeTokenPrices[i], message.tokenAmounts - ); - uint256 messageFeeUSD = (transferFeeUSD * s_priceRegistry.getPremiumMultiplierWeiPerEth(message.feeToken)); - uint256 dataAvailabilityFeeUSD = s_priceRegistry.getDataAvailabilityCost( + (uint256 transferFeeUSD,,) = + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, feeTokenPrices[i], message.tokenAmounts); + uint256 messageFeeUSD = (transferFeeUSD * s_feeQuoter.getPremiumMultiplierWeiPerEth(message.feeToken)); + uint256 dataAvailabilityFeeUSD = s_feeQuoter.getDataAvailabilityCost( DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, message.data.length, @@ -1624,8 +1594,8 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { feeToken: testTokens[i], extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: customGasLimit})) }); - uint64 premiumMultiplierWeiPerEth = s_priceRegistry.getPremiumMultiplierWeiPerEth(message.feeToken); - PriceRegistry.DestChainConfig memory destChainConfig = s_priceRegistry.getDestChainConfig(DEST_CHAIN_SELECTOR); + uint64 premiumMultiplierWeiPerEth = s_feeQuoter.getPremiumMultiplierWeiPerEth(message.feeToken); + FeeQuoter.DestChainConfig memory destChainConfig = s_feeQuoter.getDestChainConfig(DEST_CHAIN_SELECTOR); message.tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceFeeToken, amount: 10000e18}); // feeTokenAmount message.tokenAmounts[1] = Client.EVMTokenAmount({token: CUSTOM_TOKEN, amount: 200000e18}); // customTokenAmount @@ -1635,21 +1605,19 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { uint32 tokenBytesOverhead = 0; for (uint256 j = 0; j < message.tokenAmounts.length; ++j) { tokenGasOverhead += - s_priceRegistry.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[j].token).destGasOverhead; - uint32 destBytesOverhead = s_priceRegistry.getTokenTransferFeeConfig( - DEST_CHAIN_SELECTOR, message.tokenAmounts[j].token - ).destBytesOverhead; + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[j].token).destGasOverhead; + uint32 destBytesOverhead = + s_feeQuoter.getTokenTransferFeeConfig(DEST_CHAIN_SELECTOR, message.tokenAmounts[j].token).destBytesOverhead; tokenBytesOverhead += destBytesOverhead == 0 ? uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) : destBytesOverhead; } uint256 gasUsed = customGasLimit + DEST_GAS_OVERHEAD + message.data.length * DEST_GAS_PER_PAYLOAD_BYTE + tokenGasOverhead; uint256 gasFeeUSD = (gasUsed * destChainConfig.gasMultiplierWeiPerEth * USD_PER_GAS); - (uint256 transferFeeUSD,,) = s_priceRegistry.getTokenTransferCost( - DEST_CHAIN_SELECTOR, message.feeToken, feeTokenPrices[i], message.tokenAmounts - ); + (uint256 transferFeeUSD,,) = + s_feeQuoter.getTokenTransferCost(DEST_CHAIN_SELECTOR, message.feeToken, feeTokenPrices[i], message.tokenAmounts); uint256 messageFeeUSD = (transferFeeUSD * premiumMultiplierWeiPerEth); - uint256 dataAvailabilityFeeUSD = s_priceRegistry.getDataAvailabilityCost( + uint256 dataAvailabilityFeeUSD = s_feeQuoter.getDataAvailabilityCost( DEST_CHAIN_SELECTOR, USD_PER_DATA_AVAILABILITY_GAS, message.data.length, @@ -1658,7 +1626,7 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { ); uint256 totalPriceInFeeToken = (gasFeeUSD + messageFeeUSD + dataAvailabilityFeeUSD) / feeTokenPrices[i]; - assertEq(totalPriceInFeeToken, s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message)); + assertEq(totalPriceInFeeToken, s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message)); } } @@ -1667,9 +1635,9 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { vm.stopPrank(); vm.startPrank(OWNER); - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs(); destChainConfigArgs[0].destChainConfig.enforceOutOfOrder = enforce; - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); Client.EVM2AnyMessage memory message = _generateEmptyMessage(); message.extraArgs = abi.encodeWithSelector( @@ -1679,16 +1647,16 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { // If enforcement is on, only true should be allowed. if (enforce && !allowOutOfOrderExecution) { - vm.expectRevert(PriceRegistry.ExtraArgOutOfOrderExecutionMustBeTrue.selector); + vm.expectRevert(FeeQuoter.ExtraArgOutOfOrderExecutionMustBeTrue.selector); } - s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); } // Reverts function test_DestinationChainNotEnabled_Revert() public { - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.DestinationChainNotEnabled.selector, DEST_CHAIN_SELECTOR + 1)); - s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR + 1, _generateEmptyMessage()); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.DestinationChainNotEnabled.selector, DEST_CHAIN_SELECTOR + 1)); + s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR + 1, _generateEmptyMessage()); } function test_EnforceOutOfOrder_Revert() public { @@ -1696,41 +1664,41 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { vm.stopPrank(); vm.startPrank(OWNER); - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs(); destChainConfigArgs[0].destChainConfig.enforceOutOfOrder = true; - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); vm.stopPrank(); Client.EVM2AnyMessage memory message = _generateEmptyMessage(); // Empty extraArgs to should revert since it enforceOutOfOrder is true. message.extraArgs = ""; - vm.expectRevert(PriceRegistry.ExtraArgOutOfOrderExecutionMustBeTrue.selector); - s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + vm.expectRevert(FeeQuoter.ExtraArgOutOfOrderExecutionMustBeTrue.selector); + s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); } function test_MessageTooLarge_Revert() public { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); message.data = new bytes(MAX_DATA_SIZE + 1); - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.MessageTooLarge.selector, MAX_DATA_SIZE, message.data.length)); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.MessageTooLarge.selector, MAX_DATA_SIZE, message.data.length)); - s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); } function test_TooManyTokens_Revert() public { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); uint256 tooMany = MAX_TOKENS_LENGTH + 1; message.tokenAmounts = new Client.EVMTokenAmount[](tooMany); - vm.expectRevert(PriceRegistry.UnsupportedNumberOfTokens.selector); - s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + vm.expectRevert(FeeQuoter.UnsupportedNumberOfTokens.selector); + s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); } // Asserts gasLimit must be <=maxGasLimit function test_MessageGasLimitTooHigh_Revert() public { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); message.extraArgs = Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: MAX_GAS_LIMIT + 1})); - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.MessageGasLimitTooHigh.selector)); - s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.MessageGasLimitTooHigh.selector)); + s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); } function test_NotAFeeToken_Revert() public { @@ -1738,9 +1706,9 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(notAFeeToken, 1); message.feeToken = notAFeeToken; - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.TokenNotSupported.selector, notAFeeToken)); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.TokenNotSupported.selector, notAFeeToken)); - s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); } function test_InvalidEVMAddress_Revert() public { @@ -1749,11 +1717,11 @@ contract PriceRegistry_getValidatedFee is PriceRegistryFeeSetup { vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, message.receiver)); - s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); } } -contract PriceRegistry_processMessageArgs is PriceRegistryFeeSetup { +contract FeeQuoter_processMessageArgs is FeeQuoterFeeSetup { using USDPriceWith18Decimals for uint224; function setUp() public virtual override { @@ -1766,7 +1734,7 @@ contract PriceRegistry_processMessageArgs is PriceRegistryFeeSetup { /* bool isOutOfOrderExecution */ , /* bytes memory convertedExtraArgs */ - ) = s_priceRegistry.processMessageArgs( + ) = s_feeQuoter.processMessageArgs( DEST_CHAIN_SELECTOR, // LINK s_sourceTokens[0], @@ -1780,14 +1748,14 @@ contract PriceRegistry_processMessageArgs is PriceRegistryFeeSetup { function test_WithConvertedTokenAmount_Success() public view { address feeToken = s_sourceTokens[1]; uint256 feeTokenAmount = 10_000 gwei; - uint256 expectedConvertedAmount = s_priceRegistry.convertTokenAmount(feeToken, feeTokenAmount, s_sourceTokens[0]); + uint256 expectedConvertedAmount = s_feeQuoter.convertTokenAmount(feeToken, feeTokenAmount, s_sourceTokens[0]); ( uint256 msgFeeJuels, /* bool isOutOfOrderExecution */ , /* bytes memory convertedExtraArgs */ - ) = s_priceRegistry.processMessageArgs(DEST_CHAIN_SELECTOR, feeToken, feeTokenAmount, ""); + ) = s_feeQuoter.processMessageArgs(DEST_CHAIN_SELECTOR, feeToken, feeTokenAmount, ""); assertEq(msgFeeJuels, expectedConvertedAmount); } @@ -1798,12 +1766,10 @@ contract PriceRegistry_processMessageArgs is PriceRegistryFeeSetup { , bool isOutOfOrderExecution, bytes memory convertedExtraArgs - ) = s_priceRegistry.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, ""); + ) = s_feeQuoter.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, ""); assertEq(isOutOfOrderExecution, false); - assertEq( - convertedExtraArgs, Client._argsToBytes(s_priceRegistry.parseEVMExtraArgsFromBytes("", DEST_CHAIN_SELECTOR)) - ); + assertEq(convertedExtraArgs, Client._argsToBytes(s_feeQuoter.parseEVMExtraArgsFromBytes("", DEST_CHAIN_SELECTOR))); } function test_WithEVMExtraArgsV1_Success() public view { @@ -1814,12 +1780,11 @@ contract PriceRegistry_processMessageArgs is PriceRegistryFeeSetup { , bool isOutOfOrderExecution, bytes memory convertedExtraArgs - ) = s_priceRegistry.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, extraArgs); + ) = s_feeQuoter.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, extraArgs); assertEq(isOutOfOrderExecution, false); assertEq( - convertedExtraArgs, - Client._argsToBytes(s_priceRegistry.parseEVMExtraArgsFromBytes(extraArgs, DEST_CHAIN_SELECTOR)) + convertedExtraArgs, Client._argsToBytes(s_feeQuoter.parseEVMExtraArgsFromBytes(extraArgs, DEST_CHAIN_SELECTOR)) ); } @@ -1831,12 +1796,11 @@ contract PriceRegistry_processMessageArgs is PriceRegistryFeeSetup { , bool isOutOfOrderExecution, bytes memory convertedExtraArgs - ) = s_priceRegistry.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, extraArgs); + ) = s_feeQuoter.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, extraArgs); assertEq(isOutOfOrderExecution, true); assertEq( - convertedExtraArgs, - Client._argsToBytes(s_priceRegistry.parseEVMExtraArgsFromBytes(extraArgs, DEST_CHAIN_SELECTOR)) + convertedExtraArgs, Client._argsToBytes(s_feeQuoter.parseEVMExtraArgsFromBytes(extraArgs, DEST_CHAIN_SELECTOR)) ); } @@ -1844,23 +1808,23 @@ contract PriceRegistry_processMessageArgs is PriceRegistryFeeSetup { function test_MessageFeeTooHigh_Revert() public { vm.expectRevert( - abi.encodeWithSelector(PriceRegistry.MessageFeeTooHigh.selector, MAX_MSG_FEES_JUELS + 1, MAX_MSG_FEES_JUELS) + abi.encodeWithSelector(FeeQuoter.MessageFeeTooHigh.selector, MAX_MSG_FEES_JUELS + 1, MAX_MSG_FEES_JUELS) ); - s_priceRegistry.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], MAX_MSG_FEES_JUELS + 1, ""); + s_feeQuoter.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], MAX_MSG_FEES_JUELS + 1, ""); } function test_InvalidExtraArgs_Revert() public { - vm.expectRevert(PriceRegistry.InvalidExtraArgsTag.selector); + vm.expectRevert(FeeQuoter.InvalidExtraArgsTag.selector); - s_priceRegistry.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, "abcde"); + s_feeQuoter.processMessageArgs(DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, "abcde"); } function test_MalformedEVMExtraArgs_Revert() public { // abi.decode error vm.expectRevert(); - s_priceRegistry.processMessageArgs( + s_feeQuoter.processMessageArgs( DEST_CHAIN_SELECTOR, s_sourceTokens[0], 0, @@ -1869,8 +1833,8 @@ contract PriceRegistry_processMessageArgs is PriceRegistryFeeSetup { } } -contract PriceRegistry_processPoolReturnData is PriceRegistryFeeSetup { - function Test_ProcessPoolReturnData_Success() public view { +contract FeeQuoter_validatePoolReturnData is FeeQuoterFeeSetup { + function test_ProcessPoolReturnData_Success() public view { Client.EVMTokenAmount[] memory sourceTokenAmounts = new Client.EVMTokenAmount[](2); sourceTokenAmounts[0].amount = 1e18; sourceTokenAmounts[0].token = s_sourceTokens[0]; @@ -1882,13 +1846,13 @@ contract PriceRegistry_processPoolReturnData is PriceRegistryFeeSetup { rampTokenAmounts[1] = _getSourceTokenData(sourceTokenAmounts[1], s_tokenAdminRegistry, DEST_CHAIN_SELECTOR); bytes[] memory expectedDestExecData = new bytes[](2); expectedDestExecData[0] = abi.encode( - s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig.destGasOverhead + s_feeQuoterTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig.destGasOverhead ); expectedDestExecData[1] = abi.encode(DEFAULT_TOKEN_DEST_GAS_OVERHEAD); //expected return data should be abi.encoded default as isEnabled is false // No revert - successful bytes[] memory destExecData = - s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + s_feeQuoter.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); for (uint256 i = 0; i < destExecData.length; ++i) { assertEq(destExecData[i], expectedDestExecData[i]); @@ -1906,7 +1870,7 @@ contract PriceRegistry_processPoolReturnData is PriceRegistryFeeSetup { // Revert due to index out of bounds access vm.expectRevert(); - s_priceRegistry.processPoolReturnData( + s_feeQuoter.processPoolReturnData( DEST_CHAIN_SELECTOR, new Internal.RampTokenAmount[](1), new Client.EVMTokenAmount[](0) ); } @@ -1922,24 +1886,22 @@ contract PriceRegistry_processPoolReturnData is PriceRegistryFeeSetup { rampTokenAmounts[0] = _getSourceTokenData(sourceTokenAmounts[0], s_tokenAdminRegistry, DEST_CHAIN_SELECTOR); // No data set, should succeed - s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + s_feeQuoter.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); // Set max data length, should succeed rampTokenAmounts[0].extraData = new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES); - s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + s_feeQuoter.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); // Set data to max length +1, should revert rampTokenAmounts[0].extraData = new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + 1); - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.SourceTokenDataTooLarge.selector, sourceETH)); - s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.SourceTokenDataTooLarge.selector, sourceETH)); + s_feeQuoter.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); // Set token config to allow larger data - PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = - _generateTokenTransferFeeConfigArgs(1, 1); + FeeQuoter.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = _generateTokenTransferFeeConfigArgs(1, 1); tokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token = sourceETH; - tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = PriceRegistry - .TokenTransferFeeConfig({ + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = FeeQuoter.TokenTransferFeeConfig({ minFeeUSDCents: 1, maxFeeUSDCents: 0, deciBps: 0, @@ -1947,17 +1909,17 @@ contract PriceRegistry_processPoolReturnData is PriceRegistryFeeSetup { destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) + 32, isEnabled: true }); - s_priceRegistry.applyTokenTransferFeeConfigUpdates( - tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + s_feeQuoter.applyTokenTransferFeeConfigUpdates( + tokenTransferFeeConfigArgs, new FeeQuoter.TokenTransferFeeConfigRemoveArgs[](0) ); - s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + s_feeQuoter.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); // Set the token data larger than the configured token data, should revert rampTokenAmounts[0].extraData = new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + 32 + 1); - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.SourceTokenDataTooLarge.selector, sourceETH)); - s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.SourceTokenDataTooLarge.selector, sourceETH)); + s_feeQuoter.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); } function test_InvalidEVMAddressDestToken_Revert() public { @@ -1972,18 +1934,18 @@ contract PriceRegistry_processPoolReturnData is PriceRegistryFeeSetup { rampTokenAmounts[0].destTokenAddress = nonEvmAddress; vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, nonEvmAddress)); - s_priceRegistry.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); + s_feeQuoter.processPoolReturnData(DEST_CHAIN_SELECTOR, rampTokenAmounts, sourceTokenAmounts); } } -contract PriceRegistry_validateDestFamilyAddress is PriceRegistrySetup { +contract FeeQuoter_validateDestFamilyAddress is FeeQuoterSetup { function test_ValidEVMAddress_Success() public view { bytes memory encodedAddress = abi.encode(address(10000)); - s_priceRegistry.validateDestFamilyAddress(Internal.CHAIN_FAMILY_SELECTOR_EVM, encodedAddress); + s_feeQuoter.validateDestFamilyAddress(Internal.CHAIN_FAMILY_SELECTOR_EVM, encodedAddress); } function test_ValidNonEVMAddress_Success() public view { - s_priceRegistry.validateDestFamilyAddress(bytes4(uint32(1)), abi.encode(type(uint208).max)); + s_feeQuoter.validateDestFamilyAddress(bytes4(uint32(1)), abi.encode(type(uint208).max)); } // Reverts @@ -1991,34 +1953,34 @@ contract PriceRegistry_validateDestFamilyAddress is PriceRegistrySetup { function test_InvalidEVMAddress_Revert() public { bytes memory invalidAddress = abi.encode(type(uint208).max); vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, invalidAddress)); - s_priceRegistry.validateDestFamilyAddress(Internal.CHAIN_FAMILY_SELECTOR_EVM, invalidAddress); + s_feeQuoter.validateDestFamilyAddress(Internal.CHAIN_FAMILY_SELECTOR_EVM, invalidAddress); } function test_InvalidEVMAddressEncodePacked_Revert() public { bytes memory invalidAddress = abi.encodePacked(address(234)); vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, invalidAddress)); - s_priceRegistry.validateDestFamilyAddress(Internal.CHAIN_FAMILY_SELECTOR_EVM, invalidAddress); + s_feeQuoter.validateDestFamilyAddress(Internal.CHAIN_FAMILY_SELECTOR_EVM, invalidAddress); } function test_InvalidEVMAddressPrecompiles_Revert() public { for (uint160 i = 0; i < Internal.PRECOMPILE_SPACE; ++i) { bytes memory invalidAddress = abi.encode(address(i)); vm.expectRevert(abi.encodeWithSelector(Internal.InvalidEVMAddress.selector, invalidAddress)); - s_priceRegistry.validateDestFamilyAddress(Internal.CHAIN_FAMILY_SELECTOR_EVM, invalidAddress); + s_feeQuoter.validateDestFamilyAddress(Internal.CHAIN_FAMILY_SELECTOR_EVM, invalidAddress); } - s_priceRegistry.validateDestFamilyAddress( + s_feeQuoter.validateDestFamilyAddress( Internal.CHAIN_FAMILY_SELECTOR_EVM, abi.encode(address(uint160(Internal.PRECOMPILE_SPACE))) ); } } -contract PriceRegistry_parseEVMExtraArgsFromBytes is PriceRegistrySetup { - PriceRegistry.DestChainConfig private s_destChainConfig; +contract FeeQuoter_parseEVMExtraArgsFromBytes is FeeQuoterSetup { + FeeQuoter.DestChainConfig private s_destChainConfig; function setUp() public virtual override { super.setUp(); - s_destChainConfig = _generatePriceRegistryDestChainConfigArgs()[0].destChainConfig; + s_destChainConfig = _generateFeeQuoterDestChainConfigArgs()[0].destChainConfig; } function test_EVMExtraArgsV1_Success() public view { @@ -2028,7 +1990,7 @@ contract PriceRegistry_parseEVMExtraArgsFromBytes is PriceRegistrySetup { Client.EVMExtraArgsV2({gasLimit: GAS_LIMIT, allowOutOfOrderExecution: false}); vm.assertEq( - abi.encode(s_priceRegistry.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig)), + abi.encode(s_feeQuoter.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig)), abi.encode(expectedOutputArgs) ); } @@ -2039,7 +2001,7 @@ contract PriceRegistry_parseEVMExtraArgsFromBytes is PriceRegistrySetup { bytes memory inputExtraArgs = Client._argsToBytes(inputArgs); vm.assertEq( - abi.encode(s_priceRegistry.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig)), abi.encode(inputArgs) + abi.encode(s_feeQuoter.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig)), abi.encode(inputArgs) ); } @@ -2048,7 +2010,7 @@ contract PriceRegistry_parseEVMExtraArgsFromBytes is PriceRegistrySetup { Client.EVMExtraArgsV2({gasLimit: s_destChainConfig.defaultTxGasLimit, allowOutOfOrderExecution: false}); vm.assertEq( - abi.encode(s_priceRegistry.parseEVMExtraArgsFromBytes("", s_destChainConfig)), abi.encode(expectedOutputArgs) + abi.encode(s_feeQuoter.parseEVMExtraArgsFromBytes("", s_destChainConfig)), abi.encode(expectedOutputArgs) ); } @@ -2061,8 +2023,8 @@ contract PriceRegistry_parseEVMExtraArgsFromBytes is PriceRegistrySetup { // Invalidate selector inputExtraArgs[0] = bytes1(uint8(0)); - vm.expectRevert(PriceRegistry.InvalidExtraArgsTag.selector); - s_priceRegistry.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig); + vm.expectRevert(FeeQuoter.InvalidExtraArgsTag.selector); + s_feeQuoter.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig); } function test_EVMExtraArgsEnforceOutOfOrder_Revert() public { @@ -2071,8 +2033,8 @@ contract PriceRegistry_parseEVMExtraArgsFromBytes is PriceRegistrySetup { bytes memory inputExtraArgs = Client._argsToBytes(inputArgs); s_destChainConfig.enforceOutOfOrder = true; - vm.expectRevert(PriceRegistry.ExtraArgOutOfOrderExecutionMustBeTrue.selector); - s_priceRegistry.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig); + vm.expectRevert(FeeQuoter.ExtraArgOutOfOrderExecutionMustBeTrue.selector); + s_feeQuoter.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig); } function test_EVMExtraArgsGasLimitTooHigh_Revert() public { @@ -2080,18 +2042,18 @@ contract PriceRegistry_parseEVMExtraArgsFromBytes is PriceRegistrySetup { Client.EVMExtraArgsV2({gasLimit: s_destChainConfig.maxPerMsgGasLimit + 1, allowOutOfOrderExecution: true}); bytes memory inputExtraArgs = Client._argsToBytes(inputArgs); - vm.expectRevert(PriceRegistry.MessageGasLimitTooHigh.selector); - s_priceRegistry.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig); + vm.expectRevert(FeeQuoter.MessageGasLimitTooHigh.selector); + s_feeQuoter.parseEVMExtraArgsFromBytes(inputExtraArgs, s_destChainConfig); } } -contract PriceRegistry_KeystoneSetup is PriceRegistrySetup { - address constant FORWARDER_1 = address(0x1); - address constant WORKFLOW_OWNER_1 = address(0x3); - bytes10 constant WORKFLOW_NAME_1 = "workflow1"; - bytes2 constant REPORT_NAME_1 = "01"; - address onReportTestToken1; - address onReportTestToken2; +contract FeeQuoter_KeystoneSetup is FeeQuoterSetup { + address internal constant FORWARDER_1 = address(0x1); + address internal constant WORKFLOW_OWNER_1 = address(0x3); + bytes10 internal constant WORKFLOW_NAME_1 = "workflow1"; + bytes2 internal constant REPORT_NAME_1 = "01"; + address internal onReportTestToken1; + address internal onReportTestToken2; function setUp() public virtual override { super.setUp(); @@ -2106,57 +2068,54 @@ contract PriceRegistry_KeystoneSetup is PriceRegistrySetup { reportName: REPORT_NAME_1, isAllowed: true }); - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeeds = new PriceRegistry.TokenPriceFeedUpdate[](2); - tokenPriceFeeds[0] = PriceRegistry.TokenPriceFeedUpdate({ + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeeds = new FeeQuoter.TokenPriceFeedUpdate[](2); + tokenPriceFeeds[0] = FeeQuoter.TokenPriceFeedUpdate({ sourceToken: onReportTestToken1, - feedConfig: IPriceRegistry.TokenPriceFeedConfig({dataFeedAddress: address(0x0), tokenDecimals: 18}) + feedConfig: IFeeQuoter.TokenPriceFeedConfig({dataFeedAddress: address(0x0), tokenDecimals: 18}) }); - tokenPriceFeeds[1] = PriceRegistry.TokenPriceFeedUpdate({ + tokenPriceFeeds[1] = FeeQuoter.TokenPriceFeedUpdate({ sourceToken: onReportTestToken2, - feedConfig: IPriceRegistry.TokenPriceFeedConfig({dataFeedAddress: address(0x0), tokenDecimals: 20}) + feedConfig: IFeeQuoter.TokenPriceFeedConfig({dataFeedAddress: address(0x0), tokenDecimals: 20}) }); - s_priceRegistry.setReportPermissions(permissions); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeeds); + s_feeQuoter.setReportPermissions(permissions); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeeds); } } -contract PriceRegistry_onReport is PriceRegistry_KeystoneSetup { +contract FeeQuoter_onReport is FeeQuoter_KeystoneSetup { function test_onReport_Success() public { bytes memory encodedPermissionsMetadata = abi.encodePacked(keccak256(abi.encode("workflowCID")), WORKFLOW_NAME_1, WORKFLOW_OWNER_1, REPORT_NAME_1); - PriceRegistry.ReceivedCCIPFeedReport[] memory report = new PriceRegistry.ReceivedCCIPFeedReport[](2); + FeeQuoter.ReceivedCCIPFeedReport[] memory report = new FeeQuoter.ReceivedCCIPFeedReport[](2); report[0] = - PriceRegistry.ReceivedCCIPFeedReport({token: onReportTestToken1, price: 4e18, timestamp: uint32(block.timestamp)}); + FeeQuoter.ReceivedCCIPFeedReport({token: onReportTestToken1, price: 4e18, timestamp: uint32(block.timestamp)}); report[1] = - PriceRegistry.ReceivedCCIPFeedReport({token: onReportTestToken2, price: 4e18, timestamp: uint32(block.timestamp)}); + FeeQuoter.ReceivedCCIPFeedReport({token: onReportTestToken2, price: 4e18, timestamp: uint32(block.timestamp)}); - bytes memory encodedReport = abi.encode(report); - uint224 expectedStoredToken1Price = s_priceRegistry.calculateRebasedValue(18, 18, report[0].price); - uint224 expectedStoredToken2Price = s_priceRegistry.calculateRebasedValue(18, 20, report[1].price); + uint224 expectedStoredToken1Price = s_feeQuoter.calculateRebasedValue(18, 18, report[0].price); + uint224 expectedStoredToken2Price = s_feeQuoter.calculateRebasedValue(18, 20, report[1].price); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(onReportTestToken1, expectedStoredToken1Price, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(onReportTestToken1, expectedStoredToken1Price, block.timestamp); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(onReportTestToken2, expectedStoredToken2Price, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(onReportTestToken2, expectedStoredToken2Price, block.timestamp); changePrank(FORWARDER_1); - s_priceRegistry.onReport(encodedPermissionsMetadata, encodedReport); + s_feeQuoter.onReport(encodedPermissionsMetadata, abi.encode(report)); - vm.assertEq(s_priceRegistry.getTokenPrice(report[0].token).value, expectedStoredToken1Price); - vm.assertEq(s_priceRegistry.getTokenPrice(report[0].token).timestamp, report[0].timestamp); + vm.assertEq(s_feeQuoter.getTokenPrice(report[0].token).value, expectedStoredToken1Price); + vm.assertEq(s_feeQuoter.getTokenPrice(report[0].token).timestamp, report[0].timestamp); - vm.assertEq(s_priceRegistry.getTokenPrice(report[1].token).value, expectedStoredToken2Price); - vm.assertEq(s_priceRegistry.getTokenPrice(report[1].token).timestamp, report[1].timestamp); + vm.assertEq(s_feeQuoter.getTokenPrice(report[1].token).value, expectedStoredToken2Price); + vm.assertEq(s_feeQuoter.getTokenPrice(report[1].token).timestamp, report[1].timestamp); } function test_onReport_InvalidForwarder_Reverts() public { bytes memory encodedPermissionsMetadata = abi.encodePacked(keccak256(abi.encode("workflowCID")), WORKFLOW_NAME_1, WORKFLOW_OWNER_1, REPORT_NAME_1); - PriceRegistry.ReceivedCCIPFeedReport[] memory report = new PriceRegistry.ReceivedCCIPFeedReport[](1); + FeeQuoter.ReceivedCCIPFeedReport[] memory report = new FeeQuoter.ReceivedCCIPFeedReport[](1); report[0] = - PriceRegistry.ReceivedCCIPFeedReport({token: s_sourceTokens[0], price: 4e18, timestamp: uint32(block.timestamp)}); - - bytes memory encodedReport = abi.encode(report); + FeeQuoter.ReceivedCCIPFeedReport({token: s_sourceTokens[0], price: 4e18, timestamp: uint32(block.timestamp)}); vm.expectRevert( abi.encodeWithSelector( @@ -2168,21 +2127,19 @@ contract PriceRegistry_onReport is PriceRegistry_KeystoneSetup { ) ); changePrank(STRANGER); - s_priceRegistry.onReport(encodedPermissionsMetadata, encodedReport); + s_feeQuoter.onReport(encodedPermissionsMetadata, abi.encode(report)); } function test_onReport_UnsupportedToken_Reverts() public { bytes memory encodedPermissionsMetadata = abi.encodePacked(keccak256(abi.encode("workflowCID")), WORKFLOW_NAME_1, WORKFLOW_OWNER_1, REPORT_NAME_1); - PriceRegistry.ReceivedCCIPFeedReport[] memory report = new PriceRegistry.ReceivedCCIPFeedReport[](1); + FeeQuoter.ReceivedCCIPFeedReport[] memory report = new FeeQuoter.ReceivedCCIPFeedReport[](1); report[0] = - PriceRegistry.ReceivedCCIPFeedReport({token: s_sourceTokens[1], price: 4e18, timestamp: uint32(block.timestamp)}); + FeeQuoter.ReceivedCCIPFeedReport({token: s_sourceTokens[1], price: 4e18, timestamp: uint32(block.timestamp)}); - bytes memory encodedReport = abi.encode(report); - - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.TokenNotSupported.selector, s_sourceTokens[1])); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.TokenNotSupported.selector, s_sourceTokens[1])); changePrank(FORWARDER_1); - s_priceRegistry.onReport(encodedPermissionsMetadata, encodedReport); + s_feeQuoter.onReport(encodedPermissionsMetadata, abi.encode(report)); } function test_OnReport_StaleUpdate_Revert() public { @@ -2190,33 +2147,28 @@ contract PriceRegistry_onReport is PriceRegistry_KeystoneSetup { bytes memory encodedPermissionsMetadata = abi.encodePacked(keccak256(abi.encode("workflowCID")), WORKFLOW_NAME_1, WORKFLOW_OWNER_1, REPORT_NAME_1); - PriceRegistry.ReceivedCCIPFeedReport[] memory report = new PriceRegistry.ReceivedCCIPFeedReport[](1); + FeeQuoter.ReceivedCCIPFeedReport[] memory report = new FeeQuoter.ReceivedCCIPFeedReport[](1); report[0] = - PriceRegistry.ReceivedCCIPFeedReport({token: onReportTestToken1, price: 4e18, timestamp: uint32(block.timestamp)}); + FeeQuoter.ReceivedCCIPFeedReport({token: onReportTestToken1, price: 4e18, timestamp: uint32(block.timestamp)}); - bytes memory encodedReport = abi.encode(report); - uint224 expectedStoredTokenPrice = s_priceRegistry.calculateRebasedValue(18, 18, report[0].price); + uint224 expectedStoredTokenPrice = s_feeQuoter.calculateRebasedValue(18, 18, report[0].price); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(onReportTestToken1, expectedStoredTokenPrice, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(onReportTestToken1, expectedStoredTokenPrice, block.timestamp); changePrank(FORWARDER_1); //setting the correct price and time with the correct report - s_priceRegistry.onReport(encodedPermissionsMetadata, encodedReport); + s_feeQuoter.onReport(encodedPermissionsMetadata, abi.encode(report)); //create a stale report - report[0] = PriceRegistry.ReceivedCCIPFeedReport({ - token: onReportTestToken1, - price: 4e18, - timestamp: uint32(block.timestamp - 1) - }); - encodedReport = abi.encode(report); + report[0] = + FeeQuoter.ReceivedCCIPFeedReport({token: onReportTestToken1, price: 4e18, timestamp: uint32(block.timestamp - 1)}); //expecting a revert vm.expectRevert( abi.encodeWithSelector( - PriceRegistry.StaleKeystoneUpdate.selector, onReportTestToken1, block.timestamp - 1, block.timestamp + FeeQuoter.StaleKeystoneUpdate.selector, onReportTestToken1, block.timestamp - 1, block.timestamp ) ); - s_priceRegistry.onReport(encodedPermissionsMetadata, encodedReport); + s_feeQuoter.onReport(encodedPermissionsMetadata, abi.encode(report)); } } diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistrySetup.t.sol b/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoterSetup.t.sol similarity index 76% rename from contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistrySetup.t.sol rename to contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoterSetup.t.sol index ee76c51c53..124980bc81 100644 --- a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistrySetup.t.sol +++ b/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoterSetup.t.sol @@ -1,17 +1,17 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; +import {IFeeQuoter} from "../../interfaces/IFeeQuoter.sol"; import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol"; -import {PriceRegistry} from "../../PriceRegistry.sol"; +import {FeeQuoter} from "../../FeeQuoter.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; import {TokenSetup} from "../TokenSetup.t.sol"; -import {PriceRegistryHelper} from "../helpers/PriceRegistryHelper.sol"; +import {FeeQuoterHelper} from "../helpers/FeeQuoterHelper.sol"; -contract PriceRegistrySetup is TokenSetup { +contract FeeQuoterSetup is TokenSetup { uint112 internal constant USD_PER_GAS = 1e6; // 0.001 gwei uint112 internal constant USD_PER_DATA_AVAILABILITY_GAS = 1e9; // 1 gwei @@ -26,7 +26,7 @@ contract PriceRegistrySetup is TokenSetup { uint224 internal constant PACKED_USD_PER_GAS = (uint224(USD_PER_DATA_AVAILABILITY_GAS) << Internal.GAS_PRICE_BITS) + USD_PER_GAS; - PriceRegistryHelper internal s_priceRegistry; + FeeQuoterHelper internal s_feeQuoter; // Cheat to store the price updates in storage since struct arrays aren't supported. bytes internal s_encodedInitialPriceUpdates; address internal s_weth; @@ -36,8 +36,8 @@ contract PriceRegistrySetup is TokenSetup { address[] internal s_destFeeTokens; uint224[] internal s_destTokenPrices; - PriceRegistry.PremiumMultiplierWeiPerEthArgs[] internal s_priceRegistryPremiumMultiplierWeiPerEthArgs; - PriceRegistry.TokenTransferFeeConfigArgs[] internal s_priceRegistryTokenTransferFeeConfigArgs; + FeeQuoter.PremiumMultiplierWeiPerEthArgs[] internal s_feeQuoterPremiumMultiplierWeiPerEthArgs; + FeeQuoter.TokenTransferFeeConfigArgs[] internal s_feeQuoterTokenTransferFeeConfigArgs; mapping(address token => address dataFeedAddress) internal s_dataFeedByToken; @@ -98,27 +98,27 @@ contract PriceRegistrySetup is TokenSetup { address[] memory feeTokens = new address[](2); feeTokens[0] = s_sourceTokens[0]; feeTokens[1] = s_weth; - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](0); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](0); - s_priceRegistryPremiumMultiplierWeiPerEthArgs.push( - PriceRegistry.PremiumMultiplierWeiPerEthArgs({ + s_feeQuoterPremiumMultiplierWeiPerEthArgs.push( + FeeQuoter.PremiumMultiplierWeiPerEthArgs({ token: s_sourceFeeToken, premiumMultiplierWeiPerEth: 5e17 // 0.5x }) ); - s_priceRegistryPremiumMultiplierWeiPerEthArgs.push( - PriceRegistry.PremiumMultiplierWeiPerEthArgs({ + s_feeQuoterPremiumMultiplierWeiPerEthArgs.push( + FeeQuoter.PremiumMultiplierWeiPerEthArgs({ token: s_sourceRouter.getWrappedNative(), premiumMultiplierWeiPerEth: 2e18 // 2x }) ); - s_priceRegistryTokenTransferFeeConfigArgs.push(); - s_priceRegistryTokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; - s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( - PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ + s_feeQuoterTokenTransferFeeConfigArgs.push(); + s_feeQuoterTokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; + s_feeQuoterTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( + FeeQuoter.TokenTransferFeeConfigSingleTokenArgs({ token: s_sourceFeeToken, - tokenTransferFeeConfig: PriceRegistry.TokenTransferFeeConfig({ + tokenTransferFeeConfig: FeeQuoter.TokenTransferFeeConfig({ minFeeUSDCents: 1_00, // 1 USD maxFeeUSDCents: 1000_00, // 1,000 USD deciBps: 2_5, // 2.5 bps, or 0.025% @@ -128,10 +128,10 @@ contract PriceRegistrySetup is TokenSetup { }) }) ); - s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( - PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ + s_feeQuoterTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( + FeeQuoter.TokenTransferFeeConfigSingleTokenArgs({ token: CUSTOM_TOKEN, - tokenTransferFeeConfig: PriceRegistry.TokenTransferFeeConfig({ + tokenTransferFeeConfig: FeeQuoter.TokenTransferFeeConfig({ minFeeUSDCents: 2_00, // 1 USD maxFeeUSDCents: 2000_00, // 1,000 USD deciBps: 10_0, // 10 bps, or 0.1% @@ -141,10 +141,10 @@ contract PriceRegistrySetup is TokenSetup { }) }) ); - s_priceRegistryTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( - PriceRegistry.TokenTransferFeeConfigSingleTokenArgs({ + s_feeQuoterTokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs.push( + FeeQuoter.TokenTransferFeeConfigSingleTokenArgs({ token: CUSTOM_TOKEN_2, - tokenTransferFeeConfig: PriceRegistry.TokenTransferFeeConfig({ + tokenTransferFeeConfig: FeeQuoter.TokenTransferFeeConfig({ minFeeUSDCents: 2_00, // 1 USD maxFeeUSDCents: 2000_00, // 1,000 USD deciBps: 10_0, // 10 bps, or 0.1% @@ -158,8 +158,8 @@ contract PriceRegistrySetup is TokenSetup { //setting up the destination token for CUSTOM_TOKEN_2 here as it is specific to these tests s_destTokenBySourceToken[CUSTOM_TOKEN_2] = address(bytes20(keccak256("CUSTOM_TOKEN_2_DEST"))); - s_priceRegistry = new PriceRegistryHelper( - PriceRegistry.StaticConfig({ + s_feeQuoter = new FeeQuoterHelper( + FeeQuoter.StaticConfig({ linkToken: s_sourceTokens[0], maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS, stalenessThreshold: uint32(TWELVE_HOURS) @@ -167,11 +167,11 @@ contract PriceRegistrySetup is TokenSetup { priceUpdaters, feeTokens, tokenPriceFeedUpdates, - s_priceRegistryTokenTransferFeeConfigArgs, - s_priceRegistryPremiumMultiplierWeiPerEthArgs, - _generatePriceRegistryDestChainConfigArgs() + s_feeQuoterTokenTransferFeeConfigArgs, + s_feeQuoterPremiumMultiplierWeiPerEthArgs, + _generateFeeQuoterDestChainConfigArgs() ); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); } function _deployTokenPriceDataFeed(address token, uint8 decimals, int256 initialAnswer) internal returns (address) { @@ -207,43 +207,39 @@ contract PriceRegistrySetup is TokenSetup { address sourceToken, address dataFeedAddress, uint8 tokenDecimals - ) internal pure returns (PriceRegistry.TokenPriceFeedUpdate memory) { - return PriceRegistry.TokenPriceFeedUpdate({ + ) internal pure returns (FeeQuoter.TokenPriceFeedUpdate memory) { + return FeeQuoter.TokenPriceFeedUpdate({ sourceToken: sourceToken, - feedConfig: IPriceRegistry.TokenPriceFeedConfig({dataFeedAddress: dataFeedAddress, tokenDecimals: tokenDecimals}) + feedConfig: IFeeQuoter.TokenPriceFeedConfig({dataFeedAddress: dataFeedAddress, tokenDecimals: tokenDecimals}) }); } function _initialiseSingleTokenPriceFeed() internal returns (address) { - PriceRegistry.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new PriceRegistry.TokenPriceFeedUpdate[](1); + FeeQuoter.TokenPriceFeedUpdate[] memory tokenPriceFeedUpdates = new FeeQuoter.TokenPriceFeedUpdate[](1); tokenPriceFeedUpdates[0] = _getSingleTokenPriceFeedUpdateStruct(s_sourceTokens[0], s_dataFeedByToken[s_sourceTokens[0]], 18); - s_priceRegistry.updateTokenPriceFeeds(tokenPriceFeedUpdates); + s_feeQuoter.updateTokenPriceFeeds(tokenPriceFeedUpdates); return s_sourceTokens[0]; } function _generateTokenTransferFeeConfigArgs( uint256 destChainSelectorLength, uint256 tokenLength - ) internal pure returns (PriceRegistry.TokenTransferFeeConfigArgs[] memory) { - PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = - new PriceRegistry.TokenTransferFeeConfigArgs[](destChainSelectorLength); + ) internal pure returns (FeeQuoter.TokenTransferFeeConfigArgs[] memory) { + FeeQuoter.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = + new FeeQuoter.TokenTransferFeeConfigArgs[](destChainSelectorLength); for (uint256 i = 0; i < destChainSelectorLength; ++i) { tokenTransferFeeConfigArgs[i].tokenTransferFeeConfigs = - new PriceRegistry.TokenTransferFeeConfigSingleTokenArgs[](tokenLength); + new FeeQuoter.TokenTransferFeeConfigSingleTokenArgs[](tokenLength); } return tokenTransferFeeConfigArgs; } - function _generatePriceRegistryDestChainConfigArgs() - internal - pure - returns (PriceRegistry.DestChainConfigArgs[] memory) - { - PriceRegistry.DestChainConfigArgs[] memory destChainConfigs = new PriceRegistry.DestChainConfigArgs[](1); - destChainConfigs[0] = PriceRegistry.DestChainConfigArgs({ + function _generateFeeQuoterDestChainConfigArgs() internal pure returns (FeeQuoter.DestChainConfigArgs[] memory) { + FeeQuoter.DestChainConfigArgs[] memory destChainConfigs = new FeeQuoter.DestChainConfigArgs[](1); + destChainConfigs[0] = FeeQuoter.DestChainConfigArgs({ destChainSelector: DEST_CHAIN_SELECTOR, - destChainConfig: PriceRegistry.DestChainConfig({ + destChainConfig: FeeQuoter.DestChainConfig({ isEnabled: true, maxNumberOfTokensPerMsg: MAX_TOKENS_LENGTH, destGasOverhead: DEST_GAS_OVERHEAD, @@ -266,26 +262,22 @@ contract PriceRegistrySetup is TokenSetup { } function _assertTokenPriceFeedConfigEquality( - IPriceRegistry.TokenPriceFeedConfig memory config1, - IPriceRegistry.TokenPriceFeedConfig memory config2 + IFeeQuoter.TokenPriceFeedConfig memory config1, + IFeeQuoter.TokenPriceFeedConfig memory config2 ) internal pure virtual { assertEq(config1.dataFeedAddress, config2.dataFeedAddress); assertEq(config1.tokenDecimals, config2.tokenDecimals); } - function _assertTokenPriceFeedConfigUnconfigured(IPriceRegistry.TokenPriceFeedConfig memory config) - internal - pure - virtual - { + function _assertTokenPriceFeedConfigUnconfigured(IFeeQuoter.TokenPriceFeedConfig memory config) internal pure virtual { _assertTokenPriceFeedConfigEquality( - config, IPriceRegistry.TokenPriceFeedConfig({dataFeedAddress: address(0), tokenDecimals: 0}) + config, IFeeQuoter.TokenPriceFeedConfig({dataFeedAddress: address(0), tokenDecimals: 0}) ); } function _assertTokenTransferFeeConfigEqual( - PriceRegistry.TokenTransferFeeConfig memory a, - PriceRegistry.TokenTransferFeeConfig memory b + FeeQuoter.TokenTransferFeeConfig memory a, + FeeQuoter.TokenTransferFeeConfig memory b ) internal pure { assertEq(a.minFeeUSDCents, b.minFeeUSDCents); assertEq(a.maxFeeUSDCents, b.maxFeeUSDCents); @@ -295,17 +287,17 @@ contract PriceRegistrySetup is TokenSetup { assertEq(a.isEnabled, b.isEnabled); } - function _assertPriceRegistryStaticConfigsEqual( - PriceRegistry.StaticConfig memory a, - PriceRegistry.StaticConfig memory b + function _assertFeeQuoterStaticConfigsEqual( + FeeQuoter.StaticConfig memory a, + FeeQuoter.StaticConfig memory b ) internal pure { assertEq(a.linkToken, b.linkToken); assertEq(a.maxFeeJuelsPerMsg, b.maxFeeJuelsPerMsg); } - function _assertPriceRegistryDestChainConfigsEqual( - PriceRegistry.DestChainConfig memory a, - PriceRegistry.DestChainConfig memory b + function _assertFeeQuoterDestChainConfigsEqual( + FeeQuoter.DestChainConfig memory a, + FeeQuoter.DestChainConfig memory b ) internal pure { assertEq(a.isEnabled, b.isEnabled); assertEq(a.maxNumberOfTokensPerMsg, b.maxNumberOfTokensPerMsg); @@ -322,7 +314,7 @@ contract PriceRegistrySetup is TokenSetup { } } -contract PriceRegistryFeeSetup is PriceRegistrySetup { +contract FeeQuoterFeeSetup is FeeQuoterSetup { uint224 internal s_feeTokenPrice; uint224 internal s_wrappedTokenPrice; uint224 internal s_customTokenPrice; @@ -339,7 +331,7 @@ contract PriceRegistryFeeSetup is PriceRegistrySetup { s_wrappedTokenPrice = s_sourceTokenPrices[2]; s_customTokenPrice = CUSTOM_TOKEN_PRICE; - s_priceRegistry.updatePrices(_getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); + s_feeQuoter.updatePrices(_getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); } function _generateEmptyMessage() public view returns (Client.EVM2AnyMessage memory) { @@ -380,7 +372,7 @@ contract PriceRegistryFeeSetup is PriceRegistrySetup { TokenAdminRegistry tokenAdminRegistry ) internal view returns (Internal.EVM2AnyRampMessage memory) { Client.EVMExtraArgsV2 memory extraArgs = - s_priceRegistry.parseEVMExtraArgsFromBytes(message.extraArgs, destChainSelector); + s_feeQuoter.parseEVMExtraArgsFromBytes(message.extraArgs, destChainSelector); Internal.EVM2AnyRampMessage memory messageEvent = Internal.EVM2AnyRampMessage({ header: Internal.RampMessageHeader({ @@ -415,12 +407,9 @@ contract PriceRegistryFeeSetup is PriceRegistrySetup { ) internal view returns (Internal.RampTokenAmount memory) { address destToken = s_destTokenBySourceToken[tokenAmount.token]; - uint256 tokenTransferFeeConfigArgIndex; - uint256 tokenTransferFeeConfigsIndex; - uint32 expectedDestGasAmount; - PriceRegistry.TokenTransferFeeConfig memory tokenTransferFeeConfig = - PriceRegistry(s_priceRegistry).getTokenTransferFeeConfig(destChainSelector, tokenAmount.token); + FeeQuoter.TokenTransferFeeConfig memory tokenTransferFeeConfig = + FeeQuoter(s_feeQuoter).getTokenTransferFeeConfig(destChainSelector, tokenAmount.token); expectedDestGasAmount = tokenTransferFeeConfig.isEnabled ? tokenTransferFeeConfig.destGasOverhead : DEFAULT_TOKEN_DEST_GAS_OVERHEAD; diff --git a/contracts/src/v0.8/ccip/test/helpers/PriceRegistryHelper.sol b/contracts/src/v0.8/ccip/test/helpers/FeeQuoterHelper.sol similarity index 95% rename from contracts/src/v0.8/ccip/test/helpers/PriceRegistryHelper.sol rename to contracts/src/v0.8/ccip/test/helpers/FeeQuoterHelper.sol index f939cd3c1f..e392ba0558 100644 --- a/contracts/src/v0.8/ccip/test/helpers/PriceRegistryHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/FeeQuoterHelper.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {PriceRegistry} from "../../PriceRegistry.sol"; +import {FeeQuoter} from "../../FeeQuoter.sol"; import {Client} from "../../libraries/Client.sol"; -contract PriceRegistryHelper is PriceRegistry { +contract FeeQuoterHelper is FeeQuoter { constructor( StaticConfig memory staticConfig, address[] memory priceUpdaters, @@ -14,7 +14,7 @@ contract PriceRegistryHelper is PriceRegistry { PremiumMultiplierWeiPerEthArgs[] memory premiumMultiplierWeiPerEthArgs, DestChainConfigArgs[] memory destChainConfigArgs ) - PriceRegistry( + FeeQuoter( staticConfig, priceUpdaters, feeTokens, diff --git a/contracts/src/v0.8/ccip/test/helpers/MultiAggregateRateLimiterHelper.sol b/contracts/src/v0.8/ccip/test/helpers/MultiAggregateRateLimiterHelper.sol index 2bcaabda33..d011ba0685 100644 --- a/contracts/src/v0.8/ccip/test/helpers/MultiAggregateRateLimiterHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/MultiAggregateRateLimiterHelper.sol @@ -6,9 +6,9 @@ import {Client} from "../../libraries/Client.sol"; contract MultiAggregateRateLimiterHelper is MultiAggregateRateLimiter { constructor( - address priceRegistry, + address feeQuoter, address[] memory authorizedCallers - ) MultiAggregateRateLimiter(priceRegistry, authorizedCallers) {} + ) MultiAggregateRateLimiter(feeQuoter, authorizedCallers) {} function getTokenValue(Client.EVMTokenAmount memory tokenAmount) public view returns (uint256) { return _getTokenValue(tokenAmount); diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol index 6162419367..493d02c7c2 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol @@ -41,7 +41,7 @@ contract EVM2EVMOffRamp_constructor is EVM2EVMOffRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry) }); EVM2EVMOffRamp.DynamicConfig memory dynamicConfig = - generateDynamicOffRampConfig(address(s_destRouter), address(s_priceRegistry)); + generateDynamicOffRampConfig(address(s_destRouter), address(s_feeQuoter)); s_offRamp = new EVM2EVMOffRampHelper(staticConfig, _getInboundRateLimiterConfig()); @@ -112,7 +112,7 @@ contract EVM2EVMOffRamp_constructor is EVM2EVMOffRampSetup { contract EVM2EVMOffRamp_setDynamicConfig is EVM2EVMOffRampSetup { function test_SetDynamicConfig_Success() public { EVM2EVMOffRamp.StaticConfig memory staticConfig = s_offRamp.getStaticConfig(); - EVM2EVMOffRamp.DynamicConfig memory dynamicConfig = generateDynamicOffRampConfig(USER_3, address(s_priceRegistry)); + EVM2EVMOffRamp.DynamicConfig memory dynamicConfig = generateDynamicOffRampConfig(USER_3, address(s_feeQuoter)); bytes memory onchainConfig = abi.encode(dynamicConfig); vm.expectEmit(); @@ -142,7 +142,7 @@ contract EVM2EVMOffRamp_setDynamicConfig is EVM2EVMOffRampSetup { function test_NonOwner_Revert() public { vm.startPrank(STRANGER); - EVM2EVMOffRamp.DynamicConfig memory dynamicConfig = generateDynamicOffRampConfig(USER_3, address(s_priceRegistry)); + EVM2EVMOffRamp.DynamicConfig memory dynamicConfig = generateDynamicOffRampConfig(USER_3, address(s_feeQuoter)); vm.expectRevert("Only callable by owner"); @@ -1856,7 +1856,7 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { // Set a high price to trip the ARL uint224 tokenPrice = 3 ** 128; Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(s_destFeeToken, tokenPrice); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); uint256 amount1 = 100; @@ -2032,7 +2032,7 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { function test_PriceNotFoundForToken_Reverts() public { // Set token price to 0 - s_priceRegistry.updatePrices(_getSingleTokenPriceUpdateStruct(s_destFeeToken, 0)); + s_feeQuoter.updatePrices(_getSingleTokenPriceUpdateStruct(s_destFeeToken, 0)); Client.EVMTokenAmount[] memory srcTokenAmounts = _getCastedSourceEVMTokenAmountsWithZeroAmounts(); uint256 amount1 = 100; diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol index a0fa6a4a8e..a5cb4f3d2b 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol @@ -10,14 +10,15 @@ import {Internal} from "../../libraries/Internal.sol"; import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; import {TokenSetup} from "../TokenSetup.t.sol"; + +import {FeeQuoterSetup} from "../feeQuoter/FeeQuoterSetup.t.sol"; import {EVM2EVMOffRampHelper} from "../helpers/EVM2EVMOffRampHelper.sol"; import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; import {MockCommitStore} from "../mocks/MockCommitStore.sol"; import {OCR2BaseSetup} from "../ocr/OCR2Base.t.sol"; -import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; -contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { +contract EVM2EVMOffRampSetup is TokenSetup, FeeQuoterSetup, OCR2BaseSetup { MockCommitStore internal s_mockCommitStore; IAny2EVMMessageReceiver internal s_receiver; IAny2EVMMessageReceiver internal s_secondary_receiver; @@ -28,9 +29,9 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { EVM2EVMOffRampHelper internal s_offRamp; address internal s_sourceTokenPool = makeAddr("sourceTokenPool"); - function setUp() public virtual override(TokenSetup, PriceRegistrySetup, OCR2BaseSetup) { + function setUp() public virtual override(TokenSetup, FeeQuoterSetup, OCR2BaseSetup) { TokenSetup.setUp(); - PriceRegistrySetup.setUp(); + FeeQuoterSetup.setUp(); OCR2BaseSetup.setUp(); s_mockCommitStore = new MockCommitStore(); @@ -60,7 +61,7 @@ contract EVM2EVMOffRampSetup is TokenSetup, PriceRegistrySetup, OCR2BaseSetup { s_valid_signers, s_valid_transmitters, s_f, - abi.encode(generateDynamicOffRampConfig(address(router), address(s_priceRegistry))), + abi.encode(generateDynamicOffRampConfig(address(router), address(s_feeQuoter))), s_offchainConfigVersion, abi.encode("") ); diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol index 04c7b0b63b..b3fb5de5a2 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol @@ -1,15 +1,15 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; +import {IFeeQuoter} from "../../interfaces/IFeeQuoter.sol"; import {IMessageInterceptor} from "../../interfaces/IMessageInterceptor.sol"; -import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; import {IRMN} from "../../interfaces/IRMN.sol"; import {IRouter} from "../../interfaces/IRouter.sol"; import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; import {CallWithExactGas} from "../../../shared/call/CallWithExactGas.sol"; +import {FeeQuoter} from "../../FeeQuoter.sol"; import {NonceManager} from "../../NonceManager.sol"; -import {PriceRegistry} from "../../PriceRegistry.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {MerkleMultiProof} from "../../libraries/MerkleMultiProof.sol"; @@ -38,7 +38,7 @@ contract OffRamp_constructor is OffRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }); - OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(address(s_priceRegistry)); + OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(address(s_feeQuoter)); OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](2); sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ @@ -159,7 +159,7 @@ contract OffRamp_constructor is OffRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_feeQuoter)), sourceChainConfigs ); } @@ -185,7 +185,7 @@ contract OffRamp_constructor is OffRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_feeQuoter)), sourceChainConfigs ); } @@ -205,7 +205,7 @@ contract OffRamp_constructor is OffRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_feeQuoter)), sourceChainConfigs ); } @@ -225,7 +225,7 @@ contract OffRamp_constructor is OffRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_feeQuoter)), sourceChainConfigs ); } @@ -245,7 +245,7 @@ contract OffRamp_constructor is OffRampSetup { tokenAdminRegistry: ZERO_ADDRESS, nonceManager: address(s_inboundNonceManager) }), - _generateDynamicOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_feeQuoter)), sourceChainConfigs ); } @@ -265,7 +265,7 @@ contract OffRamp_constructor is OffRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: ZERO_ADDRESS }), - _generateDynamicOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_feeQuoter)), sourceChainConfigs ); } @@ -273,7 +273,7 @@ contract OffRamp_constructor is OffRampSetup { contract OffRamp_setDynamicConfig is OffRampSetup { function test_SetDynamicConfig_Success() public { - OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(address(s_priceRegistry)); + OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(address(s_feeQuoter)); vm.expectEmit(); emit OffRamp.DynamicConfigSet(dynamicConfig); @@ -285,7 +285,7 @@ contract OffRamp_setDynamicConfig is OffRampSetup { } function test_SetDynamicConfigWithValidator_Success() public { - OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(address(s_priceRegistry)); + OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(address(s_feeQuoter)); dynamicConfig.messageValidator = address(s_inboundMessageValidator); vm.expectEmit(); @@ -301,14 +301,14 @@ contract OffRamp_setDynamicConfig is OffRampSetup { function test_NonOwner_Revert() public { vm.startPrank(STRANGER); - OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(address(s_priceRegistry)); + OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(address(s_feeQuoter)); vm.expectRevert("Only callable by owner"); s_offRamp.setDynamicConfig(dynamicConfig); } - function test_PriceRegistryZeroAddress_Revert() public { + function test_FeeQuoterZeroAddress_Revert() public { OffRamp.DynamicConfig memory dynamicConfig = _generateDynamicOffRampConfig(ZERO_ADDRESS); vm.expectRevert(OffRamp.ZeroAddressNotAllowed.selector); @@ -2953,8 +2953,7 @@ contract OffRamp_commit is OffRampSetup { function test_StaleReportWithRoot_Success() public { uint64 maxSeq = 12; - uint224 tokenStartPrice = - IPriceRegistry(s_offRamp.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value; + uint224 tokenStartPrice = IFeeQuoter(s_offRamp.getDynamicConfig().feeQuoter).getTokenPrice(s_sourceFeeToken).value; OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); roots[0] = OffRamp.MerkleRoot({ @@ -2989,9 +2988,7 @@ contract OffRamp_commit is OffRampSetup { assertEq(maxSeq * 2 + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); - assertEq( - tokenStartPrice, IPriceRegistry(s_offRamp.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value - ); + assertEq(tokenStartPrice, IFeeQuoter(s_offRamp.getDynamicConfig().feeQuoter).getTokenPrice(s_sourceFeeToken).value); } function test_OnlyTokenPriceUpdates_Success() public { @@ -3000,7 +2997,7 @@ contract OffRamp_commit is OffRampSetup { OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); vm.expectEmit(); emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); @@ -3016,7 +3013,7 @@ contract OffRamp_commit is OffRampSetup { OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); vm.expectEmit(); emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); @@ -3031,7 +3028,7 @@ contract OffRamp_commit is OffRampSetup { OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); _commit(commitReport, s_latestSequenceNumber); assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); @@ -3066,7 +3063,7 @@ contract OffRamp_commit is OffRampSetup { // The same sequence number can be reported again vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); _commit(commitReport, s_latestSequenceNumber); } @@ -3082,7 +3079,7 @@ contract OffRamp_commit is OffRampSetup { }); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, tokenPrice1, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, tokenPrice1, block.timestamp); vm.expectEmit(); emit MultiOCR3Base.Transmitted(uint8(Internal.OCRPluginType.Commit), s_configDigestCommit, s_latestSequenceNumber); @@ -3108,9 +3105,7 @@ contract OffRamp_commit is OffRampSetup { _commit(commitReport, s_latestSequenceNumber); assertEq(maxSeq + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); - assertEq( - tokenPrice1, IPriceRegistry(s_offRamp.getDynamicConfig().priceRegistry).getTokenPrice(s_sourceFeeToken).value - ); + assertEq(tokenPrice1, IFeeQuoter(s_offRamp.getDynamicConfig().feeQuoter).getTokenPrice(s_sourceFeeToken).value); assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); } @@ -3258,7 +3253,7 @@ contract OffRamp_commit is OffRampSetup { OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); vm.expectEmit(); - emit PriceRegistry.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); _commit(commitReport, s_latestSequenceNumber); vm.expectRevert(OffRamp.StaleCommitReport.selector); diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol index fb61fbfc7d..ff051cdd21 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol @@ -15,16 +15,17 @@ import {MultiOCR3Base} from "../../ocr/MultiOCR3Base.sol"; import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; import {OffRamp} from "../../offRamp/OffRamp.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; + +import {FeeQuoterSetup} from "../feeQuoter/FeeQuoterSetup.t.sol"; import {EVM2EVMOffRampHelper} from "../helpers/EVM2EVMOffRampHelper.sol"; import {MaybeRevertingBurnMintTokenPool} from "../helpers/MaybeRevertingBurnMintTokenPool.sol"; import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; import {OffRampHelper} from "../helpers/OffRampHelper.sol"; import {MaybeRevertMessageReceiver} from "../helpers/receivers/MaybeRevertMessageReceiver.sol"; import {MultiOCR3BaseSetup} from "../ocr/MultiOCR3BaseSetup.t.sol"; -import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; import {Vm} from "forge-std/Test.sol"; -contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { +contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { uint64 internal constant SOURCE_CHAIN_SELECTOR_1 = SOURCE_CHAIN_SELECTOR; uint64 internal constant SOURCE_CHAIN_SELECTOR_2 = 6433500567565415381; uint64 internal constant SOURCE_CHAIN_SELECTOR_3 = 4051577828743386545; @@ -56,8 +57,8 @@ contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { uint64 internal s_latestSequenceNumber; - function setUp() public virtual override(PriceRegistrySetup, MultiOCR3BaseSetup) { - PriceRegistrySetup.setUp(); + function setUp() public virtual override(FeeQuoterSetup, MultiOCR3BaseSetup) { + FeeQuoterSetup.setUp(); MultiOCR3BaseSetup.setUp(); s_inboundMessageValidator = new MessageInterceptorHelper(); @@ -81,7 +82,7 @@ contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(nonceManager) }), - _generateDynamicOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_feeQuoter)), sourceChainConfigs ); @@ -106,7 +107,7 @@ contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { transmitters: s_validTransmitters }); - s_offRamp.setDynamicConfig(_generateDynamicOffRampConfig(address(s_priceRegistry))); + s_offRamp.setDynamicConfig(_generateDynamicOffRampConfig(address(s_feeQuoter))); s_offRamp.setOCR3Configs(ocrConfigs); address[] memory authorizedCallers = new address[](1); @@ -117,7 +118,7 @@ contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { address[] memory priceUpdaters = new address[](1); priceUpdaters[0] = address(s_offRamp); - s_priceRegistry.applyAuthorizedCallerUpdates( + s_feeQuoter.applyAuthorizedCallerUpdates( AuthorizedCallers.AuthorizedCallerArgs({addedCallers: priceUpdaters, removedCallers: new address[](0)}) ); } @@ -146,7 +147,7 @@ contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { s_validSigners, s_validTransmitters, s_F, - abi.encode(_generateDynamicOffRampConfig(address(router), address(s_priceRegistry))), + abi.encode(_generateDynamicOffRampConfig(address(router), address(s_feeQuoter))), s_offchainConfigVersion, abi.encode("") ); @@ -223,10 +224,10 @@ contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { uint32 internal constant MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS = 200_000; uint32 internal constant MAX_TOKEN_POOL_TRANSFER_GAS = 50_000; - function _generateDynamicOffRampConfig(address priceRegistry) internal pure returns (OffRamp.DynamicConfig memory) { + function _generateDynamicOffRampConfig(address feeQuoter) internal pure returns (OffRamp.DynamicConfig memory) { return OffRamp.DynamicConfig({ permissionLessExecutionThresholdSeconds: PERMISSION_LESS_EXECUTION_THRESHOLD_SECONDS, - priceRegistry: priceRegistry, + feeQuoter: feeQuoter, messageValidator: address(0), maxPoolReleaseOrMintGas: MAX_TOKEN_POOL_RELEASE_OR_MINT_GAS, maxTokenTransferGas: MAX_TOKEN_POOL_TRANSFER_GAS @@ -391,7 +392,7 @@ contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { assertEq(a.maxPoolReleaseOrMintGas, b.maxPoolReleaseOrMintGas); assertEq(a.maxTokenTransferGas, b.maxTokenTransferGas); assertEq(a.messageValidator, b.messageValidator); - assertEq(a.priceRegistry, b.priceRegistry); + assertEq(a.feeQuoter, b.feeQuoter); } function _assertSourceChainConfigEquality( @@ -436,7 +437,7 @@ contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), - _generateDynamicOffRampConfig(address(s_priceRegistry)), + _generateDynamicOffRampConfig(address(s_feeQuoter)), new OffRamp.SourceChainConfigArgs[](0) ); @@ -449,7 +450,7 @@ contract OffRampSetup is PriceRegistrySetup, MultiOCR3BaseSetup { address[] memory priceUpdaters = new address[](1); priceUpdaters[0] = address(s_offRamp); - s_priceRegistry.applyAuthorizedCallerUpdates( + s_feeQuoter.applyAuthorizedCallerUpdates( AuthorizedCallers.AuthorizedCallerArgs({addedCallers: priceUpdaters, removedCallers: new address[](0)}) ); } diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol index 54054716e6..7b400c0df6 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol @@ -27,7 +27,7 @@ contract EVM2EVMOnRamp_constructor is EVM2EVMOnRampSetup { tokenAdminRegistry: address(s_tokenAdminRegistry) }); EVM2EVMOnRamp.DynamicConfig memory dynamicConfig = - generateDynamicOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)); + generateDynamicOnRampConfig(address(s_sourceRouter), address(s_feeQuoter)); vm.expectEmit(); emit EVM2EVMOnRamp.ConfigSet(staticConfig, dynamicConfig); @@ -247,7 +247,7 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { address[] memory feeTokens = new address[](1); feeTokens[0] = s_sourceTokens[1]; - s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + s_feeQuoter.applyFeeTokensUpdates(feeTokens, new address[](0)); // Since we'll mostly be testing for valid calls from the router we'll // mock all calls to be originating from the router and re-mock in @@ -437,8 +437,8 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { assertEq(IERC20(s_sourceTokens[1]).balanceOf(address(s_onRamp)), feeAmount); // Calculate conversion done by prices contract - uint256 feeTokenPrice = s_priceRegistry.getTokenPrice(s_sourceTokens[1]).value; - uint256 linkTokenPrice = s_priceRegistry.getTokenPrice(s_sourceFeeToken).value; + uint256 feeTokenPrice = s_feeQuoter.getTokenPrice(s_sourceTokens[1]).value; + uint256 linkTokenPrice = s_feeQuoter.getTokenPrice(s_sourceFeeToken).value; uint256 conversionRate = (feeTokenPrice * 1e18) / linkTokenPrice; uint256 expectedJuels = (feeAmount * conversionRate) / 1e18; @@ -487,7 +487,7 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { // Set a high price to trip the ARL uint224 tokenPrice = 3 ** 128; Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(s_sourceTokens[0], tokenPrice); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); vm.startPrank(address(s_sourceRouter)); vm.expectRevert( @@ -662,7 +662,7 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { vm.startPrank(OWNER); Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(wrongToken, 1); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); // Change back to the router vm.startPrank(address(s_sourceRouter)); @@ -694,7 +694,7 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { // Set token price to 0 vm.stopPrank(); vm.startPrank(OWNER); - s_priceRegistry.updatePrices(_getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, 0)); + s_feeQuoter.updatePrices(_getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, 0)); vm.startPrank(address(s_sourceRouter)); @@ -905,7 +905,7 @@ contract EVM2EVMOnRamp_forwardFromRouter_upgrade is EVM2EVMOnRampSetup { rmnProxy: address(s_mockRMN), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - generateDynamicOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)), + generateDynamicOnRampConfig(address(s_sourceRouter), address(s_feeQuoter)), _getOutboundRateLimiterConfig(), s_feeTokenConfigArgs, s_tokenTransferFeeConfigArgs, diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol index f827bf983c..84350448a1 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol @@ -7,12 +7,13 @@ import {Internal} from "../../libraries/Internal.sol"; import {Pool} from "../../libraries/Pool.sol"; import {EVM2EVMOnRamp} from "../../onRamp/EVM2EVMOnRamp.sol"; import {TokenSetup} from "../TokenSetup.t.sol"; + +import {FeeQuoterSetup} from "../feeQuoter/FeeQuoterSetup.t.sol"; import {EVM2EVMOnRampHelper} from "../helpers/EVM2EVMOnRampHelper.sol"; -import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { +contract EVM2EVMOnRampSetup is TokenSetup, FeeQuoterSetup { uint256 internal immutable i_tokenAmount0 = 9; uint256 internal immutable i_tokenAmount1 = 7; @@ -27,11 +28,11 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { EVM2EVMOnRamp.FeeTokenConfigArgs[] internal s_feeTokenConfigArgs; EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] internal s_tokenTransferFeeConfigArgs; - function setUp() public virtual override(TokenSetup, PriceRegistrySetup) { + function setUp() public virtual override(TokenSetup, FeeQuoterSetup) { TokenSetup.setUp(); - PriceRegistrySetup.setUp(); + FeeQuoterSetup.setUp(); - s_priceRegistry.updatePrices(_getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); + s_feeQuoter.updatePrices(_getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); address WETH = s_sourceRouter.getWrappedNative(); @@ -88,7 +89,7 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { rmnProxy: address(s_mockRMN), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - generateDynamicOnRampConfig(address(s_sourceRouter), address(s_priceRegistry)), + generateDynamicOnRampConfig(address(s_sourceRouter), address(s_feeQuoter)), _getOutboundRateLimiterConfig(), s_feeTokenConfigArgs, s_tokenTransferFeeConfigArgs, diff --git a/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol index 10c0a9f0db..43d57b4624 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol @@ -5,7 +5,7 @@ import {IMessageInterceptor} from "../../interfaces/IMessageInterceptor.sol"; import {IRouter} from "../../interfaces/IRouter.sol"; import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; -import {PriceRegistry} from "../../PriceRegistry.sol"; +import {FeeQuoter} from "../../FeeQuoter.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {Pool} from "../../libraries/Pool.sol"; @@ -25,7 +25,7 @@ contract OnRamp_constructor is OnRampSetup { nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }); - OnRamp.DynamicConfig memory dynamicConfig = _generateDynamicOnRampConfig(address(s_priceRegistry)); + OnRamp.DynamicConfig memory dynamicConfig = _generateDynamicOnRampConfig(address(s_feeQuoter)); vm.expectEmit(); emit OnRamp.ConfigSet(staticConfig, dynamicConfig); @@ -56,7 +56,7 @@ contract OnRamp_constructor is OnRampSetup { nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - _generateDynamicOnRampConfig(address(s_priceRegistry)), + _generateDynamicOnRampConfig(address(s_feeQuoter)), _generateDestChainConfigArgs(IRouter(address(0))) ); } @@ -70,7 +70,7 @@ contract OnRamp_constructor is OnRampSetup { nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - _generateDynamicOnRampConfig(address(s_priceRegistry)), + _generateDynamicOnRampConfig(address(s_feeQuoter)), _generateDestChainConfigArgs(IRouter(address(0))) ); } @@ -84,7 +84,7 @@ contract OnRamp_constructor is OnRampSetup { nonceManager: address(0), tokenAdminRegistry: address(s_tokenAdminRegistry) }), - _generateDynamicOnRampConfig(address(s_priceRegistry)), + _generateDynamicOnRampConfig(address(s_feeQuoter)), _generateDestChainConfigArgs(IRouter(address(0))) ); } @@ -98,7 +98,7 @@ contract OnRamp_constructor is OnRampSetup { nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(0) }), - _generateDynamicOnRampConfig(address(s_priceRegistry)), + _generateDynamicOnRampConfig(address(s_feeQuoter)), _generateDestChainConfigArgs(IRouter(address(0))) ); } @@ -115,7 +115,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { address[] memory feeTokens = new address[](1); feeTokens[0] = s_sourceTokens[1]; - s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + s_feeQuoter.applyFeeTokensUpdates(feeTokens, new address[](0)); // Since we'll mostly be testing for valid calls from the router we'll // mock all calls to be originating from the router and re-mock in @@ -286,8 +286,8 @@ contract OnRamp_forwardFromRouter is OnRampSetup { IERC20(s_sourceTokens[1]).transferFrom(OWNER, address(s_onRamp), feeAmount); // Calculate conversion done by prices contract - uint256 feeTokenPrice = s_priceRegistry.getTokenPrice(s_sourceTokens[1]).value; - uint256 linkTokenPrice = s_priceRegistry.getTokenPrice(s_sourceFeeToken).value; + uint256 feeTokenPrice = s_feeQuoter.getTokenPrice(s_sourceTokens[1]).value; + uint256 linkTokenPrice = s_feeQuoter.getTokenPrice(s_sourceFeeToken).value; uint256 conversionRate = (feeTokenPrice * 1e18) / linkTokenPrice; uint256 expectedJuels = (feeAmount * conversionRate) / 1e18; @@ -362,7 +362,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); message.extraArgs = bytes("bad args"); - vm.expectRevert(PriceRegistry.InvalidExtraArgsTag.selector); + vm.expectRevert(FeeQuoter.InvalidExtraArgsTag.selector); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); } @@ -421,7 +421,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { vm.startPrank(OWNER); Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(wrongToken, 1); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); // Change back to the router vm.startPrank(address(s_sourceRouter)); @@ -445,7 +445,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); vm.expectRevert( - abi.encodeWithSelector(PriceRegistry.MessageFeeTooHigh.selector, MAX_MSG_FEES_JUELS + 1, MAX_MSG_FEES_JUELS) + abi.encodeWithSelector(FeeQuoter.MessageFeeTooHigh.selector, MAX_MSG_FEES_JUELS + 1, MAX_MSG_FEES_JUELS) ); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, MAX_MSG_FEES_JUELS + 1, OWNER); @@ -495,17 +495,15 @@ contract OnRamp_forwardFromRouter is OnRampSetup { newPool.setSourceTokenData(new bytes(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES + 1)); vm.startPrank(address(s_sourceRouter)); - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.SourceTokenDataTooLarge.selector, sourceETH)); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.SourceTokenDataTooLarge.selector, sourceETH)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); // Set token config to allow larger data vm.startPrank(OWNER); - PriceRegistry.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = - _generateTokenTransferFeeConfigArgs(1, 1); + FeeQuoter.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = _generateTokenTransferFeeConfigArgs(1, 1); tokenTransferFeeConfigArgs[0].destChainSelector = DEST_CHAIN_SELECTOR; tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].token = sourceETH; - tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = PriceRegistry - .TokenTransferFeeConfig({ + tokenTransferFeeConfigArgs[0].tokenTransferFeeConfigs[0].tokenTransferFeeConfig = FeeQuoter.TokenTransferFeeConfig({ minFeeUSDCents: 1, maxFeeUSDCents: 0, deciBps: 0, @@ -513,8 +511,8 @@ contract OnRamp_forwardFromRouter is OnRampSetup { destBytesOverhead: uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) + 32, isEnabled: true }); - s_priceRegistry.applyTokenTransferFeeConfigUpdates( - tokenTransferFeeConfigArgs, new PriceRegistry.TokenTransferFeeConfigRemoveArgs[](0) + s_feeQuoter.applyTokenTransferFeeConfigUpdates( + tokenTransferFeeConfigArgs, new FeeQuoter.TokenTransferFeeConfigRemoveArgs[](0) ); vm.startPrank(address(s_sourceRouter)); @@ -525,7 +523,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { newPool.setSourceTokenData(new bytes(uint32(Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES) + 32 + 1)); vm.startPrank(address(s_sourceRouter)); - vm.expectRevert(abi.encodeWithSelector(PriceRegistry.SourceTokenDataTooLarge.selector, sourceETH)); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.SourceTokenDataTooLarge.selector, sourceETH)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); } } @@ -549,7 +547,7 @@ contract OnRamp_getFee is OnRampSetup { message.feeToken = testTokens[i]; uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); - uint256 expectedFeeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + uint256 expectedFeeAmount = s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); assertEq(expectedFeeAmount, feeAmount); } @@ -565,7 +563,7 @@ contract OnRamp_getFee is OnRampSetup { message.feeToken = testTokens[i]; uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); - uint256 expectedFeeAmount = s_priceRegistry.getValidatedFee(DEST_CHAIN_SELECTOR, message); + uint256 expectedFeeAmount = s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); assertEq(expectedFeeAmount, feeAmount); } @@ -584,16 +582,16 @@ contract OnRamp_getFee is OnRampSetup { vm.stopPrank(); vm.startPrank(OWNER); - PriceRegistry.DestChainConfigArgs[] memory destChainConfigArgs = _generatePriceRegistryDestChainConfigArgs(); + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs(); destChainConfigArgs[0].destChainConfig.enforceOutOfOrder = true; - s_priceRegistry.applyDestChainConfigUpdates(destChainConfigArgs); + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); vm.stopPrank(); Client.EVM2AnyMessage memory message = _generateEmptyMessage(); // Empty extraArgs to should revert since it enforceOutOfOrder is true. message.extraArgs = ""; - vm.expectRevert(PriceRegistry.ExtraArgOutOfOrderExecutionMustBeTrue.selector); + vm.expectRevert(FeeQuoter.ExtraArgOutOfOrderExecutionMustBeTrue.selector); s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); } } @@ -602,7 +600,7 @@ contract OnRamp_setDynamicConfig is OnRampSetup { function test_SetDynamicConfig_Success() public { OnRamp.StaticConfig memory staticConfig = s_onRamp.getStaticConfig(); OnRamp.DynamicConfig memory newConfig = OnRamp.DynamicConfig({ - priceRegistry: address(23423), + feeQuoter: address(23423), messageValidator: makeAddr("messageValidator"), feeAggregator: FEE_AGGREGATOR }); @@ -613,14 +611,14 @@ contract OnRamp_setDynamicConfig is OnRampSetup { s_onRamp.setDynamicConfig(newConfig); OnRamp.DynamicConfig memory gotDynamicConfig = s_onRamp.getDynamicConfig(); - assertEq(newConfig.priceRegistry, gotDynamicConfig.priceRegistry); + assertEq(newConfig.feeQuoter, gotDynamicConfig.feeQuoter); } // Reverts - function test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() public { + function test_SetConfigInvalidConfigFeeQuoterEqAddressZero_Revert() public { OnRamp.DynamicConfig memory newConfig = OnRamp.DynamicConfig({ - priceRegistry: address(0), + feeQuoter: address(0), feeAggregator: FEE_AGGREGATOR, messageValidator: makeAddr("messageValidator") }); @@ -631,17 +629,17 @@ contract OnRamp_setDynamicConfig is OnRampSetup { function test_SetConfigInvalidConfig_Revert() public { OnRamp.DynamicConfig memory newConfig = - OnRamp.DynamicConfig({priceRegistry: address(23423), messageValidator: address(0), feeAggregator: FEE_AGGREGATOR}); + OnRamp.DynamicConfig({feeQuoter: address(23423), messageValidator: address(0), feeAggregator: FEE_AGGREGATOR}); // Invalid price reg reverts. - newConfig.priceRegistry = address(0); + newConfig.feeQuoter = address(0); vm.expectRevert(OnRamp.InvalidConfig.selector); s_onRamp.setDynamicConfig(newConfig); } function test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() public { OnRamp.DynamicConfig memory newConfig = - OnRamp.DynamicConfig({priceRegistry: address(23423), messageValidator: address(0), feeAggregator: address(0)}); + OnRamp.DynamicConfig({feeQuoter: address(23423), messageValidator: address(0), feeAggregator: address(0)}); vm.expectRevert(OnRamp.InvalidConfig.selector); s_onRamp.setDynamicConfig(newConfig); } @@ -689,7 +687,7 @@ contract OnRamp_withdrawFeeTokens is OnRampSetup { IERC20(feeTokens[i]).transfer(address(s_onRamp), amounts[i]); } - s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + s_feeQuoter.applyFeeTokensUpdates(feeTokens, new address[](0)); for (uint256 i = 0; i < feeTokens.length; ++i) { vm.expectEmit(); diff --git a/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol index a8d1919948..635a75c843 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol @@ -9,13 +9,13 @@ import {Router} from "../../Router.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {OnRamp} from "../../onRamp/OnRamp.sol"; +import {FeeQuoterFeeSetup} from "../feeQuoter/FeeQuoterSetup.t.sol"; import {MessageInterceptorHelper} from "../helpers/MessageInterceptorHelper.sol"; import {OnRampHelper} from "../helpers/OnRampHelper.sol"; -import {PriceRegistryFeeSetup} from "../priceRegistry/PriceRegistry.t.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; -contract OnRampSetup is PriceRegistryFeeSetup { +contract OnRampSetup is FeeQuoterFeeSetup { uint256 internal immutable i_tokenAmount0 = 9; uint256 internal immutable i_tokenAmount1 = 7; @@ -84,9 +84,8 @@ contract OnRampSetup is PriceRegistryFeeSetup { ); } - function _generateDynamicOnRampConfig(address priceRegistry) internal pure returns (OnRamp.DynamicConfig memory) { - return - OnRamp.DynamicConfig({priceRegistry: priceRegistry, messageValidator: address(0), feeAggregator: FEE_AGGREGATOR}); + function _generateDynamicOnRampConfig(address feeQuoter) internal pure returns (OnRamp.DynamicConfig memory) { + return OnRamp.DynamicConfig({feeQuoter: feeQuoter, messageValidator: address(0), feeAggregator: FEE_AGGREGATOR}); } // Slicing is only available for calldata. So we have to build a new bytes array. @@ -117,7 +116,7 @@ contract OnRampSetup is PriceRegistryFeeSetup { nonceManager: nonceManager, tokenAdminRegistry: tokenAdminRegistry }), - _generateDynamicOnRampConfig(address(s_priceRegistry)), + _generateDynamicOnRampConfig(address(s_feeQuoter)), _generateDestChainConfigArgs(router) ); @@ -162,6 +161,6 @@ contract OnRampSetup is PriceRegistryFeeSetup { } function _assertDynamicConfigsEqual(OnRamp.DynamicConfig memory a, OnRamp.DynamicConfig memory b) internal pure { - assertEq(a.priceRegistry, b.priceRegistry); + assertEq(a.feeQuoter, b.feeQuoter); } } diff --git a/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol b/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol index af970b0f92..318821c441 100644 --- a/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol +++ b/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol @@ -5,12 +5,13 @@ import {AggregateRateLimiter} from "../../AggregateRateLimiter.sol"; import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; + +import {FeeQuoterSetup} from "../feeQuoter/FeeQuoterSetup.t.sol"; import {AggregateRateLimiterHelper} from "../helpers/AggregateRateLimiterHelper.sol"; -import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; import {stdError} from "forge-std/Test.sol"; -contract AggregateTokenLimiterSetup is PriceRegistrySetup { +contract AggregateTokenLimiterSetup is FeeQuoterSetup { AggregateRateLimiterHelper internal s_rateLimiter; RateLimiter.Config internal s_config; @@ -18,10 +19,10 @@ contract AggregateTokenLimiterSetup is PriceRegistrySetup { uint224 internal constant TOKEN_PRICE = 4e18; function setUp() public virtual override { - PriceRegistrySetup.setUp(); + FeeQuoterSetup.setUp(); Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(TOKEN, TOKEN_PRICE); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); s_config = RateLimiter.Config({isEnabled: true, rate: 5, capacity: 100}); s_rateLimiter = new AggregateRateLimiterHelper(s_config); @@ -219,7 +220,7 @@ contract AggregateTokenLimiter_getTokenValue is AggregateTokenLimiterSetup { function test_GetTokenValue_Success() public view { uint256 numberOfTokens = 10; Client.EVMTokenAmount memory tokenAmount = Client.EVMTokenAmount({token: TOKEN, amount: 10}); - uint256 value = s_rateLimiter.getTokenValue(tokenAmount, s_priceRegistry); + uint256 value = s_rateLimiter.getTokenValue(tokenAmount, s_feeQuoter); assertEq(value, (numberOfTokens * TOKEN_PRICE) / 1e18); } @@ -229,6 +230,6 @@ contract AggregateTokenLimiter_getTokenValue is AggregateTokenLimiterSetup { Client.EVMTokenAmount memory tokenAmount = Client.EVMTokenAmount({token: tokenWithNoPrice, amount: 10}); vm.expectRevert(abi.encodeWithSelector(AggregateRateLimiter.PriceNotFoundForToken.selector, tokenWithNoPrice)); - s_rateLimiter.getTokenValue(tokenAmount, s_priceRegistry); + s_rateLimiter.getTokenValue(tokenAmount, s_feeQuoter); } } diff --git a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol index 292c4533e4..9fcf08f722 100644 --- a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol +++ b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol @@ -7,12 +7,13 @@ import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {RateLimiter} from "../../libraries/RateLimiter.sol"; import {BaseTest} from "../BaseTest.t.sol"; + +import {FeeQuoterSetup} from "../feeQuoter/FeeQuoterSetup.t.sol"; import {MultiAggregateRateLimiterHelper} from "../helpers/MultiAggregateRateLimiterHelper.sol"; -import {PriceRegistrySetup} from "../priceRegistry/PriceRegistrySetup.t.sol"; import {stdError} from "forge-std/Test.sol"; import {Vm} from "forge-std/Vm.sol"; -contract MultiAggregateRateLimiterSetup is BaseTest, PriceRegistrySetup { +contract MultiAggregateRateLimiterSetup is BaseTest, FeeQuoterSetup { MultiAggregateRateLimiterHelper internal s_rateLimiter; address internal immutable TOKEN = 0x21118E64E1fB0c487F25Dd6d3601FF6af8D32E4e; @@ -29,12 +30,12 @@ contract MultiAggregateRateLimiterSetup is BaseTest, PriceRegistrySetup { address[] internal s_authorizedCallers; - function setUp() public virtual override(BaseTest, PriceRegistrySetup) { + function setUp() public virtual override(BaseTest, FeeQuoterSetup) { BaseTest.setUp(); - PriceRegistrySetup.setUp(); + FeeQuoterSetup.setUp(); Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(TOKEN, TOKEN_PRICE); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); MultiAggregateRateLimiter.RateLimiterConfigArgs[] memory configUpdates = new MultiAggregateRateLimiter.RateLimiterConfigArgs[](4); @@ -63,7 +64,7 @@ contract MultiAggregateRateLimiterSetup is BaseTest, PriceRegistrySetup { s_authorizedCallers[0] = MOCK_OFFRAMP; s_authorizedCallers[1] = MOCK_ONRAMP; - s_rateLimiter = new MultiAggregateRateLimiterHelper(address(s_priceRegistry), s_authorizedCallers); + s_rateLimiter = new MultiAggregateRateLimiterHelper(address(s_feeQuoter), s_authorizedCallers); s_rateLimiter.applyRateLimiterConfigUpdates(configUpdates); } @@ -114,14 +115,14 @@ contract MultiAggregateRateLimiter_constructor is MultiAggregateRateLimiterSetup address[] memory authorizedCallers = new address[](0); vm.recordLogs(); - s_rateLimiter = new MultiAggregateRateLimiterHelper(address(s_priceRegistry), authorizedCallers); + s_rateLimiter = new MultiAggregateRateLimiterHelper(address(s_feeQuoter), authorizedCallers); - // PriceRegistrySet + // FeeQuoterSet Vm.Log[] memory logEntries = vm.getRecordedLogs(); assertEq(logEntries.length, 1); assertEq(OWNER, s_rateLimiter.owner()); - assertEq(address(s_priceRegistry), s_rateLimiter.getPriceRegistry()); + assertEq(address(s_feeQuoter), s_rateLimiter.getFeeQuoter()); } function test_Constructor_Success() public { @@ -130,25 +131,25 @@ contract MultiAggregateRateLimiter_constructor is MultiAggregateRateLimiterSetup authorizedCallers[1] = MOCK_ONRAMP; vm.expectEmit(); - emit MultiAggregateRateLimiter.PriceRegistrySet(address(s_priceRegistry)); + emit MultiAggregateRateLimiter.FeeQuoterSet(address(s_feeQuoter)); - s_rateLimiter = new MultiAggregateRateLimiterHelper(address(s_priceRegistry), authorizedCallers); + s_rateLimiter = new MultiAggregateRateLimiterHelper(address(s_feeQuoter), authorizedCallers); assertEq(OWNER, s_rateLimiter.owner()); - assertEq(address(s_priceRegistry), s_rateLimiter.getPriceRegistry()); + assertEq(address(s_feeQuoter), s_rateLimiter.getFeeQuoter()); assertEq(s_rateLimiter.typeAndVersion(), "MultiAggregateRateLimiter 1.6.0-dev"); } } -contract MultiAggregateRateLimiter_setPriceRegistry is MultiAggregateRateLimiterSetup { +contract MultiAggregateRateLimiter_setFeeQuoter is MultiAggregateRateLimiterSetup { function test_Owner_Success() public { address newAddress = address(42); vm.expectEmit(); - emit MultiAggregateRateLimiter.PriceRegistrySet(newAddress); + emit MultiAggregateRateLimiter.FeeQuoterSet(newAddress); - s_rateLimiter.setPriceRegistry(newAddress); - assertEq(newAddress, s_rateLimiter.getPriceRegistry()); + s_rateLimiter.setFeeQuoter(newAddress); + assertEq(newAddress, s_rateLimiter.getFeeQuoter()); } // Reverts @@ -157,12 +158,12 @@ contract MultiAggregateRateLimiter_setPriceRegistry is MultiAggregateRateLimiter vm.startPrank(STRANGER); vm.expectRevert(bytes("Only callable by owner")); - s_rateLimiter.setPriceRegistry(STRANGER); + s_rateLimiter.setFeeQuoter(STRANGER); } function test_ZeroAddress_Revert() public { vm.expectRevert(AuthorizedCallers.ZeroAddressNotAllowed.selector); - s_rateLimiter.setPriceRegistry(address(0)); + s_rateLimiter.setFeeQuoter(address(0)); } } @@ -684,7 +685,7 @@ contract MultiAggregateRateLimiter_onInboundMessage is MultiAggregateRateLimiter Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(s_destTokens[i], TOKEN_PRICE * (i + 1)); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); } s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); } @@ -920,7 +921,7 @@ contract MultiAggregateRateLimiter_onOutboundMessage is MultiAggregateRateLimite Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(s_sourceTokens[i], TOKEN_PRICE * (i + 1)); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); } s_rateLimiter.updateRateLimitTokens(new MultiAggregateRateLimiter.LocalRateLimitToken[](0), tokensToAdd); } diff --git a/contracts/src/v0.8/ccip/test/router/Router.t.sol b/contracts/src/v0.8/ccip/test/router/Router.t.sol index 5f3a3a66ab..95d3c2f293 100644 --- a/contracts/src/v0.8/ccip/test/router/Router.t.sol +++ b/contracts/src/v0.8/ccip/test/router/Router.t.sol @@ -210,7 +210,7 @@ contract Router_ccipSend is EVM2EVMOnRampSetup { address[] memory feeTokens = new address[](1); feeTokens[0] = s_sourceTokens[1]; - s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + s_feeQuoter.applyFeeTokensUpdates(feeTokens, new address[](0)); Client.EVM2AnyMessage memory message = _generateEmptyMessage(); message.feeToken = s_sourceTokens[1]; @@ -262,7 +262,7 @@ contract Router_ccipSend is EVM2EVMOnRampSetup { // Set the new token as feeToken address[] memory feeTokens = new address[](1); feeTokens[0] = feeTokenWithZeroFeeAndGas; - s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); + s_feeQuoter.applyFeeTokensUpdates(feeTokens, new address[](0)); // Update the price of the newly set feeToken Internal.PriceUpdates memory priceUpdates = _getSingleTokenPriceUpdateStruct(feeTokenWithZeroFeeAndGas, 2_000 ether); @@ -270,7 +270,7 @@ contract Router_ccipSend is EVM2EVMOnRampSetup { priceUpdates.gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_SELECTOR, usdPerUnitGas: 0}); - s_priceRegistry.updatePrices(priceUpdates); + s_feeQuoter.updatePrices(priceUpdates); // Set the feeToken args on the onRamp EVM2EVMOnRamp.FeeTokenConfigArgs[] memory feeTokenConfigArgs = new EVM2EVMOnRamp.FeeTokenConfigArgs[](1); diff --git a/core/capabilities/ccip/ccip_integration_tests/helpers.go b/core/capabilities/ccip/ccip_integration_tests/helpers.go index a98a8ce1cd..0cc06bc30d 100644 --- a/core/capabilities/ccip/ccip_integration_tests/helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/helpers.go @@ -14,6 +14,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccip_integration_tests/integrationhelpers" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" @@ -31,7 +32,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ocr3_config_encoder" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" @@ -106,7 +106,7 @@ type onchainUniverse struct { rmn *mock_rmn_contract.MockRMNContract onramp *onramp.OnRamp offramp *offramp.OffRamp - priceRegistry *price_registry.PriceRegistry + priceRegistry *fee_quoter.FeeQuoter tokenAdminRegistry *token_admin_registry.TokenAdminRegistry nonceManager *nonce_manager.NonceManager receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver @@ -200,7 +200,7 @@ func createUniverses( TokenAdminRegistry: tokenAdminRegistry.Address(), }, onramp.OnRampDynamicConfig{ - PriceRegistry: priceRegistry.Address(), + FeeQuoter: priceRegistry.Address(), // `withdrawFeeTokens` onRamp function is not part of the message flow // so we can set this to any address FeeAggregator: testutils.NewAddress(), @@ -226,7 +226,7 @@ func createUniverses( NonceManager: nonceManager.Address(), }, offramp.OffRampDynamicConfig{ - PriceRegistry: priceRegistry.Address(), + FeeQuoter: priceRegistry.Address(), }, // Source chain configs will be set up later once we have all chains []offramp.OffRampSourceChainConfigArgs{}, @@ -660,7 +660,7 @@ func setupUniverseBasics(t *testing.T, uni onchainUniverse) { // Price updates for tokens // These are the prices of the fee tokens of local chain in USD // ============================================================================= - tokenPriceUpdates := []price_registry.InternalTokenPriceUpdate{ + tokenPriceUpdates := []fee_quoter.InternalTokenPriceUpdate{ { SourceToken: uni.linkToken.Address(), UsdPerToken: e18Mult(20), @@ -670,13 +670,13 @@ func setupUniverseBasics(t *testing.T, uni onchainUniverse) { UsdPerToken: e18Mult(4000), }, } - _, err = uni.priceRegistry.UpdatePrices(owner, price_registry.InternalPriceUpdates{ + _, err = uni.priceRegistry.UpdatePrices(owner, fee_quoter.InternalPriceUpdates{ TokenPriceUpdates: tokenPriceUpdates, }) require.NoErrorf(t, err, "failed to update prices in price registry on chain id %d", uni.chainID) uni.backend.Commit() - _, err = uni.priceRegistry.ApplyAuthorizedCallerUpdates(owner, price_registry.AuthorizedCallersAuthorizedCallerArgs{ + _, err = uni.priceRegistry.ApplyAuthorizedCallerUpdates(owner, fee_quoter.AuthorizedCallersAuthorizedCallerArgs{ AddedCallers: []common.Address{ uni.offramp.Address(), }, @@ -729,12 +729,12 @@ func wireRouter(t *testing.T, uni onchainUniverse, universes map[uint64]onchainU // Setting OnRampDestChainConfigs func wirePriceRegistry(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { owner := uni.owner - var priceRegistryDestChainConfigArgs []price_registry.PriceRegistryDestChainConfigArgs + var priceRegistryDestChainConfigArgs []fee_quoter.FeeQuoterDestChainConfigArgs for remoteChainID := range universes { if remoteChainID == uni.chainID { continue } - priceRegistryDestChainConfigArgs = append(priceRegistryDestChainConfigArgs, price_registry.PriceRegistryDestChainConfigArgs{ + priceRegistryDestChainConfigArgs = append(priceRegistryDestChainConfigArgs, fee_quoter.FeeQuoterDestChainConfigArgs{ DestChainSelector: getSelector(remoteChainID), DestChainConfig: defaultPriceRegistryDestChainConfig(t), }) @@ -801,25 +801,25 @@ func getSelector(chainID uint64) uint64 { // initRemoteChainsGasPrices sets the gas prices for all chains except the local chain in the local price registry func initRemoteChainsGasPrices(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { - var gasPriceUpdates []price_registry.InternalGasPriceUpdate + var gasPriceUpdates []fee_quoter.InternalGasPriceUpdate for remoteChainID := range universes { if remoteChainID == uni.chainID { continue } gasPriceUpdates = append(gasPriceUpdates, - price_registry.InternalGasPriceUpdate{ + fee_quoter.InternalGasPriceUpdate{ DestChainSelector: getSelector(remoteChainID), UsdPerUnitGas: big.NewInt(2e12), }, ) } - _, err := uni.priceRegistry.UpdatePrices(uni.owner, price_registry.InternalPriceUpdates{ + _, err := uni.priceRegistry.UpdatePrices(uni.owner, fee_quoter.InternalPriceUpdates{ GasPriceUpdates: gasPriceUpdates, }) require.NoError(t, err) } -func defaultPriceRegistryDestChainConfig(t *testing.T) price_registry.PriceRegistryDestChainConfig { +func defaultPriceRegistryDestChainConfig(t *testing.T) fee_quoter.FeeQuoterDestChainConfig { // https://github.com/smartcontractkit/ccip/blob/c4856b64bd766f1ddbaf5d13b42d3c4b12efde3a/contracts/src/v0.8/ccip/libraries/Internal.sol#L337-L337 /* ```Solidity @@ -829,7 +829,7 @@ func defaultPriceRegistryDestChainConfig(t *testing.T) price_registry.PriceRegis */ evmFamilySelector, err := hex.DecodeString("2812d52c") require.NoError(t, err) - return price_registry.PriceRegistryDestChainConfig{ + return fee_quoter.FeeQuoterDestChainConfig{ IsEnabled: true, MaxNumberOfTokensPerMsg: 10, MaxDataBytes: 256, @@ -901,11 +901,11 @@ func deployPriceRegistry( wethAddr common.Address, maxFeeJuelsPerMsg *big.Int, chainID uint64, -) *price_registry.PriceRegistry { - priceRegistryAddr, _, _, err := price_registry.DeployPriceRegistry( +) *fee_quoter.FeeQuoter { + priceRegistryAddr, _, _, err := fee_quoter.DeployFeeQuoter( owner, backend, - price_registry.PriceRegistryStaticConfig{ + fee_quoter.FeeQuoterStaticConfig{ MaxFeeJuelsPerMsg: maxFeeJuelsPerMsg, LinkToken: linkAddr, StalenessThreshold: 24 * 60 * 60, // 24 hours @@ -915,10 +915,10 @@ func deployPriceRegistry( }, // price updaters, will be set to offramp later []common.Address{linkAddr, wethAddr}, // fee tokens // empty for now, need to fill in when testing token transfers - []price_registry.PriceRegistryTokenPriceFeedUpdate{}, + []fee_quoter.FeeQuoterTokenPriceFeedUpdate{}, // empty for now, need to fill in when testing token transfers - []price_registry.PriceRegistryTokenTransferFeeConfigArgs{}, - []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs{ + []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs{}, + []fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs{ { PremiumMultiplierWeiPerEth: 9e17, // 0.9 ETH Token: linkAddr, @@ -929,11 +929,11 @@ func deployPriceRegistry( }, }, // Destination chain configs will be set up later once we have all chains - []price_registry.PriceRegistryDestChainConfigArgs{}, + []fee_quoter.FeeQuoterDestChainConfigArgs{}, ) require.NoErrorf(t, err, "failed to deploy price registry on chain id %d", chainID) backend.Commit() - priceRegistry, err := price_registry.NewPriceRegistry(priceRegistryAddr, backend) + priceRegistry, err := fee_quoter.NewFeeQuoter(priceRegistryAddr, backend) require.NoError(t, err) return priceRegistry } diff --git a/core/capabilities/ccip/configs/evm/contract_reader.go b/core/capabilities/ccip/configs/evm/contract_reader.go index e395013cc9..cd89e96337 100644 --- a/core/capabilities/ccip/configs/evm/contract_reader.go +++ b/core/capabilities/ccip/configs/evm/contract_reader.go @@ -7,12 +7,12 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/smartcontractkit/chainlink-ccip/pkg/consts" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -21,7 +21,7 @@ var ( onrampABI = evmtypes.MustGetABI(onramp.OnRampABI) capabilitiesRegsitryABI = evmtypes.MustGetABI(kcr.CapabilitiesRegistryABI) ccipConfigABI = evmtypes.MustGetABI(ccip_config.CCIPConfigABI) - priceRegistryABI = evmtypes.MustGetABI(price_registry.PriceRegistryABI) + priceRegistryABI = evmtypes.MustGetABI(fee_quoter.FeeQuoterABI) ) // MustSourceReaderConfig returns a ChainReaderConfig that can be used to read from the onramp. @@ -138,7 +138,7 @@ var SourceReaderConfig = evmrelaytypes.ChainReaderConfig{ }, }, consts.ContractNamePriceRegistry: { - ContractABI: price_registry.PriceRegistryABI, + ContractABI: fee_quoter.FeeQuoterABI, Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ // TODO: update with the consts from https://github.com/smartcontractkit/chainlink-ccip/pull/39 // in a followup. diff --git a/core/gethwrappers/ccip/generated/price_registry/price_registry.go b/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go similarity index 54% rename from core/gethwrappers/ccip/generated/price_registry/price_registry.go rename to core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go index a4839d7ac3..74ed33b73a 100644 --- a/core/gethwrappers/ccip/generated/price_registry/price_registry.go +++ b/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package price_registry +package fee_quoter import ( "errors" @@ -48,48 +48,7 @@ type ClientEVMTokenAmount struct { Amount *big.Int } -type IPriceRegistryTokenPriceFeedConfig struct { - DataFeedAddress common.Address - TokenDecimals uint8 -} - -type InternalGasPriceUpdate struct { - DestChainSelector uint64 - UsdPerUnitGas *big.Int -} - -type InternalPriceUpdates struct { - TokenPriceUpdates []InternalTokenPriceUpdate - GasPriceUpdates []InternalGasPriceUpdate -} - -type InternalRampTokenAmount struct { - SourcePoolAddress []byte - DestTokenAddress []byte - ExtraData []byte - Amount *big.Int - DestExecData []byte -} - -type InternalTimestampedPackedUint224 struct { - Value *big.Int - Timestamp uint32 -} - -type InternalTokenPriceUpdate struct { - SourceToken common.Address - UsdPerToken *big.Int -} - -type KeystoneFeedsPermissionHandlerPermission struct { - Forwarder common.Address - WorkflowName [10]byte - ReportName [2]byte - WorkflowOwner common.Address - IsAllowed bool -} - -type PriceRegistryDestChainConfig struct { +type FeeQuoterDestChainConfig struct { IsEnabled bool MaxNumberOfTokensPerMsg uint16 MaxDataBytes uint32 @@ -108,28 +67,28 @@ type PriceRegistryDestChainConfig struct { ChainFamilySelector [4]byte } -type PriceRegistryDestChainConfigArgs struct { +type FeeQuoterDestChainConfigArgs struct { DestChainSelector uint64 - DestChainConfig PriceRegistryDestChainConfig + DestChainConfig FeeQuoterDestChainConfig } -type PriceRegistryPremiumMultiplierWeiPerEthArgs struct { +type FeeQuoterPremiumMultiplierWeiPerEthArgs struct { Token common.Address PremiumMultiplierWeiPerEth uint64 } -type PriceRegistryStaticConfig struct { +type FeeQuoterStaticConfig struct { MaxFeeJuelsPerMsg *big.Int LinkToken common.Address StalenessThreshold uint32 } -type PriceRegistryTokenPriceFeedUpdate struct { +type FeeQuoterTokenPriceFeedUpdate struct { SourceToken common.Address - FeedConfig IPriceRegistryTokenPriceFeedConfig + FeedConfig IFeeQuoterTokenPriceFeedConfig } -type PriceRegistryTokenTransferFeeConfig struct { +type FeeQuoterTokenTransferFeeConfig struct { MinFeeUSDCents uint32 MaxFeeUSDCents uint32 DeciBps uint16 @@ -138,32 +97,73 @@ type PriceRegistryTokenTransferFeeConfig struct { IsEnabled bool } -type PriceRegistryTokenTransferFeeConfigArgs struct { +type FeeQuoterTokenTransferFeeConfigArgs struct { DestChainSelector uint64 - TokenTransferFeeConfigs []PriceRegistryTokenTransferFeeConfigSingleTokenArgs + TokenTransferFeeConfigs []FeeQuoterTokenTransferFeeConfigSingleTokenArgs } -type PriceRegistryTokenTransferFeeConfigRemoveArgs struct { +type FeeQuoterTokenTransferFeeConfigRemoveArgs struct { DestChainSelector uint64 Token common.Address } -type PriceRegistryTokenTransferFeeConfigSingleTokenArgs struct { +type FeeQuoterTokenTransferFeeConfigSingleTokenArgs struct { Token common.Address - TokenTransferFeeConfig PriceRegistryTokenTransferFeeConfig + TokenTransferFeeConfig FeeQuoterTokenTransferFeeConfig +} + +type IFeeQuoterTokenPriceFeedConfig struct { + DataFeedAddress common.Address + TokenDecimals uint8 +} + +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + +type InternalRampTokenAmount struct { + SourcePoolAddress []byte + DestTokenAddress []byte + ExtraData []byte + Amount *big.Int + DestExecData []byte +} + +type InternalTimestampedPackedUint224 struct { + Value *big.Int + Timestamp uint32 +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +type KeystoneFeedsPermissionHandlerPermission struct { + Forwarder common.Address + WorkflowName [10]byte + ReportName [2]byte + WorkflowOwner common.Address + IsAllowed bool } -var PriceRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"}],\"name\":\"ReportForwarderUnauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feedTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"storedTimeStamp\",\"type\":\"uint256\"}],\"name\":\"StaleKeystoneUpdate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"reportId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission\",\"name\":\"permission\",\"type\":\"tuple\"}],\"name\":\"ReportPermissionSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structPriceRegistry.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structPriceRegistry.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structPriceRegistry.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structPriceRegistry.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"processPoolReturnData\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"destExecDataPerToken\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission[]\",\"name\":\"permissions\",\"type\":\"tuple[]\"}],\"name\":\"setReportPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIPriceRegistry.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structPriceRegistry.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620076d8380380620076d8833981016040819052620000349162001834565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a5a565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b26565b5050505050505062001ae5565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001953565b60209081029190910101519050620002f560028262000e5f565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001953565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000e7f565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001953565b6020026020010151600b62000e7f60201b90919060201c565b1562000499578281815181106200045b576200045b62001953565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001953565b6020026020010151600b62000e9660201b90919060201c565b156200053b57818181518110620004fd57620004fd62001953565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001953565b6020908102919091018101518051818301516001600160a01b0380831660008181526007875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001953565b6020026020010151905060008383815181106200065f576200065f62001953565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061016081015163ffffffff16155b80620006ba57506101e08101516001600160e01b031916630a04b54b60e21b14155b80620006da5750806060015163ffffffff1681610160015163ffffffff16115b15620007055760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260096020526040812060010154600160881b900460e01b6001600160e01b03191690036200078557816001600160401b03167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb7248260405162000777919062001969565b60405180910390a2620007c9565b816001600160401b03167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab2082604051620007c0919062001969565b60405180910390a25b8060096000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a8154816001600160401b0302191690836001600160401b031602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000a7e5762000a7e62001953565b6020026020010151600001519050600083838151811062000aa35762000aa362001953565b6020908102919091018101518101516001600160a01b03841660008181526008845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a5d565b60005b825181101562000d9957600083828151811062000b4a5762000b4a62001953565b6020026020010151905060008160000151905060005b82602001515181101562000d8a5760008360200151828151811062000b895762000b8962001953565b602002602001015160200151905060008460200151838151811062000bb25762000bb262001953565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c115760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000d77908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000b60565b50505080600101905062000b29565b5060005b81518110156200054457600082828151811062000dbe5762000dbe62001953565b6020026020010151600001519050600083838151811062000de35762000de362001953565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000d9d565b600062000e76836001600160a01b03841662000ead565b90505b92915050565b600062000e76836001600160a01b03841662000fb1565b600062000e76836001600160a01b03841662001003565b6000818152600183016020526040812054801562000fa657600062000ed460018362001aad565b855490915060009062000eea9060019062001aad565b905081811462000f5657600086600001828154811062000f0e5762000f0e62001953565b906000526020600020015490508087600001848154811062000f345762000f3462001953565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f6a5762000f6a62001acf565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e79565b600091505062000e79565b600081815260018301602052604081205462000ffa5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e79565b50600062000e79565b6000818152600183016020526040812054801562000fa65760006200102a60018362001aad565b8554909150600090620010409060019062001aad565b905080821462000f5657600086600001828154811062000f0e5762000f0e62001953565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200109f576200109f62001064565b60405290565b60405160c081016001600160401b03811182821017156200109f576200109f62001064565b60405161020081016001600160401b03811182821017156200109f576200109f62001064565b604051601f8201601f191681016001600160401b03811182821017156200111b576200111b62001064565b604052919050565b80516001600160a01b03811681146200113b57600080fd5b919050565b805163ffffffff811681146200113b57600080fd5b6000606082840312156200116857600080fd5b604051606081016001600160401b03811182821017156200118d576200118d62001064565b604052825190915081906001600160601b0381168114620011ad57600080fd5b8152620011bd6020840162001123565b6020820152620011d06040840162001140565b60408201525092915050565b60006001600160401b03821115620011f857620011f862001064565b5060051b60200190565b600082601f8301126200121457600080fd5b815160206200122d6200122783620011dc565b620010f0565b8083825260208201915060208460051b8701019350868411156200125057600080fd5b602086015b848110156200127757620012698162001123565b835291830191830162001255565b509695505050505050565b600082601f8301126200129457600080fd5b81516020620012a76200122783620011dc565b82815260609283028501820192828201919087851115620012c757600080fd5b8387015b858110156200135a5780890382811215620012e65760008081fd5b620012f06200107a565b620012fb8362001123565b8152604080601f1984011215620013125760008081fd5b6200131c6200107a565b92506200132b88850162001123565b835283015160ff81168114620013415760008081fd5b82880152808701919091528452928401928101620012cb565b5090979650505050505050565b80516001600160401b03811681146200113b57600080fd5b805161ffff811681146200113b57600080fd5b805180151581146200113b57600080fd5b600082601f830112620013b557600080fd5b81516020620013c86200122783620011dc565b82815260059290921b84018101918181019086841115620013e857600080fd5b8286015b84811015620012775780516001600160401b03808211156200140d57600080fd5b908801906040601f19838c0381018213156200142857600080fd5b620014326200107a565b6200143f89860162001367565b815282850151848111156200145357600080fd5b8086019550508c603f8601126200146957600080fd5b8885015193506200147e6200122785620011dc565b84815260e09094028501830193898101908e8611156200149d57600080fd5b958401955b858710156200157657868f0360e0811215620014bd57600080fd5b620014c76200107a565b620014d28962001123565b815260c08683011215620014e557600080fd5b620014ef620010a5565b9150620014fe8d8a0162001140565b82526200150d878a0162001140565b8d8301526200151f60608a016200137f565b878301526200153160808a0162001140565b60608301526200154460a08a0162001140565b60808301526200155760c08a0162001392565b60a0830152808d0191909152825260e09690960195908a0190620014a2565b828b015250875250505092840192508301620013ec565b600082601f8301126200159f57600080fd5b81516020620015b26200122783620011dc565b82815260069290921b84018101918181019086841115620015d257600080fd5b8286015b84811015620012775760408189031215620015f15760008081fd5b620015fb6200107a565b620016068262001123565b81526200161585830162001367565b81860152835291830191604001620015d6565b80516001600160e01b0319811681146200113b57600080fd5b600082601f8301126200165357600080fd5b81516020620016666200122783620011dc565b82815261022092830285018201928282019190878511156200168757600080fd5b8387015b858110156200135a5780890382811215620016a65760008081fd5b620016b06200107a565b620016bb8362001367565b815261020080601f1984011215620016d35760008081fd5b620016dd620010ca565b9250620016ec88850162001392565b83526040620016fd8186016200137f565b8985015260606200171081870162001140565b82860152608091506200172582870162001140565b9085015260a06200173886820162001140565b8286015260c091506200174d8287016200137f565b9085015260e06200176086820162001140565b828601526101009150620017768287016200137f565b908501526101206200178a8682016200137f565b828601526101409150620017a08287016200137f565b90850152610160620017b486820162001140565b828601526101809150620017ca82870162001140565b908501526101a0620017de86820162001367565b828601526101c09150620017f482870162001140565b908501526101e06200180886820162001392565b828601526200181983870162001628565b9085015250508087019190915284529284019281016200168b565b6000806000806000806000610120888a0312156200185157600080fd5b6200185d898962001155565b60608901519097506001600160401b03808211156200187b57600080fd5b620018898b838c0162001202565b975060808a0151915080821115620018a057600080fd5b620018ae8b838c0162001202565b965060a08a0151915080821115620018c557600080fd5b620018d38b838c0162001282565b955060c08a0151915080821115620018ea57600080fd5b620018f88b838c01620013a3565b945060e08a01519150808211156200190f57600080fd5b6200191d8b838c016200158d565b93506101008a01519150808211156200193557600080fd5b50620019448a828b0162001641565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610200810160208301516200198a602084018261ffff169052565b506040830151620019a3604084018263ffffffff169052565b506060830151620019bc606084018263ffffffff169052565b506080830151620019d5608084018263ffffffff169052565b5060a0830151620019ec60a084018261ffff169052565b5060c083015162001a0560c084018263ffffffff169052565b5060e083015162001a1c60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501516001600160401b0316908401526101a080850151909116908301526101c0808401511515908301526101e0928301516001600160e01b031916929091019190915290565b8181038181111562000e7957634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051615b9962001b3f600039600081816102ef0152818161219101526121fa0152600081816102b301528181611917015261197701526000818161027f015281816119a00152611a100152615b996000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c806379ba509711610104578063a69c64c0116100a2578063d02641a011610071578063d02641a014610a81578063d8694ccd14610a94578063f2fde38b14610aa7578063ffdb4b3714610aba57600080fd5b8063a69c64c014610997578063bf78e03f146109aa578063c4276bfc14610a57578063cdc73d5114610a7957600080fd5b806382b49eb0116100de57806382b49eb0146107d95780638da5cb5b1461094957806391a2749a146109715780639ea600261461098457600080fd5b806379ba5097146107ab5780637afac322146107b3578063805f2132146107c657600080fd5b8063407e1086116101715780634ab35b0b1161014b5780634ab35b0b14610441578063514e8cff146104815780636def4ce714610524578063770e2dc41461079857600080fd5b8063407e1086146103fb57806341ed29e71461040e57806345ac924d1461042157600080fd5b8063085318f8116101ad578063085318f814610368578063181f5a77146103885780632451a627146103d15780633937306f146103e657600080fd5b806241e5be146101d3578063061877e3146101f957806306285c6914610252575b600080fd5b6101e66101e1366004614250565b610b02565b6040519081526020015b60405180910390f35b61023961020736600461428c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101f0565b61031c604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101f0565b61037b610376366004614304565b610b70565b6040516101f09190614416565b6103c46040518060400160405280601781526020017f5072696365526567697374727920312e362e302d64657600000000000000000081525081565b6040516101f09190614498565b6103d9610ee2565b6040516101f091906144ab565b6103f96103f4366004614505565b610ef3565b005b6103f96104093660046146a7565b6111a8565b6103f961041c3660046147d9565b6111bc565b61043461042f366004614914565b6111fe565b6040516101f09190614956565b61045461044f36600461428c565b6112c9565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b61051761048f3660046149d1565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101f091906149ec565b61078b6105323660046149d1565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101919091525067ffffffffffffffff908116600090815260096020908152604091829020825161020081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a085015271010000000000000000000000000000000000808404881660c086015275010000000000000000000000000000000000000000008404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b01000000000000000000000000000000000000000000000000000000909204861661014084015260019093015480861661016084015264010000000081049096166101808301526c0100000000000000000000000086049094166101a0820152700100000000000000000000000000000000850490911615156101c08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b166101e082015290565b6040516101f09190614a27565b6103f96107a6366004614c3e565b6112d4565b6103f96112e6565b6103f96107c1366004614f58565b6113e3565b6103f96107d4366004614ffe565b6113f5565b6108e96107e736600461506a565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff919091166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101f09190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6103f961097f366004615094565b6118dd565b6103f9610992366004615155565b6118ee565b6103f96109a5366004615362565b6118ff565b610a236109b836600461428c565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526007825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101f0565b610a6a610a65366004615427565b611910565b6040516101f093929190615496565b6103d9611b06565b610517610a8f36600461428c565b611b12565b6101e6610aa23660046154b7565b611c0e565b6103f9610ab536600461428c565b6120ac565b610acd610ac836600461550c565b6120bd565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101f0565b6000610b0d82612248565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b3485612248565b610b5c907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685615565565b610b66919061557c565b90505b9392505050565b67ffffffffffffffff8086166000908152600960205260409020600101546060917101000000000000000000000000000000000090910460e01b908590811115610bbc57610bbc614540565b604051908082528060200260200182016040528015610bef57816020015b6060815260200190600190039081610bda5790505b50915060005b85811015610ed7576000858583818110610c1157610c116155b7565b610c27926020604090920201908101915061428c565b90506000888884818110610c3d57610c3d6155b7565b9050602002810190610c4f91906155e6565b610c5d906040810190615624565b9150506020811115610d125767ffffffffffffffff8a166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115610d12576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b610d82848a8a86818110610d2857610d286155b7565b9050602002810190610d3a91906155e6565b610d48906020810190615624565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122e292505050565b67ffffffffffffffff8a166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320815160c081018352905463ffffffff8082168352640100000000820481168386015268010000000000000000820461ffff16838501526a01000000000000000000008204811660608401526e010000000000000000000000000000820481166080840152720100000000000000000000000000000000000090910460ff16151560a08301908152958552600990935290832054935190937b0100000000000000000000000000000000000000000000000000000090049091169190610e815781610e87565b82606001515b6040805163ffffffff8316602082015291925001604051602081830303815290604052888781518110610ebc57610ebc6155b7565b60200260200101819052505050505050806001019050610bf5565b505095945050505050565b6060610eee6002612339565b905090565b610efb612346565b6000610f078280615689565b9050905060005b81811015611051576000610f228480615689565b83818110610f3257610f326155b7565b905060400201803603810190610f48919061571d565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600690975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926110409290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610f0e565b5060006110616020840184615689565b9050905060005b818110156111a257600061107f6020860186615689565b8381811061108f5761108f6155b7565b9050604002018036038101906110a5919061575a565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e926111919290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101611068565b50505050565b6111b061238b565b6111b98161240c565b50565b6111c461238b565b60005b81518110156111fa576111f28282815181106111e5576111e56155b7565b602002602001015161250a565b6001016111c7565b5050565b60608160008167ffffffffffffffff81111561121c5761121c614540565b60405190808252806020026020018201604052801561126157816020015b604080518082019091526000808252602082015281526020019060019003908161123a5790505b50905060005b828110156112be57611299868683818110611284576112846155b7565b9050602002016020810190610a8f919061428c565b8282815181106112ab576112ab6155b7565b6020908102919091010152600101611267565b509150505b92915050565b60006112c382612248565b6112dc61238b565b6111fa82826126dc565b60015473ffffffffffffffffffffffffffffffffffffffff163314611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610d09565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6113eb61238b565b6111fa8282612ae9565b600080600061143987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c3092505050565b92509250925061144b33838584612c4b565b60006114598587018761577d565b905060005b81518110156118d25760006007600084848151811061147f5761147f6155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160009081205474010000000000000000000000000000000000000000900460ff169150819003611540578282815181106114e9576114e96155b7565b6020908102919091010151516040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b600061158960128386868151811061155a5761155a6155b7565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612da3565b9050600660008585815181106115a1576115a16155b7565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff16848481518110611613576116136155b7565b60200260200101516040015163ffffffff16101561171d5783838151811061163d5761163d6155b7565b60200260200101516000015184848151811061165b5761165b6155b7565b6020026020010151604001516006600087878151811061167d5761167d6155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260409081016000205490517f191ec70600000000000000000000000000000000000000000000000000000000815293909116600484015263ffffffff91821660248401527c01000000000000000000000000000000000000000000000000000000009004166044820152606401610d09565b6040518060400160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260200185858151811061175e5761175e6155b7565b60200260200101516040015163ffffffff1681525060066000868681518110611789576117896155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790558351849084908110611821576118216155b7565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff167f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a82868681518110611877576118776155b7565b6020026020010151604001516040516118c09291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a2505060010161145e565b505050505050505050565b6118e561238b565b6111b981612e69565b6118f661238b565b6111b981612ff5565b61190761238b565b6111b98161349b565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036119705785925061199e565b61199b87877f0000000000000000000000000000000000000000000000000000000000000000610b02565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611a3d576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610d09565b67ffffffffffffffff881660009081526009602052604081206001015463ffffffff1690611a6c878784613585565b9050806020015193508484611af3836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b6060610eee600b612339565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600760209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff169082015290611c0557505073ffffffffffffffffffffffffffffffffffffffff166000908152600660209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b698161372e565b67ffffffffffffffff8083166000908152600960209081526040808320815161020081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a086015271010000000000000000000000000000000000808504881660c087015275010000000000000000000000000000000000000000008504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b01000000000000000000000000000000000000000000000000000000909304861661014085015260019094015480861661016085015264010000000081049098166101808401526c0100000000000000000000000088049094166101a0830152700100000000000000000000000000000000870490931615156101c08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b166101e0840152909190611e28576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000611e376040850185615689565b9150611e93905082611e4c6020870187615624565b905083611e598880615624565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506138bd92505050565b6000600881611ea8608088016060890161428c565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff16915080611ef7611ef16080890160608a0161428c565b896120bd565b9092509050600080808615611f3d57611f31888c611f1b60808e0160608f0161428c565b888e8060400190611f2c9190615689565b613967565b91945092509050611f5d565b6101a0880151611f5a9063ffffffff16662386f26fc10000615565565b92505b61010088015160009061ffff1615611fa157611f9e896dffffffffffffffffffffffffffff607088901c16611f9560208f018f615624565b90508b86613c3f565b90505b61018089015160009067ffffffffffffffff16611fca611fc460808f018f615624565b8d613cef565b600001518563ffffffff168c60a0015161ffff168f8060200190611fee9190615624565b611ff9929150615565565b8d6080015163ffffffff1661200e9190615844565b6120189190615844565b6120229190615844565b61203c906dffffffffffffffffffffffffffff8916615565565b6120469190615565565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8716828261207d67ffffffffffffffff8c1689615565565b6120879190615844565b6120919190615844565b61209b919061557c565b9d9c50505050505050505050505050565b6120b461238b565b6111b981613db0565b67ffffffffffffffff811660009081526005602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203612175576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000816020015163ffffffff164261218d9190615857565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff1681111561222e576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610d09565b61223786612248565b9151919350909150505b9250929050565b60008061225483611b12565b9050806020015163ffffffff166000148061228c575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b156122db576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610d09565b5192915050565b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016111fa5761233481613ea5565b505050565b60606000610b6983613f58565b612351600233613fb4565b612389576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610d09565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314612389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d09565b60005b81518110156111fa57600082828151811061242c5761242c6155b7565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526007875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a250505080600101905061240f565b60006125c382600001518360600151846020015185604001516040805173ffffffffffffffffffffffffffffffffffffffff80871660208301528516918101919091527fffffffffffffffffffff00000000000000000000000000000000000000000000831660608201527fffff0000000000000000000000000000000000000000000000000000000000008216608082015260009060a001604051602081830303815290604052805190602001209050949350505050565b60808301516000828152600460205260409081902080549215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316929092179091555190915081907f32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a3906126d0908590600060a08201905073ffffffffffffffffffffffffffffffffffffffff8084511683527fffffffffffffffffffff0000000000000000000000000000000000000000000060208501511660208401527fffff00000000000000000000000000000000000000000000000000000000000060408501511660408401528060608501511660608401525060808301511515608083015292915050565b60405180910390a25050565b60005b8251811015612a055760008382815181106126fc576126fc6155b7565b6020026020010151905060008160000151905060005b8260200151518110156129f757600083602001518281518110612737576127376155b7565b602002602001015160200151905060008460200151838151811061275d5761275d6155b7565b6020026020010151600001519050602063ffffffff16826080015163ffffffff1610156127e05760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610d09565b67ffffffffffffffff84166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906129e5908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101612712565b5050508060010190506126df565b5060005b8151811015612334576000828281518110612a2657612a266155b7565b60200260200101516000015190506000838381518110612a4857612a486155b7565b60209081029190910181015181015167ffffffffffffffff84166000818152600a8452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612a09565b60005b8251811015612b8c57612b22838281518110612b0a57612b0a6155b7565b6020026020010151600b613fe390919063ffffffff16565b15612b8457828181518110612b3957612b396155b7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b600101612aec565b5060005b815181101561233457612bc6828281518110612bae57612bae6155b7565b6020026020010151600b61400590919063ffffffff16565b15612c2857818181518110612bdd57612bdd6155b7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101612b90565b6040810151604a820151605e90920151909260609290921c91565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602080840191909152908616828401527fffffffffffffffffffff00000000000000000000000000000000000000000000851660608301527fffff00000000000000000000000000000000000000000000000000000000000084166080808401919091528351808403909101815260a09092018352815191810191909120600081815260049092529190205460ff16612d9c576040517f097e17ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8087166004830152851660248201527fffffffffffffffffffff00000000000000000000000000000000000000000000841660448201527fffff00000000000000000000000000000000000000000000000000000000000083166064820152608401610d09565b5050505050565b600080612db0848661586a565b9050600060248260ff161115612de757612dcb602483615883565b612dd690600a6159bc565b612de0908561557c565b9050612e0a565b612df2826024615883565b612dfd90600a6159bc565b612e079085615565565b90505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612e60576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b95945050505050565b602081015160005b8151811015612f04576000828281518110612e8e57612e8e6155b7565b60200260200101519050612eac81600261402790919063ffffffff16565b15612efb5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612e71565b50815160005b81518110156111a2576000828281518110612f2757612f276155b7565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612f97576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fa2600282613fe3565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101612f0a565b60005b81518110156111fa576000828281518110613015576130156155b7565b602002602001015190506000838381518110613033576130336155b7565b60200260200101516000015190506000826020015190508167ffffffffffffffff166000148061306c575061016081015163ffffffff16155b806130be57506101e08101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130dd5750806060015163ffffffff1681610160015163ffffffff16115b15613120576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610d09565b67ffffffffffffffff821660009081526009602052604081206001015471010000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131c4578167ffffffffffffffff167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb724826040516131b79190614a27565b60405180910390a2613207565b8167ffffffffffffffff167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab20826040516131fe9190614a27565b60405180910390a25b80600960008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612ff8565b60005b81518110156111fa5760008282815181106134bb576134bb6155b7565b602002602001015160000151905060008383815181106134dd576134dd6155b7565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526008845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010161349e565b604080518082019091526000808252602082015260008390036135c657506040805180820190915267ffffffffffffffff8216815260006020820152610b69565b60006135d284866159cb565b905060006135e38560048189615a11565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f0000000000000000000000000000000000000000000000000000000000161368057808060200190518101906136779190615a3b565b92505050610b69565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016136fc576040518060400160405280828060200190518101906136e89190615a67565b815260006020909101529250610b69915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137bc9190615a9a565b50505091505060008112156137fd576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061387c8373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561384d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138719190615aea565b866020015184612da3565b604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff4216602082015295945050505050565b836040015163ffffffff168311156139165760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610d09565b836020015161ffff16821115613958576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111a2846101e00151826122e2565b6000808083815b81811015613c3157600087878381811061398a5761398a6155b7565b9050604002018036038101906139a09190615b07565b67ffffffffffffffff8c166000908152600a60209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090613ac0576101208d0151613a8d9061ffff16662386f26fc10000615565565b613a979088615844565b96508c610140015186613aaa9190615b40565b9550613ab7602086615b40565b94505050613c29565b604081015160009061ffff1615613b795760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614613b1c578351613b1590612248565b9050613b1f565b508a5b620186a0836040015161ffff16613b618660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661404990919063ffffffff16565b613b6b9190615565565b613b75919061557c565b9150505b6060820151613b889088615b40565b9650816080015186613b9a9190615b40565b8251909650600090613bb99063ffffffff16662386f26fc10000615565565b905080821015613bd857613bcd818a615844565b985050505050613c29565b6000836020015163ffffffff16662386f26fc10000613bf79190615565565b905080831115613c1757613c0b818b615844565b99505050505050613c29565b613c21838b615844565b995050505050505b60010161396e565b505096509650969350505050565b60008063ffffffff8316613c5561016086615565565b613c61876101c0615844565b613c6b9190615844565b613c759190615844565b905060008760c0015163ffffffff168860e0015161ffff1683613c989190615565565b613ca29190615844565b61010089015190915061ffff16613cc96dffffffffffffffffffffffffffff891683615565565b613cd39190615565565b613ce390655af3107a4000615565565b98975050505050505050565b60408051808201909152600080825260208201526000613d1b858585610160015163ffffffff16613585565b9050826060015163ffffffff1681600001511115613d65576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101c001518015613d7957508060200151155b15610b66576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603613e2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d09565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008151602014613ee457816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614498565b600082806020019051810190613efa9190615a67565b905073ffffffffffffffffffffffffffffffffffffffff811180613f1f575061040081105b156112c357826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614498565b606081600001805480602002602001604051908101604052809291908181526020018280548015613fa857602002820191906000526020600020905b815481526020019060010190808311613f94575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b69565b6000610b698373ffffffffffffffffffffffffffffffffffffffff8416614086565b6000610b698373ffffffffffffffffffffffffffffffffffffffff84166140d5565b6000610b698373ffffffffffffffffffffffffffffffffffffffff84166141cf565b6000670de0b6b3a764000061407c837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616615565565b610b69919061557c565b60008181526001830160205260408120546140cd575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112c3565b5060006112c3565b600081815260018301602052604081205480156141be5760006140f9600183615857565b855490915060009061410d90600190615857565b905080821461417257600086600001828154811061412d5761412d6155b7565b9060005260206000200154905080876000018481548110614150576141506155b7565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061418357614183615b5d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112c3565b60009150506112c3565b5092915050565b600081815260018301602052604081205480156141be5760006141f3600183615857565b855490915060009061420790600190615857565b905081811461417257600086600001828154811061412d5761412d6155b7565b803573ffffffffffffffffffffffffffffffffffffffff8116811461424b57600080fd5b919050565b60008060006060848603121561426557600080fd5b61426e84614227565b92506020840135915061428360408501614227565b90509250925092565b60006020828403121561429e57600080fd5b610b6982614227565b803567ffffffffffffffff8116811461424b57600080fd5b60008083601f8401126142d157600080fd5b50813567ffffffffffffffff8111156142e957600080fd5b6020830191508360208260051b850101111561224157600080fd5b60008060008060006060868803121561431c57600080fd5b614325866142a7565b9450602086013567ffffffffffffffff8082111561434257600080fd5b61434e89838a016142bf565b9096509450604088013591508082111561436757600080fd5b818801915088601f83011261437b57600080fd5b81358181111561438a57600080fd5b8960208260061b850101111561439f57600080fd5b9699959850939650602001949392505050565b6000815180845260005b818110156143d8576020818501810151868301820152016143bc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561448b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526144798583516143b2565b9450928501929085019060010161443f565b5092979650505050505050565b602081526000610b6960208301846143b2565b6020808252825182820181905260009190848201906040850190845b818110156144f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016144c7565b50909695505050505050565b60006020828403121561451757600080fd5b813567ffffffffffffffff81111561452e57600080fd5b820160408185031215610b6957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561459257614592614540565b60405290565b60405160a0810167ffffffffffffffff8111828210171561459257614592614540565b60405160c0810167ffffffffffffffff8111828210171561459257614592614540565b604051610200810167ffffffffffffffff8111828210171561459257614592614540565b6040516060810167ffffffffffffffff8111828210171561459257614592614540565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561466c5761466c614540565b604052919050565b600067ffffffffffffffff82111561468e5761468e614540565b5060051b60200190565b60ff811681146111b957600080fd5b600060208083850312156146ba57600080fd5b823567ffffffffffffffff8111156146d157600080fd5b8301601f810185136146e257600080fd5b80356146f56146f082614674565b614625565b8181526060918202830184019184820191908884111561471457600080fd5b938501935b838510156147b457848903818112156147325760008081fd5b61473a61456f565b61474387614227565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147775760008081fd5b61477f61456f565b925061478c898901614227565b835287013561479a81614698565b828901528088019190915283529384019391850191614719565b50979650505050505050565b80151581146111b957600080fd5b803561424b816147c0565b600060208083850312156147ec57600080fd5b823567ffffffffffffffff81111561480357600080fd5b8301601f8101851361481457600080fd5b80356148226146f082614674565b81815260a0918202830184019184820191908884111561484157600080fd5b938501935b838510156147b45780858a03121561485e5760008081fd5b614866614598565b61486f86614227565b8152868601357fffffffffffffffffffff00000000000000000000000000000000000000000000811681146148a45760008081fd5b818801526040868101357fffff000000000000000000000000000000000000000000000000000000000000811681146148dd5760008081fd5b9082015260606148ee878201614227565b90820152608086810135614901816147c0565b9082015283529384019391850191614846565b6000806020838503121561492757600080fd5b823567ffffffffffffffff81111561493e57600080fd5b61494a858286016142bf565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b828110156149c4576149b484835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101614973565b5091979650505050505050565b6000602082840312156149e357600080fd5b610b69826142a7565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff1690820152604081016112c3565b81511515815261020081016020830151614a47602084018261ffff169052565b506040830151614a5f604084018263ffffffff169052565b506060830151614a77606084018263ffffffff169052565b506080830151614a8f608084018263ffffffff169052565b5060a0830151614aa560a084018261ffff169052565b5060c0830151614abd60c084018263ffffffff169052565b5060e0830151614ad360e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff90811691840191909152610160808501518216908401526101808085015167ffffffffffffffff16908401526101a080850151909116908301526101c0808401511515908301526101e0808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461424b57600080fd5b803561ffff8116811461424b57600080fd5b600082601f830112614bb757600080fd5b81356020614bc76146f083614674565b82815260069290921b84018101918181019086841115614be657600080fd5b8286015b84811015614c335760408189031215614c035760008081fd5b614c0b61456f565b614c14826142a7565b8152614c21858301614227565b81860152835291830191604001614bea565b509695505050505050565b60008060408385031215614c5157600080fd5b67ffffffffffffffff83351115614c6757600080fd5b83601f843585010112614c7957600080fd5b614c896146f08435850135614674565b8335840180358083526020808401939260059290921b90910101861015614caf57600080fd5b602085358601015b85358601803560051b01602001811015614ebc5767ffffffffffffffff81351115614ce157600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a03011215614d1a57600080fd5b614d2261456f565b614d2e602083016142a7565b815267ffffffffffffffff60408301351115614d4957600080fd5b88603f604084013584010112614d5e57600080fd5b614d746146f06020604085013585010135614674565b6020604084810135850182810135808552928401939260e00201018b1015614d9b57600080fd5b6040808501358501015b6040858101358601602081013560e0020101811015614e9d5760e0818d031215614dce57600080fd5b614dd661456f565b614ddf82614227565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215614e1357600080fd5b614e1b6145bb565b614e2760208401614b80565b8152614e3560408401614b80565b6020820152614e4660608401614b94565b6040820152614e5760808401614b80565b6060820152614e6860a08401614b80565b6080820152614e7a60c08401356147c0565b60c083013560a0820152602082810191909152908452929092019160e001614da5565b5080602084015250508085525050602083019250602081019050614cb7565b5092505067ffffffffffffffff60208401351115614ed957600080fd5b614ee98460208501358501614ba6565b90509250929050565b600082601f830112614f0357600080fd5b81356020614f136146f083614674565b8083825260208201915060208460051b870101935086841115614f3557600080fd5b602086015b84811015614c3357614f4b81614227565b8352918301918301614f3a565b60008060408385031215614f6b57600080fd5b823567ffffffffffffffff80821115614f8357600080fd5b614f8f86838701614ef2565b93506020850135915080821115614fa557600080fd5b50614fb285828601614ef2565b9150509250929050565b60008083601f840112614fce57600080fd5b50813567ffffffffffffffff811115614fe657600080fd5b60208301915083602082850101111561224157600080fd5b6000806000806040858703121561501457600080fd5b843567ffffffffffffffff8082111561502c57600080fd5b61503888838901614fbc565b9096509450602087013591508082111561505157600080fd5b5061505e87828801614fbc565b95989497509550505050565b6000806040838503121561507d57600080fd5b615086836142a7565b9150614ee960208401614227565b6000602082840312156150a657600080fd5b813567ffffffffffffffff808211156150be57600080fd5b90830190604082860312156150d257600080fd5b6150da61456f565b8235828111156150e957600080fd5b6150f587828601614ef2565b82525060208301358281111561510a57600080fd5b61511687828601614ef2565b60208301525095945050505050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461424b57600080fd5b6000602080838503121561516857600080fd5b823567ffffffffffffffff81111561517f57600080fd5b8301601f8101851361519057600080fd5b803561519e6146f082614674565b81815261022091820283018401918482019190888411156151be57600080fd5b938501935b838510156147b457848903818112156151dc5760008081fd5b6151e461456f565b6151ed876142a7565b8152610200807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156152225760008081fd5b61522a6145de565b92506152378989016147ce565b83526040615246818a01614b94565b8a8501526060615257818b01614b80565b828601526080915061526a828b01614b80565b9085015260a061527b8a8201614b80565b8286015260c0915061528e828b01614b94565b9085015260e061529f8a8201614b80565b8286015261010091506152b3828b01614b94565b908501526101206152c58a8201614b94565b8286015261014091506152d9828b01614b94565b908501526101606152eb8a8201614b80565b8286015261018091506152ff828b01614b80565b908501526101a06153118a82016142a7565b828601526101c09150615325828b01614b80565b908501526101e06153378a82016147ce565b82860152615346838b01615125565b90850152505080880191909152835293840193918501916151c3565b6000602080838503121561537557600080fd5b823567ffffffffffffffff81111561538c57600080fd5b8301601f8101851361539d57600080fd5b80356153ab6146f082614674565b81815260069190911b820183019083810190878311156153ca57600080fd5b928401925b8284101561541c57604084890312156153e85760008081fd5b6153f061456f565b6153f985614227565b81526154068686016142a7565b81870152825260409390930192908401906153cf565b979650505050505050565b60008060008060006080868803121561543f57600080fd5b615448866142a7565b945061545660208701614227565b935060408601359250606086013567ffffffffffffffff81111561547957600080fd5b61548588828901614fbc565b969995985093965092949392505050565b8381528215156020820152606060408201526000612e6060608301846143b2565b600080604083850312156154ca57600080fd5b6154d3836142a7565b9150602083013567ffffffffffffffff8111156154ef57600080fd5b830160a0818603121561550157600080fd5b809150509250929050565b6000806040838503121561551f57600080fd5b61552883614227565b9150614ee9602084016142a7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176112c3576112c3615536565b6000826155b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261561a57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261565957600080fd5b83018035915067ffffffffffffffff82111561567457600080fd5b60200191503681900382131561224157600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126156be57600080fd5b83018035915067ffffffffffffffff8211156156d957600080fd5b6020019150600681901b360382131561224157600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461424b57600080fd5b60006040828403121561572f57600080fd5b61573761456f565b61574083614227565b815261574e602084016156f1565b60208201529392505050565b60006040828403121561576c57600080fd5b61577461456f565b615740836142a7565b6000602080838503121561579057600080fd5b823567ffffffffffffffff8111156157a757600080fd5b8301601f810185136157b857600080fd5b80356157c66146f082614674565b818152606091820283018401918482019190888411156157e557600080fd5b938501935b838510156147b45780858a0312156158025760008081fd5b61580a614602565b61581386614227565b81526158208787016156f1565b878201526040615831818801614b80565b90820152835293840193918501916157ea565b808201808211156112c3576112c3615536565b818103818111156112c3576112c3615536565b60ff81811683821601908111156112c3576112c3615536565b60ff82811682821603908111156112c3576112c3615536565b600181815b808511156158f557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156158db576158db615536565b808516156158e857918102915b93841c93908002906158a1565b509250929050565b60008261590c575060016112c3565b81615919575060006112c3565b816001811461592f576002811461593957615955565b60019150506112c3565b60ff84111561594a5761594a615536565b50506001821b6112c3565b5060208310610133831016604e8410600b8410161715615978575081810a6112c3565b615982838361589c565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156159b4576159b4615536565b029392505050565b6000610b6960ff8416836158fd565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015614b785760049490940360031b84901b1690921692915050565b60008085851115615a2157600080fd5b83861115615a2e57600080fd5b5050820193919092039150565b600060408284031215615a4d57600080fd5b615a5561456f565b82518152602083015161574e816147c0565b600060208284031215615a7957600080fd5b5051919050565b805169ffffffffffffffffffff8116811461424b57600080fd5b600080600080600060a08688031215615ab257600080fd5b615abb86615a80565b9450602086015193506040860151925060608601519150615ade60808701615a80565b90509295509295909350565b600060208284031215615afc57600080fd5b8151610b6981614698565b600060408284031215615b1957600080fd5b615b2161456f565b615b2a83614227565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156141c8576141c8615536565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", +var FeeQuoterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structFeeQuoter.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structFeeQuoter.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"}],\"name\":\"ReportForwarderUnauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feedTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"storedTimeStamp\",\"type\":\"uint256\"}],\"name\":\"StaleKeystoneUpdate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"reportId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission\",\"name\":\"permission\",\"type\":\"tuple\"}],\"name\":\"ReportPermissionSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structFeeQuoter.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structFeeQuoter.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"processPoolReturnData\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"destExecDataPerToken\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission[]\",\"name\":\"permissions\",\"type\":\"tuple[]\"}],\"name\":\"setReportPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b50604051620076d8380380620076d8833981016040819052620000349162001834565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a5a565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b26565b5050505050505062001ae5565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001953565b60209081029190910101519050620002f560028262000e5f565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001953565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000e7f565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001953565b6020026020010151600b62000e7f60201b90919060201c565b1562000499578281815181106200045b576200045b62001953565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001953565b6020026020010151600b62000e9660201b90919060201c565b156200053b57818181518110620004fd57620004fd62001953565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001953565b6020908102919091018101518051818301516001600160a01b0380831660008181526007875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001953565b6020026020010151905060008383815181106200065f576200065f62001953565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061016081015163ffffffff16155b80620006ba57506101e08101516001600160e01b031916630a04b54b60e21b14155b80620006da5750806060015163ffffffff1681610160015163ffffffff16115b15620007055760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260096020526040812060010154600160881b900460e01b6001600160e01b03191690036200078557816001600160401b03167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb7248260405162000777919062001969565b60405180910390a2620007c9565b816001600160401b03167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab2082604051620007c0919062001969565b60405180910390a25b8060096000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a8154816001600160401b0302191690836001600160401b031602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000a7e5762000a7e62001953565b6020026020010151600001519050600083838151811062000aa35762000aa362001953565b6020908102919091018101518101516001600160a01b03841660008181526008845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a5d565b60005b825181101562000d9957600083828151811062000b4a5762000b4a62001953565b6020026020010151905060008160000151905060005b82602001515181101562000d8a5760008360200151828151811062000b895762000b8962001953565b602002602001015160200151905060008460200151838151811062000bb25762000bb262001953565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c115760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000d77908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000b60565b50505080600101905062000b29565b5060005b81518110156200054457600082828151811062000dbe5762000dbe62001953565b6020026020010151600001519050600083838151811062000de35762000de362001953565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000d9d565b600062000e76836001600160a01b03841662000ead565b90505b92915050565b600062000e76836001600160a01b03841662000fb1565b600062000e76836001600160a01b03841662001003565b6000818152600183016020526040812054801562000fa657600062000ed460018362001aad565b855490915060009062000eea9060019062001aad565b905081811462000f5657600086600001828154811062000f0e5762000f0e62001953565b906000526020600020015490508087600001848154811062000f345762000f3462001953565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f6a5762000f6a62001acf565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e79565b600091505062000e79565b600081815260018301602052604081205462000ffa5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e79565b50600062000e79565b6000818152600183016020526040812054801562000fa65760006200102a60018362001aad565b8554909150600090620010409060019062001aad565b905080821462000f5657600086600001828154811062000f0e5762000f0e62001953565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200109f576200109f62001064565b60405290565b60405160c081016001600160401b03811182821017156200109f576200109f62001064565b60405161020081016001600160401b03811182821017156200109f576200109f62001064565b604051601f8201601f191681016001600160401b03811182821017156200111b576200111b62001064565b604052919050565b80516001600160a01b03811681146200113b57600080fd5b919050565b805163ffffffff811681146200113b57600080fd5b6000606082840312156200116857600080fd5b604051606081016001600160401b03811182821017156200118d576200118d62001064565b604052825190915081906001600160601b0381168114620011ad57600080fd5b8152620011bd6020840162001123565b6020820152620011d06040840162001140565b60408201525092915050565b60006001600160401b03821115620011f857620011f862001064565b5060051b60200190565b600082601f8301126200121457600080fd5b815160206200122d6200122783620011dc565b620010f0565b8083825260208201915060208460051b8701019350868411156200125057600080fd5b602086015b848110156200127757620012698162001123565b835291830191830162001255565b509695505050505050565b600082601f8301126200129457600080fd5b81516020620012a76200122783620011dc565b82815260609283028501820192828201919087851115620012c757600080fd5b8387015b858110156200135a5780890382811215620012e65760008081fd5b620012f06200107a565b620012fb8362001123565b8152604080601f1984011215620013125760008081fd5b6200131c6200107a565b92506200132b88850162001123565b835283015160ff81168114620013415760008081fd5b82880152808701919091528452928401928101620012cb565b5090979650505050505050565b80516001600160401b03811681146200113b57600080fd5b805161ffff811681146200113b57600080fd5b805180151581146200113b57600080fd5b600082601f830112620013b557600080fd5b81516020620013c86200122783620011dc565b82815260059290921b84018101918181019086841115620013e857600080fd5b8286015b84811015620012775780516001600160401b03808211156200140d57600080fd5b908801906040601f19838c0381018213156200142857600080fd5b620014326200107a565b6200143f89860162001367565b815282850151848111156200145357600080fd5b8086019550508c603f8601126200146957600080fd5b8885015193506200147e6200122785620011dc565b84815260e09094028501830193898101908e8611156200149d57600080fd5b958401955b858710156200157657868f0360e0811215620014bd57600080fd5b620014c76200107a565b620014d28962001123565b815260c08683011215620014e557600080fd5b620014ef620010a5565b9150620014fe8d8a0162001140565b82526200150d878a0162001140565b8d8301526200151f60608a016200137f565b878301526200153160808a0162001140565b60608301526200154460a08a0162001140565b60808301526200155760c08a0162001392565b60a0830152808d0191909152825260e09690960195908a0190620014a2565b828b015250875250505092840192508301620013ec565b600082601f8301126200159f57600080fd5b81516020620015b26200122783620011dc565b82815260069290921b84018101918181019086841115620015d257600080fd5b8286015b84811015620012775760408189031215620015f15760008081fd5b620015fb6200107a565b620016068262001123565b81526200161585830162001367565b81860152835291830191604001620015d6565b80516001600160e01b0319811681146200113b57600080fd5b600082601f8301126200165357600080fd5b81516020620016666200122783620011dc565b82815261022092830285018201928282019190878511156200168757600080fd5b8387015b858110156200135a5780890382811215620016a65760008081fd5b620016b06200107a565b620016bb8362001367565b815261020080601f1984011215620016d35760008081fd5b620016dd620010ca565b9250620016ec88850162001392565b83526040620016fd8186016200137f565b8985015260606200171081870162001140565b82860152608091506200172582870162001140565b9085015260a06200173886820162001140565b8286015260c091506200174d8287016200137f565b9085015260e06200176086820162001140565b828601526101009150620017768287016200137f565b908501526101206200178a8682016200137f565b828601526101409150620017a08287016200137f565b90850152610160620017b486820162001140565b828601526101809150620017ca82870162001140565b908501526101a0620017de86820162001367565b828601526101c09150620017f482870162001140565b908501526101e06200180886820162001392565b828601526200181983870162001628565b9085015250508087019190915284529284019281016200168b565b6000806000806000806000610120888a0312156200185157600080fd5b6200185d898962001155565b60608901519097506001600160401b03808211156200187b57600080fd5b620018898b838c0162001202565b975060808a0151915080821115620018a057600080fd5b620018ae8b838c0162001202565b965060a08a0151915080821115620018c557600080fd5b620018d38b838c0162001282565b955060c08a0151915080821115620018ea57600080fd5b620018f88b838c01620013a3565b945060e08a01519150808211156200190f57600080fd5b6200191d8b838c016200158d565b93506101008a01519150808211156200193557600080fd5b50620019448a828b0162001641565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610200810160208301516200198a602084018261ffff169052565b506040830151620019a3604084018263ffffffff169052565b506060830151620019bc606084018263ffffffff169052565b506080830151620019d5608084018263ffffffff169052565b5060a0830151620019ec60a084018261ffff169052565b5060c083015162001a0560c084018263ffffffff169052565b5060e083015162001a1c60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501516001600160401b0316908401526101a080850151909116908301526101c0808401511515908301526101e0928301516001600160e01b031916929091019190915290565b8181038181111562000e7957634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051615b9962001b3f600039600081816102ef0152818161219101526121fa0152600081816102b301528181611917015261197701526000818161027f015281816119a00152611a100152615b996000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c806379ba509711610104578063a69c64c0116100a2578063d02641a011610071578063d02641a014610a81578063d8694ccd14610a94578063f2fde38b14610aa7578063ffdb4b3714610aba57600080fd5b8063a69c64c014610997578063bf78e03f146109aa578063c4276bfc14610a57578063cdc73d5114610a7957600080fd5b806382b49eb0116100de57806382b49eb0146107d95780638da5cb5b1461094957806391a2749a146109715780639ea600261461098457600080fd5b806379ba5097146107ab5780637afac322146107b3578063805f2132146107c657600080fd5b8063407e1086116101715780634ab35b0b1161014b5780634ab35b0b14610441578063514e8cff146104815780636def4ce714610524578063770e2dc41461079857600080fd5b8063407e1086146103fb57806341ed29e71461040e57806345ac924d1461042157600080fd5b8063085318f8116101ad578063085318f814610368578063181f5a77146103885780632451a627146103d15780633937306f146103e657600080fd5b806241e5be146101d3578063061877e3146101f957806306285c6914610252575b600080fd5b6101e66101e1366004614250565b610b02565b6040519081526020015b60405180910390f35b61023961020736600461428c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101f0565b61031c604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101f0565b61037b610376366004614304565b610b70565b6040516101f09190614416565b6103c46040518060400160405280601381526020017f46656551756f74657220312e362e302d6465760000000000000000000000000081525081565b6040516101f09190614498565b6103d9610ee2565b6040516101f091906144ab565b6103f96103f4366004614505565b610ef3565b005b6103f96104093660046146a7565b6111a8565b6103f961041c3660046147d9565b6111bc565b61043461042f366004614914565b6111fe565b6040516101f09190614956565b61045461044f36600461428c565b6112c9565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b61051761048f3660046149d1565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101f091906149ec565b61078b6105323660046149d1565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101919091525067ffffffffffffffff908116600090815260096020908152604091829020825161020081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a085015271010000000000000000000000000000000000808404881660c086015275010000000000000000000000000000000000000000008404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b01000000000000000000000000000000000000000000000000000000909204861661014084015260019093015480861661016084015264010000000081049096166101808301526c0100000000000000000000000086049094166101a0820152700100000000000000000000000000000000850490911615156101c08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b166101e082015290565b6040516101f09190614a27565b6103f96107a6366004614c3e565b6112d4565b6103f96112e6565b6103f96107c1366004614f58565b6113e3565b6103f96107d4366004614ffe565b6113f5565b6108e96107e736600461506a565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff919091166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101f09190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6103f961097f366004615094565b6118dd565b6103f9610992366004615155565b6118ee565b6103f96109a5366004615362565b6118ff565b610a236109b836600461428c565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526007825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101f0565b610a6a610a65366004615427565b611910565b6040516101f093929190615496565b6103d9611b06565b610517610a8f36600461428c565b611b12565b6101e6610aa23660046154b7565b611c0e565b6103f9610ab536600461428c565b6120ac565b610acd610ac836600461550c565b6120bd565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101f0565b6000610b0d82612248565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b3485612248565b610b5c907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685615565565b610b66919061557c565b90505b9392505050565b67ffffffffffffffff8086166000908152600960205260409020600101546060917101000000000000000000000000000000000090910460e01b908590811115610bbc57610bbc614540565b604051908082528060200260200182016040528015610bef57816020015b6060815260200190600190039081610bda5790505b50915060005b85811015610ed7576000858583818110610c1157610c116155b7565b610c27926020604090920201908101915061428c565b90506000888884818110610c3d57610c3d6155b7565b9050602002810190610c4f91906155e6565b610c5d906040810190615624565b9150506020811115610d125767ffffffffffffffff8a166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115610d12576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b610d82848a8a86818110610d2857610d286155b7565b9050602002810190610d3a91906155e6565b610d48906020810190615624565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122e292505050565b67ffffffffffffffff8a166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320815160c081018352905463ffffffff8082168352640100000000820481168386015268010000000000000000820461ffff16838501526a01000000000000000000008204811660608401526e010000000000000000000000000000820481166080840152720100000000000000000000000000000000000090910460ff16151560a08301908152958552600990935290832054935190937b0100000000000000000000000000000000000000000000000000000090049091169190610e815781610e87565b82606001515b6040805163ffffffff8316602082015291925001604051602081830303815290604052888781518110610ebc57610ebc6155b7565b60200260200101819052505050505050806001019050610bf5565b505095945050505050565b6060610eee6002612339565b905090565b610efb612346565b6000610f078280615689565b9050905060005b81811015611051576000610f228480615689565b83818110610f3257610f326155b7565b905060400201803603810190610f48919061571d565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600690975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926110409290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610f0e565b5060006110616020840184615689565b9050905060005b818110156111a257600061107f6020860186615689565b8381811061108f5761108f6155b7565b9050604002018036038101906110a5919061575a565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e926111919290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101611068565b50505050565b6111b061238b565b6111b98161240c565b50565b6111c461238b565b60005b81518110156111fa576111f28282815181106111e5576111e56155b7565b602002602001015161250a565b6001016111c7565b5050565b60608160008167ffffffffffffffff81111561121c5761121c614540565b60405190808252806020026020018201604052801561126157816020015b604080518082019091526000808252602082015281526020019060019003908161123a5790505b50905060005b828110156112be57611299868683818110611284576112846155b7565b9050602002016020810190610a8f919061428c565b8282815181106112ab576112ab6155b7565b6020908102919091010152600101611267565b509150505b92915050565b60006112c382612248565b6112dc61238b565b6111fa82826126dc565b60015473ffffffffffffffffffffffffffffffffffffffff163314611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610d09565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6113eb61238b565b6111fa8282612ae9565b600080600061143987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c3092505050565b92509250925061144b33838584612c4b565b60006114598587018761577d565b905060005b81518110156118d25760006007600084848151811061147f5761147f6155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160009081205474010000000000000000000000000000000000000000900460ff169150819003611540578282815181106114e9576114e96155b7565b6020908102919091010151516040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b600061158960128386868151811061155a5761155a6155b7565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612da3565b9050600660008585815181106115a1576115a16155b7565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff16848481518110611613576116136155b7565b60200260200101516040015163ffffffff16101561171d5783838151811061163d5761163d6155b7565b60200260200101516000015184848151811061165b5761165b6155b7565b6020026020010151604001516006600087878151811061167d5761167d6155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260409081016000205490517f191ec70600000000000000000000000000000000000000000000000000000000815293909116600484015263ffffffff91821660248401527c01000000000000000000000000000000000000000000000000000000009004166044820152606401610d09565b6040518060400160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260200185858151811061175e5761175e6155b7565b60200260200101516040015163ffffffff1681525060066000868681518110611789576117896155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790558351849084908110611821576118216155b7565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff167f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a82868681518110611877576118776155b7565b6020026020010151604001516040516118c09291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a2505060010161145e565b505050505050505050565b6118e561238b565b6111b981612e69565b6118f661238b565b6111b981612ff5565b61190761238b565b6111b98161349b565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036119705785925061199e565b61199b87877f0000000000000000000000000000000000000000000000000000000000000000610b02565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611a3d576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610d09565b67ffffffffffffffff881660009081526009602052604081206001015463ffffffff1690611a6c878784613585565b9050806020015193508484611af3836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b6060610eee600b612339565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600760209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff169082015290611c0557505073ffffffffffffffffffffffffffffffffffffffff166000908152600660209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b698161372e565b67ffffffffffffffff8083166000908152600960209081526040808320815161020081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a086015271010000000000000000000000000000000000808504881660c087015275010000000000000000000000000000000000000000008504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b01000000000000000000000000000000000000000000000000000000909304861661014085015260019094015480861661016085015264010000000081049098166101808401526c0100000000000000000000000088049094166101a0830152700100000000000000000000000000000000870490931615156101c08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b166101e0840152909190611e28576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000611e376040850185615689565b9150611e93905082611e4c6020870187615624565b905083611e598880615624565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506138bd92505050565b6000600881611ea8608088016060890161428c565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff16915080611ef7611ef16080890160608a0161428c565b896120bd565b9092509050600080808615611f3d57611f31888c611f1b60808e0160608f0161428c565b888e8060400190611f2c9190615689565b613967565b91945092509050611f5d565b6101a0880151611f5a9063ffffffff16662386f26fc10000615565565b92505b61010088015160009061ffff1615611fa157611f9e896dffffffffffffffffffffffffffff607088901c16611f9560208f018f615624565b90508b86613c3f565b90505b61018089015160009067ffffffffffffffff16611fca611fc460808f018f615624565b8d613cef565b600001518563ffffffff168c60a0015161ffff168f8060200190611fee9190615624565b611ff9929150615565565b8d6080015163ffffffff1661200e9190615844565b6120189190615844565b6120229190615844565b61203c906dffffffffffffffffffffffffffff8916615565565b6120469190615565565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8716828261207d67ffffffffffffffff8c1689615565565b6120879190615844565b6120919190615844565b61209b919061557c565b9d9c50505050505050505050505050565b6120b461238b565b6111b981613db0565b67ffffffffffffffff811660009081526005602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203612175576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000816020015163ffffffff164261218d9190615857565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff1681111561222e576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610d09565b61223786612248565b9151919350909150505b9250929050565b60008061225483611b12565b9050806020015163ffffffff166000148061228c575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b156122db576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610d09565b5192915050565b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016111fa5761233481613ea5565b505050565b60606000610b6983613f58565b612351600233613fb4565b612389576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610d09565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314612389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d09565b60005b81518110156111fa57600082828151811061242c5761242c6155b7565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526007875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a250505080600101905061240f565b60006125c382600001518360600151846020015185604001516040805173ffffffffffffffffffffffffffffffffffffffff80871660208301528516918101919091527fffffffffffffffffffff00000000000000000000000000000000000000000000831660608201527fffff0000000000000000000000000000000000000000000000000000000000008216608082015260009060a001604051602081830303815290604052805190602001209050949350505050565b60808301516000828152600460205260409081902080549215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316929092179091555190915081907f32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a3906126d0908590600060a08201905073ffffffffffffffffffffffffffffffffffffffff8084511683527fffffffffffffffffffff0000000000000000000000000000000000000000000060208501511660208401527fffff00000000000000000000000000000000000000000000000000000000000060408501511660408401528060608501511660608401525060808301511515608083015292915050565b60405180910390a25050565b60005b8251811015612a055760008382815181106126fc576126fc6155b7565b6020026020010151905060008160000151905060005b8260200151518110156129f757600083602001518281518110612737576127376155b7565b602002602001015160200151905060008460200151838151811061275d5761275d6155b7565b6020026020010151600001519050602063ffffffff16826080015163ffffffff1610156127e05760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610d09565b67ffffffffffffffff84166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906129e5908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101612712565b5050508060010190506126df565b5060005b8151811015612334576000828281518110612a2657612a266155b7565b60200260200101516000015190506000838381518110612a4857612a486155b7565b60209081029190910181015181015167ffffffffffffffff84166000818152600a8452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612a09565b60005b8251811015612b8c57612b22838281518110612b0a57612b0a6155b7565b6020026020010151600b613fe390919063ffffffff16565b15612b8457828181518110612b3957612b396155b7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b600101612aec565b5060005b815181101561233457612bc6828281518110612bae57612bae6155b7565b6020026020010151600b61400590919063ffffffff16565b15612c2857818181518110612bdd57612bdd6155b7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101612b90565b6040810151604a820151605e90920151909260609290921c91565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602080840191909152908616828401527fffffffffffffffffffff00000000000000000000000000000000000000000000851660608301527fffff00000000000000000000000000000000000000000000000000000000000084166080808401919091528351808403909101815260a09092018352815191810191909120600081815260049092529190205460ff16612d9c576040517f097e17ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8087166004830152851660248201527fffffffffffffffffffff00000000000000000000000000000000000000000000841660448201527fffff00000000000000000000000000000000000000000000000000000000000083166064820152608401610d09565b5050505050565b600080612db0848661586a565b9050600060248260ff161115612de757612dcb602483615883565b612dd690600a6159bc565b612de0908561557c565b9050612e0a565b612df2826024615883565b612dfd90600a6159bc565b612e079085615565565b90505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612e60576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b95945050505050565b602081015160005b8151811015612f04576000828281518110612e8e57612e8e6155b7565b60200260200101519050612eac81600261402790919063ffffffff16565b15612efb5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612e71565b50815160005b81518110156111a2576000828281518110612f2757612f276155b7565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612f97576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fa2600282613fe3565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101612f0a565b60005b81518110156111fa576000828281518110613015576130156155b7565b602002602001015190506000838381518110613033576130336155b7565b60200260200101516000015190506000826020015190508167ffffffffffffffff166000148061306c575061016081015163ffffffff16155b806130be57506101e08101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130dd5750806060015163ffffffff1681610160015163ffffffff16115b15613120576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610d09565b67ffffffffffffffff821660009081526009602052604081206001015471010000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131c4578167ffffffffffffffff167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb724826040516131b79190614a27565b60405180910390a2613207565b8167ffffffffffffffff167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab20826040516131fe9190614a27565b60405180910390a25b80600960008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612ff8565b60005b81518110156111fa5760008282815181106134bb576134bb6155b7565b602002602001015160000151905060008383815181106134dd576134dd6155b7565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526008845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010161349e565b604080518082019091526000808252602082015260008390036135c657506040805180820190915267ffffffffffffffff8216815260006020820152610b69565b60006135d284866159cb565b905060006135e38560048189615a11565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f0000000000000000000000000000000000000000000000000000000000161368057808060200190518101906136779190615a3b565b92505050610b69565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016136fc576040518060400160405280828060200190518101906136e89190615a67565b815260006020909101529250610b69915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137bc9190615a9a565b50505091505060008112156137fd576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061387c8373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561384d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138719190615aea565b866020015184612da3565b604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff4216602082015295945050505050565b836040015163ffffffff168311156139165760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610d09565b836020015161ffff16821115613958576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111a2846101e00151826122e2565b6000808083815b81811015613c3157600087878381811061398a5761398a6155b7565b9050604002018036038101906139a09190615b07565b67ffffffffffffffff8c166000908152600a60209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090613ac0576101208d0151613a8d9061ffff16662386f26fc10000615565565b613a979088615844565b96508c610140015186613aaa9190615b40565b9550613ab7602086615b40565b94505050613c29565b604081015160009061ffff1615613b795760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614613b1c578351613b1590612248565b9050613b1f565b508a5b620186a0836040015161ffff16613b618660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661404990919063ffffffff16565b613b6b9190615565565b613b75919061557c565b9150505b6060820151613b889088615b40565b9650816080015186613b9a9190615b40565b8251909650600090613bb99063ffffffff16662386f26fc10000615565565b905080821015613bd857613bcd818a615844565b985050505050613c29565b6000836020015163ffffffff16662386f26fc10000613bf79190615565565b905080831115613c1757613c0b818b615844565b99505050505050613c29565b613c21838b615844565b995050505050505b60010161396e565b505096509650969350505050565b60008063ffffffff8316613c5561016086615565565b613c61876101c0615844565b613c6b9190615844565b613c759190615844565b905060008760c0015163ffffffff168860e0015161ffff1683613c989190615565565b613ca29190615844565b61010089015190915061ffff16613cc96dffffffffffffffffffffffffffff891683615565565b613cd39190615565565b613ce390655af3107a4000615565565b98975050505050505050565b60408051808201909152600080825260208201526000613d1b858585610160015163ffffffff16613585565b9050826060015163ffffffff1681600001511115613d65576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101c001518015613d7957508060200151155b15610b66576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603613e2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d09565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008151602014613ee457816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614498565b600082806020019051810190613efa9190615a67565b905073ffffffffffffffffffffffffffffffffffffffff811180613f1f575061040081105b156112c357826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614498565b606081600001805480602002602001604051908101604052809291908181526020018280548015613fa857602002820191906000526020600020905b815481526020019060010190808311613f94575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b69565b6000610b698373ffffffffffffffffffffffffffffffffffffffff8416614086565b6000610b698373ffffffffffffffffffffffffffffffffffffffff84166140d5565b6000610b698373ffffffffffffffffffffffffffffffffffffffff84166141cf565b6000670de0b6b3a764000061407c837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616615565565b610b69919061557c565b60008181526001830160205260408120546140cd575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112c3565b5060006112c3565b600081815260018301602052604081205480156141be5760006140f9600183615857565b855490915060009061410d90600190615857565b905080821461417257600086600001828154811061412d5761412d6155b7565b9060005260206000200154905080876000018481548110614150576141506155b7565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061418357614183615b5d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112c3565b60009150506112c3565b5092915050565b600081815260018301602052604081205480156141be5760006141f3600183615857565b855490915060009061420790600190615857565b905081811461417257600086600001828154811061412d5761412d6155b7565b803573ffffffffffffffffffffffffffffffffffffffff8116811461424b57600080fd5b919050565b60008060006060848603121561426557600080fd5b61426e84614227565b92506020840135915061428360408501614227565b90509250925092565b60006020828403121561429e57600080fd5b610b6982614227565b803567ffffffffffffffff8116811461424b57600080fd5b60008083601f8401126142d157600080fd5b50813567ffffffffffffffff8111156142e957600080fd5b6020830191508360208260051b850101111561224157600080fd5b60008060008060006060868803121561431c57600080fd5b614325866142a7565b9450602086013567ffffffffffffffff8082111561434257600080fd5b61434e89838a016142bf565b9096509450604088013591508082111561436757600080fd5b818801915088601f83011261437b57600080fd5b81358181111561438a57600080fd5b8960208260061b850101111561439f57600080fd5b9699959850939650602001949392505050565b6000815180845260005b818110156143d8576020818501810151868301820152016143bc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561448b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526144798583516143b2565b9450928501929085019060010161443f565b5092979650505050505050565b602081526000610b6960208301846143b2565b6020808252825182820181905260009190848201906040850190845b818110156144f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016144c7565b50909695505050505050565b60006020828403121561451757600080fd5b813567ffffffffffffffff81111561452e57600080fd5b820160408185031215610b6957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561459257614592614540565b60405290565b60405160a0810167ffffffffffffffff8111828210171561459257614592614540565b60405160c0810167ffffffffffffffff8111828210171561459257614592614540565b604051610200810167ffffffffffffffff8111828210171561459257614592614540565b6040516060810167ffffffffffffffff8111828210171561459257614592614540565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561466c5761466c614540565b604052919050565b600067ffffffffffffffff82111561468e5761468e614540565b5060051b60200190565b60ff811681146111b957600080fd5b600060208083850312156146ba57600080fd5b823567ffffffffffffffff8111156146d157600080fd5b8301601f810185136146e257600080fd5b80356146f56146f082614674565b614625565b8181526060918202830184019184820191908884111561471457600080fd5b938501935b838510156147b457848903818112156147325760008081fd5b61473a61456f565b61474387614227565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147775760008081fd5b61477f61456f565b925061478c898901614227565b835287013561479a81614698565b828901528088019190915283529384019391850191614719565b50979650505050505050565b80151581146111b957600080fd5b803561424b816147c0565b600060208083850312156147ec57600080fd5b823567ffffffffffffffff81111561480357600080fd5b8301601f8101851361481457600080fd5b80356148226146f082614674565b81815260a0918202830184019184820191908884111561484157600080fd5b938501935b838510156147b45780858a03121561485e5760008081fd5b614866614598565b61486f86614227565b8152868601357fffffffffffffffffffff00000000000000000000000000000000000000000000811681146148a45760008081fd5b818801526040868101357fffff000000000000000000000000000000000000000000000000000000000000811681146148dd5760008081fd5b9082015260606148ee878201614227565b90820152608086810135614901816147c0565b9082015283529384019391850191614846565b6000806020838503121561492757600080fd5b823567ffffffffffffffff81111561493e57600080fd5b61494a858286016142bf565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b828110156149c4576149b484835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101614973565b5091979650505050505050565b6000602082840312156149e357600080fd5b610b69826142a7565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff1690820152604081016112c3565b81511515815261020081016020830151614a47602084018261ffff169052565b506040830151614a5f604084018263ffffffff169052565b506060830151614a77606084018263ffffffff169052565b506080830151614a8f608084018263ffffffff169052565b5060a0830151614aa560a084018261ffff169052565b5060c0830151614abd60c084018263ffffffff169052565b5060e0830151614ad360e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff90811691840191909152610160808501518216908401526101808085015167ffffffffffffffff16908401526101a080850151909116908301526101c0808401511515908301526101e0808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461424b57600080fd5b803561ffff8116811461424b57600080fd5b600082601f830112614bb757600080fd5b81356020614bc76146f083614674565b82815260069290921b84018101918181019086841115614be657600080fd5b8286015b84811015614c335760408189031215614c035760008081fd5b614c0b61456f565b614c14826142a7565b8152614c21858301614227565b81860152835291830191604001614bea565b509695505050505050565b60008060408385031215614c5157600080fd5b67ffffffffffffffff83351115614c6757600080fd5b83601f843585010112614c7957600080fd5b614c896146f08435850135614674565b8335840180358083526020808401939260059290921b90910101861015614caf57600080fd5b602085358601015b85358601803560051b01602001811015614ebc5767ffffffffffffffff81351115614ce157600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a03011215614d1a57600080fd5b614d2261456f565b614d2e602083016142a7565b815267ffffffffffffffff60408301351115614d4957600080fd5b88603f604084013584010112614d5e57600080fd5b614d746146f06020604085013585010135614674565b6020604084810135850182810135808552928401939260e00201018b1015614d9b57600080fd5b6040808501358501015b6040858101358601602081013560e0020101811015614e9d5760e0818d031215614dce57600080fd5b614dd661456f565b614ddf82614227565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215614e1357600080fd5b614e1b6145bb565b614e2760208401614b80565b8152614e3560408401614b80565b6020820152614e4660608401614b94565b6040820152614e5760808401614b80565b6060820152614e6860a08401614b80565b6080820152614e7a60c08401356147c0565b60c083013560a0820152602082810191909152908452929092019160e001614da5565b5080602084015250508085525050602083019250602081019050614cb7565b5092505067ffffffffffffffff60208401351115614ed957600080fd5b614ee98460208501358501614ba6565b90509250929050565b600082601f830112614f0357600080fd5b81356020614f136146f083614674565b8083825260208201915060208460051b870101935086841115614f3557600080fd5b602086015b84811015614c3357614f4b81614227565b8352918301918301614f3a565b60008060408385031215614f6b57600080fd5b823567ffffffffffffffff80821115614f8357600080fd5b614f8f86838701614ef2565b93506020850135915080821115614fa557600080fd5b50614fb285828601614ef2565b9150509250929050565b60008083601f840112614fce57600080fd5b50813567ffffffffffffffff811115614fe657600080fd5b60208301915083602082850101111561224157600080fd5b6000806000806040858703121561501457600080fd5b843567ffffffffffffffff8082111561502c57600080fd5b61503888838901614fbc565b9096509450602087013591508082111561505157600080fd5b5061505e87828801614fbc565b95989497509550505050565b6000806040838503121561507d57600080fd5b615086836142a7565b9150614ee960208401614227565b6000602082840312156150a657600080fd5b813567ffffffffffffffff808211156150be57600080fd5b90830190604082860312156150d257600080fd5b6150da61456f565b8235828111156150e957600080fd5b6150f587828601614ef2565b82525060208301358281111561510a57600080fd5b61511687828601614ef2565b60208301525095945050505050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461424b57600080fd5b6000602080838503121561516857600080fd5b823567ffffffffffffffff81111561517f57600080fd5b8301601f8101851361519057600080fd5b803561519e6146f082614674565b81815261022091820283018401918482019190888411156151be57600080fd5b938501935b838510156147b457848903818112156151dc5760008081fd5b6151e461456f565b6151ed876142a7565b8152610200807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156152225760008081fd5b61522a6145de565b92506152378989016147ce565b83526040615246818a01614b94565b8a8501526060615257818b01614b80565b828601526080915061526a828b01614b80565b9085015260a061527b8a8201614b80565b8286015260c0915061528e828b01614b94565b9085015260e061529f8a8201614b80565b8286015261010091506152b3828b01614b94565b908501526101206152c58a8201614b94565b8286015261014091506152d9828b01614b94565b908501526101606152eb8a8201614b80565b8286015261018091506152ff828b01614b80565b908501526101a06153118a82016142a7565b828601526101c09150615325828b01614b80565b908501526101e06153378a82016147ce565b82860152615346838b01615125565b90850152505080880191909152835293840193918501916151c3565b6000602080838503121561537557600080fd5b823567ffffffffffffffff81111561538c57600080fd5b8301601f8101851361539d57600080fd5b80356153ab6146f082614674565b81815260069190911b820183019083810190878311156153ca57600080fd5b928401925b8284101561541c57604084890312156153e85760008081fd5b6153f061456f565b6153f985614227565b81526154068686016142a7565b81870152825260409390930192908401906153cf565b979650505050505050565b60008060008060006080868803121561543f57600080fd5b615448866142a7565b945061545660208701614227565b935060408601359250606086013567ffffffffffffffff81111561547957600080fd5b61548588828901614fbc565b969995985093965092949392505050565b8381528215156020820152606060408201526000612e6060608301846143b2565b600080604083850312156154ca57600080fd5b6154d3836142a7565b9150602083013567ffffffffffffffff8111156154ef57600080fd5b830160a0818603121561550157600080fd5b809150509250929050565b6000806040838503121561551f57600080fd5b61552883614227565b9150614ee9602084016142a7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176112c3576112c3615536565b6000826155b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261561a57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261565957600080fd5b83018035915067ffffffffffffffff82111561567457600080fd5b60200191503681900382131561224157600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126156be57600080fd5b83018035915067ffffffffffffffff8211156156d957600080fd5b6020019150600681901b360382131561224157600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461424b57600080fd5b60006040828403121561572f57600080fd5b61573761456f565b61574083614227565b815261574e602084016156f1565b60208201529392505050565b60006040828403121561576c57600080fd5b61577461456f565b615740836142a7565b6000602080838503121561579057600080fd5b823567ffffffffffffffff8111156157a757600080fd5b8301601f810185136157b857600080fd5b80356157c66146f082614674565b818152606091820283018401918482019190888411156157e557600080fd5b938501935b838510156147b45780858a0312156158025760008081fd5b61580a614602565b61581386614227565b81526158208787016156f1565b878201526040615831818801614b80565b90820152835293840193918501916157ea565b808201808211156112c3576112c3615536565b818103818111156112c3576112c3615536565b60ff81811683821601908111156112c3576112c3615536565b60ff82811682821603908111156112c3576112c3615536565b600181815b808511156158f557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156158db576158db615536565b808516156158e857918102915b93841c93908002906158a1565b509250929050565b60008261590c575060016112c3565b81615919575060006112c3565b816001811461592f576002811461593957615955565b60019150506112c3565b60ff84111561594a5761594a615536565b50506001821b6112c3565b5060208310610133831016604e8410600b8410161715615978575081810a6112c3565b615982838361589c565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156159b4576159b4615536565b029392505050565b6000610b6960ff8416836158fd565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015614b785760049490940360031b84901b1690921692915050565b60008085851115615a2157600080fd5b83861115615a2e57600080fd5b5050820193919092039150565b600060408284031215615a4d57600080fd5b615a5561456f565b82518152602083015161574e816147c0565b600060208284031215615a7957600080fd5b5051919050565b805169ffffffffffffffffffff8116811461424b57600080fd5b600080600080600060a08688031215615ab257600080fd5b615abb86615a80565b9450602086015193506040860151925060608601519150615ade60808701615a80565b90509295509295909350565b600060208284031215615afc57600080fd5b8151610b6981614698565b600060408284031215615b1957600080fd5b615b2161456f565b615b2a83614227565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156141c8576141c8615536565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } -var PriceRegistryABI = PriceRegistryMetaData.ABI +var FeeQuoterABI = FeeQuoterMetaData.ABI -var PriceRegistryBin = PriceRegistryMetaData.Bin +var FeeQuoterBin = FeeQuoterMetaData.Bin -func DeployPriceRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig PriceRegistryStaticConfig, priceUpdaters []common.Address, feeTokens []common.Address, tokenPriceFeeds []PriceRegistryTokenPriceFeedUpdate, tokenTransferFeeConfigArgs []PriceRegistryTokenTransferFeeConfigArgs, premiumMultiplierWeiPerEthArgs []PriceRegistryPremiumMultiplierWeiPerEthArgs, destChainConfigArgs []PriceRegistryDestChainConfigArgs) (common.Address, *types.Transaction, *PriceRegistry, error) { - parsed, err := PriceRegistryMetaData.GetAbi() +func DeployFeeQuoter(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig FeeQuoterStaticConfig, priceUpdaters []common.Address, feeTokens []common.Address, tokenPriceFeeds []FeeQuoterTokenPriceFeedUpdate, tokenTransferFeeConfigArgs []FeeQuoterTokenTransferFeeConfigArgs, premiumMultiplierWeiPerEthArgs []FeeQuoterPremiumMultiplierWeiPerEthArgs, destChainConfigArgs []FeeQuoterDestChainConfigArgs) (common.Address, *types.Transaction, *FeeQuoter, error) { + parsed, err := FeeQuoterMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -171,132 +171,132 @@ func DeployPriceRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PriceRegistryBin), backend, staticConfig, priceUpdaters, feeTokens, tokenPriceFeeds, tokenTransferFeeConfigArgs, premiumMultiplierWeiPerEthArgs, destChainConfigArgs) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FeeQuoterBin), backend, staticConfig, priceUpdaters, feeTokens, tokenPriceFeeds, tokenTransferFeeConfigArgs, premiumMultiplierWeiPerEthArgs, destChainConfigArgs) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &PriceRegistry{address: address, abi: *parsed, PriceRegistryCaller: PriceRegistryCaller{contract: contract}, PriceRegistryTransactor: PriceRegistryTransactor{contract: contract}, PriceRegistryFilterer: PriceRegistryFilterer{contract: contract}}, nil + return address, tx, &FeeQuoter{address: address, abi: *parsed, FeeQuoterCaller: FeeQuoterCaller{contract: contract}, FeeQuoterTransactor: FeeQuoterTransactor{contract: contract}, FeeQuoterFilterer: FeeQuoterFilterer{contract: contract}}, nil } -type PriceRegistry struct { +type FeeQuoter struct { address common.Address abi abi.ABI - PriceRegistryCaller - PriceRegistryTransactor - PriceRegistryFilterer + FeeQuoterCaller + FeeQuoterTransactor + FeeQuoterFilterer } -type PriceRegistryCaller struct { +type FeeQuoterCaller struct { contract *bind.BoundContract } -type PriceRegistryTransactor struct { +type FeeQuoterTransactor struct { contract *bind.BoundContract } -type PriceRegistryFilterer struct { +type FeeQuoterFilterer struct { contract *bind.BoundContract } -type PriceRegistrySession struct { - Contract *PriceRegistry +type FeeQuoterSession struct { + Contract *FeeQuoter CallOpts bind.CallOpts TransactOpts bind.TransactOpts } -type PriceRegistryCallerSession struct { - Contract *PriceRegistryCaller +type FeeQuoterCallerSession struct { + Contract *FeeQuoterCaller CallOpts bind.CallOpts } -type PriceRegistryTransactorSession struct { - Contract *PriceRegistryTransactor +type FeeQuoterTransactorSession struct { + Contract *FeeQuoterTransactor TransactOpts bind.TransactOpts } -type PriceRegistryRaw struct { - Contract *PriceRegistry +type FeeQuoterRaw struct { + Contract *FeeQuoter } -type PriceRegistryCallerRaw struct { - Contract *PriceRegistryCaller +type FeeQuoterCallerRaw struct { + Contract *FeeQuoterCaller } -type PriceRegistryTransactorRaw struct { - Contract *PriceRegistryTransactor +type FeeQuoterTransactorRaw struct { + Contract *FeeQuoterTransactor } -func NewPriceRegistry(address common.Address, backend bind.ContractBackend) (*PriceRegistry, error) { - abi, err := abi.JSON(strings.NewReader(PriceRegistryABI)) +func NewFeeQuoter(address common.Address, backend bind.ContractBackend) (*FeeQuoter, error) { + abi, err := abi.JSON(strings.NewReader(FeeQuoterABI)) if err != nil { return nil, err } - contract, err := bindPriceRegistry(address, backend, backend, backend) + contract, err := bindFeeQuoter(address, backend, backend, backend) if err != nil { return nil, err } - return &PriceRegistry{address: address, abi: abi, PriceRegistryCaller: PriceRegistryCaller{contract: contract}, PriceRegistryTransactor: PriceRegistryTransactor{contract: contract}, PriceRegistryFilterer: PriceRegistryFilterer{contract: contract}}, nil + return &FeeQuoter{address: address, abi: abi, FeeQuoterCaller: FeeQuoterCaller{contract: contract}, FeeQuoterTransactor: FeeQuoterTransactor{contract: contract}, FeeQuoterFilterer: FeeQuoterFilterer{contract: contract}}, nil } -func NewPriceRegistryCaller(address common.Address, caller bind.ContractCaller) (*PriceRegistryCaller, error) { - contract, err := bindPriceRegistry(address, caller, nil, nil) +func NewFeeQuoterCaller(address common.Address, caller bind.ContractCaller) (*FeeQuoterCaller, error) { + contract, err := bindFeeQuoter(address, caller, nil, nil) if err != nil { return nil, err } - return &PriceRegistryCaller{contract: contract}, nil + return &FeeQuoterCaller{contract: contract}, nil } -func NewPriceRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*PriceRegistryTransactor, error) { - contract, err := bindPriceRegistry(address, nil, transactor, nil) +func NewFeeQuoterTransactor(address common.Address, transactor bind.ContractTransactor) (*FeeQuoterTransactor, error) { + contract, err := bindFeeQuoter(address, nil, transactor, nil) if err != nil { return nil, err } - return &PriceRegistryTransactor{contract: contract}, nil + return &FeeQuoterTransactor{contract: contract}, nil } -func NewPriceRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*PriceRegistryFilterer, error) { - contract, err := bindPriceRegistry(address, nil, nil, filterer) +func NewFeeQuoterFilterer(address common.Address, filterer bind.ContractFilterer) (*FeeQuoterFilterer, error) { + contract, err := bindFeeQuoter(address, nil, nil, filterer) if err != nil { return nil, err } - return &PriceRegistryFilterer{contract: contract}, nil + return &FeeQuoterFilterer{contract: contract}, nil } -func bindPriceRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := PriceRegistryMetaData.GetAbi() +func bindFeeQuoter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := FeeQuoterMetaData.GetAbi() if err != nil { return nil, err } return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } -func (_PriceRegistry *PriceRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _PriceRegistry.Contract.PriceRegistryCaller.contract.Call(opts, result, method, params...) +func (_FeeQuoter *FeeQuoterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _FeeQuoter.Contract.FeeQuoterCaller.contract.Call(opts, result, method, params...) } -func (_PriceRegistry *PriceRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _PriceRegistry.Contract.PriceRegistryTransactor.contract.Transfer(opts) +func (_FeeQuoter *FeeQuoterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FeeQuoter.Contract.FeeQuoterTransactor.contract.Transfer(opts) } -func (_PriceRegistry *PriceRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _PriceRegistry.Contract.PriceRegistryTransactor.contract.Transact(opts, method, params...) +func (_FeeQuoter *FeeQuoterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _FeeQuoter.Contract.FeeQuoterTransactor.contract.Transact(opts, method, params...) } -func (_PriceRegistry *PriceRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _PriceRegistry.Contract.contract.Call(opts, result, method, params...) +func (_FeeQuoter *FeeQuoterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _FeeQuoter.Contract.contract.Call(opts, result, method, params...) } -func (_PriceRegistry *PriceRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _PriceRegistry.Contract.contract.Transfer(opts) +func (_FeeQuoter *FeeQuoterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FeeQuoter.Contract.contract.Transfer(opts) } -func (_PriceRegistry *PriceRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _PriceRegistry.Contract.contract.Transact(opts, method, params...) +func (_FeeQuoter *FeeQuoterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _FeeQuoter.Contract.contract.Transact(opts, method, params...) } -func (_PriceRegistry *PriceRegistryCaller) ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { +func (_FeeQuoter *FeeQuoterCaller) ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "convertTokenAmount", fromToken, fromTokenAmount, toToken) + err := _FeeQuoter.contract.Call(opts, &out, "convertTokenAmount", fromToken, fromTokenAmount, toToken) if err != nil { return *new(*big.Int), err @@ -308,17 +308,17 @@ func (_PriceRegistry *PriceRegistryCaller) ConvertTokenAmount(opts *bind.CallOpt } -func (_PriceRegistry *PriceRegistrySession) ConvertTokenAmount(fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { - return _PriceRegistry.Contract.ConvertTokenAmount(&_PriceRegistry.CallOpts, fromToken, fromTokenAmount, toToken) +func (_FeeQuoter *FeeQuoterSession) ConvertTokenAmount(fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + return _FeeQuoter.Contract.ConvertTokenAmount(&_FeeQuoter.CallOpts, fromToken, fromTokenAmount, toToken) } -func (_PriceRegistry *PriceRegistryCallerSession) ConvertTokenAmount(fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { - return _PriceRegistry.Contract.ConvertTokenAmount(&_PriceRegistry.CallOpts, fromToken, fromTokenAmount, toToken) +func (_FeeQuoter *FeeQuoterCallerSession) ConvertTokenAmount(fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + return _FeeQuoter.Contract.ConvertTokenAmount(&_FeeQuoter.CallOpts, fromToken, fromTokenAmount, toToken) } -func (_PriceRegistry *PriceRegistryCaller) GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) { +func (_FeeQuoter *FeeQuoterCaller) GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getAllAuthorizedCallers") + err := _FeeQuoter.contract.Call(opts, &out, "getAllAuthorizedCallers") if err != nil { return *new([]common.Address), err @@ -330,39 +330,39 @@ func (_PriceRegistry *PriceRegistryCaller) GetAllAuthorizedCallers(opts *bind.Ca } -func (_PriceRegistry *PriceRegistrySession) GetAllAuthorizedCallers() ([]common.Address, error) { - return _PriceRegistry.Contract.GetAllAuthorizedCallers(&_PriceRegistry.CallOpts) +func (_FeeQuoter *FeeQuoterSession) GetAllAuthorizedCallers() ([]common.Address, error) { + return _FeeQuoter.Contract.GetAllAuthorizedCallers(&_FeeQuoter.CallOpts) } -func (_PriceRegistry *PriceRegistryCallerSession) GetAllAuthorizedCallers() ([]common.Address, error) { - return _PriceRegistry.Contract.GetAllAuthorizedCallers(&_PriceRegistry.CallOpts) +func (_FeeQuoter *FeeQuoterCallerSession) GetAllAuthorizedCallers() ([]common.Address, error) { + return _FeeQuoter.Contract.GetAllAuthorizedCallers(&_FeeQuoter.CallOpts) } -func (_PriceRegistry *PriceRegistryCaller) GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (PriceRegistryDestChainConfig, error) { +func (_FeeQuoter *FeeQuoterCaller) GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (FeeQuoterDestChainConfig, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getDestChainConfig", destChainSelector) + err := _FeeQuoter.contract.Call(opts, &out, "getDestChainConfig", destChainSelector) if err != nil { - return *new(PriceRegistryDestChainConfig), err + return *new(FeeQuoterDestChainConfig), err } - out0 := *abi.ConvertType(out[0], new(PriceRegistryDestChainConfig)).(*PriceRegistryDestChainConfig) + out0 := *abi.ConvertType(out[0], new(FeeQuoterDestChainConfig)).(*FeeQuoterDestChainConfig) return out0, err } -func (_PriceRegistry *PriceRegistrySession) GetDestChainConfig(destChainSelector uint64) (PriceRegistryDestChainConfig, error) { - return _PriceRegistry.Contract.GetDestChainConfig(&_PriceRegistry.CallOpts, destChainSelector) +func (_FeeQuoter *FeeQuoterSession) GetDestChainConfig(destChainSelector uint64) (FeeQuoterDestChainConfig, error) { + return _FeeQuoter.Contract.GetDestChainConfig(&_FeeQuoter.CallOpts, destChainSelector) } -func (_PriceRegistry *PriceRegistryCallerSession) GetDestChainConfig(destChainSelector uint64) (PriceRegistryDestChainConfig, error) { - return _PriceRegistry.Contract.GetDestChainConfig(&_PriceRegistry.CallOpts, destChainSelector) +func (_FeeQuoter *FeeQuoterCallerSession) GetDestChainConfig(destChainSelector uint64) (FeeQuoterDestChainConfig, error) { + return _FeeQuoter.Contract.GetDestChainConfig(&_FeeQuoter.CallOpts, destChainSelector) } -func (_PriceRegistry *PriceRegistryCaller) GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (InternalTimestampedPackedUint224, error) { +func (_FeeQuoter *FeeQuoterCaller) GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (InternalTimestampedPackedUint224, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getDestinationChainGasPrice", destChainSelector) + err := _FeeQuoter.contract.Call(opts, &out, "getDestinationChainGasPrice", destChainSelector) if err != nil { return *new(InternalTimestampedPackedUint224), err @@ -374,17 +374,17 @@ func (_PriceRegistry *PriceRegistryCaller) GetDestinationChainGasPrice(opts *bin } -func (_PriceRegistry *PriceRegistrySession) GetDestinationChainGasPrice(destChainSelector uint64) (InternalTimestampedPackedUint224, error) { - return _PriceRegistry.Contract.GetDestinationChainGasPrice(&_PriceRegistry.CallOpts, destChainSelector) +func (_FeeQuoter *FeeQuoterSession) GetDestinationChainGasPrice(destChainSelector uint64) (InternalTimestampedPackedUint224, error) { + return _FeeQuoter.Contract.GetDestinationChainGasPrice(&_FeeQuoter.CallOpts, destChainSelector) } -func (_PriceRegistry *PriceRegistryCallerSession) GetDestinationChainGasPrice(destChainSelector uint64) (InternalTimestampedPackedUint224, error) { - return _PriceRegistry.Contract.GetDestinationChainGasPrice(&_PriceRegistry.CallOpts, destChainSelector) +func (_FeeQuoter *FeeQuoterCallerSession) GetDestinationChainGasPrice(destChainSelector uint64) (InternalTimestampedPackedUint224, error) { + return _FeeQuoter.Contract.GetDestinationChainGasPrice(&_FeeQuoter.CallOpts, destChainSelector) } -func (_PriceRegistry *PriceRegistryCaller) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { +func (_FeeQuoter *FeeQuoterCaller) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getFeeTokens") + err := _FeeQuoter.contract.Call(opts, &out, "getFeeTokens") if err != nil { return *new([]common.Address), err @@ -396,17 +396,17 @@ func (_PriceRegistry *PriceRegistryCaller) GetFeeTokens(opts *bind.CallOpts) ([] } -func (_PriceRegistry *PriceRegistrySession) GetFeeTokens() ([]common.Address, error) { - return _PriceRegistry.Contract.GetFeeTokens(&_PriceRegistry.CallOpts) +func (_FeeQuoter *FeeQuoterSession) GetFeeTokens() ([]common.Address, error) { + return _FeeQuoter.Contract.GetFeeTokens(&_FeeQuoter.CallOpts) } -func (_PriceRegistry *PriceRegistryCallerSession) GetFeeTokens() ([]common.Address, error) { - return _PriceRegistry.Contract.GetFeeTokens(&_PriceRegistry.CallOpts) +func (_FeeQuoter *FeeQuoterCallerSession) GetFeeTokens() ([]common.Address, error) { + return _FeeQuoter.Contract.GetFeeTokens(&_FeeQuoter.CallOpts) } -func (_PriceRegistry *PriceRegistryCaller) GetPremiumMultiplierWeiPerEth(opts *bind.CallOpts, token common.Address) (uint64, error) { +func (_FeeQuoter *FeeQuoterCaller) GetPremiumMultiplierWeiPerEth(opts *bind.CallOpts, token common.Address) (uint64, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getPremiumMultiplierWeiPerEth", token) + err := _FeeQuoter.contract.Call(opts, &out, "getPremiumMultiplierWeiPerEth", token) if err != nil { return *new(uint64), err @@ -418,41 +418,41 @@ func (_PriceRegistry *PriceRegistryCaller) GetPremiumMultiplierWeiPerEth(opts *b } -func (_PriceRegistry *PriceRegistrySession) GetPremiumMultiplierWeiPerEth(token common.Address) (uint64, error) { - return _PriceRegistry.Contract.GetPremiumMultiplierWeiPerEth(&_PriceRegistry.CallOpts, token) +func (_FeeQuoter *FeeQuoterSession) GetPremiumMultiplierWeiPerEth(token common.Address) (uint64, error) { + return _FeeQuoter.Contract.GetPremiumMultiplierWeiPerEth(&_FeeQuoter.CallOpts, token) } -func (_PriceRegistry *PriceRegistryCallerSession) GetPremiumMultiplierWeiPerEth(token common.Address) (uint64, error) { - return _PriceRegistry.Contract.GetPremiumMultiplierWeiPerEth(&_PriceRegistry.CallOpts, token) +func (_FeeQuoter *FeeQuoterCallerSession) GetPremiumMultiplierWeiPerEth(token common.Address) (uint64, error) { + return _FeeQuoter.Contract.GetPremiumMultiplierWeiPerEth(&_FeeQuoter.CallOpts, token) } -func (_PriceRegistry *PriceRegistryCaller) GetStaticConfig(opts *bind.CallOpts) (PriceRegistryStaticConfig, error) { +func (_FeeQuoter *FeeQuoterCaller) GetStaticConfig(opts *bind.CallOpts) (FeeQuoterStaticConfig, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getStaticConfig") + err := _FeeQuoter.contract.Call(opts, &out, "getStaticConfig") if err != nil { - return *new(PriceRegistryStaticConfig), err + return *new(FeeQuoterStaticConfig), err } - out0 := *abi.ConvertType(out[0], new(PriceRegistryStaticConfig)).(*PriceRegistryStaticConfig) + out0 := *abi.ConvertType(out[0], new(FeeQuoterStaticConfig)).(*FeeQuoterStaticConfig) return out0, err } -func (_PriceRegistry *PriceRegistrySession) GetStaticConfig() (PriceRegistryStaticConfig, error) { - return _PriceRegistry.Contract.GetStaticConfig(&_PriceRegistry.CallOpts) +func (_FeeQuoter *FeeQuoterSession) GetStaticConfig() (FeeQuoterStaticConfig, error) { + return _FeeQuoter.Contract.GetStaticConfig(&_FeeQuoter.CallOpts) } -func (_PriceRegistry *PriceRegistryCallerSession) GetStaticConfig() (PriceRegistryStaticConfig, error) { - return _PriceRegistry.Contract.GetStaticConfig(&_PriceRegistry.CallOpts) +func (_FeeQuoter *FeeQuoterCallerSession) GetStaticConfig() (FeeQuoterStaticConfig, error) { + return _FeeQuoter.Contract.GetStaticConfig(&_FeeQuoter.CallOpts) } -func (_PriceRegistry *PriceRegistryCaller) GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, +func (_FeeQuoter *FeeQuoterCaller) GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getTokenAndGasPrices", token, destChainSelector) + err := _FeeQuoter.contract.Call(opts, &out, "getTokenAndGasPrices", token, destChainSelector) outstruct := new(GetTokenAndGasPrices) if err != nil { @@ -466,21 +466,21 @@ func (_PriceRegistry *PriceRegistryCaller) GetTokenAndGasPrices(opts *bind.CallO } -func (_PriceRegistry *PriceRegistrySession) GetTokenAndGasPrices(token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, +func (_FeeQuoter *FeeQuoterSession) GetTokenAndGasPrices(token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, error) { - return _PriceRegistry.Contract.GetTokenAndGasPrices(&_PriceRegistry.CallOpts, token, destChainSelector) + return _FeeQuoter.Contract.GetTokenAndGasPrices(&_FeeQuoter.CallOpts, token, destChainSelector) } -func (_PriceRegistry *PriceRegistryCallerSession) GetTokenAndGasPrices(token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, +func (_FeeQuoter *FeeQuoterCallerSession) GetTokenAndGasPrices(token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, error) { - return _PriceRegistry.Contract.GetTokenAndGasPrices(&_PriceRegistry.CallOpts, token, destChainSelector) + return _FeeQuoter.Contract.GetTokenAndGasPrices(&_FeeQuoter.CallOpts, token, destChainSelector) } -func (_PriceRegistry *PriceRegistryCaller) GetTokenPrice(opts *bind.CallOpts, token common.Address) (InternalTimestampedPackedUint224, error) { +func (_FeeQuoter *FeeQuoterCaller) GetTokenPrice(opts *bind.CallOpts, token common.Address) (InternalTimestampedPackedUint224, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getTokenPrice", token) + err := _FeeQuoter.contract.Call(opts, &out, "getTokenPrice", token) if err != nil { return *new(InternalTimestampedPackedUint224), err @@ -492,39 +492,39 @@ func (_PriceRegistry *PriceRegistryCaller) GetTokenPrice(opts *bind.CallOpts, to } -func (_PriceRegistry *PriceRegistrySession) GetTokenPrice(token common.Address) (InternalTimestampedPackedUint224, error) { - return _PriceRegistry.Contract.GetTokenPrice(&_PriceRegistry.CallOpts, token) +func (_FeeQuoter *FeeQuoterSession) GetTokenPrice(token common.Address) (InternalTimestampedPackedUint224, error) { + return _FeeQuoter.Contract.GetTokenPrice(&_FeeQuoter.CallOpts, token) } -func (_PriceRegistry *PriceRegistryCallerSession) GetTokenPrice(token common.Address) (InternalTimestampedPackedUint224, error) { - return _PriceRegistry.Contract.GetTokenPrice(&_PriceRegistry.CallOpts, token) +func (_FeeQuoter *FeeQuoterCallerSession) GetTokenPrice(token common.Address) (InternalTimestampedPackedUint224, error) { + return _FeeQuoter.Contract.GetTokenPrice(&_FeeQuoter.CallOpts, token) } -func (_PriceRegistry *PriceRegistryCaller) GetTokenPriceFeedConfig(opts *bind.CallOpts, token common.Address) (IPriceRegistryTokenPriceFeedConfig, error) { +func (_FeeQuoter *FeeQuoterCaller) GetTokenPriceFeedConfig(opts *bind.CallOpts, token common.Address) (IFeeQuoterTokenPriceFeedConfig, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getTokenPriceFeedConfig", token) + err := _FeeQuoter.contract.Call(opts, &out, "getTokenPriceFeedConfig", token) if err != nil { - return *new(IPriceRegistryTokenPriceFeedConfig), err + return *new(IFeeQuoterTokenPriceFeedConfig), err } - out0 := *abi.ConvertType(out[0], new(IPriceRegistryTokenPriceFeedConfig)).(*IPriceRegistryTokenPriceFeedConfig) + out0 := *abi.ConvertType(out[0], new(IFeeQuoterTokenPriceFeedConfig)).(*IFeeQuoterTokenPriceFeedConfig) return out0, err } -func (_PriceRegistry *PriceRegistrySession) GetTokenPriceFeedConfig(token common.Address) (IPriceRegistryTokenPriceFeedConfig, error) { - return _PriceRegistry.Contract.GetTokenPriceFeedConfig(&_PriceRegistry.CallOpts, token) +func (_FeeQuoter *FeeQuoterSession) GetTokenPriceFeedConfig(token common.Address) (IFeeQuoterTokenPriceFeedConfig, error) { + return _FeeQuoter.Contract.GetTokenPriceFeedConfig(&_FeeQuoter.CallOpts, token) } -func (_PriceRegistry *PriceRegistryCallerSession) GetTokenPriceFeedConfig(token common.Address) (IPriceRegistryTokenPriceFeedConfig, error) { - return _PriceRegistry.Contract.GetTokenPriceFeedConfig(&_PriceRegistry.CallOpts, token) +func (_FeeQuoter *FeeQuoterCallerSession) GetTokenPriceFeedConfig(token common.Address) (IFeeQuoterTokenPriceFeedConfig, error) { + return _FeeQuoter.Contract.GetTokenPriceFeedConfig(&_FeeQuoter.CallOpts, token) } -func (_PriceRegistry *PriceRegistryCaller) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]InternalTimestampedPackedUint224, error) { +func (_FeeQuoter *FeeQuoterCaller) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]InternalTimestampedPackedUint224, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getTokenPrices", tokens) + err := _FeeQuoter.contract.Call(opts, &out, "getTokenPrices", tokens) if err != nil { return *new([]InternalTimestampedPackedUint224), err @@ -536,39 +536,39 @@ func (_PriceRegistry *PriceRegistryCaller) GetTokenPrices(opts *bind.CallOpts, t } -func (_PriceRegistry *PriceRegistrySession) GetTokenPrices(tokens []common.Address) ([]InternalTimestampedPackedUint224, error) { - return _PriceRegistry.Contract.GetTokenPrices(&_PriceRegistry.CallOpts, tokens) +func (_FeeQuoter *FeeQuoterSession) GetTokenPrices(tokens []common.Address) ([]InternalTimestampedPackedUint224, error) { + return _FeeQuoter.Contract.GetTokenPrices(&_FeeQuoter.CallOpts, tokens) } -func (_PriceRegistry *PriceRegistryCallerSession) GetTokenPrices(tokens []common.Address) ([]InternalTimestampedPackedUint224, error) { - return _PriceRegistry.Contract.GetTokenPrices(&_PriceRegistry.CallOpts, tokens) +func (_FeeQuoter *FeeQuoterCallerSession) GetTokenPrices(tokens []common.Address) ([]InternalTimestampedPackedUint224, error) { + return _FeeQuoter.Contract.GetTokenPrices(&_FeeQuoter.CallOpts, tokens) } -func (_PriceRegistry *PriceRegistryCaller) GetTokenTransferFeeConfig(opts *bind.CallOpts, destChainSelector uint64, token common.Address) (PriceRegistryTokenTransferFeeConfig, error) { +func (_FeeQuoter *FeeQuoterCaller) GetTokenTransferFeeConfig(opts *bind.CallOpts, destChainSelector uint64, token common.Address) (FeeQuoterTokenTransferFeeConfig, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getTokenTransferFeeConfig", destChainSelector, token) + err := _FeeQuoter.contract.Call(opts, &out, "getTokenTransferFeeConfig", destChainSelector, token) if err != nil { - return *new(PriceRegistryTokenTransferFeeConfig), err + return *new(FeeQuoterTokenTransferFeeConfig), err } - out0 := *abi.ConvertType(out[0], new(PriceRegistryTokenTransferFeeConfig)).(*PriceRegistryTokenTransferFeeConfig) + out0 := *abi.ConvertType(out[0], new(FeeQuoterTokenTransferFeeConfig)).(*FeeQuoterTokenTransferFeeConfig) return out0, err } -func (_PriceRegistry *PriceRegistrySession) GetTokenTransferFeeConfig(destChainSelector uint64, token common.Address) (PriceRegistryTokenTransferFeeConfig, error) { - return _PriceRegistry.Contract.GetTokenTransferFeeConfig(&_PriceRegistry.CallOpts, destChainSelector, token) +func (_FeeQuoter *FeeQuoterSession) GetTokenTransferFeeConfig(destChainSelector uint64, token common.Address) (FeeQuoterTokenTransferFeeConfig, error) { + return _FeeQuoter.Contract.GetTokenTransferFeeConfig(&_FeeQuoter.CallOpts, destChainSelector, token) } -func (_PriceRegistry *PriceRegistryCallerSession) GetTokenTransferFeeConfig(destChainSelector uint64, token common.Address) (PriceRegistryTokenTransferFeeConfig, error) { - return _PriceRegistry.Contract.GetTokenTransferFeeConfig(&_PriceRegistry.CallOpts, destChainSelector, token) +func (_FeeQuoter *FeeQuoterCallerSession) GetTokenTransferFeeConfig(destChainSelector uint64, token common.Address) (FeeQuoterTokenTransferFeeConfig, error) { + return _FeeQuoter.Contract.GetTokenTransferFeeConfig(&_FeeQuoter.CallOpts, destChainSelector, token) } -func (_PriceRegistry *PriceRegistryCaller) GetValidatedFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { +func (_FeeQuoter *FeeQuoterCaller) GetValidatedFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getValidatedFee", destChainSelector, message) + err := _FeeQuoter.contract.Call(opts, &out, "getValidatedFee", destChainSelector, message) if err != nil { return *new(*big.Int), err @@ -580,17 +580,17 @@ func (_PriceRegistry *PriceRegistryCaller) GetValidatedFee(opts *bind.CallOpts, } -func (_PriceRegistry *PriceRegistrySession) GetValidatedFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { - return _PriceRegistry.Contract.GetValidatedFee(&_PriceRegistry.CallOpts, destChainSelector, message) +func (_FeeQuoter *FeeQuoterSession) GetValidatedFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _FeeQuoter.Contract.GetValidatedFee(&_FeeQuoter.CallOpts, destChainSelector, message) } -func (_PriceRegistry *PriceRegistryCallerSession) GetValidatedFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { - return _PriceRegistry.Contract.GetValidatedFee(&_PriceRegistry.CallOpts, destChainSelector, message) +func (_FeeQuoter *FeeQuoterCallerSession) GetValidatedFee(destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) { + return _FeeQuoter.Contract.GetValidatedFee(&_FeeQuoter.CallOpts, destChainSelector, message) } -func (_PriceRegistry *PriceRegistryCaller) GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) { +func (_FeeQuoter *FeeQuoterCaller) GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "getValidatedTokenPrice", token) + err := _FeeQuoter.contract.Call(opts, &out, "getValidatedTokenPrice", token) if err != nil { return *new(*big.Int), err @@ -602,17 +602,17 @@ func (_PriceRegistry *PriceRegistryCaller) GetValidatedTokenPrice(opts *bind.Cal } -func (_PriceRegistry *PriceRegistrySession) GetValidatedTokenPrice(token common.Address) (*big.Int, error) { - return _PriceRegistry.Contract.GetValidatedTokenPrice(&_PriceRegistry.CallOpts, token) +func (_FeeQuoter *FeeQuoterSession) GetValidatedTokenPrice(token common.Address) (*big.Int, error) { + return _FeeQuoter.Contract.GetValidatedTokenPrice(&_FeeQuoter.CallOpts, token) } -func (_PriceRegistry *PriceRegistryCallerSession) GetValidatedTokenPrice(token common.Address) (*big.Int, error) { - return _PriceRegistry.Contract.GetValidatedTokenPrice(&_PriceRegistry.CallOpts, token) +func (_FeeQuoter *FeeQuoterCallerSession) GetValidatedTokenPrice(token common.Address) (*big.Int, error) { + return _FeeQuoter.Contract.GetValidatedTokenPrice(&_FeeQuoter.CallOpts, token) } -func (_PriceRegistry *PriceRegistryCaller) Owner(opts *bind.CallOpts) (common.Address, error) { +func (_FeeQuoter *FeeQuoterCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "owner") + err := _FeeQuoter.contract.Call(opts, &out, "owner") if err != nil { return *new(common.Address), err @@ -624,19 +624,19 @@ func (_PriceRegistry *PriceRegistryCaller) Owner(opts *bind.CallOpts) (common.Ad } -func (_PriceRegistry *PriceRegistrySession) Owner() (common.Address, error) { - return _PriceRegistry.Contract.Owner(&_PriceRegistry.CallOpts) +func (_FeeQuoter *FeeQuoterSession) Owner() (common.Address, error) { + return _FeeQuoter.Contract.Owner(&_FeeQuoter.CallOpts) } -func (_PriceRegistry *PriceRegistryCallerSession) Owner() (common.Address, error) { - return _PriceRegistry.Contract.Owner(&_PriceRegistry.CallOpts) +func (_FeeQuoter *FeeQuoterCallerSession) Owner() (common.Address, error) { + return _FeeQuoter.Contract.Owner(&_FeeQuoter.CallOpts) } -func (_PriceRegistry *PriceRegistryCaller) ProcessMessageArgs(opts *bind.CallOpts, destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (ProcessMessageArgs, +func (_FeeQuoter *FeeQuoterCaller) ProcessMessageArgs(opts *bind.CallOpts, destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (ProcessMessageArgs, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "processMessageArgs", destChainSelector, feeToken, feeTokenAmount, extraArgs) + err := _FeeQuoter.contract.Call(opts, &out, "processMessageArgs", destChainSelector, feeToken, feeTokenAmount, extraArgs) outstruct := new(ProcessMessageArgs) if err != nil { @@ -651,21 +651,21 @@ func (_PriceRegistry *PriceRegistryCaller) ProcessMessageArgs(opts *bind.CallOpt } -func (_PriceRegistry *PriceRegistrySession) ProcessMessageArgs(destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (ProcessMessageArgs, +func (_FeeQuoter *FeeQuoterSession) ProcessMessageArgs(destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (ProcessMessageArgs, error) { - return _PriceRegistry.Contract.ProcessMessageArgs(&_PriceRegistry.CallOpts, destChainSelector, feeToken, feeTokenAmount, extraArgs) + return _FeeQuoter.Contract.ProcessMessageArgs(&_FeeQuoter.CallOpts, destChainSelector, feeToken, feeTokenAmount, extraArgs) } -func (_PriceRegistry *PriceRegistryCallerSession) ProcessMessageArgs(destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (ProcessMessageArgs, +func (_FeeQuoter *FeeQuoterCallerSession) ProcessMessageArgs(destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (ProcessMessageArgs, error) { - return _PriceRegistry.Contract.ProcessMessageArgs(&_PriceRegistry.CallOpts, destChainSelector, feeToken, feeTokenAmount, extraArgs) + return _FeeQuoter.Contract.ProcessMessageArgs(&_FeeQuoter.CallOpts, destChainSelector, feeToken, feeTokenAmount, extraArgs) } -func (_PriceRegistry *PriceRegistryCaller) ProcessPoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) ([][]byte, error) { +func (_FeeQuoter *FeeQuoterCaller) ProcessPoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) ([][]byte, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "processPoolReturnData", destChainSelector, rampTokenAmounts, sourceTokenAmounts) + err := _FeeQuoter.contract.Call(opts, &out, "processPoolReturnData", destChainSelector, rampTokenAmounts, sourceTokenAmounts) if err != nil { return *new([][]byte), err @@ -677,17 +677,17 @@ func (_PriceRegistry *PriceRegistryCaller) ProcessPoolReturnData(opts *bind.Call } -func (_PriceRegistry *PriceRegistrySession) ProcessPoolReturnData(destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) ([][]byte, error) { - return _PriceRegistry.Contract.ProcessPoolReturnData(&_PriceRegistry.CallOpts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) +func (_FeeQuoter *FeeQuoterSession) ProcessPoolReturnData(destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) ([][]byte, error) { + return _FeeQuoter.Contract.ProcessPoolReturnData(&_FeeQuoter.CallOpts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) } -func (_PriceRegistry *PriceRegistryCallerSession) ProcessPoolReturnData(destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) ([][]byte, error) { - return _PriceRegistry.Contract.ProcessPoolReturnData(&_PriceRegistry.CallOpts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) +func (_FeeQuoter *FeeQuoterCallerSession) ProcessPoolReturnData(destChainSelector uint64, rampTokenAmounts []InternalRampTokenAmount, sourceTokenAmounts []ClientEVMTokenAmount) ([][]byte, error) { + return _FeeQuoter.Contract.ProcessPoolReturnData(&_FeeQuoter.CallOpts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) } -func (_PriceRegistry *PriceRegistryCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { +func (_FeeQuoter *FeeQuoterCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { var out []interface{} - err := _PriceRegistry.contract.Call(opts, &out, "typeAndVersion") + err := _FeeQuoter.contract.Call(opts, &out, "typeAndVersion") if err != nil { return *new(string), err @@ -699,148 +699,148 @@ func (_PriceRegistry *PriceRegistryCaller) TypeAndVersion(opts *bind.CallOpts) ( } -func (_PriceRegistry *PriceRegistrySession) TypeAndVersion() (string, error) { - return _PriceRegistry.Contract.TypeAndVersion(&_PriceRegistry.CallOpts) +func (_FeeQuoter *FeeQuoterSession) TypeAndVersion() (string, error) { + return _FeeQuoter.Contract.TypeAndVersion(&_FeeQuoter.CallOpts) } -func (_PriceRegistry *PriceRegistryCallerSession) TypeAndVersion() (string, error) { - return _PriceRegistry.Contract.TypeAndVersion(&_PriceRegistry.CallOpts) +func (_FeeQuoter *FeeQuoterCallerSession) TypeAndVersion() (string, error) { + return _FeeQuoter.Contract.TypeAndVersion(&_FeeQuoter.CallOpts) } -func (_PriceRegistry *PriceRegistryTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _PriceRegistry.contract.Transact(opts, "acceptOwnership") +func (_FeeQuoter *FeeQuoterTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FeeQuoter.contract.Transact(opts, "acceptOwnership") } -func (_PriceRegistry *PriceRegistrySession) AcceptOwnership() (*types.Transaction, error) { - return _PriceRegistry.Contract.AcceptOwnership(&_PriceRegistry.TransactOpts) +func (_FeeQuoter *FeeQuoterSession) AcceptOwnership() (*types.Transaction, error) { + return _FeeQuoter.Contract.AcceptOwnership(&_FeeQuoter.TransactOpts) } -func (_PriceRegistry *PriceRegistryTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _PriceRegistry.Contract.AcceptOwnership(&_PriceRegistry.TransactOpts) +func (_FeeQuoter *FeeQuoterTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _FeeQuoter.Contract.AcceptOwnership(&_FeeQuoter.TransactOpts) } -func (_PriceRegistry *PriceRegistryTransactor) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { - return _PriceRegistry.contract.Transact(opts, "applyAuthorizedCallerUpdates", authorizedCallerArgs) +func (_FeeQuoter *FeeQuoterTransactor) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _FeeQuoter.contract.Transact(opts, "applyAuthorizedCallerUpdates", authorizedCallerArgs) } -func (_PriceRegistry *PriceRegistrySession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { - return _PriceRegistry.Contract.ApplyAuthorizedCallerUpdates(&_PriceRegistry.TransactOpts, authorizedCallerArgs) +func (_FeeQuoter *FeeQuoterSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _FeeQuoter.Contract.ApplyAuthorizedCallerUpdates(&_FeeQuoter.TransactOpts, authorizedCallerArgs) } -func (_PriceRegistry *PriceRegistryTransactorSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { - return _PriceRegistry.Contract.ApplyAuthorizedCallerUpdates(&_PriceRegistry.TransactOpts, authorizedCallerArgs) +func (_FeeQuoter *FeeQuoterTransactorSession) ApplyAuthorizedCallerUpdates(authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + return _FeeQuoter.Contract.ApplyAuthorizedCallerUpdates(&_FeeQuoter.TransactOpts, authorizedCallerArgs) } -func (_PriceRegistry *PriceRegistryTransactor) ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []PriceRegistryDestChainConfigArgs) (*types.Transaction, error) { - return _PriceRegistry.contract.Transact(opts, "applyDestChainConfigUpdates", destChainConfigArgs) +func (_FeeQuoter *FeeQuoterTransactor) ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []FeeQuoterDestChainConfigArgs) (*types.Transaction, error) { + return _FeeQuoter.contract.Transact(opts, "applyDestChainConfigUpdates", destChainConfigArgs) } -func (_PriceRegistry *PriceRegistrySession) ApplyDestChainConfigUpdates(destChainConfigArgs []PriceRegistryDestChainConfigArgs) (*types.Transaction, error) { - return _PriceRegistry.Contract.ApplyDestChainConfigUpdates(&_PriceRegistry.TransactOpts, destChainConfigArgs) +func (_FeeQuoter *FeeQuoterSession) ApplyDestChainConfigUpdates(destChainConfigArgs []FeeQuoterDestChainConfigArgs) (*types.Transaction, error) { + return _FeeQuoter.Contract.ApplyDestChainConfigUpdates(&_FeeQuoter.TransactOpts, destChainConfigArgs) } -func (_PriceRegistry *PriceRegistryTransactorSession) ApplyDestChainConfigUpdates(destChainConfigArgs []PriceRegistryDestChainConfigArgs) (*types.Transaction, error) { - return _PriceRegistry.Contract.ApplyDestChainConfigUpdates(&_PriceRegistry.TransactOpts, destChainConfigArgs) +func (_FeeQuoter *FeeQuoterTransactorSession) ApplyDestChainConfigUpdates(destChainConfigArgs []FeeQuoterDestChainConfigArgs) (*types.Transaction, error) { + return _FeeQuoter.Contract.ApplyDestChainConfigUpdates(&_FeeQuoter.TransactOpts, destChainConfigArgs) } -func (_PriceRegistry *PriceRegistryTransactor) ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { - return _PriceRegistry.contract.Transact(opts, "applyFeeTokensUpdates", feeTokensToAdd, feeTokensToRemove) +func (_FeeQuoter *FeeQuoterTransactor) ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _FeeQuoter.contract.Transact(opts, "applyFeeTokensUpdates", feeTokensToAdd, feeTokensToRemove) } -func (_PriceRegistry *PriceRegistrySession) ApplyFeeTokensUpdates(feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { - return _PriceRegistry.Contract.ApplyFeeTokensUpdates(&_PriceRegistry.TransactOpts, feeTokensToAdd, feeTokensToRemove) +func (_FeeQuoter *FeeQuoterSession) ApplyFeeTokensUpdates(feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _FeeQuoter.Contract.ApplyFeeTokensUpdates(&_FeeQuoter.TransactOpts, feeTokensToAdd, feeTokensToRemove) } -func (_PriceRegistry *PriceRegistryTransactorSession) ApplyFeeTokensUpdates(feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { - return _PriceRegistry.Contract.ApplyFeeTokensUpdates(&_PriceRegistry.TransactOpts, feeTokensToAdd, feeTokensToRemove) +func (_FeeQuoter *FeeQuoterTransactorSession) ApplyFeeTokensUpdates(feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _FeeQuoter.Contract.ApplyFeeTokensUpdates(&_FeeQuoter.TransactOpts, feeTokensToAdd, feeTokensToRemove) } -func (_PriceRegistry *PriceRegistryTransactor) ApplyPremiumMultiplierWeiPerEthUpdates(opts *bind.TransactOpts, premiumMultiplierWeiPerEthArgs []PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) { - return _PriceRegistry.contract.Transact(opts, "applyPremiumMultiplierWeiPerEthUpdates", premiumMultiplierWeiPerEthArgs) +func (_FeeQuoter *FeeQuoterTransactor) ApplyPremiumMultiplierWeiPerEthUpdates(opts *bind.TransactOpts, premiumMultiplierWeiPerEthArgs []FeeQuoterPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) { + return _FeeQuoter.contract.Transact(opts, "applyPremiumMultiplierWeiPerEthUpdates", premiumMultiplierWeiPerEthArgs) } -func (_PriceRegistry *PriceRegistrySession) ApplyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs []PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) { - return _PriceRegistry.Contract.ApplyPremiumMultiplierWeiPerEthUpdates(&_PriceRegistry.TransactOpts, premiumMultiplierWeiPerEthArgs) +func (_FeeQuoter *FeeQuoterSession) ApplyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs []FeeQuoterPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) { + return _FeeQuoter.Contract.ApplyPremiumMultiplierWeiPerEthUpdates(&_FeeQuoter.TransactOpts, premiumMultiplierWeiPerEthArgs) } -func (_PriceRegistry *PriceRegistryTransactorSession) ApplyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs []PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) { - return _PriceRegistry.Contract.ApplyPremiumMultiplierWeiPerEthUpdates(&_PriceRegistry.TransactOpts, premiumMultiplierWeiPerEthArgs) +func (_FeeQuoter *FeeQuoterTransactorSession) ApplyPremiumMultiplierWeiPerEthUpdates(premiumMultiplierWeiPerEthArgs []FeeQuoterPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) { + return _FeeQuoter.Contract.ApplyPremiumMultiplierWeiPerEthUpdates(&_FeeQuoter.TransactOpts, premiumMultiplierWeiPerEthArgs) } -func (_PriceRegistry *PriceRegistryTransactor) ApplyTokenTransferFeeConfigUpdates(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) { - return _PriceRegistry.contract.Transact(opts, "applyTokenTransferFeeConfigUpdates", tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) +func (_FeeQuoter *FeeQuoterTransactor) ApplyTokenTransferFeeConfigUpdates(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []FeeQuoterTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []FeeQuoterTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) { + return _FeeQuoter.contract.Transact(opts, "applyTokenTransferFeeConfigUpdates", tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) } -func (_PriceRegistry *PriceRegistrySession) ApplyTokenTransferFeeConfigUpdates(tokenTransferFeeConfigArgs []PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) { - return _PriceRegistry.Contract.ApplyTokenTransferFeeConfigUpdates(&_PriceRegistry.TransactOpts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) +func (_FeeQuoter *FeeQuoterSession) ApplyTokenTransferFeeConfigUpdates(tokenTransferFeeConfigArgs []FeeQuoterTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []FeeQuoterTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) { + return _FeeQuoter.Contract.ApplyTokenTransferFeeConfigUpdates(&_FeeQuoter.TransactOpts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) } -func (_PriceRegistry *PriceRegistryTransactorSession) ApplyTokenTransferFeeConfigUpdates(tokenTransferFeeConfigArgs []PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) { - return _PriceRegistry.Contract.ApplyTokenTransferFeeConfigUpdates(&_PriceRegistry.TransactOpts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) +func (_FeeQuoter *FeeQuoterTransactorSession) ApplyTokenTransferFeeConfigUpdates(tokenTransferFeeConfigArgs []FeeQuoterTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []FeeQuoterTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) { + return _FeeQuoter.Contract.ApplyTokenTransferFeeConfigUpdates(&_FeeQuoter.TransactOpts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) } -func (_PriceRegistry *PriceRegistryTransactor) OnReport(opts *bind.TransactOpts, metadata []byte, report []byte) (*types.Transaction, error) { - return _PriceRegistry.contract.Transact(opts, "onReport", metadata, report) +func (_FeeQuoter *FeeQuoterTransactor) OnReport(opts *bind.TransactOpts, metadata []byte, report []byte) (*types.Transaction, error) { + return _FeeQuoter.contract.Transact(opts, "onReport", metadata, report) } -func (_PriceRegistry *PriceRegistrySession) OnReport(metadata []byte, report []byte) (*types.Transaction, error) { - return _PriceRegistry.Contract.OnReport(&_PriceRegistry.TransactOpts, metadata, report) +func (_FeeQuoter *FeeQuoterSession) OnReport(metadata []byte, report []byte) (*types.Transaction, error) { + return _FeeQuoter.Contract.OnReport(&_FeeQuoter.TransactOpts, metadata, report) } -func (_PriceRegistry *PriceRegistryTransactorSession) OnReport(metadata []byte, report []byte) (*types.Transaction, error) { - return _PriceRegistry.Contract.OnReport(&_PriceRegistry.TransactOpts, metadata, report) +func (_FeeQuoter *FeeQuoterTransactorSession) OnReport(metadata []byte, report []byte) (*types.Transaction, error) { + return _FeeQuoter.Contract.OnReport(&_FeeQuoter.TransactOpts, metadata, report) } -func (_PriceRegistry *PriceRegistryTransactor) SetReportPermissions(opts *bind.TransactOpts, permissions []KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { - return _PriceRegistry.contract.Transact(opts, "setReportPermissions", permissions) +func (_FeeQuoter *FeeQuoterTransactor) SetReportPermissions(opts *bind.TransactOpts, permissions []KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { + return _FeeQuoter.contract.Transact(opts, "setReportPermissions", permissions) } -func (_PriceRegistry *PriceRegistrySession) SetReportPermissions(permissions []KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { - return _PriceRegistry.Contract.SetReportPermissions(&_PriceRegistry.TransactOpts, permissions) +func (_FeeQuoter *FeeQuoterSession) SetReportPermissions(permissions []KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { + return _FeeQuoter.Contract.SetReportPermissions(&_FeeQuoter.TransactOpts, permissions) } -func (_PriceRegistry *PriceRegistryTransactorSession) SetReportPermissions(permissions []KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { - return _PriceRegistry.Contract.SetReportPermissions(&_PriceRegistry.TransactOpts, permissions) +func (_FeeQuoter *FeeQuoterTransactorSession) SetReportPermissions(permissions []KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { + return _FeeQuoter.Contract.SetReportPermissions(&_FeeQuoter.TransactOpts, permissions) } -func (_PriceRegistry *PriceRegistryTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _PriceRegistry.contract.Transact(opts, "transferOwnership", to) +func (_FeeQuoter *FeeQuoterTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _FeeQuoter.contract.Transact(opts, "transferOwnership", to) } -func (_PriceRegistry *PriceRegistrySession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _PriceRegistry.Contract.TransferOwnership(&_PriceRegistry.TransactOpts, to) +func (_FeeQuoter *FeeQuoterSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _FeeQuoter.Contract.TransferOwnership(&_FeeQuoter.TransactOpts, to) } -func (_PriceRegistry *PriceRegistryTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _PriceRegistry.Contract.TransferOwnership(&_PriceRegistry.TransactOpts, to) +func (_FeeQuoter *FeeQuoterTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _FeeQuoter.Contract.TransferOwnership(&_FeeQuoter.TransactOpts, to) } -func (_PriceRegistry *PriceRegistryTransactor) UpdatePrices(opts *bind.TransactOpts, priceUpdates InternalPriceUpdates) (*types.Transaction, error) { - return _PriceRegistry.contract.Transact(opts, "updatePrices", priceUpdates) +func (_FeeQuoter *FeeQuoterTransactor) UpdatePrices(opts *bind.TransactOpts, priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _FeeQuoter.contract.Transact(opts, "updatePrices", priceUpdates) } -func (_PriceRegistry *PriceRegistrySession) UpdatePrices(priceUpdates InternalPriceUpdates) (*types.Transaction, error) { - return _PriceRegistry.Contract.UpdatePrices(&_PriceRegistry.TransactOpts, priceUpdates) +func (_FeeQuoter *FeeQuoterSession) UpdatePrices(priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _FeeQuoter.Contract.UpdatePrices(&_FeeQuoter.TransactOpts, priceUpdates) } -func (_PriceRegistry *PriceRegistryTransactorSession) UpdatePrices(priceUpdates InternalPriceUpdates) (*types.Transaction, error) { - return _PriceRegistry.Contract.UpdatePrices(&_PriceRegistry.TransactOpts, priceUpdates) +func (_FeeQuoter *FeeQuoterTransactorSession) UpdatePrices(priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _FeeQuoter.Contract.UpdatePrices(&_FeeQuoter.TransactOpts, priceUpdates) } -func (_PriceRegistry *PriceRegistryTransactor) UpdateTokenPriceFeeds(opts *bind.TransactOpts, tokenPriceFeedUpdates []PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error) { - return _PriceRegistry.contract.Transact(opts, "updateTokenPriceFeeds", tokenPriceFeedUpdates) +func (_FeeQuoter *FeeQuoterTransactor) UpdateTokenPriceFeeds(opts *bind.TransactOpts, tokenPriceFeedUpdates []FeeQuoterTokenPriceFeedUpdate) (*types.Transaction, error) { + return _FeeQuoter.contract.Transact(opts, "updateTokenPriceFeeds", tokenPriceFeedUpdates) } -func (_PriceRegistry *PriceRegistrySession) UpdateTokenPriceFeeds(tokenPriceFeedUpdates []PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error) { - return _PriceRegistry.Contract.UpdateTokenPriceFeeds(&_PriceRegistry.TransactOpts, tokenPriceFeedUpdates) +func (_FeeQuoter *FeeQuoterSession) UpdateTokenPriceFeeds(tokenPriceFeedUpdates []FeeQuoterTokenPriceFeedUpdate) (*types.Transaction, error) { + return _FeeQuoter.Contract.UpdateTokenPriceFeeds(&_FeeQuoter.TransactOpts, tokenPriceFeedUpdates) } -func (_PriceRegistry *PriceRegistryTransactorSession) UpdateTokenPriceFeeds(tokenPriceFeedUpdates []PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error) { - return _PriceRegistry.Contract.UpdateTokenPriceFeeds(&_PriceRegistry.TransactOpts, tokenPriceFeedUpdates) +func (_FeeQuoter *FeeQuoterTransactorSession) UpdateTokenPriceFeeds(tokenPriceFeedUpdates []FeeQuoterTokenPriceFeedUpdate) (*types.Transaction, error) { + return _FeeQuoter.Contract.UpdateTokenPriceFeeds(&_FeeQuoter.TransactOpts, tokenPriceFeedUpdates) } -type PriceRegistryAuthorizedCallerAddedIterator struct { - Event *PriceRegistryAuthorizedCallerAdded +type FeeQuoterAuthorizedCallerAddedIterator struct { + Event *FeeQuoterAuthorizedCallerAdded contract *bind.BoundContract event string @@ -851,7 +851,7 @@ type PriceRegistryAuthorizedCallerAddedIterator struct { fail error } -func (it *PriceRegistryAuthorizedCallerAddedIterator) Next() bool { +func (it *FeeQuoterAuthorizedCallerAddedIterator) Next() bool { if it.fail != nil { return false @@ -860,7 +860,7 @@ func (it *PriceRegistryAuthorizedCallerAddedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryAuthorizedCallerAdded) + it.Event = new(FeeQuoterAuthorizedCallerAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -875,7 +875,7 @@ func (it *PriceRegistryAuthorizedCallerAddedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryAuthorizedCallerAdded) + it.Event = new(FeeQuoterAuthorizedCallerAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -890,32 +890,32 @@ func (it *PriceRegistryAuthorizedCallerAddedIterator) Next() bool { } } -func (it *PriceRegistryAuthorizedCallerAddedIterator) Error() error { +func (it *FeeQuoterAuthorizedCallerAddedIterator) Error() error { return it.fail } -func (it *PriceRegistryAuthorizedCallerAddedIterator) Close() error { +func (it *FeeQuoterAuthorizedCallerAddedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryAuthorizedCallerAdded struct { +type FeeQuoterAuthorizedCallerAdded struct { Caller common.Address Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*PriceRegistryAuthorizedCallerAddedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*FeeQuoterAuthorizedCallerAddedIterator, error) { - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "AuthorizedCallerAdded") + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "AuthorizedCallerAdded") if err != nil { return nil, err } - return &PriceRegistryAuthorizedCallerAddedIterator{contract: _PriceRegistry.contract, event: "AuthorizedCallerAdded", logs: logs, sub: sub}, nil + return &FeeQuoterAuthorizedCallerAddedIterator{contract: _FeeQuoter.contract, event: "AuthorizedCallerAdded", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryAuthorizedCallerAdded) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *FeeQuoterAuthorizedCallerAdded) (event.Subscription, error) { - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "AuthorizedCallerAdded") + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "AuthorizedCallerAdded") if err != nil { return nil, err } @@ -925,8 +925,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchAuthorizedCallerAdded(opts *bi select { case log := <-logs: - event := new(PriceRegistryAuthorizedCallerAdded) - if err := _PriceRegistry.contract.UnpackLog(event, "AuthorizedCallerAdded", log); err != nil { + event := new(FeeQuoterAuthorizedCallerAdded) + if err := _FeeQuoter.contract.UnpackLog(event, "AuthorizedCallerAdded", log); err != nil { return err } event.Raw = log @@ -947,17 +947,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchAuthorizedCallerAdded(opts *bi }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseAuthorizedCallerAdded(log types.Log) (*PriceRegistryAuthorizedCallerAdded, error) { - event := new(PriceRegistryAuthorizedCallerAdded) - if err := _PriceRegistry.contract.UnpackLog(event, "AuthorizedCallerAdded", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseAuthorizedCallerAdded(log types.Log) (*FeeQuoterAuthorizedCallerAdded, error) { + event := new(FeeQuoterAuthorizedCallerAdded) + if err := _FeeQuoter.contract.UnpackLog(event, "AuthorizedCallerAdded", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryAuthorizedCallerRemovedIterator struct { - Event *PriceRegistryAuthorizedCallerRemoved +type FeeQuoterAuthorizedCallerRemovedIterator struct { + Event *FeeQuoterAuthorizedCallerRemoved contract *bind.BoundContract event string @@ -968,7 +968,7 @@ type PriceRegistryAuthorizedCallerRemovedIterator struct { fail error } -func (it *PriceRegistryAuthorizedCallerRemovedIterator) Next() bool { +func (it *FeeQuoterAuthorizedCallerRemovedIterator) Next() bool { if it.fail != nil { return false @@ -977,7 +977,7 @@ func (it *PriceRegistryAuthorizedCallerRemovedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryAuthorizedCallerRemoved) + it.Event = new(FeeQuoterAuthorizedCallerRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -992,7 +992,7 @@ func (it *PriceRegistryAuthorizedCallerRemovedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryAuthorizedCallerRemoved) + it.Event = new(FeeQuoterAuthorizedCallerRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1007,32 +1007,32 @@ func (it *PriceRegistryAuthorizedCallerRemovedIterator) Next() bool { } } -func (it *PriceRegistryAuthorizedCallerRemovedIterator) Error() error { +func (it *FeeQuoterAuthorizedCallerRemovedIterator) Error() error { return it.fail } -func (it *PriceRegistryAuthorizedCallerRemovedIterator) Close() error { +func (it *FeeQuoterAuthorizedCallerRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryAuthorizedCallerRemoved struct { +type FeeQuoterAuthorizedCallerRemoved struct { Caller common.Address Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*PriceRegistryAuthorizedCallerRemovedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*FeeQuoterAuthorizedCallerRemovedIterator, error) { - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "AuthorizedCallerRemoved") + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "AuthorizedCallerRemoved") if err != nil { return nil, err } - return &PriceRegistryAuthorizedCallerRemovedIterator{contract: _PriceRegistry.contract, event: "AuthorizedCallerRemoved", logs: logs, sub: sub}, nil + return &FeeQuoterAuthorizedCallerRemovedIterator{contract: _FeeQuoter.contract, event: "AuthorizedCallerRemoved", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryAuthorizedCallerRemoved) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *FeeQuoterAuthorizedCallerRemoved) (event.Subscription, error) { - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "AuthorizedCallerRemoved") + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "AuthorizedCallerRemoved") if err != nil { return nil, err } @@ -1042,8 +1042,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchAuthorizedCallerRemoved(opts * select { case log := <-logs: - event := new(PriceRegistryAuthorizedCallerRemoved) - if err := _PriceRegistry.contract.UnpackLog(event, "AuthorizedCallerRemoved", log); err != nil { + event := new(FeeQuoterAuthorizedCallerRemoved) + if err := _FeeQuoter.contract.UnpackLog(event, "AuthorizedCallerRemoved", log); err != nil { return err } event.Raw = log @@ -1064,17 +1064,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchAuthorizedCallerRemoved(opts * }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseAuthorizedCallerRemoved(log types.Log) (*PriceRegistryAuthorizedCallerRemoved, error) { - event := new(PriceRegistryAuthorizedCallerRemoved) - if err := _PriceRegistry.contract.UnpackLog(event, "AuthorizedCallerRemoved", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseAuthorizedCallerRemoved(log types.Log) (*FeeQuoterAuthorizedCallerRemoved, error) { + event := new(FeeQuoterAuthorizedCallerRemoved) + if err := _FeeQuoter.contract.UnpackLog(event, "AuthorizedCallerRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryDestChainAddedIterator struct { - Event *PriceRegistryDestChainAdded +type FeeQuoterDestChainAddedIterator struct { + Event *FeeQuoterDestChainAdded contract *bind.BoundContract event string @@ -1085,7 +1085,7 @@ type PriceRegistryDestChainAddedIterator struct { fail error } -func (it *PriceRegistryDestChainAddedIterator) Next() bool { +func (it *FeeQuoterDestChainAddedIterator) Next() bool { if it.fail != nil { return false @@ -1094,7 +1094,7 @@ func (it *PriceRegistryDestChainAddedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryDestChainAdded) + it.Event = new(FeeQuoterDestChainAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1109,7 +1109,7 @@ func (it *PriceRegistryDestChainAddedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryDestChainAdded) + it.Event = new(FeeQuoterDestChainAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1124,43 +1124,43 @@ func (it *PriceRegistryDestChainAddedIterator) Next() bool { } } -func (it *PriceRegistryDestChainAddedIterator) Error() error { +func (it *FeeQuoterDestChainAddedIterator) Error() error { return it.fail } -func (it *PriceRegistryDestChainAddedIterator) Close() error { +func (it *FeeQuoterDestChainAddedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryDestChainAdded struct { +type FeeQuoterDestChainAdded struct { DestChainSelector uint64 - DestChainConfig PriceRegistryDestChainConfig + DestChainConfig FeeQuoterDestChainConfig Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterDestChainAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*PriceRegistryDestChainAddedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterDestChainAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*FeeQuoterDestChainAddedIterator, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "DestChainAdded", destChainSelectorRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "DestChainAdded", destChainSelectorRule) if err != nil { return nil, err } - return &PriceRegistryDestChainAddedIterator{contract: _PriceRegistry.contract, event: "DestChainAdded", logs: logs, sub: sub}, nil + return &FeeQuoterDestChainAddedIterator{contract: _FeeQuoter.contract, event: "DestChainAdded", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchDestChainAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryDestChainAdded, destChainSelector []uint64) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchDestChainAdded(opts *bind.WatchOpts, sink chan<- *FeeQuoterDestChainAdded, destChainSelector []uint64) (event.Subscription, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "DestChainAdded", destChainSelectorRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "DestChainAdded", destChainSelectorRule) if err != nil { return nil, err } @@ -1170,8 +1170,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchDestChainAdded(opts *bind.Watc select { case log := <-logs: - event := new(PriceRegistryDestChainAdded) - if err := _PriceRegistry.contract.UnpackLog(event, "DestChainAdded", log); err != nil { + event := new(FeeQuoterDestChainAdded) + if err := _FeeQuoter.contract.UnpackLog(event, "DestChainAdded", log); err != nil { return err } event.Raw = log @@ -1192,17 +1192,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchDestChainAdded(opts *bind.Watc }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseDestChainAdded(log types.Log) (*PriceRegistryDestChainAdded, error) { - event := new(PriceRegistryDestChainAdded) - if err := _PriceRegistry.contract.UnpackLog(event, "DestChainAdded", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseDestChainAdded(log types.Log) (*FeeQuoterDestChainAdded, error) { + event := new(FeeQuoterDestChainAdded) + if err := _FeeQuoter.contract.UnpackLog(event, "DestChainAdded", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryDestChainConfigUpdatedIterator struct { - Event *PriceRegistryDestChainConfigUpdated +type FeeQuoterDestChainConfigUpdatedIterator struct { + Event *FeeQuoterDestChainConfigUpdated contract *bind.BoundContract event string @@ -1213,7 +1213,7 @@ type PriceRegistryDestChainConfigUpdatedIterator struct { fail error } -func (it *PriceRegistryDestChainConfigUpdatedIterator) Next() bool { +func (it *FeeQuoterDestChainConfigUpdatedIterator) Next() bool { if it.fail != nil { return false @@ -1222,7 +1222,7 @@ func (it *PriceRegistryDestChainConfigUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryDestChainConfigUpdated) + it.Event = new(FeeQuoterDestChainConfigUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1237,7 +1237,7 @@ func (it *PriceRegistryDestChainConfigUpdatedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryDestChainConfigUpdated) + it.Event = new(FeeQuoterDestChainConfigUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1252,43 +1252,43 @@ func (it *PriceRegistryDestChainConfigUpdatedIterator) Next() bool { } } -func (it *PriceRegistryDestChainConfigUpdatedIterator) Error() error { +func (it *FeeQuoterDestChainConfigUpdatedIterator) Error() error { return it.fail } -func (it *PriceRegistryDestChainConfigUpdatedIterator) Close() error { +func (it *FeeQuoterDestChainConfigUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryDestChainConfigUpdated struct { +type FeeQuoterDestChainConfigUpdated struct { DestChainSelector uint64 - DestChainConfig PriceRegistryDestChainConfig + DestChainConfig FeeQuoterDestChainConfig Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterDestChainConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*PriceRegistryDestChainConfigUpdatedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterDestChainConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*FeeQuoterDestChainConfigUpdatedIterator, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "DestChainConfigUpdated", destChainSelectorRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "DestChainConfigUpdated", destChainSelectorRule) if err != nil { return nil, err } - return &PriceRegistryDestChainConfigUpdatedIterator{contract: _PriceRegistry.contract, event: "DestChainConfigUpdated", logs: logs, sub: sub}, nil + return &FeeQuoterDestChainConfigUpdatedIterator{contract: _FeeQuoter.contract, event: "DestChainConfigUpdated", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchDestChainConfigUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryDestChainConfigUpdated, destChainSelector []uint64) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchDestChainConfigUpdated(opts *bind.WatchOpts, sink chan<- *FeeQuoterDestChainConfigUpdated, destChainSelector []uint64) (event.Subscription, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "DestChainConfigUpdated", destChainSelectorRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "DestChainConfigUpdated", destChainSelectorRule) if err != nil { return nil, err } @@ -1298,8 +1298,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchDestChainConfigUpdated(opts *b select { case log := <-logs: - event := new(PriceRegistryDestChainConfigUpdated) - if err := _PriceRegistry.contract.UnpackLog(event, "DestChainConfigUpdated", log); err != nil { + event := new(FeeQuoterDestChainConfigUpdated) + if err := _FeeQuoter.contract.UnpackLog(event, "DestChainConfigUpdated", log); err != nil { return err } event.Raw = log @@ -1320,17 +1320,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchDestChainConfigUpdated(opts *b }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseDestChainConfigUpdated(log types.Log) (*PriceRegistryDestChainConfigUpdated, error) { - event := new(PriceRegistryDestChainConfigUpdated) - if err := _PriceRegistry.contract.UnpackLog(event, "DestChainConfigUpdated", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseDestChainConfigUpdated(log types.Log) (*FeeQuoterDestChainConfigUpdated, error) { + event := new(FeeQuoterDestChainConfigUpdated) + if err := _FeeQuoter.contract.UnpackLog(event, "DestChainConfigUpdated", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryFeeTokenAddedIterator struct { - Event *PriceRegistryFeeTokenAdded +type FeeQuoterFeeTokenAddedIterator struct { + Event *FeeQuoterFeeTokenAdded contract *bind.BoundContract event string @@ -1341,7 +1341,7 @@ type PriceRegistryFeeTokenAddedIterator struct { fail error } -func (it *PriceRegistryFeeTokenAddedIterator) Next() bool { +func (it *FeeQuoterFeeTokenAddedIterator) Next() bool { if it.fail != nil { return false @@ -1350,7 +1350,7 @@ func (it *PriceRegistryFeeTokenAddedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryFeeTokenAdded) + it.Event = new(FeeQuoterFeeTokenAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1365,7 +1365,7 @@ func (it *PriceRegistryFeeTokenAddedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryFeeTokenAdded) + it.Event = new(FeeQuoterFeeTokenAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1380,42 +1380,42 @@ func (it *PriceRegistryFeeTokenAddedIterator) Next() bool { } } -func (it *PriceRegistryFeeTokenAddedIterator) Error() error { +func (it *FeeQuoterFeeTokenAddedIterator) Error() error { return it.fail } -func (it *PriceRegistryFeeTokenAddedIterator) Close() error { +func (it *FeeQuoterFeeTokenAddedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryFeeTokenAdded struct { +type FeeQuoterFeeTokenAdded struct { FeeToken common.Address Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenAddedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*FeeQuoterFeeTokenAddedIterator, error) { var feeTokenRule []interface{} for _, feeTokenItem := range feeToken { feeTokenRule = append(feeTokenRule, feeTokenItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "FeeTokenAdded", feeTokenRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "FeeTokenAdded", feeTokenRule) if err != nil { return nil, err } - return &PriceRegistryFeeTokenAddedIterator{contract: _PriceRegistry.contract, event: "FeeTokenAdded", logs: logs, sub: sub}, nil + return &FeeQuoterFeeTokenAddedIterator{contract: _FeeQuoter.contract, event: "FeeTokenAdded", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *FeeQuoterFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) { var feeTokenRule []interface{} for _, feeTokenItem := range feeToken { feeTokenRule = append(feeTokenRule, feeTokenItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "FeeTokenAdded", feeTokenRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "FeeTokenAdded", feeTokenRule) if err != nil { return nil, err } @@ -1425,8 +1425,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenAdded(opts *bind.Watch select { case log := <-logs: - event := new(PriceRegistryFeeTokenAdded) - if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenAdded", log); err != nil { + event := new(FeeQuoterFeeTokenAdded) + if err := _FeeQuoter.contract.UnpackLog(event, "FeeTokenAdded", log); err != nil { return err } event.Raw = log @@ -1447,17 +1447,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenAdded(opts *bind.Watch }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseFeeTokenAdded(log types.Log) (*PriceRegistryFeeTokenAdded, error) { - event := new(PriceRegistryFeeTokenAdded) - if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenAdded", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseFeeTokenAdded(log types.Log) (*FeeQuoterFeeTokenAdded, error) { + event := new(FeeQuoterFeeTokenAdded) + if err := _FeeQuoter.contract.UnpackLog(event, "FeeTokenAdded", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryFeeTokenRemovedIterator struct { - Event *PriceRegistryFeeTokenRemoved +type FeeQuoterFeeTokenRemovedIterator struct { + Event *FeeQuoterFeeTokenRemoved contract *bind.BoundContract event string @@ -1468,7 +1468,7 @@ type PriceRegistryFeeTokenRemovedIterator struct { fail error } -func (it *PriceRegistryFeeTokenRemovedIterator) Next() bool { +func (it *FeeQuoterFeeTokenRemovedIterator) Next() bool { if it.fail != nil { return false @@ -1477,7 +1477,7 @@ func (it *PriceRegistryFeeTokenRemovedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryFeeTokenRemoved) + it.Event = new(FeeQuoterFeeTokenRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1492,7 +1492,7 @@ func (it *PriceRegistryFeeTokenRemovedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryFeeTokenRemoved) + it.Event = new(FeeQuoterFeeTokenRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1507,42 +1507,42 @@ func (it *PriceRegistryFeeTokenRemovedIterator) Next() bool { } } -func (it *PriceRegistryFeeTokenRemovedIterator) Error() error { +func (it *FeeQuoterFeeTokenRemovedIterator) Error() error { return it.fail } -func (it *PriceRegistryFeeTokenRemovedIterator) Close() error { +func (it *FeeQuoterFeeTokenRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryFeeTokenRemoved struct { +type FeeQuoterFeeTokenRemoved struct { FeeToken common.Address Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenRemovedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*FeeQuoterFeeTokenRemovedIterator, error) { var feeTokenRule []interface{} for _, feeTokenItem := range feeToken { feeTokenRule = append(feeTokenRule, feeTokenItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "FeeTokenRemoved", feeTokenRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "FeeTokenRemoved", feeTokenRule) if err != nil { return nil, err } - return &PriceRegistryFeeTokenRemovedIterator{contract: _PriceRegistry.contract, event: "FeeTokenRemoved", logs: logs, sub: sub}, nil + return &FeeQuoterFeeTokenRemovedIterator{contract: _FeeQuoter.contract, event: "FeeTokenRemoved", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *FeeQuoterFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) { var feeTokenRule []interface{} for _, feeTokenItem := range feeToken { feeTokenRule = append(feeTokenRule, feeTokenItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "FeeTokenRemoved", feeTokenRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "FeeTokenRemoved", feeTokenRule) if err != nil { return nil, err } @@ -1552,8 +1552,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenRemoved(opts *bind.Wat select { case log := <-logs: - event := new(PriceRegistryFeeTokenRemoved) - if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenRemoved", log); err != nil { + event := new(FeeQuoterFeeTokenRemoved) + if err := _FeeQuoter.contract.UnpackLog(event, "FeeTokenRemoved", log); err != nil { return err } event.Raw = log @@ -1574,17 +1574,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenRemoved(opts *bind.Wat }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseFeeTokenRemoved(log types.Log) (*PriceRegistryFeeTokenRemoved, error) { - event := new(PriceRegistryFeeTokenRemoved) - if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenRemoved", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseFeeTokenRemoved(log types.Log) (*FeeQuoterFeeTokenRemoved, error) { + event := new(FeeQuoterFeeTokenRemoved) + if err := _FeeQuoter.contract.UnpackLog(event, "FeeTokenRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryOwnershipTransferRequestedIterator struct { - Event *PriceRegistryOwnershipTransferRequested +type FeeQuoterOwnershipTransferRequestedIterator struct { + Event *FeeQuoterOwnershipTransferRequested contract *bind.BoundContract event string @@ -1595,7 +1595,7 @@ type PriceRegistryOwnershipTransferRequestedIterator struct { fail error } -func (it *PriceRegistryOwnershipTransferRequestedIterator) Next() bool { +func (it *FeeQuoterOwnershipTransferRequestedIterator) Next() bool { if it.fail != nil { return false @@ -1604,7 +1604,7 @@ func (it *PriceRegistryOwnershipTransferRequestedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryOwnershipTransferRequested) + it.Event = new(FeeQuoterOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1619,7 +1619,7 @@ func (it *PriceRegistryOwnershipTransferRequestedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryOwnershipTransferRequested) + it.Event = new(FeeQuoterOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1634,22 +1634,22 @@ func (it *PriceRegistryOwnershipTransferRequestedIterator) Next() bool { } } -func (it *PriceRegistryOwnershipTransferRequestedIterator) Error() error { +func (it *FeeQuoterOwnershipTransferRequestedIterator) Error() error { return it.fail } -func (it *PriceRegistryOwnershipTransferRequestedIterator) Close() error { +func (it *FeeQuoterOwnershipTransferRequestedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryOwnershipTransferRequested struct { +type FeeQuoterOwnershipTransferRequested struct { From common.Address To common.Address Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferRequestedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FeeQuoterOwnershipTransferRequestedIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1660,14 +1660,14 @@ func (_PriceRegistry *PriceRegistryFilterer) FilterOwnershipTransferRequested(op toRule = append(toRule, toItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } - return &PriceRegistryOwnershipTransferRequestedIterator{contract: _PriceRegistry.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil + return &FeeQuoterOwnershipTransferRequestedIterator{contract: _FeeQuoter.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FeeQuoterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1678,7 +1678,7 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferRequested(opt toRule = append(toRule, toItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } @@ -1688,8 +1688,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferRequested(opt select { case log := <-logs: - event := new(PriceRegistryOwnershipTransferRequested) - if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + event := new(FeeQuoterOwnershipTransferRequested) + if err := _FeeQuoter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return err } event.Raw = log @@ -1710,17 +1710,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferRequested(opt }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseOwnershipTransferRequested(log types.Log) (*PriceRegistryOwnershipTransferRequested, error) { - event := new(PriceRegistryOwnershipTransferRequested) - if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseOwnershipTransferRequested(log types.Log) (*FeeQuoterOwnershipTransferRequested, error) { + event := new(FeeQuoterOwnershipTransferRequested) + if err := _FeeQuoter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryOwnershipTransferredIterator struct { - Event *PriceRegistryOwnershipTransferred +type FeeQuoterOwnershipTransferredIterator struct { + Event *FeeQuoterOwnershipTransferred contract *bind.BoundContract event string @@ -1731,7 +1731,7 @@ type PriceRegistryOwnershipTransferredIterator struct { fail error } -func (it *PriceRegistryOwnershipTransferredIterator) Next() bool { +func (it *FeeQuoterOwnershipTransferredIterator) Next() bool { if it.fail != nil { return false @@ -1740,7 +1740,7 @@ func (it *PriceRegistryOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryOwnershipTransferred) + it.Event = new(FeeQuoterOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1755,7 +1755,7 @@ func (it *PriceRegistryOwnershipTransferredIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryOwnershipTransferred) + it.Event = new(FeeQuoterOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1770,22 +1770,22 @@ func (it *PriceRegistryOwnershipTransferredIterator) Next() bool { } } -func (it *PriceRegistryOwnershipTransferredIterator) Error() error { +func (it *FeeQuoterOwnershipTransferredIterator) Error() error { return it.fail } -func (it *PriceRegistryOwnershipTransferredIterator) Close() error { +func (it *FeeQuoterOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryOwnershipTransferred struct { +type FeeQuoterOwnershipTransferred struct { From common.Address To common.Address Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferredIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FeeQuoterOwnershipTransferredIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1796,14 +1796,14 @@ func (_PriceRegistry *PriceRegistryFilterer) FilterOwnershipTransferred(opts *bi toRule = append(toRule, toItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } - return &PriceRegistryOwnershipTransferredIterator{contract: _PriceRegistry.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &FeeQuoterOwnershipTransferredIterator{contract: _FeeQuoter.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FeeQuoterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1814,7 +1814,7 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferred(opts *bin toRule = append(toRule, toItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } @@ -1824,8 +1824,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferred(opts *bin select { case log := <-logs: - event := new(PriceRegistryOwnershipTransferred) - if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(FeeQuoterOwnershipTransferred) + if err := _FeeQuoter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -1846,17 +1846,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferred(opts *bin }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseOwnershipTransferred(log types.Log) (*PriceRegistryOwnershipTransferred, error) { - event := new(PriceRegistryOwnershipTransferred) - if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseOwnershipTransferred(log types.Log) (*FeeQuoterOwnershipTransferred, error) { + event := new(FeeQuoterOwnershipTransferred) + if err := _FeeQuoter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator struct { - Event *PriceRegistryPremiumMultiplierWeiPerEthUpdated +type FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator struct { + Event *FeeQuoterPremiumMultiplierWeiPerEthUpdated contract *bind.BoundContract event string @@ -1867,7 +1867,7 @@ type PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator struct { fail error } -func (it *PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator) Next() bool { +func (it *FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator) Next() bool { if it.fail != nil { return false @@ -1876,7 +1876,7 @@ func (it *PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryPremiumMultiplierWeiPerEthUpdated) + it.Event = new(FeeQuoterPremiumMultiplierWeiPerEthUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1891,7 +1891,7 @@ func (it *PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryPremiumMultiplierWeiPerEthUpdated) + it.Event = new(FeeQuoterPremiumMultiplierWeiPerEthUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1906,43 +1906,43 @@ func (it *PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator) Next() bool { } } -func (it *PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator) Error() error { +func (it *FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator) Error() error { return it.fail } -func (it *PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator) Close() error { +func (it *FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryPremiumMultiplierWeiPerEthUpdated struct { +type FeeQuoterPremiumMultiplierWeiPerEthUpdated struct { Token common.Address PremiumMultiplierWeiPerEth uint64 Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterPremiumMultiplierWeiPerEthUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterPremiumMultiplierWeiPerEthUpdated(opts *bind.FilterOpts, token []common.Address) (*FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator, error) { var tokenRule []interface{} for _, tokenItem := range token { tokenRule = append(tokenRule, tokenItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PremiumMultiplierWeiPerEthUpdated", tokenRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "PremiumMultiplierWeiPerEthUpdated", tokenRule) if err != nil { return nil, err } - return &PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator{contract: _PriceRegistry.contract, event: "PremiumMultiplierWeiPerEthUpdated", logs: logs, sub: sub}, nil + return &FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator{contract: _FeeQuoter.contract, event: "PremiumMultiplierWeiPerEthUpdated", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchPremiumMultiplierWeiPerEthUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryPremiumMultiplierWeiPerEthUpdated, token []common.Address) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchPremiumMultiplierWeiPerEthUpdated(opts *bind.WatchOpts, sink chan<- *FeeQuoterPremiumMultiplierWeiPerEthUpdated, token []common.Address) (event.Subscription, error) { var tokenRule []interface{} for _, tokenItem := range token { tokenRule = append(tokenRule, tokenItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PremiumMultiplierWeiPerEthUpdated", tokenRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "PremiumMultiplierWeiPerEthUpdated", tokenRule) if err != nil { return nil, err } @@ -1952,8 +1952,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchPremiumMultiplierWeiPerEthUpda select { case log := <-logs: - event := new(PriceRegistryPremiumMultiplierWeiPerEthUpdated) - if err := _PriceRegistry.contract.UnpackLog(event, "PremiumMultiplierWeiPerEthUpdated", log); err != nil { + event := new(FeeQuoterPremiumMultiplierWeiPerEthUpdated) + if err := _FeeQuoter.contract.UnpackLog(event, "PremiumMultiplierWeiPerEthUpdated", log); err != nil { return err } event.Raw = log @@ -1974,17 +1974,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchPremiumMultiplierWeiPerEthUpda }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParsePremiumMultiplierWeiPerEthUpdated(log types.Log) (*PriceRegistryPremiumMultiplierWeiPerEthUpdated, error) { - event := new(PriceRegistryPremiumMultiplierWeiPerEthUpdated) - if err := _PriceRegistry.contract.UnpackLog(event, "PremiumMultiplierWeiPerEthUpdated", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParsePremiumMultiplierWeiPerEthUpdated(log types.Log) (*FeeQuoterPremiumMultiplierWeiPerEthUpdated, error) { + event := new(FeeQuoterPremiumMultiplierWeiPerEthUpdated) + if err := _FeeQuoter.contract.UnpackLog(event, "PremiumMultiplierWeiPerEthUpdated", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryPriceFeedPerTokenUpdatedIterator struct { - Event *PriceRegistryPriceFeedPerTokenUpdated +type FeeQuoterPriceFeedPerTokenUpdatedIterator struct { + Event *FeeQuoterPriceFeedPerTokenUpdated contract *bind.BoundContract event string @@ -1995,7 +1995,7 @@ type PriceRegistryPriceFeedPerTokenUpdatedIterator struct { fail error } -func (it *PriceRegistryPriceFeedPerTokenUpdatedIterator) Next() bool { +func (it *FeeQuoterPriceFeedPerTokenUpdatedIterator) Next() bool { if it.fail != nil { return false @@ -2004,7 +2004,7 @@ func (it *PriceRegistryPriceFeedPerTokenUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryPriceFeedPerTokenUpdated) + it.Event = new(FeeQuoterPriceFeedPerTokenUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2019,7 +2019,7 @@ func (it *PriceRegistryPriceFeedPerTokenUpdatedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryPriceFeedPerTokenUpdated) + it.Event = new(FeeQuoterPriceFeedPerTokenUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2034,43 +2034,43 @@ func (it *PriceRegistryPriceFeedPerTokenUpdatedIterator) Next() bool { } } -func (it *PriceRegistryPriceFeedPerTokenUpdatedIterator) Error() error { +func (it *FeeQuoterPriceFeedPerTokenUpdatedIterator) Error() error { return it.fail } -func (it *PriceRegistryPriceFeedPerTokenUpdatedIterator) Close() error { +func (it *FeeQuoterPriceFeedPerTokenUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryPriceFeedPerTokenUpdated struct { +type FeeQuoterPriceFeedPerTokenUpdated struct { Token common.Address - PriceFeedConfig IPriceRegistryTokenPriceFeedConfig + PriceFeedConfig IFeeQuoterTokenPriceFeedConfig Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterPriceFeedPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryPriceFeedPerTokenUpdatedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterPriceFeedPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*FeeQuoterPriceFeedPerTokenUpdatedIterator, error) { var tokenRule []interface{} for _, tokenItem := range token { tokenRule = append(tokenRule, tokenItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PriceFeedPerTokenUpdated", tokenRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "PriceFeedPerTokenUpdated", tokenRule) if err != nil { return nil, err } - return &PriceRegistryPriceFeedPerTokenUpdatedIterator{contract: _PriceRegistry.contract, event: "PriceFeedPerTokenUpdated", logs: logs, sub: sub}, nil + return &FeeQuoterPriceFeedPerTokenUpdatedIterator{contract: _FeeQuoter.contract, event: "PriceFeedPerTokenUpdated", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchPriceFeedPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceFeedPerTokenUpdated, token []common.Address) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchPriceFeedPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *FeeQuoterPriceFeedPerTokenUpdated, token []common.Address) (event.Subscription, error) { var tokenRule []interface{} for _, tokenItem := range token { tokenRule = append(tokenRule, tokenItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PriceFeedPerTokenUpdated", tokenRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "PriceFeedPerTokenUpdated", tokenRule) if err != nil { return nil, err } @@ -2080,8 +2080,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchPriceFeedPerTokenUpdated(opts select { case log := <-logs: - event := new(PriceRegistryPriceFeedPerTokenUpdated) - if err := _PriceRegistry.contract.UnpackLog(event, "PriceFeedPerTokenUpdated", log); err != nil { + event := new(FeeQuoterPriceFeedPerTokenUpdated) + if err := _FeeQuoter.contract.UnpackLog(event, "PriceFeedPerTokenUpdated", log); err != nil { return err } event.Raw = log @@ -2102,17 +2102,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchPriceFeedPerTokenUpdated(opts }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParsePriceFeedPerTokenUpdated(log types.Log) (*PriceRegistryPriceFeedPerTokenUpdated, error) { - event := new(PriceRegistryPriceFeedPerTokenUpdated) - if err := _PriceRegistry.contract.UnpackLog(event, "PriceFeedPerTokenUpdated", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParsePriceFeedPerTokenUpdated(log types.Log) (*FeeQuoterPriceFeedPerTokenUpdated, error) { + event := new(FeeQuoterPriceFeedPerTokenUpdated) + if err := _FeeQuoter.contract.UnpackLog(event, "PriceFeedPerTokenUpdated", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryReportPermissionSetIterator struct { - Event *PriceRegistryReportPermissionSet +type FeeQuoterReportPermissionSetIterator struct { + Event *FeeQuoterReportPermissionSet contract *bind.BoundContract event string @@ -2123,7 +2123,7 @@ type PriceRegistryReportPermissionSetIterator struct { fail error } -func (it *PriceRegistryReportPermissionSetIterator) Next() bool { +func (it *FeeQuoterReportPermissionSetIterator) Next() bool { if it.fail != nil { return false @@ -2132,7 +2132,7 @@ func (it *PriceRegistryReportPermissionSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryReportPermissionSet) + it.Event = new(FeeQuoterReportPermissionSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2147,7 +2147,7 @@ func (it *PriceRegistryReportPermissionSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryReportPermissionSet) + it.Event = new(FeeQuoterReportPermissionSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2162,43 +2162,43 @@ func (it *PriceRegistryReportPermissionSetIterator) Next() bool { } } -func (it *PriceRegistryReportPermissionSetIterator) Error() error { +func (it *FeeQuoterReportPermissionSetIterator) Error() error { return it.fail } -func (it *PriceRegistryReportPermissionSetIterator) Close() error { +func (it *FeeQuoterReportPermissionSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryReportPermissionSet struct { +type FeeQuoterReportPermissionSet struct { ReportId [32]byte Permission KeystoneFeedsPermissionHandlerPermission Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterReportPermissionSet(opts *bind.FilterOpts, reportId [][32]byte) (*PriceRegistryReportPermissionSetIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterReportPermissionSet(opts *bind.FilterOpts, reportId [][32]byte) (*FeeQuoterReportPermissionSetIterator, error) { var reportIdRule []interface{} for _, reportIdItem := range reportId { reportIdRule = append(reportIdRule, reportIdItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "ReportPermissionSet", reportIdRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "ReportPermissionSet", reportIdRule) if err != nil { return nil, err } - return &PriceRegistryReportPermissionSetIterator{contract: _PriceRegistry.contract, event: "ReportPermissionSet", logs: logs, sub: sub}, nil + return &FeeQuoterReportPermissionSetIterator{contract: _FeeQuoter.contract, event: "ReportPermissionSet", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchReportPermissionSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryReportPermissionSet, reportId [][32]byte) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchReportPermissionSet(opts *bind.WatchOpts, sink chan<- *FeeQuoterReportPermissionSet, reportId [][32]byte) (event.Subscription, error) { var reportIdRule []interface{} for _, reportIdItem := range reportId { reportIdRule = append(reportIdRule, reportIdItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "ReportPermissionSet", reportIdRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "ReportPermissionSet", reportIdRule) if err != nil { return nil, err } @@ -2208,8 +2208,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchReportPermissionSet(opts *bind select { case log := <-logs: - event := new(PriceRegistryReportPermissionSet) - if err := _PriceRegistry.contract.UnpackLog(event, "ReportPermissionSet", log); err != nil { + event := new(FeeQuoterReportPermissionSet) + if err := _FeeQuoter.contract.UnpackLog(event, "ReportPermissionSet", log); err != nil { return err } event.Raw = log @@ -2230,17 +2230,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchReportPermissionSet(opts *bind }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseReportPermissionSet(log types.Log) (*PriceRegistryReportPermissionSet, error) { - event := new(PriceRegistryReportPermissionSet) - if err := _PriceRegistry.contract.UnpackLog(event, "ReportPermissionSet", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseReportPermissionSet(log types.Log) (*FeeQuoterReportPermissionSet, error) { + event := new(FeeQuoterReportPermissionSet) + if err := _FeeQuoter.contract.UnpackLog(event, "ReportPermissionSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryTokenTransferFeeConfigDeletedIterator struct { - Event *PriceRegistryTokenTransferFeeConfigDeleted +type FeeQuoterTokenTransferFeeConfigDeletedIterator struct { + Event *FeeQuoterTokenTransferFeeConfigDeleted contract *bind.BoundContract event string @@ -2251,7 +2251,7 @@ type PriceRegistryTokenTransferFeeConfigDeletedIterator struct { fail error } -func (it *PriceRegistryTokenTransferFeeConfigDeletedIterator) Next() bool { +func (it *FeeQuoterTokenTransferFeeConfigDeletedIterator) Next() bool { if it.fail != nil { return false @@ -2260,7 +2260,7 @@ func (it *PriceRegistryTokenTransferFeeConfigDeletedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryTokenTransferFeeConfigDeleted) + it.Event = new(FeeQuoterTokenTransferFeeConfigDeleted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2275,7 +2275,7 @@ func (it *PriceRegistryTokenTransferFeeConfigDeletedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryTokenTransferFeeConfigDeleted) + it.Event = new(FeeQuoterTokenTransferFeeConfigDeleted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2290,22 +2290,22 @@ func (it *PriceRegistryTokenTransferFeeConfigDeletedIterator) Next() bool { } } -func (it *PriceRegistryTokenTransferFeeConfigDeletedIterator) Error() error { +func (it *FeeQuoterTokenTransferFeeConfigDeletedIterator) Error() error { return it.fail } -func (it *PriceRegistryTokenTransferFeeConfigDeletedIterator) Close() error { +func (it *FeeQuoterTokenTransferFeeConfigDeletedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryTokenTransferFeeConfigDeleted struct { +type FeeQuoterTokenTransferFeeConfigDeleted struct { DestChainSelector uint64 Token common.Address Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*PriceRegistryTokenTransferFeeConfigDeletedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*FeeQuoterTokenTransferFeeConfigDeletedIterator, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { @@ -2316,14 +2316,14 @@ func (_PriceRegistry *PriceRegistryFilterer) FilterTokenTransferFeeConfigDeleted tokenRule = append(tokenRule, tokenItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "TokenTransferFeeConfigDeleted", destChainSelectorRule, tokenRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "TokenTransferFeeConfigDeleted", destChainSelectorRule, tokenRule) if err != nil { return nil, err } - return &PriceRegistryTokenTransferFeeConfigDeletedIterator{contract: _PriceRegistry.contract, event: "TokenTransferFeeConfigDeleted", logs: logs, sub: sub}, nil + return &FeeQuoterTokenTransferFeeConfigDeletedIterator{contract: _FeeQuoter.contract, event: "TokenTransferFeeConfigDeleted", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *PriceRegistryTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *FeeQuoterTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { @@ -2334,7 +2334,7 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchTokenTransferFeeConfigDeleted( tokenRule = append(tokenRule, tokenItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "TokenTransferFeeConfigDeleted", destChainSelectorRule, tokenRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "TokenTransferFeeConfigDeleted", destChainSelectorRule, tokenRule) if err != nil { return nil, err } @@ -2344,8 +2344,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchTokenTransferFeeConfigDeleted( select { case log := <-logs: - event := new(PriceRegistryTokenTransferFeeConfigDeleted) - if err := _PriceRegistry.contract.UnpackLog(event, "TokenTransferFeeConfigDeleted", log); err != nil { + event := new(FeeQuoterTokenTransferFeeConfigDeleted) + if err := _FeeQuoter.contract.UnpackLog(event, "TokenTransferFeeConfigDeleted", log); err != nil { return err } event.Raw = log @@ -2366,17 +2366,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchTokenTransferFeeConfigDeleted( }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseTokenTransferFeeConfigDeleted(log types.Log) (*PriceRegistryTokenTransferFeeConfigDeleted, error) { - event := new(PriceRegistryTokenTransferFeeConfigDeleted) - if err := _PriceRegistry.contract.UnpackLog(event, "TokenTransferFeeConfigDeleted", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseTokenTransferFeeConfigDeleted(log types.Log) (*FeeQuoterTokenTransferFeeConfigDeleted, error) { + event := new(FeeQuoterTokenTransferFeeConfigDeleted) + if err := _FeeQuoter.contract.UnpackLog(event, "TokenTransferFeeConfigDeleted", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryTokenTransferFeeConfigUpdatedIterator struct { - Event *PriceRegistryTokenTransferFeeConfigUpdated +type FeeQuoterTokenTransferFeeConfigUpdatedIterator struct { + Event *FeeQuoterTokenTransferFeeConfigUpdated contract *bind.BoundContract event string @@ -2387,7 +2387,7 @@ type PriceRegistryTokenTransferFeeConfigUpdatedIterator struct { fail error } -func (it *PriceRegistryTokenTransferFeeConfigUpdatedIterator) Next() bool { +func (it *FeeQuoterTokenTransferFeeConfigUpdatedIterator) Next() bool { if it.fail != nil { return false @@ -2396,7 +2396,7 @@ func (it *PriceRegistryTokenTransferFeeConfigUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryTokenTransferFeeConfigUpdated) + it.Event = new(FeeQuoterTokenTransferFeeConfigUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2411,7 +2411,7 @@ func (it *PriceRegistryTokenTransferFeeConfigUpdatedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryTokenTransferFeeConfigUpdated) + it.Event = new(FeeQuoterTokenTransferFeeConfigUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2426,23 +2426,23 @@ func (it *PriceRegistryTokenTransferFeeConfigUpdatedIterator) Next() bool { } } -func (it *PriceRegistryTokenTransferFeeConfigUpdatedIterator) Error() error { +func (it *FeeQuoterTokenTransferFeeConfigUpdatedIterator) Error() error { return it.fail } -func (it *PriceRegistryTokenTransferFeeConfigUpdatedIterator) Close() error { +func (it *FeeQuoterTokenTransferFeeConfigUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryTokenTransferFeeConfigUpdated struct { +type FeeQuoterTokenTransferFeeConfigUpdated struct { DestChainSelector uint64 Token common.Address - TokenTransferFeeConfig PriceRegistryTokenTransferFeeConfig + TokenTransferFeeConfig FeeQuoterTokenTransferFeeConfig Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterTokenTransferFeeConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*PriceRegistryTokenTransferFeeConfigUpdatedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterTokenTransferFeeConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*FeeQuoterTokenTransferFeeConfigUpdatedIterator, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { @@ -2453,14 +2453,14 @@ func (_PriceRegistry *PriceRegistryFilterer) FilterTokenTransferFeeConfigUpdated tokenRule = append(tokenRule, tokenItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "TokenTransferFeeConfigUpdated", destChainSelectorRule, tokenRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "TokenTransferFeeConfigUpdated", destChainSelectorRule, tokenRule) if err != nil { return nil, err } - return &PriceRegistryTokenTransferFeeConfigUpdatedIterator{contract: _PriceRegistry.contract, event: "TokenTransferFeeConfigUpdated", logs: logs, sub: sub}, nil + return &FeeQuoterTokenTransferFeeConfigUpdatedIterator{contract: _FeeQuoter.contract, event: "TokenTransferFeeConfigUpdated", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchTokenTransferFeeConfigUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryTokenTransferFeeConfigUpdated, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchTokenTransferFeeConfigUpdated(opts *bind.WatchOpts, sink chan<- *FeeQuoterTokenTransferFeeConfigUpdated, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { @@ -2471,7 +2471,7 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchTokenTransferFeeConfigUpdated( tokenRule = append(tokenRule, tokenItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "TokenTransferFeeConfigUpdated", destChainSelectorRule, tokenRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "TokenTransferFeeConfigUpdated", destChainSelectorRule, tokenRule) if err != nil { return nil, err } @@ -2481,8 +2481,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchTokenTransferFeeConfigUpdated( select { case log := <-logs: - event := new(PriceRegistryTokenTransferFeeConfigUpdated) - if err := _PriceRegistry.contract.UnpackLog(event, "TokenTransferFeeConfigUpdated", log); err != nil { + event := new(FeeQuoterTokenTransferFeeConfigUpdated) + if err := _FeeQuoter.contract.UnpackLog(event, "TokenTransferFeeConfigUpdated", log); err != nil { return err } event.Raw = log @@ -2503,17 +2503,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchTokenTransferFeeConfigUpdated( }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseTokenTransferFeeConfigUpdated(log types.Log) (*PriceRegistryTokenTransferFeeConfigUpdated, error) { - event := new(PriceRegistryTokenTransferFeeConfigUpdated) - if err := _PriceRegistry.contract.UnpackLog(event, "TokenTransferFeeConfigUpdated", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseTokenTransferFeeConfigUpdated(log types.Log) (*FeeQuoterTokenTransferFeeConfigUpdated, error) { + event := new(FeeQuoterTokenTransferFeeConfigUpdated) + if err := _FeeQuoter.contract.UnpackLog(event, "TokenTransferFeeConfigUpdated", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryUsdPerTokenUpdatedIterator struct { - Event *PriceRegistryUsdPerTokenUpdated +type FeeQuoterUsdPerTokenUpdatedIterator struct { + Event *FeeQuoterUsdPerTokenUpdated contract *bind.BoundContract event string @@ -2524,7 +2524,7 @@ type PriceRegistryUsdPerTokenUpdatedIterator struct { fail error } -func (it *PriceRegistryUsdPerTokenUpdatedIterator) Next() bool { +func (it *FeeQuoterUsdPerTokenUpdatedIterator) Next() bool { if it.fail != nil { return false @@ -2533,7 +2533,7 @@ func (it *PriceRegistryUsdPerTokenUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryUsdPerTokenUpdated) + it.Event = new(FeeQuoterUsdPerTokenUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2548,7 +2548,7 @@ func (it *PriceRegistryUsdPerTokenUpdatedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryUsdPerTokenUpdated) + it.Event = new(FeeQuoterUsdPerTokenUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2563,44 +2563,44 @@ func (it *PriceRegistryUsdPerTokenUpdatedIterator) Next() bool { } } -func (it *PriceRegistryUsdPerTokenUpdatedIterator) Error() error { +func (it *FeeQuoterUsdPerTokenUpdatedIterator) Error() error { return it.fail } -func (it *PriceRegistryUsdPerTokenUpdatedIterator) Close() error { +func (it *FeeQuoterUsdPerTokenUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryUsdPerTokenUpdated struct { +type FeeQuoterUsdPerTokenUpdated struct { Token common.Address Value *big.Int Timestamp *big.Int Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryUsdPerTokenUpdatedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*FeeQuoterUsdPerTokenUpdatedIterator, error) { var tokenRule []interface{} for _, tokenItem := range token { tokenRule = append(tokenRule, tokenItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "UsdPerTokenUpdated", tokenRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "UsdPerTokenUpdated", tokenRule) if err != nil { return nil, err } - return &PriceRegistryUsdPerTokenUpdatedIterator{contract: _PriceRegistry.contract, event: "UsdPerTokenUpdated", logs: logs, sub: sub}, nil + return &FeeQuoterUsdPerTokenUpdatedIterator{contract: _FeeQuoter.contract, event: "UsdPerTokenUpdated", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *FeeQuoterUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) { var tokenRule []interface{} for _, tokenItem := range token { tokenRule = append(tokenRule, tokenItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "UsdPerTokenUpdated", tokenRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "UsdPerTokenUpdated", tokenRule) if err != nil { return nil, err } @@ -2610,8 +2610,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerTokenUpdated(opts *bind. select { case log := <-logs: - event := new(PriceRegistryUsdPerTokenUpdated) - if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerTokenUpdated", log); err != nil { + event := new(FeeQuoterUsdPerTokenUpdated) + if err := _FeeQuoter.contract.UnpackLog(event, "UsdPerTokenUpdated", log); err != nil { return err } event.Raw = log @@ -2632,17 +2632,17 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerTokenUpdated(opts *bind. }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseUsdPerTokenUpdated(log types.Log) (*PriceRegistryUsdPerTokenUpdated, error) { - event := new(PriceRegistryUsdPerTokenUpdated) - if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerTokenUpdated", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseUsdPerTokenUpdated(log types.Log) (*FeeQuoterUsdPerTokenUpdated, error) { + event := new(FeeQuoterUsdPerTokenUpdated) + if err := _FeeQuoter.contract.UnpackLog(event, "UsdPerTokenUpdated", log); err != nil { return nil, err } event.Raw = log return event, nil } -type PriceRegistryUsdPerUnitGasUpdatedIterator struct { - Event *PriceRegistryUsdPerUnitGasUpdated +type FeeQuoterUsdPerUnitGasUpdatedIterator struct { + Event *FeeQuoterUsdPerUnitGasUpdated contract *bind.BoundContract event string @@ -2653,7 +2653,7 @@ type PriceRegistryUsdPerUnitGasUpdatedIterator struct { fail error } -func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Next() bool { +func (it *FeeQuoterUsdPerUnitGasUpdatedIterator) Next() bool { if it.fail != nil { return false @@ -2662,7 +2662,7 @@ func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(PriceRegistryUsdPerUnitGasUpdated) + it.Event = new(FeeQuoterUsdPerUnitGasUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2677,7 +2677,7 @@ func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(PriceRegistryUsdPerUnitGasUpdated) + it.Event = new(FeeQuoterUsdPerUnitGasUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2692,44 +2692,44 @@ func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Next() bool { } } -func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Error() error { +func (it *FeeQuoterUsdPerUnitGasUpdatedIterator) Error() error { return it.fail } -func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Close() error { +func (it *FeeQuoterUsdPerUnitGasUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -type PriceRegistryUsdPerUnitGasUpdated struct { +type FeeQuoterUsdPerUnitGasUpdated struct { DestChain uint64 Value *big.Int Timestamp *big.Int Raw types.Log } -func (_PriceRegistry *PriceRegistryFilterer) FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*PriceRegistryUsdPerUnitGasUpdatedIterator, error) { +func (_FeeQuoter *FeeQuoterFilterer) FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*FeeQuoterUsdPerUnitGasUpdatedIterator, error) { var destChainRule []interface{} for _, destChainItem := range destChain { destChainRule = append(destChainRule, destChainItem) } - logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "UsdPerUnitGasUpdated", destChainRule) + logs, sub, err := _FeeQuoter.contract.FilterLogs(opts, "UsdPerUnitGasUpdated", destChainRule) if err != nil { return nil, err } - return &PriceRegistryUsdPerUnitGasUpdatedIterator{contract: _PriceRegistry.contract, event: "UsdPerUnitGasUpdated", logs: logs, sub: sub}, nil + return &FeeQuoterUsdPerUnitGasUpdatedIterator{contract: _FeeQuoter.contract, event: "UsdPerUnitGasUpdated", logs: logs, sub: sub}, nil } -func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) { +func (_FeeQuoter *FeeQuoterFilterer) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *FeeQuoterUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) { var destChainRule []interface{} for _, destChainItem := range destChain { destChainRule = append(destChainRule, destChainItem) } - logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "UsdPerUnitGasUpdated", destChainRule) + logs, sub, err := _FeeQuoter.contract.WatchLogs(opts, "UsdPerUnitGasUpdated", destChainRule) if err != nil { return nil, err } @@ -2739,8 +2739,8 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerUnitGasUpdated(opts *bin select { case log := <-logs: - event := new(PriceRegistryUsdPerUnitGasUpdated) - if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerUnitGasUpdated", log); err != nil { + event := new(FeeQuoterUsdPerUnitGasUpdated) + if err := _FeeQuoter.contract.UnpackLog(event, "UsdPerUnitGasUpdated", log); err != nil { return err } event.Raw = log @@ -2761,9 +2761,9 @@ func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerUnitGasUpdated(opts *bin }), nil } -func (_PriceRegistry *PriceRegistryFilterer) ParseUsdPerUnitGasUpdated(log types.Log) (*PriceRegistryUsdPerUnitGasUpdated, error) { - event := new(PriceRegistryUsdPerUnitGasUpdated) - if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerUnitGasUpdated", log); err != nil { +func (_FeeQuoter *FeeQuoterFilterer) ParseUsdPerUnitGasUpdated(log types.Log) (*FeeQuoterUsdPerUnitGasUpdated, error) { + event := new(FeeQuoterUsdPerUnitGasUpdated) + if err := _FeeQuoter.contract.UnpackLog(event, "UsdPerUnitGasUpdated", log); err != nil { return nil, err } event.Raw = log @@ -2780,114 +2780,114 @@ type ProcessMessageArgs struct { ConvertedExtraArgs []byte } -func (_PriceRegistry *PriceRegistry) ParseLog(log types.Log) (generated.AbigenLog, error) { +func (_FeeQuoter *FeeQuoter) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _PriceRegistry.abi.Events["AuthorizedCallerAdded"].ID: - return _PriceRegistry.ParseAuthorizedCallerAdded(log) - case _PriceRegistry.abi.Events["AuthorizedCallerRemoved"].ID: - return _PriceRegistry.ParseAuthorizedCallerRemoved(log) - case _PriceRegistry.abi.Events["DestChainAdded"].ID: - return _PriceRegistry.ParseDestChainAdded(log) - case _PriceRegistry.abi.Events["DestChainConfigUpdated"].ID: - return _PriceRegistry.ParseDestChainConfigUpdated(log) - case _PriceRegistry.abi.Events["FeeTokenAdded"].ID: - return _PriceRegistry.ParseFeeTokenAdded(log) - case _PriceRegistry.abi.Events["FeeTokenRemoved"].ID: - return _PriceRegistry.ParseFeeTokenRemoved(log) - case _PriceRegistry.abi.Events["OwnershipTransferRequested"].ID: - return _PriceRegistry.ParseOwnershipTransferRequested(log) - case _PriceRegistry.abi.Events["OwnershipTransferred"].ID: - return _PriceRegistry.ParseOwnershipTransferred(log) - case _PriceRegistry.abi.Events["PremiumMultiplierWeiPerEthUpdated"].ID: - return _PriceRegistry.ParsePremiumMultiplierWeiPerEthUpdated(log) - case _PriceRegistry.abi.Events["PriceFeedPerTokenUpdated"].ID: - return _PriceRegistry.ParsePriceFeedPerTokenUpdated(log) - case _PriceRegistry.abi.Events["ReportPermissionSet"].ID: - return _PriceRegistry.ParseReportPermissionSet(log) - case _PriceRegistry.abi.Events["TokenTransferFeeConfigDeleted"].ID: - return _PriceRegistry.ParseTokenTransferFeeConfigDeleted(log) - case _PriceRegistry.abi.Events["TokenTransferFeeConfigUpdated"].ID: - return _PriceRegistry.ParseTokenTransferFeeConfigUpdated(log) - case _PriceRegistry.abi.Events["UsdPerTokenUpdated"].ID: - return _PriceRegistry.ParseUsdPerTokenUpdated(log) - case _PriceRegistry.abi.Events["UsdPerUnitGasUpdated"].ID: - return _PriceRegistry.ParseUsdPerUnitGasUpdated(log) + case _FeeQuoter.abi.Events["AuthorizedCallerAdded"].ID: + return _FeeQuoter.ParseAuthorizedCallerAdded(log) + case _FeeQuoter.abi.Events["AuthorizedCallerRemoved"].ID: + return _FeeQuoter.ParseAuthorizedCallerRemoved(log) + case _FeeQuoter.abi.Events["DestChainAdded"].ID: + return _FeeQuoter.ParseDestChainAdded(log) + case _FeeQuoter.abi.Events["DestChainConfigUpdated"].ID: + return _FeeQuoter.ParseDestChainConfigUpdated(log) + case _FeeQuoter.abi.Events["FeeTokenAdded"].ID: + return _FeeQuoter.ParseFeeTokenAdded(log) + case _FeeQuoter.abi.Events["FeeTokenRemoved"].ID: + return _FeeQuoter.ParseFeeTokenRemoved(log) + case _FeeQuoter.abi.Events["OwnershipTransferRequested"].ID: + return _FeeQuoter.ParseOwnershipTransferRequested(log) + case _FeeQuoter.abi.Events["OwnershipTransferred"].ID: + return _FeeQuoter.ParseOwnershipTransferred(log) + case _FeeQuoter.abi.Events["PremiumMultiplierWeiPerEthUpdated"].ID: + return _FeeQuoter.ParsePremiumMultiplierWeiPerEthUpdated(log) + case _FeeQuoter.abi.Events["PriceFeedPerTokenUpdated"].ID: + return _FeeQuoter.ParsePriceFeedPerTokenUpdated(log) + case _FeeQuoter.abi.Events["ReportPermissionSet"].ID: + return _FeeQuoter.ParseReportPermissionSet(log) + case _FeeQuoter.abi.Events["TokenTransferFeeConfigDeleted"].ID: + return _FeeQuoter.ParseTokenTransferFeeConfigDeleted(log) + case _FeeQuoter.abi.Events["TokenTransferFeeConfigUpdated"].ID: + return _FeeQuoter.ParseTokenTransferFeeConfigUpdated(log) + case _FeeQuoter.abi.Events["UsdPerTokenUpdated"].ID: + return _FeeQuoter.ParseUsdPerTokenUpdated(log) + case _FeeQuoter.abi.Events["UsdPerUnitGasUpdated"].ID: + return _FeeQuoter.ParseUsdPerUnitGasUpdated(log) default: return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) } } -func (PriceRegistryAuthorizedCallerAdded) Topic() common.Hash { +func (FeeQuoterAuthorizedCallerAdded) Topic() common.Hash { return common.HexToHash("0xeb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef") } -func (PriceRegistryAuthorizedCallerRemoved) Topic() common.Hash { +func (FeeQuoterAuthorizedCallerRemoved) Topic() common.Hash { return common.HexToHash("0xc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda77580") } -func (PriceRegistryDestChainAdded) Topic() common.Hash { +func (FeeQuoterDestChainAdded) Topic() common.Hash { return common.HexToHash("0xd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb724") } -func (PriceRegistryDestChainConfigUpdated) Topic() common.Hash { +func (FeeQuoterDestChainConfigUpdated) Topic() common.Hash { return common.HexToHash("0x1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab20") } -func (PriceRegistryFeeTokenAdded) Topic() common.Hash { +func (FeeQuoterFeeTokenAdded) Topic() common.Hash { return common.HexToHash("0xdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba23") } -func (PriceRegistryFeeTokenRemoved) Topic() common.Hash { +func (FeeQuoterFeeTokenRemoved) Topic() common.Hash { return common.HexToHash("0x1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f91") } -func (PriceRegistryOwnershipTransferRequested) Topic() common.Hash { +func (FeeQuoterOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } -func (PriceRegistryOwnershipTransferred) Topic() common.Hash { +func (FeeQuoterOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (PriceRegistryPremiumMultiplierWeiPerEthUpdated) Topic() common.Hash { +func (FeeQuoterPremiumMultiplierWeiPerEthUpdated) Topic() common.Hash { return common.HexToHash("0xbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d") } -func (PriceRegistryPriceFeedPerTokenUpdated) Topic() common.Hash { +func (FeeQuoterPriceFeedPerTokenUpdated) Topic() common.Hash { return common.HexToHash("0x08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464") } -func (PriceRegistryReportPermissionSet) Topic() common.Hash { +func (FeeQuoterReportPermissionSet) Topic() common.Hash { return common.HexToHash("0x32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a3") } -func (PriceRegistryTokenTransferFeeConfigDeleted) Topic() common.Hash { +func (FeeQuoterTokenTransferFeeConfigDeleted) Topic() common.Hash { return common.HexToHash("0x4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b") } -func (PriceRegistryTokenTransferFeeConfigUpdated) Topic() common.Hash { +func (FeeQuoterTokenTransferFeeConfigUpdated) Topic() common.Hash { return common.HexToHash("0x94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5") } -func (PriceRegistryUsdPerTokenUpdated) Topic() common.Hash { +func (FeeQuoterUsdPerTokenUpdated) Topic() common.Hash { return common.HexToHash("0x52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a") } -func (PriceRegistryUsdPerUnitGasUpdated) Topic() common.Hash { +func (FeeQuoterUsdPerUnitGasUpdated) Topic() common.Hash { return common.HexToHash("0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e") } -func (_PriceRegistry *PriceRegistry) Address() common.Address { - return _PriceRegistry.address +func (_FeeQuoter *FeeQuoter) Address() common.Address { + return _FeeQuoter.address } -type PriceRegistryInterface interface { +type FeeQuoterInterface interface { ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) - GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (PriceRegistryDestChainConfig, error) + GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (FeeQuoterDestChainConfig, error) GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (InternalTimestampedPackedUint224, error) @@ -2895,7 +2895,7 @@ type PriceRegistryInterface interface { GetPremiumMultiplierWeiPerEth(opts *bind.CallOpts, token common.Address) (uint64, error) - GetStaticConfig(opts *bind.CallOpts) (PriceRegistryStaticConfig, error) + GetStaticConfig(opts *bind.CallOpts) (FeeQuoterStaticConfig, error) GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, @@ -2903,11 +2903,11 @@ type PriceRegistryInterface interface { GetTokenPrice(opts *bind.CallOpts, token common.Address) (InternalTimestampedPackedUint224, error) - GetTokenPriceFeedConfig(opts *bind.CallOpts, token common.Address) (IPriceRegistryTokenPriceFeedConfig, error) + GetTokenPriceFeedConfig(opts *bind.CallOpts, token common.Address) (IFeeQuoterTokenPriceFeedConfig, error) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]InternalTimestampedPackedUint224, error) - GetTokenTransferFeeConfig(opts *bind.CallOpts, destChainSelector uint64, token common.Address) (PriceRegistryTokenTransferFeeConfig, error) + GetTokenTransferFeeConfig(opts *bind.CallOpts, destChainSelector uint64, token common.Address) (FeeQuoterTokenTransferFeeConfig, error) GetValidatedFee(opts *bind.CallOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*big.Int, error) @@ -2927,13 +2927,13 @@ type PriceRegistryInterface interface { ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) - ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []PriceRegistryDestChainConfigArgs) (*types.Transaction, error) + ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []FeeQuoterDestChainConfigArgs) (*types.Transaction, error) ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) - ApplyPremiumMultiplierWeiPerEthUpdates(opts *bind.TransactOpts, premiumMultiplierWeiPerEthArgs []PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) + ApplyPremiumMultiplierWeiPerEthUpdates(opts *bind.TransactOpts, premiumMultiplierWeiPerEthArgs []FeeQuoterPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) - ApplyTokenTransferFeeConfigUpdates(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) + ApplyTokenTransferFeeConfigUpdates(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []FeeQuoterTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []FeeQuoterTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) OnReport(opts *bind.TransactOpts, metadata []byte, report []byte) (*types.Transaction, error) @@ -2943,97 +2943,97 @@ type PriceRegistryInterface interface { UpdatePrices(opts *bind.TransactOpts, priceUpdates InternalPriceUpdates) (*types.Transaction, error) - UpdateTokenPriceFeeds(opts *bind.TransactOpts, tokenPriceFeedUpdates []PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error) + UpdateTokenPriceFeeds(opts *bind.TransactOpts, tokenPriceFeedUpdates []FeeQuoterTokenPriceFeedUpdate) (*types.Transaction, error) - FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*PriceRegistryAuthorizedCallerAddedIterator, error) + FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*FeeQuoterAuthorizedCallerAddedIterator, error) - WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryAuthorizedCallerAdded) (event.Subscription, error) + WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *FeeQuoterAuthorizedCallerAdded) (event.Subscription, error) - ParseAuthorizedCallerAdded(log types.Log) (*PriceRegistryAuthorizedCallerAdded, error) + ParseAuthorizedCallerAdded(log types.Log) (*FeeQuoterAuthorizedCallerAdded, error) - FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*PriceRegistryAuthorizedCallerRemovedIterator, error) + FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*FeeQuoterAuthorizedCallerRemovedIterator, error) - WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryAuthorizedCallerRemoved) (event.Subscription, error) + WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *FeeQuoterAuthorizedCallerRemoved) (event.Subscription, error) - ParseAuthorizedCallerRemoved(log types.Log) (*PriceRegistryAuthorizedCallerRemoved, error) + ParseAuthorizedCallerRemoved(log types.Log) (*FeeQuoterAuthorizedCallerRemoved, error) - FilterDestChainAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*PriceRegistryDestChainAddedIterator, error) + FilterDestChainAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*FeeQuoterDestChainAddedIterator, error) - WatchDestChainAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryDestChainAdded, destChainSelector []uint64) (event.Subscription, error) + WatchDestChainAdded(opts *bind.WatchOpts, sink chan<- *FeeQuoterDestChainAdded, destChainSelector []uint64) (event.Subscription, error) - ParseDestChainAdded(log types.Log) (*PriceRegistryDestChainAdded, error) + ParseDestChainAdded(log types.Log) (*FeeQuoterDestChainAdded, error) - FilterDestChainConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*PriceRegistryDestChainConfigUpdatedIterator, error) + FilterDestChainConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*FeeQuoterDestChainConfigUpdatedIterator, error) - WatchDestChainConfigUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryDestChainConfigUpdated, destChainSelector []uint64) (event.Subscription, error) + WatchDestChainConfigUpdated(opts *bind.WatchOpts, sink chan<- *FeeQuoterDestChainConfigUpdated, destChainSelector []uint64) (event.Subscription, error) - ParseDestChainConfigUpdated(log types.Log) (*PriceRegistryDestChainConfigUpdated, error) + ParseDestChainConfigUpdated(log types.Log) (*FeeQuoterDestChainConfigUpdated, error) - FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenAddedIterator, error) + FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*FeeQuoterFeeTokenAddedIterator, error) - WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) + WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *FeeQuoterFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) - ParseFeeTokenAdded(log types.Log) (*PriceRegistryFeeTokenAdded, error) + ParseFeeTokenAdded(log types.Log) (*FeeQuoterFeeTokenAdded, error) - FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenRemovedIterator, error) + FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*FeeQuoterFeeTokenRemovedIterator, error) - WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) + WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *FeeQuoterFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) - ParseFeeTokenRemoved(log types.Log) (*PriceRegistryFeeTokenRemoved, error) + ParseFeeTokenRemoved(log types.Log) (*FeeQuoterFeeTokenRemoved, error) - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferRequestedIterator, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FeeQuoterOwnershipTransferRequestedIterator, error) - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FeeQuoterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - ParseOwnershipTransferRequested(log types.Log) (*PriceRegistryOwnershipTransferRequested, error) + ParseOwnershipTransferRequested(log types.Log) (*FeeQuoterOwnershipTransferRequested, error) - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferredIterator, error) + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FeeQuoterOwnershipTransferredIterator, error) - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FeeQuoterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - ParseOwnershipTransferred(log types.Log) (*PriceRegistryOwnershipTransferred, error) + ParseOwnershipTransferred(log types.Log) (*FeeQuoterOwnershipTransferred, error) - FilterPremiumMultiplierWeiPerEthUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator, error) + FilterPremiumMultiplierWeiPerEthUpdated(opts *bind.FilterOpts, token []common.Address) (*FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator, error) - WatchPremiumMultiplierWeiPerEthUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryPremiumMultiplierWeiPerEthUpdated, token []common.Address) (event.Subscription, error) + WatchPremiumMultiplierWeiPerEthUpdated(opts *bind.WatchOpts, sink chan<- *FeeQuoterPremiumMultiplierWeiPerEthUpdated, token []common.Address) (event.Subscription, error) - ParsePremiumMultiplierWeiPerEthUpdated(log types.Log) (*PriceRegistryPremiumMultiplierWeiPerEthUpdated, error) + ParsePremiumMultiplierWeiPerEthUpdated(log types.Log) (*FeeQuoterPremiumMultiplierWeiPerEthUpdated, error) - FilterPriceFeedPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryPriceFeedPerTokenUpdatedIterator, error) + FilterPriceFeedPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*FeeQuoterPriceFeedPerTokenUpdatedIterator, error) - WatchPriceFeedPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceFeedPerTokenUpdated, token []common.Address) (event.Subscription, error) + WatchPriceFeedPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *FeeQuoterPriceFeedPerTokenUpdated, token []common.Address) (event.Subscription, error) - ParsePriceFeedPerTokenUpdated(log types.Log) (*PriceRegistryPriceFeedPerTokenUpdated, error) + ParsePriceFeedPerTokenUpdated(log types.Log) (*FeeQuoterPriceFeedPerTokenUpdated, error) - FilterReportPermissionSet(opts *bind.FilterOpts, reportId [][32]byte) (*PriceRegistryReportPermissionSetIterator, error) + FilterReportPermissionSet(opts *bind.FilterOpts, reportId [][32]byte) (*FeeQuoterReportPermissionSetIterator, error) - WatchReportPermissionSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryReportPermissionSet, reportId [][32]byte) (event.Subscription, error) + WatchReportPermissionSet(opts *bind.WatchOpts, sink chan<- *FeeQuoterReportPermissionSet, reportId [][32]byte) (event.Subscription, error) - ParseReportPermissionSet(log types.Log) (*PriceRegistryReportPermissionSet, error) + ParseReportPermissionSet(log types.Log) (*FeeQuoterReportPermissionSet, error) - FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*PriceRegistryTokenTransferFeeConfigDeletedIterator, error) + FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*FeeQuoterTokenTransferFeeConfigDeletedIterator, error) - WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *PriceRegistryTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) + WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *FeeQuoterTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) - ParseTokenTransferFeeConfigDeleted(log types.Log) (*PriceRegistryTokenTransferFeeConfigDeleted, error) + ParseTokenTransferFeeConfigDeleted(log types.Log) (*FeeQuoterTokenTransferFeeConfigDeleted, error) - FilterTokenTransferFeeConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*PriceRegistryTokenTransferFeeConfigUpdatedIterator, error) + FilterTokenTransferFeeConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*FeeQuoterTokenTransferFeeConfigUpdatedIterator, error) - WatchTokenTransferFeeConfigUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryTokenTransferFeeConfigUpdated, destChainSelector []uint64, token []common.Address) (event.Subscription, error) + WatchTokenTransferFeeConfigUpdated(opts *bind.WatchOpts, sink chan<- *FeeQuoterTokenTransferFeeConfigUpdated, destChainSelector []uint64, token []common.Address) (event.Subscription, error) - ParseTokenTransferFeeConfigUpdated(log types.Log) (*PriceRegistryTokenTransferFeeConfigUpdated, error) + ParseTokenTransferFeeConfigUpdated(log types.Log) (*FeeQuoterTokenTransferFeeConfigUpdated, error) - FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryUsdPerTokenUpdatedIterator, error) + FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*FeeQuoterUsdPerTokenUpdatedIterator, error) - WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) + WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *FeeQuoterUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) - ParseUsdPerTokenUpdated(log types.Log) (*PriceRegistryUsdPerTokenUpdated, error) + ParseUsdPerTokenUpdated(log types.Log) (*FeeQuoterUsdPerTokenUpdated, error) - FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*PriceRegistryUsdPerUnitGasUpdatedIterator, error) + FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*FeeQuoterUsdPerUnitGasUpdatedIterator, error) - WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) + WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *FeeQuoterUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) - ParseUsdPerUnitGasUpdated(log types.Log) (*PriceRegistryUsdPerUnitGasUpdated, error) + ParseUsdPerUnitGasUpdated(log types.Log) (*FeeQuoterUsdPerUnitGasUpdated, error) ParseLog(log types.Log) (generated.AbigenLog, error) diff --git a/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go b/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go index d8a34b9483..e1942e68da 100644 --- a/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go +++ b/core/gethwrappers/ccip/generated/multi_aggregate_rate_limiter/multi_aggregate_rate_limiter.go @@ -87,15 +87,15 @@ type RateLimiterTokenBucket struct { } var MultiAggregateRateLimiterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"PriceRegistrySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"RateLimiterConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimiterConfigArgs[]\",\"name\":\"rateLimiterUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applyRateLimiterConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"}],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"localTokens\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"remoteTokens\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onInboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onOutboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPriceRegistry\",\"type\":\"address\"}],\"name\":\"setPriceRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken\",\"name\":\"localTokenArgs\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimitTokenArgs[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b506040516200327338038062003273833981016040819052620000349162000538565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000102565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001ad565b50620000fa82620002fc565b50506200066f565b336001600160a01b038216036200015c5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b81518110156200023d576000828281518110620001d657620001d662000621565b60209081029190910101519050620001f060028262000378565b1562000233576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001b5565b50815160005b8151811015620002f657600082828151811062000264576200026462000621565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002a2576040516342bcdf7f60e11b815260040160405180910390fd5b620002af60028262000398565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000243565b50505050565b6001600160a01b03811662000324576040516342bcdf7f60e11b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b60006200038f836001600160a01b038416620003af565b90505b92915050565b60006200038f836001600160a01b038416620004b3565b60008181526001830160205260408120548015620004a8576000620003d660018362000637565b8554909150600090620003ec9060019062000637565b90508181146200045857600086600001828154811062000410576200041062000621565b906000526020600020015490508087600001848154811062000436576200043662000621565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200046c576200046c62000659565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000392565b600091505062000392565b6000818152600183016020526040812054620004fc5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000392565b50600062000392565b80516001600160a01b03811681146200051d57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200054c57600080fd5b620005578362000505565b602084810151919350906001600160401b03808211156200057757600080fd5b818601915086601f8301126200058c57600080fd5b815181811115620005a157620005a162000522565b8060051b604051601f19603f83011681018181108582111715620005c957620005c962000522565b604052918252848201925083810185019189831115620005e857600080fd5b938501935b828510156200061157620006018562000505565b84529385019392850192620005ed565b8096505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039257634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b612bf4806200067f6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063537e304e1161008c57806391a2749a1161006657806391a2749a14610252578063e0a0e50614610265578063f2fde38b14610278578063fe843cd01461028b57600080fd5b8063537e304e1461020b57806379ba50971461022c5780638da5cb5b1461023457600080fd5b8063181f5a77116100c8578063181f5a77146101bb5780631af18b7b146101d05780632451a627146101e3578063508ee9de146101f857600080fd5b806308d450a1146100ef5780630a35bcc4146101045780630d6c107e1461017c575b600080fd5b6101026100fd366004612003565b61029e565b005b6101176101123660046120e3565b6102bd565b604051610173919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60405180910390f35b60055473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b6101c3610382565b604051610173919061217a565b6101026101de3660046122b4565b61039e565b6101eb6105ca565b60405161017391906123d1565b6101026102063660046123e4565b6105db565b61021e6102193660046123ff565b6105ec565b60405161017392919061241a565b610102610759565b60005473ffffffffffffffffffffffffffffffffffffffff16610196565b610102610260366004612510565b61085b565b6101026102733660046125a1565b61086c565b6101026102863660046123e4565b6108e1565b610102610299366004612616565b6108f2565b6102a6610c31565b6102ba816020015182608001516000610c76565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526103796102f58484610d4d565b6040805160a08101825282546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff16151593830193909352600190930154808316606083015292909204166080820152610d7d565b90505b92915050565b604051806060016040528060238152602001612bc56023913981565b6103a6610e2f565b60005b82518110156104845760008382815181106103c6576103c661274a565b602002602001015160200151905060008483815181106103e8576103e861274a565b6020908102919091018101515167ffffffffffffffff811660009081526004909252604090912090915061041c9083610eb0565b1561047a576040805167ffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff841660208201527f530cabd30786b7235e124a6c0db77e0b685ef22813b1fe87554247f404eb8ed6910160405180910390a15b50506001016103a9565b5060005b81518110156105c55760008282815181106104a5576104a561274a565b602002602001015160000151905060008383815181106104c7576104c761274a565b6020026020010151602001519050600082602001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061051857508151155b1561054f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825167ffffffffffffffff81166000908152600460205260409020610575908385610ed2565b156105b6577fad72a792d2a307f400c278be7deaeec6964276783304580cdc4e905436b8d5c58184846040516105ad93929190612779565b60405180910390a15b50505050806001019050610488565b505050565b60606105d66002610eff565b905090565b6105e3610e2f565b6102ba81610f0c565b67ffffffffffffffff81166000908152600460205260408120606091829161061390610fd2565b90508067ffffffffffffffff81111561062e5761062e611d74565b604051908082528060200260200182016040528015610657578160200160208202803683370190505b5092508067ffffffffffffffff81111561067357610673611d74565b6040519080825280602002602001820160405280156106a657816020015b60608152602001906001900390816106915790505b50915060005b818110156107525767ffffffffffffffff8516600090815260046020526040812081906106d99084610fdd565b91509150818684815181106106f0576106f061274a565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508085848151811061073d5761073d61274a565b602090810291909101015250506001016106ac565b5050915091565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610863610e2f565b6102ba81610ffc565b610874610c31565b6108dd8261088560408401846127c2565b808060200260200160405190810160405280939291908181526020016000905b828210156108d1576108c26040830286013681900381019061282a565b815260200190600101906108a5565b50505050506001610c76565b5050565b6108e9610e2f565b6102ba81611188565b6108fa610e2f565b60005b81518110156108dd57600082828151811061091a5761091a61274a565b6020908102919091010151604081015181519192509067ffffffffffffffff8116600003610974576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015160006109858383610d4d565b8054909150700100000000000000000000000000000000900463ffffffff16600003610bd3576040805160a081018252602080870180516fffffffffffffffffffffffffffffffff908116845263ffffffff421692840192909252875115158385015251811660608301529186015190911660808201528215610aec5767ffffffffffffffff8416600090815260066020908152604091829020835160028201805493860151948601516fffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009095169490941770010000000000000000000000000000000063ffffffff9096168602177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000941515949094029390931790925560608401516080850151908316921690920217600390910155610bcd565b67ffffffffffffffff84166000908152600660209081526040918290208351815492850151938501516fffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff00000000000000000000000000000000000000009094169390931770010000000000000000000000000000000063ffffffff9095168502177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000093151593909302929092178155606084015160808501519083169216909202176001909101555b50610bdd565b610bdd818561127d565b8267ffffffffffffffff167ff14a5415ce6988a9e870a85fff0b9d7b7dd79bbc228cb63cad610daf6f7b6b978386604051610c19929190612846565b60405180910390a250505050508060010190506108fd565b610c3c60023361142c565b610c74576040517fd86ad9cf0000000000000000000000000000000000000000000000000000000081523360048201526024016107d6565b565b6000610c828483610d4d565b805490915074010000000000000000000000000000000000000000900460ff1615610d47576000805b8451811015610d3257610cf6858281518110610cc957610cc961274a565b6020908102919091018101515167ffffffffffffffff89166000908152600490925260409091209061145b565b15610d2a57610d1d858281518110610d1057610d1061274a565b602002602001015161147d565b610d2790836128b9565b91505b600101610cab565b508015610d4557610d45828260006115b9565b505b50505050565b67ffffffffffffffff821660009081526006602052604081208215610d7657600201905061037c565b905061037c565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152610e0b82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642610def91906128cc565b85608001516fffffffffffffffffffffffffffffffff1661193c565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107d6565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611964565b6000610ef58473ffffffffffffffffffffffffffffffffffffffff851684611988565b90505b9392505050565b60606000610ef8836119ad565b73ffffffffffffffffffffffffffffffffffffffff8116610f59576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df99060200160405180910390a150565b600061037c82611a09565b600060608180610fed8686611a14565b909450925050505b9250929050565b602081015160005b81518110156110975760008282815181106110215761102161274a565b6020026020010151905061103f816002611ad190919063ffffffff16565b1561108e5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101611004565b50815160005b8151811015610d475760008282815181106110ba576110ba61274a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361112a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611135600282611af3565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010161109d565b3373ffffffffffffffffffffffffffffffffffffffff821603611207576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107d6565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b81546000906112a690700100000000000000000000000000000000900463ffffffff16426128cc565b9050801561134857600183015483546112ee916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661193c565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461136e916fffffffffffffffffffffffffffffffff9081169116611b15565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061141f9084906128df565b60405180910390a1505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610379565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611b2b565b60055481516040517fd02641a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526000928392169063d02641a0906024016040805180830381865afa1580156114f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611515919061291b565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660000361158b5782516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016107d6565b6020830151610ef8907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690611b37565b825474010000000000000000000000000000000000000000900460ff1615806115e0575081155b156115ea57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061163090700100000000000000000000000000000000900463ffffffff16426128cc565b905080156116f05781831115611672576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546116ac9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661193c565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156117a75773ffffffffffffffffffffffffffffffffffffffff841661174f576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016107d6565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016107d6565b848310156118ba5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906117eb90826128cc565b6117f5878a6128cc565b6117ff91906128b9565b6118099190612986565b905073ffffffffffffffffffffffffffffffffffffffff8616611862576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016107d6565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016107d6565b6118c485846128cc565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600061195b8561194c84866129c1565b61195690876128b9565b611b15565b95945050505050565b6000818152600283016020526040812061197e9082611d26565b6103798383611b74565b600082815260028401602052604081206119a28382612a7b565b50610ef58484611b80565b6060816000018054806020026020016040519081016040528092919081815260200182805480156119fd57602002820191906000526020600020905b8154815260200190600101908083116119e9575b50505050509050919050565b600061037c82611b8c565b6000606081611a238585611b96565b60008181526002870160205260409020805491925082918190611a45906129d8565b80601f0160208091040260200160405190810160405280929190818152602001828054611a71906129d8565b8015611abe5780601f10611a9357610100808354040283529160200191611abe565b820191906000526020600020905b815481529060010190602001808311611aa157829003601f168201915b5050505050905092509250509250929050565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611ba2565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611c95565b6000818310611b245781610379565b5090919050565b60006103798383611ce4565b6000670de0b6b3a7640000611b6a837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166129c1565b6103799190612986565b60006103798383611ba2565b60006103798383611c95565b600061037c825490565b60006103798383611cfc565b60008181526001830160205260408120548015611c8b576000611bc66001836128cc565b8554909150600090611bda906001906128cc565b9050818114611c3f576000866000018281548110611bfa57611bfa61274a565b9060005260206000200154905080876000018481548110611c1d57611c1d61274a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611c5057611c50612b95565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061037c565b600091505061037c565b6000818152600183016020526040812054611cdc5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561037c565b50600061037c565b60008181526001830160205260408120541515610379565b6000826000018281548110611d1357611d1361274a565b9060005260206000200154905092915050565b508054611d32906129d8565b6000825580601f10611d42575050565b601f0160209004906000526020600020908101906102ba91905b80821115611d705760008155600101611d5c565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611dc657611dc6611d74565b60405290565b60405160a0810167ffffffffffffffff81118282101715611dc657611dc6611d74565b6040516060810167ffffffffffffffff81118282101715611dc657611dc6611d74565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e5957611e59611d74565b604052919050565b803567ffffffffffffffff81168114611e7957600080fd5b919050565b600082601f830112611e8f57600080fd5b813567ffffffffffffffff811115611ea957611ea9611d74565b611eda60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611e12565b818152846020838601011115611eef57600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115611f2657611f26611d74565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff81168114611e7957600080fd5b600060408284031215611f6657600080fd5b611f6e611da3565b9050611f7982611f30565b81526020820135602082015292915050565b600082601f830112611f9c57600080fd5b81356020611fb1611fac83611f0c565b611e12565b8083825260208201915060208460061b870101935086841115611fd357600080fd5b602086015b84811015611ff857611fea8882611f54565b835291830191604001611fd8565b509695505050505050565b60006020828403121561201557600080fd5b813567ffffffffffffffff8082111561202d57600080fd5b9083019060a0828603121561204157600080fd5b612049611dcc565b8235815261205960208401611e61565b602082015260408301358281111561207057600080fd5b61207c87828601611e7e565b60408301525060608301358281111561209457600080fd5b6120a087828601611e7e565b6060830152506080830135828111156120b857600080fd5b6120c487828601611f8b565b60808301525095945050505050565b80358015158114611e7957600080fd5b600080604083850312156120f657600080fd5b6120ff83611e61565b915061210d602084016120d3565b90509250929050565b6000815180845260005b8181101561213c57602081850181015186830182015201612120565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006103796020830184612116565b60006040828403121561219f57600080fd5b6121a7611da3565b90506121b282611e61565b81526121c060208301611f30565b602082015292915050565b600082601f8301126121dc57600080fd5b813560206121ec611fac83611f0c565b82815260059290921b8401810191818101908684111561220b57600080fd5b8286015b84811015611ff857803567ffffffffffffffff808211156122305760008081fd5b81890191506060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d030112156122695760008081fd5b612271611da3565b61227d8c89860161218d565b81529083013590828211156122925760008081fd5b6122a08c8984870101611e7e565b81890152865250505091830191830161220f565b60008060408084860312156122c857600080fd5b833567ffffffffffffffff808211156122e057600080fd5b818601915086601f8301126122f457600080fd5b81356020612304611fac83611f0c565b8083825260208201915060208460061b87010193508a84111561232657600080fd5b6020860195505b8386101561234e5761233f8b8761218d565b8252948601949082019061232d565b9750505050602086013592508083111561236757600080fd5b5050612375858286016121cb565b9150509250929050565b60008151808452602080850194506020840160005b838110156123c657815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612394565b509495945050505050565b602081526000610379602083018461237f565b6000602082840312156123f657600080fd5b61037982611f30565b60006020828403121561241157600080fd5b61037982611e61565b60408152600061242d604083018561237f565b6020838203818501528185518084528284019150828160051b85010183880160005b8381101561249b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0878403018552612489838351612116565b9486019492509085019060010161244f565b50909998505050505050505050565b600082601f8301126124bb57600080fd5b813560206124cb611fac83611f0c565b8083825260208201915060208460051b8701019350868411156124ed57600080fd5b602086015b84811015611ff85761250381611f30565b83529183019183016124f2565b60006020828403121561252257600080fd5b813567ffffffffffffffff8082111561253a57600080fd5b908301906040828603121561254e57600080fd5b612556611da3565b82358281111561256557600080fd5b612571878286016124aa565b82525060208301358281111561258657600080fd5b612592878286016124aa565b60208301525095945050505050565b600080604083850312156125b457600080fd5b6125bd83611e61565b9150602083013567ffffffffffffffff8111156125d957600080fd5b830160a081860312156125eb57600080fd5b809150509250929050565b80356fffffffffffffffffffffffffffffffff81168114611e7957600080fd5b6000602080838503121561262957600080fd5b823567ffffffffffffffff81111561264057600080fd5b8301601f8101851361265157600080fd5b803561265f611fac82611f0c565b81815260a0918202830184019184820191908884111561267e57600080fd5b938501935b8385101561273e578489038181121561269c5760008081fd5b6126a4611def565b6126ad87611e61565b81526126ba8888016120d3565b8882015260406060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0850112156126f25760008081fd5b6126fa611def565b9350612707828a016120d3565b8452612714818a016125f6565b8a85015250612725608089016125f6565b8382015281019190915283529384019391850191612683565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff8416815260606020820152600061279c6060830185612116565b905073ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126127f757600080fd5b83018035915067ffffffffffffffff82111561281257600080fd5b6020019150600681901b3603821315610ff557600080fd5b60006040828403121561283c57600080fd5b6103798383611f54565b821515815260808101610ef860208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561037c5761037c61288a565b8181038181111561037c5761037c61288a565b6060810161037c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006040828403121561292d57600080fd5b612935611da3565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461296157600080fd5b8152602083015163ffffffff8116811461297a57600080fd5b60208201529392505050565b6000826129bc577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761037c5761037c61288a565b600181811c908216806129ec57607f821691505b602082108103612a25577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105c5576000816000526020600020601f850160051c81016020861015612a545750805b601f850160051c820191505b81811015612a7357828155600101612a60565b505050505050565b815167ffffffffffffffff811115612a9557612a95611d74565b612aa981612aa384546129d8565b84612a2b565b602080601f831160018114612afc5760008415612ac65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612a73565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015612b4957888601518255948401946001909101908401612b2a565b5085821015612b8557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe4d756c7469416767726567617465526174654c696d6974657220312e362e302d646576a164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeQuoter\",\"type\":\"address\"}],\"name\":\"FeeQuoterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"RateLimiterConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"TokenAggregateRateLimitRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimiterConfigArgs[]\",\"name\":\"rateLimiterUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applyRateLimiterConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isOutboundLane\",\"type\":\"bool\"}],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllRateLimitTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"localTokens\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"remoteTokens\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeQuoter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onInboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"onOutboundMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFeeQuoter\",\"type\":\"address\"}],\"name\":\"setFeeQuoter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structMultiAggregateRateLimiter.LocalRateLimitToken\",\"name\":\"localTokenArgs\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"}],\"internalType\":\"structMultiAggregateRateLimiter.RateLimitTokenArgs[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"updateRateLimitTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b506040516200327338038062003273833981016040819052620000349162000538565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000102565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001ad565b50620000fa82620002fc565b50506200066f565b336001600160a01b038216036200015c5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b81518110156200023d576000828281518110620001d657620001d662000621565b60209081029190910101519050620001f060028262000378565b1562000233576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001b5565b50815160005b8151811015620002f657600082828151811062000264576200026462000621565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002a2576040516342bcdf7f60e11b815260040160405180910390fd5b620002af60028262000398565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000243565b50505050565b6001600160a01b03811662000324576040516342bcdf7f60e11b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527f7c737a8eddf62436489aa3600ed26e75e0a58b0f8c0d266bbcee64358c39fdac9060200160405180910390a150565b60006200038f836001600160a01b038416620003af565b90505b92915050565b60006200038f836001600160a01b038416620004b3565b60008181526001830160205260408120548015620004a8576000620003d660018362000637565b8554909150600090620003ec9060019062000637565b90508181146200045857600086600001828154811062000410576200041062000621565b906000526020600020015490508087600001848154811062000436576200043662000621565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200046c576200046c62000659565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000392565b600091505062000392565b6000818152600183016020526040812054620004fc5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000392565b50600062000392565b80516001600160a01b03811681146200051d57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200054c57600080fd5b620005578362000505565b602084810151919350906001600160401b03808211156200057757600080fd5b818601915086601f8301126200058c57600080fd5b815181811115620005a157620005a162000522565b8060051b604051601f19603f83011681018181108582111715620005c957620005c962000522565b604052918252848201925083810185019189831115620005e857600080fd5b938501935b828510156200061157620006018562000505565b84529385019392850192620005ed565b8096505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200039257634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b612bf4806200067f6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638da5cb5b1161008c578063e145291611610066578063e145291614610247578063e835232b14610265578063f2fde38b14610278578063fe843cd01461028b57600080fd5b80638da5cb5b146101e257806391a2749a14610221578063e0a0e5061461023457600080fd5b80631af18b7b116100c85780631af18b7b146101915780632451a627146101a4578063537e304e146101b957806379ba5097146101da57600080fd5b806308d450a1146100ef5780630a35bcc414610104578063181f5a771461017c575b600080fd5b6101026100fd366004612003565b61029e565b005b6101176101123660046120e3565b6102bd565b604051610173919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60405180910390f35b610184610382565b604051610173919061217a565b61010261019f3660046122b4565b61039e565b6101ac6105ca565b60405161017391906123d1565b6101cc6101c73660046123e4565b6105db565b6040516101739291906123ff565b610102610748565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b61010261022f3660046124f5565b61084a565b610102610242366004612586565b61085b565b60055473ffffffffffffffffffffffffffffffffffffffff166101fc565b6101026102733660046125db565b6108d0565b6101026102863660046125db565b6108e1565b610102610299366004612616565b6108f2565b6102a6610c31565b6102ba816020015182608001516000610c76565b50565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526103796102f58484610d4d565b6040805160a08101825282546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff16151593830193909352600190930154808316606083015292909204166080820152610d7d565b90505b92915050565b604051806060016040528060238152602001612bc56023913981565b6103a6610e2f565b60005b82518110156104845760008382815181106103c6576103c661274a565b602002602001015160200151905060008483815181106103e8576103e861274a565b6020908102919091018101515167ffffffffffffffff811660009081526004909252604090912090915061041c9083610eb0565b1561047a576040805167ffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff841660208201527f530cabd30786b7235e124a6c0db77e0b685ef22813b1fe87554247f404eb8ed6910160405180910390a15b50506001016103a9565b5060005b81518110156105c55760008282815181106104a5576104a561274a565b602002602001015160000151905060008383815181106104c7576104c761274a565b6020026020010151602001519050600082602001519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061051857508151155b1561054f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825167ffffffffffffffff81166000908152600460205260409020610575908385610ed2565b156105b6577fad72a792d2a307f400c278be7deaeec6964276783304580cdc4e905436b8d5c58184846040516105ad93929190612779565b60405180910390a15b50505050806001019050610488565b505050565b60606105d66002610eff565b905090565b67ffffffffffffffff81166000908152600460205260408120606091829161060290610f0c565b90508067ffffffffffffffff81111561061d5761061d611d74565b604051908082528060200260200182016040528015610646578160200160208202803683370190505b5092508067ffffffffffffffff81111561066257610662611d74565b60405190808252806020026020018201604052801561069557816020015b60608152602001906001900390816106805790505b50915060005b818110156107415767ffffffffffffffff8516600090815260046020526040812081906106c89084610f17565b91509150818684815181106106df576106df61274a565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508085848151811061072c5761072c61274a565b6020908102919091010152505060010161069b565b5050915091565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610852610e2f565b6102ba81610f36565b610863610c31565b6108cc8261087460408401846127c2565b808060200260200160405190810160405280939291908181526020016000905b828210156108c0576108b16040830286013681900381019061282a565b81526020019060010190610894565b50505050506001610c76565b5050565b6108d8610e2f565b6102ba816110c2565b6108e9610e2f565b6102ba81611188565b6108fa610e2f565b60005b81518110156108cc57600082828151811061091a5761091a61274a565b6020908102919091010151604081015181519192509067ffffffffffffffff8116600003610974576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015160006109858383610d4d565b8054909150700100000000000000000000000000000000900463ffffffff16600003610bd3576040805160a081018252602080870180516fffffffffffffffffffffffffffffffff908116845263ffffffff421692840192909252875115158385015251811660608301529186015190911660808201528215610aec5767ffffffffffffffff8416600090815260066020908152604091829020835160028201805493860151948601516fffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff00000000000000000000000000000000000000009095169490941770010000000000000000000000000000000063ffffffff9096168602177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000941515949094029390931790925560608401516080850151908316921690920217600390910155610bcd565b67ffffffffffffffff84166000908152600660209081526040918290208351815492850151938501516fffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff00000000000000000000000000000000000000009094169390931770010000000000000000000000000000000063ffffffff9095168502177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000093151593909302929092178155606084015160808501519083169216909202176001909101555b50610bdd565b610bdd818561127d565b8267ffffffffffffffff167ff14a5415ce6988a9e870a85fff0b9d7b7dd79bbc228cb63cad610daf6f7b6b978386604051610c19929190612846565b60405180910390a250505050508060010190506108fd565b610c3c60023361142c565b610c74576040517fd86ad9cf0000000000000000000000000000000000000000000000000000000081523360048201526024016107c5565b565b6000610c828483610d4d565b805490915074010000000000000000000000000000000000000000900460ff1615610d47576000805b8451811015610d3257610cf6858281518110610cc957610cc961274a565b6020908102919091018101515167ffffffffffffffff89166000908152600490925260409091209061145b565b15610d2a57610d1d858281518110610d1057610d1061274a565b602002602001015161147d565b610d2790836128b9565b91505b600101610cab565b508015610d4557610d45828260006115b9565b505b50505050565b67ffffffffffffffff821660009081526006602052604081208215610d7657600201905061037c565b905061037c565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152610e0b82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642610def91906128cc565b85608001516fffffffffffffffffffffffffffffffff1661193c565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107c5565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611964565b6000610ef58473ffffffffffffffffffffffffffffffffffffffff851684611988565b90505b9392505050565b60606000610ef8836119ad565b600061037c82611a09565b600060608180610f278686611a14565b909450925050505b9250929050565b602081015160005b8151811015610fd1576000828281518110610f5b57610f5b61274a565b60200260200101519050610f79816002611ad190919063ffffffff16565b15610fc85760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101610f3e565b50815160005b8151811015610d47576000828281518110610ff457610ff461274a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611064576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61106f600282611af3565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101610fd7565b73ffffffffffffffffffffffffffffffffffffffff811661110f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f7c737a8eddf62436489aa3600ed26e75e0a58b0f8c0d266bbcee64358c39fdac9060200160405180910390a150565b3373ffffffffffffffffffffffffffffffffffffffff821603611207576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107c5565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b81546000906112a690700100000000000000000000000000000000900463ffffffff16426128cc565b9050801561134857600183015483546112ee916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661193c565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461136e916fffffffffffffffffffffffffffffffff9081169116611b15565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061141f9084906128df565b60405180910390a1505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610379565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611b2b565b60055481516040517fd02641a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526000928392169063d02641a0906024016040805180830381865afa1580156114f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611515919061291b565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660000361158b5782516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016107c5565b6020830151610ef8907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff831690611b37565b825474010000000000000000000000000000000000000000900460ff1615806115e0575081155b156115ea57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061163090700100000000000000000000000000000000900463ffffffff16426128cc565b905080156116f05781831115611672576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546116ac9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661193c565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156117a75773ffffffffffffffffffffffffffffffffffffffff841661174f576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016107c5565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016107c5565b848310156118ba5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906117eb90826128cc565b6117f5878a6128cc565b6117ff91906128b9565b6118099190612986565b905073ffffffffffffffffffffffffffffffffffffffff8616611862576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016107c5565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016107c5565b6118c485846128cc565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600061195b8561194c84866129c1565b61195690876128b9565b611b15565b95945050505050565b6000818152600283016020526040812061197e9082611d26565b6103798383611b74565b600082815260028401602052604081206119a28382612a7b565b50610ef58484611b80565b6060816000018054806020026020016040519081016040528092919081815260200182805480156119fd57602002820191906000526020600020905b8154815260200190600101908083116119e9575b50505050509050919050565b600061037c82611b8c565b6000606081611a238585611b96565b60008181526002870160205260409020805491925082918190611a45906129d8565b80601f0160208091040260200160405190810160405280929190818152602001828054611a71906129d8565b8015611abe5780601f10611a9357610100808354040283529160200191611abe565b820191906000526020600020905b815481529060010190602001808311611aa157829003601f168201915b5050505050905092509250509250929050565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611ba2565b60006103798373ffffffffffffffffffffffffffffffffffffffff8416611c95565b6000818310611b245781610379565b5090919050565b60006103798383611ce4565b6000670de0b6b3a7640000611b6a837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166129c1565b6103799190612986565b60006103798383611ba2565b60006103798383611c95565b600061037c825490565b60006103798383611cfc565b60008181526001830160205260408120548015611c8b576000611bc66001836128cc565b8554909150600090611bda906001906128cc565b9050818114611c3f576000866000018281548110611bfa57611bfa61274a565b9060005260206000200154905080876000018481548110611c1d57611c1d61274a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611c5057611c50612b95565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061037c565b600091505061037c565b6000818152600183016020526040812054611cdc5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561037c565b50600061037c565b60008181526001830160205260408120541515610379565b6000826000018281548110611d1357611d1361274a565b9060005260206000200154905092915050565b508054611d32906129d8565b6000825580601f10611d42575050565b601f0160209004906000526020600020908101906102ba91905b80821115611d705760008155600101611d5c565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611dc657611dc6611d74565b60405290565b60405160a0810167ffffffffffffffff81118282101715611dc657611dc6611d74565b6040516060810167ffffffffffffffff81118282101715611dc657611dc6611d74565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e5957611e59611d74565b604052919050565b803567ffffffffffffffff81168114611e7957600080fd5b919050565b600082601f830112611e8f57600080fd5b813567ffffffffffffffff811115611ea957611ea9611d74565b611eda60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611e12565b818152846020838601011115611eef57600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115611f2657611f26611d74565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff81168114611e7957600080fd5b600060408284031215611f6657600080fd5b611f6e611da3565b9050611f7982611f30565b81526020820135602082015292915050565b600082601f830112611f9c57600080fd5b81356020611fb1611fac83611f0c565b611e12565b8083825260208201915060208460061b870101935086841115611fd357600080fd5b602086015b84811015611ff857611fea8882611f54565b835291830191604001611fd8565b509695505050505050565b60006020828403121561201557600080fd5b813567ffffffffffffffff8082111561202d57600080fd5b9083019060a0828603121561204157600080fd5b612049611dcc565b8235815261205960208401611e61565b602082015260408301358281111561207057600080fd5b61207c87828601611e7e565b60408301525060608301358281111561209457600080fd5b6120a087828601611e7e565b6060830152506080830135828111156120b857600080fd5b6120c487828601611f8b565b60808301525095945050505050565b80358015158114611e7957600080fd5b600080604083850312156120f657600080fd5b6120ff83611e61565b915061210d602084016120d3565b90509250929050565b6000815180845260005b8181101561213c57602081850181015186830182015201612120565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006103796020830184612116565b60006040828403121561219f57600080fd5b6121a7611da3565b90506121b282611e61565b81526121c060208301611f30565b602082015292915050565b600082601f8301126121dc57600080fd5b813560206121ec611fac83611f0c565b82815260059290921b8401810191818101908684111561220b57600080fd5b8286015b84811015611ff857803567ffffffffffffffff808211156122305760008081fd5b81890191506060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d030112156122695760008081fd5b612271611da3565b61227d8c89860161218d565b81529083013590828211156122925760008081fd5b6122a08c8984870101611e7e565b81890152865250505091830191830161220f565b60008060408084860312156122c857600080fd5b833567ffffffffffffffff808211156122e057600080fd5b818601915086601f8301126122f457600080fd5b81356020612304611fac83611f0c565b8083825260208201915060208460061b87010193508a84111561232657600080fd5b6020860195505b8386101561234e5761233f8b8761218d565b8252948601949082019061232d565b9750505050602086013592508083111561236757600080fd5b5050612375858286016121cb565b9150509250929050565b60008151808452602080850194506020840160005b838110156123c657815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612394565b509495945050505050565b602081526000610379602083018461237f565b6000602082840312156123f657600080fd5b61037982611e61565b604081526000612412604083018561237f565b6020838203818501528185518084528284019150828160051b85010183880160005b83811015612480577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087840301855261246e838351612116565b94860194925090850190600101612434565b50909998505050505050505050565b600082601f8301126124a057600080fd5b813560206124b0611fac83611f0c565b8083825260208201915060208460051b8701019350868411156124d257600080fd5b602086015b84811015611ff8576124e881611f30565b83529183019183016124d7565b60006020828403121561250757600080fd5b813567ffffffffffffffff8082111561251f57600080fd5b908301906040828603121561253357600080fd5b61253b611da3565b82358281111561254a57600080fd5b6125568782860161248f565b82525060208301358281111561256b57600080fd5b6125778782860161248f565b60208301525095945050505050565b6000806040838503121561259957600080fd5b6125a283611e61565b9150602083013567ffffffffffffffff8111156125be57600080fd5b830160a081860312156125d057600080fd5b809150509250929050565b6000602082840312156125ed57600080fd5b61037982611f30565b80356fffffffffffffffffffffffffffffffff81168114611e7957600080fd5b6000602080838503121561262957600080fd5b823567ffffffffffffffff81111561264057600080fd5b8301601f8101851361265157600080fd5b803561265f611fac82611f0c565b81815260a0918202830184019184820191908884111561267e57600080fd5b938501935b8385101561273e578489038181121561269c5760008081fd5b6126a4611def565b6126ad87611e61565b81526126ba8888016120d3565b8882015260406060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0850112156126f25760008081fd5b6126fa611def565b9350612707828a016120d3565b8452612714818a016125f6565b8a85015250612725608089016125f6565b8382015281019190915283529384019391850191612683565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff8416815260606020820152600061279c6060830185612116565b905073ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126127f757600080fd5b83018035915067ffffffffffffffff82111561281257600080fd5b6020019150600681901b3603821315610f2f57600080fd5b60006040828403121561283c57600080fd5b6103798383611f54565b821515815260808101610ef860208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561037c5761037c61288a565b8181038181111561037c5761037c61288a565b6060810161037c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006040828403121561292d57600080fd5b612935611da3565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461296157600080fd5b8152602083015163ffffffff8116811461297a57600080fd5b60208201529392505050565b6000826129bc577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761037c5761037c61288a565b600181811c908216806129ec57607f821691505b602082108103612a25577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105c5576000816000526020600020601f850160051c81016020861015612a545750805b601f850160051c820191505b81811015612a7357828155600101612a60565b505050505050565b815167ffffffffffffffff811115612a9557612a95611d74565b612aa981612aa384546129d8565b84612a2b565b602080601f831160018114612afc5760008415612ac65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612a73565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015612b4957888601518255948401946001909101908401612b2a565b5085821015612b8557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe4d756c7469416767726567617465526174654c696d6974657220312e362e302d646576a164736f6c6343000818000a", } var MultiAggregateRateLimiterABI = MultiAggregateRateLimiterMetaData.ABI var MultiAggregateRateLimiterBin = MultiAggregateRateLimiterMetaData.Bin -func DeployMultiAggregateRateLimiter(auth *bind.TransactOpts, backend bind.ContractBackend, priceRegistry common.Address, authorizedCallers []common.Address) (common.Address, *types.Transaction, *MultiAggregateRateLimiter, error) { +func DeployMultiAggregateRateLimiter(auth *bind.TransactOpts, backend bind.ContractBackend, feeQuoter common.Address, authorizedCallers []common.Address) (common.Address, *types.Transaction, *MultiAggregateRateLimiter, error) { parsed, err := MultiAggregateRateLimiterMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -104,7 +104,7 @@ func DeployMultiAggregateRateLimiter(auth *bind.TransactOpts, backend bind.Contr return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MultiAggregateRateLimiterBin), backend, priceRegistry, authorizedCallers) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MultiAggregateRateLimiterBin), backend, feeQuoter, authorizedCallers) if err != nil { return common.Address{}, nil, nil, err } @@ -301,9 +301,9 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerSession) GetAll return _MultiAggregateRateLimiter.Contract.GetAllRateLimitTokens(&_MultiAggregateRateLimiter.CallOpts, remoteChainSelector) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) GetPriceRegistry(opts *bind.CallOpts) (common.Address, error) { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) GetFeeQuoter(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _MultiAggregateRateLimiter.contract.Call(opts, &out, "getPriceRegistry") + err := _MultiAggregateRateLimiter.contract.Call(opts, &out, "getFeeQuoter") if err != nil { return *new(common.Address), err @@ -315,12 +315,12 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) GetPriceRegis } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) GetPriceRegistry() (common.Address, error) { - return _MultiAggregateRateLimiter.Contract.GetPriceRegistry(&_MultiAggregateRateLimiter.CallOpts) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) GetFeeQuoter() (common.Address, error) { + return _MultiAggregateRateLimiter.Contract.GetFeeQuoter(&_MultiAggregateRateLimiter.CallOpts) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerSession) GetPriceRegistry() (common.Address, error) { - return _MultiAggregateRateLimiter.Contract.GetPriceRegistry(&_MultiAggregateRateLimiter.CallOpts) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCallerSession) GetFeeQuoter() (common.Address, error) { + return _MultiAggregateRateLimiter.Contract.GetFeeQuoter(&_MultiAggregateRateLimiter.CallOpts) } func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterCaller) Owner(opts *bind.CallOpts) (common.Address, error) { @@ -427,16 +427,16 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) On return _MultiAggregateRateLimiter.Contract.OnOutboundMessage(&_MultiAggregateRateLimiter.TransactOpts, destChainSelector, message) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) SetPriceRegistry(opts *bind.TransactOpts, newPriceRegistry common.Address) (*types.Transaction, error) { - return _MultiAggregateRateLimiter.contract.Transact(opts, "setPriceRegistry", newPriceRegistry) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) SetFeeQuoter(opts *bind.TransactOpts, newFeeQuoter common.Address) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.contract.Transact(opts, "setFeeQuoter", newFeeQuoter) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) SetPriceRegistry(newPriceRegistry common.Address) (*types.Transaction, error) { - return _MultiAggregateRateLimiter.Contract.SetPriceRegistry(&_MultiAggregateRateLimiter.TransactOpts, newPriceRegistry) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterSession) SetFeeQuoter(newFeeQuoter common.Address) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.SetFeeQuoter(&_MultiAggregateRateLimiter.TransactOpts, newFeeQuoter) } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) SetPriceRegistry(newPriceRegistry common.Address) (*types.Transaction, error) { - return _MultiAggregateRateLimiter.Contract.SetPriceRegistry(&_MultiAggregateRateLimiter.TransactOpts, newPriceRegistry) +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactorSession) SetFeeQuoter(newFeeQuoter common.Address) (*types.Transaction, error) { + return _MultiAggregateRateLimiter.Contract.SetFeeQuoter(&_MultiAggregateRateLimiter.TransactOpts, newFeeQuoter) } func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { @@ -814,8 +814,8 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseConfig return event, nil } -type MultiAggregateRateLimiterOwnershipTransferRequestedIterator struct { - Event *MultiAggregateRateLimiterOwnershipTransferRequested +type MultiAggregateRateLimiterFeeQuoterSetIterator struct { + Event *MultiAggregateRateLimiterFeeQuoterSet contract *bind.BoundContract event string @@ -826,7 +826,7 @@ type MultiAggregateRateLimiterOwnershipTransferRequestedIterator struct { fail error } -func (it *MultiAggregateRateLimiterOwnershipTransferRequestedIterator) Next() bool { +func (it *MultiAggregateRateLimiterFeeQuoterSetIterator) Next() bool { if it.fail != nil { return false @@ -835,7 +835,7 @@ func (it *MultiAggregateRateLimiterOwnershipTransferRequestedIterator) Next() bo if it.done { select { case log := <-it.logs: - it.Event = new(MultiAggregateRateLimiterOwnershipTransferRequested) + it.Event = new(MultiAggregateRateLimiterFeeQuoterSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -850,7 +850,7 @@ func (it *MultiAggregateRateLimiterOwnershipTransferRequestedIterator) Next() bo select { case log := <-it.logs: - it.Event = new(MultiAggregateRateLimiterOwnershipTransferRequested) + it.Event = new(MultiAggregateRateLimiterFeeQuoterSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -865,51 +865,32 @@ func (it *MultiAggregateRateLimiterOwnershipTransferRequestedIterator) Next() bo } } -func (it *MultiAggregateRateLimiterOwnershipTransferRequestedIterator) Error() error { +func (it *MultiAggregateRateLimiterFeeQuoterSetIterator) Error() error { return it.fail } -func (it *MultiAggregateRateLimiterOwnershipTransferRequestedIterator) Close() error { +func (it *MultiAggregateRateLimiterFeeQuoterSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type MultiAggregateRateLimiterOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log +type MultiAggregateRateLimiterFeeQuoterSet struct { + NewFeeQuoter common.Address + Raw types.Log } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiAggregateRateLimiterOwnershipTransferRequestedIterator, error) { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterFeeQuoterSet(opts *bind.FilterOpts) (*MultiAggregateRateLimiterFeeQuoterSetIterator, error) { - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "FeeQuoterSet") if err != nil { return nil, err } - return &MultiAggregateRateLimiterOwnershipTransferRequestedIterator{contract: _MultiAggregateRateLimiter.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil + return &MultiAggregateRateLimiterFeeQuoterSetIterator{contract: _MultiAggregateRateLimiter.contract, event: "FeeQuoterSet", logs: logs, sub: sub}, nil } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchFeeQuoterSet(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterFeeQuoterSet) (event.Subscription, error) { - logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "FeeQuoterSet") if err != nil { return nil, err } @@ -919,8 +900,8 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchOwners select { case log := <-logs: - event := new(MultiAggregateRateLimiterOwnershipTransferRequested) - if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + event := new(MultiAggregateRateLimiterFeeQuoterSet) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "FeeQuoterSet", log); err != nil { return err } event.Raw = log @@ -941,17 +922,17 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchOwners }), nil } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseOwnershipTransferRequested(log types.Log) (*MultiAggregateRateLimiterOwnershipTransferRequested, error) { - event := new(MultiAggregateRateLimiterOwnershipTransferRequested) - if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseFeeQuoterSet(log types.Log) (*MultiAggregateRateLimiterFeeQuoterSet, error) { + event := new(MultiAggregateRateLimiterFeeQuoterSet) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "FeeQuoterSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -type MultiAggregateRateLimiterOwnershipTransferredIterator struct { - Event *MultiAggregateRateLimiterOwnershipTransferred +type MultiAggregateRateLimiterOwnershipTransferRequestedIterator struct { + Event *MultiAggregateRateLimiterOwnershipTransferRequested contract *bind.BoundContract event string @@ -962,7 +943,7 @@ type MultiAggregateRateLimiterOwnershipTransferredIterator struct { fail error } -func (it *MultiAggregateRateLimiterOwnershipTransferredIterator) Next() bool { +func (it *MultiAggregateRateLimiterOwnershipTransferRequestedIterator) Next() bool { if it.fail != nil { return false @@ -971,7 +952,7 @@ func (it *MultiAggregateRateLimiterOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(MultiAggregateRateLimiterOwnershipTransferred) + it.Event = new(MultiAggregateRateLimiterOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -986,7 +967,7 @@ func (it *MultiAggregateRateLimiterOwnershipTransferredIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(MultiAggregateRateLimiterOwnershipTransferred) + it.Event = new(MultiAggregateRateLimiterOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1001,22 +982,22 @@ func (it *MultiAggregateRateLimiterOwnershipTransferredIterator) Next() bool { } } -func (it *MultiAggregateRateLimiterOwnershipTransferredIterator) Error() error { +func (it *MultiAggregateRateLimiterOwnershipTransferRequestedIterator) Error() error { return it.fail } -func (it *MultiAggregateRateLimiterOwnershipTransferredIterator) Close() error { +func (it *MultiAggregateRateLimiterOwnershipTransferRequestedIterator) Close() error { it.sub.Unsubscribe() return nil } -type MultiAggregateRateLimiterOwnershipTransferred struct { +type MultiAggregateRateLimiterOwnershipTransferRequested struct { From common.Address To common.Address Raw types.Log } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiAggregateRateLimiterOwnershipTransferredIterator, error) { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiAggregateRateLimiterOwnershipTransferRequestedIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1027,14 +1008,14 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterOwner toRule = append(toRule, toItem) } - logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } - return &MultiAggregateRateLimiterOwnershipTransferredIterator{contract: _MultiAggregateRateLimiter.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &MultiAggregateRateLimiterOwnershipTransferRequestedIterator{contract: _MultiAggregateRateLimiter.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -1045,7 +1026,7 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchOwners toRule = append(toRule, toItem) } - logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } @@ -1055,8 +1036,8 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchOwners select { case log := <-logs: - event := new(MultiAggregateRateLimiterOwnershipTransferred) - if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(MultiAggregateRateLimiterOwnershipTransferRequested) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return err } event.Raw = log @@ -1077,17 +1058,17 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchOwners }), nil } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseOwnershipTransferred(log types.Log) (*MultiAggregateRateLimiterOwnershipTransferred, error) { - event := new(MultiAggregateRateLimiterOwnershipTransferred) - if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseOwnershipTransferRequested(log types.Log) (*MultiAggregateRateLimiterOwnershipTransferRequested, error) { + event := new(MultiAggregateRateLimiterOwnershipTransferRequested) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return nil, err } event.Raw = log return event, nil } -type MultiAggregateRateLimiterPriceRegistrySetIterator struct { - Event *MultiAggregateRateLimiterPriceRegistrySet +type MultiAggregateRateLimiterOwnershipTransferredIterator struct { + Event *MultiAggregateRateLimiterOwnershipTransferred contract *bind.BoundContract event string @@ -1098,7 +1079,7 @@ type MultiAggregateRateLimiterPriceRegistrySetIterator struct { fail error } -func (it *MultiAggregateRateLimiterPriceRegistrySetIterator) Next() bool { +func (it *MultiAggregateRateLimiterOwnershipTransferredIterator) Next() bool { if it.fail != nil { return false @@ -1107,7 +1088,7 @@ func (it *MultiAggregateRateLimiterPriceRegistrySetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(MultiAggregateRateLimiterPriceRegistrySet) + it.Event = new(MultiAggregateRateLimiterOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1122,7 +1103,7 @@ func (it *MultiAggregateRateLimiterPriceRegistrySetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(MultiAggregateRateLimiterPriceRegistrySet) + it.Event = new(MultiAggregateRateLimiterOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1137,32 +1118,51 @@ func (it *MultiAggregateRateLimiterPriceRegistrySetIterator) Next() bool { } } -func (it *MultiAggregateRateLimiterPriceRegistrySetIterator) Error() error { +func (it *MultiAggregateRateLimiterOwnershipTransferredIterator) Error() error { return it.fail } -func (it *MultiAggregateRateLimiterPriceRegistrySetIterator) Close() error { +func (it *MultiAggregateRateLimiterOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -type MultiAggregateRateLimiterPriceRegistrySet struct { - NewPriceRegistry common.Address - Raw types.Log +type MultiAggregateRateLimiterOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterPriceRegistrySet(opts *bind.FilterOpts) (*MultiAggregateRateLimiterPriceRegistrySetIterator, error) { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiAggregateRateLimiterOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } - logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "PriceRegistrySet") + logs, sub, err := _MultiAggregateRateLimiter.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } - return &MultiAggregateRateLimiterPriceRegistrySetIterator{contract: _MultiAggregateRateLimiter.contract, event: "PriceRegistrySet", logs: logs, sub: sub}, nil + return &MultiAggregateRateLimiterOwnershipTransferredIterator{contract: _MultiAggregateRateLimiter.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchPriceRegistrySet(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterPriceRegistrySet) (event.Subscription, error) { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } - logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "PriceRegistrySet") + logs, sub, err := _MultiAggregateRateLimiter.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } @@ -1172,8 +1172,8 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchPriceR select { case log := <-logs: - event := new(MultiAggregateRateLimiterPriceRegistrySet) - if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "PriceRegistrySet", log); err != nil { + event := new(MultiAggregateRateLimiterOwnershipTransferred) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -1194,9 +1194,9 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) WatchPriceR }), nil } -func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParsePriceRegistrySet(log types.Log) (*MultiAggregateRateLimiterPriceRegistrySet, error) { - event := new(MultiAggregateRateLimiterPriceRegistrySet) - if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "PriceRegistrySet", log); err != nil { +func (_MultiAggregateRateLimiter *MultiAggregateRateLimiterFilterer) ParseOwnershipTransferred(log types.Log) (*MultiAggregateRateLimiterOwnershipTransferred, error) { + event := new(MultiAggregateRateLimiterOwnershipTransferred) + if err := _MultiAggregateRateLimiter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log @@ -1699,12 +1699,12 @@ func (_MultiAggregateRateLimiter *MultiAggregateRateLimiter) ParseLog(log types. return _MultiAggregateRateLimiter.ParseAuthorizedCallerRemoved(log) case _MultiAggregateRateLimiter.abi.Events["ConfigChanged"].ID: return _MultiAggregateRateLimiter.ParseConfigChanged(log) + case _MultiAggregateRateLimiter.abi.Events["FeeQuoterSet"].ID: + return _MultiAggregateRateLimiter.ParseFeeQuoterSet(log) case _MultiAggregateRateLimiter.abi.Events["OwnershipTransferRequested"].ID: return _MultiAggregateRateLimiter.ParseOwnershipTransferRequested(log) case _MultiAggregateRateLimiter.abi.Events["OwnershipTransferred"].ID: return _MultiAggregateRateLimiter.ParseOwnershipTransferred(log) - case _MultiAggregateRateLimiter.abi.Events["PriceRegistrySet"].ID: - return _MultiAggregateRateLimiter.ParsePriceRegistrySet(log) case _MultiAggregateRateLimiter.abi.Events["RateLimiterConfigUpdated"].ID: return _MultiAggregateRateLimiter.ParseRateLimiterConfigUpdated(log) case _MultiAggregateRateLimiter.abi.Events["TokenAggregateRateLimitAdded"].ID: @@ -1731,6 +1731,10 @@ func (MultiAggregateRateLimiterConfigChanged) Topic() common.Hash { return common.HexToHash("0x9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19") } +func (MultiAggregateRateLimiterFeeQuoterSet) Topic() common.Hash { + return common.HexToHash("0x7c737a8eddf62436489aa3600ed26e75e0a58b0f8c0d266bbcee64358c39fdac") +} + func (MultiAggregateRateLimiterOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } @@ -1739,10 +1743,6 @@ func (MultiAggregateRateLimiterOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (MultiAggregateRateLimiterPriceRegistrySet) Topic() common.Hash { - return common.HexToHash("0xdeaac1a8daeabcc5254b10b54edf3678fdfcd1cea89fe9d364b6285f6ace2df9") -} - func (MultiAggregateRateLimiterRateLimiterConfigUpdated) Topic() common.Hash { return common.HexToHash("0xf14a5415ce6988a9e870a85fff0b9d7b7dd79bbc228cb63cad610daf6f7b6b97") } @@ -1772,7 +1772,7 @@ type MultiAggregateRateLimiterInterface interface { error) - GetPriceRegistry(opts *bind.CallOpts) (common.Address, error) + GetFeeQuoter(opts *bind.CallOpts) (common.Address, error) Owner(opts *bind.CallOpts) (common.Address, error) @@ -1788,7 +1788,7 @@ type MultiAggregateRateLimiterInterface interface { OnOutboundMessage(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage) (*types.Transaction, error) - SetPriceRegistry(opts *bind.TransactOpts, newPriceRegistry common.Address) (*types.Transaction, error) + SetFeeQuoter(opts *bind.TransactOpts, newFeeQuoter common.Address) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) @@ -1812,6 +1812,12 @@ type MultiAggregateRateLimiterInterface interface { ParseConfigChanged(log types.Log) (*MultiAggregateRateLimiterConfigChanged, error) + FilterFeeQuoterSet(opts *bind.FilterOpts) (*MultiAggregateRateLimiterFeeQuoterSetIterator, error) + + WatchFeeQuoterSet(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterFeeQuoterSet) (event.Subscription, error) + + ParseFeeQuoterSet(log types.Log) (*MultiAggregateRateLimiterFeeQuoterSet, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MultiAggregateRateLimiterOwnershipTransferRequestedIterator, error) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) @@ -1824,12 +1830,6 @@ type MultiAggregateRateLimiterInterface interface { ParseOwnershipTransferred(log types.Log) (*MultiAggregateRateLimiterOwnershipTransferred, error) - FilterPriceRegistrySet(opts *bind.FilterOpts) (*MultiAggregateRateLimiterPriceRegistrySetIterator, error) - - WatchPriceRegistrySet(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterPriceRegistrySet) (event.Subscription, error) - - ParsePriceRegistrySet(log types.Log) (*MultiAggregateRateLimiterPriceRegistrySet, error) - FilterRateLimiterConfigUpdated(opts *bind.FilterOpts, remoteChainSelector []uint64) (*MultiAggregateRateLimiterRateLimiterConfigUpdatedIterator, error) WatchRateLimiterConfigUpdated(opts *bind.WatchOpts, sink chan<- *MultiAggregateRateLimiterRateLimiterConfigUpdated, remoteChainSelector []uint64) (event.Subscription, error) diff --git a/core/gethwrappers/ccip/generated/offramp/offramp.go b/core/gethwrappers/ccip/generated/offramp/offramp.go index 0dd7280074..2ce6804b3c 100644 --- a/core/gethwrappers/ccip/generated/offramp/offramp.go +++ b/core/gethwrappers/ccip/generated/offramp/offramp.go @@ -119,7 +119,7 @@ type OffRampCommitReport struct { } type OffRampDynamicConfig struct { - PriceRegistry common.Address + FeeQuoter common.Address PermissionLessExecutionThresholdSeconds uint32 MaxTokenTransferGas uint32 MaxPoolReleaseOrMintGas uint32 @@ -164,7 +164,7 @@ type OffRampUnblessedRoot struct { } var OffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", Bin: "0x6101206040523480156200001257600080fd5b5060405162006c1a38038062006c1a8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615f4462000cd6600039600081816102660152612a010152600081816102370152612ef40152600081816102080152818161142b015261196d0152600081816101d801526125f00152600081816117f3015261183f0152615f446000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063ccd37ba31161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063ccd37ba31461050b578063d2a15d3514610550578063e9d68a8e1461056357600080fd5b8063991a5018116100bd578063991a5018146104c5578063a80036b4146104d8578063c673e584146104eb57600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b8063311cd5131161012f5780635e36480c116101145780635e36480c146103785780637437ff9f1461039857806379ba50971461049457600080fd5b8063311cd513146103495780633f4b04aa1461035c57600080fd5b806306285c691161016057806306285c69146101a4578063181f5a77146102ed5780632d04ab761461033657600080fd5b806304666f9c1461017c57806305d938b514610191575b600080fd5b61018f61018a3660046140af565b6105cc565b005b61018f61019f36600461473b565b6105e0565b61029660408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102e49190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103296040518060400160405280601181526020017f4f666652616d7020312e362e302d64657600000000000000000000000000000081525081565b6040516102e491906148b6565b61018f610344366004614961565b610785565b61018f610357366004614a14565b610b5c565b60095460405167ffffffffffffffff90911681526020016102e4565b61038b610386366004614a68565b610bc5565b6040516102e49190614ac5565b6104376040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102e49190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610c1b565b61018f610177366004614ad3565b6000546040516001600160a01b0390911681526020016102e4565b61018f6104d3366004614b22565b610cd9565b61018f6104e6366004614b96565b610cea565b6104fe6104f9366004614c03565b61105d565b6040516102e49190614c63565b610542610519366004614cd8565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102e4565b61018f61055e366004614d02565b6111bb565b610576610571366004614d77565b611275565b6040516102e49190614d92565b61018f610591366004614de0565b611382565b61018f6105a4366004614e65565b611393565b6105bc6105b7366004614fa3565b6113d5565b60405190151581526020016102e4565b6105d4611496565b6105dd816114f2565b50565b6105e86117f0565b815181518114610624576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8181101561077557600084828151811061064357610643614fbc565b6020026020010151905060008160200151519050600085848151811061066b5761066b614fbc565b60200260200101519050805182146106af576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b828110156107665760008282815181106106ce576106ce614fbc565b602002602001015190508060001461075d57846020015182815181106106f6576106f6614fbc565b60200260200101516080015181101561075d5784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064015b60405180910390fd5b506001016106b2565b50505050806001019050610627565b506107808383611871565b505050565b600061079387890189615142565b805151519091501515806107ac57508051602001515115155b156108ac5760095460208a01359067ffffffffffffffff8083169116101561086b576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261083492910161536a565b600060405180830381600087803b15801561084e57600080fd5b505af1158015610862573d6000803e3d6000fd5b505050506108aa565b8160200151516000036108aa576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b816020015151811015610aa5576000826020015182815181106108d4576108d4614fbc565b602002602001015190506000816000015190506108f081611921565b60006108fb82611a23565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061093f575060208084015190810151905167ffffffffffffffff9182169116115b1561097f57825160208401516040517feefb0cac00000000000000000000000000000000000000000000000000000000815261075492919060040161537d565b6040830151806109bb576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff16600090815260086020908152604080832084845290915290205415610a2e5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101829052604401610754565b6020808501510151610a419060016153c8565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff9283160217909255925116600090815260086020908152604080832094835293905291909120429055506001016108af565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610ad591906153f0565b60405180910390a1610b5160008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b9250611a8a915050565b505050505050505050565b610b9c610b6b8284018461548d565b6040805160008082526020820190925290610b96565b6060815260200190600190039081610b815790505b50611871565b604080516000808252602082019092529050610bbf600185858585866000611a8a565b50505050565b6000610bd3600160046154c2565b6002610be06080856154eb565b67ffffffffffffffff16610bf49190615512565b610bfe8585611e01565b901c166003811115610c1257610c12614a9b565b90505b92915050565b6001546001600160a01b03163314610c755760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610754565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ce1611496565b6105dd81611e48565b333014610d23576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281610d60565b6040805180820190915260008082526020820152815260200190600190039081610d395790505b5060a08501515190915015610d9457610d918460a00151856020015186606001518760000151602001518787611fae565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff1681830152808701518351600094840192610dd09291016148b6565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015610edd576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a190610e4a9085906004016155cb565b600060405180830381600087803b158015610e6457600080fd5b505af1925050508015610e75575060015b610edd573d808015610ea3576040519150601f19603f3d011682016040523d82523d6000602084013e610ea8565b606091505b50806040517f09c2532500000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b604086015151158015610ef257506080860151155b80610f09575060608601516001600160a01b03163b155b80610f4957506060860151610f47906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120cd565b155b15610f5657505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf9798392610fce92899261138892916004016155de565b6000604051808303816000875af1158015610fed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611015919081019061561a565b50915091508161105357806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b5050505050505050565b6110a06040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c08201529485529182018054845181840281018401909552808552929385830193909283018282801561114957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161112b575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156111ab57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161118d575b5050505050815250509050919050565b6111c3611496565b60005b818110156107805760008383838181106111e2576111e2614fbc565b9050604002018036038101906111f891906156b0565b905061120781602001516113d5565b61126c57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b506001016111c6565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191611302906156e9565b80601f016020809104026020016040519081016040528092919081815260200182805461132e906156e9565b80156111ab5780601f10611350576101008083540402835291602001916111ab565b820191906000526020600020905b81548152906001019060200180831161135e57505050919092525091949350505050565b61138a611496565b6105dd816120e9565b61139b611496565b60005b81518110156113d1576113c98282815181106113bc576113bc614fbc565b602002602001015161219f565b60010161139e565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611472573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c159190615723565b6000546001600160a01b031633146114f05760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610754565b565b60005b81518110156113d157600082828151811061151257611512614fbc565b602002602001015190506000816020015190508067ffffffffffffffff16600003611569576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611591576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115bc906156e9565b80601f01602080910402602001604051908101604052809291908181526020018280546115e8906156e9565b80156116355780601f1061160a57610100808354040283529160200191611635565b820191906000526020600020905b81548152906001019060200180831161161857829003601f168201915b5050505050905060008460600151905081516000036116ed578051600003611670576040516342bcdf7f60e11b815260040160405180910390fd5b6001830161167e8282615788565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611740565b8080519060200120828051906020012014611740576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610754565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117d8908690615848565b60405180910390a250505050508060010190506114f5565b467f0000000000000000000000000000000000000000000000000000000000000000146114f0576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610754565b81516000036118ab576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b845181101561191a576119128582815181106118e0576118e0614fbc565b60200260200101518461190c578583815181106118ff576118ff614fbc565b60200260200101516124e3565b836124e3565b6001016118c2565b5050505050565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa1580156119bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e09190615723565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610754565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610c15576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610754565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611ae98760a4615916565b9050826060015115611b31578451611b02906020615512565b8651611b0f906020615512565b611b1a9060a0615916565b611b249190615916565b611b2e9082615916565b90505b368114611b73576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610754565b5081518114611bbb5781516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610754565b611bc36117f0565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611c1157611c11614a9b565b6002811115611c2257611c22614a9b565b9052509050600281602001516002811115611c3f57611c3f614a9b565b148015611c935750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611c7b57611c7b614fbc565b6000918252602090912001546001600160a01b031633145b611cc9576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611dab576020820151611ce4906001615929565b60ff16855114611d20576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611d5b576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611d6d929190615942565b604051908190038120611d84918b90602001615952565b604051602081830303815290604052805190602001209050611da98a82888888612c86565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b67ffffffffffffffff8216600090815260076020526040812081611e26608085615966565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b80516001600160a01b0316611e70576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fca57611fca613ec6565b60405190808252806020026020018201604052801561200f57816020015b6040805180820190915260008082526020820152815260200190600190039081611fe85790505b50905060005b87518110156120c15761209c88828151811061203357612033614fbc565b602002602001015188888888888781811061205057612050614fbc565b9050602002810190612062919061598d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9392505050565b8282815181106120ae576120ae614fbc565b6020908102919091010152600101612015565b505b9695505050505050565b60006120d883613238565b8015610c125750610c12838361329c565b336001600160a01b038216036121415760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610754565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ca576000604051631b3fab5160e11b815260040161075491906159f2565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223757606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff90921691909117905561228c565b6060840151600182015460ff620100009091041615159015151461228c576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff84166004820152602401610754565b60a08401518051601f60ff821611156122bb576001604051631b3fab5160e11b815260040161075491906159f2565b612321858560030180548060200260200160405190810160405280929190818152602001828054801561231757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122f9575b5050505050613357565b8560600151156124505761238f8585600201805480602002602001604051908101604052809291908181526020018280548015612317576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122f9575050505050613357565b608086015180516123a99060028701906020840190613e20565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f1015612409576002604051631b3fab5160e11b815260040161075491906159f2565b6040880151612419906003615a0c565b60ff168160ff1611612441576003604051631b3fab5160e11b815260040161075491906159f2565b61244d878360016133c0565b50505b61245c858360026133c0565b81516124719060038601906020850190613e20565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ca938a939260028b01929190615a28565b60405180910390a16124db85613540565b505050505050565b81516124ee81611921565b60006124f982611a23565b602085015151909150600081900361253c576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461257a576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561259557612595613ec6565b6040519080825280602002602001820160405280156125be578160200160208202803683370190505b50905060005b82811015612733576000876020015182815181106125e4576125e4614fbc565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461267757805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610754565b61270d8186600101805461268a906156e9565b80601f01602080910402602001604051908101604052809291908181526020018280546126b6906156e9565b80156127035780601f106126d857610100808354040283529160200191612703565b820191906000526020600020905b8154815290600101906020018083116126e657829003601f168201915b505050505061355c565b83838151811061271f5761271f614fbc565b6020908102919091010152506001016125c4565b50600061274a858389606001518a6080015161367e565b905080600003612792576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610754565b8551151560005b84811015610b515760005a905060008a6020015183815181106127be576127be614fbc565b6020026020010151905060006127dc8a836000015160600151610bc5565b905060008160038111156127f2576127f2614a9b565b148061280f5750600381600381111561280d5761280d614a9b565b145b612867578151606001516040805167ffffffffffffffff808e16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a1505050612c7e565b841561293757600454600090600160a01b900463ffffffff1661288a88426154c2565b11905080806128aa575060038260038111156128a8576128a8614a9b565b145b6128ec576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8c166004820152602401610754565b8b85815181106128fe576128fe614fbc565b6020026020010151600014612931578b858151811061291f5761291f614fbc565b60200260200101518360800181815250505b50612998565b600081600381111561294b5761294b614a9b565b14612998578151606001516040805167ffffffffffffffff808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612857565b81516080015167ffffffffffffffff1615612a875760008160038111156129c1576129c1614a9b565b03612a875781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612a38928f929190600401615ad4565b6020604051808303816000875af1158015612a57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7b9190615723565b612a8757505050612c7e565b60008c604001518581518110612a9f57612a9f614fbc565b6020026020010151905080518360a001515114612b03578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808e1660048301529091166024820152604401610754565b612b178b84600001516060015160016136d4565b600080612b24858461377c565b91509150612b3b8d866000015160600151846136d4565b8715612bab576003826003811115612b5557612b55614a9b565b03612bab576000846003811115612b6e57612b6e614a9b565b14612bab578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261075491908390600401615b01565b6002826003811115612bbf57612bbf614a9b565b14612c19576003826003811115612bd857612bd8614a9b565b14612c19578451606001516040517f926c5a3e000000000000000000000000000000000000000000000000000000008152610754918f918590600401615b1a565b8451805160609091015167ffffffffffffffff908116908f167fdc8ccbc35e0eebd81239bcd1971fcd53c7eb34034880142a0f43c809a458732f85855a612c60908d6154c2565b604051612c6f93929190615b40565b60405180910390a45050505050505b600101612799565b612c8e613e92565b835160005b81811015611053576000600188868460208110612cb257612cb2614fbc565b612cbf91901a601b615929565b898581518110612cd157612cd1614fbc565b6020026020010151898681518110612ceb57612ceb614fbc565b602002602001015160405160008152602001604052604051612d29949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612d4b573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b03851683528152858220858701909652855480841686529397509095509293928401916101009004166002811115612dac57612dac614a9b565b6002811115612dbd57612dbd614a9b565b9052509050600181602001516002811115612dda57612dda614a9b565b14612e11576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f8110612e2857612e28614fbc565b602002015115612e64576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f8110612e7f57612e7f614fbc565b911515602090920201525050600101612c93565b60408051808201909152600080825260208201526000612eb68760200151613846565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5f9190615b70565b90506001600160a01b0381161580612fa75750612fa56001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120cd565b155b15612fe9576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610754565b600454600090819061300b9089908690600160e01b900463ffffffff166138ec565b9150915060008060006130d86040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b8152506040516024016130899190615b8d565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a1a565b9250925092508261311757816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b815160201461315f5781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610754565b6000828060200190518101906131759190615c5a565b9050866001600160a01b03168c6001600160a01b03161461320a5760006131a68d8a6131a1868a6154c2565b6138ec565b509050868110806131c05750816131bd88836154c2565b14155b15613208576040517fa966e21f000000000000000000000000000000000000000000000000000000008152600481018390526024810188905260448101829052606401610754565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613264827f01ffc9a70000000000000000000000000000000000000000000000000000000061329c565b8015610c155750613295827fffffffff0000000000000000000000000000000000000000000000000000000061329c565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015613340575060208210155b801561334c5750600081115b979650505050505050565b60005b81518110156107805760ff83166000908152600360205260408120835190919084908490811061338c5761338c614fbc565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161335a565b60005b82518160ff161015610bbf576000838260ff16815181106133e6576133e6614fbc565b602002602001015190506000600281111561340357613403614a9b565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561344257613442614a9b565b14613463576004604051631b3fab5160e11b815260040161075491906159f2565b6001600160a01b0381166134a3576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134c9576134c9614a9b565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561352657613526614a9b565b0217905550905050508061353990615c73565b90506133c3565b60ff81166105dd576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936135a2937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c92565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135eb9794969395929491939101615cc5565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136229190615dd7565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061368c858585613b40565b9050613697816113d5565b6136a55760009150506136cc565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026136e36080856154eb565b67ffffffffffffffff166136f79190615512565b905060006137058585611e01565b905081613714600160046154c2565b901b19168183600381111561372b5761372b614a9b565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161375a608088615966565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fa80036b4000000000000000000000000000000000000000000000000000000008152600090606090309063a80036b4906137c09087908790600401615e37565b600060405180830381600087803b1580156137da57600080fd5b505af19250505080156137eb575060015b61382a573d808015613819576040519150601f19603f3d011682016040523d82523d6000602084013e61381e565b606091505b5060039250905061383f565b50506040805160208101909152600081526002905b9250929050565b6000815160201461388557816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b60008280602001905181019061389b9190615c5a565b90506001600160a01b038111806138b3575061040081105b15610c1557826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b60008060008060006139668860405160240161391791906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a1a565b925092509250826139a557816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b60208251146139ed5781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610754565b81806020019051810190613a019190615c5a565b613a0b82886154c2565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a3d57613a3d613ec6565b6040519080825280601f01601f191660200182016040528015613a67576020820181803683370190505b509150863b613a9a577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613acd577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613b06577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b295750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b81576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b9557506101018111155b613bb2576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bdc576040516309bde33960e01b815260040160405180910390fd5b80600003613c095786600081518110613bf757613bf7614fbc565b60200260200101519350505050613dd8565b60008167ffffffffffffffff811115613c2457613c24613ec6565b604051908082528060200260200182016040528015613c4d578160200160208202803683370190505b50905060008080805b85811015613d775760006001821b8b811603613cb15788851015613c9a578c5160018601958e918110613c8b57613c8b614fbc565b60200260200101519050613cd3565b8551600185019487918110613c8b57613c8b614fbc565b8b5160018401938d918110613cc857613cc8614fbc565b602002602001015190505b600089861015613d03578d5160018701968f918110613cf457613cf4614fbc565b60200260200101519050613d25565b8651600186019588918110613d1a57613d1a614fbc565b602002602001015190505b82851115613d46576040516309bde33960e01b815260040160405180910390fd5b613d508282613ddf565b878481518110613d6257613d62614fbc565b60209081029190910101525050600101613c56565b506001850382148015613d8957508683145b8015613d9457508581145b613db1576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613dc657613dc6614fbc565b60200260200101519750505050505050505b9392505050565b6000818310613df757613df28284613dfd565b610c12565b610c1283835b604080516001602082015290810183905260608101829052600090608001613660565b828054828255906000526020600020908101928215613e82579160200282015b82811115613e82578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e40565b50613e8e929150613eb1565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e8e5760008155600101613eb2565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613eff57613eff613ec6565b60405290565b60405160a0810167ffffffffffffffff81118282101715613eff57613eff613ec6565b60405160c0810167ffffffffffffffff81118282101715613eff57613eff613ec6565b6040805190810167ffffffffffffffff81118282101715613eff57613eff613ec6565b6040516060810167ffffffffffffffff81118282101715613eff57613eff613ec6565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fba57613fba613ec6565b604052919050565b600067ffffffffffffffff821115613fdc57613fdc613ec6565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461401357600080fd5b919050565b80151581146105dd57600080fd5b803561401381614018565b600067ffffffffffffffff82111561404b5761404b613ec6565b50601f01601f191660200190565b600082601f83011261406a57600080fd5b813561407d61407882614031565b613f91565b81815284602083860101111561409257600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140c257600080fd5b823567ffffffffffffffff808211156140da57600080fd5b818501915085601f8301126140ee57600080fd5b81356140fc61407882613fc2565b81815260059190911b8301840190848101908883111561411b57600080fd5b8585015b838110156141c1578035858111156141375760008081fd5b86016080818c03601f190181131561414f5760008081fd5b614157613edc565b8983013561416481613fe6565b81526040614173848201613ffb565b8b83015260608085013561418681614018565b8383015292840135928984111561419f57600091508182fd5b6141ad8f8d86880101614059565b90830152508552505091860191860161411f565b5098975050505050505050565b600060a082840312156141e057600080fd5b6141e8613f05565b9050813581526141fa60208301613ffb565b602082015261420b60408301613ffb565b604082015261421c60608301613ffb565b606082015261422d60808301613ffb565b608082015292915050565b803561401381613fe6565b600082601f83011261425457600080fd5b8135602061426461407883613fc2565b82815260059290921b8401810191818101908684111561428357600080fd5b8286015b848110156120c157803567ffffffffffffffff808211156142a85760008081fd5b818901915060a080601f19848d030112156142c35760008081fd5b6142cb613f05565b87840135838111156142dd5760008081fd5b6142eb8d8a83880101614059565b825250604080850135848111156143025760008081fd5b6143108e8b83890101614059565b8a84015250606080860135858111156143295760008081fd5b6143378f8c838a0101614059565b8385015250608091508186013581840152508285013592508383111561435d5760008081fd5b61436b8d8a85880101614059565b908201528652505050918301918301614287565b6000610140828403121561439257600080fd5b61439a613f28565b90506143a683836141ce565b815260a082013567ffffffffffffffff808211156143c357600080fd5b6143cf85838601614059565b602084015260c08401359150808211156143e857600080fd5b6143f485838601614059565b604084015261440560e08501614238565b6060840152610100840135608084015261012084013591508082111561442a57600080fd5b5061443784828501614243565b60a08301525092915050565b600082601f83011261445457600080fd5b8135602061446461407883613fc2565b82815260059290921b8401810191818101908684111561448357600080fd5b8286015b848110156120c157803567ffffffffffffffff8111156144a75760008081fd5b6144b58986838b010161437f565b845250918301918301614487565b600082601f8301126144d457600080fd5b813560206144e461407883613fc2565b82815260059290921b8401810191818101908684111561450357600080fd5b8286015b848110156120c157803567ffffffffffffffff8082111561452757600080fd5b818901915089603f83011261453b57600080fd5b8582013561454b61407882613fc2565b81815260059190911b830160400190878101908c83111561456b57600080fd5b604085015b838110156145a45780358581111561458757600080fd5b6145968f6040838a0101614059565b845250918901918901614570565b50875250505092840192508301614507565b600082601f8301126145c757600080fd5b813560206145d761407883613fc2565b8083825260208201915060208460051b8701019350868411156145f957600080fd5b602086015b848110156120c157803583529183019183016145fe565b600082601f83011261462657600080fd5b8135602061463661407883613fc2565b82815260059290921b8401810191818101908684111561465557600080fd5b8286015b848110156120c157803567ffffffffffffffff8082111561467a5760008081fd5b818901915060a080601f19848d030112156146955760008081fd5b61469d613f05565b6146a8888501613ffb565b8152604080850135848111156146be5760008081fd5b6146cc8e8b83890101614443565b8a84015250606080860135858111156146e55760008081fd5b6146f38f8c838a01016144c3565b838501525060809150818601358581111561470e5760008081fd5b61471c8f8c838a01016145b6565b9184019190915250919093013590830152508352918301918301614659565b600080604080848603121561474f57600080fd5b833567ffffffffffffffff8082111561476757600080fd5b61477387838801614615565b945060209150818601358181111561478a57600080fd5b8601601f8101881361479b57600080fd5b80356147a961407882613fc2565b81815260059190911b8201840190848101908a8311156147c857600080fd5b8584015b83811015614854578035868111156147e45760008081fd5b8501603f81018d136147f65760008081fd5b8781013561480661407882613fc2565b81815260059190911b82018a0190898101908f8311156148265760008081fd5b928b01925b828410156148445783358252928a0192908a019061482b565b86525050509186019186016147cc565b50809750505050505050509250929050565b60005b83811015614881578181015183820152602001614869565b50506000910152565b600081518084526148a2816020860160208601614866565b601f01601f19169290920160200192915050565b602081526000610c12602083018461488a565b8060608101831015610c1557600080fd5b60008083601f8401126148ec57600080fd5b50813567ffffffffffffffff81111561490457600080fd5b60208301915083602082850101111561383f57600080fd5b60008083601f84011261492e57600080fd5b50813567ffffffffffffffff81111561494657600080fd5b6020830191508360208260051b850101111561383f57600080fd5b60008060008060008060008060e0898b03121561497d57600080fd5b6149878a8a6148c9565b9750606089013567ffffffffffffffff808211156149a457600080fd5b6149b08c838d016148da565b909950975060808b01359150808211156149c957600080fd5b6149d58c838d0161491c565b909750955060a08b01359150808211156149ee57600080fd5b506149fb8b828c0161491c565b999c989b50969995989497949560c00135949350505050565b600080600060808486031215614a2957600080fd5b614a3385856148c9565b9250606084013567ffffffffffffffff811115614a4f57600080fd5b614a5b868287016148da565b9497909650939450505050565b60008060408385031215614a7b57600080fd5b614a8483613ffb565b9150614a9260208401613ffb565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614ac157614ac1614a9b565b9052565b60208101610c158284614ab1565b600060208284031215614ae557600080fd5b813567ffffffffffffffff811115614afc57600080fd5b820160a08185031215613dd857600080fd5b803563ffffffff8116811461401357600080fd5b600060a08284031215614b3457600080fd5b614b3c613f05565b8235614b4781613fe6565b8152614b5560208401614b0e565b6020820152614b6660408401614b0e565b6040820152614b7760608401614b0e565b60608201526080830135614b8a81613fe6565b60808201529392505050565b600080600060408486031215614bab57600080fd5b833567ffffffffffffffff80821115614bc357600080fd5b614bcf8783880161437f565b94506020860135915080821115614be557600080fd5b50614a5b8682870161491c565b803560ff8116811461401357600080fd5b600060208284031215614c1557600080fd5b610c1282614bf2565b60008151808452602080850194506020840160005b83811015614c585781516001600160a01b031687529582019590820190600101614c33565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614cb260e0840182614c1e565b90506040840151601f198483030160c0850152614ccf8282614c1e565b95945050505050565b60008060408385031215614ceb57600080fd5b614cf483613ffb565b946020939093013593505050565b60008060208385031215614d1557600080fd5b823567ffffffffffffffff80821115614d2d57600080fd5b818501915085601f830112614d4157600080fd5b813581811115614d5057600080fd5b8660208260061b8501011115614d6557600080fd5b60209290920196919550909350505050565b600060208284031215614d8957600080fd5b610c1282613ffb565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136cc60a084018261488a565b600060208284031215614df257600080fd5b8135613dd881613fe6565b600082601f830112614e0e57600080fd5b81356020614e1e61407883613fc2565b8083825260208201915060208460051b870101935086841115614e4057600080fd5b602086015b848110156120c1578035614e5881613fe6565b8352918301918301614e45565b60006020808385031215614e7857600080fd5b823567ffffffffffffffff80821115614e9057600080fd5b818501915085601f830112614ea457600080fd5b8135614eb261407882613fc2565b81815260059190911b83018401908481019088831115614ed157600080fd5b8585015b838110156141c157803585811115614eec57600080fd5b860160c0818c03601f19011215614f035760008081fd5b614f0b613f28565b8882013581526040614f1e818401614bf2565b8a8301526060614f2f818501614bf2565b8284015260809150614f42828501614026565b9083015260a08381013589811115614f5a5760008081fd5b614f688f8d83880101614dfd565b838501525060c0840135915088821115614f825760008081fd5b614f908e8c84870101614dfd565b9083015250845250918601918601614ed5565b600060208284031215614fb557600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b80356001600160e01b038116811461401357600080fd5b600082601f830112614ffa57600080fd5b8135602061500a61407883613fc2565b82815260069290921b8401810191818101908684111561502957600080fd5b8286015b848110156120c157604081890312156150465760008081fd5b61504e613f4b565b61505782613ffb565b8152615064858301614fd2565b8186015283529183019160400161502d565b600082601f83011261508757600080fd5b8135602061509761407883613fc2565b82815260079290921b840181019181810190868411156150b657600080fd5b8286015b848110156120c15780880360808112156150d45760008081fd5b6150dc613f6e565b6150e583613ffb565b8152604080601f19840112156150fb5760008081fd5b615103613f4b565b9250615110878501613ffb565b835261511d818501613ffb565b83880152818701929092526060830135918101919091528352918301916080016150ba565b6000602080838503121561515557600080fd5b823567ffffffffffffffff8082111561516d57600080fd5b8185019150604080838803121561518357600080fd5b61518b613f4b565b83358381111561519a57600080fd5b84016040818a0312156151ac57600080fd5b6151b4613f4b565b8135858111156151c357600080fd5b8201601f81018b136151d457600080fd5b80356151e261407882613fc2565b81815260069190911b8201890190898101908d83111561520157600080fd5b928a01925b828410156152515787848f03121561521e5760008081fd5b615226613f4b565b843561523181613fe6565b815261523e858d01614fd2565b818d0152825292870192908a0190615206565b84525050508187013593508484111561526957600080fd5b6152758a858401614fe9565b818801528252508385013591508282111561528f57600080fd5b61529b88838601615076565b85820152809550505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b8181101561530457835180516001600160a01b031684528501516001600160e01b03168584015292840192918501916001016152cd565b50508583015187820388850152805180835290840192506000918401905b8083101561535e578351805167ffffffffffffffff1683528501516001600160e01b031685830152928401926001929092019190850190615322565b50979650505050505050565b602081526000610c1260208301846152ad565b67ffffffffffffffff8316815260608101613dd86020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153e9576153e96153b2565b5092915050565b60006020808352606084516040808487015261540f60608701836152ad565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141c157845167ffffffffffffffff81511683528781015161546f89850182805167ffffffffffffffff908116835260209182015116910152565b50840151828701529386019360019290920191608090910190615430565b60006020828403121561549f57600080fd5b813567ffffffffffffffff8111156154b657600080fd5b6136cc84828501614615565b81810381811115610c1557610c156153b2565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff80841680615506576155066154d5565b92169190910692915050565b8082028115828204841417610c1557610c156153b2565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261555d60a087018261488a565b905060608501518682036060880152615576828261488a565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561535e57835180516001600160a01b0316835286015186830152928501926001929092019190840190615599565b602081526000610c126020830184615529565b6080815260006155f16080830187615529565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561562f57600080fd5b835161563a81614018565b602085015190935067ffffffffffffffff81111561565757600080fd5b8401601f8101861361566857600080fd5b805161567661407882614031565b81815287602083850101111561568b57600080fd5b61569c826020830160208601614866565b809450505050604084015190509250925092565b6000604082840312156156c257600080fd5b6156ca613f4b565b6156d383613ffb565b8152602083013560208201528091505092915050565b600181811c908216806156fd57607f821691505b60208210810361571d57634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561573557600080fd5b8151613dd881614018565b601f821115610780576000816000526020600020601f850160051c810160208610156157695750805b601f850160051c820191505b818110156124db57828155600101615775565b815167ffffffffffffffff8111156157a2576157a2613ec6565b6157b6816157b084546156e9565b84615740565b602080601f8311600181146157eb57600084156157d35750858301515b600019600386901b1c1916600185901b1785556124db565b600085815260208120601f198616915b8281101561581a578886015182559484019460019091019084016157fb565b50858210156158385787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c1660608501525060018085016080808601526000815461589a816156e9565b8060a089015260c060018316600081146158bb57600181146158d757615907565b60ff19841660c08b015260c083151560051b8b01019450615907565b85600052602060002060005b848110156158fe5781548c82018501529088019089016158e3565b8b0160c0019550505b50929998505050505050505050565b80820180821115610c1557610c156153b2565b60ff8181168382160190811115610c1557610c156153b2565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff80841680615981576159816154d5565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126159c257600080fd5b83018035915067ffffffffffffffff8211156159dd57600080fd5b60200191503681900382131561383f57600080fd5b6020810160058310615a0657615a06614a9b565b91905290565b60ff81811683821602908116908181146153e9576153e96153b2565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a805784546001600160a01b031683526001948501949284019201615a5b565b50508481036060860152865180825290820192508187019060005b81811015615ac05782516001600160a01b031685529383019391830191600101615a9b565b50505060ff851660808501525090506120c3565b600067ffffffffffffffff808616835280851660208401525060606040830152614ccf606083018461488a565b8281526040602082015260006136cc604083018461488a565b67ffffffffffffffff848116825283166020820152606081016136cc6040830184614ab1565b615b4a8185614ab1565b606060208201526000615b60606083018561488a565b9050826040830152949350505050565b600060208284031215615b8257600080fd5b8151613dd881613fe6565b6020815260008251610100806020850152615bac61012085018361488a565b91506020850151615bc9604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615c0360a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615c20848361488a565b935060c08701519150808685030160e0870152615c3d848361488a565b935060e08701519150808685030183870152506120c3838261488a565b600060208284031215615c6c57600080fd5b5051919050565b600060ff821660ff8103615c8957615c896153b2565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c3608083018461488a565b86815260c060208201526000615cde60c083018861488a565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615dca57601f19868403018952815160a08151818652615d5b8287018261488a565b9150508582015185820387870152615d73828261488a565b91505060408083015186830382880152615d8d838261488a565b92505050606080830151818701525060808083015192508582038187015250615db6818361488a565b9a86019a9450505090830190600101615d35565b5090979650505050505050565b602081526000610c126020830184615d18565b60008282518085526020808601955060208260051b8401016020860160005b84811015615dca57601f19868403018952615e2583835161488a565b98840198925090830190600101615e09565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e9f61018085018361488a565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615edc848361488a565b935060608801519150615efb6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615f228282615d18565b9150508281036020840152614ccf8185615dea56fea164736f6c6343000818000a", } diff --git a/core/gethwrappers/ccip/generated/onramp/onramp.go b/core/gethwrappers/ccip/generated/onramp/onramp.go index 46804a0e47..db21305dc8 100644 --- a/core/gethwrappers/ccip/generated/onramp/onramp.go +++ b/core/gethwrappers/ccip/generated/onramp/onramp.go @@ -81,7 +81,7 @@ type OnRampDestChainConfigArgs struct { } type OnRampDynamicConfig struct { - PriceRegistry common.Address + FeeQuoter common.Address MessageValidator common.Address FeeAggregator common.Address } @@ -94,7 +94,7 @@ type OnRampStaticConfig struct { } var OnRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Bin: "0x6101006040523480156200001257600080fd5b506040516200382d3803806200382d83398101604081905262000035916200069c565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000186565b505083516001600160401b031615905080620000e6575060208301516001600160a01b0316155b80620000fd575060408301516001600160a01b0316155b8062000114575060608301516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b82516001600160401b031660805260208301516001600160a01b0390811660a0526040840151811660c05260608401511660e052620001728262000231565b6200017d816200036d565b5050506200079c565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316158062000254575060408101516001600160a01b0316155b1562000273576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b03938416179091556020808401805160038054851691861691909117905560408086018051600480549096169087161790945580516080808201835280516001600160401b031680835260a08051891684880190815260c080518b1686880190815260e080518d166060988901908152895196875293518d169a86019a909a52518b169684019690965251891693820193909352885188169181019190915292518616908301529251909316918301919091527f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558910160405180910390a150565b60005b8151811015620004aa57600082828151811062000391576200039162000786565b602002602001015190506000838381518110620003b257620003b262000786565b6020026020010151600001519050806001600160401b0316600003620003f75760405163c35aa79d60e01b81526001600160401b038216600482015260240162000083565b6040805180820182526001600160401b03838116600081815260056020818152868320805480871688528a8301516001600160a01b03908116848a019081529587905293835287518551851668010000000000000000026001600160e01b0319909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a250505080600101905062000370565b5050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620004e957620004e9620004ae565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200051a576200051a620004ae565b604052919050565b80516001600160401b03811681146200053a57600080fd5b919050565b6001600160a01b03811681146200055557600080fd5b50565b6000606082840312156200056b57600080fd5b604051606081016001600160401b0381118282101715620005905762000590620004ae565b80604052508091508251620005a5816200053f565b81526020830151620005b7816200053f565b60208201526040830151620005cc816200053f565b6040919091015292915050565b600082601f830112620005eb57600080fd5b815160206001600160401b03821115620006095762000609620004ae565b62000619818360051b01620004ef565b82815260069290921b840181019181810190868411156200063957600080fd5b8286015b84811015620006915760408189031215620006585760008081fd5b62000662620004c4565b6200066d8262000522565b8152848201516200067e816200053f565b818601528352918301916040016200063d565b509695505050505050565b6000806000838503610100811215620006b457600080fd5b6080811215620006c357600080fd5b50604051608081016001600160401b038082118383101715620006ea57620006ea620004ae565b81604052620006f98762000522565b8352602087015191506200070d826200053f565b8160208401526040870151915062000725826200053f565b816040840152606087015191506200073d826200053f565b81606084015282955062000755886080890162000558565b945060e08701519250808311156200076c57600080fd5b50506200077c86828701620005d9565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e05161301862000815600039600081816101eb015281816108a201526116700152600081816101af01528181610dc60152611649015260008181610173015281816104c4015261161f01526000818161014301528181610cec0152818161121101526115f201526130186000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637437ff9f11610097578063d77d5ed011610066578063d77d5ed0146103ba578063df0aa9e914610406578063f2fde38b14610419578063fbca3b741461042c57600080fd5b80637437ff9f146102fb57806379ba5097146103685780638da5cb5b146103705780639041be3d1461038e57600080fd5b806320487ded116100d357806320487ded1461028757806334d560e4146102a85780633a019940146102bb57806348a98aa4146102c357600080fd5b80630242cf60146100fa57806306285c691461010f578063181f5a771461023e575b600080fd5b61010d610108366004612098565b61044c565b005b61022860408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b604051610235919061215b565b60405180910390f35b61027a6040518060400160405280601081526020017f4f6e52616d7020312e362e302d6465760000000000000000000000000000000081525081565b6040516102359190612220565b61029a61029536600461224b565b610460565b604051908152602001610235565b61010d6102b63660046122ab565b610619565b61010d61062a565b6102d66102d136600461231d565b61085a565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610235565b61035b6040805160608101825260008082526020820181905291810191909152506040805160608101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454169181019190915290565b6040516102359190612356565b61010d61090f565b60005473ffffffffffffffffffffffffffffffffffffffff166102d6565b6103a161039c366004612393565b610a0c565b60405167ffffffffffffffff9091168152602001610235565b6102d66103c8366004612393565b67ffffffffffffffff1660009081526005602052604090205468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b61029a6104143660046123b0565b610a35565b61010d61042736600461241c565b6112c6565b61043f61043a366004612393565b6112d7565b6040516102359190612439565b61045461130b565b61045d8161138e565b50565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561050b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052f91906124a3565b15610577576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6002546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd906105cf90869086906004016125d2565b602060405180830381865afa1580156105ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610610919061271b565b90505b92915050565b61062161130b565b61045d81611506565b600254604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610699573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106df9190810190612734565b60045490915073ffffffffffffffffffffffffffffffffffffffff1660005b825181101561085557600083828151811061071b5761071b6127c3565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610796573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ba919061271b565b9050801561084b576107e373ffffffffffffffffffffffffffffffffffffffff831685836116d0565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e8360405161084291815260200190565b60405180910390a35b50506001016106fe565b505050565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa1580156108eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061091906127f2565b60015473ffffffffffffffffffffffffffffffffffffffff163314610990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161056e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff80821660009081526005602052604081205490916106139116600161283e565b67ffffffffffffffff8416600090815260056020526040812073ffffffffffffffffffffffffffffffffffffffff8316610a9b576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610af7576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035473ffffffffffffffffffffffffffffffffffffffff168015610b9d576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610b6a908a908a906004016125d2565b600060405180830381600087803b158015610b8457600080fd5b505af1158015610b98573d6000803e3d6000fd5b505050505b506002546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a610bd460808c0160608d0161241c565b8a610be260808e018e612866565b6040518663ffffffff1660e01b8152600401610c029594939291906128cb565b600060405180830381865afa158015610c1f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c659190810190612993565b91945092509050610c7c6080890160608a0161241c565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f84604051610cc391815260200190565b60405180910390a2604080516101a081019091526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528c811661014085015287549293928392916101608401918a918791610d3891166129ea565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200186610e38576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e339190612a11565b610e3b565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a8060200190610e799190612866565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610ebd8b80612866565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f0460808c018c612866565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f4e60808c0160608d0161241c565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190610f7f9190612a2e565b905067ffffffffffffffff811115610f9957610f99611f95565b604051908082528060200260200182016040528015610ffc57816020015b610fe96040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b815260200190600190039081610fb75790505b509052905060005b61101160408b018b612a2e565b90508110156110c05761109761102a60408c018c612a2e565b8381811061103a5761103a6127c3565b9050604002018036038101906110509190612a96565b8c61105b8d80612866565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e925061175d915050565b8260e0015182815181106110ad576110ad6127c3565b6020908102919091010152600101611004565b5060025460e082015160009173ffffffffffffffffffffffffffffffffffffffff169063085318f8908d906110f860408f018f612a2e565b6040518563ffffffff1660e01b81526004016111179493929190612bad565b600060405180830381865afa158015611134573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261117a9190810190612be3565b905060005b8260e00151518110156111d35781818151811061119e5761119e6127c3565b60200260200101518360e0015182815181106111bc576111bc6127c3565b60209081029190910101516080015260010161117f565b506080808301849052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908d166060820152309181019190915261126d90839060a00160405160208183030381529060405280519060200120611a83565b82515260405167ffffffffffffffff8c16907fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140906112ac908590612c94565b60405180910390a25051519450505050505b949350505050565b6112ce61130b565b61045d81611b83565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461138c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161056e565b565b60005b81518110156115025760008282815181106113ae576113ae6127c3565b6020026020010151905060008383815181106113cc576113cc6127c3565b60200260200101516000015190508067ffffffffffffffff1660000361142a576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161056e565b60408051808201825267ffffffffffffffff838116600081815260056020818152868320805480871688528a83015173ffffffffffffffffffffffffffffffffffffffff908116848a019081529587905293835287518551851668010000000000000000027fffffffff00000000000000000000000000000000000000000000000000000000909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a2505050806001019050611391565b5050565b805173ffffffffffffffffffffffffffffffffffffffff1615806115425750604081015173ffffffffffffffffffffffffffffffffffffffff16155b15611579576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480549094169085161790925581516080810183527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008416918101919091527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558916116c5918490612de2565b60405180910390a150565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610855908490611c78565b61178f6040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b84602001516000036117cd576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006117dd85876000015161085a565b905073ffffffffffffffffffffffffffffffffffffffff811615806118ad57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015611887573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ab91906124a3565b155b156118ff5785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161056e565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b815260040161199e9190612e74565b6000604051808303816000875af11580156119bd573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611a039190810190612eea565b6040805160a0810190915273ffffffffffffffffffffffffffffffffffffffff841660c08201529091508060e0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181526020016040518060200160405280600081525081525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c00151604051602001611ac596959493929190612f7b565b604051602081830303815290604052805190602001208560400151805190602001208660e00151604051602001611afc9190612fdc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611c02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161056e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611cda826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611d849092919063ffffffff16565b8051909150156108555780806020019051810190611cf891906124a3565b610855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161056e565b6060611d938484600085611d9d565b90505b9392505050565b606082471015611e2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161056e565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611e589190612fef565b60006040518083038185875af1925050503d8060008114611e95576040519150601f19603f3d011682016040523d82523d6000602084013e611e9a565b606091505b5091509150611eab87838387611eb6565b979650505050505050565b60608315611f4c578251600003611f455773ffffffffffffffffffffffffffffffffffffffff85163b611f45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161056e565b50816112be565b6112be8383815115611f615781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056e9190612220565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611fe757611fe7611f95565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561203457612034611f95565b604052919050565b600067ffffffffffffffff82111561205657612056611f95565b5060051b60200190565b67ffffffffffffffff8116811461045d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461045d57600080fd5b600060208083850312156120ab57600080fd5b823567ffffffffffffffff8111156120c257600080fd5b8301601f810185136120d357600080fd5b80356120e66120e18261203c565b611fed565b81815260069190911b8201830190838101908783111561210557600080fd5b928401925b82841015611eab57604084890312156121235760008081fd5b61212b611fc4565b843561213681612060565b81528486013561214581612076565b818701528252604093909301929084019061210a565b60808101610613828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b838110156121cd5781810151838201526020016121b5565b50506000910152565b600081518084526121ee8160208601602086016121b2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061061060208301846121d6565b600060a0828403121561224557600080fd5b50919050565b6000806040838503121561225e57600080fd5b823561226981612060565b9150602083013567ffffffffffffffff81111561228557600080fd5b61229185828601612233565b9150509250929050565b80356122a681612076565b919050565b6000606082840312156122bd57600080fd5b6040516060810181811067ffffffffffffffff821117156122e0576122e0611f95565b60405282356122ee81612076565b815260208301356122fe81612076565b6020820152604083013561231181612076565b60408201529392505050565b6000806040838503121561233057600080fd5b823561233b81612060565b9150602083013561234b81612076565b809150509250929050565b606081016106138284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260409182015116910152565b6000602082840312156123a557600080fd5b8135611d9681612060565b600080600080608085870312156123c657600080fd5b84356123d181612060565b9350602085013567ffffffffffffffff8111156123ed57600080fd5b6123f987828801612233565b93505060408501359150606085013561241181612076565b939692955090935050565b60006020828403121561242e57600080fd5b8135611d9681612076565b6020808252825182820181905260009190848201906040850190845b8181101561248757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612455565b50909695505050505050565b805180151581146122a657600080fd5b6000602082840312156124b557600080fd5b61061082612493565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126124f357600080fd5b830160208101925035905067ffffffffffffffff81111561251357600080fd5b80360382131561252257600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156125c757813561259581612076565b73ffffffffffffffffffffffffffffffffffffffff168752818301358388015260409687019690910190600101612582565b509495945050505050565b600067ffffffffffffffff8085168352604060208401526125f384856124be565b60a0604086015261260860e086018284612529565b91505061261860208601866124be565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087850301606088015261264e848385612529565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe188360301831261268757600080fd5b602092880192830192359150848211156126a057600080fd5b8160061b36038313156126b257600080fd5b808785030160808801526126c7848385612572565b94506126d56060890161229b565b73ffffffffffffffffffffffffffffffffffffffff811660a0890152935061270060808901896124be565b94509250808786030160c08801525050611eab838383612529565b60006020828403121561272d57600080fd5b5051919050565b6000602080838503121561274757600080fd5b825167ffffffffffffffff81111561275e57600080fd5b8301601f8101851361276f57600080fd5b805161277d6120e18261203c565b81815260059190911b8201830190838101908783111561279c57600080fd5b928401925b82841015611eab5783516127b481612076565b825292840192908401906127a1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561280457600080fd5b8151611d9681612076565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561285f5761285f61280f565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261289b57600080fd5b83018035915067ffffffffffffffff8211156128b657600080fd5b60200191503681900382131561252257600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152608060608201526000611eab608083018486612529565b600082601f83011261292257600080fd5b815167ffffffffffffffff81111561293c5761293c611f95565b61296d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611fed565b81815284602083860101111561298257600080fd5b6112be8260208301602087016121b2565b6000806000606084860312156129a857600080fd5b835192506129b860208501612493565b9150604084015167ffffffffffffffff8111156129d457600080fd5b6129e086828701612911565b9150509250925092565b600067ffffffffffffffff808316818103612a0757612a0761280f565b6001019392505050565b600060208284031215612a2357600080fd5b8151611d9681612060565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612a6357600080fd5b83018035915067ffffffffffffffff821115612a7e57600080fd5b6020019150600681901b360382131561252257600080fd5b600060408284031215612aa857600080fd5b612ab0611fc4565b8235612abb81612076565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b84811015612ba0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160a08151818652612b31828701826121d6565b9150508582015185820387870152612b4982826121d6565b91505060408083015186830382880152612b6383826121d6565b92505050606080830151818701525060808083015192508582038187015250612b8c81836121d6565b9a86019a9450505090830190600101612aed565b5090979650505050505050565b67ffffffffffffffff85168152606060208201526000612bd06060830186612ad0565b8281036040840152611eab818587612572565b60006020808385031215612bf657600080fd5b825167ffffffffffffffff80821115612c0e57600080fd5b818501915085601f830112612c2257600080fd5b8151612c306120e18261203c565b81815260059190911b83018401908481019088831115612c4f57600080fd5b8585015b83811015612c8757805185811115612c6b5760008081fd5b612c798b89838a0101612911565b845250918601918601612c53565b5098975050505050505050565b60208152612ce560208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b60006020830151612d0e60c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e0850152612d2b6101a08501836121d6565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301610100870152612d6884836121d6565b9350608087015191508086850301610120870152612d8684836121d6565b935060a08701519150612db261014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e0870151915080868503018387015250612dd88382612ad0565b9695505050505050565b60e08101612e39828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a084015260408401511660c0830152611d96565b602081526000825160a06020840152612e9060c08401826121d6565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600060208284031215612efc57600080fd5b815167ffffffffffffffff80821115612f1457600080fd5b9083019060408286031215612f2857600080fd5b612f30611fc4565b825182811115612f3f57600080fd5b612f4b87828601612911565b825250602083015182811115612f6057600080fd5b612f6c87828601612911565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c06020840152612fab60c08401896121d6565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b6020815260006106106020830184612ad0565b600082516130018184602087016121b2565b919091019291505056fea164736f6c6343000818000a", } diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 4ebdb09e02..9fd0ac9e8d 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -11,6 +11,7 @@ commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitSto ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin b0d77babbe635cd6ba04c2af049badc9e9d28a4b6ed6bb75f830ad902a618beb evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 5c02c2b167946b3467636ff2bb58594cb4652fc63d8bdfee2488ed562e2a3e50 +fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin 95cdd54835272004bbe4a469b8529aa6f92ece2f903d914615010f1bf80a16c8 lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin e6a8ec9e8faccb1da7d90e0f702ed72975964f97dc3222b54cfcca0a0ba3fea2 lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin e632b08be0fbd1d013e8b3a9d75293d0d532b83071c531ff2be1deec1fa48ec1 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 @@ -18,12 +19,12 @@ message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin d976651d36b33ac2196b32b9d2f4fa6690c6a18d41b621365659fce1c1d1e737 mock_usdc_token_transmitter: ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin be0dbc3e475741ea0b7a54ec2b935a321b428baa9f4ce18180a87fb38bb87de2 mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin 518e19efa2ff52b0fefd8e597b05765317ee7638189bfe34ca43de2f6599faf4 -multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin 51435ef057455bea49888b81b06ed92f6b82c58f59e3575e4c60833031e23750 +multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin 0b541232e49727e947dc164eadf35963c66e67576f21baa0ecaa06a8833148ed multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin aa299e0c2659d53aad4eace4d66be0e734b1366008593669cf30361ff529da6a nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 6f64e1083b356c06ee66b9138e398b9c97a4cd3e8c9ec38cf3010cebc79af536 ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 -offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin e47ad9f887ace1741af3147cbd82c89e10deb3c68d8ffcd7fcbca33dc017e35a -onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 5b00bebfbf22003a13a2bce78e35c90869ca1dc2ebd3febd9bdf8151d8fa11e0 +offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin 4c1965d8e60a5ce133f71d46102b6cb932edce4538da096b048477154fac9fc1 +onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 13927b48bd09b9ab2c62143973c747f8c2e1ebc9f95f17a61ace67a68c71ec75 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin c1c2f8a65c7ffd971899cae7fe62f2da57d09e936151e2b92163c4bebe699d6b price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin e7781d600c1bb7aa4620106af7f6e146a109b97f4cb6a7d06c9e15773340ecb2 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 75be86323c227917a9bbc3f799d7ed02f92db546653a36db30ed0ebe64461353 diff --git a/core/gethwrappers/ccip/go_generate.go b/core/gethwrappers/ccip/go_generate.go index f57226b3e3..e61bcb0ba1 100644 --- a/core/gethwrappers/ccip/go_generate.go +++ b/core/gethwrappers/ccip/go_generate.go @@ -14,7 +14,7 @@ package ccip //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin OffRamp offramp //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin MultiAggregateRateLimiter multi_aggregate_rate_limiter //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin Router router -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin PriceRegistry price_registry +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin FeeQuoter fee_quoter //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin CCIPConfig ccip_config //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin NonceManager nonce_manager diff --git a/core/gethwrappers/ccip/mocks/fee_quoter_interface.go b/core/gethwrappers/ccip/mocks/fee_quoter_interface.go new file mode 100644 index 0000000000..27f53c0bd9 --- /dev/null +++ b/core/gethwrappers/ccip/mocks/fee_quoter_interface.go @@ -0,0 +1,4509 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mock_contracts + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + + event "github.com/ethereum/go-ethereum/event" + + fee_quoter "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" + + generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + + mock "github.com/stretchr/testify/mock" + + types "github.com/ethereum/go-ethereum/core/types" +) + +// FeeQuoterInterface is an autogenerated mock type for the FeeQuoterInterface type +type FeeQuoterInterface struct { + mock.Mock +} + +type FeeQuoterInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *FeeQuoterInterface) EXPECT() *FeeQuoterInterface_Expecter { + return &FeeQuoterInterface_Expecter{mock: &_m.Mock} +} + +// AcceptOwnership provides a mock function with given fields: opts +func (_m *FeeQuoterInterface) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for AcceptOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_AcceptOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AcceptOwnership' +type FeeQuoterInterface_AcceptOwnership_Call struct { + *mock.Call +} + +// AcceptOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +func (_e *FeeQuoterInterface_Expecter) AcceptOwnership(opts interface{}) *FeeQuoterInterface_AcceptOwnership_Call { + return &FeeQuoterInterface_AcceptOwnership_Call{Call: _e.mock.On("AcceptOwnership", opts)} +} + +func (_c *FeeQuoterInterface_AcceptOwnership_Call) Run(run func(opts *bind.TransactOpts)) *FeeQuoterInterface_AcceptOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts)) + }) + return _c +} + +func (_c *FeeQuoterInterface_AcceptOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *FeeQuoterInterface_AcceptOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_AcceptOwnership_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *FeeQuoterInterface_AcceptOwnership_Call { + _c.Call.Return(run) + return _c +} + +// Address provides a mock function with given fields: +func (_m *FeeQuoterInterface) Address() common.Address { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Address") + } + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// FeeQuoterInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' +type FeeQuoterInterface_Address_Call struct { + *mock.Call +} + +// Address is a helper method to define mock.On call +func (_e *FeeQuoterInterface_Expecter) Address() *FeeQuoterInterface_Address_Call { + return &FeeQuoterInterface_Address_Call{Call: _e.mock.On("Address")} +} + +func (_c *FeeQuoterInterface_Address_Call) Run(run func()) *FeeQuoterInterface_Address_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *FeeQuoterInterface_Address_Call) Return(_a0 common.Address) *FeeQuoterInterface_Address_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *FeeQuoterInterface_Address_Call) RunAndReturn(run func() common.Address) *FeeQuoterInterface_Address_Call { + _c.Call.Return(run) + return _c +} + +// ApplyAuthorizedCallerUpdates provides a mock function with given fields: opts, authorizedCallerArgs +func (_m *FeeQuoterInterface) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs fee_quoter.AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { + ret := _m.Called(opts, authorizedCallerArgs) + + if len(ret) == 0 { + panic("no return value specified for ApplyAuthorizedCallerUpdates") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, fee_quoter.AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error)); ok { + return rf(opts, authorizedCallerArgs) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, fee_quoter.AuthorizedCallersAuthorizedCallerArgs) *types.Transaction); ok { + r0 = rf(opts, authorizedCallerArgs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, fee_quoter.AuthorizedCallersAuthorizedCallerArgs) error); ok { + r1 = rf(opts, authorizedCallerArgs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ApplyAuthorizedCallerUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyAuthorizedCallerUpdates' +type FeeQuoterInterface_ApplyAuthorizedCallerUpdates_Call struct { + *mock.Call +} + +// ApplyAuthorizedCallerUpdates is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - authorizedCallerArgs fee_quoter.AuthorizedCallersAuthorizedCallerArgs +func (_e *FeeQuoterInterface_Expecter) ApplyAuthorizedCallerUpdates(opts interface{}, authorizedCallerArgs interface{}) *FeeQuoterInterface_ApplyAuthorizedCallerUpdates_Call { + return &FeeQuoterInterface_ApplyAuthorizedCallerUpdates_Call{Call: _e.mock.On("ApplyAuthorizedCallerUpdates", opts, authorizedCallerArgs)} +} + +func (_c *FeeQuoterInterface_ApplyAuthorizedCallerUpdates_Call) Run(run func(opts *bind.TransactOpts, authorizedCallerArgs fee_quoter.AuthorizedCallersAuthorizedCallerArgs)) *FeeQuoterInterface_ApplyAuthorizedCallerUpdates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(fee_quoter.AuthorizedCallersAuthorizedCallerArgs)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ApplyAuthorizedCallerUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *FeeQuoterInterface_ApplyAuthorizedCallerUpdates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ApplyAuthorizedCallerUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, fee_quoter.AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error)) *FeeQuoterInterface_ApplyAuthorizedCallerUpdates_Call { + _c.Call.Return(run) + return _c +} + +// ApplyDestChainConfigUpdates provides a mock function with given fields: opts, destChainConfigArgs +func (_m *FeeQuoterInterface) ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []fee_quoter.FeeQuoterDestChainConfigArgs) (*types.Transaction, error) { + ret := _m.Called(opts, destChainConfigArgs) + + if len(ret) == 0 { + panic("no return value specified for ApplyDestChainConfigUpdates") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []fee_quoter.FeeQuoterDestChainConfigArgs) (*types.Transaction, error)); ok { + return rf(opts, destChainConfigArgs) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []fee_quoter.FeeQuoterDestChainConfigArgs) *types.Transaction); ok { + r0 = rf(opts, destChainConfigArgs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []fee_quoter.FeeQuoterDestChainConfigArgs) error); ok { + r1 = rf(opts, destChainConfigArgs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ApplyDestChainConfigUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyDestChainConfigUpdates' +type FeeQuoterInterface_ApplyDestChainConfigUpdates_Call struct { + *mock.Call +} + +// ApplyDestChainConfigUpdates is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - destChainConfigArgs []fee_quoter.FeeQuoterDestChainConfigArgs +func (_e *FeeQuoterInterface_Expecter) ApplyDestChainConfigUpdates(opts interface{}, destChainConfigArgs interface{}) *FeeQuoterInterface_ApplyDestChainConfigUpdates_Call { + return &FeeQuoterInterface_ApplyDestChainConfigUpdates_Call{Call: _e.mock.On("ApplyDestChainConfigUpdates", opts, destChainConfigArgs)} +} + +func (_c *FeeQuoterInterface_ApplyDestChainConfigUpdates_Call) Run(run func(opts *bind.TransactOpts, destChainConfigArgs []fee_quoter.FeeQuoterDestChainConfigArgs)) *FeeQuoterInterface_ApplyDestChainConfigUpdates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]fee_quoter.FeeQuoterDestChainConfigArgs)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ApplyDestChainConfigUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *FeeQuoterInterface_ApplyDestChainConfigUpdates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ApplyDestChainConfigUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []fee_quoter.FeeQuoterDestChainConfigArgs) (*types.Transaction, error)) *FeeQuoterInterface_ApplyDestChainConfigUpdates_Call { + _c.Call.Return(run) + return _c +} + +// ApplyFeeTokensUpdates provides a mock function with given fields: opts, feeTokensToAdd, feeTokensToRemove +func (_m *FeeQuoterInterface) ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, feeTokensToAdd, feeTokensToRemove) + + if len(ret) == 0 { + panic("no return value specified for ApplyFeeTokensUpdates") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address) (*types.Transaction, error)); ok { + return rf(opts, feeTokensToAdd, feeTokensToRemove) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address) *types.Transaction); ok { + r0 = rf(opts, feeTokensToAdd, feeTokensToRemove) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, feeTokensToAdd, feeTokensToRemove) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ApplyFeeTokensUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyFeeTokensUpdates' +type FeeQuoterInterface_ApplyFeeTokensUpdates_Call struct { + *mock.Call +} + +// ApplyFeeTokensUpdates is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - feeTokensToAdd []common.Address +// - feeTokensToRemove []common.Address +func (_e *FeeQuoterInterface_Expecter) ApplyFeeTokensUpdates(opts interface{}, feeTokensToAdd interface{}, feeTokensToRemove interface{}) *FeeQuoterInterface_ApplyFeeTokensUpdates_Call { + return &FeeQuoterInterface_ApplyFeeTokensUpdates_Call{Call: _e.mock.On("ApplyFeeTokensUpdates", opts, feeTokensToAdd, feeTokensToRemove)} +} + +func (_c *FeeQuoterInterface_ApplyFeeTokensUpdates_Call) Run(run func(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address)) *FeeQuoterInterface_ApplyFeeTokensUpdates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ApplyFeeTokensUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *FeeQuoterInterface_ApplyFeeTokensUpdates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ApplyFeeTokensUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []common.Address, []common.Address) (*types.Transaction, error)) *FeeQuoterInterface_ApplyFeeTokensUpdates_Call { + _c.Call.Return(run) + return _c +} + +// ApplyPremiumMultiplierWeiPerEthUpdates provides a mock function with given fields: opts, premiumMultiplierWeiPerEthArgs +func (_m *FeeQuoterInterface) ApplyPremiumMultiplierWeiPerEthUpdates(opts *bind.TransactOpts, premiumMultiplierWeiPerEthArgs []fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) { + ret := _m.Called(opts, premiumMultiplierWeiPerEthArgs) + + if len(ret) == 0 { + panic("no return value specified for ApplyPremiumMultiplierWeiPerEthUpdates") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error)); ok { + return rf(opts, premiumMultiplierWeiPerEthArgs) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs) *types.Transaction); ok { + r0 = rf(opts, premiumMultiplierWeiPerEthArgs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs) error); ok { + r1 = rf(opts, premiumMultiplierWeiPerEthArgs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyPremiumMultiplierWeiPerEthUpdates' +type FeeQuoterInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call struct { + *mock.Call +} + +// ApplyPremiumMultiplierWeiPerEthUpdates is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - premiumMultiplierWeiPerEthArgs []fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs +func (_e *FeeQuoterInterface_Expecter) ApplyPremiumMultiplierWeiPerEthUpdates(opts interface{}, premiumMultiplierWeiPerEthArgs interface{}) *FeeQuoterInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call { + return &FeeQuoterInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call{Call: _e.mock.On("ApplyPremiumMultiplierWeiPerEthUpdates", opts, premiumMultiplierWeiPerEthArgs)} +} + +func (_c *FeeQuoterInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call) Run(run func(opts *bind.TransactOpts, premiumMultiplierWeiPerEthArgs []fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs)) *FeeQuoterInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *FeeQuoterInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error)) *FeeQuoterInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call { + _c.Call.Return(run) + return _c +} + +// ApplyTokenTransferFeeConfigUpdates provides a mock function with given fields: opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs +func (_m *FeeQuoterInterface) ApplyTokenTransferFeeConfigUpdates(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []fee_quoter.FeeQuoterTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) { + ret := _m.Called(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) + + if len(ret) == 0 { + panic("no return value specified for ApplyTokenTransferFeeConfigUpdates") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs, []fee_quoter.FeeQuoterTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error)); ok { + return rf(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs, []fee_quoter.FeeQuoterTokenTransferFeeConfigRemoveArgs) *types.Transaction); ok { + r0 = rf(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs, []fee_quoter.FeeQuoterTokenTransferFeeConfigRemoveArgs) error); ok { + r1 = rf(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ApplyTokenTransferFeeConfigUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyTokenTransferFeeConfigUpdates' +type FeeQuoterInterface_ApplyTokenTransferFeeConfigUpdates_Call struct { + *mock.Call +} + +// ApplyTokenTransferFeeConfigUpdates is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - tokenTransferFeeConfigArgs []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs +// - tokensToUseDefaultFeeConfigs []fee_quoter.FeeQuoterTokenTransferFeeConfigRemoveArgs +func (_e *FeeQuoterInterface_Expecter) ApplyTokenTransferFeeConfigUpdates(opts interface{}, tokenTransferFeeConfigArgs interface{}, tokensToUseDefaultFeeConfigs interface{}) *FeeQuoterInterface_ApplyTokenTransferFeeConfigUpdates_Call { + return &FeeQuoterInterface_ApplyTokenTransferFeeConfigUpdates_Call{Call: _e.mock.On("ApplyTokenTransferFeeConfigUpdates", opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs)} +} + +func (_c *FeeQuoterInterface_ApplyTokenTransferFeeConfigUpdates_Call) Run(run func(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []fee_quoter.FeeQuoterTokenTransferFeeConfigRemoveArgs)) *FeeQuoterInterface_ApplyTokenTransferFeeConfigUpdates_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]fee_quoter.FeeQuoterTokenTransferFeeConfigArgs), args[2].([]fee_quoter.FeeQuoterTokenTransferFeeConfigRemoveArgs)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ApplyTokenTransferFeeConfigUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *FeeQuoterInterface_ApplyTokenTransferFeeConfigUpdates_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ApplyTokenTransferFeeConfigUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs, []fee_quoter.FeeQuoterTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error)) *FeeQuoterInterface_ApplyTokenTransferFeeConfigUpdates_Call { + _c.Call.Return(run) + return _c +} + +// ConvertTokenAmount provides a mock function with given fields: opts, fromToken, fromTokenAmount, toToken +func (_m *FeeQuoterInterface) ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + ret := _m.Called(opts, fromToken, fromTokenAmount, toToken) + + if len(ret) == 0 { + panic("no return value specified for ConvertTokenAmount") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, *big.Int, common.Address) (*big.Int, error)); ok { + return rf(opts, fromToken, fromTokenAmount, toToken) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, *big.Int, common.Address) *big.Int); ok { + r0 = rf(opts, fromToken, fromTokenAmount, toToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address, *big.Int, common.Address) error); ok { + r1 = rf(opts, fromToken, fromTokenAmount, toToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ConvertTokenAmount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ConvertTokenAmount' +type FeeQuoterInterface_ConvertTokenAmount_Call struct { + *mock.Call +} + +// ConvertTokenAmount is a helper method to define mock.On call +// - opts *bind.CallOpts +// - fromToken common.Address +// - fromTokenAmount *big.Int +// - toToken common.Address +func (_e *FeeQuoterInterface_Expecter) ConvertTokenAmount(opts interface{}, fromToken interface{}, fromTokenAmount interface{}, toToken interface{}) *FeeQuoterInterface_ConvertTokenAmount_Call { + return &FeeQuoterInterface_ConvertTokenAmount_Call{Call: _e.mock.On("ConvertTokenAmount", opts, fromToken, fromTokenAmount, toToken)} +} + +func (_c *FeeQuoterInterface_ConvertTokenAmount_Call) Run(run func(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address)) *FeeQuoterInterface_ConvertTokenAmount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address), args[2].(*big.Int), args[3].(common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ConvertTokenAmount_Call) Return(_a0 *big.Int, _a1 error) *FeeQuoterInterface_ConvertTokenAmount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ConvertTokenAmount_Call) RunAndReturn(run func(*bind.CallOpts, common.Address, *big.Int, common.Address) (*big.Int, error)) *FeeQuoterInterface_ConvertTokenAmount_Call { + _c.Call.Return(run) + return _c +} + +// FilterAuthorizedCallerAdded provides a mock function with given fields: opts +func (_m *FeeQuoterInterface) FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*fee_quoter.FeeQuoterAuthorizedCallerAddedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterAuthorizedCallerAdded") + } + + var r0 *fee_quoter.FeeQuoterAuthorizedCallerAddedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*fee_quoter.FeeQuoterAuthorizedCallerAddedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *fee_quoter.FeeQuoterAuthorizedCallerAddedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterAuthorizedCallerAddedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterAuthorizedCallerAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterAuthorizedCallerAdded' +type FeeQuoterInterface_FilterAuthorizedCallerAdded_Call struct { + *mock.Call +} + +// FilterAuthorizedCallerAdded is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *FeeQuoterInterface_Expecter) FilterAuthorizedCallerAdded(opts interface{}) *FeeQuoterInterface_FilterAuthorizedCallerAdded_Call { + return &FeeQuoterInterface_FilterAuthorizedCallerAdded_Call{Call: _e.mock.On("FilterAuthorizedCallerAdded", opts)} +} + +func (_c *FeeQuoterInterface_FilterAuthorizedCallerAdded_Call) Run(run func(opts *bind.FilterOpts)) *FeeQuoterInterface_FilterAuthorizedCallerAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterAuthorizedCallerAdded_Call) Return(_a0 *fee_quoter.FeeQuoterAuthorizedCallerAddedIterator, _a1 error) *FeeQuoterInterface_FilterAuthorizedCallerAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterAuthorizedCallerAdded_Call) RunAndReturn(run func(*bind.FilterOpts) (*fee_quoter.FeeQuoterAuthorizedCallerAddedIterator, error)) *FeeQuoterInterface_FilterAuthorizedCallerAdded_Call { + _c.Call.Return(run) + return _c +} + +// FilterAuthorizedCallerRemoved provides a mock function with given fields: opts +func (_m *FeeQuoterInterface) FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*fee_quoter.FeeQuoterAuthorizedCallerRemovedIterator, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for FilterAuthorizedCallerRemoved") + } + + var r0 *fee_quoter.FeeQuoterAuthorizedCallerRemovedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*fee_quoter.FeeQuoterAuthorizedCallerRemovedIterator, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *fee_quoter.FeeQuoterAuthorizedCallerRemovedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterAuthorizedCallerRemovedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterAuthorizedCallerRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterAuthorizedCallerRemoved' +type FeeQuoterInterface_FilterAuthorizedCallerRemoved_Call struct { + *mock.Call +} + +// FilterAuthorizedCallerRemoved is a helper method to define mock.On call +// - opts *bind.FilterOpts +func (_e *FeeQuoterInterface_Expecter) FilterAuthorizedCallerRemoved(opts interface{}) *FeeQuoterInterface_FilterAuthorizedCallerRemoved_Call { + return &FeeQuoterInterface_FilterAuthorizedCallerRemoved_Call{Call: _e.mock.On("FilterAuthorizedCallerRemoved", opts)} +} + +func (_c *FeeQuoterInterface_FilterAuthorizedCallerRemoved_Call) Run(run func(opts *bind.FilterOpts)) *FeeQuoterInterface_FilterAuthorizedCallerRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterAuthorizedCallerRemoved_Call) Return(_a0 *fee_quoter.FeeQuoterAuthorizedCallerRemovedIterator, _a1 error) *FeeQuoterInterface_FilterAuthorizedCallerRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterAuthorizedCallerRemoved_Call) RunAndReturn(run func(*bind.FilterOpts) (*fee_quoter.FeeQuoterAuthorizedCallerRemovedIterator, error)) *FeeQuoterInterface_FilterAuthorizedCallerRemoved_Call { + _c.Call.Return(run) + return _c +} + +// FilterDestChainAdded provides a mock function with given fields: opts, destChainSelector +func (_m *FeeQuoterInterface) FilterDestChainAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*fee_quoter.FeeQuoterDestChainAddedIterator, error) { + ret := _m.Called(opts, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for FilterDestChainAdded") + } + + var r0 *fee_quoter.FeeQuoterDestChainAddedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*fee_quoter.FeeQuoterDestChainAddedIterator, error)); ok { + return rf(opts, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *fee_quoter.FeeQuoterDestChainAddedIterator); ok { + r0 = rf(opts, destChainSelector) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterDestChainAddedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { + r1 = rf(opts, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterDestChainAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterDestChainAdded' +type FeeQuoterInterface_FilterDestChainAdded_Call struct { + *mock.Call +} + +// FilterDestChainAdded is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - destChainSelector []uint64 +func (_e *FeeQuoterInterface_Expecter) FilterDestChainAdded(opts interface{}, destChainSelector interface{}) *FeeQuoterInterface_FilterDestChainAdded_Call { + return &FeeQuoterInterface_FilterDestChainAdded_Call{Call: _e.mock.On("FilterDestChainAdded", opts, destChainSelector)} +} + +func (_c *FeeQuoterInterface_FilterDestChainAdded_Call) Run(run func(opts *bind.FilterOpts, destChainSelector []uint64)) *FeeQuoterInterface_FilterDestChainAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterDestChainAdded_Call) Return(_a0 *fee_quoter.FeeQuoterDestChainAddedIterator, _a1 error) *FeeQuoterInterface_FilterDestChainAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterDestChainAdded_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*fee_quoter.FeeQuoterDestChainAddedIterator, error)) *FeeQuoterInterface_FilterDestChainAdded_Call { + _c.Call.Return(run) + return _c +} + +// FilterDestChainConfigUpdated provides a mock function with given fields: opts, destChainSelector +func (_m *FeeQuoterInterface) FilterDestChainConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*fee_quoter.FeeQuoterDestChainConfigUpdatedIterator, error) { + ret := _m.Called(opts, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for FilterDestChainConfigUpdated") + } + + var r0 *fee_quoter.FeeQuoterDestChainConfigUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*fee_quoter.FeeQuoterDestChainConfigUpdatedIterator, error)); ok { + return rf(opts, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *fee_quoter.FeeQuoterDestChainConfigUpdatedIterator); ok { + r0 = rf(opts, destChainSelector) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterDestChainConfigUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { + r1 = rf(opts, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterDestChainConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterDestChainConfigUpdated' +type FeeQuoterInterface_FilterDestChainConfigUpdated_Call struct { + *mock.Call +} + +// FilterDestChainConfigUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - destChainSelector []uint64 +func (_e *FeeQuoterInterface_Expecter) FilterDestChainConfigUpdated(opts interface{}, destChainSelector interface{}) *FeeQuoterInterface_FilterDestChainConfigUpdated_Call { + return &FeeQuoterInterface_FilterDestChainConfigUpdated_Call{Call: _e.mock.On("FilterDestChainConfigUpdated", opts, destChainSelector)} +} + +func (_c *FeeQuoterInterface_FilterDestChainConfigUpdated_Call) Run(run func(opts *bind.FilterOpts, destChainSelector []uint64)) *FeeQuoterInterface_FilterDestChainConfigUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterDestChainConfigUpdated_Call) Return(_a0 *fee_quoter.FeeQuoterDestChainConfigUpdatedIterator, _a1 error) *FeeQuoterInterface_FilterDestChainConfigUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterDestChainConfigUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*fee_quoter.FeeQuoterDestChainConfigUpdatedIterator, error)) *FeeQuoterInterface_FilterDestChainConfigUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FilterFeeTokenAdded provides a mock function with given fields: opts, feeToken +func (_m *FeeQuoterInterface) FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*fee_quoter.FeeQuoterFeeTokenAddedIterator, error) { + ret := _m.Called(opts, feeToken) + + if len(ret) == 0 { + panic("no return value specified for FilterFeeTokenAdded") + } + + var r0 *fee_quoter.FeeQuoterFeeTokenAddedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*fee_quoter.FeeQuoterFeeTokenAddedIterator, error)); ok { + return rf(opts, feeToken) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *fee_quoter.FeeQuoterFeeTokenAddedIterator); ok { + r0 = rf(opts, feeToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterFeeTokenAddedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, feeToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterFeeTokenAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterFeeTokenAdded' +type FeeQuoterInterface_FilterFeeTokenAdded_Call struct { + *mock.Call +} + +// FilterFeeTokenAdded is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - feeToken []common.Address +func (_e *FeeQuoterInterface_Expecter) FilterFeeTokenAdded(opts interface{}, feeToken interface{}) *FeeQuoterInterface_FilterFeeTokenAdded_Call { + return &FeeQuoterInterface_FilterFeeTokenAdded_Call{Call: _e.mock.On("FilterFeeTokenAdded", opts, feeToken)} +} + +func (_c *FeeQuoterInterface_FilterFeeTokenAdded_Call) Run(run func(opts *bind.FilterOpts, feeToken []common.Address)) *FeeQuoterInterface_FilterFeeTokenAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterFeeTokenAdded_Call) Return(_a0 *fee_quoter.FeeQuoterFeeTokenAddedIterator, _a1 error) *FeeQuoterInterface_FilterFeeTokenAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterFeeTokenAdded_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*fee_quoter.FeeQuoterFeeTokenAddedIterator, error)) *FeeQuoterInterface_FilterFeeTokenAdded_Call { + _c.Call.Return(run) + return _c +} + +// FilterFeeTokenRemoved provides a mock function with given fields: opts, feeToken +func (_m *FeeQuoterInterface) FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*fee_quoter.FeeQuoterFeeTokenRemovedIterator, error) { + ret := _m.Called(opts, feeToken) + + if len(ret) == 0 { + panic("no return value specified for FilterFeeTokenRemoved") + } + + var r0 *fee_quoter.FeeQuoterFeeTokenRemovedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*fee_quoter.FeeQuoterFeeTokenRemovedIterator, error)); ok { + return rf(opts, feeToken) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *fee_quoter.FeeQuoterFeeTokenRemovedIterator); ok { + r0 = rf(opts, feeToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterFeeTokenRemovedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, feeToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterFeeTokenRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterFeeTokenRemoved' +type FeeQuoterInterface_FilterFeeTokenRemoved_Call struct { + *mock.Call +} + +// FilterFeeTokenRemoved is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - feeToken []common.Address +func (_e *FeeQuoterInterface_Expecter) FilterFeeTokenRemoved(opts interface{}, feeToken interface{}) *FeeQuoterInterface_FilterFeeTokenRemoved_Call { + return &FeeQuoterInterface_FilterFeeTokenRemoved_Call{Call: _e.mock.On("FilterFeeTokenRemoved", opts, feeToken)} +} + +func (_c *FeeQuoterInterface_FilterFeeTokenRemoved_Call) Run(run func(opts *bind.FilterOpts, feeToken []common.Address)) *FeeQuoterInterface_FilterFeeTokenRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterFeeTokenRemoved_Call) Return(_a0 *fee_quoter.FeeQuoterFeeTokenRemovedIterator, _a1 error) *FeeQuoterInterface_FilterFeeTokenRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterFeeTokenRemoved_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*fee_quoter.FeeQuoterFeeTokenRemovedIterator, error)) *FeeQuoterInterface_FilterFeeTokenRemoved_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferRequested provides a mock function with given fields: opts, from, to +func (_m *FeeQuoterInterface) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*fee_quoter.FeeQuoterOwnershipTransferRequestedIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferRequested") + } + + var r0 *fee_quoter.FeeQuoterOwnershipTransferRequestedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*fee_quoter.FeeQuoterOwnershipTransferRequestedIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *fee_quoter.FeeQuoterOwnershipTransferRequestedIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterOwnershipTransferRequestedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferRequested' +type FeeQuoterInterface_FilterOwnershipTransferRequested_Call struct { + *mock.Call +} + +// FilterOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *FeeQuoterInterface_Expecter) FilterOwnershipTransferRequested(opts interface{}, from interface{}, to interface{}) *FeeQuoterInterface_FilterOwnershipTransferRequested_Call { + return &FeeQuoterInterface_FilterOwnershipTransferRequested_Call{Call: _e.mock.On("FilterOwnershipTransferRequested", opts, from, to)} +} + +func (_c *FeeQuoterInterface_FilterOwnershipTransferRequested_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *FeeQuoterInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterOwnershipTransferRequested_Call) Return(_a0 *fee_quoter.FeeQuoterOwnershipTransferRequestedIterator, _a1 error) *FeeQuoterInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*fee_quoter.FeeQuoterOwnershipTransferRequestedIterator, error)) *FeeQuoterInterface_FilterOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// FilterOwnershipTransferred provides a mock function with given fields: opts, from, to +func (_m *FeeQuoterInterface) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*fee_quoter.FeeQuoterOwnershipTransferredIterator, error) { + ret := _m.Called(opts, from, to) + + if len(ret) == 0 { + panic("no return value specified for FilterOwnershipTransferred") + } + + var r0 *fee_quoter.FeeQuoterOwnershipTransferredIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*fee_quoter.FeeQuoterOwnershipTransferredIterator, error)); ok { + return rf(opts, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *fee_quoter.FeeQuoterOwnershipTransferredIterator); ok { + r0 = rf(opts, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterOwnershipTransferredIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferred' +type FeeQuoterInterface_FilterOwnershipTransferred_Call struct { + *mock.Call +} + +// FilterOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - from []common.Address +// - to []common.Address +func (_e *FeeQuoterInterface_Expecter) FilterOwnershipTransferred(opts interface{}, from interface{}, to interface{}) *FeeQuoterInterface_FilterOwnershipTransferred_Call { + return &FeeQuoterInterface_FilterOwnershipTransferred_Call{Call: _e.mock.On("FilterOwnershipTransferred", opts, from, to)} +} + +func (_c *FeeQuoterInterface_FilterOwnershipTransferred_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *FeeQuoterInterface_FilterOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterOwnershipTransferred_Call) Return(_a0 *fee_quoter.FeeQuoterOwnershipTransferredIterator, _a1 error) *FeeQuoterInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterOwnershipTransferred_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*fee_quoter.FeeQuoterOwnershipTransferredIterator, error)) *FeeQuoterInterface_FilterOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// FilterPremiumMultiplierWeiPerEthUpdated provides a mock function with given fields: opts, token +func (_m *FeeQuoterInterface) FilterPremiumMultiplierWeiPerEthUpdated(opts *bind.FilterOpts, token []common.Address) (*fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for FilterPremiumMultiplierWeiPerEthUpdated") + } + + var r0 *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator); ok { + r0 = rf(opts, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPremiumMultiplierWeiPerEthUpdated' +type FeeQuoterInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call struct { + *mock.Call +} + +// FilterPremiumMultiplierWeiPerEthUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - token []common.Address +func (_e *FeeQuoterInterface_Expecter) FilterPremiumMultiplierWeiPerEthUpdated(opts interface{}, token interface{}) *FeeQuoterInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call { + return &FeeQuoterInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call{Call: _e.mock.On("FilterPremiumMultiplierWeiPerEthUpdated", opts, token)} +} + +func (_c *FeeQuoterInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call) Run(run func(opts *bind.FilterOpts, token []common.Address)) *FeeQuoterInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call) Return(_a0 *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator, _a1 error) *FeeQuoterInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdatedIterator, error)) *FeeQuoterInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FilterPriceFeedPerTokenUpdated provides a mock function with given fields: opts, token +func (_m *FeeQuoterInterface) FilterPriceFeedPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*fee_quoter.FeeQuoterPriceFeedPerTokenUpdatedIterator, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for FilterPriceFeedPerTokenUpdated") + } + + var r0 *fee_quoter.FeeQuoterPriceFeedPerTokenUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*fee_quoter.FeeQuoterPriceFeedPerTokenUpdatedIterator, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *fee_quoter.FeeQuoterPriceFeedPerTokenUpdatedIterator); ok { + r0 = rf(opts, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterPriceFeedPerTokenUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterPriceFeedPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPriceFeedPerTokenUpdated' +type FeeQuoterInterface_FilterPriceFeedPerTokenUpdated_Call struct { + *mock.Call +} + +// FilterPriceFeedPerTokenUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - token []common.Address +func (_e *FeeQuoterInterface_Expecter) FilterPriceFeedPerTokenUpdated(opts interface{}, token interface{}) *FeeQuoterInterface_FilterPriceFeedPerTokenUpdated_Call { + return &FeeQuoterInterface_FilterPriceFeedPerTokenUpdated_Call{Call: _e.mock.On("FilterPriceFeedPerTokenUpdated", opts, token)} +} + +func (_c *FeeQuoterInterface_FilterPriceFeedPerTokenUpdated_Call) Run(run func(opts *bind.FilterOpts, token []common.Address)) *FeeQuoterInterface_FilterPriceFeedPerTokenUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterPriceFeedPerTokenUpdated_Call) Return(_a0 *fee_quoter.FeeQuoterPriceFeedPerTokenUpdatedIterator, _a1 error) *FeeQuoterInterface_FilterPriceFeedPerTokenUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterPriceFeedPerTokenUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*fee_quoter.FeeQuoterPriceFeedPerTokenUpdatedIterator, error)) *FeeQuoterInterface_FilterPriceFeedPerTokenUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FilterReportPermissionSet provides a mock function with given fields: opts, reportId +func (_m *FeeQuoterInterface) FilterReportPermissionSet(opts *bind.FilterOpts, reportId [][32]byte) (*fee_quoter.FeeQuoterReportPermissionSetIterator, error) { + ret := _m.Called(opts, reportId) + + if len(ret) == 0 { + panic("no return value specified for FilterReportPermissionSet") + } + + var r0 *fee_quoter.FeeQuoterReportPermissionSetIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, [][32]byte) (*fee_quoter.FeeQuoterReportPermissionSetIterator, error)); ok { + return rf(opts, reportId) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, [][32]byte) *fee_quoter.FeeQuoterReportPermissionSetIterator); ok { + r0 = rf(opts, reportId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterReportPermissionSetIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, [][32]byte) error); ok { + r1 = rf(opts, reportId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterReportPermissionSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterReportPermissionSet' +type FeeQuoterInterface_FilterReportPermissionSet_Call struct { + *mock.Call +} + +// FilterReportPermissionSet is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - reportId [][32]byte +func (_e *FeeQuoterInterface_Expecter) FilterReportPermissionSet(opts interface{}, reportId interface{}) *FeeQuoterInterface_FilterReportPermissionSet_Call { + return &FeeQuoterInterface_FilterReportPermissionSet_Call{Call: _e.mock.On("FilterReportPermissionSet", opts, reportId)} +} + +func (_c *FeeQuoterInterface_FilterReportPermissionSet_Call) Run(run func(opts *bind.FilterOpts, reportId [][32]byte)) *FeeQuoterInterface_FilterReportPermissionSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([][32]byte)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterReportPermissionSet_Call) Return(_a0 *fee_quoter.FeeQuoterReportPermissionSetIterator, _a1 error) *FeeQuoterInterface_FilterReportPermissionSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterReportPermissionSet_Call) RunAndReturn(run func(*bind.FilterOpts, [][32]byte) (*fee_quoter.FeeQuoterReportPermissionSetIterator, error)) *FeeQuoterInterface_FilterReportPermissionSet_Call { + _c.Call.Return(run) + return _c +} + +// FilterTokenTransferFeeConfigDeleted provides a mock function with given fields: opts, destChainSelector, token +func (_m *FeeQuoterInterface) FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*fee_quoter.FeeQuoterTokenTransferFeeConfigDeletedIterator, error) { + ret := _m.Called(opts, destChainSelector, token) + + if len(ret) == 0 { + panic("no return value specified for FilterTokenTransferFeeConfigDeleted") + } + + var r0 *fee_quoter.FeeQuoterTokenTransferFeeConfigDeletedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) (*fee_quoter.FeeQuoterTokenTransferFeeConfigDeletedIterator, error)); ok { + return rf(opts, destChainSelector, token) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) *fee_quoter.FeeQuoterTokenTransferFeeConfigDeletedIterator); ok { + r0 = rf(opts, destChainSelector, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterTokenTransferFeeConfigDeletedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, []common.Address) error); ok { + r1 = rf(opts, destChainSelector, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterTokenTransferFeeConfigDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTokenTransferFeeConfigDeleted' +type FeeQuoterInterface_FilterTokenTransferFeeConfigDeleted_Call struct { + *mock.Call +} + +// FilterTokenTransferFeeConfigDeleted is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - destChainSelector []uint64 +// - token []common.Address +func (_e *FeeQuoterInterface_Expecter) FilterTokenTransferFeeConfigDeleted(opts interface{}, destChainSelector interface{}, token interface{}) *FeeQuoterInterface_FilterTokenTransferFeeConfigDeleted_Call { + return &FeeQuoterInterface_FilterTokenTransferFeeConfigDeleted_Call{Call: _e.mock.On("FilterTokenTransferFeeConfigDeleted", opts, destChainSelector, token)} +} + +func (_c *FeeQuoterInterface_FilterTokenTransferFeeConfigDeleted_Call) Run(run func(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address)) *FeeQuoterInterface_FilterTokenTransferFeeConfigDeleted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterTokenTransferFeeConfigDeleted_Call) Return(_a0 *fee_quoter.FeeQuoterTokenTransferFeeConfigDeletedIterator, _a1 error) *FeeQuoterInterface_FilterTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterTokenTransferFeeConfigDeleted_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, []common.Address) (*fee_quoter.FeeQuoterTokenTransferFeeConfigDeletedIterator, error)) *FeeQuoterInterface_FilterTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(run) + return _c +} + +// FilterTokenTransferFeeConfigUpdated provides a mock function with given fields: opts, destChainSelector, token +func (_m *FeeQuoterInterface) FilterTokenTransferFeeConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*fee_quoter.FeeQuoterTokenTransferFeeConfigUpdatedIterator, error) { + ret := _m.Called(opts, destChainSelector, token) + + if len(ret) == 0 { + panic("no return value specified for FilterTokenTransferFeeConfigUpdated") + } + + var r0 *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) (*fee_quoter.FeeQuoterTokenTransferFeeConfigUpdatedIterator, error)); ok { + return rf(opts, destChainSelector, token) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdatedIterator); ok { + r0 = rf(opts, destChainSelector, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterTokenTransferFeeConfigUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, []common.Address) error); ok { + r1 = rf(opts, destChainSelector, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterTokenTransferFeeConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTokenTransferFeeConfigUpdated' +type FeeQuoterInterface_FilterTokenTransferFeeConfigUpdated_Call struct { + *mock.Call +} + +// FilterTokenTransferFeeConfigUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - destChainSelector []uint64 +// - token []common.Address +func (_e *FeeQuoterInterface_Expecter) FilterTokenTransferFeeConfigUpdated(opts interface{}, destChainSelector interface{}, token interface{}) *FeeQuoterInterface_FilterTokenTransferFeeConfigUpdated_Call { + return &FeeQuoterInterface_FilterTokenTransferFeeConfigUpdated_Call{Call: _e.mock.On("FilterTokenTransferFeeConfigUpdated", opts, destChainSelector, token)} +} + +func (_c *FeeQuoterInterface_FilterTokenTransferFeeConfigUpdated_Call) Run(run func(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address)) *FeeQuoterInterface_FilterTokenTransferFeeConfigUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterTokenTransferFeeConfigUpdated_Call) Return(_a0 *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdatedIterator, _a1 error) *FeeQuoterInterface_FilterTokenTransferFeeConfigUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterTokenTransferFeeConfigUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, []common.Address) (*fee_quoter.FeeQuoterTokenTransferFeeConfigUpdatedIterator, error)) *FeeQuoterInterface_FilterTokenTransferFeeConfigUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FilterUsdPerTokenUpdated provides a mock function with given fields: opts, token +func (_m *FeeQuoterInterface) FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*fee_quoter.FeeQuoterUsdPerTokenUpdatedIterator, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for FilterUsdPerTokenUpdated") + } + + var r0 *fee_quoter.FeeQuoterUsdPerTokenUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*fee_quoter.FeeQuoterUsdPerTokenUpdatedIterator, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *fee_quoter.FeeQuoterUsdPerTokenUpdatedIterator); ok { + r0 = rf(opts, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterUsdPerTokenUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterUsdPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterUsdPerTokenUpdated' +type FeeQuoterInterface_FilterUsdPerTokenUpdated_Call struct { + *mock.Call +} + +// FilterUsdPerTokenUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - token []common.Address +func (_e *FeeQuoterInterface_Expecter) FilterUsdPerTokenUpdated(opts interface{}, token interface{}) *FeeQuoterInterface_FilterUsdPerTokenUpdated_Call { + return &FeeQuoterInterface_FilterUsdPerTokenUpdated_Call{Call: _e.mock.On("FilterUsdPerTokenUpdated", opts, token)} +} + +func (_c *FeeQuoterInterface_FilterUsdPerTokenUpdated_Call) Run(run func(opts *bind.FilterOpts, token []common.Address)) *FeeQuoterInterface_FilterUsdPerTokenUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterUsdPerTokenUpdated_Call) Return(_a0 *fee_quoter.FeeQuoterUsdPerTokenUpdatedIterator, _a1 error) *FeeQuoterInterface_FilterUsdPerTokenUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterUsdPerTokenUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*fee_quoter.FeeQuoterUsdPerTokenUpdatedIterator, error)) *FeeQuoterInterface_FilterUsdPerTokenUpdated_Call { + _c.Call.Return(run) + return _c +} + +// FilterUsdPerUnitGasUpdated provides a mock function with given fields: opts, destChain +func (_m *FeeQuoterInterface) FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*fee_quoter.FeeQuoterUsdPerUnitGasUpdatedIterator, error) { + ret := _m.Called(opts, destChain) + + if len(ret) == 0 { + panic("no return value specified for FilterUsdPerUnitGasUpdated") + } + + var r0 *fee_quoter.FeeQuoterUsdPerUnitGasUpdatedIterator + var r1 error + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*fee_quoter.FeeQuoterUsdPerUnitGasUpdatedIterator, error)); ok { + return rf(opts, destChain) + } + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *fee_quoter.FeeQuoterUsdPerUnitGasUpdatedIterator); ok { + r0 = rf(opts, destChain) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterUsdPerUnitGasUpdatedIterator) + } + } + + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { + r1 = rf(opts, destChain) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_FilterUsdPerUnitGasUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterUsdPerUnitGasUpdated' +type FeeQuoterInterface_FilterUsdPerUnitGasUpdated_Call struct { + *mock.Call +} + +// FilterUsdPerUnitGasUpdated is a helper method to define mock.On call +// - opts *bind.FilterOpts +// - destChain []uint64 +func (_e *FeeQuoterInterface_Expecter) FilterUsdPerUnitGasUpdated(opts interface{}, destChain interface{}) *FeeQuoterInterface_FilterUsdPerUnitGasUpdated_Call { + return &FeeQuoterInterface_FilterUsdPerUnitGasUpdated_Call{Call: _e.mock.On("FilterUsdPerUnitGasUpdated", opts, destChain)} +} + +func (_c *FeeQuoterInterface_FilterUsdPerUnitGasUpdated_Call) Run(run func(opts *bind.FilterOpts, destChain []uint64)) *FeeQuoterInterface_FilterUsdPerUnitGasUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.FilterOpts), args[1].([]uint64)) + }) + return _c +} + +func (_c *FeeQuoterInterface_FilterUsdPerUnitGasUpdated_Call) Return(_a0 *fee_quoter.FeeQuoterUsdPerUnitGasUpdatedIterator, _a1 error) *FeeQuoterInterface_FilterUsdPerUnitGasUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_FilterUsdPerUnitGasUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*fee_quoter.FeeQuoterUsdPerUnitGasUpdatedIterator, error)) *FeeQuoterInterface_FilterUsdPerUnitGasUpdated_Call { + _c.Call.Return(run) + return _c +} + +// GetAllAuthorizedCallers provides a mock function with given fields: opts +func (_m *FeeQuoterInterface) GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetAllAuthorizedCallers") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetAllAuthorizedCallers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAllAuthorizedCallers' +type FeeQuoterInterface_GetAllAuthorizedCallers_Call struct { + *mock.Call +} + +// GetAllAuthorizedCallers is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *FeeQuoterInterface_Expecter) GetAllAuthorizedCallers(opts interface{}) *FeeQuoterInterface_GetAllAuthorizedCallers_Call { + return &FeeQuoterInterface_GetAllAuthorizedCallers_Call{Call: _e.mock.On("GetAllAuthorizedCallers", opts)} +} + +func (_c *FeeQuoterInterface_GetAllAuthorizedCallers_Call) Run(run func(opts *bind.CallOpts)) *FeeQuoterInterface_GetAllAuthorizedCallers_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetAllAuthorizedCallers_Call) Return(_a0 []common.Address, _a1 error) *FeeQuoterInterface_GetAllAuthorizedCallers_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetAllAuthorizedCallers_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *FeeQuoterInterface_GetAllAuthorizedCallers_Call { + _c.Call.Return(run) + return _c +} + +// GetDestChainConfig provides a mock function with given fields: opts, destChainSelector +func (_m *FeeQuoterInterface) GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (fee_quoter.FeeQuoterDestChainConfig, error) { + ret := _m.Called(opts, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for GetDestChainConfig") + } + + var r0 fee_quoter.FeeQuoterDestChainConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (fee_quoter.FeeQuoterDestChainConfig, error)); ok { + return rf(opts, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) fee_quoter.FeeQuoterDestChainConfig); ok { + r0 = rf(opts, destChainSelector) + } else { + r0 = ret.Get(0).(fee_quoter.FeeQuoterDestChainConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetDestChainConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDestChainConfig' +type FeeQuoterInterface_GetDestChainConfig_Call struct { + *mock.Call +} + +// GetDestChainConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +func (_e *FeeQuoterInterface_Expecter) GetDestChainConfig(opts interface{}, destChainSelector interface{}) *FeeQuoterInterface_GetDestChainConfig_Call { + return &FeeQuoterInterface_GetDestChainConfig_Call{Call: _e.mock.On("GetDestChainConfig", opts, destChainSelector)} +} + +func (_c *FeeQuoterInterface_GetDestChainConfig_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64)) *FeeQuoterInterface_GetDestChainConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetDestChainConfig_Call) Return(_a0 fee_quoter.FeeQuoterDestChainConfig, _a1 error) *FeeQuoterInterface_GetDestChainConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetDestChainConfig_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (fee_quoter.FeeQuoterDestChainConfig, error)) *FeeQuoterInterface_GetDestChainConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetDestinationChainGasPrice provides a mock function with given fields: opts, destChainSelector +func (_m *FeeQuoterInterface) GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (fee_quoter.InternalTimestampedPackedUint224, error) { + ret := _m.Called(opts, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for GetDestinationChainGasPrice") + } + + var r0 fee_quoter.InternalTimestampedPackedUint224 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (fee_quoter.InternalTimestampedPackedUint224, error)); ok { + return rf(opts, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) fee_quoter.InternalTimestampedPackedUint224); ok { + r0 = rf(opts, destChainSelector) + } else { + r0 = ret.Get(0).(fee_quoter.InternalTimestampedPackedUint224) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { + r1 = rf(opts, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetDestinationChainGasPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDestinationChainGasPrice' +type FeeQuoterInterface_GetDestinationChainGasPrice_Call struct { + *mock.Call +} + +// GetDestinationChainGasPrice is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +func (_e *FeeQuoterInterface_Expecter) GetDestinationChainGasPrice(opts interface{}, destChainSelector interface{}) *FeeQuoterInterface_GetDestinationChainGasPrice_Call { + return &FeeQuoterInterface_GetDestinationChainGasPrice_Call{Call: _e.mock.On("GetDestinationChainGasPrice", opts, destChainSelector)} +} + +func (_c *FeeQuoterInterface_GetDestinationChainGasPrice_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64)) *FeeQuoterInterface_GetDestinationChainGasPrice_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetDestinationChainGasPrice_Call) Return(_a0 fee_quoter.InternalTimestampedPackedUint224, _a1 error) *FeeQuoterInterface_GetDestinationChainGasPrice_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetDestinationChainGasPrice_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (fee_quoter.InternalTimestampedPackedUint224, error)) *FeeQuoterInterface_GetDestinationChainGasPrice_Call { + _c.Call.Return(run) + return _c +} + +// GetFeeTokens provides a mock function with given fields: opts +func (_m *FeeQuoterInterface) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetFeeTokens") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetFeeTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFeeTokens' +type FeeQuoterInterface_GetFeeTokens_Call struct { + *mock.Call +} + +// GetFeeTokens is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *FeeQuoterInterface_Expecter) GetFeeTokens(opts interface{}) *FeeQuoterInterface_GetFeeTokens_Call { + return &FeeQuoterInterface_GetFeeTokens_Call{Call: _e.mock.On("GetFeeTokens", opts)} +} + +func (_c *FeeQuoterInterface_GetFeeTokens_Call) Run(run func(opts *bind.CallOpts)) *FeeQuoterInterface_GetFeeTokens_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetFeeTokens_Call) Return(_a0 []common.Address, _a1 error) *FeeQuoterInterface_GetFeeTokens_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetFeeTokens_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *FeeQuoterInterface_GetFeeTokens_Call { + _c.Call.Return(run) + return _c +} + +// GetPremiumMultiplierWeiPerEth provides a mock function with given fields: opts, token +func (_m *FeeQuoterInterface) GetPremiumMultiplierWeiPerEth(opts *bind.CallOpts, token common.Address) (uint64, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for GetPremiumMultiplierWeiPerEth") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (uint64, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) uint64); ok { + r0 = rf(opts, token) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetPremiumMultiplierWeiPerEth_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPremiumMultiplierWeiPerEth' +type FeeQuoterInterface_GetPremiumMultiplierWeiPerEth_Call struct { + *mock.Call +} + +// GetPremiumMultiplierWeiPerEth is a helper method to define mock.On call +// - opts *bind.CallOpts +// - token common.Address +func (_e *FeeQuoterInterface_Expecter) GetPremiumMultiplierWeiPerEth(opts interface{}, token interface{}) *FeeQuoterInterface_GetPremiumMultiplierWeiPerEth_Call { + return &FeeQuoterInterface_GetPremiumMultiplierWeiPerEth_Call{Call: _e.mock.On("GetPremiumMultiplierWeiPerEth", opts, token)} +} + +func (_c *FeeQuoterInterface_GetPremiumMultiplierWeiPerEth_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *FeeQuoterInterface_GetPremiumMultiplierWeiPerEth_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetPremiumMultiplierWeiPerEth_Call) Return(_a0 uint64, _a1 error) *FeeQuoterInterface_GetPremiumMultiplierWeiPerEth_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetPremiumMultiplierWeiPerEth_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (uint64, error)) *FeeQuoterInterface_GetPremiumMultiplierWeiPerEth_Call { + _c.Call.Return(run) + return _c +} + +// GetStaticConfig provides a mock function with given fields: opts +func (_m *FeeQuoterInterface) GetStaticConfig(opts *bind.CallOpts) (fee_quoter.FeeQuoterStaticConfig, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for GetStaticConfig") + } + + var r0 fee_quoter.FeeQuoterStaticConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (fee_quoter.FeeQuoterStaticConfig, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) fee_quoter.FeeQuoterStaticConfig); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(fee_quoter.FeeQuoterStaticConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetStaticConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStaticConfig' +type FeeQuoterInterface_GetStaticConfig_Call struct { + *mock.Call +} + +// GetStaticConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *FeeQuoterInterface_Expecter) GetStaticConfig(opts interface{}) *FeeQuoterInterface_GetStaticConfig_Call { + return &FeeQuoterInterface_GetStaticConfig_Call{Call: _e.mock.On("GetStaticConfig", opts)} +} + +func (_c *FeeQuoterInterface_GetStaticConfig_Call) Run(run func(opts *bind.CallOpts)) *FeeQuoterInterface_GetStaticConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetStaticConfig_Call) Return(_a0 fee_quoter.FeeQuoterStaticConfig, _a1 error) *FeeQuoterInterface_GetStaticConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetStaticConfig_Call) RunAndReturn(run func(*bind.CallOpts) (fee_quoter.FeeQuoterStaticConfig, error)) *FeeQuoterInterface_GetStaticConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenAndGasPrices provides a mock function with given fields: opts, token, destChainSelector +func (_m *FeeQuoterInterface) GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (fee_quoter.GetTokenAndGasPrices, error) { + ret := _m.Called(opts, token, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for GetTokenAndGasPrices") + } + + var r0 fee_quoter.GetTokenAndGasPrices + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, uint64) (fee_quoter.GetTokenAndGasPrices, error)); ok { + return rf(opts, token, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, uint64) fee_quoter.GetTokenAndGasPrices); ok { + r0 = rf(opts, token, destChainSelector) + } else { + r0 = ret.Get(0).(fee_quoter.GetTokenAndGasPrices) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address, uint64) error); ok { + r1 = rf(opts, token, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetTokenAndGasPrices_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenAndGasPrices' +type FeeQuoterInterface_GetTokenAndGasPrices_Call struct { + *mock.Call +} + +// GetTokenAndGasPrices is a helper method to define mock.On call +// - opts *bind.CallOpts +// - token common.Address +// - destChainSelector uint64 +func (_e *FeeQuoterInterface_Expecter) GetTokenAndGasPrices(opts interface{}, token interface{}, destChainSelector interface{}) *FeeQuoterInterface_GetTokenAndGasPrices_Call { + return &FeeQuoterInterface_GetTokenAndGasPrices_Call{Call: _e.mock.On("GetTokenAndGasPrices", opts, token, destChainSelector)} +} + +func (_c *FeeQuoterInterface_GetTokenAndGasPrices_Call) Run(run func(opts *bind.CallOpts, token common.Address, destChainSelector uint64)) *FeeQuoterInterface_GetTokenAndGasPrices_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address), args[2].(uint64)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetTokenAndGasPrices_Call) Return(_a0 fee_quoter.GetTokenAndGasPrices, _a1 error) *FeeQuoterInterface_GetTokenAndGasPrices_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetTokenAndGasPrices_Call) RunAndReturn(run func(*bind.CallOpts, common.Address, uint64) (fee_quoter.GetTokenAndGasPrices, error)) *FeeQuoterInterface_GetTokenAndGasPrices_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenPrice provides a mock function with given fields: opts, token +func (_m *FeeQuoterInterface) GetTokenPrice(opts *bind.CallOpts, token common.Address) (fee_quoter.InternalTimestampedPackedUint224, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for GetTokenPrice") + } + + var r0 fee_quoter.InternalTimestampedPackedUint224 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (fee_quoter.InternalTimestampedPackedUint224, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) fee_quoter.InternalTimestampedPackedUint224); ok { + r0 = rf(opts, token) + } else { + r0 = ret.Get(0).(fee_quoter.InternalTimestampedPackedUint224) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetTokenPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenPrice' +type FeeQuoterInterface_GetTokenPrice_Call struct { + *mock.Call +} + +// GetTokenPrice is a helper method to define mock.On call +// - opts *bind.CallOpts +// - token common.Address +func (_e *FeeQuoterInterface_Expecter) GetTokenPrice(opts interface{}, token interface{}) *FeeQuoterInterface_GetTokenPrice_Call { + return &FeeQuoterInterface_GetTokenPrice_Call{Call: _e.mock.On("GetTokenPrice", opts, token)} +} + +func (_c *FeeQuoterInterface_GetTokenPrice_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *FeeQuoterInterface_GetTokenPrice_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetTokenPrice_Call) Return(_a0 fee_quoter.InternalTimestampedPackedUint224, _a1 error) *FeeQuoterInterface_GetTokenPrice_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetTokenPrice_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (fee_quoter.InternalTimestampedPackedUint224, error)) *FeeQuoterInterface_GetTokenPrice_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenPriceFeedConfig provides a mock function with given fields: opts, token +func (_m *FeeQuoterInterface) GetTokenPriceFeedConfig(opts *bind.CallOpts, token common.Address) (fee_quoter.IFeeQuoterTokenPriceFeedConfig, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for GetTokenPriceFeedConfig") + } + + var r0 fee_quoter.IFeeQuoterTokenPriceFeedConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (fee_quoter.IFeeQuoterTokenPriceFeedConfig, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) fee_quoter.IFeeQuoterTokenPriceFeedConfig); ok { + r0 = rf(opts, token) + } else { + r0 = ret.Get(0).(fee_quoter.IFeeQuoterTokenPriceFeedConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetTokenPriceFeedConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenPriceFeedConfig' +type FeeQuoterInterface_GetTokenPriceFeedConfig_Call struct { + *mock.Call +} + +// GetTokenPriceFeedConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +// - token common.Address +func (_e *FeeQuoterInterface_Expecter) GetTokenPriceFeedConfig(opts interface{}, token interface{}) *FeeQuoterInterface_GetTokenPriceFeedConfig_Call { + return &FeeQuoterInterface_GetTokenPriceFeedConfig_Call{Call: _e.mock.On("GetTokenPriceFeedConfig", opts, token)} +} + +func (_c *FeeQuoterInterface_GetTokenPriceFeedConfig_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *FeeQuoterInterface_GetTokenPriceFeedConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetTokenPriceFeedConfig_Call) Return(_a0 fee_quoter.IFeeQuoterTokenPriceFeedConfig, _a1 error) *FeeQuoterInterface_GetTokenPriceFeedConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetTokenPriceFeedConfig_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (fee_quoter.IFeeQuoterTokenPriceFeedConfig, error)) *FeeQuoterInterface_GetTokenPriceFeedConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenPrices provides a mock function with given fields: opts, tokens +func (_m *FeeQuoterInterface) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]fee_quoter.InternalTimestampedPackedUint224, error) { + ret := _m.Called(opts, tokens) + + if len(ret) == 0 { + panic("no return value specified for GetTokenPrices") + } + + var r0 []fee_quoter.InternalTimestampedPackedUint224 + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, []common.Address) ([]fee_quoter.InternalTimestampedPackedUint224, error)); ok { + return rf(opts, tokens) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, []common.Address) []fee_quoter.InternalTimestampedPackedUint224); ok { + r0 = rf(opts, tokens) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]fee_quoter.InternalTimestampedPackedUint224) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, []common.Address) error); ok { + r1 = rf(opts, tokens) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetTokenPrices_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenPrices' +type FeeQuoterInterface_GetTokenPrices_Call struct { + *mock.Call +} + +// GetTokenPrices is a helper method to define mock.On call +// - opts *bind.CallOpts +// - tokens []common.Address +func (_e *FeeQuoterInterface_Expecter) GetTokenPrices(opts interface{}, tokens interface{}) *FeeQuoterInterface_GetTokenPrices_Call { + return &FeeQuoterInterface_GetTokenPrices_Call{Call: _e.mock.On("GetTokenPrices", opts, tokens)} +} + +func (_c *FeeQuoterInterface_GetTokenPrices_Call) Run(run func(opts *bind.CallOpts, tokens []common.Address)) *FeeQuoterInterface_GetTokenPrices_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetTokenPrices_Call) Return(_a0 []fee_quoter.InternalTimestampedPackedUint224, _a1 error) *FeeQuoterInterface_GetTokenPrices_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetTokenPrices_Call) RunAndReturn(run func(*bind.CallOpts, []common.Address) ([]fee_quoter.InternalTimestampedPackedUint224, error)) *FeeQuoterInterface_GetTokenPrices_Call { + _c.Call.Return(run) + return _c +} + +// GetTokenTransferFeeConfig provides a mock function with given fields: opts, destChainSelector, token +func (_m *FeeQuoterInterface) GetTokenTransferFeeConfig(opts *bind.CallOpts, destChainSelector uint64, token common.Address) (fee_quoter.FeeQuoterTokenTransferFeeConfig, error) { + ret := _m.Called(opts, destChainSelector, token) + + if len(ret) == 0 { + panic("no return value specified for GetTokenTransferFeeConfig") + } + + var r0 fee_quoter.FeeQuoterTokenTransferFeeConfig + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address) (fee_quoter.FeeQuoterTokenTransferFeeConfig, error)); ok { + return rf(opts, destChainSelector, token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address) fee_quoter.FeeQuoterTokenTransferFeeConfig); ok { + r0 = rf(opts, destChainSelector, token) + } else { + r0 = ret.Get(0).(fee_quoter.FeeQuoterTokenTransferFeeConfig) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, common.Address) error); ok { + r1 = rf(opts, destChainSelector, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetTokenTransferFeeConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenTransferFeeConfig' +type FeeQuoterInterface_GetTokenTransferFeeConfig_Call struct { + *mock.Call +} + +// GetTokenTransferFeeConfig is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +// - token common.Address +func (_e *FeeQuoterInterface_Expecter) GetTokenTransferFeeConfig(opts interface{}, destChainSelector interface{}, token interface{}) *FeeQuoterInterface_GetTokenTransferFeeConfig_Call { + return &FeeQuoterInterface_GetTokenTransferFeeConfig_Call{Call: _e.mock.On("GetTokenTransferFeeConfig", opts, destChainSelector, token)} +} + +func (_c *FeeQuoterInterface_GetTokenTransferFeeConfig_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, token common.Address)) *FeeQuoterInterface_GetTokenTransferFeeConfig_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetTokenTransferFeeConfig_Call) Return(_a0 fee_quoter.FeeQuoterTokenTransferFeeConfig, _a1 error) *FeeQuoterInterface_GetTokenTransferFeeConfig_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetTokenTransferFeeConfig_Call) RunAndReturn(run func(*bind.CallOpts, uint64, common.Address) (fee_quoter.FeeQuoterTokenTransferFeeConfig, error)) *FeeQuoterInterface_GetTokenTransferFeeConfig_Call { + _c.Call.Return(run) + return _c +} + +// GetValidatedFee provides a mock function with given fields: opts, destChainSelector, message +func (_m *FeeQuoterInterface) GetValidatedFee(opts *bind.CallOpts, destChainSelector uint64, message fee_quoter.ClientEVM2AnyMessage) (*big.Int, error) { + ret := _m.Called(opts, destChainSelector, message) + + if len(ret) == 0 { + panic("no return value specified for GetValidatedFee") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, fee_quoter.ClientEVM2AnyMessage) (*big.Int, error)); ok { + return rf(opts, destChainSelector, message) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, fee_quoter.ClientEVM2AnyMessage) *big.Int); ok { + r0 = rf(opts, destChainSelector, message) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, fee_quoter.ClientEVM2AnyMessage) error); ok { + r1 = rf(opts, destChainSelector, message) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetValidatedFee_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetValidatedFee' +type FeeQuoterInterface_GetValidatedFee_Call struct { + *mock.Call +} + +// GetValidatedFee is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +// - message fee_quoter.ClientEVM2AnyMessage +func (_e *FeeQuoterInterface_Expecter) GetValidatedFee(opts interface{}, destChainSelector interface{}, message interface{}) *FeeQuoterInterface_GetValidatedFee_Call { + return &FeeQuoterInterface_GetValidatedFee_Call{Call: _e.mock.On("GetValidatedFee", opts, destChainSelector, message)} +} + +func (_c *FeeQuoterInterface_GetValidatedFee_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, message fee_quoter.ClientEVM2AnyMessage)) *FeeQuoterInterface_GetValidatedFee_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(fee_quoter.ClientEVM2AnyMessage)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetValidatedFee_Call) Return(_a0 *big.Int, _a1 error) *FeeQuoterInterface_GetValidatedFee_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetValidatedFee_Call) RunAndReturn(run func(*bind.CallOpts, uint64, fee_quoter.ClientEVM2AnyMessage) (*big.Int, error)) *FeeQuoterInterface_GetValidatedFee_Call { + _c.Call.Return(run) + return _c +} + +// GetValidatedTokenPrice provides a mock function with given fields: opts, token +func (_m *FeeQuoterInterface) GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) { + ret := _m.Called(opts, token) + + if len(ret) == 0 { + panic("no return value specified for GetValidatedTokenPrice") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (*big.Int, error)); ok { + return rf(opts, token) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) *big.Int); ok { + r0 = rf(opts, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { + r1 = rf(opts, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_GetValidatedTokenPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetValidatedTokenPrice' +type FeeQuoterInterface_GetValidatedTokenPrice_Call struct { + *mock.Call +} + +// GetValidatedTokenPrice is a helper method to define mock.On call +// - opts *bind.CallOpts +// - token common.Address +func (_e *FeeQuoterInterface_Expecter) GetValidatedTokenPrice(opts interface{}, token interface{}) *FeeQuoterInterface_GetValidatedTokenPrice_Call { + return &FeeQuoterInterface_GetValidatedTokenPrice_Call{Call: _e.mock.On("GetValidatedTokenPrice", opts, token)} +} + +func (_c *FeeQuoterInterface_GetValidatedTokenPrice_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *FeeQuoterInterface_GetValidatedTokenPrice_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_GetValidatedTokenPrice_Call) Return(_a0 *big.Int, _a1 error) *FeeQuoterInterface_GetValidatedTokenPrice_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_GetValidatedTokenPrice_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (*big.Int, error)) *FeeQuoterInterface_GetValidatedTokenPrice_Call { + _c.Call.Return(run) + return _c +} + +// OnReport provides a mock function with given fields: opts, metadata, report +func (_m *FeeQuoterInterface) OnReport(opts *bind.TransactOpts, metadata []byte, report []byte) (*types.Transaction, error) { + ret := _m.Called(opts, metadata, report) + + if len(ret) == 0 { + panic("no return value specified for OnReport") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []byte, []byte) (*types.Transaction, error)); ok { + return rf(opts, metadata, report) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []byte, []byte) *types.Transaction); ok { + r0 = rf(opts, metadata, report) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []byte, []byte) error); ok { + r1 = rf(opts, metadata, report) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_OnReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OnReport' +type FeeQuoterInterface_OnReport_Call struct { + *mock.Call +} + +// OnReport is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - metadata []byte +// - report []byte +func (_e *FeeQuoterInterface_Expecter) OnReport(opts interface{}, metadata interface{}, report interface{}) *FeeQuoterInterface_OnReport_Call { + return &FeeQuoterInterface_OnReport_Call{Call: _e.mock.On("OnReport", opts, metadata, report)} +} + +func (_c *FeeQuoterInterface_OnReport_Call) Run(run func(opts *bind.TransactOpts, metadata []byte, report []byte)) *FeeQuoterInterface_OnReport_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]byte), args[2].([]byte)) + }) + return _c +} + +func (_c *FeeQuoterInterface_OnReport_Call) Return(_a0 *types.Transaction, _a1 error) *FeeQuoterInterface_OnReport_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_OnReport_Call) RunAndReturn(run func(*bind.TransactOpts, []byte, []byte) (*types.Transaction, error)) *FeeQuoterInterface_OnReport_Call { + _c.Call.Return(run) + return _c +} + +// Owner provides a mock function with given fields: opts +func (_m *FeeQuoterInterface) Owner(opts *bind.CallOpts) (common.Address, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for Owner") + } + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_Owner_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Owner' +type FeeQuoterInterface_Owner_Call struct { + *mock.Call +} + +// Owner is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *FeeQuoterInterface_Expecter) Owner(opts interface{}) *FeeQuoterInterface_Owner_Call { + return &FeeQuoterInterface_Owner_Call{Call: _e.mock.On("Owner", opts)} +} + +func (_c *FeeQuoterInterface_Owner_Call) Run(run func(opts *bind.CallOpts)) *FeeQuoterInterface_Owner_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *FeeQuoterInterface_Owner_Call) Return(_a0 common.Address, _a1 error) *FeeQuoterInterface_Owner_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_Owner_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *FeeQuoterInterface_Owner_Call { + _c.Call.Return(run) + return _c +} + +// ParseAuthorizedCallerAdded provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseAuthorizedCallerAdded(log types.Log) (*fee_quoter.FeeQuoterAuthorizedCallerAdded, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseAuthorizedCallerAdded") + } + + var r0 *fee_quoter.FeeQuoterAuthorizedCallerAdded + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterAuthorizedCallerAdded, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterAuthorizedCallerAdded); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterAuthorizedCallerAdded) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseAuthorizedCallerAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseAuthorizedCallerAdded' +type FeeQuoterInterface_ParseAuthorizedCallerAdded_Call struct { + *mock.Call +} + +// ParseAuthorizedCallerAdded is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseAuthorizedCallerAdded(log interface{}) *FeeQuoterInterface_ParseAuthorizedCallerAdded_Call { + return &FeeQuoterInterface_ParseAuthorizedCallerAdded_Call{Call: _e.mock.On("ParseAuthorizedCallerAdded", log)} +} + +func (_c *FeeQuoterInterface_ParseAuthorizedCallerAdded_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseAuthorizedCallerAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseAuthorizedCallerAdded_Call) Return(_a0 *fee_quoter.FeeQuoterAuthorizedCallerAdded, _a1 error) *FeeQuoterInterface_ParseAuthorizedCallerAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseAuthorizedCallerAdded_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterAuthorizedCallerAdded, error)) *FeeQuoterInterface_ParseAuthorizedCallerAdded_Call { + _c.Call.Return(run) + return _c +} + +// ParseAuthorizedCallerRemoved provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseAuthorizedCallerRemoved(log types.Log) (*fee_quoter.FeeQuoterAuthorizedCallerRemoved, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseAuthorizedCallerRemoved") + } + + var r0 *fee_quoter.FeeQuoterAuthorizedCallerRemoved + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterAuthorizedCallerRemoved, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterAuthorizedCallerRemoved); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterAuthorizedCallerRemoved) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseAuthorizedCallerRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseAuthorizedCallerRemoved' +type FeeQuoterInterface_ParseAuthorizedCallerRemoved_Call struct { + *mock.Call +} + +// ParseAuthorizedCallerRemoved is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseAuthorizedCallerRemoved(log interface{}) *FeeQuoterInterface_ParseAuthorizedCallerRemoved_Call { + return &FeeQuoterInterface_ParseAuthorizedCallerRemoved_Call{Call: _e.mock.On("ParseAuthorizedCallerRemoved", log)} +} + +func (_c *FeeQuoterInterface_ParseAuthorizedCallerRemoved_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseAuthorizedCallerRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseAuthorizedCallerRemoved_Call) Return(_a0 *fee_quoter.FeeQuoterAuthorizedCallerRemoved, _a1 error) *FeeQuoterInterface_ParseAuthorizedCallerRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseAuthorizedCallerRemoved_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterAuthorizedCallerRemoved, error)) *FeeQuoterInterface_ParseAuthorizedCallerRemoved_Call { + _c.Call.Return(run) + return _c +} + +// ParseDestChainAdded provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseDestChainAdded(log types.Log) (*fee_quoter.FeeQuoterDestChainAdded, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseDestChainAdded") + } + + var r0 *fee_quoter.FeeQuoterDestChainAdded + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterDestChainAdded, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterDestChainAdded); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterDestChainAdded) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseDestChainAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseDestChainAdded' +type FeeQuoterInterface_ParseDestChainAdded_Call struct { + *mock.Call +} + +// ParseDestChainAdded is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseDestChainAdded(log interface{}) *FeeQuoterInterface_ParseDestChainAdded_Call { + return &FeeQuoterInterface_ParseDestChainAdded_Call{Call: _e.mock.On("ParseDestChainAdded", log)} +} + +func (_c *FeeQuoterInterface_ParseDestChainAdded_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseDestChainAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseDestChainAdded_Call) Return(_a0 *fee_quoter.FeeQuoterDestChainAdded, _a1 error) *FeeQuoterInterface_ParseDestChainAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseDestChainAdded_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterDestChainAdded, error)) *FeeQuoterInterface_ParseDestChainAdded_Call { + _c.Call.Return(run) + return _c +} + +// ParseDestChainConfigUpdated provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseDestChainConfigUpdated(log types.Log) (*fee_quoter.FeeQuoterDestChainConfigUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseDestChainConfigUpdated") + } + + var r0 *fee_quoter.FeeQuoterDestChainConfigUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterDestChainConfigUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterDestChainConfigUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterDestChainConfigUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseDestChainConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseDestChainConfigUpdated' +type FeeQuoterInterface_ParseDestChainConfigUpdated_Call struct { + *mock.Call +} + +// ParseDestChainConfigUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseDestChainConfigUpdated(log interface{}) *FeeQuoterInterface_ParseDestChainConfigUpdated_Call { + return &FeeQuoterInterface_ParseDestChainConfigUpdated_Call{Call: _e.mock.On("ParseDestChainConfigUpdated", log)} +} + +func (_c *FeeQuoterInterface_ParseDestChainConfigUpdated_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseDestChainConfigUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseDestChainConfigUpdated_Call) Return(_a0 *fee_quoter.FeeQuoterDestChainConfigUpdated, _a1 error) *FeeQuoterInterface_ParseDestChainConfigUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseDestChainConfigUpdated_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterDestChainConfigUpdated, error)) *FeeQuoterInterface_ParseDestChainConfigUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ParseFeeTokenAdded provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseFeeTokenAdded(log types.Log) (*fee_quoter.FeeQuoterFeeTokenAdded, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseFeeTokenAdded") + } + + var r0 *fee_quoter.FeeQuoterFeeTokenAdded + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterFeeTokenAdded, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterFeeTokenAdded); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterFeeTokenAdded) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseFeeTokenAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseFeeTokenAdded' +type FeeQuoterInterface_ParseFeeTokenAdded_Call struct { + *mock.Call +} + +// ParseFeeTokenAdded is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseFeeTokenAdded(log interface{}) *FeeQuoterInterface_ParseFeeTokenAdded_Call { + return &FeeQuoterInterface_ParseFeeTokenAdded_Call{Call: _e.mock.On("ParseFeeTokenAdded", log)} +} + +func (_c *FeeQuoterInterface_ParseFeeTokenAdded_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseFeeTokenAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseFeeTokenAdded_Call) Return(_a0 *fee_quoter.FeeQuoterFeeTokenAdded, _a1 error) *FeeQuoterInterface_ParseFeeTokenAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseFeeTokenAdded_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterFeeTokenAdded, error)) *FeeQuoterInterface_ParseFeeTokenAdded_Call { + _c.Call.Return(run) + return _c +} + +// ParseFeeTokenRemoved provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseFeeTokenRemoved(log types.Log) (*fee_quoter.FeeQuoterFeeTokenRemoved, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseFeeTokenRemoved") + } + + var r0 *fee_quoter.FeeQuoterFeeTokenRemoved + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterFeeTokenRemoved, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterFeeTokenRemoved); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterFeeTokenRemoved) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseFeeTokenRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseFeeTokenRemoved' +type FeeQuoterInterface_ParseFeeTokenRemoved_Call struct { + *mock.Call +} + +// ParseFeeTokenRemoved is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseFeeTokenRemoved(log interface{}) *FeeQuoterInterface_ParseFeeTokenRemoved_Call { + return &FeeQuoterInterface_ParseFeeTokenRemoved_Call{Call: _e.mock.On("ParseFeeTokenRemoved", log)} +} + +func (_c *FeeQuoterInterface_ParseFeeTokenRemoved_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseFeeTokenRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseFeeTokenRemoved_Call) Return(_a0 *fee_quoter.FeeQuoterFeeTokenRemoved, _a1 error) *FeeQuoterInterface_ParseFeeTokenRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseFeeTokenRemoved_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterFeeTokenRemoved, error)) *FeeQuoterInterface_ParseFeeTokenRemoved_Call { + _c.Call.Return(run) + return _c +} + +// ParseLog provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseLog") + } + + var r0 generated.AbigenLog + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generated.AbigenLog) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' +type FeeQuoterInterface_ParseLog_Call struct { + *mock.Call +} + +// ParseLog is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseLog(log interface{}) *FeeQuoterInterface_ParseLog_Call { + return &FeeQuoterInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} +} + +func (_c *FeeQuoterInterface_ParseLog_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *FeeQuoterInterface_ParseLog_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *FeeQuoterInterface_ParseLog_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferRequested provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseOwnershipTransferRequested(log types.Log) (*fee_quoter.FeeQuoterOwnershipTransferRequested, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferRequested") + } + + var r0 *fee_quoter.FeeQuoterOwnershipTransferRequested + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterOwnershipTransferRequested, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterOwnershipTransferRequested); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterOwnershipTransferRequested) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferRequested' +type FeeQuoterInterface_ParseOwnershipTransferRequested_Call struct { + *mock.Call +} + +// ParseOwnershipTransferRequested is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseOwnershipTransferRequested(log interface{}) *FeeQuoterInterface_ParseOwnershipTransferRequested_Call { + return &FeeQuoterInterface_ParseOwnershipTransferRequested_Call{Call: _e.mock.On("ParseOwnershipTransferRequested", log)} +} + +func (_c *FeeQuoterInterface_ParseOwnershipTransferRequested_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseOwnershipTransferRequested_Call) Return(_a0 *fee_quoter.FeeQuoterOwnershipTransferRequested, _a1 error) *FeeQuoterInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseOwnershipTransferRequested_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterOwnershipTransferRequested, error)) *FeeQuoterInterface_ParseOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// ParseOwnershipTransferred provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseOwnershipTransferred(log types.Log) (*fee_quoter.FeeQuoterOwnershipTransferred, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseOwnershipTransferred") + } + + var r0 *fee_quoter.FeeQuoterOwnershipTransferred + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterOwnershipTransferred, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterOwnershipTransferred); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterOwnershipTransferred) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferred' +type FeeQuoterInterface_ParseOwnershipTransferred_Call struct { + *mock.Call +} + +// ParseOwnershipTransferred is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseOwnershipTransferred(log interface{}) *FeeQuoterInterface_ParseOwnershipTransferred_Call { + return &FeeQuoterInterface_ParseOwnershipTransferred_Call{Call: _e.mock.On("ParseOwnershipTransferred", log)} +} + +func (_c *FeeQuoterInterface_ParseOwnershipTransferred_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseOwnershipTransferred_Call) Return(_a0 *fee_quoter.FeeQuoterOwnershipTransferred, _a1 error) *FeeQuoterInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseOwnershipTransferred_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterOwnershipTransferred, error)) *FeeQuoterInterface_ParseOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// ParsePremiumMultiplierWeiPerEthUpdated provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParsePremiumMultiplierWeiPerEthUpdated(log types.Log) (*fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParsePremiumMultiplierWeiPerEthUpdated") + } + + var r0 *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePremiumMultiplierWeiPerEthUpdated' +type FeeQuoterInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call struct { + *mock.Call +} + +// ParsePremiumMultiplierWeiPerEthUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParsePremiumMultiplierWeiPerEthUpdated(log interface{}) *FeeQuoterInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call { + return &FeeQuoterInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call{Call: _e.mock.On("ParsePremiumMultiplierWeiPerEthUpdated", log)} +} + +func (_c *FeeQuoterInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call) Return(_a0 *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated, _a1 error) *FeeQuoterInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated, error)) *FeeQuoterInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ParsePriceFeedPerTokenUpdated provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParsePriceFeedPerTokenUpdated(log types.Log) (*fee_quoter.FeeQuoterPriceFeedPerTokenUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParsePriceFeedPerTokenUpdated") + } + + var r0 *fee_quoter.FeeQuoterPriceFeedPerTokenUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterPriceFeedPerTokenUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterPriceFeedPerTokenUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterPriceFeedPerTokenUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParsePriceFeedPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePriceFeedPerTokenUpdated' +type FeeQuoterInterface_ParsePriceFeedPerTokenUpdated_Call struct { + *mock.Call +} + +// ParsePriceFeedPerTokenUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParsePriceFeedPerTokenUpdated(log interface{}) *FeeQuoterInterface_ParsePriceFeedPerTokenUpdated_Call { + return &FeeQuoterInterface_ParsePriceFeedPerTokenUpdated_Call{Call: _e.mock.On("ParsePriceFeedPerTokenUpdated", log)} +} + +func (_c *FeeQuoterInterface_ParsePriceFeedPerTokenUpdated_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParsePriceFeedPerTokenUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParsePriceFeedPerTokenUpdated_Call) Return(_a0 *fee_quoter.FeeQuoterPriceFeedPerTokenUpdated, _a1 error) *FeeQuoterInterface_ParsePriceFeedPerTokenUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParsePriceFeedPerTokenUpdated_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterPriceFeedPerTokenUpdated, error)) *FeeQuoterInterface_ParsePriceFeedPerTokenUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ParseReportPermissionSet provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseReportPermissionSet(log types.Log) (*fee_quoter.FeeQuoterReportPermissionSet, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseReportPermissionSet") + } + + var r0 *fee_quoter.FeeQuoterReportPermissionSet + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterReportPermissionSet, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterReportPermissionSet); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterReportPermissionSet) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseReportPermissionSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseReportPermissionSet' +type FeeQuoterInterface_ParseReportPermissionSet_Call struct { + *mock.Call +} + +// ParseReportPermissionSet is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseReportPermissionSet(log interface{}) *FeeQuoterInterface_ParseReportPermissionSet_Call { + return &FeeQuoterInterface_ParseReportPermissionSet_Call{Call: _e.mock.On("ParseReportPermissionSet", log)} +} + +func (_c *FeeQuoterInterface_ParseReportPermissionSet_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseReportPermissionSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseReportPermissionSet_Call) Return(_a0 *fee_quoter.FeeQuoterReportPermissionSet, _a1 error) *FeeQuoterInterface_ParseReportPermissionSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseReportPermissionSet_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterReportPermissionSet, error)) *FeeQuoterInterface_ParseReportPermissionSet_Call { + _c.Call.Return(run) + return _c +} + +// ParseTokenTransferFeeConfigDeleted provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseTokenTransferFeeConfigDeleted(log types.Log) (*fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTokenTransferFeeConfigDeleted") + } + + var r0 *fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseTokenTransferFeeConfigDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTokenTransferFeeConfigDeleted' +type FeeQuoterInterface_ParseTokenTransferFeeConfigDeleted_Call struct { + *mock.Call +} + +// ParseTokenTransferFeeConfigDeleted is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseTokenTransferFeeConfigDeleted(log interface{}) *FeeQuoterInterface_ParseTokenTransferFeeConfigDeleted_Call { + return &FeeQuoterInterface_ParseTokenTransferFeeConfigDeleted_Call{Call: _e.mock.On("ParseTokenTransferFeeConfigDeleted", log)} +} + +func (_c *FeeQuoterInterface_ParseTokenTransferFeeConfigDeleted_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseTokenTransferFeeConfigDeleted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseTokenTransferFeeConfigDeleted_Call) Return(_a0 *fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted, _a1 error) *FeeQuoterInterface_ParseTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseTokenTransferFeeConfigDeleted_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted, error)) *FeeQuoterInterface_ParseTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(run) + return _c +} + +// ParseTokenTransferFeeConfigUpdated provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseTokenTransferFeeConfigUpdated(log types.Log) (*fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseTokenTransferFeeConfigUpdated") + } + + var r0 *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseTokenTransferFeeConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTokenTransferFeeConfigUpdated' +type FeeQuoterInterface_ParseTokenTransferFeeConfigUpdated_Call struct { + *mock.Call +} + +// ParseTokenTransferFeeConfigUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseTokenTransferFeeConfigUpdated(log interface{}) *FeeQuoterInterface_ParseTokenTransferFeeConfigUpdated_Call { + return &FeeQuoterInterface_ParseTokenTransferFeeConfigUpdated_Call{Call: _e.mock.On("ParseTokenTransferFeeConfigUpdated", log)} +} + +func (_c *FeeQuoterInterface_ParseTokenTransferFeeConfigUpdated_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseTokenTransferFeeConfigUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseTokenTransferFeeConfigUpdated_Call) Return(_a0 *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated, _a1 error) *FeeQuoterInterface_ParseTokenTransferFeeConfigUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseTokenTransferFeeConfigUpdated_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated, error)) *FeeQuoterInterface_ParseTokenTransferFeeConfigUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ParseUsdPerTokenUpdated provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseUsdPerTokenUpdated(log types.Log) (*fee_quoter.FeeQuoterUsdPerTokenUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseUsdPerTokenUpdated") + } + + var r0 *fee_quoter.FeeQuoterUsdPerTokenUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterUsdPerTokenUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterUsdPerTokenUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterUsdPerTokenUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseUsdPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseUsdPerTokenUpdated' +type FeeQuoterInterface_ParseUsdPerTokenUpdated_Call struct { + *mock.Call +} + +// ParseUsdPerTokenUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseUsdPerTokenUpdated(log interface{}) *FeeQuoterInterface_ParseUsdPerTokenUpdated_Call { + return &FeeQuoterInterface_ParseUsdPerTokenUpdated_Call{Call: _e.mock.On("ParseUsdPerTokenUpdated", log)} +} + +func (_c *FeeQuoterInterface_ParseUsdPerTokenUpdated_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseUsdPerTokenUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseUsdPerTokenUpdated_Call) Return(_a0 *fee_quoter.FeeQuoterUsdPerTokenUpdated, _a1 error) *FeeQuoterInterface_ParseUsdPerTokenUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseUsdPerTokenUpdated_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterUsdPerTokenUpdated, error)) *FeeQuoterInterface_ParseUsdPerTokenUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ParseUsdPerUnitGasUpdated provides a mock function with given fields: log +func (_m *FeeQuoterInterface) ParseUsdPerUnitGasUpdated(log types.Log) (*fee_quoter.FeeQuoterUsdPerUnitGasUpdated, error) { + ret := _m.Called(log) + + if len(ret) == 0 { + panic("no return value specified for ParseUsdPerUnitGasUpdated") + } + + var r0 *fee_quoter.FeeQuoterUsdPerUnitGasUpdated + var r1 error + if rf, ok := ret.Get(0).(func(types.Log) (*fee_quoter.FeeQuoterUsdPerUnitGasUpdated, error)); ok { + return rf(log) + } + if rf, ok := ret.Get(0).(func(types.Log) *fee_quoter.FeeQuoterUsdPerUnitGasUpdated); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*fee_quoter.FeeQuoterUsdPerUnitGasUpdated) + } + } + + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ParseUsdPerUnitGasUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseUsdPerUnitGasUpdated' +type FeeQuoterInterface_ParseUsdPerUnitGasUpdated_Call struct { + *mock.Call +} + +// ParseUsdPerUnitGasUpdated is a helper method to define mock.On call +// - log types.Log +func (_e *FeeQuoterInterface_Expecter) ParseUsdPerUnitGasUpdated(log interface{}) *FeeQuoterInterface_ParseUsdPerUnitGasUpdated_Call { + return &FeeQuoterInterface_ParseUsdPerUnitGasUpdated_Call{Call: _e.mock.On("ParseUsdPerUnitGasUpdated", log)} +} + +func (_c *FeeQuoterInterface_ParseUsdPerUnitGasUpdated_Call) Run(run func(log types.Log)) *FeeQuoterInterface_ParseUsdPerUnitGasUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Log)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ParseUsdPerUnitGasUpdated_Call) Return(_a0 *fee_quoter.FeeQuoterUsdPerUnitGasUpdated, _a1 error) *FeeQuoterInterface_ParseUsdPerUnitGasUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ParseUsdPerUnitGasUpdated_Call) RunAndReturn(run func(types.Log) (*fee_quoter.FeeQuoterUsdPerUnitGasUpdated, error)) *FeeQuoterInterface_ParseUsdPerUnitGasUpdated_Call { + _c.Call.Return(run) + return _c +} + +// ProcessMessageArgs provides a mock function with given fields: opts, destChainSelector, feeToken, feeTokenAmount, extraArgs +func (_m *FeeQuoterInterface) ProcessMessageArgs(opts *bind.CallOpts, destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (fee_quoter.ProcessMessageArgs, error) { + ret := _m.Called(opts, destChainSelector, feeToken, feeTokenAmount, extraArgs) + + if len(ret) == 0 { + panic("no return value specified for ProcessMessageArgs") + } + + var r0 fee_quoter.ProcessMessageArgs + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address, *big.Int, []byte) (fee_quoter.ProcessMessageArgs, error)); ok { + return rf(opts, destChainSelector, feeToken, feeTokenAmount, extraArgs) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address, *big.Int, []byte) fee_quoter.ProcessMessageArgs); ok { + r0 = rf(opts, destChainSelector, feeToken, feeTokenAmount, extraArgs) + } else { + r0 = ret.Get(0).(fee_quoter.ProcessMessageArgs) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, common.Address, *big.Int, []byte) error); ok { + r1 = rf(opts, destChainSelector, feeToken, feeTokenAmount, extraArgs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ProcessMessageArgs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ProcessMessageArgs' +type FeeQuoterInterface_ProcessMessageArgs_Call struct { + *mock.Call +} + +// ProcessMessageArgs is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +// - feeToken common.Address +// - feeTokenAmount *big.Int +// - extraArgs []byte +func (_e *FeeQuoterInterface_Expecter) ProcessMessageArgs(opts interface{}, destChainSelector interface{}, feeToken interface{}, feeTokenAmount interface{}, extraArgs interface{}) *FeeQuoterInterface_ProcessMessageArgs_Call { + return &FeeQuoterInterface_ProcessMessageArgs_Call{Call: _e.mock.On("ProcessMessageArgs", opts, destChainSelector, feeToken, feeTokenAmount, extraArgs)} +} + +func (_c *FeeQuoterInterface_ProcessMessageArgs_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte)) *FeeQuoterInterface_ProcessMessageArgs_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(common.Address), args[3].(*big.Int), args[4].([]byte)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ProcessMessageArgs_Call) Return(_a0 fee_quoter.ProcessMessageArgs, _a1 error) *FeeQuoterInterface_ProcessMessageArgs_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ProcessMessageArgs_Call) RunAndReturn(run func(*bind.CallOpts, uint64, common.Address, *big.Int, []byte) (fee_quoter.ProcessMessageArgs, error)) *FeeQuoterInterface_ProcessMessageArgs_Call { + _c.Call.Return(run) + return _c +} + +// ProcessPoolReturnData provides a mock function with given fields: opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts +func (_m *FeeQuoterInterface) ProcessPoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []fee_quoter.InternalRampTokenAmount, sourceTokenAmounts []fee_quoter.ClientEVMTokenAmount) ([][]byte, error) { + ret := _m.Called(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) + + if len(ret) == 0 { + panic("no return value specified for ProcessPoolReturnData") + } + + var r0 [][]byte + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, []fee_quoter.InternalRampTokenAmount, []fee_quoter.ClientEVMTokenAmount) ([][]byte, error)); ok { + return rf(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, []fee_quoter.InternalRampTokenAmount, []fee_quoter.ClientEVMTokenAmount) [][]byte); ok { + r0 = rf(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([][]byte) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, []fee_quoter.InternalRampTokenAmount, []fee_quoter.ClientEVMTokenAmount) error); ok { + r1 = rf(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_ProcessPoolReturnData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ProcessPoolReturnData' +type FeeQuoterInterface_ProcessPoolReturnData_Call struct { + *mock.Call +} + +// ProcessPoolReturnData is a helper method to define mock.On call +// - opts *bind.CallOpts +// - destChainSelector uint64 +// - rampTokenAmounts []fee_quoter.InternalRampTokenAmount +// - sourceTokenAmounts []fee_quoter.ClientEVMTokenAmount +func (_e *FeeQuoterInterface_Expecter) ProcessPoolReturnData(opts interface{}, destChainSelector interface{}, rampTokenAmounts interface{}, sourceTokenAmounts interface{}) *FeeQuoterInterface_ProcessPoolReturnData_Call { + return &FeeQuoterInterface_ProcessPoolReturnData_Call{Call: _e.mock.On("ProcessPoolReturnData", opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts)} +} + +func (_c *FeeQuoterInterface_ProcessPoolReturnData_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []fee_quoter.InternalRampTokenAmount, sourceTokenAmounts []fee_quoter.ClientEVMTokenAmount)) *FeeQuoterInterface_ProcessPoolReturnData_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].([]fee_quoter.InternalRampTokenAmount), args[3].([]fee_quoter.ClientEVMTokenAmount)) + }) + return _c +} + +func (_c *FeeQuoterInterface_ProcessPoolReturnData_Call) Return(_a0 [][]byte, _a1 error) *FeeQuoterInterface_ProcessPoolReturnData_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_ProcessPoolReturnData_Call) RunAndReturn(run func(*bind.CallOpts, uint64, []fee_quoter.InternalRampTokenAmount, []fee_quoter.ClientEVMTokenAmount) ([][]byte, error)) *FeeQuoterInterface_ProcessPoolReturnData_Call { + _c.Call.Return(run) + return _c +} + +// SetReportPermissions provides a mock function with given fields: opts, permissions +func (_m *FeeQuoterInterface) SetReportPermissions(opts *bind.TransactOpts, permissions []fee_quoter.KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { + ret := _m.Called(opts, permissions) + + if len(ret) == 0 { + panic("no return value specified for SetReportPermissions") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []fee_quoter.KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error)); ok { + return rf(opts, permissions) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []fee_quoter.KeystoneFeedsPermissionHandlerPermission) *types.Transaction); ok { + r0 = rf(opts, permissions) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []fee_quoter.KeystoneFeedsPermissionHandlerPermission) error); ok { + r1 = rf(opts, permissions) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_SetReportPermissions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetReportPermissions' +type FeeQuoterInterface_SetReportPermissions_Call struct { + *mock.Call +} + +// SetReportPermissions is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - permissions []fee_quoter.KeystoneFeedsPermissionHandlerPermission +func (_e *FeeQuoterInterface_Expecter) SetReportPermissions(opts interface{}, permissions interface{}) *FeeQuoterInterface_SetReportPermissions_Call { + return &FeeQuoterInterface_SetReportPermissions_Call{Call: _e.mock.On("SetReportPermissions", opts, permissions)} +} + +func (_c *FeeQuoterInterface_SetReportPermissions_Call) Run(run func(opts *bind.TransactOpts, permissions []fee_quoter.KeystoneFeedsPermissionHandlerPermission)) *FeeQuoterInterface_SetReportPermissions_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]fee_quoter.KeystoneFeedsPermissionHandlerPermission)) + }) + return _c +} + +func (_c *FeeQuoterInterface_SetReportPermissions_Call) Return(_a0 *types.Transaction, _a1 error) *FeeQuoterInterface_SetReportPermissions_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_SetReportPermissions_Call) RunAndReturn(run func(*bind.TransactOpts, []fee_quoter.KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error)) *FeeQuoterInterface_SetReportPermissions_Call { + _c.Call.Return(run) + return _c +} + +// TransferOwnership provides a mock function with given fields: opts, to +func (_m *FeeQuoterInterface) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + ret := _m.Called(opts, to) + + if len(ret) == 0 { + panic("no return value specified for TransferOwnership") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { + return rf(opts, to) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { + r0 = rf(opts, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { + r1 = rf(opts, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_TransferOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TransferOwnership' +type FeeQuoterInterface_TransferOwnership_Call struct { + *mock.Call +} + +// TransferOwnership is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - to common.Address +func (_e *FeeQuoterInterface_Expecter) TransferOwnership(opts interface{}, to interface{}) *FeeQuoterInterface_TransferOwnership_Call { + return &FeeQuoterInterface_TransferOwnership_Call{Call: _e.mock.On("TransferOwnership", opts, to)} +} + +func (_c *FeeQuoterInterface_TransferOwnership_Call) Run(run func(opts *bind.TransactOpts, to common.Address)) *FeeQuoterInterface_TransferOwnership_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_TransferOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *FeeQuoterInterface_TransferOwnership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_TransferOwnership_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *FeeQuoterInterface_TransferOwnership_Call { + _c.Call.Return(run) + return _c +} + +// TypeAndVersion provides a mock function with given fields: opts +func (_m *FeeQuoterInterface) TypeAndVersion(opts *bind.CallOpts) (string, error) { + ret := _m.Called(opts) + + if len(ret) == 0 { + panic("no return value specified for TypeAndVersion") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts) (string, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts) string); ok { + r0 = rf(opts) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_TypeAndVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TypeAndVersion' +type FeeQuoterInterface_TypeAndVersion_Call struct { + *mock.Call +} + +// TypeAndVersion is a helper method to define mock.On call +// - opts *bind.CallOpts +func (_e *FeeQuoterInterface_Expecter) TypeAndVersion(opts interface{}) *FeeQuoterInterface_TypeAndVersion_Call { + return &FeeQuoterInterface_TypeAndVersion_Call{Call: _e.mock.On("TypeAndVersion", opts)} +} + +func (_c *FeeQuoterInterface_TypeAndVersion_Call) Run(run func(opts *bind.CallOpts)) *FeeQuoterInterface_TypeAndVersion_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts)) + }) + return _c +} + +func (_c *FeeQuoterInterface_TypeAndVersion_Call) Return(_a0 string, _a1 error) *FeeQuoterInterface_TypeAndVersion_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_TypeAndVersion_Call) RunAndReturn(run func(*bind.CallOpts) (string, error)) *FeeQuoterInterface_TypeAndVersion_Call { + _c.Call.Return(run) + return _c +} + +// UpdatePrices provides a mock function with given fields: opts, priceUpdates +func (_m *FeeQuoterInterface) UpdatePrices(opts *bind.TransactOpts, priceUpdates fee_quoter.InternalPriceUpdates) (*types.Transaction, error) { + ret := _m.Called(opts, priceUpdates) + + if len(ret) == 0 { + panic("no return value specified for UpdatePrices") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, fee_quoter.InternalPriceUpdates) (*types.Transaction, error)); ok { + return rf(opts, priceUpdates) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, fee_quoter.InternalPriceUpdates) *types.Transaction); ok { + r0 = rf(opts, priceUpdates) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, fee_quoter.InternalPriceUpdates) error); ok { + r1 = rf(opts, priceUpdates) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_UpdatePrices_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdatePrices' +type FeeQuoterInterface_UpdatePrices_Call struct { + *mock.Call +} + +// UpdatePrices is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - priceUpdates fee_quoter.InternalPriceUpdates +func (_e *FeeQuoterInterface_Expecter) UpdatePrices(opts interface{}, priceUpdates interface{}) *FeeQuoterInterface_UpdatePrices_Call { + return &FeeQuoterInterface_UpdatePrices_Call{Call: _e.mock.On("UpdatePrices", opts, priceUpdates)} +} + +func (_c *FeeQuoterInterface_UpdatePrices_Call) Run(run func(opts *bind.TransactOpts, priceUpdates fee_quoter.InternalPriceUpdates)) *FeeQuoterInterface_UpdatePrices_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].(fee_quoter.InternalPriceUpdates)) + }) + return _c +} + +func (_c *FeeQuoterInterface_UpdatePrices_Call) Return(_a0 *types.Transaction, _a1 error) *FeeQuoterInterface_UpdatePrices_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_UpdatePrices_Call) RunAndReturn(run func(*bind.TransactOpts, fee_quoter.InternalPriceUpdates) (*types.Transaction, error)) *FeeQuoterInterface_UpdatePrices_Call { + _c.Call.Return(run) + return _c +} + +// UpdateTokenPriceFeeds provides a mock function with given fields: opts, tokenPriceFeedUpdates +func (_m *FeeQuoterInterface) UpdateTokenPriceFeeds(opts *bind.TransactOpts, tokenPriceFeedUpdates []fee_quoter.FeeQuoterTokenPriceFeedUpdate) (*types.Transaction, error) { + ret := _m.Called(opts, tokenPriceFeedUpdates) + + if len(ret) == 0 { + panic("no return value specified for UpdateTokenPriceFeeds") + } + + var r0 *types.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []fee_quoter.FeeQuoterTokenPriceFeedUpdate) (*types.Transaction, error)); ok { + return rf(opts, tokenPriceFeedUpdates) + } + if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []fee_quoter.FeeQuoterTokenPriceFeedUpdate) *types.Transaction); ok { + r0 = rf(opts, tokenPriceFeedUpdates) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []fee_quoter.FeeQuoterTokenPriceFeedUpdate) error); ok { + r1 = rf(opts, tokenPriceFeedUpdates) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_UpdateTokenPriceFeeds_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateTokenPriceFeeds' +type FeeQuoterInterface_UpdateTokenPriceFeeds_Call struct { + *mock.Call +} + +// UpdateTokenPriceFeeds is a helper method to define mock.On call +// - opts *bind.TransactOpts +// - tokenPriceFeedUpdates []fee_quoter.FeeQuoterTokenPriceFeedUpdate +func (_e *FeeQuoterInterface_Expecter) UpdateTokenPriceFeeds(opts interface{}, tokenPriceFeedUpdates interface{}) *FeeQuoterInterface_UpdateTokenPriceFeeds_Call { + return &FeeQuoterInterface_UpdateTokenPriceFeeds_Call{Call: _e.mock.On("UpdateTokenPriceFeeds", opts, tokenPriceFeedUpdates)} +} + +func (_c *FeeQuoterInterface_UpdateTokenPriceFeeds_Call) Run(run func(opts *bind.TransactOpts, tokenPriceFeedUpdates []fee_quoter.FeeQuoterTokenPriceFeedUpdate)) *FeeQuoterInterface_UpdateTokenPriceFeeds_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.TransactOpts), args[1].([]fee_quoter.FeeQuoterTokenPriceFeedUpdate)) + }) + return _c +} + +func (_c *FeeQuoterInterface_UpdateTokenPriceFeeds_Call) Return(_a0 *types.Transaction, _a1 error) *FeeQuoterInterface_UpdateTokenPriceFeeds_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_UpdateTokenPriceFeeds_Call) RunAndReturn(run func(*bind.TransactOpts, []fee_quoter.FeeQuoterTokenPriceFeedUpdate) (*types.Transaction, error)) *FeeQuoterInterface_UpdateTokenPriceFeeds_Call { + _c.Call.Return(run) + return _c +} + +// WatchAuthorizedCallerAdded provides a mock function with given fields: opts, sink +func (_m *FeeQuoterInterface) WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterAuthorizedCallerAdded) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchAuthorizedCallerAdded") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterAuthorizedCallerAdded) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterAuthorizedCallerAdded) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterAuthorizedCallerAdded) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchAuthorizedCallerAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchAuthorizedCallerAdded' +type FeeQuoterInterface_WatchAuthorizedCallerAdded_Call struct { + *mock.Call +} + +// WatchAuthorizedCallerAdded is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterAuthorizedCallerAdded +func (_e *FeeQuoterInterface_Expecter) WatchAuthorizedCallerAdded(opts interface{}, sink interface{}) *FeeQuoterInterface_WatchAuthorizedCallerAdded_Call { + return &FeeQuoterInterface_WatchAuthorizedCallerAdded_Call{Call: _e.mock.On("WatchAuthorizedCallerAdded", opts, sink)} +} + +func (_c *FeeQuoterInterface_WatchAuthorizedCallerAdded_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterAuthorizedCallerAdded)) *FeeQuoterInterface_WatchAuthorizedCallerAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterAuthorizedCallerAdded)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchAuthorizedCallerAdded_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchAuthorizedCallerAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchAuthorizedCallerAdded_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterAuthorizedCallerAdded) (event.Subscription, error)) *FeeQuoterInterface_WatchAuthorizedCallerAdded_Call { + _c.Call.Return(run) + return _c +} + +// WatchAuthorizedCallerRemoved provides a mock function with given fields: opts, sink +func (_m *FeeQuoterInterface) WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterAuthorizedCallerRemoved) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + if len(ret) == 0 { + panic("no return value specified for WatchAuthorizedCallerRemoved") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterAuthorizedCallerRemoved) (event.Subscription, error)); ok { + return rf(opts, sink) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterAuthorizedCallerRemoved) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterAuthorizedCallerRemoved) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchAuthorizedCallerRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchAuthorizedCallerRemoved' +type FeeQuoterInterface_WatchAuthorizedCallerRemoved_Call struct { + *mock.Call +} + +// WatchAuthorizedCallerRemoved is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterAuthorizedCallerRemoved +func (_e *FeeQuoterInterface_Expecter) WatchAuthorizedCallerRemoved(opts interface{}, sink interface{}) *FeeQuoterInterface_WatchAuthorizedCallerRemoved_Call { + return &FeeQuoterInterface_WatchAuthorizedCallerRemoved_Call{Call: _e.mock.On("WatchAuthorizedCallerRemoved", opts, sink)} +} + +func (_c *FeeQuoterInterface_WatchAuthorizedCallerRemoved_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterAuthorizedCallerRemoved)) *FeeQuoterInterface_WatchAuthorizedCallerRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterAuthorizedCallerRemoved)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchAuthorizedCallerRemoved_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchAuthorizedCallerRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchAuthorizedCallerRemoved_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterAuthorizedCallerRemoved) (event.Subscription, error)) *FeeQuoterInterface_WatchAuthorizedCallerRemoved_Call { + _c.Call.Return(run) + return _c +} + +// WatchDestChainAdded provides a mock function with given fields: opts, sink, destChainSelector +func (_m *FeeQuoterInterface) WatchDestChainAdded(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterDestChainAdded, destChainSelector []uint64) (event.Subscription, error) { + ret := _m.Called(opts, sink, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for WatchDestChainAdded") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterDestChainAdded, []uint64) (event.Subscription, error)); ok { + return rf(opts, sink, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterDestChainAdded, []uint64) event.Subscription); ok { + r0 = rf(opts, sink, destChainSelector) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterDestChainAdded, []uint64) error); ok { + r1 = rf(opts, sink, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchDestChainAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchDestChainAdded' +type FeeQuoterInterface_WatchDestChainAdded_Call struct { + *mock.Call +} + +// WatchDestChainAdded is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterDestChainAdded +// - destChainSelector []uint64 +func (_e *FeeQuoterInterface_Expecter) WatchDestChainAdded(opts interface{}, sink interface{}, destChainSelector interface{}) *FeeQuoterInterface_WatchDestChainAdded_Call { + return &FeeQuoterInterface_WatchDestChainAdded_Call{Call: _e.mock.On("WatchDestChainAdded", opts, sink, destChainSelector)} +} + +func (_c *FeeQuoterInterface_WatchDestChainAdded_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterDestChainAdded, destChainSelector []uint64)) *FeeQuoterInterface_WatchDestChainAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterDestChainAdded), args[2].([]uint64)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchDestChainAdded_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchDestChainAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchDestChainAdded_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterDestChainAdded, []uint64) (event.Subscription, error)) *FeeQuoterInterface_WatchDestChainAdded_Call { + _c.Call.Return(run) + return _c +} + +// WatchDestChainConfigUpdated provides a mock function with given fields: opts, sink, destChainSelector +func (_m *FeeQuoterInterface) WatchDestChainConfigUpdated(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterDestChainConfigUpdated, destChainSelector []uint64) (event.Subscription, error) { + ret := _m.Called(opts, sink, destChainSelector) + + if len(ret) == 0 { + panic("no return value specified for WatchDestChainConfigUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterDestChainConfigUpdated, []uint64) (event.Subscription, error)); ok { + return rf(opts, sink, destChainSelector) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterDestChainConfigUpdated, []uint64) event.Subscription); ok { + r0 = rf(opts, sink, destChainSelector) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterDestChainConfigUpdated, []uint64) error); ok { + r1 = rf(opts, sink, destChainSelector) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchDestChainConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchDestChainConfigUpdated' +type FeeQuoterInterface_WatchDestChainConfigUpdated_Call struct { + *mock.Call +} + +// WatchDestChainConfigUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterDestChainConfigUpdated +// - destChainSelector []uint64 +func (_e *FeeQuoterInterface_Expecter) WatchDestChainConfigUpdated(opts interface{}, sink interface{}, destChainSelector interface{}) *FeeQuoterInterface_WatchDestChainConfigUpdated_Call { + return &FeeQuoterInterface_WatchDestChainConfigUpdated_Call{Call: _e.mock.On("WatchDestChainConfigUpdated", opts, sink, destChainSelector)} +} + +func (_c *FeeQuoterInterface_WatchDestChainConfigUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterDestChainConfigUpdated, destChainSelector []uint64)) *FeeQuoterInterface_WatchDestChainConfigUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterDestChainConfigUpdated), args[2].([]uint64)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchDestChainConfigUpdated_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchDestChainConfigUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchDestChainConfigUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterDestChainConfigUpdated, []uint64) (event.Subscription, error)) *FeeQuoterInterface_WatchDestChainConfigUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WatchFeeTokenAdded provides a mock function with given fields: opts, sink, feeToken +func (_m *FeeQuoterInterface) WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, feeToken) + + if len(ret) == 0 { + panic("no return value specified for WatchFeeTokenAdded") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterFeeTokenAdded, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, feeToken) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterFeeTokenAdded, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, feeToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterFeeTokenAdded, []common.Address) error); ok { + r1 = rf(opts, sink, feeToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchFeeTokenAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchFeeTokenAdded' +type FeeQuoterInterface_WatchFeeTokenAdded_Call struct { + *mock.Call +} + +// WatchFeeTokenAdded is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterFeeTokenAdded +// - feeToken []common.Address +func (_e *FeeQuoterInterface_Expecter) WatchFeeTokenAdded(opts interface{}, sink interface{}, feeToken interface{}) *FeeQuoterInterface_WatchFeeTokenAdded_Call { + return &FeeQuoterInterface_WatchFeeTokenAdded_Call{Call: _e.mock.On("WatchFeeTokenAdded", opts, sink, feeToken)} +} + +func (_c *FeeQuoterInterface_WatchFeeTokenAdded_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterFeeTokenAdded, feeToken []common.Address)) *FeeQuoterInterface_WatchFeeTokenAdded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterFeeTokenAdded), args[2].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchFeeTokenAdded_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchFeeTokenAdded_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchFeeTokenAdded_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterFeeTokenAdded, []common.Address) (event.Subscription, error)) *FeeQuoterInterface_WatchFeeTokenAdded_Call { + _c.Call.Return(run) + return _c +} + +// WatchFeeTokenRemoved provides a mock function with given fields: opts, sink, feeToken +func (_m *FeeQuoterInterface) WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, feeToken) + + if len(ret) == 0 { + panic("no return value specified for WatchFeeTokenRemoved") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterFeeTokenRemoved, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, feeToken) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterFeeTokenRemoved, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, feeToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterFeeTokenRemoved, []common.Address) error); ok { + r1 = rf(opts, sink, feeToken) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchFeeTokenRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchFeeTokenRemoved' +type FeeQuoterInterface_WatchFeeTokenRemoved_Call struct { + *mock.Call +} + +// WatchFeeTokenRemoved is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterFeeTokenRemoved +// - feeToken []common.Address +func (_e *FeeQuoterInterface_Expecter) WatchFeeTokenRemoved(opts interface{}, sink interface{}, feeToken interface{}) *FeeQuoterInterface_WatchFeeTokenRemoved_Call { + return &FeeQuoterInterface_WatchFeeTokenRemoved_Call{Call: _e.mock.On("WatchFeeTokenRemoved", opts, sink, feeToken)} +} + +func (_c *FeeQuoterInterface_WatchFeeTokenRemoved_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterFeeTokenRemoved, feeToken []common.Address)) *FeeQuoterInterface_WatchFeeTokenRemoved_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterFeeTokenRemoved), args[2].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchFeeTokenRemoved_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchFeeTokenRemoved_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchFeeTokenRemoved_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterFeeTokenRemoved, []common.Address) (event.Subscription, error)) *FeeQuoterInterface_WatchFeeTokenRemoved_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferRequested provides a mock function with given fields: opts, sink, from, to +func (_m *FeeQuoterInterface) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferRequested") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterOwnershipTransferRequested, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterOwnershipTransferRequested, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferRequested' +type FeeQuoterInterface_WatchOwnershipTransferRequested_Call struct { + *mock.Call +} + +// WatchOwnershipTransferRequested is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterOwnershipTransferRequested +// - from []common.Address +// - to []common.Address +func (_e *FeeQuoterInterface_Expecter) WatchOwnershipTransferRequested(opts interface{}, sink interface{}, from interface{}, to interface{}) *FeeQuoterInterface_WatchOwnershipTransferRequested_Call { + return &FeeQuoterInterface_WatchOwnershipTransferRequested_Call{Call: _e.mock.On("WatchOwnershipTransferRequested", opts, sink, from, to)} +} + +func (_c *FeeQuoterInterface_WatchOwnershipTransferRequested_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterOwnershipTransferRequested, from []common.Address, to []common.Address)) *FeeQuoterInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterOwnershipTransferRequested), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchOwnershipTransferRequested_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)) *FeeQuoterInterface_WatchOwnershipTransferRequested_Call { + _c.Call.Return(run) + return _c +} + +// WatchOwnershipTransferred provides a mock function with given fields: opts, sink, from, to +func (_m *FeeQuoterInterface) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, from, to) + + if len(ret) == 0 { + panic("no return value specified for WatchOwnershipTransferred") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, from, to) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterOwnershipTransferred, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, from, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterOwnershipTransferred, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, from, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferred' +type FeeQuoterInterface_WatchOwnershipTransferred_Call struct { + *mock.Call +} + +// WatchOwnershipTransferred is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterOwnershipTransferred +// - from []common.Address +// - to []common.Address +func (_e *FeeQuoterInterface_Expecter) WatchOwnershipTransferred(opts interface{}, sink interface{}, from interface{}, to interface{}) *FeeQuoterInterface_WatchOwnershipTransferred_Call { + return &FeeQuoterInterface_WatchOwnershipTransferred_Call{Call: _e.mock.On("WatchOwnershipTransferred", opts, sink, from, to)} +} + +func (_c *FeeQuoterInterface_WatchOwnershipTransferred_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterOwnershipTransferred, from []common.Address, to []common.Address)) *FeeQuoterInterface_WatchOwnershipTransferred_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterOwnershipTransferred), args[2].([]common.Address), args[3].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchOwnershipTransferred_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchOwnershipTransferred_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)) *FeeQuoterInterface_WatchOwnershipTransferred_Call { + _c.Call.Return(run) + return _c +} + +// WatchPremiumMultiplierWeiPerEthUpdated provides a mock function with given fields: opts, sink, token +func (_m *FeeQuoterInterface) WatchPremiumMultiplierWeiPerEthUpdated(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated, token []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, token) + + if len(ret) == 0 { + panic("no return value specified for WatchPremiumMultiplierWeiPerEthUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, token) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated, []common.Address) error); ok { + r1 = rf(opts, sink, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPremiumMultiplierWeiPerEthUpdated' +type FeeQuoterInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call struct { + *mock.Call +} + +// WatchPremiumMultiplierWeiPerEthUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated +// - token []common.Address +func (_e *FeeQuoterInterface_Expecter) WatchPremiumMultiplierWeiPerEthUpdated(opts interface{}, sink interface{}, token interface{}) *FeeQuoterInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call { + return &FeeQuoterInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call{Call: _e.mock.On("WatchPremiumMultiplierWeiPerEthUpdated", opts, sink, token)} +} + +func (_c *FeeQuoterInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated, token []common.Address)) *FeeQuoterInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated), args[2].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthUpdated, []common.Address) (event.Subscription, error)) *FeeQuoterInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WatchPriceFeedPerTokenUpdated provides a mock function with given fields: opts, sink, token +func (_m *FeeQuoterInterface) WatchPriceFeedPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterPriceFeedPerTokenUpdated, token []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, token) + + if len(ret) == 0 { + panic("no return value specified for WatchPriceFeedPerTokenUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterPriceFeedPerTokenUpdated, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, token) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterPriceFeedPerTokenUpdated, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterPriceFeedPerTokenUpdated, []common.Address) error); ok { + r1 = rf(opts, sink, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchPriceFeedPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPriceFeedPerTokenUpdated' +type FeeQuoterInterface_WatchPriceFeedPerTokenUpdated_Call struct { + *mock.Call +} + +// WatchPriceFeedPerTokenUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterPriceFeedPerTokenUpdated +// - token []common.Address +func (_e *FeeQuoterInterface_Expecter) WatchPriceFeedPerTokenUpdated(opts interface{}, sink interface{}, token interface{}) *FeeQuoterInterface_WatchPriceFeedPerTokenUpdated_Call { + return &FeeQuoterInterface_WatchPriceFeedPerTokenUpdated_Call{Call: _e.mock.On("WatchPriceFeedPerTokenUpdated", opts, sink, token)} +} + +func (_c *FeeQuoterInterface_WatchPriceFeedPerTokenUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterPriceFeedPerTokenUpdated, token []common.Address)) *FeeQuoterInterface_WatchPriceFeedPerTokenUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterPriceFeedPerTokenUpdated), args[2].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchPriceFeedPerTokenUpdated_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchPriceFeedPerTokenUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchPriceFeedPerTokenUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterPriceFeedPerTokenUpdated, []common.Address) (event.Subscription, error)) *FeeQuoterInterface_WatchPriceFeedPerTokenUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WatchReportPermissionSet provides a mock function with given fields: opts, sink, reportId +func (_m *FeeQuoterInterface) WatchReportPermissionSet(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterReportPermissionSet, reportId [][32]byte) (event.Subscription, error) { + ret := _m.Called(opts, sink, reportId) + + if len(ret) == 0 { + panic("no return value specified for WatchReportPermissionSet") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterReportPermissionSet, [][32]byte) (event.Subscription, error)); ok { + return rf(opts, sink, reportId) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterReportPermissionSet, [][32]byte) event.Subscription); ok { + r0 = rf(opts, sink, reportId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterReportPermissionSet, [][32]byte) error); ok { + r1 = rf(opts, sink, reportId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchReportPermissionSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchReportPermissionSet' +type FeeQuoterInterface_WatchReportPermissionSet_Call struct { + *mock.Call +} + +// WatchReportPermissionSet is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterReportPermissionSet +// - reportId [][32]byte +func (_e *FeeQuoterInterface_Expecter) WatchReportPermissionSet(opts interface{}, sink interface{}, reportId interface{}) *FeeQuoterInterface_WatchReportPermissionSet_Call { + return &FeeQuoterInterface_WatchReportPermissionSet_Call{Call: _e.mock.On("WatchReportPermissionSet", opts, sink, reportId)} +} + +func (_c *FeeQuoterInterface_WatchReportPermissionSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterReportPermissionSet, reportId [][32]byte)) *FeeQuoterInterface_WatchReportPermissionSet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterReportPermissionSet), args[2].([][32]byte)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchReportPermissionSet_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchReportPermissionSet_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchReportPermissionSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterReportPermissionSet, [][32]byte) (event.Subscription, error)) *FeeQuoterInterface_WatchReportPermissionSet_Call { + _c.Call.Return(run) + return _c +} + +// WatchTokenTransferFeeConfigDeleted provides a mock function with given fields: opts, sink, destChainSelector, token +func (_m *FeeQuoterInterface) WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, destChainSelector, token) + + if len(ret) == 0 { + panic("no return value specified for WatchTokenTransferFeeConfigDeleted") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted, []uint64, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, destChainSelector, token) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted, []uint64, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, destChainSelector, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted, []uint64, []common.Address) error); ok { + r1 = rf(opts, sink, destChainSelector, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchTokenTransferFeeConfigDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTokenTransferFeeConfigDeleted' +type FeeQuoterInterface_WatchTokenTransferFeeConfigDeleted_Call struct { + *mock.Call +} + +// WatchTokenTransferFeeConfigDeleted is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted +// - destChainSelector []uint64 +// - token []common.Address +func (_e *FeeQuoterInterface_Expecter) WatchTokenTransferFeeConfigDeleted(opts interface{}, sink interface{}, destChainSelector interface{}, token interface{}) *FeeQuoterInterface_WatchTokenTransferFeeConfigDeleted_Call { + return &FeeQuoterInterface_WatchTokenTransferFeeConfigDeleted_Call{Call: _e.mock.On("WatchTokenTransferFeeConfigDeleted", opts, sink, destChainSelector, token)} +} + +func (_c *FeeQuoterInterface_WatchTokenTransferFeeConfigDeleted_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address)) *FeeQuoterInterface_WatchTokenTransferFeeConfigDeleted_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted), args[2].([]uint64), args[3].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchTokenTransferFeeConfigDeleted_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchTokenTransferFeeConfigDeleted_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigDeleted, []uint64, []common.Address) (event.Subscription, error)) *FeeQuoterInterface_WatchTokenTransferFeeConfigDeleted_Call { + _c.Call.Return(run) + return _c +} + +// WatchTokenTransferFeeConfigUpdated provides a mock function with given fields: opts, sink, destChainSelector, token +func (_m *FeeQuoterInterface) WatchTokenTransferFeeConfigUpdated(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, destChainSelector, token) + + if len(ret) == 0 { + panic("no return value specified for WatchTokenTransferFeeConfigUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated, []uint64, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, destChainSelector, token) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated, []uint64, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, destChainSelector, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated, []uint64, []common.Address) error); ok { + r1 = rf(opts, sink, destChainSelector, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchTokenTransferFeeConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTokenTransferFeeConfigUpdated' +type FeeQuoterInterface_WatchTokenTransferFeeConfigUpdated_Call struct { + *mock.Call +} + +// WatchTokenTransferFeeConfigUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated +// - destChainSelector []uint64 +// - token []common.Address +func (_e *FeeQuoterInterface_Expecter) WatchTokenTransferFeeConfigUpdated(opts interface{}, sink interface{}, destChainSelector interface{}, token interface{}) *FeeQuoterInterface_WatchTokenTransferFeeConfigUpdated_Call { + return &FeeQuoterInterface_WatchTokenTransferFeeConfigUpdated_Call{Call: _e.mock.On("WatchTokenTransferFeeConfigUpdated", opts, sink, destChainSelector, token)} +} + +func (_c *FeeQuoterInterface_WatchTokenTransferFeeConfigUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated, destChainSelector []uint64, token []common.Address)) *FeeQuoterInterface_WatchTokenTransferFeeConfigUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated), args[2].([]uint64), args[3].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchTokenTransferFeeConfigUpdated_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchTokenTransferFeeConfigUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchTokenTransferFeeConfigUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterTokenTransferFeeConfigUpdated, []uint64, []common.Address) (event.Subscription, error)) *FeeQuoterInterface_WatchTokenTransferFeeConfigUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WatchUsdPerTokenUpdated provides a mock function with given fields: opts, sink, token +func (_m *FeeQuoterInterface) WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, token) + + if len(ret) == 0 { + panic("no return value specified for WatchUsdPerTokenUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterUsdPerTokenUpdated, []common.Address) (event.Subscription, error)); ok { + return rf(opts, sink, token) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterUsdPerTokenUpdated, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterUsdPerTokenUpdated, []common.Address) error); ok { + r1 = rf(opts, sink, token) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchUsdPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchUsdPerTokenUpdated' +type FeeQuoterInterface_WatchUsdPerTokenUpdated_Call struct { + *mock.Call +} + +// WatchUsdPerTokenUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterUsdPerTokenUpdated +// - token []common.Address +func (_e *FeeQuoterInterface_Expecter) WatchUsdPerTokenUpdated(opts interface{}, sink interface{}, token interface{}) *FeeQuoterInterface_WatchUsdPerTokenUpdated_Call { + return &FeeQuoterInterface_WatchUsdPerTokenUpdated_Call{Call: _e.mock.On("WatchUsdPerTokenUpdated", opts, sink, token)} +} + +func (_c *FeeQuoterInterface_WatchUsdPerTokenUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterUsdPerTokenUpdated, token []common.Address)) *FeeQuoterInterface_WatchUsdPerTokenUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterUsdPerTokenUpdated), args[2].([]common.Address)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchUsdPerTokenUpdated_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchUsdPerTokenUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchUsdPerTokenUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterUsdPerTokenUpdated, []common.Address) (event.Subscription, error)) *FeeQuoterInterface_WatchUsdPerTokenUpdated_Call { + _c.Call.Return(run) + return _c +} + +// WatchUsdPerUnitGasUpdated provides a mock function with given fields: opts, sink, destChain +func (_m *FeeQuoterInterface) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) { + ret := _m.Called(opts, sink, destChain) + + if len(ret) == 0 { + panic("no return value specified for WatchUsdPerUnitGasUpdated") + } + + var r0 event.Subscription + var r1 error + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterUsdPerUnitGasUpdated, []uint64) (event.Subscription, error)); ok { + return rf(opts, sink, destChain) + } + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterUsdPerUnitGasUpdated, []uint64) event.Subscription); ok { + r0 = rf(opts, sink, destChain) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterUsdPerUnitGasUpdated, []uint64) error); ok { + r1 = rf(opts, sink, destChain) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeQuoterInterface_WatchUsdPerUnitGasUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchUsdPerUnitGasUpdated' +type FeeQuoterInterface_WatchUsdPerUnitGasUpdated_Call struct { + *mock.Call +} + +// WatchUsdPerUnitGasUpdated is a helper method to define mock.On call +// - opts *bind.WatchOpts +// - sink chan<- *fee_quoter.FeeQuoterUsdPerUnitGasUpdated +// - destChain []uint64 +func (_e *FeeQuoterInterface_Expecter) WatchUsdPerUnitGasUpdated(opts interface{}, sink interface{}, destChain interface{}) *FeeQuoterInterface_WatchUsdPerUnitGasUpdated_Call { + return &FeeQuoterInterface_WatchUsdPerUnitGasUpdated_Call{Call: _e.mock.On("WatchUsdPerUnitGasUpdated", opts, sink, destChain)} +} + +func (_c *FeeQuoterInterface_WatchUsdPerUnitGasUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *fee_quoter.FeeQuoterUsdPerUnitGasUpdated, destChain []uint64)) *FeeQuoterInterface_WatchUsdPerUnitGasUpdated_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.WatchOpts), args[1].(chan<- *fee_quoter.FeeQuoterUsdPerUnitGasUpdated), args[2].([]uint64)) + }) + return _c +} + +func (_c *FeeQuoterInterface_WatchUsdPerUnitGasUpdated_Call) Return(_a0 event.Subscription, _a1 error) *FeeQuoterInterface_WatchUsdPerUnitGasUpdated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeQuoterInterface_WatchUsdPerUnitGasUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *fee_quoter.FeeQuoterUsdPerUnitGasUpdated, []uint64) (event.Subscription, error)) *FeeQuoterInterface_WatchUsdPerUnitGasUpdated_Call { + _c.Call.Return(run) + return _c +} + +// NewFeeQuoterInterface creates a new instance of FeeQuoterInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewFeeQuoterInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *FeeQuoterInterface { + mock := &FeeQuoterInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/gethwrappers/ccip/mocks/price_registry_interface.go b/core/gethwrappers/ccip/mocks/price_registry_interface.go deleted file mode 100644 index 04104ce835..0000000000 --- a/core/gethwrappers/ccip/mocks/price_registry_interface.go +++ /dev/null @@ -1,4509 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package mock_contracts - -import ( - big "math/big" - - bind "github.com/ethereum/go-ethereum/accounts/abi/bind" - common "github.com/ethereum/go-ethereum/common" - - event "github.com/ethereum/go-ethereum/event" - - generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" - - mock "github.com/stretchr/testify/mock" - - price_registry "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" - - types "github.com/ethereum/go-ethereum/core/types" -) - -// PriceRegistryInterface is an autogenerated mock type for the PriceRegistryInterface type -type PriceRegistryInterface struct { - mock.Mock -} - -type PriceRegistryInterface_Expecter struct { - mock *mock.Mock -} - -func (_m *PriceRegistryInterface) EXPECT() *PriceRegistryInterface_Expecter { - return &PriceRegistryInterface_Expecter{mock: &_m.Mock} -} - -// AcceptOwnership provides a mock function with given fields: opts -func (_m *PriceRegistryInterface) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - ret := _m.Called(opts) - - if len(ret) == 0 { - panic("no return value specified for AcceptOwnership") - } - - var r0 *types.Transaction - var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts) (*types.Transaction, error)); ok { - return rf(opts) - } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts) *types.Transaction); ok { - r0 = rf(opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Transaction) - } - } - - if rf, ok := ret.Get(1).(func(*bind.TransactOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_AcceptOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AcceptOwnership' -type PriceRegistryInterface_AcceptOwnership_Call struct { - *mock.Call -} - -// AcceptOwnership is a helper method to define mock.On call -// - opts *bind.TransactOpts -func (_e *PriceRegistryInterface_Expecter) AcceptOwnership(opts interface{}) *PriceRegistryInterface_AcceptOwnership_Call { - return &PriceRegistryInterface_AcceptOwnership_Call{Call: _e.mock.On("AcceptOwnership", opts)} -} - -func (_c *PriceRegistryInterface_AcceptOwnership_Call) Run(run func(opts *bind.TransactOpts)) *PriceRegistryInterface_AcceptOwnership_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts)) - }) - return _c -} - -func (_c *PriceRegistryInterface_AcceptOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_AcceptOwnership_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_AcceptOwnership_Call) RunAndReturn(run func(*bind.TransactOpts) (*types.Transaction, error)) *PriceRegistryInterface_AcceptOwnership_Call { - _c.Call.Return(run) - return _c -} - -// Address provides a mock function with given fields: -func (_m *PriceRegistryInterface) Address() common.Address { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for Address") - } - - var r0 common.Address - if rf, ok := ret.Get(0).(func() common.Address); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(common.Address) - } - } - - return r0 -} - -// PriceRegistryInterface_Address_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Address' -type PriceRegistryInterface_Address_Call struct { - *mock.Call -} - -// Address is a helper method to define mock.On call -func (_e *PriceRegistryInterface_Expecter) Address() *PriceRegistryInterface_Address_Call { - return &PriceRegistryInterface_Address_Call{Call: _e.mock.On("Address")} -} - -func (_c *PriceRegistryInterface_Address_Call) Run(run func()) *PriceRegistryInterface_Address_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *PriceRegistryInterface_Address_Call) Return(_a0 common.Address) *PriceRegistryInterface_Address_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *PriceRegistryInterface_Address_Call) RunAndReturn(run func() common.Address) *PriceRegistryInterface_Address_Call { - _c.Call.Return(run) - return _c -} - -// ApplyAuthorizedCallerUpdates provides a mock function with given fields: opts, authorizedCallerArgs -func (_m *PriceRegistryInterface) ApplyAuthorizedCallerUpdates(opts *bind.TransactOpts, authorizedCallerArgs price_registry.AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error) { - ret := _m.Called(opts, authorizedCallerArgs) - - if len(ret) == 0 { - panic("no return value specified for ApplyAuthorizedCallerUpdates") - } - - var r0 *types.Transaction - var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, price_registry.AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error)); ok { - return rf(opts, authorizedCallerArgs) - } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, price_registry.AuthorizedCallersAuthorizedCallerArgs) *types.Transaction); ok { - r0 = rf(opts, authorizedCallerArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Transaction) - } - } - - if rf, ok := ret.Get(1).(func(*bind.TransactOpts, price_registry.AuthorizedCallersAuthorizedCallerArgs) error); ok { - r1 = rf(opts, authorizedCallerArgs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyAuthorizedCallerUpdates' -type PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call struct { - *mock.Call -} - -// ApplyAuthorizedCallerUpdates is a helper method to define mock.On call -// - opts *bind.TransactOpts -// - authorizedCallerArgs price_registry.AuthorizedCallersAuthorizedCallerArgs -func (_e *PriceRegistryInterface_Expecter) ApplyAuthorizedCallerUpdates(opts interface{}, authorizedCallerArgs interface{}) *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call { - return &PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call{Call: _e.mock.On("ApplyAuthorizedCallerUpdates", opts, authorizedCallerArgs)} -} - -func (_c *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call) Run(run func(opts *bind.TransactOpts, authorizedCallerArgs price_registry.AuthorizedCallersAuthorizedCallerArgs)) *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts), args[1].(price_registry.AuthorizedCallersAuthorizedCallerArgs)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, price_registry.AuthorizedCallersAuthorizedCallerArgs) (*types.Transaction, error)) *PriceRegistryInterface_ApplyAuthorizedCallerUpdates_Call { - _c.Call.Return(run) - return _c -} - -// ApplyDestChainConfigUpdates provides a mock function with given fields: opts, destChainConfigArgs -func (_m *PriceRegistryInterface) ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []price_registry.PriceRegistryDestChainConfigArgs) (*types.Transaction, error) { - ret := _m.Called(opts, destChainConfigArgs) - - if len(ret) == 0 { - panic("no return value specified for ApplyDestChainConfigUpdates") - } - - var r0 *types.Transaction - var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryDestChainConfigArgs) (*types.Transaction, error)); ok { - return rf(opts, destChainConfigArgs) - } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryDestChainConfigArgs) *types.Transaction); ok { - r0 = rf(opts, destChainConfigArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Transaction) - } - } - - if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []price_registry.PriceRegistryDestChainConfigArgs) error); ok { - r1 = rf(opts, destChainConfigArgs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ApplyDestChainConfigUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyDestChainConfigUpdates' -type PriceRegistryInterface_ApplyDestChainConfigUpdates_Call struct { - *mock.Call -} - -// ApplyDestChainConfigUpdates is a helper method to define mock.On call -// - opts *bind.TransactOpts -// - destChainConfigArgs []price_registry.PriceRegistryDestChainConfigArgs -func (_e *PriceRegistryInterface_Expecter) ApplyDestChainConfigUpdates(opts interface{}, destChainConfigArgs interface{}) *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call { - return &PriceRegistryInterface_ApplyDestChainConfigUpdates_Call{Call: _e.mock.On("ApplyDestChainConfigUpdates", opts, destChainConfigArgs)} -} - -func (_c *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call) Run(run func(opts *bind.TransactOpts, destChainConfigArgs []price_registry.PriceRegistryDestChainConfigArgs)) *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts), args[1].([]price_registry.PriceRegistryDestChainConfigArgs)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []price_registry.PriceRegistryDestChainConfigArgs) (*types.Transaction, error)) *PriceRegistryInterface_ApplyDestChainConfigUpdates_Call { - _c.Call.Return(run) - return _c -} - -// ApplyFeeTokensUpdates provides a mock function with given fields: opts, feeTokensToAdd, feeTokensToRemove -func (_m *PriceRegistryInterface) ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { - ret := _m.Called(opts, feeTokensToAdd, feeTokensToRemove) - - if len(ret) == 0 { - panic("no return value specified for ApplyFeeTokensUpdates") - } - - var r0 *types.Transaction - var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address) (*types.Transaction, error)); ok { - return rf(opts, feeTokensToAdd, feeTokensToRemove) - } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []common.Address, []common.Address) *types.Transaction); ok { - r0 = rf(opts, feeTokensToAdd, feeTokensToRemove) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Transaction) - } - } - - if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []common.Address, []common.Address) error); ok { - r1 = rf(opts, feeTokensToAdd, feeTokensToRemove) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ApplyFeeTokensUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyFeeTokensUpdates' -type PriceRegistryInterface_ApplyFeeTokensUpdates_Call struct { - *mock.Call -} - -// ApplyFeeTokensUpdates is a helper method to define mock.On call -// - opts *bind.TransactOpts -// - feeTokensToAdd []common.Address -// - feeTokensToRemove []common.Address -func (_e *PriceRegistryInterface_Expecter) ApplyFeeTokensUpdates(opts interface{}, feeTokensToAdd interface{}, feeTokensToRemove interface{}) *PriceRegistryInterface_ApplyFeeTokensUpdates_Call { - return &PriceRegistryInterface_ApplyFeeTokensUpdates_Call{Call: _e.mock.On("ApplyFeeTokensUpdates", opts, feeTokensToAdd, feeTokensToRemove)} -} - -func (_c *PriceRegistryInterface_ApplyFeeTokensUpdates_Call) Run(run func(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address)) *PriceRegistryInterface_ApplyFeeTokensUpdates_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts), args[1].([]common.Address), args[2].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ApplyFeeTokensUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_ApplyFeeTokensUpdates_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ApplyFeeTokensUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []common.Address, []common.Address) (*types.Transaction, error)) *PriceRegistryInterface_ApplyFeeTokensUpdates_Call { - _c.Call.Return(run) - return _c -} - -// ApplyPremiumMultiplierWeiPerEthUpdates provides a mock function with given fields: opts, premiumMultiplierWeiPerEthArgs -func (_m *PriceRegistryInterface) ApplyPremiumMultiplierWeiPerEthUpdates(opts *bind.TransactOpts, premiumMultiplierWeiPerEthArgs []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error) { - ret := _m.Called(opts, premiumMultiplierWeiPerEthArgs) - - if len(ret) == 0 { - panic("no return value specified for ApplyPremiumMultiplierWeiPerEthUpdates") - } - - var r0 *types.Transaction - var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error)); ok { - return rf(opts, premiumMultiplierWeiPerEthArgs) - } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs) *types.Transaction); ok { - r0 = rf(opts, premiumMultiplierWeiPerEthArgs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Transaction) - } - } - - if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs) error); ok { - r1 = rf(opts, premiumMultiplierWeiPerEthArgs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyPremiumMultiplierWeiPerEthUpdates' -type PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call struct { - *mock.Call -} - -// ApplyPremiumMultiplierWeiPerEthUpdates is a helper method to define mock.On call -// - opts *bind.TransactOpts -// - premiumMultiplierWeiPerEthArgs []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs -func (_e *PriceRegistryInterface_Expecter) ApplyPremiumMultiplierWeiPerEthUpdates(opts interface{}, premiumMultiplierWeiPerEthArgs interface{}) *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call { - return &PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call{Call: _e.mock.On("ApplyPremiumMultiplierWeiPerEthUpdates", opts, premiumMultiplierWeiPerEthArgs)} -} - -func (_c *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call) Run(run func(opts *bind.TransactOpts, premiumMultiplierWeiPerEthArgs []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs)) *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts), args[1].([]price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs) (*types.Transaction, error)) *PriceRegistryInterface_ApplyPremiumMultiplierWeiPerEthUpdates_Call { - _c.Call.Return(run) - return _c -} - -// ApplyTokenTransferFeeConfigUpdates provides a mock function with given fields: opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs -func (_m *PriceRegistryInterface) ApplyTokenTransferFeeConfigUpdates(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []price_registry.PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error) { - ret := _m.Called(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) - - if len(ret) == 0 { - panic("no return value specified for ApplyTokenTransferFeeConfigUpdates") - } - - var r0 *types.Transaction - var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryTokenTransferFeeConfigArgs, []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error)); ok { - return rf(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) - } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryTokenTransferFeeConfigArgs, []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs) *types.Transaction); ok { - r0 = rf(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Transaction) - } - } - - if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []price_registry.PriceRegistryTokenTransferFeeConfigArgs, []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs) error); ok { - r1 = rf(opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyTokenTransferFeeConfigUpdates' -type PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call struct { - *mock.Call -} - -// ApplyTokenTransferFeeConfigUpdates is a helper method to define mock.On call -// - opts *bind.TransactOpts -// - tokenTransferFeeConfigArgs []price_registry.PriceRegistryTokenTransferFeeConfigArgs -// - tokensToUseDefaultFeeConfigs []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs -func (_e *PriceRegistryInterface_Expecter) ApplyTokenTransferFeeConfigUpdates(opts interface{}, tokenTransferFeeConfigArgs interface{}, tokensToUseDefaultFeeConfigs interface{}) *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call { - return &PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call{Call: _e.mock.On("ApplyTokenTransferFeeConfigUpdates", opts, tokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs)} -} - -func (_c *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call) Run(run func(opts *bind.TransactOpts, tokenTransferFeeConfigArgs []price_registry.PriceRegistryTokenTransferFeeConfigArgs, tokensToUseDefaultFeeConfigs []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs)) *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts), args[1].([]price_registry.PriceRegistryTokenTransferFeeConfigArgs), args[2].([]price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call) RunAndReturn(run func(*bind.TransactOpts, []price_registry.PriceRegistryTokenTransferFeeConfigArgs, []price_registry.PriceRegistryTokenTransferFeeConfigRemoveArgs) (*types.Transaction, error)) *PriceRegistryInterface_ApplyTokenTransferFeeConfigUpdates_Call { - _c.Call.Return(run) - return _c -} - -// ConvertTokenAmount provides a mock function with given fields: opts, fromToken, fromTokenAmount, toToken -func (_m *PriceRegistryInterface) ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { - ret := _m.Called(opts, fromToken, fromTokenAmount, toToken) - - if len(ret) == 0 { - panic("no return value specified for ConvertTokenAmount") - } - - var r0 *big.Int - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, *big.Int, common.Address) (*big.Int, error)); ok { - return rf(opts, fromToken, fromTokenAmount, toToken) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, *big.Int, common.Address) *big.Int); ok { - r0 = rf(opts, fromToken, fromTokenAmount, toToken) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*big.Int) - } - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address, *big.Int, common.Address) error); ok { - r1 = rf(opts, fromToken, fromTokenAmount, toToken) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ConvertTokenAmount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ConvertTokenAmount' -type PriceRegistryInterface_ConvertTokenAmount_Call struct { - *mock.Call -} - -// ConvertTokenAmount is a helper method to define mock.On call -// - opts *bind.CallOpts -// - fromToken common.Address -// - fromTokenAmount *big.Int -// - toToken common.Address -func (_e *PriceRegistryInterface_Expecter) ConvertTokenAmount(opts interface{}, fromToken interface{}, fromTokenAmount interface{}, toToken interface{}) *PriceRegistryInterface_ConvertTokenAmount_Call { - return &PriceRegistryInterface_ConvertTokenAmount_Call{Call: _e.mock.On("ConvertTokenAmount", opts, fromToken, fromTokenAmount, toToken)} -} - -func (_c *PriceRegistryInterface_ConvertTokenAmount_Call) Run(run func(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address)) *PriceRegistryInterface_ConvertTokenAmount_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(common.Address), args[2].(*big.Int), args[3].(common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ConvertTokenAmount_Call) Return(_a0 *big.Int, _a1 error) *PriceRegistryInterface_ConvertTokenAmount_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ConvertTokenAmount_Call) RunAndReturn(run func(*bind.CallOpts, common.Address, *big.Int, common.Address) (*big.Int, error)) *PriceRegistryInterface_ConvertTokenAmount_Call { - _c.Call.Return(run) - return _c -} - -// FilterAuthorizedCallerAdded provides a mock function with given fields: opts -func (_m *PriceRegistryInterface) FilterAuthorizedCallerAdded(opts *bind.FilterOpts) (*price_registry.PriceRegistryAuthorizedCallerAddedIterator, error) { - ret := _m.Called(opts) - - if len(ret) == 0 { - panic("no return value specified for FilterAuthorizedCallerAdded") - } - - var r0 *price_registry.PriceRegistryAuthorizedCallerAddedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*price_registry.PriceRegistryAuthorizedCallerAddedIterator, error)); ok { - return rf(opts) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *price_registry.PriceRegistryAuthorizedCallerAddedIterator); ok { - r0 = rf(opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryAuthorizedCallerAddedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterAuthorizedCallerAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterAuthorizedCallerAdded' -type PriceRegistryInterface_FilterAuthorizedCallerAdded_Call struct { - *mock.Call -} - -// FilterAuthorizedCallerAdded is a helper method to define mock.On call -// - opts *bind.FilterOpts -func (_e *PriceRegistryInterface_Expecter) FilterAuthorizedCallerAdded(opts interface{}) *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call { - return &PriceRegistryInterface_FilterAuthorizedCallerAdded_Call{Call: _e.mock.On("FilterAuthorizedCallerAdded", opts)} -} - -func (_c *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call) Run(run func(opts *bind.FilterOpts)) *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call) Return(_a0 *price_registry.PriceRegistryAuthorizedCallerAddedIterator, _a1 error) *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call) RunAndReturn(run func(*bind.FilterOpts) (*price_registry.PriceRegistryAuthorizedCallerAddedIterator, error)) *PriceRegistryInterface_FilterAuthorizedCallerAdded_Call { - _c.Call.Return(run) - return _c -} - -// FilterAuthorizedCallerRemoved provides a mock function with given fields: opts -func (_m *PriceRegistryInterface) FilterAuthorizedCallerRemoved(opts *bind.FilterOpts) (*price_registry.PriceRegistryAuthorizedCallerRemovedIterator, error) { - ret := _m.Called(opts) - - if len(ret) == 0 { - panic("no return value specified for FilterAuthorizedCallerRemoved") - } - - var r0 *price_registry.PriceRegistryAuthorizedCallerRemovedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts) (*price_registry.PriceRegistryAuthorizedCallerRemovedIterator, error)); ok { - return rf(opts) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *price_registry.PriceRegistryAuthorizedCallerRemovedIterator); ok { - r0 = rf(opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryAuthorizedCallerRemovedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterAuthorizedCallerRemoved' -type PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call struct { - *mock.Call -} - -// FilterAuthorizedCallerRemoved is a helper method to define mock.On call -// - opts *bind.FilterOpts -func (_e *PriceRegistryInterface_Expecter) FilterAuthorizedCallerRemoved(opts interface{}) *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call { - return &PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call{Call: _e.mock.On("FilterAuthorizedCallerRemoved", opts)} -} - -func (_c *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call) Run(run func(opts *bind.FilterOpts)) *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call) Return(_a0 *price_registry.PriceRegistryAuthorizedCallerRemovedIterator, _a1 error) *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call) RunAndReturn(run func(*bind.FilterOpts) (*price_registry.PriceRegistryAuthorizedCallerRemovedIterator, error)) *PriceRegistryInterface_FilterAuthorizedCallerRemoved_Call { - _c.Call.Return(run) - return _c -} - -// FilterDestChainAdded provides a mock function with given fields: opts, destChainSelector -func (_m *PriceRegistryInterface) FilterDestChainAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*price_registry.PriceRegistryDestChainAddedIterator, error) { - ret := _m.Called(opts, destChainSelector) - - if len(ret) == 0 { - panic("no return value specified for FilterDestChainAdded") - } - - var r0 *price_registry.PriceRegistryDestChainAddedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*price_registry.PriceRegistryDestChainAddedIterator, error)); ok { - return rf(opts, destChainSelector) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *price_registry.PriceRegistryDestChainAddedIterator); ok { - r0 = rf(opts, destChainSelector) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryDestChainAddedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { - r1 = rf(opts, destChainSelector) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterDestChainAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterDestChainAdded' -type PriceRegistryInterface_FilterDestChainAdded_Call struct { - *mock.Call -} - -// FilterDestChainAdded is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - destChainSelector []uint64 -func (_e *PriceRegistryInterface_Expecter) FilterDestChainAdded(opts interface{}, destChainSelector interface{}) *PriceRegistryInterface_FilterDestChainAdded_Call { - return &PriceRegistryInterface_FilterDestChainAdded_Call{Call: _e.mock.On("FilterDestChainAdded", opts, destChainSelector)} -} - -func (_c *PriceRegistryInterface_FilterDestChainAdded_Call) Run(run func(opts *bind.FilterOpts, destChainSelector []uint64)) *PriceRegistryInterface_FilterDestChainAdded_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]uint64)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterDestChainAdded_Call) Return(_a0 *price_registry.PriceRegistryDestChainAddedIterator, _a1 error) *PriceRegistryInterface_FilterDestChainAdded_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterDestChainAdded_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*price_registry.PriceRegistryDestChainAddedIterator, error)) *PriceRegistryInterface_FilterDestChainAdded_Call { - _c.Call.Return(run) - return _c -} - -// FilterDestChainConfigUpdated provides a mock function with given fields: opts, destChainSelector -func (_m *PriceRegistryInterface) FilterDestChainConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*price_registry.PriceRegistryDestChainConfigUpdatedIterator, error) { - ret := _m.Called(opts, destChainSelector) - - if len(ret) == 0 { - panic("no return value specified for FilterDestChainConfigUpdated") - } - - var r0 *price_registry.PriceRegistryDestChainConfigUpdatedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*price_registry.PriceRegistryDestChainConfigUpdatedIterator, error)); ok { - return rf(opts, destChainSelector) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *price_registry.PriceRegistryDestChainConfigUpdatedIterator); ok { - r0 = rf(opts, destChainSelector) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryDestChainConfigUpdatedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { - r1 = rf(opts, destChainSelector) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterDestChainConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterDestChainConfigUpdated' -type PriceRegistryInterface_FilterDestChainConfigUpdated_Call struct { - *mock.Call -} - -// FilterDestChainConfigUpdated is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - destChainSelector []uint64 -func (_e *PriceRegistryInterface_Expecter) FilterDestChainConfigUpdated(opts interface{}, destChainSelector interface{}) *PriceRegistryInterface_FilterDestChainConfigUpdated_Call { - return &PriceRegistryInterface_FilterDestChainConfigUpdated_Call{Call: _e.mock.On("FilterDestChainConfigUpdated", opts, destChainSelector)} -} - -func (_c *PriceRegistryInterface_FilterDestChainConfigUpdated_Call) Run(run func(opts *bind.FilterOpts, destChainSelector []uint64)) *PriceRegistryInterface_FilterDestChainConfigUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]uint64)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterDestChainConfigUpdated_Call) Return(_a0 *price_registry.PriceRegistryDestChainConfigUpdatedIterator, _a1 error) *PriceRegistryInterface_FilterDestChainConfigUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterDestChainConfigUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*price_registry.PriceRegistryDestChainConfigUpdatedIterator, error)) *PriceRegistryInterface_FilterDestChainConfigUpdated_Call { - _c.Call.Return(run) - return _c -} - -// FilterFeeTokenAdded provides a mock function with given fields: opts, feeToken -func (_m *PriceRegistryInterface) FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*price_registry.PriceRegistryFeeTokenAddedIterator, error) { - ret := _m.Called(opts, feeToken) - - if len(ret) == 0 { - panic("no return value specified for FilterFeeTokenAdded") - } - - var r0 *price_registry.PriceRegistryFeeTokenAddedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryFeeTokenAddedIterator, error)); ok { - return rf(opts, feeToken) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryFeeTokenAddedIterator); ok { - r0 = rf(opts, feeToken) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryFeeTokenAddedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { - r1 = rf(opts, feeToken) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterFeeTokenAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterFeeTokenAdded' -type PriceRegistryInterface_FilterFeeTokenAdded_Call struct { - *mock.Call -} - -// FilterFeeTokenAdded is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - feeToken []common.Address -func (_e *PriceRegistryInterface_Expecter) FilterFeeTokenAdded(opts interface{}, feeToken interface{}) *PriceRegistryInterface_FilterFeeTokenAdded_Call { - return &PriceRegistryInterface_FilterFeeTokenAdded_Call{Call: _e.mock.On("FilterFeeTokenAdded", opts, feeToken)} -} - -func (_c *PriceRegistryInterface_FilterFeeTokenAdded_Call) Run(run func(opts *bind.FilterOpts, feeToken []common.Address)) *PriceRegistryInterface_FilterFeeTokenAdded_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterFeeTokenAdded_Call) Return(_a0 *price_registry.PriceRegistryFeeTokenAddedIterator, _a1 error) *PriceRegistryInterface_FilterFeeTokenAdded_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterFeeTokenAdded_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryFeeTokenAddedIterator, error)) *PriceRegistryInterface_FilterFeeTokenAdded_Call { - _c.Call.Return(run) - return _c -} - -// FilterFeeTokenRemoved provides a mock function with given fields: opts, feeToken -func (_m *PriceRegistryInterface) FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*price_registry.PriceRegistryFeeTokenRemovedIterator, error) { - ret := _m.Called(opts, feeToken) - - if len(ret) == 0 { - panic("no return value specified for FilterFeeTokenRemoved") - } - - var r0 *price_registry.PriceRegistryFeeTokenRemovedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryFeeTokenRemovedIterator, error)); ok { - return rf(opts, feeToken) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryFeeTokenRemovedIterator); ok { - r0 = rf(opts, feeToken) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryFeeTokenRemovedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { - r1 = rf(opts, feeToken) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterFeeTokenRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterFeeTokenRemoved' -type PriceRegistryInterface_FilterFeeTokenRemoved_Call struct { - *mock.Call -} - -// FilterFeeTokenRemoved is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - feeToken []common.Address -func (_e *PriceRegistryInterface_Expecter) FilterFeeTokenRemoved(opts interface{}, feeToken interface{}) *PriceRegistryInterface_FilterFeeTokenRemoved_Call { - return &PriceRegistryInterface_FilterFeeTokenRemoved_Call{Call: _e.mock.On("FilterFeeTokenRemoved", opts, feeToken)} -} - -func (_c *PriceRegistryInterface_FilterFeeTokenRemoved_Call) Run(run func(opts *bind.FilterOpts, feeToken []common.Address)) *PriceRegistryInterface_FilterFeeTokenRemoved_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterFeeTokenRemoved_Call) Return(_a0 *price_registry.PriceRegistryFeeTokenRemovedIterator, _a1 error) *PriceRegistryInterface_FilterFeeTokenRemoved_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterFeeTokenRemoved_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryFeeTokenRemovedIterator, error)) *PriceRegistryInterface_FilterFeeTokenRemoved_Call { - _c.Call.Return(run) - return _c -} - -// FilterOwnershipTransferRequested provides a mock function with given fields: opts, from, to -func (_m *PriceRegistryInterface) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*price_registry.PriceRegistryOwnershipTransferRequestedIterator, error) { - ret := _m.Called(opts, from, to) - - if len(ret) == 0 { - panic("no return value specified for FilterOwnershipTransferRequested") - } - - var r0 *price_registry.PriceRegistryOwnershipTransferRequestedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*price_registry.PriceRegistryOwnershipTransferRequestedIterator, error)); ok { - return rf(opts, from, to) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *price_registry.PriceRegistryOwnershipTransferRequestedIterator); ok { - r0 = rf(opts, from, to) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryOwnershipTransferRequestedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { - r1 = rf(opts, from, to) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferRequested' -type PriceRegistryInterface_FilterOwnershipTransferRequested_Call struct { - *mock.Call -} - -// FilterOwnershipTransferRequested is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - from []common.Address -// - to []common.Address -func (_e *PriceRegistryInterface_Expecter) FilterOwnershipTransferRequested(opts interface{}, from interface{}, to interface{}) *PriceRegistryInterface_FilterOwnershipTransferRequested_Call { - return &PriceRegistryInterface_FilterOwnershipTransferRequested_Call{Call: _e.mock.On("FilterOwnershipTransferRequested", opts, from, to)} -} - -func (_c *PriceRegistryInterface_FilterOwnershipTransferRequested_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *PriceRegistryInterface_FilterOwnershipTransferRequested_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterOwnershipTransferRequested_Call) Return(_a0 *price_registry.PriceRegistryOwnershipTransferRequestedIterator, _a1 error) *PriceRegistryInterface_FilterOwnershipTransferRequested_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*price_registry.PriceRegistryOwnershipTransferRequestedIterator, error)) *PriceRegistryInterface_FilterOwnershipTransferRequested_Call { - _c.Call.Return(run) - return _c -} - -// FilterOwnershipTransferred provides a mock function with given fields: opts, from, to -func (_m *PriceRegistryInterface) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*price_registry.PriceRegistryOwnershipTransferredIterator, error) { - ret := _m.Called(opts, from, to) - - if len(ret) == 0 { - panic("no return value specified for FilterOwnershipTransferred") - } - - var r0 *price_registry.PriceRegistryOwnershipTransferredIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) (*price_registry.PriceRegistryOwnershipTransferredIterator, error)); ok { - return rf(opts, from, to) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *price_registry.PriceRegistryOwnershipTransferredIterator); ok { - r0 = rf(opts, from, to) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryOwnershipTransferredIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { - r1 = rf(opts, from, to) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterOwnershipTransferred' -type PriceRegistryInterface_FilterOwnershipTransferred_Call struct { - *mock.Call -} - -// FilterOwnershipTransferred is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - from []common.Address -// - to []common.Address -func (_e *PriceRegistryInterface_Expecter) FilterOwnershipTransferred(opts interface{}, from interface{}, to interface{}) *PriceRegistryInterface_FilterOwnershipTransferred_Call { - return &PriceRegistryInterface_FilterOwnershipTransferred_Call{Call: _e.mock.On("FilterOwnershipTransferred", opts, from, to)} -} - -func (_c *PriceRegistryInterface_FilterOwnershipTransferred_Call) Run(run func(opts *bind.FilterOpts, from []common.Address, to []common.Address)) *PriceRegistryInterface_FilterOwnershipTransferred_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]common.Address), args[2].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterOwnershipTransferred_Call) Return(_a0 *price_registry.PriceRegistryOwnershipTransferredIterator, _a1 error) *PriceRegistryInterface_FilterOwnershipTransferred_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterOwnershipTransferred_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address, []common.Address) (*price_registry.PriceRegistryOwnershipTransferredIterator, error)) *PriceRegistryInterface_FilterOwnershipTransferred_Call { - _c.Call.Return(run) - return _c -} - -// FilterPremiumMultiplierWeiPerEthUpdated provides a mock function with given fields: opts, token -func (_m *PriceRegistryInterface) FilterPremiumMultiplierWeiPerEthUpdated(opts *bind.FilterOpts, token []common.Address) (*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator, error) { - ret := _m.Called(opts, token) - - if len(ret) == 0 { - panic("no return value specified for FilterPremiumMultiplierWeiPerEthUpdated") - } - - var r0 *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator, error)); ok { - return rf(opts, token) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator); ok { - r0 = rf(opts, token) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { - r1 = rf(opts, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPremiumMultiplierWeiPerEthUpdated' -type PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call struct { - *mock.Call -} - -// FilterPremiumMultiplierWeiPerEthUpdated is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - token []common.Address -func (_e *PriceRegistryInterface_Expecter) FilterPremiumMultiplierWeiPerEthUpdated(opts interface{}, token interface{}) *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call { - return &PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call{Call: _e.mock.On("FilterPremiumMultiplierWeiPerEthUpdated", opts, token)} -} - -func (_c *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call) Run(run func(opts *bind.FilterOpts, token []common.Address)) *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call) Return(_a0 *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator, _a1 error) *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdatedIterator, error)) *PriceRegistryInterface_FilterPremiumMultiplierWeiPerEthUpdated_Call { - _c.Call.Return(run) - return _c -} - -// FilterPriceFeedPerTokenUpdated provides a mock function with given fields: opts, token -func (_m *PriceRegistryInterface) FilterPriceFeedPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator, error) { - ret := _m.Called(opts, token) - - if len(ret) == 0 { - panic("no return value specified for FilterPriceFeedPerTokenUpdated") - } - - var r0 *price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator, error)); ok { - return rf(opts, token) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator); ok { - r0 = rf(opts, token) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { - r1 = rf(opts, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterPriceFeedPerTokenUpdated' -type PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call struct { - *mock.Call -} - -// FilterPriceFeedPerTokenUpdated is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - token []common.Address -func (_e *PriceRegistryInterface_Expecter) FilterPriceFeedPerTokenUpdated(opts interface{}, token interface{}) *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call { - return &PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call{Call: _e.mock.On("FilterPriceFeedPerTokenUpdated", opts, token)} -} - -func (_c *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call) Run(run func(opts *bind.FilterOpts, token []common.Address)) *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call) Return(_a0 *price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator, _a1 error) *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryPriceFeedPerTokenUpdatedIterator, error)) *PriceRegistryInterface_FilterPriceFeedPerTokenUpdated_Call { - _c.Call.Return(run) - return _c -} - -// FilterReportPermissionSet provides a mock function with given fields: opts, reportId -func (_m *PriceRegistryInterface) FilterReportPermissionSet(opts *bind.FilterOpts, reportId [][32]byte) (*price_registry.PriceRegistryReportPermissionSetIterator, error) { - ret := _m.Called(opts, reportId) - - if len(ret) == 0 { - panic("no return value specified for FilterReportPermissionSet") - } - - var r0 *price_registry.PriceRegistryReportPermissionSetIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, [][32]byte) (*price_registry.PriceRegistryReportPermissionSetIterator, error)); ok { - return rf(opts, reportId) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, [][32]byte) *price_registry.PriceRegistryReportPermissionSetIterator); ok { - r0 = rf(opts, reportId) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryReportPermissionSetIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, [][32]byte) error); ok { - r1 = rf(opts, reportId) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterReportPermissionSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterReportPermissionSet' -type PriceRegistryInterface_FilterReportPermissionSet_Call struct { - *mock.Call -} - -// FilterReportPermissionSet is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - reportId [][32]byte -func (_e *PriceRegistryInterface_Expecter) FilterReportPermissionSet(opts interface{}, reportId interface{}) *PriceRegistryInterface_FilterReportPermissionSet_Call { - return &PriceRegistryInterface_FilterReportPermissionSet_Call{Call: _e.mock.On("FilterReportPermissionSet", opts, reportId)} -} - -func (_c *PriceRegistryInterface_FilterReportPermissionSet_Call) Run(run func(opts *bind.FilterOpts, reportId [][32]byte)) *PriceRegistryInterface_FilterReportPermissionSet_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([][32]byte)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterReportPermissionSet_Call) Return(_a0 *price_registry.PriceRegistryReportPermissionSetIterator, _a1 error) *PriceRegistryInterface_FilterReportPermissionSet_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterReportPermissionSet_Call) RunAndReturn(run func(*bind.FilterOpts, [][32]byte) (*price_registry.PriceRegistryReportPermissionSetIterator, error)) *PriceRegistryInterface_FilterReportPermissionSet_Call { - _c.Call.Return(run) - return _c -} - -// FilterTokenTransferFeeConfigDeleted provides a mock function with given fields: opts, destChainSelector, token -func (_m *PriceRegistryInterface) FilterTokenTransferFeeConfigDeleted(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator, error) { - ret := _m.Called(opts, destChainSelector, token) - - if len(ret) == 0 { - panic("no return value specified for FilterTokenTransferFeeConfigDeleted") - } - - var r0 *price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator, error)); ok { - return rf(opts, destChainSelector, token) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) *price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator); ok { - r0 = rf(opts, destChainSelector, token) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, []common.Address) error); ok { - r1 = rf(opts, destChainSelector, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTokenTransferFeeConfigDeleted' -type PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call struct { - *mock.Call -} - -// FilterTokenTransferFeeConfigDeleted is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - destChainSelector []uint64 -// - token []common.Address -func (_e *PriceRegistryInterface_Expecter) FilterTokenTransferFeeConfigDeleted(opts interface{}, destChainSelector interface{}, token interface{}) *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call { - return &PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call{Call: _e.mock.On("FilterTokenTransferFeeConfigDeleted", opts, destChainSelector, token)} -} - -func (_c *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call) Run(run func(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address)) *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call) Return(_a0 *price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator, _a1 error) *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigDeletedIterator, error)) *PriceRegistryInterface_FilterTokenTransferFeeConfigDeleted_Call { - _c.Call.Return(run) - return _c -} - -// FilterTokenTransferFeeConfigUpdated provides a mock function with given fields: opts, destChainSelector, token -func (_m *PriceRegistryInterface) FilterTokenTransferFeeConfigUpdated(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator, error) { - ret := _m.Called(opts, destChainSelector, token) - - if len(ret) == 0 { - panic("no return value specified for FilterTokenTransferFeeConfigUpdated") - } - - var r0 *price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator, error)); ok { - return rf(opts, destChainSelector, token) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64, []common.Address) *price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator); ok { - r0 = rf(opts, destChainSelector, token) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64, []common.Address) error); ok { - r1 = rf(opts, destChainSelector, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterTokenTransferFeeConfigUpdated' -type PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call struct { - *mock.Call -} - -// FilterTokenTransferFeeConfigUpdated is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - destChainSelector []uint64 -// - token []common.Address -func (_e *PriceRegistryInterface_Expecter) FilterTokenTransferFeeConfigUpdated(opts interface{}, destChainSelector interface{}, token interface{}) *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call { - return &PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call{Call: _e.mock.On("FilterTokenTransferFeeConfigUpdated", opts, destChainSelector, token)} -} - -func (_c *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call) Run(run func(opts *bind.FilterOpts, destChainSelector []uint64, token []common.Address)) *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]uint64), args[2].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call) Return(_a0 *price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator, _a1 error) *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64, []common.Address) (*price_registry.PriceRegistryTokenTransferFeeConfigUpdatedIterator, error)) *PriceRegistryInterface_FilterTokenTransferFeeConfigUpdated_Call { - _c.Call.Return(run) - return _c -} - -// FilterUsdPerTokenUpdated provides a mock function with given fields: opts, token -func (_m *PriceRegistryInterface) FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*price_registry.PriceRegistryUsdPerTokenUpdatedIterator, error) { - ret := _m.Called(opts, token) - - if len(ret) == 0 { - panic("no return value specified for FilterUsdPerTokenUpdated") - } - - var r0 *price_registry.PriceRegistryUsdPerTokenUpdatedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryUsdPerTokenUpdatedIterator, error)); ok { - return rf(opts, token) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address) *price_registry.PriceRegistryUsdPerTokenUpdatedIterator); ok { - r0 = rf(opts, token) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryUsdPerTokenUpdatedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address) error); ok { - r1 = rf(opts, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterUsdPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterUsdPerTokenUpdated' -type PriceRegistryInterface_FilterUsdPerTokenUpdated_Call struct { - *mock.Call -} - -// FilterUsdPerTokenUpdated is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - token []common.Address -func (_e *PriceRegistryInterface_Expecter) FilterUsdPerTokenUpdated(opts interface{}, token interface{}) *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call { - return &PriceRegistryInterface_FilterUsdPerTokenUpdated_Call{Call: _e.mock.On("FilterUsdPerTokenUpdated", opts, token)} -} - -func (_c *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call) Run(run func(opts *bind.FilterOpts, token []common.Address)) *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call) Return(_a0 *price_registry.PriceRegistryUsdPerTokenUpdatedIterator, _a1 error) *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []common.Address) (*price_registry.PriceRegistryUsdPerTokenUpdatedIterator, error)) *PriceRegistryInterface_FilterUsdPerTokenUpdated_Call { - _c.Call.Return(run) - return _c -} - -// FilterUsdPerUnitGasUpdated provides a mock function with given fields: opts, destChain -func (_m *PriceRegistryInterface) FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator, error) { - ret := _m.Called(opts, destChain) - - if len(ret) == 0 { - panic("no return value specified for FilterUsdPerUnitGasUpdated") - } - - var r0 *price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator - var r1 error - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) (*price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator, error)); ok { - return rf(opts, destChain) - } - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint64) *price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator); ok { - r0 = rf(opts, destChain) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator) - } - } - - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint64) error); ok { - r1 = rf(opts, destChain) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FilterUsdPerUnitGasUpdated' -type PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call struct { - *mock.Call -} - -// FilterUsdPerUnitGasUpdated is a helper method to define mock.On call -// - opts *bind.FilterOpts -// - destChain []uint64 -func (_e *PriceRegistryInterface_Expecter) FilterUsdPerUnitGasUpdated(opts interface{}, destChain interface{}) *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call { - return &PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call{Call: _e.mock.On("FilterUsdPerUnitGasUpdated", opts, destChain)} -} - -func (_c *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call) Run(run func(opts *bind.FilterOpts, destChain []uint64)) *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.FilterOpts), args[1].([]uint64)) - }) - return _c -} - -func (_c *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call) Return(_a0 *price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator, _a1 error) *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call) RunAndReturn(run func(*bind.FilterOpts, []uint64) (*price_registry.PriceRegistryUsdPerUnitGasUpdatedIterator, error)) *PriceRegistryInterface_FilterUsdPerUnitGasUpdated_Call { - _c.Call.Return(run) - return _c -} - -// GetAllAuthorizedCallers provides a mock function with given fields: opts -func (_m *PriceRegistryInterface) GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) { - ret := _m.Called(opts) - - if len(ret) == 0 { - panic("no return value specified for GetAllAuthorizedCallers") - } - - var r0 []common.Address - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { - return rf(opts) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { - r0 = rf(opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]common.Address) - } - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetAllAuthorizedCallers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAllAuthorizedCallers' -type PriceRegistryInterface_GetAllAuthorizedCallers_Call struct { - *mock.Call -} - -// GetAllAuthorizedCallers is a helper method to define mock.On call -// - opts *bind.CallOpts -func (_e *PriceRegistryInterface_Expecter) GetAllAuthorizedCallers(opts interface{}) *PriceRegistryInterface_GetAllAuthorizedCallers_Call { - return &PriceRegistryInterface_GetAllAuthorizedCallers_Call{Call: _e.mock.On("GetAllAuthorizedCallers", opts)} -} - -func (_c *PriceRegistryInterface_GetAllAuthorizedCallers_Call) Run(run func(opts *bind.CallOpts)) *PriceRegistryInterface_GetAllAuthorizedCallers_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetAllAuthorizedCallers_Call) Return(_a0 []common.Address, _a1 error) *PriceRegistryInterface_GetAllAuthorizedCallers_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetAllAuthorizedCallers_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *PriceRegistryInterface_GetAllAuthorizedCallers_Call { - _c.Call.Return(run) - return _c -} - -// GetDestChainConfig provides a mock function with given fields: opts, destChainSelector -func (_m *PriceRegistryInterface) GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (price_registry.PriceRegistryDestChainConfig, error) { - ret := _m.Called(opts, destChainSelector) - - if len(ret) == 0 { - panic("no return value specified for GetDestChainConfig") - } - - var r0 price_registry.PriceRegistryDestChainConfig - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (price_registry.PriceRegistryDestChainConfig, error)); ok { - return rf(opts, destChainSelector) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) price_registry.PriceRegistryDestChainConfig); ok { - r0 = rf(opts, destChainSelector) - } else { - r0 = ret.Get(0).(price_registry.PriceRegistryDestChainConfig) - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { - r1 = rf(opts, destChainSelector) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetDestChainConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDestChainConfig' -type PriceRegistryInterface_GetDestChainConfig_Call struct { - *mock.Call -} - -// GetDestChainConfig is a helper method to define mock.On call -// - opts *bind.CallOpts -// - destChainSelector uint64 -func (_e *PriceRegistryInterface_Expecter) GetDestChainConfig(opts interface{}, destChainSelector interface{}) *PriceRegistryInterface_GetDestChainConfig_Call { - return &PriceRegistryInterface_GetDestChainConfig_Call{Call: _e.mock.On("GetDestChainConfig", opts, destChainSelector)} -} - -func (_c *PriceRegistryInterface_GetDestChainConfig_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64)) *PriceRegistryInterface_GetDestChainConfig_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(uint64)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetDestChainConfig_Call) Return(_a0 price_registry.PriceRegistryDestChainConfig, _a1 error) *PriceRegistryInterface_GetDestChainConfig_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetDestChainConfig_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (price_registry.PriceRegistryDestChainConfig, error)) *PriceRegistryInterface_GetDestChainConfig_Call { - _c.Call.Return(run) - return _c -} - -// GetDestinationChainGasPrice provides a mock function with given fields: opts, destChainSelector -func (_m *PriceRegistryInterface) GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (price_registry.InternalTimestampedPackedUint224, error) { - ret := _m.Called(opts, destChainSelector) - - if len(ret) == 0 { - panic("no return value specified for GetDestinationChainGasPrice") - } - - var r0 price_registry.InternalTimestampedPackedUint224 - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) (price_registry.InternalTimestampedPackedUint224, error)); ok { - return rf(opts, destChainSelector) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64) price_registry.InternalTimestampedPackedUint224); ok { - r0 = rf(opts, destChainSelector) - } else { - r0 = ret.Get(0).(price_registry.InternalTimestampedPackedUint224) - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64) error); ok { - r1 = rf(opts, destChainSelector) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetDestinationChainGasPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDestinationChainGasPrice' -type PriceRegistryInterface_GetDestinationChainGasPrice_Call struct { - *mock.Call -} - -// GetDestinationChainGasPrice is a helper method to define mock.On call -// - opts *bind.CallOpts -// - destChainSelector uint64 -func (_e *PriceRegistryInterface_Expecter) GetDestinationChainGasPrice(opts interface{}, destChainSelector interface{}) *PriceRegistryInterface_GetDestinationChainGasPrice_Call { - return &PriceRegistryInterface_GetDestinationChainGasPrice_Call{Call: _e.mock.On("GetDestinationChainGasPrice", opts, destChainSelector)} -} - -func (_c *PriceRegistryInterface_GetDestinationChainGasPrice_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64)) *PriceRegistryInterface_GetDestinationChainGasPrice_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(uint64)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetDestinationChainGasPrice_Call) Return(_a0 price_registry.InternalTimestampedPackedUint224, _a1 error) *PriceRegistryInterface_GetDestinationChainGasPrice_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetDestinationChainGasPrice_Call) RunAndReturn(run func(*bind.CallOpts, uint64) (price_registry.InternalTimestampedPackedUint224, error)) *PriceRegistryInterface_GetDestinationChainGasPrice_Call { - _c.Call.Return(run) - return _c -} - -// GetFeeTokens provides a mock function with given fields: opts -func (_m *PriceRegistryInterface) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { - ret := _m.Called(opts) - - if len(ret) == 0 { - panic("no return value specified for GetFeeTokens") - } - - var r0 []common.Address - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts) ([]common.Address, error)); ok { - return rf(opts) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { - r0 = rf(opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]common.Address) - } - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetFeeTokens_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFeeTokens' -type PriceRegistryInterface_GetFeeTokens_Call struct { - *mock.Call -} - -// GetFeeTokens is a helper method to define mock.On call -// - opts *bind.CallOpts -func (_e *PriceRegistryInterface_Expecter) GetFeeTokens(opts interface{}) *PriceRegistryInterface_GetFeeTokens_Call { - return &PriceRegistryInterface_GetFeeTokens_Call{Call: _e.mock.On("GetFeeTokens", opts)} -} - -func (_c *PriceRegistryInterface_GetFeeTokens_Call) Run(run func(opts *bind.CallOpts)) *PriceRegistryInterface_GetFeeTokens_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetFeeTokens_Call) Return(_a0 []common.Address, _a1 error) *PriceRegistryInterface_GetFeeTokens_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetFeeTokens_Call) RunAndReturn(run func(*bind.CallOpts) ([]common.Address, error)) *PriceRegistryInterface_GetFeeTokens_Call { - _c.Call.Return(run) - return _c -} - -// GetPremiumMultiplierWeiPerEth provides a mock function with given fields: opts, token -func (_m *PriceRegistryInterface) GetPremiumMultiplierWeiPerEth(opts *bind.CallOpts, token common.Address) (uint64, error) { - ret := _m.Called(opts, token) - - if len(ret) == 0 { - panic("no return value specified for GetPremiumMultiplierWeiPerEth") - } - - var r0 uint64 - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (uint64, error)); ok { - return rf(opts, token) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) uint64); ok { - r0 = rf(opts, token) - } else { - r0 = ret.Get(0).(uint64) - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { - r1 = rf(opts, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPremiumMultiplierWeiPerEth' -type PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call struct { - *mock.Call -} - -// GetPremiumMultiplierWeiPerEth is a helper method to define mock.On call -// - opts *bind.CallOpts -// - token common.Address -func (_e *PriceRegistryInterface_Expecter) GetPremiumMultiplierWeiPerEth(opts interface{}, token interface{}) *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call { - return &PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call{Call: _e.mock.On("GetPremiumMultiplierWeiPerEth", opts, token)} -} - -func (_c *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call) Return(_a0 uint64, _a1 error) *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (uint64, error)) *PriceRegistryInterface_GetPremiumMultiplierWeiPerEth_Call { - _c.Call.Return(run) - return _c -} - -// GetStaticConfig provides a mock function with given fields: opts -func (_m *PriceRegistryInterface) GetStaticConfig(opts *bind.CallOpts) (price_registry.PriceRegistryStaticConfig, error) { - ret := _m.Called(opts) - - if len(ret) == 0 { - panic("no return value specified for GetStaticConfig") - } - - var r0 price_registry.PriceRegistryStaticConfig - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts) (price_registry.PriceRegistryStaticConfig, error)); ok { - return rf(opts) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts) price_registry.PriceRegistryStaticConfig); ok { - r0 = rf(opts) - } else { - r0 = ret.Get(0).(price_registry.PriceRegistryStaticConfig) - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetStaticConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStaticConfig' -type PriceRegistryInterface_GetStaticConfig_Call struct { - *mock.Call -} - -// GetStaticConfig is a helper method to define mock.On call -// - opts *bind.CallOpts -func (_e *PriceRegistryInterface_Expecter) GetStaticConfig(opts interface{}) *PriceRegistryInterface_GetStaticConfig_Call { - return &PriceRegistryInterface_GetStaticConfig_Call{Call: _e.mock.On("GetStaticConfig", opts)} -} - -func (_c *PriceRegistryInterface_GetStaticConfig_Call) Run(run func(opts *bind.CallOpts)) *PriceRegistryInterface_GetStaticConfig_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetStaticConfig_Call) Return(_a0 price_registry.PriceRegistryStaticConfig, _a1 error) *PriceRegistryInterface_GetStaticConfig_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetStaticConfig_Call) RunAndReturn(run func(*bind.CallOpts) (price_registry.PriceRegistryStaticConfig, error)) *PriceRegistryInterface_GetStaticConfig_Call { - _c.Call.Return(run) - return _c -} - -// GetTokenAndGasPrices provides a mock function with given fields: opts, token, destChainSelector -func (_m *PriceRegistryInterface) GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (price_registry.GetTokenAndGasPrices, error) { - ret := _m.Called(opts, token, destChainSelector) - - if len(ret) == 0 { - panic("no return value specified for GetTokenAndGasPrices") - } - - var r0 price_registry.GetTokenAndGasPrices - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, uint64) (price_registry.GetTokenAndGasPrices, error)); ok { - return rf(opts, token, destChainSelector) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address, uint64) price_registry.GetTokenAndGasPrices); ok { - r0 = rf(opts, token, destChainSelector) - } else { - r0 = ret.Get(0).(price_registry.GetTokenAndGasPrices) - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address, uint64) error); ok { - r1 = rf(opts, token, destChainSelector) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetTokenAndGasPrices_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenAndGasPrices' -type PriceRegistryInterface_GetTokenAndGasPrices_Call struct { - *mock.Call -} - -// GetTokenAndGasPrices is a helper method to define mock.On call -// - opts *bind.CallOpts -// - token common.Address -// - destChainSelector uint64 -func (_e *PriceRegistryInterface_Expecter) GetTokenAndGasPrices(opts interface{}, token interface{}, destChainSelector interface{}) *PriceRegistryInterface_GetTokenAndGasPrices_Call { - return &PriceRegistryInterface_GetTokenAndGasPrices_Call{Call: _e.mock.On("GetTokenAndGasPrices", opts, token, destChainSelector)} -} - -func (_c *PriceRegistryInterface_GetTokenAndGasPrices_Call) Run(run func(opts *bind.CallOpts, token common.Address, destChainSelector uint64)) *PriceRegistryInterface_GetTokenAndGasPrices_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(common.Address), args[2].(uint64)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetTokenAndGasPrices_Call) Return(_a0 price_registry.GetTokenAndGasPrices, _a1 error) *PriceRegistryInterface_GetTokenAndGasPrices_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetTokenAndGasPrices_Call) RunAndReturn(run func(*bind.CallOpts, common.Address, uint64) (price_registry.GetTokenAndGasPrices, error)) *PriceRegistryInterface_GetTokenAndGasPrices_Call { - _c.Call.Return(run) - return _c -} - -// GetTokenPrice provides a mock function with given fields: opts, token -func (_m *PriceRegistryInterface) GetTokenPrice(opts *bind.CallOpts, token common.Address) (price_registry.InternalTimestampedPackedUint224, error) { - ret := _m.Called(opts, token) - - if len(ret) == 0 { - panic("no return value specified for GetTokenPrice") - } - - var r0 price_registry.InternalTimestampedPackedUint224 - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (price_registry.InternalTimestampedPackedUint224, error)); ok { - return rf(opts, token) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) price_registry.InternalTimestampedPackedUint224); ok { - r0 = rf(opts, token) - } else { - r0 = ret.Get(0).(price_registry.InternalTimestampedPackedUint224) - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { - r1 = rf(opts, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetTokenPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenPrice' -type PriceRegistryInterface_GetTokenPrice_Call struct { - *mock.Call -} - -// GetTokenPrice is a helper method to define mock.On call -// - opts *bind.CallOpts -// - token common.Address -func (_e *PriceRegistryInterface_Expecter) GetTokenPrice(opts interface{}, token interface{}) *PriceRegistryInterface_GetTokenPrice_Call { - return &PriceRegistryInterface_GetTokenPrice_Call{Call: _e.mock.On("GetTokenPrice", opts, token)} -} - -func (_c *PriceRegistryInterface_GetTokenPrice_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *PriceRegistryInterface_GetTokenPrice_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetTokenPrice_Call) Return(_a0 price_registry.InternalTimestampedPackedUint224, _a1 error) *PriceRegistryInterface_GetTokenPrice_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetTokenPrice_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (price_registry.InternalTimestampedPackedUint224, error)) *PriceRegistryInterface_GetTokenPrice_Call { - _c.Call.Return(run) - return _c -} - -// GetTokenPriceFeedConfig provides a mock function with given fields: opts, token -func (_m *PriceRegistryInterface) GetTokenPriceFeedConfig(opts *bind.CallOpts, token common.Address) (price_registry.IPriceRegistryTokenPriceFeedConfig, error) { - ret := _m.Called(opts, token) - - if len(ret) == 0 { - panic("no return value specified for GetTokenPriceFeedConfig") - } - - var r0 price_registry.IPriceRegistryTokenPriceFeedConfig - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (price_registry.IPriceRegistryTokenPriceFeedConfig, error)); ok { - return rf(opts, token) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) price_registry.IPriceRegistryTokenPriceFeedConfig); ok { - r0 = rf(opts, token) - } else { - r0 = ret.Get(0).(price_registry.IPriceRegistryTokenPriceFeedConfig) - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { - r1 = rf(opts, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetTokenPriceFeedConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenPriceFeedConfig' -type PriceRegistryInterface_GetTokenPriceFeedConfig_Call struct { - *mock.Call -} - -// GetTokenPriceFeedConfig is a helper method to define mock.On call -// - opts *bind.CallOpts -// - token common.Address -func (_e *PriceRegistryInterface_Expecter) GetTokenPriceFeedConfig(opts interface{}, token interface{}) *PriceRegistryInterface_GetTokenPriceFeedConfig_Call { - return &PriceRegistryInterface_GetTokenPriceFeedConfig_Call{Call: _e.mock.On("GetTokenPriceFeedConfig", opts, token)} -} - -func (_c *PriceRegistryInterface_GetTokenPriceFeedConfig_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *PriceRegistryInterface_GetTokenPriceFeedConfig_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetTokenPriceFeedConfig_Call) Return(_a0 price_registry.IPriceRegistryTokenPriceFeedConfig, _a1 error) *PriceRegistryInterface_GetTokenPriceFeedConfig_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetTokenPriceFeedConfig_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (price_registry.IPriceRegistryTokenPriceFeedConfig, error)) *PriceRegistryInterface_GetTokenPriceFeedConfig_Call { - _c.Call.Return(run) - return _c -} - -// GetTokenPrices provides a mock function with given fields: opts, tokens -func (_m *PriceRegistryInterface) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]price_registry.InternalTimestampedPackedUint224, error) { - ret := _m.Called(opts, tokens) - - if len(ret) == 0 { - panic("no return value specified for GetTokenPrices") - } - - var r0 []price_registry.InternalTimestampedPackedUint224 - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, []common.Address) ([]price_registry.InternalTimestampedPackedUint224, error)); ok { - return rf(opts, tokens) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, []common.Address) []price_registry.InternalTimestampedPackedUint224); ok { - r0 = rf(opts, tokens) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]price_registry.InternalTimestampedPackedUint224) - } - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, []common.Address) error); ok { - r1 = rf(opts, tokens) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetTokenPrices_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenPrices' -type PriceRegistryInterface_GetTokenPrices_Call struct { - *mock.Call -} - -// GetTokenPrices is a helper method to define mock.On call -// - opts *bind.CallOpts -// - tokens []common.Address -func (_e *PriceRegistryInterface_Expecter) GetTokenPrices(opts interface{}, tokens interface{}) *PriceRegistryInterface_GetTokenPrices_Call { - return &PriceRegistryInterface_GetTokenPrices_Call{Call: _e.mock.On("GetTokenPrices", opts, tokens)} -} - -func (_c *PriceRegistryInterface_GetTokenPrices_Call) Run(run func(opts *bind.CallOpts, tokens []common.Address)) *PriceRegistryInterface_GetTokenPrices_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetTokenPrices_Call) Return(_a0 []price_registry.InternalTimestampedPackedUint224, _a1 error) *PriceRegistryInterface_GetTokenPrices_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetTokenPrices_Call) RunAndReturn(run func(*bind.CallOpts, []common.Address) ([]price_registry.InternalTimestampedPackedUint224, error)) *PriceRegistryInterface_GetTokenPrices_Call { - _c.Call.Return(run) - return _c -} - -// GetTokenTransferFeeConfig provides a mock function with given fields: opts, destChainSelector, token -func (_m *PriceRegistryInterface) GetTokenTransferFeeConfig(opts *bind.CallOpts, destChainSelector uint64, token common.Address) (price_registry.PriceRegistryTokenTransferFeeConfig, error) { - ret := _m.Called(opts, destChainSelector, token) - - if len(ret) == 0 { - panic("no return value specified for GetTokenTransferFeeConfig") - } - - var r0 price_registry.PriceRegistryTokenTransferFeeConfig - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address) (price_registry.PriceRegistryTokenTransferFeeConfig, error)); ok { - return rf(opts, destChainSelector, token) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address) price_registry.PriceRegistryTokenTransferFeeConfig); ok { - r0 = rf(opts, destChainSelector, token) - } else { - r0 = ret.Get(0).(price_registry.PriceRegistryTokenTransferFeeConfig) - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, common.Address) error); ok { - r1 = rf(opts, destChainSelector, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetTokenTransferFeeConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenTransferFeeConfig' -type PriceRegistryInterface_GetTokenTransferFeeConfig_Call struct { - *mock.Call -} - -// GetTokenTransferFeeConfig is a helper method to define mock.On call -// - opts *bind.CallOpts -// - destChainSelector uint64 -// - token common.Address -func (_e *PriceRegistryInterface_Expecter) GetTokenTransferFeeConfig(opts interface{}, destChainSelector interface{}, token interface{}) *PriceRegistryInterface_GetTokenTransferFeeConfig_Call { - return &PriceRegistryInterface_GetTokenTransferFeeConfig_Call{Call: _e.mock.On("GetTokenTransferFeeConfig", opts, destChainSelector, token)} -} - -func (_c *PriceRegistryInterface_GetTokenTransferFeeConfig_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, token common.Address)) *PriceRegistryInterface_GetTokenTransferFeeConfig_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetTokenTransferFeeConfig_Call) Return(_a0 price_registry.PriceRegistryTokenTransferFeeConfig, _a1 error) *PriceRegistryInterface_GetTokenTransferFeeConfig_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetTokenTransferFeeConfig_Call) RunAndReturn(run func(*bind.CallOpts, uint64, common.Address) (price_registry.PriceRegistryTokenTransferFeeConfig, error)) *PriceRegistryInterface_GetTokenTransferFeeConfig_Call { - _c.Call.Return(run) - return _c -} - -// GetValidatedFee provides a mock function with given fields: opts, destChainSelector, message -func (_m *PriceRegistryInterface) GetValidatedFee(opts *bind.CallOpts, destChainSelector uint64, message price_registry.ClientEVM2AnyMessage) (*big.Int, error) { - ret := _m.Called(opts, destChainSelector, message) - - if len(ret) == 0 { - panic("no return value specified for GetValidatedFee") - } - - var r0 *big.Int - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, price_registry.ClientEVM2AnyMessage) (*big.Int, error)); ok { - return rf(opts, destChainSelector, message) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, price_registry.ClientEVM2AnyMessage) *big.Int); ok { - r0 = rf(opts, destChainSelector, message) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*big.Int) - } - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, price_registry.ClientEVM2AnyMessage) error); ok { - r1 = rf(opts, destChainSelector, message) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetValidatedFee_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetValidatedFee' -type PriceRegistryInterface_GetValidatedFee_Call struct { - *mock.Call -} - -// GetValidatedFee is a helper method to define mock.On call -// - opts *bind.CallOpts -// - destChainSelector uint64 -// - message price_registry.ClientEVM2AnyMessage -func (_e *PriceRegistryInterface_Expecter) GetValidatedFee(opts interface{}, destChainSelector interface{}, message interface{}) *PriceRegistryInterface_GetValidatedFee_Call { - return &PriceRegistryInterface_GetValidatedFee_Call{Call: _e.mock.On("GetValidatedFee", opts, destChainSelector, message)} -} - -func (_c *PriceRegistryInterface_GetValidatedFee_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, message price_registry.ClientEVM2AnyMessage)) *PriceRegistryInterface_GetValidatedFee_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(price_registry.ClientEVM2AnyMessage)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetValidatedFee_Call) Return(_a0 *big.Int, _a1 error) *PriceRegistryInterface_GetValidatedFee_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetValidatedFee_Call) RunAndReturn(run func(*bind.CallOpts, uint64, price_registry.ClientEVM2AnyMessage) (*big.Int, error)) *PriceRegistryInterface_GetValidatedFee_Call { - _c.Call.Return(run) - return _c -} - -// GetValidatedTokenPrice provides a mock function with given fields: opts, token -func (_m *PriceRegistryInterface) GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) { - ret := _m.Called(opts, token) - - if len(ret) == 0 { - panic("no return value specified for GetValidatedTokenPrice") - } - - var r0 *big.Int - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) (*big.Int, error)); ok { - return rf(opts, token) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) *big.Int); ok { - r0 = rf(opts, token) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*big.Int) - } - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { - r1 = rf(opts, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_GetValidatedTokenPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetValidatedTokenPrice' -type PriceRegistryInterface_GetValidatedTokenPrice_Call struct { - *mock.Call -} - -// GetValidatedTokenPrice is a helper method to define mock.On call -// - opts *bind.CallOpts -// - token common.Address -func (_e *PriceRegistryInterface_Expecter) GetValidatedTokenPrice(opts interface{}, token interface{}) *PriceRegistryInterface_GetValidatedTokenPrice_Call { - return &PriceRegistryInterface_GetValidatedTokenPrice_Call{Call: _e.mock.On("GetValidatedTokenPrice", opts, token)} -} - -func (_c *PriceRegistryInterface_GetValidatedTokenPrice_Call) Run(run func(opts *bind.CallOpts, token common.Address)) *PriceRegistryInterface_GetValidatedTokenPrice_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_GetValidatedTokenPrice_Call) Return(_a0 *big.Int, _a1 error) *PriceRegistryInterface_GetValidatedTokenPrice_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_GetValidatedTokenPrice_Call) RunAndReturn(run func(*bind.CallOpts, common.Address) (*big.Int, error)) *PriceRegistryInterface_GetValidatedTokenPrice_Call { - _c.Call.Return(run) - return _c -} - -// OnReport provides a mock function with given fields: opts, metadata, report -func (_m *PriceRegistryInterface) OnReport(opts *bind.TransactOpts, metadata []byte, report []byte) (*types.Transaction, error) { - ret := _m.Called(opts, metadata, report) - - if len(ret) == 0 { - panic("no return value specified for OnReport") - } - - var r0 *types.Transaction - var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []byte, []byte) (*types.Transaction, error)); ok { - return rf(opts, metadata, report) - } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []byte, []byte) *types.Transaction); ok { - r0 = rf(opts, metadata, report) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Transaction) - } - } - - if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []byte, []byte) error); ok { - r1 = rf(opts, metadata, report) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_OnReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OnReport' -type PriceRegistryInterface_OnReport_Call struct { - *mock.Call -} - -// OnReport is a helper method to define mock.On call -// - opts *bind.TransactOpts -// - metadata []byte -// - report []byte -func (_e *PriceRegistryInterface_Expecter) OnReport(opts interface{}, metadata interface{}, report interface{}) *PriceRegistryInterface_OnReport_Call { - return &PriceRegistryInterface_OnReport_Call{Call: _e.mock.On("OnReport", opts, metadata, report)} -} - -func (_c *PriceRegistryInterface_OnReport_Call) Run(run func(opts *bind.TransactOpts, metadata []byte, report []byte)) *PriceRegistryInterface_OnReport_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts), args[1].([]byte), args[2].([]byte)) - }) - return _c -} - -func (_c *PriceRegistryInterface_OnReport_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_OnReport_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_OnReport_Call) RunAndReturn(run func(*bind.TransactOpts, []byte, []byte) (*types.Transaction, error)) *PriceRegistryInterface_OnReport_Call { - _c.Call.Return(run) - return _c -} - -// Owner provides a mock function with given fields: opts -func (_m *PriceRegistryInterface) Owner(opts *bind.CallOpts) (common.Address, error) { - ret := _m.Called(opts) - - if len(ret) == 0 { - panic("no return value specified for Owner") - } - - var r0 common.Address - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts) (common.Address, error)); ok { - return rf(opts) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { - r0 = rf(opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(common.Address) - } - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_Owner_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Owner' -type PriceRegistryInterface_Owner_Call struct { - *mock.Call -} - -// Owner is a helper method to define mock.On call -// - opts *bind.CallOpts -func (_e *PriceRegistryInterface_Expecter) Owner(opts interface{}) *PriceRegistryInterface_Owner_Call { - return &PriceRegistryInterface_Owner_Call{Call: _e.mock.On("Owner", opts)} -} - -func (_c *PriceRegistryInterface_Owner_Call) Run(run func(opts *bind.CallOpts)) *PriceRegistryInterface_Owner_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts)) - }) - return _c -} - -func (_c *PriceRegistryInterface_Owner_Call) Return(_a0 common.Address, _a1 error) *PriceRegistryInterface_Owner_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_Owner_Call) RunAndReturn(run func(*bind.CallOpts) (common.Address, error)) *PriceRegistryInterface_Owner_Call { - _c.Call.Return(run) - return _c -} - -// ParseAuthorizedCallerAdded provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseAuthorizedCallerAdded(log types.Log) (*price_registry.PriceRegistryAuthorizedCallerAdded, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseAuthorizedCallerAdded") - } - - var r0 *price_registry.PriceRegistryAuthorizedCallerAdded - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryAuthorizedCallerAdded, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryAuthorizedCallerAdded); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryAuthorizedCallerAdded) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseAuthorizedCallerAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseAuthorizedCallerAdded' -type PriceRegistryInterface_ParseAuthorizedCallerAdded_Call struct { - *mock.Call -} - -// ParseAuthorizedCallerAdded is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseAuthorizedCallerAdded(log interface{}) *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call { - return &PriceRegistryInterface_ParseAuthorizedCallerAdded_Call{Call: _e.mock.On("ParseAuthorizedCallerAdded", log)} -} - -func (_c *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call) Return(_a0 *price_registry.PriceRegistryAuthorizedCallerAdded, _a1 error) *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryAuthorizedCallerAdded, error)) *PriceRegistryInterface_ParseAuthorizedCallerAdded_Call { - _c.Call.Return(run) - return _c -} - -// ParseAuthorizedCallerRemoved provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseAuthorizedCallerRemoved(log types.Log) (*price_registry.PriceRegistryAuthorizedCallerRemoved, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseAuthorizedCallerRemoved") - } - - var r0 *price_registry.PriceRegistryAuthorizedCallerRemoved - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryAuthorizedCallerRemoved, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryAuthorizedCallerRemoved); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryAuthorizedCallerRemoved) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseAuthorizedCallerRemoved' -type PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call struct { - *mock.Call -} - -// ParseAuthorizedCallerRemoved is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseAuthorizedCallerRemoved(log interface{}) *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call { - return &PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call{Call: _e.mock.On("ParseAuthorizedCallerRemoved", log)} -} - -func (_c *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call) Return(_a0 *price_registry.PriceRegistryAuthorizedCallerRemoved, _a1 error) *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryAuthorizedCallerRemoved, error)) *PriceRegistryInterface_ParseAuthorizedCallerRemoved_Call { - _c.Call.Return(run) - return _c -} - -// ParseDestChainAdded provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseDestChainAdded(log types.Log) (*price_registry.PriceRegistryDestChainAdded, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseDestChainAdded") - } - - var r0 *price_registry.PriceRegistryDestChainAdded - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryDestChainAdded, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryDestChainAdded); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryDestChainAdded) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseDestChainAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseDestChainAdded' -type PriceRegistryInterface_ParseDestChainAdded_Call struct { - *mock.Call -} - -// ParseDestChainAdded is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseDestChainAdded(log interface{}) *PriceRegistryInterface_ParseDestChainAdded_Call { - return &PriceRegistryInterface_ParseDestChainAdded_Call{Call: _e.mock.On("ParseDestChainAdded", log)} -} - -func (_c *PriceRegistryInterface_ParseDestChainAdded_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseDestChainAdded_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseDestChainAdded_Call) Return(_a0 *price_registry.PriceRegistryDestChainAdded, _a1 error) *PriceRegistryInterface_ParseDestChainAdded_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseDestChainAdded_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryDestChainAdded, error)) *PriceRegistryInterface_ParseDestChainAdded_Call { - _c.Call.Return(run) - return _c -} - -// ParseDestChainConfigUpdated provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseDestChainConfigUpdated(log types.Log) (*price_registry.PriceRegistryDestChainConfigUpdated, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseDestChainConfigUpdated") - } - - var r0 *price_registry.PriceRegistryDestChainConfigUpdated - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryDestChainConfigUpdated, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryDestChainConfigUpdated); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryDestChainConfigUpdated) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseDestChainConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseDestChainConfigUpdated' -type PriceRegistryInterface_ParseDestChainConfigUpdated_Call struct { - *mock.Call -} - -// ParseDestChainConfigUpdated is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseDestChainConfigUpdated(log interface{}) *PriceRegistryInterface_ParseDestChainConfigUpdated_Call { - return &PriceRegistryInterface_ParseDestChainConfigUpdated_Call{Call: _e.mock.On("ParseDestChainConfigUpdated", log)} -} - -func (_c *PriceRegistryInterface_ParseDestChainConfigUpdated_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseDestChainConfigUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseDestChainConfigUpdated_Call) Return(_a0 *price_registry.PriceRegistryDestChainConfigUpdated, _a1 error) *PriceRegistryInterface_ParseDestChainConfigUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseDestChainConfigUpdated_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryDestChainConfigUpdated, error)) *PriceRegistryInterface_ParseDestChainConfigUpdated_Call { - _c.Call.Return(run) - return _c -} - -// ParseFeeTokenAdded provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseFeeTokenAdded(log types.Log) (*price_registry.PriceRegistryFeeTokenAdded, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseFeeTokenAdded") - } - - var r0 *price_registry.PriceRegistryFeeTokenAdded - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryFeeTokenAdded, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryFeeTokenAdded); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryFeeTokenAdded) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseFeeTokenAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseFeeTokenAdded' -type PriceRegistryInterface_ParseFeeTokenAdded_Call struct { - *mock.Call -} - -// ParseFeeTokenAdded is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseFeeTokenAdded(log interface{}) *PriceRegistryInterface_ParseFeeTokenAdded_Call { - return &PriceRegistryInterface_ParseFeeTokenAdded_Call{Call: _e.mock.On("ParseFeeTokenAdded", log)} -} - -func (_c *PriceRegistryInterface_ParseFeeTokenAdded_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseFeeTokenAdded_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseFeeTokenAdded_Call) Return(_a0 *price_registry.PriceRegistryFeeTokenAdded, _a1 error) *PriceRegistryInterface_ParseFeeTokenAdded_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseFeeTokenAdded_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryFeeTokenAdded, error)) *PriceRegistryInterface_ParseFeeTokenAdded_Call { - _c.Call.Return(run) - return _c -} - -// ParseFeeTokenRemoved provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseFeeTokenRemoved(log types.Log) (*price_registry.PriceRegistryFeeTokenRemoved, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseFeeTokenRemoved") - } - - var r0 *price_registry.PriceRegistryFeeTokenRemoved - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryFeeTokenRemoved, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryFeeTokenRemoved); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryFeeTokenRemoved) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseFeeTokenRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseFeeTokenRemoved' -type PriceRegistryInterface_ParseFeeTokenRemoved_Call struct { - *mock.Call -} - -// ParseFeeTokenRemoved is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseFeeTokenRemoved(log interface{}) *PriceRegistryInterface_ParseFeeTokenRemoved_Call { - return &PriceRegistryInterface_ParseFeeTokenRemoved_Call{Call: _e.mock.On("ParseFeeTokenRemoved", log)} -} - -func (_c *PriceRegistryInterface_ParseFeeTokenRemoved_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseFeeTokenRemoved_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseFeeTokenRemoved_Call) Return(_a0 *price_registry.PriceRegistryFeeTokenRemoved, _a1 error) *PriceRegistryInterface_ParseFeeTokenRemoved_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseFeeTokenRemoved_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryFeeTokenRemoved, error)) *PriceRegistryInterface_ParseFeeTokenRemoved_Call { - _c.Call.Return(run) - return _c -} - -// ParseLog provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseLog(log types.Log) (generated.AbigenLog, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseLog") - } - - var r0 generated.AbigenLog - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (generated.AbigenLog, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) generated.AbigenLog); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(generated.AbigenLog) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseLog' -type PriceRegistryInterface_ParseLog_Call struct { - *mock.Call -} - -// ParseLog is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseLog(log interface{}) *PriceRegistryInterface_ParseLog_Call { - return &PriceRegistryInterface_ParseLog_Call{Call: _e.mock.On("ParseLog", log)} -} - -func (_c *PriceRegistryInterface_ParseLog_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseLog_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseLog_Call) Return(_a0 generated.AbigenLog, _a1 error) *PriceRegistryInterface_ParseLog_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseLog_Call) RunAndReturn(run func(types.Log) (generated.AbigenLog, error)) *PriceRegistryInterface_ParseLog_Call { - _c.Call.Return(run) - return _c -} - -// ParseOwnershipTransferRequested provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseOwnershipTransferRequested(log types.Log) (*price_registry.PriceRegistryOwnershipTransferRequested, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseOwnershipTransferRequested") - } - - var r0 *price_registry.PriceRegistryOwnershipTransferRequested - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryOwnershipTransferRequested, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryOwnershipTransferRequested); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryOwnershipTransferRequested) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferRequested' -type PriceRegistryInterface_ParseOwnershipTransferRequested_Call struct { - *mock.Call -} - -// ParseOwnershipTransferRequested is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseOwnershipTransferRequested(log interface{}) *PriceRegistryInterface_ParseOwnershipTransferRequested_Call { - return &PriceRegistryInterface_ParseOwnershipTransferRequested_Call{Call: _e.mock.On("ParseOwnershipTransferRequested", log)} -} - -func (_c *PriceRegistryInterface_ParseOwnershipTransferRequested_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseOwnershipTransferRequested_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseOwnershipTransferRequested_Call) Return(_a0 *price_registry.PriceRegistryOwnershipTransferRequested, _a1 error) *PriceRegistryInterface_ParseOwnershipTransferRequested_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseOwnershipTransferRequested_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryOwnershipTransferRequested, error)) *PriceRegistryInterface_ParseOwnershipTransferRequested_Call { - _c.Call.Return(run) - return _c -} - -// ParseOwnershipTransferred provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseOwnershipTransferred(log types.Log) (*price_registry.PriceRegistryOwnershipTransferred, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseOwnershipTransferred") - } - - var r0 *price_registry.PriceRegistryOwnershipTransferred - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryOwnershipTransferred, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryOwnershipTransferred); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryOwnershipTransferred) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseOwnershipTransferred' -type PriceRegistryInterface_ParseOwnershipTransferred_Call struct { - *mock.Call -} - -// ParseOwnershipTransferred is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseOwnershipTransferred(log interface{}) *PriceRegistryInterface_ParseOwnershipTransferred_Call { - return &PriceRegistryInterface_ParseOwnershipTransferred_Call{Call: _e.mock.On("ParseOwnershipTransferred", log)} -} - -func (_c *PriceRegistryInterface_ParseOwnershipTransferred_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseOwnershipTransferred_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseOwnershipTransferred_Call) Return(_a0 *price_registry.PriceRegistryOwnershipTransferred, _a1 error) *PriceRegistryInterface_ParseOwnershipTransferred_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseOwnershipTransferred_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryOwnershipTransferred, error)) *PriceRegistryInterface_ParseOwnershipTransferred_Call { - _c.Call.Return(run) - return _c -} - -// ParsePremiumMultiplierWeiPerEthUpdated provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParsePremiumMultiplierWeiPerEthUpdated(log types.Log) (*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParsePremiumMultiplierWeiPerEthUpdated") - } - - var r0 *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePremiumMultiplierWeiPerEthUpdated' -type PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call struct { - *mock.Call -} - -// ParsePremiumMultiplierWeiPerEthUpdated is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParsePremiumMultiplierWeiPerEthUpdated(log interface{}) *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call { - return &PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call{Call: _e.mock.On("ParsePremiumMultiplierWeiPerEthUpdated", log)} -} - -func (_c *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call) Return(_a0 *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, _a1 error) *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, error)) *PriceRegistryInterface_ParsePremiumMultiplierWeiPerEthUpdated_Call { - _c.Call.Return(run) - return _c -} - -// ParsePriceFeedPerTokenUpdated provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParsePriceFeedPerTokenUpdated(log types.Log) (*price_registry.PriceRegistryPriceFeedPerTokenUpdated, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParsePriceFeedPerTokenUpdated") - } - - var r0 *price_registry.PriceRegistryPriceFeedPerTokenUpdated - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryPriceFeedPerTokenUpdated, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryPriceFeedPerTokenUpdated); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryPriceFeedPerTokenUpdated) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParsePriceFeedPerTokenUpdated' -type PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call struct { - *mock.Call -} - -// ParsePriceFeedPerTokenUpdated is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParsePriceFeedPerTokenUpdated(log interface{}) *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call { - return &PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call{Call: _e.mock.On("ParsePriceFeedPerTokenUpdated", log)} -} - -func (_c *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call) Return(_a0 *price_registry.PriceRegistryPriceFeedPerTokenUpdated, _a1 error) *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryPriceFeedPerTokenUpdated, error)) *PriceRegistryInterface_ParsePriceFeedPerTokenUpdated_Call { - _c.Call.Return(run) - return _c -} - -// ParseReportPermissionSet provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseReportPermissionSet(log types.Log) (*price_registry.PriceRegistryReportPermissionSet, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseReportPermissionSet") - } - - var r0 *price_registry.PriceRegistryReportPermissionSet - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryReportPermissionSet, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryReportPermissionSet); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryReportPermissionSet) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseReportPermissionSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseReportPermissionSet' -type PriceRegistryInterface_ParseReportPermissionSet_Call struct { - *mock.Call -} - -// ParseReportPermissionSet is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseReportPermissionSet(log interface{}) *PriceRegistryInterface_ParseReportPermissionSet_Call { - return &PriceRegistryInterface_ParseReportPermissionSet_Call{Call: _e.mock.On("ParseReportPermissionSet", log)} -} - -func (_c *PriceRegistryInterface_ParseReportPermissionSet_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseReportPermissionSet_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseReportPermissionSet_Call) Return(_a0 *price_registry.PriceRegistryReportPermissionSet, _a1 error) *PriceRegistryInterface_ParseReportPermissionSet_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseReportPermissionSet_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryReportPermissionSet, error)) *PriceRegistryInterface_ParseReportPermissionSet_Call { - _c.Call.Return(run) - return _c -} - -// ParseTokenTransferFeeConfigDeleted provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseTokenTransferFeeConfigDeleted(log types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigDeleted, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseTokenTransferFeeConfigDeleted") - } - - var r0 *price_registry.PriceRegistryTokenTransferFeeConfigDeleted - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigDeleted, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryTokenTransferFeeConfigDeleted); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryTokenTransferFeeConfigDeleted) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTokenTransferFeeConfigDeleted' -type PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call struct { - *mock.Call -} - -// ParseTokenTransferFeeConfigDeleted is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseTokenTransferFeeConfigDeleted(log interface{}) *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call { - return &PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call{Call: _e.mock.On("ParseTokenTransferFeeConfigDeleted", log)} -} - -func (_c *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call) Return(_a0 *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, _a1 error) *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigDeleted, error)) *PriceRegistryInterface_ParseTokenTransferFeeConfigDeleted_Call { - _c.Call.Return(run) - return _c -} - -// ParseTokenTransferFeeConfigUpdated provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseTokenTransferFeeConfigUpdated(log types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigUpdated, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseTokenTransferFeeConfigUpdated") - } - - var r0 *price_registry.PriceRegistryTokenTransferFeeConfigUpdated - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigUpdated, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryTokenTransferFeeConfigUpdated); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryTokenTransferFeeConfigUpdated) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseTokenTransferFeeConfigUpdated' -type PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call struct { - *mock.Call -} - -// ParseTokenTransferFeeConfigUpdated is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseTokenTransferFeeConfigUpdated(log interface{}) *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call { - return &PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call{Call: _e.mock.On("ParseTokenTransferFeeConfigUpdated", log)} -} - -func (_c *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call) Return(_a0 *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, _a1 error) *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryTokenTransferFeeConfigUpdated, error)) *PriceRegistryInterface_ParseTokenTransferFeeConfigUpdated_Call { - _c.Call.Return(run) - return _c -} - -// ParseUsdPerTokenUpdated provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseUsdPerTokenUpdated(log types.Log) (*price_registry.PriceRegistryUsdPerTokenUpdated, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseUsdPerTokenUpdated") - } - - var r0 *price_registry.PriceRegistryUsdPerTokenUpdated - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryUsdPerTokenUpdated, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryUsdPerTokenUpdated); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryUsdPerTokenUpdated) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseUsdPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseUsdPerTokenUpdated' -type PriceRegistryInterface_ParseUsdPerTokenUpdated_Call struct { - *mock.Call -} - -// ParseUsdPerTokenUpdated is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseUsdPerTokenUpdated(log interface{}) *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call { - return &PriceRegistryInterface_ParseUsdPerTokenUpdated_Call{Call: _e.mock.On("ParseUsdPerTokenUpdated", log)} -} - -func (_c *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call) Return(_a0 *price_registry.PriceRegistryUsdPerTokenUpdated, _a1 error) *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryUsdPerTokenUpdated, error)) *PriceRegistryInterface_ParseUsdPerTokenUpdated_Call { - _c.Call.Return(run) - return _c -} - -// ParseUsdPerUnitGasUpdated provides a mock function with given fields: log -func (_m *PriceRegistryInterface) ParseUsdPerUnitGasUpdated(log types.Log) (*price_registry.PriceRegistryUsdPerUnitGasUpdated, error) { - ret := _m.Called(log) - - if len(ret) == 0 { - panic("no return value specified for ParseUsdPerUnitGasUpdated") - } - - var r0 *price_registry.PriceRegistryUsdPerUnitGasUpdated - var r1 error - if rf, ok := ret.Get(0).(func(types.Log) (*price_registry.PriceRegistryUsdPerUnitGasUpdated, error)); ok { - return rf(log) - } - if rf, ok := ret.Get(0).(func(types.Log) *price_registry.PriceRegistryUsdPerUnitGasUpdated); ok { - r0 = rf(log) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*price_registry.PriceRegistryUsdPerUnitGasUpdated) - } - } - - if rf, ok := ret.Get(1).(func(types.Log) error); ok { - r1 = rf(log) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ParseUsdPerUnitGasUpdated' -type PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call struct { - *mock.Call -} - -// ParseUsdPerUnitGasUpdated is a helper method to define mock.On call -// - log types.Log -func (_e *PriceRegistryInterface_Expecter) ParseUsdPerUnitGasUpdated(log interface{}) *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call { - return &PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call{Call: _e.mock.On("ParseUsdPerUnitGasUpdated", log)} -} - -func (_c *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call) Run(run func(log types.Log)) *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Log)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call) Return(_a0 *price_registry.PriceRegistryUsdPerUnitGasUpdated, _a1 error) *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call) RunAndReturn(run func(types.Log) (*price_registry.PriceRegistryUsdPerUnitGasUpdated, error)) *PriceRegistryInterface_ParseUsdPerUnitGasUpdated_Call { - _c.Call.Return(run) - return _c -} - -// ProcessMessageArgs provides a mock function with given fields: opts, destChainSelector, feeToken, feeTokenAmount, extraArgs -func (_m *PriceRegistryInterface) ProcessMessageArgs(opts *bind.CallOpts, destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte) (price_registry.ProcessMessageArgs, error) { - ret := _m.Called(opts, destChainSelector, feeToken, feeTokenAmount, extraArgs) - - if len(ret) == 0 { - panic("no return value specified for ProcessMessageArgs") - } - - var r0 price_registry.ProcessMessageArgs - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address, *big.Int, []byte) (price_registry.ProcessMessageArgs, error)); ok { - return rf(opts, destChainSelector, feeToken, feeTokenAmount, extraArgs) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, common.Address, *big.Int, []byte) price_registry.ProcessMessageArgs); ok { - r0 = rf(opts, destChainSelector, feeToken, feeTokenAmount, extraArgs) - } else { - r0 = ret.Get(0).(price_registry.ProcessMessageArgs) - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, common.Address, *big.Int, []byte) error); ok { - r1 = rf(opts, destChainSelector, feeToken, feeTokenAmount, extraArgs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ProcessMessageArgs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ProcessMessageArgs' -type PriceRegistryInterface_ProcessMessageArgs_Call struct { - *mock.Call -} - -// ProcessMessageArgs is a helper method to define mock.On call -// - opts *bind.CallOpts -// - destChainSelector uint64 -// - feeToken common.Address -// - feeTokenAmount *big.Int -// - extraArgs []byte -func (_e *PriceRegistryInterface_Expecter) ProcessMessageArgs(opts interface{}, destChainSelector interface{}, feeToken interface{}, feeTokenAmount interface{}, extraArgs interface{}) *PriceRegistryInterface_ProcessMessageArgs_Call { - return &PriceRegistryInterface_ProcessMessageArgs_Call{Call: _e.mock.On("ProcessMessageArgs", opts, destChainSelector, feeToken, feeTokenAmount, extraArgs)} -} - -func (_c *PriceRegistryInterface_ProcessMessageArgs_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, feeToken common.Address, feeTokenAmount *big.Int, extraArgs []byte)) *PriceRegistryInterface_ProcessMessageArgs_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].(common.Address), args[3].(*big.Int), args[4].([]byte)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ProcessMessageArgs_Call) Return(_a0 price_registry.ProcessMessageArgs, _a1 error) *PriceRegistryInterface_ProcessMessageArgs_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ProcessMessageArgs_Call) RunAndReturn(run func(*bind.CallOpts, uint64, common.Address, *big.Int, []byte) (price_registry.ProcessMessageArgs, error)) *PriceRegistryInterface_ProcessMessageArgs_Call { - _c.Call.Return(run) - return _c -} - -// ProcessPoolReturnData provides a mock function with given fields: opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts -func (_m *PriceRegistryInterface) ProcessPoolReturnData(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []price_registry.InternalRampTokenAmount, sourceTokenAmounts []price_registry.ClientEVMTokenAmount) ([][]byte, error) { - ret := _m.Called(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) - - if len(ret) == 0 { - panic("no return value specified for ProcessPoolReturnData") - } - - var r0 [][]byte - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, []price_registry.InternalRampTokenAmount, []price_registry.ClientEVMTokenAmount) ([][]byte, error)); ok { - return rf(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, uint64, []price_registry.InternalRampTokenAmount, []price_registry.ClientEVMTokenAmount) [][]byte); ok { - r0 = rf(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([][]byte) - } - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, uint64, []price_registry.InternalRampTokenAmount, []price_registry.ClientEVMTokenAmount) error); ok { - r1 = rf(opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_ProcessPoolReturnData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ProcessPoolReturnData' -type PriceRegistryInterface_ProcessPoolReturnData_Call struct { - *mock.Call -} - -// ProcessPoolReturnData is a helper method to define mock.On call -// - opts *bind.CallOpts -// - destChainSelector uint64 -// - rampTokenAmounts []price_registry.InternalRampTokenAmount -// - sourceTokenAmounts []price_registry.ClientEVMTokenAmount -func (_e *PriceRegistryInterface_Expecter) ProcessPoolReturnData(opts interface{}, destChainSelector interface{}, rampTokenAmounts interface{}, sourceTokenAmounts interface{}) *PriceRegistryInterface_ProcessPoolReturnData_Call { - return &PriceRegistryInterface_ProcessPoolReturnData_Call{Call: _e.mock.On("ProcessPoolReturnData", opts, destChainSelector, rampTokenAmounts, sourceTokenAmounts)} -} - -func (_c *PriceRegistryInterface_ProcessPoolReturnData_Call) Run(run func(opts *bind.CallOpts, destChainSelector uint64, rampTokenAmounts []price_registry.InternalRampTokenAmount, sourceTokenAmounts []price_registry.ClientEVMTokenAmount)) *PriceRegistryInterface_ProcessPoolReturnData_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts), args[1].(uint64), args[2].([]price_registry.InternalRampTokenAmount), args[3].([]price_registry.ClientEVMTokenAmount)) - }) - return _c -} - -func (_c *PriceRegistryInterface_ProcessPoolReturnData_Call) Return(_a0 [][]byte, _a1 error) *PriceRegistryInterface_ProcessPoolReturnData_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_ProcessPoolReturnData_Call) RunAndReturn(run func(*bind.CallOpts, uint64, []price_registry.InternalRampTokenAmount, []price_registry.ClientEVMTokenAmount) ([][]byte, error)) *PriceRegistryInterface_ProcessPoolReturnData_Call { - _c.Call.Return(run) - return _c -} - -// SetReportPermissions provides a mock function with given fields: opts, permissions -func (_m *PriceRegistryInterface) SetReportPermissions(opts *bind.TransactOpts, permissions []price_registry.KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error) { - ret := _m.Called(opts, permissions) - - if len(ret) == 0 { - panic("no return value specified for SetReportPermissions") - } - - var r0 *types.Transaction - var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error)); ok { - return rf(opts, permissions) - } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.KeystoneFeedsPermissionHandlerPermission) *types.Transaction); ok { - r0 = rf(opts, permissions) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Transaction) - } - } - - if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []price_registry.KeystoneFeedsPermissionHandlerPermission) error); ok { - r1 = rf(opts, permissions) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_SetReportPermissions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetReportPermissions' -type PriceRegistryInterface_SetReportPermissions_Call struct { - *mock.Call -} - -// SetReportPermissions is a helper method to define mock.On call -// - opts *bind.TransactOpts -// - permissions []price_registry.KeystoneFeedsPermissionHandlerPermission -func (_e *PriceRegistryInterface_Expecter) SetReportPermissions(opts interface{}, permissions interface{}) *PriceRegistryInterface_SetReportPermissions_Call { - return &PriceRegistryInterface_SetReportPermissions_Call{Call: _e.mock.On("SetReportPermissions", opts, permissions)} -} - -func (_c *PriceRegistryInterface_SetReportPermissions_Call) Run(run func(opts *bind.TransactOpts, permissions []price_registry.KeystoneFeedsPermissionHandlerPermission)) *PriceRegistryInterface_SetReportPermissions_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts), args[1].([]price_registry.KeystoneFeedsPermissionHandlerPermission)) - }) - return _c -} - -func (_c *PriceRegistryInterface_SetReportPermissions_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_SetReportPermissions_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_SetReportPermissions_Call) RunAndReturn(run func(*bind.TransactOpts, []price_registry.KeystoneFeedsPermissionHandlerPermission) (*types.Transaction, error)) *PriceRegistryInterface_SetReportPermissions_Call { - _c.Call.Return(run) - return _c -} - -// TransferOwnership provides a mock function with given fields: opts, to -func (_m *PriceRegistryInterface) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - ret := _m.Called(opts, to) - - if len(ret) == 0 { - panic("no return value specified for TransferOwnership") - } - - var r0 *types.Transaction - var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) (*types.Transaction, error)); ok { - return rf(opts, to) - } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, common.Address) *types.Transaction); ok { - r0 = rf(opts, to) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Transaction) - } - } - - if rf, ok := ret.Get(1).(func(*bind.TransactOpts, common.Address) error); ok { - r1 = rf(opts, to) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_TransferOwnership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TransferOwnership' -type PriceRegistryInterface_TransferOwnership_Call struct { - *mock.Call -} - -// TransferOwnership is a helper method to define mock.On call -// - opts *bind.TransactOpts -// - to common.Address -func (_e *PriceRegistryInterface_Expecter) TransferOwnership(opts interface{}, to interface{}) *PriceRegistryInterface_TransferOwnership_Call { - return &PriceRegistryInterface_TransferOwnership_Call{Call: _e.mock.On("TransferOwnership", opts, to)} -} - -func (_c *PriceRegistryInterface_TransferOwnership_Call) Run(run func(opts *bind.TransactOpts, to common.Address)) *PriceRegistryInterface_TransferOwnership_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts), args[1].(common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_TransferOwnership_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_TransferOwnership_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_TransferOwnership_Call) RunAndReturn(run func(*bind.TransactOpts, common.Address) (*types.Transaction, error)) *PriceRegistryInterface_TransferOwnership_Call { - _c.Call.Return(run) - return _c -} - -// TypeAndVersion provides a mock function with given fields: opts -func (_m *PriceRegistryInterface) TypeAndVersion(opts *bind.CallOpts) (string, error) { - ret := _m.Called(opts) - - if len(ret) == 0 { - panic("no return value specified for TypeAndVersion") - } - - var r0 string - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts) (string, error)); ok { - return rf(opts) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts) string); ok { - r0 = rf(opts) - } else { - r0 = ret.Get(0).(string) - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_TypeAndVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TypeAndVersion' -type PriceRegistryInterface_TypeAndVersion_Call struct { - *mock.Call -} - -// TypeAndVersion is a helper method to define mock.On call -// - opts *bind.CallOpts -func (_e *PriceRegistryInterface_Expecter) TypeAndVersion(opts interface{}) *PriceRegistryInterface_TypeAndVersion_Call { - return &PriceRegistryInterface_TypeAndVersion_Call{Call: _e.mock.On("TypeAndVersion", opts)} -} - -func (_c *PriceRegistryInterface_TypeAndVersion_Call) Run(run func(opts *bind.CallOpts)) *PriceRegistryInterface_TypeAndVersion_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.CallOpts)) - }) - return _c -} - -func (_c *PriceRegistryInterface_TypeAndVersion_Call) Return(_a0 string, _a1 error) *PriceRegistryInterface_TypeAndVersion_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_TypeAndVersion_Call) RunAndReturn(run func(*bind.CallOpts) (string, error)) *PriceRegistryInterface_TypeAndVersion_Call { - _c.Call.Return(run) - return _c -} - -// UpdatePrices provides a mock function with given fields: opts, priceUpdates -func (_m *PriceRegistryInterface) UpdatePrices(opts *bind.TransactOpts, priceUpdates price_registry.InternalPriceUpdates) (*types.Transaction, error) { - ret := _m.Called(opts, priceUpdates) - - if len(ret) == 0 { - panic("no return value specified for UpdatePrices") - } - - var r0 *types.Transaction - var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, price_registry.InternalPriceUpdates) (*types.Transaction, error)); ok { - return rf(opts, priceUpdates) - } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, price_registry.InternalPriceUpdates) *types.Transaction); ok { - r0 = rf(opts, priceUpdates) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Transaction) - } - } - - if rf, ok := ret.Get(1).(func(*bind.TransactOpts, price_registry.InternalPriceUpdates) error); ok { - r1 = rf(opts, priceUpdates) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_UpdatePrices_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdatePrices' -type PriceRegistryInterface_UpdatePrices_Call struct { - *mock.Call -} - -// UpdatePrices is a helper method to define mock.On call -// - opts *bind.TransactOpts -// - priceUpdates price_registry.InternalPriceUpdates -func (_e *PriceRegistryInterface_Expecter) UpdatePrices(opts interface{}, priceUpdates interface{}) *PriceRegistryInterface_UpdatePrices_Call { - return &PriceRegistryInterface_UpdatePrices_Call{Call: _e.mock.On("UpdatePrices", opts, priceUpdates)} -} - -func (_c *PriceRegistryInterface_UpdatePrices_Call) Run(run func(opts *bind.TransactOpts, priceUpdates price_registry.InternalPriceUpdates)) *PriceRegistryInterface_UpdatePrices_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts), args[1].(price_registry.InternalPriceUpdates)) - }) - return _c -} - -func (_c *PriceRegistryInterface_UpdatePrices_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_UpdatePrices_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_UpdatePrices_Call) RunAndReturn(run func(*bind.TransactOpts, price_registry.InternalPriceUpdates) (*types.Transaction, error)) *PriceRegistryInterface_UpdatePrices_Call { - _c.Call.Return(run) - return _c -} - -// UpdateTokenPriceFeeds provides a mock function with given fields: opts, tokenPriceFeedUpdates -func (_m *PriceRegistryInterface) UpdateTokenPriceFeeds(opts *bind.TransactOpts, tokenPriceFeedUpdates []price_registry.PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error) { - ret := _m.Called(opts, tokenPriceFeedUpdates) - - if len(ret) == 0 { - panic("no return value specified for UpdateTokenPriceFeeds") - } - - var r0 *types.Transaction - var r1 error - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error)); ok { - return rf(opts, tokenPriceFeedUpdates) - } - if rf, ok := ret.Get(0).(func(*bind.TransactOpts, []price_registry.PriceRegistryTokenPriceFeedUpdate) *types.Transaction); ok { - r0 = rf(opts, tokenPriceFeedUpdates) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Transaction) - } - } - - if rf, ok := ret.Get(1).(func(*bind.TransactOpts, []price_registry.PriceRegistryTokenPriceFeedUpdate) error); ok { - r1 = rf(opts, tokenPriceFeedUpdates) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_UpdateTokenPriceFeeds_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateTokenPriceFeeds' -type PriceRegistryInterface_UpdateTokenPriceFeeds_Call struct { - *mock.Call -} - -// UpdateTokenPriceFeeds is a helper method to define mock.On call -// - opts *bind.TransactOpts -// - tokenPriceFeedUpdates []price_registry.PriceRegistryTokenPriceFeedUpdate -func (_e *PriceRegistryInterface_Expecter) UpdateTokenPriceFeeds(opts interface{}, tokenPriceFeedUpdates interface{}) *PriceRegistryInterface_UpdateTokenPriceFeeds_Call { - return &PriceRegistryInterface_UpdateTokenPriceFeeds_Call{Call: _e.mock.On("UpdateTokenPriceFeeds", opts, tokenPriceFeedUpdates)} -} - -func (_c *PriceRegistryInterface_UpdateTokenPriceFeeds_Call) Run(run func(opts *bind.TransactOpts, tokenPriceFeedUpdates []price_registry.PriceRegistryTokenPriceFeedUpdate)) *PriceRegistryInterface_UpdateTokenPriceFeeds_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.TransactOpts), args[1].([]price_registry.PriceRegistryTokenPriceFeedUpdate)) - }) - return _c -} - -func (_c *PriceRegistryInterface_UpdateTokenPriceFeeds_Call) Return(_a0 *types.Transaction, _a1 error) *PriceRegistryInterface_UpdateTokenPriceFeeds_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_UpdateTokenPriceFeeds_Call) RunAndReturn(run func(*bind.TransactOpts, []price_registry.PriceRegistryTokenPriceFeedUpdate) (*types.Transaction, error)) *PriceRegistryInterface_UpdateTokenPriceFeeds_Call { - _c.Call.Return(run) - return _c -} - -// WatchAuthorizedCallerAdded provides a mock function with given fields: opts, sink -func (_m *PriceRegistryInterface) WatchAuthorizedCallerAdded(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryAuthorizedCallerAdded) (event.Subscription, error) { - ret := _m.Called(opts, sink) - - if len(ret) == 0 { - panic("no return value specified for WatchAuthorizedCallerAdded") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerAdded) (event.Subscription, error)); ok { - return rf(opts, sink) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerAdded) event.Subscription); ok { - r0 = rf(opts, sink) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerAdded) error); ok { - r1 = rf(opts, sink) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchAuthorizedCallerAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchAuthorizedCallerAdded' -type PriceRegistryInterface_WatchAuthorizedCallerAdded_Call struct { - *mock.Call -} - -// WatchAuthorizedCallerAdded is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryAuthorizedCallerAdded -func (_e *PriceRegistryInterface_Expecter) WatchAuthorizedCallerAdded(opts interface{}, sink interface{}) *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call { - return &PriceRegistryInterface_WatchAuthorizedCallerAdded_Call{Call: _e.mock.On("WatchAuthorizedCallerAdded", opts, sink)} -} - -func (_c *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryAuthorizedCallerAdded)) *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryAuthorizedCallerAdded)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerAdded) (event.Subscription, error)) *PriceRegistryInterface_WatchAuthorizedCallerAdded_Call { - _c.Call.Return(run) - return _c -} - -// WatchAuthorizedCallerRemoved provides a mock function with given fields: opts, sink -func (_m *PriceRegistryInterface) WatchAuthorizedCallerRemoved(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved) (event.Subscription, error) { - ret := _m.Called(opts, sink) - - if len(ret) == 0 { - panic("no return value specified for WatchAuthorizedCallerRemoved") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved) (event.Subscription, error)); ok { - return rf(opts, sink) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved) event.Subscription); ok { - r0 = rf(opts, sink) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved) error); ok { - r1 = rf(opts, sink) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchAuthorizedCallerRemoved' -type PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call struct { - *mock.Call -} - -// WatchAuthorizedCallerRemoved is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved -func (_e *PriceRegistryInterface_Expecter) WatchAuthorizedCallerRemoved(opts interface{}, sink interface{}) *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call { - return &PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call{Call: _e.mock.On("WatchAuthorizedCallerRemoved", opts, sink)} -} - -func (_c *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved)) *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryAuthorizedCallerRemoved) (event.Subscription, error)) *PriceRegistryInterface_WatchAuthorizedCallerRemoved_Call { - _c.Call.Return(run) - return _c -} - -// WatchDestChainAdded provides a mock function with given fields: opts, sink, destChainSelector -func (_m *PriceRegistryInterface) WatchDestChainAdded(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryDestChainAdded, destChainSelector []uint64) (event.Subscription, error) { - ret := _m.Called(opts, sink, destChainSelector) - - if len(ret) == 0 { - panic("no return value specified for WatchDestChainAdded") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainAdded, []uint64) (event.Subscription, error)); ok { - return rf(opts, sink, destChainSelector) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainAdded, []uint64) event.Subscription); ok { - r0 = rf(opts, sink, destChainSelector) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainAdded, []uint64) error); ok { - r1 = rf(opts, sink, destChainSelector) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchDestChainAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchDestChainAdded' -type PriceRegistryInterface_WatchDestChainAdded_Call struct { - *mock.Call -} - -// WatchDestChainAdded is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryDestChainAdded -// - destChainSelector []uint64 -func (_e *PriceRegistryInterface_Expecter) WatchDestChainAdded(opts interface{}, sink interface{}, destChainSelector interface{}) *PriceRegistryInterface_WatchDestChainAdded_Call { - return &PriceRegistryInterface_WatchDestChainAdded_Call{Call: _e.mock.On("WatchDestChainAdded", opts, sink, destChainSelector)} -} - -func (_c *PriceRegistryInterface_WatchDestChainAdded_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryDestChainAdded, destChainSelector []uint64)) *PriceRegistryInterface_WatchDestChainAdded_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryDestChainAdded), args[2].([]uint64)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchDestChainAdded_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchDestChainAdded_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchDestChainAdded_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainAdded, []uint64) (event.Subscription, error)) *PriceRegistryInterface_WatchDestChainAdded_Call { - _c.Call.Return(run) - return _c -} - -// WatchDestChainConfigUpdated provides a mock function with given fields: opts, sink, destChainSelector -func (_m *PriceRegistryInterface) WatchDestChainConfigUpdated(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryDestChainConfigUpdated, destChainSelector []uint64) (event.Subscription, error) { - ret := _m.Called(opts, sink, destChainSelector) - - if len(ret) == 0 { - panic("no return value specified for WatchDestChainConfigUpdated") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainConfigUpdated, []uint64) (event.Subscription, error)); ok { - return rf(opts, sink, destChainSelector) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainConfigUpdated, []uint64) event.Subscription); ok { - r0 = rf(opts, sink, destChainSelector) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainConfigUpdated, []uint64) error); ok { - r1 = rf(opts, sink, destChainSelector) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchDestChainConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchDestChainConfigUpdated' -type PriceRegistryInterface_WatchDestChainConfigUpdated_Call struct { - *mock.Call -} - -// WatchDestChainConfigUpdated is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryDestChainConfigUpdated -// - destChainSelector []uint64 -func (_e *PriceRegistryInterface_Expecter) WatchDestChainConfigUpdated(opts interface{}, sink interface{}, destChainSelector interface{}) *PriceRegistryInterface_WatchDestChainConfigUpdated_Call { - return &PriceRegistryInterface_WatchDestChainConfigUpdated_Call{Call: _e.mock.On("WatchDestChainConfigUpdated", opts, sink, destChainSelector)} -} - -func (_c *PriceRegistryInterface_WatchDestChainConfigUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryDestChainConfigUpdated, destChainSelector []uint64)) *PriceRegistryInterface_WatchDestChainConfigUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryDestChainConfigUpdated), args[2].([]uint64)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchDestChainConfigUpdated_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchDestChainConfigUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchDestChainConfigUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryDestChainConfigUpdated, []uint64) (event.Subscription, error)) *PriceRegistryInterface_WatchDestChainConfigUpdated_Call { - _c.Call.Return(run) - return _c -} - -// WatchFeeTokenAdded provides a mock function with given fields: opts, sink, feeToken -func (_m *PriceRegistryInterface) WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) { - ret := _m.Called(opts, sink, feeToken) - - if len(ret) == 0 { - panic("no return value specified for WatchFeeTokenAdded") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenAdded, []common.Address) (event.Subscription, error)); ok { - return rf(opts, sink, feeToken) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenAdded, []common.Address) event.Subscription); ok { - r0 = rf(opts, sink, feeToken) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenAdded, []common.Address) error); ok { - r1 = rf(opts, sink, feeToken) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchFeeTokenAdded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchFeeTokenAdded' -type PriceRegistryInterface_WatchFeeTokenAdded_Call struct { - *mock.Call -} - -// WatchFeeTokenAdded is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryFeeTokenAdded -// - feeToken []common.Address -func (_e *PriceRegistryInterface_Expecter) WatchFeeTokenAdded(opts interface{}, sink interface{}, feeToken interface{}) *PriceRegistryInterface_WatchFeeTokenAdded_Call { - return &PriceRegistryInterface_WatchFeeTokenAdded_Call{Call: _e.mock.On("WatchFeeTokenAdded", opts, sink, feeToken)} -} - -func (_c *PriceRegistryInterface_WatchFeeTokenAdded_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryFeeTokenAdded, feeToken []common.Address)) *PriceRegistryInterface_WatchFeeTokenAdded_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryFeeTokenAdded), args[2].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchFeeTokenAdded_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchFeeTokenAdded_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchFeeTokenAdded_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenAdded, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchFeeTokenAdded_Call { - _c.Call.Return(run) - return _c -} - -// WatchFeeTokenRemoved provides a mock function with given fields: opts, sink, feeToken -func (_m *PriceRegistryInterface) WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) { - ret := _m.Called(opts, sink, feeToken) - - if len(ret) == 0 { - panic("no return value specified for WatchFeeTokenRemoved") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenRemoved, []common.Address) (event.Subscription, error)); ok { - return rf(opts, sink, feeToken) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenRemoved, []common.Address) event.Subscription); ok { - r0 = rf(opts, sink, feeToken) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenRemoved, []common.Address) error); ok { - r1 = rf(opts, sink, feeToken) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchFeeTokenRemoved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchFeeTokenRemoved' -type PriceRegistryInterface_WatchFeeTokenRemoved_Call struct { - *mock.Call -} - -// WatchFeeTokenRemoved is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryFeeTokenRemoved -// - feeToken []common.Address -func (_e *PriceRegistryInterface_Expecter) WatchFeeTokenRemoved(opts interface{}, sink interface{}, feeToken interface{}) *PriceRegistryInterface_WatchFeeTokenRemoved_Call { - return &PriceRegistryInterface_WatchFeeTokenRemoved_Call{Call: _e.mock.On("WatchFeeTokenRemoved", opts, sink, feeToken)} -} - -func (_c *PriceRegistryInterface_WatchFeeTokenRemoved_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryFeeTokenRemoved, feeToken []common.Address)) *PriceRegistryInterface_WatchFeeTokenRemoved_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryFeeTokenRemoved), args[2].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchFeeTokenRemoved_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchFeeTokenRemoved_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchFeeTokenRemoved_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryFeeTokenRemoved, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchFeeTokenRemoved_Call { - _c.Call.Return(run) - return _c -} - -// WatchOwnershipTransferRequested provides a mock function with given fields: opts, sink, from, to -func (_m *PriceRegistryInterface) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { - ret := _m.Called(opts, sink, from, to) - - if len(ret) == 0 { - panic("no return value specified for WatchOwnershipTransferRequested") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)); ok { - return rf(opts, sink, from, to) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferRequested, []common.Address, []common.Address) event.Subscription); ok { - r0 = rf(opts, sink, from, to) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferRequested, []common.Address, []common.Address) error); ok { - r1 = rf(opts, sink, from, to) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchOwnershipTransferRequested_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferRequested' -type PriceRegistryInterface_WatchOwnershipTransferRequested_Call struct { - *mock.Call -} - -// WatchOwnershipTransferRequested is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryOwnershipTransferRequested -// - from []common.Address -// - to []common.Address -func (_e *PriceRegistryInterface_Expecter) WatchOwnershipTransferRequested(opts interface{}, sink interface{}, from interface{}, to interface{}) *PriceRegistryInterface_WatchOwnershipTransferRequested_Call { - return &PriceRegistryInterface_WatchOwnershipTransferRequested_Call{Call: _e.mock.On("WatchOwnershipTransferRequested", opts, sink, from, to)} -} - -func (_c *PriceRegistryInterface_WatchOwnershipTransferRequested_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address)) *PriceRegistryInterface_WatchOwnershipTransferRequested_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryOwnershipTransferRequested), args[2].([]common.Address), args[3].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchOwnershipTransferRequested_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchOwnershipTransferRequested_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchOwnershipTransferRequested_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferRequested, []common.Address, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchOwnershipTransferRequested_Call { - _c.Call.Return(run) - return _c -} - -// WatchOwnershipTransferred provides a mock function with given fields: opts, sink, from, to -func (_m *PriceRegistryInterface) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { - ret := _m.Called(opts, sink, from, to) - - if len(ret) == 0 { - panic("no return value specified for WatchOwnershipTransferred") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)); ok { - return rf(opts, sink, from, to) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferred, []common.Address, []common.Address) event.Subscription); ok { - r0 = rf(opts, sink, from, to) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferred, []common.Address, []common.Address) error); ok { - r1 = rf(opts, sink, from, to) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchOwnershipTransferred_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchOwnershipTransferred' -type PriceRegistryInterface_WatchOwnershipTransferred_Call struct { - *mock.Call -} - -// WatchOwnershipTransferred is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryOwnershipTransferred -// - from []common.Address -// - to []common.Address -func (_e *PriceRegistryInterface_Expecter) WatchOwnershipTransferred(opts interface{}, sink interface{}, from interface{}, to interface{}) *PriceRegistryInterface_WatchOwnershipTransferred_Call { - return &PriceRegistryInterface_WatchOwnershipTransferred_Call{Call: _e.mock.On("WatchOwnershipTransferred", opts, sink, from, to)} -} - -func (_c *PriceRegistryInterface_WatchOwnershipTransferred_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address)) *PriceRegistryInterface_WatchOwnershipTransferred_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryOwnershipTransferred), args[2].([]common.Address), args[3].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchOwnershipTransferred_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchOwnershipTransferred_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchOwnershipTransferred_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryOwnershipTransferred, []common.Address, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchOwnershipTransferred_Call { - _c.Call.Return(run) - return _c -} - -// WatchPremiumMultiplierWeiPerEthUpdated provides a mock function with given fields: opts, sink, token -func (_m *PriceRegistryInterface) WatchPremiumMultiplierWeiPerEthUpdated(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, token []common.Address) (event.Subscription, error) { - ret := _m.Called(opts, sink, token) - - if len(ret) == 0 { - panic("no return value specified for WatchPremiumMultiplierWeiPerEthUpdated") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, []common.Address) (event.Subscription, error)); ok { - return rf(opts, sink, token) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, []common.Address) event.Subscription); ok { - r0 = rf(opts, sink, token) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, []common.Address) error); ok { - r1 = rf(opts, sink, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPremiumMultiplierWeiPerEthUpdated' -type PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call struct { - *mock.Call -} - -// WatchPremiumMultiplierWeiPerEthUpdated is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated -// - token []common.Address -func (_e *PriceRegistryInterface_Expecter) WatchPremiumMultiplierWeiPerEthUpdated(opts interface{}, sink interface{}, token interface{}) *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call { - return &PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call{Call: _e.mock.On("WatchPremiumMultiplierWeiPerEthUpdated", opts, sink, token)} -} - -func (_c *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, token []common.Address)) *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated), args[2].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPremiumMultiplierWeiPerEthUpdated, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchPremiumMultiplierWeiPerEthUpdated_Call { - _c.Call.Return(run) - return _c -} - -// WatchPriceFeedPerTokenUpdated provides a mock function with given fields: opts, sink, token -func (_m *PriceRegistryInterface) WatchPriceFeedPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated, token []common.Address) (event.Subscription, error) { - ret := _m.Called(opts, sink, token) - - if len(ret) == 0 { - panic("no return value specified for WatchPriceFeedPerTokenUpdated") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated, []common.Address) (event.Subscription, error)); ok { - return rf(opts, sink, token) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated, []common.Address) event.Subscription); ok { - r0 = rf(opts, sink, token) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated, []common.Address) error); ok { - r1 = rf(opts, sink, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchPriceFeedPerTokenUpdated' -type PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call struct { - *mock.Call -} - -// WatchPriceFeedPerTokenUpdated is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated -// - token []common.Address -func (_e *PriceRegistryInterface_Expecter) WatchPriceFeedPerTokenUpdated(opts interface{}, sink interface{}, token interface{}) *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call { - return &PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call{Call: _e.mock.On("WatchPriceFeedPerTokenUpdated", opts, sink, token)} -} - -func (_c *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated, token []common.Address)) *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated), args[2].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryPriceFeedPerTokenUpdated, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchPriceFeedPerTokenUpdated_Call { - _c.Call.Return(run) - return _c -} - -// WatchReportPermissionSet provides a mock function with given fields: opts, sink, reportId -func (_m *PriceRegistryInterface) WatchReportPermissionSet(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryReportPermissionSet, reportId [][32]byte) (event.Subscription, error) { - ret := _m.Called(opts, sink, reportId) - - if len(ret) == 0 { - panic("no return value specified for WatchReportPermissionSet") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryReportPermissionSet, [][32]byte) (event.Subscription, error)); ok { - return rf(opts, sink, reportId) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryReportPermissionSet, [][32]byte) event.Subscription); ok { - r0 = rf(opts, sink, reportId) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryReportPermissionSet, [][32]byte) error); ok { - r1 = rf(opts, sink, reportId) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchReportPermissionSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchReportPermissionSet' -type PriceRegistryInterface_WatchReportPermissionSet_Call struct { - *mock.Call -} - -// WatchReportPermissionSet is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryReportPermissionSet -// - reportId [][32]byte -func (_e *PriceRegistryInterface_Expecter) WatchReportPermissionSet(opts interface{}, sink interface{}, reportId interface{}) *PriceRegistryInterface_WatchReportPermissionSet_Call { - return &PriceRegistryInterface_WatchReportPermissionSet_Call{Call: _e.mock.On("WatchReportPermissionSet", opts, sink, reportId)} -} - -func (_c *PriceRegistryInterface_WatchReportPermissionSet_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryReportPermissionSet, reportId [][32]byte)) *PriceRegistryInterface_WatchReportPermissionSet_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryReportPermissionSet), args[2].([][32]byte)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchReportPermissionSet_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchReportPermissionSet_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchReportPermissionSet_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryReportPermissionSet, [][32]byte) (event.Subscription, error)) *PriceRegistryInterface_WatchReportPermissionSet_Call { - _c.Call.Return(run) - return _c -} - -// WatchTokenTransferFeeConfigDeleted provides a mock function with given fields: opts, sink, destChainSelector, token -func (_m *PriceRegistryInterface) WatchTokenTransferFeeConfigDeleted(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { - ret := _m.Called(opts, sink, destChainSelector, token) - - if len(ret) == 0 { - panic("no return value specified for WatchTokenTransferFeeConfigDeleted") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, []uint64, []common.Address) (event.Subscription, error)); ok { - return rf(opts, sink, destChainSelector, token) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, []uint64, []common.Address) event.Subscription); ok { - r0 = rf(opts, sink, destChainSelector, token) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, []uint64, []common.Address) error); ok { - r1 = rf(opts, sink, destChainSelector, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTokenTransferFeeConfigDeleted' -type PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call struct { - *mock.Call -} - -// WatchTokenTransferFeeConfigDeleted is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted -// - destChainSelector []uint64 -// - token []common.Address -func (_e *PriceRegistryInterface_Expecter) WatchTokenTransferFeeConfigDeleted(opts interface{}, sink interface{}, destChainSelector interface{}, token interface{}) *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call { - return &PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call{Call: _e.mock.On("WatchTokenTransferFeeConfigDeleted", opts, sink, destChainSelector, token)} -} - -func (_c *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, destChainSelector []uint64, token []common.Address)) *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted), args[2].([]uint64), args[3].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigDeleted, []uint64, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchTokenTransferFeeConfigDeleted_Call { - _c.Call.Return(run) - return _c -} - -// WatchTokenTransferFeeConfigUpdated provides a mock function with given fields: opts, sink, destChainSelector, token -func (_m *PriceRegistryInterface) WatchTokenTransferFeeConfigUpdated(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, destChainSelector []uint64, token []common.Address) (event.Subscription, error) { - ret := _m.Called(opts, sink, destChainSelector, token) - - if len(ret) == 0 { - panic("no return value specified for WatchTokenTransferFeeConfigUpdated") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, []uint64, []common.Address) (event.Subscription, error)); ok { - return rf(opts, sink, destChainSelector, token) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, []uint64, []common.Address) event.Subscription); ok { - r0 = rf(opts, sink, destChainSelector, token) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, []uint64, []common.Address) error); ok { - r1 = rf(opts, sink, destChainSelector, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchTokenTransferFeeConfigUpdated' -type PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call struct { - *mock.Call -} - -// WatchTokenTransferFeeConfigUpdated is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated -// - destChainSelector []uint64 -// - token []common.Address -func (_e *PriceRegistryInterface_Expecter) WatchTokenTransferFeeConfigUpdated(opts interface{}, sink interface{}, destChainSelector interface{}, token interface{}) *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call { - return &PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call{Call: _e.mock.On("WatchTokenTransferFeeConfigUpdated", opts, sink, destChainSelector, token)} -} - -func (_c *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, destChainSelector []uint64, token []common.Address)) *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated), args[2].([]uint64), args[3].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryTokenTransferFeeConfigUpdated, []uint64, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchTokenTransferFeeConfigUpdated_Call { - _c.Call.Return(run) - return _c -} - -// WatchUsdPerTokenUpdated provides a mock function with given fields: opts, sink, token -func (_m *PriceRegistryInterface) WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) { - ret := _m.Called(opts, sink, token) - - if len(ret) == 0 { - panic("no return value specified for WatchUsdPerTokenUpdated") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerTokenUpdated, []common.Address) (event.Subscription, error)); ok { - return rf(opts, sink, token) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerTokenUpdated, []common.Address) event.Subscription); ok { - r0 = rf(opts, sink, token) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerTokenUpdated, []common.Address) error); ok { - r1 = rf(opts, sink, token) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchUsdPerTokenUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchUsdPerTokenUpdated' -type PriceRegistryInterface_WatchUsdPerTokenUpdated_Call struct { - *mock.Call -} - -// WatchUsdPerTokenUpdated is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryUsdPerTokenUpdated -// - token []common.Address -func (_e *PriceRegistryInterface_Expecter) WatchUsdPerTokenUpdated(opts interface{}, sink interface{}, token interface{}) *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call { - return &PriceRegistryInterface_WatchUsdPerTokenUpdated_Call{Call: _e.mock.On("WatchUsdPerTokenUpdated", opts, sink, token)} -} - -func (_c *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryUsdPerTokenUpdated, token []common.Address)) *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryUsdPerTokenUpdated), args[2].([]common.Address)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerTokenUpdated, []common.Address) (event.Subscription, error)) *PriceRegistryInterface_WatchUsdPerTokenUpdated_Call { - _c.Call.Return(run) - return _c -} - -// WatchUsdPerUnitGasUpdated provides a mock function with given fields: opts, sink, destChain -func (_m *PriceRegistryInterface) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) { - ret := _m.Called(opts, sink, destChain) - - if len(ret) == 0 { - panic("no return value specified for WatchUsdPerUnitGasUpdated") - } - - var r0 event.Subscription - var r1 error - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated, []uint64) (event.Subscription, error)); ok { - return rf(opts, sink, destChain) - } - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated, []uint64) event.Subscription); ok { - r0 = rf(opts, sink, destChain) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(event.Subscription) - } - } - - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated, []uint64) error); ok { - r1 = rf(opts, sink, destChain) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchUsdPerUnitGasUpdated' -type PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call struct { - *mock.Call -} - -// WatchUsdPerUnitGasUpdated is a helper method to define mock.On call -// - opts *bind.WatchOpts -// - sink chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated -// - destChain []uint64 -func (_e *PriceRegistryInterface_Expecter) WatchUsdPerUnitGasUpdated(opts interface{}, sink interface{}, destChain interface{}) *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call { - return &PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call{Call: _e.mock.On("WatchUsdPerUnitGasUpdated", opts, sink, destChain)} -} - -func (_c *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call) Run(run func(opts *bind.WatchOpts, sink chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated, destChain []uint64)) *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*bind.WatchOpts), args[1].(chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated), args[2].([]uint64)) - }) - return _c -} - -func (_c *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call) Return(_a0 event.Subscription, _a1 error) *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call) RunAndReturn(run func(*bind.WatchOpts, chan<- *price_registry.PriceRegistryUsdPerUnitGasUpdated, []uint64) (event.Subscription, error)) *PriceRegistryInterface_WatchUsdPerUnitGasUpdated_Call { - _c.Call.Return(run) - return _c -} - -// NewPriceRegistryInterface creates a new instance of PriceRegistryInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewPriceRegistryInterface(t interface { - mock.TestingT - Cleanup(func()) -}) *PriceRegistryInterface { - mock := &PriceRegistryInterface{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/scripts/ccip/revert-reason/handler/reason.go b/core/scripts/ccip/revert-reason/handler/reason.go index 2e41935ffa..7256b85856 100644 --- a/core/scripts/ccip/revert-reason/handler/reason.go +++ b/core/scripts/ccip/revert-reason/handler/reason.go @@ -19,12 +19,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" @@ -144,7 +144,7 @@ func getAllABIs() []string { usdc_token_pool.USDCTokenPoolABI, commit_store.CommitStoreABI, token_admin_registry.TokenAdminRegistryABI, - price_registry.PriceRegistryABI, + fee_quoter.FeeQuoterABI, evm_2_evm_onramp.EVM2EVMOnRampABI, evm_2_evm_offramp.EVM2EVMOffRampABI, router.RouterABI, diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/test_helpers.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/test_helpers.go index e7972d5f5f..fb991be59d 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/test_helpers.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/test_helpers.go @@ -9,37 +9,37 @@ import ( "github.com/stretchr/testify/require" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" ) // ApplyPriceRegistryUpdate is a helper function used in tests only. func ApplyPriceRegistryUpdate(t *testing.T, user *bind.TransactOpts, addr common.Address, ec client.Client, gasPrices []cciptypes.GasPrice, tokenPrices []cciptypes.TokenPrice) common.Hash { require.True(t, len(gasPrices) <= 2) - pr, err := price_registry.NewPriceRegistry(addr, ec) + pr, err := fee_quoter.NewFeeQuoter(addr, ec) require.NoError(t, err) o, err := pr.Owner(nil) require.NoError(t, err) require.Equal(t, user.From, o) - var tps []price_registry.InternalTokenPriceUpdate + var tps []fee_quoter.InternalTokenPriceUpdate for _, tp := range tokenPrices { evmAddrs, err1 := ccipcalc.GenericAddrsToEvm(tp.Token) assert.NoError(t, err1) - tps = append(tps, price_registry.InternalTokenPriceUpdate{ + tps = append(tps, fee_quoter.InternalTokenPriceUpdate{ SourceToken: evmAddrs[0], UsdPerToken: tp.Value, }) } - var gps []price_registry.InternalGasPriceUpdate + var gps []fee_quoter.InternalGasPriceUpdate for _, gp := range gasPrices { - gps = append(gps, price_registry.InternalGasPriceUpdate{ + gps = append(gps, fee_quoter.InternalGasPriceUpdate{ DestChainSelector: gp.DestChainSelector, UsdPerUnitGas: gp.Value, }) } - tx, err := pr.UpdatePrices(user, price_registry.InternalPriceUpdates{ + tx, err := pr.UpdatePrices(user, fee_quoter.InternalPriceUpdates{ TokenPriceUpdates: tps, GasPriceUpdates: gps, }) diff --git a/integration-tests/ccip-tests/actions/ccip_helpers.go b/integration-tests/ccip-tests/actions/ccip_helpers.go index ff8bfa2c9a..0bffa84291 100644 --- a/integration-tests/ccip-tests/actions/ccip_helpers.go +++ b/integration-tests/ccip-tests/actions/ccip_helpers.go @@ -56,8 +56,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_pool" @@ -528,8 +528,8 @@ func (ccipModule *CCIPCommon) WaitForPriceUpdates( // of price update events and add the event details to watchers. It subscribes to 'UsdPerUnitGasUpdated' // and 'UsdPerTokenUpdated' event. func (ccipModule *CCIPCommon) WatchForPriceUpdates(ctx context.Context, lggr *zerolog.Logger) error { - gasUpdateEventLatest := make(chan *price_registry.PriceRegistryUsdPerUnitGasUpdated) - tokenUpdateEvent := make(chan *price_registry.PriceRegistryUsdPerTokenUpdated) + gasUpdateEventLatest := make(chan *fee_quoter.FeeQuoterUsdPerUnitGasUpdated) + tokenUpdateEvent := make(chan *fee_quoter.FeeQuoterUsdPerTokenUpdated) sub := event.Resubscribe(DefaultResubscriptionTimeout, func(_ context.Context) (event.Subscription, error) { lggr.Info().Msg("Subscribing to UsdPerUnitGasUpdated event") eventSub, err := ccipModule.PriceRegistry.WatchUsdPerUnitGasUpdated(nil, gasUpdateEventLatest, nil) diff --git a/integration-tests/ccip-tests/contracts/contract_models.go b/integration-tests/ccip-tests/contracts/contract_models.go index 26794816dd..9b59ce4008 100644 --- a/integration-tests/ccip-tests/contracts/contract_models.go +++ b/integration-tests/ccip-tests/contracts/contract_models.go @@ -27,13 +27,13 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_v3_aggregator_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" @@ -1111,7 +1111,7 @@ type PriceRegistryUsdPerUnitGasUpdated struct { } type PriceRegistryWrapper struct { - Latest *price_registry.PriceRegistry + Latest *fee_quoter.FeeQuoter V1_2_0 *price_registry_1_2_0.PriceRegistry } @@ -1137,7 +1137,7 @@ func (p *PriceRegistryWrapper) AddPriceUpdater(opts *bind.TransactOpts, addr com if p.Latest != nil { return p.Latest.ApplyAuthorizedCallerUpdates( opts, - price_registry.AuthorizedCallersAuthorizedCallerArgs{ + fee_quoter.AuthorizedCallersAuthorizedCallerArgs{ AddedCallers: []common.Address{addr}, RemovedCallers: []common.Address{}, }, @@ -1243,21 +1243,21 @@ func (c *PriceRegistry) UpdatePrices(tokenUpdates []InternalTokenPriceUpdate, ga } var tx *types.Transaction if c.Instance.Latest != nil { - var tokenUpdatesLatest []price_registry.InternalTokenPriceUpdate - var gasUpdatesLatest []price_registry.InternalGasPriceUpdate + var tokenUpdatesLatest []fee_quoter.InternalTokenPriceUpdate + var gasUpdatesLatest []fee_quoter.InternalGasPriceUpdate for _, update := range tokenUpdates { - tokenUpdatesLatest = append(tokenUpdatesLatest, price_registry.InternalTokenPriceUpdate{ + tokenUpdatesLatest = append(tokenUpdatesLatest, fee_quoter.InternalTokenPriceUpdate{ SourceToken: update.SourceToken, UsdPerToken: update.UsdPerToken, }) } for _, update := range gasUpdates { - gasUpdatesLatest = append(gasUpdatesLatest, price_registry.InternalGasPriceUpdate{ + gasUpdatesLatest = append(gasUpdatesLatest, fee_quoter.InternalGasPriceUpdate{ DestChainSelector: update.DestChainSelector, UsdPerUnitGas: update.UsdPerUnitGas, }) } - tx, err = c.Instance.Latest.UpdatePrices(opts, price_registry.InternalPriceUpdates{ + tx, err = c.Instance.Latest.UpdatePrices(opts, fee_quoter.InternalPriceUpdates{ TokenPriceUpdates: tokenUpdatesLatest, GasPriceUpdates: gasUpdatesLatest, }) @@ -1299,12 +1299,12 @@ func (c *PriceRegistry) UpdatePrices(tokenUpdates []InternalTokenPriceUpdate, ga return c.client.ProcessTransaction(tx) } -func (c *PriceRegistry) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, latest chan *price_registry.PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) { +func (c *PriceRegistry) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, latest chan *fee_quoter.FeeQuoterUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) { if c.Instance.Latest != nil { return c.Instance.Latest.WatchUsdPerUnitGasUpdated(opts, latest, destChain) } if c.Instance.V1_2_0 != nil { - newP, err := price_registry.NewPriceRegistry(c.Instance.V1_2_0.Address(), wrappers.MustNewWrappedContractBackend(c.client, nil)) + newP, err := fee_quoter.NewFeeQuoter(c.Instance.V1_2_0.Address(), wrappers.MustNewWrappedContractBackend(c.client, nil)) if err != nil { return nil, fmt.Errorf("failed to create new PriceRegistry contract: %w", err) } @@ -1313,12 +1313,12 @@ func (c *PriceRegistry) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, latest c return nil, fmt.Errorf("no instance found to watch for price updates for gas") } -func (c *PriceRegistry) WatchUsdPerTokenUpdated(opts *bind.WatchOpts, latest chan *price_registry.PriceRegistryUsdPerTokenUpdated) (event.Subscription, error) { +func (c *PriceRegistry) WatchUsdPerTokenUpdated(opts *bind.WatchOpts, latest chan *fee_quoter.FeeQuoterUsdPerTokenUpdated) (event.Subscription, error) { if c.Instance.Latest != nil { return c.Instance.Latest.WatchUsdPerTokenUpdated(opts, latest, nil) } if c.Instance.V1_2_0 != nil { - newP, err := price_registry.NewPriceRegistry(c.Instance.V1_2_0.Address(), wrappers.MustNewWrappedContractBackend(c.client, nil)) + newP, err := fee_quoter.NewFeeQuoter(c.Instance.V1_2_0.Address(), wrappers.MustNewWrappedContractBackend(c.client, nil)) if err != nil { return nil, fmt.Errorf("failed to create new PriceRegistry contract: %w", err) } diff --git a/integration-tests/deployment/ccip/add_lane.go b/integration-tests/deployment/ccip/add_lane.go index 1f8dcd43f9..16384e0aba 100644 --- a/integration-tests/deployment/ccip/add_lane.go +++ b/integration-tests/deployment/ccip/add_lane.go @@ -7,10 +7,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" ) @@ -37,8 +36,8 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) } _, err = state.Chains[from].PriceRegistry.UpdatePrices( - e.Chains[from].DeployerKey, price_registry.InternalPriceUpdates{ - TokenPriceUpdates: []price_registry.InternalTokenPriceUpdate{ + e.Chains[from].DeployerKey, fee_quoter.InternalPriceUpdates{ + TokenPriceUpdates: []fee_quoter.InternalTokenPriceUpdate{ { SourceToken: state.Chains[from].LinkToken.Address(), UsdPerToken: deployment.E18Mult(20), @@ -48,7 +47,7 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) UsdPerToken: deployment.E18Mult(4000), }, }, - GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + GasPriceUpdates: []fee_quoter.InternalGasPriceUpdate{ { DestChainSelector: to, UsdPerUnitGas: big.NewInt(2e12), @@ -60,7 +59,7 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) // Enable dest in price registry tx, err = state.Chains[from].PriceRegistry.ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, - []price_registry.PriceRegistryDestChainConfigArgs{ + []fee_quoter.FeeQuoterDestChainConfigArgs{ { DestChainSelector: to, DestChainConfig: defaultPriceRegistryDestChainConfig(), @@ -91,7 +90,7 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) return deployment.ConfirmIfNoError(e.Chains[to], tx, err) } -func defaultPriceRegistryDestChainConfig() price_registry.PriceRegistryDestChainConfig { +func defaultPriceRegistryDestChainConfig() fee_quoter.FeeQuoterDestChainConfig { // https://github.com/smartcontractkit/ccip/blob/c4856b64bd766f1ddbaf5d13b42d3c4b12efde3a/contracts/src/v0.8/ccip/libraries/Internal.sol#L337-L337 /* ```Solidity @@ -100,7 +99,7 @@ func defaultPriceRegistryDestChainConfig() price_registry.PriceRegistryDestChain ``` */ evmFamilySelector, _ := hex.DecodeString("2812d52c") - return price_registry.PriceRegistryDestChainConfig{ + return fee_quoter.FeeQuoterDestChainConfig{ IsEnabled: true, MaxNumberOfTokensPerMsg: 10, MaxDataBytes: 256, diff --git a/integration-tests/deployment/ccip/deploy.go b/integration-tests/deployment/ccip/deploy.go index 3385551a22..ff589d1430 100644 --- a/integration-tests/deployment/ccip/deploy.go +++ b/integration-tests/deployment/ccip/deploy.go @@ -1,7 +1,6 @@ package ccipdeployment import ( - "encoding/hex" "fmt" "math/big" @@ -10,17 +9,16 @@ import ( "github.com/ethereum/go-ethereum/core/types" owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/integration-tests/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - - "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" @@ -52,7 +50,7 @@ type Contracts interface { *rmn_proxy_contract.RMNProxyContract | *ccip_config.CCIPConfig | *nonce_manager.NonceManager | - *price_registry.PriceRegistry | + *fee_quoter.FeeQuoter | *router.Router | *token_admin_registry.TokenAdminRegistry | *weth9.WETH9 | @@ -114,16 +112,16 @@ type DeployCCIPContractConfig struct { // Or mock vs real RMN. // Deployment produces an address book of everything it deployed. func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) (deployment.AddressBook, error) { - ab := deployment.NewMemoryAddressBook() + var ab deployment.AddressBook = deployment.NewMemoryAddressBook() nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) if err != nil || len(nodes) == 0 { e.Logger.Errorw("Failed to get node info", "err", err) return ab, err } - if _, ok := c.CapabilityRegistry[c.HomeChainSel]; !ok { + if c.Chains[c.HomeChainSel].CapabilityRegistry == nil { return ab, fmt.Errorf("Capability registry not found for home chain %d, needs to be deployed first", c.HomeChainSel) } - cr, err := c.CapabilityRegistry[c.HomeChainSel].GetHashedCapabilityId( + cr, err := c.Chains[c.HomeChainSel].CapabilityRegistry.GetHashedCapabilityId( &bind.CallOpts{}, CapabilityLabelledName, CapabilityVersion) if err != nil { e.Logger.Errorw("Failed to get hashed capability id", "err", err) @@ -131,7 +129,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( } // Signal to CR that our nodes support CCIP capability. if err := AddNodes( - c.CapabilityRegistry[c.HomeChainSel], + c.Chains[c.HomeChainSel].CapabilityRegistry, e.Chains[c.HomeChainSel], nodes.PeerIDs(c.HomeChainSel), // Doesn't actually matter which sel here [][32]byte{cr}, @@ -139,283 +137,33 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( return ab, err } - for sel, chain := range e.Chains { - ccipReceiver, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver] { - receiverAddr, tx, receiver, err2 := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver( - chain.DeployerKey, - chain.Client, - false, - ) - return ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver]{ - receiverAddr, receiver, tx, deployment.NewTypeAndVersion(CCIPReceiver, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy receiver", "err", err) - return ab, err - } - e.Logger.Infow("deployed receiver", "addr", ccipReceiver.Address) - - // TODO: Still waiting for RMNRemote/RMNHome contracts etc. - mockARM, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*mock_rmn_contract.MockRMNContract] { - mockARMAddr, tx, mockARM, err2 := mock_rmn_contract.DeployMockRMNContract( - chain.DeployerKey, - chain.Client, - ) - return ContractDeploy[*mock_rmn_contract.MockRMNContract]{ - mockARMAddr, mockARM, tx, deployment.NewTypeAndVersion(MockARM, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy mockARM", "err", err) - return ab, err - } - e.Logger.Infow("deployed mockARM", "addr", mockARM) - - mcm, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*owner_helpers.ManyChainMultiSig] { - mcmAddr, tx, mcm, err2 := owner_helpers.DeployManyChainMultiSig( - chain.DeployerKey, - chain.Client, - ) - return ContractDeploy[*owner_helpers.ManyChainMultiSig]{ - mcmAddr, mcm, tx, deployment.NewTypeAndVersion(ManyChainMultisig, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy mcm", "err", err) - return ab, err - } - // TODO: Address soon - e.Logger.Infow("deployed mcm", "addr", mcm.Address) - - _, err = deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*owner_helpers.RBACTimelock] { - timelock, tx, cc, err2 := owner_helpers.DeployRBACTimelock( - chain.DeployerKey, - chain.Client, - big.NewInt(0), // minDelay - mcm.Address, - []common.Address{mcm.Address}, // proposers - []common.Address{chain.DeployerKey.From}, //executors - []common.Address{mcm.Address}, // cancellers - []common.Address{mcm.Address}, // bypassers - ) - return ContractDeploy[*owner_helpers.RBACTimelock]{ - timelock, cc, tx, deployment.NewTypeAndVersion(RBACTimelock, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy timelock", "err", err) - return ab, err - } - e.Logger.Infow("deployed timelock", "addr", mcm.Address) - - armProxy, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*rmn_proxy_contract.RMNProxyContract] { - armProxyAddr, tx, armProxy, err2 := rmn_proxy_contract.DeployRMNProxyContract( - chain.DeployerKey, - chain.Client, - mockARM.Address, - ) - return ContractDeploy[*rmn_proxy_contract.RMNProxyContract]{ - armProxyAddr, armProxy, tx, deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy armProxy", "err", err) - return ab, err - } - e.Logger.Infow("deployed armProxy", "addr", armProxy.Address) - - weth9, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*weth9.WETH9] { - weth9Addr, tx, weth9c, err2 := weth9.DeployWETH9( - chain.DeployerKey, - chain.Client, - ) - return ContractDeploy[*weth9.WETH9]{ - weth9Addr, weth9c, tx, deployment.NewTypeAndVersion(WETH9, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy weth9", "err", err) - return ab, err - } - - linkToken, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*burn_mint_erc677.BurnMintERC677] { - linkTokenAddr, tx, linkToken, err2 := burn_mint_erc677.DeployBurnMintERC677( - chain.DeployerKey, - chain.Client, - "Link Token", - "LINK", - uint8(18), - big.NewInt(0).Mul(big.NewInt(1e9), big.NewInt(1e18)), - ) - return ContractDeploy[*burn_mint_erc677.BurnMintERC677]{ - linkTokenAddr, linkToken, tx, deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0), err2, - } - }) + for _, chain := range e.Chains { + ab, err = DeployChainContracts(e, chain, ab) if err != nil { - e.Logger.Errorw("Failed to deploy linkToken", "err", err) return ab, err } - - routerContract, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*router.Router] { - routerAddr, tx, routerC, err2 := router.DeployRouter( - chain.DeployerKey, - chain.Client, - weth9.Address, - armProxy.Address, - ) - return ContractDeploy[*router.Router]{ - routerAddr, routerC, tx, deployment.NewTypeAndVersion(Router, deployment.Version1_2_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy router", "err", err) - return ab, err - } - e.Logger.Infow("deployed router", "addr", routerContract) - - tokenAdminRegistry, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*token_admin_registry.TokenAdminRegistry] { - tokenAdminRegistryAddr, tx, tokenAdminRegistry, err2 := token_admin_registry.DeployTokenAdminRegistry( - chain.DeployerKey, - chain.Client) - return ContractDeploy[*token_admin_registry.TokenAdminRegistry]{ - tokenAdminRegistryAddr, tokenAdminRegistry, tx, deployment.NewTypeAndVersion(TokenAdminRegistry, deployment.Version1_5_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy token admin registry", "err", err) - return ab, err - } - e.Logger.Infow("deployed tokenAdminRegistry", "addr", tokenAdminRegistry) - - nonceManager, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*nonce_manager.NonceManager] { - nonceManagerAddr, tx, nonceManager, err2 := nonce_manager.DeployNonceManager( - chain.DeployerKey, - chain.Client, - []common.Address{}, // Need to add onRamp after - ) - return ContractDeploy[*nonce_manager.NonceManager]{ - nonceManagerAddr, nonceManager, tx, deployment.NewTypeAndVersion(NonceManager, deployment.Version1_6_0_dev), err2, - } - }) + chainAddresses, err := ab.AddressesForChain(chain.Selector) if err != nil { - e.Logger.Errorw("Failed to deploy router", "err", err) + e.Logger.Errorw("Failed to get chain addresses", "err", err) return ab, err } - - priceRegistry, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*price_registry.PriceRegistry] { - prAddr, tx, pr, err2 := price_registry.DeployPriceRegistry( - chain.DeployerKey, - chain.Client, - price_registry.PriceRegistryStaticConfig{ - MaxFeeJuelsPerMsg: big.NewInt(0).Mul(big.NewInt(2e2), big.NewInt(1e18)), - LinkToken: linkToken.Address, - StalenessThreshold: uint32(24 * 60 * 60), - }, - []common.Address{}, // ramps added after - []common.Address{weth9.Address, linkToken.Address}, // fee tokens - []price_registry.PriceRegistryTokenPriceFeedUpdate{}, - []price_registry.PriceRegistryTokenTransferFeeConfigArgs{}, // TODO: tokens - []price_registry.PriceRegistryPremiumMultiplierWeiPerEthArgs{ - { - PremiumMultiplierWeiPerEth: 9e17, // 0.9 ETH - Token: linkToken.Address, - }, - { - PremiumMultiplierWeiPerEth: 1e18, - Token: weth9.Address, - }, - }, - []price_registry.PriceRegistryDestChainConfigArgs{}, - ) - return ContractDeploy[*price_registry.PriceRegistry]{ - prAddr, pr, tx, deployment.NewTypeAndVersion(PriceRegistry, deployment.Version1_6_0_dev), err2, - } - }) + chainState, err := LoadChainState(chain, chainAddresses) if err != nil { - e.Logger.Errorw("Failed to deploy price registry", "err", err) + e.Logger.Errorw("Failed to load chain state", "err", err) return ab, err } - - onRamp, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*onramp.OnRamp] { - onRampAddr, tx, onRamp, err2 := onramp.DeployOnRamp( - chain.DeployerKey, - chain.Client, - onramp.OnRampStaticConfig{ - ChainSelector: sel, - RmnProxy: armProxy.Address, - NonceManager: nonceManager.Address, - TokenAdminRegistry: tokenAdminRegistry.Address, - }, - onramp.OnRampDynamicConfig{ - PriceRegistry: priceRegistry.Address, - FeeAggregator: common.HexToAddress("0x1"), // TODO real fee aggregator - }, - []onramp.OnRampDestChainConfigArgs{}, - ) - return ContractDeploy[*onramp.OnRamp]{ - onRampAddr, onRamp, tx, deployment.NewTypeAndVersion(OnRamp, deployment.Version1_6_0_dev), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy onramp", "err", err) - return ab, err - } - e.Logger.Infow("deployed onramp", "addr", onRamp.Address) - - offRamp, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*offramp.OffRamp] { - offRampAddr, tx, offRamp, err2 := offramp.DeployOffRamp( - chain.DeployerKey, - chain.Client, - offramp.OffRampStaticConfig{ - ChainSelector: sel, - RmnProxy: armProxy.Address, - NonceManager: nonceManager.Address, - TokenAdminRegistry: tokenAdminRegistry.Address, - }, - offramp.OffRampDynamicConfig{ - PriceRegistry: priceRegistry.Address, - PermissionLessExecutionThresholdSeconds: uint32(86400), - MaxTokenTransferGas: uint32(200_000), - MaxPoolReleaseOrMintGas: uint32(200_000), - }, - []offramp.OffRampSourceChainConfigArgs{}, - ) - return ContractDeploy[*offramp.OffRamp]{ - offRampAddr, offRamp, tx, deployment.NewTypeAndVersion(OffRamp, deployment.Version1_6_0_dev), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy offramp", "err", err) - return ab, err - } - e.Logger.Infow("deployed offramp", "addr", offRamp) - // Enable ramps on price registry/nonce manager - tx, err := priceRegistry.Contract.ApplyAuthorizedCallerUpdates(chain.DeployerKey, price_registry.AuthorizedCallersAuthorizedCallerArgs{ + tx, err := chainState.PriceRegistry.ApplyAuthorizedCallerUpdates(chain.DeployerKey, fee_quoter.AuthorizedCallersAuthorizedCallerArgs{ // TODO: We enable the deployer initially to set prices - AddedCallers: []common.Address{offRamp.Address, chain.DeployerKey.From}, + AddedCallers: []common.Address{chainState.EvmOffRampV160.Address(), chain.DeployerKey.From}, }) if err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { e.Logger.Errorw("Failed to confirm price registry authorized caller update", "err", err) return ab, err } - tx, err = nonceManager.Contract.ApplyAuthorizedCallerUpdates(chain.DeployerKey, nonce_manager.AuthorizedCallersAuthorizedCallerArgs{ - AddedCallers: []common.Address{offRamp.Address, onRamp.Address}, + tx, err = chainState.NonceManager.ApplyAuthorizedCallerUpdates(chain.DeployerKey, nonce_manager.AuthorizedCallersAuthorizedCallerArgs{ + AddedCallers: []common.Address{chainState.EvmOffRampV160.Address(), chainState.EvmOnRampV160.Address()}, }) if err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { e.Logger.Errorw("Failed to update nonce manager with ramps", "err", err) @@ -425,7 +173,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( // Add chain config for each chain. _, err = AddChainConfig(e.Logger, e.Chains[c.HomeChainSel], - c.CCIPOnChainState.CCIPConfig[c.HomeChainSel], + c.Chains[c.HomeChainSel].CCIPConfig, chain.Selector, nodes.PeerIDs(chain.Selector), uint8(len(nodes)/3)) @@ -436,9 +184,9 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( // For each chain, we create a DON on the home chain. if err := AddDON(e.Logger, cr, - c.CapabilityRegistry[c.HomeChainSel], - c.CCIPConfig[c.HomeChainSel], - offRamp.Contract, + c.Chains[c.HomeChainSel].CapabilityRegistry, + c.Chains[c.HomeChainSel].CCIPConfig, + chainState.EvmOffRampV160, chain, e.Chains[c.HomeChainSel], uint8(len(nodes)/3), @@ -454,108 +202,269 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( return ab, nil } -func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) error { - // TODO: Batch - tx, err := state.Routers[from].ApplyRampUpdates(e.Chains[from].DeployerKey, []router.RouterOnRamp{ - { - DestChainSelector: to, - OnRamp: state.EvmOnRampsV160[from].Address(), - }, - }, []router.RouterOffRamp{}, []router.RouterOffRamp{}) - if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { - return err +func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab deployment.AddressBook) (deployment.AddressBook, error) { + ccipReceiver, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver] { + receiverAddr, tx, receiver, err2 := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver( + chain.DeployerKey, + chain.Client, + false, + ) + return ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver]{ + receiverAddr, receiver, tx, deployment.NewTypeAndVersion(CCIPReceiver, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy receiver", "err", err) + return ab, err + } + e.Logger.Infow("deployed receiver", "addr", ccipReceiver.Address) + + // TODO: Still waiting for RMNRemote/RMNHome contracts etc. + mockARM, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*mock_rmn_contract.MockRMNContract] { + mockARMAddr, tx, mockARM, err2 := mock_rmn_contract.DeployMockRMNContract( + chain.DeployerKey, + chain.Client, + ) + return ContractDeploy[*mock_rmn_contract.MockRMNContract]{ + mockARMAddr, mockARM, tx, deployment.NewTypeAndVersion(MockARM, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy mockARM", "err", err) + return ab, err + } + e.Logger.Infow("deployed mockARM", "addr", mockARM) + + mcm, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*owner_helpers.ManyChainMultiSig] { + mcmAddr, tx, mcm, err2 := owner_helpers.DeployManyChainMultiSig( + chain.DeployerKey, + chain.Client, + ) + return ContractDeploy[*owner_helpers.ManyChainMultiSig]{ + mcmAddr, mcm, tx, deployment.NewTypeAndVersion(ManyChainMultisig, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy mcm", "err", err) + return ab, err } - tx, err = state.EvmOnRampsV160[from].ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, - []onramp.OnRampDestChainConfigArgs{ - { - DestChainSelector: to, - Router: state.Routers[from].Address(), - }, + // TODO: Address soon + e.Logger.Infow("deployed mcm", "addr", mcm.Address) + + _, err = deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*owner_helpers.RBACTimelock] { + timelock, tx, cc, err2 := owner_helpers.DeployRBACTimelock( + chain.DeployerKey, + chain.Client, + big.NewInt(0), // minDelay + mcm.Address, + []common.Address{mcm.Address}, // proposers + []common.Address{chain.DeployerKey.From}, //executors + []common.Address{mcm.Address}, // cancellers + []common.Address{mcm.Address}, // bypassers + ) + return ContractDeploy[*owner_helpers.RBACTimelock]{ + timelock, cc, tx, deployment.NewTypeAndVersion(RBACTimelock, deployment.Version1_0_0), err2, + } }) - if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { - return err + if err != nil { + e.Logger.Errorw("Failed to deploy timelock", "err", err) + return ab, err + } + e.Logger.Infow("deployed timelock", "addr", mcm.Address) + + rmnProxy, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*rmn_proxy_contract.RMNProxyContract] { + rmnProxyAddr, tx, rmnProxy, err2 := rmn_proxy_contract.DeployRMNProxyContract( + chain.DeployerKey, + chain.Client, + mockARM.Address, + ) + return ContractDeploy[*rmn_proxy_contract.RMNProxyContract]{ + rmnProxyAddr, rmnProxy, tx, deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy rmnProxy", "err", err) + return ab, err + } + e.Logger.Infow("deployed rmnProxy", "addr", rmnProxy.Address) + + weth9, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*weth9.WETH9] { + weth9Addr, tx, weth9c, err2 := weth9.DeployWETH9( + chain.DeployerKey, + chain.Client, + ) + return ContractDeploy[*weth9.WETH9]{ + weth9Addr, weth9c, tx, deployment.NewTypeAndVersion(WETH9, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy weth9", "err", err) + return ab, err } - _, err = state.PriceRegistries[from].UpdatePrices( - e.Chains[from].DeployerKey, price_registry.InternalPriceUpdates{ - TokenPriceUpdates: []price_registry.InternalTokenPriceUpdate{ - { - SourceToken: state.LinkTokens[from].Address(), - UsdPerToken: deployment.E18Mult(20), - }, - { - SourceToken: state.Weth9s[from].Address(), - UsdPerToken: deployment.E18Mult(4000), - }, - }, - GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ - { - DestChainSelector: to, - UsdPerUnitGas: big.NewInt(2e12), - }, - }}) - if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { - return err + linkToken, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*burn_mint_erc677.BurnMintERC677] { + linkTokenAddr, tx, linkToken, err2 := burn_mint_erc677.DeployBurnMintERC677( + chain.DeployerKey, + chain.Client, + "Link Token", + "LINK", + uint8(18), + big.NewInt(0).Mul(big.NewInt(1e9), big.NewInt(1e18)), + ) + return ContractDeploy[*burn_mint_erc677.BurnMintERC677]{ + linkTokenAddr, linkToken, tx, deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy linkToken", "err", err) + return ab, err } - // Enable dest in price registry - tx, err = state.PriceRegistries[from].ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, - []price_registry.PriceRegistryDestChainConfigArgs{ - { - DestChainSelector: to, - DestChainConfig: defaultPriceRegistryDestChainConfig(), - }, + routerContract, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*router.Router] { + routerAddr, tx, routerC, err2 := router.DeployRouter( + chain.DeployerKey, + chain.Client, + weth9.Address, + rmnProxy.Address, + ) + return ContractDeploy[*router.Router]{ + routerAddr, routerC, tx, deployment.NewTypeAndVersion(Router, deployment.Version1_2_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy router", "err", err) + return ab, err + } + e.Logger.Infow("deployed router", "addr", routerContract) + + tokenAdminRegistry, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*token_admin_registry.TokenAdminRegistry] { + tokenAdminRegistryAddr, tx, tokenAdminRegistry, err2 := token_admin_registry.DeployTokenAdminRegistry( + chain.DeployerKey, + chain.Client) + return ContractDeploy[*token_admin_registry.TokenAdminRegistry]{ + tokenAdminRegistryAddr, tokenAdminRegistry, tx, deployment.NewTypeAndVersion(TokenAdminRegistry, deployment.Version1_5_0), err2, + } }) - if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { - return err + if err != nil { + e.Logger.Errorw("Failed to deploy token admin registry", "err", err) + return ab, err + } + e.Logger.Infow("deployed tokenAdminRegistry", "addr", tokenAdminRegistry) + + nonceManager, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*nonce_manager.NonceManager] { + nonceManagerAddr, tx, nonceManager, err2 := nonce_manager.DeployNonceManager( + chain.DeployerKey, + chain.Client, + []common.Address{}, // Need to add onRamp after + ) + return ContractDeploy[*nonce_manager.NonceManager]{ + nonceManagerAddr, nonceManager, tx, deployment.NewTypeAndVersion(NonceManager, deployment.Version1_6_0_dev), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy router", "err", err) + return ab, err } - tx, err = state.EvmOffRampsV160[to].ApplySourceChainConfigUpdates(e.Chains[to].DeployerKey, - []offramp.OffRampSourceChainConfigArgs{ - { - Router: state.Routers[to].Address(), - SourceChainSelector: from, - IsEnabled: true, - OnRamp: common.LeftPadBytes(state.EvmOnRampsV160[from].Address().Bytes(), 32), - }, + feeQuoter, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*fee_quoter.FeeQuoter] { + prAddr, tx, pr, err2 := fee_quoter.DeployFeeQuoter( + chain.DeployerKey, + chain.Client, + fee_quoter.FeeQuoterStaticConfig{ + MaxFeeJuelsPerMsg: big.NewInt(0).Mul(big.NewInt(2e2), big.NewInt(1e18)), + LinkToken: linkToken.Address, + StalenessThreshold: uint32(24 * 60 * 60), + }, + []common.Address{}, // ramps added after + []common.Address{weth9.Address, linkToken.Address}, // fee tokens + []fee_quoter.FeeQuoterTokenPriceFeedUpdate{}, + []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs{}, // TODO: tokens + []fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs{ + { + PremiumMultiplierWeiPerEth: 9e17, // 0.9 ETH + Token: linkToken.Address, + }, + { + PremiumMultiplierWeiPerEth: 1e18, + Token: weth9.Address, + }, + }, + []fee_quoter.FeeQuoterDestChainConfigArgs{}, + ) + return ContractDeploy[*fee_quoter.FeeQuoter]{ + prAddr, pr, tx, deployment.NewTypeAndVersion(PriceRegistry, deployment.Version1_6_0_dev), err2, + } }) - if err := deployment.ConfirmIfNoError(e.Chains[to], tx, err); err != nil { - return err + if err != nil { + e.Logger.Errorw("Failed to deploy price registry", "err", err) + return ab, err } - tx, err = state.Routers[to].ApplyRampUpdates(e.Chains[to].DeployerKey, []router.RouterOnRamp{}, []router.RouterOffRamp{}, []router.RouterOffRamp{ - { - SourceChainSelector: from, - OffRamp: state.EvmOffRampsV160[to].Address(), - }, - }) - return deployment.ConfirmIfNoError(e.Chains[to], tx, err) -} -func defaultPriceRegistryDestChainConfig() price_registry.PriceRegistryDestChainConfig { - // https://github.com/smartcontractkit/ccip/blob/c4856b64bd766f1ddbaf5d13b42d3c4b12efde3a/contracts/src/v0.8/ccip/libraries/Internal.sol#L337-L337 - /* - ```Solidity - // bytes4(keccak256("CCIP ChainFamilySelector EVM")) - bytes4 public constant CHAIN_FAMILY_SELECTOR_EVM = 0x2812d52c; - ``` - */ - evmFamilySelector, _ := hex.DecodeString("2812d52c") - return price_registry.PriceRegistryDestChainConfig{ - IsEnabled: true, - MaxNumberOfTokensPerMsg: 10, - MaxDataBytes: 256, - MaxPerMsgGasLimit: 3_000_000, - DestGasOverhead: 50_000, - DefaultTokenFeeUSDCents: 1, - DestGasPerPayloadByte: 10, - DestDataAvailabilityOverheadGas: 0, - DestGasPerDataAvailabilityByte: 100, - DestDataAvailabilityMultiplierBps: 1, - DefaultTokenDestGasOverhead: 125_000, - DefaultTokenDestBytesOverhead: 32, - DefaultTxGasLimit: 200_000, - GasMultiplierWeiPerEth: 1, - NetworkFeeUSDCents: 1, - ChainFamilySelector: [4]byte(evmFamilySelector), + onRamp, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*onramp.OnRamp] { + onRampAddr, tx, onRamp, err2 := onramp.DeployOnRamp( + chain.DeployerKey, + chain.Client, + onramp.OnRampStaticConfig{ + ChainSelector: chain.Selector, + RmnProxy: rmnProxy.Address, + NonceManager: nonceManager.Address, + TokenAdminRegistry: tokenAdminRegistry.Address, + }, + onramp.OnRampDynamicConfig{ + FeeQuoter: feeQuoter.Address, + FeeAggregator: common.HexToAddress("0x1"), // TODO real fee aggregator + }, + []onramp.OnRampDestChainConfigArgs{}, + ) + return ContractDeploy[*onramp.OnRamp]{ + onRampAddr, onRamp, tx, deployment.NewTypeAndVersion(OnRamp, deployment.Version1_6_0_dev), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy onramp", "err", err) + return ab, err } + e.Logger.Infow("deployed onramp", "addr", onRamp.Address) + + offRamp, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*offramp.OffRamp] { + offRampAddr, tx, offRamp, err2 := offramp.DeployOffRamp( + chain.DeployerKey, + chain.Client, + offramp.OffRampStaticConfig{ + ChainSelector: chain.Selector, + RmnProxy: rmnProxy.Address, + NonceManager: nonceManager.Address, + TokenAdminRegistry: tokenAdminRegistry.Address, + }, + offramp.OffRampDynamicConfig{ + FeeQuoter: feeQuoter.Address, + PermissionLessExecutionThresholdSeconds: uint32(86400), + MaxTokenTransferGas: uint32(200_000), + MaxPoolReleaseOrMintGas: uint32(200_000), + }, + []offramp.OffRampSourceChainConfigArgs{}, + ) + return ContractDeploy[*offramp.OffRamp]{ + offRampAddr, offRamp, tx, deployment.NewTypeAndVersion(OffRamp, deployment.Version1_6_0_dev), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy offramp", "err", err) + return ab, err + } + e.Logger.Infow("deployed offramp", "addr", offRamp) + return ab, nil } diff --git a/integration-tests/deployment/ccip/state.go b/integration-tests/deployment/ccip/state.go index 1e9c904726..f641d30ed4 100644 --- a/integration-tests/deployment/ccip/state.go +++ b/integration-tests/deployment/ccip/state.go @@ -7,25 +7,49 @@ import ( "github.com/pkg/errors" chainsel "github.com/smartcontractkit/chain-selectors" + owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" - - owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" ) +type CCIPChainState struct { + EvmOnRampV160 *onramp.OnRamp + EvmOffRampV160 *offramp.OffRamp + PriceRegistry *fee_quoter.FeeQuoter + ArmProxy *rmn_proxy_contract.RMNProxyContract + NonceManager *nonce_manager.NonceManager + TokenAdminRegistry *token_admin_registry.TokenAdminRegistry + Router *router.Router + Weth9 *weth9.WETH9 + MockRmn *mock_rmn_contract.MockRMNContract + // TODO: May need to support older link too + LinkToken *burn_mint_erc677.BurnMintERC677 + // Note we only expect one of these (on the home chain) + CapabilityRegistry *capabilities_registry.CapabilitiesRegistry + CCIPConfig *ccip_config.CCIPConfig + Mcm *owner_wrappers.ManyChainMultiSig + // TODO: remove once we have Address() on wrappers + McmsAddr common.Address + Timelock *owner_wrappers.RBACTimelock + + // Test contracts + Receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver +} + // Onchain state always derivable from an address book. // Offchain state always derivable from a list of nodeIds. // Note can translate this into Go struct needed for MCMS/Docs/UI. @@ -33,27 +57,7 @@ type CCIPOnChainState struct { // Populated go bindings for the appropriate version for all contracts. // We would hold 2 versions of each contract here. Once we upgrade we can phase out the old one. // When generating bindings, make sure the package name corresponds to the version. - EvmOnRampsV160 map[uint64]*onramp.OnRamp - EvmOffRampsV160 map[uint64]*offramp.OffRamp - PriceRegistries map[uint64]*price_registry.PriceRegistry - ArmProxies map[uint64]*rmn_proxy_contract.RMNProxyContract - NonceManagers map[uint64]*nonce_manager.NonceManager - TokenAdminRegistries map[uint64]*token_admin_registry.TokenAdminRegistry - Routers map[uint64]*router.Router - Weth9s map[uint64]*weth9.WETH9 - MockArms map[uint64]*mock_rmn_contract.MockRMNContract - // TODO: May need to support older link too - LinkTokens map[uint64]*burn_mint_erc677.BurnMintERC677 - // Note we only expect one of these (on the home chain) - CapabilityRegistry map[uint64]*capabilities_registry.CapabilitiesRegistry - CCIPConfig map[uint64]*ccip_config.CCIPConfig - Mcms map[uint64]*owner_wrappers.ManyChainMultiSig - // TODO: remove once we have Address() on wrappers - McmsAddrs map[uint64]common.Address - Timelocks map[uint64]*owner_wrappers.RBACTimelock - - // Test contracts - Receivers map[uint64]*maybe_revert_message_receiver.MaybeRevertMessageReceiver + Chains map[uint64]CCIPChainState } type CCIPSnapShot struct { @@ -95,8 +99,12 @@ func (s CCIPOnChainState) Snapshot(chains []uint64) (CCIPSnapShot, error) { if err != nil { return snapshot, err } + if _, ok := s.Chains[chainSelector]; !ok { + return snapshot, fmt.Errorf("chain not supported %d", chainSelector) + } var c Chain - if ta, ok := s.TokenAdminRegistries[chainSelector]; ok { + ta := s.Chains[chainSelector].TokenAdminRegistry + if ta != nil { tokens, err := ta.GetAllConfiguredTokens(nil, 0, 10) if err != nil { return snapshot, err @@ -113,7 +121,8 @@ func (s CCIPOnChainState) Snapshot(chains []uint64) (CCIPSnapShot, error) { Tokens: tokens, } } - if nm, ok := s.NonceManagers[chainSelector]; ok { + nm := s.Chains[chainSelector].NonceManager + if nm != nil { authorizedCallers, err := nm.GetAllAuthorizedCallers(nil) if err != nil { return snapshot, err @@ -137,134 +146,130 @@ func (s CCIPOnChainState) Snapshot(chains []uint64) (CCIPSnapShot, error) { } func SnapshotState(e deployment.Environment, ab deployment.AddressBook) (CCIPSnapShot, error) { - state, err := GenerateOnchainState(e, ab) + state, err := LoadOnchainState(e, ab) if err != nil { return CCIPSnapShot{}, err } return state.Snapshot(e.AllChainSelectors()) } -func GenerateOnchainState(e deployment.Environment, ab deployment.AddressBook) (CCIPOnChainState, error) { +func LoadOnchainState(e deployment.Environment, ab deployment.AddressBook) (CCIPOnChainState, error) { state := CCIPOnChainState{ - EvmOnRampsV160: make(map[uint64]*onramp.OnRamp), - EvmOffRampsV160: make(map[uint64]*offramp.OffRamp), - PriceRegistries: make(map[uint64]*price_registry.PriceRegistry), - ArmProxies: make(map[uint64]*rmn_proxy_contract.RMNProxyContract), - NonceManagers: make(map[uint64]*nonce_manager.NonceManager), - TokenAdminRegistries: make(map[uint64]*token_admin_registry.TokenAdminRegistry), - Routers: make(map[uint64]*router.Router), - MockArms: make(map[uint64]*mock_rmn_contract.MockRMNContract), - LinkTokens: make(map[uint64]*burn_mint_erc677.BurnMintERC677), - Weth9s: make(map[uint64]*weth9.WETH9), - Mcms: make(map[uint64]*owner_wrappers.ManyChainMultiSig), - McmsAddrs: make(map[uint64]common.Address), - Timelocks: make(map[uint64]*owner_wrappers.RBACTimelock), - CapabilityRegistry: make(map[uint64]*capabilities_registry.CapabilitiesRegistry), - CCIPConfig: make(map[uint64]*ccip_config.CCIPConfig), - Receivers: make(map[uint64]*maybe_revert_message_receiver.MaybeRevertMessageReceiver), + Chains: make(map[uint64]CCIPChainState), } - // Get all the onchain state addresses, err := ab.Addresses() if err != nil { return state, errors.Wrap(err, "could not get addresses") } for chainSelector, addresses := range addresses { - for address, tvStr := range addresses { - switch tvStr.String() { - case deployment.NewTypeAndVersion(RBACTimelock, deployment.Version1_0_0).String(): - tl, err := owner_wrappers.NewRBACTimelock(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.Timelocks[chainSelector] = tl - case deployment.NewTypeAndVersion(ManyChainMultisig, deployment.Version1_0_0).String(): - mcms, err := owner_wrappers.NewManyChainMultiSig(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.Mcms[chainSelector] = mcms - state.McmsAddrs[chainSelector] = common.HexToAddress(address) - case deployment.NewTypeAndVersion(CapabilitiesRegistry, deployment.Version1_0_0).String(): - cr, err := capabilities_registry.NewCapabilitiesRegistry(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.CapabilityRegistry[chainSelector] = cr - case deployment.NewTypeAndVersion(OnRamp, deployment.Version1_6_0_dev).String(): - onRamp, err := onramp.NewOnRamp(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.EvmOnRampsV160[chainSelector] = onRamp - case deployment.NewTypeAndVersion(OffRamp, deployment.Version1_6_0_dev).String(): - offRamp, err := offramp.NewOffRamp(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.EvmOffRampsV160[chainSelector] = offRamp - case deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0).String(): - armProxy, err := rmn_proxy_contract.NewRMNProxyContract(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.ArmProxies[chainSelector] = armProxy - case deployment.NewTypeAndVersion(MockARM, deployment.Version1_0_0).String(): - mockARM, err := mock_rmn_contract.NewMockRMNContract(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.MockArms[chainSelector] = mockARM - case deployment.NewTypeAndVersion(WETH9, deployment.Version1_0_0).String(): - weth9, err := weth9.NewWETH9(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.Weth9s[chainSelector] = weth9 - case deployment.NewTypeAndVersion(NonceManager, deployment.Version1_6_0_dev).String(): - nm, err := nonce_manager.NewNonceManager(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.NonceManagers[chainSelector] = nm - case deployment.NewTypeAndVersion(TokenAdminRegistry, deployment.Version1_5_0).String(): - tm, err := token_admin_registry.NewTokenAdminRegistry(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.TokenAdminRegistries[chainSelector] = tm - case deployment.NewTypeAndVersion(Router, deployment.Version1_2_0).String(): - r, err := router.NewRouter(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.Routers[chainSelector] = r - case deployment.NewTypeAndVersion(PriceRegistry, deployment.Version1_6_0_dev).String(): - pr, err := price_registry.NewPriceRegistry(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.PriceRegistries[chainSelector] = pr - case deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0).String(): - lt, err := burn_mint_erc677.NewBurnMintERC677(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.LinkTokens[chainSelector] = lt - case deployment.NewTypeAndVersion(CCIPConfig, deployment.Version1_6_0_dev).String(): - cc, err := ccip_config.NewCCIPConfig(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.CCIPConfig[chainSelector] = cc - case deployment.NewTypeAndVersion(CCIPReceiver, deployment.Version1_0_0).String(): - mr, err := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(common.HexToAddress(address), e.Chains[chainSelector].Client) - if err != nil { - return state, err - } - state.Receivers[chainSelector] = mr - default: - return state, fmt.Errorf("unknown contract %s", tvStr) + chainState, err := LoadChainState(e.Chains[chainSelector], addresses) + if err != nil { + return state, err + } + state.Chains[chainSelector] = chainState + } + return state, nil +} + +// Loads all state for a chain into state +// Modifies map in place +func LoadChainState(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (CCIPChainState, error) { + var state CCIPChainState + for address, tvStr := range addresses { + switch tvStr.String() { + case deployment.NewTypeAndVersion(RBACTimelock, deployment.Version1_0_0).String(): + tl, err := owner_wrappers.NewRBACTimelock(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.Timelock = tl + case deployment.NewTypeAndVersion(ManyChainMultisig, deployment.Version1_0_0).String(): + mcms, err := owner_wrappers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.Mcm = mcms + state.McmsAddr = common.HexToAddress(address) + case deployment.NewTypeAndVersion(CapabilitiesRegistry, deployment.Version1_0_0).String(): + cr, err := capabilities_registry.NewCapabilitiesRegistry(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.CapabilityRegistry = cr + case deployment.NewTypeAndVersion(OnRamp, deployment.Version1_6_0_dev).String(): + onRampC, err := onramp.NewOnRamp(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.EvmOnRampV160 = onRampC + case deployment.NewTypeAndVersion(OffRamp, deployment.Version1_6_0_dev).String(): + offRamp, err := offramp.NewOffRamp(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.EvmOffRampV160 = offRamp + case deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0).String(): + armProxy, err := rmn_proxy_contract.NewRMNProxyContract(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.ArmProxy = armProxy + case deployment.NewTypeAndVersion(MockARM, deployment.Version1_0_0).String(): + mockARM, err := mock_rmn_contract.NewMockRMNContract(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.MockRmn = mockARM + case deployment.NewTypeAndVersion(WETH9, deployment.Version1_0_0).String(): + weth9, err := weth9.NewWETH9(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.Weth9 = weth9 + case deployment.NewTypeAndVersion(NonceManager, deployment.Version1_6_0_dev).String(): + nm, err := nonce_manager.NewNonceManager(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.NonceManager = nm + case deployment.NewTypeAndVersion(TokenAdminRegistry, deployment.Version1_5_0).String(): + tm, err := token_admin_registry.NewTokenAdminRegistry(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.TokenAdminRegistry = tm + case deployment.NewTypeAndVersion(Router, deployment.Version1_2_0).String(): + r, err := router.NewRouter(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.Router = r + case deployment.NewTypeAndVersion(PriceRegistry, deployment.Version1_6_0_dev).String(): + pr, err := fee_quoter.NewFeeQuoter(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.PriceRegistry = pr + case deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0).String(): + lt, err := burn_mint_erc677.NewBurnMintERC677(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.LinkToken = lt + case deployment.NewTypeAndVersion(CCIPConfig, deployment.Version1_6_0_dev).String(): + cc, err := ccip_config.NewCCIPConfig(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.CCIPConfig = cc + case deployment.NewTypeAndVersion(CCIPReceiver, deployment.Version1_0_0).String(): + mr, err := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err } + state.Receiver = mr + default: + return state, fmt.Errorf("unknown contract %s", tvStr) } } return state, nil From 1b5a5a24ef5f6893e362c446e77c8417efef02b3 Mon Sep 17 00:00:00 2001 From: Makram Date: Tue, 27 Aug 2024 20:44:05 +0300 Subject: [PATCH 230/432] core/capabilities/ccip: update ccipreader test (#1373) We want to add a test for GetExpectedNextSequenceNumber in ccipreader_test.go Related PR: https://github.com/smartcontractkit/chainlink-ccip/pull/81 Add a test for GetExpectedNextSequenceNumber in ccipreader_test.go --- .../ccip/test/helpers/CCIPReaderTester.sol | 15 +++++++ .../ccipreader/ccipreader_test.go | 36 ++++++++++++++++ .../ccip_reader_tester/ccip_reader_tester.go | 42 ++++++++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 12 ++++-- integration-tests/go.sum | 32 +++++++++++--- integration-tests/load/go.mod | 7 ++-- integration-tests/load/go.sum | 14 ++++--- 12 files changed, 145 insertions(+), 27 deletions(-) diff --git a/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol b/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol index 707d38ddf2..c2acddc796 100644 --- a/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol +++ b/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol @@ -8,6 +8,21 @@ contract CCIPReaderTester { event CCIPSendRequested(uint64 indexed destChainSelector, Internal.EVM2AnyRampMessage message); mapping(uint64 sourceChainSelector => OffRamp.SourceChainConfig sourceChainConfig) internal s_sourceChainConfigs; + mapping(uint64 destChainSelector => uint64 sequenceNumber) internal s_destChainSeqNrs; + + /// @notice Gets the next sequence number to be used in the onRamp + /// @param destChainSelector The destination chain selector + /// @return nextSequenceNumber The next sequence number to be used + function getExpectedNextSequenceNumber(uint64 destChainSelector) external view returns (uint64) { + return s_destChainSeqNrs[destChainSelector] + 1; + } + + /// @notice Sets the sequence number in the onRamp + /// @param destChainSelector The destination chain selector + /// @param sequenceNumber The sequence number + function setDestChainSeqNr(uint64 destChainSelector, uint64 sequenceNumber) external { + s_destChainSeqNrs[destChainSelector] = sequenceNumber; + } function getSourceChainConfig(uint64 sourceChainSelector) external view returns (OffRamp.SourceChainConfig memory) { return s_sourceChainConfigs[sourceChainSelector]; diff --git a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go index a179949d93..ed5fe1aedb 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go @@ -316,6 +316,42 @@ func TestCCIPReader_NextSeqNum(t *testing.T) { assert.Equal(t, cciptypes.SeqNum(30), seqNums[2]) } +func TestCCIPReader_GetExpectedNextSequenceNumber(t *testing.T) { + ctx := testutils.Context(t) + + cfg := evmtypes.ChainReaderConfig{ + Contracts: map[string]evmtypes.ChainContractReader{ + consts.ContractNameOnRamp: { + ContractABI: ccip_reader_tester.CCIPReaderTesterABI, + Configs: map[string]*evmtypes.ChainReaderDefinition{ + consts.MethodNameGetExpectedNextSequenceNumber: { + ChainSpecificName: "getExpectedNextSequenceNumber", + ReadType: evmtypes.Method, + }, + }, + }, + }, + } + + s := testSetup(ctx, t, chainS1, chainD, nil, cfg) + + _, err := s.contract.SetDestChainSeqNr(s.auth, uint64(chainD), 10) + require.NoError(t, err) + s.sb.Commit() + + seqNum, err := s.reader.GetExpectedNextSequenceNumber(ctx, chainS1, chainD) + require.NoError(t, err) + require.Equal(t, cciptypes.SeqNum(10)+1, seqNum) + + _, err = s.contract.SetDestChainSeqNr(s.auth, uint64(chainD), 25) + require.NoError(t, err) + s.sb.Commit() + + seqNum, err = s.reader.GetExpectedNextSequenceNumber(ctx, chainS1, chainD) + require.NoError(t, err) + require.Equal(t, cciptypes.SeqNum(25)+1, seqNum) +} + func testSetup(ctx context.Context, t *testing.T, readerChain, destChain cciptypes.ChainSelector, onChainSeqNums map[cciptypes.ChainSelector]cciptypes.SeqNum, cfg evmtypes.ChainReaderConfig) *testSetupData { const chainID = 1337 diff --git a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go index 915a045c10..cce56e0d80 100644 --- a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go +++ b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go @@ -96,8 +96,8 @@ type OffRampSourceChainConfig struct { } var CCIPReaderTesterMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPSendRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061118d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80634cf66e361461005c57806385096da914610071578063e44302b714610084578063e83eabba14610097578063e9d68a8e146100aa575b600080fd5b61006f61006a3660046104c9565b6100d3565b005b61006f61007f366004610741565b610128565b61006f6100923660046109df565b61016d565b61006f6100a5366004610b49565b6101a7565b6100bd6100b8366004610c04565b610233565b6040516100ca9190610c6c565b60405180910390f35b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051610119929190610cc4565b60405180910390a45050505050565b816001600160401b03167fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140826040516101619190610dc7565b60405180910390a25050565b7f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161019c9190610f81565b60405180910390a150565b6001600160401b0380831660009081526020818152604091829020845181549286015193860151909416600160a81b02600160a81b600160e81b0319931515600160a01b026001600160a81b03199093166001600160a01b039095169490941791909117919091169190911781556060820151829190600182019061022c90826110c1565b5050505050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b038781168452838352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b9092049092169483019490945260018401805493949293918401916102be90611036565b80601f01602080910402602001604051908101604052809291908181526020018280546102ea90611036565b80156103375780601f1061030c57610100808354040283529160200191610337565b820191906000526020600020905b81548152906001019060200180831161031a57829003601f168201915b5050505050815250509050919050565b80356001600160401b038116811461035e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b038111828210171561039b5761039b610363565b60405290565b60405161010081016001600160401b038111828210171561039b5761039b610363565b604080519081016001600160401b038111828210171561039b5761039b610363565b604051606081016001600160401b038111828210171561039b5761039b610363565b604051608081016001600160401b038111828210171561039b5761039b610363565b604051601f8201601f191681016001600160401b038111828210171561045257610452610363565b604052919050565b600082601f83011261046b57600080fd5b81356001600160401b0381111561048457610484610363565b610497601f8201601f191660200161042a565b8181528460208386010111156104ac57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a086880312156104e157600080fd5b6104ea86610347565b94506104f860208701610347565b93506040860135925060608601356004811061051357600080fd5b915060808601356001600160401b0381111561052e57600080fd5b61053a8882890161045a565b9150509295509295909350565b600060a0828403121561055957600080fd5b610561610379565b90508135815261057360208301610347565b602082015261058460408301610347565b604082015261059560608301610347565b60608201526105a660808301610347565b608082015292915050565b6001600160a01b03811681146105c657600080fd5b50565b803561035e816105b1565b60006001600160401b038211156105ed576105ed610363565b5060051b60200190565b600082601f83011261060857600080fd5b8135602061061d610618836105d4565b61042a565b82815260059290921b8401810191818101908684111561063c57600080fd5b8286015b848110156107365780356001600160401b03808211156106605760008081fd5b9088019060a0828b03601f190181131561067a5760008081fd5b610682610379565b87840135838111156106945760008081fd5b6106a28d8a8388010161045a565b825250604080850135848111156106b95760008081fd5b6106c78e8b8389010161045a565b8a84015250606080860135858111156106e05760008081fd5b6106ee8f8c838a010161045a565b838501525060809150818601358184015250828501359250838311156107145760008081fd5b6107228d8a8588010161045a565b908201528652505050918301918301610640565b509695505050505050565b6000806040838503121561075457600080fd5b61075d83610347565b915060208301356001600160401b038082111561077957600080fd5b90840190610180828703121561078e57600080fd5b6107966103a1565b6107a08784610547565b81526107ae60a084016105c9565b602082015260c0830135828111156107c557600080fd5b6107d18882860161045a565b60408301525060e0830135828111156107e957600080fd5b6107f58882860161045a565b6060830152506101008301358281111561080e57600080fd5b61081a8882860161045a565b60808301525061082d61012084016105c9565b60a082015261014083013560c08201526101608301358281111561085057600080fd5b61085c888286016105f7565b60e0830152508093505050509250929050565b80356001600160e01b038116811461035e57600080fd5b600082601f83011261089757600080fd5b813560206108a7610618836105d4565b82815260069290921b840181019181810190868411156108c657600080fd5b8286015b8481101561073657604081890312156108e35760008081fd5b6108eb6103c4565b6108f482610347565b815261090185830161086f565b818601528352918301916040016108ca565b600082601f83011261092457600080fd5b81356020610934610618836105d4565b82815260079290921b8401810191818101908684111561095357600080fd5b8286015b848110156107365780880360808112156109715760008081fd5b6109796103e6565b61098283610347565b8152604080601f19840112156109985760008081fd5b6109a06103c4565b92506109ad878501610347565b83526109ba818501610347565b8388015281870192909252606083013591810191909152835291830191608001610957565b600060208083850312156109f257600080fd5b82356001600160401b0380821115610a0957600080fd5b81850191506040808388031215610a1f57600080fd5b610a276103c4565b833583811115610a3657600080fd5b84016040818a031215610a4857600080fd5b610a506103c4565b813585811115610a5f57600080fd5b8201601f81018b13610a7057600080fd5b8035610a7e610618826105d4565b81815260069190911b8201890190898101908d831115610a9d57600080fd5b928a01925b82841015610aed5787848f031215610aba5760008081fd5b610ac26103c4565b8435610acd816105b1565b8152610ada858d0161086f565b818d0152825292870192908a0190610aa2565b845250505081870135935084841115610b0557600080fd5b610b118a858401610886565b8188015282525083850135915082821115610b2b57600080fd5b610b3788838601610913565b85820152809550505050505092915050565b60008060408385031215610b5c57600080fd5b610b6583610347565b915060208301356001600160401b0380821115610b8157600080fd5b9084019060808287031215610b9557600080fd5b610b9d610408565b8235610ba8816105b1565b815260208301358015158114610bbd57600080fd5b6020820152610bce60408401610347565b6040820152606083013582811115610be557600080fd5b610bf18882860161045a565b6060830152508093505050509250929050565b600060208284031215610c1657600080fd5b610c1f82610347565b9392505050565b6000815180845260005b81811015610c4c57602081850181015186830182015201610c30565b506000602082860101526020601f19601f83011685010191505092915050565b602080825282516001600160a01b03168282015282015115156040808301919091528201516001600160401b0316606080830191909152820151608080830152600090610cbc60a0840182610c26565b949350505050565b600060048410610ce457634e487b7160e01b600052602160045260246000fd5b83825260406020830152610cbc6040830184610c26565b6001600160a01b03169052565b600082825180855260208086019550808260051b84010181860160005b84811015610dba57601f19868403018952815160a08151818652610d4b82870182610c26565b9150508582015185820387870152610d638282610c26565b91505060408083015186830382880152610d7d8382610c26565b92505050606080830151818701525060808083015192508582038187015250610da68183610c26565b9a86019a9450505090830190600101610d25565b5090979650505050505050565b60208152610e14602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b60006020830151610e2860c0840182610cfb565b5060408301516101808060e0850152610e456101a0850183610c26565b91506060850151601f198086850301610100870152610e648483610c26565b9350608087015191508086850301610120870152610e828483610c26565b935060a08701519150610e99610140870183610cfb565b60c087015161016087015260e0870151915080868503018387015250610ebf8382610d08565b9695505050505050565b60008151808452602080850194506020840160005b83811015610f1757815180516001600160401b031688528301516001600160e01b03168388015260409096019590820190600101610ede565b509495945050505050565b600081518084526020808501945080840160005b83811015610f1757815180516001600160401b0390811689528482015180518216868b0152850151166040898101919091520151606088015260809096019590820190600101610f36565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b80831015610fef57835180516001600160a01b031683528701516001600160e01b031687830152928601926001929092019190840190610fb4565b5093850151878503605f190160808901529361100b8186610ec9565b945050505050818501519150601f1984820301604085015261102d8183610f22565b95945050505050565b600181811c9082168061104a57607f821691505b60208210810361106a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156110bc576000816000526020600020601f850160051c810160208610156110995750805b601f850160051c820191505b818110156110b8578281556001016110a5565b5050505b505050565b81516001600160401b038111156110da576110da610363565b6110ee816110e88454611036565b84611070565b602080601f831160018114611123576000841561110b5750858301515b600019600386901b1c1916600185901b1785556110b8565b600085815260208120601f198616915b8281101561115257888601518255948401946001909101908401611133565b50858210156111705787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPSendRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"setDestChainSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061129d806100206000396000f3fe608060405234801561001057600080fd5b506004361061006d5760003560e01c80634cf66e361461007257806385096da9146100875780639041be3d1461009a578063c1a5a355146100ca578063e44302b714610106578063e83eabba14610119578063e9d68a8e1461012c575b600080fd5b610085610080366004610571565b61014c565b005b6100856100953660046107e9565b6101a1565b6100ad6100a8366004610917565b6101e6565b6040516001600160401b0390911681526020015b60405180910390f35b6100856100d8366004610939565b6001600160401b03918216600090815260016020526040902080546001600160401b03191691909216179055565b610085610114366004610adc565b610215565b610085610127366004610c46565b61024f565b61013f61013a366004610917565b6102db565b6040516100c19190610d47565b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051610192929190610d9f565b60405180910390a45050505050565b816001600160401b03167fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140826040516101da9190610ea2565b60405180910390a25050565b6001600160401b038082166000908152600160208190526040822054919261020f921690610fa4565b92915050565b7f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d816040516102449190611091565b60405180910390a150565b6001600160401b0380831660009081526020818152604091829020845181549286015193860151909416600160a81b02600160a81b600160e81b0319931515600160a01b026001600160a81b03199093166001600160a01b03909516949094179190911791909116919091178155606082015182919060018201906102d490826111d1565b5050505050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b038781168452838352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b90920490921694830194909452600184018054939492939184019161036690611146565b80601f016020809104026020016040519081016040528092919081815260200182805461039290611146565b80156103df5780601f106103b4576101008083540402835291602001916103df565b820191906000526020600020905b8154815290600101906020018083116103c257829003601f168201915b5050505050815250509050919050565b80356001600160401b038116811461040657600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156104435761044361040b565b60405290565b60405161010081016001600160401b03811182821017156104435761044361040b565b604080519081016001600160401b03811182821017156104435761044361040b565b604051606081016001600160401b03811182821017156104435761044361040b565b604051608081016001600160401b03811182821017156104435761044361040b565b604051601f8201601f191681016001600160401b03811182821017156104fa576104fa61040b565b604052919050565b600082601f83011261051357600080fd5b81356001600160401b0381111561052c5761052c61040b565b61053f601f8201601f19166020016104d2565b81815284602083860101111561055457600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561058957600080fd5b610592866103ef565b94506105a0602087016103ef565b9350604086013592506060860135600481106105bb57600080fd5b915060808601356001600160401b038111156105d657600080fd5b6105e288828901610502565b9150509295509295909350565b600060a0828403121561060157600080fd5b610609610421565b90508135815261061b602083016103ef565b602082015261062c604083016103ef565b604082015261063d606083016103ef565b606082015261064e608083016103ef565b608082015292915050565b6001600160a01b038116811461066e57600080fd5b50565b803561040681610659565b60006001600160401b038211156106955761069561040b565b5060051b60200190565b600082601f8301126106b057600080fd5b813560206106c56106c08361067c565b6104d2565b82815260059290921b840181019181810190868411156106e457600080fd5b8286015b848110156107de5780356001600160401b03808211156107085760008081fd5b9088019060a0828b03601f19018113156107225760008081fd5b61072a610421565b878401358381111561073c5760008081fd5b61074a8d8a83880101610502565b825250604080850135848111156107615760008081fd5b61076f8e8b83890101610502565b8a84015250606080860135858111156107885760008081fd5b6107968f8c838a0101610502565b838501525060809150818601358184015250828501359250838311156107bc5760008081fd5b6107ca8d8a85880101610502565b9082015286525050509183019183016106e8565b509695505050505050565b600080604083850312156107fc57600080fd5b610805836103ef565b915060208301356001600160401b038082111561082157600080fd5b90840190610180828703121561083657600080fd5b61083e610449565b61084887846105ef565b815261085660a08401610671565b602082015260c08301358281111561086d57600080fd5b61087988828601610502565b60408301525060e08301358281111561089157600080fd5b61089d88828601610502565b606083015250610100830135828111156108b657600080fd5b6108c288828601610502565b6080830152506108d56101208401610671565b60a082015261014083013560c0820152610160830135828111156108f857600080fd5b6109048882860161069f565b60e0830152508093505050509250929050565b60006020828403121561092957600080fd5b610932826103ef565b9392505050565b6000806040838503121561094c57600080fd5b610955836103ef565b9150610963602084016103ef565b90509250929050565b80356001600160e01b038116811461040657600080fd5b600082601f83011261099457600080fd5b813560206109a46106c08361067c565b82815260069290921b840181019181810190868411156109c357600080fd5b8286015b848110156107de57604081890312156109e05760008081fd5b6109e861046c565b6109f1826103ef565b81526109fe85830161096c565b818601528352918301916040016109c7565b600082601f830112610a2157600080fd5b81356020610a316106c08361067c565b82815260079290921b84018101918181019086841115610a5057600080fd5b8286015b848110156107de578088036080811215610a6e5760008081fd5b610a7661048e565b610a7f836103ef565b8152604080601f1984011215610a955760008081fd5b610a9d61046c565b9250610aaa8785016103ef565b8352610ab78185016103ef565b8388015281870192909252606083013591810191909152835291830191608001610a54565b60006020808385031215610aef57600080fd5b82356001600160401b0380821115610b0657600080fd5b81850191506040808388031215610b1c57600080fd5b610b2461046c565b833583811115610b3357600080fd5b84016040818a031215610b4557600080fd5b610b4d61046c565b813585811115610b5c57600080fd5b8201601f81018b13610b6d57600080fd5b8035610b7b6106c08261067c565b81815260069190911b8201890190898101908d831115610b9a57600080fd5b928a01925b82841015610bea5787848f031215610bb75760008081fd5b610bbf61046c565b8435610bca81610659565b8152610bd7858d0161096c565b818d0152825292870192908a0190610b9f565b845250505081870135935084841115610c0257600080fd5b610c0e8a858401610983565b8188015282525083850135915082821115610c2857600080fd5b610c3488838601610a10565b85820152809550505050505092915050565b60008060408385031215610c5957600080fd5b610c62836103ef565b915060208301356001600160401b0380821115610c7e57600080fd5b9084019060808287031215610c9257600080fd5b610c9a6104b0565b8235610ca581610659565b815260208301358015158114610cba57600080fd5b6020820152610ccb604084016103ef565b6040820152606083013582811115610ce257600080fd5b610cee88828601610502565b6060830152508093505050509250929050565b6000815180845260005b81811015610d2757602081850181015186830182015201610d0b565b506000602082860101526020601f19601f83011685010191505092915050565b602080825282516001600160a01b03168282015282015115156040808301919091528201516001600160401b0316606080830191909152820151608080830152600090610d9760a0840182610d01565b949350505050565b600060048410610dbf57634e487b7160e01b600052602160045260246000fd5b83825260406020830152610d976040830184610d01565b6001600160a01b03169052565b600082825180855260208086019550808260051b84010181860160005b84811015610e9557601f19868403018952815160a08151818652610e2682870182610d01565b9150508582015185820387870152610e3e8282610d01565b91505060408083015186830382880152610e588382610d01565b92505050606080830151818701525060808083015192508582038187015250610e818183610d01565b9a86019a9450505090830190600101610e00565b5090979650505050505050565b60208152610eef602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b60006020830151610f0360c0840182610dd6565b5060408301516101808060e0850152610f206101a0850183610d01565b91506060850151601f198086850301610100870152610f3f8483610d01565b9350608087015191508086850301610120870152610f5d8483610d01565b935060a08701519150610f74610140870183610dd6565b60c087015161016087015260e0870151915080868503018387015250610f9a8382610de3565b9695505050505050565b6001600160401b03818116838216019080821115610fd257634e487b7160e01b600052601160045260246000fd5b5092915050565b60008151808452602080850194506020840160005b8381101561102757815180516001600160401b031688528301516001600160e01b03168388015260409096019590820190600101610fee565b509495945050505050565b600081518084526020808501945080840160005b8381101561102757815180516001600160401b0390811689528482015180518216868b0152850151166040898101919091520151606088015260809096019590820190600101611046565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b808310156110ff57835180516001600160a01b031683528701516001600160e01b0316878301529286019260019290920191908401906110c4565b5093850151878503605f190160808901529361111b8186610fd9565b945050505050818501519150601f1984820301604085015261113d8183611032565b95945050505050565b600181811c9082168061115a57607f821691505b60208210810361117a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156111cc576000816000526020600020601f850160051c810160208610156111a95750805b601f850160051c820191505b818110156111c8578281556001016111b5565b5050505b505050565b81516001600160401b038111156111ea576111ea61040b565b6111fe816111f88454611146565b84611180565b602080601f831160018114611233576000841561121b5750858301515b600019600386901b1c1916600185901b1785556111c8565b600085815260208120601f198616915b8281101561126257888601518255948401946001909101908401611243565b50858210156112805787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", } var CCIPReaderTesterABI = CCIPReaderTesterMetaData.ABI @@ -236,6 +236,28 @@ func (_CCIPReaderTester *CCIPReaderTesterTransactorRaw) Transact(opts *bind.Tran return _CCIPReaderTester.Contract.contract.Transact(opts, method, params...) } +func (_CCIPReaderTester *CCIPReaderTesterCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts, destChainSelector uint64) (uint64, error) { + var out []interface{} + err := _CCIPReaderTester.contract.Call(opts, &out, "getExpectedNextSequenceNumber", destChainSelector) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CCIPReaderTester *CCIPReaderTesterSession) GetExpectedNextSequenceNumber(destChainSelector uint64) (uint64, error) { + return _CCIPReaderTester.Contract.GetExpectedNextSequenceNumber(&_CCIPReaderTester.CallOpts, destChainSelector) +} + +func (_CCIPReaderTester *CCIPReaderTesterCallerSession) GetExpectedNextSequenceNumber(destChainSelector uint64) (uint64, error) { + return _CCIPReaderTester.Contract.GetExpectedNextSequenceNumber(&_CCIPReaderTester.CallOpts, destChainSelector) +} + func (_CCIPReaderTester *CCIPReaderTesterCaller) GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (OffRampSourceChainConfig, error) { var out []interface{} err := _CCIPReaderTester.contract.Call(opts, &out, "getSourceChainConfig", sourceChainSelector) @@ -294,6 +316,18 @@ func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) EmitExecutionStateCh return _CCIPReaderTester.Contract.EmitExecutionStateChanged(&_CCIPReaderTester.TransactOpts, sourceChainSelector, sequenceNumber, messageId, state, returnData) } +func (_CCIPReaderTester *CCIPReaderTesterTransactor) SetDestChainSeqNr(opts *bind.TransactOpts, destChainSelector uint64, sequenceNumber uint64) (*types.Transaction, error) { + return _CCIPReaderTester.contract.Transact(opts, "setDestChainSeqNr", destChainSelector, sequenceNumber) +} + +func (_CCIPReaderTester *CCIPReaderTesterSession) SetDestChainSeqNr(destChainSelector uint64, sequenceNumber uint64) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.SetDestChainSeqNr(&_CCIPReaderTester.TransactOpts, destChainSelector, sequenceNumber) +} + +func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) SetDestChainSeqNr(destChainSelector uint64, sequenceNumber uint64) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.SetDestChainSeqNr(&_CCIPReaderTester.TransactOpts, destChainSelector, sequenceNumber) +} + func (_CCIPReaderTester *CCIPReaderTesterTransactor) SetSourceChainConfig(opts *bind.TransactOpts, sourceChainSelector uint64, sourceChainConfig OffRampSourceChainConfig) (*types.Transaction, error) { return _CCIPReaderTester.contract.Transact(opts, "setSourceChainConfig", sourceChainSelector, sourceChainConfig) } @@ -729,6 +763,8 @@ func (_CCIPReaderTester *CCIPReaderTester) Address() common.Address { } type CCIPReaderTesterInterface interface { + GetExpectedNextSequenceNumber(opts *bind.CallOpts, destChainSelector uint64) (uint64, error) + GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (OffRampSourceChainConfig, error) EmitCCIPSendRequested(opts *bind.TransactOpts, destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) @@ -737,6 +773,8 @@ type CCIPReaderTesterInterface interface { EmitExecutionStateChanged(opts *bind.TransactOpts, sourceChainSelector uint64, sequenceNumber uint64, messageId [32]byte, state uint8, returnData []byte) (*types.Transaction, error) + SetDestChainSeqNr(opts *bind.TransactOpts, destChainSelector uint64, sequenceNumber uint64) (*types.Transaction, error) + SetSourceChainConfig(opts *bind.TransactOpts, sourceChainSelector uint64, sourceChainConfig OffRampSourceChainConfig) (*types.Transaction, error) FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*CCIPReaderTesterCCIPSendRequestedIterator, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 9fd0ac9e8d..98fb5dd620 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -5,7 +5,7 @@ burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoo burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6333d0314d0bd29e75ea5e05fe62a4516ade0c6db91c30b6f93645035db52ed8 burn_with_from_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin 08ed1235dda921ce8841b26aa18d0c0f36db4884779dd7670857159801b6d597 ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 213d4adc8634671aea16fb4207989375b1aac919b04d608f4767c29592affbf5 -ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin 459ae9c785343bd032856baaacdfc8bf4f6b0d9f5d9082e1580b5846c2be80e5 +ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin d8d70fe111bacc7702c7c263f8c4733dcb2fff77e52c9f60c30d303731bc97c1 commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin 274d87db70b643e00ab0a7e7845bb4b791f3b613bfc87708d33fc5a8369e2a41 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin f7128dcc2ee6dbcbc976288abcc16970ffb19b59412c5202ef6b259d2007f801 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 368cee79d9..b167d6cd02 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -274,7 +274,7 @@ require ( github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 7e684e245d..7ab6113b2a 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1070,8 +1070,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 h1:+Km1o8ApEv/DofxAa5MIPbkxXkKo4BG5u3GKLKB5FSI= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc h1:8267l5X5oF2JnGsDaEG4i0JSQO9o0eC61SscTfWc1bk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/go.mod b/go.mod index 8a75274125..783b28e5a2 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa diff --git a/go.sum b/go.sum index d25f3d297a..081c0a2aee 100644 --- a/go.sum +++ b/go.sum @@ -1027,8 +1027,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 h1:+Km1o8ApEv/DofxAa5MIPbkxXkKo4BG5u3GKLKB5FSI= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc h1:8267l5X5oF2JnGsDaEG4i0JSQO9o0eC61SscTfWc1bk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 7e6b10aae4..e20e98bcf9 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -8,6 +8,7 @@ replace github.com/smartcontractkit/chainlink/v2 => ../ require ( dario.cat/mergo v1.0.0 github.com/AlekSi/pointer v1.1.0 + github.com/Khan/genqlient v0.7.0 github.com/Masterminds/semver/v3 v3.2.1 github.com/avast/retry-go/v4 v4.6.0 github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df @@ -35,15 +36,15 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 - github.com/smartcontractkit/chainlink-testing-framework v1.33.0 + github.com/smartcontractkit/chainlink-testing-framework v1.34.5 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-00010101000000-000000000000 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/smartcontractkit/seth v1.0.12 + github.com/smartcontractkit/seth v1.1.1 github.com/smartcontractkit/wasp v0.4.5 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 @@ -100,10 +101,14 @@ require ( github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/XSAM/otelsql v0.27.0 // indirect + github.com/agnivade/levenshtein v1.1.1 // indirect github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect + github.com/alexflint/go-arg v1.4.2 // indirect + github.com/alexflint/go-scalar v1.0.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/avast/retry-go v3.0.0+incompatible // indirect + github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect github.com/aws/aws-sdk-go v1.45.25 // indirect github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect github.com/aws/jsii-runtime-go v1.75.0 // indirect @@ -427,6 +432,7 @@ require ( github.com/ugorji/go/codec v1.2.12 // indirect github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 // indirect github.com/valyala/fastjson v1.4.1 // indirect + github.com/vektah/gqlparser/v2 v2.5.11 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index c2ec1e83f4..5789a6ccc2 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -125,6 +125,8 @@ github.com/K-Phoen/grabana v0.22.1 h1:b/O+C3H2H6VNYSeMCYUO4X4wYuwFXgBcRkvYa+fjpQ github.com/K-Phoen/grabana v0.22.1/go.mod h1:3LTXrTzQzTKTgvKSXdRjlsJbizSOW/V23Q3iX00R5bU= github.com/K-Phoen/sdk v0.12.4 h1:j2EYuBJm3zDTD0fGKACVFWxAXtkR0q5QzfVqxmHSeGQ= github.com/K-Phoen/sdk v0.12.4/go.mod h1:qmM0wO23CtoDux528MXPpYvS4XkRWkWX6rvX9Za8EVU= +github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= +github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -158,6 +160,8 @@ github.com/Workiva/go-datastructures v1.1.0 h1:hu20UpgZneBhQ3ZvwiOGlqJSKIosin2Rd github.com/Workiva/go-datastructures v1.1.0/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= +github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= +github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -166,6 +170,10 @@ github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrI github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= +github.com/alexflint/go-arg v1.4.2 h1:lDWZAXxpAnZUq4qwb86p/3rIJJ2Li81EoMbTMujhVa0= +github.com/alexflint/go-arg v1.4.2/go.mod h1:9iRbDxne7LcR/GSvEr7ma++GLpdIU1zrghf2y2768kM= +github.com/alexflint/go-scalar v1.0.0 h1:NGupf1XV/Xb04wXskDFzS0KWOLH632W/EO4fAFi+A70= +github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis v2.5.0+incompatible h1:yBHoLpsyjupjz3NL3MhKMVkR41j82Yjf3KFv7ApYzUI= @@ -175,7 +183,11 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -192,6 +204,8 @@ github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHS github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= +github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= +github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= @@ -220,6 +234,8 @@ github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6 github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= +github.com/bradleyjkemp/cupaloy/v2 v2.6.0 h1:knToPYa2xtfg42U3I6punFEjaGFKWQRXJwj0JTv4mTs= +github.com/bradleyjkemp/cupaloy/v2 v2.6.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= @@ -411,6 +427,8 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E= github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= @@ -1378,8 +1396,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 h1:+Km1o8ApEv/DofxAa5MIPbkxXkKo4BG5u3GKLKB5FSI= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc h1:8267l5X5oF2JnGsDaEG4i0JSQO9o0eC61SscTfWc1bk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= @@ -1392,8 +1410,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.33.0 h1:vHQODEdsq5AIbRiyZZ30de6uwJUNFXLYvCr+Odr8TIs= -github.com/smartcontractkit/chainlink-testing-framework v1.33.0/go.mod h1:GrhHthZ5AmceF82+Ypw6Fov1EvB05JJbb1T0EKyO1x0= +github.com/smartcontractkit/chainlink-testing-framework v1.34.5 h1:6itLSDW4NHDDNR+Y+Z8YDzxxCN9SjdKb6SmLCl0vTFM= +github.com/smartcontractkit/chainlink-testing-framework v1.34.5/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= @@ -1404,8 +1422,8 @@ github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1 github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= -github.com/smartcontractkit/seth v1.0.12 h1:iVdgMx42XWanPPnBaM5StR4c1XsTr/0/B/kKRZL5BsY= -github.com/smartcontractkit/seth v1.0.12/go.mod h1:thWtbLyW4nRHJGzC5heknQDORoJPErE15sF34LHkorg= +github.com/smartcontractkit/seth v1.1.1 h1:6hvexjJD7ek8ht/CLlEwQcH21K2E/WEYwbSRdKInZmM= +github.com/smartcontractkit/seth v1.1.1/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= @@ -1536,6 +1554,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE= github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= +github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 2d81105f99..ef077ba768 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,11 +17,11 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 - github.com/smartcontractkit/chainlink-testing-framework v1.33.0 + github.com/smartcontractkit/chainlink-testing-framework v1.34.5 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/smartcontractkit/seth v1.0.12 + github.com/smartcontractkit/seth v1.1.1 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 github.com/smartcontractkit/wasp v0.4.7 github.com/stretchr/testify v1.9.0 @@ -35,13 +35,14 @@ require ( cosmossdk.io/depinject v1.0.0-alpha.4 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/math v1.3.0 // indirect + github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect github.com/containerd/errdefs v0.1.0 // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/testcontainers/testcontainers-go v0.28.0 // indirect k8s.io/apimachinery v0.30.2 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index f74595e42e..3e5d20d303 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -192,6 +192,8 @@ github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHS github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= +github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= +github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= @@ -1358,8 +1360,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15 h1:+Km1o8ApEv/DofxAa5MIPbkxXkKo4BG5u3GKLKB5FSI= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240826120733-199eb5870f15/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc h1:8267l5X5oF2JnGsDaEG4i0JSQO9o0eC61SscTfWc1bk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= @@ -1372,8 +1374,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.33.0 h1:vHQODEdsq5AIbRiyZZ30de6uwJUNFXLYvCr+Odr8TIs= -github.com/smartcontractkit/chainlink-testing-framework v1.33.0/go.mod h1:GrhHthZ5AmceF82+Ypw6Fov1EvB05JJbb1T0EKyO1x0= +github.com/smartcontractkit/chainlink-testing-framework v1.34.5 h1:6itLSDW4NHDDNR+Y+Z8YDzxxCN9SjdKb6SmLCl0vTFM= +github.com/smartcontractkit/chainlink-testing-framework v1.34.5/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= @@ -1384,8 +1386,8 @@ github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1 github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= -github.com/smartcontractkit/seth v1.0.12 h1:iVdgMx42XWanPPnBaM5StR4c1XsTr/0/B/kKRZL5BsY= -github.com/smartcontractkit/seth v1.0.12/go.mod h1:thWtbLyW4nRHJGzC5heknQDORoJPErE15sF34LHkorg= +github.com/smartcontractkit/seth v1.1.1 h1:6hvexjJD7ek8ht/CLlEwQcH21K2E/WEYwbSRdKInZmM= +github.com/smartcontractkit/seth v1.1.1/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= From ebc10996366abde8da2056d7f7757bf53da35ea7 Mon Sep 17 00:00:00 2001 From: kanth <70688600+defistar@users.noreply.github.com> Date: Tue, 27 Aug 2024 23:36:58 +0530 Subject: [PATCH 231/432] feat: emit msghash with offramp (#1370) ## Motivation RMN checks the full hash of the message. However, hash(Any2EVMMessage) != Any2EVMMessage.header.messageId . ## Solution emit `messageHash` along with `ExecutionStateChanged` event --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> Co-authored-by: Rens Rooimans --- contracts/gas-snapshots/ccip.gas-snapshot | 182 +++++++++--------- contracts/src/v0.8/ccip/offRamp/OffRamp.sol | 2 + .../src/v0.8/ccip/test/NonceManager.t.sol | 6 + .../v0.8/ccip/test/e2e/MultiRampsEnd2End.sol | 139 +++++++------ .../src/v0.8/ccip/test/offRamp/OffRamp.t.sol | 46 +++++ .../v0.8/ccip/test/offRamp/OffRampSetup.t.sol | 7 +- .../ccip/generated/offramp/offramp.go | 7 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 8 files changed, 232 insertions(+), 159 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index af1f296236..c13660452d 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -543,18 +543,18 @@ MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 410714) -MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1486877) +MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1504468) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71847) -NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 257298) -NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 259415) -NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 320051) -NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 295325) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244940) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 233260) -NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 150194) +NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 260262) +NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 262359) +NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 326051) +NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 298263) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244814) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 233069) +NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 153186) NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 168502) NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 220478) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) @@ -591,7 +591,7 @@ OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51686) OCR2Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 23484) OCR2Base_transmit:test_UnauthorizedSigner_Revert() (gas: 39665) OCR2Base_transmit:test_WrongNumberOfSignatures_Revert() (gas: 20557) -OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 40127) +OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 40149) OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 107130) OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 88331) OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 39848) @@ -599,129 +599,129 @@ OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMi OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 42843) OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 89579) OffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 467917) -OffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99161) +OffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99183) OffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12395) OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 93181) OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 109824) OffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13263) OffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17988) -OffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15343) -OffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 313729) -OffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 255119) -OffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 166168) -OffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187819) -OffRamp_batchExecute:test_SingleReport_Success() (gas: 153185) -OffRamp_batchExecute:test_Unhealthy_Revert() (gas: 532970) -OffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10439) +OffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15300) +OffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 322171) +OffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 263506) +OffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 169162) +OffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 188589) +OffRamp_batchExecute:test_SingleReport_Success() (gas: 156230) +OffRamp_batchExecute:test_Unhealthy_Revert() (gas: 533834) +OffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10461) OffRamp_ccipReceive:test_Reverts() (gas: 15773) -OffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67436) +OffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67458) OffRamp_commit:test_InvalidInterval_Revert() (gas: 59778) OffRamp_commit:test_InvalidRootRevert() (gas: 58858) -OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6551011) -OffRamp_commit:test_NoConfig_Revert() (gas: 6134083) -OffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106295) +OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6560573) +OffRamp_commit:test_NoConfig_Revert() (gas: 6143711) +OffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106317) OffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116369) -OffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106316) +OffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106338) OffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351652) OffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159342) OffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136480) -OffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136947) +OffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136880) OffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 59126) OffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225582) OffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117632) -OffRamp_commit:test_Unhealthy_Revert() (gas: 77652) +OffRamp_commit:test_Unhealthy_Revert() (gas: 77674) OffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 205066) -OffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6545334) +OffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6554962) OffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47832) -OffRamp_constructor:test_Constructor_Success() (gas: 6137987) -OffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137086) -OffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103803) -OffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101696) -OffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139661) -OffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101573) -OffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101618) +OffRamp_constructor:test_Constructor_Success() (gas: 6147616) +OffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137128) +OffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103845) +OffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101716) +OffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139680) +OffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101593) +OffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101660) OffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17305) -OffRamp_execute:test_LargeBatch_Success() (gas: 1728220) -OffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 349589) -OffRamp_execute:test_MultipleReports_Success() (gas: 277112) -OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6601732) -OffRamp_execute:test_NoConfig_Revert() (gas: 6184566) -OffRamp_execute:test_NonArray_Revert() (gas: 27777) -OffRamp_execute:test_SingleReport_Success() (gas: 172547) -OffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147479) -OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6963806) -OffRamp_execute:test_ZeroReports_Revert() (gas: 17203) -OffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18235) -OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249015) +OffRamp_execute:test_LargeBatch_Success() (gas: 1828972) +OffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 358063) +OffRamp_execute:test_MultipleReports_Success() (gas: 285617) +OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6611685) +OffRamp_execute:test_NoConfig_Revert() (gas: 6194563) +OffRamp_execute:test_NonArray_Revert() (gas: 27809) +OffRamp_execute:test_SingleReport_Success() (gas: 175620) +OffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147848) +OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6973803) +OffRamp_execute:test_ZeroReports_Revert() (gas: 17225) +OffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18257) +OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249037) OffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20517) -OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 207654) +OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 207676) OffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48779) OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48302) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229610) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86181) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 280837) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92415) -OffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35127) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229565) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86203) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 280859) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92437) +OffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35104) OffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23923) -OffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 486078) +OffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 492333) OffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54457) -OffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35905) -OffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154471) +OffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35927) +OffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154493) OffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35338) -OffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 184911) -OffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 196169) -OffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48074) -OffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 444732) -OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 250427) -OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 187283) -OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 206863) -OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 263565) -OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 138454) -OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 417627) +OffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 187911) +OffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 199215) +OffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48096) +OffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 447759) +OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 251078) +OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 193345) +OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 212938) +OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 266576) +OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 141488) +OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 423378) OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65877) -OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80910) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 576137) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 525167) +OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80932) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 587410) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 536450) OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35743) -OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 531800) -OffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 529168) -OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 494410) -OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 133560) -OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 162760) +OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 532474) +OffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 529798) +OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 495040) +OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 136580) +OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 165799) OffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3742124) -OffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118859) +OffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118836) OffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 88048) OffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75551) OffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26439) -OffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 168628) -OffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205504) +OffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 171639) +OffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205796) OffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 25993) OffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152822) -OffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 518556) -OffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2384534) -OffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 205857) -OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 215965) -OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 649750) -OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 319062) +OffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 524603) +OffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2388943) +OffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 208553) +OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 219343) +OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 663643) +OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 330148) OffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 165822) OffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 24603) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 66263) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 41294) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 66285) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 41316) OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 83291) OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 177934) OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 191136) OffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11423) -OffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215351) +OffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215373) OffRamp_setDynamicConfig:test_FeeQuoterZeroAddress_Revert() (gas: 11585) -OffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14130) -OffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49093) -OffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27103) -OffRamp_trialExecute:test_RateLimitError_Success() (gas: 225773) -OffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 234394) +OffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14152) +OffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49115) +OffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27037) +OffRamp_trialExecute:test_RateLimitError_Success() (gas: 225795) +OffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 234416) OffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 309206) -OffRamp_trialExecute:test_trialExecute_Success() (gas: 283972) +OffRamp_trialExecute:test_trialExecute_Success() (gas: 283994) OffRamp_verify:test_Blessed_Success() (gas: 176664) -OffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178732) +OffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178754) OffRamp_verify:test_NotBlessed_Success() (gas: 141593) OffRamp_verify:test_TooManyLeaves_Revert() (gas: 51510) OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 390336) diff --git a/contracts/src/v0.8/ccip/offRamp/OffRamp.sol b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol index 20ce6115dc..d594597d18 100644 --- a/contracts/src/v0.8/ccip/offRamp/OffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol @@ -68,6 +68,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { uint64 indexed sourceChainSelector, uint64 indexed sequenceNumber, bytes32 indexed messageId, + bytes32 messageHash, Internal.MessageExecutionState state, bytes returnData, uint256 gasUsed @@ -473,6 +474,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { sourceChainSelector, message.header.sequenceNumber, message.header.messageId, + hashedLeaves[i], newState, returnData, gasStart - gasleft() diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol index 81da419253..ebb51a9619 100644 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -395,6 +395,7 @@ contract NonceManager_OffRampUpgrade is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -426,6 +427,7 @@ contract NonceManager_OffRampUpgrade is OffRampSetup { SOURCE_CHAIN_SELECTOR_3, messagesChain3[0].header.sequenceNumber, messagesChain3[0].header.messageId, + Internal._hash(messagesChain3[0], ON_RAMP_ADDRESS_3), Internal.MessageExecutionState.SUCCESS, "" ); @@ -507,6 +509,7 @@ contract NonceManager_OffRampUpgrade is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].header.sequenceNumber, messagesMultiRamp[0].header.messageId, + Internal._hash(messagesMultiRamp[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -527,6 +530,7 @@ contract NonceManager_OffRampUpgrade is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].header.sequenceNumber, messagesMultiRamp[0].header.messageId, + Internal._hash(messagesMultiRamp[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -561,6 +565,7 @@ contract NonceManager_OffRampUpgrade is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].header.sequenceNumber, messagesMultiRamp[0].header.messageId, + Internal._hash(messagesMultiRamp[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -611,6 +616,7 @@ contract NonceManager_OffRampUpgrade is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); diff --git a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol index 4f9d0ac2c7..b22e4db9d4 100644 --- a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol +++ b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol @@ -105,74 +105,90 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup { function test_E2E_3MessagesMMultiOffRampSuccess_gas() public { vm.pauseGasMetering(); - IERC20 token0 = IERC20(s_sourceTokens[0]); - IERC20 token1 = IERC20(s_sourceTokens[1]); - uint256 balance0Pre = token0.balanceOf(OWNER); - uint256 balance1Pre = token1.balanceOf(OWNER); - // Send messages Internal.Any2EVMRampMessage[] memory messages1 = new Internal.Any2EVMRampMessage[](2); - messages1[0] = _sendRequest(1, SOURCE_CHAIN_SELECTOR, 1, s_metadataHash, s_sourceRouter, s_tokenAdminRegistry); - messages1[1] = _sendRequest(2, SOURCE_CHAIN_SELECTOR, 2, s_metadataHash, s_sourceRouter, s_tokenAdminRegistry); Internal.Any2EVMRampMessage[] memory messages2 = new Internal.Any2EVMRampMessage[](1); - messages2[0] = - _sendRequest(1, SOURCE_CHAIN_SELECTOR + 1, 1, s_metadataHash2, s_sourceRouter2, s_tokenAdminRegistry2); - uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, _generateTokenMessage()); - // Asserts that the tokens have been sent and the fee has been paid. - assertEq( - balance0Pre - (messages1.length + messages2.length) * (i_tokenAmount0 + expectedFee), token0.balanceOf(OWNER) - ); - assertEq(balance1Pre - (messages1.length + messages2.length) * i_tokenAmount1, token1.balanceOf(OWNER)); + // Scoped to sending to reduce stack pressure + { + IERC20 token0 = IERC20(s_sourceTokens[0]); + IERC20 token1 = IERC20(s_sourceTokens[1]); - // Commit - bytes32[] memory hashedMessages1 = new bytes32[](2); - hashedMessages1[0] = messages1[0]._hash(abi.encode(address(s_onRamp))); - hashedMessages1[1] = messages1[1]._hash(abi.encode(address(s_onRamp))); - bytes32[] memory hashedMessages2 = new bytes32[](1); - hashedMessages2[0] = messages2[0]._hash(abi.encode(address(s_onRamp2))); + uint256 balance0Pre = token0.balanceOf(OWNER); + uint256 balance1Pre = token1.balanceOf(OWNER); - bytes32[] memory merkleRoots = new bytes32[](2); - merkleRoots[0] = MerkleHelper.getMerkleRoot(hashedMessages1); - merkleRoots[1] = MerkleHelper.getMerkleRoot(hashedMessages2); - - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](2); - roots[0] = OffRamp.MerkleRoot({ - sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: OffRamp.Interval(messages1[0].header.sequenceNumber, messages1[1].header.sequenceNumber), - merkleRoot: merkleRoots[0] - }); - roots[1] = OffRamp.MerkleRoot({ - sourceChainSelector: SOURCE_CHAIN_SELECTOR + 1, - interval: OffRamp.Interval(messages2[0].header.sequenceNumber, messages2[0].header.sequenceNumber), - merkleRoot: merkleRoots[1] - }); + // Send messages + messages1[0] = _sendRequest(1, SOURCE_CHAIN_SELECTOR, 1, s_metadataHash, s_sourceRouter, s_tokenAdminRegistry); + messages1[1] = _sendRequest(2, SOURCE_CHAIN_SELECTOR, 2, s_metadataHash, s_sourceRouter, s_tokenAdminRegistry); + messages2[0] = + _sendRequest(1, SOURCE_CHAIN_SELECTOR + 1, 1, s_metadataHash2, s_sourceRouter2, s_tokenAdminRegistry2); - OffRamp.CommitReport memory report = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + uint256 expectedFee = s_sourceRouter.getFee(DEST_CHAIN_SELECTOR, _generateTokenMessage()); + // Asserts that the tokens have been sent and the fee has been paid. + assertEq( + balance0Pre - (messages1.length + messages2.length) * (i_tokenAmount0 + expectedFee), token0.balanceOf(OWNER) + ); + assertEq(balance1Pre - (messages1.length + messages2.length) * i_tokenAmount1, token1.balanceOf(OWNER)); + } - vm.resumeGasMetering(); - _commit(report, ++s_latestSequenceNumber); - vm.pauseGasMetering(); + // Commit - s_mockRMN.setTaggedRootBlessed(IRMN.TaggedRoot({commitStore: address(s_offRamp), root: merkleRoots[0]}), true); - s_mockRMN.setTaggedRootBlessed(IRMN.TaggedRoot({commitStore: address(s_offRamp), root: merkleRoots[1]}), true); + bytes32[] memory merkleRoots = new bytes32[](2); - bytes32[] memory proofs = new bytes32[](0); - bytes32[] memory hashedLeaves = new bytes32[](1); - hashedLeaves[0] = merkleRoots[0]; - uint256 timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR, hashedLeaves, proofs, 2 ** 2 - 1); - assertEq(BLOCK_TIME, timestamp); - hashedLeaves[0] = merkleRoots[1]; - timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR + 1, hashedLeaves, proofs, 2 ** 2 - 1); - assertEq(BLOCK_TIME, timestamp); + // Scoped to commit to reduce stack pressure + { + bytes32[] memory hashedMessages1 = new bytes32[](2); + hashedMessages1[0] = messages1[0]._hash(abi.encode(address(s_onRamp))); + hashedMessages1[1] = messages1[1]._hash(abi.encode(address(s_onRamp))); + bytes32[] memory hashedMessages2 = new bytes32[](1); + hashedMessages2[0] = messages2[0]._hash(abi.encode(address(s_onRamp2))); + + merkleRoots[0] = MerkleHelper.getMerkleRoot(hashedMessages1); + merkleRoots[1] = MerkleHelper.getMerkleRoot(hashedMessages2); + + OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](2); + roots[0] = OffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR, + interval: OffRamp.Interval(messages1[0].header.sequenceNumber, messages1[1].header.sequenceNumber), + merkleRoot: merkleRoots[0] + }); + roots[1] = OffRamp.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR + 1, + interval: OffRamp.Interval(messages2[0].header.sequenceNumber, messages2[0].header.sequenceNumber), + merkleRoot: merkleRoots[1] + }); + + OffRamp.CommitReport memory report = + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + + vm.resumeGasMetering(); + _commit(report, ++s_latestSequenceNumber); + vm.pauseGasMetering(); + } - // We change the block time so when execute would e.g. use the current - // block time instead of the committed block time the value would be - // incorrect in the checks below. - vm.warp(BLOCK_TIME + 2000); + // Scoped to RMN and verify to reduce stack pressure + { + s_mockRMN.setTaggedRootBlessed(IRMN.TaggedRoot({commitStore: address(s_offRamp), root: merkleRoots[0]}), true); + s_mockRMN.setTaggedRootBlessed(IRMN.TaggedRoot({commitStore: address(s_offRamp), root: merkleRoots[1]}), true); + + bytes32[] memory proofs = new bytes32[](0); + bytes32[] memory hashedLeaves = new bytes32[](1); + hashedLeaves[0] = merkleRoots[0]; + + uint256 timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR, hashedLeaves, proofs, 2 ** 2 - 1); + assertEq(BLOCK_TIME, timestamp); + hashedLeaves[0] = merkleRoots[1]; + timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR + 1, hashedLeaves, proofs, 2 ** 2 - 1); + assertEq(BLOCK_TIME, timestamp); + + // We change the block time so when execute would e.g. use the current + // block time instead of the committed block time the value would be + // incorrect in the checks below. + vm.warp(BLOCK_TIME + 2000); + } // Execute + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR, messages1); reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR + 1, messages2); @@ -185,6 +201,7 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup { SOURCE_CHAIN_SELECTOR, messages1[0].header.sequenceNumber, messages1[0].header.messageId, + messages1[0]._hash(abi.encode(address(s_onRamp))), Internal.MessageExecutionState.SUCCESS, "" ); @@ -193,6 +210,7 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup { SOURCE_CHAIN_SELECTOR, messages1[1].header.sequenceNumber, messages1[1].header.messageId, + messages1[1]._hash(abi.encode(address(s_onRamp))), Internal.MessageExecutionState.SUCCESS, "" ); @@ -201,6 +219,7 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup { SOURCE_CHAIN_SELECTOR + 1, messages2[0].header.sequenceNumber, messages2[0].header.messageId, + messages2[0]._hash(abi.encode(address(s_onRamp2))), Internal.MessageExecutionState.SUCCESS, "" ); @@ -215,9 +234,7 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup { TokenAdminRegistry tokenAdminRegistry ) public returns (Internal.Any2EVMRampMessage memory) { Client.EVM2AnyMessage memory message = _generateTokenMessage(); - uint256 expectedFee = router.getFee(DEST_CHAIN_SELECTOR, message); - - IERC20(s_sourceTokens[0]).approve(address(router), i_tokenAmount0 + expectedFee); + IERC20(s_sourceTokens[0]).approve(address(router), i_tokenAmount0 + router.getFee(DEST_CHAIN_SELECTOR, message)); IERC20(s_sourceTokens[1]).approve(address(router), i_tokenAmount1); message.receiver = abi.encode(address(s_receiver)); @@ -227,7 +244,7 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup { DEST_CHAIN_SELECTOR, expectedSeqNum, nonce, - expectedFee, + router.getFee(DEST_CHAIN_SELECTOR, message), OWNER, metadataHash, tokenAdminRegistry @@ -240,8 +257,6 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup { router.ccipSend(DEST_CHAIN_SELECTOR, message); vm.pauseGasMetering(); - uint256 gasLimit = s_feeQuoter.parseEVMExtraArgsFromBytes(msgEvent.extraArgs, DEST_CHAIN_SELECTOR).gasLimit; - return Internal.Any2EVMRampMessage({ header: Internal.RampMessageHeader({ messageId: msgEvent.header.messageId, @@ -253,7 +268,7 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup { sender: abi.encode(msgEvent.sender), data: msgEvent.data, receiver: abi.decode(msgEvent.receiver, (address)), - gasLimit: gasLimit, + gasLimit: s_feeQuoter.parseEVMExtraArgsFromBytes(msgEvent.extraArgs, DEST_CHAIN_SELECTOR).gasLimit, tokenAmounts: msgEvent.tokenAmounts }); } diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol index b3fb5de5a2..9167f3f075 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol @@ -346,6 +346,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -361,6 +362,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -381,6 +383,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -402,6 +405,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -455,6 +459,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector( OffRamp.ReceiverError.selector, @@ -495,6 +500,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -510,6 +516,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -532,6 +539,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -557,6 +565,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -576,6 +585,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -598,6 +608,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -606,6 +617,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[1].header.sequenceNumber, messages[1].header.messageId, + Internal._hash(messages[1], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -628,6 +640,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -635,6 +648,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[1].header.sequenceNumber, messages[1].header.messageId, + Internal._hash(messages[1], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -676,6 +690,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[i].header.sequenceNumber, messages[i].header.messageId, + Internal._hash(messages[i], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -702,6 +717,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector( OffRamp.TokenHandlingError.selector, @@ -891,6 +907,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector(CallWithExactGas.NotEnoughGasForCall.selector) ); @@ -914,6 +931,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector( OffRamp.ReceiverError.selector, @@ -1108,6 +1126,7 @@ contract OffRamp_batchExecute is OffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1134,6 +1153,7 @@ contract OffRamp_batchExecute is OffRampSetup { messages1[0].header.sourceChainSelector, messages1[0].header.sequenceNumber, messages1[0].header.messageId, + Internal._hash(messages1[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1142,6 +1162,7 @@ contract OffRamp_batchExecute is OffRampSetup { messages1[1].header.sourceChainSelector, messages1[1].header.sequenceNumber, messages1[1].header.messageId, + Internal._hash(messages1[1], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1150,6 +1171,7 @@ contract OffRamp_batchExecute is OffRampSetup { messages2[0].header.sourceChainSelector, messages2[0].header.sequenceNumber, messages2[0].header.messageId, + Internal._hash(messages2[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1177,6 +1199,7 @@ contract OffRamp_batchExecute is OffRampSetup { messages1[0].header.sourceChainSelector, messages1[0].header.sequenceNumber, messages1[0].header.messageId, + Internal._hash(messages1[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1185,6 +1208,7 @@ contract OffRamp_batchExecute is OffRampSetup { messages1[1].header.sourceChainSelector, messages1[1].header.sequenceNumber, messages1[1].header.messageId, + Internal._hash(messages1[1], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1193,6 +1217,7 @@ contract OffRamp_batchExecute is OffRampSetup { messages2[0].header.sourceChainSelector, messages2[0].header.sequenceNumber, messages2[0].header.messageId, + Internal._hash(messages2[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1222,6 +1247,7 @@ contract OffRamp_batchExecute is OffRampSetup { messages[0].header.sourceChainSelector, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1294,6 +1320,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1317,6 +1344,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1343,6 +1371,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector( OffRamp.ReceiverError.selector, abi.encodeWithSelector(MaybeRevertMessageReceiver.CustomError.selector, "") @@ -1397,6 +1426,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages1[j].header.sequenceNumber, messages1[j].header.messageId, + Internal._hash(messages1[j], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1407,6 +1437,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages2[k].header.sequenceNumber, messages2[k].header.messageId, + Internal._hash(messages2[k], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1430,6 +1461,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1438,6 +1470,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[1].header.sequenceNumber, messages[1].header.messageId, + Internal._hash(messages[1], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector( OffRamp.ReceiverError.selector, @@ -1449,6 +1482,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[2].header.sequenceNumber, messages[2].header.messageId, + Internal._hash(messages[2], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1469,6 +1503,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1487,6 +1522,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector(OffRamp.ReceiverError.selector, "") ); @@ -1504,6 +1540,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1693,6 +1730,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1729,6 +1767,7 @@ contract OffRamp_execute is OffRampSetup { SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, + Internal._hash(messages[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1757,6 +1796,7 @@ contract OffRamp_execute is OffRampSetup { messages1[0].header.sourceChainSelector, messages1[0].header.sequenceNumber, messages1[0].header.messageId, + Internal._hash(messages1[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1765,6 +1805,7 @@ contract OffRamp_execute is OffRampSetup { messages1[1].header.sourceChainSelector, messages1[1].header.sequenceNumber, messages1[1].header.messageId, + Internal._hash(messages1[1], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1773,6 +1814,7 @@ contract OffRamp_execute is OffRampSetup { messages2[0].header.sourceChainSelector, messages2[0].header.sequenceNumber, messages2[0].header.messageId, + Internal._hash(messages2[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1803,6 +1845,7 @@ contract OffRamp_execute is OffRampSetup { reports[i].messages[j].header.sourceChainSelector, reports[i].messages[j].header.sequenceNumber, reports[i].messages[j].header.messageId, + Internal._hash(reports[i].messages[j], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1838,6 +1881,7 @@ contract OffRamp_execute is OffRampSetup { messages1[0].header.sourceChainSelector, messages1[0].header.sequenceNumber, messages1[0].header.messageId, + Internal._hash(messages1[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector( IMessageInterceptor.MessageValidationError.selector, @@ -1849,6 +1893,7 @@ contract OffRamp_execute is OffRampSetup { messages1[1].header.sourceChainSelector, messages1[1].header.sequenceNumber, messages1[1].header.messageId, + Internal._hash(messages1[1], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1857,6 +1902,7 @@ contract OffRamp_execute is OffRampSetup { messages2[0].header.sourceChainSelector, messages2[0].header.sequenceNumber, messages2[0].header.messageId, + Internal._hash(messages2[0], ON_RAMP_ADDRESS_1), Internal.MessageExecutionState.FAILURE, abi.encodeWithSelector( IMessageInterceptor.MessageValidationError.selector, diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol index ff051cdd21..403655f10a 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol @@ -30,7 +30,7 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { uint64 internal constant SOURCE_CHAIN_SELECTOR_2 = 6433500567565415381; uint64 internal constant SOURCE_CHAIN_SELECTOR_3 = 4051577828743386545; bytes32 internal constant EXECUTION_STATE_CHANGE_TOPIC_HASH = - keccak256("ExecutionStateChanged(uint64,uint64,bytes32,uint8,bytes,uint256)"); + keccak256("ExecutionStateChanged(uint64,uint64,bytes32,bytes32,uint8,bytes,uint256)"); bytes internal constant ON_RAMP_ADDRESS_1 = abi.encode(ON_RAMP_ADDRESS); bytes internal constant ON_RAMP_ADDRESS_2 = abi.encode(0xaA3f843Cf8E33B1F02dd28303b6bD87B1aBF8AE4); @@ -484,6 +484,7 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { uint64 sourceChainSelector, uint64 sequenceNumber, bytes32 messageId, + bytes32 messageHash, Internal.MessageExecutionState state, bytes memory returnData ) public { @@ -493,11 +494,13 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { uint64 logSourceChainSelector = uint64(uint256(logs[i].topics[1])); uint64 logSequenceNumber = uint64(uint256(logs[i].topics[2])); bytes32 logMessageId = bytes32(logs[i].topics[3]); - (uint8 logState, bytes memory logReturnData,) = abi.decode(logs[i].data, (uint8, bytes, uint256)); + (bytes32 logMessageHash, uint8 logState, bytes memory logReturnData,) = + abi.decode(logs[i].data, (bytes32, uint8, bytes, uint256)); if (logMessageId == messageId) { assertEq(logSourceChainSelector, sourceChainSelector); assertEq(logSequenceNumber, sequenceNumber); assertEq(logMessageId, messageId); + assertEq(logMessageHash, messageHash); assertEq(logState, uint8(state)); assertEq(logReturnData, returnData); } diff --git a/core/gethwrappers/ccip/generated/offramp/offramp.go b/core/gethwrappers/ccip/generated/offramp/offramp.go index 2ce6804b3c..65795e0626 100644 --- a/core/gethwrappers/ccip/generated/offramp/offramp.go +++ b/core/gethwrappers/ccip/generated/offramp/offramp.go @@ -164,8 +164,8 @@ type OffRampUnblessedRoot struct { } var OffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162006c1a38038062006c1a8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615f4462000cd6600039600081816102660152612a010152600081816102370152612ef40152600081816102080152818161142b015261196d0152600081816101d801526125f00152600081816117f3015261183f0152615f446000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063ccd37ba31161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063ccd37ba31461050b578063d2a15d3514610550578063e9d68a8e1461056357600080fd5b8063991a5018116100bd578063991a5018146104c5578063a80036b4146104d8578063c673e584146104eb57600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b8063311cd5131161012f5780635e36480c116101145780635e36480c146103785780637437ff9f1461039857806379ba50971461049457600080fd5b8063311cd513146103495780633f4b04aa1461035c57600080fd5b806306285c691161016057806306285c69146101a4578063181f5a77146102ed5780632d04ab761461033657600080fd5b806304666f9c1461017c57806305d938b514610191575b600080fd5b61018f61018a3660046140af565b6105cc565b005b61018f61019f36600461473b565b6105e0565b61029660408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102e49190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103296040518060400160405280601181526020017f4f666652616d7020312e362e302d64657600000000000000000000000000000081525081565b6040516102e491906148b6565b61018f610344366004614961565b610785565b61018f610357366004614a14565b610b5c565b60095460405167ffffffffffffffff90911681526020016102e4565b61038b610386366004614a68565b610bc5565b6040516102e49190614ac5565b6104376040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102e49190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610c1b565b61018f610177366004614ad3565b6000546040516001600160a01b0390911681526020016102e4565b61018f6104d3366004614b22565b610cd9565b61018f6104e6366004614b96565b610cea565b6104fe6104f9366004614c03565b61105d565b6040516102e49190614c63565b610542610519366004614cd8565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102e4565b61018f61055e366004614d02565b6111bb565b610576610571366004614d77565b611275565b6040516102e49190614d92565b61018f610591366004614de0565b611382565b61018f6105a4366004614e65565b611393565b6105bc6105b7366004614fa3565b6113d5565b60405190151581526020016102e4565b6105d4611496565b6105dd816114f2565b50565b6105e86117f0565b815181518114610624576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8181101561077557600084828151811061064357610643614fbc565b6020026020010151905060008160200151519050600085848151811061066b5761066b614fbc565b60200260200101519050805182146106af576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b828110156107665760008282815181106106ce576106ce614fbc565b602002602001015190508060001461075d57846020015182815181106106f6576106f6614fbc565b60200260200101516080015181101561075d5784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064015b60405180910390fd5b506001016106b2565b50505050806001019050610627565b506107808383611871565b505050565b600061079387890189615142565b805151519091501515806107ac57508051602001515115155b156108ac5760095460208a01359067ffffffffffffffff8083169116101561086b576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261083492910161536a565b600060405180830381600087803b15801561084e57600080fd5b505af1158015610862573d6000803e3d6000fd5b505050506108aa565b8160200151516000036108aa576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b816020015151811015610aa5576000826020015182815181106108d4576108d4614fbc565b602002602001015190506000816000015190506108f081611921565b60006108fb82611a23565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061093f575060208084015190810151905167ffffffffffffffff9182169116115b1561097f57825160208401516040517feefb0cac00000000000000000000000000000000000000000000000000000000815261075492919060040161537d565b6040830151806109bb576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff16600090815260086020908152604080832084845290915290205415610a2e5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101829052604401610754565b6020808501510151610a419060016153c8565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff9283160217909255925116600090815260086020908152604080832094835293905291909120429055506001016108af565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610ad591906153f0565b60405180910390a1610b5160008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b9250611a8a915050565b505050505050505050565b610b9c610b6b8284018461548d565b6040805160008082526020820190925290610b96565b6060815260200190600190039081610b815790505b50611871565b604080516000808252602082019092529050610bbf600185858585866000611a8a565b50505050565b6000610bd3600160046154c2565b6002610be06080856154eb565b67ffffffffffffffff16610bf49190615512565b610bfe8585611e01565b901c166003811115610c1257610c12614a9b565b90505b92915050565b6001546001600160a01b03163314610c755760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610754565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ce1611496565b6105dd81611e48565b333014610d23576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281610d60565b6040805180820190915260008082526020820152815260200190600190039081610d395790505b5060a08501515190915015610d9457610d918460a00151856020015186606001518760000151602001518787611fae565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff1681830152808701518351600094840192610dd09291016148b6565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015610edd576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a190610e4a9085906004016155cb565b600060405180830381600087803b158015610e6457600080fd5b505af1925050508015610e75575060015b610edd573d808015610ea3576040519150601f19603f3d011682016040523d82523d6000602084013e610ea8565b606091505b50806040517f09c2532500000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b604086015151158015610ef257506080860151155b80610f09575060608601516001600160a01b03163b155b80610f4957506060860151610f47906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120cd565b155b15610f5657505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf9798392610fce92899261138892916004016155de565b6000604051808303816000875af1158015610fed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611015919081019061561a565b50915091508161105357806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b5050505050505050565b6110a06040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c08201529485529182018054845181840281018401909552808552929385830193909283018282801561114957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161112b575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156111ab57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161118d575b5050505050815250509050919050565b6111c3611496565b60005b818110156107805760008383838181106111e2576111e2614fbc565b9050604002018036038101906111f891906156b0565b905061120781602001516113d5565b61126c57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b506001016111c6565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b909204909216948301949094526001840180549394929391840191611302906156e9565b80601f016020809104026020016040519081016040528092919081815260200182805461132e906156e9565b80156111ab5780601f10611350576101008083540402835291602001916111ab565b820191906000526020600020905b81548152906001019060200180831161135e57505050919092525091949350505050565b61138a611496565b6105dd816120e9565b61139b611496565b60005b81518110156113d1576113c98282815181106113bc576113bc614fbc565b602002602001015161219f565b60010161139e565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611472573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c159190615723565b6000546001600160a01b031633146114f05760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610754565b565b60005b81518110156113d157600082828151811061151257611512614fbc565b602002602001015190506000816020015190508067ffffffffffffffff16600003611569576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611591576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115bc906156e9565b80601f01602080910402602001604051908101604052809291908181526020018280546115e8906156e9565b80156116355780601f1061160a57610100808354040283529160200191611635565b820191906000526020600020905b81548152906001019060200180831161161857829003601f168201915b5050505050905060008460600151905081516000036116ed578051600003611670576040516342bcdf7f60e11b815260040160405180910390fd5b6001830161167e8282615788565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611740565b8080519060200120828051906020012014611740576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610754565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117d8908690615848565b60405180910390a250505050508060010190506114f5565b467f0000000000000000000000000000000000000000000000000000000000000000146114f0576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610754565b81516000036118ab576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b845181101561191a576119128582815181106118e0576118e0614fbc565b60200260200101518461190c578583815181106118ff576118ff614fbc565b60200260200101516124e3565b836124e3565b6001016118c2565b5050505050565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa1580156119bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e09190615723565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610754565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610c15576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610754565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611ae98760a4615916565b9050826060015115611b31578451611b02906020615512565b8651611b0f906020615512565b611b1a9060a0615916565b611b249190615916565b611b2e9082615916565b90505b368114611b73576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610754565b5081518114611bbb5781516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610754565b611bc36117f0565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611c1157611c11614a9b565b6002811115611c2257611c22614a9b565b9052509050600281602001516002811115611c3f57611c3f614a9b565b148015611c935750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611c7b57611c7b614fbc565b6000918252602090912001546001600160a01b031633145b611cc9576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611dab576020820151611ce4906001615929565b60ff16855114611d20576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611d5b576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611d6d929190615942565b604051908190038120611d84918b90602001615952565b604051602081830303815290604052805190602001209050611da98a82888888612c86565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b67ffffffffffffffff8216600090815260076020526040812081611e26608085615966565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b80516001600160a01b0316611e70576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fca57611fca613ec6565b60405190808252806020026020018201604052801561200f57816020015b6040805180820190915260008082526020820152815260200190600190039081611fe85790505b50905060005b87518110156120c15761209c88828151811061203357612033614fbc565b602002602001015188888888888781811061205057612050614fbc565b9050602002810190612062919061598d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9392505050565b8282815181106120ae576120ae614fbc565b6020908102919091010152600101612015565b505b9695505050505050565b60006120d883613238565b8015610c125750610c12838361329c565b336001600160a01b038216036121415760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610754565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ca576000604051631b3fab5160e11b815260040161075491906159f2565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223757606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff90921691909117905561228c565b6060840151600182015460ff620100009091041615159015151461228c576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff84166004820152602401610754565b60a08401518051601f60ff821611156122bb576001604051631b3fab5160e11b815260040161075491906159f2565b612321858560030180548060200260200160405190810160405280929190818152602001828054801561231757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122f9575b5050505050613357565b8560600151156124505761238f8585600201805480602002602001604051908101604052809291908181526020018280548015612317576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122f9575050505050613357565b608086015180516123a99060028701906020840190613e20565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f1015612409576002604051631b3fab5160e11b815260040161075491906159f2565b6040880151612419906003615a0c565b60ff168160ff1611612441576003604051631b3fab5160e11b815260040161075491906159f2565b61244d878360016133c0565b50505b61245c858360026133c0565b81516124719060038601906020850190613e20565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ca938a939260028b01929190615a28565b60405180910390a16124db85613540565b505050505050565b81516124ee81611921565b60006124f982611a23565b602085015151909150600081900361253c576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461257a576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561259557612595613ec6565b6040519080825280602002602001820160405280156125be578160200160208202803683370190505b50905060005b82811015612733576000876020015182815181106125e4576125e4614fbc565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461267757805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610754565b61270d8186600101805461268a906156e9565b80601f01602080910402602001604051908101604052809291908181526020018280546126b6906156e9565b80156127035780601f106126d857610100808354040283529160200191612703565b820191906000526020600020905b8154815290600101906020018083116126e657829003601f168201915b505050505061355c565b83838151811061271f5761271f614fbc565b6020908102919091010152506001016125c4565b50600061274a858389606001518a6080015161367e565b905080600003612792576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610754565b8551151560005b84811015610b515760005a905060008a6020015183815181106127be576127be614fbc565b6020026020010151905060006127dc8a836000015160600151610bc5565b905060008160038111156127f2576127f2614a9b565b148061280f5750600381600381111561280d5761280d614a9b565b145b612867578151606001516040805167ffffffffffffffff808e16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a1505050612c7e565b841561293757600454600090600160a01b900463ffffffff1661288a88426154c2565b11905080806128aa575060038260038111156128a8576128a8614a9b565b145b6128ec576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8c166004820152602401610754565b8b85815181106128fe576128fe614fbc565b6020026020010151600014612931578b858151811061291f5761291f614fbc565b60200260200101518360800181815250505b50612998565b600081600381111561294b5761294b614a9b565b14612998578151606001516040805167ffffffffffffffff808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612857565b81516080015167ffffffffffffffff1615612a875760008160038111156129c1576129c1614a9b565b03612a875781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612a38928f929190600401615ad4565b6020604051808303816000875af1158015612a57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7b9190615723565b612a8757505050612c7e565b60008c604001518581518110612a9f57612a9f614fbc565b6020026020010151905080518360a001515114612b03578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808e1660048301529091166024820152604401610754565b612b178b84600001516060015160016136d4565b600080612b24858461377c565b91509150612b3b8d866000015160600151846136d4565b8715612bab576003826003811115612b5557612b55614a9b565b03612bab576000846003811115612b6e57612b6e614a9b565b14612bab578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261075491908390600401615b01565b6002826003811115612bbf57612bbf614a9b565b14612c19576003826003811115612bd857612bd8614a9b565b14612c19578451606001516040517f926c5a3e000000000000000000000000000000000000000000000000000000008152610754918f918590600401615b1a565b8451805160609091015167ffffffffffffffff908116908f167fdc8ccbc35e0eebd81239bcd1971fcd53c7eb34034880142a0f43c809a458732f85855a612c60908d6154c2565b604051612c6f93929190615b40565b60405180910390a45050505050505b600101612799565b612c8e613e92565b835160005b81811015611053576000600188868460208110612cb257612cb2614fbc565b612cbf91901a601b615929565b898581518110612cd157612cd1614fbc565b6020026020010151898681518110612ceb57612ceb614fbc565b602002602001015160405160008152602001604052604051612d29949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612d4b573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b03851683528152858220858701909652855480841686529397509095509293928401916101009004166002811115612dac57612dac614a9b565b6002811115612dbd57612dbd614a9b565b9052509050600181602001516002811115612dda57612dda614a9b565b14612e11576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f8110612e2857612e28614fbc565b602002015115612e64576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f8110612e7f57612e7f614fbc565b911515602090920201525050600101612c93565b60408051808201909152600080825260208201526000612eb68760200151613846565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5f9190615b70565b90506001600160a01b0381161580612fa75750612fa56001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120cd565b155b15612fe9576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610754565b600454600090819061300b9089908690600160e01b900463ffffffff166138ec565b9150915060008060006130d86040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b8152506040516024016130899190615b8d565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a1a565b9250925092508261311757816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b815160201461315f5781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610754565b6000828060200190518101906131759190615c5a565b9050866001600160a01b03168c6001600160a01b03161461320a5760006131a68d8a6131a1868a6154c2565b6138ec565b509050868110806131c05750816131bd88836154c2565b14155b15613208576040517fa966e21f000000000000000000000000000000000000000000000000000000008152600481018390526024810188905260448101829052606401610754565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613264827f01ffc9a70000000000000000000000000000000000000000000000000000000061329c565b8015610c155750613295827fffffffff0000000000000000000000000000000000000000000000000000000061329c565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015613340575060208210155b801561334c5750600081115b979650505050505050565b60005b81518110156107805760ff83166000908152600360205260408120835190919084908490811061338c5761338c614fbc565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161335a565b60005b82518160ff161015610bbf576000838260ff16815181106133e6576133e6614fbc565b602002602001015190506000600281111561340357613403614a9b565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561344257613442614a9b565b14613463576004604051631b3fab5160e11b815260040161075491906159f2565b6001600160a01b0381166134a3576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134c9576134c9614a9b565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561352657613526614a9b565b0217905550905050508061353990615c73565b90506133c3565b60ff81166105dd576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936135a2937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615c92565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135eb9794969395929491939101615cc5565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136229190615dd7565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061368c858585613b40565b9050613697816113d5565b6136a55760009150506136cc565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b600060026136e36080856154eb565b67ffffffffffffffff166136f79190615512565b905060006137058585611e01565b905081613714600160046154c2565b901b19168183600381111561372b5761372b614a9b565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161375a608088615966565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fa80036b4000000000000000000000000000000000000000000000000000000008152600090606090309063a80036b4906137c09087908790600401615e37565b600060405180830381600087803b1580156137da57600080fd5b505af19250505080156137eb575060015b61382a573d808015613819576040519150601f19603f3d011682016040523d82523d6000602084013e61381e565b606091505b5060039250905061383f565b50506040805160208101909152600081526002905b9250929050565b6000815160201461388557816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b60008280602001905181019061389b9190615c5a565b90506001600160a01b038111806138b3575061040081105b15610c1557826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b60008060008060006139668860405160240161391791906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a1a565b925092509250826139a557816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161075491906148b6565b60208251146139ed5781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610754565b81806020019051810190613a019190615c5a565b613a0b82886154c2565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a3d57613a3d613ec6565b6040519080825280601f01601f191660200182016040528015613a67576020820181803683370190505b509150863b613a9a577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613acd577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613b06577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b295750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b81576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b9557506101018111155b613bb2576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bdc576040516309bde33960e01b815260040160405180910390fd5b80600003613c095786600081518110613bf757613bf7614fbc565b60200260200101519350505050613dd8565b60008167ffffffffffffffff811115613c2457613c24613ec6565b604051908082528060200260200182016040528015613c4d578160200160208202803683370190505b50905060008080805b85811015613d775760006001821b8b811603613cb15788851015613c9a578c5160018601958e918110613c8b57613c8b614fbc565b60200260200101519050613cd3565b8551600185019487918110613c8b57613c8b614fbc565b8b5160018401938d918110613cc857613cc8614fbc565b602002602001015190505b600089861015613d03578d5160018701968f918110613cf457613cf4614fbc565b60200260200101519050613d25565b8651600186019588918110613d1a57613d1a614fbc565b602002602001015190505b82851115613d46576040516309bde33960e01b815260040160405180910390fd5b613d508282613ddf565b878481518110613d6257613d62614fbc565b60209081029190910101525050600101613c56565b506001850382148015613d8957508683145b8015613d9457508581145b613db1576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613dc657613dc6614fbc565b60200260200101519750505050505050505b9392505050565b6000818310613df757613df28284613dfd565b610c12565b610c1283835b604080516001602082015290810183905260608101829052600090608001613660565b828054828255906000526020600020908101928215613e82579160200282015b82811115613e82578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e40565b50613e8e929150613eb1565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613e8e5760008155600101613eb2565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613eff57613eff613ec6565b60405290565b60405160a0810167ffffffffffffffff81118282101715613eff57613eff613ec6565b60405160c0810167ffffffffffffffff81118282101715613eff57613eff613ec6565b6040805190810167ffffffffffffffff81118282101715613eff57613eff613ec6565b6040516060810167ffffffffffffffff81118282101715613eff57613eff613ec6565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fba57613fba613ec6565b604052919050565b600067ffffffffffffffff821115613fdc57613fdc613ec6565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461401357600080fd5b919050565b80151581146105dd57600080fd5b803561401381614018565b600067ffffffffffffffff82111561404b5761404b613ec6565b50601f01601f191660200190565b600082601f83011261406a57600080fd5b813561407d61407882614031565b613f91565b81815284602083860101111561409257600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140c257600080fd5b823567ffffffffffffffff808211156140da57600080fd5b818501915085601f8301126140ee57600080fd5b81356140fc61407882613fc2565b81815260059190911b8301840190848101908883111561411b57600080fd5b8585015b838110156141c1578035858111156141375760008081fd5b86016080818c03601f190181131561414f5760008081fd5b614157613edc565b8983013561416481613fe6565b81526040614173848201613ffb565b8b83015260608085013561418681614018565b8383015292840135928984111561419f57600091508182fd5b6141ad8f8d86880101614059565b90830152508552505091860191860161411f565b5098975050505050505050565b600060a082840312156141e057600080fd5b6141e8613f05565b9050813581526141fa60208301613ffb565b602082015261420b60408301613ffb565b604082015261421c60608301613ffb565b606082015261422d60808301613ffb565b608082015292915050565b803561401381613fe6565b600082601f83011261425457600080fd5b8135602061426461407883613fc2565b82815260059290921b8401810191818101908684111561428357600080fd5b8286015b848110156120c157803567ffffffffffffffff808211156142a85760008081fd5b818901915060a080601f19848d030112156142c35760008081fd5b6142cb613f05565b87840135838111156142dd5760008081fd5b6142eb8d8a83880101614059565b825250604080850135848111156143025760008081fd5b6143108e8b83890101614059565b8a84015250606080860135858111156143295760008081fd5b6143378f8c838a0101614059565b8385015250608091508186013581840152508285013592508383111561435d5760008081fd5b61436b8d8a85880101614059565b908201528652505050918301918301614287565b6000610140828403121561439257600080fd5b61439a613f28565b90506143a683836141ce565b815260a082013567ffffffffffffffff808211156143c357600080fd5b6143cf85838601614059565b602084015260c08401359150808211156143e857600080fd5b6143f485838601614059565b604084015261440560e08501614238565b6060840152610100840135608084015261012084013591508082111561442a57600080fd5b5061443784828501614243565b60a08301525092915050565b600082601f83011261445457600080fd5b8135602061446461407883613fc2565b82815260059290921b8401810191818101908684111561448357600080fd5b8286015b848110156120c157803567ffffffffffffffff8111156144a75760008081fd5b6144b58986838b010161437f565b845250918301918301614487565b600082601f8301126144d457600080fd5b813560206144e461407883613fc2565b82815260059290921b8401810191818101908684111561450357600080fd5b8286015b848110156120c157803567ffffffffffffffff8082111561452757600080fd5b818901915089603f83011261453b57600080fd5b8582013561454b61407882613fc2565b81815260059190911b830160400190878101908c83111561456b57600080fd5b604085015b838110156145a45780358581111561458757600080fd5b6145968f6040838a0101614059565b845250918901918901614570565b50875250505092840192508301614507565b600082601f8301126145c757600080fd5b813560206145d761407883613fc2565b8083825260208201915060208460051b8701019350868411156145f957600080fd5b602086015b848110156120c157803583529183019183016145fe565b600082601f83011261462657600080fd5b8135602061463661407883613fc2565b82815260059290921b8401810191818101908684111561465557600080fd5b8286015b848110156120c157803567ffffffffffffffff8082111561467a5760008081fd5b818901915060a080601f19848d030112156146955760008081fd5b61469d613f05565b6146a8888501613ffb565b8152604080850135848111156146be5760008081fd5b6146cc8e8b83890101614443565b8a84015250606080860135858111156146e55760008081fd5b6146f38f8c838a01016144c3565b838501525060809150818601358581111561470e5760008081fd5b61471c8f8c838a01016145b6565b9184019190915250919093013590830152508352918301918301614659565b600080604080848603121561474f57600080fd5b833567ffffffffffffffff8082111561476757600080fd5b61477387838801614615565b945060209150818601358181111561478a57600080fd5b8601601f8101881361479b57600080fd5b80356147a961407882613fc2565b81815260059190911b8201840190848101908a8311156147c857600080fd5b8584015b83811015614854578035868111156147e45760008081fd5b8501603f81018d136147f65760008081fd5b8781013561480661407882613fc2565b81815260059190911b82018a0190898101908f8311156148265760008081fd5b928b01925b828410156148445783358252928a0192908a019061482b565b86525050509186019186016147cc565b50809750505050505050509250929050565b60005b83811015614881578181015183820152602001614869565b50506000910152565b600081518084526148a2816020860160208601614866565b601f01601f19169290920160200192915050565b602081526000610c12602083018461488a565b8060608101831015610c1557600080fd5b60008083601f8401126148ec57600080fd5b50813567ffffffffffffffff81111561490457600080fd5b60208301915083602082850101111561383f57600080fd5b60008083601f84011261492e57600080fd5b50813567ffffffffffffffff81111561494657600080fd5b6020830191508360208260051b850101111561383f57600080fd5b60008060008060008060008060e0898b03121561497d57600080fd5b6149878a8a6148c9565b9750606089013567ffffffffffffffff808211156149a457600080fd5b6149b08c838d016148da565b909950975060808b01359150808211156149c957600080fd5b6149d58c838d0161491c565b909750955060a08b01359150808211156149ee57600080fd5b506149fb8b828c0161491c565b999c989b50969995989497949560c00135949350505050565b600080600060808486031215614a2957600080fd5b614a3385856148c9565b9250606084013567ffffffffffffffff811115614a4f57600080fd5b614a5b868287016148da565b9497909650939450505050565b60008060408385031215614a7b57600080fd5b614a8483613ffb565b9150614a9260208401613ffb565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614ac157614ac1614a9b565b9052565b60208101610c158284614ab1565b600060208284031215614ae557600080fd5b813567ffffffffffffffff811115614afc57600080fd5b820160a08185031215613dd857600080fd5b803563ffffffff8116811461401357600080fd5b600060a08284031215614b3457600080fd5b614b3c613f05565b8235614b4781613fe6565b8152614b5560208401614b0e565b6020820152614b6660408401614b0e565b6040820152614b7760608401614b0e565b60608201526080830135614b8a81613fe6565b60808201529392505050565b600080600060408486031215614bab57600080fd5b833567ffffffffffffffff80821115614bc357600080fd5b614bcf8783880161437f565b94506020860135915080821115614be557600080fd5b50614a5b8682870161491c565b803560ff8116811461401357600080fd5b600060208284031215614c1557600080fd5b610c1282614bf2565b60008151808452602080850194506020840160005b83811015614c585781516001600160a01b031687529582019590820190600101614c33565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614cb260e0840182614c1e565b90506040840151601f198483030160c0850152614ccf8282614c1e565b95945050505050565b60008060408385031215614ceb57600080fd5b614cf483613ffb565b946020939093013593505050565b60008060208385031215614d1557600080fd5b823567ffffffffffffffff80821115614d2d57600080fd5b818501915085601f830112614d4157600080fd5b813581811115614d5057600080fd5b8660208260061b8501011115614d6557600080fd5b60209290920196919550909350505050565b600060208284031215614d8957600080fd5b610c1282613ffb565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136cc60a084018261488a565b600060208284031215614df257600080fd5b8135613dd881613fe6565b600082601f830112614e0e57600080fd5b81356020614e1e61407883613fc2565b8083825260208201915060208460051b870101935086841115614e4057600080fd5b602086015b848110156120c1578035614e5881613fe6565b8352918301918301614e45565b60006020808385031215614e7857600080fd5b823567ffffffffffffffff80821115614e9057600080fd5b818501915085601f830112614ea457600080fd5b8135614eb261407882613fc2565b81815260059190911b83018401908481019088831115614ed157600080fd5b8585015b838110156141c157803585811115614eec57600080fd5b860160c0818c03601f19011215614f035760008081fd5b614f0b613f28565b8882013581526040614f1e818401614bf2565b8a8301526060614f2f818501614bf2565b8284015260809150614f42828501614026565b9083015260a08381013589811115614f5a5760008081fd5b614f688f8d83880101614dfd565b838501525060c0840135915088821115614f825760008081fd5b614f908e8c84870101614dfd565b9083015250845250918601918601614ed5565b600060208284031215614fb557600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b80356001600160e01b038116811461401357600080fd5b600082601f830112614ffa57600080fd5b8135602061500a61407883613fc2565b82815260069290921b8401810191818101908684111561502957600080fd5b8286015b848110156120c157604081890312156150465760008081fd5b61504e613f4b565b61505782613ffb565b8152615064858301614fd2565b8186015283529183019160400161502d565b600082601f83011261508757600080fd5b8135602061509761407883613fc2565b82815260079290921b840181019181810190868411156150b657600080fd5b8286015b848110156120c15780880360808112156150d45760008081fd5b6150dc613f6e565b6150e583613ffb565b8152604080601f19840112156150fb5760008081fd5b615103613f4b565b9250615110878501613ffb565b835261511d818501613ffb565b83880152818701929092526060830135918101919091528352918301916080016150ba565b6000602080838503121561515557600080fd5b823567ffffffffffffffff8082111561516d57600080fd5b8185019150604080838803121561518357600080fd5b61518b613f4b565b83358381111561519a57600080fd5b84016040818a0312156151ac57600080fd5b6151b4613f4b565b8135858111156151c357600080fd5b8201601f81018b136151d457600080fd5b80356151e261407882613fc2565b81815260069190911b8201890190898101908d83111561520157600080fd5b928a01925b828410156152515787848f03121561521e5760008081fd5b615226613f4b565b843561523181613fe6565b815261523e858d01614fd2565b818d0152825292870192908a0190615206565b84525050508187013593508484111561526957600080fd5b6152758a858401614fe9565b818801528252508385013591508282111561528f57600080fd5b61529b88838601615076565b85820152809550505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b8181101561530457835180516001600160a01b031684528501516001600160e01b03168584015292840192918501916001016152cd565b50508583015187820388850152805180835290840192506000918401905b8083101561535e578351805167ffffffffffffffff1683528501516001600160e01b031685830152928401926001929092019190850190615322565b50979650505050505050565b602081526000610c1260208301846152ad565b67ffffffffffffffff8316815260608101613dd86020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156153e9576153e96153b2565b5092915050565b60006020808352606084516040808487015261540f60608701836152ad565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141c157845167ffffffffffffffff81511683528781015161546f89850182805167ffffffffffffffff908116835260209182015116910152565b50840151828701529386019360019290920191608090910190615430565b60006020828403121561549f57600080fd5b813567ffffffffffffffff8111156154b657600080fd5b6136cc84828501614615565b81810381811115610c1557610c156153b2565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff80841680615506576155066154d5565b92169190910692915050565b8082028115828204841417610c1557610c156153b2565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261555d60a087018261488a565b905060608501518682036060880152615576828261488a565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561535e57835180516001600160a01b0316835286015186830152928501926001929092019190840190615599565b602081526000610c126020830184615529565b6080815260006155f16080830187615529565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561562f57600080fd5b835161563a81614018565b602085015190935067ffffffffffffffff81111561565757600080fd5b8401601f8101861361566857600080fd5b805161567661407882614031565b81815287602083850101111561568b57600080fd5b61569c826020830160208601614866565b809450505050604084015190509250925092565b6000604082840312156156c257600080fd5b6156ca613f4b565b6156d383613ffb565b8152602083013560208201528091505092915050565b600181811c908216806156fd57607f821691505b60208210810361571d57634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561573557600080fd5b8151613dd881614018565b601f821115610780576000816000526020600020601f850160051c810160208610156157695750805b601f850160051c820191505b818110156124db57828155600101615775565b815167ffffffffffffffff8111156157a2576157a2613ec6565b6157b6816157b084546156e9565b84615740565b602080601f8311600181146157eb57600084156157d35750858301515b600019600386901b1c1916600185901b1785556124db565b600085815260208120601f198616915b8281101561581a578886015182559484019460019091019084016157fb565b50858210156158385787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c1660608501525060018085016080808601526000815461589a816156e9565b8060a089015260c060018316600081146158bb57600181146158d757615907565b60ff19841660c08b015260c083151560051b8b01019450615907565b85600052602060002060005b848110156158fe5781548c82018501529088019089016158e3565b8b0160c0019550505b50929998505050505050505050565b80820180821115610c1557610c156153b2565b60ff8181168382160190811115610c1557610c156153b2565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff80841680615981576159816154d5565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126159c257600080fd5b83018035915067ffffffffffffffff8211156159dd57600080fd5b60200191503681900382131561383f57600080fd5b6020810160058310615a0657615a06614a9b565b91905290565b60ff81811683821602908116908181146153e9576153e96153b2565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a805784546001600160a01b031683526001948501949284019201615a5b565b50508481036060860152865180825290820192508187019060005b81811015615ac05782516001600160a01b031685529383019391830191600101615a9b565b50505060ff851660808501525090506120c3565b600067ffffffffffffffff808616835280851660208401525060606040830152614ccf606083018461488a565b8281526040602082015260006136cc604083018461488a565b67ffffffffffffffff848116825283166020820152606081016136cc6040830184614ab1565b615b4a8185614ab1565b606060208201526000615b60606083018561488a565b9050826040830152949350505050565b600060208284031215615b8257600080fd5b8151613dd881613fe6565b6020815260008251610100806020850152615bac61012085018361488a565b91506020850151615bc9604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615c0360a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615c20848361488a565b935060c08701519150808685030160e0870152615c3d848361488a565b935060e08701519150808685030183870152506120c3838261488a565b600060208284031215615c6c57600080fd5b5051919050565b600060ff821660ff8103615c8957615c896153b2565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c3608083018461488a565b86815260c060208201526000615cde60c083018861488a565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615dca57601f19868403018952815160a08151818652615d5b8287018261488a565b9150508582015185820387870152615d73828261488a565b91505060408083015186830382880152615d8d838261488a565b92505050606080830151818701525060808083015192508582038187015250615db6818361488a565b9a86019a9450505090830190600101615d35565b5090979650505050505050565b602081526000610c126020830184615d18565b60008282518085526020808601955060208260051b8401016020860160005b84811015615dca57601f19868403018952615e2583835161488a565b98840198925090830190600101615e09565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615e9f61018085018361488a565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615edc848361488a565b935060608801519150615efb6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615f228282615d18565b9150508281036020840152614ccf8185615dea56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162006c4a38038062006c4a8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615f7462000cd6600039600081816102660152612a010152600081816102370152612f1d0152600081816102080152818161142b015261196d0152600081816101d801526125f00152600081816117f3015261183f0152615f746000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063ccd37ba31161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063ccd37ba31461050b578063d2a15d3514610550578063e9d68a8e1461056357600080fd5b8063991a5018116100bd578063991a5018146104c5578063a80036b4146104d8578063c673e584146104eb57600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b8063311cd5131161012f5780635e36480c116101145780635e36480c146103785780637437ff9f1461039857806379ba50971461049457600080fd5b8063311cd513146103495780633f4b04aa1461035c57600080fd5b806306285c691161016057806306285c69146101a4578063181f5a77146102ed5780632d04ab761461033657600080fd5b806304666f9c1461017c57806305d938b514610191575b600080fd5b61018f61018a3660046140d8565b6105cc565b005b61018f61019f366004614764565b6105e0565b61029660408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102e49190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103296040518060400160405280601181526020017f4f666652616d7020312e362e302d64657600000000000000000000000000000081525081565b6040516102e491906148df565b61018f61034436600461498a565b610785565b61018f610357366004614a3d565b610b5c565b60095460405167ffffffffffffffff90911681526020016102e4565b61038b610386366004614a91565b610bc5565b6040516102e49190614aee565b6104376040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102e49190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610c1b565b61018f610177366004614afc565b6000546040516001600160a01b0390911681526020016102e4565b61018f6104d3366004614b4b565b610cd9565b61018f6104e6366004614bbf565b610cea565b6104fe6104f9366004614c2c565b61105d565b6040516102e49190614c8c565b610542610519366004614d01565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102e4565b61018f61055e366004614d2b565b6111bb565b610576610571366004614da0565b611275565b6040516102e49190614dbb565b61018f610591366004614e09565b611382565b61018f6105a4366004614e8e565b611393565b6105bc6105b7366004614fcc565b6113d5565b60405190151581526020016102e4565b6105d4611496565b6105dd816114f2565b50565b6105e86117f0565b815181518114610624576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8181101561077557600084828151811061064357610643614fe5565b6020026020010151905060008160200151519050600085848151811061066b5761066b614fe5565b60200260200101519050805182146106af576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b828110156107665760008282815181106106ce576106ce614fe5565b602002602001015190508060001461075d57846020015182815181106106f6576106f6614fe5565b60200260200101516080015181101561075d5784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064015b60405180910390fd5b506001016106b2565b50505050806001019050610627565b506107808383611871565b505050565b60006107938789018961516b565b805151519091501515806107ac57508051602001515115155b156108ac5760095460208a01359067ffffffffffffffff8083169116101561086b576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f92610834929101615393565b600060405180830381600087803b15801561084e57600080fd5b505af1158015610862573d6000803e3d6000fd5b505050506108aa565b8160200151516000036108aa576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b816020015151811015610aa5576000826020015182815181106108d4576108d4614fe5565b602002602001015190506000816000015190506108f081611921565b60006108fb82611a23565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061093f575060208084015190810151905167ffffffffffffffff9182169116115b1561097f57825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107549291906004016153a6565b6040830151806109bb576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff16600090815260086020908152604080832084845290915290205415610a2e5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101829052604401610754565b6020808501510151610a419060016153f1565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff9283160217909255925116600090815260086020908152604080832094835293905291909120429055506001016108af565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610ad59190615419565b60405180910390a1610b5160008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b9250611a8a915050565b505050505050505050565b610b9c610b6b828401846154b6565b6040805160008082526020820190925290610b96565b6060815260200190600190039081610b815790505b50611871565b604080516000808252602082019092529050610bbf600185858585866000611a8a565b50505050565b6000610bd3600160046154eb565b6002610be0608085615514565b67ffffffffffffffff16610bf4919061553b565b610bfe8585611e01565b901c166003811115610c1257610c12614ac4565b90505b92915050565b6001546001600160a01b03163314610c755760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610754565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ce1611496565b6105dd81611e48565b333014610d23576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281610d60565b6040805180820190915260008082526020820152815260200190600190039081610d395790505b5060a08501515190915015610d9457610d918460a00151856020015186606001518760000151602001518787611fae565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff1681830152808701518351600094840192610dd09291016148df565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015610edd576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a190610e4a9085906004016155f4565b600060405180830381600087803b158015610e6457600080fd5b505af1925050508015610e75575060015b610edd573d808015610ea3576040519150601f19603f3d011682016040523d82523d6000602084013e610ea8565b606091505b50806040517f09c2532500000000000000000000000000000000000000000000000000000000815260040161075491906148df565b604086015151158015610ef257506080860151155b80610f09575060608601516001600160a01b03163b155b80610f4957506060860151610f47906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120cd565b155b15610f5657505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf9798392610fce9289926113889291600401615607565b6000604051808303816000875af1158015610fed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110159190810190615643565b50915091508161105357806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161075491906148df565b5050505050505050565b6110a06040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c08201529485529182018054845181840281018401909552808552929385830193909283018282801561114957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161112b575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156111ab57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161118d575b5050505050815250509050919050565b6111c3611496565b60005b818110156107805760008383838181106111e2576111e2614fe5565b9050604002018036038101906111f891906156d9565b905061120781602001516113d5565b61126c57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b506001016111c6565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b90920490921694830194909452600184018054939492939184019161130290615712565b80601f016020809104026020016040519081016040528092919081815260200182805461132e90615712565b80156111ab5780601f10611350576101008083540402835291602001916111ab565b820191906000526020600020905b81548152906001019060200180831161135e57505050919092525091949350505050565b61138a611496565b6105dd816120e9565b61139b611496565b60005b81518110156113d1576113c98282815181106113bc576113bc614fe5565b602002602001015161219f565b60010161139e565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611472573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c15919061574c565b6000546001600160a01b031633146114f05760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610754565b565b60005b81518110156113d157600082828151811061151257611512614fe5565b602002602001015190506000816020015190508067ffffffffffffffff16600003611569576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611591576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115bc90615712565b80601f01602080910402602001604051908101604052809291908181526020018280546115e890615712565b80156116355780601f1061160a57610100808354040283529160200191611635565b820191906000526020600020905b81548152906001019060200180831161161857829003601f168201915b5050505050905060008460600151905081516000036116ed578051600003611670576040516342bcdf7f60e11b815260040160405180910390fd5b6001830161167e82826157b1565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611740565b8080519060200120828051906020012014611740576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610754565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117d8908690615871565b60405180910390a250505050508060010190506114f5565b467f0000000000000000000000000000000000000000000000000000000000000000146114f0576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610754565b81516000036118ab576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b845181101561191a576119128582815181106118e0576118e0614fe5565b60200260200101518461190c578583815181106118ff576118ff614fe5565b60200260200101516124e3565b836124e3565b6001016118c2565b5050505050565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa1580156119bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e0919061574c565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610754565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610c15576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610754565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611ae98760a461593f565b9050826060015115611b31578451611b0290602061553b565b8651611b0f90602061553b565b611b1a9060a061593f565b611b24919061593f565b611b2e908261593f565b90505b368114611b73576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610754565b5081518114611bbb5781516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610754565b611bc36117f0565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611c1157611c11614ac4565b6002811115611c2257611c22614ac4565b9052509050600281602001516002811115611c3f57611c3f614ac4565b148015611c935750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611c7b57611c7b614fe5565b6000918252602090912001546001600160a01b031633145b611cc9576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611dab576020820151611ce4906001615952565b60ff16855114611d20576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611d5b576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611d6d92919061596b565b604051908190038120611d84918b9060200161597b565b604051602081830303815290604052805190602001209050611da98a82888888612caf565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b67ffffffffffffffff8216600090815260076020526040812081611e2660808561598f565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b80516001600160a01b0316611e70576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fca57611fca613eef565b60405190808252806020026020018201604052801561200f57816020015b6040805180820190915260008082526020820152815260200190600190039081611fe85790505b50905060005b87518110156120c15761209c88828151811061203357612033614fe5565b602002602001015188888888888781811061205057612050614fe5565b905060200281019061206291906159b6565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612ebc92505050565b8282815181106120ae576120ae614fe5565b6020908102919091010152600101612015565b505b9695505050505050565b60006120d883613261565b8015610c125750610c1283836132c5565b336001600160a01b038216036121415760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610754565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ca576000604051631b3fab5160e11b81526004016107549190615a1b565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223757606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff90921691909117905561228c565b6060840151600182015460ff620100009091041615159015151461228c576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff84166004820152602401610754565b60a08401518051601f60ff821611156122bb576001604051631b3fab5160e11b81526004016107549190615a1b565b612321858560030180548060200260200160405190810160405280929190818152602001828054801561231757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122f9575b5050505050613380565b8560600151156124505761238f8585600201805480602002602001604051908101604052809291908181526020018280548015612317576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122f9575050505050613380565b608086015180516123a99060028701906020840190613e49565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f1015612409576002604051631b3fab5160e11b81526004016107549190615a1b565b6040880151612419906003615a35565b60ff168160ff1611612441576003604051631b3fab5160e11b81526004016107549190615a1b565b61244d878360016133e9565b50505b61245c858360026133e9565b81516124719060038601906020850190613e49565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ca938a939260028b01929190615a51565b60405180910390a16124db85613569565b505050505050565b81516124ee81611921565b60006124f982611a23565b602085015151909150600081900361253c576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461257a576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561259557612595613eef565b6040519080825280602002602001820160405280156125be578160200160208202803683370190505b50905060005b82811015612733576000876020015182815181106125e4576125e4614fe5565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461267757805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610754565b61270d8186600101805461268a90615712565b80601f01602080910402602001604051908101604052809291908181526020018280546126b690615712565b80156127035780601f106126d857610100808354040283529160200191612703565b820191906000526020600020905b8154815290600101906020018083116126e657829003601f168201915b5050505050613585565b83838151811061271f5761271f614fe5565b6020908102919091010152506001016125c4565b50600061274a858389606001518a608001516136a7565b905080600003612792576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610754565b8551151560005b84811015610b515760005a905060008a6020015183815181106127be576127be614fe5565b6020026020010151905060006127dc8a836000015160600151610bc5565b905060008160038111156127f2576127f2614ac4565b148061280f5750600381600381111561280d5761280d614ac4565b145b612867578151606001516040805167ffffffffffffffff808e16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a1505050612ca7565b841561293757600454600090600160a01b900463ffffffff1661288a88426154eb565b11905080806128aa575060038260038111156128a8576128a8614ac4565b145b6128ec576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8c166004820152602401610754565b8b85815181106128fe576128fe614fe5565b6020026020010151600014612931578b858151811061291f5761291f614fe5565b60200260200101518360800181815250505b50612998565b600081600381111561294b5761294b614ac4565b14612998578151606001516040805167ffffffffffffffff808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612857565b81516080015167ffffffffffffffff1615612a875760008160038111156129c1576129c1614ac4565b03612a875781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612a38928f929190600401615afd565b6020604051808303816000875af1158015612a57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7b919061574c565b612a8757505050612ca7565b60008c604001518581518110612a9f57612a9f614fe5565b6020026020010151905080518360a001515114612b03578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808e1660048301529091166024820152604401610754565b612b178b84600001516060015160016136fd565b600080612b2485846137a5565b91509150612b3b8d866000015160600151846136fd565b8715612bab576003826003811115612b5557612b55614ac4565b03612bab576000846003811115612b6e57612b6e614ac4565b14612bab578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261075491908390600401615b2a565b6002826003811115612bbf57612bbf614ac4565b14612c19576003826003811115612bd857612bd8614ac4565b14612c19578451606001516040517f926c5a3e000000000000000000000000000000000000000000000000000000008152610754918f918590600401615b43565b84600001516000015185600001516060015167ffffffffffffffff168e67ffffffffffffffff167f05665fe9ad095383d018353f4cbcba77e84db27dd215081bbf7cdf9ae6fbe48b8d8b81518110612c7357612c73614fe5565b602002602001015186865a612c88908e6154eb565b604051612c989493929190615b69565b60405180910390a45050505050505b600101612799565b612cb7613ebb565b835160005b81811015611053576000600188868460208110612cdb57612cdb614fe5565b612ce891901a601b615952565b898581518110612cfa57612cfa614fe5565b6020026020010151898681518110612d1457612d14614fe5565b602002602001015160405160008152602001604052604051612d52949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612d74573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b03851683528152858220858701909652855480841686529397509095509293928401916101009004166002811115612dd557612dd5614ac4565b6002811115612de657612de6614ac4565b9052509050600181602001516002811115612e0357612e03614ac4565b14612e3a576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f8110612e5157612e51614fe5565b602002015115612e8d576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f8110612ea857612ea8614fe5565b911515602090920201525050600101612cbc565b60408051808201909152600080825260208201526000612edf876020015161386f565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f889190615ba0565b90506001600160a01b0381161580612fd05750612fce6001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120cd565b155b15613012576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610754565b60045460009081906130349089908690600160e01b900463ffffffff16613915565b9150915060008060006131016040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b8152506040516024016130b29190615bbd565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a43565b9250925092508261314057816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161075491906148df565b81516020146131885781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610754565b60008280602001905181019061319e9190615c8a565b9050866001600160a01b03168c6001600160a01b0316146132335760006131cf8d8a6131ca868a6154eb565b613915565b509050868110806131e95750816131e688836154eb565b14155b15613231576040517fa966e21f000000000000000000000000000000000000000000000000000000008152600481018390526024810188905260448101829052606401610754565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b600061328d827f01ffc9a7000000000000000000000000000000000000000000000000000000006132c5565b8015610c1557506132be827fffffffff000000000000000000000000000000000000000000000000000000006132c5565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015613369575060208210155b80156133755750600081115b979650505050505050565b60005b81518110156107805760ff8316600090815260036020526040812083519091908490849081106133b5576133b5614fe5565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613383565b60005b82518160ff161015610bbf576000838260ff168151811061340f5761340f614fe5565b602002602001015190506000600281111561342c5761342c614ac4565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561346b5761346b614ac4565b1461348c576004604051631b3fab5160e11b81526004016107549190615a1b565b6001600160a01b0381166134cc576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134f2576134f2614ac4565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561354f5761354f614ac4565b0217905550905050508061356290615ca3565b90506133ec565b60ff81166105dd576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936135cb937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615cc2565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976136149794969395929491939101615cf5565b604051602081830303815290604052805190602001208560400151805190602001208660a0015160405160200161364b9190615e07565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b6000806136b5858585613b69565b90506136c0816113d5565b6136ce5760009150506136f5565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b6000600261370c608085615514565b67ffffffffffffffff16613720919061553b565b9050600061372e8585611e01565b90508161373d600160046154eb565b901b19168183600381111561375457613754614ac4565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161378360808861598f565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fa80036b4000000000000000000000000000000000000000000000000000000008152600090606090309063a80036b4906137e99087908790600401615e67565b600060405180830381600087803b15801561380357600080fd5b505af1925050508015613814575060015b613853573d808015613842576040519150601f19603f3d011682016040523d82523d6000602084013e613847565b606091505b50600392509050613868565b50506040805160208101909152600081526002905b9250929050565b600081516020146138ae57816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161075491906148df565b6000828060200190518101906138c49190615c8a565b90506001600160a01b038111806138dc575061040081105b15610c1557826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161075491906148df565b600080600080600061398f8860405160240161394091906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a43565b925092509250826139ce57816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161075491906148df565b6020825114613a165781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610754565b81806020019051810190613a2a9190615c8a565b613a3482886154eb565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a6657613a66613eef565b6040519080825280601f01601f191660200182016040528015613a90576020820181803683370190505b509150863b613ac3577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613af6577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613b2f577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b525750835b808352806000602085013e50955095509592505050565b8251825160009190818303613baa576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613bbe57506101018111155b613bdb576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613c05576040516309bde33960e01b815260040160405180910390fd5b80600003613c325786600081518110613c2057613c20614fe5565b60200260200101519350505050613e01565b60008167ffffffffffffffff811115613c4d57613c4d613eef565b604051908082528060200260200182016040528015613c76578160200160208202803683370190505b50905060008080805b85811015613da05760006001821b8b811603613cda5788851015613cc3578c5160018601958e918110613cb457613cb4614fe5565b60200260200101519050613cfc565b8551600185019487918110613cb457613cb4614fe5565b8b5160018401938d918110613cf157613cf1614fe5565b602002602001015190505b600089861015613d2c578d5160018701968f918110613d1d57613d1d614fe5565b60200260200101519050613d4e565b8651600186019588918110613d4357613d43614fe5565b602002602001015190505b82851115613d6f576040516309bde33960e01b815260040160405180910390fd5b613d798282613e08565b878481518110613d8b57613d8b614fe5565b60209081029190910101525050600101613c7f565b506001850382148015613db257508683145b8015613dbd57508581145b613dda576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613def57613def614fe5565b60200260200101519750505050505050505b9392505050565b6000818310613e2057613e1b8284613e26565b610c12565b610c1283835b604080516001602082015290810183905260608101829052600090608001613689565b828054828255906000526020600020908101928215613eab579160200282015b82811115613eab578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e69565b50613eb7929150613eda565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613eb75760008155600101613edb565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613f2857613f28613eef565b60405290565b60405160a0810167ffffffffffffffff81118282101715613f2857613f28613eef565b60405160c0810167ffffffffffffffff81118282101715613f2857613f28613eef565b6040805190810167ffffffffffffffff81118282101715613f2857613f28613eef565b6040516060810167ffffffffffffffff81118282101715613f2857613f28613eef565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fe357613fe3613eef565b604052919050565b600067ffffffffffffffff82111561400557614005613eef565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461403c57600080fd5b919050565b80151581146105dd57600080fd5b803561403c81614041565b600067ffffffffffffffff82111561407457614074613eef565b50601f01601f191660200190565b600082601f83011261409357600080fd5b81356140a66140a18261405a565b613fba565b8181528460208386010111156140bb57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140eb57600080fd5b823567ffffffffffffffff8082111561410357600080fd5b818501915085601f83011261411757600080fd5b81356141256140a182613feb565b81815260059190911b8301840190848101908883111561414457600080fd5b8585015b838110156141ea578035858111156141605760008081fd5b86016080818c03601f19018113156141785760008081fd5b614180613f05565b8983013561418d8161400f565b8152604061419c848201614024565b8b8301526060808501356141af81614041565b838301529284013592898411156141c857600091508182fd5b6141d68f8d86880101614082565b908301525085525050918601918601614148565b5098975050505050505050565b600060a0828403121561420957600080fd5b614211613f2e565b90508135815261422360208301614024565b602082015261423460408301614024565b604082015261424560608301614024565b606082015261425660808301614024565b608082015292915050565b803561403c8161400f565b600082601f83011261427d57600080fd5b8135602061428d6140a183613feb565b82815260059290921b840181019181810190868411156142ac57600080fd5b8286015b848110156120c157803567ffffffffffffffff808211156142d15760008081fd5b818901915060a080601f19848d030112156142ec5760008081fd5b6142f4613f2e565b87840135838111156143065760008081fd5b6143148d8a83880101614082565b8252506040808501358481111561432b5760008081fd5b6143398e8b83890101614082565b8a84015250606080860135858111156143525760008081fd5b6143608f8c838a0101614082565b838501525060809150818601358184015250828501359250838311156143865760008081fd5b6143948d8a85880101614082565b9082015286525050509183019183016142b0565b600061014082840312156143bb57600080fd5b6143c3613f51565b90506143cf83836141f7565b815260a082013567ffffffffffffffff808211156143ec57600080fd5b6143f885838601614082565b602084015260c084013591508082111561441157600080fd5b61441d85838601614082565b604084015261442e60e08501614261565b6060840152610100840135608084015261012084013591508082111561445357600080fd5b506144608482850161426c565b60a08301525092915050565b600082601f83011261447d57600080fd5b8135602061448d6140a183613feb565b82815260059290921b840181019181810190868411156144ac57600080fd5b8286015b848110156120c157803567ffffffffffffffff8111156144d05760008081fd5b6144de8986838b01016143a8565b8452509183019183016144b0565b600082601f8301126144fd57600080fd5b8135602061450d6140a183613feb565b82815260059290921b8401810191818101908684111561452c57600080fd5b8286015b848110156120c157803567ffffffffffffffff8082111561455057600080fd5b818901915089603f83011261456457600080fd5b858201356145746140a182613feb565b81815260059190911b830160400190878101908c83111561459457600080fd5b604085015b838110156145cd578035858111156145b057600080fd5b6145bf8f6040838a0101614082565b845250918901918901614599565b50875250505092840192508301614530565b600082601f8301126145f057600080fd5b813560206146006140a183613feb565b8083825260208201915060208460051b87010193508684111561462257600080fd5b602086015b848110156120c15780358352918301918301614627565b600082601f83011261464f57600080fd5b8135602061465f6140a183613feb565b82815260059290921b8401810191818101908684111561467e57600080fd5b8286015b848110156120c157803567ffffffffffffffff808211156146a35760008081fd5b818901915060a080601f19848d030112156146be5760008081fd5b6146c6613f2e565b6146d1888501614024565b8152604080850135848111156146e75760008081fd5b6146f58e8b8389010161446c565b8a840152506060808601358581111561470e5760008081fd5b61471c8f8c838a01016144ec565b83850152506080915081860135858111156147375760008081fd5b6147458f8c838a01016145df565b9184019190915250919093013590830152508352918301918301614682565b600080604080848603121561477857600080fd5b833567ffffffffffffffff8082111561479057600080fd5b61479c8783880161463e565b94506020915081860135818111156147b357600080fd5b8601601f810188136147c457600080fd5b80356147d26140a182613feb565b81815260059190911b8201840190848101908a8311156147f157600080fd5b8584015b8381101561487d5780358681111561480d5760008081fd5b8501603f81018d1361481f5760008081fd5b8781013561482f6140a182613feb565b81815260059190911b82018a0190898101908f83111561484f5760008081fd5b928b01925b8284101561486d5783358252928a0192908a0190614854565b86525050509186019186016147f5565b50809750505050505050509250929050565b60005b838110156148aa578181015183820152602001614892565b50506000910152565b600081518084526148cb81602086016020860161488f565b601f01601f19169290920160200192915050565b602081526000610c1260208301846148b3565b8060608101831015610c1557600080fd5b60008083601f84011261491557600080fd5b50813567ffffffffffffffff81111561492d57600080fd5b60208301915083602082850101111561386857600080fd5b60008083601f84011261495757600080fd5b50813567ffffffffffffffff81111561496f57600080fd5b6020830191508360208260051b850101111561386857600080fd5b60008060008060008060008060e0898b0312156149a657600080fd5b6149b08a8a6148f2565b9750606089013567ffffffffffffffff808211156149cd57600080fd5b6149d98c838d01614903565b909950975060808b01359150808211156149f257600080fd5b6149fe8c838d01614945565b909750955060a08b0135915080821115614a1757600080fd5b50614a248b828c01614945565b999c989b50969995989497949560c00135949350505050565b600080600060808486031215614a5257600080fd5b614a5c85856148f2565b9250606084013567ffffffffffffffff811115614a7857600080fd5b614a8486828701614903565b9497909650939450505050565b60008060408385031215614aa457600080fd5b614aad83614024565b9150614abb60208401614024565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614aea57614aea614ac4565b9052565b60208101610c158284614ada565b600060208284031215614b0e57600080fd5b813567ffffffffffffffff811115614b2557600080fd5b820160a08185031215613e0157600080fd5b803563ffffffff8116811461403c57600080fd5b600060a08284031215614b5d57600080fd5b614b65613f2e565b8235614b708161400f565b8152614b7e60208401614b37565b6020820152614b8f60408401614b37565b6040820152614ba060608401614b37565b60608201526080830135614bb38161400f565b60808201529392505050565b600080600060408486031215614bd457600080fd5b833567ffffffffffffffff80821115614bec57600080fd5b614bf8878388016143a8565b94506020860135915080821115614c0e57600080fd5b50614a8486828701614945565b803560ff8116811461403c57600080fd5b600060208284031215614c3e57600080fd5b610c1282614c1b565b60008151808452602080850194506020840160005b83811015614c815781516001600160a01b031687529582019590820190600101614c5c565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614cdb60e0840182614c47565b90506040840151601f198483030160c0850152614cf88282614c47565b95945050505050565b60008060408385031215614d1457600080fd5b614d1d83614024565b946020939093013593505050565b60008060208385031215614d3e57600080fd5b823567ffffffffffffffff80821115614d5657600080fd5b818501915085601f830112614d6a57600080fd5b813581811115614d7957600080fd5b8660208260061b8501011115614d8e57600080fd5b60209290920196919550909350505050565b600060208284031215614db257600080fd5b610c1282614024565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136f560a08401826148b3565b600060208284031215614e1b57600080fd5b8135613e018161400f565b600082601f830112614e3757600080fd5b81356020614e476140a183613feb565b8083825260208201915060208460051b870101935086841115614e6957600080fd5b602086015b848110156120c1578035614e818161400f565b8352918301918301614e6e565b60006020808385031215614ea157600080fd5b823567ffffffffffffffff80821115614eb957600080fd5b818501915085601f830112614ecd57600080fd5b8135614edb6140a182613feb565b81815260059190911b83018401908481019088831115614efa57600080fd5b8585015b838110156141ea57803585811115614f1557600080fd5b860160c0818c03601f19011215614f2c5760008081fd5b614f34613f51565b8882013581526040614f47818401614c1b565b8a8301526060614f58818501614c1b565b8284015260809150614f6b82850161404f565b9083015260a08381013589811115614f835760008081fd5b614f918f8d83880101614e26565b838501525060c0840135915088821115614fab5760008081fd5b614fb98e8c84870101614e26565b9083015250845250918601918601614efe565b600060208284031215614fde57600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b80356001600160e01b038116811461403c57600080fd5b600082601f83011261502357600080fd5b813560206150336140a183613feb565b82815260069290921b8401810191818101908684111561505257600080fd5b8286015b848110156120c1576040818903121561506f5760008081fd5b615077613f74565b61508082614024565b815261508d858301614ffb565b81860152835291830191604001615056565b600082601f8301126150b057600080fd5b813560206150c06140a183613feb565b82815260079290921b840181019181810190868411156150df57600080fd5b8286015b848110156120c15780880360808112156150fd5760008081fd5b615105613f97565b61510e83614024565b8152604080601f19840112156151245760008081fd5b61512c613f74565b9250615139878501614024565b8352615146818501614024565b83880152818701929092526060830135918101919091528352918301916080016150e3565b6000602080838503121561517e57600080fd5b823567ffffffffffffffff8082111561519657600080fd5b818501915060408083880312156151ac57600080fd5b6151b4613f74565b8335838111156151c357600080fd5b84016040818a0312156151d557600080fd5b6151dd613f74565b8135858111156151ec57600080fd5b8201601f81018b136151fd57600080fd5b803561520b6140a182613feb565b81815260069190911b8201890190898101908d83111561522a57600080fd5b928a01925b8284101561527a5787848f0312156152475760008081fd5b61524f613f74565b843561525a8161400f565b8152615267858d01614ffb565b818d0152825292870192908a019061522f565b84525050508187013593508484111561529257600080fd5b61529e8a858401615012565b81880152825250838501359150828211156152b857600080fd5b6152c48883860161509f565b85820152809550505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b8181101561532d57835180516001600160a01b031684528501516001600160e01b03168584015292840192918501916001016152f6565b50508583015187820388850152805180835290840192506000918401905b80831015615387578351805167ffffffffffffffff1683528501516001600160e01b03168583015292840192600192909201919085019061534b565b50979650505050505050565b602081526000610c1260208301846152d6565b67ffffffffffffffff8316815260608101613e016020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff818116838216019080821115615412576154126153db565b5092915050565b60006020808352606084516040808487015261543860608701836152d6565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141ea57845167ffffffffffffffff81511683528781015161549889850182805167ffffffffffffffff908116835260209182015116910152565b50840151828701529386019360019290920191608090910190615459565b6000602082840312156154c857600080fd5b813567ffffffffffffffff8111156154df57600080fd5b6136f58482850161463e565b81810381811115610c1557610c156153db565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff8084168061552f5761552f6154fe565b92169190910692915050565b8082028115828204841417610c1557610c156153db565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261558660a08701826148b3565b90506060850151868203606088015261559f82826148b3565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561538757835180516001600160a01b03168352860151868301529285019260019290920191908401906155c2565b602081526000610c126020830184615552565b60808152600061561a6080830187615552565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561565857600080fd5b835161566381614041565b602085015190935067ffffffffffffffff81111561568057600080fd5b8401601f8101861361569157600080fd5b805161569f6140a18261405a565b8181528760208385010111156156b457600080fd5b6156c582602083016020860161488f565b809450505050604084015190509250925092565b6000604082840312156156eb57600080fd5b6156f3613f74565b6156fc83614024565b8152602083013560208201528091505092915050565b600181811c9082168061572657607f821691505b60208210810361574657634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561575e57600080fd5b8151613e0181614041565b601f821115610780576000816000526020600020601f850160051c810160208610156157925750805b601f850160051c820191505b818110156124db5782815560010161579e565b815167ffffffffffffffff8111156157cb576157cb613eef565b6157df816157d98454615712565b84615769565b602080601f83116001811461581457600084156157fc5750858301515b600019600386901b1c1916600185901b1785556124db565b600085815260208120601f198616915b8281101561584357888601518255948401946001909101908401615824565b50858210156158615787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546158c381615712565b8060a089015260c060018316600081146158e4576001811461590057615930565b60ff19841660c08b015260c083151560051b8b01019450615930565b85600052602060002060005b848110156159275781548c820185015290880190890161590c565b8b0160c0019550505b50929998505050505050505050565b80820180821115610c1557610c156153db565b60ff8181168382160190811115610c1557610c156153db565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff808416806159aa576159aa6154fe565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126159eb57600080fd5b83018035915067ffffffffffffffff821115615a0657600080fd5b60200191503681900382131561386857600080fd5b6020810160058310615a2f57615a2f614ac4565b91905290565b60ff8181168382160290811690818114615412576154126153db565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615aa95784546001600160a01b031683526001948501949284019201615a84565b50508481036060860152865180825290820192508187019060005b81811015615ae95782516001600160a01b031685529383019391830191600101615ac4565b50505060ff851660808501525090506120c3565b600067ffffffffffffffff808616835280851660208401525060606040830152614cf860608301846148b3565b8281526040602082015260006136f560408301846148b3565b67ffffffffffffffff848116825283166020820152606081016136f56040830184614ada565b848152615b796020820185614ada565b608060408201526000615b8f60808301856148b3565b905082606083015295945050505050565b600060208284031215615bb257600080fd5b8151613e018161400f565b6020815260008251610100806020850152615bdc6101208501836148b3565b91506020850151615bf9604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615c3360a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615c5084836148b3565b935060c08701519150808685030160e0870152615c6d84836148b3565b935060e08701519150808685030183870152506120c383826148b3565b600060208284031215615c9c57600080fd5b5051919050565b600060ff821660ff8103615cb957615cb96153db565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c360808301846148b3565b86815260c060208201526000615d0e60c08301886148b3565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615dfa57601f19868403018952815160a08151818652615d8b828701826148b3565b9150508582015185820387870152615da382826148b3565b91505060408083015186830382880152615dbd83826148b3565b92505050606080830151818701525060808083015192508582038187015250615de681836148b3565b9a86019a9450505090830190600101615d65565b5090979650505050505050565b602081526000610c126020830184615d48565b60008282518085526020808601955060208260051b8401016020860160005b84811015615dfa57601f19868403018952615e558383516148b3565b98840198925090830190600101615e39565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615ecf6101808501836148b3565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615f0c84836148b3565b935060608801519150615f2b6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615f528282615d48565b9150508281036020840152614cf88185615e1a56fea164736f6c6343000818000a", } var OffRampABI = OffRampMetaData.ABI @@ -1201,6 +1201,7 @@ type OffRampExecutionStateChanged struct { SourceChainSelector uint64 SequenceNumber uint64 MessageId [32]byte + MessageHash [32]byte State uint8 ReturnData []byte GasUsed *big.Int @@ -2334,7 +2335,7 @@ func (OffRampDynamicConfigSet) Topic() common.Hash { } func (OffRampExecutionStateChanged) Topic() common.Hash { - return common.HexToHash("0xdc8ccbc35e0eebd81239bcd1971fcd53c7eb34034880142a0f43c809a458732f") + return common.HexToHash("0x05665fe9ad095383d018353f4cbcba77e84db27dd215081bbf7cdf9ae6fbe48b") } func (OffRampOwnershipTransferRequested) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 98fb5dd620..688818f694 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -23,7 +23,7 @@ multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRate multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin aa299e0c2659d53aad4eace4d66be0e734b1366008593669cf30361ff529da6a nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 6f64e1083b356c06ee66b9138e398b9c97a4cd3e8c9ec38cf3010cebc79af536 ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 -offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin 4c1965d8e60a5ce133f71d46102b6cb932edce4538da096b048477154fac9fc1 +offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin a3b8a9644f0d450dbf53d3371555dcc4084fb2eaf138a3797ef5cf73ed665bae onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 13927b48bd09b9ab2c62143973c747f8c2e1ebc9f95f17a61ace67a68c71ec75 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin c1c2f8a65c7ffd971899cae7fe62f2da57d09e936151e2b92163c4bebe699d6b price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin e7781d600c1bb7aa4620106af7f6e146a109b97f4cb6a7d06c9e15773340ecb2 From 68d13b7bfa53df836d538e7ec3bf04fdaacfc74c Mon Sep 17 00:00:00 2001 From: Josh Weintraub <26035072+jhweintraub@users.noreply.github.com> Date: Tue, 27 Aug 2024 18:04:17 -0400 Subject: [PATCH 232/432] Multi-Mechanism USDC Token Pools (#1280) ## Motivation Currently all USDC token transfers occur using Burn/Mint with calls to Circle's CCTP system for cross-chain transfers. Certain chains in CCIP have non-canonical USDC deployed and want to integrate the ability to use CCIP as a canonical bridge whereby canonical-USDC is locked on the source-chain and then minted on the destination chain. Then at a later date, when circle decides to add that chain to CCTP, the non-canonical USDC will be converted into canonical by burning the locked-tokens on the source-chain. To accomplish this, the token pool needs to be capable of identifying when tokens should be burned/minted with CCTP, or if they should use regular lock-release, and act accordingly. ## Solution `USDCTokenPool.sol` was been modified into a new file to allow for two different mechanisms to be used simultaneously. The primary mechanism, which is opt-out, and the secondary-mechanism which is opt in. These mechanisms are configured on a per-chain-selector basis, and must be manually enabled. In this implementation CCTP is the primary mechanism, and Lock/Release is the alternative mechanism. There are two new files 1. `HybridLockReleaseUSDCTokenPool.sol`, The actual implementation of the hybrid pool structure. 3. `USDCBridgeMigrator.sol`, which contains the logic necessary to conform to [Circle's migration policy guide](https://github.com/circlefin/stablecoin-evm/blob/master/doc/bridged_USDC_standard.md#transferring-the-roles-to-circle) --- contracts/gas-snapshots/ccip.gas-snapshot | 22 + .../USDC/HybridLockReleaseUSDCTokenPool.sol | 220 ++++++ .../ccip/pools/USDC/USDCBridgeMigrator.sol | 119 ++++ .../HybridLockReleaseUSDCTokenPool.t.sol | 661 ++++++++++++++++++ 4 files changed, 1022 insertions(+) create mode 100644 contracts/src/v0.8/ccip/pools/USDC/HybridLockReleaseUSDCTokenPool.sol create mode 100644 contracts/src/v0.8/ccip/pools/USDC/USDCBridgeMigrator.sol create mode 100644 contracts/src/v0.8/ccip/test/pools/HybridLockReleaseUSDCTokenPool.t.sol diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index c13660452d..5abff8ca4c 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -431,6 +431,28 @@ FeeQuoter_validatePoolReturnData:test_InvalidEVMAddressDestToken_Revert() (gas: FeeQuoter_validatePoolReturnData:test_ProcessPoolReturnData_Success() (gas: 73252) FeeQuoter_validatePoolReturnData:test_SourceTokenDataTooLarge_Revert() (gas: 107744) FeeQuoter_validatePoolReturnData:test_TokenAmountArraysMismatching_Revert() (gas: 40091) +HybridUSDCTokenPoolMigrationTests:test_LockOrBurn_LocKReleaseMechanism_then_switchToPrimary_Success() (gas: 208137) +HybridUSDCTokenPoolMigrationTests:test_LockOrBurn_PrimaryMechanism_Success() (gas: 135392) +HybridUSDCTokenPoolMigrationTests:test_LockOrBurn_WhileMigrationPause_Revert() (gas: 106624) +HybridUSDCTokenPoolMigrationTests:test_LockOrBurn_onLockReleaseMechanism_Success() (gas: 143884) +HybridUSDCTokenPoolMigrationTests:test_MintOrRelease_OnLockReleaseMechanism_Success() (gas: 230399) +HybridUSDCTokenPoolMigrationTests:test_MintOrRelease_OnLockReleaseMechanism_then_switchToPrimary_Success() (gas: 438259) +HybridUSDCTokenPoolMigrationTests:test_MintOrRelease_incomingMessageWithPrimaryMechanism() (gas: 269968) +HybridUSDCTokenPoolMigrationTests:test_burnLockedUSDC_invalidPermissions_Revert() (gas: 39124) +HybridUSDCTokenPoolMigrationTests:test_cancelExistingCCTPMigrationProposal() (gas: 31124) +HybridUSDCTokenPoolMigrationTests:test_cannotCancelANonExistentMigrationProposal() (gas: 12628) +HybridUSDCTokenPoolMigrationTests:test_cannotModifyLiquidityWithoutPermissions_Revert() (gas: 17133) +HybridUSDCTokenPoolMigrationTests:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 252432) +HybridUSDCTokenPoolMigrationTests:test_transferLiquidity_Success() (gas: 157049) +HybridUSDCTokenPoolMigrationTests:test_withdrawLiquidity_Success() (gas: 140780) +HybridUSDCTokenPoolTests:test_LockOrBurn_LocKReleaseMechanism_then_switchToPrimary_Success() (gas: 208102) +HybridUSDCTokenPoolTests:test_LockOrBurn_PrimaryMechanism_Success() (gas: 135365) +HybridUSDCTokenPoolTests:test_LockOrBurn_WhileMigrationPause_Revert() (gas: 106589) +HybridUSDCTokenPoolTests:test_LockOrBurn_onLockReleaseMechanism_Success() (gas: 143832) +HybridUSDCTokenPoolTests:test_MintOrRelease_OnLockReleaseMechanism_Success() (gas: 230365) +HybridUSDCTokenPoolTests:test_MintOrRelease_OnLockReleaseMechanism_then_switchToPrimary_Success() (gas: 438171) +HybridUSDCTokenPoolTests:test_MintOrRelease_incomingMessageWithPrimaryMechanism() (gas: 269912) +HybridUSDCTokenPoolTests:test_withdrawLiquidity_Success() (gas: 140774) LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Revert() (gas: 10970) LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Success() (gas: 17992) LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3368110) diff --git a/contracts/src/v0.8/ccip/pools/USDC/HybridLockReleaseUSDCTokenPool.sol b/contracts/src/v0.8/ccip/pools/USDC/HybridLockReleaseUSDCTokenPool.sol new file mode 100644 index 0000000000..f38127825d --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/USDC/HybridLockReleaseUSDCTokenPool.sol @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ILiquidityContainer} from "../../../liquiditymanager/interfaces/ILiquidityContainer.sol"; +import {ITokenMessenger} from "../USDC/ITokenMessenger.sol"; + +import {Pool} from "../../libraries/Pool.sol"; +import {TokenPool} from "../TokenPool.sol"; +import {USDCTokenPool} from "../USDC/USDCTokenPool.sol"; +import {USDCBridgeMigrator} from "./USDCBridgeMigrator.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +/// @notice A token pool for USDC which uses CCTP for supported chains and Lock/Release for all others +/// @dev The functionality from LockReleaseTokenPool.sol has been duplicated due to lack of compiler support for shared +/// constructors between parents +/// @dev The primary token mechanism in this pool is Burn/Mint with CCTP, with Lock/Release as the +/// secondary, opt in mechanism for chains not currently supporting CCTP. +contract HybridLockReleaseUSDCTokenPool is USDCTokenPool, USDCBridgeMigrator { + using SafeERC20 for IERC20; + using EnumerableSet for EnumerableSet.UintSet; + + event LiquidityTransferred(address indexed from, uint64 indexed remoteChainSelector, uint256 amount); + event LiquidityProviderSet( + address indexed oldProvider, address indexed newProvider, uint64 indexed remoteChainSelector + ); + + event LockReleaseEnabled(uint64 indexed remoteChainSelector); + event LockReleaseDisabled(uint64 indexed remoteChainSelector); + + error LanePausedForCCTPMigration(uint64 remoteChainSelector); + error TokenLockingNotAllowedAfterMigration(uint64 remoteChainSelector); + + /// @notice The address of the liquidity provider for a specific chain. + /// External liquidity is not required when there is one canonical token deployed to a chain, + /// and CCIP is facilitating mint/burn on all the other chains, in which case the invariant + /// balanceOf(pool) on home chain >= sum(totalSupply(mint/burn "wrapped" token) on all remote chains) should always hold + mapping(uint64 remoteChainSelector => address liquidityProvider) internal s_liquidityProvider; + + constructor( + ITokenMessenger tokenMessenger, + IERC20 token, + address[] memory allowlist, + address rmnProxy, + address router + ) USDCTokenPool(tokenMessenger, token, allowlist, rmnProxy, router) USDCBridgeMigrator(address(token), router) {} + + // ================================================================ + // │ Incoming/Outgoing Mechanisms | + // ================================================================ + + /// @notice Locks the token in the pool + /// @dev The _validateLockOrBurn check is an essential security check + function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + public + virtual + override + returns (Pool.LockOrBurnOutV1 memory) + { + // // If the alternative mechanism (L/R) for chains which have it enabled + if (!shouldUseLockRelease(lockOrBurnIn.remoteChainSelector)) { + return super.lockOrBurn(lockOrBurnIn); + } + + // Circle requires a supply-lock to prevent outgoing messages once the migration process begins. + // This prevents new outgoing messages once the migration has begun to ensure any the procedure runs as expected + if (s_proposedUSDCMigrationChain == lockOrBurnIn.remoteChainSelector) { + revert LanePausedForCCTPMigration(s_proposedUSDCMigrationChain); + } + + return _lockReleaseOutgoingMessage(lockOrBurnIn); + } + + /// @notice Release tokens from the pool to the recipient + /// @dev The _validateReleaseOrMint check is an essential security check + function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + public + virtual + override + returns (Pool.ReleaseOrMintOutV1 memory) + { + if (!shouldUseLockRelease(releaseOrMintIn.remoteChainSelector)) { + return super.releaseOrMint(releaseOrMintIn); + } + return _lockReleaseIncomingMessage(releaseOrMintIn); + } + + /// @notice Contains the alternative mechanism for incoming tokens, in this implementation is "Release" incoming tokens + function _lockReleaseIncomingMessage(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) + internal + virtual + returns (Pool.ReleaseOrMintOutV1 memory) + { + _validateReleaseOrMint(releaseOrMintIn); + + // Decrease internal tracking of locked tokens to ensure accurate accounting for burnLockedUSDC() migration + s_lockedTokensByChainSelector[releaseOrMintIn.remoteChainSelector] -= releaseOrMintIn.amount; + + // Release to the offRamp, which forwards it to the recipient + getToken().safeTransfer(releaseOrMintIn.receiver, releaseOrMintIn.amount); + + emit Released(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); + + return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + } + + /// @notice Contains the alternative mechanism, in this implementation is "Lock" on outgoing tokens + function _lockReleaseOutgoingMessage(Pool.LockOrBurnInV1 calldata lockOrBurnIn) + internal + virtual + returns (Pool.LockOrBurnOutV1 memory) + { + _validateLockOrBurn(lockOrBurnIn); + + // Increase internal accounting of locked tokens for burnLockedUSDC() migration + s_lockedTokensByChainSelector[lockOrBurnIn.remoteChainSelector] += lockOrBurnIn.amount; + + emit Locked(msg.sender, lockOrBurnIn.amount); + + return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); + } + + // ================================================================ + // │ Liquidity Management | + // ================================================================ + + /// @notice Gets LiquidityManager, can be address(0) if none is configured. + /// @return The current liquidity manager for the given chain selector + function getLiquidityProvider(uint64 remoteChainSelector) external view returns (address) { + return s_liquidityProvider[remoteChainSelector]; + } + + /// @notice Sets the LiquidityManager address. + /// @dev Only callable by the owner. + function setLiquidityProvider(uint64 remoteChainSelector, address liquidityProvider) external onlyOwner { + address oldProvider = s_liquidityProvider[remoteChainSelector]; + + s_liquidityProvider[remoteChainSelector] = liquidityProvider; + + emit LiquidityProviderSet(oldProvider, liquidityProvider, remoteChainSelector); + } + + /// @notice Adds liquidity to the pool for a specific chain. The tokens should be approved first. + /// @dev Liquidity is expected to be added on a per chain basis. Parties are expected to provide liquidity for their + /// own chain which implements non canonical USDC and liquidity is not shared across lanes. + /// @param amount The amount of liquidity to provide. + /// @param remoteChainSelector The chain for which liquidity is provided to. Necessary to ensure there's accurate + /// parity between locked USDC in this contract and the circulating supply on the remote chain + function provideLiquidity(uint64 remoteChainSelector, uint256 amount) external { + if (s_liquidityProvider[remoteChainSelector] != msg.sender) revert TokenPool.Unauthorized(msg.sender); + + s_lockedTokensByChainSelector[remoteChainSelector] += amount; + + i_token.safeTransferFrom(msg.sender, address(this), amount); + + emit ILiquidityContainer.LiquidityAdded(msg.sender, amount); + } + + /// @notice Removed liquidity to the pool. The tokens will be sent to msg.sender. + /// @param remoteChainSelector The chain where liquidity is being released. + /// @param amount The amount of liquidity to remove. + /// @dev The function should only be called if non canonical USDC on the remote chain has been burned and is not being + /// withdrawn on this chain, otherwise a mismatch may occur between locked token balance and remote circulating supply + /// which may block a potential future migration of the chain to CCTP. + function withdrawLiquidity(uint64 remoteChainSelector, uint256 amount) external { + if (s_liquidityProvider[remoteChainSelector] != msg.sender) revert TokenPool.Unauthorized(msg.sender); + + s_lockedTokensByChainSelector[remoteChainSelector] -= amount; + + i_token.safeTransfer(msg.sender, amount); + emit ILiquidityContainer.LiquidityRemoved(msg.sender, amount); + } + + /// @notice This function can be used to transfer liquidity from an older version of the pool to this pool. To do so + /// this pool will have to be set as the liquidity provider in the older version of the pool. This allows it to transfer the + /// funds in the old pool to the new pool. + /// @dev When upgrading a LockRelease pool, this function can be called at the same time as the pool is changed in the + /// TokenAdminRegistry. This allows for a smooth transition of both liquidity and transactions to the new pool. + /// Alternatively, when no multicall is available, a portion of the funds can be transferred to the new pool before + /// changing which pool CCIP uses, to ensure both pools can operate. Then the pool should be changed in the + /// TokenAdminRegistry, which will activate the new pool. All new transactions will use the new pool and its + /// liquidity. Finally, the remaining liquidity can be transferred to the new pool using this function one more time. + /// @param from The address of the old pool. + /// @param amount The amount of liquidity to transfer. + function transferLiquidity(address from, uint64 remoteChainSelector, uint256 amount) external onlyOwner { + HybridLockReleaseUSDCTokenPool(from).withdrawLiquidity(remoteChainSelector, amount); + + s_lockedTokensByChainSelector[remoteChainSelector] += amount; + + emit LiquidityTransferred(from, remoteChainSelector, amount); + } + + // ================================================================ + // │ Alt Mechanism Logic | + // ================================================================ + + /// @notice Return whether a lane should use the alternative L/R mechanism in the token pool. + /// @param remoteChainSelector the remote chain the lane is interacting with + /// @return bool Return true if the alternative L/R mechanism should be used + function shouldUseLockRelease(uint64 remoteChainSelector) public view virtual returns (bool) { + return s_shouldUseLockRelease[remoteChainSelector]; + } + + /// @notice Updates Updates designations for chains on whether to use primary or alt mechanism on CCIP messages + /// @param removes A list of chain selectors to disable Lock-Release, and enforce BM + /// @param adds A list of chain selectors to enable LR instead of BM + function updateChainSelectorMechanisms(uint64[] calldata removes, uint64[] calldata adds) external onlyOwner { + for (uint256 i = 0; i < removes.length; ++i) { + delete s_shouldUseLockRelease[removes[i]]; + emit LockReleaseDisabled(removes[i]); + } + + for (uint256 i = 0; i < adds.length; ++i) { + s_shouldUseLockRelease[adds[i]] = true; + emit LockReleaseEnabled(adds[i]); + } + } +} diff --git a/contracts/src/v0.8/ccip/pools/USDC/USDCBridgeMigrator.sol b/contracts/src/v0.8/ccip/pools/USDC/USDCBridgeMigrator.sol new file mode 100644 index 0000000000..827787f4cf --- /dev/null +++ b/contracts/src/v0.8/ccip/pools/USDC/USDCBridgeMigrator.sol @@ -0,0 +1,119 @@ +pragma solidity ^0.8.24; + +import {OwnerIsCreator} from "../../../shared/access/OwnerIsCreator.sol"; +import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; + +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; + +import {Router} from "../../Router.sol"; + +/// @notice Allows migration of a lane in a token pool from Lock/Release to CCTP supported Burn/Mint. Contract +/// functionality is based on hard requirements defined by Circle to allow future CCTP compatibility +/// @dev Once a migration for a lane has occured, it can never be reversed, and CCTP will be the mechanism forever. This makes the assumption that Circle will continue to support that lane indefinitely. +abstract contract USDCBridgeMigrator is OwnerIsCreator { + using EnumerableSet for EnumerableSet.UintSet; + + event CCTPMigrationProposed(uint64 remoteChainSelector); + event CCTPMigrationExecuted(uint64 remoteChainSelector, uint256 USDCBurned); + event CCTPMigrationCancelled(uint64 existingProposalSelector); + event CircleMigratorAddressSet(address migratorAddress); + + error onlyCircle(); + error ExistingMigrationProposal(); + error NoExistingMigrationProposal(); + error NoMigrationProposalPending(); + error InvalidChainSelector(uint64 remoteChainSelector); + + IBurnMintERC20 internal immutable i_USDC; + Router internal immutable i_router; + + address internal s_circleUSDCMigrator; + uint64 internal s_proposedUSDCMigrationChain; + + mapping(uint64 chainSelector => uint256 lockedBalance) internal s_lockedTokensByChainSelector; + + mapping(uint64 chainSelector => bool shouldUseLockRelease) internal s_shouldUseLockRelease; + + constructor(address token, address router) { + i_USDC = IBurnMintERC20(token); + i_router = Router(router); + } + + /// @notice Burn USDC locked for a specific lane so that destination USDC can be converted from + /// non-canonical to canonical USDC. + /// @dev This function can only be called by an address specified by the owner to be controlled by circle + /// @dev proposeCCTPMigration must be called first on an approved lane to execute properly. + /// @dev This function signature should NEVER be overwritten, otherwise it will be unable to be called by + /// circle to properly migrate USDC over to CCTP. + function burnLockedUSDC() public { + if (msg.sender != s_circleUSDCMigrator) revert onlyCircle(); + if (s_proposedUSDCMigrationChain == 0) revert ExistingMigrationProposal(); + + uint64 burnChainSelector = s_proposedUSDCMigrationChain; + uint256 tokensToBurn = s_lockedTokensByChainSelector[burnChainSelector]; + + // Even though USDC is a trusted call, ensure CEI by updating state first + delete s_lockedTokensByChainSelector[burnChainSelector]; + delete s_proposedUSDCMigrationChain; + + // This should only be called after this contract has been granted a "zero allowance minter role" on USDC by Circle, + // otherwise the call will revert. Executing this burn will functionally convert all USDC on the destination chain + // to canonical USDC by removing the canonical USDC backing it from circulation. + i_USDC.burn(tokensToBurn); + + // Disable L/R automatically on burned chain and enable CCTP + delete s_shouldUseLockRelease[burnChainSelector]; + + emit CCTPMigrationExecuted(burnChainSelector, tokensToBurn); + } + + /// @notice Propose a destination chain to migrate from lock/release mechanism to CCTP enabled burn/mint + /// through a Circle controlled burn. + /// @param remoteChainSelector the CCIP specific selector for the remote chain currently using a + /// non-canonical form of USDC which they wish to update to canonical. Function will revert if the chain + /// selector is zero, or if a migration has already occured for the specified selector. + /// @dev This function can only be called by the owner + function proposeCCTPMigration(uint64 remoteChainSelector) external onlyOwner { + // Prevent overwriting existing migration proposals until the current one is finished + if (s_proposedUSDCMigrationChain != 0) revert ExistingMigrationProposal(); + + s_proposedUSDCMigrationChain = remoteChainSelector; + + emit CCTPMigrationProposed(remoteChainSelector); + } + + /// @notice Cancel an existing proposal to migrate a lane to CCTP. + function cancelExistingCCTPMigrationProposal() external onlyOwner { + if (s_proposedUSDCMigrationChain == 0) revert NoExistingMigrationProposal(); + + uint64 currentProposalChainSelector = s_proposedUSDCMigrationChain; + delete s_proposedUSDCMigrationChain; + + emit CCTPMigrationCancelled(currentProposalChainSelector); + } + + /// @notice retrieve the chain selector for an ongoing CCTP migration in progress. + /// @return uint64 the chain selector of the lane to be migrated. Will be zero if no proposal currently + /// exists + function getCurrentProposedCCTPChainMigration() public view returns (uint64) { + return s_proposedUSDCMigrationChain; + } + + /// @notice Set the address of the circle-controlled wallet which will execute a CCTP lane migration + /// @dev The function should only be invoked once the address has been confirmed by Circle prior to + /// chain expansion. + function setCircleMigratorAddress(address migrator) external onlyOwner { + s_circleUSDCMigrator = migrator; + + emit CircleMigratorAddressSet(migrator); + } + + /// @notice Retrieve the amount of canonical USDC locked into this lane and minted on the destination + /// @param remoteChainSelector the CCIP specific destination chain implementing a mintable and + /// non-canonical form of USDC at present. + /// @return uint256 the amount of USDC locked into the specified lane. If non-zero, the number + /// should match the current circulating supply of USDC on the destination chain + function getLockedTokensForChain(uint64 remoteChainSelector) public view returns (uint256) { + return s_lockedTokensByChainSelector[remoteChainSelector]; + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/HybridLockReleaseUSDCTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/HybridLockReleaseUSDCTokenPool.t.sol new file mode 100644 index 0000000000..96216c6fcc --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/HybridLockReleaseUSDCTokenPool.t.sol @@ -0,0 +1,661 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {ILiquidityContainer} from "../../../liquiditymanager/interfaces/ILiquidityContainer.sol"; +import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; +import {IPoolV1} from "../../interfaces/IPool.sol"; +import {ITokenMessenger} from "../../pools/USDC/ITokenMessenger.sol"; + +import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; +import {Router} from "../../Router.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {Pool} from "../../libraries/Pool.sol"; +import {RateLimiter} from "../../libraries/RateLimiter.sol"; + +import {TokenPool} from "../../pools/TokenPool.sol"; +import {HybridLockReleaseUSDCTokenPool} from "../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; +import {USDCBridgeMigrator} from "../../pools/USDC/USDCBridgeMigrator.sol"; +import {USDCTokenPool} from "../../pools/USDC/USDCTokenPool.sol"; +import {BaseTest} from "../BaseTest.t.sol"; +import {USDCTokenPoolHelper} from "../helpers/USDCTokenPoolHelper.sol"; +import {MockE2EUSDCTransmitter} from "../mocks/MockE2EUSDCTransmitter.sol"; +import {MockUSDCTokenMessenger} from "../mocks/MockUSDCTokenMessenger.sol"; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/IERC165.sol"; + +contract USDCTokenPoolSetup is BaseTest { + IBurnMintERC20 internal s_token; + MockUSDCTokenMessenger internal s_mockUSDC; + MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; + uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; + + struct USDCMessage { + uint32 version; + uint32 sourceDomain; + uint32 destinationDomain; + uint64 nonce; + bytes32 sender; + bytes32 recipient; + bytes32 destinationCaller; + bytes messageBody; + } + + uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; + uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; + + bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); + address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); + address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); + address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); + + address internal s_routerAllowedOnRamp = address(3456); + address internal s_routerAllowedOffRamp = address(234); + Router internal s_router; + + HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; + HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; + address[] internal s_allowedList; + + function setUp() public virtual override { + BaseTest.setUp(); + BurnMintERC677 usdcToken = new BurnMintERC677("LINK", "LNK", 18, 0); + s_token = usdcToken; + deal(address(s_token), OWNER, type(uint256).max); + setUpRamps(); + + s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); + s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); + + usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); + + s_usdcTokenPool = + new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); + + s_usdcTokenPoolTransferLiquidity = + new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); + + usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); + usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), + remoteTokenAddress: abi.encode(address(s_token)), + allowed: true, + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() + }); + chainUpdates[1] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), + remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), + allowed: true, + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() + }); + + s_usdcTokenPool.applyChainUpdates(chainUpdates); + + USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); + domains[0] = USDCTokenPool.DomainUpdate({ + destChainSelector: DEST_CHAIN_SELECTOR, + domainIdentifier: 9999, + allowedCaller: keccak256("allowedCaller"), + enabled: true + }); + + s_usdcTokenPool.setDomains(domains); + + vm.expectEmit(); + emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); + + s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); + } + + function setUpRamps() internal { + s_router = new Router(address(s_token), address(s_mockRMN)); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + address[] memory offRamps = new address[](1); + offRamps[0] = s_routerAllowedOffRamp; + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); + + s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } + + function _generateUSDCMessage(USDCMessage memory usdcMessage) internal pure returns (bytes memory) { + return abi.encodePacked( + usdcMessage.version, + usdcMessage.sourceDomain, + usdcMessage.destinationDomain, + usdcMessage.nonce, + usdcMessage.sender, + usdcMessage.recipient, + usdcMessage.destinationCaller, + usdcMessage.messageBody + ); + } +} + +contract HybridUSDCTokenPoolTests is USDCTokenPoolSetup { + function test_LockOrBurn_onLockReleaseMechanism_Success() public { + bytes32 receiver = bytes32(uint256(uint160(STRANGER))); + + // Mark the destination chain as supporting CCTP, so use L/R instead. + uint64[] memory destChainAdds = new uint64[](1); + destChainAdds[0] = DEST_CHAIN_SELECTOR; + + s_usdcTokenPool.updateChainSelectorMechanisms(new uint64[](0), destChainAdds); + + assertTrue( + s_usdcTokenPool.shouldUseLockRelease(DEST_CHAIN_SELECTOR), + "Lock/Release mech not configured for outgoing message to DEST_CHAIN_SELECTOR" + ); + + uint256 amount = 1e6; + + s_token.transfer(address(s_usdcTokenPool), amount); + + vm.startPrank(s_routerAllowedOnRamp); + + vm.expectEmit(); + emit TokenPool.Locked(s_routerAllowedOnRamp, amount); + + s_usdcTokenPool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: abi.encodePacked(receiver), + amount: amount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + + assertEq(s_token.balanceOf(address(s_usdcTokenPool)), amount, "Incorrect token amount in the tokenPool"); + } + + function test_MintOrRelease_OnLockReleaseMechanism_Success() public { + address recipient = address(1234); + + // Designate the SOURCE_CHAIN as not using native-USDC, and so the L/R mechanism must be used instead + uint64[] memory destChainAdds = new uint64[](1); + destChainAdds[0] = SOURCE_CHAIN_SELECTOR; + + s_usdcTokenPool.updateChainSelectorMechanisms(new uint64[](0), destChainAdds); + + assertTrue( + s_usdcTokenPool.shouldUseLockRelease(SOURCE_CHAIN_SELECTOR), + "Lock/Release mech not configured for incoming message from SOURCE_CHAIN_SELECTOR" + ); + + vm.startPrank(OWNER); + s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); + + // Add 1e12 liquidity so that there's enough to release + vm.startPrank(s_usdcTokenPool.getLiquidityProvider(SOURCE_CHAIN_SELECTOR)); + + s_token.approve(address(s_usdcTokenPool), type(uint256).max); + + uint256 liquidityAmount = 1e12; + s_usdcTokenPool.provideLiquidity(SOURCE_CHAIN_SELECTOR, liquidityAmount); + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), + destTokenAddress: abi.encode(address(s_usdcTokenPool)), + extraData: abi.encode(USDCTokenPool.SourceTokenDataPayload({nonce: 1, sourceDomain: SOURCE_DOMAIN_IDENTIFIER})), + destGasAmount: USDC_DEST_TOKEN_GAS + }); + + uint256 amount = 1e6; + + vm.startPrank(s_routerAllowedOffRamp); + + vm.expectEmit(); + emit TokenPool.Released(s_routerAllowedOffRamp, recipient, amount); + + Pool.ReleaseOrMintOutV1 memory poolReturnDataV1 = s_usdcTokenPool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + receiver: recipient, + amount: amount, + localToken: address(s_token), + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: "", + offchainTokenData: "" + }) + ); + + assertEq(poolReturnDataV1.destinationAmount, amount, "destinationAmount and actual amount transferred differ"); + + // Simulate the off-ramp forwarding tokens to the recipient on destination chain + // s_token.transfer(recipient, amount); + + assertEq( + s_token.balanceOf(address(s_usdcTokenPool)), + liquidityAmount - amount, + "Incorrect remaining liquidity in TokenPool" + ); + assertEq(s_token.balanceOf(recipient), amount, "Tokens not transferred to recipient"); + } + + function test_LockOrBurn_PrimaryMechanism_Success() public { + bytes32 receiver = bytes32(uint256(uint160(STRANGER))); + uint256 amount = 1; + + vm.startPrank(OWNER); + + s_token.transfer(address(s_usdcTokenPool), amount); + + vm.startPrank(s_routerAllowedOnRamp); + + USDCTokenPool.Domain memory expectedDomain = s_usdcTokenPool.getDomain(DEST_CHAIN_SELECTOR); + + vm.expectEmit(); + emit RateLimiter.TokensConsumed(amount); + + vm.expectEmit(); + emit ITokenMessenger.DepositForBurn( + s_mockUSDC.s_nonce(), + address(s_token), + amount, + address(s_usdcTokenPool), + receiver, + expectedDomain.domainIdentifier, + s_mockUSDC.DESTINATION_TOKEN_MESSENGER(), + expectedDomain.allowedCaller + ); + + vm.expectEmit(); + emit TokenPool.Burned(s_routerAllowedOnRamp, amount); + + Pool.LockOrBurnOutV1 memory poolReturnDataV1 = s_usdcTokenPool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: abi.encodePacked(receiver), + amount: amount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + + uint64 nonce = abi.decode(poolReturnDataV1.destPoolData, (uint64)); + assertEq(s_mockUSDC.s_nonce() - 1, nonce); + } + + // https://etherscan.io/tx/0xac9f501fe0b76df1f07a22e1db30929fd12524bc7068d74012dff948632f0883 + function test_MintOrRelease_incomingMessageWithPrimaryMechanism() public { + bytes memory encodedUsdcMessage = + hex"000000000000000300000000000000000000127a00000000000000000000000019330d10d9cc8751218eaf51e8885d058642e08a000000000000000000000000bd3fa81b58ba92a82136038b25adec7066af3155000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e58310000000000000000000000004af08f56978be7dce2d1be3c65c005b41e79401c000000000000000000000000000000000000000000000000000000002057ff7a0000000000000000000000003a23f943181408eac424116af7b7790c94cb97a50000000000000000000000000000000000000000000000000000000000000000000000000000008274119237535fd659626b090f87e365ff89ebc7096bb32e8b0e85f155626b73ae7c4bb2485c184b7cc3cf7909045487890b104efb62ae74a73e32901bdcec91df1bb9ee08ccb014fcbcfe77b74d1263fd4e0b0e8de05d6c9a5913554364abfd5ea768b222f50c715908183905d74044bb2b97527c7e70ae7983c443a603557cac3b1c000000000000000000000000000000000000000000000000000000000000"; + bytes memory attestation = bytes("attestation bytes"); + + uint32 nonce = 4730; + uint32 sourceDomain = 3; + uint256 amount = 100; + + Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ + sourcePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), + destTokenAddress: abi.encode(address(s_usdcTokenPool)), + extraData: abi.encode(USDCTokenPool.SourceTokenDataPayload({nonce: nonce, sourceDomain: sourceDomain})), + destGasAmount: USDC_DEST_TOKEN_GAS + }); + + // The mocked receiver does not release the token to the pool, so we manually do it here + deal(address(s_token), address(s_usdcTokenPool), amount); + + bytes memory offchainTokenData = + abi.encode(USDCTokenPool.MessageAndAttestation({message: encodedUsdcMessage, attestation: attestation})); + + vm.expectCall( + address(s_mockUSDCTransmitter), + abi.encodeWithSelector(MockE2EUSDCTransmitter.receiveMessage.selector, encodedUsdcMessage, attestation) + ); + + vm.startPrank(s_routerAllowedOffRamp); + s_usdcTokenPool.releaseOrMint( + Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + receiver: OWNER, + amount: amount, + localToken: address(s_token), + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + sourcePoolAddress: sourceTokenData.sourcePoolAddress, + sourcePoolData: sourceTokenData.extraData, + offchainTokenData: offchainTokenData + }) + ); + } + + function test_LockOrBurn_LocKReleaseMechanism_then_switchToPrimary_Success() public { + // Test Enabling the LR mechanism and sending an outgoing message + test_LockOrBurn_PrimaryMechanism_Success(); + + // Disable the LR mechanism so that primary CCTP is used and then attempt to send a message + uint64[] memory destChainRemoves = new uint64[](1); + destChainRemoves[0] = DEST_CHAIN_SELECTOR; + + vm.startPrank(OWNER); + + vm.expectEmit(); + emit HybridLockReleaseUSDCTokenPool.LockReleaseDisabled(DEST_CHAIN_SELECTOR); + + s_usdcTokenPool.updateChainSelectorMechanisms(destChainRemoves, new uint64[](0)); + + // Send an outgoing message + test_LockOrBurn_PrimaryMechanism_Success(); + } + + function test_MintOrRelease_OnLockReleaseMechanism_then_switchToPrimary_Success() public { + test_MintOrRelease_OnLockReleaseMechanism_Success(); + + // Disable the LR mechanism so that primary CCTP is used and then attempt to send a message + uint64[] memory destChainRemoves = new uint64[](1); + destChainRemoves[0] = SOURCE_CHAIN_SELECTOR; + + vm.startPrank(OWNER); + + vm.expectEmit(); + emit HybridLockReleaseUSDCTokenPool.LockReleaseDisabled(SOURCE_CHAIN_SELECTOR); + + s_usdcTokenPool.updateChainSelectorMechanisms(destChainRemoves, new uint64[](0)); + + vm.expectEmit(); + emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(OWNER, OWNER, SOURCE_CHAIN_SELECTOR); + + s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); + + // Test incoming on the primary mechanism after disable LR, simulating Circle's new support for CCTP on + // DEST_CHAIN_SELECTOR + test_MintOrRelease_incomingMessageWithPrimaryMechanism(); + } + + function test_withdrawLiquidity_Success() public { + uint256 liquidityAmount = 1e12; + + vm.startPrank(OWNER); + s_token.approve(address(s_usdcTokenPool), type(uint256).max); + + s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); + assertEq(s_usdcTokenPool.getLiquidityProvider(SOURCE_CHAIN_SELECTOR), OWNER, "Owner is not Rebalancer"); + + s_usdcTokenPool.provideLiquidity(SOURCE_CHAIN_SELECTOR, liquidityAmount); + + assertEq(s_usdcTokenPool.getLockedTokensForChain(SOURCE_CHAIN_SELECTOR), liquidityAmount); + + assertEq( + s_token.balanceOf(address(s_usdcTokenPool)), + liquidityAmount, + "Available tokens doesn't match provided liquidity amount" + ); + + uint256 withdrawalAmount = liquidityAmount / 2; // Withdraw half of the liquidity + + vm.expectEmit(); + emit ILiquidityContainer.LiquidityRemoved(OWNER, withdrawalAmount); + + s_usdcTokenPool.withdrawLiquidity(SOURCE_CHAIN_SELECTOR, withdrawalAmount); + + assertEq( + s_usdcTokenPool.getLockedTokensForChain(SOURCE_CHAIN_SELECTOR), + liquidityAmount - withdrawalAmount, + "Remaining liquidity incorrect" + ); + assertEq( + s_token.balanceOf(address(s_usdcTokenPool)), + liquidityAmount - withdrawalAmount, + "Available tokens doesn't match provided liquidity amount" + ); + } + + function test_LockOrBurn_WhileMigrationPause_Revert() public { + // Create a fake migration proposal + s_usdcTokenPool.proposeCCTPMigration(DEST_CHAIN_SELECTOR); + + assertEq(s_usdcTokenPool.getCurrentProposedCCTPChainMigration(), DEST_CHAIN_SELECTOR); + + bytes32 receiver = bytes32(uint256(uint160(STRANGER))); + + // Mark the destination chain as supporting CCTP, so use L/R instead. + uint64[] memory destChainAdds = new uint64[](1); + destChainAdds[0] = DEST_CHAIN_SELECTOR; + + s_usdcTokenPool.updateChainSelectorMechanisms(new uint64[](0), destChainAdds); + + assertTrue( + s_usdcTokenPool.shouldUseLockRelease(DEST_CHAIN_SELECTOR), + "Lock Release mech not configured for outgoing message to DEST_CHAIN_SELECTOR" + ); + + uint256 amount = 1e6; + + s_token.transfer(address(s_usdcTokenPool), amount); + + vm.startPrank(s_routerAllowedOnRamp); + + // Expect the lockOrBurn to fail because a pending CCTP-Migration has paused outgoing messages on CCIP + vm.expectRevert( + abi.encodeWithSelector(HybridLockReleaseUSDCTokenPool.LanePausedForCCTPMigration.selector, DEST_CHAIN_SELECTOR) + ); + + s_usdcTokenPool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: abi.encodePacked(receiver), + amount: amount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + } +} + +contract HybridUSDCTokenPoolMigrationTests is HybridUSDCTokenPoolTests { + function test_lockOrBurn_then_BurnInCCTPMigration_Success() public { + bytes32 receiver = bytes32(uint256(uint160(STRANGER))); + address CIRCLE = makeAddr("CIRCLE CCTP Migrator"); + + // Mark the destination chain as supporting CCTP, so use L/R instead. + uint64[] memory destChainAdds = new uint64[](1); + destChainAdds[0] = DEST_CHAIN_SELECTOR; + + s_usdcTokenPool.updateChainSelectorMechanisms(new uint64[](0), destChainAdds); + + assertTrue( + s_usdcTokenPool.shouldUseLockRelease(DEST_CHAIN_SELECTOR), + "Lock/Release mech not configured for outgoing message to DEST_CHAIN_SELECTOR" + ); + + uint256 amount = 1e6; + + s_token.transfer(address(s_usdcTokenPool), amount); + + vm.startPrank(s_routerAllowedOnRamp); + + vm.expectEmit(); + emit TokenPool.Locked(s_routerAllowedOnRamp, amount); + + s_usdcTokenPool.lockOrBurn( + Pool.LockOrBurnInV1({ + originalSender: OWNER, + receiver: abi.encodePacked(receiver), + amount: amount, + remoteChainSelector: DEST_CHAIN_SELECTOR, + localToken: address(s_token) + }) + ); + + // Ensure that the tokens are properly locked + assertEq(s_token.balanceOf(address(s_usdcTokenPool)), amount, "Incorrect token amount in the tokenPool"); + + assertEq( + s_usdcTokenPool.getLockedTokensForChain(DEST_CHAIN_SELECTOR), + amount, + "Internal locked token accounting is incorrect" + ); + + vm.startPrank(OWNER); + + vm.expectEmit(); + emit USDCBridgeMigrator.CircleMigratorAddressSet(CIRCLE); + + s_usdcTokenPool.setCircleMigratorAddress(CIRCLE); + + vm.expectEmit(); + emit USDCBridgeMigrator.CCTPMigrationProposed(DEST_CHAIN_SELECTOR); + + // Propose the migration to CCTP + s_usdcTokenPool.proposeCCTPMigration(DEST_CHAIN_SELECTOR); + + assertEq( + s_usdcTokenPool.getCurrentProposedCCTPChainMigration(), + DEST_CHAIN_SELECTOR, + "Current proposed chain migration does not match expected for DEST_CHAIN_SELECTOR" + ); + + // Impersonate the set circle address and execute the proposal + vm.startPrank(CIRCLE); + + vm.expectEmit(); + emit USDCBridgeMigrator.CCTPMigrationExecuted(DEST_CHAIN_SELECTOR, amount); + + // Ensure the call to the burn function is properly + vm.expectCall(address(s_token), abi.encodeWithSelector(bytes4(keccak256("burn(uint256)")), amount)); + + s_usdcTokenPool.burnLockedUSDC(); + + // Assert that the tokens were actually burned + assertEq(s_token.balanceOf(address(s_usdcTokenPool)), 0, "Tokens were not burned out of the tokenPool"); + + // Ensure the proposal slot was cleared and there's no tokens locked for the destination chain anymore + assertEq(s_usdcTokenPool.getCurrentProposedCCTPChainMigration(), 0, "Proposal Slot should be empty"); + assertEq( + s_usdcTokenPool.getLockedTokensForChain(DEST_CHAIN_SELECTOR), + 0, + "No tokens should be locked for DEST_CHAIN_SELECTOR after CCTP-approved burn" + ); + + assertFalse( + s_usdcTokenPool.shouldUseLockRelease(DEST_CHAIN_SELECTOR), "Lock/Release mech should be disabled after a burn" + ); + + test_LockOrBurn_PrimaryMechanism_Success(); + } + + function test_cancelExistingCCTPMigrationProposal() public { + vm.startPrank(OWNER); + + vm.expectEmit(); + emit USDCBridgeMigrator.CCTPMigrationProposed(DEST_CHAIN_SELECTOR); + + s_usdcTokenPool.proposeCCTPMigration(DEST_CHAIN_SELECTOR); + + assertEq( + s_usdcTokenPool.getCurrentProposedCCTPChainMigration(), + DEST_CHAIN_SELECTOR, + "migration proposal should exist, but doesn't" + ); + + vm.expectEmit(); + emit USDCBridgeMigrator.CCTPMigrationCancelled(DEST_CHAIN_SELECTOR); + + s_usdcTokenPool.cancelExistingCCTPMigrationProposal(); + + assertEq( + s_usdcTokenPool.getCurrentProposedCCTPChainMigration(), + 0, + "migration proposal exists, but shouldn't after being cancelled" + ); + + vm.expectRevert(USDCBridgeMigrator.NoExistingMigrationProposal.selector); + s_usdcTokenPool.cancelExistingCCTPMigrationProposal(); + } + + function test_burnLockedUSDC_invalidPermissions_Revert() public { + address CIRCLE = makeAddr("CIRCLE"); + + vm.startPrank(OWNER); + + // Set the circle migrator address for later, but don't start pranking as it yet + s_usdcTokenPool.setCircleMigratorAddress(CIRCLE); + + vm.expectRevert(abi.encodeWithSelector(USDCBridgeMigrator.onlyCircle.selector)); + + // Should fail because only Circle can call this function + s_usdcTokenPool.burnLockedUSDC(); + + vm.startPrank(CIRCLE); + + vm.expectRevert(abi.encodeWithSelector(USDCBridgeMigrator.ExistingMigrationProposal.selector)); + s_usdcTokenPool.burnLockedUSDC(); + } + + function test_transferLiquidity_Success() public { + // Set as the OWNER so we can provide liquidity + vm.startPrank(OWNER); + s_usdcTokenPoolTransferLiquidity.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); + + s_token.approve(address(s_usdcTokenPoolTransferLiquidity), type(uint256).max); + + uint256 liquidityAmount = 1e9; + + // Provide 1000 USDC as liquidity + s_usdcTokenPoolTransferLiquidity.provideLiquidity(DEST_CHAIN_SELECTOR, liquidityAmount); + + // Set the new token pool as the rebalancer + s_usdcTokenPoolTransferLiquidity.setLiquidityProvider(DEST_CHAIN_SELECTOR, address(s_usdcTokenPool)); + + vm.expectEmit(); + emit ILiquidityContainer.LiquidityRemoved(address(s_usdcTokenPool), liquidityAmount); + + vm.expectEmit(); + emit HybridLockReleaseUSDCTokenPool.LiquidityTransferred( + address(s_usdcTokenPoolTransferLiquidity), DEST_CHAIN_SELECTOR, liquidityAmount + ); + + s_usdcTokenPool.transferLiquidity(address(s_usdcTokenPoolTransferLiquidity), DEST_CHAIN_SELECTOR, liquidityAmount); + + assertEq( + s_usdcTokenPool.getLockedTokensForChain(DEST_CHAIN_SELECTOR), + liquidityAmount, + "Tokens locked for dest chain doesn't match expected amount in storage" + ); + + assertEq( + s_usdcTokenPoolTransferLiquidity.getLockedTokensForChain(DEST_CHAIN_SELECTOR), + 0, + "Tokens locked for dest chain in old token pool doesn't match expected amount in storage" + ); + + assertEq( + s_token.balanceOf(address(s_usdcTokenPool)), + liquidityAmount, + "Liquidity amount of tokens should be new in new pool, but aren't" + ); + } + + function test_cannotModifyLiquidityWithoutPermissions_Revert() public { + address randomAddr = makeAddr("RANDOM"); + + vm.startPrank(randomAddr); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.Unauthorized.selector, randomAddr)); + + // Revert because there's insufficient permissions for the DEST_CHAIN_SELECTOR to provide liquidity + s_usdcTokenPool.provideLiquidity(DEST_CHAIN_SELECTOR, 1e6); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.Unauthorized.selector, randomAddr)); + + // Revert because there's insufficient permissions for the DEST_CHAIN_SELECTOR to withdraw liquidity + s_usdcTokenPool.withdrawLiquidity(DEST_CHAIN_SELECTOR, 1e6); + } + + function test_cannotCancelANonExistentMigrationProposal() public { + vm.expectRevert(USDCBridgeMigrator.NoExistingMigrationProposal.selector); + + // Proposal to migrate doesn't exist, and so the chain selector is zero, and therefore should revert + s_usdcTokenPool.cancelExistingCCTPMigrationProposal(); + } +} From 99d9d28dd21cf4a6c851a1a86b5116878c651d74 Mon Sep 17 00:00:00 2001 From: Ryan Tinianov Date: Wed, 28 Aug 2024 13:26:26 -0400 Subject: [PATCH 233/432] Use interpolate keys from common (#14262) --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/workflows/engine.go | 3 +- core/services/workflows/state.go | 95 --------- core/services/workflows/state_test.go | 268 ------------------------ core/services/workflows/store/models.go | 16 ++ go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 12 files changed, 30 insertions(+), 376 deletions(-) delete mode 100644 core/services/workflows/state_test.go diff --git a/core/scripts/go.mod b/core/scripts/go.mod index f106525d2a..de3f19b898 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index fbc83070e4..d24e6d2277 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1186,8 +1186,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a h1:MA1Lw4ZL8A/xyr5lW5WjM0zgI8ZL1AEfIOOTjZFcZlI= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index f3bca4b900..e98c592cc2 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -10,6 +10,7 @@ import ( "time" "github.com/jonboulle/clockwork" + "github.com/smartcontractkit/chainlink-common/pkg/workflows/exec" "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/services" @@ -726,7 +727,7 @@ func (e *Engine) executeStep(ctx context.Context, msg stepRequest) (*values.Map, inputs = step.Inputs.Mapping } - i, err := findAndInterpolateAllKeys(inputs, msg.state) + i, err := exec.FindAndInterpolateAllKeys(inputs, msg.state) if err != nil { return nil, nil, err } diff --git a/core/services/workflows/state.go b/core/services/workflows/state.go index cd4247d0ee..3a67f82a1e 100644 --- a/core/services/workflows/state.go +++ b/core/services/workflows/state.go @@ -1,14 +1,9 @@ package workflows import ( - "fmt" - "strconv" - "strings" - "github.com/smartcontractkit/chainlink/v2/core/services/workflows/store" "github.com/smartcontractkit/chainlink-common/pkg/values" - "github.com/smartcontractkit/chainlink-common/pkg/workflows" ) // copyState returns a deep copy of the input executionState @@ -44,93 +39,3 @@ func copyState(es store.WorkflowExecution) store.WorkflowExecution { Steps: steps, } } - -// interpolateKey takes a multi-part, dot-separated key and attempts to replace -// it with its corresponding value in `state`. -// -// A key is valid if it contains at least two parts, with: -// - the first part being the workflow step's `ref` variable -// - the second part being one of `inputs` or `outputs` -// -// If a key has more than two parts, then we traverse the parts -// to find the value we want to replace. -// We support traversing both nested maps and lists and any combination of the two. -func interpolateKey(key string, state store.WorkflowExecution) (any, error) { - parts := strings.Split(key, ".") - - if len(parts) < 2 { - return "", fmt.Errorf("cannot interpolate %s: must have at least two parts", key) - } - - // lookup the step we want to get either input or output state from - sc, ok := state.Steps[parts[0]] - if !ok { - return "", fmt.Errorf("could not find ref `%s`", parts[0]) - } - - var value values.Value - switch parts[1] { - case "inputs": - value = sc.Inputs - case "outputs": - if sc.Outputs.Err != nil { - return "", fmt.Errorf("cannot interpolate ref part `%s` in `%+v`: step has errored", parts[1], sc) - } - - value = sc.Outputs.Value - default: - return "", fmt.Errorf("cannot interpolate ref part `%s` in `%+v`: second part must be `inputs` or `outputs`", parts[1], sc) - } - - val, err := values.Unwrap(value) - if err != nil { - return "", err - } - - remainingParts := parts[2:] - for _, r := range remainingParts { - switch v := val.(type) { - case map[string]any: - inner, ok := v[r] - if !ok { - return "", fmt.Errorf("could not find ref part `%s` (ref: `%s`) in `%+v`", r, key, v) - } - - val = inner - case []any: - i, err := strconv.Atoi(r) - if err != nil { - return "", fmt.Errorf("could not interpolate ref part `%s` (ref: `%s`) in `%+v`: `%s` is not convertible to an int", r, key, v, r) - } - - if (i > len(v)-1) || (i < 0) { - return "", fmt.Errorf("could not interpolate ref part `%s` (ref: `%s`) in `%+v`: index out of bounds %d", r, key, v, i) - } - - val = v[i] - default: - return "", fmt.Errorf("could not interpolate ref part `%s` (ref: `%s`) in `%+v`", r, key, val) - } - } - - return val, nil -} - -// findAndInterpolateAllKeys takes an `input` any value, and recursively -// identifies any values that should be replaced from `state`. -// -// A value `v` should be replaced if it is wrapped as follows: `$(v)`. -func findAndInterpolateAllKeys(input any, state store.WorkflowExecution) (any, error) { - return workflows.DeepMap( - input, - func(el string) (any, error) { - matches := workflows.InterpolationTokenRe.FindStringSubmatch(el) - if len(matches) < 2 { - return el, nil - } - - interpolatedVar := matches[1] - return interpolateKey(interpolatedVar, state) - }, - ) -} diff --git a/core/services/workflows/state_test.go b/core/services/workflows/state_test.go deleted file mode 100644 index a9829a97c7..0000000000 --- a/core/services/workflows/state_test.go +++ /dev/null @@ -1,268 +0,0 @@ -package workflows - -import ( - "errors" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-common/pkg/values" - "github.com/smartcontractkit/chainlink/v2/core/services/workflows/store" -) - -func TestInterpolateKey(t *testing.T) { - t.Parallel() - val, err := values.NewMap( - map[string]any{ - "reports": map[string]any{ - "inner": "key", - }, - "reportsList": []any{ - "listElement", - }, - }, - ) - require.NoError(t, err) - - testCases := []struct { - name string - key string - state store.WorkflowExecution - expected any - errMsg string - }{ - { - name: "digging into a string", - key: "evm_median.outputs.reports", - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{ - "evm_median": { - Outputs: store.StepOutput{ - Value: values.NewString("
    "), - }, - }, - }, - }, - errMsg: "could not interpolate ref part `reports` (ref: `evm_median.outputs.reports`) in ``", - }, - { - name: "ref doesn't exist", - key: "evm_median.outputs.reports", - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{}, - }, - errMsg: "could not find ref `evm_median`", - }, - { - name: "less than 2 parts", - key: "evm_median", - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{}, - }, - errMsg: "must have at least two parts", - }, - { - name: "second part isn't `inputs` or `outputs`", - key: "evm_median.foo", - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{ - "evm_median": { - Outputs: store.StepOutput{ - Value: values.NewString(""), - }, - }, - }, - }, - errMsg: "second part must be `inputs` or `outputs`", - }, - { - name: "outputs has errored", - key: "evm_median.outputs", - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{ - "evm_median": { - Outputs: store.StepOutput{ - Err: errors.New("catastrophic error"), - }, - }, - }, - }, - errMsg: "step has errored", - }, - { - name: "digging into a recursive map", - key: "evm_median.outputs.reports.inner", - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{ - "evm_median": { - Outputs: store.StepOutput{ - Value: val, - }, - }, - }, - }, - expected: "key", - }, - { - name: "missing key in map", - key: "evm_median.outputs.reports.missing", - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{ - "evm_median": { - Outputs: store.StepOutput{ - Value: val, - }, - }, - }, - }, - errMsg: "could not find ref part `missing` (ref: `evm_median.outputs.reports.missing`) in", - }, - { - name: "digging into an array", - key: "evm_median.outputs.reportsList.0", - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{ - "evm_median": { - Outputs: store.StepOutput{ - Value: val, - }, - }, - }, - }, - expected: "listElement", - }, - { - name: "digging into an array that's too small", - key: "evm_median.outputs.reportsList.2", - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{ - "evm_median": { - Outputs: store.StepOutput{ - Value: val, - }, - }, - }, - }, - errMsg: "index out of bounds 2", - }, - { - name: "digging into an array with a string key", - key: "evm_median.outputs.reportsList.notAString", - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{ - "evm_median": { - Outputs: store.StepOutput{ - Value: val, - }, - }, - }, - }, - errMsg: "could not interpolate ref part `notAString` (ref: `evm_median.outputs.reportsList.notAString`) in `[listElement]`: `notAString` is not convertible to an int", - }, - { - name: "digging into an array with a negative index", - key: "evm_median.outputs.reportsList.-1", - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{ - "evm_median": { - Outputs: store.StepOutput{ - Value: val, - }, - }, - }, - }, - errMsg: "could not interpolate ref part `-1` (ref: `evm_median.outputs.reportsList.-1`) in `[listElement]`: index out of bounds -1", - }, - { - name: "empty element", - key: "evm_median.outputs..notAString", - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{ - "evm_median": { - Outputs: store.StepOutput{ - Value: val, - }, - }, - }, - }, - errMsg: "could not find ref part `` (ref: `evm_median.outputs..notAString`) in", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(st *testing.T) { - got, err := interpolateKey(tc.key, tc.state) - if tc.errMsg != "" { - require.ErrorContains(st, err, tc.errMsg) - } else { - require.NoError(t, err) - assert.Equal(t, tc.expected, got) - } - }) - } -} - -func TestInterpolateInputsFromState(t *testing.T) { - t.Parallel() - testCases := []struct { - name string - inputs map[string]any - state store.WorkflowExecution - expected any - errMsg string - }{ - { - name: "substituting with a variable that exists", - inputs: map[string]any{ - "shouldnotinterpolate": map[string]any{ - "shouldinterpolate": "$(evm_median.outputs)", - }, - }, - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{ - "evm_median": { - Outputs: store.StepOutput{ - Value: values.NewString(""), - }, - }, - }, - }, - expected: map[string]any{ - "shouldnotinterpolate": map[string]any{ - "shouldinterpolate": "", - }, - }, - }, - { - name: "no substitution required", - inputs: map[string]any{ - "foo": "bar", - }, - state: store.WorkflowExecution{ - Steps: map[string]*store.WorkflowExecutionStep{ - "evm_median": { - Outputs: store.StepOutput{ - Value: values.NewString(""), - }, - }, - }, - }, - expected: map[string]any{ - "foo": "bar", - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(st *testing.T) { - got, err := findAndInterpolateAllKeys(tc.inputs, tc.state) - if tc.errMsg != "" { - require.ErrorContains(st, err, tc.errMsg) - } else { - require.NoError(t, err) - assert.Equal(t, tc.expected, got) - } - }) - } -} diff --git a/core/services/workflows/store/models.go b/core/services/workflows/store/models.go index 275ca85b4f..b7c7d189ad 100644 --- a/core/services/workflows/store/models.go +++ b/core/services/workflows/store/models.go @@ -4,6 +4,7 @@ import ( "time" "github.com/smartcontractkit/chainlink-common/pkg/values" + "github.com/smartcontractkit/chainlink-common/pkg/workflows/exec" ) // Note: any update to the enum below should be reflected in @@ -50,3 +51,18 @@ type WorkflowExecution struct { UpdatedAt *time.Time FinishedAt *time.Time } + +func (w WorkflowExecution) ResultForStep(s string) (*exec.Result, bool) { + step, ok := w.Steps[s] + if !ok { + return &exec.Result{}, false + } + + return &exec.Result{ + Inputs: step.Inputs, + Outputs: step.Outputs.Value, + Error: step.Outputs.Err, + }, true +} + +var _ exec.Results = WorkflowExecution{} diff --git a/go.mod b/go.mod index 3fec96a015..83767a55fc 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index eeb48f39e6..217300324c 100644 --- a/go.sum +++ b/go.sum @@ -1141,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a h1:MA1Lw4ZL8A/xyr5lW5WjM0zgI8ZL1AEfIOOTjZFcZlI= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 783be44031..d73eb28f4b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -36,7 +36,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 745644e1bb..3994397b52 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1421,8 +1421,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a h1:MA1Lw4ZL8A/xyr5lW5WjM0zgI8ZL1AEfIOOTjZFcZlI= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index c887e800ab..ca6d98dc0f 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 9f2ad9a92c..9280dc968f 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1391,8 +1391,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a h1:MA1Lw4ZL8A/xyr5lW5WjM0zgI8ZL1AEfIOOTjZFcZlI= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= From c323e0d600c659a4ea584dbae0a0db187afd51eb Mon Sep 17 00:00:00 2001 From: "Abdelrahman Soliman (Boda)" <2677789+asoliman92@users.noreply.github.com> Date: Wed, 28 Aug 2024 23:50:41 +0400 Subject: [PATCH 234/432] Fixes to capabilities and contracts merges [CCIP-2946] (#14266) Fix merge issues --- .changeset/famous-plums-kiss.md | 5 + .gitignore | 2 + contracts/.changeset/quick-olives-accept.md | 5 + contracts/.husky/README.md | 37 + contracts/.husky/pre-commit | 14 + contracts/.husky/pre-push | 47 + contracts/.husky/prepare.sh | 19 + contracts/.husky/verify-changeset.sh | 20 + contracts/GNUmakefile | 10 + contracts/gas-snapshots/ccip.gas-snapshot | 60 +- contracts/gas-snapshots/shared.gas-snapshot | 24 +- contracts/hardhat.config.ts | 10 +- contracts/package.json | 91 +- contracts/pnpm-lock.yaml | 41 +- .../scripts/native_solc_compile_all_ccip | 6 + .../src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol | 15 +- .../v0.8/keystone/KeystoneFeedsConsumer.sol | 77 +- .../v0.8/operatorforwarder/Operator.test.ts | 2454 ++++++++--------- .../integrationhelpers/integration_helpers.go | 4 +- core/capabilities/remote/trigger_publisher.go | 2 +- .../price_registry_1_2_0/price_registry.go | 2 +- core/gethwrappers/ccip/go_generate.go | 1 + core/scripts/ccip/liquiditymanager/util.go | 433 --- .../helpers/contractmodels.go | 85 - .../helpers/contractwrappers.go | 189 -- core/scripts/ccip/manual-execution/main.go | 447 --- .../ccip/revert-reason/handler/reason.go | 208 -- core/scripts/go.mod | 101 +- core/scripts/go.sum | 472 +++- .../chainlink/relayer_chain_interoperators.go | 2 +- .../ocr2/plugins/ccip/exportinternal.go | 2 +- .../ccip/internal/ccipdata/factory/onramp.go | 3 +- .../ccip/internal/ccipdata/v1_0_0/onramp.go | 3 +- .../ccip/internal/ccipdata/v1_2_0/onramp.go | 3 +- .../ccip/internal/ccipdata/v1_5_0/onramp.go | 2 +- .../ccip/testhelpers/ccip_contracts.go | 4 +- .../ocr2/plugins/ccip/testhelpers/config.go | 1 + .../ccip/testhelpers/integration/chainlink.go | 52 +- .../testhelpers_1_4_0/ccip_contracts_1_4_0.go | 4 +- .../testhelpers_1_4_0/config_1_4_0.go | 1 + .../internal/integration_test.go | 843 ------ .../multichain_config_tracker_test.go | 323 --- go.mod | 113 +- go.sum | 472 +++- integration-tests/actions/actions.go | 3 +- .../ccip-tests/contracts/contract_deployer.go | 5 +- .../ccip-tests/testsetups/lm_setup.go | 845 ------ .../contracts/contract_models.go | 40 +- integration-tests/deployment/ccip/add_lane.go | 119 - integration-tests/deployment/ccip/deploy.go | 470 ---- .../deployment/ccip/deploy_home_chain.go | 410 --- .../deployment/ccip/deploy_test.go | 49 - integration-tests/deployment/ccip/jobs.go | 70 - .../ccip/migrations/1_initial_deploy.go | 34 - .../ccip/migrations/1_initial_deploy_test.go | 295 -- integration-tests/deployment/ccip/propose.go | 64 - integration-tests/deployment/ccip/state.go | 276 -- .../deployment/ccip/test_helpers.go | 75 - integration-tests/deployment/memory/node.go | 20 +- integration-tests/deployment/migrations.go | 28 - integration-tests/go.mod | 126 +- integration-tests/go.sum | 255 +- integration-tests/load/go.mod | 109 +- integration-tests/load/go.sum | 201 +- package.json | 13 +- 65 files changed, 2900 insertions(+), 7316 deletions(-) create mode 100644 .changeset/famous-plums-kiss.md create mode 100644 contracts/.changeset/quick-olives-accept.md create mode 100644 contracts/.husky/README.md create mode 100644 contracts/.husky/pre-commit create mode 100644 contracts/.husky/pre-push create mode 100755 contracts/.husky/prepare.sh create mode 100755 contracts/.husky/verify-changeset.sh delete mode 100644 core/scripts/ccip/liquiditymanager/util.go delete mode 100644 core/scripts/ccip/manual-execution/helpers/contractmodels.go delete mode 100644 core/scripts/ccip/manual-execution/helpers/contractwrappers.go delete mode 100644 core/scripts/ccip/manual-execution/main.go delete mode 100644 core/scripts/ccip/revert-reason/handler/reason.go delete mode 100644 core/services/ocr2/plugins/liquiditymanager/internal/integration_test.go delete mode 100644 core/services/ocr2/plugins/liquiditymanager/ocr3impls/multichain_config_tracker_test.go delete mode 100644 integration-tests/ccip-tests/testsetups/lm_setup.go delete mode 100644 integration-tests/deployment/ccip/add_lane.go delete mode 100644 integration-tests/deployment/ccip/deploy.go delete mode 100644 integration-tests/deployment/ccip/deploy_home_chain.go delete mode 100644 integration-tests/deployment/ccip/deploy_test.go delete mode 100644 integration-tests/deployment/ccip/jobs.go delete mode 100644 integration-tests/deployment/ccip/migrations/1_initial_deploy.go delete mode 100644 integration-tests/deployment/ccip/migrations/1_initial_deploy_test.go delete mode 100644 integration-tests/deployment/ccip/propose.go delete mode 100644 integration-tests/deployment/ccip/state.go delete mode 100644 integration-tests/deployment/ccip/test_helpers.go delete mode 100644 integration-tests/deployment/migrations.go diff --git a/.changeset/famous-plums-kiss.md b/.changeset/famous-plums-kiss.md new file mode 100644 index 0000000000..e884f0bceb --- /dev/null +++ b/.changeset/famous-plums-kiss.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#updated move latest capabilities code from ccip repo to chainlink repo [CCIP-2946] diff --git a/.gitignore b/.gitignore index bd7a6b72cd..4c4e76bee9 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,5 @@ override*.toml .venv/ ocr_soak_report.csv + +vendor/* diff --git a/contracts/.changeset/quick-olives-accept.md b/contracts/.changeset/quick-olives-accept.md new file mode 100644 index 0000000000..92d69c1673 --- /dev/null +++ b/contracts/.changeset/quick-olives-accept.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': minor +--- + +#updated move latest ccip contracts code from ccip repo to chainlink repo [CCIP-2946] diff --git a/contracts/.husky/README.md b/contracts/.husky/README.md new file mode 100644 index 0000000000..846e5d3c3a --- /dev/null +++ b/contracts/.husky/README.md @@ -0,0 +1,37 @@ +# Husky git hooks +The folder contains [husky](https://github.com/typicode/husky) git hooks that automate pre-commit and pre-push commands. + +## Setup + +Create an `.env` file in this folder to enable hooks: + +```sh +# Can be left blank to compile everything +FOUNDRY_PROFILE=ccip +HUSKY_ENABLE_PUSH_HOOKS=true +HUSKY_ENABLE_COMMIT_HOOKS=true +UPSTREAM_BRANCH=origin/ccip-develop +``` + +```sh +# Automatically ran after pnpm install +pnpm prepare +``` + +### Script procedure + +The setup is done via the `prepare.sh` script, which installs husky and enables the hooks. + +The prepare step is skipped if we are in CI. This is checked via the `CI=true` flag, which is always set to true on GitHub actions. + +## Hooks & Scripts + +### Pre-commit +Runs [lint-staged](https://github.com/lint-staged/lint-staged), which automatically detects `.sol` file changes and applies `forge fmt` only on the changed files. + +Configured in `package.json` in the `lint-staged` field. + +### Pre-push +Runs forge build, test, solhint and optionally suggests to generate snapshots and wrappers. + +Due to a [git workflow limitation](https://stackoverflow.com/questions/21334493/git-commit-in-pre-push-hook), generating wrappers & snapshots requires resubmitting the push (via `--no-verify` or by skiping the snapshot / wrappers). diff --git a/contracts/.husky/pre-commit b/contracts/.husky/pre-commit new file mode 100644 index 0000000000..a411da1567 --- /dev/null +++ b/contracts/.husky/pre-commit @@ -0,0 +1,14 @@ +#!/bin/bash +set -e + +source contracts/.husky/.env + +# Only run hook on enabled +if ! [[ $HUSKY_ENABLE_COMMIT_HOOKS == "true" && -n $UPSTREAM_BRANCH ]]; then + exit 0 +fi + +cd contracts + +# Run lint steps +pnpm lint-staged -v diff --git a/contracts/.husky/pre-push b/contracts/.husky/pre-push new file mode 100644 index 0000000000..dfa33c3942 --- /dev/null +++ b/contracts/.husky/pre-push @@ -0,0 +1,47 @@ +#!/bin/bash +set -e + +source contracts/.husky/.env + +# Only run hook on enabled +if ! [[ $HUSKY_ENABLE_PUSH_HOOKS == "true" && -n $UPSTREAM_BRANCH ]]; then + exit 0 +fi + +# Skip on no changes +current_branch=$(git branch --show-current) +changes_root=$(git diff --name-only $UPSTREAM_BRANCH...$current_branch -- "contracts/") + +if ! [[ -n $changes_root ]]; then + echo "Pre-push hook for contracts skipped - no changes detected" + exit 0 +fi + +cd contracts + +FOUNDRY_PROFILE=$FOUNDRY_PROFILE forge build +FOUNDRY_PROFILE=$FOUNDRY_PROFILE forge test +pnpm solhint + +# Skip interactive commands if interactive mode (/dev/tty) is unavailable +# https://stackoverflow.com/a/69088164 +if sh -c ": >/dev/tty" >/dev/null 2>/dev/null; then + read -n1 -p "Re-generate snapshots & wrappers? (Y/n)" snapshot_answer < /dev/tty + echo $snapshot_answer + + if [ "$snapshot_answer" != "${snapshot_answer#[Yy]}" ] ;then + # Create gas snapshot & commit gas snapshot + make snapshot + make wrappers + + git add ./gas-snapshots + git add ../core/gethwrappers + + # Check if commit is successful (non-empty) + if git commit -m "chore: update gas snapshots and wrappers"; then + # The commit is not included - need to push again (https://stackoverflow.com/questions/21334493/git-commit-in-pre-push-hook) + printf "\033[0;31m Snapshot commit created - run git push again \033[1;33m(skip snapshot, or use the --no-verify push option)\n" + exit 1 + fi + fi +fi diff --git a/contracts/.husky/prepare.sh b/contracts/.husky/prepare.sh new file mode 100755 index 0000000000..ce10e6449e --- /dev/null +++ b/contracts/.husky/prepare.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -e + +# Detect if in CI to skip hooks +# https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables +if [[ $CI == "true" ]]; then + exit 0 +fi + +# Skip hooks creation if unconfigured +if ! [ -f .husky/.env ]; then + printf "\033[1;33mNo .env file found in contracts/.husky, skipping hooks setup.\e[0m\n" + exit 0 +fi + +cd ../ +chmod +x ./contracts/.husky/*.sh +pnpm husky ./contracts/.husky +echo "Husky hooks prepared." diff --git a/contracts/.husky/verify-changeset.sh b/contracts/.husky/verify-changeset.sh new file mode 100755 index 0000000000..980b5e4182 --- /dev/null +++ b/contracts/.husky/verify-changeset.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -e + +# Determine the current branch +current_branch=$(git branch --show-current) +upstream_branch="origin/ccip-develop" + +# Compare the directory against the upstream branch +changes_root=$(git diff --name-only $upstream_branch...$current_branch -- ".changeset") + +if ! [ -n "$changes_root" ]; then + printf "\033[1;33mRoot changeset changes not found, Consider running pnpm changeset in the root directory if there is significant off-chain impact.\e[0m\n" +fi + +changes_contracts=$(git diff --name-only $upstream_branch...$current_branch -- "contracts/.changeset") + +if ! [ -n "$changes_contracts" ]; then + printf "\033[0;31mContracts changeset changes not found, Make sure to run & commit \033[1;33mpnpm changeset\033[0;31m in the contracts directory.\n" + exit 1 +fi diff --git a/contracts/GNUmakefile b/contracts/GNUmakefile index 2f111be018..862d75a432 100644 --- a/contracts/GNUmakefile +++ b/contracts/GNUmakefile @@ -88,6 +88,16 @@ wrappers-all: pnpmdep mockery abigen ## Recompiles solidity contracts and their # go_generate contains a call to compile all contracts before generating wrappers go generate ../core/gethwrappers/go_generate.go +# Use this to generate compiled JSON artifacts for gauntlet-plus-plus. +# This is currently only used for CCIP. +# example: make artifact-generate contract=LockReleaseTokenPoolAndProxy solcversion=0.8.24 artifactpath=../../gauntlet-plus-plus/packages-ethereum/operations-ccip/src/artifacts/1.5.0/lock-release-token-pool-and-proxy.json +artifact-generate: export FOUNDRY_PROFILE=ccip +.PHONY: artifact-generate +artifact-generate: + chmod +x ./scripts/generate_compiled_json_ccip.sh + ./scripts/generate_compiled_json_ccip.sh $(contract) $(solcversion) $(artifactpath) + + help: @echo "" @echo " .__ .__ .__ .__ __" diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 5abff8ca4c..cf27861983 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -103,7 +103,7 @@ CommitStore_report:test_OnlyPriceUpdateStaleReport_Revert() (gas: 59071) CommitStore_report:test_OnlyTokenPriceUpdates_Success() (gas: 53273) CommitStore_report:test_Paused_Revert() (gas: 21259) CommitStore_report:test_ReportAndPriceUpdate_Success() (gas: 84264) -CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56313) +CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56249) CommitStore_report:test_RootAlreadyCommitted_Revert() (gas: 63969) CommitStore_report:test_StaleReportWithRoot_Success() (gas: 119364) CommitStore_report:test_Unhealthy_Revert() (gas: 44751) @@ -123,7 +123,7 @@ CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424256) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1104033) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1100023) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37797) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103733) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85258) @@ -162,13 +162,13 @@ EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 42539) EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 157347) EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 172692) EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 247069) -EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114153) +EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 113842) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 407451) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54096) EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 131047) EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52090) EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 563385) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 495508) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 494182) EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35383) EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 544641) EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64326) @@ -178,7 +178,7 @@ EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 427337) EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18502) EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 278097) EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 18659) -EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 221421) +EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 223921) EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47881) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 47352) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 313917) @@ -230,21 +230,21 @@ EVM2EVMOnRamp_forwardFromRouter:test_MaxFeeBalanceReached_Revert() (gas: 36457) EVM2EVMOnRamp_forwardFromRouter:test_MessageGasLimitTooHigh_Revert() (gas: 29015) EVM2EVMOnRamp_forwardFromRouter:test_MessageTooLarge_Revert() (gas: 107571) EVM2EVMOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 22679) -EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 224619) +EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 227119) EVM2EVMOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 53072) EVM2EVMOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 25481) EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59341) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179148) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 177430) EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137254) -EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3822827) +EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3825327) EVM2EVMOnRamp_forwardFromRouter:test_TooManyTokens_Revert() (gas: 30187) EVM2EVMOnRamp_forwardFromRouter:test_Unhealthy_Revert() (gas: 43300) EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109305) EVM2EVMOnRamp_forwardFromRouter:test_ZeroAddressReceiver_Revert() (gas: 312579) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_ShouldStoreLinkFees_Success() (gas: 112322) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 72206) -EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 710475) +EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 712975) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 147664) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 190529) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 121320) @@ -275,7 +275,7 @@ EVM2EVMOnRamp_getTokenTransferCost:test__getTokenTransferCost_selfServeUsesDefau EVM2EVMOnRamp_linkAvailableForPayment:test_InsufficientLinkBalance_Success() (gas: 32615) EVM2EVMOnRamp_linkAvailableForPayment:test_LinkAvailableForPayment_Success() (gas: 134833) EVM2EVMOnRamp_payNops:test_AdminPayNops_Success() (gas: 143159) -EVM2EVMOnRamp_payNops:test_InsufficientBalance_Revert() (gas: 26543) +EVM2EVMOnRamp_payNops:test_InsufficientBalance_Revert() (gas: 29043) EVM2EVMOnRamp_payNops:test_NoFeesToPay_Revert() (gas: 127367) EVM2EVMOnRamp_payNops:test_NoNopsToPay_Revert() (gas: 133251) EVM2EVMOnRamp_payNops:test_NopPayNops_Success() (gas: 146446) @@ -307,7 +307,7 @@ EVM2EVMOnRamp_withdrawNonLinkFees:test_SettlingBalance_Success() (gas: 272035) EVM2EVMOnRamp_withdrawNonLinkFees:test_WithdrawNonLinkFees_Success() (gas: 53446) EVM2EVMOnRamp_withdrawNonLinkFees:test_WithdrawToZeroAddress_Revert() (gas: 12830) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_fallbackToWethTransfer() (gas: 96729) -EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 47688) +EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 49688) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongToken() (gas: 17384) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongTokenAmount() (gas: 15677) EtherSenderReceiverTest_ccipSend:test_ccipSend_reverts_insufficientFee_feeToken() (gas: 99741) @@ -514,7 +514,7 @@ MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExce MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78668) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 311927) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54728) -MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 9223372036854754743) +MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 1073667529) MultiAggregateRateLimiter_onOutboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 19149) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 15823) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213716) @@ -556,16 +556,16 @@ MultiOCR3Base_transmit:test_InsufficientSignatures_Revert() (gas: 76930) MultiOCR3Base_transmit:test_NonUniqueSignature_Revert() (gas: 66127) MultiOCR3Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 33419) MultiOCR3Base_transmit:test_TooManySignatures_Revert() (gas: 79521) -MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34131) +MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34020) MultiOCR3Base_transmit:test_TransmitWithExtraCalldataArgs_Revert() (gas: 47114) MultiOCR3Base_transmit:test_TransmitWithLessCalldataArgs_Revert() (gas: 25682) -MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18726) +MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18714) MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 410714) -MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1504468) +MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1499807) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) @@ -595,7 +595,7 @@ OCR2BaseNoChecks_setOCR2Config:test_TooManyTransmitter_Revert() (gas: 36938) OCR2BaseNoChecks_setOCR2Config:test_TransmitterCannotBeZeroAddress_Revert() (gas: 24158) OCR2BaseNoChecks_transmit:test_ConfigDigestMismatch_Revert() (gas: 17448) OCR2BaseNoChecks_transmit:test_ForkedChain_Revert() (gas: 26726) -OCR2BaseNoChecks_transmit:test_TransmitSuccess_gas() (gas: 27478) +OCR2BaseNoChecks_transmit:test_TransmitSuccess_gas() (gas: 27466) OCR2BaseNoChecks_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 21296) OCR2Base_setOCR2Config:test_FMustBePositive_Revert() (gas: 12189) OCR2Base_setOCR2Config:test_FTooHigh_Revert() (gas: 12345) @@ -609,7 +609,7 @@ OCR2Base_transmit:test_ConfigDigestMismatch_Revert() (gas: 19623) OCR2Base_transmit:test_ForkedChain_Revert() (gas: 37683) OCR2Base_transmit:test_NonUniqueSignature_Revert() (gas: 55309) OCR2Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 20962) -OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51686) +OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51674) OCR2Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 23484) OCR2Base_transmit:test_UnauthorizedSigner_Revert() (gas: 39665) OCR2Base_transmit:test_WrongNumberOfSignatures_Revert() (gas: 20557) @@ -676,7 +676,7 @@ OffRamp_execute:test_ZeroReports_Revert() (gas: 17225) OffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18257) OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249037) OffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20517) -OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 207676) +OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 210176) OffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48779) OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48302) OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229565) @@ -698,12 +698,12 @@ OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 193345) OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 212938) OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 266576) -OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 141488) +OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 141191) OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 423378) OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65877) OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80932) OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 587410) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 536450) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 535220) OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35743) OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 532474) OffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 529798) @@ -772,10 +772,10 @@ OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 208301) OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 122714) OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 144094) -OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3887491) +OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3889991) OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108659) OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 74066) -OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 273416) +OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 275916) OnRamp_getFee:test_EmptyMessage_Success() (gas: 104351) OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 73173) OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119675) @@ -788,7 +788,7 @@ OnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11112) OnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939) OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 52018) OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97192) -PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150169) +PingPong_ccipReceive:test_CcipReceive_Success() (gas: 152669) PingPong_plumbing:test_OutOfOrderExecution_Success() (gas: 20277) PingPong_plumbing:test_Pausing_Success() (gas: 17777) PingPong_startPingPong:test_StartPingPong_With_OOO_Success() (gas: 163187) @@ -801,7 +801,7 @@ RMN_ownerUnbless:test_Unbless_Success() (gas: 74699) RMN_ownerUnvoteToCurse:test_CanBlessAndCurseAfterGlobalCurseIsLifted() (gas: 470965) RMN_ownerUnvoteToCurse:test_IsIdempotent() (gas: 397532) RMN_ownerUnvoteToCurse:test_NonOwner_Revert() (gas: 18591) -RMN_ownerUnvoteToCurse:test_OwnerUnvoteToCurseSuccess_gas() (gas: 357403) +RMN_ownerUnvoteToCurse:test_OwnerUnvoteToCurseSuccess_gas() (gas: 357400) RMN_ownerUnvoteToCurse:test_UnknownVoter_Revert() (gas: 32980) RMN_ownerUnvoteToCurse_Benchmark:test_OwnerUnvoteToCurse_1Voter_LiftsCurse_gas() (gas: 261985) RMN_permaBlessing:test_PermaBlessing() (gas: 202686) @@ -809,7 +809,7 @@ RMN_setConfig:test_BlessVoterIsZeroAddress_Revert() (gas: 15494) RMN_setConfig:test_EitherThresholdIsZero_Revert() (gas: 21095) RMN_setConfig:test_NonOwner_Revert() (gas: 14713) RMN_setConfig:test_RepeatedAddress_Revert() (gas: 18213) -RMN_setConfig:test_SetConfigSuccess_gas() (gas: 104204) +RMN_setConfig:test_SetConfigSuccess_gas() (gas: 104022) RMN_setConfig:test_TotalWeightsSmallerThanEachThreshold_Revert() (gas: 30173) RMN_setConfig:test_VoteToBlessByEjectedVoter_Revert() (gas: 130303) RMN_setConfig:test_VotersLengthIsZero_Revert() (gas: 12128) @@ -894,18 +894,18 @@ Router_getFee:test_GetFeeSupportedChain_Success() (gas: 46458) Router_getFee:test_UnsupportedDestinationChain_Revert() (gas: 17138) Router_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10460) Router_recoverTokens:test_RecoverTokensInvalidRecipient_Revert() (gas: 11316) -Router_recoverTokens:test_RecoverTokensNoFunds_Revert() (gas: 17761) +Router_recoverTokens:test_RecoverTokensNoFunds_Revert() (gas: 20261) Router_recoverTokens:test_RecoverTokensNonOwner_Revert() (gas: 11159) Router_recoverTokens:test_RecoverTokensValueReceiver_Revert() (gas: 422138) -Router_recoverTokens:test_RecoverTokens_Success() (gas: 50437) +Router_recoverTokens:test_RecoverTokens_Success() (gas: 52437) Router_routeMessage:test_AutoExec_Success() (gas: 42684) Router_routeMessage:test_ExecutionEvent_Success() (gas: 157980) Router_routeMessage:test_ManualExec_Success() (gas: 35381) Router_routeMessage:test_OnlyOffRamp_Revert() (gas: 25116) Router_routeMessage:test_WhenNotHealthy_Revert() (gas: 44724) Router_setWrappedNative:test_OnlyOwner_Revert() (gas: 10985) -SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 53531) -SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 416966) +SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 55531) +SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 419466) SelfFundedPingPong_setCountIncrBeforeFunding:test_setCountIncrBeforeFunding() (gas: 20151) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_OnlyPendingAdministrator_Revert() (gas: 51085) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_Success() (gas: 43947) @@ -933,8 +933,8 @@ TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6070353) TokenPoolAndProxy:test_lockOrBurn_burnWithFromMint_Success() (gas: 6101826) TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6319594) TokenPoolAndProxy:test_setPreviousPool_Success() (gas: 3387124) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6913778) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7097803) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6916278) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7100303) TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2209837) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12089) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23324) diff --git a/contracts/gas-snapshots/shared.gas-snapshot b/contracts/gas-snapshots/shared.gas-snapshot index c194511ca6..dda850089c 100644 --- a/contracts/gas-snapshots/shared.gas-snapshot +++ b/contracts/gas-snapshots/shared.gas-snapshot @@ -39,41 +39,41 @@ CallWithExactGas__callWithExactGas:test_CallWithExactGasSafeReturnDataExactGas() CallWithExactGas__callWithExactGas:test_NoContractReverts() (gas: 11559) CallWithExactGas__callWithExactGas:test_NoGasForCallExactCheckReverts() (gas: 15788) CallWithExactGas__callWithExactGas:test_NotEnoughGasForCallReverts() (gas: 16241) -CallWithExactGas__callWithExactGas:test_callWithExactGasSuccess(bytes,bytes4) (runs: 256, μ: 15812, ~: 15752) +CallWithExactGas__callWithExactGas:test_callWithExactGasSuccess(bytes,bytes4) (runs: 256, μ: 15766, ~: 15719) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractExactGasSuccess() (gas: 20116) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractReceiverErrorSuccess() (gas: 67721) -CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractSuccess(bytes,bytes4) (runs: 256, μ: 16321, ~: 16262) +CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractSuccess(bytes,bytes4) (runs: 256, μ: 16276, ~: 16229) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoContractSuccess() (gas: 12962) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoGasForCallExactCheckReturnFalseSuccess() (gas: 13005) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NotEnoughGasForCallReturnsFalseSuccess() (gas: 13317) CallWithExactGas__callWithExactGasSafeReturnData:test_CallWithExactGasSafeReturnDataExactGas() (gas: 20331) CallWithExactGas__callWithExactGasSafeReturnData:test_NoContractReverts() (gas: 13917) CallWithExactGas__callWithExactGasSafeReturnData:test_NoGasForCallExactCheckReverts() (gas: 16139) -CallWithExactGas__callWithExactGasSafeReturnData:test_NotEnoughGasForCallReverts() (gas: 16547) -CallWithExactGas__callWithExactGasSafeReturnData:test_callWithExactGasSafeReturnData_ThrowOOGError_Revert() (gas: 36752) +CallWithExactGas__callWithExactGasSafeReturnData:test_NotEnoughGasForCallReverts() (gas: 16569) +CallWithExactGas__callWithExactGasSafeReturnData:test_callWithExactGasSafeReturnData_ThrowOOGError_Revert() (gas: 36708) EnumerableMapAddresses_at:testAtSuccess() (gas: 95086) EnumerableMapAddresses_at:testBytes32AtSuccess() (gas: 94877) +EnumerableMapAddresses_at:testBytesAtSuccess() (gas: 96564) EnumerableMapAddresses_contains:testBytes32ContainsSuccess() (gas: 93518) +EnumerableMapAddresses_contains:testBytesContainsSuccess() (gas: 94012) EnumerableMapAddresses_contains:testContainsSuccess() (gas: 93696) EnumerableMapAddresses_get:testBytes32GetSuccess() (gas: 94278) +EnumerableMapAddresses_get:testBytesGetSuccess() (gas: 95879) EnumerableMapAddresses_get:testGetSuccess() (gas: 94453) +EnumerableMapAddresses_get_errorMessage:testBytesGetErrorMessageSuccess() (gas: 95878) EnumerableMapAddresses_get_errorMessage:testGetErrorMessageSuccess() (gas: 94489) EnumerableMapAddresses_length:testBytes32LengthSuccess() (gas: 72445) +EnumerableMapAddresses_length:testBytesLengthSuccess() (gas: 73011) EnumerableMapAddresses_length:testLengthSuccess() (gas: 72640) EnumerableMapAddresses_remove:testBytes32RemoveSuccess() (gas: 73462) +EnumerableMapAddresses_remove:testBytesRemoveSuccess() (gas: 74249) EnumerableMapAddresses_remove:testRemoveSuccess() (gas: 73686) EnumerableMapAddresses_set:testBytes32SetSuccess() (gas: 94496) +EnumerableMapAddresses_set:testBytesSetSuccess() (gas: 95428) EnumerableMapAddresses_set:testSetSuccess() (gas: 94685) EnumerableMapAddresses_tryGet:testBytes32TryGetSuccess() (gas: 94622) -EnumerableMapAddresses_tryGet:testTryGetSuccess() (gas: 94893) -EnumerableMapAddresses_at:testBytesAtSuccess() (gas: 96564) -EnumerableMapAddresses_contains:testBytesContainsSuccess() (gas: 94012) -EnumerableMapAddresses_get:testBytesGetSuccess() (gas: 95879) -EnumerableMapAddresses_get_errorMessage:testBytesGetErrorMessageSuccess() (gas: 95878) -EnumerableMapAddresses_length:testBytesLengthSuccess() (gas: 73011) -EnumerableMapAddresses_remove:testBytesRemoveSuccess() (gas: 74249) -EnumerableMapAddresses_set:testBytesSetSuccess() (gas: 95428) EnumerableMapAddresses_tryGet:testBytesTryGetSuccess() (gas: 96279) +EnumerableMapAddresses_tryGet:testTryGetSuccess() (gas: 94893) OpStackBurnMintERC677_constructor:testConstructorSuccess() (gas: 1743649) OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 298649) OpStackBurnMintERC677_interfaceCompatibility:testMintCompatibility() (gas: 137957) diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 65934d3866..73e70081e9 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -21,10 +21,8 @@ subtask(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS).setAction( async (_, __, runSuper) => { const paths = await runSuper() const noTests = paths.filter((p: string) => !p.endsWith('.t.sol')) - const noCCIPTests = noTests.filter( - (p: string) => !p.includes('/v0.8/ccip/test'), - ) - return noCCIPTests.filter( + const noCCIP = noTests.filter((p: string) => !p.includes('/v0.8/ccip')) + return noCCIP.filter( (p: string) => !p.includes('src/v0.8/vendor/forge-std'), ) }, @@ -41,8 +39,8 @@ let config = { paths: { artifacts: './artifacts', cache: './cache', - sources: './src/v0.8', - tests: './test/v0.8', + sources: './src', + tests: './test', }, typechain: { outDir: './typechain', diff --git a/contracts/package.json b/contracts/package.json index 334b75701c..c260c0a578 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -1,9 +1,9 @@ { - "name": "@chainlink/contracts-ccip", - "version": "1.5.0", - "description": "Chainlink CCIP smart contracts", + "name": "@chainlink/contracts", + "version": "1.2.0", + "description": "Chainlink smart contracts", "author": "Chainlink devs", - "license": "BUSL-1.1", + "license": "MIT", "private": false, "scripts": { "test": "hardhat test --parallel", @@ -13,52 +13,16 @@ "size": "hardhat size-contracts", "clean": "hardhat clean", "compile:native": "./scripts/native_solc_compile_all", - "compile": "hardhat compile --no-typechain", + "compile": "hardhat compile", "coverage": "hardhat coverage", - "prepare": "chmod +x .husky/prepare.sh && ./.husky/prepare.sh", "prepublishOnly": "pnpm compile && ./scripts/prepublish_generate_abi_folder", "publish-beta": "pnpm publish --tag beta", - "publish-prod": "npm dist-tag add @chainlink/contracts-ccip@1.5.0 latest", - "solhint:ccip": "solhint --max-warnings 0 \"./src/v0.8/ccip/**/*.sol\"", + "publish-prod": "pnpm publish --tag latest", "solhint": "solhint --max-warnings 0 \"./src/v0.8/**/*.sol\"" }, "files": [ - "src/v0.8/ccip/**/*.sol", - "src/v0.8/shared/access/ConfirmedOwner.sol", - "src/v0.8/shared/access/ConfirmedOwnerWithProposal.sol", - "src/v0.8/shared/access/OwnerIsCreator.sol", - "src/v0.8/shared/access/AuthorizedCallers.sol", - "src/v0.8/shared/call/CallWithExactGas.sol", - "src/v0.8/shared/enumerable/EnumerableMapBytes32.sol", - "src/v0.8/shared/enumerable/EnumerableMapAddresses.sol", - "src/v0.8/shared/interfaces/IOwnable.sol", - "src/v0.8/shared/interfaces/ITypeAndVersion.sol", - "src/v0.8/shared/interfaces/IERC677Receiver.sol", - "src/v0.8/shared/interfaces/AggregatorV3Interface.sol", - "src/v0.8/shared/token/ERC20/IBurnMintERC20.sol", - "src/v0.8/shared/token/ERC677/IERC677.sol", - "src/v0.8/shared/token/ERC677/IERC677Receiver.sol", - "src/v0.8/shared/token/ERC677/ERC677.sol", - "src/v0.8/shared/token/ERC677/BurnMintERC677.sol", - "src/v0.8/shared/util/SortedSetValidationUtil.sol", - "src/v0.8/liquiditymanager/interfaces/ILiquidityContainer.sol", - "src/v0.8/keystone/interfaces/ICapabilityConfiguration.sol", - "src/v0.8/vendor/openzeppelin-solidity", - "src/v0.8/vendor/Context.sol", - "src/v0.8/vendor/Pausable.sol", - "abi/v0.8/", - "src/v0.8/ccip/LICENSE.md", - "src/v0.8/ccip/LICENSE-MIT.md", - "src/v0.8/ccip/v1.5-CCIP-License-grants.md", - "!src/v0.8/ccip/test/**/*", - "src/v0.8/ccip/test/mocks/**/*", - "!src/v0.8/ccip/test/mocks/test/*", - "!src/v0.8/ccip/onRamp/OnRamp.sol", - "!src/v0.8/ccip/offRamp/OffRamp.sol", - "!src/v0.8/ccip/ocr/MultiOCR3Base.sol", - "!src/v0.8/ccip/NonceManager.sol", - "!src/v0.8/ccip/MultiAggregateRateLimiter.sol", - "!src/v0.8/ccip/capability" + "src/v0.8", + "abi/v0.8" ], "pnpm": { "_comment": "See https://github.com/ethers-io/ethers.js/discussions/2849#discussioncomment-2696454", @@ -79,56 +43,49 @@ "@ethersproject/providers": "~5.7.2", "@nomicfoundation/hardhat-chai-matchers": "^1.0.6", "@nomicfoundation/hardhat-ethers": "^3.0.6", - "@nomicfoundation/hardhat-network-helpers": "^1.0.9", - "@nomicfoundation/hardhat-verify": "^2.0.7", + "@nomicfoundation/hardhat-network-helpers": "^1.0.11", + "@nomicfoundation/hardhat-verify": "^2.0.9", "@typechain/ethers-v5": "^7.2.0", "@typechain/hardhat": "^7.0.0", "@types/cbor": "~5.0.1", - "@types/chai": "^4.3.16", + "@types/chai": "^4.3.17", "@types/debug": "^4.1.12", "@types/deep-equal-in-any-order": "^1.0.3", - "@types/mocha": "^10.0.6", - "@types/node": "^20.12.12", - "@typescript-eslint/eslint-plugin": "^7.10.0", - "@typescript-eslint/parser": "^7.10.0", + "@types/mocha": "^10.0.7", + "@types/node": "^20.14.15", + "@typescript-eslint/eslint-plugin": "^7.18.0", + "@typescript-eslint/parser": "^7.18.0", "abi-to-sol": "^0.6.6", "cbor": "^5.2.0", - "chai": "^4.3.10", - "debug": "^4.3.4", + "chai": "^4.5.0", + "debug": "^4.3.6", "deep-equal-in-any-order": "^2.0.6", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-prettier": "^5.2.1", "ethers": "~5.7.2", "hardhat": "~2.20.1", "hardhat-abi-exporter": "^2.10.1", "hardhat-ignore-warnings": "^0.2.6", - "husky": "^9.0.11", - "lint-staged": "^15.2.2", "moment": "^2.30.1", - "prettier": "^3.2.5", + "prettier": "^3.3.3", "prettier-plugin-solidity": "^1.3.1", - "solhint": "^5.0.1", + "solhint": "^5.0.3", "solhint-plugin-chainlink-solidity": "git+https://github.com/smartcontractkit/chainlink-solhint-rules.git#v1.2.1", "solhint-plugin-prettier": "^0.1.0", "ts-node": "^10.9.2", "typechain": "^8.2.1", - "typescript": "^5.4.5" + "typescript": "^5.5.4" }, "dependencies": { "@arbitrum/nitro-contracts": "1.1.1", "@arbitrum/token-bridge-contracts": "1.1.2", "@changesets/changelog-github": "^0.5.0", - "@changesets/cli": "~2.27.3", + "@changesets/cli": "~2.27.7", "@eth-optimism/contracts": "0.6.0", "@openzeppelin/contracts": "4.9.3", "@openzeppelin/contracts-upgradeable": "4.9.3", "@scroll-tech/contracts": "0.1.0", - "semver": "^7.6.2" - }, - "lint-staged": { - "*.sol": [ - "forge fmt" - ] + "semver": "^7.6.3" } -} +} \ No newline at end of file diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index 5c45da8ab0..ec89b5a4b5 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -1057,6 +1057,10 @@ packages: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + brorand@1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} @@ -1559,6 +1563,10 @@ packages: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + find-replace@3.0.0: resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} engines: {node: '>=4.0.0'} @@ -1828,10 +1836,6 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} - ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} - engines: {node: '>= 4'} - ignore@5.3.1: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} @@ -2177,6 +2181,10 @@ packages: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -3332,7 +3340,7 @@ snapshots: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - micromatch: 4.0.5 + micromatch: 4.0.8 '@changesets/errors@0.2.0': dependencies: @@ -3372,7 +3380,7 @@ snapshots: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 is-subdir: 1.2.0 - micromatch: 4.0.5 + micromatch: 4.0.8 spawndamnit: 2.0.0 '@changesets/logger@0.1.0': @@ -4566,6 +4574,10 @@ snapshots: dependencies: fill-range: 7.0.1 + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + brorand@1.1.0: {} browser-stdout@1.3.1: {} @@ -5311,7 +5323,7 @@ snapshots: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.5 + micromatch: 4.0.8 fast-json-stable-stringify@2.1.0: {} @@ -5329,6 +5341,10 @@ snapshots: dependencies: to-regex-range: 5.0.1 + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + find-replace@3.0.0: dependencies: array-back: 3.1.0 @@ -5349,7 +5365,7 @@ snapshots: find-yarn-workspace-root2@1.2.16: dependencies: - micromatch: 4.0.5 + micromatch: 4.0.8 pkg-dir: 4.2.0 find-yarn-workspace-root@2.0.0: @@ -5522,7 +5538,7 @@ snapshots: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.3.1 - ignore: 5.2.4 + ignore: 5.3.1 merge2: 1.4.1 slash: 3.0.0 @@ -5724,8 +5740,6 @@ snapshots: dependencies: safer-buffer: 2.1.2 - ignore@5.2.4: {} - ignore@5.3.1: {} immutable@4.1.0: {} @@ -6064,6 +6078,11 @@ snapshots: braces: 3.0.2 picomatch: 2.3.1 + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + mimic-response@1.0.1: {} mimic-response@3.1.0: {} diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index 21f4014cf7..7b2c580b3c 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -40,11 +40,16 @@ compileContract () { echo "OnRamp uses $OPTIMIZE_RUNS_ONRAMP optimizer runs." optimize_runs=$OPTIMIZE_RUNS_ONRAMP ;; + "ccip/test/helpers/CCIPReaderTester.sol") + echo "CCIPReaderTester uses 1 optimizer runs for reduced contract size." + optimize_runs=1 + ;; esac solc --overwrite --optimize --optimize-runs $optimize_runs --metadata-hash none \ -o "$ROOT"/contracts/solc/v$SOLC_VERSION/"$contract" \ --abi --bin --allow-paths "$ROOT"/contracts/src/v0.8 \ + --bin-runtime --hashes --metadata --metadata-literal --combined-json abi,hashes,metadata,srcmap,srcmap-runtime \ --evm-version paris \ "$ROOT"/contracts/src/v0.8/"$1" } @@ -88,6 +93,7 @@ compileContract ccip/pools/TokenPool.sol compileContract ccip/test/helpers/BurnMintERC677Helper.sol compileContract ccip/test/helpers/CommitStoreHelper.sol compileContract ccip/test/helpers/MessageHasher.sol +compileContract ccip/test/helpers/CCIPReaderTester.sol compileContract ccip/test/helpers/ReportCodec.sol compileContract ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol compileContract ccip/test/helpers/MultiOCR3Helper.sol diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol index 97139d0560..0be7fe7511 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol @@ -477,18 +477,9 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersio ) internal returns (Internal.MessageExecutionState, bytes memory) { try this.executeSingleMessage(message, offchainTokenData, tokenGasOverrides) {} catch (bytes memory err) { - if ( - ReceiverError.selector == bytes4(err) || TokenHandlingError.selector == bytes4(err) - || Internal.InvalidEVMAddress.selector == bytes4(err) || InvalidDataLength.selector == bytes4(err) - || CallWithExactGas.NoContract.selector == bytes4(err) || NotACompatiblePool.selector == bytes4(err) - ) { - // If CCIP receiver execution is not successful, bubble up receiver revert data, - // prepended by the 4 bytes of ReceiverError.selector, TokenHandlingError.selector or InvalidPoolAddress.selector. - // Max length of revert data is Router.MAX_RET_BYTES, max length of err is 4 + Router.MAX_RET_BYTES - return (Internal.MessageExecutionState.FAILURE, err); - } - // If revert is not caused by CCIP receiver, it is unexpected, bubble up the revert. - revert ExecutionError(err); + // return the message execution state as FAILURE and the revert data + // Max length of revert data is Router.MAX_RET_BYTES, max length of err is 4 + Router.MAX_RET_BYTES + return (Internal.MessageExecutionState.FAILURE, err); } // If message execution succeeded, no CCIP receiver return data is expected, return with empty bytes. return (Internal.MessageExecutionState.SUCCESS, ""); diff --git a/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol b/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol index bc722eff29..654e4e7f76 100644 --- a/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol +++ b/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol @@ -1,15 +1,17 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; +import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol"; import {IReceiver} from "./interfaces/IReceiver.sol"; -import {KeystoneFeedsPermissionHandler} from "./KeystoneFeedsPermissionHandler.sol"; -import {KeystoneFeedDefaultMetadataLib} from "./lib/KeystoneFeedDefaultMetadataLib.sol"; - -contract KeystoneFeedsConsumer is IReceiver, KeystoneFeedsPermissionHandler { - using KeystoneFeedDefaultMetadataLib for bytes; +contract KeystoneFeedsConsumer is IReceiver, OwnerIsCreator, IERC165 { event FeedReceived(bytes32 indexed feedId, uint224 price, uint32 timestamp); + error UnauthorizedSender(address sender); + error UnauthorizedWorkflowOwner(address workflowOwner); + error UnauthorizedWorkflowName(bytes10 workflowName); + struct ReceivedFeedReport { bytes32 FeedId; uint224 Price; @@ -22,11 +24,53 @@ contract KeystoneFeedsConsumer is IReceiver, KeystoneFeedsPermissionHandler { } mapping(bytes32 feedId => StoredFeedReport feedReport) internal s_feedReports; + address[] internal s_allowedSendersList; + mapping(address sender => bool) internal s_allowedSenders; + address[] internal s_allowedWorkflowOwnersList; + mapping(address owner => bool) internal s_allowedWorkflowOwners; + bytes10[] internal s_allowedWorkflowNamesList; + mapping(bytes10 workflowName => bool) internal s_allowedWorkflowNames; + + function setConfig( + address[] calldata _allowedSendersList, + address[] calldata _allowedWorkflowOwnersList, + bytes10[] calldata _allowedWorkflowNamesList + ) external onlyOwner { + for (uint32 i = 0; i < s_allowedSendersList.length; ++i) { + s_allowedSenders[s_allowedSendersList[i]] = false; + } + for (uint32 i = 0; i < _allowedSendersList.length; ++i) { + s_allowedSenders[_allowedSendersList[i]] = true; + } + s_allowedSendersList = _allowedSendersList; + for (uint32 i = 0; i < s_allowedWorkflowOwnersList.length; ++i) { + s_allowedWorkflowOwners[s_allowedWorkflowOwnersList[i]] = false; + } + for (uint32 i = 0; i < _allowedWorkflowOwnersList.length; ++i) { + s_allowedWorkflowOwners[_allowedWorkflowOwnersList[i]] = true; + } + s_allowedWorkflowOwnersList = _allowedWorkflowOwnersList; + for (uint32 i = 0; i < s_allowedWorkflowNamesList.length; ++i) { + s_allowedWorkflowNames[s_allowedWorkflowNamesList[i]] = false; + } + for (uint32 i = 0; i < _allowedWorkflowNamesList.length; ++i) { + s_allowedWorkflowNames[_allowedWorkflowNamesList[i]] = true; + } + s_allowedWorkflowNamesList = _allowedWorkflowNamesList; + } function onReport(bytes calldata metadata, bytes calldata rawReport) external { - (bytes10 workflowName, address workflowOwner, bytes2 reportName) = metadata._extractMetadataInfo(); + if (!s_allowedSenders[msg.sender]) { + revert UnauthorizedSender(msg.sender); + } - _validateReportPermission(msg.sender, workflowOwner, workflowName, reportName); + (bytes10 workflowName, address workflowOwner) = _getInfo(metadata); + if (!s_allowedWorkflowNames[workflowName]) { + revert UnauthorizedWorkflowName(workflowName); + } + if (!s_allowedWorkflowOwners[workflowOwner]) { + revert UnauthorizedWorkflowOwner(workflowOwner); + } ReceivedFeedReport[] memory feeds = abi.decode(rawReport, (ReceivedFeedReport[])); for (uint256 i = 0; i < feeds.length; ++i) { @@ -35,8 +79,27 @@ contract KeystoneFeedsConsumer is IReceiver, KeystoneFeedsPermissionHandler { } } + // solhint-disable-next-line chainlink-solidity/explicit-returns + function _getInfo(bytes memory metadata) internal pure returns (bytes10 workflowName, address workflowOwner) { + // (first 32 bytes contain length of the byte array) + // workflow_cid // offset 32, size 32 + // workflow_name // offset 64, size 10 + // workflow_owner // offset 74, size 20 + // report_name // offset 94, size 2 + assembly { + // no shifting needed for bytes10 type + workflowName := mload(add(metadata, 64)) + // shift right by 12 bytes to get the actual value + workflowOwner := shr(mul(12, 8), mload(add(metadata, 74))) + } + } + function getPrice(bytes32 feedId) external view returns (uint224, uint32) { StoredFeedReport memory report = s_feedReports[feedId]; return (report.Price, report.Timestamp); } + + function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { + return interfaceId == this.onReport.selector; + } } diff --git a/contracts/test/v0.8/operatorforwarder/Operator.test.ts b/contracts/test/v0.8/operatorforwarder/Operator.test.ts index 6fb8768f54..96e882979c 100644 --- a/contracts/test/v0.8/operatorforwarder/Operator.test.ts +++ b/contracts/test/v0.8/operatorforwarder/Operator.test.ts @@ -50,34 +50,34 @@ before(async () => { roles = users.roles basicConsumerFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/BasicConsumer.sol:BasicConsumer', + 'src/v0.8/operatorforwarder/test/testhelpers/BasicConsumer.sol:BasicConsumer', ) multiWordConsumerFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/MultiWordConsumer.sol:MultiWordConsumer', + 'src/v0.8/operatorforwarder/test/testhelpers/MultiWordConsumer.sol:MultiWordConsumer', ) gasGuzzlingConsumerFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/GasGuzzlingConsumer.sol:GasGuzzlingConsumer', + 'src/v0.8/operatorforwarder/test/testhelpers/GasGuzzlingConsumer.sol:GasGuzzlingConsumer', ) getterSetterFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/GetterSetter.sol:GetterSetter', + 'src/v0.8/operatorforwarder/test/testhelpers/GetterSetter.sol:GetterSetter', ) maliciousRequesterFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/MaliciousRequester.sol:MaliciousRequester', + 'src/v0.8/operatorforwarder/test/testhelpers/MaliciousRequester.sol:MaliciousRequester', ) maliciousConsumerFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/MaliciousConsumer.sol:MaliciousConsumer', + 'src/v0.8/operatorforwarder/test/testhelpers/MaliciousConsumer.sol:MaliciousConsumer', ) maliciousMultiWordConsumerFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/MaliciousMultiWordConsumer.sol:MaliciousMultiWordConsumer', + 'src/v0.8/operatorforwarder/test/testhelpers/MaliciousMultiWordConsumer.sol:MaliciousMultiWordConsumer', ) operatorFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/Operator.sol:Operator', + 'src/v0.8/operatorforwarder/Operator.sol:Operator', ) forwarderFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/AuthorizedForwarder.sol:AuthorizedForwarder', + 'src/v0.8/operatorforwarder/AuthorizedForwarder.sol:AuthorizedForwarder', ) linkTokenFactory = await ethers.getContractFactory( - 'src/v0.8/shared/test/helpers/LinkTokenTestHelper.sol:LinkTokenTestHelper', + 'src/v0.8/shared/test/helpers/LinkTokenTestHelper.sol:LinkTokenTestHelper', ) }) @@ -94,16 +94,16 @@ describe('Operator', () => { beforeEach(async () => { fHash = getterSetterFactory.interface.getSighash('requestedBytes32') specId = - '0x4c7b7ffb66b344fbaa64995af81e355a00000000000000000000000000000000' + '0x4c7b7ffb66b344fbaa64995af81e355a00000000000000000000000000000000' to = '0x80e29acb842498fe6591f020bd82766dce619d43' link = await linkTokenFactory.connect(roles.defaultAccount).deploy() owner = roles.defaultAccount operator = await operatorFactory - .connect(owner) - .deploy(link.address, await owner.getAddress()) + .connect(owner) + .deploy(link.address, await owner.getAddress()) await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders([await roles.oracleNode.getAddress()]) + .connect(roles.defaultAccount) + .setAuthorizedSenders([await roles.oracleNode.getAddress()]) }) it('has a limited public interface [ @skip-coverage ]', () => { @@ -146,30 +146,30 @@ describe('Operator', () => { describe('#transferOwnableContracts', () => { beforeEach(async () => { forwarder1 = await forwarderFactory - .connect(owner) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(owner) + .deploy(link.address, operator.address, zeroAddress, '0x') forwarder2 = await forwarderFactory - .connect(owner) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(owner) + .deploy(link.address, operator.address, zeroAddress, '0x') }) describe('being called by the owner', () => { it('cannot transfer to self', async () => { await evmRevert( - operator - .connect(owner) - .transferOwnableContracts([forwarder1.address], operator.address), - 'Cannot transfer to self', + operator + .connect(owner) + .transferOwnableContracts([forwarder1.address], operator.address), + 'Cannot transfer to self', ) }) it('emits an ownership transfer request event', async () => { const tx = await operator - .connect(owner) - .transferOwnableContracts( - [forwarder1.address, forwarder2.address], - await roles.oracleNode1.getAddress(), - ) + .connect(owner) + .transferOwnableContracts( + [forwarder1.address, forwarder2.address], + await roles.oracleNode1.getAddress(), + ) const receipt = await tx.wait() assert.equal(receipt?.events?.length, 2) const log1 = receipt?.events?.[0] @@ -188,13 +188,13 @@ describe('Operator', () => { describe('being called by a non-owner', () => { it('reverts with message', async () => { await evmRevert( - operator - .connect(roles.stranger) - .transferOwnableContracts( - [forwarder1.address], - await roles.oracleNode2.getAddress(), - ), - 'Only callable by owner', + operator + .connect(roles.stranger) + .transferOwnableContracts( + [forwarder1.address], + await roles.oracleNode2.getAddress(), + ), + 'Only callable by owner', ) }) }) @@ -207,23 +207,23 @@ describe('Operator', () => { beforeEach(async () => { operator2 = await operatorFactory - .connect(roles.defaultAccount) - .deploy(link.address, await roles.defaultAccount.getAddress()) + .connect(roles.defaultAccount) + .deploy(link.address, await roles.defaultAccount.getAddress()) forwarder1 = await forwarderFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, zeroAddress, '0x') forwarder2 = await forwarderFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, zeroAddress, '0x') await operator - .connect(roles.defaultAccount) - .transferOwnableContracts( - [forwarder1.address, forwarder2.address], - operator2.address, - ) + .connect(roles.defaultAccount) + .transferOwnableContracts( + [forwarder1.address, forwarder2.address], + operator2.address, + ) const tx = await operator2 - .connect(roles.defaultAccount) - .acceptOwnableContracts([forwarder1.address, forwarder2.address]) + .connect(roles.defaultAccount) + .acceptOwnableContracts([forwarder1.address, forwarder2.address]) receipt = await tx.wait() }) @@ -253,8 +253,8 @@ describe('Operator', () => { describe('being called by a non-owner authorized sender', () => { it('does not revert', async () => { await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders([await roles.oracleNode1.getAddress()]) + .connect(roles.defaultAccount) + .setAuthorizedSenders([await roles.oracleNode1.getAddress()]) await operator.connect(roles.oracleNode1).acceptOwnableContracts([]) }) @@ -263,10 +263,10 @@ describe('Operator', () => { describe('being called by a non owner', () => { it('reverts with message', async () => { await evmRevert( - operator - .connect(roles.stranger) - .acceptOwnableContracts([await roles.oracleNode2.getAddress()]), - 'Cannot set authorized senders', + operator + .connect(roles.stranger) + .acceptOwnableContracts([await roles.oracleNode2.getAddress()]), + 'Cannot set authorized senders', ) }) }) @@ -276,8 +276,8 @@ describe('Operator', () => { describe('when called with empty arrays', () => { it('reverts with invalid array message', async () => { await evmRevert( - operator.connect(roles.defaultAccount).distributeFunds([], []), - 'Invalid array length(s)', + operator.connect(roles.defaultAccount).distributeFunds([], []), + 'Invalid array length(s)', ) }) }) @@ -290,10 +290,10 @@ describe('Operator', () => { ] const amounts = [1, 2, 3] await evmRevert( - operator - .connect(roles.defaultAccount) - .distributeFunds(receivers, amounts), - 'Invalid array length(s)', + operator + .connect(roles.defaultAccount) + .distributeFunds(receivers, amounts), + 'Invalid array length(s)', ) }) }) @@ -304,15 +304,15 @@ describe('Operator', () => { const amountToSend = toWei('2') const ethSent = toWei('1') await expect( - operator - .connect(roles.defaultAccount) - .distributeFunds( - [await roles.oracleNode2.getAddress()], - [amountToSend], - { - value: ethSent, - }, - ), + operator + .connect(roles.defaultAccount) + .distributeFunds( + [await roles.oracleNode2.getAddress()], + [amountToSend], + { + value: ethSent, + }, + ), ).to.be.revertedWithPanic(0x11) }) }) @@ -322,16 +322,16 @@ describe('Operator', () => { const amountToSend = toWei('2') const ethSent = toWei('3') await evmRevert( - operator - .connect(roles.defaultAccount) - .distributeFunds( - [await roles.oracleNode2.getAddress()], - [amountToSend], - { - value: ethSent, - }, - ), - 'Too much ETH sent', + operator + .connect(roles.defaultAccount) + .distributeFunds( + [await roles.oracleNode2.getAddress()], + [amountToSend], + { + value: ethSent, + }, + ), + 'Too much ETH sent', ) }) }) @@ -350,20 +350,20 @@ describe('Operator', () => { const amounts = [sendNode2, sendNode3] await operator - .connect(roles.defaultAccount) - .distributeFunds(receivers, amounts, { value: totalAmount }) + .connect(roles.defaultAccount) + .distributeFunds(receivers, amounts, { value: totalAmount }) const node2BalanceAfter = await roles.oracleNode2.getBalance() const node3BalanceAfter = await roles.oracleNode3.getBalance() assert.equal( - node2BalanceAfter.sub(node2BalanceBefore).toString(), - sendNode2.toString(), + node2BalanceAfter.sub(node2BalanceBefore).toString(), + sendNode2.toString(), ) assert.equal( - node3BalanceAfter.sub(node3BalanceBefore).toString(), - sendNode3.toString(), + node3BalanceAfter.sub(node3BalanceBefore).toString(), + sendNode3.toString(), ) }) }) @@ -381,8 +381,8 @@ describe('Operator', () => { await roles.oracleNode3.getAddress(), ] const tx = await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders(newSenders) + .connect(roles.defaultAccount) + .setAuthorizedSenders(newSenders) receipt = await tx.wait() }) @@ -398,8 +398,8 @@ describe('Operator', () => { assert.equal(receipt.events?.length, 1) const encodedSenders1 = ethers.utils.defaultAbiCoder.encode( - ['address[]', 'address'], - [newSenders, await roles.defaultAccount.getAddress()], + ['address[]', 'address'], + [newSenders, await roles.defaultAccount.getAddress()], ) const responseEvent1 = receipt.events?.[0] @@ -409,15 +409,15 @@ describe('Operator', () => { it('replaces the authorized nodes', async () => { const originalAuthorization = await operator - .connect(roles.defaultAccount) - .isAuthorizedSender(await roles.oracleNode.getAddress()) + .connect(roles.defaultAccount) + .isAuthorizedSender(await roles.oracleNode.getAddress()) assert.isFalse(originalAuthorization) }) after(async () => { await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders([await roles.oracleNode.getAddress()]) + .connect(roles.defaultAccount) + .setAuthorizedSenders([await roles.oracleNode.getAddress()]) }) }) @@ -428,10 +428,10 @@ describe('Operator', () => { it('reverts with a minimum senders message', async () => { await evmRevert( - operator - .connect(roles.defaultAccount) - .setAuthorizedSenders(newSenders), - 'Must have at least 1 sender', + operator + .connect(roles.defaultAccount) + .setAuthorizedSenders(newSenders), + 'Must have at least 1 sender', ) }) }) @@ -441,24 +441,24 @@ describe('Operator', () => { beforeEach(async () => { newSenders = [await roles.oracleNode1.getAddress()] await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders(newSenders) + .connect(roles.defaultAccount) + .setAuthorizedSenders(newSenders) }) it('succeeds', async () => { await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders([await roles.stranger.getAddress()]) + .connect(roles.defaultAccount) + .setAuthorizedSenders([await roles.stranger.getAddress()]) }) }) describe('when called by a non-owner', () => { it('cannot add an authorized node', async () => { await evmRevert( - operator - .connect(roles.stranger) - .setAuthorizedSenders([await roles.stranger.getAddress()]), - 'Cannot set authorized senders', + operator + .connect(roles.stranger) + .setAuthorizedSenders([await roles.stranger.getAddress()]), + 'Cannot set authorized senders', ) }) }) @@ -469,28 +469,28 @@ describe('Operator', () => { beforeEach(async () => { await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders([await roles.oracleNode1.getAddress()]) + .connect(roles.defaultAccount) + .setAuthorizedSenders([await roles.oracleNode1.getAddress()]) newSenders = [ await roles.oracleNode2.getAddress(), await roles.oracleNode3.getAddress(), ] forwarder1 = await forwarderFactory - .connect(owner) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(owner) + .deploy(link.address, operator.address, zeroAddress, '0x') forwarder2 = await forwarderFactory - .connect(owner) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(owner) + .deploy(link.address, operator.address, zeroAddress, '0x') }) describe('when called by a non-authorized sender', () => { it('reverts', async () => { await evmRevert( - operator - .connect(roles.stranger) - .setAuthorizedSendersOn(newSenders, [forwarder1.address]), - 'Cannot set authorized senders', + operator + .connect(roles.stranger) + .setAuthorizedSendersOn(newSenders, [forwarder1.address]), + 'Cannot set authorized senders', ) }) }) @@ -498,43 +498,43 @@ describe('Operator', () => { describe('when called by an owner', () => { it('does not revert', async () => { await operator - .connect(roles.defaultAccount) - .setAuthorizedSendersOn( - [forwarder1.address, forwarder2.address], - newSenders, - ) + .connect(roles.defaultAccount) + .setAuthorizedSendersOn( + [forwarder1.address, forwarder2.address], + newSenders, + ) }) }) describe('when called by an authorized sender', () => { it('does not revert', async () => { await operator - .connect(roles.oracleNode1) - .setAuthorizedSendersOn( - [forwarder1.address, forwarder2.address], - newSenders, - ) + .connect(roles.oracleNode1) + .setAuthorizedSendersOn( + [forwarder1.address, forwarder2.address], + newSenders, + ) }) it('does revert with 0 senders', async () => { await operator - .connect(roles.oracleNode1) - .setAuthorizedSendersOn( - [forwarder1.address, forwarder2.address], - newSenders, - ) + .connect(roles.oracleNode1) + .setAuthorizedSendersOn( + [forwarder1.address, forwarder2.address], + newSenders, + ) }) it('emits a log announcing the change and who made it', async () => { const targets = [forwarder1.address, forwarder2.address] const tx = await operator - .connect(roles.oracleNode1) - .setAuthorizedSendersOn(targets, newSenders) + .connect(roles.oracleNode1) + .setAuthorizedSendersOn(targets, newSenders) const receipt = await tx.wait() const encodedArgs = ethers.utils.defaultAbiCoder.encode( - ['address[]', 'address[]', 'address'], - [targets, newSenders, await roles.oracleNode1.getAddress()], + ['address[]', 'address[]', 'address'], + [targets, newSenders, await roles.oracleNode1.getAddress()], ) const event1 = receipt.events?.[0] @@ -545,17 +545,17 @@ describe('Operator', () => { it('updates the sender list on each of the targets', async () => { const tx = await operator - .connect(roles.oracleNode1) - .setAuthorizedSendersOn( - [forwarder1.address, forwarder2.address], - newSenders, - ) + .connect(roles.oracleNode1) + .setAuthorizedSendersOn( + [forwarder1.address, forwarder2.address], + newSenders, + ) const receipt = await tx.wait() assert.equal(receipt.events?.length, 3, receipt.toString()) const encodedSenders = ethers.utils.defaultAbiCoder.encode( - ['address[]', 'address'], - [newSenders, operator.address], + ['address[]', 'address'], + [newSenders, operator.address], ) const event1 = receipt.events?.[1] @@ -580,31 +580,31 @@ describe('Operator', () => { beforeEach(async () => { operator2 = await operatorFactory - .connect(roles.defaultAccount) - .deploy(link.address, await roles.defaultAccount.getAddress()) + .connect(roles.defaultAccount) + .deploy(link.address, await roles.defaultAccount.getAddress()) forwarder1 = await forwarderFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, zeroAddress, '0x') forwarder2 = await forwarderFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, zeroAddress, '0x') await operator - .connect(roles.defaultAccount) - .transferOwnableContracts( - [forwarder1.address, forwarder2.address], - operator2.address, - ) + .connect(roles.defaultAccount) + .transferOwnableContracts( + [forwarder1.address, forwarder2.address], + operator2.address, + ) newSenders = [ await roles.oracleNode2.getAddress(), await roles.oracleNode3.getAddress(), ] const tx = await operator2 - .connect(roles.defaultAccount) - .acceptAuthorizedReceivers( - [forwarder1.address, forwarder2.address], - newSenders, - ) + .connect(roles.defaultAccount) + .acceptAuthorizedReceivers( + [forwarder1.address, forwarder2.address], + newSenders, + ) receipt = await tx.wait() }) @@ -630,13 +630,13 @@ describe('Operator', () => { assert.equal(receipt?.events?.[3]?.args?.[1], operator2.address) assert.equal( - receipt?.events?.[4]?.event, - 'TargetsUpdatedAuthorizedSenders', + receipt?.events?.[4]?.event, + 'TargetsUpdatedAuthorizedSenders', ) const encodedSenders = ethers.utils.defaultAbiCoder.encode( - ['address[]', 'address'], - [newSenders, operator2.address], + ['address[]', 'address'], + [newSenders, operator2.address], ) assert.equal(receipt?.events?.[5]?.event, 'AuthorizedSendersChanged') assert.equal(receipt?.events?.[5]?.address, forwarder1.address) @@ -651,13 +651,13 @@ describe('Operator', () => { describe('being called by a non owner', () => { it('reverts with message', async () => { await evmRevert( - operator - .connect(roles.stranger) - .acceptAuthorizedReceivers( - [forwarder1.address, forwarder2.address], - newSenders, - ), - 'Cannot set authorized senders', + operator + .connect(roles.stranger) + .acceptAuthorizedReceivers( + [forwarder1.address, forwarder2.address], + newSenders, + ), + 'Cannot set authorized senders', ) }) }) @@ -667,19 +667,19 @@ describe('Operator', () => { describe('when called from any address but the LINK token', () => { it('triggers the intended method', async () => { const callData = encodeOracleRequest( - specId, - to, - fHash, - 0, - constants.HashZero, + specId, + to, + fHash, + 0, + constants.HashZero, ) await evmRevert( - operator.onTokenTransfer( - await roles.defaultAccount.getAddress(), - 0, - callData, - ), + operator.onTokenTransfer( + await roles.defaultAccount.getAddress(), + 0, + callData, + ), ) }) }) @@ -687,11 +687,11 @@ describe('Operator', () => { describe('when called from the LINK token', () => { it('triggers the intended method', async () => { const callData = encodeOracleRequest( - specId, - to, - fHash, - 0, - constants.HashZero, + specId, + to, + fHash, + 0, + constants.HashZero, ) const tx = await link.transferAndCall(operator.address, 0, callData, { @@ -705,9 +705,9 @@ describe('Operator', () => { describe('with no data', () => { it('reverts', async () => { await evmRevert( - link.transferAndCall(operator.address, 0, '0x', { - value: 0, - }), + link.transferAndCall(operator.address, 0, '0x', { + value: 0, + }), ) }) }) @@ -720,8 +720,8 @@ describe('Operator', () => { beforeEach(async () => { mock = await maliciousRequesterFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(mock.address, paymentAmount) }) @@ -750,8 +750,8 @@ describe('Operator', () => { it('the target requester can still create valid requests', async () => { requester = await basicConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) await link.transfer(requester.address, paymentAmount) await mock.maliciousTargetConsumer(requester.address) await requester.requestEthereumPrice('USD', paymentAmount) @@ -761,27 +761,27 @@ describe('Operator', () => { it('does not allow recursive calls of onTokenTransfer', async () => { const requestPayload = encodeOracleRequest( - specId, - to, - fHash, - 0, - constants.HashZero, + specId, + to, + fHash, + 0, + constants.HashZero, ) const ottSelector = - operatorFactory.interface.getSighash('onTokenTransfer') + operatorFactory.interface.getSighash('onTokenTransfer') const header = - '000000000000000000000000c5fdf4076b8f3a5357c5e395ab970b5b54098fef' + // to - '0000000000000000000000000000000000000000000000000000000000000539' + // amount - '0000000000000000000000000000000000000000000000000000000000000060' + // offset - '0000000000000000000000000000000000000000000000000000000000000136' // length + '000000000000000000000000c5fdf4076b8f3a5357c5e395ab970b5b54098fef' + // to + '0000000000000000000000000000000000000000000000000000000000000539' + // amount + '0000000000000000000000000000000000000000000000000000000000000060' + // offset + '0000000000000000000000000000000000000000000000000000000000000136' // length const maliciousPayload = ottSelector + header + requestPayload.slice(2) await evmRevert( - link.transferAndCall(operator.address, 0, maliciousPayload, { - value: 0, - }), + link.transferAndCall(operator.address, 0, maliciousPayload, { + value: 0, + }), ) }) }) @@ -794,11 +794,11 @@ describe('Operator', () => { beforeEach(async () => { const args = encodeOracleRequest( - specId, - to, - fHash, - 1, - constants.HashZero, + specId, + to, + fHash, + 1, + constants.HashZero, ) const tx = await link.transferAndCall(operator.address, paid, args) receipt = await tx.wait() @@ -820,17 +820,17 @@ describe('Operator', () => { it('uses the expected event signature', async () => { // If updating this test, be sure to update models.RunLogTopic. const eventSignature = - '0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65' + '0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65' assert.equal(eventSignature, log?.topics?.[0]) }) it('does not allow the same requestId to be used twice', async () => { const args2 = encodeOracleRequest( - specId, - to, - fHash, - 1, - constants.HashZero, + specId, + to, + fHash, + 1, + constants.HashZero, ) await evmRevert(link.transferAndCall(operator.address, paid, args2)) }) @@ -838,12 +838,12 @@ describe('Operator', () => { describe('when called with a payload between 3 and 9 EVM words', () => { it('throws an error', async () => { const funcSelector = - operatorFactory.interface.getSighash('oracleRequest') + operatorFactory.interface.getSighash('oracleRequest') const maliciousData = - funcSelector + - '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' + funcSelector + + '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' await evmRevert( - link.transferAndCall(operator.address, paid, maliciousData), + link.transferAndCall(operator.address, paid, maliciousData), ) }) }) @@ -853,12 +853,12 @@ describe('Operator', () => { it('throws an error', async () => { const paid = 100 const args = encodeOracleRequest( - specId, - to, - fHash, - 1, - constants.HashZero, - 256, + specId, + to, + fHash, + 1, + constants.HashZero, + 256, ) await evmRevert(link.transferAndCall(operator.address, paid, args)) }) @@ -867,18 +867,18 @@ describe('Operator', () => { describe('when not called through the LINK token', () => { it('reverts', async () => { await evmRevert( - operator - .connect(roles.oracleNode) - .oracleRequest( - '0x0000000000000000000000000000000000000000', - 0, - specId, - to, - fHash, - 1, - 1, - '0x', - ), + operator + .connect(roles.oracleNode) + .oracleRequest( + '0x0000000000000000000000000000000000000000', + 0, + specId, + to, + fHash, + 1, + 1, + '0x', + ), ) }) }) @@ -892,10 +892,10 @@ describe('Operator', () => { beforeEach(async () => { const args = encodeRequestOracleData( - specId, - fHash, - 1, - constants.HashZero, + specId, + fHash, + 1, + constants.HashZero, ) const tx = await link.transferAndCall(operator.address, paid, args) receipt = await tx.wait() @@ -917,16 +917,16 @@ describe('Operator', () => { it('uses the expected event signature', async () => { // If updating this test, be sure to update models.RunLogTopic. const eventSignature = - '0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65' + '0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65' assert.equal(eventSignature, log?.topics?.[0]) }) it('does not allow the same requestId to be used twice', async () => { const args2 = encodeRequestOracleData( - specId, - fHash, - 1, - constants.HashZero, + specId, + fHash, + 1, + constants.HashZero, ) await evmRevert(link.transferAndCall(operator.address, paid, args2)) }) @@ -936,11 +936,11 @@ describe('Operator', () => { it('throws an error', async () => { const paid = 100 const args = encodeRequestOracleData( - specId, - fHash, - 1, - constants.HashZero, - 256, + specId, + fHash, + 1, + constants.HashZero, + 256, ) await evmRevert(link.transferAndCall(operator.address, paid, args)) }) @@ -949,18 +949,18 @@ describe('Operator', () => { describe('when not called through the LINK token', () => { it('reverts', async () => { await evmRevert( - operator - .connect(roles.oracleNode) - .oracleRequest( - '0x0000000000000000000000000000000000000000', - 0, - specId, - to, - fHash, - 1, - 1, - '0x', - ), + operator + .connect(roles.oracleNode) + .oracleRequest( + '0x0000000000000000000000000000000000000000', + 0, + specId, + to, + fHash, + 1, + 1, + '0x', + ), ) }) }) @@ -977,12 +977,12 @@ describe('Operator', () => { describe('gas guzzling consumer [ @skip-coverage ]', () => { beforeEach(async () => { gasGuzzlingConsumer = await gasGuzzlingConsumerFactory - .connect(roles.consumer) - .deploy(link.address, operator.address, specId) + .connect(roles.consumer) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(gasGuzzlingConsumer.address, paymentAmount) const tx = - await gasGuzzlingConsumer.gassyRequestEthereumPrice(paymentAmount) + await gasGuzzlingConsumer.gassyRequestEthereumPrice(paymentAmount) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) }) @@ -990,8 +990,8 @@ describe('Operator', () => { it('emits an OracleResponse event', async () => { const fulfillParams = convertFufillParams(request, response) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 1) const responseEvent = receipt.events?.[0] @@ -1003,14 +1003,14 @@ describe('Operator', () => { describe('cooperative consumer', () => { beforeEach(async () => { basicConsumer = await basicConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(basicConsumer.address, paymentAmount) const currency = 'USD' const tx = await basicConsumer.requestEthereumPrice( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1019,18 +1019,18 @@ describe('Operator', () => { describe('when called by an unauthorized node', () => { beforeEach(async () => { assert.equal( - false, - await operator.isAuthorizedSender( - await roles.stranger.getAddress(), - ), + false, + await operator.isAuthorizedSender( + await roles.stranger.getAddress(), + ), ) }) it('raises an error', async () => { await evmRevert( - operator - .connect(roles.stranger) - .fulfillOracleRequest(...convertFufillParams(request, response)), + operator + .connect(roles.stranger) + .fulfillOracleRequest(...convertFufillParams(request, response)), ) }) }) @@ -1039,14 +1039,14 @@ describe('Operator', () => { let basicConsumer beforeEach(async () => { basicConsumer = await basicConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(basicConsumer.address, paymentAmount) const currency = 'USD' const tx = await basicConsumer.requestEthereumPrice( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1054,9 +1054,9 @@ describe('Operator', () => { it('raises an error', async () => { await evmRevert( - operator - .connect(roles.stranger) - .fulfillOracleRequest(...convertFufillParams(request, response)), + operator + .connect(roles.stranger) + .fulfillOracleRequest(...convertFufillParams(request, response)), ) }) }) @@ -1065,16 +1065,16 @@ describe('Operator', () => { it('raises an error if the request ID does not exist', async () => { request.requestId = ethers.utils.formatBytes32String('DOESNOTEXIST') await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)), ) }) it('sets the value on the requested contract', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) const currentValue = await basicConsumer.getCurrentPrice() assert.equal(response, ethers.utils.parseBytes32String(currentValue)) @@ -1083,8 +1083,8 @@ describe('Operator', () => { it('emits an OracleResponse event', async () => { const fulfillParams = convertFufillParams(request, response) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 3) const responseEvent = receipt.events?.[0] @@ -1096,13 +1096,13 @@ describe('Operator', () => { const response2 = response + ' && Hello World!!' await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response2)), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response2)), ) const currentValue = await basicConsumer.getCurrentPrice() @@ -1121,11 +1121,11 @@ describe('Operator', () => { it('does not allow the oracle to withdraw the payment', async () => { await evmRevert( - operator.connect(roles.oracleNode).fulfillOracleRequest( - ...convertFufillParams(request, response, { - gasLimit: 70000, - }), - ), + operator.connect(roles.oracleNode).fulfillOracleRequest( + ...convertFufillParams(request, response, { + gasLimit: 70000, + }), + ), ) bigNumEquals(0, await operator.withdrawable()) @@ -1133,9 +1133,9 @@ describe('Operator', () => { it(`${defaultGasLimit} is enough to pass the gas requirement`, async () => { await operator.connect(roles.oracleNode).fulfillOracleRequest( - ...convertFufillParams(request, response, { - gasLimit: defaultGasLimit, - }), + ...convertFufillParams(request, response, { + gasLimit: defaultGasLimit, + }), ) bigNumEquals(request.payment, await operator.withdrawable()) @@ -1147,17 +1147,17 @@ describe('Operator', () => { beforeEach(async () => { const paymentAmount = toWei('1') maliciousRequester = await maliciousRequesterFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousRequester.address, paymentAmount) }) it('cannot cancel before the expiration', async () => { await evmRevert( - maliciousRequester.maliciousRequestCancel( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), - ), + maliciousRequester.maliciousRequestCancel( + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + ), ) }) @@ -1188,16 +1188,16 @@ describe('Operator', () => { beforeEach(async () => { maliciousConsumer = await maliciousConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousConsumer.address, paymentAmount) }) describe('fails during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1205,20 +1205,20 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -1227,13 +1227,13 @@ describe('Operator', () => { const response2 = 'hack the planet 102' await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response2)), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response2)), ) }) }) @@ -1241,8 +1241,8 @@ describe('Operator', () => { describe('calls selfdestruct', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1251,19 +1251,19 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -1272,8 +1272,8 @@ describe('Operator', () => { describe('request is canceled during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('cancelRequestOnFulfill(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('cancelRequestOnFulfill(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1283,22 +1283,22 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) const mockBalance = await link.balanceOf(maliciousConsumer.address) bigNumEquals(mockBalance, 0) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -1307,13 +1307,13 @@ describe('Operator', () => { const response2 = 'hack the planet 102' await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response2)), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response2)), ) }) }) @@ -1321,53 +1321,53 @@ describe('Operator', () => { describe('tries to steal funds from node', () => { it('is not successful with call', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with send', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with transfer', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) }) @@ -1375,14 +1375,14 @@ describe('Operator', () => { describe('when calling an owned contract', () => { beforeEach(async () => { forwarder1 = await forwarderFactory - .connect(roles.defaultAccount) - .deploy(link.address, link.address, operator.address, '0x') + .connect(roles.defaultAccount) + .deploy(link.address, link.address, operator.address, '0x') }) it('does not allow the contract to callback to owned contracts', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('whatever(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('whatever(bytes32,bytes32)'), ) const receipt = await tx.wait() let request = decodeRunRequest(receipt.logs?.[3]) @@ -1392,26 +1392,26 @@ describe('Operator', () => { //accept ownership await operator - .connect(roles.defaultAccount) - .acceptOwnableContracts([forwarder1.address]) + .connect(roles.defaultAccount) + .acceptOwnableContracts([forwarder1.address]) // do the thing await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...responseParams), - 'Cannot call owned contract', + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...responseParams), + 'Cannot call owned contract', ) await operator - .connect(roles.defaultAccount) - .transferOwnableContracts([forwarder1.address], link.address) + .connect(roles.defaultAccount) + .transferOwnableContracts([forwarder1.address], link.address) //reverts for a different reason after transferring ownership await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...responseParams), - 'Params do not match request ID', + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...responseParams), + 'Params do not match request ID', ) }) }) @@ -1433,25 +1433,25 @@ describe('Operator', () => { describe('gas guzzling consumer [ @skip-coverage ]', () => { beforeEach(async () => { gasGuzzlingConsumer = await gasGuzzlingConsumerFactory - .connect(roles.consumer) - .deploy(link.address, operator.address, specId) + .connect(roles.consumer) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(gasGuzzlingConsumer.address, paymentAmount) const tx = - await gasGuzzlingConsumer.gassyRequestEthereumPrice(paymentAmount) + await gasGuzzlingConsumer.gassyRequestEthereumPrice(paymentAmount) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) }) it('emits an OracleResponse2 event', async () => { const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 1) const responseEvent = receipt.events?.[0] @@ -1463,14 +1463,14 @@ describe('Operator', () => { describe('cooperative consumer', () => { beforeEach(async () => { basicConsumer = await basicConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(basicConsumer.address, paymentAmount) const currency = 'USD' const tx = await basicConsumer.requestEthereumPrice( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1479,24 +1479,24 @@ describe('Operator', () => { describe('when called by an unauthorized node', () => { beforeEach(async () => { assert.equal( - false, - await operator.isAuthorizedSender( - await roles.stranger.getAddress(), - ), + false, + await operator.isAuthorizedSender( + await roles.stranger.getAddress(), + ), ) }) it('raises an error', async () => { await evmRevert( - operator - .connect(roles.stranger) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ), + operator + .connect(roles.stranger) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ), ) }) }) @@ -1505,45 +1505,45 @@ describe('Operator', () => { it('raises an error if the request ID does not exist', async () => { request.requestId = ethers.utils.formatBytes32String('DOESNOTEXIST') await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ), ) }) it('sets the value on the requested contract', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const currentValue = await basicConsumer.getCurrentPrice() assert.equal( - response, - ethers.utils.parseBytes32String(currentValue), + response, + ethers.utils.parseBytes32String(currentValue), ) }) it('emits an OracleResponse2 event', async () => { const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 3) const responseEvent = receipt.events?.[0] @@ -1555,31 +1555,31 @@ describe('Operator', () => { const response2 = response + ' && Hello World!!' const response2Values = [toBytes32String(response2)] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) - - await evmRevert( - operator .connect(roles.oracleNode) .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - response2Values, - ), - ), + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) + + await evmRevert( + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + response2Values, + ), + ), ) const currentValue = await basicConsumer.getCurrentPrice() assert.equal( - response, - ethers.utils.parseBytes32String(currentValue), + response, + ethers.utils.parseBytes32String(currentValue), ) }) }) @@ -1595,16 +1595,16 @@ describe('Operator', () => { it('does not allow the oracle to withdraw the payment', async () => { await evmRevert( - operator.connect(roles.oracleNode).fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - { - gasLimit: 70000, - }, + operator.connect(roles.oracleNode).fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + { + gasLimit: 70000, + }, + ), ), - ), ) bigNumEquals(0, await operator.withdrawable()) @@ -1612,9 +1612,9 @@ describe('Operator', () => { it(`${defaultGasLimit} is enough to pass the gas requirement`, async () => { await operator.connect(roles.oracleNode).fulfillOracleRequest2( - ...convertFulfill2Params(request, responseTypes, responseValues, { - gasLimit: defaultGasLimit, - }), + ...convertFulfill2Params(request, responseTypes, responseValues, { + gasLimit: defaultGasLimit, + }), ) bigNumEquals(request.payment, await operator.withdrawable()) @@ -1626,22 +1626,22 @@ describe('Operator', () => { beforeEach(async () => { // Setup Request 1 basicConsumer = await basicConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(basicConsumer.address, paymentAmount) const currency = 'USD' const tx = await basicConsumer.requestEthereumPrice( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) // Setup Request 2 await link.transfer(basicConsumer.address, paymentAmount) const tx2 = await basicConsumer.requestEthereumPrice( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt2 = await tx2.wait() request2 = decodeRunRequest(receipt2.logs?.[3]) @@ -1651,37 +1651,37 @@ describe('Operator', () => { // Malicious Oracle Fulfill 2 const functionSelector = '0x6ae0bc76' // fulfillOracleRequest2 const dataOffset = - '0000000000000000000000000000000000000000000000000000000000000100' // Moved to 0x0124 + '0000000000000000000000000000000000000000000000000000000000000100' // Moved to 0x0124 const fillerBytes = - '0000000000000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000000' const expectedCalldataStart = request.requestId.slice(2) // 0xe4, this is checked against requestId in validateMultiWordResponseId const dataSize = - '0000000000000000000000000000000000000000000000000000000000000040' // Two 32 byte blocks + '0000000000000000000000000000000000000000000000000000000000000040' // Two 32 byte blocks const maliciousCalldataId = request2.requestId.slice(2) // 0x0124, set to a different requestId const calldataData = - '1122334455667788991122334455667788991122334455667788991122334455' // some garbage value as response value + '1122334455667788991122334455667788991122334455667788991122334455' // some garbage value as response value const data = - functionSelector + - /** Input Params - slice off 0x prefix and pad with 0's */ - request.requestId.slice(2) + - request.payment.slice(2).padStart(64, '0') + - request.callbackAddr.slice(2).padStart(64, '0') + - request.callbackFunc.slice(2).padEnd(64, '0') + - request.expiration.slice(2).padStart(64, '0') + - // calldata "data" - dataOffset + - fillerBytes + - expectedCalldataStart + - dataSize + - maliciousCalldataId + - calldataData + functionSelector + + /** Input Params - slice off 0x prefix and pad with 0's */ + request.requestId.slice(2) + + request.payment.slice(2).padStart(64, '0') + + request.callbackAddr.slice(2).padStart(64, '0') + + request.callbackFunc.slice(2).padEnd(64, '0') + + request.expiration.slice(2).padStart(64, '0') + + // calldata "data" + dataOffset + + fillerBytes + + expectedCalldataStart + + dataSize + + maliciousCalldataId + + calldataData await evmRevert( - operator.connect(roles.oracleNode).signer.sendTransaction({ - to: operator.address, - data, - }), + operator.connect(roles.oracleNode).signer.sendTransaction({ + to: operator.address, + data, + }), ) }) }) @@ -1690,17 +1690,17 @@ describe('Operator', () => { beforeEach(async () => { const paymentAmount = toWei('1') maliciousRequester = await maliciousRequesterFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousRequester.address, paymentAmount) }) it('cannot cancel before the expiration', async () => { await evmRevert( - maliciousRequester.maliciousRequestCancel( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), - ), + maliciousRequester.maliciousRequestCancel( + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + ), ) }) @@ -1731,16 +1731,16 @@ describe('Operator', () => { beforeEach(async () => { maliciousConsumer = await maliciousConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousConsumer.address, paymentAmount) }) describe('fails during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1748,26 +1748,26 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -1776,34 +1776,34 @@ describe('Operator', () => { const response2 = 'hack the planet 102' const response2Values = [toBytes32String(response2)] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) - - await evmRevert( - operator .connect(roles.oracleNode) .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - response2Values, - ), - ), - ) - }) + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) + + await evmRevert( + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + response2Values, + ), + ), + ) + }) }) describe('calls selfdestruct', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1812,25 +1812,25 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -1839,10 +1839,10 @@ describe('Operator', () => { describe('request is canceled during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes( - 'cancelRequestOnFulfill(bytes32,bytes32)', - ), + specId, + ethers.utils.toUtf8Bytes( + 'cancelRequestOnFulfill(bytes32,bytes32)', + ), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1852,28 +1852,28 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const mockBalance = await link.balanceOf(maliciousConsumer.address) bigNumEquals(mockBalance, 0) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -1883,25 +1883,25 @@ describe('Operator', () => { const response2Values = [toBytes32String(response2)] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) - - await evmRevert( - operator .connect(roles.oracleNode) .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - response2Values, - ), - ), + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) + + await evmRevert( + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + response2Values, + ), + ), ) }) }) @@ -1909,71 +1909,71 @@ describe('Operator', () => { describe('tries to steal funds from node', () => { it('is not successful with call', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with send', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with transfer', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) }) @@ -1981,14 +1981,14 @@ describe('Operator', () => { describe('when calling an owned contract', () => { beforeEach(async () => { forwarder1 = await forwarderFactory - .connect(roles.defaultAccount) - .deploy(link.address, link.address, operator.address, '0x') + .connect(roles.defaultAccount) + .deploy(link.address, link.address, operator.address, '0x') }) it('does not allow the contract to callback to owned contracts', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('whatever(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('whatever(bytes32,bytes32)'), ) const receipt = await tx.wait() let request = decodeRunRequest(receipt.logs?.[3]) @@ -1998,26 +1998,26 @@ describe('Operator', () => { //accept ownership await operator - .connect(roles.defaultAccount) - .acceptOwnableContracts([forwarder1.address]) + .connect(roles.defaultAccount) + .acceptOwnableContracts([forwarder1.address]) // do the thing await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...responseParams), - 'Cannot call owned contract', + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2(...responseParams), + 'Cannot call owned contract', ) await operator - .connect(roles.defaultAccount) - .transferOwnableContracts([forwarder1.address], link.address) + .connect(roles.defaultAccount) + .transferOwnableContracts([forwarder1.address], link.address) //reverts for a different reason after transferring ownership await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...responseParams), - 'Params do not match request ID', + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...responseParams), + 'Params do not match request ID', ) }) }) @@ -2027,8 +2027,8 @@ describe('Operator', () => { describe('multi word fulfills', () => { describe('one bytes parameter', () => { const response = - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.\ - Fusce euismod malesuada ligula, eget semper metus ultrices sit amet.' + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.\ + Fusce euismod malesuada ligula, eget semper metus ultrices sit amet.' const responseTypes = ['bytes'] const responseValues = [stringToBytes(response)] let maliciousRequester: Contract @@ -2040,25 +2040,25 @@ describe('Operator', () => { describe('gas guzzling consumer [ @skip-coverage ]', () => { beforeEach(async () => { gasGuzzlingConsumer = await gasGuzzlingConsumerFactory - .connect(roles.consumer) - .deploy(link.address, operator.address, specId) + .connect(roles.consumer) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(gasGuzzlingConsumer.address, paymentAmount) const tx = - await gasGuzzlingConsumer.gassyMultiWordRequest(paymentAmount) + await gasGuzzlingConsumer.gassyMultiWordRequest(paymentAmount) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) }) it('emits an OracleResponse2 event', async () => { const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 1) const responseEvent = receipt.events?.[0] @@ -2070,14 +2070,14 @@ describe('Operator', () => { describe('cooperative consumer', () => { beforeEach(async () => { multiConsumer = await multiWordConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(multiConsumer.address, paymentAmount) const currency = 'USD' const tx = await multiConsumer.requestEthereumPrice( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2089,8 +2089,8 @@ describe('Operator', () => { const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) const packed = ethers.utils.solidityPack( - ['address', 'uint256'], - [multiConsumer.address, nonce], + ['address', 'uint256'], + [multiConsumer.address, nonce], ) const expected = ethers.utils.keccak256(packed) assert.equal(expected, request.requestId) @@ -2099,24 +2099,24 @@ describe('Operator', () => { describe('when called by an unauthorized node', () => { beforeEach(async () => { assert.equal( - false, - await operator.isAuthorizedSender( - await roles.stranger.getAddress(), - ), + false, + await operator.isAuthorizedSender( + await roles.stranger.getAddress(), + ), ) }) it('raises an error', async () => { await evmRevert( - operator - .connect(roles.stranger) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ), + operator + .connect(roles.stranger) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ), ) }) }) @@ -2124,30 +2124,30 @@ describe('Operator', () => { describe('when called by an authorized node', () => { it('raises an error if the request ID does not exist', async () => { request.requestId = - ethers.utils.formatBytes32String('DOESNOTEXIST') + ethers.utils.formatBytes32String('DOESNOTEXIST') await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ), ) }) it('sets the value on the requested contract', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const currentValue = await multiConsumer.getCurrentPrice() assert.equal(response, ethers.utils.toUtf8String(currentValue)) @@ -2155,13 +2155,13 @@ describe('Operator', () => { it('emits an OracleResponse2 event', async () => { const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 3) const responseEvent = receipt.events?.[0] @@ -2174,25 +2174,25 @@ describe('Operator', () => { const response2Values = [stringToBytes(response2)] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) - - await evmRevert( - operator .connect(roles.oracleNode) .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - response2Values, - ), - ), + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) + + await evmRevert( + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + response2Values, + ), + ), ) const currentValue = await multiConsumer.getCurrentPrice() @@ -2211,16 +2211,16 @@ describe('Operator', () => { it('does not allow the oracle to withdraw the payment', async () => { await evmRevert( - operator.connect(roles.oracleNode).fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - { - gasLimit: 70000, - }, + operator.connect(roles.oracleNode).fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + { + gasLimit: 70000, + }, + ), ), - ), ) bigNumEquals(0, await operator.withdrawable()) @@ -2228,14 +2228,14 @@ describe('Operator', () => { it(`${defaultGasLimit} is enough to pass the gas requirement`, async () => { await operator.connect(roles.oracleNode).fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - { - gasLimit: defaultGasLimit, - }, - ), + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + { + gasLimit: defaultGasLimit, + }, + ), ) bigNumEquals(request.payment, await operator.withdrawable()) @@ -2247,17 +2247,17 @@ describe('Operator', () => { beforeEach(async () => { const paymentAmount = toWei('1') maliciousRequester = await maliciousRequesterFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousRequester.address, paymentAmount) }) it('cannot cancel before the expiration', async () => { await evmRevert( - maliciousRequester.maliciousRequestCancel( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), - ), + maliciousRequester.maliciousRequestCancel( + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + ), ) }) @@ -2288,16 +2288,16 @@ describe('Operator', () => { beforeEach(async () => { maliciousConsumer = await maliciousMultiWordConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousConsumer.address, paymentAmount) }) describe('fails during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2305,26 +2305,26 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -2333,25 +2333,25 @@ describe('Operator', () => { const response2 = 'hack the planet 102' const response2Values = [stringToBytes(response2)] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) - - await evmRevert( - operator .connect(roles.oracleNode) .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - response2Values, - ), - ), + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) + + await evmRevert( + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + response2Values, + ), + ), ) }) }) @@ -2359,8 +2359,8 @@ describe('Operator', () => { describe('calls selfdestruct', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2369,25 +2369,25 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -2396,10 +2396,10 @@ describe('Operator', () => { describe('request is canceled during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes( - 'cancelRequestOnFulfill(bytes32,bytes32)', - ), + specId, + ethers.utils.toUtf8Bytes( + 'cancelRequestOnFulfill(bytes32,bytes32)', + ), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2409,30 +2409,30 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const mockBalance = await link.balanceOf( - maliciousConsumer.address, + maliciousConsumer.address, ) bigNumEquals(mockBalance, 0) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -2441,25 +2441,25 @@ describe('Operator', () => { const response2 = 'hack the planet 102' const response2Values = [stringToBytes(response2)] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) - - await evmRevert( - operator .connect(roles.oracleNode) .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - response2Values, - ), - ), + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) + + await evmRevert( + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + response2Values, + ), + ), ) }) }) @@ -2467,71 +2467,71 @@ describe('Operator', () => { describe('tries to steal funds from node', () => { it('is not successful with call', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with send', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with transfer', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) }) @@ -2557,25 +2557,25 @@ describe('Operator', () => { describe('gas guzzling consumer [ @skip-coverage ]', () => { beforeEach(async () => { gasGuzzlingConsumer = await gasGuzzlingConsumerFactory - .connect(roles.consumer) - .deploy(link.address, operator.address, specId) + .connect(roles.consumer) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(gasGuzzlingConsumer.address, paymentAmount) const tx = - await gasGuzzlingConsumer.gassyMultiWordRequest(paymentAmount) + await gasGuzzlingConsumer.gassyMultiWordRequest(paymentAmount) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) }) it('emits an OracleResponse2 event', async () => { const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 1) const responseEvent = receipt.events?.[0] @@ -2587,14 +2587,14 @@ describe('Operator', () => { describe('cooperative consumer', () => { beforeEach(async () => { multiConsumer = await multiWordConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(multiConsumer.address, paymentAmount) const currency = 'USD' const tx = await multiConsumer.requestMultipleParameters( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2603,24 +2603,24 @@ describe('Operator', () => { describe('when called by an unauthorized node', () => { beforeEach(async () => { assert.equal( - false, - await operator.isAuthorizedSender( - await roles.stranger.getAddress(), - ), + false, + await operator.isAuthorizedSender( + await roles.stranger.getAddress(), + ), ) }) it('raises an error', async () => { await evmRevert( - operator - .connect(roles.stranger) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ), + operator + .connect(roles.stranger) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ), ) }) }) @@ -2628,57 +2628,57 @@ describe('Operator', () => { describe('when called by an authorized node', () => { it('raises an error if the request ID does not exist', async () => { request.requestId = - ethers.utils.formatBytes32String('DOESNOTEXIST') + ethers.utils.formatBytes32String('DOESNOTEXIST') await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ), ) }) it('sets the value on the requested contract', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const firstValue = await multiConsumer.usd() const secondValue = await multiConsumer.eur() const thirdValue = await multiConsumer.jpy() assert.equal( - response1, - ethers.utils.parseBytes32String(firstValue), + response1, + ethers.utils.parseBytes32String(firstValue), ) assert.equal( - response2, - ethers.utils.parseBytes32String(secondValue), + response2, + ethers.utils.parseBytes32String(secondValue), ) assert.equal( - response3, - ethers.utils.parseBytes32String(thirdValue), + response3, + ethers.utils.parseBytes32String(thirdValue), ) }) it('emits an OracleResponse2 event', async () => { const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 3) const responseEvent = receipt.events?.[0] @@ -2695,41 +2695,41 @@ describe('Operator', () => { ] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) - - await evmRevert( - operator .connect(roles.oracleNode) .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - repeatedResponseValues, - ), - ), + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) + + await evmRevert( + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + repeatedResponseValues, + ), + ), ) const firstValue = await multiConsumer.usd() const secondValue = await multiConsumer.eur() const thirdValue = await multiConsumer.jpy() assert.equal( - response1, - ethers.utils.parseBytes32String(firstValue), + response1, + ethers.utils.parseBytes32String(firstValue), ) assert.equal( - response2, - ethers.utils.parseBytes32String(secondValue), + response2, + ethers.utils.parseBytes32String(secondValue), ) assert.equal( - response3, - ethers.utils.parseBytes32String(thirdValue), + response3, + ethers.utils.parseBytes32String(thirdValue), ) }) }) @@ -2745,16 +2745,16 @@ describe('Operator', () => { it('does not allow the oracle to withdraw the payment', async () => { await evmRevert( - operator.connect(roles.oracleNode).fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - { - gasLimit: 70000, - }, + operator.connect(roles.oracleNode).fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + { + gasLimit: 70000, + }, + ), ), - ), ) bigNumEquals(0, await operator.withdrawable()) @@ -2762,14 +2762,14 @@ describe('Operator', () => { it(`${defaultGasLimit} is enough to pass the gas requirement`, async () => { await operator.connect(roles.oracleNode).fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - { - gasLimit: defaultGasLimit, - }, - ), + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + { + gasLimit: defaultGasLimit, + }, + ), ) bigNumEquals(request.payment, await operator.withdrawable()) @@ -2781,17 +2781,17 @@ describe('Operator', () => { beforeEach(async () => { const paymentAmount = toWei('1') maliciousRequester = await maliciousRequesterFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousRequester.address, paymentAmount) }) it('cannot cancel before the expiration', async () => { await evmRevert( - maliciousRequester.maliciousRequestCancel( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), - ), + maliciousRequester.maliciousRequestCancel( + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + ), ) }) @@ -2822,16 +2822,16 @@ describe('Operator', () => { beforeEach(async () => { maliciousConsumer = await maliciousMultiWordConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousConsumer.address, paymentAmount) }) describe('fails during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2839,26 +2839,26 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -2871,25 +2871,25 @@ describe('Operator', () => { toBytes32String(response4), ] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) - - await evmRevert( - operator .connect(roles.oracleNode) .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - repeatedResponseValues, - ), - ), + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) + + await evmRevert( + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + repeatedResponseValues, + ), + ), ) }) }) @@ -2897,8 +2897,8 @@ describe('Operator', () => { describe('calls selfdestruct', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2907,25 +2907,25 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -2934,10 +2934,10 @@ describe('Operator', () => { describe('request is canceled during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes( - 'cancelRequestOnFulfill(bytes32,bytes32)', - ), + specId, + ethers.utils.toUtf8Bytes( + 'cancelRequestOnFulfill(bytes32,bytes32)', + ), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2947,30 +2947,30 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const mockBalance = await link.balanceOf( - maliciousConsumer.address, + maliciousConsumer.address, ) bigNumEquals(mockBalance, 0) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -2983,25 +2983,25 @@ describe('Operator', () => { toBytes32String(response4), ] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) - - await evmRevert( - operator .connect(roles.oracleNode) .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - repeatedResponseValues, - ), - ), + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) + + await evmRevert( + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + repeatedResponseValues, + ), + ), ) }) }) @@ -3009,71 +3009,71 @@ describe('Operator', () => { describe('tries to steal funds from node', () => { it('is not successful with call', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with send', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with transfer', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) }) @@ -3088,28 +3088,28 @@ describe('Operator', () => { it('reverts', async () => { let basicConsumer = await basicConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(basicConsumer.address, paymentAmount) const tx = await basicConsumer.requestEthereumPrice( - 'USD', - paymentAmount, + 'USD', + paymentAmount, ) const receipt = await tx.wait() let request = decodeRunRequest(receipt.logs?.[3]) const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) fulfillParams[5] = '0x' // overwrite the data to be of lenght 0 await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams), - 'Response must be > 32 bytes', + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams), + 'Response must be > 32 bytes', ) }) }) @@ -3121,9 +3121,9 @@ describe('Operator', () => { let balance = await link.balanceOf(await roles.oracleNode.getAddress()) assert.equal(0, balance.toNumber()) await evmRevert( - operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), toWei('1')), + operator + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), toWei('1')), ) balance = await link.balanceOf(await roles.oracleNode.getAddress()) assert.equal(0, balance.toNumber()) @@ -3138,22 +3138,22 @@ describe('Operator', () => { it('withdraws funds', async () => { const operatorBalanceBefore = await link.balanceOf(operator.address) const accountBalanceBefore = await link.balanceOf( - await roles.defaultAccount.getAddress(), + await roles.defaultAccount.getAddress(), ) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.defaultAccount.getAddress(), paid) + .connect(roles.defaultAccount) + .withdraw(await roles.defaultAccount.getAddress(), paid) const operatorBalanceAfter = await link.balanceOf(operator.address) const accountBalanceAfter = await link.balanceOf( - await roles.defaultAccount.getAddress(), + await roles.defaultAccount.getAddress(), ) const accountDifference = - accountBalanceAfter.sub(accountBalanceBefore) + accountBalanceAfter.sub(accountBalanceBefore) const operatorDifference = - operatorBalanceBefore.sub(operatorBalanceAfter) + operatorBalanceBefore.sub(operatorBalanceAfter) bigNumEquals(operatorDifference, paid) bigNumEquals(accountDifference, paid) @@ -3168,11 +3168,11 @@ describe('Operator', () => { beforeEach(async () => { const requester = await roles.defaultAccount.getAddress() const args = encodeOracleRequest( - specId, - requester, - fHash, - 0, - constants.HashZero, + specId, + requester, + fHash, + 0, + constants.HashZero, ) const tx = await link.transferAndCall(operator.address, payment, args) const receipt = await tx.wait() @@ -3183,12 +3183,12 @@ describe('Operator', () => { describe('but not freeing funds w fulfillOracleRequest', () => { it('does not transfer funds', async () => { await evmRevert( - operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), payment), + operator + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), payment), ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) assert.equal(0, balance.toNumber()) }) @@ -3202,22 +3202,22 @@ describe('Operator', () => { it('withdraws funds', async () => { const operatorBalanceBefore = await link.balanceOf(operator.address) const accountBalanceBefore = await link.balanceOf( - await roles.defaultAccount.getAddress(), + await roles.defaultAccount.getAddress(), ) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.defaultAccount.getAddress(), paid) + .connect(roles.defaultAccount) + .withdraw(await roles.defaultAccount.getAddress(), paid) const operatorBalanceAfter = await link.balanceOf(operator.address) const accountBalanceAfter = await link.balanceOf( - await roles.defaultAccount.getAddress(), + await roles.defaultAccount.getAddress(), ) const accountDifference = - accountBalanceAfter.sub(accountBalanceBefore) + accountBalanceAfter.sub(accountBalanceBefore) const operatorDifference = - operatorBalanceBefore.sub(operatorBalanceAfter) + operatorBalanceBefore.sub(operatorBalanceAfter) bigNumEquals(operatorDifference, paid) bigNumEquals(accountDifference, paid) @@ -3228,38 +3228,38 @@ describe('Operator', () => { describe('and freeing funds', () => { beforeEach(async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest( - ...convertFufillParams(request, 'Hello World!'), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest( + ...convertFufillParams(request, 'Hello World!'), + ) }) it('does not allow input greater than the balance', async () => { const originalOracleBalance = await link.balanceOf(operator.address) const originalStrangerBalance = await link.balanceOf( - await roles.stranger.getAddress(), + await roles.stranger.getAddress(), ) const withdrawalAmount = payment + 1 assert.isAbove(withdrawalAmount, originalOracleBalance.toNumber()) await evmRevert( - operator - .connect(roles.defaultAccount) - .withdraw(await roles.stranger.getAddress(), withdrawalAmount), + operator + .connect(roles.defaultAccount) + .withdraw(await roles.stranger.getAddress(), withdrawalAmount), ) const newOracleBalance = await link.balanceOf(operator.address) const newStrangerBalance = await link.balanceOf( - await roles.stranger.getAddress(), + await roles.stranger.getAddress(), ) assert.equal( - originalOracleBalance.toNumber(), - newOracleBalance.toNumber(), + originalOracleBalance.toNumber(), + newOracleBalance.toNumber(), ) assert.equal( - originalStrangerBalance.toNumber(), - newStrangerBalance.toNumber(), + originalStrangerBalance.toNumber(), + newStrangerBalance.toNumber(), ) }) @@ -3267,10 +3267,10 @@ describe('Operator', () => { const partialAmount = 6 const difference = payment - partialAmount await operator - .connect(roles.defaultAccount) - .withdraw(await roles.stranger.getAddress(), partialAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.stranger.getAddress(), partialAmount) const strangerBalance = await link.balanceOf( - await roles.stranger.getAddress(), + await roles.stranger.getAddress(), ) const oracleBalance = await link.balanceOf(operator.address) assert.equal(partialAmount, strangerBalance.toNumber()) @@ -3279,22 +3279,22 @@ describe('Operator', () => { it('allows transfer of entire balance by owner to specified address', async () => { await operator - .connect(roles.defaultAccount) - .withdraw(await roles.stranger.getAddress(), payment) + .connect(roles.defaultAccount) + .withdraw(await roles.stranger.getAddress(), payment) const balance = await link.balanceOf( - await roles.stranger.getAddress(), + await roles.stranger.getAddress(), ) assert.equal(payment, balance.toNumber()) }) it('does not allow a transfer of funds by non-owner', async () => { await evmRevert( - operator - .connect(roles.stranger) - .withdraw(await roles.stranger.getAddress(), payment), + operator + .connect(roles.stranger) + .withdraw(await roles.stranger.getAddress(), payment), ) const balance = await link.balanceOf( - await roles.stranger.getAddress(), + await roles.stranger.getAddress(), ) assert.isTrue(ethers.constants.Zero.eq(balance)) }) @@ -3308,22 +3308,22 @@ describe('Operator', () => { it('withdraws funds', async () => { const operatorBalanceBefore = await link.balanceOf(operator.address) const accountBalanceBefore = await link.balanceOf( - await roles.defaultAccount.getAddress(), + await roles.defaultAccount.getAddress(), ) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.defaultAccount.getAddress(), paid) + .connect(roles.defaultAccount) + .withdraw(await roles.defaultAccount.getAddress(), paid) const operatorBalanceAfter = await link.balanceOf(operator.address) const accountBalanceAfter = await link.balanceOf( - await roles.defaultAccount.getAddress(), + await roles.defaultAccount.getAddress(), ) const accountDifference = - accountBalanceAfter.sub(accountBalanceBefore) + accountBalanceAfter.sub(accountBalanceBefore) const operatorDifference = - operatorBalanceBefore.sub(operatorBalanceAfter) + operatorBalanceBefore.sub(operatorBalanceAfter) bigNumEquals(operatorDifference, paid) bigNumEquals(accountDifference, paid) @@ -3340,19 +3340,19 @@ describe('Operator', () => { beforeEach(async () => { const requester = await roles.defaultAccount.getAddress() const args = encodeOracleRequest( - specId, - requester, - fHash, - 0, - constants.HashZero, + specId, + requester, + fHash, + 0, + constants.HashZero, ) const tx = await link.transferAndCall(operator.address, amount, args) const receipt = await tx.wait() assert.equal(3, receipt.logs?.length) request = decodeRunRequest(receipt.logs?.[2]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, 'Hello World!')) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, 'Hello World!')) }) it('returns the correct value', async () => { @@ -3384,15 +3384,15 @@ describe('Operator', () => { beforeEach(async () => { operator2 = await operatorFactory - .connect(roles.oracleNode2) - .deploy(link.address, await roles.oracleNode2.getAddress()) + .connect(roles.oracleNode2) + .deploy(link.address, await roles.oracleNode2.getAddress()) to = operator2.address args = encodeOracleRequest( - specId, - operator.address, - operatorFactory.interface.getSighash('fulfillOracleRequest'), - 1, - constants.HashZero, + specId, + operator.address, + operatorFactory.interface.getSighash('fulfillOracleRequest'), + 1, + constants.HashZero, ) }) @@ -3400,10 +3400,10 @@ describe('Operator', () => { it('reverts with owner error message', async () => { await link.transfer(operator.address, startingBalance) await evmRevert( - operator - .connect(roles.stranger) - .ownerTransferAndCall(to, payment, args), - 'Only callable by owner', + operator + .connect(roles.stranger) + .ownerTransferAndCall(to, payment, args), + 'Only callable by owner', ) }) }) @@ -3417,10 +3417,10 @@ describe('Operator', () => { it('reverts with funds message', async () => { const tooMuch = startingBalance * 2 await evmRevert( - operator - .connect(roles.defaultAccount) - .ownerTransferAndCall(to, tooMuch, args), - 'Amount requested is greater than withdrawable balance', + operator + .connect(roles.defaultAccount) + .ownerTransferAndCall(to, tooMuch, args), + 'Amount requested is greater than withdrawable balance', ) }) }) @@ -3437,8 +3437,8 @@ describe('Operator', () => { requesterBalanceBefore = await link.balanceOf(operator.address) receiverBalanceBefore = await link.balanceOf(operator2.address) tx = await operator - .connect(roles.defaultAccount) - .ownerTransferAndCall(to, payment, args) + .connect(roles.defaultAccount) + .ownerTransferAndCall(to, payment, args) receipt = await tx.wait() requesterBalanceAfter = await link.balanceOf(operator.address) receiverBalanceAfter = await link.balanceOf(operator2.address) @@ -3456,8 +3456,8 @@ describe('Operator', () => { it('transfers the tokens', async () => { bigNumEquals( - requesterBalanceBefore.sub(requesterBalanceAfter), - payment, + requesterBalanceBefore.sub(requesterBalanceAfter), + payment, ) bigNumEquals(receiverBalanceAfter.sub(receiverBalanceBefore), payment) }) @@ -3474,7 +3474,7 @@ describe('Operator', () => { requestId: ethers.utils.formatBytes32String('1337'), payment: '0', callbackFunc: - getterSetterFactory.interface.getSighash('requestedBytes32'), + getterSetterFactory.interface.getSighash('requestedBytes32'), expiration: '999999999999', callbackAddr: '', @@ -3487,11 +3487,11 @@ describe('Operator', () => { await increaseTime5Minutes(ethers.provider) await evmRevert( - operator - .connect(roles.stranger) - .cancelOracleRequestByRequester( - ...convertCancelByRequesterParams(fakeRequest, nonce), - ), + operator + .connect(roles.stranger) + .cancelOracleRequestByRequester( + ...convertCancelByRequesterParams(fakeRequest, nonce), + ), ) }) }) @@ -3507,15 +3507,15 @@ describe('Operator', () => { await link.transfer(await roles.consumer.getAddress(), startingBalance) const args = encodeOracleRequest( - specId, - await roles.consumer.getAddress(), - fHash, - nonce, - constants.HashZero, + specId, + await roles.consumer.getAddress(), + fHash, + nonce, + constants.HashZero, ) const tx = await link - .connect(roles.consumer) - .transferAndCall(operator.address, requestAmount, args) + .connect(roles.consumer) + .transferAndCall(operator.address, requestAmount, args) receipt = await tx.wait() assert.equal(3, receipt.logs?.length) @@ -3526,22 +3526,22 @@ describe('Operator', () => { bigNumEquals(request.payment, oracleBalance) const consumerAmount = await link.balanceOf( - await roles.consumer.getAddress(), + await roles.consumer.getAddress(), ) assert.equal( - startingBalance - Number(request.payment), - consumerAmount.toNumber(), + startingBalance - Number(request.payment), + consumerAmount.toNumber(), ) }) describe('from a stranger', () => { it('fails', async () => { await evmRevert( - operator - .connect(roles.consumer) - .cancelOracleRequestByRequester( - ...convertCancelByRequesterParams(request, nonce), - ), + operator + .connect(roles.consumer) + .cancelOracleRequestByRequester( + ...convertCancelByRequesterParams(request, nonce), + ), ) }) }) @@ -3550,12 +3550,12 @@ describe('Operator', () => { it('refunds the correct amount', async () => { await increaseTime5Minutes(ethers.provider) await operator - .connect(roles.consumer) - .cancelOracleRequestByRequester( - ...convertCancelByRequesterParams(request, nonce), - ) + .connect(roles.consumer) + .cancelOracleRequestByRequester( + ...convertCancelByRequesterParams(request, nonce), + ) const balance = await link.balanceOf( - await roles.consumer.getAddress(), + await roles.consumer.getAddress(), ) assert.equal(startingBalance, balance.toNumber()) // 100 @@ -3564,10 +3564,10 @@ describe('Operator', () => { it('triggers a cancellation event', async () => { await increaseTime5Minutes(ethers.provider) const tx = await operator - .connect(roles.consumer) - .cancelOracleRequestByRequester( - ...convertCancelByRequesterParams(request, nonce), - ) + .connect(roles.consumer) + .cancelOracleRequestByRequester( + ...convertCancelByRequesterParams(request, nonce), + ) const receipt = await tx.wait() assert.equal(receipt.logs?.length, 2) @@ -3577,15 +3577,15 @@ describe('Operator', () => { it('fails when called twice', async () => { await increaseTime5Minutes(ethers.provider) await operator - .connect(roles.consumer) - .cancelOracleRequestByRequester( - ...convertCancelByRequesterParams(request, nonce), - ) + .connect(roles.consumer) + .cancelOracleRequestByRequester( + ...convertCancelByRequesterParams(request, nonce), + ) await evmRevert( - operator - .connect(roles.consumer) - .cancelOracleRequestByRequester(...convertCancelParams(request)), + operator + .connect(roles.consumer) + .cancelOracleRequestByRequester(...convertCancelParams(request)), ) }) }) @@ -3599,7 +3599,7 @@ describe('Operator', () => { requestId: ethers.utils.formatBytes32String('1337'), payment: '0', callbackFunc: - getterSetterFactory.interface.getSighash('requestedBytes32'), + getterSetterFactory.interface.getSighash('requestedBytes32'), expiration: '999999999999', callbackAddr: '', @@ -3612,9 +3612,9 @@ describe('Operator', () => { await increaseTime5Minutes(ethers.provider) await evmRevert( - operator - .connect(roles.stranger) - .cancelOracleRequest(...convertCancelParams(fakeRequest)), + operator + .connect(roles.stranger) + .cancelOracleRequest(...convertCancelParams(fakeRequest)), ) }) }) @@ -3630,15 +3630,15 @@ describe('Operator', () => { await link.transfer(await roles.consumer.getAddress(), startingBalance) const args = encodeOracleRequest( - specId, - await roles.consumer.getAddress(), - fHash, - 1, - constants.HashZero, + specId, + await roles.consumer.getAddress(), + fHash, + 1, + constants.HashZero, ) const tx = await link - .connect(roles.consumer) - .transferAndCall(operator.address, requestAmount, args) + .connect(roles.consumer) + .transferAndCall(operator.address, requestAmount, args) receipt = await tx.wait() assert.equal(3, receipt.logs?.length) @@ -3650,20 +3650,20 @@ describe('Operator', () => { bigNumEquals(request.payment, oracleBalance) const consumerAmount = await link.balanceOf( - await roles.consumer.getAddress(), + await roles.consumer.getAddress(), ) assert.equal( - startingBalance - Number(request.payment), - consumerAmount.toNumber(), + startingBalance - Number(request.payment), + consumerAmount.toNumber(), ) }) describe('from a stranger', () => { it('fails', async () => { await evmRevert( - operator - .connect(roles.consumer) - .cancelOracleRequest(...convertCancelParams(request)), + operator + .connect(roles.consumer) + .cancelOracleRequest(...convertCancelParams(request)), ) }) }) @@ -3672,10 +3672,10 @@ describe('Operator', () => { it('refunds the correct amount', async () => { await increaseTime5Minutes(ethers.provider) await operator - .connect(roles.consumer) - .cancelOracleRequest(...convertCancelParams(request)) + .connect(roles.consumer) + .cancelOracleRequest(...convertCancelParams(request)) const balance = await link.balanceOf( - await roles.consumer.getAddress(), + await roles.consumer.getAddress(), ) assert.equal(startingBalance, balance.toNumber()) // 100 @@ -3684,8 +3684,8 @@ describe('Operator', () => { it('triggers a cancellation event', async () => { await increaseTime5Minutes(ethers.provider) const tx = await operator - .connect(roles.consumer) - .cancelOracleRequest(...convertCancelParams(request)) + .connect(roles.consumer) + .cancelOracleRequest(...convertCancelParams(request)) const receipt = await tx.wait() assert.equal(receipt.logs?.length, 2) @@ -3695,13 +3695,13 @@ describe('Operator', () => { it('fails when called twice', async () => { await increaseTime5Minutes(ethers.provider) await operator - .connect(roles.consumer) - .cancelOracleRequest(...convertCancelParams(request)) + .connect(roles.consumer) + .cancelOracleRequest(...convertCancelParams(request)) await evmRevert( - operator - .connect(roles.consumer) - .cancelOracleRequest(...convertCancelParams(request)), + operator + .connect(roles.consumer) + .cancelOracleRequest(...convertCancelParams(request)), ) }) }) @@ -3716,8 +3716,8 @@ describe('Operator', () => { beforeEach(async () => { bytes = ethers.utils.hexlify(ethers.utils.randomBytes(100)) payload = getterSetterFactory.interface.encodeFunctionData( - getterSetterFactory.interface.getFunction('setBytes'), - [bytes], + getterSetterFactory.interface.getFunction('setBytes'), + [bytes], ) mock = await getterSetterFactory.connect(roles.defaultAccount).deploy() }) @@ -3725,7 +3725,7 @@ describe('Operator', () => { describe('when called by a non-owner', () => { it('reverts', async () => { await evmRevert( - operator.connect(roles.stranger).ownerForward(mock.address, payload), + operator.connect(roles.stranger).ownerForward(mock.address, payload), ) }) }) @@ -3735,10 +3735,10 @@ describe('Operator', () => { it('reverts', async () => { const sighash = linkTokenFactory.interface.getSighash('name') await evmRevert( - operator - .connect(roles.defaultAccount) - .ownerForward(link.address, sighash), - 'Cannot call to LINK', + operator + .connect(roles.defaultAccount) + .ownerForward(link.address, sighash), + 'Cannot call to LINK', ) }) }) @@ -3746,31 +3746,31 @@ describe('Operator', () => { describe('when forwarding to any other address', () => { it('forwards the data', async () => { const tx = await operator - .connect(roles.defaultAccount) - .ownerForward(mock.address, payload) + .connect(roles.defaultAccount) + .ownerForward(mock.address, payload) await tx.wait() assert.equal(await mock.getBytes(), bytes) }) it('reverts when sending to a non-contract address', async () => { await evmRevert( - operator - .connect(roles.defaultAccount) - .ownerForward(zeroAddress, payload), - 'Must forward to a contract', + operator + .connect(roles.defaultAccount) + .ownerForward(zeroAddress, payload), + 'Must forward to a contract', ) }) it('perceives the message is sent by the Operator', async () => { const tx = await operator - .connect(roles.defaultAccount) - .ownerForward(mock.address, payload) + .connect(roles.defaultAccount) + .ownerForward(mock.address, payload) const receipt = await tx.wait() const log: any = receipt.logs?.[0] const logData = mock.interface.decodeEventLog( - mock.interface.getEvent('SetBytes'), - log.data, - log.topics, + mock.interface.getEvent('SetBytes'), + log.data, + log.topics, ) assert.equal(ethers.utils.getAddress(logData.from), operator.address) }) diff --git a/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go b/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go index 9d2edad28c..40323574b1 100644 --- a/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go @@ -41,6 +41,8 @@ import ( const chainID = 1337 +var CapabilityID = fmt.Sprintf("%s@%s", CcipCapabilityLabelledName, CcipCapabilityVersion) + func NewReader( t *testing.T, logPoller logpoller.LogPoller, @@ -82,8 +84,6 @@ const ( CcipCapabilityVersion = "v1.0" ) -var CapabilityID = fmt.Sprintf("%s@%s", CcipCapabilityLabelledName, CcipCapabilityVersion) - type TestUniverse struct { Transactor *bind.TransactOpts Backend *backends.SimulatedBackend diff --git a/core/capabilities/remote/trigger_publisher.go b/core/capabilities/remote/trigger_publisher.go index b46d8bcb72..c5b4e84185 100644 --- a/core/capabilities/remote/trigger_publisher.go +++ b/core/capabilities/remote/trigger_publisher.go @@ -2,7 +2,7 @@ package remote import ( "context" - sync "sync" + "sync" "time" "github.com/smartcontractkit/chainlink-common/pkg/capabilities" diff --git a/core/gethwrappers/ccip/generated/price_registry_1_2_0/price_registry.go b/core/gethwrappers/ccip/generated/price_registry_1_2_0/price_registry.go index 30b1b26da9..64e16bd1dc 100644 --- a/core/gethwrappers/ccip/generated/price_registry_1_2_0/price_registry.go +++ b/core/gethwrappers/ccip/generated/price_registry_1_2_0/price_registry.go @@ -1690,4 +1690,4 @@ type PriceRegistryInterface interface { ParseLog(log types.Log) (generated.AbigenLog, error) Address() common.Address -} +} \ No newline at end of file diff --git a/core/gethwrappers/ccip/go_generate.go b/core/gethwrappers/ccip/go_generate.go index e61bcb0ba1..5c316af1ac 100644 --- a/core/gethwrappers/ccip/go_generate.go +++ b/core/gethwrappers/ccip/go_generate.go @@ -36,6 +36,7 @@ package ccip //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin SelfFundedPingPong self_funded_ping_pong //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin MessageHasher message_hasher //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin MultiOCR3Helper multi_ocr3_helper +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin CCIPReaderTester ccip_reader_tester //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin ReportCodec report_codec //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin EtherSenderReceiver ether_sender_receiver //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin WETH9 weth9 diff --git a/core/scripts/ccip/liquiditymanager/util.go b/core/scripts/ccip/liquiditymanager/util.go deleted file mode 100644 index 45aa69ddb8..0000000000 --- a/core/scripts/ccip/liquiditymanager/util.go +++ /dev/null @@ -1,433 +0,0 @@ -package main - -import ( - "context" - "fmt" - "math/big" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethclient" - chainsel "github.com/smartcontractkit/chain-selectors" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - - "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - - "github.com/smartcontractkit/chainlink/core/scripts/ccip/liquiditymanager/arb" - "github.com/smartcontractkit/chainlink/core/scripts/ccip/liquiditymanager/multienv" - "github.com/smartcontractkit/chainlink/core/scripts/ccip/liquiditymanager/opstack" - helpers "github.com/smartcontractkit/chainlink/core/scripts/common" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" - cciprouter "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_l1_bridge_adapter" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_l2_bridge_adapter" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/liquiditymanager" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_l1_bridge_adapter" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/optimism_l2_bridge_adapter" -) - -type universe struct { - L1 struct { - Arm common.Address - ArmProxy common.Address - TokenPool common.Address - LiquidityManager common.Address - BridgeAdapterAddress common.Address - } - L2 struct { - Arm common.Address - ArmProxy common.Address - TokenPool common.Address - LiquidityManager common.Address - BridgeAdapterAddress common.Address - } -} - -func deployUniverse( - env multienv.Env, - l1ChainID, l2ChainID uint64, - l1TokenAddress, l2TokenAddress common.Address, -) universe { - validateEnv(env, l1ChainID, l2ChainID, false) - - l1Client, l2Client := env.Clients[l1ChainID], env.Clients[l2ChainID] - l1Transactor, l2Transactor := env.Transactors[l1ChainID], env.Transactors[l2ChainID] - l1ChainSelector, l2ChainSelector := mustGetChainByEvmID(l1ChainID).Selector, mustGetChainByEvmID(l2ChainID).Selector - - // L1 deploys - // deploy arm and arm proxy. - // required by the token pool. - l1Arm, l1ArmProxy := deployArm(l1Transactor, l1Client, l1ChainID) - - _, tx, _, err := cciprouter.DeployRouter(l1Transactor, l1Client, common.Address{}, l1ArmProxy.Address()) - helpers.PanicErr(err) - l1RouterAddress := helpers.ConfirmContractDeployed(context.Background(), l1Client, tx, int64(l1ChainID)) - - // deploy token pool targeting l1TokenAddress. - l1TokenPool, l1Rebalancer := deployTokenPoolAndRebalancer(l1Transactor, l1Client, l1TokenAddress, l1ArmProxy.Address(), l1ChainSelector, l1RouterAddress) - - // deploy the appropriate L1 bridge adapter depending on the chain. - l1BridgeAdapterAddress := deployL1BridgeAdapter(l1Transactor, l1Client, l1ChainID, l2ChainID) - - // L2 deploys - // deploy arm and arm proxy. - // required by the token pool. - l2Arm, l2ArmProxy := deployArm(l2Transactor, l2Client, l2ChainID) - - _, tx, _, err = cciprouter.DeployRouter(l2Transactor, l2Client, common.Address{}, l2ArmProxy.Address()) - helpers.PanicErr(err) - l2RouterAddress := helpers.ConfirmContractDeployed(context.Background(), l2Client, tx, int64(l2ChainID)) - - // deploy token pool targeting l2TokenAddress - l2TokenPool, l2Rebalancer := deployTokenPoolAndRebalancer(l2Transactor, l2Client, l2TokenAddress, l2ArmProxy.Address(), l2ChainSelector, l2RouterAddress) - - // deploy the L2 bridge adapter to point to the token address - l2BridgeAdapterAddress := deployL2BridgeAdapter(l2Transactor, l2Client, l2ChainID) - - // link the l1 and l2 rebalancers together via the SetCrossChainRebalancer function - tx, err = l1Rebalancer.SetCrossChainRebalancer(l1Transactor, liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs{ - RemoteRebalancer: l2Rebalancer.Address(), - LocalBridge: l1BridgeAdapterAddress, - RemoteToken: l2TokenAddress, - RemoteChainSelector: l2ChainSelector, - Enabled: true, - }) - helpers.PanicErr(err) - helpers.ConfirmTXMined(context.Background(), l1Client, tx, int64(l1ChainID), "setting cross chain liquidityManager on L1 liquidityManager") - // assertion - onchainRebalancer, err := l1Rebalancer.GetCrossChainRebalancer(nil, l2ChainSelector) - helpers.PanicErr(err) - if onchainRebalancer.RemoteRebalancer != l2Rebalancer.Address() || - onchainRebalancer.LocalBridge != l1BridgeAdapterAddress { - panic(fmt.Sprintf("onchain liquidityManager address does not match, expected %s got %s, or local bridge does not match, expected %s got %s", - l2Rebalancer.Address().Hex(), - onchainRebalancer.RemoteRebalancer.Hex(), - l1BridgeAdapterAddress.Hex(), - onchainRebalancer.LocalBridge.Hex())) - } - - tx, err = l2Rebalancer.SetCrossChainRebalancer(l2Transactor, liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs{ - RemoteRebalancer: l1Rebalancer.Address(), - LocalBridge: l2BridgeAdapterAddress, - RemoteToken: l1TokenAddress, - RemoteChainSelector: l1ChainSelector, - Enabled: true, - }) - helpers.PanicErr(err) - helpers.ConfirmTXMined(context.Background(), l2Client, tx, int64(l2ChainID), "setting cross chain liquidityManager on L2 liquidityManager") - // assertion - onchainRebalancer, err = l2Rebalancer.GetCrossChainRebalancer(nil, l1ChainSelector) - helpers.PanicErr(err) - if onchainRebalancer.RemoteRebalancer != l1Rebalancer.Address() || - onchainRebalancer.LocalBridge != l2BridgeAdapterAddress { - panic(fmt.Sprintf("onchain liquidityManager address does not match, expected %s got %s, or local bridge does not match, expected %s got %s", - l1Rebalancer.Address().Hex(), - onchainRebalancer.RemoteRebalancer.Hex(), - l2BridgeAdapterAddress.Hex(), - onchainRebalancer.LocalBridge.Hex())) - } - - fmt.Println("Deployments complete\n", - "L1 Chain ID:", l1ChainID, "\n", - "L1 Chain Selector:", l1ChainSelector, "\n", - "L1 Arm:", helpers.ContractExplorerLink(int64(l1ChainID), l1Arm.Address()), "(", l1Arm.Address().Hex(), ")\n", - "L1 Arm Proxy:", helpers.ContractExplorerLink(int64(l1ChainID), l1ArmProxy.Address()), "(", l1ArmProxy.Address().Hex(), ")\n", - "L1 Token Pool:", helpers.ContractExplorerLink(int64(l1ChainID), l1TokenPool.Address()), "(", l1TokenPool.Address().Hex(), ")\n", - "L1 LiquidityManager:", helpers.ContractExplorerLink(int64(l1ChainID), l1Rebalancer.Address()), "(", l1Rebalancer.Address().Hex(), ")\n", - "L1 Bridge Adapter:", helpers.ContractExplorerLink(int64(l1ChainID), l1BridgeAdapterAddress), "(", l1BridgeAdapterAddress.Hex(), ")\n", - "L2 Chain ID:", l2ChainID, "\n", - "L2 Chain Selector:", l2ChainSelector, "\n", - "L2 Arm:", helpers.ContractExplorerLink(int64(l2ChainID), l2Arm.Address()), "(", l2Arm.Address().Hex(), ")\n", - "L2 Arm Proxy:", helpers.ContractExplorerLink(int64(l2ChainID), l2ArmProxy.Address()), "(", l2ArmProxy.Address().Hex(), ")\n", - "L2 Token Pool:", helpers.ContractExplorerLink(int64(l2ChainID), l2TokenPool.Address()), "(", l2TokenPool.Address().Hex(), ")\n", - "L2 LiquidityManager:", helpers.ContractExplorerLink(int64(l2ChainID), l2Rebalancer.Address()), "(", l2Rebalancer.Address().Hex(), ")\n", - "L2 Bridge Adapter:", helpers.ContractExplorerLink(int64(l2ChainID), l2BridgeAdapterAddress), "(", l2BridgeAdapterAddress.Hex(), ")", - ) - - return universe{ - L1: struct { - Arm common.Address - ArmProxy common.Address - TokenPool common.Address - LiquidityManager common.Address - BridgeAdapterAddress common.Address - }{ - Arm: l1Arm.Address(), - ArmProxy: l1ArmProxy.Address(), - TokenPool: l1TokenPool.Address(), - LiquidityManager: l1Rebalancer.Address(), - BridgeAdapterAddress: l1BridgeAdapterAddress, - }, - L2: struct { - Arm common.Address - ArmProxy common.Address - TokenPool common.Address - LiquidityManager common.Address - BridgeAdapterAddress common.Address - }{ - Arm: l2Arm.Address(), - ArmProxy: l2ArmProxy.Address(), - TokenPool: l2TokenPool.Address(), - LiquidityManager: l2Rebalancer.Address(), - BridgeAdapterAddress: l2BridgeAdapterAddress, - }, - } -} - -func deployL1BridgeAdapter( - l1Transactor *bind.TransactOpts, - l1Client *ethclient.Client, - l1ChainID, l2ChainID uint64, -) common.Address { - if l2ChainID == chainsel.ETHEREUM_MAINNET_ARBITRUM_1.EvmChainID || l2ChainID == chainsel.ETHEREUM_TESTNET_SEPOLIA_ARBITRUM_1.EvmChainID { - _, tx, _, err := arbitrum_l1_bridge_adapter.DeployArbitrumL1BridgeAdapter( - l1Transactor, - l1Client, - arb.ArbitrumContracts[l1ChainID]["L1GatewayRouter"], - arb.ArbitrumContracts[l1ChainID]["L1Outbox"], - ) - helpers.PanicErr(err) - return helpers.ConfirmContractDeployed(context.Background(), l1Client, tx, int64(l1ChainID)) - } else if l2ChainID == chainsel.ETHEREUM_MAINNET_OPTIMISM_1.EvmChainID || l2ChainID == chainsel.ETHEREUM_TESTNET_SEPOLIA_OPTIMISM_1.EvmChainID { - _, tx, _, err := optimism_l1_bridge_adapter.DeployOptimismL1BridgeAdapter( - l1Transactor, - l1Client, - opstack.OptimismContractsByChainID[l1ChainID]["L1StandardBridge"], - opstack.OptimismContractsByChainID[l1ChainID]["WETH"], - opstack.OptimismContractsByChainID[l1ChainID]["OptimismPortalProxy"], - ) - helpers.PanicErr(err) - return helpers.ConfirmContractDeployed(context.Background(), l1Client, tx, int64(l1ChainID)) - } - panic(fmt.Sprintf("unsupported chain id %d", l1ChainID)) -} - -func deployL2BridgeAdapter( - l2Transactor *bind.TransactOpts, - l2Client *ethclient.Client, - l2ChainID uint64, -) common.Address { - if l2ChainID == chainsel.ETHEREUM_MAINNET_ARBITRUM_1.EvmChainID || l2ChainID == chainsel.ETHEREUM_TESTNET_SEPOLIA_ARBITRUM_1.EvmChainID { - _, tx, _, err := arbitrum_l2_bridge_adapter.DeployArbitrumL2BridgeAdapter( - l2Transactor, - l2Client, - arb.ArbitrumContracts[l2ChainID]["L2GatewayRouter"], - ) - helpers.PanicErr(err) - return helpers.ConfirmContractDeployed(context.Background(), l2Client, tx, int64(l2ChainID)) - } else if l2ChainID == chainsel.ETHEREUM_MAINNET_OPTIMISM_1.EvmChainID || l2ChainID == chainsel.ETHEREUM_TESTNET_SEPOLIA_OPTIMISM_1.EvmChainID { - _, tx, _, err := optimism_l2_bridge_adapter.DeployOptimismL2BridgeAdapter( - l2Transactor, - l2Client, - opstack.OptimismContractsByChainID[l2ChainID]["WETH"], - ) - helpers.PanicErr(err) - return helpers.ConfirmContractDeployed(context.Background(), l2Client, tx, int64(l2ChainID)) - } - panic(fmt.Sprintf("unsupported l2 chain id %d", l2ChainID)) -} - -func deployTokenPoolAndRebalancer( - transactor *bind.TransactOpts, - client *ethclient.Client, - tokenAddress, - armProxyAddress common.Address, - chainID uint64, - router common.Address, -) (*lock_release_token_pool.LockReleaseTokenPool, *liquiditymanager.LiquidityManager) { - _, tx, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( - transactor, - client, - tokenAddress, - []common.Address{}, - armProxyAddress, - true, - router, - ) - helpers.PanicErr(err) - tokenPoolAddress := helpers.ConfirmContractDeployed(context.Background(), client, tx, int64(chainID)) - tokenPool, err := lock_release_token_pool.NewLockReleaseTokenPool(tokenPoolAddress, client) - helpers.PanicErr(err) - - _, tx, _, err = liquiditymanager.DeployLiquidityManager( - transactor, - client, - tokenAddress, - chainID, - tokenPoolAddress, - big.NewInt(0), - common.Address{}, - ) - helpers.PanicErr(err) - rebalancerAddress := helpers.ConfirmContractDeployed(context.Background(), client, tx, int64(chainID)) - liquidityManager, err := liquiditymanager.NewLiquidityManager(rebalancerAddress, client) - helpers.PanicErr(err) - tx, err = tokenPool.SetRebalancer(transactor, rebalancerAddress) - helpers.PanicErr(err) - helpers.ConfirmTXMined(context.Background(), client, tx, int64(chainID), - "setting liquidityManager on token pool") - onchainRebalancer, err := tokenPool.GetRebalancer(nil) - helpers.PanicErr(err) - if onchainRebalancer != rebalancerAddress { - panic(fmt.Sprintf("onchain liquidityManager address does not match, expected %s got %s", - rebalancerAddress.Hex(), onchainRebalancer.Hex())) - } - return tokenPool, liquidityManager -} - -func deployArm( - transactor *bind.TransactOpts, - client *ethclient.Client, - chainID uint64) (*mock_rmn_contract.MockRMNContract, *rmn_proxy_contract.RMNProxyContract) { - _, tx, _, err := mock_rmn_contract.DeployMockRMNContract(transactor, client) - helpers.PanicErr(err) - armAddress := helpers.ConfirmContractDeployed(context.Background(), client, tx, int64(chainID)) - arm, err := mock_rmn_contract.NewMockRMNContract(armAddress, client) - helpers.PanicErr(err) - - _, tx, _, err = rmn_proxy_contract.DeployRMNProxyContract(transactor, client, arm.Address()) - helpers.PanicErr(err) - armProxyAddress := helpers.ConfirmContractDeployed(context.Background(), client, tx, int64(chainID)) - armProxy, err := rmn_proxy_contract.NewRMNProxyContract(armProxyAddress, client) - helpers.PanicErr(err) - - return arm, armProxy -} - -// sum of MaxDurationQuery/MaxDurationObservation/DeltaGrace must be less than DeltaProgress -func setConfig( - e multienv.Env, - args setConfigArgs, -) { - validateEnv(e, args.l1ChainID, args.l2ChainID, false) - - l1Transactor, l2Transactor := e.Transactors[args.l1ChainID], e.Transactors[args.l2ChainID] - - // lengths of all the arrays must be equal - if len(args.signers) != len(args.offchainPubKeys) || - len(args.signers) != len(args.configPubKeys) || - len(args.signers) != len(args.l1Transmitters) || - len(args.signers) != len(args.l2Transmitters) { - panic("lengths of all the arrays must be equal") - } - - l1Rebalancer, err := liquiditymanager.NewLiquidityManager(args.l1LiquidityManagerAddress, e.Clients[args.l1ChainID]) - helpers.PanicErr(err) - l2Rebalancer, err := liquiditymanager.NewLiquidityManager(args.l2LiquidityManagerAddress, e.Clients[args.l2ChainID]) - helpers.PanicErr(err) - - // set config on L2 first then L1 - var ( - l1Oracles []confighelper2.OracleIdentityExtra - l2Oracles []confighelper2.OracleIdentityExtra - ) - for i := 0; i < len(args.signers); i++ { - l1Oracles = append(l1Oracles, confighelper2.OracleIdentityExtra{ - OracleIdentity: confighelper2.OracleIdentity{ - OffchainPublicKey: args.offchainPubKeys[i], - OnchainPublicKey: args.signers[i].Bytes(), - PeerID: args.peerIDs[i], - TransmitAccount: types.Account(args.l1Transmitters[i].Hex()), - }, - ConfigEncryptionPublicKey: args.configPubKeys[i], - }) - l2Oracles = append(l2Oracles, confighelper2.OracleIdentityExtra{ - OracleIdentity: confighelper2.OracleIdentity{ - OffchainPublicKey: args.offchainPubKeys[i], - OnchainPublicKey: args.signers[i].Bytes(), - PeerID: args.peerIDs[i], - TransmitAccount: types.Account(args.l2Transmitters[i].Hex()), - }, - ConfigEncryptionPublicKey: args.configPubKeys[i], - }) - } - var schedule []int - for range l1Oracles { - schedule = append(schedule, 1) - } - offchainConfig, onchainConfig := []byte{}, []byte{} - f := uint8(1) - _, _, f, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( - args.deltaProgress, - args.deltaResend, - args.deltaInitial, - args.deltaRound, - args.deltaGrace, - args.deltaCertifiedCommitRequest, - args.deltaStage, - args.rMax, - schedule, - l2Oracles, - offchainConfig, - args.maxDurationQuery, - args.maxDurationObservation, - args.maxDurationShouldAcceptAttestedReport, - args.maxDurationShouldTransmitAcceptedReport, - int(f), - onchainConfig) - helpers.PanicErr(err) - tx, err := l2Rebalancer.SetOCR3Config(l2Transactor, args.signers, args.l2Transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) - helpers.PanicErr(err) - helpers.ConfirmTXMined(context.Background(), e.Clients[args.l2ChainID], tx, int64(args.l2ChainID), "setting OCR3 config on L2 liquidityManager") - - fmt.Println("sleeping a bit before setting config on L1") - time.Sleep(1 * time.Minute) - - // set config on L1 - offchainConfig, onchainConfig = []byte{}, []byte{} - _, _, f, onchainConfig, offchainConfigVersion, offchainConfig, err = ocr3confighelper.ContractSetConfigArgsForTests( - args.deltaProgress, - args.deltaResend, - args.deltaInitial, - args.deltaRound, - args.deltaGrace, - args.deltaCertifiedCommitRequest, - args.deltaStage, - args.rMax, - schedule, - l1Oracles, - offchainConfig, - args.maxDurationQuery, - args.maxDurationObservation, - args.maxDurationShouldAcceptAttestedReport, - args.maxDurationShouldTransmitAcceptedReport, - int(f), - onchainConfig) - helpers.PanicErr(err) - tx, err = l1Rebalancer.SetOCR3Config(l1Transactor, args.signers, args.l1Transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) - helpers.PanicErr(err) - helpers.ConfirmTXMined(context.Background(), e.Clients[args.l1ChainID], tx, int64(args.l1ChainID), "setting OCR3 config on L1 liquidityManager") -} - -func validateEnv(env multienv.Env, l1ChainID, l2ChainID uint64, websocket bool) { - _, ok := env.Clients[l1ChainID] - if !ok { - panic("L1 client not found") - } - _, ok = env.Clients[l2ChainID] - if !ok { - panic("L2 client not found") - } - _, ok = env.Transactors[l1ChainID] - if !ok { - panic("L1 transactor not found") - } - _, ok = env.Transactors[l2ChainID] - if !ok { - panic("L2 transactor not found") - } - if websocket { - _, ok = env.WSURLs[l1ChainID] - if !ok { - panic("L1 websocket URL not found") - } - _, ok = env.WSURLs[l2ChainID] - if !ok { - panic("L2 websocket URL not found") - } - } -} diff --git a/core/scripts/ccip/manual-execution/helpers/contractmodels.go b/core/scripts/ccip/manual-execution/helpers/contractmodels.go deleted file mode 100644 index 000b32dd39..0000000000 --- a/core/scripts/ccip/manual-execution/helpers/contractmodels.go +++ /dev/null @@ -1,85 +0,0 @@ -package helpers - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -type CommitStoreReportAccepted struct { - Report ICommitStoreCommitReport - Raw types.Log -} - -type ICommitStoreCommitReport struct { - PriceUpdates InternalPriceUpdates - Interval ICommitStoreInterval - MerkleRoot [32]byte -} - -type InternalGasPriceUpdate struct { - DestChainSelector uint64 - UsdPerUnitGas *big.Int -} - -type InternalPriceUpdates struct { - TokenPriceUpdates []InternalTokenPriceUpdate - GasPriceUpdates []InternalGasPriceUpdate -} - -type InternalTokenPriceUpdate struct { - SourceToken common.Address - UsdPerToken *big.Int -} - -type ICommitStoreInterval struct { - Min uint64 - Max uint64 -} - -type InternalEVM2EVMMessage struct { - SourceChainSelector uint64 - Sender common.Address - Receiver common.Address - SequenceNumber uint64 - GasLimit *big.Int - Strict bool - Nonce uint64 - FeeToken common.Address - FeeTokenAmount *big.Int - Data []byte - TokenAmounts []ClientEVMTokenAmount - SourceTokenData [][]byte - MessageId [32]byte -} - -type ClientEVMTokenAmount struct { - Token common.Address - Amount *big.Int -} - -type SendRequestedEvent struct { - Message InternalEVM2EVMMessage - Raw types.Log -} - -type InternalExecutionReport struct { - Messages []InternalEVM2EVMMessage - OffchainTokenData [][][]byte - Proofs [][32]byte - ProofFlagBits *big.Int -} - -type EVM2EVMOffRampExecutionStateChanged struct { - SequenceNumber uint64 - MessageId [32]byte - State uint8 - ReturnData []byte - Raw types.Log -} - -type EVM2EVMOffRampGasLimitOverride struct { - ReceiverExecutionGasLimit *big.Int - TokenGasOverrides []*big.Int -} diff --git a/core/scripts/ccip/manual-execution/helpers/contractwrappers.go b/core/scripts/ccip/manual-execution/helpers/contractwrappers.go deleted file mode 100644 index 027577b912..0000000000 --- a/core/scripts/ccip/manual-execution/helpers/contractwrappers.go +++ /dev/null @@ -1,189 +0,0 @@ -package helpers - -import ( - "fmt" - "strings" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/event" -) - -const ( - OffRampABI = "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"contractIERC20[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"contractIPool[]\",\"name\":\"pools\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getDestinationToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDestinationTokens\",\"outputs\":[{\"internalType\":\"contractIERC20[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"getPoolByDestToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"contractIERC20[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]" - CommitStoreABI = "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]" - OnRampABI = "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"tokensAndPools\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"}],\"name\":\"InvalidNopAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWithdrawParams\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkBalanceNotSettled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeeBalanceReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoFeesToPay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoNopsToPay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdminOrNop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyNops\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeConfig\",\"type\":\"tuple[]\"}],\"name\":\"FeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NopPaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nopWeightsTotal\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"NopsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"transferFeeConfig\",\"type\":\"tuple[]\"}],\"name\":\"TokenTransferFeeConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getFeeTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfig\",\"name\":\"feeTokenConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNopFeesJuels\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNops\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"weightsTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setFeeTokenConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setTokenTransferFeeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawNonLinkFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" -) - -func DecodeEvents( - ethC *ethclient.Client, - opts *bind.FilterOpts, - address, contractABI, eventName string, - query ...[]interface{}, -) (*bind.BoundContract, chan types.Log, event.Subscription, error) { - contractAddress := common.HexToAddress(address) - abi, err := abi.JSON(strings.NewReader(contractABI)) - if err != nil { - return nil, nil, nil, err - } - boundContract := bind.NewBoundContract(contractAddress, abi, ethC, ethC, ethC) - logs, subs, err := boundContract.FilterLogs(opts, eventName, query...) - if err != nil { - return nil, nil, nil, err - } - return boundContract, logs, subs, err -} - -type logIterator struct { - Raw types.Log - Contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *logIterator) Next() bool { - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *logIterator) Error() error { - return it.fail -} - -func (it *logIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -func FilterCCIPSendRequested(chain *ethclient.Client, opts *bind.FilterOpts, onRampAddr string) (*logIterator, error) { - onRampContract, logs, sub, err := DecodeEvents(chain, opts, onRampAddr, OnRampABI, "CCIPSendRequested") - if err != nil { - return nil, err - } - return &logIterator{ - Contract: onRampContract, - event: "CCIPSendRequested", - logs: logs, - sub: sub, - }, nil -} - -func (it *logIterator) SendRequestedEventFromLog() (*SendRequestedEvent, error) { - event := new(SendRequestedEvent) - err := it.Contract.UnpackLog(event, "CCIPSendRequested", it.Raw) - if err != nil { - return nil, err - } - return event, nil -} - -func (it *logIterator) CommitStoreReportAcceptedFromLog() (*CommitStoreReportAccepted, error) { - event := new(CommitStoreReportAccepted) - err := it.Contract.UnpackLog(event, "ReportAccepted", it.Raw) - if err != nil { - return nil, err - } - return event, nil -} - -func FilterReportAccepted(chain *ethclient.Client, opts *bind.FilterOpts, commitStoreAddr string) (*logIterator, error) { - commitStoreContract, logs, sub, err := DecodeEvents(chain, opts, commitStoreAddr, CommitStoreABI, "ReportAccepted") - if err != nil { - return nil, err - } - return &logIterator{ - Contract: commitStoreContract, - event: "ReportAccepted", - logs: logs, - sub: sub, - }, nil -} - -func FilterExecutionStateChanged( - chain *ethclient.Client, - opts *bind.FilterOpts, - offRampAddr string, - sequenceNumber []uint64, - messageId [][32]byte, -) (int, error) { - var sequenceNumberRule []interface{} - for _, sequenceNumberItem := range sequenceNumber { - sequenceNumberRule = append(sequenceNumberRule, sequenceNumberItem) - } - var messageIdRule []interface{} - for _, messageIdItem := range messageId { - messageIdRule = append(messageIdRule, messageIdItem) - } - offRamp, logs, sub, err := DecodeEvents(chain, opts, offRampAddr, OffRampABI, "ExecutionStateChanged", sequenceNumberRule, messageIdRule) - if err != nil { - return 0, err - } - it := &logIterator{ - Contract: offRamp, - event: "ExecutionStateChanged", - logs: logs, - sub: sub, - } - - executionState := -1 - for it.Next() && executionState != 2 { - execStateEvent := new(EVM2EVMOffRampExecutionStateChanged) - err = it.Contract.UnpackLog(execStateEvent, "ExecutionStateChanged", it.Raw) - if err != nil { - return 0, err - } - executionState = int(execStateEvent.State) - } - - if executionState == -1 { - return 0, fmt.Errorf("no ExecutionStateChanged found for seq num %v and msg id %v", sequenceNumber, messageId) - } - return executionState, nil -} - -func ManuallyExecute( - ethC *ethclient.Client, - opts *bind.TransactOpts, - address string, - report InternalExecutionReport, - gasLimitOverrides []*EVM2EVMOffRampGasLimitOverride, -) (*types.Transaction, error) { - offRampContract := common.HexToAddress(address) - abi, err := abi.JSON(strings.NewReader(OffRampABI)) - if err != nil { - return nil, err - } - boundContract := bind.NewBoundContract(offRampContract, abi, ethC, ethC, ethC) - return boundContract.Transact(opts, "manuallyExecute", report, gasLimitOverrides) -} diff --git a/core/scripts/ccip/manual-execution/main.go b/core/scripts/ccip/manual-execution/main.go deleted file mode 100644 index ad86457e6b..0000000000 --- a/core/scripts/ccip/manual-execution/main.go +++ /dev/null @@ -1,447 +0,0 @@ -package main - -import ( - "context" - "encoding/hex" - "encoding/json" - "flag" - "fmt" - "log" - "math" - "math/big" - "os" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethclient" - chainselectors "github.com/smartcontractkit/chain-selectors" - "go.uber.org/multierr" - - "manual-execution/helpers" -) - -const NumberOfBlocks = 5000 - -// Config represents configuration fields -type Config struct { - SrcNodeURL string `json:"src_rpc"` - DestNodeURL string `json:"dest_rpc"` - DestOwner string `json:"dest_owner_key"` - CommitStore string `json:"commit_store"` - OffRamp string `json:"off_ramp"` - DestStartBlock uint64 `json:"dest_start_block"` - SourceChainTx string `json:"source_chain_tx"` - CCIPMsgID string `json:"ccip_msg_id"` - DestDeployedAt uint64 `json:"dest_deployed_at"` - GasLimitOverride uint64 `json:"gas_limit_override"` -} - -type execArgs struct { - cfg Config - seqNum uint64 - msgID [32]byte - sourceChain *ethclient.Client - sourceChainId *big.Int - destChain *ethclient.Client - destUser *bind.TransactOpts - destChainId *big.Int - srcStartBlock *big.Int - destStartBlock uint64 - destLatestBlock uint64 - OnRamp common.Address - tokenGasOverrides []*big.Int -} - -func main() { - configPath := flag.String("configFile", "./config.json", "config for manually executing a failed ccip message "+ - "which has been successfully committed but failed to get executed") - flag.Parse() - - if *configPath == "" { - log.Println("config json is required") - os.Exit(1) - } - cData, err := os.ReadFile(*configPath) - if err != nil { - log.Println("unable to read the json at ", *configPath, "error - ", err) - os.Exit(1) - } - var cfg Config - err = json.Unmarshal(cData, &cfg) - if err != nil { - log.Println("unable to marshal the json at ", *configPath, "error - ", err, `sample json -{ - "src_rpc": "", - "dest_rpc": "", - "dest_owner_key": "", - "commit_store": "", - "off_ramp": "", - "dest_start_block": "", - "ccip_send_tx": "", - "source_start_block": "", - "dest_deployed_at": 0, - "gas_limit_override": 0, -}`) - os.Exit(1) - } - // mandatory fields check - err = cfg.verifyConfig() - if err != nil { - log.Println("config validation failed: \n", err) - os.Exit(1) - } - args := &execArgs{cfg: cfg} - err = args.populateValues() - if err != nil { - log.Println("error instantiating manual execution args ", err) - os.Exit(1) - } - err = args.execute() - if err != nil { - log.Println("manual execution was not successful - ", err) - os.Exit(1) - } -} - -func (cfg Config) verifyConfig() error { - var allErr error - if cfg.SrcNodeURL == "" { - allErr = multierr.Append(allErr, fmt.Errorf("must set src_rpc - source chain rpc\n")) - } - if cfg.DestNodeURL == "" { - allErr = multierr.Append(allErr, fmt.Errorf("must set dest_rpc - destination chain rpc\n")) - } - if cfg.DestOwner == "" { - allErr = multierr.Append(allErr, fmt.Errorf("must set dest_owner_key - destination user private key\n")) - } - if cfg.SourceChainTx == "" { - allErr = multierr.Append(allErr, fmt.Errorf("must set source_chain_tx - txHash of ccip-send request\n")) - } - - if cfg.DestStartBlock == 0 && cfg.DestDeployedAt == 0 { - allErr = multierr.Append(allErr, fmt.Errorf(`must set either of - -dest_deployed_at - the block number before destination contracts were deployed; -dest_start_block - the block number from which events will be filtered at destination chain. -`)) - } - if cfg.GasLimitOverride == 0 { - allErr = multierr.Append(allErr, fmt.Errorf("must set gas_limit_override - new value of gas limit for ccip-send request\n")) - } - err := helpers.VerifyAddress(cfg.CommitStore) - if err != nil { - allErr = multierr.Append(allErr, fmt.Errorf("check the commit_store address - %v\n", err)) - } - err = helpers.VerifyAddress(cfg.OffRamp) - if err != nil { - allErr = multierr.Append(allErr, fmt.Errorf("check the off_ramp address - %v\n", err)) - } - - return allErr -} - -func (args *execArgs) populateValues() error { - var err error - cfg := args.cfg - args.sourceChain, err = ethclient.Dial(cfg.SrcNodeURL) - if err != nil { - return err - } - args.sourceChainId, err = args.sourceChain.ChainID(context.Background()) - if err != nil { - return err - } - - args.destChain, err = ethclient.Dial(cfg.DestNodeURL) - if err != nil { - return err - } - args.destChainId, err = args.destChain.ChainID(context.Background()) - if err != nil { - return err - } - ownerKey, err := crypto.HexToECDSA(cfg.DestOwner) - if err != nil { - return err - } - - args.destUser, err = bind.NewKeyedTransactorWithChainID(ownerKey, args.destChainId) - if err != nil { - return err - } - log.Println("--- Owner address---/n", args.destUser.From.Hex()) - - var txReceipt *types.Receipt - txReceipt, err = args.sourceChain.TransactionReceipt(context.Background(), common.HexToHash(cfg.SourceChainTx)) - if err != nil { - return err - } - args.srcStartBlock = big.NewInt(0).Sub(txReceipt.BlockNumber, big.NewInt(NumberOfBlocks)) - args.destLatestBlock, err = args.destChain.BlockNumber(context.Background()) - if err != nil { - return err - } - - err = args.seqNumFromCCIPSendRequested(txReceipt.Logs) - if err != nil { - return err - } - if args.cfg.DestStartBlock < 1 { - err = args.approxDestStartBlock() - if err != nil { - return err - } - } else { - args.destStartBlock = args.cfg.DestStartBlock - } - return nil -} - -func (args *execArgs) execute() error { - iterator, err := helpers.FilterReportAccepted(args.destChain, &bind.FilterOpts{Start: args.destStartBlock}, args.cfg.CommitStore) - if err != nil { - return err - } - - var commitReport *helpers.ICommitStoreCommitReport - for iterator.Next() { - eventReport, err := iterator.CommitStoreReportAcceptedFromLog() - if err != nil { - return err - } - - if eventReport.Report.Interval.Min <= args.seqNum && eventReport.Report.Interval.Max >= args.seqNum { - commitReport = &eventReport.Report - log.Println("Found root") - break - } - } - if commitReport == nil { - return fmt.Errorf("unable to find seq num %d in commit report", args.seqNum) - } - log.Println("Executing request manually") - seqNr := args.seqNum - // Build a merkle tree for the report - mctx := helpers.NewKeccakCtx() - leafHasher := helpers.NewLeafHasher( - GetCCIPChainSelector(args.sourceChainId.Uint64()), - GetCCIPChainSelector(args.destChainId.Uint64()), - args.OnRamp, - mctx, - ) - - var leaves [][32]byte - var curr, prove int - var tokenData [][][]byte - var msgs []helpers.InternalEVM2EVMMessage - - sendRequestedIterator, err := helpers.FilterCCIPSendRequested(args.sourceChain, &bind.FilterOpts{ - Start: args.srcStartBlock.Uint64(), - }, args.OnRamp.Hex()) - if err != nil { - return err - } - - for sendRequestedIterator.Next() { - event, err := sendRequestedIterator.SendRequestedEventFromLog() - if err != nil { - return err - } - if event.Message.SequenceNumber <= commitReport.Interval.Max && - event.Message.SequenceNumber >= commitReport.Interval.Min { - log.Println("Found seq num in commit report", event.Message.SequenceNumber, commitReport.Interval) - hash, err := leafHasher.HashLeaf(sendRequestedIterator.Raw) - if err != nil { - return err - } - leaves = append(leaves, hash) - if event.Message.SequenceNumber == seqNr && event.Message.MessageId == args.msgID { - log.Printf("Found proving %d %+v\n\n", curr, event.Message) - msgs = append(msgs, event.Message) - - var msgTokenData [][]byte - for range event.Message.TokenAmounts { - msgTokenData = append(msgTokenData, []byte{}) - } - - tokenData = append(tokenData, msgTokenData) - prove = curr - } - curr++ - } - } - - sendRequestedIterator.Close() - if len(msgs) == 0 { - return fmt.Errorf("unable to find msg with seqNr %d", seqNr) - } - - expectedNumberOfLeaves := int(commitReport.Interval.Max) - int(commitReport.Interval.Min) + 1 - if len(leaves) != expectedNumberOfLeaves { - return fmt.Errorf("not enough leaves gather to build a commit root - want %d got %d. Please set NumberOfBlocks const to a higher value", expectedNumberOfLeaves, len(leaves)) - } - - tree, err := helpers.NewTree(mctx, leaves) - if err != nil { - return err - } - if tree.Root() != commitReport.MerkleRoot { - return fmt.Errorf("root doesn't match. cannot execute") - } - - proof := tree.Prove([]int{prove}) - offRampProof := helpers.InternalExecutionReport{ - Messages: msgs, - Proofs: proof.Hashes, - OffchainTokenData: tokenData, - ProofFlagBits: helpers.ProofFlagsToBits(proof.SourceFlags), - } - - gasLimitOverrides := make([]*helpers.EVM2EVMOffRampGasLimitOverride, len(offRampProof.Messages)) - - for range offRampProof.Messages { - evm2evmOffRampGasLimitOverride := &helpers.EVM2EVMOffRampGasLimitOverride{ - ReceiverExecutionGasLimit: big.NewInt(int64(args.cfg.GasLimitOverride)), - TokenGasOverrides: args.tokenGasOverrides, - } - gasLimitOverrides = append(gasLimitOverrides, evm2evmOffRampGasLimitOverride) - } - - tx, err := helpers.ManuallyExecute(args.destChain, args.destUser, args.cfg.OffRamp, offRampProof, gasLimitOverrides) - if err != nil { - return err - } - // wait for tx confirmation - err = helpers.WaitForSuccessfulTxReceipt(args.destChain, tx.Hash()) - if err != nil { - return err - } - - // check if the message got successfully delivered - changed, err := helpers.FilterExecutionStateChanged(args.destChain, &bind.FilterOpts{ - Start: args.destStartBlock, - }, args.cfg.OffRamp, []uint64{args.seqNum}, [][32]byte{args.msgID}) - if err != nil { - return err - } - if changed != 2 { - return fmt.Errorf("manual execution did not result in ExecutionStateChanged as success") - } - return nil -} - -func (args *execArgs) seqNumFromCCIPSendRequested(logs []*types.Log) error { - abi, err := abi.JSON(strings.NewReader(helpers.OnRampABI)) - if err != nil { - return err - } - var topic0 common.Hash - for name, abiEvent := range abi.Events { - if name == "CCIPSendRequested" { - topic0 = abiEvent.ID - break - } - } - if topic0 == (common.Hash{}) { - return fmt.Errorf("no CCIPSendRequested event found in ABI") - } - var sendRequestedLogs []types.Log - for _, sendReqLog := range logs { - if sendReqLog.Topics[0] == topic0 && sendReqLog.TxHash == common.HexToHash(args.cfg.SourceChainTx) { - args.OnRamp = sendReqLog.Address - sendRequestedLogs = append(sendRequestedLogs, *sendReqLog) - } - } - - if len(sendRequestedLogs) == 0 { - return fmt.Errorf("no CCIPSendRequested logs found for in txReceipt for txhash %s", args.cfg.SourceChainTx) - } - onRampContract := bind.NewBoundContract(args.OnRamp, abi, args.sourceChain, args.sourceChain, args.sourceChain) - - for _, sendReqLog := range sendRequestedLogs { - var event helpers.SendRequestedEvent - - err = onRampContract.UnpackLog(&event, "CCIPSendRequested", sendReqLog) - if err != nil { - return err - } - - if args.cfg.CCIPMsgID != "" && - "0x"+hex.EncodeToString(event.Message.MessageId[:]) != args.cfg.CCIPMsgID { - continue - } - - args.seqNum = event.Message.SequenceNumber - args.msgID = event.Message.MessageId - return nil - } - - return fmt.Errorf("send request not found in logs") -} - -func (args *execArgs) approxDestStartBlock() error { - sourceBlockHdr, err := args.sourceChain.HeaderByNumber(context.Background(), args.srcStartBlock) - if err != nil { - return err - } - sendTxTime := sourceBlockHdr.Time - maxBlockNum := args.destLatestBlock - // setting this to an approx value of 1000 considering destination chain would have at least 1000 blocks before the transaction started - minBlockNum := args.cfg.DestDeployedAt - closestBlockNum := uint64(math.Floor((float64(maxBlockNum) + float64(minBlockNum)) / 2)) - var closestBlockHdr *types.Header - closestBlockHdr, err = args.destChain.HeaderByNumber(context.Background(), big.NewInt(int64(closestBlockNum))) - if err != nil { - return err - } - // to reduce the number of RPC calls increase the value of blockOffset - blockOffset := uint64(10) - for { - blockNum := closestBlockHdr.Number.Uint64() - if minBlockNum > maxBlockNum { - break - } - timeDiff := math.Abs(float64(closestBlockHdr.Time - sendTxTime)) - // break if the difference in timestamp is lesser than 1 minute - if timeDiff < 60 { - break - } else if closestBlockHdr.Time > sendTxTime { - maxBlockNum = blockNum - 1 - } else { - minBlockNum = blockNum + 1 - } - closestBlockNum = uint64(math.Floor((float64(maxBlockNum) + float64(minBlockNum)) / 2)) - closestBlockHdr, err = args.destChain.HeaderByNumber(context.Background(), big.NewInt(int64(closestBlockNum))) - if err != nil { - return err - } - } - - for { - if closestBlockHdr.Time <= sendTxTime { - break - } - closestBlockNum = closestBlockNum - blockOffset - if closestBlockNum <= 0 { - return fmt.Errorf("approx destination blocknumber not found") - } - closestBlockHdr, err = args.destChain.HeaderByNumber(context.Background(), big.NewInt(int64(closestBlockNum))) - if err != nil { - return err - } - } - args.destStartBlock = closestBlockHdr.Number.Uint64() - log.Printf("using approx destination start block number %d for filtering event", args.destStartBlock) - return nil -} - -func GetCCIPChainSelector(chainId uint64) uint64 { - selector, err := chainselectors.SelectorFromChainId(chainId) - if err != nil { - panic(fmt.Sprintf("no chain selector for %d", chainId)) - } - return selector -} diff --git a/core/scripts/ccip/revert-reason/handler/reason.go b/core/scripts/ccip/revert-reason/handler/reason.go deleted file mode 100644 index 7256b85856..0000000000 --- a/core/scripts/ccip/revert-reason/handler/reason.go +++ /dev/null @@ -1,208 +0,0 @@ -package handler - -import ( - "bytes" - "context" - "encoding/hex" - "encoding/json" - "fmt" - "strings" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/pkg/errors" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/usdc_token_pool" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/usdc_token_pool_1_4_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/burn_mint_erc677" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/erc20" -) - -// RevertReasonFromErrorCodeString attempts to decode an error code string -func (h *BaseHandler) RevertReasonFromErrorCodeString(errorCodeString string) (string, error) { - errorCodeString = strings.TrimPrefix(errorCodeString, "0x") - return DecodeErrorStringFromABI(errorCodeString) -} - -// RevertReasonFromTx attempts to fetch more info on failed TX -func (h *BaseHandler) RevertReasonFromTx(txHash string) (string, error) { - // Need a node URL - // NOTE: this node needs to run in archive mode - ethUrl := h.cfg.NodeURL - if ethUrl == "" { - panicErr(errors.New("you must define ETH_NODE env variable")) - } - requester := h.cfg.FromAddress - - ec, err := ethclient.Dial(ethUrl) - panicErr(err) - errorString, _ := GetErrorForTx(ec, txHash, requester) - - return DecodeErrorStringFromABI(errorString) -} - -func DecodeErrorStringFromABI(errorString string) (string, error) { - contractABIs := getAllABIs() - - // Sanitize error string - errorString = strings.TrimPrefix(errorString, "Reverted ") - errorString = strings.TrimPrefix(errorString, "0x") - - data, err := hex.DecodeString(errorString) - if err != nil { - return "", errors.Wrap(err, "error decoding error string") - } - - for _, contractABI := range contractABIs { - parsedAbi, err2 := abi.JSON(strings.NewReader(contractABI)) - if err2 != nil { - return "", errors.Wrap(err2, "error loading ABI") - } - - for errorName, abiError := range parsedAbi.Errors { - if bytes.Equal(data[:4], abiError.ID.Bytes()[:4]) { - // Found a matching error - v, err3 := abiError.Unpack(data) - if err3 != nil { - return "", errors.Wrap(err3, "error unpacking data") - } - - // If exec error, the actual error is within the revert reason - if errorName == "ExecutionError" || errorName == "TokenRateLimitError" || errorName == "TokenHandlingError" || errorName == "ReceiverError" { - // Get the inner type, which is `bytes` - fmt.Printf("Error is \"%v\" \ninner error: ", errorName) - errorBytes := v.([]interface{})[0].([]byte) - if len(errorBytes) < 4 { - return "[reverted without error code]", nil - } - return DecodeErrorStringFromABI(hex.EncodeToString(errorBytes)) - } - return fmt.Sprintf("error is \"%v\" args %v\n", errorName, v), nil - } - } - } - - if len(errorString) > 8 && errorString[:8] == "4e487b71" { - fmt.Println("Assertion failure") - indicator := errorString[len(errorString)-2:] - switch indicator { - case "01": - return "If you call assert with an argument that evaluates to false.", nil - case "11": - return "If an arithmetic operation results in underflow or overflow outside of an unchecked { ... } block.", nil - case "12": - return "If you divide or modulo by zero (e.g. 5 / 0 or 23 modulo 0).", nil - case "21": - return "If you convert a value that is too big or negative into an enum type.", nil - case "31": - return "If you call .pop() on an empty array.", nil - case "32": - return "If you access an array, bytesN or an array slice at an out-of-bounds or negative index (i.e. x[i] where i >= x.length or i < 0).", nil - case "41": - return "If you allocate too much memory or create an array that is too large.", nil - case "51": - return "If you call a zero-initialized variable of internal function type.", nil - default: - return fmt.Sprintf("This is a revert produced by an assertion failure. Exact code not found \"%s\"", indicator), nil - } - } - - stringErr, err := abi.UnpackRevert(data) - if err == nil { - return fmt.Sprintf("string error: %s", stringErr), nil - } - - return "", errors.Errorf(`cannot match error with contract ABI. Error code "%s"`, errorString) -} - -func getAllABIs() []string { - return []string{ - rmn_contract.RMNContractABI, - lock_release_token_pool_1_4_0.LockReleaseTokenPoolABI, - burn_mint_token_pool_1_2_0.BurnMintTokenPoolABI, - usdc_token_pool_1_4_0.USDCTokenPoolABI, - burn_mint_erc677.BurnMintERC677ABI, - erc20.ERC20ABI, - lock_release_token_pool.LockReleaseTokenPoolABI, - burn_mint_token_pool.BurnMintTokenPoolABI, - usdc_token_pool.USDCTokenPoolABI, - commit_store.CommitStoreABI, - token_admin_registry.TokenAdminRegistryABI, - fee_quoter.FeeQuoterABI, - evm_2_evm_onramp.EVM2EVMOnRampABI, - evm_2_evm_offramp.EVM2EVMOffRampABI, - router.RouterABI, - onramp.OnRampABI, - offramp.OffRampABI, - maybe_revert_message_receiver.MaybeRevertMessageReceiverABI, - } -} - -func GetErrorForTx(client *ethclient.Client, txHash string, requester string) (string, error) { - tx, _, err := client.TransactionByHash(context.Background(), common.HexToHash(txHash)) - if err != nil { - return "", errors.Wrap(err, "error getting transaction from hash") - } - re, err := client.TransactionReceipt(context.Background(), common.HexToHash(txHash)) - if err != nil { - return "", errors.Wrap(err, "error getting transaction receipt") - } - - call := ethereum.CallMsg{ - From: common.HexToAddress(requester), - To: tx.To(), - Data: tx.Data(), - Value: tx.Value(), - Gas: tx.Gas(), - GasPrice: tx.GasPrice(), - } - _, err = client.CallContract(context.Background(), call, re.BlockNumber) - if err == nil { - panic("no error calling contract") - } - - return parseError(err) -} - -func parseError(txError error) (string, error) { - b, err := json.Marshal(txError) - if err != nil { - return "", err - } - var callErr struct { - Code int - Data string `json:"data"` - Message string `json:"message"` - } - if json.Unmarshal(b, &callErr) != nil { - return "", err - } - - if callErr.Data == "" && strings.Contains(callErr.Message, "missing trie node") { - return "", errors.Errorf("please use an archive node") - } - - return callErr.Data, nil -} - -func panicErr(err error) { - if err != nil { - panic(err) - } -} diff --git a/core/scripts/go.mod b/core/scripts/go.mod index b167d6cd02..8d53e9505e 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -19,21 +19,18 @@ require ( github.com/montanaflynn/stats v0.7.1 github.com/olekukonko/tablewriter v0.0.5 github.com/pelletier/go-toml/v2 v2.2.0 - github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 - github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 - github.com/spf13/viper v1.18.2 + github.com/spf13/viper v1.15.0 github.com/stretchr/testify v1.9.0 github.com/umbracle/ethgo v0.1.3 github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 github.com/urfave/cli v1.22.14 - go.uber.org/multierr v1.11.0 google.golang.org/protobuf v1.34.2 k8s.io/api v0.30.0 k8s.io/apimachinery v0.30.0 @@ -44,14 +41,14 @@ require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect - cosmossdk.io/depinject v1.0.0-alpha.4 // indirect - cosmossdk.io/errors v1.0.1 // indirect - cosmossdk.io/math v1.3.0 // indirect + cosmossdk.io/depinject v1.0.0-alpha.3 // indirect + cosmossdk.io/errors v1.0.0 // indirect + cosmossdk.io/math v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect - github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect + github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect github.com/CosmWasm/wasmd v0.40.1 // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect @@ -80,25 +77,25 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect - github.com/cockroachdb/errors v1.10.0 // indirect + github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect - github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/redact v1.1.3 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.37.5 // indirect - github.com/cometbft/cometbft-db v0.8.0 // indirect + github.com/cometbft/cometbft v0.37.2 // indirect + github.com/cometbft/cometbft-db v0.7.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect - github.com/cosmos/cosmos-sdk v0.47.11 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect + github.com/cosmos/cosmos-sdk v0.47.4 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.11 // indirect - github.com/cosmos/iavl v0.20.1 // indirect - github.com/cosmos/ibc-go/v7 v7.5.1 // indirect - github.com/cosmos/ics23/go v0.10.0 // indirect - github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect + github.com/cosmos/iavl v0.20.0 // indirect + github.com/cosmos/ibc-go/v7 v7.0.1 // indirect + github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect + github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect @@ -120,7 +117,7 @@ require ( github.com/esote/minmaxheap v1.0.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fatih/color v1.16.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fxamacker/cbor/v2 v2.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gagliardetto/binary v0.7.7 // indirect @@ -129,7 +126,7 @@ require ( github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 // indirect - github.com/getsentry/sentry-go v0.23.0 // indirect + github.com/getsentry/sentry-go v0.19.0 // indirect github.com/gin-contrib/cors v1.5.0 // indirect github.com/gin-contrib/expvar v0.0.1 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect @@ -174,14 +171,14 @@ require ( github.com/gorilla/sessions v1.2.2 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/grafana/pyroscope-go v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/graph-gophers/dataloader v5.0.0+incompatible // indirect github.com/graph-gophers/graphql-go v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect @@ -216,7 +213,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.3 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -225,7 +222,6 @@ require ( github.com/leodido/go-urn v1.2.4 // indirect github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -254,6 +250,7 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/pressly/goose/v3 v3.21.1 // indirect @@ -266,33 +263,33 @@ require ( github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect - github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/scylladb/go-reflectx v1.0.1 // indirect github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc // indirect + github.com/smartcontractkit/chain-selectors v1.0.21 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.7.3 // indirect - github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/subosito/gotenv v1.6.0 // indirect + github.com/subosito/gotenv v1.4.2 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect + github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect github.com/test-go/testify v1.1.4 // indirect @@ -313,15 +310,15 @@ require ( github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zondax/hid v0.9.2 // indirect - github.com/zondax/ledger-go v0.14.3 // indirect + github.com/zondax/hid v0.9.1 // indirect + github.com/zondax/ledger-go v0.14.1 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect go.etcd.io/bbolt v1.3.7 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect @@ -329,24 +326,25 @@ require ( go.opentelemetry.io/otel/sdk v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect + go.uber.org/multierr v1.11.0 // indirect go.uber.org/ratelimit v0.3.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/arch v0.7.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/oauth2 v0.20.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/tools v0.24.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect google.golang.org/grpc v1.65.0 // indirect gopkg.in/guregu/null.v4 v4.0.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect @@ -357,7 +355,7 @@ require ( k8s.io/klog/v2 v2.120.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect - pgregory.net/rapid v1.1.0 // indirect + pgregory.net/rapid v0.5.5 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect @@ -373,4 +371,5 @@ replace ( // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f + ) diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 7ab6113b2a..83e2968983 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -4,33 +4,52 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= -cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= +cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= +cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= +cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= +cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= +cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.27.2 h1:5cE5hdrwJV/92ravlwIFRGnyH9CpLGhh4N0ZDVTU+BA= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= +cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw= +cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= -cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= +cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo= @@ -39,14 +58,14 @@ cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= -cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= -cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= -cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= -cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= -cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= -cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= -cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= -cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= +cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= +cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= +cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= +cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= +cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca h1:msenprh2BLLRwNT7zN56TbBHOGk/7ARQckXHxXyvjoQ= +cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c= +cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= +cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -59,6 +78,7 @@ github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo8 github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= @@ -66,8 +86,10 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzS github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= -github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= github.com/CosmWasm/wasmd v0.40.1/go.mod h1:6EOwnv7MpuFaEqxcUOdFV9i4yvrdOciaY6VQ1o7A3yg= github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= @@ -79,6 +101,7 @@ github.com/Depado/ginprom v1.8.0 h1:zaaibRLNI1dMiiuj1MKzatm8qrcHzikMlCc1anqOdyo= github.com/Depado/ginprom v1.8.0/go.mod h1:XBaKzeNBqPF4vxJpNLincSQZeMDnZp1tIbU0FU0UKgg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= @@ -93,6 +116,7 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= @@ -100,7 +124,10 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/ github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= +github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= +github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -126,6 +153,7 @@ github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -206,29 +234,35 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= +github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= +github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.10.0 h1:lfxS8zZz1+OjtV4MtNWgboi/W5tyLEB6VQZBXN+0VUU= -github.com/cockroachdb/errors v1.10.0/go.mod h1:lknhIsEVQ9Ss/qKDBQS/UqFSvPQjOwNq2qyKAxtHRqE= +github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= +github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= -github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= -github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= -github.com/cometbft/cometbft v0.37.5 h1:/U/TlgMh4NdnXNo+YU9T2NMCWyhXNDF34Mx582jlvq0= -github.com/cometbft/cometbft v0.37.5/go.mod h1:QC+mU0lBhKn8r9qvmnq53Dmf3DWBt4VtkcKw2C81wxY= -github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= -github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0= +github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= +github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= +github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= +github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -248,10 +282,10 @@ github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= -github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= -github.com/cosmos/cosmos-sdk v0.47.11 h1:0Qx7eORw0RJqPv+mvDuU8NQ1LV3nJJKJnPoYblWHolc= -github.com/cosmos/cosmos-sdk v0.47.11/go.mod h1:ADjORYzUQqQv/FxDi0H0K5gW/rAk1CiDR3ZKsExfJV0= +github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= +github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= +github.com/cosmos/cosmos-sdk v0.47.4 h1:FVUpEprm58nMmBX4xkRdMDaIG5Nr4yy92HZAfGAw9bg= +github.com/cosmos/cosmos-sdk v0.47.4/go.mod h1:R5n+uM7vguVPFap4pgkdvQCT1nVo/OtPwrlAU40rvok= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -259,14 +293,14 @@ github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiK github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v0.20.1 h1:rM1kqeG3/HBT85vsZdoSNsehciqUQPWrR4BYmqE2+zg= -github.com/cosmos/iavl v0.20.1/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= -github.com/cosmos/ibc-go/v7 v7.5.1 h1:KqS/g7W7EMX1OtOvufS8lWMJibOKpdgtNNZIU6fAgVU= -github.com/cosmos/ibc-go/v7 v7.5.1/go.mod h1:ktFg5GvKOyrGCqTWtW7Grj5uweU4ZapxrNeVS1CLLbo= -github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= -github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= -github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw= -github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M= +github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= +github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/ibc-go/v7 v7.0.1 h1:NIBNRWjlOoFvFQu1ZlgwkaSeHO5avf4C1YQiWegt8jw= +github.com/cosmos/ibc-go/v7 v7.0.1/go.mod h1:vEaapV6nuLPQlS+g8IKmxMo6auPi0i7HMv1PhViht/E= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= +github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= +github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -282,6 +316,10 @@ github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJF github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= +github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= +github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -306,6 +344,7 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFM github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70/go.mod h1:EoK/8RFbMEteaCaz89uessDTnCWjbbcr+DXcBh4el5o= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= @@ -331,24 +370,36 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo= github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/esote/minmaxheap v1.0.0 h1:rgA7StnXXpZG6qlM0S7pUmEv1KpWe32rYT4x8J8ntaA= github.com/esote/minmaxheap v1.0.0/go.mod h1:Ln8+i7fS1k3PLgZI2JAo0iA1as95QnIYiGCrqSJ5FZk= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= github.com/ethereum/go-ethereum v1.13.8/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -360,8 +411,8 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= @@ -374,14 +425,16 @@ github.com/gagliardetto/solana-go v1.8.4 h1:vmD/JmTlonyXGy39bAo0inMhmbdAwV7rXZtL github.com/gagliardetto/solana-go v1.8.4/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM= -github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE= -github.com/getsentry/sentry-go v0.23.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/getsentry/sentry-go v0.19.0 h1:BcCH3CN5tXt5aML+gwmbFwVptLLQA+eT866fCO9wVOM= +github.com/getsentry/sentry-go v0.19.0/go.mod h1:y3+lGEFEFexZtpbG1GUE2WD/f9zGyKYwpEqryTOC/nE= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= @@ -406,6 +459,8 @@ github.com/gkampitakis/go-snaps v0.5.4 h1:GX+dkKmVsRenz7SoTbdIEL4KQARZctkMiZ8ZKp github.com/gkampitakis/go-snaps v0.5.4/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -432,6 +487,7 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= @@ -464,6 +520,9 @@ github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6l github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= @@ -474,8 +533,12 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= @@ -493,7 +556,9 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -501,6 +566,7 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -520,6 +586,7 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -530,14 +597,18 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= @@ -545,6 +616,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -552,6 +625,11 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= @@ -564,12 +642,13 @@ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/enterprise-certificate-proxy v0.3.1 h1:SBWmZhjUDRorQxrN0nwzf+AHBxnbFjViHQS4P0yVpmQ= +github.com/googleapis/enterprise-certificate-proxy v0.3.1/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -582,13 +661,14 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= @@ -604,8 +684,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= @@ -648,6 +728,7 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= @@ -681,10 +762,12 @@ github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -692,6 +775,11 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -770,20 +858,30 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -797,6 +895,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= @@ -810,8 +910,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= -github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= @@ -829,9 +927,12 @@ github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -839,6 +940,7 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -851,11 +953,14 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= @@ -896,6 +1001,7 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= @@ -903,6 +1009,10 @@ github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ib github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -919,6 +1029,7 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= @@ -967,6 +1078,7 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -1006,6 +1118,8 @@ github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= +github.com/regen-network/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= @@ -1020,6 +1134,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= @@ -1028,25 +1143,24 @@ github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= -github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= +github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= -github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= -github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= @@ -1070,18 +1184,18 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc h1:8267l5X5oF2JnGsDaEG4i0JSQO9o0eC61SscTfWc1bk= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= -github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa/go.mod h1:wZvLHX/Sd9hskN51016cTFcT3G62KXVa6xbVDS7tRjc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= @@ -1099,14 +1213,12 @@ github.com/smartcontractkit/wsrpc v0.7.3/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgq github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= -github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= +github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= @@ -1115,14 +1227,16 @@ github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= +github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= @@ -1149,13 +1263,15 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= -github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= @@ -1190,8 +1306,10 @@ github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2 github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= @@ -1209,10 +1327,14 @@ github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE= github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -1220,23 +1342,31 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= -github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= -github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= +github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= +github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= +github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= @@ -1263,10 +1393,10 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/contrib/propagators/b3 v1.24.0 h1:n4xwCdTx3pZqZs2CjS/CUZAs03y3dZcGhC/FepKtEUY= go.opentelemetry.io/contrib/propagators/b3 v1.24.0/go.mod h1:k5wRxKRU2uXx2F8uNJ4TaonuEO/V7/5xoz7kdsDACT8= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= @@ -1279,8 +1409,8 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= -go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= +go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= +go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -1315,8 +1445,8 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= -golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1326,21 +1456,26 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1351,8 +1486,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1366,6 +1501,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1374,11 +1510,13 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1390,46 +1528,64 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= -golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1437,12 +1593,14 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1480,32 +1638,47 @@ golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1513,8 +1686,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1522,8 +1695,8 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1536,19 +1709,22 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1581,16 +1757,33 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1610,16 +1803,27 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= -google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= +google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1639,18 +1843,37 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= +google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1663,9 +1886,15 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1676,6 +1905,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -1701,8 +1931,10 @@ gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:a gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1718,19 +1950,21 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= @@ -1761,8 +1995,8 @@ modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= -pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= +pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index ffcfc67b87..582dd61677 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -8,7 +8,7 @@ import ( "sync" "github.com/smartcontractkit/chainlink-common/pkg/loop" - relay "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" + "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/adapters" diff --git a/core/services/ocr2/plugins/ccip/exportinternal.go b/core/services/ocr2/plugins/ccip/exportinternal.go index aecf1a0b16..e6c41a28b2 100644 --- a/core/services/ocr2/plugins/ccip/exportinternal.go +++ b/core/services/ocr2/plugins/ccip/exportinternal.go @@ -6,8 +6,8 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp.go index cb9e0015ca..682b070491 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/factory/onramp.go @@ -3,11 +3,12 @@ package factory import ( "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go index 6737abe64c..2190d7ad49 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/onramp.go @@ -10,12 +10,13 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go index 2939682347..071e8a8e03 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/onramp.go @@ -11,12 +11,13 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go index 354a5defdd..ad540ffd64 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_5_0/onramp.go @@ -11,13 +11,13 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/smartcontractkit/chainlink-common/pkg/hashutil" + "github.com/smartcontractkit/chainlink-common/pkg/logger" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go index 08bfa37c4c..e1aed59053 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -97,7 +97,8 @@ func NewCommitOffchainConfig( ExecGasPriceDeviationPPB uint32, TokenPriceHeartBeat config.Duration, TokenPriceDeviationPPB uint32, - InflightCacheExpiry config.Duration) CommitOffchainConfig { + InflightCacheExpiry config.Duration, + priceReportingDisabled bool) CommitOffchainConfig { return CommitOffchainConfig{v1_2_0.JSONCommitOffchainConfig{ GasPriceHeartBeat: GasPriceHeartBeat, DAGasPriceDeviationPPB: DAGasPriceDeviationPPB, @@ -105,6 +106,7 @@ func NewCommitOffchainConfig( TokenPriceHeartBeat: TokenPriceHeartBeat, TokenPriceDeviationPPB: TokenPriceDeviationPPB, InflightCacheExpiry: InflightCacheExpiry, + PriceReportingDisabled: priceReportingDisabled, }} } diff --git a/core/services/ocr2/plugins/ccip/testhelpers/config.go b/core/services/ocr2/plugins/ccip/testhelpers/config.go index 4e2f358835..c9d1ca5a12 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/config.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/config.go @@ -41,6 +41,7 @@ func (c *CCIPContracts) createCommitOffchainConfig(t *testing.T, feeUpdateHearBe *config.MustNewDuration(feeUpdateHearBeat), 1, *config.MustNewDuration(inflightCacheExpiry), + false, ).Encode() require.NoError(t, err) return config diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go index 35401b0316..676ae79e35 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go @@ -7,6 +7,7 @@ import ( "math/big" "net/http" "net/http/httptest" + "slices" "strconv" "strings" "testing" @@ -36,6 +37,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" v2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -47,6 +49,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" @@ -378,7 +381,6 @@ func setupNodeCCIP( fmt.Sprintf("127.0.0.1:%d", port), } c.Log.Level = &loglevel - c.Feature.CCIP = &trueRef c.Feature.UICSAKeys = &trueRef c.Feature.FeedsManager = &trueRef c.OCR.Enabled = &falseRef @@ -458,9 +460,10 @@ func setupNodeCCIP( } loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing()) relayerFactory := chainlink.RelayerFactory{ - Logger: lggr, - LoopRegistry: loopRegistry, - GRPCOpts: loop.GRPCOpts{}, + Logger: lggr, + LoopRegistry: loopRegistry, + GRPCOpts: loop.GRPCOpts{}, + CapabilitiesRegistry: coretypes.NewCapabilitiesRegistry(t), } testCtx := testutils.Context(t) // evm alway enabled for backward compatibility @@ -761,6 +764,47 @@ func (c *CCIPIntegrationTestHarness) NoNodesHaveExecutedSeqNum(t *testing.T, seq return log } +func (c *CCIPIntegrationTestHarness) EventuallyPriceRegistryUpdated(t *testing.T, block uint64, srcSelector uint64, tokens []common.Address, sourceNative common.Address, priceRegistryOpts ...common.Address) { + var priceRegistry *price_registry_1_2_0.PriceRegistry + var err error + if len(priceRegistryOpts) > 0 { + priceRegistry, err = price_registry_1_2_0.NewPriceRegistry(priceRegistryOpts[0], c.Dest.Chain) + require.NoError(t, err) + } else { + require.NotNil(t, c.Dest.PriceRegistry, "no priceRegistry configured") + priceRegistry = c.Dest.PriceRegistry + } + + g := gomega.NewGomegaWithT(t) + g.Eventually(func() bool { + it, err := priceRegistry.FilterUsdPerTokenUpdated(&bind.FilterOpts{Start: block}, tokens) + g.Expect(err).NotTo(gomega.HaveOccurred(), "Error filtering UsdPerTokenUpdated event") + + tokensFetched := make([]common.Address, 0, len(tokens)) + for it.Next() { + tokenFetched := it.Event.Token + tokensFetched = append(tokensFetched, tokenFetched) + t.Log("Token price updated", tokenFetched.String(), it.Event.Value.String(), it.Event.Timestamp.String()) + } + + for _, token := range tokens { + if !slices.Contains(tokensFetched, token) { + return false + } + } + + return true + }, testutils.WaitTimeout(t), 10*time.Second).Should(gomega.BeTrue(), "Tokens prices has not been updated") + + g.Eventually(func() bool { + it, err := priceRegistry.FilterUsdPerUnitGasUpdated(&bind.FilterOpts{Start: block}, []uint64{srcSelector}) + g.Expect(err).NotTo(gomega.HaveOccurred(), "Error filtering UsdPerUnitGasUpdated event") + g.Expect(it.Next()).To(gomega.BeTrue(), "No UsdPerUnitGasUpdated event found") + + return true + }, testutils.WaitTimeout(t), 10*time.Second).Should(gomega.BeTrue(), "source gas price has not been updated") +} + func (c *CCIPIntegrationTestHarness) EventuallyCommitReportAccepted(t *testing.T, currentBlock uint64, commitStoreOpts ...common.Address) commit_store.CommitStoreCommitReport { var commitStore *commit_store.CommitStore var err error diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go index ceb96d4c15..b8db2dfff7 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go @@ -96,7 +96,8 @@ func NewCommitOffchainConfig( ExecGasPriceDeviationPPB uint32, TokenPriceHeartBeat config.Duration, TokenPriceDeviationPPB uint32, - InflightCacheExpiry config.Duration) CommitOffchainConfig { + InflightCacheExpiry config.Duration, + priceReportingDisabled bool) CommitOffchainConfig { return CommitOffchainConfig{v1_2_0.JSONCommitOffchainConfig{ GasPriceHeartBeat: GasPriceHeartBeat, DAGasPriceDeviationPPB: DAGasPriceDeviationPPB, @@ -104,6 +105,7 @@ func NewCommitOffchainConfig( TokenPriceHeartBeat: TokenPriceHeartBeat, TokenPriceDeviationPPB: TokenPriceDeviationPPB, InflightCacheExpiry: InflightCacheExpiry, + PriceReportingDisabled: priceReportingDisabled, }} } diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go index 751ae5c1a9..666ad79e59 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go @@ -38,6 +38,7 @@ func (c *CCIPContracts) createCommitOffchainConfig(t *testing.T, feeUpdateHearBe *config.MustNewDuration(feeUpdateHearBeat), 1, *config.MustNewDuration(inflightCacheExpiry), + false, ).Encode() require.NoError(t, err) return config diff --git a/core/services/ocr2/plugins/liquiditymanager/internal/integration_test.go b/core/services/ocr2/plugins/liquiditymanager/internal/integration_test.go deleted file mode 100644 index 765366a5c3..0000000000 --- a/core/services/ocr2/plugins/liquiditymanager/internal/integration_test.go +++ /dev/null @@ -1,843 +0,0 @@ -package internal_test - -import ( - "context" - "fmt" - "math/big" - "net/http" - "sync" - "testing" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core" - gethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" - "github.com/hashicorp/consul/sdk/freeport" - chainsel "github.com/smartcontractkit/chain-selectors" - "github.com/smartcontractkit/libocr/commontypes" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink-common/pkg/config" - - "github.com/smartcontractkit/chainlink-common/pkg/loop" - "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - v2toml "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" - evmutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/liquiditymanager" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/mock_l1_bridge_adapter" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/logger/audit" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/bridge/testonlybridge" - integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/testhelpers/integration" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" - "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" - "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" - - "github.com/smartcontractkit/chainlink/v2/core/utils" - "github.com/smartcontractkit/chainlink/v2/plugins" -) - -var ( - mainChainID = int64(chainsel.GETH_TESTNET.EvmChainID) -) - -func TestLiquidityManager_Integration(t *testing.T) { - t.Skip("flakey test") - newTestUniverse(t, 2, false) -} - -type ocr3Node struct { - app chainlink.Application - peerID string - transmitters map[int64]common.Address - keybundle ocr2key.KeyBundle -} - -type onchainUniverse struct { - backend *backends.SimulatedBackend - chainID uint64 - wethToken *weth9.WETH9 - lockReleasePool *lock_release_token_pool.LockReleaseTokenPool - liquidityManager *liquiditymanager.LiquidityManager - bridgeAdapter *mock_l1_bridge_adapter.MockL1BridgeAdapter -} - -func setupNodeOCR3( - t *testing.T, - owner *bind.TransactOpts, - port int, - chainIDToBackend map[int64]*backends.SimulatedBackend, - p2pV2Bootstrappers []commontypes.BootstrapperLocator, - useForwarders bool, -) *ocr3Node { - // Do not want to load fixtures as they contain a dummy chainID. - config, db := heavyweight.FullTestDBNoFixturesV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.Insecure.OCRDevelopmentMode = ptr(true) // Disables ocr spec validation so we can have fast polling for the test. - - c.Feature.LogPoller = ptr(true) - - c.P2P.V2.Enabled = ptr(true) - c.P2P.V2.DeltaDial = config.MustNewDuration(500 * time.Millisecond) - c.P2P.V2.DeltaReconcile = config.MustNewDuration(5 * time.Second) - c.P2P.V2.ListenAddresses = &[]string{fmt.Sprintf("127.0.0.1:%d", port)} - if len(p2pV2Bootstrappers) > 0 { - c.P2P.V2.DefaultBootstrappers = &p2pV2Bootstrappers - } - - c.OCR.Enabled = ptr(false) - c.OCR.DefaultTransactionQueueDepth = ptr(uint32(200)) - c.OCR2.Enabled = ptr(true) - - c.EVM[0].LogPollInterval = config.MustNewDuration(500 * time.Millisecond) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](3_500_000) - c.EVM[0].Transactions.ForwardersEnabled = &useForwarders - c.OCR2.ContractPollInterval = config.MustNewDuration(5 * time.Second) - - var chains v2toml.EVMConfigs - for chainID := range chainIDToBackend { - chains = append(chains, createConfigV2Chain(big.NewInt(chainID))) - } - c.EVM = chains - c.OCR2.ContractPollInterval = config.MustNewDuration(5 * time.Second) - }) - - lggr := logger.TestLogger(t) - lggr.SetLogLevel(zapcore.InfoLevel) - ctx := testutils.Context(t) - clients := make(map[int64]client.Client) - - for chainID, backend := range chainIDToBackend { - clients[chainID] = client.NewSimulatedBackendClient(t, backend, big.NewInt(chainID)) - } - - master := keystore.New(db, utils.FastScryptParams, lggr) - - keystore := KeystoreSim{ - eks: &EthKeystoreSim{ - Eth: master.Eth(), - t: t, - }, - csa: master.CSA(), - } - mailMon := mailbox.NewMonitor("LiquidityManager", lggr.Named("mailbox")) - evmOpts := chainlink.EVMFactoryConfig{ - ChainOpts: legacyevm.ChainOpts{ - AppConfig: config, - GenEthClient: func(i *big.Int) client.Client { - t.Log("genning eth client for chain id:", i.String()) - client, ok := clients[i.Int64()] - if !ok { - t.Fatal("no backend for chainID", i) - } - return client - }, - MailMon: mailMon, - DS: db, - }, - CSAETHKeystore: keystore, - } - relayerFactory := chainlink.RelayerFactory{ - Logger: lggr, - LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing()), - GRPCOpts: loop.GRPCOpts{}, - } - initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitEVM(testutils.Context(t), relayerFactory, evmOpts)} - rci, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) - require.NoError(t, err) - - app, err := chainlink.NewApplication(chainlink.ApplicationOpts{ - Config: config, - DS: db, - KeyStore: master, - RelayerChainInteroperators: rci, - Logger: lggr, - ExternalInitiatorManager: nil, - CloseLogger: lggr.Sync, - UnrestrictedHTTPClient: &http.Client{}, - RestrictedHTTPClient: &http.Client{}, - AuditLogger: audit.NoopLogger, - MailMon: mailMon, - LoopRegistry: plugins.NewLoopRegistry(lggr, config.Tracing()), - }) - require.NoError(t, err) - require.NoError(t, app.GetKeyStore().Unlock(ctx, "password")) - _, err = app.GetKeyStore().P2P().Create(ctx) - require.NoError(t, err) - - p2pIDs, err := app.GetKeyStore().P2P().GetAll() - require.NoError(t, err) - require.Len(t, p2pIDs, 1) - peerID := p2pIDs[0].PeerID() - - // create a transmitter for each chain - transmitters := make(map[int64]common.Address) - for chainID, backend := range chainIDToBackend { - addrs, err2 := app.GetKeyStore().Eth().EnabledAddressesForChain(testutils.Context(t), big.NewInt(chainID)) - require.NoError(t, err2) - if len(addrs) == 1 { - // just fund the address - fundAddress(t, owner, addrs[0], assets.Ether(10).ToInt(), backend) - transmitters[chainID] = addrs[0] - } else { - // create key and fund it - _, err3 := app.GetKeyStore().Eth().Create(testutils.Context(t), big.NewInt(chainID)) - require.NoError(t, err3, "failed to create key for chain", chainID) - sendingKeys, err3 := app.GetKeyStore().Eth().EnabledAddressesForChain(testutils.Context(t), big.NewInt(chainID)) - require.NoError(t, err3) - require.Len(t, sendingKeys, 1) - fundAddress(t, owner, sendingKeys[0], assets.Ether(10).ToInt(), backend) - transmitters[chainID] = sendingKeys[0] - } - } - require.Len(t, transmitters, len(chainIDToBackend)) - - keybundle, err := app.GetKeyStore().OCR2().Create(ctx, chaintype.EVM) - require.NoError(t, err) - - return &ocr3Node{ - app: app, - peerID: peerID.Raw(), - transmitters: transmitters, - keybundle: keybundle, - } -} - -func newTestUniverse(t *testing.T, numChains int, adapterHoldNative bool) { - // create chains and deploy contracts - owner, chains := createChains(t, numChains) - universes := deployContracts(t, owner, chains, adapterHoldNative) - createConnectedNetwork(t, owner, chains, universes) - transferBalances(t, owner, universes) - mainContract := universes[mainChainID].liquidityManager.Address() - - t.Log("Creating bootstrap node") - bootstrapNodePort := freeport.GetOne(t) - bootstrapNode := setupNodeOCR3(t, owner, bootstrapNodePort, chains, nil, false) - numNodes := 4 - - t.Log("creating ocr3 nodes") - var ( - oracles = make(map[int64][]confighelper2.OracleIdentityExtra) - transmitters = make(map[int64][]common.Address) - onchainPubKeys []common.Address - kbs []ocr2key.KeyBundle - apps []chainlink.Application - nodes []*ocr3Node - ) - ports := freeport.GetN(t, numNodes) - for i := 0; i < numNodes; i++ { - // Supply the bootstrap IP and port as a V2 peer address - bootstrappers := []commontypes.BootstrapperLocator{ - {PeerID: bootstrapNode.peerID, Addrs: []string{ - fmt.Sprintf("127.0.0.1:%d", bootstrapNodePort), - }}, - } - node := setupNodeOCR3(t, owner, ports[i], chains, bootstrappers, false) - - kbs = append(kbs, node.keybundle) - apps = append(apps, node.app) - for chainID, transmitter := range node.transmitters { - transmitters[chainID] = append(transmitters[chainID], transmitter) - } - onchainPubKeys = append(onchainPubKeys, common.BytesToAddress(node.keybundle.PublicKey())) - for chainID, transmitter := range node.transmitters { - identity := confighelper2.OracleIdentityExtra{ - OracleIdentity: confighelper2.OracleIdentity{ - OnchainPublicKey: node.keybundle.PublicKey(), - TransmitAccount: ocrtypes.Account(transmitter.Hex()), - OffchainPublicKey: node.keybundle.OffchainPublicKey(), - PeerID: node.peerID, - }, - ConfigEncryptionPublicKey: node.keybundle.ConfigEncryptionPublicKey(), - } - oracles[chainID] = append(oracles[chainID], identity) - } - nodes = append(nodes, node) - } - - t.Log("starting ticker to commit blocks") - tick := time.NewTicker(1 * time.Second) - defer tick.Stop() - tickCtx, tickCancel := context.WithCancel(testutils.Context(t)) - defer tickCancel() - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - for { - select { - case <-tick.C: - for _, backend := range chains { - backend.Commit() - } - case <-tickCtx.Done(): - return - } - } - }() - t.Cleanup(func() { - tickCancel() - wg.Wait() - }) - - t.Log("setting config") - blocksBeforeConfig := setLiquidityManagerConfigs( - t, - owner, - universes, - chains, - onchainPubKeys, - transmitters, - oracles) - mainFromBlock := blocksBeforeConfig[mainChainID] - - t.Log("adding bootstrap node job") - err := bootstrapNode.app.Start(testutils.Context(t)) - require.NoError(t, err, "failed to start bootstrap node") - t.Cleanup(func() { - require.NoError(t, bootstrapNode.app.Stop()) - }) - - evmChains := bootstrapNode.app.GetRelayers().LegacyEVMChains() - require.NotNil(t, evmChains) - require.Len(t, evmChains.Slice(), numChains) - bootstrapJobSpec, err := integrationtesthelpers.NewBootsrapJobSpec(&integrationtesthelpers.LMJobSpecParams{ - ChainID: 1337, - ContractID: mainContract.Hex(), - RelayFromBlock: mainFromBlock, - }) - require.NoError(t, err, "failed to create bootstrap job spec") - bootstrapJobSpecStr, err := bootstrapJobSpec.String() - require.NoError(t, err, "failed to convert bootstrap job spec to string") - t.Log("creating bootstrap job with spec:\n", bootstrapJobSpecStr) - ocrJob, err := ocrbootstrap.ValidatedBootstrapSpecToml(bootstrapJobSpecStr) - require.NoError(t, err, "failed to validate bootstrap job") - err = bootstrapNode.app.AddJobV2(testutils.Context(t), &ocrJob) - require.NoError(t, err, "failed to add bootstrap job") - - t.Log("creating ocr3 jobs") - for i := 0; i < numNodes; i++ { - err = apps[i].Start(testutils.Context(t)) - require.NoError(t, err) - tapp := apps[i] - t.Cleanup(func() { - require.NoError(t, tapp.Stop()) - }) - - mainChain := mustGetChainByEvmID(t, testutils.SimulatedChainID.Int64()) - jobSpec, err := integrationtesthelpers.NewJobSpec(&integrationtesthelpers.LMJobSpecParams{ - Name: "liquiditymanager-integration-test", - Type: "ping-pong", - ChainID: 1337, - ContractID: mainContract.Hex(), - OCRKeyBundleID: kbs[i].ID(), - TransmitterID: nodes[i].transmitters[1337].Hex(), - RelayFromBlock: mainFromBlock, - FollowerChains: buildFollowerChainsFromBlocksToml(blocksBeforeConfig), - LiquidityManagerAddress: mainContract, - NetworkSelector: mainChain.Selector, - }) - require.NoError(t, err, "failed to create job spec") - jobSpecStr, err := jobSpec.String() - require.NoError(t, err, "failed to convert job spec to string") - t.Log("Creating liquidityManager job with spec:\n", jobSpecStr) - ocrJob2, err2 := validate.ValidatedOracleSpecToml( - testutils.Context(t), - apps[i].GetConfig().OCR2(), - apps[i].GetConfig().Insecure(), - jobSpecStr, - nil, - ) - require.NoError(t, err2, "failed to validate liquidityManager job") - err2 = apps[i].AddJobV2(testutils.Context(t), &ocrJob2) - require.NoError(t, err2, "failed to add liquidityManager job") - } - - t.Log("waiting for a transmission") - waitForTransmissions(t, universes) -} - -func waitForTransmissions( - t *testing.T, - universes map[int64]onchainUniverse, -) { - start := uint64(1) - liquidityTransferredSink := make(chan *liquiditymanager.LiquidityManagerLiquidityTransferred) - finalizationStepSink := make(chan *liquiditymanager.LiquidityManagerFinalizationStepCompleted) - var subs []event.Subscription - for _, uni := range universes { - sub, err := uni.liquidityManager.WatchLiquidityTransferred(&bind.WatchOpts{ - Start: &start, - }, liquidityTransferredSink, nil, nil, nil) - require.NoError(t, err, "failed to create subscription") - subs = append(subs, sub) - - sub, err = uni.liquidityManager.WatchFinalizationStepCompleted(&bind.WatchOpts{ - Start: &start, - }, finalizationStepSink, nil, nil) - require.NoError(t, err, "failed to create subscription") - subs = append(subs, sub) - } - defer func() { - for _, sub := range subs { - sub.Unsubscribe() - } - }() - ticker := time.NewTicker(1 * time.Second) - defer ticker.Stop() - sentEvents := map[string]struct{}{} - for { - select { - case lt := <-liquidityTransferredSink: - // determine if it's a send or receive event based on the BridgeReturnData field - // if it's a send event, then the BridgeReturnData will not be empty - if len(lt.BridgeReturnData) > 0 { - // for the test bridges, bridge return data is just a nonce - nonce, err := testonlybridge.UnpackBridgeSendReturnData(lt.BridgeReturnData) - require.NoError(t, err) - t.Log("received send event with nonce:", nonce, "tx hash:", lt.Raw.TxHash.String()) - sentEvents[nonce.String()] = struct{}{} - } else { - // for the test bridges, the bridge specific data is an amount and a nonce - amount, nonce, err := testonlybridge.UnpackFinalizeBridgePayload(lt.BridgeSpecificData) - require.NoError(t, err) - t.Log("received receive event with amount:", amount, "nonce:", nonce, "tx hash:", lt.Raw.TxHash.String()) - _, ok := sentEvents[nonce.String()] - if ok { - t.Log("received corresponding receive event") - return - } - t.Fatal("received receive event without corresponding send event") - } - case fsc := <-finalizationStepSink: - nonce, err := testonlybridge.UnpackProveBridgePayload(fsc.BridgeSpecificData) - require.NoError(t, err) - t.Log("received finalization step completed event with seqNr:", fsc.OcrSeqNum, - ", nonce:", nonce.String(), ", tx hash:", fsc.Raw.TxHash.String()) - case <-ticker.C: - t.Log("waiting for transmission or liquidity transferred event") - } - } -} - -func setLiquidityManagerConfig( - t *testing.T, - owner *bind.TransactOpts, - wrapper *liquiditymanager.LiquidityManager, - chain *backends.SimulatedBackend, - onchainPubKeys []common.Address, - transmitters []common.Address, - oracles []confighelper2.OracleIdentityExtra, -) (blockBeforeConfig int64) { - beforeConfig, err := chain.BlockByNumber(testutils.Context(t), nil) - require.NoError(t, err) - - // most of the config on the follower chains does not matter - // except for signers + transmitters - var schedule []int - for range oracles { - schedule = append(schedule, 1) - } - offchainConfig, onchainConfig := []byte{}, []byte{} - f := uint8(1) - _, _, f, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( - 30*time.Second, // deltaProgress - 10*time.Second, // deltaResend - 20*time.Second, // deltaInitial - 2*time.Second, // deltaRound - 20*time.Second, // deltaGrace - 10*time.Second, // deltaCertifiedCommitRequest - 10*time.Second, // deltaStage - 3, // rmax - schedule, - oracles, - offchainConfig, - 50*time.Millisecond, // maxDurationQuery - 5*time.Second, // maxDurationObservation - 10*time.Second, // maxDurationShouldAcceptAttestedReport - 10*time.Second, // maxDurationShouldTransmitAcceptedReport - int(f), - onchainConfig) - require.NoError(t, err, "failed to create contract config") - _, err = wrapper.SetOCR3Config( - owner, - onchainPubKeys, - transmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig) - require.NoError(t, err, "failed to set config") - chain.Commit() - - iter, err := wrapper.FilterConfigSet(&bind.FilterOpts{ - Start: beforeConfig.Number().Uint64(), - }) - require.NoError(t, err, "failed to create ConfigSet filter") - require.True(t, iter.Next()) - e := iter.Event - require.Equal(t, onchainPubKeys, e.Signers, "signers do not match") - require.Equal(t, transmitters, e.Transmitters, "transmitters do not match") - t.Log("config digest for liquidityManager at address: ", wrapper.Address(), ", is:", hexutil.Encode(e.ConfigDigest[:])) - - return beforeConfig.Number().Int64() -} - -func setLiquidityManagerConfigs( - t *testing.T, - owner *bind.TransactOpts, - universes map[int64]onchainUniverse, - chains map[int64]*backends.SimulatedBackend, - onchainPubKeys []common.Address, - transmitters map[int64][]common.Address, - oracles map[int64][]confighelper2.OracleIdentityExtra) (blocksBeforeConfig map[int64]int64) { - blocksBeforeConfig = make(map[int64]int64) - for chainID, uni := range universes { - blocksBeforeConfig[chainID] = setLiquidityManagerConfig( - t, - owner, - uni.liquidityManager, - chains[chainID], - onchainPubKeys, - transmitters[chainID], - oracles[chainID], - ) - } - return -} - -func ptr[T any](v T) *T { return &v } - -func createConfigV2Chain(chainID *big.Int) *v2toml.EVMConfig { - chain := v2toml.Defaults((*evmutils.Big)(chainID)) - chain.GasEstimator.LimitDefault = ptr(uint64(4e6)) - chain.LogPollInterval = config.MustNewDuration(500 * time.Millisecond) - chain.Transactions.ForwardersEnabled = ptr(false) - chain.FinalityDepth = ptr(uint32(2)) - return &v2toml.EVMConfig{ - ChainID: (*evmutils.Big)(chainID), - Enabled: ptr(true), - Chain: chain, - Nodes: v2toml.EVMNodes{&v2toml.Node{}}, - } -} - -var _ keystore.Eth = &EthKeystoreSim{} - -type EthKeystoreSim struct { - keystore.Eth - t *testing.T -} - -// override -func (e *EthKeystoreSim) SignTx(ctx context.Context, address common.Address, tx *gethtypes.Transaction, chainID *big.Int) (*gethtypes.Transaction, error) { - // always sign with chain id 1337 for the simulated backend - e.t.Log("always signing tx for chain id:", chainID.String(), "with chain id 1337, tx hash:", tx.Hash()) - return e.Eth.SignTx(ctx, address, tx, big.NewInt(1337)) -} - -type KeystoreSim struct { - eks keystore.Eth - csa keystore.CSA -} - -func (e KeystoreSim) Eth() keystore.Eth { - return e.eks -} - -func (e KeystoreSim) CSA() keystore.CSA { - return e.csa -} - -func fundAddress(t *testing.T, from *bind.TransactOpts, to common.Address, amount *big.Int, backend *backends.SimulatedBackend) { - nonce, err := backend.PendingNonceAt(testutils.Context(t), from.From) - require.NoError(t, err) - gp, err := backend.SuggestGasPrice(testutils.Context(t)) - require.NoError(t, err) - rawTx := gethtypes.NewTx(&gethtypes.LegacyTx{ - Nonce: nonce, - GasPrice: gp, - Gas: 21000, - To: &to, - Value: amount, - }) - signedTx, err := from.Signer(from.From, rawTx) - require.NoError(t, err) - err = backend.SendTransaction(testutils.Context(t), signedTx) - require.NoError(t, err) - backend.Commit() -} - -func createChains(t *testing.T, numChains int) (owner *bind.TransactOpts, chains map[int64]*backends.SimulatedBackend) { - owner = testutils.MustNewSimTransactor(t) - chains = make(map[int64]*backends.SimulatedBackend) - - chains[mainChainID] = backends.NewSimulatedBackend(core.GenesisAlloc{ - owner.From: core.GenesisAccount{ - Balance: assets.Ether(10_000).ToInt(), - }, - }, 30e6) - - for chainID := int64(chainsel.TEST_90000001.EvmChainID); chainID < int64(chainsel.TEST_90000020.EvmChainID); chainID++ { - chains[chainID] = backends.NewSimulatedBackend(core.GenesisAlloc{ - owner.From: core.GenesisAccount{ - Balance: assets.Ether(10000).ToInt(), - }, - }, 30e6) - - if len(chains) == numChains { - break - } - } - return -} - -func deployContracts( - t *testing.T, - owner *bind.TransactOpts, - chains map[int64]*backends.SimulatedBackend, - adapterHoldNative bool, -) ( - universes map[int64]onchainUniverse, -) { - universes = make(map[int64]onchainUniverse) - for chainID, backend := range chains { - // Deploy wrapped ether contract - // will act as the ERC-20 being bridged - wethAddress, _, _, err := weth9.DeployWETH9(owner, backend) - require.NoError(t, err, "failed to deploy WETH9 contract") - backend.Commit() - wethToken, err := weth9.NewWETH9(wethAddress, backend) - require.NoError(t, err, "failed to create WETH9 wrapper") - - // deposit some eth into the weth contract - _, err = wethToken.Deposit(&bind.TransactOpts{ - From: owner.From, - Signer: owner.Signer, - Value: assets.Ether(100).ToInt(), - Context: testutils.Context(t), - }) - require.NoError(t, err, "failed to deposit eth into weth contract") - - // deploy arm and arm proxy. - // required by the token pool - // otherwise not used by this test. - armAddress, _, _, err := mock_rmn_contract.DeployMockRMNContract(owner, backend) - require.NoError(t, err, "failed to deploy MockRMNContract contract") - backend.Commit() - armProxyAddress, _, _, err := rmn_proxy_contract.DeployRMNProxyContract(owner, backend, armAddress) - require.NoError(t, err, "failed to deploy RMNProxyContract contract") - backend.Commit() - - routerAddress, _, _, err := router.DeployRouter(owner, backend, wethAddress, armProxyAddress) - require.NoError(t, err, "failed to deploy Router contract") - backend.Commit() - - // deploy lock/release pool targeting the weth9 contract - lockReleasePoolAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( - owner, backend, wethAddress, []common.Address{}, armProxyAddress, true, routerAddress) - require.NoError(t, err, "failed to deploy LockReleaseTokenPool contract") - backend.Commit() - lockReleasePool, err := lock_release_token_pool.NewLockReleaseTokenPool(lockReleasePoolAddress, backend) - require.NoError(t, err) - - // deploy the liquidityManager and set the liquidity container to be the lock release pool - ch := mustGetChainByEvmID(t, chainID) - liquidityManagerAddr, _, _, err := liquiditymanager.DeployLiquidityManager(owner, backend, wethAddress, ch.Selector, lockReleasePoolAddress, big.NewInt(0), common.Address{}) - require.NoError(t, err, "failed to deploy LiquidityManager contract") - liquidityManager, err := liquiditymanager.NewLiquidityManager(liquidityManagerAddr, backend) - require.NoError(t, err, "failed to create LiquidityManager wrapper") - - // set the liquidityManager of the lock release pool to be the just deployed liquidityManager - _, err = lockReleasePool.SetRebalancer(owner, liquidityManagerAddr) - require.NoError(t, err, "failed to set liquidityManager on lock/release pool") - backend.Commit() - actualLiquidityManager, err := lockReleasePool.GetRebalancer(&bind.CallOpts{Context: testutils.Context(t)}) - require.NoError(t, err) - require.Equal(t, liquidityManagerAddr, actualLiquidityManager) - - // deploy the bridge adapter to point to the weth contract address - bridgeAdapterAddress, _, _, err := mock_l1_bridge_adapter.DeployMockL1BridgeAdapter(owner, backend, wethAddress, adapterHoldNative) - require.NoError(t, err, "failed to deploy mock l1 bridge adapter") - backend.Commit() - bridgeAdapter, err := mock_l1_bridge_adapter.NewMockL1BridgeAdapter(bridgeAdapterAddress, backend) - require.NoError(t, err) - - universes[chainID] = onchainUniverse{ - backend: backend, - chainID: uint64(chainID), - wethToken: wethToken, - lockReleasePool: lockReleasePool, - liquidityManager: liquidityManager, - bridgeAdapter: bridgeAdapter, - } - - t.Log("deployed contracts for chain:", chainID, - "weth:", wethAddress.Hex(), - "lockReleasePool:", lockReleasePool.Address().Hex(), - "rebalancer:", liquidityManagerAddr.Hex(), - "bridgeAdapter:", bridgeAdapterAddress.Hex(), - ) - } - return -} - -func buildFollowerChainsFromBlocksToml(fromBlocks map[int64]int64) string { - var s string - for chainID, fromBlock := range fromBlocks { - if chainID == mainChainID { - continue - } - s += fmt.Sprintf("%d = %d\n", chainID, fromBlock) - } - return s -} - -func transferBalances( - t *testing.T, - owner *bind.TransactOpts, - universes map[int64]onchainUniverse, -) { - for _, uni := range universes { - // move some weth to the bridge adapters - // so that they can transfer it to the rebalancer - // when it calls finalizeWithdrawal - _, err := uni.wethToken.Transfer(owner, uni.bridgeAdapter.Address(), assets.Ether(5).ToInt()) - require.NoError(t, err, "failed to transfer weth to bridge adapter") - uni.backend.Commit() - // confirm balance - bal, err := uni.wethToken.BalanceOf(&bind.CallOpts{Context: testutils.Context(t)}, uni.bridgeAdapter.Address()) - require.NoError(t, err) - require.Equal(t, assets.Ether(5).ToInt(), bal) - - // move some weth to the lock/release pool - // the LM will pull from this pool in order to send cross-chain - _, err = uni.wethToken.Transfer(owner, uni.lockReleasePool.Address(), assets.Ether(5).ToInt()) - require.NoError(t, err, "failed to transfer weth to lock/release pool") - uni.backend.Commit() - // confirm balance - bal, err = uni.wethToken.BalanceOf(&bind.CallOpts{Context: testutils.Context(t)}, uni.lockReleasePool.Address()) - require.NoError(t, err) - require.Equal(t, assets.Ether(5).ToInt(), bal) - - // check the balance of the token pool through the rebalancer, - // should be the same as the balance of the lock/release pool - // retrieved above. - bal, err = uni.liquidityManager.GetLiquidity(&bind.CallOpts{Context: testutils.Context(t)}) - require.NoError(t, err) - require.Equal(t, assets.Ether(5).ToInt(), bal) - } -} - -// create a connection from the main chain to all follower chains -// and from all follower chains to the main chain -// this is analogous to the main chain being an L1 and all other -// chains being L2's. -func createConnectedNetwork( - t *testing.T, - owner *bind.TransactOpts, - chains map[int64]*backends.SimulatedBackend, - universes map[int64]onchainUniverse, -) { - for chainID, uni := range universes { - if chainID == mainChainID { - continue - } - // follower -> main connection - remoteChain := mustGetChainByEvmID(t, mainChainID) - - _, err := uni.liquidityManager.SetCrossChainRebalancer( - owner, - liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs{ - RemoteRebalancer: universes[mainChainID].liquidityManager.Address(), - RemoteChainSelector: remoteChain.Selector, - Enabled: true, - LocalBridge: uni.bridgeAdapter.Address(), - RemoteToken: universes[mainChainID].wethToken.Address(), - }) - require.NoError(t, err, "failed to SetCrossChainRebalancer from follower to main chain") - chains[chainID].Commit() - - mgr, err := uni.liquidityManager.GetCrossChainRebalancer(&bind.CallOpts{Context: testutils.Context(t)}, remoteChain.Selector) - require.NoError(t, err) - require.Equal(t, universes[mainChainID].liquidityManager.Address(), mgr.RemoteRebalancer) - require.Equal(t, uni.bridgeAdapter.Address(), mgr.LocalBridge) - require.Equal(t, universes[mainChainID].wethToken.Address(), mgr.RemoteToken) - require.True(t, mgr.Enabled) - - // main -> follower connection - remoteChain = mustGetChainByEvmID(t, chainID) - - _, err = universes[mainChainID].liquidityManager.SetCrossChainRebalancer( - owner, - liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs{ - RemoteRebalancer: uni.liquidityManager.Address(), - RemoteChainSelector: remoteChain.Selector, - Enabled: true, - LocalBridge: universes[mainChainID].bridgeAdapter.Address(), - RemoteToken: uni.wethToken.Address(), - }) - require.NoError(t, err, "failed to add neighbor from main to follower chain") - chains[mainChainID].Commit() - - mgr, err = universes[mainChainID].liquidityManager.GetCrossChainRebalancer( - &bind.CallOpts{Context: testutils.Context(t)}, remoteChain.Selector) - require.NoError(t, err) - require.Equal(t, uni.liquidityManager.Address(), mgr.RemoteRebalancer) - require.Equal(t, universes[mainChainID].bridgeAdapter.Address(), mgr.LocalBridge) - require.Equal(t, uni.wethToken.Address(), mgr.RemoteToken) - require.True(t, mgr.Enabled) - } - - // sanity check connections - for chainID, uni := range universes { - destChains, err := uni.liquidityManager.GetSupportedDestChains(&bind.CallOpts{Context: testutils.Context(t)}) - require.NoError(t, err, "couldn't get supported dest chains") - t.Log("num dest chains:", len(destChains), "dest chains:", destChains) - if chainID == mainChainID { - require.Len(t, destChains, len(universes)-1) - } else { - require.Len(t, destChains, 1) - } - mgrs, err := uni.liquidityManager.GetAllCrossChainRebalancers(&bind.CallOpts{ - Context: testutils.Context(t), - }) - require.NoError(t, err, "couldn't get all cross-chain liquidity managers") - t.Log("chainID:", chainID, "num neighbors:", len(mgrs)) - if chainID == mainChainID { - // should be connected to all follower chains - require.Len(t, mgrs, len(universes)-1, "unexpected number of neighbors on main chain") - } else { - // should be connected to just the main chain - require.Len(t, mgrs, 1, "unexpected number of neighbors on follower chain") - } - } -} - -func mustGetChainByEvmID(t *testing.T, chainID int64) chainsel.Chain { - ch, exists := chainsel.ChainByEvmChainID(uint64(chainID)) - require.True(t, exists) - return ch -} diff --git a/core/services/ocr2/plugins/liquiditymanager/ocr3impls/multichain_config_tracker_test.go b/core/services/ocr2/plugins/liquiditymanager/ocr3impls/multichain_config_tracker_test.go deleted file mode 100644 index 13dd88d1f2..0000000000 --- a/core/services/ocr2/plugins/liquiditymanager/ocr3impls/multichain_config_tracker_test.go +++ /dev/null @@ -1,323 +0,0 @@ -package ocr3impls_test - -import ( - "encoding/hex" - "math/big" - "strconv" - "testing" - "time" - - "github.com/jmoiron/sqlx" - chainsel "github.com/smartcontractkit/chain-selectors" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/no_op_ocr3" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" - discoverermocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/discoverer/mocks" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/graph" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/models" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/ocr3impls" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" - "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" -) - -func setupLogPoller[RI ocr3impls.MultichainMeta](t *testing.T, db *sqlx.DB, bs *keyringsAndSigners[RI]) (logpoller.LogPoller, testUniverse[RI]) { - lggr := logger.TestLogger(t) - - o := logpoller.NewORM(testutils.SimulatedChainID, db, lggr) - - // create the universe which will deploy the OCR contract and set config - // we will replay on the log poller to get the appropriate ConfigSet log - uni := newTestUniverse[RI](t, bs) - lpOpts := logpoller.Opts{ - PollPeriod: 1 * time.Second, - FinalityDepth: 100, - BackfillBatchSize: 100, - RpcBatchSize: 100, - KeepFinalizedBlocksDepth: 200, - } - headTracker := headtracker.NewSimulatedHeadTracker(uni.simClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) - if lpOpts.PollPeriod == 0 { - lpOpts.PollPeriod = 1 * time.Hour - } - lp := logpoller.NewLogPoller(o, uni.simClient, lggr, headTracker, lpOpts) - return lp, uni -} - -func TestConfigSet(t *testing.T) { - require.Equal(t, no_op_ocr3.NoOpOCR3ConfigSet{}.Topic().Hex(), ocr3impls.ConfigSet.Hex()) -} - -func TestMultichainConfigTracker_New(t *testing.T) { - t.Run("master chain not in log pollers", func(t *testing.T) { - db := pgtest.NewSqlxDB(t) - _, uni := setupLogPoller[multichainMeta](t, db, nil) - - masterChain := commontypes.RelayID{ - Network: relay.NetworkEVM, - ChainID: testutils.SimulatedChainID.String(), - } - mockDiscovererFactory := discoverermocks.NewFactory(t) - _, err := ocr3impls.NewMultichainConfigTracker( - masterChain, - logger.TestLogger(t), - map[commontypes.RelayID]logpoller.LogPoller{}, - uni.simClient, - uni.wrapper.Address(), - mockDiscovererFactory, - ocr3impls.TransmitterCombiner, - nil, - ) - require.Error(t, err, "expected error creating multichain config tracker") - }) - - t.Run("combiner is nil", func(t *testing.T) { - db := pgtest.NewSqlxDB(t) - lp, uni := setupLogPoller[multichainMeta](t, db, nil) - - masterChain := commontypes.RelayID{ - Network: relay.NetworkEVM, - ChainID: testutils.SimulatedChainID.String(), - } - mockDiscovererFactory := discoverermocks.NewFactory(t) - _, err := ocr3impls.NewMultichainConfigTracker( - masterChain, - logger.TestLogger(t), - map[commontypes.RelayID]logpoller.LogPoller{masterChain: lp}, - uni.simClient, - uni.wrapper.Address(), - mockDiscovererFactory, - nil, - nil, - ) - require.Error(t, err, "expected error creating multichain config tracker") - }) - - t.Run("factory is nil", func(t *testing.T) { - db := pgtest.NewSqlxDB(t) - lp, uni := setupLogPoller[multichainMeta](t, db, nil) - - masterChain := commontypes.RelayID{ - Network: relay.NetworkEVM, - ChainID: testutils.SimulatedChainID.String(), - } - _, err := ocr3impls.NewMultichainConfigTracker( - masterChain, - logger.TestLogger(t), - map[commontypes.RelayID]logpoller.LogPoller{masterChain: lp}, - uni.simClient, - uni.wrapper.Address(), - nil, - ocr3impls.TransmitterCombiner, - nil, - ) - require.Error(t, err, "expected error creating multichain config tracker") - }) -} - -func TestMultichainConfigTracker_SingleChain(t *testing.T) { - db := pgtest.NewSqlxDB(t) - lp, uni := setupLogPoller[multichainMeta](t, db, nil) - require.NoError(t, lp.Start(testutils.Context(t))) - t.Cleanup(func() { require.NoError(t, lp.Close()) }) - - masterChain := commontypes.RelayID{ - Network: relay.NetworkEVM, - ChainID: testutils.SimulatedChainID.String(), - } - - ch, exists := chainsel.ChainByEvmChainID(uint64(mustStrToI64(t, masterChain.ChainID))) - assert.True(t, exists) - - // for this test only one LM is "deployed" - // so the discovery will return a single LM which is the master LM - g := graph.NewGraph() - g.(graph.GraphTest).AddNetwork(models.NetworkSelector(ch.Selector), graph.Data{ - Liquidity: big.NewInt(1234), // liquidity doesn't matter for this test - LiquidityManagerAddress: models.Address(uni.wrapper.Address()), - }) - mockDiscoverer := discoverermocks.NewDiscoverer(t) - mockDiscoverer.On("Discover", mock.Anything).Return(g, nil) - defer mockDiscoverer.AssertExpectations(t) - mockDiscovererFactory := discoverermocks.NewFactory(t) - mockDiscovererFactory.On("NewDiscoverer", models.NetworkSelector(ch.Selector), models.Address(uni.wrapper.Address())). - Return(mockDiscoverer, nil) - defer mockDiscovererFactory.AssertExpectations(t) - tracker, err := ocr3impls.NewMultichainConfigTracker( - masterChain, - logger.TestLogger(t), - map[commontypes.RelayID]logpoller.LogPoller{masterChain: lp}, - uni.simClient, - uni.wrapper.Address(), - mockDiscovererFactory, - ocr3impls.TransmitterCombiner, - nil, - ) - require.NoError(t, err, "failed to create multichain config tracker") - - // Replay the log poller to get the ConfigSet log - err = tracker.ReplayChain(testutils.Context(t), masterChain, 1) - require.NoError(t, err, "failed to replay log poller") - - // fetch config digest from the tracker - changedInBlock, configDigest, err := tracker.LatestConfigDetails(testutils.Context(t)) - require.NoError(t, err, "failed to get latest config details") - c, err := uni.wrapper.LatestConfigDetails(nil) - require.NoError(t, err, "failed to get latest config digest and epoch") - require.Equal(t, hex.EncodeToString(c.ConfigDigest[:]), configDigest.Hex(), "expected latest config digest to match") - - // fetch config details from the tracker - config, err := tracker.LatestConfig(testutils.Context(t), changedInBlock) - require.NoError(t, err, "failed to get latest config") - require.Equal(t, uint64(1), config.ConfigCount, "expected config count to match") - require.Equal(t, configDigest, config.ConfigDigest, "expected config digest to match") - require.Equal(t, uint8(1), config.F, "expected f to match") - require.Equal(t, []byte{}, config.OnchainConfig, "expected onchain config to match") - require.Equal(t, []byte{}, config.OffchainConfig, "expected offchain config to match") - require.Equal(t, uint64(3), config.OffchainConfigVersion, "expected offchain config version to match") - expectedSigners := func() []ocrtypes.OnchainPublicKey { - var signers []ocrtypes.OnchainPublicKey - for _, b := range uni.keyrings { - signers = append(signers, b.PublicKey()) - } - return signers - }() - expectedTransmitters := func() []ocrtypes.Account { - var accounts []ocrtypes.Account - for _, tm := range uni.transmitters { - accounts = append(accounts, ocrtypes.Account(ocr3impls.EncodeTransmitter(masterChain, ocrtypes.Account(tm.From.Hex())))) - } - return accounts - }() - require.Equal(t, expectedSigners, config.Signers, "expected signers to match") - require.Equal(t, expectedTransmitters, config.Transmitters, "expected transmitters to match") -} - -func TestMultichainConfigTracker_Multichain(t *testing.T) { - // create heavyweight db's because the log pollers need to have separate - // databases to avoid conflicts. - _, db1 := heavyweight.FullTestDBV2(t, nil) - _, db2 := heavyweight.FullTestDBV2(t, nil) - - lp1, uni1 := setupLogPoller[multichainMeta](t, db1, nil) - lp2, uni2 := setupLogPoller[multichainMeta](t, db2, &keyringsAndSigners[multichainMeta]{ - keyrings: uni1.keyrings, - signers: uni1.signers, - }) - t.Cleanup(func() { - require.NoError(t, lp1.Close()) - require.NoError(t, lp2.Close()) - }) - - // finality depth - uni2.backend.Commit() - uni2.backend.Commit() - - // start the log pollers - require.NoError(t, lp1.Start(testutils.Context(t))) - require.NoError(t, lp2.Start(testutils.Context(t))) - - // create the multichain config tracker - // the chain id's we're using in the mappings are different from the - // simulated chain id but that should be fine for this test. - masterChain := commontypes.RelayID{ - Network: relay.NetworkEVM, - ChainID: strconv.FormatUint(chainsel.TEST_90000001.EvmChainID, 10), - } - secondChain := commontypes.RelayID{ - Network: relay.NetworkEVM, - ChainID: strconv.FormatUint(chainsel.TEST_90000002.EvmChainID, 10), - } - - chain1, exists := chainsel.ChainByEvmChainID(uint64(mustStrToI64(t, masterChain.ChainID))) - assert.True(t, exists) - - chain2, exists := chainsel.ChainByEvmChainID(uint64(mustStrToI64(t, secondChain.ChainID))) - assert.True(t, exists) - - // this test doesn't care about the connections, just the vertices themselves - g := graph.NewGraph() - g.(graph.GraphTest).AddNetwork(models.NetworkSelector(chain1.Selector), graph.Data{ - Liquidity: big.NewInt(1234), // liquidity doesn't matter for this test - LiquidityManagerAddress: models.Address(uni1.wrapper.Address()), - }) - g.(graph.GraphTest).AddNetwork(models.NetworkSelector(chain2.Selector), graph.Data{ - Liquidity: big.NewInt(1234), // liquidity doesn't matter for this test - LiquidityManagerAddress: models.Address(uni2.wrapper.Address()), - }) - mockDiscoverer := discoverermocks.NewDiscoverer(t) - mockDiscoverer.On("Discover", mock.Anything).Return(g, nil) - defer mockDiscoverer.AssertExpectations(t) - mockDiscovererFactory := discoverermocks.NewFactory(t) - mockDiscovererFactory.On("NewDiscoverer", models.NetworkSelector(chain1.Selector), models.Address(uni1.wrapper.Address())). - Return(mockDiscoverer, nil) - defer mockDiscovererFactory.AssertExpectations(t) - tracker, err := ocr3impls.NewMultichainConfigTracker( - masterChain, - logger.TestLogger(t), - map[commontypes.RelayID]logpoller.LogPoller{ - masterChain: lp1, - secondChain: lp2, - }, - uni1.simClient, - uni1.wrapper.Address(), - mockDiscovererFactory, - ocr3impls.TransmitterCombiner, - nil, // we call replay explicitly below - ) - require.NoError(t, err, "failed to create multichain config tracker") - - // Replay the log pollers to get the ConfigSet log - // on each respective chain - require.NoError(t, tracker.ReplayChain(testutils.Context(t), masterChain, 1), "failed to replay log poller on master chain") - require.NoError(t, tracker.ReplayChain(testutils.Context(t), secondChain, 1), "failed to replay log poller on second chain") - - // fetch config digest from the tracker - changedInBlock, configDigest, err := tracker.LatestConfigDetails(testutils.Context(t)) - require.NoError(t, err, "failed to get latest config details") - c, err := uni1.wrapper.LatestConfigDetails(nil) - require.NoError(t, err, "failed to get latest config digest and epoch") - require.Equal(t, hex.EncodeToString(c.ConfigDigest[:]), configDigest.Hex(), "expected latest config digest to match") - - // fetch config details from the tracker - config, err := tracker.LatestConfig(testutils.Context(t), changedInBlock) - require.NoError(t, err, "failed to get latest config") - require.Equal(t, uint64(1), config.ConfigCount, "expected config count to match") - require.Equal(t, configDigest, config.ConfigDigest, "expected config digest to match") - require.Equal(t, uint8(1), config.F, "expected f to match") - require.Equal(t, []byte{}, config.OnchainConfig, "expected onchain config to match") - require.Equal(t, []byte{}, config.OffchainConfig, "expected offchain config to match") - require.Equal(t, uint64(3), config.OffchainConfigVersion, "expected offchain config version to match") - expectedSigners := func() []ocrtypes.OnchainPublicKey { - var signers []ocrtypes.OnchainPublicKey - for _, b := range uni1.keyrings { - signers = append(signers, b.PublicKey()) - } - return signers - }() - require.Equal(t, expectedSigners, config.Signers, "expected signers to match") - expectedTransmitters := func() []ocrtypes.Account { - var accounts []ocrtypes.Account - for i := range uni1.transmitters { - t1 := ocr3impls.EncodeTransmitter(masterChain, ocrtypes.Account(uni1.transmitters[i].From.Hex())) - t2 := ocr3impls.EncodeTransmitter(secondChain, ocrtypes.Account(uni2.transmitters[i].From.Hex())) - accounts = append(accounts, ocrtypes.Account(ocr3impls.JoinTransmitters([]string{t1, t2}))) - } - return accounts - }() - require.Equal(t, expectedTransmitters, config.Transmitters, "expected transmitters to match") -} - -func mustStrToI64(t *testing.T, s string) int64 { - i, err := strconv.ParseInt(s, 10, 64) - require.NoError(t, err) - return i -} diff --git a/go.mod b/go.mod index 783b28e5a2..3aa0a7be64 100644 --- a/go.mod +++ b/go.mod @@ -11,8 +11,8 @@ require ( github.com/XSAM/otelsql v0.27.0 github.com/avast/retry-go/v4 v4.6.0 github.com/btcsuite/btcd/btcec/v2 v2.3.2 - github.com/cometbft/cometbft v0.37.5 - github.com/cosmos/cosmos-sdk v0.47.11 + github.com/cometbft/cometbft v0.37.2 + github.com/cosmos/cosmos-sdk v0.47.4 github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e github.com/deckarep/golang-set/v2 v2.6.0 github.com/dominikbraun/graph v0.23.0 @@ -21,7 +21,7 @@ require ( github.com/fatih/color v1.16.0 github.com/fxamacker/cbor/v2 v2.5.0 github.com/gagliardetto/solana-go v1.8.4 - github.com/getsentry/sentry-go v0.23.0 + github.com/getsentry/sentry-go v0.19.0 github.com/gin-contrib/cors v1.5.0 github.com/gin-contrib/expvar v0.0.1 github.com/gin-contrib/sessions v0.0.5 @@ -68,18 +68,18 @@ require ( github.com/prometheus/prometheus v0.48.1 github.com/robfig/cron/v3 v3.0.1 github.com/rogpeppe/go-internal v1.12.0 - github.com/rs/zerolog v1.32.0 + github.com/rs/zerolog v1.30.0 github.com/scylladb/go-reflectx v1.0.1 github.com/shirou/gopsutil/v3 v3.24.3 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc - github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 @@ -102,15 +102,15 @@ require ( go.opentelemetry.io/otel v1.28.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.25.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - golang.org/x/mod v0.19.0 - golang.org/x/net v0.27.0 - golang.org/x/sync v0.7.0 - golang.org/x/term v0.22.0 - golang.org/x/text v0.16.0 + golang.org/x/crypto v0.26.0 + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa + golang.org/x/mod v0.20.0 + golang.org/x/net v0.28.0 + golang.org/x/sync v0.8.0 + golang.org/x/term v0.23.0 + golang.org/x/text v0.17.0 golang.org/x/time v0.5.0 - golang.org/x/tools v0.23.0 + golang.org/x/tools v0.24.0 gonum.org/v1/gonum v0.15.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 @@ -120,27 +120,22 @@ require ( ) require ( - github.com/bahlo/generic-list-go v0.2.0 // indirect - github.com/buger/jsonparser v1.1.1 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect - github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/sourcegraph/conc v0.3.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) - -require ( + cloud.google.com/go/auth v0.7.1 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect + cloud.google.com/go/compute/metadata v0.5.0 // indirect + cloud.google.com/go/iam v1.1.11 // indirect + cloud.google.com/go/storage v1.43.0 // indirect contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect - cosmossdk.io/depinject v1.0.0-alpha.4 // indirect - cosmossdk.io/errors v1.0.1 // indirect - cosmossdk.io/math v1.3.0 // indirect + cosmossdk.io/depinject v1.0.0-alpha.3 // indirect + cosmossdk.io/errors v1.0.0 // indirect + cosmossdk.io/math v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect - github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect + github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect github.com/CosmWasm/wasmd v0.40.1 // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect @@ -148,11 +143,13 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/blendle/zapdriver v1.3.1 // indirect + github.com/buger/jsonparser v1.1.1 // indirect github.com/bytedance/sonic v1.10.1 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -160,23 +157,23 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect - github.com/cockroachdb/errors v1.10.0 // indirect + github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect - github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/redact v1.1.3 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft-db v0.8.0 // indirect + github.com/cometbft/cometbft-db v0.7.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.11 // indirect - github.com/cosmos/iavl v0.20.1 // indirect - github.com/cosmos/ibc-go/v7 v7.5.1 // indirect - github.com/cosmos/ics23/go v0.10.0 // indirect - github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect + github.com/cosmos/iavl v0.20.0 // indirect + github.com/cosmos/ibc-go/v7 v7.0.1 // indirect + github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect + github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect @@ -191,7 +188,8 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect @@ -225,12 +223,12 @@ require ( github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/gorilla/context v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect @@ -257,15 +255,15 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.3 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect @@ -295,16 +293,18 @@ require ( github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.18.2 // indirect + github.com/spf13/viper v1.15.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/subosito/gotenv v1.6.0 // indirect + github.com/subosito/gotenv v1.4.2 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect + github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect github.com/tidwall/btree v1.6.0 // indirect @@ -318,13 +318,14 @@ require ( github.com/valyala/fastjson v1.4.1 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zondax/hid v0.9.2 // indirect - github.com/zondax/ledger-go v0.14.3 // indirect + github.com/zondax/hid v0.9.1 // indirect + github.com/zondax/ledger-go v0.14.1 // indirect go.dedis.ch/protobuf v1.0.11 // indirect go.etcd.io/bbolt v1.3.7 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect @@ -332,15 +333,17 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/ratelimit v0.3.0 // indirect - golang.org/x/arch v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + google.golang.org/api v0.188.0 // indirect + google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect gopkg.in/guregu/null.v2 v2.1.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - pgregory.net/rapid v1.1.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + pgregory.net/rapid v0.5.5 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 081c0a2aee..770fc187f6 100644 --- a/go.sum +++ b/go.sum @@ -4,33 +4,51 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= -cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= +cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= +cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= +cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= +cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= +cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= +cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw= +cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= -cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= +cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo= @@ -39,14 +57,14 @@ cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= -cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= -cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= -cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= -cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= -cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= -cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= -cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= -cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= +cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= +cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= +cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= +cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= +cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca h1:msenprh2BLLRwNT7zN56TbBHOGk/7ARQckXHxXyvjoQ= +cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c= +cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= +cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -59,6 +77,7 @@ github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo8 github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= @@ -66,8 +85,10 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzS github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= -github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= github.com/CosmWasm/wasmd v0.40.1/go.mod h1:6EOwnv7MpuFaEqxcUOdFV9i4yvrdOciaY6VQ1o7A3yg= github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= @@ -79,6 +100,7 @@ github.com/Depado/ginprom v1.8.0 h1:zaaibRLNI1dMiiuj1MKzatm8qrcHzikMlCc1anqOdyo= github.com/Depado/ginprom v1.8.0/go.mod h1:XBaKzeNBqPF4vxJpNLincSQZeMDnZp1tIbU0FU0UKgg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= @@ -98,13 +120,17 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= +github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= +github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -130,6 +156,7 @@ github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -192,29 +219,35 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= +github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= +github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.10.0 h1:lfxS8zZz1+OjtV4MtNWgboi/W5tyLEB6VQZBXN+0VUU= -github.com/cockroachdb/errors v1.10.0/go.mod h1:lknhIsEVQ9Ss/qKDBQS/UqFSvPQjOwNq2qyKAxtHRqE= +github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= +github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= -github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= -github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= -github.com/cometbft/cometbft v0.37.5 h1:/U/TlgMh4NdnXNo+YU9T2NMCWyhXNDF34Mx582jlvq0= -github.com/cometbft/cometbft v0.37.5/go.mod h1:QC+mU0lBhKn8r9qvmnq53Dmf3DWBt4VtkcKw2C81wxY= -github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= -github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0= +github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= +github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= +github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= +github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -235,10 +268,10 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= -github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= -github.com/cosmos/cosmos-sdk v0.47.11 h1:0Qx7eORw0RJqPv+mvDuU8NQ1LV3nJJKJnPoYblWHolc= -github.com/cosmos/cosmos-sdk v0.47.11/go.mod h1:ADjORYzUQqQv/FxDi0H0K5gW/rAk1CiDR3ZKsExfJV0= +github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= +github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= +github.com/cosmos/cosmos-sdk v0.47.4 h1:FVUpEprm58nMmBX4xkRdMDaIG5Nr4yy92HZAfGAw9bg= +github.com/cosmos/cosmos-sdk v0.47.4/go.mod h1:R5n+uM7vguVPFap4pgkdvQCT1nVo/OtPwrlAU40rvok= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -246,14 +279,14 @@ github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiK github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v0.20.1 h1:rM1kqeG3/HBT85vsZdoSNsehciqUQPWrR4BYmqE2+zg= -github.com/cosmos/iavl v0.20.1/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= -github.com/cosmos/ibc-go/v7 v7.5.1 h1:KqS/g7W7EMX1OtOvufS8lWMJibOKpdgtNNZIU6fAgVU= -github.com/cosmos/ibc-go/v7 v7.5.1/go.mod h1:ktFg5GvKOyrGCqTWtW7Grj5uweU4ZapxrNeVS1CLLbo= -github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= -github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= -github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw= -github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M= +github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= +github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/ibc-go/v7 v7.0.1 h1:NIBNRWjlOoFvFQu1ZlgwkaSeHO5avf4C1YQiWegt8jw= +github.com/cosmos/ibc-go/v7 v7.0.1/go.mod h1:vEaapV6nuLPQlS+g8IKmxMo6auPi0i7HMv1PhViht/E= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= +github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= +github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -269,6 +302,10 @@ github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJF github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= +github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= +github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -289,6 +326,7 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFM github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70/go.mod h1:EoK/8RFbMEteaCaz89uessDTnCWjbbcr+DXcBh4el5o= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= @@ -312,22 +350,34 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo= github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/esote/minmaxheap v1.0.0 h1:rgA7StnXXpZG6qlM0S7pUmEv1KpWe32rYT4x8J8ntaA= github.com/esote/minmaxheap v1.0.0/go.mod h1:Ln8+i7fS1k3PLgZI2JAo0iA1as95QnIYiGCrqSJ5FZk= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= github.com/ethereum/go-ethereum v1.13.8/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -339,8 +389,8 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE= github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= @@ -353,14 +403,16 @@ github.com/gagliardetto/solana-go v1.8.4 h1:vmD/JmTlonyXGy39bAo0inMhmbdAwV7rXZtL github.com/gagliardetto/solana-go v1.8.4/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM= -github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE= -github.com/getsentry/sentry-go v0.23.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/getsentry/sentry-go v0.19.0 h1:BcCH3CN5tXt5aML+gwmbFwVptLLQA+eT866fCO9wVOM= +github.com/getsentry/sentry-go v0.19.0/go.mod h1:y3+lGEFEFexZtpbG1GUE2WD/f9zGyKYwpEqryTOC/nE= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= @@ -379,6 +431,8 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -405,6 +459,7 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -429,6 +484,9 @@ github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6l github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= @@ -440,8 +498,12 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= @@ -459,7 +521,9 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -467,6 +531,7 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -486,6 +551,7 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -494,14 +560,18 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= @@ -509,6 +579,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -516,6 +588,11 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= @@ -533,8 +610,9 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA= +github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -547,13 +625,14 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= @@ -569,8 +648,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= @@ -613,6 +692,7 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= @@ -649,11 +729,13 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -661,6 +743,11 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -736,19 +823,29 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -762,6 +859,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= @@ -775,8 +874,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= -github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= @@ -792,9 +889,12 @@ github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9 github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -802,11 +902,11 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -815,11 +915,14 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= @@ -856,11 +959,16 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -878,6 +986,7 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -923,6 +1032,7 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -962,6 +1072,8 @@ github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= +github.com/regen-network/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= @@ -976,6 +1088,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= @@ -985,25 +1098,24 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= -github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= +github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= -github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= -github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= @@ -1027,18 +1139,18 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc h1:8267l5X5oF2JnGsDaEG4i0JSQO9o0eC61SscTfWc1bk= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= -github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa/go.mod h1:wZvLHX/Sd9hskN51016cTFcT3G62KXVa6xbVDS7tRjc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= @@ -1056,14 +1168,12 @@ github.com/smartcontractkit/wsrpc v0.7.3/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgq github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= -github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= +github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= @@ -1073,14 +1183,16 @@ github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= +github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= @@ -1107,12 +1219,14 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= -github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= @@ -1143,8 +1257,10 @@ github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2 github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= @@ -1162,10 +1278,14 @@ github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE= github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -1173,23 +1293,31 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= -github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= -github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= +github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= +github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= +github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= @@ -1217,10 +1345,10 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/contrib/propagators/b3 v1.24.0 h1:n4xwCdTx3pZqZs2CjS/CUZAs03y3dZcGhC/FepKtEUY= go.opentelemetry.io/contrib/propagators/b3 v1.24.0/go.mod h1:k5wRxKRU2uXx2F8uNJ4TaonuEO/V7/5xoz7kdsDACT8= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= @@ -1233,8 +1361,8 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= -go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= +go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= +go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -1269,8 +1397,8 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= -golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1279,22 +1407,27 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1305,8 +1438,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1320,6 +1453,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1328,11 +1462,13 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1343,30 +1479,44 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -1374,15 +1524,19 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= -golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1390,12 +1544,14 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1433,30 +1589,45 @@ golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1465,8 +1636,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1475,8 +1646,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1490,19 +1661,22 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1535,16 +1709,33 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1564,16 +1755,27 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= -google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= +google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1593,18 +1795,37 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= +google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1617,9 +1838,15 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1630,6 +1857,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -1653,8 +1881,10 @@ gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1670,19 +1900,21 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= @@ -1703,8 +1935,8 @@ modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= -pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= +pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index 04767c842e..adc214f847 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -490,7 +490,8 @@ func DeployForwarderContracts( operatorFactoryInstance = &instance for i := 0; i < numberOfOperatorForwarderPairs; i++ { - decodedTx, err := seth.Decode(operatorFactoryInstance.DeployNewOperatorAndForwarder()) + tx, deployErr := operatorFactoryInstance.DeployNewOperatorAndForwarder() + decodedTx, err := seth.Decode(tx, deployErr) require.NoError(t, err, "Deploying new operator with proposed ownership with forwarder shouldn't fail") for i, event := range decodedTx.Events { diff --git a/integration-tests/ccip-tests/contracts/contract_deployer.go b/integration-tests/ccip-tests/contracts/contract_deployer.go index bc797ad5da..c051531fb9 100644 --- a/integration-tests/ccip-tests/contracts/contract_deployer.go +++ b/integration-tests/ccip-tests/contracts/contract_deployer.go @@ -1399,7 +1399,8 @@ func NewCommitOffchainConfig( ExecGasPriceDeviationPPB uint32, TokenPriceHeartBeat config.Duration, TokenPriceDeviationPPB uint32, - InflightCacheExpiry config.Duration) (ccipconfig.OffchainConfig, error) { + InflightCacheExpiry config.Duration, + priceReportingDisabled bool) (ccipconfig.OffchainConfig, error) { switch VersionMap[CommitStoreContract] { case Latest: return testhelpers.NewCommitOffchainConfig( @@ -1409,6 +1410,7 @@ func NewCommitOffchainConfig( TokenPriceHeartBeat, TokenPriceDeviationPPB, InflightCacheExpiry, + priceReportingDisabled, ), nil case V1_2_0: return testhelpers_1_4_0.NewCommitOffchainConfig( @@ -1418,6 +1420,7 @@ func NewCommitOffchainConfig( TokenPriceHeartBeat, TokenPriceDeviationPPB, InflightCacheExpiry, + priceReportingDisabled, ), nil default: return nil, fmt.Errorf("version not supported: %s", VersionMap[CommitStoreContract]) diff --git a/integration-tests/ccip-tests/testsetups/lm_setup.go b/integration-tests/ccip-tests/testsetups/lm_setup.go deleted file mode 100644 index 9884d9661c..0000000000 --- a/integration-tests/ccip-tests/testsetups/lm_setup.go +++ /dev/null @@ -1,845 +0,0 @@ -package testsetups - -import ( - "context" - "crypto/ed25519" - "encoding/hex" - "fmt" - "math/big" - "os" - "strconv" - "strings" - "testing" - "time" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/erc20" - - ocrconfighelper2 "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2/types" - "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - "golang.org/x/crypto/curve25519" - - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" - - "github.com/ethereum/go-ethereum/common" - "github.com/lib/pq" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/liquiditymanager" - - "github.com/AlekSi/pointer" - "github.com/pkg/errors" - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" - chainselectors "github.com/smartcontractkit/chain-selectors" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - "golang.org/x/sync/errgroup" - - integrationactions "github.com/smartcontractkit/chainlink/integration-tests/actions" - - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/config" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" - - "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" - "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" - - integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/liquiditymanager/testhelpers/integration" -) - -type LMTestSetupOutputs struct { - CCIPTestSetUpOutputs - LMModules map[int64]*actions.LMCommon -} - -// TODO - Copied over from ccip tests as such. Refactor and remove unused code -func (o *LMTestSetupOutputs) CreateLMEnvironment( - lggr *zerolog.Logger, - envName string, - reportPath string, -) map[int64]blockchain.EVMClient { - t := o.Cfg.Test - testConfig := o.Cfg - var ( - ccipEnv *actions.CCIPTestEnv - k8Env *environment.Environment - err error - chains []blockchain.EVMClient - local *test_env.CLClusterTestEnv - deployCL func() error - ) - - envConfig := createEnvironmentConfig(t, envName, testConfig, reportPath) - - configureCLNode := !testConfig.useExistingDeployment() || pointer.GetString(testConfig.EnvInput.EnvToConnect) != "" - namespace := "" - if testConfig.TestGroupInput.LoadProfile != nil { - namespace = testConfig.TestGroupInput.LoadProfile.TestRunName - } - require.False(t, testConfig.localCluster() && testConfig.ExistingCLCluster(), - "local cluster and existing cluster cannot be true at the same time") - // if it's a new deployment, deploy the env - // Or if EnvToConnect is given connect to that k8 environment - if configureCLNode { - if !testConfig.ExistingCLCluster() { - // if it's a local cluster, deploy the local cluster in docker - if testConfig.localCluster() { - local, deployCL = DeployLocalCluster(t, testConfig) - ccipEnv = &actions.CCIPTestEnv{ - LocalCluster: local, - } - namespace = "local-docker-deployment" - } else { - // Otherwise, deploy the k8s env - lggr.Info().Msg("Deploying test environment") - // deploy the env if configureCLNode is true - k8Env = DeployEnvironments(t, envConfig, testConfig) - ccipEnv = &actions.CCIPTestEnv{K8Env: k8Env} - namespace = ccipEnv.K8Env.Cfg.Namespace - } - } else { - // if there is already a cluster, use the existing cluster to connect to the nodes - ccipEnv = &actions.CCIPTestEnv{} - mockserverURL := pointer.GetString(testConfig.EnvInput.Mockserver) - require.NotEmpty(t, mockserverURL, "mockserver URL cannot be nil") - ccipEnv.MockServer = ctfClient.NewMockserverClient(&ctfClient.MockserverConfig{ - LocalURL: mockserverURL, - ClusterURL: mockserverURL, - }) - } - ccipEnv.CLNodeWithKeyReady, _ = errgroup.WithContext(o.SetUpContext) - o.Env = ccipEnv - if ccipEnv.K8Env != nil && ccipEnv.K8Env.WillUseRemoteRunner() { - return nil - } - } else { - // if configureCLNode is false it means we don't need to deploy any additional pods, - // use a placeholder env to create just the remote runner in it. - if value, set := os.LookupEnv(config.EnvVarJobImage); set && value != "" { - k8Env = environment.New(envConfig) - err = k8Env.Run() - require.NoErrorf(t, err, "error creating environment remote runner") - o.Env = &actions.CCIPTestEnv{K8Env: k8Env} - if k8Env.WillUseRemoteRunner() { - return nil - } - } - } - chainByChainID := make(map[int64]blockchain.EVMClient) - if pointer.GetBool(testConfig.TestGroupInput.LocalCluster) { - require.NotNil(t, ccipEnv.LocalCluster, "Local cluster shouldn't be nil") - for _, n := range ccipEnv.LocalCluster.EVMNetworks { - if evmClient, err := blockchain.NewEVMClientFromNetwork(*n, *lggr); err == nil { - chainByChainID[evmClient.GetChainID().Int64()] = evmClient - chains = append(chains, evmClient) - } else { - lggr.Error().Err(err).Msgf("EVMClient for chainID %d not found", n.ChainID) - } - } - } else { - for _, n := range testConfig.SelectedNetworks { - if _, ok := chainByChainID[n.ChainID]; ok { - continue - } - var ec blockchain.EVMClient - if k8Env == nil { - ec, err = blockchain.ConnectEVMClient(n, *lggr) - } else { - log.Info().Interface("urls", k8Env.URLs).Msg("URLs") - ec, err = blockchain.NewEVMClient(n, k8Env, *lggr) - } - require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail") - chains = append(chains, ec) - chainByChainID[n.ChainID] = ec - } - } - if configureCLNode { - ccipEnv.CLNodeWithKeyReady.Go(func() error { - var totalNodes int - if !o.Cfg.ExistingCLCluster() { - if ccipEnv.LocalCluster != nil { - err = deployCL() - if err != nil { - return err - } - } - err = ccipEnv.ConnectToDeployedNodes() - if err != nil { - return fmt.Errorf("error connecting to chainlink nodes: %w", err) - } - totalNodes = pointer.GetInt(testConfig.EnvInput.NewCLCluster.NoOfNodes) - } else { - totalNodes = pointer.GetInt(testConfig.EnvInput.ExistingCLCluster.NoOfNodes) - err = ccipEnv.ConnectToExistingNodes(o.Cfg.EnvInput) - if err != nil { - return fmt.Errorf("error deploying and connecting to chainlink nodes: %w", err) - } - } - err = ccipEnv.SetUpNodeKeysAndFund(lggr, big.NewFloat(testConfig.TestGroupInput.NodeFunding), chains) - if err != nil { - return fmt.Errorf("error setting up nodes and keys %w", err) - } - // first node is the bootstrapper - ccipEnv.CommitNodeStartIndex = 1 - ccipEnv.ExecNodeStartIndex = 1 - ccipEnv.NumOfCommitNodes = testConfig.TestGroupInput.NoOfCommitNodes - ccipEnv.NumOfExecNodes = ccipEnv.NumOfCommitNodes - if !pointer.GetBool(testConfig.TestGroupInput.CommitAndExecuteOnSameDON) { - if len(ccipEnv.CLNodesWithKeys) < 11 { - return fmt.Errorf("not enough CL nodes for separate commit and execution nodes") - } - if testConfig.TestGroupInput.NoOfCommitNodes >= totalNodes { - return fmt.Errorf("number of commit nodes can not be greater than total number of nodes in DON") - } - // first two nodes are reserved for bootstrap commit and bootstrap exec - ccipEnv.CommitNodeStartIndex = 2 - ccipEnv.ExecNodeStartIndex = 2 + testConfig.TestGroupInput.NoOfCommitNodes - ccipEnv.NumOfExecNodes = totalNodes - (2 + testConfig.TestGroupInput.NoOfCommitNodes) - if ccipEnv.NumOfExecNodes < 4 { - return fmt.Errorf("insufficient number of exec nodes") - } - } - ccipEnv.NumOfAllowedFaultyExec = (ccipEnv.NumOfExecNodes - 1) / 3 - ccipEnv.NumOfAllowedFaultyCommit = (ccipEnv.NumOfCommitNodes - 1) / 3 - return nil - }) - } - - t.Cleanup(func() { - if configureCLNode { - if ccipEnv.LocalCluster != nil { - err := ccipEnv.LocalCluster.Terminate() - require.NoError(t, err, "Local cluster termination shouldn't fail") - //require.NoError(t, o.Reporter.SendReport(t, namespace, false), "Aggregating and sending report shouldn't fail") - return - } - if pointer.GetBool(testConfig.TestGroupInput.KeepEnvAlive) || testConfig.ExistingCLCluster() { - //require.NoError(t, o.Reporter.SendReport(t, namespace, true), "Aggregating and sending report shouldn't fail") - return - } - lggr.Info().Msg("Tearing down the environment") - err = integrationactions.TeardownSuite(t, nil, ccipEnv.K8Env, ccipEnv.CLNodes, o.Reporter, zapcore.DPanicLevel, o.Cfg.EnvInput) - require.NoError(t, err, "Environment teardown shouldn't fail") - } else { - //just send the report - require.NoError(t, o.Reporter.SendReport(t, namespace, true), "Aggregating and sending report shouldn't fail") - } - }) - return chainByChainID -} - -func (o *LMTestSetupOutputs) DeployLMChainContracts( - lggr *zerolog.Logger, - networkCfg blockchain.EVMNetwork, - lmCommon actions.LMCommon, - l2ChainID int64, -) error { - var k8Env *environment.Environment - ccipEnv := o.Env - chainClient := lmCommon.ChainClient - if ccipEnv != nil { - k8Env = ccipEnv.K8Env - } - if k8Env != nil && chainClient.NetworkSimulated() { - networkCfg.URLs = k8Env.URLs[chainClient.GetNetworkConfig().Name] - } - - chain, err := blockchain.ConcurrentEVMClient(networkCfg, k8Env, chainClient, *lggr) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to create chain client for %s: %w", networkCfg.Name, err)) - } - - chain.ParallelTransactions(true) - //defer chain.Close() - - cd, err := contracts.NewCCIPContractsDeployer(lggr, chain) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to create contract deployer: %w", err)) - } - - // Deploy Wrapped Native contract only on private geth networks - if lmCommon.ChainSelectror == chainselectors.GETH_TESTNET.Selector || - lmCommon.ChainSelectror == chainselectors.GETH_DEVNET_2.Selector { - lggr.Info().Msg("Deploying Wrapped Native contract") - wrapperNative, err := cd.DeployWrappedNative() - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deploy Wrapped Native contract: %w", err)) - } - lggr.Info().Str("Address", wrapperNative.String()).Msg("Deployed Wrapped Native contract") - lmCommon.WrapperNative = wrapperNative - } - - // Deploy Bridge Adapter contracts - switch lmCommon.ChainSelectror { - case chainselectors.GETH_TESTNET.Selector: - lggr.Info().Msg("Deploying Mock L1 Bridge Adapter contract") - bridgeAdapter, err := cd.DeployMockL1BridgeAdapter(*lmCommon.WrapperNative, true) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deploy Mock L1 Bridge Adapter contract: %w", err)) - } - lggr.Info().Str("Address", bridgeAdapter.EthAddress.String()).Msg("Deployed Mock L1 Bridge Adapter contract") - lmCommon.BridgeAdapterAddr = bridgeAdapter.EthAddress - case chainselectors.GETH_DEVNET_2.Selector: - lggr.Info().Msg("Deploying Mock L2 Bridge Adapter contract") - bridgeAdapter, err := cd.DeployMockL2BridgeAdapter() - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deploy Mock L2 Bridge Adapter contract: %w", err)) - } - lggr.Info().Str("Address", bridgeAdapter.EthAddress.String()).Msg("Deployed Mock L2 Bridge Adapter contract") - lmCommon.BridgeAdapterAddr = bridgeAdapter.EthAddress - case chainselectors.ETHEREUM_TESTNET_SEPOLIA.Selector: - if l2ChainID == int64(chainselectors.ETHEREUM_TESTNET_SEPOLIA_ARBITRUM_1.EvmChainID) { - wethAddress := common.HexToAddress("0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9") - lmCommon.WrapperNative = &wethAddress - lggr.Info().Msg("Deploying Arbitrum L1 Bridge Adapter contract") - bridgeAdapter, err := cd.DeployArbitrumL1BridgeAdapter( - common.HexToAddress("0xcE18836b233C83325Cc8848CA4487e94C6288264"), - common.HexToAddress("0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F"), - ) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deploy Arbitrum L1 Bridge Adapter contract: %w", err)) - } - lggr.Info().Str("Address", bridgeAdapter.EthAddress.String()).Msg("Deployed Arbitrum L1 Bridge Adapter contract") - lmCommon.BridgeAdapterAddr = bridgeAdapter.EthAddress - } - if l2ChainID == int64(chainselectors.ETHEREUM_TESTNET_SEPOLIA_OPTIMISM_1.EvmChainID) { - wethAddress := common.HexToAddress("0x7b79995e5f793a07bc00c21412e50ecae098e7f9") - lmCommon.WrapperNative = &wethAddress - lggr.Info().Msg("Deploying Optimism L1 Bridge Adapter contract") - bridgeAdapter, err := cd.DeployOptimismL1BridgeAdapter( - common.HexToAddress("0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1"), - *lmCommon.WrapperNative, - common.HexToAddress("0x16Fc5058F25648194471939df75CF27A2fdC48BC"), - ) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deploy Optimism L1 Bridge Adapter contract: %w", err)) - } - lggr.Info().Str("Address", bridgeAdapter.EthAddress.String()).Msg("Deployed Optimism L1 Bridge Adapter contract") - lmCommon.BridgeAdapterAddr = bridgeAdapter.EthAddress - } - case chainselectors.ETHEREUM_TESTNET_SEPOLIA_ARBITRUM_1.Selector: - wethAddress := common.HexToAddress("0x980B62Da83eFf3D4576C647993b0c1D7faf17c73") - lmCommon.WrapperNative = &wethAddress - lggr.Info().Msg("Deploying Arbitrum L2 Bridge Adapter contract") - bridgeAdapter, err := cd.DeployArbitrumL2BridgeAdapter(common.HexToAddress("0x9fDD1C4E4AA24EEc1d913FABea925594a20d43C7")) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deploy Arbitrum L2 Bridge Adapter contract: %w", err)) - } - lggr.Info().Str("Address", bridgeAdapter.EthAddress.String()).Msg("Deployed Arbitrum L2 Bridge Adapter contract") - lmCommon.BridgeAdapterAddr = bridgeAdapter.EthAddress - case chainselectors.ETHEREUM_TESTNET_SEPOLIA_OPTIMISM_1.Selector: - wethAddress := common.HexToAddress("0x4200000000000000000000000000000000000006") - lmCommon.WrapperNative = &wethAddress - lggr.Info().Msg("Deploying Optimism L2 Bridge Adapter contract") - bridgeAdapter, err := cd.DeployOptimismL2BridgeAdapter(*lmCommon.WrapperNative) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deploy Optimism L2 Bridge Adapter contract: %w", err)) - } - lggr.Info().Str("Address", bridgeAdapter.EthAddress.String()).Msg("Deployed Optimism L2 Bridge Adapter contract") - lmCommon.BridgeAdapterAddr = bridgeAdapter.EthAddress - } - - // Deploy Mock ARM contract - lggr.Info().Msg("Deploying Mock ARM contract") - mockRMNContract, err := cd.DeployMockRMNContract() - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deploy Mock ARM contract: %w", err)) - } - lggr.Info().Str("Address", mockRMNContract.String()).Msg("Deployed Mock ARM contract") - lmCommon.MockArm = mockRMNContract - - // Deploy ARM Proxy contract - lggr.Info().Msg("Deploying ARM Proxy contract") - RMNProxyContract, err := cd.DeployArmProxy(*mockRMNContract) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deploy ARM Proxy contract: %w", err)) - } - lggr.Info().Str("Address", RMNProxyContract.EthAddress.String()).Msg("Deployed ARM Proxy contract") - lmCommon.ArmProxy = RMNProxyContract - - // Deploy CCIP Router contract - lggr.Info().Msg("Deploying CCIP Router contract") - ccipRouterContract, err := cd.DeployRouter(common.Address{}, *lmCommon.ArmProxy.EthAddress) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deploy CCIP Router contract: %w", err)) - } - lggr.Info().Str("Address", ccipRouterContract.EthAddress.String()).Msg("Deployed CCIP Router contract") - lmCommon.CcipRouter = ccipRouterContract - - // Deploy Lock Release Token contract - lggr.Info().Msg("Deploying Lock Release Token contract") - lockReleaseTokenPool, err := cd.DeployLockReleaseTokenPoolContract(lmCommon.WrapperNative.String(), *lmCommon.MockArm, lmCommon.CcipRouter.EthAddress) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deploy Lock Release Token contract: %w", err)) - } - lggr.Info().Str("Address", lockReleaseTokenPool.EthAddress.String()).Msg("Deployed Lock Release Token contract") - lmCommon.TokenPool = lockReleaseTokenPool - - // Deploy Liquidity Manager contract - lggr.Info().Msg("Deploying Liquidity Manager contract") - liquidityManager, err := cd.DeployLiquidityManager(*lmCommon.WrapperNative, lmCommon.ChainSelectror, lmCommon.TokenPool.EthAddress, lmCommon.MinimumLiquidity) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deploy Liquidity Manager contract: %w", err)) - } - lggr.Info().Str("Address", liquidityManager.EthAddress.String()).Msg("Deployed Liquidity Manager contract") - lmCommon.LM = liquidityManager - - // Set Liquidity Manager on Token Pool - lggr.Info().Msg("Setting Liquidity Manager on Token Pool") - err = lockReleaseTokenPool.SetRebalancer(*liquidityManager.EthAddress) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to set Liquidity Manager on Token Pool: %w", err)) - } - lggr.Info().Msg("Set Liquidity Manager on Token Pool") - - err = chain.WaitForEvents() - if err != nil { - return errors.WithStack(fmt.Errorf("failed to wait for events: %w", err)) - } - - // Verify on chain rebalancer from token pool matches deployed Liquidity Manager - onchainRebalancer, err := lockReleaseTokenPool.GetRebalancer() - if err != nil { - return errors.WithStack(fmt.Errorf("failed to get rebalancer from Token Pool: %w", err)) - } - if onchainRebalancer != *liquidityManager.EthAddress { - return errors.WithStack(fmt.Errorf("onchainRebalancer doesn not match the deployed Liquidity Manager")) - } - - lggr.Debug().Interface("lmCommon", lmCommon).Msg("lmCommon") - o.LMModules[chainClient.GetChainID().Int64()] = &lmCommon - - return nil -} - -func stripKeyPrefix(key string) string { - chunks := strings.Split(key, "_") - if len(chunks) == 3 { - return chunks[2] - } - return key -} - -func (o *LMTestSetupOutputs) SetOCR3Config(chainId int64) error { - clNodesWithKeys := o.Env.CLNodesWithKeys[strconv.FormatInt(chainId, 10)] - donNodes := clNodesWithKeys[1:] - oracleIdentities := make([]ocrconfighelper2.OracleIdentityExtra, 0) - var onChainKeys []ocrtypes2.OnchainPublicKey - var transmitters []common.Address - var schedule []int - - for i, nodeWithKeys := range donNodes { - ocr2Key := nodeWithKeys.KeysBundle.OCR2Key.Data - offChainPubKeyTemp, err := hex.DecodeString(stripKeyPrefix(ocr2Key.Attributes.OffChainPublicKey)) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to decode offchain public key: %w", err)) - } - formattedOnChainPubKey := stripKeyPrefix(ocr2Key.Attributes.OnChainPublicKey) - cfgPubKeyTemp, err := hex.DecodeString(stripKeyPrefix(ocr2Key.Attributes.ConfigPublicKey)) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to decode config public key: %w", err)) - } - cfgPubKeyBytes := [ed25519.PublicKeySize]byte{} - copy(cfgPubKeyBytes[:], cfgPubKeyTemp) - offChainPubKey := [curve25519.PointSize]byte{} - copy(offChainPubKey[:], offChainPubKeyTemp) - ethAddress := nodeWithKeys.KeysBundle.EthAddress - p2pKeys := nodeWithKeys.KeysBundle.P2PKeys - peerID := p2pKeys.Data[0].Attributes.PeerID - oracleIdentities = append(oracleIdentities, ocrconfighelper2.OracleIdentityExtra{ - OracleIdentity: ocrconfighelper2.OracleIdentity{ - OffchainPublicKey: offChainPubKey, - OnchainPublicKey: common.HexToAddress(formattedOnChainPubKey).Bytes(), - PeerID: peerID, - TransmitAccount: ocrtypes2.Account(ethAddress), - }, - ConfigEncryptionPublicKey: cfgPubKeyBytes, - }) - onChainKeys = append(onChainKeys, oracleIdentities[i].OnchainPublicKey) - transmitters = append(transmitters, common.HexToAddress(ethAddress)) - schedule = append(schedule, 1) - - } - signers, err := evm.OnchainPublicKeyToAddress(onChainKeys) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to convert onchain public keys to addresses: %w", err)) - } - - offchainConfig, onchainConfig := []byte{}, []byte{} - f := uint8(1) - _, _, f, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( - 2*time.Minute, - 2*time.Minute, - 20*time.Second, - 2*time.Second, - 20*time.Second, - 10*time.Second, - 40*time.Second, - 3, - schedule, - oracleIdentities, - offchainConfig, - 50*time.Millisecond, - 1*time.Minute, - 1*time.Minute, - 1*time.Second, - int(f), - onchainConfig, - ) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to set OCR3 config args for tests: %w", err)) - } - err = o.LMModules[chainId].LM.SetOCR3Config(signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to set OCR3 config: %w", err)) - } - return nil -} - -func (o *LMTestSetupOutputs) FundPool(chainId int64, lggr *zerolog.Logger, fundingAmount *big.Int) error { - token, err := erc20.NewERC20(*o.LMModules[chainId].WrapperNative, o.LMModules[chainId].ChainClient.Backend()) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to create ERC20 contract instance: %w", err)) - } - balance, err := token.BalanceOf(nil, common.HexToAddress(o.LMModules[chainId].ChainClient.GetDefaultWallet().Address())) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to get token pool balance: %w", err)) - } - lggr.Debug().Str("balance", balance.String()).Msg("weth balance of transactor") - symbol, err := token.Symbol(nil) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to get token symbol: %w", err)) - } - if symbol == "WETH" { - weth, err := weth9.NewWETH9(*o.LMModules[chainId].WrapperNative, o.LMModules[chainId].ChainClient.Backend()) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to create WETH contract instance: %w", err)) - } - nativeBalance, err := o.LMModules[chainId].ChainClient.BalanceAt(context.Background(), common.HexToAddress(o.LMModules[chainId].ChainClient.GetDefaultWallet().Address())) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to get native balance: %w", err)) - } - lggr.Debug().Str("nativeBalance", nativeBalance.String()).Msg("nativeBalance") - if nativeBalance.Cmp(fundingAmount) < 0 { - return errors.WithStack(fmt.Errorf("not enough native balance")) - } - lggr.Info().Msg("Depositing tokenpool funding to WETH contract") - txOpts, err := o.LMModules[chainId].ChainClient.TransactionOpts(o.LMModules[chainId].ChainClient.GetDefaultWallet()) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to get transaction options: %w", err)) - } - txOpts.Value = fundingAmount - tx, err := weth.Deposit(txOpts) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to deposit to WETH contract: %w", err)) - } - receipt, err := bind.WaitMined(context.Background(), o.LMModules[chainId].ChainClient.DeployBackend(), tx) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to wait for transaction receipt: %w", err)) - } - - lggr.Info().Str("tx hash", receipt.TxHash.String()).Msg("Deposited tokenpool funding to WETH contract") - } - lggr.Info().Msg("Funding token pool") - txOpts, err := o.LMModules[chainId].ChainClient.TransactionOpts(o.LMModules[chainId].ChainClient.GetDefaultWallet()) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to get transaction options: %w", err)) - - } - tx, err := token.Transfer(txOpts, o.LMModules[chainId].TokenPool.EthAddress, fundingAmount) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to transfer to token pool: %w", err)) - } - receipt, err := bind.WaitMined(context.Background(), o.LMModules[chainId].ChainClient.DeployBackend(), tx) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to wait for transaction receipt: %w", err)) - } - lggr.Info().Str("tx hash", receipt.TxHash.String()).Msg("Funded token pool") - - balance, err = token.BalanceOf(nil, o.LMModules[chainId].TokenPool.EthAddress) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to get token pool balance: %w", err)) - } - lggr.Debug().Str("balance", balance.String()).Msg("weth balance of token pool") - - return nil -} - -func (o *LMTestSetupOutputs) FundLM(chainId int64, lggr *zerolog.Logger, fundingAmount *big.Int) error { - transactor, err := o.LMModules[chainId].ChainClient.TransactionOpts(o.LMModules[chainId].ChainClient.GetDefaultWallet()) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to get transaction options: %w", err)) - } - cl := o.LMModules[chainId].ChainClient.Backend() - - nonce, err := cl.PendingNonceAt(context.Background(), transactor.From) - if err != nil { - return err - } - - gasPrice, err := cl.SuggestGasPrice(context.Background()) - if err != nil { - return err - } - - gasEstimate, err := cl.EstimateGas(context.Background(), ethereum.CallMsg{ - From: transactor.From, - To: o.LMModules[chainId].LM.EthAddress, - Value: fundingAmount, - }) - if err != nil { - return err - } - - tx := types.NewTx( - &types.LegacyTx{ - Nonce: nonce, - GasPrice: gasPrice, - Gas: gasEstimate, - To: o.LMModules[chainId].LM.EthAddress, - Value: fundingAmount, - }, - ) - signedTx, err := transactor.Signer(transactor.From, tx) - if err != nil { - return err - } - lggr.Info().Msg("Funding Liquidity Manager") - err = cl.SendTransaction(context.Background(), signedTx) - if err != nil { - return err - } - receipt, err := bind.WaitMined(context.Background(), o.LMModules[chainId].ChainClient.DeployBackend(), signedTx) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to wait for transaction receipt: %w", err)) - } - lggr.Info().Str("tx hash", receipt.TxHash.String()).Msg("Funded Liquidity Manager") - return nil -} - -func (o *LMTestSetupOutputs) AddJobs(chainId int64, lggr *zerolog.Logger) error { - // Add bootstrap job - clNodesWithKeys := o.Env.CLNodesWithKeys[strconv.FormatInt(chainId, 10)] - bootstrapNode := clNodesWithKeys[0] - bootstrapSpec, err := integrationtesthelpers.NewBootsrapJobSpec(&integrationtesthelpers.LMJobSpecParams{ - ChainID: uint64(chainId), - ContractID: o.LMModules[chainId].LM.EthAddress.String(), - CfgTrackerInterval: 15 * time.Second, - }) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to create bootstrap job spec: %w", err)) - } - lggr.Info().Msg("Adding bootstrap job") - j, err := bootstrapNode.Node.MustCreateJob(bootstrapSpec) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to create bootstrap job: %w", err)) - } - lggr.Info().Str("jobId", j.Data.ID).Msg("Bootstrap job added") - - P2Pv2Bootstrapper := fmt.Sprintf("%s@%s:%d", bootstrapNode.KeysBundle.P2PKeys.Data[0].Attributes.PeerID, bootstrapNode.Node.InternalIP(), 6690) - - // Add LM jobs - donNodes := clNodesWithKeys[1:] - - for _, node := range donNodes { - lmJobSpec, err := integrationtesthelpers.NewJobSpec(&integrationtesthelpers.LMJobSpecParams{ - ChainID: uint64(chainId), - ContractID: o.LMModules[chainId].LM.EthAddress.String(), - OCRKeyBundleID: node.KeysBundle.OCR2Key.Data.ID, - TransmitterID: node.KeysBundle.EthAddress, - P2PV2Bootstrappers: pq.StringArray{P2Pv2Bootstrapper}, - CfgTrackerInterval: 15 * time.Second, - LiquidityManagerAddress: *o.LMModules[chainId].LM.EthAddress, - NetworkSelector: o.LMModules[chainId].ChainSelectror, - Type: "ping-pong", - }) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to create LM job spec: %w", err)) - } - lggr.Debug().Interface("lmJobSpec", lmJobSpec).Msg("lmJobSpec") - lggr.Info().Str("Node URL", node.Node.URL()).Msg("Adding LM job") - j, err := node.Node.MustCreateJob(lmJobSpec) - if err != nil { - return errors.WithStack(fmt.Errorf("failed to create LM job: %w", err)) - } - lggr.Info().Str("jobId", j.Data.ID).Msg("LM job added") - - } - return nil -} - -func LMDefaultTestSetup( - t *testing.T, - lggr *zerolog.Logger, - envName string, - testConfig *CCIPTestConfig, -) *LMTestSetupOutputs { - var ( - err error - ) - reportPath := "tmp_laneconfig" - parent, cancel := context.WithCancel(context.Background()) - defer cancel() - lmModules := make(map[int64]*actions.LMCommon) - setUpArgs := &LMTestSetupOutputs{ - CCIPTestSetUpOutputs{ - SetUpContext: parent, - Cfg: testConfig, - }, - lmModules, - } - - chainByChainID := setUpArgs.CreateLMEnvironment(lggr, envName, reportPath) - - chainAddGrp, _ := errgroup.WithContext(setUpArgs.SetUpContext) - lggr.Info().Msg("Deploying common contracts") - chainSelectors := make(map[int64]uint64) - - testConfig.SelectedNetworks, _, err = testConfig.EnvInput.EVMNetworks() - require.NoError(t, err) - - testConfig.AllNetworks = make(map[string]blockchain.EVMNetwork) - for _, net := range testConfig.SelectedNetworks { - testConfig.AllNetworks[net.Name] = net - if _, exists := chainSelectors[net.ChainID]; !exists { - chainSelectors[net.ChainID], err = chainselectors.SelectorFromChainId(uint64(net.ChainID)) - require.NoError(t, err) - } - } - - l1ChainId := testConfig.SelectedNetworks[0].ChainID - l2ChainId := testConfig.SelectedNetworks[1].ChainID - - for _, net := range testConfig.AllNetworks { - chain := chainByChainID[net.ChainID] - net := net - net.HTTPURLs = chain.GetNetworkConfig().HTTPURLs - net.URLs = chain.GetNetworkConfig().URLs - var selectors []uint64 - for chainId, selector := range chainSelectors { - if chainId == net.ChainID { - selectors = append(selectors, selector) - } - } - lmCommon, err := actions.DefaultLMModule( - chain, - big.NewInt(0), - selectors[0], - ) - require.NoError(t, err) - chainAddGrp.Go(func() error { - return setUpArgs.DeployLMChainContracts(lggr, net, *lmCommon, l2ChainId) - }) - } - require.NoError(t, chainAddGrp.Wait(), "Deploying common contracts shouldn't fail") - - lggr.Debug().Interface("lmModules", lmModules).Msg("lmModules") - - //Set Cross Chain Rebalancer on L1 Rebalancer - err = lmModules[l1ChainId].LM.SetCrossChainRebalancer( - liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs{ - RemoteRebalancer: *lmModules[l2ChainId].LM.EthAddress, - LocalBridge: *lmModules[l1ChainId].BridgeAdapterAddr, - RemoteToken: *lmModules[l2ChainId].WrapperNative, - RemoteChainSelector: lmModules[l2ChainId].ChainSelectror, - Enabled: true, - }) - require.NoError(t, err, "Setting Cross Chain Rebalancer on L1 Rebalancer shouldn't fail") - - //Set Cross Chain Rebalancer on L2 Rebalancer - err = lmModules[l2ChainId].LM.SetCrossChainRebalancer( - liquiditymanager.ILiquidityManagerCrossChainRebalancerArgs{ - RemoteRebalancer: *lmModules[l1ChainId].LM.EthAddress, - LocalBridge: *lmModules[l2ChainId].BridgeAdapterAddr, - RemoteToken: *lmModules[l1ChainId].WrapperNative, - RemoteChainSelector: lmModules[l1ChainId].ChainSelectror, - Enabled: true, - }) - require.NoError(t, err, "Setting Cross Chain Rebalancer on L1 Rebalancer shouldn't fail") - - // Wait for setting cross chain balancers on both chains to confirm - err = lmModules[l1ChainId].ChainClient.WaitForEvents() - require.NoError(t, err, "Waiting for events to confirm on L1 chain shouldn't fail") - - err = lmModules[l2ChainId].ChainClient.WaitForEvents() - require.NoError(t, err, "Waiting for events to confirm on L2 chain shouldn't fail") - - // Verify that onchain rebalancer matches the deployed Liquidity Manager - onchainRebalancerL1, err := lmModules[l1ChainId].TokenPool.GetRebalancer() - require.NoError(t, err, "Getting rebalancer from Token Pool shouldn't fail") - - onchainRebalancerL2, err := lmModules[l2ChainId].TokenPool.GetRebalancer() - require.NoError(t, err, "Getting rebalancer from Token Pool shouldn't fail") - - if onchainRebalancerL1.String() != lmModules[l1ChainId].LM.EthAddress.String() || - onchainRebalancerL2.String() != lmModules[l2ChainId].LM.EthAddress.String() { - lggr.Debug(). - Str("onchainRebalancerL1", onchainRebalancerL1.String()). - Str("onchainRebalancerL2", onchainRebalancerL2.String()). - Str("L2 LM", lmModules[l2ChainId].LM.EthAddress.String()). - Str("L1 LM", lmModules[l1ChainId].LM.EthAddress.String()). - Msg("Onchain rebalancer mismatch") - t.Fatalf("Onchain rebalancer mismatch") - } - - // Fund L1 Token Pool - err = setUpArgs.FundPool(l1ChainId, lggr, big.NewInt(1000000000)) - require.NoError(t, err, "Funding L1 Token Pool shouldn't fail") - - //Fund L1 LM - err = setUpArgs.FundLM(l1ChainId, lggr, big.NewInt(1000000000)) - require.NoError(t, err, "Funding L1 LM shouldn't fail") - - err = lmModules[l1ChainId].ChainClient.WaitForEvents() - require.NoError(t, err, "Waiting for events to confirm on L1 chain shouldn't fail") - - // Fund L2 Token Pool - err = setUpArgs.FundPool(l2ChainId, lggr, big.NewInt(1000000000)) - require.NoError(t, err, "Funding L2 Token Pool shouldn't fail") - - //Fund L2 LM - err = setUpArgs.FundLM(l2ChainId, lggr, big.NewInt(1000000000)) - require.NoError(t, err, "Funding L2 LM shouldn't fail") - - err = lmModules[l2ChainId].ChainClient.WaitForEvents() - require.NoError(t, err, "Waiting for events to confirm on L2 chain shouldn't fail") - - liquidity, err := setUpArgs.LMModules[l1ChainId].LM.GetLiquidity() - require.NoError(t, err, "Getting liquidity from L1 LM shouldn't fail") - lggr.Debug().Interface("liquidity", liquidity).Msg("Liquidity") - require.Equal(t, big.NewInt(1000000000), liquidity, "Liquidity should match") - - liquidity, err = setUpArgs.LMModules[l2ChainId].LM.GetLiquidity() - require.NoError(t, err, "Getting liquidity from L1 LM shouldn't fail") - lggr.Debug().Interface("liquidity", liquidity).Msg("Liquidity") - require.Equal(t, big.NewInt(1000000000), liquidity, "Liquidity should match") - - err = setUpArgs.Env.CLNodeWithKeyReady.Wait() - require.NoError(t, err, "Waiting for CL nodes to be ready shouldn't fail") - - err = setUpArgs.AddJobs(l1ChainId, lggr) - require.NoError(t, err, "Adding jobs on L1 chain shouldn't fail") - - // Set Config on L2 Chain - err = setUpArgs.SetOCR3Config(l2ChainId) - require.NoError(t, err, "Setting OCR3 config on L2 chain shouldn't fail") - - // TODO: Remove this sleep when it is no longer needed - time.Sleep(30 * time.Second) - - // Set Config on L1 Chain - err = setUpArgs.SetOCR3Config(l1ChainId) - require.NoError(t, err, "Setting OCR3 config on L1 chain shouldn't fail") - - defer lmModules[l1ChainId].ChainClient.Close() - defer lmModules[l2ChainId].ChainClient.Close() - - return setUpArgs -} diff --git a/integration-tests/contracts/contract_models.go b/integration-tests/contracts/contract_models.go index ea63f1aa4d..46f10f06bb 100644 --- a/integration-tests/contracts/contract_models.go +++ b/integration-tests/contracts/contract_models.go @@ -14,6 +14,8 @@ import ( ocrConfigHelper "github.com/smartcontractkit/libocr/offchainreporting/confighelper" ocrConfigHelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/functions_billing_registry_events_mock" @@ -124,22 +126,22 @@ type OffChainAggregatorConfig struct { } type OffChainAggregatorV2Config struct { - DeltaProgress time.Duration - DeltaResend time.Duration - DeltaRound time.Duration - DeltaGrace time.Duration - DeltaStage time.Duration - RMax uint8 - S []int - Oracles []ocrConfigHelper2.OracleIdentityExtra - ReportingPluginConfig []byte - MaxDurationQuery time.Duration - MaxDurationObservation time.Duration - MaxDurationReport time.Duration - MaxDurationShouldAcceptFinalizedReport time.Duration - MaxDurationShouldTransmitAcceptedReport time.Duration - F int - OnchainConfig []byte + DeltaProgress *config.Duration `toml:",omitempty"` + DeltaResend *config.Duration `toml:",omitempty"` + DeltaRound *config.Duration `toml:",omitempty"` + DeltaGrace *config.Duration `toml:",omitempty"` + DeltaStage *config.Duration `toml:",omitempty"` + RMax uint8 `toml:"-"` + S []int `toml:"-"` + Oracles []ocrConfigHelper2.OracleIdentityExtra `toml:"-"` + ReportingPluginConfig []byte `toml:"-"` + MaxDurationQuery *config.Duration `toml:",omitempty"` + MaxDurationObservation *config.Duration `toml:",omitempty"` + MaxDurationReport *config.Duration `toml:",omitempty"` + MaxDurationShouldAcceptFinalizedReport *config.Duration `toml:",omitempty"` + MaxDurationShouldTransmitAcceptedReport *config.Duration `toml:",omitempty"` + F int `toml:"-"` + OnchainConfig []byte `toml:"-"` } type OffchainAggregatorData struct { @@ -230,6 +232,12 @@ type MockLINKETHFeed interface { LatestRoundDataUpdatedAt() (*big.Int, error) } +type MockETHLINKFeed interface { + Address() string + LatestRoundData() (*big.Int, error) + LatestRoundDataUpdatedAt() (*big.Int, error) +} + type MockETHUSDFeed interface { Address() string LatestRoundData() (*big.Int, error) diff --git a/integration-tests/deployment/ccip/add_lane.go b/integration-tests/deployment/ccip/add_lane.go deleted file mode 100644 index 16384e0aba..0000000000 --- a/integration-tests/deployment/ccip/add_lane.go +++ /dev/null @@ -1,119 +0,0 @@ -package ccipdeployment - -import ( - "encoding/hex" - "math/big" - - "github.com/ethereum/go-ethereum/common" - - "github.com/smartcontractkit/chainlink/integration-tests/deployment" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" -) - -func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) error { - // TODO: Batch - tx, err := state.Chains[from].Router.ApplyRampUpdates(e.Chains[from].DeployerKey, []router.RouterOnRamp{ - { - DestChainSelector: to, - OnRamp: state.Chains[from].EvmOnRampV160.Address(), - }, - }, []router.RouterOffRamp{}, []router.RouterOffRamp{}) - if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { - return err - } - tx, err = state.Chains[from].EvmOnRampV160.ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, - []onramp.OnRampDestChainConfigArgs{ - { - DestChainSelector: to, - Router: state.Chains[from].Router.Address(), - }, - }) - if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { - return err - } - - _, err = state.Chains[from].PriceRegistry.UpdatePrices( - e.Chains[from].DeployerKey, fee_quoter.InternalPriceUpdates{ - TokenPriceUpdates: []fee_quoter.InternalTokenPriceUpdate{ - { - SourceToken: state.Chains[from].LinkToken.Address(), - UsdPerToken: deployment.E18Mult(20), - }, - { - SourceToken: state.Chains[from].Weth9.Address(), - UsdPerToken: deployment.E18Mult(4000), - }, - }, - GasPriceUpdates: []fee_quoter.InternalGasPriceUpdate{ - { - DestChainSelector: to, - UsdPerUnitGas: big.NewInt(2e12), - }, - }}) - if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { - return err - } - - // Enable dest in price registry - tx, err = state.Chains[from].PriceRegistry.ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, - []fee_quoter.FeeQuoterDestChainConfigArgs{ - { - DestChainSelector: to, - DestChainConfig: defaultPriceRegistryDestChainConfig(), - }, - }) - if err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { - return err - } - - tx, err = state.Chains[to].EvmOffRampV160.ApplySourceChainConfigUpdates(e.Chains[to].DeployerKey, - []offramp.OffRampSourceChainConfigArgs{ - { - Router: state.Chains[to].Router.Address(), - SourceChainSelector: from, - IsEnabled: true, - OnRamp: common.LeftPadBytes(state.Chains[from].EvmOnRampV160.Address().Bytes(), 32), - }, - }) - if err := deployment.ConfirmIfNoError(e.Chains[to], tx, err); err != nil { - return err - } - tx, err = state.Chains[to].Router.ApplyRampUpdates(e.Chains[to].DeployerKey, []router.RouterOnRamp{}, []router.RouterOffRamp{}, []router.RouterOffRamp{ - { - SourceChainSelector: from, - OffRamp: state.Chains[to].EvmOffRampV160.Address(), - }, - }) - return deployment.ConfirmIfNoError(e.Chains[to], tx, err) -} - -func defaultPriceRegistryDestChainConfig() fee_quoter.FeeQuoterDestChainConfig { - // https://github.com/smartcontractkit/ccip/blob/c4856b64bd766f1ddbaf5d13b42d3c4b12efde3a/contracts/src/v0.8/ccip/libraries/Internal.sol#L337-L337 - /* - ```Solidity - // bytes4(keccak256("CCIP ChainFamilySelector EVM")) - bytes4 public constant CHAIN_FAMILY_SELECTOR_EVM = 0x2812d52c; - ``` - */ - evmFamilySelector, _ := hex.DecodeString("2812d52c") - return fee_quoter.FeeQuoterDestChainConfig{ - IsEnabled: true, - MaxNumberOfTokensPerMsg: 10, - MaxDataBytes: 256, - MaxPerMsgGasLimit: 3_000_000, - DestGasOverhead: 50_000, - DefaultTokenFeeUSDCents: 1, - DestGasPerPayloadByte: 10, - DestDataAvailabilityOverheadGas: 0, - DestGasPerDataAvailabilityByte: 100, - DestDataAvailabilityMultiplierBps: 1, - DefaultTokenDestGasOverhead: 125_000, - DefaultTxGasLimit: 200_000, - GasMultiplierWeiPerEth: 1, - NetworkFeeUSDCents: 1, - ChainFamilySelector: [4]byte(evmFamilySelector), - } -} diff --git a/integration-tests/deployment/ccip/deploy.go b/integration-tests/deployment/ccip/deploy.go deleted file mode 100644 index ff589d1430..0000000000 --- a/integration-tests/deployment/ccip/deploy.go +++ /dev/null @@ -1,470 +0,0 @@ -package ccipdeployment - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" - - "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink/integration-tests/deployment" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" -) - -var ( - MockARM deployment.ContractType = "MockRMN" - LinkToken deployment.ContractType = "LinkToken" - ARMProxy deployment.ContractType = "ARMProxy" - WETH9 deployment.ContractType = "WETH9" - Router deployment.ContractType = "Router" - TokenAdminRegistry deployment.ContractType = "TokenAdminRegistry" - NonceManager deployment.ContractType = "NonceManager" - PriceRegistry deployment.ContractType = "PriceRegistry" - ManyChainMultisig deployment.ContractType = "ManyChainMultiSig" - CCIPConfig deployment.ContractType = "CCIPConfig" - RBACTimelock deployment.ContractType = "RBACTimelock" - OnRamp deployment.ContractType = "OnRamp" - OffRamp deployment.ContractType = "OffRamp" - CCIPReceiver deployment.ContractType = "CCIPReceiver" - CapabilitiesRegistry deployment.ContractType = "CapabilitiesRegistry" -) - -type Contracts interface { - *capabilities_registry.CapabilitiesRegistry | - *rmn_proxy_contract.RMNProxyContract | - *ccip_config.CCIPConfig | - *nonce_manager.NonceManager | - *fee_quoter.FeeQuoter | - *router.Router | - *token_admin_registry.TokenAdminRegistry | - *weth9.WETH9 | - *mock_rmn_contract.MockRMNContract | - *owner_helpers.ManyChainMultiSig | - *owner_helpers.RBACTimelock | - *offramp.OffRamp | - *onramp.OnRamp | - *burn_mint_erc677.BurnMintERC677 | - *maybe_revert_message_receiver.MaybeRevertMessageReceiver -} - -type ContractDeploy[C Contracts] struct { - // We just keep all the deploy return values - // since some will be empty if there's an error. - Address common.Address - Contract C - Tx *types.Transaction - Tv deployment.TypeAndVersion - Err error -} - -// TODO: pull up to general deployment pkg somehow -// without exposing all product specific contracts? -func deployContract[C Contracts]( - lggr logger.Logger, - chain deployment.Chain, - addressBook deployment.AddressBook, - deploy func(chain deployment.Chain) ContractDeploy[C], -) (*ContractDeploy[C], error) { - contractDeploy := deploy(chain) - if contractDeploy.Err != nil { - lggr.Errorw("Failed to deploy contract", "err", contractDeploy.Err) - return nil, contractDeploy.Err - } - err := chain.Confirm(contractDeploy.Tx.Hash()) - if err != nil { - lggr.Errorw("Failed to confirm deployment", "err", err) - return nil, err - } - err = addressBook.Save(chain.Selector, contractDeploy.Address.String(), contractDeploy.Tv) - if err != nil { - lggr.Errorw("Failed to save contract address", "err", err) - return nil, err - } - return &contractDeploy, nil -} - -type DeployCCIPContractConfig struct { - HomeChainSel uint64 - // Existing contracts which we want to skip deployment - // Leave empty if we want to deploy everything - // TODO: Add skips to deploy function. - CCIPOnChainState -} - -// TODO: Likely we'll want to further parameterize the deployment -// For example a list of contracts to skip deploying if they already exist. -// Or mock vs real RMN. -// Deployment produces an address book of everything it deployed. -func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) (deployment.AddressBook, error) { - var ab deployment.AddressBook = deployment.NewMemoryAddressBook() - nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) - if err != nil || len(nodes) == 0 { - e.Logger.Errorw("Failed to get node info", "err", err) - return ab, err - } - if c.Chains[c.HomeChainSel].CapabilityRegistry == nil { - return ab, fmt.Errorf("Capability registry not found for home chain %d, needs to be deployed first", c.HomeChainSel) - } - cr, err := c.Chains[c.HomeChainSel].CapabilityRegistry.GetHashedCapabilityId( - &bind.CallOpts{}, CapabilityLabelledName, CapabilityVersion) - if err != nil { - e.Logger.Errorw("Failed to get hashed capability id", "err", err) - return ab, err - } - // Signal to CR that our nodes support CCIP capability. - if err := AddNodes( - c.Chains[c.HomeChainSel].CapabilityRegistry, - e.Chains[c.HomeChainSel], - nodes.PeerIDs(c.HomeChainSel), // Doesn't actually matter which sel here - [][32]byte{cr}, - ); err != nil { - return ab, err - } - - for _, chain := range e.Chains { - ab, err = DeployChainContracts(e, chain, ab) - if err != nil { - return ab, err - } - chainAddresses, err := ab.AddressesForChain(chain.Selector) - if err != nil { - e.Logger.Errorw("Failed to get chain addresses", "err", err) - return ab, err - } - chainState, err := LoadChainState(chain, chainAddresses) - if err != nil { - e.Logger.Errorw("Failed to load chain state", "err", err) - return ab, err - } - // Enable ramps on price registry/nonce manager - tx, err := chainState.PriceRegistry.ApplyAuthorizedCallerUpdates(chain.DeployerKey, fee_quoter.AuthorizedCallersAuthorizedCallerArgs{ - // TODO: We enable the deployer initially to set prices - AddedCallers: []common.Address{chainState.EvmOffRampV160.Address(), chain.DeployerKey.From}, - }) - if err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { - e.Logger.Errorw("Failed to confirm price registry authorized caller update", "err", err) - return ab, err - } - - tx, err = chainState.NonceManager.ApplyAuthorizedCallerUpdates(chain.DeployerKey, nonce_manager.AuthorizedCallersAuthorizedCallerArgs{ - AddedCallers: []common.Address{chainState.EvmOffRampV160.Address(), chainState.EvmOnRampV160.Address()}, - }) - if err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { - e.Logger.Errorw("Failed to update nonce manager with ramps", "err", err) - return ab, err - } - - // Add chain config for each chain. - _, err = AddChainConfig(e.Logger, - e.Chains[c.HomeChainSel], - c.Chains[c.HomeChainSel].CCIPConfig, - chain.Selector, - nodes.PeerIDs(chain.Selector), - uint8(len(nodes)/3)) - if err != nil { - return ab, err - } - - // For each chain, we create a DON on the home chain. - if err := AddDON(e.Logger, - cr, - c.Chains[c.HomeChainSel].CapabilityRegistry, - c.Chains[c.HomeChainSel].CCIPConfig, - chainState.EvmOffRampV160, - chain, - e.Chains[c.HomeChainSel], - uint8(len(nodes)/3), - nodes.BootstrapPeerIDs(chain.Selector)[0], - nodes.PeerIDs(chain.Selector), - nodes, - ); err != nil { - e.Logger.Errorw("Failed to add DON", "err", err) - return ab, err - } - } - - return ab, nil -} - -func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab deployment.AddressBook) (deployment.AddressBook, error) { - ccipReceiver, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver] { - receiverAddr, tx, receiver, err2 := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver( - chain.DeployerKey, - chain.Client, - false, - ) - return ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver]{ - receiverAddr, receiver, tx, deployment.NewTypeAndVersion(CCIPReceiver, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy receiver", "err", err) - return ab, err - } - e.Logger.Infow("deployed receiver", "addr", ccipReceiver.Address) - - // TODO: Still waiting for RMNRemote/RMNHome contracts etc. - mockARM, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*mock_rmn_contract.MockRMNContract] { - mockARMAddr, tx, mockARM, err2 := mock_rmn_contract.DeployMockRMNContract( - chain.DeployerKey, - chain.Client, - ) - return ContractDeploy[*mock_rmn_contract.MockRMNContract]{ - mockARMAddr, mockARM, tx, deployment.NewTypeAndVersion(MockARM, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy mockARM", "err", err) - return ab, err - } - e.Logger.Infow("deployed mockARM", "addr", mockARM) - - mcm, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*owner_helpers.ManyChainMultiSig] { - mcmAddr, tx, mcm, err2 := owner_helpers.DeployManyChainMultiSig( - chain.DeployerKey, - chain.Client, - ) - return ContractDeploy[*owner_helpers.ManyChainMultiSig]{ - mcmAddr, mcm, tx, deployment.NewTypeAndVersion(ManyChainMultisig, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy mcm", "err", err) - return ab, err - } - // TODO: Address soon - e.Logger.Infow("deployed mcm", "addr", mcm.Address) - - _, err = deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*owner_helpers.RBACTimelock] { - timelock, tx, cc, err2 := owner_helpers.DeployRBACTimelock( - chain.DeployerKey, - chain.Client, - big.NewInt(0), // minDelay - mcm.Address, - []common.Address{mcm.Address}, // proposers - []common.Address{chain.DeployerKey.From}, //executors - []common.Address{mcm.Address}, // cancellers - []common.Address{mcm.Address}, // bypassers - ) - return ContractDeploy[*owner_helpers.RBACTimelock]{ - timelock, cc, tx, deployment.NewTypeAndVersion(RBACTimelock, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy timelock", "err", err) - return ab, err - } - e.Logger.Infow("deployed timelock", "addr", mcm.Address) - - rmnProxy, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*rmn_proxy_contract.RMNProxyContract] { - rmnProxyAddr, tx, rmnProxy, err2 := rmn_proxy_contract.DeployRMNProxyContract( - chain.DeployerKey, - chain.Client, - mockARM.Address, - ) - return ContractDeploy[*rmn_proxy_contract.RMNProxyContract]{ - rmnProxyAddr, rmnProxy, tx, deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy rmnProxy", "err", err) - return ab, err - } - e.Logger.Infow("deployed rmnProxy", "addr", rmnProxy.Address) - - weth9, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*weth9.WETH9] { - weth9Addr, tx, weth9c, err2 := weth9.DeployWETH9( - chain.DeployerKey, - chain.Client, - ) - return ContractDeploy[*weth9.WETH9]{ - weth9Addr, weth9c, tx, deployment.NewTypeAndVersion(WETH9, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy weth9", "err", err) - return ab, err - } - - linkToken, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*burn_mint_erc677.BurnMintERC677] { - linkTokenAddr, tx, linkToken, err2 := burn_mint_erc677.DeployBurnMintERC677( - chain.DeployerKey, - chain.Client, - "Link Token", - "LINK", - uint8(18), - big.NewInt(0).Mul(big.NewInt(1e9), big.NewInt(1e18)), - ) - return ContractDeploy[*burn_mint_erc677.BurnMintERC677]{ - linkTokenAddr, linkToken, tx, deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy linkToken", "err", err) - return ab, err - } - - routerContract, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*router.Router] { - routerAddr, tx, routerC, err2 := router.DeployRouter( - chain.DeployerKey, - chain.Client, - weth9.Address, - rmnProxy.Address, - ) - return ContractDeploy[*router.Router]{ - routerAddr, routerC, tx, deployment.NewTypeAndVersion(Router, deployment.Version1_2_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy router", "err", err) - return ab, err - } - e.Logger.Infow("deployed router", "addr", routerContract) - - tokenAdminRegistry, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*token_admin_registry.TokenAdminRegistry] { - tokenAdminRegistryAddr, tx, tokenAdminRegistry, err2 := token_admin_registry.DeployTokenAdminRegistry( - chain.DeployerKey, - chain.Client) - return ContractDeploy[*token_admin_registry.TokenAdminRegistry]{ - tokenAdminRegistryAddr, tokenAdminRegistry, tx, deployment.NewTypeAndVersion(TokenAdminRegistry, deployment.Version1_5_0), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy token admin registry", "err", err) - return ab, err - } - e.Logger.Infow("deployed tokenAdminRegistry", "addr", tokenAdminRegistry) - - nonceManager, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*nonce_manager.NonceManager] { - nonceManagerAddr, tx, nonceManager, err2 := nonce_manager.DeployNonceManager( - chain.DeployerKey, - chain.Client, - []common.Address{}, // Need to add onRamp after - ) - return ContractDeploy[*nonce_manager.NonceManager]{ - nonceManagerAddr, nonceManager, tx, deployment.NewTypeAndVersion(NonceManager, deployment.Version1_6_0_dev), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy router", "err", err) - return ab, err - } - - feeQuoter, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*fee_quoter.FeeQuoter] { - prAddr, tx, pr, err2 := fee_quoter.DeployFeeQuoter( - chain.DeployerKey, - chain.Client, - fee_quoter.FeeQuoterStaticConfig{ - MaxFeeJuelsPerMsg: big.NewInt(0).Mul(big.NewInt(2e2), big.NewInt(1e18)), - LinkToken: linkToken.Address, - StalenessThreshold: uint32(24 * 60 * 60), - }, - []common.Address{}, // ramps added after - []common.Address{weth9.Address, linkToken.Address}, // fee tokens - []fee_quoter.FeeQuoterTokenPriceFeedUpdate{}, - []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs{}, // TODO: tokens - []fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs{ - { - PremiumMultiplierWeiPerEth: 9e17, // 0.9 ETH - Token: linkToken.Address, - }, - { - PremiumMultiplierWeiPerEth: 1e18, - Token: weth9.Address, - }, - }, - []fee_quoter.FeeQuoterDestChainConfigArgs{}, - ) - return ContractDeploy[*fee_quoter.FeeQuoter]{ - prAddr, pr, tx, deployment.NewTypeAndVersion(PriceRegistry, deployment.Version1_6_0_dev), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy price registry", "err", err) - return ab, err - } - - onRamp, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*onramp.OnRamp] { - onRampAddr, tx, onRamp, err2 := onramp.DeployOnRamp( - chain.DeployerKey, - chain.Client, - onramp.OnRampStaticConfig{ - ChainSelector: chain.Selector, - RmnProxy: rmnProxy.Address, - NonceManager: nonceManager.Address, - TokenAdminRegistry: tokenAdminRegistry.Address, - }, - onramp.OnRampDynamicConfig{ - FeeQuoter: feeQuoter.Address, - FeeAggregator: common.HexToAddress("0x1"), // TODO real fee aggregator - }, - []onramp.OnRampDestChainConfigArgs{}, - ) - return ContractDeploy[*onramp.OnRamp]{ - onRampAddr, onRamp, tx, deployment.NewTypeAndVersion(OnRamp, deployment.Version1_6_0_dev), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy onramp", "err", err) - return ab, err - } - e.Logger.Infow("deployed onramp", "addr", onRamp.Address) - - offRamp, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*offramp.OffRamp] { - offRampAddr, tx, offRamp, err2 := offramp.DeployOffRamp( - chain.DeployerKey, - chain.Client, - offramp.OffRampStaticConfig{ - ChainSelector: chain.Selector, - RmnProxy: rmnProxy.Address, - NonceManager: nonceManager.Address, - TokenAdminRegistry: tokenAdminRegistry.Address, - }, - offramp.OffRampDynamicConfig{ - FeeQuoter: feeQuoter.Address, - PermissionLessExecutionThresholdSeconds: uint32(86400), - MaxTokenTransferGas: uint32(200_000), - MaxPoolReleaseOrMintGas: uint32(200_000), - }, - []offramp.OffRampSourceChainConfigArgs{}, - ) - return ContractDeploy[*offramp.OffRamp]{ - offRampAddr, offRamp, tx, deployment.NewTypeAndVersion(OffRamp, deployment.Version1_6_0_dev), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy offramp", "err", err) - return ab, err - } - e.Logger.Infow("deployed offramp", "addr", offRamp) - return ab, nil -} diff --git a/integration-tests/deployment/ccip/deploy_home_chain.go b/integration-tests/deployment/ccip/deploy_home_chain.go deleted file mode 100644 index 315ebfb413..0000000000 --- a/integration-tests/deployment/ccip/deploy_home_chain.go +++ /dev/null @@ -1,410 +0,0 @@ -package ccipdeployment - -import ( - "bytes" - "context" - "errors" - "sort" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - - deployment2 "github.com/smartcontractkit/ccip/integration-tests/deployment" - - "github.com/smartcontractkit/chainlink-ccip/chainconfig" - "github.com/smartcontractkit/chainlink-ccip/pluginconfig" - commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" - - "github.com/smartcontractkit/chainlink/integration-tests/deployment" - cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ocr3_config_encoder" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" -) - -const ( - NodeOperatorID = 1 - CapabilityLabelledName = "ccip" - CapabilityVersion = "v1.0.0" - - FirstBlockAge = 8 * time.Hour - RemoteGasPriceBatchWriteFrequency = 30 * time.Minute - BatchGasLimit = 6_500_000 - RelativeBoostPerWaitHour = 1.5 - InflightCacheExpiry = 10 * time.Minute - RootSnoozeTime = 30 * time.Minute - BatchingStrategyID = 0 - DeltaProgress = 30 * time.Second - DeltaResend = 10 * time.Second - DeltaInitial = 20 * time.Second - DeltaRound = 2 * time.Second - DeltaGrace = 2 * time.Second - DeltaCertifiedCommitRequest = 10 * time.Second - DeltaStage = 10 * time.Second - Rmax = 3 - MaxDurationQuery = 50 * time.Millisecond - MaxDurationObservation = 5 * time.Second - MaxDurationShouldAcceptAttestedReport = 10 * time.Second - MaxDurationShouldTransmitAcceptedReport = 10 * time.Second -) - -func DeployCapReg(lggr logger.Logger, chains map[uint64]deployment.Chain, chainSel uint64) (deployment.AddressBook, error) { - ab := deployment.NewMemoryAddressBook() - chain := chains[chainSel] - capReg, err := deployContract(lggr, chain, ab, - func(chain deployment.Chain) ContractDeploy[*capabilities_registry.CapabilitiesRegistry] { - crAddr, tx, cr, err2 := capabilities_registry.DeployCapabilitiesRegistry( - chain.DeployerKey, - chain.Client, - ) - return ContractDeploy[*capabilities_registry.CapabilitiesRegistry]{ - Address: crAddr, Contract: cr, TvStr: CapabilitiesRegistry_1_0_0, Tx: tx, Err: err2, - } - }) - if err != nil { - lggr.Errorw("Failed to deploy capreg", "err", err) - return ab, err - } - lggr.Infow("deployed capreg", "addr", capReg.Address) - ccipConfig, err := deployContract( - lggr, chain, ab, - func(chain deployment.Chain) ContractDeploy[*ccip_config.CCIPConfig] { - ccAddr, tx, cc, err2 := ccip_config.DeployCCIPConfig( - chain.DeployerKey, - chain.Client, - capReg.Address, - ) - return ContractDeploy[*ccip_config.CCIPConfig]{ - Address: ccAddr, TvStr: CCIPConfig_1_6_0, Tx: tx, Err: err2, Contract: cc, - } - }) - if err != nil { - lggr.Errorw("Failed to deploy ccip config", "err", err) - return ab, err - } - lggr.Infow("deployed ccip config", "addr", ccipConfig.Address) - - tx, err := capReg.Contract.AddCapabilities(chain.DeployerKey, []capabilities_registry.CapabilitiesRegistryCapability{ - { - LabelledName: CapabilityLabelledName, - Version: CapabilityVersion, - CapabilityType: 2, // consensus. not used (?) - ResponseType: 0, // report. not used (?) - ConfigurationContract: ccipConfig.Address, - }, - }) - if err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { - lggr.Errorw("Failed to add capabilities", "err", err) - return ab, err - } - // TODO: Just one for testing. - tx, err = capReg.Contract.AddNodeOperators(chain.DeployerKey, []capabilities_registry.CapabilitiesRegistryNodeOperator{ - { - Admin: chain.DeployerKey.From, - Name: "NodeOperator", - }, - }) - if err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { - lggr.Errorw("Failed to add node operators", "err", err) - return ab, err - } - return ab, nil -} - -func sortP2PIDS(p2pIDs [][32]byte) { - sort.Slice(p2pIDs, func(i, j int) bool { - return bytes.Compare(p2pIDs[i][:], p2pIDs[j][:]) < 0 - }) -} - -func AddNodes( - capReg *capabilities_registry.CapabilitiesRegistry, - chain deployment.Chain, - p2pIDs [][32]byte, - capabilityIDs [][32]byte, -) error { - // Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail - sortP2PIDS(p2pIDs) - var nodeParams []capabilities_registry.CapabilitiesRegistryNodeParams - for _, p2pID := range p2pIDs { - nodeParam := capabilities_registry.CapabilitiesRegistryNodeParams{ - NodeOperatorId: NodeOperatorID, - Signer: p2pID, // Not used in tests - P2pId: p2pID, - HashedCapabilityIds: capabilityIDs, - } - nodeParams = append(nodeParams, nodeParam) - } - tx, err := capReg.AddNodes(chain.DeployerKey, nodeParams) - if err != nil { - return err - } - return chain.Confirm(tx.Hash()) -} - -func SetupConfigInfo(chainSelector uint64, readers [][32]byte, fChain uint8, cfg []byte) ccip_config.CCIPConfigTypesChainConfigInfo { - return ccip_config.CCIPConfigTypesChainConfigInfo{ - ChainSelector: chainSelector, - ChainConfig: ccip_config.CCIPConfigTypesChainConfig{ - Readers: readers, - FChain: fChain, - Config: cfg, - }, - } -} - -func AddChainConfig( - lggr logger.Logger, - h deployment.Chain, - ccipConfig *ccip_config.CCIPConfig, - chainSelector uint64, - p2pIDs [][32]byte, - f uint8, -) (ccip_config.CCIPConfigTypesChainConfigInfo, error) { - // Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail - sortP2PIDS(p2pIDs) - // First Add ChainConfig that includes all p2pIDs as readers - encodedExtraChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ - GasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(1000), - DAGasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(0), - FinalityDepth: 10, - OptimisticConfirmations: 1, - }) - if err != nil { - return ccip_config.CCIPConfigTypesChainConfigInfo{}, err - } - chainConfig := SetupConfigInfo(chainSelector, p2pIDs, f, encodedExtraChainConfig) - inputConfig := []ccip_config.CCIPConfigTypesChainConfigInfo{ - chainConfig, - } - tx, err := ccipConfig.ApplyChainConfigUpdates(h.DeployerKey, nil, inputConfig) - if err != nil { - return ccip_config.CCIPConfigTypesChainConfigInfo{}, err - } - if err := h.Confirm(tx.Hash()); err != nil { - return ccip_config.CCIPConfigTypesChainConfigInfo{}, err - } - return chainConfig, nil -} - -func AddDON( - lggr logger.Logger, - ccipCapabilityID [32]byte, - capReg *capabilities_registry.CapabilitiesRegistry, - ccipConfig *ccip_config.CCIPConfig, - offRamp *offramp.OffRamp, - dest deployment.Chain, - home deployment.Chain, - f uint8, - bootstrapP2PID [32]byte, - p2pIDs [][32]byte, - nodes []deployment2.Node, -) error { - sortP2PIDS(p2pIDs) - // Get OCR3 Config from helper - var schedule []int - var oracles []confighelper2.OracleIdentityExtra - for _, node := range nodes { - schedule = append(schedule, 1) - cfg := node.SelToOCRConfig[dest.Selector] - oracles = append(oracles, confighelper2.OracleIdentityExtra{ - OracleIdentity: confighelper2.OracleIdentity{ - OnchainPublicKey: cfg.OnchainPublicKey, - TransmitAccount: cfg.TransmitAccount, - OffchainPublicKey: cfg.OffchainPublicKey, - PeerID: cfg.PeerID.String()[4:], - }, ConfigEncryptionPublicKey: cfg.ConfigEncryptionPublicKey, - }) - } - - tabi, err := ocr3_config_encoder.IOCR3ConfigEncoderMetaData.GetAbi() - if err != nil { - return err - } - - // Add DON on capability registry contract - var ocr3Configs []ocr3_config_encoder.CCIPConfigTypesOCR3Config - for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { - var encodedOffchainConfig []byte - var err2 error - if pluginType == cctypes.PluginTypeCCIPCommit { - encodedOffchainConfig, err2 = pluginconfig.EncodeCommitOffchainConfig(pluginconfig.CommitOffchainConfig{ - RemoteGasPriceBatchWriteFrequency: *commonconfig.MustNewDuration(RemoteGasPriceBatchWriteFrequency), - // TODO: implement token price writes - // TokenPriceBatchWriteFrequency: *commonconfig.MustNewDuration(tokenPriceBatchWriteFrequency), - }) - } else { - encodedOffchainConfig, err2 = pluginconfig.EncodeExecuteOffchainConfig(pluginconfig.ExecuteOffchainConfig{ - BatchGasLimit: BatchGasLimit, - RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, - MessageVisibilityInterval: *commonconfig.MustNewDuration(FirstBlockAge), - InflightCacheExpiry: *commonconfig.MustNewDuration(InflightCacheExpiry), - RootSnoozeTime: *commonconfig.MustNewDuration(RootSnoozeTime), - BatchingStrategyID: BatchingStrategyID, - }) - } - if err2 != nil { - return err2 - } - signers, transmitters, configF, _, offchainConfigVersion, offchainConfig, err2 := ocr3confighelper.ContractSetConfigArgsForTests( - DeltaProgress, - DeltaResend, - DeltaInitial, - DeltaRound, - DeltaGrace, - DeltaCertifiedCommitRequest, - DeltaStage, - Rmax, - schedule, - oracles, - encodedOffchainConfig, - MaxDurationQuery, - MaxDurationObservation, - MaxDurationShouldAcceptAttestedReport, - MaxDurationShouldTransmitAcceptedReport, - int(f), - []byte{}, // empty OnChainConfig - ) - if err2 != nil { - return err2 - } - - signersBytes := make([][]byte, len(signers)) - for i, signer := range signers { - signersBytes[i] = signer - } - - transmittersBytes := make([][]byte, len(transmitters)) - for i, transmitter := range transmitters { - parsed, err2 := common.ParseHexOrString(string(transmitter)) - if err2 != nil { - return err2 - } - transmittersBytes[i] = parsed - } - - ocr3Configs = append(ocr3Configs, ocr3_config_encoder.CCIPConfigTypesOCR3Config{ - PluginType: uint8(pluginType), - ChainSelector: dest.Selector, - F: configF, - OffchainConfigVersion: offchainConfigVersion, - OfframpAddress: offRamp.Address().Bytes(), - BootstrapP2PIds: [][32]byte{bootstrapP2PID}, - P2pIds: p2pIDs, - Signers: signersBytes, - Transmitters: transmittersBytes, - OffchainConfig: offchainConfig, - }) - } - - encodedCall, err := tabi.Pack("exposeOCR3Config", ocr3Configs) - if err != nil { - return err - } - - // Trim first four bytes to remove function selector. - encodedConfigs := encodedCall[4:] - - // commit so that we have an empty block to filter events from - // TODO: required? - //h.backend.Commit() - - tx, err := capReg.AddDON(home.DeployerKey, p2pIDs, []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ - { - CapabilityId: ccipCapabilityID, - Config: encodedConfigs, - }, - }, false, false, f) - if err := deployment.ConfirmIfNoError(home, tx, err); err != nil { - return err - } - - latestBlock, err := home.Client.HeaderByNumber(context.Background(), nil) - if err != nil { - return err - } - endBlock := latestBlock.Number.Uint64() - iter, err := capReg.FilterConfigSet(&bind.FilterOpts{ - Start: endBlock - 1, - End: &endBlock, - }) - if err != nil { - return err - } - var donID uint32 - for iter.Next() { - donID = iter.Event.DonId - break - } - if donID == 0 { - return errors.New("failed to get donID") - } - - var signerAddresses []common.Address - for _, oracle := range oracles { - signerAddresses = append(signerAddresses, common.BytesToAddress(oracle.OnchainPublicKey)) - } - - var transmitterAddresses []common.Address - for _, oracle := range oracles { - transmitterAddresses = append(transmitterAddresses, common.HexToAddress(string(oracle.TransmitAccount))) - } - - // get the config digest from the ccip config contract and set config on the offramp. - var offrampOCR3Configs []offramp.MultiOCR3BaseOCRConfigArgs - for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { - ocrConfig, err2 := ccipConfig.GetOCRConfig(&bind.CallOpts{ - Context: context.Background(), - }, donID, uint8(pluginType)) - if err2 != nil { - return err2 - } - if len(ocrConfig) != 1 { - return errors.New("expected exactly one OCR3 config") - } - - offrampOCR3Configs = append(offrampOCR3Configs, offramp.MultiOCR3BaseOCRConfigArgs{ - ConfigDigest: ocrConfig[0].ConfigDigest, - OcrPluginType: uint8(pluginType), - F: f, - IsSignatureVerificationEnabled: pluginType == cctypes.PluginTypeCCIPCommit, - Signers: signerAddresses, - Transmitters: transmitterAddresses, - }) - } - - //uni.backend.Commit() - - tx, err = offRamp.SetOCR3Configs(dest.DeployerKey, offrampOCR3Configs) - if err := deployment.ConfirmIfNoError(dest, tx, err); err != nil { - return err - } - - for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { - _, err = offRamp.LatestConfigDetails(&bind.CallOpts{ - Context: context.Background(), - }, uint8(pluginType)) - if err != nil { - //return err - return deployment.MaybeDataErr(err) - } - // TODO: assertions - //require.Equalf(t, offrampOCR3Configs[pluginType].ConfigDigest, ocrConfig.ConfigInfo.ConfigDigest, "%s OCR3 config digest mismatch", pluginType.String()) - //require.Equalf(t, offrampOCR3Configs[pluginType].F, ocrConfig.ConfigInfo.F, "%s OCR3 config F mismatch", pluginType.String()) - //require.Equalf(t, offrampOCR3Configs[pluginType].IsSignatureVerificationEnabled, ocrConfig.ConfigInfo.IsSignatureVerificationEnabled, "%s OCR3 config signature verification mismatch", pluginType.String()) - //if pluginType == cctypes.PluginTypeCCIPCommit { - // // only commit will set signers, exec doesn't need them. - // require.Equalf(t, offrampOCR3Configs[pluginType].Signers, ocrConfig.Signers, "%s OCR3 config signers mismatch", pluginType.String()) - //} - //require.Equalf(t, offrampOCR3Configs[pluginType].TransmittersByEVMChainID, ocrConfig.TransmittersByEVMChainID, "%s OCR3 config transmitters mismatch", pluginType.String()) - } - - lggr.Infof("set ocr3 config on the offramp, signers: %+v, transmitters: %+v", signerAddresses, transmitterAddresses) - return nil -} diff --git a/integration-tests/deployment/ccip/deploy_test.go b/integration-tests/deployment/ccip/deploy_test.go deleted file mode 100644 index ed2378cef3..0000000000 --- a/integration-tests/deployment/ccip/deploy_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package ccipdeployment - -import ( - "encoding/json" - "fmt" - "testing" - - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" - - "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -func TestDeployCCIPContracts(t *testing.T) { - lggr := logger.TestLogger(t) - e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ - Chains: 1, - Nodes: 1, - }) - // Deploy all the CCIP contracts. - ab, err := DeployCCIPContracts(e, DeployCCIPContractConfig{}) - require.NoError(t, err) - state, err := GenerateOnchainState(e, ab) - require.NoError(t, err) - snap, err := state.Snapshot(e.AllChainSelectors()) - require.NoError(t, err) - - // Assert expect every deployed address to be in the address book. - // TODO: Add the rest of CCIPv2 representation - b, err := json.MarshalIndent(snap, "", " ") - require.NoError(t, err) - fmt.Println(string(b)) -} - -func TestJobSpecGeneration(t *testing.T) { - lggr := logger.TestLogger(t) - e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ - Chains: 1, - Nodes: 1, - }) - js, err := NewCCIPJobSpecs(e.NodeIDs, e.Offchain) - require.NoError(t, err) - for node, jb := range js { - fmt.Println(node, jb) - } - // TODO: Add job assertions -} diff --git a/integration-tests/deployment/ccip/jobs.go b/integration-tests/deployment/ccip/jobs.go deleted file mode 100644 index f45fe4c553..0000000000 --- a/integration-tests/deployment/ccip/jobs.go +++ /dev/null @@ -1,70 +0,0 @@ -package ccipdeployment - -import ( - "context" - "fmt" - - "github.com/smartcontractkit/chainlink/integration-tests/deployment" - nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1" - "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" -) - -// In our case, the only address needed is the cap registry which is actually an env var. -// and will pre-exist for our deployment. So the job specs only depend on the environment operators. -func NewCCIPJobSpecs(nodeIds []string, oc deployment.OffchainClient) (map[string][]string, error) { - // Generate a set of brand new job specs for CCIP for a specific environment - // (including NOPs) and new addresses. - // We want to assign one CCIP capability job to each node. And node with - // an addr we'll list as bootstrapper. - // Find the bootstrap nodes - bootstrapMp := make(map[string]struct{}) - for _, node := range nodeIds { - // TODO: Filter should accept multiple nodes - nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ - NodeId: node, - }}) - if err != nil { - return nil, err - } - for _, chainConfig := range nodeChainConfigs.ChainConfigs { - if chainConfig.Ocr2Config.IsBootstrap { - bootstrapMp[fmt.Sprintf("%s@%s", - // p2p_12D3... -> 12D3... - chainConfig.Ocr2Config.P2PKeyBundle.PeerId[4:], chainConfig.Ocr2Config.Multiaddr)] = struct{}{} - } - } - } - var bootstraps []string - for b := range bootstrapMp { - bootstraps = append(bootstraps, b) - } - nodesToJobSpecs := make(map[string][]string) - for _, node := range nodeIds { - // TODO: Filter should accept multiple. - nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ - NodeId: node, - }}) - if err != nil { - return nil, err - } - spec, err := validate.NewCCIPSpecToml(validate.SpecArgs{ - P2PV2Bootstrappers: bootstraps, - CapabilityVersion: CapabilityVersion, - CapabilityLabelledName: CapabilityLabelledName, - OCRKeyBundleIDs: map[string]string{ - // TODO: Validate that that all EVM chains are using the same keybundle. - relay.NetworkEVM: nodeChainConfigs.ChainConfigs[0].Ocr2Config.OcrKeyBundle.BundleId, - }, - // TODO: validate that all EVM chains are using the same keybundle - P2PKeyID: nodeChainConfigs.ChainConfigs[0].Ocr2Config.P2PKeyBundle.PeerId, - RelayConfigs: nil, - PluginConfig: map[string]any{}, - }) - if err != nil { - return nil, err - } - nodesToJobSpecs[node] = append(nodesToJobSpecs[node], spec) - } - return nodesToJobSpecs, nil -} diff --git a/integration-tests/deployment/ccip/migrations/1_initial_deploy.go b/integration-tests/deployment/ccip/migrations/1_initial_deploy.go deleted file mode 100644 index e92d7c0e8b..0000000000 --- a/integration-tests/deployment/ccip/migrations/1_initial_deploy.go +++ /dev/null @@ -1,34 +0,0 @@ -package migrations - -import ( - "github.com/smartcontractkit/chainlink/integration-tests/deployment" - - ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" -) - -// We expect the migration input to be unique per migration. -// TODO: Maybe there's a generics approach here? -// Note if the migration is a deployment and it fails we have 2 options: -// - Just throw away the addresses, fix issue and try again (potentially expensive on mainnet) -// - Roll forward with another migration completing the deployment -func Apply0001(env deployment.Environment, c ccipdeployment.DeployCCIPContractConfig) (deployment.MigrationOutput, error) { - ab, err := ccipdeployment.DeployCCIPContracts(env, c) - if err != nil { - env.Logger.Errorw("Failed to deploy CCIP contracts", "err", err, "addresses", ab) - return deployment.MigrationOutput{}, err - } - js, err := ccipdeployment.NewCCIPJobSpecs(env.NodeIDs, env.Offchain) - if err != nil { - return deployment.MigrationOutput{}, err - } - proposal, err := ccipdeployment.GenerateAcceptOwnershipProposal(env, env.AllChainSelectors(), ab) - if err != nil { - return deployment.MigrationOutput{}, err - } - return deployment.MigrationOutput{ - Proposals: []deployment.Proposal{proposal}, - AddressBook: ab, - // Mapping of which nodes get which jobs. - JobSpecs: js, - }, nil -} diff --git a/integration-tests/deployment/ccip/migrations/1_initial_deploy_test.go b/integration-tests/deployment/ccip/migrations/1_initial_deploy_test.go deleted file mode 100644 index d75f5cbc2b..0000000000 --- a/integration-tests/deployment/ccip/migrations/1_initial_deploy_test.go +++ /dev/null @@ -1,295 +0,0 @@ -package migrations - -import ( - "context" - "math/big" - "sync" - "testing" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" - chainsel "github.com/smartcontractkit/chain-selectors" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink/integration-tests/deployment" - - "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" - - jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - - ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" - "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" - - "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -// Context returns a context with the test's deadline, if available. -func Context(tb testing.TB) context.Context { - ctx := context.Background() - var cancel func() - switch t := tb.(type) { - case *testing.T: - if d, ok := t.Deadline(); ok { - ctx, cancel = context.WithDeadline(ctx, d) - } - } - if cancel == nil { - ctx, cancel = context.WithCancel(ctx) - } - tb.Cleanup(cancel) - return ctx -} - -func Test0001_InitialDeploy(t *testing.T) { - lggr := logger.TestLogger(t) - ctx := Context(t) - chains := memory.NewMemoryChains(t, 3) - homeChainSel := uint64(0) - homeChainEVM := uint64(0) - // First chain is home chain. - for chainSel := range chains { - homeChainEVM, _ = chainsel.ChainIdFromSelector(chainSel) - homeChainSel = chainSel - break - } - ab, err := ccipdeployment.DeployCapReg(lggr, chains, homeChainSel) - require.NoError(t, err) - - addrs, err := ab.AddressesForChain(homeChainSel) - require.NoError(t, err) - require.Len(t, addrs, 2) - capReg := common.Address{} - for addr := range addrs { - capReg = common.HexToAddress(addr) - break - } - nodes := memory.NewNodes(t, zapcore.InfoLevel, chains, 4, 1, memory.RegistryConfig{ - EVMChainID: homeChainEVM, - Contract: capReg, - }) - for _, node := range nodes { - require.NoError(t, node.App.Start(ctx)) - } - - e := memory.NewMemoryEnvironmentFromChainsNodes(t, lggr, chains, nodes) - state, err := ccipdeployment.GenerateOnchainState(e, ab) - require.NoError(t, err) - - capabilities, err := state.CapabilityRegistry[homeChainSel].GetCapabilities(nil) - require.NoError(t, err) - require.Len(t, capabilities, 1) - ccipCap, err := state.CapabilityRegistry[homeChainSel].GetHashedCapabilityId(nil, - ccipdeployment.CapabilityLabelledName, ccipdeployment.CapabilityVersion) - require.NoError(t, err) - _, err = state.CapabilityRegistry[homeChainSel].GetCapability(nil, ccipCap) - require.NoError(t, err) - - // Apply migration - output, err := Apply0001(e, ccipdeployment.DeployCCIPContractConfig{ - HomeChainSel: homeChainSel, - // Capreg/config already exist. - CCIPOnChainState: state, - }) - require.NoError(t, err) - // Get new state after migration. - state, err = ccipdeployment.GenerateOnchainState(e, output.AddressBook) - require.NoError(t, err) - - // Ensure capreg logs are up to date. - require.NoError(t, ReplayAllLogs(nodes, chains)) - - // Apply the jobs. - for nodeID, jobs := range output.JobSpecs { - for _, job := range jobs { - // Note these auto-accept - _, err := e.Offchain.ProposeJob(ctx, - &jobv1.ProposeJobRequest{ - NodeId: nodeID, - Spec: job, - }) - require.NoError(t, err) - } - } - // Wait for plugins to register filters? - // TODO: Investigate how to avoid. - time.Sleep(30 * time.Second) - - // Ensure job related logs are up to date. - require.NoError(t, ReplayAllLogs(nodes, chains)) - - // Send a request from every router - // Add all lanes - for source := range e.Chains { - for dest := range e.Chains { - if source != dest { - require.NoError(t, ccipdeployment.AddLane(e, state, source, dest)) - } - } - } - - // Send a message from each chain to every other chain. - for src, srcChain := range e.Chains { - for dest := range e.Chains { - if src == dest { - continue - } - msg := router.ClientEVM2AnyMessage{ - Receiver: common.LeftPadBytes(state.Receivers[dest].Address().Bytes(), 32), - Data: []byte("hello"), - TokenAmounts: nil, // TODO: no tokens for now - FeeToken: state.Weth9s[src].Address(), - ExtraArgs: nil, // TODO: no extra args for now, falls back to default - } - fee, err := state.Routers[src].GetFee( - &bind.CallOpts{Context: context.Background()}, dest, msg) - require.NoError(t, err, deployment.MaybeDataErr(err)) - tx, err := state.Weth9s[src].Deposit(&bind.TransactOpts{ - From: e.Chains[src].DeployerKey.From, - Signer: e.Chains[src].DeployerKey.Signer, - Value: fee, - }) - require.NoError(t, err) - require.NoError(t, srcChain.Confirm(tx.Hash())) - - // TODO: should be able to avoid this by using native? - tx, err = state.Weth9s[src].Approve(e.Chains[src].DeployerKey, - state.Routers[src].Address(), fee) - require.NoError(t, err) - require.NoError(t, srcChain.Confirm(tx.Hash())) - - t.Logf("Sending CCIP request from chain selector %d to chain selector %d", - src, dest) - tx, err = state.Routers[src].CcipSend(e.Chains[src].DeployerKey, dest, msg) - require.NoError(t, err) - require.NoError(t, srcChain.Confirm(tx.Hash())) - } - } - - // Wait for all commit reports to land. - var wg sync.WaitGroup - for src, srcChain := range e.Chains { - for dest, dstChain := range e.Chains { - if src == dest { - continue - } - srcChain := srcChain - dstChain := dstChain - wg.Add(1) - go func(src, dest uint64) { - defer wg.Done() - waitForCommitWithInterval(t, srcChain, dstChain, state.EvmOffRampsV160[dest], ccipocr3.SeqNumRange{1, 1}) - }(src, dest) - } - } - wg.Wait() - - // Wait for all exec reports to land - for src, srcChain := range e.Chains { - for dest, dstChain := range e.Chains { - if src == dest { - continue - } - srcChain := srcChain - dstChain := dstChain - wg.Add(1) - go func(src, dest uint64) { - defer wg.Done() - waitForExecWithSeqNr(t, srcChain, dstChain, state.EvmOffRampsV160[dest], 1) - }(src, dest) - } - } - wg.Wait() - - // TODO: Apply the proposal. -} - -func ReplayAllLogs(nodes map[string]memory.Node, chains map[uint64]deployment.Chain) error { - for _, node := range nodes { - for sel := range chains { - chainID, _ := chainsel.ChainIdFromSelector(sel) - if err := node.App.ReplayFromBlock(big.NewInt(int64(chainID)), 1, false); err != nil { - return err - } - } - } - return nil -} - -func waitForCommitWithInterval( - t *testing.T, - src deployment.Chain, - dest deployment.Chain, - offRamp *offramp.OffRamp, - expectedSeqNumRange ccipocr3.SeqNumRange, -) { - sink := make(chan *offramp.OffRampCommitReportAccepted) - subscription, err := offRamp.WatchCommitReportAccepted(&bind.WatchOpts{ - Context: context.Background(), - }, sink) - require.NoError(t, err) - ticker := time.NewTicker(1 * time.Second) - defer ticker.Stop() - - //revive:disable - for { - select { - case <-ticker.C: - src.Client.(*backends.SimulatedBackend).Commit() - dest.Client.(*backends.SimulatedBackend).Commit() - t.Logf("Waiting for commit report on chain selector %d from source selector %d expected seq nr range %s", - dest.Selector, src.Selector, expectedSeqNumRange.String()) - case subErr := <-subscription.Err(): - t.Fatalf("Subscription error: %+v", subErr) - case report := <-sink: - if len(report.Report.MerkleRoots) > 0 { - // Check the interval of sequence numbers and make sure it matches - // the expected range. - for _, mr := range report.Report.MerkleRoots { - if mr.SourceChainSelector == src.Selector && - uint64(expectedSeqNumRange.Start()) == mr.Interval.Min && - uint64(expectedSeqNumRange.End()) == mr.Interval.Max { - t.Logf("Received commit report on selector %d from source selector %d expected seq nr range %s", - dest.Selector, src.Selector, expectedSeqNumRange.String()) - return - } - } - } - } - } -} - -func waitForExecWithSeqNr(t *testing.T, - source, dest deployment.Chain, - offramp *offramp.OffRamp, - expectedSeqNr uint64) { - tick := time.NewTicker(5 * time.Second) - defer tick.Stop() - for range tick.C { - // TODO: Clean this up - source.Client.(*backends.SimulatedBackend).Commit() - dest.Client.(*backends.SimulatedBackend).Commit() - scc, err := offramp.GetSourceChainConfig(nil, source.Selector) - require.NoError(t, err) - t.Logf("Waiting for ExecutionStateChanged on chain %d from chain %d with expected sequence number %d, current onchain minSeqNr: %d", - dest.Selector, source.Selector, expectedSeqNr, scc.MinSeqNr) - iter, err := offramp.FilterExecutionStateChanged(nil, - []uint64{source.Selector}, []uint64{expectedSeqNr}, nil) - require.NoError(t, err) - var count int - for iter.Next() { - if iter.Event.SequenceNumber == expectedSeqNr && iter.Event.SourceChainSelector == source.Selector { - count++ - } - } - if count == 1 { - t.Logf("Received ExecutionStateChanged on chain %d from chain %d with expected sequence number %d", - dest.Selector, source.Selector, expectedSeqNr) - return - } - } -} diff --git a/integration-tests/deployment/ccip/propose.go b/integration-tests/deployment/ccip/propose.go deleted file mode 100644 index 0dc42acc87..0000000000 --- a/integration-tests/deployment/ccip/propose.go +++ /dev/null @@ -1,64 +0,0 @@ -package ccipdeployment - -import ( - "math/big" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" - chainsel "github.com/smartcontractkit/chain-selectors" - - "github.com/smartcontractkit/chainlink/integration-tests/deployment" -) - -// TODO: Pull up to deploy -func SimTransactOpts() *bind.TransactOpts { - return &bind.TransactOpts{Signer: func(address common.Address, transaction *types.Transaction) (*types.Transaction, error) { - return transaction, nil - }, From: common.HexToAddress("0x0"), NoSend: true, GasLimit: 200_000} -} - -func GenerateAcceptOwnershipProposal( - e deployment.Environment, - chains []uint64, - ab deployment.AddressBook, -) (deployment.Proposal, error) { - state, err := GenerateOnchainState(e, ab) - if err != nil { - return deployment.Proposal{}, err - } - // TODO: Just onramp as an example - var ops []owner_helpers.ManyChainMultiSigOp - for _, sel := range chains { - opCount, err := state.Mcms[sel].GetOpCount(nil) - if err != nil { - return deployment.Proposal{}, err - } - - txData, err := state.EvmOnRampsV160[sel].AcceptOwnership(SimTransactOpts()) - if err != nil { - return deployment.Proposal{}, err - } - evmID, err := chainsel.ChainIdFromSelector(sel) - if err != nil { - return deployment.Proposal{}, err - } - ops = append(ops, owner_helpers.ManyChainMultiSigOp{ - ChainId: big.NewInt(int64(evmID)), - MultiSig: state.McmsAddrs[sel], - Nonce: opCount, - To: state.EvmOnRampsV160[sel].Address(), - Value: big.NewInt(0), - Data: txData.Data(), - }) - } - // TODO: Real valid until. - return deployment.Proposal{ValidUntil: uint32(time.Now().Unix()), Ops: ops}, nil -} - -func ApplyProposal(env deployment.Environment, p deployment.Proposal, state CCIPOnChainState) error { - // TODO - return nil -} diff --git a/integration-tests/deployment/ccip/state.go b/integration-tests/deployment/ccip/state.go deleted file mode 100644 index f641d30ed4..0000000000 --- a/integration-tests/deployment/ccip/state.go +++ /dev/null @@ -1,276 +0,0 @@ -package ccipdeployment - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/common" - "github.com/pkg/errors" - chainsel "github.com/smartcontractkit/chain-selectors" - - owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" - - "github.com/smartcontractkit/chainlink/integration-tests/deployment" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" -) - -type CCIPChainState struct { - EvmOnRampV160 *onramp.OnRamp - EvmOffRampV160 *offramp.OffRamp - PriceRegistry *fee_quoter.FeeQuoter - ArmProxy *rmn_proxy_contract.RMNProxyContract - NonceManager *nonce_manager.NonceManager - TokenAdminRegistry *token_admin_registry.TokenAdminRegistry - Router *router.Router - Weth9 *weth9.WETH9 - MockRmn *mock_rmn_contract.MockRMNContract - // TODO: May need to support older link too - LinkToken *burn_mint_erc677.BurnMintERC677 - // Note we only expect one of these (on the home chain) - CapabilityRegistry *capabilities_registry.CapabilitiesRegistry - CCIPConfig *ccip_config.CCIPConfig - Mcm *owner_wrappers.ManyChainMultiSig - // TODO: remove once we have Address() on wrappers - McmsAddr common.Address - Timelock *owner_wrappers.RBACTimelock - - // Test contracts - Receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver -} - -// Onchain state always derivable from an address book. -// Offchain state always derivable from a list of nodeIds. -// Note can translate this into Go struct needed for MCMS/Docs/UI. -type CCIPOnChainState struct { - // Populated go bindings for the appropriate version for all contracts. - // We would hold 2 versions of each contract here. Once we upgrade we can phase out the old one. - // When generating bindings, make sure the package name corresponds to the version. - Chains map[uint64]CCIPChainState -} - -type CCIPSnapShot struct { - Chains map[string]Chain `json:"chains"` -} - -type Contract struct { - TypeAndVersion string `json:"typeAndVersion"` - Address common.Address `json:"address"` -} - -type TokenAdminRegistryView struct { - Contract - Tokens []common.Address `json:"tokens"` -} - -type NonceManagerView struct { - Contract - AuthorizedCallers []common.Address `json:"authorizedCallers"` -} - -type Chain struct { - // TODO: this will have to be versioned for getting state during upgrades. - TokenAdminRegistry TokenAdminRegistryView `json:"tokenAdminRegistry"` - NonceManager NonceManagerView `json:"nonceManager"` -} - -func (s CCIPOnChainState) Snapshot(chains []uint64) (CCIPSnapShot, error) { - snapshot := CCIPSnapShot{ - Chains: make(map[string]Chain), - } - for _, chainSelector := range chains { - // TODO: Need a utility for this - chainid, err := chainsel.ChainIdFromSelector(chainSelector) - if err != nil { - return snapshot, err - } - chainName, err := chainsel.NameFromChainId(chainid) - if err != nil { - return snapshot, err - } - if _, ok := s.Chains[chainSelector]; !ok { - return snapshot, fmt.Errorf("chain not supported %d", chainSelector) - } - var c Chain - ta := s.Chains[chainSelector].TokenAdminRegistry - if ta != nil { - tokens, err := ta.GetAllConfiguredTokens(nil, 0, 10) - if err != nil { - return snapshot, err - } - tv, err := ta.TypeAndVersion(nil) - if err != nil { - return snapshot, err - } - c.TokenAdminRegistry = TokenAdminRegistryView{ - Contract: Contract{ - TypeAndVersion: tv, - Address: ta.Address(), - }, - Tokens: tokens, - } - } - nm := s.Chains[chainSelector].NonceManager - if nm != nil { - authorizedCallers, err := nm.GetAllAuthorizedCallers(nil) - if err != nil { - return snapshot, err - } - tv, err := nm.TypeAndVersion(nil) - if err != nil { - return snapshot, err - } - c.NonceManager = NonceManagerView{ - Contract: Contract{ - TypeAndVersion: tv, - Address: nm.Address(), - }, - // TODO: these can be resolved using an address book - AuthorizedCallers: authorizedCallers, - } - } - snapshot.Chains[chainName] = c - } - return snapshot, nil -} - -func SnapshotState(e deployment.Environment, ab deployment.AddressBook) (CCIPSnapShot, error) { - state, err := LoadOnchainState(e, ab) - if err != nil { - return CCIPSnapShot{}, err - } - return state.Snapshot(e.AllChainSelectors()) -} - -func LoadOnchainState(e deployment.Environment, ab deployment.AddressBook) (CCIPOnChainState, error) { - state := CCIPOnChainState{ - Chains: make(map[uint64]CCIPChainState), - } - addresses, err := ab.Addresses() - if err != nil { - return state, errors.Wrap(err, "could not get addresses") - } - for chainSelector, addresses := range addresses { - chainState, err := LoadChainState(e.Chains[chainSelector], addresses) - if err != nil { - return state, err - } - state.Chains[chainSelector] = chainState - } - return state, nil -} - -// Loads all state for a chain into state -// Modifies map in place -func LoadChainState(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (CCIPChainState, error) { - var state CCIPChainState - for address, tvStr := range addresses { - switch tvStr.String() { - case deployment.NewTypeAndVersion(RBACTimelock, deployment.Version1_0_0).String(): - tl, err := owner_wrappers.NewRBACTimelock(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.Timelock = tl - case deployment.NewTypeAndVersion(ManyChainMultisig, deployment.Version1_0_0).String(): - mcms, err := owner_wrappers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.Mcm = mcms - state.McmsAddr = common.HexToAddress(address) - case deployment.NewTypeAndVersion(CapabilitiesRegistry, deployment.Version1_0_0).String(): - cr, err := capabilities_registry.NewCapabilitiesRegistry(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.CapabilityRegistry = cr - case deployment.NewTypeAndVersion(OnRamp, deployment.Version1_6_0_dev).String(): - onRampC, err := onramp.NewOnRamp(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.EvmOnRampV160 = onRampC - case deployment.NewTypeAndVersion(OffRamp, deployment.Version1_6_0_dev).String(): - offRamp, err := offramp.NewOffRamp(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.EvmOffRampV160 = offRamp - case deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0).String(): - armProxy, err := rmn_proxy_contract.NewRMNProxyContract(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.ArmProxy = armProxy - case deployment.NewTypeAndVersion(MockARM, deployment.Version1_0_0).String(): - mockARM, err := mock_rmn_contract.NewMockRMNContract(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.MockRmn = mockARM - case deployment.NewTypeAndVersion(WETH9, deployment.Version1_0_0).String(): - weth9, err := weth9.NewWETH9(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.Weth9 = weth9 - case deployment.NewTypeAndVersion(NonceManager, deployment.Version1_6_0_dev).String(): - nm, err := nonce_manager.NewNonceManager(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.NonceManager = nm - case deployment.NewTypeAndVersion(TokenAdminRegistry, deployment.Version1_5_0).String(): - tm, err := token_admin_registry.NewTokenAdminRegistry(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.TokenAdminRegistry = tm - case deployment.NewTypeAndVersion(Router, deployment.Version1_2_0).String(): - r, err := router.NewRouter(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.Router = r - case deployment.NewTypeAndVersion(PriceRegistry, deployment.Version1_6_0_dev).String(): - pr, err := fee_quoter.NewFeeQuoter(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.PriceRegistry = pr - case deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0).String(): - lt, err := burn_mint_erc677.NewBurnMintERC677(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.LinkToken = lt - case deployment.NewTypeAndVersion(CCIPConfig, deployment.Version1_6_0_dev).String(): - cc, err := ccip_config.NewCCIPConfig(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.CCIPConfig = cc - case deployment.NewTypeAndVersion(CCIPReceiver, deployment.Version1_0_0).String(): - mr, err := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.Receiver = mr - default: - return state, fmt.Errorf("unknown contract %s", tvStr) - } - } - return state, nil -} diff --git a/integration-tests/deployment/ccip/test_helpers.go b/integration-tests/deployment/ccip/test_helpers.go deleted file mode 100644 index 2ec837c9ee..0000000000 --- a/integration-tests/deployment/ccip/test_helpers.go +++ /dev/null @@ -1,75 +0,0 @@ -package ccipdeployment - -import ( - "context" - "testing" - - chainsel "github.com/smartcontractkit/chain-selectors" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink/integration-tests/deployment" - "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" - - "github.com/smartcontractkit/chainlink-common/pkg/logger" -) - -// Context returns a context with the test's deadline, if available. -func Context(tb testing.TB) context.Context { - ctx := context.Background() - var cancel func() - switch t := tb.(type) { - case *testing.T: - if d, ok := t.Deadline(); ok { - ctx, cancel = context.WithDeadline(ctx, d) - } - } - if cancel == nil { - ctx, cancel = context.WithCancel(ctx) - } - tb.Cleanup(cancel) - return ctx -} - -type DeployedTestEnvironment struct { - Ab deployment.AddressBook - Env deployment.Environment - HomeChainSel uint64 - Nodes map[string]memory.Node -} - -// NewDeployedEnvironment creates a new CCIP environment -// with capreg and nodes set up. -func NewDeployedTestEnvironment(t *testing.T, lggr logger.Logger) DeployedTestEnvironment { - ctx := Context(t) - chains := memory.NewMemoryChains(t, 3) - homeChainSel := uint64(0) - homeChainEVM := uint64(0) - // Say first chain is home chain. - for chainSel := range chains { - homeChainEVM, _ = chainsel.ChainIdFromSelector(chainSel) - homeChainSel = chainSel - break - } - ab, capReg, err := DeployCapReg(lggr, chains, homeChainSel) - require.NoError(t, err) - - nodes := memory.NewNodes(t, zapcore.InfoLevel, chains, 4, 1, memory.RegistryConfig{ - EVMChainID: homeChainEVM, - Contract: capReg, - }) - for _, node := range nodes { - require.NoError(t, node.App.Start(ctx)) - t.Cleanup(func() { - require.NoError(t, node.App.Stop()) - }) - } - - e := memory.NewMemoryEnvironmentFromChainsNodes(t, lggr, chains, nodes) - return DeployedTestEnvironment{ - Ab: ab, - Env: e, - HomeChainSel: homeChainSel, - Nodes: nodes, - } -} diff --git a/integration-tests/deployment/memory/node.go b/integration-tests/deployment/memory/node.go index cc800f18bd..8dfba05874 100644 --- a/integration-tests/deployment/memory/node.go +++ b/integration-tests/deployment/memory/node.go @@ -12,12 +12,15 @@ import ( "github.com/ethereum/go-ethereum/common" gethtypes "github.com/ethereum/go-ethereum/core/types" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + evmcapabilities "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" v2toml "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -61,6 +64,16 @@ type Node struct { IsBoostrap bool } +func (n Node) ReplayLogs(chains map[uint64]uint64) error { + for sel, block := range chains { + chainID, _ := chainsel.ChainIdFromSelector(sel) + if err := n.App.ReplayFromBlock(big.NewInt(int64(chainID)), block, false); err != nil { + return err + } + } + return nil +} + type RegistryConfig struct { EVMChainID uint64 Contract common.Address @@ -152,9 +165,10 @@ func NewNode( // Build relayer factory with EVM. relayerFactory := chainlink.RelayerFactory{ - Logger: lggr, - LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), cfg.Tracing()), - GRPCOpts: loop.GRPCOpts{}, + Logger: lggr, + LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), cfg.Tracing()), + GRPCOpts: loop.GRPCOpts{}, + CapabilitiesRegistry: evmcapabilities.NewRegistry(lggr), } initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitEVM(context.Background(), relayerFactory, evmOpts)} rci, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) diff --git a/integration-tests/deployment/migrations.go b/integration-tests/deployment/migrations.go deleted file mode 100644 index 5defd56075..0000000000 --- a/integration-tests/deployment/migrations.go +++ /dev/null @@ -1,28 +0,0 @@ -package deployment - -import ( - owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" -) - -// TODO: Move to real MCM structs once available. -type Proposal struct { - // keccak256(abi.encode(root, validUntil)) is what is signed by MCMS - // signers. - ValidUntil uint32 - // Leaves are the items in the proposal. - // Uses these to generate the root as well as display whats in the root. - // These Ops may be destined for distinct chains. - Ops []owner_wrappers.ManyChainMultiSigOp -} - -func (p Proposal) String() string { - // TODO - return "" -} - -// Services as input to CI/Async tasks -type MigrationOutput struct { - JobSpecs map[string][]string - Proposals []Proposal - AddressBook AddressBook -} diff --git a/integration-tests/go.mod b/integration-tests/go.mod index e20e98bcf9..b65712d8bb 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -1,4 +1,4 @@ -module github.com/smartcontractkit/ccip/integration-tests +module github.com/smartcontractkit/chainlink/integration-tests go 1.22.5 @@ -12,10 +12,10 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 github.com/avast/retry-go/v4 v4.6.0 github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df - github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f + github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a github.com/cli/go-gh/v2 v2.0.0 github.com/ethereum/go-ethereum v1.13.8 - github.com/fxamacker/cbor/v2 v2.6.0 + github.com/fxamacker/cbor/v2 v2.7.0 github.com/go-resty/resty/v2 v2.11.0 github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 @@ -28,7 +28,7 @@ require ( github.com/pelletier/go-toml/v2 v2.2.2 github.com/pkg/errors v0.9.1 github.com/prometheus/common v0.55.0 - github.com/rs/zerolog v1.32.0 + github.com/rs/zerolog v1.33.0 github.com/scylladb/go-reflectx v1.0.1 github.com/segmentio/ksuid v1.0.4 github.com/shopspring/decimal v1.4.0 @@ -36,16 +36,14 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc - github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 - github.com/smartcontractkit/chainlink-testing-framework v1.34.5 - github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 - github.com/smartcontractkit/chainlink/integration-tests v0.0.0-00010101000000-000000000000 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 + github.com/smartcontractkit/chainlink-testing-framework v1.34.9 + github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 + github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 + github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 + github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 - github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/smartcontractkit/seth v1.1.1 - github.com/smartcontractkit/wasp v0.4.5 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 github.com/test-go/testify v1.1.4 @@ -55,16 +53,14 @@ require ( go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.26.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa golang.org/x/sync v0.8.0 golang.org/x/text v0.17.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 gopkg.in/guregu/null.v4 v4.0.0 - gopkg.in/yaml.v2 v2.4.0 - gopkg.in/yaml.v3 v3.0.1 gotest.tools/v3 v3.5.1 - k8s.io/apimachinery v0.28.2 + k8s.io/apimachinery v0.31.0 ) // avoids ambigious imports of indirect dependencies @@ -110,13 +106,28 @@ require ( github.com/avast/retry-go v3.0.0+incompatible // indirect github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect github.com/aws/aws-sdk-go v1.45.25 // indirect + github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect + github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.28 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 // indirect github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect github.com/aws/jsii-runtime-go v1.75.0 // indirect + github.com/aws/smithy-go v1.20.4 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect github.com/blendle/zapdriver v1.3.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/buger/jsonparser v1.1.1 // indirect @@ -182,7 +193,6 @@ require ( github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/esote/minmaxheap v1.0.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect - github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect @@ -190,7 +200,6 @@ require ( github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/fvbommel/sortorder v1.1.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/solana-go v1.8.4 // indirect @@ -243,7 +252,7 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect + github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/context v1.1.1 // indirect github.com/gorilla/mux v1.8.0 // indirect @@ -257,15 +266,15 @@ require ( github.com/grafana/grafana-foundation-sdk/go v0.0.0-20240326122733-6f96a993222b // indirect github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 // indirect github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect - github.com/grafana/pyroscope-go v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect + github.com/grafana/pyroscope-go v1.1.2 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect @@ -314,7 +323,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.7 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -356,11 +365,13 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/mwitkow/grpc-proxy v0.0.0-20230212185441-f345521cb9c9 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/oklog/run v1.1.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/opencontainers/runc v1.1.7 // indirect github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e // indirect github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect @@ -395,13 +406,15 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect + github.com/smartcontractkit/wasp v0.4.5 // indirect github.com/smartcontractkit/wsrpc v0.8.1 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect @@ -441,16 +454,16 @@ require ( github.com/zondax/ledger-go v0.14.3 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect - go.etcd.io/bbolt v1.3.8 // indirect - go.etcd.io/etcd/api/v3 v3.5.12 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.12 // indirect - go.etcd.io/etcd/client/v3 v3.5.12 // indirect + go.etcd.io/bbolt v1.3.9 // indirect + go.etcd.io/etcd/api/v3 v3.5.14 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect + go.etcd.io/etcd/client/v3 v3.5.14 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 // indirect go.opentelemetry.io/collector/semconv v0.87.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect @@ -462,49 +475,47 @@ require ( go.uber.org/goleak v1.3.0 // indirect go.uber.org/ratelimit v0.3.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect - golang.org/x/arch v0.7.0 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/sys v0.24.0 // indirect golang.org/x/term v0.23.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/time v0.6.0 // indirect + golang.org/x/tools v0.24.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect - k8s.io/api v0.28.2 // indirect - k8s.io/apiextensions-apiserver v0.28.2 // indirect - k8s.io/cli-runtime v0.28.2 // indirect - k8s.io/client-go v0.28.2 // indirect - k8s.io/component-base v0.28.2 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.31.0 // indirect + k8s.io/apiextensions-apiserver v0.31.0 // indirect + k8s.io/cli-runtime v0.31.0 // indirect + k8s.io/client-go v0.31.0 // indirect + k8s.io/component-base v0.31.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect - k8s.io/kubectl v0.28.2 // indirect - k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect + k8s.io/kubectl v0.31.0 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect nhooyr.io/websocket v1.8.10 // indirect pgregory.net/rapid v1.1.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect - sigs.k8s.io/controller-runtime v0.16.2 // indirect + sigs.k8s.io/controller-runtime v0.19.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect - sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/api v0.17.2 // indirect + sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) exclude github.com/chaos-mesh/chaos-mesh/api/v1alpha1 v0.0.0-20220226050744-799408773657 -replace ( - github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.14.0 - github.com/prometheus/common => github.com/prometheus/common v0.42.0 -) - replace ( github.com/go-kit/log => github.com/go-kit/log v0.2.1 @@ -519,6 +530,9 @@ replace ( // type func(a Label, b Label) bool of func(a, b Label) bool {…} does not match inferred type func(a Label, b Label) int for func(a E, b E) int github.com/prometheus/prometheus => github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 +) - github.com/smartcontractkit/chainlink/integration-tests => ../integration-tests +replace ( + github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/common => github.com/prometheus/common v0.42.0 ) diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 5789a6ccc2..2c07f0f3e2 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -14,23 +14,27 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= -cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= +cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= +cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= +cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= +cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= +cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= +cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute v1.27.2 h1:5cE5hdrwJV/92ravlwIFRGnyH9CpLGhh4N0ZDVTU+BA= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= +cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw= +cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -40,8 +44,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= -cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= +cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= +cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo= @@ -211,10 +215,38 @@ github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8= +github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= +github.com/aws/aws-sdk-go-v2/config v1.27.28 h1:OTxWGW/91C61QlneCtnD62NLb4W616/NM1jA8LhJqbg= +github.com/aws/aws-sdk-go-v2/config v1.27.28/go.mod h1:uzVRVtJSU5EFv6Fu82AoVFKozJi2ZCY6WRCXj06rbvs= +github.com/aws/aws-sdk-go-v2/credentials v1.17.28 h1:m8+AHY/ND8CMHJnPoH7PJIRakWGa4gbfbxuY9TGTUXM= +github.com/aws/aws-sdk-go-v2/credentials v1.17.28/go.mod h1:6TF7dSc78ehD1SL6KpRIPKMA1GyyWflIkjqg+qmf4+c= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 h1:yjwoSyDZF8Jth+mUk5lSPJCkMC0lMy6FaCD51jm6ayE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12/go.mod h1:fuR57fAgMk7ot3WcNQfb6rSEn+SUffl7ri+aa8uKysI= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 h1:UDXu9dqpCZYonj7poM4kFISjzTdWI0v3WUusM+w+Gfc= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5/go.mod h1:5NPkI3RsTOhwz1CuG7VVSgJCm3CINKkoIaUbUZWQ67w= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.5/go.mod h1:ZeDX1SnKsVlejeuz41GiajjZpRSWR7/42q/EyA/QEiM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 h1:SKvPgvdvmiTWoi0GAJ7AsJfOz3ngVkD/ERbs5pUnHNI= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5/go.mod h1:20sz31hv/WsPa3HhU3hfrIet2kxM4Pe0r20eBZ20Tac= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 h1:iAckBT2OeEK/kBDyN/jDtpEExhjeeA/Im2q4X0rJZT8= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.4/go.mod h1:vmSqFK+BVIwVpDAGZB3CoCXHzurt4qBE8lf+I/kRTh0= github.com/aws/constructs-go/constructs/v10 v10.1.255 h1:5hARfEmhBqHSTQf/C3QLA3sWOxO2Dfja0iA1W7ZcI7g= github.com/aws/constructs-go/constructs/v10 v10.1.255/go.mod h1:DCdBSjN04Ck2pajCacTD4RKFqSA7Utya8d62XreYctI= github.com/aws/jsii-runtime-go v1.75.0 h1:NhpUfyiL7/wsRuUekFsz8FFBCYLfPD/l61kKg9kL/a4= github.com/aws/jsii-runtime-go v1.75.0/go.mod h1:TKCyrtM0pygEPo4rDZzbMSDNCDNTSYSN6/mGyHI6O3I= +github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= +github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= @@ -232,6 +264,8 @@ github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsy github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/bradleyjkemp/cupaloy/v2 v2.6.0 h1:knToPYa2xtfg42U3I6punFEjaGFKWQRXJwj0JTv4mTs= @@ -275,8 +309,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= -github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f h1:onZ3oc6l1Gz8pVpQ0c1U1Cb11kIMoDb3xtEy/iZbYZM= -github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f/go.mod h1:x11iCbZV6hzzSQWMq610B6Wl5Lg1dhwqcVfeiWQQnQQ= +github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a h1:6Pg3a6j/41QDzH/oYcMLwwKsf3x/HXcu9W/dBaf2Hzs= +github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a/go.mod h1:x11iCbZV6hzzSQWMq610B6Wl5Lg1dhwqcVfeiWQQnQQ= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= @@ -497,10 +531,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= -github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= -github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= -github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= @@ -557,8 +589,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= @@ -754,8 +786,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= @@ -804,10 +836,10 @@ github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 h1:gdrsYbmk8822v6qv github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503/go.mod h1:d8seWXCEXkL42mhuIJYcGi6DxfehzoIpLrMQWJojvOo= github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 h1:wQ0FnSeebhJIBkgYOD06Mxk9HV2KhtEG0hp/7R+5RUQ= github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0= -github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= -github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= +github.com/grafana/pyroscope-go v1.1.2 h1:7vCfdORYQMCxIzI3NlYAs3FcBP760+gWuYWOyiVyYx8= +github.com/grafana/pyroscope-go v1.1.2/go.mod h1:HSSmHo2KRn6FasBA4vK7BMiQqyQq8KSuBKvrhkXxYPU= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= @@ -827,8 +859,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= @@ -1034,9 +1066,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= -github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -1075,6 +1106,8 @@ github.com/linode/linodego v1.19.0 h1:n4WJrcr9+30e9JGZ6DI0nZbm5SdAj1kSwvvt/998YU github.com/linode/linodego v1.19.0/go.mod h1:XZFR+yJ9mm2kwf6itZ6SCpu+6w3KnIevV0Uu5HNWJgQ= github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= +github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= +github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= @@ -1203,6 +1236,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE= @@ -1222,8 +1257,8 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= -github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= @@ -1234,8 +1269,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= -github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= +github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo= github.com/opentracing-contrib/go-stdlib v1.0.0 h1:TBS7YuVotp8myLon4Pv7BtCBzOTo1DeZCld0Z63mW2w= @@ -1338,8 +1373,8 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= -github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -1396,34 +1431,36 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc h1:8267l5X5oF2JnGsDaEG4i0JSQO9o0eC61SscTfWc1bk= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= -github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa/go.mod h1:wZvLHX/Sd9hskN51016cTFcT3G62KXVa6xbVDS7tRjc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.5 h1:6itLSDW4NHDDNR+Y+Z8YDzxxCN9SjdKb6SmLCl0vTFM= -github.com/smartcontractkit/chainlink-testing-framework v1.34.5/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= +github.com/smartcontractkit/chainlink-testing-framework v1.34.9 h1:SA7YdICzBmIOFMzLBMAol3CYPyLEF7yKkx63SUrB4RE= +github.com/smartcontractkit/chainlink-testing-framework v1.34.9/go.mod h1:t2au5jHgrDklr25+Nurcy40Bgy5o5VBJvjipmnm6nVc= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 h1:1/r1wQZ4TOFpZ13w94r7amdF096Z96RuEnkOmrz1BGE= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= +github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= +github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 h1:wEc6EKMOOK/9w6z/zv2/wPZsV/txctbYoVJ1sCxhXwI= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0/go.mod h1:upYGPS9lOBW2pJg6XD8TTNSD1GtRfayU2Ct5bcfvqFw= +github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= +github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= -github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1:ZEhn2Yo1jY4hqy8nasDL4k4pNtopT3rS3Ap1GDb7ODc= -github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= -github.com/smartcontractkit/seth v1.1.1 h1:6hvexjJD7ek8ht/CLlEwQcH21K2E/WEYwbSRdKInZmM= -github.com/smartcontractkit/seth v1.1.1/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= @@ -1600,14 +1637,14 @@ go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRL go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= -go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c= -go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= -go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A= -go.etcd.io/etcd/client/pkg/v3 v3.5.12/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4= -go.etcd.io/etcd/client/v3 v3.5.12 h1:v5lCPXn1pf1Uu3M4laUE2hp/geOTc5uPcYYsNe1lDxg= -go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw= +go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= +go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= +go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= +go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= +go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= +go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= +go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= +go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= @@ -1631,8 +1668,8 @@ go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0. go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= @@ -1645,8 +1682,8 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= -go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= +go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= +go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -1684,8 +1721,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= -golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1725,8 +1762,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1751,8 +1788,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1808,8 +1845,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1817,8 +1854,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1922,8 +1959,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1956,8 +1993,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -2019,8 +2056,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2049,8 +2086,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= -google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= +google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= +google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2095,12 +2132,12 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= +google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -2145,6 +2182,8 @@ gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= @@ -2183,26 +2222,26 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= -k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= -k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= -k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= -k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= -k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= -k8s.io/cli-runtime v0.28.2 h1:64meB2fDj10/ThIMEJLO29a1oujSm0GQmKzh1RtA/uk= -k8s.io/cli-runtime v0.28.2/go.mod h1:bTpGOvpdsPtDKoyfG4EG041WIyFZLV9qq4rPlkyYfDA= -k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= -k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= -k8s.io/component-base v0.28.2 h1:Yc1yU+6AQSlpJZyvehm/NkJBII72rzlEsd6MkBQ+G0E= -k8s.io/component-base v0.28.2/go.mod h1:4IuQPQviQCg3du4si8GpMrhAIegxpsgPngPRR/zWpzc= +k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= +k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= +k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= +k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= +k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc= +k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/cli-runtime v0.31.0 h1:V2Q1gj1u3/WfhD475HBQrIYsoryg/LrhhK4RwpN+DhA= +k8s.io/cli-runtime v0.31.0/go.mod h1:vg3H94wsubuvWfSmStDbekvbla5vFGC+zLWqcf+bGDw= +k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8= +k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= +k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs= +k8s.io/component-base v0.31.0/go.mod h1:TYVuzI1QmN4L5ItVdMSXKvH7/DtvIuas5/mm8YT3rTo= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f h1:2sXuKesAYbRHxL3aE2PN6zX/gcJr22cjrsej+W784Tc= k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= -k8s.io/kubectl v0.28.2 h1:fOWOtU6S0smdNjG1PB9WFbqEIMlkzU5ahyHkc7ESHgM= -k8s.io/kubectl v0.28.2/go.mod h1:6EQWTPySF1fn7yKoQZHYf9TPwIl2AygHEcJoxFekr64= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kubectl v0.31.0 h1:kANwAAPVY02r4U4jARP/C+Q1sssCcN/1p9Nk+7BQKVg= +k8s.io/kubectl v0.31.0/go.mod h1:pB47hhFypGsaHAPjlwrNbvhXgmuAr01ZBvAIIUaI8d4= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= @@ -2214,14 +2253,14 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= -sigs.k8s.io/controller-runtime v0.16.2 h1:mwXAVuEk3EQf478PQwQ48zGOXvW27UJc8NHktQVuIPU= -sigs.k8s.io/controller-runtime v0.16.2/go.mod h1:vpMu3LpI5sYWtujJOa2uPK61nB5rbwlN7BAB8aSLvGU= +sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= +sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= +sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= +sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0= +sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= +sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index ef077ba768..d2dc40e3da 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -13,17 +13,17 @@ require ( github.com/go-resty/resty/v2 v2.11.0 github.com/pelletier/go-toml/v2 v2.2.2 github.com/pkg/errors v0.9.1 - github.com/rs/zerolog v1.32.0 + github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 - github.com/smartcontractkit/chainlink-testing-framework v1.34.5 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 + github.com/smartcontractkit/chainlink-testing-framework v1.34.9 + github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 + github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/smartcontractkit/seth v1.1.1 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 - github.com/smartcontractkit/wasp v0.4.7 github.com/stretchr/testify v1.9.0 github.com/wiremock/go-wiremock v1.9.0 go.uber.org/ratelimit v0.3.0 @@ -36,16 +36,35 @@ require ( cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/math v1.3.0 // indirect github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect + github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect + github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.28 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 // indirect + github.com/aws/smithy-go v1.20.4 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect github.com/containerd/errdefs v0.1.0 // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect + github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/testcontainers/testcontainers-go v0.28.0 // indirect - k8s.io/apimachinery v0.30.2 // indirect + github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 // indirect + github.com/smartcontractkit/wasp v0.4.7 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + k8s.io/apimachinery v0.31.0 // indirect ) // avoids ambigious imports of indirect dependencies @@ -104,7 +123,7 @@ require ( github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f // indirect + github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect github.com/cockroachdb/errors v1.10.0 // indirect @@ -165,7 +184,7 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect - github.com/fxamacker/cbor/v2 v2.6.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/solana-go v1.8.4 // indirect @@ -218,7 +237,7 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect + github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/context v1.1.1 // indirect @@ -233,15 +252,15 @@ require ( github.com/grafana/grafana-foundation-sdk/go v0.0.0-20240326122733-6f96a993222b // indirect github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 // indirect github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect - github.com/grafana/pyroscope-go v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect + github.com/grafana/pyroscope-go v1.1.2 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect @@ -291,7 +310,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.7 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -301,7 +320,6 @@ require ( github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect - github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -376,17 +394,15 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect - github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 // indirect - github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 // indirect + github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.8.1 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect - github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cobra v1.8.1 // indirect @@ -401,6 +417,7 @@ require ( github.com/tendermint/go-amino v0.16.0 // indirect github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect github.com/test-go/testify v1.1.4 // indirect + github.com/testcontainers/testcontainers-go v0.28.0 // indirect github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a // indirect github.com/tidwall/btree v1.6.0 // indirect github.com/tidwall/gjson v1.17.0 // indirect @@ -424,16 +441,16 @@ require ( github.com/zondax/ledger-go v0.14.3 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect - go.etcd.io/bbolt v1.3.8 // indirect - go.etcd.io/etcd/api/v3 v3.5.12 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.12 // indirect - go.etcd.io/etcd/client/v3 v3.5.12 // indirect + go.etcd.io/bbolt v1.3.9 // indirect + go.etcd.io/etcd/api/v3 v3.5.14 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect + go.etcd.io/etcd/client/v3 v3.5.14 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 // indirect go.opentelemetry.io/collector/semconv v0.87.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect @@ -447,23 +464,23 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect - golang.org/x/arch v0.7.0 // indirect + golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/time v0.6.0 // indirect + golang.org/x/tools v0.24.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/guregu/null.v4 v4.0.0 // indirect @@ -472,22 +489,22 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.30.2 // indirect - k8s.io/apiextensions-apiserver v0.30.2 // indirect - k8s.io/cli-runtime v0.28.2 // indirect + k8s.io/api v0.31.0 // indirect + k8s.io/apiextensions-apiserver v0.31.0 // indirect + k8s.io/cli-runtime v0.31.0 // indirect k8s.io/client-go v1.5.2 // indirect - k8s.io/component-base v0.30.2 // indirect + k8s.io/component-base v0.31.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect - k8s.io/kubectl v0.28.2 // indirect - k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect + k8s.io/kubectl v0.31.0 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect nhooyr.io/websocket v1.8.10 // indirect pgregory.net/rapid v1.1.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect - sigs.k8s.io/controller-runtime v0.18.4 // indirect + sigs.k8s.io/controller-runtime v0.19.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect - sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/api v0.17.2 // indirect + sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect; indirect nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 3e5d20d303..1072b818b0 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -14,23 +14,27 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= -cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= +cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= +cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= +cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= +cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= +cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= +cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute v1.27.2 h1:5cE5hdrwJV/92ravlwIFRGnyH9CpLGhh4N0ZDVTU+BA= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= +cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw= +cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -40,8 +44,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= -cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= +cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= +cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo= @@ -199,10 +203,38 @@ github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8= +github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= +github.com/aws/aws-sdk-go-v2/config v1.27.28 h1:OTxWGW/91C61QlneCtnD62NLb4W616/NM1jA8LhJqbg= +github.com/aws/aws-sdk-go-v2/config v1.27.28/go.mod h1:uzVRVtJSU5EFv6Fu82AoVFKozJi2ZCY6WRCXj06rbvs= +github.com/aws/aws-sdk-go-v2/credentials v1.17.28 h1:m8+AHY/ND8CMHJnPoH7PJIRakWGa4gbfbxuY9TGTUXM= +github.com/aws/aws-sdk-go-v2/credentials v1.17.28/go.mod h1:6TF7dSc78ehD1SL6KpRIPKMA1GyyWflIkjqg+qmf4+c= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 h1:yjwoSyDZF8Jth+mUk5lSPJCkMC0lMy6FaCD51jm6ayE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12/go.mod h1:fuR57fAgMk7ot3WcNQfb6rSEn+SUffl7ri+aa8uKysI= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 h1:UDXu9dqpCZYonj7poM4kFISjzTdWI0v3WUusM+w+Gfc= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5/go.mod h1:5NPkI3RsTOhwz1CuG7VVSgJCm3CINKkoIaUbUZWQ67w= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.5/go.mod h1:ZeDX1SnKsVlejeuz41GiajjZpRSWR7/42q/EyA/QEiM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 h1:SKvPgvdvmiTWoi0GAJ7AsJfOz3ngVkD/ERbs5pUnHNI= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5/go.mod h1:20sz31hv/WsPa3HhU3hfrIet2kxM4Pe0r20eBZ20Tac= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 h1:iAckBT2OeEK/kBDyN/jDtpEExhjeeA/Im2q4X0rJZT8= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.4/go.mod h1:vmSqFK+BVIwVpDAGZB3CoCXHzurt4qBE8lf+I/kRTh0= github.com/aws/constructs-go/constructs/v10 v10.1.255 h1:5hARfEmhBqHSTQf/C3QLA3sWOxO2Dfja0iA1W7ZcI7g= github.com/aws/constructs-go/constructs/v10 v10.1.255/go.mod h1:DCdBSjN04Ck2pajCacTD4RKFqSA7Utya8d62XreYctI= github.com/aws/jsii-runtime-go v1.75.0 h1:NhpUfyiL7/wsRuUekFsz8FFBCYLfPD/l61kKg9kL/a4= github.com/aws/jsii-runtime-go v1.75.0/go.mod h1:TKCyrtM0pygEPo4rDZzbMSDNCDNTSYSN6/mGyHI6O3I= +github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= +github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= @@ -220,6 +252,8 @@ github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsy github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= @@ -473,8 +507,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= -github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= -github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= @@ -728,8 +762,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= @@ -778,10 +812,10 @@ github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 h1:gdrsYbmk8822v6qv github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503/go.mod h1:d8seWXCEXkL42mhuIJYcGi6DxfehzoIpLrMQWJojvOo= github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 h1:wQ0FnSeebhJIBkgYOD06Mxk9HV2KhtEG0hp/7R+5RUQ= github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0= -github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= -github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= +github.com/grafana/pyroscope-go v1.1.2 h1:7vCfdORYQMCxIzI3NlYAs3FcBP760+gWuYWOyiVyYx8= +github.com/grafana/pyroscope-go v1.1.2/go.mod h1:HSSmHo2KRn6FasBA4vK7BMiQqyQq8KSuBKvrhkXxYPU= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= @@ -801,8 +835,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= @@ -1006,9 +1040,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= -github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -1304,8 +1337,8 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= -github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -1360,34 +1393,36 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc h1:8267l5X5oF2JnGsDaEG4i0JSQO9o0eC61SscTfWc1bk= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240827164549-33f5819d7ddc/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834 h1:pTf4xdcmiWBqWZ6rTy2RMTDBzhHk89VC1pM7jXKQztI= -github.com/smartcontractkit/chainlink-common v0.2.1-0.20240717132349-ee5af9b79834/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949 h1:9YHYswxhxMAgdJhb+APrf57ZEPsxML8H71oxxvU36eU= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828121637-da5837469949/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa h1:g75H8oh2ws52s8BekwvGQ9XvBVu3E7WM1rfiA0PN0zk= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240718160222-2dc0c8136bfa/go.mod h1:wZvLHX/Sd9hskN51016cTFcT3G62KXVa6xbVDS7tRjc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e h1:PzwzlHNv1YbJ6ZIdl/pIFRoOuOS4V4WLvjZvFUnZFL4= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240712132946-267a37c5ac6e/go.mod h1:hsFhop+SlQHKD+DEFjZrMJmbauT1A/wvtZIeeo4PxFU= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.5 h1:6itLSDW4NHDDNR+Y+Z8YDzxxCN9SjdKb6SmLCl0vTFM= -github.com/smartcontractkit/chainlink-testing-framework v1.34.5/go.mod h1:hRZEDh2+afO8MSZb9qYNscmWb+3mHZf01J5ACZuIdTQ= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239 h1:Kk5OVlx/5g9q3Z3lhxytZS4/f8ds1MiNM8yaHgK3Oe8= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240405215812-5a72bc9af239/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= +github.com/smartcontractkit/chainlink-testing-framework v1.34.9 h1:SA7YdICzBmIOFMzLBMAol3CYPyLEF7yKkx63SUrB4RE= +github.com/smartcontractkit/chainlink-testing-framework v1.34.9/go.mod h1:t2au5jHgrDklr25+Nurcy40Bgy5o5VBJvjipmnm6nVc= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a h1:8GtvGJaGyKzx/ar1yX74GxrzIYWTZVTyv4pYB/1ln8w= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= +github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= +github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0 h1:wEc6EKMOOK/9w6z/zv2/wPZsV/txctbYoVJ1sCxhXwI= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.0/go.mod h1:upYGPS9lOBW2pJg6XD8TTNSD1GtRfayU2Ct5bcfvqFw= +github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= +github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= -github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37 h1:ZEhn2Yo1jY4hqy8nasDL4k4pNtopT3rS3Ap1GDb7ODc= -github.com/smartcontractkit/havoc/k8schaos v0.0.0-20240409145249-e78d20847e37/go.mod h1:/kFr0D7SI/vueXl1N03uzOun4nViGPFRyA5X6eL3jXw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= -github.com/smartcontractkit/seth v1.1.1 h1:6hvexjJD7ek8ht/CLlEwQcH21K2E/WEYwbSRdKInZmM= -github.com/smartcontractkit/seth v1.1.1/go.mod h1:cDfKHi/hJLpO9sRpVbrflrHCOV+MJPAMJHloExJnIXk= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= @@ -1562,14 +1597,14 @@ go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRL go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= -go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c= -go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= -go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A= -go.etcd.io/etcd/client/pkg/v3 v3.5.12/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4= -go.etcd.io/etcd/client/v3 v3.5.12 h1:v5lCPXn1pf1Uu3M4laUE2hp/geOTc5uPcYYsNe1lDxg= -go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw= +go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= +go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= +go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= +go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= +go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= +go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= +go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= +go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= @@ -1593,8 +1628,8 @@ go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0. go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= @@ -1607,8 +1642,8 @@ go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6b go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= -go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= +go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= +go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -1646,8 +1681,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= -golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1687,8 +1722,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1713,8 +1748,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1770,8 +1805,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1779,8 +1814,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1882,8 +1917,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1916,8 +1951,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -1979,8 +2014,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2009,8 +2044,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= -google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= +google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= +google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2055,12 +2090,12 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= +google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -2105,6 +2140,8 @@ gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= @@ -2162,8 +2199,8 @@ k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f h1:2sXuKesAYbRHxL3aE2PN6z k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= k8s.io/kubectl v0.28.2 h1:fOWOtU6S0smdNjG1PB9WFbqEIMlkzU5ahyHkc7ESHgM= k8s.io/kubectl v0.28.2/go.mod h1:6EQWTPySF1fn7yKoQZHYf9TPwIl2AygHEcJoxFekr64= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= @@ -2179,10 +2216,10 @@ sigs.k8s.io/controller-runtime v0.16.2 h1:mwXAVuEk3EQf478PQwQ48zGOXvW27UJc8NHktQ sigs.k8s.io/controller-runtime v0.16.2/go.mod h1:vpMu3LpI5sYWtujJOa2uPK61nB5rbwlN7BAB8aSLvGU= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= +sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= +sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0= +sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= +sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= diff --git a/package.json b/package.json index 541cfb1aaf..e8bda4e61a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "ccip", - "version": "2.14.0-ccip1.5.0", + "name": "chainlink", + "version": "2.15.0", "description": "node of the decentralized oracle network, bridging on and off-chain computation", "main": "index.js", "scripts": { @@ -9,14 +9,14 @@ "private": true, "repository": { "type": "git", - "url": "git+ssh://git@github.com/smartcontractkit/ccip.git" + "url": "git+ssh://git@github.com/smartcontractkit/chainlink.git" }, "author": "smartcontractkit", "license": "MIT", "bugs": { - "url": "https://github.com/smartcontractkit/ccip/issues" + "url": "https://github.com/smartcontractkit/chainlink/issues" }, - "homepage": "https://github.com/smartcontractkit/ccip#readme", + "homepage": "https://github.com/smartcontractkit/chainlink#readme", "engines": { "node": ">=18", "pnpm": ">=9" @@ -24,7 +24,6 @@ "devDependencies": { "@changesets/changelog-github": "^0.4.8", "@changesets/cli": "~2.26.2", - "husky": "^9.0.11", "semver": "^7.6.1" } -} +} \ No newline at end of file From 5fe6efff80ddcc7b0be3f5ce42171685297d45b3 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Wed, 28 Aug 2024 18:23:18 -0700 Subject: [PATCH 235/432] Use repo var for JIRA_HOST (#14270) --- .github/workflows/changeset.yml | 2 +- .github/workflows/solidity-foundry-artifacts.yml | 2 +- .github/workflows/solidity-tracability.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/changeset.yml b/.github/workflows/changeset.yml index a89e91171e..0d8c3a828b 100644 --- a/.github/workflows/changeset.yml +++ b/.github/workflows/changeset.yml @@ -92,7 +92,7 @@ jobs: pnpm install && pnpm issue:update env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - JIRA_HOST: ${{ secrets.JIRA_HOST }} + JIRA_HOST: ${{ vars.JIRA_HOST }} JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} CHAINLINK_VERSION: ${{ steps.chainlink-version.outputs.chainlink_version }} diff --git a/.github/workflows/solidity-foundry-artifacts.yml b/.github/workflows/solidity-foundry-artifacts.yml index 5f03acbe1d..647ed33257 100644 --- a/.github/workflows/solidity-foundry-artifacts.yml +++ b/.github/workflows/solidity-foundry-artifacts.yml @@ -404,7 +404,7 @@ jobs: HEAD_REF: ${{ env.head_ref }} ARTIFACT_URL: ${{ steps.gather-all-artifacts.outputs.artifact-url }} - JIRA_HOST: https://smartcontract-it.atlassian.net/ + JIRA_HOST: ${{ vars.JIRA_HOST }} JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} diff --git a/.github/workflows/solidity-tracability.yml b/.github/workflows/solidity-tracability.yml index 4acf94688a..9c61d4adbc 100644 --- a/.github/workflows/solidity-tracability.yml +++ b/.github/workflows/solidity-tracability.yml @@ -107,7 +107,7 @@ jobs: PR_TITLE: ${{ github.event.pull_request.title }} BRANCH_NAME: ${{ github.event.pull_request.head.ref }} - JIRA_HOST: https://smartcontract-it.atlassian.net/ + JIRA_HOST: ${{ vars.JIRA_HOST }} JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} From 7f69993c8655053b7550f50b817ba9c6888037e2 Mon Sep 17 00:00:00 2001 From: Graham Goh Date: Thu, 29 Aug 2024 16:50:49 +1000 Subject: [PATCH 236/432] [OPCORE-863]: fix(service): start multiple feeds managers (#14197) * fix(service): start multiple feeds managers In order to support connection to multiple feed managers, when on start of the node, we want to attempt to connect to list of registered feed managers. * fix: feature flag for multi feeds managers Introduce a new feature flag for enabling support for multi feeds managers. * refactor(service): delete ListJobProposals No longer used, since it was replaced by ListJobProposalsByManagersIDs * [OPCORE-855]: fix: support creating more than 1 manager (#14225) --------- Co-authored-by: Margaret Ma --- .changeset/gorgeous-lobsters-argue.md | 5 + .changeset/moody-turkeys-provide.md | 5 + core/config/app_config.go | 2 + core/config/docs/core.toml | 2 + core/config/feature_config.go | 1 + core/config/toml/types.go | 12 +- core/services/chainlink/config_feature.go | 4 + .../services/chainlink/config_feature_test.go | 1 + core/services/chainlink/config_general.go | 4 + core/services/chainlink/config_test.go | 10 +- .../chainlink/mocks/general_config.go | 45 +++++ .../testdata/config-empty-effective.toml | 1 + .../chainlink/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 1 + core/services/feeds/config.go | 1 + core/services/feeds/mocks/orm.go | 117 ++++++------- core/services/feeds/mocks/service.go | 114 ------------- core/services/feeds/orm.go | 33 ++-- core/services/feeds/orm_test.go | 62 +++---- core/services/feeds/service.go | 61 ++++--- core/services/feeds/service_test.go | 159 +++++++++++++----- core/web/features_controller.go | 6 +- core/web/features_controller_test.go | 6 +- core/web/resolver/features.go | 5 + core/web/resolver/features_test.go | 5 +- core/web/resolver/feeds_manager.go | 29 ++++ core/web/resolver/feeds_manager_test.go | 23 +++ core/web/resolver/mutation.go | 2 +- .../testdata/config-empty-effective.toml | 1 + core/web/resolver/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 1 + core/web/schema/type/features.graphql | 1 + core/web/schema/type/feeds_manager.graphql | 10 +- docs/CONFIG.md | 7 + testdata/scripts/node/validate/default.txtar | 1 + .../disk-based-logging-disabled.txtar | 1 + .../validate/disk-based-logging-no-dir.txtar | 1 + .../node/validate/disk-based-logging.txtar | 1 + .../node/validate/invalid-ocr-p2p.txtar | 1 + testdata/scripts/node/validate/invalid.txtar | 1 + testdata/scripts/node/validate/valid.txtar | 1 + testdata/scripts/node/validate/warnings.txtar | 1 + 42 files changed, 445 insertions(+), 301 deletions(-) create mode 100644 .changeset/gorgeous-lobsters-argue.md create mode 100644 .changeset/moody-turkeys-provide.md diff --git a/.changeset/gorgeous-lobsters-argue.md b/.changeset/gorgeous-lobsters-argue.md new file mode 100644 index 0000000000..e1960eb61c --- /dev/null +++ b/.changeset/gorgeous-lobsters-argue.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#changed Connect to multiple feeds managers on app start instead of just one (default to first) diff --git a/.changeset/moody-turkeys-provide.md b/.changeset/moody-turkeys-provide.md new file mode 100644 index 0000000000..5a89e4596e --- /dev/null +++ b/.changeset/moody-turkeys-provide.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#changed Allow registration of more than 1 feeds manager on CreateFeedsManager diff --git a/core/config/app_config.go b/core/config/app_config.go index 112e242636..27d56bb4cb 100644 --- a/core/config/app_config.go +++ b/core/config/app_config.go @@ -56,6 +56,8 @@ type AppConfig interface { Threshold() Threshold WebServer() WebServer Tracing() Tracing + + FeatureMultiFeedsManagers() bool } type DatabaseBackupMode string diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index d0960779c6..3783689db3 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -15,6 +15,8 @@ LogPoller = false # Default UICSAKeys = false # Default # CCIP enables the CCIP service. CCIP = true # Default +# MultiFeedsManagers enables support for multiple feeds manager connections. +MultiFeedsManagers = false # Default [Database] # DefaultIdleInTxSessionTimeout is the maximum time allowed for a transaction to be open and idle before timing out. See Postgres `idle_in_transaction_session_timeout` for more details. diff --git a/core/config/feature_config.go b/core/config/feature_config.go index fbb3a4ea54..200a1fd8ed 100644 --- a/core/config/feature_config.go +++ b/core/config/feature_config.go @@ -4,4 +4,5 @@ type Feature interface { FeedsManager() bool UICSAKeys() bool LogPoller() bool + MultiFeedsManagers() bool } diff --git a/core/config/toml/types.go b/core/config/toml/types.go index 0c91ddd81a..427e3f01cb 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -300,10 +300,11 @@ func (p *PrometheusSecrets) validateMerge(f *PrometheusSecrets) (err error) { } type Feature struct { - FeedsManager *bool - LogPoller *bool - UICSAKeys *bool - CCIP *bool + FeedsManager *bool + LogPoller *bool + UICSAKeys *bool + CCIP *bool + MultiFeedsManagers *bool } func (f *Feature) setFrom(f2 *Feature) { @@ -319,6 +320,9 @@ func (f *Feature) setFrom(f2 *Feature) { if v := f2.CCIP; v != nil { f.CCIP = v } + if v := f2.MultiFeedsManagers; v != nil { + f.MultiFeedsManagers = v + } } type Database struct { diff --git a/core/services/chainlink/config_feature.go b/core/services/chainlink/config_feature.go index 2e968df052..f5cc878641 100644 --- a/core/services/chainlink/config_feature.go +++ b/core/services/chainlink/config_feature.go @@ -17,3 +17,7 @@ func (f *featureConfig) LogPoller() bool { func (f *featureConfig) UICSAKeys() bool { return *f.c.UICSAKeys } + +func (f *featureConfig) MultiFeedsManagers() bool { + return *f.c.MultiFeedsManagers +} diff --git a/core/services/chainlink/config_feature_test.go b/core/services/chainlink/config_feature_test.go index bc0418c157..8fa5884450 100644 --- a/core/services/chainlink/config_feature_test.go +++ b/core/services/chainlink/config_feature_test.go @@ -18,4 +18,5 @@ func TestFeatureConfig(t *testing.T) { assert.True(t, f.LogPoller()) assert.True(t, f.FeedsManager()) assert.True(t, f.UICSAKeys()) + assert.True(t, f.MultiFeedsManagers()) } diff --git a/core/services/chainlink/config_general.go b/core/services/chainlink/config_general.go index 79c92f8214..d329fb0fac 100644 --- a/core/services/chainlink/config_general.go +++ b/core/services/chainlink/config_general.go @@ -282,6 +282,10 @@ func (g *generalConfig) FeatureFeedsManager() bool { return *g.c.Feature.FeedsManager } +func (g *generalConfig) FeatureMultiFeedsManagers() bool { + return *g.c.Feature.MultiFeedsManagers +} + func (g *generalConfig) OCR() config.OCR { return &ocrConfig{c: g.c.OCR} } diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 56b0661854..17c059cba9 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -258,10 +258,11 @@ func TestConfig_Marshal(t *testing.T) { } full.Feature = toml.Feature{ - FeedsManager: ptr(true), - LogPoller: ptr(true), - UICSAKeys: ptr(true), - CCIP: ptr(true), + FeedsManager: ptr(true), + LogPoller: ptr(true), + UICSAKeys: ptr(true), + CCIP: ptr(true), + MultiFeedsManagers: ptr(true), } full.Database = toml.Database{ DefaultIdleInTxSessionTimeout: commoncfg.MustNewDuration(time.Minute), @@ -775,6 +776,7 @@ FeedsManager = true LogPoller = true UICSAKeys = true CCIP = true +MultiFeedsManagers = true `}, {"Database", Config{Core: toml.Core{Database: full.Database}}, `[Database] DefaultIdleInTxSessionTimeout = '1m0s' diff --git a/core/services/chainlink/mocks/general_config.go b/core/services/chainlink/mocks/general_config.go index f4594a4322..2339cf9656 100644 --- a/core/services/chainlink/mocks/general_config.go +++ b/core/services/chainlink/mocks/general_config.go @@ -694,6 +694,51 @@ func (_c *GeneralConfig_Feature_Call) RunAndReturn(run func() config.Feature) *G return _c } +// FeatureMultiFeedsManagers provides a mock function with given fields: +func (_m *GeneralConfig) FeatureMultiFeedsManagers() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for FeatureMultiFeedsManagers") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// GeneralConfig_FeatureMultiFeedsManagers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FeatureMultiFeedsManagers' +type GeneralConfig_FeatureMultiFeedsManagers_Call struct { + *mock.Call +} + +// FeatureMultiFeedsManagers is a helper method to define mock.On call +func (_e *GeneralConfig_Expecter) FeatureMultiFeedsManagers() *GeneralConfig_FeatureMultiFeedsManagers_Call { + return &GeneralConfig_FeatureMultiFeedsManagers_Call{Call: _e.mock.On("FeatureMultiFeedsManagers")} +} + +func (_c *GeneralConfig_FeatureMultiFeedsManagers_Call) Run(run func()) *GeneralConfig_FeatureMultiFeedsManagers_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *GeneralConfig_FeatureMultiFeedsManagers_Call) Return(_a0 bool) *GeneralConfig_FeatureMultiFeedsManagers_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GeneralConfig_FeatureMultiFeedsManagers_Call) RunAndReturn(run func() bool) *GeneralConfig_FeatureMultiFeedsManagers_Call { + _c.Call.Return(run) + return _c +} + // FluxMonitor provides a mock function with given fields: func (_m *GeneralConfig) FluxMonitor() config.FluxMonitor { ret := _m.Called() diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index f1325d824e..d549e4024e 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -7,6 +7,7 @@ FeedsManager = true LogPoller = false UICSAKeys = false CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index ff044fff58..af41766a6c 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -7,6 +7,7 @@ FeedsManager = true LogPoller = true UICSAKeys = true CCIP = true +MultiFeedsManagers = true [Database] DefaultIdleInTxSessionTimeout = '1m0s' diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 8bfc93c7be..640e6708bd 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -7,6 +7,7 @@ FeedsManager = true LogPoller = false UICSAKeys = false CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/core/services/feeds/config.go b/core/services/feeds/config.go index e2ec889b23..690117a510 100644 --- a/core/services/feeds/config.go +++ b/core/services/feeds/config.go @@ -10,6 +10,7 @@ import ( type GeneralConfig interface { OCR() coreconfig.OCR Insecure() coreconfig.Insecure + FeatureMultiFeedsManagers() bool } type JobConfig interface { diff --git a/core/services/feeds/mocks/orm.go b/core/services/feeds/mocks/orm.go index 3fce89eb60..d6cae81dc6 100644 --- a/core/services/feeds/mocks/orm.go +++ b/core/services/feeds/mocks/orm.go @@ -6,6 +6,8 @@ import ( context "context" feeds "github.com/smartcontractkit/chainlink/v2/core/services/feeds" + crypto "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" + mock "github.com/stretchr/testify/mock" sqlutil "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" @@ -1269,64 +1271,6 @@ func (_c *ORM_ListChainConfigsByManagerIDs_Call) RunAndReturn(run func(context.C return _c } -// ListJobProposals provides a mock function with given fields: ctx -func (_m *ORM) ListJobProposals(ctx context.Context) ([]feeds.JobProposal, error) { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for ListJobProposals") - } - - var r0 []feeds.JobProposal - var r1 error - if rf, ok := ret.Get(0).(func(context.Context) ([]feeds.JobProposal, error)); ok { - return rf(ctx) - } - if rf, ok := ret.Get(0).(func(context.Context) []feeds.JobProposal); ok { - r0 = rf(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]feeds.JobProposal) - } - } - - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(ctx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ORM_ListJobProposals_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListJobProposals' -type ORM_ListJobProposals_Call struct { - *mock.Call -} - -// ListJobProposals is a helper method to define mock.On call -// - ctx context.Context -func (_e *ORM_Expecter) ListJobProposals(ctx interface{}) *ORM_ListJobProposals_Call { - return &ORM_ListJobProposals_Call{Call: _e.mock.On("ListJobProposals", ctx)} -} - -func (_c *ORM_ListJobProposals_Call) Run(run func(ctx context.Context)) *ORM_ListJobProposals_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *ORM_ListJobProposals_Call) Return(jps []feeds.JobProposal, err error) *ORM_ListJobProposals_Call { - _c.Call.Return(jps, err) - return _c -} - -func (_c *ORM_ListJobProposals_Call) RunAndReturn(run func(context.Context) ([]feeds.JobProposal, error)) *ORM_ListJobProposals_Call { - _c.Call.Return(run) - return _c -} - // ListJobProposalsByManagersIDs provides a mock function with given fields: ctx, ids func (_m *ORM) ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]feeds.JobProposal, error) { ret := _m.Called(ctx, ids) @@ -1562,6 +1506,63 @@ func (_c *ORM_ListSpecsByJobProposalIDs_Call) RunAndReturn(run func(context.Cont return _c } +// ManagerExists provides a mock function with given fields: ctx, publicKey +func (_m *ORM) ManagerExists(ctx context.Context, publicKey crypto.PublicKey) (bool, error) { + ret := _m.Called(ctx, publicKey) + + if len(ret) == 0 { + panic("no return value specified for ManagerExists") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, crypto.PublicKey) (bool, error)); ok { + return rf(ctx, publicKey) + } + if rf, ok := ret.Get(0).(func(context.Context, crypto.PublicKey) bool); ok { + r0 = rf(ctx, publicKey) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context, crypto.PublicKey) error); ok { + r1 = rf(ctx, publicKey) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ORM_ManagerExists_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ManagerExists' +type ORM_ManagerExists_Call struct { + *mock.Call +} + +// ManagerExists is a helper method to define mock.On call +// - ctx context.Context +// - publicKey crypto.PublicKey +func (_e *ORM_Expecter) ManagerExists(ctx interface{}, publicKey interface{}) *ORM_ManagerExists_Call { + return &ORM_ManagerExists_Call{Call: _e.mock.On("ManagerExists", ctx, publicKey)} +} + +func (_c *ORM_ManagerExists_Call) Run(run func(ctx context.Context, publicKey crypto.PublicKey)) *ORM_ManagerExists_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(crypto.PublicKey)) + }) + return _c +} + +func (_c *ORM_ManagerExists_Call) Return(_a0 bool, _a1 error) *ORM_ManagerExists_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ORM_ManagerExists_Call) RunAndReturn(run func(context.Context, crypto.PublicKey) (bool, error)) *ORM_ManagerExists_Call { + _c.Call.Return(run) + return _c +} + // RejectSpec provides a mock function with given fields: ctx, id func (_m *ORM) RejectSpec(ctx context.Context, id int64) error { ret := _m.Called(ctx, id) diff --git a/core/services/feeds/mocks/service.go b/core/services/feeds/mocks/service.go index d37c327850..d84879bb70 100644 --- a/core/services/feeds/mocks/service.go +++ b/core/services/feeds/mocks/service.go @@ -220,62 +220,6 @@ func (_c *Service_CountJobProposalsByStatus_Call) RunAndReturn(run func(context. return _c } -// CountManagers provides a mock function with given fields: ctx -func (_m *Service) CountManagers(ctx context.Context) (int64, error) { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for CountManagers") - } - - var r0 int64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context) (int64, error)); ok { - return rf(ctx) - } - if rf, ok := ret.Get(0).(func(context.Context) int64); ok { - r0 = rf(ctx) - } else { - r0 = ret.Get(0).(int64) - } - - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(ctx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Service_CountManagers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CountManagers' -type Service_CountManagers_Call struct { - *mock.Call -} - -// CountManagers is a helper method to define mock.On call -// - ctx context.Context -func (_e *Service_Expecter) CountManagers(ctx interface{}) *Service_CountManagers_Call { - return &Service_CountManagers_Call{Call: _e.mock.On("CountManagers", ctx)} -} - -func (_c *Service_CountManagers_Call) Run(run func(ctx context.Context)) *Service_CountManagers_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *Service_CountManagers_Call) Return(_a0 int64, _a1 error) *Service_CountManagers_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *Service_CountManagers_Call) RunAndReturn(run func(context.Context) (int64, error)) *Service_CountManagers_Call { - _c.Call.Return(run) - return _c -} - // CreateChainConfig provides a mock function with given fields: ctx, cfg func (_m *Service) CreateChainConfig(ctx context.Context, cfg feeds.ChainConfig) (int64, error) { ret := _m.Called(ctx, cfg) @@ -799,64 +743,6 @@ func (_c *Service_ListChainConfigsByManagerIDs_Call) RunAndReturn(run func(conte return _c } -// ListJobProposals provides a mock function with given fields: ctx -func (_m *Service) ListJobProposals(ctx context.Context) ([]feeds.JobProposal, error) { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for ListJobProposals") - } - - var r0 []feeds.JobProposal - var r1 error - if rf, ok := ret.Get(0).(func(context.Context) ([]feeds.JobProposal, error)); ok { - return rf(ctx) - } - if rf, ok := ret.Get(0).(func(context.Context) []feeds.JobProposal); ok { - r0 = rf(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]feeds.JobProposal) - } - } - - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(ctx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Service_ListJobProposals_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListJobProposals' -type Service_ListJobProposals_Call struct { - *mock.Call -} - -// ListJobProposals is a helper method to define mock.On call -// - ctx context.Context -func (_e *Service_Expecter) ListJobProposals(ctx interface{}) *Service_ListJobProposals_Call { - return &Service_ListJobProposals_Call{Call: _e.mock.On("ListJobProposals", ctx)} -} - -func (_c *Service_ListJobProposals_Call) Run(run func(ctx context.Context)) *Service_ListJobProposals_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *Service_ListJobProposals_Call) Return(_a0 []feeds.JobProposal, _a1 error) *Service_ListJobProposals_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *Service_ListJobProposals_Call) RunAndReturn(run func(context.Context) ([]feeds.JobProposal, error)) *Service_ListJobProposals_Call { - _c.Call.Return(run) - return _c -} - // ListJobProposalsByManagersIDs provides a mock function with given fields: ctx, ids func (_m *Service) ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]feeds.JobProposal, error) { ret := _m.Called(ctx, ids) diff --git a/core/services/feeds/orm.go b/core/services/feeds/orm.go index d130316fb2..7f1e019417 100644 --- a/core/services/feeds/orm.go +++ b/core/services/feeds/orm.go @@ -9,11 +9,13 @@ import ( "github.com/google/uuid" "github.com/lib/pq" "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" ) type ORM interface { + ManagerExists(ctx context.Context, publicKey crypto.PublicKey) (bool, error) CountManagers(ctx context.Context) (int64, error) CreateManager(ctx context.Context, ms *FeedsManager) (int64, error) GetManager(ctx context.Context, id int64) (*FeedsManager, error) @@ -34,7 +36,6 @@ type ORM interface { DeleteProposal(ctx context.Context, id int64) error GetJobProposal(ctx context.Context, id int64) (*JobProposal, error) GetJobProposalByRemoteUUID(ctx context.Context, uuid uuid.UUID) (*JobProposal, error) - ListJobProposals(ctx context.Context) (jps []JobProposal, err error) ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]JobProposal, error) UpdateJobProposalStatus(ctx context.Context, id int64, status JobProposalStatus) error // NEEDED? UpsertJobProposal(ctx context.Context, jp *JobProposal) (int64, error) @@ -74,6 +75,7 @@ func (o *orm) Transact(ctx context.Context, fn func(ORM) error) error { func (o *orm) WithDataSource(ds sqlutil.DataSource) ORM { return &orm{ds} } // Count counts the number of feeds manager records. +// TODO: delete once multiple feeds managers support is released func (o *orm) CountManagers(ctx context.Context) (count int64, err error) { stmt := ` SELECT COUNT(*) @@ -84,6 +86,21 @@ FROM feeds_managers return count, errors.Wrap(err, "CountManagers failed") } +// ManagerExists checks if a feeds manager exists by public key. +func (o *orm) ManagerExists(ctx context.Context, publicKey crypto.PublicKey) (bool, error) { + stmt := ` +SELECT EXISTS ( + SELECT 1 + FROM feeds_managers + WHERE public_key = $1 +); + ` + + var exists bool + err := o.ds.GetContext(ctx, &exists, stmt, publicKey) + return exists, errors.Wrap(err, "ManagerExists failed") +} + // CreateManager creates a feeds manager. func (o *orm) CreateManager(ctx context.Context, ms *FeedsManager) (id int64, err error) { stmt := ` @@ -264,7 +281,8 @@ WHERE id = $1 func (o *orm) ListManagers(ctx context.Context) (mgrs []FeedsManager, err error) { stmt := ` SELECT id, name, uri, public_key, created_at, updated_at -FROM feeds_managers; +FROM feeds_managers +ORDER BY created_at; ` err = o.ds.SelectContext(ctx, &mgrs, stmt) @@ -373,17 +391,6 @@ AND status <> $2; return jp, errors.Wrap(err, "GetJobProposalByRemoteUUID failed") } -// ListJobProposals lists all job proposals. -func (o *orm) ListJobProposals(ctx context.Context) (jps []JobProposal, err error) { - stmt := ` -SELECT * -FROM job_proposals; -` - - err = o.ds.SelectContext(ctx, &jps, stmt) - return jps, errors.Wrap(err, "ListJobProposals failed") -} - // ListJobProposalsByManagersIDs gets job proposals by feeds managers IDs. func (o *orm) ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]JobProposal, error) { stmt := ` diff --git a/core/services/feeds/orm_test.go b/core/services/feeds/orm_test.go index c4c9ced2ce..4ff1a85aea 100644 --- a/core/services/feeds/orm_test.go +++ b/core/services/feeds/orm_test.go @@ -53,7 +53,7 @@ func setupORM(t *testing.T) *TestORM { // Managers -func Test_ORM_CreateManager(t *testing.T) { +func Test_ORM_CreateManager_CountManagers(t *testing.T) { t.Parallel() ctx := testutils.Context(t) @@ -80,6 +80,33 @@ func Test_ORM_CreateManager(t *testing.T) { assert.NotZero(t, id) } +func Test_ORM_CreateManager(t *testing.T) { + t.Parallel() + ctx := testutils.Context(t) + + var ( + orm = setupORM(t) + mgr = &feeds.FeedsManager{ + URI: uri, + Name: name, + PublicKey: publicKey, + } + ) + + exists, err := orm.ManagerExists(ctx, publicKey) + require.NoError(t, err) + require.Equal(t, false, exists) + + id, err := orm.CreateManager(ctx, mgr) + require.NoError(t, err) + + exists, err = orm.ManagerExists(ctx, publicKey) + require.NoError(t, err) + require.Equal(t, true, exists) + + assert.NotZero(t, id) +} + func Test_ORM_GetManager(t *testing.T) { t.Parallel() ctx := testutils.Context(t) @@ -555,39 +582,6 @@ func Test_ORM_GetJobProposal(t *testing.T) { }) } -func Test_ORM_ListJobProposals(t *testing.T) { - t.Parallel() - ctx := testutils.Context(t) - - orm := setupORM(t) - fmID := createFeedsManager(t, orm) - uuid := uuid.New() - name := null.StringFrom("jp1") - - jp := &feeds.JobProposal{ - Name: name, - RemoteUUID: uuid, - Status: feeds.JobProposalStatusPending, - FeedsManagerID: fmID, - } - - id, err := orm.CreateJobProposal(ctx, jp) - require.NoError(t, err) - - jps, err := orm.ListJobProposals(ctx) - require.NoError(t, err) - require.Len(t, jps, 1) - - actual := jps[0] - assert.Equal(t, id, actual.ID) - assert.Equal(t, name, actual.Name) - assert.Equal(t, uuid, actual.RemoteUUID) - assert.Equal(t, jp.Status, actual.Status) - assert.False(t, actual.ExternalJobID.Valid) - assert.False(t, actual.PendingUpdate) - assert.Equal(t, jp.FeedsManagerID, actual.FeedsManagerID) -} - func Test_ORM_CountJobProposalsByStatus(t *testing.T) { t.Parallel() diff --git a/core/services/feeds/service.go b/core/services/feeds/service.go index 5e8e743109..9671900309 100644 --- a/core/services/feeds/service.go +++ b/core/services/feeds/service.go @@ -37,11 +37,13 @@ import ( ) var ( - ErrOCR2Disabled = errors.New("ocr2 is disabled") - ErrOCRDisabled = errors.New("ocr is disabled") - ErrSingleFeedsManager = errors.New("only a single feeds manager is supported") - ErrJobAlreadyExists = errors.New("a job for this contract address already exists - please use the 'force' option to replace it") - ErrFeedsManagerDisabled = errors.New("feeds manager is disabled") + ErrOCR2Disabled = errors.New("ocr2 is disabled") + ErrOCRDisabled = errors.New("ocr is disabled") + // TODO: delete once multiple feeds managers support is released + ErrSingleFeedsManager = errors.New("only a single feeds manager is supported") + ErrDuplicateFeedsManager = errors.New("manager was previously registered using the same public key") + ErrJobAlreadyExists = errors.New("a job for this contract address already exists - please use the 'force' option to replace it") + ErrFeedsManagerDisabled = errors.New("feeds manager is disabled") promJobProposalRequest = promauto.NewCounter(prometheus.CounterOpts{ Name: "feeds_job_proposal_requests", @@ -77,7 +79,6 @@ type Service interface { Start(ctx context.Context) error Close() error - CountManagers(ctx context.Context) (int64, error) GetManager(ctx context.Context, id int64) (*FeedsManager, error) ListManagers(ctx context.Context) ([]FeedsManager, error) ListManagersByIDs(ctx context.Context, ids []int64) ([]FeedsManager, error) @@ -98,7 +99,6 @@ type Service interface { CountJobProposalsByStatus(ctx context.Context) (*JobProposalCounts, error) GetJobProposal(ctx context.Context, id int64) (*JobProposal, error) - ListJobProposals(ctx context.Context) ([]JobProposal, error) ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]JobProposal, error) ApproveSpec(ctx context.Context, id int64, force bool) error @@ -186,15 +186,23 @@ type RegisterManagerParams struct { // RegisterManager registers a new ManagerService and attempts to establish a // connection. -// -// Only a single feeds manager is currently supported. func (s *service) RegisterManager(ctx context.Context, params RegisterManagerParams) (int64, error) { - count, err := s.CountManagers(ctx) - if err != nil { - return 0, err - } - if count >= 1 { - return 0, ErrSingleFeedsManager + if s.gCfg.FeatureMultiFeedsManagers() { + exists, err := s.orm.ManagerExists(ctx, params.PublicKey) + if err != nil { + return 0, err + } + if exists { + return 0, ErrDuplicateFeedsManager + } + } else { + count, err := s.CountManagers(ctx) + if err != nil { + return 0, err + } + if count >= 1 { + return 0, ErrSingleFeedsManager + } } mgr := FeedsManager{ @@ -205,7 +213,7 @@ func (s *service) RegisterManager(ctx context.Context, params RegisterManagerPar var id int64 - err = s.orm.Transact(ctx, func(tx ORM) error { + err := s.orm.Transact(ctx, func(tx ORM) error { var txerr error id, txerr = tx.CreateManager(ctx, &mgr) @@ -325,6 +333,7 @@ func (s *service) ListManagersByIDs(ctx context.Context, ids []int64) ([]FeedsMa } // CountManagers gets the total number of manager services +// TODO: delete once multiple feeds managers support is released func (s *service) CountManagers(ctx context.Context) (int64, error) { return s.orm.CountManagers(ctx) } @@ -421,14 +430,6 @@ func (s *service) UpdateChainConfig(ctx context.Context, cfg ChainConfig) (int64 return id, nil } -// Lists all JobProposals -// -// When we support multiple feed managers, we will need to change this to filter -// by feeds manager -func (s *service) ListJobProposals(ctx context.Context) ([]JobProposal, error) { - return s.orm.ListJobProposals(ctx) -} - // ListJobProposalsByManagersIDs gets job proposals by feeds managers IDs func (s *service) ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]JobProposal, error) { return s.orm.ListJobProposalsByManagersIDs(ctx, ids) @@ -1023,7 +1024,6 @@ func (s *service) Start(ctx context.Context) error { return err } - // We only support a single feeds manager right now mgrs, err := s.ListManagers(ctx) if err != nil { return err @@ -1034,8 +1034,14 @@ func (s *service) Start(ctx context.Context) error { return nil } - mgr := mgrs[0] - s.connectFeedManager(ctx, mgr, privkey) + if s.gCfg.FeatureMultiFeedsManagers() { + s.lggr.Infof("starting connection to %d feeds managers", len(mgrs)) + for _, mgr := range mgrs { + s.connectFeedManager(ctx, mgr, privkey) + } + } else { + s.connectFeedManager(ctx, mgrs[0], privkey) + } if err = s.observeJobProposalCounts(ctx); err != nil { s.lggr.Error("failed to observe job proposal count when starting service", err) @@ -1450,7 +1456,6 @@ func (ns NullService) Close() error { return nil } func (ns NullService) ApproveSpec(ctx context.Context, id int64, force bool) error { return ErrFeedsManagerDisabled } -func (ns NullService) CountManagers(ctx context.Context) (int64, error) { return 0, nil } func (ns NullService) CountJobProposalsByStatus(ctx context.Context) (*JobProposalCounts, error) { return nil, ErrFeedsManagerDisabled } diff --git a/core/services/feeds/service_test.go b/core/services/feeds/service_test.go index e98ae984fb..41c62ea5e0 100644 --- a/core/services/feeds/service_test.go +++ b/core/services/feeds/service_test.go @@ -265,6 +265,63 @@ func Test_Service_RegisterManager(t *testing.T) { assert.Equal(t, actual, id) } +func Test_Service_RegisterManager_MultiFeedsManager(t *testing.T) { + t.Parallel() + + key := cltest.DefaultCSAKey + + var ( + id = int64(1) + pubKeyHex = "0f17c3bf72de8beef6e2d17a14c0a972f5d7e0e66e70722373f12b88382d40f9" + ) + + var pubKey crypto.PublicKey + _, err := hex.Decode([]byte(pubKeyHex), pubKey) + require.NoError(t, err) + + var ( + mgr = feeds.FeedsManager{ + Name: "FMS", + URI: "localhost:8080", + PublicKey: pubKey, + } + params = feeds.RegisterManagerParams{ + Name: "FMS", + URI: "localhost:8080", + PublicKey: pubKey, + } + ) + + svc := setupTestServiceCfg(t, func(c *chainlink.Config, s *chainlink.Secrets) { + var multiFeedsManagers = true + c.Feature.MultiFeedsManagers = &multiFeedsManagers + }) + ctx := testutils.Context(t) + + svc.orm.On("ManagerExists", ctx, params.PublicKey).Return(false, nil) + svc.orm.On("CreateManager", mock.Anything, &mgr, mock.Anything). + Return(id, nil) + svc.orm.On("CreateBatchChainConfig", mock.Anything, params.ChainConfigs, mock.Anything). + Return([]int64{}, nil) + svc.csaKeystore.On("GetAll").Return([]csakey.KeyV2{key}, nil) + // ListManagers runs in a goroutine so it might be called. + svc.orm.On("ListManagers", ctx).Return([]feeds.FeedsManager{mgr}, nil).Maybe() + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) + svc.connMgr.On("Connect", mock.IsType(feeds.ConnectOpts{})) + + actual, err := svc.RegisterManager(ctx, params) + // We need to stop the service because the manager will attempt to make a + // connection + svc.Close() + require.NoError(t, err) + + assert.Equal(t, actual, id) +} + func Test_Service_RegisterManager_InvalidCreateManager(t *testing.T) { t.Parallel() @@ -311,6 +368,45 @@ func Test_Service_RegisterManager_InvalidCreateManager(t *testing.T) { assert.Equal(t, "orm error", err.Error()) } +func Test_Service_RegisterManager_DuplicateFeedsManager(t *testing.T) { + t.Parallel() + + var pubKeyHex = "0f17c3bf72de8beef6e2d17a14c0a972f5d7e0e66e70722373f12b88382d40f9" + var pubKey crypto.PublicKey + _, err := hex.Decode([]byte(pubKeyHex), pubKey) + + var ( + mgr = feeds.FeedsManager{ + Name: "FMS", + URI: "localhost:8080", + PublicKey: pubKey, + } + params = feeds.RegisterManagerParams{ + Name: "FMS", + URI: "localhost:8080", + PublicKey: pubKey, + } + ) + + svc := setupTestServiceCfg(t, func(c *chainlink.Config, s *chainlink.Secrets) { + var multiFeedsManagers = true + c.Feature.MultiFeedsManagers = &multiFeedsManagers + }) + ctx := testutils.Context(t) + + svc.orm.On("ManagerExists", ctx, params.PublicKey).Return(true, nil) + // ListManagers runs in a goroutine so it might be called. + svc.orm.On("ListManagers", ctx).Return([]feeds.FeedsManager{mgr}, nil).Maybe() + + _, err = svc.RegisterManager(ctx, params) + // We need to stop the service because the manager will attempt to make a + // connection + svc.Close() + require.Error(t, err) + + assert.Equal(t, "manager was previously registered using the same public key", err.Error()) +} + func Test_Service_ListManagers(t *testing.T) { t.Parallel() ctx := testutils.Context(t) @@ -388,24 +484,6 @@ func Test_Service_ListManagersByIDs(t *testing.T) { assert.Equal(t, mgrs, actual) } -func Test_Service_CountManagers(t *testing.T) { - t.Parallel() - ctx := testutils.Context(t) - - var ( - count = int64(1) - ) - svc := setupTestService(t) - - svc.orm.On("CountManagers", mock.Anything). - Return(count, nil) - - actual, err := svc.CountManagers(ctx) - require.NoError(t, err) - - assert.Equal(t, count, actual) -} - func Test_Service_CreateChainConfig(t *testing.T) { var ( mgr = feeds.FeedsManager{ID: 1} @@ -1527,25 +1605,6 @@ func Test_Service_IsJobManaged(t *testing.T) { assert.True(t, isManaged) } -func Test_Service_ListJobProposals(t *testing.T) { - t.Parallel() - ctx := testutils.Context(t) - - var ( - jp = feeds.JobProposal{} - jps = []feeds.JobProposal{jp} - ) - svc := setupTestService(t) - - svc.orm.On("ListJobProposals", mock.Anything). - Return(jps, nil) - - actual, err := svc.ListJobProposals(ctx) - require.NoError(t, err) - - assert.Equal(t, actual, jps) -} - func Test_Service_ListJobProposalsByManagersIDs(t *testing.T) { t.Parallel() ctx := testutils.Context(t) @@ -3851,6 +3910,10 @@ func Test_Service_StartStop(t *testing.T) { ID: 1, URI: "localhost:2000", } + mgr2 = feeds.FeedsManager{ + ID: 2, + URI: "localhost:2001", + } pubKeyHex = "0f17c3bf72de8beef6e2d17a14c0a972f5d7e0e66e70722373f12b88382d40f9" ) @@ -3859,8 +3922,9 @@ func Test_Service_StartStop(t *testing.T) { require.NoError(t, err) tests := []struct { - name string - beforeFunc func(svc *TestService) + name string + enableMultiFeedsManagers bool + beforeFunc func(svc *TestService) }{ { name: "success with a feeds manager connection", @@ -3873,6 +3937,19 @@ func Test_Service_StartStop(t *testing.T) { svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) }, }, + { + name: "success with multiple feeds managers connection", + enableMultiFeedsManagers: true, + beforeFunc: func(svc *TestService) { + svc.csaKeystore.On("GetAll").Return([]csakey.KeyV2{key}, nil) + svc.orm.On("ListManagers", mock.Anything).Return([]feeds.FeedsManager{mgr, mgr2}, nil) + svc.connMgr.On("IsConnected", mgr.ID).Return(false) + svc.connMgr.On("IsConnected", mgr2.ID).Return(false) + svc.connMgr.On("Connect", mock.IsType(feeds.ConnectOpts{})).Twice() + svc.connMgr.On("Close") + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + }, + }, { name: "success with no registered managers", beforeFunc: func(svc *TestService) { @@ -3889,7 +3966,9 @@ func Test_Service_StartStop(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Parallel() - svc := setupTestService(t) + svc := setupTestServiceCfg(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.Feature.MultiFeedsManagers = &tt.enableMultiFeedsManagers + }) if tt.beforeFunc != nil { tt.beforeFunc(svc) diff --git a/core/web/features_controller.go b/core/web/features_controller.go index 76f04fe262..66cd9e60c4 100644 --- a/core/web/features_controller.go +++ b/core/web/features_controller.go @@ -13,8 +13,9 @@ type FeaturesController struct { } const ( - FeatureKeyCSA string = "csa" - FeatureKeyFeedsManager string = "feeds_manager" + FeatureKeyCSA string = "csa" + FeatureKeyFeedsManager string = "feeds_manager" + FeatureKeyMultiFeedsManagers string = "multi_feeds_managers" ) // Index retrieves the features @@ -24,6 +25,7 @@ func (fc *FeaturesController) Index(c *gin.Context) { resources := []presenters.FeatureResource{ *presenters.NewFeatureResource(FeatureKeyCSA, fc.App.GetConfig().Feature().UICSAKeys()), *presenters.NewFeatureResource(FeatureKeyFeedsManager, fc.App.GetConfig().Feature().FeedsManager()), + *presenters.NewFeatureResource(FeatureKeyMultiFeedsManagers, fc.App.GetConfig().Feature().MultiFeedsManagers()), } jsonAPIResponse(c, resources, "features") diff --git a/core/web/features_controller_test.go b/core/web/features_controller_test.go index 727d7db547..02f75f14bc 100644 --- a/core/web/features_controller_test.go +++ b/core/web/features_controller_test.go @@ -19,6 +19,7 @@ func Test_FeaturesController_List(t *testing.T) { app := cltest.NewApplicationWithConfig(t, configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { csa := true c.Feature.UICSAKeys = &csa + c.Feature.MultiFeedsManagers = &csa })) require.NoError(t, app.Start(testutils.Context(t))) client := app.NewHTTPClient(nil) @@ -30,11 +31,14 @@ func Test_FeaturesController_List(t *testing.T) { resources := []presenters.FeatureResource{} err := web.ParseJSONAPIResponse(cltest.ParseResponseBody(t, resp), &resources) require.NoError(t, err) - require.Len(t, resources, 2) + require.Len(t, resources, 3) assert.Equal(t, "csa", resources[0].ID) assert.True(t, resources[0].Enabled) assert.Equal(t, "feeds_manager", resources[1].ID) assert.True(t, resources[1].Enabled) + + assert.Equal(t, "multi_feeds_managers", resources[2].ID) + assert.True(t, resources[2].Enabled) } diff --git a/core/web/resolver/features.go b/core/web/resolver/features.go index 9ce39a773c..9d6c135a93 100644 --- a/core/web/resolver/features.go +++ b/core/web/resolver/features.go @@ -20,6 +20,11 @@ func (r *FeaturesResolver) FeedsManager() bool { return r.cfg.FeedsManager() } +// MultiFeedsManagers resolves to whether multiple feed managers support is enable. +func (r *FeaturesResolver) MultiFeedsManagers() bool { + return r.cfg.MultiFeedsManagers() +} + type FeaturesPayloadResolver struct { cfg config.Feature } diff --git a/core/web/resolver/features_test.go b/core/web/resolver/features_test.go index 76394f038b..4e8f9e8c26 100644 --- a/core/web/resolver/features_test.go +++ b/core/web/resolver/features_test.go @@ -15,6 +15,7 @@ func Test_ToFeatures(t *testing.T) { ... on Features { csa feedsManager + multiFeedsManagers } } }` @@ -29,6 +30,7 @@ func Test_ToFeatures(t *testing.T) { t, f := true, false c.Feature.UICSAKeys = &f c.Feature.FeedsManager = &t + c.Feature.MultiFeedsManagers = &f })) }, query: query, @@ -36,7 +38,8 @@ func Test_ToFeatures(t *testing.T) { { "features": { "csa": false, - "feedsManager": true + "feedsManager": true, + "multiFeedsManagers": false } }`, }, diff --git a/core/web/resolver/feeds_manager.go b/core/web/resolver/feeds_manager.go index 86705cf207..0711cb1354 100644 --- a/core/web/resolver/feeds_manager.go +++ b/core/web/resolver/feeds_manager.go @@ -145,6 +145,7 @@ func (r *CreateFeedsManagerPayloadResolver) ToCreateFeedsManagerSuccess() (*Crea return nil, false } +// TODO: delete once multiple feeds managers support is released func (r *CreateFeedsManagerPayloadResolver) ToSingleFeedsManagerError() (*SingleFeedsManagerErrorResolver, bool) { if r.err != nil && errors.Is(r.err, feeds.ErrSingleFeedsManager) { return NewSingleFeedsManagerError(r.err.Error()), true @@ -153,6 +154,14 @@ func (r *CreateFeedsManagerPayloadResolver) ToSingleFeedsManagerError() (*Single return nil, false } +func (r *CreateFeedsManagerPayloadResolver) ToDuplicateFeedsManagerError() (*DuplicateFeedsManagerErrorResolver, bool) { + if r.err != nil && errors.Is(r.err, feeds.ErrDuplicateFeedsManager) { + return NewDuplicateFeedsManagerError(r.err.Error()), true + } + + return nil, false +} + func (r *CreateFeedsManagerPayloadResolver) ToInputErrors() (*InputErrorsResolver, bool) { if r.inputErrs != nil { var errs []*InputErrorResolver @@ -182,6 +191,7 @@ func (r *CreateFeedsManagerSuccessResolver) FeedsManager() *FeedsManagerResolver } // SingleFeedsManagerErrorResolver - +// TODO: delete once multiple feeds managers support is released type SingleFeedsManagerErrorResolver struct { message string } @@ -200,6 +210,25 @@ func (r *SingleFeedsManagerErrorResolver) Code() ErrorCode { return ErrorCodeUnprocessable } +// DuplicateFeedsManagerErrorResolver - +type DuplicateFeedsManagerErrorResolver struct { + message string +} + +func NewDuplicateFeedsManagerError(message string) *DuplicateFeedsManagerErrorResolver { + return &DuplicateFeedsManagerErrorResolver{ + message: message, + } +} + +func (r *DuplicateFeedsManagerErrorResolver) Message() string { + return r.message +} + +func (r *DuplicateFeedsManagerErrorResolver) Code() ErrorCode { + return ErrorCodeUnprocessable +} + // -- UpdateFeedsManager Mutation -- // UpdateFeedsManagerPayloadResolver - diff --git a/core/web/resolver/feeds_manager_test.go b/core/web/resolver/feeds_manager_test.go index bafb50ab0d..4237c6a774 100644 --- a/core/web/resolver/feeds_manager_test.go +++ b/core/web/resolver/feeds_manager_test.go @@ -183,6 +183,10 @@ func Test_CreateFeedsManager(t *testing.T) { message code } + ... on DuplicateFeedsManagerError { + message + code + } ... on NotFoundError { message code @@ -264,6 +268,25 @@ func Test_CreateFeedsManager(t *testing.T) { } }`, }, + { + name: "register duplicate feeds manager error", + authenticated: true, + before: func(ctx context.Context, f *gqlTestFramework) { + f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) + f.Mocks.feedsSvc. + On("RegisterManager", mock.Anything, mock.IsType(feeds.RegisterManagerParams{})). + Return(int64(0), feeds.ErrDuplicateFeedsManager) + }, + query: mutation, + variables: variables, + result: ` + { + "createFeedsManager": { + "message": "manager was previously registered using the same public key", + "code": "UNPROCESSABLE" + } + }`, + }, { name: "not found", authenticated: true, diff --git a/core/web/resolver/mutation.go b/core/web/resolver/mutation.go index 4da5b1da65..a9c1f634dc 100644 --- a/core/web/resolver/mutation.go +++ b/core/web/resolver/mutation.go @@ -424,7 +424,7 @@ func (r *Resolver) CreateFeedsManager(ctx context.Context, args struct { id, err := feedsService.RegisterManager(ctx, params) if err != nil { - if errors.Is(err, feeds.ErrSingleFeedsManager) { + if errors.Is(err, feeds.ErrSingleFeedsManager) || errors.Is(err, feeds.ErrDuplicateFeedsManager) { return NewCreateFeedsManagerPayload(nil, err, nil), nil } return nil, err diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index f1325d824e..d549e4024e 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -7,6 +7,7 @@ FeedsManager = true LogPoller = false UICSAKeys = false CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 37644c1d22..9eea404f48 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -7,6 +7,7 @@ FeedsManager = true LogPoller = true UICSAKeys = true CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1m0s' diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 55f998156c..d3a9819de3 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -7,6 +7,7 @@ FeedsManager = true LogPoller = false UICSAKeys = false CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/core/web/schema/type/features.graphql b/core/web/schema/type/features.graphql index 4254bdecb6..ff434ab4bd 100644 --- a/core/web/schema/type/features.graphql +++ b/core/web/schema/type/features.graphql @@ -1,6 +1,7 @@ type Features { csa: Boolean! feedsManager: Boolean! + multiFeedsManagers: Boolean! } # FeaturesPayload defines the response of fetching the features availability in the UI diff --git a/core/web/schema/type/feeds_manager.graphql b/core/web/schema/type/feeds_manager.graphql index 12e8732c8e..9da8f64e1c 100644 --- a/core/web/schema/type/feeds_manager.graphql +++ b/core/web/schema/type/feeds_manager.graphql @@ -77,6 +77,13 @@ type CreateFeedsManagerSuccess { feedsManager: FeedsManager! } +type DuplicateFeedsManagerError implements Error { + message: String! + code: ErrorCode! +} + +# DEPRECATED: No longer used since we now support multiple feeds manager. +# Keeping this to avoid breaking change. type SingleFeedsManagerError implements Error { message: String! code: ErrorCode! @@ -84,7 +91,8 @@ type SingleFeedsManagerError implements Error { # CreateFeedsManagerPayload defines the response when creating a feeds manager union CreateFeedsManagerPayload = CreateFeedsManagerSuccess - | SingleFeedsManagerError + | DuplicateFeedsManagerError + | SingleFeedsManagerError # // TODO: delete once multiple feeds managers support is released | NotFoundError | InputErrors diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 883bb49d31..2f86b40fde 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -52,6 +52,7 @@ FeedsManager = true # Default LogPoller = false # Default UICSAKeys = false # Default CCIP = true # Default +MultiFeedsManagers = false # Default ``` @@ -79,6 +80,12 @@ CCIP = true # Default ``` CCIP enables the CCIP service. +### MultiFeedsManagers +```toml +MultiFeedsManagers = false # Default +``` +MultiFeedsManagers enables support for multiple feeds manager connections. + ## Database ```toml [Database] diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index ff8b4889c4..114bb9f29a 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -19,6 +19,7 @@ FeedsManager = true LogPoller = false UICSAKeys = false CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index 016d416d5f..6f11019046 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -63,6 +63,7 @@ FeedsManager = true LogPoller = false UICSAKeys = false CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index f8a98b2c49..2d84d1f70b 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -63,6 +63,7 @@ FeedsManager = true LogPoller = false UICSAKeys = false CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index aef3b106a5..7bf4c3543f 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -63,6 +63,7 @@ FeedsManager = true LogPoller = false UICSAKeys = false CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar index 0cdf001ecc..14a8449ee1 100644 --- a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -48,6 +48,7 @@ FeedsManager = true LogPoller = false UICSAKeys = false CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 2912a80327..6e5e3b932a 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -53,6 +53,7 @@ FeedsManager = true LogPoller = false UICSAKeys = false CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index ce40c91f66..71a055b021 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -60,6 +60,7 @@ FeedsManager = true LogPoller = false UICSAKeys = false CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index dea40ec8da..b6ebc1dc12 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -42,6 +42,7 @@ FeedsManager = true LogPoller = false UICSAKeys = false CCIP = true +MultiFeedsManagers = false [Database] DefaultIdleInTxSessionTimeout = '1h0m0s' From 73cd2931ea9b5c7bbfd33cc66232fc92e4b0efc8 Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Thu, 29 Aug 2024 13:00:13 +0400 Subject: [PATCH 237/432] bump seth to v1.2.1 (#14272) --- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index d73eb28f4b..c1361f40dd 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -40,7 +40,7 @@ require ( github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 - github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 + github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 3994397b52..286310b1dd 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1439,8 +1439,8 @@ github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 h1:1/r1wQ github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 h1:ItZ75xmt+VHR/lw+GJwSWj9XICpgZ94dJ+I/5jdet7c= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 h1:GRAAvtn2+jhO/8Z3lig10eQXVcV4VuOI4UgCyoPdJBg= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index ca6d98dc0f..2720d38aa5 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -18,7 +18,7 @@ require ( github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe - github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 + github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 9280dc968f..5716b6ff9b 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1409,8 +1409,8 @@ github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.2024080 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6 h1:ItZ75xmt+VHR/lw+GJwSWj9XICpgZ94dJ+I/5jdet7c= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1-0.20240827112945-bd8c580392d6/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 h1:GRAAvtn2+jhO/8Z3lig10eQXVcV4VuOI4UgCyoPdJBg= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= From faf051f82be1ac17d1f7f8fb6b005c6597779636 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Thu, 29 Aug 2024 11:45:10 +0200 Subject: [PATCH 238/432] pin CTF version to a tag (#14273) --- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index c1361f40dd..08ac5e6e4e 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -37,7 +37,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a - github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe + github.com/smartcontractkit/chainlink-testing-framework v1.34.10 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 286310b1dd..d66ef5ac23 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1433,8 +1433,8 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe h1:5EaoT0jYlmubsDawLVLgPxgEWG7IPxjuxJP3cJ1wRzw= -github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= +github.com/smartcontractkit/chainlink-testing-framework v1.34.10 h1:7boGJr/wkX5TF6TBb4wRnP6t1IFL6RD98+fZBJBZyCY= +github.com/smartcontractkit/chainlink-testing-framework v1.34.10/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 h1:1/r1wQZ4TOFpZ13w94r7amdF096Z96RuEnkOmrz1BGE= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 2720d38aa5..578a540aa8 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,7 +17,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a - github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe + github.com/smartcontractkit/chainlink-testing-framework v1.34.10 github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 5716b6ff9b..16cedc84cd 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1403,8 +1403,8 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe h1:5EaoT0jYlmubsDawLVLgPxgEWG7IPxjuxJP3cJ1wRzw= -github.com/smartcontractkit/chainlink-testing-framework v1.34.10-0.20240828122712-9ea5d6ac33fe/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= +github.com/smartcontractkit/chainlink-testing-framework v1.34.10 h1:7boGJr/wkX5TF6TBb4wRnP6t1IFL6RD98+fZBJBZyCY= +github.com/smartcontractkit/chainlink-testing-framework v1.34.10/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a h1:8GtvGJaGyKzx/ar1yX74GxrzIYWTZVTyv4pYB/1ln8w= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= From d356f62e7ccf35fe563e3e03df8998d1d4935271 Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs <5300706+iljapavlovs@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:42:41 +0300 Subject: [PATCH 239/432] DEVSVCS-138: adding billing test and GHA workflow running smoke tests (#14265) * DEVSVCS-138: adding billing test and GHA workflow running smoke tests * DEVSVCS-138: minor fixes * DEVSVCS-138: adding sub_billing_tolerance_wei --- .github/workflows/live-vrf-tests.yml | 193 -------------- .../on-demand-vrfv2plus-smoke-tests.yml | 115 ++++++++ integration-tests/actions/actions.go | 9 + .../actions/vrf/vrfv2plus/contract_steps.go | 4 +- .../actions/vrf/vrfv2plus/logging_helpers.go | 17 ++ .../contracts/contract_vrf_models.go | 1 + .../contracts/ethereum_vrf_contracts.go | 21 ++ .../contracts/ethereum_vrfv2plus_contracts.go | 12 + integration-tests/smoke/vrfv2_test.go | 6 +- integration-tests/smoke/vrfv2plus_test.go | 252 ++++++++++-------- .../testconfig/vrfv2plus/config.go | 6 +- .../testconfig/vrfv2plus/vrfv2plus.toml | 1 + 12 files changed, 332 insertions(+), 305 deletions(-) delete mode 100644 .github/workflows/live-vrf-tests.yml create mode 100644 .github/workflows/on-demand-vrfv2plus-smoke-tests.yml diff --git a/.github/workflows/live-vrf-tests.yml b/.github/workflows/live-vrf-tests.yml deleted file mode 100644 index 28f5867954..0000000000 --- a/.github/workflows/live-vrf-tests.yml +++ /dev/null @@ -1,193 +0,0 @@ -# Funding address: 0xC1107e57082945E28d3202A81B1520DEA3AE6AEC -name: Generic Live Smoke Tests -on: - workflow_dispatch: - inputs: - networks: - description: "Comma-separated list of networks to run on" - required: true - default: "SEPOLIA,OPTIMISM_SEPOLIA,ARBITRUM_SEPOLIA" - test_list: - description: "Comma-separated list of tests to run" - required: true - default: "TestVRFBasic,TestVRFv2Basic,TestVRFv2Plus" - -env: - CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com - MOD_CACHE_VERSION: 2 - CHAINLINK_NODE_FUNDING: .5 - PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - LOKI_TENANT_ID: ${{ vars.LOKI_TENANT_ID }} - LOKI_URL: ${{ secrets.LOKI_URL }} - LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} - LOGSTREAM_LOG_TARGETS: loki - GRAFANA_URL: ${{ vars.GRAFANA_URL }} - RUN_ID: ${{ github.run_id }} - - CHAINLINK_COMMIT_SHA: ${{ github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: debug - -jobs: - - # Build Test Dependencies - - build-chainlink: - environment: integration - permissions: - id-token: write - contents: read - name: Build Chainlink Image - runs-on: ubuntu-latest - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: live-vrf-build-chainlink - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Chainlink Image - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Build Chainlink Image - uses: ./.github/actions/build-chainlink-image - with: - tag_suffix: "" - dockerfile: core/chainlink.Dockerfile - git_commit_sha: ${{ github.sha }} - GRAFANA_CLOUD_BASIC_AUTH: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - GRAFANA_CLOUD_HOST: ${{ secrets.GRAFANA_CLOUD_HOST }} - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - build-tests: - environment: integration - permissions: - id-token: write - contents: read - name: Build Tests Binary - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.build-matrix.outputs.matrix }} - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: live-vrf-build-test-image - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Tests Binary - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Build Network Matrix - id: build-matrix - run: | - NETWORKS="[\"${{ github.event.inputs.networks }}\"]" - NETWORKS="${NETWORKS//,/\",\"}" - echo "matrix=${NETWORKS}" >> "$GITHUB_OUTPUT" - - name: Build Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-tests@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_download_vendor_packages_command: cd ./integration-tests && go mod download - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - go_tags: embed - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - binary_name: tests - - - # End Build Test Dependencies - - live-smoke-tests: - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-tests] - strategy: - fail-fast: false - matrix: - network: ${{fromJson(needs.build-tests.outputs.matrix)}} - name: Smoke Tests on ${{ matrix.network }} - runs-on: ubuntu-latest - steps: - - name: Build Secrets Names - id: build-secrets-names - run: | - echo "HTTP_URLS_SECRET_NAME=QA_${{ matrix.network }}_HTTP_URLS" >> $GITHUB_ENV - echo "URLS_SECRET_NAME=QA_${{ matrix.network }}_URLS" >> $GITHUB_ENV - - name: Split Test Names - id: split_list - run: | - IFS=',' read -ra ADDR <<< "${{ inputs.test_list }}" - echo "test_list=${ADDR[*]}" >> $GITHUB_ENV - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config-live-testnets - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - network: ${{ matrix.network }} - httpEndpoints: ${{ secrets[env.HTTP_URLS_SECRET_NAME] }} - wsEndpoints: ${{ secrets[env.URLS_SECRET_NAME] }} - fundingKeys: ${{ secrets.QA_EVM_KEYS }} - - name: Download Tests Binary - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - with: - name: tests - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_command_to_run: ./tests -test.v -test.timeout 4h -test.count=1 -test.parallel=1 -test.run ${{ env.test_list }} - binary_name: tests - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - artifacts_location: ./logs - token: ${{ secrets.GITHUB_TOKEN }} - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directories: "./" diff --git a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml new file mode 100644 index 0000000000..5977f92622 --- /dev/null +++ b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml @@ -0,0 +1,115 @@ +name: On Demand VRFV2 Plus Smoke Tests +on: + workflow_dispatch: + inputs: + base64Config: + description: base64-ed config + required: true + type: string + test_suite: + description: "Test Suite to run" + required: true + type: choice + options: + - "All Tests" + - "Selected Tests" + test_list_regex: + description: "Regex for 'Selected Tests' to run" + required: false + default: "(TestVRFv2Plus$/(Link_Billing|Native_Billing|Direct_Funding)|TestVRFV2PlusWithBHS|TestVRFV2PlusWithBHF)" + test_secrets_override_key: + description: 'Key to run tests with custom test secrets' + required: false + type: string + +jobs: + vrfv2plus_smoke_test: + name: VRFV2 Plus Smoke Test + environment: integration + runs-on: ubuntu22.04-8cores-32GB + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + env: + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + TEST_LOG_LEVEL: debug + REF_NAME: ${{ github.head_ref || github.ref_name }} + SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} + SLACK_CHANNEL: ${{ secrets.QA_VRF_SLACK_CHANNEL }} + GRAFANA_URL: "http://localhost:8080/primary" + GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + WASP_LOG_LEVEL: info + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 + with: + id: on-demand-vrfv2plus-smoke-tests + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: ${{ inputs.network }} VRFV2 Plus Smoke Test + continue-on-error: true + - name: Checkout code + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + fetch-depth: 0 + - name: Mask base64 config + run: | + BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64Config' $GITHUB_EVENT_PATH) + echo ::add-mask::$BASE64_CONFIG_OVERRIDE + echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV + - name: Merge and export base64 config + uses: ./.github/actions/setup-merge-base64-config + with: + base64Config: ${{ env.BASE64_CONFIG_OVERRIDE }} + - name: Send details to Step Summary + shell: bash + run: | + echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY + echo "\`${{ env.CHAINLINK_IMAGE }}\`" >>$GITHUB_STEP_SUMMARY + echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY + echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY + echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY + echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY + - name: Run Tests + if: ${{ github.event.inputs.test_suite == 'Selected Tests' }} + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 + with: + test_command_to_run: cd ./integration-tests/smoke && go test -v -count=1 -parallel=1 -timeout 2h -run "${{ inputs.test_list_regex }}" + test_download_vendor_packages_command: cd ./integration-tests && go mod download + test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} + cl_repo: ${{ env.CHAINLINK_IMAGE }} + cl_image_tag: ${{ env.CHAINLINK_VERSION }} + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + artifacts_name: vrf-test-logs + artifacts_location: ./integration-tests/smoke/vrfv2plus/logs/ + token: ${{ secrets.GITHUB_TOKEN }} + go_mod_path: ./integration-tests/go.mod + should_cleanup: false + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + - name: Run Tests + if: ${{ github.event.inputs.test_suite == 'All Tests' }} + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 + with: + test_command_to_run: cd ./integration-tests/smoke && go test -v -count=1 -parallel=1 -timeout 3h vrfv2plus_test.go + test_download_vendor_packages_command: cd ./integration-tests && go mod download + test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} + cl_repo: ${{ env.CHAINLINK_IMAGE }} + cl_image_tag: ${{ env.CHAINLINK_VERSION }} + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + artifacts_name: vrf-test-logs + artifacts_location: ./integration-tests/smoke/vrfv2plus/logs/ + token: ${{ secrets.GITHUB_TOKEN }} + go_mod_path: ./integration-tests/go.mod + should_cleanup: false + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index 04767c842e..b6fc820042 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -1285,3 +1285,12 @@ func ContinuouslyGenerateTXsOnChain(sethClient *seth.Client, stopChannel chan bo } } } + +func WithinTolerance(a, b, tolerance float64) (bool, float64) { + if a == b { + return true, 0 + } + diff := math.Abs(a - b) + isWithinTolerance := diff < tolerance + return isWithinTolerance, diff +} diff --git a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go index 6b3345edd0..f3f41a0e66 100644 --- a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go @@ -41,7 +41,7 @@ func DeployVRFV2_5Contracts( if err != nil { return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployCoordinatorV2Plus, err) } - err = opStackCoordinator.SetL1FeeCalculation(configGeneral.L1FeeCalculationMode, configGeneral.L1FeeCoefficient) + err = opStackCoordinator.SetL1FeeCalculation(*configGeneral.L1FeeCalculationMode, *configGeneral.L1FeeCoefficient) if err != nil { return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrSetL1FeeCalculation, err) } @@ -437,7 +437,7 @@ func DeployVRFV2PlusDirectFundingContracts( if err != nil { return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployWrapper, err) } - err = opStackWrapper.SetL1FeeCalculation(configGeneral.L1FeeCalculationMode, configGeneral.L1FeeCoefficient) + err = opStackWrapper.SetL1FeeCalculation(*configGeneral.L1FeeCalculationMode, *configGeneral.L1FeeCoefficient) if err != nil { return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrSetL1FeeCalculation, err) } diff --git a/integration-tests/actions/vrf/vrfv2plus/logging_helpers.go b/integration-tests/actions/vrf/vrfv2plus/logging_helpers.go index 1c6e2edaa0..758200f86f 100644 --- a/integration-tests/actions/vrf/vrfv2plus/logging_helpers.go +++ b/integration-tests/actions/vrf/vrfv2plus/logging_helpers.go @@ -4,9 +4,11 @@ import ( "fmt" "math/big" + "github.com/ethereum/go-ethereum/core/types" "github.com/rs/zerolog" "github.com/smartcontractkit/chainlink/integration-tests/contracts" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" vrfv2plus_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2plus" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version" @@ -55,3 +57,18 @@ func LogSubDetailsAfterMigration(l zerolog.Logger, newCoordinator contracts.Coor Interface("Subscription Consumers", migratedSubscription.Consumers). Msg("Subscription Data After Migration to New Coordinator") } + +func LogPaymentDetails(l zerolog.Logger, fulfillmentTxFeeWei *big.Int, fulfillmentTxReceipt *types.Receipt, actualSubPaymentWei *big.Int, expectedSubPaymentWei *big.Float, configCopy tc.TestConfig) { + l.Info(). + Str("Tx Fee in Wei", fulfillmentTxFeeWei.String()). + Str("Effective Gas Price", fulfillmentTxReceipt.EffectiveGasPrice.String()). + Uint64("Gas Used", fulfillmentTxReceipt.GasUsed). + Str("Actual Subscription Payment in Wei", actualSubPaymentWei.String()). + Str("Expected Subscription Payment in Wei", expectedSubPaymentWei.String()). + Uint8("Native Premium Percentage", *configCopy.VRFv2Plus.General.NativePremiumPercentage). + Uint8("Link Premium Percentage", *configCopy.VRFv2Plus.General.LinkPremiumPercentage). + Uint32("FulfillmentFlatFeeNativePPM", *configCopy.VRFv2Plus.General.FulfillmentFlatFeeNativePPM). + Uint32("FulfillmentFlatFeeLinkDiscountPPM", *configCopy.VRFv2Plus.General.FulfillmentFlatFeeLinkDiscountPPM). + Uint32("GasAfterPaymentCalculation", *configCopy.VRFv2Plus.General.GasAfterPaymentCalculation). + Msg("Randomness Fulfillment Payment Details") +} diff --git a/integration-tests/contracts/contract_vrf_models.go b/integration-tests/contracts/contract_vrf_models.go index db8b427b07..8d1424cbfd 100644 --- a/integration-tests/contracts/contract_vrf_models.go +++ b/integration-tests/contracts/contract_vrf_models.go @@ -125,6 +125,7 @@ type VRFCoordinatorV2_5 interface { GetBlockHashStoreAddress(ctx context.Context) (common.Address, error) GetLinkAddress(ctx context.Context) (common.Address, error) GetLinkNativeFeed(ctx context.Context) (common.Address, error) + GetConfig(ctx context.Context) (vrf_coordinator_v2_5.SConfig, error) } type VRFCoordinatorV2PlusUpgradedVersion interface { diff --git a/integration-tests/contracts/ethereum_vrf_contracts.go b/integration-tests/contracts/ethereum_vrf_contracts.go index 3f83d8fd30..52b178d412 100644 --- a/integration-tests/contracts/ethereum_vrf_contracts.go +++ b/integration-tests/contracts/ethereum_vrf_contracts.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_ethlink_aggregator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper" @@ -353,6 +354,26 @@ func DeployVRFMockETHLINKFeed(seth *seth.Client, answer *big.Int) (VRFMockETHLIN }, err } +func LoadVRFMockETHLINKFeed(client *seth.Client, address common.Address) (VRFMockETHLINKFeed, error) { + abi, err := mock_ethlink_aggregator_wrapper.MockETHLINKAggregatorMetaData.GetAbi() + if err != nil { + return &EthereumVRFMockETHLINKFeed{}, fmt.Errorf("failed to get VRFMockETHLINKAggregator ABI: %w", err) + } + client.ContractStore.AddABI("VRFMockETHLINKAggregator", *abi) + client.ContractStore.AddBIN("VRFMockETHLINKAggregator", common.FromHex(mock_ethlink_aggregator_wrapper.MockETHLINKAggregatorMetaData.Bin)) + + instance, err := vrf_mock_ethlink_aggregator.NewVRFMockETHLINKAggregator(address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumVRFMockETHLINKFeed{}, fmt.Errorf("failed to instantiate VRFMockETHLINKAggregator instance: %w", err) + } + + return &EthereumVRFMockETHLINKFeed{ + address: address, + client: client, + feed: instance, + }, nil +} + func (v *EthereumBlockhashStore) Address() string { return v.address.Hex() } diff --git a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go index 2741209114..35d22e8ef5 100644 --- a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go @@ -435,6 +435,18 @@ func (v *EthereumVRFCoordinatorV2_5) GetLinkNativeFeed(ctx context.Context) (com return address, nil } +func (v *EthereumVRFCoordinatorV2_5) GetConfig(ctx context.Context) (vrf_coordinator_v2_5.SConfig, error) { + opts := &bind.CallOpts{ + From: v.client.MustGetRootKeyAddress(), + Context: ctx, + } + config, err := v.coordinator.SConfig(opts) + if err != nil { + return vrf_coordinator_v2_5.SConfig{}, err + } + return config, nil +} + // OwnerCancelSubscription cancels subscription by Coordinator owner // return funds to sub owner, // does not check if pending requests for a sub exist diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index a72af0a229..8d32204dd3 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -1029,7 +1029,6 @@ func TestVRFV2NodeReorg(t *testing.T) { env *test_env.CLClusterTestEnv vrfContracts *vrfcommon.VRFContracts subIDsForCancellingAfterTest []uint64 - defaultWalletAddress string vrfKey *vrfcommon.VRFKeyData sethClient *seth.Client ) @@ -1051,7 +1050,7 @@ func TestVRFV2NodeReorg(t *testing.T) { } else { if *vrfv2Config.General.CancelSubsAfterTestRun { //cancel subs and return funds to sub owner - vrfv2.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, defaultWalletAddress, subIDsForCancellingAfterTest, l) + vrfv2.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) } } if !*vrfv2Config.General.UseExistingEnv { @@ -1208,7 +1207,6 @@ func TestVRFv2BatchFulfillmentEnabledDisabled(t *testing.T) { env *test_env.CLClusterTestEnv vrfContracts *vrfcommon.VRFContracts subIDsForCancellingAfterTest []uint64 - defaultWalletAddress string vrfKey *vrfcommon.VRFKeyData nodeTypeToNodeMap map[vrfcommon.VRFNodeType]*vrfcommon.VRFNode sethClient *seth.Client @@ -1228,7 +1226,7 @@ func TestVRFv2BatchFulfillmentEnabledDisabled(t *testing.T) { } else { if *vrfv2Config.General.CancelSubsAfterTestRun { //cancel subs and return funds to sub owner - vrfv2.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, defaultWalletAddress, subIDsForCancellingAfterTest, l) + vrfv2.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) } } if !*vrfv2Config.General.UseExistingEnv { diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index 76d1523f89..d8ea7cac10 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -127,12 +127,6 @@ func TestVRFv2Plus(t *testing.T) { require.Equal(t, isNativeBilling, randomWordsFulfilledEvent.NativePayment, "RandomWordsFulfilled Event's `NativePayment` field should be false") require.True(t, randomWordsFulfilledEvent.Success, "RandomWordsFulfilled Event's `Success` field should be true") - expectedSubBalanceJuels := new(big.Int).Sub(subBalanceBeforeRequest, randomWordsFulfilledEvent.Payment) - subscription, err = vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subIDForRequestRandomness) - require.NoError(t, err, "error getting subscription information") - subBalanceAfterRequest := subscription.Balance - require.Equal(t, expectedSubBalanceJuels, subBalanceAfterRequest) - status, err := consumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, status.Fulfilled) @@ -143,6 +137,19 @@ func TestVRFv2Plus(t *testing.T) { l.Info().Str("Output", w.String()).Msg("Randomness fulfilled") require.Equal(t, 1, w.Cmp(big.NewInt(0)), "Expected the VRF job give an answer bigger than 0") } + t.Run("Verify Billing", func(t *testing.T) { + actualSubPaymentJuels := randomWordsFulfilledEvent.Payment + + expectedSubBalanceJuels := new(big.Int).Sub(subBalanceBeforeRequest, actualSubPaymentJuels) + subscription, err = vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subIDForRequestRandomness) + require.NoError(t, err, "error getting subscription information") + subBalanceAfterRequest := subscription.Balance + require.Equal(t, expectedSubBalanceJuels, subBalanceAfterRequest) + + //todo - need to refactor the test so that when running on live testnet and deploying a new environment, + // we would load real Link Token and Link/ETH feed addresses from the config + }) + }) t.Run("Native Billing", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) @@ -183,12 +190,6 @@ func TestVRFv2Plus(t *testing.T) { require.False(t, randomWordsFulfilledEvent.OnlyPremium) require.Equal(t, isNativeBilling, randomWordsFulfilledEvent.NativePayment) require.True(t, randomWordsFulfilledEvent.Success) - expectedSubBalanceWei := new(big.Int).Sub(subNativeTokenBalanceBeforeRequest, randomWordsFulfilledEvent.Payment) - subscription, err = vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) - require.NoError(t, err) - subBalanceAfterRequest := subscription.NativeBalance - require.Equal(t, expectedSubBalanceWei, subBalanceAfterRequest) - status, err := consumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, status.Fulfilled) @@ -199,92 +200,51 @@ func TestVRFv2Plus(t *testing.T) { l.Info().Str("Output", w.String()).Msg("Randomness fulfilled") require.Equal(t, 1, w.Cmp(big.NewInt(0)), "Expected the VRF job give an answer bigger than 0") } - }) - t.Run("VRF Node waits block confirmation number specified by the consumer before sending fulfilment on-chain", func(t *testing.T) { - configCopy := config.MustCopy().(tc.TestConfig) - testConfig := configCopy.VRFv2Plus.General - var isNativeBilling = true - - consumers, subIDs, err := vrfv2plus.SetupNewConsumersAndSubs( - testcontext.Get(t), - sethClient, - vrfContracts.CoordinatorV2Plus, - configCopy, - vrfContracts.LinkToken, - 1, - 1, - l, - ) - require.NoError(t, err, "error setting up new consumers and subs") - subID := subIDs[0] - subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) - require.NoError(t, err, "error getting subscription information") - vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) - subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) - - expectedBlockNumberWait := uint16(10) - testConfig.MinimumConfirmations = ptr.Ptr[uint16](expectedBlockNumberWait) - randomWordsRequestedEvent, randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( - consumers[0], - vrfContracts.CoordinatorV2Plus, - vrfKey, - subID, - isNativeBilling, - testConfig, - l, - 0, - ) - require.NoError(t, err, "error requesting randomness and waiting for fulfilment") - - // check that VRF node waited at least the number of blocks specified by the consumer in the rand request min confs field - blockNumberWait := randomWordsRequestedEvent.Raw.BlockNumber - randomWordsFulfilledEvent.Raw.BlockNumber - require.GreaterOrEqual(t, blockNumberWait, uint64(expectedBlockNumberWait)) - - status, err := consumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) - require.NoError(t, err, "error getting rand request status") - require.True(t, status.Fulfilled) - l.Info().Bool("Fulfilment Status", status.Fulfilled).Msg("Random Words Request Fulfilment Status") - }) - t.Run("CL Node VRF Job Runs", func(t *testing.T) { - configCopy := config.MustCopy().(tc.TestConfig) - var isNativeBilling = false - - consumers, subIDsForRequestRandomness, err := vrfv2plus.SetupNewConsumersAndSubs( - testcontext.Get(t), - sethClient, - vrfContracts.CoordinatorV2Plus, - configCopy, - vrfContracts.LinkToken, - 1, - 1, - l, - ) - require.NoError(t, err, "error setting up new consumers and subs") - subIDForRequestRandomness := subIDsForRequestRandomness[0] - subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subIDForRequestRandomness) - require.NoError(t, err, "error getting subscription information") - vrfcommon.LogSubDetails(l, subscription, subIDForRequestRandomness.String(), vrfContracts.CoordinatorV2Plus) - subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForRequestRandomness...) - - jobRunsBeforeTest, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodeTypeToNodeMap[vrfcommon.VRF].Job.Data.ID) - require.NoError(t, err, "error reading job runs") - - // test and assert - _, _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( - consumers[0], - vrfContracts.CoordinatorV2Plus, - vrfKey, - subIDForRequestRandomness, - isNativeBilling, - configCopy.VRFv2Plus.General, - l, - 0, - ) - require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + t.Run("Verify Billing", func(t *testing.T) { + actualSubPaymentWei := randomWordsFulfilledEvent.Payment + expectedSubBalanceWei := new(big.Int).Sub(subNativeTokenBalanceBeforeRequest, actualSubPaymentWei) + subscription, err = vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err) + subBalanceAfterRequest := subscription.NativeBalance + require.Equal(t, expectedSubBalanceWei, subBalanceAfterRequest) - jobRuns, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodeTypeToNodeMap[vrfcommon.VRF].Job.Data.ID) - require.NoError(t, err, "error reading job runs") - require.Equal(t, len(jobRunsBeforeTest.Data)+1, len(jobRuns.Data)) + // verify that the actual sub payment is within the expected range - this cannot be checked on SIMULATED env + coordinatorConfig, err := vrfContracts.CoordinatorV2Plus.GetConfig(testcontext.Get(t)) + require.NoError(t, err, "error getting coordinator config") + //check that Coordinator config is correct + require.Equal(t, *configCopy.VRFv2Plus.General.FulfillmentFlatFeeNativePPM, coordinatorConfig.FulfillmentFlatFeeNativePPM) + require.Equal(t, *configCopy.VRFv2Plus.General.NativePremiumPercentage, coordinatorConfig.NativePremiumPercentage) + require.Equal(t, *configCopy.VRFv2Plus.General.GasAfterPaymentCalculation, coordinatorConfig.GasAfterPaymentCalculation) + // check that the actual sub payment is within the expected range and is according to the coordinator config's billing settings + fulfillmentTxHash := randomWordsFulfilledEvent.Raw.TxHash + fulfillmentTxReceipt, err := sethClient.Client.TransactionReceipt(testcontext.Get(t), fulfillmentTxHash) + require.NoError(t, err, "error getting fulfilment tx receipt") + + txGasUsed := new(big.Int).SetUint64(fulfillmentTxReceipt.GasUsed) + // we don't have that information for older Geth versions + if fulfillmentTxReceipt.EffectiveGasPrice == nil { + fulfillmentTxReceipt.EffectiveGasPrice = new(big.Int).SetUint64(0) + } + fulfillmentTxFeeWei := new(big.Int).Mul(txGasUsed, fulfillmentTxReceipt.EffectiveGasPrice) + + premiumFeeInDecimal := new(big.Float).Quo(big.NewFloat(float64(*configCopy.VRFv2Plus.General.CoordinatorNativePremiumPercentage)), big.NewFloat(100)) + premiumFeeRatio := new(big.Float).Add(premiumFeeInDecimal, big.NewFloat(1)) + // since - tx fee * (premium fee in decimal + 1) = expected sub payment + fulfillmentTxFeeWeiFloat64, _ := fulfillmentTxFeeWei.Float64() + expectedSubPaymentWeiWithoutFlatFee := new(big.Float).Mul(big.NewFloat(fulfillmentTxFeeWeiFloat64), premiumFeeRatio) + flatFee := new(big.Float).Mul(big.NewFloat(float64(*configCopy.VRFv2Plus.General.FulfillmentFlatFeeNativePPM)), big.NewFloat(1e12)) + expectedSubPaymentWeiWitFlatFee := new(big.Float).Add(expectedSubPaymentWeiWithoutFlatFee, flatFee) + vrfv2plus.LogPaymentDetails(l, fulfillmentTxFeeWei, fulfillmentTxReceipt, actualSubPaymentWei, expectedSubPaymentWeiWitFlatFee, configCopy) + actualSubPaymentWeiFloat, _ := actualSubPaymentWei.Float64() + expectedSubPaymentWeiFloat, _ := expectedSubPaymentWeiWitFlatFee.Float64() + + //verify that the actual sub payment is more than TX fee + require.Equal(t, 1, actualSubPaymentWei.Cmp(fulfillmentTxFeeWei), "the actual sub payment has to be more than the TX fee") + + tolerance := *testConfig.SubBillingTolerance + isWithinTolerance, diff := actions.WithinTolerance(actualSubPaymentWeiFloat, expectedSubPaymentWeiFloat, tolerance) + require.True(t, isWithinTolerance, fmt.Sprintf("Expected the actual sub payment to be within %f tolerance of the expected sub payment. Diff: %f", tolerance, diff)) + }) }) t.Run("Direct Funding", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) @@ -399,6 +359,92 @@ func TestVRFv2Plus(t *testing.T) { } }) }) + t.Run("VRF Node waits block confirmation number specified by the consumer before sending fulfilment on-chain", func(t *testing.T) { + configCopy := config.MustCopy().(tc.TestConfig) + testConfig := configCopy.VRFv2Plus.General + var isNativeBilling = true + + consumers, subIDs, err := vrfv2plus.SetupNewConsumersAndSubs( + testcontext.Get(t), + sethClient, + vrfContracts.CoordinatorV2Plus, + configCopy, + vrfContracts.LinkToken, + 1, + 1, + l, + ) + require.NoError(t, err, "error setting up new consumers and subs") + subID := subIDs[0] + subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) + subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) + + expectedBlockNumberWait := uint16(10) + testConfig.MinimumConfirmations = ptr.Ptr[uint16](expectedBlockNumberWait) + randomWordsRequestedEvent, randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( + consumers[0], + vrfContracts.CoordinatorV2Plus, + vrfKey, + subID, + isNativeBilling, + testConfig, + l, + 0, + ) + require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + + // check that VRF node waited at least the number of blocks specified by the consumer in the rand request min confs field + blockNumberWait := randomWordsRequestedEvent.Raw.BlockNumber - randomWordsFulfilledEvent.Raw.BlockNumber + require.GreaterOrEqual(t, blockNumberWait, uint64(expectedBlockNumberWait)) + + status, err := consumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) + require.NoError(t, err, "error getting rand request status") + require.True(t, status.Fulfilled) + l.Info().Bool("Fulfilment Status", status.Fulfilled).Msg("Random Words Request Fulfilment Status") + }) + t.Run("CL Node VRF Job Runs", func(t *testing.T) { + configCopy := config.MustCopy().(tc.TestConfig) + var isNativeBilling = false + + consumers, subIDsForRequestRandomness, err := vrfv2plus.SetupNewConsumersAndSubs( + testcontext.Get(t), + sethClient, + vrfContracts.CoordinatorV2Plus, + configCopy, + vrfContracts.LinkToken, + 1, + 1, + l, + ) + require.NoError(t, err, "error setting up new consumers and subs") + subIDForRequestRandomness := subIDsForRequestRandomness[0] + subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subIDForRequestRandomness) + require.NoError(t, err, "error getting subscription information") + vrfcommon.LogSubDetails(l, subscription, subIDForRequestRandomness.String(), vrfContracts.CoordinatorV2Plus) + subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForRequestRandomness...) + + jobRunsBeforeTest, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodeTypeToNodeMap[vrfcommon.VRF].Job.Data.ID) + require.NoError(t, err, "error reading job runs") + + // test and assert + _, _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( + consumers[0], + vrfContracts.CoordinatorV2Plus, + vrfKey, + subIDForRequestRandomness, + isNativeBilling, + configCopy.VRFv2Plus.General, + l, + 0, + ) + require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + + jobRuns, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodeTypeToNodeMap[vrfcommon.VRF].Job.Data.ID) + require.NoError(t, err, "error reading job runs") + require.Equal(t, len(jobRunsBeforeTest.Data)+1, len(jobRuns.Data)) + }) t.Run("Canceling Sub And Returning Funds", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) @@ -748,8 +794,8 @@ func TestVRFv2PlusMultipleSendingKeys(t *testing.T) { config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2Plus) require.NoError(t, err, "Error getting config") vrfv2PlusConfig := config.VRFv2Plus - chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID - + network := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0] + chainID := network.ChainID cleanupFn := func() { if sethClient.Cfg.IsSimulatedNetwork() { l.Info(). @@ -1698,7 +1744,7 @@ func TestVRFv2PlusReplayAfterTimeout(t *testing.T) { env, vrfContracts, vrfKey, nodeTypeToNodeMap, sethClient, err = vrfv2plus.SetupVRFV2PlusUniverse(testcontext.Get(t), t, vrfEnvConfig, newEnvConfig, l) require.NoError(t, err, "error setting up VRFV2Plus universe") - t.Run("Timed out request fulfilled after node restart with replay", func(t *testing.T) { + t.Run("Replaying Requests", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) var isNativeBilling = false @@ -1916,7 +1962,6 @@ func TestVRFv2PlusNodeReorg(t *testing.T) { env *test_env.CLClusterTestEnv vrfContracts *vrfcommon.VRFContracts subIDsForCancellingAfterTest []*big.Int - defaultWalletAddress string vrfKey *vrfcommon.VRFKeyData sethClient *seth.Client ) @@ -1938,7 +1983,7 @@ func TestVRFv2PlusNodeReorg(t *testing.T) { } else { if *vrfv2PlusConfig.General.CancelSubsAfterTestRun { //cancel subs and return funds to sub owner - vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, defaultWalletAddress, subIDsForCancellingAfterTest, l) + vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) } } if !*vrfv2PlusConfig.General.UseExistingEnv { @@ -2095,7 +2140,6 @@ func TestVRFv2PlusBatchFulfillmentEnabledDisabled(t *testing.T) { env *test_env.CLClusterTestEnv vrfContracts *vrfcommon.VRFContracts subIDsForCancellingAfterTest []*big.Int - defaultWalletAddress string vrfKey *vrfcommon.VRFKeyData nodeTypeToNodeMap map[vrfcommon.VRFNodeType]*vrfcommon.VRFNode sethClient *seth.Client @@ -2115,7 +2159,7 @@ func TestVRFv2PlusBatchFulfillmentEnabledDisabled(t *testing.T) { } else { if *vrfv2PlusConfig.General.CancelSubsAfterTestRun { //cancel subs and return funds to sub owner - vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, defaultWalletAddress, subIDsForCancellingAfterTest, l) + vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) } } if !*vrfv2PlusConfig.General.UseExistingEnv { diff --git a/integration-tests/testconfig/vrfv2plus/config.go b/integration-tests/testconfig/vrfv2plus/config.go index 52d518e539..4ae5ee5c35 100644 --- a/integration-tests/testconfig/vrfv2plus/config.go +++ b/integration-tests/testconfig/vrfv2plus/config.go @@ -57,10 +57,12 @@ type General struct { CoordinatorLinkPremiumPercentage *uint8 `toml:"coordinator_link_premium_percentage"` //OP Stack chains settings - L1FeeCalculationMode uint8 `toml:"l1_fee_calculation_mode"` - L1FeeCoefficient uint8 `toml:"l1_fee_coefficient"` + L1FeeCalculationMode *uint8 `toml:"l1_fee_calculation_mode"` + L1FeeCoefficient *uint8 `toml:"l1_fee_coefficient"` UseTestCoordinator *bool `toml:"use_test_coordinator"` + + SubBillingTolerance *float64 `toml:"sub_billing_tolerance_wei"` } func (c *General) Validate() error { diff --git a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml index 1281ae7f2d..1b43d73e17 100644 --- a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml +++ b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml @@ -189,6 +189,7 @@ chainlink_node_funding = 0.7 [VRFv2Plus] [VRFv2Plus.General] +sub_billing_tolerance_wei = 1e15 use_test_coordinator = false cancel_subs_after_test_run = true use_existing_env = false From 80a8ed076ff19b3c7e03f29ad5d13f9b09481f03 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Thu, 29 Aug 2024 13:52:36 +0200 Subject: [PATCH 240/432] add RPC chaos test example for CRIB (#14274) --- .github/workflows/crib-integration-test.yml | 2 +- integration-tests/crib/README.md | 2 +- integration-tests/crib/connect.go | 15 +++++----- integration-tests/crib/ocr_test.go | 33 +++++++++++++++++++-- integration-tests/load/ocr/ocr_test.go | 4 +-- 5 files changed, 43 insertions(+), 13 deletions(-) diff --git a/.github/workflows/crib-integration-test.yml b/.github/workflows/crib-integration-test.yml index 6fcfe28155..56e025eeff 100644 --- a/.github/workflows/crib-integration-test.yml +++ b/.github/workflows/crib-integration-test.yml @@ -104,7 +104,7 @@ jobs: # RESTY_DEBUG: true TEST_PERSISTENCE: true run: |- - go test -v -run TestCRIB + go test -v -run TestCRIBChaos - name: Destroy CRIB Environment id: destroy if: always() && steps.deploy-crib.outputs.devspace-namespace != '' diff --git a/integration-tests/crib/README.md b/integration-tests/crib/README.md index e895cca676..c37cbfec9c 100644 --- a/integration-tests/crib/README.md +++ b/integration-tests/crib/README.md @@ -19,7 +19,7 @@ export CRIB_NODES=5 # min 5 nodes #export RESTY_DEBUG=true #export TEST_PERSISTENCE=true # to run the chaos test export GAP_URL=https://localhost:8080/primary # only applicable in CI, unset the var to connect locally -go test -v -run TestCRIB +go test -v -run TestCRIBChaos ``` ## Configuring CI workflow diff --git a/integration-tests/crib/connect.go b/integration-tests/crib/connect.go index ae62d31a0e..48507757d8 100644 --- a/integration-tests/crib/connect.go +++ b/integration-tests/crib/connect.go @@ -37,16 +37,17 @@ func ConnectRemote() ( *msClient.MockserverClient, *client.ChainlinkK8sClient, []*client.ChainlinkK8sClient, + *crib.CoreDONConnectionConfig, error, ) { vars, err := crib.CoreDONSimulatedConnection() if err != nil { - return nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, err } // TODO: move all the parts of ConnectRemote() to CTF when Seth config refactor is finalized config, err := tc.GetConfig([]string{"CRIB"}, tc.OCR) if err != nil { - return nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, err } var sethClient *seth.Client switch vars.Network { @@ -69,10 +70,10 @@ func ConnectRemote() ( } sethClient, err = seth_utils.GetChainClient(config, net) if err != nil { - return nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, err } default: - return nil, nil, nil, nil, errors.New("CRIB network is not supported") + return nil, nil, nil, nil, nil, errors.New("CRIB network is not supported") } // bootstrap node clClients := make([]*client.ChainlinkK8sClient, 0) @@ -84,7 +85,7 @@ func ConnectRemote() ( Headers: vars.NodeHeaders[0], }, vars.NodeInternalDNS[0], vars.Namespace) if err != nil { - return nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, err } clClients = append(clClients, c) // all the other nodes, indices of nodes in CRIB starts with 1 @@ -97,7 +98,7 @@ func ConnectRemote() ( Headers: vars.NodeHeaders[i], }, vars.NodeInternalDNS[i], vars.Namespace) if err != nil { - return nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, err } clClients = append(clClients, cl) } @@ -108,5 +109,5 @@ func ConnectRemote() ( }) //nolint:gosec // G602 - false positive https://github.com/securego/gosec/issues/1005 - return sethClient, mockServerClient, clClients[0], clClients[1:], nil + return sethClient, mockServerClient, clClients[0], clClients[1:], vars, nil } diff --git a/integration-tests/crib/ocr_test.go b/integration-tests/crib/ocr_test.go index 0b7c38597c..1c855fa8d5 100644 --- a/integration-tests/crib/ocr_test.go +++ b/integration-tests/crib/ocr_test.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink-testing-framework/client" "github.com/smartcontractkit/chainlink-testing-framework/havoc" "github.com/stretchr/testify/require" @@ -16,10 +17,11 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/logging" ) -func TestCRIB(t *testing.T) { +// TestCRIBChaos an example of how we can run chaos tests with havoc and core CRIB +func TestCRIBChaos(t *testing.T) { l := logging.GetTestLogger(t) - sethClient, msClient, bootstrapNode, workerNodes, err := ConnectRemote() + sethClient, msClient, bootstrapNode, workerNodes, _, err := ConnectRemote() require.NoError(t, err) lta, err := actions.SetupOCRv1Cluster(l, sethClient, workerNodes) @@ -55,3 +57,30 @@ func TestCRIB(t *testing.T) { }, 20*time.Minute, 5*time.Second) } } + +// TestCRIBRPCChaos and example of how we can run RPC chaos with Geth or Anvil +func TestCRIBRPCChaos(t *testing.T) { + l := logging.GetTestLogger(t) + + sethClient, msClient, bootstrapNode, workerNodes, vars, err := ConnectRemote() + require.NoError(t, err) + + lta, err := actions.SetupOCRv1Cluster(l, sethClient, workerNodes) + require.NoError(t, err) + ocrInstances, err := actions.SetupOCRv1Feed(l, sethClient, lta, msClient, bootstrapNode, workerNodes) + require.NoError(t, err) + + err = actions.SetAllAdapterResponsesToTheSameValue(10, ocrInstances, workerNodes, msClient) + require.NoError(t, err) + actions.SimulateOCRv1EAActivity(l, 3*time.Second, ocrInstances, workerNodes, msClient) + + err = actions.WatchNewOCRRound(l, sethClient, 1, contracts.V1OffChainAgrregatorToOffChainAggregatorWithRounds(ocrInstances), 5*time.Minute) + require.NoError(t, err, "Error watching for new OCR round") + + ac := client.NewRPCClient(sethClient.URL, vars.BlockchainNodeHeaders) + err = ac.GethSetHead(10) + require.NoError(t, err) + + err = actions.WatchNewOCRRound(l, sethClient, 3, contracts.V1OffChainAgrregatorToOffChainAggregatorWithRounds(ocrInstances), 5*time.Minute) + require.NoError(t, err, "Error watching for new OCR round") +} diff --git a/integration-tests/load/ocr/ocr_test.go b/integration-tests/load/ocr/ocr_test.go index 69475b09da..b5c7fa97cd 100644 --- a/integration-tests/load/ocr/ocr_test.go +++ b/integration-tests/load/ocr/ocr_test.go @@ -28,7 +28,7 @@ func TestOCRLoad(t *testing.T) { config, err := tc.GetConfig([]string{"Load"}, tc.OCR) require.NoError(t, err) - sethClient, msClient, bootstrapNode, workerNodes, err := crib.ConnectRemote() + sethClient, msClient, bootstrapNode, workerNodes, _, err := crib.ConnectRemote() require.NoError(t, err) lta, err := actions.SetupOCRv1Cluster(l, sethClient, workerNodes) @@ -61,7 +61,7 @@ func TestOCRVolume(t *testing.T) { config, err := tc.GetConfig([]string{"Volume"}, tc.OCR) require.NoError(t, err) - sethClient, msClient, bootstrapNode, workerNodes, err := crib.ConnectRemote() + sethClient, msClient, bootstrapNode, workerNodes, _, err := crib.ConnectRemote() require.NoError(t, err) lta, err := actions.SetupOCRv1Cluster(l, sethClient, workerNodes) From 23393e636910ede2ffc19d8ca9984b24bce11e1f Mon Sep 17 00:00:00 2001 From: Patrick Date: Thu, 29 Aug 2024 08:19:30 -0400 Subject: [PATCH 241/432] wiring through TLSCertPath to SetupTracing (#14224) --- core/cmd/shell.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/cmd/shell.go b/core/cmd/shell.go index 515cc96869..ba3d56d748 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -74,6 +74,7 @@ func initGlobals(cfgProm config.Prometheus, cfgTracing config.Tracing, logger lo CollectorTarget: cfgTracing.CollectorTarget(), NodeAttributes: cfgTracing.Attributes(), SamplingRatio: cfgTracing.SamplingRatio(), + TLSCertPath: cfgTracing.TLSCertPath(), OnDialError: func(error) { logger.Errorw("Failed to dial", "err", err) }, }) }) From 7905901c40fc6ab7c65066d02e2d63324e2d640f Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Thu, 29 Aug 2024 16:29:14 +0100 Subject: [PATCH 242/432] gas limit default value (#14258) --- .changeset/sixty-fireants-return.md | 5 + .../evm/config/chain_scoped_workflow.go | 4 +- core/chains/evm/config/config.go | 2 +- core/chains/evm/config/toml/config.go | 6 +- .../evm/config/toml/defaults/fallback.toml | 2 +- core/config/docs/chains-evm.toml | 4 +- core/config/docs/docs_test.go | 5 +- core/services/chainlink/config_test.go | 9 + .../chainlink/testdata/config-full.toml | 3 + .../config-multi-chain-effective.toml | 9 + core/services/relay/evm/evm.go | 6 +- core/services/relay/evm/write_target.go | 6 +- core/services/relay/evm/write_target_test.go | 8 +- core/web/resolver/testdata/config-full.toml | 3 + .../config-multi-chain-effective.toml | 9 + docs/CONFIG.md | 191 +++++++++++++++++- .../disk-based-logging-disabled.txtar | 3 + .../validate/disk-based-logging-no-dir.txtar | 3 + .../node/validate/disk-based-logging.txtar | 3 + testdata/scripts/node/validate/invalid.txtar | 3 + testdata/scripts/node/validate/valid.txtar | 3 + 21 files changed, 265 insertions(+), 22 deletions(-) create mode 100644 .changeset/sixty-fireants-return.md diff --git a/.changeset/sixty-fireants-return.md b/.changeset/sixty-fireants-return.md new file mode 100644 index 0000000000..1ae63c7830 --- /dev/null +++ b/.changeset/sixty-fireants-return.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal gas limit default value diff --git a/core/chains/evm/config/chain_scoped_workflow.go b/core/chains/evm/config/chain_scoped_workflow.go index 42bc8aed95..816270886a 100644 --- a/core/chains/evm/config/chain_scoped_workflow.go +++ b/core/chains/evm/config/chain_scoped_workflow.go @@ -17,6 +17,6 @@ func (b *workflowConfig) ForwarderAddress() *types.EIP55Address { return b.c.ForwarderAddress } -func (b *workflowConfig) DefaultGasLimit() uint64 { - return b.c.DefaultGasLimit +func (b *workflowConfig) GasLimitDefault() *uint64 { + return b.c.GasLimitDefault } diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index e313438038..6d7e7efc09 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -162,7 +162,7 @@ type BlockHistory interface { type Workflow interface { FromAddress() *types.EIP55Address ForwarderAddress() *types.EIP55Address - DefaultGasLimit() uint64 + GasLimitDefault() *uint64 } type NodePool interface { diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index a22fa31ddf..c7f7228606 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -521,7 +521,7 @@ func (a *Automation) setFrom(f *Automation) { type Workflow struct { FromAddress *types.EIP55Address `toml:",omitempty"` ForwarderAddress *types.EIP55Address `toml:",omitempty"` - DefaultGasLimit uint64 + GasLimitDefault *uint64 } func (m *Workflow) setFrom(f *Workflow) { @@ -532,7 +532,9 @@ func (m *Workflow) setFrom(f *Workflow) { m.ForwarderAddress = v } - m.DefaultGasLimit = f.DefaultGasLimit + if v := f.GasLimitDefault; v != nil { + m.GasLimitDefault = v + } } type BalanceMonitor struct { diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index a3def55b4a..a01d0801cc 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -86,4 +86,4 @@ ObservationGracePeriod = '1s' GasLimit = 5400000 [Workflow] -DefaultGasLimit = 400_000 +GasLimitDefault = 400_000 diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index aef9be0966..fceffe539e 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -471,5 +471,5 @@ GasLimit = 5400000 # Default FromAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example # ForwarderAddress is the keystone forwarder contract address on chain. ForwarderAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example -# DefaultGasLimit is the default gas limit for workflow transactions. -DefaultGasLimit = 400_000 # Default +# GasLimitDefault is the default gas limit for workflow transactions. +GasLimitDefault = 400_000 # Default diff --git a/core/config/docs/docs_test.go b/core/config/docs/docs_test.go index 7a7d665044..13256a5764 100644 --- a/core/config/docs/docs_test.go +++ b/core/config/docs/docs_test.go @@ -83,11 +83,12 @@ func TestDoc(t *testing.T) { docDefaults.OperatorFactoryAddress = nil require.Empty(t, docDefaults.Workflow.FromAddress) require.Empty(t, docDefaults.Workflow.ForwarderAddress) - require.Equal(t, uint64(400_000), docDefaults.Workflow.DefaultGasLimit) + gasLimitDefault := uint64(400_000) + require.Equal(t, &gasLimitDefault, docDefaults.Workflow.GasLimitDefault) docDefaults.Workflow.FromAddress = nil docDefaults.Workflow.ForwarderAddress = nil - docDefaults.Workflow.DefaultGasLimit = uint64(400_000) + docDefaults.Workflow.GasLimitDefault = &gasLimitDefault docDefaults.NodePool.Errors = evmcfg.ClientErrors{} // Transactions.AutoPurge configs are only set if the feature is enabled diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 17c059cba9..a151b78fed 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -632,6 +632,9 @@ func TestConfig_Marshal(t *testing.T) { GasLimit: ptr[uint32](540), }, }, + Workflow: evmcfg.Workflow{ + GasLimitDefault: ptr[uint64](400000), + }, }, Nodes: []*evmcfg.Node{ { @@ -1107,6 +1110,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 540 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'foo' WSURL = 'wss://web.socket/test/foo' @@ -1243,6 +1249,9 @@ func TestConfig_full(t *testing.T) { if got.EVM[c].Workflow.ForwarderAddress == nil { got.EVM[c].Workflow.ForwarderAddress = &addr } + if got.EVM[c].Workflow.GasLimitDefault == nil { + got.EVM[c].Workflow.GasLimitDefault = ptr(uint64(400000)) + } for n := range got.EVM[c].Nodes { if got.EVM[c].Nodes[n].WSURL == nil { got.EVM[c].Nodes[n].WSURL = new(commoncfg.URL) diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index af41766a6c..fb43bed841 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -396,6 +396,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 540 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'foo' WSURL = 'wss://web.socket/test/foo' diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 640e6708bd..ffd4903bcd 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -350,6 +350,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 10500000 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'primary' WSURL = 'wss://web.socket/mainnet' @@ -451,6 +454,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 5400000 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'foo' WSURL = 'wss://web.socket/test/foo' @@ -546,6 +552,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 5400000 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'bar' WSURL = 'wss://web.socket/test/bar' diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index fffac7194d..35417c615c 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -211,7 +211,11 @@ func NewRelayer(lggr logger.Logger, chain legacyevm.Chain, opts RelayerOpts) (*R // Initialize write target capability if configuration is defined if chain.Config().EVM().Workflow().ForwarderAddress() != nil { ctx := context.Background() - capability, err := NewWriteTarget(ctx, relayer, chain, chain.Config().EVM().Workflow().DefaultGasLimit(), + if chain.Config().EVM().Workflow().GasLimitDefault() == nil { + return nil, fmt.Errorf("unable to instantiate write target as default gas limit is not set") + } + + capability, err := NewWriteTarget(ctx, relayer, chain, *chain.Config().EVM().Workflow().GasLimitDefault(), lggr) if err != nil { return nil, fmt.Errorf("failed to initialize write target: %w", err) diff --git a/core/services/relay/evm/write_target.go b/core/services/relay/evm/write_target.go index 69ee23ee85..6d54336057 100644 --- a/core/services/relay/evm/write_target.go +++ b/core/services/relay/evm/write_target.go @@ -15,7 +15,7 @@ import ( relayevmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) -func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain, defaultGasLimit uint64, lggr logger.Logger) (*targets.WriteTarget, error) { +func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain, gasLimitDefault uint64, lggr logger.Logger) (*targets.WriteTarget, error) { // generate ID based on chain selector id := fmt.Sprintf("write_%v@1.0.0", chain.ID()) chainName, err := chainselectors.NameFromChainId(chain.ID().Uint64()) @@ -56,7 +56,7 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain ChainSpecificName: "report", Checker: "simulate", FromAddress: config.FromAddress().Address(), - GasLimit: defaultGasLimit, + GasLimit: gasLimitDefault, }, }, }, @@ -74,5 +74,5 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain return nil, err } - return targets.NewWriteTarget(logger.Named(lggr, "WriteTarget"), id, cr, cw, config.ForwarderAddress().String(), defaultGasLimit), nil + return targets.NewWriteTarget(logger.Named(lggr, "WriteTarget"), id, cr, cw, config.ForwarderAddress().String(), gasLimitDefault), nil } diff --git a/core/services/relay/evm/write_target_test.go b/core/services/relay/evm/write_target_test.go index 67e45228cf..e8a6afee06 100644 --- a/core/services/relay/evm/write_target_test.go +++ b/core/services/relay/evm/write_target_test.go @@ -196,11 +196,11 @@ func TestEvmWrite(t *testing.T) { require.Equal(t, signatures, payload["signatures"]) }).Once() - defaultGasLimit := uint64(400_000) + gasLimitDefault := uint64(400_000) t.Run("succeeds with valid report", func(t *testing.T) { ctx := testutils.Context(t) - capability, err := evm.NewWriteTarget(ctx, relayer, chain, defaultGasLimit, lggr) + capability, err := evm.NewWriteTarget(ctx, relayer, chain, gasLimitDefault, lggr) require.NoError(t, err) req := capabilities.CapabilityRequest{ @@ -218,7 +218,7 @@ func TestEvmWrite(t *testing.T) { t.Run("fails with invalid config", func(t *testing.T) { ctx := testutils.Context(t) - capability, err := evm.NewWriteTarget(ctx, relayer, chain, defaultGasLimit, logger.TestLogger(t)) + capability, err := evm.NewWriteTarget(ctx, relayer, chain, gasLimitDefault, logger.TestLogger(t)) require.NoError(t, err) invalidConfig, err := values.NewMap(map[string]any{ @@ -238,7 +238,7 @@ func TestEvmWrite(t *testing.T) { t.Run("fails when TXM CreateTransaction returns error", func(t *testing.T) { ctx := testutils.Context(t) - capability, err := evm.NewWriteTarget(ctx, relayer, chain, defaultGasLimit, logger.TestLogger(t)) + capability, err := evm.NewWriteTarget(ctx, relayer, chain, gasLimitDefault, logger.TestLogger(t)) require.NoError(t, err) req := capabilities.CapabilityRequest{ diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 9eea404f48..ba994650c6 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -395,6 +395,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 540 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'foo' WSURL = 'wss://web.socket/test/foo' diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index d3a9819de3..8f8121613b 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -350,6 +350,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 10500000 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'primary' WSURL = 'wss://web.socket/mainnet' @@ -451,6 +454,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 5400000 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'foo' WSURL = 'wss://web.socket/test/foo' @@ -546,6 +552,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 5400000 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'bar' WSURL = 'wss://web.socket/test/bar' diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 2f86b40fde..03908e08ed 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1870,6 +1870,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 10500000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -1965,6 +1968,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -2060,6 +2066,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -2155,6 +2164,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -2251,6 +2263,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 6500000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -2346,6 +2361,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -2441,6 +2459,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -2537,6 +2558,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -2632,6 +2656,9 @@ ObservationGracePeriod = '500ms' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -2726,6 +2753,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -2820,6 +2850,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -2915,6 +2948,9 @@ ObservationGracePeriod = '500ms' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -3011,6 +3047,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -3106,6 +3145,9 @@ ObservationGracePeriod = '500ms' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -3201,6 +3243,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -3296,6 +3341,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -3391,6 +3439,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -3486,6 +3537,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 3800000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -3581,6 +3635,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -3676,6 +3733,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -3771,6 +3831,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -3866,6 +3929,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -3962,6 +4028,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 6500000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -4057,6 +4126,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -4151,6 +4223,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -4246,6 +4321,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -4341,6 +4419,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -4436,6 +4517,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -4531,6 +4615,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -4625,6 +4712,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -4720,6 +4810,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -4815,6 +4908,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -4910,6 +5006,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -5005,6 +5104,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 3800000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -5099,6 +5201,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -5194,6 +5299,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 6500000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -5289,6 +5397,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -5385,6 +5496,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -5481,6 +5595,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -5577,6 +5694,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 14500000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -5672,6 +5792,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -5767,6 +5890,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -5862,6 +5988,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -5957,6 +6086,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -6051,6 +6183,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -6145,6 +6280,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -6239,6 +6377,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -6334,6 +6475,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -6429,6 +6573,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -6523,6 +6670,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -6618,6 +6768,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 6500000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -6713,6 +6866,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 6500000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -6809,6 +6965,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -6905,6 +7064,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 14500000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -7000,6 +7162,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 14500000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -7095,6 +7260,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -7190,6 +7358,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -7285,6 +7456,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 10500000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -7380,6 +7554,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 6500000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -7475,6 +7652,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -7570,6 +7750,9 @@ ObservationGracePeriod = '1s' [OCR2] [OCR2.Automation] GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 ```

    @@ -8602,7 +8785,7 @@ GasLimit controls the gas limit for transmit transactions from ocr2automation jo [EVM.Workflow] FromAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example ForwarderAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example -DefaultGasLimit = 400_000 # Default +GasLimitDefault = 400_000 # Default ``` @@ -8618,11 +8801,11 @@ ForwarderAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example ``` ForwarderAddress is the keystone forwarder contract address on chain. -### DefaultGasLimit +### GasLimitDefault ```toml -DefaultGasLimit = 400_000 # Default +GasLimitDefault = 400_000 # Default ``` -DefaultGasLimit is the default gas limit for workflow transactions. +GasLimitDefault is the default gas limit for workflow transactions. ## Cosmos ```toml diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index 6f11019046..c95144dbf7 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -406,6 +406,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 10500000 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'fake' WSURL = 'wss://foo.bar/ws' diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 2d84d1f70b..0cdeff3606 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -406,6 +406,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 10500000 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'fake' WSURL = 'wss://foo.bar/ws' diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 7bf4c3543f..60059e2ab8 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -406,6 +406,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 10500000 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'fake' WSURL = 'wss://foo.bar/ws' diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 6e5e3b932a..70a6cde243 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -396,6 +396,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 10500000 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'fake' WSURL = 'wss://foo.bar/ws' diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index 71a055b021..ca2f10fb88 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -403,6 +403,9 @@ ObservationGracePeriod = '1s' [EVM.OCR2.Automation] GasLimit = 10500000 +[EVM.Workflow] +GasLimitDefault = 400000 + [[EVM.Nodes]] Name = 'fake' WSURL = 'wss://foo.bar/ws' From f7cf307ae9988e0f8fc6dba443c3106c33e80c9c Mon Sep 17 00:00:00 2001 From: Ryan Tinianov Date: Thu, 29 Aug 2024 12:07:47 -0400 Subject: [PATCH 243/432] update mapstructure to the blessed fork, the original is archived and this fork has our changes (#14279) --- core/scripts/go.mod | 3 ++- core/scripts/go.sum | 6 ++++-- core/services/pipeline/common.go | 3 ++- core/services/pipeline/task.eth_tx.go | 3 ++- core/services/relay/evm/codec.go | 2 +- core/services/relay/evm/decoder.go | 2 +- go.mod | 8 +++----- go.sum | 12 ++++++++---- integration-tests/go.mod | 3 ++- integration-tests/go.sum | 6 ++++-- integration-tests/load/go.mod | 3 ++- integration-tests/load/go.sum | 6 ++++-- 12 files changed, 35 insertions(+), 22 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index de3f19b898..66743dd4d6 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 @@ -150,6 +150,7 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.15.5 // indirect + github.com/go-viper/mapstructure/v2 v2.1.0 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect github.com/goccy/go-json v0.10.2 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index d24e6d2277..8f7a960a77 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -516,6 +516,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-viper/mapstructure/v2 v2.1.0 h1:gHnMa2Y/pIxElCH2GlZZ1lZSsn6XMtufpGyP1XxdC/w= +github.com/go-viper/mapstructure/v2 v2.1.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6lpIc2g= github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= @@ -1186,8 +1188,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a h1:MA1Lw4ZL8A/xyr5lW5WjM0zgI8ZL1AEfIOOTjZFcZlI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 h1:MOFuL1J4/rRcR0x09qSlOsKIiq4I7YzbZcQ421KqUZA= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8/go.mod h1:TJSY2ETKiXLRPvGHNO7Dp1tlpFIPSCWwN3iIdrsadIE= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= diff --git a/core/services/pipeline/common.go b/core/services/pipeline/common.go index 1b36c8a664..4e7c5b9cef 100644 --- a/core/services/pipeline/common.go +++ b/core/services/pipeline/common.go @@ -11,14 +11,15 @@ import ( "strings" "time" + "github.com/go-viper/mapstructure/v2" "github.com/google/uuid" - "github.com/mitchellh/mapstructure" pkgerrors "github.com/pkg/errors" "gopkg.in/guregu/null.v4" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" cutils "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-common/pkg/utils/jsonserializable" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" "github.com/smartcontractkit/chainlink/v2/core/logger" cnull "github.com/smartcontractkit/chainlink/v2/core/null" diff --git a/core/services/pipeline/task.eth_tx.go b/core/services/pipeline/task.eth_tx.go index 964591cacd..506a2518f7 100644 --- a/core/services/pipeline/task.eth_tx.go +++ b/core/services/pipeline/task.eth_tx.go @@ -8,13 +8,14 @@ import ( "strconv" "github.com/ethereum/go-ethereum/common" - "github.com/mitchellh/mapstructure" + "github.com/go-viper/mapstructure/v2" "github.com/pkg/errors" "go.uber.org/multierr" "gopkg.in/guregu/null.v4" "github.com/smartcontractkit/chainlink-common/pkg/utils/hex" clnull "github.com/smartcontractkit/chainlink-common/pkg/utils/null" + txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" diff --git a/core/services/relay/evm/codec.go b/core/services/relay/evm/codec.go index 2f01adfbdc..45810bb1ab 100644 --- a/core/services/relay/evm/codec.go +++ b/core/services/relay/evm/codec.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/mitchellh/mapstructure" + "github.com/go-viper/mapstructure/v2" "github.com/smartcontractkit/chainlink-common/pkg/codec" diff --git a/core/services/relay/evm/decoder.go b/core/services/relay/evm/decoder.go index 732ee91d9e..e86ade3ac7 100644 --- a/core/services/relay/evm/decoder.go +++ b/core/services/relay/evm/decoder.go @@ -5,7 +5,7 @@ import ( "fmt" "reflect" - "github.com/mitchellh/mapstructure" + "github.com/go-viper/mapstructure/v2" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" diff --git a/go.mod b/go.mod index 83767a55fc..a5ab488452 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,7 @@ require ( github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 github.com/gin-gonic/gin v1.9.1 github.com/go-ldap/ldap/v3 v3.4.6 + github.com/go-viper/mapstructure/v2 v2.1.0 github.com/go-webauthn/webauthn v0.9.4 github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b github.com/google/uuid v1.6.0 @@ -53,7 +54,6 @@ require ( github.com/lib/pq v1.10.9 github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f github.com/mitchellh/go-homedir v1.1.0 - github.com/mitchellh/mapstructure v1.5.0 github.com/mr-tron/base58 v1.2.0 github.com/olekukonko/tablewriter v0.0.5 github.com/onsi/gomega v1.30.0 @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 @@ -272,6 +272,7 @@ require ( github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -355,9 +356,6 @@ replace ( // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 - // until nolag updates merged upstream - github.com/mitchellh/mapstructure => github.com/nolag/mapstructure v1.5.2-0.20240625151721-90ea83a3f479 - // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f ) diff --git a/go.sum b/go.sum index 217300324c..47b1c06525 100644 --- a/go.sum +++ b/go.sum @@ -480,6 +480,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-viper/mapstructure/v2 v2.1.0 h1:gHnMa2Y/pIxElCH2GlZZ1lZSsn6XMtufpGyP1XxdC/w= +github.com/go-viper/mapstructure/v2 v2.1.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6lpIc2g= github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= @@ -941,6 +943,10 @@ github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJ github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= @@ -973,8 +979,6 @@ github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdh github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= -github.com/nolag/mapstructure v1.5.2-0.20240625151721-90ea83a3f479 h1:1jCGDLFXDOHF2sdeTJYKrIuSLGMpQZpgXXHNGXR5Ouk= -github.com/nolag/mapstructure v1.5.2-0.20240625151721-90ea83a3f479/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE= github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -1141,8 +1145,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a h1:MA1Lw4ZL8A/xyr5lW5WjM0zgI8ZL1AEfIOOTjZFcZlI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 h1:MOFuL1J4/rRcR0x09qSlOsKIiq4I7YzbZcQ421KqUZA= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8/go.mod h1:TJSY2ETKiXLRPvGHNO7Dp1tlpFIPSCWwN3iIdrsadIE= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 08ac5e6e4e..c16a02c1c7 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -36,7 +36,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 github.com/smartcontractkit/chainlink-testing-framework v1.34.10 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 @@ -231,6 +231,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/go-viper/mapstructure/v2 v2.1.0 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect github.com/goccy/go-json v0.10.2 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index d66ef5ac23..07b4c7c40b 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -646,6 +646,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-viper/mapstructure/v2 v2.1.0 h1:gHnMa2Y/pIxElCH2GlZZ1lZSsn6XMtufpGyP1XxdC/w= +github.com/go-viper/mapstructure/v2 v2.1.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6lpIc2g= github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= @@ -1421,8 +1423,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a h1:MA1Lw4ZL8A/xyr5lW5WjM0zgI8ZL1AEfIOOTjZFcZlI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 h1:MOFuL1J4/rRcR0x09qSlOsKIiq4I7YzbZcQ421KqUZA= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8/go.mod h1:TJSY2ETKiXLRPvGHNO7Dp1tlpFIPSCWwN3iIdrsadIE= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 578a540aa8..78d46b5d38 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 github.com/smartcontractkit/chainlink-testing-framework v1.34.10 github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 @@ -52,6 +52,7 @@ require ( github.com/aws/smithy-go v1.20.4 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/containerd/errdefs v0.1.0 // indirect + github.com/go-viper/mapstructure/v2 v2.1.0 // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 16cedc84cd..8377b2d432 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -626,6 +626,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-viper/mapstructure/v2 v2.1.0 h1:gHnMa2Y/pIxElCH2GlZZ1lZSsn6XMtufpGyP1XxdC/w= +github.com/go-viper/mapstructure/v2 v2.1.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6lpIc2g= github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= @@ -1391,8 +1393,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 h1:LAgJTg9Yr/uCo2g7Krp88Dco2U45Y6sbJVl8uKoLkys= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95/go.mod h1:/ZWraCBaDDgaIN1prixYcbVvIk/6HeED9+8zbWQ+TMo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a h1:MA1Lw4ZL8A/xyr5lW5WjM0zgI8ZL1AEfIOOTjZFcZlI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240828152114-571392f2833a/go.mod h1:bE6E7KwB8dkFUWKxJTTTtrNAl9xFPGlurKpDVhRz1tk= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 h1:MOFuL1J4/rRcR0x09qSlOsKIiq4I7YzbZcQ421KqUZA= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8/go.mod h1:TJSY2ETKiXLRPvGHNO7Dp1tlpFIPSCWwN3iIdrsadIE= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= From 7c248e7c466ad278b0024e4ac743813009b16805 Mon Sep 17 00:00:00 2001 From: Christopher Dimitri Sastropranoto Date: Thu, 29 Aug 2024 23:10:46 +0700 Subject: [PATCH 244/432] Index DON ID in ConfigSet event (#14241) * index DON ID in ConfigSet event * update wrappers * Pass empty ID array to the Filter function --------- Co-authored-by: Bolek Kulbabinski <1416262+bolekk@users.noreply.github.com> --- .changeset/kind-houses-smile.md | 5 ++++ contracts/.changeset/chilled-melons-warn.md | 5 ++++ .../v0.8/keystone/CapabilitiesRegistry.sol | 2 +- .../ccip/ccip_integration_tests/helpers.go | 2 +- .../capabilities_registry.go | 26 +++++++++++++------ ...rapper-dependency-versions-do-not-edit.txt | 2 +- 6 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 .changeset/kind-houses-smile.md create mode 100644 contracts/.changeset/chilled-melons-warn.md diff --git a/.changeset/kind-houses-smile.md b/.changeset/kind-houses-smile.md new file mode 100644 index 0000000000..037adbcad3 --- /dev/null +++ b/.changeset/kind-houses-smile.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal index don ID in ConfigSet event diff --git a/contracts/.changeset/chilled-melons-warn.md b/contracts/.changeset/chilled-melons-warn.md new file mode 100644 index 0000000000..f94192bb60 --- /dev/null +++ b/contracts/.changeset/chilled-melons-warn.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +#internal index don ID in ConfigSet event diff --git a/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol b/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol index 461bbca898..68c59c7f8c 100644 --- a/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol +++ b/contracts/src/v0.8/keystone/CapabilitiesRegistry.sol @@ -396,7 +396,7 @@ contract CapabilitiesRegistry is OwnerIsCreator, TypeAndVersionInterface { /// @param donId The ID of the DON the config was set for /// @param configCount The number of times the DON has been /// configured - event ConfigSet(uint32 donId, uint32 configCount); + event ConfigSet(uint32 indexed donId, uint32 configCount); /// @notice This event is emitted when a new node operator is added /// @param nodeOperatorId The ID of the newly added node operator diff --git a/core/capabilities/ccip/ccip_integration_tests/helpers.go b/core/capabilities/ccip/ccip_integration_tests/helpers.go index 7606c8bbeb..7143d0cd31 100644 --- a/core/capabilities/ccip/ccip_integration_tests/helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/helpers.go @@ -562,7 +562,7 @@ func (h *homeChain) AddDON( iter, err := h.capabilityRegistry.FilterConfigSet(&bind.FilterOpts{ Start: h.backend.Blockchain().CurrentBlock().Number.Uint64() - 1, End: &endBlock, - }) + }, []uint32{}) require.NoError(t, err, "failed to filter config set events") var donID uint32 for iter.Next() { diff --git a/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go b/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go index e5ae52c71c..d9c7dbe69f 100644 --- a/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go +++ b/core/gethwrappers/keystone/generated/capabilities_registry/capabilities_registry.go @@ -86,8 +86,8 @@ type CapabilitiesRegistryNodeParams struct { } var CapabilitiesRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityIsDeprecated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"CapabilityRequiredByDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"DONDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONNode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"nodeCount\",\"type\":\"uint256\"}],\"name\":\"InvalidFaultTolerance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"InvalidNodeCapabilities\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"InvalidNodeP2PId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotSupportCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfCapabilitiesDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfWorkflowDON\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilitiesRegistry.Capability[]\",\"name\":\"capabilities\",\"type\":\"tuple[]\"}],\"name\":\"addCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"addDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"addNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"deprecateCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityConfigs\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"getDON\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"getHashedCapabilityId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"getNode\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo\",\"name\":\"nodeInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodeOperators\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodes\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"isCapabilityDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"donIds\",\"type\":\"uint32[]\"}],\"name\":\"removeDONs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"removedNodeP2PIds\",\"type\":\"bytes32[]\"}],\"name\":\"removeNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"updateDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"updateNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6080604052600e80546001600160401b0319166401000000011790553480156200002857600080fd5b503380600081620000805760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000b357620000b381620000bc565b50505062000167565b336001600160a01b03821603620001165760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000077565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61516480620001776000396000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80635d83d967116100ee57806386fa424611610097578063d8bc7b6811610071578063d8bc7b68146103f6578063ddbe4f8214610409578063e29581aa1461041e578063f2fde38b1461043357600080fd5b806386fa42461461039b5780638da5cb5b146103ae5780639cb7c5f4146103d657600080fd5b8063715f5295116100c8578063715f52951461036d57806373ac22b41461038057806379ba50971461039357600080fd5b80635d83d967146103325780635e65e3091461034557806366acaa331461035857600080fd5b8063235374051161015b5780632c01a1e8116101355780632c01a1e8146102cb578063398f3773146102de5780633f2a13c9146102f157806350c946fe1461031257600080fd5b80632353740514610285578063275459f2146102a55780632a852933146102b857600080fd5b80631d05394c1161018c5780631d05394c1461023b578063214502431461025057806322bdbcbc1461026557600080fd5b80630fe5800a146101b357806312570011146101d9578063181f5a77146101fc575b600080fd5b6101c66101c1366004613f46565b610446565b6040519081526020015b60405180910390f35b6101ec6101e7366004613faa565b61047a565b60405190151581526020016101d0565b604080518082018252601a81527f4361706162696c6974696573526567697374727920312e302e30000000000000602082015290516101d09190614031565b61024e610249366004614089565b610487565b005b61025861069c565b6040516101d0919061420b565b6102786102733660046142a6565b6107f9565b6040516101d091906142fe565b6102986102933660046142a6565b6108e6565b6040516101d09190614311565b61024e6102b3366004614089565b61092a565b61024e6102c6366004614345565b610a01565b61024e6102d9366004614089565b610ae1565b61024e6102ec366004614089565b610d7d565b6103046102ff3660046143e7565b610f3c565b6040516101d0929190614411565b610325610320366004613faa565b611128565b6040516101d091906144d6565b61024e610340366004614089565b611202565b61024e610353366004614089565b6112f7565b610360611a1f565b6040516101d091906144e9565b61024e61037b366004614089565b611c02565b61024e61038e366004614089565b611cb4565b61024e612182565b61024e6103a936600461455e565b61227f565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d0565b6103e96103e4366004613faa565b6125bf565b6040516101d091906146ad565b61024e6104043660046146c0565b6127fa565b6104116128c4565b6040516101d09190614746565b6104266129b8565b6040516101d091906147bb565b61024e610441366004614854565b612ac1565b6000828260405160200161045b929190614411565b6040516020818303038152906040528051906020012090505b92915050565b6000610474600583612ad5565b61048f612af0565b60005b818110156106975760008383838181106104ae576104ae61486f565b90506020020160208101906104c391906142a6565b63ffffffff8181166000908152600d60209081526040808320805464010000000081049095168085526001820190935290832094955093909290916a010000000000000000000090910460ff16905b61051b83612b73565b8110156105bb57811561057157600c60006105368584612b7d565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556105b3565b6105b18663ffffffff16600c60006105928588612b7d90919063ffffffff16565b8152602001908152602001600020600401612b8990919063ffffffff16565b505b600101610512565b508354640100000000900463ffffffff16600003610612576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff861660048201526024015b60405180910390fd5b63ffffffff85166000818152600d6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffff00000000000000000000001690558051938452908301919091527ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c1581703651910160405180910390a15050505050806001019050610492565b505050565b600e54606090640100000000900463ffffffff1660006106bd6001836148cd565b63ffffffff1667ffffffffffffffff8111156106db576106db613de0565b60405190808252806020026020018201604052801561076257816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816106f95790505b509050600060015b8363ffffffff168163ffffffff1610156107d65763ffffffff8082166000908152600d602052604090205416156107ce576107a481612b95565b8383815181106107b6576107b661486f565b6020026020010181905250816107cb906148ea565b91505b60010161076a565b506107e26001846148cd565b63ffffffff1681146107f2578082525b5092915050565b60408051808201909152600081526060602082015263ffffffff82166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161085d90614922565b80601f016020809104026020016040519081016040528092919081815260200182805461088990614922565b80156108d65780601f106108ab576101008083540402835291602001916108d6565b820191906000526020600020905b8154815290600101906020018083116108b957829003601f168201915b5050505050815250509050919050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c081019190915261047482612b95565b610932612af0565b60005b63ffffffff811682111561069757600083838363ffffffff1681811061095d5761095d61486f565b905060200201602081019061097291906142a6565b63ffffffff81166000908152600b6020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559192506109bd6001830182613d73565b505060405163ffffffff8216907fa59268ca81d40429e65ccea5385b59cf2d3fc6519371dee92f8eb1dae5107a7a90600090a2506109fa81614975565b9050610935565b610a09612af0565b63ffffffff8088166000908152600d60205260408120805490926401000000009091041690819003610a6f576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff8a166004820152602401610609565b610ad6888888886040518060a001604052808f63ffffffff16815260200187610a9790614975565b63ffffffff811682528b15156020830152895460ff6a01000000000000000000009091048116151560408401528b166060909201919091529650612e60565b505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d77576000848483818110610b1b57610b1b61486f565b602090810292909201356000818152600c90935260409092206001810154929350919050610b78576040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260048101839052602401610609565b6000610b8682600401612b73565b1115610bdb57610b996004820184612b7d565b6040517f60a6d89800000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101839052604401610609565b805468010000000000000000900463ffffffff1615610c435780546040517f60b9df730000000000000000000000000000000000000000000000000000000081526801000000000000000090910463ffffffff16600482015260248101839052604401610609565b83158015610c7d5750805463ffffffff166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15610cb6576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6001810154610cc790600790612b89565b506002810154610cd990600990612b89565b506000828152600c6020526040812080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815560018101829055600281018290559060048201818181610d2e8282613dad565b5050505050507f5254e609a97bab37b7cc79fe128f85c097bd6015c6e1624ae0ba392eb975320582604051610d6591815260200190565b60405180910390a15050600101610aff565b50505050565b610d85612af0565b60005b81811015610697576000838383818110610da457610da461486f565b9050602002810190610db69190614998565b610dbf906149d6565b805190915073ffffffffffffffffffffffffffffffffffffffff16610e10576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815263ffffffff9095166000818152600b909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251919290916001820190610e9c9082614a90565b5050600e8054909150600090610eb79063ffffffff16614975565b91906101000a81548163ffffffff021916908363ffffffff160217905550816000015173ffffffffffffffffffffffffffffffffffffffff168163ffffffff167f78e94ca80be2c30abc061b99e7eb8583b1254781734b1e3ce339abb57da2fe8e8460200151604051610f2a9190614031565b60405180910390a35050600101610d88565b63ffffffff8083166000908152600d60209081526040808320805464010000000090049094168084526001909401825280832085845260030190915281208054606093849390929091610f8e90614922565b80601f0160208091040260200160405190810160405280929190818152602001828054610fba90614922565b80156110075780601f10610fdc57610100808354040283529160200191611007565b820191906000526020600020905b815481529060010190602001808311610fea57829003601f168201915b5050506000888152600260208190526040909120015492935060609262010000900473ffffffffffffffffffffffffffffffffffffffff1615915061111a905057600086815260026020819052604091829020015490517f8318ed5d00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526201000090910473ffffffffffffffffffffffffffffffffffffffff1690638318ed5d90602401600060405180830381865afa1580156110d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111179190810190614baa565b90505b9093509150505b9250929050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c08101919091526040805160e0810182526000848152600c6020908152838220805463ffffffff8082168652640100000000820481168487018190526801000000000000000090920416858701526001820154606086015260028201546080860152835260030190529190912060a08201906111d790613685565b81526020016111fa600c6000868152602001908152602001600020600401613685565b905292915050565b61120a612af0565b60005b818110156106975760008383838181106112295761122961486f565b905060200201359050611246816003612ad590919063ffffffff16565b61127f576040517fe181733f00000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b61128a600582613692565b6112c3576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b60405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a25060010161120d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d775760008484838181106113315761133161486f565b90506020028101906113439190614c18565b61134c90614c4c565b6040808201516000908152600c6020908152828220805463ffffffff168352600b82528383208451808601909552805473ffffffffffffffffffffffffffffffffffffffff16855260018101805496975091959394939092840191906113b190614922565b80601f01602080910402602001604051908101604052809291908181526020018280546113dd90614922565b801561142a5780601f106113ff5761010080835404028352916020019161142a565b820191906000526020600020905b81548152906001019060200180831161140d57829003601f168201915b50505091909252505050600183015490915061147a5782604001516040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b8415801561149f5750805173ffffffffffffffffffffffffffffffffffffffff163314155b156114d8576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6020830151611513576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018201546020840151811461159457602084015161153490600790612ad5565b1561156b576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208401516001840155611580600782612b89565b50602084015161159290600790613692565b505b606084015180516000036115d657806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614d1f565b835460009085906004906115f790640100000000900463ffffffff16614975565b91906101000a81548163ffffffff021916908363ffffffff1602179055905060005b82518110156116dc5761164f8382815181106116375761163761486f565b60200260200101516003612ad590919063ffffffff16565b61168757826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614d1f565b6116d383828151811061169c5761169c61486f565b60200260200101518760030160008563ffffffff1663ffffffff16815260200190815260200160002061369290919063ffffffff16565b50600101611619565b50845468010000000000000000900463ffffffff16801561183d5763ffffffff8082166000908152600d60209081526040808320805464010000000090049094168352600190930181528282206002018054845181840281018401909552808552929392909183018282801561177157602002820191906000526020600020905b81548152602001906001019080831161175d575b5050505050905060005b815181101561183a576117d08282815181106117995761179961486f565b60200260200101518960030160008763ffffffff1663ffffffff168152602001908152602001600020612ad590919063ffffffff16565b611832578181815181106117e6576117e661486f565b6020026020010151836040517f03dcd86200000000000000000000000000000000000000000000000000000000815260040161060992919091825263ffffffff16602082015260400190565b60010161177b565b50505b600061184b87600401613685565b905060005b81518163ffffffff161015611991576000828263ffffffff16815181106118795761187961486f565b60209081029190910181015163ffffffff8082166000908152600d8452604080822080546401000000009004909316825260019092018452818120600201805483518187028101870190945280845293955090939192909183018282801561190057602002820191906000526020600020905b8154815260200190600101908083116118ec575b5050505050905060005b815181101561197d5761195f8282815181106119285761192861486f565b60200260200101518c60030160008a63ffffffff1663ffffffff168152602001908152602001600020612ad590919063ffffffff16565b611975578181815181106117e6576117e661486f565b60010161190a565b5050508061198a90614975565b9050611850565b50875187547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90911690811788556040808a015160028a018190556020808c01518351928352908201527f4b5b465e22eea0c3d40c30e936643245b80d19b2dcf75788c0699fe8d8db645b910160405180910390a25050505050505050806001019050611315565b600e5460609063ffffffff166000611a386001836148cd565b63ffffffff1667ffffffffffffffff811115611a5657611a56613de0565b604051908082528060200260200182016040528015611a9c57816020015b604080518082019091526000815260606020820152815260200190600190039081611a745790505b509050600060015b8363ffffffff168163ffffffff161015611bec5763ffffffff81166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611be45763ffffffff81166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191611b3890614922565b80601f0160208091040260200160405190810160405280929190818152602001828054611b6490614922565b8015611bb15780601f10611b8657610100808354040283529160200191611bb1565b820191906000526020600020905b815481529060010190602001808311611b9457829003601f168201915b505050505081525050838381518110611bcc57611bcc61486f565b602002602001018190525081611be1906148ea565b91505b600101611aa4565b50600e546107e29060019063ffffffff166148cd565b611c0a612af0565b60005b81811015610697576000838383818110611c2957611c2961486f565b9050602002810190611c3b9190614d63565b611c4490614da6565b90506000611c5a82600001518360200151610446565b9050611c67600382613692565b611ca0576040517febf5255100000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b611caa818361369e565b5050600101611c0d565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d77576000848483818110611cee57611cee61486f565b9050602002810190611d009190614c18565b611d0990614c4c565b805163ffffffff166000908152600b602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191611d5f90614922565b80601f0160208091040260200160405190810160405280929190818152602001828054611d8b90614922565b8015611dd85780601f10611dad57610100808354040283529160200191611dd8565b820191906000526020600020905b815481529060010190602001808311611dbb57829003601f168201915b50505091909252505081519192505073ffffffffffffffffffffffffffffffffffffffff16611e3e5781516040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff9091166004820152602401610609565b83158015611e635750805173ffffffffffffffffffffffffffffffffffffffff163314155b15611e9c576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6040808301516000908152600c60205220600181015415611ef15782604001516040517f5461848300000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b6040830151611f345782604001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b60208301511580611f5157506020830151611f5190600790612ad5565b15611f88576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608301518051600003611fca57806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614d1f565b81548290600490611fe890640100000000900463ffffffff16614975565b82546101009290920a63ffffffff818102199093169183160217909155825464010000000090041660005b82518110156120be576120318382815181106116375761163761486f565b61206957826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614d1f565b6120b583828151811061207e5761207e61486f565b60200260200101518560030160008563ffffffff1663ffffffff16815260200190815260200160002061369290919063ffffffff16565b50600101612013565b50845183547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff91821617845560408601516002850155602086015160018501819055612114916007919061369216565b50604085015161212690600990613692565b50845160408087015160208089015183519283529082015263ffffffff909216917f74becb12a5e8fd0e98077d02dfba8f647c9670c9df177e42c2418cf17a636f05910160405180910390a25050505050806001019050611cd2565b60015473ffffffffffffffffffffffffffffffffffffffff163314612203576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610609565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b8281146122c2576040517fab8b67c60000000000000000000000000000000000000000000000000000000081526004810184905260248101829052604401610609565b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156125b75760008686838181106122fa576122fa61486f565b905060200201602081019061230f91906142a6565b63ffffffff81166000908152600b6020526040902080549192509073ffffffffffffffffffffffffffffffffffffffff1661237e576040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff83166004820152602401610609565b60008686858181106123925761239261486f565b90506020028101906123a49190614998565b6123ad906149d6565b805190915073ffffffffffffffffffffffffffffffffffffffff166123fe576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815473ffffffffffffffffffffffffffffffffffffffff16331480159061243b57503373ffffffffffffffffffffffffffffffffffffffff861614155b15612474576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b8051825473ffffffffffffffffffffffffffffffffffffffff90811691161415806124f057506020808201516040516124ad9201614031565b60405160208183030381529060405280519060200120826001016040516020016124d79190614e4c565b6040516020818303038152906040528051906020012014155b156125a957805182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020810151600183019061254a9082614a90565b50806000015173ffffffffffffffffffffffffffffffffffffffff168363ffffffff167f86f41145bde5dd7f523305452e4aad3685508c181432ec733d5f345009358a2883602001516040516125a09190614031565b60405180910390a35b5050508060010190506122de565b505050505050565b6126006040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b6040805160e0810182528381526000848152600260209081529290208054919283019161262c90614922565b80601f016020809104026020016040519081016040528092919081815260200182805461265890614922565b80156126a55780601f1061267a576101008083540402835291602001916126a5565b820191906000526020600020905b81548152906001019060200180831161268857829003601f168201915b505050505081526020016002600085815260200190815260200160002060010180546126d090614922565b80601f01602080910402602001604051908101604052809291908181526020018280546126fc90614922565b80156127495780601f1061271e57610100808354040283529160200191612749565b820191906000526020600020905b81548152906001019060200180831161272c57829003601f168201915b50505091835250506000848152600260208181526040909220015491019060ff16600381111561277b5761277b6145ca565b815260008481526002602081815260409092200154910190610100900460ff1660018111156127ac576127ac6145ca565b81526000848152600260208181526040928390209091015462010000900473ffffffffffffffffffffffffffffffffffffffff1690830152016127f0600585612ad5565b1515905292915050565b612802612af0565b600e805460009164010000000090910463ffffffff1690600461282483614975565b82546101009290920a63ffffffff81810219909316918316021790915581166000818152600d602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001684179055815160a08101835292835260019083015286151590820152841515606082015260ff841660808201529091506128ba908990899089908990612e60565b5050505050505050565b606060006128d26003613685565b90506000815167ffffffffffffffff8111156128f0576128f0613de0565b60405190808252806020026020018201604052801561296257816020015b61294f6040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b81526020019060019003908161290e5790505b50905060005b82518110156107f2576129938382815181106129865761298661486f565b60200260200101516125bf565b8282815181106129a5576129a561486f565b6020908102919091010152600101612968565b606060006129c66009613685565b90506000815167ffffffffffffffff8111156129e4576129e4613de0565b604051908082528060200260200182016040528015612a6b57816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181612a025790505b50905060005b82518110156107f257612a9c838281518110612a8f57612a8f61486f565b6020026020010151611128565b828281518110612aae57612aae61486f565b6020908102919091010152600101612a71565b612ac9612af0565b612ad281613886565b50565b600081815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612b71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610609565b565b6000610474825490565b6000612ae9838361397b565b6000612ae983836139a5565b6040805160e0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840181905260c084015263ffffffff8581168352600d8252848320805464010000000090049091168084526001909101825284832060028101805487518186028101860190985280885295969295919493909190830182828015612c4657602002820191906000526020600020905b815481526020019060010190808311612c32575b505050505090506000815167ffffffffffffffff811115612c6957612c69613de0565b604051908082528060200260200182016040528015612caf57816020015b604080518082019091526000815260606020820152815260200190600190039081612c875790505b50905060005b8151811015612dc7576040518060400160405280848381518110612cdb57612cdb61486f565b60200260200101518152602001856003016000868581518110612d0057612d0061486f565b602002602001015181526020019081526020016000208054612d2190614922565b80601f0160208091040260200160405190810160405280929190818152602001828054612d4d90614922565b8015612d9a5780601f10612d6f57610100808354040283529160200191612d9a565b820191906000526020600020905b815481529060010190602001808311612d7d57829003601f168201915b5050505050815250828281518110612db457612db461486f565b6020908102919091010152600101612cb5565b506040805160e08101825263ffffffff8089166000818152600d6020818152868320548086168752948b168187015260ff680100000000000000008604811697870197909752690100000000000000000085048716151560608701529290915290526a010000000000000000000090049091161515608082015260a08101612e4e85613685565b81526020019190915295945050505050565b805163ffffffff9081166000908152600d602090815260408083208286015190941683526001909301905220608082015160ff161580612eb2575060808201518590612ead906001614efa565b60ff16115b15612efb5760808201516040517f25b4d61800000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101869052604401610609565b6001826020015163ffffffff161115612fe357815163ffffffff166000908152600d602090815260408220908401516001918201918391612f3c91906148cd565b63ffffffff1663ffffffff168152602001908152602001600020905060005b612f6482612b73565b811015612fe057612f93846000015163ffffffff16600c60006105928587600001612b7d90919063ffffffff16565b50600c6000612fa28484612b7d565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff169055600101612f5b565b50505b60005b8581101561321d576130138787838181106130035761300361486f565b8592602090910201359050613692565b61307457825187878381811061302b5761302b61486f565b6040517f636e405700000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8260600151156131cb57825163ffffffff16600c600089898581811061309c5761309c61486f565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff16148015906131165750600c60008888848181106130e7576130e761486f565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff1615155b1561317857825187878381811061312f5761312f61486f565b6040517f60b9df7300000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8251600c60008989858181106131905761319061486f565b90506020020135815260200190815260200160002060000160086101000a81548163ffffffff021916908363ffffffff160217905550613215565b82516132139063ffffffff16600c60008a8a868181106131ed576131ed61486f565b90506020020135815260200190815260200160002060040161369290919063ffffffff16565b505b600101612fe6565b5060005b8381101561362b573685858381811061323c5761323c61486f565b905060200281019061324e9190614998565b905061325c60038235612ad5565b613295576040517fe181733f00000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b6132a160058235612ad5565b156132db576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b80356000908152600384016020526040812080546132f890614922565b905011156133445783516040517f3927d08000000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015281356024820152604401610609565b60005b8781101561344e576133eb8235600c60008c8c8681811061336a5761336a61486f565b9050602002013581526020019081526020016000206003016000600c60008e8e8881811061339a5761339a61486f565b90506020020135815260200190815260200160002060000160049054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020612ad590919063ffffffff16565b613446578888828181106134015761340161486f565b6040517fa7e792500000000000000000000000000000000000000000000000000000000081526020909102929092013560048301525082356024820152604401610609565b600101613347565b506002830180546001810182556000918252602091829020833591015561347790820182614f13565b82356000908152600386016020526040902091613495919083614f78565b50604080850151855163ffffffff9081166000908152600d602090815284822080549415156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff90951694909417909355606088015188518316825284822080549115156a0100000000000000000000027fffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff9092169190911790556080880151885183168252848220805460ff9290921668010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff909216919091179055828801805189518416835294909120805494909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9094169390931790558551915161362292918435908c908c906135e890880188614f13565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a9892505050565b50600101613221565b50815160208301516040517ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c15817036519261367592909163ffffffff92831681529116602082015260400190565b60405180910390a1505050505050565b60606000612ae983613b79565b6000612ae98383613bd5565b608081015173ffffffffffffffffffffffffffffffffffffffff1615613740576136ec81608001517f78bea72100000000000000000000000000000000000000000000000000000000613c24565b6137405760808101516040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610609565b60008281526002602052604090208151829190819061375f9082614a90565b50602082015160018201906137749082614a90565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660018360038111156137b6576137b66145ca565b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156137fd576137fd6145ca565b0217905550608091909101516002909101805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff90921691909117905560405182907f04f0a9bcf3f3a3b42a4d7ca081119755f82ebe43e0d30c8f7292c4fe0dc4a2ae90600090a25050565b3373ffffffffffffffffffffffffffffffffffffffff821603613905576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610609565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008260000182815481106139925761399261486f565b9060005260206000200154905092915050565b60008181526001830160205260408120548015613a8e5760006139c9600183615093565b85549091506000906139dd90600190615093565b9050818114613a425760008660000182815481106139fd576139fd61486f565b9060005260206000200154905080876000018481548110613a2057613a2061486f565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613a5357613a536150a6565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610474565b6000915050610474565b6000848152600260208190526040909120015462010000900473ffffffffffffffffffffffffffffffffffffffff16156125b757600084815260026020819052604091829020015490517ffba64a7c0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169063fba64a7c90613b3f908690869086908b908d906004016150d5565b600060405180830381600087803b158015613b5957600080fd5b505af1158015613b6d573d6000803e3d6000fd5b50505050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015613bc957602002820191906000526020600020905b815481526020019060010190808311613bb5575b50505050509050919050565b6000818152600183016020526040812054613c1c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610474565b506000610474565b6000613c2f83613c40565b8015612ae95750612ae98383613ca4565b6000613c6c827f01ffc9a700000000000000000000000000000000000000000000000000000000613ca4565b80156104745750613c9d827fffffffff00000000000000000000000000000000000000000000000000000000613ca4565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613d5c575060208210155b8015613d685750600081115b979650505050505050565b508054613d7f90614922565b6000825580601f10613d8f575050565b601f016020900490600052602060002090810190612ad29190613dc7565b5080546000825590600052602060002090810190612ad291905b5b80821115613ddc5760008155600101613dc8565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613e3257613e32613de0565b60405290565b60405160a0810167ffffffffffffffff81118282101715613e3257613e32613de0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613ea257613ea2613de0565b604052919050565b600067ffffffffffffffff821115613ec457613ec4613de0565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613f0157600080fd5b8135613f14613f0f82613eaa565b613e5b565b818152846020838601011115613f2957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613f5957600080fd5b823567ffffffffffffffff80821115613f7157600080fd5b613f7d86838701613ef0565b93506020850135915080821115613f9357600080fd5b50613fa085828601613ef0565b9150509250929050565b600060208284031215613fbc57600080fd5b5035919050565b60005b83811015613fde578181015183820152602001613fc6565b50506000910152565b60008151808452613fff816020860160208601613fc3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612ae96020830184613fe7565b60008083601f84011261405657600080fd5b50813567ffffffffffffffff81111561406e57600080fd5b6020830191508360208260051b850101111561112157600080fd5b6000806020838503121561409c57600080fd5b823567ffffffffffffffff8111156140b357600080fd5b6140bf85828601614044565b90969095509350505050565b60008151808452602080850194506020840160005b838110156140fc578151875295820195908201906001016140e0565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b84811015614184578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018952815180518452840151604085850181905261417081860183613fe7565b9a86019a9450505090830190600101614124565b5090979650505050505050565b600063ffffffff8083511684528060208401511660208501525060ff604083015116604084015260608201511515606084015260808201511515608084015260a082015160e060a08501526141e960e08501826140cb565b905060c083015184820360c08601526142028282614107565b95945050505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614280577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261426e858351614191565b94509285019290850190600101614234565b5092979650505050505050565b803563ffffffff811681146142a157600080fd5b919050565b6000602082840312156142b857600080fd5b612ae98261428d565b73ffffffffffffffffffffffffffffffffffffffff815116825260006020820151604060208501526142f66040850182613fe7565b949350505050565b602081526000612ae960208301846142c1565b602081526000612ae96020830184614191565b803580151581146142a157600080fd5b803560ff811681146142a157600080fd5b600080600080600080600060a0888a03121561436057600080fd5b6143698861428d565b9650602088013567ffffffffffffffff8082111561438657600080fd5b6143928b838c01614044565b909850965060408a01359150808211156143ab57600080fd5b506143b88a828b01614044565b90955093506143cb905060608901614324565b91506143d960808901614334565b905092959891949750929550565b600080604083850312156143fa57600080fd5b6144038361428d565b946020939093013593505050565b6040815260006144246040830185613fe7565b82810360208401526142028185613fe7565b600063ffffffff808351168452602081818501511681860152816040850151166040860152606084015160608601526080840151608086015260a0840151915060e060a086015261448a60e08601836140cb565b60c08581015187830391880191909152805180835290830193506000918301905b808310156144cb57845182529383019360019290920191908301906144ab565b509695505050505050565b602081526000612ae96020830184614436565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614280577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261454c8583516142c1565b94509285019290850190600101614512565b6000806000806040858703121561457457600080fd5b843567ffffffffffffffff8082111561458c57600080fd5b61459888838901614044565b909650945060208701359150808211156145b157600080fd5b506145be87828801614044565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b805182526000602082015160e0602085015261461860e0850182613fe7565b9050604083015184820360408601526146318282613fe7565b915050606083015160048110614649576146496145ca565b6060850152608083015160028110614663576146636145ca565b8060808601525060a083015161469160a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c08301516146a560c086018215159052565b509392505050565b602081526000612ae960208301846145f9565b600080600080600080600060a0888a0312156146db57600080fd5b873567ffffffffffffffff808211156146f357600080fd5b6146ff8b838c01614044565b909950975060208a013591508082111561471857600080fd5b506147258a828b01614044565b9096509450614738905060408901614324565b92506143cb60608901614324565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614280577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526147a98583516145f9565b9450928501929085019060010161476f565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614280577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261481e858351614436565b945092850192908501906001016147e4565b803573ffffffffffffffffffffffffffffffffffffffff811681146142a157600080fd5b60006020828403121561486657600080fd5b612ae982614830565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff8281168282160390808211156107f2576107f261489e565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361491b5761491b61489e565b5060010190565b600181811c9082168061493657607f821691505b60208210810361496f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600063ffffffff80831681810361498e5761498e61489e565b6001019392505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126149cc57600080fd5b9190910192915050565b6000604082360312156149e857600080fd5b6040516040810167ffffffffffffffff8282108183111715614a0c57614a0c613de0565b81604052614a1985614830565b83526020850135915080821115614a2f57600080fd5b50614a3c36828601613ef0565b60208301525092915050565b601f821115610697576000816000526020600020601f850160051c81016020861015614a715750805b601f850160051c820191505b818110156125b757828155600101614a7d565b815167ffffffffffffffff811115614aaa57614aaa613de0565b614abe81614ab88454614922565b84614a48565b602080601f831160018114614b115760008415614adb5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556125b7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614b5e57888601518255948401946001909101908401614b3f565b5085821015614b9a57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215614bbc57600080fd5b815167ffffffffffffffff811115614bd357600080fd5b8201601f81018413614be457600080fd5b8051614bf2613f0f82613eaa565b818152856020838501011115614c0757600080fd5b614202826020830160208601613fc3565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126149cc57600080fd5b600060808236031215614c5e57600080fd5b614c66613e0f565b614c6f8361428d565b81526020808401358183015260408401356040830152606084013567ffffffffffffffff80821115614ca057600080fd5b9085019036601f830112614cb357600080fd5b813581811115614cc557614cc5613de0565b8060051b9150614cd6848301613e5b565b8181529183018401918481019036841115614cf057600080fd5b938501935b83851015614d0e57843582529385019390850190614cf5565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614d5757835183529284019291840191600101614d3b565b50909695505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff618336030181126149cc57600080fd5b8035600281106142a157600080fd5b600060a08236031215614db857600080fd5b614dc0613e38565b823567ffffffffffffffff80821115614dd857600080fd5b614de436838701613ef0565b83526020850135915080821115614dfa57600080fd5b50614e0736828601613ef0565b602083015250604083013560048110614e1f57600080fd5b6040820152614e3060608401614d97565b6060820152614e4160808401614830565b608082015292915050565b6000602080835260008454614e6081614922565b8060208701526040600180841660008114614e825760018114614ebc57614eec565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550614eec565b89600052602060002060005b85811015614ee35781548b8201860152908301908801614ec8565b8a016040019650505b509398975050505050505050565b60ff81811683821601908111156104745761047461489e565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614f4857600080fd5b83018035915067ffffffffffffffff821115614f6357600080fd5b60200191503681900382131561112157600080fd5b67ffffffffffffffff831115614f9057614f90613de0565b614fa483614f9e8354614922565b83614a48565b6000601f841160018114614ff65760008515614fc05750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561508c565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156150455786850135825560209485019460019092019101615025565b5086821015615080577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b818103818111156104745761047461489e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6080815284608082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86111561510e57600080fd5b8560051b808860a0850137820182810360a0908101602085015261513490820187613fe7565b91505063ffffffff8085166040840152808416606084015250969550505050505056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityIsDeprecated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"CapabilityRequiredByDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"DONDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateDONNode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"nodeCount\",\"type\":\"uint256\"}],\"name\":\"InvalidFaultTolerance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"InvalidNodeCapabilities\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"InvalidNodeP2PId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"NodeDoesNotSupportCapability\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfCapabilitiesDON\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nodeP2PId\",\"type\":\"bytes32\"}],\"name\":\"NodePartOfWorkflowDON\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"}],\"name\":\"NodeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilitiesRegistry.Capability[]\",\"name\":\"capabilities\",\"type\":\"tuple[]\"}],\"name\":\"addCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"addDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"addNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"deprecateCapabilities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityType\",\"name\":\"capabilityType\",\"type\":\"uint8\"},{\"internalType\":\"enumCapabilitiesRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isDeprecated\",\"type\":\"bool\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityConfigs\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"getDON\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"acceptsWorkflows\",\"type\":\"bool\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodeP2PIds\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"}],\"internalType\":\"structCapabilitiesRegistry.DONInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"labelledName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"getHashedCapabilityId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"getNode\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo\",\"name\":\"nodeInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodeOperators\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNodes\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"workflowDONId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256[]\",\"name\":\"capabilitiesDONIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"isCapabilityDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"donIds\",\"type\":\"uint32[]\"}],\"name\":\"removeDONs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"removedNodeP2PIds\",\"type\":\"bytes32[]\"}],\"name\":\"removeNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"nodes\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCapabilitiesRegistry.CapabilityConfiguration[]\",\"name\":\"capabilityConfigurations\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"updateDON\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint32[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilitiesRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nodeOperatorId\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"signer\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilitiesRegistry.NodeParams[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"updateNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6080604052600e80546001600160401b0319166401000000011790553480156200002857600080fd5b503380600081620000805760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000b357620000b381620000bc565b50505062000167565b336001600160a01b03821603620001165760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000077565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61514e80620001776000396000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80635d83d967116100ee57806386fa424611610097578063d8bc7b6811610071578063d8bc7b68146103f6578063ddbe4f8214610409578063e29581aa1461041e578063f2fde38b1461043357600080fd5b806386fa42461461039b5780638da5cb5b146103ae5780639cb7c5f4146103d657600080fd5b8063715f5295116100c8578063715f52951461036d57806373ac22b41461038057806379ba50971461039357600080fd5b80635d83d967146103325780635e65e3091461034557806366acaa331461035857600080fd5b8063235374051161015b5780632c01a1e8116101355780632c01a1e8146102cb578063398f3773146102de5780633f2a13c9146102f157806350c946fe1461031257600080fd5b80632353740514610285578063275459f2146102a55780632a852933146102b857600080fd5b80631d05394c1161018c5780631d05394c1461023b578063214502431461025057806322bdbcbc1461026557600080fd5b80630fe5800a146101b357806312570011146101d9578063181f5a77146101fc575b600080fd5b6101c66101c1366004613f30565b610446565b6040519081526020015b60405180910390f35b6101ec6101e7366004613f94565b61047a565b60405190151581526020016101d0565b604080518082018252601a81527f4361706162696c6974696573526567697374727920312e302e30000000000000602082015290516101d0919061401b565b61024e610249366004614073565b610487565b005b610258610694565b6040516101d091906141f5565b610278610273366004614290565b6107f1565b6040516101d091906142e8565b610298610293366004614290565b6108de565b6040516101d091906142fb565b61024e6102b3366004614073565b610922565b61024e6102c636600461432f565b6109f9565b61024e6102d9366004614073565b610ad9565b61024e6102ec366004614073565b610d75565b6103046102ff3660046143d1565b610f34565b6040516101d09291906143fb565b610325610320366004613f94565b611120565b6040516101d091906144c0565b61024e610340366004614073565b6111fa565b61024e610353366004614073565b6112ef565b610360611a17565b6040516101d091906144d3565b61024e61037b366004614073565b611bfa565b61024e61038e366004614073565b611cac565b61024e61217a565b61024e6103a9366004614548565b612277565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d0565b6103e96103e4366004613f94565b6125b7565b6040516101d09190614697565b61024e6104043660046146aa565b6127f2565b6104116128bc565b6040516101d09190614730565b6104266129b0565b6040516101d091906147a5565b61024e61044136600461483e565b612ab9565b6000828260405160200161045b9291906143fb565b6040516020818303038152906040528051906020012090505b92915050565b6000610474600583612acd565b61048f612ae8565b60005b8181101561068f5760008383838181106104ae576104ae614859565b90506020020160208101906104c39190614290565b63ffffffff8181166000908152600d60209081526040808320805464010000000081049095168085526001820190935290832094955093909290916a010000000000000000000090910460ff16905b61051b83612b6b565b8110156105bb57811561057157600c60006105368584612b75565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff1690556105b3565b6105b18663ffffffff16600c60006105928588612b7590919063ffffffff16565b8152602001908152602001600020600401612b8190919063ffffffff16565b505b600101610512565b508354640100000000900463ffffffff16600003610612576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff861660048201526024015b60405180910390fd5b63ffffffff85166000818152600d6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffff0000000000000000000000169055519182527ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c1581703651910160405180910390a25050505050806001019050610492565b505050565b600e54606090640100000000900463ffffffff1660006106b56001836148b7565b63ffffffff1667ffffffffffffffff8111156106d3576106d3613dca565b60405190808252806020026020018201604052801561075a57816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816106f15790505b509050600060015b8363ffffffff168163ffffffff1610156107ce5763ffffffff8082166000908152600d602052604090205416156107c65761079c81612b8d565b8383815181106107ae576107ae614859565b6020026020010181905250816107c3906148d4565b91505b600101610762565b506107da6001846148b7565b63ffffffff1681146107ea578082525b5092915050565b60408051808201909152600081526060602082015263ffffffff82166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff16835260018101805491928401916108559061490c565b80601f01602080910402602001604051908101604052809291908181526020018280546108819061490c565b80156108ce5780601f106108a3576101008083540402835291602001916108ce565b820191906000526020600020905b8154815290600101906020018083116108b157829003601f168201915b5050505050815250509050919050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c081019190915261047482612b8d565b61092a612ae8565b60005b63ffffffff811682111561068f57600083838363ffffffff1681811061095557610955614859565b905060200201602081019061096a9190614290565b63ffffffff81166000908152600b6020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559192506109b56001830182613d5d565b505060405163ffffffff8216907fa59268ca81d40429e65ccea5385b59cf2d3fc6519371dee92f8eb1dae5107a7a90600090a2506109f28161495f565b905061092d565b610a01612ae8565b63ffffffff8088166000908152600d60205260408120805490926401000000009091041690819003610a67576040517f2b62be9b00000000000000000000000000000000000000000000000000000000815263ffffffff8a166004820152602401610609565b610ace888888886040518060a001604052808f63ffffffff16815260200187610a8f9061495f565b63ffffffff811682528b15156020830152895460ff6a01000000000000000000009091048116151560408401528b166060909201919091529650612e58565b505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d6f576000848483818110610b1357610b13614859565b602090810292909201356000818152600c90935260409092206001810154929350919050610b70576040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260048101839052602401610609565b6000610b7e82600401612b6b565b1115610bd357610b916004820184612b75565b6040517f60a6d89800000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101839052604401610609565b805468010000000000000000900463ffffffff1615610c3b5780546040517f60b9df730000000000000000000000000000000000000000000000000000000081526801000000000000000090910463ffffffff16600482015260248101839052604401610609565b83158015610c755750805463ffffffff166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15610cae576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6001810154610cbf90600790612b81565b506002810154610cd190600990612b81565b506000828152600c6020526040812080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815560018101829055600281018290559060048201818181610d268282613d97565b5050505050507f5254e609a97bab37b7cc79fe128f85c097bd6015c6e1624ae0ba392eb975320582604051610d5d91815260200190565b60405180910390a15050600101610af7565b50505050565b610d7d612ae8565b60005b8181101561068f576000838383818110610d9c57610d9c614859565b9050602002810190610dae9190614982565b610db7906149c0565b805190915073ffffffffffffffffffffffffffffffffffffffff16610e08576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815263ffffffff9095166000818152600b909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251919290916001820190610e949082614a7a565b5050600e8054909150600090610eaf9063ffffffff1661495f565b91906101000a81548163ffffffff021916908363ffffffff160217905550816000015173ffffffffffffffffffffffffffffffffffffffff168163ffffffff167f78e94ca80be2c30abc061b99e7eb8583b1254781734b1e3ce339abb57da2fe8e8460200151604051610f22919061401b565b60405180910390a35050600101610d80565b63ffffffff8083166000908152600d60209081526040808320805464010000000090049094168084526001909401825280832085845260030190915281208054606093849390929091610f869061490c565b80601f0160208091040260200160405190810160405280929190818152602001828054610fb29061490c565b8015610fff5780601f10610fd457610100808354040283529160200191610fff565b820191906000526020600020905b815481529060010190602001808311610fe257829003601f168201915b5050506000888152600260208190526040909120015492935060609262010000900473ffffffffffffffffffffffffffffffffffffffff16159150611112905057600086815260026020819052604091829020015490517f8318ed5d00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526201000090910473ffffffffffffffffffffffffffffffffffffffff1690638318ed5d90602401600060405180830381865afa1580156110c9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261110f9190810190614b94565b90505b9093509150505b9250929050565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082019290925260a0810182905260c08101919091526040805160e0810182526000848152600c6020908152838220805463ffffffff8082168652640100000000820481168487018190526801000000000000000090920416858701526001820154606086015260028201546080860152835260030190529190912060a08201906111cf9061366f565b81526020016111f2600c600086815260200190815260200160002060040161366f565b905292915050565b611202612ae8565b60005b8181101561068f57600083838381811061122157611221614859565b90506020020135905061123e816003612acd90919063ffffffff16565b611277576040517fe181733f00000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b61128260058261367c565b6112bb576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b60405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a250600101611205565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d6f57600084848381811061132957611329614859565b905060200281019061133b9190614c02565b61134490614c36565b6040808201516000908152600c6020908152828220805463ffffffff168352600b82528383208451808601909552805473ffffffffffffffffffffffffffffffffffffffff16855260018101805496975091959394939092840191906113a99061490c565b80601f01602080910402602001604051908101604052809291908181526020018280546113d59061490c565b80156114225780601f106113f757610100808354040283529160200191611422565b820191906000526020600020905b81548152906001019060200180831161140557829003601f168201915b5050509190925250505060018301549091506114725782604001516040517fd82f6adb00000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b841580156114975750805173ffffffffffffffffffffffffffffffffffffffff163314155b156114d0576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b602083015161150b576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018201546020840151811461158c57602084015161152c90600790612acd565b15611563576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208401516001840155611578600782612b81565b50602084015161158a9060079061367c565b505b606084015180516000036115ce57806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614d09565b835460009085906004906115ef90640100000000900463ffffffff1661495f565b91906101000a81548163ffffffff021916908363ffffffff1602179055905060005b82518110156116d45761164783828151811061162f5761162f614859565b60200260200101516003612acd90919063ffffffff16565b61167f57826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614d09565b6116cb83828151811061169457611694614859565b60200260200101518760030160008563ffffffff1663ffffffff16815260200190815260200160002061367c90919063ffffffff16565b50600101611611565b50845468010000000000000000900463ffffffff1680156118355763ffffffff8082166000908152600d60209081526040808320805464010000000090049094168352600190930181528282206002018054845181840281018401909552808552929392909183018282801561176957602002820191906000526020600020905b815481526020019060010190808311611755575b5050505050905060005b8151811015611832576117c882828151811061179157611791614859565b60200260200101518960030160008763ffffffff1663ffffffff168152602001908152602001600020612acd90919063ffffffff16565b61182a578181815181106117de576117de614859565b6020026020010151836040517f03dcd86200000000000000000000000000000000000000000000000000000000815260040161060992919091825263ffffffff16602082015260400190565b600101611773565b50505b60006118438760040161366f565b905060005b81518163ffffffff161015611989576000828263ffffffff168151811061187157611871614859565b60209081029190910181015163ffffffff8082166000908152600d845260408082208054640100000000900490931682526001909201845281812060020180548351818702810187019094528084529395509093919290918301828280156118f857602002820191906000526020600020905b8154815260200190600101908083116118e4575b5050505050905060005b81518110156119755761195782828151811061192057611920614859565b60200260200101518c60030160008a63ffffffff1663ffffffff168152602001908152602001600020612acd90919063ffffffff16565b61196d578181815181106117de576117de614859565b600101611902565b505050806119829061495f565b9050611848565b50875187547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90911690811788556040808a015160028a018190556020808c01518351928352908201527f4b5b465e22eea0c3d40c30e936643245b80d19b2dcf75788c0699fe8d8db645b910160405180910390a2505050505050505080600101905061130d565b600e5460609063ffffffff166000611a306001836148b7565b63ffffffff1667ffffffffffffffff811115611a4e57611a4e613dca565b604051908082528060200260200182016040528015611a9457816020015b604080518082019091526000815260606020820152815260200190600190039081611a6c5790505b509050600060015b8363ffffffff168163ffffffff161015611be45763ffffffff81166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611bdc5763ffffffff81166000908152600b60209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191611b309061490c565b80601f0160208091040260200160405190810160405280929190818152602001828054611b5c9061490c565b8015611ba95780601f10611b7e57610100808354040283529160200191611ba9565b820191906000526020600020905b815481529060010190602001808311611b8c57829003601f168201915b505050505081525050838381518110611bc457611bc4614859565b602002602001018190525081611bd9906148d4565b91505b600101611a9c565b50600e546107da9060019063ffffffff166148b7565b611c02612ae8565b60005b8181101561068f576000838383818110611c2157611c21614859565b9050602002810190611c339190614d4d565b611c3c90614d90565b90506000611c5282600001518360200151610446565b9050611c5f60038261367c565b611c98576040517febf5255100000000000000000000000000000000000000000000000000000000815260048101829052602401610609565b611ca28183613688565b5050600101611c05565b6000805473ffffffffffffffffffffffffffffffffffffffff163314905b82811015610d6f576000848483818110611ce657611ce6614859565b9050602002810190611cf89190614c02565b611d0190614c36565b805163ffffffff166000908152600b602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191611d579061490c565b80601f0160208091040260200160405190810160405280929190818152602001828054611d839061490c565b8015611dd05780601f10611da557610100808354040283529160200191611dd0565b820191906000526020600020905b815481529060010190602001808311611db357829003601f168201915b50505091909252505081519192505073ffffffffffffffffffffffffffffffffffffffff16611e365781516040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff9091166004820152602401610609565b83158015611e5b5750805173ffffffffffffffffffffffffffffffffffffffff163314155b15611e94576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b6040808301516000908152600c60205220600181015415611ee95782604001516040517f5461848300000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b6040830151611f2c5782604001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161060991815260200190565b60208301511580611f4957506020830151611f4990600790612acd565b15611f80576040517f8377314600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608301518051600003611fc257806040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614d09565b81548290600490611fe090640100000000900463ffffffff1661495f565b82546101009290920a63ffffffff818102199093169183160217909155825464010000000090041660005b82518110156120b65761202983828151811061162f5761162f614859565b61206157826040517f3748d4c60000000000000000000000000000000000000000000000000000000081526004016106099190614d09565b6120ad83828151811061207657612076614859565b60200260200101518560030160008563ffffffff1663ffffffff16815260200190815260200160002061367c90919063ffffffff16565b5060010161200b565b50845183547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9182161784556040860151600285015560208601516001850181905561210c916007919061367c16565b50604085015161211e9060099061367c565b50845160408087015160208089015183519283529082015263ffffffff909216917f74becb12a5e8fd0e98077d02dfba8f647c9670c9df177e42c2418cf17a636f05910160405180910390a25050505050806001019050611cca565b60015473ffffffffffffffffffffffffffffffffffffffff1633146121fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610609565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b8281146122ba576040517fab8b67c60000000000000000000000000000000000000000000000000000000081526004810184905260248101829052604401610609565b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156125af5760008686838181106122f2576122f2614859565b90506020020160208101906123079190614290565b63ffffffff81166000908152600b6020526040902080549192509073ffffffffffffffffffffffffffffffffffffffff16612376576040517fadd9ae1e00000000000000000000000000000000000000000000000000000000815263ffffffff83166004820152602401610609565b600086868581811061238a5761238a614859565b905060200281019061239c9190614982565b6123a5906149c0565b805190915073ffffffffffffffffffffffffffffffffffffffff166123f6576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815473ffffffffffffffffffffffffffffffffffffffff16331480159061243357503373ffffffffffffffffffffffffffffffffffffffff861614155b1561246c576040517f9473075d000000000000000000000000000000000000000000000000000000008152336004820152602401610609565b8051825473ffffffffffffffffffffffffffffffffffffffff90811691161415806124e857506020808201516040516124a5920161401b565b60405160208183030381529060405280519060200120826001016040516020016124cf9190614e36565b6040516020818303038152906040528051906020012014155b156125a157805182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602081015160018301906125429082614a7a565b50806000015173ffffffffffffffffffffffffffffffffffffffff168363ffffffff167f86f41145bde5dd7f523305452e4aad3685508c181432ec733d5f345009358a288360200151604051612598919061401b565b60405180910390a35b5050508060010190506122d6565b505050505050565b6125f86040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b6040805160e081018252838152600084815260026020908152929020805491928301916126249061490c565b80601f01602080910402602001604051908101604052809291908181526020018280546126509061490c565b801561269d5780601f106126725761010080835404028352916020019161269d565b820191906000526020600020905b81548152906001019060200180831161268057829003601f168201915b505050505081526020016002600085815260200190815260200160002060010180546126c89061490c565b80601f01602080910402602001604051908101604052809291908181526020018280546126f49061490c565b80156127415780601f1061271657610100808354040283529160200191612741565b820191906000526020600020905b81548152906001019060200180831161272457829003601f168201915b50505091835250506000848152600260208181526040909220015491019060ff166003811115612773576127736145b4565b815260008481526002602081815260409092200154910190610100900460ff1660018111156127a4576127a46145b4565b81526000848152600260208181526040928390209091015462010000900473ffffffffffffffffffffffffffffffffffffffff1690830152016127e8600585612acd565b1515905292915050565b6127fa612ae8565b600e805460009164010000000090910463ffffffff1690600461281c8361495f565b82546101009290920a63ffffffff81810219909316918316021790915581166000818152600d602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001684179055815160a08101835292835260019083015286151590820152841515606082015260ff841660808201529091506128b2908990899089908990612e58565b5050505050505050565b606060006128ca600361366f565b90506000815167ffffffffffffffff8111156128e8576128e8613dca565b60405190808252806020026020018201604052801561295a57816020015b6129476040805160e0810182526000808252606060208301819052928201839052909182019081526020016000815260006020820181905260409091015290565b8152602001906001900390816129065790505b50905060005b82518110156107ea5761298b83828151811061297e5761297e614859565b60200260200101516125b7565b82828151811061299d5761299d614859565b6020908102919091010152600101612960565b606060006129be600961366f565b90506000815167ffffffffffffffff8111156129dc576129dc613dca565b604051908082528060200260200182016040528015612a6357816020015b6040805160e081018252600080825260208083018290529282018190526060808301829052608083019190915260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816129fa5790505b50905060005b82518110156107ea57612a94838281518110612a8757612a87614859565b6020026020010151611120565b828281518110612aa657612aa6614859565b6020908102919091010152600101612a69565b612ac1612ae8565b612aca81613870565b50565b600081815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612b69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610609565b565b6000610474825490565b6000612ae18383613965565b6000612ae1838361398f565b6040805160e0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840181905260c084015263ffffffff8581168352600d8252848320805464010000000090049091168084526001909101825284832060028101805487518186028101860190985280885295969295919493909190830182828015612c3e57602002820191906000526020600020905b815481526020019060010190808311612c2a575b505050505090506000815167ffffffffffffffff811115612c6157612c61613dca565b604051908082528060200260200182016040528015612ca757816020015b604080518082019091526000815260606020820152815260200190600190039081612c7f5790505b50905060005b8151811015612dbf576040518060400160405280848381518110612cd357612cd3614859565b60200260200101518152602001856003016000868581518110612cf857612cf8614859565b602002602001015181526020019081526020016000208054612d199061490c565b80601f0160208091040260200160405190810160405280929190818152602001828054612d459061490c565b8015612d925780601f10612d6757610100808354040283529160200191612d92565b820191906000526020600020905b815481529060010190602001808311612d7557829003601f168201915b5050505050815250828281518110612dac57612dac614859565b6020908102919091010152600101612cad565b506040805160e08101825263ffffffff8089166000818152600d6020818152868320548086168752948b168187015260ff680100000000000000008604811697870197909752690100000000000000000085048716151560608701529290915290526a010000000000000000000090049091161515608082015260a08101612e468561366f565b81526020019190915295945050505050565b805163ffffffff9081166000908152600d602090815260408083208286015190941683526001909301905220608082015160ff161580612eaa575060808201518590612ea5906001614ee4565b60ff16115b15612ef35760808201516040517f25b4d61800000000000000000000000000000000000000000000000000000000815260ff909116600482015260248101869052604401610609565b6001826020015163ffffffff161115612fdb57815163ffffffff166000908152600d602090815260408220908401516001918201918391612f3491906148b7565b63ffffffff1663ffffffff168152602001908152602001600020905060005b612f5c82612b6b565b811015612fd857612f8b846000015163ffffffff16600c60006105928587600001612b7590919063ffffffff16565b50600c6000612f9a8484612b75565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff169055600101612f53565b50505b60005b858110156132155761300b878783818110612ffb57612ffb614859565b859260209091020135905061367c565b61306c57825187878381811061302357613023614859565b6040517f636e405700000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8260600151156131c357825163ffffffff16600c600089898581811061309457613094614859565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff161480159061310e5750600c60008888848181106130df576130df614859565b602090810292909201358352508101919091526040016000205468010000000000000000900463ffffffff1615155b1561317057825187878381811061312757613127614859565b6040517f60b9df7300000000000000000000000000000000000000000000000000000000815263ffffffff90941660048501526020029190910135602483015250604401610609565b8251600c600089898581811061318857613188614859565b90506020020135815260200190815260200160002060000160086101000a81548163ffffffff021916908363ffffffff16021790555061320d565b825161320b9063ffffffff16600c60008a8a868181106131e5576131e5614859565b90506020020135815260200190815260200160002060040161367c90919063ffffffff16565b505b600101612fde565b5060005b83811015613623573685858381811061323457613234614859565b90506020028101906132469190614982565b905061325460038235612acd565b61328d576040517fe181733f00000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b61329960058235612acd565b156132d3576040517ff7d7a29400000000000000000000000000000000000000000000000000000000815281356004820152602401610609565b80356000908152600384016020526040812080546132f09061490c565b9050111561333c5783516040517f3927d08000000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015281356024820152604401610609565b60005b87811015613446576133e38235600c60008c8c8681811061336257613362614859565b9050602002013581526020019081526020016000206003016000600c60008e8e8881811061339257613392614859565b90506020020135815260200190815260200160002060000160049054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020612acd90919063ffffffff16565b61343e578888828181106133f9576133f9614859565b6040517fa7e792500000000000000000000000000000000000000000000000000000000081526020909102929092013560048301525082356024820152604401610609565b60010161333f565b506002830180546001810182556000918252602091829020833591015561346f90820182614efd565b8235600090815260038601602052604090209161348d919083614f62565b50604080850151855163ffffffff9081166000908152600d602090815284822080549415156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff90951694909417909355606088015188518316825284822080549115156a0100000000000000000000027fffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff9092169190911790556080880151885183168252848220805460ff9290921668010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff909216919091179055828801805189518416835294909120805494909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9094169390931790558551915161361a92918435908c908c906135e090880188614efd565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613a8292505050565b50600101613219565b50815160208084015160405163ffffffff91821681529216917ff264aae70bf6a9d90e68e0f9b393f4e7fbea67b063b0f336e0b36c1581703651910160405180910390a2505050505050565b60606000612ae183613b63565b6000612ae18383613bbf565b608081015173ffffffffffffffffffffffffffffffffffffffff161561372a576136d681608001517f78bea72100000000000000000000000000000000000000000000000000000000613c0e565b61372a5760808101516040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610609565b6000828152600260205260409020815182919081906137499082614a7a565b506020820151600182019061375e9082614a7a565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660018360038111156137a0576137a06145b4565b021790555060608201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101008360018111156137e7576137e76145b4565b0217905550608091909101516002909101805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff90921691909117905560405182907f04f0a9bcf3f3a3b42a4d7ca081119755f82ebe43e0d30c8f7292c4fe0dc4a2ae90600090a25050565b3373ffffffffffffffffffffffffffffffffffffffff8216036138ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610609565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600082600001828154811061397c5761397c614859565b9060005260206000200154905092915050565b60008181526001830160205260408120548015613a785760006139b360018361507d565b85549091506000906139c79060019061507d565b9050818114613a2c5760008660000182815481106139e7576139e7614859565b9060005260206000200154905080876000018481548110613a0a57613a0a614859565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613a3d57613a3d615090565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610474565b6000915050610474565b6000848152600260208190526040909120015462010000900473ffffffffffffffffffffffffffffffffffffffff16156125af57600084815260026020819052604091829020015490517ffba64a7c0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169063fba64a7c90613b29908690869086908b908d906004016150bf565b600060405180830381600087803b158015613b4357600080fd5b505af1158015613b57573d6000803e3d6000fd5b50505050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015613bb357602002820191906000526020600020905b815481526020019060010190808311613b9f575b50505050509050919050565b6000818152600183016020526040812054613c0657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610474565b506000610474565b6000613c1983613c2a565b8015612ae15750612ae18383613c8e565b6000613c56827f01ffc9a700000000000000000000000000000000000000000000000000000000613c8e565b80156104745750613c87827fffffffff00000000000000000000000000000000000000000000000000000000613c8e565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613d46575060208210155b8015613d525750600081115b979650505050505050565b508054613d699061490c565b6000825580601f10613d79575050565b601f016020900490600052602060002090810190612aca9190613db1565b5080546000825590600052602060002090810190612aca91905b5b80821115613dc65760008155600101613db2565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613e1c57613e1c613dca565b60405290565b60405160a0810167ffffffffffffffff81118282101715613e1c57613e1c613dca565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613e8c57613e8c613dca565b604052919050565b600067ffffffffffffffff821115613eae57613eae613dca565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613eeb57600080fd5b8135613efe613ef982613e94565b613e45565b818152846020838601011115613f1357600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613f4357600080fd5b823567ffffffffffffffff80821115613f5b57600080fd5b613f6786838701613eda565b93506020850135915080821115613f7d57600080fd5b50613f8a85828601613eda565b9150509250929050565b600060208284031215613fa657600080fd5b5035919050565b60005b83811015613fc8578181015183820152602001613fb0565b50506000910152565b60008151808452613fe9816020860160208601613fad565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612ae16020830184613fd1565b60008083601f84011261404057600080fd5b50813567ffffffffffffffff81111561405857600080fd5b6020830191508360208260051b850101111561111957600080fd5b6000806020838503121561408657600080fd5b823567ffffffffffffffff81111561409d57600080fd5b6140a98582860161402e565b90969095509350505050565b60008151808452602080850194506020840160005b838110156140e6578151875295820195908201906001016140ca565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b8481101561416e578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018952815180518452840151604085850181905261415a81860183613fd1565b9a86019a945050509083019060010161410e565b5090979650505050505050565b600063ffffffff8083511684528060208401511660208501525060ff604083015116604084015260608201511515606084015260808201511515608084015260a082015160e060a08501526141d360e08501826140b5565b905060c083015184820360c08601526141ec82826140f1565b95945050505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561426a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261425885835161417b565b9450928501929085019060010161421e565b5092979650505050505050565b803563ffffffff8116811461428b57600080fd5b919050565b6000602082840312156142a257600080fd5b612ae182614277565b73ffffffffffffffffffffffffffffffffffffffff815116825260006020820151604060208501526142e06040850182613fd1565b949350505050565b602081526000612ae160208301846142ab565b602081526000612ae1602083018461417b565b8035801515811461428b57600080fd5b803560ff8116811461428b57600080fd5b600080600080600080600060a0888a03121561434a57600080fd5b61435388614277565b9650602088013567ffffffffffffffff8082111561437057600080fd5b61437c8b838c0161402e565b909850965060408a013591508082111561439557600080fd5b506143a28a828b0161402e565b90955093506143b590506060890161430e565b91506143c36080890161431e565b905092959891949750929550565b600080604083850312156143e457600080fd5b6143ed83614277565b946020939093013593505050565b60408152600061440e6040830185613fd1565b82810360208401526141ec8185613fd1565b600063ffffffff808351168452602081818501511681860152816040850151166040860152606084015160608601526080840151608086015260a0840151915060e060a086015261447460e08601836140b5565b60c08581015187830391880191909152805180835290830193506000918301905b808310156144b55784518252938301936001929092019190830190614495565b509695505050505050565b602081526000612ae16020830184614420565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561426a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526145368583516142ab565b945092850192908501906001016144fc565b6000806000806040858703121561455e57600080fd5b843567ffffffffffffffff8082111561457657600080fd5b6145828883890161402e565b9096509450602087013591508082111561459b57600080fd5b506145a88782880161402e565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b805182526000602082015160e0602085015261460260e0850182613fd1565b90506040830151848203604086015261461b8282613fd1565b915050606083015160048110614633576146336145b4565b606085015260808301516002811061464d5761464d6145b4565b8060808601525060a083015161467b60a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015161468f60c086018215159052565b509392505050565b602081526000612ae160208301846145e3565b600080600080600080600060a0888a0312156146c557600080fd5b873567ffffffffffffffff808211156146dd57600080fd5b6146e98b838c0161402e565b909950975060208a013591508082111561470257600080fd5b5061470f8a828b0161402e565b909650945061472290506040890161430e565b92506143b56060890161430e565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561426a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526147938583516145e3565b94509285019290850190600101614759565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561426a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452614808858351614420565b945092850192908501906001016147ce565b803573ffffffffffffffffffffffffffffffffffffffff8116811461428b57600080fd5b60006020828403121561485057600080fd5b612ae18261481a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff8281168282160390808211156107ea576107ea614888565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361490557614905614888565b5060010190565b600181811c9082168061492057607f821691505b602082108103614959577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600063ffffffff80831681810361497857614978614888565b6001019392505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126149b657600080fd5b9190910192915050565b6000604082360312156149d257600080fd5b6040516040810167ffffffffffffffff82821081831117156149f6576149f6613dca565b81604052614a038561481a565b83526020850135915080821115614a1957600080fd5b50614a2636828601613eda565b60208301525092915050565b601f82111561068f576000816000526020600020601f850160051c81016020861015614a5b5750805b601f850160051c820191505b818110156125af57828155600101614a67565b815167ffffffffffffffff811115614a9457614a94613dca565b614aa881614aa2845461490c565b84614a32565b602080601f831160018114614afb5760008415614ac55750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556125af565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614b4857888601518255948401946001909101908401614b29565b5085821015614b8457878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215614ba657600080fd5b815167ffffffffffffffff811115614bbd57600080fd5b8201601f81018413614bce57600080fd5b8051614bdc613ef982613e94565b818152856020838501011115614bf157600080fd5b6141ec826020830160208601613fad565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126149b657600080fd5b600060808236031215614c4857600080fd5b614c50613df9565b614c5983614277565b81526020808401358183015260408401356040830152606084013567ffffffffffffffff80821115614c8a57600080fd5b9085019036601f830112614c9d57600080fd5b813581811115614caf57614caf613dca565b8060051b9150614cc0848301613e45565b8181529183018401918481019036841115614cda57600080fd5b938501935b83851015614cf857843582529385019390850190614cdf565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614d4157835183529284019291840191600101614d25565b50909695505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff618336030181126149b657600080fd5b80356002811061428b57600080fd5b600060a08236031215614da257600080fd5b614daa613e22565b823567ffffffffffffffff80821115614dc257600080fd5b614dce36838701613eda565b83526020850135915080821115614de457600080fd5b50614df136828601613eda565b602083015250604083013560048110614e0957600080fd5b6040820152614e1a60608401614d81565b6060820152614e2b6080840161481a565b608082015292915050565b6000602080835260008454614e4a8161490c565b8060208701526040600180841660008114614e6c5760018114614ea657614ed6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00851660408a0152604084151560051b8a01019550614ed6565b89600052602060002060005b85811015614ecd5781548b8201860152908301908801614eb2565b8a016040019650505b509398975050505050505050565b60ff818116838216019081111561047457610474614888565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614f3257600080fd5b83018035915067ffffffffffffffff821115614f4d57600080fd5b60200191503681900382131561111957600080fd5b67ffffffffffffffff831115614f7a57614f7a613dca565b614f8e83614f88835461490c565b83614a32565b6000601f841160018114614fe05760008515614faa5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355615076565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561502f578685013582556020948501946001909201910161500f565b508682101561506a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8181038181111561047457610474614888565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6080815284608082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8611156150f857600080fd5b8560051b808860a0850137820182810360a0908101602085015261511e90820187613fd1565b91505063ffffffff8085166040840152808416606084015250969550505050505056fea164736f6c6343000818000a", } var CapabilitiesRegistryABI = CapabilitiesRegistryMetaData.ABI @@ -989,18 +989,28 @@ type CapabilitiesRegistryConfigSet struct { Raw types.Log } -func (_CapabilitiesRegistry *CapabilitiesRegistryFilterer) FilterConfigSet(opts *bind.FilterOpts) (*CapabilitiesRegistryConfigSetIterator, error) { +func (_CapabilitiesRegistry *CapabilitiesRegistryFilterer) FilterConfigSet(opts *bind.FilterOpts, donId []uint32) (*CapabilitiesRegistryConfigSetIterator, error) { - logs, sub, err := _CapabilitiesRegistry.contract.FilterLogs(opts, "ConfigSet") + var donIdRule []interface{} + for _, donIdItem := range donId { + donIdRule = append(donIdRule, donIdItem) + } + + logs, sub, err := _CapabilitiesRegistry.contract.FilterLogs(opts, "ConfigSet", donIdRule) if err != nil { return nil, err } return &CapabilitiesRegistryConfigSetIterator{contract: _CapabilitiesRegistry.contract, event: "ConfigSet", logs: logs, sub: sub}, nil } -func (_CapabilitiesRegistry *CapabilitiesRegistryFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CapabilitiesRegistryConfigSet) (event.Subscription, error) { +func (_CapabilitiesRegistry *CapabilitiesRegistryFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CapabilitiesRegistryConfigSet, donId []uint32) (event.Subscription, error) { + + var donIdRule []interface{} + for _, donIdItem := range donId { + donIdRule = append(donIdRule, donIdItem) + } - logs, sub, err := _CapabilitiesRegistry.contract.WatchLogs(opts, "ConfigSet") + logs, sub, err := _CapabilitiesRegistry.contract.WatchLogs(opts, "ConfigSet", donIdRule) if err != nil { return nil, err } @@ -2232,9 +2242,9 @@ type CapabilitiesRegistryInterface interface { ParseCapabilityDeprecated(log types.Log) (*CapabilitiesRegistryCapabilityDeprecated, error) - FilterConfigSet(opts *bind.FilterOpts) (*CapabilitiesRegistryConfigSetIterator, error) + FilterConfigSet(opts *bind.FilterOpts, donId []uint32) (*CapabilitiesRegistryConfigSetIterator, error) - WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CapabilitiesRegistryConfigSet) (event.Subscription, error) + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CapabilitiesRegistryConfigSet, donId []uint32) (event.Subscription, error) ParseConfigSet(log types.Log) (*CapabilitiesRegistryConfigSet, error) diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 26ad8f3315..dc179a7112 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,5 +1,5 @@ GETH_VERSION: 1.13.8 -capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin 2c8947475e3db9e4feadde2c4325bb093f905e352879518dadac470f33e000ce +capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin cb3e79280a928979bc37de154b12b876996bdbe10f1827e683ee2bfa7a429a6c feeds_consumer: ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin 8c3a2b18a80be41e7c40d2bc3a4c8d1b5e18d55c1fd20ad5af68cebb66109fc5 forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin 45d9b866c64b41c1349a90b6764aee42a6d078b454d38f369b5fe02b23b9d16e ocr3_capability: ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.bin 8bf0f53f222efce7143dea6134552eb26ea1eef845407b4475a0d79b7d7ba9f8 From 81733d9de4f322a574842c528f2eaa38cec11a4a Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Thu, 29 Aug 2024 19:34:15 +0200 Subject: [PATCH 245/432] core/services/ocr2/plugins/llo: use write lock during mock read closer Reads (#14276) --- ...nchain_channel_definition_cache_integration_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go index d084e51531..6067887681 100644 --- a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go +++ b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go @@ -58,7 +58,7 @@ func (h *mockHTTPClient) SetResponse(resp *http.Response, err error) { type MockReadCloser struct { data []byte - mu sync.RWMutex + mu sync.Mutex reader *bytes.Reader } @@ -71,8 +71,8 @@ func NewMockReadCloser(data []byte) *MockReadCloser { // Read reads from the underlying data func (m *MockReadCloser) Read(p []byte) (int, error) { - m.mu.RLock() - defer m.mu.RUnlock() + m.mu.Lock() + defer m.mu.Unlock() return m.reader.Read(p) } @@ -80,8 +80,8 @@ func (m *MockReadCloser) Read(p []byte) (int, error) { func (m *MockReadCloser) Close() error { m.mu.Lock() defer m.mu.Unlock() - m.reader.Seek(0, io.SeekStart) - return nil + _, err := m.reader.Seek(0, io.SeekStart) + return err } func Test_ChannelDefinitionCache_Integration(t *testing.T) { From 674eac31cc161250fdadb838ba2a0fc7c796e932 Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Thu, 29 Aug 2024 12:24:04 -0700 Subject: [PATCH 246/432] [KS-420] Add rate-limiting to Dispatcher (#14239) * [KS-420] Add rate-limiting to Dispatcher * Implements rate limiter on dispatcher * Improves TOML config * Updates toml config docs * Fixes config_capabilities.go * Adds changeset * Updates txtar files * Fixes tests + updates docs * Renames interface methods * Fixes CI * Fixes CI --------- Co-authored-by: vyzaldysanchez --- .changeset/calm-laws-begin.md | 5 ++ core/capabilities/remote/dispatcher.go | 49 ++++++++---- core/capabilities/remote/dispatcher_test.go | 80 ++++++++++++++++++- core/config/capabilities_config.go | 1 + core/config/dispatcher_config.go | 14 ++++ core/config/docs/core.toml | 16 ++++ core/config/toml/types.go | 42 ++++++++++ core/services/chainlink/application.go | 5 +- .../services/chainlink/config_capabilities.go | 40 ++++++++++ core/services/chainlink/config_test.go | 10 +++ .../testdata/config-empty-effective.toml | 10 +++ .../chainlink/testdata/config-full.toml | 10 +++ .../config-multi-chain-effective.toml | 10 +++ .../testdata/config-empty-effective.toml | 10 +++ core/web/resolver/testdata/config-full.toml | 10 +++ .../config-multi-chain-effective.toml | 10 +++ docs/CONFIG.md | 54 +++++++++++++ testdata/scripts/health/default.txtar | 2 +- testdata/scripts/node/validate/default.txtar | 10 +++ .../disk-based-logging-disabled.txtar | 10 +++ .../validate/disk-based-logging-no-dir.txtar | 10 +++ .../node/validate/disk-based-logging.txtar | 10 +++ .../node/validate/invalid-ocr-p2p.txtar | 10 +++ testdata/scripts/node/validate/invalid.txtar | 10 +++ testdata/scripts/node/validate/valid.txtar | 10 +++ testdata/scripts/node/validate/warnings.txtar | 10 +++ 26 files changed, 435 insertions(+), 23 deletions(-) create mode 100644 .changeset/calm-laws-begin.md create mode 100644 core/config/dispatcher_config.go diff --git a/.changeset/calm-laws-begin.md b/.changeset/calm-laws-begin.md new file mode 100644 index 0000000000..5549f1a966 --- /dev/null +++ b/.changeset/calm-laws-begin.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#added Implements rate limiter for capabilities dispatcher diff --git a/core/capabilities/remote/dispatcher.go b/core/capabilities/remote/dispatcher.go index bed485c286..f27d691bb6 100644 --- a/core/capabilities/remote/dispatcher.go +++ b/core/capabilities/remote/dispatcher.go @@ -2,20 +2,22 @@ package remote import ( "context" - "errors" "fmt" - sync "sync" + "sync" "time" + "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "google.golang.org/protobuf/proto" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types/core" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" - remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" + "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) @@ -25,11 +27,13 @@ var ( // dispatcher en/decodes messages and routes traffic between peers and capabilities type dispatcher struct { + cfg config.Dispatcher peerWrapper p2ptypes.PeerWrapper peer p2ptypes.Peer peerID p2ptypes.PeerID signer p2ptypes.Signer registry core.CapabilitiesRegistry + rateLimiter *common.RateLimiter receivers map[key]*receiver mu sync.RWMutex stopCh services.StopChan @@ -44,17 +48,26 @@ type key struct { var _ services.Service = &dispatcher{} -const supportedVersion = 1 - -func NewDispatcher(peerWrapper p2ptypes.PeerWrapper, signer p2ptypes.Signer, registry core.CapabilitiesRegistry, lggr logger.Logger) *dispatcher { +func NewDispatcher(cfg config.Dispatcher, peerWrapper p2ptypes.PeerWrapper, signer p2ptypes.Signer, registry core.CapabilitiesRegistry, lggr logger.Logger) (*dispatcher, error) { + rl, err := common.NewRateLimiter(common.RateLimiterConfig{ + GlobalRPS: cfg.RateLimit().GlobalRPS(), + GlobalBurst: cfg.RateLimit().GlobalBurst(), + PerSenderRPS: cfg.RateLimit().PerSenderRPS(), + PerSenderBurst: cfg.RateLimit().PerSenderBurst(), + }) + if err != nil { + return nil, errors.Wrap(err, "failed to create rate limiter") + } return &dispatcher{ + cfg: cfg, peerWrapper: peerWrapper, signer: signer, registry: registry, + rateLimiter: rl, receivers: make(map[key]*receiver), stopCh: make(services.StopChan), lggr: lggr.Named("Dispatcher"), - } + }, nil } func (d *dispatcher) Start(ctx context.Context) error { @@ -85,14 +98,12 @@ var capReceiveChannelUsage = promauto.NewGaugeVec(prometheus.GaugeOpts{ Help: "The usage of the receive channel for each capability, 0 indicates empty, 1 indicates full.", }, []string{"capabilityId", "donId"}) -const receiverBufferSize = 10000 - type receiver struct { cancel context.CancelFunc - ch chan *remotetypes.MessageBody + ch chan *types.MessageBody } -func (d *dispatcher) SetReceiver(capabilityId string, donId uint32, rec remotetypes.Receiver) error { +func (d *dispatcher) SetReceiver(capabilityId string, donId uint32, rec types.Receiver) error { d.mu.Lock() defer d.mu.Unlock() k := key{capabilityId, donId} @@ -101,7 +112,7 @@ func (d *dispatcher) SetReceiver(capabilityId string, donId uint32, rec remotety return fmt.Errorf("%w: receiver already exists for capability %s and don %d", ErrReceiverExists, capabilityId, donId) } - receiverCh := make(chan *remotetypes.MessageBody, receiverBufferSize) + receiverCh := make(chan *types.MessageBody, d.cfg.ReceiverBufferSize()) ctx, cancelCtx := d.stopCh.NewCtx() d.wg.Add(1) @@ -139,8 +150,8 @@ func (d *dispatcher) RemoveReceiver(capabilityId string, donId uint32) { } } -func (d *dispatcher) Send(peerID p2ptypes.PeerID, msgBody *remotetypes.MessageBody) error { - msgBody.Version = supportedVersion +func (d *dispatcher) Send(peerID p2ptypes.PeerID, msgBody *types.MessageBody) error { + msgBody.Version = uint32(d.cfg.SupportedVersion()) msgBody.Sender = d.peerID[:] msgBody.Receiver = peerID[:] msgBody.Timestamp = time.Now().UnixMilli() @@ -152,7 +163,7 @@ func (d *dispatcher) Send(peerID p2ptypes.PeerID, msgBody *remotetypes.MessageBo if err != nil { return err } - msg := &remotetypes.Message{Signature: signature, Body: rawBody} + msg := &types.Message{Signature: signature, Body: rawBody} rawMsg, err := proto.Marshal(msg) if err != nil { return err @@ -168,6 +179,10 @@ func (d *dispatcher) receive() { d.lggr.Info("stopped - exiting receive") return case msg := <-recvCh: + if !d.rateLimiter.Allow(msg.Sender.String()) { + d.lggr.Debugw("rate limit exceeded, dropping message", "sender", msg.Sender) + continue + } body, err := ValidateMessage(msg, d.peerID) if err != nil { d.lggr.Debugw("received invalid message", "error", err) @@ -184,7 +199,7 @@ func (d *dispatcher) receive() { continue } - receiverQueueUsage := float64(len(receiver.ch)) / receiverBufferSize + receiverQueueUsage := float64(len(receiver.ch)) / float64(d.cfg.ReceiverBufferSize()) capReceiveChannelUsage.WithLabelValues(k.capId, fmt.Sprint(k.donId)).Set(receiverQueueUsage) select { case receiver.ch <- body: @@ -195,7 +210,7 @@ func (d *dispatcher) receive() { } } -func (d *dispatcher) tryRespondWithError(peerID p2ptypes.PeerID, body *remotetypes.MessageBody, errType types.Error) { +func (d *dispatcher) tryRespondWithError(peerID p2ptypes.PeerID, body *types.MessageBody, errType types.Error) { if body == nil { return } diff --git a/core/capabilities/remote/dispatcher_test.go b/core/capabilities/remote/dispatcher_test.go index 7ea4c2e262..50edc5f353 100644 --- a/core/capabilities/remote/dispatcher_test.go +++ b/core/capabilities/remote/dispatcher_test.go @@ -10,6 +10,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" + "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" @@ -32,6 +33,47 @@ func (r *testReceiver) Receive(_ context.Context, msg *remotetypes.MessageBody) r.ch <- msg } +type testRateLimitConfig struct { + globalRPS float64 + globalBurst int + rps float64 + burst int +} + +func (c testRateLimitConfig) GlobalRPS() float64 { + return c.globalRPS +} + +func (c testRateLimitConfig) GlobalBurst() int { + return c.globalBurst +} + +func (c testRateLimitConfig) PerSenderRPS() float64 { + return c.rps +} + +func (c testRateLimitConfig) PerSenderBurst() int { + return c.burst +} + +type testConfig struct { + supportedVersion int + receiverBufferSize int + rateLimit testRateLimitConfig +} + +func (c testConfig) SupportedVersion() int { + return c.supportedVersion +} + +func (c testConfig) ReceiverBufferSize() int { + return c.receiverBufferSize +} + +func (c testConfig) RateLimit() config.DispatcherRateLimit { + return c.rateLimit +} + func TestDispatcher_CleanStartClose(t *testing.T) { lggr := logger.TestLogger(t) ctx := testutils.Context(t) @@ -44,7 +86,17 @@ func TestDispatcher_CleanStartClose(t *testing.T) { signer := mocks.NewSigner(t) registry := commonMocks.NewCapabilitiesRegistry(t) - dispatcher := remote.NewDispatcher(wrapper, signer, registry, lggr) + dispatcher, err := remote.NewDispatcher(testConfig{ + supportedVersion: 1, + receiverBufferSize: 10000, + rateLimit: testRateLimitConfig{ + globalRPS: 800.0, + globalBurst: 100, + rps: 10.0, + burst: 50, + }, + }, wrapper, signer, registry, lggr) + require.NoError(t, err) require.NoError(t, dispatcher.Start(ctx)) require.NoError(t, dispatcher.Close()) } @@ -65,11 +117,21 @@ func TestDispatcher_Receive(t *testing.T) { signer.On("Sign", mock.Anything).Return(nil, errors.New("not implemented")) registry := commonMocks.NewCapabilitiesRegistry(t) - dispatcher := remote.NewDispatcher(wrapper, signer, registry, lggr) + dispatcher, err := remote.NewDispatcher(testConfig{ + supportedVersion: 1, + receiverBufferSize: 10000, + rateLimit: testRateLimitConfig{ + globalRPS: 800.0, + globalBurst: 100, + rps: 10.0, + burst: 50, + }, + }, wrapper, signer, registry, lggr) + require.NoError(t, err) require.NoError(t, dispatcher.Start(ctx)) rcv := newReceiver() - err := dispatcher.SetReceiver(capId1, donId1, rcv) + err = dispatcher.SetReceiver(capId1, donId1, rcv) require.NoError(t, err) // supported capability @@ -113,7 +175,17 @@ func TestDispatcher_RespondWithError(t *testing.T) { signer.On("Sign", mock.Anything).Return([]byte{}, nil) registry := commonMocks.NewCapabilitiesRegistry(t) - dispatcher := remote.NewDispatcher(wrapper, signer, registry, lggr) + dispatcher, err := remote.NewDispatcher(testConfig{ + supportedVersion: 1, + receiverBufferSize: 10000, + rateLimit: testRateLimitConfig{ + globalRPS: 800.0, + globalBurst: 100, + rps: 10.0, + burst: 50, + }, + }, wrapper, signer, registry, lggr) + require.NoError(t, err) require.NoError(t, dispatcher.Start(ctx)) // unknown capability diff --git a/core/config/capabilities_config.go b/core/config/capabilities_config.go index ae542c062c..8c10896d09 100644 --- a/core/config/capabilities_config.go +++ b/core/config/capabilities_config.go @@ -13,5 +13,6 @@ type CapabilitiesExternalRegistry interface { type Capabilities interface { Peering() P2P + Dispatcher() Dispatcher ExternalRegistry() CapabilitiesExternalRegistry } diff --git a/core/config/dispatcher_config.go b/core/config/dispatcher_config.go new file mode 100644 index 0000000000..ec6f13e8f4 --- /dev/null +++ b/core/config/dispatcher_config.go @@ -0,0 +1,14 @@ +package config + +type DispatcherRateLimit interface { + GlobalRPS() float64 + GlobalBurst() int + PerSenderRPS() float64 + PerSenderBurst() int +} + +type Dispatcher interface { + SupportedVersion() int + ReceiverBufferSize() int + RateLimit() DispatcherRateLimit +} diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index 3783689db3..e8524c2918 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -452,6 +452,22 @@ NetworkID = 'evm' # Default # ChainID identifies the target chain id where the remote registry is located. ChainID = '1' # Default +[Capabilities.Dispatcher] +# SupportedVersion is the version of the version of message schema. +SupportedVersion = 1 # Default +# ReceiverBufferSize is the size of the buffer for incoming messages. +ReceiverBufferSize = 10000 # Default + +[Capabilities.Dispatcher.RateLimit] +# GlobalRPS is the global rate limit for the dispatcher. +GlobalRPS = 800 # Default +# GlobalBurst is the global burst limit for the dispatcher. +GlobalBurst = 1000 # Default +# PerSenderRPS is the per-sender rate limit for the dispatcher. +PerSenderRPS = 10 # Default +# PerSenderBurst is the per-sender burst limit for the dispatcher. +PerSenderBurst = 50 # Default + [Capabilities.Peering] # IncomingMessageBufferSize is the per-remote number of incoming # messages to buffer. Any additional messages received on top of those diff --git a/core/config/toml/types.go b/core/config/toml/types.go index 427e3f01cb..47c8cb46b7 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -1438,14 +1438,56 @@ func (r *ExternalRegistry) setFrom(f *ExternalRegistry) { } } +type Dispatcher struct { + SupportedVersion *int + ReceiverBufferSize *int + RateLimit DispatcherRateLimit +} + +func (d *Dispatcher) setFrom(f *Dispatcher) { + d.RateLimit.setFrom(&f.RateLimit) + + if f.ReceiverBufferSize != nil { + d.ReceiverBufferSize = f.ReceiverBufferSize + } + + if f.SupportedVersion != nil { + d.SupportedVersion = f.SupportedVersion + } +} + +type DispatcherRateLimit struct { + GlobalRPS *float64 + GlobalBurst *int + PerSenderRPS *float64 + PerSenderBurst *int +} + +func (drl *DispatcherRateLimit) setFrom(f *DispatcherRateLimit) { + if f.GlobalRPS != nil { + drl.GlobalRPS = f.GlobalRPS + } + if f.GlobalBurst != nil { + drl.GlobalBurst = f.GlobalBurst + } + if f.PerSenderRPS != nil { + drl.PerSenderRPS = f.PerSenderRPS + } + if f.PerSenderBurst != nil { + drl.PerSenderBurst = f.PerSenderBurst + } +} + type Capabilities struct { Peering P2P `toml:",omitempty"` + Dispatcher Dispatcher `toml:",omitempty"` ExternalRegistry ExternalRegistry `toml:",omitempty"` } func (c *Capabilities) setFrom(f *Capabilities) { c.Peering.setFrom(&f.Peering) c.ExternalRegistry.setFrom(&f.ExternalRegistry) + c.Dispatcher.setFrom(&f.Dispatcher) } type ThresholdKeyShareSecrets struct { diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 3efc92c227..6df51045c0 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -213,7 +213,10 @@ func NewApplication(opts ApplicationOpts) (Application, error) { externalPeer := externalp2p.NewExternalPeerWrapper(keyStore.P2P(), cfg.Capabilities().Peering(), opts.DS, globalLogger) signer := externalPeer externalPeerWrapper = externalPeer - remoteDispatcher := remote.NewDispatcher(externalPeerWrapper, signer, opts.CapabilitiesRegistry, globalLogger) + remoteDispatcher, err := remote.NewDispatcher(cfg.Capabilities().Dispatcher(), externalPeerWrapper, signer, opts.CapabilitiesRegistry, globalLogger) + if err != nil { + return nil, fmt.Errorf("could not create dispatcher: %w", err) + } dispatcher = remoteDispatcher } else { dispatcher = opts.CapabilitiesDispatcher diff --git a/core/services/chainlink/config_capabilities.go b/core/services/chainlink/config_capabilities.go index c438ca249d..734a5ae270 100644 --- a/core/services/chainlink/config_capabilities.go +++ b/core/services/chainlink/config_capabilities.go @@ -23,6 +23,46 @@ func (c *capabilitiesConfig) ExternalRegistry() config.CapabilitiesExternalRegis } } +func (c *capabilitiesConfig) Dispatcher() config.Dispatcher { + return &dispatcher{d: c.c.Dispatcher} +} + +type dispatcher struct { + d toml.Dispatcher +} + +func (d *dispatcher) SupportedVersion() int { + return *d.d.SupportedVersion +} + +func (d *dispatcher) ReceiverBufferSize() int { + return *d.d.ReceiverBufferSize +} + +func (d *dispatcher) RateLimit() config.DispatcherRateLimit { + return &dispatcherRateLimit{r: d.d.RateLimit} +} + +type dispatcherRateLimit struct { + r toml.DispatcherRateLimit +} + +func (r *dispatcherRateLimit) GlobalRPS() float64 { + return *r.r.GlobalRPS +} + +func (r *dispatcherRateLimit) GlobalBurst() int { + return *r.r.GlobalBurst +} + +func (r *dispatcherRateLimit) PerSenderRPS() float64 { + return *r.r.PerSenderRPS +} + +func (r *dispatcherRateLimit) PerSenderBurst() int { + return *r.r.PerSenderBurst +} + type capabilitiesExternalRegistry struct { c toml.ExternalRegistry } diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index a151b78fed..52ad0487d5 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -452,6 +452,16 @@ func TestConfig_Marshal(t *testing.T) { ChainID: ptr("1"), NetworkID: ptr("evm"), }, + Dispatcher: toml.Dispatcher{ + SupportedVersion: ptr(1), + ReceiverBufferSize: ptr(10000), + RateLimit: toml.DispatcherRateLimit{ + GlobalRPS: ptr(800.0), + GlobalBurst: ptr(1000), + PerSenderRPS: ptr(10.0), + PerSenderBurst: ptr(50), + }, + }, } full.Keeper = toml.Keeper{ DefaultTransactionQueueDepth: ptr[uint32](17), diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index d549e4024e..6050401634 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -253,6 +253,16 @@ DeltaDial = '15s' DeltaReconcile = '1m0s' ListenAddresses = [] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index fb43bed841..77f60ef550 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -263,6 +263,16 @@ DeltaDial = '1m0s' DeltaReconcile = '2s' ListenAddresses = ['foo', 'bar'] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index ffd4903bcd..e7d0244606 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -253,6 +253,16 @@ DeltaDial = '15s' DeltaReconcile = '1m0s' ListenAddresses = [] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index d549e4024e..6050401634 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -253,6 +253,16 @@ DeltaDial = '15s' DeltaReconcile = '1m0s' ListenAddresses = [] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index ba994650c6..426caf39eb 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -263,6 +263,16 @@ DeltaDial = '1m0s' DeltaReconcile = '2s' ListenAddresses = ['foo', 'bar'] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 8f8121613b..658d364d10 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -253,6 +253,16 @@ DeltaDial = '15s' DeltaReconcile = '1m0s' ListenAddresses = [] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 03908e08ed..d10da596e7 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1240,6 +1240,60 @@ ChainID = '1' # Default ``` ChainID identifies the target chain id where the remote registry is located. +## Capabilities.Dispatcher +```toml +[Capabilities.Dispatcher] +SupportedVersion = 1 # Default +ReceiverBufferSize = 10000 # Default +``` + + +### SupportedVersion +```toml +SupportedVersion = 1 # Default +``` +SupportedVersion is the version of the version of message schema. + +### ReceiverBufferSize +```toml +ReceiverBufferSize = 10000 # Default +``` +ReceiverBufferSize is the size of the buffer for incoming messages. + +## Capabilities.Dispatcher.RateLimit +```toml +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800 # Default +GlobalBurst = 1000 # Default +PerSenderRPS = 10 # Default +PerSenderBurst = 50 # Default +``` + + +### GlobalRPS +```toml +GlobalRPS = 800 # Default +``` +GlobalRPS is the global rate limit for the dispatcher. + +### GlobalBurst +```toml +GlobalBurst = 1000 # Default +``` +GlobalBurst is the global burst limit for the dispatcher. + +### PerSenderRPS +```toml +PerSenderRPS = 10 # Default +``` +PerSenderRPS is the per-sender rate limit for the dispatcher. + +### PerSenderBurst +```toml +PerSenderBurst = 50 # Default +``` +PerSenderBurst is the per-sender burst limit for the dispatcher. + ## Capabilities.Peering ```toml [Capabilities.Peering] diff --git a/testdata/scripts/health/default.txtar b/testdata/scripts/health/default.txtar index 777d3e5e12..8480345e27 100644 --- a/testdata/scripts/health/default.txtar +++ b/testdata/scripts/health/default.txtar @@ -126,4 +126,4 @@ ok TelemetryManager } } ] -} +} \ No newline at end of file diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index 114bb9f29a..cca4f4ef5e 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -265,6 +265,16 @@ DeltaDial = '15s' DeltaReconcile = '1m0s' ListenAddresses = [] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index c95144dbf7..26544e5801 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -309,6 +309,16 @@ DeltaDial = '15s' DeltaReconcile = '1m0s' ListenAddresses = [] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 0cdeff3606..17d86ef41e 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -309,6 +309,16 @@ DeltaDial = '15s' DeltaReconcile = '1m0s' ListenAddresses = [] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 60059e2ab8..e8eb6b93d0 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -309,6 +309,16 @@ DeltaDial = '15s' DeltaReconcile = '1m0s' ListenAddresses = [] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar index 14a8449ee1..3fe384e487 100644 --- a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -294,6 +294,16 @@ DeltaDial = '15s' DeltaReconcile = '1m0s' ListenAddresses = [] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 70a6cde243..4bfa96d302 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -299,6 +299,16 @@ DeltaDial = '15s' DeltaReconcile = '1m0s' ListenAddresses = [] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index ca2f10fb88..cea4c1b4f8 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -306,6 +306,16 @@ DeltaDial = '15s' DeltaReconcile = '1m0s' ListenAddresses = [] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index b6ebc1dc12..ed727815b3 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -288,6 +288,16 @@ DeltaDial = '15s' DeltaReconcile = '1m0s' ListenAddresses = [] +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + [Capabilities.ExternalRegistry] Address = '' NetworkID = 'evm' From 7e829721588a25bd7632295a419332009a39daaf Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Fri, 30 Aug 2024 07:50:18 +0200 Subject: [PATCH 247/432] [TT-1423] reusable cleanup vrf (#13939) * reuse clean up functions in VRF, hopefully solve NPEs * TT-1423: removing TODOs * fixing NPE * BHS test improvement * GHA improvement * GHA improvement * GHA improvement --------- Co-authored-by: Ilja Pavlovs <5300706+iljapavlovs@users.noreply.github.com> Co-authored-by: Ilja Pavlovs --- .../on-demand-vrfv2plus-smoke-tests.yml | 6 +- integration-tests/smoke/vrfv2_test.go | 173 ++++------- integration-tests/smoke/vrfv2plus_test.go | 287 ++++++------------ 3 files changed, 155 insertions(+), 311 deletions(-) diff --git a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml index 5977f92622..5bd8375c40 100644 --- a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml +++ b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml @@ -16,7 +16,7 @@ on: test_list_regex: description: "Regex for 'Selected Tests' to run" required: false - default: "(TestVRFv2Plus$/(Link_Billing|Native_Billing|Direct_Funding)|TestVRFV2PlusWithBHS|TestVRFV2PlusWithBHF)" + default: "TestVRFv2Plus$/(Link_Billing|Native_Billing|Direct_Funding)|TestVRFV2PlusWithBHS" test_secrets_override_key: description: 'Key to run tests with custom test secrets' required: false @@ -81,7 +81,7 @@ jobs: if: ${{ github.event.inputs.test_suite == 'Selected Tests' }} uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 with: - test_command_to_run: cd ./integration-tests/smoke && go test -v -count=1 -parallel=1 -timeout 2h -run "${{ inputs.test_list_regex }}" + test_command_to_run: cd ./integration-tests/smoke && go test -v -count=1 -parallel=1 -timeout 2h -run "${{ inputs.test_list_regex }}" 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} cl_repo: ${{ env.CHAINLINK_IMAGE }} @@ -99,7 +99,7 @@ jobs: if: ${{ github.event.inputs.test_suite == 'All Tests' }} uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 with: - test_command_to_run: cd ./integration-tests/smoke && go test -v -count=1 -parallel=1 -timeout 3h vrfv2plus_test.go + test_command_to_run: cd ./integration-tests/smoke && go test -v -count=1 -parallel=1 -timeout 3h vrfv2plus_test.go 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} cl_repo: ${{ env.CHAINLINK_IMAGE }} diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index 8d32204dd3..b21dafcacd 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -40,6 +40,53 @@ const ( SethRootKeyIndex = 0 ) +// vrfv2CleanUpFn is a cleanup function that captures pointers from context, in which it's called and uses them to clean up the test environment +var vrfv2CleanUpFn = func( + t **testing.T, + sethClient **seth.Client, + config **tc.TestConfig, + testEnv **test_env.CLClusterTestEnv, + vrfContracts **vrfcommon.VRFContracts, + subIDsForCancellingAfterTest *[]uint64, + walletAddress **string, +) func() { + return func() { + logger := logging.GetTestLogger(*t) + testConfig := **config + network := networks.MustGetSelectedNetworkConfig(testConfig.GetNetworkConfig())[0] + if network.Simulated { + logger.Info(). + Str("Network Name", network.Name). + Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") + } else { + if *vrfContracts != nil && *sethClient != nil { + if *testConfig.VRFv2.General.CancelSubsAfterTestRun { + client := *sethClient + var returnToAddress string + if walletAddress == nil || *walletAddress == nil { + returnToAddress = client.MustGetRootKeyAddress().Hex() + } else { + returnToAddress = **walletAddress + } + //cancel subs and return funds to sub owner + vrfv2.CancelSubsAndReturnFunds(testcontext.Get(*t), *vrfContracts, returnToAddress, *subIDsForCancellingAfterTest, logger) + } + } else { + logger.Error().Msg("VRF Contracts and/or Seth client are nil. Cannot execute cleanup") + } + } + if !*testConfig.VRFv2.General.UseExistingEnv { + if *testEnv == nil { + logger.Error().Msg("Test environment is nil. Cannot execute cleanup") + return + } + if err := (*testEnv).Cleanup(test_env.CleanupOpts{TestName: (*t).Name()}); err != nil { + logger.Error().Err(err).Msg("Error cleaning up test environment") + } + } + } +} + func TestVRFv2Basic(t *testing.T) { t.Parallel() var ( @@ -54,30 +101,13 @@ func TestVRFv2Basic(t *testing.T) { config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2) require.NoError(t, err, "Error getting config") - vrfv2Config := config.VRFv2 chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2Config.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } + configPtr := &config vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2CleanUpFn(&t, &sethClient, &configPtr, &testEnv, &vrfContracts, &subIDsForCancellingAfterTest, nil), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, @@ -574,29 +604,12 @@ func TestVRFv2MultipleSendingKeys(t *testing.T) { t.Fatal(err) } chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID - vrfv2Config := config.VRFv2 - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2Config.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } + configPtr := &config vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2CleanUpFn(&t, &sethClient, &configPtr, &testEnv, &vrfContracts, &subIDsForCancellingAfterTest, nil), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, @@ -680,29 +693,12 @@ func TestVRFOwner(t *testing.T) { config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2) require.NoError(t, err, "Error getting config") chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID - vrfv2Config := config.VRFv2 - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2Config.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } + configPtr := &config vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2CleanUpFn(&t, &sethClient, &configPtr, &testEnv, &vrfContracts, &subIDsForCancellingAfterTest, nil), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, @@ -818,23 +814,7 @@ func TestVRFV2WithBHS(t *testing.T) { vrfv2Config := config.VRFv2 chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2Config.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } + configPtr := &config //decrease default span for checking blockhashes for unfulfilled requests vrfv2Config.General.BHSJobWaitBlocks = ptr.Ptr(2) @@ -842,7 +822,7 @@ func TestVRFV2WithBHS(t *testing.T) { vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2CleanUpFn(&t, &sethClient, &configPtr, &testEnv, &vrfContracts, &subIDsForCancellingAfterTest, nil), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF, vrfcommon.BHS}, @@ -1036,30 +1016,13 @@ func TestVRFV2NodeReorg(t *testing.T) { config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2) require.NoError(t, err, "Error getting config") - vrfv2Config := config.VRFv2 network := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0] if !network.Simulated { t.Skip("Skipped since Reorg test could only be run on Simulated chain.") } chainID := network.ChainID - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2Config.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2Config.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } + configPtr := &config chainlinkNodeLogScannerSettings := test_env.GetDefaultChainlinkNodeLogScannerSettingsWithExtraAllowedMessages( testreporters.NewAllowedLogMessage( "Got very old block.", @@ -1075,7 +1038,7 @@ func TestVRFV2NodeReorg(t *testing.T) { vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2CleanUpFn(&t, &sethClient, &configPtr, &env, &vrfContracts, &subIDsForCancellingAfterTest, nil), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, @@ -1215,30 +1178,14 @@ func TestVRFv2BatchFulfillmentEnabledDisabled(t *testing.T) { config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2) require.NoError(t, err, "Error getting config") - vrfv2Config := config.VRFv2 network := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0] chainID := network.ChainID - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2Config.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2Config.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } + + configPtr := &config vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2CleanUpFn(&t, &sethClient, &configPtr, &env, &vrfContracts, &subIDsForCancellingAfterTest, nil), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index d8ea7cac10..30b0814a96 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -37,6 +37,47 @@ import ( it_utils "github.com/smartcontractkit/chainlink/integration-tests/utils" ) +// vrfv2PlusCleanUpFn is a cleanup function that captures pointers from context, in which it's called and uses them to clean up the test environment +var vrfv2PlusCleanUpFn = func( + t **testing.T, + sethClient **seth.Client, + config **tc.TestConfig, + testEnv **test_env.CLClusterTestEnv, + vrfContracts **vrfcommon.VRFContracts, + subIDsForCancellingAfterTest *[]*big.Int, +) func() { + return func() { + l := logging.GetTestLogger(*t) + testConfig := **config + network := networks.MustGetSelectedNetworkConfig(testConfig.GetNetworkConfig())[0] + if network.Simulated { + l.Info(). + Str("Network Name", network.Name). + Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") + } else { + if *vrfContracts != nil && *sethClient != nil { + if *testConfig.VRFv2Plus.General.CancelSubsAfterTestRun { + client := *sethClient + returnToAddress := client.MustGetRootKeyAddress().Hex() + //cancel subs and return funds to sub owner + vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(*t), *vrfContracts, returnToAddress, *subIDsForCancellingAfterTest, l) + } + } else { + l.Error().Msg("VRF Contracts and/or Seth client are nil. Cannot execute cleanup") + } + } + if !*testConfig.VRFv2Plus.General.UseExistingEnv { + if *testEnv == nil { + l.Error().Msg("Test environment is nil. Cannot execute cleanup") + return + } + if err := (*testEnv).Cleanup(test_env.CleanupOpts{TestName: (*t).Name()}); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + } + } +} + func TestVRFv2Plus(t *testing.T) { t.Parallel() var ( @@ -52,30 +93,13 @@ func TestVRFv2Plus(t *testing.T) { config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2Plus) require.NoError(t, err, "Error getting config") - vrfv2PlusConfig := config.VRFv2Plus chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID + configPtr := &config - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2PlusConfig.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2PlusCleanUpFn(&t, &sethClient, &configPtr, &env, &vrfContracts, &subIDsForCancellingAfterTest), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, @@ -793,30 +817,13 @@ func TestVRFv2PlusMultipleSendingKeys(t *testing.T) { config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2Plus) require.NoError(t, err, "Error getting config") - vrfv2PlusConfig := config.VRFv2Plus - network := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0] - chainID := network.ChainID - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2PlusConfig.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } + chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID + configPtr := &config + vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2PlusCleanUpFn(&t, &sethClient, &configPtr, &env, &vrfContracts, &subIDsForCancellingAfterTest), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, @@ -898,30 +905,13 @@ func TestVRFv2PlusMigration(t *testing.T) { config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2Plus) require.NoError(t, err, "Error getting config") - vrfv2PlusConfig := config.VRFv2Plus chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID + configPtr := &config - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2PlusConfig.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2PlusCleanUpFn(&t, &sethClient, &configPtr, &env, &vrfContracts, &subIDsForCancellingAfterTest), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, @@ -1292,24 +1282,7 @@ func TestVRFV2PlusWithBHS(t *testing.T) { require.NoError(t, err, "Error getting config") vrfv2PlusConfig := config.VRFv2Plus chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID - - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2PlusConfig.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } + configPtr := &config //decrease default span for checking blockhashes for unfulfilled requests vrfv2PlusConfig.General.BHSJobWaitBlocks = ptr.Ptr(2) @@ -1317,7 +1290,7 @@ func TestVRFV2PlusWithBHS(t *testing.T) { vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2PlusCleanUpFn(&t, &sethClient, &configPtr, &env, &vrfContracts, &subIDsForCancellingAfterTest), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF, vrfcommon.BHS}, @@ -1490,28 +1463,36 @@ func TestVRFV2PlusWithBHS(t *testing.T) { metrics, err := consumers[0].GetLoadTestMetrics(testcontext.Get(t)) require.Equal(t, 0, metrics.RequestCount.Cmp(big.NewInt(1))) require.Equal(t, 0, metrics.FulfilmentCount.Cmp(big.NewInt(0))) - - var clNodeTxs *client.TransactionsData - var txHash string gom := gomega.NewGomegaWithT(t) - gom.Eventually(func(g gomega.Gomega) { - clNodeTxs, _, err = nodeTypeToNodeMap[vrfcommon.BHS].CLNode.API.ReadTransactions() - g.Expect(err).ShouldNot(gomega.HaveOccurred(), "error getting CL Node transactions") - l.Info().Int("Number of TXs", len(clNodeTxs.Data)).Msg("BHS Node txs") - g.Expect(len(clNodeTxs.Data)).Should(gomega.BeNumerically("==", 1), "Expected 1 tx posted by BHS Node, but found %d", len(clNodeTxs.Data)) - txHash = clNodeTxs.Data[0].Attributes.Hash - }, "2m", "1s").Should(gomega.Succeed()) - require.Equal(t, strings.ToLower(vrfContracts.BHS.Address()), strings.ToLower(clNodeTxs.Data[0].Attributes.To)) - - bhsStoreTx, _, err := sethClient.Client.TransactionByHash(testcontext.Get(t), common.HexToHash(txHash)) - require.NoError(t, err, "error getting tx from hash") + if !*configCopy.VRFv2Plus.General.UseExistingEnv { + l.Info().Msg("Checking BHS Node's transactions") + var clNodeTxs *client.TransactionsData + var txHash string + gom.Eventually(func(g gomega.Gomega) { + clNodeTxs, _, err = nodeTypeToNodeMap[vrfcommon.BHS].CLNode.API.ReadTransactions() + g.Expect(err).ShouldNot(gomega.HaveOccurred(), "error getting CL Node transactions") + g.Expect(len(clNodeTxs.Data)).Should(gomega.BeNumerically("==", 1), "Expected 1 tx posted by BHS Node, but found %d", len(clNodeTxs.Data)) + txHash = clNodeTxs.Data[0].Attributes.Hash + l.Info(). + Str("TX Hash", txHash). + Int("Number of TXs", len(clNodeTxs.Data)). + Msg("BHS Node txs") + }, "2m", "1s").Should(gomega.Succeed()) + + require.Equal(t, strings.ToLower(vrfContracts.BHS.Address()), strings.ToLower(clNodeTxs.Data[0].Attributes.To)) + + bhsStoreTx, _, err := sethClient.Client.TransactionByHash(testcontext.Get(t), common.HexToHash(txHash)) + require.NoError(t, err, "error getting tx from hash") - bhsStoreTxInputData, err := actions.DecodeTxInputData(blockhash_store.BlockhashStoreABI, bhsStoreTx.Data()) - l.Info(). - Str("Block Number", bhsStoreTxInputData["n"].(*big.Int).String()). - Msg("BHS Node's Store Blockhash for Blocknumber Method TX") - require.Equal(t, randRequestBlockNumber, bhsStoreTxInputData["n"].(*big.Int).Uint64()) + bhsStoreTxInputData, err := actions.DecodeTxInputData(blockhash_store.BlockhashStoreABI, bhsStoreTx.Data()) + l.Info(). + Str("Block Number", bhsStoreTxInputData["n"].(*big.Int).String()). + Msg("BHS Node's Store Blockhash for Blocknumber Method TX") + require.Equal(t, randRequestBlockNumber, bhsStoreTxInputData["n"].(*big.Int).Uint64()) + } else { + l.Warn().Msg("Skipping BHS Node's transactions check as existing env is used") + } var randRequestBlockHash [32]byte gom.Eventually(func(g gomega.Gomega) { @@ -1540,28 +1521,10 @@ func TestVRFV2PlusWithBHF(t *testing.T) { config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2Plus) require.NoError(t, err, "Error getting config") - vrfv2PlusConfig := config.VRFv2Plus chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID + configPtr := &config - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2PlusConfig.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } - - // BHF job config + // BHF job config - NOTE - not possible to create BHF job spec with waitBlocks being less than 256 blocks config.VRFv2Plus.General.BHFJobWaitBlocks = ptr.Ptr(260) config.VRFv2Plus.General.BHFJobLookBackBlocks = ptr.Ptr(500) config.VRFv2Plus.General.BHFJobPollPeriod = ptr.Ptr(blockchain.StrDuration{Duration: time.Second * 30}) @@ -1569,7 +1532,7 @@ func TestVRFV2PlusWithBHF(t *testing.T) { vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2PlusCleanUpFn(&t, &sethClient, &configPtr, &env, &vrfContracts, &subIDsForCancellingAfterTest), } chainlinkNodeLogScannerSettings := test_env.GetDefaultChainlinkNodeLogScannerSettingsWithExtraAllowedMessages(testreporters.NewAllowedLogMessage( "Pipeline error", @@ -1703,30 +1666,13 @@ func TestVRFv2PlusReplayAfterTimeout(t *testing.T) { config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2Plus) require.NoError(t, err, "Error getting config") - vrfv2PlusConfig := config.VRFv2Plus chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID + configPtr := &config - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2PlusConfig.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2PlusCleanUpFn(&t, &sethClient, &configPtr, &env, &vrfContracts, &subIDsForCancellingAfterTest), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, @@ -1744,7 +1690,7 @@ func TestVRFv2PlusReplayAfterTimeout(t *testing.T) { env, vrfContracts, vrfKey, nodeTypeToNodeMap, sethClient, err = vrfv2plus.SetupVRFV2PlusUniverse(testcontext.Get(t), t, vrfEnvConfig, newEnvConfig, l) require.NoError(t, err, "error setting up VRFV2Plus universe") - t.Run("Replaying Requests", func(t *testing.T) { + t.Run("Timed out request fulfilled after node restart with replay", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) var isNativeBilling = false @@ -1876,30 +1822,13 @@ func TestVRFv2PlusPendingBlockSimulationAndZeroConfirmationDelays(t *testing.T) config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2Plus) require.NoError(t, err, "Error getting config") - vrfv2PlusConfig := config.VRFv2Plus chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID + configPtr := &config - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2PlusConfig.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2PlusCleanUpFn(&t, &sethClient, &configPtr, &env, &vrfContracts, &subIDsForCancellingAfterTest), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, @@ -1969,33 +1898,17 @@ func TestVRFv2PlusNodeReorg(t *testing.T) { config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2Plus) require.NoError(t, err, "Error getting config") - vrfv2PlusConfig := config.VRFv2Plus network := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0] if !network.Simulated { t.Skip("Skipped since Reorg test could only be run on Simulated chain.") } chainID := network.ChainID - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2PlusConfig.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } + configPtr := &config + vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2PlusCleanUpFn(&t, &sethClient, &configPtr, &env, &vrfContracts, &subIDsForCancellingAfterTest), } chainlinkNodeLogScannerSettings := test_env.GetDefaultChainlinkNodeLogScannerSettingsWithExtraAllowedMessages( testreporters.NewAllowedLogMessage( @@ -2148,30 +2061,14 @@ func TestVRFv2PlusBatchFulfillmentEnabledDisabled(t *testing.T) { config, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.VRFv2Plus) require.NoError(t, err, "Error getting config") - vrfv2PlusConfig := config.VRFv2Plus network := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0] chainID := network.ChainID - cleanupFn := func() { - if sethClient.Cfg.IsSimulatedNetwork() { - l.Info(). - Str("Network Name", sethClient.Cfg.Network.Name). - Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") - } else { - if *vrfv2PlusConfig.General.CancelSubsAfterTestRun { - //cancel subs and return funds to sub owner - vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, sethClient.MustGetRootKeyAddress().Hex(), subIDsForCancellingAfterTest, l) - } - } - if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { - l.Error().Err(err).Msg("Error cleaning up test environment") - } - } - } + configPtr := &config + vrfEnvConfig := vrfcommon.VRFEnvConfig{ TestConfig: config, ChainID: chainID, - CleanupFn: cleanupFn, + CleanupFn: vrfv2PlusCleanUpFn(&t, &sethClient, &configPtr, &env, &vrfContracts, &subIDsForCancellingAfterTest), } newEnvConfig := vrfcommon.NewEnvConfig{ NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, From 5bda8af16b9c6ebbf8813fdedf74a21178c1db10 Mon Sep 17 00:00:00 2001 From: Patrick Date: Fri, 30 Aug 2024 02:05:52 -0400 Subject: [PATCH 248/432] support default config file overrides (#14090) * support default config file overrides * lint * adding test for when default is not used * WIP: negative test for when an override is specified for a chain that does not exist in the embedded defaults * using env package * relaxing strict override restriction, and improving log line details * lint + CustomDefaultsEnvKey --> CustomDefaults * removing invalid test * crash the node if can't read or load all files from overriden defaults * accounting for Fatalf in control flow * evm defaults look for evm suffix. Duplicate chain IDs fail validation * removing negative path testing due to CI failures * removing mkdirs * updating config after rebase * re-enabling negative path * removing comment --- core/chains/evm/config/toml/defaults.go | 79 +++- core/config/env/env.go | 1 + main_test.go | 4 + .../node/validate/defaults-override.txtar | 444 ++++++++++++++++++ 4 files changed, 523 insertions(+), 5 deletions(-) create mode 100644 testdata/scripts/node/validate/defaults-override.txtar diff --git a/core/chains/evm/config/toml/defaults.go b/core/chains/evm/config/toml/defaults.go index c3f087da8c..4e1ebfb34d 100644 --- a/core/chains/evm/config/toml/defaults.go +++ b/core/chains/evm/config/toml/defaults.go @@ -3,7 +3,10 @@ package toml import ( "bytes" "embed" + "fmt" + "io" "log" + "os" "path/filepath" "slices" "strings" @@ -12,37 +15,43 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/config/env" ) var ( + //go:embed defaults/*.toml defaultsFS embed.FS fallback Chain defaults = map[string]Chain{} defaultNames = map[string]string{} + customDefaults = map[string]Chain{} + // DefaultIDs is the set of chain ids which have defaults. DefaultIDs []*big.Big ) func init() { + // read the defaults first + fes, err := defaultsFS.ReadDir("defaults") if err != nil { log.Fatalf("failed to read defaults/: %v", err) } for _, fe := range fes { path := filepath.Join("defaults", fe.Name()) - b, err := defaultsFS.ReadFile(path) - if err != nil { - log.Fatalf("failed to read %q: %v", path, err) + b, err2 := defaultsFS.ReadFile(path) + if err2 != nil { + log.Fatalf("failed to read %q: %v", path, err2) } var config = struct { ChainID *big.Big Chain }{} - if err := cconfig.DecodeTOML(bytes.NewReader(b), &config); err != nil { - log.Fatalf("failed to decode %q: %v", path, err) + if err3 := cconfig.DecodeTOML(bytes.NewReader(b), &config); err3 != nil { + log.Fatalf("failed to decode %q: %v", path, err3) } if fe.Name() == "fallback.toml" { if config.ChainID != nil { @@ -65,6 +74,63 @@ func init() { slices.SortFunc(DefaultIDs, func(a, b *big.Big) int { return a.Cmp(b) }) + + // read the custom defaults overrides + dir := env.CustomDefaults.Get() + if dir == "" { + // short-circuit; no default overrides provided + return + } + + // use evm overrides specifically + evmDir := fmt.Sprintf("%s/evm", dir) + + // Read directory contents for evm only + entries, err := os.ReadDir(evmDir) + if err != nil { + log.Fatalf("error reading evm custom defaults override directory: %v", err) + return + } + + for _, entry := range entries { + if entry.IsDir() { + // Skip directories + continue + } + + path := evmDir + "/" + entry.Name() + file, err := os.Open(path) + if err != nil { + log.Fatalf("error opening file (name: %v) in custom defaults override directory: %v", entry.Name(), err) + } + + // Read file contents + b, err := io.ReadAll(file) + file.Close() + if err != nil { + log.Fatalf("error reading file (name: %v) contents in custom defaults override directory: %v", entry.Name(), err) + } + + var config = struct { + ChainID *big.Big + Chain + }{} + + if err := cconfig.DecodeTOML(bytes.NewReader(b), &config); err != nil { + log.Fatalf("failed to decode %q in custom defaults override directory: %v", path, err) + } + + if config.ChainID == nil { + log.Fatalf("missing ChainID in: %s in custom defaults override directory. exiting", path) + } + + id := config.ChainID.String() + + if _, ok := customDefaults[id]; ok { + log.Fatalf("%q contains duplicate ChainID: %s", path, id) + } + customDefaults[id] = config.Chain + } } // DefaultsNamed returns the default Chain values, optionally for the given chainID, as well as a name if the chainID is known. @@ -78,6 +144,9 @@ func DefaultsNamed(chainID *big.Big) (c Chain, name string) { c.SetFrom(&d) name = defaultNames[s] } + if overrides, ok := customDefaults[s]; ok { + c.SetFrom(&overrides) + } return } diff --git a/core/config/env/env.go b/core/config/env/env.go index 0ebfc357bf..c34cd7f4f5 100644 --- a/core/config/env/env.go +++ b/core/config/env/env.go @@ -20,6 +20,7 @@ var ( ThresholdKeyShare = Secret("CL_THRESHOLD_KEY_SHARE") // Migrations env vars EVMChainIDNotNullMigration0195 = "CL_EVM_CHAINID_NOT_NULL_MIGRATION_0195" + CustomDefaults = Var("CL_CHAIN_DEFAULTS") ) // LOOPP commands and vars diff --git a/main_test.go b/main_test.go index 81e056e3b8..419a4af051 100644 --- a/main_test.go +++ b/main_test.go @@ -42,6 +42,10 @@ func TestMain(m *testing.M) { })) } +// TestScripts walks through the testdata/scripts directory and runs all tests that end in +// .txt or .txtar with the testscripts library. To run an individual test, specify it in the +// -run param of go test without the txtar or txt suffix, like so: +// go test . -run TestScripts/node/validate/default func TestScripts(t *testing.T) { if testing.Short() { t.Skip("skipping testscript") diff --git a/testdata/scripts/node/validate/defaults-override.txtar b/testdata/scripts/node/validate/defaults-override.txtar new file mode 100644 index 0000000000..3accd1584b --- /dev/null +++ b/testdata/scripts/node/validate/defaults-override.txtar @@ -0,0 +1,444 @@ +# test with default override +env CL_CHAIN_DEFAULTS=default_overrides +exec chainlink node -c config.toml -s secrets.toml validate +cmp stdout out.txt + +# remove override, FinalityTagEnabled should no longer match +env CL_CHAIN_DEFAULTS= +exec chainlink node -c config.toml -s secrets.toml validate +! cmp stdout out.txt + +# overrides outside of evm suffix, FinalityTagEnabled should not match as override is not applied +env CL_CHAIN_DEFAULTS=default_overrides2 +! exec chainlink node -c config.toml -s secrets.toml validate + +# duplicate chain IDs +env CL_CHAIN_DEFAULTS=default_overrides3 +! exec chainlink node -c config.toml -s secrets.toml validate +stderr 'contains duplicate ChainID' + +-- default_overrides/evm/Ethereum_Mainnet.toml -- +ChainID = '1' +FinalityTagEnabled = true + +-- default_overrides2/Ethereum_Mainnet.toml -- +ChainID = '1' +FinalityTagEnabled = true + +-- default_overrides3/evm/Ethereum_Mainnet.toml -- +ChainID = '1' + +-- default_overrides3/evm/Ethereum_Testnet.toml -- +ChainID = '1' + +-- config.toml -- +Log.Level = 'debug' + +[[EVM]] +ChainID = '1' + +[[EVM.Nodes]] +Name = 'fake' +WSURL = 'wss://foo.bar/ws' +HTTPURL = 'https://foo.bar' + +-- secrets.toml -- +[Database] +URL = 'postgresql://user:pass1234567890abcd@localhost:5432/dbname?sslmode=disable' + +[Password] +Keystore = 'keystore_pass' + +-- out.txt -- +# Secrets: +[Database] +URL = 'xxxxx' +AllowSimplePasswords = false + +[Password] +Keystore = 'xxxxx' + +# Input Configuration: +[Log] +Level = 'debug' + +[[EVM]] +ChainID = '1' + +[[EVM.Nodes]] +Name = 'fake' +WSURL = 'wss://foo.bar/ws' +HTTPURL = 'https://foo.bar' + +# Effective Configuration, with defaults applied: +InsecureFastScrypt = false +RootDir = '~/.chainlink' +ShutdownGracePeriod = '5s' + +[Feature] +FeedsManager = true +LogPoller = false +UICSAKeys = false +CCIP = true +MultiFeedsManagers = false + +[Database] +DefaultIdleInTxSessionTimeout = '1h0m0s' +DefaultLockTimeout = '15s' +DefaultQueryTimeout = '10s' +LogQueries = false +MaxIdleConns = 10 +MaxOpenConns = 100 +MigrateOnStartup = true + +[Database.Backup] +Dir = '' +Frequency = '1h0m0s' +Mode = 'none' +OnVersionUpgrade = true + +[Database.Listener] +MaxReconnectDuration = '10m0s' +MinReconnectInterval = '1m0s' +FallbackPollInterval = '30s' + +[Database.Lock] +Enabled = true +LeaseDuration = '10s' +LeaseRefreshInterval = '1s' + +[TelemetryIngress] +UniConn = true +Logging = false +BufferSize = 100 +MaxBatchSize = 50 +SendInterval = '500ms' +SendTimeout = '10s' +UseBatchSend = true + +[AuditLogger] +Enabled = false +ForwardToUrl = '' +JsonWrapperKey = '' +Headers = [] + +[Log] +Level = 'debug' +JSONConsole = false +UnixTS = false + +[Log.File] +Dir = '' +MaxSize = '5.12gb' +MaxAgeDays = 0 +MaxBackups = 1 + +[WebServer] +AuthenticationMethod = 'local' +AllowOrigins = 'http://localhost:3000,http://localhost:6688' +BridgeResponseURL = '' +BridgeCacheTTL = '0s' +HTTPWriteTimeout = '10s' +HTTPPort = 6688 +SecureCookies = true +SessionTimeout = '15m0s' +SessionReaperExpiration = '240h0m0s' +HTTPMaxSize = '32.77kb' +StartTimeout = '15s' +ListenIP = '0.0.0.0' + +[WebServer.LDAP] +ServerTLS = true +SessionTimeout = '15m0s' +QueryTimeout = '2m0s' +BaseUserAttr = 'uid' +BaseDN = '' +UsersDN = 'ou=users' +GroupsDN = 'ou=groups' +ActiveAttribute = '' +ActiveAttributeAllowedValue = '' +AdminUserGroupCN = 'NodeAdmins' +EditUserGroupCN = 'NodeEditors' +RunUserGroupCN = 'NodeRunners' +ReadUserGroupCN = 'NodeReadOnly' +UserApiTokenEnabled = false +UserAPITokenDuration = '240h0m0s' +UpstreamSyncInterval = '0s' +UpstreamSyncRateLimit = '2m0s' + +[WebServer.MFA] +RPID = '' +RPOrigin = '' + +[WebServer.RateLimit] +Authenticated = 1000 +AuthenticatedPeriod = '1m0s' +Unauthenticated = 5 +UnauthenticatedPeriod = '20s' + +[WebServer.TLS] +CertPath = '' +ForceRedirect = false +Host = '' +HTTPSPort = 6689 +KeyPath = '' +ListenIP = '0.0.0.0' + +[JobPipeline] +ExternalInitiatorsEnabled = false +MaxRunDuration = '10m0s' +MaxSuccessfulRuns = 10000 +ReaperInterval = '1h0m0s' +ReaperThreshold = '24h0m0s' +ResultWriteQueueDepth = 100 +VerboseLogging = true + +[JobPipeline.HTTPRequest] +DefaultTimeout = '15s' +MaxSize = '32.77kb' + +[FluxMonitor] +DefaultTransactionQueueDepth = 1 +SimulateTransactions = false + +[OCR2] +Enabled = false +ContractConfirmations = 3 +BlockchainTimeout = '20s' +ContractPollInterval = '1m0s' +ContractSubscribeInterval = '2m0s' +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' +CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = true +DefaultTransactionQueueDepth = 1 +SimulateTransactions = false +TraceLogging = false + +[OCR] +Enabled = false +ObservationTimeout = '5s' +BlockchainTimeout = '20s' +ContractPollInterval = '1m0s' +ContractSubscribeInterval = '2m0s' +DefaultTransactionQueueDepth = 1 +KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' +SimulateTransactions = false +TransmitterAddress = '' +CaptureEATelemetry = false +TraceLogging = false + +[P2P] +IncomingMessageBufferSize = 10 +OutgoingMessageBufferSize = 10 +PeerID = '' +TraceLogging = false + +[P2P.V2] +Enabled = true +AnnounceAddresses = [] +DefaultBootstrappers = [] +DeltaDial = '15s' +DeltaReconcile = '1m0s' +ListenAddresses = [] + +[Keeper] +DefaultTransactionQueueDepth = 1 +GasPriceBufferPercent = 20 +GasTipCapBufferPercent = 20 +BaseFeeBufferPercent = 20 +MaxGracePeriod = 100 +TurnLookBack = 1000 + +[Keeper.Registry] +CheckGasOverhead = 200000 +PerformGasOverhead = 300000 +MaxPerformDataSize = 5000 +SyncInterval = '30m0s' +SyncUpkeepQueueSize = 10 + +[AutoPprof] +Enabled = false +ProfileRoot = '' +PollInterval = '10s' +GatherDuration = '10s' +GatherTraceDuration = '5s' +MaxProfileSize = '100.00mb' +CPUProfileRate = 1 +MemProfileRate = 1 +BlockProfileRate = 1 +MutexProfileFraction = 1 +MemThreshold = '4.00gb' +GoroutineThreshold = 5000 + +[Pyroscope] +ServerAddress = '' +Environment = 'mainnet' + +[Sentry] +Debug = false +DSN = '' +Environment = '' +Release = '' + +[Insecure] +DevWebServer = false +OCRDevelopmentMode = false +InfiniteDepthQueries = false +DisableRateLimiting = false + +[Tracing] +Enabled = false +CollectorTarget = '' +NodeID = '' +SamplingRatio = 0.0 +Mode = 'tls' +TLSCertPath = '' + +[Mercury] +VerboseLogging = false + +[Mercury.Cache] +LatestReportTTL = '1s' +MaxStaleAge = '1h0m0s' +LatestReportDeadline = '5s' + +[Mercury.TLS] +CertFile = '' + +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + +[Capabilities] +[Capabilities.Peering] +IncomingMessageBufferSize = 10 +OutgoingMessageBufferSize = 10 +PeerID = '' +TraceLogging = false + +[Capabilities.Peering.V2] +Enabled = false +AnnounceAddresses = [] +DefaultBootstrappers = [] +DeltaDial = '15s' +DeltaReconcile = '1m0s' +ListenAddresses = [] + +[Capabilities.Dispatcher] +SupportedVersion = 1 +ReceiverBufferSize = 10000 + +[Capabilities.Dispatcher.RateLimit] +GlobalRPS = 800.0 +GlobalBurst = 1000 +PerSenderRPS = 10.0 +PerSenderBurst = 50 + +[Capabilities.ExternalRegistry] +Address = '' +NetworkID = 'evm' +ChainID = '1' + +[[EVM]] +ChainID = '1' +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +FinalityDepth = 50 +FinalityTagEnabled = true +LinkContractAddress = '0x514910771AF9Ca656af840dff83E8264EcF986CA' +LogBackfillBatchSize = 1000 +LogPollInterval = '15s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 3 +MinContractPayment = '0.1 link' +NonceAutoSync = true +NoNewHeadsThreshold = '3m0s' +OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 +FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '9m0s' + +[EVM.Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '1m0s' + +[EVM.Transactions.AutoPurge] +Enabled = false + +[EVM.BalanceMonitor] +Enabled = true + +[EVM.GasEstimator] +Mode = 'BlockHistory' +PriceDefault = '20 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '1 gwei' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +EstimateGasLimit = false +BumpMin = '5 gwei' +BumpPercent = 20 +BumpThreshold = 3 +EIP1559DynamicFees = true +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[EVM.GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 4 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 50 + +[EVM.HeadTracker] +HistoryDepth = 100 +MaxBufferSize = 3 +SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true + +[EVM.NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 5 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false +FinalizedBlockPollInterval = '5s' +EnforceRepeatableRead = false +DeathDeclarationDelay = '10s' + +[EVM.OCR] +ContractConfirmations = 4 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[EVM.OCR2] +[EVM.OCR2.Automation] +GasLimit = 10500000 + +[EVM.Workflow] +GasLimitDefault = 400000 + +[[EVM.Nodes]] +Name = 'fake' +WSURL = 'wss://foo.bar/ws' +HTTPURL = 'https://foo.bar' + +Valid configuration. From 77ffa7ab36775d9b4a440deb6a751b84e5b7d7fe Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Fri, 30 Aug 2024 10:09:47 +0200 Subject: [PATCH 249/432] Remove automation related secret keys from toml test config (#14257) * Remove secret keys from test config toml * Use CTF mod without common test secrets * Reset go mod * Update readme * Bump gha in workflows * Bump gha * Fix lint --- .../workflows/automation-benchmark-tests.yml | 3 +- .github/workflows/automation-load-tests.yml | 3 +- .../workflows/automation-nightly-tests.yml | 2 +- .github/workflows/ccip-load-tests.yml | 15 ++--- .github/workflows/on-demand-ocr-soak-test.yml | 3 +- .../on-demand-vrfv2-eth2-clients-test.yml | 18 +++--- .../on-demand-vrfv2-performance-test.yml | 3 +- .../on-demand-vrfv2plus-eth2-clients-test.yml | 18 +++--- .../on-demand-vrfv2plus-performance-test.yml | 3 +- .../on-demand-vrfv2plus-smoke-tests.yml | 6 +- .../run-e2e-tests-reusable-workflow.yml | 4 +- integration-tests/smoke/vrfv2plus_test.go | 1 + integration-tests/testconfig/README.md | 15 ++++- .../testconfig/automation/config.go | 6 +- integration-tests/testconfig/testconfig.go | 55 +++++++++++++++++++ 15 files changed, 117 insertions(+), 38 deletions(-) diff --git a/.github/workflows/automation-benchmark-tests.yml b/.github/workflows/automation-benchmark-tests.yml index c5ee22cbfd..8867a1250f 100644 --- a/.github/workflows/automation-benchmark-tests.yml +++ b/.github/workflows/automation-benchmark-tests.yml @@ -71,7 +71,7 @@ jobs: QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} suites: benchmark chaos reorg load - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 env: DETACH_RUNNER: true TEST_SUITE: benchmark @@ -86,6 +86,7 @@ jobs: test_command_to_run: cd integration-tests && go test -timeout 30m -v -run ^TestAutomationBenchmark$ ./benchmark -count=1 test_download_vendor_packages_command: make gomod test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} + test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/automation-load-tests.yml b/.github/workflows/automation-load-tests.yml index 187ca3b5b6..45a1dc422b 100644 --- a/.github/workflows/automation-load-tests.yml +++ b/.github/workflows/automation-load-tests.yml @@ -86,7 +86,7 @@ jobs: QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} suites: benchmark chaos reorg load - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 env: RR_CPU: 4000m RR_MEM: 4Gi @@ -100,6 +100,7 @@ jobs: with: test_command_to_run: cd integration-tests/load && go test -timeout 1h -v -run TestLogTrigger ./automationv2_1 -count=1 test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} + test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} test_download_vendor_packages_command: make gomod cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} diff --git a/.github/workflows/automation-nightly-tests.yml b/.github/workflows/automation-nightly-tests.yml index 437bc5e2be..59d1172895 100644 --- a/.github/workflows/automation-nightly-tests.yml +++ b/.github/workflows/automation-nightly-tests.yml @@ -97,7 +97,7 @@ jobs: # other inputs duplicate-authorization-header: "true" - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c164251be2a7c5b2b23a6e5f7014982f232c14 # v2.3.32 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 env: TEST_SUITE: ${{ matrix.tests.suite }} E2E_TEST_SELECTED_NETWORK: ${{ env.SELECTED_NETWORKS }} diff --git a/.github/workflows/ccip-load-tests.yml b/.github/workflows/ccip-load-tests.yml index a6d073715d..fdf77067a5 100644 --- a/.github/workflows/ccip-load-tests.yml +++ b/.github/workflows/ccip-load-tests.yml @@ -180,7 +180,7 @@ jobs: chainlinkVersion: ${{ github.sha }} logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d38226be720c5ccc1ff4d3cee40608ebf264cd59 # v2.3.26 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 env: TEST_SUITE: load TEST_ARGS: -test.timeout 900h @@ -190,10 +190,17 @@ jobs: TEST_TRIGGERED_BY: ccip-load-test-ci-${{ matrix.type.name }} BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} + E2E_TEST_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} + E2E_TEST_LOKI_TENANT_ID: ${{ vars.LOKI_TENANT_ID }} + E2E_TEST_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} + E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + E2E_TEST_GRAFANA_BASE_URL: ${{ vars.GRAFANA_URL }} + E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" with: test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 70m -count=1 -json -run ${{ matrix.type.run }} ./load 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci test_download_vendor_packages_command: cd ./integration-tests && go mod download test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} + test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} token: ${{ secrets.GITHUB_TOKEN }} go_mod_path: ./integration-tests/go.mod QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} @@ -206,12 +213,6 @@ jobs: cache_key_id: ccip-load-${{ env.MOD_CACHE_VERSION }} cache_restore_only: "true" should_cleanup: "true" - DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - DEFAULT_LOKI_TENANT_ID: ${{ vars.LOKI_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: ${{ vars.GRAFANA_URL }} - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" # Reporting Jobs start-slack-thread: diff --git a/.github/workflows/on-demand-ocr-soak-test.yml b/.github/workflows/on-demand-ocr-soak-test.yml index 924b43829e..3b827032b1 100644 --- a/.github/workflows/on-demand-ocr-soak-test.yml +++ b/.github/workflows/on-demand-ocr-soak-test.yml @@ -93,7 +93,7 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 env: DETACH_RUNNER: true TEST_SUITE: soak @@ -106,6 +106,7 @@ jobs: test_command_to_run: cd ./integration-tests && go test -v -count=1 -run ^${{ github.event.inputs.testToRun }}$ ./soak test_download_vendor_packages_command: make gomod test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} + test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml b/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml index 6d92acd9ea..b949db0911 100644 --- a/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml +++ b/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml @@ -50,11 +50,12 @@ jobs: echo "### Execution client used" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.ETH2_EL_CLIENT }}\`" >>$GITHUB_STEP_SUMMARY - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -run TestVRFv2Basic ./smoke/vrfv2_test.go 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} + test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} @@ -68,10 +69,11 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: "" - DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + env: + E2E_TEST_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} + E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" + E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} diff --git a/.github/workflows/on-demand-vrfv2-performance-test.yml b/.github/workflows/on-demand-vrfv2-performance-test.yml index 3d55c38458..b5a4c40d12 100644 --- a/.github/workflows/on-demand-vrfv2-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2-performance-test.yml @@ -81,11 +81,12 @@ jobs: echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 with: test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run "${{ inputs.test_list_regex }}" ./vrfv2 test_download_vendor_packages_command: cd ./integration-tests && go mod download test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} + test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} diff --git a/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml b/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml index 1e58002fc1..652c51095f 100644 --- a/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml @@ -50,11 +50,12 @@ jobs: echo "### Execution client used" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.ETH2_EL_CLIENT }}\`" >>$GITHUB_STEP_SUMMARY - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -run ^TestVRFv2Plus$/^Link_Billing$ ./smoke/vrfv2plus_test.go 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} + test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} @@ -68,10 +69,11 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: "" - DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + env: + E2E_TEST_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} + E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" + E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} diff --git a/.github/workflows/on-demand-vrfv2plus-performance-test.yml b/.github/workflows/on-demand-vrfv2plus-performance-test.yml index 658736ab03..04e0c9318a 100644 --- a/.github/workflows/on-demand-vrfv2plus-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-performance-test.yml @@ -76,11 +76,12 @@ jobs: echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 with: test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run "${{ inputs.test_list_regex }}" ./vrfv2plus test_download_vendor_packages_command: cd ./integration-tests && go mod download test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} + test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} diff --git a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml index 5bd8375c40..1a62e0fe06 100644 --- a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml +++ b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml @@ -79,11 +79,12 @@ jobs: echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - name: Run Tests if: ${{ github.event.inputs.test_suite == 'Selected Tests' }} - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 with: test_command_to_run: cd ./integration-tests/smoke && go test -v -count=1 -parallel=1 -timeout 2h -run "${{ inputs.test_list_regex }}" 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} + test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} @@ -97,11 +98,12 @@ jobs: QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - name: Run Tests if: ${{ github.event.inputs.test_suite == 'All Tests' }} - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2967f2287bd3f3ddbac7b476e9568993df01796e # v2.3.27 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 with: test_command_to_run: cd ./integration-tests/smoke && go test -v -count=1 -parallel=1 -timeout 3h vrfv2plus_test.go 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} + test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index 6644bba8d9..de3f254539 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -483,7 +483,7 @@ jobs: - name: Run tests id: run_tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c164251be2a7c5b2b23a6e5f7014982f232c14 # v2.3.32 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 env: DETACH_RUNNER: true E2E_TEST_CHAINLINK_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || inputs.chainlink_version || github.sha }} @@ -665,7 +665,7 @@ jobs: - name: Run tests id: run_tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c164251be2a7c5b2b23a6e5f7014982f232c14 # v2.3.32 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 env: DETACH_RUNNER: true RR_MEM: ${{ matrix.tests.remote_runner_memory }} diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index 30b0814a96..aa2db33fa5 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -1486,6 +1486,7 @@ func TestVRFV2PlusWithBHS(t *testing.T) { require.NoError(t, err, "error getting tx from hash") bhsStoreTxInputData, err := actions.DecodeTxInputData(blockhash_store.BlockhashStoreABI, bhsStoreTx.Data()) + require.NoError(t, err, "error decoding tx input data") l.Info(). Str("Block Number", bhsStoreTxInputData["n"].(*big.Int).String()). Msg("BHS Node's Store Blockhash for Blocknumber Method TX") diff --git a/integration-tests/testconfig/README.md b/integration-tests/testconfig/README.md index 878b36bc75..9055cff2cb 100644 --- a/integration-tests/testconfig/README.md +++ b/integration-tests/testconfig/README.md @@ -51,7 +51,6 @@ This file is recommended for local use to adjust dynamic variables or modify pre ```toml [ChainlinkImage] -image = "your image name" version = "your tag" ``` @@ -64,7 +63,6 @@ cat << EOF > config.toml selected_networks=["$SELECTED_NETWORKS"] [ChainlinkImage] -image="" version="$CHAINLINK_VERSION" postgres_version="$CHAINLINK_POSTGRES_VERSION" @@ -89,6 +87,19 @@ Test secrets are not stored directly within the `TestConfig` TOML for security r For detailed instructions on how to set test secrets both locally and within CI environments, please visit: [Test Secrets Guide in CTF](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md#test-secrets) +### All test secrets + +See [All E2E Test Secrets in CTF](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md#all-e2e-test-secrets). + +### Core repo specific test secrets + +| Secret | Env Var | Example | Description | +| ----------------------------- | ------------------------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------ | +| Data Streams Url | `E2E_TEST_DATA_STREAMS_URL` | `E2E_TEST_DATA_STREAMS_URL=url` | Required by some automation tests to connect to data streams. | +| Data Streams Username | `E2E_TEST_DATA_STREAMS_USERNAME` | `E2E_TEST_DATA_STREAMS_USERNAME=username` | Required by some automation tests to connect to data streams. | +| Data Streams Password | `E2E_TEST_DATA_STREAMS_PASSWORD` | `E2E_TEST_DATA_STREAMS_PASSWORD=password` | Required by some automation tests to connect to data streams. | + + ## Named Configurations Named configurations allow for the customization of settings through unique identifiers, such as a test name or type, acting as specific overrides. Here's how you can define and use these configurations: diff --git a/integration-tests/testconfig/automation/config.go b/integration-tests/testconfig/automation/config.go index e6df7714af..bb38b213ec 100644 --- a/integration-tests/testconfig/automation/config.go +++ b/integration-tests/testconfig/automation/config.go @@ -129,9 +129,9 @@ func (c *Load) Validate() error { type DataStreams struct { Enabled *bool `toml:"enabled"` - URL *string `toml:"url"` - Username *string `toml:"username"` - Password *string `toml:"password"` + URL *string `toml:"-"` + Username *string `toml:"-"` + Password *string `toml:"-"` DefaultFeedID *string `toml:"default_feed_id"` } diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index 9510886f06..5bdabcecd6 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -72,6 +72,12 @@ type Ocr2TestConfig interface { GetOCR2Config() *ocr_config.Config } +const ( + E2E_TEST_DATA_STREAMS_URL_ENV = "E2E_TEST_DATA_STREAMS_URL" + E2E_TEST_DATA_STREAMS_USERNAME_ENV = "E2E_TEST_DATA_STREAMS_USERNAME" + E2E_TEST_DATA_STREAMS_PASSWORD_ENV = "E2E_TEST_DATA_STREAMS_PASSWORD" +) + type TestConfig struct { ctf_config.TestConfig @@ -404,6 +410,55 @@ func GetConfig(configurationNames []string, product Product) (TestConfig, error) return testConfig, nil } +// Read config values from environment variables +func (c *TestConfig) ReadFromEnvVar() error { + logger := logging.GetTestLogger(nil) + + // Read values for base config from env vars + err := c.TestConfig.ReadFromEnvVar() + if err != nil { + return errors.Wrapf(err, "error reading test config values from env vars") + } + + dsURL := ctf_config.MustReadEnvVar_String(E2E_TEST_DATA_STREAMS_URL_ENV) + if dsURL != "" { + if c.Automation == nil { + c.Automation = &a_config.Config{} + } + if c.Automation.DataStreams == nil { + c.Automation.DataStreams = &a_config.DataStreams{} + } + logger.Debug().Msgf("Using %s env var to override Automation.DataStreams.URL", E2E_TEST_DATA_STREAMS_URL_ENV) + c.Automation.DataStreams.URL = &dsURL + } + + dsUsername := ctf_config.MustReadEnvVar_String(E2E_TEST_DATA_STREAMS_USERNAME_ENV) + if dsUsername != "" { + if c.Automation == nil { + c.Automation = &a_config.Config{} + } + if c.Automation.DataStreams == nil { + c.Automation.DataStreams = &a_config.DataStreams{} + } + logger.Debug().Msgf("Using %s env var to override Automation.DataStreams.Username", E2E_TEST_DATA_STREAMS_USERNAME_ENV) + c.Automation.DataStreams.Username = &dsUsername + } + + dsPassword := ctf_config.MustReadEnvVar_String(E2E_TEST_DATA_STREAMS_PASSWORD_ENV) + if dsPassword != "" { + if c.Automation == nil { + c.Automation = &a_config.Config{} + } + if c.Automation.DataStreams == nil { + c.Automation.DataStreams = &a_config.DataStreams{} + } + logger.Debug().Msgf("Using %s env var to override Automation.DataStreams.Password", E2E_TEST_DATA_STREAMS_PASSWORD_ENV) + c.Automation.DataStreams.Password = &dsPassword + } + + return nil +} + func (c *TestConfig) logRiskySettings(logger zerolog.Logger) { isAnySimulated := false for _, network := range c.Network.SelectedNetworks { From 5fa57ccefd05024f651e6ce834740df1a2529d11 Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs <5300706+iljapavlovs@users.noreply.github.com> Date: Fri, 30 Aug 2024 11:13:31 +0300 Subject: [PATCH 250/432] Fix VRF CTF Test Lint issue (#14283) --- integration-tests/smoke/vrfv2_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index b21dafcacd..0caff0910c 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -985,6 +985,7 @@ func TestVRFV2WithBHS(t *testing.T) { require.NoError(t, err, "error getting tx from hash") bhsStoreTxInputData, err := actions.DecodeTxInputData(blockhash_store.BlockhashStoreABI, bhsStoreTx.Data()) + require.NoError(t, err, "error decoding tx input data") l.Info(). Str("Block Number", bhsStoreTxInputData["n"].(*big.Int).String()). Msg("BHS Node's Store Blockhash for Blocknumber Method TX") From b36e7313458035197640bd445cde0228d5fdf6ae Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Fri, 30 Aug 2024 11:28:04 +0200 Subject: [PATCH 251/432] pin havoc to v0.1.0 (#14284) --- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index c16a02c1c7..6db9ac2af9 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -39,7 +39,7 @@ require ( github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 github.com/smartcontractkit/chainlink-testing-framework v1.34.10 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 - github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 + github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 07b4c7c40b..82c6f71c3c 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1439,8 +1439,8 @@ github.com/smartcontractkit/chainlink-testing-framework v1.34.10 h1:7boGJr/wkX5T github.com/smartcontractkit/chainlink-testing-framework v1.34.10/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 h1:1/r1wQZ4TOFpZ13w94r7amdF096Z96RuEnkOmrz1BGE= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= -github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= -github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= +github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 h1:eHsvf2SklyyZ5fTHJIsIZ3eUnfO0TJU2BSZ7j8kLvzM= +github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 h1:GRAAvtn2+jhO/8Z3lig10eQXVcV4VuOI4UgCyoPdJBg= github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 78d46b5d38..e56161f01d 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -61,7 +61,7 @@ require ( github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240806144315-04ac101e9c95 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 // indirect + github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect k8s.io/apimachinery v0.31.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 8377b2d432..31cc2eec6c 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1409,8 +1409,8 @@ github.com/smartcontractkit/chainlink-testing-framework v1.34.10 h1:7boGJr/wkX5T github.com/smartcontractkit/chainlink-testing-framework v1.34.10/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a h1:8GtvGJaGyKzx/ar1yX74GxrzIYWTZVTyv4pYB/1ln8w= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= -github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1 h1:7LbvjrRseY/Cu9mgPO31SgdEUiZJJemc6glCfpLdMtM= -github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-20240822140612-df8e03c10dc1/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= +github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 h1:eHsvf2SklyyZ5fTHJIsIZ3eUnfO0TJU2BSZ7j8kLvzM= +github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 h1:GRAAvtn2+jhO/8Z3lig10eQXVcV4VuOI4UgCyoPdJBg= github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= From 7cb4959fa45aa0d4824c8cd821af36eaad8a140f Mon Sep 17 00:00:00 2001 From: Kostis Karantias <732062+gtklocker@users.noreply.github.com> Date: Wed, 28 Aug 2024 15:17:57 +0300 Subject: [PATCH 252/432] Fix typo in RMN.sol doc (#1383) --- contracts/src/v0.8/ccip/RMN.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/src/v0.8/ccip/RMN.sol b/contracts/src/v0.8/ccip/RMN.sol index ef672bb7ab..deffb57fbe 100644 --- a/contracts/src/v0.8/ccip/RMN.sol +++ b/contracts/src/v0.8/ccip/RMN.sol @@ -13,7 +13,7 @@ import {EnumerableSet} from "../vendor/openzeppelin-solidity/v5.0.2/contracts/ut // deployed, relying on isCursed(). bytes16 constant LEGACY_CURSE_SUBJECT = 0x01000000000000000000000000000000; -// An active curse on this subject will cause isCursed() and isCursed(bytes32) to return true. Use this subject for +// An active curse on this subject will cause isCursed() and isCursed(bytes16) to return true. Use this subject for // issues affecting all of CCIP chains, or pertaining to the chain that this contract is deployed on, instead of using // the local chain selector as a subject. bytes16 constant GLOBAL_CURSE_SUBJECT = 0x01000000000000000000000000000001; From d7c47cbd358b94ab27accb37dc12ca7c0cb166f2 Mon Sep 17 00:00:00 2001 From: kanth <70688600+defistar@users.noreply.github.com> Date: Wed, 28 Aug 2024 19:14:14 +0530 Subject: [PATCH 253/432] feat: CCIP-3020 Add AllowList Config struct and implementation (#1335) The key objective of allowlisting senders is to restrict the senders (EOA or smart contract) that can send CCIP Messages from a given blockchain to a specified destination blockchain. While acknowledging this additional check may come with gas cost, we aim to achieve this objective with minimal gas cost increments. The CCIP OnRamp contract must be able to allow only specific senders (EOA or smart contract), identified by address, to send CCIP messages to a specific destination blockchain, identified by destinationChainSelector. CCIP messages for a specific destination blockchain for which the sender is not included in the allowlist must be rejected. A proper error must be returned. It should be possible to activate/deactivate the allowlist capability of an OnRamp for a given destination chain. Options include: - A flag that enables/disables allowlisting capability - The selected approach should consider gas cost, clarity and simplicity. Only a designed entity must be able to update the allowlist configuration. By default this is CCIP Owner, but it must be possible for CCIP Owner to also add a third party (i.e. AllowListAdmin) to have this privilege. - Add new properties to DestChainConfig Struct ```js /// @dev Struct to hold the configs for a destination chain /// @dev sequenceNumber, allowListEnabled, router will all be packed in 1 slot struct DestChainConfig { // The last used sequence number. This is zero in the case where no messages have yet been sent. // 0 is not a valid sequence number for any real transaction. uint64 sequenceNumber; // boolean indicator to specify if allowList check is enabled bool allowListEnabled; // This is the local router address that is allowed to send messages to the destination chain. // This is NOT the receiving router address on the destination chain. IRouter router; // This is the list of addresses allowed to send messages from onRamp EnumerableSet.AddressSet allowedSendersList; } ``` - functions to applyAllowList ```js function applyAllowListUpdates(AllowListConfigArgs[] calldata allowListConfigArgsItems) external { ``` - a struct to hold the applyAllowList Information ```js struct AllowListConfigArgs { uint64 destChainSelector; // Destination chain selector bool allowListEnabled; // indicator to check if the allowedSendersList is enabled address[] addedAllowlistedSenders; // list of senders to be added to the allowedSendersList address[] removedAllowlistedSenders; // list of senders to be removed from the allowedSendersList } ``` --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/gas-snapshots/ccip.gas-snapshot | 150 ++--- contracts/src/v0.8/ccip/onRamp/OnRamp.sol | 124 ++++- .../src/v0.8/ccip/test/onRamp/OnRamp.t.sol | 215 +++++++- .../v0.8/ccip/test/onRamp/OnRampSetup.t.sol | 7 +- .../ccip/generated/onramp/onramp.go | 519 +++++++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- integration-tests/web/sdk/client/client.go | 4 +- 7 files changed, 914 insertions(+), 107 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index cf27861983..e2c0c4ad78 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -103,7 +103,7 @@ CommitStore_report:test_OnlyPriceUpdateStaleReport_Revert() (gas: 59071) CommitStore_report:test_OnlyTokenPriceUpdates_Success() (gas: 53273) CommitStore_report:test_Paused_Revert() (gas: 21259) CommitStore_report:test_ReportAndPriceUpdate_Success() (gas: 84264) -CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56249) +CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56313) CommitStore_report:test_RootAlreadyCommitted_Revert() (gas: 63969) CommitStore_report:test_StaleReportWithRoot_Success() (gas: 119364) CommitStore_report:test_Unhealthy_Revert() (gas: 44751) @@ -123,7 +123,7 @@ CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424256) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1100023) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1104033) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37797) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103733) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85258) @@ -162,13 +162,13 @@ EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 42539) EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 157347) EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 172692) EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 247069) -EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 113842) +EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114153) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 407451) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54096) EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 131047) EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52090) EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 563385) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 494182) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 495508) EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35383) EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 544641) EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64326) @@ -178,7 +178,7 @@ EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 427337) EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18502) EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 278097) EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 18659) -EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 223921) +EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 221421) EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47881) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 47352) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 313917) @@ -230,21 +230,21 @@ EVM2EVMOnRamp_forwardFromRouter:test_MaxFeeBalanceReached_Revert() (gas: 36457) EVM2EVMOnRamp_forwardFromRouter:test_MessageGasLimitTooHigh_Revert() (gas: 29015) EVM2EVMOnRamp_forwardFromRouter:test_MessageTooLarge_Revert() (gas: 107571) EVM2EVMOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 22679) -EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 227119) +EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 224619) EVM2EVMOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 53072) EVM2EVMOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 25481) EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59341) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179148) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 177430) EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137254) -EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3825327) +EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3822827) EVM2EVMOnRamp_forwardFromRouter:test_TooManyTokens_Revert() (gas: 30187) EVM2EVMOnRamp_forwardFromRouter:test_Unhealthy_Revert() (gas: 43300) EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109305) EVM2EVMOnRamp_forwardFromRouter:test_ZeroAddressReceiver_Revert() (gas: 312579) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_ShouldStoreLinkFees_Success() (gas: 112322) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 72206) -EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 712975) +EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 710475) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 147664) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 190529) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 121320) @@ -275,7 +275,7 @@ EVM2EVMOnRamp_getTokenTransferCost:test__getTokenTransferCost_selfServeUsesDefau EVM2EVMOnRamp_linkAvailableForPayment:test_InsufficientLinkBalance_Success() (gas: 32615) EVM2EVMOnRamp_linkAvailableForPayment:test_LinkAvailableForPayment_Success() (gas: 134833) EVM2EVMOnRamp_payNops:test_AdminPayNops_Success() (gas: 143159) -EVM2EVMOnRamp_payNops:test_InsufficientBalance_Revert() (gas: 29043) +EVM2EVMOnRamp_payNops:test_InsufficientBalance_Revert() (gas: 26543) EVM2EVMOnRamp_payNops:test_NoFeesToPay_Revert() (gas: 127367) EVM2EVMOnRamp_payNops:test_NoNopsToPay_Revert() (gas: 133251) EVM2EVMOnRamp_payNops:test_NopPayNops_Success() (gas: 146446) @@ -307,7 +307,7 @@ EVM2EVMOnRamp_withdrawNonLinkFees:test_SettlingBalance_Success() (gas: 272035) EVM2EVMOnRamp_withdrawNonLinkFees:test_WithdrawNonLinkFees_Success() (gas: 53446) EVM2EVMOnRamp_withdrawNonLinkFees:test_WithdrawToZeroAddress_Revert() (gas: 12830) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_fallbackToWethTransfer() (gas: 96729) -EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 49688) +EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 47688) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongToken() (gas: 17384) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongTokenAmount() (gas: 15677) EtherSenderReceiverTest_ccipSend:test_ccipSend_reverts_insufficientFee_feeToken() (gas: 99741) @@ -514,7 +514,7 @@ MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExce MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78668) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 311927) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54728) -MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 1073667529) +MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 9223372036854754743) MultiAggregateRateLimiter_onOutboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 19149) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 15823) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213716) @@ -556,16 +556,16 @@ MultiOCR3Base_transmit:test_InsufficientSignatures_Revert() (gas: 76930) MultiOCR3Base_transmit:test_NonUniqueSignature_Revert() (gas: 66127) MultiOCR3Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 33419) MultiOCR3Base_transmit:test_TooManySignatures_Revert() (gas: 79521) -MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34020) +MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34131) MultiOCR3Base_transmit:test_TransmitWithExtraCalldataArgs_Revert() (gas: 47114) MultiOCR3Base_transmit:test_TransmitWithLessCalldataArgs_Revert() (gas: 25682) -MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18714) +MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18726) MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) -MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 410714) -MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1499807) +MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 410978) +MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1504783) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) @@ -577,10 +577,10 @@ NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success( NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244814) NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 233069) NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 153186) -NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 168502) -NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 220478) +NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 168681) +NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 220836) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) -NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 107731) +NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 107910) NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 122943) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOffRamp_Revert() (gas: 42959) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRampAndOffRamp_Revert() (gas: 64282) @@ -595,7 +595,7 @@ OCR2BaseNoChecks_setOCR2Config:test_TooManyTransmitter_Revert() (gas: 36938) OCR2BaseNoChecks_setOCR2Config:test_TransmitterCannotBeZeroAddress_Revert() (gas: 24158) OCR2BaseNoChecks_transmit:test_ConfigDigestMismatch_Revert() (gas: 17448) OCR2BaseNoChecks_transmit:test_ForkedChain_Revert() (gas: 26726) -OCR2BaseNoChecks_transmit:test_TransmitSuccess_gas() (gas: 27466) +OCR2BaseNoChecks_transmit:test_TransmitSuccess_gas() (gas: 27478) OCR2BaseNoChecks_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 21296) OCR2Base_setOCR2Config:test_FMustBePositive_Revert() (gas: 12189) OCR2Base_setOCR2Config:test_FTooHigh_Revert() (gas: 12345) @@ -609,7 +609,7 @@ OCR2Base_transmit:test_ConfigDigestMismatch_Revert() (gas: 19623) OCR2Base_transmit:test_ForkedChain_Revert() (gas: 37683) OCR2Base_transmit:test_NonUniqueSignature_Revert() (gas: 55309) OCR2Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 20962) -OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51674) +OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51686) OCR2Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 23484) OCR2Base_transmit:test_UnauthorizedSigner_Revert() (gas: 39665) OCR2Base_transmit:test_WrongNumberOfSignatures_Revert() (gas: 20557) @@ -676,7 +676,7 @@ OffRamp_execute:test_ZeroReports_Revert() (gas: 17225) OffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18257) OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249037) OffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20517) -OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 210176) +OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 207676) OffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48779) OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48302) OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229565) @@ -698,12 +698,12 @@ OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 193345) OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 212938) OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 266576) -OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 141191) +OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 141488) OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 423378) OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65877) OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80932) OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 587410) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 535220) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 536450) OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35743) OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 532474) OffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 529798) @@ -747,48 +747,56 @@ OffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178754) OffRamp_verify:test_NotBlessed_Success() (gas: 141593) OffRamp_verify:test_TooManyLeaves_Revert() (gas: 51510) OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 390336) -OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 63649) +OnRamp_allowListConfigUpdates:test_applyAllowList_Success() (gas: 323566) +OnRamp_allowListConfigUpdates:test_applyAllowList_Revert() (gas: 66509) +OnRamp_allowListConfigUpdates:test_setAllowListAdmin_ByNonOwner_Revert() (gas: 11833) +OnRamp_allowListConfigUpdates:test_setAllowListAdmin_Success() (gas: 36159) +OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInvalidChainSelector_Revert() (gas: 13242) +OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 64501) OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() (gas: 13308) -OnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94260) -OnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92177) -OnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97198) -OnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92235) -OnRamp_constructor:test_Constructor_Success() (gas: 2455004) -OnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 72010) -OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 112791) -OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 143561) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 143137) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 141314) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 143367) -OnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 142736) -OnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 135246) -OnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 26349) -OnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 133253) -OnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 24426) -OnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12872) -OnRamp_forwardFromRouter:test_Paused_Revert() (gas: 32033) -OnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 15762) -OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 182032) -OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 208301) -OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 122714) -OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 144094) -OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3889991) -OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108659) -OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 74066) -OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 275916) -OnRamp_getFee:test_EmptyMessage_Success() (gas: 104351) -OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 73173) -OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119675) -OnRamp_getFee:test_Unhealthy_Revert() (gas: 43679) +OnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94878) +OnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92812) +OnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97827) +OnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92870) +OnRamp_constructor:test_Constructor_Success() (gas: 2866937) +OnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 72097) +OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 115250) +OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 146019) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 145615) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 143816) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 145847) +OnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 145216) +OnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 140359) +OnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 28810) +OnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 138683) +OnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 26910) +OnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12918) +OnRamp_forwardFromRouter:test_Paused_Revert() (gas: 37224) +OnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 18179) +OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 185252) +OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 211543) +OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 125128) +OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 146530) +OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3891732) +OnRamp_forwardFromRouter:test_UnAllowedOriginalSender_Revert() (gas: 18609) +OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 111118) +OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 76545) +OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 278740) +OnRamp_forwardFromRouter:test_MultiCannotSendZeroTokens_Revert() (gas: 74456) +OnRamp_getFee:test_EmptyMessage_Success() (gas: 104331) +OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 73163) +OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119655) +OnRamp_getFee:test_Unhealthy_Revert() (gas: 43669) OnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10438) -OnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35270) -OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11155) -OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeQuoterEqAddressZero_Revert() (gas: 12763) -OnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11112) -OnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939) -OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 52018) -OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97192) -PingPong_ccipReceive:test_CcipReceive_Success() (gas: 152669) +OnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35204) +OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11402) +OnRamp_setDynamicConfig:test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() (gas: 12978) +OnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11359) +OnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 16385) +OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 55321) +OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeQuoterEqAddressZero_Revert() (gas: 13001) +OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97107) +PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150169) PingPong_plumbing:test_OutOfOrderExecution_Success() (gas: 20277) PingPong_plumbing:test_Pausing_Success() (gas: 17777) PingPong_startPingPong:test_StartPingPong_With_OOO_Success() (gas: 163187) @@ -801,7 +809,7 @@ RMN_ownerUnbless:test_Unbless_Success() (gas: 74699) RMN_ownerUnvoteToCurse:test_CanBlessAndCurseAfterGlobalCurseIsLifted() (gas: 470965) RMN_ownerUnvoteToCurse:test_IsIdempotent() (gas: 397532) RMN_ownerUnvoteToCurse:test_NonOwner_Revert() (gas: 18591) -RMN_ownerUnvoteToCurse:test_OwnerUnvoteToCurseSuccess_gas() (gas: 357400) +RMN_ownerUnvoteToCurse:test_OwnerUnvoteToCurseSuccess_gas() (gas: 357403) RMN_ownerUnvoteToCurse:test_UnknownVoter_Revert() (gas: 32980) RMN_ownerUnvoteToCurse_Benchmark:test_OwnerUnvoteToCurse_1Voter_LiftsCurse_gas() (gas: 261985) RMN_permaBlessing:test_PermaBlessing() (gas: 202686) @@ -809,7 +817,7 @@ RMN_setConfig:test_BlessVoterIsZeroAddress_Revert() (gas: 15494) RMN_setConfig:test_EitherThresholdIsZero_Revert() (gas: 21095) RMN_setConfig:test_NonOwner_Revert() (gas: 14713) RMN_setConfig:test_RepeatedAddress_Revert() (gas: 18213) -RMN_setConfig:test_SetConfigSuccess_gas() (gas: 104022) +RMN_setConfig:test_SetConfigSuccess_gas() (gas: 104204) RMN_setConfig:test_TotalWeightsSmallerThanEachThreshold_Revert() (gas: 30173) RMN_setConfig:test_VoteToBlessByEjectedVoter_Revert() (gas: 130303) RMN_setConfig:test_VotersLengthIsZero_Revert() (gas: 12128) @@ -894,18 +902,18 @@ Router_getFee:test_GetFeeSupportedChain_Success() (gas: 46458) Router_getFee:test_UnsupportedDestinationChain_Revert() (gas: 17138) Router_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10460) Router_recoverTokens:test_RecoverTokensInvalidRecipient_Revert() (gas: 11316) -Router_recoverTokens:test_RecoverTokensNoFunds_Revert() (gas: 20261) +Router_recoverTokens:test_RecoverTokensNoFunds_Revert() (gas: 17761) Router_recoverTokens:test_RecoverTokensNonOwner_Revert() (gas: 11159) Router_recoverTokens:test_RecoverTokensValueReceiver_Revert() (gas: 422138) -Router_recoverTokens:test_RecoverTokens_Success() (gas: 52437) +Router_recoverTokens:test_RecoverTokens_Success() (gas: 50437) Router_routeMessage:test_AutoExec_Success() (gas: 42684) Router_routeMessage:test_ExecutionEvent_Success() (gas: 157980) Router_routeMessage:test_ManualExec_Success() (gas: 35381) Router_routeMessage:test_OnlyOffRamp_Revert() (gas: 25116) Router_routeMessage:test_WhenNotHealthy_Revert() (gas: 44724) Router_setWrappedNative:test_OnlyOwner_Revert() (gas: 10985) -SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 55531) -SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 419466) +SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 53531) +SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 416966) SelfFundedPingPong_setCountIncrBeforeFunding:test_setCountIncrBeforeFunding() (gas: 20151) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_OnlyPendingAdministrator_Revert() (gas: 51085) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_Success() (gas: 43947) @@ -933,8 +941,8 @@ TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6070353) TokenPoolAndProxy:test_lockOrBurn_burnWithFromMint_Success() (gas: 6101826) TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6319594) TokenPoolAndProxy:test_setPreviousPool_Success() (gas: 3387124) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6916278) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7100303) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6913778) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7097803) TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2209837) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12089) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23324) diff --git a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol index aa4edba3ac..947859eb01 100644 --- a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol @@ -19,12 +19,14 @@ import {USDPriceWith18Decimals} from "../libraries/USDPriceWith18Decimals.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; /// @notice The OnRamp is a contract that handles lane-specific fee logic /// @dev The OnRamp and OffRamp form an xchain upgradeable unit. Any change to one of them /// results in an onchain upgrade of all 3. contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { using SafeERC20 for IERC20; + using EnumerableSet for EnumerableSet.AddressSet; using USDPriceWith18Decimals for uint224; error CannotSendZeroTokens(); @@ -35,13 +37,21 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { error CursedByRMN(uint64 sourceChainSelector); error GetSupportedTokensFunctionalityRemovedCheckAdminRegistry(); error InvalidDestChainConfig(uint64 sourceChainSelector); + error OnlyCallableByOwnerOrAllowlistAdmin(); + error SenderNotAllowed(address sender); + error InvalidAllowListRequest(uint64 destChainSelector); event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig); - event DestChainConfigSet(uint64 indexed destChainSelector, DestChainConfig destChainConfig); + event DestChainConfigSet( + uint64 indexed destChainSelector, uint64 sequenceNumber, IRouter router, bool allowListEnabled + ); event FeePaid(address indexed feeToken, uint256 feeValueJuels); event FeeTokenWithdrawn(address indexed feeAggregator, address indexed feeToken, uint256 amount); /// RMN depends on this event, if changing, please notify the RMN maintainers. event CCIPSendRequested(uint64 indexed destChainSelector, Internal.EVM2AnyRampMessage message); + event AllowListAdminSet(address indexed allowListAdmin); + event AllowListSendersAdded(uint64 indexed destChainSelector, address[] senders); + event AllowListSendersRemoved(uint64 indexed destChainSelector, address[] senders); /// @dev Struct that contains the static configuration /// RMN depends on this struct, if changing, please notify the RMN maintainers. @@ -59,16 +69,19 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { address feeQuoter; // FeeQuoter address address messageValidator; // Optional message validator to validate outbound messages (zero address = no validator) address feeAggregator; // Fee aggregator address + address allowListAdmin; // authorized admin to add or remove allowed senders } /// @dev Struct to hold the configs for a destination chain + /// @dev sequenceNumber, allowListEnabled, router will all be packed in 1 slot struct DestChainConfig { // The last used sequence number. This is zero in the case where no messages have yet been sent. // 0 is not a valid sequence number for any real transaction. - uint64 sequenceNumber; - // This is the local router address that is allowed to send messages to the destination chain. - // This is NOT the receiving router address on the destination chain. - IRouter router; + uint64 sequenceNumber; // ──────╮ The last used sequence number + bool allowListEnabled; // │ boolean indicator to specify if allowList check is enabled + IRouter router; // ─────────────╯ Local router address that is allowed to send messages to the destination chain. + // This is the list of addresses allowed to send messages from onRamp + EnumerableSet.AddressSet allowedSendersList; } /// @dev Same as DestChainConfig but with the destChainSelector so that an array of these @@ -79,6 +92,19 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { IRouter router; // Source router address } + /// @dev Struct used to apply AllowList Senders for multiple destChainSelectors + /// @dev the senders in the AllowlistedSenders here is the user that sends the message + /// @dev the config restricts the chain to allow only allowedList of senders to send message from this chain to a destChainSelector + /// @dev destChainSelector, allowListEnabled will be packed in 1 slot + //solhint-disable gas-struct-packing + struct AllowListConfigArgs { + uint64 destChainSelector; // ─────────────╮ Destination chain selector + // │ destChainSelector and allowListEnabled are packed in the same slot + bool allowListEnabled; // ────────────────╯ boolean indicator to specify if allowList check is enabled. + address[] addedAllowlistedSenders; // list of senders to be added to the allowedSendersList + address[] removedAllowlistedSenders; // list of senders to be removed from the allowedSendersList + } + // STATIC CONFIG string public constant override typeAndVersion = "OnRamp 1.6.0-dev"; /// @dev The chain ID of the source chain that this contract is deployed to @@ -141,6 +167,13 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { // NOTE: assumes the message has already been validated through the getFee call // Validate message sender is set and allowed. Not validated in `getFee` since it is not user-driven. if (originalSender == address(0)) revert RouterMustSetOriginalSender(); + + if (destChainConfig.allowListEnabled) { + if (!destChainConfig.allowedSendersList.contains(originalSender)) { + revert SenderNotAllowed(originalSender); + } + } + // Router address may be zero intentionally to pause. if (msg.sender != address(destChainConfig.router)) revert MustBeCalledByRouter(); @@ -327,13 +360,82 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { revert InvalidDestChainConfig(destChainSelector); } - DestChainConfig memory newDestChainConfig = DestChainConfig({ - sequenceNumber: s_destChainConfigs[destChainSelector].sequenceNumber, - router: destChainConfigArg.router - }); - s_destChainConfigs[destChainSelector] = newDestChainConfig; + DestChainConfig storage destChainConfig = s_destChainConfigs[destChainSelector]; + destChainConfig.router = destChainConfigArg.router; + + emit DestChainConfigSet( + destChainSelector, destChainConfig.sequenceNumber, destChainConfigArg.router, destChainConfig.allowListEnabled + ); + } + } + + /// @notice get ChainConfig configured for the DestinationChainSelector + /// @param destChainSelector The destination chain selector + /// @return sequenceNumber The last used sequence number + /// @return allowListEnabled boolean indicator to specify if allowList check is enabled + /// @return router address of the router + function getDestChainConfig(uint64 destChainSelector) + public + view + returns (uint64 sequenceNumber, bool allowListEnabled, address router) + { + DestChainConfig storage config = s_destChainConfigs[destChainSelector]; + sequenceNumber = config.sequenceNumber; + allowListEnabled = config.allowListEnabled; + router = address(config.router); + return (sequenceNumber, allowListEnabled, router); + } + + /// @notice get allowedSenders List configured for the DestinationChainSelector + /// @param destChainSelector The destination chain selector + /// @return array of allowedList of Senders + function getAllowedSendersList(uint64 destChainSelector) public view returns (address[] memory) { + return s_destChainConfigs[destChainSelector].allowedSendersList.values(); + } + + // ================================================================ + // │ Allowlist │ + // ================================================================ + + /// @notice Updates allowListConfig for Senders + /// @dev configuration used to set the list of senders who are authorized to send messages + /// @param allowListConfigArgsItems Array of AllowListConfigArguments where each item is for a destChainSelector + function applyAllowListUpdates(AllowListConfigArgs[] calldata allowListConfigArgsItems) external { + if (msg.sender != owner()) { + if (msg.sender != s_dynamicConfig.allowListAdmin) { + revert OnlyCallableByOwnerOrAllowlistAdmin(); + } + } + + for (uint256 i = 0; i < allowListConfigArgsItems.length; ++i) { + AllowListConfigArgs memory allowListConfigArgs = allowListConfigArgsItems[i]; - emit DestChainConfigSet(destChainSelector, newDestChainConfig); + DestChainConfig storage destChainConfig = s_destChainConfigs[allowListConfigArgs.destChainSelector]; + destChainConfig.allowListEnabled = allowListConfigArgs.allowListEnabled; + + if (allowListConfigArgs.allowListEnabled) { + for (uint256 j = 0; j < allowListConfigArgs.addedAllowlistedSenders.length; ++j) { + address toAdd = allowListConfigArgs.addedAllowlistedSenders[j]; + if (toAdd == address(0)) { + revert InvalidAllowListRequest(allowListConfigArgs.destChainSelector); + } + destChainConfig.allowedSendersList.add(toAdd); + } + + if (allowListConfigArgs.addedAllowlistedSenders.length > 0) { + emit AllowListSendersAdded(allowListConfigArgs.destChainSelector, allowListConfigArgs.addedAllowlistedSenders); + } + } + + for (uint256 k = 0; k < allowListConfigArgs.removedAllowlistedSenders.length; ++k) { + destChainConfig.allowedSendersList.remove(allowListConfigArgs.removedAllowlistedSenders[k]); + } + + if (allowListConfigArgs.removedAllowlistedSenders.length > 0) { + emit AllowListSendersRemoved( + allowListConfigArgs.destChainSelector, allowListConfigArgs.removedAllowlistedSenders + ); + } } } diff --git a/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol index 43d57b4624..f69a4eafec 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol @@ -30,7 +30,7 @@ contract OnRamp_constructor is OnRampSetup { vm.expectEmit(); emit OnRamp.ConfigSet(staticConfig, dynamicConfig); vm.expectEmit(); - emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, OnRamp.DestChainConfig(0, s_sourceRouter)); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, 0, s_sourceRouter, false); _deployOnRamp(SOURCE_CHAIN_SELECTOR, s_sourceRouter, address(s_outboundNonceManager), address(s_tokenAdminRegistry)); @@ -117,6 +117,20 @@ contract OnRamp_forwardFromRouter is OnRampSetup { feeTokens[0] = s_sourceTokens[1]; s_feeQuoter.applyFeeTokensUpdates(feeTokens, new address[](0)); + uint64[] memory destinationChainSelectors = new uint64[](1); + destinationChainSelectors[0] = DEST_CHAIN_SELECTOR; + address[] memory addAllowedList = new address[](1); + addAllowedList[0] = OWNER; + OnRamp.AllowListConfigArgs memory allowListConfigArgs = OnRamp.AllowListConfigArgs({ + allowListEnabled: true, + destChainSelector: DEST_CHAIN_SELECTOR, + addedAllowlistedSenders: addAllowedList, + removedAllowlistedSenders: new address[](0) + }); + OnRamp.AllowListConfigArgs[] memory applyAllowListConfigArgsItems = new OnRamp.AllowListConfigArgs[](1); + applyAllowListConfigArgsItems[0] = allowListConfigArgs; + s_onRamp.applyAllowListUpdates(applyAllowListConfigArgsItems); + // Since we'll mostly be testing for valid calls from the router we'll // mock all calls to be originating from the router and re-mock in // tests that require failure. @@ -308,6 +322,25 @@ contract OnRamp_forwardFromRouter is OnRampSetup { vm.assume(originalSender != address(0)); vm.assume(uint160(receiver) >= Internal.PRECOMPILE_SPACE); feeTokenAmount = uint96(bound(feeTokenAmount, 0, MAX_MSG_FEES_JUELS)); + vm.stopPrank(); + + vm.startPrank(OWNER); + uint64[] memory destinationChainSelectors = new uint64[](1); + destinationChainSelectors[0] = uint64(DEST_CHAIN_SELECTOR); + address[] memory addAllowedList = new address[](1); + addAllowedList[0] = originalSender; + OnRamp.AllowListConfigArgs memory allowListConfigArgs = OnRamp.AllowListConfigArgs({ + allowListEnabled: true, + destChainSelector: DEST_CHAIN_SELECTOR, + addedAllowlistedSenders: addAllowedList, + removedAllowlistedSenders: new address[](0) + }); + OnRamp.AllowListConfigArgs[] memory applyAllowListConfigArgsItems = new OnRamp.AllowListConfigArgs[](1); + applyAllowListConfigArgsItems[0] = allowListConfigArgs; + s_onRamp.applyAllowListUpdates(applyAllowListConfigArgsItems); + vm.stopPrank(); + + vm.startPrank(address(s_sourceRouter)); Client.EVM2AnyMessage memory message = _generateEmptyMessage(); message.receiver = abi.encode(receiver); @@ -379,6 +412,13 @@ contract OnRamp_forwardFromRouter is OnRampSetup { s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, address(0)); } + function test_UnAllowedOriginalSender_Revert() public { + vm.stopPrank(); + vm.startPrank(STRANGER); + vm.expectRevert(abi.encodeWithSelector(OnRamp.SenderNotAllowed.selector, STRANGER)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, STRANGER); + } + function test_MessageValidationError_Revert() public { _enableOutboundMessageValidator(); @@ -398,13 +438,13 @@ contract OnRamp_forwardFromRouter is OnRampSetup { s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } - function test_CannotSendZeroTokens_Revert() public { + function test_MultiCannotSendZeroTokens_Revert() public { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); message.tokenAmounts = new Client.EVMTokenAmount[](1); message.tokenAmounts[0].amount = 0; message.tokenAmounts[0].token = s_sourceTokens[0]; vm.expectRevert(OnRamp.CannotSendZeroTokens.selector); - s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, STRANGER); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); } function test_UnsupportedToken_Revert() public { @@ -602,7 +642,8 @@ contract OnRamp_setDynamicConfig is OnRampSetup { OnRamp.DynamicConfig memory newConfig = OnRamp.DynamicConfig({ feeQuoter: address(23423), messageValidator: makeAddr("messageValidator"), - feeAggregator: FEE_AGGREGATOR + feeAggregator: FEE_AGGREGATOR, + allowListAdmin: address(0) }); vm.expectEmit(); @@ -620,7 +661,8 @@ contract OnRamp_setDynamicConfig is OnRampSetup { OnRamp.DynamicConfig memory newConfig = OnRamp.DynamicConfig({ feeQuoter: address(0), feeAggregator: FEE_AGGREGATOR, - messageValidator: makeAddr("messageValidator") + messageValidator: makeAddr("messageValidator"), + allowListAdmin: address(0) }); vm.expectRevert(OnRamp.InvalidConfig.selector); @@ -628,8 +670,12 @@ contract OnRamp_setDynamicConfig is OnRampSetup { } function test_SetConfigInvalidConfig_Revert() public { - OnRamp.DynamicConfig memory newConfig = - OnRamp.DynamicConfig({feeQuoter: address(23423), messageValidator: address(0), feeAggregator: FEE_AGGREGATOR}); + OnRamp.DynamicConfig memory newConfig = OnRamp.DynamicConfig({ + feeQuoter: address(23423), + messageValidator: address(0), + feeAggregator: FEE_AGGREGATOR, + allowListAdmin: address(0) + }); // Invalid price reg reverts. newConfig.feeQuoter = address(0); @@ -638,8 +684,13 @@ contract OnRamp_setDynamicConfig is OnRampSetup { } function test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() public { - OnRamp.DynamicConfig memory newConfig = - OnRamp.DynamicConfig({feeQuoter: address(23423), messageValidator: address(0), feeAggregator: address(0)}); + OnRamp.DynamicConfig memory newConfig = OnRamp.DynamicConfig({ + feeQuoter: address(23423), + messageValidator: address(0), + feeAggregator: address(0), + allowListAdmin: address(0) + }); + vm.expectRevert(OnRamp.InvalidConfig.selector); s_onRamp.setDynamicConfig(newConfig); } @@ -740,7 +791,7 @@ contract OnRamp_applyDestChainConfigUpdates is OnRampSetup { // supports disabling a lane by setting a router to zero vm.expectEmit(); - emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, OnRamp.DestChainConfig(0, IRouter(address(0)))); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, 0, IRouter(address(0)), false); s_onRamp.applyDestChainConfigUpdates(configArgs); assertEq(address(0), address(s_onRamp.getRouter(DEST_CHAIN_SELECTOR))); @@ -749,9 +800,9 @@ contract OnRamp_applyDestChainConfigUpdates is OnRampSetup { configArgs[0] = OnRamp.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, router: s_sourceRouter}); configArgs[1] = OnRamp.DestChainConfigArgs({destChainSelector: 9999, router: IRouter(address(9999))}); vm.expectEmit(); - emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, OnRamp.DestChainConfig(0, s_sourceRouter)); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, 0, s_sourceRouter, false); vm.expectEmit(); - emit OnRamp.DestChainConfigSet(9999, OnRamp.DestChainConfig(0, IRouter(address(9999)))); + emit OnRamp.DestChainConfigSet(9999, 0, IRouter(address(9999)), false); s_onRamp.applyDestChainConfigUpdates(configArgs); assertEq(address(s_sourceRouter), address(s_onRamp.getRouter(DEST_CHAIN_SELECTOR))); assertEq(address(9999), address(s_onRamp.getRouter(9999))); @@ -763,7 +814,7 @@ contract OnRamp_applyDestChainConfigUpdates is OnRampSetup { assertEq(numLogs, vm.getRecordedLogs().length); // indicates no changes made } - function test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() external { + function test_ApplyDestChainConfigUpdates_WithInvalidChainSelector_Revert() external { vm.stopPrank(); vm.startPrank(OWNER); OnRamp.DestChainConfigArgs[] memory configArgs = new OnRamp.DestChainConfigArgs[](1); @@ -772,3 +823,141 @@ contract OnRamp_applyDestChainConfigUpdates is OnRampSetup { s_onRamp.applyDestChainConfigUpdates(configArgs); } } + +contract OnRamp_allowListConfigUpdates is OnRampSetup { + function test_applyAllowList_Success() public { + vm.stopPrank(); + vm.startPrank(OWNER); + + OnRamp.DestChainConfigArgs[] memory configArgs = new OnRamp.DestChainConfigArgs[](2); + configArgs[0] = OnRamp.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, router: s_sourceRouter}); + configArgs[1] = OnRamp.DestChainConfigArgs({destChainSelector: 9999, router: IRouter(address(9999))}); + vm.expectEmit(); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, 0, s_sourceRouter, false); + vm.expectEmit(); + emit OnRamp.DestChainConfigSet(9999, 0, IRouter(address(9999)), false); + s_onRamp.applyDestChainConfigUpdates(configArgs); + + (uint64 sequenceNumber, bool allowListEnabled, address router) = s_onRamp.getDestChainConfig(9999); + assertEq(sequenceNumber, 0); + assertEq(allowListEnabled, false); + assertEq(router, address(9999)); + + uint64[] memory destinationChainSelectors = new uint64[](2); + destinationChainSelectors[0] = DEST_CHAIN_SELECTOR; + destinationChainSelectors[1] = uint64(99999); + + address[] memory addedAllowlistedSenders = new address[](4); + addedAllowlistedSenders[0] = vm.addr(1); + addedAllowlistedSenders[1] = vm.addr(2); + addedAllowlistedSenders[2] = vm.addr(3); + addedAllowlistedSenders[3] = vm.addr(4); + + vm.expectEmit(); + emit OnRamp.AllowListSendersAdded(DEST_CHAIN_SELECTOR, addedAllowlistedSenders); + + OnRamp.AllowListConfigArgs memory allowListConfigArgs = OnRamp.AllowListConfigArgs({ + allowListEnabled: true, + destChainSelector: DEST_CHAIN_SELECTOR, + addedAllowlistedSenders: addedAllowlistedSenders, + removedAllowlistedSenders: new address[](0) + }); + + OnRamp.AllowListConfigArgs[] memory applyAllowListConfigArgsItems = new OnRamp.AllowListConfigArgs[](1); + applyAllowListConfigArgsItems[0] = allowListConfigArgs; + + s_onRamp.applyAllowListUpdates(applyAllowListConfigArgsItems); + assertEq(4, s_onRamp.getAllowedSendersList(DEST_CHAIN_SELECTOR).length); + + assertEq(addedAllowlistedSenders, s_onRamp.getAllowedSendersList(DEST_CHAIN_SELECTOR)); + + address[] memory removedAllowlistedSenders = new address[](1); + removedAllowlistedSenders[0] = vm.addr(2); + + vm.expectEmit(); + emit OnRamp.AllowListSendersRemoved(DEST_CHAIN_SELECTOR, removedAllowlistedSenders); + + allowListConfigArgs = OnRamp.AllowListConfigArgs({ + allowListEnabled: true, + destChainSelector: DEST_CHAIN_SELECTOR, + addedAllowlistedSenders: new address[](0), + removedAllowlistedSenders: removedAllowlistedSenders + }); + + OnRamp.AllowListConfigArgs[] memory allowListConfigArgsItems_2 = new OnRamp.AllowListConfigArgs[](1); + allowListConfigArgsItems_2[0] = allowListConfigArgs; + + s_onRamp.applyAllowListUpdates(allowListConfigArgsItems_2); + assertEq(3, s_onRamp.getAllowedSendersList(DEST_CHAIN_SELECTOR).length); + + addedAllowlistedSenders = new address[](2); + addedAllowlistedSenders[0] = vm.addr(5); + addedAllowlistedSenders[1] = vm.addr(6); + + removedAllowlistedSenders = new address[](2); + removedAllowlistedSenders[0] = vm.addr(1); + removedAllowlistedSenders[1] = vm.addr(3); + + vm.expectEmit(); + emit OnRamp.AllowListSendersAdded(DEST_CHAIN_SELECTOR, addedAllowlistedSenders); + emit OnRamp.AllowListSendersRemoved(DEST_CHAIN_SELECTOR, removedAllowlistedSenders); + + allowListConfigArgs = OnRamp.AllowListConfigArgs({ + allowListEnabled: true, + destChainSelector: DEST_CHAIN_SELECTOR, + addedAllowlistedSenders: addedAllowlistedSenders, + removedAllowlistedSenders: removedAllowlistedSenders + }); + + OnRamp.AllowListConfigArgs[] memory allowListConfigArgsItems_3 = new OnRamp.AllowListConfigArgs[](1); + allowListConfigArgsItems_3[0] = allowListConfigArgs; + + s_onRamp.applyAllowListUpdates(allowListConfigArgsItems_3); + assertEq(3, s_onRamp.getAllowedSendersList(DEST_CHAIN_SELECTOR).length); + } + + function test_applyAllowList_Revert() public { + vm.stopPrank(); + vm.startPrank(OWNER); + + OnRamp.DestChainConfigArgs[] memory configArgs = new OnRamp.DestChainConfigArgs[](2); + configArgs[0] = OnRamp.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, router: s_sourceRouter}); + configArgs[1] = OnRamp.DestChainConfigArgs({destChainSelector: 9999, router: IRouter(address(9999))}); + vm.expectEmit(); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, 0, s_sourceRouter, false); + vm.expectEmit(); + emit OnRamp.DestChainConfigSet(9999, 0, IRouter(address(9999)), false); + s_onRamp.applyDestChainConfigUpdates(configArgs); + + uint64[] memory destinationChainSelectors = new uint64[](2); + destinationChainSelectors[0] = DEST_CHAIN_SELECTOR; + destinationChainSelectors[1] = uint64(99999); + + address[] memory addedAllowlistedSenders = new address[](4); + addedAllowlistedSenders[0] = vm.addr(1); + addedAllowlistedSenders[1] = vm.addr(2); + addedAllowlistedSenders[2] = vm.addr(3); + addedAllowlistedSenders[3] = vm.addr(4); + + OnRamp.AllowListConfigArgs memory allowListConfigArgs = OnRamp.AllowListConfigArgs({ + allowListEnabled: true, + destChainSelector: DEST_CHAIN_SELECTOR, + addedAllowlistedSenders: addedAllowlistedSenders, + removedAllowlistedSenders: new address[](0) + }); + + OnRamp.AllowListConfigArgs[] memory applyAllowListConfigArgsItems = new OnRamp.AllowListConfigArgs[](1); + applyAllowListConfigArgsItems[0] = allowListConfigArgs; + + vm.startPrank(STRANGER); + vm.expectRevert(OnRamp.OnlyCallableByOwnerOrAllowlistAdmin.selector); + s_onRamp.applyAllowListUpdates(applyAllowListConfigArgsItems); + vm.stopPrank(); + + applyAllowListConfigArgsItems[0].addedAllowlistedSenders[0] = address(0); + vm.expectRevert(abi.encodeWithSelector(OnRamp.InvalidAllowListRequest.selector, DEST_CHAIN_SELECTOR)); + vm.startPrank(OWNER); + s_onRamp.applyAllowListUpdates(applyAllowListConfigArgsItems); + vm.stopPrank(); + } +} diff --git a/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol index 635a75c843..f43bce6a99 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol @@ -85,7 +85,12 @@ contract OnRampSetup is FeeQuoterFeeSetup { } function _generateDynamicOnRampConfig(address feeQuoter) internal pure returns (OnRamp.DynamicConfig memory) { - return OnRamp.DynamicConfig({feeQuoter: feeQuoter, messageValidator: address(0), feeAggregator: FEE_AGGREGATOR}); + return OnRamp.DynamicConfig({ + feeQuoter: feeQuoter, + messageValidator: address(0), + feeAggregator: FEE_AGGREGATOR, + allowListAdmin: address(0) + }); } // Slicing is only available for calldata. So we have to build a new bytes array. diff --git a/core/gethwrappers/ccip/generated/onramp/onramp.go b/core/gethwrappers/ccip/generated/onramp/onramp.go index db21305dc8..dd2428a143 100644 --- a/core/gethwrappers/ccip/generated/onramp/onramp.go +++ b/core/gethwrappers/ccip/generated/onramp/onramp.go @@ -70,9 +70,11 @@ type InternalRampTokenAmount struct { DestExecData []byte } -type OnRampDestChainConfig struct { - SequenceNumber uint64 - Router common.Address +type OnRampAllowListConfigArgs struct { + DestChainSelector uint64 + AllowListEnabled bool + AddedAllowlistedSenders []common.Address + RemovedAllowlistedSenders []common.Address } type OnRampDestChainConfigArgs struct { @@ -84,6 +86,7 @@ type OnRampDynamicConfig struct { FeeQuoter common.Address MessageValidator common.Address FeeAggregator common.Address + AllowListAdmin common.Address } type OnRampStaticConfig struct { @@ -94,8 +97,8 @@ type OnRampStaticConfig struct { } var OnRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b506040516200382d3803806200382d83398101604081905262000035916200069c565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000186565b505083516001600160401b031615905080620000e6575060208301516001600160a01b0316155b80620000fd575060408301516001600160a01b0316155b8062000114575060608301516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b82516001600160401b031660805260208301516001600160a01b0390811660a0526040840151811660c05260608401511660e052620001728262000231565b6200017d816200036d565b5050506200079c565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316158062000254575060408101516001600160a01b0316155b1562000273576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b03938416179091556020808401805160038054851691861691909117905560408086018051600480549096169087161790945580516080808201835280516001600160401b031680835260a08051891684880190815260c080518b1686880190815260e080518d166060988901908152895196875293518d169a86019a909a52518b169684019690965251891693820193909352885188169181019190915292518616908301529251909316918301919091527f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558910160405180910390a150565b60005b8151811015620004aa57600082828151811062000391576200039162000786565b602002602001015190506000838381518110620003b257620003b262000786565b6020026020010151600001519050806001600160401b0316600003620003f75760405163c35aa79d60e01b81526001600160401b038216600482015260240162000083565b6040805180820182526001600160401b03838116600081815260056020818152868320805480871688528a8301516001600160a01b03908116848a019081529587905293835287518551851668010000000000000000026001600160e01b0319909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a250505080600101905062000370565b5050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620004e957620004e9620004ae565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200051a576200051a620004ae565b604052919050565b80516001600160401b03811681146200053a57600080fd5b919050565b6001600160a01b03811681146200055557600080fd5b50565b6000606082840312156200056b57600080fd5b604051606081016001600160401b0381118282101715620005905762000590620004ae565b80604052508091508251620005a5816200053f565b81526020830151620005b7816200053f565b60208201526040830151620005cc816200053f565b6040919091015292915050565b600082601f830112620005eb57600080fd5b815160206001600160401b03821115620006095762000609620004ae565b62000619818360051b01620004ef565b82815260069290921b840181019181810190868411156200063957600080fd5b8286015b84811015620006915760408189031215620006585760008081fd5b62000662620004c4565b6200066d8262000522565b8152848201516200067e816200053f565b818601528352918301916040016200063d565b509695505050505050565b6000806000838503610100811215620006b457600080fd5b6080811215620006c357600080fd5b50604051608081016001600160401b038082118383101715620006ea57620006ea620004ae565b81604052620006f98762000522565b8352602087015191506200070d826200053f565b8160208401526040870151915062000725826200053f565b816040840152606087015191506200073d826200053f565b81606084015282955062000755886080890162000558565b945060e08701519250808311156200076c57600080fd5b50506200077c86828701620005d9565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e05161301862000815600039600081816101eb015281816108a201526116700152600081816101af01528181610dc60152611649015260008181610173015281816104c4015261161f01526000818161014301528181610cec0152818161121101526115f201526130186000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637437ff9f11610097578063d77d5ed011610066578063d77d5ed0146103ba578063df0aa9e914610406578063f2fde38b14610419578063fbca3b741461042c57600080fd5b80637437ff9f146102fb57806379ba5097146103685780638da5cb5b146103705780639041be3d1461038e57600080fd5b806320487ded116100d357806320487ded1461028757806334d560e4146102a85780633a019940146102bb57806348a98aa4146102c357600080fd5b80630242cf60146100fa57806306285c691461010f578063181f5a771461023e575b600080fd5b61010d610108366004612098565b61044c565b005b61022860408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b604051610235919061215b565b60405180910390f35b61027a6040518060400160405280601081526020017f4f6e52616d7020312e362e302d6465760000000000000000000000000000000081525081565b6040516102359190612220565b61029a61029536600461224b565b610460565b604051908152602001610235565b61010d6102b63660046122ab565b610619565b61010d61062a565b6102d66102d136600461231d565b61085a565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610235565b61035b6040805160608101825260008082526020820181905291810191909152506040805160608101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454169181019190915290565b6040516102359190612356565b61010d61090f565b60005473ffffffffffffffffffffffffffffffffffffffff166102d6565b6103a161039c366004612393565b610a0c565b60405167ffffffffffffffff9091168152602001610235565b6102d66103c8366004612393565b67ffffffffffffffff1660009081526005602052604090205468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b61029a6104143660046123b0565b610a35565b61010d61042736600461241c565b6112c6565b61043f61043a366004612393565b6112d7565b6040516102359190612439565b61045461130b565b61045d8161138e565b50565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561050b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052f91906124a3565b15610577576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6002546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd906105cf90869086906004016125d2565b602060405180830381865afa1580156105ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610610919061271b565b90505b92915050565b61062161130b565b61045d81611506565b600254604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610699573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106df9190810190612734565b60045490915073ffffffffffffffffffffffffffffffffffffffff1660005b825181101561085557600083828151811061071b5761071b6127c3565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610796573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ba919061271b565b9050801561084b576107e373ffffffffffffffffffffffffffffffffffffffff831685836116d0565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e8360405161084291815260200190565b60405180910390a35b50506001016106fe565b505050565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa1580156108eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061091906127f2565b60015473ffffffffffffffffffffffffffffffffffffffff163314610990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161056e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff80821660009081526005602052604081205490916106139116600161283e565b67ffffffffffffffff8416600090815260056020526040812073ffffffffffffffffffffffffffffffffffffffff8316610a9b576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610af7576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035473ffffffffffffffffffffffffffffffffffffffff168015610b9d576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610b6a908a908a906004016125d2565b600060405180830381600087803b158015610b8457600080fd5b505af1158015610b98573d6000803e3d6000fd5b505050505b506002546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a610bd460808c0160608d0161241c565b8a610be260808e018e612866565b6040518663ffffffff1660e01b8152600401610c029594939291906128cb565b600060405180830381865afa158015610c1f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c659190810190612993565b91945092509050610c7c6080890160608a0161241c565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f84604051610cc391815260200190565b60405180910390a2604080516101a081019091526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528c811661014085015287549293928392916101608401918a918791610d3891166129ea565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200186610e38576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e339190612a11565b610e3b565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a8060200190610e799190612866565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610ebd8b80612866565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f0460808c018c612866565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f4e60808c0160608d0161241c565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190610f7f9190612a2e565b905067ffffffffffffffff811115610f9957610f99611f95565b604051908082528060200260200182016040528015610ffc57816020015b610fe96040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b815260200190600190039081610fb75790505b509052905060005b61101160408b018b612a2e565b90508110156110c05761109761102a60408c018c612a2e565b8381811061103a5761103a6127c3565b9050604002018036038101906110509190612a96565b8c61105b8d80612866565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e925061175d915050565b8260e0015182815181106110ad576110ad6127c3565b6020908102919091010152600101611004565b5060025460e082015160009173ffffffffffffffffffffffffffffffffffffffff169063085318f8908d906110f860408f018f612a2e565b6040518563ffffffff1660e01b81526004016111179493929190612bad565b600060405180830381865afa158015611134573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261117a9190810190612be3565b905060005b8260e00151518110156111d35781818151811061119e5761119e6127c3565b60200260200101518360e0015182815181106111bc576111bc6127c3565b60209081029190910101516080015260010161117f565b506080808301849052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908d166060820152309181019190915261126d90839060a00160405160208183030381529060405280519060200120611a83565b82515260405167ffffffffffffffff8c16907fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140906112ac908590612c94565b60405180910390a25051519450505050505b949350505050565b6112ce61130b565b61045d81611b83565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461138c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161056e565b565b60005b81518110156115025760008282815181106113ae576113ae6127c3565b6020026020010151905060008383815181106113cc576113cc6127c3565b60200260200101516000015190508067ffffffffffffffff1660000361142a576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161056e565b60408051808201825267ffffffffffffffff838116600081815260056020818152868320805480871688528a83015173ffffffffffffffffffffffffffffffffffffffff908116848a019081529587905293835287518551851668010000000000000000027fffffffff00000000000000000000000000000000000000000000000000000000909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a2505050806001019050611391565b5050565b805173ffffffffffffffffffffffffffffffffffffffff1615806115425750604081015173ffffffffffffffffffffffffffffffffffffffff16155b15611579576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480549094169085161790925581516080810183527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008416918101919091527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558916116c5918490612de2565b60405180910390a150565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610855908490611c78565b61178f6040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b84602001516000036117cd576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006117dd85876000015161085a565b905073ffffffffffffffffffffffffffffffffffffffff811615806118ad57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015611887573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ab91906124a3565b155b156118ff5785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161056e565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b815260040161199e9190612e74565b6000604051808303816000875af11580156119bd573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611a039190810190612eea565b6040805160a0810190915273ffffffffffffffffffffffffffffffffffffffff841660c08201529091508060e0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181526020016040518060200160405280600081525081525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c00151604051602001611ac596959493929190612f7b565b604051602081830303815290604052805190602001208560400151805190602001208660e00151604051602001611afc9190612fdc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611c02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161056e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611cda826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611d849092919063ffffffff16565b8051909150156108555780806020019051810190611cf891906124a3565b610855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161056e565b6060611d938484600085611d9d565b90505b9392505050565b606082471015611e2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161056e565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611e589190612fef565b60006040518083038185875af1925050503d8060008114611e95576040519150601f19603f3d011682016040523d82523d6000602084013e611e9a565b606091505b5091509150611eab87838387611eb6565b979650505050505050565b60608315611f4c578251600003611f455773ffffffffffffffffffffffffffffffffffffffff85163b611f45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161056e565b50816112be565b6112be8383815115611f615781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056e9190612220565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611fe757611fe7611f95565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561203457612034611f95565b604052919050565b600067ffffffffffffffff82111561205657612056611f95565b5060051b60200190565b67ffffffffffffffff8116811461045d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461045d57600080fd5b600060208083850312156120ab57600080fd5b823567ffffffffffffffff8111156120c257600080fd5b8301601f810185136120d357600080fd5b80356120e66120e18261203c565b611fed565b81815260069190911b8201830190838101908783111561210557600080fd5b928401925b82841015611eab57604084890312156121235760008081fd5b61212b611fc4565b843561213681612060565b81528486013561214581612076565b818701528252604093909301929084019061210a565b60808101610613828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b838110156121cd5781810151838201526020016121b5565b50506000910152565b600081518084526121ee8160208601602086016121b2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061061060208301846121d6565b600060a0828403121561224557600080fd5b50919050565b6000806040838503121561225e57600080fd5b823561226981612060565b9150602083013567ffffffffffffffff81111561228557600080fd5b61229185828601612233565b9150509250929050565b80356122a681612076565b919050565b6000606082840312156122bd57600080fd5b6040516060810181811067ffffffffffffffff821117156122e0576122e0611f95565b60405282356122ee81612076565b815260208301356122fe81612076565b6020820152604083013561231181612076565b60408201529392505050565b6000806040838503121561233057600080fd5b823561233b81612060565b9150602083013561234b81612076565b809150509250929050565b606081016106138284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260409182015116910152565b6000602082840312156123a557600080fd5b8135611d9681612060565b600080600080608085870312156123c657600080fd5b84356123d181612060565b9350602085013567ffffffffffffffff8111156123ed57600080fd5b6123f987828801612233565b93505060408501359150606085013561241181612076565b939692955090935050565b60006020828403121561242e57600080fd5b8135611d9681612076565b6020808252825182820181905260009190848201906040850190845b8181101561248757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612455565b50909695505050505050565b805180151581146122a657600080fd5b6000602082840312156124b557600080fd5b61061082612493565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126124f357600080fd5b830160208101925035905067ffffffffffffffff81111561251357600080fd5b80360382131561252257600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156125c757813561259581612076565b73ffffffffffffffffffffffffffffffffffffffff168752818301358388015260409687019690910190600101612582565b509495945050505050565b600067ffffffffffffffff8085168352604060208401526125f384856124be565b60a0604086015261260860e086018284612529565b91505061261860208601866124be565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087850301606088015261264e848385612529565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe188360301831261268757600080fd5b602092880192830192359150848211156126a057600080fd5b8160061b36038313156126b257600080fd5b808785030160808801526126c7848385612572565b94506126d56060890161229b565b73ffffffffffffffffffffffffffffffffffffffff811660a0890152935061270060808901896124be565b94509250808786030160c08801525050611eab838383612529565b60006020828403121561272d57600080fd5b5051919050565b6000602080838503121561274757600080fd5b825167ffffffffffffffff81111561275e57600080fd5b8301601f8101851361276f57600080fd5b805161277d6120e18261203c565b81815260059190911b8201830190838101908783111561279c57600080fd5b928401925b82841015611eab5783516127b481612076565b825292840192908401906127a1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561280457600080fd5b8151611d9681612076565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561285f5761285f61280f565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261289b57600080fd5b83018035915067ffffffffffffffff8211156128b657600080fd5b60200191503681900382131561252257600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152608060608201526000611eab608083018486612529565b600082601f83011261292257600080fd5b815167ffffffffffffffff81111561293c5761293c611f95565b61296d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611fed565b81815284602083860101111561298257600080fd5b6112be8260208301602087016121b2565b6000806000606084860312156129a857600080fd5b835192506129b860208501612493565b9150604084015167ffffffffffffffff8111156129d457600080fd5b6129e086828701612911565b9150509250925092565b600067ffffffffffffffff808316818103612a0757612a0761280f565b6001019392505050565b600060208284031215612a2357600080fd5b8151611d9681612060565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612a6357600080fd5b83018035915067ffffffffffffffff821115612a7e57600080fd5b6020019150600681901b360382131561252257600080fd5b600060408284031215612aa857600080fd5b612ab0611fc4565b8235612abb81612076565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b84811015612ba0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160a08151818652612b31828701826121d6565b9150508582015185820387870152612b4982826121d6565b91505060408083015186830382880152612b6383826121d6565b92505050606080830151818701525060808083015192508582038187015250612b8c81836121d6565b9a86019a9450505090830190600101612aed565b5090979650505050505050565b67ffffffffffffffff85168152606060208201526000612bd06060830186612ad0565b8281036040840152611eab818587612572565b60006020808385031215612bf657600080fd5b825167ffffffffffffffff80821115612c0e57600080fd5b818501915085601f830112612c2257600080fd5b8151612c306120e18261203c565b81815260059190911b83018401908481019088831115612c4f57600080fd5b8585015b83811015612c8757805185811115612c6b5760008081fd5b612c798b89838a0101612911565b845250918601918601612c53565b5098975050505050505050565b60208152612ce560208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b60006020830151612d0e60c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e0850152612d2b6101a08501836121d6565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301610100870152612d6884836121d6565b9350608087015191508086850301610120870152612d8684836121d6565b935060a08701519150612db261014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e0870151915080868503018387015250612dd88382612ad0565b9695505050505050565b60e08101612e39828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a084015260408401511660c0830152611d96565b602081526000825160a06020840152612e9060c08401826121d6565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600060208284031215612efc57600080fd5b815167ffffffffffffffff80821115612f1457600080fd5b9083019060408286031215612f2857600080fd5b612f30611fc4565b825182811115612f3f57600080fd5b612f4b87828601612911565b825250602083015182811115612f6057600080fd5b612f6c87828601612911565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c06020840152612fab60c08401896121d6565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b6020815260006106106020830184612ad0565b600082516130018184602087016121b2565b919091019291505056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidAllowListRequest\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAllowlistAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"name\":\"AllowListAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"senders\",\"type\":\"address[]\"}],\"name\":\"AllowListSendersAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"senders\",\"type\":\"address[]\"}],\"name\":\"AllowListSendersRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowListEnabled\",\"type\":\"bool\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowListEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"addedAllowlistedSenders\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedAllowlistedSenders\",\"type\":\"address[]\"}],\"internalType\":\"structOnRamp.AllowListConfigArgs[]\",\"name\":\"allowListConfigArgsItems\",\"type\":\"tuple[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowListEnabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b506040516200407338038062004073833981016040819052620000359162000665565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000186565b505083516001600160401b031615905080620000e6575060208301516001600160a01b0316155b80620000fd575060408301516001600160a01b0316155b8062000114575060608301516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b82516001600160401b031660805260208301516001600160a01b0390811660a0526040840151811660c05260608401511660e052620001728262000231565b6200017d8162000390565b5050506200079f565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316158062000254575060408101516001600160a01b0316155b1562000273576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b0393841617909155602080840180516003805485169186169190911790556040808601805160048054871691881691909117905560608088018051600580549098169089161790965582516080808201855280516001600160401b031680835260a080518b16848a0190815260c080518d16868a0190815260e080518f169789019788528a5195865292518e169b85019b909b5299518c169783019790975292518a169381019390935289518916908301529351871693810193909352518516928201929092529151909216918101919091527f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32906101000160405180910390a150565b60005b8151811015620004cf576000828281518110620003b457620003b462000789565b602002602001015190506000838381518110620003d557620003d562000789565b6020026020010151600001519050806001600160401b03166000036200041a5760405163c35aa79d60e01b81526001600160401b038216600482015260240162000083565b6001600160401b03818116600081815260066020908152604091829020868201518154600160481b600160e81b0319811669010000000000000000006001600160a01b03909316928302908117808555865192891691909816178152928301526801000000000000000090940460ff161515918101919091527fd5ad72bc37dc7a80a8b9b9df20500046fd7341adb1be2258a540466fdd7dcef59060600160405180910390a250505080600101905062000393565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156200050e576200050e620004d3565b60405290565b604080519081016001600160401b03811182821017156200050e576200050e620004d3565b604051601f8201601f191681016001600160401b0381118282101715620005645762000564620004d3565b604052919050565b80516001600160401b03811681146200058457600080fd5b919050565b6001600160a01b03811681146200059f57600080fd5b50565b600082601f830112620005b457600080fd5b815160206001600160401b03821115620005d257620005d2620004d3565b620005e2818360051b0162000539565b82815260069290921b840181019181810190868411156200060257600080fd5b8286015b848110156200065a5760408189031215620006215760008081fd5b6200062b62000514565b62000636826200056c565b815284820151620006478162000589565b8186015283529183019160400162000606565b509695505050505050565b60008060008385036101208112156200067d57600080fd5b60808112156200068c57600080fd5b62000696620004e9565b620006a1866200056c565b81526020860151620006b38162000589565b60208201526040860151620006c88162000589565b60408201526060860151620006dd8162000589565b606082015293506080607f1982011215620006f757600080fd5b5062000702620004e9565b6080850151620007128162000589565b815260a0850151620007248162000589565b602082015260c0850151620007398162000589565b604082015260e08501516200074e8162000589565b60608201526101008501519092506001600160401b038111156200077157600080fd5b6200077f86828701620005a2565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e05161385b620008186000396000818161022c01528181610c790152611beb0152600081816101f0015281816112480152611bc40152600081816101b4015281816105de0152611b9a0152600081816101840152818161116e015281816116930152611b6d015261385b6000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c806379ba5097116100b2578063a6f3ab6c11610081578063df0aa9e911610066578063df0aa9e91461052d578063f2fde38b14610540578063fbca3b741461055357600080fd5b8063a6f3ab6c146104cd578063d77d5ed0146104e057600080fd5b806379ba50971461045b5780638da5cb5b146104635780639041be3d14610481578063972b4612146104ad57600080fd5b806334adf4941161010957806348a98aa4116100ee57806348a98aa4146103045780636def4ce71461033c5780637437ff9f146103db57600080fd5b806334adf494146102e95780633a019940146102fc57600080fd5b80630242cf601461013b57806306285c6914610150578063181f5a771461027f57806320487ded146102c8575b600080fd5b61014e6101493660046126e0565b610566565b005b61026960408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161027691906127a3565b60405180910390f35b6102bb6040518060400160405280601081526020017f4f6e52616d7020312e362e302d6465760000000000000000000000000000000081525081565b6040516102769190612868565b6102db6102d6366004612893565b61057a565b604051908152602001610276565b61014e6102f73660046128e3565b610733565b61014e610a06565b610317610312366004612958565b610c31565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610276565b61039f61034a366004612991565b67ffffffffffffffff9081166000908152600660205260409020549081169168010000000000000000820460ff16916901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b6040805167ffffffffffffffff9094168452911515602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610276565b61044e604080516080810182526000808252602082018190529181018290526060810191909152506040805160808101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454811692820192909252600554909116606082015290565b60405161027691906129ae565b61014e610ce6565b60005473ffffffffffffffffffffffffffffffffffffffff16610317565b61049461048f366004612991565b610de3565b60405167ffffffffffffffff9091168152602001610276565b6104c06104bb366004612991565b610e0c565b60405161027691906129f7565b61014e6104db366004612a61565b610e34565b6103176104ee366004612991565b67ffffffffffffffff166000908152600660205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b6102db61053b366004612ac8565b610e45565b61014e61054e366004612b34565b611748565b6104c0610561366004612991565b611759565b61056e61178d565b61057781611810565b50565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa158015610625573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106499190612b5f565b15610691576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6002546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd906106e99086908690600401612c90565b602060405180830381865afa158015610706573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072a9190612dd9565b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107a35760055473ffffffffffffffffffffffffffffffffffffffff1633146107a3576040517f905d7d9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610a015760008383838181106107c2576107c2612df2565b90506020028101906107d49190612e21565b6107dd90612ed2565b805167ffffffffffffffff1660009081526006602090815260409091209082015181547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000009115801592909202178255919250906109545760005b8260400151518110156108fd5760008360400151828151811061086757610867612df2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036108e65783516040517f463258ff00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610688565b6108f36001840182611987565b5050600101610842565b506040820151511561095457816000015167ffffffffffffffff167f330939f6eafe8bb516716892fe962ff19770570838686e6579dbc1cc51fc3281836040015160405161094b91906129f7565b60405180910390a25b60005b8260600151518110156109a0576109978360600151828151811061097d5761097d612df2565b6020026020010151836001016119a990919063ffffffff16565b50600101610957565b50606082015151156109f757816000015167ffffffffffffffff167fc237ec1921f855ccd5e9a5af9733f2d58943a5a8501ec5988e305d7a4d42158683606001516040516109ee91906129f7565b60405180910390a25b50506001016107a6565b505050565b600254604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610a75573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610abb9190810190612f65565b60045490915073ffffffffffffffffffffffffffffffffffffffff1660005b8251811015610a01576000838281518110610af757610af7612df2565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610b72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b969190612dd9565b90508015610c2757610bbf73ffffffffffffffffffffffffffffffffffffffff831685836119cb565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e83604051610c1e91815260200190565b60405180910390a35b5050600101610ada565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610cc2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072a9190612ff4565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610688565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff808216600090815260066020526040812054909161072d91166001613040565b67ffffffffffffffff8116600090815260066020526040902060609061072d90600101611a58565b610e3c61178d565b61057781611a6c565b67ffffffffffffffff8416600090815260066020526040812073ffffffffffffffffffffffffffffffffffffffff8316610eab576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805468010000000000000000900460ff1615610f1c57610ece6001820184611c4e565b610f1c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610688565b80546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610f79576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035473ffffffffffffffffffffffffffffffffffffffff16801561101f576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610fec908a908a90600401612c90565b600060405180830381600087803b15801561100657600080fd5b505af115801561101a573d6000803e3d6000fd5b505050505b506002546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a61105660808c0160608d01612b34565b8a61106460808e018e613061565b6040518663ffffffff1660e01b81526004016110849594939291906130c6565b600060405180830381865afa1580156110a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110e7919081019061318e565b919450925090506110fe6080890160608a01612b34565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f8460405161114591815260200190565b60405180910390a2604080516101a081019091526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528c811661014085015287549293928392916101608401918a9187916111ba91166131e8565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff168152602001866112ba576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015611291573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b5919061320f565b6112bd565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a80602001906112fb9190613061565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200161133f8b80613061565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200161138660808c018c613061565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050908252506020016113d060808c0160608d01612b34565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190611401919061322c565b905067ffffffffffffffff81111561141b5761141b6125ba565b60405190808252806020026020018201604052801561147e57816020015b61146b6040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b8152602001906001900390816114395790505b509052905060005b61149360408b018b61322c565b9050811015611542576115196114ac60408c018c61322c565b838181106114bc576114bc612df2565b9050604002018036038101906114d29190613294565b8c6114dd8d80613061565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e9250611c7d915050565b8260e00151828151811061152f5761152f612df2565b6020908102919091010152600101611486565b5060025460e082015160009173ffffffffffffffffffffffffffffffffffffffff169063085318f8908d9061157a60408f018f61322c565b6040518563ffffffff1660e01b815260040161159994939291906133ab565b600060405180830381865afa1580156115b6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526115fc91908101906133e1565b905060005b8260e00151518110156116555781818151811061162057611620612df2565b60200260200101518360e00151828151811061163e5761163e612df2565b602090810291909101015160800152600101611601565b506080808301849052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908d16606082015230918101919091526116ef90839060a00160405160208183030381529060405280519060200120611fa3565b82515260405167ffffffffffffffff8c16907fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c931409061172e908590613492565b60405180910390a25051519450505050505b949350505050565b61175061178d565b610577816120a3565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461180e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610688565b565b60005b815181101561198357600082828151811061183057611830612df2565b60200260200101519050600083838151811061184e5761184e612df2565b60200260200101516000015190508067ffffffffffffffff166000036118ac576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610688565b67ffffffffffffffff8181166000818152600660209081526040918290208682015181547fffffff0000000000000000000000000000000000000000ffffffffffffffffff8116690100000000000000000073ffffffffffffffffffffffffffffffffffffffff909316928302908117808555865192891691909816178152928301526801000000000000000090940460ff161515918101919091527fd5ad72bc37dc7a80a8b9b9df20500046fd7341adb1be2258a540466fdd7dcef59060600160405180910390a2505050806001019050611813565b5050565b600061072a8373ffffffffffffffffffffffffffffffffffffffff8416612198565b600061072a8373ffffffffffffffffffffffffffffffffffffffff84166121e7565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610a019084906122e1565b60606000611a65836123ed565b9392505050565b805173ffffffffffffffffffffffffffffffffffffffff161580611aa85750604081015173ffffffffffffffffffffffffffffffffffffffff16155b15611adf576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480548516918616919091179055606080860151600580549095169086161790935580516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008516928101929092527f00000000000000000000000000000000000000000000000000000000000000008416828201527f00000000000000000000000000000000000000000000000000000000000000009093169181019190915290517f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e3291611c439184906135e0565b60405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561072a565b611caf6040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b8460200151600003611ced576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611cfd858760000151610c31565b905073ffffffffffffffffffffffffffffffffffffffff81161580611dcd57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015611da7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dcb9190612b5f565b155b15611e1f5785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610688565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401611ebe919061367f565b6000604051808303816000875af1158015611edd573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611f2391908101906136f5565b6040805160a0810190915273ffffffffffffffffffffffffffffffffffffffff841660c08201529091508060e0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181526020016040518060200160405280600081525081525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c00151604051602001611fe596959493929190613786565b604051602081830303815290604052805190602001208560400151805190602001208660e0015160405160200161201c91906137e7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603612122576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610688565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120546121df5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561072d565b50600061072d565b600081815260018301602052604081205480156122d057600061220b6001836137fa565b855490915060009061221f906001906137fa565b905080821461228457600086600001828154811061223f5761223f612df2565b906000526020600020015490508087600001848154811061226257612262612df2565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806122955761229561380d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061072d565b600091505061072d565b5092915050565b6000612343826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166124499092919063ffffffff16565b805190915015610a0157808060200190518101906123619190612b5f565b610a01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610688565b60608160000180548060200260200160405190810160405280929190818152602001828054801561243d57602002820191906000526020600020905b815481526020019060010190808311612429575b50505050509050919050565b60606117408484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161247d919061383c565b60006040518083038185875af1925050503d80600081146124ba576040519150601f19603f3d011682016040523d82523d6000602084013e6124bf565b606091505b50915091506124d0878383876124db565b979650505050505050565b6060831561257157825160000361256a5773ffffffffffffffffffffffffffffffffffffffff85163b61256a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610688565b5081611740565b61174083838151156125865781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106889190612868565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561260c5761260c6125ba565b60405290565b6040516080810167ffffffffffffffff8111828210171561260c5761260c6125ba565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561267c5761267c6125ba565b604052919050565b600067ffffffffffffffff82111561269e5761269e6125ba565b5060051b60200190565b67ffffffffffffffff8116811461057757600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461057757600080fd5b600060208083850312156126f357600080fd5b823567ffffffffffffffff81111561270a57600080fd5b8301601f8101851361271b57600080fd5b803561272e61272982612684565b612635565b81815260069190911b8201830190838101908783111561274d57600080fd5b928401925b828410156124d0576040848903121561276b5760008081fd5b6127736125e9565b843561277e816126a8565b81528486013561278d816126be565b8187015282526040939093019290840190612752565b6080810161072d828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b838110156128155781810151838201526020016127fd565b50506000910152565b600081518084526128368160208601602086016127fa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061072a602083018461281e565b600060a0828403121561288d57600080fd5b50919050565b600080604083850312156128a657600080fd5b82356128b1816126a8565b9150602083013567ffffffffffffffff8111156128cd57600080fd5b6128d98582860161287b565b9150509250929050565b600080602083850312156128f657600080fd5b823567ffffffffffffffff8082111561290e57600080fd5b818501915085601f83011261292257600080fd5b81358181111561293157600080fd5b8660208260051b850101111561294657600080fd5b60209290920196919550909350505050565b6000806040838503121561296b57600080fd5b8235612976816126a8565b91506020830135612986816126be565b809150509250929050565b6000602082840312156129a357600080fd5b8135611a65816126a8565b6080810161072d8284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260408083015182169084015260609182015116910152565b6020808252825182820181905260009190848201906040850190845b81811015612a4557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612a13565b50909695505050505050565b8035612a5c816126be565b919050565b600060808284031215612a7357600080fd5b612a7b612612565b8235612a86816126be565b81526020830135612a96816126be565b60208201526040830135612aa9816126be565b60408201526060830135612abc816126be565b60608201529392505050565b60008060008060808587031215612ade57600080fd5b8435612ae9816126a8565b9350602085013567ffffffffffffffff811115612b0557600080fd5b612b118782880161287b565b935050604085013591506060850135612b29816126be565b939692955090935050565b600060208284031215612b4657600080fd5b8135611a65816126be565b801515811461057757600080fd5b600060208284031215612b7157600080fd5b8151611a6581612b51565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612bb157600080fd5b830160208101925035905067ffffffffffffffff811115612bd157600080fd5b803603821315612be057600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b85811015612c85578135612c53816126be565b73ffffffffffffffffffffffffffffffffffffffff168752818301358388015260409687019690910190600101612c40565b509495945050505050565b600067ffffffffffffffff808516835260406020840152612cb18485612b7c565b60a06040860152612cc660e086018284612be7565b915050612cd66020860186612b7c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080878503016060880152612d0c848385612be7565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1883603018312612d4557600080fd5b60209288019283019235915084821115612d5e57600080fd5b8160061b3603831315612d7057600080fd5b80878503016080880152612d85848385612c30565b9450612d9360608901612a51565b73ffffffffffffffffffffffffffffffffffffffff811660a08901529350612dbe6080890189612b7c565b94509250808786030160c088015250506124d0838383612be7565b600060208284031215612deb57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112612e5557600080fd5b9190910192915050565b600082601f830112612e7057600080fd5b81356020612e8061272983612684565b8083825260208201915060208460051b870101935086841115612ea257600080fd5b602086015b84811015612ec7578035612eba816126be565b8352918301918301612ea7565b509695505050505050565b600060808236031215612ee457600080fd5b612eec612612565b8235612ef7816126a8565b81526020830135612f0781612b51565b6020820152604083013567ffffffffffffffff80821115612f2757600080fd5b612f3336838701612e5f565b60408401526060850135915080821115612f4c57600080fd5b50612f5936828601612e5f565b60608301525092915050565b60006020808385031215612f7857600080fd5b825167ffffffffffffffff811115612f8f57600080fd5b8301601f81018513612fa057600080fd5b8051612fae61272982612684565b81815260059190911b82018301908381019087831115612fcd57600080fd5b928401925b828410156124d0578351612fe5816126be565b82529284019290840190612fd2565b60006020828403121561300657600080fd5b8151611a65816126be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156122da576122da613011565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261309657600080fd5b83018035915067ffffffffffffffff8211156130b157600080fd5b602001915036819003821315612be057600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff851660208201528360408201526080606082015260006124d0608083018486612be7565b600082601f83011261311d57600080fd5b815167ffffffffffffffff811115613137576131376125ba565b61316860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612635565b81815284602083860101111561317d57600080fd5b6117408260208301602087016127fa565b6000806000606084860312156131a357600080fd5b8351925060208401516131b581612b51565b604085015190925067ffffffffffffffff8111156131d257600080fd5b6131de8682870161310c565b9150509250925092565b600067ffffffffffffffff80831681810361320557613205613011565b6001019392505050565b60006020828403121561322157600080fd5b8151611a65816126a8565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261326157600080fd5b83018035915067ffffffffffffffff82111561327c57600080fd5b6020019150600681901b3603821315612be057600080fd5b6000604082840312156132a657600080fd5b6132ae6125e9565b82356132b9816126be565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b8481101561339e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160a0815181865261332f8287018261281e565b9150508582015185820387870152613347828261281e565b91505060408083015186830382880152613361838261281e565b9250505060608083015181870152506080808301519250858203818701525061338a818361281e565b9a86019a94505050908301906001016132eb565b5090979650505050505050565b67ffffffffffffffff851681526060602082015260006133ce60608301866132ce565b82810360408401526124d0818587612c30565b600060208083850312156133f457600080fd5b825167ffffffffffffffff8082111561340c57600080fd5b818501915085601f83011261342057600080fd5b815161342e61272982612684565b81815260059190911b8301840190848101908883111561344d57600080fd5b8585015b83811015613485578051858111156134695760008081fd5b6134778b89838a010161310c565b845250918601918601613451565b5098975050505050505050565b602081526134e360208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b6000602083015161350c60c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e08501526135296101a085018361281e565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301610100870152613566848361281e565b9350608087015191508086850301610120870152613584848361281e565b935060a087015191506135b061014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e08701519150808685030183870152506135d683826132ce565b9695505050505050565b6101008101613638828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a08401526040840151811660c084015260608401511660e0830152611a65565b602081526000825160a0602084015261369b60c084018261281e565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b60006020828403121561370757600080fd5b815167ffffffffffffffff8082111561371f57600080fd5b908301906040828603121561373357600080fd5b61373b6125e9565b82518281111561374a57600080fd5b6137568782860161310c565b82525060208301518281111561376b57600080fd5b6137778782860161310c565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c060208401526137b660c084018961281e565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b60208152600061072a60208301846132ce565b8181038181111561072d5761072d613011565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251612e558184602087016127fa56fea164736f6c6343000818000a", } var OnRampABI = OnRampMetaData.ABI @@ -234,6 +237,59 @@ func (_OnRamp *OnRampTransactorRaw) Transact(opts *bind.TransactOpts, method str return _OnRamp.Contract.contract.Transact(opts, method, params...) } +func (_OnRamp *OnRampCaller) GetAllowedSendersList(opts *bind.CallOpts, destChainSelector uint64) ([]common.Address, error) { + var out []interface{} + err := _OnRamp.contract.Call(opts, &out, "getAllowedSendersList", destChainSelector) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_OnRamp *OnRampSession) GetAllowedSendersList(destChainSelector uint64) ([]common.Address, error) { + return _OnRamp.Contract.GetAllowedSendersList(&_OnRamp.CallOpts, destChainSelector) +} + +func (_OnRamp *OnRampCallerSession) GetAllowedSendersList(destChainSelector uint64) ([]common.Address, error) { + return _OnRamp.Contract.GetAllowedSendersList(&_OnRamp.CallOpts, destChainSelector) +} + +func (_OnRamp *OnRampCaller) GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (GetDestChainConfig, + + error) { + var out []interface{} + err := _OnRamp.contract.Call(opts, &out, "getDestChainConfig", destChainSelector) + + outstruct := new(GetDestChainConfig) + if err != nil { + return *outstruct, err + } + + outstruct.SequenceNumber = *abi.ConvertType(out[0], new(uint64)).(*uint64) + outstruct.AllowListEnabled = *abi.ConvertType(out[1], new(bool)).(*bool) + outstruct.Router = *abi.ConvertType(out[2], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +func (_OnRamp *OnRampSession) GetDestChainConfig(destChainSelector uint64) (GetDestChainConfig, + + error) { + return _OnRamp.Contract.GetDestChainConfig(&_OnRamp.CallOpts, destChainSelector) +} + +func (_OnRamp *OnRampCallerSession) GetDestChainConfig(destChainSelector uint64) (GetDestChainConfig, + + error) { + return _OnRamp.Contract.GetDestChainConfig(&_OnRamp.CallOpts, destChainSelector) +} + func (_OnRamp *OnRampCaller) GetDynamicConfig(opts *bind.CallOpts) (OnRampDynamicConfig, error) { var out []interface{} err := _OnRamp.contract.Call(opts, &out, "getDynamicConfig") @@ -444,6 +500,18 @@ func (_OnRamp *OnRampTransactorSession) AcceptOwnership() (*types.Transaction, e return _OnRamp.Contract.AcceptOwnership(&_OnRamp.TransactOpts) } +func (_OnRamp *OnRampTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, allowListConfigArgsItems []OnRampAllowListConfigArgs) (*types.Transaction, error) { + return _OnRamp.contract.Transact(opts, "applyAllowListUpdates", allowListConfigArgsItems) +} + +func (_OnRamp *OnRampSession) ApplyAllowListUpdates(allowListConfigArgsItems []OnRampAllowListConfigArgs) (*types.Transaction, error) { + return _OnRamp.Contract.ApplyAllowListUpdates(&_OnRamp.TransactOpts, allowListConfigArgsItems) +} + +func (_OnRamp *OnRampTransactorSession) ApplyAllowListUpdates(allowListConfigArgsItems []OnRampAllowListConfigArgs) (*types.Transaction, error) { + return _OnRamp.Contract.ApplyAllowListUpdates(&_OnRamp.TransactOpts, allowListConfigArgsItems) +} + func (_OnRamp *OnRampTransactor) ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []OnRampDestChainConfigArgs) (*types.Transaction, error) { return _OnRamp.contract.Transact(opts, "applyDestChainConfigUpdates", destChainConfigArgs) } @@ -504,6 +572,389 @@ func (_OnRamp *OnRampTransactorSession) WithdrawFeeTokens() (*types.Transaction, return _OnRamp.Contract.WithdrawFeeTokens(&_OnRamp.TransactOpts) } +type OnRampAllowListAdminSetIterator struct { + Event *OnRampAllowListAdminSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OnRampAllowListAdminSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OnRampAllowListAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(OnRampAllowListAdminSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *OnRampAllowListAdminSetIterator) Error() error { + return it.fail +} + +func (it *OnRampAllowListAdminSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OnRampAllowListAdminSet struct { + AllowListAdmin common.Address + Raw types.Log +} + +func (_OnRamp *OnRampFilterer) FilterAllowListAdminSet(opts *bind.FilterOpts, allowListAdmin []common.Address) (*OnRampAllowListAdminSetIterator, error) { + + var allowListAdminRule []interface{} + for _, allowListAdminItem := range allowListAdmin { + allowListAdminRule = append(allowListAdminRule, allowListAdminItem) + } + + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "AllowListAdminSet", allowListAdminRule) + if err != nil { + return nil, err + } + return &OnRampAllowListAdminSetIterator{contract: _OnRamp.contract, event: "AllowListAdminSet", logs: logs, sub: sub}, nil +} + +func (_OnRamp *OnRampFilterer) WatchAllowListAdminSet(opts *bind.WatchOpts, sink chan<- *OnRampAllowListAdminSet, allowListAdmin []common.Address) (event.Subscription, error) { + + var allowListAdminRule []interface{} + for _, allowListAdminItem := range allowListAdmin { + allowListAdminRule = append(allowListAdminRule, allowListAdminItem) + } + + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "AllowListAdminSet", allowListAdminRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OnRampAllowListAdminSet) + if err := _OnRamp.contract.UnpackLog(event, "AllowListAdminSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_OnRamp *OnRampFilterer) ParseAllowListAdminSet(log types.Log) (*OnRampAllowListAdminSet, error) { + event := new(OnRampAllowListAdminSet) + if err := _OnRamp.contract.UnpackLog(event, "AllowListAdminSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OnRampAllowListSendersAddedIterator struct { + Event *OnRampAllowListSendersAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OnRampAllowListSendersAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OnRampAllowListSendersAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(OnRampAllowListSendersAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *OnRampAllowListSendersAddedIterator) Error() error { + return it.fail +} + +func (it *OnRampAllowListSendersAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OnRampAllowListSendersAdded struct { + DestChainSelector uint64 + Senders []common.Address + Raw types.Log +} + +func (_OnRamp *OnRampFilterer) FilterAllowListSendersAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampAllowListSendersAddedIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "AllowListSendersAdded", destChainSelectorRule) + if err != nil { + return nil, err + } + return &OnRampAllowListSendersAddedIterator{contract: _OnRamp.contract, event: "AllowListSendersAdded", logs: logs, sub: sub}, nil +} + +func (_OnRamp *OnRampFilterer) WatchAllowListSendersAdded(opts *bind.WatchOpts, sink chan<- *OnRampAllowListSendersAdded, destChainSelector []uint64) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "AllowListSendersAdded", destChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OnRampAllowListSendersAdded) + if err := _OnRamp.contract.UnpackLog(event, "AllowListSendersAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_OnRamp *OnRampFilterer) ParseAllowListSendersAdded(log types.Log) (*OnRampAllowListSendersAdded, error) { + event := new(OnRampAllowListSendersAdded) + if err := _OnRamp.contract.UnpackLog(event, "AllowListSendersAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OnRampAllowListSendersRemovedIterator struct { + Event *OnRampAllowListSendersRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OnRampAllowListSendersRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OnRampAllowListSendersRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(OnRampAllowListSendersRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *OnRampAllowListSendersRemovedIterator) Error() error { + return it.fail +} + +func (it *OnRampAllowListSendersRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OnRampAllowListSendersRemoved struct { + DestChainSelector uint64 + Senders []common.Address + Raw types.Log +} + +func (_OnRamp *OnRampFilterer) FilterAllowListSendersRemoved(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampAllowListSendersRemovedIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "AllowListSendersRemoved", destChainSelectorRule) + if err != nil { + return nil, err + } + return &OnRampAllowListSendersRemovedIterator{contract: _OnRamp.contract, event: "AllowListSendersRemoved", logs: logs, sub: sub}, nil +} + +func (_OnRamp *OnRampFilterer) WatchAllowListSendersRemoved(opts *bind.WatchOpts, sink chan<- *OnRampAllowListSendersRemoved, destChainSelector []uint64) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "AllowListSendersRemoved", destChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OnRampAllowListSendersRemoved) + if err := _OnRamp.contract.UnpackLog(event, "AllowListSendersRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_OnRamp *OnRampFilterer) ParseAllowListSendersRemoved(log types.Log) (*OnRampAllowListSendersRemoved, error) { + event := new(OnRampAllowListSendersRemoved) + if err := _OnRamp.contract.UnpackLog(event, "AllowListSendersRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type OnRampCCIPSendRequestedIterator struct { Event *OnRampCCIPSendRequested @@ -812,7 +1263,9 @@ func (it *OnRampDestChainConfigSetIterator) Close() error { type OnRampDestChainConfigSet struct { DestChainSelector uint64 - DestChainConfig OnRampDestChainConfig + SequenceNumber uint64 + Router common.Address + AllowListEnabled bool Raw types.Log } @@ -1415,8 +1868,20 @@ func (_OnRamp *OnRampFilterer) ParseOwnershipTransferred(log types.Log) (*OnRamp return event, nil } +type GetDestChainConfig struct { + SequenceNumber uint64 + AllowListEnabled bool + Router common.Address +} + func (_OnRamp *OnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { + case _OnRamp.abi.Events["AllowListAdminSet"].ID: + return _OnRamp.ParseAllowListAdminSet(log) + case _OnRamp.abi.Events["AllowListSendersAdded"].ID: + return _OnRamp.ParseAllowListSendersAdded(log) + case _OnRamp.abi.Events["AllowListSendersRemoved"].ID: + return _OnRamp.ParseAllowListSendersRemoved(log) case _OnRamp.abi.Events["CCIPSendRequested"].ID: return _OnRamp.ParseCCIPSendRequested(log) case _OnRamp.abi.Events["ConfigSet"].ID: @@ -1437,16 +1902,28 @@ func (_OnRamp *OnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { } } +func (OnRampAllowListAdminSet) Topic() common.Hash { + return common.HexToHash("0xb8c9b44ae5b5e3afb195f67391d9ff50cb904f9c0fa5fd520e497a97c1aa5a1e") +} + +func (OnRampAllowListSendersAdded) Topic() common.Hash { + return common.HexToHash("0x330939f6eafe8bb516716892fe962ff19770570838686e6579dbc1cc51fc3281") +} + +func (OnRampAllowListSendersRemoved) Topic() common.Hash { + return common.HexToHash("0xc237ec1921f855ccd5e9a5af9733f2d58943a5a8501ec5988e305d7a4d421586") +} + func (OnRampCCIPSendRequested) Topic() common.Hash { return common.HexToHash("0xcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140") } func (OnRampConfigSet) Topic() common.Hash { - return common.HexToHash("0x2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558") + return common.HexToHash("0x23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32") } func (OnRampDestChainConfigSet) Topic() common.Hash { - return common.HexToHash("0x324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6") + return common.HexToHash("0xd5ad72bc37dc7a80a8b9b9df20500046fd7341adb1be2258a540466fdd7dcef5") } func (OnRampFeePaid) Topic() common.Hash { @@ -1470,6 +1947,12 @@ func (_OnRamp *OnRamp) Address() common.Address { } type OnRampInterface interface { + GetAllowedSendersList(opts *bind.CallOpts, destChainSelector uint64) ([]common.Address, error) + + GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (GetDestChainConfig, + + error) + GetDynamicConfig(opts *bind.CallOpts) (OnRampDynamicConfig, error) GetExpectedNextSequenceNumber(opts *bind.CallOpts, destChainSelector uint64) (uint64, error) @@ -1490,6 +1973,8 @@ type OnRampInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + ApplyAllowListUpdates(opts *bind.TransactOpts, allowListConfigArgsItems []OnRampAllowListConfigArgs) (*types.Transaction, error) + ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []OnRampDestChainConfigArgs) (*types.Transaction, error) ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) @@ -1500,6 +1985,24 @@ type OnRampInterface interface { WithdrawFeeTokens(opts *bind.TransactOpts) (*types.Transaction, error) + FilterAllowListAdminSet(opts *bind.FilterOpts, allowListAdmin []common.Address) (*OnRampAllowListAdminSetIterator, error) + + WatchAllowListAdminSet(opts *bind.WatchOpts, sink chan<- *OnRampAllowListAdminSet, allowListAdmin []common.Address) (event.Subscription, error) + + ParseAllowListAdminSet(log types.Log) (*OnRampAllowListAdminSet, error) + + FilterAllowListSendersAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampAllowListSendersAddedIterator, error) + + WatchAllowListSendersAdded(opts *bind.WatchOpts, sink chan<- *OnRampAllowListSendersAdded, destChainSelector []uint64) (event.Subscription, error) + + ParseAllowListSendersAdded(log types.Log) (*OnRampAllowListSendersAdded, error) + + FilterAllowListSendersRemoved(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampAllowListSendersRemovedIterator, error) + + WatchAllowListSendersRemoved(opts *bind.WatchOpts, sink chan<- *OnRampAllowListSendersRemoved, destChainSelector []uint64) (event.Subscription, error) + + ParseAllowListSendersRemoved(log types.Log) (*OnRampAllowListSendersRemoved, error) + FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampCCIPSendRequestedIterator, error) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *OnRampCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 688818f694..f8a7a120af 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -24,7 +24,7 @@ multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Help nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 6f64e1083b356c06ee66b9138e398b9c97a4cd3e8c9ec38cf3010cebc79af536 ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin a3b8a9644f0d450dbf53d3371555dcc4084fb2eaf138a3797ef5cf73ed665bae -onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 13927b48bd09b9ab2c62143973c747f8c2e1ebc9f95f17a61ace67a68c71ec75 +onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 1ae9e3ebefc56d0382308c67c4ec066cdf3fa3eed2d31af8015d5d8db67f9c90 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin c1c2f8a65c7ffd971899cae7fe62f2da57d09e936151e2b92163c4bebe699d6b price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin e7781d600c1bb7aa4620106af7f6e146a109b97f4cb6a7d06c9e15773340ecb2 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 75be86323c227917a9bbc3f799d7ed02f92db546653a36db30ed0ebe64461353 diff --git a/integration-tests/web/sdk/client/client.go b/integration-tests/web/sdk/client/client.go index bcfd3b1f0b..454e18a234 100644 --- a/integration-tests/web/sdk/client/client.go +++ b/integration-tests/web/sdk/client/client.go @@ -48,12 +48,12 @@ type Credentials struct { } func New(baseURI string, creds Credentials) (Client, error) { - e := endpoints{ + ep := endpoints{ Sessions: baseURI + "/sessions", Query: baseURI + "/query", } c := &client{ - endpoints: e, + endpoints: ep, credentials: creds, } From b99a4de7b72bd965c08f3b419a6c736f60116c95 Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Thu, 29 Aug 2024 13:02:54 +0200 Subject: [PATCH 254/432] assert fees can be set to zero (#1380) Assert we would have the option to set any of the fee components to zero if we would want. --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/gas-snapshots/ccip.gas-snapshot | 56 +++++++++---------- contracts/src/v0.8/ccip/FeeQuoter.sol | 5 +- .../v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol | 2 +- .../v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol | 26 +++++++++ .../src/v0.8/ccip/test/onRamp/OnRamp.t.sol | 29 ++++++++++ .../ccip/generated/fee_quoter/fee_quoter.go | 4 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 7 files changed, 89 insertions(+), 35 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index e2c0c4ad78..97609ff3aa 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -252,6 +252,7 @@ EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2_Success() (gas: 95349) EVM2EVMOnRamp_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 20544) EVM2EVMOnRamp_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20912) EVM2EVMOnRamp_getFee:test_EmptyMessage_Success() (gas: 78230) +EVM2EVMOnRamp_getFee:test_GetFeeOfZeroForTokenMessage_Success() (gas: 81762) EVM2EVMOnRamp_getFee:test_HighGasMessage_Success() (gas: 234078) EVM2EVMOnRamp_getFee:test_MessageGasLimitTooHigh_Revert() (gas: 16715) EVM2EVMOnRamp_getFee:test_MessageTooLarge_Revert() (gas: 95271) @@ -343,10 +344,10 @@ FeeQuoter_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfig_Su FeeQuoter_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeZeroInput() (gas: 13089) FeeQuoter_applyTokenTransferFeeConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 17071) FeeQuoter_applyTokenTransferFeeConfigUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 12240) -FeeQuoter_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 107016) -FeeQuoter_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 111366) -FeeQuoter_constructor:test_InvalidStalenessThreshold_Revert() (gas: 111419) -FeeQuoter_constructor:test_Setup_Success() (gas: 5336824) +FeeQuoter_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 107046) +FeeQuoter_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 111396) +FeeQuoter_constructor:test_InvalidStalenessThreshold_Revert() (gas: 111449) +FeeQuoter_constructor:test_Setup_Success() (gas: 5358690) FeeQuoter_convertTokenAmount:test_ConvertTokenAmount_Success() (gas: 72739) FeeQuoter_convertTokenAmount:test_LinkTokenNotSupported_Revert() (gas: 30963) FeeQuoter_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 94303) @@ -368,17 +369,17 @@ FeeQuoter_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_S FeeQuoter_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 40013) FeeQuoter_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29299) FeeQuoter_getValidatedFee:test_DestinationChainNotEnabled_Revert() (gas: 18180) -FeeQuoter_getValidatedFee:test_EmptyMessage_Success() (gas: 81054) -FeeQuoter_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 54294) -FeeQuoter_getValidatedFee:test_HighGasMessage_Success() (gas: 237472) -FeeQuoter_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 19949) -FeeQuoter_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 31746) -FeeQuoter_getValidatedFee:test_MessageTooLarge_Revert() (gas: 97692) -FeeQuoter_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 142833) -FeeQuoter_getValidatedFee:test_NotAFeeToken_Revert() (gas: 29407) -FeeQuoter_getValidatedFee:test_SingleTokenMessage_Success() (gas: 111861) -FeeQuoter_getValidatedFee:test_TooManyTokens_Revert() (gas: 20085) -FeeQuoter_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 61933) +FeeQuoter_getValidatedFee:test_EmptyMessage_Success() (gas: 85936) +FeeQuoter_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 56735) +FeeQuoter_getValidatedFee:test_HighGasMessage_Success() (gas: 242354) +FeeQuoter_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 22390) +FeeQuoter_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 34187) +FeeQuoter_getValidatedFee:test_MessageTooLarge_Revert() (gas: 100133) +FeeQuoter_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 147715) +FeeQuoter_getValidatedFee:test_NotAFeeToken_Revert() (gas: 21043) +FeeQuoter_getValidatedFee:test_SingleTokenMessage_Success() (gas: 116743) +FeeQuoter_getValidatedFee:test_TooManyTokens_Revert() (gas: 22526) +FeeQuoter_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 64374) FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Above18Decimals_Success() (gas: 2094539) FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Below18Decimals_Success() (gas: 2094497) FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt0Decimals_Success() (gas: 2074616) @@ -564,8 +565,8 @@ MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) -MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 410978) -MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1504783) +MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 414301) +MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1506106) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) @@ -747,19 +748,15 @@ OffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178754) OffRamp_verify:test_NotBlessed_Success() (gas: 141593) OffRamp_verify:test_TooManyLeaves_Revert() (gas: 51510) OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 390336) -OnRamp_allowListConfigUpdates:test_applyAllowList_Success() (gas: 323566) OnRamp_allowListConfigUpdates:test_applyAllowList_Revert() (gas: 66509) -OnRamp_allowListConfigUpdates:test_setAllowListAdmin_ByNonOwner_Revert() (gas: 11833) -OnRamp_allowListConfigUpdates:test_setAllowListAdmin_Success() (gas: 36159) -OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInvalidChainSelector_Revert() (gas: 13242) +OnRamp_allowListConfigUpdates:test_applyAllowList_Success() (gas: 323566) OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 64501) -OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() (gas: 13308) +OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInvalidChainSelector_Revert() (gas: 13242) OnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94878) OnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92812) OnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97827) OnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92870) OnRamp_constructor:test_Constructor_Success() (gas: 2866937) -OnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 72097) OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 115250) OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 146019) OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 145615) @@ -770,6 +767,7 @@ OnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter OnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 28810) OnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 138683) OnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 26910) +OnRamp_forwardFromRouter:test_MultiCannotSendZeroTokens_Revert() (gas: 74456) OnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12918) OnRamp_forwardFromRouter:test_Paused_Revert() (gas: 37224) OnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 18179) @@ -782,19 +780,19 @@ OnRamp_forwardFromRouter:test_UnAllowedOriginalSender_Revert() (gas: 18609) OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 111118) OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 76545) OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 278740) -OnRamp_forwardFromRouter:test_MultiCannotSendZeroTokens_Revert() (gas: 74456) -OnRamp_getFee:test_EmptyMessage_Success() (gas: 104331) -OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 73163) -OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119655) +OnRamp_getFee:test_EmptyMessage_Success() (gas: 110107) +OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 75610) +OnRamp_getFee:test_GetFeeOfZeroForTokenMessage_Success() (gas: 95456) +OnRamp_getFee:test_NotAFeeTokenButPricedToken_Revert() (gas: 41814) +OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 125476) OnRamp_getFee:test_Unhealthy_Revert() (gas: 43669) OnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10438) OnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35204) OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11402) -OnRamp_setDynamicConfig:test_SetConfigInvalidConfigPriceRegistryEqAddressZero_Revert() (gas: 12978) +OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeQuoterEqAddressZero_Revert() (gas: 13001) OnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11359) OnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 16385) OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 55321) -OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeQuoterEqAddressZero_Revert() (gas: 13001) OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97107) PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150169) PingPong_plumbing:test_OutOfOrderExecution_Success() (gas: 20277) diff --git a/contracts/src/v0.8/ccip/FeeQuoter.sol b/contracts/src/v0.8/ccip/FeeQuoter.sol index c2a7231d96..aea632fc4e 100644 --- a/contracts/src/v0.8/ccip/FeeQuoter.sol +++ b/contracts/src/v0.8/ccip/FeeQuoter.sol @@ -28,6 +28,7 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, using KeystoneFeedDefaultMetadataLib for bytes; error TokenNotSupported(address token); + error FeeTokenNotSupported(address token); error ChainNotSupported(uint64 chain); error StaleGasPrice(uint64 destChainSelector, uint256 threshold, uint256 timePassed); error StaleKeystoneUpdate(address token, uint256 feedTimestamp, uint256 storedTimeStamp); @@ -147,7 +148,7 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, /// applyPremiumMultiplierWeiPerEthUpdates to set the mapping struct PremiumMultiplierWeiPerEthArgs { address token; // // ───────────────────╮ Token address - uint64 premiumMultiplierWeiPerEth; // ──╯ Multiplier for destination chain specific premiums. Should never be 0 so can be used as an isEnabled flag + uint64 premiumMultiplierWeiPerEth; // ──╯ Multiplier for destination chain specific premiums. } string public constant override typeAndVersion = "FeeQuoter 1.6.0-dev"; @@ -174,7 +175,6 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, mapping(address token => IFeeQuoter.TokenPriceFeedConfig dataFeedAddress) private s_usdPriceFeedsPerToken; /// @dev The multiplier for destination chain specific premiums that can be set by the owner or fee admin - /// This should never be 0 once set, so it can be used as an isEnabled flag mapping(address token => uint64 premiumMultiplierWeiPerEth) internal s_premiumMultiplierWeiPerEth; /// @dev The destination chain specific fee configs @@ -473,6 +473,7 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, ) external view returns (uint256 feeTokenAmount) { DestChainConfig memory destChainConfig = s_destChainConfigs[destChainSelector]; if (!destChainConfig.isEnabled) revert DestinationChainNotEnabled(destChainSelector); + if (!s_feeTokens.contains(message.feeToken)) revert FeeTokenNotSupported(message.feeToken); uint256 numberOfTokens = message.tokenAmounts.length; _validateMessage(destChainConfig, message.data.length, numberOfTokens, message.receiver); diff --git a/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol b/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol index 11836b3d7b..cdbf1cef7a 100644 --- a/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol +++ b/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol @@ -1706,7 +1706,7 @@ contract FeeQuoter_getValidatedFee is FeeQuoterFeeSetup { Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(notAFeeToken, 1); message.feeToken = notAFeeToken; - vm.expectRevert(abi.encodeWithSelector(FeeQuoter.TokenNotSupported.selector, notAFeeToken)); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.FeeTokenNotSupported.selector, notAFeeToken)); s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); } diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol index 7b400c0df6..f0cd0f80ed 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol @@ -1407,6 +1407,32 @@ contract EVM2EVMOnRamp_getFee is EVM2EVMOnRamp_getFeeSetup { } } + function test_GetFeeOfZeroForTokenMessage_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + assertTrue(feeAmount > 0); + + EVM2EVMOnRamp.FeeTokenConfigArgs[] memory feeTokenConfigArgs = new EVM2EVMOnRamp.FeeTokenConfigArgs[](1); + feeTokenConfigArgs[0] = EVM2EVMOnRamp.FeeTokenConfigArgs({ + token: message.feeToken, + networkFeeUSDCents: 0, + gasMultiplierWeiPerEth: 0, + premiumMultiplierWeiPerEth: 0, + enabled: true + }); + + s_onRamp.setFeeTokenConfig(feeTokenConfigArgs); + EVM2EVMOnRamp.DynamicConfig memory config = + generateDynamicOnRampConfig(address(s_sourceRouter), address(s_feeQuoter)); + config.destDataAvailabilityMultiplierBps = 0; + + s_onRamp.setDynamicConfig(config); + + feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + assertEq(0, feeAmount); + } + function test_ZeroDataAvailabilityMultiplier_Success() public { EVM2EVMOnRamp.DynamicConfig memory dynamicConfig = s_onRamp.getDynamicConfig(); dynamicConfig.destDataAvailabilityMultiplierBps = 0; diff --git a/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol index f69a4eafec..a6f4205ee1 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol @@ -609,6 +609,26 @@ contract OnRamp_getFee is OnRampSetup { } } + function test_GetFeeOfZeroForTokenMessage_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + assertTrue(feeAmount > 0); + + FeeQuoter.PremiumMultiplierWeiPerEthArgs[] memory tokenMults = new FeeQuoter.PremiumMultiplierWeiPerEthArgs[](1); + tokenMults[0] = FeeQuoter.PremiumMultiplierWeiPerEthArgs({token: message.feeToken, premiumMultiplierWeiPerEth: 0}); + s_feeQuoter.applyPremiumMultiplierWeiPerEthUpdates(tokenMults); + + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs(); + destChainConfigArgs[0].destChainConfig.destDataAvailabilityMultiplierBps = 0; + destChainConfigArgs[0].destChainConfig.gasMultiplierWeiPerEth = 0; + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); + + feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + + assertEq(0, feeAmount); + } + // Reverts function test_Unhealthy_Revert() public { @@ -634,6 +654,15 @@ contract OnRamp_getFee is OnRampSetup { vm.expectRevert(FeeQuoter.ExtraArgOutOfOrderExecutionMustBeTrue.selector); s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); } + + function test_NotAFeeTokenButPricedToken_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = s_sourceTokens[1]; + + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.FeeTokenNotSupported.selector, message.feeToken)); + + s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + } } contract OnRamp_setDynamicConfig is OnRampSetup { diff --git a/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go b/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go index 74ed33b73a..807a932da6 100644 --- a/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go +++ b/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go @@ -154,8 +154,8 @@ type KeystoneFeedsPermissionHandlerPermission struct { } var FeeQuoterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structFeeQuoter.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structFeeQuoter.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"}],\"name\":\"ReportForwarderUnauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feedTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"storedTimeStamp\",\"type\":\"uint256\"}],\"name\":\"StaleKeystoneUpdate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"reportId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission\",\"name\":\"permission\",\"type\":\"tuple\"}],\"name\":\"ReportPermissionSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structFeeQuoter.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structFeeQuoter.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"processPoolReturnData\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"destExecDataPerToken\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission[]\",\"name\":\"permissions\",\"type\":\"tuple[]\"}],\"name\":\"setReportPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620076d8380380620076d8833981016040819052620000349162001834565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a5a565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b26565b5050505050505062001ae5565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001953565b60209081029190910101519050620002f560028262000e5f565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001953565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000e7f565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001953565b6020026020010151600b62000e7f60201b90919060201c565b1562000499578281815181106200045b576200045b62001953565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001953565b6020026020010151600b62000e9660201b90919060201c565b156200053b57818181518110620004fd57620004fd62001953565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001953565b6020908102919091018101518051818301516001600160a01b0380831660008181526007875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001953565b6020026020010151905060008383815181106200065f576200065f62001953565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061016081015163ffffffff16155b80620006ba57506101e08101516001600160e01b031916630a04b54b60e21b14155b80620006da5750806060015163ffffffff1681610160015163ffffffff16115b15620007055760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260096020526040812060010154600160881b900460e01b6001600160e01b03191690036200078557816001600160401b03167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb7248260405162000777919062001969565b60405180910390a2620007c9565b816001600160401b03167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab2082604051620007c0919062001969565b60405180910390a25b8060096000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a8154816001600160401b0302191690836001600160401b031602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000a7e5762000a7e62001953565b6020026020010151600001519050600083838151811062000aa35762000aa362001953565b6020908102919091018101518101516001600160a01b03841660008181526008845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a5d565b60005b825181101562000d9957600083828151811062000b4a5762000b4a62001953565b6020026020010151905060008160000151905060005b82602001515181101562000d8a5760008360200151828151811062000b895762000b8962001953565b602002602001015160200151905060008460200151838151811062000bb25762000bb262001953565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c115760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000d77908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000b60565b50505080600101905062000b29565b5060005b81518110156200054457600082828151811062000dbe5762000dbe62001953565b6020026020010151600001519050600083838151811062000de35762000de362001953565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000d9d565b600062000e76836001600160a01b03841662000ead565b90505b92915050565b600062000e76836001600160a01b03841662000fb1565b600062000e76836001600160a01b03841662001003565b6000818152600183016020526040812054801562000fa657600062000ed460018362001aad565b855490915060009062000eea9060019062001aad565b905081811462000f5657600086600001828154811062000f0e5762000f0e62001953565b906000526020600020015490508087600001848154811062000f345762000f3462001953565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f6a5762000f6a62001acf565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e79565b600091505062000e79565b600081815260018301602052604081205462000ffa5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e79565b50600062000e79565b6000818152600183016020526040812054801562000fa65760006200102a60018362001aad565b8554909150600090620010409060019062001aad565b905080821462000f5657600086600001828154811062000f0e5762000f0e62001953565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200109f576200109f62001064565b60405290565b60405160c081016001600160401b03811182821017156200109f576200109f62001064565b60405161020081016001600160401b03811182821017156200109f576200109f62001064565b604051601f8201601f191681016001600160401b03811182821017156200111b576200111b62001064565b604052919050565b80516001600160a01b03811681146200113b57600080fd5b919050565b805163ffffffff811681146200113b57600080fd5b6000606082840312156200116857600080fd5b604051606081016001600160401b03811182821017156200118d576200118d62001064565b604052825190915081906001600160601b0381168114620011ad57600080fd5b8152620011bd6020840162001123565b6020820152620011d06040840162001140565b60408201525092915050565b60006001600160401b03821115620011f857620011f862001064565b5060051b60200190565b600082601f8301126200121457600080fd5b815160206200122d6200122783620011dc565b620010f0565b8083825260208201915060208460051b8701019350868411156200125057600080fd5b602086015b848110156200127757620012698162001123565b835291830191830162001255565b509695505050505050565b600082601f8301126200129457600080fd5b81516020620012a76200122783620011dc565b82815260609283028501820192828201919087851115620012c757600080fd5b8387015b858110156200135a5780890382811215620012e65760008081fd5b620012f06200107a565b620012fb8362001123565b8152604080601f1984011215620013125760008081fd5b6200131c6200107a565b92506200132b88850162001123565b835283015160ff81168114620013415760008081fd5b82880152808701919091528452928401928101620012cb565b5090979650505050505050565b80516001600160401b03811681146200113b57600080fd5b805161ffff811681146200113b57600080fd5b805180151581146200113b57600080fd5b600082601f830112620013b557600080fd5b81516020620013c86200122783620011dc565b82815260059290921b84018101918181019086841115620013e857600080fd5b8286015b84811015620012775780516001600160401b03808211156200140d57600080fd5b908801906040601f19838c0381018213156200142857600080fd5b620014326200107a565b6200143f89860162001367565b815282850151848111156200145357600080fd5b8086019550508c603f8601126200146957600080fd5b8885015193506200147e6200122785620011dc565b84815260e09094028501830193898101908e8611156200149d57600080fd5b958401955b858710156200157657868f0360e0811215620014bd57600080fd5b620014c76200107a565b620014d28962001123565b815260c08683011215620014e557600080fd5b620014ef620010a5565b9150620014fe8d8a0162001140565b82526200150d878a0162001140565b8d8301526200151f60608a016200137f565b878301526200153160808a0162001140565b60608301526200154460a08a0162001140565b60808301526200155760c08a0162001392565b60a0830152808d0191909152825260e09690960195908a0190620014a2565b828b015250875250505092840192508301620013ec565b600082601f8301126200159f57600080fd5b81516020620015b26200122783620011dc565b82815260069290921b84018101918181019086841115620015d257600080fd5b8286015b84811015620012775760408189031215620015f15760008081fd5b620015fb6200107a565b620016068262001123565b81526200161585830162001367565b81860152835291830191604001620015d6565b80516001600160e01b0319811681146200113b57600080fd5b600082601f8301126200165357600080fd5b81516020620016666200122783620011dc565b82815261022092830285018201928282019190878511156200168757600080fd5b8387015b858110156200135a5780890382811215620016a65760008081fd5b620016b06200107a565b620016bb8362001367565b815261020080601f1984011215620016d35760008081fd5b620016dd620010ca565b9250620016ec88850162001392565b83526040620016fd8186016200137f565b8985015260606200171081870162001140565b82860152608091506200172582870162001140565b9085015260a06200173886820162001140565b8286015260c091506200174d8287016200137f565b9085015260e06200176086820162001140565b828601526101009150620017768287016200137f565b908501526101206200178a8682016200137f565b828601526101409150620017a08287016200137f565b90850152610160620017b486820162001140565b828601526101809150620017ca82870162001140565b908501526101a0620017de86820162001367565b828601526101c09150620017f482870162001140565b908501526101e06200180886820162001392565b828601526200181983870162001628565b9085015250508087019190915284529284019281016200168b565b6000806000806000806000610120888a0312156200185157600080fd5b6200185d898962001155565b60608901519097506001600160401b03808211156200187b57600080fd5b620018898b838c0162001202565b975060808a0151915080821115620018a057600080fd5b620018ae8b838c0162001202565b965060a08a0151915080821115620018c557600080fd5b620018d38b838c0162001282565b955060c08a0151915080821115620018ea57600080fd5b620018f88b838c01620013a3565b945060e08a01519150808211156200190f57600080fd5b6200191d8b838c016200158d565b93506101008a01519150808211156200193557600080fd5b50620019448a828b0162001641565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610200810160208301516200198a602084018261ffff169052565b506040830151620019a3604084018263ffffffff169052565b506060830151620019bc606084018263ffffffff169052565b506080830151620019d5608084018263ffffffff169052565b5060a0830151620019ec60a084018261ffff169052565b5060c083015162001a0560c084018263ffffffff169052565b5060e083015162001a1c60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501516001600160401b0316908401526101a080850151909116908301526101c0808401511515908301526101e0928301516001600160e01b031916929091019190915290565b8181038181111562000e7957634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051615b9962001b3f600039600081816102ef0152818161219101526121fa0152600081816102b301528181611917015261197701526000818161027f015281816119a00152611a100152615b996000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c806379ba509711610104578063a69c64c0116100a2578063d02641a011610071578063d02641a014610a81578063d8694ccd14610a94578063f2fde38b14610aa7578063ffdb4b3714610aba57600080fd5b8063a69c64c014610997578063bf78e03f146109aa578063c4276bfc14610a57578063cdc73d5114610a7957600080fd5b806382b49eb0116100de57806382b49eb0146107d95780638da5cb5b1461094957806391a2749a146109715780639ea600261461098457600080fd5b806379ba5097146107ab5780637afac322146107b3578063805f2132146107c657600080fd5b8063407e1086116101715780634ab35b0b1161014b5780634ab35b0b14610441578063514e8cff146104815780636def4ce714610524578063770e2dc41461079857600080fd5b8063407e1086146103fb57806341ed29e71461040e57806345ac924d1461042157600080fd5b8063085318f8116101ad578063085318f814610368578063181f5a77146103885780632451a627146103d15780633937306f146103e657600080fd5b806241e5be146101d3578063061877e3146101f957806306285c6914610252575b600080fd5b6101e66101e1366004614250565b610b02565b6040519081526020015b60405180910390f35b61023961020736600461428c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101f0565b61031c604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101f0565b61037b610376366004614304565b610b70565b6040516101f09190614416565b6103c46040518060400160405280601381526020017f46656551756f74657220312e362e302d6465760000000000000000000000000081525081565b6040516101f09190614498565b6103d9610ee2565b6040516101f091906144ab565b6103f96103f4366004614505565b610ef3565b005b6103f96104093660046146a7565b6111a8565b6103f961041c3660046147d9565b6111bc565b61043461042f366004614914565b6111fe565b6040516101f09190614956565b61045461044f36600461428c565b6112c9565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b61051761048f3660046149d1565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101f091906149ec565b61078b6105323660046149d1565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101919091525067ffffffffffffffff908116600090815260096020908152604091829020825161020081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a085015271010000000000000000000000000000000000808404881660c086015275010000000000000000000000000000000000000000008404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b01000000000000000000000000000000000000000000000000000000909204861661014084015260019093015480861661016084015264010000000081049096166101808301526c0100000000000000000000000086049094166101a0820152700100000000000000000000000000000000850490911615156101c08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b166101e082015290565b6040516101f09190614a27565b6103f96107a6366004614c3e565b6112d4565b6103f96112e6565b6103f96107c1366004614f58565b6113e3565b6103f96107d4366004614ffe565b6113f5565b6108e96107e736600461506a565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff919091166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101f09190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6103f961097f366004615094565b6118dd565b6103f9610992366004615155565b6118ee565b6103f96109a5366004615362565b6118ff565b610a236109b836600461428c565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526007825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101f0565b610a6a610a65366004615427565b611910565b6040516101f093929190615496565b6103d9611b06565b610517610a8f36600461428c565b611b12565b6101e6610aa23660046154b7565b611c0e565b6103f9610ab536600461428c565b6120ac565b610acd610ac836600461550c565b6120bd565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101f0565b6000610b0d82612248565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b3485612248565b610b5c907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685615565565b610b66919061557c565b90505b9392505050565b67ffffffffffffffff8086166000908152600960205260409020600101546060917101000000000000000000000000000000000090910460e01b908590811115610bbc57610bbc614540565b604051908082528060200260200182016040528015610bef57816020015b6060815260200190600190039081610bda5790505b50915060005b85811015610ed7576000858583818110610c1157610c116155b7565b610c27926020604090920201908101915061428c565b90506000888884818110610c3d57610c3d6155b7565b9050602002810190610c4f91906155e6565b610c5d906040810190615624565b9150506020811115610d125767ffffffffffffffff8a166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115610d12576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b610d82848a8a86818110610d2857610d286155b7565b9050602002810190610d3a91906155e6565b610d48906020810190615624565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122e292505050565b67ffffffffffffffff8a166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320815160c081018352905463ffffffff8082168352640100000000820481168386015268010000000000000000820461ffff16838501526a01000000000000000000008204811660608401526e010000000000000000000000000000820481166080840152720100000000000000000000000000000000000090910460ff16151560a08301908152958552600990935290832054935190937b0100000000000000000000000000000000000000000000000000000090049091169190610e815781610e87565b82606001515b6040805163ffffffff8316602082015291925001604051602081830303815290604052888781518110610ebc57610ebc6155b7565b60200260200101819052505050505050806001019050610bf5565b505095945050505050565b6060610eee6002612339565b905090565b610efb612346565b6000610f078280615689565b9050905060005b81811015611051576000610f228480615689565b83818110610f3257610f326155b7565b905060400201803603810190610f48919061571d565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600690975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926110409290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610f0e565b5060006110616020840184615689565b9050905060005b818110156111a257600061107f6020860186615689565b8381811061108f5761108f6155b7565b9050604002018036038101906110a5919061575a565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e926111919290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101611068565b50505050565b6111b061238b565b6111b98161240c565b50565b6111c461238b565b60005b81518110156111fa576111f28282815181106111e5576111e56155b7565b602002602001015161250a565b6001016111c7565b5050565b60608160008167ffffffffffffffff81111561121c5761121c614540565b60405190808252806020026020018201604052801561126157816020015b604080518082019091526000808252602082015281526020019060019003908161123a5790505b50905060005b828110156112be57611299868683818110611284576112846155b7565b9050602002016020810190610a8f919061428c565b8282815181106112ab576112ab6155b7565b6020908102919091010152600101611267565b509150505b92915050565b60006112c382612248565b6112dc61238b565b6111fa82826126dc565b60015473ffffffffffffffffffffffffffffffffffffffff163314611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610d09565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6113eb61238b565b6111fa8282612ae9565b600080600061143987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c3092505050565b92509250925061144b33838584612c4b565b60006114598587018761577d565b905060005b81518110156118d25760006007600084848151811061147f5761147f6155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160009081205474010000000000000000000000000000000000000000900460ff169150819003611540578282815181106114e9576114e96155b7565b6020908102919091010151516040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b600061158960128386868151811061155a5761155a6155b7565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612da3565b9050600660008585815181106115a1576115a16155b7565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff16848481518110611613576116136155b7565b60200260200101516040015163ffffffff16101561171d5783838151811061163d5761163d6155b7565b60200260200101516000015184848151811061165b5761165b6155b7565b6020026020010151604001516006600087878151811061167d5761167d6155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260409081016000205490517f191ec70600000000000000000000000000000000000000000000000000000000815293909116600484015263ffffffff91821660248401527c01000000000000000000000000000000000000000000000000000000009004166044820152606401610d09565b6040518060400160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260200185858151811061175e5761175e6155b7565b60200260200101516040015163ffffffff1681525060066000868681518110611789576117896155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790558351849084908110611821576118216155b7565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff167f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a82868681518110611877576118776155b7565b6020026020010151604001516040516118c09291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a2505060010161145e565b505050505050505050565b6118e561238b565b6111b981612e69565b6118f661238b565b6111b981612ff5565b61190761238b565b6111b98161349b565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036119705785925061199e565b61199b87877f0000000000000000000000000000000000000000000000000000000000000000610b02565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611a3d576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610d09565b67ffffffffffffffff881660009081526009602052604081206001015463ffffffff1690611a6c878784613585565b9050806020015193508484611af3836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b6060610eee600b612339565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600760209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff169082015290611c0557505073ffffffffffffffffffffffffffffffffffffffff166000908152600660209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b698161372e565b67ffffffffffffffff8083166000908152600960209081526040808320815161020081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a086015271010000000000000000000000000000000000808504881660c087015275010000000000000000000000000000000000000000008504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b01000000000000000000000000000000000000000000000000000000909304861661014085015260019094015480861661016085015264010000000081049098166101808401526c0100000000000000000000000088049094166101a0830152700100000000000000000000000000000000870490931615156101c08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b166101e0840152909190611e28576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000611e376040850185615689565b9150611e93905082611e4c6020870187615624565b905083611e598880615624565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506138bd92505050565b6000600881611ea8608088016060890161428c565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff16915080611ef7611ef16080890160608a0161428c565b896120bd565b9092509050600080808615611f3d57611f31888c611f1b60808e0160608f0161428c565b888e8060400190611f2c9190615689565b613967565b91945092509050611f5d565b6101a0880151611f5a9063ffffffff16662386f26fc10000615565565b92505b61010088015160009061ffff1615611fa157611f9e896dffffffffffffffffffffffffffff607088901c16611f9560208f018f615624565b90508b86613c3f565b90505b61018089015160009067ffffffffffffffff16611fca611fc460808f018f615624565b8d613cef565b600001518563ffffffff168c60a0015161ffff168f8060200190611fee9190615624565b611ff9929150615565565b8d6080015163ffffffff1661200e9190615844565b6120189190615844565b6120229190615844565b61203c906dffffffffffffffffffffffffffff8916615565565b6120469190615565565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8716828261207d67ffffffffffffffff8c1689615565565b6120879190615844565b6120919190615844565b61209b919061557c565b9d9c50505050505050505050505050565b6120b461238b565b6111b981613db0565b67ffffffffffffffff811660009081526005602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203612175576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000816020015163ffffffff164261218d9190615857565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff1681111561222e576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610d09565b61223786612248565b9151919350909150505b9250929050565b60008061225483611b12565b9050806020015163ffffffff166000148061228c575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b156122db576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610d09565b5192915050565b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016111fa5761233481613ea5565b505050565b60606000610b6983613f58565b612351600233613fb4565b612389576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610d09565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314612389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d09565b60005b81518110156111fa57600082828151811061242c5761242c6155b7565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526007875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a250505080600101905061240f565b60006125c382600001518360600151846020015185604001516040805173ffffffffffffffffffffffffffffffffffffffff80871660208301528516918101919091527fffffffffffffffffffff00000000000000000000000000000000000000000000831660608201527fffff0000000000000000000000000000000000000000000000000000000000008216608082015260009060a001604051602081830303815290604052805190602001209050949350505050565b60808301516000828152600460205260409081902080549215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316929092179091555190915081907f32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a3906126d0908590600060a08201905073ffffffffffffffffffffffffffffffffffffffff8084511683527fffffffffffffffffffff0000000000000000000000000000000000000000000060208501511660208401527fffff00000000000000000000000000000000000000000000000000000000000060408501511660408401528060608501511660608401525060808301511515608083015292915050565b60405180910390a25050565b60005b8251811015612a055760008382815181106126fc576126fc6155b7565b6020026020010151905060008160000151905060005b8260200151518110156129f757600083602001518281518110612737576127376155b7565b602002602001015160200151905060008460200151838151811061275d5761275d6155b7565b6020026020010151600001519050602063ffffffff16826080015163ffffffff1610156127e05760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610d09565b67ffffffffffffffff84166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906129e5908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101612712565b5050508060010190506126df565b5060005b8151811015612334576000828281518110612a2657612a266155b7565b60200260200101516000015190506000838381518110612a4857612a486155b7565b60209081029190910181015181015167ffffffffffffffff84166000818152600a8452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612a09565b60005b8251811015612b8c57612b22838281518110612b0a57612b0a6155b7565b6020026020010151600b613fe390919063ffffffff16565b15612b8457828181518110612b3957612b396155b7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b600101612aec565b5060005b815181101561233457612bc6828281518110612bae57612bae6155b7565b6020026020010151600b61400590919063ffffffff16565b15612c2857818181518110612bdd57612bdd6155b7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101612b90565b6040810151604a820151605e90920151909260609290921c91565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602080840191909152908616828401527fffffffffffffffffffff00000000000000000000000000000000000000000000851660608301527fffff00000000000000000000000000000000000000000000000000000000000084166080808401919091528351808403909101815260a09092018352815191810191909120600081815260049092529190205460ff16612d9c576040517f097e17ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8087166004830152851660248201527fffffffffffffffffffff00000000000000000000000000000000000000000000841660448201527fffff00000000000000000000000000000000000000000000000000000000000083166064820152608401610d09565b5050505050565b600080612db0848661586a565b9050600060248260ff161115612de757612dcb602483615883565b612dd690600a6159bc565b612de0908561557c565b9050612e0a565b612df2826024615883565b612dfd90600a6159bc565b612e079085615565565b90505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612e60576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b95945050505050565b602081015160005b8151811015612f04576000828281518110612e8e57612e8e6155b7565b60200260200101519050612eac81600261402790919063ffffffff16565b15612efb5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612e71565b50815160005b81518110156111a2576000828281518110612f2757612f276155b7565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612f97576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fa2600282613fe3565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101612f0a565b60005b81518110156111fa576000828281518110613015576130156155b7565b602002602001015190506000838381518110613033576130336155b7565b60200260200101516000015190506000826020015190508167ffffffffffffffff166000148061306c575061016081015163ffffffff16155b806130be57506101e08101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130dd5750806060015163ffffffff1681610160015163ffffffff16115b15613120576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610d09565b67ffffffffffffffff821660009081526009602052604081206001015471010000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131c4578167ffffffffffffffff167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb724826040516131b79190614a27565b60405180910390a2613207565b8167ffffffffffffffff167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab20826040516131fe9190614a27565b60405180910390a25b80600960008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612ff8565b60005b81518110156111fa5760008282815181106134bb576134bb6155b7565b602002602001015160000151905060008383815181106134dd576134dd6155b7565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526008845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010161349e565b604080518082019091526000808252602082015260008390036135c657506040805180820190915267ffffffffffffffff8216815260006020820152610b69565b60006135d284866159cb565b905060006135e38560048189615a11565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f0000000000000000000000000000000000000000000000000000000000161368057808060200190518101906136779190615a3b565b92505050610b69565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016136fc576040518060400160405280828060200190518101906136e89190615a67565b815260006020909101529250610b69915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137bc9190615a9a565b50505091505060008112156137fd576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061387c8373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561384d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138719190615aea565b866020015184612da3565b604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff4216602082015295945050505050565b836040015163ffffffff168311156139165760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610d09565b836020015161ffff16821115613958576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111a2846101e00151826122e2565b6000808083815b81811015613c3157600087878381811061398a5761398a6155b7565b9050604002018036038101906139a09190615b07565b67ffffffffffffffff8c166000908152600a60209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090613ac0576101208d0151613a8d9061ffff16662386f26fc10000615565565b613a979088615844565b96508c610140015186613aaa9190615b40565b9550613ab7602086615b40565b94505050613c29565b604081015160009061ffff1615613b795760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614613b1c578351613b1590612248565b9050613b1f565b508a5b620186a0836040015161ffff16613b618660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661404990919063ffffffff16565b613b6b9190615565565b613b75919061557c565b9150505b6060820151613b889088615b40565b9650816080015186613b9a9190615b40565b8251909650600090613bb99063ffffffff16662386f26fc10000615565565b905080821015613bd857613bcd818a615844565b985050505050613c29565b6000836020015163ffffffff16662386f26fc10000613bf79190615565565b905080831115613c1757613c0b818b615844565b99505050505050613c29565b613c21838b615844565b995050505050505b60010161396e565b505096509650969350505050565b60008063ffffffff8316613c5561016086615565565b613c61876101c0615844565b613c6b9190615844565b613c759190615844565b905060008760c0015163ffffffff168860e0015161ffff1683613c989190615565565b613ca29190615844565b61010089015190915061ffff16613cc96dffffffffffffffffffffffffffff891683615565565b613cd39190615565565b613ce390655af3107a4000615565565b98975050505050505050565b60408051808201909152600080825260208201526000613d1b858585610160015163ffffffff16613585565b9050826060015163ffffffff1681600001511115613d65576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101c001518015613d7957508060200151155b15610b66576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603613e2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d09565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008151602014613ee457816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614498565b600082806020019051810190613efa9190615a67565b905073ffffffffffffffffffffffffffffffffffffffff811180613f1f575061040081105b156112c357826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614498565b606081600001805480602002602001604051908101604052809291908181526020018280548015613fa857602002820191906000526020600020905b815481526020019060010190808311613f94575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b69565b6000610b698373ffffffffffffffffffffffffffffffffffffffff8416614086565b6000610b698373ffffffffffffffffffffffffffffffffffffffff84166140d5565b6000610b698373ffffffffffffffffffffffffffffffffffffffff84166141cf565b6000670de0b6b3a764000061407c837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616615565565b610b69919061557c565b60008181526001830160205260408120546140cd575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112c3565b5060006112c3565b600081815260018301602052604081205480156141be5760006140f9600183615857565b855490915060009061410d90600190615857565b905080821461417257600086600001828154811061412d5761412d6155b7565b9060005260206000200154905080876000018481548110614150576141506155b7565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061418357614183615b5d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112c3565b60009150506112c3565b5092915050565b600081815260018301602052604081205480156141be5760006141f3600183615857565b855490915060009061420790600190615857565b905081811461417257600086600001828154811061412d5761412d6155b7565b803573ffffffffffffffffffffffffffffffffffffffff8116811461424b57600080fd5b919050565b60008060006060848603121561426557600080fd5b61426e84614227565b92506020840135915061428360408501614227565b90509250925092565b60006020828403121561429e57600080fd5b610b6982614227565b803567ffffffffffffffff8116811461424b57600080fd5b60008083601f8401126142d157600080fd5b50813567ffffffffffffffff8111156142e957600080fd5b6020830191508360208260051b850101111561224157600080fd5b60008060008060006060868803121561431c57600080fd5b614325866142a7565b9450602086013567ffffffffffffffff8082111561434257600080fd5b61434e89838a016142bf565b9096509450604088013591508082111561436757600080fd5b818801915088601f83011261437b57600080fd5b81358181111561438a57600080fd5b8960208260061b850101111561439f57600080fd5b9699959850939650602001949392505050565b6000815180845260005b818110156143d8576020818501810151868301820152016143bc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561448b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526144798583516143b2565b9450928501929085019060010161443f565b5092979650505050505050565b602081526000610b6960208301846143b2565b6020808252825182820181905260009190848201906040850190845b818110156144f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016144c7565b50909695505050505050565b60006020828403121561451757600080fd5b813567ffffffffffffffff81111561452e57600080fd5b820160408185031215610b6957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561459257614592614540565b60405290565b60405160a0810167ffffffffffffffff8111828210171561459257614592614540565b60405160c0810167ffffffffffffffff8111828210171561459257614592614540565b604051610200810167ffffffffffffffff8111828210171561459257614592614540565b6040516060810167ffffffffffffffff8111828210171561459257614592614540565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561466c5761466c614540565b604052919050565b600067ffffffffffffffff82111561468e5761468e614540565b5060051b60200190565b60ff811681146111b957600080fd5b600060208083850312156146ba57600080fd5b823567ffffffffffffffff8111156146d157600080fd5b8301601f810185136146e257600080fd5b80356146f56146f082614674565b614625565b8181526060918202830184019184820191908884111561471457600080fd5b938501935b838510156147b457848903818112156147325760008081fd5b61473a61456f565b61474387614227565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147775760008081fd5b61477f61456f565b925061478c898901614227565b835287013561479a81614698565b828901528088019190915283529384019391850191614719565b50979650505050505050565b80151581146111b957600080fd5b803561424b816147c0565b600060208083850312156147ec57600080fd5b823567ffffffffffffffff81111561480357600080fd5b8301601f8101851361481457600080fd5b80356148226146f082614674565b81815260a0918202830184019184820191908884111561484157600080fd5b938501935b838510156147b45780858a03121561485e5760008081fd5b614866614598565b61486f86614227565b8152868601357fffffffffffffffffffff00000000000000000000000000000000000000000000811681146148a45760008081fd5b818801526040868101357fffff000000000000000000000000000000000000000000000000000000000000811681146148dd5760008081fd5b9082015260606148ee878201614227565b90820152608086810135614901816147c0565b9082015283529384019391850191614846565b6000806020838503121561492757600080fd5b823567ffffffffffffffff81111561493e57600080fd5b61494a858286016142bf565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b828110156149c4576149b484835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101614973565b5091979650505050505050565b6000602082840312156149e357600080fd5b610b69826142a7565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff1690820152604081016112c3565b81511515815261020081016020830151614a47602084018261ffff169052565b506040830151614a5f604084018263ffffffff169052565b506060830151614a77606084018263ffffffff169052565b506080830151614a8f608084018263ffffffff169052565b5060a0830151614aa560a084018261ffff169052565b5060c0830151614abd60c084018263ffffffff169052565b5060e0830151614ad360e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff90811691840191909152610160808501518216908401526101808085015167ffffffffffffffff16908401526101a080850151909116908301526101c0808401511515908301526101e0808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461424b57600080fd5b803561ffff8116811461424b57600080fd5b600082601f830112614bb757600080fd5b81356020614bc76146f083614674565b82815260069290921b84018101918181019086841115614be657600080fd5b8286015b84811015614c335760408189031215614c035760008081fd5b614c0b61456f565b614c14826142a7565b8152614c21858301614227565b81860152835291830191604001614bea565b509695505050505050565b60008060408385031215614c5157600080fd5b67ffffffffffffffff83351115614c6757600080fd5b83601f843585010112614c7957600080fd5b614c896146f08435850135614674565b8335840180358083526020808401939260059290921b90910101861015614caf57600080fd5b602085358601015b85358601803560051b01602001811015614ebc5767ffffffffffffffff81351115614ce157600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a03011215614d1a57600080fd5b614d2261456f565b614d2e602083016142a7565b815267ffffffffffffffff60408301351115614d4957600080fd5b88603f604084013584010112614d5e57600080fd5b614d746146f06020604085013585010135614674565b6020604084810135850182810135808552928401939260e00201018b1015614d9b57600080fd5b6040808501358501015b6040858101358601602081013560e0020101811015614e9d5760e0818d031215614dce57600080fd5b614dd661456f565b614ddf82614227565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215614e1357600080fd5b614e1b6145bb565b614e2760208401614b80565b8152614e3560408401614b80565b6020820152614e4660608401614b94565b6040820152614e5760808401614b80565b6060820152614e6860a08401614b80565b6080820152614e7a60c08401356147c0565b60c083013560a0820152602082810191909152908452929092019160e001614da5565b5080602084015250508085525050602083019250602081019050614cb7565b5092505067ffffffffffffffff60208401351115614ed957600080fd5b614ee98460208501358501614ba6565b90509250929050565b600082601f830112614f0357600080fd5b81356020614f136146f083614674565b8083825260208201915060208460051b870101935086841115614f3557600080fd5b602086015b84811015614c3357614f4b81614227565b8352918301918301614f3a565b60008060408385031215614f6b57600080fd5b823567ffffffffffffffff80821115614f8357600080fd5b614f8f86838701614ef2565b93506020850135915080821115614fa557600080fd5b50614fb285828601614ef2565b9150509250929050565b60008083601f840112614fce57600080fd5b50813567ffffffffffffffff811115614fe657600080fd5b60208301915083602082850101111561224157600080fd5b6000806000806040858703121561501457600080fd5b843567ffffffffffffffff8082111561502c57600080fd5b61503888838901614fbc565b9096509450602087013591508082111561505157600080fd5b5061505e87828801614fbc565b95989497509550505050565b6000806040838503121561507d57600080fd5b615086836142a7565b9150614ee960208401614227565b6000602082840312156150a657600080fd5b813567ffffffffffffffff808211156150be57600080fd5b90830190604082860312156150d257600080fd5b6150da61456f565b8235828111156150e957600080fd5b6150f587828601614ef2565b82525060208301358281111561510a57600080fd5b61511687828601614ef2565b60208301525095945050505050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461424b57600080fd5b6000602080838503121561516857600080fd5b823567ffffffffffffffff81111561517f57600080fd5b8301601f8101851361519057600080fd5b803561519e6146f082614674565b81815261022091820283018401918482019190888411156151be57600080fd5b938501935b838510156147b457848903818112156151dc5760008081fd5b6151e461456f565b6151ed876142a7565b8152610200807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156152225760008081fd5b61522a6145de565b92506152378989016147ce565b83526040615246818a01614b94565b8a8501526060615257818b01614b80565b828601526080915061526a828b01614b80565b9085015260a061527b8a8201614b80565b8286015260c0915061528e828b01614b94565b9085015260e061529f8a8201614b80565b8286015261010091506152b3828b01614b94565b908501526101206152c58a8201614b94565b8286015261014091506152d9828b01614b94565b908501526101606152eb8a8201614b80565b8286015261018091506152ff828b01614b80565b908501526101a06153118a82016142a7565b828601526101c09150615325828b01614b80565b908501526101e06153378a82016147ce565b82860152615346838b01615125565b90850152505080880191909152835293840193918501916151c3565b6000602080838503121561537557600080fd5b823567ffffffffffffffff81111561538c57600080fd5b8301601f8101851361539d57600080fd5b80356153ab6146f082614674565b81815260069190911b820183019083810190878311156153ca57600080fd5b928401925b8284101561541c57604084890312156153e85760008081fd5b6153f061456f565b6153f985614227565b81526154068686016142a7565b81870152825260409390930192908401906153cf565b979650505050505050565b60008060008060006080868803121561543f57600080fd5b615448866142a7565b945061545660208701614227565b935060408601359250606086013567ffffffffffffffff81111561547957600080fd5b61548588828901614fbc565b969995985093965092949392505050565b8381528215156020820152606060408201526000612e6060608301846143b2565b600080604083850312156154ca57600080fd5b6154d3836142a7565b9150602083013567ffffffffffffffff8111156154ef57600080fd5b830160a0818603121561550157600080fd5b809150509250929050565b6000806040838503121561551f57600080fd5b61552883614227565b9150614ee9602084016142a7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176112c3576112c3615536565b6000826155b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261561a57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261565957600080fd5b83018035915067ffffffffffffffff82111561567457600080fd5b60200191503681900382131561224157600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126156be57600080fd5b83018035915067ffffffffffffffff8211156156d957600080fd5b6020019150600681901b360382131561224157600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461424b57600080fd5b60006040828403121561572f57600080fd5b61573761456f565b61574083614227565b815261574e602084016156f1565b60208201529392505050565b60006040828403121561576c57600080fd5b61577461456f565b615740836142a7565b6000602080838503121561579057600080fd5b823567ffffffffffffffff8111156157a757600080fd5b8301601f810185136157b857600080fd5b80356157c66146f082614674565b818152606091820283018401918482019190888411156157e557600080fd5b938501935b838510156147b45780858a0312156158025760008081fd5b61580a614602565b61581386614227565b81526158208787016156f1565b878201526040615831818801614b80565b90820152835293840193918501916157ea565b808201808211156112c3576112c3615536565b818103818111156112c3576112c3615536565b60ff81811683821601908111156112c3576112c3615536565b60ff82811682821603908111156112c3576112c3615536565b600181815b808511156158f557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156158db576158db615536565b808516156158e857918102915b93841c93908002906158a1565b509250929050565b60008261590c575060016112c3565b81615919575060006112c3565b816001811461592f576002811461593957615955565b60019150506112c3565b60ff84111561594a5761594a615536565b50506001821b6112c3565b5060208310610133831016604e8410600b8410161715615978575081810a6112c3565b615982838361589c565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156159b4576159b4615536565b029392505050565b6000610b6960ff8416836158fd565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015614b785760049490940360031b84901b1690921692915050565b60008085851115615a2157600080fd5b83861115615a2e57600080fd5b5050820193919092039150565b600060408284031215615a4d57600080fd5b615a5561456f565b82518152602083015161574e816147c0565b600060208284031215615a7957600080fd5b5051919050565b805169ffffffffffffffffffff8116811461424b57600080fd5b600080600080600060a08688031215615ab257600080fd5b615abb86615a80565b9450602086015193506040860151925060608601519150615ade60808701615a80565b90509295509295909350565b600060208284031215615afc57600080fd5b8151610b6981614698565b600060408284031215615b1957600080fd5b615b2161456f565b615b2a83614227565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156141c8576141c8615536565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structFeeQuoter.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structFeeQuoter.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"FeeTokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"}],\"name\":\"ReportForwarderUnauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feedTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"storedTimeStamp\",\"type\":\"uint256\"}],\"name\":\"StaleKeystoneUpdate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"reportId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission\",\"name\":\"permission\",\"type\":\"tuple\"}],\"name\":\"ReportPermissionSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structFeeQuoter.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structFeeQuoter.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"processPoolReturnData\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"destExecDataPerToken\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission[]\",\"name\":\"permissions\",\"type\":\"tuple[]\"}],\"name\":\"setReportPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b506040516200775238038062007752833981016040819052620000349162001834565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a5a565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b26565b5050505050505062001ae5565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001953565b60209081029190910101519050620002f560028262000e5f565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001953565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000e7f565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001953565b6020026020010151600b62000e7f60201b90919060201c565b1562000499578281815181106200045b576200045b62001953565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001953565b6020026020010151600b62000e9660201b90919060201c565b156200053b57818181518110620004fd57620004fd62001953565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001953565b6020908102919091018101518051818301516001600160a01b0380831660008181526007875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001953565b6020026020010151905060008383815181106200065f576200065f62001953565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061016081015163ffffffff16155b80620006ba57506101e08101516001600160e01b031916630a04b54b60e21b14155b80620006da5750806060015163ffffffff1681610160015163ffffffff16115b15620007055760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260096020526040812060010154600160881b900460e01b6001600160e01b03191690036200078557816001600160401b03167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb7248260405162000777919062001969565b60405180910390a2620007c9565b816001600160401b03167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab2082604051620007c0919062001969565b60405180910390a25b8060096000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a8154816001600160401b0302191690836001600160401b031602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000a7e5762000a7e62001953565b6020026020010151600001519050600083838151811062000aa35762000aa362001953565b6020908102919091018101518101516001600160a01b03841660008181526008845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a5d565b60005b825181101562000d9957600083828151811062000b4a5762000b4a62001953565b6020026020010151905060008160000151905060005b82602001515181101562000d8a5760008360200151828151811062000b895762000b8962001953565b602002602001015160200151905060008460200151838151811062000bb25762000bb262001953565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c115760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000d77908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000b60565b50505080600101905062000b29565b5060005b81518110156200054457600082828151811062000dbe5762000dbe62001953565b6020026020010151600001519050600083838151811062000de35762000de362001953565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000d9d565b600062000e76836001600160a01b03841662000ead565b90505b92915050565b600062000e76836001600160a01b03841662000fb1565b600062000e76836001600160a01b03841662001003565b6000818152600183016020526040812054801562000fa657600062000ed460018362001aad565b855490915060009062000eea9060019062001aad565b905081811462000f5657600086600001828154811062000f0e5762000f0e62001953565b906000526020600020015490508087600001848154811062000f345762000f3462001953565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f6a5762000f6a62001acf565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e79565b600091505062000e79565b600081815260018301602052604081205462000ffa5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e79565b50600062000e79565b6000818152600183016020526040812054801562000fa65760006200102a60018362001aad565b8554909150600090620010409060019062001aad565b905080821462000f5657600086600001828154811062000f0e5762000f0e62001953565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200109f576200109f62001064565b60405290565b60405160c081016001600160401b03811182821017156200109f576200109f62001064565b60405161020081016001600160401b03811182821017156200109f576200109f62001064565b604051601f8201601f191681016001600160401b03811182821017156200111b576200111b62001064565b604052919050565b80516001600160a01b03811681146200113b57600080fd5b919050565b805163ffffffff811681146200113b57600080fd5b6000606082840312156200116857600080fd5b604051606081016001600160401b03811182821017156200118d576200118d62001064565b604052825190915081906001600160601b0381168114620011ad57600080fd5b8152620011bd6020840162001123565b6020820152620011d06040840162001140565b60408201525092915050565b60006001600160401b03821115620011f857620011f862001064565b5060051b60200190565b600082601f8301126200121457600080fd5b815160206200122d6200122783620011dc565b620010f0565b8083825260208201915060208460051b8701019350868411156200125057600080fd5b602086015b848110156200127757620012698162001123565b835291830191830162001255565b509695505050505050565b600082601f8301126200129457600080fd5b81516020620012a76200122783620011dc565b82815260609283028501820192828201919087851115620012c757600080fd5b8387015b858110156200135a5780890382811215620012e65760008081fd5b620012f06200107a565b620012fb8362001123565b8152604080601f1984011215620013125760008081fd5b6200131c6200107a565b92506200132b88850162001123565b835283015160ff81168114620013415760008081fd5b82880152808701919091528452928401928101620012cb565b5090979650505050505050565b80516001600160401b03811681146200113b57600080fd5b805161ffff811681146200113b57600080fd5b805180151581146200113b57600080fd5b600082601f830112620013b557600080fd5b81516020620013c86200122783620011dc565b82815260059290921b84018101918181019086841115620013e857600080fd5b8286015b84811015620012775780516001600160401b03808211156200140d57600080fd5b908801906040601f19838c0381018213156200142857600080fd5b620014326200107a565b6200143f89860162001367565b815282850151848111156200145357600080fd5b8086019550508c603f8601126200146957600080fd5b8885015193506200147e6200122785620011dc565b84815260e09094028501830193898101908e8611156200149d57600080fd5b958401955b858710156200157657868f0360e0811215620014bd57600080fd5b620014c76200107a565b620014d28962001123565b815260c08683011215620014e557600080fd5b620014ef620010a5565b9150620014fe8d8a0162001140565b82526200150d878a0162001140565b8d8301526200151f60608a016200137f565b878301526200153160808a0162001140565b60608301526200154460a08a0162001140565b60808301526200155760c08a0162001392565b60a0830152808d0191909152825260e09690960195908a0190620014a2565b828b015250875250505092840192508301620013ec565b600082601f8301126200159f57600080fd5b81516020620015b26200122783620011dc565b82815260069290921b84018101918181019086841115620015d257600080fd5b8286015b84811015620012775760408189031215620015f15760008081fd5b620015fb6200107a565b620016068262001123565b81526200161585830162001367565b81860152835291830191604001620015d6565b80516001600160e01b0319811681146200113b57600080fd5b600082601f8301126200165357600080fd5b81516020620016666200122783620011dc565b82815261022092830285018201928282019190878511156200168757600080fd5b8387015b858110156200135a5780890382811215620016a65760008081fd5b620016b06200107a565b620016bb8362001367565b815261020080601f1984011215620016d35760008081fd5b620016dd620010ca565b9250620016ec88850162001392565b83526040620016fd8186016200137f565b8985015260606200171081870162001140565b82860152608091506200172582870162001140565b9085015260a06200173886820162001140565b8286015260c091506200174d8287016200137f565b9085015260e06200176086820162001140565b828601526101009150620017768287016200137f565b908501526101206200178a8682016200137f565b828601526101409150620017a08287016200137f565b90850152610160620017b486820162001140565b828601526101809150620017ca82870162001140565b908501526101a0620017de86820162001367565b828601526101c09150620017f482870162001140565b908501526101e06200180886820162001392565b828601526200181983870162001628565b9085015250508087019190915284529284019281016200168b565b6000806000806000806000610120888a0312156200185157600080fd5b6200185d898962001155565b60608901519097506001600160401b03808211156200187b57600080fd5b620018898b838c0162001202565b975060808a0151915080821115620018a057600080fd5b620018ae8b838c0162001202565b965060a08a0151915080821115620018c557600080fd5b620018d38b838c0162001282565b955060c08a0151915080821115620018ea57600080fd5b620018f88b838c01620013a3565b945060e08a01519150808211156200190f57600080fd5b6200191d8b838c016200158d565b93506101008a01519150808211156200193557600080fd5b50620019448a828b0162001641565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610200810160208301516200198a602084018261ffff169052565b506040830151620019a3604084018263ffffffff169052565b506060830151620019bc606084018263ffffffff169052565b506080830151620019d5608084018263ffffffff169052565b5060a0830151620019ec60a084018261ffff169052565b5060c083015162001a0560c084018263ffffffff169052565b5060e083015162001a1c60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501516001600160401b0316908401526101a080850151909116908301526101c0808401511515908301526101e0928301516001600160e01b031916929091019190915290565b8181038181111562000e7957634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051615c1362001b3f600039600081816102ef0152818161220b01526122740152600081816102b301528181611917015261197701526000818161027f015281816119a00152611a100152615c136000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c806379ba509711610104578063a69c64c0116100a2578063d02641a011610071578063d02641a014610a81578063d8694ccd14610a94578063f2fde38b14610aa7578063ffdb4b3714610aba57600080fd5b8063a69c64c014610997578063bf78e03f146109aa578063c4276bfc14610a57578063cdc73d5114610a7957600080fd5b806382b49eb0116100de57806382b49eb0146107d95780638da5cb5b1461094957806391a2749a146109715780639ea600261461098457600080fd5b806379ba5097146107ab5780637afac322146107b3578063805f2132146107c657600080fd5b8063407e1086116101715780634ab35b0b1161014b5780634ab35b0b14610441578063514e8cff146104815780636def4ce714610524578063770e2dc41461079857600080fd5b8063407e1086146103fb57806341ed29e71461040e57806345ac924d1461042157600080fd5b8063085318f8116101ad578063085318f814610368578063181f5a77146103885780632451a627146103d15780633937306f146103e657600080fd5b806241e5be146101d3578063061877e3146101f957806306285c6914610252575b600080fd5b6101e66101e13660046142ca565b610b02565b6040519081526020015b60405180910390f35b610239610207366004614306565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101f0565b61031c604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101f0565b61037b61037636600461437e565b610b70565b6040516101f09190614490565b6103c46040518060400160405280601381526020017f46656551756f74657220312e362e302d6465760000000000000000000000000081525081565b6040516101f09190614512565b6103d9610ee2565b6040516101f09190614525565b6103f96103f436600461457f565b610ef3565b005b6103f9610409366004614721565b6111a8565b6103f961041c366004614853565b6111bc565b61043461042f36600461498e565b6111fe565b6040516101f091906149d0565b61045461044f366004614306565b6112c9565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b61051761048f366004614a4b565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101f09190614a66565b61078b610532366004614a4b565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101919091525067ffffffffffffffff908116600090815260096020908152604091829020825161020081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a085015271010000000000000000000000000000000000808404881660c086015275010000000000000000000000000000000000000000008404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b01000000000000000000000000000000000000000000000000000000909204861661014084015260019093015480861661016084015264010000000081049096166101808301526c0100000000000000000000000086049094166101a0820152700100000000000000000000000000000000850490911615156101c08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b166101e082015290565b6040516101f09190614aa1565b6103f96107a6366004614cb8565b6112d4565b6103f96112e6565b6103f96107c1366004614fd2565b6113e3565b6103f96107d4366004615078565b6113f5565b6108e96107e73660046150e4565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff919091166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101f09190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6103f961097f36600461510e565b6118dd565b6103f96109923660046151cf565b6118ee565b6103f96109a53660046153dc565b6118ff565b610a236109b8366004614306565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526007825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101f0565b610a6a610a653660046154a1565b611910565b6040516101f093929190615510565b6103d9611b06565b610517610a8f366004614306565b611b12565b6101e6610aa2366004615531565b611c0e565b6103f9610ab5366004614306565b612126565b610acd610ac8366004615586565b612137565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101f0565b6000610b0d826122c2565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b34856122c2565b610b5c907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16856155df565b610b6691906155f6565b90505b9392505050565b67ffffffffffffffff8086166000908152600960205260409020600101546060917101000000000000000000000000000000000090910460e01b908590811115610bbc57610bbc6145ba565b604051908082528060200260200182016040528015610bef57816020015b6060815260200190600190039081610bda5790505b50915060005b85811015610ed7576000858583818110610c1157610c11615631565b610c279260206040909202019081019150614306565b90506000888884818110610c3d57610c3d615631565b9050602002810190610c4f9190615660565b610c5d90604081019061569e565b9150506020811115610d125767ffffffffffffffff8a166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115610d12576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b610d82848a8a86818110610d2857610d28615631565b9050602002810190610d3a9190615660565b610d4890602081019061569e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061235c92505050565b67ffffffffffffffff8a166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320815160c081018352905463ffffffff8082168352640100000000820481168386015268010000000000000000820461ffff16838501526a01000000000000000000008204811660608401526e010000000000000000000000000000820481166080840152720100000000000000000000000000000000000090910460ff16151560a08301908152958552600990935290832054935190937b0100000000000000000000000000000000000000000000000000000090049091169190610e815781610e87565b82606001515b6040805163ffffffff8316602082015291925001604051602081830303815290604052888781518110610ebc57610ebc615631565b60200260200101819052505050505050806001019050610bf5565b505095945050505050565b6060610eee60026123b3565b905090565b610efb6123c0565b6000610f078280615703565b9050905060005b81811015611051576000610f228480615703565b83818110610f3257610f32615631565b905060400201803603810190610f489190615797565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600690975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926110409290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610f0e565b5060006110616020840184615703565b9050905060005b818110156111a257600061107f6020860186615703565b8381811061108f5761108f615631565b9050604002018036038101906110a591906157d4565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e926111919290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101611068565b50505050565b6111b0612405565b6111b981612486565b50565b6111c4612405565b60005b81518110156111fa576111f28282815181106111e5576111e5615631565b6020026020010151612584565b6001016111c7565b5050565b60608160008167ffffffffffffffff81111561121c5761121c6145ba565b60405190808252806020026020018201604052801561126157816020015b604080518082019091526000808252602082015281526020019060019003908161123a5790505b50905060005b828110156112be5761129986868381811061128457611284615631565b9050602002016020810190610a8f9190614306565b8282815181106112ab576112ab615631565b6020908102919091010152600101611267565b509150505b92915050565b60006112c3826122c2565b6112dc612405565b6111fa8282612756565b60015473ffffffffffffffffffffffffffffffffffffffff163314611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610d09565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6113eb612405565b6111fa8282612b63565b600080600061143987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612caa92505050565b92509250925061144b33838584612cc5565b6000611459858701876157f7565b905060005b81518110156118d25760006007600084848151811061147f5761147f615631565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160009081205474010000000000000000000000000000000000000000900460ff169150819003611540578282815181106114e9576114e9615631565b6020908102919091010151516040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b600061158960128386868151811061155a5761155a615631565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612e1d565b9050600660008585815181106115a1576115a1615631565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff1684848151811061161357611613615631565b60200260200101516040015163ffffffff16101561171d5783838151811061163d5761163d615631565b60200260200101516000015184848151811061165b5761165b615631565b6020026020010151604001516006600087878151811061167d5761167d615631565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260409081016000205490517f191ec70600000000000000000000000000000000000000000000000000000000815293909116600484015263ffffffff91821660248401527c01000000000000000000000000000000000000000000000000000000009004166044820152606401610d09565b6040518060400160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260200185858151811061175e5761175e615631565b60200260200101516040015163ffffffff168152506006600086868151811061178957611789615631565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179055835184908490811061182157611821615631565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff167f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a8286868151811061187757611877615631565b6020026020010151604001516040516118c09291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a2505060010161145e565b505050505050505050565b6118e5612405565b6111b981612ee3565b6118f6612405565b6111b98161306f565b611907612405565b6111b981613515565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036119705785925061199e565b61199b87877f0000000000000000000000000000000000000000000000000000000000000000610b02565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611a3d576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610d09565b67ffffffffffffffff881660009081526009602052604081206001015463ffffffff1690611a6c8787846135ff565b9050806020015193508484611af3836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b6060610eee600b6123b3565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600760209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff169082015290611c0557505073ffffffffffffffffffffffffffffffffffffffff166000908152600660209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b69816137a8565b67ffffffffffffffff8083166000908152600960209081526040808320815161020081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a086015271010000000000000000000000000000000000808504881660c087015275010000000000000000000000000000000000000000008504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b01000000000000000000000000000000000000000000000000000000909304861661014085015260019094015480861661016085015264010000000081049098166101808401526c0100000000000000000000000088049094166101a0830152700100000000000000000000000000000000870490931615156101c08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b166101e0840152909190611e28576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b611e43611e3b6080850160608601614306565b600b90613937565b611ea257611e576080840160608501614306565b6040517f2502348c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b6000611eb16040850185615703565b9150611f0d905082611ec6602087018761569e565b905083611ed3888061569e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061396692505050565b6000600881611f226080880160608901614306565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff16915080611f71611f6b6080890160608a01614306565b89612137565b9092509050600080808615611fb757611fab888c611f9560808e0160608f01614306565b888e8060400190611fa69190615703565b613a10565b91945092509050611fd7565b6101a0880151611fd49063ffffffff16662386f26fc100006155df565b92505b61010088015160009061ffff161561201b57612018896dffffffffffffffffffffffffffff607088901c1661200f60208f018f61569e565b90508b86613ce8565b90505b61018089015160009067ffffffffffffffff1661204461203e60808f018f61569e565b8d613d98565b600001518563ffffffff168c60a0015161ffff168f8060200190612068919061569e565b6120739291506155df565b8d6080015163ffffffff1661208891906158be565b61209291906158be565b61209c91906158be565b6120b6906dffffffffffffffffffffffffffff89166155df565b6120c091906155df565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff871682826120f767ffffffffffffffff8c16896155df565b61210191906158be565b61210b91906158be565b61211591906155f6565b9d9c50505050505050505050505050565b61212e612405565b6111b981613e59565b67ffffffffffffffff811660009081526005602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff16918101829052829182036121ef576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000816020015163ffffffff164261220791906158d1565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168111156122a8576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610d09565b6122b1866122c2565b9151919350909150505b9250929050565b6000806122ce83611b12565b9050806020015163ffffffff1660001480612306575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15612355576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610d09565b5192915050565b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016111fa576123ae81613f4e565b505050565b60606000610b6983614001565b6123cb600233613937565b612403576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610d09565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314612403576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d09565b60005b81518110156111fa5760008282815181106124a6576124a6615631565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526007875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a2505050806001019050612489565b600061263d82600001518360600151846020015185604001516040805173ffffffffffffffffffffffffffffffffffffffff80871660208301528516918101919091527fffffffffffffffffffff00000000000000000000000000000000000000000000831660608201527fffff0000000000000000000000000000000000000000000000000000000000008216608082015260009060a001604051602081830303815290604052805190602001209050949350505050565b60808301516000828152600460205260409081902080549215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316929092179091555190915081907f32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a39061274a908590600060a08201905073ffffffffffffffffffffffffffffffffffffffff8084511683527fffffffffffffffffffff0000000000000000000000000000000000000000000060208501511660208401527fffff00000000000000000000000000000000000000000000000000000000000060408501511660408401528060608501511660608401525060808301511515608083015292915050565b60405180910390a25050565b60005b8251811015612a7f57600083828151811061277657612776615631565b6020026020010151905060008160000151905060005b826020015151811015612a71576000836020015182815181106127b1576127b1615631565b60200260200101516020015190506000846020015183815181106127d7576127d7615631565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101561285a5760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610d09565b67ffffffffffffffff84166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b590612a5f908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010161278c565b505050806001019050612759565b5060005b81518110156123ae576000828281518110612aa057612aa0615631565b60200260200101516000015190506000838381518110612ac257612ac2615631565b60209081029190910181015181015167ffffffffffffffff84166000818152600a8452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612a83565b60005b8251811015612c0657612b9c838281518110612b8457612b84615631565b6020026020010151600b61405d90919063ffffffff16565b15612bfe57828181518110612bb357612bb3615631565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b600101612b66565b5060005b81518110156123ae57612c40828281518110612c2857612c28615631565b6020026020010151600b61407f90919063ffffffff16565b15612ca257818181518110612c5757612c57615631565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101612c0a565b6040810151604a820151605e90920151909260609290921c91565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602080840191909152908616828401527fffffffffffffffffffff00000000000000000000000000000000000000000000851660608301527fffff00000000000000000000000000000000000000000000000000000000000084166080808401919091528351808403909101815260a09092018352815191810191909120600081815260049092529190205460ff16612e16576040517f097e17ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8087166004830152851660248201527fffffffffffffffffffff00000000000000000000000000000000000000000000841660448201527fffff00000000000000000000000000000000000000000000000000000000000083166064820152608401610d09565b5050505050565b600080612e2a84866158e4565b9050600060248260ff161115612e6157612e456024836158fd565b612e5090600a615a36565b612e5a90856155f6565b9050612e84565b612e6c8260246158fd565b612e7790600a615a36565b612e8190856155df565b90505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612eda576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b95945050505050565b602081015160005b8151811015612f7e576000828281518110612f0857612f08615631565b60200260200101519050612f268160026140a190919063ffffffff16565b15612f755760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612eeb565b50815160005b81518110156111a2576000828281518110612fa157612fa1615631565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613011576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61301c60028261405d565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101612f84565b60005b81518110156111fa57600082828151811061308f5761308f615631565b6020026020010151905060008383815181106130ad576130ad615631565b60200260200101516000015190506000826020015190508167ffffffffffffffff16600014806130e6575061016081015163ffffffff16155b8061313857506101e08101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806131575750806060015163ffffffff1681610160015163ffffffff16115b1561319a576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610d09565b67ffffffffffffffff821660009081526009602052604081206001015471010000000000000000000000000000000000900460e01b7fffffffff0000000000000000000000000000000000000000000000000000000016900361323e578167ffffffffffffffff167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb724826040516132319190614aa1565b60405180910390a2613281565b8167ffffffffffffffff167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab20826040516132789190614aa1565b60405180910390a25b80600960008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050613072565b60005b81518110156111fa57600082828151811061353557613535615631565b6020026020010151600001519050600083838151811061355757613557615631565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526008845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a25050600101613518565b6040805180820190915260008082526020820152600083900361364057506040805180820190915267ffffffffffffffff8216815260006020820152610b69565b600061364c8486615a45565b9050600061365d8560048189615a8b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f000000000000000000000000000000000000000000000000000000000016136fa57808060200190518101906136f19190615ab5565b92505050610b69565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601613776576040518060400160405280828060200190518101906137629190615ae1565b815260006020909101529250610b69915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613812573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138369190615b14565b5050509150506000811215613877576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006138f68373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156138c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138eb9190615b64565b866020015184612e1d565b604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff4216602082015295945050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b69565b836040015163ffffffff168311156139bf5760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610d09565b836020015161ffff16821115613a01576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111a2846101e001518261235c565b6000808083815b81811015613cda576000878783818110613a3357613a33615631565b905060400201803603810190613a499190615b81565b67ffffffffffffffff8c166000908152600a60209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090613b69576101208d0151613b369061ffff16662386f26fc100006155df565b613b4090886158be565b96508c610140015186613b539190615bba565b9550613b60602086615bba565b94505050613cd2565b604081015160009061ffff1615613c225760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614613bc5578351613bbe906122c2565b9050613bc8565b508a5b620186a0836040015161ffff16613c0a8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166140c390919063ffffffff16565b613c1491906155df565b613c1e91906155f6565b9150505b6060820151613c319088615bba565b9650816080015186613c439190615bba565b8251909650600090613c629063ffffffff16662386f26fc100006155df565b905080821015613c8157613c76818a6158be565b985050505050613cd2565b6000836020015163ffffffff16662386f26fc10000613ca091906155df565b905080831115613cc057613cb4818b6158be565b99505050505050613cd2565b613cca838b6158be565b995050505050505b600101613a17565b505096509650969350505050565b60008063ffffffff8316613cfe610160866155df565b613d0a876101c06158be565b613d1491906158be565b613d1e91906158be565b905060008760c0015163ffffffff168860e0015161ffff1683613d4191906155df565b613d4b91906158be565b61010089015190915061ffff16613d726dffffffffffffffffffffffffffff8916836155df565b613d7c91906155df565b613d8c90655af3107a40006155df565b98975050505050505050565b60408051808201909152600080825260208201526000613dc4858585610160015163ffffffff166135ff565b9050826060015163ffffffff1681600001511115613e0e576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101c001518015613e2257508060200151155b15610b66576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603613ed8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d09565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008151602014613f8d57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614512565b600082806020019051810190613fa39190615ae1565b905073ffffffffffffffffffffffffffffffffffffffff811180613fc8575061040081105b156112c357826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614512565b60608160000180548060200260200160405190810160405280929190818152602001828054801561405157602002820191906000526020600020905b81548152602001906001019080831161403d575b50505050509050919050565b6000610b698373ffffffffffffffffffffffffffffffffffffffff8416614100565b6000610b698373ffffffffffffffffffffffffffffffffffffffff841661414f565b6000610b698373ffffffffffffffffffffffffffffffffffffffff8416614249565b6000670de0b6b3a76400006140f6837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166155df565b610b6991906155f6565b6000818152600183016020526040812054614147575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112c3565b5060006112c3565b600081815260018301602052604081205480156142385760006141736001836158d1565b8554909150600090614187906001906158d1565b90508082146141ec5760008660000182815481106141a7576141a7615631565b90600052602060002001549050808760000184815481106141ca576141ca615631565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806141fd576141fd615bd7565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112c3565b60009150506112c3565b5092915050565b6000818152600183016020526040812054801561423857600061426d6001836158d1565b8554909150600090614281906001906158d1565b90508181146141ec5760008660000182815481106141a7576141a7615631565b803573ffffffffffffffffffffffffffffffffffffffff811681146142c557600080fd5b919050565b6000806000606084860312156142df57600080fd5b6142e8846142a1565b9250602084013591506142fd604085016142a1565b90509250925092565b60006020828403121561431857600080fd5b610b69826142a1565b803567ffffffffffffffff811681146142c557600080fd5b60008083601f84011261434b57600080fd5b50813567ffffffffffffffff81111561436357600080fd5b6020830191508360208260051b85010111156122bb57600080fd5b60008060008060006060868803121561439657600080fd5b61439f86614321565b9450602086013567ffffffffffffffff808211156143bc57600080fd5b6143c889838a01614339565b909650945060408801359150808211156143e157600080fd5b818801915088601f8301126143f557600080fd5b81358181111561440457600080fd5b8960208260061b850101111561441957600080fd5b9699959850939650602001949392505050565b6000815180845260005b8181101561445257602081850181015186830182015201614436565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614505577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526144f385835161442c565b945092850192908501906001016144b9565b5092979650505050505050565b602081526000610b69602083018461442c565b6020808252825182820181905260009190848201906040850190845b8181101561457357835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614541565b50909695505050505050565b60006020828403121561459157600080fd5b813567ffffffffffffffff8111156145a857600080fd5b820160408185031215610b6957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561460c5761460c6145ba565b60405290565b60405160a0810167ffffffffffffffff8111828210171561460c5761460c6145ba565b60405160c0810167ffffffffffffffff8111828210171561460c5761460c6145ba565b604051610200810167ffffffffffffffff8111828210171561460c5761460c6145ba565b6040516060810167ffffffffffffffff8111828210171561460c5761460c6145ba565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156146e6576146e66145ba565b604052919050565b600067ffffffffffffffff821115614708576147086145ba565b5060051b60200190565b60ff811681146111b957600080fd5b6000602080838503121561473457600080fd5b823567ffffffffffffffff81111561474b57600080fd5b8301601f8101851361475c57600080fd5b803561476f61476a826146ee565b61469f565b8181526060918202830184019184820191908884111561478e57600080fd5b938501935b8385101561482e57848903818112156147ac5760008081fd5b6147b46145e9565b6147bd876142a1565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147f15760008081fd5b6147f96145e9565b92506148068989016142a1565b835287013561481481614712565b828901528088019190915283529384019391850191614793565b50979650505050505050565b80151581146111b957600080fd5b80356142c58161483a565b6000602080838503121561486657600080fd5b823567ffffffffffffffff81111561487d57600080fd5b8301601f8101851361488e57600080fd5b803561489c61476a826146ee565b81815260a091820283018401918482019190888411156148bb57600080fd5b938501935b8385101561482e5780858a0312156148d85760008081fd5b6148e0614612565b6148e9866142a1565b8152868601357fffffffffffffffffffff000000000000000000000000000000000000000000008116811461491e5760008081fd5b818801526040868101357fffff000000000000000000000000000000000000000000000000000000000000811681146149575760008081fd5b9082015260606149688782016142a1565b9082015260808681013561497b8161483a565b90820152835293840193918501916148c0565b600080602083850312156149a157600080fd5b823567ffffffffffffffff8111156149b857600080fd5b6149c485828601614339565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b82811015614a3e57614a2e84835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b92840192908501906001016149ed565b5091979650505050505050565b600060208284031215614a5d57600080fd5b610b6982614321565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff1690820152604081016112c3565b81511515815261020081016020830151614ac1602084018261ffff169052565b506040830151614ad9604084018263ffffffff169052565b506060830151614af1606084018263ffffffff169052565b506080830151614b09608084018263ffffffff169052565b5060a0830151614b1f60a084018261ffff169052565b5060c0830151614b3760c084018263ffffffff169052565b5060e0830151614b4d60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff90811691840191909152610160808501518216908401526101808085015167ffffffffffffffff16908401526101a080850151909116908301526101c0808401511515908301526101e0808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff811681146142c557600080fd5b803561ffff811681146142c557600080fd5b600082601f830112614c3157600080fd5b81356020614c4161476a836146ee565b82815260069290921b84018101918181019086841115614c6057600080fd5b8286015b84811015614cad5760408189031215614c7d5760008081fd5b614c856145e9565b614c8e82614321565b8152614c9b8583016142a1565b81860152835291830191604001614c64565b509695505050505050565b60008060408385031215614ccb57600080fd5b67ffffffffffffffff83351115614ce157600080fd5b83601f843585010112614cf357600080fd5b614d0361476a84358501356146ee565b8335840180358083526020808401939260059290921b90910101861015614d2957600080fd5b602085358601015b85358601803560051b01602001811015614f365767ffffffffffffffff81351115614d5b57600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a03011215614d9457600080fd5b614d9c6145e9565b614da860208301614321565b815267ffffffffffffffff60408301351115614dc357600080fd5b88603f604084013584010112614dd857600080fd5b614dee61476a60206040850135850101356146ee565b6020604084810135850182810135808552928401939260e00201018b1015614e1557600080fd5b6040808501358501015b6040858101358601602081013560e0020101811015614f175760e0818d031215614e4857600080fd5b614e506145e9565b614e59826142a1565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215614e8d57600080fd5b614e95614635565b614ea160208401614bfa565b8152614eaf60408401614bfa565b6020820152614ec060608401614c0e565b6040820152614ed160808401614bfa565b6060820152614ee260a08401614bfa565b6080820152614ef460c084013561483a565b60c083013560a0820152602082810191909152908452929092019160e001614e1f565b5080602084015250508085525050602083019250602081019050614d31565b5092505067ffffffffffffffff60208401351115614f5357600080fd5b614f638460208501358501614c20565b90509250929050565b600082601f830112614f7d57600080fd5b81356020614f8d61476a836146ee565b8083825260208201915060208460051b870101935086841115614faf57600080fd5b602086015b84811015614cad57614fc5816142a1565b8352918301918301614fb4565b60008060408385031215614fe557600080fd5b823567ffffffffffffffff80821115614ffd57600080fd5b61500986838701614f6c565b9350602085013591508082111561501f57600080fd5b5061502c85828601614f6c565b9150509250929050565b60008083601f84011261504857600080fd5b50813567ffffffffffffffff81111561506057600080fd5b6020830191508360208285010111156122bb57600080fd5b6000806000806040858703121561508e57600080fd5b843567ffffffffffffffff808211156150a657600080fd5b6150b288838901615036565b909650945060208701359150808211156150cb57600080fd5b506150d887828801615036565b95989497509550505050565b600080604083850312156150f757600080fd5b61510083614321565b9150614f63602084016142a1565b60006020828403121561512057600080fd5b813567ffffffffffffffff8082111561513857600080fd5b908301906040828603121561514c57600080fd5b6151546145e9565b82358281111561516357600080fd5b61516f87828601614f6c565b82525060208301358281111561518457600080fd5b61519087828601614f6c565b60208301525095945050505050565b80357fffffffff00000000000000000000000000000000000000000000000000000000811681146142c557600080fd5b600060208083850312156151e257600080fd5b823567ffffffffffffffff8111156151f957600080fd5b8301601f8101851361520a57600080fd5b803561521861476a826146ee565b818152610220918202830184019184820191908884111561523857600080fd5b938501935b8385101561482e57848903818112156152565760008081fd5b61525e6145e9565b61526787614321565b8152610200807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08401121561529c5760008081fd5b6152a4614658565b92506152b1898901614848565b835260406152c0818a01614c0e565b8a85015260606152d1818b01614bfa565b82860152608091506152e4828b01614bfa565b9085015260a06152f58a8201614bfa565b8286015260c09150615308828b01614c0e565b9085015260e06153198a8201614bfa565b82860152610100915061532d828b01614c0e565b9085015261012061533f8a8201614c0e565b828601526101409150615353828b01614c0e565b908501526101606153658a8201614bfa565b828601526101809150615379828b01614bfa565b908501526101a061538b8a8201614321565b828601526101c0915061539f828b01614bfa565b908501526101e06153b18a8201614848565b828601526153c0838b0161519f565b908501525050808801919091528352938401939185019161523d565b600060208083850312156153ef57600080fd5b823567ffffffffffffffff81111561540657600080fd5b8301601f8101851361541757600080fd5b803561542561476a826146ee565b81815260069190911b8201830190838101908783111561544457600080fd5b928401925b8284101561549657604084890312156154625760008081fd5b61546a6145e9565b615473856142a1565b8152615480868601614321565b8187015282526040939093019290840190615449565b979650505050505050565b6000806000806000608086880312156154b957600080fd5b6154c286614321565b94506154d0602087016142a1565b935060408601359250606086013567ffffffffffffffff8111156154f357600080fd5b6154ff88828901615036565b969995985093965092949392505050565b8381528215156020820152606060408201526000612eda606083018461442c565b6000806040838503121561554457600080fd5b61554d83614321565b9150602083013567ffffffffffffffff81111561556957600080fd5b830160a0818603121561557b57600080fd5b809150509250929050565b6000806040838503121561559957600080fd5b6155a2836142a1565b9150614f6360208401614321565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176112c3576112c36155b0565b60008261562c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261569457600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126156d357600080fd5b83018035915067ffffffffffffffff8211156156ee57600080fd5b6020019150368190038213156122bb57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261573857600080fd5b83018035915067ffffffffffffffff82111561575357600080fd5b6020019150600681901b36038213156122bb57600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146142c557600080fd5b6000604082840312156157a957600080fd5b6157b16145e9565b6157ba836142a1565b81526157c86020840161576b565b60208201529392505050565b6000604082840312156157e657600080fd5b6157ee6145e9565b6157ba83614321565b6000602080838503121561580a57600080fd5b823567ffffffffffffffff81111561582157600080fd5b8301601f8101851361583257600080fd5b803561584061476a826146ee565b8181526060918202830184019184820191908884111561585f57600080fd5b938501935b8385101561482e5780858a03121561587c5760008081fd5b61588461467c565b61588d866142a1565b815261589a87870161576b565b8782015260406158ab818801614bfa565b9082015283529384019391850191615864565b808201808211156112c3576112c36155b0565b818103818111156112c3576112c36155b0565b60ff81811683821601908111156112c3576112c36155b0565b60ff82811682821603908111156112c3576112c36155b0565b600181815b8085111561596f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615955576159556155b0565b8085161561596257918102915b93841c939080029061591b565b509250929050565b600082615986575060016112c3565b81615993575060006112c3565b81600181146159a957600281146159b3576159cf565b60019150506112c3565b60ff8411156159c4576159c46155b0565b50506001821b6112c3565b5060208310610133831016604e8410600b84101617156159f2575081810a6112c3565b6159fc8383615916565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615a2e57615a2e6155b0565b029392505050565b6000610b6960ff841683615977565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015614bf25760049490940360031b84901b1690921692915050565b60008085851115615a9b57600080fd5b83861115615aa857600080fd5b5050820193919092039150565b600060408284031215615ac757600080fd5b615acf6145e9565b8251815260208301516157c88161483a565b600060208284031215615af357600080fd5b5051919050565b805169ffffffffffffffffffff811681146142c557600080fd5b600080600080600060a08688031215615b2c57600080fd5b615b3586615afa565b9450602086015193506040860151925060608601519150615b5860808701615afa565b90509295509295909350565b600060208284031215615b7657600080fd5b8151610b6981614712565b600060408284031215615b9357600080fd5b615b9b6145e9565b615ba4836142a1565b8152602083013560208201528091505092915050565b63ffffffff818116838216019080821115614242576142426155b0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var FeeQuoterABI = FeeQuoterMetaData.ABI diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index f8a7a120af..afbdd51c79 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -11,7 +11,7 @@ commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitSto ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin b0d77babbe635cd6ba04c2af049badc9e9d28a4b6ed6bb75f830ad902a618beb evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 5c02c2b167946b3467636ff2bb58594cb4652fc63d8bdfee2488ed562e2a3e50 -fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin 95cdd54835272004bbe4a469b8529aa6f92ece2f903d914615010f1bf80a16c8 +fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin 920b7a293165fe8306fbed0cafd866bafc5943e8759486f7803bfbbd40309b6b lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin e6a8ec9e8faccb1da7d90e0f702ed72975964f97dc3222b54cfcca0a0ba3fea2 lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin e632b08be0fbd1d013e8b3a9d75293d0d532b83071c531ff2be1deec1fa48ec1 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 From 3dd8a72e929d6964c268d0e6b71bc22036501bbf Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Thu, 29 Aug 2024 16:23:49 +0200 Subject: [PATCH 255/432] pnpm i && snapshot && forge fmt --- contracts/gas-snapshots/ccip.gas-snapshot | 60 +-- .../gas-snapshots/functions.gas-snapshot | 234 ++++++------ contracts/gas-snapshots/keystone.gas-snapshot | 179 +++++---- .../gas-snapshots/llo-feeds.gas-snapshot | 244 ------------- contracts/gas-snapshots/shared.gas-snapshot | 4 +- contracts/pnpm-lock.yaml | 343 +++++++++++++++++- contracts/src/v0.8/ccip/FeeQuoter.sol | 35 +- .../v0.8/ccip/MultiAggregateRateLimiter.sol | 8 +- contracts/src/v0.8/ccip/RMN.sol | 12 +- .../ccip/applications/CCIPClientExample.sol | 10 +- .../ccip/applications/DefensiveExample.sol | 17 +- .../ccip/applications/EtherSenderReceiver.sol | 8 +- .../v0.8/ccip/applications/PingPongDemo.sol | 2 +- .../src/v0.8/ccip/capability/CCIPConfig.sol | 4 +- contracts/src/v0.8/ccip/interfaces/IPool.sol | 12 +- .../v0.8/ccip/interfaces/IPriceRegistry.sol | 7 +- .../src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol | 8 +- contracts/src/v0.8/ccip/onRamp/OnRamp.sol | 8 +- .../ccip/pools/BurnMintTokenPoolAbstract.sol | 18 +- .../ccip/pools/BurnMintTokenPoolAndProxy.sol | 18 +- .../BurnWithFromMintTokenPoolAndProxy.sol | 18 +- .../v0.8/ccip/pools/LockReleaseTokenPool.sol | 18 +- .../pools/LockReleaseTokenPoolAndProxy.sol | 18 +- contracts/src/v0.8/ccip/pools/TokenPool.sol | 16 +- .../USDC/HybridLockReleaseUSDCTokenPool.sol | 34 +- .../v0.8/ccip/pools/USDC/USDCTokenPool.sol | 18 +- .../src/v0.8/ccip/test/NonceManager.t.sol | 8 +- .../onRamp/ReentrantMaliciousTokenPool.sol | 17 +- .../ccip/test/capability/CCIPConfig.t.sol | 7 +- .../v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol | 6 +- .../test/helpers/BurnMintMultiTokenPool.sol | 18 +- .../ccip/test/helpers/CCIPConfigHelper.sol | 4 +- .../MaybeRevertingBurnMintTokenPool.sol | 18 +- .../v0.8/ccip/test/helpers/MessageHasher.sol | 8 +- .../ccip/test/helpers/TokenPoolHelper.sol | 18 +- .../helpers/receivers/ReentrancyAbuser.sol | 8 +- .../ccip/test/legacy/BurnMintTokenPool1_4.sol | 16 +- .../test/offRamp/EVM2EVMOffRampSetup.t.sol | 40 +- .../src/v0.8/ccip/test/offRamp/OffRamp.t.sol | 6 +- .../v0.8/ccip/test/offRamp/OffRampSetup.t.sol | 24 +- .../v0.8/ccip/test/pools/USDCTokenPool.t.sol | 8 +- .../MultiAggregateRateLimiter.t.sol | 16 +- 42 files changed, 763 insertions(+), 812 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 97609ff3aa..1658bd8dcb 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -103,7 +103,7 @@ CommitStore_report:test_OnlyPriceUpdateStaleReport_Revert() (gas: 59071) CommitStore_report:test_OnlyTokenPriceUpdates_Success() (gas: 53273) CommitStore_report:test_Paused_Revert() (gas: 21259) CommitStore_report:test_ReportAndPriceUpdate_Success() (gas: 84264) -CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56313) +CommitStore_report:test_ReportOnlyRootSuccess_gas() (gas: 56249) CommitStore_report:test_RootAlreadyCommitted_Revert() (gas: 63969) CommitStore_report:test_StaleReportWithRoot_Success() (gas: 119364) CommitStore_report:test_Unhealthy_Revert() (gas: 44751) @@ -123,7 +123,7 @@ CommitStore_verify:test_Paused_Revert() (gas: 18496) CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424256) -E2E:test_E2E_3MessagesSuccess_gas() (gas: 1104033) +E2E:test_E2E_3MessagesSuccess_gas() (gas: 1100023) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37797) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103733) EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85258) @@ -162,13 +162,13 @@ EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 42539) EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 157347) EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 172692) EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 247069) -EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 114153) +EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 113842) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 407451) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54096) EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 131047) EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52090) EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 563385) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 495508) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 494182) EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35383) EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 544641) EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64326) @@ -178,7 +178,7 @@ EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 427337) EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18502) EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 278097) EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 18659) -EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 221421) +EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 223921) EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47881) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 47352) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 313917) @@ -230,21 +230,21 @@ EVM2EVMOnRamp_forwardFromRouter:test_MaxFeeBalanceReached_Revert() (gas: 36457) EVM2EVMOnRamp_forwardFromRouter:test_MessageGasLimitTooHigh_Revert() (gas: 29015) EVM2EVMOnRamp_forwardFromRouter:test_MessageTooLarge_Revert() (gas: 107571) EVM2EVMOnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 22679) -EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 224619) +EVM2EVMOnRamp_forwardFromRouter:test_OverValueWithARLOff_Success() (gas: 227119) EVM2EVMOnRamp_forwardFromRouter:test_Paused_Revert() (gas: 53072) EVM2EVMOnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 25481) EVM2EVMOnRamp_forwardFromRouter:test_PriceNotFoundForToken_Revert() (gas: 59341) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 179148) EVM2EVMOnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 177430) EVM2EVMOnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 137254) -EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3822827) +EVM2EVMOnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3825327) EVM2EVMOnRamp_forwardFromRouter:test_TooManyTokens_Revert() (gas: 30187) EVM2EVMOnRamp_forwardFromRouter:test_Unhealthy_Revert() (gas: 43300) EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109305) EVM2EVMOnRamp_forwardFromRouter:test_ZeroAddressReceiver_Revert() (gas: 312579) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_ShouldStoreLinkFees_Success() (gas: 112322) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 72206) -EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 710475) +EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 712975) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 147664) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 190529) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 121320) @@ -276,7 +276,7 @@ EVM2EVMOnRamp_getTokenTransferCost:test__getTokenTransferCost_selfServeUsesDefau EVM2EVMOnRamp_linkAvailableForPayment:test_InsufficientLinkBalance_Success() (gas: 32615) EVM2EVMOnRamp_linkAvailableForPayment:test_LinkAvailableForPayment_Success() (gas: 134833) EVM2EVMOnRamp_payNops:test_AdminPayNops_Success() (gas: 143159) -EVM2EVMOnRamp_payNops:test_InsufficientBalance_Revert() (gas: 26543) +EVM2EVMOnRamp_payNops:test_InsufficientBalance_Revert() (gas: 29043) EVM2EVMOnRamp_payNops:test_NoFeesToPay_Revert() (gas: 127367) EVM2EVMOnRamp_payNops:test_NoNopsToPay_Revert() (gas: 133251) EVM2EVMOnRamp_payNops:test_NopPayNops_Success() (gas: 146446) @@ -308,7 +308,7 @@ EVM2EVMOnRamp_withdrawNonLinkFees:test_SettlingBalance_Success() (gas: 272035) EVM2EVMOnRamp_withdrawNonLinkFees:test_WithdrawNonLinkFees_Success() (gas: 53446) EVM2EVMOnRamp_withdrawNonLinkFees:test_WithdrawToZeroAddress_Revert() (gas: 12830) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_fallbackToWethTransfer() (gas: 96729) -EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 47688) +EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 49688) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongToken() (gas: 17384) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongTokenAmount() (gas: 15677) EtherSenderReceiverTest_ccipSend:test_ccipSend_reverts_insufficientFee_feeToken() (gas: 99741) @@ -515,7 +515,7 @@ MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitExce MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithRateLimitReset_Success() (gas: 78668) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokensOnDifferentChains_Success() (gas: 311927) MultiAggregateRateLimiter_onInboundMessage:test_ValidateMessageWithTokens_Success() (gas: 54728) -MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 9223372036854754743) +MultiAggregateRateLimiter_onOutboundMessage:test_RateLimitValueDifferentLanes_Success() (gas: 1073667529) MultiAggregateRateLimiter_onOutboundMessage:test_ValidateMessageWithNoTokens_Success() (gas: 19149) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageFromUnauthorizedCaller_Revert() (gas: 15823) MultiAggregateRateLimiter_onOutboundMessage:test_onOutboundMessage_ValidateMessageWithDifferentTokensOnDifferentChains_Success() (gas: 213716) @@ -557,16 +557,16 @@ MultiOCR3Base_transmit:test_InsufficientSignatures_Revert() (gas: 76930) MultiOCR3Base_transmit:test_NonUniqueSignature_Revert() (gas: 66127) MultiOCR3Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 33419) MultiOCR3Base_transmit:test_TooManySignatures_Revert() (gas: 79521) -MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34131) +MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34020) MultiOCR3Base_transmit:test_TransmitWithExtraCalldataArgs_Revert() (gas: 47114) MultiOCR3Base_transmit:test_TransmitWithLessCalldataArgs_Revert() (gas: 25682) -MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18726) +MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18714) MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 414301) -MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1506106) +MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1501445) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) @@ -596,7 +596,7 @@ OCR2BaseNoChecks_setOCR2Config:test_TooManyTransmitter_Revert() (gas: 36938) OCR2BaseNoChecks_setOCR2Config:test_TransmitterCannotBeZeroAddress_Revert() (gas: 24158) OCR2BaseNoChecks_transmit:test_ConfigDigestMismatch_Revert() (gas: 17448) OCR2BaseNoChecks_transmit:test_ForkedChain_Revert() (gas: 26726) -OCR2BaseNoChecks_transmit:test_TransmitSuccess_gas() (gas: 27478) +OCR2BaseNoChecks_transmit:test_TransmitSuccess_gas() (gas: 27466) OCR2BaseNoChecks_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 21296) OCR2Base_setOCR2Config:test_FMustBePositive_Revert() (gas: 12189) OCR2Base_setOCR2Config:test_FTooHigh_Revert() (gas: 12345) @@ -610,7 +610,7 @@ OCR2Base_transmit:test_ConfigDigestMismatch_Revert() (gas: 19623) OCR2Base_transmit:test_ForkedChain_Revert() (gas: 37683) OCR2Base_transmit:test_NonUniqueSignature_Revert() (gas: 55309) OCR2Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 20962) -OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51686) +OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51674) OCR2Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 23484) OCR2Base_transmit:test_UnauthorizedSigner_Revert() (gas: 39665) OCR2Base_transmit:test_WrongNumberOfSignatures_Revert() (gas: 20557) @@ -677,7 +677,7 @@ OffRamp_execute:test_ZeroReports_Revert() (gas: 17225) OffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18257) OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249037) OffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20517) -OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 207676) +OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 210176) OffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48779) OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48302) OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229565) @@ -699,12 +699,12 @@ OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 193345) OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 212938) OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 266576) -OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 141488) +OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 141191) OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 423378) OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65877) OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80932) OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 587410) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 536450) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 535220) OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35743) OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 532474) OffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 529798) @@ -775,11 +775,11 @@ OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 211543) OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 125128) OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 146530) -OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3891732) +OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3894232) OnRamp_forwardFromRouter:test_UnAllowedOriginalSender_Revert() (gas: 18609) OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 111118) OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 76545) -OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 278740) +OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 281240) OnRamp_getFee:test_EmptyMessage_Success() (gas: 110107) OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 75610) OnRamp_getFee:test_GetFeeOfZeroForTokenMessage_Success() (gas: 95456) @@ -794,7 +794,7 @@ OnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11359) OnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 16385) OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 55321) OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97107) -PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150169) +PingPong_ccipReceive:test_CcipReceive_Success() (gas: 152669) PingPong_plumbing:test_OutOfOrderExecution_Success() (gas: 20277) PingPong_plumbing:test_Pausing_Success() (gas: 17777) PingPong_startPingPong:test_StartPingPong_With_OOO_Success() (gas: 163187) @@ -807,7 +807,7 @@ RMN_ownerUnbless:test_Unbless_Success() (gas: 74699) RMN_ownerUnvoteToCurse:test_CanBlessAndCurseAfterGlobalCurseIsLifted() (gas: 470965) RMN_ownerUnvoteToCurse:test_IsIdempotent() (gas: 397532) RMN_ownerUnvoteToCurse:test_NonOwner_Revert() (gas: 18591) -RMN_ownerUnvoteToCurse:test_OwnerUnvoteToCurseSuccess_gas() (gas: 357403) +RMN_ownerUnvoteToCurse:test_OwnerUnvoteToCurseSuccess_gas() (gas: 357400) RMN_ownerUnvoteToCurse:test_UnknownVoter_Revert() (gas: 32980) RMN_ownerUnvoteToCurse_Benchmark:test_OwnerUnvoteToCurse_1Voter_LiftsCurse_gas() (gas: 261985) RMN_permaBlessing:test_PermaBlessing() (gas: 202686) @@ -815,7 +815,7 @@ RMN_setConfig:test_BlessVoterIsZeroAddress_Revert() (gas: 15494) RMN_setConfig:test_EitherThresholdIsZero_Revert() (gas: 21095) RMN_setConfig:test_NonOwner_Revert() (gas: 14713) RMN_setConfig:test_RepeatedAddress_Revert() (gas: 18213) -RMN_setConfig:test_SetConfigSuccess_gas() (gas: 104204) +RMN_setConfig:test_SetConfigSuccess_gas() (gas: 104022) RMN_setConfig:test_TotalWeightsSmallerThanEachThreshold_Revert() (gas: 30173) RMN_setConfig:test_VoteToBlessByEjectedVoter_Revert() (gas: 130303) RMN_setConfig:test_VotersLengthIsZero_Revert() (gas: 12128) @@ -900,18 +900,18 @@ Router_getFee:test_GetFeeSupportedChain_Success() (gas: 46458) Router_getFee:test_UnsupportedDestinationChain_Revert() (gas: 17138) Router_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10460) Router_recoverTokens:test_RecoverTokensInvalidRecipient_Revert() (gas: 11316) -Router_recoverTokens:test_RecoverTokensNoFunds_Revert() (gas: 17761) +Router_recoverTokens:test_RecoverTokensNoFunds_Revert() (gas: 20261) Router_recoverTokens:test_RecoverTokensNonOwner_Revert() (gas: 11159) Router_recoverTokens:test_RecoverTokensValueReceiver_Revert() (gas: 422138) -Router_recoverTokens:test_RecoverTokens_Success() (gas: 50437) +Router_recoverTokens:test_RecoverTokens_Success() (gas: 52437) Router_routeMessage:test_AutoExec_Success() (gas: 42684) Router_routeMessage:test_ExecutionEvent_Success() (gas: 157980) Router_routeMessage:test_ManualExec_Success() (gas: 35381) Router_routeMessage:test_OnlyOffRamp_Revert() (gas: 25116) Router_routeMessage:test_WhenNotHealthy_Revert() (gas: 44724) Router_setWrappedNative:test_OnlyOwner_Revert() (gas: 10985) -SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 53531) -SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 416966) +SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 55531) +SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 419466) SelfFundedPingPong_setCountIncrBeforeFunding:test_setCountIncrBeforeFunding() (gas: 20151) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_OnlyPendingAdministrator_Revert() (gas: 51085) TokenAdminRegistry_acceptAdminRole:test_acceptAdminRole_Success() (gas: 43947) @@ -939,8 +939,8 @@ TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6070353) TokenPoolAndProxy:test_lockOrBurn_burnWithFromMint_Success() (gas: 6101826) TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6319594) TokenPoolAndProxy:test_setPreviousPool_Success() (gas: 3387124) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6913778) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7097803) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6916278) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7100303) TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2209837) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12089) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23324) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index 69e0271684..b54662b868 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,21 +1,21 @@ -ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumGoerli() (gas: 16076840) -ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumMainnet() (gas: 16076819) -ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumSepolia() (gas: 16076888) -ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseGoerli() (gas: 16076608) -ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseMainnet() (gas: 16076564) -ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseSepolia() (gas: 16076635) -ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismGoerli() (gas: 16076521) -ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismMainnet() (gas: 16076543) -ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismSepolia() (gas: 16076586) +ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumGoerli() (gas: 15903239) +ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumMainnet() (gas: 15903196) +ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumSepolia() (gas: 15903265) +ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseGoerli() (gas: 15903033) +ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseMainnet() (gas: 15903011) +ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseSepolia() (gas: 15903060) +ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismGoerli() (gas: 15902946) +ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismMainnet() (gas: 15902968) +ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismSepolia() (gas: 15903011) FunctionsBilling_Constructor:test_Constructor_Success() (gas: 17982) -FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13283) -FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15853) +FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13260) +FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15875) FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32450) -FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 90977) +FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 90999) FunctionsBilling_EstimateCost:test_EstimateCost_SuccessLowGasPrice() (gas: 91102) FunctionsBilling_GetAdminFeeJuels:test_GetAdminFeeJuels_Success() (gas: 18671) -FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 30750) -FunctionsBilling_GetDONFeeJuels:test_GetDONFeeJuels_Success() (gas: 41151) +FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 30727) +FunctionsBilling_GetDONFeeJuels:test_GetDONFeeJuels_Success() (gas: 41128) FunctionsBilling_GetOperationFee:test_GetOperationFeeJuels_Success() (gas: 40548) FunctionsBilling_GetWeiPerUnitLink:test_GetWeiPerUnitLink_Success() (gas: 29751) FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertIfInsufficientBalance() (gas: 70136) @@ -23,41 +23,41 @@ FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertWithNoBalance() (gas: FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessCoordinatorOwner() (gas: 129908) FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceNoAmountGiven() (gas: 171930) FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceValidAmountGiven() (gas: 145165) -FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13320) +FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13297) FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 222357) -FunctionsBilling_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 21632) -FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 54099) +FunctionsBilling_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 21654) +FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 54121) FunctionsBilling__DisperseFeePool:test__DisperseFeePool_RevertIfNotSet() (gas: 8810) -FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13353) -FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 185976) +FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13375) +FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 185953) FunctionsBilling__StartBilling:test__FulfillAndBill_HasUniqueGlobalRequestId() (gas: 524582) FunctionsClient_Constructor:test_Constructor_Success() (gas: 10407) -FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_RevertIfNotRouter() (gas: 14595) -FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_Success() (gas: 22983) +FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_RevertIfNotRouter() (gas: 14617) +FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_Success() (gas: 22917) FunctionsClient__SendRequest:test__SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 55069) FunctionsCoordinator_Constructor:test_Constructor_Success() (gas: 15085) -FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_RevertIfEmpty() (gas: 15356) +FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_RevertIfEmpty() (gas: 15378) FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_Success() (gas: 91691) -FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_RevertIfEmpty() (gas: 15334) -FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_Success() (gas: 515951) -FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_RevertNotOwner() (gas: 20409) +FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_RevertIfEmpty() (gas: 15356) +FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_Success() (gas: 515973) +FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_RevertNotOwner() (gas: 20365) FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_Success() (gas: 88970) -FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_RevertNotOwner() (gas: 13915) +FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_RevertNotOwner() (gas: 13892) FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_Success() (gas: 513165) -FunctionsCoordinator_StartRequest:test_StartRequest_RevertIfNotRouter() (gas: 22802) -FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 152650) +FunctionsCoordinator_StartRequest:test_StartRequest_RevertIfNotRouter() (gas: 22736) +FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 152672) FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessFound() (gas: 15106) -FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessNotFound() (gas: 22916) +FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessNotFound() (gas: 22938) FunctionsRequest_DEFAULT_BUFFER_SIZE:test_DEFAULT_BUFFER_SIZE() (gas: 3089) FunctionsRequest_EncodeCBOR:test_EncodeCBOR_Success() (gas: 3066) FunctionsRequest_REQUEST_DATA_VERSION:test_REQUEST_DATA_VERSION() (gas: 3068) FunctionsRouter_Constructor:test_Constructor_Success() (gas: 15107) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 172475) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 172497) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 163010) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 38777) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35900) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 180976) -FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28152) +FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28086) FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 156535) FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 335070) FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 348695) @@ -65,19 +65,19 @@ FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2627478) FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 658423) FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 18323) FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 13241) -FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 40193) -FunctionsRouter_GetContractById:test_GetContractById_RevertIfRouteDoesNotExist() (gas: 13862) +FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 40170) +FunctionsRouter_GetContractById:test_GetContractById_RevertIfRouteDoesNotExist() (gas: 13839) FunctionsRouter_GetContractById:test_GetContractById_SuccessIfRouteExists() (gas: 17704) -FunctionsRouter_GetProposedContractById:test_GetProposedContractById_RevertIfRouteDoesNotExist() (gas: 16417) -FunctionsRouter_GetProposedContractById:test_GetProposedContractById_SuccessIfRouteExists() (gas: 24289) +FunctionsRouter_GetProposedContractById:test_GetProposedContractById_RevertIfRouteDoesNotExist() (gas: 16373) +FunctionsRouter_GetProposedContractById:test_GetProposedContractById_SuccessIfRouteExists() (gas: 24266) FunctionsRouter_GetProposedContractSet:test_GetProposedContractSet_Success() (gas: 27289) FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertGasLimitTooBig() (gas: 28087) FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertInvalidConfig() (gas: 41095) FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_Success() (gas: 24632) -FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13361) -FunctionsRouter_Pause:test_Pause_Success() (gas: 20647) -FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfEmptyAddress() (gas: 14769) -FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfExceedsMaxProposal() (gas: 21716) +FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13338) +FunctionsRouter_Pause:test_Pause_Success() (gas: 20669) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfEmptyAddress() (gas: 14791) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfExceedsMaxProposal() (gas: 21693) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfLengthMismatch() (gas: 14670) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotNewContract() (gas: 19048) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotOwner() (gas: 23392) @@ -85,151 +85,149 @@ FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_Success() (ga FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 59400) FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 217996) FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29426) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57882) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57904) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 208451) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 50953) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25082) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29177) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29132) FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34291) -FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 226324) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65918) +FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 226346) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65896) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 36012) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29896) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() (gas: 57539) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidDonId() (gas: 27503) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35672) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35717) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40810) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 232783) FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 214899) FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 33531) -FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13381) -FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13337) -FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77748) -FunctionsRouter_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 24415) -FunctionsRouter_UpdateConfig:test_UpdateConfig_Success() (gas: 63331) -FunctionsRouter_UpdateContracts:test_UpdateContracts_RevertIfNotOwner() (gas: 13314) +FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13403) +FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13293) +FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77725) +FunctionsRouter_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 24437) +FunctionsRouter_UpdateConfig:test_UpdateConfig_Success() (gas: 63353) +FunctionsRouter_UpdateContracts:test_UpdateContracts_RevertIfNotOwner() (gas: 13336) FunctionsRouter_UpdateContracts:test_UpdateContracts_Success() (gas: 39269) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 60413) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 61040) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 139706) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62780) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 239919) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 239911) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 138033) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 164977) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12933) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 102428) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87272) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12955) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 102450) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87205) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfPaused() (gas: 18100) FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 96221) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubscription() (gas: 15053) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 102507) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89341) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 102529) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89318) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20157) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 218308) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 218330) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 115656) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() (gas: 126964) FunctionsSubscriptions_CancelSubscription_ReceiveDeposit:test_CancelSubscription_SuccessRecieveDeposit() (gas: 75369) FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 10488) FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28688) -FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 18038) +FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 17994) FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_Success() (gas: 353899) -FunctionsSubscriptions_GetConsumer:test_GetConsumer_Success() (gas: 17279) -FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessInvalidSubscription() (gas: 13504) -FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessValidSubscription() (gas: 41221) +FunctionsSubscriptions_GetConsumer:test_GetConsumer_Success() (gas: 17256) +FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessInvalidSubscription() (gas: 13438) +FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessValidSubscription() (gas: 41243) FunctionsSubscriptions_GetSubscription:test_GetSubscription_Success() (gas: 32968) FunctionsSubscriptions_GetSubscriptionCount:test_GetSubscriptionCount_Success() (gas: 13305) -FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfEndIsAfterLastSubscription() (gas: 16570) +FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfEndIsAfterLastSubscription() (gas: 16547) FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfStartIsAfterEnd() (gas: 13465) -FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_Success() (gas: 65968) -FunctionsSubscriptions_GetTotalBalance:test_GetTotalBalance_Success() (gas: 15370) +FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_Success() (gas: 65990) +FunctionsSubscriptions_GetTotalBalance:test_GetTotalBalance_Success() (gas: 15347) FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoCalldata() (gas: 39908) FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoSubscription() (gas: 42382) FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNotLink() (gas: 13419) FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfPaused() (gas: 47325) FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_Success() (gas: 84314) -FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfAmountMoreThanBalance() (gas: 20744) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfAmountMoreThanBalance() (gas: 20766) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfBalanceInvariant() (gas: 189) -FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfNoAmount() (gas: 15686) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfNoAmount() (gas: 15641) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfPaused() (gas: 20859) -FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessPaysRecipient() (gas: 60119) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessPaysRecipient() (gas: 60075) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessSetsBalanceToZero() (gas: 57716) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNoSubscription() (gas: 12796) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15594) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 55177) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNoSubscription() (gas: 12818) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15549) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 55141) FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessDeletesSubscription() (gas: 49607) FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessSubOwnerRefunded() (gas: 53166) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 186511) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17923) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 186533) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17945) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfBalanceInvariant() (gas: 210) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15600) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15555) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas: 33839) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfRecipientAddressZero() (gas: 31627) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfRecipientAddressZero() (gas: 31649) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 33935) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 31584) -FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 17796) -FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 203311) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27642) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57793) +FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 17818) +FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 203333) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27664) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57815) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15013) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 119820) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() (gas: 17947) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() (gas: 20181) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68574) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_SuccessChangeProposedOwner() (gas: 83582) -FunctionsSubscriptions_RecoverFunds:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15577) -FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41358) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 119775) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() (gas: 17969) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() (gas: 20137) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68596) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_SuccessChangeProposedOwner() (gas: 83539) +FunctionsSubscriptions_RecoverFunds:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15554) +FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41376) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfInvalidConsumer() (gas: 30310) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription() (gas: 15031) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 102444) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87277) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18103) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87254) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18058) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 215863) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42066) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42088) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12888) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15684) FunctionsSubscriptions_SetFlags:test_SetFlags_Success() (gas: 38434) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfPaused() (gas: 25955) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfTimeoutNotExceeded() (gas: 25261) -FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28220) -FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 58394) -FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26462) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28242) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 58416) +FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26418) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15759) FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 153701) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 94943) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25925) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 89013) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23620) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866619) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 28526) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1946966) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 104555) -FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15535) -FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 97587) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 94913) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25859) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 88990) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23619) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866552) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 28525) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1946965) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 104509) +FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15491) +FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 97541) FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 15345) FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19243) FunctionsTermsOfServiceAllowList_GetAllowedSendersCount:test_GetAllowedSendersCount_Success() (gas: 13332) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13326576) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16532) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13307) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20335) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13153024) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16554) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13284) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20312) FunctionsTermsOfServiceAllowList_GetBlockedSendersCount:test_GetBlockedSendersCount_Success() (gas: 13268) -FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13326564) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13153034) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16549) -FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13345) -FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_Success() (gas: 18580) -FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 16411) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13367) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_Success() (gas: 18537) +FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 16388) FunctionsTermsOfServiceAllowList_GetMessage:test_GetMessage_Success() (gas: 11918) -FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 16235) -FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23877) +FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 16257) +FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23848) FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessFalse() (gas: 15776) FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTrue() (gas: 86974) -FunctionsTermsOfServiceAllowList_MigratePreviouslyAllowedSenders:test_MigratePreviouslyAllowedSenders_RevertIfNotOwner() (gas: 13987) -FunctionsTermsOfServiceAllowList_MigratePreviouslyAllowedSenders:test_MigratePreviouslyAllowedSenders_Success() (gas: 210636) -FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13548) -FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 96240) -FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13819) -FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22824) -Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84725) +FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13502) +FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 96216) +FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13812) +FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22817) +Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84702) Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79140) Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73419) Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MaximumGas() (gas: 20562) diff --git a/contracts/gas-snapshots/keystone.gas-snapshot b/contracts/gas-snapshots/keystone.gas-snapshot index ad8bc2798e..2880e4c0e3 100644 --- a/contracts/gas-snapshots/keystone.gas-snapshot +++ b/contracts/gas-snapshots/keystone.gas-snapshot @@ -1,114 +1,107 @@ -CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_NoConfigurationContract() (gas: 154809) -CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_WithConfiguration() (gas: 180379) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 24678) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CapabilityExists() (gas: 145613) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractDoesNotMatchInterface() (gas: 94543) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractNotDeployed() (gas: 96326) -CapabilitiesRegistry_AddDONTest:test_AddDON() (gas: 373700) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19288) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 169767) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 239739) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 250950) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 116905) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_FaultToleranceIsZero() (gas: 43373) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeAlreadyBelongsToWorkflowDON() (gas: 343954) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 180165) -CapabilitiesRegistry_AddDONTest_WhenMaliciousCapabilityConfigurationConfigured:test_RevertWhen_MaliciousCapabilitiesConfigContractTriesToRemoveCapabilitiesFromDONNodes() (gas: 340514) -CapabilitiesRegistry_AddNodeOperatorsTest:test_AddNodeOperators() (gas: 184157) -CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_CalledByNonAdmin() (gas: 17624) -CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_NodeOperatorAdminAddressZero() (gas: 18520) -CapabilitiesRegistry_AddNodesTest:test_AddsNodeParams() (gas: 358492) -CapabilitiesRegistry_AddNodesTest:test_OwnerCanAddNodes() (gas: 358458) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingDuplicateP2PId() (gas: 301273) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 55196) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidNodeOperator() (gas: 24917) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithoutCapabilities() (gas: 27691) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25130) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 27430) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 27069) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressNotUnique() (gas: 309723) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_DeprecatesCapability() (gas: 89742) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_EmitsEvent() (gas: 89870) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 22879) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 16166) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityIsDeprecated() (gas: 91134) -CapabilitiesRegistry_GetCapabilitiesTest:test_ReturnsCapabilities() (gas: 135488) +CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_NoConfigurationContract() (gas: 154832) +CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_WithConfiguration() (gas: 178813) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 24723) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CapabilityExists() (gas: 145703) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractDoesNotMatchInterface() (gas: 94606) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractNotDeployed() (gas: 92961) +CapabilitiesRegistry_AddDONTest:test_AddDON() (gas: 372302) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19273) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 169752) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 239789) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 249596) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 116890) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_FaultToleranceIsZero() (gas: 43358) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeAlreadyBelongsToWorkflowDON() (gas: 343924) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 180150) +CapabilitiesRegistry_AddNodeOperatorsTest:test_AddNodeOperators() (gas: 184135) +CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_CalledByNonAdmin() (gas: 17602) +CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_NodeOperatorAdminAddressZero() (gas: 18498) +CapabilitiesRegistry_AddNodesTest:test_AddsNodeParams() (gas: 358448) +CapabilitiesRegistry_AddNodesTest:test_OwnerCanAddNodes() (gas: 358414) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingDuplicateP2PId() (gas: 301229) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 55174) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidNodeOperator() (gas: 24895) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithoutCapabilities() (gas: 27669) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25108) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 27408) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 27047) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressNotUnique() (gas: 309679) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_DeprecatesCapability() (gas: 89807) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_EmitsEvent() (gas: 89935) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 22944) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 16231) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityIsDeprecated() (gas: 91264) +CapabilitiesRegistry_GetCapabilitiesTest:test_ReturnsCapabilities() (gas: 135553) CapabilitiesRegistry_GetDONsTest:test_CorrectlyFetchesDONs() (gas: 65468) CapabilitiesRegistry_GetDONsTest:test_DoesNotIncludeRemovedDONs() (gas: 64924) CapabilitiesRegistry_GetHashedCapabilityTest:test_CorrectlyGeneratesHashedCapabilityId() (gas: 11428) CapabilitiesRegistry_GetHashedCapabilityTest:test_DoesNotCauseIncorrectClashes() (gas: 13087) -CapabilitiesRegistry_GetNodeOperatorsTest:test_CorrectlyFetchesNodeOperators() (gas: 36429) -CapabilitiesRegistry_GetNodeOperatorsTest:test_DoesNotIncludeRemovedNodeOperators() (gas: 38714) +CapabilitiesRegistry_GetNodeOperatorsTest:test_CorrectlyFetchesNodeOperators() (gas: 36407) +CapabilitiesRegistry_GetNodeOperatorsTest:test_DoesNotIncludeRemovedNodeOperators() (gas: 38692) CapabilitiesRegistry_GetNodesTest:test_CorrectlyFetchesNodes() (gas: 65288) -CapabilitiesRegistry_GetNodesTest:test_DoesNotIncludeRemovedNodes() (gas: 73497) -CapabilitiesRegistry_RemoveDONsTest:test_RemovesDON() (gas: 54783) +CapabilitiesRegistry_GetNodesTest:test_DoesNotIncludeRemovedNodes() (gas: 73533) +CapabilitiesRegistry_RemoveDONsTest:test_RemovesDON() (gas: 54761) CapabilitiesRegistry_RemoveDONsTest:test_RevertWhen_CalledByNonAdmin() (gas: 15647) CapabilitiesRegistry_RemoveDONsTest:test_RevertWhen_DONDoesNotExist() (gas: 16550) CapabilitiesRegistry_RemoveNodeOperatorsTest:test_RemovesNodeOperator() (gas: 36122) CapabilitiesRegistry_RemoveNodeOperatorsTest:test_RevertWhen_CalledByNonOwner() (gas: 15816) -CapabilitiesRegistry_RemoveNodesTest:test_CanAddNodeWithSameSignerAddressAfterRemoving() (gas: 115150) -CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenDONDeleted() (gas: 287663) -CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenNodeNoLongerPartOfDON() (gas: 561017) -CapabilitiesRegistry_RemoveNodesTest:test_OwnerCanRemoveNodes() (gas: 73358) -CapabilitiesRegistry_RemoveNodesTest:test_RemovesNode() (gas: 75192) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25008) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 18373) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodePartOfCapabilitiesDON() (gas: 385339) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 18363) +CapabilitiesRegistry_RemoveNodesTest:test_CanAddNodeWithSameSignerAddressAfterRemoving() (gas: 115151) +CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenDONDeleted() (gas: 287716) +CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenNodeNoLongerPartOfDON() (gas: 561023) +CapabilitiesRegistry_RemoveNodesTest:test_OwnerCanRemoveNodes() (gas: 73376) +CapabilitiesRegistry_RemoveNodesTest:test_RemovesNode() (gas: 75211) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25053) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 18418) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodePartOfCapabilitiesDON() (gas: 385369) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 18408) CapabilitiesRegistry_TypeAndVersionTest:test_TypeAndVersion() (gas: 9796) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19323) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 152958) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DONDoesNotExist() (gas: 17749) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 222975) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 236986) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 107687) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 163401) -CapabilitiesRegistry_UpdateDONTest:test_UpdatesDON() (gas: 373317) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_CalledByNonAdminAndNonOwner() (gas: 20684) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorAdminIsZeroAddress() (gas: 20008) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorDoesNotExist() (gas: 19746) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorIdAndParamLengthsMismatch() (gas: 15386) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_UpdatesNodeOperator() (gas: 36990) -CapabilitiesRegistry_UpdateNodesTest:test_CanUpdateParamsIfNodeSignerAddressNoLongerUsed() (gas: 256437) -CapabilitiesRegistry_UpdateNodesTest:test_OwnerCanUpdateNodes() (gas: 162210) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 35895) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByAnotherNodeOperatorAdmin() (gas: 29222) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 29399) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 29221) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeSignerAlreadyAssignedToAnotherNode() (gas: 31348) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 29187) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByCapabilityDON() (gas: 470947) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByWorkflowDON() (gas: 341228) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 29080) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 27609) -CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162264) -KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 2003568) -KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() (gas: 124908) -KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverNotContract() (gas: 126927) -KeystoneForwarder_ReportTest:test_Report_SuccessfulDelivery() (gas: 361243) -KeystoneForwarder_ReportTest:test_Report_SuccessfulRetryWithMoreGas() (gas: 501084) -KeystoneForwarder_ReportTest:test_RevertWhen_AnySignatureIsInvalid() (gas: 86326) -KeystoneForwarder_ReportTest:test_RevertWhen_AnySignerIsInvalid() (gas: 118521) -KeystoneForwarder_ReportTest:test_RevertWhen_AttemptingTransmissionWithInsufficientGas() (gas: 96279) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19415) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 152914) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DONDoesNotExist() (gas: 17835) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 222996) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 232804) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 107643) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 163357) +CapabilitiesRegistry_UpdateDONTest:test_UpdatesDON() (gas: 371909) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_CalledByNonAdminAndNonOwner() (gas: 20631) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorAdminIsZeroAddress() (gas: 20052) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorDoesNotExist() (gas: 19790) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorIdAndParamLengthsMismatch() (gas: 15430) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_UpdatesNodeOperator() (gas: 36937) +CapabilitiesRegistry_UpdateNodesTest:test_CanUpdateParamsIfNodeSignerAddressNoLongerUsed() (gas: 256157) +CapabilitiesRegistry_UpdateNodesTest:test_OwnerCanUpdateNodes() (gas: 162059) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 35766) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25069) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 27308) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeSignerAlreadyAssignedToAnotherNode() (gas: 29219) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 27296) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByCapabilityDON() (gas: 470803) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByWorkflowDON() (gas: 341084) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 26951) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 25480) +CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162113) +KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 1797755) +KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() (gas: 125910) +KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverNotContract() (gas: 127403) +KeystoneForwarder_ReportTest:test_Report_SuccessfulDelivery() (gas: 155928) +KeystoneForwarder_ReportTest:test_RevertWhen_AlreadyAttempted() (gas: 152358) +KeystoneForwarder_ReportTest:test_RevertWhen_AnySignatureIsInvalid() (gas: 86348) +KeystoneForwarder_ReportTest:test_RevertWhen_AnySignerIsInvalid() (gas: 118486) KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasDuplicateSignatures() (gas: 94516) KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasIncorrectDON() (gas: 75930) KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasInexistentConfigVersion() (gas: 76298) -KeystoneForwarder_ReportTest:test_RevertWhen_ReportIsMalformed() (gas: 45563) -KeystoneForwarder_ReportTest:test_RevertWhen_RetryingInvalidContractTransmission() (gas: 143591) -KeystoneForwarder_ReportTest:test_RevertWhen_RetryingSuccessfulTransmission() (gas: 354042) +KeystoneForwarder_ReportTest:test_RevertWhen_ReportIsMalformed() (gas: 45585) KeystoneForwarder_ReportTest:test_RevertWhen_TooFewSignatures() (gas: 55292) KeystoneForwarder_ReportTest:test_RevertWhen_TooManySignatures() (gas: 56050) KeystoneForwarder_SetConfigTest:test_RevertWhen_ExcessSigners() (gas: 20184) KeystoneForwarder_SetConfigTest:test_RevertWhen_FaultToleranceIsZero() (gas: 88057) KeystoneForwarder_SetConfigTest:test_RevertWhen_InsufficientSigners() (gas: 14533) -KeystoneForwarder_SetConfigTest:test_RevertWhen_NotOwner() (gas: 88766) -KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingDuplicateSigners() (gas: 114570) -KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingZeroAddressSigner() (gas: 114225) -KeystoneForwarder_SetConfigTest:test_SetConfig_FirstTime() (gas: 1540541) -KeystoneForwarder_SetConfigTest:test_SetConfig_WhenSignersAreRemoved() (gas: 1535211) +KeystoneForwarder_SetConfigTest:test_RevertWhen_NotOwner() (gas: 88788) +KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingDuplicateSigners() (gas: 114507) +KeystoneForwarder_SetConfigTest:test_SetConfig_FirstTime() (gas: 1539921) +KeystoneForwarder_SetConfigTest:test_SetConfig_WhenSignersAreRemoved() (gas: 1534476) KeystoneForwarder_TypeAndVersionTest:test_TypeAndVersion() (gas: 9641) KeystoneRouter_SetConfigTest:test_AddForwarder_RevertWhen_NotOwner() (gas: 10978) KeystoneRouter_SetConfigTest:test_RemoveForwarder_RevertWhen_NotOwner() (gas: 10923) -KeystoneRouter_SetConfigTest:test_RemoveForwarder_Success() (gas: 17599) -KeystoneRouter_SetConfigTest:test_Route_RevertWhen_UnauthorizedForwarder() (gas: 18552) -KeystoneRouter_SetConfigTest:test_Route_Success() (gas: 79379) \ No newline at end of file +KeystoneRouter_SetConfigTest:test_Route_RevertWhen_UnauthorizedForwarder() (gas: 18553) +KeystoneRouter_SetConfigTest:test_Route_Success() (gas: 75629) \ No newline at end of file diff --git a/contracts/gas-snapshots/llo-feeds.gas-snapshot b/contracts/gas-snapshots/llo-feeds.gas-snapshot index 68f3c016f6..187d3cd89f 100644 --- a/contracts/gas-snapshots/llo-feeds.gas-snapshot +++ b/contracts/gas-snapshots/llo-feeds.gas-snapshot @@ -18,223 +18,6 @@ ByteUtilTest:test_readUint32MultiWord() (gas: 3393) ByteUtilTest:test_readUint32WithEmptyArray() (gas: 3253) ByteUtilTest:test_readUint32WithNotEnoughBytes() (gas: 3272) ByteUtilTest:test_readZeroAddress() (gas: 3365) -ChannelConfigStoreTest:testSetChannelDefinitions() (gas: 46927) -ChannelConfigStoreTest:testSupportsInterface() (gas: 8367) -ChannelConfigStoreTest:testTypeAndVersion() (gas: 9621) -DestinationFeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52669) -DestinationFeeManagerProcessFeeTest:test_DiscountIsReturnedForNative() (gas: 52685) -DestinationFeeManagerProcessFeeTest:test_DiscountIsReturnedForNativeWithSurcharge() (gas: 78876) -DestinationFeeManagerProcessFeeTest:test_V1PayloadVerifies() (gas: 29324) -DestinationFeeManagerProcessFeeTest:test_V1PayloadVerifiesAndReturnsChange() (gas: 61187) -DestinationFeeManagerProcessFeeTest:test_V2PayloadVerifies() (gas: 121137) -DestinationFeeManagerProcessFeeTest:test_V2PayloadWithoutQuoteFails() (gas: 29669) -DestinationFeeManagerProcessFeeTest:test_V2PayloadWithoutZeroFee() (gas: 74797) -DestinationFeeManagerProcessFeeTest:test_WithdrawERC20() (gas: 72796) -DestinationFeeManagerProcessFeeTest:test_WithdrawNonAdminAddr() (gas: 56334) -DestinationFeeManagerProcessFeeTest:test_WithdrawUnwrappedNative() (gas: 26411) -DestinationFeeManagerProcessFeeTest:test_addVerifier() (gas: 131079) -DestinationFeeManagerProcessFeeTest:test_addVerifierExistingAddress() (gas: 34148) -DestinationFeeManagerProcessFeeTest:test_baseFeeIsAppliedForLink() (gas: 17214) -DestinationFeeManagerProcessFeeTest:test_baseFeeIsAppliedForNative() (gas: 20152) -DestinationFeeManagerProcessFeeTest:test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() (gas: 91103) -DestinationFeeManagerProcessFeeTest:test_discountAIsNotAppliedWhenSetForOtherUsers() (gas: 56580) -DestinationFeeManagerProcessFeeTest:test_discountFeeRoundsDownWhenUneven() (gas: 52871) -DestinationFeeManagerProcessFeeTest:test_discountIsAppliedForLink() (gas: 49682) -DestinationFeeManagerProcessFeeTest:test_discountIsAppliedWith100PercentSurcharge() (gas: 78949) -DestinationFeeManagerProcessFeeTest:test_discountIsNoLongerAppliedAfterRemoving() (gas: 46567) -DestinationFeeManagerProcessFeeTest:test_discountIsNotAppliedForInvalidTokenAddress() (gas: 17582) -DestinationFeeManagerProcessFeeTest:test_discountIsNotAppliedToOtherFeeds() (gas: 54628) -DestinationFeeManagerProcessFeeTest:test_discountIsReturnedForLink() (gas: 49654) -DestinationFeeManagerProcessFeeTest:test_emptyQuoteRevertsWithError() (gas: 12231) -DestinationFeeManagerProcessFeeTest:test_eventIsEmittedAfterSurchargeIsSet() (gas: 41424) -DestinationFeeManagerProcessFeeTest:test_eventIsEmittedIfNotEnoughLink() (gas: 179229) -DestinationFeeManagerProcessFeeTest:test_eventIsEmittedUponWithdraw() (gas: 69057) -DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterDiscountIsRemoved() (gas: 49831) -DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewDiscountIsApplied() (gas: 67769) -DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewSurchargeIsApplied() (gas: 64460) -DestinationFeeManagerProcessFeeTest:test_feeIsZeroWith100PercentDiscount() (gas: 52091) -DestinationFeeManagerProcessFeeTest:test_getBaseRewardWithLinkQuote() (gas: 17231) -DestinationFeeManagerProcessFeeTest:test_getLinkFeeIsRoundedUp() (gas: 49853) -DestinationFeeManagerProcessFeeTest:test_getLinkRewardIsSameAsFee() (gas: 55711) -DestinationFeeManagerProcessFeeTest:test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() (gas: 82833) -DestinationFeeManagerProcessFeeTest:test_getRewardWithLinkDiscount() (gas: 49700) -DestinationFeeManagerProcessFeeTest:test_getRewardWithLinkQuoteAndLinkDiscount() (gas: 49681) -DestinationFeeManagerProcessFeeTest:test_getRewardWithNativeQuote() (gas: 20150) -DestinationFeeManagerProcessFeeTest:test_getRewardWithNativeQuoteAndSurcharge() (gas: 50885) -DestinationFeeManagerProcessFeeTest:test_linkAvailableForPaymentReturnsLinkBalance() (gas: 53172) -DestinationFeeManagerProcessFeeTest:test_nativeSurcharge0Percent() (gas: 30937) -DestinationFeeManagerProcessFeeTest:test_nativeSurcharge100Percent() (gas: 50887) -DestinationFeeManagerProcessFeeTest:test_nativeSurchargeCannotExceed100Percent() (gas: 17220) -DestinationFeeManagerProcessFeeTest:test_nativeSurchargeEventIsEmittedOnUpdate() (gas: 41402) -DestinationFeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFee() (gas: 51914) -DestinationFeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() (gas: 78172) -DestinationFeeManagerProcessFeeTest:test_nonAdminProxyUserCannotProcessFee() (gas: 24185) -DestinationFeeManagerProcessFeeTest:test_nonAdminUserCanNotSetDiscount() (gas: 19871) -DestinationFeeManagerProcessFeeTest:test_onlyCallableByOwnerReverts() (gas: 15453) -DestinationFeeManagerProcessFeeTest:test_payLinkDeficit() (gas: 198072) -DestinationFeeManagerProcessFeeTest:test_payLinkDeficitOnlyCallableByAdmin() (gas: 17415) -DestinationFeeManagerProcessFeeTest:test_payLinkDeficitPaysAllFeesProcessed() (gas: 218691) -DestinationFeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 202446) -DestinationFeeManagerProcessFeeTest:test_poolIdsCannotBeZeroAddress() (gas: 115317) -DestinationFeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 121475) -DestinationFeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 29745) -DestinationFeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 165393) -DestinationFeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 32563) -DestinationFeeManagerProcessFeeTest:test_processFeeNative() (gas: 178204) -DestinationFeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 122766) -DestinationFeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 31822) -DestinationFeeManagerProcessFeeTest:test_processFeeWithDiscountEmitsEvent() (gas: 245890) -DestinationFeeManagerProcessFeeTest:test_processFeeWithInvalidReportVersionFailsToDecode() (gas: 30770) -DestinationFeeManagerProcessFeeTest:test_processFeeWithNoDiscountDoesNotEmitEvent() (gas: 171109) -DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNative() (gas: 186069) -DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddress() (gas: 135874) -DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() (gas: 161459) -DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeShortFunds() (gas: 94841) -DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeWithExcessiveFee() (gas: 193032) -DestinationFeeManagerProcessFeeTest:test_processFeeWithWithCorruptQuotePayload() (gas: 75084) -DestinationFeeManagerProcessFeeTest:test_processFeeWithWithEmptyQuotePayload() (gas: 30006) -DestinationFeeManagerProcessFeeTest:test_processFeeWithWithZeroQuotePayload() (gas: 30056) -DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() (gas: 35320) -DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() (gas: 158081) -DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkReturnsChange() (gas: 56059) -DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() (gas: 121473) -DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() (gas: 38024) -DestinationFeeManagerProcessFeeTest:test_processMultipleLinkReports() (gas: 230434) -DestinationFeeManagerProcessFeeTest:test_processMultipleUnwrappedNativeReports() (gas: 264223) -DestinationFeeManagerProcessFeeTest:test_processMultipleV1Reports() (gas: 81155) -DestinationFeeManagerProcessFeeTest:test_processMultipleWrappedNativeReports() (gas: 247072) -DestinationFeeManagerProcessFeeTest:test_processPoolIdsPassedMismatched() (gas: 98793) -DestinationFeeManagerProcessFeeTest:test_processV1V2V3Reports() (gas: 215445) -DestinationFeeManagerProcessFeeTest:test_processV1V2V3ReportsWithUnwrapped() (gas: 257087) -DestinationFeeManagerProcessFeeTest:test_removeVerifierNonExistentAddress() (gas: 12822) -DestinationFeeManagerProcessFeeTest:test_removeVerifierZeroAaddress() (gas: 10678) -DestinationFeeManagerProcessFeeTest:test_reportWithNoExpiryOrFeeReturnsZero() (gas: 13615) -DestinationFeeManagerProcessFeeTest:test_revertOnSettingAnAddressZeroVerifier() (gas: 10614) -DestinationFeeManagerProcessFeeTest:test_rewardsAreCorrectlySentToEachAssociatedPoolWhenVerifyingInBulk() (gas: 263181) -DestinationFeeManagerProcessFeeTest:test_setDiscountOver100Percent() (gas: 19562) -DestinationFeeManagerProcessFeeTest:test_setRewardManagerZeroAddress() (gas: 10626) -DestinationFeeManagerProcessFeeTest:test_subscriberDiscountEventIsEmittedOnUpdate() (gas: 46329) -DestinationFeeManagerProcessFeeTest:test_surchargeFeeRoundsUpWhenUneven() (gas: 51261) -DestinationFeeManagerProcessFeeTest:test_surchargeIsApplied() (gas: 51165) -DestinationFeeManagerProcessFeeTest:test_surchargeIsAppliedForNativeFeeWithDiscount() (gas: 79356) -DestinationFeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 47132) -DestinationFeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 49962) -DestinationFeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 78352) -DestinationFeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 14943) -DestinationRewardManagerClaimTest:test_claimAllRecipients() (gas: 277191) -DestinationRewardManagerClaimTest:test_claimMultipleRecipients() (gas: 154371) -DestinationRewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 330208) -DestinationRewardManagerClaimTest:test_claimSingleRecipient() (gas: 89039) -DestinationRewardManagerClaimTest:test_claimUnevenAmountRoundsDown() (gas: 315411) -DestinationRewardManagerClaimTest:test_claimUnregisteredPoolId() (gas: 35164) -DestinationRewardManagerClaimTest:test_claimUnregisteredRecipient() (gas: 41201) -DestinationRewardManagerClaimTest:test_eventIsEmittedUponClaim() (gas: 86084) -DestinationRewardManagerClaimTest:test_eventIsNotEmittedUponUnsuccessfulClaim() (gas: 25050) -DestinationRewardManagerClaimTest:test_recipientsClaimMultipleDeposits() (gas: 386857) -DestinationRewardManagerClaimTest:test_singleRecipientClaimMultipleDeposits() (gas: 137777) -DestinationRewardManagerNoRecipientSet:test_claimAllRecipientsAfterRecipientsSet() (gas: 492227) -DestinationRewardManagerPayRecipientsTest:test_addFundsToPoolAsNonOwnerOrFeeManager() (gas: 11503) -DestinationRewardManagerPayRecipientsTest:test_addFundsToPoolAsOwner() (gas: 53944) -DestinationRewardManagerPayRecipientsTest:test_payAllRecipients() (gas: 250829) -DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsFromNonAdminUser() (gas: 20496) -DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsFromRecipientInPool() (gas: 251075) -DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalInvalidRecipient() (gas: 262275) -DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalUnregisteredRecipient() (gas: 265760) -DestinationRewardManagerPayRecipientsTest:test_payRecipientWithInvalidPool() (gas: 28908) -DestinationRewardManagerPayRecipientsTest:test_payRecipientsEmptyRecipientList() (gas: 25333) -DestinationRewardManagerPayRecipientsTest:test_payRecipientsWithInvalidPoolId() (gas: 31402) -DestinationRewardManagerPayRecipientsTest:test_paySingleRecipient() (gas: 84709) -DestinationRewardManagerPayRecipientsTest:test_paySubsetOfRecipientsInPool() (gas: 198474) -DestinationRewardManagerRecipientClaimDifferentWeightsTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 280853) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsMultiplePools() (gas: 512489) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsSinglePool() (gas: 283649) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimEmptyPoolWhenSecondPoolContainsFunds() (gas: 293497) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsMultiplePools() (gas: 263075) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsSinglePool() (gas: 154537) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleRecipientMultiplePools() (gas: 132653) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleUniqueRecipient() (gas: 106056) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimUnevenAmountRoundsDown() (gas: 579776) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimUnregisteredRecipient() (gas: 64664) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorAndTotalPoolsEqual() (gas: 13074) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorCannotBeGreaterThanTotalPools() (gas: 12703) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorSingleResult() (gas: 22471) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPools() (gas: 32248) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() (gas: 148629) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInNoPools() (gas: 21728) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInSinglePool() (gas: 27765) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_recipientsClaimMultipleDeposits() (gas: 391427) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_singleRecipientClaimMultipleDeposits() (gas: 137862) -DestinationRewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 199546) -DestinationRewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() (gas: 219419) -DestinationRewardManagerSetRecipientsTest:test_eventIsEmittedUponSetRecipients() (gas: 191707) -DestinationRewardManagerSetRecipientsTest:test_setRecipientContainsDuplicateRecipients() (gas: 126060) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientFromManagerAddress() (gas: 214117) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() (gas: 21496) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientTwice() (gas: 193280) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWeights() (gas: 180608) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroAddress() (gas: 90202) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroWeight() (gas: 191312) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipients() (gas: 185567) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientsIsEmpty() (gas: 87091) -DestinationRewardManagerSetRecipientsTest:test_setSingleRewardRecipient() (gas: 110349) -DestinationRewardManagerSetupTest:test_addFeeManagerExistingAddress() (gas: 35281) -DestinationRewardManagerSetupTest:test_addFeeManagerZeroAddress() (gas: 10580) -DestinationRewardManagerSetupTest:test_addRemoveFeeManager() (gas: 48248) -DestinationRewardManagerSetupTest:test_eventEmittedUponFeeManagerUpdate() (gas: 41581) -DestinationRewardManagerSetupTest:test_eventEmittedUponFeePaid() (gas: 259172) -DestinationRewardManagerSetupTest:test_rejectsZeroLinkAddressOnConstruction() (gas: 59610) -DestinationRewardManagerSetupTest:test_removeFeeManagerNonExistentAddress() (gas: 12778) -DestinationRewardManagerSetupTest:test_setFeeManagerZeroAddress() (gas: 17084) -DestinationRewardManagerUpdateRewardRecipientsMultiplePoolsTest:test_updatePrimaryRecipientWeights() (gas: 376674) -DestinationRewardManagerUpdateRewardRecipientsTest:test_eventIsEmittedUponUpdateRecipients() (gas: 280411) -DestinationRewardManagerUpdateRewardRecipientsTest:test_onlyAdminCanUpdateRecipients() (gas: 19705) -DestinationRewardManagerUpdateRewardRecipientsTest:test_partialUpdateRecipientWeights() (gas: 221004) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateAllRecipientsWithSameAddressAndWeight() (gas: 274233) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsToSubset() (gas: 254156) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithExcessiveWeight() (gas: 259143) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithSameAddressAndWeight() (gas: 149856) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithUnderWeightSet() (gas: 259217) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientWeights() (gas: 372155) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientWithNewZeroAddress() (gas: 270700) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsContainsDuplicateRecipients() (gas: 288483) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentLargerSet() (gas: 407780) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentPartialSet() (gas: 317945) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSet() (gas: 377692) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSetWithInvalidWeights() (gas: 312038) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForLargerSet() (gas: 399603) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() (gas: 289433) -DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 639153) -DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNative() (gas: 640232) -DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrapped() (gas: 661796) -DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrappedReturnsChange() (gas: 661751) -DestinationVerifierConstructorTest:test_falseIfIsNotCorrectInterface() (gas: 8719) -DestinationVerifierConstructorTest:test_revertsIfInitializedWithEmptyVerifierProxy() (gas: 61121) -DestinationVerifierConstructorTest:test_trueIfIsCorrectInterface() (gas: 8604) -DestinationVerifierConstructorTest:test_typeAndVersion() (gas: 2818189) -DestinationVerifierProxyInitializeVerifierTest:test_correctlySetsTheOwner() (gas: 1035181) -DestinationVerifierProxyInitializeVerifierTest:test_correctlySetsVersion() (gas: 9841) -DestinationVerifierProxyInitializeVerifierTest:test_setVerifierCalledByNoOwner() (gas: 17483) -DestinationVerifierProxyInitializeVerifierTest:test_setVerifierOk() (gas: 30622) -DestinationVerifierProxyInitializeVerifierTest:test_setVerifierWhichDoesntHonourInterface() (gas: 16851) -DestinationVerifierSetAccessControllerTest:test_emitsTheCorrectEvent() (gas: 35391) -DestinationVerifierSetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 15089) -DestinationVerifierSetAccessControllerTest:test_successfullySetsNewAccessController() (gas: 34885) -DestinationVerifierSetAccessControllerTest:test_successfullySetsNewAccessControllerIsEmpty() (gas: 15007) -DestinationVerifierSetConfigTest:test_NoDonConfigAlreadyExists() (gas: 2874492) -DestinationVerifierSetConfigTest:test_addressesAndWeightsDoNotProduceSideEffectsInDonConfigIds() (gas: 1323177) -DestinationVerifierSetConfigTest:test_donConfigIdIsSameForSignersInDifferentOrder() (gas: 1290374) -DestinationVerifierSetConfigTest:test_removeLatestConfig() (gas: 786275) -DestinationVerifierSetConfigTest:test_removeLatestConfigWhenNoConfigShouldFail() (gas: 12870) -DestinationVerifierSetConfigTest:test_revertsIfCalledByNonOwner() (gas: 174936) -DestinationVerifierSetConfigTest:test_revertsIfDuplicateSigners() (gas: 171604) -DestinationVerifierSetConfigTest:test_revertsIfFaultToleranceIsZero() (gas: 168484) -DestinationVerifierSetConfigTest:test_revertsIfNotEnoughSigners() (gas: 11571) -DestinationVerifierSetConfigTest:test_revertsIfSetWithTooManySigners() (gas: 17943) -DestinationVerifierSetConfigTest:test_revertsIfSignerContainsZeroAddress() (gas: 324333) -DestinationVerifierSetConfigTest:test_setConfigActiveUnknownDonConfigId() (gas: 13102) -DestinationVerifierSetConfigTest:test_setConfigWithActivationTime() (gas: 1088176) -DestinationVerifierSetConfigTest:test_setConfigWithActivationTimeEarlierThanLatestConfigShouldFail() (gas: 1963414) -DestinationVerifierSetConfigTest:test_setConfigWithActivationTimeNoFutureTimeShouldFail() (gas: 259797) FeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52645) FeeManagerProcessFeeTest:test_DiscountIsReturnedForNative() (gas: 52595) FeeManagerProcessFeeTest:test_DiscountIsReturnedForNativeWithSurcharge() (gas: 78808) @@ -325,7 +108,6 @@ FeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 47 FeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 49938) FeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 78261) FeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 14919) -MultiVerifierBillingTests:test_multipleFeeManagersAndVerifiers() (gas: 4586990) RewardManagerClaimTest:test_claimAllRecipients() (gas: 277131) RewardManagerClaimTest:test_claimMultipleRecipients() (gas: 154341) RewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 330086) @@ -418,13 +200,6 @@ VerifierActivateFeedTest:test_revertsIfNoFeedExistsActivate() (gas: 13179) VerifierActivateFeedTest:test_revertsIfNoFeedExistsDeactivate() (gas: 13157) VerifierActivateFeedTest:test_revertsIfNotOwnerActivateFeed() (gas: 17109) VerifierActivateFeedTest:test_revertsIfNotOwnerDeactivateFeed() (gas: 17164) -VerifierBillingTests:test_rewardsAreDistributedAccordingToWeights() (gas: 1731717) -VerifierBillingTests:test_rewardsAreDistributedAccordingToWeightsMultipleWeigths() (gas: 4460715) -VerifierBillingTests:test_rewardsAreDistributedAccordingToWeightsUsingHistoricalConfigs() (gas: 2098833) -VerifierBillingTests:test_verifyWithLinkV3Report() (gas: 1591346) -VerifierBillingTests:test_verifyWithNativeERC20() (gas: 1467256) -VerifierBillingTests:test_verifyWithNativeUnwrapped() (gas: 1376447) -VerifierBillingTests:test_verifyWithNativeUnwrappedReturnsChange() (gas: 1383493) VerifierBulkVerifyBillingReport:test_verifyMultiVersions() (gas: 476595) VerifierBulkVerifyBillingReport:test_verifyMultiVersionsReturnsVerifiedReports() (gas: 474853) VerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 557541) @@ -437,7 +212,6 @@ VerifierDeactivateFeedWithVerifyTest:test_currentReportAllowsVerification() (gas VerifierDeactivateFeedWithVerifyTest:test_currentReportFailsVerification() (gas: 113388) VerifierDeactivateFeedWithVerifyTest:test_previousReportAllowsVerification() (gas: 99624) VerifierDeactivateFeedWithVerifyTest:test_previousReportFailsVerification() (gas: 69943) -VerifierInterfacesTest:test_DestinationContractInterfaces() (gas: 623467) VerifierProxyAccessControlledVerificationTest:test_proxiesToTheVerifierIfHasAccess() (gas: 208529) VerifierProxyAccessControlledVerificationTest:test_revertsIfNoAccess() (gas: 112345) VerifierProxyConstructorTest:test_correctlySetsTheCorrectAccessControllerInterface() (gas: 1485359) @@ -462,9 +236,6 @@ VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_correctlyUnsetsVeri VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_emitsAnEventAfterUnsettingVerifier() (gas: 17961) VerifierProxyVerifyTest:test_proxiesToTheCorrectVerifier() (gas: 204342) VerifierProxyVerifyTest:test_revertsIfNoVerifierConfigured() (gas: 117264) -VerifierSetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 17196) -VerifierSetAccessControllerTest:test_setFeeManagerWhichDoesntHonourInterface() (gas: 16571) -VerifierSetAccessControllerTest:test_successfullySetsNewFeeManager() (gas: 44855) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 542302) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 967768) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 523251) @@ -485,9 +256,6 @@ VerifierTestBillingReport:test_verifyWithLink() (gas: 275293) VerifierTestBillingReport:test_verifyWithNative() (gas: 316326) VerifierTestBillingReport:test_verifyWithNativeUnwrapped() (gas: 318574) VerifierTestBillingReport:test_verifyWithNativeUnwrappedReturnsChange() (gas: 325642) -VerifierVerifyBulkTest:test_revertsVerifyBulkIfNoAccess() (gas: 112867) -VerifierVerifyBulkTest:test_verifyBulkSingleCaseWithSingleConfig() (gas: 745046) -VerifierVerifyBulkTest:test_verifyBulkWithSingleConfigOneVerifyFails() (gas: 698203) VerifierVerifyMultipleConfigDigestTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 133961) VerifierVerifyMultipleConfigDigestTest:test_canVerifyOlderReportsWithOlderConfigs() (gas: 189865) VerifierVerifyMultipleConfigDigestTest:test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() (gas: 88216) @@ -502,18 +270,6 @@ VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedByNonProxy() (gas: 10 VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedWithIncorrectAddresses() (gas: 184077) VerifierVerifySingleConfigDigestTest:test_revertsIfWrongNumberOfSigners() (gas: 110042) VerifierVerifySingleConfigDigestTest:test_setsTheCorrectEpoch() (gas: 194592) -VerifierVerifyTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 861741) -VerifierVerifyTest:test_canVerifyOlderV3ReportsWithOlderConfigs() (gas: 815984) -VerifierVerifyTest:test_failToVerifyReportIfDupSigners() (gas: 450715) -VerifierVerifyTest:test_failToVerifyReportIfNoSigners() (gas: 426492) -VerifierVerifyTest:test_failToVerifyReportIfNotEnoughSigners() (gas: 434814) -VerifierVerifyTest:test_failToVerifyReportIfSignerNotInConfig() (gas: 456866) -VerifierVerifyTest:test_revertsVerifyIfNoAccess() (gas: 109465) -VerifierVerifyTest:test_rollingOutConfiguration() (gas: 1497254) -VerifierVerifyTest:test_scenarioRollingNewChainWithHistoricConfigs() (gas: 976162) -VerifierVerifyTest:test_verifyFailsWhenReportIsOlderThanConfig() (gas: 2303366) -VerifierVerifyTest:test_verifyReport() (gas: 1434811) -VerifierVerifyTest:test_verifyTooglingActiveFlagsDonConfigs() (gas: 1918797) Verifier_accessControlledVerify:testVerifyWithAccessControl_gas() (gas: 212077) Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithLinkFeeSuccess_gas() (gas: 519389) Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithNativeFeeSuccess_gas() (gas: 542808) diff --git a/contracts/gas-snapshots/shared.gas-snapshot b/contracts/gas-snapshots/shared.gas-snapshot index dda850089c..0848baa098 100644 --- a/contracts/gas-snapshots/shared.gas-snapshot +++ b/contracts/gas-snapshots/shared.gas-snapshot @@ -39,10 +39,10 @@ CallWithExactGas__callWithExactGas:test_CallWithExactGasSafeReturnDataExactGas() CallWithExactGas__callWithExactGas:test_NoContractReverts() (gas: 11559) CallWithExactGas__callWithExactGas:test_NoGasForCallExactCheckReverts() (gas: 15788) CallWithExactGas__callWithExactGas:test_NotEnoughGasForCallReverts() (gas: 16241) -CallWithExactGas__callWithExactGas:test_callWithExactGasSuccess(bytes,bytes4) (runs: 256, μ: 15766, ~: 15719) +CallWithExactGas__callWithExactGas:test_callWithExactGasSuccess(bytes,bytes4) (runs: 257, μ: 15767, ~: 15719) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractExactGasSuccess() (gas: 20116) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractReceiverErrorSuccess() (gas: 67721) -CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractSuccess(bytes,bytes4) (runs: 256, μ: 16276, ~: 16229) +CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractSuccess(bytes,bytes4) (runs: 257, μ: 16277, ~: 16229) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoContractSuccess() (gas: 12962) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoGasForCallExactCheckReturnFalseSuccess() (gas: 13005) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NotEnoughGasForCallReturnsFalseSuccess() (gas: 13317) diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index ec89b5a4b5..e2a4f29137 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -132,6 +132,12 @@ importers: hardhat-ignore-warnings: specifier: ^0.2.6 version: 0.2.11 + husky: + specifier: ^9.0.11 + version: 9.1.5 + lint-staged: + specifier: ^15.2.2 + version: 15.2.9 moment: specifier: ^2.30.1 version: 2.30.1 @@ -916,6 +922,10 @@ packages: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} + ansi-escapes@7.0.0: + resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + engines: {node: '>=18'} + ansi-regex@2.1.1: resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} engines: {node: '>=0.10.0'} @@ -924,6 +934,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -932,6 +946,10 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + antlr4@4.13.1-patch-1: resolution: {integrity: sha512-OjFLWWLzDMV9rdFhpvroCWR4ooktNg9/nvVYSA5z28wuVpU36QUNuioR1XLnQtcjVlf8npjyz593PxnU/f/Cow==} engines: {node: '>=16'} @@ -1145,6 +1163,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + change-case@3.0.2: resolution: {integrity: sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==} @@ -1176,6 +1198,14 @@ packages: resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} engines: {node: '>=6'} + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} + cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -1199,6 +1229,9 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + command-exists@1.2.9: resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} @@ -1214,6 +1247,10 @@ packages: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + commander@3.0.2: resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==} @@ -1370,6 +1407,9 @@ packages: elliptic@6.5.4: resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} + emoji-regex@10.4.0: + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1384,6 +1424,10 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -1522,9 +1566,16 @@ packages: resolution: {integrity: sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==} engines: {node: '>=6.5.0', npm: '>=3'} + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + evp_bytestokey@1.0.3: resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} @@ -1655,6 +1706,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} @@ -1673,6 +1728,10 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} @@ -1832,10 +1891,23 @@ packages: human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + husky@9.1.5: + resolution: {integrity: sha512-rowAVRUBfI0b4+niA4SJMhfQwc107VLkBUgEYYAOQAbqDCnra1nYh83hF/MDmhYs9t9n1E3DuKOrs2LYNC+0Ag==} + engines: {node: '>=18'} + hasBin: true + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} + ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + ignore@5.3.1: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} @@ -1925,6 +1997,14 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + + is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -1971,6 +2051,10 @@ packages: resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} engines: {node: '>= 0.4'} + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -2089,9 +2173,22 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + lint-staged@15.2.9: + resolution: {integrity: sha512-BZAt8Lk3sEnxw7tfxM7jeZlPRuT4M68O0/CwZhhaw6eeWu0Lz5eERE3m386InivXB64fp/mDID452h48tvKlRQ==} + engines: {node: '>=18.12.0'} + hasBin: true + + listr2@8.2.4: + resolution: {integrity: sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==} + engines: {node: '>=18.0.0'} + load-yaml-file@0.2.0: resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} engines: {node: '>=6'} @@ -2136,6 +2233,10 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + log-update@6.1.0: + resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} + engines: {node: '>=18'} + loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} @@ -2173,6 +2274,9 @@ packages: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -2185,6 +2289,14 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -2296,6 +2408,10 @@ packages: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + number-to-bn@1.7.0: resolution: {integrity: sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==} engines: {node: '>=6.5.0', npm: '>=3'} @@ -2321,6 +2437,14 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + open@7.4.2: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} engines: {node: '>=8'} @@ -2433,6 +2557,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -2455,6 +2583,11 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} @@ -2593,6 +2726,10 @@ packages: responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -2601,6 +2738,9 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} hasBin: true @@ -2722,6 +2862,10 @@ packages: signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + slash@2.0.0: resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} engines: {node: '>=6'} @@ -2734,6 +2878,14 @@ packages: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} + slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + + slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + snake-case@2.1.0: resolution: {integrity: sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==} @@ -2846,6 +2998,10 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + string-format@2.0.0: resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} @@ -2853,6 +3009,10 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + string.prototype.trim@1.2.8: resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} engines: {node: '>= 0.4'} @@ -2881,10 +3041,18 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + strip-hex-prefix@1.0.0: resolution: {integrity: sha1-DF8VX+8RUTczd96du1iNoFUA428=} engines: {node: '>=6.5.0', npm: '>=3'} @@ -3160,6 +3328,10 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -3198,6 +3370,11 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} + yaml@2.5.0: + resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==} + engines: {node: '>= 14'} + hasBin: true + yargs-parser@20.2.4: resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} engines: {node: '>=10'} @@ -3340,7 +3517,7 @@ snapshots: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - micromatch: 4.0.8 + micromatch: 4.0.5 '@changesets/errors@0.2.0': dependencies: @@ -3380,7 +3557,7 @@ snapshots: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 is-subdir: 1.2.0 - micromatch: 4.0.8 + micromatch: 4.0.5 spawndamnit: 2.0.0 '@changesets/logger@0.1.0': @@ -4419,10 +4596,16 @@ snapshots: dependencies: type-fest: 0.21.3 + ansi-escapes@7.0.0: + dependencies: + environment: 1.1.0 + ansi-regex@2.1.1: {} ansi-regex@5.0.1: {} + ansi-regex@6.0.1: {} + ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -4431,6 +4614,8 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@6.2.1: {} + antlr4@4.13.1-patch-1: {} anymatch@3.1.2: @@ -4686,6 +4871,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.3.0: {} + change-case@3.0.2: dependencies: camel-case: 3.0.0 @@ -4738,6 +4925,15 @@ snapshots: cli-boxes@2.2.1: {} + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-truncate@4.0.0: + dependencies: + slice-ansi: 5.0.0 + string-width: 7.2.0 + cliui@7.0.4: dependencies: string-width: 4.2.3 @@ -4762,6 +4958,8 @@ snapshots: color-name@1.1.4: {} + colorette@2.0.20: {} + command-exists@1.2.9: {} command-line-args@5.2.1: @@ -4780,6 +4978,8 @@ snapshots: commander@10.0.1: {} + commander@12.1.0: {} + commander@3.0.2: {} compare-versions@6.1.1: @@ -4961,6 +5161,8 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + emoji-regex@10.4.0: {} + emoji-regex@8.0.0: {} end-of-stream@1.4.4: @@ -4973,6 +5175,8 @@ snapshots: env-paths@2.2.1: {} + environment@1.1.0: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -5296,11 +5500,25 @@ snapshots: is-hex-prefixed: 1.0.0 strip-hex-prefix: 1.0.0 + eventemitter3@5.0.1: {} + evp_bytestokey@1.0.3: dependencies: md5.js: 1.3.5 safe-buffer: 5.2.1 + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + extendable-error@0.1.7: {} external-editor@3.1.0: @@ -5323,7 +5541,7 @@ snapshots: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.8 + micromatch: 4.0.5 fast-json-stable-stringify@2.1.0: {} @@ -5365,7 +5583,7 @@ snapshots: find-yarn-workspace-root2@1.2.16: dependencies: - micromatch: 4.0.8 + micromatch: 4.0.5 pkg-dir: 4.2.0 find-yarn-workspace-root@2.0.0: @@ -5443,6 +5661,8 @@ snapshots: get-caller-file@2.0.5: {} + get-east-asian-width@1.2.0: {} + get-func-name@2.0.2: {} get-intrinsic@1.2.2: @@ -5468,6 +5688,8 @@ snapshots: get-stream@6.0.1: {} + get-stream@8.0.1: {} + get-symbol-description@1.0.0: dependencies: call-bind: 1.0.5 @@ -5538,7 +5760,7 @@ snapshots: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.3.1 - ignore: 5.3.1 + ignore: 5.2.4 merge2: 1.4.1 slash: 3.0.0 @@ -5736,10 +5958,16 @@ snapshots: human-id@1.0.2: {} + human-signals@5.0.0: {} + + husky@9.1.5: {} + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 + ignore@5.2.4: {} + ignore@5.3.1: {} immutable@4.1.0: {} @@ -5831,6 +6059,12 @@ snapshots: is-fullwidth-code-point@3.0.0: {} + is-fullwidth-code-point@4.0.0: {} + + is-fullwidth-code-point@5.0.0: + dependencies: + get-east-asian-width: 1.2.0 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -5874,6 +6108,8 @@ snapshots: call-bind: 1.0.7 optional: true + is-stream@3.0.0: {} + is-string@1.0.7: dependencies: has-tostringtag: 1.0.0 @@ -5995,8 +6231,34 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + lilconfig@3.1.2: {} + lines-and-columns@1.2.4: {} + lint-staged@15.2.9: + dependencies: + chalk: 5.3.0 + commander: 12.1.0 + debug: 4.3.6 + execa: 8.0.1 + lilconfig: 3.1.2 + listr2: 8.2.4 + micromatch: 4.0.8 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.5.0 + transitivePeerDependencies: + - supports-color + + listr2@8.2.4: + dependencies: + cli-truncate: 4.0.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 6.1.0 + rfdc: 1.4.1 + wrap-ansi: 9.0.0 + load-yaml-file@0.2.0: dependencies: graceful-fs: 4.2.10 @@ -6038,6 +6300,14 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + log-update@6.1.0: + dependencies: + ansi-escapes: 7.0.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 + loupe@2.3.7: dependencies: get-func-name: 2.0.2 @@ -6071,6 +6341,8 @@ snapshots: memorystream@0.3.1: {} + merge-stream@2.0.0: {} + merge2@1.4.1: {} micromatch@4.0.5: @@ -6083,6 +6355,10 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mimic-fn@4.0.0: {} + + mimic-function@5.0.1: {} + mimic-response@1.0.1: {} mimic-response@3.1.0: {} @@ -6181,6 +6457,10 @@ snapshots: normalize-url@6.1.0: {} + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + number-to-bn@1.7.0: dependencies: bn.js: 4.11.6 @@ -6214,6 +6494,14 @@ snapshots: dependencies: wrappy: 1.0.2 + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + open@7.4.2: dependencies: is-docker: 2.2.1 @@ -6332,6 +6620,8 @@ snapshots: path-key@3.1.1: {} + path-key@4.0.0: {} + path-parse@1.0.7: {} path-starts-with@2.0.1: {} @@ -6350,6 +6640,8 @@ snapshots: picomatch@2.3.1: {} + pidtree@0.6.0: {} + pify@4.0.1: {} pkg-dir@4.2.0: @@ -6495,11 +6787,18 @@ snapshots: dependencies: lowercase-keys: 2.0.0 + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + retry@0.12.0: optional: true reusify@1.0.4: {} + rfdc@1.4.1: {} + rimraf@2.7.1: dependencies: glob: 7.2.3 @@ -6641,6 +6940,8 @@ snapshots: signal-exit@3.0.7: {} + signal-exit@4.1.0: {} + slash@2.0.0: {} slash@3.0.0: {} @@ -6651,6 +6952,16 @@ snapshots: astral-regex: 2.0.0 is-fullwidth-code-point: 3.0.0 + slice-ansi@5.0.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + + slice-ansi@7.1.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + snake-case@2.1.0: dependencies: no-case: 2.3.2 @@ -6773,6 +7084,8 @@ snapshots: statuses@2.0.1: {} + string-argv@0.3.2: {} + string-format@2.0.0: {} string-width@4.2.3: @@ -6781,6 +7094,12 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@7.2.0: + dependencies: + emoji-regex: 10.4.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + string.prototype.trim@1.2.8: dependencies: call-bind: 1.0.5 @@ -6832,8 +7151,14 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + strip-bom@3.0.0: {} + strip-final-newline@3.0.0: {} + strip-hex-prefix@1.0.0: dependencies: is-hex-prefixed: 1.0.0 @@ -7158,6 +7483,12 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@9.0.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 7.2.0 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} ws@7.4.6: {} @@ -7170,6 +7501,8 @@ snapshots: yaml@1.10.2: {} + yaml@2.5.0: {} + yargs-parser@20.2.4: {} yargs-unparser@2.0.0: diff --git a/contracts/src/v0.8/ccip/FeeQuoter.sol b/contracts/src/v0.8/ccip/FeeQuoter.sol index aea632fc4e..970485e90f 100644 --- a/contracts/src/v0.8/ccip/FeeQuoter.sol +++ b/contracts/src/v0.8/ccip/FeeQuoter.sol @@ -241,12 +241,9 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, } /// @inheritdoc IPriceRegistry - function getTokenPrices(address[] calldata tokens) - external - view - override - returns (Internal.TimestampedPackedUint224[] memory) - { + function getTokenPrices( + address[] calldata tokens + ) external view override returns (Internal.TimestampedPackedUint224[] memory) { uint256 length = tokens.length; Internal.TimestampedPackedUint224[] memory tokenPrices = new Internal.TimestampedPackedUint224[](length); for (uint256 i = 0; i < length; ++i) { @@ -256,22 +253,16 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, } /// @inheritdoc IFeeQuoter - function getTokenPriceFeedConfig(address token) - external - view - override - returns (IFeeQuoter.TokenPriceFeedConfig memory) - { + function getTokenPriceFeedConfig( + address token + ) external view override returns (IFeeQuoter.TokenPriceFeedConfig memory) { return s_usdPriceFeedsPerToken[token]; } /// @inheritdoc IPriceRegistry - function getDestinationChainGasPrice(uint64 destChainSelector) - external - view - override - returns (Internal.TimestampedPackedUint224 memory) - { + function getDestinationChainGasPrice( + uint64 destChainSelector + ) external view override returns (Internal.TimestampedPackedUint224 memory) { return s_usdPerUnitGasByDestChainSelector[destChainSelector]; } @@ -319,11 +310,9 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, /// @notice Gets the token price from a data feed address, rebased to the same units as s_usdPerToken /// @param priceFeedConfig token data feed configuration with valid data feed address (used to retrieve price & timestamp) /// @return tokenPrice data feed price answer rebased to s_usdPerToken units, with latest block timestamp - function _getTokenPriceFromDataFeed(IFeeQuoter.TokenPriceFeedConfig memory priceFeedConfig) - internal - view - returns (Internal.TimestampedPackedUint224 memory tokenPrice) - { + function _getTokenPriceFromDataFeed( + IFeeQuoter.TokenPriceFeedConfig memory priceFeedConfig + ) internal view returns (Internal.TimestampedPackedUint224 memory tokenPrice) { AggregatorV3Interface dataFeedContract = AggregatorV3Interface(priceFeedConfig.dataFeedAddress); ( /* uint80 roundID */ diff --git a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol index 0f1e9b9702..1fbfd22d1c 100644 --- a/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol +++ b/contracts/src/v0.8/ccip/MultiAggregateRateLimiter.sol @@ -196,11 +196,9 @@ contract MultiAggregateRateLimiter is IMessageInterceptor, AuthorizedCallers, IT /// @param remoteChainSelector chain selector to get rate limit tokens for. /// @return localTokens The local chain representation of the tokens that are rate limited. /// @return remoteTokens The remote representation of the tokens that are rate limited. - function getAllRateLimitTokens(uint64 remoteChainSelector) - external - view - returns (address[] memory localTokens, bytes[] memory remoteTokens) - { + function getAllRateLimitTokens( + uint64 remoteChainSelector + ) external view returns (address[] memory localTokens, bytes[] memory remoteTokens) { uint256 tokenCount = s_rateLimitedTokensLocalToRemote[remoteChainSelector].length(); localTokens = new address[](tokenCount); diff --git a/contracts/src/v0.8/ccip/RMN.sol b/contracts/src/v0.8/ccip/RMN.sol index deffb57fbe..3b9af7e0ce 100644 --- a/contracts/src/v0.8/ccip/RMN.sol +++ b/contracts/src/v0.8/ccip/RMN.sol @@ -732,11 +732,9 @@ contract RMN is IRMN, OwnerIsCreator, ITypeAndVersion { /// @return accumulatedWeight sum of weights of voters, will be zero if voting took place with an older config version /// @return blessed will be accurate regardless of when voting took place /// @dev This is a helper method for offchain code so efficiency is not really a concern. - function getBlessProgress(IRMN.TaggedRoot calldata taggedRoot) - external - view - returns (address[] memory blessVoteAddrs, uint16 accumulatedWeight, bool blessed) - { + function getBlessProgress( + IRMN.TaggedRoot calldata taggedRoot + ) external view returns (address[] memory blessVoteAddrs, uint16 accumulatedWeight, bool blessed) { bytes32 taggedRootHash = _taggedRootHash(taggedRoot); BlessVoteProgress memory progress = s_blessVoteProgressByTaggedRootHash[taggedRootHash]; blessed = progress.weightThresholdMet; @@ -762,7 +760,9 @@ contract RMN is IRMN, OwnerIsCreator, ITypeAndVersion { /// @return cursed might be true even if the owner has no active vote and accumulatedWeight < curseWeightThreshold, /// due to a retained curse from a prior config /// @dev This is a helper method for offchain code so efficiency is not really a concern. - function getCurseProgress(bytes16 subject) + function getCurseProgress( + bytes16 subject + ) external view returns (address[] memory curseVoteAddrs, bytes28[] memory cursesHashes, uint16 accumulatedWeight, bool cursed) diff --git a/contracts/src/v0.8/ccip/applications/CCIPClientExample.sol b/contracts/src/v0.8/ccip/applications/CCIPClientExample.sol index b105cf8b00..77816ceadb 100644 --- a/contracts/src/v0.8/ccip/applications/CCIPClientExample.sol +++ b/contracts/src/v0.8/ccip/applications/CCIPClientExample.sol @@ -57,13 +57,9 @@ contract CCIPClientExample is CCIPReceiver, OwnerIsCreator { delete s_chains[chainSelector]; } - function ccipReceive(Client.Any2EVMMessage calldata message) - external - virtual - override - onlyRouter - validChain(message.sourceChainSelector) - { + function ccipReceive( + Client.Any2EVMMessage calldata message + ) external virtual override onlyRouter validChain(message.sourceChainSelector) { // Extremely important to ensure only router calls this. // Tokens in message if any will be transferred to this contract // TODO: Validate sender/origin chain and process message and/or tokens. diff --git a/contracts/src/v0.8/ccip/applications/DefensiveExample.sol b/contracts/src/v0.8/ccip/applications/DefensiveExample.sol index 30b0972bb3..89435ccbf1 100644 --- a/contracts/src/v0.8/ccip/applications/DefensiveExample.sol +++ b/contracts/src/v0.8/ccip/applications/DefensiveExample.sol @@ -45,12 +45,9 @@ contract DefensiveExample is CCIPClientExample { /// never revert, all errors should be handled internally in this contract. /// @param message The message to process. /// @dev Extremely important to ensure only router calls this. - function ccipReceive(Client.Any2EVMMessage calldata message) - external - override - onlyRouter - validChain(message.sourceChainSelector) - { + function ccipReceive( + Client.Any2EVMMessage calldata message + ) external override onlyRouter validChain(message.sourceChainSelector) { try this.processMessage(message) {} catch (bytes memory err) { // Could set different error codes based on the caught error. Each could be @@ -70,11 +67,9 @@ contract DefensiveExample is CCIPClientExample { /// @dev This example just sends the tokens to the owner of this contracts. More /// interesting functions could be implemented. /// @dev It has to be external because of the try/catch. - function processMessage(Client.Any2EVMMessage calldata message) - external - onlySelf - validChain(message.sourceChainSelector) - { + function processMessage( + Client.Any2EVMMessage calldata message + ) external onlySelf validChain(message.sourceChainSelector) { // Simulate a revert if (s_simRevert) revert ErrorCase(); diff --git a/contracts/src/v0.8/ccip/applications/EtherSenderReceiver.sol b/contracts/src/v0.8/ccip/applications/EtherSenderReceiver.sol index ce8ed1ff7a..05d604d9c1 100644 --- a/contracts/src/v0.8/ccip/applications/EtherSenderReceiver.sol +++ b/contracts/src/v0.8/ccip/applications/EtherSenderReceiver.sol @@ -115,11 +115,9 @@ contract EtherSenderReceiver is CCIPReceiver, ITypeAndVersion { /// @notice Validate the message content. /// @dev Only allows a single token to be sent. Always overwritten to be address(i_weth) /// and receiver is always msg.sender. - function _validatedMessage(Client.EVM2AnyMessage calldata message) - internal - view - returns (Client.EVM2AnyMessage memory) - { + function _validatedMessage( + Client.EVM2AnyMessage calldata message + ) internal view returns (Client.EVM2AnyMessage memory) { Client.EVM2AnyMessage memory validatedMessage = message; if (validatedMessage.tokenAmounts.length != 1) { diff --git a/contracts/src/v0.8/ccip/applications/PingPongDemo.sol b/contracts/src/v0.8/ccip/applications/PingPongDemo.sol index 3697c7ff5a..b902c47618 100644 --- a/contracts/src/v0.8/ccip/applications/PingPongDemo.sol +++ b/contracts/src/v0.8/ccip/applications/PingPongDemo.sol @@ -62,7 +62,7 @@ contract PingPongDemo is CCIPReceiver, OwnerIsCreator, ITypeAndVersion { tokenAmounts: new Client.EVMTokenAmount[](0), extraArgs: Client._argsToBytes( Client.EVMExtraArgsV2({gasLimit: uint256(DEFAULT_GAS_LIMIT), allowOutOfOrderExecution: s_outOfOrderExecution}) - ), + ), feeToken: address(s_feeToken) }); IRouterClient(getRouter()).ccipSend(s_counterpartChainSelector, message); diff --git a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol index 9e43f23f66..ae1e4cc597 100644 --- a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol +++ b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol @@ -346,7 +346,9 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator /// @param ocr3Configs The OCR3 configurations to group. /// @return commitConfigs The commit configurations. /// @return execConfigs The execution configurations. - function _groupByPluginType(CCIPConfigTypes.OCR3Config[] memory ocr3Configs) + function _groupByPluginType( + CCIPConfigTypes.OCR3Config[] memory ocr3Configs + ) internal pure returns (CCIPConfigTypes.OCR3Config[] memory commitConfigs, CCIPConfigTypes.OCR3Config[] memory execConfigs) diff --git a/contracts/src/v0.8/ccip/interfaces/IPool.sol b/contracts/src/v0.8/ccip/interfaces/IPool.sol index e01f5fe38e..a2b9281228 100644 --- a/contracts/src/v0.8/ccip/interfaces/IPool.sol +++ b/contracts/src/v0.8/ccip/interfaces/IPool.sol @@ -11,9 +11,9 @@ interface IPoolV1 is IERC165 { /// @notice Lock tokens into the pool or burn the tokens. /// @param lockOrBurnIn Encoded data fields for the processing of tokens on the source chain. /// @return lockOrBurnOut Encoded data fields for the processing of tokens on the destination chain. - function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - external - returns (Pool.LockOrBurnOutV1 memory lockOrBurnOut); + function lockOrBurn( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) external returns (Pool.LockOrBurnOutV1 memory lockOrBurnOut); /// @notice Releases or mints tokens to the receiver address. /// @param releaseOrMintIn All data required to release or mint tokens. @@ -21,9 +21,9 @@ interface IPoolV1 is IERC165 { /// in the local token's decimals. /// @dev The offramp asserts that the balanceOf of the receiver has been incremented by exactly the number /// of tokens that is returned in ReleaseOrMintOutV1.destinationAmount. If the amounts do not match, the tx reverts. - function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - external - returns (Pool.ReleaseOrMintOutV1 memory); + function releaseOrMint( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) external returns (Pool.ReleaseOrMintOutV1 memory); /// @notice Checks whether a remote chain is supported in the token pool. /// @param remoteChainSelector The selector of the remote chain. diff --git a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol index a2c7bc1880..757ef09b0c 100644 --- a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol +++ b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol @@ -32,10 +32,9 @@ interface IPriceRegistry { /// PriceRegistry does not contain chain-specific logic to parse destination chain price components. /// @param destChainSelector The destination chain to get the price for. /// @return gasPrice The encoded gasPrice for the given destination chain ID. - function getDestinationChainGasPrice(uint64 destChainSelector) - external - view - returns (Internal.TimestampedPackedUint224 memory); + function getDestinationChainGasPrice( + uint64 destChainSelector + ) external view returns (Internal.TimestampedPackedUint224 memory); /// @notice Gets the fee token price and the gas price, both denominated in dollars. /// @param token The source token to get the price for. diff --git a/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol b/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol index 8ccd94b5e9..0c48b10e64 100644 --- a/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol @@ -716,11 +716,9 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, } /// @notice Gets the transfer fee config for a given token. - function getTokenTransferFeeConfig(address token) - external - view - returns (TokenTransferFeeConfig memory tokenTransferFeeConfig) - { + function getTokenTransferFeeConfig( + address token + ) external view returns (TokenTransferFeeConfig memory tokenTransferFeeConfig) { return s_tokenTransferFeeConfig[token]; } diff --git a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol index 947859eb01..3587854e90 100644 --- a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol @@ -374,11 +374,9 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { /// @return sequenceNumber The last used sequence number /// @return allowListEnabled boolean indicator to specify if allowList check is enabled /// @return router address of the router - function getDestChainConfig(uint64 destChainSelector) - public - view - returns (uint64 sequenceNumber, bool allowListEnabled, address router) - { + function getDestChainConfig( + uint64 destChainSelector + ) public view returns (uint64 sequenceNumber, bool allowListEnabled, address router) { DestChainConfig storage config = s_destChainConfigs[destChainSelector]; sequenceNumber = config.sequenceNumber; allowListEnabled = config.allowListEnabled; diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol index a31d4fd219..99908c91d0 100644 --- a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol @@ -14,12 +14,9 @@ abstract contract BurnMintTokenPoolAbstract is TokenPool { /// @notice Burn the token in the pool /// @dev The _validateLockOrBurn check is an essential security check - function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - external - virtual - override - returns (Pool.LockOrBurnOutV1 memory) - { + function lockOrBurn( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) external virtual override returns (Pool.LockOrBurnOutV1 memory) { _validateLockOrBurn(lockOrBurnIn); _burn(lockOrBurnIn.amount); @@ -31,12 +28,9 @@ abstract contract BurnMintTokenPoolAbstract is TokenPool { /// @notice Mint tokens from the pool to the recipient /// @dev The _validateReleaseOrMint check is an essential security check - function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - external - virtual - override - returns (Pool.ReleaseOrMintOutV1 memory) - { + function releaseOrMint( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) external virtual override returns (Pool.ReleaseOrMintOutV1 memory) { _validateReleaseOrMint(releaseOrMintIn); // Mint to the receiver diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol index 6ca8b7d6a0..6e3fb0f479 100644 --- a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAndProxy.sol @@ -19,12 +19,9 @@ contract BurnMintTokenPoolAndProxy is ITypeAndVersion, LegacyPoolWrapper { /// @notice Burn the token in the pool /// @dev The _validateLockOrBurn check is an essential security check - function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - external - virtual - override - returns (Pool.LockOrBurnOutV1 memory) - { + function lockOrBurn( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) external virtual override returns (Pool.LockOrBurnOutV1 memory) { _validateLockOrBurn(lockOrBurnIn); if (!_hasLegacyPool()) { @@ -40,12 +37,9 @@ contract BurnMintTokenPoolAndProxy is ITypeAndVersion, LegacyPoolWrapper { /// @notice Mint tokens from the pool to the recipient /// @dev The _validateReleaseOrMint check is an essential security check - function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - external - virtual - override - returns (Pool.ReleaseOrMintOutV1 memory) - { + function releaseOrMint( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) external virtual override returns (Pool.ReleaseOrMintOutV1 memory) { _validateReleaseOrMint(releaseOrMintIn); if (!_hasLegacyPool()) { diff --git a/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPoolAndProxy.sol b/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPoolAndProxy.sol index 7890d85824..324fd484a7 100644 --- a/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPoolAndProxy.sol +++ b/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPoolAndProxy.sol @@ -27,12 +27,9 @@ contract BurnWithFromMintTokenPoolAndProxy is ITypeAndVersion, LegacyPoolWrapper /// @notice Burn the token in the pool /// @dev The _validateLockOrBurn check is an essential security check - function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - external - virtual - override - returns (Pool.LockOrBurnOutV1 memory) - { + function lockOrBurn( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) external virtual override returns (Pool.LockOrBurnOutV1 memory) { _validateLockOrBurn(lockOrBurnIn); if (!_hasLegacyPool()) { @@ -48,12 +45,9 @@ contract BurnWithFromMintTokenPoolAndProxy is ITypeAndVersion, LegacyPoolWrapper /// @notice Mint tokens from the pool to the recipient /// @dev The _validateReleaseOrMint check is an essential security check - function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - external - virtual - override - returns (Pool.ReleaseOrMintOutV1 memory) - { + function releaseOrMint( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) external virtual override returns (Pool.ReleaseOrMintOutV1 memory) { _validateReleaseOrMint(releaseOrMintIn); if (!_hasLegacyPool()) { diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol index bc451f435a..3a4a4aef6d 100644 --- a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol @@ -44,12 +44,9 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion /// @notice Locks the token in the pool /// @dev The _validateLockOrBurn check is an essential security check - function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - external - virtual - override - returns (Pool.LockOrBurnOutV1 memory) - { + function lockOrBurn( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) external virtual override returns (Pool.LockOrBurnOutV1 memory) { _validateLockOrBurn(lockOrBurnIn); emit Locked(msg.sender, lockOrBurnIn.amount); @@ -59,12 +56,9 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion /// @notice Release tokens from the pool to the recipient /// @dev The _validateReleaseOrMint check is an essential security check - function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - external - virtual - override - returns (Pool.ReleaseOrMintOutV1 memory) - { + function releaseOrMint( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) external virtual override returns (Pool.ReleaseOrMintOutV1 memory) { _validateReleaseOrMint(releaseOrMintIn); // Release to the recipient diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol index af79e821b8..e8c39127de 100644 --- a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPoolAndProxy.sol @@ -42,12 +42,9 @@ contract LockReleaseTokenPoolAndProxy is LegacyPoolWrapper, ILiquidityContainer, /// @notice Locks the token in the pool /// @dev The _validateLockOrBurn check is an essential security check - function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - external - virtual - override - returns (Pool.LockOrBurnOutV1 memory) - { + function lockOrBurn( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) external virtual override returns (Pool.LockOrBurnOutV1 memory) { _validateLockOrBurn(lockOrBurnIn); if (_hasLegacyPool()) { @@ -61,12 +58,9 @@ contract LockReleaseTokenPoolAndProxy is LegacyPoolWrapper, ILiquidityContainer, /// @notice Release tokens from the pool to the recipient /// @dev The _validateReleaseOrMint check is an essential security check - function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - external - virtual - override - returns (Pool.ReleaseOrMintOutV1 memory) - { + function releaseOrMint( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) external virtual override returns (Pool.ReleaseOrMintOutV1 memory) { _validateReleaseOrMint(releaseOrMintIn); if (!_hasLegacyPool()) { diff --git a/contracts/src/v0.8/ccip/pools/TokenPool.sol b/contracts/src/v0.8/ccip/pools/TokenPool.sol index 0b87b6dfcb..b12a12ca7a 100644 --- a/contracts/src/v0.8/ccip/pools/TokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/TokenPool.sol @@ -325,21 +325,17 @@ abstract contract TokenPool is IPoolV1, OwnerIsCreator { /// @notice Gets the token bucket with its values for the block it was requested at. /// @return The token bucket. - function getCurrentOutboundRateLimiterState(uint64 remoteChainSelector) - external - view - returns (RateLimiter.TokenBucket memory) - { + function getCurrentOutboundRateLimiterState( + uint64 remoteChainSelector + ) external view returns (RateLimiter.TokenBucket memory) { return s_remoteChainConfigs[remoteChainSelector].outboundRateLimiterConfig._currentTokenBucketState(); } /// @notice Gets the token bucket with its values for the block it was requested at. /// @return The token bucket. - function getCurrentInboundRateLimiterState(uint64 remoteChainSelector) - external - view - returns (RateLimiter.TokenBucket memory) - { + function getCurrentInboundRateLimiterState( + uint64 remoteChainSelector + ) external view returns (RateLimiter.TokenBucket memory) { return s_remoteChainConfigs[remoteChainSelector].inboundRateLimiterConfig._currentTokenBucketState(); } diff --git a/contracts/src/v0.8/ccip/pools/USDC/HybridLockReleaseUSDCTokenPool.sol b/contracts/src/v0.8/ccip/pools/USDC/HybridLockReleaseUSDCTokenPool.sol index f38127825d..49cdeafcbc 100644 --- a/contracts/src/v0.8/ccip/pools/USDC/HybridLockReleaseUSDCTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/USDC/HybridLockReleaseUSDCTokenPool.sol @@ -53,12 +53,9 @@ contract HybridLockReleaseUSDCTokenPool is USDCTokenPool, USDCBridgeMigrator { /// @notice Locks the token in the pool /// @dev The _validateLockOrBurn check is an essential security check - function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - public - virtual - override - returns (Pool.LockOrBurnOutV1 memory) - { + function lockOrBurn( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) public virtual override returns (Pool.LockOrBurnOutV1 memory) { // // If the alternative mechanism (L/R) for chains which have it enabled if (!shouldUseLockRelease(lockOrBurnIn.remoteChainSelector)) { return super.lockOrBurn(lockOrBurnIn); @@ -75,12 +72,9 @@ contract HybridLockReleaseUSDCTokenPool is USDCTokenPool, USDCBridgeMigrator { /// @notice Release tokens from the pool to the recipient /// @dev The _validateReleaseOrMint check is an essential security check - function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - public - virtual - override - returns (Pool.ReleaseOrMintOutV1 memory) - { + function releaseOrMint( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) public virtual override returns (Pool.ReleaseOrMintOutV1 memory) { if (!shouldUseLockRelease(releaseOrMintIn.remoteChainSelector)) { return super.releaseOrMint(releaseOrMintIn); } @@ -88,11 +82,9 @@ contract HybridLockReleaseUSDCTokenPool is USDCTokenPool, USDCBridgeMigrator { } /// @notice Contains the alternative mechanism for incoming tokens, in this implementation is "Release" incoming tokens - function _lockReleaseIncomingMessage(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - internal - virtual - returns (Pool.ReleaseOrMintOutV1 memory) - { + function _lockReleaseIncomingMessage( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) internal virtual returns (Pool.ReleaseOrMintOutV1 memory) { _validateReleaseOrMint(releaseOrMintIn); // Decrease internal tracking of locked tokens to ensure accurate accounting for burnLockedUSDC() migration @@ -107,11 +99,9 @@ contract HybridLockReleaseUSDCTokenPool is USDCTokenPool, USDCBridgeMigrator { } /// @notice Contains the alternative mechanism, in this implementation is "Lock" on outgoing tokens - function _lockReleaseOutgoingMessage(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - internal - virtual - returns (Pool.LockOrBurnOutV1 memory) - { + function _lockReleaseOutgoingMessage( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) internal virtual returns (Pool.LockOrBurnOutV1 memory) { _validateLockOrBurn(lockOrBurnIn); // Increase internal accounting of locked tokens for burnLockedUSDC() migration diff --git a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol index e58b6374db..56ab40c9b5 100644 --- a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol @@ -96,12 +96,9 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { /// @notice Burn the token in the pool /// @dev emits ITokenMessenger.DepositForBurn /// @dev Assumes caller has validated destinationReceiver - function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - public - virtual - override - returns (Pool.LockOrBurnOutV1 memory) - { + function lockOrBurn( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) public virtual override returns (Pool.LockOrBurnOutV1 memory) { _validateLockOrBurn(lockOrBurnIn); Domain memory domain = s_chainToDomain[lockOrBurnIn.remoteChainSelector]; @@ -138,12 +135,9 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { /// for that message, including its (nonce, sourceDomain). This way, the only /// non-reverting offchainTokenData that can be supplied is a valid attestation for the /// specific message that was sent on source. - function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - public - virtual - override - returns (Pool.ReleaseOrMintOutV1 memory) - { + function releaseOrMint( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) public virtual override returns (Pool.ReleaseOrMintOutV1 memory) { _validateReleaseOrMint(releaseOrMintIn); SourceTokenDataPayload memory sourceTokenDataPayload = abi.decode(releaseOrMintIn.sourcePoolData, (SourceTokenDataPayload)); diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol index ebb51a9619..69afc7104e 100644 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -623,11 +623,9 @@ contract NonceManager_OffRampUpgrade is OffRampSetup { assertEq(startNonce + 2, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender)); } - function _generateSingleLaneRampReportFromMessages(Internal.EVM2EVMMessage[] memory messages) - internal - pure - returns (Internal.ExecutionReport memory) - { + function _generateSingleLaneRampReportFromMessages( + Internal.EVM2EVMMessage[] memory messages + ) internal pure returns (Internal.ExecutionReport memory) { bytes[][] memory offchainTokenData = new bytes[][](messages.length); for (uint256 i = 0; i < messages.length; ++i) { diff --git a/contracts/src/v0.8/ccip/test/attacks/onRamp/ReentrantMaliciousTokenPool.sol b/contracts/src/v0.8/ccip/test/attacks/onRamp/ReentrantMaliciousTokenPool.sol index 17c13a8148..5b6b367984 100644 --- a/contracts/src/v0.8/ccip/test/attacks/onRamp/ReentrantMaliciousTokenPool.sol +++ b/contracts/src/v0.8/ccip/test/attacks/onRamp/ReentrantMaliciousTokenPool.sol @@ -22,11 +22,9 @@ contract ReentrantMaliciousTokenPool is TokenPool { } /// @dev Calls into Facade to reenter Router exactly 1 time - function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - external - override - returns (Pool.LockOrBurnOutV1 memory) - { + function lockOrBurn( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) external override returns (Pool.LockOrBurnOutV1 memory) { if (s_attacked) { return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); @@ -39,12 +37,9 @@ contract ReentrantMaliciousTokenPool is TokenPool { return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); } - function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - external - pure - override - returns (Pool.ReleaseOrMintOutV1 memory) - { + function releaseOrMint( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) external pure override returns (Pool.ReleaseOrMintOutV1 memory) { return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); } } diff --git a/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol b/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol index 2ac30b355a..ca7f2114a6 100644 --- a/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol +++ b/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol @@ -63,10 +63,9 @@ contract CCIPConfigSetup is Test { if (i < right) _sort(arr, i, right); } - function _addChainConfig(uint256 numNodes) - internal - returns (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) - { + function _addChainConfig( + uint256 numNodes + ) internal returns (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) { p2pIds = _makeBytes32Array(numNodes, 0); _sort(p2pIds, 0, int256(numNodes - 1)); signers = _makeBytesArray(numNodes, 10); diff --git a/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol b/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol index cdbf1cef7a..f6dc8c25bf 100644 --- a/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol +++ b/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol @@ -725,9 +725,9 @@ contract FeeQuoter_updateTokenPriceFeeds is FeeQuoterSetup { } contract FeeQuoter_applyDestChainConfigUpdates is FeeQuoterSetup { - function test_Fuzz_applyDestChainConfigUpdates_Success(FeeQuoter.DestChainConfigArgs memory destChainConfigArgs) - public - { + function test_Fuzz_applyDestChainConfigUpdates_Success( + FeeQuoter.DestChainConfigArgs memory destChainConfigArgs + ) public { vm.assume(destChainConfigArgs.destChainSelector != 0); vm.assume(destChainConfigArgs.destChainConfig.maxPerMsgGasLimit != 0); destChainConfigArgs.destChainConfig.defaultTxGasLimit = uint32( diff --git a/contracts/src/v0.8/ccip/test/helpers/BurnMintMultiTokenPool.sol b/contracts/src/v0.8/ccip/test/helpers/BurnMintMultiTokenPool.sol index ec6f1d2047..bb1d4c9af3 100644 --- a/contracts/src/v0.8/ccip/test/helpers/BurnMintMultiTokenPool.sol +++ b/contracts/src/v0.8/ccip/test/helpers/BurnMintMultiTokenPool.sol @@ -18,12 +18,9 @@ contract BurnMintMultiTokenPool is MultiTokenPool { /// @notice Burn the token in the pool /// @dev The _validateLockOrBurn check is an essential security check - function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - external - virtual - override - returns (Pool.LockOrBurnOutV1 memory) - { + function lockOrBurn( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) external virtual override returns (Pool.LockOrBurnOutV1 memory) { _validateLockOrBurn(lockOrBurnIn); IBurnMintERC20(lockOrBurnIn.localToken).burn(lockOrBurnIn.amount); @@ -38,12 +35,9 @@ contract BurnMintMultiTokenPool is MultiTokenPool { /// @notice Mint tokens from the pool to the recipient /// @dev The _validateReleaseOrMint check is an essential security check - function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - external - virtual - override - returns (Pool.ReleaseOrMintOutV1 memory) - { + function releaseOrMint( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) external virtual override returns (Pool.ReleaseOrMintOutV1 memory) { _validateReleaseOrMint(releaseOrMintIn); // Mint to the receiver diff --git a/contracts/src/v0.8/ccip/test/helpers/CCIPConfigHelper.sol b/contracts/src/v0.8/ccip/test/helpers/CCIPConfigHelper.sol index 74f03890d3..efade5190b 100644 --- a/contracts/src/v0.8/ccip/test/helpers/CCIPConfigHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/CCIPConfigHelper.sol @@ -36,7 +36,9 @@ contract CCIPConfigHelper is CCIPConfig { return _computeNewConfigWithMeta(donId, currentConfig, newConfig, currentState, newState); } - function groupByPluginType(CCIPConfigTypes.OCR3Config[] memory ocr3Configs) + function groupByPluginType( + CCIPConfigTypes.OCR3Config[] memory ocr3Configs + ) public pure returns (CCIPConfigTypes.OCR3Config[] memory commitConfigs, CCIPConfigTypes.OCR3Config[] memory execConfigs) diff --git a/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol b/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol index b203315bc6..73e764ae03 100644 --- a/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol +++ b/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol @@ -30,12 +30,9 @@ contract MaybeRevertingBurnMintTokenPool is BurnMintTokenPool { s_releaseOrMintMultiplier = multiplier; } - function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - external - virtual - override - returns (Pool.LockOrBurnOutV1 memory) - { + function lockOrBurn( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) external virtual override returns (Pool.LockOrBurnOutV1 memory) { _validateLockOrBurn(lockOrBurnIn); bytes memory revertReason = s_revertReason; @@ -54,12 +51,9 @@ contract MaybeRevertingBurnMintTokenPool is BurnMintTokenPool { } /// @notice Reverts depending on the value of `s_revertReason` - function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - external - virtual - override - returns (Pool.ReleaseOrMintOutV1 memory) - { + function releaseOrMint( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) external virtual override returns (Pool.ReleaseOrMintOutV1 memory) { _validateReleaseOrMint(releaseOrMintIn); bytes memory revertReason = s_revertReason; diff --git a/contracts/src/v0.8/ccip/test/helpers/MessageHasher.sol b/contracts/src/v0.8/ccip/test/helpers/MessageHasher.sol index 19f35df796..d56cf8949a 100644 --- a/contracts/src/v0.8/ccip/test/helpers/MessageHasher.sol +++ b/contracts/src/v0.8/ccip/test/helpers/MessageHasher.sol @@ -12,11 +12,9 @@ contract MessageHasher { return Internal._hash(message, onRamp); } - function encodeTokenAmountsHashPreimage(Internal.RampTokenAmount[] memory rampTokenAmounts) - public - pure - returns (bytes memory) - { + function encodeTokenAmountsHashPreimage( + Internal.RampTokenAmount[] memory rampTokenAmounts + ) public pure returns (bytes memory) { return abi.encode(rampTokenAmounts); } diff --git a/contracts/src/v0.8/ccip/test/helpers/TokenPoolHelper.sol b/contracts/src/v0.8/ccip/test/helpers/TokenPoolHelper.sol index c57bfa3311..4965d1ed2f 100644 --- a/contracts/src/v0.8/ccip/test/helpers/TokenPoolHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/TokenPoolHelper.sol @@ -14,21 +14,15 @@ contract TokenPoolHelper is TokenPool { address router ) TokenPool(token, allowlist, rmnProxy, router) {} - function lockOrBurn(Pool.LockOrBurnInV1 calldata lockOrBurnIn) - external - view - override - returns (Pool.LockOrBurnOutV1 memory) - { + function lockOrBurn( + Pool.LockOrBurnInV1 calldata lockOrBurnIn + ) external view override returns (Pool.LockOrBurnOutV1 memory) { return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); } - function releaseOrMint(Pool.ReleaseOrMintInV1 calldata releaseOrMintIn) - external - pure - override - returns (Pool.ReleaseOrMintOutV1 memory) - { + function releaseOrMint( + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn + ) external pure override returns (Pool.ReleaseOrMintOutV1 memory) { return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); } diff --git a/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol b/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol index e53df4de1b..b69bbcaa43 100644 --- a/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol +++ b/contracts/src/v0.8/ccip/test/helpers/receivers/ReentrancyAbuser.sol @@ -36,11 +36,9 @@ contract ReentrancyAbuser is CCIPReceiver { } } - function _getGasLimitsFromMessages(Internal.EVM2EVMMessage[] memory messages) - internal - pure - returns (EVM2EVMOffRamp.GasLimitOverride[] memory) - { + function _getGasLimitsFromMessages( + Internal.EVM2EVMMessage[] memory messages + ) internal pure returns (EVM2EVMOffRamp.GasLimitOverride[] memory) { EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = new EVM2EVMOffRamp.GasLimitOverride[](messages.length); for (uint256 i = 0; i < messages.length; ++i) { gasLimitOverrides[i].receiverExecutionGasLimit = messages[i].gasLimit; diff --git a/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_4.sol b/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_4.sol index 9e80438239..168afee4f0 100644 --- a/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_4.sol +++ b/contracts/src/v0.8/ccip/test/legacy/BurnMintTokenPool1_4.sol @@ -211,21 +211,17 @@ abstract contract TokenPool1_4 is IPoolPriorTo1_5, OwnerIsCreator, IERC165 { /// @notice Gets the token bucket with its values for the block it was requested at. /// @return The token bucket. - function getCurrentOutboundRateLimiterState(uint64 remoteChainSelector) - external - view - returns (RateLimiter.TokenBucket memory) - { + function getCurrentOutboundRateLimiterState( + uint64 remoteChainSelector + ) external view returns (RateLimiter.TokenBucket memory) { return s_outboundRateLimits[remoteChainSelector]._currentTokenBucketState(); } /// @notice Gets the token bucket with its values for the block it was requested at. /// @return The token bucket. - function getCurrentInboundRateLimiterState(uint64 remoteChainSelector) - external - view - returns (RateLimiter.TokenBucket memory) - { + function getCurrentInboundRateLimiterState( + uint64 remoteChainSelector + ) external view returns (RateLimiter.TokenBucket memory) { return s_inboundRateLimits[remoteChainSelector]._currentTokenBucketState(); } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol index a5cb4f3d2b..8399637718 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRampSetup.t.sol @@ -91,11 +91,9 @@ contract EVM2EVMOffRampSetup is TokenSetup, FeeQuoterSetup, OCR2BaseSetup { }); } - function _convertToGeneralMessage(Internal.EVM2EVMMessage memory original) - internal - view - returns (Client.Any2EVMMessage memory message) - { + function _convertToGeneralMessage( + Internal.EVM2EVMMessage memory original + ) internal view returns (Client.Any2EVMMessage memory message) { uint256 numberOfTokens = original.tokenAmounts.length; Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](numberOfTokens); @@ -118,11 +116,9 @@ contract EVM2EVMOffRampSetup is TokenSetup, FeeQuoterSetup, OCR2BaseSetup { }); } - function _generateAny2EVMMessageNoTokens(uint64 sequenceNumber) - internal - view - returns (Internal.EVM2EVMMessage memory) - { + function _generateAny2EVMMessageNoTokens( + uint64 sequenceNumber + ) internal view returns (Internal.EVM2EVMMessage memory) { return _generateAny2EVMMessage(sequenceNumber, new Client.EVMTokenAmount[](0), false); } @@ -206,11 +202,9 @@ contract EVM2EVMOffRampSetup is TokenSetup, FeeQuoterSetup, OCR2BaseSetup { return messages; } - function _generateReportFromMessages(Internal.EVM2EVMMessage[] memory messages) - internal - pure - returns (Internal.ExecutionReport memory) - { + function _generateReportFromMessages( + Internal.EVM2EVMMessage[] memory messages + ) internal pure returns (Internal.ExecutionReport memory) { bytes[][] memory offchainTokenData = new bytes[][](messages.length); for (uint256 i = 0; i < messages.length; ++i) { @@ -225,11 +219,9 @@ contract EVM2EVMOffRampSetup is TokenSetup, FeeQuoterSetup, OCR2BaseSetup { }); } - function _getGasLimitsFromMessages(Internal.EVM2EVMMessage[] memory messages) - internal - pure - returns (EVM2EVMOffRamp.GasLimitOverride[] memory) - { + function _getGasLimitsFromMessages( + Internal.EVM2EVMMessage[] memory messages + ) internal pure returns (EVM2EVMOffRamp.GasLimitOverride[] memory) { EVM2EVMOffRamp.GasLimitOverride[] memory gasLimitOverrides = new EVM2EVMOffRamp.GasLimitOverride[](messages.length); for (uint256 i = 0; i < messages.length; ++i) { gasLimitOverrides[i].receiverExecutionGasLimit = messages[i].gasLimit; @@ -251,11 +243,9 @@ contract EVM2EVMOffRampSetup is TokenSetup, FeeQuoterSetup, OCR2BaseSetup { assertEq(a.maxDataBytes, b.maxDataBytes); } - function _getDefaultSourceTokenData(Client.EVMTokenAmount[] memory srcTokenAmounts) - internal - view - returns (bytes[] memory) - { + function _getDefaultSourceTokenData( + Client.EVMTokenAmount[] memory srcTokenAmounts + ) internal view returns (bytes[] memory) { bytes[] memory sourceTokenData = new bytes[](srcTokenAmounts.length); for (uint256 i = 0; i < srcTokenAmounts.length; ++i) { sourceTokenData[i] = abi.encode( diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol index 9167f3f075..ec8ac65008 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol @@ -2841,9 +2841,9 @@ contract OffRamp_applySourceChainConfigUpdates is OffRampSetup { } } - function test_Fuzz_applySourceChainConfigUpdate_Success(OffRamp.SourceChainConfigArgs memory sourceChainConfigArgs) - public - { + function test_Fuzz_applySourceChainConfigUpdate_Success( + OffRamp.SourceChainConfigArgs memory sourceChainConfigArgs + ) public { // Skip invalid inputs vm.assume(sourceChainConfigArgs.sourceChainSelector != 0); vm.assume(sourceChainConfigArgs.onRamp.length != 0); diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol index 403655f10a..ae9fc044ac 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol @@ -234,11 +234,9 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { }); } - function _convertToGeneralMessage(Internal.Any2EVMRampMessage memory original) - internal - view - returns (Client.Any2EVMMessage memory message) - { + function _convertToGeneralMessage( + Internal.Any2EVMRampMessage memory original + ) internal view returns (Client.Any2EVMMessage memory message) { uint256 numberOfTokens = original.tokenAmounts.length; Client.EVMTokenAmount[] memory destTokenAmounts = new Client.EVMTokenAmount[](numberOfTokens); @@ -374,11 +372,9 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { return reports; } - function _getGasLimitsFromMessages(Internal.Any2EVMRampMessage[] memory messages) - internal - pure - returns (uint256[] memory) - { + function _getGasLimitsFromMessages( + Internal.Any2EVMRampMessage[] memory messages + ) internal pure returns (uint256[] memory) { uint256[] memory gasLimits = new uint256[](messages.length); for (uint256 i = 0; i < messages.length; ++i) { gasLimits[i] = messages[i].gasLimit; @@ -405,11 +401,9 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { assertEq(address(config1.router), address(config2.router)); } - function _getDefaultSourceTokenData(Client.EVMTokenAmount[] memory srcTokenAmounts) - internal - view - returns (Internal.RampTokenAmount[] memory) - { + function _getDefaultSourceTokenData( + Client.EVMTokenAmount[] memory srcTokenAmounts + ) internal view returns (Internal.RampTokenAmount[] memory) { Internal.RampTokenAmount[] memory sourceTokenData = new Internal.RampTokenAmount[](srcTokenAmounts.length); for (uint256 i = 0; i < srcTokenAmounts.length; ++i) { sourceTokenData[i] = Internal.RampTokenAmount({ diff --git a/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol b/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol index e60d5542f4..b71094a310 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDCTokenPool.t.sol @@ -352,7 +352,7 @@ contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { bytes32(uint256(uint160(recipient))), amount, bytes32(uint256(uint160(OWNER))) - ) + ) }); bytes memory message = _generateUSDCMessage(usdcMessage); @@ -363,7 +363,7 @@ contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { destTokenAddress: abi.encode(address(s_usdcTokenPool)), extraData: abi.encode( USDCTokenPool.SourceTokenDataPayload({nonce: usdcMessage.nonce, sourceDomain: SOURCE_DOMAIN_IDENTIFIER}) - ), + ), destGasAmount: USDC_DEST_TOKEN_GAS }); @@ -460,7 +460,7 @@ contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { bytes32(uint256(uint160(OWNER))), amount, bytes32(uint256(uint160(OWNER))) - ) + ) }); Internal.SourceTokenData memory sourceTokenData = Internal.SourceTokenData({ @@ -468,7 +468,7 @@ contract USDCTokenPool_releaseOrMint is USDCTokenPoolSetup { destTokenAddress: abi.encode(address(s_usdcTokenPool)), extraData: abi.encode( USDCTokenPool.SourceTokenDataPayload({nonce: usdcMessage.nonce, sourceDomain: SOURCE_DOMAIN_IDENTIFIER}) - ), + ), destGasAmount: USDC_DEST_TOKEN_GAS }); diff --git a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol index 9fcf08f722..a7d73cc8b3 100644 --- a/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol +++ b/contracts/src/v0.8/ccip/test/rateLimiter/MultiAggregateRateLimiter.t.sol @@ -101,11 +101,9 @@ contract MultiAggregateRateLimiterSetup is BaseTest, FeeQuoterSetup { }); } - function _generateAny2EVMMessageNoTokens(uint64 sourceChainSelector) - internal - pure - returns (Client.Any2EVMMessage memory) - { + function _generateAny2EVMMessageNoTokens( + uint64 sourceChainSelector + ) internal pure returns (Client.Any2EVMMessage memory) { return _generateAny2EVMMessage(sourceChainSelector, new Client.EVMTokenAmount[](0)); } } @@ -1180,11 +1178,9 @@ contract MultiAggregateRateLimiter_onOutboundMessage is MultiAggregateRateLimite s_rateLimiter.onOutboundMessage(CHAIN_SELECTOR_1, _generateEVM2AnyMessageNoTokens()); } - function _generateEVM2AnyMessage(Client.EVMTokenAmount[] memory tokenAmounts) - public - view - returns (Client.EVM2AnyMessage memory) - { + function _generateEVM2AnyMessage( + Client.EVMTokenAmount[] memory tokenAmounts + ) public view returns (Client.EVM2AnyMessage memory) { return Client.EVM2AnyMessage({ receiver: abi.encode(OWNER), data: "", From 3e28ee64bac6e53a14326f62bac2cbdfb40aa59f Mon Sep 17 00:00:00 2001 From: asoliman Date: Fri, 30 Aug 2024 13:53:39 +0400 Subject: [PATCH 256/432] Run pnpm i & fix Operator.test.ts formatting run pnpm prettier --- contracts/package.json | 2 +- contracts/pnpm-lock.yaml | 352 --- .../v0.8/keystone/KeystoneFeedsConsumer.sol | 4 +- .../v0.8/operatorforwarder/Operator.test.ts | 2452 ++++++++--------- 4 files changed, 1229 insertions(+), 1581 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index c260c0a578..26fbd88570 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -88,4 +88,4 @@ "@scroll-tech/contracts": "0.1.0", "semver": "^7.6.3" } -} \ No newline at end of file +} diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index e2a4f29137..5c45da8ab0 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -132,12 +132,6 @@ importers: hardhat-ignore-warnings: specifier: ^0.2.6 version: 0.2.11 - husky: - specifier: ^9.0.11 - version: 9.1.5 - lint-staged: - specifier: ^15.2.2 - version: 15.2.9 moment: specifier: ^2.30.1 version: 2.30.1 @@ -922,10 +916,6 @@ packages: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} - ansi-escapes@7.0.0: - resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} - engines: {node: '>=18'} - ansi-regex@2.1.1: resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} engines: {node: '>=0.10.0'} @@ -934,10 +924,6 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -946,10 +932,6 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - antlr4@4.13.1-patch-1: resolution: {integrity: sha512-OjFLWWLzDMV9rdFhpvroCWR4ooktNg9/nvVYSA5z28wuVpU36QUNuioR1XLnQtcjVlf8npjyz593PxnU/f/Cow==} engines: {node: '>=16'} @@ -1075,10 +1057,6 @@ packages: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - brorand@1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} @@ -1163,10 +1141,6 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - change-case@3.0.2: resolution: {integrity: sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==} @@ -1198,14 +1172,6 @@ packages: resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} engines: {node: '>=6'} - cli-cursor@5.0.0: - resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} - engines: {node: '>=18'} - - cli-truncate@4.0.0: - resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} - engines: {node: '>=18'} - cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -1229,9 +1195,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - command-exists@1.2.9: resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} @@ -1247,10 +1210,6 @@ packages: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} - commander@12.1.0: - resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} - engines: {node: '>=18'} - commander@3.0.2: resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==} @@ -1407,9 +1366,6 @@ packages: elliptic@6.5.4: resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} - emoji-regex@10.4.0: - resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} - emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1424,10 +1380,6 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} - environment@1.1.0: - resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} - engines: {node: '>=18'} - error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -1566,16 +1518,9 @@ packages: resolution: {integrity: sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==} engines: {node: '>=6.5.0', npm: '>=3'} - eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - evp_bytestokey@1.0.3: resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} - extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} @@ -1614,10 +1559,6 @@ packages: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - find-replace@3.0.0: resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} engines: {node: '>=4.0.0'} @@ -1706,10 +1647,6 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.2.0: - resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} - engines: {node: '>=18'} - get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} @@ -1728,10 +1665,6 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} @@ -1891,15 +1824,6 @@ packages: human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - - husky@9.1.5: - resolution: {integrity: sha512-rowAVRUBfI0b4+niA4SJMhfQwc107VLkBUgEYYAOQAbqDCnra1nYh83hF/MDmhYs9t9n1E3DuKOrs2LYNC+0Ag==} - engines: {node: '>=18'} - hasBin: true - iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -1997,14 +1921,6 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} - - is-fullwidth-code-point@5.0.0: - resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} - engines: {node: '>=18'} - is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -2051,10 +1967,6 @@ packages: resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} engines: {node: '>= 0.4'} - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -2173,22 +2085,9 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lilconfig@3.1.2: - resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} - engines: {node: '>=14'} - lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lint-staged@15.2.9: - resolution: {integrity: sha512-BZAt8Lk3sEnxw7tfxM7jeZlPRuT4M68O0/CwZhhaw6eeWu0Lz5eERE3m386InivXB64fp/mDID452h48tvKlRQ==} - engines: {node: '>=18.12.0'} - hasBin: true - - listr2@8.2.4: - resolution: {integrity: sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==} - engines: {node: '>=18.0.0'} - load-yaml-file@0.2.0: resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} engines: {node: '>=6'} @@ -2233,10 +2132,6 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} - log-update@6.1.0: - resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} - engines: {node: '>=18'} - loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} @@ -2274,9 +2169,6 @@ packages: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -2285,18 +2177,6 @@ packages: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - - mimic-function@5.0.1: - resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} - engines: {node: '>=18'} - mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -2408,10 +2288,6 @@ packages: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - number-to-bn@1.7.0: resolution: {integrity: sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==} engines: {node: '>=6.5.0', npm: '>=3'} @@ -2437,14 +2313,6 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - - onetime@7.0.0: - resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} - engines: {node: '>=18'} - open@7.4.2: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} engines: {node: '>=8'} @@ -2557,10 +2425,6 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -2583,11 +2447,6 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - pidtree@0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} - engines: {node: '>=0.10'} - hasBin: true - pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} @@ -2726,10 +2585,6 @@ packages: responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} - restore-cursor@5.1.0: - resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} - engines: {node: '>=18'} - retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -2738,9 +2593,6 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rfdc@1.4.1: - resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} hasBin: true @@ -2862,10 +2714,6 @@ packages: signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - slash@2.0.0: resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} engines: {node: '>=6'} @@ -2878,14 +2726,6 @@ packages: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} - slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} - - slice-ansi@7.1.0: - resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} - engines: {node: '>=18'} - snake-case@2.1.0: resolution: {integrity: sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==} @@ -2998,10 +2838,6 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - string-argv@0.3.2: - resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} - engines: {node: '>=0.6.19'} - string-format@2.0.0: resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} @@ -3009,10 +2845,6 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} - string.prototype.trim@1.2.8: resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} engines: {node: '>= 0.4'} @@ -3041,18 +2873,10 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - strip-hex-prefix@1.0.0: resolution: {integrity: sha1-DF8VX+8RUTczd96du1iNoFUA428=} engines: {node: '>=6.5.0', npm: '>=3'} @@ -3328,10 +3152,6 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - wrap-ansi@9.0.0: - resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} - engines: {node: '>=18'} - wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -3370,11 +3190,6 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yaml@2.5.0: - resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==} - engines: {node: '>= 14'} - hasBin: true - yargs-parser@20.2.4: resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} engines: {node: '>=10'} @@ -4596,16 +4411,10 @@ snapshots: dependencies: type-fest: 0.21.3 - ansi-escapes@7.0.0: - dependencies: - environment: 1.1.0 - ansi-regex@2.1.1: {} ansi-regex@5.0.1: {} - ansi-regex@6.0.1: {} - ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -4614,8 +4423,6 @@ snapshots: dependencies: color-convert: 2.0.1 - ansi-styles@6.2.1: {} - antlr4@4.13.1-patch-1: {} anymatch@3.1.2: @@ -4759,10 +4566,6 @@ snapshots: dependencies: fill-range: 7.0.1 - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - brorand@1.1.0: {} browser-stdout@1.3.1: {} @@ -4871,8 +4674,6 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.3.0: {} - change-case@3.0.2: dependencies: camel-case: 3.0.0 @@ -4925,15 +4726,6 @@ snapshots: cli-boxes@2.2.1: {} - cli-cursor@5.0.0: - dependencies: - restore-cursor: 5.1.0 - - cli-truncate@4.0.0: - dependencies: - slice-ansi: 5.0.0 - string-width: 7.2.0 - cliui@7.0.4: dependencies: string-width: 4.2.3 @@ -4958,8 +4750,6 @@ snapshots: color-name@1.1.4: {} - colorette@2.0.20: {} - command-exists@1.2.9: {} command-line-args@5.2.1: @@ -4978,8 +4768,6 @@ snapshots: commander@10.0.1: {} - commander@12.1.0: {} - commander@3.0.2: {} compare-versions@6.1.1: @@ -5161,8 +4949,6 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - emoji-regex@10.4.0: {} - emoji-regex@8.0.0: {} end-of-stream@1.4.4: @@ -5175,8 +4961,6 @@ snapshots: env-paths@2.2.1: {} - environment@1.1.0: {} - error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -5500,25 +5284,11 @@ snapshots: is-hex-prefixed: 1.0.0 strip-hex-prefix: 1.0.0 - eventemitter3@5.0.1: {} - evp_bytestokey@1.0.3: dependencies: md5.js: 1.3.5 safe-buffer: 5.2.1 - execa@8.0.1: - dependencies: - cross-spawn: 7.0.3 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 - extendable-error@0.1.7: {} external-editor@3.1.0: @@ -5559,10 +5329,6 @@ snapshots: dependencies: to-regex-range: 5.0.1 - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - find-replace@3.0.0: dependencies: array-back: 3.1.0 @@ -5661,8 +5427,6 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.2.0: {} - get-func-name@2.0.2: {} get-intrinsic@1.2.2: @@ -5688,8 +5452,6 @@ snapshots: get-stream@6.0.1: {} - get-stream@8.0.1: {} - get-symbol-description@1.0.0: dependencies: call-bind: 1.0.5 @@ -5958,10 +5720,6 @@ snapshots: human-id@1.0.2: {} - human-signals@5.0.0: {} - - husky@9.1.5: {} - iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -6059,12 +5817,6 @@ snapshots: is-fullwidth-code-point@3.0.0: {} - is-fullwidth-code-point@4.0.0: {} - - is-fullwidth-code-point@5.0.0: - dependencies: - get-east-asian-width: 1.2.0 - is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -6108,8 +5860,6 @@ snapshots: call-bind: 1.0.7 optional: true - is-stream@3.0.0: {} - is-string@1.0.7: dependencies: has-tostringtag: 1.0.0 @@ -6231,34 +5981,8 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lilconfig@3.1.2: {} - lines-and-columns@1.2.4: {} - lint-staged@15.2.9: - dependencies: - chalk: 5.3.0 - commander: 12.1.0 - debug: 4.3.6 - execa: 8.0.1 - lilconfig: 3.1.2 - listr2: 8.2.4 - micromatch: 4.0.8 - pidtree: 0.6.0 - string-argv: 0.3.2 - yaml: 2.5.0 - transitivePeerDependencies: - - supports-color - - listr2@8.2.4: - dependencies: - cli-truncate: 4.0.0 - colorette: 2.0.20 - eventemitter3: 5.0.1 - log-update: 6.1.0 - rfdc: 1.4.1 - wrap-ansi: 9.0.0 - load-yaml-file@0.2.0: dependencies: graceful-fs: 4.2.10 @@ -6300,14 +6024,6 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 - log-update@6.1.0: - dependencies: - ansi-escapes: 7.0.0 - cli-cursor: 5.0.0 - slice-ansi: 7.1.0 - strip-ansi: 7.1.0 - wrap-ansi: 9.0.0 - loupe@2.3.7: dependencies: get-func-name: 2.0.2 @@ -6341,8 +6057,6 @@ snapshots: memorystream@0.3.1: {} - merge-stream@2.0.0: {} - merge2@1.4.1: {} micromatch@4.0.5: @@ -6350,15 +6064,6 @@ snapshots: braces: 3.0.2 picomatch: 2.3.1 - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - mimic-fn@4.0.0: {} - - mimic-function@5.0.1: {} - mimic-response@1.0.1: {} mimic-response@3.1.0: {} @@ -6457,10 +6162,6 @@ snapshots: normalize-url@6.1.0: {} - npm-run-path@5.3.0: - dependencies: - path-key: 4.0.0 - number-to-bn@1.7.0: dependencies: bn.js: 4.11.6 @@ -6494,14 +6195,6 @@ snapshots: dependencies: wrappy: 1.0.2 - onetime@6.0.0: - dependencies: - mimic-fn: 4.0.0 - - onetime@7.0.0: - dependencies: - mimic-function: 5.0.1 - open@7.4.2: dependencies: is-docker: 2.2.1 @@ -6620,8 +6313,6 @@ snapshots: path-key@3.1.1: {} - path-key@4.0.0: {} - path-parse@1.0.7: {} path-starts-with@2.0.1: {} @@ -6640,8 +6331,6 @@ snapshots: picomatch@2.3.1: {} - pidtree@0.6.0: {} - pify@4.0.1: {} pkg-dir@4.2.0: @@ -6787,18 +6476,11 @@ snapshots: dependencies: lowercase-keys: 2.0.0 - restore-cursor@5.1.0: - dependencies: - onetime: 7.0.0 - signal-exit: 4.1.0 - retry@0.12.0: optional: true reusify@1.0.4: {} - rfdc@1.4.1: {} - rimraf@2.7.1: dependencies: glob: 7.2.3 @@ -6940,8 +6622,6 @@ snapshots: signal-exit@3.0.7: {} - signal-exit@4.1.0: {} - slash@2.0.0: {} slash@3.0.0: {} @@ -6952,16 +6632,6 @@ snapshots: astral-regex: 2.0.0 is-fullwidth-code-point: 3.0.0 - slice-ansi@5.0.0: - dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 4.0.0 - - slice-ansi@7.1.0: - dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 5.0.0 - snake-case@2.1.0: dependencies: no-case: 2.3.2 @@ -7084,8 +6754,6 @@ snapshots: statuses@2.0.1: {} - string-argv@0.3.2: {} - string-format@2.0.0: {} string-width@4.2.3: @@ -7094,12 +6762,6 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@7.2.0: - dependencies: - emoji-regex: 10.4.0 - get-east-asian-width: 1.2.0 - strip-ansi: 7.1.0 - string.prototype.trim@1.2.8: dependencies: call-bind: 1.0.5 @@ -7151,14 +6813,8 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - strip-bom@3.0.0: {} - strip-final-newline@3.0.0: {} - strip-hex-prefix@1.0.0: dependencies: is-hex-prefixed: 1.0.0 @@ -7483,12 +7139,6 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - wrap-ansi@9.0.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 7.2.0 - strip-ansi: 7.1.0 - wrappy@1.0.2: {} ws@7.4.6: {} @@ -7501,8 +7151,6 @@ snapshots: yaml@1.10.2: {} - yaml@2.5.0: {} - yargs-parser@20.2.4: {} yargs-unparser@2.0.0: diff --git a/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol b/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol index 654e4e7f76..ba1a7c6a8c 100644 --- a/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol +++ b/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol @@ -87,9 +87,9 @@ contract KeystoneFeedsConsumer is IReceiver, OwnerIsCreator, IERC165 { // workflow_owner // offset 74, size 20 // report_name // offset 94, size 2 assembly { - // no shifting needed for bytes10 type + // no shifting needed for bytes10 type workflowName := mload(add(metadata, 64)) - // shift right by 12 bytes to get the actual value + // shift right by 12 bytes to get the actual value workflowOwner := shr(mul(12, 8), mload(add(metadata, 74))) } } diff --git a/contracts/test/v0.8/operatorforwarder/Operator.test.ts b/contracts/test/v0.8/operatorforwarder/Operator.test.ts index 96e882979c..6fb8768f54 100644 --- a/contracts/test/v0.8/operatorforwarder/Operator.test.ts +++ b/contracts/test/v0.8/operatorforwarder/Operator.test.ts @@ -50,34 +50,34 @@ before(async () => { roles = users.roles basicConsumerFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/BasicConsumer.sol:BasicConsumer', + 'src/v0.8/operatorforwarder/test/testhelpers/BasicConsumer.sol:BasicConsumer', ) multiWordConsumerFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/MultiWordConsumer.sol:MultiWordConsumer', + 'src/v0.8/operatorforwarder/test/testhelpers/MultiWordConsumer.sol:MultiWordConsumer', ) gasGuzzlingConsumerFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/GasGuzzlingConsumer.sol:GasGuzzlingConsumer', + 'src/v0.8/operatorforwarder/test/testhelpers/GasGuzzlingConsumer.sol:GasGuzzlingConsumer', ) getterSetterFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/GetterSetter.sol:GetterSetter', + 'src/v0.8/operatorforwarder/test/testhelpers/GetterSetter.sol:GetterSetter', ) maliciousRequesterFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/MaliciousRequester.sol:MaliciousRequester', + 'src/v0.8/operatorforwarder/test/testhelpers/MaliciousRequester.sol:MaliciousRequester', ) maliciousConsumerFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/MaliciousConsumer.sol:MaliciousConsumer', + 'src/v0.8/operatorforwarder/test/testhelpers/MaliciousConsumer.sol:MaliciousConsumer', ) maliciousMultiWordConsumerFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/test/testhelpers/MaliciousMultiWordConsumer.sol:MaliciousMultiWordConsumer', + 'src/v0.8/operatorforwarder/test/testhelpers/MaliciousMultiWordConsumer.sol:MaliciousMultiWordConsumer', ) operatorFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/Operator.sol:Operator', + 'src/v0.8/operatorforwarder/Operator.sol:Operator', ) forwarderFactory = await ethers.getContractFactory( - 'src/v0.8/operatorforwarder/AuthorizedForwarder.sol:AuthorizedForwarder', + 'src/v0.8/operatorforwarder/AuthorizedForwarder.sol:AuthorizedForwarder', ) linkTokenFactory = await ethers.getContractFactory( - 'src/v0.8/shared/test/helpers/LinkTokenTestHelper.sol:LinkTokenTestHelper', + 'src/v0.8/shared/test/helpers/LinkTokenTestHelper.sol:LinkTokenTestHelper', ) }) @@ -94,16 +94,16 @@ describe('Operator', () => { beforeEach(async () => { fHash = getterSetterFactory.interface.getSighash('requestedBytes32') specId = - '0x4c7b7ffb66b344fbaa64995af81e355a00000000000000000000000000000000' + '0x4c7b7ffb66b344fbaa64995af81e355a00000000000000000000000000000000' to = '0x80e29acb842498fe6591f020bd82766dce619d43' link = await linkTokenFactory.connect(roles.defaultAccount).deploy() owner = roles.defaultAccount operator = await operatorFactory - .connect(owner) - .deploy(link.address, await owner.getAddress()) + .connect(owner) + .deploy(link.address, await owner.getAddress()) await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders([await roles.oracleNode.getAddress()]) + .connect(roles.defaultAccount) + .setAuthorizedSenders([await roles.oracleNode.getAddress()]) }) it('has a limited public interface [ @skip-coverage ]', () => { @@ -146,30 +146,30 @@ describe('Operator', () => { describe('#transferOwnableContracts', () => { beforeEach(async () => { forwarder1 = await forwarderFactory - .connect(owner) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(owner) + .deploy(link.address, operator.address, zeroAddress, '0x') forwarder2 = await forwarderFactory - .connect(owner) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(owner) + .deploy(link.address, operator.address, zeroAddress, '0x') }) describe('being called by the owner', () => { it('cannot transfer to self', async () => { await evmRevert( - operator - .connect(owner) - .transferOwnableContracts([forwarder1.address], operator.address), - 'Cannot transfer to self', + operator + .connect(owner) + .transferOwnableContracts([forwarder1.address], operator.address), + 'Cannot transfer to self', ) }) it('emits an ownership transfer request event', async () => { const tx = await operator - .connect(owner) - .transferOwnableContracts( - [forwarder1.address, forwarder2.address], - await roles.oracleNode1.getAddress(), - ) + .connect(owner) + .transferOwnableContracts( + [forwarder1.address, forwarder2.address], + await roles.oracleNode1.getAddress(), + ) const receipt = await tx.wait() assert.equal(receipt?.events?.length, 2) const log1 = receipt?.events?.[0] @@ -188,13 +188,13 @@ describe('Operator', () => { describe('being called by a non-owner', () => { it('reverts with message', async () => { await evmRevert( - operator - .connect(roles.stranger) - .transferOwnableContracts( - [forwarder1.address], - await roles.oracleNode2.getAddress(), - ), - 'Only callable by owner', + operator + .connect(roles.stranger) + .transferOwnableContracts( + [forwarder1.address], + await roles.oracleNode2.getAddress(), + ), + 'Only callable by owner', ) }) }) @@ -207,23 +207,23 @@ describe('Operator', () => { beforeEach(async () => { operator2 = await operatorFactory - .connect(roles.defaultAccount) - .deploy(link.address, await roles.defaultAccount.getAddress()) + .connect(roles.defaultAccount) + .deploy(link.address, await roles.defaultAccount.getAddress()) forwarder1 = await forwarderFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, zeroAddress, '0x') forwarder2 = await forwarderFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, zeroAddress, '0x') await operator - .connect(roles.defaultAccount) - .transferOwnableContracts( - [forwarder1.address, forwarder2.address], - operator2.address, - ) + .connect(roles.defaultAccount) + .transferOwnableContracts( + [forwarder1.address, forwarder2.address], + operator2.address, + ) const tx = await operator2 - .connect(roles.defaultAccount) - .acceptOwnableContracts([forwarder1.address, forwarder2.address]) + .connect(roles.defaultAccount) + .acceptOwnableContracts([forwarder1.address, forwarder2.address]) receipt = await tx.wait() }) @@ -253,8 +253,8 @@ describe('Operator', () => { describe('being called by a non-owner authorized sender', () => { it('does not revert', async () => { await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders([await roles.oracleNode1.getAddress()]) + .connect(roles.defaultAccount) + .setAuthorizedSenders([await roles.oracleNode1.getAddress()]) await operator.connect(roles.oracleNode1).acceptOwnableContracts([]) }) @@ -263,10 +263,10 @@ describe('Operator', () => { describe('being called by a non owner', () => { it('reverts with message', async () => { await evmRevert( - operator - .connect(roles.stranger) - .acceptOwnableContracts([await roles.oracleNode2.getAddress()]), - 'Cannot set authorized senders', + operator + .connect(roles.stranger) + .acceptOwnableContracts([await roles.oracleNode2.getAddress()]), + 'Cannot set authorized senders', ) }) }) @@ -276,8 +276,8 @@ describe('Operator', () => { describe('when called with empty arrays', () => { it('reverts with invalid array message', async () => { await evmRevert( - operator.connect(roles.defaultAccount).distributeFunds([], []), - 'Invalid array length(s)', + operator.connect(roles.defaultAccount).distributeFunds([], []), + 'Invalid array length(s)', ) }) }) @@ -290,10 +290,10 @@ describe('Operator', () => { ] const amounts = [1, 2, 3] await evmRevert( - operator - .connect(roles.defaultAccount) - .distributeFunds(receivers, amounts), - 'Invalid array length(s)', + operator + .connect(roles.defaultAccount) + .distributeFunds(receivers, amounts), + 'Invalid array length(s)', ) }) }) @@ -304,15 +304,15 @@ describe('Operator', () => { const amountToSend = toWei('2') const ethSent = toWei('1') await expect( - operator - .connect(roles.defaultAccount) - .distributeFunds( - [await roles.oracleNode2.getAddress()], - [amountToSend], - { - value: ethSent, - }, - ), + operator + .connect(roles.defaultAccount) + .distributeFunds( + [await roles.oracleNode2.getAddress()], + [amountToSend], + { + value: ethSent, + }, + ), ).to.be.revertedWithPanic(0x11) }) }) @@ -322,16 +322,16 @@ describe('Operator', () => { const amountToSend = toWei('2') const ethSent = toWei('3') await evmRevert( - operator - .connect(roles.defaultAccount) - .distributeFunds( - [await roles.oracleNode2.getAddress()], - [amountToSend], - { - value: ethSent, - }, - ), - 'Too much ETH sent', + operator + .connect(roles.defaultAccount) + .distributeFunds( + [await roles.oracleNode2.getAddress()], + [amountToSend], + { + value: ethSent, + }, + ), + 'Too much ETH sent', ) }) }) @@ -350,20 +350,20 @@ describe('Operator', () => { const amounts = [sendNode2, sendNode3] await operator - .connect(roles.defaultAccount) - .distributeFunds(receivers, amounts, { value: totalAmount }) + .connect(roles.defaultAccount) + .distributeFunds(receivers, amounts, { value: totalAmount }) const node2BalanceAfter = await roles.oracleNode2.getBalance() const node3BalanceAfter = await roles.oracleNode3.getBalance() assert.equal( - node2BalanceAfter.sub(node2BalanceBefore).toString(), - sendNode2.toString(), + node2BalanceAfter.sub(node2BalanceBefore).toString(), + sendNode2.toString(), ) assert.equal( - node3BalanceAfter.sub(node3BalanceBefore).toString(), - sendNode3.toString(), + node3BalanceAfter.sub(node3BalanceBefore).toString(), + sendNode3.toString(), ) }) }) @@ -381,8 +381,8 @@ describe('Operator', () => { await roles.oracleNode3.getAddress(), ] const tx = await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders(newSenders) + .connect(roles.defaultAccount) + .setAuthorizedSenders(newSenders) receipt = await tx.wait() }) @@ -398,8 +398,8 @@ describe('Operator', () => { assert.equal(receipt.events?.length, 1) const encodedSenders1 = ethers.utils.defaultAbiCoder.encode( - ['address[]', 'address'], - [newSenders, await roles.defaultAccount.getAddress()], + ['address[]', 'address'], + [newSenders, await roles.defaultAccount.getAddress()], ) const responseEvent1 = receipt.events?.[0] @@ -409,15 +409,15 @@ describe('Operator', () => { it('replaces the authorized nodes', async () => { const originalAuthorization = await operator - .connect(roles.defaultAccount) - .isAuthorizedSender(await roles.oracleNode.getAddress()) + .connect(roles.defaultAccount) + .isAuthorizedSender(await roles.oracleNode.getAddress()) assert.isFalse(originalAuthorization) }) after(async () => { await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders([await roles.oracleNode.getAddress()]) + .connect(roles.defaultAccount) + .setAuthorizedSenders([await roles.oracleNode.getAddress()]) }) }) @@ -428,10 +428,10 @@ describe('Operator', () => { it('reverts with a minimum senders message', async () => { await evmRevert( - operator - .connect(roles.defaultAccount) - .setAuthorizedSenders(newSenders), - 'Must have at least 1 sender', + operator + .connect(roles.defaultAccount) + .setAuthorizedSenders(newSenders), + 'Must have at least 1 sender', ) }) }) @@ -441,24 +441,24 @@ describe('Operator', () => { beforeEach(async () => { newSenders = [await roles.oracleNode1.getAddress()] await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders(newSenders) + .connect(roles.defaultAccount) + .setAuthorizedSenders(newSenders) }) it('succeeds', async () => { await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders([await roles.stranger.getAddress()]) + .connect(roles.defaultAccount) + .setAuthorizedSenders([await roles.stranger.getAddress()]) }) }) describe('when called by a non-owner', () => { it('cannot add an authorized node', async () => { await evmRevert( - operator - .connect(roles.stranger) - .setAuthorizedSenders([await roles.stranger.getAddress()]), - 'Cannot set authorized senders', + operator + .connect(roles.stranger) + .setAuthorizedSenders([await roles.stranger.getAddress()]), + 'Cannot set authorized senders', ) }) }) @@ -469,28 +469,28 @@ describe('Operator', () => { beforeEach(async () => { await operator - .connect(roles.defaultAccount) - .setAuthorizedSenders([await roles.oracleNode1.getAddress()]) + .connect(roles.defaultAccount) + .setAuthorizedSenders([await roles.oracleNode1.getAddress()]) newSenders = [ await roles.oracleNode2.getAddress(), await roles.oracleNode3.getAddress(), ] forwarder1 = await forwarderFactory - .connect(owner) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(owner) + .deploy(link.address, operator.address, zeroAddress, '0x') forwarder2 = await forwarderFactory - .connect(owner) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(owner) + .deploy(link.address, operator.address, zeroAddress, '0x') }) describe('when called by a non-authorized sender', () => { it('reverts', async () => { await evmRevert( - operator - .connect(roles.stranger) - .setAuthorizedSendersOn(newSenders, [forwarder1.address]), - 'Cannot set authorized senders', + operator + .connect(roles.stranger) + .setAuthorizedSendersOn(newSenders, [forwarder1.address]), + 'Cannot set authorized senders', ) }) }) @@ -498,43 +498,43 @@ describe('Operator', () => { describe('when called by an owner', () => { it('does not revert', async () => { await operator - .connect(roles.defaultAccount) - .setAuthorizedSendersOn( - [forwarder1.address, forwarder2.address], - newSenders, - ) + .connect(roles.defaultAccount) + .setAuthorizedSendersOn( + [forwarder1.address, forwarder2.address], + newSenders, + ) }) }) describe('when called by an authorized sender', () => { it('does not revert', async () => { await operator - .connect(roles.oracleNode1) - .setAuthorizedSendersOn( - [forwarder1.address, forwarder2.address], - newSenders, - ) + .connect(roles.oracleNode1) + .setAuthorizedSendersOn( + [forwarder1.address, forwarder2.address], + newSenders, + ) }) it('does revert with 0 senders', async () => { await operator - .connect(roles.oracleNode1) - .setAuthorizedSendersOn( - [forwarder1.address, forwarder2.address], - newSenders, - ) + .connect(roles.oracleNode1) + .setAuthorizedSendersOn( + [forwarder1.address, forwarder2.address], + newSenders, + ) }) it('emits a log announcing the change and who made it', async () => { const targets = [forwarder1.address, forwarder2.address] const tx = await operator - .connect(roles.oracleNode1) - .setAuthorizedSendersOn(targets, newSenders) + .connect(roles.oracleNode1) + .setAuthorizedSendersOn(targets, newSenders) const receipt = await tx.wait() const encodedArgs = ethers.utils.defaultAbiCoder.encode( - ['address[]', 'address[]', 'address'], - [targets, newSenders, await roles.oracleNode1.getAddress()], + ['address[]', 'address[]', 'address'], + [targets, newSenders, await roles.oracleNode1.getAddress()], ) const event1 = receipt.events?.[0] @@ -545,17 +545,17 @@ describe('Operator', () => { it('updates the sender list on each of the targets', async () => { const tx = await operator - .connect(roles.oracleNode1) - .setAuthorizedSendersOn( - [forwarder1.address, forwarder2.address], - newSenders, - ) + .connect(roles.oracleNode1) + .setAuthorizedSendersOn( + [forwarder1.address, forwarder2.address], + newSenders, + ) const receipt = await tx.wait() assert.equal(receipt.events?.length, 3, receipt.toString()) const encodedSenders = ethers.utils.defaultAbiCoder.encode( - ['address[]', 'address'], - [newSenders, operator.address], + ['address[]', 'address'], + [newSenders, operator.address], ) const event1 = receipt.events?.[1] @@ -580,31 +580,31 @@ describe('Operator', () => { beforeEach(async () => { operator2 = await operatorFactory - .connect(roles.defaultAccount) - .deploy(link.address, await roles.defaultAccount.getAddress()) + .connect(roles.defaultAccount) + .deploy(link.address, await roles.defaultAccount.getAddress()) forwarder1 = await forwarderFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, zeroAddress, '0x') forwarder2 = await forwarderFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, zeroAddress, '0x') + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, zeroAddress, '0x') await operator - .connect(roles.defaultAccount) - .transferOwnableContracts( - [forwarder1.address, forwarder2.address], - operator2.address, - ) + .connect(roles.defaultAccount) + .transferOwnableContracts( + [forwarder1.address, forwarder2.address], + operator2.address, + ) newSenders = [ await roles.oracleNode2.getAddress(), await roles.oracleNode3.getAddress(), ] const tx = await operator2 - .connect(roles.defaultAccount) - .acceptAuthorizedReceivers( - [forwarder1.address, forwarder2.address], - newSenders, - ) + .connect(roles.defaultAccount) + .acceptAuthorizedReceivers( + [forwarder1.address, forwarder2.address], + newSenders, + ) receipt = await tx.wait() }) @@ -630,13 +630,13 @@ describe('Operator', () => { assert.equal(receipt?.events?.[3]?.args?.[1], operator2.address) assert.equal( - receipt?.events?.[4]?.event, - 'TargetsUpdatedAuthorizedSenders', + receipt?.events?.[4]?.event, + 'TargetsUpdatedAuthorizedSenders', ) const encodedSenders = ethers.utils.defaultAbiCoder.encode( - ['address[]', 'address'], - [newSenders, operator2.address], + ['address[]', 'address'], + [newSenders, operator2.address], ) assert.equal(receipt?.events?.[5]?.event, 'AuthorizedSendersChanged') assert.equal(receipt?.events?.[5]?.address, forwarder1.address) @@ -651,13 +651,13 @@ describe('Operator', () => { describe('being called by a non owner', () => { it('reverts with message', async () => { await evmRevert( - operator - .connect(roles.stranger) - .acceptAuthorizedReceivers( - [forwarder1.address, forwarder2.address], - newSenders, - ), - 'Cannot set authorized senders', + operator + .connect(roles.stranger) + .acceptAuthorizedReceivers( + [forwarder1.address, forwarder2.address], + newSenders, + ), + 'Cannot set authorized senders', ) }) }) @@ -667,19 +667,19 @@ describe('Operator', () => { describe('when called from any address but the LINK token', () => { it('triggers the intended method', async () => { const callData = encodeOracleRequest( - specId, - to, - fHash, - 0, - constants.HashZero, + specId, + to, + fHash, + 0, + constants.HashZero, ) await evmRevert( - operator.onTokenTransfer( - await roles.defaultAccount.getAddress(), - 0, - callData, - ), + operator.onTokenTransfer( + await roles.defaultAccount.getAddress(), + 0, + callData, + ), ) }) }) @@ -687,11 +687,11 @@ describe('Operator', () => { describe('when called from the LINK token', () => { it('triggers the intended method', async () => { const callData = encodeOracleRequest( - specId, - to, - fHash, - 0, - constants.HashZero, + specId, + to, + fHash, + 0, + constants.HashZero, ) const tx = await link.transferAndCall(operator.address, 0, callData, { @@ -705,9 +705,9 @@ describe('Operator', () => { describe('with no data', () => { it('reverts', async () => { await evmRevert( - link.transferAndCall(operator.address, 0, '0x', { - value: 0, - }), + link.transferAndCall(operator.address, 0, '0x', { + value: 0, + }), ) }) }) @@ -720,8 +720,8 @@ describe('Operator', () => { beforeEach(async () => { mock = await maliciousRequesterFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(mock.address, paymentAmount) }) @@ -750,8 +750,8 @@ describe('Operator', () => { it('the target requester can still create valid requests', async () => { requester = await basicConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) await link.transfer(requester.address, paymentAmount) await mock.maliciousTargetConsumer(requester.address) await requester.requestEthereumPrice('USD', paymentAmount) @@ -761,27 +761,27 @@ describe('Operator', () => { it('does not allow recursive calls of onTokenTransfer', async () => { const requestPayload = encodeOracleRequest( - specId, - to, - fHash, - 0, - constants.HashZero, + specId, + to, + fHash, + 0, + constants.HashZero, ) const ottSelector = - operatorFactory.interface.getSighash('onTokenTransfer') + operatorFactory.interface.getSighash('onTokenTransfer') const header = - '000000000000000000000000c5fdf4076b8f3a5357c5e395ab970b5b54098fef' + // to - '0000000000000000000000000000000000000000000000000000000000000539' + // amount - '0000000000000000000000000000000000000000000000000000000000000060' + // offset - '0000000000000000000000000000000000000000000000000000000000000136' // length + '000000000000000000000000c5fdf4076b8f3a5357c5e395ab970b5b54098fef' + // to + '0000000000000000000000000000000000000000000000000000000000000539' + // amount + '0000000000000000000000000000000000000000000000000000000000000060' + // offset + '0000000000000000000000000000000000000000000000000000000000000136' // length const maliciousPayload = ottSelector + header + requestPayload.slice(2) await evmRevert( - link.transferAndCall(operator.address, 0, maliciousPayload, { - value: 0, - }), + link.transferAndCall(operator.address, 0, maliciousPayload, { + value: 0, + }), ) }) }) @@ -794,11 +794,11 @@ describe('Operator', () => { beforeEach(async () => { const args = encodeOracleRequest( - specId, - to, - fHash, - 1, - constants.HashZero, + specId, + to, + fHash, + 1, + constants.HashZero, ) const tx = await link.transferAndCall(operator.address, paid, args) receipt = await tx.wait() @@ -820,17 +820,17 @@ describe('Operator', () => { it('uses the expected event signature', async () => { // If updating this test, be sure to update models.RunLogTopic. const eventSignature = - '0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65' + '0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65' assert.equal(eventSignature, log?.topics?.[0]) }) it('does not allow the same requestId to be used twice', async () => { const args2 = encodeOracleRequest( - specId, - to, - fHash, - 1, - constants.HashZero, + specId, + to, + fHash, + 1, + constants.HashZero, ) await evmRevert(link.transferAndCall(operator.address, paid, args2)) }) @@ -838,12 +838,12 @@ describe('Operator', () => { describe('when called with a payload between 3 and 9 EVM words', () => { it('throws an error', async () => { const funcSelector = - operatorFactory.interface.getSighash('oracleRequest') + operatorFactory.interface.getSighash('oracleRequest') const maliciousData = - funcSelector + - '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' + funcSelector + + '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' await evmRevert( - link.transferAndCall(operator.address, paid, maliciousData), + link.transferAndCall(operator.address, paid, maliciousData), ) }) }) @@ -853,12 +853,12 @@ describe('Operator', () => { it('throws an error', async () => { const paid = 100 const args = encodeOracleRequest( - specId, - to, - fHash, - 1, - constants.HashZero, - 256, + specId, + to, + fHash, + 1, + constants.HashZero, + 256, ) await evmRevert(link.transferAndCall(operator.address, paid, args)) }) @@ -867,18 +867,18 @@ describe('Operator', () => { describe('when not called through the LINK token', () => { it('reverts', async () => { await evmRevert( - operator - .connect(roles.oracleNode) - .oracleRequest( - '0x0000000000000000000000000000000000000000', - 0, - specId, - to, - fHash, - 1, - 1, - '0x', - ), + operator + .connect(roles.oracleNode) + .oracleRequest( + '0x0000000000000000000000000000000000000000', + 0, + specId, + to, + fHash, + 1, + 1, + '0x', + ), ) }) }) @@ -892,10 +892,10 @@ describe('Operator', () => { beforeEach(async () => { const args = encodeRequestOracleData( - specId, - fHash, - 1, - constants.HashZero, + specId, + fHash, + 1, + constants.HashZero, ) const tx = await link.transferAndCall(operator.address, paid, args) receipt = await tx.wait() @@ -917,16 +917,16 @@ describe('Operator', () => { it('uses the expected event signature', async () => { // If updating this test, be sure to update models.RunLogTopic. const eventSignature = - '0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65' + '0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65' assert.equal(eventSignature, log?.topics?.[0]) }) it('does not allow the same requestId to be used twice', async () => { const args2 = encodeRequestOracleData( - specId, - fHash, - 1, - constants.HashZero, + specId, + fHash, + 1, + constants.HashZero, ) await evmRevert(link.transferAndCall(operator.address, paid, args2)) }) @@ -936,11 +936,11 @@ describe('Operator', () => { it('throws an error', async () => { const paid = 100 const args = encodeRequestOracleData( - specId, - fHash, - 1, - constants.HashZero, - 256, + specId, + fHash, + 1, + constants.HashZero, + 256, ) await evmRevert(link.transferAndCall(operator.address, paid, args)) }) @@ -949,18 +949,18 @@ describe('Operator', () => { describe('when not called through the LINK token', () => { it('reverts', async () => { await evmRevert( - operator - .connect(roles.oracleNode) - .oracleRequest( - '0x0000000000000000000000000000000000000000', - 0, - specId, - to, - fHash, - 1, - 1, - '0x', - ), + operator + .connect(roles.oracleNode) + .oracleRequest( + '0x0000000000000000000000000000000000000000', + 0, + specId, + to, + fHash, + 1, + 1, + '0x', + ), ) }) }) @@ -977,12 +977,12 @@ describe('Operator', () => { describe('gas guzzling consumer [ @skip-coverage ]', () => { beforeEach(async () => { gasGuzzlingConsumer = await gasGuzzlingConsumerFactory - .connect(roles.consumer) - .deploy(link.address, operator.address, specId) + .connect(roles.consumer) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(gasGuzzlingConsumer.address, paymentAmount) const tx = - await gasGuzzlingConsumer.gassyRequestEthereumPrice(paymentAmount) + await gasGuzzlingConsumer.gassyRequestEthereumPrice(paymentAmount) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) }) @@ -990,8 +990,8 @@ describe('Operator', () => { it('emits an OracleResponse event', async () => { const fulfillParams = convertFufillParams(request, response) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 1) const responseEvent = receipt.events?.[0] @@ -1003,14 +1003,14 @@ describe('Operator', () => { describe('cooperative consumer', () => { beforeEach(async () => { basicConsumer = await basicConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(basicConsumer.address, paymentAmount) const currency = 'USD' const tx = await basicConsumer.requestEthereumPrice( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1019,18 +1019,18 @@ describe('Operator', () => { describe('when called by an unauthorized node', () => { beforeEach(async () => { assert.equal( - false, - await operator.isAuthorizedSender( - await roles.stranger.getAddress(), - ), + false, + await operator.isAuthorizedSender( + await roles.stranger.getAddress(), + ), ) }) it('raises an error', async () => { await evmRevert( - operator - .connect(roles.stranger) - .fulfillOracleRequest(...convertFufillParams(request, response)), + operator + .connect(roles.stranger) + .fulfillOracleRequest(...convertFufillParams(request, response)), ) }) }) @@ -1039,14 +1039,14 @@ describe('Operator', () => { let basicConsumer beforeEach(async () => { basicConsumer = await basicConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(basicConsumer.address, paymentAmount) const currency = 'USD' const tx = await basicConsumer.requestEthereumPrice( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1054,9 +1054,9 @@ describe('Operator', () => { it('raises an error', async () => { await evmRevert( - operator - .connect(roles.stranger) - .fulfillOracleRequest(...convertFufillParams(request, response)), + operator + .connect(roles.stranger) + .fulfillOracleRequest(...convertFufillParams(request, response)), ) }) }) @@ -1065,16 +1065,16 @@ describe('Operator', () => { it('raises an error if the request ID does not exist', async () => { request.requestId = ethers.utils.formatBytes32String('DOESNOTEXIST') await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)), ) }) it('sets the value on the requested contract', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) const currentValue = await basicConsumer.getCurrentPrice() assert.equal(response, ethers.utils.parseBytes32String(currentValue)) @@ -1083,8 +1083,8 @@ describe('Operator', () => { it('emits an OracleResponse event', async () => { const fulfillParams = convertFufillParams(request, response) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 3) const responseEvent = receipt.events?.[0] @@ -1096,13 +1096,13 @@ describe('Operator', () => { const response2 = response + ' && Hello World!!' await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response2)), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response2)), ) const currentValue = await basicConsumer.getCurrentPrice() @@ -1121,11 +1121,11 @@ describe('Operator', () => { it('does not allow the oracle to withdraw the payment', async () => { await evmRevert( - operator.connect(roles.oracleNode).fulfillOracleRequest( - ...convertFufillParams(request, response, { - gasLimit: 70000, - }), - ), + operator.connect(roles.oracleNode).fulfillOracleRequest( + ...convertFufillParams(request, response, { + gasLimit: 70000, + }), + ), ) bigNumEquals(0, await operator.withdrawable()) @@ -1133,9 +1133,9 @@ describe('Operator', () => { it(`${defaultGasLimit} is enough to pass the gas requirement`, async () => { await operator.connect(roles.oracleNode).fulfillOracleRequest( - ...convertFufillParams(request, response, { - gasLimit: defaultGasLimit, - }), + ...convertFufillParams(request, response, { + gasLimit: defaultGasLimit, + }), ) bigNumEquals(request.payment, await operator.withdrawable()) @@ -1147,17 +1147,17 @@ describe('Operator', () => { beforeEach(async () => { const paymentAmount = toWei('1') maliciousRequester = await maliciousRequesterFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousRequester.address, paymentAmount) }) it('cannot cancel before the expiration', async () => { await evmRevert( - maliciousRequester.maliciousRequestCancel( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), - ), + maliciousRequester.maliciousRequestCancel( + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + ), ) }) @@ -1188,16 +1188,16 @@ describe('Operator', () => { beforeEach(async () => { maliciousConsumer = await maliciousConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousConsumer.address, paymentAmount) }) describe('fails during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1205,20 +1205,20 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -1227,13 +1227,13 @@ describe('Operator', () => { const response2 = 'hack the planet 102' await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response2)), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response2)), ) }) }) @@ -1241,8 +1241,8 @@ describe('Operator', () => { describe('calls selfdestruct', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1251,19 +1251,19 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -1272,8 +1272,8 @@ describe('Operator', () => { describe('request is canceled during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('cancelRequestOnFulfill(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('cancelRequestOnFulfill(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1283,22 +1283,22 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) const mockBalance = await link.balanceOf(maliciousConsumer.address) bigNumEquals(mockBalance, 0) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -1307,13 +1307,13 @@ describe('Operator', () => { const response2 = 'hack the planet 102' await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response2)), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response2)), ) }) }) @@ -1321,53 +1321,53 @@ describe('Operator', () => { describe('tries to steal funds from node', () => { it('is not successful with call', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with send', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with transfer', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, response)) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, response)) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) }) @@ -1375,14 +1375,14 @@ describe('Operator', () => { describe('when calling an owned contract', () => { beforeEach(async () => { forwarder1 = await forwarderFactory - .connect(roles.defaultAccount) - .deploy(link.address, link.address, operator.address, '0x') + .connect(roles.defaultAccount) + .deploy(link.address, link.address, operator.address, '0x') }) it('does not allow the contract to callback to owned contracts', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('whatever(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('whatever(bytes32,bytes32)'), ) const receipt = await tx.wait() let request = decodeRunRequest(receipt.logs?.[3]) @@ -1392,26 +1392,26 @@ describe('Operator', () => { //accept ownership await operator - .connect(roles.defaultAccount) - .acceptOwnableContracts([forwarder1.address]) + .connect(roles.defaultAccount) + .acceptOwnableContracts([forwarder1.address]) // do the thing await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...responseParams), - 'Cannot call owned contract', + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...responseParams), + 'Cannot call owned contract', ) await operator - .connect(roles.defaultAccount) - .transferOwnableContracts([forwarder1.address], link.address) + .connect(roles.defaultAccount) + .transferOwnableContracts([forwarder1.address], link.address) //reverts for a different reason after transferring ownership await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...responseParams), - 'Params do not match request ID', + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...responseParams), + 'Params do not match request ID', ) }) }) @@ -1433,25 +1433,25 @@ describe('Operator', () => { describe('gas guzzling consumer [ @skip-coverage ]', () => { beforeEach(async () => { gasGuzzlingConsumer = await gasGuzzlingConsumerFactory - .connect(roles.consumer) - .deploy(link.address, operator.address, specId) + .connect(roles.consumer) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(gasGuzzlingConsumer.address, paymentAmount) const tx = - await gasGuzzlingConsumer.gassyRequestEthereumPrice(paymentAmount) + await gasGuzzlingConsumer.gassyRequestEthereumPrice(paymentAmount) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) }) it('emits an OracleResponse2 event', async () => { const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 1) const responseEvent = receipt.events?.[0] @@ -1463,14 +1463,14 @@ describe('Operator', () => { describe('cooperative consumer', () => { beforeEach(async () => { basicConsumer = await basicConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(basicConsumer.address, paymentAmount) const currency = 'USD' const tx = await basicConsumer.requestEthereumPrice( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1479,24 +1479,24 @@ describe('Operator', () => { describe('when called by an unauthorized node', () => { beforeEach(async () => { assert.equal( - false, - await operator.isAuthorizedSender( - await roles.stranger.getAddress(), - ), + false, + await operator.isAuthorizedSender( + await roles.stranger.getAddress(), + ), ) }) it('raises an error', async () => { await evmRevert( - operator - .connect(roles.stranger) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ), + operator + .connect(roles.stranger) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ), ) }) }) @@ -1505,45 +1505,45 @@ describe('Operator', () => { it('raises an error if the request ID does not exist', async () => { request.requestId = ethers.utils.formatBytes32String('DOESNOTEXIST') await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ), ) }) it('sets the value on the requested contract', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const currentValue = await basicConsumer.getCurrentPrice() assert.equal( - response, - ethers.utils.parseBytes32String(currentValue), + response, + ethers.utils.parseBytes32String(currentValue), ) }) it('emits an OracleResponse2 event', async () => { const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 3) const responseEvent = receipt.events?.[0] @@ -1555,31 +1555,31 @@ describe('Operator', () => { const response2 = response + ' && Hello World!!' const response2Values = [toBytes32String(response2)] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - response2Values, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + response2Values, + ), + ), ) const currentValue = await basicConsumer.getCurrentPrice() assert.equal( - response, - ethers.utils.parseBytes32String(currentValue), + response, + ethers.utils.parseBytes32String(currentValue), ) }) }) @@ -1595,16 +1595,16 @@ describe('Operator', () => { it('does not allow the oracle to withdraw the payment', async () => { await evmRevert( - operator.connect(roles.oracleNode).fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - { - gasLimit: 70000, - }, - ), + operator.connect(roles.oracleNode).fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + { + gasLimit: 70000, + }, ), + ), ) bigNumEquals(0, await operator.withdrawable()) @@ -1612,9 +1612,9 @@ describe('Operator', () => { it(`${defaultGasLimit} is enough to pass the gas requirement`, async () => { await operator.connect(roles.oracleNode).fulfillOracleRequest2( - ...convertFulfill2Params(request, responseTypes, responseValues, { - gasLimit: defaultGasLimit, - }), + ...convertFulfill2Params(request, responseTypes, responseValues, { + gasLimit: defaultGasLimit, + }), ) bigNumEquals(request.payment, await operator.withdrawable()) @@ -1626,22 +1626,22 @@ describe('Operator', () => { beforeEach(async () => { // Setup Request 1 basicConsumer = await basicConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(basicConsumer.address, paymentAmount) const currency = 'USD' const tx = await basicConsumer.requestEthereumPrice( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) // Setup Request 2 await link.transfer(basicConsumer.address, paymentAmount) const tx2 = await basicConsumer.requestEthereumPrice( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt2 = await tx2.wait() request2 = decodeRunRequest(receipt2.logs?.[3]) @@ -1651,37 +1651,37 @@ describe('Operator', () => { // Malicious Oracle Fulfill 2 const functionSelector = '0x6ae0bc76' // fulfillOracleRequest2 const dataOffset = - '0000000000000000000000000000000000000000000000000000000000000100' // Moved to 0x0124 + '0000000000000000000000000000000000000000000000000000000000000100' // Moved to 0x0124 const fillerBytes = - '0000000000000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000000' const expectedCalldataStart = request.requestId.slice(2) // 0xe4, this is checked against requestId in validateMultiWordResponseId const dataSize = - '0000000000000000000000000000000000000000000000000000000000000040' // Two 32 byte blocks + '0000000000000000000000000000000000000000000000000000000000000040' // Two 32 byte blocks const maliciousCalldataId = request2.requestId.slice(2) // 0x0124, set to a different requestId const calldataData = - '1122334455667788991122334455667788991122334455667788991122334455' // some garbage value as response value + '1122334455667788991122334455667788991122334455667788991122334455' // some garbage value as response value const data = - functionSelector + - /** Input Params - slice off 0x prefix and pad with 0's */ - request.requestId.slice(2) + - request.payment.slice(2).padStart(64, '0') + - request.callbackAddr.slice(2).padStart(64, '0') + - request.callbackFunc.slice(2).padEnd(64, '0') + - request.expiration.slice(2).padStart(64, '0') + - // calldata "data" - dataOffset + - fillerBytes + - expectedCalldataStart + - dataSize + - maliciousCalldataId + - calldataData + functionSelector + + /** Input Params - slice off 0x prefix and pad with 0's */ + request.requestId.slice(2) + + request.payment.slice(2).padStart(64, '0') + + request.callbackAddr.slice(2).padStart(64, '0') + + request.callbackFunc.slice(2).padEnd(64, '0') + + request.expiration.slice(2).padStart(64, '0') + + // calldata "data" + dataOffset + + fillerBytes + + expectedCalldataStart + + dataSize + + maliciousCalldataId + + calldataData await evmRevert( - operator.connect(roles.oracleNode).signer.sendTransaction({ - to: operator.address, - data, - }), + operator.connect(roles.oracleNode).signer.sendTransaction({ + to: operator.address, + data, + }), ) }) }) @@ -1690,17 +1690,17 @@ describe('Operator', () => { beforeEach(async () => { const paymentAmount = toWei('1') maliciousRequester = await maliciousRequesterFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousRequester.address, paymentAmount) }) it('cannot cancel before the expiration', async () => { await evmRevert( - maliciousRequester.maliciousRequestCancel( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), - ), + maliciousRequester.maliciousRequestCancel( + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + ), ) }) @@ -1731,16 +1731,16 @@ describe('Operator', () => { beforeEach(async () => { maliciousConsumer = await maliciousConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousConsumer.address, paymentAmount) }) describe('fails during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1748,26 +1748,26 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -1776,34 +1776,34 @@ describe('Operator', () => { const response2 = 'hack the planet 102' const response2Values = [toBytes32String(response2)] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - response2Values, - ), - ), - ) + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + response2Values, + ), + ), + ) }) }) describe('calls selfdestruct', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1812,25 +1812,25 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -1839,10 +1839,10 @@ describe('Operator', () => { describe('request is canceled during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes( - 'cancelRequestOnFulfill(bytes32,bytes32)', - ), + specId, + ethers.utils.toUtf8Bytes( + 'cancelRequestOnFulfill(bytes32,bytes32)', + ), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -1852,28 +1852,28 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const mockBalance = await link.balanceOf(maliciousConsumer.address) bigNumEquals(mockBalance, 0) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -1883,25 +1883,25 @@ describe('Operator', () => { const response2Values = [toBytes32String(response2)] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - response2Values, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + response2Values, + ), + ), ) }) }) @@ -1909,71 +1909,71 @@ describe('Operator', () => { describe('tries to steal funds from node', () => { it('is not successful with call', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with send', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with transfer', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) }) @@ -1981,14 +1981,14 @@ describe('Operator', () => { describe('when calling an owned contract', () => { beforeEach(async () => { forwarder1 = await forwarderFactory - .connect(roles.defaultAccount) - .deploy(link.address, link.address, operator.address, '0x') + .connect(roles.defaultAccount) + .deploy(link.address, link.address, operator.address, '0x') }) it('does not allow the contract to callback to owned contracts', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('whatever(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('whatever(bytes32,bytes32)'), ) const receipt = await tx.wait() let request = decodeRunRequest(receipt.logs?.[3]) @@ -1998,26 +1998,26 @@ describe('Operator', () => { //accept ownership await operator - .connect(roles.defaultAccount) - .acceptOwnableContracts([forwarder1.address]) + .connect(roles.defaultAccount) + .acceptOwnableContracts([forwarder1.address]) // do the thing await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...responseParams), - 'Cannot call owned contract', + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2(...responseParams), + 'Cannot call owned contract', ) await operator - .connect(roles.defaultAccount) - .transferOwnableContracts([forwarder1.address], link.address) + .connect(roles.defaultAccount) + .transferOwnableContracts([forwarder1.address], link.address) //reverts for a different reason after transferring ownership await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...responseParams), - 'Params do not match request ID', + operator + .connect(roles.oracleNode) + .fulfillOracleRequest(...responseParams), + 'Params do not match request ID', ) }) }) @@ -2027,8 +2027,8 @@ describe('Operator', () => { describe('multi word fulfills', () => { describe('one bytes parameter', () => { const response = - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.\ - Fusce euismod malesuada ligula, eget semper metus ultrices sit amet.' + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.\ + Fusce euismod malesuada ligula, eget semper metus ultrices sit amet.' const responseTypes = ['bytes'] const responseValues = [stringToBytes(response)] let maliciousRequester: Contract @@ -2040,25 +2040,25 @@ describe('Operator', () => { describe('gas guzzling consumer [ @skip-coverage ]', () => { beforeEach(async () => { gasGuzzlingConsumer = await gasGuzzlingConsumerFactory - .connect(roles.consumer) - .deploy(link.address, operator.address, specId) + .connect(roles.consumer) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(gasGuzzlingConsumer.address, paymentAmount) const tx = - await gasGuzzlingConsumer.gassyMultiWordRequest(paymentAmount) + await gasGuzzlingConsumer.gassyMultiWordRequest(paymentAmount) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) }) it('emits an OracleResponse2 event', async () => { const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 1) const responseEvent = receipt.events?.[0] @@ -2070,14 +2070,14 @@ describe('Operator', () => { describe('cooperative consumer', () => { beforeEach(async () => { multiConsumer = await multiWordConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(multiConsumer.address, paymentAmount) const currency = 'USD' const tx = await multiConsumer.requestEthereumPrice( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2089,8 +2089,8 @@ describe('Operator', () => { const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) const packed = ethers.utils.solidityPack( - ['address', 'uint256'], - [multiConsumer.address, nonce], + ['address', 'uint256'], + [multiConsumer.address, nonce], ) const expected = ethers.utils.keccak256(packed) assert.equal(expected, request.requestId) @@ -2099,24 +2099,24 @@ describe('Operator', () => { describe('when called by an unauthorized node', () => { beforeEach(async () => { assert.equal( - false, - await operator.isAuthorizedSender( - await roles.stranger.getAddress(), - ), + false, + await operator.isAuthorizedSender( + await roles.stranger.getAddress(), + ), ) }) it('raises an error', async () => { await evmRevert( - operator - .connect(roles.stranger) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ), + operator + .connect(roles.stranger) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ), ) }) }) @@ -2124,30 +2124,30 @@ describe('Operator', () => { describe('when called by an authorized node', () => { it('raises an error if the request ID does not exist', async () => { request.requestId = - ethers.utils.formatBytes32String('DOESNOTEXIST') + ethers.utils.formatBytes32String('DOESNOTEXIST') await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ), ) }) it('sets the value on the requested contract', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const currentValue = await multiConsumer.getCurrentPrice() assert.equal(response, ethers.utils.toUtf8String(currentValue)) @@ -2155,13 +2155,13 @@ describe('Operator', () => { it('emits an OracleResponse2 event', async () => { const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 3) const responseEvent = receipt.events?.[0] @@ -2174,25 +2174,25 @@ describe('Operator', () => { const response2Values = [stringToBytes(response2)] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - response2Values, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + response2Values, + ), + ), ) const currentValue = await multiConsumer.getCurrentPrice() @@ -2211,16 +2211,16 @@ describe('Operator', () => { it('does not allow the oracle to withdraw the payment', async () => { await evmRevert( - operator.connect(roles.oracleNode).fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - { - gasLimit: 70000, - }, - ), + operator.connect(roles.oracleNode).fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + { + gasLimit: 70000, + }, ), + ), ) bigNumEquals(0, await operator.withdrawable()) @@ -2228,14 +2228,14 @@ describe('Operator', () => { it(`${defaultGasLimit} is enough to pass the gas requirement`, async () => { await operator.connect(roles.oracleNode).fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - { - gasLimit: defaultGasLimit, - }, - ), + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + { + gasLimit: defaultGasLimit, + }, + ), ) bigNumEquals(request.payment, await operator.withdrawable()) @@ -2247,17 +2247,17 @@ describe('Operator', () => { beforeEach(async () => { const paymentAmount = toWei('1') maliciousRequester = await maliciousRequesterFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousRequester.address, paymentAmount) }) it('cannot cancel before the expiration', async () => { await evmRevert( - maliciousRequester.maliciousRequestCancel( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), - ), + maliciousRequester.maliciousRequestCancel( + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + ), ) }) @@ -2288,16 +2288,16 @@ describe('Operator', () => { beforeEach(async () => { maliciousConsumer = await maliciousMultiWordConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousConsumer.address, paymentAmount) }) describe('fails during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2305,26 +2305,26 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -2333,25 +2333,25 @@ describe('Operator', () => { const response2 = 'hack the planet 102' const response2Values = [stringToBytes(response2)] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - response2Values, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + response2Values, + ), + ), ) }) }) @@ -2359,8 +2359,8 @@ describe('Operator', () => { describe('calls selfdestruct', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2369,25 +2369,25 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -2396,10 +2396,10 @@ describe('Operator', () => { describe('request is canceled during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes( - 'cancelRequestOnFulfill(bytes32,bytes32)', - ), + specId, + ethers.utils.toUtf8Bytes( + 'cancelRequestOnFulfill(bytes32,bytes32)', + ), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2409,30 +2409,30 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const mockBalance = await link.balanceOf( - maliciousConsumer.address, + maliciousConsumer.address, ) bigNumEquals(mockBalance, 0) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -2441,25 +2441,25 @@ describe('Operator', () => { const response2 = 'hack the planet 102' const response2Values = [stringToBytes(response2)] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - response2Values, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + response2Values, + ), + ), ) }) }) @@ -2467,71 +2467,71 @@ describe('Operator', () => { describe('tries to steal funds from node', () => { it('is not successful with call', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with send', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with transfer', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) }) @@ -2557,25 +2557,25 @@ describe('Operator', () => { describe('gas guzzling consumer [ @skip-coverage ]', () => { beforeEach(async () => { gasGuzzlingConsumer = await gasGuzzlingConsumerFactory - .connect(roles.consumer) - .deploy(link.address, operator.address, specId) + .connect(roles.consumer) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(gasGuzzlingConsumer.address, paymentAmount) const tx = - await gasGuzzlingConsumer.gassyMultiWordRequest(paymentAmount) + await gasGuzzlingConsumer.gassyMultiWordRequest(paymentAmount) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) }) it('emits an OracleResponse2 event', async () => { const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 1) const responseEvent = receipt.events?.[0] @@ -2587,14 +2587,14 @@ describe('Operator', () => { describe('cooperative consumer', () => { beforeEach(async () => { multiConsumer = await multiWordConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(multiConsumer.address, paymentAmount) const currency = 'USD' const tx = await multiConsumer.requestMultipleParameters( - currency, - paymentAmount, + currency, + paymentAmount, ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2603,24 +2603,24 @@ describe('Operator', () => { describe('when called by an unauthorized node', () => { beforeEach(async () => { assert.equal( - false, - await operator.isAuthorizedSender( - await roles.stranger.getAddress(), - ), + false, + await operator.isAuthorizedSender( + await roles.stranger.getAddress(), + ), ) }) it('raises an error', async () => { await evmRevert( - operator - .connect(roles.stranger) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ), + operator + .connect(roles.stranger) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ), ) }) }) @@ -2628,57 +2628,57 @@ describe('Operator', () => { describe('when called by an authorized node', () => { it('raises an error if the request ID does not exist', async () => { request.requestId = - ethers.utils.formatBytes32String('DOESNOTEXIST') + ethers.utils.formatBytes32String('DOESNOTEXIST') await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ), ) }) it('sets the value on the requested contract', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const firstValue = await multiConsumer.usd() const secondValue = await multiConsumer.eur() const thirdValue = await multiConsumer.jpy() assert.equal( - response1, - ethers.utils.parseBytes32String(firstValue), + response1, + ethers.utils.parseBytes32String(firstValue), ) assert.equal( - response2, - ethers.utils.parseBytes32String(secondValue), + response2, + ethers.utils.parseBytes32String(secondValue), ) assert.equal( - response3, - ethers.utils.parseBytes32String(thirdValue), + response3, + ethers.utils.parseBytes32String(thirdValue), ) }) it('emits an OracleResponse2 event', async () => { const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) const tx = await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams) + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams) const receipt = await tx.wait() assert.equal(receipt.events?.length, 3) const responseEvent = receipt.events?.[0] @@ -2695,41 +2695,41 @@ describe('Operator', () => { ] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - repeatedResponseValues, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + repeatedResponseValues, + ), + ), ) const firstValue = await multiConsumer.usd() const secondValue = await multiConsumer.eur() const thirdValue = await multiConsumer.jpy() assert.equal( - response1, - ethers.utils.parseBytes32String(firstValue), + response1, + ethers.utils.parseBytes32String(firstValue), ) assert.equal( - response2, - ethers.utils.parseBytes32String(secondValue), + response2, + ethers.utils.parseBytes32String(secondValue), ) assert.equal( - response3, - ethers.utils.parseBytes32String(thirdValue), + response3, + ethers.utils.parseBytes32String(thirdValue), ) }) }) @@ -2745,16 +2745,16 @@ describe('Operator', () => { it('does not allow the oracle to withdraw the payment', async () => { await evmRevert( - operator.connect(roles.oracleNode).fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - { - gasLimit: 70000, - }, - ), + operator.connect(roles.oracleNode).fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + { + gasLimit: 70000, + }, ), + ), ) bigNumEquals(0, await operator.withdrawable()) @@ -2762,14 +2762,14 @@ describe('Operator', () => { it(`${defaultGasLimit} is enough to pass the gas requirement`, async () => { await operator.connect(roles.oracleNode).fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - { - gasLimit: defaultGasLimit, - }, - ), + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + { + gasLimit: defaultGasLimit, + }, + ), ) bigNumEquals(request.payment, await operator.withdrawable()) @@ -2781,17 +2781,17 @@ describe('Operator', () => { beforeEach(async () => { const paymentAmount = toWei('1') maliciousRequester = await maliciousRequesterFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousRequester.address, paymentAmount) }) it('cannot cancel before the expiration', async () => { await evmRevert( - maliciousRequester.maliciousRequestCancel( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), - ), + maliciousRequester.maliciousRequestCancel( + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + ), ) }) @@ -2822,16 +2822,16 @@ describe('Operator', () => { beforeEach(async () => { maliciousConsumer = await maliciousMultiWordConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address) await link.transfer(maliciousConsumer.address, paymentAmount) }) describe('fails during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('assertFail(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2839,26 +2839,26 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -2871,25 +2871,25 @@ describe('Operator', () => { toBytes32String(response4), ] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - repeatedResponseValues, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + repeatedResponseValues, + ), + ), ) }) }) @@ -2897,8 +2897,8 @@ describe('Operator', () => { describe('calls selfdestruct', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('doesNothing(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2907,25 +2907,25 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -2934,10 +2934,10 @@ describe('Operator', () => { describe('request is canceled during fulfillment', () => { beforeEach(async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes( - 'cancelRequestOnFulfill(bytes32,bytes32)', - ), + specId, + ethers.utils.toUtf8Bytes( + 'cancelRequestOnFulfill(bytes32,bytes32)', + ), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) @@ -2947,30 +2947,30 @@ describe('Operator', () => { it('allows the oracle node to receive their payment', async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) const mockBalance = await link.balanceOf( - maliciousConsumer.address, + maliciousConsumer.address, ) bigNumEquals(mockBalance, 0) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(balance, 0) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), paymentAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), paymentAmount) const newBalance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) bigNumEquals(paymentAmount, newBalance) }) @@ -2983,25 +2983,25 @@ describe('Operator', () => { toBytes32String(response4), ] await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - repeatedResponseValues, - ), - ), + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + repeatedResponseValues, + ), + ), ) }) }) @@ -3009,71 +3009,71 @@ describe('Operator', () => { describe('tries to steal funds from node', () => { it('is not successful with call', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthCall(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with send', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthSend(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) it('is not successful with transfer', async () => { const tx = await maliciousConsumer.requestData( - specId, - ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), + specId, + ethers.utils.toUtf8Bytes('stealEthTransfer(bytes32,bytes32)'), ) const receipt = await tx.wait() request = decodeRunRequest(receipt.logs?.[3]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest2( - ...convertFulfill2Params( - request, - responseTypes, - responseValues, - ), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest2( + ...convertFulfill2Params( + request, + responseTypes, + responseValues, + ), + ) bigNumEquals( - 0, - await ethers.provider.getBalance(maliciousConsumer.address), + 0, + await ethers.provider.getBalance(maliciousConsumer.address), ) }) }) @@ -3088,28 +3088,28 @@ describe('Operator', () => { it('reverts', async () => { let basicConsumer = await basicConsumerFactory - .connect(roles.defaultAccount) - .deploy(link.address, operator.address, specId) + .connect(roles.defaultAccount) + .deploy(link.address, operator.address, specId) const paymentAmount = toWei('1') await link.transfer(basicConsumer.address, paymentAmount) const tx = await basicConsumer.requestEthereumPrice( - 'USD', - paymentAmount, + 'USD', + paymentAmount, ) const receipt = await tx.wait() let request = decodeRunRequest(receipt.logs?.[3]) const fulfillParams = convertFulfill2Params( - request, - responseTypes, - responseValues, + request, + responseTypes, + responseValues, ) fulfillParams[5] = '0x' // overwrite the data to be of lenght 0 await evmRevert( - operator - .connect(roles.oracleNode) - .fulfillOracleRequest2(...fulfillParams), - 'Response must be > 32 bytes', + operator + .connect(roles.oracleNode) + .fulfillOracleRequest2(...fulfillParams), + 'Response must be > 32 bytes', ) }) }) @@ -3121,9 +3121,9 @@ describe('Operator', () => { let balance = await link.balanceOf(await roles.oracleNode.getAddress()) assert.equal(0, balance.toNumber()) await evmRevert( - operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), toWei('1')), + operator + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), toWei('1')), ) balance = await link.balanceOf(await roles.oracleNode.getAddress()) assert.equal(0, balance.toNumber()) @@ -3138,22 +3138,22 @@ describe('Operator', () => { it('withdraws funds', async () => { const operatorBalanceBefore = await link.balanceOf(operator.address) const accountBalanceBefore = await link.balanceOf( - await roles.defaultAccount.getAddress(), + await roles.defaultAccount.getAddress(), ) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.defaultAccount.getAddress(), paid) + .connect(roles.defaultAccount) + .withdraw(await roles.defaultAccount.getAddress(), paid) const operatorBalanceAfter = await link.balanceOf(operator.address) const accountBalanceAfter = await link.balanceOf( - await roles.defaultAccount.getAddress(), + await roles.defaultAccount.getAddress(), ) const accountDifference = - accountBalanceAfter.sub(accountBalanceBefore) + accountBalanceAfter.sub(accountBalanceBefore) const operatorDifference = - operatorBalanceBefore.sub(operatorBalanceAfter) + operatorBalanceBefore.sub(operatorBalanceAfter) bigNumEquals(operatorDifference, paid) bigNumEquals(accountDifference, paid) @@ -3168,11 +3168,11 @@ describe('Operator', () => { beforeEach(async () => { const requester = await roles.defaultAccount.getAddress() const args = encodeOracleRequest( - specId, - requester, - fHash, - 0, - constants.HashZero, + specId, + requester, + fHash, + 0, + constants.HashZero, ) const tx = await link.transferAndCall(operator.address, payment, args) const receipt = await tx.wait() @@ -3183,12 +3183,12 @@ describe('Operator', () => { describe('but not freeing funds w fulfillOracleRequest', () => { it('does not transfer funds', async () => { await evmRevert( - operator - .connect(roles.defaultAccount) - .withdraw(await roles.oracleNode.getAddress(), payment), + operator + .connect(roles.defaultAccount) + .withdraw(await roles.oracleNode.getAddress(), payment), ) const balance = await link.balanceOf( - await roles.oracleNode.getAddress(), + await roles.oracleNode.getAddress(), ) assert.equal(0, balance.toNumber()) }) @@ -3202,22 +3202,22 @@ describe('Operator', () => { it('withdraws funds', async () => { const operatorBalanceBefore = await link.balanceOf(operator.address) const accountBalanceBefore = await link.balanceOf( - await roles.defaultAccount.getAddress(), + await roles.defaultAccount.getAddress(), ) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.defaultAccount.getAddress(), paid) + .connect(roles.defaultAccount) + .withdraw(await roles.defaultAccount.getAddress(), paid) const operatorBalanceAfter = await link.balanceOf(operator.address) const accountBalanceAfter = await link.balanceOf( - await roles.defaultAccount.getAddress(), + await roles.defaultAccount.getAddress(), ) const accountDifference = - accountBalanceAfter.sub(accountBalanceBefore) + accountBalanceAfter.sub(accountBalanceBefore) const operatorDifference = - operatorBalanceBefore.sub(operatorBalanceAfter) + operatorBalanceBefore.sub(operatorBalanceAfter) bigNumEquals(operatorDifference, paid) bigNumEquals(accountDifference, paid) @@ -3228,38 +3228,38 @@ describe('Operator', () => { describe('and freeing funds', () => { beforeEach(async () => { await operator - .connect(roles.oracleNode) - .fulfillOracleRequest( - ...convertFufillParams(request, 'Hello World!'), - ) + .connect(roles.oracleNode) + .fulfillOracleRequest( + ...convertFufillParams(request, 'Hello World!'), + ) }) it('does not allow input greater than the balance', async () => { const originalOracleBalance = await link.balanceOf(operator.address) const originalStrangerBalance = await link.balanceOf( - await roles.stranger.getAddress(), + await roles.stranger.getAddress(), ) const withdrawalAmount = payment + 1 assert.isAbove(withdrawalAmount, originalOracleBalance.toNumber()) await evmRevert( - operator - .connect(roles.defaultAccount) - .withdraw(await roles.stranger.getAddress(), withdrawalAmount), + operator + .connect(roles.defaultAccount) + .withdraw(await roles.stranger.getAddress(), withdrawalAmount), ) const newOracleBalance = await link.balanceOf(operator.address) const newStrangerBalance = await link.balanceOf( - await roles.stranger.getAddress(), + await roles.stranger.getAddress(), ) assert.equal( - originalOracleBalance.toNumber(), - newOracleBalance.toNumber(), + originalOracleBalance.toNumber(), + newOracleBalance.toNumber(), ) assert.equal( - originalStrangerBalance.toNumber(), - newStrangerBalance.toNumber(), + originalStrangerBalance.toNumber(), + newStrangerBalance.toNumber(), ) }) @@ -3267,10 +3267,10 @@ describe('Operator', () => { const partialAmount = 6 const difference = payment - partialAmount await operator - .connect(roles.defaultAccount) - .withdraw(await roles.stranger.getAddress(), partialAmount) + .connect(roles.defaultAccount) + .withdraw(await roles.stranger.getAddress(), partialAmount) const strangerBalance = await link.balanceOf( - await roles.stranger.getAddress(), + await roles.stranger.getAddress(), ) const oracleBalance = await link.balanceOf(operator.address) assert.equal(partialAmount, strangerBalance.toNumber()) @@ -3279,22 +3279,22 @@ describe('Operator', () => { it('allows transfer of entire balance by owner to specified address', async () => { await operator - .connect(roles.defaultAccount) - .withdraw(await roles.stranger.getAddress(), payment) + .connect(roles.defaultAccount) + .withdraw(await roles.stranger.getAddress(), payment) const balance = await link.balanceOf( - await roles.stranger.getAddress(), + await roles.stranger.getAddress(), ) assert.equal(payment, balance.toNumber()) }) it('does not allow a transfer of funds by non-owner', async () => { await evmRevert( - operator - .connect(roles.stranger) - .withdraw(await roles.stranger.getAddress(), payment), + operator + .connect(roles.stranger) + .withdraw(await roles.stranger.getAddress(), payment), ) const balance = await link.balanceOf( - await roles.stranger.getAddress(), + await roles.stranger.getAddress(), ) assert.isTrue(ethers.constants.Zero.eq(balance)) }) @@ -3308,22 +3308,22 @@ describe('Operator', () => { it('withdraws funds', async () => { const operatorBalanceBefore = await link.balanceOf(operator.address) const accountBalanceBefore = await link.balanceOf( - await roles.defaultAccount.getAddress(), + await roles.defaultAccount.getAddress(), ) await operator - .connect(roles.defaultAccount) - .withdraw(await roles.defaultAccount.getAddress(), paid) + .connect(roles.defaultAccount) + .withdraw(await roles.defaultAccount.getAddress(), paid) const operatorBalanceAfter = await link.balanceOf(operator.address) const accountBalanceAfter = await link.balanceOf( - await roles.defaultAccount.getAddress(), + await roles.defaultAccount.getAddress(), ) const accountDifference = - accountBalanceAfter.sub(accountBalanceBefore) + accountBalanceAfter.sub(accountBalanceBefore) const operatorDifference = - operatorBalanceBefore.sub(operatorBalanceAfter) + operatorBalanceBefore.sub(operatorBalanceAfter) bigNumEquals(operatorDifference, paid) bigNumEquals(accountDifference, paid) @@ -3340,19 +3340,19 @@ describe('Operator', () => { beforeEach(async () => { const requester = await roles.defaultAccount.getAddress() const args = encodeOracleRequest( - specId, - requester, - fHash, - 0, - constants.HashZero, + specId, + requester, + fHash, + 0, + constants.HashZero, ) const tx = await link.transferAndCall(operator.address, amount, args) const receipt = await tx.wait() assert.equal(3, receipt.logs?.length) request = decodeRunRequest(receipt.logs?.[2]) await operator - .connect(roles.oracleNode) - .fulfillOracleRequest(...convertFufillParams(request, 'Hello World!')) + .connect(roles.oracleNode) + .fulfillOracleRequest(...convertFufillParams(request, 'Hello World!')) }) it('returns the correct value', async () => { @@ -3384,15 +3384,15 @@ describe('Operator', () => { beforeEach(async () => { operator2 = await operatorFactory - .connect(roles.oracleNode2) - .deploy(link.address, await roles.oracleNode2.getAddress()) + .connect(roles.oracleNode2) + .deploy(link.address, await roles.oracleNode2.getAddress()) to = operator2.address args = encodeOracleRequest( - specId, - operator.address, - operatorFactory.interface.getSighash('fulfillOracleRequest'), - 1, - constants.HashZero, + specId, + operator.address, + operatorFactory.interface.getSighash('fulfillOracleRequest'), + 1, + constants.HashZero, ) }) @@ -3400,10 +3400,10 @@ describe('Operator', () => { it('reverts with owner error message', async () => { await link.transfer(operator.address, startingBalance) await evmRevert( - operator - .connect(roles.stranger) - .ownerTransferAndCall(to, payment, args), - 'Only callable by owner', + operator + .connect(roles.stranger) + .ownerTransferAndCall(to, payment, args), + 'Only callable by owner', ) }) }) @@ -3417,10 +3417,10 @@ describe('Operator', () => { it('reverts with funds message', async () => { const tooMuch = startingBalance * 2 await evmRevert( - operator - .connect(roles.defaultAccount) - .ownerTransferAndCall(to, tooMuch, args), - 'Amount requested is greater than withdrawable balance', + operator + .connect(roles.defaultAccount) + .ownerTransferAndCall(to, tooMuch, args), + 'Amount requested is greater than withdrawable balance', ) }) }) @@ -3437,8 +3437,8 @@ describe('Operator', () => { requesterBalanceBefore = await link.balanceOf(operator.address) receiverBalanceBefore = await link.balanceOf(operator2.address) tx = await operator - .connect(roles.defaultAccount) - .ownerTransferAndCall(to, payment, args) + .connect(roles.defaultAccount) + .ownerTransferAndCall(to, payment, args) receipt = await tx.wait() requesterBalanceAfter = await link.balanceOf(operator.address) receiverBalanceAfter = await link.balanceOf(operator2.address) @@ -3456,8 +3456,8 @@ describe('Operator', () => { it('transfers the tokens', async () => { bigNumEquals( - requesterBalanceBefore.sub(requesterBalanceAfter), - payment, + requesterBalanceBefore.sub(requesterBalanceAfter), + payment, ) bigNumEquals(receiverBalanceAfter.sub(receiverBalanceBefore), payment) }) @@ -3474,7 +3474,7 @@ describe('Operator', () => { requestId: ethers.utils.formatBytes32String('1337'), payment: '0', callbackFunc: - getterSetterFactory.interface.getSighash('requestedBytes32'), + getterSetterFactory.interface.getSighash('requestedBytes32'), expiration: '999999999999', callbackAddr: '', @@ -3487,11 +3487,11 @@ describe('Operator', () => { await increaseTime5Minutes(ethers.provider) await evmRevert( - operator - .connect(roles.stranger) - .cancelOracleRequestByRequester( - ...convertCancelByRequesterParams(fakeRequest, nonce), - ), + operator + .connect(roles.stranger) + .cancelOracleRequestByRequester( + ...convertCancelByRequesterParams(fakeRequest, nonce), + ), ) }) }) @@ -3507,15 +3507,15 @@ describe('Operator', () => { await link.transfer(await roles.consumer.getAddress(), startingBalance) const args = encodeOracleRequest( - specId, - await roles.consumer.getAddress(), - fHash, - nonce, - constants.HashZero, + specId, + await roles.consumer.getAddress(), + fHash, + nonce, + constants.HashZero, ) const tx = await link - .connect(roles.consumer) - .transferAndCall(operator.address, requestAmount, args) + .connect(roles.consumer) + .transferAndCall(operator.address, requestAmount, args) receipt = await tx.wait() assert.equal(3, receipt.logs?.length) @@ -3526,22 +3526,22 @@ describe('Operator', () => { bigNumEquals(request.payment, oracleBalance) const consumerAmount = await link.balanceOf( - await roles.consumer.getAddress(), + await roles.consumer.getAddress(), ) assert.equal( - startingBalance - Number(request.payment), - consumerAmount.toNumber(), + startingBalance - Number(request.payment), + consumerAmount.toNumber(), ) }) describe('from a stranger', () => { it('fails', async () => { await evmRevert( - operator - .connect(roles.consumer) - .cancelOracleRequestByRequester( - ...convertCancelByRequesterParams(request, nonce), - ), + operator + .connect(roles.consumer) + .cancelOracleRequestByRequester( + ...convertCancelByRequesterParams(request, nonce), + ), ) }) }) @@ -3550,12 +3550,12 @@ describe('Operator', () => { it('refunds the correct amount', async () => { await increaseTime5Minutes(ethers.provider) await operator - .connect(roles.consumer) - .cancelOracleRequestByRequester( - ...convertCancelByRequesterParams(request, nonce), - ) + .connect(roles.consumer) + .cancelOracleRequestByRequester( + ...convertCancelByRequesterParams(request, nonce), + ) const balance = await link.balanceOf( - await roles.consumer.getAddress(), + await roles.consumer.getAddress(), ) assert.equal(startingBalance, balance.toNumber()) // 100 @@ -3564,10 +3564,10 @@ describe('Operator', () => { it('triggers a cancellation event', async () => { await increaseTime5Minutes(ethers.provider) const tx = await operator - .connect(roles.consumer) - .cancelOracleRequestByRequester( - ...convertCancelByRequesterParams(request, nonce), - ) + .connect(roles.consumer) + .cancelOracleRequestByRequester( + ...convertCancelByRequesterParams(request, nonce), + ) const receipt = await tx.wait() assert.equal(receipt.logs?.length, 2) @@ -3577,15 +3577,15 @@ describe('Operator', () => { it('fails when called twice', async () => { await increaseTime5Minutes(ethers.provider) await operator - .connect(roles.consumer) - .cancelOracleRequestByRequester( - ...convertCancelByRequesterParams(request, nonce), - ) + .connect(roles.consumer) + .cancelOracleRequestByRequester( + ...convertCancelByRequesterParams(request, nonce), + ) await evmRevert( - operator - .connect(roles.consumer) - .cancelOracleRequestByRequester(...convertCancelParams(request)), + operator + .connect(roles.consumer) + .cancelOracleRequestByRequester(...convertCancelParams(request)), ) }) }) @@ -3599,7 +3599,7 @@ describe('Operator', () => { requestId: ethers.utils.formatBytes32String('1337'), payment: '0', callbackFunc: - getterSetterFactory.interface.getSighash('requestedBytes32'), + getterSetterFactory.interface.getSighash('requestedBytes32'), expiration: '999999999999', callbackAddr: '', @@ -3612,9 +3612,9 @@ describe('Operator', () => { await increaseTime5Minutes(ethers.provider) await evmRevert( - operator - .connect(roles.stranger) - .cancelOracleRequest(...convertCancelParams(fakeRequest)), + operator + .connect(roles.stranger) + .cancelOracleRequest(...convertCancelParams(fakeRequest)), ) }) }) @@ -3630,15 +3630,15 @@ describe('Operator', () => { await link.transfer(await roles.consumer.getAddress(), startingBalance) const args = encodeOracleRequest( - specId, - await roles.consumer.getAddress(), - fHash, - 1, - constants.HashZero, + specId, + await roles.consumer.getAddress(), + fHash, + 1, + constants.HashZero, ) const tx = await link - .connect(roles.consumer) - .transferAndCall(operator.address, requestAmount, args) + .connect(roles.consumer) + .transferAndCall(operator.address, requestAmount, args) receipt = await tx.wait() assert.equal(3, receipt.logs?.length) @@ -3650,20 +3650,20 @@ describe('Operator', () => { bigNumEquals(request.payment, oracleBalance) const consumerAmount = await link.balanceOf( - await roles.consumer.getAddress(), + await roles.consumer.getAddress(), ) assert.equal( - startingBalance - Number(request.payment), - consumerAmount.toNumber(), + startingBalance - Number(request.payment), + consumerAmount.toNumber(), ) }) describe('from a stranger', () => { it('fails', async () => { await evmRevert( - operator - .connect(roles.consumer) - .cancelOracleRequest(...convertCancelParams(request)), + operator + .connect(roles.consumer) + .cancelOracleRequest(...convertCancelParams(request)), ) }) }) @@ -3672,10 +3672,10 @@ describe('Operator', () => { it('refunds the correct amount', async () => { await increaseTime5Minutes(ethers.provider) await operator - .connect(roles.consumer) - .cancelOracleRequest(...convertCancelParams(request)) + .connect(roles.consumer) + .cancelOracleRequest(...convertCancelParams(request)) const balance = await link.balanceOf( - await roles.consumer.getAddress(), + await roles.consumer.getAddress(), ) assert.equal(startingBalance, balance.toNumber()) // 100 @@ -3684,8 +3684,8 @@ describe('Operator', () => { it('triggers a cancellation event', async () => { await increaseTime5Minutes(ethers.provider) const tx = await operator - .connect(roles.consumer) - .cancelOracleRequest(...convertCancelParams(request)) + .connect(roles.consumer) + .cancelOracleRequest(...convertCancelParams(request)) const receipt = await tx.wait() assert.equal(receipt.logs?.length, 2) @@ -3695,13 +3695,13 @@ describe('Operator', () => { it('fails when called twice', async () => { await increaseTime5Minutes(ethers.provider) await operator - .connect(roles.consumer) - .cancelOracleRequest(...convertCancelParams(request)) + .connect(roles.consumer) + .cancelOracleRequest(...convertCancelParams(request)) await evmRevert( - operator - .connect(roles.consumer) - .cancelOracleRequest(...convertCancelParams(request)), + operator + .connect(roles.consumer) + .cancelOracleRequest(...convertCancelParams(request)), ) }) }) @@ -3716,8 +3716,8 @@ describe('Operator', () => { beforeEach(async () => { bytes = ethers.utils.hexlify(ethers.utils.randomBytes(100)) payload = getterSetterFactory.interface.encodeFunctionData( - getterSetterFactory.interface.getFunction('setBytes'), - [bytes], + getterSetterFactory.interface.getFunction('setBytes'), + [bytes], ) mock = await getterSetterFactory.connect(roles.defaultAccount).deploy() }) @@ -3725,7 +3725,7 @@ describe('Operator', () => { describe('when called by a non-owner', () => { it('reverts', async () => { await evmRevert( - operator.connect(roles.stranger).ownerForward(mock.address, payload), + operator.connect(roles.stranger).ownerForward(mock.address, payload), ) }) }) @@ -3735,10 +3735,10 @@ describe('Operator', () => { it('reverts', async () => { const sighash = linkTokenFactory.interface.getSighash('name') await evmRevert( - operator - .connect(roles.defaultAccount) - .ownerForward(link.address, sighash), - 'Cannot call to LINK', + operator + .connect(roles.defaultAccount) + .ownerForward(link.address, sighash), + 'Cannot call to LINK', ) }) }) @@ -3746,31 +3746,31 @@ describe('Operator', () => { describe('when forwarding to any other address', () => { it('forwards the data', async () => { const tx = await operator - .connect(roles.defaultAccount) - .ownerForward(mock.address, payload) + .connect(roles.defaultAccount) + .ownerForward(mock.address, payload) await tx.wait() assert.equal(await mock.getBytes(), bytes) }) it('reverts when sending to a non-contract address', async () => { await evmRevert( - operator - .connect(roles.defaultAccount) - .ownerForward(zeroAddress, payload), - 'Must forward to a contract', + operator + .connect(roles.defaultAccount) + .ownerForward(zeroAddress, payload), + 'Must forward to a contract', ) }) it('perceives the message is sent by the Operator', async () => { const tx = await operator - .connect(roles.defaultAccount) - .ownerForward(mock.address, payload) + .connect(roles.defaultAccount) + .ownerForward(mock.address, payload) const receipt = await tx.wait() const log: any = receipt.logs?.[0] const logData = mock.interface.decodeEventLog( - mock.interface.getEvent('SetBytes'), - log.data, - log.topics, + mock.interface.getEvent('SetBytes'), + log.data, + log.topics, ) assert.equal(ethers.utils.getAddress(logData.from), operator.address) }) From 45d97f6b9c3cc4278a033bd096d570193ddb6a0e Mon Sep 17 00:00:00 2001 From: asoliman Date: Fri, 30 Aug 2024 14:27:22 +0400 Subject: [PATCH 257/432] make snapshot-all --- .../gas-snapshots/functions.gas-snapshot | 234 ++++++++--------- contracts/gas-snapshots/keystone.gas-snapshot | 181 ++++++------- .../gas-snapshots/llo-feeds.gas-snapshot | 244 ++++++++++++++++++ .../operatorforwarder.gas-snapshot | 8 +- contracts/gas-snapshots/shared.gas-snapshot | 4 +- 5 files changed, 462 insertions(+), 209 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index b54662b868..69e0271684 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,21 +1,21 @@ -ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumGoerli() (gas: 15903239) -ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumMainnet() (gas: 15903196) -ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumSepolia() (gas: 15903265) -ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseGoerli() (gas: 15903033) -ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseMainnet() (gas: 15903011) -ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseSepolia() (gas: 15903060) -ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismGoerli() (gas: 15902946) -ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismMainnet() (gas: 15902968) -ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismSepolia() (gas: 15903011) +ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumGoerli() (gas: 16076840) +ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumMainnet() (gas: 16076819) +ChainSpecificUtil__getL1FeeUpperLimit_Arbitrum:test__getL1FeeUpperLimit_SuccessWhenArbitrumSepolia() (gas: 16076888) +ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseGoerli() (gas: 16076608) +ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseMainnet() (gas: 16076564) +ChainSpecificUtil__getL1FeeUpperLimit_Base:test__getL1FeeUpperLimit_SuccessWhenBaseSepolia() (gas: 16076635) +ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismGoerli() (gas: 16076521) +ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismMainnet() (gas: 16076543) +ChainSpecificUtil__getL1FeeUpperLimit_Optimism:test__getL1FeeUpperLimit_SuccessWhenOptimismSepolia() (gas: 16076586) FunctionsBilling_Constructor:test_Constructor_Success() (gas: 17982) -FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13260) -FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15875) +FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13283) +FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15853) FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32450) -FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 90999) +FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 90977) FunctionsBilling_EstimateCost:test_EstimateCost_SuccessLowGasPrice() (gas: 91102) FunctionsBilling_GetAdminFeeJuels:test_GetAdminFeeJuels_Success() (gas: 18671) -FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 30727) -FunctionsBilling_GetDONFeeJuels:test_GetDONFeeJuels_Success() (gas: 41128) +FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 30750) +FunctionsBilling_GetDONFeeJuels:test_GetDONFeeJuels_Success() (gas: 41151) FunctionsBilling_GetOperationFee:test_GetOperationFeeJuels_Success() (gas: 40548) FunctionsBilling_GetWeiPerUnitLink:test_GetWeiPerUnitLink_Success() (gas: 29751) FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertIfInsufficientBalance() (gas: 70136) @@ -23,41 +23,41 @@ FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertWithNoBalance() (gas: FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessCoordinatorOwner() (gas: 129908) FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceNoAmountGiven() (gas: 171930) FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceValidAmountGiven() (gas: 145165) -FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13297) +FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13320) FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 222357) -FunctionsBilling_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 21654) -FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 54121) +FunctionsBilling_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 21632) +FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 54099) FunctionsBilling__DisperseFeePool:test__DisperseFeePool_RevertIfNotSet() (gas: 8810) -FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13375) -FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 185953) +FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13353) +FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 185976) FunctionsBilling__StartBilling:test__FulfillAndBill_HasUniqueGlobalRequestId() (gas: 524582) FunctionsClient_Constructor:test_Constructor_Success() (gas: 10407) -FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_RevertIfNotRouter() (gas: 14617) -FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_Success() (gas: 22917) +FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_RevertIfNotRouter() (gas: 14595) +FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_Success() (gas: 22983) FunctionsClient__SendRequest:test__SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 55069) FunctionsCoordinator_Constructor:test_Constructor_Success() (gas: 15085) -FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_RevertIfEmpty() (gas: 15378) +FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_RevertIfEmpty() (gas: 15356) FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_Success() (gas: 91691) -FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_RevertIfEmpty() (gas: 15356) -FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_Success() (gas: 515973) -FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_RevertNotOwner() (gas: 20365) +FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_RevertIfEmpty() (gas: 15334) +FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_Success() (gas: 515951) +FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_RevertNotOwner() (gas: 20409) FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_Success() (gas: 88970) -FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_RevertNotOwner() (gas: 13892) +FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_RevertNotOwner() (gas: 13915) FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_Success() (gas: 513165) -FunctionsCoordinator_StartRequest:test_StartRequest_RevertIfNotRouter() (gas: 22736) -FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 152672) +FunctionsCoordinator_StartRequest:test_StartRequest_RevertIfNotRouter() (gas: 22802) +FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 152650) FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessFound() (gas: 15106) -FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessNotFound() (gas: 22938) +FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessNotFound() (gas: 22916) FunctionsRequest_DEFAULT_BUFFER_SIZE:test_DEFAULT_BUFFER_SIZE() (gas: 3089) FunctionsRequest_EncodeCBOR:test_EncodeCBOR_Success() (gas: 3066) FunctionsRequest_REQUEST_DATA_VERSION:test_REQUEST_DATA_VERSION() (gas: 3068) FunctionsRouter_Constructor:test_Constructor_Success() (gas: 15107) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 172497) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 172475) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 163010) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 38777) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35900) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 180976) -FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28086) +FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28152) FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 156535) FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 335070) FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 348695) @@ -65,19 +65,19 @@ FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2627478) FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 658423) FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 18323) FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 13241) -FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 40170) -FunctionsRouter_GetContractById:test_GetContractById_RevertIfRouteDoesNotExist() (gas: 13839) +FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 40193) +FunctionsRouter_GetContractById:test_GetContractById_RevertIfRouteDoesNotExist() (gas: 13862) FunctionsRouter_GetContractById:test_GetContractById_SuccessIfRouteExists() (gas: 17704) -FunctionsRouter_GetProposedContractById:test_GetProposedContractById_RevertIfRouteDoesNotExist() (gas: 16373) -FunctionsRouter_GetProposedContractById:test_GetProposedContractById_SuccessIfRouteExists() (gas: 24266) +FunctionsRouter_GetProposedContractById:test_GetProposedContractById_RevertIfRouteDoesNotExist() (gas: 16417) +FunctionsRouter_GetProposedContractById:test_GetProposedContractById_SuccessIfRouteExists() (gas: 24289) FunctionsRouter_GetProposedContractSet:test_GetProposedContractSet_Success() (gas: 27289) FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertGasLimitTooBig() (gas: 28087) FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertInvalidConfig() (gas: 41095) FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_Success() (gas: 24632) -FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13338) -FunctionsRouter_Pause:test_Pause_Success() (gas: 20669) -FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfEmptyAddress() (gas: 14791) -FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfExceedsMaxProposal() (gas: 21693) +FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13361) +FunctionsRouter_Pause:test_Pause_Success() (gas: 20647) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfEmptyAddress() (gas: 14769) +FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfExceedsMaxProposal() (gas: 21716) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfLengthMismatch() (gas: 14670) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotNewContract() (gas: 19048) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotOwner() (gas: 23392) @@ -85,149 +85,151 @@ FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_Success() (ga FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 59400) FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 217996) FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29426) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57904) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57882) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 208451) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 50953) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25082) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29132) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29177) FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34291) -FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 226346) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65896) +FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 226324) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65918) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 36012) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29896) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() (gas: 57539) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidDonId() (gas: 27503) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35717) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35672) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40810) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 232783) FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 214899) FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 33531) -FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13403) -FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13293) -FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77725) -FunctionsRouter_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 24437) -FunctionsRouter_UpdateConfig:test_UpdateConfig_Success() (gas: 63353) -FunctionsRouter_UpdateContracts:test_UpdateContracts_RevertIfNotOwner() (gas: 13336) +FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13381) +FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13337) +FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77748) +FunctionsRouter_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 24415) +FunctionsRouter_UpdateConfig:test_UpdateConfig_Success() (gas: 63331) +FunctionsRouter_UpdateContracts:test_UpdateContracts_RevertIfNotOwner() (gas: 13314) FunctionsRouter_UpdateContracts:test_UpdateContracts_Success() (gas: 39269) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 60413) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 61040) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 139706) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62780) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 239911) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 239919) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 138033) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 164977) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12955) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 102450) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87205) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12933) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 102428) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87272) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfPaused() (gas: 18100) FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 96221) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubscription() (gas: 15053) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 102529) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89318) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 102507) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89341) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20157) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 218330) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 218308) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 115656) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() (gas: 126964) FunctionsSubscriptions_CancelSubscription_ReceiveDeposit:test_CancelSubscription_SuccessRecieveDeposit() (gas: 75369) FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 10488) FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28688) -FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 17994) +FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 18038) FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_Success() (gas: 353899) -FunctionsSubscriptions_GetConsumer:test_GetConsumer_Success() (gas: 17256) -FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessInvalidSubscription() (gas: 13438) -FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessValidSubscription() (gas: 41243) +FunctionsSubscriptions_GetConsumer:test_GetConsumer_Success() (gas: 17279) +FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessInvalidSubscription() (gas: 13504) +FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessValidSubscription() (gas: 41221) FunctionsSubscriptions_GetSubscription:test_GetSubscription_Success() (gas: 32968) FunctionsSubscriptions_GetSubscriptionCount:test_GetSubscriptionCount_Success() (gas: 13305) -FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfEndIsAfterLastSubscription() (gas: 16547) +FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfEndIsAfterLastSubscription() (gas: 16570) FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfStartIsAfterEnd() (gas: 13465) -FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_Success() (gas: 65990) -FunctionsSubscriptions_GetTotalBalance:test_GetTotalBalance_Success() (gas: 15347) +FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_Success() (gas: 65968) +FunctionsSubscriptions_GetTotalBalance:test_GetTotalBalance_Success() (gas: 15370) FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoCalldata() (gas: 39908) FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoSubscription() (gas: 42382) FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNotLink() (gas: 13419) FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfPaused() (gas: 47325) FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_Success() (gas: 84314) -FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfAmountMoreThanBalance() (gas: 20766) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfAmountMoreThanBalance() (gas: 20744) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfBalanceInvariant() (gas: 189) -FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfNoAmount() (gas: 15641) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfNoAmount() (gas: 15686) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfPaused() (gas: 20859) -FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessPaysRecipient() (gas: 60075) +FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessPaysRecipient() (gas: 60119) FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessSetsBalanceToZero() (gas: 57716) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNoSubscription() (gas: 12818) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15549) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 55141) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNoSubscription() (gas: 12796) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15594) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 55177) FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessDeletesSubscription() (gas: 49607) FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessSubOwnerRefunded() (gas: 53166) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 186533) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17945) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 186511) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17923) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfBalanceInvariant() (gas: 210) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15555) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15600) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas: 33839) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfRecipientAddressZero() (gas: 31649) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfRecipientAddressZero() (gas: 31627) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 33935) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 31584) -FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 17818) -FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 203333) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27664) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57815) +FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 17796) +FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 203311) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27642) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57793) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15013) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 119775) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() (gas: 17969) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() (gas: 20137) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68596) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_SuccessChangeProposedOwner() (gas: 83539) -FunctionsSubscriptions_RecoverFunds:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15554) -FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41376) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 119820) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() (gas: 17947) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() (gas: 20181) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68574) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_SuccessChangeProposedOwner() (gas: 83582) +FunctionsSubscriptions_RecoverFunds:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15577) +FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41358) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfInvalidConsumer() (gas: 30310) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription() (gas: 15031) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 102444) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87254) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18058) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87277) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18103) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 215863) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42088) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42066) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12888) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15684) FunctionsSubscriptions_SetFlags:test_SetFlags_Success() (gas: 38434) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfPaused() (gas: 25955) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfTimeoutNotExceeded() (gas: 25261) -FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28242) -FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 58416) -FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26418) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28220) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 58394) +FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26462) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15759) FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 153701) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 94913) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25859) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 88990) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23619) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866552) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 28525) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1946965) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 104509) -FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15491) -FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 97541) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 94943) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25925) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 89013) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23620) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866619) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 28526) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1946966) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 104555) +FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15535) +FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 97587) FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 15345) FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19243) FunctionsTermsOfServiceAllowList_GetAllowedSendersCount:test_GetAllowedSendersCount_Success() (gas: 13332) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13153024) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16554) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13284) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20312) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13326576) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16532) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13307) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20335) FunctionsTermsOfServiceAllowList_GetBlockedSendersCount:test_GetBlockedSendersCount_Success() (gas: 13268) -FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13153034) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13326564) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16549) -FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13367) -FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_Success() (gas: 18537) -FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 16388) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13345) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_Success() (gas: 18580) +FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 16411) FunctionsTermsOfServiceAllowList_GetMessage:test_GetMessage_Success() (gas: 11918) -FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 16257) -FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23848) +FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 16235) +FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23877) FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessFalse() (gas: 15776) FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTrue() (gas: 86974) -FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13502) -FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 96216) -FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13812) -FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22817) -Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84702) +FunctionsTermsOfServiceAllowList_MigratePreviouslyAllowedSenders:test_MigratePreviouslyAllowedSenders_RevertIfNotOwner() (gas: 13987) +FunctionsTermsOfServiceAllowList_MigratePreviouslyAllowedSenders:test_MigratePreviouslyAllowedSenders_Success() (gas: 210636) +FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13548) +FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 96240) +FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13819) +FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22824) +Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84725) Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79140) Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73419) Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MaximumGas() (gas: 20562) diff --git a/contracts/gas-snapshots/keystone.gas-snapshot b/contracts/gas-snapshots/keystone.gas-snapshot index 2880e4c0e3..0f3af9a543 100644 --- a/contracts/gas-snapshots/keystone.gas-snapshot +++ b/contracts/gas-snapshots/keystone.gas-snapshot @@ -1,107 +1,114 @@ -CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_NoConfigurationContract() (gas: 154832) -CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_WithConfiguration() (gas: 178813) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 24723) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CapabilityExists() (gas: 145703) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractDoesNotMatchInterface() (gas: 94606) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractNotDeployed() (gas: 92961) -CapabilitiesRegistry_AddDONTest:test_AddDON() (gas: 372302) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19273) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 169752) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 239789) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 249596) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 116890) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_FaultToleranceIsZero() (gas: 43358) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeAlreadyBelongsToWorkflowDON() (gas: 343924) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 180150) -CapabilitiesRegistry_AddNodeOperatorsTest:test_AddNodeOperators() (gas: 184135) -CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_CalledByNonAdmin() (gas: 17602) -CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_NodeOperatorAdminAddressZero() (gas: 18498) -CapabilitiesRegistry_AddNodesTest:test_AddsNodeParams() (gas: 358448) -CapabilitiesRegistry_AddNodesTest:test_OwnerCanAddNodes() (gas: 358414) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingDuplicateP2PId() (gas: 301229) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 55174) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidNodeOperator() (gas: 24895) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithoutCapabilities() (gas: 27669) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25108) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 27408) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 27047) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressNotUnique() (gas: 309679) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_DeprecatesCapability() (gas: 89807) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_EmitsEvent() (gas: 89935) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 22944) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 16231) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityIsDeprecated() (gas: 91264) -CapabilitiesRegistry_GetCapabilitiesTest:test_ReturnsCapabilities() (gas: 135553) +CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_NoConfigurationContract() (gas: 154809) +CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_WithConfiguration() (gas: 180379) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 24678) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CapabilityExists() (gas: 145613) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractDoesNotMatchInterface() (gas: 94543) +CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractNotDeployed() (gas: 96326) +CapabilitiesRegistry_AddDONTest:test_AddDON() (gas: 373893) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19288) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 169767) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 239739) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 250950) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 116905) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_FaultToleranceIsZero() (gas: 43373) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeAlreadyBelongsToWorkflowDON() (gas: 344037) +CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 180165) +CapabilitiesRegistry_AddDONTest_WhenMaliciousCapabilityConfigurationConfigured:test_RevertWhen_MaliciousCapabilitiesConfigContractTriesToRemoveCapabilitiesFromDONNodes() (gas: 340514) +CapabilitiesRegistry_AddNodeOperatorsTest:test_AddNodeOperators() (gas: 184157) +CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_CalledByNonAdmin() (gas: 17624) +CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_NodeOperatorAdminAddressZero() (gas: 18520) +CapabilitiesRegistry_AddNodesTest:test_AddsNodeParams() (gas: 358492) +CapabilitiesRegistry_AddNodesTest:test_OwnerCanAddNodes() (gas: 358458) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingDuplicateP2PId() (gas: 301273) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 55196) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidNodeOperator() (gas: 24917) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithoutCapabilities() (gas: 27691) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25130) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 27430) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 27069) +CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressNotUnique() (gas: 309723) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_DeprecatesCapability() (gas: 89742) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_EmitsEvent() (gas: 89870) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 22879) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 16166) +CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityIsDeprecated() (gas: 91134) +CapabilitiesRegistry_GetCapabilitiesTest:test_ReturnsCapabilities() (gas: 135488) CapabilitiesRegistry_GetDONsTest:test_CorrectlyFetchesDONs() (gas: 65468) -CapabilitiesRegistry_GetDONsTest:test_DoesNotIncludeRemovedDONs() (gas: 64924) +CapabilitiesRegistry_GetDONsTest:test_DoesNotIncludeRemovedDONs() (gas: 65016) CapabilitiesRegistry_GetHashedCapabilityTest:test_CorrectlyGeneratesHashedCapabilityId() (gas: 11428) CapabilitiesRegistry_GetHashedCapabilityTest:test_DoesNotCauseIncorrectClashes() (gas: 13087) -CapabilitiesRegistry_GetNodeOperatorsTest:test_CorrectlyFetchesNodeOperators() (gas: 36407) -CapabilitiesRegistry_GetNodeOperatorsTest:test_DoesNotIncludeRemovedNodeOperators() (gas: 38692) +CapabilitiesRegistry_GetNodeOperatorsTest:test_CorrectlyFetchesNodeOperators() (gas: 36429) +CapabilitiesRegistry_GetNodeOperatorsTest:test_DoesNotIncludeRemovedNodeOperators() (gas: 38714) CapabilitiesRegistry_GetNodesTest:test_CorrectlyFetchesNodes() (gas: 65288) -CapabilitiesRegistry_GetNodesTest:test_DoesNotIncludeRemovedNodes() (gas: 73533) -CapabilitiesRegistry_RemoveDONsTest:test_RemovesDON() (gas: 54761) +CapabilitiesRegistry_GetNodesTest:test_DoesNotIncludeRemovedNodes() (gas: 73497) +CapabilitiesRegistry_RemoveDONsTest:test_RemovesDON() (gas: 54982) CapabilitiesRegistry_RemoveDONsTest:test_RevertWhen_CalledByNonAdmin() (gas: 15647) CapabilitiesRegistry_RemoveDONsTest:test_RevertWhen_DONDoesNotExist() (gas: 16550) CapabilitiesRegistry_RemoveNodeOperatorsTest:test_RemovesNodeOperator() (gas: 36122) CapabilitiesRegistry_RemoveNodeOperatorsTest:test_RevertWhen_CalledByNonOwner() (gas: 15816) -CapabilitiesRegistry_RemoveNodesTest:test_CanAddNodeWithSameSignerAddressAfterRemoving() (gas: 115151) -CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenDONDeleted() (gas: 287716) -CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenNodeNoLongerPartOfDON() (gas: 561023) -CapabilitiesRegistry_RemoveNodesTest:test_OwnerCanRemoveNodes() (gas: 73376) -CapabilitiesRegistry_RemoveNodesTest:test_RemovesNode() (gas: 75211) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25053) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 18418) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodePartOfCapabilitiesDON() (gas: 385369) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 18408) +CapabilitiesRegistry_RemoveNodesTest:test_CanAddNodeWithSameSignerAddressAfterRemoving() (gas: 115150) +CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenDONDeleted() (gas: 287838) +CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenNodeNoLongerPartOfDON() (gas: 561183) +CapabilitiesRegistry_RemoveNodesTest:test_OwnerCanRemoveNodes() (gas: 73358) +CapabilitiesRegistry_RemoveNodesTest:test_RemovesNode() (gas: 75192) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25008) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 18373) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodePartOfCapabilitiesDON() (gas: 385422) +CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 18363) CapabilitiesRegistry_TypeAndVersionTest:test_TypeAndVersion() (gas: 9796) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19415) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 152914) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DONDoesNotExist() (gas: 17835) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 222996) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 232804) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 107643) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 163357) -CapabilitiesRegistry_UpdateDONTest:test_UpdatesDON() (gas: 371909) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_CalledByNonAdminAndNonOwner() (gas: 20631) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorAdminIsZeroAddress() (gas: 20052) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorDoesNotExist() (gas: 19790) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorIdAndParamLengthsMismatch() (gas: 15430) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_UpdatesNodeOperator() (gas: 36937) -CapabilitiesRegistry_UpdateNodesTest:test_CanUpdateParamsIfNodeSignerAddressNoLongerUsed() (gas: 256157) -CapabilitiesRegistry_UpdateNodesTest:test_OwnerCanUpdateNodes() (gas: 162059) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 35766) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25069) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 27308) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeSignerAlreadyAssignedToAnotherNode() (gas: 29219) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 27296) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByCapabilityDON() (gas: 470803) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByWorkflowDON() (gas: 341084) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 26951) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 25480) -CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162113) -KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 1797755) -KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() (gas: 125910) -KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverNotContract() (gas: 127403) -KeystoneForwarder_ReportTest:test_Report_SuccessfulDelivery() (gas: 155928) -KeystoneForwarder_ReportTest:test_RevertWhen_AlreadyAttempted() (gas: 152358) -KeystoneForwarder_ReportTest:test_RevertWhen_AnySignatureIsInvalid() (gas: 86348) -KeystoneForwarder_ReportTest:test_RevertWhen_AnySignerIsInvalid() (gas: 118486) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19323) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 152958) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DONDoesNotExist() (gas: 17749) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 222975) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 236986) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 107687) +CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 163401) +CapabilitiesRegistry_UpdateDONTest:test_UpdatesDON() (gas: 373510) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_CalledByNonAdminAndNonOwner() (gas: 20684) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorAdminIsZeroAddress() (gas: 20008) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorDoesNotExist() (gas: 19746) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorIdAndParamLengthsMismatch() (gas: 15386) +CapabilitiesRegistry_UpdateNodeOperatorTest:test_UpdatesNodeOperator() (gas: 36990) +CapabilitiesRegistry_UpdateNodesTest:test_CanUpdateParamsIfNodeSignerAddressNoLongerUsed() (gas: 256437) +CapabilitiesRegistry_UpdateNodesTest:test_OwnerCanUpdateNodes() (gas: 162210) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 35895) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByAnotherNodeOperatorAdmin() (gas: 29222) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 29399) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 29221) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeSignerAlreadyAssignedToAnotherNode() (gas: 31348) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 29187) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByCapabilityDON() (gas: 471030) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByWorkflowDON() (gas: 341311) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 29080) +CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 27609) +CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162264) +KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 2003568) +KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() (gas: 124908) +KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverNotContract() (gas: 126927) +KeystoneForwarder_ReportTest:test_Report_SuccessfulDelivery() (gas: 361243) +KeystoneForwarder_ReportTest:test_Report_SuccessfulRetryWithMoreGas() (gas: 501084) +KeystoneForwarder_ReportTest:test_RevertWhen_AnySignatureIsInvalid() (gas: 86326) +KeystoneForwarder_ReportTest:test_RevertWhen_AnySignerIsInvalid() (gas: 118521) +KeystoneForwarder_ReportTest:test_RevertWhen_AttemptingTransmissionWithInsufficientGas() (gas: 96279) KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasDuplicateSignatures() (gas: 94516) KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasIncorrectDON() (gas: 75930) KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasInexistentConfigVersion() (gas: 76298) -KeystoneForwarder_ReportTest:test_RevertWhen_ReportIsMalformed() (gas: 45585) +KeystoneForwarder_ReportTest:test_RevertWhen_ReportIsMalformed() (gas: 45563) +KeystoneForwarder_ReportTest:test_RevertWhen_RetryingInvalidContractTransmission() (gas: 143591) +KeystoneForwarder_ReportTest:test_RevertWhen_RetryingSuccessfulTransmission() (gas: 354042) KeystoneForwarder_ReportTest:test_RevertWhen_TooFewSignatures() (gas: 55292) KeystoneForwarder_ReportTest:test_RevertWhen_TooManySignatures() (gas: 56050) KeystoneForwarder_SetConfigTest:test_RevertWhen_ExcessSigners() (gas: 20184) KeystoneForwarder_SetConfigTest:test_RevertWhen_FaultToleranceIsZero() (gas: 88057) KeystoneForwarder_SetConfigTest:test_RevertWhen_InsufficientSigners() (gas: 14533) -KeystoneForwarder_SetConfigTest:test_RevertWhen_NotOwner() (gas: 88788) -KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingDuplicateSigners() (gas: 114507) -KeystoneForwarder_SetConfigTest:test_SetConfig_FirstTime() (gas: 1539921) -KeystoneForwarder_SetConfigTest:test_SetConfig_WhenSignersAreRemoved() (gas: 1534476) +KeystoneForwarder_SetConfigTest:test_RevertWhen_NotOwner() (gas: 88766) +KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingDuplicateSigners() (gas: 114570) +KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingZeroAddressSigner() (gas: 114225) +KeystoneForwarder_SetConfigTest:test_SetConfig_FirstTime() (gas: 1540541) +KeystoneForwarder_SetConfigTest:test_SetConfig_WhenSignersAreRemoved() (gas: 1535211) KeystoneForwarder_TypeAndVersionTest:test_TypeAndVersion() (gas: 9641) KeystoneRouter_SetConfigTest:test_AddForwarder_RevertWhen_NotOwner() (gas: 10978) KeystoneRouter_SetConfigTest:test_RemoveForwarder_RevertWhen_NotOwner() (gas: 10923) -KeystoneRouter_SetConfigTest:test_Route_RevertWhen_UnauthorizedForwarder() (gas: 18553) -KeystoneRouter_SetConfigTest:test_Route_Success() (gas: 75629) \ No newline at end of file +KeystoneRouter_SetConfigTest:test_RemoveForwarder_Success() (gas: 17599) +KeystoneRouter_SetConfigTest:test_Route_RevertWhen_UnauthorizedForwarder() (gas: 18552) +KeystoneRouter_SetConfigTest:test_Route_Success() (gas: 79379) \ No newline at end of file diff --git a/contracts/gas-snapshots/llo-feeds.gas-snapshot b/contracts/gas-snapshots/llo-feeds.gas-snapshot index 187d3cd89f..68f3c016f6 100644 --- a/contracts/gas-snapshots/llo-feeds.gas-snapshot +++ b/contracts/gas-snapshots/llo-feeds.gas-snapshot @@ -18,6 +18,223 @@ ByteUtilTest:test_readUint32MultiWord() (gas: 3393) ByteUtilTest:test_readUint32WithEmptyArray() (gas: 3253) ByteUtilTest:test_readUint32WithNotEnoughBytes() (gas: 3272) ByteUtilTest:test_readZeroAddress() (gas: 3365) +ChannelConfigStoreTest:testSetChannelDefinitions() (gas: 46927) +ChannelConfigStoreTest:testSupportsInterface() (gas: 8367) +ChannelConfigStoreTest:testTypeAndVersion() (gas: 9621) +DestinationFeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52669) +DestinationFeeManagerProcessFeeTest:test_DiscountIsReturnedForNative() (gas: 52685) +DestinationFeeManagerProcessFeeTest:test_DiscountIsReturnedForNativeWithSurcharge() (gas: 78876) +DestinationFeeManagerProcessFeeTest:test_V1PayloadVerifies() (gas: 29324) +DestinationFeeManagerProcessFeeTest:test_V1PayloadVerifiesAndReturnsChange() (gas: 61187) +DestinationFeeManagerProcessFeeTest:test_V2PayloadVerifies() (gas: 121137) +DestinationFeeManagerProcessFeeTest:test_V2PayloadWithoutQuoteFails() (gas: 29669) +DestinationFeeManagerProcessFeeTest:test_V2PayloadWithoutZeroFee() (gas: 74797) +DestinationFeeManagerProcessFeeTest:test_WithdrawERC20() (gas: 72796) +DestinationFeeManagerProcessFeeTest:test_WithdrawNonAdminAddr() (gas: 56334) +DestinationFeeManagerProcessFeeTest:test_WithdrawUnwrappedNative() (gas: 26411) +DestinationFeeManagerProcessFeeTest:test_addVerifier() (gas: 131079) +DestinationFeeManagerProcessFeeTest:test_addVerifierExistingAddress() (gas: 34148) +DestinationFeeManagerProcessFeeTest:test_baseFeeIsAppliedForLink() (gas: 17214) +DestinationFeeManagerProcessFeeTest:test_baseFeeIsAppliedForNative() (gas: 20152) +DestinationFeeManagerProcessFeeTest:test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() (gas: 91103) +DestinationFeeManagerProcessFeeTest:test_discountAIsNotAppliedWhenSetForOtherUsers() (gas: 56580) +DestinationFeeManagerProcessFeeTest:test_discountFeeRoundsDownWhenUneven() (gas: 52871) +DestinationFeeManagerProcessFeeTest:test_discountIsAppliedForLink() (gas: 49682) +DestinationFeeManagerProcessFeeTest:test_discountIsAppliedWith100PercentSurcharge() (gas: 78949) +DestinationFeeManagerProcessFeeTest:test_discountIsNoLongerAppliedAfterRemoving() (gas: 46567) +DestinationFeeManagerProcessFeeTest:test_discountIsNotAppliedForInvalidTokenAddress() (gas: 17582) +DestinationFeeManagerProcessFeeTest:test_discountIsNotAppliedToOtherFeeds() (gas: 54628) +DestinationFeeManagerProcessFeeTest:test_discountIsReturnedForLink() (gas: 49654) +DestinationFeeManagerProcessFeeTest:test_emptyQuoteRevertsWithError() (gas: 12231) +DestinationFeeManagerProcessFeeTest:test_eventIsEmittedAfterSurchargeIsSet() (gas: 41424) +DestinationFeeManagerProcessFeeTest:test_eventIsEmittedIfNotEnoughLink() (gas: 179229) +DestinationFeeManagerProcessFeeTest:test_eventIsEmittedUponWithdraw() (gas: 69057) +DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterDiscountIsRemoved() (gas: 49831) +DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewDiscountIsApplied() (gas: 67769) +DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewSurchargeIsApplied() (gas: 64460) +DestinationFeeManagerProcessFeeTest:test_feeIsZeroWith100PercentDiscount() (gas: 52091) +DestinationFeeManagerProcessFeeTest:test_getBaseRewardWithLinkQuote() (gas: 17231) +DestinationFeeManagerProcessFeeTest:test_getLinkFeeIsRoundedUp() (gas: 49853) +DestinationFeeManagerProcessFeeTest:test_getLinkRewardIsSameAsFee() (gas: 55711) +DestinationFeeManagerProcessFeeTest:test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() (gas: 82833) +DestinationFeeManagerProcessFeeTest:test_getRewardWithLinkDiscount() (gas: 49700) +DestinationFeeManagerProcessFeeTest:test_getRewardWithLinkQuoteAndLinkDiscount() (gas: 49681) +DestinationFeeManagerProcessFeeTest:test_getRewardWithNativeQuote() (gas: 20150) +DestinationFeeManagerProcessFeeTest:test_getRewardWithNativeQuoteAndSurcharge() (gas: 50885) +DestinationFeeManagerProcessFeeTest:test_linkAvailableForPaymentReturnsLinkBalance() (gas: 53172) +DestinationFeeManagerProcessFeeTest:test_nativeSurcharge0Percent() (gas: 30937) +DestinationFeeManagerProcessFeeTest:test_nativeSurcharge100Percent() (gas: 50887) +DestinationFeeManagerProcessFeeTest:test_nativeSurchargeCannotExceed100Percent() (gas: 17220) +DestinationFeeManagerProcessFeeTest:test_nativeSurchargeEventIsEmittedOnUpdate() (gas: 41402) +DestinationFeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFee() (gas: 51914) +DestinationFeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() (gas: 78172) +DestinationFeeManagerProcessFeeTest:test_nonAdminProxyUserCannotProcessFee() (gas: 24185) +DestinationFeeManagerProcessFeeTest:test_nonAdminUserCanNotSetDiscount() (gas: 19871) +DestinationFeeManagerProcessFeeTest:test_onlyCallableByOwnerReverts() (gas: 15453) +DestinationFeeManagerProcessFeeTest:test_payLinkDeficit() (gas: 198072) +DestinationFeeManagerProcessFeeTest:test_payLinkDeficitOnlyCallableByAdmin() (gas: 17415) +DestinationFeeManagerProcessFeeTest:test_payLinkDeficitPaysAllFeesProcessed() (gas: 218691) +DestinationFeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 202446) +DestinationFeeManagerProcessFeeTest:test_poolIdsCannotBeZeroAddress() (gas: 115317) +DestinationFeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 121475) +DestinationFeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 29745) +DestinationFeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 165393) +DestinationFeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 32563) +DestinationFeeManagerProcessFeeTest:test_processFeeNative() (gas: 178204) +DestinationFeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 122766) +DestinationFeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 31822) +DestinationFeeManagerProcessFeeTest:test_processFeeWithDiscountEmitsEvent() (gas: 245890) +DestinationFeeManagerProcessFeeTest:test_processFeeWithInvalidReportVersionFailsToDecode() (gas: 30770) +DestinationFeeManagerProcessFeeTest:test_processFeeWithNoDiscountDoesNotEmitEvent() (gas: 171109) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNative() (gas: 186069) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddress() (gas: 135874) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() (gas: 161459) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeShortFunds() (gas: 94841) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeWithExcessiveFee() (gas: 193032) +DestinationFeeManagerProcessFeeTest:test_processFeeWithWithCorruptQuotePayload() (gas: 75084) +DestinationFeeManagerProcessFeeTest:test_processFeeWithWithEmptyQuotePayload() (gas: 30006) +DestinationFeeManagerProcessFeeTest:test_processFeeWithWithZeroQuotePayload() (gas: 30056) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() (gas: 35320) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() (gas: 158081) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkReturnsChange() (gas: 56059) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() (gas: 121473) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() (gas: 38024) +DestinationFeeManagerProcessFeeTest:test_processMultipleLinkReports() (gas: 230434) +DestinationFeeManagerProcessFeeTest:test_processMultipleUnwrappedNativeReports() (gas: 264223) +DestinationFeeManagerProcessFeeTest:test_processMultipleV1Reports() (gas: 81155) +DestinationFeeManagerProcessFeeTest:test_processMultipleWrappedNativeReports() (gas: 247072) +DestinationFeeManagerProcessFeeTest:test_processPoolIdsPassedMismatched() (gas: 98793) +DestinationFeeManagerProcessFeeTest:test_processV1V2V3Reports() (gas: 215445) +DestinationFeeManagerProcessFeeTest:test_processV1V2V3ReportsWithUnwrapped() (gas: 257087) +DestinationFeeManagerProcessFeeTest:test_removeVerifierNonExistentAddress() (gas: 12822) +DestinationFeeManagerProcessFeeTest:test_removeVerifierZeroAaddress() (gas: 10678) +DestinationFeeManagerProcessFeeTest:test_reportWithNoExpiryOrFeeReturnsZero() (gas: 13615) +DestinationFeeManagerProcessFeeTest:test_revertOnSettingAnAddressZeroVerifier() (gas: 10614) +DestinationFeeManagerProcessFeeTest:test_rewardsAreCorrectlySentToEachAssociatedPoolWhenVerifyingInBulk() (gas: 263181) +DestinationFeeManagerProcessFeeTest:test_setDiscountOver100Percent() (gas: 19562) +DestinationFeeManagerProcessFeeTest:test_setRewardManagerZeroAddress() (gas: 10626) +DestinationFeeManagerProcessFeeTest:test_subscriberDiscountEventIsEmittedOnUpdate() (gas: 46329) +DestinationFeeManagerProcessFeeTest:test_surchargeFeeRoundsUpWhenUneven() (gas: 51261) +DestinationFeeManagerProcessFeeTest:test_surchargeIsApplied() (gas: 51165) +DestinationFeeManagerProcessFeeTest:test_surchargeIsAppliedForNativeFeeWithDiscount() (gas: 79356) +DestinationFeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 47132) +DestinationFeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 49962) +DestinationFeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 78352) +DestinationFeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 14943) +DestinationRewardManagerClaimTest:test_claimAllRecipients() (gas: 277191) +DestinationRewardManagerClaimTest:test_claimMultipleRecipients() (gas: 154371) +DestinationRewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 330208) +DestinationRewardManagerClaimTest:test_claimSingleRecipient() (gas: 89039) +DestinationRewardManagerClaimTest:test_claimUnevenAmountRoundsDown() (gas: 315411) +DestinationRewardManagerClaimTest:test_claimUnregisteredPoolId() (gas: 35164) +DestinationRewardManagerClaimTest:test_claimUnregisteredRecipient() (gas: 41201) +DestinationRewardManagerClaimTest:test_eventIsEmittedUponClaim() (gas: 86084) +DestinationRewardManagerClaimTest:test_eventIsNotEmittedUponUnsuccessfulClaim() (gas: 25050) +DestinationRewardManagerClaimTest:test_recipientsClaimMultipleDeposits() (gas: 386857) +DestinationRewardManagerClaimTest:test_singleRecipientClaimMultipleDeposits() (gas: 137777) +DestinationRewardManagerNoRecipientSet:test_claimAllRecipientsAfterRecipientsSet() (gas: 492227) +DestinationRewardManagerPayRecipientsTest:test_addFundsToPoolAsNonOwnerOrFeeManager() (gas: 11503) +DestinationRewardManagerPayRecipientsTest:test_addFundsToPoolAsOwner() (gas: 53944) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipients() (gas: 250829) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsFromNonAdminUser() (gas: 20496) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsFromRecipientInPool() (gas: 251075) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalInvalidRecipient() (gas: 262275) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalUnregisteredRecipient() (gas: 265760) +DestinationRewardManagerPayRecipientsTest:test_payRecipientWithInvalidPool() (gas: 28908) +DestinationRewardManagerPayRecipientsTest:test_payRecipientsEmptyRecipientList() (gas: 25333) +DestinationRewardManagerPayRecipientsTest:test_payRecipientsWithInvalidPoolId() (gas: 31402) +DestinationRewardManagerPayRecipientsTest:test_paySingleRecipient() (gas: 84709) +DestinationRewardManagerPayRecipientsTest:test_paySubsetOfRecipientsInPool() (gas: 198474) +DestinationRewardManagerRecipientClaimDifferentWeightsTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 280853) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsMultiplePools() (gas: 512489) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsSinglePool() (gas: 283649) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimEmptyPoolWhenSecondPoolContainsFunds() (gas: 293497) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsMultiplePools() (gas: 263075) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsSinglePool() (gas: 154537) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleRecipientMultiplePools() (gas: 132653) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleUniqueRecipient() (gas: 106056) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimUnevenAmountRoundsDown() (gas: 579776) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimUnregisteredRecipient() (gas: 64664) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorAndTotalPoolsEqual() (gas: 13074) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorCannotBeGreaterThanTotalPools() (gas: 12703) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorSingleResult() (gas: 22471) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPools() (gas: 32248) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() (gas: 148629) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInNoPools() (gas: 21728) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInSinglePool() (gas: 27765) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_recipientsClaimMultipleDeposits() (gas: 391427) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_singleRecipientClaimMultipleDeposits() (gas: 137862) +DestinationRewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 199546) +DestinationRewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() (gas: 219419) +DestinationRewardManagerSetRecipientsTest:test_eventIsEmittedUponSetRecipients() (gas: 191707) +DestinationRewardManagerSetRecipientsTest:test_setRecipientContainsDuplicateRecipients() (gas: 126060) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientFromManagerAddress() (gas: 214117) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() (gas: 21496) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientTwice() (gas: 193280) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWeights() (gas: 180608) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroAddress() (gas: 90202) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroWeight() (gas: 191312) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipients() (gas: 185567) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientsIsEmpty() (gas: 87091) +DestinationRewardManagerSetRecipientsTest:test_setSingleRewardRecipient() (gas: 110349) +DestinationRewardManagerSetupTest:test_addFeeManagerExistingAddress() (gas: 35281) +DestinationRewardManagerSetupTest:test_addFeeManagerZeroAddress() (gas: 10580) +DestinationRewardManagerSetupTest:test_addRemoveFeeManager() (gas: 48248) +DestinationRewardManagerSetupTest:test_eventEmittedUponFeeManagerUpdate() (gas: 41581) +DestinationRewardManagerSetupTest:test_eventEmittedUponFeePaid() (gas: 259172) +DestinationRewardManagerSetupTest:test_rejectsZeroLinkAddressOnConstruction() (gas: 59610) +DestinationRewardManagerSetupTest:test_removeFeeManagerNonExistentAddress() (gas: 12778) +DestinationRewardManagerSetupTest:test_setFeeManagerZeroAddress() (gas: 17084) +DestinationRewardManagerUpdateRewardRecipientsMultiplePoolsTest:test_updatePrimaryRecipientWeights() (gas: 376674) +DestinationRewardManagerUpdateRewardRecipientsTest:test_eventIsEmittedUponUpdateRecipients() (gas: 280411) +DestinationRewardManagerUpdateRewardRecipientsTest:test_onlyAdminCanUpdateRecipients() (gas: 19705) +DestinationRewardManagerUpdateRewardRecipientsTest:test_partialUpdateRecipientWeights() (gas: 221004) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateAllRecipientsWithSameAddressAndWeight() (gas: 274233) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsToSubset() (gas: 254156) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithExcessiveWeight() (gas: 259143) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithSameAddressAndWeight() (gas: 149856) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithUnderWeightSet() (gas: 259217) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientWeights() (gas: 372155) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientWithNewZeroAddress() (gas: 270700) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsContainsDuplicateRecipients() (gas: 288483) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentLargerSet() (gas: 407780) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentPartialSet() (gas: 317945) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSet() (gas: 377692) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSetWithInvalidWeights() (gas: 312038) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForLargerSet() (gas: 399603) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() (gas: 289433) +DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 639153) +DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNative() (gas: 640232) +DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrapped() (gas: 661796) +DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrappedReturnsChange() (gas: 661751) +DestinationVerifierConstructorTest:test_falseIfIsNotCorrectInterface() (gas: 8719) +DestinationVerifierConstructorTest:test_revertsIfInitializedWithEmptyVerifierProxy() (gas: 61121) +DestinationVerifierConstructorTest:test_trueIfIsCorrectInterface() (gas: 8604) +DestinationVerifierConstructorTest:test_typeAndVersion() (gas: 2818189) +DestinationVerifierProxyInitializeVerifierTest:test_correctlySetsTheOwner() (gas: 1035181) +DestinationVerifierProxyInitializeVerifierTest:test_correctlySetsVersion() (gas: 9841) +DestinationVerifierProxyInitializeVerifierTest:test_setVerifierCalledByNoOwner() (gas: 17483) +DestinationVerifierProxyInitializeVerifierTest:test_setVerifierOk() (gas: 30622) +DestinationVerifierProxyInitializeVerifierTest:test_setVerifierWhichDoesntHonourInterface() (gas: 16851) +DestinationVerifierSetAccessControllerTest:test_emitsTheCorrectEvent() (gas: 35391) +DestinationVerifierSetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 15089) +DestinationVerifierSetAccessControllerTest:test_successfullySetsNewAccessController() (gas: 34885) +DestinationVerifierSetAccessControllerTest:test_successfullySetsNewAccessControllerIsEmpty() (gas: 15007) +DestinationVerifierSetConfigTest:test_NoDonConfigAlreadyExists() (gas: 2874492) +DestinationVerifierSetConfigTest:test_addressesAndWeightsDoNotProduceSideEffectsInDonConfigIds() (gas: 1323177) +DestinationVerifierSetConfigTest:test_donConfigIdIsSameForSignersInDifferentOrder() (gas: 1290374) +DestinationVerifierSetConfigTest:test_removeLatestConfig() (gas: 786275) +DestinationVerifierSetConfigTest:test_removeLatestConfigWhenNoConfigShouldFail() (gas: 12870) +DestinationVerifierSetConfigTest:test_revertsIfCalledByNonOwner() (gas: 174936) +DestinationVerifierSetConfigTest:test_revertsIfDuplicateSigners() (gas: 171604) +DestinationVerifierSetConfigTest:test_revertsIfFaultToleranceIsZero() (gas: 168484) +DestinationVerifierSetConfigTest:test_revertsIfNotEnoughSigners() (gas: 11571) +DestinationVerifierSetConfigTest:test_revertsIfSetWithTooManySigners() (gas: 17943) +DestinationVerifierSetConfigTest:test_revertsIfSignerContainsZeroAddress() (gas: 324333) +DestinationVerifierSetConfigTest:test_setConfigActiveUnknownDonConfigId() (gas: 13102) +DestinationVerifierSetConfigTest:test_setConfigWithActivationTime() (gas: 1088176) +DestinationVerifierSetConfigTest:test_setConfigWithActivationTimeEarlierThanLatestConfigShouldFail() (gas: 1963414) +DestinationVerifierSetConfigTest:test_setConfigWithActivationTimeNoFutureTimeShouldFail() (gas: 259797) FeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52645) FeeManagerProcessFeeTest:test_DiscountIsReturnedForNative() (gas: 52595) FeeManagerProcessFeeTest:test_DiscountIsReturnedForNativeWithSurcharge() (gas: 78808) @@ -108,6 +325,7 @@ FeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 47 FeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 49938) FeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 78261) FeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 14919) +MultiVerifierBillingTests:test_multipleFeeManagersAndVerifiers() (gas: 4586990) RewardManagerClaimTest:test_claimAllRecipients() (gas: 277131) RewardManagerClaimTest:test_claimMultipleRecipients() (gas: 154341) RewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 330086) @@ -200,6 +418,13 @@ VerifierActivateFeedTest:test_revertsIfNoFeedExistsActivate() (gas: 13179) VerifierActivateFeedTest:test_revertsIfNoFeedExistsDeactivate() (gas: 13157) VerifierActivateFeedTest:test_revertsIfNotOwnerActivateFeed() (gas: 17109) VerifierActivateFeedTest:test_revertsIfNotOwnerDeactivateFeed() (gas: 17164) +VerifierBillingTests:test_rewardsAreDistributedAccordingToWeights() (gas: 1731717) +VerifierBillingTests:test_rewardsAreDistributedAccordingToWeightsMultipleWeigths() (gas: 4460715) +VerifierBillingTests:test_rewardsAreDistributedAccordingToWeightsUsingHistoricalConfigs() (gas: 2098833) +VerifierBillingTests:test_verifyWithLinkV3Report() (gas: 1591346) +VerifierBillingTests:test_verifyWithNativeERC20() (gas: 1467256) +VerifierBillingTests:test_verifyWithNativeUnwrapped() (gas: 1376447) +VerifierBillingTests:test_verifyWithNativeUnwrappedReturnsChange() (gas: 1383493) VerifierBulkVerifyBillingReport:test_verifyMultiVersions() (gas: 476595) VerifierBulkVerifyBillingReport:test_verifyMultiVersionsReturnsVerifiedReports() (gas: 474853) VerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 557541) @@ -212,6 +437,7 @@ VerifierDeactivateFeedWithVerifyTest:test_currentReportAllowsVerification() (gas VerifierDeactivateFeedWithVerifyTest:test_currentReportFailsVerification() (gas: 113388) VerifierDeactivateFeedWithVerifyTest:test_previousReportAllowsVerification() (gas: 99624) VerifierDeactivateFeedWithVerifyTest:test_previousReportFailsVerification() (gas: 69943) +VerifierInterfacesTest:test_DestinationContractInterfaces() (gas: 623467) VerifierProxyAccessControlledVerificationTest:test_proxiesToTheVerifierIfHasAccess() (gas: 208529) VerifierProxyAccessControlledVerificationTest:test_revertsIfNoAccess() (gas: 112345) VerifierProxyConstructorTest:test_correctlySetsTheCorrectAccessControllerInterface() (gas: 1485359) @@ -236,6 +462,9 @@ VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_correctlyUnsetsVeri VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_emitsAnEventAfterUnsettingVerifier() (gas: 17961) VerifierProxyVerifyTest:test_proxiesToTheCorrectVerifier() (gas: 204342) VerifierProxyVerifyTest:test_revertsIfNoVerifierConfigured() (gas: 117264) +VerifierSetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 17196) +VerifierSetAccessControllerTest:test_setFeeManagerWhichDoesntHonourInterface() (gas: 16571) +VerifierSetAccessControllerTest:test_successfullySetsNewFeeManager() (gas: 44855) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 542302) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 967768) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 523251) @@ -256,6 +485,9 @@ VerifierTestBillingReport:test_verifyWithLink() (gas: 275293) VerifierTestBillingReport:test_verifyWithNative() (gas: 316326) VerifierTestBillingReport:test_verifyWithNativeUnwrapped() (gas: 318574) VerifierTestBillingReport:test_verifyWithNativeUnwrappedReturnsChange() (gas: 325642) +VerifierVerifyBulkTest:test_revertsVerifyBulkIfNoAccess() (gas: 112867) +VerifierVerifyBulkTest:test_verifyBulkSingleCaseWithSingleConfig() (gas: 745046) +VerifierVerifyBulkTest:test_verifyBulkWithSingleConfigOneVerifyFails() (gas: 698203) VerifierVerifyMultipleConfigDigestTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 133961) VerifierVerifyMultipleConfigDigestTest:test_canVerifyOlderReportsWithOlderConfigs() (gas: 189865) VerifierVerifyMultipleConfigDigestTest:test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() (gas: 88216) @@ -270,6 +502,18 @@ VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedByNonProxy() (gas: 10 VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedWithIncorrectAddresses() (gas: 184077) VerifierVerifySingleConfigDigestTest:test_revertsIfWrongNumberOfSigners() (gas: 110042) VerifierVerifySingleConfigDigestTest:test_setsTheCorrectEpoch() (gas: 194592) +VerifierVerifyTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 861741) +VerifierVerifyTest:test_canVerifyOlderV3ReportsWithOlderConfigs() (gas: 815984) +VerifierVerifyTest:test_failToVerifyReportIfDupSigners() (gas: 450715) +VerifierVerifyTest:test_failToVerifyReportIfNoSigners() (gas: 426492) +VerifierVerifyTest:test_failToVerifyReportIfNotEnoughSigners() (gas: 434814) +VerifierVerifyTest:test_failToVerifyReportIfSignerNotInConfig() (gas: 456866) +VerifierVerifyTest:test_revertsVerifyIfNoAccess() (gas: 109465) +VerifierVerifyTest:test_rollingOutConfiguration() (gas: 1497254) +VerifierVerifyTest:test_scenarioRollingNewChainWithHistoricConfigs() (gas: 976162) +VerifierVerifyTest:test_verifyFailsWhenReportIsOlderThanConfig() (gas: 2303366) +VerifierVerifyTest:test_verifyReport() (gas: 1434811) +VerifierVerifyTest:test_verifyTooglingActiveFlagsDonConfigs() (gas: 1918797) Verifier_accessControlledVerify:testVerifyWithAccessControl_gas() (gas: 212077) Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithLinkFeeSuccess_gas() (gas: 519389) Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithNativeFeeSuccess_gas() (gas: 542808) diff --git a/contracts/gas-snapshots/operatorforwarder.gas-snapshot b/contracts/gas-snapshots/operatorforwarder.gas-snapshot index 66bb19f1f6..551fde38f3 100644 --- a/contracts/gas-snapshots/operatorforwarder.gas-snapshot +++ b/contracts/gas-snapshots/operatorforwarder.gas-snapshot @@ -2,8 +2,8 @@ FactoryTest:test_DeployNewForwarderAndTransferOwnership_Success() (gas: 1059722) FactoryTest:test_DeployNewForwarder_Success() (gas: 1048209) FactoryTest:test_DeployNewOperatorAndForwarder_Success() (gas: 4069305) FactoryTest:test_DeployNewOperator_Success() (gas: 3020464) -ForwarderTest:test_Forward_Success(uint256) (runs: 257, μ: 226979, ~: 227289) -ForwarderTest:test_MultiForward_Success(uint256,uint256) (runs: 257, μ: 258577, ~: 259120) +ForwarderTest:test_Forward_Success(uint256) (runs: 256, μ: 226978, ~: 227289) +ForwarderTest:test_MultiForward_Success(uint256,uint256) (runs: 256, μ: 258575, ~: 259120) ForwarderTest:test_OwnerForward_Success() (gas: 30118) ForwarderTest:test_SetAuthorizedSenders_Success() (gas: 160524) ForwarderTest:test_TransferOwnershipWithMessage_Success() (gas: 35123) @@ -11,5 +11,5 @@ OperatorTest:test_CancelOracleRequest_Success() (gas: 274436) OperatorTest:test_FulfillOracleRequest_Success() (gas: 330603) OperatorTest:test_NotAuthorizedSender_Revert() (gas: 246716) OperatorTest:test_OracleRequest_Success() (gas: 250019) -OperatorTest:test_SendRequestAndCancelRequest_Success(uint96) (runs: 257, μ: 387121, ~: 387124) -OperatorTest:test_SendRequest_Success(uint96) (runs: 257, μ: 303612, ~: 303615) \ No newline at end of file +OperatorTest:test_SendRequestAndCancelRequest_Success(uint96) (runs: 256, μ: 387121, ~: 387124) +OperatorTest:test_SendRequest_Success(uint96) (runs: 256, μ: 303612, ~: 303615) \ No newline at end of file diff --git a/contracts/gas-snapshots/shared.gas-snapshot b/contracts/gas-snapshots/shared.gas-snapshot index 0848baa098..dda850089c 100644 --- a/contracts/gas-snapshots/shared.gas-snapshot +++ b/contracts/gas-snapshots/shared.gas-snapshot @@ -39,10 +39,10 @@ CallWithExactGas__callWithExactGas:test_CallWithExactGasSafeReturnDataExactGas() CallWithExactGas__callWithExactGas:test_NoContractReverts() (gas: 11559) CallWithExactGas__callWithExactGas:test_NoGasForCallExactCheckReverts() (gas: 15788) CallWithExactGas__callWithExactGas:test_NotEnoughGasForCallReverts() (gas: 16241) -CallWithExactGas__callWithExactGas:test_callWithExactGasSuccess(bytes,bytes4) (runs: 257, μ: 15767, ~: 15719) +CallWithExactGas__callWithExactGas:test_callWithExactGasSuccess(bytes,bytes4) (runs: 256, μ: 15766, ~: 15719) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractExactGasSuccess() (gas: 20116) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractReceiverErrorSuccess() (gas: 67721) -CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractSuccess(bytes,bytes4) (runs: 257, μ: 16277, ~: 16229) +CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractSuccess(bytes,bytes4) (runs: 256, μ: 16276, ~: 16229) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoContractSuccess() (gas: 12962) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoGasForCallExactCheckReturnFalseSuccess() (gas: 13005) CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NotEnoughGasForCallReturnsFalseSuccess() (gas: 13317) From 1356b654d5baa16ca0c1a41f300fa131e614d2f8 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Fri, 30 Aug 2024 14:18:14 +0200 Subject: [PATCH 258/432] bump go-plugin; rm replace (#14288) --- core/scripts/go.mod | 5 +---- core/scripts/go.sum | 4 ++-- go.mod | 5 +---- go.sum | 4 ++-- integration-tests/go.mod | 5 +---- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 5 +---- integration-tests/load/go.sum | 4 ++-- 8 files changed, 12 insertions(+), 24 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 648c856f4a..2ae9753630 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -188,7 +188,7 @@ require ( github.com/hashicorp/go-envparse v0.1.0 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-plugin v1.6.0 // indirect + github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 // indirect github.com/hashicorp/go-retryablehttp v0.7.5 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -367,9 +367,6 @@ replace ( // replicating the replace directive on cosmos SDK github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 - github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 - // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f diff --git a/core/scripts/go.sum b/core/scripts/go.sum index bfdc83dd75..e9fefa6d4f 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -718,6 +718,8 @@ github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJ github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 h1:OSQYEsRT3tRttZkk6zyC3aAaliwd7Loi/KgXgXxGtwA= +github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= @@ -1200,8 +1202,6 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= -github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= diff --git a/go.mod b/go.mod index ea1dda8916..baf4c187ef 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/graph-gophers/graphql-go v1.3.0 github.com/hashicorp/consul/sdk v0.16.0 github.com/hashicorp/go-envparse v0.1.0 - github.com/hashicorp/go-plugin v1.6.0 + github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 github.com/hashicorp/go-retryablehttp v0.7.5 github.com/hdevalence/ed25519consensus v0.1.0 github.com/jackc/pgconn v1.14.3 @@ -353,9 +353,6 @@ replace ( // replicating the replace directive on cosmos SDK github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 - github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 - // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f ) diff --git a/go.sum b/go.sum index 915e5efce7..fee72a6493 100644 --- a/go.sum +++ b/go.sum @@ -682,6 +682,8 @@ github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJ github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 h1:OSQYEsRT3tRttZkk6zyC3aAaliwd7Loi/KgXgXxGtwA= +github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= @@ -1157,8 +1159,6 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= -github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 7a4090aa88..792452ee52 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -283,7 +283,7 @@ require ( github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-msgpack v0.5.5 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.6.0 // indirect + github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 // indirect github.com/hashicorp/go-retryablehttp v0.7.5 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect @@ -518,9 +518,6 @@ replace ( // replicating the replace directive on cosmos SDK github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 - github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 - // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 1a2f647e80..3227d1ec70 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -897,6 +897,8 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 h1:OSQYEsRT3tRttZkk6zyC3aAaliwd7Loi/KgXgXxGtwA= +github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= @@ -1445,8 +1447,6 @@ github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 h1:GRAAvtn2+ github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= -github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= -github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 4210ef7874..6e9b41bf38 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -273,7 +273,7 @@ require ( github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-msgpack v0.5.5 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.6.0 // indirect + github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 // indirect github.com/hashicorp/go-retryablehttp v0.7.5 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect @@ -515,9 +515,6 @@ replace ( // replicating the replace directive on cosmos SDK github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 - github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 - // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index b5a834a1cd..252abe8104 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -881,6 +881,8 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 h1:OSQYEsRT3tRttZkk6zyC3aAaliwd7Loi/KgXgXxGtwA= +github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= @@ -1415,8 +1417,6 @@ github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 h1:GRAAvtn2+ github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= -github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= -github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= From 154ff5fd525d2f22c9e09d302afbd50bc41c634a Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Fri, 30 Aug 2024 14:19:27 +0200 Subject: [PATCH 259/432] Make lint-integration-tests job required in PRs (#14287) * Make lint-integration-tests job required in PRs * rename step * test lint * test lint 2 * fix lint --- .github/workflows/integration-tests.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 972228bc8e..9a9dec15c8 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -308,7 +308,7 @@ jobs: if: always() name: ETH Smoke Tests runs-on: ubuntu-latest - needs: [run-core-e2e-tests-workflow, run-ccip-e2e-tests-workflow] + needs: [lint-integration-tests, run-core-e2e-tests-workflow, run-ccip-e2e-tests-workflow] steps: - name: Check Core test results id: check_core_results @@ -340,13 +340,13 @@ jobs: channel-id: "#team-test-tooling-internal" slack-message: ":x: :mild-panic-intensifies: Node Migration Tests Failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}\n${{ format('Notifying ', secrets.GUARDIAN_SLACK_NOTIFICATION_HANDLE) }}" - - name: Fail the job if Core tests failed - if: always() && needs.run-core-e2e-tests-workflow.result == 'failure' - run: | - echo "Core E2E tests failed" - echo "Job status:" - echo ${{ needs.run-core-e2e-tests-workflow.result }} - exit 1 + - name: Fail the job if core tests not successful + if: always() && needs.run-core-e2e-tests-workflow.result != 'success' + run: exit 1 + + - name: Fail the job if lint not successful + if: always() && needs.lint-integration-tests.result != 'success' + run: exit 1 cleanup: name: Clean up integration environment deployments From df43633f04430bac2b4f3ba150eefc9995a17162 Mon Sep 17 00:00:00 2001 From: Michael Fletcher <36506122+Fletch153@users.noreply.github.com> Date: Fri, 30 Aug 2024 13:21:18 +0100 Subject: [PATCH 260/432] Merge sbrv (#14259) * Initial Impl of SBRV * Generate wrappers/ABI * Removed ZeroAddress check for feemanager & AC * Update gethwrappers * Rename RewardManager=>DestinationRewardManager * Remove circular dependency between proxy and verifier * Fixes to init logic * Update gethwrappers * llo-feeds: v0.4.0 reward manager tests * Add check to remove assumption that feeManager cannot be nil * Generate * Fixed poolIdMismatch not being thrown * Fix logic error when looking up the activeDonConfig * Update gethwrappers * Update interface sanity checks when setting verifier * Add remaining interface functionality * Update gethwrappers * llo-feeds: verifier SetConfig tests * llo-feeds: adding verifier contract get methods for easier testing * adding rewards wire up for testing * incomeplte fix for test_setConfigWithAddressesAndWeightsAreSetCorrectly * llo-feeds: adjusting setConfig tests due to changes * llo-feeds: fee manager v0.4.0 tests: making v0.3.0 tests pass * llo-feeds: fee manager v0.4.0 tests: fee manager - adding test for PoolIdMismatch * llo-feeds: fee manager v0.4.0 tests: nits * llo-feeds: feeManager bulk reverts when PoolId is 0 * llo-feeds: feeManager tests revertOnSettingAnAddressZeroVerifier onlyCallableByOwnerReverts * llo-feeds: feeManager test poolIdsCannotBeZeroAddress * llo-feeds: rewardManager test_rewardsAreCorrectlySentToEachAssociatedPoolWhenVerifyingInBulk * llo-feeds: verifier proxy tests * llo-feeds: fixing DestinationProxy error handling * llo-feeds: fixing DestinationProxy test remove verifiercontract zero check * llo-feeds: remove interface checks for verifierProxy * llo-feeds: clean up setConfig tests from checking internal state * fix issue when processing rewards * Apply suggestions from code review * Update contracts/src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol * Update contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifierProxy.sol * llo-feeds: verifier proxy remove test test_setVerifierZeroVerifier * llo-feeds: tests for verify and verifyBulk * clean up * temporal fix for compile error * llo: v0.4.0 removing V1 report tests * better comments * llo-feeds: verify test test_rollingOutConfiguration * llo-feeds: verify test test_verifyFailsWhenReportIsOlderThanConfig * llo-feeds: verify test test_verifyFailsWhenReportIsOlderThanConfig * llo-feeds: tests for billing / billing bulk * fixing tests * fixing tests names * llo-feeds: fix proxy contract should send value in call to verify * llo-feeds: fix billing tests * squash me * llo-feeds: billing bulk verify tests * llo-feeds: clean up * llo-feeds: VerifierSetAccessControllerTest * llo-feeds: clean up * llo-feeds: extra proxy tests * Update contracts/src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol * Fix issue with oldest config verifying incorrectly * Fix issue with oldest config verifying incorrectly * llo-feeds: fix underflow and test_verifyFailsWhenReportIsOlderThanConfig * Update gethwrappers * Update gethwrappers * llo-feeds: DestinationVerifier setFeeManager tests * llo-feeds: Tests for Rewards and configs * llo-feeds: Tests for DestinationVerifier constructor * llo-feeds: reverse looping efficiently * Update contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifier.sol * Update gethwrappers * llo-feeds: fmt contract tests * llo-feeds: npx prettify contract tests * llo-feeds: npx prettify v0.4.0 contracts * se --Add ability to amend config array * Update gethwrappers * Fix issue with future timestamps * Update gethwrappers * Small fix * Fix broken tests * Update gethwrappers * llo-feeds: Tests setConfigWithActivationTime * llo-feeds: Tests setConfigWithActivationTime * llo-feeds: Tests VerifierRemoveLatestConfigTest * llo-feeds: fixing linter errors (unused imports) * llo-feeds: tests better filenaming * Improve upgradability of contracts * Update gethwrappers * Small fix when setting rewardManager * Update gethwrappers * Fix var name to honour same interface * Update gethwrappers * Improve getter consistency * Update gethwrappers * Fix comments & conventions * Update DON Config to camal case * Update gethwrappers * solhint + gas snapshot * prettier * Solhint fixes * Update gethwrappers * gas snapshot * Fixed gas issue * Gas snapshot * llo-feeds: testing multiple fee managers and verifiers * llo: fixing tests * Update contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTestRewardsMultiVefifierFeeManager.t.sol Co-authored-by: msuchacz-cll <170782674+msuchacz-cll@users.noreply.github.com> * llo: v0.4.0 interfaces test * Fixed gas snaposhot * prettier * Fixed issues when feeManager isn't set * Fix IERC impl for v0.4.0 contracts * Optimisations * Add global discount * Update gethwrappers * Small fixes * Fix conflicting configs on same timestamp * Fix tests * Update gethwrappers * Prettier / cleanup * Fix generate --------- Co-authored-by: Sam Davies Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> Co-authored-by: David Przybilla Co-authored-by: ad0ll <20057155+ad0ll@users.noreply.github.com> Co-authored-by: msuchacz-cll <170782674+msuchacz-cll@users.noreply.github.com> --- .../gas-snapshots/llo-feeds.gas-snapshot | 434 +++++++++--------- .../v0.4.0/DestinationFeeManager.sol | 64 ++- .../v0.4.0/DestinationRewardManager.sol | 16 +- .../llo-feeds/v0.4.0/DestinationVerifier.sol | 73 +-- .../v0.4.0/DestinationVerifierProxy.sol | 25 +- .../interfaces/IDestinationFeeManager.sol | 46 +- .../interfaces/IDestinationVerifier.sol | 45 +- .../IDestinationVerifierFeeManager.sol | 45 ++ .../interfaces/IDestinationVerifierProxy.sol | 4 +- .../IDestinationVerifierProxyVerifier.sol | 48 ++ .../BaseDestinationFeeManager.t.sol | 14 +- ...estinationFeeManager.getFeeAndReward.t.sol | 114 +++++ .../test/mocks/DestinationFeeManagerProxy.sol | 8 +- .../DestinationVerifierProxyTest.t.sol | 2 +- .../DestinationVerifierSetConfigTest.t.sol | 17 + .../verifier/DestinationVerifierTest.t.sol | 7 +- .../DestinationVerifierVerifyTest.t.sol | 3 + .../destination_fee_manager.go | 42 +- .../destination_reward_manager.go | 2 +- .../destination_verifier.go | 7 +- .../destination_verifier_proxy.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 8 +- 22 files changed, 628 insertions(+), 398 deletions(-) create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierFeeManager.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierProxyVerifier.sol diff --git a/contracts/gas-snapshots/llo-feeds.gas-snapshot b/contracts/gas-snapshots/llo-feeds.gas-snapshot index 68f3c016f6..8b52c6a6c5 100644 --- a/contracts/gas-snapshots/llo-feeds.gas-snapshot +++ b/contracts/gas-snapshots/llo-feeds.gas-snapshot @@ -21,220 +21,230 @@ ByteUtilTest:test_readZeroAddress() (gas: 3365) ChannelConfigStoreTest:testSetChannelDefinitions() (gas: 46927) ChannelConfigStoreTest:testSupportsInterface() (gas: 8367) ChannelConfigStoreTest:testTypeAndVersion() (gas: 9621) -DestinationFeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52669) -DestinationFeeManagerProcessFeeTest:test_DiscountIsReturnedForNative() (gas: 52685) -DestinationFeeManagerProcessFeeTest:test_DiscountIsReturnedForNativeWithSurcharge() (gas: 78876) -DestinationFeeManagerProcessFeeTest:test_V1PayloadVerifies() (gas: 29324) -DestinationFeeManagerProcessFeeTest:test_V1PayloadVerifiesAndReturnsChange() (gas: 61187) -DestinationFeeManagerProcessFeeTest:test_V2PayloadVerifies() (gas: 121137) -DestinationFeeManagerProcessFeeTest:test_V2PayloadWithoutQuoteFails() (gas: 29669) -DestinationFeeManagerProcessFeeTest:test_V2PayloadWithoutZeroFee() (gas: 74797) -DestinationFeeManagerProcessFeeTest:test_WithdrawERC20() (gas: 72796) -DestinationFeeManagerProcessFeeTest:test_WithdrawNonAdminAddr() (gas: 56334) -DestinationFeeManagerProcessFeeTest:test_WithdrawUnwrappedNative() (gas: 26411) -DestinationFeeManagerProcessFeeTest:test_addVerifier() (gas: 131079) -DestinationFeeManagerProcessFeeTest:test_addVerifierExistingAddress() (gas: 34148) -DestinationFeeManagerProcessFeeTest:test_baseFeeIsAppliedForLink() (gas: 17214) -DestinationFeeManagerProcessFeeTest:test_baseFeeIsAppliedForNative() (gas: 20152) -DestinationFeeManagerProcessFeeTest:test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() (gas: 91103) -DestinationFeeManagerProcessFeeTest:test_discountAIsNotAppliedWhenSetForOtherUsers() (gas: 56580) -DestinationFeeManagerProcessFeeTest:test_discountFeeRoundsDownWhenUneven() (gas: 52871) -DestinationFeeManagerProcessFeeTest:test_discountIsAppliedForLink() (gas: 49682) -DestinationFeeManagerProcessFeeTest:test_discountIsAppliedWith100PercentSurcharge() (gas: 78949) -DestinationFeeManagerProcessFeeTest:test_discountIsNoLongerAppliedAfterRemoving() (gas: 46567) -DestinationFeeManagerProcessFeeTest:test_discountIsNotAppliedForInvalidTokenAddress() (gas: 17582) -DestinationFeeManagerProcessFeeTest:test_discountIsNotAppliedToOtherFeeds() (gas: 54628) -DestinationFeeManagerProcessFeeTest:test_discountIsReturnedForLink() (gas: 49654) -DestinationFeeManagerProcessFeeTest:test_emptyQuoteRevertsWithError() (gas: 12231) -DestinationFeeManagerProcessFeeTest:test_eventIsEmittedAfterSurchargeIsSet() (gas: 41424) -DestinationFeeManagerProcessFeeTest:test_eventIsEmittedIfNotEnoughLink() (gas: 179229) -DestinationFeeManagerProcessFeeTest:test_eventIsEmittedUponWithdraw() (gas: 69057) -DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterDiscountIsRemoved() (gas: 49831) -DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewDiscountIsApplied() (gas: 67769) -DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewSurchargeIsApplied() (gas: 64460) -DestinationFeeManagerProcessFeeTest:test_feeIsZeroWith100PercentDiscount() (gas: 52091) -DestinationFeeManagerProcessFeeTest:test_getBaseRewardWithLinkQuote() (gas: 17231) -DestinationFeeManagerProcessFeeTest:test_getLinkFeeIsRoundedUp() (gas: 49853) -DestinationFeeManagerProcessFeeTest:test_getLinkRewardIsSameAsFee() (gas: 55711) -DestinationFeeManagerProcessFeeTest:test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() (gas: 82833) -DestinationFeeManagerProcessFeeTest:test_getRewardWithLinkDiscount() (gas: 49700) -DestinationFeeManagerProcessFeeTest:test_getRewardWithLinkQuoteAndLinkDiscount() (gas: 49681) -DestinationFeeManagerProcessFeeTest:test_getRewardWithNativeQuote() (gas: 20150) -DestinationFeeManagerProcessFeeTest:test_getRewardWithNativeQuoteAndSurcharge() (gas: 50885) -DestinationFeeManagerProcessFeeTest:test_linkAvailableForPaymentReturnsLinkBalance() (gas: 53172) -DestinationFeeManagerProcessFeeTest:test_nativeSurcharge0Percent() (gas: 30937) -DestinationFeeManagerProcessFeeTest:test_nativeSurcharge100Percent() (gas: 50887) -DestinationFeeManagerProcessFeeTest:test_nativeSurchargeCannotExceed100Percent() (gas: 17220) -DestinationFeeManagerProcessFeeTest:test_nativeSurchargeEventIsEmittedOnUpdate() (gas: 41402) -DestinationFeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFee() (gas: 51914) -DestinationFeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() (gas: 78172) -DestinationFeeManagerProcessFeeTest:test_nonAdminProxyUserCannotProcessFee() (gas: 24185) -DestinationFeeManagerProcessFeeTest:test_nonAdminUserCanNotSetDiscount() (gas: 19871) -DestinationFeeManagerProcessFeeTest:test_onlyCallableByOwnerReverts() (gas: 15453) -DestinationFeeManagerProcessFeeTest:test_payLinkDeficit() (gas: 198072) -DestinationFeeManagerProcessFeeTest:test_payLinkDeficitOnlyCallableByAdmin() (gas: 17415) -DestinationFeeManagerProcessFeeTest:test_payLinkDeficitPaysAllFeesProcessed() (gas: 218691) -DestinationFeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 202446) -DestinationFeeManagerProcessFeeTest:test_poolIdsCannotBeZeroAddress() (gas: 115317) -DestinationFeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 121475) -DestinationFeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 29745) -DestinationFeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 165393) -DestinationFeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 32563) -DestinationFeeManagerProcessFeeTest:test_processFeeNative() (gas: 178204) -DestinationFeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 122766) -DestinationFeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 31822) -DestinationFeeManagerProcessFeeTest:test_processFeeWithDiscountEmitsEvent() (gas: 245890) -DestinationFeeManagerProcessFeeTest:test_processFeeWithInvalidReportVersionFailsToDecode() (gas: 30770) -DestinationFeeManagerProcessFeeTest:test_processFeeWithNoDiscountDoesNotEmitEvent() (gas: 171109) -DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNative() (gas: 186069) -DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddress() (gas: 135874) -DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() (gas: 161459) -DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeShortFunds() (gas: 94841) -DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeWithExcessiveFee() (gas: 193032) -DestinationFeeManagerProcessFeeTest:test_processFeeWithWithCorruptQuotePayload() (gas: 75084) -DestinationFeeManagerProcessFeeTest:test_processFeeWithWithEmptyQuotePayload() (gas: 30006) -DestinationFeeManagerProcessFeeTest:test_processFeeWithWithZeroQuotePayload() (gas: 30056) -DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() (gas: 35320) -DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() (gas: 158081) -DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkReturnsChange() (gas: 56059) -DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() (gas: 121473) -DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() (gas: 38024) -DestinationFeeManagerProcessFeeTest:test_processMultipleLinkReports() (gas: 230434) -DestinationFeeManagerProcessFeeTest:test_processMultipleUnwrappedNativeReports() (gas: 264223) -DestinationFeeManagerProcessFeeTest:test_processMultipleV1Reports() (gas: 81155) -DestinationFeeManagerProcessFeeTest:test_processMultipleWrappedNativeReports() (gas: 247072) -DestinationFeeManagerProcessFeeTest:test_processPoolIdsPassedMismatched() (gas: 98793) -DestinationFeeManagerProcessFeeTest:test_processV1V2V3Reports() (gas: 215445) -DestinationFeeManagerProcessFeeTest:test_processV1V2V3ReportsWithUnwrapped() (gas: 257087) +DestinationFeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52717) +DestinationFeeManagerProcessFeeTest:test_DiscountIsReturnedForNative() (gas: 52645) +DestinationFeeManagerProcessFeeTest:test_DiscountIsReturnedForNativeWithSurcharge() (gas: 78879) +DestinationFeeManagerProcessFeeTest:test_GlobalDiscountCantBeSetToMoreThanMaximum() (gas: 19544) +DestinationFeeManagerProcessFeeTest:test_GlobalDiscountIsOverridenByIndividualDiscountLink() (gas: 79509) +DestinationFeeManagerProcessFeeTest:test_GlobalDiscountIsOverridenByIndividualDiscountNative() (gas: 82523) +DestinationFeeManagerProcessFeeTest:test_GlobalDiscountIsUpdatedAfterBeingSetToZeroLink() (gas: 48409) +DestinationFeeManagerProcessFeeTest:test_GlobalDiscountIsUpdatedAfterBeingSetToZeroNative() (gas: 51589) +DestinationFeeManagerProcessFeeTest:test_GlobalDiscountWithLink() (gas: 51902) +DestinationFeeManagerProcessFeeTest:test_GlobalDiscountWithNative() (gas: 54892) +DestinationFeeManagerProcessFeeTest:test_GlobalDiscountWithNativeAndLink() (gas: 83739) +DestinationFeeManagerProcessFeeTest:test_V1PayloadVerifies() (gas: 29280) +DestinationFeeManagerProcessFeeTest:test_V1PayloadVerifiesAndReturnsChange() (gas: 61209) +DestinationFeeManagerProcessFeeTest:test_V2PayloadVerifies() (gas: 123469) +DestinationFeeManagerProcessFeeTest:test_V2PayloadWithoutQuoteFails() (gas: 29691) +DestinationFeeManagerProcessFeeTest:test_V2PayloadWithoutZeroFee() (gas: 77080) +DestinationFeeManagerProcessFeeTest:test_WithdrawERC20() (gas: 72819) +DestinationFeeManagerProcessFeeTest:test_WithdrawNonAdminAddr() (gas: 56357) +DestinationFeeManagerProcessFeeTest:test_WithdrawUnwrappedNative() (gas: 26434) +DestinationFeeManagerProcessFeeTest:test_addVerifier() (gas: 128899) +DestinationFeeManagerProcessFeeTest:test_addVerifierExistingAddress() (gas: 34192) +DestinationFeeManagerProcessFeeTest:test_baseFeeIsAppliedForLink() (gas: 19497) +DestinationFeeManagerProcessFeeTest:test_baseFeeIsAppliedForNative() (gas: 22502) +DestinationFeeManagerProcessFeeTest:test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() (gas: 91133) +DestinationFeeManagerProcessFeeTest:test_discountAIsNotAppliedWhenSetForOtherUsers() (gas: 58864) +DestinationFeeManagerProcessFeeTest:test_discountFeeRoundsDownWhenUneven() (gas: 52919) +DestinationFeeManagerProcessFeeTest:test_discountIsAppliedForLink() (gas: 49730) +DestinationFeeManagerProcessFeeTest:test_discountIsAppliedWith100PercentSurcharge() (gas: 78908) +DestinationFeeManagerProcessFeeTest:test_discountIsNoLongerAppliedAfterRemoving() (gas: 48362) +DestinationFeeManagerProcessFeeTest:test_discountIsNotAppliedForInvalidTokenAddress() (gas: 17516) +DestinationFeeManagerProcessFeeTest:test_discountIsNotAppliedToOtherFeeds() (gas: 56912) +DestinationFeeManagerProcessFeeTest:test_discountIsReturnedForLink() (gas: 49657) +DestinationFeeManagerProcessFeeTest:test_emptyQuoteRevertsWithError() (gas: 12253) +DestinationFeeManagerProcessFeeTest:test_eventIsEmittedAfterSurchargeIsSet() (gas: 41379) +DestinationFeeManagerProcessFeeTest:test_eventIsEmittedIfNotEnoughLink() (gas: 182671) +DestinationFeeManagerProcessFeeTest:test_eventIsEmittedUponWithdraw() (gas: 69080) +DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterDiscountIsRemoved() (gas: 51626) +DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewDiscountIsApplied() (gas: 67777) +DestinationFeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewSurchargeIsApplied() (gas: 66960) +DestinationFeeManagerProcessFeeTest:test_feeIsZeroWith100PercentDiscount() (gas: 52073) +DestinationFeeManagerProcessFeeTest:test_getBaseRewardWithLinkQuote() (gas: 19495) +DestinationFeeManagerProcessFeeTest:test_getLinkFeeIsRoundedUp() (gas: 49857) +DestinationFeeManagerProcessFeeTest:test_getLinkRewardIsSameAsFee() (gas: 55762) +DestinationFeeManagerProcessFeeTest:test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() (gas: 85050) +DestinationFeeManagerProcessFeeTest:test_getRewardWithLinkDiscount() (gas: 49726) +DestinationFeeManagerProcessFeeTest:test_getRewardWithLinkQuoteAndLinkDiscount() (gas: 49685) +DestinationFeeManagerProcessFeeTest:test_getRewardWithNativeQuote() (gas: 22456) +DestinationFeeManagerProcessFeeTest:test_getRewardWithNativeQuoteAndSurcharge() (gas: 53190) +DestinationFeeManagerProcessFeeTest:test_linkAvailableForPaymentReturnsLinkBalance() (gas: 53194) +DestinationFeeManagerProcessFeeTest:test_nativeSurcharge0Percent() (gas: 33198) +DestinationFeeManagerProcessFeeTest:test_nativeSurcharge100Percent() (gas: 53170) +DestinationFeeManagerProcessFeeTest:test_nativeSurchargeCannotExceed100Percent() (gas: 17152) +DestinationFeeManagerProcessFeeTest:test_nativeSurchargeEventIsEmittedOnUpdate() (gas: 41357) +DestinationFeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFee() (gas: 51918) +DestinationFeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() (gas: 78108) +DestinationFeeManagerProcessFeeTest:test_nonAdminProxyUserCannotProcessFee() (gas: 24141) +DestinationFeeManagerProcessFeeTest:test_nonAdminUserCanNotSetDiscount() (gas: 19784) +DestinationFeeManagerProcessFeeTest:test_onlyCallableByOwnerReverts() (gas: 15475) +DestinationFeeManagerProcessFeeTest:test_onlyOwnerCanSetGlobalDiscount() (gas: 19929) +DestinationFeeManagerProcessFeeTest:test_payLinkDeficit() (gas: 199884) +DestinationFeeManagerProcessFeeTest:test_payLinkDeficitOnlyCallableByAdmin() (gas: 17348) +DestinationFeeManagerProcessFeeTest:test_payLinkDeficitPaysAllFeesProcessed() (gas: 221262) +DestinationFeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 204204) +DestinationFeeManagerProcessFeeTest:test_poolIdsCannotBeZeroAddress() (gas: 117907) +DestinationFeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 123807) +DestinationFeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 29767) +DestinationFeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 167721) +DestinationFeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 30107) +DestinationFeeManagerProcessFeeTest:test_processFeeNative() (gas: 180514) +DestinationFeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 125076) +DestinationFeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 31844) +DestinationFeeManagerProcessFeeTest:test_processFeeWithDiscountEmitsEvent() (gas: 245978) +DestinationFeeManagerProcessFeeTest:test_processFeeWithInvalidReportVersionFailsToDecode() (gas: 30814) +DestinationFeeManagerProcessFeeTest:test_processFeeWithNoDiscountDoesNotEmitEvent() (gas: 173419) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNative() (gas: 188379) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddress() (gas: 138180) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() (gas: 163791) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeShortFunds() (gas: 97147) +DestinationFeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeWithExcessiveFee() (gas: 195364) +DestinationFeeManagerProcessFeeTest:test_processFeeWithWithCorruptQuotePayload() (gas: 77390) +DestinationFeeManagerProcessFeeTest:test_processFeeWithWithEmptyQuotePayload() (gas: 30028) +DestinationFeeManagerProcessFeeTest:test_processFeeWithWithZeroQuotePayload() (gas: 30078) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() (gas: 37626) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() (gas: 160391) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkReturnsChange() (gas: 58387) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() (gas: 123718) +DestinationFeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() (gas: 40330) +DestinationFeeManagerProcessFeeTest:test_processMultipleLinkReports() (gas: 233880) +DestinationFeeManagerProcessFeeTest:test_processMultipleUnwrappedNativeReports() (gas: 267669) +DestinationFeeManagerProcessFeeTest:test_processMultipleV1Reports() (gas: 81177) +DestinationFeeManagerProcessFeeTest:test_processMultipleWrappedNativeReports() (gas: 250518) +DestinationFeeManagerProcessFeeTest:test_processPoolIdsPassedMismatched() (gas: 98815) +DestinationFeeManagerProcessFeeTest:test_processV1V2V3Reports() (gas: 218585) +DestinationFeeManagerProcessFeeTest:test_processV1V2V3ReportsWithUnwrapped() (gas: 260249) DestinationFeeManagerProcessFeeTest:test_removeVerifierNonExistentAddress() (gas: 12822) -DestinationFeeManagerProcessFeeTest:test_removeVerifierZeroAaddress() (gas: 10678) -DestinationFeeManagerProcessFeeTest:test_reportWithNoExpiryOrFeeReturnsZero() (gas: 13615) -DestinationFeeManagerProcessFeeTest:test_revertOnSettingAnAddressZeroVerifier() (gas: 10614) -DestinationFeeManagerProcessFeeTest:test_rewardsAreCorrectlySentToEachAssociatedPoolWhenVerifyingInBulk() (gas: 263181) -DestinationFeeManagerProcessFeeTest:test_setDiscountOver100Percent() (gas: 19562) +DestinationFeeManagerProcessFeeTest:test_removeVerifierZeroAaddress() (gas: 10700) +DestinationFeeManagerProcessFeeTest:test_reportWithNoExpiryOrFeeReturnsZero() (gas: 13682) +DestinationFeeManagerProcessFeeTest:test_revertOnSettingAnAddressZeroVerifier() (gas: 10636) +DestinationFeeManagerProcessFeeTest:test_rewardsAreCorrectlySentToEachAssociatedPoolWhenVerifyingInBulk() (gas: 266627) +DestinationFeeManagerProcessFeeTest:test_setDiscountOver100Percent() (gas: 19540) DestinationFeeManagerProcessFeeTest:test_setRewardManagerZeroAddress() (gas: 10626) -DestinationFeeManagerProcessFeeTest:test_subscriberDiscountEventIsEmittedOnUpdate() (gas: 46329) -DestinationFeeManagerProcessFeeTest:test_surchargeFeeRoundsUpWhenUneven() (gas: 51261) -DestinationFeeManagerProcessFeeTest:test_surchargeIsApplied() (gas: 51165) -DestinationFeeManagerProcessFeeTest:test_surchargeIsAppliedForNativeFeeWithDiscount() (gas: 79356) -DestinationFeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 47132) -DestinationFeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 49962) -DestinationFeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 78352) -DestinationFeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 14943) -DestinationRewardManagerClaimTest:test_claimAllRecipients() (gas: 277191) -DestinationRewardManagerClaimTest:test_claimMultipleRecipients() (gas: 154371) -DestinationRewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 330208) -DestinationRewardManagerClaimTest:test_claimSingleRecipient() (gas: 89039) -DestinationRewardManagerClaimTest:test_claimUnevenAmountRoundsDown() (gas: 315411) -DestinationRewardManagerClaimTest:test_claimUnregisteredPoolId() (gas: 35164) -DestinationRewardManagerClaimTest:test_claimUnregisteredRecipient() (gas: 41201) -DestinationRewardManagerClaimTest:test_eventIsEmittedUponClaim() (gas: 86084) -DestinationRewardManagerClaimTest:test_eventIsNotEmittedUponUnsuccessfulClaim() (gas: 25050) -DestinationRewardManagerClaimTest:test_recipientsClaimMultipleDeposits() (gas: 386857) -DestinationRewardManagerClaimTest:test_singleRecipientClaimMultipleDeposits() (gas: 137777) -DestinationRewardManagerNoRecipientSet:test_claimAllRecipientsAfterRecipientsSet() (gas: 492227) +DestinationFeeManagerProcessFeeTest:test_subscriberDiscountEventIsEmittedOnUpdate() (gas: 46285) +DestinationFeeManagerProcessFeeTest:test_surchargeFeeRoundsUpWhenUneven() (gas: 53501) +DestinationFeeManagerProcessFeeTest:test_surchargeIsApplied() (gas: 53426) +DestinationFeeManagerProcessFeeTest:test_surchargeIsAppliedForNativeFeeWithDiscount() (gas: 79315) +DestinationFeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 49149) +DestinationFeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 52223) +DestinationFeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 78311) +DestinationFeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 14987) +DestinationRewardManagerClaimTest:test_claimAllRecipients() (gas: 277223) +DestinationRewardManagerClaimTest:test_claimMultipleRecipients() (gas: 154387) +DestinationRewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 330244) +DestinationRewardManagerClaimTest:test_claimSingleRecipient() (gas: 89047) +DestinationRewardManagerClaimTest:test_claimUnevenAmountRoundsDown() (gas: 315447) +DestinationRewardManagerClaimTest:test_claimUnregisteredPoolId() (gas: 35168) +DestinationRewardManagerClaimTest:test_claimUnregisteredRecipient() (gas: 41205) +DestinationRewardManagerClaimTest:test_eventIsEmittedUponClaim() (gas: 86092) +DestinationRewardManagerClaimTest:test_eventIsNotEmittedUponUnsuccessfulClaim() (gas: 25054) +DestinationRewardManagerClaimTest:test_recipientsClaimMultipleDeposits() (gas: 386925) +DestinationRewardManagerClaimTest:test_singleRecipientClaimMultipleDeposits() (gas: 137797) +DestinationRewardManagerNoRecipientSet:test_claimAllRecipientsAfterRecipientsSet() (gas: 494460) DestinationRewardManagerPayRecipientsTest:test_addFundsToPoolAsNonOwnerOrFeeManager() (gas: 11503) -DestinationRewardManagerPayRecipientsTest:test_addFundsToPoolAsOwner() (gas: 53944) -DestinationRewardManagerPayRecipientsTest:test_payAllRecipients() (gas: 250829) -DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsFromNonAdminUser() (gas: 20496) -DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsFromRecipientInPool() (gas: 251075) -DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalInvalidRecipient() (gas: 262275) -DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalUnregisteredRecipient() (gas: 265760) -DestinationRewardManagerPayRecipientsTest:test_payRecipientWithInvalidPool() (gas: 28908) -DestinationRewardManagerPayRecipientsTest:test_payRecipientsEmptyRecipientList() (gas: 25333) -DestinationRewardManagerPayRecipientsTest:test_payRecipientsWithInvalidPoolId() (gas: 31402) -DestinationRewardManagerPayRecipientsTest:test_paySingleRecipient() (gas: 84709) -DestinationRewardManagerPayRecipientsTest:test_paySubsetOfRecipientsInPool() (gas: 198474) -DestinationRewardManagerRecipientClaimDifferentWeightsTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 280853) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsMultiplePools() (gas: 512489) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsSinglePool() (gas: 283649) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimEmptyPoolWhenSecondPoolContainsFunds() (gas: 293497) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsMultiplePools() (gas: 263075) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsSinglePool() (gas: 154537) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleRecipientMultiplePools() (gas: 132653) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleUniqueRecipient() (gas: 106056) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimUnevenAmountRoundsDown() (gas: 579776) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimUnregisteredRecipient() (gas: 64664) +DestinationRewardManagerPayRecipientsTest:test_addFundsToPoolAsOwner() (gas: 53947) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipients() (gas: 253082) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsFromNonAdminUser() (gas: 20472) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsFromRecipientInPool() (gas: 248964) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalInvalidRecipient() (gas: 264532) +DestinationRewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalUnregisteredRecipient() (gas: 268017) +DestinationRewardManagerPayRecipientsTest:test_payRecipientWithInvalidPool() (gas: 31133) +DestinationRewardManagerPayRecipientsTest:test_payRecipientsEmptyRecipientList() (gas: 27554) +DestinationRewardManagerPayRecipientsTest:test_payRecipientsWithInvalidPoolId() (gas: 33639) +DestinationRewardManagerPayRecipientsTest:test_paySingleRecipient() (gas: 86938) +DestinationRewardManagerPayRecipientsTest:test_paySubsetOfRecipientsInPool() (gas: 200719) +DestinationRewardManagerRecipientClaimDifferentWeightsTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 280885) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsMultiplePools() (gas: 512553) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsSinglePool() (gas: 283681) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimEmptyPoolWhenSecondPoolContainsFunds() (gas: 293533) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsMultiplePools() (gas: 263107) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsSinglePool() (gas: 154553) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleRecipientMultiplePools() (gas: 132669) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleUniqueRecipient() (gas: 106068) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimUnevenAmountRoundsDown() (gas: 579848) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_claimUnregisteredRecipient() (gas: 64672) DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorAndTotalPoolsEqual() (gas: 13074) DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorCannotBeGreaterThanTotalPools() (gas: 12703) DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorSingleResult() (gas: 22471) DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPools() (gas: 32248) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() (gas: 148629) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() (gas: 148645) DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInNoPools() (gas: 21728) DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInSinglePool() (gas: 27765) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_recipientsClaimMultipleDeposits() (gas: 391427) -DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_singleRecipientClaimMultipleDeposits() (gas: 137862) -DestinationRewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 199546) -DestinationRewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() (gas: 219419) -DestinationRewardManagerSetRecipientsTest:test_eventIsEmittedUponSetRecipients() (gas: 191707) -DestinationRewardManagerSetRecipientsTest:test_setRecipientContainsDuplicateRecipients() (gas: 126060) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientFromManagerAddress() (gas: 214117) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_recipientsClaimMultipleDeposits() (gas: 391495) +DestinationRewardManagerRecipientClaimMultiplePoolsTest:test_singleRecipientClaimMultipleDeposits() (gas: 137882) +DestinationRewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 199566) +DestinationRewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() (gas: 219439) +DestinationRewardManagerSetRecipientsTest:test_eventIsEmittedUponSetRecipients() (gas: 193892) +DestinationRewardManagerSetRecipientsTest:test_setRecipientContainsDuplicateRecipients() (gas: 128245) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientFromManagerAddress() (gas: 213998) DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() (gas: 21496) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientTwice() (gas: 193280) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWeights() (gas: 180608) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroAddress() (gas: 90202) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroWeight() (gas: 191312) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipients() (gas: 185567) -DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientsIsEmpty() (gas: 87091) -DestinationRewardManagerSetRecipientsTest:test_setSingleRewardRecipient() (gas: 110349) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientTwice() (gas: 195650) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWeights() (gas: 182793) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroAddress() (gas: 92387) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroWeight() (gas: 193497) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipients() (gas: 187752) +DestinationRewardManagerSetRecipientsTest:test_setRewardRecipientsIsEmpty() (gas: 89276) +DestinationRewardManagerSetRecipientsTest:test_setSingleRewardRecipient() (gas: 112534) DestinationRewardManagerSetupTest:test_addFeeManagerExistingAddress() (gas: 35281) DestinationRewardManagerSetupTest:test_addFeeManagerZeroAddress() (gas: 10580) DestinationRewardManagerSetupTest:test_addRemoveFeeManager() (gas: 48248) DestinationRewardManagerSetupTest:test_eventEmittedUponFeeManagerUpdate() (gas: 41581) -DestinationRewardManagerSetupTest:test_eventEmittedUponFeePaid() (gas: 259172) -DestinationRewardManagerSetupTest:test_rejectsZeroLinkAddressOnConstruction() (gas: 59610) +DestinationRewardManagerSetupTest:test_eventEmittedUponFeePaid() (gas: 261361) +DestinationRewardManagerSetupTest:test_rejectsZeroLinkAddressOnConstruction() (gas: 59481) DestinationRewardManagerSetupTest:test_removeFeeManagerNonExistentAddress() (gas: 12778) DestinationRewardManagerSetupTest:test_setFeeManagerZeroAddress() (gas: 17084) -DestinationRewardManagerUpdateRewardRecipientsMultiplePoolsTest:test_updatePrimaryRecipientWeights() (gas: 376674) -DestinationRewardManagerUpdateRewardRecipientsTest:test_eventIsEmittedUponUpdateRecipients() (gas: 280411) +DestinationRewardManagerUpdateRewardRecipientsMultiplePoolsTest:test_updatePrimaryRecipientWeights() (gas: 376742) +DestinationRewardManagerUpdateRewardRecipientsTest:test_eventIsEmittedUponUpdateRecipients() (gas: 280443) DestinationRewardManagerUpdateRewardRecipientsTest:test_onlyAdminCanUpdateRecipients() (gas: 19705) -DestinationRewardManagerUpdateRewardRecipientsTest:test_partialUpdateRecipientWeights() (gas: 221004) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateAllRecipientsWithSameAddressAndWeight() (gas: 274233) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsToSubset() (gas: 254156) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithExcessiveWeight() (gas: 259143) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithSameAddressAndWeight() (gas: 149856) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithUnderWeightSet() (gas: 259217) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientWeights() (gas: 372155) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientWithNewZeroAddress() (gas: 270700) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsContainsDuplicateRecipients() (gas: 288483) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentLargerSet() (gas: 407780) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentPartialSet() (gas: 317945) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSet() (gas: 377692) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSetWithInvalidWeights() (gas: 312038) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForLargerSet() (gas: 399603) -DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() (gas: 289433) -DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 639153) -DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNative() (gas: 640232) -DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrapped() (gas: 661796) -DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrappedReturnsChange() (gas: 661751) -DestinationVerifierConstructorTest:test_falseIfIsNotCorrectInterface() (gas: 8719) -DestinationVerifierConstructorTest:test_revertsIfInitializedWithEmptyVerifierProxy() (gas: 61121) -DestinationVerifierConstructorTest:test_trueIfIsCorrectInterface() (gas: 8604) -DestinationVerifierConstructorTest:test_typeAndVersion() (gas: 2818189) -DestinationVerifierProxyInitializeVerifierTest:test_correctlySetsTheOwner() (gas: 1035181) +DestinationRewardManagerUpdateRewardRecipientsTest:test_partialUpdateRecipientWeights() (gas: 221040) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateAllRecipientsWithSameAddressAndWeight() (gas: 274265) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsToSubset() (gas: 254188) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithExcessiveWeight() (gas: 259175) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithSameAddressAndWeight() (gas: 149872) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithUnderWeightSet() (gas: 259249) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientWeights() (gas: 372223) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientWithNewZeroAddress() (gas: 270736) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsContainsDuplicateRecipients() (gas: 288531) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentLargerSet() (gas: 407832) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentPartialSet() (gas: 317985) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSet() (gas: 377740) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSetWithInvalidWeights() (gas: 312078) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForLargerSet() (gas: 399655) +DestinationRewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() (gas: 289469) +DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 642599) +DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNative() (gas: 643674) +DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrapped() (gas: 665238) +DestinationVerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrappedReturnsChange() (gas: 665193) +DestinationVerifierConstructorTest:test_falseIfIsNotCorrectInterface() (gas: 8481) +DestinationVerifierConstructorTest:test_revertsIfInitializedWithEmptyVerifierProxy() (gas: 60885) +DestinationVerifierConstructorTest:test_trueIfIsCorrectInterface() (gas: 9383) +DestinationVerifierConstructorTest:test_typeAndVersion() (gas: 2624729) +DestinationVerifierProxyInitializeVerifierTest:test_correctlySetsTheOwner() (gas: 862226) DestinationVerifierProxyInitializeVerifierTest:test_correctlySetsVersion() (gas: 9841) DestinationVerifierProxyInitializeVerifierTest:test_setVerifierCalledByNoOwner() (gas: 17483) -DestinationVerifierProxyInitializeVerifierTest:test_setVerifierOk() (gas: 30622) -DestinationVerifierProxyInitializeVerifierTest:test_setVerifierWhichDoesntHonourInterface() (gas: 16851) +DestinationVerifierProxyInitializeVerifierTest:test_setVerifierOk() (gas: 27727) +DestinationVerifierProxyInitializeVerifierTest:test_setVerifierWhichDoesntHonourInterface() (gas: 16535) DestinationVerifierSetAccessControllerTest:test_emitsTheCorrectEvent() (gas: 35391) DestinationVerifierSetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 15089) DestinationVerifierSetAccessControllerTest:test_successfullySetsNewAccessController() (gas: 34885) DestinationVerifierSetAccessControllerTest:test_successfullySetsNewAccessControllerIsEmpty() (gas: 15007) -DestinationVerifierSetConfigTest:test_NoDonConfigAlreadyExists() (gas: 2874492) -DestinationVerifierSetConfigTest:test_addressesAndWeightsDoNotProduceSideEffectsInDonConfigIds() (gas: 1323177) -DestinationVerifierSetConfigTest:test_donConfigIdIsSameForSignersInDifferentOrder() (gas: 1290374) -DestinationVerifierSetConfigTest:test_removeLatestConfig() (gas: 786275) +DestinationVerifierSetConfigTest:test_NoDonConfigAlreadyExists() (gas: 2877761) +DestinationVerifierSetConfigTest:test_addressesAndWeightsDoNotProduceSideEffectsInDonConfigIds() (gas: 1323254) +DestinationVerifierSetConfigTest:test_donConfigIdIsSameForSignersInDifferentOrder() (gas: 1290451) +DestinationVerifierSetConfigTest:test_removeLatestConfig() (gas: 786161) DestinationVerifierSetConfigTest:test_removeLatestConfigWhenNoConfigShouldFail() (gas: 12870) DestinationVerifierSetConfigTest:test_revertsIfCalledByNonOwner() (gas: 174936) -DestinationVerifierSetConfigTest:test_revertsIfDuplicateSigners() (gas: 171604) -DestinationVerifierSetConfigTest:test_revertsIfFaultToleranceIsZero() (gas: 168484) +DestinationVerifierSetConfigTest:test_revertsIfDuplicateSigners() (gas: 171299) +DestinationVerifierSetConfigTest:test_revertsIfFaultToleranceIsZero() (gas: 168506) DestinationVerifierSetConfigTest:test_revertsIfNotEnoughSigners() (gas: 11571) DestinationVerifierSetConfigTest:test_revertsIfSetWithTooManySigners() (gas: 17943) -DestinationVerifierSetConfigTest:test_revertsIfSignerContainsZeroAddress() (gas: 324333) -DestinationVerifierSetConfigTest:test_setConfigActiveUnknownDonConfigId() (gas: 13102) -DestinationVerifierSetConfigTest:test_setConfigWithActivationTime() (gas: 1088176) -DestinationVerifierSetConfigTest:test_setConfigWithActivationTimeEarlierThanLatestConfigShouldFail() (gas: 1963414) -DestinationVerifierSetConfigTest:test_setConfigWithActivationTimeNoFutureTimeShouldFail() (gas: 259797) +DestinationVerifierSetConfigTest:test_revertsIfSignerContainsZeroAddress() (gas: 324006) +DestinationVerifierSetConfigTest:test_setConfigActiveUnknownDonConfigId() (gas: 13124) +DestinationVerifierSetConfigTest:test_setConfigWithActivationTime() (gas: 1088159) +DestinationVerifierSetConfigTest:test_setConfigWithActivationTimeEarlierThanLatestConfigShouldFail() (gas: 1963073) +DestinationVerifierSetConfigTest:test_setConfigWithActivationTimeNoFutureTimeShouldFail() (gas: 259470) +DestinationVerifierSetConfigTest:test_setConfigWithActivationTimeTheSameAsLatestConfigShouldFail() (gas: 1283783) FeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52645) FeeManagerProcessFeeTest:test_DiscountIsReturnedForNative() (gas: 52595) FeeManagerProcessFeeTest:test_DiscountIsReturnedForNativeWithSurcharge() (gas: 78808) @@ -289,7 +299,7 @@ FeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 198803) FeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 117088) FeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 27462) FeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 163205) -FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 30327) +FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 27827) FeeManagerProcessFeeTest:test_processFeeNative() (gas: 173826) FeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 118379) FeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 29536) @@ -325,7 +335,7 @@ FeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 47 FeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 49938) FeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 78261) FeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 14919) -MultiVerifierBillingTests:test_multipleFeeManagersAndVerifiers() (gas: 4586990) +MultiVerifierBillingTests:test_multipleFeeManagersAndVerifiers() (gas: 4598487) RewardManagerClaimTest:test_claimAllRecipients() (gas: 277131) RewardManagerClaimTest:test_claimMultipleRecipients() (gas: 154341) RewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 330086) @@ -418,13 +428,13 @@ VerifierActivateFeedTest:test_revertsIfNoFeedExistsActivate() (gas: 13179) VerifierActivateFeedTest:test_revertsIfNoFeedExistsDeactivate() (gas: 13157) VerifierActivateFeedTest:test_revertsIfNotOwnerActivateFeed() (gas: 17109) VerifierActivateFeedTest:test_revertsIfNotOwnerDeactivateFeed() (gas: 17164) -VerifierBillingTests:test_rewardsAreDistributedAccordingToWeights() (gas: 1731717) -VerifierBillingTests:test_rewardsAreDistributedAccordingToWeightsMultipleWeigths() (gas: 4460715) -VerifierBillingTests:test_rewardsAreDistributedAccordingToWeightsUsingHistoricalConfigs() (gas: 2098833) -VerifierBillingTests:test_verifyWithLinkV3Report() (gas: 1591346) -VerifierBillingTests:test_verifyWithNativeERC20() (gas: 1467256) -VerifierBillingTests:test_verifyWithNativeUnwrapped() (gas: 1376447) -VerifierBillingTests:test_verifyWithNativeUnwrappedReturnsChange() (gas: 1383493) +VerifierBillingTests:test_rewardsAreDistributedAccordingToWeights() (gas: 1736216) +VerifierBillingTests:test_rewardsAreDistributedAccordingToWeightsMultipleWeigths() (gas: 4468029) +VerifierBillingTests:test_rewardsAreDistributedAccordingToWeightsUsingHistoricalConfigs() (gas: 2106504) +VerifierBillingTests:test_verifyWithLinkV3Report() (gas: 1593617) +VerifierBillingTests:test_verifyWithNativeERC20() (gas: 1467526) +VerifierBillingTests:test_verifyWithNativeUnwrapped() (gas: 1378718) +VerifierBillingTests:test_verifyWithNativeUnwrappedReturnsChange() (gas: 1385764) VerifierBulkVerifyBillingReport:test_verifyMultiVersions() (gas: 476595) VerifierBulkVerifyBillingReport:test_verifyMultiVersionsReturnsVerifiedReports() (gas: 474853) VerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 557541) @@ -437,7 +447,7 @@ VerifierDeactivateFeedWithVerifyTest:test_currentReportAllowsVerification() (gas VerifierDeactivateFeedWithVerifyTest:test_currentReportFailsVerification() (gas: 113388) VerifierDeactivateFeedWithVerifyTest:test_previousReportAllowsVerification() (gas: 99624) VerifierDeactivateFeedWithVerifyTest:test_previousReportFailsVerification() (gas: 69943) -VerifierInterfacesTest:test_DestinationContractInterfaces() (gas: 623467) +VerifierInterfacesTest:test_DestinationContractInterfaces() (gas: 628127) VerifierProxyAccessControlledVerificationTest:test_proxiesToTheVerifierIfHasAccess() (gas: 208529) VerifierProxyAccessControlledVerificationTest:test_revertsIfNoAccess() (gas: 112345) VerifierProxyConstructorTest:test_correctlySetsTheCorrectAccessControllerInterface() (gas: 1485359) @@ -463,8 +473,8 @@ VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_emitsAnEventAfterUn VerifierProxyVerifyTest:test_proxiesToTheCorrectVerifier() (gas: 204342) VerifierProxyVerifyTest:test_revertsIfNoVerifierConfigured() (gas: 117264) VerifierSetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 17196) -VerifierSetAccessControllerTest:test_setFeeManagerWhichDoesntHonourInterface() (gas: 16571) -VerifierSetAccessControllerTest:test_successfullySetsNewFeeManager() (gas: 44855) +VerifierSetAccessControllerTest:test_setFeeManagerWhichDoesntHonourInterface() (gas: 16272) +VerifierSetAccessControllerTest:test_successfullySetsNewFeeManager() (gas: 42226) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 542302) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 967768) VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 523251) @@ -486,8 +496,8 @@ VerifierTestBillingReport:test_verifyWithNative() (gas: 316326) VerifierTestBillingReport:test_verifyWithNativeUnwrapped() (gas: 318574) VerifierTestBillingReport:test_verifyWithNativeUnwrappedReturnsChange() (gas: 325642) VerifierVerifyBulkTest:test_revertsVerifyBulkIfNoAccess() (gas: 112867) -VerifierVerifyBulkTest:test_verifyBulkSingleCaseWithSingleConfig() (gas: 745046) -VerifierVerifyBulkTest:test_verifyBulkWithSingleConfigOneVerifyFails() (gas: 698203) +VerifierVerifyBulkTest:test_verifyBulkSingleCaseWithSingleConfig() (gas: 745006) +VerifierVerifyBulkTest:test_verifyBulkWithSingleConfigOneVerifyFails() (gas: 698163) VerifierVerifyMultipleConfigDigestTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 133961) VerifierVerifyMultipleConfigDigestTest:test_canVerifyOlderReportsWithOlderConfigs() (gas: 189865) VerifierVerifyMultipleConfigDigestTest:test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() (gas: 88216) @@ -502,18 +512,18 @@ VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedByNonProxy() (gas: 10 VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedWithIncorrectAddresses() (gas: 184077) VerifierVerifySingleConfigDigestTest:test_revertsIfWrongNumberOfSigners() (gas: 110042) VerifierVerifySingleConfigDigestTest:test_setsTheCorrectEpoch() (gas: 194592) -VerifierVerifyTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 861741) -VerifierVerifyTest:test_canVerifyOlderV3ReportsWithOlderConfigs() (gas: 815984) -VerifierVerifyTest:test_failToVerifyReportIfDupSigners() (gas: 450715) -VerifierVerifyTest:test_failToVerifyReportIfNoSigners() (gas: 426492) -VerifierVerifyTest:test_failToVerifyReportIfNotEnoughSigners() (gas: 434814) -VerifierVerifyTest:test_failToVerifyReportIfSignerNotInConfig() (gas: 456866) +VerifierVerifyTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 862947) +VerifierVerifyTest:test_canVerifyOlderV3ReportsWithOlderConfigs() (gas: 815907) +VerifierVerifyTest:test_failToVerifyReportIfDupSigners() (gas: 450675) +VerifierVerifyTest:test_failToVerifyReportIfNoSigners() (gas: 426452) +VerifierVerifyTest:test_failToVerifyReportIfNotEnoughSigners() (gas: 434774) +VerifierVerifyTest:test_failToVerifyReportIfSignerNotInConfig() (gas: 456826) VerifierVerifyTest:test_revertsVerifyIfNoAccess() (gas: 109465) -VerifierVerifyTest:test_rollingOutConfiguration() (gas: 1497254) -VerifierVerifyTest:test_scenarioRollingNewChainWithHistoricConfigs() (gas: 976162) -VerifierVerifyTest:test_verifyFailsWhenReportIsOlderThanConfig() (gas: 2303366) -VerifierVerifyTest:test_verifyReport() (gas: 1434811) -VerifierVerifyTest:test_verifyTooglingActiveFlagsDonConfigs() (gas: 1918797) +VerifierVerifyTest:test_rollingOutConfiguration() (gas: 1497140) +VerifierVerifyTest:test_scenarioRollingNewChainWithHistoricConfigs() (gas: 976048) +VerifierVerifyTest:test_verifyFailsWhenReportIsOlderThanConfig() (gas: 2303291) +VerifierVerifyTest:test_verifyReport() (gas: 1434772) +VerifierVerifyTest:test_verifyTooglingActiveFlagsDonConfigs() (gas: 1918758) Verifier_accessControlledVerify:testVerifyWithAccessControl_gas() (gas: 212077) Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithLinkFeeSuccess_gas() (gas: 519389) Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithNativeFeeSuccess_gas() (gas: 542808) diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol index 38d93de5cb..08ac1d45f5 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol @@ -11,6 +11,7 @@ import {Math} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/ma import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; import {IDestinationRewardManager} from "./interfaces/IDestinationRewardManager.sol"; import {IDestinationFeeManager} from "./interfaces/IDestinationFeeManager.sol"; +import {IDestinationVerifierFeeManager} from "./interfaces/IDestinationVerifierFeeManager.sol"; /** * @title FeeManager @@ -18,12 +19,20 @@ import {IDestinationFeeManager} from "./interfaces/IDestinationFeeManager.sol"; * @author Austin Born * @notice This contract is used for the handling of fees required for users verifying reports. */ -contract DestinationFeeManager is IDestinationFeeManager, ConfirmedOwner, TypeAndVersionInterface { +contract DestinationFeeManager is + IDestinationFeeManager, + IDestinationVerifierFeeManager, + ConfirmedOwner, + TypeAndVersionInterface +{ using SafeERC20 for IERC20; /// @notice list of subscribers and their discounts subscriberDiscounts[subscriber][feedId][token] mapping(address => mapping(bytes32 => mapping(address => uint256))) public s_subscriberDiscounts; + /// @notice map of global discounts + mapping(address => mapping(address => uint256)) public s_globalDiscounts; + /// @notice keep track of any subsidised link that is owed to the reward manager. mapping(bytes32 => uint256) public s_linkDeficit; @@ -150,11 +159,6 @@ contract DestinationFeeManager is IDestinationFeeManager, ConfirmedOwner, TypeAn IERC20(i_linkAddress).approve(address(i_rewardManager), type(uint256).max); } - modifier onlyOwnerOrVerifier() { - if (msg.sender != s_verifierAddressList[msg.sender] && msg.sender != owner()) revert Unauthorized(); - _; - } - modifier onlyVerifier() { if (msg.sender != s_verifierAddressList[msg.sender]) revert Unauthorized(); _; @@ -162,26 +166,17 @@ contract DestinationFeeManager is IDestinationFeeManager, ConfirmedOwner, TypeAn /// @inheritdoc TypeAndVersionInterface function typeAndVersion() external pure override returns (string memory) { - return "DestinationFeeManager 1.0.0"; + return "DestinationFeeManager 0.4.0"; } /// @inheritdoc IERC165 function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { - //for each function in IDestinationFeeManager we need to check if it matches the selector return - interfaceId == this.getFeeAndReward.selector || - interfaceId == this.setNativeSurcharge.selector || - interfaceId == this.updateSubscriberDiscount.selector || - interfaceId == this.withdraw.selector || - interfaceId == this.linkAvailableForPayment.selector || - interfaceId == this.payLinkDeficit.selector || - interfaceId == this.addVerifier.selector || - interfaceId == this.removeVerifier.selector || - interfaceId == this.processFee.selector || - interfaceId == this.processFeeBulk.selector || - interfaceId == this.setFeeRecipients.selector; + interfaceId == type(IDestinationFeeManager).interfaceId || + interfaceId == type(IDestinationVerifierFeeManager).interfaceId; } + /// @inheritdoc IDestinationVerifierFeeManager function processFee( bytes32 recipient, bytes calldata payload, @@ -209,7 +204,7 @@ contract DestinationFeeManager is IDestinationFeeManager, ConfirmedOwner, TypeAn } } - /// @inheritdoc IDestinationFeeManager + /// @inheritdoc IDestinationVerifierFeeManager function processFeeBulk( bytes32[] memory poolIds, bytes[] calldata payloads, @@ -304,9 +299,14 @@ contract DestinationFeeManager is IDestinationFeeManager, ConfirmedOwner, TypeAn revert ExpiredReport(); } - //get the discount being applied + //check if feed discount has been applied uint256 discount = s_subscriberDiscounts[subscriber][feedId][quoteAddress]; + if (discount == 0) { + //check if a global discount has been applied + discount = s_globalDiscounts[subscriber][quoteAddress]; + } + //the reward is always set in LINK reward.assetAddress = i_linkAddress; reward.amount = Math.ceilDiv(linkQuantity * (PERCENTAGE_SCALAR - discount), PERCENTAGE_SCALAR); @@ -326,11 +326,11 @@ contract DestinationFeeManager is IDestinationFeeManager, ConfirmedOwner, TypeAn return (fee, reward, discount); } - /// @inheritdoc IDestinationFeeManager + /// @inheritdoc IDestinationVerifierFeeManager function setFeeRecipients( bytes32 configDigest, Common.AddressAndWeight[] calldata rewardRecipientAndWeights - ) external onlyOwnerOrVerifier { + ) external onlyVerifier { i_rewardManager.setRewardRecipients(configDigest, rewardRecipientAndWeights); } @@ -360,6 +360,17 @@ contract DestinationFeeManager is IDestinationFeeManager, ConfirmedOwner, TypeAn emit SubscriberDiscountUpdated(subscriber, feedId, token, discount); } + function updateSubscriberGlobalDiscount(address subscriber, address token, uint64 discount) external onlyOwner { + //make sure the discount is not greater than the total discount that can be applied + if (discount > PERCENTAGE_SCALAR) revert InvalidDiscount(); + //make sure the token is either LINK or native + if (token != i_linkAddress && token != i_nativeAddress) revert InvalidAddress(); + + s_globalDiscounts[subscriber][token] = discount; + + emit SubscriberDiscountUpdated(subscriber, bytes32(0), token, discount); + } + /// @inheritdoc IDestinationFeeManager function withdraw(address assetAddress, address recipient, uint192 quantity) external onlyOwner { //address 0 is used to withdraw native in the context of withdrawing @@ -550,8 +561,13 @@ contract DestinationFeeManager is IDestinationFeeManager, ConfirmedOwner, TypeAn /// @inheritdoc IDestinationFeeManager function setRewardManager(address rewardManagerAddress) external onlyOwner { if (rewardManagerAddress == address(0)) revert InvalidAddress(); + + if (!IERC165(rewardManagerAddress).supportsInterface(type(IDestinationRewardManager).interfaceId)) { + revert InvalidAddress(); + } + IERC20(i_linkAddress).approve(address(i_rewardManager), 0); i_rewardManager = IDestinationRewardManager(rewardManagerAddress); - IERC20(i_linkAddress).approve(address(i_rewardManager), type(uint256).max); + IERC20(i_linkAddress).approve(address(rewardManagerAddress), type(uint256).max); } } diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationRewardManager.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationRewardManager.sol index ae40a2385c..4b4c1f50ef 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationRewardManager.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationRewardManager.sol @@ -75,29 +75,21 @@ contract DestinationRewardManager is IDestinationRewardManager, ConfirmedOwner, // @inheritdoc TypeAndVersionInterface function typeAndVersion() external pure override returns (string memory) { - return "RewardManager 1.0.0"; + return "DestinationRewardManager 0.4.0"; } // @inheritdoc IERC165 function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { - return - interfaceId == this.claimRewards.selector || - interfaceId == this.setRewardRecipients.selector || - interfaceId == this.updateRewardRecipients.selector || - interfaceId == this.payRecipients.selector || - interfaceId == this.addFeeManager.selector || - interfaceId == this.removeFeeManager.selector || - interfaceId == this.getAvailableRewardPoolIds.selector || - interfaceId == this.onFeePaid.selector; + return interfaceId == type(IDestinationRewardManager).interfaceId; } modifier onlyOwnerOrFeeManager() { - if (msg.sender != owner() && msg.sender != s_feeManagerAddressList[msg.sender]) revert Unauthorized(); + if (msg.sender != s_feeManagerAddressList[msg.sender] && msg.sender != owner()) revert Unauthorized(); _; } modifier onlyOwnerOrRecipientInPool(bytes32 poolId) { - if (msg.sender != owner() && s_rewardRecipientWeights[poolId][msg.sender] == 0) revert Unauthorized(); + if (s_rewardRecipientWeights[poolId][msg.sender] == 0 && msg.sender != owner()) revert Unauthorized(); _; } diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifier.sol index 52b2bd7c9a..8ab0f6acc2 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifier.sol @@ -8,7 +8,8 @@ import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/inter import {Common} from "../libraries/Common.sol"; import {IAccessController} from "../../shared/interfaces/IAccessController.sol"; import {IDestinationVerifierProxy} from "./interfaces/IDestinationVerifierProxy.sol"; -import {IDestinationFeeManager} from "./interfaces/IDestinationFeeManager.sol"; +import {IDestinationVerifierProxyVerifier} from "./interfaces/IDestinationVerifierProxyVerifier.sol"; +import {IDestinationVerifierFeeManager} from "./interfaces/IDestinationVerifierFeeManager.sol"; // OCR2 standard uint256 constant MAX_NUM_ORACLES = 31; @@ -18,7 +19,12 @@ uint256 constant MAX_NUM_ORACLES = 31; * @author Michael Fletcher * @notice This contract will be used to verify reports based on the oracle signatures. This is not the source verifier which required individual fee configurations, instead, this checks that a report has been signed by one of the configured oracles. */ -contract DestinationVerifier is IDestinationVerifier, ConfirmedOwner, TypeAndVersionInterface, IERC165 { +contract DestinationVerifier is + IDestinationVerifier, + IDestinationVerifierProxyVerifier, + ConfirmedOwner, + TypeAndVersionInterface +{ /// @notice The list of DON configurations by hash(address|donConfigId) - set to true if the signer is part of the config mapping(bytes32 => bool) private s_signerByAddressAndDonConfigId; @@ -84,9 +90,6 @@ contract DestinationVerifier is IDestinationVerifier, ConfirmedOwner, TypeAndVer /// @notice This error is thrown whenever a config does not exist error DonConfigDoesNotExist(); - /// @notice this error is thrown when the verifierProxy is incorrect when initialising - error VerifierProxyInvalid(); - /// @notice This error is thrown when the activation time is either in the future or less than the current configs error BadActivationTime(); @@ -105,7 +108,8 @@ contract DestinationVerifier is IDestinationVerifier, ConfirmedOwner, TypeAndVer bytes24 indexed donConfigId, address[] signers, uint8 f, - Common.AddressAndWeight[] recipientAddressesAndWeights + Common.AddressAndWeight[] recipientAddressesAndWeights, + uint16 donConfigIndex ); /// @notice This event is emitted when a new fee manager is set @@ -137,18 +141,25 @@ contract DestinationVerifier is IDestinationVerifier, ConfirmedOwner, TypeAndVer i_verifierProxy = IDestinationVerifierProxy(verifierProxy); } - /// @inheritdoc IDestinationVerifier + /// @inheritdoc IDestinationVerifierProxyVerifier function verify( bytes calldata signedReport, bytes calldata parameterPayload, address sender - ) external payable override checkValidProxy checkAccess(sender) returns (bytes memory) { + ) external payable override onlyProxy checkAccess(sender) returns (bytes memory) { (bytes memory verifierResponse, bytes32 donConfigId) = _verify(signedReport, sender); address fm = s_feeManager; if (fm != address(0)) { //process the fee and catch the error - try IDestinationFeeManager(fm).processFee{value: msg.value}(donConfigId, signedReport, parameterPayload, sender) { + try + IDestinationVerifierFeeManager(fm).processFee{value: msg.value}( + donConfigId, + signedReport, + parameterPayload, + sender + ) + { //do nothing } catch { // we purposefully obfuscate the error here to prevent information leaking leading to free verifications @@ -159,12 +170,12 @@ contract DestinationVerifier is IDestinationVerifier, ConfirmedOwner, TypeAndVer return verifierResponse; } - /// @inheritdoc IDestinationVerifier + /// @inheritdoc IDestinationVerifierProxyVerifier function verifyBulk( bytes[] calldata signedReports, bytes calldata parameterPayload, address sender - ) external payable override checkValidProxy checkAccess(sender) returns (bytes[] memory) { + ) external payable override onlyProxy checkAccess(sender) returns (bytes[] memory) { bytes[] memory verifierResponses = new bytes[](signedReports.length); bytes32[] memory donConfigs = new bytes32[](signedReports.length); @@ -178,7 +189,12 @@ contract DestinationVerifier is IDestinationVerifier, ConfirmedOwner, TypeAndVer if (fm != address(0)) { //process the fee and catch the error try - IDestinationFeeManager(fm).processFeeBulk{value: msg.value}(donConfigs, signedReports, parameterPayload, sender) + IDestinationVerifierFeeManager(fm).processFeeBulk{value: msg.value}( + donConfigs, + signedReports, + parameterPayload, + sender + ) { //do nothing } catch { @@ -276,7 +292,7 @@ contract DestinationVerifier is IDestinationVerifier, ConfirmedOwner, TypeAndVer uint8 f, Common.AddressAndWeight[] memory recipientAddressesAndWeights, uint32 activationTime - ) internal checkConfigValid(signers.length, f) onlyOwner { + ) internal { // Duplicate addresses would break protocol rules if (Common._hasDuplicateAddresses(signers)) { revert NonUniqueSignatures(); @@ -304,7 +320,7 @@ contract DestinationVerifier is IDestinationVerifier, ConfirmedOwner, TypeAndVer // Check the activation time is greater than the latest config uint256 donConfigLength = s_donConfigs.length; - if (donConfigLength > 0 && s_donConfigs[donConfigLength - 1].activationTime > activationTime) { + if (donConfigLength > 0 && s_donConfigs[donConfigLength - 1].activationTime >= activationTime) { revert BadActivationTime(); } @@ -315,22 +331,22 @@ contract DestinationVerifier is IDestinationVerifier, ConfirmedOwner, TypeAndVer // We may want to register these later or skip this step in the unlikely scenario they've previously been registered in the RewardsManager if (recipientAddressesAndWeights.length != 0) { - IDestinationFeeManager(s_feeManager).setFeeRecipients(donConfigId, recipientAddressesAndWeights); + if (s_feeManager == address(0)) { + revert FeeManagerInvalid(); + } + IDestinationVerifierFeeManager(s_feeManager).setFeeRecipients(donConfigId, recipientAddressesAndWeights); } // push the DonConfig s_donConfigs.push(DonConfig(donConfigId, f, true, activationTime)); - emit ConfigSet(donConfigId, signers, f, recipientAddressesAndWeights); + emit ConfigSet(donConfigId, signers, f, recipientAddressesAndWeights, uint16(donConfigLength)); } /// @inheritdoc IDestinationVerifier function setFeeManager(address feeManager) external override onlyOwner { - if ( - !IERC165(feeManager).supportsInterface(IDestinationFeeManager.processFee.selector) || - !IERC165(feeManager).supportsInterface(IDestinationFeeManager.processFeeBulk.selector) || - !IERC165(feeManager).supportsInterface(IDestinationFeeManager.setFeeRecipients.selector) - ) revert FeeManagerInvalid(); + if (!IERC165(feeManager).supportsInterface(type(IDestinationVerifierFeeManager).interfaceId)) + revert FeeManagerInvalid(); address oldFeeManager = s_feeManager; s_feeManager = feeManager; @@ -400,7 +416,7 @@ contract DestinationVerifier is IDestinationVerifier, ConfirmedOwner, TypeAndVer _; } - modifier checkValidProxy() { + modifier onlyProxy() { if (address(i_verifierProxy) != msg.sender) { revert AccessForbidden(); } @@ -416,19 +432,12 @@ contract DestinationVerifier is IDestinationVerifier, ConfirmedOwner, TypeAndVer /// @inheritdoc IERC165 function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { return - interfaceId == this.verify.selector || - interfaceId == this.verifyBulk.selector || - interfaceId == this.s_accessController.selector || - interfaceId == this.s_feeManager.selector || - interfaceId == this.setConfig.selector || - interfaceId == this.setConfigWithActivationTime.selector || - interfaceId == this.setFeeManager.selector || - interfaceId == this.setAccessController.selector || - interfaceId == this.setConfigActive.selector; + interfaceId == type(IDestinationVerifier).interfaceId || + interfaceId == type(IDestinationVerifierProxyVerifier).interfaceId; } /// @inheritdoc TypeAndVersionInterface function typeAndVersion() external pure override returns (string memory) { - return "DestinationVerifier 1.0.0"; + return "DestinationVerifier 0.4.0"; } } diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifierProxy.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifierProxy.sol index 1a5c62b429..6790883ba3 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifierProxy.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/DestinationVerifierProxy.sol @@ -5,16 +5,16 @@ import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; import {IDestinationVerifierProxy} from "./interfaces/IDestinationVerifierProxy.sol"; -import {IDestinationVerifier} from "./interfaces/IDestinationVerifier.sol"; +import {IDestinationVerifierProxyVerifier} from "./interfaces/IDestinationVerifierProxyVerifier.sol"; /** * @title DestinationVerifierProxy * @author Michael Fletcher * @notice This contract will be used to route all requests through to the assigned verifier contract. This contract does not support individual feed configurations and is aimed at being a simple proxy for the verifier contract on any destination chain. */ -contract DestinationVerifierProxy is IDestinationVerifierProxy, ConfirmedOwner, TypeAndVersionInterface, IERC165 { +contract DestinationVerifierProxy is IDestinationVerifierProxy, ConfirmedOwner, TypeAndVersionInterface { /// @notice The active verifier for this proxy - IDestinationVerifier private s_verifier; + IDestinationVerifierProxyVerifier private s_verifier; /// @notice This error is thrown whenever a zero address is passed error ZeroAddress(); @@ -26,7 +26,7 @@ contract DestinationVerifierProxy is IDestinationVerifierProxy, ConfirmedOwner, /// @inheritdoc TypeAndVersionInterface function typeAndVersion() external pure override returns (string memory) { - return "DestinationVerifierProxy 1.0.0"; + return "DestinationVerifierProxy 0.4.0"; } /// @inheritdoc IDestinationVerifierProxy @@ -45,14 +45,10 @@ contract DestinationVerifierProxy is IDestinationVerifierProxy, ConfirmedOwner, /// @inheritdoc IDestinationVerifierProxy function setVerifier(address verifierAddress) external onlyOwner { //check it supports the functions we need - if ( - !IERC165(verifierAddress).supportsInterface(IDestinationVerifier.s_accessController.selector) || - !IERC165(verifierAddress).supportsInterface(IDestinationVerifier.s_feeManager.selector) || - !IERC165(verifierAddress).supportsInterface(IDestinationVerifier.verify.selector) || - !IERC165(verifierAddress).supportsInterface(IDestinationVerifier.verifyBulk.selector) - ) revert VerifierInvalid(verifierAddress); + if (!IERC165(verifierAddress).supportsInterface(type(IDestinationVerifierProxyVerifier).interfaceId)) + revert VerifierInvalid(verifierAddress); - s_verifier = IDestinationVerifier(verifierAddress); + s_verifier = IDestinationVerifierProxyVerifier(verifierAddress); } /// @inheritdoc IDestinationVerifierProxy @@ -69,11 +65,6 @@ contract DestinationVerifierProxy is IDestinationVerifierProxy, ConfirmedOwner, /// @inheritdoc IERC165 function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { - return - interfaceId == this.setVerifier.selector || - interfaceId == this.verify.selector || - interfaceId == this.verifyBulk.selector || - interfaceId == this.s_feeManager.selector || - interfaceId == this.s_accessController.selector; + return interfaceId == type(IDestinationVerifierProxy).interfaceId; } } diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationFeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationFeeManager.sol index f92e7cd146..00420a4edb 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationFeeManager.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationFeeManager.sol @@ -33,6 +33,14 @@ interface IDestinationFeeManager is IERC165 { */ function updateSubscriberDiscount(address subscriber, bytes32 feedId, address token, uint64 discount) external; + /** + * @notice Adds a subscriber to the fee manager + * @param subscriber address of the subscriber + * @param token token to apply the discount to + * @param discount discount to be applied to the fee + */ + function updateSubscriberGlobalDiscount(address subscriber, address token, uint64 discount) external; + /** * @notice Withdraws any native or LINK rewards to the owner address * @param assetAddress address of the asset to withdraw @@ -71,44 +79,6 @@ interface IDestinationFeeManager is IERC165 { */ function setRewardManager(address rewardManager) external; - /** - * @notice Handles fees for a report from the subscriber and manages rewards - * @param poolId pool id of the pool to pay into - * @param payload report to process the fee for - * @param parameterPayload fee payload - * @param subscriber address of the fee will be applied - */ - function processFee( - bytes32 poolId, - bytes calldata payload, - bytes calldata parameterPayload, - address subscriber - ) external payable; - - /** - * @notice Processes the fees for each report in the payload, billing the subscriber and paying the reward manager - * @param poolIds pool ids of the pool to pay into - * @param payloads reports to process - * @param parameterPayload fee payload - * @param subscriber address of the user to process fee for - */ - function processFeeBulk( - bytes32[] memory poolIds, - bytes[] calldata payloads, - bytes calldata parameterPayload, - address subscriber - ) external payable; - - /** - * @notice Sets the fee recipients according to the fee manager - * @param configDigest digest of the configuration - * @param rewardRecipientAndWeights the address and weights of all the recipients to receive rewards - */ - function setFeeRecipients( - bytes32 configDigest, - Common.AddressAndWeight[] calldata rewardRecipientAndWeights - ) external; - /** * @notice The structure to hold a fee and reward to verify a report * @param digest the digest linked to the fee and reward diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifier.sol index 69516f6e92..041a8c8f72 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifier.sol @@ -2,36 +2,9 @@ pragma solidity 0.8.19; import {Common} from "../../libraries/Common.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -interface IDestinationVerifier { - /** - * @notice Verifies that the data encoded has been signed correctly using the signatures included within the payload. - * @param signedReport The encoded data to be verified. - * @param parameterPayload The encoded parameters to be used in the verification and billing process. - * @param sender The address that requested to verify the contract.Used for logging and applying the fee. - * @dev Verification is typically only done through the proxy contract so we can't just use msg.sender. - * @return verifierResponse The encoded verified response. - */ - function verify( - bytes calldata signedReport, - bytes calldata parameterPayload, - address sender - ) external payable returns (bytes memory verifierResponse); - - /** - * @notice Bulk verifies that the data encoded has been signed correctly using the signatures included within the payload. - * @param signedReports The encoded data to be verified. - * @param parameterPayload The encoded parameters to be used in the verification and billing process. - * @param sender The address that requested to verify the contract. Used for logging and applying the fee. - * @dev Verification is typically only done through the proxy contract so we can't just use msg.sender. - * @return verifiedReports The encoded verified responses. - */ - function verifyBulk( - bytes[] calldata signedReports, - bytes calldata parameterPayload, - address sender - ) external payable returns (bytes[] memory verifiedReports); - +interface IDestinationVerifier is IERC165 { /** * @notice sets off-chain reporting protocol configuration incl. participating oracles * @param signers addresses with which oracles sign the reports @@ -81,18 +54,4 @@ interface IDestinationVerifier { * @notice Removes the latest config */ function removeLatestConfig() external; - - /* - * @notice Returns the reward manager - * @return IDestinationRewardManager - */ - // solhint-disable-next-line func-name-mixedcase - function s_feeManager() external view returns (address); - - /** - * @notice Returns the access controller - * @return IDestinationFeeManager - */ - // solhint-disable-next-line func-name-mixedcase - function s_accessController() external view returns (address); } diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierFeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierFeeManager.sol new file mode 100644 index 0000000000..291f3706b3 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierFeeManager.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; + +interface IDestinationVerifierFeeManager is IERC165 { + /** + * @notice Handles fees for a report from the subscriber and manages rewards + * @param poolId pool id of the pool to pay into + * @param payload report to process the fee for + * @param parameterPayload fee payload + * @param subscriber address of the fee will be applied + */ + function processFee( + bytes32 poolId, + bytes calldata payload, + bytes calldata parameterPayload, + address subscriber + ) external payable; + + /** + * @notice Processes the fees for each report in the payload, billing the subscriber and paying the reward manager + * @param poolIds pool ids of the pool to pay into + * @param payloads reports to process + * @param parameterPayload fee payload + * @param subscriber address of the user to process fee for + */ + function processFeeBulk( + bytes32[] memory poolIds, + bytes[] calldata payloads, + bytes calldata parameterPayload, + address subscriber + ) external payable; + + /** + * @notice Sets the fee recipients according to the fee manager + * @param configDigest digest of the configuration + * @param rewardRecipientAndWeights the address and weights of all the recipients to receive rewards + */ + function setFeeRecipients( + bytes32 configDigest, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights + ) external; +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierProxy.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierProxy.sol index a88349b301..e0dcb30d54 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierProxy.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierProxy.sol @@ -1,7 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -interface IDestinationVerifierProxy { +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; + +interface IDestinationVerifierProxy is IERC165 { /** * @notice Verifies that the data encoded has been signed * correctly by routing to the verifier, and bills the user if applicable. diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierProxyVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierProxyVerifier.sol new file mode 100644 index 0000000000..a957f8f928 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/interfaces/IDestinationVerifierProxyVerifier.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; + +interface IDestinationVerifierProxyVerifier is IERC165 { + /** + * @notice Verifies that the data encoded has been signed correctly using the signatures included within the payload. + * @param signedReport The encoded data to be verified. + * @param parameterPayload The encoded parameters to be used in the verification and billing process. + * @param sender The address that requested to verify the contract.Used for logging and applying the fee. + * @dev Verification is typically only done through the proxy contract so we can't just use msg.sender. + * @return verifierResponse The encoded verified response. + */ + function verify( + bytes calldata signedReport, + bytes calldata parameterPayload, + address sender + ) external payable returns (bytes memory verifierResponse); + + /** + * @notice Bulk verifies that the data encoded has been signed correctly using the signatures included within the payload. + * @param signedReports The encoded data to be verified. + * @param parameterPayload The encoded parameters to be used in the verification and billing process. + * @param sender The address that requested to verify the contract. Used for logging and applying the fee. + * @dev Verification is typically only done through the proxy contract so we can't just use msg.sender. + * @return verifiedReports The encoded verified responses. + */ + function verifyBulk( + bytes[] calldata signedReports, + bytes calldata parameterPayload, + address sender + ) external payable returns (bytes[] memory verifiedReports); + + /* + * @notice Returns the reward manager + * @return IDestinationRewardManager + */ + // solhint-disable-next-line func-name-mixedcase + function s_feeManager() external view returns (address); + + /** + * @notice Returns the access controller + * @return IDestinationFeeManager + */ + // solhint-disable-next-line func-name-mixedcase + function s_accessController() external view returns (address); +} diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/BaseDestinationFeeManager.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/BaseDestinationFeeManager.t.sol index 8b70e5b2b3..38b1bad217 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/BaseDestinationFeeManager.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/BaseDestinationFeeManager.t.sol @@ -108,7 +108,7 @@ contract BaseDestinationFeeManagerTest is Test { ); //link the feeManager to the proxy - feeManagerProxy.setDestinationFeeManager(feeManager); + feeManagerProxy.setDestinationFeeManager(address(feeManager)); //link the feeManager to the reward manager rewardManager.addFeeManager(address(feeManager)); @@ -147,6 +147,18 @@ contract BaseDestinationFeeManagerTest is Test { changePrank(originalAddr); } + function setSubscriberGlobalDiscount(address subscriber, address token, uint256 discount, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //set the discount + feeManager.updateSubscriberGlobalDiscount(subscriber, token, uint64(discount)); + + //change back to the original address + changePrank(originalAddr); + } + function setNativeSurcharge(uint256 surcharge, address sender) public { //record the current address and switch to the recipient address originalAddr = msg.sender; diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.getFeeAndReward.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.getFeeAndReward.t.sol index 30be694df2..ddd3ac5a8e 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.getFeeAndReward.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/fee-manager/DestinationFeeManager.getFeeAndReward.t.sol @@ -603,4 +603,118 @@ contract DestinationFeeManagerProcessFeeTest is BaseDestinationFeeManagerTest { //fee should be half the default assertEq(discount, FEE_SCALAR / 2); } + + function test_GlobalDiscountWithNative() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(native), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } + + function test_GlobalDiscountWithLink() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(link), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } + + function test_GlobalDiscountWithNativeAndLink() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(native), FEE_SCALAR / 2, ADMIN); + setSubscriberGlobalDiscount(USER, address(link), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } + + function test_GlobalDiscountIsOverridenByIndividualDiscountNative() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(native), FEE_SCALAR / 2, ADMIN); + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 4, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 4); + } + + function test_GlobalDiscountIsOverridenByIndividualDiscountLink() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(link), FEE_SCALAR / 2, ADMIN); + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 4, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 4); + } + + function test_GlobalDiscountIsUpdatedAfterBeingSetToZeroLink() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(link), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + + //set the global discount to zero + setSubscriberGlobalDiscount(USER, address(link), 0, ADMIN); + + //get the discount applied + discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be zero + assertEq(discount, 0); + } + + function test_GlobalDiscountIsUpdatedAfterBeingSetToZeroNative() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(native), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + + //set the global discount to zero + setSubscriberGlobalDiscount(USER, address(native), 0, ADMIN); + + //get the discount applied + discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be zero + assertEq(discount, 0); + } + + function test_GlobalDiscountCantBeSetToMoreThanMaximum() public { + //should revert with invalid discount + vm.expectRevert(INVALID_DISCOUNT_ERROR); + + //set the global discount to 101% + setSubscriberGlobalDiscount(USER, address(native), FEE_SCALAR + 1, ADMIN); + } + + function test_onlyOwnerCanSetGlobalDiscount() public { + //should revert with unauthorized + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(native), FEE_SCALAR / 2, USER); + } } diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/mocks/DestinationFeeManagerProxy.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/mocks/DestinationFeeManagerProxy.sol index 46ec7fff3b..7dde878321 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/test/mocks/DestinationFeeManagerProxy.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/mocks/DestinationFeeManagerProxy.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import {IDestinationFeeManager} from "../../interfaces/IDestinationFeeManager.sol"; +import {IDestinationVerifierFeeManager} from "../../interfaces/IDestinationVerifierFeeManager.sol"; contract DestinationFeeManagerProxy { - IDestinationFeeManager internal s_feeManager; + IDestinationVerifierFeeManager internal s_feeManager; function processFee(bytes32 poolId, bytes calldata payload, bytes calldata parameterPayload) public payable { s_feeManager.processFee{value: msg.value}(poolId, payload, parameterPayload, msg.sender); @@ -18,7 +18,7 @@ contract DestinationFeeManagerProxy { s_feeManager.processFeeBulk{value: msg.value}(poolIds, payloads, parameterPayload, msg.sender); } - function setDestinationFeeManager(IDestinationFeeManager feeManager) public { - s_feeManager = feeManager; + function setDestinationFeeManager(address feeManager) public { + s_feeManager = IDestinationVerifierFeeManager(feeManager); } } diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierProxyTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierProxyTest.t.sol index c93c9dc6d9..2851057d0e 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierProxyTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierProxyTest.t.sol @@ -33,6 +33,6 @@ contract DestinationVerifierProxyInitializeVerifierTest is BaseTest { function test_correctlySetsVersion() public view { string memory version = s_verifierProxy.typeAndVersion(); - assertEq(version, "DestinationVerifierProxy 1.0.0"); + assertEq(version, "DestinationVerifierProxy 0.4.0"); } } diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetConfigTest.t.sol index f6e5fd1f21..4f96e4969a 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierSetConfigTest.t.sol @@ -64,6 +64,7 @@ contract DestinationVerifierSetConfigTest is BaseTest { bytes24 expectedDonConfigId = _donConfigIdFromConfigData(signerAddrs, FAULT_TOLERANCE); s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + vm.warp(block.timestamp + 1); address temp = signerAddrs[0]; signerAddrs[0] = signerAddrs[1]; @@ -80,9 +81,13 @@ contract DestinationVerifierSetConfigTest is BaseTest { s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + vm.warp(block.timestamp + 1); + // testing adding same set of Signers but different FAULT_TOLERENCE does not result in DonConfigAlreadyExists revert s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE - 1, new Common.AddressAndWeight[](0)); + vm.warp(block.timestamp + 1); + // testing adding a different set of Signers with same FAULT_TOLERENCE does not result in DonConfigAlreadyExists revert address[] memory signerAddrsMinusOne = new address[](signerAddrs.length - 1); for (uint256 i = 0; i < signerAddrs.length - 1; i++) { @@ -96,6 +101,7 @@ contract DestinationVerifierSetConfigTest is BaseTest { address[] memory signerAddrs = _getSignerAddresses(signers); s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + vm.warp(block.timestamp + 1); bytes24 expectedDonConfigId = _donConfigIdFromConfigData(signerAddrs, FAULT_TOLERANCE); @@ -156,4 +162,15 @@ contract DestinationVerifierSetConfigTest is BaseTest { oldActivationTime ); } + + function test_setConfigWithActivationTimeTheSameAsLatestConfigShouldFail() public { + // setting a config older than the latest current config should fail + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + // sets a config with timestamp = block.timestamp + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + // setting a config with ealier timestamp retuls in failure + vm.expectRevert(abi.encodeWithSelector(DestinationVerifier.BadActivationTime.selector)); + s_verifier.setConfig(signerAddrs, FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + } } diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTest.t.sol index dd157d2a47..476acbf806 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierTest.t.sol @@ -3,6 +3,8 @@ pragma solidity 0.8.19; import {BaseTest} from "./BaseDestinationVerifierTest.t.sol"; import {DestinationVerifier} from "../../../v0.4.0/DestinationVerifier.sol"; +import {IDestinationVerifier} from "../../../v0.4.0/interfaces/IDestinationVerifier.sol"; +import {IDestinationVerifierProxyVerifier} from "../../../v0.4.0/interfaces/IDestinationVerifierProxyVerifier.sol"; contract DestinationVerifierConstructorTest is BaseTest { bytes32[3] internal s_reportContext; @@ -16,7 +18,7 @@ contract DestinationVerifierConstructorTest is BaseTest { DestinationVerifier v = new DestinationVerifier(address(s_verifierProxy)); assertEq(v.owner(), ADMIN); string memory typeAndVersion = s_verifier.typeAndVersion(); - assertEq(typeAndVersion, "DestinationVerifier 1.0.0"); + assertEq(typeAndVersion, "DestinationVerifier 0.4.0"); } function test_falseIfIsNotCorrectInterface() public view { @@ -25,7 +27,8 @@ contract DestinationVerifierConstructorTest is BaseTest { } function test_trueIfIsCorrectInterface() public view { - bool isInterface = s_verifier.supportsInterface(DestinationVerifier.verify.selector); + bool isInterface = s_verifier.supportsInterface(type(IDestinationVerifier).interfaceId) && + s_verifier.supportsInterface(type(IDestinationVerifierProxyVerifier).interfaceId); assertEq(isInterface, true); } } diff --git a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierVerifyTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierVerifyTest.t.sol index 658bf4f127..e72cfd09b6 100644 --- a/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierVerifyTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.4.0/test/verifier/DestinationVerifierVerifyTest.t.sol @@ -313,6 +313,7 @@ contract VerifierVerifyTest is BaseTest { address[] memory signersAddrSubset1 = _getSignerAddresses(signersSubset1); // Config1 s_verifier.setConfig(signersAddrSubset1, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + vm.warp(block.timestamp + 1); BaseTest.Signer[] memory signersSubset2 = new BaseTest.Signer[](7); signersSubset2[0] = signers[7]; @@ -326,6 +327,7 @@ contract VerifierVerifyTest is BaseTest { address[] memory signersAddrSubset2 = _getSignerAddresses(signersSubset2); // Config2 s_verifier.setConfig(signersAddrSubset2, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + vm.warp(block.timestamp + 1); BaseTest.Signer[] memory signersSubset3 = new BaseTest.Signer[](7); signersSubset3[0] = signers[30]; @@ -339,6 +341,7 @@ contract VerifierVerifyTest is BaseTest { address[] memory signersAddrSubset3 = _getSignerAddresses(signersSubset3); // Config3 s_verifier.setConfig(signersAddrSubset3, MINIMAL_FAULT_TOLERANCE, new Common.AddressAndWeight[](0)); + vm.warp(block.timestamp + 1); V3Report memory report = V3Report({ feedId: FEED_ID_V3, diff --git a/core/gethwrappers/llo-feeds/generated/destination_fee_manager/destination_fee_manager.go b/core/gethwrappers/llo-feeds/generated/destination_fee_manager/destination_fee_manager.go index b87cf068ac..fc9cda0b3d 100644 --- a/core/gethwrappers/llo-feeds/generated/destination_fee_manager/destination_fee_manager.go +++ b/core/gethwrappers/llo-feeds/generated/destination_fee_manager/destination_fee_manager.go @@ -46,8 +46,8 @@ type IDestinationRewardManagerFeePayment struct { } var DestinationFeeManagerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_linkAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_nativeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verifierAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ExpiredReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDiscount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidQuote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReceivingAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSurcharge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolIdMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroDeficit\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.Asset\",\"name\":\"fee\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.Asset\",\"name\":\"reward\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"appliedDiscount\",\"type\":\"uint256\"}],\"name\":\"DiscountApplied\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIDestinationRewardManager.FeePayment[]\",\"name\":\"rewards\",\"type\":\"tuple[]\"}],\"name\":\"InsufficientLink\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"}],\"name\":\"LinkDeficitCleared\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newSurcharge\",\"type\":\"uint64\"}],\"name\":\"NativeSurchargeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"SubscriberDiscountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"addVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"quoteAddress\",\"type\":\"address\"}],\"name\":\"getFeeAndReward\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_linkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_nativeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_rewardManager\",\"outputs\":[{\"internalType\":\"contractIDestinationRewardManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"payLinkDeficit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"recipient\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFee\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"poolIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFeeBulk\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"removeVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_linkDeficit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_nativeSurcharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_subscriberDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_verifierAddressList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setFeeRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"surcharge\",\"type\":\"uint64\"}],\"name\":\"setNativeSurcharge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rewardManagerAddress\",\"type\":\"address\"}],\"name\":\"setRewardManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"updateSubscriberDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60c06040523480156200001157600080fd5b5060405162003c3238038062003c328339810160408190526200003491620002af565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620001e7565b5050506001600160a01b0384161580620000df57506001600160a01b038316155b80620000f257506001600160a01b038216155b806200010557506001600160a01b038116155b15620001245760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03848116608081905284821660a05283821660008181526004602081905260409182902080546001600160a01b03199081169094179055600580549093169486169485179092555163095ea7b360e01b81529081019290925260001960248301529063095ea7b3906044016020604051808303816000875af1158015620001b6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001dc91906200030c565b505050505062000337565b336001600160a01b03821603620002415760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620002aa57600080fd5b919050565b60008060008060808587031215620002c657600080fd5b620002d18562000292565b9350620002e16020860162000292565b9250620002f16040860162000292565b9150620003016060860162000292565b905092959194509250565b6000602082840312156200031f57600080fd5b815180151581146200033057600080fd5b9392505050565b60805160a051613850620003e26000396000818161033b0152818161151c0152818161177a015281816117d101528181611a7e0152818161248e01526125370152600081816105430152818161098e01528181610a9801528181610e9b015281816111f4015281816114c50152818161165c0152818161179f015281816118280152818161196d015281816119da01528181611a1a01528181612109015261262b01526138506000f3fe60806040526004361061018b5760003560e01c806386968cfd116100d6578063d09dc3391161007f578063ea4b861b11610059578063ea4b861b14610531578063f2fde38b14610565578063f65df9621461058557600080fd5b8063d09dc33914610491578063e03dab1a146104a6578063e389d9a41461051157600080fd5b80639000b3d6116100b05780639000b3d614610431578063ca2dfd0a14610451578063ce7817d11461047157600080fd5b806386968cfd146103b557806387d6d843146103c85780638da5cb5b1461040657600080fd5b80633690750911610138578063638786681161011257806363878668146103295780637700feeb1461035d57806379ba5097146103a057600080fd5b806336907509146102a45780633aa5ac07146102b7578063505380941461030957600080fd5b8063181f5a7711610169578063181f5a77146102225780631d4d84a21461026e57806332f5f7461461028e57600080fd5b8063013f542b1461019057806301ffc9a7146101d0578063153ee55414610200575b600080fd5b34801561019c57600080fd5b506101bd6101ab366004612d9a565b60036020526000908152604090205481565b6040519081526020015b60405180910390f35b3480156101dc57600080fd5b506101f06101eb366004612db3565b6105a5565b60405190151581526020016101c7565b34801561020c57600080fd5b5061022061021b366004612e27565b6108ea565b005b34801561022e57600080fd5b50604080518082018252601b81527f44657374696e6174696f6e4665654d616e6167657220312e302e300000000000602082015290516101c79190612e68565b34801561027a57600080fd5b50610220610289366004612edf565b610b0b565b34801561029a57600080fd5b506101bd60065481565b6102206102b2366004613036565b610c9f565b3480156102c357600080fd5b506005546102e49073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c7565b34801561031557600080fd5b50610220610324366004613156565b610f50565b34801561033557600080fd5b506102e47f000000000000000000000000000000000000000000000000000000000000000081565b34801561036957600080fd5b506102e4610378366004612e27565b60046020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103ac57600080fd5b50610220610fea565b6102206103c3366004613171565b6110ec565b3480156103d457600080fd5b506101bd6103e33660046131fd565b600260209081526000938452604080852082529284528284209052825290205481565b34801561041257600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166102e4565b34801561043d57600080fd5b5061022061044c366004612e27565b61126d565b34801561045d57600080fd5b5061022061046c366004612e27565b611370565b34801561047d57600080fd5b5061022061048c366004613234565b61146f565b34801561049d57600080fd5b506101bd61162b565b3480156104b257600080fd5b506104c66104c1366004613313565b6116e1565b60408051845173ffffffffffffffffffffffffffffffffffffffff9081168252602095860151868301528451169181019190915292909101516060830152608082015260a0016101c7565b34801561051d57600080fd5b5061022061052c366004612d9a565b611ae0565b34801561053d57600080fd5b506102e47f000000000000000000000000000000000000000000000000000000000000000081565b34801561057157600080fd5b50610220610580366004612e27565b611c95565b34801561059157600080fd5b506102206105a036600461336c565b611ca9565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe03dab1a00000000000000000000000000000000000000000000000000000000148061063857507fffffffff0000000000000000000000000000000000000000000000000000000082167f5053809400000000000000000000000000000000000000000000000000000000145b8061068457507fffffffff0000000000000000000000000000000000000000000000000000000082167fce7817d100000000000000000000000000000000000000000000000000000000145b806106d057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1d4d84a200000000000000000000000000000000000000000000000000000000145b8061071c57507fffffffff0000000000000000000000000000000000000000000000000000000082167fd09dc33900000000000000000000000000000000000000000000000000000000145b8061076857507fffffffff0000000000000000000000000000000000000000000000000000000082167fe389d9a400000000000000000000000000000000000000000000000000000000145b806107b457507fffffffff0000000000000000000000000000000000000000000000000000000082167f9000b3d600000000000000000000000000000000000000000000000000000000145b8061080057507fffffffff0000000000000000000000000000000000000000000000000000000082167fca2dfd0a00000000000000000000000000000000000000000000000000000000145b8061084c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f86968cfd00000000000000000000000000000000000000000000000000000000145b8061089857507fffffffff0000000000000000000000000000000000000000000000000000000082167f3690750900000000000000000000000000000000000000000000000000000000145b806108e457507fffffffff0000000000000000000000000000000000000000000000000000000082167ff65df96200000000000000000000000000000000000000000000000000000000145b92915050565b6108f2611dbd565b73ffffffffffffffffffffffffffffffffffffffff811661093f576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600060248201527f00000000000000000000000000000000000000000000000000000000000000009091169063095ea7b3906044016020604051808303816000875af11580156109d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fd91906133eb565b50600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8381169182179092556040517f095ea7b300000000000000000000000000000000000000000000000000000000815260048101919091527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248201527f00000000000000000000000000000000000000000000000000000000000000009091169063095ea7b3906044016020604051808303816000875af1158015610ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0791906133eb565b5050565b610b13611dbd565b73ffffffffffffffffffffffffffffffffffffffff8316610be85760008273ffffffffffffffffffffffffffffffffffffffff168277ffffffffffffffffffffffffffffffffffffffffffffffff1660405160006040518083038185875af1925050503d8060008114610ba2576040519150601f19603f3d011682016040523d82523d6000602084013e610ba7565b606091505b5050905080610be2576040517fef2af20100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b610c2373ffffffffffffffffffffffffffffffffffffffff84168377ffffffffffffffffffffffffffffffffffffffffffffffff8416611e40565b6040805133815273ffffffffffffffffffffffffffffffffffffffff848116602083015285168183015277ffffffffffffffffffffffffffffffffffffffffffffffff8316606082015290517f7ff78a71698bdb18dcca96f52ab25e0a1b146fb6a49adf8e6845299e49021f299181900360800190a15b505050565b3360008181526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1614610cfc576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85518414610d35576040517e154a0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008467ffffffffffffffff811115610d5057610d50612f2a565b604051908082528060200260200182016040528015610d8957816020015b610d76612d0d565b815260200190600190039081610d6e5790505b5090506000806000805b88811015610f16576000801b8b8281518110610db157610db161340d565b602002602001015103610df0576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000610e248d8d86818110610e0a57610e0a61340d565b9050602002810190610e1c919061343c565b8d8d8d611f14565b9250925092508260200151600014610f025760405180608001604052808f8681518110610e5357610e5361340d565b6020026020010151815260200184815260200183815260200182815250888680610e7c906134d0565b975081518110610e8e57610e8e61340d565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1603610efb57866001019650610f02565b8560010195505b50505080610f0f906134d0565b9050610d93565b5082151580610f2457508115155b15610f3a57610f3585858585612024565b610f44565b610f44853461281e565b50505050505050505050565b610f58611dbd565b670de0b6b3a764000067ffffffffffffffff82161115610fa4576040517f05e8ac2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660068190556040519081527f08f7c0d17932ddb8523bc06754d42ff19ebc77d76a8b9bfde02c28ab1ed3d6399060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff163314611070576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3360008181526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1614611149576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600061115b8888888888611f14565b925092509250826020015160000361117f57611177843461281e565b505050611265565b604080516001808252818301909252600091816020015b61119e612d0d565b81526020019060019003908161119657905050905060405180608001604052808b815260200185815260200184815260200183815250816000815181106111e7576111e761340d565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff160361125757610f35858260016000612024565b610f44858260006001612024565b505050505050565b611275611dbd565b73ffffffffffffffffffffffffffffffffffffffff81166112c2576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600460205260409020541615611321576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600081815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b611378611dbd565b73ffffffffffffffffffffffffffffffffffffffff81166113c5576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81811660009081526004602052604090205416611423576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b611477611dbd565b670de0b6b3a764000067ffffffffffffffff821611156114c3576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561156b57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156115a2576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff848116600081815260026020908152604080832088845282528083209487168084529482529182902067ffffffffffffffff86169081905582519485529084015285927f5eba5a8afa39780f0f99b6cbeb95f3da6a7040ca00abd46bdc91a0a060134139910160405180910390a350505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156116b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116dc9190613508565b905090565b604080518082018252600080825260208083018290528351808501855282815280820183905284518086018652838152808301849052855180870190965283865291850183905292938261173488613521565b90507fffff0000000000000000000000000000000000000000000000000000000000008082169081016117cf57505073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811683527f0000000000000000000000000000000000000000000000000000000000000000168152909350915060009050611ad7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161415801561187757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614155b156118ae576040517ff861803000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008b8060200190518101906118c7919061357a565b77ffffffffffffffffffffffffffffffffffffffffffffffff91821698509116955063ffffffff169350505042821015905061192f576040517fb6c405f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808e16600090815260026020908152604080832089845282528083208f851684529091529020547f000000000000000000000000000000000000000000000000000000000000000090911687526119be6119a682670de0b6b3a76400006135e0565b6119b090866135f3565b670de0b6b3a7640000612867565b602088015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116908d1603611a4b5773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016885260208088015190890152611ac8565b600654600090611a67906119a690670de0b6b3a764000061360a565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168a529050611ac1611ab783670de0b6b3a76400006135e0565b6119b090836135f3565b60208a0152505b96995094975094955050505050505b93509350939050565b611ae8611dbd565b60008181526003602052604081205490819003611b31576040517f03aad31200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600360205260408082208290558051600180825281830190925290816020015b6040805180820190915260008082526020820152815260200190600190039081611b5657905050905060405180604001604052808481526020018377ffffffffffffffffffffffffffffffffffffffffffffffff1681525081600081518110611bc157611bc161340d565b60209081029190910101526005546040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063b0d9fa1990611c24908490309060040161367d565b600060405180830381600087803b158015611c3e57600080fd5b505af1158015611c52573d6000803e3d6000fd5b50505050827f843f0b103e50b42b08f9d30f12f961845a6d02623730872e24644899c0dd989583604051611c8891815260200190565b60405180910390a2505050565b611c9d611dbd565b611ca68161289f565b50565b3360008181526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1614801590611cf5575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611d2c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517f14060f2300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906314060f2390611d86908690869086906004016136b5565b600060405180830381600087803b158015611da057600080fd5b505af1158015611db4573d6000803e3d6000fd5b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611e3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611067565b565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c9a9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612994565b6040805180820190915260008082526020820152604080518082019091526000808252602082015260003073ffffffffffffffffffffffffffffffffffffffff851603611f8d576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611f9b888a018a613735565b915050600081611faa90613521565b905060007e010000000000000000000000000000000000000000000000000000000000007fffff00000000000000000000000000000000000000000000000000000000000083161461200557612002888a018a612e27565b90505b6120108784836116e1565b955095509550505050955095509592505050565b60008267ffffffffffffffff81111561203f5761203f612f2a565b60405190808252806020026020018201604052801561208457816020015b604080518082019091526000808252602082015281526020019060019003908161205d5790505b50905060008267ffffffffffffffff8111156120a2576120a2612f2a565b6040519080825280602002602001820160405280156120e757816020015b60408051808201909152600080825260208201528152602001906001900390816120c05790505b5090506000808080806120fa888a61360a565b905060005b81811015612449577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168b82815181106121505761215061340d565b6020026020010151602001516000015173ffffffffffffffffffffffffffffffffffffffff16036122165760405180604001604052808c83815181106121985761219861340d565b60200260200101516000015181526020018c83815181106121bb576121bb61340d565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff168152508885806121f4906134d0565b9650815181106122065761220661340d565b602002602001018190525061230b565b60405180604001604052808c83815181106122335761223361340d565b60200260200101516000015181526020018c83815181106122565761225661340d565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff1681525087848061228f906134d0565b9550815181106122a1576122a161340d565b60200260200101819052508a81815181106122be576122be61340d565b60200260200101516020015160200151866122d9919061360a565b95508a81815181106122ed576122ed61340d565b6020026020010151604001516020015185612308919061360a565b94505b8a818151811061231d5761231d61340d565b602002602001015160600151600014612439578b73ffffffffffffffffffffffffffffffffffffffff168b82815181106123595761235961340d565b6020026020010151600001517f88b15eb682210089cddf967648e2cb2a4535aeadc8f8f36050922e33c04e71258d84815181106123985761239861340d565b6020026020010151602001518e85815181106123b6576123b661340d565b6020026020010151604001518f86815181106123d4576123d461340d565b60200260200101516060015160405161243093929190835173ffffffffffffffffffffffffffffffffffffffff908116825260209485015185830152835116604082015291909201516060820152608081019190915260a00190565b60405180910390a35b612442816134d0565b90506120ff565b5060003415612517573486111561248c576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0876040518263ffffffff1660e01b81526004016000604051808303818588803b1580156124f457600080fd5b505af1158015612508573d6000803e3d6000fd5b5050505050853403905061255f565b851561255f5761255f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168d3089612aa0565b8751156125f657600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b0d9fa19898e6040518363ffffffff1660e01b81526004016125c392919061367d565b600060405180830381600087803b1580156125dd57600080fd5b505af11580156125f1573d6000803e3d6000fd5b505050505b865115612806576040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612687573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ab9190613508565b85111561277b5760005b875181101561273e578781815181106126d0576126d061340d565b60200260200101516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16600360008a848151811061270c5761270c61340d565b60209081029190910181015151825281019190915260400160002080549091019055612737816134d0565b90506126b5565b507ff52e5907b69d97c33392936c12d78b494463b78c5b72df50b4c497eee5720b678760405161276e91906137d9565b60405180910390a1612806565b6005546040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063b0d9fa19906127d3908a90309060040161367d565b600060405180830381600087803b1580156127ed57600080fd5b505af1158015612801573d6000803e3d6000fd5b505050505b6128108c8261281e565b505050505050505050505050565b8015610b075760405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610c9a573d6000803e3d6000fd5b60008215612895578161287b6001856135e0565b61288591906137ec565b61289090600161360a565b612898565b60005b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361291e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611067565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006129f6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612afe9092919063ffffffff16565b805190915015610c9a5780806020019051810190612a1491906133eb565b610c9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611067565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610be29085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611e92565b6060612b0d8484600085612b15565b949350505050565b606082471015612ba7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611067565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612bd09190613827565b60006040518083038185875af1925050503d8060008114612c0d576040519150601f19603f3d011682016040523d82523d6000602084013e612c12565b606091505b5091509150612c2387838387612c2e565b979650505050505050565b60608315612cc4578251600003612cbd5773ffffffffffffffffffffffffffffffffffffffff85163b612cbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611067565b5081612b0d565b612b0d8383815115612cd95781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110679190612e68565b604051806080016040528060008019168152602001612d556040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b8152602001612d8d6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b8152602001600081525090565b600060208284031215612dac57600080fd5b5035919050565b600060208284031215612dc557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461289857600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611ca657600080fd5b8035612e2281612df5565b919050565b600060208284031215612e3957600080fd5b813561289881612df5565b60005b83811015612e5f578181015183820152602001612e47565b50506000910152565b6020815260008251806020840152612e87816040850160208701612e44565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b77ffffffffffffffffffffffffffffffffffffffffffffffff81168114611ca657600080fd5b600080600060608486031215612ef457600080fd5b8335612eff81612df5565b92506020840135612f0f81612df5565b91506040840135612f1f81612eb9565b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612fa057612fa0612f2a565b604052919050565b60008083601f840112612fba57600080fd5b50813567ffffffffffffffff811115612fd257600080fd5b6020830191508360208260051b8501011115612fed57600080fd5b9250929050565b60008083601f84011261300657600080fd5b50813567ffffffffffffffff81111561301e57600080fd5b602083019150836020828501011115612fed57600080fd5b6000806000806000806080878903121561304f57600080fd5b863567ffffffffffffffff8082111561306757600080fd5b818901915089601f83011261307b57600080fd5b813560208282111561308f5761308f612f2a565b8160051b61309e828201612f59565b928352848101820192828101908e8511156130b857600080fd5b958301955b848710156130d6578635825295830195908301906130bd565b9b5050508a0135925050808211156130ed57600080fd5b6130f98a838b01612fa8565b9097509550604089013591508082111561311257600080fd5b5061311f89828a01612ff4565b9094509250613132905060608801612e17565b90509295509295509295565b803567ffffffffffffffff81168114612e2257600080fd5b60006020828403121561316857600080fd5b6128988261313e565b6000806000806000806080878903121561318a57600080fd5b86359550602087013567ffffffffffffffff808211156131a957600080fd5b6131b58a838b01612ff4565b909750955060408901359150808211156131ce57600080fd5b506131db89828a01612ff4565b90945092505060608701356131ef81612df5565b809150509295509295509295565b60008060006060848603121561321257600080fd5b833561321d81612df5565b9250602084013591506040840135612f1f81612df5565b6000806000806080858703121561324a57600080fd5b843561325581612df5565b935060208501359250604085013561326c81612df5565b915061327a6060860161313e565b905092959194509250565b600082601f83011261329657600080fd5b813567ffffffffffffffff8111156132b0576132b0612f2a565b6132e160207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612f59565b8181528460208386010111156132f657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561332857600080fd5b833561333381612df5565b9250602084013567ffffffffffffffff81111561334f57600080fd5b61335b86828701613285565b9250506040840135612f1f81612df5565b60008060006040848603121561338157600080fd5b83359250602084013567ffffffffffffffff808211156133a057600080fd5b818601915086601f8301126133b457600080fd5b8135818111156133c357600080fd5b8760208260061b85010111156133d857600080fd5b6020830194508093505050509250925092565b6000602082840312156133fd57600080fd5b8151801515811461289857600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261347157600080fd5b83018035915067ffffffffffffffff82111561348c57600080fd5b602001915036819003821315612fed57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613501576135016134a1565b5060010190565b60006020828403121561351a57600080fd5b5051919050565b80516020808301519190811015613560577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b805163ffffffff81168114612e2257600080fd5b60008060008060008060c0878903121561359357600080fd5b865195506135a360208801613566565b94506135b160408801613566565b935060608701516135c181612eb9565b60808801519093506135d281612eb9565b915061313260a08801613566565b818103818111156108e4576108e46134a1565b80820281158282048414176108e4576108e46134a1565b808201808211156108e4576108e46134a1565b600081518084526020808501945080840160005b838110156136725781518051885283015177ffffffffffffffffffffffffffffffffffffffffffffffff168388015260409096019590820190600101613631565b509495945050505050565b604081526000613690604083018561361d565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b8381526040602080830182905282820184905260009190859060608501845b878110156137285783356136e781612df5565b73ffffffffffffffffffffffffffffffffffffffff16825267ffffffffffffffff61371385850161313e565b168284015292840192908401906001016136d4565b5098975050505050505050565b6000806080838503121561374857600080fd5b83601f84011261375757600080fd5b6040516060810167ffffffffffffffff828210818311171561377b5761377b612f2a565b81604052829150606086018781111561379357600080fd5b865b818110156137ad578035845260209384019301613795565b50929450913591808311156137c157600080fd5b50506137cf85828601613285565b9150509250929050565b602081526000612898602083018461361d565b600082613822577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613839818460208701612e44565b919091019291505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_linkAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_nativeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verifierAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ExpiredReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDiscount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidQuote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReceivingAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSurcharge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolIdMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroDeficit\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.Asset\",\"name\":\"fee\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.Asset\",\"name\":\"reward\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"appliedDiscount\",\"type\":\"uint256\"}],\"name\":\"DiscountApplied\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIDestinationRewardManager.FeePayment[]\",\"name\":\"rewards\",\"type\":\"tuple[]\"}],\"name\":\"InsufficientLink\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"}],\"name\":\"LinkDeficitCleared\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newSurcharge\",\"type\":\"uint64\"}],\"name\":\"NativeSurchargeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"SubscriberDiscountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"addVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"quoteAddress\",\"type\":\"address\"}],\"name\":\"getFeeAndReward\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_linkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_nativeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_rewardManager\",\"outputs\":[{\"internalType\":\"contractIDestinationRewardManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"payLinkDeficit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"recipient\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFee\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"poolIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFeeBulk\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"removeVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_globalDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_linkDeficit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_nativeSurcharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_subscriberDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_verifierAddressList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setFeeRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"surcharge\",\"type\":\"uint64\"}],\"name\":\"setNativeSurcharge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rewardManagerAddress\",\"type\":\"address\"}],\"name\":\"setRewardManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"updateSubscriberDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"updateSubscriberGlobalDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b5060405162003d4538038062003d458339810160408190526200003491620002ae565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620001e6565b5050506001600160a01b0384161580620000df57506001600160a01b038316155b80620000f257506001600160a01b038216155b806200010557506001600160a01b038116155b15620001245760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03848116608081905284821660a0528382166000818152600560205260409081902080546001600160a01b03199081169093179055600680549092169385169384179091555163095ea7b360e01b8152600481019290925260001960248301529063095ea7b3906044016020604051808303816000875af1158015620001b5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001db91906200030b565b505050505062000336565b336001600160a01b03821603620002405760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620002a957600080fd5b919050565b60008060008060808587031215620002c557600080fd5b620002d08562000291565b9350620002e06020860162000291565b9250620002f06040860162000291565b9150620003006060860162000291565b905092959194509250565b6000602082840312156200031e57600080fd5b815180151581146200032f57600080fd5b9392505050565b60805160a051613956620003ef6000396000818161038901528181610f3d01528181611577015281816117d50152818161182c01528181611b2a0152818161251401526125bd0152600081816105b1015281816108340152818161093e01528181610d4101528181610ee60152818161124f01528181611520015281816116b7015281816117fa0152818161188301528181611a1b01528181611a8601528181611ac60152818161218f01526126b101526139566000f3fe6080604052600436106101a15760003560e01c806379ba5097116100e1578063ce7817d11161008a578063e389d9a411610064578063e389d9a41461057f578063ea4b861b1461059f578063f2fde38b146105d3578063f65df962146105f357600080fd5b8063ce7817d1146104df578063d09dc339146104ff578063e03dab1a1461051457600080fd5b80638da5cb5b116100bb5780638da5cb5b146104745780639000b3d61461049f578063ca2dfd0a146104bf57600080fd5b806379ba50971461040e57806386968cfd1461042357806387d6d8431461043657600080fd5b806332f5f7461161014e57806350538094116101285780635053809414610357578063638786681461037757806376cf3187146103ab5780637700feeb146103cb57600080fd5b806332f5f746146102dc57806336907509146102f25780633aa5ac071461030557600080fd5b8063181f5a771161017f578063181f5a77146102385780631cc7f2d8146102845780631d4d84a2146102bc57600080fd5b8063013f542b146101a657806301ffc9a7146101e6578063153ee55414610216575b600080fd5b3480156101b257600080fd5b506101d36101c1366004612e20565b60046020526000908152604090205481565b6040519081526020015b60405180910390f35b3480156101f257600080fd5b50610206610201366004612e39565b610613565b60405190151581526020016101dd565b34801561022257600080fd5b50610236610231366004612ead565b6106ac565b005b34801561024457600080fd5b50604080518082018252601b81527f44657374696e6174696f6e4665654d616e6167657220302e342e300000000000602082015290516101dd9190612eee565b34801561029057600080fd5b506101d361029f366004612f3f565b600360209081526000928352604080842090915290825290205481565b3480156102c857600080fd5b506102366102d7366004612f9e565b6109b1565b3480156102e857600080fd5b506101d360075481565b6102366103003660046130f5565b610b45565b34801561031157600080fd5b506006546103329073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101dd565b34801561036357600080fd5b50610236610372366004613215565b610df6565b34801561038357600080fd5b506103327f000000000000000000000000000000000000000000000000000000000000000081565b3480156103b757600080fd5b506102366103c6366004613230565b610e90565b3480156103d757600080fd5b506103326103e6366004612ead565b60056020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b34801561041a57600080fd5b50610236611045565b610236610431366004613277565b611147565b34801561044257600080fd5b506101d3610451366004613303565b600260209081526000938452604080852082529284528284209052825290205481565b34801561048057600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610332565b3480156104ab57600080fd5b506102366104ba366004612ead565b6112c8565b3480156104cb57600080fd5b506102366104da366004612ead565b6113cb565b3480156104eb57600080fd5b506102366104fa36600461333a565b6114ca565b34801561050b57600080fd5b506101d3611686565b34801561052057600080fd5b5061053461052f366004613419565b61173c565b60408051845173ffffffffffffffffffffffffffffffffffffffff9081168252602095860151868301528451169181019190915292909101516060830152608082015260a0016101dd565b34801561058b57600080fd5b5061023661059a366004612e20565b611b8c565b3480156105ab57600080fd5b506103327f000000000000000000000000000000000000000000000000000000000000000081565b3480156105df57600080fd5b506102366105ee366004612ead565b611d41565b3480156105ff57600080fd5b5061023661060e366004613472565b611d55565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f6993386f0000000000000000000000000000000000000000000000000000000014806106a657507fffffffff0000000000000000000000000000000000000000000000000000000082167f465b009600000000000000000000000000000000000000000000000000000000145b92915050565b6106b4611e43565b73ffffffffffffffffffffffffffffffffffffffff8116610701576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f768ffd3a00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa15801561078b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107af91906134f1565b6107e5576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600060248201527f00000000000000000000000000000000000000000000000000000000000000009091169063095ea7b3906044016020604051808303816000875af115801561087f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a391906134f1565b50600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8381169182179092556040517f095ea7b300000000000000000000000000000000000000000000000000000000815260048101919091527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248201527f00000000000000000000000000000000000000000000000000000000000000009091169063095ea7b3906044016020604051808303816000875af1158015610989573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ad91906134f1565b5050565b6109b9611e43565b73ffffffffffffffffffffffffffffffffffffffff8316610a8e5760008273ffffffffffffffffffffffffffffffffffffffff168277ffffffffffffffffffffffffffffffffffffffffffffffff1660405160006040518083038185875af1925050503d8060008114610a48576040519150601f19603f3d011682016040523d82523d6000602084013e610a4d565b606091505b5050905080610a88576040517fef2af20100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b610ac973ffffffffffffffffffffffffffffffffffffffff84168377ffffffffffffffffffffffffffffffffffffffffffffffff8416611ec6565b6040805133815273ffffffffffffffffffffffffffffffffffffffff848116602083015285168183015277ffffffffffffffffffffffffffffffffffffffffffffffff8316606082015290517f7ff78a71698bdb18dcca96f52ab25e0a1b146fb6a49adf8e6845299e49021f299181900360800190a15b505050565b3360008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1614610ba2576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85518414610bdb576040517e154a0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008467ffffffffffffffff811115610bf657610bf6612fe9565b604051908082528060200260200182016040528015610c2f57816020015b610c1c612d93565b815260200190600190039081610c145790505b5090506000806000805b88811015610dbc576000801b8b8281518110610c5757610c57613513565b602002602001015103610c96576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000610cca8d8d86818110610cb057610cb0613513565b9050602002810190610cc29190613542565b8d8d8d611f9a565b9250925092508260200151600014610da85760405180608001604052808f8681518110610cf957610cf9613513565b6020026020010151815260200184815260200183815260200182815250888680610d22906135d6565b975081518110610d3457610d34613513565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1603610da157866001019650610da8565b8560010195505b50505080610db5906135d6565b9050610c39565b5082151580610dca57508115155b15610de057610ddb858585856120aa565b610dea565b610dea85346128a4565b50505050505050505050565b610dfe611e43565b670de0b6b3a764000067ffffffffffffffff82161115610e4a576040517f05e8ac2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660078190556040519081527f08f7c0d17932ddb8523bc06754d42ff19ebc77d76a8b9bfde02c28ab1ed3d6399060200160405180910390a150565b610e98611e43565b670de0b6b3a764000067ffffffffffffffff82161115610ee4576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015610f8c57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15610fc3576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff838116600081815260036020908152604080832094871680845294825280832067ffffffffffffffff87169081905581519586529185019190915290927f5eba5a8afa39780f0f99b6cbeb95f3da6a7040ca00abd46bdc91a0a060134139910160405180910390a3505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3360008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff16146111a4576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060006111b68888888888611f9a565b92509250925082602001516000036111da576111d284346128a4565b5050506112c0565b604080516001808252818301909252600091816020015b6111f9612d93565b8152602001906001900390816111f157905050905060405180608001604052808b8152602001858152602001848152602001838152508160008151811061124257611242613513565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff16036112b257610ddb8582600160006120aa565b610dea8582600060016120aa565b505050505050565b6112d0611e43565b73ffffffffffffffffffffffffffffffffffffffff811661131d576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff818116600090815260056020526040902054161561137c576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600081815260056020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b6113d3611e43565b73ffffffffffffffffffffffffffffffffffffffff8116611420576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600560205260409020541661147e576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260056020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6114d2611e43565b670de0b6b3a764000067ffffffffffffffff8216111561151e576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156115c657507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156115fd576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff848116600081815260026020908152604080832088845282528083209487168084529482529182902067ffffffffffffffff86169081905582519485529084015285927f5eba5a8afa39780f0f99b6cbeb95f3da6a7040ca00abd46bdc91a0a060134139910160405180910390a350505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611713573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611737919061360e565b905090565b604080518082018252600080825260208083018290528351808501855282815280820183905284518086018652838152808301849052855180870190965283865291850183905292938261178f88613627565b90507fffff00000000000000000000000000000000000000000000000000000000000080821690810161182a57505073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811683527f0000000000000000000000000000000000000000000000000000000000000000168152909350915060009050611b83565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16141580156118d257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614155b15611909576040517ff861803000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008b8060200190518101906119229190613680565b77ffffffffffffffffffffffffffffffffffffffffffffffff91821698509116955063ffffffff169350505042821015905061198a576040517fb6c405f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808e1660009081526002602090815260408083208984528252808320938f1683529290529081205490819003611a04575073ffffffffffffffffffffffffffffffffffffffff808e166000908152600360209081526040808320938f16835292905220545b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168752611a6a611a5282670de0b6b3a76400006136e6565b611a5c90866136f9565b670de0b6b3a76400006128ed565b602088015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116908d1603611af75773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016885260208088015190890152611b74565b600754600090611b1390611a5290670de0b6b3a7640000613710565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168a529050611b6d611b6383670de0b6b3a76400006136e6565b611a5c90836136f9565b60208a0152505b96995094975094955050505050505b93509350939050565b611b94611e43565b60008181526004602052604081205490819003611bdd576040517f03aad31200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600460205260408082208290558051600180825281830190925290816020015b6040805180820190915260008082526020820152815260200190600190039081611c0257905050905060405180604001604052808481526020018377ffffffffffffffffffffffffffffffffffffffffffffffff1681525081600081518110611c6d57611c6d613513565b60209081029190910101526006546040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063b0d9fa1990611cd09084903090600401613783565b600060405180830381600087803b158015611cea57600080fd5b505af1158015611cfe573d6000803e3d6000fd5b50505050827f843f0b103e50b42b08f9d30f12f961845a6d02623730872e24644899c0dd989583604051611d3491815260200190565b60405180910390a2505050565b611d49611e43565b611d5281612925565b50565b3360008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1614611db2576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006546040517f14060f2300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906314060f2390611e0c908690869086906004016137bb565b600060405180830381600087803b158015611e2657600080fd5b505af1158015611e3a573d6000803e3d6000fd5b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ec4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016110c2565b565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610b409084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a1a565b6040805180820190915260008082526020820152604080518082019091526000808252602082015260003073ffffffffffffffffffffffffffffffffffffffff851603612013576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612021888a018a61383b565b91505060008161203090613627565b905060007e010000000000000000000000000000000000000000000000000000000000007fffff00000000000000000000000000000000000000000000000000000000000083161461208b57612088888a018a612ead565b90505b61209687848361173c565b955095509550505050955095509592505050565b60008267ffffffffffffffff8111156120c5576120c5612fe9565b60405190808252806020026020018201604052801561210a57816020015b60408051808201909152600080825260208201528152602001906001900390816120e35790505b50905060008267ffffffffffffffff81111561212857612128612fe9565b60405190808252806020026020018201604052801561216d57816020015b60408051808201909152600080825260208201528152602001906001900390816121465790505b509050600080808080612180888a613710565b905060005b818110156124cf577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168b82815181106121d6576121d6613513565b6020026020010151602001516000015173ffffffffffffffffffffffffffffffffffffffff160361229c5760405180604001604052808c838151811061221e5761221e613513565b60200260200101516000015181526020018c838151811061224157612241613513565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff1681525088858061227a906135d6565b96508151811061228c5761228c613513565b6020026020010181905250612391565b60405180604001604052808c83815181106122b9576122b9613513565b60200260200101516000015181526020018c83815181106122dc576122dc613513565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16815250878480612315906135d6565b95508151811061232757612327613513565b60200260200101819052508a818151811061234457612344613513565b602002602001015160200151602001518661235f9190613710565b95508a818151811061237357612373613513565b602002602001015160400151602001518561238e9190613710565b94505b8a81815181106123a3576123a3613513565b6020026020010151606001516000146124bf578b73ffffffffffffffffffffffffffffffffffffffff168b82815181106123df576123df613513565b6020026020010151600001517f88b15eb682210089cddf967648e2cb2a4535aeadc8f8f36050922e33c04e71258d848151811061241e5761241e613513565b6020026020010151602001518e858151811061243c5761243c613513565b6020026020010151604001518f868151811061245a5761245a613513565b6020026020010151606001516040516124b693929190835173ffffffffffffffffffffffffffffffffffffffff908116825260209485015185830152835116604082015291909201516060820152608081019190915260a00190565b60405180910390a35b6124c8816135d6565b9050612185565b506000341561259d5734861115612512576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0876040518263ffffffff1660e01b81526004016000604051808303818588803b15801561257a57600080fd5b505af115801561258e573d6000803e3d6000fd5b505050505085340390506125e5565b85156125e5576125e573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168d3089612b26565b87511561267c57600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b0d9fa19898e6040518363ffffffff1660e01b8152600401612649929190613783565b600060405180830381600087803b15801561266357600080fd5b505af1158015612677573d6000803e3d6000fd5b505050505b86511561288c576040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561270d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612731919061360e565b8511156128015760005b87518110156127c45787818151811061275657612756613513565b60200260200101516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16600460008a848151811061279257612792613513565b602090810291909101810151518252810191909152604001600020805490910190556127bd816135d6565b905061273b565b507ff52e5907b69d97c33392936c12d78b494463b78c5b72df50b4c497eee5720b67876040516127f491906138df565b60405180910390a161288c565b6006546040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063b0d9fa1990612859908a903090600401613783565b600060405180830381600087803b15801561287357600080fd5b505af1158015612887573d6000803e3d6000fd5b505050505b6128968c826128a4565b505050505050505050505050565b80156109ad5760405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610b40573d6000803e3d6000fd5b6000821561291b57816129016001856136e6565b61290b91906138f2565b612916906001613710565b61291e565b60005b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036129a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016110c2565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612a7c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612b849092919063ffffffff16565b805190915015610b405780806020019051810190612a9a91906134f1565b610b40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016110c2565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a889085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611f18565b6060612b938484600085612b9b565b949350505050565b606082471015612c2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016110c2565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612c56919061392d565b60006040518083038185875af1925050503d8060008114612c93576040519150601f19603f3d011682016040523d82523d6000602084013e612c98565b606091505b5091509150612ca987838387612cb4565b979650505050505050565b60608315612d4a578251600003612d435773ffffffffffffffffffffffffffffffffffffffff85163b612d43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016110c2565b5081612b93565b612b938383815115612d5f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c29190612eee565b604051806080016040528060008019168152602001612ddb6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b8152602001612e136040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b8152602001600081525090565b600060208284031215612e3257600080fd5b5035919050565b600060208284031215612e4b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461291e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611d5257600080fd5b8035612ea881612e7b565b919050565b600060208284031215612ebf57600080fd5b813561291e81612e7b565b60005b83811015612ee5578181015183820152602001612ecd565b50506000910152565b6020815260008251806020840152612f0d816040850160208701612eca565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215612f5257600080fd5b8235612f5d81612e7b565b91506020830135612f6d81612e7b565b809150509250929050565b77ffffffffffffffffffffffffffffffffffffffffffffffff81168114611d5257600080fd5b600080600060608486031215612fb357600080fd5b8335612fbe81612e7b565b92506020840135612fce81612e7b565b91506040840135612fde81612f78565b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561305f5761305f612fe9565b604052919050565b60008083601f84011261307957600080fd5b50813567ffffffffffffffff81111561309157600080fd5b6020830191508360208260051b85010111156130ac57600080fd5b9250929050565b60008083601f8401126130c557600080fd5b50813567ffffffffffffffff8111156130dd57600080fd5b6020830191508360208285010111156130ac57600080fd5b6000806000806000806080878903121561310e57600080fd5b863567ffffffffffffffff8082111561312657600080fd5b818901915089601f83011261313a57600080fd5b813560208282111561314e5761314e612fe9565b8160051b61315d828201613018565b928352848101820192828101908e85111561317757600080fd5b958301955b848710156131955786358252958301959083019061317c565b9b5050508a0135925050808211156131ac57600080fd5b6131b88a838b01613067565b909750955060408901359150808211156131d157600080fd5b506131de89828a016130b3565b90945092506131f1905060608801612e9d565b90509295509295509295565b803567ffffffffffffffff81168114612ea857600080fd5b60006020828403121561322757600080fd5b61291e826131fd565b60008060006060848603121561324557600080fd5b833561325081612e7b565b9250602084013561326081612e7b565b915061326e604085016131fd565b90509250925092565b6000806000806000806080878903121561329057600080fd5b86359550602087013567ffffffffffffffff808211156132af57600080fd5b6132bb8a838b016130b3565b909750955060408901359150808211156132d457600080fd5b506132e189828a016130b3565b90945092505060608701356132f581612e7b565b809150509295509295509295565b60008060006060848603121561331857600080fd5b833561332381612e7b565b9250602084013591506040840135612fde81612e7b565b6000806000806080858703121561335057600080fd5b843561335b81612e7b565b935060208501359250604085013561337281612e7b565b9150613380606086016131fd565b905092959194509250565b600082601f83011261339c57600080fd5b813567ffffffffffffffff8111156133b6576133b6612fe9565b6133e760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613018565b8181528460208386010111156133fc57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561342e57600080fd5b833561343981612e7b565b9250602084013567ffffffffffffffff81111561345557600080fd5b6134618682870161338b565b9250506040840135612fde81612e7b565b60008060006040848603121561348757600080fd5b83359250602084013567ffffffffffffffff808211156134a657600080fd5b818601915086601f8301126134ba57600080fd5b8135818111156134c957600080fd5b8760208260061b85010111156134de57600080fd5b6020830194508093505050509250925092565b60006020828403121561350357600080fd5b8151801515811461291e57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261357757600080fd5b83018035915067ffffffffffffffff82111561359257600080fd5b6020019150368190038213156130ac57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613607576136076135a7565b5060010190565b60006020828403121561362057600080fd5b5051919050565b80516020808301519190811015613666577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b805163ffffffff81168114612ea857600080fd5b60008060008060008060c0878903121561369957600080fd5b865195506136a96020880161366c565b94506136b76040880161366c565b935060608701516136c781612f78565b60808801519093506136d881612f78565b91506131f160a0880161366c565b818103818111156106a6576106a66135a7565b80820281158282048414176106a6576106a66135a7565b808201808211156106a6576106a66135a7565b600081518084526020808501945080840160005b838110156137785781518051885283015177ffffffffffffffffffffffffffffffffffffffffffffffff168388015260409096019590820190600101613737565b509495945050505050565b6040815260006137966040830185613723565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b8381526040602080830182905282820184905260009190859060608501845b8781101561382e5783356137ed81612e7b565b73ffffffffffffffffffffffffffffffffffffffff16825267ffffffffffffffff6138198585016131fd565b168284015292840192908401906001016137da565b5098975050505050505050565b6000806080838503121561384e57600080fd5b83601f84011261385d57600080fd5b6040516060810167ffffffffffffffff828210818311171561388157613881612fe9565b81604052829150606086018781111561389957600080fd5b865b818110156138b357803584526020938401930161389b565b50929450913591808311156138c757600080fd5b50506138d58582860161338b565b9150509250929050565b60208152600061291e6020830184613723565b600082613928577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000825161393f818460208701612eca565b919091019291505056fea164736f6c6343000813000a", } var DestinationFeeManagerABI = DestinationFeeManagerMetaData.ABI @@ -320,6 +320,28 @@ func (_DestinationFeeManager *DestinationFeeManagerCallerSession) Owner() (commo return _DestinationFeeManager.Contract.Owner(&_DestinationFeeManager.CallOpts) } +func (_DestinationFeeManager *DestinationFeeManagerCaller) SGlobalDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (*big.Int, error) { + var out []interface{} + err := _DestinationFeeManager.contract.Call(opts, &out, "s_globalDiscounts", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) SGlobalDiscounts(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _DestinationFeeManager.Contract.SGlobalDiscounts(&_DestinationFeeManager.CallOpts, arg0, arg1) +} + +func (_DestinationFeeManager *DestinationFeeManagerCallerSession) SGlobalDiscounts(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _DestinationFeeManager.Contract.SGlobalDiscounts(&_DestinationFeeManager.CallOpts, arg0, arg1) +} + func (_DestinationFeeManager *DestinationFeeManagerCaller) SLinkDeficit(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) { var out []interface{} err := _DestinationFeeManager.contract.Call(opts, &out, "s_linkDeficit", arg0) @@ -584,6 +606,18 @@ func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) UpdateSubs return _DestinationFeeManager.Contract.UpdateSubscriberDiscount(&_DestinationFeeManager.TransactOpts, subscriber, feedId, token, discount) } +func (_DestinationFeeManager *DestinationFeeManagerTransactor) UpdateSubscriberGlobalDiscount(opts *bind.TransactOpts, subscriber common.Address, token common.Address, discount uint64) (*types.Transaction, error) { + return _DestinationFeeManager.contract.Transact(opts, "updateSubscriberGlobalDiscount", subscriber, token, discount) +} + +func (_DestinationFeeManager *DestinationFeeManagerSession) UpdateSubscriberGlobalDiscount(subscriber common.Address, token common.Address, discount uint64) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.UpdateSubscriberGlobalDiscount(&_DestinationFeeManager.TransactOpts, subscriber, token, discount) +} + +func (_DestinationFeeManager *DestinationFeeManagerTransactorSession) UpdateSubscriberGlobalDiscount(subscriber common.Address, token common.Address, discount uint64) (*types.Transaction, error) { + return _DestinationFeeManager.Contract.UpdateSubscriberGlobalDiscount(&_DestinationFeeManager.TransactOpts, subscriber, token, discount) +} + func (_DestinationFeeManager *DestinationFeeManagerTransactor) Withdraw(opts *bind.TransactOpts, assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) { return _DestinationFeeManager.contract.Transact(opts, "withdraw", assetAddress, recipient, quantity) } @@ -1700,6 +1734,8 @@ type DestinationFeeManagerInterface interface { Owner(opts *bind.CallOpts) (common.Address, error) + SGlobalDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (*big.Int, error) + SLinkDeficit(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) SNativeSurcharge(opts *bind.CallOpts) (*big.Int, error) @@ -1734,6 +1770,8 @@ type DestinationFeeManagerInterface interface { UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) + UpdateSubscriberGlobalDiscount(opts *bind.TransactOpts, subscriber common.Address, token common.Address, discount uint64) (*types.Transaction, error) + Withdraw(opts *bind.TransactOpts, assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) FilterDiscountApplied(opts *bind.FilterOpts, configDigest [][32]byte, subscriber []common.Address) (*DestinationFeeManagerDiscountAppliedIterator, error) diff --git a/core/gethwrappers/llo-feeds/generated/destination_reward_manager/destination_reward_manager.go b/core/gethwrappers/llo-feeds/generated/destination_reward_manager/destination_reward_manager.go index 989482fc0e..75ff7abe7e 100644 --- a/core/gethwrappers/llo-feeds/generated/destination_reward_manager/destination_reward_manager.go +++ b/core/gethwrappers/llo-feeds/generated/destination_reward_manager/destination_reward_manager.go @@ -42,7 +42,7 @@ type IDestinationRewardManagerFeePayment struct { var DestinationRewardManagerMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWeights\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"FeeManagerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIDestinationRewardManager.FeePayment[]\",\"name\":\"payments\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"RewardRecipientsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"RewardsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"addFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"poolIds\",\"type\":\"bytes32[]\"}],\"name\":\"claimRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endIndex\",\"type\":\"uint256\"}],\"name\":\"getAvailableRewardPoolIds\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_linkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"internalType\":\"structIDestinationRewardManager.FeePayment[]\",\"name\":\"payments\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"name\":\"onFeePaid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"recipients\",\"type\":\"address[]\"}],\"name\":\"payRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeManagerAddress\",\"type\":\"address\"}],\"name\":\"removeFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_feeManagerAddressList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_registeredPoolIds\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_rewardRecipientWeights\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_rewardRecipientWeightsSet\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_totalRewardRecipientFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_totalRewardRecipientFeesLastClaimedAmounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"updateRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b506040516200244c3803806200244c8339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b60805161224a62000202600039600081816103bb0152818161107601526112b1015261224a6000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c806360122608116100cd5780639604d05f11610081578063cd5f729211610066578063cd5f7292146103a3578063ea4b861b146103b6578063f2fde38b146103dd57600080fd5b80639604d05f1461035a578063b0d9fa191461039057600080fd5b80638115c9cc116100b25780638115c9cc146102dd5780638ac85a5c146102f05780638da5cb5b1461031b57600080fd5b806360122608146102aa57806379ba5097146102d557600080fd5b806339ee81e1116101245780634944832f116101095780634944832f146102615780634d32208414610274578063592562011461028757600080fd5b806339ee81e114610213578063472264751461024157600080fd5b806314060f231161015557806314060f23146101ae578063181f5a77146101c15780631f2d32c31461020057600080fd5b806301ffc9a7146101715780630f3c34d114610199575b600080fd5b61018461017f366004611b3d565b6103f0565b60405190151581526020015b60405180910390f35b6101ac6101a7366004611bfd565b610651565b005b6101ac6101bc366004611cef565b61065f565b604080518082018252601381527f5265776172644d616e6167657220312e302e3000000000000000000000000000602082015290516101909190611d5f565b6101ac61020e366004611dd9565b610821565b610233610221366004611df4565b60026020526000908152604090205481565b604051908152602001610190565b61025461024f366004611e0d565b610959565b6040516101909190611e40565b6101ac61026f366004611cef565b610ae3565b6101ac610282366004611e84565b610c2c565b610184610295366004611df4565b60056020526000908152604090205460ff1681565b6102336102b8366004611f03565b600360209081526000928352604080842090915290825290205481565b6101ac610d6b565b6101ac6102eb366004611dd9565b610e6d565b6102336102fe366004611f03565b600460209081526000928352604080842090915290825290205481565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610190565b610335610368366004611dd9565b60076020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6101ac61039e366004611f2f565b610f1f565b6102336103b1366004611df4565b6110df565b6103357f000000000000000000000000000000000000000000000000000000000000000081565b6101ac6103eb366004611dd9565b611100565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f0f3c34d100000000000000000000000000000000000000000000000000000000148061048357507fffffffff0000000000000000000000000000000000000000000000000000000082167f14060f2300000000000000000000000000000000000000000000000000000000145b806104cf57507fffffffff0000000000000000000000000000000000000000000000000000000082167f4944832f00000000000000000000000000000000000000000000000000000000145b8061051b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f4d32208400000000000000000000000000000000000000000000000000000000145b8061056757507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f2d32c300000000000000000000000000000000000000000000000000000000145b806105b357507fffffffff0000000000000000000000000000000000000000000000000000000082167f8115c9cc00000000000000000000000000000000000000000000000000000000145b806105ff57507fffffffff0000000000000000000000000000000000000000000000000000000082167f4722647500000000000000000000000000000000000000000000000000000000145b8061064b57507fffffffff0000000000000000000000000000000000000000000000000000000082167fb0d9fa1900000000000000000000000000000000000000000000000000000000145b92915050565b61065b3382611114565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906106ab57503360008181526007602052604090205473ffffffffffffffffffffffffffffffffffffffff1614155b156106e2576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081900361071d576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526005602052604090205460ff1615610766576040517f0afa7ee800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805460018181019092557ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01849055600084815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790556107e2838383670de0b6b3a76400006112df565b827f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe68383604051610814929190611f9b565b60405180910390a2505050565b6108296114b6565b73ffffffffffffffffffffffffffffffffffffffff8116610876576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81811660009081526007602052604090205416156108d5576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602090815260409182902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905590519182527fe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b4910160405180910390a150565b600654606090600081841161096e5783610970565b815b9050808511156109ac576040517fa22caccc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109b88683612032565b67ffffffffffffffff8111156109d0576109d0611b7f565b6040519080825280602002602001820160405280156109f9578160200160208202803683370190505b5090506000865b83811015610ad657600060068281548110610a1d57610a1d612045565b600091825260208083209091015480835260048252604080842073ffffffffffffffffffffffffffffffffffffffff8f16855290925291205490915015610ac5576000818152600260209081526040808320546003835281842073ffffffffffffffffffffffffffffffffffffffff8f168552909252909120548114610ac35781858580600101965081518110610ab657610ab6612045565b6020026020010181815250505b505b50610acf81612074565b9050610a00565b5090979650505050505050565b610aeb6114b6565b604080516001808252818301909252600091602080830190803683370190505090508381600081518110610b2157610b21612045565b6020026020010181815250506000805b83811015610bde576000858583818110610b4d57610b4d612045565b610b639260206040909202019081019150611dd9565b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902054909150610bc7878785818110610bab57610bab612045565b610bc19260206040909202019081019150611dd9565b86611114565b50929092019150610bd781612074565b9050610b31565b50610beb858585846112df565b847f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe68585604051610c1d929190611f9b565b60405180910390a25050505050565b82610c4c60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015610c9e57506000818152600460209081526040808320338452909152902054155b15610cd5576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001808252818301909252600091602080830190803683370190505090508481600081518110610d0b57610d0b612045565b60200260200101818152505060005b83811015610d6357610d52858583818110610d3757610d37612045565b9050602002016020810190610d4c9190611dd9565b83611114565b50610d5c81612074565b9050610d1a565b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610df1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e756114b6565b73ffffffffffffffffffffffffffffffffffffffff81811660009081526007602052604090205416610ed3576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260076020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b3360008181526007602052604090205473ffffffffffffffffffffffffffffffffffffffff1614610f7c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8381101561105b57848482818110610f9a57610f9a612045565b9050604002016020016020810190610fb291906120d4565b77ffffffffffffffffffffffffffffffffffffffffffffffff1660026000878785818110610fe257610fe2612045565b604090810292909201358352506020820192909252016000208054909101905584848281811061101457611014612045565b905060400201602001602081019061102c91906120d4565b77ffffffffffffffffffffffffffffffffffffffffffffffff16820191508061105490612074565b9050610f80565b5061109e73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016833084611539565b7fa1cc025ea76bacce5d740ee4bc331899375dc2c5f2ab33933aaacbd9ba001b668484846040516110d1939291906120ef565b60405180910390a150505050565b600681815481106110ef57600080fd5b600091825260209091200154905081565b6111086114b6565b6111118161161b565b50565b60008060005b835181101561129057600084828151811061113757611137612045565b6020026020010151905060006002600083815260200190815260200160002054905080600003611168575050611280565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b16808552908352818420548685526004845282852091855292528220549083039190670de0b6b3a7640000908302049050806000036111d15750505050611280565b600084815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d16808552925290912084905588519682019689908790811061121c5761121c612045565b60200260200101517f989969655bc1d593922527fe85d71347bb8e12fa423cc71f362dd8ef7cb10ef283604051611273919077ffffffffffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a3505050505b61128981612074565b905061111a565b5080156112d8576112d873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168583611710565b9392505050565b61133a8383808060200260200160405190810160405280939291908181526020016000905b828210156113305761132160408302860136819003810190612176565b81526020019060010190611304565b505050505061176b565b15611371576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8381101561147557600085858381811061139157611391612045565b90506040020160200160208101906113a991906121d1565b67ffffffffffffffff16905060008686848181106113c9576113c9612045565b6113df9260206040909202019081019150611dd9565b905073ffffffffffffffffffffffffffffffffffffffff811661142e576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff909416835292905220819055919091019061146e81612074565b9050611375565b508181146114af576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610de8565b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526116159085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611822565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361169a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610de8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526117669084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611593565b505050565b6000805b82518110156118195760006117858260016121ec565b90505b8351811015611810578381815181106117a3576117a3612045565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168483815181106117d7576117d7612045565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603611808575060019392505050565b600101611788565b5060010161176f565b50600092915050565b6000611884826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661192e9092919063ffffffff16565b80519091501561176657808060200190518101906118a291906121ff565b611766576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610de8565b606061193d8484600085611945565b949350505050565b6060824710156119d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610de8565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611a009190612221565b60006040518083038185875af1925050503d8060008114611a3d576040519150601f19603f3d011682016040523d82523d6000602084013e611a42565b606091505b5091509150611a5387838387611a5e565b979650505050505050565b60608315611af4578251600003611aed5773ffffffffffffffffffffffffffffffffffffffff85163b611aed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610de8565b508161193d565b61193d8383815115611b095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de89190611d5f565b600060208284031215611b4f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146112d857600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611bf557611bf5611b7f565b604052919050565b60006020808385031215611c1057600080fd5b823567ffffffffffffffff80821115611c2857600080fd5b818501915085601f830112611c3c57600080fd5b813581811115611c4e57611c4e611b7f565b8060051b9150611c5f848301611bae565b8181529183018401918481019088841115611c7957600080fd5b938501935b83851015611c9757843582529385019390850190611c7e565b98975050505050505050565b60008083601f840112611cb557600080fd5b50813567ffffffffffffffff811115611ccd57600080fd5b6020830191508360208260061b8501011115611ce857600080fd5b9250929050565b600080600060408486031215611d0457600080fd5b83359250602084013567ffffffffffffffff811115611d2257600080fd5b611d2e86828701611ca3565b9497909650939450505050565b60005b83811015611d56578181015183820152602001611d3e565b50506000910152565b6020815260008251806020840152611d7e816040850160208701611d3b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611dd457600080fd5b919050565b600060208284031215611deb57600080fd5b6112d882611db0565b600060208284031215611e0657600080fd5b5035919050565b600080600060608486031215611e2257600080fd5b611e2b84611db0565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015611e7857835183529284019291840191600101611e5c565b50909695505050505050565b600080600060408486031215611e9957600080fd5b83359250602084013567ffffffffffffffff80821115611eb857600080fd5b818601915086601f830112611ecc57600080fd5b813581811115611edb57600080fd5b8760208260051b8501011115611ef057600080fd5b6020830194508093505050509250925092565b60008060408385031215611f1657600080fd5b82359150611f2660208401611db0565b90509250929050565b600080600060408486031215611f4457600080fd5b833567ffffffffffffffff811115611f5b57600080fd5b611f6786828701611ca3565b9094509250611f7a905060208501611db0565b90509250925092565b803567ffffffffffffffff81168114611dd457600080fd5b6020808252818101839052600090604080840186845b87811015610ad65773ffffffffffffffffffffffffffffffffffffffff611fd783611db0565b16835267ffffffffffffffff611fee868401611f83565b16838601529183019190830190600101611fb1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561064b5761064b612003565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036120a5576120a5612003565b5060010190565b803577ffffffffffffffffffffffffffffffffffffffffffffffff81168114611dd457600080fd5b6000602082840312156120e657600080fd5b6112d8826120ac565b60408082528181018490526000908560608401835b8781101561214b5782358252602077ffffffffffffffffffffffffffffffffffffffffffffffff6121368286016120ac565b16908301529183019190830190600101612104565b5080935050505073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b60006040828403121561218857600080fd5b6040516040810181811067ffffffffffffffff821117156121ab576121ab611b7f565b6040526121b783611db0565b81526121c560208401611f83565b60208201529392505050565b6000602082840312156121e357600080fd5b6112d882611f83565b8082018082111561064b5761064b612003565b60006020828403121561221157600080fd5b815180151581146112d857600080fd5b60008251612233818460208701611d3b565b919091019291505056fea164736f6c6343000813000a", + Bin: "0x60a06040523480156200001157600080fd5b5060405162002205380380620022058339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b60805161200362000202600039600081816103fd01528181610e26015261106101526120036000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c806360122608116100cd5780639604d05f11610081578063cd5f729211610066578063cd5f7292146103e5578063ea4b861b146103f8578063f2fde38b1461041f57600080fd5b80639604d05f1461039c578063b0d9fa19146103d257600080fd5b80638115c9cc116100b25780638115c9cc1461031f5780638ac85a5c146103325780638da5cb5b1461035d57600080fd5b806360122608146102ec57806379ba50971461031757600080fd5b806339ee81e1116101245780634944832f116101095780634944832f146102a35780634d322084146102b657806359256201146102c957600080fd5b806339ee81e114610255578063472264751461028357600080fd5b806314060f231161015557806314060f23146101f0578063181f5a77146102035780631f2d32c31461024257600080fd5b806301ffc9a7146101715780630f3c34d1146101db575b600080fd5b6101c661017f3660046118ef565b7fffffffff00000000000000000000000000000000000000000000000000000000167f768ffd3a000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b6101ee6101e93660046119af565b610432565b005b6101ee6101fe366004611aa1565b610440565b604080518082018252601e81527f44657374696e6174696f6e5265776172644d616e6167657220302e342e300000602082015290516101d29190611b11565b6101ee610250366004611b8b565b610602565b610275610263366004611bad565b60026020526000908152604090205481565b6040519081526020016101d2565b610296610291366004611bc6565b61073a565b6040516101d29190611bf9565b6101ee6102b1366004611aa1565b6108c4565b6101ee6102c4366004611c3d565b610a0d565b6101c66102d7366004611bad565b60056020526000908152604090205460ff1681565b6102756102fa366004611cbc565b600360209081526000928352604080842090915290825290205481565b6101ee610b1b565b6101ee61032d366004611b8b565b610c1d565b610275610340366004611cbc565b600460209081526000928352604080842090915290825290205481565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6103776103aa366004611b8b565b60076020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6101ee6103e0366004611ce8565b610ccf565b6102756103f3366004611bad565b610e8f565b6103777f000000000000000000000000000000000000000000000000000000000000000081565b6101ee61042d366004611b8b565b610eb0565b61043c3382610ec4565b5050565b3360008181526007602052604090205473ffffffffffffffffffffffffffffffffffffffff161480159061048c575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156104c3576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008190036104fe576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526005602052604090205460ff1615610547576040517f0afa7ee800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805460018181019092557ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01849055600084815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790556105c3838383670de0b6b3a7640000611091565b827f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe683836040516105f5929190611d54565b60405180910390a2505050565b61060a611268565b73ffffffffffffffffffffffffffffffffffffffff8116610657576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81811660009081526007602052604090205416156106b6576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602090815260409182902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905590519182527fe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b4910160405180910390a150565b600654606090600081841161074f5783610751565b815b90508085111561078d576040517fa22caccc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107998683611deb565b67ffffffffffffffff8111156107b1576107b1611931565b6040519080825280602002602001820160405280156107da578160200160208202803683370190505b5090506000865b838110156108b7576000600682815481106107fe576107fe611dfe565b600091825260208083209091015480835260048252604080842073ffffffffffffffffffffffffffffffffffffffff8f168552909252912054909150156108a6576000818152600260209081526040808320546003835281842073ffffffffffffffffffffffffffffffffffffffff8f1685529092529091205481146108a4578185858060010196508151811061089757610897611dfe565b6020026020010181815250505b505b506108b081611e2d565b90506107e1565b5090979650505050505050565b6108cc611268565b60408051600180825281830190925260009160208083019080368337019050509050838160008151811061090257610902611dfe565b6020026020010181815250506000805b838110156109bf57600085858381811061092e5761092e611dfe565b6109449260206040909202019081019150611b8b565b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020549091506109a887878581811061098c5761098c611dfe565b6109a29260206040909202019081019150611b8b565b86610ec4565b509290920191506109b881611e2d565b9050610912565b506109cc85858584611091565b847f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe685856040516109fe929190611d54565b60405180910390a25050505050565b60008381526004602090815260408083203384529091529020548390158015610a4e575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15610a85576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001808252818301909252600091602080830190803683370190505090508481600081518110610abb57610abb611dfe565b60200260200101818152505060005b83811015610b1357610b02858583818110610ae757610ae7611dfe565b9050602002016020810190610afc9190611b8b565b83610ec4565b50610b0c81611e2d565b9050610aca565b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ba1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610c25611268565b73ffffffffffffffffffffffffffffffffffffffff81811660009081526007602052604090205416610c83576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260076020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b3360008181526007602052604090205473ffffffffffffffffffffffffffffffffffffffff1614610d2c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b83811015610e0b57848482818110610d4a57610d4a611dfe565b9050604002016020016020810190610d629190611e8d565b77ffffffffffffffffffffffffffffffffffffffffffffffff1660026000878785818110610d9257610d92611dfe565b6040908102929092013583525060208201929092520160002080549091019055848482818110610dc457610dc4611dfe565b9050604002016020016020810190610ddc9190611e8d565b77ffffffffffffffffffffffffffffffffffffffffffffffff168201915080610e0490611e2d565b9050610d30565b50610e4e73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168330846112eb565b7fa1cc025ea76bacce5d740ee4bc331899375dc2c5f2ab33933aaacbd9ba001b66848484604051610e8193929190611ea8565b60405180910390a150505050565b60068181548110610e9f57600080fd5b600091825260209091200154905081565b610eb8611268565b610ec1816113cd565b50565b60008060005b8351811015611040576000848281518110610ee757610ee7611dfe565b6020026020010151905060006002600083815260200190815260200160002054905080600003610f18575050611030565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b16808552908352818420548685526004845282852091855292528220549083039190670de0b6b3a764000090830204905080600003610f815750505050611030565b600084815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d168085529252909120849055885196820196899087908110610fcc57610fcc611dfe565b60200260200101517f989969655bc1d593922527fe85d71347bb8e12fa423cc71f362dd8ef7cb10ef283604051611023919077ffffffffffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a3505050505b61103981611e2d565b9050610eca565b5080156110885761108873ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001685836114c2565b90505b92915050565b6110ec8383808060200260200160405190810160405280939291908181526020016000905b828210156110e2576110d360408302860136819003810190611f2f565b815260200190600101906110b6565b505050505061151d565b15611123576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8381101561122757600085858381811061114357611143611dfe565b905060400201602001602081019061115b9190611f8a565b67ffffffffffffffff169050600086868481811061117b5761117b611dfe565b6111919260206040909202019081019150611b8b565b905073ffffffffffffffffffffffffffffffffffffffff81166111e0576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff909416835292905220819055919091019061122081611e2d565b9050611127565b50818114611261576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146112e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610b98565b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526113c79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526115d4565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361144c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610b98565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526115189084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611345565b505050565b6000805b82518110156115cb576000611537826001611fa5565b90505b83518110156115c25783818151811061155557611555611dfe565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1684838151811061158957611589611dfe565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036115ba575060019392505050565b60010161153a565b50600101611521565b50600092915050565b6000611636826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166116e09092919063ffffffff16565b80519091501561151857808060200190518101906116549190611fb8565b611518576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b98565b60606116ef84846000856116f7565b949350505050565b606082471015611789576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b98565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516117b29190611fda565b60006040518083038185875af1925050503d80600081146117ef576040519150601f19603f3d011682016040523d82523d6000602084013e6117f4565b606091505b509150915061180587838387611810565b979650505050505050565b606083156118a657825160000361189f5773ffffffffffffffffffffffffffffffffffffffff85163b61189f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b98565b50816116ef565b6116ef83838151156118bb5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b989190611b11565b60006020828403121561190157600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461108857600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156119a7576119a7611931565b604052919050565b600060208083850312156119c257600080fd5b823567ffffffffffffffff808211156119da57600080fd5b818501915085601f8301126119ee57600080fd5b813581811115611a0057611a00611931565b8060051b9150611a11848301611960565b8181529183018401918481019088841115611a2b57600080fd5b938501935b83851015611a4957843582529385019390850190611a30565b98975050505050505050565b60008083601f840112611a6757600080fd5b50813567ffffffffffffffff811115611a7f57600080fd5b6020830191508360208260061b8501011115611a9a57600080fd5b9250929050565b600080600060408486031215611ab657600080fd5b83359250602084013567ffffffffffffffff811115611ad457600080fd5b611ae086828701611a55565b9497909650939450505050565b60005b83811015611b08578181015183820152602001611af0565b50506000910152565b6020815260008251806020840152611b30816040850160208701611aed565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611b8657600080fd5b919050565b600060208284031215611b9d57600080fd5b611ba682611b62565b9392505050565b600060208284031215611bbf57600080fd5b5035919050565b600080600060608486031215611bdb57600080fd5b611be484611b62565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015611c3157835183529284019291840191600101611c15565b50909695505050505050565b600080600060408486031215611c5257600080fd5b83359250602084013567ffffffffffffffff80821115611c7157600080fd5b818601915086601f830112611c8557600080fd5b813581811115611c9457600080fd5b8760208260051b8501011115611ca957600080fd5b6020830194508093505050509250925092565b60008060408385031215611ccf57600080fd5b82359150611cdf60208401611b62565b90509250929050565b600080600060408486031215611cfd57600080fd5b833567ffffffffffffffff811115611d1457600080fd5b611d2086828701611a55565b9094509250611d33905060208501611b62565b90509250925092565b803567ffffffffffffffff81168114611b8657600080fd5b6020808252818101839052600090604080840186845b878110156108b75773ffffffffffffffffffffffffffffffffffffffff611d9083611b62565b16835267ffffffffffffffff611da7868401611d3c565b16838601529183019190830190600101611d6a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561108b5761108b611dbc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611e5e57611e5e611dbc565b5060010190565b803577ffffffffffffffffffffffffffffffffffffffffffffffff81168114611b8657600080fd5b600060208284031215611e9f57600080fd5b611ba682611e65565b60408082528181018490526000908560608401835b87811015611f045782358252602077ffffffffffffffffffffffffffffffffffffffffffffffff611eef828601611e65565b16908301529183019190830190600101611ebd565b5080935050505073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b600060408284031215611f4157600080fd5b6040516040810181811067ffffffffffffffff82111715611f6457611f64611931565b604052611f7083611b62565b8152611f7e60208401611d3c565b60208201529392505050565b600060208284031215611f9c57600080fd5b611ba682611d3c565b8082018082111561108b5761108b611dbc565b600060208284031215611fca57600080fd5b8151801515811461108857600080fd5b60008251611fec818460208701611aed565b919091019291505056fea164736f6c6343000813000a", } var DestinationRewardManagerABI = DestinationRewardManagerMetaData.ABI diff --git a/core/gethwrappers/llo-feeds/generated/destination_verifier/destination_verifier.go b/core/gethwrappers/llo-feeds/generated/destination_verifier/destination_verifier.go index 2fa48b7249..41ae715fe9 100644 --- a/core/gethwrappers/llo-feeds/generated/destination_verifier/destination_verifier.go +++ b/core/gethwrappers/llo-feeds/generated/destination_verifier/destination_verifier.go @@ -36,8 +36,8 @@ type CommonAddressAndWeight struct { } var DestinationVerifierMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierProxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadActivationTime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes24\",\"name\":\"donConfigId\",\"type\":\"bytes24\"}],\"name\":\"DonConfigAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DonConfigDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeeManagerInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"MismatchedSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerifierProxyInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessController\",\"type\":\"address\"}],\"name\":\"AccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes24\",\"name\":\"donConfigId\",\"type\":\"bytes24\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isActive\",\"type\":\"bool\"}],\"name\":\"ConfigActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes24\",\"name\":\"donConfigId\",\"type\":\"bytes24\"}],\"name\":\"ConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes24\",\"name\":\"donConfigId\",\"type\":\"bytes24\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldFeeManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManager\",\"type\":\"address\"}],\"name\":\"FeeManagerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"ReportVerified\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_verifierProxy\",\"outputs\":[{\"internalType\":\"contractIDestinationVerifierProxy\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"removeLatestConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_accessController\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessController\",\"type\":\"address\"}],\"name\":\"setAccessController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"donConfigIndex\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isActive\",\"type\":\"bool\"}],\"name\":\"setConfigActive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint32\",\"name\":\"activationTime\",\"type\":\"uint32\"}],\"name\":\"setConfigWithActivationTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeManager\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signedReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"signedReports\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verifyBulk\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b506040516200379d3803806200379d8339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b60805161359b62000202600039600081816102d70152818161062a0152611064015261359b6000f3fe6080604052600436106100f35760003560e01c80638da5cb5b1161008a578063d7c72e4e11610059578063d7c72e4e146102f9578063f08391d814610319578063f2fde38b14610339578063f9c7bf771461035957600080fd5b80638da5cb5b1461025857806394ba284614610283578063af4fed24146102b0578063b97455c7146102c557600080fd5b8063453ec61b116100c6578063453ec61b146101e1578063472d35b9146102035780635ad72fae1461022357806379ba50971461024357600080fd5b806301ffc9a7146100f8578063181f5a771461012d578063294d2bb11461017c57806338416b5b1461018f575b600080fd5b34801561010457600080fd5b50610118610113366004612622565b610379565b60405190151581526020015b60405180910390f35b34801561013957600080fd5b5060408051808201909152601981527f44657374696e6174696f6e566572696669657220312e302e300000000000000060208201525b60405161012491906126cf565b61016f61018a366004612754565b610626565b34801561019b57600080fd5b506004546101bc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b3480156101ed57600080fd5b506102016101fc3660046129e3565b610873565b005b34801561020f57600080fd5b5061020161021e366004612a57565b61097b565b34801561022f57600080fd5b5061020161023e366004612a80565b610c5c565b34801561024f57600080fd5b50610201610d72565b34801561026457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166101bc565b34801561028f57600080fd5b506005546101bc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102bc57600080fd5b50610201610e6f565b3480156102d157600080fd5b506101bc7f000000000000000000000000000000000000000000000000000000000000000081565b61030c610307366004612ab0565b611060565b6040516101249190612b33565b34801561032557600080fd5b50610201610334366004612a57565b611352565b34801561034557600080fd5b50610201610354366004612a57565b6113d9565b34801561036557600080fd5b50610201610374366004612bc5565b6113ed565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f294d2bb100000000000000000000000000000000000000000000000000000000148061040c57507fffffffff0000000000000000000000000000000000000000000000000000000082167fd7c72e4e00000000000000000000000000000000000000000000000000000000145b8061045857507fffffffff0000000000000000000000000000000000000000000000000000000082167f94ba284600000000000000000000000000000000000000000000000000000000145b806104a457507fffffffff0000000000000000000000000000000000000000000000000000000082167f38416b5b00000000000000000000000000000000000000000000000000000000145b806104f057507fffffffff0000000000000000000000000000000000000000000000000000000082167f453ec61b00000000000000000000000000000000000000000000000000000000145b8061053c57507fffffffff0000000000000000000000000000000000000000000000000000000082167ff9c7bf7700000000000000000000000000000000000000000000000000000000145b8061058857507fffffffff0000000000000000000000000000000000000000000000000000000082167f472d35b900000000000000000000000000000000000000000000000000000000145b806105d457507fffffffff0000000000000000000000000000000000000000000000000000000082167ff08391d800000000000000000000000000000000000000000000000000000000145b8061062057507fffffffff0000000000000000000000000000000000000000000000000000000082167f5ad72fae00000000000000000000000000000000000000000000000000000000145b92915050565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163314610697576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554829073ffffffffffffffffffffffffffffffffffffffff16801580159061075657506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf8906107139085906000903690600401612c95565b602060405180830381865afa158015610730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107549190612cce565b155b1561078d576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061079b8a8a886114ab565b600454919350915073ffffffffffffffffffffffffffffffffffffffff168015610864578073ffffffffffffffffffffffffffffffffffffffff166386968cfd34848e8e8e8e8e6040518863ffffffff1660e01b815260040161080396959493929190612ceb565b6000604051808303818588803b15801561081c57600080fd5b505af19350505050801561082e575060015b610864576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50909998505050505050505050565b82518260ff16806000036108b3576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8211156108fd576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044015b60405180910390fd5b610908816003612d71565b8211610960578161091a826003612d71565b610925906001612d88565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016108f4565b6109686119b0565b61097485858542611a33565b5050505050565b6109836119b0565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f86968cfd00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610a0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a319190612cce565b1580610ae857506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f3690750900000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610ac2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae69190612cce565b155b80610b9e57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527ff65df96200000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610b78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9c9190612cce565b155b15610bd5576040517f8238941900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f04628abcaa6b1674651352125cb94b65b289145bc2bc4d67720bb7d966372f0391015b60405180910390a15050565b610c646119b0565b6003548210610c9f576040517f5a0d6fe200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038381548110610cb457610cb4612d9b565b600091825260209182902001805484151579010000000000000000000000000000000000000000000000000081027fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff909216919091178083556040805191811b7fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000168252938101919091529092507f90186a1e77b498ec417ea88bd026cae00d7043c357cc45221777623bda582dd4910160405180910390a1505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610df3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108f4565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e776119b0565b600354600003610eb3576040517f5a0d6fe200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6003805460009190610ec790600190612dca565b81548110610ed757610ed7612d9b565b600091825260209182902060408051608081018252929091015480821b7fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001683527801000000000000000000000000000000000000000000000000810460ff9081169484019490945279010000000000000000000000000000000000000000000000000081049093161515908201527a01000000000000000000000000000000000000000000000000000090910463ffffffff166060820152600380549192509080610fa557610fa5612ddd565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffff00000000000000000000000000000000000000000000000000000000000016905501905580516040517f970fd8f3ebdd9a271080aacf9807a5c709be0b448e4047a6fc212b8cc165368d91611055917fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000091909116815260200190565b60405180910390a150565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1633146110d1576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554829073ffffffffffffffffffffffffffffffffffffffff16801580159061119057506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf89061114d9085906000903690600401612c95565b602060405180830381865afa15801561116a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118e9190612cce565b155b156111c7576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008767ffffffffffffffff8111156111e2576111e26127d5565b60405190808252806020026020018201604052801561121557816020015b60608152602001906001900390816112005790505b50905060008867ffffffffffffffff811115611233576112336127d5565b60405190808252806020026020018201604052801561125c578160200160208202803683370190505b50905060005b898110156112ee5760008061129a8d8d8581811061128257611282612d9b565b90506020028101906112949190612e0c565b8b6114ab565b91509150818584815181106112b1576112b1612d9b565b6020026020010181905250808484815181106112cf576112cf612d9b565b6020026020010181815250505050806112e790612e71565b9050611262565b5060045473ffffffffffffffffffffffffffffffffffffffff168015610864578073ffffffffffffffffffffffffffffffffffffffff16633690750934848e8e8e8e8e6040518863ffffffff1660e01b815260040161080396959493929190612ea9565b61135a6119b0565b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b69101610c50565b6113e16119b0565b6113ea816120eb565b50565b83518360ff168060000361142d576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115611472576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044016108f4565b61147d816003612d71565b821161148f578161091a826003612d71565b6114976119b0565b6114a386868686611a33565b505050505050565b6060600080808080806114c0898b018b6130db565b94509450945094509450815183511461151257825182516040517ff0d31408000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016108f4565b825160000361154d576040517fc7af40f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008480519060200120866040516020016115699291906131b6565b6040516020818303038152906040528051906020012090506000845167ffffffffffffffff81111561159d5761159d6127d5565b6040519080825280602002602001820160405280156115c6578160200160208202803683370190505b50905060005b85518110156116d4576001838583602081106115ea576115ea612d9b565b6115f791901a601b6131f2565b88848151811061160957611609612d9b565b602002602001015188858151811061162357611623612d9b565b602002602001015160405160008152602001604052604051611661949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611683573d6000803e3d6000fd5b5050506020604051035182828151811061169f5761169f612d9b565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526116cd81612e71565b90506115cc565b506116de816121e0565b15611715576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006117208761228f565b9050600061172d826122b5565b80519091507fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001661178a576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80604001516117c5576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015160ff16835111611806576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b84518110156119245784818151811061182557611825612d9b565b6020026020010151836000015160405160200161189592919060609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001682527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166014820152602c0190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600290935291205490925060ff16611914576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61191d81612e71565b905061180a565b5061192e8961320b565b60405173ffffffffffffffffffffffffffffffffffffffff8f1681527f58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc59060200160405180910390a25051969d7fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009097169c50959a5050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108f4565b565b83518360ff1680600003611a73576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115611ab8576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044016108f4565b611ac3816003612d71565b8211611ad5578161091a826003612d71565b611add6119b0565b611ae6866121e0565b15611b1d576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b428363ffffffff161115611b5d576040517f0114c7e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b7686600060018951611b719190612dca565b61243a565b60008686604051602001611b8b929190613250565b60405160208183030381529060405280519060200120905060005b8751811015611d3257600073ffffffffffffffffffffffffffffffffffffffff16888281518110611bd957611bd9612d9b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611c2e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600260008a8481518110611c4657611c46612d9b565b602002602001015185604051602001611cb292919060609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001682527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166014820152602c0190565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291815281516020928301208352908201929092520160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055611d2b81612e71565b9050611ba6565b506003548015801590611d96575063ffffffff85166003611d54600184612dca565b81548110611d6457611d64612d9b565b6000918252602090912001547a010000000000000000000000000000000000000000000000000000900463ffffffff16115b15611dcd576040517f0114c7e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081118015611e4b57507fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000082166003611e08600184612dca565b81548110611e1857611e18612d9b565b60009182526020909120015460401b7fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016145b15611ea6576040517fc0178c860000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000831660048201526024016108f4565b855115611f3757600480546040517ff65df96200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169163f65df96291611f049186918b910161332e565b600060405180830381600087803b158015611f1e57600080fd5b505af1158015611f32573d6000803e3d6000fd5b505050505b604080516080810182527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000841680825260ff808b1660208401908152600184860181815263ffffffff808d166060880190815260038054948501815560005296517fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b90930180549451925197519091167a010000000000000000000000000000000000000000000000000000027fffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffff97151579010000000000000000000000000000000000000000000000000002979097167fffff0000000000ffffffffffffffffffffffffffffffffffffffffffffffffff929095167801000000000000000000000000000000000000000000000000027fffffffffffffff0000000000000000000000000000000000000000000000000090941692881c929092179290921791909116919091179290921790915590517f2d763a674a99583454a287d792819ffb9ff7e791c23e7745a082701136ce336c906120d9908b908b908b90613371565b60405180910390a25050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361216a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108f4565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000805b82518110156122865760006121fa826001612d88565b90505b835181101561227d5783818151811061221857612218612d9b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1684838151811061224857612248612d9b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603612275575060019392505050565b6001016121fd565b506001016121e4565b50600092915050565b600080828060200190518101906122a691906133dd565b63ffffffff1695945050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091526003545b80156124335761231081613420565b9050836003828154811061232657612326612d9b565b6000918252602090912001547a010000000000000000000000000000000000000000000000000000900463ffffffff161161242e576003818154811061236e5761236e612d9b565b600091825260209182902060408051608081018252929091015480821b7fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001683527801000000000000000000000000000000000000000000000000810460ff9081169484019490945279010000000000000000000000000000000000000000000000000081049093161515908201527a01000000000000000000000000000000000000000000000000000090910463ffffffff1660608201529150612433565b612301565b5092915050565b818180820361244a575050505050565b60008560026124598787613455565b6124639190613475565b61246d9087613504565b8151811061247d5761247d612d9b565b602002602001015190505b8183136125fc575b8073ffffffffffffffffffffffffffffffffffffffff168684815181106124b9576124b9612d9b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610156124ef57826124e78161352c565b935050612490565b85828151811061250157612501612d9b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16101561254e57816125468161355d565b9250506124ef565b8183136125f75785828151811061256757612567612d9b565b602002602001015186848151811061258157612581612d9b565b602002602001015187858151811061259b5761259b612d9b565b602002602001018885815181106125b4576125b4612d9b565b73ffffffffffffffffffffffffffffffffffffffff938416602091820292909201015291169052826125e58161352c565b93505081806125f39061355d565b9250505b612488565b8185121561260f5761260f86868461243a565b838312156114a3576114a386848661243a565b60006020828403121561263457600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461266457600080fd5b9392505050565b6000815180845260005b8181101561269157602081850181015186830182015201612675565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000612664602083018461266b565b60008083601f8401126126f457600080fd5b50813567ffffffffffffffff81111561270c57600080fd5b60208301915083602082850101111561272457600080fd5b9250929050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461274f57600080fd5b919050565b60008060008060006060868803121561276c57600080fd5b853567ffffffffffffffff8082111561278457600080fd5b61279089838a016126e2565b909750955060208801359150808211156127a957600080fd5b506127b6888289016126e2565b90945092506127c990506040870161272b565b90509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612827576128276127d5565b60405290565b6040516060810167ffffffffffffffff81118282101715612827576128276127d5565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612897576128976127d5565b604052919050565b600067ffffffffffffffff8211156128b9576128b96127d5565b5060051b60200190565b600082601f8301126128d457600080fd5b813560206128e96128e48361289f565b612850565b82815260059290921b8401810191818101908684111561290857600080fd5b8286015b8481101561292a5761291d8161272b565b835291830191830161290c565b509695505050505050565b803560ff8116811461274f57600080fd5b600082601f83011261295757600080fd5b813560206129676128e48361289f565b82815260069290921b8401810191818101908684111561298657600080fd5b8286015b8481101561292a57604081890312156129a35760008081fd5b6129ab612804565b6129b48261272b565b81528482013567ffffffffffffffff811681146129d15760008081fd5b8186015283529183019160400161298a565b6000806000606084860312156129f857600080fd5b833567ffffffffffffffff80821115612a1057600080fd5b612a1c878388016128c3565b9450612a2a60208701612935565b93506040860135915080821115612a4057600080fd5b50612a4d86828701612946565b9150509250925092565b600060208284031215612a6957600080fd5b6126648261272b565b80151581146113ea57600080fd5b60008060408385031215612a9357600080fd5b823591506020830135612aa581612a72565b809150509250929050565b600080600080600060608688031215612ac857600080fd5b853567ffffffffffffffff80821115612ae057600080fd5b818801915088601f830112612af457600080fd5b813581811115612b0357600080fd5b8960208260051b8501011115612b1857600080fd5b6020928301975095509087013590808211156127a957600080fd5b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612ba6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452612b9485835161266b565b94509285019290850190600101612b5a565b5092979650505050505050565b63ffffffff811681146113ea57600080fd5b60008060008060808587031215612bdb57600080fd5b843567ffffffffffffffff80821115612bf357600080fd5b612bff888389016128c3565b9550612c0d60208801612935565b94506040870135915080821115612c2357600080fd5b50612c3087828801612946565b9250506060850135612c4181612bb3565b939692955090935050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff84168152604060208201526000612cc5604083018486612c4c565b95945050505050565b600060208284031215612ce057600080fd5b815161266481612a72565b868152608060208201526000612d05608083018789612c4c565b8281036040840152612d18818688612c4c565b91505073ffffffffffffffffffffffffffffffffffffffff83166060830152979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761062057610620612d42565b8082018082111561062057610620612d42565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561062057610620612d42565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612e4157600080fd5b83018035915067ffffffffffffffff821115612e5c57600080fd5b60200191503681900382131561272457600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612ea257612ea2612d42565b5060010190565b6080808252875190820181905260009060209060a0840190828b01845b82811015612ee257815184529284019290840190600101612ec6565b50505083810382850152878152818101600589901b820183018a60005b8b811015612faa577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085840301845281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18e3603018112612f6057600080fd5b8d01868101903567ffffffffffffffff811115612f7c57600080fd5b803603821315612f8b57600080fd5b612f96858284612c4c565b958801959450505090850190600101612eff565b50508581036040870152612fbf81898b612c4c565b945050505050612fe7606083018473ffffffffffffffffffffffffffffffffffffffff169052565b979650505050505050565b600082601f83011261300357600080fd5b813567ffffffffffffffff81111561301d5761301d6127d5565b61304e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612850565b81815284602083860101111561306357600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261309157600080fd5b813560206130a16128e48361289f565b82815260059290921b840181019181810190868411156130c057600080fd5b8286015b8481101561292a57803583529183019183016130c4565b600080600080600060e086880312156130f357600080fd5b86601f87011261310257600080fd5b61310a61282d565b80606088018981111561311c57600080fd5b885b8181101561313657803584526020938401930161311e565b5090965035905067ffffffffffffffff8082111561315357600080fd5b61315f89838a01612ff2565b9550608088013591508082111561317557600080fd5b61318189838a01613080565b945060a088013591508082111561319757600080fd5b506131a488828901613080565b9598949750929560c001359392505050565b828152600060208083018460005b60038110156131e1578151835291830191908301906001016131c4565b505050506080820190509392505050565b60ff818116838216019081111561062057610620612d42565b8051602080830151919081101561324a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b825160009082906020808701845b8381101561329057815173ffffffffffffffffffffffffffffffffffffffff168552938201939082019060010161325e565b5050505060f89390931b7fff000000000000000000000000000000000000000000000000000000000000001683525050600101919050565b600081518084526020808501945080840160005b83811015613323578151805173ffffffffffffffffffffffffffffffffffffffff16885283015167ffffffffffffffff1683880152604090960195908201906001016132dc565b509495945050505050565b7fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000008316815260406020820152600061336960408301846132c8565b949350505050565b606080825284519082018190526000906020906080840190828801845b828110156133c057815173ffffffffffffffffffffffffffffffffffffffff168452928401929084019060010161338e565b50505060ff8616828501528381036040850152612fe781866132c8565b6000806000606084860312156133f257600080fd5b83519250602084015161340481612bb3565b604085015190925061341581612bb3565b809150509250925092565b60008161342f5761342f612d42565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b818103600083128015838313168383128216171561243357612433612d42565b6000826134ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156134ff576134ff612d42565b500590565b808201828112600083128015821682158216171561352457613524612d42565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612ea257612ea2612d42565b60007f8000000000000000000000000000000000000000000000000000000000000000820361342f5761342f612d4256fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierProxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadActivationTime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes24\",\"name\":\"donConfigId\",\"type\":\"bytes24\"}],\"name\":\"DonConfigAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DonConfigDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeeManagerInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"MismatchedSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessController\",\"type\":\"address\"}],\"name\":\"AccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes24\",\"name\":\"donConfigId\",\"type\":\"bytes24\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isActive\",\"type\":\"bool\"}],\"name\":\"ConfigActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes24\",\"name\":\"donConfigId\",\"type\":\"bytes24\"}],\"name\":\"ConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes24\",\"name\":\"donConfigId\",\"type\":\"bytes24\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"donConfigIndex\",\"type\":\"uint16\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldFeeManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManager\",\"type\":\"address\"}],\"name\":\"FeeManagerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"ReportVerified\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_verifierProxy\",\"outputs\":[{\"internalType\":\"contractIDestinationVerifierProxy\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"removeLatestConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_accessController\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessController\",\"type\":\"address\"}],\"name\":\"setAccessController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"donConfigIndex\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isActive\",\"type\":\"bool\"}],\"name\":\"setConfigActive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint32\",\"name\":\"activationTime\",\"type\":\"uint32\"}],\"name\":\"setConfigWithActivationTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeManager\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signedReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"signedReports\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verifyBulk\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b50604051620033d8380380620033d88339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b6080516131d662000202600039600081816102d7015281816104160152610ce201526131d66000f3fe6080604052600436106100f35760003560e01c80638da5cb5b1161008a578063d7c72e4e11610059578063d7c72e4e146102f9578063f08391d814610319578063f2fde38b14610339578063f9c7bf771461035957600080fd5b80638da5cb5b1461025857806394ba284614610283578063af4fed24146102b0578063b97455c7146102c557600080fd5b8063453ec61b116100c6578063453ec61b146101e1578063472d35b9146102035780635ad72fae1461022357806379ba50971461024357600080fd5b806301ffc9a7146100f8578063181f5a771461012d578063294d2bb11461017c57806338416b5b1461018f575b600080fd5b34801561010457600080fd5b50610118610113366004612246565b610379565b60405190151581526020015b60405180910390f35b34801561013957600080fd5b5060408051808201909152601981527f44657374696e6174696f6e566572696669657220302e342e300000000000000060208201525b60405161012491906122f3565b61016f61018a366004612378565b610412565b34801561019b57600080fd5b506004546101bc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b3480156101ed57600080fd5b506102016101fc366004612607565b61065f565b005b34801561020f57600080fd5b5061020161021e36600461267b565b610767565b34801561022f57600080fd5b5061020161023e3660046126a4565b6108da565b34801561024f57600080fd5b506102016109f0565b34801561026457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166101bc565b34801561028f57600080fd5b506005546101bc9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102bc57600080fd5b50610201610aed565b3480156102d157600080fd5b506101bc7f000000000000000000000000000000000000000000000000000000000000000081565b61030c6103073660046126d4565b610cde565b6040516101249190612757565b34801561032557600080fd5b5061020161033436600461267b565b610fd0565b34801561034557600080fd5b5061020161035436600461267b565b611057565b34801561036557600080fd5b506102016103743660046127e9565b61106b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167ffecf1f8700000000000000000000000000000000000000000000000000000000148061040c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f527146e200000000000000000000000000000000000000000000000000000000145b92915050565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163314610483576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554829073ffffffffffffffffffffffffffffffffffffffff16801580159061054257506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf8906104ff90859060009036906004016128b9565b602060405180830381865afa15801561051c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054091906128f2565b155b15610579576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806105878a8a88611129565b600454919350915073ffffffffffffffffffffffffffffffffffffffff168015610650578073ffffffffffffffffffffffffffffffffffffffff166386968cfd34848e8e8e8e8e6040518863ffffffff1660e01b81526004016105ef9695949392919061290f565b6000604051808303818588803b15801561060857600080fd5b505af19350505050801561061a575060015b610650576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50909998505050505050505050565b82518260ff168060000361069f576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8211156106e9576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044015b60405180910390fd5b6106f4816003612995565b821161074c5781610706826003612995565b6107119060016129ac565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016106e0565b61075461162e565b610760858585426116b1565b5050505050565b61076f61162e565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f465b009600000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156107f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081d91906128f2565b610853576040517f8238941900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f04628abcaa6b1674651352125cb94b65b289145bc2bc4d67720bb7d966372f0391015b60405180910390a15050565b6108e261162e565b600354821061091d576040517f5a0d6fe200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038381548110610932576109326129bf565b600091825260209182902001805484151579010000000000000000000000000000000000000000000000000081027fffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff909216919091178083556040805191811b7fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000168252938101919091529092507f90186a1e77b498ec417ea88bd026cae00d7043c357cc45221777623bda582dd4910160405180910390a1505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106e0565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610af561162e565b600354600003610b31576040517f5a0d6fe200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6003805460009190610b45906001906129ee565b81548110610b5557610b556129bf565b600091825260209182902060408051608081018252929091015480821b7fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001683527801000000000000000000000000000000000000000000000000810460ff9081169484019490945279010000000000000000000000000000000000000000000000000081049093161515908201527a01000000000000000000000000000000000000000000000000000090910463ffffffff166060820152600380549192509080610c2357610c23612a01565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffff00000000000000000000000000000000000000000000000000000000000016905501905580516040517f970fd8f3ebdd9a271080aacf9807a5c709be0b448e4047a6fc212b8cc165368d91610cd3917fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000091909116815260200190565b60405180910390a150565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163314610d4f576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554829073ffffffffffffffffffffffffffffffffffffffff168015801590610e0e57506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890610dcb90859060009036906004016128b9565b602060405180830381865afa158015610de8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0c91906128f2565b155b15610e45576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008767ffffffffffffffff811115610e6057610e606123f9565b604051908082528060200260200182016040528015610e9357816020015b6060815260200190600190039081610e7e5790505b50905060008867ffffffffffffffff811115610eb157610eb16123f9565b604051908082528060200260200182016040528015610eda578160200160208202803683370190505b50905060005b89811015610f6c57600080610f188d8d85818110610f0057610f006129bf565b9050602002810190610f129190612a30565b8b611129565b9150915081858481518110610f2f57610f2f6129bf565b602002602001018190525080848481518110610f4d57610f4d6129bf565b602002602001018181525050505080610f6590612a95565b9050610ee0565b5060045473ffffffffffffffffffffffffffffffffffffffff168015610650578073ffffffffffffffffffffffffffffffffffffffff16633690750934848e8e8e8e8e6040518863ffffffff1660e01b81526004016105ef96959493929190612acd565b610fd861162e565b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b691016108ce565b61105f61162e565b61106881611d0f565b50565b83518360ff16806000036110ab576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8211156110f0576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044016106e0565b6110fb816003612995565b821161110d5781610706826003612995565b61111561162e565b611121868686866116b1565b505050505050565b60606000808080808061113e898b018b612cff565b94509450945094509450815183511461119057825182516040517ff0d31408000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016106e0565b82516000036111cb576040517fc7af40f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008480519060200120866040516020016111e7929190612dda565b6040516020818303038152906040528051906020012090506000845167ffffffffffffffff81111561121b5761121b6123f9565b604051908082528060200260200182016040528015611244578160200160208202803683370190505b50905060005b855181101561135257600183858360208110611268576112686129bf565b61127591901a601b612e16565b888481518110611287576112876129bf565b60200260200101518885815181106112a1576112a16129bf565b6020026020010151604051600081526020016040526040516112df949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611301573d6000803e3d6000fd5b5050506020604051035182828151811061131d5761131d6129bf565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015261134b81612a95565b905061124a565b5061135c81611e04565b15611393576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061139e87611eb3565b905060006113ab82611ed9565b80519091507fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016611408576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060400151611443576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015160ff16835111611484576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b84518110156115a2578481815181106114a3576114a36129bf565b6020026020010151836000015160405160200161151392919060609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001682527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166014820152602c0190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600290935291205490925060ff16611592576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61159b81612a95565b9050611488565b506115ac89612e2f565b60405173ffffffffffffffffffffffffffffffffffffffff8f1681527f58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc59060200160405180910390a25051969d7fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009097169c50959a5050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146116af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106e0565b565b6116ba84611e04565b156116f1576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b428163ffffffff161115611731576040517f0114c7e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61174a8460006001875161174591906129ee565b61205e565b6000848460405160200161175f929190612e74565b60405160208183030381529060405280519060200120905060005b855181101561190657600073ffffffffffffffffffffffffffffffffffffffff168682815181106117ad576117ad6129bf565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611802576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016002600088848151811061181a5761181a6129bf565b60200260200101518560405160200161188692919060609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001682527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166014820152602c0190565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291815281516020928301208352908201929092520160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556118ff81612a95565b905061177a565b50600354801580159061196b575063ffffffff831660036119286001846129ee565b81548110611938576119386129bf565b6000918252602090912001547a010000000000000000000000000000000000000000000000000000900463ffffffff1610155b156119a2576040517f0114c7e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081118015611a2057507fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000821660036119dd6001846129ee565b815481106119ed576119ed6129bf565b60009182526020909120015460401b7fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016145b15611a7b576040517fc0178c860000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000831660048201526024016106e0565b835115611b5b5760045473ffffffffffffffffffffffffffffffffffffffff16611ad1576040517f8238941900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480546040517ff65df96200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169163f65df96291611b28918691899101612f52565b600060405180830381600087803b158015611b4257600080fd5b505af1158015611b56573d6000803e3d6000fd5b505050505b604080516080810182527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000841680825260ff80891660208401908152600184860181815263ffffffff808b166060880190815260038054948501815560005296517fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b90930180549451925197519091167a010000000000000000000000000000000000000000000000000000027fffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffff97151579010000000000000000000000000000000000000000000000000002979097167fffff0000000000ffffffffffffffffffffffffffffffffffffffffffffffffff929095167801000000000000000000000000000000000000000000000000027fffffffffffffff0000000000000000000000000000000000000000000000000090941692881c929092179290921791909116919091179290921790915590517fa7d03f81dd1c1d8a55355fd71e1221d5959b7d9fb171fbb6389f207f63598fa590611cff908990899089908790612f95565b60405180910390a2505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611d8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106e0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000805b8251811015611eaa576000611e1e8260016129ac565b90505b8351811015611ea157838181518110611e3c57611e3c6129bf565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16848381518110611e6c57611e6c6129bf565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611e99575060019392505050565b600101611e21565b50600101611e08565b50600092915050565b60008082806020019051810190611eca9190613018565b63ffffffff1695945050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091526003545b801561205757611f348161305b565b90508360038281548110611f4a57611f4a6129bf565b6000918252602090912001547a010000000000000000000000000000000000000000000000000000900463ffffffff16116120525760038181548110611f9257611f926129bf565b600091825260209182902060408051608081018252929091015480821b7fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001683527801000000000000000000000000000000000000000000000000810460ff9081169484019490945279010000000000000000000000000000000000000000000000000081049093161515908201527a01000000000000000000000000000000000000000000000000000090910463ffffffff1660608201529150612057565b611f25565b5092915050565b818180820361206e575050505050565b600085600261207d8787613090565b61208791906130b0565b612091908761313f565b815181106120a1576120a16129bf565b602002602001015190505b818313612220575b8073ffffffffffffffffffffffffffffffffffffffff168684815181106120dd576120dd6129bf565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161015612113578261210b81613167565b9350506120b4565b858281518110612125576121256129bf565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161015612172578161216a81613198565b925050612113565b81831361221b5785828151811061218b5761218b6129bf565b60200260200101518684815181106121a5576121a56129bf565b60200260200101518785815181106121bf576121bf6129bf565b602002602001018885815181106121d8576121d86129bf565b73ffffffffffffffffffffffffffffffffffffffff9384166020918202929092010152911690528261220981613167565b935050818061221790613198565b9250505b6120ac565b818512156122335761223386868461205e565b838312156111215761112186848661205e565b60006020828403121561225857600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461228857600080fd5b9392505050565b6000815180845260005b818110156122b557602081850181015186830182015201612299565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000612288602083018461228f565b60008083601f84011261231857600080fd5b50813567ffffffffffffffff81111561233057600080fd5b60208301915083602082850101111561234857600080fd5b9250929050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461237357600080fd5b919050565b60008060008060006060868803121561239057600080fd5b853567ffffffffffffffff808211156123a857600080fd5b6123b489838a01612306565b909750955060208801359150808211156123cd57600080fd5b506123da88828901612306565b90945092506123ed90506040870161234f565b90509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561244b5761244b6123f9565b60405290565b6040516060810167ffffffffffffffff8111828210171561244b5761244b6123f9565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156124bb576124bb6123f9565b604052919050565b600067ffffffffffffffff8211156124dd576124dd6123f9565b5060051b60200190565b600082601f8301126124f857600080fd5b8135602061250d612508836124c3565b612474565b82815260059290921b8401810191818101908684111561252c57600080fd5b8286015b8481101561254e576125418161234f565b8352918301918301612530565b509695505050505050565b803560ff8116811461237357600080fd5b600082601f83011261257b57600080fd5b8135602061258b612508836124c3565b82815260069290921b840181019181810190868411156125aa57600080fd5b8286015b8481101561254e57604081890312156125c75760008081fd5b6125cf612428565b6125d88261234f565b81528482013567ffffffffffffffff811681146125f55760008081fd5b818601528352918301916040016125ae565b60008060006060848603121561261c57600080fd5b833567ffffffffffffffff8082111561263457600080fd5b612640878388016124e7565b945061264e60208701612559565b9350604086013591508082111561266457600080fd5b506126718682870161256a565b9150509250925092565b60006020828403121561268d57600080fd5b6122888261234f565b801515811461106857600080fd5b600080604083850312156126b757600080fd5b8235915060208301356126c981612696565b809150509250929050565b6000806000806000606086880312156126ec57600080fd5b853567ffffffffffffffff8082111561270457600080fd5b818801915088601f83011261271857600080fd5b81358181111561272757600080fd5b8960208260051b850101111561273c57600080fd5b6020928301975095509087013590808211156123cd57600080fd5b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156127ca577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526127b885835161228f565b9450928501929085019060010161277e565b5092979650505050505050565b63ffffffff8116811461106857600080fd5b600080600080608085870312156127ff57600080fd5b843567ffffffffffffffff8082111561281757600080fd5b612823888389016124e7565b955061283160208801612559565b9450604087013591508082111561284757600080fd5b506128548782880161256a565b9250506060850135612865816127d7565b939692955090935050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff841681526040602082015260006128e9604083018486612870565b95945050505050565b60006020828403121561290457600080fd5b815161228881612696565b868152608060208201526000612929608083018789612870565b828103604084015261293c818688612870565b91505073ffffffffffffffffffffffffffffffffffffffff83166060830152979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761040c5761040c612966565b8082018082111561040c5761040c612966565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561040c5761040c612966565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612a6557600080fd5b83018035915067ffffffffffffffff821115612a8057600080fd5b60200191503681900382131561234857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612ac657612ac6612966565b5060010190565b6080808252875190820181905260009060209060a0840190828b01845b82811015612b0657815184529284019290840190600101612aea565b50505083810382850152878152818101600589901b820183018a60005b8b811015612bce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085840301845281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18e3603018112612b8457600080fd5b8d01868101903567ffffffffffffffff811115612ba057600080fd5b803603821315612baf57600080fd5b612bba858284612870565b958801959450505090850190600101612b23565b50508581036040870152612be381898b612870565b945050505050612c0b606083018473ffffffffffffffffffffffffffffffffffffffff169052565b979650505050505050565b600082601f830112612c2757600080fd5b813567ffffffffffffffff811115612c4157612c416123f9565b612c7260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612474565b818152846020838601011115612c8757600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f830112612cb557600080fd5b81356020612cc5612508836124c3565b82815260059290921b84018101918181019086841115612ce457600080fd5b8286015b8481101561254e5780358352918301918301612ce8565b600080600080600060e08688031215612d1757600080fd5b86601f870112612d2657600080fd5b612d2e612451565b806060880189811115612d4057600080fd5b885b81811015612d5a578035845260209384019301612d42565b5090965035905067ffffffffffffffff80821115612d7757600080fd5b612d8389838a01612c16565b95506080880135915080821115612d9957600080fd5b612da589838a01612ca4565b945060a0880135915080821115612dbb57600080fd5b50612dc888828901612ca4565b9598949750929560c001359392505050565b828152600060208083018460005b6003811015612e0557815183529183019190830190600101612de8565b505050506080820190509392505050565b60ff818116838216019081111561040c5761040c612966565b80516020808301519190811015612e6e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b825160009082906020808701845b83811015612eb457815173ffffffffffffffffffffffffffffffffffffffff1685529382019390820190600101612e82565b5050505060f89390931b7fff000000000000000000000000000000000000000000000000000000000000001683525050600101919050565b600081518084526020808501945080840160005b83811015612f47578151805173ffffffffffffffffffffffffffffffffffffffff16885283015167ffffffffffffffff168388015260409096019590820190600101612f00565b509495945050505050565b7fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168152604060208201526000612f8d6040830184612eec565b949350505050565b6080808252855190820181905260009060209060a0840190828901845b82811015612fe457815173ffffffffffffffffffffffffffffffffffffffff1684529284019290840190600101612fb2565b50505060ff87168285015283810360408501526130018187612eec565b9250505061ffff8316606083015295945050505050565b60008060006060848603121561302d57600080fd5b83519250602084015161303f816127d7565b6040850151909250613050816127d7565b809150509250925092565b60008161306a5761306a612966565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b818103600083128015838313168383128216171561205757612057612966565b6000826130e6577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561313a5761313a612966565b500590565b808201828112600083128015821682158216171561315f5761315f612966565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612ac657612ac6612966565b60007f8000000000000000000000000000000000000000000000000000000000000000820361306a5761306a61296656fea164736f6c6343000813000a", } var DestinationVerifierABI = DestinationVerifierMetaData.ABI @@ -846,6 +846,7 @@ type DestinationVerifierConfigSet struct { Signers []common.Address F uint8 RecipientAddressesAndWeights []CommonAddressAndWeight + DonConfigIndex uint16 Raw types.Log } @@ -1466,7 +1467,7 @@ func (DestinationVerifierConfigRemoved) Topic() common.Hash { } func (DestinationVerifierConfigSet) Topic() common.Hash { - return common.HexToHash("0x2d763a674a99583454a287d792819ffb9ff7e791c23e7745a082701136ce336c") + return common.HexToHash("0xa7d03f81dd1c1d8a55355fd71e1221d5959b7d9fb171fbb6389f207f63598fa5") } func (DestinationVerifierFeeManagerSet) Topic() common.Hash { diff --git a/core/gethwrappers/llo-feeds/generated/destination_verifier_proxy/destination_verifier_proxy.go b/core/gethwrappers/llo-feeds/generated/destination_verifier_proxy/destination_verifier_proxy.go index a2ae546d9b..7111fc7763 100644 --- a/core/gethwrappers/llo-feeds/generated/destination_verifier_proxy/destination_verifier_proxy.go +++ b/core/gethwrappers/llo-feeds/generated/destination_verifier_proxy/destination_verifier_proxy.go @@ -32,7 +32,7 @@ var ( var DestinationVerifierProxyMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_accessController\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"setVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"}],\"name\":\"verifyBulk\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"verifiedReports\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61130b806101576000396000f3fe6080604052600436106100b15760003560e01c80638da5cb5b11610069578063f2fde38b1161004e578063f2fde38b146101eb578063f7e83aee1461020b578063f873a61c1461021e57600080fd5b80638da5cb5b146101ab57806394ba2846146101d657600080fd5b806338416b5b1161009a57806338416b5b1461013a5780635437988d1461017457806379ba50971461019657600080fd5b806301ffc9a7146100b6578063181f5a77146100eb575b600080fd5b3480156100c257600080fd5b506100d66100d1366004610c56565b61023e565b60405190151581526020015b60405180910390f35b3480156100f757600080fd5b5060408051808201909152601e81527f44657374696e6174696f6e566572696669657250726f787920312e302e30000060208201525b6040516100e29190610d0d565b34801561014657600080fd5b5061014f6103bb565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e2565b34801561018057600080fd5b5061019461018f366004610d42565b610454565b005b3480156101a257600080fd5b506101946107c8565b3480156101b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661014f565b3480156101e257600080fd5b5061014f6108c5565b3480156101f757600080fd5b50610194610206366004610d42565b610935565b61012d610219366004610da8565b610949565b61023161022c366004610e14565b610a18565b6040516100e29190610e95565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f5437988d0000000000000000000000000000000000000000000000000000000014806102d157507fffffffff0000000000000000000000000000000000000000000000000000000082167ff7e83aee00000000000000000000000000000000000000000000000000000000145b8061031d57507fffffffff0000000000000000000000000000000000000000000000000000000082167ff873a61c00000000000000000000000000000000000000000000000000000000145b8061036957507fffffffff0000000000000000000000000000000000000000000000000000000082167f38416b5b00000000000000000000000000000000000000000000000000000000145b806103b557507fffffffff0000000000000000000000000000000000000000000000000000000082167f94ba284600000000000000000000000000000000000000000000000000000000145b92915050565b600254604080517f38416b5b000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916338416b5b9160048083019260209291908290030181865afa15801561042b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061044f9190610f15565b905090565b61045c610ade565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f94ba284600000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156104e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050a9190610f32565b15806105c157506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f38416b5b00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa15801561059b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105bf9190610f32565b155b8061067757506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f294d2bb100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106759190610f32565b155b8061072d57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fd7c72e4e00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610707573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072b9190610f32565b155b15610781576040517f96ac86f300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024015b60405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610849576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610778565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600254604080517f94ba2846000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916394ba28469160048083019260209291908290030181865afa15801561042b573d6000803e3d6000fd5b61093d610ade565b61094681610b61565b50565b6002546040517f294d2bb100000000000000000000000000000000000000000000000000000000815260609173ffffffffffffffffffffffffffffffffffffffff169063294d2bb19034906109aa9089908990899089903390600401610f9d565b60006040518083038185885af11580156109c8573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a0f91908101906110f5565b95945050505050565b6002546040517fd7c72e4e00000000000000000000000000000000000000000000000000000000815260609173ffffffffffffffffffffffffffffffffffffffff169063d7c72e4e903490610a79908990899089908990339060040161112a565b60006040518083038185885af1158015610a97573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a0f919081019061123b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610778565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610be0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610778565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610c6857600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610c9857600080fd5b9392505050565b60005b83811015610cba578181015183820152602001610ca2565b50506000910152565b60008151808452610cdb816020860160208601610c9f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610c986020830184610cc3565b73ffffffffffffffffffffffffffffffffffffffff8116811461094657600080fd5b600060208284031215610d5457600080fd5b8135610c9881610d20565b60008083601f840112610d7157600080fd5b50813567ffffffffffffffff811115610d8957600080fd5b602083019150836020828501011115610da157600080fd5b9250929050565b60008060008060408587031215610dbe57600080fd5b843567ffffffffffffffff80821115610dd657600080fd5b610de288838901610d5f565b90965094506020870135915080821115610dfb57600080fd5b50610e0887828801610d5f565b95989497509550505050565b60008060008060408587031215610e2a57600080fd5b843567ffffffffffffffff80821115610e4257600080fd5b818701915087601f830112610e5657600080fd5b813581811115610e6557600080fd5b8860208260051b8501011115610e7a57600080fd5b602092830196509450908601359080821115610dfb57600080fd5b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015610f08577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452610ef6858351610cc3565b94509285019290850190600101610ebc565b5092979650505050505050565b600060208284031215610f2757600080fd5b8151610c9881610d20565b600060208284031215610f4457600080fd5b81518015158114610c9857600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000610fb1606083018789610f54565b8281036020840152610fc4818688610f54565b91505073ffffffffffffffffffffffffffffffffffffffff831660408301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561106357611063610fed565b604052919050565b600082601f83011261107c57600080fd5b815167ffffffffffffffff81111561109657611096610fed565b6110c760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161101c565b8181528460208386010111156110dc57600080fd5b6110ed826020830160208701610c9f565b949350505050565b60006020828403121561110757600080fd5b815167ffffffffffffffff81111561111e57600080fd5b6110ed8482850161106b565b6060808252810185905260006080600587901b8301810190830188835b898110156111f6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8086850301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18c36030181126111a857600080fd5b8b01602081810191359067ffffffffffffffff8211156111c757600080fd5b8136038313156111d657600080fd5b6111e1878385610f54565b96509485019493909301925050600101611147565b505050828103602084015261120c818688610f54565b915050611231604083018473ffffffffffffffffffffffffffffffffffffffff169052565b9695505050505050565b6000602080838503121561124e57600080fd5b825167ffffffffffffffff8082111561126657600080fd5b818501915085601f83011261127a57600080fd5b81518181111561128c5761128c610fed565b8060051b61129b85820161101c565b91825283810185019185810190898411156112b557600080fd5b86860192505b838310156112f1578251858111156112d35760008081fd5b6112e18b89838a010161106b565b83525091860191908601906112bb565b999850505050505050505056fea164736f6c6343000813000a", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610fac806101576000396000f3fe6080604052600436106100b15760003560e01c80638da5cb5b11610069578063f2fde38b1161004e578063f2fde38b1461022d578063f7e83aee1461024d578063f873a61c1461026057600080fd5b80638da5cb5b146101ed57806394ba28461461021857600080fd5b806338416b5b1161009a57806338416b5b1461017c5780635437988d146101b657806379ba5097146101d857600080fd5b806301ffc9a7146100b6578063181f5a771461012d575b600080fd5b3480156100c257600080fd5b506101186100d13660046108f7565b7fffffffff00000000000000000000000000000000000000000000000000000000167ff7574762000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b34801561013957600080fd5b5060408051808201909152601e81527f44657374696e6174696f6e566572696669657250726f787920302e342e30000060208201525b60405161012491906109ae565b34801561018857600080fd5b50610191610280565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b3480156101c257600080fd5b506101d66101d13660046109e3565b610319565b005b3480156101e457600080fd5b506101d6610469565b3480156101f957600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610191565b34801561022457600080fd5b50610191610566565b34801561023957600080fd5b506101d66102483660046109e3565b6105d6565b61016f61025b366004610a49565b6105ea565b61027361026e366004610ab5565b6106b9565b6040516101249190610b36565b600254604080517f38416b5b000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916338416b5b9160048083019260209291908290030181865afa1580156102f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103149190610bb6565b905090565b61032161077f565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f527146e200000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156103ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103cf9190610bd3565b610422576040517f96ac86f300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024015b60405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff1633146104ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610419565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600254604080517f94ba2846000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916394ba28469160048083019260209291908290030181865afa1580156102f0573d6000803e3d6000fd5b6105de61077f565b6105e781610802565b50565b6002546040517f294d2bb100000000000000000000000000000000000000000000000000000000815260609173ffffffffffffffffffffffffffffffffffffffff169063294d2bb190349061064b9089908990899089903390600401610c3e565b60006040518083038185885af1158015610669573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106b09190810190610d96565b95945050505050565b6002546040517fd7c72e4e00000000000000000000000000000000000000000000000000000000815260609173ffffffffffffffffffffffffffffffffffffffff169063d7c72e4e90349061071a9089908990899089903390600401610dcb565b60006040518083038185885af1158015610738573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106b09190810190610edc565b60005473ffffffffffffffffffffffffffffffffffffffff163314610800576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610419565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610881576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610419565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561090957600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461093957600080fd5b9392505050565b60005b8381101561095b578181015183820152602001610943565b50506000910152565b6000815180845261097c816020860160208601610940565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006109396020830184610964565b73ffffffffffffffffffffffffffffffffffffffff811681146105e757600080fd5b6000602082840312156109f557600080fd5b8135610939816109c1565b60008083601f840112610a1257600080fd5b50813567ffffffffffffffff811115610a2a57600080fd5b602083019150836020828501011115610a4257600080fd5b9250929050565b60008060008060408587031215610a5f57600080fd5b843567ffffffffffffffff80821115610a7757600080fd5b610a8388838901610a00565b90965094506020870135915080821115610a9c57600080fd5b50610aa987828801610a00565b95989497509550505050565b60008060008060408587031215610acb57600080fd5b843567ffffffffffffffff80821115610ae357600080fd5b818701915087601f830112610af757600080fd5b813581811115610b0657600080fd5b8860208260051b8501011115610b1b57600080fd5b602092830196509450908601359080821115610a9c57600080fd5b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015610ba9577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452610b97858351610964565b94509285019290850190600101610b5d565b5092979650505050505050565b600060208284031215610bc857600080fd5b8151610939816109c1565b600060208284031215610be557600080fd5b8151801515811461093957600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b606081526000610c52606083018789610bf5565b8281036020840152610c65818688610bf5565b91505073ffffffffffffffffffffffffffffffffffffffff831660408301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d0457610d04610c8e565b604052919050565b600082601f830112610d1d57600080fd5b815167ffffffffffffffff811115610d3757610d37610c8e565b610d6860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610cbd565b818152846020838601011115610d7d57600080fd5b610d8e826020830160208701610940565b949350505050565b600060208284031215610da857600080fd5b815167ffffffffffffffff811115610dbf57600080fd5b610d8e84828501610d0c565b6060808252810185905260006080600587901b8301810190830188835b89811015610e97577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8086850301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18c3603018112610e4957600080fd5b8b01602081810191359067ffffffffffffffff821115610e6857600080fd5b813603831315610e7757600080fd5b610e82878385610bf5565b96509485019493909301925050600101610de8565b5050508281036020840152610ead818688610bf5565b915050610ed2604083018473ffffffffffffffffffffffffffffffffffffffff169052565b9695505050505050565b60006020808385031215610eef57600080fd5b825167ffffffffffffffff80821115610f0757600080fd5b818501915085601f830112610f1b57600080fd5b815181811115610f2d57610f2d610c8e565b8060051b610f3c858201610cbd565b9182528381018501918581019089841115610f5657600080fd5b86860192505b83831015610f9257825185811115610f745760008081fd5b610f828b89838a0101610d0c565b8352509186019190860190610f5c565b999850505050505050505056fea164736f6c6343000813000a", } var DestinationVerifierProxyABI = DestinationVerifierProxyMetaData.ABI diff --git a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt index ef04a38f87..b576628ef5 100644 --- a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -2,10 +2,10 @@ GETH_VERSION: 1.13.8 channel_config_store: ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin 3fafe83ea21d50488f5533962f62683988ffa6fd1476dccbbb9040be2369cb37 channel_config_verifier_proxy: ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.abi ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.bin 655658e5f61dfadfe3268de04f948b7e690ad03ca45676e645d6cd6018154661 channel_verifier: ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.abi ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.bin e6020553bd8e3e6b250fcaffe7efd22aea955c8c1a0eb05d282fdeb0ab6550b7 -destination_fee_manager: ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.abi ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.bin c581af84832b8fd886685f59518bcdb11bd1c9b508d88b07c04d6226e6a2789e -destination_reward_manager: ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.abi ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.bin 6aed4313578f74ede71bcb60674391103d265d96d56d4736a79ef4128f0590f4 -destination_verifier: ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.abi ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.bin 2dc118aecd5c30d34a69354a9fb603beb98d46215a18d31c59f0f7902fd8f4c2 -destination_verifier_proxy: ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.abi ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.bin a4bf230bbba8a7b8e32a85a6161ca1343f7472b257c358a73ac37996809ce1c0 +destination_fee_manager: ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.abi ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.bin a56ae53e35e6610269f086b1e915ca1e80f5d0bf5695d09156e82fccfc2d77b3 +destination_reward_manager: ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.abi ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.bin 77874e97a54ecbd9c61132964da5b053f0b584dc7b774d75dd51baedd2bc7c40 +destination_verifier: ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.abi ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.bin 369323ce520923b9eb31ed90885f5ebd0f46b6799288fbf4da5d6ede7d697aef +destination_verifier_proxy: ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.abi ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.bin 4e255301cf6657777e7292eccea3e4c0ce65281404341e9248e095703a9fe392 errored_verifier: ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.abi ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.bin ad8ac8d6b99890081725e2304d79d1ba7dd5212b89d130aa9689f4269eed4691 exposed_channel_verifier: ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.abi ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.bin c21cde078900241c06de69e2bc5d906c5ef558b52db66caa68bed065940a2253 exposed_verifier: ../../../contracts/solc/v0.8.19/ExposedVerifier/ExposedVerifier.abi ../../../contracts/solc/v0.8.19/ExposedVerifier/ExposedVerifier.bin 00816ab345f768e522c79abadeadf9155c2c688067e18f8f73e5d6ab71037663 From 5607fc6f8ce5610b7eaca20577161a47928f5780 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Fri, 30 Aug 2024 14:40:54 +0200 Subject: [PATCH 261/432] Fix min coverage (#14286) * fix matrix path of min coverage * run fmt on contracts/GNUmakefile change * adjust min coverage * run forge fmt also on non-src changes * lower min code cov for keystone --- .github/workflows/solidity-foundry.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index 0c0c3be434..582503b034 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -28,15 +28,15 @@ jobs: cat < matrix.json [ { "name": "automation", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": false, "run-forge-fmt": false }}, - { "name": "ccip", "setup": { "run-coverage": true, "min-coverage": 98.5, "run-gas-snapshot": true, "run-forge-fmt": true }}, + { "name": "ccip", "setup": { "run-coverage": true, "min-coverage": 97.6, "run-gas-snapshot": true, "run-forge-fmt": true }}, { "name": "functions", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": true, "run-forge-fmt": false }}, - { "name": "keystone", "setup": { "run-coverage": true, "min-coverage": 74.1, "run-gas-snapshot": false, "run-forge-fmt": false }}, - { "name": "l2ep", "setup": { "run-coverage": true, "min-coverage": 65.6, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "keystone", "setup": { "run-coverage": true, "min-coverage": 72.8, "run-gas-snapshot": false, "run-forge-fmt": false }}, + { "name": "l2ep", "setup": { "run-coverage": true, "min-coverage": 63.4, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "liquiditymanager", "setup": { "run-coverage": true, "min-coverage": 46.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "llo-feeds", "setup": { "run-coverage": true, "min-coverage": 49.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "operatorforwarder", "setup": { "run-coverage": true, "min-coverage": 55.7, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "shared", "setup": { "run-coverage": true, "extra-coverage-params": "--no-match-path='*CallWithExactGas*'", "min-coverage": 32.6, "run-gas-snapshot": true, "run-forge-fmt": false }}, - { "name": "transmission", "setup": { "run-coverage": true, "min-coverage": 65.6, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "transmission", "setup": { "run-coverage": true, "min-coverage": 61.5, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "vrf", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": false, "run-forge-fmt": false }} ] EOF @@ -59,7 +59,6 @@ jobs: outputs: non_src_changes: ${{ steps.changes.outputs.non_src }} sol_modified_added: ${{ steps.changes.outputs.sol }} - sol_modified_added_files: ${{ steps.changes.outputs.sol_files }} sol_mod_only: ${{ steps.changes.outputs.sol_mod_only }} sol_mod_only_files: ${{ steps.changes.outputs.sol_mod_only_files }} not_test_sol_modified: ${{ steps.changes-non-test.outputs.not_test_sol }} @@ -79,6 +78,7 @@ jobs: - 'contracts/foundry.toml' - 'contracts/gas-snapshots/*.gas-snapshot' - 'contracts/package.json' + - 'contracts/GNUmakefile' sol: - modified|added: 'contracts/src/v0.8/**/*.sol' sol_mod_only: @@ -246,7 +246,7 @@ jobs: with: update-comment: false coverage-files: ./contracts/lcov.info.pruned - minimum-coverage: ${{ matrix.product.min-coverage }} + minimum-coverage: ${{ matrix.product.setup.min-coverage }} artifact-name: code-coverage-report-${{ matrix.product.name }} working-directory: ./contracts @@ -549,23 +549,23 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout the repo - if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) && matrix.product.setup.run-forge-fmt }} + if: ${{ (contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) || needs.changes.outputs.non_src_changes == 'true') && matrix.product.setup.run-forge-fmt }} uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: submodules: recursive - name: Setup NodeJS - if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) && matrix.product.setup.run-forge-fmt }} + if: ${{ (contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) || needs.changes.outputs.non_src_changes == 'true') && matrix.product.setup.run-forge-fmt }} uses: ./.github/actions/setup-nodejs - name: Install Foundry - if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) && matrix.product.setup.run-forge-fmt }} + if: ${{ (contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) || needs.changes.outputs.non_src_changes == 'true') && matrix.product.setup.run-forge-fmt }} uses: foundry-rs/foundry-toolchain@8f1998e9878d786675189ef566a2e4bf24869773 # v1.2.0 with: version: ${{ needs.define-matrix.outputs.foundry-version }} - name: Run Forge fmt - if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) && matrix.product.setup.run-forge-fmt }} + if: ${{ (contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) || needs.changes.outputs.non_src_changes == 'true') && matrix.product.setup.run-forge-fmt }} run: forge fmt --check id: fmt working-directory: contracts @@ -573,7 +573,7 @@ jobs: FOUNDRY_PROFILE: ${{ matrix.product.name }} - name: Collect Metrics - if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) && matrix.product.setup.run-forge-fmt }} + if: ${{ (contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) || needs.changes.outputs.non_src_changes == 'true') && matrix.product.setup.run-forge-fmt }} id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 with: From 73c41d1f27ac43ec6ed6a27368776b187c5e5e45 Mon Sep 17 00:00:00 2001 From: Margaret Ma Date: Fri, 30 Aug 2024 11:39:03 -0400 Subject: [PATCH 262/432] skip deleted proposals when checking `isJobManaged` (#14281) --- .changeset/tricky-eagles-knock.md | 5 +++++ core/services/feeds/orm.go | 1 + core/services/feeds/orm_test.go | 8 ++++++++ 3 files changed, 14 insertions(+) create mode 100644 .changeset/tricky-eagles-knock.md diff --git a/.changeset/tricky-eagles-knock.md b/.changeset/tricky-eagles-knock.md new file mode 100644 index 0000000000..cbb4d4d8c7 --- /dev/null +++ b/.changeset/tricky-eagles-knock.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +skip checking isJobManaged if the proposal in fms has already been deleted #changed diff --git a/core/services/feeds/orm.go b/core/services/feeds/orm.go index 7f1e019417..a49882ccf5 100644 --- a/core/services/feeds/orm.go +++ b/core/services/feeds/orm.go @@ -826,6 +826,7 @@ SELECT exists ( FROM job_proposals INNER JOIN jobs ON job_proposals.external_job_id = jobs.external_job_id WHERE jobs.id = $1 + AND job_proposals.status <> 'deleted' ); ` diff --git a/core/services/feeds/orm_test.go b/core/services/feeds/orm_test.go index 4ff1a85aea..976465f37f 100644 --- a/core/services/feeds/orm_test.go +++ b/core/services/feeds/orm_test.go @@ -1653,6 +1653,14 @@ func Test_ORM_IsJobManaged(t *testing.T) { isManaged, err = orm.IsJobManaged(ctx, int64(j.ID)) require.NoError(t, err) assert.True(t, isManaged) + + // delete the proposal + err = orm.DeleteProposal(ctx, jpID) + require.NoError(t, err) + + isManaged, err = orm.IsJobManaged(ctx, int64(j.ID)) + require.NoError(t, err) + assert.False(t, isManaged) } // Helpers From 4d5fc1943bd6a60b49cbc3d263c0aa47dc3cecb7 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Fri, 30 Aug 2024 18:33:15 +0200 Subject: [PATCH 263/432] fail on failure instead of != success (#14295) * fail on failure instead of != success * test with commented condition * remove test change --- .github/workflows/integration-tests.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 9a9dec15c8..7e2b5bc7c4 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -165,7 +165,7 @@ jobs: test_download_vendor_packages_command: cd ${{ matrix.project.path }} && go mod download go_mod_path: ${{ matrix.project.path }}/go.mod cache_key_id: ${{ matrix.project.cache_id }} - cache_restore_only: "true" + cache_restore_only: "true" - name: Lint Go uses: golangci/golangci-lint-action@3cfe3a4abbb849e10058ce4af15d205b6da42804 # v4.0.0 with: @@ -262,11 +262,11 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} run-ccip-e2e-tests-workflow: name: Run CCIP E2E Tests @@ -298,12 +298,12 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + check-e2e-test-results: if: always() name: ETH Smoke Tests @@ -341,11 +341,11 @@ jobs: slack-message: ":x: :mild-panic-intensifies: Node Migration Tests Failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}\n${{ format('Notifying ', secrets.GUARDIAN_SLACK_NOTIFICATION_HANDLE) }}" - name: Fail the job if core tests not successful - if: always() && needs.run-core-e2e-tests-workflow.result != 'success' + if: always() && needs.run-core-e2e-tests-workflow.result == 'failure' run: exit 1 - name: Fail the job if lint not successful - if: always() && needs.lint-integration-tests.result != 'success' + if: always() && needs.lint-integration-tests.result == 'failure' run: exit 1 cleanup: From fc8453721b4feee38f0fe0254b9f5e44dd4a4087 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:24:49 +0200 Subject: [PATCH 264/432] Fix slack notification for client compatibility tests (#14302) --- .github/workflows/client-compatibility-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index ea0b911936..58ec0ff94e 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -710,7 +710,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "${{ contains(join(needs.*.result, ','), 'failure') && format('Some tests failed, notifying ', secrets.COMPAT_SLACK_NOTIFICATION_HANDLE) || 'All Good!' }}" + "text": "${{ contains(join(needs.*.result, ','), 'failure') && format('Some tests failed, notifying ', secrets.COMPAT_SLACK_NOTIFICATION_HANDLE) || 'All Good!' }}" } }, { From 702fe12eace2c7c4d2ce346887eebb8eed0ed644 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Mon, 2 Sep 2024 12:18:42 +0200 Subject: [PATCH 265/432] Bump chainlink-testing-framework to remove secret config keys from test configs and BASE64_NETWORK_CONFIG env (#14303) * Bump ctf * fix lint * Fix test * bump --- .../ccip-tests/testconfig/global.go | 4 --- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +-- integration-tests/testconfig/testconfig.go | 4 --- .../testconfig/testconfig_test.go | 25 +++++++++++-------- 7 files changed, 20 insertions(+), 25 deletions(-) diff --git a/integration-tests/ccip-tests/testconfig/global.go b/integration-tests/ccip-tests/testconfig/global.go index b20c4ff86f..c00bfdcfea 100644 --- a/integration-tests/ccip-tests/testconfig/global.go +++ b/integration-tests/ccip-tests/testconfig/global.go @@ -430,10 +430,6 @@ func (p *Common) Validate() error { // read the default network config, if specified p.Network.UpperCaseNetworkNames() p.Network.OverrideURLsAndKeysFromEVMNetwork() - err := p.Network.Default() - if err != nil { - return fmt.Errorf("error reading default network config %w", err) - } if err := p.Network.Validate(); err != nil { return fmt.Errorf("error validating networks config %w", err) } diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 792452ee52..1026c72018 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -37,7 +37,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 - github.com/smartcontractkit/chainlink-testing-framework v1.34.10 + github.com/smartcontractkit/chainlink-testing-framework v1.35.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 3227d1ec70..06729ec744 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1437,8 +1437,8 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.10 h1:7boGJr/wkX5TF6TBb4wRnP6t1IFL6RD98+fZBJBZyCY= -github.com/smartcontractkit/chainlink-testing-framework v1.34.10/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= +github.com/smartcontractkit/chainlink-testing-framework v1.35.0 h1:5FzS4YOwzjRe59VMM7MmEyjgJCq4/aXR1fzdEJEPiL8= +github.com/smartcontractkit/chainlink-testing-framework v1.35.0/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 h1:1/r1wQZ4TOFpZ13w94r7amdF096Z96RuEnkOmrz1BGE= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 h1:eHsvf2SklyyZ5fTHJIsIZ3eUnfO0TJU2BSZ7j8kLvzM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 6e9b41bf38..13d87c970d 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,7 +17,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 - github.com/smartcontractkit/chainlink-testing-framework v1.34.10 + github.com/smartcontractkit/chainlink-testing-framework v1.35.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 252abe8104..c5f5705cec 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1407,8 +1407,8 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.34.10 h1:7boGJr/wkX5TF6TBb4wRnP6t1IFL6RD98+fZBJBZyCY= -github.com/smartcontractkit/chainlink-testing-framework v1.34.10/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= +github.com/smartcontractkit/chainlink-testing-framework v1.35.0 h1:5FzS4YOwzjRe59VMM7MmEyjgJCq4/aXR1fzdEJEPiL8= +github.com/smartcontractkit/chainlink-testing-framework v1.35.0/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a h1:8GtvGJaGyKzx/ar1yX74GxrzIYWTZVTyv4pYB/1ln8w= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 h1:eHsvf2SklyyZ5fTHJIsIZ3eUnfO0TJU2BSZ7j8kLvzM= diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index 5bdabcecd6..d0839d7239 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -577,10 +577,6 @@ func (c *TestConfig) readNetworkConfiguration() error { c.Network.UpperCaseNetworkNames() c.Network.OverrideURLsAndKeysFromEVMNetwork() - err := c.Network.Default() - if err != nil { - return errors.Wrapf(err, "error reading default network config") - } // this is the only value we need to generate dynamically before starting a new simulated chain if c.PrivateEthereumNetwork != nil && c.PrivateEthereumNetwork.EthereumChainConfig != nil { diff --git a/integration-tests/testconfig/testconfig_test.go b/integration-tests/testconfig/testconfig_test.go index 91d2524fcf..09f5402bd1 100644 --- a/integration-tests/testconfig/testconfig_test.go +++ b/integration-tests/testconfig/testconfig_test.go @@ -15,17 +15,18 @@ import ( ) func TestBase64ConfigRead(t *testing.T) { - networkConfigTOML := ` - [RpcHttpUrls] - arbitrum_goerli = ["https://devnet-1.mt/ABC/rpc/"] - optimism_goerli = ["https://devnet-3.mt/ABC/rpc/"] - - [RpcWsUrls] - arbitrum_goerli = ["wss://devnet-1.mt/ABC/rpc/"] - optimism_goerli = ["wss://devnet-2.mt/ABC/rpc/"] - ` - networksEncoded := base64.StdEncoding.EncodeToString([]byte(networkConfigTOML)) - os.Setenv(ctf_config.Base64NetworkConfigEnvVarName, networksEncoded) + os.Setenv("E2E_TEST_ARBITRUM_GOERLI_RPC_HTTP_URL", "https://devnet-1.mt/ABC/rpc/") + os.Setenv("E2E_TEST_ARBITRUM_GOERLI_RPC_WS_URL", "wss://devnet-1.mt/ABC/rpc/") + os.Setenv("E2E_TEST_ARBITRUM_GOERLI_WALLET_KEY", "0x3333333333333333333333333333333333333333") + defer os.Unsetenv("E2E_TEST_ARBITRUM_GOERLI_RPC_HTTP_URL") + defer os.Unsetenv("E2E_TEST_ARBITRUM_GOERLI_RPC_WS_URL") + defer os.Unsetenv("E2E_TEST_ARBITRUM_GOERLI_WALLET_KEY") + os.Setenv("E2E_TEST_OPTIMISM_GOERLI_RPC_HTTP_URL", "https://devnet-3.mt/ABC/rpc/") + os.Setenv("E2E_TEST_OPTIMISM_GOERLI_RPC_WS_URL", "wss://devnet-3.mt/ABC/rpc/") + os.Setenv("E2E_TEST_OPTIMISM_GOERLI_WALLET_KEY", "0x3333333333333333333333333333333333333333") + defer os.Unsetenv("E2E_TEST_OPTIMISM_GOERLI_RPC_HTTP_URL") + defer os.Unsetenv("E2E_TEST_OPTIMISM_GOERLI_RPC_WS_URL") + defer os.Unsetenv("E2E_TEST_OPTIMISM_GOERLI_WALLET_KEY") testConfig := TestConfig{ Automation: &a_config.Config{ @@ -35,6 +36,8 @@ func TestBase64ConfigRead(t *testing.T) { BlockTime: ptr.Ptr(10), SpecType: ptr.Ptr("minimum"), ChainlinkNodeLogLevel: ptr.Ptr("debug"), + UsePrometheus: ptr.Ptr(true), + RemoveNamespace: ptr.Ptr(true), }, Load: []a_config.Load{ { From 85b33fd9acbd342d25bd84804d08451ab2590b97 Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Mon, 2 Sep 2024 04:14:05 -0700 Subject: [PATCH 266/432] ccip 3076/ccip - port deployment tooling (#14298) * porting ccip tooling into chainlink * make deployment test run * add missing changes * fix build error * make private * more updates * changes * make lint happy * make lint happy * Use tests.WaitTimeout for CCIPReader e2e tests (#1382) We've noticed that this tests have failed a few times on the CI. I've run the tests with `go test ./... -count 100 -failfast` and it never failed locally. I assume it runs slow in CI that's why we have some failing cases, I am replacing `10s` with `tests.WaitTimeout(t)`. * core/capabilities/ccip: fix oracle startup logic (#1348) Ticket: https://smartcontract-it.atlassian.net/browse/CCIP-3078 We can't start bootstrap oracles and plugin oracles on the same chainlink node. The main reason for this is that we have a singleton `SingletonPeerWrapper` object which manages all libocr peers for the application as a whole. Since this singleton only works with a single peer ID, it creates a single OCR peer, and all streams are created using this OCR peer. Since streams must have unique config digests for the same peer object, running a bootstrap oracle and a plugin oracle for the same config digest will fail because the stream will not be created. In order to remedy this we match what will be the case in production, which is: * Separate bootstrap node, with a peer ID that is either part of the OCR committee or not (most likely the latter, in order to avoid exporting / importing the P2P key from one node's DB to another). This bootstrap node will have to have a DNS name and be publicly accessible over the internet in order to be accessed by all nodes in the committee, at least initially, to facilitate peer discovery. * Plugin node that is more locked down, i.e no public DNS name required. To enable this, in this PR we: * Tweak the `launcher` component to launch bootstrap nodes only or plugin nodes only, and not both. This does NOT rely on the on-chain bootstrap P2P IDs that are set in the OCR config. This field will be removed in subsequent PRs. * Tweak the `OracleCreator` interface to support the above operation Follow ups: * Remove the `bootstrapP2PIds` field from the OCR config in CCIPConfig.sol * Add changeset --------- Co-authored-by: dimitris Co-authored-by: Makram Co-authored-by: asoliman Co-authored-by: Abdelrahman Soliman (Boda) <2677789+asoliman92@users.noreply.github.com> --- .changeset/tiny-doors-brush.md | 5 + .github/workflows/ci-core.yml | 2 + .../ccipreader/ccipreader_test.go | 5 +- core/capabilities/ccip/delegate.go | 48 +- core/capabilities/ccip/launcher/bluegreen.go | 54 +- .../ccip/launcher/bluegreen_test.go | 428 +---- core/capabilities/ccip/launcher/diff.go | 13 - core/capabilities/ccip/launcher/diff_test.go | 9 - .../ccip/launcher/integration_test.go | 19 +- core/capabilities/ccip/launcher/launcher.go | 57 +- .../ccip/launcher/launcher_test.go | 277 ++- .../ccip/launcher/test_helpers.go | 2 + .../ccip/oraclecreator/bootstrap.go | 97 + .../ccip/oraclecreator/inprocess_test.go | 239 --- .../oraclecreator/{inprocess.go => plugin.go} | 305 ++-- .../ccip/types/mocks/oracle_creator.go | 74 +- core/capabilities/ccip/types/types.go | 18 +- core/capabilities/ccip/validate/validate.go | 3 - integration-tests/deployment/README.md | 20 +- integration-tests/deployment/address_book.go | 118 +- .../deployment/address_book_test.go | 117 +- integration-tests/deployment/ccip/add_lane.go | 120 ++ .../deployment/ccip/add_lane_test.go | 1 + .../deployment/ccip/changeset/1_cap_reg.go | 21 + .../ccip/changeset/2_initial_deploy.go | 33 + .../ccip/changeset/2_initial_deploy_test.go | 244 +++ integration-tests/deployment/ccip/deploy.go | 471 +++++ .../deployment/ccip/deploy_home_chain.go | 402 ++++ .../deployment/ccip/deploy_test.go | 58 + integration-tests/deployment/ccip/jobs.go | 79 + integration-tests/deployment/ccip/propose.go | 64 + integration-tests/deployment/ccip/state.go | 276 +++ .../deployment/ccip/test_helpers.go | 75 + integration-tests/deployment/environment.go | 14 +- .../deployment/jd/csa/v1/csa.pb.go | 418 +++++ .../deployment/jd/csa/v1/csa_grpc.pb.go | 146 ++ .../deployment/jd/job/v1/job.pb.go | 685 ++++--- .../deployment/jd/job/v1/job_grpc.pb.go | 41 +- .../deployment/jd/node/v1/node.pb.go | 1618 +++++++++++++---- .../deployment/jd/node/v1/node_grpc.pb.go | 158 +- .../deployment/jd/node/v1/shared.pb.go | 239 --- .../deployment/jd/shared/ptypes/label.pb.go | 2 +- .../deployment/memory/environment.go | 23 +- .../deployment/memory/job_client.go | 59 +- integration-tests/deployment/memory/node.go | 7 +- integration-tests/go.mod | 2 +- integration-tests/web/sdk/client/client.go | 45 +- .../sdk/client/{internal => }/doer/doer.go | 0 integration-tests/web/sdk/client/types.go | 50 + .../web/sdk/client/types_test.go | 67 + .../web/sdk/internal/generated/generated.go | 582 +++++- .../web/sdk/internal/genqlient.graphql | 51 + 52 files changed, 5879 insertions(+), 2082 deletions(-) create mode 100644 .changeset/tiny-doors-brush.md create mode 100644 core/capabilities/ccip/oraclecreator/bootstrap.go delete mode 100644 core/capabilities/ccip/oraclecreator/inprocess_test.go rename core/capabilities/ccip/oraclecreator/{inprocess.go => plugin.go} (79%) create mode 100644 integration-tests/deployment/ccip/add_lane.go create mode 100644 integration-tests/deployment/ccip/add_lane_test.go create mode 100644 integration-tests/deployment/ccip/changeset/1_cap_reg.go create mode 100644 integration-tests/deployment/ccip/changeset/2_initial_deploy.go create mode 100644 integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go create mode 100644 integration-tests/deployment/ccip/deploy.go create mode 100644 integration-tests/deployment/ccip/deploy_home_chain.go create mode 100644 integration-tests/deployment/ccip/deploy_test.go create mode 100644 integration-tests/deployment/ccip/jobs.go create mode 100644 integration-tests/deployment/ccip/propose.go create mode 100644 integration-tests/deployment/ccip/state.go create mode 100644 integration-tests/deployment/ccip/test_helpers.go create mode 100644 integration-tests/deployment/jd/csa/v1/csa.pb.go create mode 100644 integration-tests/deployment/jd/csa/v1/csa_grpc.pb.go delete mode 100644 integration-tests/deployment/jd/node/v1/shared.pb.go rename integration-tests/web/sdk/client/{internal => }/doer/doer.go (100%) create mode 100644 integration-tests/web/sdk/client/types.go create mode 100644 integration-tests/web/sdk/client/types_test.go diff --git a/.changeset/tiny-doors-brush.md b/.changeset/tiny-doors-brush.md new file mode 100644 index 0000000000..2581817ba7 --- /dev/null +++ b/.changeset/tiny-doors-brush.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +moved deployments ccip tooling from ccip repo to chainlink repo #added diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 7a4f70ef3c..dd79493d13 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -45,7 +45,9 @@ jobs: with: filters: | changes: + - 'integration-tests/deployment/**' - '!integration-tests/**' + - 'integration-tests/deployment/**' - name: Ignore Filter On Workflow Dispatch if: ${{ github.event_name == 'workflow_dispatch' }} id: ignore-filter diff --git a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go index ed5fe1aedb..05a91eb289 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go @@ -19,6 +19,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" @@ -115,7 +116,7 @@ func TestCCIPReader_CommitReportsGTETimestamp(t *testing.T) { ) require.NoError(t, err) return len(reports) == numReports-1 - }, 10*time.Second, 50*time.Millisecond) + }, tests.WaitTimeout(t), 50*time.Millisecond) assert.Len(t, reports[0].Report.MerkleRoots, 1) assert.Equal(t, chainS1, reports[0].Report.MerkleRoots[0].ChainSel) @@ -268,7 +269,7 @@ func TestCCIPReader_MsgsBetweenSeqNums(t *testing.T) { ) require.NoError(t, err) return len(msgs) == 2 - }, 10*time.Second, 100*time.Millisecond) + }, tests.WaitTimeout(t), 100*time.Millisecond) require.Len(t, msgs, 2) // sort to ensure ascending order of sequence numbers. diff --git a/core/capabilities/ccip/delegate.go b/core/capabilities/ccip/delegate.go index 6dd30b1507..7623a18af9 100644 --- a/core/capabilities/ccip/delegate.go +++ b/core/capabilities/ccip/delegate.go @@ -23,6 +23,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/config" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" @@ -161,21 +162,36 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services ccipConfigBinding, ) - oracleCreator := oraclecreator.New( - ocrKeys, - transmitterKeys, - d.chains, - d.peerWrapper, - spec.ExternalJobID, - spec.ID, - d.isNewlyCreatedJob, - spec.CCIPSpec.PluginConfig, - ocrDB, - d.lggr, - d.monitoringEndpointGen, - bootstrapperLocators, - hcr, - ) + // if bootstrappers are provided we assume that the node is a plugin oracle. + // the reason for this is that bootstrap oracles do not need to be aware + // of other bootstrap oracles. however, plugin oracles, at least initially, + // must be aware of available bootstrappers. + var oracleCreator cctypes.OracleCreator + if len(spec.CCIPSpec.P2PV2Bootstrappers) > 0 { + oracleCreator = oraclecreator.NewPluginOracleCreator( + ocrKeys, + transmitterKeys, + d.chains, + d.peerWrapper, + spec.ExternalJobID, + spec.ID, + d.isNewlyCreatedJob, + spec.CCIPSpec.PluginConfig, + ocrDB, + d.lggr, + d.monitoringEndpointGen, + bootstrapperLocators, + hcr, + ) + } else { + oracleCreator = oraclecreator.NewBootstrapOracleCreator( + d.peerWrapper, + bootstrapperLocators, + ocrDB, + d.monitoringEndpointGen, + d.lggr, + ) + } capabilityID := fmt.Sprintf("%s@%s", spec.CCIPSpec.CapabilityLabelledName, spec.CCIPSpec.CapabilityVersion) capLauncher := launcher.New( @@ -183,8 +199,8 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services ragep2ptypes.PeerID(p2pID.PeerID()), d.lggr, hcr, - oracleCreator, 12*time.Second, + oracleCreator, ) // register the capability launcher with the registry syncer diff --git a/core/capabilities/ccip/launcher/bluegreen.go b/core/capabilities/ccip/launcher/bluegreen.go index 6245846629..c15f8c038f 100644 --- a/core/capabilities/ccip/launcher/bluegreen.go +++ b/core/capabilities/ccip/launcher/bluegreen.go @@ -16,21 +16,11 @@ type blueGreenDeployment struct { // blue must always be present. blue cctypes.CCIPOracle - // bootstrapBlue is the bootstrap node of the blue OCR instance. - // Only a subset of the DON will be running bootstrap instances, - // so this may be nil. - bootstrapBlue cctypes.CCIPOracle - // green is the green OCR instance. // green may or may not be present. // green must never be present if blue is not present. // TODO: should we enforce this invariant somehow? green cctypes.CCIPOracle - - // bootstrapGreen is the bootstrap node of the green OCR instance. - // Only a subset of the DON will be running bootstrap instances, - // so this may be nil, even when green is not nil. - bootstrapGreen cctypes.CCIPOracle } // ccipDeployment represents blue-green deployments of both commit and exec @@ -44,33 +34,21 @@ type ccipDeployment struct { func (c *ccipDeployment) Close() error { var err error - // shutdown blue commit instances. + // shutdown blue commit instance. err = multierr.Append(err, c.commit.blue.Close()) - if c.commit.bootstrapBlue != nil { - err = multierr.Append(err, c.commit.bootstrapBlue.Close()) - } - // shutdown green commit instances. + // shutdown green commit instance. if c.commit.green != nil { err = multierr.Append(err, c.commit.green.Close()) } - if c.commit.bootstrapGreen != nil { - err = multierr.Append(err, c.commit.bootstrapGreen.Close()) - } - // shutdown blue exec instances. + // shutdown blue exec instance. err = multierr.Append(err, c.exec.blue.Close()) - if c.exec.bootstrapBlue != nil { - err = multierr.Append(err, c.exec.bootstrapBlue.Close()) - } - // shutdown green exec instances. + // shutdown green exec instance. if c.exec.green != nil { err = multierr.Append(err, c.exec.green.Close()) } - if c.exec.bootstrapGreen != nil { - err = multierr.Append(err, c.exec.bootstrapGreen.Close()) - } return err } @@ -80,13 +58,7 @@ func (c *ccipDeployment) StartBlue() error { var err error err = multierr.Append(err, c.commit.blue.Start()) - if c.commit.bootstrapBlue != nil { - err = multierr.Append(err, c.commit.bootstrapBlue.Start()) - } err = multierr.Append(err, c.exec.blue.Start()) - if c.exec.bootstrapBlue != nil { - err = multierr.Append(err, c.exec.bootstrapBlue.Start()) - } return err } @@ -96,13 +68,7 @@ func (c *ccipDeployment) CloseBlue() error { var err error err = multierr.Append(err, c.commit.blue.Close()) - if c.commit.bootstrapBlue != nil { - err = multierr.Append(err, c.commit.bootstrapBlue.Close()) - } err = multierr.Append(err, c.exec.blue.Close()) - if c.exec.bootstrapBlue != nil { - err = multierr.Append(err, c.exec.bootstrapBlue.Close()) - } return err } @@ -127,28 +93,16 @@ func (c *ccipDeployment) HandleBlueGreen(prevDeployment *ccipDeployment) error { var err error if prevDeployment.commit.green != nil && c.commit.green == nil { err = multierr.Append(err, prevDeployment.commit.blue.Close()) - if prevDeployment.commit.bootstrapBlue != nil { - err = multierr.Append(err, prevDeployment.commit.bootstrapBlue.Close()) - } } else if prevDeployment.commit.green == nil && c.commit.green != nil { err = multierr.Append(err, c.commit.green.Start()) - if c.commit.bootstrapGreen != nil { - err = multierr.Append(err, c.commit.bootstrapGreen.Start()) - } } else { return fmt.Errorf("invalid blue-green deployment transition") } if prevDeployment.exec.green != nil && c.exec.green == nil { err = multierr.Append(err, prevDeployment.exec.blue.Close()) - if prevDeployment.exec.bootstrapBlue != nil { - err = multierr.Append(err, prevDeployment.exec.bootstrapBlue.Close()) - } } else if prevDeployment.exec.green == nil && c.exec.green != nil { err = multierr.Append(err, c.exec.green.Start()) - if c.exec.bootstrapGreen != nil { - err = multierr.Append(err, c.exec.bootstrapGreen.Start()) - } } else { return fmt.Errorf("invalid blue-green deployment transition") } diff --git a/core/capabilities/ccip/launcher/bluegreen_test.go b/core/capabilities/ccip/launcher/bluegreen_test.go index 9fd71a0cb4..965491180e 100644 --- a/core/capabilities/ccip/launcher/bluegreen_test.go +++ b/core/capabilities/ccip/launcher/bluegreen_test.go @@ -14,14 +14,10 @@ import ( func Test_ccipDeployment_Close(t *testing.T) { type args struct { - commitBlue *mocktypes.CCIPOracle - commitBlueBootstrap *mocktypes.CCIPOracle - commitGreen *mocktypes.CCIPOracle - commitGreenBootstrap *mocktypes.CCIPOracle - execBlue *mocktypes.CCIPOracle - execBlueBootstrap *mocktypes.CCIPOracle - execGreen *mocktypes.CCIPOracle - execGreenBootstrap *mocktypes.CCIPOracle + commitBlue *mocktypes.CCIPOracle + commitGreen *mocktypes.CCIPOracle + execBlue *mocktypes.CCIPOracle + execGreen *mocktypes.CCIPOracle } tests := []struct { name string @@ -33,12 +29,10 @@ func Test_ccipDeployment_Close(t *testing.T) { { name: "no errors, blue only", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitGreen: nil, - commitGreenBootstrap: nil, - execBlue: mocktypes.NewCCIPOracle(t), - execGreen: nil, - execGreenBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: nil, + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: nil, }, expect: func(t *testing.T, args args) { args.commitBlue.On("Close").Return(nil).Once() @@ -90,62 +84,6 @@ func Test_ccipDeployment_Close(t *testing.T) { }, wantErr: true, }, - { - name: "bootstrap blue also closed", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Close").Return(nil).Once() - args.commitBlueBootstrap.On("Close").Return(nil).Once() - args.execBlue.On("Close").Return(nil).Once() - args.execBlueBootstrap.On("Close").Return(nil).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.commitBlueBootstrap.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - args.execBlueBootstrap.AssertExpectations(t) - }, - wantErr: false, - }, - { - name: "bootstrap green also closed", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: mocktypes.NewCCIPOracle(t), - commitGreenBootstrap: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: mocktypes.NewCCIPOracle(t), - execGreenBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Close").Return(nil).Once() - args.commitBlueBootstrap.On("Close").Return(nil).Once() - args.commitGreen.On("Close").Return(nil).Once() - args.commitGreenBootstrap.On("Close").Return(nil).Once() - args.execBlue.On("Close").Return(nil).Once() - args.execBlueBootstrap.On("Close").Return(nil).Once() - args.execGreen.On("Close").Return(nil).Once() - args.execGreenBootstrap.On("Close").Return(nil).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.commitBlueBootstrap.AssertExpectations(t) - args.commitGreen.AssertExpectations(t) - args.commitGreenBootstrap.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - args.execBlueBootstrap.AssertExpectations(t) - args.execGreen.AssertExpectations(t) - args.execGreenBootstrap.AssertExpectations(t) - }, - wantErr: false, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -160,22 +98,10 @@ func Test_ccipDeployment_Close(t *testing.T) { if tt.args.commitGreen != nil { c.commit.green = tt.args.commitGreen } - if tt.args.commitBlueBootstrap != nil { - c.commit.bootstrapBlue = tt.args.commitBlueBootstrap - } - if tt.args.commitGreenBootstrap != nil { - c.commit.bootstrapGreen = tt.args.commitGreenBootstrap - } if tt.args.execGreen != nil { c.exec.green = tt.args.execGreen } - if tt.args.execBlueBootstrap != nil { - c.exec.bootstrapBlue = tt.args.execBlueBootstrap - } - if tt.args.execGreenBootstrap != nil { - c.exec.bootstrapGreen = tt.args.execGreenBootstrap - } tt.expect(t, tt.args) defer tt.asserts(t, tt.args) @@ -191,10 +117,8 @@ func Test_ccipDeployment_Close(t *testing.T) { func Test_ccipDeployment_StartBlue(t *testing.T) { type args struct { - commitBlue *mocktypes.CCIPOracle - commitBlueBootstrap *mocktypes.CCIPOracle - execBlue *mocktypes.CCIPOracle - execBlueBootstrap *mocktypes.CCIPOracle + commitBlue *mocktypes.CCIPOracle + execBlue *mocktypes.CCIPOracle } tests := []struct { name string @@ -204,12 +128,10 @@ func Test_ccipDeployment_StartBlue(t *testing.T) { wantErr bool }{ { - name: "no errors, no bootstrap", + name: "no errors", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), }, expect: func(t *testing.T, args args) { args.commitBlue.On("Start").Return(nil).Once() @@ -221,35 +143,11 @@ func Test_ccipDeployment_StartBlue(t *testing.T) { }, wantErr: false, }, - { - name: "no errors, with bootstrap", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Start").Return(nil).Once() - args.commitBlueBootstrap.On("Start").Return(nil).Once() - args.execBlue.On("Start").Return(nil).Once() - args.execBlueBootstrap.On("Start").Return(nil).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.commitBlueBootstrap.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - args.execBlueBootstrap.AssertExpectations(t) - }, - wantErr: false, - }, { name: "error on commit blue", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), }, expect: func(t *testing.T, args args) { args.commitBlue.On("Start").Return(errors.New("failed")).Once() @@ -264,10 +162,8 @@ func Test_ccipDeployment_StartBlue(t *testing.T) { { name: "error on exec blue", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), }, expect: func(t *testing.T, args args) { args.commitBlue.On("Start").Return(nil).Once() @@ -279,46 +175,6 @@ func Test_ccipDeployment_StartBlue(t *testing.T) { }, wantErr: true, }, - { - name: "error on commit blue bootstrap", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: nil, - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Start").Return(nil).Once() - args.commitBlueBootstrap.On("Start").Return(errors.New("failed")).Once() - args.execBlue.On("Start").Return(nil).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.commitBlueBootstrap.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - }, - wantErr: true, - }, - { - name: "error on exec blue bootstrap", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Start").Return(nil).Once() - args.execBlue.On("Start").Return(nil).Once() - args.execBlueBootstrap.On("Start").Return(errors.New("failed")).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - args.execBlueBootstrap.AssertExpectations(t) - }, - wantErr: true, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -330,12 +186,6 @@ func Test_ccipDeployment_StartBlue(t *testing.T) { blue: tt.args.execBlue, }, } - if tt.args.commitBlueBootstrap != nil { - c.commit.bootstrapBlue = tt.args.commitBlueBootstrap - } - if tt.args.execBlueBootstrap != nil { - c.exec.bootstrapBlue = tt.args.execBlueBootstrap - } tt.expect(t, tt.args) defer tt.asserts(t, tt.args) @@ -351,10 +201,8 @@ func Test_ccipDeployment_StartBlue(t *testing.T) { func Test_ccipDeployment_CloseBlue(t *testing.T) { type args struct { - commitBlue *mocktypes.CCIPOracle - commitBlueBootstrap *mocktypes.CCIPOracle - execBlue *mocktypes.CCIPOracle - execBlueBootstrap *mocktypes.CCIPOracle + commitBlue *mocktypes.CCIPOracle + execBlue *mocktypes.CCIPOracle } tests := []struct { name string @@ -364,12 +212,10 @@ func Test_ccipDeployment_CloseBlue(t *testing.T) { wantErr bool }{ { - name: "no errors, no bootstrap", + name: "no errors", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), }, expect: func(t *testing.T, args args) { args.commitBlue.On("Close").Return(nil).Once() @@ -381,35 +227,11 @@ func Test_ccipDeployment_CloseBlue(t *testing.T) { }, wantErr: false, }, - { - name: "no errors, with bootstrap", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Close").Return(nil).Once() - args.commitBlueBootstrap.On("Close").Return(nil).Once() - args.execBlue.On("Close").Return(nil).Once() - args.execBlueBootstrap.On("Close").Return(nil).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.commitBlueBootstrap.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - args.execBlueBootstrap.AssertExpectations(t) - }, - wantErr: false, - }, { name: "error on commit blue", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), }, expect: func(t *testing.T, args args) { args.commitBlue.On("Close").Return(errors.New("failed")).Once() @@ -424,10 +246,8 @@ func Test_ccipDeployment_CloseBlue(t *testing.T) { { name: "error on exec blue", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), }, expect: func(t *testing.T, args args) { args.commitBlue.On("Close").Return(nil).Once() @@ -439,46 +259,6 @@ func Test_ccipDeployment_CloseBlue(t *testing.T) { }, wantErr: true, }, - { - name: "error on commit blue bootstrap", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: nil, - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Close").Return(nil).Once() - args.commitBlueBootstrap.On("Close").Return(errors.New("failed")).Once() - args.execBlue.On("Close").Return(nil).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.commitBlueBootstrap.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - }, - wantErr: true, - }, - { - name: "error on exec blue bootstrap", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Close").Return(nil).Once() - args.execBlue.On("Close").Return(nil).Once() - args.execBlueBootstrap.On("Close").Return(errors.New("failed")).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - args.execBlueBootstrap.AssertExpectations(t) - }, - wantErr: true, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -490,12 +270,6 @@ func Test_ccipDeployment_CloseBlue(t *testing.T) { blue: tt.args.execBlue, }, } - if tt.args.commitBlueBootstrap != nil { - c.commit.bootstrapBlue = tt.args.commitBlueBootstrap - } - if tt.args.execBlueBootstrap != nil { - c.exec.bootstrapBlue = tt.args.execBlueBootstrap - } tt.expect(t, tt.args) defer tt.asserts(t, tt.args) @@ -515,14 +289,10 @@ func Test_ccipDeployment_HandleBlueGreen_PrevDeploymentNil(t *testing.T) { func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { type args struct { - commitBlue *mocktypes.CCIPOracle - commitBlueBootstrap *mocktypes.CCIPOracle - commitGreen *mocktypes.CCIPOracle - commitGreenBootstrap *mocktypes.CCIPOracle - execBlue *mocktypes.CCIPOracle - execBlueBootstrap *mocktypes.CCIPOracle - execGreen *mocktypes.CCIPOracle - execGreenBootstrap *mocktypes.CCIPOracle + commitBlue *mocktypes.CCIPOracle + commitGreen *mocktypes.CCIPOracle + execBlue *mocktypes.CCIPOracle + execGreen *mocktypes.CCIPOracle } tests := []struct { name string @@ -533,7 +303,7 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { wantErr bool }{ { - name: "promotion blue to green, no bootstrap", + name: "promotion blue to green", argsPrevDeployment: args{ commitBlue: mocktypes.NewCCIPOracle(t), commitGreen: mocktypes.NewCCIPOracle(t), @@ -557,43 +327,7 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { wantErr: false, }, { - name: "promotion blue to green, with bootstrap", - argsPrevDeployment: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: mocktypes.NewCCIPOracle(t), - commitGreenBootstrap: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: mocktypes.NewCCIPOracle(t), - execGreenBootstrap: mocktypes.NewCCIPOracle(t), - }, - argsFutureDeployment: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: nil, - commitGreenBootstrap: nil, - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: nil, - execGreenBootstrap: nil, - }, - expect: func(t *testing.T, args args, argsPrevDeployment args) { - argsPrevDeployment.commitBlue.On("Close").Return(nil).Once() - argsPrevDeployment.commitBlueBootstrap.On("Close").Return(nil).Once() - argsPrevDeployment.execBlue.On("Close").Return(nil).Once() - argsPrevDeployment.execBlueBootstrap.On("Close").Return(nil).Once() - }, - asserts: func(t *testing.T, args args, argsPrevDeployment args) { - argsPrevDeployment.commitBlue.AssertExpectations(t) - argsPrevDeployment.commitBlueBootstrap.AssertExpectations(t) - argsPrevDeployment.execBlue.AssertExpectations(t) - argsPrevDeployment.execBlueBootstrap.AssertExpectations(t) - }, - wantErr: false, - }, - { - name: "new green deployment, no bootstrap", + name: "new green deployment", argsPrevDeployment: args{ commitBlue: mocktypes.NewCCIPOracle(t), commitGreen: nil, @@ -616,42 +350,6 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { }, wantErr: false, }, - { - name: "new green deployment, with bootstrap", - argsPrevDeployment: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: nil, - commitGreenBootstrap: nil, - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: nil, - execGreenBootstrap: nil, - }, - argsFutureDeployment: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: mocktypes.NewCCIPOracle(t), - commitGreenBootstrap: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: mocktypes.NewCCIPOracle(t), - execGreenBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args, argsPrevDeployment args) { - args.commitGreen.On("Start").Return(nil).Once() - args.commitGreenBootstrap.On("Start").Return(nil).Once() - args.execGreen.On("Start").Return(nil).Once() - args.execGreenBootstrap.On("Start").Return(nil).Once() - }, - asserts: func(t *testing.T, args args, argsPrevDeployment args) { - args.commitGreen.AssertExpectations(t) - args.commitGreenBootstrap.AssertExpectations(t) - args.execGreen.AssertExpectations(t) - args.execGreenBootstrap.AssertExpectations(t) - }, - wantErr: false, - }, { name: "error on commit green start", argsPrevDeployment: args{ @@ -700,42 +398,6 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { }, wantErr: true, }, - { - name: "error on commit green bootstrap start", - argsPrevDeployment: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: nil, - commitGreenBootstrap: nil, - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: nil, - execGreenBootstrap: nil, - }, - argsFutureDeployment: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: mocktypes.NewCCIPOracle(t), - commitGreenBootstrap: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: mocktypes.NewCCIPOracle(t), - execGreenBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args, argsPrevDeployment args) { - args.commitGreen.On("Start").Return(nil).Once() - args.commitGreenBootstrap.On("Start").Return(errors.New("failed")).Once() - args.execGreen.On("Start").Return(nil).Once() - args.execGreenBootstrap.On("Start").Return(nil).Once() - }, - asserts: func(t *testing.T, args args, argsPrevDeployment args) { - args.commitGreen.AssertExpectations(t) - args.commitGreenBootstrap.AssertExpectations(t) - args.execGreen.AssertExpectations(t) - args.execGreenBootstrap.AssertExpectations(t) - }, - wantErr: true, - }, { name: "invalid blue-green deployment transition commit: both prev and future deployment have green", argsPrevDeployment: args{ @@ -755,7 +417,7 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { wantErr: true, }, { - name: "invalid blue-green deployment transition exec: both prev and future deployment have green", + name: "invalid blue-green deployment transition exec: both prev and future exec deployment have green", argsPrevDeployment: args{ commitBlue: mocktypes.NewCCIPOracle(t), commitGreen: nil, @@ -790,21 +452,9 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { if tt.argsFutureDeployment.commitGreen != nil { futDeployment.commit.green = tt.argsFutureDeployment.commitGreen } - if tt.argsFutureDeployment.commitBlueBootstrap != nil { - futDeployment.commit.bootstrapBlue = tt.argsFutureDeployment.commitBlueBootstrap - } - if tt.argsFutureDeployment.commitGreenBootstrap != nil { - futDeployment.commit.bootstrapGreen = tt.argsFutureDeployment.commitGreenBootstrap - } if tt.argsFutureDeployment.execGreen != nil { futDeployment.exec.green = tt.argsFutureDeployment.execGreen } - if tt.argsFutureDeployment.execBlueBootstrap != nil { - futDeployment.exec.bootstrapBlue = tt.argsFutureDeployment.execBlueBootstrap - } - if tt.argsFutureDeployment.execGreenBootstrap != nil { - futDeployment.exec.bootstrapGreen = tt.argsFutureDeployment.execGreenBootstrap - } prevDeployment := &ccipDeployment{ commit: blueGreenDeployment{ @@ -817,21 +467,9 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { if tt.argsPrevDeployment.commitGreen != nil { prevDeployment.commit.green = tt.argsPrevDeployment.commitGreen } - if tt.argsPrevDeployment.commitBlueBootstrap != nil { - prevDeployment.commit.bootstrapBlue = tt.argsPrevDeployment.commitBlueBootstrap - } - if tt.argsPrevDeployment.commitGreenBootstrap != nil { - prevDeployment.commit.bootstrapGreen = tt.argsPrevDeployment.commitGreenBootstrap - } if tt.argsPrevDeployment.execGreen != nil { prevDeployment.exec.green = tt.argsPrevDeployment.execGreen } - if tt.argsPrevDeployment.execBlueBootstrap != nil { - prevDeployment.exec.bootstrapBlue = tt.argsPrevDeployment.execBlueBootstrap - } - if tt.argsPrevDeployment.execGreenBootstrap != nil { - prevDeployment.exec.bootstrapGreen = tt.argsPrevDeployment.execGreenBootstrap - } tt.expect(t, tt.argsFutureDeployment, tt.argsPrevDeployment) defer tt.asserts(t, tt.argsFutureDeployment, tt.argsPrevDeployment) diff --git a/core/capabilities/ccip/launcher/diff.go b/core/capabilities/ccip/launcher/diff.go index e631ea9fc7..de429deedc 100644 --- a/core/capabilities/ccip/launcher/diff.go +++ b/core/capabilities/ccip/launcher/diff.go @@ -126,16 +126,3 @@ func isMemberOfDON(don registrysyncer.DON, p2pID ragep2ptypes.PeerID) bool { } return false } - -// isMemberOfBootstrapSubcommittee returns true if and only if the given p2pID is a member of the given bootstrap subcommittee. -func isMemberOfBootstrapSubcommittee( - bootstrapP2PIDs [][32]byte, - p2pID ragep2ptypes.PeerID, -) bool { - for _, bootstrapID := range bootstrapP2PIDs { - if bootstrapID == p2pID { - return true - } - } - return false -} diff --git a/core/capabilities/ccip/launcher/diff_test.go b/core/capabilities/ccip/launcher/diff_test.go index f3dd327fe9..3b168d9148 100644 --- a/core/capabilities/ccip/launcher/diff_test.go +++ b/core/capabilities/ccip/launcher/diff_test.go @@ -341,12 +341,3 @@ func Test_isMemberOfDON(t *testing.T) { require.True(t, isMemberOfDON(don, ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(1)).PeerID()))) require.False(t, isMemberOfDON(don, ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(5)).PeerID()))) } - -func Test_isMemberOfBootstrapSubcommittee(t *testing.T) { - var bootstrapKeys [][32]byte - for i := range [4]struct{}{} { - bootstrapKeys = append(bootstrapKeys, p2pkey.MustNewV2XXXTestingOnly(big.NewInt(int64(i+1))).PeerID()) - } - require.True(t, isMemberOfBootstrapSubcommittee(bootstrapKeys, p2pID1)) - require.False(t, isMemberOfBootstrapSubcommittee(bootstrapKeys, getP2PID(5))) -} diff --git a/core/capabilities/ccip/launcher/integration_test.go b/core/capabilities/ccip/launcher/integration_test.go index 7973316b31..ea22360c66 100644 --- a/core/capabilities/ccip/launcher/integration_test.go +++ b/core/capabilities/ccip/launcher/integration_test.go @@ -42,17 +42,16 @@ func TestIntegration_Launcher(t *testing.T) { ) require.NoError(t, err) - hcr := uni.HomeChainReader - + oracleCreator := &oracleCreatorPrints{ + t: t, + } launcher := New( it.CapabilityID, p2pIDs[0], logger.TestLogger(t), - hcr, - &oracleCreatorPrints{ - t: t, - }, + uni.HomeChainReader, 1*time.Second, + oracleCreator, ) regSyncer.AddLauncher(launcher) @@ -109,14 +108,14 @@ type oracleCreatorPrints struct { t *testing.T } -func (o *oracleCreatorPrints) CreatePluginOracle(pluginType cctypes.PluginType, config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { +func (o *oracleCreatorPrints) Create(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { + pluginType := cctypes.PluginType(config.Config.PluginType) o.t.Logf("Creating plugin oracle (pluginType: %s) with config %+v\n", pluginType, config) return &oraclePrints{pluginType: pluginType, config: config, t: o.t}, nil } -func (o *oracleCreatorPrints) CreateBootstrapOracle(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { - o.t.Logf("Creating bootstrap oracle with config %+v\n", config) - return &oraclePrints{pluginType: cctypes.PluginTypeCCIPCommit, config: config, isBootstrap: true, t: o.t}, nil +func (o *oracleCreatorPrints) Type() cctypes.OracleType { + return cctypes.OracleTypePlugin } var _ cctypes.OracleCreator = &oracleCreatorPrints{} diff --git a/core/capabilities/ccip/launcher/launcher.go b/core/capabilities/ccip/launcher/launcher.go index 2dc1a1954f..9fb92d20f5 100644 --- a/core/capabilities/ccip/launcher/launcher.go +++ b/core/capabilities/ccip/launcher/launcher.go @@ -33,8 +33,8 @@ func New( p2pID ragep2ptypes.PeerID, lggr logger.Logger, homeChainReader ccipreader.HomeChain, - oracleCreator cctypes.OracleCreator, tickInterval time.Duration, + oracleCreator cctypes.OracleCreator, ) *launcher { return &launcher{ p2pID: p2pID, @@ -46,9 +46,9 @@ func New( IDsToNodes: make(map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo), IDsToCapabilities: make(map[string]registrysyncer.Capability), }, - oracleCreator: oracleCreator, dons: make(map[registrysyncer.DonID]*ccipDeployment), tickInterval: tickInterval, + oracleCreator: oracleCreator, } } @@ -194,9 +194,9 @@ func (l *launcher) processUpdate(updated map[registrysyncer.DonID]registrysyncer l.lggr, l.p2pID, l.homeChainReader, - l.oracleCreator, *prevDeployment, don, + l.oracleCreator, ) if err != nil { return err @@ -225,8 +225,8 @@ func (l *launcher) processAdded(added map[registrysyncer.DonID]registrysyncer.DO l.lggr, l.p2pID, l.homeChainReader, - l.oracleCreator, don, + l.oracleCreator, ) if err != nil { return err @@ -284,9 +284,9 @@ func updateDON( lggr logger.Logger, p2pID ragep2ptypes.PeerID, homeChainReader ccipreader.HomeChain, - oracleCreator cctypes.OracleCreator, prevDeployment ccipDeployment, don registrysyncer.DON, + oracleCreator cctypes.OracleCreator, ) (futDeployment *ccipDeployment, err error) { if !isMemberOfDON(don, p2pID) { lggr.Infow("Not a member of this DON, skipping", "donId", don.ID, "p2pId", p2pID.String()) @@ -335,7 +335,7 @@ func createFutureBlueGreenDeployment( var deployment blueGreenDeployment if isNewGreenInstance(pluginType, ocrConfigs, prevDeployment) { // this is a new green instance. - greenOracle, err := oracleCreator.CreatePluginOracle(pluginType, cctypes.OCR3ConfigWithMeta(ocrConfigs[1])) + greenOracle, err := oracleCreator.Create(cctypes.OCR3ConfigWithMeta(ocrConfigs[1])) if err != nil { return blueGreenDeployment{}, fmt.Errorf("failed to create CCIP commit oracle: %w", err) } @@ -358,14 +358,9 @@ func createDON( lggr logger.Logger, p2pID ragep2ptypes.PeerID, homeChainReader ccipreader.HomeChain, - oracleCreator cctypes.OracleCreator, don registrysyncer.DON, + oracleCreator cctypes.OracleCreator, ) (*ccipDeployment, error) { - if !isMemberOfDON(don, p2pID) { - lggr.Infow("Not a member of this DON, skipping", "donId", don.ID, "p2pId", p2pID.String()) - return nil, nil - } - // this should be a retryable error. commitOCRConfigs, err := homeChainReader.GetOCRConfigs(context.Background(), don.ID, uint8(cctypes.PluginTypeCCIPCommit)) if err != nil { @@ -388,45 +383,29 @@ func createDON( return nil, fmt.Errorf("expected exactly one OCR config for CCIP exec plugin (don id: %d), got %d", don.ID, len(execOCRConfigs)) } - commitOracle, commitBootstrap, err := createOracle(p2pID, oracleCreator, cctypes.PluginTypeCCIPCommit, commitOCRConfigs) + if !isMemberOfDON(don, p2pID) && oracleCreator.Type() == cctypes.OracleTypePlugin { + lggr.Infow("Not a member of this DON and not a bootstrap node either, skipping", "donId", don.ID, "p2pId", p2pID.String()) + return nil, nil + } + + // at this point we know we are either a member of the DON or a bootstrap node. + // the injected oracleCreator will create the appropriate oracle. + commitOracle, err := oracleCreator.Create(cctypes.OCR3ConfigWithMeta(commitOCRConfigs[0])) if err != nil { return nil, fmt.Errorf("failed to create CCIP commit oracle: %w", err) } - execOracle, execBootstrap, err := createOracle(p2pID, oracleCreator, cctypes.PluginTypeCCIPExec, execOCRConfigs) + execOracle, err := oracleCreator.Create(cctypes.OCR3ConfigWithMeta(execOCRConfigs[0])) if err != nil { return nil, fmt.Errorf("failed to create CCIP exec oracle: %w", err) } return &ccipDeployment{ commit: blueGreenDeployment{ - blue: commitOracle, - bootstrapBlue: commitBootstrap, + blue: commitOracle, }, exec: blueGreenDeployment{ - blue: execOracle, - bootstrapBlue: execBootstrap, + blue: execOracle, }, }, nil } - -func createOracle( - p2pID ragep2ptypes.PeerID, - oracleCreator cctypes.OracleCreator, - pluginType cctypes.PluginType, - ocrConfigs []ccipreader.OCR3ConfigWithMeta, -) (pluginOracle, bootstrapOracle cctypes.CCIPOracle, err error) { - pluginOracle, err = oracleCreator.CreatePluginOracle(pluginType, cctypes.OCR3ConfigWithMeta(ocrConfigs[0])) - if err != nil { - return nil, nil, fmt.Errorf("failed to create CCIP plugin oracle (plugintype: %d): %w", pluginType, err) - } - - if isMemberOfBootstrapSubcommittee(ocrConfigs[0].Config.BootstrapP2PIds, p2pID) { - bootstrapOracle, err = oracleCreator.CreateBootstrapOracle(cctypes.OCR3ConfigWithMeta(ocrConfigs[0])) - if err != nil { - return nil, nil, fmt.Errorf("failed to create CCIP bootstrap oracle (plugintype: %d): %w", pluginType, err) - } - } - - return pluginOracle, bootstrapOracle, nil -} diff --git a/core/capabilities/ccip/launcher/launcher_test.go b/core/capabilities/ccip/launcher/launcher_test.go index 242dd0be24..dd917c6915 100644 --- a/core/capabilities/ccip/launcher/launcher_test.go +++ b/core/capabilities/ccip/launcher/launcher_test.go @@ -1,7 +1,6 @@ package launcher import ( - "errors" "math/big" "reflect" "testing" @@ -15,170 +14,108 @@ import ( ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" ) -func Test_createOracle(t *testing.T) { - var p2pKeys []ragep2ptypes.PeerID - for i := 0; i < 3; i++ { - p2pKeys = append(p2pKeys, ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(int64(i+1))).PeerID())) - } - myP2PKey := p2pKeys[0] +func Test_createDON(t *testing.T) { type args struct { - p2pID ragep2ptypes.PeerID - oracleCreator *mocks.OracleCreator - pluginType cctypes.PluginType - ocrConfigs []ccipreaderpkg.OCR3ConfigWithMeta + lggr logger.Logger + p2pID ragep2ptypes.PeerID + homeChainReader *mocks.HomeChainReader + oracleCreator *mocks.OracleCreator + don registrysyncer.DON } tests := []struct { name string args args - expect func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) + expect func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) wantErr bool }{ { - "success, no bootstrap", + "not a member of the DON and not a bootstrap node", args{ - myP2PKey, + logger.TestLogger(t), + p2pID1, + mocks.NewHomeChainReader(t), mocks.NewOracleCreator(t), - cctypes.PluginTypeCCIPCommit, - []ccipreaderpkg.OCR3ConfigWithMeta{ - { - Config: ccipreaderpkg.OCR3Config{}, - ConfigCount: 1, - ConfigDigest: testutils.Random32Byte(), - }, + registrysyncer.DON{ + DON: getDON(2, []ragep2ptypes.PeerID{p2pID3, p2pID4}, 0), + CapabilityConfigurations: defaultCapCfgs, }, }, - func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) { - oracleCreator. - On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). - Return(mocks.NewCCIPOracle(t), nil) - }, - false, - }, - { - "success, with bootstrap", - args{ - myP2PKey, - mocks.NewOracleCreator(t), - cctypes.PluginTypeCCIPCommit, - []ccipreaderpkg.OCR3ConfigWithMeta{ - { + func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) { + homeChainReader. + On("GetOCRConfigs", mock.Anything, uint32(2), uint8(cctypes.PluginTypeCCIPCommit)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ Config: ccipreaderpkg.OCR3Config{ - BootstrapP2PIds: [][32]byte{myP2PKey}, + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + P2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(3)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(4)).PeerID(), + }, }, - ConfigCount: 1, - ConfigDigest: testutils.Random32Byte(), - }, - }, - }, - func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) { - oracleCreator. - On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). - Return(mocks.NewCCIPOracle(t), nil) - oracleCreator. - On("CreateBootstrapOracle", cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). - Return(mocks.NewCCIPOracle(t), nil) - }, - false, - }, - { - "error creating plugin oracle", - args{ - myP2PKey, - mocks.NewOracleCreator(t), - cctypes.PluginTypeCCIPCommit, - []ccipreaderpkg.OCR3ConfigWithMeta{ - { - Config: ccipreaderpkg.OCR3Config{}, - ConfigCount: 1, - ConfigDigest: testutils.Random32Byte(), - }, - }, - }, - func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) { - oracleCreator. - On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). - Return(nil, errors.New("error creating oracle")) - }, - true, - }, - { - "error creating bootstrap oracle", - args{ - myP2PKey, - mocks.NewOracleCreator(t), - cctypes.PluginTypeCCIPCommit, - []ccipreaderpkg.OCR3ConfigWithMeta{ - { + }}, nil) + homeChainReader. + On("GetOCRConfigs", mock.Anything, uint32(2), uint8(cctypes.PluginTypeCCIPExec)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ Config: ccipreaderpkg.OCR3Config{ - BootstrapP2PIds: [][32]byte{myP2PKey}, + PluginType: uint8(cctypes.PluginTypeCCIPExec), + P2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(3)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(4)).PeerID(), + }, }, - ConfigCount: 1, - ConfigDigest: testutils.Random32Byte(), - }, - }, - }, - func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) { - oracleCreator. - On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). - Return(mocks.NewCCIPOracle(t), nil) - oracleCreator. - On("CreateBootstrapOracle", cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). - Return(nil, errors.New("error creating oracle")) + }}, nil) + oracleCreator.EXPECT().Type().Return(cctypes.OracleTypePlugin).Once() }, - true, + false, }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tt.expect(t, tt.args, tt.args.oracleCreator) - _, _, err := createOracle(tt.args.p2pID, tt.args.oracleCreator, tt.args.pluginType, tt.args.ocrConfigs) - if tt.wantErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} - -func Test_createDON(t *testing.T) { - type args struct { - lggr logger.Logger - p2pID ragep2ptypes.PeerID - homeChainReader *mocks.HomeChainReader - oracleCreator *mocks.OracleCreator - don registrysyncer.DON - } - tests := []struct { - name string - args args - expect func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) - wantErr bool - }{ { - "not a member of the DON", + "not a member of the DON but a running a bootstrap oracle creator", args{ logger.TestLogger(t), - p2pID1, + ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(1)).PeerID()), mocks.NewHomeChainReader(t), mocks.NewOracleCreator(t), registrysyncer.DON{ - DON: getDON(2, []ragep2ptypes.PeerID{p2pID2}, 0), + DON: getDON(2, []ragep2ptypes.PeerID{p2pID3, p2pID4}, 0), CapabilityConfigurations: defaultCapCfgs, }, }, func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) { + homeChainReader. + On("GetOCRConfigs", mock.Anything, uint32(2), uint8(cctypes.PluginTypeCCIPCommit)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + P2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(3)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(4)).PeerID(), + }, + }, + }}, nil) + homeChainReader. + On("GetOCRConfigs", mock.Anything, uint32(2), uint8(cctypes.PluginTypeCCIPExec)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPExec), + P2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(3)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(4)).PeerID(), + }, + }, + }}, nil) + oracleCreator.EXPECT().Type().Return(cctypes.OracleTypeBootstrap).Once() + oracleCreator. + On("Create", mock.Anything). + Return(mocks.NewCCIPOracle(t), nil).Twice() }, false, }, { - "success, no bootstrap", + "success", args{ logger.TestLogger(t), p2pID1, @@ -189,15 +126,34 @@ func Test_createDON(t *testing.T) { func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) { homeChainReader. On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPCommit)). - Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}}, nil) + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + P2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(1)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(2)).PeerID(), + }, + }, + }}, nil) homeChainReader. On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPExec)). - Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}}, nil) - oracleCreator. - On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, mock.Anything). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPExec), + P2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(1)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(2)).PeerID(), + }, + }, + }}, nil) + + oracleCreator.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) + })). Return(mocks.NewCCIPOracle(t), nil) - oracleCreator. - On("CreatePluginOracle", cctypes.PluginTypeCCIPExec, mock.Anything). + oracleCreator.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) + })). Return(mocks.NewCCIPOracle(t), nil) }, false, @@ -208,7 +164,8 @@ func Test_createDON(t *testing.T) { if tt.expect != nil { tt.expect(t, tt.args, tt.args.oracleCreator, tt.args.homeChainReader) } - _, err := createDON(tt.args.lggr, tt.args.p2pID, tt.args.homeChainReader, tt.args.oracleCreator, tt.args.don) + + _, err := createDON(tt.args.lggr, tt.args.p2pID, tt.args.homeChainReader, tt.args.don, tt.args.oracleCreator) if tt.wantErr { require.Error(t, err) } else { @@ -266,7 +223,7 @@ func Test_updateDON(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - gotFutDeployment, err := updateDON(tt.args.lggr, tt.args.p2pID, tt.args.homeChainReader, tt.args.oracleCreator, tt.args.prevDeployment, tt.args.don) + gotFutDeployment, err := updateDON(tt.args.lggr, tt.args.p2pID, tt.args.homeChainReader, tt.args.prevDeployment, tt.args.don, tt.args.oracleCreator) if (err != nil) != tt.wantErr { t.Errorf("updateDON() error = %v, wantErr %v", err, tt.wantErr) return @@ -346,9 +303,17 @@ func Test_launcher_processDiff(t *testing.T) { return mocks.NewHomeChainReader(t) }, func(m *mocks.HomeChainReader) { m.On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPCommit)). - Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}}, nil) + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + }, + }}, nil) m.On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPExec)). - Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}}, nil) + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPExec), + }, + }}, nil) }), oracleCreator: newMock(t, func(t *testing.T) *mocks.OracleCreator { return mocks.NewOracleCreator(t) @@ -357,9 +322,13 @@ func Test_launcher_processDiff(t *testing.T) { commitOracle.On("Start").Return(nil) execOracle := mocks.NewCCIPOracle(t) execOracle.On("Start").Return(nil) - m.On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, mock.Anything). + m.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) + })). Return(commitOracle, nil) - m.On("CreatePluginOracle", cctypes.PluginTypeCCIPExec, mock.Anything). + m.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) + })). Return(execOracle, nil) }), dons: map[registrysyncer.DonID]*ccipDeployment{}, @@ -389,9 +358,25 @@ func Test_launcher_processDiff(t *testing.T) { return mocks.NewHomeChainReader(t) }, func(m *mocks.HomeChainReader) { m.On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPCommit)). - Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}, {}}, nil) + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + }, + }, { + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + }, + }}, nil) m.On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPExec)). - Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}, {}}, nil) + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPExec), + }, + }, { + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPExec), + }, + }}, nil) }), oracleCreator: newMock(t, func(t *testing.T) *mocks.OracleCreator { return mocks.NewOracleCreator(t) @@ -400,9 +385,13 @@ func Test_launcher_processDiff(t *testing.T) { commitOracle.On("Start").Return(nil) execOracle := mocks.NewCCIPOracle(t) execOracle.On("Start").Return(nil) - m.On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, mock.Anything). + m.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) + })). Return(commitOracle, nil) - m.On("CreatePluginOracle", cctypes.PluginTypeCCIPExec, mock.Anything). + m.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) + })). Return(execOracle, nil) }), dons: map[registrysyncer.DonID]*ccipDeployment{ diff --git a/core/capabilities/ccip/launcher/test_helpers.go b/core/capabilities/ccip/launcher/test_helpers.go index e1b47fa352..f4ded9c2cf 100644 --- a/core/capabilities/ccip/launcher/test_helpers.go +++ b/core/capabilities/ccip/launcher/test_helpers.go @@ -23,6 +23,8 @@ var ( newCapability = getCapability(ccipCapName, ccipCapNewVersion) p2pID1 = getP2PID(1) p2pID2 = getP2PID(2) + p2pID3 = getP2PID(3) + p2pID4 = getP2PID(4) defaultCapCfgs = map[string]registrysyncer.CapabilityConfiguration{ defaultCapability.ID: {}, } diff --git a/core/capabilities/ccip/oraclecreator/bootstrap.go b/core/capabilities/ccip/oraclecreator/bootstrap.go new file mode 100644 index 0000000000..a4bf03a4de --- /dev/null +++ b/core/capabilities/ccip/oraclecreator/bootstrap.go @@ -0,0 +1,97 @@ +package oraclecreator + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/common/hexutil" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/libocr/commontypes" + libocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + + "github.com/smartcontractkit/chainlink-common/pkg/types" + + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ocrimpls" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" +) + +var _ cctypes.OracleCreator = &bootstrapOracleCreator{} + +type bootstrapOracleCreator struct { + peerWrapper *ocrcommon.SingletonPeerWrapper + bootstrapperLocators []commontypes.BootstrapperLocator + db ocr3types.Database + monitoringEndpointGen telemetry.MonitoringEndpointGenerator + lggr logger.Logger +} + +func NewBootstrapOracleCreator( + peerWrapper *ocrcommon.SingletonPeerWrapper, + bootstrapperLocators []commontypes.BootstrapperLocator, + db ocr3types.Database, + monitoringEndpointGen telemetry.MonitoringEndpointGenerator, + lggr logger.Logger, +) cctypes.OracleCreator { + return &bootstrapOracleCreator{ + peerWrapper: peerWrapper, + bootstrapperLocators: bootstrapperLocators, + db: db, + monitoringEndpointGen: monitoringEndpointGen, + lggr: lggr, + } +} + +// Type implements types.OracleCreator. +func (i *bootstrapOracleCreator) Type() cctypes.OracleType { + return cctypes.OracleTypeBootstrap +} + +// Create implements types.OracleCreator. +func (i *bootstrapOracleCreator) Create(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { + // Assuming that the chain selector is referring to an evm chain for now. + // TODO: add an api that returns chain family. + // NOTE: this doesn't really matter for the bootstrap node, it doesn't do anything on-chain. + // Its for the monitoring endpoint generation below. + chainID, err := chainsel.ChainIdFromSelector(uint64(config.Config.ChainSelector)) + if err != nil { + return nil, fmt.Errorf("failed to get chain ID from selector: %w", err) + } + + destChainFamily := chaintype.EVM + destRelayID := types.NewRelayID(string(destChainFamily), fmt.Sprintf("%d", chainID)) + + bootstrapperArgs := libocr3.BootstrapperArgs{ + BootstrapperFactory: i.peerWrapper.Peer2, + V2Bootstrappers: i.bootstrapperLocators, + ContractConfigTracker: ocrimpls.NewConfigTracker(config), + Database: i.db, + LocalConfig: defaultLocalConfig(), + Logger: ocrcommon.NewOCRWrapper( + i.lggr. + Named("CCIPBootstrap"). + Named(destRelayID.String()). + Named(config.Config.ChainSelector.String()). + Named(hexutil.Encode(config.Config.OfframpAddress)), + false, /* traceLogging */ + func(ctx context.Context, msg string) {}), + MonitoringEndpoint: i.monitoringEndpointGen.GenMonitoringEndpoint( + string(destChainFamily), + destRelayID.ChainID, + hexutil.Encode(config.Config.OfframpAddress), + synchronization.OCR3CCIPBootstrap, + ), + OffchainConfigDigester: ocrimpls.NewConfigDigester(config.ConfigDigest), + } + bootstrapper, err := libocr3.NewBootstrapper(bootstrapperArgs) + if err != nil { + return nil, err + } + return bootstrapper, nil +} diff --git a/core/capabilities/ccip/oraclecreator/inprocess_test.go b/core/capabilities/ccip/oraclecreator/inprocess_test.go deleted file mode 100644 index 639f01e62e..0000000000 --- a/core/capabilities/ccip/oraclecreator/inprocess_test.go +++ /dev/null @@ -1,239 +0,0 @@ -package oraclecreator_test - -import ( - "fmt" - "testing" - "time" - - "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/oraclecreator" - cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" - - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/google/uuid" - "github.com/hashicorp/consul/sdk/freeport" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gopkg.in/guregu/null.v4" - - chainsel "github.com/smartcontractkit/chain-selectors" - "github.com/smartcontractkit/libocr/offchainreporting2/types" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - - "github.com/smartcontractkit/chainlink-ccip/pkg/reader" - "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" - "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - - "github.com/smartcontractkit/libocr/commontypes" - - "github.com/smartcontractkit/chainlink/v2/core/bridges" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2" - ocr2validate "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" - "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" - "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" - "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" - "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" - "github.com/smartcontractkit/chainlink/v2/core/utils" -) - -func TestOracleCreator_CreateBootstrap(t *testing.T) { - db := pgtest.NewSqlxDB(t) - - keyStore := keystore.New(db, utils.DefaultScryptParams, logger.NullLogger) - require.NoError(t, keyStore.Unlock(testutils.Context(t), cltest.Password), "unable to unlock keystore") - p2pKey, err := keyStore.P2P().Create(testutils.Context(t)) - require.NoError(t, err) - peerID := p2pKey.PeerID() - listenPort := freeport.GetOne(t) - generalConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.P2P.PeerID = ptr(peerID) - c.P2P.TraceLogging = ptr(false) - c.P2P.V2.Enabled = ptr(true) - c.P2P.V2.ListenAddresses = ptr([]string{fmt.Sprintf("127.0.0.1:%d", listenPort)}) - - c.OCR2.Enabled = ptr(true) - }) - peerWrapper := ocrcommon.NewSingletonPeerWrapper(keyStore, generalConfig.P2P(), generalConfig.OCR(), db, logger.NullLogger) - require.NoError(t, peerWrapper.Start(testutils.Context(t))) - t.Cleanup(func() { assert.NoError(t, peerWrapper.Close()) }) - - // NOTE: this is a bit of a hack to get the OCR2 job created in order to use the ocr db - // the ocr2_contract_configs table has a foreign key constraint on ocr2_oracle_spec_id - // which is passed into ocr2.NewDB. - pipelineORM := pipeline.NewORM(db, - logger.NullLogger, generalConfig.JobPipeline().MaxSuccessfulRuns()) - bridgesORM := bridges.NewORM(db) - - jobORM := job.NewORM(db, pipelineORM, bridgesORM, keyStore, logger.TestLogger(t)) - t.Cleanup(func() { assert.NoError(t, jobORM.Close()) }) - - jb, err := ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), generalConfig.OCR2(), generalConfig.Insecure(), testspecs.GetOCR2EVMSpecMinimal(), nil) - require.NoError(t, err) - const juelsPerFeeCoinSource = ` - ds [type=http method=GET url="https://chain.link/ETH-USD"]; - ds_parse [type=jsonparse path="data.price" separator="."]; - ds_multiply [type=multiply times=100]; - ds -> ds_parse -> ds_multiply;` - - _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) - jb.Name = null.StringFrom("Job 1") - jb.OCR2OracleSpec.TransmitterID = null.StringFrom(address.String()) - jb.OCR2OracleSpec.PluginConfig["juelsPerFeeCoinSource"] = juelsPerFeeCoinSource - - err = jobORM.CreateJob(testutils.Context(t), &jb) - require.NoError(t, err) - - cltest.AssertCount(t, db, "ocr2_oracle_specs", 1) - cltest.AssertCount(t, db, "jobs", 1) - - var oracleSpecID int32 - err = db.Get(&oracleSpecID, "SELECT id FROM ocr2_oracle_specs LIMIT 1") - require.NoError(t, err) - - ocrdb := ocr2.NewDB(db, oracleSpecID, 0, logger.NullLogger) - - oc := oraclecreator.New( - nil, - nil, - nil, - peerWrapper, - uuid.Max, - 0, - false, - nil, - ocrdb, - logger.TestLogger(t), - &mockEndpointGen{}, - []commontypes.BootstrapperLocator{}, - nil, - ) - - chainSelector := chainsel.GETH_TESTNET.Selector - oracles, offchainConfig := ocrOffchainConfig(t, keyStore) - bootstrapP2PID, err := p2pkey.MakePeerID(oracles[0].PeerID) - require.NoError(t, err) - transmitters := func() [][]byte { - var transmitters [][]byte - for _, o := range oracles { - transmitters = append(transmitters, hexutil.MustDecode(string(o.TransmitAccount))) - } - return transmitters - }() - configDigest := ccipConfigDigest() - bootstrap, err := oc.CreateBootstrapOracle(cctypes.OCR3ConfigWithMeta{ - ConfigDigest: configDigest, - ConfigCount: 1, - Config: reader.OCR3Config{ - ChainSelector: ccipocr3.ChainSelector(chainSelector), - OfframpAddress: testutils.NewAddress().Bytes(), - PluginType: uint8(cctypes.PluginTypeCCIPCommit), - F: 1, - OffchainConfigVersion: 30, - BootstrapP2PIds: [][32]byte{bootstrapP2PID}, - P2PIds: func() [][32]byte { - var ids [][32]byte - for _, o := range oracles { - id, err2 := p2pkey.MakePeerID(o.PeerID) - require.NoError(t, err2) - ids = append(ids, id) - } - return ids - }(), - Signers: func() [][]byte { - var signers [][]byte - for _, o := range oracles { - signers = append(signers, o.OnchainPublicKey) - } - return signers - }(), - Transmitters: transmitters, - OffchainConfig: offchainConfig, - }, - }) - require.NoError(t, err) - require.NoError(t, bootstrap.Start()) - t.Cleanup(func() { assert.NoError(t, bootstrap.Close()) }) - - tests.AssertEventually(t, func() bool { - c, err := ocrdb.ReadConfig(testutils.Context(t)) - require.NoError(t, err) - return c.ConfigDigest == configDigest - }) -} - -func ccipConfigDigest() [32]byte { - rand32Bytes := testutils.Random32Byte() - // overwrite first four bytes to be 0x000a, to match the prefix in libocr. - rand32Bytes[0] = 0x00 - rand32Bytes[1] = 0x0a - return rand32Bytes -} - -type mockEndpointGen struct{} - -func (m *mockEndpointGen) GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) commontypes.MonitoringEndpoint { - return &telemetry.NoopAgent{} -} - -func ptr[T any](b T) *T { - return &b -} - -func ocrOffchainConfig(t *testing.T, ks keystore.Master) (oracles []confighelper2.OracleIdentityExtra, offchainConfig []byte) { - for i := 0; i < 4; i++ { - kb, err := ks.OCR2().Create(testutils.Context(t), chaintype.EVM) - require.NoError(t, err) - p2pKey, err := ks.P2P().Create(testutils.Context(t)) - require.NoError(t, err) - ethKey, err := ks.Eth().Create(testutils.Context(t)) - require.NoError(t, err) - oracles = append(oracles, confighelper2.OracleIdentityExtra{ - OracleIdentity: confighelper2.OracleIdentity{ - OffchainPublicKey: kb.OffchainPublicKey(), - OnchainPublicKey: types.OnchainPublicKey(kb.OnChainPublicKey()), - PeerID: p2pKey.ID(), - TransmitAccount: types.Account(ethKey.Address.Hex()), - }, - ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), - }) - } - var schedule []int - for range oracles { - schedule = append(schedule, 1) - } - offchainConfig, onchainConfig := []byte{}, []byte{} - f := uint8(1) - - _, _, _, _, _, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( - 30*time.Second, // deltaProgress - 10*time.Second, // deltaResend - 20*time.Second, // deltaInitial - 2*time.Second, // deltaRound - 20*time.Second, // deltaGrace - 10*time.Second, // deltaCertifiedCommitRequest - 10*time.Second, // deltaStage - 3, // rmax - schedule, - oracles, - offchainConfig, - 50*time.Millisecond, // maxDurationQuery - 5*time.Second, // maxDurationObservation - 10*time.Second, // maxDurationShouldAcceptAttestedReport - 10*time.Second, // maxDurationShouldTransmitAcceptedReport - int(f), - onchainConfig) - require.NoError(t, err, "failed to create contract config") - - return oracles, offchainConfig -} diff --git a/core/capabilities/ccip/oraclecreator/inprocess.go b/core/capabilities/ccip/oraclecreator/plugin.go similarity index 79% rename from core/capabilities/ccip/oraclecreator/inprocess.go rename to core/capabilities/ccip/oraclecreator/plugin.go index 21e9bcec6d..c87c4e97c1 100644 --- a/core/capabilities/ccip/oraclecreator/inprocess.go +++ b/core/capabilities/ccip/oraclecreator/plugin.go @@ -36,7 +36,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" "github.com/smartcontractkit/chainlink/v2/core/services/relay" @@ -46,15 +45,15 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" ) -var _ cctypes.OracleCreator = &inprocessOracleCreator{} +var _ cctypes.OracleCreator = &pluginOracleCreator{} const ( defaultCommitGasLimit = 500_000 ) -// inprocessOracleCreator creates oracles that reference plugins running +// pluginOracleCreator creates oracles that reference plugins running // in the same process as the chainlink node, i.e not LOOPPs. -type inprocessOracleCreator struct { +type pluginOracleCreator struct { ocrKeyBundles map[string]ocr2key.KeyBundle transmitters map[types.RelayID][]string chains legacyevm.LegacyChainContainer @@ -70,7 +69,7 @@ type inprocessOracleCreator struct { homeChainReader ccipreaderpkg.HomeChain } -func New( +func NewPluginOracleCreator( ocrKeyBundles map[string]ocr2key.KeyBundle, transmitters map[types.RelayID][]string, chains legacyevm.LegacyChainContainer, @@ -85,7 +84,7 @@ func New( bootstrapperLocators []commontypes.BootstrapperLocator, homeChainReader ccipreaderpkg.HomeChain, ) cctypes.OracleCreator { - return &inprocessOracleCreator{ + return &pluginOracleCreator{ ocrKeyBundles: ocrKeyBundles, transmitters: transmitters, chains: chains, @@ -102,49 +101,15 @@ func New( } } -// CreateBootstrapOracle implements types.OracleCreator. -func (i *inprocessOracleCreator) CreateBootstrapOracle(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { - // Assuming that the chain selector is referring to an evm chain for now. - // TODO: add an api that returns chain family. - chainID, err := chainsel.ChainIdFromSelector(uint64(config.Config.ChainSelector)) - if err != nil { - return nil, fmt.Errorf("failed to get chain ID from selector: %w", err) - } - - destChainFamily := chaintype.EVM - destRelayID := types.NewRelayID(string(destChainFamily), fmt.Sprintf("%d", chainID)) - - bootstrapperArgs := libocr3.BootstrapperArgs{ - BootstrapperFactory: i.peerWrapper.Peer2, - V2Bootstrappers: i.bootstrapperLocators, - ContractConfigTracker: ocrimpls.NewConfigTracker(config), - Database: i.db, - LocalConfig: defaultLocalConfig(), - Logger: ocrcommon.NewOCRWrapper( - i.lggr. - Named("CCIPBootstrap"). - Named(destRelayID.String()). - Named(config.Config.ChainSelector.String()). - Named(hexutil.Encode(config.Config.OfframpAddress)), - false, /* traceLogging */ - func(ctx context.Context, msg string) {}), - MonitoringEndpoint: i.monitoringEndpointGen.GenMonitoringEndpoint( - string(destChainFamily), - destRelayID.ChainID, - hexutil.Encode(config.Config.OfframpAddress), - synchronization.OCR3CCIPBootstrap, - ), - OffchainConfigDigester: ocrimpls.NewConfigDigester(config.ConfigDigest), - } - bootstrapper, err := libocr3.NewBootstrapper(bootstrapperArgs) - if err != nil { - return nil, err - } - return bootstrapper, nil +// Type implements types.OracleCreator. +func (i *pluginOracleCreator) Type() cctypes.OracleType { + return cctypes.OracleTypePlugin } -// CreatePluginOracle implements types.OracleCreator. -func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginType, config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { +// Create implements types.OracleCreator. +func (i *pluginOracleCreator) Create(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { + pluginType := cctypes.PluginType(config.Config.PluginType) + // Assuming that the chain selector is referring to an evm chain for now. // TODO: add an api that returns chain family. destChainID, err := chainsel.ChainIdFromSelector(uint64(config.Config.ChainSelector)) @@ -172,7 +137,141 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp execBatchGasLimit = execOffchainConfig.BatchGasLimit } - // this is so that we can use the msg hasher and report encoder from that dest chain relayer's provider. + contractReaders, chainWriters, err := i.createReadersAndWriters( + destChainID, + pluginType, + config, + execBatchGasLimit, + ) + if err != nil { + return nil, fmt.Errorf("failed to create readers and writers: %w", err) + } + + // build the onchain keyring. it will be the signing key for the destination chain family. + keybundle, ok := i.ocrKeyBundles[destChainFamily] + if !ok { + return nil, fmt.Errorf("no OCR key bundle found for chain family %s, forgot to create one?", destChainFamily) + } + onchainKeyring := ocrimpls.NewOnchainKeyring[[]byte](keybundle, i.lggr) + + // build the contract transmitter + // assume that we are using the first account in the keybundle as the from account + // and that we are able to transmit to the dest chain. + // TODO: revisit this in the future, since not all oracles will be able to transmit to the dest chain. + destChainWriter, ok := chainWriters[config.Config.ChainSelector] + if !ok { + return nil, fmt.Errorf("no chain writer found for dest chain selector %d, can't create contract transmitter", + config.Config.ChainSelector) + } + destFromAccounts, ok := i.transmitters[destRelayID] + if !ok { + return nil, fmt.Errorf("no transmitter found for dest relay ID %s, can't create contract transmitter", destRelayID) + } + + // TODO: Extract the correct transmitter address from the destsFromAccount + factory, transmitter, err := i.createFactoryAndTransmitter(config, destRelayID, contractReaders, chainWriters, destChainWriter, destFromAccounts) + if err != nil { + return nil, fmt.Errorf("failed to create factory and transmitter: %w", err) + } + + oracleArgs := libocr3.OCR3OracleArgs[[]byte]{ + BinaryNetworkEndpointFactory: i.peerWrapper.Peer2, + Database: i.db, + // NOTE: when specifying V2Bootstrappers here we actually do NOT need to run a full bootstrap node! + // Thus it is vital that the bootstrapper locators are correctly set in the job spec. + V2Bootstrappers: i.bootstrapperLocators, + ContractConfigTracker: configTracker, + ContractTransmitter: transmitter, + LocalConfig: defaultLocalConfig(), + Logger: ocrcommon.NewOCRWrapper( + i.lggr. + Named(fmt.Sprintf("CCIP%sOCR3", pluginType.String())). + Named(destRelayID.String()). + Named(hexutil.Encode(config.Config.OfframpAddress)), + false, + func(ctx context.Context, msg string) {}), + MetricsRegisterer: prometheus.WrapRegistererWith(map[string]string{"name": fmt.Sprintf("commit-%d", config.Config.ChainSelector)}, prometheus.DefaultRegisterer), + MonitoringEndpoint: i.monitoringEndpointGen.GenMonitoringEndpoint( + destChainFamily, + destRelayID.ChainID, + string(config.Config.OfframpAddress), + synchronization.OCR3CCIPCommit, + ), + OffchainConfigDigester: ocrimpls.NewConfigDigester(config.ConfigDigest), + OffchainKeyring: keybundle, + OnchainKeyring: onchainKeyring, + ReportingPluginFactory: factory, + } + oracle, err := libocr3.NewOracle(oracleArgs) + if err != nil { + return nil, err + } + return oracle, nil +} + +func (i *pluginOracleCreator) createFactoryAndTransmitter( + config cctypes.OCR3ConfigWithMeta, + destRelayID types.RelayID, + contractReaders map[cciptypes.ChainSelector]types.ContractReader, + chainWriters map[cciptypes.ChainSelector]types.ChainWriter, + destChainWriter types.ChainWriter, + destFromAccounts []string, +) (ocr3types.ReportingPluginFactory[[]byte], ocr3types.ContractTransmitter[[]byte], error) { + var factory ocr3types.ReportingPluginFactory[[]byte] + var transmitter ocr3types.ContractTransmitter[[]byte] + if config.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) { + factory = commitocr3.NewPluginFactory( + i.lggr. + Named("CCIPCommitPlugin"). + Named(destRelayID.String()). + Named(fmt.Sprintf("%d", config.Config.ChainSelector)). + Named(hexutil.Encode(config.Config.OfframpAddress)), + ccipreaderpkg.OCR3ConfigWithMeta(config), + ccipevm.NewCommitPluginCodecV1(), + ccipevm.NewMessageHasherV1(), + i.homeChainReader, + contractReaders, + chainWriters, + ) + transmitter = ocrimpls.NewCommitContractTransmitter[[]byte](destChainWriter, + ocrtypes.Account(destFromAccounts[0]), + hexutil.Encode(config.Config.OfframpAddress), // TODO: this works for evm only, how about non-evm? + ) + } else if config.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) { + factory = execocr3.NewPluginFactory( + i.lggr. + Named("CCIPExecPlugin"). + Named(destRelayID.String()). + Named(hexutil.Encode(config.Config.OfframpAddress)), + ccipreaderpkg.OCR3ConfigWithMeta(config), + ccipevm.NewExecutePluginCodecV1(), + ccipevm.NewMessageHasherV1(), + i.homeChainReader, + superfakes.NewNilTokenDataReader(), + ccipevm.NewGasEstimateProvider(), + contractReaders, + chainWriters, + ) + transmitter = ocrimpls.NewExecContractTransmitter[[]byte](destChainWriter, + ocrtypes.Account(destFromAccounts[0]), + hexutil.Encode(config.Config.OfframpAddress), // TODO: this works for evm only, how about non-evm? + ) + } else { + return nil, nil, fmt.Errorf("unsupported plugin type %d", config.Config.PluginType) + } + return factory, transmitter, nil +} + +func (i *pluginOracleCreator) createReadersAndWriters( + destChainID uint64, + pluginType cctypes.PluginType, + config cctypes.OCR3ConfigWithMeta, + execBatchGasLimit uint64, +) ( + map[cciptypes.ChainSelector]types.ContractReader, + map[cciptypes.ChainSelector]types.ChainWriter, + error, +) { contractReaders := make(map[cciptypes.ChainSelector]types.ContractReader) chainWriters := make(map[cciptypes.ChainSelector]types.ChainWriter) for _, chain := range i.chains.Slice() { @@ -194,7 +293,7 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp chainReaderConfig, ) if err2 != nil { - return nil, fmt.Errorf("failed to create contract reader for chain %s: %w", chain.ID(), err2) + return nil, nil, fmt.Errorf("failed to create contract reader for chain %s: %w", chain.ID(), err2) } if chain.ID().Uint64() == destChainID { @@ -207,7 +306,7 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp }, }) if err3 != nil { - return nil, fmt.Errorf("failed to bind chain reader for dest chain %s's offramp at %s: %w", chain.ID(), offrampAddressHex, err3) + return nil, nil, fmt.Errorf("failed to bind chain reader for dest chain %s's offramp at %s: %w", chain.ID(), offrampAddressHex, err3) } } @@ -215,7 +314,7 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp // maybe from the plugin directly? err2 = cr.Start(context.Background()) if err2 != nil { - return nil, fmt.Errorf("failed to start contract reader for chain %s: %w", chain.ID(), err2) + return nil, nil, fmt.Errorf("failed to start contract reader for chain %s: %w", chain.ID(), err2) } // Even though we only write to the dest chain, we need to create chain writers for all chains @@ -240,121 +339,25 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp ), ) if err2 != nil { - return nil, fmt.Errorf("failed to create chain writer for chain %s: %w", chain.ID(), err2) + return nil, nil, fmt.Errorf("failed to create chain writer for chain %s: %w", chain.ID(), err2) } // TODO: figure out shutdown. // maybe from the plugin directly? err2 = cw.Start(context.Background()) if err2 != nil { - return nil, fmt.Errorf("failed to start chain writer for chain %s: %w", chain.ID(), err2) + return nil, nil, fmt.Errorf("failed to start chain writer for chain %s: %w", chain.ID(), err2) } chainSelector, ok := chainsel.EvmChainIdToChainSelector()[chain.ID().Uint64()] if !ok { - return nil, fmt.Errorf("failed to get chain selector from chain ID %s", chain.ID()) + return nil, nil, fmt.Errorf("failed to get chain selector from chain ID %s", chain.ID()) } contractReaders[cciptypes.ChainSelector(chainSelector)] = cr chainWriters[cciptypes.ChainSelector(chainSelector)] = cw } - - // build the onchain keyring. it will be the signing key for the destination chain family. - keybundle, ok := i.ocrKeyBundles[destChainFamily] - if !ok { - return nil, fmt.Errorf("no OCR key bundle found for chain family %s, forgot to create one?", destChainFamily) - } - onchainKeyring := ocrimpls.NewOnchainKeyring[[]byte](keybundle, i.lggr) - - // build the contract transmitter - // assume that we are using the first account in the keybundle as the from account - // and that we are able to transmit to the dest chain. - // TODO: revisit this in the future, since not all oracles will be able to transmit to the dest chain. - destChainWriter, ok := chainWriters[config.Config.ChainSelector] - if !ok { - return nil, fmt.Errorf("no chain writer found for dest chain selector %d, can't create contract transmitter", - config.Config.ChainSelector) - } - destFromAccounts, ok := i.transmitters[destRelayID] - if !ok { - return nil, fmt.Errorf("no transmitter found for dest relay ID %s, can't create contract transmitter", destRelayID) - } - - // TODO: Extract the correct transmitter address from the destsFromAccount - var factory ocr3types.ReportingPluginFactory[[]byte] - var transmitter ocr3types.ContractTransmitter[[]byte] - if config.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) { - factory = commitocr3.NewPluginFactory( - i.lggr. - Named("CCIPCommitPlugin"). - Named(destRelayID.String()). - Named(fmt.Sprintf("%d", config.Config.ChainSelector)). - Named(hexutil.Encode(config.Config.OfframpAddress)), - ccipreaderpkg.OCR3ConfigWithMeta(config), - ccipevm.NewCommitPluginCodecV1(), - ccipevm.NewMessageHasherV1(), - i.homeChainReader, - contractReaders, - chainWriters, - ) - transmitter = ocrimpls.NewCommitContractTransmitter[[]byte](destChainWriter, - ocrtypes.Account(destFromAccounts[0]), - hexutil.Encode(config.Config.OfframpAddress), // TODO: this works for evm only, how about non-evm? - ) - } else if config.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) { - factory = execocr3.NewPluginFactory( - i.lggr. - Named("CCIPExecPlugin"). - Named(destRelayID.String()). - Named(hexutil.Encode(config.Config.OfframpAddress)), - ccipreaderpkg.OCR3ConfigWithMeta(config), - ccipevm.NewExecutePluginCodecV1(), - ccipevm.NewMessageHasherV1(), - i.homeChainReader, - superfakes.NewNilTokenDataReader(), - ccipevm.NewGasEstimateProvider(), // TODO: this works for evm only, how about non-evm? - contractReaders, - chainWriters, - ) - transmitter = ocrimpls.NewExecContractTransmitter[[]byte](destChainWriter, - ocrtypes.Account(destFromAccounts[0]), - hexutil.Encode(config.Config.OfframpAddress), // TODO: this works for evm only, how about non-evm? - ) - } else { - return nil, fmt.Errorf("unsupported plugin type %d", config.Config.PluginType) - } - - oracleArgs := libocr3.OCR3OracleArgs[[]byte]{ - BinaryNetworkEndpointFactory: i.peerWrapper.Peer2, - Database: i.db, - V2Bootstrappers: i.bootstrapperLocators, - ContractConfigTracker: configTracker, - ContractTransmitter: transmitter, - LocalConfig: defaultLocalConfig(), - Logger: ocrcommon.NewOCRWrapper( - i.lggr. - Named(fmt.Sprintf("CCIP%sOCR3", pluginType.String())). - Named(destRelayID.String()). - Named(hexutil.Encode(config.Config.OfframpAddress)), - false, - func(ctx context.Context, msg string) {}), - MetricsRegisterer: prometheus.WrapRegistererWith(map[string]string{"name": fmt.Sprintf("commit-%d", config.Config.ChainSelector)}, prometheus.DefaultRegisterer), - MonitoringEndpoint: i.monitoringEndpointGen.GenMonitoringEndpoint( - destChainFamily, - destRelayID.ChainID, - string(config.Config.OfframpAddress), - synchronization.OCR3CCIPCommit, - ), - OffchainConfigDigester: ocrimpls.NewConfigDigester(config.ConfigDigest), - OffchainKeyring: keybundle, - OnchainKeyring: onchainKeyring, - ReportingPluginFactory: factory, - } - oracle, err := libocr3.NewOracle(oracleArgs) - if err != nil { - return nil, err - } - return oracle, nil + return contractReaders, chainWriters, nil } func defaultLocalConfig() ocrtypes.LocalConfig { diff --git a/core/capabilities/ccip/types/mocks/oracle_creator.go b/core/capabilities/ccip/types/mocks/oracle_creator.go index d83ad042bf..1d327e9652 100644 --- a/core/capabilities/ccip/types/mocks/oracle_creator.go +++ b/core/capabilities/ccip/types/mocks/oracle_creator.go @@ -20,12 +20,12 @@ func (_m *OracleCreator) EXPECT() *OracleCreator_Expecter { return &OracleCreator_Expecter{mock: &_m.Mock} } -// CreateBootstrapOracle provides a mock function with given fields: config -func (_m *OracleCreator) CreateBootstrapOracle(config types.OCR3ConfigWithMeta) (types.CCIPOracle, error) { +// Create provides a mock function with given fields: config +func (_m *OracleCreator) Create(config types.OCR3ConfigWithMeta) (types.CCIPOracle, error) { ret := _m.Called(config) if len(ret) == 0 { - panic("no return value specified for CreateBootstrapOracle") + panic("no return value specified for Create") } var r0 types.CCIPOracle @@ -50,89 +50,75 @@ func (_m *OracleCreator) CreateBootstrapOracle(config types.OCR3ConfigWithMeta) return r0, r1 } -// OracleCreator_CreateBootstrapOracle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateBootstrapOracle' -type OracleCreator_CreateBootstrapOracle_Call struct { +// OracleCreator_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' +type OracleCreator_Create_Call struct { *mock.Call } -// CreateBootstrapOracle is a helper method to define mock.On call +// Create is a helper method to define mock.On call // - config types.OCR3ConfigWithMeta -func (_e *OracleCreator_Expecter) CreateBootstrapOracle(config interface{}) *OracleCreator_CreateBootstrapOracle_Call { - return &OracleCreator_CreateBootstrapOracle_Call{Call: _e.mock.On("CreateBootstrapOracle", config)} +func (_e *OracleCreator_Expecter) Create(config interface{}) *OracleCreator_Create_Call { + return &OracleCreator_Create_Call{Call: _e.mock.On("Create", config)} } -func (_c *OracleCreator_CreateBootstrapOracle_Call) Run(run func(config types.OCR3ConfigWithMeta)) *OracleCreator_CreateBootstrapOracle_Call { +func (_c *OracleCreator_Create_Call) Run(run func(config types.OCR3ConfigWithMeta)) *OracleCreator_Create_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(types.OCR3ConfigWithMeta)) }) return _c } -func (_c *OracleCreator_CreateBootstrapOracle_Call) Return(_a0 types.CCIPOracle, _a1 error) *OracleCreator_CreateBootstrapOracle_Call { +func (_c *OracleCreator_Create_Call) Return(_a0 types.CCIPOracle, _a1 error) *OracleCreator_Create_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *OracleCreator_CreateBootstrapOracle_Call) RunAndReturn(run func(types.OCR3ConfigWithMeta) (types.CCIPOracle, error)) *OracleCreator_CreateBootstrapOracle_Call { +func (_c *OracleCreator_Create_Call) RunAndReturn(run func(types.OCR3ConfigWithMeta) (types.CCIPOracle, error)) *OracleCreator_Create_Call { _c.Call.Return(run) return _c } -// CreatePluginOracle provides a mock function with given fields: pluginType, config -func (_m *OracleCreator) CreatePluginOracle(pluginType types.PluginType, config types.OCR3ConfigWithMeta) (types.CCIPOracle, error) { - ret := _m.Called(pluginType, config) +// Type provides a mock function with given fields: +func (_m *OracleCreator) Type() types.OracleType { + ret := _m.Called() if len(ret) == 0 { - panic("no return value specified for CreatePluginOracle") + panic("no return value specified for Type") } - var r0 types.CCIPOracle - var r1 error - if rf, ok := ret.Get(0).(func(types.PluginType, types.OCR3ConfigWithMeta) (types.CCIPOracle, error)); ok { - return rf(pluginType, config) - } - if rf, ok := ret.Get(0).(func(types.PluginType, types.OCR3ConfigWithMeta) types.CCIPOracle); ok { - r0 = rf(pluginType, config) + var r0 types.OracleType + if rf, ok := ret.Get(0).(func() types.OracleType); ok { + r0 = rf() } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(types.CCIPOracle) - } + r0 = ret.Get(0).(types.OracleType) } - if rf, ok := ret.Get(1).(func(types.PluginType, types.OCR3ConfigWithMeta) error); ok { - r1 = rf(pluginType, config) - } else { - r1 = ret.Error(1) - } - - return r0, r1 + return r0 } -// OracleCreator_CreatePluginOracle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePluginOracle' -type OracleCreator_CreatePluginOracle_Call struct { +// OracleCreator_Type_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Type' +type OracleCreator_Type_Call struct { *mock.Call } -// CreatePluginOracle is a helper method to define mock.On call -// - pluginType types.PluginType -// - config types.OCR3ConfigWithMeta -func (_e *OracleCreator_Expecter) CreatePluginOracle(pluginType interface{}, config interface{}) *OracleCreator_CreatePluginOracle_Call { - return &OracleCreator_CreatePluginOracle_Call{Call: _e.mock.On("CreatePluginOracle", pluginType, config)} +// Type is a helper method to define mock.On call +func (_e *OracleCreator_Expecter) Type() *OracleCreator_Type_Call { + return &OracleCreator_Type_Call{Call: _e.mock.On("Type")} } -func (_c *OracleCreator_CreatePluginOracle_Call) Run(run func(pluginType types.PluginType, config types.OCR3ConfigWithMeta)) *OracleCreator_CreatePluginOracle_Call { +func (_c *OracleCreator_Type_Call) Run(run func()) *OracleCreator_Type_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.PluginType), args[1].(types.OCR3ConfigWithMeta)) + run() }) return _c } -func (_c *OracleCreator_CreatePluginOracle_Call) Return(_a0 types.CCIPOracle, _a1 error) *OracleCreator_CreatePluginOracle_Call { - _c.Call.Return(_a0, _a1) +func (_c *OracleCreator_Type_Call) Return(_a0 types.OracleType) *OracleCreator_Type_Call { + _c.Call.Return(_a0) return _c } -func (_c *OracleCreator_CreatePluginOracle_Call) RunAndReturn(run func(types.PluginType, types.OCR3ConfigWithMeta) (types.CCIPOracle, error)) *OracleCreator_CreatePluginOracle_Call { +func (_c *OracleCreator_Type_Call) RunAndReturn(run func() types.OracleType) *OracleCreator_Type_Call { _c.Call.Return(run) return _c } diff --git a/core/capabilities/ccip/types/types.go b/core/capabilities/ccip/types/types.go index 952b8fe446..e42990f4c4 100644 --- a/core/capabilities/ccip/types/types.go +++ b/core/capabilities/ccip/types/types.go @@ -27,6 +27,13 @@ func (pt PluginType) String() string { } } +type OracleType uint8 + +const ( + OracleTypePlugin OracleType = 0 + OracleTypeBootstrap OracleType = 1 +) + // CCIPOracle represents either a CCIP commit or exec oracle or a bootstrap node. type CCIPOracle interface { Close() error @@ -36,11 +43,12 @@ type CCIPOracle interface { // OracleCreator is an interface for creating CCIP oracles. // Whether the oracle uses a LOOPP or not is an implementation detail. type OracleCreator interface { - // CreatePlugin creates a new oracle that will run either the commit or exec ccip plugin. + // Create creates a new oracle that will run either the commit or exec ccip plugin, + // if its a plugin oracle, or a bootstrap oracle if its a bootstrap oracle. // The oracle must be returned unstarted. - CreatePluginOracle(pluginType PluginType, config OCR3ConfigWithMeta) (CCIPOracle, error) + Create(config OCR3ConfigWithMeta) (CCIPOracle, error) - // CreateBootstrapOracle creates a new bootstrap node with the given OCR config. - // The oracle must be returned unstarted. - CreateBootstrapOracle(config OCR3ConfigWithMeta) (CCIPOracle, error) + // Type returns the type of oracle that this creator creates. + // The only valid values are OracleTypePlugin and OracleTypeBootstrap. + Type() OracleType } diff --git a/core/capabilities/ccip/validate/validate.go b/core/capabilities/ccip/validate/validate.go index 04f4f4a495..02e1cb5c8e 100644 --- a/core/capabilities/ccip/validate/validate.go +++ b/core/capabilities/ccip/validate/validate.go @@ -40,9 +40,6 @@ func ValidatedCCIPSpec(tomlString string) (jb job.Job, err error) { if jb.CCIPSpec.P2PKeyID == "" { return job.Job{}, fmt.Errorf("p2pKeyID must be set") } - if len(jb.CCIPSpec.P2PV2Bootstrappers) == 0 { - return job.Job{}, fmt.Errorf("p2pV2Bootstrappers must be set") - } // ensure that the P2PV2Bootstrappers is in the right format. for _, bootstrapperLocator := range jb.CCIPSpec.P2PV2Bootstrappers { diff --git a/integration-tests/deployment/README.md b/integration-tests/deployment/README.md index 7e0f82b546..1c2019b540 100644 --- a/integration-tests/deployment/README.md +++ b/integration-tests/deployment/README.md @@ -2,25 +2,25 @@ The deployment package in the integration-tests Go module serves as a product agnostic set of environment abstractions used to deploy and configure products including both on/offchain -dependencies. The environment abstractions allow for +dependencies. The environment abstractions allow for complex and critical deployment/configuration logic to be tested against ephemeral environments and then exposed for use in persistent -environments like testnet/mainnet. +environments like testnet/mainnet. ### Directory structure -/deployment +/deployment - package name `deployment` - Product agnostic environment abstractions and helpers using those -abstractions + abstractions /deployment/memory - package name `memory` - In-memory environment for fast integration testing -- EVM only +- EVM only /deployment/docker -- Coming soon +- Coming soon - package name `docker` - Docker environment for higher fidelity testing - Support non-EVMs @@ -30,12 +30,12 @@ abstractions - Files and tests per product deployment/configuration workflows - Tests can use deployment/memory for fast integration testing - TODO: System state representation is defined here, need to define -an interface to comply with for all products. + an interface to comply with for all products. /deployment/ccip/changeset -- package name `changeset` imported as `ccipchangesets` -- These function like scripts describing state transitions -you wish to apply to _persistent_ environments like testnet/mainnet +- package name `changeset` imported as `ccipchangesets` +- These function like scripts describing state transitions + you wish to apply to _persistent_ environments like testnet/mainnet - Ordered list of Go functions following the format ```Go 0001_descriptive_name.go diff --git a/integration-tests/deployment/address_book.go b/integration-tests/deployment/address_book.go index 409b3a482c..4a5916111c 100644 --- a/integration-tests/deployment/address_book.go +++ b/integration-tests/deployment/address_book.go @@ -1,25 +1,112 @@ package deployment -import "fmt" +import ( + "fmt" + "strings" + + "github.com/Masterminds/semver/v3" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + chainsel "github.com/smartcontractkit/chain-selectors" +) + +var ( + ErrInvalidChainSelector = fmt.Errorf("invalid chain selector") + ErrInvalidAddress = fmt.Errorf("invalid address") +) + +// ContractType is a simple string type for identifying contract types. +type ContractType string + +var ( + Version1_0_0 = *semver.MustParse("1.0.0") + Version1_1_0 = *semver.MustParse("1.1.0") + Version1_2_0 = *semver.MustParse("1.2.0") + Version1_5_0 = *semver.MustParse("1.5.0") + Version1_6_0_dev = *semver.MustParse("1.6.0-dev") +) + +type TypeAndVersion struct { + Type ContractType + Version semver.Version +} + +func (tv TypeAndVersion) String() string { + return fmt.Sprintf("%s %s", tv.Type, tv.Version.String()) +} + +func (tv TypeAndVersion) Equal(other TypeAndVersion) bool { + return tv.String() == other.String() +} + +func MustTypeAndVersionFromString(s string) TypeAndVersion { + tv, err := TypeAndVersionFromString(s) + if err != nil { + panic(err) + } + return tv +} + +// Note this will become useful for validation. When we want +// to assert an onchain call to typeAndVersion yields whats expected. +func TypeAndVersionFromString(s string) (TypeAndVersion, error) { + parts := strings.Split(s, " ") + if len(parts) != 2 { + return TypeAndVersion{}, fmt.Errorf("invalid type and version string: %s", s) + } + v, err := semver.NewVersion(parts[1]) + if err != nil { + return TypeAndVersion{}, err + } + return TypeAndVersion{ + Type: ContractType(parts[0]), + Version: *v, + }, nil +} + +func NewTypeAndVersion(t ContractType, v semver.Version) TypeAndVersion { + return TypeAndVersion{ + Type: t, + Version: v, + } +} // AddressBook is a simple interface for storing and retrieving contract addresses across -// chains. It is family agnostic. +// chains. It is family agnostic as the keys are chain selectors. +// We store rather than derive typeAndVersion as some contracts do not support it. +// For ethereum addresses are always stored in EIP55 format. type AddressBook interface { - Save(chainSelector uint64, address string, typeAndVersion string) error - Addresses() (map[uint64]map[string]string, error) - AddressesForChain(chain uint64) (map[string]string, error) + Save(chainSelector uint64, address string, tv TypeAndVersion) error + Addresses() (map[uint64]map[string]TypeAndVersion, error) + AddressesForChain(chain uint64) (map[string]TypeAndVersion, error) // Allows for merging address books (e.g. new deployments with existing ones) Merge(other AddressBook) error } type AddressBookMap struct { - AddressesByChain map[uint64]map[string]string + AddressesByChain map[uint64]map[string]TypeAndVersion } -func (m *AddressBookMap) Save(chainSelector uint64, address string, typeAndVersion string) error { +func (m *AddressBookMap) Save(chainSelector uint64, address string, typeAndVersion TypeAndVersion) error { + _, exists := chainsel.ChainBySelector(chainSelector) + if !exists { + return errors.Wrapf(ErrInvalidChainSelector, "chain selector %d not found", chainSelector) + } + if address == "" || address == common.HexToAddress("0x0").Hex() { + return errors.Wrap(ErrInvalidAddress, "address cannot be empty") + } + if common.IsHexAddress(address) { + // IMPORTANT: WE ALWAYS STANDARDIZE ETHEREUM ADDRESS STRINGS TO EIP55 + address = common.HexToAddress(address).Hex() + } else { + return errors.Wrapf(ErrInvalidAddress, "address %s is not a valid Ethereum address, only Ethereum addresses supported", address) + } + if typeAndVersion.Type == "" { + return fmt.Errorf("type cannot be empty") + } if _, exists := m.AddressesByChain[chainSelector]; !exists { // First time chain add, create map - m.AddressesByChain[chainSelector] = make(map[string]string) + m.AddressesByChain[chainSelector] = make(map[string]TypeAndVersion) } if _, exists := m.AddressesByChain[chainSelector][address]; exists { return fmt.Errorf("address %s already exists for chain %d", address, chainSelector) @@ -28,11 +115,11 @@ func (m *AddressBookMap) Save(chainSelector uint64, address string, typeAndVersi return nil } -func (m *AddressBookMap) Addresses() (map[uint64]map[string]string, error) { +func (m *AddressBookMap) Addresses() (map[uint64]map[string]TypeAndVersion, error) { return m.AddressesByChain, nil } -func (m *AddressBookMap) AddressesForChain(chain uint64) (map[string]string, error) { +func (m *AddressBookMap) AddressesForChain(chain uint64) (map[string]TypeAndVersion, error) { if _, exists := m.AddressesByChain[chain]; !exists { return nil, fmt.Errorf("chain %d not found", chain) } @@ -55,8 +142,17 @@ func (m *AddressBookMap) Merge(ab AddressBook) error { return nil } +// TODO: Maybe could add an environment argument +// which would ensure only mainnet/testnet chain selectors are used +// for further safety? func NewMemoryAddressBook() *AddressBookMap { return &AddressBookMap{ - AddressesByChain: make(map[uint64]map[string]string), + AddressesByChain: make(map[uint64]map[string]TypeAndVersion), + } +} + +func NewMemoryAddressBookFromMap(addressesByChain map[uint64]map[string]TypeAndVersion) *AddressBookMap { + return &AddressBookMap{ + AddressesByChain: addressesByChain, } } diff --git a/integration-tests/deployment/address_book_test.go b/integration-tests/deployment/address_book_test.go index d34053e89c..c6967df0ca 100644 --- a/integration-tests/deployment/address_book_test.go +++ b/integration-tests/deployment/address_book_test.go @@ -1,71 +1,112 @@ package deployment import ( + "errors" "testing" + "github.com/ethereum/go-ethereum/common" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" "gotest.tools/v3/assert" ) -func TestAddressBook(t *testing.T) { +func TestAddressBook_Save(t *testing.T) { ab := NewMemoryAddressBook() - err := ab.Save(1, "0x1", "OnRamp 1.0.0") + onRamp100 := NewTypeAndVersion("OnRamp", Version1_0_0) + onRamp110 := NewTypeAndVersion("OnRamp", Version1_1_0) + addr1 := common.HexToAddress("0x1").String() + addr2 := common.HexToAddress("0x2").String() + + err := ab.Save(chainsel.TEST_90000001.Selector, addr1, onRamp100) require.NoError(t, err) - // Duplicate address will error - err = ab.Save(1, "0x1", "OnRamp 1.0.0") + + // Check input validation + err = ab.Save(chainsel.TEST_90000001.Selector, "asdlfkj", onRamp100) + require.Error(t, err) + assert.Equal(t, errors.Is(err, ErrInvalidAddress), true, "err %s", err) + err = ab.Save(0, addr1, onRamp100) + require.Error(t, err) + assert.Equal(t, errors.Is(err, ErrInvalidChainSelector), true) + // Duplicate + err = ab.Save(chainsel.TEST_90000001.Selector, addr1, onRamp100) + require.Error(t, err) + // Zero address + err = ab.Save(chainsel.TEST_90000001.Selector, common.HexToAddress("0x0").Hex(), onRamp100) require.Error(t, err) + // Distinct address same TV will not - err = ab.Save(1, "0x2", "OnRamp 1.0.0") + err = ab.Save(chainsel.TEST_90000001.Selector, addr2, onRamp100) require.NoError(t, err) // Same address different chain will not error - err = ab.Save(2, "0x1", "OnRamp 1.0.0") + err = ab.Save(chainsel.TEST_90000002.Selector, addr1, onRamp100) require.NoError(t, err) // We can save different versions of the same contract - err = ab.Save(2, "0x2", "OnRamp 1.2.0") + err = ab.Save(chainsel.TEST_90000002.Selector, addr2, onRamp110) require.NoError(t, err) addresses, err := ab.Addresses() require.NoError(t, err) - assert.DeepEqual(t, addresses, map[uint64]map[string]string{ - 1: { - "0x1": "OnRamp 1.0.0", - "0x2": "OnRamp 1.0.0", + assert.DeepEqual(t, addresses, map[uint64]map[string]TypeAndVersion{ + chainsel.TEST_90000001.Selector: { + addr1: onRamp100, + addr2: onRamp100, }, - 2: { - "0x1": "OnRamp 1.0.0", - "0x2": "OnRamp 1.2.0", + chainsel.TEST_90000002.Selector: { + addr1: onRamp100, + addr2: onRamp110, }, }) +} - // Test merge - ab2 := NewMemoryAddressBook() - require.NoError(t, ab2.Save(3, "0x3", "OnRamp 1.0.0")) - require.NoError(t, ab.Merge(ab2)) - // Other address book should remain unchanged. - addresses, err = ab2.Addresses() - require.NoError(t, err) - assert.DeepEqual(t, addresses, map[uint64]map[string]string{ - 3: { - "0x3": "OnRamp 1.0.0", +func TestAddressBook_Merge(t *testing.T) { + onRamp100 := NewTypeAndVersion("OnRamp", Version1_0_0) + onRamp110 := NewTypeAndVersion("OnRamp", Version1_1_0) + addr1 := common.HexToAddress("0x1").String() + addr2 := common.HexToAddress("0x2").String() + a1 := NewMemoryAddressBookFromMap(map[uint64]map[string]TypeAndVersion{ + chainsel.TEST_90000001.Selector: { + addr1: onRamp100, }, }) - // Existing addressbook should contain the new elements. - addresses, err = ab.Addresses() - require.NoError(t, err) - assert.DeepEqual(t, addresses, map[uint64]map[string]string{ - 1: { - "0x1": "OnRamp 1.0.0", - "0x2": "OnRamp 1.0.0", + a2 := NewMemoryAddressBookFromMap(map[uint64]map[string]TypeAndVersion{ + chainsel.TEST_90000001.Selector: { + addr2: onRamp100, }, - 2: { - "0x1": "OnRamp 1.0.0", - "0x2": "OnRamp 1.2.0", + chainsel.TEST_90000002.Selector: { + addr1: onRamp110, }, - 3: { - "0x3": "OnRamp 1.0.0", + }) + require.NoError(t, a1.Merge(a2)) + + addresses, err := a1.Addresses() + require.NoError(t, err) + assert.DeepEqual(t, addresses, map[uint64]map[string]TypeAndVersion{ + chainsel.TEST_90000001.Selector: { + addr1: onRamp100, + addr2: onRamp100, + }, + chainsel.TEST_90000002.Selector: { + addr1: onRamp110, }, }) - // Merge to an existing chain. - require.NoError(t, ab2.Save(2, "0x3", "OffRamp 1.0.0")) + // Merge with conflicting addresses should error + a3 := NewMemoryAddressBookFromMap(map[uint64]map[string]TypeAndVersion{ + chainsel.TEST_90000001.Selector: { + addr1: onRamp100, + }, + }) + require.Error(t, a1.Merge(a3)) + // a1 should not have changed + addresses, err = a1.Addresses() + require.NoError(t, err) + assert.DeepEqual(t, addresses, map[uint64]map[string]TypeAndVersion{ + chainsel.TEST_90000001.Selector: { + addr1: onRamp100, + addr2: onRamp100, + }, + chainsel.TEST_90000002.Selector: { + addr1: onRamp110, + }, + }) } diff --git a/integration-tests/deployment/ccip/add_lane.go b/integration-tests/deployment/ccip/add_lane.go new file mode 100644 index 0000000000..7ea757f03a --- /dev/null +++ b/integration-tests/deployment/ccip/add_lane.go @@ -0,0 +1,120 @@ +package ccipdeployment + +import ( + "encoding/hex" + "math/big" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" +) + +func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) error { + // TODO: Batch + tx, err := state.Chains[from].Router.ApplyRampUpdates(e.Chains[from].DeployerKey, []router.RouterOnRamp{ + { + DestChainSelector: to, + OnRamp: state.Chains[from].EvmOnRampV160.Address(), + }, + }, []router.RouterOffRamp{}, []router.RouterOffRamp{}) + if _, err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { + return err + } + tx, err = state.Chains[from].EvmOnRampV160.ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, + []onramp.OnRampDestChainConfigArgs{ + { + DestChainSelector: to, + Router: state.Chains[from].Router.Address(), + }, + }) + if _, err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { + return err + } + + _, err = state.Chains[from].PriceRegistry.UpdatePrices( + e.Chains[from].DeployerKey, fee_quoter.InternalPriceUpdates{ + TokenPriceUpdates: []fee_quoter.InternalTokenPriceUpdate{ + { + SourceToken: state.Chains[from].LinkToken.Address(), + UsdPerToken: deployment.E18Mult(20), + }, + { + SourceToken: state.Chains[from].Weth9.Address(), + UsdPerToken: deployment.E18Mult(4000), + }, + }, + GasPriceUpdates: []fee_quoter.InternalGasPriceUpdate{ + { + DestChainSelector: to, + UsdPerUnitGas: big.NewInt(2e12), + }, + }}) + if _, err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { + return err + } + + // Enable dest in price registry + tx, err = state.Chains[from].PriceRegistry.ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, + []fee_quoter.FeeQuoterDestChainConfigArgs{ + { + DestChainSelector: to, + DestChainConfig: defaultPriceRegistryDestChainConfig(), + }, + }) + if _, err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { + return err + } + + tx, err = state.Chains[to].EvmOffRampV160.ApplySourceChainConfigUpdates(e.Chains[to].DeployerKey, + []offramp.OffRampSourceChainConfigArgs{ + { + Router: state.Chains[to].Router.Address(), + SourceChainSelector: from, + IsEnabled: true, + OnRamp: common.LeftPadBytes(state.Chains[from].EvmOnRampV160.Address().Bytes(), 32), + }, + }) + if _, err := deployment.ConfirmIfNoError(e.Chains[to], tx, err); err != nil { + return err + } + tx, err = state.Chains[to].Router.ApplyRampUpdates(e.Chains[to].DeployerKey, []router.RouterOnRamp{}, []router.RouterOffRamp{}, []router.RouterOffRamp{ + { + SourceChainSelector: from, + OffRamp: state.Chains[to].EvmOffRampV160.Address(), + }, + }) + _, err = deployment.ConfirmIfNoError(e.Chains[to], tx, err) + return err +} + +func defaultPriceRegistryDestChainConfig() fee_quoter.FeeQuoterDestChainConfig { + // https://github.com/smartcontractkit/ccip/blob/c4856b64bd766f1ddbaf5d13b42d3c4b12efde3a/contracts/src/v0.8/ccip/libraries/Internal.sol#L337-L337 + /* + ```Solidity + // bytes4(keccak256("CCIP ChainFamilySelector EVM")) + bytes4 public constant CHAIN_FAMILY_SELECTOR_EVM = 0x2812d52c; + ``` + */ + evmFamilySelector, _ := hex.DecodeString("2812d52c") + return fee_quoter.FeeQuoterDestChainConfig{ + IsEnabled: true, + MaxNumberOfTokensPerMsg: 10, + MaxDataBytes: 256, + MaxPerMsgGasLimit: 3_000_000, + DestGasOverhead: 50_000, + DefaultTokenFeeUSDCents: 1, + DestGasPerPayloadByte: 10, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 100, + DestDataAvailabilityMultiplierBps: 1, + DefaultTokenDestGasOverhead: 125_000, + DefaultTxGasLimit: 200_000, + GasMultiplierWeiPerEth: 1, + NetworkFeeUSDCents: 1, + ChainFamilySelector: [4]byte(evmFamilySelector), + } +} diff --git a/integration-tests/deployment/ccip/add_lane_test.go b/integration-tests/deployment/ccip/add_lane_test.go new file mode 100644 index 0000000000..567f5ca685 --- /dev/null +++ b/integration-tests/deployment/ccip/add_lane_test.go @@ -0,0 +1 @@ +package ccipdeployment diff --git a/integration-tests/deployment/ccip/changeset/1_cap_reg.go b/integration-tests/deployment/ccip/changeset/1_cap_reg.go new file mode 100644 index 0000000000..1929aede02 --- /dev/null +++ b/integration-tests/deployment/ccip/changeset/1_cap_reg.go @@ -0,0 +1,21 @@ +package changeset + +import ( + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" +) + +// Separate migration because cap reg is an env var for CL nodes. +func Apply0001(env deployment.Environment, homeChainSel uint64) (deployment.ChangesetOutput, error) { + // Note we also deploy the cap reg. + ab, _, err := ccipdeployment.DeployCapReg(env.Logger, env.Chains, homeChainSel) + if err != nil { + env.Logger.Errorw("Failed to deploy cap reg", "err", err, "addresses", ab) + return deployment.ChangesetOutput{}, err + } + return deployment.ChangesetOutput{ + Proposals: []deployment.Proposal{}, + AddressBook: ab, + JobSpecs: nil, + }, nil +} diff --git a/integration-tests/deployment/ccip/changeset/2_initial_deploy.go b/integration-tests/deployment/ccip/changeset/2_initial_deploy.go new file mode 100644 index 0000000000..b20ffb2d4a --- /dev/null +++ b/integration-tests/deployment/ccip/changeset/2_initial_deploy.go @@ -0,0 +1,33 @@ +package changeset + +import ( + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + + ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" +) + +// We expect the change set input to be unique per change set. +// TODO: Maybe there's a generics approach here? +// Note if the change set is a deployment and it fails we have 2 options: +// - Just throw away the addresses, fix issue and try again (potentially expensive on mainnet) +func Apply0002(env deployment.Environment, c ccipdeployment.DeployCCIPContractConfig) (deployment.ChangesetOutput, error) { + ab, err := ccipdeployment.DeployCCIPContracts(env, c) + if err != nil { + env.Logger.Errorw("Failed to deploy CCIP contracts", "err", err, "addresses", ab) + return deployment.ChangesetOutput{}, err + } + js, err := ccipdeployment.NewCCIPJobSpecs(env.NodeIDs, env.Offchain) + if err != nil { + return deployment.ChangesetOutput{}, err + } + proposal, err := ccipdeployment.GenerateAcceptOwnershipProposal(env, env.AllChainSelectors(), ab) + if err != nil { + return deployment.ChangesetOutput{}, err + } + return deployment.ChangesetOutput{ + Proposals: []deployment.Proposal{proposal}, + AddressBook: ab, + // Mapping of which nodes get which jobs. + JobSpecs: js, + }, nil +} diff --git a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go new file mode 100644 index 0000000000..1e0ee39c20 --- /dev/null +++ b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go @@ -0,0 +1,244 @@ +package changeset + +import ( + "context" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + + ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func Test0002_InitialDeploy(t *testing.T) { + lggr := logger.TestLogger(t) + ctx := ccipdeployment.Context(t) + tenv := ccipdeployment.NewDeployedTestEnvironment(t, lggr) + e := tenv.Env + nodes := tenv.Nodes + chains := e.Chains + + state, err := ccipdeployment.LoadOnchainState(tenv.Env, tenv.Ab) + require.NoError(t, err) + + // Apply migration + output, err := Apply0002(tenv.Env, ccipdeployment.DeployCCIPContractConfig{ + HomeChainSel: tenv.HomeChainSel, + // Capreg/config already exist. + CCIPOnChainState: state, + }) + require.NoError(t, err) + // Get new state after migration. + state, err = ccipdeployment.LoadOnchainState(e, output.AddressBook) + require.NoError(t, err) + + // Ensure capreg logs are up to date. + require.NoError(t, ReplayAllLogs(nodes, chains)) + + // Apply the jobs. + for nodeID, jobs := range output.JobSpecs { + for _, job := range jobs { + // Note these auto-accept + _, err := e.Offchain.ProposeJob(ctx, + &jobv1.ProposeJobRequest{ + NodeId: nodeID, + Spec: job, + }) + require.NoError(t, err) + } + } + // Wait for plugins to register filters? + // TODO: Investigate how to avoid. + time.Sleep(30 * time.Second) + + // Ensure job related logs are up to date. + require.NoError(t, ReplayAllLogs(nodes, chains)) + + // Send a request from every router + // Add all lanes + for source := range e.Chains { + for dest := range e.Chains { + if source != dest { + require.NoError(t, ccipdeployment.AddLane(e, state, source, dest)) + } + } + } + + // Send a message from each chain to every other chain. + for src, srcChain := range e.Chains { + for dest := range e.Chains { + if src == dest { + continue + } + msg := router.ClientEVM2AnyMessage{ + Receiver: common.LeftPadBytes(state.Chains[dest].Receiver.Address().Bytes(), 32), + Data: []byte("hello"), + TokenAmounts: nil, // TODO: no tokens for now + FeeToken: state.Chains[src].Weth9.Address(), + ExtraArgs: nil, // TODO: no extra args for now, falls back to default + } + fee, err := state.Chains[src].Router.GetFee( + &bind.CallOpts{Context: context.Background()}, dest, msg) + require.NoError(t, err, deployment.MaybeDataErr(err)) + tx, err := state.Chains[src].Weth9.Deposit(&bind.TransactOpts{ + From: e.Chains[src].DeployerKey.From, + Signer: e.Chains[src].DeployerKey.Signer, + Value: fee, + }) + require.NoError(t, err) + _, err = srcChain.Confirm(tx.Hash()) + require.NoError(t, err) + + // TODO: should be able to avoid this by using native? + tx, err = state.Chains[src].Weth9.Approve(e.Chains[src].DeployerKey, + state.Chains[src].Router.Address(), fee) + require.NoError(t, err) + _, err = srcChain.Confirm(tx.Hash()) + require.NoError(t, err) + + t.Logf("Sending CCIP request from chain selector %d to chain selector %d", + src, dest) + tx, err = state.Chains[src].Router.CcipSend(e.Chains[src].DeployerKey, dest, msg) + require.NoError(t, err) + _, err = srcChain.Confirm(tx.Hash()) + require.NoError(t, err) + } + } + + // Wait for all commit reports to land. + var wg sync.WaitGroup + for src, srcChain := range e.Chains { + for dest, dstChain := range e.Chains { + if src == dest { + continue + } + srcChain := srcChain + dstChain := dstChain + wg.Add(1) + go func(src, dest uint64) { + defer wg.Done() + waitForCommitWithInterval(t, srcChain, dstChain, state.Chains[dest].EvmOffRampV160, ccipocr3.SeqNumRange{1, 1}) + }(src, dest) + } + } + wg.Wait() + + // Wait for all exec reports to land + for src, srcChain := range e.Chains { + for dest, dstChain := range e.Chains { + if src == dest { + continue + } + srcChain := srcChain + dstChain := dstChain + wg.Add(1) + go func(src, dest deployment.Chain) { + defer wg.Done() + waitForExecWithSeqNr(t, src, dest, state.Chains[dest.Selector].EvmOffRampV160, 1) + }(srcChain, dstChain) + } + } + wg.Wait() + + // TODO: Apply the proposal. +} + +func ReplayAllLogs(nodes map[string]memory.Node, chains map[uint64]deployment.Chain) error { + for _, node := range nodes { + for sel := range chains { + if err := node.ReplayLogs(map[uint64]uint64{sel: 1}); err != nil { + return err + } + } + } + return nil +} + +func waitForCommitWithInterval( + t *testing.T, + src deployment.Chain, + dest deployment.Chain, + offRamp *offramp.OffRamp, + expectedSeqNumRange ccipocr3.SeqNumRange, +) { + sink := make(chan *offramp.OffRampCommitReportAccepted) + subscription, err := offRamp.WatchCommitReportAccepted(&bind.WatchOpts{ + Context: context.Background(), + }, sink) + require.NoError(t, err) + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + + //revive:disable + for { + select { + case <-ticker.C: + src.Client.(*backends.SimulatedBackend).Commit() + dest.Client.(*backends.SimulatedBackend).Commit() + t.Logf("Waiting for commit report on chain selector %d from source selector %d expected seq nr range %s", + dest.Selector, src.Selector, expectedSeqNumRange.String()) + case subErr := <-subscription.Err(): + t.Fatalf("Subscription error: %+v", subErr) + case report := <-sink: + if len(report.Report.MerkleRoots) > 0 { + // Check the interval of sequence numbers and make sure it matches + // the expected range. + for _, mr := range report.Report.MerkleRoots { + if mr.SourceChainSelector == src.Selector && + uint64(expectedSeqNumRange.Start()) == mr.Interval.Min && + uint64(expectedSeqNumRange.End()) == mr.Interval.Max { + t.Logf("Received commit report on selector %d from source selector %d expected seq nr range %s", + dest.Selector, src.Selector, expectedSeqNumRange.String()) + return + } + } + } + } + } +} + +func waitForExecWithSeqNr(t *testing.T, + source, dest deployment.Chain, + offramp *offramp.OffRamp, + expectedSeqNr uint64) { + tick := time.NewTicker(5 * time.Second) + defer tick.Stop() + for range tick.C { + // TODO: Clean this up + source.Client.(*backends.SimulatedBackend).Commit() + dest.Client.(*backends.SimulatedBackend).Commit() + scc, err := offramp.GetSourceChainConfig(nil, source.Selector) + require.NoError(t, err) + t.Logf("Waiting for ExecutionStateChanged on chain %d from chain %d with expected sequence number %d, current onchain minSeqNr: %d", + dest.Selector, source.Selector, expectedSeqNr, scc.MinSeqNr) + iter, err := offramp.FilterExecutionStateChanged(nil, + []uint64{source.Selector}, []uint64{expectedSeqNr}, nil) + require.NoError(t, err) + var count int + for iter.Next() { + if iter.Event.SequenceNumber == expectedSeqNr && iter.Event.SourceChainSelector == source.Selector { + count++ + } + } + if count == 1 { + t.Logf("Received ExecutionStateChanged on chain %d from chain %d with expected sequence number %d", + dest.Selector, source.Selector, expectedSeqNr) + return + } + } +} diff --git a/integration-tests/deployment/ccip/deploy.go b/integration-tests/deployment/ccip/deploy.go new file mode 100644 index 0000000000..be546c2e66 --- /dev/null +++ b/integration-tests/deployment/ccip/deploy.go @@ -0,0 +1,471 @@ +package ccipdeployment + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" +) + +var ( + MockARM deployment.ContractType = "MockRMN" + LinkToken deployment.ContractType = "LinkToken" + ARMProxy deployment.ContractType = "ARMProxy" + WETH9 deployment.ContractType = "WETH9" + Router deployment.ContractType = "Router" + TokenAdminRegistry deployment.ContractType = "TokenAdminRegistry" + NonceManager deployment.ContractType = "NonceManager" + PriceRegistry deployment.ContractType = "PriceRegistry" + ManyChainMultisig deployment.ContractType = "ManyChainMultiSig" + CCIPConfig deployment.ContractType = "CCIPConfig" + RBACTimelock deployment.ContractType = "RBACTimelock" + OnRamp deployment.ContractType = "OnRamp" + OffRamp deployment.ContractType = "OffRamp" + CCIPReceiver deployment.ContractType = "CCIPReceiver" + CapabilitiesRegistry deployment.ContractType = "CapabilitiesRegistry" +) + +type Contracts interface { + *capabilities_registry.CapabilitiesRegistry | + *rmn_proxy_contract.RMNProxyContract | + *ccip_config.CCIPConfig | + *nonce_manager.NonceManager | + *fee_quoter.FeeQuoter | + *router.Router | + *token_admin_registry.TokenAdminRegistry | + *weth9.WETH9 | + *mock_rmn_contract.MockRMNContract | + *owner_helpers.ManyChainMultiSig | + *owner_helpers.RBACTimelock | + *offramp.OffRamp | + *onramp.OnRamp | + *burn_mint_erc677.BurnMintERC677 | + *maybe_revert_message_receiver.MaybeRevertMessageReceiver +} + +type ContractDeploy[C Contracts] struct { + // We just keep all the deploy return values + // since some will be empty if there's an error. + Address common.Address + Contract C + Tx *types.Transaction + Tv deployment.TypeAndVersion + Err error +} + +// TODO: pull up to general deployment pkg somehow +// without exposing all product specific contracts? +func deployContract[C Contracts]( + lggr logger.Logger, + chain deployment.Chain, + addressBook deployment.AddressBook, + deploy func(chain deployment.Chain) ContractDeploy[C], +) (*ContractDeploy[C], error) { + contractDeploy := deploy(chain) + if contractDeploy.Err != nil { + lggr.Errorw("Failed to deploy contract", "err", contractDeploy.Err) + return nil, contractDeploy.Err + } + _, err := chain.Confirm(contractDeploy.Tx.Hash()) + if err != nil { + lggr.Errorw("Failed to confirm deployment", "err", err) + return nil, err + } + err = addressBook.Save(chain.Selector, contractDeploy.Address.String(), contractDeploy.Tv) + if err != nil { + lggr.Errorw("Failed to save contract address", "err", err) + return nil, err + } + return &contractDeploy, nil +} + +type DeployCCIPContractConfig struct { + HomeChainSel uint64 + // Existing contracts which we want to skip deployment + // Leave empty if we want to deploy everything + // TODO: Add skips to deploy function. + CCIPOnChainState +} + +// TODO: Likely we'll want to further parameterize the deployment +// For example a list of contracts to skip deploying if they already exist. +// Or mock vs real RMN. +// Deployment produces an address book of everything it deployed. +func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) (deployment.AddressBook, error) { + var ab deployment.AddressBook = deployment.NewMemoryAddressBook() + nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) + if err != nil || len(nodes) == 0 { + e.Logger.Errorw("Failed to get node info", "err", err) + return ab, err + } + if c.Chains[c.HomeChainSel].CapabilityRegistry == nil { + return ab, fmt.Errorf("Capability registry not found for home chain %d, needs to be deployed first", c.HomeChainSel) + } + cr, err := c.Chains[c.HomeChainSel].CapabilityRegistry.GetHashedCapabilityId( + &bind.CallOpts{}, CapabilityLabelledName, CapabilityVersion) + if err != nil { + e.Logger.Errorw("Failed to get hashed capability id", "err", err) + return ab, err + } + // Signal to CR that our nodes support CCIP capability. + if err := AddNodes( + c.Chains[c.HomeChainSel].CapabilityRegistry, + e.Chains[c.HomeChainSel], + nodes.PeerIDs(c.HomeChainSel), // Doesn't actually matter which sel here + [][32]byte{cr}, + ); err != nil { + return ab, err + } + + for _, chain := range e.Chains { + ab, err = DeployChainContracts(e, chain, ab) + if err != nil { + return ab, err + } + chainAddresses, err := ab.AddressesForChain(chain.Selector) + if err != nil { + e.Logger.Errorw("Failed to get chain addresses", "err", err) + return ab, err + } + chainState, err := LoadChainState(chain, chainAddresses) + if err != nil { + e.Logger.Errorw("Failed to load chain state", "err", err) + return ab, err + } + // Enable ramps on price registry/nonce manager + tx, err := chainState.PriceRegistry.ApplyAuthorizedCallerUpdates(chain.DeployerKey, fee_quoter.AuthorizedCallersAuthorizedCallerArgs{ + // TODO: We enable the deployer initially to set prices + AddedCallers: []common.Address{chainState.EvmOffRampV160.Address(), chain.DeployerKey.From}, + }) + if _, err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { + e.Logger.Errorw("Failed to confirm price registry authorized caller update", "err", err) + return ab, err + } + + tx, err = chainState.NonceManager.ApplyAuthorizedCallerUpdates(chain.DeployerKey, nonce_manager.AuthorizedCallersAuthorizedCallerArgs{ + AddedCallers: []common.Address{chainState.EvmOffRampV160.Address(), chainState.EvmOnRampV160.Address()}, + }) + if _, err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { + e.Logger.Errorw("Failed to update nonce manager with ramps", "err", err) + return ab, err + } + + // Add chain config for each chain. + _, err = AddChainConfig(e.Logger, + e.Chains[c.HomeChainSel], + c.Chains[c.HomeChainSel].CCIPConfig, + chain.Selector, + nodes.PeerIDs(chain.Selector), + uint8(len(nodes)/3)) + if err != nil { + return ab, err + } + + // For each chain, we create a DON on the home chain. + if err := AddDON(e.Logger, + cr, + c.Chains[c.HomeChainSel].CapabilityRegistry, + c.Chains[c.HomeChainSel].CCIPConfig, + chainState.EvmOffRampV160, + chain, + e.Chains[c.HomeChainSel], + uint8(len(nodes)/3), + nodes.BootstrapPeerIDs(chain.Selector)[0], + nodes.PeerIDs(chain.Selector), + nodes, + ); err != nil { + e.Logger.Errorw("Failed to add DON", "err", err) + return ab, err + } + } + + return ab, nil +} + +func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab deployment.AddressBook) (deployment.AddressBook, error) { + ccipReceiver, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver] { + receiverAddr, tx, receiver, err2 := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver( + chain.DeployerKey, + chain.Client, + false, + ) + return ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver]{ + receiverAddr, receiver, tx, deployment.NewTypeAndVersion(CCIPReceiver, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy receiver", "err", err) + return ab, err + } + e.Logger.Infow("deployed receiver", "addr", ccipReceiver.Address) + + // TODO: Still waiting for RMNRemote/RMNHome contracts etc. + mockARM, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*mock_rmn_contract.MockRMNContract] { + mockARMAddr, tx, mockARM, err2 := mock_rmn_contract.DeployMockRMNContract( + chain.DeployerKey, + chain.Client, + ) + return ContractDeploy[*mock_rmn_contract.MockRMNContract]{ + mockARMAddr, mockARM, tx, deployment.NewTypeAndVersion(MockARM, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy mockARM", "err", err) + return ab, err + } + e.Logger.Infow("deployed mockARM", "addr", mockARM) + + mcm, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*owner_helpers.ManyChainMultiSig] { + mcmAddr, tx, mcm, err2 := owner_helpers.DeployManyChainMultiSig( + chain.DeployerKey, + chain.Client, + ) + return ContractDeploy[*owner_helpers.ManyChainMultiSig]{ + mcmAddr, mcm, tx, deployment.NewTypeAndVersion(ManyChainMultisig, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy mcm", "err", err) + return ab, err + } + // TODO: Address soon + e.Logger.Infow("deployed mcm", "addr", mcm.Address) + + _, err = deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*owner_helpers.RBACTimelock] { + timelock, tx, cc, err2 := owner_helpers.DeployRBACTimelock( + chain.DeployerKey, + chain.Client, + big.NewInt(0), // minDelay + mcm.Address, + []common.Address{mcm.Address}, // proposers + []common.Address{chain.DeployerKey.From}, //executors + []common.Address{mcm.Address}, // cancellers + []common.Address{mcm.Address}, // bypassers + ) + return ContractDeploy[*owner_helpers.RBACTimelock]{ + timelock, cc, tx, deployment.NewTypeAndVersion(RBACTimelock, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy timelock", "err", err) + return ab, err + } + e.Logger.Infow("deployed timelock", "addr", mcm.Address) + + rmnProxy, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*rmn_proxy_contract.RMNProxyContract] { + rmnProxyAddr, tx, rmnProxy, err2 := rmn_proxy_contract.DeployRMNProxyContract( + chain.DeployerKey, + chain.Client, + mockARM.Address, + ) + return ContractDeploy[*rmn_proxy_contract.RMNProxyContract]{ + rmnProxyAddr, rmnProxy, tx, deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy rmnProxy", "err", err) + return ab, err + } + e.Logger.Infow("deployed rmnProxy", "addr", rmnProxy.Address) + + weth9, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*weth9.WETH9] { + weth9Addr, tx, weth9c, err2 := weth9.DeployWETH9( + chain.DeployerKey, + chain.Client, + ) + return ContractDeploy[*weth9.WETH9]{ + weth9Addr, weth9c, tx, deployment.NewTypeAndVersion(WETH9, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy weth9", "err", err) + return ab, err + } + + linkToken, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*burn_mint_erc677.BurnMintERC677] { + linkTokenAddr, tx, linkToken, err2 := burn_mint_erc677.DeployBurnMintERC677( + chain.DeployerKey, + chain.Client, + "Link Token", + "LINK", + uint8(18), + big.NewInt(0).Mul(big.NewInt(1e9), big.NewInt(1e18)), + ) + return ContractDeploy[*burn_mint_erc677.BurnMintERC677]{ + linkTokenAddr, linkToken, tx, deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy linkToken", "err", err) + return ab, err + } + + routerContract, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*router.Router] { + routerAddr, tx, routerC, err2 := router.DeployRouter( + chain.DeployerKey, + chain.Client, + weth9.Address, + rmnProxy.Address, + ) + return ContractDeploy[*router.Router]{ + routerAddr, routerC, tx, deployment.NewTypeAndVersion(Router, deployment.Version1_2_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy router", "err", err) + return ab, err + } + e.Logger.Infow("deployed router", "addr", routerContract) + + tokenAdminRegistry, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*token_admin_registry.TokenAdminRegistry] { + tokenAdminRegistryAddr, tx, tokenAdminRegistry, err2 := token_admin_registry.DeployTokenAdminRegistry( + chain.DeployerKey, + chain.Client) + return ContractDeploy[*token_admin_registry.TokenAdminRegistry]{ + tokenAdminRegistryAddr, tokenAdminRegistry, tx, deployment.NewTypeAndVersion(TokenAdminRegistry, deployment.Version1_5_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy token admin registry", "err", err) + return ab, err + } + e.Logger.Infow("deployed tokenAdminRegistry", "addr", tokenAdminRegistry) + + nonceManager, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*nonce_manager.NonceManager] { + nonceManagerAddr, tx, nonceManager, err2 := nonce_manager.DeployNonceManager( + chain.DeployerKey, + chain.Client, + []common.Address{}, // Need to add onRamp after + ) + return ContractDeploy[*nonce_manager.NonceManager]{ + nonceManagerAddr, nonceManager, tx, deployment.NewTypeAndVersion(NonceManager, deployment.Version1_6_0_dev), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy router", "err", err) + return ab, err + } + + feeQuoter, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*fee_quoter.FeeQuoter] { + prAddr, tx, pr, err2 := fee_quoter.DeployFeeQuoter( + chain.DeployerKey, + chain.Client, + fee_quoter.FeeQuoterStaticConfig{ + MaxFeeJuelsPerMsg: big.NewInt(0).Mul(big.NewInt(2e2), big.NewInt(1e18)), + LinkToken: linkToken.Address, + StalenessThreshold: uint32(24 * 60 * 60), + }, + []common.Address{}, // ramps added after + []common.Address{weth9.Address, linkToken.Address}, // fee tokens + []fee_quoter.FeeQuoterTokenPriceFeedUpdate{}, + []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs{}, // TODO: tokens + []fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs{ + { + PremiumMultiplierWeiPerEth: 9e17, // 0.9 ETH + Token: linkToken.Address, + }, + { + PremiumMultiplierWeiPerEth: 1e18, + Token: weth9.Address, + }, + }, + []fee_quoter.FeeQuoterDestChainConfigArgs{}, + ) + return ContractDeploy[*fee_quoter.FeeQuoter]{ + prAddr, pr, tx, deployment.NewTypeAndVersion(PriceRegistry, deployment.Version1_6_0_dev), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy price registry", "err", err) + return ab, err + } + + onRamp, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*onramp.OnRamp] { + onRampAddr, tx, onRamp, err2 := onramp.DeployOnRamp( + chain.DeployerKey, + chain.Client, + onramp.OnRampStaticConfig{ + ChainSelector: chain.Selector, + RmnProxy: rmnProxy.Address, + NonceManager: nonceManager.Address, + TokenAdminRegistry: tokenAdminRegistry.Address, + }, + onramp.OnRampDynamicConfig{ + FeeQuoter: feeQuoter.Address, + FeeAggregator: common.HexToAddress("0x1"), // TODO real fee aggregator + }, + []onramp.OnRampDestChainConfigArgs{}, + ) + return ContractDeploy[*onramp.OnRamp]{ + onRampAddr, onRamp, tx, deployment.NewTypeAndVersion(OnRamp, deployment.Version1_6_0_dev), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy onramp", "err", err) + return ab, err + } + e.Logger.Infow("deployed onramp", "addr", onRamp.Address) + + offRamp, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*offramp.OffRamp] { + offRampAddr, tx, offRamp, err2 := offramp.DeployOffRamp( + chain.DeployerKey, + chain.Client, + offramp.OffRampStaticConfig{ + ChainSelector: chain.Selector, + RmnProxy: rmnProxy.Address, + NonceManager: nonceManager.Address, + TokenAdminRegistry: tokenAdminRegistry.Address, + }, + offramp.OffRampDynamicConfig{ + FeeQuoter: feeQuoter.Address, + PermissionLessExecutionThresholdSeconds: uint32(86400), + MaxTokenTransferGas: uint32(200_000), + MaxPoolReleaseOrMintGas: uint32(200_000), + }, + []offramp.OffRampSourceChainConfigArgs{}, + ) + return ContractDeploy[*offramp.OffRamp]{ + offRampAddr, offRamp, tx, deployment.NewTypeAndVersion(OffRamp, deployment.Version1_6_0_dev), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy offramp", "err", err) + return ab, err + } + e.Logger.Infow("deployed offramp", "addr", offRamp) + return ab, nil +} diff --git a/integration-tests/deployment/ccip/deploy_home_chain.go b/integration-tests/deployment/ccip/deploy_home_chain.go new file mode 100644 index 0000000000..d5b33d5050 --- /dev/null +++ b/integration-tests/deployment/ccip/deploy_home_chain.go @@ -0,0 +1,402 @@ +package ccipdeployment + +import ( + "bytes" + "context" + "errors" + "sort" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + + "github.com/smartcontractkit/chainlink-ccip/chainconfig" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ocr3_config_encoder" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" +) + +const ( + NodeOperatorID = 1 + CapabilityLabelledName = "ccip" + CapabilityVersion = "v1.0.0" + + FirstBlockAge = 8 * time.Hour + RemoteGasPriceBatchWriteFrequency = 30 * time.Minute + BatchGasLimit = 6_500_000 + RelativeBoostPerWaitHour = 1.5 + InflightCacheExpiry = 10 * time.Minute + RootSnoozeTime = 30 * time.Minute + BatchingStrategyID = 0 + DeltaProgress = 30 * time.Second + DeltaResend = 10 * time.Second + DeltaInitial = 20 * time.Second + DeltaRound = 2 * time.Second + DeltaGrace = 2 * time.Second + DeltaCertifiedCommitRequest = 10 * time.Second + DeltaStage = 10 * time.Second + Rmax = 3 + MaxDurationQuery = 50 * time.Millisecond + MaxDurationObservation = 5 * time.Second + MaxDurationShouldAcceptAttestedReport = 10 * time.Second + MaxDurationShouldTransmitAcceptedReport = 10 * time.Second +) + +func DeployCapReg(lggr logger.Logger, chains map[uint64]deployment.Chain, chainSel uint64) (deployment.AddressBook, common.Address, error) { + ab := deployment.NewMemoryAddressBook() + chain := chains[chainSel] + capReg, err := deployContract(lggr, chain, ab, + func(chain deployment.Chain) ContractDeploy[*capabilities_registry.CapabilitiesRegistry] { + crAddr, tx, cr, err2 := capabilities_registry.DeployCapabilitiesRegistry( + chain.DeployerKey, + chain.Client, + ) + return ContractDeploy[*capabilities_registry.CapabilitiesRegistry]{ + Address: crAddr, Contract: cr, Tv: deployment.NewTypeAndVersion(CapabilitiesRegistry, deployment.Version1_0_0), Tx: tx, Err: err2, + } + }) + if err != nil { + lggr.Errorw("Failed to deploy capreg", "err", err) + return ab, common.Address{}, err + } + lggr.Infow("deployed capreg", "addr", capReg.Address) + ccipConfig, err := deployContract( + lggr, chain, ab, + func(chain deployment.Chain) ContractDeploy[*ccip_config.CCIPConfig] { + ccAddr, tx, cc, err2 := ccip_config.DeployCCIPConfig( + chain.DeployerKey, + chain.Client, + capReg.Address, + ) + return ContractDeploy[*ccip_config.CCIPConfig]{ + Address: ccAddr, Tv: deployment.NewTypeAndVersion(CCIPConfig, deployment.Version1_6_0_dev), Tx: tx, Err: err2, Contract: cc, + } + }) + if err != nil { + lggr.Errorw("Failed to deploy ccip config", "err", err) + return ab, common.Address{}, err + } + lggr.Infow("deployed ccip config", "addr", ccipConfig.Address) + + tx, err := capReg.Contract.AddCapabilities(chain.DeployerKey, []capabilities_registry.CapabilitiesRegistryCapability{ + { + LabelledName: CapabilityLabelledName, + Version: CapabilityVersion, + CapabilityType: 2, // consensus. not used (?) + ResponseType: 0, // report. not used (?) + ConfigurationContract: ccipConfig.Address, + }, + }) + if _, err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { + lggr.Errorw("Failed to add capabilities", "err", err) + return ab, common.Address{}, err + } + // TODO: Just one for testing. + tx, err = capReg.Contract.AddNodeOperators(chain.DeployerKey, []capabilities_registry.CapabilitiesRegistryNodeOperator{ + { + Admin: chain.DeployerKey.From, + Name: "NodeOperator", + }, + }) + if _, err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { + lggr.Errorw("Failed to add node operators", "err", err) + return ab, common.Address{}, err + } + return ab, capReg.Address, nil +} + +func sortP2PIDS(p2pIDs [][32]byte) { + sort.Slice(p2pIDs, func(i, j int) bool { + return bytes.Compare(p2pIDs[i][:], p2pIDs[j][:]) < 0 + }) +} + +func AddNodes( + capReg *capabilities_registry.CapabilitiesRegistry, + chain deployment.Chain, + p2pIDs [][32]byte, + capabilityIDs [][32]byte, +) error { + // Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail + sortP2PIDS(p2pIDs) + var nodeParams []capabilities_registry.CapabilitiesRegistryNodeParams + for _, p2pID := range p2pIDs { + nodeParam := capabilities_registry.CapabilitiesRegistryNodeParams{ + NodeOperatorId: NodeOperatorID, + Signer: p2pID, // Not used in tests + P2pId: p2pID, + HashedCapabilityIds: capabilityIDs, + } + nodeParams = append(nodeParams, nodeParam) + } + tx, err := capReg.AddNodes(chain.DeployerKey, nodeParams) + if err != nil { + return err + } + _, err = chain.Confirm(tx.Hash()) + return err +} + +func SetupConfigInfo(chainSelector uint64, readers [][32]byte, fChain uint8, cfg []byte) ccip_config.CCIPConfigTypesChainConfigInfo { + return ccip_config.CCIPConfigTypesChainConfigInfo{ + ChainSelector: chainSelector, + ChainConfig: ccip_config.CCIPConfigTypesChainConfig{ + Readers: readers, + FChain: fChain, + Config: cfg, + }, + } +} + +func AddChainConfig( + lggr logger.Logger, + h deployment.Chain, + ccipConfig *ccip_config.CCIPConfig, + chainSelector uint64, + p2pIDs [][32]byte, + f uint8, +) (ccip_config.CCIPConfigTypesChainConfigInfo, error) { + // Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail + sortP2PIDS(p2pIDs) + // First Add ChainConfig that includes all p2pIDs as readers + encodedExtraChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ + GasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(1000), + DAGasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(0), + FinalityDepth: 10, + OptimisticConfirmations: 1, + }) + if err != nil { + return ccip_config.CCIPConfigTypesChainConfigInfo{}, err + } + chainConfig := SetupConfigInfo(chainSelector, p2pIDs, f, encodedExtraChainConfig) + inputConfig := []ccip_config.CCIPConfigTypesChainConfigInfo{ + chainConfig, + } + tx, err := ccipConfig.ApplyChainConfigUpdates(h.DeployerKey, nil, inputConfig) + if _, err := deployment.ConfirmIfNoError(h, tx, err); err != nil { + return ccip_config.CCIPConfigTypesChainConfigInfo{}, err + } + lggr.Infow("Applied chain config updates", "chainConfig", chainConfig) + return chainConfig, nil +} + +func AddDON( + lggr logger.Logger, + ccipCapabilityID [32]byte, + capReg *capabilities_registry.CapabilitiesRegistry, + ccipConfig *ccip_config.CCIPConfig, + offRamp *offramp.OffRamp, + dest deployment.Chain, + home deployment.Chain, + f uint8, + bootstrapP2PID [32]byte, + p2pIDs [][32]byte, + nodes []deployment.Node, +) error { + sortP2PIDS(p2pIDs) + // Get OCR3 Config from helper + var schedule []int + var oracles []confighelper2.OracleIdentityExtra + for _, node := range nodes { + schedule = append(schedule, 1) + cfg := node.SelToOCRConfig[dest.Selector] + oracles = append(oracles, confighelper2.OracleIdentityExtra{ + OracleIdentity: confighelper2.OracleIdentity{ + OnchainPublicKey: cfg.OnchainPublicKey, + TransmitAccount: cfg.TransmitAccount, + OffchainPublicKey: cfg.OffchainPublicKey, + PeerID: cfg.PeerID.String()[4:], + }, ConfigEncryptionPublicKey: cfg.ConfigEncryptionPublicKey, + }) + } + + tabi, err := ocr3_config_encoder.IOCR3ConfigEncoderMetaData.GetAbi() + if err != nil { + return err + } + + // Add DON on capability registry contract + var ocr3Configs []ocr3_config_encoder.CCIPConfigTypesOCR3Config + for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { + var encodedOffchainConfig []byte + var err2 error + if pluginType == cctypes.PluginTypeCCIPCommit { + encodedOffchainConfig, err2 = pluginconfig.EncodeCommitOffchainConfig(pluginconfig.CommitOffchainConfig{ + RemoteGasPriceBatchWriteFrequency: *commonconfig.MustNewDuration(RemoteGasPriceBatchWriteFrequency), + // TODO: implement token price writes + // TokenPriceBatchWriteFrequency: *commonconfig.MustNewDuration(tokenPriceBatchWriteFrequency), + }) + } else { + encodedOffchainConfig, err2 = pluginconfig.EncodeExecuteOffchainConfig(pluginconfig.ExecuteOffchainConfig{ + BatchGasLimit: BatchGasLimit, + RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, + MessageVisibilityInterval: *commonconfig.MustNewDuration(FirstBlockAge), + InflightCacheExpiry: *commonconfig.MustNewDuration(InflightCacheExpiry), + RootSnoozeTime: *commonconfig.MustNewDuration(RootSnoozeTime), + BatchingStrategyID: BatchingStrategyID, + }) + } + if err2 != nil { + return err2 + } + signers, transmitters, configF, _, offchainConfigVersion, offchainConfig, err2 := ocr3confighelper.ContractSetConfigArgsForTests( + DeltaProgress, + DeltaResend, + DeltaInitial, + DeltaRound, + DeltaGrace, + DeltaCertifiedCommitRequest, + DeltaStage, + Rmax, + schedule, + oracles, + encodedOffchainConfig, + MaxDurationQuery, + MaxDurationObservation, + MaxDurationShouldAcceptAttestedReport, + MaxDurationShouldTransmitAcceptedReport, + int(f), + []byte{}, // empty OnChainConfig + ) + if err2 != nil { + return err2 + } + + signersBytes := make([][]byte, len(signers)) + for i, signer := range signers { + signersBytes[i] = signer + } + + transmittersBytes := make([][]byte, len(transmitters)) + for i, transmitter := range transmitters { + parsed, err2 := common.ParseHexOrString(string(transmitter)) + if err2 != nil { + return err2 + } + transmittersBytes[i] = parsed + } + + ocr3Configs = append(ocr3Configs, ocr3_config_encoder.CCIPConfigTypesOCR3Config{ + PluginType: uint8(pluginType), + ChainSelector: dest.Selector, + F: configF, + OffchainConfigVersion: offchainConfigVersion, + OfframpAddress: offRamp.Address().Bytes(), + BootstrapP2PIds: [][32]byte{bootstrapP2PID}, + P2pIds: p2pIDs, + Signers: signersBytes, + Transmitters: transmittersBytes, + OffchainConfig: offchainConfig, + }) + } + + encodedCall, err := tabi.Pack("exposeOCR3Config", ocr3Configs) + if err != nil { + return err + } + + // Trim first four bytes to remove function selector. + encodedConfigs := encodedCall[4:] + + tx, err := capReg.AddDON(home.DeployerKey, p2pIDs, []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: ccipCapabilityID, + Config: encodedConfigs, + }, + }, false, false, f) + if _, err := deployment.ConfirmIfNoError(home, tx, err); err != nil { + return err + } + + latestBlock, err := home.Client.HeaderByNumber(context.Background(), nil) + if err != nil { + return err + } + endBlock := latestBlock.Number.Uint64() + iter, err := capReg.FilterConfigSet(&bind.FilterOpts{ + Start: endBlock - 1, + End: &endBlock, + }, []uint32{}) + if err != nil { + return err + } + var donID uint32 + for iter.Next() { + donID = iter.Event.DonId + break + } + if donID == 0 { + return errors.New("failed to get donID") + } + + var signerAddresses []common.Address + for _, oracle := range oracles { + signerAddresses = append(signerAddresses, common.BytesToAddress(oracle.OnchainPublicKey)) + } + + var transmitterAddresses []common.Address + for _, oracle := range oracles { + transmitterAddresses = append(transmitterAddresses, common.HexToAddress(string(oracle.TransmitAccount))) + } + + // get the config digest from the ccip config contract and set config on the offramp. + var offrampOCR3Configs []offramp.MultiOCR3BaseOCRConfigArgs + for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { + ocrConfig, err2 := ccipConfig.GetOCRConfig(&bind.CallOpts{ + Context: context.Background(), + }, donID, uint8(pluginType)) + if err2 != nil { + return err2 + } + if len(ocrConfig) != 1 { + return errors.New("expected exactly one OCR3 config") + } + + offrampOCR3Configs = append(offrampOCR3Configs, offramp.MultiOCR3BaseOCRConfigArgs{ + ConfigDigest: ocrConfig[0].ConfigDigest, + OcrPluginType: uint8(pluginType), + F: f, + IsSignatureVerificationEnabled: pluginType == cctypes.PluginTypeCCIPCommit, + Signers: signerAddresses, + Transmitters: transmitterAddresses, + }) + } + + tx, err = offRamp.SetOCR3Configs(dest.DeployerKey, offrampOCR3Configs) + if _, err := deployment.ConfirmIfNoError(dest, tx, err); err != nil { + return err + } + + for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { + _, err = offRamp.LatestConfigDetails(&bind.CallOpts{ + Context: context.Background(), + }, uint8(pluginType)) + if err != nil { + //return err + return deployment.MaybeDataErr(err) + } + // TODO: assertions to be done as part of full state + // resprentation validation CCIP-3047 + //require.Equalf(t, offrampOCR3Configs[pluginType].ConfigDigest, ocrConfig.ConfigInfo.ConfigDigest, "%s OCR3 config digest mismatch", pluginType.String()) + //require.Equalf(t, offrampOCR3Configs[pluginType].F, ocrConfig.ConfigInfo.F, "%s OCR3 config F mismatch", pluginType.String()) + //require.Equalf(t, offrampOCR3Configs[pluginType].IsSignatureVerificationEnabled, ocrConfig.ConfigInfo.IsSignatureVerificationEnabled, "%s OCR3 config signature verification mismatch", pluginType.String()) + //if pluginType == cctypes.PluginTypeCCIPCommit { + // // only commit will set signers, exec doesn't need them. + // require.Equalf(t, offrampOCR3Configs[pluginType].Signers, ocrConfig.Signers, "%s OCR3 config signers mismatch", pluginType.String()) + //} + //require.Equalf(t, offrampOCR3Configs[pluginType].TransmittersByEVMChainID, ocrConfig.TransmittersByEVMChainID, "%s OCR3 config transmitters mismatch", pluginType.String()) + } + + lggr.Infof("set ocr3 config on the offramp, signers: %+v, transmitters: %+v", signerAddresses, transmitterAddresses) + return nil +} diff --git a/integration-tests/deployment/ccip/deploy_test.go b/integration-tests/deployment/ccip/deploy_test.go new file mode 100644 index 0000000000..7bc56f82f7 --- /dev/null +++ b/integration-tests/deployment/ccip/deploy_test.go @@ -0,0 +1,58 @@ +package ccipdeployment + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestDeployCCIPContracts(t *testing.T) { + lggr := logger.TestLogger(t) + e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Bootstraps: 1, + Chains: 1, + Nodes: 4, + }) + // Deploy all the CCIP contracts. + homeChain := e.AllChainSelectors()[0] + capRegAddresses, _, err := DeployCapReg(lggr, e.Chains, homeChain) + require.NoError(t, err) + s, err := LoadOnchainState(e, capRegAddresses) + require.NoError(t, err) + ab, err := DeployCCIPContracts(e, DeployCCIPContractConfig{ + HomeChainSel: homeChain, + CCIPOnChainState: s, + }) + require.NoError(t, err) + state, err := LoadOnchainState(e, ab) + require.NoError(t, err) + snap, err := state.Snapshot(e.AllChainSelectors()) + require.NoError(t, err) + + // Assert expect every deployed address to be in the address book. + // TODO (CCIP-3047): Add the rest of CCIPv2 representation + b, err := json.MarshalIndent(snap, "", " ") + require.NoError(t, err) + fmt.Println(string(b)) +} + +func TestJobSpecGeneration(t *testing.T) { + lggr := logger.TestLogger(t) + e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Chains: 1, + Nodes: 1, + }) + js, err := NewCCIPJobSpecs(e.NodeIDs, e.Offchain) + require.NoError(t, err) + for node, jb := range js { + fmt.Println(node, jb) + } + // TODO: Add job assertions +} diff --git a/integration-tests/deployment/ccip/jobs.go b/integration-tests/deployment/ccip/jobs.go new file mode 100644 index 0000000000..c46ab7270f --- /dev/null +++ b/integration-tests/deployment/ccip/jobs.go @@ -0,0 +1,79 @@ +package ccipdeployment + +import ( + "context" + "fmt" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" +) + +// In our case, the only address needed is the cap registry which is actually an env var. +// and will pre-exist for our deployment. So the job specs only depend on the environment operators. +func NewCCIPJobSpecs(nodeIds []string, oc deployment.OffchainClient) (map[string][]string, error) { + // Generate a set of brand new job specs for CCIP for a specific environment + // (including NOPs) and new addresses. + // We want to assign one CCIP capability job to each node. And node with + // an addr we'll list as bootstrapper. + // Find the bootstrap nodes + bootstrapMp := make(map[string]struct{}) + for _, node := range nodeIds { + // TODO: Filter should accept multiple nodes + nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ + NodeIds: []string{node}, + }}) + if err != nil { + return nil, err + } + for _, chainConfig := range nodeChainConfigs.ChainConfigs { + if chainConfig.Ocr2Config.IsBootstrap { + bootstrapMp[fmt.Sprintf("%s@%s", + // p2p_12D3... -> 12D3... + chainConfig.Ocr2Config.P2PKeyBundle.PeerId[4:], chainConfig.Ocr2Config.Multiaddr)] = struct{}{} + } + } + } + var bootstraps []string + for b := range bootstrapMp { + bootstraps = append(bootstraps, b) + } + nodesToJobSpecs := make(map[string][]string) + for _, node := range nodeIds { + // TODO: Filter should accept multiple. + nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ + NodeIds: []string{node}, + }}) + if err != nil { + return nil, err + } + + // only set P2PV2Bootstrappers in the job spec if the node is a plugin node. + var p2pV2Bootstrappers []string + for _, chainConfig := range nodeChainConfigs.ChainConfigs { + if !chainConfig.Ocr2Config.IsBootstrap { + p2pV2Bootstrappers = bootstraps + break + } + } + spec, err := validate.NewCCIPSpecToml(validate.SpecArgs{ + P2PV2Bootstrappers: p2pV2Bootstrappers, + CapabilityVersion: CapabilityVersion, + CapabilityLabelledName: CapabilityLabelledName, + OCRKeyBundleIDs: map[string]string{ + // TODO: Validate that that all EVM chains are using the same keybundle. + relay.NetworkEVM: nodeChainConfigs.ChainConfigs[0].Ocr2Config.OcrKeyBundle.BundleId, + }, + // TODO: validate that all EVM chains are using the same keybundle + P2PKeyID: nodeChainConfigs.ChainConfigs[0].Ocr2Config.P2PKeyBundle.PeerId, + RelayConfigs: nil, + PluginConfig: map[string]any{}, + }) + if err != nil { + return nil, err + } + nodesToJobSpecs[node] = append(nodesToJobSpecs[node], spec) + } + return nodesToJobSpecs, nil +} diff --git a/integration-tests/deployment/ccip/propose.go b/integration-tests/deployment/ccip/propose.go new file mode 100644 index 0000000000..4fc38965ea --- /dev/null +++ b/integration-tests/deployment/ccip/propose.go @@ -0,0 +1,64 @@ +package ccipdeployment + +import ( + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" + chainsel "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" +) + +// TODO: Pull up to deploy +func SimTransactOpts() *bind.TransactOpts { + return &bind.TransactOpts{Signer: func(address common.Address, transaction *types.Transaction) (*types.Transaction, error) { + return transaction, nil + }, From: common.HexToAddress("0x0"), NoSend: true, GasLimit: 200_000} +} + +func GenerateAcceptOwnershipProposal( + e deployment.Environment, + chains []uint64, + ab deployment.AddressBook, +) (deployment.Proposal, error) { + state, err := LoadOnchainState(e, ab) + if err != nil { + return deployment.Proposal{}, err + } + // TODO: Just onramp as an example + var ops []owner_helpers.ManyChainMultiSigOp + for _, sel := range chains { + opCount, err := state.Chains[sel].Mcm.GetOpCount(nil) + if err != nil { + return deployment.Proposal{}, err + } + + txData, err := state.Chains[sel].EvmOnRampV160.AcceptOwnership(SimTransactOpts()) + if err != nil { + return deployment.Proposal{}, err + } + evmID, err := chainsel.ChainIdFromSelector(sel) + if err != nil { + return deployment.Proposal{}, err + } + ops = append(ops, owner_helpers.ManyChainMultiSigOp{ + ChainId: big.NewInt(int64(evmID)), + MultiSig: state.Chains[sel].McmsAddr, + Nonce: opCount, + To: state.Chains[sel].EvmOnRampV160.Address(), + Value: big.NewInt(0), + Data: txData.Data(), + }) + } + // TODO: Real valid until. + return deployment.Proposal{ValidUntil: uint32(time.Now().Unix()), Ops: ops}, nil +} + +func ApplyProposal(env deployment.Environment, p deployment.Proposal, state CCIPOnChainState) error { + // TODO + return nil +} diff --git a/integration-tests/deployment/ccip/state.go b/integration-tests/deployment/ccip/state.go new file mode 100644 index 0000000000..f641d30ed4 --- /dev/null +++ b/integration-tests/deployment/ccip/state.go @@ -0,0 +1,276 @@ +package ccipdeployment + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + chainsel "github.com/smartcontractkit/chain-selectors" + + owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" +) + +type CCIPChainState struct { + EvmOnRampV160 *onramp.OnRamp + EvmOffRampV160 *offramp.OffRamp + PriceRegistry *fee_quoter.FeeQuoter + ArmProxy *rmn_proxy_contract.RMNProxyContract + NonceManager *nonce_manager.NonceManager + TokenAdminRegistry *token_admin_registry.TokenAdminRegistry + Router *router.Router + Weth9 *weth9.WETH9 + MockRmn *mock_rmn_contract.MockRMNContract + // TODO: May need to support older link too + LinkToken *burn_mint_erc677.BurnMintERC677 + // Note we only expect one of these (on the home chain) + CapabilityRegistry *capabilities_registry.CapabilitiesRegistry + CCIPConfig *ccip_config.CCIPConfig + Mcm *owner_wrappers.ManyChainMultiSig + // TODO: remove once we have Address() on wrappers + McmsAddr common.Address + Timelock *owner_wrappers.RBACTimelock + + // Test contracts + Receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver +} + +// Onchain state always derivable from an address book. +// Offchain state always derivable from a list of nodeIds. +// Note can translate this into Go struct needed for MCMS/Docs/UI. +type CCIPOnChainState struct { + // Populated go bindings for the appropriate version for all contracts. + // We would hold 2 versions of each contract here. Once we upgrade we can phase out the old one. + // When generating bindings, make sure the package name corresponds to the version. + Chains map[uint64]CCIPChainState +} + +type CCIPSnapShot struct { + Chains map[string]Chain `json:"chains"` +} + +type Contract struct { + TypeAndVersion string `json:"typeAndVersion"` + Address common.Address `json:"address"` +} + +type TokenAdminRegistryView struct { + Contract + Tokens []common.Address `json:"tokens"` +} + +type NonceManagerView struct { + Contract + AuthorizedCallers []common.Address `json:"authorizedCallers"` +} + +type Chain struct { + // TODO: this will have to be versioned for getting state during upgrades. + TokenAdminRegistry TokenAdminRegistryView `json:"tokenAdminRegistry"` + NonceManager NonceManagerView `json:"nonceManager"` +} + +func (s CCIPOnChainState) Snapshot(chains []uint64) (CCIPSnapShot, error) { + snapshot := CCIPSnapShot{ + Chains: make(map[string]Chain), + } + for _, chainSelector := range chains { + // TODO: Need a utility for this + chainid, err := chainsel.ChainIdFromSelector(chainSelector) + if err != nil { + return snapshot, err + } + chainName, err := chainsel.NameFromChainId(chainid) + if err != nil { + return snapshot, err + } + if _, ok := s.Chains[chainSelector]; !ok { + return snapshot, fmt.Errorf("chain not supported %d", chainSelector) + } + var c Chain + ta := s.Chains[chainSelector].TokenAdminRegistry + if ta != nil { + tokens, err := ta.GetAllConfiguredTokens(nil, 0, 10) + if err != nil { + return snapshot, err + } + tv, err := ta.TypeAndVersion(nil) + if err != nil { + return snapshot, err + } + c.TokenAdminRegistry = TokenAdminRegistryView{ + Contract: Contract{ + TypeAndVersion: tv, + Address: ta.Address(), + }, + Tokens: tokens, + } + } + nm := s.Chains[chainSelector].NonceManager + if nm != nil { + authorizedCallers, err := nm.GetAllAuthorizedCallers(nil) + if err != nil { + return snapshot, err + } + tv, err := nm.TypeAndVersion(nil) + if err != nil { + return snapshot, err + } + c.NonceManager = NonceManagerView{ + Contract: Contract{ + TypeAndVersion: tv, + Address: nm.Address(), + }, + // TODO: these can be resolved using an address book + AuthorizedCallers: authorizedCallers, + } + } + snapshot.Chains[chainName] = c + } + return snapshot, nil +} + +func SnapshotState(e deployment.Environment, ab deployment.AddressBook) (CCIPSnapShot, error) { + state, err := LoadOnchainState(e, ab) + if err != nil { + return CCIPSnapShot{}, err + } + return state.Snapshot(e.AllChainSelectors()) +} + +func LoadOnchainState(e deployment.Environment, ab deployment.AddressBook) (CCIPOnChainState, error) { + state := CCIPOnChainState{ + Chains: make(map[uint64]CCIPChainState), + } + addresses, err := ab.Addresses() + if err != nil { + return state, errors.Wrap(err, "could not get addresses") + } + for chainSelector, addresses := range addresses { + chainState, err := LoadChainState(e.Chains[chainSelector], addresses) + if err != nil { + return state, err + } + state.Chains[chainSelector] = chainState + } + return state, nil +} + +// Loads all state for a chain into state +// Modifies map in place +func LoadChainState(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (CCIPChainState, error) { + var state CCIPChainState + for address, tvStr := range addresses { + switch tvStr.String() { + case deployment.NewTypeAndVersion(RBACTimelock, deployment.Version1_0_0).String(): + tl, err := owner_wrappers.NewRBACTimelock(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.Timelock = tl + case deployment.NewTypeAndVersion(ManyChainMultisig, deployment.Version1_0_0).String(): + mcms, err := owner_wrappers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.Mcm = mcms + state.McmsAddr = common.HexToAddress(address) + case deployment.NewTypeAndVersion(CapabilitiesRegistry, deployment.Version1_0_0).String(): + cr, err := capabilities_registry.NewCapabilitiesRegistry(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.CapabilityRegistry = cr + case deployment.NewTypeAndVersion(OnRamp, deployment.Version1_6_0_dev).String(): + onRampC, err := onramp.NewOnRamp(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.EvmOnRampV160 = onRampC + case deployment.NewTypeAndVersion(OffRamp, deployment.Version1_6_0_dev).String(): + offRamp, err := offramp.NewOffRamp(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.EvmOffRampV160 = offRamp + case deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0).String(): + armProxy, err := rmn_proxy_contract.NewRMNProxyContract(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.ArmProxy = armProxy + case deployment.NewTypeAndVersion(MockARM, deployment.Version1_0_0).String(): + mockARM, err := mock_rmn_contract.NewMockRMNContract(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.MockRmn = mockARM + case deployment.NewTypeAndVersion(WETH9, deployment.Version1_0_0).String(): + weth9, err := weth9.NewWETH9(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.Weth9 = weth9 + case deployment.NewTypeAndVersion(NonceManager, deployment.Version1_6_0_dev).String(): + nm, err := nonce_manager.NewNonceManager(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.NonceManager = nm + case deployment.NewTypeAndVersion(TokenAdminRegistry, deployment.Version1_5_0).String(): + tm, err := token_admin_registry.NewTokenAdminRegistry(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.TokenAdminRegistry = tm + case deployment.NewTypeAndVersion(Router, deployment.Version1_2_0).String(): + r, err := router.NewRouter(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.Router = r + case deployment.NewTypeAndVersion(PriceRegistry, deployment.Version1_6_0_dev).String(): + pr, err := fee_quoter.NewFeeQuoter(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.PriceRegistry = pr + case deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0).String(): + lt, err := burn_mint_erc677.NewBurnMintERC677(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.LinkToken = lt + case deployment.NewTypeAndVersion(CCIPConfig, deployment.Version1_6_0_dev).String(): + cc, err := ccip_config.NewCCIPConfig(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.CCIPConfig = cc + case deployment.NewTypeAndVersion(CCIPReceiver, deployment.Version1_0_0).String(): + mr, err := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.Receiver = mr + default: + return state, fmt.Errorf("unknown contract %s", tvStr) + } + } + return state, nil +} diff --git a/integration-tests/deployment/ccip/test_helpers.go b/integration-tests/deployment/ccip/test_helpers.go new file mode 100644 index 0000000000..2ec837c9ee --- /dev/null +++ b/integration-tests/deployment/ccip/test_helpers.go @@ -0,0 +1,75 @@ +package ccipdeployment + +import ( + "context" + "testing" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" +) + +// Context returns a context with the test's deadline, if available. +func Context(tb testing.TB) context.Context { + ctx := context.Background() + var cancel func() + switch t := tb.(type) { + case *testing.T: + if d, ok := t.Deadline(); ok { + ctx, cancel = context.WithDeadline(ctx, d) + } + } + if cancel == nil { + ctx, cancel = context.WithCancel(ctx) + } + tb.Cleanup(cancel) + return ctx +} + +type DeployedTestEnvironment struct { + Ab deployment.AddressBook + Env deployment.Environment + HomeChainSel uint64 + Nodes map[string]memory.Node +} + +// NewDeployedEnvironment creates a new CCIP environment +// with capreg and nodes set up. +func NewDeployedTestEnvironment(t *testing.T, lggr logger.Logger) DeployedTestEnvironment { + ctx := Context(t) + chains := memory.NewMemoryChains(t, 3) + homeChainSel := uint64(0) + homeChainEVM := uint64(0) + // Say first chain is home chain. + for chainSel := range chains { + homeChainEVM, _ = chainsel.ChainIdFromSelector(chainSel) + homeChainSel = chainSel + break + } + ab, capReg, err := DeployCapReg(lggr, chains, homeChainSel) + require.NoError(t, err) + + nodes := memory.NewNodes(t, zapcore.InfoLevel, chains, 4, 1, memory.RegistryConfig{ + EVMChainID: homeChainEVM, + Contract: capReg, + }) + for _, node := range nodes { + require.NoError(t, node.App.Start(ctx)) + t.Cleanup(func() { + require.NoError(t, node.App.Stop()) + }) + } + + e := memory.NewMemoryEnvironmentFromChainsNodes(t, lggr, chains, nodes) + return DeployedTestEnvironment{ + Ab: ab, + Env: e, + HomeChainSel: homeChainSel, + Nodes: nodes, + } +} diff --git a/integration-tests/deployment/environment.go b/integration-tests/deployment/environment.go index 7d8fb6e631..2e28bff5ab 100644 --- a/integration-tests/deployment/environment.go +++ b/integration-tests/deployment/environment.go @@ -15,6 +15,8 @@ import ( types2 "github.com/smartcontractkit/libocr/offchainreporting2/types" types3 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + csav1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/csa/v1" + jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" @@ -32,6 +34,7 @@ type OffchainClient interface { // The job distributor grpc interface can be used to abstract offchain read/writes jobv1.JobServiceClient nodev1.NodeServiceClient + csav1.CSAServiceClient } type Chain struct { @@ -40,7 +43,7 @@ type Chain struct { Client OnchainClient // Note the Sign function can be abstract supporting a variety of key storage mechanisms (e.g. KMS etc). DeployerKey *bind.TransactOpts - Confirm func(tx common.Hash) error + Confirm func(tx common.Hash) (uint64, error) } type Environment struct { @@ -59,15 +62,15 @@ func (e Environment) AllChainSelectors() []uint64 { return selectors } -func ConfirmIfNoError(chain Chain, tx *types.Transaction, err error) error { +func ConfirmIfNoError(chain Chain, tx *types.Transaction, err error) (uint64, error) { if err != nil { //revive:disable var d rpc.DataError ok := errors.As(err, &d) if ok { - return fmt.Errorf("got Data Error: %s", d.ErrorData()) + return 0, fmt.Errorf("got Data Error: %s", d.ErrorData()) } - return err + return 0, err } return chain.Confirm(tx.Hash()) } @@ -150,7 +153,7 @@ func NodeInfo(nodeIDs []string, oc OffchainClient) (Nodes, error) { for _, node := range nodeIDs { // TODO: Filter should accept multiple nodes nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ - NodeId: node, + NodeIds: []string{node}, }}) if err != nil { return nil, err @@ -191,5 +194,6 @@ func NodeInfo(nodeIDs []string, oc OffchainClient) (Nodes, error) { SelToOCRConfig: selToOCRConfig, }) } + return nodes, nil } diff --git a/integration-tests/deployment/jd/csa/v1/csa.pb.go b/integration-tests/deployment/jd/csa/v1/csa.pb.go new file mode 100644 index 0000000000..77ad4be4c0 --- /dev/null +++ b/integration-tests/deployment/jd/csa/v1/csa.pb.go @@ -0,0 +1,418 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.29.0 +// protoc v4.25.3 +// source: csa/v1/csa.proto + +package v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Keypair struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + PublicKey string `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *Keypair) Reset() { + *x = Keypair{} + if protoimpl.UnsafeEnabled { + mi := &file_csa_v1_csa_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Keypair) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Keypair) ProtoMessage() {} + +func (x *Keypair) ProtoReflect() protoreflect.Message { + mi := &file_csa_v1_csa_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Keypair.ProtoReflect.Descriptor instead. +func (*Keypair) Descriptor() ([]byte, []int) { + return file_csa_v1_csa_proto_rawDescGZIP(), []int{0} +} + +func (x *Keypair) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Keypair) GetPublicKey() string { + if x != nil { + return x.PublicKey + } + return "" +} + +func (x *Keypair) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +type GetKeypairRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetKeypairRequest) Reset() { + *x = GetKeypairRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_csa_v1_csa_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetKeypairRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetKeypairRequest) ProtoMessage() {} + +func (x *GetKeypairRequest) ProtoReflect() protoreflect.Message { + mi := &file_csa_v1_csa_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetKeypairRequest.ProtoReflect.Descriptor instead. +func (*GetKeypairRequest) Descriptor() ([]byte, []int) { + return file_csa_v1_csa_proto_rawDescGZIP(), []int{1} +} + +type GetKeypairResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Keypair *Keypair `protobuf:"bytes,1,opt,name=keypair,proto3" json:"keypair,omitempty"` +} + +func (x *GetKeypairResponse) Reset() { + *x = GetKeypairResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_csa_v1_csa_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetKeypairResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetKeypairResponse) ProtoMessage() {} + +func (x *GetKeypairResponse) ProtoReflect() protoreflect.Message { + mi := &file_csa_v1_csa_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetKeypairResponse.ProtoReflect.Descriptor instead. +func (*GetKeypairResponse) Descriptor() ([]byte, []int) { + return file_csa_v1_csa_proto_rawDescGZIP(), []int{2} +} + +func (x *GetKeypairResponse) GetKeypair() *Keypair { + if x != nil { + return x.Keypair + } + return nil +} + +type ListKeypairsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListKeypairsRequest) Reset() { + *x = ListKeypairsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_csa_v1_csa_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListKeypairsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListKeypairsRequest) ProtoMessage() {} + +func (x *ListKeypairsRequest) ProtoReflect() protoreflect.Message { + mi := &file_csa_v1_csa_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListKeypairsRequest.ProtoReflect.Descriptor instead. +func (*ListKeypairsRequest) Descriptor() ([]byte, []int) { + return file_csa_v1_csa_proto_rawDescGZIP(), []int{3} +} + +type ListKeypairsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Keypairs []*Keypair `protobuf:"bytes,1,rep,name=keypairs,proto3" json:"keypairs,omitempty"` +} + +func (x *ListKeypairsResponse) Reset() { + *x = ListKeypairsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_csa_v1_csa_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListKeypairsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListKeypairsResponse) ProtoMessage() {} + +func (x *ListKeypairsResponse) ProtoReflect() protoreflect.Message { + mi := &file_csa_v1_csa_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListKeypairsResponse.ProtoReflect.Descriptor instead. +func (*ListKeypairsResponse) Descriptor() ([]byte, []int) { + return file_csa_v1_csa_proto_rawDescGZIP(), []int{4} +} + +func (x *ListKeypairsResponse) GetKeypairs() []*Keypair { + if x != nil { + return x.Keypairs + } + return nil +} + +var File_csa_v1_csa_proto protoreflect.FileDescriptor + +var file_csa_v1_csa_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x63, 0x73, 0x61, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x73, 0x61, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x0a, 0x61, 0x70, 0x69, 0x2e, 0x63, 0x73, 0x61, 0x2e, 0x76, 0x31, 0x1a, 0x1f, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0x73, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x70, 0x61, 0x69, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x22, 0x13, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x70, 0x61, + 0x69, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x43, 0x0a, 0x12, 0x47, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x70, 0x61, 0x69, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x2d, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x70, 0x61, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x63, 0x73, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, + 0x79, 0x70, 0x61, 0x69, 0x72, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x70, 0x61, 0x69, 0x72, 0x22, 0x15, + 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x70, 0x61, 0x69, 0x72, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x47, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, + 0x70, 0x61, 0x69, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, + 0x08, 0x6b, 0x65, 0x79, 0x70, 0x61, 0x69, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x63, 0x73, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, + 0x70, 0x61, 0x69, 0x72, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x70, 0x61, 0x69, 0x72, 0x73, 0x32, 0xac, + 0x01, 0x0a, 0x0a, 0x43, 0x53, 0x41, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4b, 0x0a, + 0x0a, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x70, 0x61, 0x69, 0x72, 0x12, 0x1d, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x63, 0x73, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x70, + 0x61, 0x69, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x63, 0x73, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x70, 0x61, + 0x69, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0c, 0x4c, 0x69, + 0x73, 0x74, 0x4b, 0x65, 0x79, 0x70, 0x61, 0x69, 0x72, 0x73, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x63, 0x73, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x70, + 0x61, 0x69, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x63, 0x73, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, + 0x70, 0x61, 0x69, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x08, 0x5a, + 0x06, 0x63, 0x73, 0x61, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_csa_v1_csa_proto_rawDescOnce sync.Once + file_csa_v1_csa_proto_rawDescData = file_csa_v1_csa_proto_rawDesc +) + +func file_csa_v1_csa_proto_rawDescGZIP() []byte { + file_csa_v1_csa_proto_rawDescOnce.Do(func() { + file_csa_v1_csa_proto_rawDescData = protoimpl.X.CompressGZIP(file_csa_v1_csa_proto_rawDescData) + }) + return file_csa_v1_csa_proto_rawDescData +} + +var file_csa_v1_csa_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_csa_v1_csa_proto_goTypes = []interface{}{ + (*Keypair)(nil), // 0: api.csa.v1.Keypair + (*GetKeypairRequest)(nil), // 1: api.csa.v1.GetKeypairRequest + (*GetKeypairResponse)(nil), // 2: api.csa.v1.GetKeypairResponse + (*ListKeypairsRequest)(nil), // 3: api.csa.v1.ListKeypairsRequest + (*ListKeypairsResponse)(nil), // 4: api.csa.v1.ListKeypairsResponse + (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp +} +var file_csa_v1_csa_proto_depIdxs = []int32{ + 5, // 0: api.csa.v1.Keypair.created_at:type_name -> google.protobuf.Timestamp + 0, // 1: api.csa.v1.GetKeypairResponse.keypair:type_name -> api.csa.v1.Keypair + 0, // 2: api.csa.v1.ListKeypairsResponse.keypairs:type_name -> api.csa.v1.Keypair + 1, // 3: api.csa.v1.CSAService.GetKeypair:input_type -> api.csa.v1.GetKeypairRequest + 3, // 4: api.csa.v1.CSAService.ListKeypairs:input_type -> api.csa.v1.ListKeypairsRequest + 2, // 5: api.csa.v1.CSAService.GetKeypair:output_type -> api.csa.v1.GetKeypairResponse + 4, // 6: api.csa.v1.CSAService.ListKeypairs:output_type -> api.csa.v1.ListKeypairsResponse + 5, // [5:7] is the sub-list for method output_type + 3, // [3:5] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_csa_v1_csa_proto_init() } +func file_csa_v1_csa_proto_init() { + if File_csa_v1_csa_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_csa_v1_csa_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Keypair); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_csa_v1_csa_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetKeypairRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_csa_v1_csa_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetKeypairResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_csa_v1_csa_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListKeypairsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_csa_v1_csa_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListKeypairsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_csa_v1_csa_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_csa_v1_csa_proto_goTypes, + DependencyIndexes: file_csa_v1_csa_proto_depIdxs, + MessageInfos: file_csa_v1_csa_proto_msgTypes, + }.Build() + File_csa_v1_csa_proto = out.File + file_csa_v1_csa_proto_rawDesc = nil + file_csa_v1_csa_proto_goTypes = nil + file_csa_v1_csa_proto_depIdxs = nil +} diff --git a/integration-tests/deployment/jd/csa/v1/csa_grpc.pb.go b/integration-tests/deployment/jd/csa/v1/csa_grpc.pb.go new file mode 100644 index 0000000000..7e058bd9fd --- /dev/null +++ b/integration-tests/deployment/jd/csa/v1/csa_grpc.pb.go @@ -0,0 +1,146 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.25.3 +// source: csa/v1/csa.proto + +package v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + CSAService_GetKeypair_FullMethodName = "/api.csa.v1.CSAService/GetKeypair" + CSAService_ListKeypairs_FullMethodName = "/api.csa.v1.CSAService/ListKeypairs" +) + +// CSAServiceClient is the client API for CSAService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type CSAServiceClient interface { + GetKeypair(ctx context.Context, in *GetKeypairRequest, opts ...grpc.CallOption) (*GetKeypairResponse, error) + ListKeypairs(ctx context.Context, in *ListKeypairsRequest, opts ...grpc.CallOption) (*ListKeypairsResponse, error) +} + +type cSAServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewCSAServiceClient(cc grpc.ClientConnInterface) CSAServiceClient { + return &cSAServiceClient{cc} +} + +func (c *cSAServiceClient) GetKeypair(ctx context.Context, in *GetKeypairRequest, opts ...grpc.CallOption) (*GetKeypairResponse, error) { + out := new(GetKeypairResponse) + err := c.cc.Invoke(ctx, CSAService_GetKeypair_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cSAServiceClient) ListKeypairs(ctx context.Context, in *ListKeypairsRequest, opts ...grpc.CallOption) (*ListKeypairsResponse, error) { + out := new(ListKeypairsResponse) + err := c.cc.Invoke(ctx, CSAService_ListKeypairs_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// CSAServiceServer is the server API for CSAService service. +// All implementations must embed UnimplementedCSAServiceServer +// for forward compatibility +type CSAServiceServer interface { + GetKeypair(context.Context, *GetKeypairRequest) (*GetKeypairResponse, error) + ListKeypairs(context.Context, *ListKeypairsRequest) (*ListKeypairsResponse, error) + mustEmbedUnimplementedCSAServiceServer() +} + +// UnimplementedCSAServiceServer must be embedded to have forward compatible implementations. +type UnimplementedCSAServiceServer struct { +} + +func (UnimplementedCSAServiceServer) GetKeypair(context.Context, *GetKeypairRequest) (*GetKeypairResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetKeypair not implemented") +} +func (UnimplementedCSAServiceServer) ListKeypairs(context.Context, *ListKeypairsRequest) (*ListKeypairsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListKeypairs not implemented") +} +func (UnimplementedCSAServiceServer) mustEmbedUnimplementedCSAServiceServer() {} + +// UnsafeCSAServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to CSAServiceServer will +// result in compilation errors. +type UnsafeCSAServiceServer interface { + mustEmbedUnimplementedCSAServiceServer() +} + +func RegisterCSAServiceServer(s grpc.ServiceRegistrar, srv CSAServiceServer) { + s.RegisterService(&CSAService_ServiceDesc, srv) +} + +func _CSAService_GetKeypair_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetKeypairRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CSAServiceServer).GetKeypair(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CSAService_GetKeypair_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CSAServiceServer).GetKeypair(ctx, req.(*GetKeypairRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CSAService_ListKeypairs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListKeypairsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CSAServiceServer).ListKeypairs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CSAService_ListKeypairs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CSAServiceServer).ListKeypairs(ctx, req.(*ListKeypairsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// CSAService_ServiceDesc is the grpc.ServiceDesc for CSAService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var CSAService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "api.csa.v1.CSAService", + HandlerType: (*CSAServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetKeypair", + Handler: _CSAService_GetKeypair_Handler, + }, + { + MethodName: "ListKeypairs", + Handler: _CSAService_ListKeypairs_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "csa/v1/csa.proto", +} \ No newline at end of file diff --git a/integration-tests/deployment/jd/job/v1/job.pb.go b/integration-tests/deployment/jd/job/v1/job.pb.go index deaf1ccf30..5544a12bdd 100644 --- a/integration-tests/deployment/jd/job/v1/job.pb.go +++ b/integration-tests/deployment/jd/job/v1/job.pb.go @@ -7,6 +7,7 @@ package v1 import ( + ptypes "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/shared/ptypes" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" @@ -149,6 +150,7 @@ type Job struct { CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Timestamp when the job was created. UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // Timestamp when the job was last updated. DeletedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=deleted_at,json=deletedAt,proto3" json:"deleted_at,omitempty"` // Timestamp when the job was deleted, if applicable. + Labels []*ptypes.Label `protobuf:"bytes,8,rep,name=labels,proto3" json:"labels,omitempty"` // Set of labels associated with the job. } func (x *Job) Reset() { @@ -232,6 +234,13 @@ func (x *Job) GetDeletedAt() *timestamppb.Timestamp { return nil } +func (x *Job) GetLabels() []*ptypes.Label { + if x != nil { + return x.Labels + } + return nil +} + // Proposal represents a job proposal. type Proposal struct { state protoimpl.MessageState @@ -239,7 +248,7 @@ type Proposal struct { unknownFields protoimpl.UnknownFields Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier for the proposal. - Version int64 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"` // Version number of the proposal. + Revision int64 `protobuf:"varint,2,opt,name=revision,proto3" json:"revision,omitempty"` // Revision number of the proposal. Montonically increasing. Status ProposalStatus `protobuf:"varint,3,opt,name=status,proto3,enum=api.job.v1.ProposalStatus" json:"status,omitempty"` // Current status of the proposal. DeliveryStatus ProposalDeliveryStatus `protobuf:"varint,4,opt,name=delivery_status,json=deliveryStatus,proto3,enum=api.job.v1.ProposalDeliveryStatus" json:"delivery_status,omitempty"` // Delivery status of the proposal. Spec string `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` // Specification of the job proposed. @@ -289,9 +298,9 @@ func (x *Proposal) GetId() string { return "" } -func (x *Proposal) GetVersion() int64 { +func (x *Proposal) GetRevision() int64 { if x != nil { - return x.Version + return x.Revision } return 0 } @@ -776,8 +785,9 @@ type ProposeJobRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` // ID of the node to which the job is proposed. - Spec string `protobuf:"bytes,2,opt,name=spec,proto3" json:"spec,omitempty"` // Specification of the job being proposed. + NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` // ID of the node to which the job is proposed. + Spec string `protobuf:"bytes,2,opt,name=spec,proto3" json:"spec,omitempty"` // Specification of the job being proposed. + Labels []*ptypes.Label `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty"` // Labels to associate with the job. } func (x *ProposeJobRequest) Reset() { @@ -826,6 +836,13 @@ func (x *ProposeJobRequest) GetSpec() string { return "" } +func (x *ProposeJobRequest) GetLabels() []*ptypes.Label { + if x != nil { + return x.Labels + } + return nil +} + // ProposeJobResponse returns the newly created proposal. type ProposeJobResponse struct { state protoimpl.MessageState @@ -1134,19 +1151,158 @@ func (x *DeleteJobResponse) GetJob() *Job { return nil } +// UpdateJobRequest specifies the criteria for updating a job. +type UpdateJobRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to IdOneof: + // + // *UpdateJobRequest_Id + // *UpdateJobRequest_Uuid + IdOneof isUpdateJobRequest_IdOneof `protobuf_oneof:"id_oneof"` + Labels []*ptypes.Label `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty"` // Set of labels associated with the job. +} + +func (x *UpdateJobRequest) Reset() { + *x = UpdateJobRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateJobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateJobRequest) ProtoMessage() {} + +func (x *UpdateJobRequest) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateJobRequest.ProtoReflect.Descriptor instead. +func (*UpdateJobRequest) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{16} +} + +func (m *UpdateJobRequest) GetIdOneof() isUpdateJobRequest_IdOneof { + if m != nil { + return m.IdOneof + } + return nil +} + +func (x *UpdateJobRequest) GetId() string { + if x, ok := x.GetIdOneof().(*UpdateJobRequest_Id); ok { + return x.Id + } + return "" +} + +func (x *UpdateJobRequest) GetUuid() string { + if x, ok := x.GetIdOneof().(*UpdateJobRequest_Uuid); ok { + return x.Uuid + } + return "" +} + +func (x *UpdateJobRequest) GetLabels() []*ptypes.Label { + if x != nil { + return x.Labels + } + return nil +} + +type isUpdateJobRequest_IdOneof interface { + isUpdateJobRequest_IdOneof() +} + +type UpdateJobRequest_Id struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3,oneof"` // Unique identifier of the job to update. +} + +type UpdateJobRequest_Uuid struct { + Uuid string `protobuf:"bytes,2,opt,name=uuid,proto3,oneof"` // Universally unique identifier of the job to update. +} + +func (*UpdateJobRequest_Id) isUpdateJobRequest_IdOneof() {} + +func (*UpdateJobRequest_Uuid) isUpdateJobRequest_IdOneof() {} + +// UpdateJobResponse returns details of the updated job. +type UpdateJobResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Job *Job `protobuf:"bytes,1,opt,name=job,proto3" json:"job,omitempty"` // Details of the updated job. +} + +func (x *UpdateJobResponse) Reset() { + *x = UpdateJobResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_job_v1_job_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateJobResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateJobResponse) ProtoMessage() {} + +func (x *UpdateJobResponse) ProtoReflect() protoreflect.Message { + mi := &file_job_v1_job_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateJobResponse.ProtoReflect.Descriptor instead. +func (*UpdateJobResponse) Descriptor() ([]byte, []int) { + return file_job_v1_job_proto_rawDescGZIP(), []int{17} +} + +func (x *UpdateJobResponse) GetJob() *Job { + if x != nil { + return x.Job + } + return nil +} + type ListJobsRequest_Filter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"` // Filter by job IDs. - NodeIds []string `protobuf:"bytes,2,rep,name=node_ids,json=nodeIds,proto3" json:"node_ids,omitempty"` // Filter by node IDs. + Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"` // Filter by job IDs. + NodeIds []string `protobuf:"bytes,2,rep,name=node_ids,json=nodeIds,proto3" json:"node_ids,omitempty"` // Filter by node IDs. + Selectors []*ptypes.Selector `protobuf:"bytes,3,rep,name=selectors,proto3" json:"selectors,omitempty"` // Filter by selectors } func (x *ListJobsRequest_Filter) Reset() { *x = ListJobsRequest_Filter{} if protoimpl.UnsafeEnabled { - mi := &file_job_v1_job_proto_msgTypes[16] + mi := &file_job_v1_job_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1159,7 +1315,7 @@ func (x *ListJobsRequest_Filter) String() string { func (*ListJobsRequest_Filter) ProtoMessage() {} func (x *ListJobsRequest_Filter) ProtoReflect() protoreflect.Message { - mi := &file_job_v1_job_proto_msgTypes[16] + mi := &file_job_v1_job_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1189,6 +1345,13 @@ func (x *ListJobsRequest_Filter) GetNodeIds() []string { return nil } +func (x *ListJobsRequest_Filter) GetSelectors() []*ptypes.Selector { + if x != nil { + return x.Selectors + } + return nil +} + type ListProposalsRequest_Filter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1201,7 +1364,7 @@ type ListProposalsRequest_Filter struct { func (x *ListProposalsRequest_Filter) Reset() { *x = ListProposalsRequest_Filter{} if protoimpl.UnsafeEnabled { - mi := &file_job_v1_job_proto_msgTypes[17] + mi := &file_job_v1_job_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1214,7 +1377,7 @@ func (x *ListProposalsRequest_Filter) String() string { func (*ListProposalsRequest_Filter) ProtoMessage() {} func (x *ListProposalsRequest_Filter) ProtoReflect() protoreflect.Message { - mi := &file_job_v1_job_proto_msgTypes[17] + mi := &file_job_v1_job_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1250,186 +1413,211 @@ var file_job_v1_job_proto_rawDesc = []byte{ 0x0a, 0x10, 0x6a, 0x6f, 0x62, 0x2f, 0x76, 0x31, 0x2f, 0x6a, 0x6f, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0x96, 0x02, 0x0a, 0x03, 0x4a, 0x6f, 0x62, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6e, - 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, - 0x64, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, - 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x70, - 0x6f, 0x73, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x19, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc0, 0x02, 0x0a, 0x03, 0x4a, + 0x6f, 0x62, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, + 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x49, + 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, - 0x0a, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, + 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x64, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x8b, 0x04, 0x0a, 0x08, 0x50, 0x72, 0x6f, - 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x32, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, - 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, - 0x61, 0x6c, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x0e, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x73, 0x70, 0x65, 0x63, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x64, 0x41, 0x74, 0x12, 0x28, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x22, 0x8d, 0x04, + 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x72, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x64, 0x65, + 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0e, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x15, 0x0a, 0x06, 0x6a, + 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, + 0x49, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, + 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x61, 0x63, 0x6b, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, - 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, - 0x00, 0x52, 0x07, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x51, 0x0a, - 0x14, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, - 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x01, 0x52, 0x12, 0x72, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, - 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x42, 0x17, 0x0a, - 0x15, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, - 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x22, 0x43, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x04, 0x75, 0x75, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x42, - 0x0a, 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x33, 0x0a, 0x0e, 0x47, - 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, - 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x03, 0x6a, 0x6f, 0x62, - 0x22, 0x24, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x47, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, - 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, - 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, - 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x22, - 0x84, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, - 0x35, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6e, - 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6e, - 0x6f, 0x64, 0x65, 0x49, 0x64, 0x73, 0x22, 0x37, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, - 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x6a, 0x6f, - 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, - 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x22, - 0x8c, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, - 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, - 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x33, 0x0a, 0x06, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x73, 0x22, 0x4b, - 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x70, 0x6f, - 0x73, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, - 0x52, 0x09, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x73, 0x22, 0x40, 0x0a, 0x11, 0x50, - 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x65, - 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x46, 0x0a, - 0x12, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, - 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x22, 0x46, 0x0a, 0x10, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, - 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x04, 0x75, - 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x75, 0x75, 0x69, - 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x45, 0x0a, - 0x11, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, - 0x6f, 0x73, 0x61, 0x6c, 0x22, 0x46, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, - 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x04, 0x75, 0x75, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, - 0x42, 0x0a, 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x36, 0x0a, 0x11, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x21, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4a, 0x6f, 0x62, 0x52, - 0x03, 0x6a, 0x6f, 0x62, 0x2a, 0xe4, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, - 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x50, 0x52, 0x4f, 0x50, 0x4f, - 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x4f, 0x50, - 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x50, - 0x4f, 0x53, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, - 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, - 0x45, 0x44, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, - 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, - 0x04, 0x12, 0x1b, 0x0a, 0x17, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x1b, - 0x0a, 0x17, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x52, 0x45, 0x56, 0x4f, 0x4b, 0x45, 0x44, 0x10, 0x06, 0x2a, 0xba, 0x01, 0x0a, 0x16, - 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, 0x24, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x07, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x41, + 0x74, 0x88, 0x01, 0x01, 0x12, 0x51, 0x0a, 0x14, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x01, + 0x52, 0x12, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, + 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x61, 0x63, 0x6b, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x42, 0x17, 0x0a, 0x15, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x22, 0x43, 0x0a, + 0x0d, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x14, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x6f, 0x6e, 0x65, + 0x6f, 0x66, 0x22, 0x33, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4a, + 0x6f, 0x62, 0x52, 0x03, 0x6a, 0x6f, 0x62, 0x22, 0x24, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x72, + 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x47, 0x0a, + 0x13, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x08, 0x70, 0x72, + 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x22, 0xb7, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4a, + 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x68, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, + 0x64, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x73, 0x12, 0x31, 0x0a, + 0x09, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, + 0x22, 0x37, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, + 0x4a, 0x6f, 0x62, 0x52, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x22, 0x8c, 0x01, 0x0a, 0x14, 0x4c, 0x69, + 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x1a, 0x33, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, + 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, + 0x17, 0x0a, 0x07, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x06, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x73, 0x22, 0x4b, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x32, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x70, + 0x6f, 0x73, 0x61, 0x6c, 0x73, 0x22, 0x6a, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, + 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, + 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, + 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x28, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x22, 0x46, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, + 0x73, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, + 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x22, 0x46, 0x0a, 0x10, 0x52, 0x65, 0x76, + 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x14, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x04, 0x75, 0x75, 0x69, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, + 0x66, 0x22, 0x45, 0x0a, 0x11, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, + 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, + 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x08, + 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x22, 0x46, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, + 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, + 0x75, 0x75, 0x69, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, + 0x22, 0x36, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, + 0x4a, 0x6f, 0x62, 0x52, 0x03, 0x6a, 0x6f, 0x62, 0x22, 0x70, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, + 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, + 0x75, 0x75, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x42, 0x0a, + 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x36, 0x0a, 0x11, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x21, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x03, 0x6a, + 0x6f, 0x62, 0x2a, 0xe4, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, + 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, + 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, + 0x45, 0x44, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, 0x45, 0x44, + 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, + 0x12, 0x1d, 0x0a, 0x19, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, + 0x1b, 0x0a, 0x17, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x1b, 0x0a, 0x17, + 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x52, 0x45, 0x56, 0x4f, 0x4b, 0x45, 0x44, 0x10, 0x06, 0x2a, 0xba, 0x01, 0x0a, 0x16, 0x50, 0x72, + 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, 0x24, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, + 0x5f, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x26, + 0x0a, 0x22, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x44, 0x45, 0x4c, 0x49, 0x56, + 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x45, 0x4c, 0x49, 0x56, + 0x45, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x29, 0x0a, 0x25, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x26, 0x0a, 0x22, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x44, 0x45, 0x4c, - 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x45, 0x4c, - 0x49, 0x56, 0x45, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x29, 0x0a, 0x25, 0x50, 0x52, 0x4f, 0x50, - 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x4b, 0x4e, 0x4f, 0x57, 0x4c, 0x45, 0x44, 0x47, 0x45, - 0x44, 0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, - 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x32, 0xa9, 0x04, 0x0a, 0x0a, 0x4a, 0x6f, 0x62, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4a, 0x6f, - 0x62, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0b, 0x47, 0x65, - 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, - 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, - 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x08, - 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, - 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, - 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x73, 0x12, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, + 0x55, 0x53, 0x5f, 0x41, 0x43, 0x4b, 0x4e, 0x4f, 0x57, 0x4c, 0x45, 0x44, 0x47, 0x45, 0x44, 0x10, + 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x44, 0x45, + 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, + 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x32, 0xf5, 0x04, 0x0a, 0x0a, 0x4a, 0x6f, 0x62, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x12, + 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, + 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, + 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, + 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x08, 0x4c, 0x69, + 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, + 0x73, 0x61, 0x6c, 0x73, 0x12, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, - 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, - 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4d, 0x0a, - 0x0a, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1d, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, - 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, - 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x09, - 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x0a, 0x50, + 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, + 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, + 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x09, 0x52, 0x65, + 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x6a, 0x6f, 0x62, 0x2f, 0x76, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x4a, 0x6f, 0x62, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, + 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x08, + 0x5a, 0x06, 0x6a, 0x6f, 0x62, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1445,7 +1633,7 @@ func file_job_v1_job_proto_rawDescGZIP() []byte { } var file_job_v1_job_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_job_v1_job_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_job_v1_job_proto_msgTypes = make([]protoimpl.MessageInfo, 20) var file_job_v1_job_proto_goTypes = []interface{}{ (ProposalStatus)(0), // 0: api.job.v1.ProposalStatus (ProposalDeliveryStatus)(0), // 1: api.job.v1.ProposalDeliveryStatus @@ -1465,48 +1653,59 @@ var file_job_v1_job_proto_goTypes = []interface{}{ (*RevokeJobResponse)(nil), // 15: api.job.v1.RevokeJobResponse (*DeleteJobRequest)(nil), // 16: api.job.v1.DeleteJobRequest (*DeleteJobResponse)(nil), // 17: api.job.v1.DeleteJobResponse - (*ListJobsRequest_Filter)(nil), // 18: api.job.v1.ListJobsRequest.Filter - (*ListProposalsRequest_Filter)(nil), // 19: api.job.v1.ListProposalsRequest.Filter - (*timestamppb.Timestamp)(nil), // 20: google.protobuf.Timestamp + (*UpdateJobRequest)(nil), // 18: api.job.v1.UpdateJobRequest + (*UpdateJobResponse)(nil), // 19: api.job.v1.UpdateJobResponse + (*ListJobsRequest_Filter)(nil), // 20: api.job.v1.ListJobsRequest.Filter + (*ListProposalsRequest_Filter)(nil), // 21: api.job.v1.ListProposalsRequest.Filter + (*timestamppb.Timestamp)(nil), // 22: google.protobuf.Timestamp + (*ptypes.Label)(nil), // 23: api.label.Label + (*ptypes.Selector)(nil), // 24: api.label.Selector } var file_job_v1_job_proto_depIdxs = []int32{ - 20, // 0: api.job.v1.Job.created_at:type_name -> google.protobuf.Timestamp - 20, // 1: api.job.v1.Job.updated_at:type_name -> google.protobuf.Timestamp - 20, // 2: api.job.v1.Job.deleted_at:type_name -> google.protobuf.Timestamp - 0, // 3: api.job.v1.Proposal.status:type_name -> api.job.v1.ProposalStatus - 1, // 4: api.job.v1.Proposal.delivery_status:type_name -> api.job.v1.ProposalDeliveryStatus - 20, // 5: api.job.v1.Proposal.created_at:type_name -> google.protobuf.Timestamp - 20, // 6: api.job.v1.Proposal.updated_at:type_name -> google.protobuf.Timestamp - 20, // 7: api.job.v1.Proposal.acked_at:type_name -> google.protobuf.Timestamp - 20, // 8: api.job.v1.Proposal.response_received_at:type_name -> google.protobuf.Timestamp - 2, // 9: api.job.v1.GetJobResponse.job:type_name -> api.job.v1.Job - 3, // 10: api.job.v1.GetProposalResponse.proposal:type_name -> api.job.v1.Proposal - 18, // 11: api.job.v1.ListJobsRequest.filter:type_name -> api.job.v1.ListJobsRequest.Filter - 2, // 12: api.job.v1.ListJobsResponse.jobs:type_name -> api.job.v1.Job - 19, // 13: api.job.v1.ListProposalsRequest.filter:type_name -> api.job.v1.ListProposalsRequest.Filter - 3, // 14: api.job.v1.ListProposalsResponse.proposals:type_name -> api.job.v1.Proposal - 3, // 15: api.job.v1.ProposeJobResponse.proposal:type_name -> api.job.v1.Proposal - 3, // 16: api.job.v1.RevokeJobResponse.proposal:type_name -> api.job.v1.Proposal - 2, // 17: api.job.v1.DeleteJobResponse.job:type_name -> api.job.v1.Job - 4, // 18: api.job.v1.JobService.GetJob:input_type -> api.job.v1.GetJobRequest - 6, // 19: api.job.v1.JobService.GetProposal:input_type -> api.job.v1.GetProposalRequest - 8, // 20: api.job.v1.JobService.ListJobs:input_type -> api.job.v1.ListJobsRequest - 10, // 21: api.job.v1.JobService.ListProposals:input_type -> api.job.v1.ListProposalsRequest - 12, // 22: api.job.v1.JobService.ProposeJob:input_type -> api.job.v1.ProposeJobRequest - 14, // 23: api.job.v1.JobService.RevokeJob:input_type -> api.job.v1.RevokeJobRequest - 16, // 24: api.job.v1.JobService.DeleteJob:input_type -> api.job.v1.DeleteJobRequest - 5, // 25: api.job.v1.JobService.GetJob:output_type -> api.job.v1.GetJobResponse - 7, // 26: api.job.v1.JobService.GetProposal:output_type -> api.job.v1.GetProposalResponse - 9, // 27: api.job.v1.JobService.ListJobs:output_type -> api.job.v1.ListJobsResponse - 11, // 28: api.job.v1.JobService.ListProposals:output_type -> api.job.v1.ListProposalsResponse - 13, // 29: api.job.v1.JobService.ProposeJob:output_type -> api.job.v1.ProposeJobResponse - 15, // 30: api.job.v1.JobService.RevokeJob:output_type -> api.job.v1.RevokeJobResponse - 17, // 31: api.job.v1.JobService.DeleteJob:output_type -> api.job.v1.DeleteJobResponse - 25, // [25:32] is the sub-list for method output_type - 18, // [18:25] is the sub-list for method input_type - 18, // [18:18] is the sub-list for extension type_name - 18, // [18:18] is the sub-list for extension extendee - 0, // [0:18] is the sub-list for field type_name + 22, // 0: api.job.v1.Job.created_at:type_name -> google.protobuf.Timestamp + 22, // 1: api.job.v1.Job.updated_at:type_name -> google.protobuf.Timestamp + 22, // 2: api.job.v1.Job.deleted_at:type_name -> google.protobuf.Timestamp + 23, // 3: api.job.v1.Job.labels:type_name -> api.label.Label + 0, // 4: api.job.v1.Proposal.status:type_name -> api.job.v1.ProposalStatus + 1, // 5: api.job.v1.Proposal.delivery_status:type_name -> api.job.v1.ProposalDeliveryStatus + 22, // 6: api.job.v1.Proposal.created_at:type_name -> google.protobuf.Timestamp + 22, // 7: api.job.v1.Proposal.updated_at:type_name -> google.protobuf.Timestamp + 22, // 8: api.job.v1.Proposal.acked_at:type_name -> google.protobuf.Timestamp + 22, // 9: api.job.v1.Proposal.response_received_at:type_name -> google.protobuf.Timestamp + 2, // 10: api.job.v1.GetJobResponse.job:type_name -> api.job.v1.Job + 3, // 11: api.job.v1.GetProposalResponse.proposal:type_name -> api.job.v1.Proposal + 20, // 12: api.job.v1.ListJobsRequest.filter:type_name -> api.job.v1.ListJobsRequest.Filter + 2, // 13: api.job.v1.ListJobsResponse.jobs:type_name -> api.job.v1.Job + 21, // 14: api.job.v1.ListProposalsRequest.filter:type_name -> api.job.v1.ListProposalsRequest.Filter + 3, // 15: api.job.v1.ListProposalsResponse.proposals:type_name -> api.job.v1.Proposal + 23, // 16: api.job.v1.ProposeJobRequest.labels:type_name -> api.label.Label + 3, // 17: api.job.v1.ProposeJobResponse.proposal:type_name -> api.job.v1.Proposal + 3, // 18: api.job.v1.RevokeJobResponse.proposal:type_name -> api.job.v1.Proposal + 2, // 19: api.job.v1.DeleteJobResponse.job:type_name -> api.job.v1.Job + 23, // 20: api.job.v1.UpdateJobRequest.labels:type_name -> api.label.Label + 2, // 21: api.job.v1.UpdateJobResponse.job:type_name -> api.job.v1.Job + 24, // 22: api.job.v1.ListJobsRequest.Filter.selectors:type_name -> api.label.Selector + 4, // 23: api.job.v1.JobService.GetJob:input_type -> api.job.v1.GetJobRequest + 6, // 24: api.job.v1.JobService.GetProposal:input_type -> api.job.v1.GetProposalRequest + 8, // 25: api.job.v1.JobService.ListJobs:input_type -> api.job.v1.ListJobsRequest + 10, // 26: api.job.v1.JobService.ListProposals:input_type -> api.job.v1.ListProposalsRequest + 12, // 27: api.job.v1.JobService.ProposeJob:input_type -> api.job.v1.ProposeJobRequest + 14, // 28: api.job.v1.JobService.RevokeJob:input_type -> api.job.v1.RevokeJobRequest + 16, // 29: api.job.v1.JobService.DeleteJob:input_type -> api.job.v1.DeleteJobRequest + 18, // 30: api.job.v1.JobService.UpdateJob:input_type -> api.job.v1.UpdateJobRequest + 5, // 31: api.job.v1.JobService.GetJob:output_type -> api.job.v1.GetJobResponse + 7, // 32: api.job.v1.JobService.GetProposal:output_type -> api.job.v1.GetProposalResponse + 9, // 33: api.job.v1.JobService.ListJobs:output_type -> api.job.v1.ListJobsResponse + 11, // 34: api.job.v1.JobService.ListProposals:output_type -> api.job.v1.ListProposalsResponse + 13, // 35: api.job.v1.JobService.ProposeJob:output_type -> api.job.v1.ProposeJobResponse + 15, // 36: api.job.v1.JobService.RevokeJob:output_type -> api.job.v1.RevokeJobResponse + 17, // 37: api.job.v1.JobService.DeleteJob:output_type -> api.job.v1.DeleteJobResponse + 19, // 38: api.job.v1.JobService.UpdateJob:output_type -> api.job.v1.UpdateJobResponse + 31, // [31:39] is the sub-list for method output_type + 23, // [23:31] is the sub-list for method input_type + 23, // [23:23] is the sub-list for extension type_name + 23, // [23:23] is the sub-list for extension extendee + 0, // [0:23] is the sub-list for field type_name } func init() { file_job_v1_job_proto_init() } @@ -1708,7 +1907,7 @@ func file_job_v1_job_proto_init() { } } file_job_v1_job_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListJobsRequest_Filter); i { + switch v := v.(*UpdateJobRequest); i { case 0: return &v.state case 1: @@ -1720,6 +1919,30 @@ func file_job_v1_job_proto_init() { } } file_job_v1_job_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateJobResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListJobsRequest_Filter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_v1_job_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListProposalsRequest_Filter); i { case 0: return &v.state @@ -1745,13 +1968,17 @@ func file_job_v1_job_proto_init() { (*DeleteJobRequest_Id)(nil), (*DeleteJobRequest_Uuid)(nil), } + file_job_v1_job_proto_msgTypes[16].OneofWrappers = []interface{}{ + (*UpdateJobRequest_Id)(nil), + (*UpdateJobRequest_Uuid)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_job_v1_job_proto_rawDesc, NumEnums: 2, - NumMessages: 18, + NumMessages: 20, NumExtensions: 0, NumServices: 1, }, @@ -1764,4 +1991,4 @@ func file_job_v1_job_proto_init() { file_job_v1_job_proto_rawDesc = nil file_job_v1_job_proto_goTypes = nil file_job_v1_job_proto_depIdxs = nil -} +} \ No newline at end of file diff --git a/integration-tests/deployment/jd/job/v1/job_grpc.pb.go b/integration-tests/deployment/jd/job/v1/job_grpc.pb.go index 9b9207c020..1ac2ca13c9 100644 --- a/integration-tests/deployment/jd/job/v1/job_grpc.pb.go +++ b/integration-tests/deployment/jd/job/v1/job_grpc.pb.go @@ -26,6 +26,7 @@ const ( JobService_ProposeJob_FullMethodName = "/api.job.v1.JobService/ProposeJob" JobService_RevokeJob_FullMethodName = "/api.job.v1.JobService/RevokeJob" JobService_DeleteJob_FullMethodName = "/api.job.v1.JobService/DeleteJob" + JobService_UpdateJob_FullMethodName = "/api.job.v1.JobService/UpdateJob" ) // JobServiceClient is the client API for JobService service. @@ -46,6 +47,8 @@ type JobServiceClient interface { RevokeJob(ctx context.Context, in *RevokeJobRequest, opts ...grpc.CallOption) (*RevokeJobResponse, error) // DeleteJob deletes a job from the system. DeleteJob(ctx context.Context, in *DeleteJobRequest, opts ...grpc.CallOption) (*DeleteJobResponse, error) + // UpdateJob updates a job in the system. + UpdateJob(ctx context.Context, in *UpdateJobRequest, opts ...grpc.CallOption) (*UpdateJobResponse, error) } type jobServiceClient struct { @@ -119,6 +122,15 @@ func (c *jobServiceClient) DeleteJob(ctx context.Context, in *DeleteJobRequest, return out, nil } +func (c *jobServiceClient) UpdateJob(ctx context.Context, in *UpdateJobRequest, opts ...grpc.CallOption) (*UpdateJobResponse, error) { + out := new(UpdateJobResponse) + err := c.cc.Invoke(ctx, JobService_UpdateJob_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // JobServiceServer is the server API for JobService service. // All implementations must embed UnimplementedJobServiceServer // for forward compatibility @@ -137,6 +149,8 @@ type JobServiceServer interface { RevokeJob(context.Context, *RevokeJobRequest) (*RevokeJobResponse, error) // DeleteJob deletes a job from the system. DeleteJob(context.Context, *DeleteJobRequest) (*DeleteJobResponse, error) + // UpdateJob updates a job in the system. + UpdateJob(context.Context, *UpdateJobRequest) (*UpdateJobResponse, error) mustEmbedUnimplementedJobServiceServer() } @@ -165,6 +179,9 @@ func (UnimplementedJobServiceServer) RevokeJob(context.Context, *RevokeJobReques func (UnimplementedJobServiceServer) DeleteJob(context.Context, *DeleteJobRequest) (*DeleteJobResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteJob not implemented") } +func (UnimplementedJobServiceServer) UpdateJob(context.Context, *UpdateJobRequest) (*UpdateJobResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateJob not implemented") +} func (UnimplementedJobServiceServer) mustEmbedUnimplementedJobServiceServer() {} // UnsafeJobServiceServer may be embedded to opt out of forward compatibility for this service. @@ -304,6 +321,24 @@ func _JobService_DeleteJob_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _JobService_UpdateJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateJobRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(JobServiceServer).UpdateJob(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: JobService_UpdateJob_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(JobServiceServer).UpdateJob(ctx, req.(*UpdateJobRequest)) + } + return interceptor(ctx, in, info, handler) +} + // JobService_ServiceDesc is the grpc.ServiceDesc for JobService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -339,7 +374,11 @@ var JobService_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteJob", Handler: _JobService_DeleteJob_Handler, }, + { + MethodName: "UpdateJob", + Handler: _JobService_UpdateJob_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "job/v1/job.proto", -} +} \ No newline at end of file diff --git a/integration-tests/deployment/jd/node/v1/node.pb.go b/integration-tests/deployment/jd/node/v1/node.pb.go index f5b22ba3ae..172e285645 100644 --- a/integration-tests/deployment/jd/node/v1/node.pb.go +++ b/integration-tests/deployment/jd/node/v1/node.pb.go @@ -7,14 +7,12 @@ package v1 import ( - "reflect" - "sync" - - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/runtime/protoimpl" - _ "google.golang.org/protobuf/types/known/timestamppb" - - "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/shared/ptypes" + ptypes "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/shared/ptypes" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" ) const ( @@ -30,6 +28,7 @@ const ( ChainType_CHAIN_TYPE_UNSPECIFIED ChainType = 0 ChainType_CHAIN_TYPE_EVM ChainType = 1 ChainType_CHAIN_TYPE_SOLANA ChainType = 2 + ChainType_CHAIN_TYPE_STARKNET ChainType = 3 ) // Enum value maps for ChainType. @@ -38,11 +37,13 @@ var ( 0: "CHAIN_TYPE_UNSPECIFIED", 1: "CHAIN_TYPE_EVM", 2: "CHAIN_TYPE_SOLANA", + 3: "CHAIN_TYPE_STARKNET", } ChainType_value = map[string]int32{ "CHAIN_TYPE_UNSPECIFIED": 0, "CHAIN_TYPE_EVM": 1, "CHAIN_TYPE_SOLANA": 2, + "CHAIN_TYPE_STARKNET": 3, } ) @@ -73,56 +74,160 @@ func (ChainType) EnumDescriptor() ([]byte, []int) { return file_node_v1_node_proto_rawDescGZIP(), []int{0} } -// ArchiveState represents the archived state of the node. -type ArchiveState int32 +// EnableState represents the enabled state of the node. +type EnableState int32 const ( - ArchiveState_ARCHIVE_STATE_UNSPECIFIED ArchiveState = 0 - ArchiveState_ARCHIVE_STATE_ARCHIVED ArchiveState = 1 - ArchiveState_ARCHIVE_STATE_ACTIVE ArchiveState = 2 + EnableState_ENABLE_STATE_UNSPECIFIED EnableState = 0 + EnableState_ENABLE_STATE_ENABLED EnableState = 1 + EnableState_ENABLE_STATE_DISABLED EnableState = 2 ) -// Enum value maps for ArchiveState. +// Enum value maps for EnableState. var ( - ArchiveState_name = map[int32]string{ - 0: "ARCHIVE_STATE_UNSPECIFIED", - 1: "ARCHIVE_STATE_ARCHIVED", - 2: "ARCHIVE_STATE_ACTIVE", + EnableState_name = map[int32]string{ + 0: "ENABLE_STATE_UNSPECIFIED", + 1: "ENABLE_STATE_ENABLED", + 2: "ENABLE_STATE_DISABLED", } - ArchiveState_value = map[string]int32{ - "ARCHIVE_STATE_UNSPECIFIED": 0, - "ARCHIVE_STATE_ARCHIVED": 1, - "ARCHIVE_STATE_ACTIVE": 2, + EnableState_value = map[string]int32{ + "ENABLE_STATE_UNSPECIFIED": 0, + "ENABLE_STATE_ENABLED": 1, + "ENABLE_STATE_DISABLED": 2, } ) -func (x ArchiveState) Enum() *ArchiveState { - p := new(ArchiveState) +func (x EnableState) Enum() *EnableState { + p := new(EnableState) *p = x return p } -func (x ArchiveState) String() string { +func (x EnableState) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (ArchiveState) Descriptor() protoreflect.EnumDescriptor { +func (EnableState) Descriptor() protoreflect.EnumDescriptor { return file_node_v1_node_proto_enumTypes[1].Descriptor() } -func (ArchiveState) Type() protoreflect.EnumType { +func (EnableState) Type() protoreflect.EnumType { return &file_node_v1_node_proto_enumTypes[1] } -func (x ArchiveState) Number() protoreflect.EnumNumber { +func (x EnableState) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } -// Deprecated: Use ArchiveState.Descriptor instead. -func (ArchiveState) EnumDescriptor() ([]byte, []int) { +// Deprecated: Use EnableState.Descriptor instead. +func (EnableState) EnumDescriptor() ([]byte, []int) { return file_node_v1_node_proto_rawDescGZIP(), []int{1} } +// Node represents a node within the Job Distributor system. +type Node struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier for the node. + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // Human-readable name for the node. + PublicKey string `protobuf:"bytes,3,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` // Public key used for secure communications. + IsEnabled bool `protobuf:"varint,4,opt,name=is_enabled,json=isEnabled,proto3" json:"is_enabled,omitempty"` // Indicates if the node is currently enabled. + IsConnected bool `protobuf:"varint,5,opt,name=is_connected,json=isConnected,proto3" json:"is_connected,omitempty"` // Indicates if the node is currently connected to the network. + Labels []*ptypes.Label `protobuf:"bytes,6,rep,name=labels,proto3" json:"labels,omitempty"` // Set of labels associated with the node. + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Timestamp when the node was created. + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // Timestamp when the node was last updated. +} + +func (x *Node) Reset() { + *x = Node{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Node) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Node) ProtoMessage() {} + +func (x *Node) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Node.ProtoReflect.Descriptor instead. +func (*Node) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{0} +} + +func (x *Node) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Node) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Node) GetPublicKey() string { + if x != nil { + return x.PublicKey + } + return "" +} + +func (x *Node) GetIsEnabled() bool { + if x != nil { + return x.IsEnabled + } + return false +} + +func (x *Node) GetIsConnected() bool { + if x != nil { + return x.IsConnected + } + return false +} + +func (x *Node) GetLabels() []*ptypes.Label { + if x != nil { + return x.Labels + } + return nil +} + +func (x *Node) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Node) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + type Chain struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -135,7 +240,7 @@ type Chain struct { func (x *Chain) Reset() { *x = Chain{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[0] + mi := &file_node_v1_node_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -148,7 +253,7 @@ func (x *Chain) String() string { func (*Chain) ProtoMessage() {} func (x *Chain) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[0] + mi := &file_node_v1_node_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -161,7 +266,7 @@ func (x *Chain) ProtoReflect() protoreflect.Message { // Deprecated: Use Chain.ProtoReflect.Descriptor instead. func (*Chain) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{0} + return file_node_v1_node_proto_rawDescGZIP(), []int{1} } func (x *Chain) GetId() string { @@ -178,6 +283,55 @@ func (x *Chain) GetType() ChainType { return ChainType_CHAIN_TYPE_UNSPECIFIED } +// The config for Flux Monitor on a specific chain +type FluxMonitorConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` +} + +func (x *FluxMonitorConfig) Reset() { + *x = FluxMonitorConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FluxMonitorConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FluxMonitorConfig) ProtoMessage() {} + +func (x *FluxMonitorConfig) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FluxMonitorConfig.ProtoReflect.Descriptor instead. +func (*FluxMonitorConfig) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{2} +} + +func (x *FluxMonitorConfig) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +// The config for OCR1 on a specific chain type OCR1Config struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -193,7 +347,7 @@ type OCR1Config struct { func (x *OCR1Config) Reset() { *x = OCR1Config{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[1] + mi := &file_node_v1_node_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -206,7 +360,7 @@ func (x *OCR1Config) String() string { func (*OCR1Config) ProtoMessage() {} func (x *OCR1Config) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[1] + mi := &file_node_v1_node_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -219,7 +373,7 @@ func (x *OCR1Config) ProtoReflect() protoreflect.Message { // Deprecated: Use OCR1Config.ProtoReflect.Descriptor instead. func (*OCR1Config) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{1} + return file_node_v1_node_proto_rawDescGZIP(), []int{3} } func (x *OCR1Config) GetEnabled() bool { @@ -257,6 +411,7 @@ func (x *OCR1Config) GetMultiaddr() string { return "" } +// The config for OCR2 on a specific chain type OCR2Config struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -268,13 +423,13 @@ type OCR2Config struct { OcrKeyBundle *OCR2Config_OCRKeyBundle `protobuf:"bytes,4,opt,name=ocr_key_bundle,json=ocrKeyBundle,proto3" json:"ocr_key_bundle,omitempty"` Multiaddr string `protobuf:"bytes,5,opt,name=multiaddr,proto3" json:"multiaddr,omitempty"` Plugins *OCR2Config_Plugins `protobuf:"bytes,6,opt,name=plugins,proto3" json:"plugins,omitempty"` - ForwarderAddress string `protobuf:"bytes,7,opt,name=forwarder_address,json=forwarderAddress,proto3" json:"forwarder_address,omitempty"` + ForwarderAddress *string `protobuf:"bytes,7,opt,name=forwarder_address,json=forwarderAddress,proto3,oneof" json:"forwarder_address,omitempty"` } func (x *OCR2Config) Reset() { *x = OCR2Config{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[2] + mi := &file_node_v1_node_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -287,7 +442,7 @@ func (x *OCR2Config) String() string { func (*OCR2Config) ProtoMessage() {} func (x *OCR2Config) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[2] + mi := &file_node_v1_node_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -300,7 +455,7 @@ func (x *OCR2Config) ProtoReflect() protoreflect.Message { // Deprecated: Use OCR2Config.ProtoReflect.Descriptor instead. func (*OCR2Config) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{2} + return file_node_v1_node_proto_rawDescGZIP(), []int{4} } func (x *OCR2Config) GetEnabled() bool { @@ -346,8 +501,8 @@ func (x *OCR2Config) GetPlugins() *OCR2Config_Plugins { } func (x *OCR2Config) GetForwarderAddress() string { - if x != nil { - return x.ForwarderAddress + if x != nil && x.ForwarderAddress != nil { + return *x.ForwarderAddress } return "" } @@ -357,17 +512,23 @@ type ChainConfig struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Chain *Chain `protobuf:"bytes,1,opt,name=chain,proto3" json:"chain,omitempty"` - AccountAddress string `protobuf:"bytes,2,opt,name=account_address,json=accountAddress,proto3" json:"account_address,omitempty"` - AdminAddress string `protobuf:"bytes,3,opt,name=admin_address,json=adminAddress,proto3" json:"admin_address,omitempty"` - Ocr1Config *OCR1Config `protobuf:"bytes,4,opt,name=ocr1_config,json=ocr1Config,proto3" json:"ocr1_config,omitempty"` - Ocr2Config *OCR2Config `protobuf:"bytes,5,opt,name=ocr2_config,json=ocr2Config,proto3" json:"ocr2_config,omitempty"` + Chain *Chain `protobuf:"bytes,1,opt,name=chain,proto3" json:"chain,omitempty"` + AccountAddress string `protobuf:"bytes,2,opt,name=account_address,json=accountAddress,proto3" json:"account_address,omitempty"` + AdminAddress string `protobuf:"bytes,3,opt,name=admin_address,json=adminAddress,proto3" json:"admin_address,omitempty"` + FluxMonitorConfig *FluxMonitorConfig `protobuf:"bytes,4,opt,name=flux_monitor_config,json=fluxMonitorConfig,proto3" json:"flux_monitor_config,omitempty"` + Ocr1Config *OCR1Config `protobuf:"bytes,5,opt,name=ocr1_config,json=ocr1Config,proto3" json:"ocr1_config,omitempty"` + Ocr2Config *OCR2Config `protobuf:"bytes,6,opt,name=ocr2_config,json=ocr2Config,proto3" json:"ocr2_config,omitempty"` + // For EVM chains, we do not need this value and it is kept in the node's + // keystore. For starknet, because the wallet address needs to be deployed + // using this value and this pub key needs to be passed into the starknet + // relayer, we request the node to send this directly to CLO. + AccountAddressPublicKey *string `protobuf:"bytes,7,opt,name=account_address_public_key,json=accountAddressPublicKey,proto3,oneof" json:"account_address_public_key,omitempty"` } func (x *ChainConfig) Reset() { *x = ChainConfig{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[3] + mi := &file_node_v1_node_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -380,7 +541,7 @@ func (x *ChainConfig) String() string { func (*ChainConfig) ProtoMessage() {} func (x *ChainConfig) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[3] + mi := &file_node_v1_node_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -393,7 +554,7 @@ func (x *ChainConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use ChainConfig.ProtoReflect.Descriptor instead. func (*ChainConfig) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{3} + return file_node_v1_node_proto_rawDescGZIP(), []int{5} } func (x *ChainConfig) GetChain() *Chain { @@ -410,53 +571,502 @@ func (x *ChainConfig) GetAccountAddress() string { return "" } -func (x *ChainConfig) GetAdminAddress() string { - if x != nil { - return x.AdminAddress +func (x *ChainConfig) GetAdminAddress() string { + if x != nil { + return x.AdminAddress + } + return "" +} + +func (x *ChainConfig) GetFluxMonitorConfig() *FluxMonitorConfig { + if x != nil { + return x.FluxMonitorConfig + } + return nil +} + +func (x *ChainConfig) GetOcr1Config() *OCR1Config { + if x != nil { + return x.Ocr1Config + } + return nil +} + +func (x *ChainConfig) GetOcr2Config() *OCR2Config { + if x != nil { + return x.Ocr2Config + } + return nil +} + +func (x *ChainConfig) GetAccountAddressPublicKey() string { + if x != nil && x.AccountAddressPublicKey != nil { + return *x.AccountAddressPublicKey + } + return "" +} + +// RegisterNodeRequest contains the information needed to register a new node. +type RegisterNodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Desired name for the node. + PublicKey string `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` // Public key for the node. + Labels []*ptypes.Label `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty"` // Labels to associate with the node. +} + +func (x *RegisterNodeRequest) Reset() { + *x = RegisterNodeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterNodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterNodeRequest) ProtoMessage() {} + +func (x *RegisterNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterNodeRequest.ProtoReflect.Descriptor instead. +func (*RegisterNodeRequest) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{6} +} + +func (x *RegisterNodeRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RegisterNodeRequest) GetPublicKey() string { + if x != nil { + return x.PublicKey + } + return "" +} + +func (x *RegisterNodeRequest) GetLabels() []*ptypes.Label { + if x != nil { + return x.Labels + } + return nil +} + +// RegisterNodeResponse returns the newly registered node. +type RegisterNodeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` // Details of the newly registered node. +} + +func (x *RegisterNodeResponse) Reset() { + *x = RegisterNodeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterNodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterNodeResponse) ProtoMessage() {} + +func (x *RegisterNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterNodeResponse.ProtoReflect.Descriptor instead. +func (*RegisterNodeResponse) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{7} +} + +func (x *RegisterNodeResponse) GetNode() *Node { + if x != nil { + return x.Node + } + return nil +} + +// GetNodeRequest is the request to retrieve a single node by its ID. +type GetNodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier of the node to retrieve. +} + +func (x *GetNodeRequest) Reset() { + *x = GetNodeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeRequest) ProtoMessage() {} + +func (x *GetNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeRequest.ProtoReflect.Descriptor instead. +func (*GetNodeRequest) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{8} +} + +func (x *GetNodeRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// GetNodeResponse is the response containing the requested node. +type GetNodeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` // Details of the retrieved node. +} + +func (x *GetNodeResponse) Reset() { + *x = GetNodeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeResponse) ProtoMessage() {} + +func (x *GetNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeResponse.ProtoReflect.Descriptor instead. +func (*GetNodeResponse) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{9} +} + +func (x *GetNodeResponse) GetNode() *Node { + if x != nil { + return x.Node + } + return nil +} + +// * +// ListNodesRequest is the request object for the ListNodes method. +// +// Provide a filter to return a subset of data. Nodes can be filtered by: +// - ids - A list of node ids. +// - archived - The archived state of the node. +// - selectors - A list of selectors to filter nodes by their labels. +// +// If no filter is provided, all nodes are returned. +type ListNodesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Filter *ListNodesRequest_Filter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` +} + +func (x *ListNodesRequest) Reset() { + *x = ListNodesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListNodesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListNodesRequest) ProtoMessage() {} + +func (x *ListNodesRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListNodesRequest.ProtoReflect.Descriptor instead. +func (*ListNodesRequest) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{10} +} + +func (x *ListNodesRequest) GetFilter() *ListNodesRequest_Filter { + if x != nil { + return x.Filter + } + return nil +} + +// * +// ListNodesResponse is the response object for the ListNodes method. +// +// It returns a list of nodes that match the filter criteria. +type ListNodesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nodes []*Node `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"` // List of nodes. +} + +func (x *ListNodesResponse) Reset() { + *x = ListNodesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListNodesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListNodesResponse) ProtoMessage() {} + +func (x *ListNodesResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListNodesResponse.ProtoReflect.Descriptor instead. +func (*ListNodesResponse) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{11} +} + +func (x *ListNodesResponse) GetNodes() []*Node { + if x != nil { + return x.Nodes + } + return nil +} + +// UpdateNodeRequest contains the information necessary to update a node. +type UpdateNodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier of the node to update. + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // New name for the node, if changing. + PublicKey string `protobuf:"bytes,3,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` // New public key for the node, if changing. + Labels []*ptypes.Label `protobuf:"bytes,4,rep,name=labels,proto3" json:"labels,omitempty"` // New set of labels for the node, if changing. +} + +func (x *UpdateNodeRequest) Reset() { + *x = UpdateNodeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateNodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateNodeRequest) ProtoMessage() {} + +func (x *UpdateNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateNodeRequest.ProtoReflect.Descriptor instead. +func (*UpdateNodeRequest) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{12} +} + +func (x *UpdateNodeRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateNodeRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateNodeRequest) GetPublicKey() string { + if x != nil { + return x.PublicKey + } + return "" +} + +func (x *UpdateNodeRequest) GetLabels() []*ptypes.Label { + if x != nil { + return x.Labels + } + return nil +} + +// UpdateNodeResponse returns the updated node. +type UpdateNodeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` // Updated node details. +} + +func (x *UpdateNodeResponse) Reset() { + *x = UpdateNodeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateNodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateNodeResponse) ProtoMessage() {} + +func (x *UpdateNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return "" + return mi.MessageOf(x) } -func (x *ChainConfig) GetOcr1Config() *OCR1Config { - if x != nil { - return x.Ocr1Config - } - return nil +// Deprecated: Use UpdateNodeResponse.ProtoReflect.Descriptor instead. +func (*UpdateNodeResponse) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{13} } -func (x *ChainConfig) GetOcr2Config() *OCR2Config { +func (x *UpdateNodeResponse) GetNode() *Node { if x != nil { - return x.Ocr2Config + return x.Node } return nil } -// GetNodeRequest is the request to retrieve a single node by its ID. -type GetNodeRequest struct { +// DisableNodeRequest is used to mark a node as disabled. +type DisableNodeRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier of the node to retrieve. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier of the node to disable. } -func (x *GetNodeRequest) Reset() { - *x = GetNodeRequest{} +func (x *DisableNodeRequest) Reset() { + *x = DisableNodeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[4] + mi := &file_node_v1_node_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *GetNodeRequest) String() string { +func (x *DisableNodeRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetNodeRequest) ProtoMessage() {} +func (*DisableNodeRequest) ProtoMessage() {} -func (x *GetNodeRequest) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[4] +func (x *DisableNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -467,44 +1077,44 @@ func (x *GetNodeRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetNodeRequest.ProtoReflect.Descriptor instead. -func (*GetNodeRequest) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{4} +// Deprecated: Use DisableNodeRequest.ProtoReflect.Descriptor instead. +func (*DisableNodeRequest) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{14} } -func (x *GetNodeRequest) GetId() string { +func (x *DisableNodeRequest) GetId() string { if x != nil { return x.Id } return "" } -// GetNodeResponse is the response containing the requested node. -type GetNodeResponse struct { +// DisableNodeResponse returns the disabled node. +type DisableNodeResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` // Details of the retrieved node. + Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` // Disabled node details. } -func (x *GetNodeResponse) Reset() { - *x = GetNodeResponse{} +func (x *DisableNodeResponse) Reset() { + *x = DisableNodeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[5] + mi := &file_node_v1_node_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *GetNodeResponse) String() string { +func (x *DisableNodeResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetNodeResponse) ProtoMessage() {} +func (*DisableNodeResponse) ProtoMessage() {} -func (x *GetNodeResponse) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[5] +func (x *DisableNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -515,52 +1125,44 @@ func (x *GetNodeResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetNodeResponse.ProtoReflect.Descriptor instead. -func (*GetNodeResponse) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{5} +// Deprecated: Use DisableNodeResponse.ProtoReflect.Descriptor instead. +func (*DisableNodeResponse) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{15} } -func (x *GetNodeResponse) GetNode() *Node { +func (x *DisableNodeResponse) GetNode() *Node { if x != nil { return x.Node } return nil } -// * -// ListNodesRequest is the request object for the ListNodes method. -// -// Provide a filter to return a subset of data. Nodes can be filtered by: -// - ids - A list of node ids. -// - archived - The archived state of the node. -// - selectors - A list of selectors to filter nodes by their labels. -// -// If no filter is provided, all nodes are returned. -type ListNodesRequest struct { +// EnableNodeRequest is used to reactivate a disabled node. +type EnableNodeRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Filter *ListNodesRequest_Filter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier of the node to enable. } -func (x *ListNodesRequest) Reset() { - *x = ListNodesRequest{} +func (x *EnableNodeRequest) Reset() { + *x = EnableNodeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[6] + mi := &file_node_v1_node_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ListNodesRequest) String() string { +func (x *EnableNodeRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListNodesRequest) ProtoMessage() {} +func (*EnableNodeRequest) ProtoMessage() {} -func (x *ListNodesRequest) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[6] +func (x *EnableNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -571,47 +1173,44 @@ func (x *ListNodesRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListNodesRequest.ProtoReflect.Descriptor instead. -func (*ListNodesRequest) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{6} +// Deprecated: Use EnableNodeRequest.ProtoReflect.Descriptor instead. +func (*EnableNodeRequest) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{16} } -func (x *ListNodesRequest) GetFilter() *ListNodesRequest_Filter { +func (x *EnableNodeRequest) GetId() string { if x != nil { - return x.Filter + return x.Id } - return nil + return "" } -// * -// ListNodesResponse is the response object for the ListNodes method. -// -// It returns a list of nodes that match the filter criteria. -type ListNodesResponse struct { +// EnableNodeResponse returns the enabled node. +type EnableNodeResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Nodes []*Node `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"` // List of nodes. + Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` // Enabled node details. } -func (x *ListNodesResponse) Reset() { - *x = ListNodesResponse{} +func (x *EnableNodeResponse) Reset() { + *x = EnableNodeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[7] + mi := &file_node_v1_node_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ListNodesResponse) String() string { +func (x *EnableNodeResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListNodesResponse) ProtoMessage() {} +func (*EnableNodeResponse) ProtoMessage() {} -func (x *ListNodesResponse) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[7] +func (x *EnableNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -622,14 +1221,14 @@ func (x *ListNodesResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListNodesResponse.ProtoReflect.Descriptor instead. -func (*ListNodesResponse) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{7} +// Deprecated: Use EnableNodeResponse.ProtoReflect.Descriptor instead. +func (*EnableNodeResponse) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{17} } -func (x *ListNodesResponse) GetNodes() []*Node { +func (x *EnableNodeResponse) GetNode() *Node { if x != nil { - return x.Nodes + return x.Node } return nil } @@ -645,7 +1244,7 @@ type ListNodeChainConfigsRequest struct { func (x *ListNodeChainConfigsRequest) Reset() { *x = ListNodeChainConfigsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[8] + mi := &file_node_v1_node_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -658,7 +1257,7 @@ func (x *ListNodeChainConfigsRequest) String() string { func (*ListNodeChainConfigsRequest) ProtoMessage() {} func (x *ListNodeChainConfigsRequest) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[8] + mi := &file_node_v1_node_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -671,7 +1270,7 @@ func (x *ListNodeChainConfigsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListNodeChainConfigsRequest.ProtoReflect.Descriptor instead. func (*ListNodeChainConfigsRequest) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{8} + return file_node_v1_node_proto_rawDescGZIP(), []int{18} } func (x *ListNodeChainConfigsRequest) GetFilter() *ListNodeChainConfigsRequest_Filter { @@ -692,7 +1291,7 @@ type ListNodeChainConfigsResponse struct { func (x *ListNodeChainConfigsResponse) Reset() { *x = ListNodeChainConfigsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[9] + mi := &file_node_v1_node_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -705,7 +1304,7 @@ func (x *ListNodeChainConfigsResponse) String() string { func (*ListNodeChainConfigsResponse) ProtoMessage() {} func (x *ListNodeChainConfigsResponse) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[9] + mi := &file_node_v1_node_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -718,7 +1317,7 @@ func (x *ListNodeChainConfigsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListNodeChainConfigsResponse.ProtoReflect.Descriptor instead. func (*ListNodeChainConfigsResponse) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{9} + return file_node_v1_node_proto_rawDescGZIP(), []int{19} } func (x *ListNodeChainConfigsResponse) GetChainConfigs() []*ChainConfig { @@ -740,7 +1339,7 @@ type OCR1Config_P2PKeyBundle struct { func (x *OCR1Config_P2PKeyBundle) Reset() { *x = OCR1Config_P2PKeyBundle{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[10] + mi := &file_node_v1_node_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -753,7 +1352,7 @@ func (x *OCR1Config_P2PKeyBundle) String() string { func (*OCR1Config_P2PKeyBundle) ProtoMessage() {} func (x *OCR1Config_P2PKeyBundle) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[10] + mi := &file_node_v1_node_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -766,7 +1365,7 @@ func (x *OCR1Config_P2PKeyBundle) ProtoReflect() protoreflect.Message { // Deprecated: Use OCR1Config_P2PKeyBundle.ProtoReflect.Descriptor instead. func (*OCR1Config_P2PKeyBundle) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{1, 0} + return file_node_v1_node_proto_rawDescGZIP(), []int{3, 0} } func (x *OCR1Config_P2PKeyBundle) GetPeerId() string { @@ -797,7 +1396,7 @@ type OCR1Config_OCRKeyBundle struct { func (x *OCR1Config_OCRKeyBundle) Reset() { *x = OCR1Config_OCRKeyBundle{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[11] + mi := &file_node_v1_node_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -810,7 +1409,7 @@ func (x *OCR1Config_OCRKeyBundle) String() string { func (*OCR1Config_OCRKeyBundle) ProtoMessage() {} func (x *OCR1Config_OCRKeyBundle) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[11] + mi := &file_node_v1_node_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -823,7 +1422,7 @@ func (x *OCR1Config_OCRKeyBundle) ProtoReflect() protoreflect.Message { // Deprecated: Use OCR1Config_OCRKeyBundle.ProtoReflect.Descriptor instead. func (*OCR1Config_OCRKeyBundle) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{1, 1} + return file_node_v1_node_proto_rawDescGZIP(), []int{3, 1} } func (x *OCR1Config_OCRKeyBundle) GetBundleId() string { @@ -866,7 +1465,7 @@ type OCR2Config_P2PKeyBundle struct { func (x *OCR2Config_P2PKeyBundle) Reset() { *x = OCR2Config_P2PKeyBundle{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[12] + mi := &file_node_v1_node_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -879,7 +1478,7 @@ func (x *OCR2Config_P2PKeyBundle) String() string { func (*OCR2Config_P2PKeyBundle) ProtoMessage() {} func (x *OCR2Config_P2PKeyBundle) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[12] + mi := &file_node_v1_node_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -892,7 +1491,7 @@ func (x *OCR2Config_P2PKeyBundle) ProtoReflect() protoreflect.Message { // Deprecated: Use OCR2Config_P2PKeyBundle.ProtoReflect.Descriptor instead. func (*OCR2Config_P2PKeyBundle) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{2, 0} + return file_node_v1_node_proto_rawDescGZIP(), []int{4, 0} } func (x *OCR2Config_P2PKeyBundle) GetPeerId() string { @@ -923,7 +1522,7 @@ type OCR2Config_OCRKeyBundle struct { func (x *OCR2Config_OCRKeyBundle) Reset() { *x = OCR2Config_OCRKeyBundle{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[13] + mi := &file_node_v1_node_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -936,7 +1535,7 @@ func (x *OCR2Config_OCRKeyBundle) String() string { func (*OCR2Config_OCRKeyBundle) ProtoMessage() {} func (x *OCR2Config_OCRKeyBundle) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[13] + mi := &file_node_v1_node_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -949,7 +1548,7 @@ func (x *OCR2Config_OCRKeyBundle) ProtoReflect() protoreflect.Message { // Deprecated: Use OCR2Config_OCRKeyBundle.ProtoReflect.Descriptor instead. func (*OCR2Config_OCRKeyBundle) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{2, 1} + return file_node_v1_node_proto_rawDescGZIP(), []int{4, 1} } func (x *OCR2Config_OCRKeyBundle) GetBundleId() string { @@ -995,7 +1594,7 @@ type OCR2Config_Plugins struct { func (x *OCR2Config_Plugins) Reset() { *x = OCR2Config_Plugins{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[14] + mi := &file_node_v1_node_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1008,7 +1607,7 @@ func (x *OCR2Config_Plugins) String() string { func (*OCR2Config_Plugins) ProtoMessage() {} func (x *OCR2Config_Plugins) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[14] + mi := &file_node_v1_node_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1021,7 +1620,7 @@ func (x *OCR2Config_Plugins) ProtoReflect() protoreflect.Message { // Deprecated: Use OCR2Config_Plugins.ProtoReflect.Descriptor instead. func (*OCR2Config_Plugins) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{2, 2} + return file_node_v1_node_proto_rawDescGZIP(), []int{4, 2} } func (x *OCR2Config_Plugins) GetCommit() bool { @@ -1065,14 +1664,14 @@ type ListNodesRequest_Filter struct { unknownFields protoimpl.UnknownFields Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"` - Archived ArchiveState `protobuf:"varint,2,opt,name=archived,proto3,enum=api.node.v1.ArchiveState" json:"archived,omitempty"` + Enabled EnableState `protobuf:"varint,2,opt,name=enabled,proto3,enum=api.node.v1.EnableState" json:"enabled,omitempty"` Selectors []*ptypes.Selector `protobuf:"bytes,3,rep,name=selectors,proto3" json:"selectors,omitempty"` } func (x *ListNodesRequest_Filter) Reset() { *x = ListNodesRequest_Filter{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[15] + mi := &file_node_v1_node_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1085,7 +1684,7 @@ func (x *ListNodesRequest_Filter) String() string { func (*ListNodesRequest_Filter) ProtoMessage() {} func (x *ListNodesRequest_Filter) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[15] + mi := &file_node_v1_node_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1098,7 +1697,7 @@ func (x *ListNodesRequest_Filter) ProtoReflect() protoreflect.Message { // Deprecated: Use ListNodesRequest_Filter.ProtoReflect.Descriptor instead. func (*ListNodesRequest_Filter) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{6, 0} + return file_node_v1_node_proto_rawDescGZIP(), []int{10, 0} } func (x *ListNodesRequest_Filter) GetIds() []string { @@ -1108,11 +1707,11 @@ func (x *ListNodesRequest_Filter) GetIds() []string { return nil } -func (x *ListNodesRequest_Filter) GetArchived() ArchiveState { +func (x *ListNodesRequest_Filter) GetEnabled() EnableState { if x != nil { - return x.Archived + return x.Enabled } - return ArchiveState_ARCHIVE_STATE_UNSPECIFIED + return EnableState_ENABLE_STATE_UNSPECIFIED } func (x *ListNodesRequest_Filter) GetSelectors() []*ptypes.Selector { @@ -1127,13 +1726,13 @@ type ListNodeChainConfigsRequest_Filter struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` + NodeIds []string `protobuf:"bytes,1,rep,name=node_ids,json=nodeIds,proto3" json:"node_ids,omitempty"` } func (x *ListNodeChainConfigsRequest_Filter) Reset() { *x = ListNodeChainConfigsRequest_Filter{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[16] + mi := &file_node_v1_node_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1146,7 +1745,7 @@ func (x *ListNodeChainConfigsRequest_Filter) String() string { func (*ListNodeChainConfigsRequest_Filter) ProtoMessage() {} func (x *ListNodeChainConfigsRequest_Filter) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[16] + mi := &file_node_v1_node_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1159,14 +1758,14 @@ func (x *ListNodeChainConfigsRequest_Filter) ProtoReflect() protoreflect.Message // Deprecated: Use ListNodeChainConfigsRequest_Filter.ProtoReflect.Descriptor instead. func (*ListNodeChainConfigsRequest_Filter) Descriptor() ([]byte, []int) { - return file_node_v1_node_proto_rawDescGZIP(), []int{8, 0} + return file_node_v1_node_proto_rawDescGZIP(), []int{18, 0} } -func (x *ListNodeChainConfigsRequest_Filter) GetNodeId() string { +func (x *ListNodeChainConfigsRequest_Filter) GetNodeIds() []string { if x != nil { - return x.NodeId + return x.NodeIds } - return "" + return nil } var File_node_v1_node_proto protoreflect.FileDescriptor @@ -1176,30 +1775,90 @@ var file_node_v1_node_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x14, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x68, 0x61, 0x72, - 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, - 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0x43, 0x0a, 0x05, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x89, 0x04, 0x0a, 0x0a, 0x4f, 0x43, 0x52, - 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, - 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x42, 0x6f, 0x6f, 0x74, 0x73, - 0x74, 0x72, 0x61, 0x70, 0x12, 0x4a, 0x0a, 0x0e, 0x70, 0x32, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, - 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x31, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x32, 0x50, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x52, 0x0c, 0x70, 0x32, 0x70, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, - 0x12, 0x4a, 0x0a, 0x0e, 0x6f, 0x63, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, - 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x4f, 0x43, 0x52, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x0c, - 0x6f, 0x63, 0x72, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x1a, 0x46, 0x0a, 0x0c, 0x50, 0x32, + 0x74, 0x6f, 0x1a, 0x19, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xab, 0x02, + 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, + 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, + 0x69, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x43, 0x0a, 0x05, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x2d, 0x0a, 0x11, 0x46, 0x6c, 0x75, 0x78, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, + 0x89, 0x04, 0x0a, 0x0a, 0x4f, 0x43, 0x52, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, + 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x62, + 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, + 0x69, 0x73, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x12, 0x4a, 0x0a, 0x0e, 0x70, + 0x32, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x32, 0x50, + 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x0c, 0x70, 0x32, 0x70, 0x4b, 0x65, + 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x4a, 0x0a, 0x0e, 0x6f, 0x63, 0x72, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, + 0x52, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4f, 0x43, 0x52, 0x4b, 0x65, 0x79, 0x42, + 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x0c, 0x6f, 0x63, 0x72, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, + 0x72, 0x1a, 0x46, 0x0a, 0x0c, 0x50, 0x32, 0x50, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, + 0x65, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x1a, 0xbf, 0x01, 0x0a, 0x0c, 0x4f, 0x43, + 0x52, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x75, + 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, + 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x13, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x11, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x17, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, + 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x67, + 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x9c, 0x06, 0x0a, 0x0a, + 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, + 0x74, 0x72, 0x61, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x42, 0x6f, + 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x12, 0x4a, 0x0a, 0x0e, 0x70, 0x32, 0x70, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, + 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x32, 0x50, 0x4b, 0x65, 0x79, 0x42, + 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x0c, 0x70, 0x32, 0x70, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x12, 0x4a, 0x0a, 0x0e, 0x6f, 0x63, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, + 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4f, 0x43, 0x52, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, + 0x65, 0x52, 0x0c, 0x6f, 0x63, 0x72, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x12, 0x39, 0x0a, + 0x07, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, + 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x52, + 0x07, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x11, 0x66, 0x6f, 0x72, 0x77, + 0x61, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x10, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, 0x1a, 0x46, 0x0a, 0x0c, 0x50, 0x32, 0x50, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, @@ -1216,139 +1875,170 @@ var file_node_v1_node_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x22, 0x81, 0x06, 0x0a, 0x0a, 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, - 0x0c, 0x69, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, - 0x12, 0x4a, 0x0a, 0x0e, 0x70, 0x32, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, - 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x50, 0x32, 0x50, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x0c, - 0x70, 0x32, 0x70, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x4a, 0x0a, 0x0e, - 0x6f, 0x63, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4f, 0x43, - 0x52, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x0c, 0x6f, 0x63, 0x72, 0x4b, - 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, - 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x52, 0x07, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x66, 0x6f, - 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x1a, 0x46, - 0x0a, 0x0c, 0x50, 0x32, 0x50, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x17, - 0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x1a, 0xbf, 0x01, 0x0a, 0x0c, 0x4f, 0x43, 0x52, 0x4b, 0x65, - 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x75, 0x6e, 0x64, 0x6c, - 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, - 0x12, 0x2e, 0x0a, 0x13, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6f, - 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, - 0x12, 0x36, 0x0a, 0x17, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x6e, - 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x15, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, - 0x67, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x1a, 0x8d, 0x01, 0x0a, 0x07, 0x50, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, - 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x12, 0x18, - 0x0a, 0x07, 0x6d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x6d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x65, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x22, 0xf9, 0x01, 0x0a, 0x0b, 0x43, 0x68, 0x61, - 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, - 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, - 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x38, 0x0a, 0x0b, 0x6f, 0x63, 0x72, 0x31, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, - 0x6f, 0x63, 0x72, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x0b, 0x6f, 0x63, - 0x72, 0x32, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, - 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x6f, 0x63, 0x72, 0x32, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x22, 0x20, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x38, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x6e, 0x6f, 0x64, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, - 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, - 0x22, 0xd7, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x1a, 0x84, 0x01, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x10, - 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, - 0x12, 0x35, 0x0a, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x61, - 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x31, 0x0a, 0x09, 0x73, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, - 0x09, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x3c, 0x0a, 0x11, 0x4c, 0x69, - 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x27, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, - 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x89, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, - 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, - 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x1a, 0x21, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x6e, - 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, - 0x64, 0x65, 0x49, 0x64, 0x22, 0x5d, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, - 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x73, 0x2a, 0x52, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, - 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x56, 0x4d, 0x10, 0x01, - 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, - 0x4f, 0x4c, 0x41, 0x4e, 0x41, 0x10, 0x02, 0x2a, 0x63, 0x0a, 0x0c, 0x41, 0x72, 0x63, 0x68, 0x69, - 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x52, 0x43, 0x48, 0x49, - 0x56, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, - 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x44, - 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x32, 0x92, 0x02, 0x0a, - 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x07, - 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, - 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, - 0x73, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x68, - 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x28, 0x2e, 0x61, 0x70, 0x69, + 0x72, 0x65, 0x73, 0x73, 0x1a, 0x8d, 0x01, 0x0a, 0x07, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, + 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x72, 0x63, 0x75, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x65, 0x72, + 0x63, 0x75, 0x72, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x65, 0x72, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, + 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0xaa, 0x03, 0x0a, 0x0b, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a, 0x05, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, + 0x0d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x13, 0x66, 0x6c, 0x75, 0x78, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6c, + 0x75, 0x78, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x11, 0x66, 0x6c, 0x75, 0x78, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x38, 0x0a, 0x0b, 0x6f, 0x63, 0x72, 0x31, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x0a, 0x6f, 0x63, 0x72, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x0b, + 0x6f, 0x63, 0x72, 0x32, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x6f, 0x63, 0x72, 0x32, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x40, 0x0a, 0x1a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x17, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x88, 0x01, 0x01, 0x42, 0x1d, 0x0a, 0x1b, 0x5f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0x72, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x12, 0x28, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x22, 0x3d, 0x0a, 0x14, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x20, 0x0a, 0x0e, 0x47, 0x65, + 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x38, 0x0a, 0x0f, + 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x25, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, + 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0xd4, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4e, + 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, + 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x81, 0x01, 0x0a, 0x06, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x32, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x31, 0x0a, 0x09, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x52, 0x09, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x3c, 0x0a, + 0x11, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x80, 0x01, 0x0a, 0x11, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x22, 0x3b, + 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x24, 0x0a, 0x12, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x22, 0x3c, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22, + 0x23, 0x0a, 0x11, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x22, 0x3b, 0x0a, 0x12, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, + 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x6e, 0x6f, + 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, + 0x65, 0x22, 0x8b, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x68, + 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x47, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x23, 0x0a, 0x06, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x73, 0x22, + 0x5d, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3d, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x0c, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x2a, 0x6b, + 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x43, + 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x56, 0x4d, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, + 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4f, 0x4c, 0x41, 0x4e, 0x41, + 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x53, 0x54, 0x41, 0x52, 0x4b, 0x4e, 0x45, 0x54, 0x10, 0x03, 0x2a, 0x60, 0x0a, 0x0b, 0x45, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x4e, + 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x45, 0x4e, 0x41, 0x42, + 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, + 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x45, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x32, 0xdf, 0x04, + 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, + 0x0b, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1f, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x4f, 0x0a, 0x0a, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, + 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x46, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, + 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x4c, 0x69, + 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, + 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, + 0x12, 0x28, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, - 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x42, 0x09, 0x5a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, + 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, + 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1e, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, + 0x09, 0x5a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -1364,58 +2054,87 @@ func file_node_v1_node_proto_rawDescGZIP() []byte { } var file_node_v1_node_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 27) var file_node_v1_node_proto_goTypes = []interface{}{ (ChainType)(0), // 0: api.node.v1.ChainType - (ArchiveState)(0), // 1: api.node.v1.ArchiveState - (*Chain)(nil), // 2: api.node.v1.Chain - (*OCR1Config)(nil), // 3: api.node.v1.OCR1Config - (*OCR2Config)(nil), // 4: api.node.v1.OCR2Config - (*ChainConfig)(nil), // 5: api.node.v1.ChainConfig - (*GetNodeRequest)(nil), // 6: api.node.v1.GetNodeRequest - (*GetNodeResponse)(nil), // 7: api.node.v1.GetNodeResponse - (*ListNodesRequest)(nil), // 8: api.node.v1.ListNodesRequest - (*ListNodesResponse)(nil), // 9: api.node.v1.ListNodesResponse - (*ListNodeChainConfigsRequest)(nil), // 10: api.node.v1.ListNodeChainConfigsRequest - (*ListNodeChainConfigsResponse)(nil), // 11: api.node.v1.ListNodeChainConfigsResponse - (*OCR1Config_P2PKeyBundle)(nil), // 12: api.node.v1.OCR1Config.P2PKeyBundle - (*OCR1Config_OCRKeyBundle)(nil), // 13: api.node.v1.OCR1Config.OCRKeyBundle - (*OCR2Config_P2PKeyBundle)(nil), // 14: api.node.v1.OCR2Config.P2PKeyBundle - (*OCR2Config_OCRKeyBundle)(nil), // 15: api.node.v1.OCR2Config.OCRKeyBundle - (*OCR2Config_Plugins)(nil), // 16: api.node.v1.OCR2Config.Plugins - (*ListNodesRequest_Filter)(nil), // 17: api.node.v1.ListNodesRequest.Filter - (*ListNodeChainConfigsRequest_Filter)(nil), // 18: api.node.v1.ListNodeChainConfigsRequest.Filter - (*Node)(nil), // 19: api.node.v1.Node - (*ptypes.Selector)(nil), // 20: api.label.Selector + (EnableState)(0), // 1: api.node.v1.EnableState + (*Node)(nil), // 2: api.node.v1.Node + (*Chain)(nil), // 3: api.node.v1.Chain + (*FluxMonitorConfig)(nil), // 4: api.node.v1.FluxMonitorConfig + (*OCR1Config)(nil), // 5: api.node.v1.OCR1Config + (*OCR2Config)(nil), // 6: api.node.v1.OCR2Config + (*ChainConfig)(nil), // 7: api.node.v1.ChainConfig + (*RegisterNodeRequest)(nil), // 8: api.node.v1.RegisterNodeRequest + (*RegisterNodeResponse)(nil), // 9: api.node.v1.RegisterNodeResponse + (*GetNodeRequest)(nil), // 10: api.node.v1.GetNodeRequest + (*GetNodeResponse)(nil), // 11: api.node.v1.GetNodeResponse + (*ListNodesRequest)(nil), // 12: api.node.v1.ListNodesRequest + (*ListNodesResponse)(nil), // 13: api.node.v1.ListNodesResponse + (*UpdateNodeRequest)(nil), // 14: api.node.v1.UpdateNodeRequest + (*UpdateNodeResponse)(nil), // 15: api.node.v1.UpdateNodeResponse + (*DisableNodeRequest)(nil), // 16: api.node.v1.DisableNodeRequest + (*DisableNodeResponse)(nil), // 17: api.node.v1.DisableNodeResponse + (*EnableNodeRequest)(nil), // 18: api.node.v1.EnableNodeRequest + (*EnableNodeResponse)(nil), // 19: api.node.v1.EnableNodeResponse + (*ListNodeChainConfigsRequest)(nil), // 20: api.node.v1.ListNodeChainConfigsRequest + (*ListNodeChainConfigsResponse)(nil), // 21: api.node.v1.ListNodeChainConfigsResponse + (*OCR1Config_P2PKeyBundle)(nil), // 22: api.node.v1.OCR1Config.P2PKeyBundle + (*OCR1Config_OCRKeyBundle)(nil), // 23: api.node.v1.OCR1Config.OCRKeyBundle + (*OCR2Config_P2PKeyBundle)(nil), // 24: api.node.v1.OCR2Config.P2PKeyBundle + (*OCR2Config_OCRKeyBundle)(nil), // 25: api.node.v1.OCR2Config.OCRKeyBundle + (*OCR2Config_Plugins)(nil), // 26: api.node.v1.OCR2Config.Plugins + (*ListNodesRequest_Filter)(nil), // 27: api.node.v1.ListNodesRequest.Filter + (*ListNodeChainConfigsRequest_Filter)(nil), // 28: api.node.v1.ListNodeChainConfigsRequest.Filter + (*ptypes.Label)(nil), // 29: api.label.Label + (*timestamppb.Timestamp)(nil), // 30: google.protobuf.Timestamp + (*ptypes.Selector)(nil), // 31: api.label.Selector } var file_node_v1_node_proto_depIdxs = []int32{ - 0, // 0: api.node.v1.Chain.type:type_name -> api.node.v1.ChainType - 12, // 1: api.node.v1.OCR1Config.p2p_key_bundle:type_name -> api.node.v1.OCR1Config.P2PKeyBundle - 13, // 2: api.node.v1.OCR1Config.ocr_key_bundle:type_name -> api.node.v1.OCR1Config.OCRKeyBundle - 14, // 3: api.node.v1.OCR2Config.p2p_key_bundle:type_name -> api.node.v1.OCR2Config.P2PKeyBundle - 15, // 4: api.node.v1.OCR2Config.ocr_key_bundle:type_name -> api.node.v1.OCR2Config.OCRKeyBundle - 16, // 5: api.node.v1.OCR2Config.plugins:type_name -> api.node.v1.OCR2Config.Plugins - 2, // 6: api.node.v1.ChainConfig.chain:type_name -> api.node.v1.Chain - 3, // 7: api.node.v1.ChainConfig.ocr1_config:type_name -> api.node.v1.OCR1Config - 4, // 8: api.node.v1.ChainConfig.ocr2_config:type_name -> api.node.v1.OCR2Config - 19, // 9: api.node.v1.GetNodeResponse.node:type_name -> api.node.v1.Node - 17, // 10: api.node.v1.ListNodesRequest.filter:type_name -> api.node.v1.ListNodesRequest.Filter - 19, // 11: api.node.v1.ListNodesResponse.nodes:type_name -> api.node.v1.Node - 18, // 12: api.node.v1.ListNodeChainConfigsRequest.filter:type_name -> api.node.v1.ListNodeChainConfigsRequest.Filter - 5, // 13: api.node.v1.ListNodeChainConfigsResponse.chain_configs:type_name -> api.node.v1.ChainConfig - 1, // 14: api.node.v1.ListNodesRequest.Filter.archived:type_name -> api.node.v1.ArchiveState - 20, // 15: api.node.v1.ListNodesRequest.Filter.selectors:type_name -> api.label.Selector - 6, // 16: api.node.v1.NodeService.GetNode:input_type -> api.node.v1.GetNodeRequest - 8, // 17: api.node.v1.NodeService.ListNodes:input_type -> api.node.v1.ListNodesRequest - 10, // 18: api.node.v1.NodeService.ListNodeChainConfigs:input_type -> api.node.v1.ListNodeChainConfigsRequest - 7, // 19: api.node.v1.NodeService.GetNode:output_type -> api.node.v1.GetNodeResponse - 9, // 20: api.node.v1.NodeService.ListNodes:output_type -> api.node.v1.ListNodesResponse - 11, // 21: api.node.v1.NodeService.ListNodeChainConfigs:output_type -> api.node.v1.ListNodeChainConfigsResponse - 19, // [19:22] is the sub-list for method output_type - 16, // [16:19] is the sub-list for method input_type - 16, // [16:16] is the sub-list for extension type_name - 16, // [16:16] is the sub-list for extension extendee - 0, // [0:16] is the sub-list for field type_name + 29, // 0: api.node.v1.Node.labels:type_name -> api.label.Label + 30, // 1: api.node.v1.Node.created_at:type_name -> google.protobuf.Timestamp + 30, // 2: api.node.v1.Node.updated_at:type_name -> google.protobuf.Timestamp + 0, // 3: api.node.v1.Chain.type:type_name -> api.node.v1.ChainType + 22, // 4: api.node.v1.OCR1Config.p2p_key_bundle:type_name -> api.node.v1.OCR1Config.P2PKeyBundle + 23, // 5: api.node.v1.OCR1Config.ocr_key_bundle:type_name -> api.node.v1.OCR1Config.OCRKeyBundle + 24, // 6: api.node.v1.OCR2Config.p2p_key_bundle:type_name -> api.node.v1.OCR2Config.P2PKeyBundle + 25, // 7: api.node.v1.OCR2Config.ocr_key_bundle:type_name -> api.node.v1.OCR2Config.OCRKeyBundle + 26, // 8: api.node.v1.OCR2Config.plugins:type_name -> api.node.v1.OCR2Config.Plugins + 3, // 9: api.node.v1.ChainConfig.chain:type_name -> api.node.v1.Chain + 4, // 10: api.node.v1.ChainConfig.flux_monitor_config:type_name -> api.node.v1.FluxMonitorConfig + 5, // 11: api.node.v1.ChainConfig.ocr1_config:type_name -> api.node.v1.OCR1Config + 6, // 12: api.node.v1.ChainConfig.ocr2_config:type_name -> api.node.v1.OCR2Config + 29, // 13: api.node.v1.RegisterNodeRequest.labels:type_name -> api.label.Label + 2, // 14: api.node.v1.RegisterNodeResponse.node:type_name -> api.node.v1.Node + 2, // 15: api.node.v1.GetNodeResponse.node:type_name -> api.node.v1.Node + 27, // 16: api.node.v1.ListNodesRequest.filter:type_name -> api.node.v1.ListNodesRequest.Filter + 2, // 17: api.node.v1.ListNodesResponse.nodes:type_name -> api.node.v1.Node + 29, // 18: api.node.v1.UpdateNodeRequest.labels:type_name -> api.label.Label + 2, // 19: api.node.v1.UpdateNodeResponse.node:type_name -> api.node.v1.Node + 2, // 20: api.node.v1.DisableNodeResponse.node:type_name -> api.node.v1.Node + 2, // 21: api.node.v1.EnableNodeResponse.node:type_name -> api.node.v1.Node + 28, // 22: api.node.v1.ListNodeChainConfigsRequest.filter:type_name -> api.node.v1.ListNodeChainConfigsRequest.Filter + 7, // 23: api.node.v1.ListNodeChainConfigsResponse.chain_configs:type_name -> api.node.v1.ChainConfig + 1, // 24: api.node.v1.ListNodesRequest.Filter.enabled:type_name -> api.node.v1.EnableState + 31, // 25: api.node.v1.ListNodesRequest.Filter.selectors:type_name -> api.label.Selector + 16, // 26: api.node.v1.NodeService.DisableNode:input_type -> api.node.v1.DisableNodeRequest + 18, // 27: api.node.v1.NodeService.EnableNode:input_type -> api.node.v1.EnableNodeRequest + 10, // 28: api.node.v1.NodeService.GetNode:input_type -> api.node.v1.GetNodeRequest + 12, // 29: api.node.v1.NodeService.ListNodes:input_type -> api.node.v1.ListNodesRequest + 20, // 30: api.node.v1.NodeService.ListNodeChainConfigs:input_type -> api.node.v1.ListNodeChainConfigsRequest + 8, // 31: api.node.v1.NodeService.RegisterNode:input_type -> api.node.v1.RegisterNodeRequest + 14, // 32: api.node.v1.NodeService.UpdateNode:input_type -> api.node.v1.UpdateNodeRequest + 17, // 33: api.node.v1.NodeService.DisableNode:output_type -> api.node.v1.DisableNodeResponse + 19, // 34: api.node.v1.NodeService.EnableNode:output_type -> api.node.v1.EnableNodeResponse + 11, // 35: api.node.v1.NodeService.GetNode:output_type -> api.node.v1.GetNodeResponse + 13, // 36: api.node.v1.NodeService.ListNodes:output_type -> api.node.v1.ListNodesResponse + 21, // 37: api.node.v1.NodeService.ListNodeChainConfigs:output_type -> api.node.v1.ListNodeChainConfigsResponse + 9, // 38: api.node.v1.NodeService.RegisterNode:output_type -> api.node.v1.RegisterNodeResponse + 15, // 39: api.node.v1.NodeService.UpdateNode:output_type -> api.node.v1.UpdateNodeResponse + 33, // [33:40] is the sub-list for method output_type + 26, // [26:33] is the sub-list for method input_type + 26, // [26:26] is the sub-list for extension type_name + 26, // [26:26] is the sub-list for extension extendee + 0, // [0:26] is the sub-list for field type_name } func init() { file_node_v1_node_proto_init() } @@ -1423,10 +2142,9 @@ func file_node_v1_node_proto_init() { if File_node_v1_node_proto != nil { return } - file_node_v1_shared_proto_init() if !protoimpl.UnsafeEnabled { file_node_v1_node_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Chain); i { + switch v := v.(*Node); i { case 0: return &v.state case 1: @@ -1438,7 +2156,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OCR1Config); i { + switch v := v.(*Chain); i { case 0: return &v.state case 1: @@ -1450,7 +2168,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OCR2Config); i { + switch v := v.(*FluxMonitorConfig); i { case 0: return &v.state case 1: @@ -1462,7 +2180,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChainConfig); i { + switch v := v.(*OCR1Config); i { case 0: return &v.state case 1: @@ -1474,7 +2192,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetNodeRequest); i { + switch v := v.(*OCR2Config); i { case 0: return &v.state case 1: @@ -1486,7 +2204,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetNodeResponse); i { + switch v := v.(*ChainConfig); i { case 0: return &v.state case 1: @@ -1498,7 +2216,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListNodesRequest); i { + switch v := v.(*RegisterNodeRequest); i { case 0: return &v.state case 1: @@ -1510,7 +2228,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListNodesResponse); i { + switch v := v.(*RegisterNodeResponse); i { case 0: return &v.state case 1: @@ -1522,7 +2240,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListNodeChainConfigsRequest); i { + switch v := v.(*GetNodeRequest); i { case 0: return &v.state case 1: @@ -1534,7 +2252,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListNodeChainConfigsResponse); i { + switch v := v.(*GetNodeResponse); i { case 0: return &v.state case 1: @@ -1546,7 +2264,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OCR1Config_P2PKeyBundle); i { + switch v := v.(*ListNodesRequest); i { case 0: return &v.state case 1: @@ -1558,7 +2276,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OCR1Config_OCRKeyBundle); i { + switch v := v.(*ListNodesResponse); i { case 0: return &v.state case 1: @@ -1570,7 +2288,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OCR2Config_P2PKeyBundle); i { + switch v := v.(*UpdateNodeRequest); i { case 0: return &v.state case 1: @@ -1582,7 +2300,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OCR2Config_OCRKeyBundle); i { + switch v := v.(*UpdateNodeResponse); i { case 0: return &v.state case 1: @@ -1594,7 +2312,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OCR2Config_Plugins); i { + switch v := v.(*DisableNodeRequest); i { case 0: return &v.state case 1: @@ -1606,7 +2324,7 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListNodesRequest_Filter); i { + switch v := v.(*DisableNodeResponse); i { case 0: return &v.state case 1: @@ -1618,6 +2336,126 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnableNodeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnableNodeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNodeChainConfigsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNodeChainConfigsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCR1Config_P2PKeyBundle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCR1Config_OCRKeyBundle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCR2Config_P2PKeyBundle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCR2Config_OCRKeyBundle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCR2Config_Plugins); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListNodesRequest_Filter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListNodeChainConfigsRequest_Filter); i { case 0: return &v.state @@ -1630,13 +2468,15 @@ func file_node_v1_node_proto_init() { } } } + file_node_v1_node_proto_msgTypes[4].OneofWrappers = []interface{}{} + file_node_v1_node_proto_msgTypes[5].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_node_v1_node_proto_rawDesc, NumEnums: 2, - NumMessages: 17, + NumMessages: 27, NumExtensions: 0, NumServices: 1, }, @@ -1649,4 +2489,4 @@ func file_node_v1_node_proto_init() { file_node_v1_node_proto_rawDesc = nil file_node_v1_node_proto_goTypes = nil file_node_v1_node_proto_depIdxs = nil -} +} \ No newline at end of file diff --git a/integration-tests/deployment/jd/node/v1/node_grpc.pb.go b/integration-tests/deployment/jd/node/v1/node_grpc.pb.go index 5fc0c505ee..70010f3f0c 100644 --- a/integration-tests/deployment/jd/node/v1/node_grpc.pb.go +++ b/integration-tests/deployment/jd/node/v1/node_grpc.pb.go @@ -19,20 +19,32 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( + NodeService_DisableNode_FullMethodName = "/api.node.v1.NodeService/DisableNode" + NodeService_EnableNode_FullMethodName = "/api.node.v1.NodeService/EnableNode" NodeService_GetNode_FullMethodName = "/api.node.v1.NodeService/GetNode" NodeService_ListNodes_FullMethodName = "/api.node.v1.NodeService/ListNodes" NodeService_ListNodeChainConfigs_FullMethodName = "/api.node.v1.NodeService/ListNodeChainConfigs" + NodeService_RegisterNode_FullMethodName = "/api.node.v1.NodeService/RegisterNode" + NodeService_UpdateNode_FullMethodName = "/api.node.v1.NodeService/UpdateNode" ) // NodeServiceClient is the client API for NodeService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type NodeServiceClient interface { + // DisableNode marks a node as disabled, disabling any active operations on it. + DisableNode(ctx context.Context, in *DisableNodeRequest, opts ...grpc.CallOption) (*DisableNodeResponse, error) + // EnableNode enabled a disabled node, allowing operations to resume. + EnableNode(ctx context.Context, in *EnableNodeRequest, opts ...grpc.CallOption) (*EnableNodeResponse, error) // GetNode retrieves the details of a node by its unique identifier. GetNode(ctx context.Context, in *GetNodeRequest, opts ...grpc.CallOption) (*GetNodeResponse, error) // ListNodes returns a list of nodes, optionally filtered by the provided criteria. ListNodes(ctx context.Context, in *ListNodesRequest, opts ...grpc.CallOption) (*ListNodesResponse, error) ListNodeChainConfigs(ctx context.Context, in *ListNodeChainConfigsRequest, opts ...grpc.CallOption) (*ListNodeChainConfigsResponse, error) + // RegisterNode registers a new node to the system. + RegisterNode(ctx context.Context, in *RegisterNodeRequest, opts ...grpc.CallOption) (*RegisterNodeResponse, error) + // UpdateNode updates the details of an existing node. + UpdateNode(ctx context.Context, in *UpdateNodeRequest, opts ...grpc.CallOption) (*UpdateNodeResponse, error) } type nodeServiceClient struct { @@ -43,6 +55,24 @@ func NewNodeServiceClient(cc grpc.ClientConnInterface) NodeServiceClient { return &nodeServiceClient{cc} } +func (c *nodeServiceClient) DisableNode(ctx context.Context, in *DisableNodeRequest, opts ...grpc.CallOption) (*DisableNodeResponse, error) { + out := new(DisableNodeResponse) + err := c.cc.Invoke(ctx, NodeService_DisableNode_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nodeServiceClient) EnableNode(ctx context.Context, in *EnableNodeRequest, opts ...grpc.CallOption) (*EnableNodeResponse, error) { + out := new(EnableNodeResponse) + err := c.cc.Invoke(ctx, NodeService_EnableNode_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *nodeServiceClient) GetNode(ctx context.Context, in *GetNodeRequest, opts ...grpc.CallOption) (*GetNodeResponse, error) { out := new(GetNodeResponse) err := c.cc.Invoke(ctx, NodeService_GetNode_FullMethodName, in, out, opts...) @@ -70,15 +100,41 @@ func (c *nodeServiceClient) ListNodeChainConfigs(ctx context.Context, in *ListNo return out, nil } +func (c *nodeServiceClient) RegisterNode(ctx context.Context, in *RegisterNodeRequest, opts ...grpc.CallOption) (*RegisterNodeResponse, error) { + out := new(RegisterNodeResponse) + err := c.cc.Invoke(ctx, NodeService_RegisterNode_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nodeServiceClient) UpdateNode(ctx context.Context, in *UpdateNodeRequest, opts ...grpc.CallOption) (*UpdateNodeResponse, error) { + out := new(UpdateNodeResponse) + err := c.cc.Invoke(ctx, NodeService_UpdateNode_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // NodeServiceServer is the server API for NodeService service. // All implementations must embed UnimplementedNodeServiceServer // for forward compatibility type NodeServiceServer interface { + // DisableNode marks a node as disabled, disabling any active operations on it. + DisableNode(context.Context, *DisableNodeRequest) (*DisableNodeResponse, error) + // EnableNode enabled a disabled node, allowing operations to resume. + EnableNode(context.Context, *EnableNodeRequest) (*EnableNodeResponse, error) // GetNode retrieves the details of a node by its unique identifier. GetNode(context.Context, *GetNodeRequest) (*GetNodeResponse, error) // ListNodes returns a list of nodes, optionally filtered by the provided criteria. ListNodes(context.Context, *ListNodesRequest) (*ListNodesResponse, error) ListNodeChainConfigs(context.Context, *ListNodeChainConfigsRequest) (*ListNodeChainConfigsResponse, error) + // RegisterNode registers a new node to the system. + RegisterNode(context.Context, *RegisterNodeRequest) (*RegisterNodeResponse, error) + // UpdateNode updates the details of an existing node. + UpdateNode(context.Context, *UpdateNodeRequest) (*UpdateNodeResponse, error) mustEmbedUnimplementedNodeServiceServer() } @@ -86,6 +142,12 @@ type NodeServiceServer interface { type UnimplementedNodeServiceServer struct { } +func (UnimplementedNodeServiceServer) DisableNode(context.Context, *DisableNodeRequest) (*DisableNodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DisableNode not implemented") +} +func (UnimplementedNodeServiceServer) EnableNode(context.Context, *EnableNodeRequest) (*EnableNodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method EnableNode not implemented") +} func (UnimplementedNodeServiceServer) GetNode(context.Context, *GetNodeRequest) (*GetNodeResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetNode not implemented") } @@ -95,6 +157,12 @@ func (UnimplementedNodeServiceServer) ListNodes(context.Context, *ListNodesReque func (UnimplementedNodeServiceServer) ListNodeChainConfigs(context.Context, *ListNodeChainConfigsRequest) (*ListNodeChainConfigsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListNodeChainConfigs not implemented") } +func (UnimplementedNodeServiceServer) RegisterNode(context.Context, *RegisterNodeRequest) (*RegisterNodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterNode not implemented") +} +func (UnimplementedNodeServiceServer) UpdateNode(context.Context, *UpdateNodeRequest) (*UpdateNodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateNode not implemented") +} func (UnimplementedNodeServiceServer) mustEmbedUnimplementedNodeServiceServer() {} // UnsafeNodeServiceServer may be embedded to opt out of forward compatibility for this service. @@ -108,6 +176,42 @@ func RegisterNodeServiceServer(s grpc.ServiceRegistrar, srv NodeServiceServer) { s.RegisterService(&NodeService_ServiceDesc, srv) } +func _NodeService_DisableNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DisableNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).DisableNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: NodeService_DisableNode_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).DisableNode(ctx, req.(*DisableNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NodeService_EnableNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EnableNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).EnableNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: NodeService_EnableNode_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).EnableNode(ctx, req.(*EnableNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _NodeService_GetNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetNodeRequest) if err := dec(in); err != nil { @@ -162,6 +266,42 @@ func _NodeService_ListNodeChainConfigs_Handler(srv interface{}, ctx context.Cont return interceptor(ctx, in, info, handler) } +func _NodeService_RegisterNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).RegisterNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: NodeService_RegisterNode_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).RegisterNode(ctx, req.(*RegisterNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NodeService_UpdateNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).UpdateNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: NodeService_UpdateNode_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).UpdateNode(ctx, req.(*UpdateNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + // NodeService_ServiceDesc is the grpc.ServiceDesc for NodeService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -169,6 +309,14 @@ var NodeService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "api.node.v1.NodeService", HandlerType: (*NodeServiceServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "DisableNode", + Handler: _NodeService_DisableNode_Handler, + }, + { + MethodName: "EnableNode", + Handler: _NodeService_EnableNode_Handler, + }, { MethodName: "GetNode", Handler: _NodeService_GetNode_Handler, @@ -181,7 +329,15 @@ var NodeService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListNodeChainConfigs", Handler: _NodeService_ListNodeChainConfigs_Handler, }, + { + MethodName: "RegisterNode", + Handler: _NodeService_RegisterNode_Handler, + }, + { + MethodName: "UpdateNode", + Handler: _NodeService_UpdateNode_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "node/v1/node.proto", -} +} \ No newline at end of file diff --git a/integration-tests/deployment/jd/node/v1/shared.pb.go b/integration-tests/deployment/jd/node/v1/shared.pb.go deleted file mode 100644 index 4099dd6bd7..0000000000 --- a/integration-tests/deployment/jd/node/v1/shared.pb.go +++ /dev/null @@ -1,239 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.29.0 -// protoc v4.25.3 -// source: node/v1/shared.proto - -package v1 - -import ( - "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/shared/ptypes" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Node represents a node within the Job Distributor system. -type Node struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique identifier for the node. - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // Human-readable name for the node. - PublicKey string `protobuf:"bytes,3,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` // Public key used for secure communications. - IsEnabled bool `protobuf:"varint,4,opt,name=is_enabled,json=isEnabled,proto3" json:"is_enabled,omitempty"` // Indicates if the node is currently enabled. - IsConnected bool `protobuf:"varint,5,opt,name=is_connected,json=isConnected,proto3" json:"is_connected,omitempty"` // Indicates if the node is currently connected to the network. - Labels []*ptypes.Label `protobuf:"bytes,6,rep,name=labels,proto3" json:"labels,omitempty"` // Set of labels associated with the node. - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Timestamp when the node was created. - UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // Timestamp when the node was last updated. - ArchivedAt *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=archived_at,json=archivedAt,proto3" json:"archived_at,omitempty"` // Timestamp when the node was archived. -} - -func (x *Node) Reset() { - *x = Node{} - if protoimpl.UnsafeEnabled { - mi := &file_node_v1_shared_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Node) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Node) ProtoMessage() {} - -func (x *Node) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_shared_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Node.ProtoReflect.Descriptor instead. -func (*Node) Descriptor() ([]byte, []int) { - return file_node_v1_shared_proto_rawDescGZIP(), []int{0} -} - -func (x *Node) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Node) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Node) GetPublicKey() string { - if x != nil { - return x.PublicKey - } - return "" -} - -func (x *Node) GetIsEnabled() bool { - if x != nil { - return x.IsEnabled - } - return false -} - -func (x *Node) GetIsConnected() bool { - if x != nil { - return x.IsConnected - } - return false -} - -func (x *Node) GetLabels() []*ptypes.Label { - if x != nil { - return x.Labels - } - return nil -} - -func (x *Node) GetCreatedAt() *timestamppb.Timestamp { - if x != nil { - return x.CreatedAt - } - return nil -} - -func (x *Node) GetUpdatedAt() *timestamppb.Timestamp { - if x != nil { - return x.UpdatedAt - } - return nil -} - -func (x *Node) GetArchivedAt() *timestamppb.Timestamp { - if x != nil { - return x.ArchivedAt - } - return nil -} - -var File_node_v1_shared_proto protoreflect.FileDescriptor - -var file_node_v1_shared_proto_rawDesc = []byte{ - 0x0a, 0x14, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x61, 0x70, 0x69, 0x2e, 0x6e, 0x6f, 0x64, 0x65, - 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0xe8, 0x02, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x69, - 0x73, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x69, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, - 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0b, 0x69, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x28, 0x0a, - 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, - 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3b, 0x0a, - 0x0b, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, - 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x42, 0x09, 0x5a, 0x07, 0x6e, 0x6f, - 0x64, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_node_v1_shared_proto_rawDescOnce sync.Once - file_node_v1_shared_proto_rawDescData = file_node_v1_shared_proto_rawDesc -) - -func file_node_v1_shared_proto_rawDescGZIP() []byte { - file_node_v1_shared_proto_rawDescOnce.Do(func() { - file_node_v1_shared_proto_rawDescData = protoimpl.X.CompressGZIP(file_node_v1_shared_proto_rawDescData) - }) - return file_node_v1_shared_proto_rawDescData -} - -var file_node_v1_shared_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_node_v1_shared_proto_goTypes = []interface{}{ - (*Node)(nil), // 0: api.node.v1.Node - (*ptypes.Label)(nil), // 1: api.label.Label - (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp -} -var file_node_v1_shared_proto_depIdxs = []int32{ - 1, // 0: api.node.v1.Node.labels:type_name -> api.label.Label - 2, // 1: api.node.v1.Node.created_at:type_name -> google.protobuf.Timestamp - 2, // 2: api.node.v1.Node.updated_at:type_name -> google.protobuf.Timestamp - 2, // 3: api.node.v1.Node.archived_at:type_name -> google.protobuf.Timestamp - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name -} - -func init() { file_node_v1_shared_proto_init() } -func file_node_v1_shared_proto_init() { - if File_node_v1_shared_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_node_v1_shared_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Node); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_node_v1_shared_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_node_v1_shared_proto_goTypes, - DependencyIndexes: file_node_v1_shared_proto_depIdxs, - MessageInfos: file_node_v1_shared_proto_msgTypes, - }.Build() - File_node_v1_shared_proto = out.File - file_node_v1_shared_proto_rawDesc = nil - file_node_v1_shared_proto_goTypes = nil - file_node_v1_shared_proto_depIdxs = nil -} diff --git a/integration-tests/deployment/jd/shared/ptypes/label.pb.go b/integration-tests/deployment/jd/shared/ptypes/label.pb.go index e8195bd6c3..ab8f0db54c 100644 --- a/integration-tests/deployment/jd/shared/ptypes/label.pb.go +++ b/integration-tests/deployment/jd/shared/ptypes/label.pb.go @@ -308,4 +308,4 @@ func file_shared_ptypes_label_proto_init() { file_shared_ptypes_label_proto_rawDesc = nil file_shared_ptypes_label_proto_goTypes = nil file_shared_ptypes_label_proto_depIdxs = nil -} +} \ No newline at end of file diff --git a/integration-tests/deployment/memory/environment.go b/integration-tests/deployment/memory/environment.go index d496d173c0..fcccdca373 100644 --- a/integration-tests/deployment/memory/environment.go +++ b/integration-tests/deployment/memory/environment.go @@ -39,7 +39,7 @@ func NewMemoryChains(t *testing.T, numChains int) map[uint64]deployment.Chain { Selector: sel, Client: chain.Backend, DeployerKey: chain.DeployerKey, - Confirm: func(tx common.Hash) error { + Confirm: func(tx common.Hash) (uint64, error) { for { chain.Backend.Commit() receipt, err := chain.Backend.TransactionReceipt(context.Background(), tx) @@ -50,7 +50,7 @@ func NewMemoryChains(t *testing.T, numChains int) map[uint64]deployment.Chain { if receipt.Status == 0 { t.Logf("Status (reverted) %d for txhash %s\n", receipt.Status, tx.String()) } - return nil + return receipt.BlockNumber.Uint64(), nil } }, } @@ -71,15 +71,18 @@ func NewNodes(t *testing.T, logLevel zapcore.Level, chains map[uint64]deployment } } nodesByPeerID := make(map[string]Node) - ports := freeport.GetN(t, numNodes) - var existingNumBootstraps int + ports := freeport.GetN(t, numBootstraps+numNodes) + // bootstrap nodes must be separate nodes from plugin nodes, + // since we won't run a bootstrapper and a plugin oracle on the same + // chainlink node in production. + for i := 0; i < numBootstraps; i++ { + node := NewNode(t, ports[i], mchains, logLevel, true /* bootstrap */, registryConfig) + nodesByPeerID[node.Keys.PeerID.String()] = *node + // Note in real env, this ID is allocated by JD. + } for i := 0; i < numNodes; i++ { - bootstrap := false - if existingNumBootstraps < numBootstraps { - bootstrap = true - existingNumBootstraps++ - } - node := NewNode(t, ports[i], mchains, logLevel, bootstrap, registryConfig) + // grab port offset by numBootstraps, since above loop also takes some ports. + node := NewNode(t, ports[numBootstraps+i], mchains, logLevel, false /* bootstrap */, registryConfig) nodesByPeerID[node.Keys.PeerID.String()] = *node // Note in real env, this ID is allocated by JD. } diff --git a/integration-tests/deployment/memory/job_client.go b/integration-tests/deployment/memory/job_client.go index a9e837eab2..25fec711d8 100644 --- a/integration-tests/deployment/memory/job_client.go +++ b/integration-tests/deployment/memory/job_client.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "google.golang.org/grpc" + csav1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/csa/v1" jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" @@ -16,18 +17,53 @@ type JobClient struct { Nodes map[string]Node } -func (j JobClient) GetNode(ctx context.Context, in *nodev1.GetNodeRequest, opts ...grpc.CallOption) (*nodev1.GetNodeResponse, error) { +func (j JobClient) UpdateJob(ctx context.Context, in *jobv1.UpdateJobRequest, opts ...grpc.CallOption) (*jobv1.UpdateJobResponse, error) { + //TODO CCIP-3108 implement me + panic("implement me") +} + +func (j JobClient) DisableNode(ctx context.Context, in *nodev1.DisableNodeRequest, opts ...grpc.CallOption) (*nodev1.DisableNodeResponse, error) { + //TODO CCIP-3108 implement me + panic("implement me") +} + +func (j JobClient) EnableNode(ctx context.Context, in *nodev1.EnableNodeRequest, opts ...grpc.CallOption) (*nodev1.EnableNodeResponse, error) { + //TODO CCIP-3108 implement me + panic("implement me") +} + +func (j JobClient) RegisterNode(ctx context.Context, in *nodev1.RegisterNodeRequest, opts ...grpc.CallOption) (*nodev1.RegisterNodeResponse, error) { //TODO implement me panic("implement me") } -func (j JobClient) ListNodes(ctx context.Context, in *nodev1.ListNodesRequest, opts ...grpc.CallOption) (*nodev1.ListNodesResponse, error) { +func (j JobClient) UpdateNode(ctx context.Context, in *nodev1.UpdateNodeRequest, opts ...grpc.CallOption) (*nodev1.UpdateNodeResponse, error) { + //TODO CCIP-3108 implement me + panic("implement me") +} + +func (j JobClient) GetKeypair(ctx context.Context, in *csav1.GetKeypairRequest, opts ...grpc.CallOption) (*csav1.GetKeypairResponse, error) { //TODO implement me panic("implement me") } +func (j JobClient) ListKeypairs(ctx context.Context, in *csav1.ListKeypairsRequest, opts ...grpc.CallOption) (*csav1.ListKeypairsResponse, error) { + //TODO CCIP-3108 implement me + panic("implement me") +} + +func (j JobClient) GetNode(ctx context.Context, in *nodev1.GetNodeRequest, opts ...grpc.CallOption) (*nodev1.GetNodeResponse, error) { + //TODO CCIP-3108 implement me + panic("implement me") +} + +func (j JobClient) ListNodes(ctx context.Context, in *nodev1.ListNodesRequest, opts ...grpc.CallOption) (*nodev1.ListNodesResponse, error) { + //TODO CCIP-3108 implement me + panic("implement me") +} + func (j JobClient) ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNodeChainConfigsRequest, opts ...grpc.CallOption) (*nodev1.ListNodeChainConfigsResponse, error) { - n := j.Nodes[in.Filter.NodeId] + n := j.Nodes[in.Filter.NodeIds[0]] offpk := n.Keys.OCRKeyBundle.OffchainPublicKey() cpk := n.Keys.OCRKeyBundle.ConfigEncryptionPublicKey() var chainConfigs []*nodev1.ChainConfig @@ -54,7 +90,7 @@ func (j JobClient) ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNode }, Multiaddr: n.Addr.String(), Plugins: nil, - ForwarderAddress: "", + ForwarderAddress: ptr(""), }, }) } @@ -66,22 +102,22 @@ func (j JobClient) ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNode } func (j JobClient) GetJob(ctx context.Context, in *jobv1.GetJobRequest, opts ...grpc.CallOption) (*jobv1.GetJobResponse, error) { - //TODO implement me + //TODO CCIP-3108 implement me panic("implement me") } func (j JobClient) GetProposal(ctx context.Context, in *jobv1.GetProposalRequest, opts ...grpc.CallOption) (*jobv1.GetProposalResponse, error) { - //TODO implement me + //TODO CCIP-3108 implement me panic("implement me") } func (j JobClient) ListJobs(ctx context.Context, in *jobv1.ListJobsRequest, opts ...grpc.CallOption) (*jobv1.ListJobsResponse, error) { - //TODO implement me + //TODO CCIP-3108 implement me panic("implement me") } func (j JobClient) ListProposals(ctx context.Context, in *jobv1.ListProposalsRequest, opts ...grpc.CallOption) (*jobv1.ListProposalsResponse, error) { - //TODO implement me + //TODO CCIP-3108 implement me panic("implement me") } @@ -97,8 +133,7 @@ func (j JobClient) ProposeJob(ctx context.Context, in *jobv1.ProposeJobRequest, return nil, err } return &jobv1.ProposeJobResponse{Proposal: &jobv1.Proposal{ - Id: "", - Version: 0, + Id: "", // Auto approve for now Status: jobv1.ProposalStatus_PROPOSAL_STATUS_APPROVED, DeliveryStatus: jobv1.ProposalDeliveryStatus_PROPOSAL_DELIVERY_STATUS_DELIVERED, @@ -112,12 +147,12 @@ func (j JobClient) ProposeJob(ctx context.Context, in *jobv1.ProposeJobRequest, } func (j JobClient) RevokeJob(ctx context.Context, in *jobv1.RevokeJobRequest, opts ...grpc.CallOption) (*jobv1.RevokeJobResponse, error) { - //TODO implement me + //TODO CCIP-3108 implement me panic("implement me") } func (j JobClient) DeleteJob(ctx context.Context, in *jobv1.DeleteJobRequest, opts ...grpc.CallOption) (*jobv1.DeleteJobResponse, error) { - //TODO implement me + //TODO CCIP-3108 implement me panic("implement me") } diff --git a/integration-tests/deployment/memory/node.go b/integration-tests/deployment/memory/node.go index 8dfba05874..d062877121 100644 --- a/integration-tests/deployment/memory/node.go +++ b/integration-tests/deployment/memory/node.go @@ -13,14 +13,15 @@ import ( "github.com/ethereum/go-ethereum/common" gethtypes "github.com/ethereum/go-ethereum/core/types" chainsel "github.com/smartcontractkit/chain-selectors" - "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" + coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core/mocks" + "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - evmcapabilities "github.com/smartcontractkit/chainlink/v2/core/capabilities" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" v2toml "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -168,7 +169,7 @@ func NewNode( Logger: lggr, LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), cfg.Tracing()), GRPCOpts: loop.GRPCOpts{}, - CapabilitiesRegistry: evmcapabilities.NewRegistry(lggr), + CapabilitiesRegistry: coretypes.NewCapabilitiesRegistry(t), } initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitEVM(context.Background(), relayerFactory, evmOpts)} rci, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 1026c72018..37ddf694bf 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -36,6 +36,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 github.com/smartcontractkit/chainlink-testing-framework v1.35.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 @@ -403,7 +404,6 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/integration-tests/web/sdk/client/client.go b/integration-tests/web/sdk/client/client.go index 454e18a234..74be13562e 100644 --- a/integration-tests/web/sdk/client/client.go +++ b/integration-tests/web/sdk/client/client.go @@ -9,7 +9,7 @@ import ( "github.com/Khan/genqlient/graphql" - "github.com/smartcontractkit/chainlink/integration-tests/web/sdk/client/internal/doer" + "github.com/smartcontractkit/chainlink/integration-tests/web/sdk/client/doer" "github.com/smartcontractkit/chainlink/integration-tests/web/sdk/internal/generated" ) @@ -19,10 +19,11 @@ type Client interface { ListJobs(ctx context.Context, offset, limit int) (*generated.ListJobsResponse, error) GetBridge(ctx context.Context, id string) (*generated.GetBridgeResponse, error) ListBridges(ctx context.Context, offset, limit int) (*generated.ListBridgesResponse, error) - GetFeedsManager(ctx context.Context, id string) (*generated.GetFeedsManagerResponse, error) - ListFeedsManagers(ctx context.Context) (*generated.ListFeedsManagersResponse, error) - CreateFeedsManager(ctx context.Context, cmd generated.CreateFeedsManagerInput) (*generated.CreateFeedsManagerResponse, error) - UpdateFeedsManager(ctx context.Context, id string, cmd generated.UpdateFeedsManagerInput) (*generated.UpdateFeedsManagerResponse, error) + GetJobDistributor(ctx context.Context, id string) (*generated.GetFeedsManagerResponse, error) + ListJobDistributors(ctx context.Context) (*generated.ListFeedsManagersResponse, error) + CreateJobDistributor(ctx context.Context, cmd FeedsManagerInput) error + UpdateJobDistributor(ctx context.Context, id string, cmd FeedsManagerInput) error + CreateJobDistributorChainConfig(ctx context.Context, in CreateFeedsManagerChainConfigInput) error GetJobProposal(ctx context.Context, id string) (*generated.GetJobProposalResponse, error) ApproveJobProposalSpec(ctx context.Context, id string, force bool) (*generated.ApproveJobProposalSpecResponse, error) CancelJobProposalSpec(ctx context.Context, id string) (*generated.CancelJobProposalSpecResponse, error) @@ -89,20 +90,42 @@ func (c *client) ListBridges(ctx context.Context, offset, limit int) (*generated return generated.ListBridges(ctx, c.gqlClient, offset, limit) } -func (c *client) GetFeedsManager(ctx context.Context, id string) (*generated.GetFeedsManagerResponse, error) { +func (c *client) GetJobDistributor(ctx context.Context, id string) (*generated.GetFeedsManagerResponse, error) { return generated.GetFeedsManager(ctx, c.gqlClient, id) } -func (c *client) ListFeedsManagers(ctx context.Context) (*generated.ListFeedsManagersResponse, error) { +func (c *client) ListJobDistributors(ctx context.Context) (*generated.ListFeedsManagersResponse, error) { return generated.ListFeedsManagers(ctx, c.gqlClient) } -func (c *client) CreateFeedsManager(ctx context.Context, cmd generated.CreateFeedsManagerInput) (*generated.CreateFeedsManagerResponse, error) { - return generated.CreateFeedsManager(ctx, c.gqlClient, cmd) +func (c *client) CreateJobDistributor(ctx context.Context, in FeedsManagerInput) error { + var cmd generated.CreateFeedsManagerInput + err := DecodeInput(in, &cmd) + if err != nil { + return err + } + _, err = generated.CreateFeedsManager(ctx, c.gqlClient, cmd) + return err } -func (c *client) UpdateFeedsManager(ctx context.Context, id string, cmd generated.UpdateFeedsManagerInput) (*generated.UpdateFeedsManagerResponse, error) { - return generated.UpdateFeedsManager(ctx, c.gqlClient, id, cmd) +func (c *client) UpdateJobDistributor(ctx context.Context, id string, in FeedsManagerInput) error { + var cmd generated.UpdateFeedsManagerInput + err := DecodeInput(in, &cmd) + if err != nil { + return err + } + _, err = generated.UpdateFeedsManager(ctx, c.gqlClient, id, cmd) + return err +} + +func (c *client) CreateJobDistributorChainConfig(ctx context.Context, in CreateFeedsManagerChainConfigInput) error { + var cmd generated.CreateFeedsManagerChainConfigInput + err := DecodeInput(in, &cmd) + if err != nil { + return err + } + _, err = generated.CreateFeedsManagerChainConfig(ctx, c.gqlClient, cmd) + return err } func (c *client) GetJobProposal(ctx context.Context, id string) (*generated.GetJobProposalResponse, error) { diff --git a/integration-tests/web/sdk/client/internal/doer/doer.go b/integration-tests/web/sdk/client/doer/doer.go similarity index 100% rename from integration-tests/web/sdk/client/internal/doer/doer.go rename to integration-tests/web/sdk/client/doer/doer.go diff --git a/integration-tests/web/sdk/client/types.go b/integration-tests/web/sdk/client/types.go new file mode 100644 index 0000000000..49330ee621 --- /dev/null +++ b/integration-tests/web/sdk/client/types.go @@ -0,0 +1,50 @@ +package client + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" +) + +type FeedsManagerInput struct { + Name string `json:"name"` + Uri string `json:"uri"` + PublicKey string `json:"publicKey"` +} + +type CreateFeedsManagerChainConfigInput struct { + FeedsManagerID string `json:"feedsManagerID"` + ChainID string `json:"chainID"` + ChainType string `json:"chainType"` + AccountAddr string `json:"accountAddr"` + AccountAddrPubKey string `json:"accountAddrPubKey"` + AdminAddr string `json:"adminAddr"` + FluxMonitorEnabled bool `json:"fluxMonitorEnabled"` + Ocr1Enabled bool `json:"ocr1Enabled"` + Ocr1IsBootstrap bool `json:"ocr1IsBootstrap"` + Ocr1Multiaddr string `json:"ocr1Multiaddr"` + Ocr1P2PPeerID string `json:"ocr1P2PPeerID"` + Ocr1KeyBundleID string `json:"ocr1KeyBundleID"` + Ocr2Enabled bool `json:"ocr2Enabled"` + Ocr2IsBootstrap bool `json:"ocr2IsBootstrap"` + Ocr2Multiaddr string `json:"ocr2Multiaddr"` + Ocr2ForwarderAddress string `json:"ocr2ForwarderAddress"` + Ocr2P2PPeerID string `json:"ocr2P2PPeerID"` + Ocr2KeyBundleID string `json:"ocr2KeyBundleID"` + Ocr2Plugins string `json:"ocr2Plugins"` +} + +func DecodeInput(in, out any) error { + if reflect.TypeOf(out).Kind() != reflect.Ptr || reflect.ValueOf(out).IsNil() { + return fmt.Errorf("out type must be a non-nil pointer") + } + jsonBytes, err := json.Marshal(in) + if err != nil { + return err + } + + decoder := json.NewDecoder(bytes.NewReader(jsonBytes)) + decoder.DisallowUnknownFields() + return decoder.Decode(out) +} diff --git a/integration-tests/web/sdk/client/types_test.go b/integration-tests/web/sdk/client/types_test.go new file mode 100644 index 0000000000..f67cb09954 --- /dev/null +++ b/integration-tests/web/sdk/client/types_test.go @@ -0,0 +1,67 @@ +package client + +import ( + "testing" + + "github.com/smartcontractkit/chainlink/integration-tests/web/sdk/internal/generated" +) + +func TestDecodeInput(t *testing.T) { + type args struct { + in any + out any + } + tests := []struct { + name string + args args + wantErr bool + errMessage string + }{ + { + name: "success", + args: args{&FeedsManagerInput{ + Name: "name", + Uri: "uri", + PublicKey: "publicKey", + }, &generated.CreateFeedsManagerInput{}}, + wantErr: false, + errMessage: "", + }, + { + name: "non-pointer", + args: args{&FeedsManagerInput{ + Name: "name", + Uri: "uri", + PublicKey: "publicKey", + }, generated.CreateFeedsManagerInput{}}, + wantErr: true, + errMessage: "out type must be a non-nil pointer", + }, + { + name: "incorrect type", + args: args{&FeedsManagerInput{ + Name: "name", + Uri: "uri", + PublicKey: "publicKey", + }, generated.CreateFeedsManagerChainConfigInput{}}, + wantErr: true, + errMessage: "json: cannot unmarshal object into Go value of type generated.CreateFeedsManagerChainConfigInput", + }, + { + name: "success", + args: args{&FeedsManagerInput{ + Name: "name", + Uri: "uri", + PublicKey: "publicKey", + }, &generated.UpdateFeedsManagerInput{}}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := DecodeInput(tt.args.in, tt.args.out); (err != nil) != tt.wantErr { + t.Errorf("DecodeInput() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/integration-tests/web/sdk/internal/generated/generated.go b/integration-tests/web/sdk/internal/generated/generated.go index 6fada0aaa0..b70fc15614 100644 --- a/integration-tests/web/sdk/internal/generated/generated.go +++ b/integration-tests/web/sdk/internal/generated/generated.go @@ -8,7 +8,6 @@ import ( "fmt" "github.com/Khan/genqlient/graphql" - "github.com/smartcontractkit/chainlink/v2/core/web/gqlscalar" ) @@ -538,6 +537,497 @@ func (v *CancelJobProposalSpecResponse) __premarshalJSON() (*__premarshalCancelJ return &retval, nil } +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload includes the requested fields of the GraphQL interface CreateFeedsManagerChainConfigPayload. +// +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload is implemented by the following types: +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccess +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrors +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError +type CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload interface { + implementsGraphQLInterfaceCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccess) implementsGraphQLInterfaceCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload() { +} +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrors) implementsGraphQLInterfaceCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload() { +} +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError) implementsGraphQLInterfaceCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload() { +} + +func __unmarshalCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload(b []byte, v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "CreateFeedsManagerChainConfigSuccess": + *v = new(CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccess) + return json.Unmarshal(b, *v) + case "InputErrors": + *v = new(CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrors) + return json.Unmarshal(b, *v) + case "NotFoundError": + *v = new(CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing CreateFeedsManagerChainConfigPayload.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload: "%v"`, tn.TypeName) + } +} + +func __marshalCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload(v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccess: + typename = "CreateFeedsManagerChainConfigSuccess" + + result := struct { + TypeName string `json:"__typename"` + *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccess + }{typename, v} + return json.Marshal(result) + case *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrors: + typename = "InputErrors" + + result := struct { + TypeName string `json:"__typename"` + *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrors + }{typename, v} + return json.Marshal(result) + case *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError: + typename = "NotFoundError" + + result := struct { + TypeName string `json:"__typename"` + *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload: "%T"`, v) + } +} + +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccess includes the requested fields of the GraphQL type CreateFeedsManagerChainConfigSuccess. +type CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccess struct { + Typename string `json:"__typename"` + ChainConfig CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig `json:"chainConfig"` +} + +// GetTypename returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccess.Typename, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccess) GetTypename() string { + return v.Typename +} + +// GetChainConfig returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccess.ChainConfig, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccess) GetChainConfig() CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig { + return v.ChainConfig +} + +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig includes the requested fields of the GraphQL type FeedsManagerChainConfig. +type CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig struct { + Id string `json:"id"` + ChainID string `json:"chainID"` + ChainType string `json:"chainType"` + AccountAddr string `json:"accountAddr"` + AdminAddr string `json:"adminAddr"` + FluxMonitorJobConfig CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigFluxMonitorJobConfig `json:"fluxMonitorJobConfig"` + Ocr1JobConfig CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig `json:"ocr1JobConfig"` + Ocr2JobConfig CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig `json:"ocr2JobConfig"` +} + +// GetId returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig.Id, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig) GetId() string { + return v.Id +} + +// GetChainID returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig.ChainID, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig) GetChainID() string { + return v.ChainID +} + +// GetChainType returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig.ChainType, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig) GetChainType() string { + return v.ChainType +} + +// GetAccountAddr returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig.AccountAddr, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig) GetAccountAddr() string { + return v.AccountAddr +} + +// GetAdminAddr returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig.AdminAddr, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig) GetAdminAddr() string { + return v.AdminAddr +} + +// GetFluxMonitorJobConfig returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig.FluxMonitorJobConfig, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig) GetFluxMonitorJobConfig() CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigFluxMonitorJobConfig { + return v.FluxMonitorJobConfig +} + +// GetOcr1JobConfig returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig.Ocr1JobConfig, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig) GetOcr1JobConfig() CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig { + return v.Ocr1JobConfig +} + +// GetOcr2JobConfig returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig.Ocr2JobConfig, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfig) GetOcr2JobConfig() CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig { + return v.Ocr2JobConfig +} + +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigFluxMonitorJobConfig includes the requested fields of the GraphQL type FluxMonitorJobConfig. +type CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigFluxMonitorJobConfig struct { + Enabled bool `json:"enabled"` +} + +// GetEnabled returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigFluxMonitorJobConfig.Enabled, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigFluxMonitorJobConfig) GetEnabled() bool { + return v.Enabled +} + +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig includes the requested fields of the GraphQL type OCR1JobConfig. +type CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig struct { + Enabled bool `json:"enabled"` + IsBootstrap bool `json:"isBootstrap"` + Multiaddr string `json:"multiaddr"` + P2pPeerID string `json:"p2pPeerID"` + KeyBundleID string `json:"keyBundleID"` +} + +// GetEnabled returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig.Enabled, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig) GetEnabled() bool { + return v.Enabled +} + +// GetIsBootstrap returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig.IsBootstrap, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig) GetIsBootstrap() bool { + return v.IsBootstrap +} + +// GetMultiaddr returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig.Multiaddr, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig) GetMultiaddr() string { + return v.Multiaddr +} + +// GetP2pPeerID returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig.P2pPeerID, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig) GetP2pPeerID() string { + return v.P2pPeerID +} + +// GetKeyBundleID returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig.KeyBundleID, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr1JobConfigOCR1JobConfig) GetKeyBundleID() string { + return v.KeyBundleID +} + +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig includes the requested fields of the GraphQL type OCR2JobConfig. +type CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig struct { + Enabled bool `json:"enabled"` + IsBootstrap bool `json:"isBootstrap"` + Multiaddr string `json:"multiaddr"` + ForwarderAddress string `json:"forwarderAddress"` + P2pPeerID string `json:"p2pPeerID"` + KeyBundleID string `json:"keyBundleID"` + Plugins CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins `json:"plugins"` +} + +// GetEnabled returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig.Enabled, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig) GetEnabled() bool { + return v.Enabled +} + +// GetIsBootstrap returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig.IsBootstrap, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig) GetIsBootstrap() bool { + return v.IsBootstrap +} + +// GetMultiaddr returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig.Multiaddr, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig) GetMultiaddr() string { + return v.Multiaddr +} + +// GetForwarderAddress returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig.ForwarderAddress, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig) GetForwarderAddress() string { + return v.ForwarderAddress +} + +// GetP2pPeerID returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig.P2pPeerID, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig) GetP2pPeerID() string { + return v.P2pPeerID +} + +// GetKeyBundleID returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig.KeyBundleID, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig) GetKeyBundleID() string { + return v.KeyBundleID +} + +// GetPlugins returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig.Plugins, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfig) GetPlugins() CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins { + return v.Plugins +} + +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins includes the requested fields of the GraphQL type Plugins. +type CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins struct { + Commit bool `json:"commit"` + Execute bool `json:"execute"` + Median bool `json:"median"` + Mercury bool `json:"mercury"` + Rebalancer bool `json:"rebalancer"` +} + +// GetCommit returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins.Commit, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins) GetCommit() bool { + return v.Commit +} + +// GetExecute returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins.Execute, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins) GetExecute() bool { + return v.Execute +} + +// GetMedian returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins.Median, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins) GetMedian() bool { + return v.Median +} + +// GetMercury returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins.Mercury, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins) GetMercury() bool { + return v.Mercury +} + +// GetRebalancer returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins.Rebalancer, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigSuccessChainConfigFeedsManagerChainConfigOcr2JobConfigOCR2JobConfigPlugins) GetRebalancer() bool { + return v.Rebalancer +} + +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrors includes the requested fields of the GraphQL type InputErrors. +type CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrors struct { + Typename string `json:"__typename"` + Errors []CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrorsErrorsInputError `json:"errors"` +} + +// GetTypename returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrors.Typename, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrors) GetTypename() string { + return v.Typename +} + +// GetErrors returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrors.Errors, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrors) GetErrors() []CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrorsErrorsInputError { + return v.Errors +} + +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrorsErrorsInputError includes the requested fields of the GraphQL type InputError. +type CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrorsErrorsInputError struct { + Message string `json:"message"` + Path string `json:"path"` +} + +// GetMessage returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrorsErrorsInputError.Message, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrorsErrorsInputError) GetMessage() string { + return v.Message +} + +// GetPath returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrorsErrorsInputError.Path, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigInputErrorsErrorsInputError) GetPath() string { + return v.Path +} + +// CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError includes the requested fields of the GraphQL type NotFoundError. +type CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError struct { + Typename string `json:"__typename"` + Message string `json:"message"` + Code ErrorCode `json:"code"` +} + +// GetTypename returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError.Typename, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError) GetTypename() string { + return v.Typename +} + +// GetMessage returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError.Message, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError) GetMessage() string { + return v.Message +} + +// GetCode returns CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError.Code, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigNotFoundError) GetCode() ErrorCode { + return v.Code +} + +type CreateFeedsManagerChainConfigInput struct { + FeedsManagerID string `json:"feedsManagerID"` + ChainID string `json:"chainID"` + ChainType string `json:"chainType"` + AccountAddr string `json:"accountAddr"` + AccountAddrPubKey string `json:"accountAddrPubKey"` + AdminAddr string `json:"adminAddr"` + FluxMonitorEnabled bool `json:"fluxMonitorEnabled"` + Ocr1Enabled bool `json:"ocr1Enabled"` + Ocr1IsBootstrap bool `json:"ocr1IsBootstrap"` + Ocr1Multiaddr string `json:"ocr1Multiaddr"` + Ocr1P2PPeerID string `json:"ocr1P2PPeerID"` + Ocr1KeyBundleID string `json:"ocr1KeyBundleID"` + Ocr2Enabled bool `json:"ocr2Enabled"` + Ocr2IsBootstrap bool `json:"ocr2IsBootstrap"` + Ocr2Multiaddr string `json:"ocr2Multiaddr"` + Ocr2ForwarderAddress string `json:"ocr2ForwarderAddress"` + Ocr2P2PPeerID string `json:"ocr2P2PPeerID"` + Ocr2KeyBundleID string `json:"ocr2KeyBundleID"` + Ocr2Plugins string `json:"ocr2Plugins"` +} + +// GetFeedsManagerID returns CreateFeedsManagerChainConfigInput.FeedsManagerID, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetFeedsManagerID() string { return v.FeedsManagerID } + +// GetChainID returns CreateFeedsManagerChainConfigInput.ChainID, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetChainID() string { return v.ChainID } + +// GetChainType returns CreateFeedsManagerChainConfigInput.ChainType, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetChainType() string { return v.ChainType } + +// GetAccountAddr returns CreateFeedsManagerChainConfigInput.AccountAddr, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetAccountAddr() string { return v.AccountAddr } + +// GetAccountAddrPubKey returns CreateFeedsManagerChainConfigInput.AccountAddrPubKey, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetAccountAddrPubKey() string { + return v.AccountAddrPubKey +} + +// GetAdminAddr returns CreateFeedsManagerChainConfigInput.AdminAddr, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetAdminAddr() string { return v.AdminAddr } + +// GetFluxMonitorEnabled returns CreateFeedsManagerChainConfigInput.FluxMonitorEnabled, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetFluxMonitorEnabled() bool { + return v.FluxMonitorEnabled +} + +// GetOcr1Enabled returns CreateFeedsManagerChainConfigInput.Ocr1Enabled, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetOcr1Enabled() bool { return v.Ocr1Enabled } + +// GetOcr1IsBootstrap returns CreateFeedsManagerChainConfigInput.Ocr1IsBootstrap, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetOcr1IsBootstrap() bool { return v.Ocr1IsBootstrap } + +// GetOcr1Multiaddr returns CreateFeedsManagerChainConfigInput.Ocr1Multiaddr, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetOcr1Multiaddr() string { return v.Ocr1Multiaddr } + +// GetOcr1P2PPeerID returns CreateFeedsManagerChainConfigInput.Ocr1P2PPeerID, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetOcr1P2PPeerID() string { return v.Ocr1P2PPeerID } + +// GetOcr1KeyBundleID returns CreateFeedsManagerChainConfigInput.Ocr1KeyBundleID, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetOcr1KeyBundleID() string { return v.Ocr1KeyBundleID } + +// GetOcr2Enabled returns CreateFeedsManagerChainConfigInput.Ocr2Enabled, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetOcr2Enabled() bool { return v.Ocr2Enabled } + +// GetOcr2IsBootstrap returns CreateFeedsManagerChainConfigInput.Ocr2IsBootstrap, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetOcr2IsBootstrap() bool { return v.Ocr2IsBootstrap } + +// GetOcr2Multiaddr returns CreateFeedsManagerChainConfigInput.Ocr2Multiaddr, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetOcr2Multiaddr() string { return v.Ocr2Multiaddr } + +// GetOcr2ForwarderAddress returns CreateFeedsManagerChainConfigInput.Ocr2ForwarderAddress, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetOcr2ForwarderAddress() string { + return v.Ocr2ForwarderAddress +} + +// GetOcr2P2PPeerID returns CreateFeedsManagerChainConfigInput.Ocr2P2PPeerID, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetOcr2P2PPeerID() string { return v.Ocr2P2PPeerID } + +// GetOcr2KeyBundleID returns CreateFeedsManagerChainConfigInput.Ocr2KeyBundleID, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetOcr2KeyBundleID() string { return v.Ocr2KeyBundleID } + +// GetOcr2Plugins returns CreateFeedsManagerChainConfigInput.Ocr2Plugins, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigInput) GetOcr2Plugins() string { return v.Ocr2Plugins } + +// CreateFeedsManagerChainConfigResponse is returned by CreateFeedsManagerChainConfig on success. +type CreateFeedsManagerChainConfigResponse struct { + CreateFeedsManagerChainConfig CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload `json:"-"` +} + +// GetCreateFeedsManagerChainConfig returns CreateFeedsManagerChainConfigResponse.CreateFeedsManagerChainConfig, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerChainConfigResponse) GetCreateFeedsManagerChainConfig() CreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload { + return v.CreateFeedsManagerChainConfig +} + +func (v *CreateFeedsManagerChainConfigResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CreateFeedsManagerChainConfigResponse + CreateFeedsManagerChainConfig json.RawMessage `json:"createFeedsManagerChainConfig"` + graphql.NoUnmarshalJSON + } + firstPass.CreateFeedsManagerChainConfigResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.CreateFeedsManagerChainConfig + src := firstPass.CreateFeedsManagerChainConfig + if len(src) != 0 && string(src) != "null" { + err = __unmarshalCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal CreateFeedsManagerChainConfigResponse.CreateFeedsManagerChainConfig: %w", err) + } + } + } + return nil +} + +type __premarshalCreateFeedsManagerChainConfigResponse struct { + CreateFeedsManagerChainConfig json.RawMessage `json:"createFeedsManagerChainConfig"` +} + +func (v *CreateFeedsManagerChainConfigResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CreateFeedsManagerChainConfigResponse) __premarshalJSON() (*__premarshalCreateFeedsManagerChainConfigResponse, error) { + var retval __premarshalCreateFeedsManagerChainConfigResponse + + { + + dst := &retval.CreateFeedsManagerChainConfig + src := v.CreateFeedsManagerChainConfig + var err error + *dst, err = __marshalCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigCreateFeedsManagerChainConfigPayload( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal CreateFeedsManagerChainConfigResponse.CreateFeedsManagerChainConfig: %w", err) + } + } + return &retval, nil +} + // CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload includes the requested fields of the GraphQL interface CreateFeedsManagerPayload. // // CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload is implemented by the following types: @@ -4115,6 +4605,16 @@ type __CancelJobProposalSpecInput struct { // GetId returns __CancelJobProposalSpecInput.Id, and is useful for accessing the field via an interface. func (v *__CancelJobProposalSpecInput) GetId() string { return v.Id } +// __CreateFeedsManagerChainConfigInput is used internally by genqlient +type __CreateFeedsManagerChainConfigInput struct { + Input CreateFeedsManagerChainConfigInput `json:"input"` +} + +// GetInput returns __CreateFeedsManagerChainConfigInput.Input, and is useful for accessing the field via an interface. +func (v *__CreateFeedsManagerChainConfigInput) GetInput() CreateFeedsManagerChainConfigInput { + return v.Input +} + // __CreateFeedsManagerInput is used internally by genqlient type __CreateFeedsManagerInput struct { Input CreateFeedsManagerInput `json:"input"` @@ -4382,6 +4882,86 @@ func CreateFeedsManager( return &data_, err_ } +// The query or mutation executed by CreateFeedsManagerChainConfig. +const CreateFeedsManagerChainConfig_Operation = ` +mutation CreateFeedsManagerChainConfig ($input: CreateFeedsManagerChainConfigInput!) { + createFeedsManagerChainConfig(input: $input) { + __typename + ... on CreateFeedsManagerChainConfigSuccess { + chainConfig { + id + chainID + chainType + accountAddr + adminAddr + fluxMonitorJobConfig { + enabled + } + ocr1JobConfig { + enabled + isBootstrap + multiaddr + p2pPeerID + keyBundleID + } + ocr2JobConfig { + enabled + isBootstrap + multiaddr + forwarderAddress + p2pPeerID + keyBundleID + plugins { + commit + execute + median + mercury + rebalancer + } + } + } + } + ... on NotFoundError { + message + code + } + ... on InputErrors { + errors { + message + path + } + } + } +} +` + +// createFeedsManagerChainConfig.graphql +func CreateFeedsManagerChainConfig( + ctx_ context.Context, + client_ graphql.Client, + input CreateFeedsManagerChainConfigInput, +) (*CreateFeedsManagerChainConfigResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateFeedsManagerChainConfig", + Query: CreateFeedsManagerChainConfig_Operation, + Variables: &__CreateFeedsManagerChainConfigInput{ + Input: input, + }, + } + var err_ error + + var data_ CreateFeedsManagerChainConfigResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + // The query or mutation executed by GetBridge. const GetBridge_Operation = ` query GetBridge ($id: ID!) { diff --git a/integration-tests/web/sdk/internal/genqlient.graphql b/integration-tests/web/sdk/internal/genqlient.graphql index f9e8fc1843..c6307f916a 100644 --- a/integration-tests/web/sdk/internal/genqlient.graphql +++ b/integration-tests/web/sdk/internal/genqlient.graphql @@ -228,6 +228,57 @@ mutation UpdateFeedsManager($id: ID!, $input: UpdateFeedsManagerInput!) { } } +# createFeedsManagerChainConfig.graphql +mutation CreateFeedsManagerChainConfig($input: CreateFeedsManagerChainConfigInput!) { + createFeedsManagerChainConfig(input: $input) { + ... on CreateFeedsManagerChainConfigSuccess { + chainConfig { + id + chainID + chainType + accountAddr + adminAddr + fluxMonitorJobConfig { + enabled + } + ocr1JobConfig { + enabled + isBootstrap + multiaddr + p2pPeerID + keyBundleID + } + ocr2JobConfig { + enabled + isBootstrap + multiaddr + forwarderAddress + p2pPeerID + keyBundleID + plugins { + commit + execute + median + mercury + rebalancer + } + } + } + } + ... on NotFoundError { + message + code + } + ... on InputErrors { + errors { + message + path + } + } + } +} + + ##################### # Job Proposals ##################### From 5cd03659b6fb7ddb2f16ab9f81267b4c3f22fc91 Mon Sep 17 00:00:00 2001 From: Makram Date: Mon, 2 Sep 2024 17:02:31 +0300 Subject: [PATCH 267/432] integration-tests/deployment/memory: faster lp interval (#14304) --- integration-tests/deployment/memory/node.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/deployment/memory/node.go b/integration-tests/deployment/memory/node.go index d062877121..2ca84ac6c5 100644 --- a/integration-tests/deployment/memory/node.go +++ b/integration-tests/deployment/memory/node.go @@ -256,7 +256,7 @@ func createConfigV2Chain(chainID uint64) *v2toml.EVMConfig { chainIDBig := evmutils.NewI(int64(chainID)) chain := v2toml.Defaults(chainIDBig) chain.GasEstimator.LimitDefault = ptr(uint64(5e6)) - chain.LogPollInterval = config.MustNewDuration(1000 * time.Millisecond) + chain.LogPollInterval = config.MustNewDuration(500 * time.Millisecond) chain.Transactions.ForwardersEnabled = ptr(false) chain.FinalityDepth = ptr(uint32(2)) return &v2toml.EVMConfig{ From c0223e04399d32e5f7cba7edb30e8e66d540a16d Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Mon, 2 Sep 2024 16:25:27 +0200 Subject: [PATCH 268/432] Update artifact name in URL search (#14306) --- .github/workflows/solidity-foundry-artifacts.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/solidity-foundry-artifacts.yml b/.github/workflows/solidity-foundry-artifacts.yml index 647ed33257..613272e091 100644 --- a/.github/workflows/solidity-foundry-artifacts.yml +++ b/.github/workflows/solidity-foundry-artifacts.yml @@ -374,7 +374,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | ARTIFACTS=$(gh api -X GET repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts) - ARTIFACT_ID=$(echo "$ARTIFACTS" | jq '.artifacts[] | select(.name=="review-artifacts-${{ inputs.product }}-${{ env.head_ref }}") | .id') + ARTIFACT_ID=$(echo "$ARTIFACTS" | jq '.artifacts[] | select(.name=="review-artifacts-${{ inputs.product }}-${{ inputs.base_ref }}-${{ env.head_ref }}") | .id') echo "Artifact ID: $ARTIFACT_ID" echo "# Solidity Review Artifact Generated" >> $GITHUB_STEP_SUMMARY @@ -404,7 +404,7 @@ jobs: HEAD_REF: ${{ env.head_ref }} ARTIFACT_URL: ${{ steps.gather-all-artifacts.outputs.artifact-url }} - JIRA_HOST: ${{ vars.JIRA_HOST }} + JIRA_HOST: ${{ vars.JIRA_HOST }} JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} From 0e11561a313895903424b4359b2f111b6815b876 Mon Sep 17 00:00:00 2001 From: Makram Date: Mon, 2 Sep 2024 17:53:14 +0300 Subject: [PATCH 269/432] CODEOWNERS: add ccip-offchain (#14307) --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3e32ae4956..fb066e5347 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -13,6 +13,7 @@ /core/services/directrequest @smartcontractkit/keepers /core/services/feeds @smartcontractkit/FMS /core/services/synchronization/telem @smartcontractkit/realtime +/core/capabilities/ccip @smartcontractkit/ccip-offchain # To be deprecated in Chainlink V3 /core/services/fluxmonitorv2 @smartcontractkit/foundations From 2d77ff4623d0a0032533c89f32fc251400382455 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 2 Sep 2024 16:57:30 +0200 Subject: [PATCH 270/432] bump gomods (#14296) --- GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index 775d204269..de5511ce6d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -128,7 +128,7 @@ presubmit: ## Format go files and imports. .PHONY: gomods gomods: ## Install gomods - go install github.com/jmank88/gomods@v0.1.3 + go install github.com/jmank88/gomods@v0.1.4 .PHONY: mockery mockery: $(mockery) ## Install mockery. From e47a681c92998ef4edf6aa814e6ed1fef06d4723 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 3 Sep 2024 14:37:21 +0200 Subject: [PATCH 271/432] bump common; rm proxy replace (#14300) --- core/scripts/go.mod | 14 ++++---------- core/scripts/go.sum | 8 ++++---- go.md | 3 +++ go.mod | 13 ++++--------- go.sum | 8 ++++---- integration-tests/go.mod | 7 ++----- integration-tests/go.sum | 8 ++++---- integration-tests/load/go.mod | 7 ++----- integration-tests/load/go.sum | 8 ++++---- 9 files changed, 31 insertions(+), 45 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 2ae9753630..aafcfb8ed7 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 @@ -243,7 +243,6 @@ require ( github.com/mr-tron/base58 v1.2.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/mwitkow/grpc-proxy v0.0.0-20230212185441-f345521cb9c9 // indirect github.com/oklog/run v1.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc5 // indirect @@ -277,6 +276,7 @@ require ( github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect + github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.7.3 // indirect @@ -363,11 +363,5 @@ require ( sigs.k8s.io/yaml v1.4.0 // indirect ) -replace ( - // replicating the replace directive on cosmos SDK - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - - // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 - github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f - -) +// replicating the replace directive on cosmos SDK +replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index e9fefa6d4f..f0db4b0929 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1190,8 +1190,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 h1:MOFuL1J4/rRcR0x09qSlOsKIiq4I7YzbZcQ421KqUZA= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8/go.mod h1:TJSY2ETKiXLRPvGHNO7Dp1tlpFIPSCWwN3iIdrsadIE= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e h1:kxMSsv/RaTlH0Up9YTC6FE4K9n5QWcSKxbtiTS+JHzU= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= @@ -1202,8 +1202,8 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= -github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= +github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= +github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= diff --git a/go.md b/go.md index f58a5e23e4..3f7549d6ea 100644 --- a/go.md +++ b/go.md @@ -43,6 +43,8 @@ flowchart LR click chainlink-solana href "https://github.com/smartcontractkit/chainlink-solana" chainlink/v2 --> chainlink-starknet/relayer click chainlink-starknet/relayer href "https://github.com/smartcontractkit/chainlink-starknet" + chainlink/v2 --> grpc-proxy + click grpc-proxy href "https://github.com/smartcontractkit/grpc-proxy" chainlink/v2 --> libocr click libocr href "https://github.com/smartcontractkit/libocr" chainlink/v2 --> tdh2/go/ocr2/decryptionplugin @@ -55,6 +57,7 @@ flowchart LR chainlink-automation --> libocr chainlink-ccip --> chainlink-common chainlink-ccip --> libocr + chainlink-common --> grpc-proxy chainlink-common --> libocr chainlink-cosmos --> chainlink-common chainlink-cosmos --> libocr diff --git a/go.mod b/go.mod index baf4c187ef..6d1af95e05 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 @@ -279,7 +279,6 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect github.com/mtibben/percent v0.2.1 // indirect - github.com/mwitkow/grpc-proxy v0.0.0-20230212185441-f345521cb9c9 // indirect github.com/oklog/run v1.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect @@ -294,6 +293,7 @@ require ( github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect + github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -349,10 +349,5 @@ require ( sigs.k8s.io/yaml v1.4.0 // indirect ) -replace ( - // replicating the replace directive on cosmos SDK - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - - // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 - github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f -) +// replicating the replace directive on cosmos SDK +replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 diff --git a/go.sum b/go.sum index fee72a6493..864a33678b 100644 --- a/go.sum +++ b/go.sum @@ -1147,8 +1147,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 h1:MOFuL1J4/rRcR0x09qSlOsKIiq4I7YzbZcQ421KqUZA= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8/go.mod h1:TJSY2ETKiXLRPvGHNO7Dp1tlpFIPSCWwN3iIdrsadIE= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e h1:kxMSsv/RaTlH0Up9YTC6FE4K9n5QWcSKxbtiTS+JHzU= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= @@ -1159,8 +1159,8 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= -github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= +github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= +github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 37ddf694bf..aa66fb3b02 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -37,7 +37,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e github.com/smartcontractkit/chainlink-testing-framework v1.35.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 @@ -362,7 +362,6 @@ require ( github.com/mtibben/percent v0.2.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect - github.com/mwitkow/grpc-proxy v0.0.0-20230212185441-f345521cb9c9 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/oklog/run v1.1.0 // indirect github.com/oklog/ulid v1.3.1 // indirect @@ -409,6 +408,7 @@ require ( github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect + github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.8.1 // indirect @@ -518,9 +518,6 @@ replace ( // replicating the replace directive on cosmos SDK github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 - github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f - // type func(a Label, b Label) bool of func(a, b Label) bool {…} does not match inferred type func(a Label, b Label) int for func(a E, b E) int github.com/prometheus/prometheus => github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 ) diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 06729ec744..b624ebeea0 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1425,8 +1425,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 h1:MOFuL1J4/rRcR0x09qSlOsKIiq4I7YzbZcQ421KqUZA= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8/go.mod h1:TJSY2ETKiXLRPvGHNO7Dp1tlpFIPSCWwN3iIdrsadIE= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e h1:kxMSsv/RaTlH0Up9YTC6FE4K9n5QWcSKxbtiTS+JHzU= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= @@ -1447,8 +1447,8 @@ github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 h1:GRAAvtn2+ github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= -github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= -github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= +github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= +github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 13d87c970d..8eda875851 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e github.com/smartcontractkit/chainlink-testing-framework v1.35.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 @@ -62,6 +62,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 // indirect + github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/sourcegraph/conc v0.3.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect k8s.io/apimachinery v0.31.0 // indirect @@ -351,7 +352,6 @@ require ( github.com/mtibben/percent v0.2.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect - github.com/mwitkow/grpc-proxy v0.0.0-20230212185441-f345521cb9c9 // indirect github.com/oklog/run v1.1.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect @@ -515,9 +515,6 @@ replace ( // replicating the replace directive on cosmos SDK github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 - github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f - // type func(a Label, b Label) bool of func(a, b Label) bool {…} does not match inferred type func(a Label, b Label) int for func(a E, b E) int github.com/prometheus/prometheus => github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 ) diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index c5f5705cec..b298e59726 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1395,8 +1395,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8 h1:MOFuL1J4/rRcR0x09qSlOsKIiq4I7YzbZcQ421KqUZA= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240829145110-4a45c426fbe8/go.mod h1:TJSY2ETKiXLRPvGHNO7Dp1tlpFIPSCWwN3iIdrsadIE= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e h1:kxMSsv/RaTlH0Up9YTC6FE4K9n5QWcSKxbtiTS+JHzU= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= @@ -1417,8 +1417,8 @@ github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 h1:GRAAvtn2+ github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= -github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= -github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= +github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= +github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= From 8fa3ebee3e0ce09bf2e8270ab46c168756d25db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Tue, 3 Sep 2024 16:33:42 +0300 Subject: [PATCH 272/432] Validate trigger event ID before execution (#14314) * Validate trigger event ID before execution * Fix the trigger mock --- .changeset/cyan-spies-dream.md | 5 +++++ core/services/workflows/engine.go | 6 ++++++ core/services/workflows/engine_test.go | 4 +++- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 .changeset/cyan-spies-dream.md diff --git a/.changeset/cyan-spies-dream.md b/.changeset/cyan-spies-dream.md new file mode 100644 index 0000000000..e842f26bd4 --- /dev/null +++ b/.changeset/cyan-spies-dream.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal validate capability trigger event ID before executing diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index e98c592cc2..f4ab2b82bd 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -10,6 +10,7 @@ import ( "time" "github.com/jonboulle/clockwork" + "github.com/smartcontractkit/chainlink-common/pkg/workflows/exec" "github.com/smartcontractkit/chainlink-common/pkg/capabilities" @@ -418,6 +419,11 @@ func (e *Engine) loop(ctx context.Context) { te := resp.Event + if te.ID == "" { + e.logger.With(tIDKey, te.TriggerType).Error("trigger event ID is empty; not executing") + continue + } + executionID, err := generateExecutionID(e.workflow.id, te.ID) if err != nil { e.logger.With(tIDKey, te.ID).Errorf("could not generate execution ID: %v", err) diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index 2d862823cf..5cb24b8aea 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -349,7 +349,9 @@ func mockTrigger(t *testing.T) (capabilities.TriggerCapability, capabilities.Tri require.NoError(t, err) tr := capabilities.TriggerResponse{ Event: capabilities.TriggerEvent{ - Outputs: resp, + TriggerType: mt.ID, + ID: time.Now().UTC().Format(time.RFC3339), + Outputs: resp, }, } mt.triggerEvent = &tr From 12dc328372d0cc4256bbdc9cddaeed56831f37ea Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs <5300706+iljapavlovs@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:07:58 +0300 Subject: [PATCH 273/432] DEVSVCS-241: cleanup default VRF v2 Plus performance test settings for all chains (#14309) --- .../testconfig/vrfv2plus/vrfv2plus.toml | 428 +++++------------- 1 file changed, 120 insertions(+), 308 deletions(-) diff --git a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml index 1b43d73e17..941f3a827d 100644 --- a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml +++ b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml @@ -291,19 +291,17 @@ bhs_test_rate_limit_unit_duration = "3s" bhs_test_rps = 1 #SOAK TEST CONFIG -[Soak.Common] -chainlink_node_funding = 0.1 [Soak.VRFv2Plus.General] randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 number_of_sending_keys_to_create = 0 -subscription_funding_amount_link = 50 -subscription_funding_amount_native=10 +subscription_funding_amount_link = 500 +subscription_funding_amount_native = 100 [Soak.VRFv2Plus.Performance] -test_duration = "2m" +test_duration = "2h" rate_limit_unit_duration = "10s" rps = 1 bhs_test_duration = "1m" @@ -335,16 +333,16 @@ bhs_test_rps = 1 chainlink_node_funding = 0.1 [Stress.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 30 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 number_of_sending_keys_to_create = 0 -subscription_funding_amount_link = 5.0 -subscription_funding_amount_native=1 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 [Stress.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "10m" +rate_limit_unit_duration = "10s" rps = 1 bhs_test_duration = "1m" bhs_test_rate_limit_unit_duration = "3s" @@ -445,55 +443,33 @@ wait_for_256_blocks_timeout = "15m" wrapper_consumer_funding_amount_native_token = 1.0 wrapper_consumer_funding_amount_link = 3 - -[POLYGON_AMOY-Smoke.VRFv2Plus.Performance] -test_duration = "2s" -rate_limit_unit_duration = "15s" -rps = 1 - - -#SOAK TEST CONFIG [POLYGON_AMOY-Soak.VRFv2Plus.General] -randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request +randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 +number_of_sending_keys_to_create = 0 subscription_funding_amount_link = 500 -subscription_funding_amount_native = 200 +subscription_funding_amount_native = 100 [POLYGON_AMOY-Soak.VRFv2Plus.Performance] -test_duration = "5h" -rate_limit_unit_duration = "3s" -rps = 1 - -# LOAD TEST CONFIG -[POLYGON_AMOY-Load.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting -number_of_sub_to_create = 1 -subscription_funding_amount_link = 300 -subscription_funding_amount_native = 300 - -[POLYGON_AMOY-Load.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "2h" +rate_limit_unit_duration = "10s" rps = 1 - -# STRESS TEST CONFIG [POLYGON_AMOY-Stress.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 150 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5.0 -subscription_funding_amount_native = 0.1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 [POLYGON_AMOY-Stress.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "10m" +rate_limit_unit_duration = "1m" rps = 1 ### ARBITRUM SEPOLIA Config - [ARBITRUM_SEPOLIA.VRFv2Plus.General] use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request @@ -590,53 +566,32 @@ wait_for_256_blocks_timeout = "100s" wrapper_consumer_funding_amount_native_token = 1.0 wrapper_consumer_funding_amount_link = 5 -[ARBITRUM_SEPOLIA-Smoke.VRFv2Plus.Performance] -test_duration = "1s" -rate_limit_unit_duration = "10s" -rps = 1 - - -#SOAK TEST CONFIG [ARBITRUM_SEPOLIA-Soak.VRFv2Plus.General] randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 300 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 subscription_funding_amount_native = 100 [ARBITRUM_SEPOLIA-Soak.VRFv2Plus.Performance] -test_duration = "1h" +test_duration = "2h" rate_limit_unit_duration = "10s" rps = 1 -# LOAD TEST CONFIG -[ARBITRUM_SEPOLIA-Load.VRFv2Plus.General] -randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting -number_of_sub_to_create = 1 -subscription_funding_amount_link = 100 -subscription_funding_amount_native = 60 - -[ARBITRUM_SEPOLIA-Load.VRFv2Plus.Performance] -test_duration = "30m" -rate_limit_unit_duration = "3s" -rps = 1 - - -# STRESS TEST CONFIG [ARBITRUM_SEPOLIA-Stress.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 150 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5.0 -subscription_funding_amount_native = 0.1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 [ARBITRUM_SEPOLIA-Stress.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "10m" +rate_limit_unit_duration = "1m" rps = 1 - ### AVALANCHE FUJI Config [AVALANCHE_FUJI.Common] chainlink_node_funding = 3 @@ -718,50 +673,30 @@ wait_for_256_blocks_timeout = "10m" wrapper_consumer_funding_amount_native_token = 1.0 wrapper_consumer_funding_amount_link = 5 -[AVALANCHE_FUJI-Smoke.VRFv2Plus.Performance] -test_duration = "2s" -rate_limit_unit_duration = "10s" -rps = 1 - - -#SOAK TEST CONFIG [AVALANCHE_FUJI-Soak.VRFv2Plus.General] -randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request +randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 400 -subscription_funding_amount_native = 200 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native = 100 [AVALANCHE_FUJI-Soak.VRFv2Plus.Performance] -test_duration = "5h" -rate_limit_unit_duration = "3s" -rps = 1 - -# LOAD TEST CONFIG -[AVALANCHE_FUJI-Load.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting -number_of_sub_to_create = 1 -subscription_funding_amount_link = 300 -subscription_funding_amount_native = 300 - -[AVALANCHE_FUJI-Load.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "2h" +rate_limit_unit_duration = "10s" rps = 1 - -# STRESS TEST CONFIG [AVALANCHE_FUJI-Stress.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 60 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5.0 -subscription_funding_amount_native = 0.1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 [AVALANCHE_FUJI-Stress.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "10m" +rate_limit_unit_duration = "1m" rps = 1 ### ETH SEPOLIA Config @@ -843,48 +778,30 @@ wait_for_256_blocks_timeout = "70m" wrapper_consumer_funding_amount_native_token = 1.0 wrapper_consumer_funding_amount_link = 3 -[SEPOLIA-Smoke.VRFv2Plus.Performance] -test_duration = "2s" -rate_limit_unit_duration = "3s" -rps = 1 - -#SOAK TEST CONFIG [SEPOLIA-Soak.VRFv2Plus.General] -randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request +randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 +number_of_sending_keys_to_create = 0 subscription_funding_amount_link = 500 -subscription_funding_amount_native = 200 +subscription_funding_amount_native = 100 [SEPOLIA-Soak.VRFv2Plus.Performance] test_duration = "2h" -rate_limit_unit_duration = "3s" -rps = 1 - -# LOAD TEST CONFIG -[SEPOLIA-Load.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting -number_of_sub_to_create = 1 -subscription_funding_amount_link = 5.0 -subscription_funding_amount_native = 30 - -[SEPOLIA-Load.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +rate_limit_unit_duration = "10s" rps = 1 -# STRESS TEST CONFIG [SEPOLIA-Stress.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 30 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5.0 -subscription_funding_amount_native = 0.1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 [SEPOLIA-Stress.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "10m" +rate_limit_unit_duration = "1m" rps = 1 ### BSC TESTNET Config @@ -966,53 +883,32 @@ wait_for_256_blocks_timeout = "15m" wrapper_consumer_funding_amount_native_token = 1.0 wrapper_consumer_funding_amount_link = 5 -[BSC_TESTNET-Smoke.VRFv2Plus.Performance] -test_duration = "15s" -rate_limit_unit_duration = "3s" -rps = 1 - - -#SOAK TEST CONFIG [BSC_TESTNET-Soak.VRFv2Plus.General] -randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request +randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 400 -subscription_funding_amount_native = 200 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native = 100 [BSC_TESTNET-Soak.VRFv2Plus.Performance] -test_duration = "5h" -rate_limit_unit_duration = "3s" -rps = 1 - -# LOAD TEST CONFIG -[BSC_TESTNET-Load.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting -number_of_sub_to_create = 1 -subscription_funding_amount_link = 300 -subscription_funding_amount_native = 300 - -[BSC_TESTNET-Load.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "2h" +rate_limit_unit_duration = "10s" rps = 1 - -# STRESS TEST CONFIG [BSC_TESTNET-Stress.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 60 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5.0 -subscription_funding_amount_native = 0.1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 [BSC_TESTNET-Stress.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "10m" +rate_limit_unit_duration = "1m" rps = 1 - ### NEXON QA Config [NEXON_QA.VRFv2Plus.General] use_test_coordinator = true @@ -1053,51 +949,30 @@ wait_for_256_blocks_timeout = "25m" wrapper_consumer_funding_amount_link = 21 wrapper_consumer_funding_amount_native_token = 3 - -[NEXON_QA-Smoke.VRFv2Plus.Performance] -test_duration = "2s" -rate_limit_unit_duration = "3s" -rps = 1 - - -#SOAK TEST CONFIG [NEXON_QA-Soak.VRFv2Plus.General] -randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request +randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 400 -subscription_funding_amount_native = 200 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native = 100 [NEXON_QA-Soak.VRFv2Plus.Performance] -test_duration = "5h" -rate_limit_unit_duration = "3s" -rps = 1 - -# LOAD TEST CONFIG -[NEXON_QA-Load.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting -number_of_sub_to_create = 1 -subscription_funding_amount_link = 300 -subscription_funding_amount_native = 300 - -[NEXON_QA-Load.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "2h" +rate_limit_unit_duration = "10s" rps = 1 - -# STRESS TEST CONFIG [NEXON_QA-Stress.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 60 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5.0 -subscription_funding_amount_native = 2 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 [NEXON_QA-Stress.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "10m" +rate_limit_unit_duration = "1m" rps = 1 ### NEXON DEV Config @@ -1139,53 +1014,32 @@ wait_for_256_blocks_timeout = "25m" wrapper_consumer_funding_amount_link = 21 wrapper_consumer_funding_amount_native_token = 3 -[NEXON_DEV-Smoke.VRFv2Plus.Performance] -test_duration = "2s" -rate_limit_unit_duration = "3s" -rps = 1 - - -#SOAK TEST CONFIG [NEXON_DEV-Soak.VRFv2Plus.General] -randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request +randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 400 -subscription_funding_amount_native = 200 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native = 100 [NEXON_DEV-Soak.VRFv2Plus.Performance] -test_duration = "5h" -rate_limit_unit_duration = "3s" -rps = 1 - -# LOAD TEST CONFIG -[NEXON_DEV-Load.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting -number_of_sub_to_create = 1 -subscription_funding_amount_link = 300 -subscription_funding_amount_native = 300 - -[NEXON_DEV-Load.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "2h" +rate_limit_unit_duration = "10s" rps = 1 - -# STRESS TEST CONFIG [NEXON_DEV-Stress.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 60 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5.0 -subscription_funding_amount_native = 0.1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 [NEXON_DEV-Stress.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "10m" +rate_limit_unit_duration = "1m" rps = 1 - ### NEXON TEST Config [NEXON_TEST.VRFv2Plus.General] use_test_coordinator = true @@ -1226,50 +1080,30 @@ wait_for_256_blocks_timeout = "25m" wrapper_consumer_funding_amount_link = 5 wrapper_consumer_funding_amount_native_token = 3 -[NEXON_TEST-Smoke.VRFv2Plus.Performance] -test_duration = "2s" -rate_limit_unit_duration = "3s" -rps = 1 - - -#SOAK TEST CONFIG [NEXON_TEST-Soak.VRFv2Plus.General] -randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request +randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 400 -subscription_funding_amount_native = 200 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native = 100 [NEXON_TEST-Soak.VRFv2Plus.Performance] -test_duration = "5h" -rate_limit_unit_duration = "3s" -rps = 1 - -# LOAD TEST CONFIG -[NEXON_TEST-Load.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting -number_of_sub_to_create = 1 -subscription_funding_amount_link = 300 -subscription_funding_amount_native = 300 - -[NEXON_TEST-Load.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "2h" +rate_limit_unit_duration = "10s" rps = 1 - -# STRESS TEST CONFIG [NEXON_TEST-Stress.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 60 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5.0 -subscription_funding_amount_native = 0.1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 [NEXON_TEST-Stress.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "10m" +rate_limit_unit_duration = "1m" rps = 1 @@ -1309,50 +1143,28 @@ wait_for_256_blocks_timeout = "25m" wrapper_consumer_funding_amount_link = 21 wrapper_consumer_funding_amount_native_token = 3 -[NEXON_STAGE-Smoke.VRFv2Plus.Performance] -test_duration = "2s" -rate_limit_unit_duration = "3s" -rps = 1 - - -#SOAK TEST CONFIG [NEXON_STAGE-Soak.VRFv2Plus.General] -randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request +randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 400 -subscription_funding_amount_native = 200 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native = 100 [NEXON_STAGE-Soak.VRFv2Plus.Performance] -test_duration = "5h" -rate_limit_unit_duration = "3s" -rps = 1 - -# LOAD TEST CONFIG -[NEXON_STAGE-Load.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting -number_of_sub_to_create = 1 -subscription_funding_amount_link = 300 -subscription_funding_amount_native = 300 - -[NEXON_STAGE-Load.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "2h" +rate_limit_unit_duration = "10s" rps = 1 - -# STRESS TEST CONFIG [NEXON_STAGE-Stress.VRFv2Plus.General] -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 60 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5.0 -subscription_funding_amount_native = 0.1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 [NEXON_STAGE-Stress.VRFv2Plus.Performance] -test_duration = "2m" -rate_limit_unit_duration = "3s" +test_duration = "10m" +rate_limit_unit_duration = "1m" rps = 1 - - From e8c2453e8581ed7ad83033d938567dcce8f6c5a5 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 3 Sep 2024 11:04:22 -0400 Subject: [PATCH 274/432] Initial implementation of Configurator for LLO (#14249) * Initial implementation of SourceVerifier * Prettier * Fix gas snapshot --------- Co-authored-by: Michael Fletcher --- contracts/.changeset/forty-radios-brush.md | 8 + .../gas-snapshots/llo-feeds.gas-snapshot | 4 +- .../scripts/native_solc_compile_all_llo-feeds | 8 +- .../v0.8/llo-feeds/dev/ChannelVerifier.sol | 536 ------ .../dev/interfaces/IChannelVerifier.sol | 111 -- .../dev/test/mocks/ExposedChannelVerifier.sol | 66 - .../dev/test/mocks/ExposedVerifier.sol | 69 - .../llo-feeds/interfaces/IConfigurator.sol | 28 + .../configuration}/ChannelConfigStore.sol | 4 +- .../v0.5.0/configuration/Configurator.sol | 188 ++ .../interfaces/IChannelConfigStore.sol | 2 +- .../test/ChannelConfigStore.t.sol | 0 .../test/mocks/ExposedChannelConfigStore.sol | 0 .../test/mocks/ExposedConfigurator.sol | 15 + .../channel_verifier/channel_verifier.go | 1583 ----------------- .../generated/configurator/configurator.go | 748 ++++++++ .../exposed_channel_verifier.go | 202 --- ...rapper-dependency-versions-do-not-edit.txt | 1 + core/gethwrappers/llo-feeds/go_generate.go | 3 +- core/internal/cltest/cltest.go | 3 +- .../evm/report_codec_premium_legacy_test.go | 25 + core/services/llo/offchain_config_digester.go | 123 -- .../llo/offchain_config_digester_test.go | 55 - .../services/ocr2/plugins/llo/helpers_test.go | 90 +- .../ocr2/plugins/llo/integration_test.go | 460 +++-- core/services/ocrbootstrap/delegate.go | 8 +- core/services/relay/evm/evm.go | 7 +- .../services/relay/evm/llo_config_provider.go | 43 +- .../relay/evm/llo_verifier_decoder.go | 67 - .../relay/evm/mercury/config_digest.go | 7 +- .../relay/evm/mercury/config_digest_test.go | 2 + .../relay/evm/mercury/config_poller.go | 7 +- .../evm/mercury/offchain_config_digester.go | 8 +- .../relay/evm/mercury_config_provider.go | 4 +- core/services/relay/evm/types/types.go | 3 + 35 files changed, 1333 insertions(+), 3155 deletions(-) create mode 100644 contracts/.changeset/forty-radios-brush.md delete mode 100644 contracts/src/v0.8/llo-feeds/dev/ChannelVerifier.sol delete mode 100644 contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelVerifier.sol delete mode 100644 contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelVerifier.sol delete mode 100644 contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedVerifier.sol create mode 100644 contracts/src/v0.8/llo-feeds/interfaces/IConfigurator.sol rename contracts/src/v0.8/llo-feeds/{dev => v0.5.0/configuration}/ChannelConfigStore.sol (86%) create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/configuration/Configurator.sol rename contracts/src/v0.8/llo-feeds/{dev => v0.5.0/configuration}/interfaces/IChannelConfigStore.sol (64%) rename contracts/src/v0.8/llo-feeds/{dev => v0.5.0/configuration}/test/ChannelConfigStore.t.sol (100%) rename contracts/src/v0.8/llo-feeds/{dev => v0.5.0/configuration}/test/mocks/ExposedChannelConfigStore.sol (100%) create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/configuration/test/mocks/ExposedConfigurator.sol delete mode 100644 core/gethwrappers/llo-feeds/generated/channel_verifier/channel_verifier.go create mode 100644 core/gethwrappers/llo-feeds/generated/configurator/configurator.go delete mode 100644 core/gethwrappers/llo-feeds/generated/exposed_channel_verifier/exposed_channel_verifier.go delete mode 100644 core/services/llo/offchain_config_digester.go delete mode 100644 core/services/llo/offchain_config_digester_test.go delete mode 100644 core/services/relay/evm/llo_verifier_decoder.go diff --git a/contracts/.changeset/forty-radios-brush.md b/contracts/.changeset/forty-radios-brush.md new file mode 100644 index 0000000000..f7c251b9e5 --- /dev/null +++ b/contracts/.changeset/forty-radios-brush.md @@ -0,0 +1,8 @@ +--- +'@chainlink/contracts': patch +--- + +Add Configurator contract + + +MERC-6185 \ No newline at end of file diff --git a/contracts/gas-snapshots/llo-feeds.gas-snapshot b/contracts/gas-snapshots/llo-feeds.gas-snapshot index 8b52c6a6c5..231bff7c9d 100644 --- a/contracts/gas-snapshots/llo-feeds.gas-snapshot +++ b/contracts/gas-snapshots/llo-feeds.gas-snapshot @@ -88,7 +88,7 @@ DestinationFeeManagerProcessFeeTest:test_poolIdsCannotBeZeroAddress() (gas: 1179 DestinationFeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 123807) DestinationFeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 29767) DestinationFeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 167721) -DestinationFeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 30107) +DestinationFeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 32607) DestinationFeeManagerProcessFeeTest:test_processFeeNative() (gas: 180514) DestinationFeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 125076) DestinationFeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 31844) @@ -299,7 +299,7 @@ FeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 198803) FeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 117088) FeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 27462) FeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 163205) -FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 27827) +FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 30327) FeeManagerProcessFeeTest:test_processFeeNative() (gas: 173826) FeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 118379) FeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 29536) diff --git a/contracts/scripts/native_solc_compile_all_llo-feeds b/contracts/scripts/native_solc_compile_all_llo-feeds index f0224d962c..ba5e6a4c8b 100755 --- a/contracts/scripts/native_solc_compile_all_llo-feeds +++ b/contracts/scripts/native_solc_compile_all_llo-feeds @@ -36,13 +36,9 @@ compileContract llo-feeds/v0.4.0/DestinationVerifier.sol compileContract llo-feeds/v0.4.0/DestinationVerifierProxy.sol compileContract llo-feeds/v0.4.0/DestinationFeeManager.sol compileContract llo-feeds/v0.4.0/DestinationRewardManager.sol - +compileContract llo-feeds/v0.5.0/configuration/ChannelConfigStore.sol +compileContract llo-feeds/v0.5.0/configuration/Configurator.sol # Test | Mocks compileContract llo-feeds/v0.3.0/test/mocks/ErroredVerifier.sol compileContract llo-feeds/v0.3.0/test/mocks/ExposedVerifier.sol - -# LLO -compileContract llo-feeds/dev/ChannelConfigStore.sol -compileContract llo-feeds/dev/ChannelVerifier.sol -compileContract llo-feeds/dev/test/mocks/ExposedChannelVerifier.sol diff --git a/contracts/src/v0.8/llo-feeds/dev/ChannelVerifier.sol b/contracts/src/v0.8/llo-feeds/dev/ChannelVerifier.sol deleted file mode 100644 index 424022dc44..0000000000 --- a/contracts/src/v0.8/llo-feeds/dev/ChannelVerifier.sol +++ /dev/null @@ -1,536 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.19; - -import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; -import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; -import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -import {Common} from "../libraries/Common.sol"; -import {IChannelVerifier} from "./interfaces/IChannelVerifier.sol"; - -// OCR2 standard -uint256 constant MAX_NUM_ORACLES = 31; - -/* - * The verifier contract is used to verify offchain reports signed - * by DONs. A report consists of a price, block number and feed Id. It - * represents the observed price of an asset at a specified block number for - * a feed. The verifier contract is used to verify that such reports have - * been signed by the correct signers. - **/ -contract ChannelVerifier is IChannelVerifier, ConfirmedOwner, TypeAndVersionInterface { - // The first byte of the mask can be 0, because we only ever have 31 oracles - uint256 internal constant ORACLE_MASK = 0x0001010101010101010101010101010101010101010101010101010101010101; - - enum Role { - // Default role for an oracle address. This means that the oracle address - // is not a signer - Unset, - // Role given to an oracle address that is allowed to sign feed data - Signer - } - - struct Signer { - // Index of oracle in a configuration - uint8 index; - // The oracle's role - Role role; - } - - struct Config { - // Fault tolerance - uint8 f; - // Marks whether or not a configuration is active - bool isActive; - // Map of signer addresses to oracles - mapping(address => Signer) oracles; - } - - struct VerifierState { - // The number of times a new configuration - /// has been set - uint32 configCount; - // The block number of the block the last time - /// the configuration was updated. - uint32 latestConfigBlockNumber; - // The latest epoch a report was verified for - uint32 latestEpoch; - /// The latest config digest set - bytes32 latestConfigDigest; - /// List of deactivated feeds - mapping(bytes32 => bool) deactivatedFeeds; - /// The historical record of all previously set configs by feedId - mapping(bytes32 => Config) s_verificationDataConfigs; - } - - /// @notice This event is emitted when a new report is verified. - /// It is used to keep a historical record of verified reports. - event ReportVerified(bytes32 indexed feedId, address requester); - - /// @notice This event is emitted whenever a new configuration is set. It triggers a new run of the offchain reporting protocol. - event ConfigSet( - uint32 previousConfigBlockNumber, - bytes32 configDigest, - uint64 configCount, - address[] signers, - bytes32[] offchainTransmitters, - uint8 f, - bytes onchainConfig, - uint64 offchainConfigVersion, - bytes offchainConfig - ); - - /// @notice This event is emitted whenever a configuration is deactivated - event ConfigDeactivated(bytes32 configDigest); - - /// @notice This event is emitted whenever a configuration is activated - event ConfigActivated(bytes32 configDigest); - - /// @notice This event is emitted whenever a feed is activated - event FeedActivated(bytes32 indexed feedId); - - /// @notice This event is emitted whenever a feed is deactivated - event FeedDeactivated(bytes32 indexed feedId); - - /// @notice This error is thrown whenever an address tries - /// to exeecute a transaction that it is not authorized to do so - error AccessForbidden(); - - /// @notice This error is thrown whenever a zero address is passed - error ZeroAddress(); - - /// @notice This error is thrown whenever the feed ID passed in - /// a signed report is empty - error FeedIdEmpty(); - - /// @notice This error is thrown whenever the config digest - /// is empty - error DigestEmpty(); - - /// @notice This error is thrown whenever the config digest - /// passed in has not been set in this verifier - /// @param configDigest The config digest that has not been set - error DigestNotSet(bytes32 configDigest); - - /// @notice This error is thrown whenever the config digest - /// has been deactivated - /// @param configDigest The config digest that is inactive - error DigestInactive(bytes32 configDigest); - - /// @notice This error is thrown whenever trying to set a config - /// with a fault tolerance of 0 - error FaultToleranceMustBePositive(); - - /// @notice This error is thrown whenever a report is signed - /// with more than the max number of signers - /// @param numSigners The number of signers who have signed the report - /// @param maxSigners The maximum number of signers that can sign a report - error ExcessSigners(uint256 numSigners, uint256 maxSigners); - - /// @notice This error is thrown whenever a report is signed - /// with less than the minimum number of signers - /// @param numSigners The number of signers who have signed the report - /// @param minSigners The minimum number of signers that need to sign a report - error InsufficientSigners(uint256 numSigners, uint256 minSigners); - - /// @notice This error is thrown whenever a report is signed - /// with an incorrect number of signers - /// @param numSigners The number of signers who have signed the report - /// @param expectedNumSigners The expected number of signers that need to sign - /// a report - error IncorrectSignatureCount(uint256 numSigners, uint256 expectedNumSigners); - - /// @notice This error is thrown whenever the R and S signer components - /// have different lengths - /// @param rsLength The number of r signature components - /// @param ssLength The number of s signature components - error MismatchedSignatures(uint256 rsLength, uint256 ssLength); - - /// @notice This error is thrown whenever setting a config with duplicate signatures - error NonUniqueSignatures(); - - /// @notice This error is thrown whenever a report fails to verify due to bad or duplicate signatures - error BadVerification(); - - /// @notice This error is thrown whenever the admin tries to deactivate - /// the latest config digest - /// @param configDigest The latest config digest - error CannotDeactivateLatestConfig(bytes32 configDigest); - - /// @notice This error is thrown whenever the feed ID passed in is deactivated - /// @param feedId The feed ID - error InactiveFeed(bytes32 feedId); - - /// @notice This error is thrown whenever the feed ID passed in is not found - /// @param feedId The feed ID - error InvalidFeed(bytes32 feedId); - - /// @notice The address of the verifier proxy - address private immutable i_verifierProxyAddr; - - /// @notice Verifier states keyed on Feed ID - VerifierState internal s_feedVerifierState; - - /// @param verifierProxyAddr The address of the VerifierProxy contract - constructor(address verifierProxyAddr) ConfirmedOwner(msg.sender) { - if (verifierProxyAddr == address(0)) revert ZeroAddress(); - i_verifierProxyAddr = verifierProxyAddr; - } - - modifier checkConfigValid(uint256 numSigners, uint256 f) { - if (f == 0) revert FaultToleranceMustBePositive(); - if (numSigners > MAX_NUM_ORACLES) revert ExcessSigners(numSigners, MAX_NUM_ORACLES); - if (numSigners <= 3 * f) revert InsufficientSigners(numSigners, 3 * f + 1); - _; - } - - /// @inheritdoc IERC165 - function supportsInterface(bytes4 interfaceId) external pure override returns (bool isVerifier) { - return interfaceId == this.verify.selector; - } - - /// @inheritdoc TypeAndVersionInterface - function typeAndVersion() external pure override returns (string memory) { - return "ChannelVerifier 0.0.0"; - } - - /// @inheritdoc IChannelVerifier - function verify( - bytes calldata signedReport, - address sender - ) external override returns (bytes memory verifierResponse) { - if (msg.sender != i_verifierProxyAddr) revert AccessForbidden(); - ( - bytes32[3] memory reportContext, - bytes memory reportData, - bytes32[] memory rs, - bytes32[] memory ss, - bytes32 rawVs - ) = abi.decode(signedReport, (bytes32[3], bytes, bytes32[], bytes32[], bytes32)); - - // The feed ID is the first 32 bytes of the report data. - bytes32 feedId = bytes32(reportData); - - // If the feed has been deactivated, do not verify the report - if (s_feedVerifierState.deactivatedFeeds[feedId]) { - revert InactiveFeed(feedId); - } - - // reportContext consists of: - // reportContext[0]: ConfigDigest - // reportContext[1]: 27 byte padding, 4-byte epoch and 1-byte round - // reportContext[2]: ExtraHash - bytes32 configDigest = reportContext[0]; - Config storage s_config = s_feedVerifierState.s_verificationDataConfigs[configDigest]; - - _validateReport(configDigest, rs, ss, s_config); - _updateEpoch(reportContext, s_feedVerifierState); - - bytes32 hashedReport = keccak256(reportData); - - _verifySignatures(hashedReport, reportContext, rs, ss, rawVs, s_config); - emit ReportVerified(feedId, sender); - - return reportData; - } - - /// @notice Validates parameters of the report - /// @param configDigest Config digest from the report - /// @param rs R components from the report - /// @param ss S components from the report - /// @param config Config for the given feed ID keyed on the config digest - function _validateReport( - bytes32 configDigest, - bytes32[] memory rs, - bytes32[] memory ss, - Config storage config - ) private view { - uint8 expectedNumSignatures = config.f + 1; - - if (!config.isActive) revert DigestInactive(configDigest); - if (rs.length != expectedNumSignatures) revert IncorrectSignatureCount(rs.length, expectedNumSignatures); - if (rs.length != ss.length) revert MismatchedSignatures(rs.length, ss.length); - } - - /** - * @notice Conditionally update the epoch for a feed - * @param reportContext Report context containing the epoch and round - * @param feedVerifierState Feed verifier state to conditionally update - */ - function _updateEpoch(bytes32[3] memory reportContext, VerifierState storage feedVerifierState) private { - uint40 epochAndRound = uint40(uint256(reportContext[1])); - uint32 epoch = uint32(epochAndRound >> 8); - if (epoch > feedVerifierState.latestEpoch) { - feedVerifierState.latestEpoch = epoch; - } - } - - /// @notice Verifies that a report has been signed by the correct - /// signers and that enough signers have signed the reports. - /// @param hashedReport The keccak256 hash of the raw report's bytes - /// @param reportContext The context the report was signed in - /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries - /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries - /// @param rawVs ith element is the the V component of the ith signature - /// @param s_config The config digest the report was signed for - function _verifySignatures( - bytes32 hashedReport, - bytes32[3] memory reportContext, - bytes32[] memory rs, - bytes32[] memory ss, - bytes32 rawVs, - Config storage s_config - ) private view { - bytes32 h = keccak256(abi.encodePacked(hashedReport, reportContext)); - // i-th byte counts number of sigs made by i-th signer - uint256 signedCount; - - Signer memory o; - address signerAddress; - uint256 numSigners = rs.length; - for (uint256 i; i < numSigners; ++i) { - signerAddress = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]); - o = s_config.oracles[signerAddress]; - if (o.role != Role.Signer) revert BadVerification(); - unchecked { - signedCount += 1 << (8 * o.index); - } - } - - if (signedCount & ORACLE_MASK != signedCount) revert BadVerification(); - } - - /// @inheritdoc IChannelVerifier - function setConfig( - address[] memory signers, - bytes32[] memory offchainTransmitters, - uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig, - Common.AddressAndWeight[] memory recipientAddressesAndWeights - ) external override checkConfigValid(signers.length, f) onlyOwner { - _setConfig( - block.chainid, - address(this), - 0, // 0 defaults to feedConfig.configCount + 1 - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig, - recipientAddressesAndWeights - ); - } - - /// @inheritdoc IChannelVerifier - function setConfigFromSource( - uint256 sourceChainId, - address sourceAddress, - uint32 newConfigCount, - address[] memory signers, - bytes32[] memory offchainTransmitters, - uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig, - Common.AddressAndWeight[] memory recipientAddressesAndWeights - ) external override checkConfigValid(signers.length, f) onlyOwner { - _setConfig( - sourceChainId, - sourceAddress, - newConfigCount, - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig, - recipientAddressesAndWeights - ); - } - - /// @notice Sets config based on the given arguments - /// @param sourceChainId Chain ID of source config - /// @param sourceAddress Address of source config Verifier - /// @param newConfigCount Optional param to force the new config count - /// @param signers addresses with which oracles sign the reports - /// @param offchainTransmitters CSA key for the ith Oracle - /// @param f number of faulty oracles the system can tolerate - /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) - /// @param offchainConfigVersion version number for offchainEncoding schema - /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract - /// @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards - function _setConfig( - uint256 sourceChainId, - address sourceAddress, - uint32 newConfigCount, - address[] memory signers, - bytes32[] memory offchainTransmitters, - uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig, - Common.AddressAndWeight[] memory recipientAddressesAndWeights - ) internal { - // Increment the number of times a config has been set first - if (newConfigCount > 0) s_feedVerifierState.configCount = newConfigCount; - else s_feedVerifierState.configCount++; - - bytes32 configDigest = _configDigestFromConfigData( - sourceChainId, - sourceAddress, - s_feedVerifierState.configCount, - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig - ); - - s_feedVerifierState.s_verificationDataConfigs[configDigest].f = f; - s_feedVerifierState.s_verificationDataConfigs[configDigest].isActive = true; - for (uint8 i; i < signers.length; ++i) { - address signerAddr = signers[i]; - if (signerAddr == address(0)) revert ZeroAddress(); - - // All signer roles are unset by default for a new config digest. - // Here the contract checks to see if a signer's address has already - // been set to ensure that the group of signer addresses that will - // sign reports with the config digest are unique. - bool isSignerAlreadySet = s_feedVerifierState.s_verificationDataConfigs[configDigest].oracles[signerAddr].role != - Role.Unset; - if (isSignerAlreadySet) revert NonUniqueSignatures(); - s_feedVerifierState.s_verificationDataConfigs[configDigest].oracles[signerAddr] = Signer({ - role: Role.Signer, - index: i - }); - } - - recipientAddressesAndWeights; // silence unused var warning - // IVerifierProxy(i_verifierProxyAddr).setVerifier( - // feedVerifierState.latestConfigDigest, - // configDigest, - // recipientAddressesAndWeights - // ); - - emit ConfigSet( - s_feedVerifierState.latestConfigBlockNumber, - configDigest, - s_feedVerifierState.configCount, - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig - ); - - s_feedVerifierState.latestEpoch = 0; - s_feedVerifierState.latestConfigBlockNumber = uint32(block.number); - s_feedVerifierState.latestConfigDigest = configDigest; - } - - /// @notice Generates the config digest from config data - /// @param sourceChainId Chain ID of source config - /// @param sourceAddress Address of source config Verifier - /// @param configCount ordinal number of this config setting among all config settings over the life of this contract - /// @param signers ith element is address ith oracle uses to sign a report - /// @param offchainTransmitters ith element is address ith oracle used to transmit reports (in this case used for flexible additional field, such as CSA pub keys) - /// @param f maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly - /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) - /// @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter - /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract - /// @dev This function is a modified version of the method from OCR2Abstract - function _configDigestFromConfigData( - uint256 sourceChainId, - address sourceAddress, - uint64 configCount, - address[] memory signers, - bytes32[] memory offchainTransmitters, - uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig - ) internal pure returns (bytes32) { - uint256 h = uint256( - keccak256( - abi.encode( - sourceChainId, - sourceAddress, - configCount, - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig - ) - ) - ); - uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 - // 0x0009 corresponds to ConfigDigestPrefixLLO in libocr - uint256 prefix = 0x0009 << (256 - 16); // 0x000900..00 - return bytes32((prefix & prefixMask) | (h & ~prefixMask)); - } - - /// @inheritdoc IChannelVerifier - function activateConfig(bytes32 configDigest) external onlyOwner { - if (configDigest == bytes32("")) revert DigestEmpty(); - if (s_feedVerifierState.s_verificationDataConfigs[configDigest].f == 0) revert DigestNotSet(configDigest); - s_feedVerifierState.s_verificationDataConfigs[configDigest].isActive = true; - emit ConfigActivated(configDigest); - } - - /// @inheritdoc IChannelVerifier - function deactivateConfig(bytes32 configDigest) external onlyOwner { - if (configDigest == bytes32("")) revert DigestEmpty(); - if (s_feedVerifierState.s_verificationDataConfigs[configDigest].f == 0) revert DigestNotSet(configDigest); - if (configDigest == s_feedVerifierState.latestConfigDigest) { - revert CannotDeactivateLatestConfig(configDigest); - } - s_feedVerifierState.s_verificationDataConfigs[configDigest].isActive = false; - emit ConfigDeactivated(configDigest); - } - - /// @inheritdoc IChannelVerifier - function activateFeed(bytes32 feedId) external onlyOwner { - if (s_feedVerifierState.deactivatedFeeds[feedId]) return; - - s_feedVerifierState.deactivatedFeeds[feedId] = false; - emit FeedActivated(feedId); - } - - /// @inheritdoc IChannelVerifier - function deactivateFeed(bytes32 feedId) external onlyOwner { - if (s_feedVerifierState.deactivatedFeeds[feedId] == false) return; - - s_feedVerifierState.deactivatedFeeds[feedId] = true; - emit FeedDeactivated(feedId); - } - - /// @inheritdoc IChannelVerifier - function latestConfigDigestAndEpoch() - external - view - override - returns (bool scanLogs, bytes32 configDigest, uint32 epoch) - { - return (false, s_feedVerifierState.latestConfigDigest, s_feedVerifierState.latestEpoch); - } - - /// @inheritdoc IChannelVerifier - function latestConfigDetails() - external - view - override - returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) - { - return ( - s_feedVerifierState.configCount, - s_feedVerifierState.latestConfigBlockNumber, - s_feedVerifierState.latestConfigDigest - ); - } -} diff --git a/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelVerifier.sol b/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelVerifier.sol deleted file mode 100644 index 6bab5912a7..0000000000 --- a/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelVerifier.sol +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.19; - -import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; -import {Common} from "../../libraries/Common.sol"; - -interface IChannelVerifier is IERC165 { - /** - * @notice Verifies that the data encoded has been signed - * correctly by routing to the correct verifier. - * @param signedReport The encoded data to be verified. - * @param sender The address that requested to verify the contract. - * This is only used for logging purposes. - * @dev Verification is typically only done through the proxy contract so - * we can't just use msg.sender to log the requester as the msg.sender - * contract will always be the proxy. - * @return verifierResponse The encoded verified response. - */ - function verify(bytes calldata signedReport, address sender) external returns (bytes memory verifierResponse); - - /** - * @notice sets offchain reporting protocol configuration incl. participating oracles - * @param signers addresses with which oracles sign the reports - * @param offchainTransmitters CSA key for the ith Oracle - * @param f number of faulty oracles the system can tolerate - * @param onchainConfig serialized configuration used by the contract (and possibly oracles) - * @param offchainConfigVersion version number for offchainEncoding schema - * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract - * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards - */ - function setConfig( - address[] memory signers, - bytes32[] memory offchainTransmitters, - uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig, - Common.AddressAndWeight[] memory recipientAddressesAndWeights - ) external; - - /** - * @notice identical to `setConfig` except with args for sourceChainId and sourceAddress - * @param sourceChainId Chain ID of source config - * @param sourceAddress Address of source config Verifier - * @param newConfigCount Param to force the new config count - * @param signers addresses with which oracles sign the reports - * @param offchainTransmitters CSA key for the ith Oracle - * @param f number of faulty oracles the system can tolerate - * @param onchainConfig serialized configuration used by the contract (and possibly oracles) - * @param offchainConfigVersion version number for offchainEncoding schema - * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract - * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards - */ - function setConfigFromSource( - uint256 sourceChainId, - address sourceAddress, - uint32 newConfigCount, - address[] memory signers, - bytes32[] memory offchainTransmitters, - uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig, - Common.AddressAndWeight[] memory recipientAddressesAndWeights - ) external; - - /** - * @notice Activates the configuration for a config digest - * @param configDigest The config digest to activate - * @dev This function can be called by the contract admin to activate a configuration. - */ - function activateConfig(bytes32 configDigest) external; - - /** - * @notice Deactivates the configuration for a config digest - * @param configDigest The config digest to deactivate - * @dev This function can be called by the contract admin to deactivate an incorrect configuration. - */ - function deactivateConfig(bytes32 configDigest) external; - - /** - * @notice Activates the given feed - * @param feedId Feed ID to activated - * @dev This function can be called by the contract admin to activate a feed - */ - function activateFeed(bytes32 feedId) external; - - /** - * @notice Deactivates the given feed - * @param feedId Feed ID to deactivated - * @dev This function can be called by the contract admin to deactivate a feed - */ - function deactivateFeed(bytes32 feedId) external; - - /** - * @notice returns the latest config digest and epoch - * @return scanLogs indicates whether to rely on the configDigest and epoch - * returned or whether to scan logs for the Transmitted event instead. - * @return configDigest - * @return epoch - */ - function latestConfigDigestAndEpoch() external view returns (bool scanLogs, bytes32 configDigest, uint32 epoch); - - /** - * @notice information about current offchain reporting protocol configuration - * @return configCount ordinal number of current config, out of all configs applied to this contract so far - * @return blockNumber block at which this config was set - * @return configDigest domain-separation tag for current config - */ - function latestConfigDetails() external view returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest); -} diff --git a/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelVerifier.sol b/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelVerifier.sol deleted file mode 100644 index 650b3b4a81..0000000000 --- a/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelVerifier.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.19; - -// ExposedChannelVerifier exposes certain internal Verifier -// methods/structures so that golang code can access them, and we get -// reliable type checking on their usage -contract ExposedChannelVerifier { - constructor() {} - - function _configDigestFromConfigData( - uint256 chainId, - address contractAddress, - uint64 configCount, - address[] memory signers, - bytes32[] memory offchainTransmitters, - uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig - ) internal pure returns (bytes32) { - uint256 h = uint256( - keccak256( - abi.encode( - chainId, - contractAddress, - configCount, - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig - ) - ) - ); - uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 - // 0x0009 corresponds to ConfigDigestPrefixLLO in libocr - uint256 prefix = 0x0009 << (256 - 16); // 0x000900..00 - return bytes32((prefix & prefixMask) | (h & ~prefixMask)); - } - - function exposedConfigDigestFromConfigData( - uint256 _chainId, - address _contractAddress, - uint64 _configCount, - address[] memory _signers, - bytes32[] memory _offchainTransmitters, - uint8 _f, - bytes calldata _onchainConfig, - uint64 _encodedConfigVersion, - bytes memory _encodedConfig - ) public pure returns (bytes32) { - return - _configDigestFromConfigData( - _chainId, - _contractAddress, - _configCount, - _signers, - _offchainTransmitters, - _f, - _onchainConfig, - _encodedConfigVersion, - _encodedConfig - ); - } -} diff --git a/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedVerifier.sol b/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedVerifier.sol deleted file mode 100644 index 1c004bf384..0000000000 --- a/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedVerifier.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.19; - -// ExposedVerifier exposes certain internal Verifier -// methods/structures so that golang code can access them, and we get -// reliable type checking on their usage -contract ExposedVerifier { - constructor() {} - - function _configDigestFromConfigData( - bytes32 feedId, - uint256 chainId, - address contractAddress, - uint64 configCount, - address[] memory signers, - bytes32[] memory offchainTransmitters, - uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig - ) internal pure returns (bytes32) { - uint256 h = uint256( - keccak256( - abi.encode( - feedId, - chainId, - contractAddress, - configCount, - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig - ) - ) - ); - uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 - uint256 prefix = 0x0006 << (256 - 16); // 0x000600..00 - return bytes32((prefix & prefixMask) | (h & ~prefixMask)); - } - - function exposedConfigDigestFromConfigData( - bytes32 _feedId, - uint256 _chainId, - address _contractAddress, - uint64 _configCount, - address[] memory _signers, - bytes32[] memory _offchainTransmitters, - uint8 _f, - bytes calldata _onchainConfig, - uint64 _encodedConfigVersion, - bytes memory _encodedConfig - ) public pure returns (bytes32) { - return - _configDigestFromConfigData( - _feedId, - _chainId, - _contractAddress, - _configCount, - _signers, - _offchainTransmitters, - _f, - _onchainConfig, - _encodedConfigVersion, - _encodedConfig - ); - } -} diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IConfigurator.sol b/contracts/src/v0.8/llo-feeds/interfaces/IConfigurator.sol new file mode 100644 index 0000000000..478afa918c --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/interfaces/IConfigurator.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +interface IConfigurator { + /// @notice This event is emitted whenever a new configuration is set for a feed. It triggers a new run of the offchain reporting protocol. + event ConfigSet( + bytes32 indexed configId, + uint32 previousConfigBlockNumber, + bytes32 configDigest, + uint64 configCount, + address[] signers, + bytes32[] offchainTransmitters, + uint8 f, + bytes onchainConfig, + uint64 offchainConfigVersion, + bytes offchainConfig + ); + + function setConfig( + bytes32 configId, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external; +} diff --git a/contracts/src/v0.8/llo-feeds/dev/ChannelConfigStore.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/ChannelConfigStore.sol similarity index 86% rename from contracts/src/v0.8/llo-feeds/dev/ChannelConfigStore.sol rename to contracts/src/v0.8/llo-feeds/v0.5.0/configuration/ChannelConfigStore.sol index 086379b210..f5e5040bb8 100644 --- a/contracts/src/v0.8/llo-feeds/dev/ChannelConfigStore.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/ChannelConfigStore.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.19; -import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; import {IChannelConfigStore} from "./interfaces/IChannelConfigStore.sol"; -import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; contract ChannelConfigStore is ConfirmedOwner, IChannelConfigStore, TypeAndVersionInterface { event NewChannelDefinition(uint256 indexed donId, uint32 version, string url, bytes32 sha); diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/Configurator.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/Configurator.sol new file mode 100644 index 0000000000..5945f7ab73 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/Configurator.sol @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; +import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {IConfigurator} from "../../interfaces/IConfigurator.sol"; + +// OCR2 standard +uint256 constant MAX_NUM_ORACLES = 31; + +/** + * @title Configurator + * @author samsondav + * @notice This contract is intended to be deployed on the source chain and acts as a OCR3 configurator for LLO/Mercury + **/ + +contract Configurator is IConfigurator, ConfirmedOwner, TypeAndVersionInterface, IERC165 { + /// @notice This error is thrown whenever trying to set a config + /// with a fault tolerance of 0 + error FaultToleranceMustBePositive(); + + /// @notice This error is thrown whenever a report is signed + /// with more than the max number of signers + /// @param numSigners The number of signers who have signed the report + /// @param maxSigners The maximum number of signers that can sign a report + error ExcessSigners(uint256 numSigners, uint256 maxSigners); + + /// @notice This error is thrown whenever a report is signed + /// with less than the minimum number of signers + /// @param numSigners The number of signers who have signed the report + /// @param minSigners The minimum number of signers that need to sign a report + error InsufficientSigners(uint256 numSigners, uint256 minSigners); + + struct ConfigurationState { + // The number of times a new configuration + // has been set + uint64 configCount; + // The block number of the block the last time + /// the configuration was updated. + uint32 latestConfigBlockNumber; + } + + constructor() ConfirmedOwner(msg.sender) {} + + /// @notice Configuration states keyed on DON ID + mapping(bytes32 => ConfigurationState) internal s_configurationStates; + + /// @inheritdoc IConfigurator + function setConfig( + bytes32 donId, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external override checkConfigValid(signers.length, f) onlyOwner { + _setConfig( + donId, + block.chainid, + address(this), + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + } + + /// @notice Sets config based on the given arguments + /// @param donId DON ID to set config for + /// @param sourceChainId Chain ID of source config + /// @param sourceAddress Address of source config Verifier + /// @param signers addresses with which oracles sign the reports + /// @param offchainTransmitters CSA key for the ith Oracle + /// @param f number of faulty oracles the system can tolerate + /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) + /// @param offchainConfigVersion version number for offchainEncoding schema + /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + function _setConfig( + bytes32 donId, + uint256 sourceChainId, + address sourceAddress, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal { + ConfigurationState storage configurationState = s_configurationStates[donId]; + + uint64 newConfigCount = ++configurationState.configCount; + + bytes32 configDigest = _configDigestFromConfigData( + donId, + sourceChainId, + sourceAddress, + newConfigCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + + emit ConfigSet( + donId, + configurationState.latestConfigBlockNumber, + configDigest, + newConfigCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + + configurationState.latestConfigBlockNumber = uint32(block.number); + } + + /// @notice Generates the config digest from config data + /// @param donId DON ID to set config for + /// @param sourceChainId Chain ID of configurator contract + /// @param sourceAddress Address of configurator contract + /// @param configCount ordinal number of this config setting among all config settings over the life of this contract + /// @param signers ith element is address ith oracle uses to sign a report + /// @param offchainTransmitters ith element is address ith oracle used to transmit reports (in this case used for flexible additional field, such as CSA pub keys) + /// @param f maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly + /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) + /// @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter + /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + /// @dev This function is a modified version of the method from OCR2Abstract + function _configDigestFromConfigData( + bytes32 donId, + uint256 sourceChainId, + address sourceAddress, + uint64 configCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + donId, + sourceChainId, + sourceAddress, + configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + // 0x0006 corresponds to ConfigDigestPrefixLLO in libocr + uint256 prefix = 0x0009 << (256 - 16); // 0x000900..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + /// @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) external pure override returns (bool isVerifier) { + return interfaceId == type(IConfigurator).interfaceId; + } + + /// @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "Configurator 0.4.0"; + } + + modifier checkConfigValid(uint256 numSigners, uint256 f) { + if (f == 0) revert FaultToleranceMustBePositive(); + if (numSigners > MAX_NUM_ORACLES) revert ExcessSigners(numSigners, MAX_NUM_ORACLES); + if (numSigners <= 3 * f) revert InsufficientSigners(numSigners, 3 * f + 1); + _; + } +} diff --git a/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/interfaces/IChannelConfigStore.sol similarity index 64% rename from contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol rename to contracts/src/v0.8/llo-feeds/v0.5.0/configuration/interfaces/IChannelConfigStore.sol index 873928b6de..8628e3c1d5 100644 --- a/contracts/src/v0.8/llo-feeds/dev/interfaces/IChannelConfigStore.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/interfaces/IChannelConfigStore.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; interface IChannelConfigStore is IERC165 { function setChannelDefinitions(uint32 donId, string calldata url, bytes32 sha) external; diff --git a/contracts/src/v0.8/llo-feeds/dev/test/ChannelConfigStore.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/test/ChannelConfigStore.t.sol similarity index 100% rename from contracts/src/v0.8/llo-feeds/dev/test/ChannelConfigStore.t.sol rename to contracts/src/v0.8/llo-feeds/v0.5.0/configuration/test/ChannelConfigStore.t.sol diff --git a/contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelConfigStore.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/test/mocks/ExposedChannelConfigStore.sol similarity index 100% rename from contracts/src/v0.8/llo-feeds/dev/test/mocks/ExposedChannelConfigStore.sol rename to contracts/src/v0.8/llo-feeds/v0.5.0/configuration/test/mocks/ExposedChannelConfigStore.sol diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/test/mocks/ExposedConfigurator.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/test/mocks/ExposedConfigurator.sol new file mode 100644 index 0000000000..7b1370a846 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/test/mocks/ExposedConfigurator.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {Configurator} from "../../Configurator.sol"; + +// Exposed ChannelConfigStore exposes certain internal ChannelConfigStore +// methods/structures so that golang code can access them, and we get +// reliable type checking on their usage +contract ExposedConfigurator is Configurator { + constructor() {} + + function exposedReadConfigurationStates(bytes32 donId) public view returns (ConfigurationState memory) { + return s_configurationStates[donId]; + } +} diff --git a/core/gethwrappers/llo-feeds/generated/channel_verifier/channel_verifier.go b/core/gethwrappers/llo-feeds/generated/channel_verifier/channel_verifier.go deleted file mode 100644 index 104cab6104..0000000000 --- a/core/gethwrappers/llo-feeds/generated/channel_verifier/channel_verifier.go +++ /dev/null @@ -1,1583 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package channel_verifier - -import ( - "errors" - "fmt" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" -) - -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -type CommonAddressAndWeight struct { - Addr common.Address - Weight uint64 -} - -var ChannelVerifierMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierProxyAddr\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"CannotDeactivateLatestConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DigestEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeedIdEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"InactiveFeed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expectedNumSigners\",\"type\":\"uint256\"}],\"name\":\"IncorrectSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"MismatchedSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"FeedActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"FeedDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"ReportVerified\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"activateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"activateFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"deactivateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"deactivateFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"sourceChainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sourceAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"newConfigCount\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfigFromSource\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isVerifier\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signedReport\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"verifierResponse\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620020ed380380620020ed8339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051611ef9620001f4600039600061051a0152611ef96000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063564a0a7a1161008c5780638da5cb5b116100665780638da5cb5b14610247578063afcb95d71461026f578063eb1dc803146102a4578063f2fde38b146102b757600080fd5b8063564a0a7a146101fc57806379ba50971461020f57806381ff70481461021757600080fd5b8063181f5a77116100c8578063181f5a77146101815780633d3ac1b5146101c35780633dd86430146101d657806354e68a81146101e957600080fd5b806301ffc9a7146100ef5780630d1d79af146101595780630f672ef41461016e575b600080fd5b6101446100fd3660046113d0565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61016c610167366004611419565b6102ca565b005b61016c61017c366004611419565b6103d0565b60408051808201909152601581527f4368616e6e656c566572696669657220302e302e30000000000000000000000060208201525b6040516101509190611496565b6101b66101d13660046114d2565b610500565b61016c6101e4366004611419565b610680565b61016c6101f7366004611866565b6106fd565b61016c61020a366004611419565b61080d565b61016c61088d565b6002546003546040805163ffffffff80851682526401000000009094049093166020840152820152606001610150565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610150565b600354600254604080516000815260208101939093526801000000000000000090910463ffffffff1690820152606001610150565b61016c6102b2366004611986565b61098a565b61016c6102c5366004611a79565b610a52565b6102d2610a63565b80610309576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526005602052604081205460ff16900361035b576040517f74eb4b93000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b6000818152600560205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055517fa543797a0501218bba8a3daf75a71c8df8d1a7f791f4e44d40e43b6450183cea906103c59083815260200190565b60405180910390a150565b6103d8610a63565b8061040f576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526005602052604081205460ff16900361045c576040517f74eb4b9300000000000000000000000000000000000000000000000000000000815260048101829052602401610352565b600354810361049a576040517f67863f4400000000000000000000000000000000000000000000000000000000815260048101829052602401610352565b6000818152600560205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055517f5bfaab86edc1b932e3c334327a591c9ded067cb521abae19b95ca927d6076579906103c59083815260200190565b60603373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610571576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080610583888a018a611a94565b9450945094509450945060008461059990611b6f565b60008181526004602052604090205490915060ff16156105e8576040517f36dbe74800000000000000000000000000000000000000000000000000000000815260048101829052602401610352565b8551600081815260056020526040902061060482878784610ae6565b61060f886002610bda565b86516020880120610624818a89898987610c42565b60405173ffffffffffffffffffffffffffffffffffffffff8c16815284907f58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc59060200160405180910390a250959b9a5050505050505050505050565b610688610a63565b60008181526004602052604090205460ff166106fa5760008181526004602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555182917ff438564f793525caa89c6e3a26d41e16aa39d1e589747595751e3f3df75cb2b491a25b50565b86518560ff168060000361073d576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115610782576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f6024820152604401610352565b61078d816003611c12565b82116107e5578161079f826003611c12565b6107aa906001611c2f565b6040517f9dd9e6d800000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610352565b6107ed610a63565b6107ff8c8c8c8c8c8c8c8c8c8c610ebe565b505050505050505050505050565b610815610a63565b60008181526004602052604090205460ff16156106fa5760008181526004602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917ffc4f79b8c65b6be1773063461984c0974400d1e99654c79477a092ace83fd06191a250565b60015473ffffffffffffffffffffffffffffffffffffffff16331461090e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610352565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b86518560ff16806000036109ca576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115610a0f576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f6024820152604401610352565b610a1a816003611c12565b8211610a2c578161079f826003611c12565b610a34610a63565b610a47463060008c8c8c8c8c8c8c610ebe565b505050505050505050565b610a5a610a63565b6106fa81611230565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610352565b565b8054600090610af99060ff166001611c42565b8254909150610100900460ff16610b3f576040517fd990d62100000000000000000000000000000000000000000000000000000000815260048101869052602401610352565b8060ff16845114610b8b5783516040517f5348a282000000000000000000000000000000000000000000000000000000008152600481019190915260ff82166024820152604401610352565b8251845114610bd357835183516040517ff0d3140800000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610352565b5050505050565b6020820151815463ffffffff600883901c81169168010000000000000000900416811115610c3c5782547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000063ffffffff8316021783555b50505050565b60008686604051602001610c57929190611c5b565b6040516020818303038152906040528051906020012090506000610c8b604080518082019091526000808252602082015290565b8651600090815b81811015610e5657600186898360208110610caf57610caf611bb4565b610cbc91901a601b611c42565b8c8481518110610cce57610cce611bb4565b60200260200101518c8581518110610ce857610ce8611bb4565b602002602001015160405160008152602001604052604051610d26949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610d48573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526001808d01602090815291859020848601909552845460ff808216865293995093955090850192610100900490911690811115610dcd57610dcd611c97565b6001811115610dde57610dde611c97565b9052509350600184602001516001811115610dfb57610dfb611c97565b14610e32576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015160080260ff166001901b8501945080610e4f90611cc6565b9050610c92565b50837e01010101010101010101010101010101010101010101010101010101010101851614610eb1576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050565b63ffffffff881615610eff57600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8a16179055610f35565b6002805463ffffffff16906000610f1583611cfe565b91906101000a81548163ffffffff021916908363ffffffff160217905550505b600254600090610f54908c908c9063ffffffff168b8b8b8b8b8b611325565b600081815260056020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8a16176101001790559091505b88518160ff16101561118f576000898260ff1681518110610fb857610fb8611bb4565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611028576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600085815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452600190810190925290912054610100900460ff169081111561107957611079611c97565b14801591506110b4576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff841681526020810160019052600085815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684526001908101835292208351815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00821681178355928501519193919284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216179061010090849081111561117457611174611c97565b021790555090505050508061118890611d21565b9050610f95565b506002546040517f1074b4b9a073f79bd1f7f5c808348125ce0f25c27188df7efcaa7a08276051b3916111e29163ffffffff640100000000830481169286929116908d908d908d908d908d908d90611dc1565b60405180910390a1600280547fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff1664010000000063ffffffff43160217905560035550505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036112af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610352565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808a8a8a8a8a8a8a8a8a60405160200161134999989796959493929190611e57565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e09000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6000602082840312156113e257600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461141257600080fd5b9392505050565b60006020828403121561142b57600080fd5b5035919050565b6000815180845260005b818110156114585760208185018101518683018201520161143c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006114126020830184611432565b803573ffffffffffffffffffffffffffffffffffffffff811681146114cd57600080fd5b919050565b6000806000604084860312156114e757600080fd5b833567ffffffffffffffff808211156114ff57600080fd5b818601915086601f83011261151357600080fd5b81358181111561152257600080fd5b87602082850101111561153457600080fd5b60209283019550935061154a91860190506114a9565b90509250925092565b803563ffffffff811681146114cd57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156115b9576115b9611567565b60405290565b6040516060810167ffffffffffffffff811182821017156115b9576115b9611567565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561162957611629611567565b604052919050565b600067ffffffffffffffff82111561164b5761164b611567565b5060051b60200190565b600082601f83011261166657600080fd5b8135602061167b61167683611631565b6115e2565b82815260059290921b8401810191818101908684111561169a57600080fd5b8286015b848110156116bc576116af816114a9565b835291830191830161169e565b509695505050505050565b600082601f8301126116d857600080fd5b813560206116e861167683611631565b82815260059290921b8401810191818101908684111561170757600080fd5b8286015b848110156116bc578035835291830191830161170b565b803560ff811681146114cd57600080fd5b600082601f83011261174457600080fd5b813567ffffffffffffffff81111561175e5761175e611567565b61178f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016115e2565b8181528460208386010111156117a457600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146114cd57600080fd5b600082601f8301126117ea57600080fd5b813560206117fa61167683611631565b82815260069290921b8401810191818101908684111561181957600080fd5b8286015b848110156116bc57604081890312156118365760008081fd5b61183e611596565b611847826114a9565b81526118548583016117c1565b8186015283529183019160400161181d565b6000806000806000806000806000806101408b8d03121561188657600080fd5b8a35995061189660208c016114a9565b98506118a460408c01611553565b975060608b013567ffffffffffffffff808211156118c157600080fd5b6118cd8e838f01611655565b985060808d01359150808211156118e357600080fd5b6118ef8e838f016116c7565b97506118fd60a08e01611722565b965060c08d013591508082111561191357600080fd5b61191f8e838f01611733565b955061192d60e08e016117c1565b94506101008d013591508082111561194457600080fd5b6119508e838f01611733565b93506101208d013591508082111561196757600080fd5b506119748d828e016117d9565b9150509295989b9194979a5092959850565b600080600080600080600060e0888a0312156119a157600080fd5b873567ffffffffffffffff808211156119b957600080fd5b6119c58b838c01611655565b985060208a01359150808211156119db57600080fd5b6119e78b838c016116c7565b97506119f560408b01611722565b965060608a0135915080821115611a0b57600080fd5b611a178b838c01611733565b9550611a2560808b016117c1565b945060a08a0135915080821115611a3b57600080fd5b611a478b838c01611733565b935060c08a0135915080821115611a5d57600080fd5b50611a6a8a828b016117d9565b91505092959891949750929550565b600060208284031215611a8b57600080fd5b611412826114a9565b600080600080600060e08688031215611aac57600080fd5b86601f870112611abb57600080fd5b611ac36115bf565b806060880189811115611ad557600080fd5b885b81811015611aef578035845260209384019301611ad7565b5090965035905067ffffffffffffffff80821115611b0c57600080fd5b611b1889838a01611733565b95506080880135915080821115611b2e57600080fd5b611b3a89838a016116c7565b945060a0880135915080821115611b5057600080fd5b50611b5d888289016116c7565b9598949750929560c001359392505050565b80516020808301519190811015611bae577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611c2957611c29611be3565b92915050565b80820180821115611c2957611c29611be3565b60ff8181168382160190811115611c2957611c29611be3565b828152600060208083018460005b6003811015611c8657815183529183019190830190600101611c69565b505050506080820190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611cf757611cf7611be3565b5060010190565b600063ffffffff808316818103611d1757611d17611be3565b6001019392505050565b600060ff821660ff8103611d3757611d37611be3565b60010192915050565b600081518084526020808501945080840160005b83811015611d8657815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101611d54565b509495945050505050565b600081518084526020808501945080840160005b83811015611d8657815187529582019590820190600101611da5565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152611df18184018a611d40565b90508281036080840152611e058189611d91565b905060ff871660a084015282810360c0840152611e228187611432565b905067ffffffffffffffff851660e0840152828103610100840152611e478185611432565b9c9b505050505050505050505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152611e9e8285018b611d40565b91508382036080850152611eb2828a611d91565b915060ff881660a085015283820360c0850152611ecf8288611432565b90861660e08501528381036101008501529050611e47818561143256fea164736f6c6343000813000a", -} - -var ChannelVerifierABI = ChannelVerifierMetaData.ABI - -var ChannelVerifierBin = ChannelVerifierMetaData.Bin - -func DeployChannelVerifier(auth *bind.TransactOpts, backend bind.ContractBackend, verifierProxyAddr common.Address) (common.Address, *types.Transaction, *ChannelVerifier, error) { - parsed, err := ChannelVerifierMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ChannelVerifierBin), backend, verifierProxyAddr) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &ChannelVerifier{address: address, abi: *parsed, ChannelVerifierCaller: ChannelVerifierCaller{contract: contract}, ChannelVerifierTransactor: ChannelVerifierTransactor{contract: contract}, ChannelVerifierFilterer: ChannelVerifierFilterer{contract: contract}}, nil -} - -type ChannelVerifier struct { - address common.Address - abi abi.ABI - ChannelVerifierCaller - ChannelVerifierTransactor - ChannelVerifierFilterer -} - -type ChannelVerifierCaller struct { - contract *bind.BoundContract -} - -type ChannelVerifierTransactor struct { - contract *bind.BoundContract -} - -type ChannelVerifierFilterer struct { - contract *bind.BoundContract -} - -type ChannelVerifierSession struct { - Contract *ChannelVerifier - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type ChannelVerifierCallerSession struct { - Contract *ChannelVerifierCaller - CallOpts bind.CallOpts -} - -type ChannelVerifierTransactorSession struct { - Contract *ChannelVerifierTransactor - TransactOpts bind.TransactOpts -} - -type ChannelVerifierRaw struct { - Contract *ChannelVerifier -} - -type ChannelVerifierCallerRaw struct { - Contract *ChannelVerifierCaller -} - -type ChannelVerifierTransactorRaw struct { - Contract *ChannelVerifierTransactor -} - -func NewChannelVerifier(address common.Address, backend bind.ContractBackend) (*ChannelVerifier, error) { - abi, err := abi.JSON(strings.NewReader(ChannelVerifierABI)) - if err != nil { - return nil, err - } - contract, err := bindChannelVerifier(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &ChannelVerifier{address: address, abi: abi, ChannelVerifierCaller: ChannelVerifierCaller{contract: contract}, ChannelVerifierTransactor: ChannelVerifierTransactor{contract: contract}, ChannelVerifierFilterer: ChannelVerifierFilterer{contract: contract}}, nil -} - -func NewChannelVerifierCaller(address common.Address, caller bind.ContractCaller) (*ChannelVerifierCaller, error) { - contract, err := bindChannelVerifier(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ChannelVerifierCaller{contract: contract}, nil -} - -func NewChannelVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*ChannelVerifierTransactor, error) { - contract, err := bindChannelVerifier(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ChannelVerifierTransactor{contract: contract}, nil -} - -func NewChannelVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*ChannelVerifierFilterer, error) { - contract, err := bindChannelVerifier(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ChannelVerifierFilterer{contract: contract}, nil -} - -func bindChannelVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := ChannelVerifierMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_ChannelVerifier *ChannelVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ChannelVerifier.Contract.ChannelVerifierCaller.contract.Call(opts, result, method, params...) -} - -func (_ChannelVerifier *ChannelVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ChannelVerifier.Contract.ChannelVerifierTransactor.contract.Transfer(opts) -} - -func (_ChannelVerifier *ChannelVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ChannelVerifier.Contract.ChannelVerifierTransactor.contract.Transact(opts, method, params...) -} - -func (_ChannelVerifier *ChannelVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ChannelVerifier.Contract.contract.Call(opts, result, method, params...) -} - -func (_ChannelVerifier *ChannelVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ChannelVerifier.Contract.contract.Transfer(opts) -} - -func (_ChannelVerifier *ChannelVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ChannelVerifier.Contract.contract.Transact(opts, method, params...) -} - -func (_ChannelVerifier *ChannelVerifierCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, - - error) { - var out []interface{} - err := _ChannelVerifier.contract.Call(opts, &out, "latestConfigDetails") - - outstruct := new(LatestConfigDetails) - if err != nil { - return *outstruct, err - } - - outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) - outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) - outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) - - return *outstruct, err - -} - -func (_ChannelVerifier *ChannelVerifierSession) LatestConfigDetails() (LatestConfigDetails, - - error) { - return _ChannelVerifier.Contract.LatestConfigDetails(&_ChannelVerifier.CallOpts) -} - -func (_ChannelVerifier *ChannelVerifierCallerSession) LatestConfigDetails() (LatestConfigDetails, - - error) { - return _ChannelVerifier.Contract.LatestConfigDetails(&_ChannelVerifier.CallOpts) -} - -func (_ChannelVerifier *ChannelVerifierCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, - - error) { - var out []interface{} - err := _ChannelVerifier.contract.Call(opts, &out, "latestConfigDigestAndEpoch") - - outstruct := new(LatestConfigDigestAndEpoch) - if err != nil { - return *outstruct, err - } - - outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) - outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) - outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) - - return *outstruct, err - -} - -func (_ChannelVerifier *ChannelVerifierSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, - - error) { - return _ChannelVerifier.Contract.LatestConfigDigestAndEpoch(&_ChannelVerifier.CallOpts) -} - -func (_ChannelVerifier *ChannelVerifierCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, - - error) { - return _ChannelVerifier.Contract.LatestConfigDigestAndEpoch(&_ChannelVerifier.CallOpts) -} - -func (_ChannelVerifier *ChannelVerifierCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _ChannelVerifier.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -func (_ChannelVerifier *ChannelVerifierSession) Owner() (common.Address, error) { - return _ChannelVerifier.Contract.Owner(&_ChannelVerifier.CallOpts) -} - -func (_ChannelVerifier *ChannelVerifierCallerSession) Owner() (common.Address, error) { - return _ChannelVerifier.Contract.Owner(&_ChannelVerifier.CallOpts) -} - -func (_ChannelVerifier *ChannelVerifierCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { - var out []interface{} - err := _ChannelVerifier.contract.Call(opts, &out, "supportsInterface", interfaceId) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_ChannelVerifier *ChannelVerifierSession) SupportsInterface(interfaceId [4]byte) (bool, error) { - return _ChannelVerifier.Contract.SupportsInterface(&_ChannelVerifier.CallOpts, interfaceId) -} - -func (_ChannelVerifier *ChannelVerifierCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { - return _ChannelVerifier.Contract.SupportsInterface(&_ChannelVerifier.CallOpts, interfaceId) -} - -func (_ChannelVerifier *ChannelVerifierCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _ChannelVerifier.contract.Call(opts, &out, "typeAndVersion") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -func (_ChannelVerifier *ChannelVerifierSession) TypeAndVersion() (string, error) { - return _ChannelVerifier.Contract.TypeAndVersion(&_ChannelVerifier.CallOpts) -} - -func (_ChannelVerifier *ChannelVerifierCallerSession) TypeAndVersion() (string, error) { - return _ChannelVerifier.Contract.TypeAndVersion(&_ChannelVerifier.CallOpts) -} - -func (_ChannelVerifier *ChannelVerifierTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ChannelVerifier.contract.Transact(opts, "acceptOwnership") -} - -func (_ChannelVerifier *ChannelVerifierSession) AcceptOwnership() (*types.Transaction, error) { - return _ChannelVerifier.Contract.AcceptOwnership(&_ChannelVerifier.TransactOpts) -} - -func (_ChannelVerifier *ChannelVerifierTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _ChannelVerifier.Contract.AcceptOwnership(&_ChannelVerifier.TransactOpts) -} - -func (_ChannelVerifier *ChannelVerifierTransactor) ActivateConfig(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) { - return _ChannelVerifier.contract.Transact(opts, "activateConfig", configDigest) -} - -func (_ChannelVerifier *ChannelVerifierSession) ActivateConfig(configDigest [32]byte) (*types.Transaction, error) { - return _ChannelVerifier.Contract.ActivateConfig(&_ChannelVerifier.TransactOpts, configDigest) -} - -func (_ChannelVerifier *ChannelVerifierTransactorSession) ActivateConfig(configDigest [32]byte) (*types.Transaction, error) { - return _ChannelVerifier.Contract.ActivateConfig(&_ChannelVerifier.TransactOpts, configDigest) -} - -func (_ChannelVerifier *ChannelVerifierTransactor) ActivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) { - return _ChannelVerifier.contract.Transact(opts, "activateFeed", feedId) -} - -func (_ChannelVerifier *ChannelVerifierSession) ActivateFeed(feedId [32]byte) (*types.Transaction, error) { - return _ChannelVerifier.Contract.ActivateFeed(&_ChannelVerifier.TransactOpts, feedId) -} - -func (_ChannelVerifier *ChannelVerifierTransactorSession) ActivateFeed(feedId [32]byte) (*types.Transaction, error) { - return _ChannelVerifier.Contract.ActivateFeed(&_ChannelVerifier.TransactOpts, feedId) -} - -func (_ChannelVerifier *ChannelVerifierTransactor) DeactivateConfig(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) { - return _ChannelVerifier.contract.Transact(opts, "deactivateConfig", configDigest) -} - -func (_ChannelVerifier *ChannelVerifierSession) DeactivateConfig(configDigest [32]byte) (*types.Transaction, error) { - return _ChannelVerifier.Contract.DeactivateConfig(&_ChannelVerifier.TransactOpts, configDigest) -} - -func (_ChannelVerifier *ChannelVerifierTransactorSession) DeactivateConfig(configDigest [32]byte) (*types.Transaction, error) { - return _ChannelVerifier.Contract.DeactivateConfig(&_ChannelVerifier.TransactOpts, configDigest) -} - -func (_ChannelVerifier *ChannelVerifierTransactor) DeactivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) { - return _ChannelVerifier.contract.Transact(opts, "deactivateFeed", feedId) -} - -func (_ChannelVerifier *ChannelVerifierSession) DeactivateFeed(feedId [32]byte) (*types.Transaction, error) { - return _ChannelVerifier.Contract.DeactivateFeed(&_ChannelVerifier.TransactOpts, feedId) -} - -func (_ChannelVerifier *ChannelVerifierTransactorSession) DeactivateFeed(feedId [32]byte) (*types.Transaction, error) { - return _ChannelVerifier.Contract.DeactivateFeed(&_ChannelVerifier.TransactOpts, feedId) -} - -func (_ChannelVerifier *ChannelVerifierTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { - return _ChannelVerifier.contract.Transact(opts, "setConfig", signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) -} - -func (_ChannelVerifier *ChannelVerifierSession) SetConfig(signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { - return _ChannelVerifier.Contract.SetConfig(&_ChannelVerifier.TransactOpts, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) -} - -func (_ChannelVerifier *ChannelVerifierTransactorSession) SetConfig(signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { - return _ChannelVerifier.Contract.SetConfig(&_ChannelVerifier.TransactOpts, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) -} - -func (_ChannelVerifier *ChannelVerifierTransactor) SetConfigFromSource(opts *bind.TransactOpts, sourceChainId *big.Int, sourceAddress common.Address, newConfigCount uint32, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { - return _ChannelVerifier.contract.Transact(opts, "setConfigFromSource", sourceChainId, sourceAddress, newConfigCount, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) -} - -func (_ChannelVerifier *ChannelVerifierSession) SetConfigFromSource(sourceChainId *big.Int, sourceAddress common.Address, newConfigCount uint32, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { - return _ChannelVerifier.Contract.SetConfigFromSource(&_ChannelVerifier.TransactOpts, sourceChainId, sourceAddress, newConfigCount, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) -} - -func (_ChannelVerifier *ChannelVerifierTransactorSession) SetConfigFromSource(sourceChainId *big.Int, sourceAddress common.Address, newConfigCount uint32, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { - return _ChannelVerifier.Contract.SetConfigFromSource(&_ChannelVerifier.TransactOpts, sourceChainId, sourceAddress, newConfigCount, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) -} - -func (_ChannelVerifier *ChannelVerifierTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _ChannelVerifier.contract.Transact(opts, "transferOwnership", to) -} - -func (_ChannelVerifier *ChannelVerifierSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _ChannelVerifier.Contract.TransferOwnership(&_ChannelVerifier.TransactOpts, to) -} - -func (_ChannelVerifier *ChannelVerifierTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _ChannelVerifier.Contract.TransferOwnership(&_ChannelVerifier.TransactOpts, to) -} - -func (_ChannelVerifier *ChannelVerifierTransactor) Verify(opts *bind.TransactOpts, signedReport []byte, sender common.Address) (*types.Transaction, error) { - return _ChannelVerifier.contract.Transact(opts, "verify", signedReport, sender) -} - -func (_ChannelVerifier *ChannelVerifierSession) Verify(signedReport []byte, sender common.Address) (*types.Transaction, error) { - return _ChannelVerifier.Contract.Verify(&_ChannelVerifier.TransactOpts, signedReport, sender) -} - -func (_ChannelVerifier *ChannelVerifierTransactorSession) Verify(signedReport []byte, sender common.Address) (*types.Transaction, error) { - return _ChannelVerifier.Contract.Verify(&_ChannelVerifier.TransactOpts, signedReport, sender) -} - -type ChannelVerifierConfigActivatedIterator struct { - Event *ChannelVerifierConfigActivated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *ChannelVerifierConfigActivatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierConfigActivated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierConfigActivated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *ChannelVerifierConfigActivatedIterator) Error() error { - return it.fail -} - -func (it *ChannelVerifierConfigActivatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type ChannelVerifierConfigActivated struct { - ConfigDigest [32]byte - Raw types.Log -} - -func (_ChannelVerifier *ChannelVerifierFilterer) FilterConfigActivated(opts *bind.FilterOpts) (*ChannelVerifierConfigActivatedIterator, error) { - - logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "ConfigActivated") - if err != nil { - return nil, err - } - return &ChannelVerifierConfigActivatedIterator{contract: _ChannelVerifier.contract, event: "ConfigActivated", logs: logs, sub: sub}, nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) WatchConfigActivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierConfigActivated) (event.Subscription, error) { - - logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "ConfigActivated") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(ChannelVerifierConfigActivated) - if err := _ChannelVerifier.contract.UnpackLog(event, "ConfigActivated", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) ParseConfigActivated(log types.Log) (*ChannelVerifierConfigActivated, error) { - event := new(ChannelVerifierConfigActivated) - if err := _ChannelVerifier.contract.UnpackLog(event, "ConfigActivated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type ChannelVerifierConfigDeactivatedIterator struct { - Event *ChannelVerifierConfigDeactivated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *ChannelVerifierConfigDeactivatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierConfigDeactivated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierConfigDeactivated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *ChannelVerifierConfigDeactivatedIterator) Error() error { - return it.fail -} - -func (it *ChannelVerifierConfigDeactivatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type ChannelVerifierConfigDeactivated struct { - ConfigDigest [32]byte - Raw types.Log -} - -func (_ChannelVerifier *ChannelVerifierFilterer) FilterConfigDeactivated(opts *bind.FilterOpts) (*ChannelVerifierConfigDeactivatedIterator, error) { - - logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "ConfigDeactivated") - if err != nil { - return nil, err - } - return &ChannelVerifierConfigDeactivatedIterator{contract: _ChannelVerifier.contract, event: "ConfigDeactivated", logs: logs, sub: sub}, nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) WatchConfigDeactivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierConfigDeactivated) (event.Subscription, error) { - - logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "ConfigDeactivated") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(ChannelVerifierConfigDeactivated) - if err := _ChannelVerifier.contract.UnpackLog(event, "ConfigDeactivated", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) ParseConfigDeactivated(log types.Log) (*ChannelVerifierConfigDeactivated, error) { - event := new(ChannelVerifierConfigDeactivated) - if err := _ChannelVerifier.contract.UnpackLog(event, "ConfigDeactivated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type ChannelVerifierConfigSetIterator struct { - Event *ChannelVerifierConfigSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *ChannelVerifierConfigSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierConfigSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierConfigSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *ChannelVerifierConfigSetIterator) Error() error { - return it.fail -} - -func (it *ChannelVerifierConfigSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type ChannelVerifierConfigSet struct { - PreviousConfigBlockNumber uint32 - ConfigDigest [32]byte - ConfigCount uint64 - Signers []common.Address - OffchainTransmitters [][32]byte - F uint8 - OnchainConfig []byte - OffchainConfigVersion uint64 - OffchainConfig []byte - Raw types.Log -} - -func (_ChannelVerifier *ChannelVerifierFilterer) FilterConfigSet(opts *bind.FilterOpts) (*ChannelVerifierConfigSetIterator, error) { - - logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "ConfigSet") - if err != nil { - return nil, err - } - return &ChannelVerifierConfigSetIterator{contract: _ChannelVerifier.contract, event: "ConfigSet", logs: logs, sub: sub}, nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *ChannelVerifierConfigSet) (event.Subscription, error) { - - logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "ConfigSet") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(ChannelVerifierConfigSet) - if err := _ChannelVerifier.contract.UnpackLog(event, "ConfigSet", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) ParseConfigSet(log types.Log) (*ChannelVerifierConfigSet, error) { - event := new(ChannelVerifierConfigSet) - if err := _ChannelVerifier.contract.UnpackLog(event, "ConfigSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type ChannelVerifierFeedActivatedIterator struct { - Event *ChannelVerifierFeedActivated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *ChannelVerifierFeedActivatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierFeedActivated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierFeedActivated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *ChannelVerifierFeedActivatedIterator) Error() error { - return it.fail -} - -func (it *ChannelVerifierFeedActivatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type ChannelVerifierFeedActivated struct { - FeedId [32]byte - Raw types.Log -} - -func (_ChannelVerifier *ChannelVerifierFilterer) FilterFeedActivated(opts *bind.FilterOpts, feedId [][32]byte) (*ChannelVerifierFeedActivatedIterator, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "FeedActivated", feedIdRule) - if err != nil { - return nil, err - } - return &ChannelVerifierFeedActivatedIterator{contract: _ChannelVerifier.contract, event: "FeedActivated", logs: logs, sub: sub}, nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) WatchFeedActivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierFeedActivated, feedId [][32]byte) (event.Subscription, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "FeedActivated", feedIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(ChannelVerifierFeedActivated) - if err := _ChannelVerifier.contract.UnpackLog(event, "FeedActivated", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) ParseFeedActivated(log types.Log) (*ChannelVerifierFeedActivated, error) { - event := new(ChannelVerifierFeedActivated) - if err := _ChannelVerifier.contract.UnpackLog(event, "FeedActivated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type ChannelVerifierFeedDeactivatedIterator struct { - Event *ChannelVerifierFeedDeactivated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *ChannelVerifierFeedDeactivatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierFeedDeactivated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierFeedDeactivated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *ChannelVerifierFeedDeactivatedIterator) Error() error { - return it.fail -} - -func (it *ChannelVerifierFeedDeactivatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type ChannelVerifierFeedDeactivated struct { - FeedId [32]byte - Raw types.Log -} - -func (_ChannelVerifier *ChannelVerifierFilterer) FilterFeedDeactivated(opts *bind.FilterOpts, feedId [][32]byte) (*ChannelVerifierFeedDeactivatedIterator, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "FeedDeactivated", feedIdRule) - if err != nil { - return nil, err - } - return &ChannelVerifierFeedDeactivatedIterator{contract: _ChannelVerifier.contract, event: "FeedDeactivated", logs: logs, sub: sub}, nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) WatchFeedDeactivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierFeedDeactivated, feedId [][32]byte) (event.Subscription, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "FeedDeactivated", feedIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(ChannelVerifierFeedDeactivated) - if err := _ChannelVerifier.contract.UnpackLog(event, "FeedDeactivated", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) ParseFeedDeactivated(log types.Log) (*ChannelVerifierFeedDeactivated, error) { - event := new(ChannelVerifierFeedDeactivated) - if err := _ChannelVerifier.contract.UnpackLog(event, "FeedDeactivated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type ChannelVerifierOwnershipTransferRequestedIterator struct { - Event *ChannelVerifierOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *ChannelVerifierOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierOwnershipTransferRequested) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierOwnershipTransferRequested) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *ChannelVerifierOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *ChannelVerifierOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type ChannelVerifierOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_ChannelVerifier *ChannelVerifierFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ChannelVerifierOwnershipTransferRequestedIterator, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &ChannelVerifierOwnershipTransferRequestedIterator{contract: _ChannelVerifier.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ChannelVerifierOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(ChannelVerifierOwnershipTransferRequested) - if err := _ChannelVerifier.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) ParseOwnershipTransferRequested(log types.Log) (*ChannelVerifierOwnershipTransferRequested, error) { - event := new(ChannelVerifierOwnershipTransferRequested) - if err := _ChannelVerifier.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type ChannelVerifierOwnershipTransferredIterator struct { - Event *ChannelVerifierOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *ChannelVerifierOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *ChannelVerifierOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *ChannelVerifierOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type ChannelVerifierOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_ChannelVerifier *ChannelVerifierFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ChannelVerifierOwnershipTransferredIterator, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return &ChannelVerifierOwnershipTransferredIterator{contract: _ChannelVerifier.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ChannelVerifierOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(ChannelVerifierOwnershipTransferred) - if err := _ChannelVerifier.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) ParseOwnershipTransferred(log types.Log) (*ChannelVerifierOwnershipTransferred, error) { - event := new(ChannelVerifierOwnershipTransferred) - if err := _ChannelVerifier.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type ChannelVerifierReportVerifiedIterator struct { - Event *ChannelVerifierReportVerified - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *ChannelVerifierReportVerifiedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierReportVerified) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(ChannelVerifierReportVerified) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *ChannelVerifierReportVerifiedIterator) Error() error { - return it.fail -} - -func (it *ChannelVerifierReportVerifiedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type ChannelVerifierReportVerified struct { - FeedId [32]byte - Requester common.Address - Raw types.Log -} - -func (_ChannelVerifier *ChannelVerifierFilterer) FilterReportVerified(opts *bind.FilterOpts, feedId [][32]byte) (*ChannelVerifierReportVerifiedIterator, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _ChannelVerifier.contract.FilterLogs(opts, "ReportVerified", feedIdRule) - if err != nil { - return nil, err - } - return &ChannelVerifierReportVerifiedIterator{contract: _ChannelVerifier.contract, event: "ReportVerified", logs: logs, sub: sub}, nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) WatchReportVerified(opts *bind.WatchOpts, sink chan<- *ChannelVerifierReportVerified, feedId [][32]byte) (event.Subscription, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _ChannelVerifier.contract.WatchLogs(opts, "ReportVerified", feedIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(ChannelVerifierReportVerified) - if err := _ChannelVerifier.contract.UnpackLog(event, "ReportVerified", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_ChannelVerifier *ChannelVerifierFilterer) ParseReportVerified(log types.Log) (*ChannelVerifierReportVerified, error) { - event := new(ChannelVerifierReportVerified) - if err := _ChannelVerifier.contract.UnpackLog(event, "ReportVerified", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type LatestConfigDetails struct { - ConfigCount uint32 - BlockNumber uint32 - ConfigDigest [32]byte -} -type LatestConfigDigestAndEpoch struct { - ScanLogs bool - ConfigDigest [32]byte - Epoch uint32 -} - -func (_ChannelVerifier *ChannelVerifier) ParseLog(log types.Log) (generated.AbigenLog, error) { - switch log.Topics[0] { - case _ChannelVerifier.abi.Events["ConfigActivated"].ID: - return _ChannelVerifier.ParseConfigActivated(log) - case _ChannelVerifier.abi.Events["ConfigDeactivated"].ID: - return _ChannelVerifier.ParseConfigDeactivated(log) - case _ChannelVerifier.abi.Events["ConfigSet"].ID: - return _ChannelVerifier.ParseConfigSet(log) - case _ChannelVerifier.abi.Events["FeedActivated"].ID: - return _ChannelVerifier.ParseFeedActivated(log) - case _ChannelVerifier.abi.Events["FeedDeactivated"].ID: - return _ChannelVerifier.ParseFeedDeactivated(log) - case _ChannelVerifier.abi.Events["OwnershipTransferRequested"].ID: - return _ChannelVerifier.ParseOwnershipTransferRequested(log) - case _ChannelVerifier.abi.Events["OwnershipTransferred"].ID: - return _ChannelVerifier.ParseOwnershipTransferred(log) - case _ChannelVerifier.abi.Events["ReportVerified"].ID: - return _ChannelVerifier.ParseReportVerified(log) - - default: - return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) - } -} - -func (ChannelVerifierConfigActivated) Topic() common.Hash { - return common.HexToHash("0xa543797a0501218bba8a3daf75a71c8df8d1a7f791f4e44d40e43b6450183cea") -} - -func (ChannelVerifierConfigDeactivated) Topic() common.Hash { - return common.HexToHash("0x5bfaab86edc1b932e3c334327a591c9ded067cb521abae19b95ca927d6076579") -} - -func (ChannelVerifierConfigSet) Topic() common.Hash { - return common.HexToHash("0x1074b4b9a073f79bd1f7f5c808348125ce0f25c27188df7efcaa7a08276051b3") -} - -func (ChannelVerifierFeedActivated) Topic() common.Hash { - return common.HexToHash("0xf438564f793525caa89c6e3a26d41e16aa39d1e589747595751e3f3df75cb2b4") -} - -func (ChannelVerifierFeedDeactivated) Topic() common.Hash { - return common.HexToHash("0xfc4f79b8c65b6be1773063461984c0974400d1e99654c79477a092ace83fd061") -} - -func (ChannelVerifierOwnershipTransferRequested) Topic() common.Hash { - return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") -} - -func (ChannelVerifierOwnershipTransferred) Topic() common.Hash { - return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") -} - -func (ChannelVerifierReportVerified) Topic() common.Hash { - return common.HexToHash("0x58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc5") -} - -func (_ChannelVerifier *ChannelVerifier) Address() common.Address { - return _ChannelVerifier.address -} - -type ChannelVerifierInterface interface { - LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, - - error) - - LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, - - error) - - Owner(opts *bind.CallOpts) (common.Address, error) - - SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) - - TypeAndVersion(opts *bind.CallOpts) (string, error) - - AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - - ActivateConfig(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) - - ActivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) - - DeactivateConfig(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) - - DeactivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) - - SetConfig(opts *bind.TransactOpts, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) - - SetConfigFromSource(opts *bind.TransactOpts, sourceChainId *big.Int, sourceAddress common.Address, newConfigCount uint32, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) - - TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - Verify(opts *bind.TransactOpts, signedReport []byte, sender common.Address) (*types.Transaction, error) - - FilterConfigActivated(opts *bind.FilterOpts) (*ChannelVerifierConfigActivatedIterator, error) - - WatchConfigActivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierConfigActivated) (event.Subscription, error) - - ParseConfigActivated(log types.Log) (*ChannelVerifierConfigActivated, error) - - FilterConfigDeactivated(opts *bind.FilterOpts) (*ChannelVerifierConfigDeactivatedIterator, error) - - WatchConfigDeactivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierConfigDeactivated) (event.Subscription, error) - - ParseConfigDeactivated(log types.Log) (*ChannelVerifierConfigDeactivated, error) - - FilterConfigSet(opts *bind.FilterOpts) (*ChannelVerifierConfigSetIterator, error) - - WatchConfigSet(opts *bind.WatchOpts, sink chan<- *ChannelVerifierConfigSet) (event.Subscription, error) - - ParseConfigSet(log types.Log) (*ChannelVerifierConfigSet, error) - - FilterFeedActivated(opts *bind.FilterOpts, feedId [][32]byte) (*ChannelVerifierFeedActivatedIterator, error) - - WatchFeedActivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierFeedActivated, feedId [][32]byte) (event.Subscription, error) - - ParseFeedActivated(log types.Log) (*ChannelVerifierFeedActivated, error) - - FilterFeedDeactivated(opts *bind.FilterOpts, feedId [][32]byte) (*ChannelVerifierFeedDeactivatedIterator, error) - - WatchFeedDeactivated(opts *bind.WatchOpts, sink chan<- *ChannelVerifierFeedDeactivated, feedId [][32]byte) (event.Subscription, error) - - ParseFeedDeactivated(log types.Log) (*ChannelVerifierFeedDeactivated, error) - - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ChannelVerifierOwnershipTransferRequestedIterator, error) - - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ChannelVerifierOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferRequested(log types.Log) (*ChannelVerifierOwnershipTransferRequested, error) - - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ChannelVerifierOwnershipTransferredIterator, error) - - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ChannelVerifierOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferred(log types.Log) (*ChannelVerifierOwnershipTransferred, error) - - FilterReportVerified(opts *bind.FilterOpts, feedId [][32]byte) (*ChannelVerifierReportVerifiedIterator, error) - - WatchReportVerified(opts *bind.WatchOpts, sink chan<- *ChannelVerifierReportVerified, feedId [][32]byte) (event.Subscription, error) - - ParseReportVerified(log types.Log) (*ChannelVerifierReportVerified, error) - - ParseLog(log types.Log) (generated.AbigenLog, error) - - Address() common.Address -} diff --git a/core/gethwrappers/llo-feeds/generated/configurator/configurator.go b/core/gethwrappers/llo-feeds/generated/configurator/configurator.go new file mode 100644 index 0000000000..3e6f1c7e2d --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/configurator/configurator.go @@ -0,0 +1,748 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package configurator + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var ConfiguratorMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isVerifier\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610d21806101576000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c806379ba50971161005057806379ba5097146101355780638da5cb5b1461013d578063f2fde38b1461016557600080fd5b806301ffc9a714610077578063181f5a77146100e157806344a0b2ad14610120575b600080fd5b6100cc6100853660046106c9565b7fffffffff00000000000000000000000000000000000000000000000000000000167f44a0b2ad000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b604080518082018252601281527f436f6e666967757261746f7220302e342e300000000000000000000000000000602082015290516100d89190610776565b61013361012e3660046109d8565b610178565b005b610133610289565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100d8565b610133610173366004610ab0565b610386565b85518460ff16806000036101b8576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115610202576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044015b60405180910390fd5b61020d816003610afa565b8211610265578161021f826003610afa565b61022a906001610b17565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016101f9565b61026d61039a565b61027e8946308b8b8b8b8b8b61041d565b505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461030a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016101f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61038e61039a565b61039781610526565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461041b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016101f9565b565b60008981526002602052604081208054909190829082906104479067ffffffffffffffff16610b2a565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055905060006104828c8c8c858d8d8d8d8d8d61061b565b90508b7fa23a88453230b183877098801ff5a8f771a120e2573eea559ce6c4c2e305a4da8460000160089054906101000a900463ffffffff1683858d8d8d8d8d8d6040516104d899989796959493929190610bd2565b60405180910390a2505080547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff16680100000000000000004363ffffffff1602179055505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036105a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016101f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808b8b8b8b8b8b8b8b8b8b6040516020016106419a99989796959493929190610c67565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e09000000000000000000000000000000000000000000000000000000000000179150509a9950505050505050505050565b6000602082840312156106db57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461070b57600080fd5b9392505050565b6000815180845260005b818110156107385760208185018101518683018201520161071c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061070b6020830184610712565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156107ff576107ff610789565b604052919050565b600067ffffffffffffffff82111561082157610821610789565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff8116811461084f57600080fd5b919050565b600082601f83011261086557600080fd5b8135602061087a61087583610807565b6107b8565b82815260059290921b8401810191818101908684111561089957600080fd5b8286015b848110156108bb576108ae8161082b565b835291830191830161089d565b509695505050505050565b600082601f8301126108d757600080fd5b813560206108e761087583610807565b82815260059290921b8401810191818101908684111561090657600080fd5b8286015b848110156108bb578035835291830191830161090a565b803560ff8116811461084f57600080fd5b600082601f83011261094357600080fd5b813567ffffffffffffffff81111561095d5761095d610789565b61098e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016107b8565b8181528460208386010111156109a357600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff8116811461084f57600080fd5b600080600080600080600060e0888a0312156109f357600080fd5b87359650602088013567ffffffffffffffff80821115610a1257600080fd5b610a1e8b838c01610854565b975060408a0135915080821115610a3457600080fd5b610a408b838c016108c6565b9650610a4e60608b01610921565b955060808a0135915080821115610a6457600080fd5b610a708b838c01610932565b9450610a7e60a08b016109c0565b935060c08a0135915080821115610a9457600080fd5b50610aa18a828b01610932565b91505092959891949750929550565b600060208284031215610ac257600080fd5b61070b8261082b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610b1157610b11610acb565b92915050565b80820180821115610b1157610b11610acb565b600067ffffffffffffffff808316818103610b4757610b47610acb565b6001019392505050565b600081518084526020808501945080840160005b83811015610b9757815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101610b65565b509495945050505050565b600081518084526020808501945080840160005b83811015610b9757815187529582019590820190600101610bb6565b600061012063ffffffff8c1683528a602084015267ffffffffffffffff808b166040850152816060850152610c098285018b610b51565b91508382036080850152610c1d828a610ba2565b915060ff881660a085015283820360c0850152610c3a8288610712565b90861660e08501528381036101008501529050610c578185610712565b9c9b505050505050505050505050565b60006101408c83528b602084015273ffffffffffffffffffffffffffffffffffffffff8b16604084015267ffffffffffffffff808b166060850152816080850152610cb48285018b610b51565b915083820360a0850152610cc8828a610ba2565b915060ff881660c085015283820360e0850152610ce58288610712565b9086166101008501528381036101208501529050610d038185610712565b9d9c5050505050505050505050505056fea164736f6c6343000813000a", +} + +var ConfiguratorABI = ConfiguratorMetaData.ABI + +var ConfiguratorBin = ConfiguratorMetaData.Bin + +func DeployConfigurator(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Configurator, error) { + parsed, err := ConfiguratorMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ConfiguratorBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Configurator{address: address, abi: *parsed, ConfiguratorCaller: ConfiguratorCaller{contract: contract}, ConfiguratorTransactor: ConfiguratorTransactor{contract: contract}, ConfiguratorFilterer: ConfiguratorFilterer{contract: contract}}, nil +} + +type Configurator struct { + address common.Address + abi abi.ABI + ConfiguratorCaller + ConfiguratorTransactor + ConfiguratorFilterer +} + +type ConfiguratorCaller struct { + contract *bind.BoundContract +} + +type ConfiguratorTransactor struct { + contract *bind.BoundContract +} + +type ConfiguratorFilterer struct { + contract *bind.BoundContract +} + +type ConfiguratorSession struct { + Contract *Configurator + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ConfiguratorCallerSession struct { + Contract *ConfiguratorCaller + CallOpts bind.CallOpts +} + +type ConfiguratorTransactorSession struct { + Contract *ConfiguratorTransactor + TransactOpts bind.TransactOpts +} + +type ConfiguratorRaw struct { + Contract *Configurator +} + +type ConfiguratorCallerRaw struct { + Contract *ConfiguratorCaller +} + +type ConfiguratorTransactorRaw struct { + Contract *ConfiguratorTransactor +} + +func NewConfigurator(address common.Address, backend bind.ContractBackend) (*Configurator, error) { + abi, err := abi.JSON(strings.NewReader(ConfiguratorABI)) + if err != nil { + return nil, err + } + contract, err := bindConfigurator(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Configurator{address: address, abi: abi, ConfiguratorCaller: ConfiguratorCaller{contract: contract}, ConfiguratorTransactor: ConfiguratorTransactor{contract: contract}, ConfiguratorFilterer: ConfiguratorFilterer{contract: contract}}, nil +} + +func NewConfiguratorCaller(address common.Address, caller bind.ContractCaller) (*ConfiguratorCaller, error) { + contract, err := bindConfigurator(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ConfiguratorCaller{contract: contract}, nil +} + +func NewConfiguratorTransactor(address common.Address, transactor bind.ContractTransactor) (*ConfiguratorTransactor, error) { + contract, err := bindConfigurator(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ConfiguratorTransactor{contract: contract}, nil +} + +func NewConfiguratorFilterer(address common.Address, filterer bind.ContractFilterer) (*ConfiguratorFilterer, error) { + contract, err := bindConfigurator(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ConfiguratorFilterer{contract: contract}, nil +} + +func bindConfigurator(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ConfiguratorMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_Configurator *ConfiguratorRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Configurator.Contract.ConfiguratorCaller.contract.Call(opts, result, method, params...) +} + +func (_Configurator *ConfiguratorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Configurator.Contract.ConfiguratorTransactor.contract.Transfer(opts) +} + +func (_Configurator *ConfiguratorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Configurator.Contract.ConfiguratorTransactor.contract.Transact(opts, method, params...) +} + +func (_Configurator *ConfiguratorCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Configurator.Contract.contract.Call(opts, result, method, params...) +} + +func (_Configurator *ConfiguratorTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Configurator.Contract.contract.Transfer(opts) +} + +func (_Configurator *ConfiguratorTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Configurator.Contract.contract.Transact(opts, method, params...) +} + +func (_Configurator *ConfiguratorCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Configurator.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_Configurator *ConfiguratorSession) Owner() (common.Address, error) { + return _Configurator.Contract.Owner(&_Configurator.CallOpts) +} + +func (_Configurator *ConfiguratorCallerSession) Owner() (common.Address, error) { + return _Configurator.Contract.Owner(&_Configurator.CallOpts) +} + +func (_Configurator *ConfiguratorCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _Configurator.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_Configurator *ConfiguratorSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _Configurator.Contract.SupportsInterface(&_Configurator.CallOpts, interfaceId) +} + +func (_Configurator *ConfiguratorCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _Configurator.Contract.SupportsInterface(&_Configurator.CallOpts, interfaceId) +} + +func (_Configurator *ConfiguratorCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _Configurator.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_Configurator *ConfiguratorSession) TypeAndVersion() (string, error) { + return _Configurator.Contract.TypeAndVersion(&_Configurator.CallOpts) +} + +func (_Configurator *ConfiguratorCallerSession) TypeAndVersion() (string, error) { + return _Configurator.Contract.TypeAndVersion(&_Configurator.CallOpts) +} + +func (_Configurator *ConfiguratorTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Configurator.contract.Transact(opts, "acceptOwnership") +} + +func (_Configurator *ConfiguratorSession) AcceptOwnership() (*types.Transaction, error) { + return _Configurator.Contract.AcceptOwnership(&_Configurator.TransactOpts) +} + +func (_Configurator *ConfiguratorTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _Configurator.Contract.AcceptOwnership(&_Configurator.TransactOpts) +} + +func (_Configurator *ConfiguratorTransactor) SetConfig(opts *bind.TransactOpts, donId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _Configurator.contract.Transact(opts, "setConfig", donId, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_Configurator *ConfiguratorSession) SetConfig(donId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _Configurator.Contract.SetConfig(&_Configurator.TransactOpts, donId, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_Configurator *ConfiguratorTransactorSession) SetConfig(donId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _Configurator.Contract.SetConfig(&_Configurator.TransactOpts, donId, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_Configurator *ConfiguratorTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _Configurator.contract.Transact(opts, "transferOwnership", to) +} + +func (_Configurator *ConfiguratorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _Configurator.Contract.TransferOwnership(&_Configurator.TransactOpts, to) +} + +func (_Configurator *ConfiguratorTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _Configurator.Contract.TransferOwnership(&_Configurator.TransactOpts, to) +} + +type ConfiguratorConfigSetIterator struct { + Event *ConfiguratorConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ConfiguratorConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ConfiguratorConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ConfiguratorConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ConfiguratorConfigSetIterator) Error() error { + return it.fail +} + +func (it *ConfiguratorConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ConfiguratorConfigSet struct { + ConfigId [32]byte + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + OffchainTransmitters [][32]byte + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_Configurator *ConfiguratorFilterer) FilterConfigSet(opts *bind.FilterOpts, configId [][32]byte) (*ConfiguratorConfigSetIterator, error) { + + var configIdRule []interface{} + for _, configIdItem := range configId { + configIdRule = append(configIdRule, configIdItem) + } + + logs, sub, err := _Configurator.contract.FilterLogs(opts, "ConfigSet", configIdRule) + if err != nil { + return nil, err + } + return &ConfiguratorConfigSetIterator{contract: _Configurator.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_Configurator *ConfiguratorFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *ConfiguratorConfigSet, configId [][32]byte) (event.Subscription, error) { + + var configIdRule []interface{} + for _, configIdItem := range configId { + configIdRule = append(configIdRule, configIdItem) + } + + logs, sub, err := _Configurator.contract.WatchLogs(opts, "ConfigSet", configIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ConfiguratorConfigSet) + if err := _Configurator.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Configurator *ConfiguratorFilterer) ParseConfigSet(log types.Log) (*ConfiguratorConfigSet, error) { + event := new(ConfiguratorConfigSet) + if err := _Configurator.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ConfiguratorOwnershipTransferRequestedIterator struct { + Event *ConfiguratorOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ConfiguratorOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ConfiguratorOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ConfiguratorOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ConfiguratorOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *ConfiguratorOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ConfiguratorOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_Configurator *ConfiguratorFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ConfiguratorOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Configurator.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &ConfiguratorOwnershipTransferRequestedIterator{contract: _Configurator.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_Configurator *ConfiguratorFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ConfiguratorOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Configurator.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ConfiguratorOwnershipTransferRequested) + if err := _Configurator.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Configurator *ConfiguratorFilterer) ParseOwnershipTransferRequested(log types.Log) (*ConfiguratorOwnershipTransferRequested, error) { + event := new(ConfiguratorOwnershipTransferRequested) + if err := _Configurator.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ConfiguratorOwnershipTransferredIterator struct { + Event *ConfiguratorOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ConfiguratorOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ConfiguratorOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(ConfiguratorOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *ConfiguratorOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *ConfiguratorOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ConfiguratorOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_Configurator *ConfiguratorFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ConfiguratorOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Configurator.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &ConfiguratorOwnershipTransferredIterator{contract: _Configurator.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_Configurator *ConfiguratorFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ConfiguratorOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Configurator.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ConfiguratorOwnershipTransferred) + if err := _Configurator.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Configurator *ConfiguratorFilterer) ParseOwnershipTransferred(log types.Log) (*ConfiguratorOwnershipTransferred, error) { + event := new(ConfiguratorOwnershipTransferred) + if err := _Configurator.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_Configurator *Configurator) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _Configurator.abi.Events["ConfigSet"].ID: + return _Configurator.ParseConfigSet(log) + case _Configurator.abi.Events["OwnershipTransferRequested"].ID: + return _Configurator.ParseOwnershipTransferRequested(log) + case _Configurator.abi.Events["OwnershipTransferred"].ID: + return _Configurator.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (ConfiguratorConfigSet) Topic() common.Hash { + return common.HexToHash("0xa23a88453230b183877098801ff5a8f771a120e2573eea559ce6c4c2e305a4da") +} + +func (ConfiguratorOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (ConfiguratorOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_Configurator *Configurator) Address() common.Address { + return _Configurator.address +} + +type ConfiguratorInterface interface { + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, donId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts, configId [][32]byte) (*ConfiguratorConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *ConfiguratorConfigSet, configId [][32]byte) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*ConfiguratorConfigSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ConfiguratorOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *ConfiguratorOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*ConfiguratorOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ConfiguratorOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ConfiguratorOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*ConfiguratorOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/exposed_channel_verifier/exposed_channel_verifier.go b/core/gethwrappers/llo-feeds/generated/exposed_channel_verifier/exposed_channel_verifier.go deleted file mode 100644 index e516b9a247..0000000000 --- a/core/gethwrappers/llo-feeds/generated/exposed_channel_verifier/exposed_channel_verifier.go +++ /dev/null @@ -1,202 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package exposed_channel_verifier - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -var ExposedChannelVerifierMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"_configCount\",\"type\":\"uint64\"},{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_encodedConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_encodedConfig\",\"type\":\"bytes\"}],\"name\":\"exposedConfigDigestFromConfigData\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061067e806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063b05a355014610030575b600080fd5b61004361003e3660046103f2565b610055565b60405190815260200160405180910390f35b60006100a08b8b8b8b8b8b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92508c91506100af9050565b9b9a5050505050505050505050565b6000808a8a8a8a8a8a8a8a8a6040516020016100d399989796959493929190610594565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e09000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461017e57600080fd5b919050565b803567ffffffffffffffff8116811461017e57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156102115761021161019b565b604052919050565b600067ffffffffffffffff8211156102335761023361019b565b5060051b60200190565b600082601f83011261024e57600080fd5b8135602061026361025e83610219565b6101ca565b82815260059290921b8401810191818101908684111561028257600080fd5b8286015b848110156102a4576102978161015a565b8352918301918301610286565b509695505050505050565b600082601f8301126102c057600080fd5b813560206102d061025e83610219565b82815260059290921b840181019181810190868411156102ef57600080fd5b8286015b848110156102a457803583529183019183016102f3565b803560ff8116811461017e57600080fd5b60008083601f84011261032d57600080fd5b50813567ffffffffffffffff81111561034557600080fd5b60208301915083602082850101111561035d57600080fd5b9250929050565b600082601f83011261037557600080fd5b813567ffffffffffffffff81111561038f5761038f61019b565b6103c060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016101ca565b8181528460208386010111156103d557600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806000806000806000806101208b8d03121561041257600080fd5b8a35995061042260208c0161015a565b985061043060408c01610183565b975060608b013567ffffffffffffffff8082111561044d57600080fd5b6104598e838f0161023d565b985060808d013591508082111561046f57600080fd5b61047b8e838f016102af565b975061048960a08e0161030a565b965060c08d013591508082111561049f57600080fd5b6104ab8e838f0161031b565b90965094508491506104bf60e08e01610183565b93506101008d01359150808211156104d657600080fd5b506104e38d828e01610364565b9150509295989b9194979a5092959850565b600081518084526020808501945080840160005b8381101561052557815187529582019590820190600101610509565b509495945050505050565b6000815180845260005b818110156105565760208185018101518683018201520161053a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60006101208083018c8452602073ffffffffffffffffffffffffffffffffffffffff808e168287015267ffffffffffffffff8d1660408701528360608701528293508b5180845261014087019450828d01935060005b818110156106085784518316865294830194938301936001016105ea565b5050505050828103608084015261061f81896104f5565b60ff881660a0850152905082810360c084015261063c8187610530565b67ffffffffffffffff861660e085015290508281036101008401526106618185610530565b9c9b50505050505050505050505056fea164736f6c6343000813000a", -} - -var ExposedChannelVerifierABI = ExposedChannelVerifierMetaData.ABI - -var ExposedChannelVerifierBin = ExposedChannelVerifierMetaData.Bin - -func DeployExposedChannelVerifier(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ExposedChannelVerifier, error) { - parsed, err := ExposedChannelVerifierMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ExposedChannelVerifierBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &ExposedChannelVerifier{address: address, abi: *parsed, ExposedChannelVerifierCaller: ExposedChannelVerifierCaller{contract: contract}, ExposedChannelVerifierTransactor: ExposedChannelVerifierTransactor{contract: contract}, ExposedChannelVerifierFilterer: ExposedChannelVerifierFilterer{contract: contract}}, nil -} - -type ExposedChannelVerifier struct { - address common.Address - abi abi.ABI - ExposedChannelVerifierCaller - ExposedChannelVerifierTransactor - ExposedChannelVerifierFilterer -} - -type ExposedChannelVerifierCaller struct { - contract *bind.BoundContract -} - -type ExposedChannelVerifierTransactor struct { - contract *bind.BoundContract -} - -type ExposedChannelVerifierFilterer struct { - contract *bind.BoundContract -} - -type ExposedChannelVerifierSession struct { - Contract *ExposedChannelVerifier - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type ExposedChannelVerifierCallerSession struct { - Contract *ExposedChannelVerifierCaller - CallOpts bind.CallOpts -} - -type ExposedChannelVerifierTransactorSession struct { - Contract *ExposedChannelVerifierTransactor - TransactOpts bind.TransactOpts -} - -type ExposedChannelVerifierRaw struct { - Contract *ExposedChannelVerifier -} - -type ExposedChannelVerifierCallerRaw struct { - Contract *ExposedChannelVerifierCaller -} - -type ExposedChannelVerifierTransactorRaw struct { - Contract *ExposedChannelVerifierTransactor -} - -func NewExposedChannelVerifier(address common.Address, backend bind.ContractBackend) (*ExposedChannelVerifier, error) { - abi, err := abi.JSON(strings.NewReader(ExposedChannelVerifierABI)) - if err != nil { - return nil, err - } - contract, err := bindExposedChannelVerifier(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &ExposedChannelVerifier{address: address, abi: abi, ExposedChannelVerifierCaller: ExposedChannelVerifierCaller{contract: contract}, ExposedChannelVerifierTransactor: ExposedChannelVerifierTransactor{contract: contract}, ExposedChannelVerifierFilterer: ExposedChannelVerifierFilterer{contract: contract}}, nil -} - -func NewExposedChannelVerifierCaller(address common.Address, caller bind.ContractCaller) (*ExposedChannelVerifierCaller, error) { - contract, err := bindExposedChannelVerifier(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ExposedChannelVerifierCaller{contract: contract}, nil -} - -func NewExposedChannelVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*ExposedChannelVerifierTransactor, error) { - contract, err := bindExposedChannelVerifier(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ExposedChannelVerifierTransactor{contract: contract}, nil -} - -func NewExposedChannelVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*ExposedChannelVerifierFilterer, error) { - contract, err := bindExposedChannelVerifier(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ExposedChannelVerifierFilterer{contract: contract}, nil -} - -func bindExposedChannelVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := ExposedChannelVerifierMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_ExposedChannelVerifier *ExposedChannelVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ExposedChannelVerifier.Contract.ExposedChannelVerifierCaller.contract.Call(opts, result, method, params...) -} - -func (_ExposedChannelVerifier *ExposedChannelVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ExposedChannelVerifier.Contract.ExposedChannelVerifierTransactor.contract.Transfer(opts) -} - -func (_ExposedChannelVerifier *ExposedChannelVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ExposedChannelVerifier.Contract.ExposedChannelVerifierTransactor.contract.Transact(opts, method, params...) -} - -func (_ExposedChannelVerifier *ExposedChannelVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ExposedChannelVerifier.Contract.contract.Call(opts, result, method, params...) -} - -func (_ExposedChannelVerifier *ExposedChannelVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ExposedChannelVerifier.Contract.contract.Transfer(opts) -} - -func (_ExposedChannelVerifier *ExposedChannelVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ExposedChannelVerifier.Contract.contract.Transact(opts, method, params...) -} - -func (_ExposedChannelVerifier *ExposedChannelVerifierCaller) ExposedConfigDigestFromConfigData(opts *bind.CallOpts, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { - var out []interface{} - err := _ExposedChannelVerifier.contract.Call(opts, &out, "exposedConfigDigestFromConfigData", _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -func (_ExposedChannelVerifier *ExposedChannelVerifierSession) ExposedConfigDigestFromConfigData(_chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { - return _ExposedChannelVerifier.Contract.ExposedConfigDigestFromConfigData(&_ExposedChannelVerifier.CallOpts, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) -} - -func (_ExposedChannelVerifier *ExposedChannelVerifierCallerSession) ExposedConfigDigestFromConfigData(_chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { - return _ExposedChannelVerifier.Contract.ExposedConfigDigestFromConfigData(&_ExposedChannelVerifier.CallOpts, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) -} - -func (_ExposedChannelVerifier *ExposedChannelVerifier) Address() common.Address { - return _ExposedChannelVerifier.address -} - -type ExposedChannelVerifierInterface interface { - ExposedConfigDigestFromConfigData(opts *bind.CallOpts, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) - - Address() common.Address -} diff --git a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt index b576628ef5..7d7d655ddc 100644 --- a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -2,6 +2,7 @@ GETH_VERSION: 1.13.8 channel_config_store: ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin 3fafe83ea21d50488f5533962f62683988ffa6fd1476dccbbb9040be2369cb37 channel_config_verifier_proxy: ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.abi ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.bin 655658e5f61dfadfe3268de04f948b7e690ad03ca45676e645d6cd6018154661 channel_verifier: ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.abi ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.bin e6020553bd8e3e6b250fcaffe7efd22aea955c8c1a0eb05d282fdeb0ab6550b7 +configurator: ../../../contracts/solc/v0.8.19/Configurator/Configurator.abi ../../../contracts/solc/v0.8.19/Configurator/Configurator.bin 75b9809e6e1cd00d1438028df3bbc7ce00d667dfd882a348081b4286edcdc4e0 destination_fee_manager: ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.abi ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.bin a56ae53e35e6610269f086b1e915ca1e80f5d0bf5695d09156e82fccfc2d77b3 destination_reward_manager: ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.abi ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.bin 77874e97a54ecbd9c61132964da5b053f0b584dc7b774d75dd51baedd2bc7c40 destination_verifier: ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.abi ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.bin 369323ce520923b9eb31ed90885f5ebd0f46b6799288fbf4da5d6ede7d697aef diff --git a/core/gethwrappers/llo-feeds/go_generate.go b/core/gethwrappers/llo-feeds/go_generate.go index 688b503cc1..ec950124e9 100644 --- a/core/gethwrappers/llo-feeds/go_generate.go +++ b/core/gethwrappers/llo-feeds/go_generate.go @@ -10,10 +10,9 @@ package gethwrappers //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/RewardManager/RewardManager.abi ../../../contracts/solc/v0.8.19/RewardManager/RewardManager.bin RewardManager reward_manager //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/FeeManager/FeeManager.abi ../../../contracts/solc/v0.8.19/FeeManager/FeeManager.bin FeeManager fee_manager //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin ChannelConfigStore channel_config_store -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.abi ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.bin ChannelVerifier channel_verifier -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.abi ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.bin ExposedChannelVerifier exposed_channel_verifier //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.abi ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.bin DestinationVerifier destination_verifier //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.abi ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.bin DestinationVerifierProxy destination_verifier_proxy //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.abi ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.bin DestinationFeeManager destination_fee_manager //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.abi ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.bin DestinationRewardManager destination_reward_manager +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/Configurator/Configurator.abi ../../../contracts/solc/v0.8.19/Configurator/Configurator.bin Configurator configurator diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 7447d1385f..371cada330 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -382,12 +382,14 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn LatestReportDeadline: cfg.Mercury().Cache().LatestReportDeadline(), }) + c := clhttptest.NewTestLocalOnlyHTTPClient() relayerFactory := chainlink.RelayerFactory{ Logger: lggr, LoopRegistry: loopRegistry, GRPCOpts: loop.GRPCOpts{}, MercuryPool: mercuryPool, CapabilitiesRegistry: capabilitiesRegistry, + HTTPClient: c, } evmOpts := chainlink.EVMFactoryConfig{ @@ -451,7 +453,6 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn if err != nil { t.Fatal(err) } - c := clhttptest.NewTestLocalOnlyHTTPClient() appInstance, err := chainlink.NewApplication(chainlink.ApplicationOpts{ Config: cfg, MailMon: mailMon, diff --git a/core/services/llo/evm/report_codec_premium_legacy_test.go b/core/services/llo/evm/report_codec_premium_legacy_test.go index c22d29c340..2b864af555 100644 --- a/core/services/llo/evm/report_codec_premium_legacy_test.go +++ b/core/services/llo/evm/report_codec_premium_legacy_test.go @@ -93,6 +93,31 @@ func Test_ReportCodecPremiumLegacy(t *testing.T) { }) }) + t.Run("uses zero values if fees are missing", func(t *testing.T) { + report := llo.Report{ + Values: []llo.StreamValue{nil, nil, &llo.Quote{Bid: decimal.NewFromInt(37), Benchmark: decimal.NewFromInt(38), Ask: decimal.NewFromInt(39)}}, + } + + encoded, err := rc.Encode(report, cd) + require.NoError(t, err) + + assert.Len(t, encoded, 288) + assert.Equal(t, []byte{0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x86}, encoded) + + decoded, err := rc.Decode(encoded) + require.NoError(t, err) + + assert.Equal(t, feedID, decoded.FeedId) + assert.Equal(t, uint32(0), decoded.ObservationsTimestamp) + assert.Equal(t, big.NewInt(380).String(), decoded.BenchmarkPrice.String()) + assert.Equal(t, big.NewInt(370).String(), decoded.Bid.String()) + assert.Equal(t, big.NewInt(390).String(), decoded.Ask.String()) + assert.Equal(t, uint32(1), decoded.ValidFromTimestamp) + assert.Equal(t, uint32(60), decoded.ExpiresAt) + assert.Equal(t, big.NewInt(0).String(), decoded.LinkFee.String()) + assert.Equal(t, big.NewInt(0).String(), decoded.NativeFee.String()) + }) + t.Run("Decode errors on invalid report", func(t *testing.T) { _, err := rc.Decode([]byte{1, 2, 3}) assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") diff --git a/core/services/llo/offchain_config_digester.go b/core/services/llo/offchain_config_digester.go deleted file mode 100644 index cd4d9afa3a..0000000000 --- a/core/services/llo/offchain_config_digester.go +++ /dev/null @@ -1,123 +0,0 @@ -package llo - -import ( - "crypto/ed25519" - "encoding/binary" - "encoding/hex" - "fmt" - "math/big" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/pkg/errors" - - "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/smartcontractkit/wsrpc/credentials" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/exposed_channel_verifier" -) - -// Originally sourced from: https://github.com/smartcontractkit/offchain-reporting/blob/991ebe1462fd56826a1ddfb34287d542acb2baee/lib/offchainreporting2/chains/evmutil/offchain_config_digester.go - -var _ ocrtypes.OffchainConfigDigester = OffchainConfigDigester{} - -func NewOffchainConfigDigester(chainID *big.Int, contractAddress common.Address) OffchainConfigDigester { - return OffchainConfigDigester{chainID, contractAddress} -} - -type OffchainConfigDigester struct { - ChainID *big.Int - ContractAddress common.Address -} - -func (d OffchainConfigDigester) ConfigDigest(cc ocrtypes.ContractConfig) (ocrtypes.ConfigDigest, error) { - signers := []common.Address{} - for i, signer := range cc.Signers { - if len(signer) != 20 { - return ocrtypes.ConfigDigest{}, errors.Errorf("%v-th evm signer should be a 20 byte address, but got %x", i, signer) - } - a := common.BytesToAddress(signer) - signers = append(signers, a) - } - transmitters := []credentials.StaticSizedPublicKey{} - for i, transmitter := range cc.Transmitters { - if len(transmitter) != 2*ed25519.PublicKeySize { - return ocrtypes.ConfigDigest{}, errors.Errorf("%v-th evm transmitter should be a 64 character hex-encoded ed25519 public key, but got '%v' (%d chars)", i, transmitter, len(transmitter)) - } - var t credentials.StaticSizedPublicKey - b, err := hex.DecodeString(string(transmitter)) - if err != nil { - return ocrtypes.ConfigDigest{}, errors.Wrapf(err, "%v-th evm transmitter is not valid hex, got: %q", i, transmitter) - } - copy(t[:], b) - - transmitters = append(transmitters, t) - } - - return configDigest( - d.ChainID, - d.ContractAddress, - cc.ConfigCount, - signers, - transmitters, - cc.F, - cc.OnchainConfig, - cc.OffchainConfigVersion, - cc.OffchainConfig, - ) -} - -func (d OffchainConfigDigester) ConfigDigestPrefix() (ocrtypes.ConfigDigestPrefix, error) { - return ocrtypes.ConfigDigestPrefixLLO, nil -} - -func makeConfigDigestArgs() abi.Arguments { - abi, err := abi.JSON(strings.NewReader(exposed_channel_verifier.ExposedChannelVerifierABI)) - if err != nil { - // assertion - panic(fmt.Sprintf("could not parse aggregator ABI: %s", err.Error())) - } - return abi.Methods["exposedConfigDigestFromConfigData"].Inputs -} - -var configDigestArgs = makeConfigDigestArgs() - -func configDigest( - chainID *big.Int, - contractAddress common.Address, - configCount uint64, - oracles []common.Address, - transmitters []credentials.StaticSizedPublicKey, - f uint8, - onchainConfig []byte, - offchainConfigVersion uint64, - offchainConfig []byte, -) (types.ConfigDigest, error) { - msg, err := configDigestArgs.Pack( - chainID, - contractAddress, - configCount, - oracles, - transmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig, - ) - if err != nil { - return types.ConfigDigest{}, fmt.Errorf("could not pack config digest args: %v", err) - } - rawHash := crypto.Keccak256(msg) - configDigest := types.ConfigDigest{} - if n := copy(configDigest[:], rawHash); n != len(configDigest) { - return types.ConfigDigest{}, fmt.Errorf("copied too little data: %d/%d", n, len(configDigest)) - } - binary.BigEndian.PutUint16(configDigest[:2], uint16(ocrtypes.ConfigDigestPrefixLLO)) - if !(configDigest[0] == 0 && configDigest[1] == 9) { - return types.ConfigDigest{}, fmt.Errorf("wrong ConfigDigestPrefix; got: %x, expected: %d", configDigest[:2], ocrtypes.ConfigDigestPrefixLLO) - } - return configDigest, nil -} diff --git a/core/services/llo/offchain_config_digester_test.go b/core/services/llo/offchain_config_digester_test.go deleted file mode 100644 index 0de9117e39..0000000000 --- a/core/services/llo/offchain_config_digester_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package llo - -import ( - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/stretchr/testify/require" -) - -func Test_OffchainConfigDigester_ConfigDigest(t *testing.T) { - // ChainID and ContractAddress are taken into account for computation - cd1, err := OffchainConfigDigester{ChainID: big.NewInt(0)}.ConfigDigest(types.ContractConfig{}) - require.NoError(t, err) - cd2, err := OffchainConfigDigester{ChainID: big.NewInt(0)}.ConfigDigest(types.ContractConfig{}) - require.NoError(t, err) - cd3, err := OffchainConfigDigester{ChainID: big.NewInt(1)}.ConfigDigest(types.ContractConfig{}) - require.NoError(t, err) - cd4, err := OffchainConfigDigester{ChainID: big.NewInt(1), ContractAddress: common.Address{1}}.ConfigDigest(types.ContractConfig{}) - require.NoError(t, err) - - require.Equal(t, cd1, cd2) - require.NotEqual(t, cd2, cd3) - require.NotEqual(t, cd2, cd4) - require.NotEqual(t, cd3, cd4) - - // malformed signers - _, err = OffchainConfigDigester{}.ConfigDigest(types.ContractConfig{ - Signers: []types.OnchainPublicKey{{1, 2}}, - }) - require.Error(t, err) - - // malformed transmitters - _, err = OffchainConfigDigester{}.ConfigDigest(types.ContractConfig{ - Transmitters: []types.Account{"0x"}, - }) - require.Error(t, err) - - _, err = OffchainConfigDigester{}.ConfigDigest(types.ContractConfig{ - Transmitters: []types.Account{"7343581f55146951b0f678dc6cfa8fd360e2f353"}, - }) - require.Error(t, err) - - _, err = OffchainConfigDigester{}.ConfigDigest(types.ContractConfig{ - Transmitters: []types.Account{"7343581f55146951b0f678dc6cfa8fd360e2f353aabbccddeeffaaccddeeffaz"}, - }) - require.Error(t, err) - - // well-formed transmitters - _, err = OffchainConfigDigester{ChainID: big.NewInt(0)}.ConfigDigest(types.ContractConfig{ - Transmitters: []types.Account{"7343581f55146951b0f678dc6cfa8fd360e2f353aabbccddeeffaaccddeeffaa"}, - }) - require.NoError(t, err) -} diff --git a/core/services/ocr2/plugins/llo/helpers_test.go b/core/services/ocr2/plugins/llo/helpers_test.go index 23a0cc7064..4097294ba0 100644 --- a/core/services/ocr2/plugins/llo/helpers_test.go +++ b/core/services/ocr2/plugins/llo/helpers_test.go @@ -14,11 +14,8 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/shopspring/decimal" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -29,16 +26,11 @@ import ( "github.com/smartcontractkit/wsrpc/credentials" "github.com/smartcontractkit/wsrpc/peer" - "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink/v2/core/bridges" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/destination_verifier" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/destination_verifier_proxy" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/keystest" @@ -50,7 +42,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" "github.com/smartcontractkit/chainlink/v2/core/services/streams" "github.com/smartcontractkit/chainlink/v2/core/store/models" @@ -69,14 +60,13 @@ func (r request) TransmitterID() ocr2types.Account { } type mercuryServer struct { - privKey ed25519.PrivateKey - reqsCh chan request - t *testing.T - buildReport func() []byte + privKey ed25519.PrivateKey + reqsCh chan request + t *testing.T } -func NewMercuryServer(t *testing.T, privKey ed25519.PrivateKey, reqsCh chan request, buildReport func() []byte) *mercuryServer { - return &mercuryServer{privKey, reqsCh, t, buildReport} +func NewMercuryServer(t *testing.T, privKey ed25519.PrivateKey, reqsCh chan request) *mercuryServer { + return &mercuryServer{privKey, reqsCh, t} } func (s *mercuryServer) Transmit(ctx context.Context, req *pb.TransmitRequest) (*pb.TransmitResponse, error) { @@ -94,23 +84,7 @@ func (s *mercuryServer) Transmit(ctx context.Context, req *pb.TransmitRequest) ( } func (s *mercuryServer) LatestReport(ctx context.Context, lrr *pb.LatestReportRequest) (*pb.LatestReportResponse, error) { - p, ok := peer.FromContext(ctx) - if !ok { - return nil, errors.New("could not extract public key") - } - s.t.Logf("mercury server got latest report from %x for feed id 0x%x", p.PublicKey, lrr.FeedId) - - out := new(pb.LatestReportResponse) - out.Report = new(pb.Report) - out.Report.FeedId = lrr.FeedId - - report := s.buildReport() - payload, err := mercury.PayloadTypes.Pack(evmutil.RawReportContext(ocrtypes.ReportContext{}), report, [][32]byte{}, [][32]byte{}, [32]byte{}) - if err != nil { - require.NoError(s.t, err) - } - out.Report.Payload = payload - return out, nil + panic("should not be called") } func startMercuryServer(t *testing.T, srv *mercuryServer, pubKeys []ed25519.PublicKey) (serverURL string) { @@ -184,6 +158,7 @@ func setupNode( config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { // [JobPipeline] c.JobPipeline.MaxSuccessfulRuns = ptr(uint64(0)) + c.JobPipeline.VerboseLogging = ptr(true) // [Feature] c.Feature.UICSAKeys = ptr(true) @@ -195,7 +170,7 @@ func setupNode( // [OCR2] c.OCR2.Enabled = ptr(true) - c.OCR2.ContractPollInterval = commonconfig.MustNewDuration(1 * time.Second) + c.OCR2.ContractPollInterval = commonconfig.MustNewDuration(100 * time.Millisecond) // [P2P] c.P2P.PeerID = ptr(p2pKey.PeerID()) @@ -207,6 +182,9 @@ func setupNode( c.P2P.V2.ListenAddresses = &p2paddresses c.P2P.V2.DeltaDial = commonconfig.MustNewDuration(500 * time.Millisecond) c.P2P.V2.DeltaReconcile = commonconfig.MustNewDuration(5 * time.Second) + + // [Mercury] + c.Mercury.VerboseLogging = ptr(true) }) lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.DebugLevel) @@ -294,7 +272,7 @@ observationSource = """ askBridgeName, )) } -func addBootstrapJob(t *testing.T, bootstrapNode Node, verifierAddress common.Address, name string, relayType, relayConfig string) { +func addBootstrapJob(t *testing.T, bootstrapNode Node, configuratorAddress common.Address, name string, relayType, relayConfig string) { bootstrapNode.AddBootstrapJob(t, fmt.Sprintf(` type = "bootstrap" relay = "%s" @@ -305,13 +283,13 @@ contractConfigTrackerPollInterval = "1s" [relayConfig] %s -providerType = "llo"`, relayType, name, verifierAddress.Hex(), relayConfig)) +providerType = "llo"`, relayType, name, configuratorAddress.Hex(), relayConfig)) } func addLLOJob( t *testing.T, node Node, - verifierAddress common.Address, + configuratorAddr common.Address, bootstrapPeerID string, bootstrapNodePort int, clientPubKey ed25519.PublicKey, @@ -342,7 +320,7 @@ transmitterID = "%x" [relayConfig] %s`, jobName, - verifierAddress.Hex(), + configuratorAddr.Hex(), node.KeyBundle.ID(), fmt.Sprintf("%s@127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), relayType, @@ -357,7 +335,7 @@ func addOCRJobs( streams []Stream, serverPubKey ed25519.PublicKey, serverURL string, - verifierAddress common.Address, + configuratorAddress common.Address, bootstrapPeerID string, bootstrapNodePort int, nodes []Node, @@ -382,7 +360,7 @@ func addOCRJobs( addLLOJob( t, node, - verifierAddress, + configuratorAddress, bootstrapPeerID, bootstrapNodePort, clientPubKeys[i], @@ -440,7 +418,7 @@ func addOCRJobsEVMPremiumLegacy( streams []Stream, serverPubKey ed25519.PublicKey, serverURL string, - verifierAddress common.Address, + configuratorAddress common.Address, bootstrapPeerID string, bootstrapNodePort int, nodes []Node, @@ -457,7 +435,7 @@ func addOCRJobsEVMPremiumLegacy( jobIDs[i] = make(map[uint32]int32) } for j, strm := range streams { - // assume that streams are native, link and quote + // assume that streams are native, link and additionals are quote if j < 2 { var name string if j == 0 { @@ -474,7 +452,7 @@ func addOCRJobsEVMPremiumLegacy( bmBridge, ) jobIDs[i][strm.id] = jobID - } else if j == 2 { + } else { bmBridge := createBridge(t, fmt.Sprintf("benchmarkprice-%d-%d", strm.id, j), i, strm.baseBenchmarkPrice, node.App.BridgeORM()) bidBridge := createBridge(t, fmt.Sprintf("bid-%d-%d", strm.id, j), i, strm.baseBid, node.App.BridgeORM()) askBridge := createBridge(t, fmt.Sprintf("ask-%d-%d", strm.id, j), i, strm.baseAsk, node.App.BridgeORM()) @@ -487,14 +465,12 @@ func addOCRJobsEVMPremiumLegacy( askBridge, ) jobIDs[i][strm.id] = jobID - } else { - panic("unexpected stream") } } addLLOJob( t, node, - verifierAddress, + configuratorAddress, bootstrapPeerID, bootstrapNodePort, clientPubKeys[i], @@ -506,27 +482,3 @@ func addOCRJobsEVMPremiumLegacy( } return jobIDs } - -func setupV03Blockchain(t *testing.T) (*bind.TransactOpts, *backends.SimulatedBackend, *destination_verifier.DestinationVerifier, *destination_verifier_proxy.DestinationVerifierProxy, common.Address) { - steve := testutils.MustNewSimTransactor(t) // config contract deployer and owner - genesisData := core.GenesisAlloc{steve.From: {Balance: assets.Ether(1000).ToInt()}} - backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) - backend.Commit() // ensure starting block number at least 1 - - // Deploy verifier proxy - verifierProxyAddr, _, verifierProxy, err := destination_verifier_proxy.DeployDestinationVerifierProxy(steve, backend) - require.NoError(t, err) - backend.Commit() - - // Deploy verifier - verifierAddress, _, verifier, err := destination_verifier.DeployDestinationVerifier(steve, backend, verifierProxyAddr) - require.NoError(t, err) - backend.Commit() - - // Set verifier on proxy - _, err = verifierProxy.SetVerifier(steve, verifierAddress) - require.NoError(t, err) - backend.Commit() - - return steve, backend, verifier, verifierProxy, verifierProxyAddr -} diff --git a/core/services/ocr2/plugins/llo/integration_test.go b/core/services/ocr2/plugins/llo/integration_test.go index 787946b6ad..4cebe3bf22 100644 --- a/core/services/ocr2/plugins/llo/integration_test.go +++ b/core/services/ocr2/plugins/llo/integration_test.go @@ -6,40 +6,45 @@ import ( "encoding/json" "fmt" "math/big" + "net/http" + "net/http/httptest" "strings" "testing" "time" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/hashicorp/consul/sdk/freeport" "github.com/shopspring/decimal" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" - "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" "github.com/smartcontractkit/libocr/offchainreporting2/types" "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/wsrpc/credentials" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" datastreamsllo "github.com/smartcontractkit/chainlink-data-streams/llo" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_config_store" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_verifier" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/configurator" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/destination_verifier" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier_proxy" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/destination_verifier_proxy" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" lloevm "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + mercury "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" + reportcodecv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" mercuryverifier "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/verifier" ) @@ -48,25 +53,34 @@ var ( nNodes = 4 // number of nodes (not including bootstrap) ) -func setupBlockchain(t *testing.T) (*bind.TransactOpts, *backends.SimulatedBackend, *channel_verifier.ChannelVerifier, common.Address, *channel_config_store.ChannelConfigStore, common.Address) { +func setupBlockchain(t *testing.T) (*bind.TransactOpts, *backends.SimulatedBackend, *configurator.Configurator, common.Address, *destination_verifier.DestinationVerifier, common.Address, *destination_verifier_proxy.DestinationVerifierProxy, common.Address, *channel_config_store.ChannelConfigStore, common.Address) { steve := testutils.MustNewSimTransactor(t) // config contract deployer and owner genesisData := core.GenesisAlloc{steve.From: {Balance: assets.Ether(1000).ToInt()}} backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) backend.Commit() backend.Commit() // ensure starting block number at least 1 - // Deploy contracts - verifierProxyAddr, _, _, err := verifier_proxy.DeployVerifierProxy(steve, backend, common.Address{}) // zero address for access controller disables access control + // Configurator + configuratorAddress, _, configurator, err := configurator.DeployConfigurator(steve, backend) require.NoError(t, err) - verifierAddress, _, verifierContract, err := channel_verifier.DeployChannelVerifier(steve, backend, verifierProxyAddr) + // DestinationVerifierProxy + verifierProxyAddr, _, verifierProxy, err := destination_verifier_proxy.DeployDestinationVerifierProxy(steve, backend) require.NoError(t, err) - configStoreAddress, _, configStoreContract, err := channel_config_store.DeployChannelConfigStore(steve, backend) + // DestinationVerifier + verifierAddr, _, verifier, err := destination_verifier.DeployDestinationVerifier(steve, backend, verifierProxyAddr) + require.NoError(t, err) + // AddVerifier + _, err = verifierProxy.SetVerifier(steve, verifierAddr) + require.NoError(t, err) + + // ChannelConfigStore + configStoreAddress, _, configStore, err := channel_config_store.DeployChannelConfigStore(steve, backend) require.NoError(t, err) backend.Commit() - return steve, backend, verifierContract, verifierAddress, configStoreContract, configStoreAddress + return steve, backend, configurator, configuratorAddress, verifier, verifierAddr, verifierProxy, verifierProxyAddr, configStore, configStoreAddress } type Stream struct { @@ -74,9 +88,22 @@ type Stream struct { baseBenchmarkPrice decimal.Decimal baseBid decimal.Decimal baseAsk decimal.Decimal + strmType string } +const ( + btcStreamID = 51 + ethStreamID = 52 + linkStreamID = 53 + dogeStreamID = 54 + quoteStreamID1 = 55 + quoteStreamID2 = 56 +) + var ( + quoteStreamFeedID1 = common.HexToHash(`0x0003111111111111111111111111111111111111111111111111111111111111`) + quoteStreamFeedID2 = common.HexToHash(`0x0003222222222222222222222222222222222222222222222222222222222222`) + btcStream = Stream{ id: 51, baseBenchmarkPrice: decimal.NewFromFloat32(56_114.41), @@ -93,12 +120,18 @@ var ( id: 54, baseBenchmarkPrice: decimal.NewFromFloat32(0.10960935), } - quoteStream = Stream{ + quoteStream1 = Stream{ id: 55, baseBenchmarkPrice: decimal.NewFromFloat32(1000.1212), baseBid: decimal.NewFromFloat32(998.5431), baseAsk: decimal.NewFromFloat32(1001.6999), } + quoteStream2 = Stream{ + id: 56, + baseBenchmarkPrice: decimal.NewFromFloat32(500.1212), + baseBid: decimal.NewFromFloat32(499.5431), + baseAsk: decimal.NewFromFloat32(502.6999), + } ) func generateConfig(t *testing.T, oracles []confighelper.OracleIdentityExtra) ( @@ -140,7 +173,7 @@ func generateConfig(t *testing.T, oracles []confighelper.OracleIdentityExtra) ( return } -func setConfig(t *testing.T, steve *bind.TransactOpts, backend *backends.SimulatedBackend, verifierContract *channel_verifier.ChannelVerifier, verifierAddress common.Address, nodes []Node, oracles []confighelper.OracleIdentityExtra) ocr2types.ConfigDigest { +func setConfig(t *testing.T, donID uint32, steve *bind.TransactOpts, backend *backends.SimulatedBackend, configurator *configurator.Configurator, configuratorAddress common.Address, nodes []Node, oracles []confighelper.OracleIdentityExtra) ocr2types.ConfigDigest { signers, _, _, _, offchainConfigVersion, offchainConfig := generateConfig(t, oracles) signerAddresses, err := evm.OnchainPublicKeyToAddress(signers) @@ -149,20 +182,37 @@ func setConfig(t *testing.T, steve *bind.TransactOpts, backend *backends.Simulat for i := 0; i < nNodes; i++ { offchainTransmitters[i] = nodes[i].ClientPubKey } - _, err = verifierContract.SetConfig(steve, signerAddresses, offchainTransmitters, fNodes, offchainConfig, offchainConfigVersion, offchainConfig, nil) + donIDPadded := evm.DonIDToBytes32(donID) + _, err = configurator.SetConfig(steve, donIDPadded, signerAddresses, offchainTransmitters, fNodes, offchainConfig, offchainConfigVersion, offchainConfig) require.NoError(t, err) + // libocr requires a few confirmations to accept the config + backend.Commit() backend.Commit() + backend.Commit() + backend.Commit() + + logs, err := backend.FilterLogs(testutils.Context(t), ethereum.FilterQuery{Addresses: []common.Address{configuratorAddress}, Topics: [][]common.Hash{[]common.Hash{mercury.FeedScopedConfigSet, donIDPadded}}}) + require.NoError(t, err) + require.Len(t, logs, 1) - l, err := verifierContract.LatestConfigDigestAndEpoch(&bind.CallOpts{}) + cfg, err := mercury.ConfigFromLog(logs[0].Data) require.NoError(t, err) - return l.ConfigDigest + return cfg.ConfigDigest } -// On-chain format is not finalized yet so use the dummy relayer for testing -func TestIntegration_LLO_Dummy(t *testing.T) { +func TestIntegration_LLO(t *testing.T) { testStartTimeStamp := time.Now() + donID := uint32(995544) + multiplier, err := decimal.NewFromString("1e18") + require.NoError(t, err) + expirationWindow := time.Hour / time.Second + + reqs := make(chan request) + serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) + serverPubKey := serverKey.PublicKey + srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs) clientCSAKeys := make([]csakey.KeyV2, nNodes) clientPubKeys := make([]ed25519.PublicKey, nNodes) @@ -172,15 +222,20 @@ func TestIntegration_LLO_Dummy(t *testing.T) { clientCSAKeys[i] = key clientPubKeys[i] = key.PublicKey } + serverURL := startMercuryServer(t, srv, clientPubKeys) + + // TODO: all args? + steve, backend, configurator, configuratorAddress, verifier, _, verifierProxy, _, configStore, configStoreAddress := setupBlockchain(t) + fromBlock := 1 // Setup bootstrap bootstrapCSAKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) bootstrapNodePort := freeport.GetOne(t) - appBootstrap, bootstrapPeerID, _, bootstrapKb, _ := setupNode(t, bootstrapNodePort, "bootstrap_llo", nil, bootstrapCSAKey) + appBootstrap, bootstrapPeerID, _, bootstrapKb, _ := setupNode(t, bootstrapNodePort, "bootstrap_llo", backend, bootstrapCSAKey) bootstrapNode := Node{App: appBootstrap, KeyBundle: bootstrapKb} t.Run("produces reports in v0.3 format", func(t *testing.T) { - streams := []Stream{ethStream, linkStream, quoteStream} + streams := []Stream{ethStream, linkStream, quoteStream1, quoteStream2} streamMap := make(map[uint32]Stream) for _, strm := range streams { streamMap[strm.id] = strm @@ -193,7 +248,7 @@ func TestIntegration_LLO_Dummy(t *testing.T) { ) ports := freeport.GetN(t, nNodes) for i := 0; i < nNodes; i++ { - app, peerID, transmitter, kb, observedLogs := setupNode(t, ports[i], fmt.Sprintf("oracle_streams_%d", i), nil, clientCSAKeys[i]) + app, peerID, transmitter, kb, observedLogs := setupNode(t, ports[i], fmt.Sprintf("oracle_streams_%d", i), backend, clientCSAKeys[i]) nodes = append(nodes, Node{ app, transmitter, kb, observedLogs, @@ -210,250 +265,183 @@ func TestIntegration_LLO_Dummy(t *testing.T) { }) } - verifierAddress := common.Address{} - chainID := "llo-dummy" - relayType := "dummy" - cd := ocr2types.ConfigDigest{0x01, 0x02, 0x03, 0x04} - signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig := generateConfig(t, oracles) - var signersMarshalled, transmittersMarshalled []byte - { - var err error - signersHex := make([]string, len(signers)) - for i, signer := range signers { - signersHex[i] = fmt.Sprintf("0x%x", signer) - } - signersMarshalled, err = json.Marshal(signersHex) - require.NoError(t, err) + chainID := testutils.SimulatedChainID + relayType := "evm" + relayConfig := fmt.Sprintf(` +chainID = "%s" +fromBlock = %d +lloDonID = %d +`, chainID, fromBlock, donID) + addBootstrapJob(t, bootstrapNode, configuratorAddress, "job-2", relayType, relayConfig) + + // Channel definitions + channelDefinitions := llotypes.ChannelDefinitions{ + 1: { + ReportFormat: llotypes.ReportFormatEVMPremiumLegacy, + Streams: []llotypes.Stream{ + { + StreamID: ethStreamID, + Aggregator: llotypes.AggregatorMedian, + }, + { + StreamID: linkStreamID, + Aggregator: llotypes.AggregatorMedian, + }, + { + StreamID: quoteStreamID1, + Aggregator: llotypes.AggregatorQuote, + }, + }, + Opts: llotypes.ChannelOpts([]byte(fmt.Sprintf(`{"baseUSDFee":"0.1","expirationWindow":%d,"feedId":"0x%x","multiplier":"%s"}`, expirationWindow, quoteStreamFeedID1, multiplier.String()))), + }, + 2: { + ReportFormat: llotypes.ReportFormatEVMPremiumLegacy, + Streams: []llotypes.Stream{ + { + StreamID: ethStreamID, + Aggregator: llotypes.AggregatorMedian, + }, + { + StreamID: linkStreamID, + Aggregator: llotypes.AggregatorMedian, + }, + { + StreamID: quoteStreamID2, + Aggregator: llotypes.AggregatorQuote, + }, + }, + Opts: llotypes.ChannelOpts([]byte(fmt.Sprintf(`{"baseUSDFee":"0.1","expirationWindow":%d,"feedId":"0x%x","multiplier":"%s"}`, expirationWindow, quoteStreamFeedID2, multiplier.String()))), + }, + } - transmittersMarshalled, err = json.Marshal(transmitters) + channelDefinitionsJSON, err := json.MarshalIndent(channelDefinitions, "", " ") + require.NoError(t, err) + channelDefinitionsSHA := sha3.Sum256(channelDefinitionsJSON) + + // Set up channel definitions server + channelDefinitionsServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "/channel-definitions", r.URL.Path) + assert.Equal(t, "GET", r.Method) + assert.Equal(t, "application/json", r.Header.Get("Content-Type")) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, err := w.Write(channelDefinitionsJSON) require.NoError(t, err) - } + })) + t.Cleanup(channelDefinitionsServer.Close) - relayConfig := fmt.Sprintf(`chainID = "%s" -configTracker = { - configDigest = "0x%x", - configCount = 0, - signers = %s, - transmitters = %s, - f = %d, - onchainConfig = "0x%x", - offchainConfigVersion = %d, - offchainConfig = "0x%x", - blockHeight = 10 -}`, chainID, cd[:], string(signersMarshalled), string(transmittersMarshalled), f, onchainConfig, offchainConfigVersion, offchainConfig) - addBootstrapJob(t, bootstrapNode, verifierAddress, "job-2", relayType, relayConfig) - - serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) - serverPubKey := serverKey.PublicKey - serverURL := "foo" - configStoreAddress := common.Address{} - - chainSelector := 4949039107694359620 // arbitrum mainnet - - feedID := [32]byte{00, 03, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} - expirationWindow := 3600 - multiplier := big.NewInt(1e18) - baseUSDFee := 10 - // 52 = eth, 53 = link, 55 = quote - channelDefinitions := fmt.Sprintf(` -{ - "42": { - "reportFormat": %d, - "chainSelector": %d, - "streams": [{"streamId": 52, "aggregator": %d}, {"streamId": 53, "aggregator": %d}, {"streamId": 55, "aggregator": %d}], - "opts": { - "feedId": "0x%x", - "expirationWindow": %d, - "multiplier": "%s", - "baseUSDFee": "%d" - } - } -}`, llotypes.ReportFormatEVMPremiumLegacy, chainSelector, llotypes.AggregatorMedian, llotypes.AggregatorMedian, llotypes.AggregatorQuote, feedID, expirationWindow, multiplier.String(), baseUSDFee) + // Set channel definitions + _, err = configStore.SetChannelDefinitions(steve, donID, channelDefinitionsServer.URL+"/channel-definitions", channelDefinitionsSHA) + require.NoError(t, err) + backend.Commit() - pluginConfig := fmt.Sprintf(`serverURL = "foo" -donID = 42 + pluginConfig := fmt.Sprintf(`serverURL = "%s" +donID = %d serverPubKey = "%x" -channelDefinitions = %q`, serverPubKey, channelDefinitions) - jobIDs := addOCRJobsEVMPremiumLegacy(t, streams, serverPubKey, serverURL, verifierAddress, bootstrapPeerID, bootstrapNodePort, nodes, configStoreAddress, clientPubKeys, pluginConfig, relayType, relayConfig) +channelDefinitionsContractAddress = "0x%x" +channelDefinitionsContractFromBlock = %d`, serverURL, donID, serverPubKey, configStoreAddress, fromBlock) + addOCRJobsEVMPremiumLegacy(t, streams, serverPubKey, serverURL, configuratorAddress, bootstrapPeerID, bootstrapNodePort, nodes, configStoreAddress, clientPubKeys, pluginConfig, relayType, relayConfig) - steve, backend, verifier, verifierProxy, _ := setupV03Blockchain(t) + // Set config on configurator + setConfig( + t, donID, steve, backend, configurator, configuratorAddress, nodes, oracles, + ) - // Set config - recipientAddressesAndWeights := []destination_verifier.CommonAddressAndWeight{} + // Set config on the destination verifier signerAddresses := make([]common.Address, len(oracles)) for i, oracle := range oracles { signerAddresses[i] = common.BytesToAddress(oracle.OracleIdentity.OnchainPublicKey) } + { + recipientAddressesAndWeights := []destination_verifier.CommonAddressAndWeight{} - _, err := verifier.SetConfig(steve, signerAddresses, f, recipientAddressesAndWeights) - require.NoError(t, err) - backend.Commit() - - for i, node := range nodes { - le := testutils.WaitForLogMessage(t, node.ObservedLogs, "Transmit") - fields := le.ContextMap() - assert.Equal(t, hexutil.Encode(cd[:]), "0x"+fields["digest"].(string)) - assert.Equal(t, llotypes.ReportInfo{LifeCycleStage: "production", ReportFormat: llotypes.ReportFormatEVMPremiumLegacy}, fields["report.Info"]) - - if fields["report.Report"] == nil { - t.Fatal("FAIL: expected log fields to contain 'report.Report'") - } - binaryReport := fields["report.Report"].(types.Report) - report, err := (lloevm.ReportCodecPremiumLegacy{}).Decode(binaryReport) + _, err := verifier.SetConfig(steve, signerAddresses, fNodes, recipientAddressesAndWeights) require.NoError(t, err) - assert.Equal(t, feedID, report.FeedId) - assert.GreaterOrEqual(t, report.ObservationsTimestamp, uint32(testStartTimeStamp.Unix())) - assert.Equal(t, quoteStream.baseBenchmarkPrice.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.BenchmarkPrice.String()) - assert.Equal(t, quoteStream.baseBid.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.Bid.String()) - assert.Equal(t, quoteStream.baseAsk.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.Ask.String()) - assert.GreaterOrEqual(t, report.ValidFromTimestamp, uint32(testStartTimeStamp.Unix())) - assert.Equal(t, report.ObservationsTimestamp+uint32(expirationWindow), report.ExpiresAt) - assert.Equal(t, big.NewInt(754716981132075472), report.LinkFee) - assert.Equal(t, big.NewInt(3359774760700043), report.NativeFee) - - seqNr := fields["seqNr"].(uint64) - assert.Greater(t, int(seqNr), 0) - - sigs := fields["sigs"].([]types.AttributedOnchainSignature) - - t.Run(fmt.Sprintf("emulate mercury server verifying report (local verification) - node %d", i), func(t *testing.T) { - var rs [][32]byte - var ss [][32]byte - var vs [32]byte - for i, as := range sigs { - r, s, v, err := evmutil.SplitSignature(as.Signature) - if err != nil { - panic("error in SplitSignature") - } - rs = append(rs, r) - ss = append(ss, s) - vs[i] = v - } - rc := lloevm.LegacyReportContext(cd, seqNr) - rawReportCtx := evmutil.RawReportContext(rc) - rv := mercuryverifier.NewVerifier() - - reportSigners, err := rv.Verify(mercuryverifier.SignedReport{ - RawRs: rs, - RawSs: ss, - RawVs: vs, - ReportContext: rawReportCtx, - Report: binaryReport, - }, f, signerAddresses) - require.NoError(t, err) - assert.GreaterOrEqual(t, len(reportSigners), int(f+1)) - assert.Subset(t, signerAddresses, reportSigners) - }) + backend.Commit() + } - t.Run(fmt.Sprintf("test on-chain verification - node %d", i), func(t *testing.T) { - signedReport, err := lloevm.ReportCodecPremiumLegacy{}.Pack(cd, seqNr, binaryReport, sigs) + t.Run("receives at least one report per channel from each oracle when EAs are at 100% reliability", func(t *testing.T) { + // Expect at least one report per feed from each oracle + seen := make(map[[32]byte]map[credentials.StaticSizedPublicKey]struct{}) + for _, cd := range channelDefinitions { + var opts lloevm.ReportFormatEVMPremiumLegacyOpts + err := json.Unmarshal(cd.Opts, &opts) require.NoError(t, err) - - _, err = verifierProxy.Verify(steve, signedReport, []byte{}) + // feedID will be deleted when all n oracles have reported + seen[opts.FeedID] = make(map[credentials.StaticSizedPublicKey]struct{}, nNodes) + } + for req := range reqs { + v := make(map[string]interface{}) + err := mercury.PayloadTypes.UnpackIntoMap(v, req.req.Payload) require.NoError(t, err) - - }) - } - - t.Run("if link/eth stream specs start failing, uses 0 for the fee", func(t *testing.T) { - t.Run("link/eth stream specs are missing", func(t *testing.T) { - // delete eth/link stream specs - for idx, strmIDs := range jobIDs { - for strmID, jobID := range strmIDs { - if strmID == ethStream.id || strmID == linkStream.id { - nodes[idx].DeleteJob(t, jobID) - } - } + report, exists := v["report"] + if !exists { + t.Fatalf("expected payload %#v to contain 'report'", v) } + reportElems := make(map[string]interface{}) + err = reportcodecv3.ReportTypes.UnpackIntoMap(reportElems, report.([]byte)) + require.NoError(t, err) - for _, node := range nodes { - node.ObservedLogs.TakeAll() - - le := testutils.WaitForLogMessage(t, node.ObservedLogs, "Observation failed for streams") - fields := le.ContextMap() - assert.Equal(t, []interface{}{ethStream.id, linkStream.id}, fields["failedStreamIDs"]) - assert.Equal(t, []interface{}{"StreamID: 52; Reason: missing stream: 52", "StreamID: 53; Reason: missing stream: 53"}, fields["errors"]) - - le = testutils.WaitForLogMessage(t, node.ObservedLogs, "Transmit") - fields = le.ContextMap() - assert.Equal(t, hexutil.Encode(cd[:]), "0x"+fields["digest"].(string)) - assert.Equal(t, llotypes.ReportInfo{LifeCycleStage: "production", ReportFormat: llotypes.ReportFormatEVMPremiumLegacy}, fields["report.Info"]) + feedID := reportElems["feedId"].([32]uint8) - if fields["report.Report"] == nil { - t.Fatal("FAIL: expected log fields to contain 'report.Report'") - } - binaryReport := fields["report.Report"].(types.Report) - report, err := (lloevm.ReportCodecPremiumLegacy{}).Decode(binaryReport) - require.NoError(t, err) - assert.Equal(t, feedID, report.FeedId) - assert.GreaterOrEqual(t, report.ObservationsTimestamp, uint32(testStartTimeStamp.Unix())) - assert.Equal(t, quoteStream.baseBenchmarkPrice.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.BenchmarkPrice.String()) - assert.Equal(t, quoteStream.baseBid.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.Bid.String()) - assert.Equal(t, quoteStream.baseAsk.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.Ask.String()) - assert.GreaterOrEqual(t, report.ValidFromTimestamp, uint32(testStartTimeStamp.Unix())) - assert.Equal(t, report.ObservationsTimestamp+uint32(expirationWindow), report.ExpiresAt) - assert.Equal(t, "0", report.LinkFee.String()) - assert.Equal(t, "0", report.NativeFee.String()) + if _, exists := seen[feedID]; !exists { + continue // already saw all oracles for this feed } - }) - t.Run("link/eth stream specs have EAs that return error", func(t *testing.T) { - // add new stream specs that will fail - for i, node := range nodes { - for j, strm := range streams { - if strm.id == ethStream.id || strm.id == linkStream.id { - var name string - if j == 0 { - name = "nativeprice" - } else { - name = "linkprice" - } - name = fmt.Sprintf("%s-%d-%d-erroring", name, strm.id, j) - bmBridge := createErroringBridge(t, name, i, node.App.BridgeORM()) - addSingleDecimalStreamJob( - t, - node, - strm.id, - bmBridge, - ) - } - } + var expectedBm, expectedBid, expectedAsk *big.Int + if feedID == quoteStreamFeedID1 { + expectedBm = quoteStream1.baseBenchmarkPrice.Mul(multiplier).BigInt() + expectedBid = quoteStream1.baseBid.Mul(multiplier).BigInt() + expectedAsk = quoteStream1.baseAsk.Mul(multiplier).BigInt() + } else if feedID == quoteStreamFeedID2 { + expectedBm = quoteStream2.baseBenchmarkPrice.Mul(multiplier).BigInt() + expectedBid = quoteStream2.baseBid.Mul(multiplier).BigInt() + expectedAsk = quoteStream2.baseAsk.Mul(multiplier).BigInt() + } else { + t.Fatalf("unrecognized feedID: 0x%x", feedID) } - for _, node := range nodes { - node.ObservedLogs.TakeAll() + assert.GreaterOrEqual(t, reportElems["validFromTimestamp"].(uint32), uint32(testStartTimeStamp.Unix())) + assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp.Unix())) + assert.Equal(t, "33597747607000", reportElems["nativeFee"].(*big.Int).String()) + assert.Equal(t, "7547169811320755", reportElems["linkFee"].(*big.Int).String()) + assert.Equal(t, reportElems["observationsTimestamp"].(uint32)+uint32(expirationWindow), reportElems["expiresAt"].(uint32)) + assert.Equal(t, expectedBm.String(), reportElems["benchmarkPrice"].(*big.Int).String()) + assert.Equal(t, expectedBid.String(), reportElems["bid"].(*big.Int).String()) + assert.Equal(t, expectedAsk.String(), reportElems["ask"].(*big.Int).String()) + + t.Run(fmt.Sprintf("emulate mercury server verifying report (local verification) - node %x", req.pk), func(t *testing.T) { + rv := mercuryverifier.NewVerifier() + + reportSigners, err := rv.Verify(mercuryverifier.SignedReport{ + RawRs: v["rawRs"].([][32]byte), + RawSs: v["rawSs"].([][32]byte), + RawVs: v["rawVs"].([32]byte), + ReportContext: v["reportContext"].([3][32]byte), + Report: v["report"].([]byte), + }, fNodes, signerAddresses) + require.NoError(t, err) + assert.GreaterOrEqual(t, len(reportSigners), int(fNodes+1)) + assert.Subset(t, signerAddresses, reportSigners) + }) - le := testutils.WaitForLogMessage(t, node.ObservedLogs, "Observation failed for streams") - fields := le.ContextMap() - assert.Equal(t, []interface{}{ethStream.id, linkStream.id}, fields["failedStreamIDs"]) - assert.Len(t, fields["errors"], 2) - for _, err := range fields["errors"].([]interface{}) { - assert.Contains(t, err.(string), "Reason: failed to extract big.Int") - assert.Contains(t, err.(string), "status code 500") - } + t.Run(fmt.Sprintf("test on-chain verification - node %x", req.pk), func(t *testing.T) { + _, err = verifierProxy.Verify(steve, req.req.Payload, []byte{}) + require.NoError(t, err) + + }) - le = testutils.WaitForLogMessage(t, node.ObservedLogs, "Transmit") - fields = le.ContextMap() - assert.Equal(t, hexutil.Encode(cd[:]), "0x"+fields["digest"].(string)) - assert.Equal(t, llotypes.ReportInfo{LifeCycleStage: "production", ReportFormat: llotypes.ReportFormatEVMPremiumLegacy}, fields["report.Info"]) + t.Logf("oracle %x reported for 0x%x", req.pk, feedID) - if fields["report.Report"] == nil { - t.Fatal("FAIL: expected log fields to contain 'report.Report'") + seen[feedID][req.pk] = struct{}{} + if len(seen[feedID]) == nNodes { + t.Logf("all oracles reported for 0x%x", feedID) + delete(seen, feedID) + if len(seen) == 0 { + break // saw all oracles; success! } - binaryReport := fields["report.Report"].(types.Report) - report, err := (lloevm.ReportCodecPremiumLegacy{}).Decode(binaryReport) - require.NoError(t, err) - assert.Equal(t, feedID, report.FeedId) - assert.GreaterOrEqual(t, report.ObservationsTimestamp, uint32(testStartTimeStamp.Unix())) - assert.Equal(t, quoteStream.baseBenchmarkPrice.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.BenchmarkPrice.String()) - assert.Equal(t, quoteStream.baseBid.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.Bid.String()) - assert.Equal(t, quoteStream.baseAsk.Mul(decimal.NewFromBigInt(multiplier, 0)).String(), report.Ask.String()) - assert.GreaterOrEqual(t, report.ValidFromTimestamp, uint32(testStartTimeStamp.Unix())) - assert.Equal(t, int(report.ObservationsTimestamp+uint32(expirationWindow)), int(report.ExpiresAt)) - assert.Equal(t, "0", report.LinkFee.String()) - assert.Equal(t, "0", report.NativeFee.String()) } - }) + } }) t.Run("deleting LLO jobs cleans up resources", func(t *testing.T) { diff --git a/core/services/ocrbootstrap/delegate.go b/core/services/ocrbootstrap/delegate.go index fdcb68ceec..10ac0cb45d 100644 --- a/core/services/ocrbootstrap/delegate.go +++ b/core/services/ocrbootstrap/delegate.go @@ -39,10 +39,16 @@ type Delegate struct { type relayConfig struct { // providerType used for determining which type of contract to track config on ProviderType string `json:"providerType"` + // HACK // Extra fields to enable router proxy contract support. Must match field names of functions' PluginConfig. DONID string `json:"donID"` ContractVersion uint32 `json:"contractVersion"` ContractUpdateCheckFrequencySec uint32 `json:"contractUpdateCheckFrequencySec"` + + // Annoyingly, the pre-existing donID field is already reserved and has a + // special-case usage just for functions. It's also a string and not uint32 + // as Baku requires. + LLODONID uint32 `json:"lloDonID"` } // NewDelegateBootstrap creates a new Delegate @@ -111,7 +117,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services [] var relayCfg relayConfig if err = json.Unmarshal(spec.RelayConfig.Bytes(), &relayCfg); err != nil { - return nil, err + return nil, fmt.Errorf("failed to unmarshal relay config for bootstrap job: %w", err) } var configProvider types.ConfigProvider diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 35417c615c..5156f98185 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -62,7 +62,6 @@ import ( var ( OCR2AggregatorTransmissionContractABI abi.ABI OCR2AggregatorLogDecoder LogDecoder - ChannelVerifierLogDecoder LogDecoder ) func init() { @@ -75,10 +74,6 @@ func init() { if err != nil { panic(err) } - ChannelVerifierLogDecoder, err = newChannelVerifierLogDecoder() - if err != nil { - panic(err) - } } var _ commontypes.Relayer = &Relayer{} //nolint:staticcheck @@ -488,6 +483,8 @@ func (r *Relayer) NewConfigProvider(args commontypes.RelayArgs) (configProvider if args.ProviderType == "" { if relayConfig.FeedID == nil { args.ProviderType = "median" + } else if relayConfig.LLODONID > 0 { + args.ProviderType = "llo" } else { args.ProviderType = "mercury" } diff --git a/core/services/relay/evm/llo_config_provider.go b/core/services/relay/evm/llo_config_provider.go index 71b6a39be2..0fe98d1cf7 100644 --- a/core/services/relay/evm/llo_config_provider.go +++ b/core/services/relay/evm/llo_config_provider.go @@ -2,23 +2,54 @@ package evm import ( "context" + "fmt" + "math/big" "github.com/ethereum/go-ethereum/common" - pkgerrors "github.com/pkg/errors" + "github.com/pkg/errors" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/services/llo" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) +func DonIDToBytes32(donID uint32) [32]byte { + var b [32]byte + copy(b[:], common.LeftPadBytes(big.NewInt(int64(donID)).Bytes(), 32)) + return b +} + func newLLOConfigProvider(ctx context.Context, lggr logger.Logger, chain legacyevm.Chain, opts *types.RelayOpts) (*configWatcher, error) { if !common.IsHexAddress(opts.ContractID) { - return nil, pkgerrors.Errorf("invalid contractID, expected hex address") + return nil, errors.New("invalid contractID, expected hex address") + } + + configuratorAddress := common.HexToAddress(opts.ContractID) + + relayConfig, err := opts.RelayConfig() + if err != nil { + return nil, fmt.Errorf("failed to get relay config: %w", err) + } + if relayConfig.LLODONID == 0 { + return nil, errors.New("donID must be specified in relayConfig for LLO jobs") + } + donIDPadded := DonIDToBytes32(relayConfig.LLODONID) + cp, err := mercury.NewConfigPoller( + ctx, + logger.Named(lggr, fmt.Sprintf("LLO-%d", relayConfig.LLODONID)), + chain.LogPoller(), + configuratorAddress, + donIDPadded, + // TODO: Does LLO need to support config contract? MERC-1827 + ) + if err != nil { + return nil, err } - aggregatorAddress := common.HexToAddress(opts.ContractID) - configDigester := llo.NewOffchainConfigDigester(chain.Config().EVM().ChainID(), aggregatorAddress) - return newContractConfigProvider(ctx, lggr, chain, opts, aggregatorAddress, ChannelVerifierLogDecoder, configDigester) + configDigester := mercury.NewOffchainConfigDigester(donIDPadded, chain.Config().EVM().ChainID(), configuratorAddress, ocrtypes.ConfigDigestPrefixLLO) + return newConfigWatcher(lggr, configuratorAddress, configDigester, cp, chain, relayConfig.FromBlock, opts.New), nil } diff --git a/core/services/relay/evm/llo_verifier_decoder.go b/core/services/relay/evm/llo_verifier_decoder.go deleted file mode 100644 index 922b83bec0..0000000000 --- a/core/services/relay/evm/llo_verifier_decoder.go +++ /dev/null @@ -1,67 +0,0 @@ -package evm - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/pkg/errors" - - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_verifier" -) - -var _ LogDecoder = &channelVerifierLogDecoder{} - -type channelVerifierLogDecoder struct { - eventName string - eventSig common.Hash - abi *abi.ABI -} - -func newChannelVerifierLogDecoder() (*channelVerifierLogDecoder, error) { - const eventName = "ConfigSet" - abi, err := channel_verifier.ChannelVerifierMetaData.GetAbi() - if err != nil { - return nil, err - } - return &channelVerifierLogDecoder{ - eventName: eventName, - eventSig: abi.Events[eventName].ID, - abi: abi, - }, nil -} - -func (d *channelVerifierLogDecoder) Decode(rawLog []byte) (ocrtypes.ContractConfig, error) { - unpacked := new(channel_verifier.ChannelVerifierConfigSet) - err := d.abi.UnpackIntoInterface(unpacked, d.eventName, rawLog) - if err != nil { - return ocrtypes.ContractConfig{}, errors.Wrap(err, "failed to unpack log data") - } - - var transmitAccounts []ocrtypes.Account - for _, addr := range unpacked.OffchainTransmitters { - transmitAccounts = append(transmitAccounts, ocrtypes.Account(fmt.Sprintf("%x", addr))) - } - var signers []ocrtypes.OnchainPublicKey - for _, addr := range unpacked.Signers { - addr := addr - signers = append(signers, addr[:]) - } - - return ocrtypes.ContractConfig{ - ConfigDigest: unpacked.ConfigDigest, - ConfigCount: unpacked.ConfigCount, - Signers: signers, - Transmitters: transmitAccounts, - F: unpacked.F, - OnchainConfig: unpacked.OnchainConfig, - OffchainConfigVersion: unpacked.OffchainConfigVersion, - OffchainConfig: unpacked.OffchainConfig, - }, nil -} - -func (d *channelVerifierLogDecoder) EventSig() common.Hash { - return d.eventSig -} diff --git a/core/services/relay/evm/mercury/config_digest.go b/core/services/relay/evm/mercury/config_digest.go index 291a723ee3..c7a6076c88 100644 --- a/core/services/relay/evm/mercury/config_digest.go +++ b/core/services/relay/evm/mercury/config_digest.go @@ -37,6 +37,7 @@ func configDigest( onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, + prefix types.ConfigDigestPrefix, ) types.ConfigDigest { msg, err := configDigestArgs.Pack( feedID, @@ -60,10 +61,6 @@ func configDigest( // assertion panic("copy too little data") } - binary.BigEndian.PutUint16(configDigest[:2], uint16(types.ConfigDigestPrefixMercuryV02)) - if !(configDigest[0] == 0 && configDigest[1] == 6) { - // assertion - panic("unexpected mismatch") - } + binary.BigEndian.PutUint16(configDigest[:2], uint16(prefix)) return configDigest } diff --git a/core/services/relay/evm/mercury/config_digest_test.go b/core/services/relay/evm/mercury/config_digest_test.go index fe718e92fe..680513688a 100644 --- a/core/services/relay/evm/mercury/config_digest_test.go +++ b/core/services/relay/evm/mercury/config_digest_test.go @@ -15,6 +15,7 @@ import ( "github.com/leanovate/gopter" "github.com/leanovate/gopter/gen" "github.com/leanovate/gopter/prop" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/wsrpc/credentials" "github.com/stretchr/testify/require" @@ -63,6 +64,7 @@ func TestConfigCalculationMatches(t *testing.T) { onchainConfig, offchainConfigVersion, offchainConfig, + ocrtypes.ConfigDigestPrefixMercuryV02, ) bigChainID := new(big.Int) diff --git a/core/services/relay/evm/mercury/config_poller.go b/core/services/relay/evm/mercury/config_poller.go index e93ad339ce..111c432e6f 100644 --- a/core/services/relay/evm/mercury/config_poller.go +++ b/core/services/relay/evm/mercury/config_poller.go @@ -54,7 +54,7 @@ func unpackLogData(d []byte) (*verifier.VerifierConfigSet, error) { return unpacked, nil } -func configFromLog(logData []byte) (FullConfigFromLog, error) { +func ConfigFromLog(logData []byte) (FullConfigFromLog, error) { unpacked, err := unpackLogData(logData) if err != nil { return FullConfigFromLog{}, err @@ -99,6 +99,7 @@ func FilterName(addr common.Address, feedID common.Hash) string { // NewConfigPoller creates a new Mercury ConfigPoller func NewConfigPoller(ctx context.Context, lggr logger.Logger, destChainPoller logpoller.LogPoller, addr common.Address, feedId common.Hash) (*ConfigPoller, error) { + fmt.Println("TRASH RegisterFilter", FilterName(addr, feedId)) err := destChainPoller.RegisterFilter(ctx, logpoller.Filter{Name: FilterName(addr, feedId), EventSigs: []common.Hash{FeedScopedConfigSet}, Addresses: []common.Address{addr}}) if err != nil { return nil, err @@ -140,7 +141,7 @@ func (cp *ConfigPoller) LatestConfigDetails(ctx context.Context) (changedInBlock return 0, ocrtypes.ConfigDigest{}, nil } latest := logs[len(logs)-1] - latestConfigSet, err := configFromLog(latest.Data) + latestConfigSet, err := ConfigFromLog(latest.Data) if err != nil { return 0, ocrtypes.ConfigDigest{}, err } @@ -156,7 +157,7 @@ func (cp *ConfigPoller) LatestConfig(ctx context.Context, changedInBlock uint64) if len(lgs) == 0 { return ocrtypes.ContractConfig{}, nil } - latestConfigSet, err := configFromLog(lgs[len(lgs)-1].Data) + latestConfigSet, err := ConfigFromLog(lgs[len(lgs)-1].Data) if err != nil { return ocrtypes.ContractConfig{}, err } diff --git a/core/services/relay/evm/mercury/offchain_config_digester.go b/core/services/relay/evm/mercury/offchain_config_digester.go index f9ba0b2309..80b3005455 100644 --- a/core/services/relay/evm/mercury/offchain_config_digester.go +++ b/core/services/relay/evm/mercury/offchain_config_digester.go @@ -18,14 +18,15 @@ import ( var _ ocrtypes.OffchainConfigDigester = OffchainConfigDigester{} -func NewOffchainConfigDigester(feedID [32]byte, chainID *big.Int, contractAddress common.Address) OffchainConfigDigester { - return OffchainConfigDigester{feedID, chainID, contractAddress} +func NewOffchainConfigDigester(feedID [32]byte, chainID *big.Int, contractAddress common.Address, prefix ocrtypes.ConfigDigestPrefix) OffchainConfigDigester { + return OffchainConfigDigester{feedID, chainID, contractAddress, prefix} } type OffchainConfigDigester struct { FeedID utils.FeedID ChainID *big.Int ContractAddress common.Address + Prefix ocrtypes.ConfigDigestPrefix } func (d OffchainConfigDigester) ConfigDigest(cc ocrtypes.ContractConfig) (ocrtypes.ConfigDigest, error) { @@ -63,9 +64,10 @@ func (d OffchainConfigDigester) ConfigDigest(cc ocrtypes.ContractConfig) (ocrtyp cc.OnchainConfig, cc.OffchainConfigVersion, cc.OffchainConfig, + d.Prefix, ), nil } func (d OffchainConfigDigester) ConfigDigestPrefix() (ocrtypes.ConfigDigestPrefix, error) { - return ocrtypes.ConfigDigestPrefixMercuryV02, nil + return d.Prefix, nil } diff --git a/core/services/relay/evm/mercury_config_provider.go b/core/services/relay/evm/mercury_config_provider.go index 349650c0fc..53bf8e22d2 100644 --- a/core/services/relay/evm/mercury_config_provider.go +++ b/core/services/relay/evm/mercury_config_provider.go @@ -7,6 +7,8 @@ import ( "github.com/ethereum/go-ethereum/common" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" @@ -41,6 +43,6 @@ func newMercuryConfigProvider(ctx context.Context, lggr logger.Logger, chain leg return nil, err } - offchainConfigDigester := mercury.NewOffchainConfigDigester(*relayConfig.FeedID, chain.Config().EVM().ChainID(), aggregatorAddress) + offchainConfigDigester := mercury.NewOffchainConfigDigester(*relayConfig.FeedID, chain.Config().EVM().ChainID(), aggregatorAddress, ocrtypes.ConfigDigestPrefixMercuryV02) return newConfigWatcher(lggr, aggregatorAddress, offchainConfigDigester, cp, chain, relayConfig.FromBlock, opts.New), nil } diff --git a/core/services/relay/evm/types/types.go b/core/services/relay/evm/types/types.go index 175e1535df..ac9690e2a6 100644 --- a/core/services/relay/evm/types/types.go +++ b/core/services/relay/evm/types/types.go @@ -195,6 +195,9 @@ type RelayConfig struct { // Mercury-specific FeedID *common.Hash `json:"feedID"` EnableTriggerCapability bool `json:"enableTriggerCapability"` + + // LLO-specific + LLODONID uint32 `json:"lloDonID" toml:"lloDonID"` } var ErrBadRelayConfig = errors.New("bad relay config") From 2a21b170f38ded4cf0f15db283035e69b53aeeb9 Mon Sep 17 00:00:00 2001 From: Graham Goh Date: Wed, 4 Sep 2024 01:11:53 +1000 Subject: [PATCH 275/432] feat(ui): update to latest (#14316) Bring in changes for supporting multiple job distributors. JIRA: https://smartcontract-it.atlassian.net/browse/OPCORE-858 --- .changeset/afraid-plums-look.md | 5 +++++ core/web/assets/index.html | 2 +- core/web/assets/index.html.gz | Bin 419 -> 418 bytes ...57e21d.js => main.2f351fafaaf99deb7f66.js} | 4 ++-- ....js.gz => main.2f351fafaaf99deb7f66.js.gz} | Bin 1196025 -> 1196259 bytes operator_ui/TAG | 2 +- 6 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 .changeset/afraid-plums-look.md rename core/web/assets/{main.6f07a88cfc748f57e21d.js => main.2f351fafaaf99deb7f66.js} (89%) rename core/web/assets/{main.6f07a88cfc748f57e21d.js.gz => main.2f351fafaaf99deb7f66.js.gz} (86%) diff --git a/.changeset/afraid-plums-look.md b/.changeset/afraid-plums-look.md new file mode 100644 index 0000000000..a72348e565 --- /dev/null +++ b/.changeset/afraid-plums-look.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#internal updated to latest operator-ui to bring in new UI changes for supporting multiple job distributors diff --git a/core/web/assets/index.html b/core/web/assets/index.html index e50dfc0709..541bcfe5ac 100644 --- a/core/web/assets/index.html +++ b/core/web/assets/index.html @@ -1 +1 @@ -Operator UIChainlink
    \ No newline at end of file +Operator UIChainlink
    \ No newline at end of file diff --git a/core/web/assets/index.html.gz b/core/web/assets/index.html.gz index f32bc10dbc313c6e49188a920a5f9bb14ffd54ff..9793fdb18508508c1ac4410268256ed903cae2f9 100644 GIT binary patch literal 418 zcmV;T0bTwdiwFP!000021C^3NYaB5Qh5w3c=&9N9Bx%wn*pow`kU}Xm&7nuFE$^tc zt-;n#vj4u!?q;D-D81PDfxag_%f1QhWjCQ3C8xn2PlPboi~`D!P#cQVPv1YSK5BE6 z3uJV9CVZZ_idLSBU=gREDahyo&g5~mf1FVvAxNv{A)z~87($Y8_&Q+);i{eIc`jOw6{FLm$kc9)X&I_4rWL$&lsEL!6%^w~pt3MJ@_YwdVdptd z6kskzy8GGmV9kLrSaVpMHHY0` z3m@elyj2A;C}D*K)(O>TnBnnYE3E3aC>g0Kn5NE}Q=ttsD+*3mW?6g!&4V=uyxFhn MZ}*9@?7#v50H2o41^@s6 literal 419 zcmV;U0bKqciwFP!000021C^3NYa1~Th5w2w=&ANbIe#Q(nR+A$Ogr56c3nD5OzjeQf?%W*_CNQ#|3p9rC|2?dlNpi~s6pT2)wZ?!qg z84@}@5k8MxL@Uo(FpJaA6l8D#C-S&n9xKWu1aVzGM08g(Lr5ZaUq&n-T-4K}H7ChN z%D+^>=yV;ph(CxT&snRXVDI!GGS)j|YJwuOX#p<{r9Hhg8O8VkD9?%Xw3hiR^!N7R4KYW`5CDZw7i%X-l+p+CGPbcwwB zLZhgFJr<{zORHME(*|lqsU`vC=0o3ZV7v9b-`s5b+YMe{h303~oi!&yXU%DGb{vkK z&3u-B@Iht7poA4>*hN&IV1jQaTVYiWS;;_E!8kV7TncTVNl|dRFw5){XzHvv;mxwD NzX4_MO(4Jm000Ov$-4jm diff --git a/core/web/assets/main.6f07a88cfc748f57e21d.js b/core/web/assets/main.2f351fafaaf99deb7f66.js similarity index 89% rename from core/web/assets/main.6f07a88cfc748f57e21d.js rename to core/web/assets/main.2f351fafaaf99deb7f66.js index bf6a280a99..0d616c49de 100644 --- a/core/web/assets/main.6f07a88cfc748f57e21d.js +++ b/core/web/assets/main.2f351fafaaf99deb7f66.js @@ -168,7 +168,7 @@ object-assign * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */ Object.defineProperty(t,"__esModule",{value:!0}),"undefined"==typeof window||"function"!=typeof MessageChannel){var n,r,i,a,o,s=null,u=null,c=function(){if(null!==s)try{var e=t.unstable_now();s(!0,e),s=null}catch(n){throw setTimeout(c,0),n}},l=Date.now();t.unstable_now=function(){return Date.now()-l},n=function(e){null!==s?setTimeout(n,0,e):(s=e,setTimeout(c,0))},r=function(e,t){u=setTimeout(e,t)},i=function(){clearTimeout(u)},a=function(){return!1},o=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,d=window.Date,h=window.setTimeout,p=window.clearTimeout;if("undefined"!=typeof console){var b=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof b&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var m=d.now();t.unstable_now=function(){return d.now()-m}}var g=!1,v=null,y=-1,w=5,_=0;a=function(){return t.unstable_now()>=_},o=function(){},t.unstable_forceFrameRate=function(e){0>e||125M(o,n))void 0!==u&&0>M(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[a]=n,r=a);else if(void 0!==u&&0>M(u,n))e[r]=u,e[s]=n,r=s;else break a}}return t}return null}function M(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var O=[],A=[],L=1,C=null,I=3,D=!1,N=!1,P=!1;function R(e){for(var t=x(A);null!==t;){if(null===t.callback)T(A);else if(t.startTime<=e)T(A),t.sortIndex=t.expirationTime,k(O,t);else break;t=x(A)}}function j(e){if(P=!1,R(e),!N){if(null!==x(O))N=!0,n(F);else{var t=x(A);null!==t&&r(j,t.startTime-e)}}}function F(e,n){N=!1,P&&(P=!1,i()),D=!0;var o=I;try{for(R(n),C=x(O);null!==C&&(!(C.expirationTime>n)||e&&!a());){var s=C.callback;if(null!==s){C.callback=null,I=C.priorityLevel;var u=s(C.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?C.callback=u:C===x(O)&&T(O),R(n)}else T(O);C=x(O)}if(null!==C)var c=!0;else{var l=x(A);null!==l&&r(j,l.startTime-n),c=!1}return c}finally{C=null,I=o,D=!1}}function Y(e){switch(e){case 1:return -1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var B=o;t.unstable_ImmediatePriority=1,t.unstable_UserBlockingPriority=2,t.unstable_NormalPriority=3,t.unstable_IdlePriority=5,t.unstable_LowPriority=4,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=I;I=e;try{return t()}finally{I=n}},t.unstable_next=function(e){switch(I){case 1:case 2:case 3:var t=3;break;default:t=I}var n=I;I=t;try{return e()}finally{I=n}},t.unstable_scheduleCallback=function(e,a,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0s?(e.sortIndex=u,k(A,e),null===x(O)&&e===x(A)&&(P?i():P=!0,r(j,u-s))):(e.sortIndex=o,k(O,e),N||D||(N=!0,n(F))),e},t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_wrapCallback=function(e){var t=I;return function(){var n=I;I=t;try{return e.apply(this,arguments)}finally{I=n}}},t.unstable_getCurrentPriorityLevel=function(){return I},t.unstable_shouldYield=function(){var e=t.unstable_now();R(e);var n=x(O);return n!==C&&null!==C&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function c(e,t,n){var r=t.length-1;if(r=0?(i>0&&(e.lastNeed=i-1),i):--r=0?(i>0&&(e.lastNeed=i-2),i):--r=0?(i>0&&(2===i?i=0:e.lastNeed=i-3),i):0}function l(e,t,n){if((192&t[0])!=128)return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if((192&t[1])!=128)return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&(192&t[2])!=128)return e.lastNeed=2,"�"}}function f(e){var t=this.lastTotal-this.lastNeed,n=l(this,e,t);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):void(e.copy(this.lastChar,t,0,e.length),this.lastNeed-=e.length)}function d(e,t){var n=c(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)}function h(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+"�":t}function p(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function b(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function m(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function g(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function v(e){return e.toString(this.encoding)}function y(e){return e&&e.length?this.write(e):""}t.s=s,s.prototype.write=function(e){var t,n;if(0===e.length)return"";if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n */ var r=n(48764),i=r.Buffer;function a(e,t){for(var n in e)t[n]=e[n]}function o(e,t,n){return i(e,t,n)}i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow?e.exports=r:(a(r,t),t.Buffer=o),o.prototype=Object.create(i.prototype),a(i,o),o.from=function(e,t,n){if("number"==typeof e)throw TypeError("Argument must not be a number");return i(e,t,n)},o.alloc=function(e,t,n){if("number"!=typeof e)throw TypeError("Argument must be a number");var r=i(e);return void 0!==t?"string"==typeof n?r.fill(t,n):r.fill(t):r.fill(0),r},o.allocUnsafe=function(e){if("number"!=typeof e)throw TypeError("Argument must be a number");return i(e)},o.allocUnsafeSlow=function(e){if("number"!=typeof e)throw TypeError("Argument must be a number");return r.SlowBuffer(e)}},93379(e,t,n){"use strict";var r,i,a=function(){return void 0===r&&(r=Boolean(window&&document&&document.all&&!window.atob)),r},o=(i={},function(e){if(void 0===i[e]){var t=document.querySelector(e);if(window.HTMLIFrameElement&&t instanceof window.HTMLIFrameElement)try{t=t.contentDocument.head}catch(n){t=null}i[e]=t}return i[e]}),s=[];function u(e){for(var t=-1,n=0;nOW});var r,i,a,o,s,u,c,l=n(67294),f=n.t(l,2),d=n(39814),h=n(5977),p=n(57209),b=n(32316),m=n(95880),g=n(17051),v=n(71381),y=n(81701),w=n(3022),_=n(60323),E=n(87591),S=n(25649),k=n(28902),x=n(71426),T=n(48884),M=n(94184),O=n.n(M),A=n(37703),L=n(73935),C=function(){if("undefined"!=typeof Map)return Map;function e(e,t){var n=-1;return e.some(function(e,r){return e[0]===t&&(n=r,!0)}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(t){var n=e(this.__entries__,t),r=this.__entries__[n];return r&&r[1]},t.prototype.set=function(t,n){var r=e(this.__entries__,t);~r?this.__entries__[r][1]=n:this.__entries__.push([t,n])},t.prototype.delete=function(t){var n=this.__entries__,r=e(n,t);~r&&n.splice(r,1)},t.prototype.has=function(t){return!!~e(this.__entries__,t)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(e,t){void 0===t&&(t=null);for(var n=0,r=this.__entries__;n0},e.prototype.connect_=function(){I&&!this.connected_&&(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),Y?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){I&&this.connected_&&(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(e){var t=e.propertyName,n=void 0===t?"":t;F.some(function(e){return!!~n.indexOf(e)})&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),U=function(e,t){for(var n=0,r=Object.keys(t);n0},e}(),er="undefined"!=typeof WeakMap?new WeakMap:new C,ei=function(){function e(t){if(!(this instanceof e))throw TypeError("Cannot call a class as a function.");if(!arguments.length)throw TypeError("1 argument required, but only 0 present.");var n=B.getInstance(),r=new en(t,n,this);er.set(this,r)}return e}();["observe","unobserve","disconnect"].forEach(function(e){ei.prototype[e]=function(){var t;return(t=er.get(this))[e].apply(t,arguments)}});var ea=void 0!==D.ResizeObserver?D.ResizeObserver:ei;let eo=ea;var es=function(e){var t=[],n=null,r=function(){for(var r=arguments.length,i=Array(r),a=0;a=t||n<0||f&&r>=a}function g(){var e=eb();if(m(e))return v(e);s=setTimeout(g,b(e))}function v(e){return(s=void 0,d&&r)?h(e):(r=i=void 0,o)}function y(){void 0!==s&&clearTimeout(s),c=0,r=u=i=s=void 0}function w(){return void 0===s?o:v(eb())}function _(){var e=eb(),n=m(e);if(r=arguments,i=this,u=e,n){if(void 0===s)return p(u);if(f)return clearTimeout(s),s=setTimeout(g,t),h(u)}return void 0===s&&(s=setTimeout(g,t)),o}return t=ez(t)||0,ed(n)&&(l=!!n.leading,a=(f="maxWait"in n)?eW(ez(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),_.cancel=y,_.flush=w,_}let eq=eV;var eZ="Expected a function";function eX(e,t,n){var r=!0,i=!0;if("function"!=typeof e)throw TypeError(eZ);return ed(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),eq(e,t,{leading:r,maxWait:t,trailing:i})}let eJ=eX;var eQ={debounce:eq,throttle:eJ},e1=function(e){return eQ[e]},e0=function(e){return"function"==typeof e},e2=function(){return"undefined"==typeof window},e3=function(e){return e instanceof Element||e instanceof HTMLDocument};function e4(e){return(e4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function e6(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function e5(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&l.createElement(tG.Z,{variant:"indeterminate",classes:r}))};tK.propTypes={fetchCount:el().number.isRequired};let tV=(0,b.withStyles)(tW)(tK);var tq=n(5536);let tZ=n.p+"ba8bbf16ebf8e1d05bef.svg";function tX(){return(tX=Object.assign||function(e){for(var t=1;t120){for(var d=Math.floor(u/80),h=u%80,p=[],b=0;b0},name:{enumerable:!1},nodes:{enumerable:!1},source:{enumerable:!1},positions:{enumerable:!1},originalError:{enumerable:!1}}),null!=s&&s.stack)?(Object.defineProperty(nf(b),"stack",{value:s.stack,writable:!0,configurable:!0}),nl(b)):(Error.captureStackTrace?Error.captureStackTrace(nf(b),n):Object.defineProperty(nf(b),"stack",{value:Error().stack,writable:!0,configurable:!0}),b)}return ns(n,[{key:"toString",value:function(){return nw(this)}},{key:t4.YF,get:function(){return"Object"}}]),n}(nd(Error));function ny(e){return void 0===e||0===e.length?void 0:e}function nw(e){var t=e.message;if(e.nodes)for(var n=0,r=e.nodes;n",EOF:"",BANG:"!",DOLLAR:"$",AMP:"&",PAREN_L:"(",PAREN_R:")",SPREAD:"...",COLON:":",EQUALS:"=",AT:"@",BRACKET_L:"[",BRACKET_R:"]",BRACE_L:"{",PIPE:"|",BRACE_R:"}",NAME:"Name",INT:"Int",FLOAT:"Float",STRING:"String",BLOCK_STRING:"BlockString",COMMENT:"Comment"}),nx=n(10143),nT=Object.freeze({QUERY:"QUERY",MUTATION:"MUTATION",SUBSCRIPTION:"SUBSCRIPTION",FIELD:"FIELD",FRAGMENT_DEFINITION:"FRAGMENT_DEFINITION",FRAGMENT_SPREAD:"FRAGMENT_SPREAD",INLINE_FRAGMENT:"INLINE_FRAGMENT",VARIABLE_DEFINITION:"VARIABLE_DEFINITION",SCHEMA:"SCHEMA",SCALAR:"SCALAR",OBJECT:"OBJECT",FIELD_DEFINITION:"FIELD_DEFINITION",ARGUMENT_DEFINITION:"ARGUMENT_DEFINITION",INTERFACE:"INTERFACE",UNION:"UNION",ENUM:"ENUM",ENUM_VALUE:"ENUM_VALUE",INPUT_OBJECT:"INPUT_OBJECT",INPUT_FIELD_DEFINITION:"INPUT_FIELD_DEFINITION"}),nM=n(87392),nO=function(){function e(e){var t=new nS.WU(nk.SOF,0,0,0,0,null);this.source=e,this.lastToken=t,this.token=t,this.line=1,this.lineStart=0}var t=e.prototype;return t.advance=function(){return this.lastToken=this.token,this.token=this.lookahead()},t.lookahead=function(){var e,t=this.token;if(t.kind!==nk.EOF)do t=null!==(e=t.next)&&void 0!==e?e:t.next=nC(this,t);while(t.kind===nk.COMMENT)return t},e}();function nA(e){return e===nk.BANG||e===nk.DOLLAR||e===nk.AMP||e===nk.PAREN_L||e===nk.PAREN_R||e===nk.SPREAD||e===nk.COLON||e===nk.EQUALS||e===nk.AT||e===nk.BRACKET_L||e===nk.BRACKET_R||e===nk.BRACE_L||e===nk.PIPE||e===nk.BRACE_R}function nL(e){return isNaN(e)?nk.EOF:e<127?JSON.stringify(String.fromCharCode(e)):'"\\u'.concat(("00"+e.toString(16).toUpperCase()).slice(-4),'"')}function nC(e,t){for(var n=e.source,r=n.body,i=r.length,a=t.end;a31||9===a))return new nS.WU(nk.COMMENT,t,s,n,r,i,o.slice(t+1,s))}function nN(e,t,n,r,i,a){var o=e.body,s=n,u=t,c=!1;if(45===s&&(s=o.charCodeAt(++u)),48===s){if((s=o.charCodeAt(++u))>=48&&s<=57)throw n_(e,u,"Invalid number, unexpected digit after 0: ".concat(nL(s),"."))}else u=nP(e,u,s),s=o.charCodeAt(u);if(46===s&&(c=!0,s=o.charCodeAt(++u),u=nP(e,u,s),s=o.charCodeAt(u)),(69===s||101===s)&&(c=!0,(43===(s=o.charCodeAt(++u))||45===s)&&(s=o.charCodeAt(++u)),u=nP(e,u,s),s=o.charCodeAt(u)),46===s||nU(s))throw n_(e,u,"Invalid number, expected digit but got: ".concat(nL(s),"."));return new nS.WU(c?nk.FLOAT:nk.INT,t,u,r,i,a,o.slice(t,u))}function nP(e,t,n){var r=e.body,i=t,a=n;if(a>=48&&a<=57){do a=r.charCodeAt(++i);while(a>=48&&a<=57)return i}throw n_(e,i,"Invalid number, expected digit but got: ".concat(nL(a),"."))}function nR(e,t,n,r,i){for(var a=e.body,o=t+1,s=o,u=0,c="";o=48&&e<=57?e-48:e>=65&&e<=70?e-55:e>=97&&e<=102?e-87:-1}function nB(e,t,n,r,i){for(var a=e.body,o=a.length,s=t+1,u=0;s!==o&&!isNaN(u=a.charCodeAt(s))&&(95===u||u>=48&&u<=57||u>=65&&u<=90||u>=97&&u<=122);)++s;return new nS.WU(nk.NAME,t,s,n,r,i,a.slice(t,s))}function nU(e){return 95===e||e>=65&&e<=90||e>=97&&e<=122}function nH(e,t){return new n$(e,t).parseDocument()}var n$=function(){function e(e,t){var n=(0,nx.T)(e)?e:new nx.H(e);this._lexer=new nO(n),this._options=t}var t=e.prototype;return t.parseName=function(){var e=this.expectToken(nk.NAME);return{kind:nE.h.NAME,value:e.value,loc:this.loc(e)}},t.parseDocument=function(){var e=this._lexer.token;return{kind:nE.h.DOCUMENT,definitions:this.many(nk.SOF,this.parseDefinition,nk.EOF),loc:this.loc(e)}},t.parseDefinition=function(){if(this.peek(nk.NAME))switch(this._lexer.token.value){case"query":case"mutation":case"subscription":return this.parseOperationDefinition();case"fragment":return this.parseFragmentDefinition();case"schema":case"scalar":case"type":case"interface":case"union":case"enum":case"input":case"directive":return this.parseTypeSystemDefinition();case"extend":return this.parseTypeSystemExtension()}else if(this.peek(nk.BRACE_L))return this.parseOperationDefinition();else if(this.peekDescription())return this.parseTypeSystemDefinition();throw this.unexpected()},t.parseOperationDefinition=function(){var e,t=this._lexer.token;if(this.peek(nk.BRACE_L))return{kind:nE.h.OPERATION_DEFINITION,operation:"query",name:void 0,variableDefinitions:[],directives:[],selectionSet:this.parseSelectionSet(),loc:this.loc(t)};var n=this.parseOperationType();return this.peek(nk.NAME)&&(e=this.parseName()),{kind:nE.h.OPERATION_DEFINITION,operation:n,name:e,variableDefinitions:this.parseVariableDefinitions(),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseOperationType=function(){var e=this.expectToken(nk.NAME);switch(e.value){case"query":return"query";case"mutation":return"mutation";case"subscription":return"subscription"}throw this.unexpected(e)},t.parseVariableDefinitions=function(){return this.optionalMany(nk.PAREN_L,this.parseVariableDefinition,nk.PAREN_R)},t.parseVariableDefinition=function(){var e=this._lexer.token;return{kind:nE.h.VARIABLE_DEFINITION,variable:this.parseVariable(),type:(this.expectToken(nk.COLON),this.parseTypeReference()),defaultValue:this.expectOptionalToken(nk.EQUALS)?this.parseValueLiteral(!0):void 0,directives:this.parseDirectives(!0),loc:this.loc(e)}},t.parseVariable=function(){var e=this._lexer.token;return this.expectToken(nk.DOLLAR),{kind:nE.h.VARIABLE,name:this.parseName(),loc:this.loc(e)}},t.parseSelectionSet=function(){var e=this._lexer.token;return{kind:nE.h.SELECTION_SET,selections:this.many(nk.BRACE_L,this.parseSelection,nk.BRACE_R),loc:this.loc(e)}},t.parseSelection=function(){return this.peek(nk.SPREAD)?this.parseFragment():this.parseField()},t.parseField=function(){var e,t,n=this._lexer.token,r=this.parseName();return this.expectOptionalToken(nk.COLON)?(e=r,t=this.parseName()):t=r,{kind:nE.h.FIELD,alias:e,name:t,arguments:this.parseArguments(!1),directives:this.parseDirectives(!1),selectionSet:this.peek(nk.BRACE_L)?this.parseSelectionSet():void 0,loc:this.loc(n)}},t.parseArguments=function(e){var t=e?this.parseConstArgument:this.parseArgument;return this.optionalMany(nk.PAREN_L,t,nk.PAREN_R)},t.parseArgument=function(){var e=this._lexer.token,t=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.ARGUMENT,name:t,value:this.parseValueLiteral(!1),loc:this.loc(e)}},t.parseConstArgument=function(){var e=this._lexer.token;return{kind:nE.h.ARGUMENT,name:this.parseName(),value:(this.expectToken(nk.COLON),this.parseValueLiteral(!0)),loc:this.loc(e)}},t.parseFragment=function(){var e=this._lexer.token;this.expectToken(nk.SPREAD);var t=this.expectOptionalKeyword("on");return!t&&this.peek(nk.NAME)?{kind:nE.h.FRAGMENT_SPREAD,name:this.parseFragmentName(),directives:this.parseDirectives(!1),loc:this.loc(e)}:{kind:nE.h.INLINE_FRAGMENT,typeCondition:t?this.parseNamedType():void 0,directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(e)}},t.parseFragmentDefinition=function(){var e,t=this._lexer.token;return(this.expectKeyword("fragment"),(null===(e=this._options)||void 0===e?void 0:e.experimentalFragmentVariables)===!0)?{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),variableDefinitions:this.parseVariableDefinitions(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}:{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseFragmentName=function(){if("on"===this._lexer.token.value)throw this.unexpected();return this.parseName()},t.parseValueLiteral=function(e){var t=this._lexer.token;switch(t.kind){case nk.BRACKET_L:return this.parseList(e);case nk.BRACE_L:return this.parseObject(e);case nk.INT:return this._lexer.advance(),{kind:nE.h.INT,value:t.value,loc:this.loc(t)};case nk.FLOAT:return this._lexer.advance(),{kind:nE.h.FLOAT,value:t.value,loc:this.loc(t)};case nk.STRING:case nk.BLOCK_STRING:return this.parseStringLiteral();case nk.NAME:switch(this._lexer.advance(),t.value){case"true":return{kind:nE.h.BOOLEAN,value:!0,loc:this.loc(t)};case"false":return{kind:nE.h.BOOLEAN,value:!1,loc:this.loc(t)};case"null":return{kind:nE.h.NULL,loc:this.loc(t)};default:return{kind:nE.h.ENUM,value:t.value,loc:this.loc(t)}}case nk.DOLLAR:if(!e)return this.parseVariable()}throw this.unexpected()},t.parseStringLiteral=function(){var e=this._lexer.token;return this._lexer.advance(),{kind:nE.h.STRING,value:e.value,block:e.kind===nk.BLOCK_STRING,loc:this.loc(e)}},t.parseList=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseValueLiteral(e)};return{kind:nE.h.LIST,values:this.any(nk.BRACKET_L,r,nk.BRACKET_R),loc:this.loc(n)}},t.parseObject=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseObjectField(e)};return{kind:nE.h.OBJECT,fields:this.any(nk.BRACE_L,r,nk.BRACE_R),loc:this.loc(n)}},t.parseObjectField=function(e){var t=this._lexer.token,n=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.OBJECT_FIELD,name:n,value:this.parseValueLiteral(e),loc:this.loc(t)}},t.parseDirectives=function(e){for(var t=[];this.peek(nk.AT);)t.push(this.parseDirective(e));return t},t.parseDirective=function(e){var t=this._lexer.token;return this.expectToken(nk.AT),{kind:nE.h.DIRECTIVE,name:this.parseName(),arguments:this.parseArguments(e),loc:this.loc(t)}},t.parseTypeReference=function(){var e,t=this._lexer.token;return(this.expectOptionalToken(nk.BRACKET_L)?(e=this.parseTypeReference(),this.expectToken(nk.BRACKET_R),e={kind:nE.h.LIST_TYPE,type:e,loc:this.loc(t)}):e=this.parseNamedType(),this.expectOptionalToken(nk.BANG))?{kind:nE.h.NON_NULL_TYPE,type:e,loc:this.loc(t)}:e},t.parseNamedType=function(){var e=this._lexer.token;return{kind:nE.h.NAMED_TYPE,name:this.parseName(),loc:this.loc(e)}},t.parseTypeSystemDefinition=function(){var e=this.peekDescription()?this._lexer.lookahead():this._lexer.token;if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaDefinition();case"scalar":return this.parseScalarTypeDefinition();case"type":return this.parseObjectTypeDefinition();case"interface":return this.parseInterfaceTypeDefinition();case"union":return this.parseUnionTypeDefinition();case"enum":return this.parseEnumTypeDefinition();case"input":return this.parseInputObjectTypeDefinition();case"directive":return this.parseDirectiveDefinition()}throw this.unexpected(e)},t.peekDescription=function(){return this.peek(nk.STRING)||this.peek(nk.BLOCK_STRING)},t.parseDescription=function(){if(this.peekDescription())return this.parseStringLiteral()},t.parseSchemaDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("schema");var n=this.parseDirectives(!0),r=this.many(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);return{kind:nE.h.SCHEMA_DEFINITION,description:t,directives:n,operationTypes:r,loc:this.loc(e)}},t.parseOperationTypeDefinition=function(){var e=this._lexer.token,t=this.parseOperationType();this.expectToken(nk.COLON);var n=this.parseNamedType();return{kind:nE.h.OPERATION_TYPE_DEFINITION,operation:t,type:n,loc:this.loc(e)}},t.parseScalarTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("scalar");var n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.SCALAR_TYPE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("type");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.OBJECT_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseImplementsInterfaces=function(){var e;if(!this.expectOptionalKeyword("implements"))return[];if((null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLImplementsInterfaces)===!0){var t=[];this.expectOptionalToken(nk.AMP);do t.push(this.parseNamedType());while(this.expectOptionalToken(nk.AMP)||this.peek(nk.NAME))return t}return this.delimitedMany(nk.AMP,this.parseNamedType)},t.parseFieldsDefinition=function(){var e;return(null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLEmptyFields)===!0&&this.peek(nk.BRACE_L)&&this._lexer.lookahead().kind===nk.BRACE_R?(this._lexer.advance(),this._lexer.advance(),[]):this.optionalMany(nk.BRACE_L,this.parseFieldDefinition,nk.BRACE_R)},t.parseFieldDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseArgumentDefs();this.expectToken(nk.COLON);var i=this.parseTypeReference(),a=this.parseDirectives(!0);return{kind:nE.h.FIELD_DEFINITION,description:t,name:n,arguments:r,type:i,directives:a,loc:this.loc(e)}},t.parseArgumentDefs=function(){return this.optionalMany(nk.PAREN_L,this.parseInputValueDef,nk.PAREN_R)},t.parseInputValueDef=function(){var e,t=this._lexer.token,n=this.parseDescription(),r=this.parseName();this.expectToken(nk.COLON);var i=this.parseTypeReference();this.expectOptionalToken(nk.EQUALS)&&(e=this.parseValueLiteral(!0));var a=this.parseDirectives(!0);return{kind:nE.h.INPUT_VALUE_DEFINITION,description:n,name:r,type:i,defaultValue:e,directives:a,loc:this.loc(t)}},t.parseInterfaceTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("interface");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.INTERFACE_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseUnionTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("union");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseUnionMemberTypes();return{kind:nE.h.UNION_TYPE_DEFINITION,description:t,name:n,directives:r,types:i,loc:this.loc(e)}},t.parseUnionMemberTypes=function(){return this.expectOptionalToken(nk.EQUALS)?this.delimitedMany(nk.PIPE,this.parseNamedType):[]},t.parseEnumTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("enum");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseEnumValuesDefinition();return{kind:nE.h.ENUM_TYPE_DEFINITION,description:t,name:n,directives:r,values:i,loc:this.loc(e)}},t.parseEnumValuesDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseEnumValueDefinition,nk.BRACE_R)},t.parseEnumValueDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.ENUM_VALUE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseInputObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("input");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseInputFieldsDefinition();return{kind:nE.h.INPUT_OBJECT_TYPE_DEFINITION,description:t,name:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInputFieldsDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseInputValueDef,nk.BRACE_R)},t.parseTypeSystemExtension=function(){var e=this._lexer.lookahead();if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaExtension();case"scalar":return this.parseScalarTypeExtension();case"type":return this.parseObjectTypeExtension();case"interface":return this.parseInterfaceTypeExtension();case"union":return this.parseUnionTypeExtension();case"enum":return this.parseEnumTypeExtension();case"input":return this.parseInputObjectTypeExtension()}throw this.unexpected(e)},t.parseSchemaExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("schema");var t=this.parseDirectives(!0),n=this.optionalMany(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);if(0===t.length&&0===n.length)throw this.unexpected();return{kind:nE.h.SCHEMA_EXTENSION,directives:t,operationTypes:n,loc:this.loc(e)}},t.parseScalarTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("scalar");var t=this.parseName(),n=this.parseDirectives(!0);if(0===n.length)throw this.unexpected();return{kind:nE.h.SCALAR_TYPE_EXTENSION,name:t,directives:n,loc:this.loc(e)}},t.parseObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("type");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.OBJECT_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInterfaceTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("interface");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.INTERFACE_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseUnionTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("union");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseUnionMemberTypes();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.UNION_TYPE_EXTENSION,name:t,directives:n,types:r,loc:this.loc(e)}},t.parseEnumTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("enum");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseEnumValuesDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.ENUM_TYPE_EXTENSION,name:t,directives:n,values:r,loc:this.loc(e)}},t.parseInputObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("input");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseInputFieldsDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.INPUT_OBJECT_TYPE_EXTENSION,name:t,directives:n,fields:r,loc:this.loc(e)}},t.parseDirectiveDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("directive"),this.expectToken(nk.AT);var n=this.parseName(),r=this.parseArgumentDefs(),i=this.expectOptionalKeyword("repeatable");this.expectKeyword("on");var a=this.parseDirectiveLocations();return{kind:nE.h.DIRECTIVE_DEFINITION,description:t,name:n,arguments:r,repeatable:i,locations:a,loc:this.loc(e)}},t.parseDirectiveLocations=function(){return this.delimitedMany(nk.PIPE,this.parseDirectiveLocation)},t.parseDirectiveLocation=function(){var e=this._lexer.token,t=this.parseName();if(void 0!==nT[t.value])return t;throw this.unexpected(e)},t.loc=function(e){var t;if((null===(t=this._options)||void 0===t?void 0:t.noLocation)!==!0)return new nS.Ye(e,this._lexer.lastToken,this._lexer.source)},t.peek=function(e){return this._lexer.token.kind===e},t.expectToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t;throw n_(this._lexer.source,t.start,"Expected ".concat(nG(e),", found ").concat(nz(t),"."))},t.expectOptionalToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t},t.expectKeyword=function(e){var t=this._lexer.token;if(t.kind===nk.NAME&&t.value===e)this._lexer.advance();else throw n_(this._lexer.source,t.start,'Expected "'.concat(e,'", found ').concat(nz(t),"."))},t.expectOptionalKeyword=function(e){var t=this._lexer.token;return t.kind===nk.NAME&&t.value===e&&(this._lexer.advance(),!0)},t.unexpected=function(e){var t=null!=e?e:this._lexer.token;return n_(this._lexer.source,t.start,"Unexpected ".concat(nz(t),"."))},t.any=function(e,t,n){this.expectToken(e);for(var r=[];!this.expectOptionalToken(n);)r.push(t.call(this));return r},t.optionalMany=function(e,t,n){if(this.expectOptionalToken(e)){var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r}return[]},t.many=function(e,t,n){this.expectToken(e);var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r},t.delimitedMany=function(e,t){this.expectOptionalToken(e);var n=[];do n.push(t.call(this));while(this.expectOptionalToken(e))return n},e}();function nz(e){var t=e.value;return nG(e.kind)+(null!=t?' "'.concat(t,'"'):"")}function nG(e){return nA(e)?'"'.concat(e,'"'):e}var nW=new Map,nK=new Map,nV=!0,nq=!1;function nZ(e){return e.replace(/[\s,]+/g," ").trim()}function nX(e){return nZ(e.source.body.substring(e.start,e.end))}function nJ(e){var t=new Set,n=[];return e.definitions.forEach(function(e){if("FragmentDefinition"===e.kind){var r=e.name.value,i=nX(e.loc),a=nK.get(r);a&&!a.has(i)?nV&&console.warn("Warning: fragment with name "+r+" already exists.\ngraphql-tag enforces all fragment names across your application to be unique; read more about\nthis in the docs: http://dev.apollodata.com/core/fragments.html#unique-names"):a||nK.set(r,a=new Set),a.add(i),t.has(i)||(t.add(i),n.push(e))}else n.push(e)}),(0,t0.pi)((0,t0.pi)({},e),{definitions:n})}function nQ(e){var t=new Set(e.definitions);t.forEach(function(e){e.loc&&delete e.loc,Object.keys(e).forEach(function(n){var r=e[n];r&&"object"==typeof r&&t.add(r)})});var n=e.loc;return n&&(delete n.startToken,delete n.endToken),e}function n1(e){var t=nZ(e);if(!nW.has(t)){var n=nH(e,{experimentalFragmentVariables:nq,allowLegacyFragmentVariables:nq});if(!n||"Document"!==n.kind)throw Error("Not a valid GraphQL document.");nW.set(t,nQ(nJ(n)))}return nW.get(t)}function n0(e){for(var t=[],n=1;n, or pass an ApolloClient instance in via options.'):(0,n9.kG)(!!n,32),n}var rp=n(10542),rb=n(53712),rm=n(21436),rg=Object.prototype.hasOwnProperty;function rv(e,t){return void 0===t&&(t=Object.create(null)),ry(rh(t.client),e).useQuery(t)}function ry(e,t){var n=(0,l.useRef)();n.current&&e===n.current.client&&t===n.current.query||(n.current=new rw(e,t,n.current));var r=n.current,i=(0,l.useState)(0),a=(i[0],i[1]);return r.forceUpdate=function(){a(function(e){return e+1})},r}var rw=function(){function e(e,t,n){this.client=e,this.query=t,this.ssrDisabledResult=(0,rp.J)({loading:!0,data:void 0,error:void 0,networkStatus:ru.I.loading}),this.skipStandbyResult=(0,rp.J)({loading:!1,data:void 0,error:void 0,networkStatus:ru.I.ready}),this.toQueryResultCache=new(n7.mr?WeakMap:Map),rd(t,r.Query);var i=n&&n.result,a=i&&i.data;a&&(this.previousData=a)}return e.prototype.forceUpdate=function(){__DEV__&&n9.kG.warn("Calling default no-op implementation of InternalState#forceUpdate")},e.prototype.executeQuery=function(e){var t,n=this;e.query&&Object.assign(this,{query:e.query}),this.watchQueryOptions=this.createWatchQueryOptions(this.queryHookOptions=e);var r=this.observable.reobserveAsConcast(this.getObsQueryOptions());return this.previousData=(null===(t=this.result)||void 0===t?void 0:t.data)||this.previousData,this.result=void 0,this.forceUpdate(),new Promise(function(e){var t;r.subscribe({next:function(e){t=e},error:function(){e(n.toQueryResult(n.observable.getCurrentResult()))},complete:function(){e(n.toQueryResult(t))}})})},e.prototype.useQuery=function(e){var t=this;this.renderPromises=(0,l.useContext)((0,ro.K)()).renderPromises,this.useOptions(e);var n=this.useObservableQuery(),r=rt((0,l.useCallback)(function(){if(t.renderPromises)return function(){};var e=function(){var e=t.result,r=n.getCurrentResult();!(e&&e.loading===r.loading&&e.networkStatus===r.networkStatus&&(0,ri.D)(e.data,r.data))&&t.setResult(r)},r=function(a){var o=n.last;i.unsubscribe();try{n.resetLastResults(),i=n.subscribe(e,r)}finally{n.last=o}if(!rg.call(a,"graphQLErrors"))throw a;var s=t.result;(!s||s&&s.loading||!(0,ri.D)(a,s.error))&&t.setResult({data:s&&s.data,error:a,loading:!1,networkStatus:ru.I.error})},i=n.subscribe(e,r);return function(){return setTimeout(function(){return i.unsubscribe()})}},[n,this.renderPromises,this.client.disableNetworkFetches,]),function(){return t.getCurrentResult()},function(){return t.getCurrentResult()});return this.unsafeHandlePartialRefetch(r),this.toQueryResult(r)},e.prototype.useOptions=function(t){var n,r=this.createWatchQueryOptions(this.queryHookOptions=t),i=this.watchQueryOptions;!(0,ri.D)(r,i)&&(this.watchQueryOptions=r,i&&this.observable&&(this.observable.reobserve(this.getObsQueryOptions()),this.previousData=(null===(n=this.result)||void 0===n?void 0:n.data)||this.previousData,this.result=void 0)),this.onCompleted=t.onCompleted||e.prototype.onCompleted,this.onError=t.onError||e.prototype.onError,(this.renderPromises||this.client.disableNetworkFetches)&&!1===this.queryHookOptions.ssr&&!this.queryHookOptions.skip?this.result=this.ssrDisabledResult:this.queryHookOptions.skip||"standby"===this.watchQueryOptions.fetchPolicy?this.result=this.skipStandbyResult:(this.result===this.ssrDisabledResult||this.result===this.skipStandbyResult)&&(this.result=void 0)},e.prototype.getObsQueryOptions=function(){var e=[],t=this.client.defaultOptions.watchQuery;return t&&e.push(t),this.queryHookOptions.defaultOptions&&e.push(this.queryHookOptions.defaultOptions),e.push((0,rb.o)(this.observable&&this.observable.options,this.watchQueryOptions)),e.reduce(ra.J)},e.prototype.createWatchQueryOptions=function(e){void 0===e&&(e={});var t,n=e.skip,r=Object.assign((e.ssr,e.onCompleted,e.onError,e.defaultOptions,(0,t0._T)(e,["skip","ssr","onCompleted","onError","defaultOptions"])),{query:this.query});if(this.renderPromises&&("network-only"===r.fetchPolicy||"cache-and-network"===r.fetchPolicy)&&(r.fetchPolicy="cache-first"),r.variables||(r.variables={}),n){var i=r.fetchPolicy,a=void 0===i?this.getDefaultFetchPolicy():i,o=r.initialFetchPolicy;Object.assign(r,{initialFetchPolicy:void 0===o?a:o,fetchPolicy:"standby"})}else r.fetchPolicy||(r.fetchPolicy=(null===(t=this.observable)||void 0===t?void 0:t.options.initialFetchPolicy)||this.getDefaultFetchPolicy());return r},e.prototype.getDefaultFetchPolicy=function(){var e,t;return(null===(e=this.queryHookOptions.defaultOptions)||void 0===e?void 0:e.fetchPolicy)||(null===(t=this.client.defaultOptions.watchQuery)||void 0===t?void 0:t.fetchPolicy)||"cache-first"},e.prototype.onCompleted=function(e){},e.prototype.onError=function(e){},e.prototype.useObservableQuery=function(){var e=this.observable=this.renderPromises&&this.renderPromises.getSSRObservable(this.watchQueryOptions)||this.observable||this.client.watchQuery(this.getObsQueryOptions());this.obsQueryFields=(0,l.useMemo)(function(){return{refetch:e.refetch.bind(e),reobserve:e.reobserve.bind(e),fetchMore:e.fetchMore.bind(e),updateQuery:e.updateQuery.bind(e),startPolling:e.startPolling.bind(e),stopPolling:e.stopPolling.bind(e),subscribeToMore:e.subscribeToMore.bind(e)}},[e]);var t=!(!1===this.queryHookOptions.ssr||this.queryHookOptions.skip);return this.renderPromises&&t&&(this.renderPromises.registerSSRObservable(e),e.getCurrentResult().loading&&this.renderPromises.addObservableQueryPromise(e)),e},e.prototype.setResult=function(e){var t=this.result;t&&t.data&&(this.previousData=t.data),this.result=e,this.forceUpdate(),this.handleErrorOrCompleted(e)},e.prototype.handleErrorOrCompleted=function(e){var t=this;if(!e.loading){var n=this.toApolloError(e);Promise.resolve().then(function(){n?t.onError(n):e.data&&t.onCompleted(e.data)}).catch(function(e){__DEV__&&n9.kG.warn(e)})}},e.prototype.toApolloError=function(e){return(0,rm.O)(e.errors)?new rs.cA({graphQLErrors:e.errors}):e.error},e.prototype.getCurrentResult=function(){return this.result||this.handleErrorOrCompleted(this.result=this.observable.getCurrentResult()),this.result},e.prototype.toQueryResult=function(e){var t=this.toQueryResultCache.get(e);if(t)return t;var n=e.data,r=(e.partial,(0,t0._T)(e,["data","partial"]));return this.toQueryResultCache.set(e,t=(0,t0.pi)((0,t0.pi)((0,t0.pi)({data:n},r),this.obsQueryFields),{client:this.client,observable:this.observable,variables:this.observable.variables,called:!this.queryHookOptions.skip,previousData:this.previousData})),!t.error&&(0,rm.O)(e.errors)&&(t.error=new rs.cA({graphQLErrors:e.errors})),t},e.prototype.unsafeHandlePartialRefetch=function(e){e.partial&&this.queryHookOptions.partialRefetch&&!e.loading&&(!e.data||0===Object.keys(e.data).length)&&"cache-only"!==this.observable.options.fetchPolicy&&(Object.assign(e,{loading:!0,networkStatus:ru.I.refetch}),this.observable.refetch())},e}();function r_(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:{};return rv(iH,e)},iz=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"50",10),r=i$({variables:{offset:(t-1)*n,limit:n},fetchPolicy:"network-only"}),i=r.data,a=r.loading,o=r.error;return a?l.createElement(iR,null):o?l.createElement(iD,{error:o}):i?l.createElement(iI,{chains:i.chains.results,page:t,pageSize:n,total:i.chains.metadata.total}):null},iG=n(67932),iW=n(8126),iK="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function iV(e){if(iq())return Intl.DateTimeFormat.supportedLocalesOf(e)[0]}function iq(){return("undefined"==typeof Intl?"undefined":iK(Intl))==="object"&&"function"==typeof Intl.DateTimeFormat}var iZ="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},iX=function(){function e(e,t){for(var n=0;n=i.length)break;s=i[o++]}else{if((o=i.next()).done)break;s=o.value}var s,u=s;if((void 0===e?"undefined":iZ(e))!=="object")return;e=e[u]}return e}},{key:"put",value:function(){for(var e=arguments.length,t=Array(e),n=0;n=o.length)break;c=o[u++]}else{if((u=o.next()).done)break;c=u.value}var c,l=c;"object"!==iZ(a[l])&&(a[l]={}),a=a[l]}return a[i]=r}}]),e}();let i1=iQ;var i0=new i1;function i2(e,t){if(!iq())return function(e){return e.toString()};var n=i4(e),r=JSON.stringify(t),i=i0.get(String(n),r)||i0.put(String(n),r,new Intl.DateTimeFormat(n,t));return function(e){return i.format(e)}}var i3={};function i4(e){var t=e.toString();return i3[t]?i3[t]:i3[t]=iV(e)}var i6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function i5(e){return i8(e)?e:new Date(e)}function i8(e){return e instanceof Date||i9(e)}function i9(e){return(void 0===e?"undefined":i6(e))==="object"&&"function"==typeof e.getTime}var i7=n(54087),ae=n.n(i7);function at(e,t){if(0===e.length)return 0;for(var n=0,r=e.length-1,i=void 0;n<=r;){var a=t(e[i=Math.floor((r+n)/2)]);if(0===a)return i;if(a<0){if((n=i+1)>r)return n}else if((r=i-1)=t.nextUpdateTime)aa(t,this.instances);else break}},scheduleNextTick:function(){var e=this;this.scheduledTick=ae()(function(){e.tick(),e.scheduleNextTick()})},start:function(){this.scheduleNextTick()},stop:function(){ae().cancel(this.scheduledTick)}};function ai(e){var t=an(e.getNextValue(),2),n=t[0],r=t[1];e.setValue(n),e.nextUpdateTime=r}function aa(e,t){ai(e),as(t,e),ao(t,e)}function ao(e,t){var n=au(e,t);e.splice(n,0,t)}function as(e,t){var n=e.indexOf(t);e.splice(n,1)}function au(e,t){var n=t.nextUpdateTime;return at(e,function(e){return e.nextUpdateTime===n?0:e.nextUpdateTime>n?1:-1})}var ac=(0,ec.oneOfType)([(0,ec.shape)({minTime:ec.number,formatAs:ec.string.isRequired}),(0,ec.shape)({test:ec.func,formatAs:ec.string.isRequired}),(0,ec.shape)({minTime:ec.number,format:ec.func.isRequired}),(0,ec.shape)({test:ec.func,format:ec.func.isRequired})]),al=(0,ec.oneOfType)([ec.string,(0,ec.shape)({steps:(0,ec.arrayOf)(ac).isRequired,labels:(0,ec.oneOfType)([ec.string,(0,ec.arrayOf)(ec.string)]).isRequired,round:ec.string})]),af=Object.assign||function(e){for(var t=1;t=0)&&Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function ap(e){var t=e.date,n=e.future,r=e.timeStyle,i=e.round,a=e.minTimeLeft,o=e.tooltip,s=e.component,u=e.container,c=e.wrapperComponent,f=e.wrapperProps,d=e.locale,h=e.locales,p=e.formatVerboseDate,b=e.verboseDateFormat,m=e.updateInterval,g=e.tick,v=ah(e,["date","future","timeStyle","round","minTimeLeft","tooltip","component","container","wrapperComponent","wrapperProps","locale","locales","formatVerboseDate","verboseDateFormat","updateInterval","tick"]),y=(0,l.useMemo)(function(){return d&&(h=[d]),h.concat(iW.Z.getDefaultLocale())},[d,h]),w=(0,l.useMemo)(function(){return new iW.Z(y)},[y]);t=(0,l.useMemo)(function(){return i5(t)},[t]);var _=(0,l.useCallback)(function(){var e=Date.now(),o=void 0;if(n&&e>=t.getTime()&&(e=t.getTime(),o=!0),void 0!==a){var s=t.getTime()-1e3*a;e>s&&(e=s,o=!0)}var u=w.format(t,r,{getTimeToNextUpdate:!0,now:e,future:n,round:i}),c=ad(u,2),l=c[0],f=c[1];return f=o?ag:m||f||6e4,[l,e+f]},[t,n,r,m,i,a,w]),E=(0,l.useRef)();E.current=_;var S=(0,l.useMemo)(_,[]),k=ad(S,2),x=k[0],T=k[1],M=(0,l.useState)(x),O=ad(M,2),A=O[0],L=O[1],C=ad((0,l.useState)(),2),I=C[0],D=C[1],N=(0,l.useRef)();(0,l.useEffect)(function(){if(g)return N.current=ar.add({getNextValue:function(){return E.current()},setValue:L,nextUpdateTime:T}),function(){return N.current.stop()}},[g]),(0,l.useEffect)(function(){if(N.current)N.current.forceUpdate();else{var e=_(),t=ad(e,1)[0];L(t)}},[_]),(0,l.useEffect)(function(){D(!0)},[]);var P=(0,l.useMemo)(function(){if("undefined"!=typeof window)return i2(y,b)},[y,b]),R=(0,l.useMemo)(function(){if("undefined"!=typeof window)return p?p(t):P(t)},[t,p,P]),j=l.createElement(s,af({date:t,verboseDate:I?R:void 0,tooltip:o},v),A),F=c||u;return F?l.createElement(F,af({},f,{verboseDate:I?R:void 0}),j):j}ap.propTypes={date:el().oneOfType([el().instanceOf(Date),el().number]).isRequired,locale:el().string,locales:el().arrayOf(el().string),future:el().bool,timeStyle:al,round:el().string,minTimeLeft:el().number,component:el().elementType.isRequired,tooltip:el().bool.isRequired,formatVerboseDate:el().func,verboseDateFormat:el().object,updateInterval:el().oneOfType([el().number,el().arrayOf(el().shape({threshold:el().number,interval:el().number.isRequired}))]),tick:el().bool,wrapperComponent:el().func,wrapperProps:el().object},ap.defaultProps={locales:[],component:av,tooltip:!0,verboseDateFormat:{weekday:"long",day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"2-digit",second:"2-digit"},tick:!0},ap=l.memo(ap);let ab=ap;var am,ag=31536e9;function av(e){var t=e.date,n=e.verboseDate,r=e.tooltip,i=e.children,a=ah(e,["date","verboseDate","tooltip","children"]),o=(0,l.useMemo)(function(){return t.toISOString()},[t]);return l.createElement("time",af({},a,{dateTime:o,title:r?n:void 0}),i)}av.propTypes={date:el().instanceOf(Date).isRequired,verboseDate:el().string,tooltip:el().bool.isRequired,children:el().string.isRequired};var ay=n(30381),aw=n.n(ay),a_=n(31657);function aE(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function aS(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0?new rs.cA({graphQLErrors:i}):void 0;if(u===s.current.mutationId&&!c.ignoreResults){var f={called:!0,loading:!1,data:r,error:l,client:a};s.current.isMounted&&!(0,ri.D)(s.current.result,f)&&o(s.current.result=f)}var d=e.onCompleted||(null===(n=s.current.options)||void 0===n?void 0:n.onCompleted);return null==d||d(t.data,c),t}).catch(function(t){if(u===s.current.mutationId&&s.current.isMounted){var n,r={loading:!1,error:t,data:void 0,called:!0,client:a};(0,ri.D)(s.current.result,r)||o(s.current.result=r)}var i=e.onError||(null===(n=s.current.options)||void 0===n?void 0:n.onError);if(i)return i(t,c),{data:void 0,errors:t};throw t})},[]),c=(0,l.useCallback)(function(){s.current.isMounted&&o({called:!1,loading:!1,client:n})},[]);return(0,l.useEffect)(function(){return s.current.isMounted=!0,function(){s.current.isMounted=!1}},[]),[u,(0,t0.pi)({reset:c},a)]}var os=n(59067),ou=n(28428),oc=n(11186),ol=n(78513);function of(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var od=function(e){return(0,b.createStyles)({paper:{display:"flex",margin:"".concat(2.5*e.spacing.unit,"px 0"),padding:"".concat(3*e.spacing.unit,"px ").concat(3.5*e.spacing.unit,"px")},content:{flex:1,width:"100%"},actions:of({marginTop:-(1.5*e.spacing.unit),marginLeft:-(4*e.spacing.unit)},e.breakpoints.up("sm"),{marginLeft:0,marginRight:-(1.5*e.spacing.unit)}),itemBlock:{border:"1px solid rgba(224, 224, 224, 1)",borderRadius:e.shape.borderRadius,padding:2*e.spacing.unit,marginTop:e.spacing.unit},itemBlockText:{overflowWrap:"anywhere"}})},oh=(0,b.withStyles)(od)(function(e){var t=e.actions,n=e.children,r=e.classes;return l.createElement(ii.default,{className:r.paper},l.createElement("div",{className:r.content},n),t&&l.createElement("div",{className:r.actions},t))}),op=function(e){var t=e.title;return l.createElement(x.default,{variant:"subtitle2",gutterBottom:!0},t)},ob=function(e){var t=e.children,n=e.value;return l.createElement(x.default,{variant:"body1",noWrap:!0},t||n)},om=(0,b.withStyles)(od)(function(e){var t=e.children,n=e.classes,r=e.value;return l.createElement("div",{className:n.itemBlock},l.createElement(x.default,{variant:"body1",className:n.itemBlockText},t||r))});function og(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]-1}let sq=sV;function sZ(e,t){var n=this.__data__,r=sH(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}let sX=sZ;function sJ(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e-1&&e%1==0&&e<=cC}let cD=cI;var cN="[object Arguments]",cP="[object Array]",cR="[object Boolean]",cj="[object Date]",cF="[object Error]",cY="[object Function]",cB="[object Map]",cU="[object Number]",cH="[object Object]",c$="[object RegExp]",cz="[object Set]",cG="[object String]",cW="[object WeakMap]",cK="[object ArrayBuffer]",cV="[object DataView]",cq="[object Float64Array]",cZ="[object Int8Array]",cX="[object Int16Array]",cJ="[object Int32Array]",cQ="[object Uint8Array]",c1="[object Uint8ClampedArray]",c0="[object Uint16Array]",c2="[object Uint32Array]",c3={};function c4(e){return eD(e)&&cD(e.length)&&!!c3[eC(e)]}c3["[object Float32Array]"]=c3[cq]=c3[cZ]=c3[cX]=c3[cJ]=c3[cQ]=c3[c1]=c3[c0]=c3[c2]=!0,c3[cN]=c3[cP]=c3[cK]=c3[cR]=c3[cV]=c3[cj]=c3[cF]=c3[cY]=c3[cB]=c3[cU]=c3[cH]=c3[c$]=c3[cz]=c3[cG]=c3[cW]=!1;let c6=c4;function c5(e){return function(t){return e(t)}}let c8=c5;var c9=n(79730),c7=c9.Z&&c9.Z.isTypedArray,le=c7?c8(c7):c6;let lt=le;var ln=Object.prototype.hasOwnProperty;function lr(e,t){var n=cx(e),r=!n&&cS(e),i=!n&&!r&&(0,cT.Z)(e),a=!n&&!r&&!i&<(e),o=n||r||i||a,s=o?cb(e.length,String):[],u=s.length;for(var c in e)(t||ln.call(e,c))&&!(o&&("length"==c||i&&("offset"==c||"parent"==c)||a&&("buffer"==c||"byteLength"==c||"byteOffset"==c)||cL(c,u)))&&s.push(c);return s}let li=lr;var la=Object.prototype;function lo(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||la)}let ls=lo;var lu=sT(Object.keys,Object);let lc=lu;var ll=Object.prototype.hasOwnProperty;function lf(e){if(!ls(e))return lc(e);var t=[];for(var n in Object(e))ll.call(e,n)&&"constructor"!=n&&t.push(n);return t}let ld=lf;function lh(e){return null!=e&&cD(e.length)&&!ur(e)}let lp=lh;function lb(e){return lp(e)?li(e):ld(e)}let lm=lb;function lg(e,t){return e&&ch(t,lm(t),e)}let lv=lg;function ly(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}let lw=ly;var l_=Object.prototype.hasOwnProperty;function lE(e){if(!ed(e))return lw(e);var t=ls(e),n=[];for(var r in e)"constructor"==r&&(t||!l_.call(e,r))||n.push(r);return n}let lS=lE;function lk(e){return lp(e)?li(e,!0):lS(e)}let lx=lk;function lT(e,t){return e&&ch(t,lx(t),e)}let lM=lT;var lO=n(42896);function lA(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n=0||(i[n]=e[n]);return i}function hu(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}var hc=function(e){return Array.isArray(e)&&0===e.length},hl=function(e){return"function"==typeof e},hf=function(e){return null!==e&&"object"==typeof e},hd=function(e){return String(Math.floor(Number(e)))===e},hh=function(e){return"[object String]"===Object.prototype.toString.call(e)},hp=function(e){return 0===l.Children.count(e)},hb=function(e){return hf(e)&&hl(e.then)};function hm(e,t,n,r){void 0===r&&(r=0);for(var i=d8(t);e&&r=0?[]:{}}}return(0===a?e:i)[o[a]]===n?e:(void 0===n?delete i[o[a]]:i[o[a]]=n,0===a&&void 0===n&&delete r[o[a]],r)}function hv(e,t,n,r){void 0===n&&(n=new WeakMap),void 0===r&&(r={});for(var i=0,a=Object.keys(e);i0?t.map(function(t){return x(t,hm(e,t))}):[Promise.resolve("DO_NOT_DELETE_YOU_WILL_BE_FIRED")]).then(function(e){return e.reduce(function(e,n,r){return"DO_NOT_DELETE_YOU_WILL_BE_FIRED"===n||n&&(e=hg(e,t[r],n)),e},{})})},[x]),M=(0,l.useCallback)(function(e){return Promise.all([T(e),h.validationSchema?k(e):{},h.validate?S(e):{}]).then(function(e){var t=e[0],n=e[1],r=e[2];return sk.all([t,n,r],{arrayMerge:hL})})},[h.validate,h.validationSchema,T,S,k]),O=hN(function(e){return void 0===e&&(e=_.values),E({type:"SET_ISVALIDATING",payload:!0}),M(e).then(function(e){return v.current&&(E({type:"SET_ISVALIDATING",payload:!1}),sd()(_.errors,e)||E({type:"SET_ERRORS",payload:e})),e})});(0,l.useEffect)(function(){o&&!0===v.current&&sd()(p.current,h.initialValues)&&O(p.current)},[o,O]);var A=(0,l.useCallback)(function(e){var t=e&&e.values?e.values:p.current,n=e&&e.errors?e.errors:b.current?b.current:h.initialErrors||{},r=e&&e.touched?e.touched:m.current?m.current:h.initialTouched||{},i=e&&e.status?e.status:g.current?g.current:h.initialStatus;p.current=t,b.current=n,m.current=r,g.current=i;var a=function(){E({type:"RESET_FORM",payload:{isSubmitting:!!e&&!!e.isSubmitting,errors:n,touched:r,status:i,values:t,isValidating:!!e&&!!e.isValidating,submitCount:e&&e.submitCount&&"number"==typeof e.submitCount?e.submitCount:0}})};if(h.onReset){var o=h.onReset(_.values,V);hb(o)?o.then(a):a()}else a()},[h.initialErrors,h.initialStatus,h.initialTouched]);(0,l.useEffect)(function(){!0===v.current&&!sd()(p.current,h.initialValues)&&(c&&(p.current=h.initialValues,A()),o&&O(p.current))},[c,h.initialValues,A,o,O]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(b.current,h.initialErrors)&&(b.current=h.initialErrors||hS,E({type:"SET_ERRORS",payload:h.initialErrors||hS}))},[c,h.initialErrors]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(m.current,h.initialTouched)&&(m.current=h.initialTouched||hk,E({type:"SET_TOUCHED",payload:h.initialTouched||hk}))},[c,h.initialTouched]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(g.current,h.initialStatus)&&(g.current=h.initialStatus,E({type:"SET_STATUS",payload:h.initialStatus}))},[c,h.initialStatus,h.initialTouched]);var L=hN(function(e){if(y.current[e]&&hl(y.current[e].validate)){var t=hm(_.values,e),n=y.current[e].validate(t);return hb(n)?(E({type:"SET_ISVALIDATING",payload:!0}),n.then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}}),E({type:"SET_ISVALIDATING",payload:!1})})):(E({type:"SET_FIELD_ERROR",payload:{field:e,value:n}}),Promise.resolve(n))}return h.validationSchema?(E({type:"SET_ISVALIDATING",payload:!0}),k(_.values,e).then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t[e]}}),E({type:"SET_ISVALIDATING",payload:!1})})):Promise.resolve()}),C=(0,l.useCallback)(function(e,t){var n=t.validate;y.current[e]={validate:n}},[]),I=(0,l.useCallback)(function(e){delete y.current[e]},[]),D=hN(function(e,t){return E({type:"SET_TOUCHED",payload:e}),(void 0===t?i:t)?O(_.values):Promise.resolve()}),N=(0,l.useCallback)(function(e){E({type:"SET_ERRORS",payload:e})},[]),P=hN(function(e,t){var r=hl(e)?e(_.values):e;return E({type:"SET_VALUES",payload:r}),(void 0===t?n:t)?O(r):Promise.resolve()}),R=(0,l.useCallback)(function(e,t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}})},[]),j=hN(function(e,t,r){return E({type:"SET_FIELD_VALUE",payload:{field:e,value:t}}),(void 0===r?n:r)?O(hg(_.values,e,t)):Promise.resolve()}),F=(0,l.useCallback)(function(e,t){var n,r=t,i=e;if(!hh(e)){e.persist&&e.persist();var a=e.target?e.target:e.currentTarget,o=a.type,s=a.name,u=a.id,c=a.value,l=a.checked,f=(a.outerHTML,a.options),d=a.multiple;r=t||s||u,i=/number|range/.test(o)?(n=parseFloat(c),isNaN(n)?"":n):/checkbox/.test(o)?hI(hm(_.values,r),l,c):d?hC(f):c}r&&j(r,i)},[j,_.values]),Y=hN(function(e){if(hh(e))return function(t){return F(t,e)};F(e)}),B=hN(function(e,t,n){return void 0===t&&(t=!0),E({type:"SET_FIELD_TOUCHED",payload:{field:e,value:t}}),(void 0===n?i:n)?O(_.values):Promise.resolve()}),U=(0,l.useCallback)(function(e,t){e.persist&&e.persist();var n,r=e.target,i=r.name,a=r.id;r.outerHTML,B(t||i||a,!0)},[B]),H=hN(function(e){if(hh(e))return function(t){return U(t,e)};U(e)}),$=(0,l.useCallback)(function(e){hl(e)?E({type:"SET_FORMIK_STATE",payload:e}):E({type:"SET_FORMIK_STATE",payload:function(){return e}})},[]),z=(0,l.useCallback)(function(e){E({type:"SET_STATUS",payload:e})},[]),G=(0,l.useCallback)(function(e){E({type:"SET_ISSUBMITTING",payload:e})},[]),W=hN(function(){return E({type:"SUBMIT_ATTEMPT"}),O().then(function(e){var t,n=e instanceof Error;if(!n&&0===Object.keys(e).length){try{if(void 0===(t=q()))return}catch(r){throw r}return Promise.resolve(t).then(function(e){return v.current&&E({type:"SUBMIT_SUCCESS"}),e}).catch(function(e){if(v.current)throw E({type:"SUBMIT_FAILURE"}),e})}if(v.current&&(E({type:"SUBMIT_FAILURE"}),n))throw e})}),K=hN(function(e){e&&e.preventDefault&&hl(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hl(e.stopPropagation)&&e.stopPropagation(),W().catch(function(e){console.warn("Warning: An unhandled error was caught from submitForm()",e)})}),V={resetForm:A,validateForm:O,validateField:L,setErrors:N,setFieldError:R,setFieldTouched:B,setFieldValue:j,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,setFormikState:$,submitForm:W},q=hN(function(){return f(_.values,V)}),Z=hN(function(e){e&&e.preventDefault&&hl(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hl(e.stopPropagation)&&e.stopPropagation(),A()}),X=(0,l.useCallback)(function(e){return{value:hm(_.values,e),error:hm(_.errors,e),touched:!!hm(_.touched,e),initialValue:hm(p.current,e),initialTouched:!!hm(m.current,e),initialError:hm(b.current,e)}},[_.errors,_.touched,_.values]),J=(0,l.useCallback)(function(e){return{setValue:function(t,n){return j(e,t,n)},setTouched:function(t,n){return B(e,t,n)},setError:function(t){return R(e,t)}}},[j,B,R]),Q=(0,l.useCallback)(function(e){var t=hf(e),n=t?e.name:e,r=hm(_.values,n),i={name:n,value:r,onChange:Y,onBlur:H};if(t){var a=e.type,o=e.value,s=e.as,u=e.multiple;"checkbox"===a?void 0===o?i.checked=!!r:(i.checked=!!(Array.isArray(r)&&~r.indexOf(o)),i.value=o):"radio"===a?(i.checked=r===o,i.value=o):"select"===s&&u&&(i.value=i.value||[],i.multiple=!0)}return i},[H,Y,_.values]),ee=(0,l.useMemo)(function(){return!sd()(p.current,_.values)},[p.current,_.values]),et=(0,l.useMemo)(function(){return void 0!==s?ee?_.errors&&0===Object.keys(_.errors).length:!1!==s&&hl(s)?s(h):s:_.errors&&0===Object.keys(_.errors).length},[s,ee,_.errors,h]);return ha({},_,{initialValues:p.current,initialErrors:b.current,initialTouched:m.current,initialStatus:g.current,handleBlur:H,handleChange:Y,handleReset:Z,handleSubmit:K,resetForm:A,setErrors:N,setFormikState:$,setFieldTouched:B,setFieldValue:j,setFieldError:R,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,submitForm:W,validateForm:O,validateField:L,isValid:et,dirty:ee,unregisterField:I,registerField:C,getFieldProps:Q,getFieldMeta:X,getFieldHelpers:J,validateOnBlur:i,validateOnChange:n,validateOnMount:o})}function hT(e){var t=hx(e),n=e.component,r=e.children,i=e.render,a=e.innerRef;return(0,l.useImperativeHandle)(a,function(){return t}),(0,l.createElement)(hw,{value:t},n?(0,l.createElement)(n,t):i?i(t):r?hl(r)?r(t):hp(r)?null:l.Children.only(r):null)}function hM(e){var t={};if(e.inner){if(0===e.inner.length)return hg(t,e.path,e.message);for(var n=e.inner,r=Array.isArray(n),i=0,n=r?n:n[Symbol.iterator]();;){if(r){if(i>=n.length)break;a=n[i++]}else{if((i=n.next()).done)break;a=i.value}var a,o=a;hm(t,o.path)||(t=hg(t,o.path,o.message))}}return t}function hO(e,t,n,r){void 0===n&&(n=!1),void 0===r&&(r={});var i=hA(e);return t[n?"validateSync":"validate"](i,{abortEarly:!1,context:r})}function hA(e){var t=Array.isArray(e)?[]:{};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var r=String(n);!0===Array.isArray(e[r])?t[r]=e[r].map(function(e){return!0===Array.isArray(e)||sR(e)?hA(e):""!==e?e:void 0}):sR(e[r])?t[r]=hA(e[r]):t[r]=""!==e[r]?e[r]:void 0}return t}function hL(e,t,n){var r=e.slice();return t.forEach(function(t,i){if(void 0===r[i]){var a=!1!==n.clone&&n.isMergeableObject(t);r[i]=a?sk(Array.isArray(t)?[]:{},t,n):t}else n.isMergeableObject(t)?r[i]=sk(e[i],t,n):-1===e.indexOf(t)&&r.push(t)}),r}function hC(e){return Array.from(e).filter(function(e){return e.selected}).map(function(e){return e.value})}function hI(e,t,n){if("boolean"==typeof e)return Boolean(t);var r=[],i=!1,a=-1;if(Array.isArray(e))r=e,i=(a=e.indexOf(n))>=0;else if(!n||"true"==n||"false"==n)return Boolean(t);return t&&n&&!i?r.concat(n):i?r.slice(0,a).concat(r.slice(a+1)):r}var hD="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?l.useLayoutEffect:l.useEffect;function hN(e){var t=(0,l.useRef)(e);return hD(function(){t.current=e}),(0,l.useCallback)(function(){for(var e=arguments.length,n=Array(e),r=0;re?t:e},0);return Array.from(ha({},e,{length:t+1}))};(function(e){function t(t){var n;return(n=e.call(this,t)||this).updateArrayField=function(e,t,r){var i=n.props,a=i.name;(0,i.formik.setFormikState)(function(n){var i="function"==typeof r?r:e,o="function"==typeof t?t:e,s=hg(n.values,a,e(hm(n.values,a))),u=r?i(hm(n.errors,a)):void 0,c=t?o(hm(n.touched,a)):void 0;return hc(u)&&(u=void 0),hc(c)&&(c=void 0),ha({},n,{values:s,errors:r?hg(n.errors,a,u):n.errors,touched:t?hg(n.touched,a,c):n.touched})})},n.push=function(e){return n.updateArrayField(function(t){return[].concat(hU(t),[hi(e)])},!1,!1)},n.handlePush=function(e){return function(){return n.push(e)}},n.swap=function(e,t){return n.updateArrayField(function(n){return hF(n,e,t)},!0,!0)},n.handleSwap=function(e,t){return function(){return n.swap(e,t)}},n.move=function(e,t){return n.updateArrayField(function(n){return hj(n,e,t)},!0,!0)},n.handleMove=function(e,t){return function(){return n.move(e,t)}},n.insert=function(e,t){return n.updateArrayField(function(n){return hY(n,e,t)},function(t){return hY(t,e,null)},function(t){return hY(t,e,null)})},n.handleInsert=function(e,t){return function(){return n.insert(e,t)}},n.replace=function(e,t){return n.updateArrayField(function(n){return hB(n,e,t)},!1,!1)},n.handleReplace=function(e,t){return function(){return n.replace(e,t)}},n.unshift=function(e){var t=-1;return n.updateArrayField(function(n){var r=n?[e].concat(n):[e];return t<0&&(t=r.length),r},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n}),t},n.handleUnshift=function(e){return function(){return n.unshift(e)}},n.handleRemove=function(e){return function(){return n.remove(e)}},n.handlePop=function(){return function(){return n.pop()}},n.remove=n.remove.bind(hu(n)),n.pop=n.pop.bind(hu(n)),n}ho(t,e);var n=t.prototype;return n.componentDidUpdate=function(e){this.props.validateOnChange&&this.props.formik.validateOnChange&&!sd()(hm(e.formik.values,e.name),hm(this.props.formik.values,this.props.name))&&this.props.formik.validateForm(this.props.formik.values)},n.remove=function(e){var t;return this.updateArrayField(function(n){var r=n?hU(n):[];return t||(t=r[e]),hl(r.splice)&&r.splice(e,1),r},!0,!0),t},n.pop=function(){var e;return this.updateArrayField(function(t){var n=t;return e||(e=n&&n.pop&&n.pop()),n},!0,!0),e},n.render=function(){var e={push:this.push,pop:this.pop,swap:this.swap,move:this.move,insert:this.insert,replace:this.replace,unshift:this.unshift,remove:this.remove,handlePush:this.handlePush,handlePop:this.handlePop,handleSwap:this.handleSwap,handleMove:this.handleMove,handleInsert:this.handleInsert,handleReplace:this.handleReplace,handleUnshift:this.handleUnshift,handleRemove:this.handleRemove},t=this.props,n=t.component,r=t.render,i=t.children,a=t.name,o=hs(t.formik,["validate","validationSchema"]),s=ha({},e,{form:o,name:a});return n?(0,l.createElement)(n,s):r?r(s):i?"function"==typeof i?i(s):hp(i)?null:l.Children.only(i):null},t})(l.Component).defaultProps={validateOnChange:!0},l.Component,l.Component;var hH=n(24802),h$=n(71209),hz=n(91750),hG=n(11970),hW=n(4689),hK=n(67598),hV=function(){return(hV=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&(n[r[i]]=e[r[i]]);return n}function hZ(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form,o=a.isSubmitting,s=a.touched,u=a.errors,c=e.onBlur,l=e.helperText,f=hq(e,["disabled","field","form","onBlur","helperText"]),d=hm(u,i.name),h=hm(s,i.name)&&!!d;return hV(hV({variant:f.variant,error:h,helperText:h?d:l,disabled:null!=t?t:o,onBlur:null!=c?c:function(e){r(null!=e?e:i.name)}},i),f)}function hX(e){var t=e.children,n=hq(e,["children"]);return(0,l.createElement)(iw.Z,hV({},hZ(n)),t)}function hJ(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=(e.type,e.onBlur),s=hq(e,["disabled","field","form","type","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function hQ(e){return(0,l.createElement)(hH.Z,hV({},hJ(e)))}function h1(e){var t,n=e.disabled,r=e.field,i=r.onBlur,a=hq(r,["onBlur"]),o=e.form.isSubmitting,s=(e.type,e.onBlur),u=hq(e,["disabled","field","form","type","onBlur"]);return hV(hV({disabled:null!=n?n:o,indeterminate:!Array.isArray(a.value)&&null==a.value,onBlur:null!=s?s:function(e){i(null!=e?e:a.name)}},a),u)}function h0(e){return(0,l.createElement)(h$.Z,hV({},h1(e)))}function h2(e){var t=e.Label,n=hq(e,["Label"]);return(0,l.createElement)(hz.Z,hV({control:(0,l.createElement)(h$.Z,hV({},h1(n)))},t))}function h3(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hq(e,["disabled","field","form","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h4(e){return(0,l.createElement)(hG.default,hV({},h3(e)))}function h6(e){var t=e.field,n=t.onBlur,r=hq(t,["onBlur"]),i=(e.form,e.onBlur),a=hq(e,["field","form","onBlur"]);return hV(hV({onBlur:null!=i?i:function(e){n(null!=e?e:r.name)}},r),a)}function h5(e){return(0,l.createElement)(hW.Z,hV({},h6(e)))}function h8(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hq(e,["disabled","field","form","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h9(e){return(0,l.createElement)(hK.default,hV({},h8(e)))}hX.displayName="FormikMaterialUITextField",hQ.displayName="FormikMaterialUISwitch",h0.displayName="FormikMaterialUICheckbox",h2.displayName="FormikMaterialUICheckboxWithLabel",h4.displayName="FormikMaterialUISelect",h5.displayName="FormikMaterialUIRadioGroup",h9.displayName="FormikMaterialUIInputBase";try{a=Map}catch(h7){}try{o=Set}catch(pe){}function pt(e,t,n){if(!e||"object"!=typeof e||"function"==typeof e)return e;if(e.nodeType&&"cloneNode"in e)return e.cloneNode(!0);if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return RegExp(e);if(Array.isArray(e))return e.map(pn);if(a&&e instanceof a)return new Map(Array.from(e.entries()));if(o&&e instanceof o)return new Set(Array.from(e.values()));if(e instanceof Object){t.push(e);var r=Object.create(e);for(var i in n.push(r),e){var s=t.findIndex(function(t){return t===e[i]});r[i]=s>-1?n[s]:pt(e[i],t,n)}return r}return e}function pn(e){return pt(e,[],[])}let pr=Object.prototype.toString,pi=Error.prototype.toString,pa=RegExp.prototype.toString,po="undefined"!=typeof Symbol?Symbol.prototype.toString:()=>"",ps=/^Symbol\((.*)\)(.*)$/;function pu(e){if(e!=+e)return"NaN";let t=0===e&&1/e<0;return t?"-0":""+e}function pc(e,t=!1){if(null==e||!0===e||!1===e)return""+e;let n=typeof e;if("number"===n)return pu(e);if("string"===n)return t?`"${e}"`:e;if("function"===n)return"[Function "+(e.name||"anonymous")+"]";if("symbol"===n)return po.call(e).replace(ps,"Symbol($1)");let r=pr.call(e).slice(8,-1);return"Date"===r?isNaN(e.getTime())?""+e:e.toISOString(e):"Error"===r||e instanceof Error?"["+pi.call(e)+"]":"RegExp"===r?pa.call(e):null}function pl(e,t){let n=pc(e,t);return null!==n?n:JSON.stringify(e,function(e,n){let r=pc(this[e],t);return null!==r?r:n},2)}let pf={default:"${path} is invalid",required:"${path} is a required field",oneOf:"${path} must be one of the following values: ${values}",notOneOf:"${path} must not be one of the following values: ${values}",notType({path:e,type:t,value:n,originalValue:r}){let i=null!=r&&r!==n,a=`${e} must be a \`${t}\` type, but the final value was: \`${pl(n,!0)}\``+(i?` (cast from the value \`${pl(r,!0)}\`).`:".");return null===n&&(a+='\n If "null" is intended as an empty value be sure to mark the schema as `.nullable()`'),a},defined:"${path} must be defined"},pd={length:"${path} must be exactly ${length} characters",min:"${path} must be at least ${min} characters",max:"${path} must be at most ${max} characters",matches:'${path} must match the following: "${regex}"',email:"${path} must be a valid email",url:"${path} must be a valid URL",uuid:"${path} must be a valid UUID",trim:"${path} must be a trimmed string",lowercase:"${path} must be a lowercase string",uppercase:"${path} must be a upper case string"},ph={min:"${path} must be greater than or equal to ${min}",max:"${path} must be less than or equal to ${max}",lessThan:"${path} must be less than ${less}",moreThan:"${path} must be greater than ${more}",positive:"${path} must be a positive number",negative:"${path} must be a negative number",integer:"${path} must be an integer"},pp={min:"${path} field must be later than ${min}",max:"${path} field must be at earlier than ${max}"},pb={isValue:"${path} field must be ${value}"},pm={noUnknown:"${path} field has unspecified keys: ${unknown}"},pg={min:"${path} field must have at least ${min} items",max:"${path} field must have less than or equal to ${max} items",length:"${path} must be have ${length} items"};Object.assign(Object.create(null),{mixed:pf,string:pd,number:ph,date:pp,object:pm,array:pg,boolean:pb});var pv=n(18721),py=n.n(pv);let pw=e=>e&&e.__isYupSchema__;class p_{constructor(e,t){if(this.refs=e,this.refs=e,"function"==typeof t){this.fn=t;return}if(!py()(t,"is"))throw TypeError("`is:` is required for `when()` conditions");if(!t.then&&!t.otherwise)throw TypeError("either `then:` or `otherwise:` is required for `when()` conditions");let{is:n,then:r,otherwise:i}=t,a="function"==typeof n?n:(...e)=>e.every(e=>e===n);this.fn=function(...e){let t=e.pop(),n=e.pop(),o=a(...e)?r:i;if(o)return"function"==typeof o?o(n):n.concat(o.resolve(t))}}resolve(e,t){let n=this.refs.map(e=>e.getValue(null==t?void 0:t.value,null==t?void 0:t.parent,null==t?void 0:t.context)),r=this.fn.apply(e,n.concat(e,t));if(void 0===r||r===e)return e;if(!pw(r))throw TypeError("conditions must return a schema object");return r.resolve(t)}}let pE=p_;function pS(e){return null==e?[]:[].concat(e)}function pk(){return(pk=Object.assign||function(e){for(var t=1;tpl(t[n])):"function"==typeof e?e(t):e}static isError(e){return e&&"ValidationError"===e.name}constructor(e,t,n,r){super(),this.name="ValidationError",this.value=t,this.path=n,this.type=r,this.errors=[],this.inner=[],pS(e).forEach(e=>{pT.isError(e)?(this.errors.push(...e.errors),this.inner=this.inner.concat(e.inner.length?e.inner:e)):this.errors.push(e)}),this.message=this.errors.length>1?`${this.errors.length} errors occurred`:this.errors[0],Error.captureStackTrace&&Error.captureStackTrace(this,pT)}}let pM=e=>{let t=!1;return(...n)=>{t||(t=!0,e(...n))}};function pO(e,t){let{endEarly:n,tests:r,args:i,value:a,errors:o,sort:s,path:u}=e,c=pM(t),l=r.length,f=[];if(o=o||[],!l)return o.length?c(new pT(o,a,u)):c(null,a);for(let d=0;d=0||(i[n]=e[n]);return i}function pR(e){function t(t,n){let{value:r,path:i="",label:a,options:o,originalValue:s,sync:u}=t,c=pP(t,["value","path","label","options","originalValue","sync"]),{name:l,test:f,params:d,message:h}=e,{parent:p,context:b}=o;function m(e){return pD.isRef(e)?e.getValue(r,p,b):e}function g(e={}){let t=pL()(pN({value:r,originalValue:s,label:a,path:e.path||i},d,e.params),m),n=new pT(pT.formatError(e.message||h,t),r,t.path,e.type||l);return n.params=t,n}let v=pN({path:i,parent:p,type:l,createError:g,resolve:m,options:o,originalValue:s},c);if(!u){try{Promise.resolve(f.call(v,r,v)).then(e=>{pT.isError(e)?n(e):e?n(null,e):n(g())})}catch(y){n(y)}return}let w;try{var _;if(w=f.call(v,r,v),"function"==typeof(null==(_=w)?void 0:_.then))throw Error(`Validation test of type: "${v.type}" returned a Promise during a synchronous validate. This test will finish after the validate call has returned`)}catch(E){n(E);return}pT.isError(w)?n(w):w?n(null,w):n(g())}return t.OPTIONS=e,t}pD.prototype.__isYupRef=!0;let pj=e=>e.substr(0,e.length-1).substr(1);function pF(e,t,n,r=n){let i,a,o;return t?((0,pC.forEach)(t,(s,u,c)=>{let l=u?pj(s):s;if((e=e.resolve({context:r,parent:i,value:n})).innerType){let f=c?parseInt(l,10):0;if(n&&f>=n.length)throw Error(`Yup.reach cannot resolve an array item at index: ${s}, in the path: ${t}. because there is no value at that index. `);i=n,n=n&&n[f],e=e.innerType}if(!c){if(!e.fields||!e.fields[l])throw Error(`The schema does not contain the path: ${t}. (failed at: ${o} which is a type: "${e._type}")`);i=n,n=n&&n[l],e=e.fields[l]}a=l,o=u?"["+s+"]":"."+s}),{schema:e,parent:i,parentPath:a}):{parent:i,parentPath:t,schema:e}}class pY{constructor(){this.list=new Set,this.refs=new Map}get size(){return this.list.size+this.refs.size}describe(){let e=[];for(let t of this.list)e.push(t);for(let[,n]of this.refs)e.push(n.describe());return e}toArray(){return Array.from(this.list).concat(Array.from(this.refs.values()))}add(e){pD.isRef(e)?this.refs.set(e.key,e):this.list.add(e)}delete(e){pD.isRef(e)?this.refs.delete(e.key):this.list.delete(e)}has(e,t){if(this.list.has(e))return!0;let n,r=this.refs.values();for(;!(n=r.next()).done;)if(t(n.value)===e)return!0;return!1}clone(){let e=new pY;return e.list=new Set(this.list),e.refs=new Map(this.refs),e}merge(e,t){let n=this.clone();return e.list.forEach(e=>n.add(e)),e.refs.forEach(e=>n.add(e)),t.list.forEach(e=>n.delete(e)),t.refs.forEach(e=>n.delete(e)),n}}function pB(){return(pB=Object.assign||function(e){for(var t=1;t{this.typeError(pf.notType)}),this.type=(null==e?void 0:e.type)||"mixed",this.spec=pB({strip:!1,strict:!1,abortEarly:!0,recursive:!0,nullable:!1,presence:"optional"},null==e?void 0:e.spec)}get _type(){return this.type}_typeCheck(e){return!0}clone(e){if(this._mutate)return e&&Object.assign(this.spec,e),this;let t=Object.create(Object.getPrototypeOf(this));return t.type=this.type,t._typeError=this._typeError,t._whitelistError=this._whitelistError,t._blacklistError=this._blacklistError,t._whitelist=this._whitelist.clone(),t._blacklist=this._blacklist.clone(),t.exclusiveTests=pB({},this.exclusiveTests),t.deps=[...this.deps],t.conditions=[...this.conditions],t.tests=[...this.tests],t.transforms=[...this.transforms],t.spec=pn(pB({},this.spec,e)),t}label(e){var t=this.clone();return t.spec.label=e,t}meta(...e){if(0===e.length)return this.spec.meta;let t=this.clone();return t.spec.meta=Object.assign(t.spec.meta||{},e[0]),t}withMutation(e){let t=this._mutate;this._mutate=!0;let n=e(this);return this._mutate=t,n}concat(e){if(!e||e===this)return this;if(e.type!==this.type&&"mixed"!==this.type)throw TypeError(`You cannot \`concat()\` schema's of different types: ${this.type} and ${e.type}`);let t=this,n=e.clone(),r=pB({},t.spec,n.spec);return n.spec=r,n._typeError||(n._typeError=t._typeError),n._whitelistError||(n._whitelistError=t._whitelistError),n._blacklistError||(n._blacklistError=t._blacklistError),n._whitelist=t._whitelist.merge(e._whitelist,e._blacklist),n._blacklist=t._blacklist.merge(e._blacklist,e._whitelist),n.tests=t.tests,n.exclusiveTests=t.exclusiveTests,n.withMutation(t=>{e.tests.forEach(e=>{t.test(e.OPTIONS)})}),n}isType(e){return!!this.spec.nullable&&null===e||this._typeCheck(e)}resolve(e){let t=this;if(t.conditions.length){let n=t.conditions;(t=t.clone()).conditions=[],t=(t=n.reduce((t,n)=>n.resolve(t,e),t)).resolve(e)}return t}cast(e,t={}){let n=this.resolve(pB({value:e},t)),r=n._cast(e,t);if(void 0!==e&&!1!==t.assert&&!0!==n.isType(r)){let i=pl(e),a=pl(r);throw TypeError(`The value of ${t.path||"field"} could not be cast to a value that satisfies the schema type: "${n._type}". + */ Object.defineProperty(t,"__esModule",{value:!0}),"undefined"==typeof window||"function"!=typeof MessageChannel){var n,r,i,a,o,s=null,u=null,c=function(){if(null!==s)try{var e=t.unstable_now();s(!0,e),s=null}catch(n){throw setTimeout(c,0),n}},l=Date.now();t.unstable_now=function(){return Date.now()-l},n=function(e){null!==s?setTimeout(n,0,e):(s=e,setTimeout(c,0))},r=function(e,t){u=setTimeout(e,t)},i=function(){clearTimeout(u)},a=function(){return!1},o=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,d=window.Date,h=window.setTimeout,p=window.clearTimeout;if("undefined"!=typeof console){var b=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof b&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var m=d.now();t.unstable_now=function(){return d.now()-m}}var g=!1,v=null,y=-1,w=5,_=0;a=function(){return t.unstable_now()>=_},o=function(){},t.unstable_forceFrameRate=function(e){0>e||125M(o,n))void 0!==u&&0>M(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[a]=n,r=a);else if(void 0!==u&&0>M(u,n))e[r]=u,e[s]=n,r=s;else break a}}return t}return null}function M(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var O=[],A=[],L=1,C=null,I=3,D=!1,N=!1,P=!1;function R(e){for(var t=x(A);null!==t;){if(null===t.callback)T(A);else if(t.startTime<=e)T(A),t.sortIndex=t.expirationTime,k(O,t);else break;t=x(A)}}function j(e){if(P=!1,R(e),!N){if(null!==x(O))N=!0,n(F);else{var t=x(A);null!==t&&r(j,t.startTime-e)}}}function F(e,n){N=!1,P&&(P=!1,i()),D=!0;var o=I;try{for(R(n),C=x(O);null!==C&&(!(C.expirationTime>n)||e&&!a());){var s=C.callback;if(null!==s){C.callback=null,I=C.priorityLevel;var u=s(C.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?C.callback=u:C===x(O)&&T(O),R(n)}else T(O);C=x(O)}if(null!==C)var c=!0;else{var l=x(A);null!==l&&r(j,l.startTime-n),c=!1}return c}finally{C=null,I=o,D=!1}}function Y(e){switch(e){case 1:return -1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var B=o;t.unstable_ImmediatePriority=1,t.unstable_UserBlockingPriority=2,t.unstable_NormalPriority=3,t.unstable_IdlePriority=5,t.unstable_LowPriority=4,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=I;I=e;try{return t()}finally{I=n}},t.unstable_next=function(e){switch(I){case 1:case 2:case 3:var t=3;break;default:t=I}var n=I;I=t;try{return e()}finally{I=n}},t.unstable_scheduleCallback=function(e,a,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0s?(e.sortIndex=u,k(A,e),null===x(O)&&e===x(A)&&(P?i():P=!0,r(j,u-s))):(e.sortIndex=o,k(O,e),N||D||(N=!0,n(F))),e},t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_wrapCallback=function(e){var t=I;return function(){var n=I;I=t;try{return e.apply(this,arguments)}finally{I=n}}},t.unstable_getCurrentPriorityLevel=function(){return I},t.unstable_shouldYield=function(){var e=t.unstable_now();R(e);var n=x(O);return n!==C&&null!==C&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function c(e,t,n){var r=t.length-1;if(r=0?(i>0&&(e.lastNeed=i-1),i):--r=0?(i>0&&(e.lastNeed=i-2),i):--r=0?(i>0&&(2===i?i=0:e.lastNeed=i-3),i):0}function l(e,t,n){if((192&t[0])!=128)return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if((192&t[1])!=128)return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&(192&t[2])!=128)return e.lastNeed=2,"�"}}function f(e){var t=this.lastTotal-this.lastNeed,n=l(this,e,t);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):void(e.copy(this.lastChar,t,0,e.length),this.lastNeed-=e.length)}function d(e,t){var n=c(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)}function h(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+"�":t}function p(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function b(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function m(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function g(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function v(e){return e.toString(this.encoding)}function y(e){return e&&e.length?this.write(e):""}t.s=s,s.prototype.write=function(e){var t,n;if(0===e.length)return"";if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n */ var r=n(48764),i=r.Buffer;function a(e,t){for(var n in e)t[n]=e[n]}function o(e,t,n){return i(e,t,n)}i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow?e.exports=r:(a(r,t),t.Buffer=o),o.prototype=Object.create(i.prototype),a(i,o),o.from=function(e,t,n){if("number"==typeof e)throw TypeError("Argument must not be a number");return i(e,t,n)},o.alloc=function(e,t,n){if("number"!=typeof e)throw TypeError("Argument must be a number");var r=i(e);return void 0!==t?"string"==typeof n?r.fill(t,n):r.fill(t):r.fill(0),r},o.allocUnsafe=function(e){if("number"!=typeof e)throw TypeError("Argument must be a number");return i(e)},o.allocUnsafeSlow=function(e){if("number"!=typeof e)throw TypeError("Argument must be a number");return r.SlowBuffer(e)}},93379(e,t,n){"use strict";var r,i,a=function(){return void 0===r&&(r=Boolean(window&&document&&document.all&&!window.atob)),r},o=(i={},function(e){if(void 0===i[e]){var t=document.querySelector(e);if(window.HTMLIFrameElement&&t instanceof window.HTMLIFrameElement)try{t=t.contentDocument.head}catch(n){t=null}i[e]=t}return i[e]}),s=[];function u(e){for(var t=-1,n=0;nOq});var r,i,a,o,s,u,c,l=n(67294),f=n.t(l,2),d=n(39814),h=n(5977),p=n(57209),b=n(32316),m=n(95880),g=n(17051),v=n(71381),y=n(81701),w=n(3022),_=n(60323),E=n(87591),S=n(25649),k=n(28902),x=n(71426),T=n(48884),M=n(94184),O=n.n(M),A=n(37703),L=n(73935),C=function(){if("undefined"!=typeof Map)return Map;function e(e,t){var n=-1;return e.some(function(e,r){return e[0]===t&&(n=r,!0)}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(t){var n=e(this.__entries__,t),r=this.__entries__[n];return r&&r[1]},t.prototype.set=function(t,n){var r=e(this.__entries__,t);~r?this.__entries__[r][1]=n:this.__entries__.push([t,n])},t.prototype.delete=function(t){var n=this.__entries__,r=e(n,t);~r&&n.splice(r,1)},t.prototype.has=function(t){return!!~e(this.__entries__,t)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(e,t){void 0===t&&(t=null);for(var n=0,r=this.__entries__;n0},e.prototype.connect_=function(){I&&!this.connected_&&(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),Y?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){I&&this.connected_&&(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(e){var t=e.propertyName,n=void 0===t?"":t;F.some(function(e){return!!~n.indexOf(e)})&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),U=function(e,t){for(var n=0,r=Object.keys(t);n0},e}(),er="undefined"!=typeof WeakMap?new WeakMap:new C,ei=function(){function e(t){if(!(this instanceof e))throw TypeError("Cannot call a class as a function.");if(!arguments.length)throw TypeError("1 argument required, but only 0 present.");var n=B.getInstance(),r=new en(t,n,this);er.set(this,r)}return e}();["observe","unobserve","disconnect"].forEach(function(e){ei.prototype[e]=function(){var t;return(t=er.get(this))[e].apply(t,arguments)}});var ea=void 0!==D.ResizeObserver?D.ResizeObserver:ei;let eo=ea;var es=function(e){var t=[],n=null,r=function(){for(var r=arguments.length,i=Array(r),a=0;a=t||n<0||f&&r>=a}function g(){var e=eb();if(m(e))return v(e);s=setTimeout(g,b(e))}function v(e){return(s=void 0,d&&r)?h(e):(r=i=void 0,o)}function y(){void 0!==s&&clearTimeout(s),c=0,r=u=i=s=void 0}function w(){return void 0===s?o:v(eb())}function _(){var e=eb(),n=m(e);if(r=arguments,i=this,u=e,n){if(void 0===s)return p(u);if(f)return clearTimeout(s),s=setTimeout(g,t),h(u)}return void 0===s&&(s=setTimeout(g,t)),o}return t=ez(t)||0,ed(n)&&(l=!!n.leading,a=(f="maxWait"in n)?eW(ez(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),_.cancel=y,_.flush=w,_}let eq=eV;var eZ="Expected a function";function eX(e,t,n){var r=!0,i=!0;if("function"!=typeof e)throw TypeError(eZ);return ed(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),eq(e,t,{leading:r,maxWait:t,trailing:i})}let eJ=eX;var eQ={debounce:eq,throttle:eJ},e1=function(e){return eQ[e]},e0=function(e){return"function"==typeof e},e2=function(){return"undefined"==typeof window},e3=function(e){return e instanceof Element||e instanceof HTMLDocument};function e4(e){return(e4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function e6(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function e5(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&l.createElement(tG.Z,{variant:"indeterminate",classes:r}))};tK.propTypes={fetchCount:el().number.isRequired};let tV=(0,b.withStyles)(tW)(tK);var tq=n(5536);let tZ=n.p+"ba8bbf16ebf8e1d05bef.svg";function tX(){return(tX=Object.assign||function(e){for(var t=1;t120){for(var d=Math.floor(u/80),h=u%80,p=[],b=0;b0},name:{enumerable:!1},nodes:{enumerable:!1},source:{enumerable:!1},positions:{enumerable:!1},originalError:{enumerable:!1}}),null!=s&&s.stack)?(Object.defineProperty(nf(b),"stack",{value:s.stack,writable:!0,configurable:!0}),nl(b)):(Error.captureStackTrace?Error.captureStackTrace(nf(b),n):Object.defineProperty(nf(b),"stack",{value:Error().stack,writable:!0,configurable:!0}),b)}return ns(n,[{key:"toString",value:function(){return nw(this)}},{key:t4.YF,get:function(){return"Object"}}]),n}(nd(Error));function ny(e){return void 0===e||0===e.length?void 0:e}function nw(e){var t=e.message;if(e.nodes)for(var n=0,r=e.nodes;n",EOF:"",BANG:"!",DOLLAR:"$",AMP:"&",PAREN_L:"(",PAREN_R:")",SPREAD:"...",COLON:":",EQUALS:"=",AT:"@",BRACKET_L:"[",BRACKET_R:"]",BRACE_L:"{",PIPE:"|",BRACE_R:"}",NAME:"Name",INT:"Int",FLOAT:"Float",STRING:"String",BLOCK_STRING:"BlockString",COMMENT:"Comment"}),nx=n(10143),nT=Object.freeze({QUERY:"QUERY",MUTATION:"MUTATION",SUBSCRIPTION:"SUBSCRIPTION",FIELD:"FIELD",FRAGMENT_DEFINITION:"FRAGMENT_DEFINITION",FRAGMENT_SPREAD:"FRAGMENT_SPREAD",INLINE_FRAGMENT:"INLINE_FRAGMENT",VARIABLE_DEFINITION:"VARIABLE_DEFINITION",SCHEMA:"SCHEMA",SCALAR:"SCALAR",OBJECT:"OBJECT",FIELD_DEFINITION:"FIELD_DEFINITION",ARGUMENT_DEFINITION:"ARGUMENT_DEFINITION",INTERFACE:"INTERFACE",UNION:"UNION",ENUM:"ENUM",ENUM_VALUE:"ENUM_VALUE",INPUT_OBJECT:"INPUT_OBJECT",INPUT_FIELD_DEFINITION:"INPUT_FIELD_DEFINITION"}),nM=n(87392),nO=function(){function e(e){var t=new nS.WU(nk.SOF,0,0,0,0,null);this.source=e,this.lastToken=t,this.token=t,this.line=1,this.lineStart=0}var t=e.prototype;return t.advance=function(){return this.lastToken=this.token,this.token=this.lookahead()},t.lookahead=function(){var e,t=this.token;if(t.kind!==nk.EOF)do t=null!==(e=t.next)&&void 0!==e?e:t.next=nC(this,t);while(t.kind===nk.COMMENT)return t},e}();function nA(e){return e===nk.BANG||e===nk.DOLLAR||e===nk.AMP||e===nk.PAREN_L||e===nk.PAREN_R||e===nk.SPREAD||e===nk.COLON||e===nk.EQUALS||e===nk.AT||e===nk.BRACKET_L||e===nk.BRACKET_R||e===nk.BRACE_L||e===nk.PIPE||e===nk.BRACE_R}function nL(e){return isNaN(e)?nk.EOF:e<127?JSON.stringify(String.fromCharCode(e)):'"\\u'.concat(("00"+e.toString(16).toUpperCase()).slice(-4),'"')}function nC(e,t){for(var n=e.source,r=n.body,i=r.length,a=t.end;a31||9===a))return new nS.WU(nk.COMMENT,t,s,n,r,i,o.slice(t+1,s))}function nN(e,t,n,r,i,a){var o=e.body,s=n,u=t,c=!1;if(45===s&&(s=o.charCodeAt(++u)),48===s){if((s=o.charCodeAt(++u))>=48&&s<=57)throw n_(e,u,"Invalid number, unexpected digit after 0: ".concat(nL(s),"."))}else u=nP(e,u,s),s=o.charCodeAt(u);if(46===s&&(c=!0,s=o.charCodeAt(++u),u=nP(e,u,s),s=o.charCodeAt(u)),(69===s||101===s)&&(c=!0,(43===(s=o.charCodeAt(++u))||45===s)&&(s=o.charCodeAt(++u)),u=nP(e,u,s),s=o.charCodeAt(u)),46===s||nU(s))throw n_(e,u,"Invalid number, expected digit but got: ".concat(nL(s),"."));return new nS.WU(c?nk.FLOAT:nk.INT,t,u,r,i,a,o.slice(t,u))}function nP(e,t,n){var r=e.body,i=t,a=n;if(a>=48&&a<=57){do a=r.charCodeAt(++i);while(a>=48&&a<=57)return i}throw n_(e,i,"Invalid number, expected digit but got: ".concat(nL(a),"."))}function nR(e,t,n,r,i){for(var a=e.body,o=t+1,s=o,u=0,c="";o=48&&e<=57?e-48:e>=65&&e<=70?e-55:e>=97&&e<=102?e-87:-1}function nB(e,t,n,r,i){for(var a=e.body,o=a.length,s=t+1,u=0;s!==o&&!isNaN(u=a.charCodeAt(s))&&(95===u||u>=48&&u<=57||u>=65&&u<=90||u>=97&&u<=122);)++s;return new nS.WU(nk.NAME,t,s,n,r,i,a.slice(t,s))}function nU(e){return 95===e||e>=65&&e<=90||e>=97&&e<=122}function nH(e,t){return new n$(e,t).parseDocument()}var n$=function(){function e(e,t){var n=(0,nx.T)(e)?e:new nx.H(e);this._lexer=new nO(n),this._options=t}var t=e.prototype;return t.parseName=function(){var e=this.expectToken(nk.NAME);return{kind:nE.h.NAME,value:e.value,loc:this.loc(e)}},t.parseDocument=function(){var e=this._lexer.token;return{kind:nE.h.DOCUMENT,definitions:this.many(nk.SOF,this.parseDefinition,nk.EOF),loc:this.loc(e)}},t.parseDefinition=function(){if(this.peek(nk.NAME))switch(this._lexer.token.value){case"query":case"mutation":case"subscription":return this.parseOperationDefinition();case"fragment":return this.parseFragmentDefinition();case"schema":case"scalar":case"type":case"interface":case"union":case"enum":case"input":case"directive":return this.parseTypeSystemDefinition();case"extend":return this.parseTypeSystemExtension()}else if(this.peek(nk.BRACE_L))return this.parseOperationDefinition();else if(this.peekDescription())return this.parseTypeSystemDefinition();throw this.unexpected()},t.parseOperationDefinition=function(){var e,t=this._lexer.token;if(this.peek(nk.BRACE_L))return{kind:nE.h.OPERATION_DEFINITION,operation:"query",name:void 0,variableDefinitions:[],directives:[],selectionSet:this.parseSelectionSet(),loc:this.loc(t)};var n=this.parseOperationType();return this.peek(nk.NAME)&&(e=this.parseName()),{kind:nE.h.OPERATION_DEFINITION,operation:n,name:e,variableDefinitions:this.parseVariableDefinitions(),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseOperationType=function(){var e=this.expectToken(nk.NAME);switch(e.value){case"query":return"query";case"mutation":return"mutation";case"subscription":return"subscription"}throw this.unexpected(e)},t.parseVariableDefinitions=function(){return this.optionalMany(nk.PAREN_L,this.parseVariableDefinition,nk.PAREN_R)},t.parseVariableDefinition=function(){var e=this._lexer.token;return{kind:nE.h.VARIABLE_DEFINITION,variable:this.parseVariable(),type:(this.expectToken(nk.COLON),this.parseTypeReference()),defaultValue:this.expectOptionalToken(nk.EQUALS)?this.parseValueLiteral(!0):void 0,directives:this.parseDirectives(!0),loc:this.loc(e)}},t.parseVariable=function(){var e=this._lexer.token;return this.expectToken(nk.DOLLAR),{kind:nE.h.VARIABLE,name:this.parseName(),loc:this.loc(e)}},t.parseSelectionSet=function(){var e=this._lexer.token;return{kind:nE.h.SELECTION_SET,selections:this.many(nk.BRACE_L,this.parseSelection,nk.BRACE_R),loc:this.loc(e)}},t.parseSelection=function(){return this.peek(nk.SPREAD)?this.parseFragment():this.parseField()},t.parseField=function(){var e,t,n=this._lexer.token,r=this.parseName();return this.expectOptionalToken(nk.COLON)?(e=r,t=this.parseName()):t=r,{kind:nE.h.FIELD,alias:e,name:t,arguments:this.parseArguments(!1),directives:this.parseDirectives(!1),selectionSet:this.peek(nk.BRACE_L)?this.parseSelectionSet():void 0,loc:this.loc(n)}},t.parseArguments=function(e){var t=e?this.parseConstArgument:this.parseArgument;return this.optionalMany(nk.PAREN_L,t,nk.PAREN_R)},t.parseArgument=function(){var e=this._lexer.token,t=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.ARGUMENT,name:t,value:this.parseValueLiteral(!1),loc:this.loc(e)}},t.parseConstArgument=function(){var e=this._lexer.token;return{kind:nE.h.ARGUMENT,name:this.parseName(),value:(this.expectToken(nk.COLON),this.parseValueLiteral(!0)),loc:this.loc(e)}},t.parseFragment=function(){var e=this._lexer.token;this.expectToken(nk.SPREAD);var t=this.expectOptionalKeyword("on");return!t&&this.peek(nk.NAME)?{kind:nE.h.FRAGMENT_SPREAD,name:this.parseFragmentName(),directives:this.parseDirectives(!1),loc:this.loc(e)}:{kind:nE.h.INLINE_FRAGMENT,typeCondition:t?this.parseNamedType():void 0,directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(e)}},t.parseFragmentDefinition=function(){var e,t=this._lexer.token;return(this.expectKeyword("fragment"),(null===(e=this._options)||void 0===e?void 0:e.experimentalFragmentVariables)===!0)?{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),variableDefinitions:this.parseVariableDefinitions(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}:{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseFragmentName=function(){if("on"===this._lexer.token.value)throw this.unexpected();return this.parseName()},t.parseValueLiteral=function(e){var t=this._lexer.token;switch(t.kind){case nk.BRACKET_L:return this.parseList(e);case nk.BRACE_L:return this.parseObject(e);case nk.INT:return this._lexer.advance(),{kind:nE.h.INT,value:t.value,loc:this.loc(t)};case nk.FLOAT:return this._lexer.advance(),{kind:nE.h.FLOAT,value:t.value,loc:this.loc(t)};case nk.STRING:case nk.BLOCK_STRING:return this.parseStringLiteral();case nk.NAME:switch(this._lexer.advance(),t.value){case"true":return{kind:nE.h.BOOLEAN,value:!0,loc:this.loc(t)};case"false":return{kind:nE.h.BOOLEAN,value:!1,loc:this.loc(t)};case"null":return{kind:nE.h.NULL,loc:this.loc(t)};default:return{kind:nE.h.ENUM,value:t.value,loc:this.loc(t)}}case nk.DOLLAR:if(!e)return this.parseVariable()}throw this.unexpected()},t.parseStringLiteral=function(){var e=this._lexer.token;return this._lexer.advance(),{kind:nE.h.STRING,value:e.value,block:e.kind===nk.BLOCK_STRING,loc:this.loc(e)}},t.parseList=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseValueLiteral(e)};return{kind:nE.h.LIST,values:this.any(nk.BRACKET_L,r,nk.BRACKET_R),loc:this.loc(n)}},t.parseObject=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseObjectField(e)};return{kind:nE.h.OBJECT,fields:this.any(nk.BRACE_L,r,nk.BRACE_R),loc:this.loc(n)}},t.parseObjectField=function(e){var t=this._lexer.token,n=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.OBJECT_FIELD,name:n,value:this.parseValueLiteral(e),loc:this.loc(t)}},t.parseDirectives=function(e){for(var t=[];this.peek(nk.AT);)t.push(this.parseDirective(e));return t},t.parseDirective=function(e){var t=this._lexer.token;return this.expectToken(nk.AT),{kind:nE.h.DIRECTIVE,name:this.parseName(),arguments:this.parseArguments(e),loc:this.loc(t)}},t.parseTypeReference=function(){var e,t=this._lexer.token;return(this.expectOptionalToken(nk.BRACKET_L)?(e=this.parseTypeReference(),this.expectToken(nk.BRACKET_R),e={kind:nE.h.LIST_TYPE,type:e,loc:this.loc(t)}):e=this.parseNamedType(),this.expectOptionalToken(nk.BANG))?{kind:nE.h.NON_NULL_TYPE,type:e,loc:this.loc(t)}:e},t.parseNamedType=function(){var e=this._lexer.token;return{kind:nE.h.NAMED_TYPE,name:this.parseName(),loc:this.loc(e)}},t.parseTypeSystemDefinition=function(){var e=this.peekDescription()?this._lexer.lookahead():this._lexer.token;if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaDefinition();case"scalar":return this.parseScalarTypeDefinition();case"type":return this.parseObjectTypeDefinition();case"interface":return this.parseInterfaceTypeDefinition();case"union":return this.parseUnionTypeDefinition();case"enum":return this.parseEnumTypeDefinition();case"input":return this.parseInputObjectTypeDefinition();case"directive":return this.parseDirectiveDefinition()}throw this.unexpected(e)},t.peekDescription=function(){return this.peek(nk.STRING)||this.peek(nk.BLOCK_STRING)},t.parseDescription=function(){if(this.peekDescription())return this.parseStringLiteral()},t.parseSchemaDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("schema");var n=this.parseDirectives(!0),r=this.many(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);return{kind:nE.h.SCHEMA_DEFINITION,description:t,directives:n,operationTypes:r,loc:this.loc(e)}},t.parseOperationTypeDefinition=function(){var e=this._lexer.token,t=this.parseOperationType();this.expectToken(nk.COLON);var n=this.parseNamedType();return{kind:nE.h.OPERATION_TYPE_DEFINITION,operation:t,type:n,loc:this.loc(e)}},t.parseScalarTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("scalar");var n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.SCALAR_TYPE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("type");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.OBJECT_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseImplementsInterfaces=function(){var e;if(!this.expectOptionalKeyword("implements"))return[];if((null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLImplementsInterfaces)===!0){var t=[];this.expectOptionalToken(nk.AMP);do t.push(this.parseNamedType());while(this.expectOptionalToken(nk.AMP)||this.peek(nk.NAME))return t}return this.delimitedMany(nk.AMP,this.parseNamedType)},t.parseFieldsDefinition=function(){var e;return(null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLEmptyFields)===!0&&this.peek(nk.BRACE_L)&&this._lexer.lookahead().kind===nk.BRACE_R?(this._lexer.advance(),this._lexer.advance(),[]):this.optionalMany(nk.BRACE_L,this.parseFieldDefinition,nk.BRACE_R)},t.parseFieldDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseArgumentDefs();this.expectToken(nk.COLON);var i=this.parseTypeReference(),a=this.parseDirectives(!0);return{kind:nE.h.FIELD_DEFINITION,description:t,name:n,arguments:r,type:i,directives:a,loc:this.loc(e)}},t.parseArgumentDefs=function(){return this.optionalMany(nk.PAREN_L,this.parseInputValueDef,nk.PAREN_R)},t.parseInputValueDef=function(){var e,t=this._lexer.token,n=this.parseDescription(),r=this.parseName();this.expectToken(nk.COLON);var i=this.parseTypeReference();this.expectOptionalToken(nk.EQUALS)&&(e=this.parseValueLiteral(!0));var a=this.parseDirectives(!0);return{kind:nE.h.INPUT_VALUE_DEFINITION,description:n,name:r,type:i,defaultValue:e,directives:a,loc:this.loc(t)}},t.parseInterfaceTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("interface");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.INTERFACE_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseUnionTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("union");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseUnionMemberTypes();return{kind:nE.h.UNION_TYPE_DEFINITION,description:t,name:n,directives:r,types:i,loc:this.loc(e)}},t.parseUnionMemberTypes=function(){return this.expectOptionalToken(nk.EQUALS)?this.delimitedMany(nk.PIPE,this.parseNamedType):[]},t.parseEnumTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("enum");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseEnumValuesDefinition();return{kind:nE.h.ENUM_TYPE_DEFINITION,description:t,name:n,directives:r,values:i,loc:this.loc(e)}},t.parseEnumValuesDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseEnumValueDefinition,nk.BRACE_R)},t.parseEnumValueDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.ENUM_VALUE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseInputObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("input");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseInputFieldsDefinition();return{kind:nE.h.INPUT_OBJECT_TYPE_DEFINITION,description:t,name:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInputFieldsDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseInputValueDef,nk.BRACE_R)},t.parseTypeSystemExtension=function(){var e=this._lexer.lookahead();if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaExtension();case"scalar":return this.parseScalarTypeExtension();case"type":return this.parseObjectTypeExtension();case"interface":return this.parseInterfaceTypeExtension();case"union":return this.parseUnionTypeExtension();case"enum":return this.parseEnumTypeExtension();case"input":return this.parseInputObjectTypeExtension()}throw this.unexpected(e)},t.parseSchemaExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("schema");var t=this.parseDirectives(!0),n=this.optionalMany(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);if(0===t.length&&0===n.length)throw this.unexpected();return{kind:nE.h.SCHEMA_EXTENSION,directives:t,operationTypes:n,loc:this.loc(e)}},t.parseScalarTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("scalar");var t=this.parseName(),n=this.parseDirectives(!0);if(0===n.length)throw this.unexpected();return{kind:nE.h.SCALAR_TYPE_EXTENSION,name:t,directives:n,loc:this.loc(e)}},t.parseObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("type");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.OBJECT_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInterfaceTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("interface");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.INTERFACE_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseUnionTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("union");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseUnionMemberTypes();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.UNION_TYPE_EXTENSION,name:t,directives:n,types:r,loc:this.loc(e)}},t.parseEnumTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("enum");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseEnumValuesDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.ENUM_TYPE_EXTENSION,name:t,directives:n,values:r,loc:this.loc(e)}},t.parseInputObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("input");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseInputFieldsDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.INPUT_OBJECT_TYPE_EXTENSION,name:t,directives:n,fields:r,loc:this.loc(e)}},t.parseDirectiveDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("directive"),this.expectToken(nk.AT);var n=this.parseName(),r=this.parseArgumentDefs(),i=this.expectOptionalKeyword("repeatable");this.expectKeyword("on");var a=this.parseDirectiveLocations();return{kind:nE.h.DIRECTIVE_DEFINITION,description:t,name:n,arguments:r,repeatable:i,locations:a,loc:this.loc(e)}},t.parseDirectiveLocations=function(){return this.delimitedMany(nk.PIPE,this.parseDirectiveLocation)},t.parseDirectiveLocation=function(){var e=this._lexer.token,t=this.parseName();if(void 0!==nT[t.value])return t;throw this.unexpected(e)},t.loc=function(e){var t;if((null===(t=this._options)||void 0===t?void 0:t.noLocation)!==!0)return new nS.Ye(e,this._lexer.lastToken,this._lexer.source)},t.peek=function(e){return this._lexer.token.kind===e},t.expectToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t;throw n_(this._lexer.source,t.start,"Expected ".concat(nG(e),", found ").concat(nz(t),"."))},t.expectOptionalToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t},t.expectKeyword=function(e){var t=this._lexer.token;if(t.kind===nk.NAME&&t.value===e)this._lexer.advance();else throw n_(this._lexer.source,t.start,'Expected "'.concat(e,'", found ').concat(nz(t),"."))},t.expectOptionalKeyword=function(e){var t=this._lexer.token;return t.kind===nk.NAME&&t.value===e&&(this._lexer.advance(),!0)},t.unexpected=function(e){var t=null!=e?e:this._lexer.token;return n_(this._lexer.source,t.start,"Unexpected ".concat(nz(t),"."))},t.any=function(e,t,n){this.expectToken(e);for(var r=[];!this.expectOptionalToken(n);)r.push(t.call(this));return r},t.optionalMany=function(e,t,n){if(this.expectOptionalToken(e)){var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r}return[]},t.many=function(e,t,n){this.expectToken(e);var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r},t.delimitedMany=function(e,t){this.expectOptionalToken(e);var n=[];do n.push(t.call(this));while(this.expectOptionalToken(e))return n},e}();function nz(e){var t=e.value;return nG(e.kind)+(null!=t?' "'.concat(t,'"'):"")}function nG(e){return nA(e)?'"'.concat(e,'"'):e}var nW=new Map,nK=new Map,nV=!0,nq=!1;function nZ(e){return e.replace(/[\s,]+/g," ").trim()}function nX(e){return nZ(e.source.body.substring(e.start,e.end))}function nJ(e){var t=new Set,n=[];return e.definitions.forEach(function(e){if("FragmentDefinition"===e.kind){var r=e.name.value,i=nX(e.loc),a=nK.get(r);a&&!a.has(i)?nV&&console.warn("Warning: fragment with name "+r+" already exists.\ngraphql-tag enforces all fragment names across your application to be unique; read more about\nthis in the docs: http://dev.apollodata.com/core/fragments.html#unique-names"):a||nK.set(r,a=new Set),a.add(i),t.has(i)||(t.add(i),n.push(e))}else n.push(e)}),(0,t0.pi)((0,t0.pi)({},e),{definitions:n})}function nQ(e){var t=new Set(e.definitions);t.forEach(function(e){e.loc&&delete e.loc,Object.keys(e).forEach(function(n){var r=e[n];r&&"object"==typeof r&&t.add(r)})});var n=e.loc;return n&&(delete n.startToken,delete n.endToken),e}function n1(e){var t=nZ(e);if(!nW.has(t)){var n=nH(e,{experimentalFragmentVariables:nq,allowLegacyFragmentVariables:nq});if(!n||"Document"!==n.kind)throw Error("Not a valid GraphQL document.");nW.set(t,nQ(nJ(n)))}return nW.get(t)}function n0(e){for(var t=[],n=1;n, or pass an ApolloClient instance in via options.'):(0,n9.kG)(!!n,32),n}var rp=n(10542),rb=n(53712),rm=n(21436),rg=Object.prototype.hasOwnProperty;function rv(e,t){return void 0===t&&(t=Object.create(null)),ry(rh(t.client),e).useQuery(t)}function ry(e,t){var n=(0,l.useRef)();n.current&&e===n.current.client&&t===n.current.query||(n.current=new rw(e,t,n.current));var r=n.current,i=(0,l.useState)(0),a=(i[0],i[1]);return r.forceUpdate=function(){a(function(e){return e+1})},r}var rw=function(){function e(e,t,n){this.client=e,this.query=t,this.ssrDisabledResult=(0,rp.J)({loading:!0,data:void 0,error:void 0,networkStatus:ru.I.loading}),this.skipStandbyResult=(0,rp.J)({loading:!1,data:void 0,error:void 0,networkStatus:ru.I.ready}),this.toQueryResultCache=new(n7.mr?WeakMap:Map),rd(t,r.Query);var i=n&&n.result,a=i&&i.data;a&&(this.previousData=a)}return e.prototype.forceUpdate=function(){__DEV__&&n9.kG.warn("Calling default no-op implementation of InternalState#forceUpdate")},e.prototype.executeQuery=function(e){var t,n=this;e.query&&Object.assign(this,{query:e.query}),this.watchQueryOptions=this.createWatchQueryOptions(this.queryHookOptions=e);var r=this.observable.reobserveAsConcast(this.getObsQueryOptions());return this.previousData=(null===(t=this.result)||void 0===t?void 0:t.data)||this.previousData,this.result=void 0,this.forceUpdate(),new Promise(function(e){var t;r.subscribe({next:function(e){t=e},error:function(){e(n.toQueryResult(n.observable.getCurrentResult()))},complete:function(){e(n.toQueryResult(t))}})})},e.prototype.useQuery=function(e){var t=this;this.renderPromises=(0,l.useContext)((0,ro.K)()).renderPromises,this.useOptions(e);var n=this.useObservableQuery(),r=rt((0,l.useCallback)(function(){if(t.renderPromises)return function(){};var e=function(){var e=t.result,r=n.getCurrentResult();!(e&&e.loading===r.loading&&e.networkStatus===r.networkStatus&&(0,ri.D)(e.data,r.data))&&t.setResult(r)},r=function(a){var o=n.last;i.unsubscribe();try{n.resetLastResults(),i=n.subscribe(e,r)}finally{n.last=o}if(!rg.call(a,"graphQLErrors"))throw a;var s=t.result;(!s||s&&s.loading||!(0,ri.D)(a,s.error))&&t.setResult({data:s&&s.data,error:a,loading:!1,networkStatus:ru.I.error})},i=n.subscribe(e,r);return function(){return setTimeout(function(){return i.unsubscribe()})}},[n,this.renderPromises,this.client.disableNetworkFetches,]),function(){return t.getCurrentResult()},function(){return t.getCurrentResult()});return this.unsafeHandlePartialRefetch(r),this.toQueryResult(r)},e.prototype.useOptions=function(t){var n,r=this.createWatchQueryOptions(this.queryHookOptions=t),i=this.watchQueryOptions;!(0,ri.D)(r,i)&&(this.watchQueryOptions=r,i&&this.observable&&(this.observable.reobserve(this.getObsQueryOptions()),this.previousData=(null===(n=this.result)||void 0===n?void 0:n.data)||this.previousData,this.result=void 0)),this.onCompleted=t.onCompleted||e.prototype.onCompleted,this.onError=t.onError||e.prototype.onError,(this.renderPromises||this.client.disableNetworkFetches)&&!1===this.queryHookOptions.ssr&&!this.queryHookOptions.skip?this.result=this.ssrDisabledResult:this.queryHookOptions.skip||"standby"===this.watchQueryOptions.fetchPolicy?this.result=this.skipStandbyResult:(this.result===this.ssrDisabledResult||this.result===this.skipStandbyResult)&&(this.result=void 0)},e.prototype.getObsQueryOptions=function(){var e=[],t=this.client.defaultOptions.watchQuery;return t&&e.push(t),this.queryHookOptions.defaultOptions&&e.push(this.queryHookOptions.defaultOptions),e.push((0,rb.o)(this.observable&&this.observable.options,this.watchQueryOptions)),e.reduce(ra.J)},e.prototype.createWatchQueryOptions=function(e){void 0===e&&(e={});var t,n=e.skip,r=Object.assign((e.ssr,e.onCompleted,e.onError,e.defaultOptions,(0,t0._T)(e,["skip","ssr","onCompleted","onError","defaultOptions"])),{query:this.query});if(this.renderPromises&&("network-only"===r.fetchPolicy||"cache-and-network"===r.fetchPolicy)&&(r.fetchPolicy="cache-first"),r.variables||(r.variables={}),n){var i=r.fetchPolicy,a=void 0===i?this.getDefaultFetchPolicy():i,o=r.initialFetchPolicy;Object.assign(r,{initialFetchPolicy:void 0===o?a:o,fetchPolicy:"standby"})}else r.fetchPolicy||(r.fetchPolicy=(null===(t=this.observable)||void 0===t?void 0:t.options.initialFetchPolicy)||this.getDefaultFetchPolicy());return r},e.prototype.getDefaultFetchPolicy=function(){var e,t;return(null===(e=this.queryHookOptions.defaultOptions)||void 0===e?void 0:e.fetchPolicy)||(null===(t=this.client.defaultOptions.watchQuery)||void 0===t?void 0:t.fetchPolicy)||"cache-first"},e.prototype.onCompleted=function(e){},e.prototype.onError=function(e){},e.prototype.useObservableQuery=function(){var e=this.observable=this.renderPromises&&this.renderPromises.getSSRObservable(this.watchQueryOptions)||this.observable||this.client.watchQuery(this.getObsQueryOptions());this.obsQueryFields=(0,l.useMemo)(function(){return{refetch:e.refetch.bind(e),reobserve:e.reobserve.bind(e),fetchMore:e.fetchMore.bind(e),updateQuery:e.updateQuery.bind(e),startPolling:e.startPolling.bind(e),stopPolling:e.stopPolling.bind(e),subscribeToMore:e.subscribeToMore.bind(e)}},[e]);var t=!(!1===this.queryHookOptions.ssr||this.queryHookOptions.skip);return this.renderPromises&&t&&(this.renderPromises.registerSSRObservable(e),e.getCurrentResult().loading&&this.renderPromises.addObservableQueryPromise(e)),e},e.prototype.setResult=function(e){var t=this.result;t&&t.data&&(this.previousData=t.data),this.result=e,this.forceUpdate(),this.handleErrorOrCompleted(e)},e.prototype.handleErrorOrCompleted=function(e){var t=this;if(!e.loading){var n=this.toApolloError(e);Promise.resolve().then(function(){n?t.onError(n):e.data&&t.onCompleted(e.data)}).catch(function(e){__DEV__&&n9.kG.warn(e)})}},e.prototype.toApolloError=function(e){return(0,rm.O)(e.errors)?new rs.cA({graphQLErrors:e.errors}):e.error},e.prototype.getCurrentResult=function(){return this.result||this.handleErrorOrCompleted(this.result=this.observable.getCurrentResult()),this.result},e.prototype.toQueryResult=function(e){var t=this.toQueryResultCache.get(e);if(t)return t;var n=e.data,r=(e.partial,(0,t0._T)(e,["data","partial"]));return this.toQueryResultCache.set(e,t=(0,t0.pi)((0,t0.pi)((0,t0.pi)({data:n},r),this.obsQueryFields),{client:this.client,observable:this.observable,variables:this.observable.variables,called:!this.queryHookOptions.skip,previousData:this.previousData})),!t.error&&(0,rm.O)(e.errors)&&(t.error=new rs.cA({graphQLErrors:e.errors})),t},e.prototype.unsafeHandlePartialRefetch=function(e){e.partial&&this.queryHookOptions.partialRefetch&&!e.loading&&(!e.data||0===Object.keys(e.data).length)&&"cache-only"!==this.observable.options.fetchPolicy&&(Object.assign(e,{loading:!0,networkStatus:ru.I.refetch}),this.observable.refetch())},e}();function r_(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:{};return rv(iH,e)},iz=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"50",10),r=i$({variables:{offset:(t-1)*n,limit:n},fetchPolicy:"network-only"}),i=r.data,a=r.loading,o=r.error;return a?l.createElement(iR,null):o?l.createElement(iD,{error:o}):i?l.createElement(iI,{chains:i.chains.results,page:t,pageSize:n,total:i.chains.metadata.total}):null},iG=n(67932),iW=n(8126),iK="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function iV(e){if(iq())return Intl.DateTimeFormat.supportedLocalesOf(e)[0]}function iq(){return("undefined"==typeof Intl?"undefined":iK(Intl))==="object"&&"function"==typeof Intl.DateTimeFormat}var iZ="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},iX=function(){function e(e,t){for(var n=0;n=i.length)break;s=i[o++]}else{if((o=i.next()).done)break;s=o.value}var s,u=s;if((void 0===e?"undefined":iZ(e))!=="object")return;e=e[u]}return e}},{key:"put",value:function(){for(var e=arguments.length,t=Array(e),n=0;n=o.length)break;c=o[u++]}else{if((u=o.next()).done)break;c=u.value}var c,l=c;"object"!==iZ(a[l])&&(a[l]={}),a=a[l]}return a[i]=r}}]),e}();let i1=iQ;var i0=new i1;function i2(e,t){if(!iq())return function(e){return e.toString()};var n=i4(e),r=JSON.stringify(t),i=i0.get(String(n),r)||i0.put(String(n),r,new Intl.DateTimeFormat(n,t));return function(e){return i.format(e)}}var i3={};function i4(e){var t=e.toString();return i3[t]?i3[t]:i3[t]=iV(e)}var i6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function i5(e){return i8(e)?e:new Date(e)}function i8(e){return e instanceof Date||i9(e)}function i9(e){return(void 0===e?"undefined":i6(e))==="object"&&"function"==typeof e.getTime}var i7=n(54087),ae=n.n(i7);function at(e,t){if(0===e.length)return 0;for(var n=0,r=e.length-1,i=void 0;n<=r;){var a=t(e[i=Math.floor((r+n)/2)]);if(0===a)return i;if(a<0){if((n=i+1)>r)return n}else if((r=i-1)=t.nextUpdateTime)aa(t,this.instances);else break}},scheduleNextTick:function(){var e=this;this.scheduledTick=ae()(function(){e.tick(),e.scheduleNextTick()})},start:function(){this.scheduleNextTick()},stop:function(){ae().cancel(this.scheduledTick)}};function ai(e){var t=an(e.getNextValue(),2),n=t[0],r=t[1];e.setValue(n),e.nextUpdateTime=r}function aa(e,t){ai(e),as(t,e),ao(t,e)}function ao(e,t){var n=au(e,t);e.splice(n,0,t)}function as(e,t){var n=e.indexOf(t);e.splice(n,1)}function au(e,t){var n=t.nextUpdateTime;return at(e,function(e){return e.nextUpdateTime===n?0:e.nextUpdateTime>n?1:-1})}var ac=(0,ec.oneOfType)([(0,ec.shape)({minTime:ec.number,formatAs:ec.string.isRequired}),(0,ec.shape)({test:ec.func,formatAs:ec.string.isRequired}),(0,ec.shape)({minTime:ec.number,format:ec.func.isRequired}),(0,ec.shape)({test:ec.func,format:ec.func.isRequired})]),al=(0,ec.oneOfType)([ec.string,(0,ec.shape)({steps:(0,ec.arrayOf)(ac).isRequired,labels:(0,ec.oneOfType)([ec.string,(0,ec.arrayOf)(ec.string)]).isRequired,round:ec.string})]),af=Object.assign||function(e){for(var t=1;t=0)&&Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function ap(e){var t=e.date,n=e.future,r=e.timeStyle,i=e.round,a=e.minTimeLeft,o=e.tooltip,s=e.component,u=e.container,c=e.wrapperComponent,f=e.wrapperProps,d=e.locale,h=e.locales,p=e.formatVerboseDate,b=e.verboseDateFormat,m=e.updateInterval,g=e.tick,v=ah(e,["date","future","timeStyle","round","minTimeLeft","tooltip","component","container","wrapperComponent","wrapperProps","locale","locales","formatVerboseDate","verboseDateFormat","updateInterval","tick"]),y=(0,l.useMemo)(function(){return d&&(h=[d]),h.concat(iW.Z.getDefaultLocale())},[d,h]),w=(0,l.useMemo)(function(){return new iW.Z(y)},[y]);t=(0,l.useMemo)(function(){return i5(t)},[t]);var _=(0,l.useCallback)(function(){var e=Date.now(),o=void 0;if(n&&e>=t.getTime()&&(e=t.getTime(),o=!0),void 0!==a){var s=t.getTime()-1e3*a;e>s&&(e=s,o=!0)}var u=w.format(t,r,{getTimeToNextUpdate:!0,now:e,future:n,round:i}),c=ad(u,2),l=c[0],f=c[1];return f=o?ag:m||f||6e4,[l,e+f]},[t,n,r,m,i,a,w]),E=(0,l.useRef)();E.current=_;var S=(0,l.useMemo)(_,[]),k=ad(S,2),x=k[0],T=k[1],M=(0,l.useState)(x),O=ad(M,2),A=O[0],L=O[1],C=ad((0,l.useState)(),2),I=C[0],D=C[1],N=(0,l.useRef)();(0,l.useEffect)(function(){if(g)return N.current=ar.add({getNextValue:function(){return E.current()},setValue:L,nextUpdateTime:T}),function(){return N.current.stop()}},[g]),(0,l.useEffect)(function(){if(N.current)N.current.forceUpdate();else{var e=_(),t=ad(e,1)[0];L(t)}},[_]),(0,l.useEffect)(function(){D(!0)},[]);var P=(0,l.useMemo)(function(){if("undefined"!=typeof window)return i2(y,b)},[y,b]),R=(0,l.useMemo)(function(){if("undefined"!=typeof window)return p?p(t):P(t)},[t,p,P]),j=l.createElement(s,af({date:t,verboseDate:I?R:void 0,tooltip:o},v),A),F=c||u;return F?l.createElement(F,af({},f,{verboseDate:I?R:void 0}),j):j}ap.propTypes={date:el().oneOfType([el().instanceOf(Date),el().number]).isRequired,locale:el().string,locales:el().arrayOf(el().string),future:el().bool,timeStyle:al,round:el().string,minTimeLeft:el().number,component:el().elementType.isRequired,tooltip:el().bool.isRequired,formatVerboseDate:el().func,verboseDateFormat:el().object,updateInterval:el().oneOfType([el().number,el().arrayOf(el().shape({threshold:el().number,interval:el().number.isRequired}))]),tick:el().bool,wrapperComponent:el().func,wrapperProps:el().object},ap.defaultProps={locales:[],component:av,tooltip:!0,verboseDateFormat:{weekday:"long",day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"2-digit",second:"2-digit"},tick:!0},ap=l.memo(ap);let ab=ap;var am,ag=31536e9;function av(e){var t=e.date,n=e.verboseDate,r=e.tooltip,i=e.children,a=ah(e,["date","verboseDate","tooltip","children"]),o=(0,l.useMemo)(function(){return t.toISOString()},[t]);return l.createElement("time",af({},a,{dateTime:o,title:r?n:void 0}),i)}av.propTypes={date:el().instanceOf(Date).isRequired,verboseDate:el().string,tooltip:el().bool.isRequired,children:el().string.isRequired};var ay=n(30381),aw=n.n(ay),a_=n(31657);function aE(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function aS(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0?new rs.cA({graphQLErrors:i}):void 0;if(u===s.current.mutationId&&!c.ignoreResults){var f={called:!0,loading:!1,data:r,error:l,client:a};s.current.isMounted&&!(0,ri.D)(s.current.result,f)&&o(s.current.result=f)}var d=e.onCompleted||(null===(n=s.current.options)||void 0===n?void 0:n.onCompleted);return null==d||d(t.data,c),t}).catch(function(t){if(u===s.current.mutationId&&s.current.isMounted){var n,r={loading:!1,error:t,data:void 0,called:!0,client:a};(0,ri.D)(s.current.result,r)||o(s.current.result=r)}var i=e.onError||(null===(n=s.current.options)||void 0===n?void 0:n.onError);if(i)return i(t,c),{data:void 0,errors:t};throw t})},[]),c=(0,l.useCallback)(function(){s.current.isMounted&&o({called:!1,loading:!1,client:n})},[]);return(0,l.useEffect)(function(){return s.current.isMounted=!0,function(){s.current.isMounted=!1}},[]),[u,(0,t0.pi)({reset:c},a)]}var os=n(59067),ou=n(28428),oc=n(11186),ol=n(78513);function of(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var od=function(e){return(0,b.createStyles)({paper:{display:"flex",margin:"".concat(2.5*e.spacing.unit,"px 0"),padding:"".concat(3*e.spacing.unit,"px ").concat(3.5*e.spacing.unit,"px")},content:{flex:1,width:"100%"},actions:of({marginTop:-(1.5*e.spacing.unit),marginLeft:-(4*e.spacing.unit)},e.breakpoints.up("sm"),{marginLeft:0,marginRight:-(1.5*e.spacing.unit)}),itemBlock:{border:"1px solid rgba(224, 224, 224, 1)",borderRadius:e.shape.borderRadius,padding:2*e.spacing.unit,marginTop:e.spacing.unit},itemBlockText:{overflowWrap:"anywhere"}})},oh=(0,b.withStyles)(od)(function(e){var t=e.actions,n=e.children,r=e.classes;return l.createElement(ii.default,{className:r.paper},l.createElement("div",{className:r.content},n),t&&l.createElement("div",{className:r.actions},t))}),op=function(e){var t=e.title;return l.createElement(x.default,{variant:"subtitle2",gutterBottom:!0},t)},ob=function(e){var t=e.children,n=e.value;return l.createElement(x.default,{variant:"body1",noWrap:!0},t||n)},om=(0,b.withStyles)(od)(function(e){var t=e.children,n=e.classes,r=e.value;return l.createElement("div",{className:n.itemBlock},l.createElement(x.default,{variant:"body1",className:n.itemBlockText},t||r))});function og(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]-1}let sq=sV;function sZ(e,t){var n=this.__data__,r=sH(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}let sX=sZ;function sJ(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e-1&&e%1==0&&e<=cC}let cD=cI;var cN="[object Arguments]",cP="[object Array]",cR="[object Boolean]",cj="[object Date]",cF="[object Error]",cY="[object Function]",cB="[object Map]",cU="[object Number]",cH="[object Object]",c$="[object RegExp]",cz="[object Set]",cG="[object String]",cW="[object WeakMap]",cK="[object ArrayBuffer]",cV="[object DataView]",cq="[object Float64Array]",cZ="[object Int8Array]",cX="[object Int16Array]",cJ="[object Int32Array]",cQ="[object Uint8Array]",c1="[object Uint8ClampedArray]",c0="[object Uint16Array]",c2="[object Uint32Array]",c3={};function c4(e){return eD(e)&&cD(e.length)&&!!c3[eC(e)]}c3["[object Float32Array]"]=c3[cq]=c3[cZ]=c3[cX]=c3[cJ]=c3[cQ]=c3[c1]=c3[c0]=c3[c2]=!0,c3[cN]=c3[cP]=c3[cK]=c3[cR]=c3[cV]=c3[cj]=c3[cF]=c3[cY]=c3[cB]=c3[cU]=c3[cH]=c3[c$]=c3[cz]=c3[cG]=c3[cW]=!1;let c6=c4;function c5(e){return function(t){return e(t)}}let c8=c5;var c9=n(79730),c7=c9.Z&&c9.Z.isTypedArray,le=c7?c8(c7):c6;let lt=le;var ln=Object.prototype.hasOwnProperty;function lr(e,t){var n=cx(e),r=!n&&cS(e),i=!n&&!r&&(0,cT.Z)(e),a=!n&&!r&&!i&<(e),o=n||r||i||a,s=o?cb(e.length,String):[],u=s.length;for(var c in e)(t||ln.call(e,c))&&!(o&&("length"==c||i&&("offset"==c||"parent"==c)||a&&("buffer"==c||"byteLength"==c||"byteOffset"==c)||cL(c,u)))&&s.push(c);return s}let li=lr;var la=Object.prototype;function lo(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||la)}let ls=lo;var lu=sT(Object.keys,Object);let lc=lu;var ll=Object.prototype.hasOwnProperty;function lf(e){if(!ls(e))return lc(e);var t=[];for(var n in Object(e))ll.call(e,n)&&"constructor"!=n&&t.push(n);return t}let ld=lf;function lh(e){return null!=e&&cD(e.length)&&!ur(e)}let lp=lh;function lb(e){return lp(e)?li(e):ld(e)}let lm=lb;function lg(e,t){return e&&ch(t,lm(t),e)}let lv=lg;function ly(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}let lw=ly;var l_=Object.prototype.hasOwnProperty;function lE(e){if(!ed(e))return lw(e);var t=ls(e),n=[];for(var r in e)"constructor"==r&&(t||!l_.call(e,r))||n.push(r);return n}let lS=lE;function lk(e){return lp(e)?li(e,!0):lS(e)}let lx=lk;function lT(e,t){return e&&ch(t,lx(t),e)}let lM=lT;var lO=n(42896);function lA(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n=0||(i[n]=e[n]);return i}function hu(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}var hc=function(e){return Array.isArray(e)&&0===e.length},hl=function(e){return"function"==typeof e},hf=function(e){return null!==e&&"object"==typeof e},hd=function(e){return String(Math.floor(Number(e)))===e},hh=function(e){return"[object String]"===Object.prototype.toString.call(e)},hp=function(e){return 0===l.Children.count(e)},hb=function(e){return hf(e)&&hl(e.then)};function hm(e,t,n,r){void 0===r&&(r=0);for(var i=d8(t);e&&r=0?[]:{}}}return(0===a?e:i)[o[a]]===n?e:(void 0===n?delete i[o[a]]:i[o[a]]=n,0===a&&void 0===n&&delete r[o[a]],r)}function hv(e,t,n,r){void 0===n&&(n=new WeakMap),void 0===r&&(r={});for(var i=0,a=Object.keys(e);i0?t.map(function(t){return x(t,hm(e,t))}):[Promise.resolve("DO_NOT_DELETE_YOU_WILL_BE_FIRED")]).then(function(e){return e.reduce(function(e,n,r){return"DO_NOT_DELETE_YOU_WILL_BE_FIRED"===n||n&&(e=hg(e,t[r],n)),e},{})})},[x]),M=(0,l.useCallback)(function(e){return Promise.all([T(e),h.validationSchema?k(e):{},h.validate?S(e):{}]).then(function(e){var t=e[0],n=e[1],r=e[2];return sk.all([t,n,r],{arrayMerge:hL})})},[h.validate,h.validationSchema,T,S,k]),O=hN(function(e){return void 0===e&&(e=_.values),E({type:"SET_ISVALIDATING",payload:!0}),M(e).then(function(e){return v.current&&(E({type:"SET_ISVALIDATING",payload:!1}),sd()(_.errors,e)||E({type:"SET_ERRORS",payload:e})),e})});(0,l.useEffect)(function(){o&&!0===v.current&&sd()(p.current,h.initialValues)&&O(p.current)},[o,O]);var A=(0,l.useCallback)(function(e){var t=e&&e.values?e.values:p.current,n=e&&e.errors?e.errors:b.current?b.current:h.initialErrors||{},r=e&&e.touched?e.touched:m.current?m.current:h.initialTouched||{},i=e&&e.status?e.status:g.current?g.current:h.initialStatus;p.current=t,b.current=n,m.current=r,g.current=i;var a=function(){E({type:"RESET_FORM",payload:{isSubmitting:!!e&&!!e.isSubmitting,errors:n,touched:r,status:i,values:t,isValidating:!!e&&!!e.isValidating,submitCount:e&&e.submitCount&&"number"==typeof e.submitCount?e.submitCount:0}})};if(h.onReset){var o=h.onReset(_.values,V);hb(o)?o.then(a):a()}else a()},[h.initialErrors,h.initialStatus,h.initialTouched]);(0,l.useEffect)(function(){!0===v.current&&!sd()(p.current,h.initialValues)&&(c&&(p.current=h.initialValues,A()),o&&O(p.current))},[c,h.initialValues,A,o,O]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(b.current,h.initialErrors)&&(b.current=h.initialErrors||hS,E({type:"SET_ERRORS",payload:h.initialErrors||hS}))},[c,h.initialErrors]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(m.current,h.initialTouched)&&(m.current=h.initialTouched||hk,E({type:"SET_TOUCHED",payload:h.initialTouched||hk}))},[c,h.initialTouched]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(g.current,h.initialStatus)&&(g.current=h.initialStatus,E({type:"SET_STATUS",payload:h.initialStatus}))},[c,h.initialStatus,h.initialTouched]);var L=hN(function(e){if(y.current[e]&&hl(y.current[e].validate)){var t=hm(_.values,e),n=y.current[e].validate(t);return hb(n)?(E({type:"SET_ISVALIDATING",payload:!0}),n.then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}}),E({type:"SET_ISVALIDATING",payload:!1})})):(E({type:"SET_FIELD_ERROR",payload:{field:e,value:n}}),Promise.resolve(n))}return h.validationSchema?(E({type:"SET_ISVALIDATING",payload:!0}),k(_.values,e).then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t[e]}}),E({type:"SET_ISVALIDATING",payload:!1})})):Promise.resolve()}),C=(0,l.useCallback)(function(e,t){var n=t.validate;y.current[e]={validate:n}},[]),I=(0,l.useCallback)(function(e){delete y.current[e]},[]),D=hN(function(e,t){return E({type:"SET_TOUCHED",payload:e}),(void 0===t?i:t)?O(_.values):Promise.resolve()}),N=(0,l.useCallback)(function(e){E({type:"SET_ERRORS",payload:e})},[]),P=hN(function(e,t){var r=hl(e)?e(_.values):e;return E({type:"SET_VALUES",payload:r}),(void 0===t?n:t)?O(r):Promise.resolve()}),R=(0,l.useCallback)(function(e,t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}})},[]),j=hN(function(e,t,r){return E({type:"SET_FIELD_VALUE",payload:{field:e,value:t}}),(void 0===r?n:r)?O(hg(_.values,e,t)):Promise.resolve()}),F=(0,l.useCallback)(function(e,t){var n,r=t,i=e;if(!hh(e)){e.persist&&e.persist();var a=e.target?e.target:e.currentTarget,o=a.type,s=a.name,u=a.id,c=a.value,l=a.checked,f=(a.outerHTML,a.options),d=a.multiple;r=t||s||u,i=/number|range/.test(o)?(n=parseFloat(c),isNaN(n)?"":n):/checkbox/.test(o)?hI(hm(_.values,r),l,c):d?hC(f):c}r&&j(r,i)},[j,_.values]),Y=hN(function(e){if(hh(e))return function(t){return F(t,e)};F(e)}),B=hN(function(e,t,n){return void 0===t&&(t=!0),E({type:"SET_FIELD_TOUCHED",payload:{field:e,value:t}}),(void 0===n?i:n)?O(_.values):Promise.resolve()}),U=(0,l.useCallback)(function(e,t){e.persist&&e.persist();var n,r=e.target,i=r.name,a=r.id;r.outerHTML,B(t||i||a,!0)},[B]),H=hN(function(e){if(hh(e))return function(t){return U(t,e)};U(e)}),$=(0,l.useCallback)(function(e){hl(e)?E({type:"SET_FORMIK_STATE",payload:e}):E({type:"SET_FORMIK_STATE",payload:function(){return e}})},[]),z=(0,l.useCallback)(function(e){E({type:"SET_STATUS",payload:e})},[]),G=(0,l.useCallback)(function(e){E({type:"SET_ISSUBMITTING",payload:e})},[]),W=hN(function(){return E({type:"SUBMIT_ATTEMPT"}),O().then(function(e){var t,n=e instanceof Error;if(!n&&0===Object.keys(e).length){try{if(void 0===(t=q()))return}catch(r){throw r}return Promise.resolve(t).then(function(e){return v.current&&E({type:"SUBMIT_SUCCESS"}),e}).catch(function(e){if(v.current)throw E({type:"SUBMIT_FAILURE"}),e})}if(v.current&&(E({type:"SUBMIT_FAILURE"}),n))throw e})}),K=hN(function(e){e&&e.preventDefault&&hl(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hl(e.stopPropagation)&&e.stopPropagation(),W().catch(function(e){console.warn("Warning: An unhandled error was caught from submitForm()",e)})}),V={resetForm:A,validateForm:O,validateField:L,setErrors:N,setFieldError:R,setFieldTouched:B,setFieldValue:j,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,setFormikState:$,submitForm:W},q=hN(function(){return f(_.values,V)}),Z=hN(function(e){e&&e.preventDefault&&hl(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hl(e.stopPropagation)&&e.stopPropagation(),A()}),X=(0,l.useCallback)(function(e){return{value:hm(_.values,e),error:hm(_.errors,e),touched:!!hm(_.touched,e),initialValue:hm(p.current,e),initialTouched:!!hm(m.current,e),initialError:hm(b.current,e)}},[_.errors,_.touched,_.values]),J=(0,l.useCallback)(function(e){return{setValue:function(t,n){return j(e,t,n)},setTouched:function(t,n){return B(e,t,n)},setError:function(t){return R(e,t)}}},[j,B,R]),Q=(0,l.useCallback)(function(e){var t=hf(e),n=t?e.name:e,r=hm(_.values,n),i={name:n,value:r,onChange:Y,onBlur:H};if(t){var a=e.type,o=e.value,s=e.as,u=e.multiple;"checkbox"===a?void 0===o?i.checked=!!r:(i.checked=!!(Array.isArray(r)&&~r.indexOf(o)),i.value=o):"radio"===a?(i.checked=r===o,i.value=o):"select"===s&&u&&(i.value=i.value||[],i.multiple=!0)}return i},[H,Y,_.values]),ee=(0,l.useMemo)(function(){return!sd()(p.current,_.values)},[p.current,_.values]),et=(0,l.useMemo)(function(){return void 0!==s?ee?_.errors&&0===Object.keys(_.errors).length:!1!==s&&hl(s)?s(h):s:_.errors&&0===Object.keys(_.errors).length},[s,ee,_.errors,h]);return ha({},_,{initialValues:p.current,initialErrors:b.current,initialTouched:m.current,initialStatus:g.current,handleBlur:H,handleChange:Y,handleReset:Z,handleSubmit:K,resetForm:A,setErrors:N,setFormikState:$,setFieldTouched:B,setFieldValue:j,setFieldError:R,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,submitForm:W,validateForm:O,validateField:L,isValid:et,dirty:ee,unregisterField:I,registerField:C,getFieldProps:Q,getFieldMeta:X,getFieldHelpers:J,validateOnBlur:i,validateOnChange:n,validateOnMount:o})}function hT(e){var t=hx(e),n=e.component,r=e.children,i=e.render,a=e.innerRef;return(0,l.useImperativeHandle)(a,function(){return t}),(0,l.createElement)(hw,{value:t},n?(0,l.createElement)(n,t):i?i(t):r?hl(r)?r(t):hp(r)?null:l.Children.only(r):null)}function hM(e){var t={};if(e.inner){if(0===e.inner.length)return hg(t,e.path,e.message);for(var n=e.inner,r=Array.isArray(n),i=0,n=r?n:n[Symbol.iterator]();;){if(r){if(i>=n.length)break;a=n[i++]}else{if((i=n.next()).done)break;a=i.value}var a,o=a;hm(t,o.path)||(t=hg(t,o.path,o.message))}}return t}function hO(e,t,n,r){void 0===n&&(n=!1),void 0===r&&(r={});var i=hA(e);return t[n?"validateSync":"validate"](i,{abortEarly:!1,context:r})}function hA(e){var t=Array.isArray(e)?[]:{};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var r=String(n);!0===Array.isArray(e[r])?t[r]=e[r].map(function(e){return!0===Array.isArray(e)||sR(e)?hA(e):""!==e?e:void 0}):sR(e[r])?t[r]=hA(e[r]):t[r]=""!==e[r]?e[r]:void 0}return t}function hL(e,t,n){var r=e.slice();return t.forEach(function(t,i){if(void 0===r[i]){var a=!1!==n.clone&&n.isMergeableObject(t);r[i]=a?sk(Array.isArray(t)?[]:{},t,n):t}else n.isMergeableObject(t)?r[i]=sk(e[i],t,n):-1===e.indexOf(t)&&r.push(t)}),r}function hC(e){return Array.from(e).filter(function(e){return e.selected}).map(function(e){return e.value})}function hI(e,t,n){if("boolean"==typeof e)return Boolean(t);var r=[],i=!1,a=-1;if(Array.isArray(e))r=e,i=(a=e.indexOf(n))>=0;else if(!n||"true"==n||"false"==n)return Boolean(t);return t&&n&&!i?r.concat(n):i?r.slice(0,a).concat(r.slice(a+1)):r}var hD="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?l.useLayoutEffect:l.useEffect;function hN(e){var t=(0,l.useRef)(e);return hD(function(){t.current=e}),(0,l.useCallback)(function(){for(var e=arguments.length,n=Array(e),r=0;re?t:e},0);return Array.from(ha({},e,{length:t+1}))};(function(e){function t(t){var n;return(n=e.call(this,t)||this).updateArrayField=function(e,t,r){var i=n.props,a=i.name;(0,i.formik.setFormikState)(function(n){var i="function"==typeof r?r:e,o="function"==typeof t?t:e,s=hg(n.values,a,e(hm(n.values,a))),u=r?i(hm(n.errors,a)):void 0,c=t?o(hm(n.touched,a)):void 0;return hc(u)&&(u=void 0),hc(c)&&(c=void 0),ha({},n,{values:s,errors:r?hg(n.errors,a,u):n.errors,touched:t?hg(n.touched,a,c):n.touched})})},n.push=function(e){return n.updateArrayField(function(t){return[].concat(hU(t),[hi(e)])},!1,!1)},n.handlePush=function(e){return function(){return n.push(e)}},n.swap=function(e,t){return n.updateArrayField(function(n){return hF(n,e,t)},!0,!0)},n.handleSwap=function(e,t){return function(){return n.swap(e,t)}},n.move=function(e,t){return n.updateArrayField(function(n){return hj(n,e,t)},!0,!0)},n.handleMove=function(e,t){return function(){return n.move(e,t)}},n.insert=function(e,t){return n.updateArrayField(function(n){return hY(n,e,t)},function(t){return hY(t,e,null)},function(t){return hY(t,e,null)})},n.handleInsert=function(e,t){return function(){return n.insert(e,t)}},n.replace=function(e,t){return n.updateArrayField(function(n){return hB(n,e,t)},!1,!1)},n.handleReplace=function(e,t){return function(){return n.replace(e,t)}},n.unshift=function(e){var t=-1;return n.updateArrayField(function(n){var r=n?[e].concat(n):[e];return t<0&&(t=r.length),r},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n}),t},n.handleUnshift=function(e){return function(){return n.unshift(e)}},n.handleRemove=function(e){return function(){return n.remove(e)}},n.handlePop=function(){return function(){return n.pop()}},n.remove=n.remove.bind(hu(n)),n.pop=n.pop.bind(hu(n)),n}ho(t,e);var n=t.prototype;return n.componentDidUpdate=function(e){this.props.validateOnChange&&this.props.formik.validateOnChange&&!sd()(hm(e.formik.values,e.name),hm(this.props.formik.values,this.props.name))&&this.props.formik.validateForm(this.props.formik.values)},n.remove=function(e){var t;return this.updateArrayField(function(n){var r=n?hU(n):[];return t||(t=r[e]),hl(r.splice)&&r.splice(e,1),r},!0,!0),t},n.pop=function(){var e;return this.updateArrayField(function(t){var n=t;return e||(e=n&&n.pop&&n.pop()),n},!0,!0),e},n.render=function(){var e={push:this.push,pop:this.pop,swap:this.swap,move:this.move,insert:this.insert,replace:this.replace,unshift:this.unshift,remove:this.remove,handlePush:this.handlePush,handlePop:this.handlePop,handleSwap:this.handleSwap,handleMove:this.handleMove,handleInsert:this.handleInsert,handleReplace:this.handleReplace,handleUnshift:this.handleUnshift,handleRemove:this.handleRemove},t=this.props,n=t.component,r=t.render,i=t.children,a=t.name,o=hs(t.formik,["validate","validationSchema"]),s=ha({},e,{form:o,name:a});return n?(0,l.createElement)(n,s):r?r(s):i?"function"==typeof i?i(s):hp(i)?null:l.Children.only(i):null},t})(l.Component).defaultProps={validateOnChange:!0},l.Component,l.Component;var hH=n(24802),h$=n(71209),hz=n(91750),hG=n(11970),hW=n(4689),hK=n(67598),hV=function(){return(hV=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&(n[r[i]]=e[r[i]]);return n}function hZ(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form,o=a.isSubmitting,s=a.touched,u=a.errors,c=e.onBlur,l=e.helperText,f=hq(e,["disabled","field","form","onBlur","helperText"]),d=hm(u,i.name),h=hm(s,i.name)&&!!d;return hV(hV({variant:f.variant,error:h,helperText:h?d:l,disabled:null!=t?t:o,onBlur:null!=c?c:function(e){r(null!=e?e:i.name)}},i),f)}function hX(e){var t=e.children,n=hq(e,["children"]);return(0,l.createElement)(iw.Z,hV({},hZ(n)),t)}function hJ(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=(e.type,e.onBlur),s=hq(e,["disabled","field","form","type","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function hQ(e){return(0,l.createElement)(hH.Z,hV({},hJ(e)))}function h1(e){var t,n=e.disabled,r=e.field,i=r.onBlur,a=hq(r,["onBlur"]),o=e.form.isSubmitting,s=(e.type,e.onBlur),u=hq(e,["disabled","field","form","type","onBlur"]);return hV(hV({disabled:null!=n?n:o,indeterminate:!Array.isArray(a.value)&&null==a.value,onBlur:null!=s?s:function(e){i(null!=e?e:a.name)}},a),u)}function h0(e){return(0,l.createElement)(h$.Z,hV({},h1(e)))}function h2(e){var t=e.Label,n=hq(e,["Label"]);return(0,l.createElement)(hz.Z,hV({control:(0,l.createElement)(h$.Z,hV({},h1(n)))},t))}function h3(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hq(e,["disabled","field","form","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h4(e){return(0,l.createElement)(hG.default,hV({},h3(e)))}function h6(e){var t=e.field,n=t.onBlur,r=hq(t,["onBlur"]),i=(e.form,e.onBlur),a=hq(e,["field","form","onBlur"]);return hV(hV({onBlur:null!=i?i:function(e){n(null!=e?e:r.name)}},r),a)}function h5(e){return(0,l.createElement)(hW.Z,hV({},h6(e)))}function h8(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hq(e,["disabled","field","form","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h9(e){return(0,l.createElement)(hK.default,hV({},h8(e)))}hX.displayName="FormikMaterialUITextField",hQ.displayName="FormikMaterialUISwitch",h0.displayName="FormikMaterialUICheckbox",h2.displayName="FormikMaterialUICheckboxWithLabel",h4.displayName="FormikMaterialUISelect",h5.displayName="FormikMaterialUIRadioGroup",h9.displayName="FormikMaterialUIInputBase";try{a=Map}catch(h7){}try{o=Set}catch(pe){}function pt(e,t,n){if(!e||"object"!=typeof e||"function"==typeof e)return e;if(e.nodeType&&"cloneNode"in e)return e.cloneNode(!0);if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return RegExp(e);if(Array.isArray(e))return e.map(pn);if(a&&e instanceof a)return new Map(Array.from(e.entries()));if(o&&e instanceof o)return new Set(Array.from(e.values()));if(e instanceof Object){t.push(e);var r=Object.create(e);for(var i in n.push(r),e){var s=t.findIndex(function(t){return t===e[i]});r[i]=s>-1?n[s]:pt(e[i],t,n)}return r}return e}function pn(e){return pt(e,[],[])}let pr=Object.prototype.toString,pi=Error.prototype.toString,pa=RegExp.prototype.toString,po="undefined"!=typeof Symbol?Symbol.prototype.toString:()=>"",ps=/^Symbol\((.*)\)(.*)$/;function pu(e){if(e!=+e)return"NaN";let t=0===e&&1/e<0;return t?"-0":""+e}function pc(e,t=!1){if(null==e||!0===e||!1===e)return""+e;let n=typeof e;if("number"===n)return pu(e);if("string"===n)return t?`"${e}"`:e;if("function"===n)return"[Function "+(e.name||"anonymous")+"]";if("symbol"===n)return po.call(e).replace(ps,"Symbol($1)");let r=pr.call(e).slice(8,-1);return"Date"===r?isNaN(e.getTime())?""+e:e.toISOString(e):"Error"===r||e instanceof Error?"["+pi.call(e)+"]":"RegExp"===r?pa.call(e):null}function pl(e,t){let n=pc(e,t);return null!==n?n:JSON.stringify(e,function(e,n){let r=pc(this[e],t);return null!==r?r:n},2)}let pf={default:"${path} is invalid",required:"${path} is a required field",oneOf:"${path} must be one of the following values: ${values}",notOneOf:"${path} must not be one of the following values: ${values}",notType({path:e,type:t,value:n,originalValue:r}){let i=null!=r&&r!==n,a=`${e} must be a \`${t}\` type, but the final value was: \`${pl(n,!0)}\``+(i?` (cast from the value \`${pl(r,!0)}\`).`:".");return null===n&&(a+='\n If "null" is intended as an empty value be sure to mark the schema as `.nullable()`'),a},defined:"${path} must be defined"},pd={length:"${path} must be exactly ${length} characters",min:"${path} must be at least ${min} characters",max:"${path} must be at most ${max} characters",matches:'${path} must match the following: "${regex}"',email:"${path} must be a valid email",url:"${path} must be a valid URL",uuid:"${path} must be a valid UUID",trim:"${path} must be a trimmed string",lowercase:"${path} must be a lowercase string",uppercase:"${path} must be a upper case string"},ph={min:"${path} must be greater than or equal to ${min}",max:"${path} must be less than or equal to ${max}",lessThan:"${path} must be less than ${less}",moreThan:"${path} must be greater than ${more}",positive:"${path} must be a positive number",negative:"${path} must be a negative number",integer:"${path} must be an integer"},pp={min:"${path} field must be later than ${min}",max:"${path} field must be at earlier than ${max}"},pb={isValue:"${path} field must be ${value}"},pm={noUnknown:"${path} field has unspecified keys: ${unknown}"},pg={min:"${path} field must have at least ${min} items",max:"${path} field must have less than or equal to ${max} items",length:"${path} must be have ${length} items"};Object.assign(Object.create(null),{mixed:pf,string:pd,number:ph,date:pp,object:pm,array:pg,boolean:pb});var pv=n(18721),py=n.n(pv);let pw=e=>e&&e.__isYupSchema__;class p_{constructor(e,t){if(this.refs=e,this.refs=e,"function"==typeof t){this.fn=t;return}if(!py()(t,"is"))throw TypeError("`is:` is required for `when()` conditions");if(!t.then&&!t.otherwise)throw TypeError("either `then:` or `otherwise:` is required for `when()` conditions");let{is:n,then:r,otherwise:i}=t,a="function"==typeof n?n:(...e)=>e.every(e=>e===n);this.fn=function(...e){let t=e.pop(),n=e.pop(),o=a(...e)?r:i;if(o)return"function"==typeof o?o(n):n.concat(o.resolve(t))}}resolve(e,t){let n=this.refs.map(e=>e.getValue(null==t?void 0:t.value,null==t?void 0:t.parent,null==t?void 0:t.context)),r=this.fn.apply(e,n.concat(e,t));if(void 0===r||r===e)return e;if(!pw(r))throw TypeError("conditions must return a schema object");return r.resolve(t)}}let pE=p_;function pS(e){return null==e?[]:[].concat(e)}function pk(){return(pk=Object.assign||function(e){for(var t=1;tpl(t[n])):"function"==typeof e?e(t):e}static isError(e){return e&&"ValidationError"===e.name}constructor(e,t,n,r){super(),this.name="ValidationError",this.value=t,this.path=n,this.type=r,this.errors=[],this.inner=[],pS(e).forEach(e=>{pT.isError(e)?(this.errors.push(...e.errors),this.inner=this.inner.concat(e.inner.length?e.inner:e)):this.errors.push(e)}),this.message=this.errors.length>1?`${this.errors.length} errors occurred`:this.errors[0],Error.captureStackTrace&&Error.captureStackTrace(this,pT)}}let pM=e=>{let t=!1;return(...n)=>{t||(t=!0,e(...n))}};function pO(e,t){let{endEarly:n,tests:r,args:i,value:a,errors:o,sort:s,path:u}=e,c=pM(t),l=r.length,f=[];if(o=o||[],!l)return o.length?c(new pT(o,a,u)):c(null,a);for(let d=0;d=0||(i[n]=e[n]);return i}function pR(e){function t(t,n){let{value:r,path:i="",label:a,options:o,originalValue:s,sync:u}=t,c=pP(t,["value","path","label","options","originalValue","sync"]),{name:l,test:f,params:d,message:h}=e,{parent:p,context:b}=o;function m(e){return pD.isRef(e)?e.getValue(r,p,b):e}function g(e={}){let t=pL()(pN({value:r,originalValue:s,label:a,path:e.path||i},d,e.params),m),n=new pT(pT.formatError(e.message||h,t),r,t.path,e.type||l);return n.params=t,n}let v=pN({path:i,parent:p,type:l,createError:g,resolve:m,options:o,originalValue:s},c);if(!u){try{Promise.resolve(f.call(v,r,v)).then(e=>{pT.isError(e)?n(e):e?n(null,e):n(g())})}catch(y){n(y)}return}let w;try{var _;if(w=f.call(v,r,v),"function"==typeof(null==(_=w)?void 0:_.then))throw Error(`Validation test of type: "${v.type}" returned a Promise during a synchronous validate. This test will finish after the validate call has returned`)}catch(E){n(E);return}pT.isError(w)?n(w):w?n(null,w):n(g())}return t.OPTIONS=e,t}pD.prototype.__isYupRef=!0;let pj=e=>e.substr(0,e.length-1).substr(1);function pF(e,t,n,r=n){let i,a,o;return t?((0,pC.forEach)(t,(s,u,c)=>{let l=u?pj(s):s;if((e=e.resolve({context:r,parent:i,value:n})).innerType){let f=c?parseInt(l,10):0;if(n&&f>=n.length)throw Error(`Yup.reach cannot resolve an array item at index: ${s}, in the path: ${t}. because there is no value at that index. `);i=n,n=n&&n[f],e=e.innerType}if(!c){if(!e.fields||!e.fields[l])throw Error(`The schema does not contain the path: ${t}. (failed at: ${o} which is a type: "${e._type}")`);i=n,n=n&&n[l],e=e.fields[l]}a=l,o=u?"["+s+"]":"."+s}),{schema:e,parent:i,parentPath:a}):{parent:i,parentPath:t,schema:e}}class pY{constructor(){this.list=new Set,this.refs=new Map}get size(){return this.list.size+this.refs.size}describe(){let e=[];for(let t of this.list)e.push(t);for(let[,n]of this.refs)e.push(n.describe());return e}toArray(){return Array.from(this.list).concat(Array.from(this.refs.values()))}add(e){pD.isRef(e)?this.refs.set(e.key,e):this.list.add(e)}delete(e){pD.isRef(e)?this.refs.delete(e.key):this.list.delete(e)}has(e,t){if(this.list.has(e))return!0;let n,r=this.refs.values();for(;!(n=r.next()).done;)if(t(n.value)===e)return!0;return!1}clone(){let e=new pY;return e.list=new Set(this.list),e.refs=new Map(this.refs),e}merge(e,t){let n=this.clone();return e.list.forEach(e=>n.add(e)),e.refs.forEach(e=>n.add(e)),t.list.forEach(e=>n.delete(e)),t.refs.forEach(e=>n.delete(e)),n}}function pB(){return(pB=Object.assign||function(e){for(var t=1;t{this.typeError(pf.notType)}),this.type=(null==e?void 0:e.type)||"mixed",this.spec=pB({strip:!1,strict:!1,abortEarly:!0,recursive:!0,nullable:!1,presence:"optional"},null==e?void 0:e.spec)}get _type(){return this.type}_typeCheck(e){return!0}clone(e){if(this._mutate)return e&&Object.assign(this.spec,e),this;let t=Object.create(Object.getPrototypeOf(this));return t.type=this.type,t._typeError=this._typeError,t._whitelistError=this._whitelistError,t._blacklistError=this._blacklistError,t._whitelist=this._whitelist.clone(),t._blacklist=this._blacklist.clone(),t.exclusiveTests=pB({},this.exclusiveTests),t.deps=[...this.deps],t.conditions=[...this.conditions],t.tests=[...this.tests],t.transforms=[...this.transforms],t.spec=pn(pB({},this.spec,e)),t}label(e){var t=this.clone();return t.spec.label=e,t}meta(...e){if(0===e.length)return this.spec.meta;let t=this.clone();return t.spec.meta=Object.assign(t.spec.meta||{},e[0]),t}withMutation(e){let t=this._mutate;this._mutate=!0;let n=e(this);return this._mutate=t,n}concat(e){if(!e||e===this)return this;if(e.type!==this.type&&"mixed"!==this.type)throw TypeError(`You cannot \`concat()\` schema's of different types: ${this.type} and ${e.type}`);let t=this,n=e.clone(),r=pB({},t.spec,n.spec);return n.spec=r,n._typeError||(n._typeError=t._typeError),n._whitelistError||(n._whitelistError=t._whitelistError),n._blacklistError||(n._blacklistError=t._blacklistError),n._whitelist=t._whitelist.merge(e._whitelist,e._blacklist),n._blacklist=t._blacklist.merge(e._blacklist,e._whitelist),n.tests=t.tests,n.exclusiveTests=t.exclusiveTests,n.withMutation(t=>{e.tests.forEach(e=>{t.test(e.OPTIONS)})}),n}isType(e){return!!this.spec.nullable&&null===e||this._typeCheck(e)}resolve(e){let t=this;if(t.conditions.length){let n=t.conditions;(t=t.clone()).conditions=[],t=(t=n.reduce((t,n)=>n.resolve(t,e),t)).resolve(e)}return t}cast(e,t={}){let n=this.resolve(pB({value:e},t)),r=n._cast(e,t);if(void 0!==e&&!1!==t.assert&&!0!==n.isType(r)){let i=pl(e),a=pl(r);throw TypeError(`The value of ${t.path||"field"} could not be cast to a value that satisfies the schema type: "${n._type}". attempted value: ${i} -`+(a!==i?`result of cast: ${a}`:""))}return r}_cast(e,t){let n=void 0===e?e:this.transforms.reduce((t,n)=>n.call(this,t,e,this),e);return void 0===n&&(n=this.getDefault()),n}_validate(e,t={},n){let{sync:r,path:i,from:a=[],originalValue:o=e,strict:s=this.spec.strict,abortEarly:u=this.spec.abortEarly}=t,c=e;s||(c=this._cast(c,pB({assert:!1},t)));let l={value:c,path:i,options:t,originalValue:o,schema:this,label:this.spec.label,sync:r,from:a},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),pO({args:l,value:c,path:i,sync:r,tests:f,endEarly:u},e=>{if(e)return void n(e,c);pO({tests:this.tests,args:l,path:i,sync:r,value:c,endEarly:u},n)})}validate(e,t,n){let r=this.resolve(pB({},t,{value:e}));return"function"==typeof n?r._validate(e,t,n):new Promise((n,i)=>r._validate(e,t,(e,t)=>{e?i(e):n(t)}))}validateSync(e,t){let n;return this.resolve(pB({},t,{value:e}))._validate(e,pB({},t,{sync:!0}),(e,t)=>{if(e)throw e;n=t}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,e=>{if(pT.isError(e))return!1;throw e})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(n){if(pT.isError(n))return!1;throw n}}_getDefault(){let e=this.spec.default;return null==e?e:"function"==typeof e?e.call(this):pn(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return 0===arguments.length?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return null!=e}defined(e=pf.defined){return this.test({message:e,name:"defined",exclusive:!0,test:e=>void 0!==e})}required(e=pf.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(e){return this.schema._isPresent(e)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(e=>"required"!==e.OPTIONS.name),e}nullable(e=!0){return this.clone({nullable:!1!==e})}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(void 0===(t=1===e.length?"function"==typeof e[0]?{test:e[0]}:e[0]:2===e.length?{name:e[0],test:e[1]}:{name:e[0],message:e[1],test:e[2]}).message&&(t.message=pf.default),"function"!=typeof t.test)throw TypeError("`test` is a required parameters");let n=this.clone(),r=pR(t),i=t.exclusive||t.name&&!0===n.exclusiveTests[t.name];if(t.exclusive&&!t.name)throw TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(n.exclusiveTests[t.name]=!!t.exclusive),n.tests=n.tests.filter(e=>e.OPTIONS.name!==t.name||!i&&e.OPTIONS.test!==r.OPTIONS.test),n.tests.push(r),n}when(e,t){Array.isArray(e)||"string"==typeof e||(t=e,e=".");let n=this.clone(),r=pS(e).map(e=>new pD(e));return r.forEach(e=>{e.isSibling&&n.deps.push(e.key)}),n.conditions.push(new pE(r,t)),n}typeError(e){var t=this.clone();return t._typeError=pR({message:e,name:"typeError",test(e){return!!(void 0===e||this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t}oneOf(e,t=pf.oneOf){var n=this.clone();return e.forEach(e=>{n._whitelist.add(e),n._blacklist.delete(e)}),n._whitelistError=pR({message:t,name:"oneOf",test(e){if(void 0===e)return!0;let t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}notOneOf(e,t=pf.notOneOf){var n=this.clone();return e.forEach(e=>{n._blacklist.add(e),n._whitelist.delete(e)}),n._blacklistError=pR({message:t,name:"notOneOf",test(e){let t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:n}=e.spec,r={meta:n,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(e=>({name:e.OPTIONS.name,params:e.OPTIONS.params})).filter((e,t,n)=>n.findIndex(t=>t.name===e.name)===t)};return r}}for(let pH of(pU.prototype.__isYupSchema__=!0,["validate","validateSync"]))pU.prototype[`${pH}At`]=function(e,t,n={}){let{parent:r,parentPath:i,schema:a}=pF(this,e,t,n.context);return a[pH](r&&r[i],pB({},n,{parent:r,path:e}))};for(let p$ of["equals","is"])pU.prototype[p$]=pU.prototype.oneOf;for(let pz of["not","nope"])pU.prototype[pz]=pU.prototype.notOneOf;pU.prototype.optional=pU.prototype.notRequired;let pG=pU;function pW(){return new pG}pW.prototype=pG.prototype;let pK=e=>null==e;function pV(){return new pq}class pq extends pU{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}isTrue(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test:e=>pK(e)||!0===e})}isFalse(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test:e=>pK(e)||!1===e})}}pV.prototype=pq.prototype;let pZ=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,pX=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,pJ=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,pQ=e=>pK(e)||e===e.trim(),p1=({}).toString();function p0(){return new p2}class p2 extends pU{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=null!=e&&e.toString?e.toString():e;return t===p1?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=pd.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t=pd.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t=pd.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}matches(e,t){let n=!1,r,i;return t&&("object"==typeof t?{excludeEmptyString:n=!1,message:r,name:i}=t:r=t),this.test({name:i||"matches",message:r||pd.matches,params:{regex:e},test:t=>pK(t)||""===t&&n||-1!==t.search(e)})}email(e=pd.email){return this.matches(pZ,{name:"email",message:e,excludeEmptyString:!0})}url(e=pd.url){return this.matches(pX,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=pd.uuid){return this.matches(pJ,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>null===e?"":e)}trim(e=pd.trim){return this.transform(e=>null!=e?e.trim():e).test({message:e,name:"trim",test:pQ})}lowercase(e=pd.lowercase){return this.transform(e=>pK(e)?e:e.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toLowerCase()})}uppercase(e=pd.uppercase){return this.transform(e=>pK(e)?e:e.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toUpperCase()})}}p0.prototype=p2.prototype;let p3=e=>e!=+e;function p4(){return new p6}class p6 extends pU{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!p3(e)}min(e,t=ph.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t>=this.resolve(e)}})}max(e,t=ph.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t<=this.resolve(e)}})}lessThan(e,t=ph.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(t){return pK(t)||tthis.resolve(e)}})}positive(e=ph.positive){return this.moreThan(0,e)}negative(e=ph.negative){return this.lessThan(0,e)}integer(e=ph.integer){return this.test({name:"integer",message:e,test:e=>pK(e)||Number.isInteger(e)})}truncate(){return this.transform(e=>pK(e)?e:0|e)}round(e){var t,n=["ceil","floor","round","trunc"];if("trunc"===(e=(null==(t=e)?void 0:t.toLowerCase())||"round"))return this.truncate();if(-1===n.indexOf(e.toLowerCase()))throw TypeError("Only valid options for round() are: "+n.join(", "));return this.transform(t=>pK(t)?t:Math[e](t))}}p4.prototype=p6.prototype;var p5=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function p8(e){var t,n,r=[1,4,5,6,7,10,11],i=0;if(n=p5.exec(e)){for(var a,o=0;a=r[o];++o)n[a]=+n[a]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(void 0===n[8]||""===n[8])&&(void 0===n[9]||""===n[9])?t=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):("Z"!==n[8]&&void 0!==n[9]&&(i=60*n[10]+n[11],"+"===n[9]&&(i=0-i)),t=Date.UTC(n[1],n[2],n[3],n[4],n[5]+i,n[6],n[7]))}else t=Date.parse?Date.parse(e):NaN;return t}let p9=new Date(""),p7=e=>"[object Date]"===Object.prototype.toString.call(e);function be(){return new bt}class bt extends pU{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=p8(e),isNaN(e)?p9:new Date(e))})})}_typeCheck(e){return p7(e)&&!isNaN(e.getTime())}prepareParam(e,t){let n;if(pD.isRef(e))n=e;else{let r=this.cast(e);if(!this._typeCheck(r))throw TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);n=r}return n}min(e,t=pp.min){let n=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(e){return pK(e)||e>=this.resolve(n)}})}max(e,t=pp.max){var n=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(e){return pK(e)||e<=this.resolve(n)}})}}bt.INVALID_DATE=p9,be.prototype=bt.prototype,be.INVALID_DATE=p9;var bn=n(11865),br=n.n(bn),bi=n(68929),ba=n.n(bi),bo=n(67523),bs=n.n(bo),bu=n(94633),bc=n.n(bu);function bl(e,t=[]){let n=[],r=[];function i(e,i){var a=(0,pC.split)(e)[0];~r.indexOf(a)||r.push(a),~t.indexOf(`${i}-${a}`)||n.push([i,a])}for(let a in e)if(py()(e,a)){let o=e[a];~r.indexOf(a)||r.push(a),pD.isRef(o)&&o.isSibling?i(o.path,a):pw(o)&&"deps"in o&&o.deps.forEach(e=>i(e,a))}return bc().array(r,n).reverse()}function bf(e,t){let n=1/0;return e.some((e,r)=>{var i;if((null==(i=t.path)?void 0:i.indexOf(e))!==-1)return n=r,!0}),n}function bd(e){return(t,n)=>bf(e,t)-bf(e,n)}function bh(){return(bh=Object.assign||function(e){for(var t=1;t"[object Object]"===Object.prototype.toString.call(e);function bb(e,t){let n=Object.keys(e.fields);return Object.keys(t).filter(e=>-1===n.indexOf(e))}let bm=bd([]);class bg extends pU{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=bm,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null}),e&&this.shape(e)})}_typeCheck(e){return bp(e)||"function"==typeof e}_cast(e,t={}){var n;let r=super._cast(e,t);if(void 0===r)return this.getDefault();if(!this._typeCheck(r))return r;let i=this.fields,a=null!=(n=t.stripUnknown)?n:this.spec.noUnknown,o=this._nodes.concat(Object.keys(r).filter(e=>-1===this._nodes.indexOf(e))),s={},u=bh({},t,{parent:s,__validating:t.__validating||!1}),c=!1;for(let l of o){let f=i[l],d=py()(r,l);if(f){let h,p=r[l];u.path=(t.path?`${t.path}.`:"")+l;let b="spec"in(f=f.resolve({value:p,context:t.context,parent:s}))?f.spec:void 0,m=null==b?void 0:b.strict;if(null==b?void 0:b.strip){c=c||l in r;continue}void 0!==(h=t.__validating&&m?r[l]:f.cast(r[l],u))&&(s[l]=h)}else d&&!a&&(s[l]=r[l]);s[l]!==r[l]&&(c=!0)}return c?s:r}_validate(e,t={},n){let r=[],{sync:i,from:a=[],originalValue:o=e,abortEarly:s=this.spec.abortEarly,recursive:u=this.spec.recursive}=t;a=[{schema:this,value:o},...a],t.__validating=!0,t.originalValue=o,t.from=a,super._validate(e,t,(e,c)=>{if(e){if(!pT.isError(e)||s)return void n(e,c);r.push(e)}if(!u||!bp(c)){n(r[0]||null,c);return}o=o||c;let l=this._nodes.map(e=>(n,r)=>{let i=-1===e.indexOf(".")?(t.path?`${t.path}.`:"")+e:`${t.path||""}["${e}"]`,s=this.fields[e];if(s&&"validate"in s){s.validate(c[e],bh({},t,{path:i,from:a,strict:!0,parent:c,originalValue:o[e]}),r);return}r(null)});pO({sync:i,tests:l,value:c,errors:r,endEarly:s,sort:this._sortErrors,path:t.path},n)})}clone(e){let t=super.clone(e);return t.fields=bh({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),n=t.fields;for(let[r,i]of Object.entries(this.fields)){let a=n[r];void 0===a?n[r]=i:a instanceof pU&&i instanceof pU&&(n[r]=i.concat(a))}return t.withMutation(()=>t.shape(n))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let n=this.fields[t];e[t]="default"in n?n.getDefault():void 0}),e}_getDefault(){return"default"in this.spec?super._getDefault():this._nodes.length?this.getDefaultFromShape():void 0}shape(e,t=[]){let n=this.clone(),r=Object.assign(n.fields,e);if(n.fields=r,n._sortErrors=bd(Object.keys(r)),t.length){Array.isArray(t[0])||(t=[t]);let i=t.map(([e,t])=>`${e}-${t}`);n._excludedEdges=n._excludedEdges.concat(i)}return n._nodes=bl(r,n._excludedEdges),n}pick(e){let t={};for(let n of e)this.fields[n]&&(t[n]=this.fields[n]);return this.clone().withMutation(e=>(e.fields={},e.shape(t)))}omit(e){let t=this.clone(),n=t.fields;for(let r of(t.fields={},e))delete n[r];return t.withMutation(()=>t.shape(n))}from(e,t,n){let r=(0,pC.getter)(e,!0);return this.transform(i=>{if(null==i)return i;let a=i;return py()(i,e)&&(a=bh({},i),n||delete a[e],a[t]=r(i)),a})}noUnknown(e=!0,t=pm.noUnknown){"string"==typeof e&&(t=e,e=!0);let n=this.test({name:"noUnknown",exclusive:!0,message:t,test(t){if(null==t)return!0;let n=bb(this.schema,t);return!e||0===n.length||this.createError({params:{unknown:n.join(", ")}})}});return n.spec.noUnknown=e,n}unknown(e=!0,t=pm.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&bs()(t,(t,n)=>e(n)))}camelCase(){return this.transformKeys(ba())}snakeCase(){return this.transformKeys(br())}constantCase(){return this.transformKeys(e=>br()(e).toUpperCase())}describe(){let e=super.describe();return e.fields=pL()(this.fields,e=>e.describe()),e}}function bv(e){return new bg(e)}function by(){return(by=Object.assign||function(e){for(var t=1;t{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let n=super._cast(e,t);if(!this._typeCheck(n)||!this.innerType)return n;let r=!1,i=n.map((e,n)=>{let i=this.innerType.cast(e,by({},t,{path:`${t.path||""}[${n}]`}));return i!==e&&(r=!0),i});return r?i:n}_validate(e,t={},n){var r,i;let a=[],o=t.sync,s=t.path,u=this.innerType,c=null!=(r=t.abortEarly)?r:this.spec.abortEarly,l=null!=(i=t.recursive)?i:this.spec.recursive,f=null!=t.originalValue?t.originalValue:e;super._validate(e,t,(e,r)=>{if(e){if(!pT.isError(e)||c)return void n(e,r);a.push(e)}if(!l||!u||!this._typeCheck(r)){n(a[0]||null,r);return}f=f||r;let i=Array(r.length);for(let d=0;du.validate(h,b,t)}pO({sync:o,path:s,value:r,errors:a,endEarly:c,tests:i},n)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!pw(e))throw TypeError("`array.of()` sub-schema must be a valid yup schema not: "+pl(e));return t.innerType=e,t}length(e,t=pg.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t){return t=t||pg.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t){return t=t||pg.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:null==t?[]:[].concat(t))}compact(e){let t=e?(t,n,r)=>!e(t,n,r):e=>!!e;return this.transform(e=>null!=e?e.filter(t):e)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}}bw.prototype=b_.prototype;var bE=bv().shape({name:p0().required("Required"),url:p0().required("Required")}),bS=function(e){var t=e.initialValues,n=e.onSubmit,r=e.submitButtonText,i=e.nameDisabled,a=void 0!==i&&i;return l.createElement(hT,{initialValues:t,validationSchema:bE,onSubmit:n},function(e){var t=e.isSubmitting;return l.createElement(l.Fragment,null,l.createElement(hR,{"data-testid":"bridge-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",disabled:a,required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"url",name:"url",label:"Bridge URL",placeholder:"https://",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"url-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"minimumContractPayment",name:"minimumContractPayment",label:"Minimum Contract Payment",placeholder:"0",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"minimumContractPayment-helper-text"}})),l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"confirmations",name:"confirmations",label:"Confirmations",placeholder:"0",type:"number",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"confirmations-helper-text"}})))),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},r)))))})},bk=function(e){var t=e.bridge,n=e.onSubmit,r={name:t.name,url:t.url,minimumContractPayment:t.minimumContractPayment,confirmations:t.confirmations};return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:40},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Bridge",action:l.createElement(aA.Z,{component:tz,href:"/bridges/".concat(t.id)},"Cancel")}),l.createElement(aW.Z,null,l.createElement(bS,{nameDisabled:!0,initialValues:r,onSubmit:n,submitButtonText:"Save Bridge"}))))))};function bx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]&&arguments[0],t=e?function(){return l.createElement(x.default,{variant:"body1"},"Loading...")}:function(){return null};return{isLoading:e,LoadingPlaceholder:t}},mc=n(76023);function ml(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function mB(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=4?[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]:void 0}var mZ={};function mX(e){if(0===e.length||1===e.length)return e;var t=e.join(".");return mZ[t]||(mZ[t]=mq(e)),mZ[t]}function mJ(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return mX(e.filter(function(e){return"token"!==e})).reduce(function(e,t){return mK({},e,n[t])},t)}function mQ(e){return e.join(" ")}function m1(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return m0({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(i)})})}}function m0(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,o=e.key,s=t.properties,u=t.type,c=t.tagName,f=t.value;if("text"===u)return f;if(c){var d,h=m1(n,a);if(a){var p=Object.keys(n).reduce(function(e,t){return t.split(".").forEach(function(t){e.includes(t)||e.push(t)}),e},[]),b=s.className&&s.className.includes("token")?["token"]:[],m=s.className&&b.concat(s.className.filter(function(e){return!p.includes(e)}));d=mK({},s,{className:mQ(m)||void 0,style:mJ(s.className,Object.assign({},s.style,i),n)})}else d=mK({},s,{className:mQ(s.className)});var g=h(t.children);return l.createElement(c,(0,mV.Z)({key:o},d),g)}}let m2=function(e,t){return -1!==e.listLanguages().indexOf(t)};var m3=/\n/g;function m4(e){return e.match(m3)}function m6(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return l.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof r?r(i):r},"".concat(i,"\n"))})}function m5(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,o=void 0===a?{}:a,s=e.startingLineNumber;return l.createElement("code",{style:Object.assign({},n,i)},m6({lines:t.replace(/\n$/,"").split("\n"),style:o,startingLineNumber:s}))}function m8(e){return"".concat(e.toString().length,".25em")}function m9(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function m7(e,t,n){var r,i={display:"inline-block",minWidth:m8(n),paddingRight:"1em",textAlign:"right",userSelect:"none"};return mK({},i,"function"==typeof e?e(t):e)}function ge(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=void 0===o?{}:o,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,f=e.wrapLongLines,d="function"==typeof s?s(n):s;if(d.className=c,n&&a){var h=m7(r,n,i);t.unshift(m9(n,h))}return f&l&&(d.style=mK({},d.style,{display:"flex"})),{type:"element",tagName:"span",properties:d,children:t}}function gt(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return ge({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:a,showLineNumbers:r,wrapLongLines:u})}function b(e,t){if(r&&t&&i){var n=m7(s,t,o);e.unshift(m9(t,n))}return e}function m(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||r.length>0?p(e,n,r):b(e,n)}for(var g=function(){var e=l[h],t=e.children[0].value;if(m4(t)){var n=t.split("\n");n.forEach(function(t,i){var o=r&&f.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===i){var u=l.slice(d+1,h).concat(ge({children:[s],className:e.properties.className})),c=m(u,o);f.push(c)}else if(i===n.length-1){if(l[h+1]&&l[h+1].children&&l[h+1].children[0]){var p={type:"text",value:"".concat(t)},b=ge({children:[p],className:e.properties.className});l.splice(h+1,0,b)}else{var g=[s],v=m(g,o,e.properties.className);f.push(v)}}else{var y=[s],w=m(y,o,e.properties.className);f.push(w)}}),d=h}h++};h code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}};var gu=n(98695),gc=n.n(gu);let gl=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];var gf=go(gc(),gs);gf.supportedLanguages=gl;let gd=gf;var gh=n(64566);function gp(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function gb(){var e=gp(["\n query FetchConfigV2 {\n configv2 {\n user\n effective\n }\n }\n"]);return gb=function(){return e},e}var gm=n0(gb()),gg=function(e){var t=e.children;return l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},t))},gv=function(){return l.createElement(gg,null,"...")},gy=function(e){var t=e.children;return l.createElement(gg,null,t)},gw=function(e){var t=e.loading,n=e.toml,r=e.error,i=void 0===r?"":r,a=e.title,o=e.expanded;if(i)return l.createElement(gy,null,i);if(t)return l.createElement(gv,null);a||(a="TOML");var s={display:"block"};return l.createElement(x.default,null,l.createElement(mP.Z,{defaultExpanded:o},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},a),l.createElement(mj.Z,{style:s},l.createElement(gd,{language:"toml",style:gs},n))))},g_=function(){var e=rv(gm,{fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return(null==t?void 0:t.configv2.effective)=="N/A"?l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"V2 config dump:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0})))):l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"User specified:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0,expanded:!0}),l.createElement(gw,{title:"Effective (with defaults):",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.effective,showHead:!0})))))},gE=n(34823),gS=function(e){return(0,b.createStyles)({cell:{paddingTop:1.5*e.spacing.unit,paddingBottom:1.5*e.spacing.unit}})},gk=(0,b.withStyles)(gS)(function(e){var t=e.classes,n=(0,A.I0)();(0,l.useEffect)(function(){n((0,ty.DQ)())});var r=(0,A.v9)(gE.N,A.wU);return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Node"}),l.createElement(r8.Z,null,l.createElement(r9.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"Version"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.version))),l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"SHA"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.commitSHA))))))}),gx=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,sm:12,md:8},l.createElement(d.Z,{container:!0},l.createElement(g_,null))),l.createElement(d.Z,{item:!0,sm:12,md:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gk,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mN,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mE,null))))))},gT=function(){return l.createElement(gx,null)},gM=function(){return l.createElement(gT,null)},gO=n(44431),gA=1e18,gL=function(e){return new gO.BigNumber(e).dividedBy(gA).toFixed(8)},gC=function(e){var t=e.keys,n=e.chainID,r=e.hideHeaderTitle;return l.createElement(l.Fragment,null,l.createElement(sl.Z,{title:!r&&"Account Balances",subheader:"Chain ID "+n}),l.createElement(aW.Z,null,l.createElement(w.default,{dense:!1,disablePadding:!0},t&&t.map(function(e,r){return l.createElement(l.Fragment,null,l.createElement(_.default,{disableGutters:!0,key:["acc-balance",n.toString(),r.toString()].join("-")},l.createElement(E.Z,{primary:l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(op,{title:"Address"}),l.createElement(ob,{value:e.address})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"Native Token Balance"}),l.createElement(ob,{value:e.ethBalance||"--"})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"LINK Balance"}),l.createElement(ob,{value:e.linkBalance?gL(e.linkBalance):"--"}))))})),r+1s&&l.createElement(gB.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:r.footer},l.createElement(aA.Z,{href:"/runs",component:tz},"View More"))))))});function vt(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vn(){var e=vt(["\n ","\n query FetchRecentJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...RecentJobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return vn=function(){return e},e}var vr=5,vi=n0(vn(),g9),va=function(){var e=rv(vi,{variables:{offset:0,limit:vr},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(ve,{data:t,errorMsg:null==r?void 0:r.message,loading:n,maxRunsSize:vr})},vo=function(e){return(0,b.createStyles)({style:{textAlign:"center",padding:2.5*e.spacing.unit,position:"fixed",left:"0",bottom:"0",width:"100%",borderRadius:0},bareAnchor:{color:e.palette.common.black,textDecoration:"none"}})},vs=(0,b.withStyles)(vo)(function(e){var t=e.classes,n=(0,A.v9)(gE.N,A.wU),r=(0,A.I0)();return(0,l.useEffect)(function(){r((0,ty.DQ)())}),l.createElement(ii.default,{className:t.style},l.createElement(x.default,null,"Chainlink Node ",n.version," at commit"," ",l.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/smartcontractkit/chainlink/commit/".concat(n.commitSHA),className:t.bareAnchor},n.commitSHA)))}),vu=function(e){return(0,b.createStyles)({cell:{borderColor:e.palette.divider,borderTop:"1px solid",borderBottom:"none",paddingTop:2*e.spacing.unit,paddingBottom:2*e.spacing.unit,paddingLeft:2*e.spacing.unit},block:{display:"block"},overflowEllipsis:{textOverflow:"ellipsis",overflow:"hidden"}})},vc=(0,b.withStyles)(vu)(function(e){var t=e.classes,n=e.job;return l.createElement(ir.Z,null,l.createElement(r7.default,{scope:"row",className:t.cell},l.createElement(d.Z,{container:!0,spacing:0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ih,{href:"/jobs/".concat(n.id),classes:{linkContent:t.block}},l.createElement(x.default,{className:t.overflowEllipsis,variant:"body1",component:"span",color:"primary"},n.name||n.id))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,{variant:"body1",color:"textSecondary"},"Created ",l.createElement(aO,{tooltip:!0},n.createdAt))))))});function vl(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vf(){var e=vl(["\n fragment RecentJobsPayload_ResultsFields on Job {\n id\n name\n createdAt\n }\n"]);return vf=function(){return e},e}var vd=n0(vf()),vh=function(){return(0,b.createStyles)({cardHeader:{borderBottom:0},table:{tableLayout:"fixed"}})},vp=(0,b.withStyles)(vh)(function(e){var t,n,r=e.classes,i=e.data,a=e.errorMsg,o=e.loading;return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Recent Jobs",className:r.cardHeader}),l.createElement(r8.Z,{className:r.table},l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(t=null==i?void 0:i.jobs.results)||void 0===t?void 0:t.length)===0},"No recently created jobs"),l.createElement(gU,{msg:a}),null===(n=null==i?void 0:i.jobs.results)||void 0===n?void 0:n.map(function(e,t){return l.createElement(vc,{job:e,key:t})}))))});function vb(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vm(){var e=vb(["\n ","\n query FetchRecentJobs($offset: Int, $limit: Int) {\n jobs(offset: $offset, limit: $limit) {\n results {\n ...RecentJobsPayload_ResultsFields\n }\n }\n }\n"]);return vm=function(){return e},e}var vg=5,vv=n0(vm(),vd),vy=function(){var e=rv(vv,{variables:{offset:0,limit:vg},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vp,{data:t,errorMsg:null==r?void 0:r.message,loading:n})},vw=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:8},l.createElement(va,null)),l.createElement(d.Z,{item:!0,xs:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gY,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(vy,null))))),l.createElement(vs,null))},v_=function(){return l.createElement(vw,null)},vE=function(){return l.createElement(v_,null)},vS=n(87239),vk=function(e){switch(e){case"DirectRequestSpec":return"Direct Request";case"FluxMonitorSpec":return"Flux Monitor";default:return e.replace(/Spec$/,"")}},vx=n(5022),vT=n(78718),vM=n.n(vT);function vO(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1?t-1:0),r=1;r1?t-1:0),r=1;re.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&n.map(function(e){return l.createElement(ir.Z,{key:e.id,style:{cursor:"pointer"},onClick:function(){return r.push("/runs/".concat(e.id))}},l.createElement(r7.default,{className:t.idCell,scope:"row"},l.createElement("div",{className:t.runDetails},l.createElement(x.default,{variant:"h5",color:"primary",component:"span"},e.id))),l.createElement(r7.default,{className:t.stampCell},l.createElement(x.default,{variant:"body1",color:"textSecondary",className:t.stamp},"Created ",l.createElement(aO,{tooltip:!0},e.createdAt))),l.createElement(r7.default,{className:t.statusCell,scope:"row"},l.createElement(x.default,{variant:"body1",className:O()(t.status,yh(t,e.status))},e.status.toLowerCase())))})))}),yb=n(16839),ym=n.n(yb);function yg(e){var t=e.replace(/\w+\s*=\s*<([^>]|[\r\n])*>/g,""),n=ym().read(t),r=n.edges();return n.nodes().map(function(e){var t={id:e,parentIds:r.filter(function(t){return t.w===e}).map(function(e){return e.v})};return Object.keys(n.node(e)).length>0&&(t.attributes=n.node(e)),t})}var yv=n(94164),yy=function(e){var t=e.data,n=[];return(null==t?void 0:t.attributes)&&Object.keys(t.attributes).forEach(function(e){var r;n.push(l.createElement("div",{key:e},l.createElement(x.default,{variant:"body1",color:"textSecondary",component:"div"},l.createElement("b",null,e,":")," ",null===(r=t.attributes)||void 0===r?void 0:r[e])))}),l.createElement("div",null,t&&l.createElement(x.default,{variant:"body1",color:"textPrimary"},l.createElement("b",null,t.id)),n)},yw=n(73343),y_=n(3379),yE=n.n(y_);function yS(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nwindow.innerWidth?u-r.getBoundingClientRect().width-a:u+a,n=c+r.getBoundingClientRect().height+i>window.innerHeight?c-r.getBoundingClientRect().height-a:c+a,r.style.opacity=String(1),r.style.top="".concat(n,"px"),r.style.left="".concat(t,"px"),r.style.zIndex=String(1)}},h=function(e){var t=document.getElementById("tooltip-d3-chart-".concat(e));t&&(t.style.opacity=String(0),t.style.zIndex=String(-1))};return l.createElement("div",{style:{fontFamily:"sans-serif",fontWeight:"normal"}},l.createElement(yv.kJ,{id:"task-list-graph-d3",data:i,config:s,onMouseOverNode:d,onMouseOutNode:h},"D3 chart"),n.map(function(e){return l.createElement("div",{key:"d3-tooltip-key-".concat(e.id),id:"tooltip-d3-chart-".concat(e.id),style:{position:"absolute",opacity:"0",border:"1px solid rgba(0, 0, 0, 0.1)",padding:yw.r.spacing.unit,background:"white",borderRadius:5,zIndex:-1,inlineSize:"min-content"}},l.createElement(yy,{data:e}))}))};function yL(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nyY&&l.createElement("div",{className:t.runDetails},l.createElement(aA.Z,{href:"/jobs/".concat(n.id,"/runs"),component:tz},"View more")))),l.createElement(d.Z,{item:!0,xs:12,sm:6},l.createElement(yF,{observationSource:n.observationSource})))});function yH(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:"";try{return vx.parse(e),!0}catch(t){return!1}})}),wW=function(e){var t=e.initialValues,n=e.onSubmit,r=e.onTOMLChange;return l.createElement(hT,{initialValues:t,validationSchema:wG,onSubmit:n},function(e){var t=e.isSubmitting,n=e.values;return r&&r(n.toml),l.createElement(hR,{"data-testid":"job-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"toml",name:"toml",label:"Job Spec (TOML)",required:!0,fullWidth:!0,multiline:!0,rows:10,rowsMax:25,variant:"outlined",autoComplete:"off",FormHelperTextProps:{"data-testid":"toml-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},"Create Job"))))})},wK=n(50109),wV="persistSpec";function wq(e){var t=e.query,n=new URLSearchParams(t).get("definition");return n?(wK.t8(wV,n),{toml:n}):{toml:wK.U2(wV)||""}}var wZ=function(e){var t=e.onSubmit,n=e.onTOMLChange,r=wq({query:(0,h.TH)().search}),i=function(e){var t=e.replace(/[\u200B-\u200D\uFEFF]/g,"");wK.t8("".concat(wV),t),n&&n(t)};return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"New Job"}),l.createElement(aW.Z,null,l.createElement(wW,{initialValues:r,onSubmit:t,onTOMLChange:i})))};function wX(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=t.start,r=void 0===n?6:n,i=t.end,a=void 0===i?4:i;return e.substring(0,r)+"..."+e.substring(e.length-a)}function _M(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(_W,e)},_V=function(){var e=_K({fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error,i=e.refetch;return l.createElement(_U,{loading:n,data:t,errorMsg:null==r?void 0:r.message,refetch:i})},_q=function(e){var t=e.csaKey;return l.createElement(ir.Z,{hover:!0},l.createElement(r7.default,null,l.createElement(x.default,{variant:"body1"},t.publicKey," ",l.createElement(_x,{data:t.publicKey}))))};function _Z(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function _X(){var e=_Z(["\n fragment CSAKeysPayload_ResultsFields on CSAKey {\n id\n publicKey\n }\n"]);return _X=function(){return e},e}var _J=n0(_X()),_Q=function(e){var t,n,r,i=e.data,a=e.errorMsg,o=e.loading,s=e.onCreate;return l.createElement(r5.Z,null,l.createElement(sl.Z,{action:(null===(t=null==i?void 0:i.csaKeys.results)||void 0===t?void 0:t.length)===0&&l.createElement(ok.default,{variant:"outlined",color:"primary",onClick:s},"New CSA Key"),title:"CSA Key",subheader:"Manage your CSA Key"}),l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Public Key"))),l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(n=null==i?void 0:i.csaKeys.results)||void 0===n?void 0:n.length)===0}),l.createElement(gU,{msg:a}),null===(r=null==i?void 0:i.csaKeys.results)||void 0===r?void 0:r.map(function(e,t){return l.createElement(_q,{csaKey:e,key:t})}))))};function _1(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EM,e)};function EA(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EJ,e)},E3=function(){return oo(EQ)},E4=function(){return oo(E1)},E6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(E0,e)};function E5(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(SK,e)};function Sq(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function kV(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}var kq=function(e){var t=e.run,n=l.useMemo(function(){var e=t.inputs,n=t.outputs,r=t.taskRuns,i=kK(t,["inputs","outputs","taskRuns"]),a={};try{a=JSON.parse(e)}catch(o){a={}}return kW(kz({},i),{inputs:a,outputs:n,taskRuns:r})},[t]);return l.createElement(r5.Z,null,l.createElement(aW.Z,null,l.createElement(kH,{object:n})))};function kZ(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kX(e){for(var t=1;t0&&l.createElement(kr,{errors:t.allErrors})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(h.rs,null,l.createElement(h.AW,{path:"".concat(n,"/json")},l.createElement(kq,{run:t})),l.createElement(h.AW,{path:n},t.taskRuns.length>0&&l.createElement(kN,{taskRuns:t.taskRuns,observationSource:t.job.observationSource}))))))))};function k5(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function k8(){var e=k5(["\n ","\n query FetchJobRun($id: ID!) {\n jobRun(id: $id) {\n __typename\n ... on JobRun {\n ...JobRunPayload_Fields\n }\n ... on NotFoundError {\n message\n }\n }\n }\n"]);return k8=function(){return e},e}var k9=n0(k8(),k4),k7=function(){var e=rv(k9,{variables:{id:(0,h.UO)().id}}),t=e.data,n=e.loading,r=e.error;if(n)return l.createElement(iR,null);if(r)return l.createElement(iD,{error:r});var i=null==t?void 0:t.jobRun;switch(null==i?void 0:i.__typename){case"JobRun":return l.createElement(k6,{run:i});case"NotFoundError":return l.createElement(oa,null);default:return null}};function xe(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xt(){var e=xe(["\n fragment JobRunsPayload_ResultsFields on JobRun {\n id\n allErrors\n createdAt\n finishedAt\n status\n job {\n id\n }\n }\n"]);return xt=function(){return e},e}var xn=n0(xt()),xr=function(e){var t=e.loading,n=e.data,r=e.page,i=e.pageSize,a=(0,h.k6)(),o=l.useMemo(function(){return null==n?void 0:n.jobRuns.results.map(function(e){var t,n=e.allErrors,r=e.id,i=e.createdAt;return{id:r,createdAt:i,errors:n,finishedAt:e.finishedAt,status:e.status}})},[n]);return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(iy,null,"Job Runs")),t&&l.createElement(iR,null),n&&o&&l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(yp,{runs:o}),l.createElement(it.Z,{component:"div",count:n.jobRuns.metadata.total,rowsPerPage:i,rowsPerPageOptions:[i],page:r-1,onChangePage:function(e,t){a.push("/runs?page=".concat(t+1,"&per=").concat(i))},onChangeRowsPerPage:function(){},backIconButtonProps:{"aria-label":"prev-page"},nextIconButtonProps:{"aria-label":"next-page"}})))))};function xi(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xa(){var e=xi(["\n ","\n query FetchJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...JobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return xa=function(){return e},e}var xo=n0(xa(),xn),xs=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"25",10),r=rv(xo,{variables:{offset:(t-1)*n,limit:n},fetchPolicy:"cache-and-network"}),i=r.data,a=r.loading,o=r.error;return o?l.createElement(iD,{error:o}):l.createElement(xr,{loading:a,data:i,page:t,pageSize:n})},xu=function(){var e=(0,h.$B)().path;return l.createElement(h.rs,null,l.createElement(h.AW,{exact:!0,path:e},l.createElement(xs,null)),l.createElement(h.AW,{path:"".concat(e,"/:id")},l.createElement(k7,null)))},xc=bv().shape({name:p0().required("Required"),uri:p0().required("Required"),publicKey:p0().required("Required")}),xl=function(e){var t=e.initialValues,n=e.onSubmit;return l.createElement(hT,{initialValues:t,validationSchema:xc,onSubmit:n},function(e){var t=e.isSubmitting,n=e.submitForm;return l.createElement(hR,{"data-testid":"feeds-manager-form"},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:!1,md:6}),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"uri",name:"uri",label:"URI",required:!0,fullWidth:!0,helperText:"Provided by the Feeds Manager operator",FormHelperTextProps:{"data-testid":"uri-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"publicKey",name:"publicKey",label:"Public Key",required:!0,fullWidth:!0,helperText:"Provided by the Feeds Manager operator",FormHelperTextProps:{"data-testid":"publicKey-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(ok.default,{variant:"contained",color:"primary",disabled:t,onClick:n},"Submit"))))})},xf=function(e){var t=e.data,n=e.onSubmit,r={name:t.name,uri:t.uri,publicKey:t.publicKey};return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Feeds Manager"}),l.createElement(aW.Z,null,l.createElement(xl,{initialValues:r,onSubmit:n})))))};function xd(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xh(){var e=xd(["\n query FetchFeedsManagers {\n feedsManagers {\n results {\n __typename\n id\n name\n uri\n publicKey\n isConnectionActive\n createdAt\n }\n }\n }\n"]);return xh=function(){return e},e}var xp=n0(xh()),xb=function(){return rv(xp)};function xm(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function xF(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}function xY(e,t){return xD(e)||xP(e,t)||xB(e,t)||xR()}function xB(e,t){if(e){if("string"==typeof e)return xI(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return xI(e,t)}}var xU=function(e){return"SN_MAIN"===e||"SN_SEPOLIA"===e},xH=bv().shape({chainID:p0().required("Required"),chainType:p0().required("Required"),accountAddr:p0().required("Required"),accountAddrPubKey:p0().nullable(),adminAddr:p0().required("Required"),ocr1Multiaddr:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr1P2PPeerID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr1KeyBundleID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2Multiaddr:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr2P2PPeerID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2KeyBundleID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2CommitPluginEnabled:pV().required("Required"),ocr2ExecutePluginEnabled:pV().required("Required"),ocr2MedianPluginEnabled:pV().required("Required"),ocr2MercuryPluginEnabled:pV().required("Required"),ocr2ForwarderAddress:p0().nullable()}),x$=function(e){return(0,b.createStyles)({supportedJobOptionsPaper:{padding:2*e.spacing.unit}})},xz=function(e){var t=e.chainAccounts,n=xj(e,["chainAccounts"]),r=h_(),i=r.values,a=i.chainID,o=i.accountAddr,s=r.setFieldValue,u=xY(l.useState(!1),2),c=u[0],f=u[1],d=l.useRef();l.useEffect(function(){d.current=a},[a]),l.useEffect(function(){a!==d.current&&(s(n.name,""),f(!1))},[a,s,n.name]);var h=function(e){var t=e.target.value;"custom"===t?(f(!0),s(n.name,"")):(f(!1),s(n.name,t))};return l.createElement(l.Fragment,null,!xU(a)&&l.createElement(hP,xN({},n,{select:!0,value:c?"custom":o,onChange:h}),t.map(function(e){return l.createElement(tE.default,{key:e.address,value:e.address},e.address)})),xU(a)&&l.createElement(hP,{component:hX,id:"accountAddr",name:"accountAddr",label:"Enter your account address",inputProps:{"data-testid":"customAccountAddr-input"},helperText:"The account address used for this chain",required:!0,fullWidth:!0}),xU(a)&&l.createElement("div",null,l.createElement(hP,{component:hX,id:"accountAddrPubKey",name:"accountAddrPubKey",label:"Account Address Public Key",required:!0,fullWidth:!0,helperText:"The public key for your account address",FormHelperTextProps:{"data-testid":"accountAddrPubKey-helper-text"}})))},xG=(0,b.withStyles)(x$)(function(e){var t=e.classes,n=e.editing,r=void 0!==n&&n,i=e.innerRef,a=e.initialValues,o=e.onSubmit,s=e.chainIDs,u=void 0===s?[]:s,c=e.accounts,f=void 0===c?[]:c,h=e.p2pKeys,p=void 0===h?[]:h,b=e.ocrKeys,m=void 0===b?[]:b,g=e.ocr2Keys,v=void 0===g?[]:g,y=e.showSubmit,w=void 0!==y&&y;return l.createElement(hT,{innerRef:i,initialValues:a,validationSchema:xH,onSubmit:o},function(e){var n=e.values,i=f.filter(function(e){return e.chain.id==n.chainID&&!e.isDisabled});return l.createElement(hR,{"data-testid":"feeds-manager-form",id:"chain-configuration-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"chainType",name:"chainType",label:"Chain Type",select:!0,required:!0,fullWidth:!0,disabled:!0},l.createElement(tE.default,{key:"EVM",value:"EVM"},"EVM"))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"chainID",name:"chainID",label:"Chain ID",required:!0,fullWidth:!0,select:!0,disabled:r,inputProps:{"data-testid":"chainID-input"},FormHelperTextProps:{"data-testid":"chainID-helper-text"}},u.map(function(e){return l.createElement(tE.default,{key:e,value:e},e)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(xz,{component:hX,id:"accountAddr",name:"accountAddr",label:"Account Address",inputProps:{"data-testid":"accountAddr-input"},required:!0,fullWidth:!0,select:!0,helperText:"The account address used for this chain",chainAccounts:i,FormHelperTextProps:{"data-testid":"accountAddr-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"adminAddr",name:"adminAddr",label:"Admin Address",required:!0,fullWidth:!0,helperText:"The address used for LINK payments",FormHelperTextProps:{"data-testid":"adminAddr-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Job Types")),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"fluxMonitorEnabled",type:"checkbox",Label:{label:"Flux Monitor"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1Enabled",type:"checkbox",Label:{label:"OCR"}}),n.ocr1Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),n.ocr1IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr1Multiaddr",name:"ocr1Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr1Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1P2PPeerID",name:"ocr1P2PPeerID",label:"Peer ID",select:!0,required:!0,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1P2PPeerID-helper-text"}},p.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1KeyBundleID",name:"ocr1KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1KeyBundleID-helper-text"}},m.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)})))))))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2Enabled",type:"checkbox",Label:{label:"OCR2"}}),n.ocr2Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),n.ocr2IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr2Multiaddr",name:"ocr2Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR2 Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr2Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2P2PPeerID",name:"ocr2P2PPeerID",label:"Peer ID",select:!0,required:!0,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2P2PPeerID-helper-text"}},p.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2KeyBundleID",name:"ocr2KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR2 Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2KeyBundleID-helper-text"}},v.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)}))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Plugins")),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2CommitPluginEnabled",type:"checkbox",Label:{label:"Commit"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2ExecutePluginEnabled",type:"checkbox",Label:{label:"Execute"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2RebalancerPluginEnabled",type:"checkbox",Label:{label:"Rebalancer"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MedianPluginEnabled",type:"checkbox",Label:{label:"Median"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MercuryPluginEnabled",type:"checkbox",Label:{label:"Mercury"}})),l.createElement(d.Z,{item:!0,xs:12,md:12},l.createElement(hP,{component:hX,id:"ocr2ForwarderAddress",name:"ocr2ForwarderAddress",label:"Forwarder Address (optional)",fullWidth:!0,helperText:"The forwarder address from the Operator Forwarder Contract",FormHelperTextProps:{"data-testid":"ocr2ForwarderAddress-helper-text"}}))))))),w&&l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",size:"large"},"Submit"))))})}),xW=function(e){var t=e.onClose,n=e.open,r=e.onSubmit,i=l.useRef(),a=i$({fetchPolicy:"network-only"}).data,o=_K({fetchPolicy:"cache-and-network"}).data,s=SV({fetchPolicy:"cache-and-network"}).data,u=EO({fetchPolicy:"cache-and-network"}).data,c=E2({fetchPolicy:"cache-and-network"}).data,f={chainID:"",chainType:"EVM",accountAddr:"",adminAddr:"",accountAddrPubKey:"",fluxMonitorEnabled:!1,ocr1Enabled:!1,ocr1IsBootstrap:!1,ocr1Multiaddr:"",ocr1P2PPeerID:"",ocr1KeyBundleID:"",ocr2Enabled:!1,ocr2IsBootstrap:!1,ocr2Multiaddr:"",ocr2P2PPeerID:"",ocr2KeyBundleID:"",ocr2CommitPluginEnabled:!1,ocr2ExecutePluginEnabled:!1,ocr2MedianPluginEnabled:!1,ocr2MercuryPluginEnabled:!1,ocr2RebalancerPluginEnabled:!1,ocr2ForwarderAddress:""},d=a?a.chains.results.map(function(e){return e.id}):[],h=o?o.ethKeys.results:[],p=s?s.p2pKeys.results:[],b=u?u.ocrKeyBundles.results:[],m=c?c.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:t,open:n,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"New Supported Chain")),l.createElement(oT.Z,null,l.createElement(xG,{innerRef:i,initialValues:f,onSubmit:r,chainIDs:d,accounts:h,p2pKeys:p,ocrKeys:b,ocr2Keys:m})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:t},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))},xK=function(e){var t=e.cfg,n=e.onClose,r=e.open,i=e.onSubmit,a=l.useRef(),o=i$({fetchPolicy:"network-only"}).data,s=_K({fetchPolicy:"cache-and-network"}).data,u=SV({fetchPolicy:"cache-and-network"}).data,c=EO({fetchPolicy:"cache-and-network"}).data,f=E2({fetchPolicy:"cache-and-network"}).data;if(!t)return null;var d={chainID:t.chainID,chainType:"EVM",accountAddr:t.accountAddr,adminAddr:t.adminAddr,accountAddrPubKey:t.accountAddrPubKey,fluxMonitorEnabled:t.fluxMonitorJobConfig.enabled,ocr1Enabled:t.ocr1JobConfig.enabled,ocr1IsBootstrap:t.ocr1JobConfig.isBootstrap,ocr1Multiaddr:t.ocr1JobConfig.multiaddr,ocr1P2PPeerID:t.ocr1JobConfig.p2pPeerID,ocr1KeyBundleID:t.ocr1JobConfig.keyBundleID,ocr2Enabled:t.ocr2JobConfig.enabled,ocr2IsBootstrap:t.ocr2JobConfig.isBootstrap,ocr2Multiaddr:t.ocr2JobConfig.multiaddr,ocr2P2PPeerID:t.ocr2JobConfig.p2pPeerID,ocr2KeyBundleID:t.ocr2JobConfig.keyBundleID,ocr2CommitPluginEnabled:t.ocr2JobConfig.plugins.commit,ocr2ExecutePluginEnabled:t.ocr2JobConfig.plugins.execute,ocr2MedianPluginEnabled:t.ocr2JobConfig.plugins.median,ocr2MercuryPluginEnabled:t.ocr2JobConfig.plugins.mercury,ocr2RebalancerPluginEnabled:t.ocr2JobConfig.plugins.rebalancer,ocr2ForwarderAddress:t.ocr2JobConfig.forwarderAddress},h=o?o.chains.results.map(function(e){return e.id}):[],p=s?s.ethKeys.results:[],b=u?u.p2pKeys.results:[],m=c?c.ocrKeyBundles.results:[],g=f?f.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:n,open:r,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"Edit Supported Chain")),l.createElement(oT.Z,null,l.createElement(xG,{innerRef:a,initialValues:d,onSubmit:i,chainIDs:h,accounts:p,p2pKeys:b,ocrKeys:m,ocr2Keys:g,editing:!0})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:n},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))};function xV(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xq(){var e=xV(["\n fragment FeedsManager_ChainConfigFields on FeedsManagerChainConfig {\n id\n chainID\n chainType\n accountAddr\n adminAddr\n accountAddrPubKey\n fluxMonitorJobConfig {\n enabled\n }\n ocr1JobConfig {\n enabled\n isBootstrap\n multiaddr\n p2pPeerID\n keyBundleID\n }\n ocr2JobConfig {\n enabled\n isBootstrap\n multiaddr\n forwarderAddress\n p2pPeerID\n keyBundleID\n plugins {\n commit\n execute\n median\n mercury\n rebalancer\n }\n }\n }\n"]);return xq=function(){return e},e}function xZ(){var e=xV(["\n ","\n fragment FeedsManagerFields on FeedsManager {\n id\n name\n uri\n publicKey\n isConnectionActive\n chainConfigs {\n ...FeedsManager_ChainConfigFields\n }\n }\n"]);return xZ=function(){return e},e}function xX(){var e=xV(["\n fragment FeedsManager_JobProposalsFields on JobProposal {\n id\n name\n externalJobID\n remoteUUID\n status\n pendingUpdate\n latestSpec {\n createdAt\n version\n }\n }\n"]);return xX=function(){return e},e}function xJ(){var e=xV(["\n ","\n ","\n fragment FeedsManagerPayload_ResultsFields on FeedsManager {\n ...FeedsManagerFields\n jobProposals {\n ...FeedsManager_JobProposalsFields\n }\n }\n"]);return xJ=function(){return e},e}function xQ(){var e=xV(["\n ","\n query FetchFeedManagersWithProposals {\n feedsManagers {\n results {\n ...FeedsManagerPayload_ResultsFields\n }\n }\n }\n"]);return xQ=function(){return e},e}var x1=n0(xq()),x0=n0(xZ(),x1),x2=n0(xX()),x3=n0(xJ(),x0,x2),x4=n0(xQ(),x3),x6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(x4,e)};function x5(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0?n.feedsManagers.results[0]:void 0;return n&&a?l.createElement(TZ,{manager:a}):l.createElement(h.l_,{to:{pathname:"/feeds_manager/new",state:{from:e}}})},TJ={name:"Chainlink Feeds Manager",uri:"",publicKey:""},TQ=function(e){var t=e.onSubmit;return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Register Feeds Manager"}),l.createElement(aW.Z,null,l.createElement(xl,{initialValues:TJ,onSubmit:t})))))};function T1(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);nt.version?e:t})},[o]),g=l.useMemo(function(){return ME(o).sort(function(e,t){return t.version-e.version})},[o]),v=function(e,t,n){switch(e){case"PENDING":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"text",color:"secondary",onClick:function(){return b("reject",t)}},"Reject"),m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status&&l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve"),m.id===t&&"DELETED"===n.status&&n.pendingUpdate&&l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("cancel",t)}},"Cancel"),l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs")));case"APPROVED":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",onClick:function(){return b("cancel",t)}},"Cancel"),"DELETED"===n.status&&n.pendingUpdate&&l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs"));case"CANCELLED":if(m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status)return l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve");return null;default:return null}};return l.createElement("div",null,g.map(function(e,n){return l.createElement(mP.Z,{defaultExpanded:0===n,key:n},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},l.createElement(x.default,{className:t.versionText},"Version ",e.version),l.createElement(Es.Z,{label:e.status,color:"APPROVED"===e.status?"primary":"default",variant:"REJECTED"===e.status||"CANCELLED"===e.status?"outlined":"default"}),l.createElement("div",{className:t.proposedAtContainer},l.createElement(x.default,null,"Proposed ",l.createElement(aO,{tooltip:!0},e.createdAt)))),l.createElement(mj.Z,{className:t.expansionPanelDetails},l.createElement("div",{className:t.actions},l.createElement("div",{className:t.editContainer},0===n&&("PENDING"===e.status||"CANCELLED"===e.status)&&"DELETED"!==s.status&&"REVOKED"!==s.status&&l.createElement(ok.default,{variant:"contained",onClick:function(){return p(!0)}},"Edit")),l.createElement("div",{className:t.actionsContainer},v(e.status,e.id,s))),l.createElement(gd,{language:"toml",style:gs,"data-testid":"codeblock"},e.definition)))}),l.createElement(oC,{open:null!=c,title:c?MM[c.action].title:"",body:c?MM[c.action].body:"",onConfirm:function(){if(c){switch(c.action){case"approve":n(c.id);break;case"cancel":r(c.id);break;case"reject":i(c.id)}f(null)}},cancelButtonText:"Cancel",onCancel:function(){return f(null)}}),l.createElement(Md,{open:h,onClose:function(){return p(!1)},initialValues:{definition:m.definition,id:m.id},onSubmit:a}))});function MA(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function ML(){var e=MA(["\n ","\n fragment JobProposalPayloadFields on JobProposal {\n id\n externalJobID\n remoteUUID\n jobID\n specs {\n ...JobProposal_SpecsFields\n }\n status\n pendingUpdate\n }\n"]);return ML=function(){return e},e}var MC=n0(ML(),Mx),MI=function(e){var t=e.onApprove,n=e.onCancel,r=e.onReject,i=e.onUpdateSpec,a=e.proposal;return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Proposal #",a.id))),l.createElement(Mo,{proposal:a}),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(Tq,null,"Specs"))),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(MO,{proposal:a,specs:a.specs,onReject:r,onApprove:t,onCancel:n,onUpdateSpec:i}))))};function MD(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);nU,tA:()=>$,KL:()=>H,Iw:()=>V,DQ:()=>W,cB:()=>T,LO:()=>M,t5:()=>k,qt:()=>x,Jc:()=>C,L7:()=>Y,EO:()=>B});var r,i,a=n(66289),o=n(41800),s=n.n(o),u=n(67932);(i=r||(r={})).IN_PROGRESS="in_progress",i.PENDING_INCOMING_CONFIRMATIONS="pending_incoming_confirmations",i.PENDING_CONNECTION="pending_connection",i.PENDING_BRIDGE="pending_bridge",i.PENDING_SLEEP="pending_sleep",i.ERRORED="errored",i.COMPLETED="completed";var c=n(87013),l=n(19084),f=n(34823);function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]j,v2:()=>F});var r=n(66289);function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var a="/sessions",o="/sessions",s=function e(t){var n=this;i(this,e),this.api=t,this.createSession=function(e){return n.create(e)},this.destroySession=function(){return n.destroy()},this.create=this.api.createResource(a),this.destroy=this.api.deleteResource(o)};function u(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var c="/v2/bulk_delete_runs",l=function e(t){var n=this;u(this,e),this.api=t,this.bulkDeleteJobRuns=function(e){return n.destroy(e)},this.destroy=this.api.deleteResource(c)};function f(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var d="/v2/chains/evm",h="".concat(d,"/:id"),p=function e(t){var n=this;f(this,e),this.api=t,this.getChains=function(){return n.index()},this.createChain=function(e){return n.create(e)},this.destroyChain=function(e){return n.destroy(void 0,{id:e})},this.updateChain=function(e,t){return n.update(t,{id:e})},this.index=this.api.fetchResource(d),this.create=this.api.createResource(d),this.destroy=this.api.deleteResource(h),this.update=this.api.updateResource(h)};function b(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var m="/v2/keys/evm/chain",g=function e(t){var n=this;b(this,e),this.api=t,this.chain=function(e){var t=new URLSearchParams;t.append("address",e.address),t.append("evmChainID",e.evmChainID),null!==e.nextNonce&&t.append("nextNonce",e.nextNonce),null!==e.abandon&&t.append("abandon",String(e.abandon)),null!==e.enabled&&t.append("enabled",String(e.enabled));var r=m+"?"+t.toString();return n.api.createResource(r)()}};function v(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var y="/v2/jobs",w="".concat(y,"/:specId/runs"),_=function e(t){var n=this;v(this,e),this.api=t,this.createJobRunV2=function(e,t){return n.post(t,{specId:e})},this.post=this.api.createResource(w,!0)};function E(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var S="/v2/log",k=function e(t){var n=this;E(this,e),this.api=t,this.getLogConfig=function(){return n.show()},this.updateLogConfig=function(e){return n.update(e)},this.show=this.api.fetchResource(S),this.update=this.api.updateResource(S)};function x(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var T="/v2/nodes",M=function e(t){var n=this;x(this,e),this.api=t,this.getNodes=function(){return n.index()},this.createNode=function(e){return n.create(e)},this.index=this.api.fetchResource(T),this.create=this.api.createResource(T)};function O(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var A="/v2/enroll_webauthn",L=function e(t){var n=this;O(this,e),this.api=t,this.beginKeyRegistration=function(e){return n.create(e)},this.finishKeyRegistration=function(e){return n.put(e)},this.create=this.api.fetchResource(A),this.put=this.api.createResource(A)};function C(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var I="/v2/build_info",D=function e(t){var n=this;C(this,e),this.api=t,this.show=function(){return n.api.GET(I)()}};function N(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var P=function e(t){N(this,e),this.api=t,this.buildInfo=new D(this.api),this.bulkDeleteRuns=new l(this.api),this.chains=new p(this.api),this.logConfig=new k(this.api),this.nodes=new M(this.api),this.jobs=new _(this.api),this.webauthn=new L(this.api),this.evmKeys=new g(this.api)},R=new r.V0({base:void 0}),j=new s(R),F=new P(R)},1398(e,t,n){"use strict";n.d(t,{Z:()=>d});var r=n(67294),i=n(32316),a=n(83638),o=n(94184),s=n.n(o);function u(){return(u=Object.assign||function(e){for(var t=1;tc});var r=n(67294),i=n(32316);function a(){return(a=Object.assign||function(e){for(var t=1;tx,jK:()=>v});var r=n(67294),i=n(37703),a=n(45697),o=n.n(a),s=n(82204),u=n(71426),c=n(94184),l=n.n(c),f=n(32316),d=function(e){var t=e.palette.success||{},n=e.palette.warning||{};return{base:{paddingLeft:5*e.spacing.unit,paddingRight:5*e.spacing.unit},success:{backgroundColor:t.main,color:t.contrastText},error:{backgroundColor:e.palette.error.dark,color:e.palette.error.contrastText},warning:{backgroundColor:n.contrastText,color:n.main}}},h=function(e){var t,n=e.success,r=e.error,i=e.warning,a=e.classes,o=e.className;return n?t=a.success:r?t=a.error:i&&(t=a.warning),l()(a.base,o,t)},p=function(e){return r.createElement(s.Z,{className:h(e),square:!0},r.createElement(u.default,{variant:"body2",color:"inherit",component:"div"},e.children))};p.defaultProps={success:!1,error:!1,warning:!1},p.propTypes={success:o().bool,error:o().bool,warning:o().bool};let b=(0,f.withStyles)(d)(p);var m=function(){return r.createElement(r.Fragment,null,"Unhandled error. Please help us by opening a"," ",r.createElement("a",{href:"https://github.com/smartcontractkit/chainlink/issues/new"},"bug report"))};let g=m;function v(e){return"string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null)}function y(e,t){var n;return n="string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null),r.createElement("p",{key:t},n)}var w=function(e){var t=e.notifications;return r.createElement(b,{error:!0},t.map(y))},_=function(e){var t=e.notifications;return r.createElement(b,{success:!0},t.map(y))},E=function(e){var t=e.errors,n=e.successes;return r.createElement("div",null,(null==t?void 0:t.length)>0&&r.createElement(w,{notifications:t}),n.length>0&&r.createElement(_,{notifications:n}))},S=function(e){return{errors:e.notifications.errors,successes:e.notifications.successes}},k=(0,i.$j)(S)(E);let x=k},9409(e,t,n){"use strict";n.d(t,{ZP:()=>j});var r=n(67294),i=n(37703),a=n(5977),o=n(32316),s=n(1398),u=n(82204),c=n(30060),l=n(71426),f=n(60520),d=n(39814),h=n(57209),p=n(26842),b=n(3950),m=n(5536),g=n(45697),v=n.n(g);let y=n.p+"9f6d832ef97e8493764e.svg";function w(){return(w=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&_.map(function(e,t){return r.createElement(d.Z,{item:!0,xs:12,key:t},r.createElement(u.Z,{raised:!1,className:v.error},r.createElement(c.Z,null,r.createElement(l.default,{variant:"body1",className:v.errorText},(0,b.jK)(e)))))}),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"email",label:"Email",margin:"normal",value:n,onChange:m("email"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"password",label:"Password",type:"password",autoComplete:"password",margin:"normal",value:h,onChange:m("password"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(d.Z,{container:!0,spacing:0,justify:"center"},r.createElement(d.Z,{item:!0},r.createElement(s.Z,{type:"submit",variant:"primary"},"Access Account")))),y&&r.createElement(l.default,{variant:"body1",color:"textSecondary"},"Signing in...")))))))},P=function(e){return{fetching:e.authentication.fetching,authenticated:e.authentication.allowed,errors:e.notifications.errors}},R=(0,i.$j)(P,x({submitSignIn:p.L7}))(N);let j=(0,h.wU)(e)((0,o.withStyles)(D)(R))},16353(e,t,n){"use strict";n.d(t,{ZP:()=>H,rH:()=>U});var r,i=n(37703),a=n(97779),o=n(9541),s=n(19084);function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.Mk.RECEIVE_SIGNOUT_SUCCESS:case s.Mk.RECEIVE_SIGNIN_SUCCESS:var n={allowed:t.authenticated};return o.Ks(n),f(c({},e,n),{errors:[]});case s.Mk.RECEIVE_SIGNIN_FAIL:var r={allowed:!1};return o.Ks(r),f(c({},e,r),{errors:[]});case s.Mk.RECEIVE_SIGNIN_ERROR:case s.Mk.RECEIVE_SIGNOUT_ERROR:var i={allowed:!1};return o.Ks(i),f(c({},e,i),{errors:t.errors||[]});default:return e}};let b=p;function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;return t.type?t.type.startsWith(r.REQUEST)?y(g({},e),{count:e.count+1}):t.type.startsWith(r.RECEIVE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type.startsWith(r.RESPONSE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type===s.di.REDIRECT?y(g({},e),{count:0}):e:e};let S=E;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function x(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:O,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.MATCH_ROUTE:return M(x({},O),{currentUrl:t.pathname});case s.Ih.NOTIFY_SUCCESS:var n={component:t.component,props:t.props};return M(x({},e),{successes:[n],errors:[]});case s.Ih.NOTIFY_SUCCESS_MSG:return M(x({},e),{successes:[t.msg],errors:[]});case s.Ih.NOTIFY_ERROR:var r=t.error.errors,i=null==r?void 0:r.map(function(e){return L(t,e)});return M(x({},e),{successes:[],errors:i});case s.Ih.NOTIFY_ERROR_MSG:return M(x({},e),{successes:[],errors:[t.msg]});case s.Mk.RECEIVE_SIGNIN_FAIL:return M(x({},e),{successes:[],errors:["Your email or password is incorrect. Please try again"]});default:return e}};function L(e,t){return{component:e.component,props:{msg:t.detail}}}let C=A;function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:R,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.REDIRECT:return P(D({},e),{to:t.to});case s.di.MATCH_ROUTE:return P(D({},e),{to:void 0});default:return e}};let F=j;var Y=n(87013),B=(0,a.UY)({authentication:b,fetching:S,notifications:C,redirect:F,buildInfo:Y.Z});B(void 0,{type:"INITIAL_STATE"});var U=i.v9;let H=B},19084(e,t,n){"use strict";var r,i,a,o,s,u,c,l,f,d;n.d(t,{Ih:()=>i,Mk:()=>a,Y0:()=>s,di:()=>r,jp:()=>o}),n(67294),(u=r||(r={})).REDIRECT="REDIRECT",u.MATCH_ROUTE="MATCH_ROUTE",(c=i||(i={})).NOTIFY_SUCCESS="NOTIFY_SUCCESS",c.NOTIFY_SUCCESS_MSG="NOTIFY_SUCCESS_MSG",c.NOTIFY_ERROR="NOTIFY_ERROR",c.NOTIFY_ERROR_MSG="NOTIFY_ERROR_MSG",(l=a||(a={})).REQUEST_SIGNIN="REQUEST_SIGNIN",l.RECEIVE_SIGNIN_SUCCESS="RECEIVE_SIGNIN_SUCCESS",l.RECEIVE_SIGNIN_FAIL="RECEIVE_SIGNIN_FAIL",l.RECEIVE_SIGNIN_ERROR="RECEIVE_SIGNIN_ERROR",l.RECEIVE_SIGNOUT_SUCCESS="RECEIVE_SIGNOUT_SUCCESS",l.RECEIVE_SIGNOUT_ERROR="RECEIVE_SIGNOUT_ERROR",(f=o||(o={})).RECEIVE_CREATE_ERROR="RECEIVE_CREATE_ERROR",f.RECEIVE_CREATE_SUCCESS="RECEIVE_CREATE_SUCCESS",f.RECEIVE_DELETE_ERROR="RECEIVE_DELETE_ERROR",f.RECEIVE_DELETE_SUCCESS="RECEIVE_DELETE_SUCCESS",f.RECEIVE_UPDATE_ERROR="RECEIVE_UPDATE_ERROR",f.RECEIVE_UPDATE_SUCCESS="RECEIVE_UPDATE_SUCCESS",f.REQUEST_CREATE="REQUEST_CREATE",f.REQUEST_DELETE="REQUEST_DELETE",f.REQUEST_UPDATE="REQUEST_UPDATE",f.UPSERT_CONFIGURATION="UPSERT_CONFIGURATION",f.UPSERT_JOB_RUN="UPSERT_JOB_RUN",f.UPSERT_JOB_RUNS="UPSERT_JOB_RUNS",f.UPSERT_TRANSACTION="UPSERT_TRANSACTION",f.UPSERT_TRANSACTIONS="UPSERT_TRANSACTIONS",f.UPSERT_BUILD_INFO="UPSERT_BUILD_INFO",(d=s||(s={})).FETCH_BUILD_INFO_REQUESTED="FETCH_BUILD_INFO_REQUESTED",d.FETCH_BUILD_INFO_SUCCEEDED="FETCH_BUILD_INFO_SUCCEEDED",d.FETCH_BUILD_INFO_FAILED="FETCH_BUILD_INFO_FAILED"},87013(e,t,n){"use strict";n.d(t,{Y:()=>o,Z:()=>u});var r=n(19084);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:o,t=arguments.length>1?arguments[1]:void 0;return t.type===r.Y0.FETCH_BUILD_INFO_SUCCEEDED?a({},t.buildInfo):e};let u=s},34823(e,t,n){"use strict";n.d(t,{N:()=>r});var r=function(e){return e.buildInfo}},73343(e,t,n){"use strict";n.d(t,{r:()=>u});var r=n(19350),i=n(32316),a=n(59114),o=n(5324),s={props:{MuiGrid:{spacing:3*o.default.unit},MuiCardHeader:{titleTypographyProps:{color:"secondary"}}},palette:{action:{hoverOpacity:.3},primary:{light:"#E5F1FF",main:"#3c40c6",contrastText:"#fff"},secondary:{main:"#3d5170"},success:{light:"#e8faf1",main:r.ek.A700,dark:r.ek[700],contrastText:r.y0.white},warning:{light:"#FFFBF1",main:"#fff6b6",contrastText:"#fad27a"},error:{light:"#ffdada",main:"#f44336",dark:"#d32f2f",contrastText:"#fff"},background:{default:"#f5f6f8",appBar:"#3c40c6"},text:{primary:(0,a.darken)(r.BA.A700,.7),secondary:"#818ea3"},listPendingStatus:{background:"#fef7e5",color:"#fecb4c"},listCompletedStatus:{background:"#e9faf2",color:"#4ed495"}},shape:{borderRadius:o.default.unit},overrides:{MuiButton:{root:{borderRadius:o.default.unit/2,textTransform:"none"},sizeLarge:{padding:void 0,fontSize:void 0,paddingTop:o.default.unit,paddingBottom:o.default.unit,paddingLeft:5*o.default.unit,paddingRight:5*o.default.unit}},MuiTableCell:{body:{fontSize:"1rem"},head:{fontSize:"1rem",fontWeight:400}},MuiCardHeader:{root:{borderBottom:"1px solid rgba(0, 0, 0, 0.12)"},action:{marginTop:-2,marginRight:0,"& >*":{marginLeft:2*o.default.unit}},subheader:{marginTop:.5*o.default.unit}}},typography:{useNextVariants:!0,fontFamily:"-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif",button:{textTransform:"none",fontSize:"1.2em"},body1:{fontSize:"1.0rem",fontWeight:400,lineHeight:"1.46429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body2:{fontSize:"1.0rem",fontWeight:500,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body1Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"1rem",lineHeight:1.5,letterSpacing:-.4},body2Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"0.875rem",lineHeight:1.5,letterSpacing:-.4},display1:{color:"#818ea3",fontSize:"2.125rem",fontWeight:400,lineHeight:"1.20588em",letterSpacing:-.4},display2:{color:"#818ea3",fontSize:"2.8125rem",fontWeight:400,lineHeight:"1.13333em",marginLeft:"-.02em",letterSpacing:-.4},display3:{color:"#818ea3",fontSize:"3.5rem",fontWeight:400,lineHeight:"1.30357em",marginLeft:"-.02em",letterSpacing:-.4},display4:{fontSize:14,fontWeightLight:300,fontWeightMedium:500,fontWeightRegular:400,letterSpacing:-.4},h1:{color:"rgb(29, 29, 29)",fontSize:"6rem",fontWeight:300,lineHeight:1},h2:{color:"rgb(29, 29, 29)",fontSize:"3.75rem",fontWeight:300,lineHeight:1},h3:{color:"rgb(29, 29, 29)",fontSize:"3rem",fontWeight:400,lineHeight:1.04},h4:{color:"rgb(29, 29, 29)",fontSize:"2.125rem",fontWeight:400,lineHeight:1.17},h5:{color:"rgb(29, 29, 29)",fontSize:"1.5rem",fontWeight:400,lineHeight:1.33,letterSpacing:-.4},h6:{fontSize:"0.8rem",fontWeight:450,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},subheading:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:"1.5em",letterSpacing:-.4},subtitle1:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:1.75,letterSpacing:-.4},subtitle2:{color:"rgb(29, 29, 29)",fontSize:"0.875rem",fontWeight:500,lineHeight:1.57,letterSpacing:-.4}},shadows:["none","0px 1px 3px 0px rgba(0, 0, 0, 0.1),0px 1px 1px 0px rgba(0, 0, 0, 0.04),0px 2px 1px -1px rgba(0, 0, 0, 0.02)","0px 1px 5px 0px rgba(0, 0, 0, 0.1),0px 2px 2px 0px rgba(0, 0, 0, 0.04),0px 3px 1px -2px rgba(0, 0, 0, 0.02)","0px 1px 8px 0px rgba(0, 0, 0, 0.1),0px 3px 4px 0px rgba(0, 0, 0, 0.04),0px 3px 3px -2px rgba(0, 0, 0, 0.02)","0px 2px 4px -1px rgba(0, 0, 0, 0.1),0px 4px 5px 0px rgba(0, 0, 0, 0.04),0px 1px 10px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 5px 8px 0px rgba(0, 0, 0, 0.04),0px 1px 14px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 6px 10px 0px rgba(0, 0, 0, 0.04),0px 1px 18px 0px rgba(0, 0, 0, 0.02)","0px 4px 5px -2px rgba(0, 0, 0, 0.1),0px 7px 10px 1px rgba(0, 0, 0, 0.04),0px 2px 16px 1px rgba(0, 0, 0, 0.02)","0px 5px 5px -3px rgba(0, 0, 0, 0.1),0px 8px 10px 1px rgba(0, 0, 0, 0.04),0px 3px 14px 2px rgba(0, 0, 0, 0.02)","0px 5px 6px -3px rgba(0, 0, 0, 0.1),0px 9px 12px 1px rgba(0, 0, 0, 0.04),0px 3px 16px 2px rgba(0, 0, 0, 0.02)","0px 6px 6px -3px rgba(0, 0, 0, 0.1),0px 10px 14px 1px rgba(0, 0, 0, 0.04),0px 4px 18px 3px rgba(0, 0, 0, 0.02)","0px 6px 7px -4px rgba(0, 0, 0, 0.1),0px 11px 15px 1px rgba(0, 0, 0, 0.04),0px 4px 20px 3px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 12px 17px 2px rgba(0, 0, 0, 0.04),0px 5px 22px 4px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 13px 19px 2px rgba(0, 0, 0, 0.04),0px 5px 24px 4px rgba(0, 0, 0, 0.02)","0px 7px 9px -4px rgba(0, 0, 0, 0.1),0px 14px 21px 2px rgba(0, 0, 0, 0.04),0px 5px 26px 4px rgba(0, 0, 0, 0.02)","0px 8px 9px -5px rgba(0, 0, 0, 0.1),0px 15px 22px 2px rgba(0, 0, 0, 0.04),0px 6px 28px 5px rgba(0, 0, 0, 0.02)","0px 8px 10px -5px rgba(0, 0, 0, 0.1),0px 16px 24px 2px rgba(0, 0, 0, 0.04),0px 6px 30px 5px rgba(0, 0, 0, 0.02)","0px 8px 11px -5px rgba(0, 0, 0, 0.1),0px 17px 26px 2px rgba(0, 0, 0, 0.04),0px 6px 32px 5px rgba(0, 0, 0, 0.02)","0px 9px 11px -5px rgba(0, 0, 0, 0.1),0px 18px 28px 2px rgba(0, 0, 0, 0.04),0px 7px 34px 6px rgba(0, 0, 0, 0.02)","0px 9px 12px -6px rgba(0, 0, 0, 0.1),0px 19px 29px 2px rgba(0, 0, 0, 0.04),0px 7px 36px 6px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 20px 31px 3px rgba(0, 0, 0, 0.04),0px 8px 38px 7px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 21px 33px 3px rgba(0, 0, 0, 0.04),0px 8px 40px 7px rgba(0, 0, 0, 0.02)","0px 10px 14px -6px rgba(0, 0, 0, 0.1),0px 22px 35px 3px rgba(0, 0, 0, 0.04),0px 8px 42px 7px rgba(0, 0, 0, 0.02)","0px 11px 14px -7px rgba(0, 0, 0, 0.1),0px 23px 36px 3px rgba(0, 0, 0, 0.04),0px 9px 44px 8px rgba(0, 0, 0, 0.02)","0px 11px 15px -7px rgba(0, 0, 0, 0.1),0px 24px 38px 3px rgba(0, 0, 0, 0.04),0px 9px 46px 8px rgba(0, 0, 0, 0.02)",]},u=(0,i.createMuiTheme)(s)},66289(e,t,n){"use strict";function r(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function a(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&f(i,n.prototype),i}).apply(null,arguments)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}function c(e){return -1!==Function.toString.call(e).indexOf("[native code]")}function l(e,t){return t&&("object"===p(t)||"function"==typeof t)?t:r(e)}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{V0:()=>B,_7:()=>v});var d,h,p=function(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};function b(e){var t="function"==typeof Map?new Map:void 0;return(b=function(e){if(null===e||!c(e))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return o(e,arguments,s(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,e)})(e)}function m(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}function g(e){var t=m();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}var v=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"AuthenticationError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e},],r}return n}(b(Error)),y=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"BadRequestError")).errors=a,r}return n}(b(Error)),w=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnprocessableEntityError")).errors=e,r}return n}(b(Error)),_=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"ServerError")).errors=e,r}return n}(b(Error)),E=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"ConflictError")).errors=a,r}return n}(b(Error)),S=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnknownResponseError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e.statusText},],r}return n}(b(Error));function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2e4;return Promise.race([fetch(e,t),new Promise(function(e,t){return setTimeout(function(){return t(Error("timeout"))},n)}),])}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=200&&e.status<300))return[3,2];return[2,e.json()];case 2:if(400!==e.status)return[3,3];return[2,e.json().then(function(e){throw new y(e)})];case 3:if(401!==e.status)return[3,4];throw new v(e);case 4:if(422!==e.status)return[3,6];return[4,$(e)];case 5:throw n=i.sent(),new w(n);case 6:if(409!==e.status)return[3,7];return[2,e.json().then(function(e){throw new E(e)})];case 7:if(!(e.status>=500))return[3,9];return[4,$(e)];case 8:throw r=i.sent(),new _(r);case 9:throw new S(e);case 10:return[2]}})})).apply(this,arguments)}function $(e){return z.apply(this,arguments)}function z(){return(z=j(function(e){return Y(this,function(t){return[2,e.json().then(function(t){return t.errors?t.errors.map(function(t){return{status:e.status,detail:t.detail}}):G(e)}).catch(function(){return G(e)})]})})).apply(this,arguments)}function G(e){return[{status:e.status,detail:e.statusText},]}},50109(e,t,n){"use strict";n.d(t,{LK:()=>o,U2:()=>i,eT:()=>s,t8:()=>a});var r=n(12795);function i(e){return r.ZP.getItem("chainlink.".concat(e))}function a(e,t){r.ZP.setItem("chainlink.".concat(e),t)}function o(e){var t=i(e),n={};if(t)try{return JSON.parse(t)}catch(r){}return n}function s(e,t){a(e,JSON.stringify(t))}},9541(e,t,n){"use strict";n.d(t,{Ks:()=>u,Tp:()=>a,iR:()=>o,pm:()=>s});var r=n(50109),i="persistURL";function a(){return r.U2(i)||""}function o(e){r.t8(i,e)}function s(){return r.LK("authentication")}function u(e){r.eT("authentication",e)}},67121(e,t,n){"use strict";function r(e){var t,n=e.Symbol;return"function"==typeof n?n.observable?t=n.observable:(t=n("observable"),n.observable=t):t="@@observable",t}n.r(t),n.d(t,{default:()=>o}),e=n.hmd(e),i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:e;var i,a=r(i);let o=a},2177(e,t,n){"use strict";n.d(t,{Z:()=>o});var r=!0,i="Invariant failed";function a(e,t){if(!e){if(r)throw Error(i);throw Error(i+": "+(t||""))}}let o=a},11742(e){e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;ru,ZT:()=>i,_T:()=>o,ev:()=>c,mG:()=>s,pi:()=>a});var r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)};function i(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(n[r[i]]=e[r[i]]);return n}function s(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,a){function o(e){try{u(r.next(e))}catch(t){a(t)}}function s(e){try{u(r.throw(e))}catch(t){a(t)}}function u(e){e.done?n(e.value):i(e.value).then(o,s)}u((r=r.apply(e,t||[])).next())})}function u(e,t){var n,r,i,a,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(e){return function(t){return u([e,t])}}function u(a){if(n)throw TypeError("Generator is already executing.");for(;o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!(i=(i=o.trys).length>0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]r})},94927(e,t,n){function r(e,t){if(i("noDeprecation"))return e;var n=!1;function r(){if(!n){if(i("throwDeprecation"))throw Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}return r}function i(e){try{if(!n.g.localStorage)return!1}catch(t){return!1}var r=n.g.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=r},42473(e){"use strict";var t=function(){};e.exports=t},84763(e){e.exports=Worker},47529(e){e.exports=n;var t=Object.prototype.hasOwnProperty;function n(){for(var e={},n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},7071(e){function t(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},94993(e,t,n){var r=n(18698).default,i=n(66115);function a(e,t){if(t&&("object"===r(t)||"function"==typeof t))return t;if(void 0!==t)throw TypeError("Derived constructors may only return object or undefined");return i(e)}e.exports=a,e.exports.__esModule=!0,e.exports.default=e.exports},6015(e){function t(n,r){return e.exports=t=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n,r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},861(e,t,n){var r=n(63405),i=n(79498),a=n(86116),o=n(42281);function s(e){return r(e)||i(e)||a(e)||o()}e.exports=s,e.exports.__esModule=!0,e.exports.default=e.exports},18698(e){function t(n){return e.exports=t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},86116(e,t,n){var r=n(73897);function i(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},1644(e,t,n){"use strict";var r,i;function a(e){return!!e&&e<7}n.d(t,{I:()=>r,O:()=>a}),(i=r||(r={}))[i.loading=1]="loading",i[i.setVariables=2]="setVariables",i[i.fetchMore=3]="fetchMore",i[i.refetch=4]="refetch",i[i.poll=6]="poll",i[i.ready=7]="ready",i[i.error=8]="error"},30990(e,t,n){"use strict";n.d(t,{MS:()=>s,YG:()=>a,cA:()=>c,ls:()=>o});var r=n(70655);n(83952);var i=n(13154),a=Symbol();function o(e){return!!e.extensions&&Array.isArray(e.extensions[a])}function s(e){return e.hasOwnProperty("graphQLErrors")}var u=function(e){var t=(0,r.ev)((0,r.ev)((0,r.ev)([],e.graphQLErrors,!0),e.clientErrors,!0),e.protocolErrors,!0);return e.networkError&&t.push(e.networkError),t.map(function(e){return(0,i.s)(e)&&e.message||"Error message not found."}).join("\n")},c=function(e){function t(n){var r=n.graphQLErrors,i=n.protocolErrors,a=n.clientErrors,o=n.networkError,s=n.errorMessage,c=n.extraInfo,l=e.call(this,s)||this;return l.name="ApolloError",l.graphQLErrors=r||[],l.protocolErrors=i||[],l.clientErrors=a||[],l.networkError=o||null,l.message=s||u(l),l.extraInfo=c,l.__proto__=t.prototype,l}return(0,r.ZT)(t,e),t}(Error)},85317(e,t,n){"use strict";n.d(t,{K:()=>a});var r=n(67294),i=n(30320).aS?Symbol.for("__APOLLO_CONTEXT__"):"__APOLLO_CONTEXT__";function a(){var e=r.createContext[i];return e||(Object.defineProperty(r.createContext,i,{value:e=r.createContext({}),enumerable:!1,writable:!1,configurable:!0}),e.displayName="ApolloContext"),e}},21436(e,t,n){"use strict";n.d(t,{O:()=>i,k:()=>r});var r=Array.isArray;function i(e){return Array.isArray(e)&&e.length>0}},30320(e,t,n){"use strict";n.d(t,{DN:()=>s,JC:()=>l,aS:()=>o,mr:()=>i,sy:()=>a});var r=n(83952),i="function"==typeof WeakMap&&"ReactNative"!==(0,r.wY)(function(){return navigator.product}),a="function"==typeof WeakSet,o="function"==typeof Symbol&&"function"==typeof Symbol.for,s=o&&Symbol.asyncIterator,u="function"==typeof(0,r.wY)(function(){return window.document.createElement}),c=(0,r.wY)(function(){return navigator.userAgent.indexOf("jsdom")>=0})||!1,l=u&&!c},53712(e,t,n){"use strict";function r(){for(var e=[],t=0;tr})},10542(e,t,n){"use strict";n.d(t,{J:()=>o}),n(83952);var r=n(13154);function i(e){var t=new Set([e]);return t.forEach(function(e){(0,r.s)(e)&&a(e)===e&&Object.getOwnPropertyNames(e).forEach(function(n){(0,r.s)(e[n])&&t.add(e[n])})}),e}function a(e){if(__DEV__&&!Object.isFrozen(e))try{Object.freeze(e)}catch(t){if(t instanceof TypeError)return null;throw t}return e}function o(e){return __DEV__&&i(e),e}},14012(e,t,n){"use strict";n.d(t,{J:()=>a});var r=n(70655),i=n(53712);function a(e,t){return(0,i.o)(e,t,t.variables&&{variables:(0,r.pi)((0,r.pi)({},e&&e.variables),t.variables)})}},13154(e,t,n){"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{s:()=>r})},83952(e,t,n){"use strict";n.d(t,{ej:()=>u,kG:()=>c,wY:()=>h});var r,i=n(70655),a="Invariant Violation",o=Object.setPrototypeOf,s=void 0===o?function(e,t){return e.__proto__=t,e}:o,u=function(e){function t(n){void 0===n&&(n=a);var r=e.call(this,"number"==typeof n?a+": "+n+" (see https://github.com/apollographql/invariant-packages)":n)||this;return r.framesToPop=1,r.name=a,s(r,t.prototype),r}return(0,i.ZT)(t,e),t}(Error);function c(e,t){if(!e)throw new u(t)}var l=["debug","log","warn","error","silent"],f=l.indexOf("log");function d(e){return function(){if(l.indexOf(e)>=f)return(console[e]||console.log).apply(console,arguments)}}function h(e){try{return e()}catch(t){}}(r=c||(c={})).debug=d("debug"),r.log=d("log"),r.warn=d("warn"),r.error=d("error");let p=h(function(){return globalThis})||h(function(){return window})||h(function(){return self})||h(function(){return global})||h(function(){return h.constructor("return this")()});var b="__",m=[b,b].join("DEV");function g(){try{return Boolean(__DEV__)}catch(e){return Object.defineProperty(p,m,{value:"production"!==h(function(){return"production"}),enumerable:!1,configurable:!0,writable:!0}),p[m]}}let v=g();function y(e){try{return e()}catch(t){}}var w=y(function(){return globalThis})||y(function(){return window})||y(function(){return self})||y(function(){return global})||y(function(){return y.constructor("return this")()}),_=!1;function E(){!w||y(function(){return"production"})||y(function(){return process})||(Object.defineProperty(w,"process",{value:{env:{NODE_ENV:"production"}},configurable:!0,enumerable:!1,writable:!0}),_=!0)}function S(){_&&(delete w.process,_=!1)}E();var k=n(10143);function x(){return k.H,S()}function T(){__DEV__?c("boolean"==typeof v,v):c("boolean"==typeof v,39)}x(),T()},4942(e,t,n){"use strict";function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}n.d(t,{Z:()=>r})},87462(e,t,n){"use strict";function r(){return(r=Object.assign?Object.assign.bind():function(e){for(var t=1;tr})},51721(e,t,n){"use strict";function r(e,t){return(r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e})(e,t)}function i(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>i})},63366(e,t,n){"use strict";function r(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}n.d(t,{Z:()=>r})},25821(e,t,n){"use strict";n.d(t,{Z:()=>s});var r=n(45695);function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=10,o=2;function s(e){return u(e,[])}function u(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":if(null===e)return"null";return c(e,t);default:return String(e)}}function c(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=d(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:u(i,n)}else if(Array.isArray(e))return f(e,n);return l(e,n)}function l(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>o?"["+h(e)+"]":"{ "+n.map(function(n){var r=u(e[n],t);return n+": "+r}).join(", ")+" }"}function f(e,t){if(0===e.length)return"[]";if(t.length>o)return"[Array]";for(var n=Math.min(a,e.length),r=e.length-n,i=[],s=0;s1&&i.push("... ".concat(r," more items")),"["+i.join(", ")+"]"}function d(e){var t=e[String(r.Z)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}function h(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}},45695(e,t,n){"use strict";n.d(t,{Z:()=>i});var r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;let i=r},25217(e,t,n){"use strict";function r(e,t){if(!Boolean(e))throw Error(null!=t?t:"Unexpected invariant triggered.")}n.d(t,{Ye:()=>o,WU:()=>s,UG:()=>u});var i=n(45695);function a(e){var t=e.prototype.toJSON;"function"==typeof t||r(0),e.prototype.inspect=t,i.Z&&(e.prototype[i.Z]=t)}var o=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();a(o);var s=function(){function e(e,t,n,r,i,a,o){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=i,this.value=o,this.prev=a,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();function u(e){return null!=e&&"string"==typeof e.kind}a(s)},87392(e,t,n){"use strict";function r(e){var t=e.split(/\r\n|[\n\r]/g),n=a(e);if(0!==n)for(var r=1;ro&&i(t[s-1]);)--s;return t.slice(o,s).join("\n")}function i(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),i=" "===e[0]||" "===e[0],a='"'===e[e.length-1],o="\\"===e[e.length-1],s=!r||a||o||n,u="";return s&&!(r&&i)&&(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}n.d(t,{LZ:()=>o,W7:()=>r})},97359(e,t,n){"use strict";n.d(t,{h:()=>r});var r=Object.freeze({NAME:"Name",DOCUMENT:"Document",OPERATION_DEFINITION:"OperationDefinition",VARIABLE_DEFINITION:"VariableDefinition",SELECTION_SET:"SelectionSet",FIELD:"Field",ARGUMENT:"Argument",FRAGMENT_SPREAD:"FragmentSpread",INLINE_FRAGMENT:"InlineFragment",FRAGMENT_DEFINITION:"FragmentDefinition",VARIABLE:"Variable",INT:"IntValue",FLOAT:"FloatValue",STRING:"StringValue",BOOLEAN:"BooleanValue",NULL:"NullValue",ENUM:"EnumValue",LIST:"ListValue",OBJECT:"ObjectValue",OBJECT_FIELD:"ObjectField",DIRECTIVE:"Directive",NAMED_TYPE:"NamedType",LIST_TYPE:"ListType",NON_NULL_TYPE:"NonNullType",SCHEMA_DEFINITION:"SchemaDefinition",OPERATION_TYPE_DEFINITION:"OperationTypeDefinition",SCALAR_TYPE_DEFINITION:"ScalarTypeDefinition",OBJECT_TYPE_DEFINITION:"ObjectTypeDefinition",FIELD_DEFINITION:"FieldDefinition",INPUT_VALUE_DEFINITION:"InputValueDefinition",INTERFACE_TYPE_DEFINITION:"InterfaceTypeDefinition",UNION_TYPE_DEFINITION:"UnionTypeDefinition",ENUM_TYPE_DEFINITION:"EnumTypeDefinition",ENUM_VALUE_DEFINITION:"EnumValueDefinition",INPUT_OBJECT_TYPE_DEFINITION:"InputObjectTypeDefinition",DIRECTIVE_DEFINITION:"DirectiveDefinition",SCHEMA_EXTENSION:"SchemaExtension",SCALAR_TYPE_EXTENSION:"ScalarTypeExtension",OBJECT_TYPE_EXTENSION:"ObjectTypeExtension",INTERFACE_TYPE_EXTENSION:"InterfaceTypeExtension",UNION_TYPE_EXTENSION:"UnionTypeExtension",ENUM_TYPE_EXTENSION:"EnumTypeExtension",INPUT_OBJECT_TYPE_EXTENSION:"InputObjectTypeExtension"})},10143(e,t,n){"use strict";n.d(t,{H:()=>c,T:()=>l});var r=n(99763),i=n(25821);function a(e,t){if(!Boolean(e))throw Error(t)}let o=function(e,t){return e instanceof t};function s(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||a(0,"Body must be a string. Received: ".concat((0,i.Z)(e),".")),this.body=e,this.name=t,this.locationOffset=n,this.locationOffset.line>0||a(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||a(0,"column in locationOffset is 1-indexed and must be positive.")}return u(e,[{key:r.YF,get:function(){return"Source"}}]),e}();function l(e){return o(e,c)}},99763(e,t,n){"use strict";n.d(t,{YF:()=>r});var r="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag"},37452(e){"use strict";e.exports=JSON.parse('{"AElig":"\xc6","AMP":"&","Aacute":"\xc1","Acirc":"\xc2","Agrave":"\xc0","Aring":"\xc5","Atilde":"\xc3","Auml":"\xc4","COPY":"\xa9","Ccedil":"\xc7","ETH":"\xd0","Eacute":"\xc9","Ecirc":"\xca","Egrave":"\xc8","Euml":"\xcb","GT":">","Iacute":"\xcd","Icirc":"\xce","Igrave":"\xcc","Iuml":"\xcf","LT":"<","Ntilde":"\xd1","Oacute":"\xd3","Ocirc":"\xd4","Ograve":"\xd2","Oslash":"\xd8","Otilde":"\xd5","Ouml":"\xd6","QUOT":"\\"","REG":"\xae","THORN":"\xde","Uacute":"\xda","Ucirc":"\xdb","Ugrave":"\xd9","Uuml":"\xdc","Yacute":"\xdd","aacute":"\xe1","acirc":"\xe2","acute":"\xb4","aelig":"\xe6","agrave":"\xe0","amp":"&","aring":"\xe5","atilde":"\xe3","auml":"\xe4","brvbar":"\xa6","ccedil":"\xe7","cedil":"\xb8","cent":"\xa2","copy":"\xa9","curren":"\xa4","deg":"\xb0","divide":"\xf7","eacute":"\xe9","ecirc":"\xea","egrave":"\xe8","eth":"\xf0","euml":"\xeb","frac12":"\xbd","frac14":"\xbc","frac34":"\xbe","gt":">","iacute":"\xed","icirc":"\xee","iexcl":"\xa1","igrave":"\xec","iquest":"\xbf","iuml":"\xef","laquo":"\xab","lt":"<","macr":"\xaf","micro":"\xb5","middot":"\xb7","nbsp":"\xa0","not":"\xac","ntilde":"\xf1","oacute":"\xf3","ocirc":"\xf4","ograve":"\xf2","ordf":"\xaa","ordm":"\xba","oslash":"\xf8","otilde":"\xf5","ouml":"\xf6","para":"\xb6","plusmn":"\xb1","pound":"\xa3","quot":"\\"","raquo":"\xbb","reg":"\xae","sect":"\xa7","shy":"\xad","sup1":"\xb9","sup2":"\xb2","sup3":"\xb3","szlig":"\xdf","thorn":"\xfe","times":"\xd7","uacute":"\xfa","ucirc":"\xfb","ugrave":"\xf9","uml":"\xa8","uuml":"\xfc","yacute":"\xfd","yen":"\xa5","yuml":"\xff"}')},93580(e){"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},67946(e){"use strict";e.exports=JSON.parse('{"locale":"en","long":{"year":{"previous":"last year","current":"this year","next":"next year","past":{"one":"{0} year ago","other":"{0} years ago"},"future":{"one":"in {0} year","other":"in {0} years"}},"quarter":{"previous":"last quarter","current":"this quarter","next":"next quarter","past":{"one":"{0} quarter ago","other":"{0} quarters ago"},"future":{"one":"in {0} quarter","other":"in {0} quarters"}},"month":{"previous":"last month","current":"this month","next":"next month","past":{"one":"{0} month ago","other":"{0} months ago"},"future":{"one":"in {0} month","other":"in {0} months"}},"week":{"previous":"last week","current":"this week","next":"next week","past":{"one":"{0} week ago","other":"{0} weeks ago"},"future":{"one":"in {0} week","other":"in {0} weeks"}},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":{"one":"{0} hour ago","other":"{0} hours ago"},"future":{"one":"in {0} hour","other":"in {0} hours"}},"minute":{"current":"this minute","past":{"one":"{0} minute ago","other":"{0} minutes ago"},"future":{"one":"in {0} minute","other":"in {0} minutes"}},"second":{"current":"now","past":{"one":"{0} second ago","other":"{0} seconds ago"},"future":{"one":"in {0} second","other":"in {0} seconds"}}},"short":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"narrow":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"now":{"now":{"current":"now","future":"in a moment","past":"just now"}},"mini":{"year":"{0}yr","month":"{0}mo","week":"{0}wk","day":"{0}d","hour":"{0}h","minute":"{0}m","second":"{0}s","now":"now"},"short-time":{"year":"{0} yr.","month":"{0} mo.","week":"{0} wk.","day":{"one":"{0} day","other":"{0} days"},"hour":"{0} hr.","minute":"{0} min.","second":"{0} sec."},"long-time":{"year":{"one":"{0} year","other":"{0} years"},"month":{"one":"{0} month","other":"{0} months"},"week":{"one":"{0} week","other":"{0} weeks"},"day":{"one":"{0} day","other":"{0} days"},"hour":{"one":"{0} hour","other":"{0} hours"},"minute":{"one":"{0} minute","other":"{0} minutes"},"second":{"one":"{0} second","other":"{0} seconds"}}}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;__webpack_require__.t=function(n,r){if(1&r&&(n=this(n)),8&r||"object"==typeof n&&n&&(4&r&&n.__esModule||16&r&&"function"==typeof n.then))return n;var i=Object.create(null);__webpack_require__.r(i);var a={};e=e||[null,t({}),t([]),t(t)];for(var o=2&r&&n;"object"==typeof o&&!~e.indexOf(o);o=t(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,__webpack_require__.d(i,a),i}})(),__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set(){throw Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__.p="/assets/",__webpack_require__.nc=void 0;var __webpack_exports__={};(()=>{"use strict";var e,t,n,r,i=__webpack_require__(32316),a=__webpack_require__(8126),o=__webpack_require__(5690),s=__webpack_require__(30381),u=__webpack_require__.n(s),c=__webpack_require__(67294),l=__webpack_require__(73935),f=__webpack_require__.n(l),d=__webpack_require__(57209),h=__webpack_require__(37703),p=__webpack_require__(97779),b=__webpack_require__(28500);function m(e){return function(t){var n=t.dispatch,r=t.getState;return function(t){return function(i){return"function"==typeof i?i(n,r,e):t(i)}}}}var g=m();g.withExtraArgument=m;let v=g;var y=__webpack_require__(76489);function w(e){return function(t){return function(n){return function(r){n(r);var i=e||document&&document.cookie||"",a=t.getState();if("MATCH_ROUTE"===r.type&&"/signin"!==a.notifications.currentUrl){var o=(0,y.Q)(i);if(o.explorer)try{var s=JSON.parse(o.explorer);if("error"===s.status){var u=_(s.url);n({type:"NOTIFY_ERROR_MSG",msg:u})}}catch(c){n({type:"NOTIFY_ERROR_MSG",msg:"Invalid explorer status"})}}}}}}function _(e){var t="Can't connect to explorer: ".concat(e);return e.match(/^wss?:.+/)?t:"".concat(t,". You must use a websocket.")}var E=__webpack_require__(16353);function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ei(e,t){if(e){if("string"==typeof e)return ea(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ea(e,t)}}function ea(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1,i=!1,a=arguments[1],o=a;return new n(function(n){return t.subscribe({next:function(t){var a=!i;if(i=!0,!a||r)try{o=e(o,t)}catch(s){return n.error(s)}else o=t},error:function(e){n.error(e)},complete:function(){if(!i&&!r)return n.error(TypeError("Cannot reduce an empty sequence"));n.next(o),n.complete()}})})},t.concat=function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r=0&&i.splice(e,1),o()}});i.push(s)},error:function(e){r.error(e)},complete:function(){o()}});function o(){a.closed&&0===i.length&&r.complete()}return function(){i.forEach(function(e){return e.unsubscribe()}),a.unsubscribe()}})},t[ed]=function(){return this},e.from=function(t){var n="function"==typeof this?this:e;if(null==t)throw TypeError(t+" is not an object");var r=ep(t,ed);if(r){var i=r.call(t);if(Object(i)!==i)throw TypeError(i+" is not an object");return em(i)&&i.constructor===n?i:new n(function(e){return i.subscribe(e)})}if(ec("iterator")&&(r=ep(t,ef)))return new n(function(e){ev(function(){if(!e.closed){for(var n,i=er(r.call(t));!(n=i()).done;){var a=n.value;if(e.next(a),e.closed)return}e.complete()}})});if(Array.isArray(t))return new n(function(e){ev(function(){if(!e.closed){for(var n=0;n0))return n.connection.key;var r=n.connection.filter?n.connection.filter:[];r.sort();var i={};return r.forEach(function(e){i[e]=t[e]}),"".concat(n.connection.key,"(").concat(eV(i),")")}var a=e;if(t){var o=eV(t);a+="(".concat(o,")")}return n&&Object.keys(n).forEach(function(e){-1===eW.indexOf(e)&&(n[e]&&Object.keys(n[e]).length?a+="@".concat(e,"(").concat(eV(n[e]),")"):a+="@".concat(e))}),a},{setStringify:function(e){var t=eV;return eV=e,t}}),eV=function(e){return JSON.stringify(e,eq)};function eq(e,t){return(0,eO.s)(t)&&!Array.isArray(t)&&(t=Object.keys(t).sort().reduce(function(e,n){return e[n]=t[n],e},{})),t}function eZ(e,t){if(e.arguments&&e.arguments.length){var n={};return e.arguments.forEach(function(e){var r;return ez(n,e.name,e.value,t)}),n}return null}function eX(e){return e.alias?e.alias.value:e.name.value}function eJ(e,t,n){for(var r,i=0,a=t.selections;it.indexOf(i))throw __DEV__?new Q.ej("illegal argument: ".concat(i)):new Q.ej(27)}return e}function tt(e,t){return t?t(e):eT.of()}function tn(e){return"function"==typeof e?new ta(e):e}function tr(e){return e.request.length<=1}var ti=function(e){function t(t,n){var r=e.call(this,t)||this;return r.link=n,r}return(0,en.ZT)(t,e),t}(Error),ta=function(){function e(e){e&&(this.request=e)}return e.empty=function(){return new e(function(){return eT.of()})},e.from=function(t){return 0===t.length?e.empty():t.map(tn).reduce(function(e,t){return e.concat(t)})},e.split=function(t,n,r){var i=tn(n),a=tn(r||new e(tt));return new e(tr(i)&&tr(a)?function(e){return t(e)?i.request(e)||eT.of():a.request(e)||eT.of()}:function(e,n){return t(e)?i.request(e,n)||eT.of():a.request(e,n)||eT.of()})},e.execute=function(e,t){return e.request(eM(t.context,e7(te(t))))||eT.of()},e.concat=function(t,n){var r=tn(t);if(tr(r))return __DEV__&&Q.kG.warn(new ti("You are calling concat on a terminating link, which will have no effect",r)),r;var i=tn(n);return new e(tr(i)?function(e){return r.request(e,function(e){return i.request(e)||eT.of()})||eT.of()}:function(e,t){return r.request(e,function(e){return i.request(e,t)||eT.of()})||eT.of()})},e.prototype.split=function(t,n,r){return this.concat(e.split(t,n,r||new e(tt)))},e.prototype.concat=function(t){return e.concat(this,t)},e.prototype.request=function(e,t){throw __DEV__?new Q.ej("request is not implemented"):new Q.ej(22)},e.prototype.onError=function(e,t){if(t&&t.error)return t.error(e),!1;throw e},e.prototype.setOnError=function(e){return this.onError=e,this},e}(),to=__webpack_require__(25821),ts=__webpack_require__(25217),tu={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},tc=Object.freeze({});function tl(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:tu,r=void 0,i=Array.isArray(e),a=[e],o=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],d=[],h=e;do{var p,b=++o===a.length,m=b&&0!==s.length;if(b){if(c=0===d.length?void 0:f[f.length-1],u=l,l=d.pop(),m){if(i)u=u.slice();else{for(var g={},v=0,y=Object.keys(u);v1)for(var r=new tB,i=1;i=0;--a){var o=i[a],s=isNaN(+o)?{}:[];s[o]=t,t=s}n=r.merge(n,t)}),n}var tW=Object.prototype.hasOwnProperty;function tK(e,t){var n,r,i,a,o;return(0,en.mG)(this,void 0,void 0,function(){var s,u,c,l,f,d,h,p,b,m,g,v,y,w,_,E,S,k,x,T,M,O,A;return(0,en.Jh)(this,function(L){switch(L.label){case 0:if(void 0===TextDecoder)throw Error("TextDecoder must be defined in the environment: please import a polyfill.");s=new TextDecoder("utf-8"),u=null===(n=e.headers)||void 0===n?void 0:n.get("content-type"),c="boundary=",l=(null==u?void 0:u.includes(c))?null==u?void 0:u.substring((null==u?void 0:u.indexOf(c))+c.length).replace(/['"]/g,"").replace(/\;(.*)/gm,"").trim():"-",f="\r\n--".concat(l),d="",h=tI(e),p=!0,L.label=1;case 1:if(!p)return[3,3];return[4,h.next()];case 2:for(m=(b=L.sent()).value,g=b.done,v="string"==typeof m?m:s.decode(m),y=d.length-f.length+1,p=!g,d+=v,w=d.indexOf(f,y);w>-1;){if(_=void 0,_=(O=[d.slice(0,w),d.slice(w+f.length),])[0],d=O[1],E=_.indexOf("\r\n\r\n"),(k=(S=tV(_.slice(0,E)))["content-type"])&&-1===k.toLowerCase().indexOf("application/json"))throw Error("Unsupported patch content type: application/json is required.");if(x=_.slice(E))try{T=tq(e,x),Object.keys(T).length>1||"data"in T||"incremental"in T||"errors"in T||"payload"in T?tz(T)?(M={},"payload"in T&&(M=(0,en.pi)({},T.payload)),"errors"in T&&(M=(0,en.pi)((0,en.pi)({},M),{extensions:(0,en.pi)((0,en.pi)({},"extensions"in M?M.extensions:null),((A={})[tN.YG]=T.errors,A))})),null===(r=t.next)||void 0===r||r.call(t,M)):null===(i=t.next)||void 0===i||i.call(t,T):1===Object.keys(T).length&&"hasNext"in T&&!T.hasNext&&(null===(a=t.complete)||void 0===a||a.call(t))}catch(C){tZ(C,t)}w=d.indexOf(f)}return[3,1];case 3:return null===(o=t.complete)||void 0===o||o.call(t),[2]}})})}function tV(e){var t={};return e.split("\n").forEach(function(e){var n=e.indexOf(":");if(n>-1){var r=e.slice(0,n).trim().toLowerCase(),i=e.slice(n+1).trim();t[r]=i}}),t}function tq(e,t){e.status>=300&&tD(e,function(){try{return JSON.parse(t)}catch(e){return t}}(),"Response not successful: Received status code ".concat(e.status));try{return JSON.parse(t)}catch(n){var r=n;throw r.name="ServerParseError",r.response=e,r.statusCode=e.status,r.bodyText=t,r}}function tZ(e,t){var n,r;"AbortError"!==e.name&&(e.result&&e.result.errors&&e.result.data&&(null===(n=t.next)||void 0===n||n.call(t,e.result)),null===(r=t.error)||void 0===r||r.call(t,e))}function tX(e,t,n){tJ(t)(e).then(function(e){var t,r;null===(t=n.next)||void 0===t||t.call(n,e),null===(r=n.complete)||void 0===r||r.call(n)}).catch(function(e){return tZ(e,n)})}function tJ(e){return function(t){return t.text().then(function(e){return tq(t,e)}).then(function(n){return t.status>=300&&tD(t,n,"Response not successful: Received status code ".concat(t.status)),Array.isArray(n)||tW.call(n,"data")||tW.call(n,"errors")||tD(t,n,"Server response was missing for query '".concat(Array.isArray(e)?e.map(function(e){return e.operationName}):e.operationName,"'.")),n})}}var tQ=function(e){if(!e&&"undefined"==typeof fetch)throw __DEV__?new Q.ej("\n\"fetch\" has not been found globally and no fetcher has been configured. To fix this, install a fetch package (like https://www.npmjs.com/package/cross-fetch), instantiate the fetcher, and pass it into your HttpLink constructor. For example:\n\nimport fetch from 'cross-fetch';\nimport { ApolloClient, HttpLink } from '@apollo/client';\nconst client = new ApolloClient({\n link: new HttpLink({ uri: '/graphql', fetch })\n});\n "):new Q.ej(23)},t1=__webpack_require__(87392);function t0(e){return tl(e,{leave:t3})}var t2=80,t3={Name:function(e){return e.value},Variable:function(e){return"$"+e.name},Document:function(e){return t6(e.definitions,"\n\n")+"\n"},OperationDefinition:function(e){var t=e.operation,n=e.name,r=t8("(",t6(e.variableDefinitions,", "),")"),i=t6(e.directives," "),a=e.selectionSet;return n||i||r||"query"!==t?t6([t,t6([n,r]),i,a]," "):a},VariableDefinition:function(e){var t=e.variable,n=e.type,r=e.defaultValue,i=e.directives;return t+": "+n+t8(" = ",r)+t8(" ",t6(i," "))},SelectionSet:function(e){return t5(e.selections)},Field:function(e){var t=e.alias,n=e.name,r=e.arguments,i=e.directives,a=e.selectionSet,o=t8("",t,": ")+n,s=o+t8("(",t6(r,", "),")");return s.length>t2&&(s=o+t8("(\n",t9(t6(r,"\n")),"\n)")),t6([s,t6(i," "),a]," ")},Argument:function(e){var t;return e.name+": "+e.value},FragmentSpread:function(e){var t;return"..."+e.name+t8(" ",t6(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,n=e.directives,r=e.selectionSet;return t6(["...",t8("on ",t),t6(n," "),r]," ")},FragmentDefinition:function(e){var t=e.name,n=e.typeCondition,r=e.variableDefinitions,i=e.directives,a=e.selectionSet;return"fragment ".concat(t).concat(t8("(",t6(r,", "),")")," ")+"on ".concat(n," ").concat(t8("",t6(i," ")," "))+a},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var n=e.value;return e.block?(0,t1.LZ)(n,"description"===t?"":" "):JSON.stringify(n)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+t6(e.values,", ")+"]"},ObjectValue:function(e){return"{"+t6(e.fields,", ")+"}"},ObjectField:function(e){var t;return e.name+": "+e.value},Directive:function(e){var t;return"@"+e.name+t8("(",t6(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:t4(function(e){var t=e.directives,n=e.operationTypes;return t6(["schema",t6(t," "),t5(n)]," ")}),OperationTypeDefinition:function(e){var t;return e.operation+": "+e.type},ScalarTypeDefinition:t4(function(e){var t;return t6(["scalar",e.name,t6(e.directives," ")]," ")}),ObjectTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),FieldDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.type,i=e.directives;return t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+": "+r+t8(" ",t6(i," "))}),InputValueDefinition:t4(function(e){var t=e.name,n=e.type,r=e.defaultValue,i=e.directives;return t6([t+": "+n,t8("= ",r),t6(i," ")]," ")}),InterfaceTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),UnionTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.types;return t6(["union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")}),EnumTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.values;return t6(["enum",t,t6(n," "),t5(r)]," ")}),EnumValueDefinition:t4(function(e){var t;return t6([e.name,t6(e.directives," ")]," ")}),InputObjectTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["input",t,t6(n," "),t5(r)]," ")}),DirectiveDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.repeatable,i=e.locations;return"directive @"+t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+(r?" repeatable":"")+" on "+t6(i," | ")}),SchemaExtension:function(e){var t=e.directives,n=e.operationTypes;return t6(["extend schema",t6(t," "),t5(n)]," ")},ScalarTypeExtension:function(e){var t;return t6(["extend scalar",e.name,t6(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},InterfaceTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},UnionTypeExtension:function(e){var t=e.name,n=e.directives,r=e.types;return t6(["extend union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,n=e.directives,r=e.values;return t6(["extend enum",t,t6(n," "),t5(r)]," ")},InputObjectTypeExtension:function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["extend input",t,t6(n," "),t5(r)]," ")}};function t4(e){return function(t){return t6([t.description,e(t)],"\n")}}function t6(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter(function(e){return e}).join(n))&&void 0!==t?t:""}function t5(e){return t8("{\n",t9(t6(e,"\n")),"\n}")}function t8(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+n:""}function t9(e){return t8(" ",e.replace(/\n/g,"\n "))}function t7(e){return -1!==e.indexOf("\n")}function ne(e){return null!=e&&e.some(t7)}var nt,nn,nr,ni={http:{includeQuery:!0,includeExtensions:!1,preserveHeaderCase:!1},headers:{accept:"*/*","content-type":"application/json"},options:{method:"POST"}},na=function(e,t){return t(e)};function no(e,t){for(var n=[],r=2;rObject.create(null),{forEach:nv,slice:ny}=Array.prototype,{hasOwnProperty:nw}=Object.prototype;class n_{constructor(e=!0,t=ng){this.weakness=e,this.makeData=t}lookup(...e){return this.lookupArray(e)}lookupArray(e){let t=this;return nv.call(e,e=>t=t.getChildTrie(e)),nw.call(t,"data")?t.data:t.data=this.makeData(ny.call(e))}peek(...e){return this.peekArray(e)}peekArray(e){let t=this;for(let n=0,r=e.length;t&&n=0;--o)t.definitions[o].kind===nL.h.OPERATION_DEFINITION&&++a;var s=nN(e),u=e.some(function(e){return e.remove}),c=function(e){return u&&e&&e.some(s)},l=new Map,f=!1,d={enter:function(e){if(c(e.directives))return f=!0,null}},h=tl(t,{Field:d,InlineFragment:d,VariableDefinition:{enter:function(){return!1}},Variable:{enter:function(e,t,n,r,a){var o=i(a);o&&o.variables.add(e.name.value)}},FragmentSpread:{enter:function(e,t,n,r,a){if(c(e.directives))return f=!0,null;var o=i(a);o&&o.fragmentSpreads.add(e.name.value)}},FragmentDefinition:{enter:function(e,t,n,r){l.set(JSON.stringify(r),e)},leave:function(e,t,n,i){return e===l.get(JSON.stringify(i))?e:a>0&&e.selectionSet.selections.every(function(e){return e.kind===nL.h.FIELD&&"__typename"===e.name.value})?(r(e.name.value).removed=!0,f=!0,null):void 0}},Directive:{leave:function(e){if(s(e))return f=!0,null}}});if(!f)return t;var p=function(e){return e.transitiveVars||(e.transitiveVars=new Set(e.variables),e.removed||e.fragmentSpreads.forEach(function(t){p(r(t)).transitiveVars.forEach(function(t){e.transitiveVars.add(t)})})),e},b=new Set;h.definitions.forEach(function(e){e.kind===nL.h.OPERATION_DEFINITION?p(n(e.name&&e.name.value)).fragmentSpreads.forEach(function(e){b.add(e)}):e.kind!==nL.h.FRAGMENT_DEFINITION||0!==a||r(e.name.value).removed||b.add(e.name.value)}),b.forEach(function(e){p(r(e)).fragmentSpreads.forEach(function(e){b.add(e)})});var m=function(e){return!!(!b.has(e)||r(e).removed)},g={enter:function(e){if(m(e.name.value))return null}};return nD(tl(h,{FragmentSpread:g,FragmentDefinition:g,OperationDefinition:{leave:function(e){if(e.variableDefinitions){var t=p(n(e.name&&e.name.value)).transitiveVars;if(t.size0},t.prototype.tearDownQuery=function(){this.isTornDown||(this.concast&&this.observer&&(this.concast.removeObserver(this.observer),delete this.concast,delete this.observer),this.stopPolling(),this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions.clear(),this.queryManager.stopQuery(this.queryId),this.observers.clear(),this.isTornDown=!0)},t}(eT);function n4(e){var t=e.options,n=t.fetchPolicy,r=t.nextFetchPolicy;return"cache-and-network"===n||"network-only"===n?e.reobserve({fetchPolicy:"cache-first",nextFetchPolicy:function(){return(this.nextFetchPolicy=r,"function"==typeof r)?r.apply(this,arguments):n}}):e.reobserve()}function n6(e){__DEV__&&Q.kG.error("Unhandled error",e.message,e.stack)}function n5(e){__DEV__&&e&&__DEV__&&Q.kG.debug("Missing cache result fields: ".concat(JSON.stringify(e)),e)}function n8(e){return"network-only"===e||"no-cache"===e||"standby"===e}nK(n3);function n9(e){return e.kind===nL.h.FIELD||e.kind===nL.h.FRAGMENT_SPREAD||e.kind===nL.h.INLINE_FRAGMENT}function n7(e){return e.kind===Kind.SCALAR_TYPE_DEFINITION||e.kind===Kind.OBJECT_TYPE_DEFINITION||e.kind===Kind.INTERFACE_TYPE_DEFINITION||e.kind===Kind.UNION_TYPE_DEFINITION||e.kind===Kind.ENUM_TYPE_DEFINITION||e.kind===Kind.INPUT_OBJECT_TYPE_DEFINITION}function re(e){return e.kind===Kind.SCALAR_TYPE_EXTENSION||e.kind===Kind.OBJECT_TYPE_EXTENSION||e.kind===Kind.INTERFACE_TYPE_EXTENSION||e.kind===Kind.UNION_TYPE_EXTENSION||e.kind===Kind.ENUM_TYPE_EXTENSION||e.kind===Kind.INPUT_OBJECT_TYPE_EXTENSION}var rt=function(){return Object.create(null)},rn=Array.prototype,rr=rn.forEach,ri=rn.slice,ra=function(){function e(e,t){void 0===e&&(e=!0),void 0===t&&(t=rt),this.weakness=e,this.makeData=t}return e.prototype.lookup=function(){for(var e=[],t=0;tclass{constructor(){this.id=["slot",rc++,Date.now(),Math.random().toString(36).slice(2),].join(":")}hasValue(){for(let e=rs;e;e=e.parent)if(this.id in e.slots){let t=e.slots[this.id];if(t===ru)break;return e!==rs&&(rs.slots[this.id]=t),!0}return rs&&(rs.slots[this.id]=ru),!1}getValue(){if(this.hasValue())return rs.slots[this.id]}withValue(e,t,n,r){let i={__proto__:null,[this.id]:e},a=rs;rs={parent:a,slots:i};try{return t.apply(r,n)}finally{rs=a}}static bind(e){let t=rs;return function(){let n=rs;try{return rs=t,e.apply(this,arguments)}finally{rs=n}}}static noContext(e,t,n){if(!rs)return e.apply(n,t);{let r=rs;try{return rs=null,e.apply(n,t)}finally{rs=r}}}};function rf(e){try{return e()}catch(t){}}let rd="@wry/context:Slot",rh=rf(()=>globalThis)||rf(()=>global)||Object.create(null),rp=rh,rb=rp[rd]||Array[rd]||function(e){try{Object.defineProperty(rp,rd,{value:e,enumerable:!1,writable:!1,configurable:!0})}finally{return e}}(rl()),{bind:rm,noContext:rg}=rb;function rv(){}var ry=function(){function e(e,t){void 0===e&&(e=1/0),void 0===t&&(t=rv),this.max=e,this.dispose=t,this.map=new Map,this.newest=null,this.oldest=null}return e.prototype.has=function(e){return this.map.has(e)},e.prototype.get=function(e){var t=this.getNode(e);return t&&t.value},e.prototype.getNode=function(e){var t=this.map.get(e);if(t&&t!==this.newest){var n=t.older,r=t.newer;r&&(r.older=n),n&&(n.newer=r),t.older=this.newest,t.older.newer=t,t.newer=null,this.newest=t,t===this.oldest&&(this.oldest=r)}return t},e.prototype.set=function(e,t){var n=this.getNode(e);return n?n.value=t:(n={key:e,value:t,newer:null,older:this.newest},this.newest&&(this.newest.newer=n),this.newest=n,this.oldest=this.oldest||n,this.map.set(e,n),n.value)},e.prototype.clean=function(){for(;this.oldest&&this.map.size>this.max;)this.delete(this.oldest.key)},e.prototype.delete=function(e){var t=this.map.get(e);return!!t&&(t===this.newest&&(this.newest=t.older),t===this.oldest&&(this.oldest=t.newer),t.newer&&(t.newer.older=t.older),t.older&&(t.older.newer=t.newer),this.map.delete(e),this.dispose(t.value,e),!0)},e}(),rw=new rb,r_=Object.prototype.hasOwnProperty,rE=void 0===(n=Array.from)?function(e){var t=[];return e.forEach(function(e){return t.push(e)}),t}:n;function rS(e){var t=e.unsubscribe;"function"==typeof t&&(e.unsubscribe=void 0,t())}var rk=[],rx=100;function rT(e,t){if(!e)throw Error(t||"assertion failure")}function rM(e,t){var n=e.length;return n>0&&n===t.length&&e[n-1]===t[n-1]}function rO(e){switch(e.length){case 0:throw Error("unknown value");case 1:return e[0];case 2:throw e[1]}}function rA(e){return e.slice(0)}var rL=function(){function e(t){this.fn=t,this.parents=new Set,this.childValues=new Map,this.dirtyChildren=null,this.dirty=!0,this.recomputing=!1,this.value=[],this.deps=null,++e.count}return e.prototype.peek=function(){if(1===this.value.length&&!rN(this))return rC(this),this.value[0]},e.prototype.recompute=function(e){return rT(!this.recomputing,"already recomputing"),rC(this),rN(this)?rI(this,e):rO(this.value)},e.prototype.setDirty=function(){this.dirty||(this.dirty=!0,this.value.length=0,rR(this),rS(this))},e.prototype.dispose=function(){var e=this;this.setDirty(),rH(this),rF(this,function(t,n){t.setDirty(),r$(t,e)})},e.prototype.forget=function(){this.dispose()},e.prototype.dependOn=function(e){e.add(this),this.deps||(this.deps=rk.pop()||new Set),this.deps.add(e)},e.prototype.forgetDeps=function(){var e=this;this.deps&&(rE(this.deps).forEach(function(t){return t.delete(e)}),this.deps.clear(),rk.push(this.deps),this.deps=null)},e.count=0,e}();function rC(e){var t=rw.getValue();if(t)return e.parents.add(t),t.childValues.has(e)||t.childValues.set(e,[]),rN(e)?rY(t,e):rB(t,e),t}function rI(e,t){return rH(e),rw.withValue(e,rD,[e,t]),rz(e,t)&&rP(e),rO(e.value)}function rD(e,t){e.recomputing=!0,e.value.length=0;try{e.value[0]=e.fn.apply(null,t)}catch(n){e.value[1]=n}e.recomputing=!1}function rN(e){return e.dirty||!!(e.dirtyChildren&&e.dirtyChildren.size)}function rP(e){e.dirty=!1,!rN(e)&&rj(e)}function rR(e){rF(e,rY)}function rj(e){rF(e,rB)}function rF(e,t){var n=e.parents.size;if(n)for(var r=rE(e.parents),i=0;i0&&e.childValues.forEach(function(t,n){r$(e,n)}),e.forgetDeps(),rT(null===e.dirtyChildren)}function r$(e,t){t.parents.delete(e),e.childValues.delete(t),rU(e,t)}function rz(e,t){if("function"==typeof e.subscribe)try{rS(e),e.unsubscribe=e.subscribe.apply(null,t)}catch(n){return e.setDirty(),!1}return!0}var rG={setDirty:!0,dispose:!0,forget:!0};function rW(e){var t=new Map,n=e&&e.subscribe;function r(e){var r=rw.getValue();if(r){var i=t.get(e);i||t.set(e,i=new Set),r.dependOn(i),"function"==typeof n&&(rS(i),i.unsubscribe=n(e))}}return r.dirty=function(e,n){var r=t.get(e);if(r){var i=n&&r_.call(rG,n)?n:"setDirty";rE(r).forEach(function(e){return e[i]()}),t.delete(e),rS(r)}},r}function rK(){var e=new ra("function"==typeof WeakMap);return function(){return e.lookupArray(arguments)}}var rV=rK(),rq=new Set;function rZ(e,t){void 0===t&&(t=Object.create(null));var n=new ry(t.max||65536,function(e){return e.dispose()}),r=t.keyArgs,i=t.makeCacheKey||rK(),a=function(){var a=i.apply(null,r?r.apply(null,arguments):arguments);if(void 0===a)return e.apply(null,arguments);var o=n.get(a);o||(n.set(a,o=new rL(e)),o.subscribe=t.subscribe,o.forget=function(){return n.delete(a)});var s=o.recompute(Array.prototype.slice.call(arguments));return n.set(a,o),rq.add(n),rw.hasValue()||(rq.forEach(function(e){return e.clean()}),rq.clear()),s};function o(e){var t=n.get(e);t&&t.setDirty()}function s(e){var t=n.get(e);if(t)return t.peek()}function u(e){return n.delete(e)}return Object.defineProperty(a,"size",{get:function(){return n.map.size},configurable:!1,enumerable:!1}),a.dirtyKey=o,a.dirty=function(){o(i.apply(null,arguments))},a.peekKey=s,a.peek=function(){return s(i.apply(null,arguments))},a.forgetKey=u,a.forget=function(){return u(i.apply(null,arguments))},a.makeCacheKey=i,a.getKey=r?function(){return i.apply(null,r.apply(null,arguments))}:i,Object.freeze(a)}var rX=new rb,rJ=new WeakMap;function rQ(e){var t=rJ.get(e);return t||rJ.set(e,t={vars:new Set,dep:rW()}),t}function r1(e){rQ(e).vars.forEach(function(t){return t.forgetCache(e)})}function r0(e){rQ(e).vars.forEach(function(t){return t.attachCache(e)})}function r2(e){var t=new Set,n=new Set,r=function(a){if(arguments.length>0){if(e!==a){e=a,t.forEach(function(e){rQ(e).dep.dirty(r),r3(e)});var o=Array.from(n);n.clear(),o.forEach(function(t){return t(e)})}}else{var s=rX.getValue();s&&(i(s),rQ(s).dep(r))}return e};r.onNextChange=function(e){return n.add(e),function(){n.delete(e)}};var i=r.attachCache=function(e){return t.add(e),rQ(e).vars.add(r),r};return r.forgetCache=function(e){return t.delete(e)},r}function r3(e){e.broadcastWatches&&e.broadcastWatches()}var r4=function(){function e(e){var t=e.cache,n=e.client,r=e.resolvers,i=e.fragmentMatcher;this.selectionsToResolveCache=new WeakMap,this.cache=t,n&&(this.client=n),r&&this.addResolvers(r),i&&this.setFragmentMatcher(i)}return e.prototype.addResolvers=function(e){var t=this;this.resolvers=this.resolvers||{},Array.isArray(e)?e.forEach(function(e){t.resolvers=tj(t.resolvers,e)}):this.resolvers=tj(this.resolvers,e)},e.prototype.setResolvers=function(e){this.resolvers={},this.addResolvers(e)},e.prototype.getResolvers=function(){return this.resolvers||{}},e.prototype.runResolvers=function(e){var t=e.document,n=e.remoteResult,r=e.context,i=e.variables,a=e.onlyRunForcedResolvers,o=void 0!==a&&a;return(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(e){return t?[2,this.resolveDocument(t,n.data,r,i,this.fragmentMatcher,o).then(function(e){return(0,en.pi)((0,en.pi)({},n),{data:e.result})})]:[2,n]})})},e.prototype.setFragmentMatcher=function(e){this.fragmentMatcher=e},e.prototype.getFragmentMatcher=function(){return this.fragmentMatcher},e.prototype.clientQuery=function(e){return tb(["client"],e)&&this.resolvers?e:null},e.prototype.serverQuery=function(e){return n$(e)},e.prototype.prepareContext=function(e){var t=this.cache;return(0,en.pi)((0,en.pi)({},e),{cache:t,getCacheKey:function(e){return t.identify(e)}})},e.prototype.addExportedVariables=function(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(r){return e?[2,this.resolveDocument(e,this.buildRootValueFromCache(e,t)||{},this.prepareContext(n),t).then(function(e){return(0,en.pi)((0,en.pi)({},t),e.exportedVariables)})]:[2,(0,en.pi)({},t)]})})},e.prototype.shouldForceResolvers=function(e){var t=!1;return tl(e,{Directive:{enter:function(e){if("client"===e.name.value&&e.arguments&&(t=e.arguments.some(function(e){return"always"===e.name.value&&"BooleanValue"===e.value.kind&&!0===e.value.value})))return tc}}}),t},e.prototype.buildRootValueFromCache=function(e,t){return this.cache.diff({query:nH(e),variables:t,returnPartialData:!0,optimistic:!1}).result},e.prototype.resolveDocument=function(e,t,n,r,i,a){return void 0===n&&(n={}),void 0===r&&(r={}),void 0===i&&(i=function(){return!0}),void 0===a&&(a=!1),(0,en.mG)(this,void 0,void 0,function(){var o,s,u,c,l,f,d,h,p,b,m;return(0,en.Jh)(this,function(g){return o=e8(e),s=e4(e),u=eL(s),c=this.collectSelectionsToResolve(o,u),f=(l=o.operation)?l.charAt(0).toUpperCase()+l.slice(1):"Query",d=this,h=d.cache,p=d.client,b={fragmentMap:u,context:(0,en.pi)((0,en.pi)({},n),{cache:h,client:p}),variables:r,fragmentMatcher:i,defaultOperationType:f,exportedVariables:{},selectionsToResolve:c,onlyRunForcedResolvers:a},m=!1,[2,this.resolveSelectionSet(o.selectionSet,m,t,b).then(function(e){return{result:e,exportedVariables:b.exportedVariables}})]})})},e.prototype.resolveSelectionSet=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c=this;return(0,en.Jh)(this,function(l){return i=r.fragmentMap,a=r.context,o=r.variables,s=[n],u=function(e){return(0,en.mG)(c,void 0,void 0,function(){var u,c;return(0,en.Jh)(this,function(l){return(t||r.selectionsToResolve.has(e))&&td(e,o)?eQ(e)?[2,this.resolveField(e,t,n,r).then(function(t){var n;void 0!==t&&s.push(((n={})[eX(e)]=t,n))})]:(e1(e)?u=e:(u=i[e.name.value],__DEV__?(0,Q.kG)(u,"No fragment named ".concat(e.name.value)):(0,Q.kG)(u,11)),u&&u.typeCondition&&(c=u.typeCondition.name.value,r.fragmentMatcher(n,c,a)))?[2,this.resolveSelectionSet(u.selectionSet,t,n,r).then(function(e){s.push(e)})]:[2]:[2]})})},[2,Promise.all(e.selections.map(u)).then(function(){return tF(s)})]})})},e.prototype.resolveField=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c,l,f,d,h=this;return(0,en.Jh)(this,function(p){return n?(i=r.variables,a=e.name.value,o=eX(e),s=a!==o,c=Promise.resolve(u=n[o]||n[a]),(!r.onlyRunForcedResolvers||this.shouldForceResolvers(e))&&(l=n.__typename||r.defaultOperationType,(f=this.resolvers&&this.resolvers[l])&&(d=f[s?a:o])&&(c=Promise.resolve(rX.withValue(this.cache,d,[n,eZ(e,i),r.context,{field:e,fragmentMap:r.fragmentMap},])))),[2,c.then(function(n){if(void 0===n&&(n=u),e.directives&&e.directives.forEach(function(e){"export"===e.name.value&&e.arguments&&e.arguments.forEach(function(e){"as"===e.name.value&&"StringValue"===e.value.kind&&(r.exportedVariables[e.value.value]=n)})}),!e.selectionSet||null==n)return n;var i,a,o=null!==(a=null===(i=e.directives)||void 0===i?void 0:i.some(function(e){return"client"===e.name.value}))&&void 0!==a&&a;return Array.isArray(n)?h.resolveSubSelectedArray(e,t||o,n,r):e.selectionSet?h.resolveSelectionSet(e.selectionSet,t||o,n,r):void 0})]):[2,null]})})},e.prototype.resolveSubSelectedArray=function(e,t,n,r){var i=this;return Promise.all(n.map(function(n){return null===n?null:Array.isArray(n)?i.resolveSubSelectedArray(e,t,n,r):e.selectionSet?i.resolveSelectionSet(e.selectionSet,t,n,r):void 0}))},e.prototype.collectSelectionsToResolve=function(e,t){var n=function(e){return!Array.isArray(e)},r=this.selectionsToResolveCache;function i(e){if(!r.has(e)){var a=new Set;r.set(e,a),tl(e,{Directive:function(e,t,r,i,o){"client"===e.name.value&&o.forEach(function(e){n(e)&&n9(e)&&a.add(e)})},FragmentSpread:function(e,r,o,s,u){var c=t[e.name.value];__DEV__?(0,Q.kG)(c,"No fragment named ".concat(e.name.value)):(0,Q.kG)(c,12);var l=i(c);l.size>0&&(u.forEach(function(e){n(e)&&n9(e)&&a.add(e)}),a.add(e),l.forEach(function(e){a.add(e)}))}})}return r.get(e)}return i(e)},e}(),r6=new(t_.mr?WeakMap:Map);function r5(e,t){var n=e[t];"function"==typeof n&&(e[t]=function(){return r6.set(e,(r6.get(e)+1)%1e15),n.apply(this,arguments)})}function r8(e){e.notifyTimeout&&(clearTimeout(e.notifyTimeout),e.notifyTimeout=void 0)}var r9=function(){function e(e,t){void 0===t&&(t=e.generateQueryId()),this.queryId=t,this.listeners=new Set,this.document=null,this.lastRequestId=1,this.subscriptions=new Set,this.stopped=!1,this.dirty=!1,this.observableQuery=null;var n=this.cache=e.cache;r6.has(n)||(r6.set(n,0),r5(n,"evict"),r5(n,"modify"),r5(n,"reset"))}return e.prototype.init=function(e){var t=e.networkStatus||nZ.I.loading;return this.variables&&this.networkStatus!==nZ.I.loading&&!(0,nm.D)(this.variables,e.variables)&&(t=nZ.I.setVariables),(0,nm.D)(e.variables,this.variables)||(this.lastDiff=void 0),Object.assign(this,{document:e.document,variables:e.variables,networkError:null,graphQLErrors:this.graphQLErrors||[],networkStatus:t}),e.observableQuery&&this.setObservableQuery(e.observableQuery),e.lastRequestId&&(this.lastRequestId=e.lastRequestId),this},e.prototype.reset=function(){r8(this),this.dirty=!1},e.prototype.getDiff=function(e){void 0===e&&(e=this.variables);var t=this.getDiffOptions(e);if(this.lastDiff&&(0,nm.D)(t,this.lastDiff.options))return this.lastDiff.diff;this.updateWatch(this.variables=e);var n=this.observableQuery;if(n&&"no-cache"===n.options.fetchPolicy)return{complete:!1};var r=this.cache.diff(t);return this.updateLastDiff(r,t),r},e.prototype.updateLastDiff=function(e,t){this.lastDiff=e?{diff:e,options:t||this.getDiffOptions()}:void 0},e.prototype.getDiffOptions=function(e){var t;return void 0===e&&(e=this.variables),{query:this.document,variables:e,returnPartialData:!0,optimistic:!0,canonizeResults:null===(t=this.observableQuery)||void 0===t?void 0:t.options.canonizeResults}},e.prototype.setDiff=function(e){var t=this,n=this.lastDiff&&this.lastDiff.diff;this.updateLastDiff(e),this.dirty||(0,nm.D)(n&&n.result,e&&e.result)||(this.dirty=!0,this.notifyTimeout||(this.notifyTimeout=setTimeout(function(){return t.notify()},0)))},e.prototype.setObservableQuery=function(e){var t=this;e!==this.observableQuery&&(this.oqListener&&this.listeners.delete(this.oqListener),this.observableQuery=e,e?(e.queryInfo=this,this.listeners.add(this.oqListener=function(){t.getDiff().fromOptimisticTransaction?e.observe():n4(e)})):delete this.oqListener)},e.prototype.notify=function(){var e=this;r8(this),this.shouldNotify()&&this.listeners.forEach(function(t){return t(e)}),this.dirty=!1},e.prototype.shouldNotify=function(){if(!this.dirty||!this.listeners.size)return!1;if((0,nZ.O)(this.networkStatus)&&this.observableQuery){var e=this.observableQuery.options.fetchPolicy;if("cache-only"!==e&&"cache-and-network"!==e)return!1}return!0},e.prototype.stop=function(){if(!this.stopped){this.stopped=!0,this.reset(),this.cancel(),this.cancel=e.prototype.cancel,this.subscriptions.forEach(function(e){return e.unsubscribe()});var t=this.observableQuery;t&&t.stopPolling()}},e.prototype.cancel=function(){},e.prototype.updateWatch=function(e){var t=this;void 0===e&&(e=this.variables);var n=this.observableQuery;if(!n||"no-cache"!==n.options.fetchPolicy){var r=(0,en.pi)((0,en.pi)({},this.getDiffOptions(e)),{watcher:this,callback:function(e){return t.setDiff(e)}});this.lastWatch&&(0,nm.D)(r,this.lastWatch)||(this.cancel(),this.cancel=this.cache.watch(this.lastWatch=r))}},e.prototype.resetLastWrite=function(){this.lastWrite=void 0},e.prototype.shouldWrite=function(e,t){var n=this.lastWrite;return!(n&&n.dmCount===r6.get(this.cache)&&(0,nm.D)(t,n.variables)&&(0,nm.D)(e.data,n.result.data))},e.prototype.markResult=function(e,t,n,r){var i=this,a=new tB,o=(0,tP.O)(e.errors)?e.errors.slice(0):[];if(this.reset(),"incremental"in e&&(0,tP.O)(e.incremental)){var s=tG(this.getDiff().result,e);e.data=s}else if("hasNext"in e&&e.hasNext){var u=this.getDiff();e.data=a.merge(u.result,e.data)}this.graphQLErrors=o,"no-cache"===n.fetchPolicy?this.updateLastDiff({result:e.data,complete:!0},this.getDiffOptions(n.variables)):0!==r&&(r7(e,n.errorPolicy)?this.cache.performTransaction(function(a){if(i.shouldWrite(e,n.variables))a.writeQuery({query:t,data:e.data,variables:n.variables,overwrite:1===r}),i.lastWrite={result:e,variables:n.variables,dmCount:r6.get(i.cache)};else if(i.lastDiff&&i.lastDiff.diff.complete){e.data=i.lastDiff.diff.result;return}var o=i.getDiffOptions(n.variables),s=a.diff(o);i.stopped||i.updateWatch(n.variables),i.updateLastDiff(s,o),s.complete&&(e.data=s.result)}):this.lastWrite=void 0)},e.prototype.markReady=function(){return this.networkError=null,this.networkStatus=nZ.I.ready},e.prototype.markError=function(e){return this.networkStatus=nZ.I.error,this.lastWrite=void 0,this.reset(),e.graphQLErrors&&(this.graphQLErrors=e.graphQLErrors),e.networkError&&(this.networkError=e.networkError),e},e}();function r7(e,t){void 0===t&&(t="none");var n="ignore"===t||"all"===t,r=!nO(e);return!r&&n&&e.data&&(r=!0),r}var ie=Object.prototype.hasOwnProperty,it=function(){function e(e){var t=e.cache,n=e.link,r=e.defaultOptions,i=e.queryDeduplication,a=void 0!==i&&i,o=e.onBroadcast,s=e.ssrMode,u=void 0!==s&&s,c=e.clientAwareness,l=void 0===c?{}:c,f=e.localState,d=e.assumeImmutableResults;this.clientAwareness={},this.queries=new Map,this.fetchCancelFns=new Map,this.transformCache=new(t_.mr?WeakMap:Map),this.queryIdCounter=1,this.requestIdCounter=1,this.mutationIdCounter=1,this.inFlightLinkObservables=new Map,this.cache=t,this.link=n,this.defaultOptions=r||Object.create(null),this.queryDeduplication=a,this.clientAwareness=l,this.localState=f||new r4({cache:t}),this.ssrMode=u,this.assumeImmutableResults=!!d,(this.onBroadcast=o)&&(this.mutationStore=Object.create(null))}return e.prototype.stop=function(){var e=this;this.queries.forEach(function(t,n){e.stopQueryNoBroadcast(n)}),this.cancelPendingFetches(__DEV__?new Q.ej("QueryManager stopped while query was in flight"):new Q.ej(14))},e.prototype.cancelPendingFetches=function(e){this.fetchCancelFns.forEach(function(t){return t(e)}),this.fetchCancelFns.clear()},e.prototype.mutate=function(e){var t,n,r=e.mutation,i=e.variables,a=e.optimisticResponse,o=e.updateQueries,s=e.refetchQueries,u=void 0===s?[]:s,c=e.awaitRefetchQueries,l=void 0!==c&&c,f=e.update,d=e.onQueryUpdated,h=e.fetchPolicy,p=void 0===h?(null===(t=this.defaultOptions.mutate)||void 0===t?void 0:t.fetchPolicy)||"network-only":h,b=e.errorPolicy,m=void 0===b?(null===(n=this.defaultOptions.mutate)||void 0===n?void 0:n.errorPolicy)||"none":b,g=e.keepRootFields,v=e.context;return(0,en.mG)(this,void 0,void 0,function(){var e,t,n,s,c,h;return(0,en.Jh)(this,function(b){switch(b.label){case 0:if(__DEV__?(0,Q.kG)(r,"mutation option is required. You must specify your GraphQL document in the mutation option."):(0,Q.kG)(r,15),__DEV__?(0,Q.kG)("network-only"===p||"no-cache"===p,"Mutations support only 'network-only' or 'no-cache' fetchPolicy strings. The default `network-only` behavior automatically writes mutation results to the cache. Passing `no-cache` skips the cache write."):(0,Q.kG)("network-only"===p||"no-cache"===p,16),e=this.generateMutationId(),n=(t=this.transform(r)).document,s=t.hasClientExports,r=this.cache.transformForLink(n),i=this.getVariables(r,i),!s)return[3,2];return[4,this.localState.addExportedVariables(r,i,v)];case 1:i=b.sent(),b.label=2;case 2:return c=this.mutationStore&&(this.mutationStore[e]={mutation:r,variables:i,loading:!0,error:null}),a&&this.markMutationOptimistic(a,{mutationId:e,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,updateQueries:o,update:f,keepRootFields:g}),this.broadcastQueries(),h=this,[2,new Promise(function(t,n){return nM(h.getObservableFromLink(r,(0,en.pi)((0,en.pi)({},v),{optimisticResponse:a}),i,!1),function(t){if(nO(t)&&"none"===m)throw new tN.cA({graphQLErrors:nA(t)});c&&(c.loading=!1,c.error=null);var n=(0,en.pi)({},t);return"function"==typeof u&&(u=u(n)),"ignore"===m&&nO(n)&&delete n.errors,h.markMutationResult({mutationId:e,result:n,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,update:f,updateQueries:o,awaitRefetchQueries:l,refetchQueries:u,removeOptimistic:a?e:void 0,onQueryUpdated:d,keepRootFields:g})}).subscribe({next:function(e){h.broadcastQueries(),"hasNext"in e&&!1!==e.hasNext||t(e)},error:function(t){c&&(c.loading=!1,c.error=t),a&&h.cache.removeOptimistic(e),h.broadcastQueries(),n(t instanceof tN.cA?t:new tN.cA({networkError:t}))}})})]}})})},e.prototype.markMutationResult=function(e,t){var n=this;void 0===t&&(t=this.cache);var r=e.result,i=[],a="no-cache"===e.fetchPolicy;if(!a&&r7(r,e.errorPolicy)){if(tU(r)||i.push({result:r.data,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}),tU(r)&&(0,tP.O)(r.incremental)){var o=t.diff({id:"ROOT_MUTATION",query:this.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0}),s=void 0;o.result&&(s=tG(o.result,r)),void 0!==s&&(r.data=s,i.push({result:s,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}))}var u=e.updateQueries;u&&this.queries.forEach(function(e,a){var o=e.observableQuery,s=o&&o.queryName;if(s&&ie.call(u,s)){var c,l=u[s],f=n.queries.get(a),d=f.document,h=f.variables,p=t.diff({query:d,variables:h,returnPartialData:!0,optimistic:!1}),b=p.result;if(p.complete&&b){var m=l(b,{mutationResult:r,queryName:d&&e3(d)||void 0,queryVariables:h});m&&i.push({result:m,dataId:"ROOT_QUERY",query:d,variables:h})}}})}if(i.length>0||e.refetchQueries||e.update||e.onQueryUpdated||e.removeOptimistic){var c=[];if(this.refetchQueries({updateCache:function(t){a||i.forEach(function(e){return t.write(e)});var o=e.update,s=!t$(r)||tU(r)&&!r.hasNext;if(o){if(!a){var u=t.diff({id:"ROOT_MUTATION",query:n.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0});u.complete&&("incremental"in(r=(0,en.pi)((0,en.pi)({},r),{data:u.result}))&&delete r.incremental,"hasNext"in r&&delete r.hasNext)}s&&o(t,r,{context:e.context,variables:e.variables})}a||e.keepRootFields||!s||t.modify({id:"ROOT_MUTATION",fields:function(e,t){var n=t.fieldName,r=t.DELETE;return"__typename"===n?e:r}})},include:e.refetchQueries,optimistic:!1,removeOptimistic:e.removeOptimistic,onQueryUpdated:e.onQueryUpdated||null}).forEach(function(e){return c.push(e)}),e.awaitRefetchQueries||e.onQueryUpdated)return Promise.all(c).then(function(){return r})}return Promise.resolve(r)},e.prototype.markMutationOptimistic=function(e,t){var n=this,r="function"==typeof e?e(t.variables):e;return this.cache.recordOptimisticTransaction(function(e){try{n.markMutationResult((0,en.pi)((0,en.pi)({},t),{result:{data:r}}),e)}catch(i){__DEV__&&Q.kG.error(i)}},t.mutationId)},e.prototype.fetchQuery=function(e,t,n){return this.fetchQueryObservable(e,t,n).promise},e.prototype.getQueryStore=function(){var e=Object.create(null);return this.queries.forEach(function(t,n){e[n]={variables:t.variables,networkStatus:t.networkStatus,networkError:t.networkError,graphQLErrors:t.graphQLErrors}}),e},e.prototype.resetErrors=function(e){var t=this.queries.get(e);t&&(t.networkError=void 0,t.graphQLErrors=[])},e.prototype.transform=function(e){var t=this.transformCache;if(!t.has(e)){var n=this.cache.transformDocument(e),r=nY(n),i=this.localState.clientQuery(n),a=r&&this.localState.serverQuery(r),o={document:n,hasClientExports:tm(n),hasForcedResolvers:this.localState.shouldForceResolvers(n),clientQuery:i,serverQuery:a,defaultVars:e9(e2(n)),asQuery:(0,en.pi)((0,en.pi)({},n),{definitions:n.definitions.map(function(e){return"OperationDefinition"===e.kind&&"query"!==e.operation?(0,en.pi)((0,en.pi)({},e),{operation:"query"}):e})})},s=function(e){e&&!t.has(e)&&t.set(e,o)};s(e),s(n),s(i),s(a)}return t.get(e)},e.prototype.getVariables=function(e,t){return(0,en.pi)((0,en.pi)({},this.transform(e).defaultVars),t)},e.prototype.watchQuery=function(e){void 0===(e=(0,en.pi)((0,en.pi)({},e),{variables:this.getVariables(e.query,e.variables)})).notifyOnNetworkStatusChange&&(e.notifyOnNetworkStatusChange=!1);var t=new r9(this),n=new n3({queryManager:this,queryInfo:t,options:e});return this.queries.set(n.queryId,t),t.init({document:n.query,observableQuery:n,variables:n.variables}),n},e.prototype.query=function(e,t){var n=this;return void 0===t&&(t=this.generateQueryId()),__DEV__?(0,Q.kG)(e.query,"query option is required. You must specify your GraphQL document in the query option."):(0,Q.kG)(e.query,17),__DEV__?(0,Q.kG)("Document"===e.query.kind,'You must wrap the query string in a "gql" tag.'):(0,Q.kG)("Document"===e.query.kind,18),__DEV__?(0,Q.kG)(!e.returnPartialData,"returnPartialData option only supported on watchQuery."):(0,Q.kG)(!e.returnPartialData,19),__DEV__?(0,Q.kG)(!e.pollInterval,"pollInterval option only supported on watchQuery."):(0,Q.kG)(!e.pollInterval,20),this.fetchQuery(t,e).finally(function(){return n.stopQuery(t)})},e.prototype.generateQueryId=function(){return String(this.queryIdCounter++)},e.prototype.generateRequestId=function(){return this.requestIdCounter++},e.prototype.generateMutationId=function(){return String(this.mutationIdCounter++)},e.prototype.stopQueryInStore=function(e){this.stopQueryInStoreNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryInStoreNoBroadcast=function(e){var t=this.queries.get(e);t&&t.stop()},e.prototype.clearStore=function(e){return void 0===e&&(e={discardWatches:!0}),this.cancelPendingFetches(__DEV__?new Q.ej("Store reset while query was in flight (not completed in link chain)"):new Q.ej(21)),this.queries.forEach(function(e){e.observableQuery?e.networkStatus=nZ.I.loading:e.stop()}),this.mutationStore&&(this.mutationStore=Object.create(null)),this.cache.reset(e)},e.prototype.getObservableQueries=function(e){var t=this;void 0===e&&(e="active");var n=new Map,r=new Map,i=new Set;return Array.isArray(e)&&e.forEach(function(e){"string"==typeof e?r.set(e,!1):eN(e)?r.set(t.transform(e).document,!1):(0,eO.s)(e)&&e.query&&i.add(e)}),this.queries.forEach(function(t,i){var a=t.observableQuery,o=t.document;if(a){if("all"===e){n.set(i,a);return}var s=a.queryName;if("standby"===a.options.fetchPolicy||"active"===e&&!a.hasObservers())return;("active"===e||s&&r.has(s)||o&&r.has(o))&&(n.set(i,a),s&&r.set(s,!0),o&&r.set(o,!0))}}),i.size&&i.forEach(function(e){var r=nG("legacyOneTimeQuery"),i=t.getQuery(r).init({document:e.query,variables:e.variables}),a=new n3({queryManager:t,queryInfo:i,options:(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"network-only"})});(0,Q.kG)(a.queryId===r),i.setObservableQuery(a),n.set(r,a)}),__DEV__&&r.size&&r.forEach(function(e,t){!e&&__DEV__&&Q.kG.warn("Unknown query ".concat("string"==typeof t?"named ":"").concat(JSON.stringify(t,null,2)," requested in refetchQueries options.include array"))}),n},e.prototype.reFetchObservableQueries=function(e){var t=this;void 0===e&&(e=!1);var n=[];return this.getObservableQueries(e?"all":"active").forEach(function(r,i){var a=r.options.fetchPolicy;r.resetLastResults(),(e||"standby"!==a&&"cache-only"!==a)&&n.push(r.refetch()),t.getQuery(i).setDiff(null)}),this.broadcastQueries(),Promise.all(n)},e.prototype.setObservableQuery=function(e){this.getQuery(e.queryId).setObservableQuery(e)},e.prototype.startGraphQLSubscription=function(e){var t=this,n=e.query,r=e.fetchPolicy,i=e.errorPolicy,a=e.variables,o=e.context,s=void 0===o?{}:o;n=this.transform(n).document,a=this.getVariables(n,a);var u=function(e){return t.getObservableFromLink(n,s,e).map(function(a){"no-cache"!==r&&(r7(a,i)&&t.cache.write({query:n,result:a.data,dataId:"ROOT_SUBSCRIPTION",variables:e}),t.broadcastQueries());var o=nO(a),s=(0,tN.ls)(a);if(o||s){var u={};throw o&&(u.graphQLErrors=a.errors),s&&(u.protocolErrors=a.extensions[tN.YG]),new tN.cA(u)}return a})};if(this.transform(n).hasClientExports){var c=this.localState.addExportedVariables(n,a,s).then(u);return new eT(function(e){var t=null;return c.then(function(n){return t=n.subscribe(e)},e.error),function(){return t&&t.unsubscribe()}})}return u(a)},e.prototype.stopQuery=function(e){this.stopQueryNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryNoBroadcast=function(e){this.stopQueryInStoreNoBroadcast(e),this.removeQuery(e)},e.prototype.removeQuery=function(e){this.fetchCancelFns.delete(e),this.queries.has(e)&&(this.getQuery(e).stop(),this.queries.delete(e))},e.prototype.broadcastQueries=function(){this.onBroadcast&&this.onBroadcast(),this.queries.forEach(function(e){return e.notify()})},e.prototype.getLocalState=function(){return this.localState},e.prototype.getObservableFromLink=function(e,t,n,r){var i,a,o=this;void 0===r&&(r=null!==(i=null==t?void 0:t.queryDeduplication)&&void 0!==i?i:this.queryDeduplication);var s=this.transform(e).serverQuery;if(s){var u=this,c=u.inFlightLinkObservables,l=u.link,f={query:s,variables:n,operationName:e3(s)||void 0,context:this.prepareContext((0,en.pi)((0,en.pi)({},t),{forceFetch:!r}))};if(t=f.context,r){var d=c.get(s)||new Map;c.set(s,d);var h=nx(n);if(!(a=d.get(h))){var p=new nq([np(l,f)]);d.set(h,a=p),p.beforeNext(function(){d.delete(h)&&d.size<1&&c.delete(s)})}}else a=new nq([np(l,f)])}else a=new nq([eT.of({data:{}})]),t=this.prepareContext(t);var b=this.transform(e).clientQuery;return b&&(a=nM(a,function(e){return o.localState.runResolvers({document:b,remoteResult:e,context:t,variables:n})})),a},e.prototype.getResultsFromLink=function(e,t,n){var r=e.lastRequestId=this.generateRequestId(),i=this.cache.transformForLink(this.transform(e.document).document);return nM(this.getObservableFromLink(i,n.context,n.variables),function(a){var o=nA(a),s=o.length>0;if(r>=e.lastRequestId){if(s&&"none"===n.errorPolicy)throw e.markError(new tN.cA({graphQLErrors:o}));e.markResult(a,i,n,t),e.markReady()}var u={data:a.data,loading:!1,networkStatus:nZ.I.ready};return s&&"ignore"!==n.errorPolicy&&(u.errors=o,u.networkStatus=nZ.I.error),u},function(t){var n=(0,tN.MS)(t)?t:new tN.cA({networkError:t});throw r>=e.lastRequestId&&e.markError(n),n})},e.prototype.fetchQueryObservable=function(e,t,n){return this.fetchConcastWithInfo(e,t,n).concast},e.prototype.fetchConcastWithInfo=function(e,t,n){var r,i,a=this;void 0===n&&(n=nZ.I.loading);var o=this.transform(t.query).document,s=this.getVariables(o,t.variables),u=this.getQuery(e),c=this.defaultOptions.watchQuery,l=t.fetchPolicy,f=void 0===l?c&&c.fetchPolicy||"cache-first":l,d=t.errorPolicy,h=void 0===d?c&&c.errorPolicy||"none":d,p=t.returnPartialData,b=void 0!==p&&p,m=t.notifyOnNetworkStatusChange,g=void 0!==m&&m,v=t.context,y=void 0===v?{}:v,w=Object.assign({},t,{query:o,variables:s,fetchPolicy:f,errorPolicy:h,returnPartialData:b,notifyOnNetworkStatusChange:g,context:y}),_=function(e){w.variables=e;var r=a.fetchQueryByPolicy(u,w,n);return"standby"!==w.fetchPolicy&&r.sources.length>0&&u.observableQuery&&u.observableQuery.applyNextFetchPolicy("after-fetch",t),r},E=function(){return a.fetchCancelFns.delete(e)};if(this.fetchCancelFns.set(e,function(e){E(),setTimeout(function(){return r.cancel(e)})}),this.transform(w.query).hasClientExports)r=new nq(this.localState.addExportedVariables(w.query,w.variables,w.context).then(_).then(function(e){return e.sources})),i=!0;else{var S=_(w.variables);i=S.fromLink,r=new nq(S.sources)}return r.promise.then(E,E),{concast:r,fromLink:i}},e.prototype.refetchQueries=function(e){var t=this,n=e.updateCache,r=e.include,i=e.optimistic,a=void 0!==i&&i,o=e.removeOptimistic,s=void 0===o?a?nG("refetchQueries"):void 0:o,u=e.onQueryUpdated,c=new Map;r&&this.getObservableQueries(r).forEach(function(e,n){c.set(n,{oq:e,lastDiff:t.getQuery(n).getDiff()})});var l=new Map;return n&&this.cache.batch({update:n,optimistic:a&&s||!1,removeOptimistic:s,onWatchUpdated:function(e,t,n){var r=e.watcher instanceof r9&&e.watcher.observableQuery;if(r){if(u){c.delete(r.queryId);var i=u(r,t,n);return!0===i&&(i=r.refetch()),!1!==i&&l.set(r,i),i}null!==u&&c.set(r.queryId,{oq:r,lastDiff:n,diff:t})}}}),c.size&&c.forEach(function(e,n){var r,i=e.oq,a=e.lastDiff,o=e.diff;if(u){if(!o){var s=i.queryInfo;s.reset(),o=s.getDiff()}r=u(i,o,a)}u&&!0!==r||(r=i.refetch()),!1!==r&&l.set(i,r),n.indexOf("legacyOneTimeQuery")>=0&&t.stopQueryNoBroadcast(n)}),s&&this.cache.removeOptimistic(s),l},e.prototype.fetchQueryByPolicy=function(e,t,n){var r=this,i=t.query,a=t.variables,o=t.fetchPolicy,s=t.refetchWritePolicy,u=t.errorPolicy,c=t.returnPartialData,l=t.context,f=t.notifyOnNetworkStatusChange,d=e.networkStatus;e.init({document:this.transform(i).document,variables:a,networkStatus:n});var h=function(){return e.getDiff(a)},p=function(t,n){void 0===n&&(n=e.networkStatus||nZ.I.loading);var o=t.result;!__DEV__||c||(0,nm.D)(o,{})||n5(t.missing);var s=function(e){return eT.of((0,en.pi)({data:e,loading:(0,nZ.O)(n),networkStatus:n},t.complete?null:{partial:!0}))};return o&&r.transform(i).hasForcedResolvers?r.localState.runResolvers({document:i,remoteResult:{data:o},context:l,variables:a,onlyRunForcedResolvers:!0}).then(function(e){return s(e.data||void 0)}):"none"===u&&n===nZ.I.refetch&&Array.isArray(t.missing)?s(void 0):s(o)},b="no-cache"===o?0:n===nZ.I.refetch&&"merge"!==s?1:2,m=function(){return r.getResultsFromLink(e,b,{variables:a,context:l,fetchPolicy:o,errorPolicy:u})},g=f&&"number"==typeof d&&d!==n&&(0,nZ.O)(n);switch(o){default:case"cache-first":var v=h();if(v.complete)return{fromLink:!1,sources:[p(v,e.markReady())]};if(c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-and-network":var v=h();if(v.complete||c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-only":return{fromLink:!1,sources:[p(h(),e.markReady())]};case"network-only":if(g)return{fromLink:!0,sources:[p(h()),m()]};return{fromLink:!0,sources:[m()]};case"no-cache":if(g)return{fromLink:!0,sources:[p(e.getDiff()),m(),]};return{fromLink:!0,sources:[m()]};case"standby":return{fromLink:!1,sources:[]}}},e.prototype.getQuery=function(e){return e&&!this.queries.has(e)&&this.queries.set(e,new r9(this,e)),this.queries.get(e)},e.prototype.prepareContext=function(e){void 0===e&&(e={});var t=this.localState.prepareContext(e);return(0,en.pi)((0,en.pi)({},t),{clientAwareness:this.clientAwareness})},e}(),ir=__webpack_require__(14012),ii=!1,ia=function(){function e(e){var t=this;this.resetStoreCallbacks=[],this.clearStoreCallbacks=[];var n=e.uri,r=e.credentials,i=e.headers,a=e.cache,o=e.ssrMode,s=void 0!==o&&o,u=e.ssrForceFetchDelay,c=void 0===u?0:u,l=e.connectToDevTools,f=void 0===l?"object"==typeof window&&!window.__APOLLO_CLIENT__&&__DEV__:l,d=e.queryDeduplication,h=void 0===d||d,p=e.defaultOptions,b=e.assumeImmutableResults,m=void 0!==b&&b,g=e.resolvers,v=e.typeDefs,y=e.fragmentMatcher,w=e.name,_=e.version,E=e.link;if(E||(E=n?new nh({uri:n,credentials:r,headers:i}):ta.empty()),!a)throw __DEV__?new Q.ej("To initialize Apollo Client, you must specify a 'cache' property in the options object. \nFor more information, please visit: https://go.apollo.dev/c/docs"):new Q.ej(9);if(this.link=E,this.cache=a,this.disableNetworkFetches=s||c>0,this.queryDeduplication=h,this.defaultOptions=p||Object.create(null),this.typeDefs=v,c&&setTimeout(function(){return t.disableNetworkFetches=!1},c),this.watchQuery=this.watchQuery.bind(this),this.query=this.query.bind(this),this.mutate=this.mutate.bind(this),this.resetStore=this.resetStore.bind(this),this.reFetchObservableQueries=this.reFetchObservableQueries.bind(this),f&&"object"==typeof window&&(window.__APOLLO_CLIENT__=this),!ii&&f&&__DEV__&&(ii=!0,"undefined"!=typeof window&&window.document&&window.top===window.self&&!window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__)){var S=window.navigator,k=S&&S.userAgent,x=void 0;"string"==typeof k&&(k.indexOf("Chrome/")>-1?x="https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm":k.indexOf("Firefox/")>-1&&(x="https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/")),x&&__DEV__&&Q.kG.log("Download the Apollo DevTools for a better development experience: "+x)}this.version=nb,this.localState=new r4({cache:a,client:this,resolvers:g,fragmentMatcher:y}),this.queryManager=new it({cache:this.cache,link:this.link,defaultOptions:this.defaultOptions,queryDeduplication:h,ssrMode:s,clientAwareness:{name:w,version:_},localState:this.localState,assumeImmutableResults:m,onBroadcast:f?function(){t.devToolsHookCb&&t.devToolsHookCb({action:{},state:{queries:t.queryManager.getQueryStore(),mutations:t.queryManager.mutationStore||{}},dataWithOptimisticResults:t.cache.extract(!0)})}:void 0})}return e.prototype.stop=function(){this.queryManager.stop()},e.prototype.watchQuery=function(e){return this.defaultOptions.watchQuery&&(e=(0,ir.J)(this.defaultOptions.watchQuery,e)),this.disableNetworkFetches&&("network-only"===e.fetchPolicy||"cache-and-network"===e.fetchPolicy)&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.watchQuery(e)},e.prototype.query=function(e){return this.defaultOptions.query&&(e=(0,ir.J)(this.defaultOptions.query,e)),__DEV__?(0,Q.kG)("cache-and-network"!==e.fetchPolicy,"The cache-and-network fetchPolicy does not work with client.query, because client.query can only return a single result. Please use client.watchQuery to receive multiple results from the cache and the network, or consider using a different fetchPolicy, such as cache-first or network-only."):(0,Q.kG)("cache-and-network"!==e.fetchPolicy,10),this.disableNetworkFetches&&"network-only"===e.fetchPolicy&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.query(e)},e.prototype.mutate=function(e){return this.defaultOptions.mutate&&(e=(0,ir.J)(this.defaultOptions.mutate,e)),this.queryManager.mutate(e)},e.prototype.subscribe=function(e){return this.queryManager.startGraphQLSubscription(e)},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!1),this.cache.readQuery(e,t)},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!1),this.cache.readFragment(e,t)},e.prototype.writeQuery=function(e){var t=this.cache.writeQuery(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.writeFragment=function(e){var t=this.cache.writeFragment(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.__actionHookForDevTools=function(e){this.devToolsHookCb=e},e.prototype.__requestRaw=function(e){return np(this.link,e)},e.prototype.resetStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!1})}).then(function(){return Promise.all(e.resetStoreCallbacks.map(function(e){return e()}))}).then(function(){return e.reFetchObservableQueries()})},e.prototype.clearStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!0})}).then(function(){return Promise.all(e.clearStoreCallbacks.map(function(e){return e()}))})},e.prototype.onResetStore=function(e){var t=this;return this.resetStoreCallbacks.push(e),function(){t.resetStoreCallbacks=t.resetStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.onClearStore=function(e){var t=this;return this.clearStoreCallbacks.push(e),function(){t.clearStoreCallbacks=t.clearStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.reFetchObservableQueries=function(e){return this.queryManager.reFetchObservableQueries(e)},e.prototype.refetchQueries=function(e){var t=this.queryManager.refetchQueries(e),n=[],r=[];t.forEach(function(e,t){n.push(t),r.push(e)});var i=Promise.all(r);return i.queries=n,i.results=r,i.catch(function(e){__DEV__&&Q.kG.debug("In client.refetchQueries, Promise.all promise rejected with error ".concat(e))}),i},e.prototype.getObservableQueries=function(e){return void 0===e&&(e="active"),this.queryManager.getObservableQueries(e)},e.prototype.extract=function(e){return this.cache.extract(e)},e.prototype.restore=function(e){return this.cache.restore(e)},e.prototype.addResolvers=function(e){this.localState.addResolvers(e)},e.prototype.setResolvers=function(e){this.localState.setResolvers(e)},e.prototype.getResolvers=function(){return this.localState.getResolvers()},e.prototype.setLocalStateFragmentMatcher=function(e){this.localState.setFragmentMatcher(e)},e.prototype.setLink=function(e){this.link=this.queryManager.link=e},e}(),io=function(){function e(){this.getFragmentDoc=rZ(eA)}return e.prototype.batch=function(e){var t,n=this,r="string"==typeof e.optimistic?e.optimistic:!1===e.optimistic?null:void 0;return this.performTransaction(function(){return t=e.update(n)},r),t},e.prototype.recordOptimisticTransaction=function(e,t){this.performTransaction(e,t)},e.prototype.transformDocument=function(e){return e},e.prototype.transformForLink=function(e){return e},e.prototype.identify=function(e){},e.prototype.gc=function(){return[]},e.prototype.modify=function(e){return!1},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{rootId:e.id||"ROOT_QUERY",optimistic:t}))},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{query:this.getFragmentDoc(e.fragment,e.fragmentName),rootId:e.id,optimistic:t}))},e.prototype.writeQuery=function(e){var t=e.id,n=e.data,r=(0,en._T)(e,["id","data"]);return this.write(Object.assign(r,{dataId:t||"ROOT_QUERY",result:n}))},e.prototype.writeFragment=function(e){var t=e.id,n=e.data,r=e.fragment,i=e.fragmentName,a=(0,en._T)(e,["id","data","fragment","fragmentName"]);return this.write(Object.assign(a,{query:this.getFragmentDoc(r,i),dataId:t,result:n}))},e.prototype.updateQuery=function(e,t){return this.batch({update:function(n){var r=n.readQuery(e),i=t(r);return null==i?r:(n.writeQuery((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e.prototype.updateFragment=function(e,t){return this.batch({update:function(n){var r=n.readFragment(e),i=t(r);return null==i?r:(n.writeFragment((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e}(),is=function(e){function t(n,r,i,a){var o,s=e.call(this,n)||this;if(s.message=n,s.path=r,s.query=i,s.variables=a,Array.isArray(s.path)){s.missing=s.message;for(var u=s.path.length-1;u>=0;--u)s.missing=((o={})[s.path[u]]=s.missing,o)}else s.missing=s.path;return s.__proto__=t.prototype,s}return(0,en.ZT)(t,e),t}(Error),iu=__webpack_require__(10542),ic=Object.prototype.hasOwnProperty;function il(e){return null==e}function id(e,t){var n=e.__typename,r=e.id,i=e._id;if("string"==typeof n&&(t&&(t.keyObject=il(r)?il(i)?void 0:{_id:i}:{id:r}),il(r)&&!il(i)&&(r=i),!il(r)))return"".concat(n,":").concat("number"==typeof r||"string"==typeof r?r:JSON.stringify(r))}var ih={dataIdFromObject:id,addTypename:!0,resultCaching:!0,canonizeResults:!1};function ip(e){return(0,n1.o)(ih,e)}function ib(e){var t=e.canonizeResults;return void 0===t?ih.canonizeResults:t}function im(e,t){return eD(t)?e.get(t.__ref,"__typename"):t&&t.__typename}var ig=/^[_a-z][_0-9a-z]*/i;function iv(e){var t=e.match(ig);return t?t[0]:e}function iy(e,t,n){return!!(0,eO.s)(t)&&((0,tP.k)(t)?t.every(function(t){return iy(e,t,n)}):e.selections.every(function(e){if(eQ(e)&&td(e,n)){var r=eX(e);return ic.call(t,r)&&(!e.selectionSet||iy(e.selectionSet,t[r],n))}return!0}))}function iw(e){return(0,eO.s)(e)&&!eD(e)&&!(0,tP.k)(e)}function i_(){return new tB}function iE(e,t){var n=eL(e4(e));return{fragmentMap:n,lookupFragment:function(e){var r=n[e];return!r&&t&&(r=t.lookup(e)),r||null}}}var iS=Object.create(null),ik=function(){return iS},ix=Object.create(null),iT=function(){function e(e,t){var n=this;this.policies=e,this.group=t,this.data=Object.create(null),this.rootIds=Object.create(null),this.refs=Object.create(null),this.getFieldValue=function(e,t){return(0,iu.J)(eD(e)?n.get(e.__ref,t):e&&e[t])},this.canRead=function(e){return eD(e)?n.has(e.__ref):"object"==typeof e},this.toReference=function(e,t){if("string"==typeof e)return eI(e);if(eD(e))return e;var r=n.policies.identify(e)[0];if(r){var i=eI(r);return t&&n.merge(r,e),i}}}return e.prototype.toObject=function(){return(0,en.pi)({},this.data)},e.prototype.has=function(e){return void 0!==this.lookup(e,!0)},e.prototype.get=function(e,t){if(this.group.depend(e,t),ic.call(this.data,e)){var n=this.data[e];if(n&&ic.call(n,t))return n[t]}return"__typename"===t&&ic.call(this.policies.rootTypenamesById,e)?this.policies.rootTypenamesById[e]:this instanceof iL?this.parent.get(e,t):void 0},e.prototype.lookup=function(e,t){return(t&&this.group.depend(e,"__exists"),ic.call(this.data,e))?this.data[e]:this instanceof iL?this.parent.lookup(e,t):this.policies.rootTypenamesById[e]?Object.create(null):void 0},e.prototype.merge=function(e,t){var n,r=this;eD(e)&&(e=e.__ref),eD(t)&&(t=t.__ref);var i="string"==typeof e?this.lookup(n=e):e,a="string"==typeof t?this.lookup(n=t):t;if(a){__DEV__?(0,Q.kG)("string"==typeof n,"store.merge expects a string ID"):(0,Q.kG)("string"==typeof n,1);var o=new tB(iI).merge(i,a);if(this.data[n]=o,o!==i&&(delete this.refs[n],this.group.caching)){var s=Object.create(null);i||(s.__exists=1),Object.keys(a).forEach(function(e){if(!i||i[e]!==o[e]){s[e]=1;var t=iv(e);t===e||r.policies.hasKeyArgs(o.__typename,t)||(s[t]=1),void 0!==o[e]||r instanceof iL||delete o[e]}}),s.__typename&&!(i&&i.__typename)&&this.policies.rootTypenamesById[n]===o.__typename&&delete s.__typename,Object.keys(s).forEach(function(e){return r.group.dirty(n,e)})}}},e.prototype.modify=function(e,t){var n=this,r=this.lookup(e);if(r){var i=Object.create(null),a=!1,o=!0,s={DELETE:iS,INVALIDATE:ix,isReference:eD,toReference:this.toReference,canRead:this.canRead,readField:function(t,r){return n.policies.readField("string"==typeof t?{fieldName:t,from:r||eI(e)}:t,{store:n})}};if(Object.keys(r).forEach(function(u){var c=iv(u),l=r[u];if(void 0!==l){var f="function"==typeof t?t:t[u]||t[c];if(f){var d=f===ik?iS:f((0,iu.J)(l),(0,en.pi)((0,en.pi)({},s),{fieldName:c,storeFieldName:u,storage:n.getStorage(e,u)}));d===ix?n.group.dirty(e,u):(d===iS&&(d=void 0),d!==l&&(i[u]=d,a=!0,l=d))}void 0!==l&&(o=!1)}}),a)return this.merge(e,i),o&&(this instanceof iL?this.data[e]=void 0:delete this.data[e],this.group.dirty(e,"__exists")),!0}return!1},e.prototype.delete=function(e,t,n){var r,i=this.lookup(e);if(i){var a=this.getFieldValue(i,"__typename"),o=t&&n?this.policies.getStoreFieldName({typename:a,fieldName:t,args:n}):t;return this.modify(e,o?((r={})[o]=ik,r):ik)}return!1},e.prototype.evict=function(e,t){var n=!1;return e.id&&(ic.call(this.data,e.id)&&(n=this.delete(e.id,e.fieldName,e.args)),this instanceof iL&&this!==t&&(n=this.parent.evict(e,t)||n),(e.fieldName||n)&&this.group.dirty(e.id,e.fieldName||"__exists")),n},e.prototype.clear=function(){this.replace(null)},e.prototype.extract=function(){var e=this,t=this.toObject(),n=[];return this.getRootIdSet().forEach(function(t){ic.call(e.policies.rootTypenamesById,t)||n.push(t)}),n.length&&(t.__META={extraRootIds:n.sort()}),t},e.prototype.replace=function(e){var t=this;if(Object.keys(this.data).forEach(function(n){e&&ic.call(e,n)||t.delete(n)}),e){var n=e.__META,r=(0,en._T)(e,["__META"]);Object.keys(r).forEach(function(e){t.merge(e,r[e])}),n&&n.extraRootIds.forEach(this.retain,this)}},e.prototype.retain=function(e){return this.rootIds[e]=(this.rootIds[e]||0)+1},e.prototype.release=function(e){if(this.rootIds[e]>0){var t=--this.rootIds[e];return t||delete this.rootIds[e],t}return 0},e.prototype.getRootIdSet=function(e){return void 0===e&&(e=new Set),Object.keys(this.rootIds).forEach(e.add,e),this instanceof iL?this.parent.getRootIdSet(e):Object.keys(this.policies.rootTypenamesById).forEach(e.add,e),e},e.prototype.gc=function(){var e=this,t=this.getRootIdSet(),n=this.toObject();t.forEach(function(r){ic.call(n,r)&&(Object.keys(e.findChildRefIds(r)).forEach(t.add,t),delete n[r])});var r=Object.keys(n);if(r.length){for(var i=this;i instanceof iL;)i=i.parent;r.forEach(function(e){return i.delete(e)})}return r},e.prototype.findChildRefIds=function(e){if(!ic.call(this.refs,e)){var t=this.refs[e]=Object.create(null),n=this.data[e];if(!n)return t;var r=new Set([n]);r.forEach(function(e){eD(e)&&(t[e.__ref]=!0),(0,eO.s)(e)&&Object.keys(e).forEach(function(t){var n=e[t];(0,eO.s)(n)&&r.add(n)})})}return this.refs[e]},e.prototype.makeCacheKey=function(){return this.group.keyMaker.lookupArray(arguments)},e}(),iM=function(){function e(e,t){void 0===t&&(t=null),this.caching=e,this.parent=t,this.d=null,this.resetCaching()}return e.prototype.resetCaching=function(){this.d=this.caching?rW():null,this.keyMaker=new n_(t_.mr)},e.prototype.depend=function(e,t){if(this.d){this.d(iO(e,t));var n=iv(t);n!==t&&this.d(iO(e,n)),this.parent&&this.parent.depend(e,t)}},e.prototype.dirty=function(e,t){this.d&&this.d.dirty(iO(e,t),"__exists"===t?"forget":"setDirty")},e}();function iO(e,t){return t+"#"+e}function iA(e,t){iD(e)&&e.group.depend(t,"__exists")}!function(e){var t=function(e){function t(t){var n=t.policies,r=t.resultCaching,i=void 0===r||r,a=t.seed,o=e.call(this,n,new iM(i))||this;return o.stump=new iC(o),o.storageTrie=new n_(t_.mr),a&&o.replace(a),o}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,t){return this.stump.addLayer(e,t)},t.prototype.removeLayer=function(){return this},t.prototype.getStorage=function(){return this.storageTrie.lookupArray(arguments)},t}(e);e.Root=t}(iT||(iT={}));var iL=function(e){function t(t,n,r,i){var a=e.call(this,n.policies,i)||this;return a.id=t,a.parent=n,a.replay=r,a.group=i,r(a),a}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,n){return new t(e,this,n,this.group)},t.prototype.removeLayer=function(e){var t=this,n=this.parent.removeLayer(e);return e===this.id?(this.group.caching&&Object.keys(this.data).forEach(function(e){var r=t.data[e],i=n.lookup(e);i?r?r!==i&&Object.keys(r).forEach(function(n){(0,nm.D)(r[n],i[n])||t.group.dirty(e,n)}):(t.group.dirty(e,"__exists"),Object.keys(i).forEach(function(n){t.group.dirty(e,n)})):t.delete(e)}),n):n===this.parent?this:n.addLayer(this.id,this.replay)},t.prototype.toObject=function(){return(0,en.pi)((0,en.pi)({},this.parent.toObject()),this.data)},t.prototype.findChildRefIds=function(t){var n=this.parent.findChildRefIds(t);return ic.call(this.data,t)?(0,en.pi)((0,en.pi)({},n),e.prototype.findChildRefIds.call(this,t)):n},t.prototype.getStorage=function(){for(var e=this.parent;e.parent;)e=e.parent;return e.getStorage.apply(e,arguments)},t}(iT),iC=function(e){function t(t){return e.call(this,"EntityStore.Stump",t,function(){},new iM(t.group.caching,t.group))||this}return(0,en.ZT)(t,e),t.prototype.removeLayer=function(){return this},t.prototype.merge=function(){return this.parent.merge.apply(this.parent,arguments)},t}(iL);function iI(e,t,n){var r=e[n],i=t[n];return(0,nm.D)(r,i)?r:i}function iD(e){return!!(e instanceof iT&&e.group.caching)}function iN(e){return[e.selectionSet,e.objectOrReference,e.context,e.context.canonizeResults,]}var iP=function(){function e(e){var t=this;this.knownResults=new(t_.mr?WeakMap:Map),this.config=(0,n1.o)(e,{addTypename:!1!==e.addTypename,canonizeResults:ib(e)}),this.canon=e.canon||new nk,this.executeSelectionSet=rZ(function(e){var n,r=e.context.canonizeResults,i=iN(e);i[3]=!r;var a=(n=t.executeSelectionSet).peek.apply(n,i);return a?r?(0,en.pi)((0,en.pi)({},a),{result:t.canon.admit(a.result)}):a:(iA(e.context.store,e.enclosingRef.__ref),t.execSelectionSetImpl(e))},{max:this.config.resultCacheMaxSize,keyArgs:iN,makeCacheKey:function(e,t,n,r){if(iD(n.store))return n.store.makeCacheKey(e,eD(t)?t.__ref:t,n.varString,r)}}),this.executeSubSelectedArray=rZ(function(e){return iA(e.context.store,e.enclosingRef.__ref),t.execSubSelectedArrayImpl(e)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var t=e.field,n=e.array,r=e.context;if(iD(r.store))return r.store.makeCacheKey(t,n,r.varString)}})}return e.prototype.resetCanon=function(){this.canon=new nk},e.prototype.diffQueryAgainstStore=function(e){var t,n=e.store,r=e.query,i=e.rootId,a=void 0===i?"ROOT_QUERY":i,o=e.variables,s=e.returnPartialData,u=void 0===s||s,c=e.canonizeResults,l=void 0===c?this.config.canonizeResults:c,f=this.config.cache.policies;o=(0,en.pi)((0,en.pi)({},e9(e6(r))),o);var d=eI(a),h=this.executeSelectionSet({selectionSet:e8(r).selectionSet,objectOrReference:d,enclosingRef:d,context:(0,en.pi)({store:n,query:r,policies:f,variables:o,varString:nx(o),canonizeResults:l},iE(r,this.config.fragments))});if(h.missing&&(t=[new is(iR(h.missing),h.missing,r,o)],!u))throw t[0];return{result:h.result,complete:!t,missing:t}},e.prototype.isFresh=function(e,t,n,r){if(iD(r.store)&&this.knownResults.get(e)===n){var i=this.executeSelectionSet.peek(n,t,r,this.canon.isKnown(e));if(i&&e===i.result)return!0}return!1},e.prototype.execSelectionSetImpl=function(e){var t,n=this,r=e.selectionSet,i=e.objectOrReference,a=e.enclosingRef,o=e.context;if(eD(i)&&!o.policies.rootTypenamesById[i.__ref]&&!o.store.has(i.__ref))return{result:this.canon.empty,missing:"Dangling reference to missing ".concat(i.__ref," object")};var s=o.variables,u=o.policies,c=o.store.getFieldValue(i,"__typename"),l=[],f=new tB;function d(e,n){var r;return e.missing&&(t=f.merge(t,((r={})[n]=e.missing,r))),e.result}this.config.addTypename&&"string"==typeof c&&!u.rootIdsByTypename[c]&&l.push({__typename:c});var h=new Set(r.selections);h.forEach(function(e){var r,p;if(td(e,s)){if(eQ(e)){var b=u.readField({fieldName:e.name.value,field:e,variables:o.variables,from:i},o),m=eX(e);void 0===b?nj.added(e)||(t=f.merge(t,((r={})[m]="Can't find field '".concat(e.name.value,"' on ").concat(eD(i)?i.__ref+" object":"object "+JSON.stringify(i,null,2)),r))):(0,tP.k)(b)?b=d(n.executeSubSelectedArray({field:e,array:b,enclosingRef:a,context:o}),m):e.selectionSet?null!=b&&(b=d(n.executeSelectionSet({selectionSet:e.selectionSet,objectOrReference:b,enclosingRef:eD(b)?b:a,context:o}),m)):o.canonizeResults&&(b=n.canon.pass(b)),void 0!==b&&l.push(((p={})[m]=b,p))}else{var g=eC(e,o.lookupFragment);if(!g&&e.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(e.name.value)):new Q.ej(5);g&&u.fragmentMatches(g,c)&&g.selectionSet.selections.forEach(h.add,h)}}});var p={result:tF(l),missing:t},b=o.canonizeResults?this.canon.admit(p):(0,iu.J)(p);return b.result&&this.knownResults.set(b.result,r),b},e.prototype.execSubSelectedArrayImpl=function(e){var t,n=this,r=e.field,i=e.array,a=e.enclosingRef,o=e.context,s=new tB;function u(e,n){var r;return e.missing&&(t=s.merge(t,((r={})[n]=e.missing,r))),e.result}return r.selectionSet&&(i=i.filter(o.store.canRead)),i=i.map(function(e,t){return null===e?null:(0,tP.k)(e)?u(n.executeSubSelectedArray({field:r,array:e,enclosingRef:a,context:o}),t):r.selectionSet?u(n.executeSelectionSet({selectionSet:r.selectionSet,objectOrReference:e,enclosingRef:eD(e)?e:a,context:o}),t):(__DEV__&&ij(o.store,r,e),e)}),{result:o.canonizeResults?this.canon.admit(i):i,missing:t}},e}();function iR(e){try{JSON.stringify(e,function(e,t){if("string"==typeof t)throw t;return t})}catch(t){return t}}function ij(e,t,n){if(!t.selectionSet){var r=new Set([n]);r.forEach(function(n){(0,eO.s)(n)&&(__DEV__?(0,Q.kG)(!eD(n),"Missing selection set for object of type ".concat(im(e,n)," returned for query field ").concat(t.name.value)):(0,Q.kG)(!eD(n),6),Object.values(n).forEach(r.add,r))})}}function iF(e){var t=nG("stringifyForDisplay");return JSON.stringify(e,function(e,n){return void 0===n?t:n}).split(JSON.stringify(t)).join("")}var iY=Object.create(null);function iB(e){var t=JSON.stringify(e);return iY[t]||(iY[t]=Object.create(null))}function iU(e){var t=iB(e);return t.keyFieldsFn||(t.keyFieldsFn=function(t,n){var r=function(e,t){return n.readField(t,e)},i=n.keyObject=i$(e,function(e){var i=iW(n.storeObject,e,r);return void 0===i&&t!==n.storeObject&&ic.call(t,e[0])&&(i=iW(t,e,iG)),__DEV__?(0,Q.kG)(void 0!==i,"Missing field '".concat(e.join("."),"' while extracting keyFields from ").concat(JSON.stringify(t))):(0,Q.kG)(void 0!==i,2),i});return"".concat(n.typename,":").concat(JSON.stringify(i))})}function iH(e){var t=iB(e);return t.keyArgsFn||(t.keyArgsFn=function(t,n){var r=n.field,i=n.variables,a=n.fieldName,o=JSON.stringify(i$(e,function(e){var n=e[0],a=n.charAt(0);if("@"===a){if(r&&(0,tP.O)(r.directives)){var o=n.slice(1),s=r.directives.find(function(e){return e.name.value===o}),u=s&&eZ(s,i);return u&&iW(u,e.slice(1))}return}if("$"===a){var c=n.slice(1);if(i&&ic.call(i,c)){var l=e.slice(0);return l[0]=c,iW(i,l)}return}if(t)return iW(t,e)}));return(t||"{}"!==o)&&(a+=":"+o),a})}function i$(e,t){var n=new tB;return iz(e).reduce(function(e,r){var i,a=t(r);if(void 0!==a){for(var o=r.length-1;o>=0;--o)a=((i={})[r[o]]=a,i);e=n.merge(e,a)}return e},Object.create(null))}function iz(e){var t=iB(e);if(!t.paths){var n=t.paths=[],r=[];e.forEach(function(t,i){(0,tP.k)(t)?(iz(t).forEach(function(e){return n.push(r.concat(e))}),r.length=0):(r.push(t),(0,tP.k)(e[i+1])||(n.push(r.slice(0)),r.length=0))})}return t.paths}function iG(e,t){return e[t]}function iW(e,t,n){return n=n||iG,iK(t.reduce(function e(t,r){return(0,tP.k)(t)?t.map(function(t){return e(t,r)}):t&&n(t,r)},e))}function iK(e){return(0,eO.s)(e)?(0,tP.k)(e)?e.map(iK):i$(Object.keys(e).sort(),function(t){return iW(e,t)}):e}function iV(e){return void 0!==e.args?e.args:e.field?eZ(e.field,e.variables):null}eK.setStringify(nx);var iq=function(){},iZ=function(e,t){return t.fieldName},iX=function(e,t,n){return(0,n.mergeObjects)(e,t)},iJ=function(e,t){return t},iQ=function(){function e(e){this.config=e,this.typePolicies=Object.create(null),this.toBeAdded=Object.create(null),this.supertypeMap=new Map,this.fuzzySubtypes=new Map,this.rootIdsByTypename=Object.create(null),this.rootTypenamesById=Object.create(null),this.usingPossibleTypes=!1,this.config=(0,en.pi)({dataIdFromObject:id},e),this.cache=this.config.cache,this.setRootTypename("Query"),this.setRootTypename("Mutation"),this.setRootTypename("Subscription"),e.possibleTypes&&this.addPossibleTypes(e.possibleTypes),e.typePolicies&&this.addTypePolicies(e.typePolicies)}return e.prototype.identify=function(e,t){var n,r,i=this,a=t&&(t.typename||(null===(n=t.storeObject)||void 0===n?void 0:n.__typename))||e.__typename;if(a===this.rootTypenamesById.ROOT_QUERY)return["ROOT_QUERY"];for(var o=t&&t.storeObject||e,s=(0,en.pi)((0,en.pi)({},t),{typename:a,storeObject:o,readField:t&&t.readField||function(){var e=i0(arguments,o);return i.readField(e,{store:i.cache.data,variables:e.variables})}}),u=a&&this.getTypePolicy(a),c=u&&u.keyFn||this.config.dataIdFromObject;c;){var l=c((0,en.pi)((0,en.pi)({},e),o),s);if((0,tP.k)(l))c=iU(l);else{r=l;break}}return r=r?String(r):void 0,s.keyObject?[r,s.keyObject]:[r]},e.prototype.addTypePolicies=function(e){var t=this;Object.keys(e).forEach(function(n){var r=e[n],i=r.queryType,a=r.mutationType,o=r.subscriptionType,s=(0,en._T)(r,["queryType","mutationType","subscriptionType"]);i&&t.setRootTypename("Query",n),a&&t.setRootTypename("Mutation",n),o&&t.setRootTypename("Subscription",n),ic.call(t.toBeAdded,n)?t.toBeAdded[n].push(s):t.toBeAdded[n]=[s]})},e.prototype.updateTypePolicy=function(e,t){var n=this,r=this.getTypePolicy(e),i=t.keyFields,a=t.fields;function o(e,t){e.merge="function"==typeof t?t:!0===t?iX:!1===t?iJ:e.merge}o(r,t.merge),r.keyFn=!1===i?iq:(0,tP.k)(i)?iU(i):"function"==typeof i?i:r.keyFn,a&&Object.keys(a).forEach(function(t){var r=n.getFieldPolicy(e,t,!0),i=a[t];if("function"==typeof i)r.read=i;else{var s=i.keyArgs,u=i.read,c=i.merge;r.keyFn=!1===s?iZ:(0,tP.k)(s)?iH(s):"function"==typeof s?s:r.keyFn,"function"==typeof u&&(r.read=u),o(r,c)}r.read&&r.merge&&(r.keyFn=r.keyFn||iZ)})},e.prototype.setRootTypename=function(e,t){void 0===t&&(t=e);var n="ROOT_"+e.toUpperCase(),r=this.rootTypenamesById[n];t!==r&&(__DEV__?(0,Q.kG)(!r||r===e,"Cannot change root ".concat(e," __typename more than once")):(0,Q.kG)(!r||r===e,3),r&&delete this.rootIdsByTypename[r],this.rootIdsByTypename[t]=n,this.rootTypenamesById[n]=t)},e.prototype.addPossibleTypes=function(e){var t=this;this.usingPossibleTypes=!0,Object.keys(e).forEach(function(n){t.getSupertypeSet(n,!0),e[n].forEach(function(e){t.getSupertypeSet(e,!0).add(n);var r=e.match(ig);r&&r[0]===e||t.fuzzySubtypes.set(e,RegExp(e))})})},e.prototype.getTypePolicy=function(e){var t=this;if(!ic.call(this.typePolicies,e)){var n=this.typePolicies[e]=Object.create(null);n.fields=Object.create(null);var r=this.supertypeMap.get(e);r&&r.size&&r.forEach(function(e){var r=t.getTypePolicy(e),i=r.fields;Object.assign(n,(0,en._T)(r,["fields"])),Object.assign(n.fields,i)})}var i=this.toBeAdded[e];return i&&i.length&&i.splice(0).forEach(function(n){t.updateTypePolicy(e,n)}),this.typePolicies[e]},e.prototype.getFieldPolicy=function(e,t,n){if(e){var r=this.getTypePolicy(e).fields;return r[t]||n&&(r[t]=Object.create(null))}},e.prototype.getSupertypeSet=function(e,t){var n=this.supertypeMap.get(e);return!n&&t&&this.supertypeMap.set(e,n=new Set),n},e.prototype.fragmentMatches=function(e,t,n,r){var i=this;if(!e.typeCondition)return!0;if(!t)return!1;var a=e.typeCondition.name.value;if(t===a)return!0;if(this.usingPossibleTypes&&this.supertypeMap.has(a))for(var o=this.getSupertypeSet(t,!0),s=[o],u=function(e){var t=i.getSupertypeSet(e,!1);t&&t.size&&0>s.indexOf(t)&&s.push(t)},c=!!(n&&this.fuzzySubtypes.size),l=!1,f=0;f1?a:t}:(r=(0,en.pi)({},i),ic.call(r,"from")||(r.from=t)),__DEV__&&void 0===r.from&&__DEV__&&Q.kG.warn("Undefined 'from' passed to readField with arguments ".concat(iF(Array.from(e)))),void 0===r.variables&&(r.variables=n),r}function i2(e){return function(t,n){if((0,tP.k)(t)||(0,tP.k)(n))throw __DEV__?new Q.ej("Cannot automatically merge arrays"):new Q.ej(4);if((0,eO.s)(t)&&(0,eO.s)(n)){var r=e.getFieldValue(t,"__typename"),i=e.getFieldValue(n,"__typename");if(r&&i&&r!==i)return n;if(eD(t)&&iw(n))return e.merge(t.__ref,n),t;if(iw(t)&&eD(n))return e.merge(t,n.__ref),n;if(iw(t)&&iw(n))return(0,en.pi)((0,en.pi)({},t),n)}return n}}function i3(e,t,n){var r="".concat(t).concat(n),i=e.flavors.get(r);return i||e.flavors.set(r,i=e.clientOnly===t&&e.deferred===n?e:(0,en.pi)((0,en.pi)({},e),{clientOnly:t,deferred:n})),i}var i4=function(){function e(e,t,n){this.cache=e,this.reader=t,this.fragments=n}return e.prototype.writeToStore=function(e,t){var n=this,r=t.query,i=t.result,a=t.dataId,o=t.variables,s=t.overwrite,u=e2(r),c=i_();o=(0,en.pi)((0,en.pi)({},e9(u)),o);var l=(0,en.pi)((0,en.pi)({store:e,written:Object.create(null),merge:function(e,t){return c.merge(e,t)},variables:o,varString:nx(o)},iE(r,this.fragments)),{overwrite:!!s,incomingById:new Map,clientOnly:!1,deferred:!1,flavors:new Map}),f=this.processSelectionSet({result:i||Object.create(null),dataId:a,selectionSet:u.selectionSet,mergeTree:{map:new Map},context:l});if(!eD(f))throw __DEV__?new Q.ej("Could not identify object ".concat(JSON.stringify(i))):new Q.ej(7);return l.incomingById.forEach(function(t,r){var i=t.storeObject,a=t.mergeTree,o=t.fieldNodeSet,s=eI(r);if(a&&a.map.size){var u=n.applyMerges(a,s,i,l);if(eD(u))return;i=u}if(__DEV__&&!l.overwrite){var c=Object.create(null);o.forEach(function(e){e.selectionSet&&(c[e.name.value]=!0)});var f=function(e){return!0===c[iv(e)]},d=function(e){var t=a&&a.map.get(e);return Boolean(t&&t.info&&t.info.merge)};Object.keys(i).forEach(function(e){f(e)&&!d(e)&&at(s,i,e,l.store)})}e.merge(r,i)}),e.retain(f.__ref),f},e.prototype.processSelectionSet=function(e){var t=this,n=e.dataId,r=e.result,i=e.selectionSet,a=e.context,o=e.mergeTree,s=this.cache.policies,u=Object.create(null),c=n&&s.rootTypenamesById[n]||eJ(r,i,a.fragmentMap)||n&&a.store.get(n,"__typename");"string"==typeof c&&(u.__typename=c);var l=function(){var e=i0(arguments,u,a.variables);if(eD(e.from)){var t=a.incomingById.get(e.from.__ref);if(t){var n=s.readField((0,en.pi)((0,en.pi)({},e),{from:t.storeObject}),a);if(void 0!==n)return n}}return s.readField(e,a)},f=new Set;this.flattenFields(i,r,a,c).forEach(function(e,n){var i,a=r[eX(n)];if(f.add(n),void 0!==a){var d=s.getStoreFieldName({typename:c,fieldName:n.name.value,field:n,variables:e.variables}),h=i5(o,d),p=t.processFieldValue(a,n,n.selectionSet?i3(e,!1,!1):e,h),b=void 0;n.selectionSet&&(eD(p)||iw(p))&&(b=l("__typename",p));var m=s.getMergeFunction(c,n.name.value,b);m?h.info={field:n,typename:c,merge:m}:i7(o,d),u=e.merge(u,((i={})[d]=p,i))}else __DEV__&&!e.clientOnly&&!e.deferred&&!nj.added(n)&&!s.getReadFunction(c,n.name.value)&&__DEV__&&Q.kG.error("Missing field '".concat(eX(n),"' while writing result ").concat(JSON.stringify(r,null,2)).substring(0,1e3))});try{var d=s.identify(r,{typename:c,selectionSet:i,fragmentMap:a.fragmentMap,storeObject:u,readField:l}),h=d[0],p=d[1];n=n||h,p&&(u=a.merge(u,p))}catch(b){if(!n)throw b}if("string"==typeof n){var m=eI(n),g=a.written[n]||(a.written[n]=[]);if(g.indexOf(i)>=0||(g.push(i),this.reader&&this.reader.isFresh(r,m,i,a)))return m;var v=a.incomingById.get(n);return v?(v.storeObject=a.merge(v.storeObject,u),v.mergeTree=i8(v.mergeTree,o),f.forEach(function(e){return v.fieldNodeSet.add(e)})):a.incomingById.set(n,{storeObject:u,mergeTree:i9(o)?void 0:o,fieldNodeSet:f}),m}return u},e.prototype.processFieldValue=function(e,t,n,r){var i=this;return t.selectionSet&&null!==e?(0,tP.k)(e)?e.map(function(e,a){var o=i.processFieldValue(e,t,n,i5(r,a));return i7(r,a),o}):this.processSelectionSet({result:e,selectionSet:t.selectionSet,context:n,mergeTree:r}):__DEV__?nJ(e):e},e.prototype.flattenFields=function(e,t,n,r){void 0===r&&(r=eJ(t,e,n.fragmentMap));var i=new Map,a=this.cache.policies,o=new n_(!1);return function e(s,u){var c=o.lookup(s,u.clientOnly,u.deferred);c.visited||(c.visited=!0,s.selections.forEach(function(o){if(td(o,n.variables)){var s=u.clientOnly,c=u.deferred;if(!(s&&c)&&(0,tP.O)(o.directives)&&o.directives.forEach(function(e){var t=e.name.value;if("client"===t&&(s=!0),"defer"===t){var r=eZ(e,n.variables);r&&!1===r.if||(c=!0)}}),eQ(o)){var l=i.get(o);l&&(s=s&&l.clientOnly,c=c&&l.deferred),i.set(o,i3(n,s,c))}else{var f=eC(o,n.lookupFragment);if(!f&&o.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(o.name.value)):new Q.ej(8);f&&a.fragmentMatches(f,r,t,n.variables)&&e(f.selectionSet,i3(n,s,c))}}}))}(e,n),i},e.prototype.applyMerges=function(e,t,n,r,i){var a=this;if(e.map.size&&!eD(n)){var o,s,u=!(0,tP.k)(n)&&(eD(t)||iw(t))?t:void 0,c=n;u&&!i&&(i=[eD(u)?u.__ref:u]);var l=function(e,t){return(0,tP.k)(e)?"number"==typeof t?e[t]:void 0:r.store.getFieldValue(e,String(t))};e.map.forEach(function(e,t){var n=l(u,t),o=l(c,t);if(void 0!==o){i&&i.push(t);var f=a.applyMerges(e,n,o,r,i);f!==o&&(s=s||new Map).set(t,f),i&&(0,Q.kG)(i.pop()===t)}}),s&&(n=(0,tP.k)(c)?c.slice(0):(0,en.pi)({},c),s.forEach(function(e,t){n[t]=e}))}return e.info?this.cache.policies.runMergeFunction(t,n,e.info,r,i&&(o=r.store).getStorage.apply(o,i)):n},e}(),i6=[];function i5(e,t){var n=e.map;return n.has(t)||n.set(t,i6.pop()||{map:new Map}),n.get(t)}function i8(e,t){if(e===t||!t||i9(t))return e;if(!e||i9(e))return t;var n=e.info&&t.info?(0,en.pi)((0,en.pi)({},e.info),t.info):e.info||t.info,r=e.map.size&&t.map.size,i=r?new Map:e.map.size?e.map:t.map,a={info:n,map:i};if(r){var o=new Set(t.map.keys());e.map.forEach(function(e,n){a.map.set(n,i8(e,t.map.get(n))),o.delete(n)}),o.forEach(function(n){a.map.set(n,i8(t.map.get(n),e.map.get(n)))})}return a}function i9(e){return!e||!(e.info||e.map.size)}function i7(e,t){var n=e.map,r=n.get(t);r&&i9(r)&&(i6.push(r),n.delete(t))}var ae=new Set;function at(e,t,n,r){var i=function(e){var t=r.getFieldValue(e,n);return"object"==typeof t&&t},a=i(e);if(a){var o=i(t);if(!(!o||eD(a)||(0,nm.D)(a,o)||Object.keys(a).every(function(e){return void 0!==r.getFieldValue(o,e)}))){var s=r.getFieldValue(e,"__typename")||r.getFieldValue(t,"__typename"),u=iv(n),c="".concat(s,".").concat(u);if(!ae.has(c)){ae.add(c);var l=[];(0,tP.k)(a)||(0,tP.k)(o)||[a,o].forEach(function(e){var t=r.getFieldValue(e,"__typename");"string"!=typeof t||l.includes(t)||l.push(t)}),__DEV__&&Q.kG.warn("Cache data may be lost when replacing the ".concat(u," field of a ").concat(s," object.\n\nThis could cause additional (usually avoidable) network requests to fetch data that were otherwise cached.\n\nTo address this problem (which is not a bug in Apollo Client), ").concat(l.length?"either ensure all objects of type "+l.join(" and ")+" have an ID or a custom merge function, or ":"","define a custom merge function for the ").concat(c," field, so InMemoryCache can safely merge these objects:\n\n existing: ").concat(JSON.stringify(a).slice(0,1e3),"\n incoming: ").concat(JSON.stringify(o).slice(0,1e3),"\n\nFor more information about these options, please refer to the documentation:\n\n * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers\n * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects\n"))}}}}var an=function(e){function t(t){void 0===t&&(t={});var n=e.call(this)||this;return n.watches=new Set,n.typenameDocumentCache=new Map,n.makeVar=r2,n.txCount=0,n.config=ip(t),n.addTypename=!!n.config.addTypename,n.policies=new iQ({cache:n,dataIdFromObject:n.config.dataIdFromObject,possibleTypes:n.config.possibleTypes,typePolicies:n.config.typePolicies}),n.init(),n}return(0,en.ZT)(t,e),t.prototype.init=function(){var e=this.data=new iT.Root({policies:this.policies,resultCaching:this.config.resultCaching});this.optimisticData=e.stump,this.resetResultCache()},t.prototype.resetResultCache=function(e){var t=this,n=this.storeReader,r=this.config.fragments;this.storeWriter=new i4(this,this.storeReader=new iP({cache:this,addTypename:this.addTypename,resultCacheMaxSize:this.config.resultCacheMaxSize,canonizeResults:ib(this.config),canon:e?void 0:n&&n.canon,fragments:r}),r),this.maybeBroadcastWatch=rZ(function(e,n){return t.broadcastWatch(e,n)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var n=e.optimistic?t.optimisticData:t.data;if(iD(n)){var r=e.optimistic,i=e.id,a=e.variables;return n.makeCacheKey(e.query,e.callback,nx({optimistic:r,id:i,variables:a}))}}}),new Set([this.data.group,this.optimisticData.group,]).forEach(function(e){return e.resetCaching()})},t.prototype.restore=function(e){return this.init(),e&&this.data.replace(e),this},t.prototype.extract=function(e){return void 0===e&&(e=!1),(e?this.optimisticData:this.data).extract()},t.prototype.read=function(e){var t=e.returnPartialData,n=void 0!==t&&t;try{return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,config:this.config,returnPartialData:n})).result||null}catch(r){if(r instanceof is)return null;throw r}},t.prototype.write=function(e){try{return++this.txCount,this.storeWriter.writeToStore(this.data,e)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.modify=function(e){if(ic.call(e,"id")&&!e.id)return!1;var t=e.optimistic?this.optimisticData:this.data;try{return++this.txCount,t.modify(e.id||"ROOT_QUERY",e.fields)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.diff=function(e){return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,rootId:e.id||"ROOT_QUERY",config:this.config}))},t.prototype.watch=function(e){var t=this;return this.watches.size||r0(this),this.watches.add(e),e.immediate&&this.maybeBroadcastWatch(e),function(){t.watches.delete(e)&&!t.watches.size&&r1(t),t.maybeBroadcastWatch.forget(e)}},t.prototype.gc=function(e){nx.reset();var t=this.optimisticData.gc();return e&&!this.txCount&&(e.resetResultCache?this.resetResultCache(e.resetResultIdentities):e.resetResultIdentities&&this.storeReader.resetCanon()),t},t.prototype.retain=function(e,t){return(t?this.optimisticData:this.data).retain(e)},t.prototype.release=function(e,t){return(t?this.optimisticData:this.data).release(e)},t.prototype.identify=function(e){if(eD(e))return e.__ref;try{return this.policies.identify(e)[0]}catch(t){__DEV__&&Q.kG.warn(t)}},t.prototype.evict=function(e){if(!e.id){if(ic.call(e,"id"))return!1;e=(0,en.pi)((0,en.pi)({},e),{id:"ROOT_QUERY"})}try{return++this.txCount,this.optimisticData.evict(e,this.data)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.reset=function(e){var t=this;return this.init(),nx.reset(),e&&e.discardWatches?(this.watches.forEach(function(e){return t.maybeBroadcastWatch.forget(e)}),this.watches.clear(),r1(this)):this.broadcastWatches(),Promise.resolve()},t.prototype.removeOptimistic=function(e){var t=this.optimisticData.removeLayer(e);t!==this.optimisticData&&(this.optimisticData=t,this.broadcastWatches())},t.prototype.batch=function(e){var t,n=this,r=e.update,i=e.optimistic,a=void 0===i||i,o=e.removeOptimistic,s=e.onWatchUpdated,u=function(e){var i=n,a=i.data,o=i.optimisticData;++n.txCount,e&&(n.data=n.optimisticData=e);try{return t=r(n)}finally{--n.txCount,n.data=a,n.optimisticData=o}},c=new Set;return s&&!this.txCount&&this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e){return c.add(e),!1}})),"string"==typeof a?this.optimisticData=this.optimisticData.addLayer(a,u):!1===a?u(this.data):u(),"string"==typeof o&&(this.optimisticData=this.optimisticData.removeLayer(o)),s&&c.size?(this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e,t){var n=s.call(this,e,t);return!1!==n&&c.delete(e),n}})),c.size&&c.forEach(function(e){return n.maybeBroadcastWatch.dirty(e)})):this.broadcastWatches(e),t},t.prototype.performTransaction=function(e,t){return this.batch({update:e,optimistic:t||null!==t})},t.prototype.transformDocument=function(e){if(this.addTypename){var t=this.typenameDocumentCache.get(e);return t||(t=nj(e),this.typenameDocumentCache.set(e,t),this.typenameDocumentCache.set(t,t)),t}return e},t.prototype.transformForLink=function(e){var t=this.config.fragments;return t?t.transform(e):e},t.prototype.broadcastWatches=function(e){var t=this;this.txCount||this.watches.forEach(function(n){return t.maybeBroadcastWatch(n,e)})},t.prototype.broadcastWatch=function(e,t){var n=e.lastDiff,r=this.diff(e);(!t||(e.optimistic&&"string"==typeof t.optimistic&&(r.fromOptimisticTransaction=!0),!t.onWatchUpdated||!1!==t.onWatchUpdated.call(this,e,r,n)))&&(n&&(0,nm.D)(n.result,r.result)||e.callback(e.lastDiff=r,n))},t}(io),ar={possibleTypes:{ApproveJobProposalSpecPayload:["ApproveJobProposalSpecSuccess","JobAlreadyExistsError","NotFoundError"],BridgePayload:["Bridge","NotFoundError"],CancelJobProposalSpecPayload:["CancelJobProposalSpecSuccess","NotFoundError"],ChainPayload:["Chain","NotFoundError"],CreateAPITokenPayload:["CreateAPITokenSuccess","InputErrors"],CreateBridgePayload:["CreateBridgeSuccess"],CreateCSAKeyPayload:["CSAKeyExistsError","CreateCSAKeySuccess"],CreateFeedsManagerChainConfigPayload:["CreateFeedsManagerChainConfigSuccess","InputErrors","NotFoundError"],CreateFeedsManagerPayload:["CreateFeedsManagerSuccess","InputErrors","NotFoundError","SingleFeedsManagerError"],CreateJobPayload:["CreateJobSuccess","InputErrors"],CreateOCR2KeyBundlePayload:["CreateOCR2KeyBundleSuccess"],CreateOCRKeyBundlePayload:["CreateOCRKeyBundleSuccess"],CreateP2PKeyPayload:["CreateP2PKeySuccess"],DeleteAPITokenPayload:["DeleteAPITokenSuccess","InputErrors"],DeleteBridgePayload:["DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DeleteBridgeSuccess","NotFoundError"],DeleteCSAKeyPayload:["DeleteCSAKeySuccess","NotFoundError"],DeleteFeedsManagerChainConfigPayload:["DeleteFeedsManagerChainConfigSuccess","NotFoundError"],DeleteJobPayload:["DeleteJobSuccess","NotFoundError"],DeleteOCR2KeyBundlePayload:["DeleteOCR2KeyBundleSuccess","NotFoundError"],DeleteOCRKeyBundlePayload:["DeleteOCRKeyBundleSuccess","NotFoundError"],DeleteP2PKeyPayload:["DeleteP2PKeySuccess","NotFoundError"],DeleteVRFKeyPayload:["DeleteVRFKeySuccess","NotFoundError"],DismissJobErrorPayload:["DismissJobErrorSuccess","NotFoundError"],Error:["CSAKeyExistsError","DeleteBridgeConflictError","DeleteBridgeInvalidNameError","InputError","JobAlreadyExistsError","NotFoundError","RunJobCannotRunError","SingleFeedsManagerError"],EthTransactionPayload:["EthTransaction","NotFoundError"],FeaturesPayload:["Features"],FeedsManagerPayload:["FeedsManager","NotFoundError"],GetSQLLoggingPayload:["SQLLogging"],GlobalLogLevelPayload:["GlobalLogLevel"],JobPayload:["Job","NotFoundError"],JobProposalPayload:["JobProposal","NotFoundError"],JobRunPayload:["JobRun","NotFoundError"],JobSpec:["BlockHeaderFeederSpec","BlockhashStoreSpec","BootstrapSpec","CronSpec","DirectRequestSpec","FluxMonitorSpec","GatewaySpec","KeeperSpec","OCR2Spec","OCRSpec","StandardCapabilitiesSpec","VRFSpec","WebhookSpec","WorkflowSpec"],NodePayload:["Node","NotFoundError"],PaginatedPayload:["BridgesPayload","ChainsPayload","EthTransactionAttemptsPayload","EthTransactionsPayload","JobRunsPayload","JobsPayload","NodesPayload"],RejectJobProposalSpecPayload:["NotFoundError","RejectJobProposalSpecSuccess"],RunJobPayload:["NotFoundError","RunJobCannotRunError","RunJobSuccess"],SetGlobalLogLevelPayload:["InputErrors","SetGlobalLogLevelSuccess"],SetSQLLoggingPayload:["SetSQLLoggingSuccess"],SetServicesLogLevelsPayload:["InputErrors","SetServicesLogLevelsSuccess"],UpdateBridgePayload:["NotFoundError","UpdateBridgeSuccess"],UpdateFeedsManagerChainConfigPayload:["InputErrors","NotFoundError","UpdateFeedsManagerChainConfigSuccess"],UpdateFeedsManagerPayload:["InputErrors","NotFoundError","UpdateFeedsManagerSuccess"],UpdateJobProposalSpecDefinitionPayload:["NotFoundError","UpdateJobProposalSpecDefinitionSuccess"],UpdatePasswordPayload:["InputErrors","UpdatePasswordSuccess"],VRFKeyPayload:["NotFoundError","VRFKeySuccess"]}};let ai=ar;var aa=(r=void 0,location.origin),ao=new nh({uri:"".concat(aa,"/query"),credentials:"include"}),as=new ia({cache:new an({possibleTypes:ai.possibleTypes}),link:ao});if(a.Z.locale(o),u().defaultFormat="YYYY-MM-DD h:mm:ss A","undefined"!=typeof document){var au,ac,al=f().hydrate;ac=X,al(c.createElement(et,{client:as},c.createElement(d.zj,null,c.createElement(i.MuiThemeProvider,{theme:J.r},c.createElement(ac,null)))),document.getElementById("root"))}})()})(); \ No newline at end of file +`+(a!==i?`result of cast: ${a}`:""))}return r}_cast(e,t){let n=void 0===e?e:this.transforms.reduce((t,n)=>n.call(this,t,e,this),e);return void 0===n&&(n=this.getDefault()),n}_validate(e,t={},n){let{sync:r,path:i,from:a=[],originalValue:o=e,strict:s=this.spec.strict,abortEarly:u=this.spec.abortEarly}=t,c=e;s||(c=this._cast(c,pB({assert:!1},t)));let l={value:c,path:i,options:t,originalValue:o,schema:this,label:this.spec.label,sync:r,from:a},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),pO({args:l,value:c,path:i,sync:r,tests:f,endEarly:u},e=>{if(e)return void n(e,c);pO({tests:this.tests,args:l,path:i,sync:r,value:c,endEarly:u},n)})}validate(e,t,n){let r=this.resolve(pB({},t,{value:e}));return"function"==typeof n?r._validate(e,t,n):new Promise((n,i)=>r._validate(e,t,(e,t)=>{e?i(e):n(t)}))}validateSync(e,t){let n;return this.resolve(pB({},t,{value:e}))._validate(e,pB({},t,{sync:!0}),(e,t)=>{if(e)throw e;n=t}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,e=>{if(pT.isError(e))return!1;throw e})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(n){if(pT.isError(n))return!1;throw n}}_getDefault(){let e=this.spec.default;return null==e?e:"function"==typeof e?e.call(this):pn(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return 0===arguments.length?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return null!=e}defined(e=pf.defined){return this.test({message:e,name:"defined",exclusive:!0,test:e=>void 0!==e})}required(e=pf.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(e){return this.schema._isPresent(e)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(e=>"required"!==e.OPTIONS.name),e}nullable(e=!0){return this.clone({nullable:!1!==e})}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(void 0===(t=1===e.length?"function"==typeof e[0]?{test:e[0]}:e[0]:2===e.length?{name:e[0],test:e[1]}:{name:e[0],message:e[1],test:e[2]}).message&&(t.message=pf.default),"function"!=typeof t.test)throw TypeError("`test` is a required parameters");let n=this.clone(),r=pR(t),i=t.exclusive||t.name&&!0===n.exclusiveTests[t.name];if(t.exclusive&&!t.name)throw TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(n.exclusiveTests[t.name]=!!t.exclusive),n.tests=n.tests.filter(e=>e.OPTIONS.name!==t.name||!i&&e.OPTIONS.test!==r.OPTIONS.test),n.tests.push(r),n}when(e,t){Array.isArray(e)||"string"==typeof e||(t=e,e=".");let n=this.clone(),r=pS(e).map(e=>new pD(e));return r.forEach(e=>{e.isSibling&&n.deps.push(e.key)}),n.conditions.push(new pE(r,t)),n}typeError(e){var t=this.clone();return t._typeError=pR({message:e,name:"typeError",test(e){return!!(void 0===e||this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t}oneOf(e,t=pf.oneOf){var n=this.clone();return e.forEach(e=>{n._whitelist.add(e),n._blacklist.delete(e)}),n._whitelistError=pR({message:t,name:"oneOf",test(e){if(void 0===e)return!0;let t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}notOneOf(e,t=pf.notOneOf){var n=this.clone();return e.forEach(e=>{n._blacklist.add(e),n._whitelist.delete(e)}),n._blacklistError=pR({message:t,name:"notOneOf",test(e){let t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:n}=e.spec,r={meta:n,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(e=>({name:e.OPTIONS.name,params:e.OPTIONS.params})).filter((e,t,n)=>n.findIndex(t=>t.name===e.name)===t)};return r}}for(let pH of(pU.prototype.__isYupSchema__=!0,["validate","validateSync"]))pU.prototype[`${pH}At`]=function(e,t,n={}){let{parent:r,parentPath:i,schema:a}=pF(this,e,t,n.context);return a[pH](r&&r[i],pB({},n,{parent:r,path:e}))};for(let p$ of["equals","is"])pU.prototype[p$]=pU.prototype.oneOf;for(let pz of["not","nope"])pU.prototype[pz]=pU.prototype.notOneOf;pU.prototype.optional=pU.prototype.notRequired;let pG=pU;function pW(){return new pG}pW.prototype=pG.prototype;let pK=e=>null==e;function pV(){return new pq}class pq extends pU{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}isTrue(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test:e=>pK(e)||!0===e})}isFalse(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test:e=>pK(e)||!1===e})}}pV.prototype=pq.prototype;let pZ=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,pX=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,pJ=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,pQ=e=>pK(e)||e===e.trim(),p1=({}).toString();function p0(){return new p2}class p2 extends pU{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=null!=e&&e.toString?e.toString():e;return t===p1?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=pd.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t=pd.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t=pd.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}matches(e,t){let n=!1,r,i;return t&&("object"==typeof t?{excludeEmptyString:n=!1,message:r,name:i}=t:r=t),this.test({name:i||"matches",message:r||pd.matches,params:{regex:e},test:t=>pK(t)||""===t&&n||-1!==t.search(e)})}email(e=pd.email){return this.matches(pZ,{name:"email",message:e,excludeEmptyString:!0})}url(e=pd.url){return this.matches(pX,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=pd.uuid){return this.matches(pJ,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>null===e?"":e)}trim(e=pd.trim){return this.transform(e=>null!=e?e.trim():e).test({message:e,name:"trim",test:pQ})}lowercase(e=pd.lowercase){return this.transform(e=>pK(e)?e:e.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toLowerCase()})}uppercase(e=pd.uppercase){return this.transform(e=>pK(e)?e:e.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toUpperCase()})}}p0.prototype=p2.prototype;let p3=e=>e!=+e;function p4(){return new p6}class p6 extends pU{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!p3(e)}min(e,t=ph.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t>=this.resolve(e)}})}max(e,t=ph.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t<=this.resolve(e)}})}lessThan(e,t=ph.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(t){return pK(t)||tthis.resolve(e)}})}positive(e=ph.positive){return this.moreThan(0,e)}negative(e=ph.negative){return this.lessThan(0,e)}integer(e=ph.integer){return this.test({name:"integer",message:e,test:e=>pK(e)||Number.isInteger(e)})}truncate(){return this.transform(e=>pK(e)?e:0|e)}round(e){var t,n=["ceil","floor","round","trunc"];if("trunc"===(e=(null==(t=e)?void 0:t.toLowerCase())||"round"))return this.truncate();if(-1===n.indexOf(e.toLowerCase()))throw TypeError("Only valid options for round() are: "+n.join(", "));return this.transform(t=>pK(t)?t:Math[e](t))}}p4.prototype=p6.prototype;var p5=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function p8(e){var t,n,r=[1,4,5,6,7,10,11],i=0;if(n=p5.exec(e)){for(var a,o=0;a=r[o];++o)n[a]=+n[a]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(void 0===n[8]||""===n[8])&&(void 0===n[9]||""===n[9])?t=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):("Z"!==n[8]&&void 0!==n[9]&&(i=60*n[10]+n[11],"+"===n[9]&&(i=0-i)),t=Date.UTC(n[1],n[2],n[3],n[4],n[5]+i,n[6],n[7]))}else t=Date.parse?Date.parse(e):NaN;return t}let p9=new Date(""),p7=e=>"[object Date]"===Object.prototype.toString.call(e);function be(){return new bt}class bt extends pU{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=p8(e),isNaN(e)?p9:new Date(e))})})}_typeCheck(e){return p7(e)&&!isNaN(e.getTime())}prepareParam(e,t){let n;if(pD.isRef(e))n=e;else{let r=this.cast(e);if(!this._typeCheck(r))throw TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);n=r}return n}min(e,t=pp.min){let n=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(e){return pK(e)||e>=this.resolve(n)}})}max(e,t=pp.max){var n=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(e){return pK(e)||e<=this.resolve(n)}})}}bt.INVALID_DATE=p9,be.prototype=bt.prototype,be.INVALID_DATE=p9;var bn=n(11865),br=n.n(bn),bi=n(68929),ba=n.n(bi),bo=n(67523),bs=n.n(bo),bu=n(94633),bc=n.n(bu);function bl(e,t=[]){let n=[],r=[];function i(e,i){var a=(0,pC.split)(e)[0];~r.indexOf(a)||r.push(a),~t.indexOf(`${i}-${a}`)||n.push([i,a])}for(let a in e)if(py()(e,a)){let o=e[a];~r.indexOf(a)||r.push(a),pD.isRef(o)&&o.isSibling?i(o.path,a):pw(o)&&"deps"in o&&o.deps.forEach(e=>i(e,a))}return bc().array(r,n).reverse()}function bf(e,t){let n=1/0;return e.some((e,r)=>{var i;if((null==(i=t.path)?void 0:i.indexOf(e))!==-1)return n=r,!0}),n}function bd(e){return(t,n)=>bf(e,t)-bf(e,n)}function bh(){return(bh=Object.assign||function(e){for(var t=1;t"[object Object]"===Object.prototype.toString.call(e);function bb(e,t){let n=Object.keys(e.fields);return Object.keys(t).filter(e=>-1===n.indexOf(e))}let bm=bd([]);class bg extends pU{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=bm,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null}),e&&this.shape(e)})}_typeCheck(e){return bp(e)||"function"==typeof e}_cast(e,t={}){var n;let r=super._cast(e,t);if(void 0===r)return this.getDefault();if(!this._typeCheck(r))return r;let i=this.fields,a=null!=(n=t.stripUnknown)?n:this.spec.noUnknown,o=this._nodes.concat(Object.keys(r).filter(e=>-1===this._nodes.indexOf(e))),s={},u=bh({},t,{parent:s,__validating:t.__validating||!1}),c=!1;for(let l of o){let f=i[l],d=py()(r,l);if(f){let h,p=r[l];u.path=(t.path?`${t.path}.`:"")+l;let b="spec"in(f=f.resolve({value:p,context:t.context,parent:s}))?f.spec:void 0,m=null==b?void 0:b.strict;if(null==b?void 0:b.strip){c=c||l in r;continue}void 0!==(h=t.__validating&&m?r[l]:f.cast(r[l],u))&&(s[l]=h)}else d&&!a&&(s[l]=r[l]);s[l]!==r[l]&&(c=!0)}return c?s:r}_validate(e,t={},n){let r=[],{sync:i,from:a=[],originalValue:o=e,abortEarly:s=this.spec.abortEarly,recursive:u=this.spec.recursive}=t;a=[{schema:this,value:o},...a],t.__validating=!0,t.originalValue=o,t.from=a,super._validate(e,t,(e,c)=>{if(e){if(!pT.isError(e)||s)return void n(e,c);r.push(e)}if(!u||!bp(c)){n(r[0]||null,c);return}o=o||c;let l=this._nodes.map(e=>(n,r)=>{let i=-1===e.indexOf(".")?(t.path?`${t.path}.`:"")+e:`${t.path||""}["${e}"]`,s=this.fields[e];if(s&&"validate"in s){s.validate(c[e],bh({},t,{path:i,from:a,strict:!0,parent:c,originalValue:o[e]}),r);return}r(null)});pO({sync:i,tests:l,value:c,errors:r,endEarly:s,sort:this._sortErrors,path:t.path},n)})}clone(e){let t=super.clone(e);return t.fields=bh({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),n=t.fields;for(let[r,i]of Object.entries(this.fields)){let a=n[r];void 0===a?n[r]=i:a instanceof pU&&i instanceof pU&&(n[r]=i.concat(a))}return t.withMutation(()=>t.shape(n))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let n=this.fields[t];e[t]="default"in n?n.getDefault():void 0}),e}_getDefault(){return"default"in this.spec?super._getDefault():this._nodes.length?this.getDefaultFromShape():void 0}shape(e,t=[]){let n=this.clone(),r=Object.assign(n.fields,e);if(n.fields=r,n._sortErrors=bd(Object.keys(r)),t.length){Array.isArray(t[0])||(t=[t]);let i=t.map(([e,t])=>`${e}-${t}`);n._excludedEdges=n._excludedEdges.concat(i)}return n._nodes=bl(r,n._excludedEdges),n}pick(e){let t={};for(let n of e)this.fields[n]&&(t[n]=this.fields[n]);return this.clone().withMutation(e=>(e.fields={},e.shape(t)))}omit(e){let t=this.clone(),n=t.fields;for(let r of(t.fields={},e))delete n[r];return t.withMutation(()=>t.shape(n))}from(e,t,n){let r=(0,pC.getter)(e,!0);return this.transform(i=>{if(null==i)return i;let a=i;return py()(i,e)&&(a=bh({},i),n||delete a[e],a[t]=r(i)),a})}noUnknown(e=!0,t=pm.noUnknown){"string"==typeof e&&(t=e,e=!0);let n=this.test({name:"noUnknown",exclusive:!0,message:t,test(t){if(null==t)return!0;let n=bb(this.schema,t);return!e||0===n.length||this.createError({params:{unknown:n.join(", ")}})}});return n.spec.noUnknown=e,n}unknown(e=!0,t=pm.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&bs()(t,(t,n)=>e(n)))}camelCase(){return this.transformKeys(ba())}snakeCase(){return this.transformKeys(br())}constantCase(){return this.transformKeys(e=>br()(e).toUpperCase())}describe(){let e=super.describe();return e.fields=pL()(this.fields,e=>e.describe()),e}}function bv(e){return new bg(e)}function by(){return(by=Object.assign||function(e){for(var t=1;t{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let n=super._cast(e,t);if(!this._typeCheck(n)||!this.innerType)return n;let r=!1,i=n.map((e,n)=>{let i=this.innerType.cast(e,by({},t,{path:`${t.path||""}[${n}]`}));return i!==e&&(r=!0),i});return r?i:n}_validate(e,t={},n){var r,i;let a=[],o=t.sync,s=t.path,u=this.innerType,c=null!=(r=t.abortEarly)?r:this.spec.abortEarly,l=null!=(i=t.recursive)?i:this.spec.recursive,f=null!=t.originalValue?t.originalValue:e;super._validate(e,t,(e,r)=>{if(e){if(!pT.isError(e)||c)return void n(e,r);a.push(e)}if(!l||!u||!this._typeCheck(r)){n(a[0]||null,r);return}f=f||r;let i=Array(r.length);for(let d=0;du.validate(h,b,t)}pO({sync:o,path:s,value:r,errors:a,endEarly:c,tests:i},n)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!pw(e))throw TypeError("`array.of()` sub-schema must be a valid yup schema not: "+pl(e));return t.innerType=e,t}length(e,t=pg.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t){return t=t||pg.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t){return t=t||pg.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:null==t?[]:[].concat(t))}compact(e){let t=e?(t,n,r)=>!e(t,n,r):e=>!!e;return this.transform(e=>null!=e?e.filter(t):e)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}}bw.prototype=b_.prototype;var bE=bv().shape({name:p0().required("Required"),url:p0().required("Required")}),bS=function(e){var t=e.initialValues,n=e.onSubmit,r=e.submitButtonText,i=e.nameDisabled,a=void 0!==i&&i;return l.createElement(hT,{initialValues:t,validationSchema:bE,onSubmit:n},function(e){var t=e.isSubmitting;return l.createElement(l.Fragment,null,l.createElement(hR,{"data-testid":"bridge-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",disabled:a,required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"url",name:"url",label:"Bridge URL",placeholder:"https://",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"url-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"minimumContractPayment",name:"minimumContractPayment",label:"Minimum Contract Payment",placeholder:"0",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"minimumContractPayment-helper-text"}})),l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"confirmations",name:"confirmations",label:"Confirmations",placeholder:"0",type:"number",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"confirmations-helper-text"}})))),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},r)))))})},bk=function(e){var t=e.bridge,n=e.onSubmit,r={name:t.name,url:t.url,minimumContractPayment:t.minimumContractPayment,confirmations:t.confirmations};return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:40},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Bridge",action:l.createElement(aA.Z,{component:tz,href:"/bridges/".concat(t.id)},"Cancel")}),l.createElement(aW.Z,null,l.createElement(bS,{nameDisabled:!0,initialValues:r,onSubmit:n,submitButtonText:"Save Bridge"}))))))};function bx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]&&arguments[0],t=e?function(){return l.createElement(x.default,{variant:"body1"},"Loading...")}:function(){return null};return{isLoading:e,LoadingPlaceholder:t}},mc=n(76023);function ml(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function mB(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=4?[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]:void 0}var mZ={};function mX(e){if(0===e.length||1===e.length)return e;var t=e.join(".");return mZ[t]||(mZ[t]=mq(e)),mZ[t]}function mJ(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return mX(e.filter(function(e){return"token"!==e})).reduce(function(e,t){return mK({},e,n[t])},t)}function mQ(e){return e.join(" ")}function m1(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return m0({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(i)})})}}function m0(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,o=e.key,s=t.properties,u=t.type,c=t.tagName,f=t.value;if("text"===u)return f;if(c){var d,h=m1(n,a);if(a){var p=Object.keys(n).reduce(function(e,t){return t.split(".").forEach(function(t){e.includes(t)||e.push(t)}),e},[]),b=s.className&&s.className.includes("token")?["token"]:[],m=s.className&&b.concat(s.className.filter(function(e){return!p.includes(e)}));d=mK({},s,{className:mQ(m)||void 0,style:mJ(s.className,Object.assign({},s.style,i),n)})}else d=mK({},s,{className:mQ(s.className)});var g=h(t.children);return l.createElement(c,(0,mV.Z)({key:o},d),g)}}let m2=function(e,t){return -1!==e.listLanguages().indexOf(t)};var m3=/\n/g;function m4(e){return e.match(m3)}function m6(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return l.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof r?r(i):r},"".concat(i,"\n"))})}function m5(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,o=void 0===a?{}:a,s=e.startingLineNumber;return l.createElement("code",{style:Object.assign({},n,i)},m6({lines:t.replace(/\n$/,"").split("\n"),style:o,startingLineNumber:s}))}function m8(e){return"".concat(e.toString().length,".25em")}function m9(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function m7(e,t,n){var r,i={display:"inline-block",minWidth:m8(n),paddingRight:"1em",textAlign:"right",userSelect:"none"};return mK({},i,"function"==typeof e?e(t):e)}function ge(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=void 0===o?{}:o,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,f=e.wrapLongLines,d="function"==typeof s?s(n):s;if(d.className=c,n&&a){var h=m7(r,n,i);t.unshift(m9(n,h))}return f&l&&(d.style=mK({},d.style,{display:"flex"})),{type:"element",tagName:"span",properties:d,children:t}}function gt(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return ge({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:a,showLineNumbers:r,wrapLongLines:u})}function b(e,t){if(r&&t&&i){var n=m7(s,t,o);e.unshift(m9(t,n))}return e}function m(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||r.length>0?p(e,n,r):b(e,n)}for(var g=function(){var e=l[h],t=e.children[0].value;if(m4(t)){var n=t.split("\n");n.forEach(function(t,i){var o=r&&f.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===i){var u=l.slice(d+1,h).concat(ge({children:[s],className:e.properties.className})),c=m(u,o);f.push(c)}else if(i===n.length-1){if(l[h+1]&&l[h+1].children&&l[h+1].children[0]){var p={type:"text",value:"".concat(t)},b=ge({children:[p],className:e.properties.className});l.splice(h+1,0,b)}else{var g=[s],v=m(g,o,e.properties.className);f.push(v)}}else{var y=[s],w=m(y,o,e.properties.className);f.push(w)}}),d=h}h++};h code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}};var gu=n(98695),gc=n.n(gu);let gl=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];var gf=go(gc(),gs);gf.supportedLanguages=gl;let gd=gf;var gh=n(64566);function gp(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function gb(){var e=gp(["\n query FetchConfigV2 {\n configv2 {\n user\n effective\n }\n }\n"]);return gb=function(){return e},e}var gm=n0(gb()),gg=function(e){var t=e.children;return l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},t))},gv=function(){return l.createElement(gg,null,"...")},gy=function(e){var t=e.children;return l.createElement(gg,null,t)},gw=function(e){var t=e.loading,n=e.toml,r=e.error,i=void 0===r?"":r,a=e.title,o=e.expanded;if(i)return l.createElement(gy,null,i);if(t)return l.createElement(gv,null);a||(a="TOML");var s={display:"block"};return l.createElement(x.default,null,l.createElement(mP.Z,{defaultExpanded:o},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},a),l.createElement(mj.Z,{style:s},l.createElement(gd,{language:"toml",style:gs},n))))},g_=function(){var e=rv(gm,{fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return(null==t?void 0:t.configv2.effective)=="N/A"?l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"V2 config dump:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0})))):l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"User specified:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0,expanded:!0}),l.createElement(gw,{title:"Effective (with defaults):",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.effective,showHead:!0})))))},gE=n(34823),gS=function(e){return(0,b.createStyles)({cell:{paddingTop:1.5*e.spacing.unit,paddingBottom:1.5*e.spacing.unit}})},gk=(0,b.withStyles)(gS)(function(e){var t=e.classes,n=(0,A.I0)();(0,l.useEffect)(function(){n((0,ty.DQ)())});var r=(0,A.v9)(gE.N,A.wU);return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Node"}),l.createElement(r8.Z,null,l.createElement(r9.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"Version"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.version))),l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"SHA"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.commitSHA))))))}),gx=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,sm:12,md:8},l.createElement(d.Z,{container:!0},l.createElement(g_,null))),l.createElement(d.Z,{item:!0,sm:12,md:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gk,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mN,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mE,null))))))},gT=function(){return l.createElement(gx,null)},gM=function(){return l.createElement(gT,null)},gO=n(44431),gA=1e18,gL=function(e){return new gO.BigNumber(e).dividedBy(gA).toFixed(8)},gC=function(e){var t=e.keys,n=e.chainID,r=e.hideHeaderTitle;return l.createElement(l.Fragment,null,l.createElement(sl.Z,{title:!r&&"Account Balances",subheader:"Chain ID "+n}),l.createElement(aW.Z,null,l.createElement(w.default,{dense:!1,disablePadding:!0},t&&t.map(function(e,r){return l.createElement(l.Fragment,null,l.createElement(_.default,{disableGutters:!0,key:["acc-balance",n.toString(),r.toString()].join("-")},l.createElement(E.Z,{primary:l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(op,{title:"Address"}),l.createElement(ob,{value:e.address})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"Native Token Balance"}),l.createElement(ob,{value:e.ethBalance||"--"})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"LINK Balance"}),l.createElement(ob,{value:e.linkBalance?gL(e.linkBalance):"--"}))))})),r+1s&&l.createElement(gB.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:r.footer},l.createElement(aA.Z,{href:"/runs",component:tz},"View More"))))))});function vt(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vn(){var e=vt(["\n ","\n query FetchRecentJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...RecentJobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return vn=function(){return e},e}var vr=5,vi=n0(vn(),g9),va=function(){var e=rv(vi,{variables:{offset:0,limit:vr},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(ve,{data:t,errorMsg:null==r?void 0:r.message,loading:n,maxRunsSize:vr})},vo=function(e){return(0,b.createStyles)({style:{textAlign:"center",padding:2.5*e.spacing.unit,position:"fixed",left:"0",bottom:"0",width:"100%",borderRadius:0},bareAnchor:{color:e.palette.common.black,textDecoration:"none"}})},vs=(0,b.withStyles)(vo)(function(e){var t=e.classes,n=(0,A.v9)(gE.N,A.wU),r=(0,A.I0)();return(0,l.useEffect)(function(){r((0,ty.DQ)())}),l.createElement(ii.default,{className:t.style},l.createElement(x.default,null,"Chainlink Node ",n.version," at commit"," ",l.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/smartcontractkit/chainlink/commit/".concat(n.commitSHA),className:t.bareAnchor},n.commitSHA)))}),vu=function(e){return(0,b.createStyles)({cell:{borderColor:e.palette.divider,borderTop:"1px solid",borderBottom:"none",paddingTop:2*e.spacing.unit,paddingBottom:2*e.spacing.unit,paddingLeft:2*e.spacing.unit},block:{display:"block"},overflowEllipsis:{textOverflow:"ellipsis",overflow:"hidden"}})},vc=(0,b.withStyles)(vu)(function(e){var t=e.classes,n=e.job;return l.createElement(ir.Z,null,l.createElement(r7.default,{scope:"row",className:t.cell},l.createElement(d.Z,{container:!0,spacing:0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ih,{href:"/jobs/".concat(n.id),classes:{linkContent:t.block}},l.createElement(x.default,{className:t.overflowEllipsis,variant:"body1",component:"span",color:"primary"},n.name||n.id))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,{variant:"body1",color:"textSecondary"},"Created ",l.createElement(aO,{tooltip:!0},n.createdAt))))))});function vl(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vf(){var e=vl(["\n fragment RecentJobsPayload_ResultsFields on Job {\n id\n name\n createdAt\n }\n"]);return vf=function(){return e},e}var vd=n0(vf()),vh=function(){return(0,b.createStyles)({cardHeader:{borderBottom:0},table:{tableLayout:"fixed"}})},vp=(0,b.withStyles)(vh)(function(e){var t,n,r=e.classes,i=e.data,a=e.errorMsg,o=e.loading;return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Recent Jobs",className:r.cardHeader}),l.createElement(r8.Z,{className:r.table},l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(t=null==i?void 0:i.jobs.results)||void 0===t?void 0:t.length)===0},"No recently created jobs"),l.createElement(gU,{msg:a}),null===(n=null==i?void 0:i.jobs.results)||void 0===n?void 0:n.map(function(e,t){return l.createElement(vc,{job:e,key:t})}))))});function vb(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vm(){var e=vb(["\n ","\n query FetchRecentJobs($offset: Int, $limit: Int) {\n jobs(offset: $offset, limit: $limit) {\n results {\n ...RecentJobsPayload_ResultsFields\n }\n }\n }\n"]);return vm=function(){return e},e}var vg=5,vv=n0(vm(),vd),vy=function(){var e=rv(vv,{variables:{offset:0,limit:vg},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vp,{data:t,errorMsg:null==r?void 0:r.message,loading:n})},vw=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:8},l.createElement(va,null)),l.createElement(d.Z,{item:!0,xs:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gY,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(vy,null))))),l.createElement(vs,null))},v_=function(){return l.createElement(vw,null)},vE=function(){return l.createElement(v_,null)},vS=n(87239),vk=function(e){switch(e){case"DirectRequestSpec":return"Direct Request";case"FluxMonitorSpec":return"Flux Monitor";default:return e.replace(/Spec$/,"")}},vx=n(5022),vT=n(78718),vM=n.n(vT);function vO(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1?t-1:0),r=1;r1?t-1:0),r=1;re.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&n.map(function(e){return l.createElement(ir.Z,{key:e.id,style:{cursor:"pointer"},onClick:function(){return r.push("/runs/".concat(e.id))}},l.createElement(r7.default,{className:t.idCell,scope:"row"},l.createElement("div",{className:t.runDetails},l.createElement(x.default,{variant:"h5",color:"primary",component:"span"},e.id))),l.createElement(r7.default,{className:t.stampCell},l.createElement(x.default,{variant:"body1",color:"textSecondary",className:t.stamp},"Created ",l.createElement(aO,{tooltip:!0},e.createdAt))),l.createElement(r7.default,{className:t.statusCell,scope:"row"},l.createElement(x.default,{variant:"body1",className:O()(t.status,yh(t,e.status))},e.status.toLowerCase())))})))}),yb=n(16839),ym=n.n(yb);function yg(e){var t=e.replace(/\w+\s*=\s*<([^>]|[\r\n])*>/g,""),n=ym().read(t),r=n.edges();return n.nodes().map(function(e){var t={id:e,parentIds:r.filter(function(t){return t.w===e}).map(function(e){return e.v})};return Object.keys(n.node(e)).length>0&&(t.attributes=n.node(e)),t})}var yv=n(94164),yy=function(e){var t=e.data,n=[];return(null==t?void 0:t.attributes)&&Object.keys(t.attributes).forEach(function(e){var r;n.push(l.createElement("div",{key:e},l.createElement(x.default,{variant:"body1",color:"textSecondary",component:"div"},l.createElement("b",null,e,":")," ",null===(r=t.attributes)||void 0===r?void 0:r[e])))}),l.createElement("div",null,t&&l.createElement(x.default,{variant:"body1",color:"textPrimary"},l.createElement("b",null,t.id)),n)},yw=n(73343),y_=n(3379),yE=n.n(y_);function yS(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nwindow.innerWidth?u-r.getBoundingClientRect().width-a:u+a,n=c+r.getBoundingClientRect().height+i>window.innerHeight?c-r.getBoundingClientRect().height-a:c+a,r.style.opacity=String(1),r.style.top="".concat(n,"px"),r.style.left="".concat(t,"px"),r.style.zIndex=String(1)}},h=function(e){var t=document.getElementById("tooltip-d3-chart-".concat(e));t&&(t.style.opacity=String(0),t.style.zIndex=String(-1))};return l.createElement("div",{style:{fontFamily:"sans-serif",fontWeight:"normal"}},l.createElement(yv.kJ,{id:"task-list-graph-d3",data:i,config:s,onMouseOverNode:d,onMouseOutNode:h},"D3 chart"),n.map(function(e){return l.createElement("div",{key:"d3-tooltip-key-".concat(e.id),id:"tooltip-d3-chart-".concat(e.id),style:{position:"absolute",opacity:"0",border:"1px solid rgba(0, 0, 0, 0.1)",padding:yw.r.spacing.unit,background:"white",borderRadius:5,zIndex:-1,inlineSize:"min-content"}},l.createElement(yy,{data:e}))}))};function yL(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nyY&&l.createElement("div",{className:t.runDetails},l.createElement(aA.Z,{href:"/jobs/".concat(n.id,"/runs"),component:tz},"View more")))),l.createElement(d.Z,{item:!0,xs:12,sm:6},l.createElement(yF,{observationSource:n.observationSource})))});function yH(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:"";try{return vx.parse(e),!0}catch(t){return!1}})}),wW=function(e){var t=e.initialValues,n=e.onSubmit,r=e.onTOMLChange;return l.createElement(hT,{initialValues:t,validationSchema:wG,onSubmit:n},function(e){var t=e.isSubmitting,n=e.values;return r&&r(n.toml),l.createElement(hR,{"data-testid":"job-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"toml",name:"toml",label:"Job Spec (TOML)",required:!0,fullWidth:!0,multiline:!0,rows:10,rowsMax:25,variant:"outlined",autoComplete:"off",FormHelperTextProps:{"data-testid":"toml-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},"Create Job"))))})},wK=n(50109),wV="persistSpec";function wq(e){var t=e.query,n=new URLSearchParams(t).get("definition");return n?(wK.t8(wV,n),{toml:n}):{toml:wK.U2(wV)||""}}var wZ=function(e){var t=e.onSubmit,n=e.onTOMLChange,r=wq({query:(0,h.TH)().search}),i=function(e){var t=e.replace(/[\u200B-\u200D\uFEFF]/g,"");wK.t8("".concat(wV),t),n&&n(t)};return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"New Job"}),l.createElement(aW.Z,null,l.createElement(wW,{initialValues:r,onSubmit:t,onTOMLChange:i})))};function wX(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=t.start,r=void 0===n?6:n,i=t.end,a=void 0===i?4:i;return e.substring(0,r)+"..."+e.substring(e.length-a)}function _M(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(_W,e)},_V=function(){var e=_K({fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error,i=e.refetch;return l.createElement(_U,{loading:n,data:t,errorMsg:null==r?void 0:r.message,refetch:i})},_q=function(e){var t=e.csaKey;return l.createElement(ir.Z,{hover:!0},l.createElement(r7.default,null,l.createElement(x.default,{variant:"body1"},t.publicKey," ",l.createElement(_x,{data:t.publicKey}))))};function _Z(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function _X(){var e=_Z(["\n fragment CSAKeysPayload_ResultsFields on CSAKey {\n id\n publicKey\n }\n"]);return _X=function(){return e},e}var _J=n0(_X()),_Q=function(e){var t,n,r,i=e.data,a=e.errorMsg,o=e.loading,s=e.onCreate;return l.createElement(r5.Z,null,l.createElement(sl.Z,{action:(null===(t=null==i?void 0:i.csaKeys.results)||void 0===t?void 0:t.length)===0&&l.createElement(ok.default,{variant:"outlined",color:"primary",onClick:s},"New CSA Key"),title:"CSA Key",subheader:"Manage your CSA Key"}),l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Public Key"))),l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(n=null==i?void 0:i.csaKeys.results)||void 0===n?void 0:n.length)===0}),l.createElement(gU,{msg:a}),null===(r=null==i?void 0:i.csaKeys.results)||void 0===r?void 0:r.map(function(e,t){return l.createElement(_q,{csaKey:e,key:t})}))))};function _1(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EM,e)};function EA(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EJ,e)},E3=function(){return oo(EQ)},E4=function(){return oo(E1)},E6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(E0,e)};function E5(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(SK,e)};function Sq(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function kV(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}var kq=function(e){var t=e.run,n=l.useMemo(function(){var e=t.inputs,n=t.outputs,r=t.taskRuns,i=kK(t,["inputs","outputs","taskRuns"]),a={};try{a=JSON.parse(e)}catch(o){a={}}return kW(kz({},i),{inputs:a,outputs:n,taskRuns:r})},[t]);return l.createElement(r5.Z,null,l.createElement(aW.Z,null,l.createElement(kH,{object:n})))};function kZ(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kX(e){for(var t=1;t0&&l.createElement(kr,{errors:t.allErrors})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(h.rs,null,l.createElement(h.AW,{path:"".concat(n,"/json")},l.createElement(kq,{run:t})),l.createElement(h.AW,{path:n},t.taskRuns.length>0&&l.createElement(kN,{taskRuns:t.taskRuns,observationSource:t.job.observationSource}))))))))};function k5(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function k8(){var e=k5(["\n ","\n query FetchJobRun($id: ID!) {\n jobRun(id: $id) {\n __typename\n ... on JobRun {\n ...JobRunPayload_Fields\n }\n ... on NotFoundError {\n message\n }\n }\n }\n"]);return k8=function(){return e},e}var k9=n0(k8(),k4),k7=function(){var e=rv(k9,{variables:{id:(0,h.UO)().id}}),t=e.data,n=e.loading,r=e.error;if(n)return l.createElement(iR,null);if(r)return l.createElement(iD,{error:r});var i=null==t?void 0:t.jobRun;switch(null==i?void 0:i.__typename){case"JobRun":return l.createElement(k6,{run:i});case"NotFoundError":return l.createElement(oa,null);default:return null}};function xe(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xt(){var e=xe(["\n fragment JobRunsPayload_ResultsFields on JobRun {\n id\n allErrors\n createdAt\n finishedAt\n status\n job {\n id\n }\n }\n"]);return xt=function(){return e},e}var xn=n0(xt()),xr=function(e){var t=e.loading,n=e.data,r=e.page,i=e.pageSize,a=(0,h.k6)(),o=l.useMemo(function(){return null==n?void 0:n.jobRuns.results.map(function(e){var t,n=e.allErrors,r=e.id,i=e.createdAt;return{id:r,createdAt:i,errors:n,finishedAt:e.finishedAt,status:e.status}})},[n]);return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(iy,null,"Job Runs")),t&&l.createElement(iR,null),n&&o&&l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(yp,{runs:o}),l.createElement(it.Z,{component:"div",count:n.jobRuns.metadata.total,rowsPerPage:i,rowsPerPageOptions:[i],page:r-1,onChangePage:function(e,t){a.push("/runs?page=".concat(t+1,"&per=").concat(i))},onChangeRowsPerPage:function(){},backIconButtonProps:{"aria-label":"prev-page"},nextIconButtonProps:{"aria-label":"next-page"}})))))};function xi(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xa(){var e=xi(["\n ","\n query FetchJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...JobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return xa=function(){return e},e}var xo=n0(xa(),xn),xs=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"25",10),r=rv(xo,{variables:{offset:(t-1)*n,limit:n},fetchPolicy:"cache-and-network"}),i=r.data,a=r.loading,o=r.error;return o?l.createElement(iD,{error:o}):l.createElement(xr,{loading:a,data:i,page:t,pageSize:n})},xu=function(){var e=(0,h.$B)().path;return l.createElement(h.rs,null,l.createElement(h.AW,{exact:!0,path:e},l.createElement(xs,null)),l.createElement(h.AW,{path:"".concat(e,"/:id")},l.createElement(k7,null)))};function xc(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xl(){var e=xc(["\n fragment FetchFeedsManagersPayload_ResultsFields on FeedsManager {\n __typename\n id\n name\n uri\n publicKey\n isConnectionActive\n createdAt\n }\n query FetchFeedsManagers {\n feedsManagers {\n results {\n ...FetchFeedsManagersPayload_ResultsFields\n }\n }\n }\n"]);return xl=function(){return e},e}var xf=n0(xl()),xd=function(e){return rv(xf,e)},xh=n(47559),xp=n(83165),xb=n(47298),xm=n(81395),xg=function(){return(0,b.createStyles)({root:{display:"flex"},connectedIcon:{color:xh.default[500]},disconnectedIcon:{color:xp.default[500]},text:{marginLeft:4}})},xv=(0,b.withStyles)(xg)(function(e){var t=e.isConnected,n=e.classes;return l.createElement("div",{className:n.root},t?l.createElement(xm.Z,{fontSize:"small",className:n.connectedIcon}):l.createElement(xb.Z,{fontSize:"small",className:n.disconnectedIcon}),l.createElement(x.default,{variant:"body1",inline:!0,className:n.text},t?"Connected":"Disconnected"))}),xy=(0,b.withStyles)(iu)(function(e){var t=e.jobDistributor,n=e.classes;return l.createElement(ir.Z,{className:n.row,hover:!0},l.createElement(r7.default,{className:n.cell,component:"th",scope:"row"},l.createElement(ih,{className:n.link,href:"/job_distributors/".concat(t.id)},t.name)),l.createElement(r7.default,null,l.createElement(xv,{isConnected:t.isConnectionActive})),l.createElement(r7.default,null,_T(t.publicKey,{start:6,end:6}),l.createElement(_x,{data:t.publicKey})),l.createElement(r7.default,null,t.uri))}),xw=function(e){var t=e.jobDistributors;return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Distributors")),l.createElement(d.Z,{item:!0,xs:3},l.createElement(d.Z,{container:!0,justify:"flex-end"},l.createElement(d.Z,{item:!0},l.createElement(aA.Z,{variant:"secondary",component:tz,href:"/job_distributors/new"},"New Job Distributor")))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Name"),l.createElement(r7.default,null,"Status"),l.createElement(r7.default,null,"CSA Public Key"),l.createElement(r7.default,null,"RPC URL"))),l.createElement(r9.Z,null,0===t.length&&l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},"Job Distributors have not been registered")),t.map(function(e){return l.createElement(xy,{key:e.id,jobDistributor:e})})))))))},x_=function(){var e,t=xd({fetchPolicy:"cache-and-network"}),n=t.data,r=t.loading,i=t.error;return r?l.createElement(iR,null):i?l.createElement(iD,{error:i}):l.createElement(xw,{jobDistributors:null!==(e=null==n?void 0:n.feedsManagers.results)&&void 0!==e?e:[]})},xE=bv().shape({name:p0().required("Required"),uri:p0().required("Required"),publicKey:p0().required("Required")}),xS=function(e){var t=e.initialValues,n=e.onSubmit;return l.createElement(hT,{initialValues:t,validationSchema:xE,onSubmit:n},function(e){var t=e.isSubmitting,n=e.submitForm;return l.createElement(hR,{"data-testid":"feeds-manager-form"},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:!1,md:6}),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"uri",name:"uri",label:"URI",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"uri-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"publicKey",name:"publicKey",label:"Public Key",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"publicKey-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(ok.default,{variant:"contained",color:"primary",disabled:t,onClick:n},"Submit"))))})},xk=function(e){var t=e.data,n=e.onSubmit,r={name:t.name,uri:t.uri,publicKey:t.publicKey};return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Job Distributor"}),l.createElement(aW.Z,null,l.createElement(xS,{initialValues:r,onSubmit:n})))))};function xx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(xZ,e)},xJ=n(57234);function xQ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function x6(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}function x5(e,t){return x1(e)||x2(e,t)||x8(e,t)||x3()}function x8(e,t){if(e){if("string"==typeof e)return xQ(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return xQ(e,t)}}var x9=function(e){return"SN_MAIN"===e||"SN_SEPOLIA"===e},x7=bv().shape({chainID:p0().required("Required"),chainType:p0().required("Required"),accountAddr:p0().required("Required"),accountAddrPubKey:p0().nullable(),adminAddr:p0().required("Required"),ocr1Multiaddr:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr1P2PPeerID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr1KeyBundleID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2Multiaddr:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr2P2PPeerID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2KeyBundleID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2CommitPluginEnabled:pV().required("Required"),ocr2ExecutePluginEnabled:pV().required("Required"),ocr2MedianPluginEnabled:pV().required("Required"),ocr2MercuryPluginEnabled:pV().required("Required"),ocr2ForwarderAddress:p0().nullable()}),Te=function(e){return(0,b.createStyles)({supportedJobOptionsPaper:{padding:2*e.spacing.unit}})},Tt=function(e){var t=e.chainAccounts,n=x4(e,["chainAccounts"]),r=h_(),i=r.values,a=i.chainID,o=i.accountAddr,s=r.setFieldValue,u=x5(l.useState(!1),2),c=u[0],f=u[1],d=l.useRef();l.useEffect(function(){d.current=a},[a]),l.useEffect(function(){a!==d.current&&(s(n.name,""),f(!1))},[a,s,n.name]);var h=function(e){var t=e.target.value;"custom"===t?(f(!0),s(n.name,"")):(f(!1),s(n.name,t))};return l.createElement(l.Fragment,null,!x9(a)&&l.createElement(hP,x0({},n,{select:!0,value:c?"custom":o,onChange:h}),t.map(function(e){return l.createElement(tE.default,{key:e.address,value:e.address},e.address)})),x9(a)&&l.createElement(hP,{component:hX,id:"accountAddr",name:"accountAddr",label:"Enter your account address",inputProps:{"data-testid":"customAccountAddr-input"},helperText:"The account address used for this chain",required:!0,fullWidth:!0}),x9(a)&&l.createElement("div",null,l.createElement(hP,{component:hX,id:"accountAddrPubKey",name:"accountAddrPubKey",label:"Account Address Public Key",required:!0,fullWidth:!0,helperText:"The public key for your account address",FormHelperTextProps:{"data-testid":"accountAddrPubKey-helper-text"}})))},Tn=(0,b.withStyles)(Te)(function(e){var t=e.classes,n=e.editing,r=void 0!==n&&n,i=e.innerRef,a=e.initialValues,o=e.onSubmit,s=e.chainIDs,u=void 0===s?[]:s,c=e.accounts,f=void 0===c?[]:c,h=e.p2pKeys,p=void 0===h?[]:h,b=e.ocrKeys,m=void 0===b?[]:b,g=e.ocr2Keys,v=void 0===g?[]:g,y=e.showSubmit,w=void 0!==y&&y;return l.createElement(hT,{innerRef:i,initialValues:a,validationSchema:x7,onSubmit:o},function(e){var n=e.values,i=f.filter(function(e){return e.chain.id==n.chainID&&!e.isDisabled});return l.createElement(hR,{"data-testid":"feeds-manager-form",id:"chain-configuration-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"chainType",name:"chainType",label:"Chain Type",select:!0,required:!0,fullWidth:!0,disabled:!0},l.createElement(tE.default,{key:"EVM",value:"EVM"},"EVM"))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"chainID",name:"chainID",label:"Chain ID",required:!0,fullWidth:!0,select:!0,disabled:r,inputProps:{"data-testid":"chainID-input"},FormHelperTextProps:{"data-testid":"chainID-helper-text"}},u.map(function(e){return l.createElement(tE.default,{key:e,value:e},e)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(Tt,{component:hX,id:"accountAddr",name:"accountAddr",label:"Account Address",inputProps:{"data-testid":"accountAddr-input"},required:!0,fullWidth:!0,select:!0,helperText:"The account address used for this chain",chainAccounts:i,FormHelperTextProps:{"data-testid":"accountAddr-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"adminAddr",name:"adminAddr",label:"Admin Address",required:!0,fullWidth:!0,helperText:"The address used for LINK payments",FormHelperTextProps:{"data-testid":"adminAddr-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Job Types")),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"fluxMonitorEnabled",type:"checkbox",Label:{label:"Flux Monitor"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1Enabled",type:"checkbox",Label:{label:"OCR"}}),n.ocr1Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),n.ocr1IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr1Multiaddr",name:"ocr1Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr1Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1P2PPeerID",name:"ocr1P2PPeerID",label:"Peer ID",select:!0,required:!0,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1P2PPeerID-helper-text"}},p.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1KeyBundleID",name:"ocr1KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1KeyBundleID-helper-text"}},m.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)})))))))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2Enabled",type:"checkbox",Label:{label:"OCR2"}}),n.ocr2Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),n.ocr2IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr2Multiaddr",name:"ocr2Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR2 Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr2Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2P2PPeerID",name:"ocr2P2PPeerID",label:"Peer ID",select:!0,required:!0,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2P2PPeerID-helper-text"}},p.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2KeyBundleID",name:"ocr2KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR2 Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2KeyBundleID-helper-text"}},v.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)}))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Plugins")),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2CommitPluginEnabled",type:"checkbox",Label:{label:"Commit"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2ExecutePluginEnabled",type:"checkbox",Label:{label:"Execute"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2RebalancerPluginEnabled",type:"checkbox",Label:{label:"Rebalancer"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MedianPluginEnabled",type:"checkbox",Label:{label:"Median"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MercuryPluginEnabled",type:"checkbox",Label:{label:"Mercury"}})),l.createElement(d.Z,{item:!0,xs:12,md:12},l.createElement(hP,{component:hX,id:"ocr2ForwarderAddress",name:"ocr2ForwarderAddress",label:"Forwarder Address (optional)",fullWidth:!0,helperText:"The forwarder address from the Operator Forwarder Contract",FormHelperTextProps:{"data-testid":"ocr2ForwarderAddress-helper-text"}}))))))),w&&l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",size:"large"},"Submit"))))})}),Tr=function(e){var t=e.onClose,n=e.open,r=e.onSubmit,i=l.useRef(),a=i$({fetchPolicy:"network-only"}).data,o=_K({fetchPolicy:"cache-and-network"}).data,s=SV({fetchPolicy:"cache-and-network"}).data,u=EO({fetchPolicy:"cache-and-network"}).data,c=E2({fetchPolicy:"cache-and-network"}).data,f={chainID:"",chainType:"EVM",accountAddr:"",adminAddr:"",accountAddrPubKey:"",fluxMonitorEnabled:!1,ocr1Enabled:!1,ocr1IsBootstrap:!1,ocr1Multiaddr:"",ocr1P2PPeerID:"",ocr1KeyBundleID:"",ocr2Enabled:!1,ocr2IsBootstrap:!1,ocr2Multiaddr:"",ocr2P2PPeerID:"",ocr2KeyBundleID:"",ocr2CommitPluginEnabled:!1,ocr2ExecutePluginEnabled:!1,ocr2MedianPluginEnabled:!1,ocr2MercuryPluginEnabled:!1,ocr2RebalancerPluginEnabled:!1,ocr2ForwarderAddress:""},d=a?a.chains.results.map(function(e){return e.id}):[],h=o?o.ethKeys.results:[],p=s?s.p2pKeys.results:[],b=u?u.ocrKeyBundles.results:[],m=c?c.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:t,open:n,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"New Supported Chain")),l.createElement(oT.Z,null,l.createElement(Tn,{innerRef:i,initialValues:f,onSubmit:r,chainIDs:d,accounts:h,p2pKeys:p,ocrKeys:b,ocr2Keys:m})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:t},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))},Ti=function(e){var t=e.cfg,n=e.onClose,r=e.open,i=e.onSubmit,a=l.useRef(),o=i$({fetchPolicy:"network-only"}).data,s=_K({fetchPolicy:"cache-and-network"}).data,u=SV({fetchPolicy:"cache-and-network"}).data,c=EO({fetchPolicy:"cache-and-network"}).data,f=E2({fetchPolicy:"cache-and-network"}).data;if(!t)return null;var d={chainID:t.chainID,chainType:"EVM",accountAddr:t.accountAddr,adminAddr:t.adminAddr,accountAddrPubKey:t.accountAddrPubKey,fluxMonitorEnabled:t.fluxMonitorJobConfig.enabled,ocr1Enabled:t.ocr1JobConfig.enabled,ocr1IsBootstrap:t.ocr1JobConfig.isBootstrap,ocr1Multiaddr:t.ocr1JobConfig.multiaddr,ocr1P2PPeerID:t.ocr1JobConfig.p2pPeerID,ocr1KeyBundleID:t.ocr1JobConfig.keyBundleID,ocr2Enabled:t.ocr2JobConfig.enabled,ocr2IsBootstrap:t.ocr2JobConfig.isBootstrap,ocr2Multiaddr:t.ocr2JobConfig.multiaddr,ocr2P2PPeerID:t.ocr2JobConfig.p2pPeerID,ocr2KeyBundleID:t.ocr2JobConfig.keyBundleID,ocr2CommitPluginEnabled:t.ocr2JobConfig.plugins.commit,ocr2ExecutePluginEnabled:t.ocr2JobConfig.plugins.execute,ocr2MedianPluginEnabled:t.ocr2JobConfig.plugins.median,ocr2MercuryPluginEnabled:t.ocr2JobConfig.plugins.mercury,ocr2RebalancerPluginEnabled:t.ocr2JobConfig.plugins.rebalancer,ocr2ForwarderAddress:t.ocr2JobConfig.forwarderAddress},h=o?o.chains.results.map(function(e){return e.id}):[],p=s?s.ethKeys.results:[],b=u?u.p2pKeys.results:[],m=c?c.ocrKeyBundles.results:[],g=f?f.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:n,open:r,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"Edit Supported Chain")),l.createElement(oT.Z,null,l.createElement(Tn,{innerRef:a,initialValues:d,onSubmit:i,chainIDs:h,accounts:p,p2pKeys:b,ocrKeys:m,ocr2Keys:g,editing:!0})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:n},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))};function Ta(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);nt.version?e:t})},[o]),g=l.useMemo(function(){return Mx(o).sort(function(e,t){return t.version-e.version})},[o]),v=function(e,t,n){switch(e){case"PENDING":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"text",color:"secondary",onClick:function(){return b("reject",t)}},"Reject"),m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status&&l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve"),m.id===t&&"DELETED"===n.status&&n.pendingUpdate&&l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("cancel",t)}},"Cancel"),l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs")));case"APPROVED":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",onClick:function(){return b("cancel",t)}},"Cancel"),"DELETED"===n.status&&n.pendingUpdate&&l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs"));case"CANCELLED":if(m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status)return l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve");return null;default:return null}};return l.createElement("div",null,g.map(function(e,n){return l.createElement(mP.Z,{defaultExpanded:0===n,key:n},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},l.createElement(x.default,{className:t.versionText},"Version ",e.version),l.createElement(Es.Z,{label:e.status,color:"APPROVED"===e.status?"primary":"default",variant:"REJECTED"===e.status||"CANCELLED"===e.status?"outlined":"default"}),l.createElement("div",{className:t.proposedAtContainer},l.createElement(x.default,null,"Proposed ",l.createElement(aO,{tooltip:!0},e.createdAt)))),l.createElement(mj.Z,{className:t.expansionPanelDetails},l.createElement("div",{className:t.actions},l.createElement("div",{className:t.editContainer},0===n&&("PENDING"===e.status||"CANCELLED"===e.status)&&"DELETED"!==s.status&&"REVOKED"!==s.status&&l.createElement(ok.default,{variant:"contained",onClick:function(){return p(!0)}},"Edit")),l.createElement("div",{className:t.actionsContainer},v(e.status,e.id,s))),l.createElement(gd,{language:"toml",style:gs,"data-testid":"codeblock"},e.definition)))}),l.createElement(oC,{open:null!=c,title:c?ML[c.action].title:"",body:c?ML[c.action].body:"",onConfirm:function(){if(c){switch(c.action){case"approve":n(c.id);break;case"cancel":r(c.id);break;case"reject":i(c.id)}f(null)}},cancelButtonText:"Cancel",onCancel:function(){return f(null)}}),l.createElement(Mb,{open:h,onClose:function(){return p(!1)},initialValues:{definition:m.definition,id:m.id},onSubmit:a}))});function MI(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function MD(){var e=MI(["\n ","\n fragment JobProposalPayloadFields on JobProposal {\n id\n externalJobID\n remoteUUID\n jobID\n specs {\n ...JobProposal_SpecsFields\n }\n status\n pendingUpdate\n }\n"]);return MD=function(){return e},e}var MN=n0(MD(),MO),MP=function(e){var t=e.onApprove,n=e.onCancel,r=e.onReject,i=e.onUpdateSpec,a=e.proposal;return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Proposal #",a.id))),l.createElement(Mc,{proposal:a}),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(TJ,null,"Specs"))),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(MC,{proposal:a,specs:a.specs,onReject:r,onApprove:t,onCancel:n,onUpdateSpec:i}))))};function MR(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);nU,tA:()=>$,KL:()=>H,Iw:()=>V,DQ:()=>W,cB:()=>T,LO:()=>M,t5:()=>k,qt:()=>x,Jc:()=>C,L7:()=>Y,EO:()=>B});var r,i,a=n(66289),o=n(41800),s=n.n(o),u=n(67932);(i=r||(r={})).IN_PROGRESS="in_progress",i.PENDING_INCOMING_CONFIRMATIONS="pending_incoming_confirmations",i.PENDING_CONNECTION="pending_connection",i.PENDING_BRIDGE="pending_bridge",i.PENDING_SLEEP="pending_sleep",i.ERRORED="errored",i.COMPLETED="completed";var c=n(87013),l=n(19084),f=n(34823);function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]j,v2:()=>F});var r=n(66289);function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var a="/sessions",o="/sessions",s=function e(t){var n=this;i(this,e),this.api=t,this.createSession=function(e){return n.create(e)},this.destroySession=function(){return n.destroy()},this.create=this.api.createResource(a),this.destroy=this.api.deleteResource(o)};function u(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var c="/v2/bulk_delete_runs",l=function e(t){var n=this;u(this,e),this.api=t,this.bulkDeleteJobRuns=function(e){return n.destroy(e)},this.destroy=this.api.deleteResource(c)};function f(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var d="/v2/chains/evm",h="".concat(d,"/:id"),p=function e(t){var n=this;f(this,e),this.api=t,this.getChains=function(){return n.index()},this.createChain=function(e){return n.create(e)},this.destroyChain=function(e){return n.destroy(void 0,{id:e})},this.updateChain=function(e,t){return n.update(t,{id:e})},this.index=this.api.fetchResource(d),this.create=this.api.createResource(d),this.destroy=this.api.deleteResource(h),this.update=this.api.updateResource(h)};function b(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var m="/v2/keys/evm/chain",g=function e(t){var n=this;b(this,e),this.api=t,this.chain=function(e){var t=new URLSearchParams;t.append("address",e.address),t.append("evmChainID",e.evmChainID),null!==e.nextNonce&&t.append("nextNonce",e.nextNonce),null!==e.abandon&&t.append("abandon",String(e.abandon)),null!==e.enabled&&t.append("enabled",String(e.enabled));var r=m+"?"+t.toString();return n.api.createResource(r)()}};function v(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var y="/v2/jobs",w="".concat(y,"/:specId/runs"),_=function e(t){var n=this;v(this,e),this.api=t,this.createJobRunV2=function(e,t){return n.post(t,{specId:e})},this.post=this.api.createResource(w,!0)};function E(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var S="/v2/log",k=function e(t){var n=this;E(this,e),this.api=t,this.getLogConfig=function(){return n.show()},this.updateLogConfig=function(e){return n.update(e)},this.show=this.api.fetchResource(S),this.update=this.api.updateResource(S)};function x(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var T="/v2/nodes",M=function e(t){var n=this;x(this,e),this.api=t,this.getNodes=function(){return n.index()},this.createNode=function(e){return n.create(e)},this.index=this.api.fetchResource(T),this.create=this.api.createResource(T)};function O(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var A="/v2/enroll_webauthn",L=function e(t){var n=this;O(this,e),this.api=t,this.beginKeyRegistration=function(e){return n.create(e)},this.finishKeyRegistration=function(e){return n.put(e)},this.create=this.api.fetchResource(A),this.put=this.api.createResource(A)};function C(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var I="/v2/build_info",D=function e(t){var n=this;C(this,e),this.api=t,this.show=function(){return n.api.GET(I)()}};function N(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var P=function e(t){N(this,e),this.api=t,this.buildInfo=new D(this.api),this.bulkDeleteRuns=new l(this.api),this.chains=new p(this.api),this.logConfig=new k(this.api),this.nodes=new M(this.api),this.jobs=new _(this.api),this.webauthn=new L(this.api),this.evmKeys=new g(this.api)},R=new r.V0({base:void 0}),j=new s(R),F=new P(R)},1398(e,t,n){"use strict";n.d(t,{Z:()=>d});var r=n(67294),i=n(32316),a=n(83638),o=n(94184),s=n.n(o);function u(){return(u=Object.assign||function(e){for(var t=1;tc});var r=n(67294),i=n(32316);function a(){return(a=Object.assign||function(e){for(var t=1;tx,jK:()=>v});var r=n(67294),i=n(37703),a=n(45697),o=n.n(a),s=n(82204),u=n(71426),c=n(94184),l=n.n(c),f=n(32316),d=function(e){var t=e.palette.success||{},n=e.palette.warning||{};return{base:{paddingLeft:5*e.spacing.unit,paddingRight:5*e.spacing.unit},success:{backgroundColor:t.main,color:t.contrastText},error:{backgroundColor:e.palette.error.dark,color:e.palette.error.contrastText},warning:{backgroundColor:n.contrastText,color:n.main}}},h=function(e){var t,n=e.success,r=e.error,i=e.warning,a=e.classes,o=e.className;return n?t=a.success:r?t=a.error:i&&(t=a.warning),l()(a.base,o,t)},p=function(e){return r.createElement(s.Z,{className:h(e),square:!0},r.createElement(u.default,{variant:"body2",color:"inherit",component:"div"},e.children))};p.defaultProps={success:!1,error:!1,warning:!1},p.propTypes={success:o().bool,error:o().bool,warning:o().bool};let b=(0,f.withStyles)(d)(p);var m=function(){return r.createElement(r.Fragment,null,"Unhandled error. Please help us by opening a"," ",r.createElement("a",{href:"https://github.com/smartcontractkit/chainlink/issues/new"},"bug report"))};let g=m;function v(e){return"string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null)}function y(e,t){var n;return n="string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null),r.createElement("p",{key:t},n)}var w=function(e){var t=e.notifications;return r.createElement(b,{error:!0},t.map(y))},_=function(e){var t=e.notifications;return r.createElement(b,{success:!0},t.map(y))},E=function(e){var t=e.errors,n=e.successes;return r.createElement("div",null,(null==t?void 0:t.length)>0&&r.createElement(w,{notifications:t}),n.length>0&&r.createElement(_,{notifications:n}))},S=function(e){return{errors:e.notifications.errors,successes:e.notifications.successes}},k=(0,i.$j)(S)(E);let x=k},9409(e,t,n){"use strict";n.d(t,{ZP:()=>j});var r=n(67294),i=n(37703),a=n(5977),o=n(32316),s=n(1398),u=n(82204),c=n(30060),l=n(71426),f=n(60520),d=n(39814),h=n(57209),p=n(26842),b=n(3950),m=n(5536),g=n(45697),v=n.n(g);let y=n.p+"9f6d832ef97e8493764e.svg";function w(){return(w=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&_.map(function(e,t){return r.createElement(d.Z,{item:!0,xs:12,key:t},r.createElement(u.Z,{raised:!1,className:v.error},r.createElement(c.Z,null,r.createElement(l.default,{variant:"body1",className:v.errorText},(0,b.jK)(e)))))}),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"email",label:"Email",margin:"normal",value:n,onChange:m("email"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"password",label:"Password",type:"password",autoComplete:"password",margin:"normal",value:h,onChange:m("password"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(d.Z,{container:!0,spacing:0,justify:"center"},r.createElement(d.Z,{item:!0},r.createElement(s.Z,{type:"submit",variant:"primary"},"Access Account")))),y&&r.createElement(l.default,{variant:"body1",color:"textSecondary"},"Signing in...")))))))},P=function(e){return{fetching:e.authentication.fetching,authenticated:e.authentication.allowed,errors:e.notifications.errors}},R=(0,i.$j)(P,x({submitSignIn:p.L7}))(N);let j=(0,h.wU)(e)((0,o.withStyles)(D)(R))},16353(e,t,n){"use strict";n.d(t,{ZP:()=>H,rH:()=>U});var r,i=n(37703),a=n(97779),o=n(9541),s=n(19084);function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.Mk.RECEIVE_SIGNOUT_SUCCESS:case s.Mk.RECEIVE_SIGNIN_SUCCESS:var n={allowed:t.authenticated};return o.Ks(n),f(c({},e,n),{errors:[]});case s.Mk.RECEIVE_SIGNIN_FAIL:var r={allowed:!1};return o.Ks(r),f(c({},e,r),{errors:[]});case s.Mk.RECEIVE_SIGNIN_ERROR:case s.Mk.RECEIVE_SIGNOUT_ERROR:var i={allowed:!1};return o.Ks(i),f(c({},e,i),{errors:t.errors||[]});default:return e}};let b=p;function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;return t.type?t.type.startsWith(r.REQUEST)?y(g({},e),{count:e.count+1}):t.type.startsWith(r.RECEIVE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type.startsWith(r.RESPONSE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type===s.di.REDIRECT?y(g({},e),{count:0}):e:e};let S=E;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function x(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:O,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.MATCH_ROUTE:return M(x({},O),{currentUrl:t.pathname});case s.Ih.NOTIFY_SUCCESS:var n={component:t.component,props:t.props};return M(x({},e),{successes:[n],errors:[]});case s.Ih.NOTIFY_SUCCESS_MSG:return M(x({},e),{successes:[t.msg],errors:[]});case s.Ih.NOTIFY_ERROR:var r=t.error.errors,i=null==r?void 0:r.map(function(e){return L(t,e)});return M(x({},e),{successes:[],errors:i});case s.Ih.NOTIFY_ERROR_MSG:return M(x({},e),{successes:[],errors:[t.msg]});case s.Mk.RECEIVE_SIGNIN_FAIL:return M(x({},e),{successes:[],errors:["Your email or password is incorrect. Please try again"]});default:return e}};function L(e,t){return{component:e.component,props:{msg:t.detail}}}let C=A;function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:R,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.REDIRECT:return P(D({},e),{to:t.to});case s.di.MATCH_ROUTE:return P(D({},e),{to:void 0});default:return e}};let F=j;var Y=n(87013),B=(0,a.UY)({authentication:b,fetching:S,notifications:C,redirect:F,buildInfo:Y.Z});B(void 0,{type:"INITIAL_STATE"});var U=i.v9;let H=B},19084(e,t,n){"use strict";var r,i,a,o,s,u,c,l,f,d;n.d(t,{Ih:()=>i,Mk:()=>a,Y0:()=>s,di:()=>r,jp:()=>o}),n(67294),(u=r||(r={})).REDIRECT="REDIRECT",u.MATCH_ROUTE="MATCH_ROUTE",(c=i||(i={})).NOTIFY_SUCCESS="NOTIFY_SUCCESS",c.NOTIFY_SUCCESS_MSG="NOTIFY_SUCCESS_MSG",c.NOTIFY_ERROR="NOTIFY_ERROR",c.NOTIFY_ERROR_MSG="NOTIFY_ERROR_MSG",(l=a||(a={})).REQUEST_SIGNIN="REQUEST_SIGNIN",l.RECEIVE_SIGNIN_SUCCESS="RECEIVE_SIGNIN_SUCCESS",l.RECEIVE_SIGNIN_FAIL="RECEIVE_SIGNIN_FAIL",l.RECEIVE_SIGNIN_ERROR="RECEIVE_SIGNIN_ERROR",l.RECEIVE_SIGNOUT_SUCCESS="RECEIVE_SIGNOUT_SUCCESS",l.RECEIVE_SIGNOUT_ERROR="RECEIVE_SIGNOUT_ERROR",(f=o||(o={})).RECEIVE_CREATE_ERROR="RECEIVE_CREATE_ERROR",f.RECEIVE_CREATE_SUCCESS="RECEIVE_CREATE_SUCCESS",f.RECEIVE_DELETE_ERROR="RECEIVE_DELETE_ERROR",f.RECEIVE_DELETE_SUCCESS="RECEIVE_DELETE_SUCCESS",f.RECEIVE_UPDATE_ERROR="RECEIVE_UPDATE_ERROR",f.RECEIVE_UPDATE_SUCCESS="RECEIVE_UPDATE_SUCCESS",f.REQUEST_CREATE="REQUEST_CREATE",f.REQUEST_DELETE="REQUEST_DELETE",f.REQUEST_UPDATE="REQUEST_UPDATE",f.UPSERT_CONFIGURATION="UPSERT_CONFIGURATION",f.UPSERT_JOB_RUN="UPSERT_JOB_RUN",f.UPSERT_JOB_RUNS="UPSERT_JOB_RUNS",f.UPSERT_TRANSACTION="UPSERT_TRANSACTION",f.UPSERT_TRANSACTIONS="UPSERT_TRANSACTIONS",f.UPSERT_BUILD_INFO="UPSERT_BUILD_INFO",(d=s||(s={})).FETCH_BUILD_INFO_REQUESTED="FETCH_BUILD_INFO_REQUESTED",d.FETCH_BUILD_INFO_SUCCEEDED="FETCH_BUILD_INFO_SUCCEEDED",d.FETCH_BUILD_INFO_FAILED="FETCH_BUILD_INFO_FAILED"},87013(e,t,n){"use strict";n.d(t,{Y:()=>o,Z:()=>u});var r=n(19084);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:o,t=arguments.length>1?arguments[1]:void 0;return t.type===r.Y0.FETCH_BUILD_INFO_SUCCEEDED?a({},t.buildInfo):e};let u=s},34823(e,t,n){"use strict";n.d(t,{N:()=>r});var r=function(e){return e.buildInfo}},73343(e,t,n){"use strict";n.d(t,{r:()=>u});var r=n(19350),i=n(32316),a=n(59114),o=n(5324),s={props:{MuiGrid:{spacing:3*o.default.unit},MuiCardHeader:{titleTypographyProps:{color:"secondary"}}},palette:{action:{hoverOpacity:.3},primary:{light:"#E5F1FF",main:"#3c40c6",contrastText:"#fff"},secondary:{main:"#3d5170"},success:{light:"#e8faf1",main:r.ek.A700,dark:r.ek[700],contrastText:r.y0.white},warning:{light:"#FFFBF1",main:"#fff6b6",contrastText:"#fad27a"},error:{light:"#ffdada",main:"#f44336",dark:"#d32f2f",contrastText:"#fff"},background:{default:"#f5f6f8",appBar:"#3c40c6"},text:{primary:(0,a.darken)(r.BA.A700,.7),secondary:"#818ea3"},listPendingStatus:{background:"#fef7e5",color:"#fecb4c"},listCompletedStatus:{background:"#e9faf2",color:"#4ed495"}},shape:{borderRadius:o.default.unit},overrides:{MuiButton:{root:{borderRadius:o.default.unit/2,textTransform:"none"},sizeLarge:{padding:void 0,fontSize:void 0,paddingTop:o.default.unit,paddingBottom:o.default.unit,paddingLeft:5*o.default.unit,paddingRight:5*o.default.unit}},MuiTableCell:{body:{fontSize:"1rem"},head:{fontSize:"1rem",fontWeight:400}},MuiCardHeader:{root:{borderBottom:"1px solid rgba(0, 0, 0, 0.12)"},action:{marginTop:-2,marginRight:0,"& >*":{marginLeft:2*o.default.unit}},subheader:{marginTop:.5*o.default.unit}}},typography:{useNextVariants:!0,fontFamily:"-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif",button:{textTransform:"none",fontSize:"1.2em"},body1:{fontSize:"1.0rem",fontWeight:400,lineHeight:"1.46429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body2:{fontSize:"1.0rem",fontWeight:500,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body1Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"1rem",lineHeight:1.5,letterSpacing:-.4},body2Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"0.875rem",lineHeight:1.5,letterSpacing:-.4},display1:{color:"#818ea3",fontSize:"2.125rem",fontWeight:400,lineHeight:"1.20588em",letterSpacing:-.4},display2:{color:"#818ea3",fontSize:"2.8125rem",fontWeight:400,lineHeight:"1.13333em",marginLeft:"-.02em",letterSpacing:-.4},display3:{color:"#818ea3",fontSize:"3.5rem",fontWeight:400,lineHeight:"1.30357em",marginLeft:"-.02em",letterSpacing:-.4},display4:{fontSize:14,fontWeightLight:300,fontWeightMedium:500,fontWeightRegular:400,letterSpacing:-.4},h1:{color:"rgb(29, 29, 29)",fontSize:"6rem",fontWeight:300,lineHeight:1},h2:{color:"rgb(29, 29, 29)",fontSize:"3.75rem",fontWeight:300,lineHeight:1},h3:{color:"rgb(29, 29, 29)",fontSize:"3rem",fontWeight:400,lineHeight:1.04},h4:{color:"rgb(29, 29, 29)",fontSize:"2.125rem",fontWeight:400,lineHeight:1.17},h5:{color:"rgb(29, 29, 29)",fontSize:"1.5rem",fontWeight:400,lineHeight:1.33,letterSpacing:-.4},h6:{fontSize:"0.8rem",fontWeight:450,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},subheading:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:"1.5em",letterSpacing:-.4},subtitle1:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:1.75,letterSpacing:-.4},subtitle2:{color:"rgb(29, 29, 29)",fontSize:"0.875rem",fontWeight:500,lineHeight:1.57,letterSpacing:-.4}},shadows:["none","0px 1px 3px 0px rgba(0, 0, 0, 0.1),0px 1px 1px 0px rgba(0, 0, 0, 0.04),0px 2px 1px -1px rgba(0, 0, 0, 0.02)","0px 1px 5px 0px rgba(0, 0, 0, 0.1),0px 2px 2px 0px rgba(0, 0, 0, 0.04),0px 3px 1px -2px rgba(0, 0, 0, 0.02)","0px 1px 8px 0px rgba(0, 0, 0, 0.1),0px 3px 4px 0px rgba(0, 0, 0, 0.04),0px 3px 3px -2px rgba(0, 0, 0, 0.02)","0px 2px 4px -1px rgba(0, 0, 0, 0.1),0px 4px 5px 0px rgba(0, 0, 0, 0.04),0px 1px 10px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 5px 8px 0px rgba(0, 0, 0, 0.04),0px 1px 14px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 6px 10px 0px rgba(0, 0, 0, 0.04),0px 1px 18px 0px rgba(0, 0, 0, 0.02)","0px 4px 5px -2px rgba(0, 0, 0, 0.1),0px 7px 10px 1px rgba(0, 0, 0, 0.04),0px 2px 16px 1px rgba(0, 0, 0, 0.02)","0px 5px 5px -3px rgba(0, 0, 0, 0.1),0px 8px 10px 1px rgba(0, 0, 0, 0.04),0px 3px 14px 2px rgba(0, 0, 0, 0.02)","0px 5px 6px -3px rgba(0, 0, 0, 0.1),0px 9px 12px 1px rgba(0, 0, 0, 0.04),0px 3px 16px 2px rgba(0, 0, 0, 0.02)","0px 6px 6px -3px rgba(0, 0, 0, 0.1),0px 10px 14px 1px rgba(0, 0, 0, 0.04),0px 4px 18px 3px rgba(0, 0, 0, 0.02)","0px 6px 7px -4px rgba(0, 0, 0, 0.1),0px 11px 15px 1px rgba(0, 0, 0, 0.04),0px 4px 20px 3px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 12px 17px 2px rgba(0, 0, 0, 0.04),0px 5px 22px 4px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 13px 19px 2px rgba(0, 0, 0, 0.04),0px 5px 24px 4px rgba(0, 0, 0, 0.02)","0px 7px 9px -4px rgba(0, 0, 0, 0.1),0px 14px 21px 2px rgba(0, 0, 0, 0.04),0px 5px 26px 4px rgba(0, 0, 0, 0.02)","0px 8px 9px -5px rgba(0, 0, 0, 0.1),0px 15px 22px 2px rgba(0, 0, 0, 0.04),0px 6px 28px 5px rgba(0, 0, 0, 0.02)","0px 8px 10px -5px rgba(0, 0, 0, 0.1),0px 16px 24px 2px rgba(0, 0, 0, 0.04),0px 6px 30px 5px rgba(0, 0, 0, 0.02)","0px 8px 11px -5px rgba(0, 0, 0, 0.1),0px 17px 26px 2px rgba(0, 0, 0, 0.04),0px 6px 32px 5px rgba(0, 0, 0, 0.02)","0px 9px 11px -5px rgba(0, 0, 0, 0.1),0px 18px 28px 2px rgba(0, 0, 0, 0.04),0px 7px 34px 6px rgba(0, 0, 0, 0.02)","0px 9px 12px -6px rgba(0, 0, 0, 0.1),0px 19px 29px 2px rgba(0, 0, 0, 0.04),0px 7px 36px 6px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 20px 31px 3px rgba(0, 0, 0, 0.04),0px 8px 38px 7px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 21px 33px 3px rgba(0, 0, 0, 0.04),0px 8px 40px 7px rgba(0, 0, 0, 0.02)","0px 10px 14px -6px rgba(0, 0, 0, 0.1),0px 22px 35px 3px rgba(0, 0, 0, 0.04),0px 8px 42px 7px rgba(0, 0, 0, 0.02)","0px 11px 14px -7px rgba(0, 0, 0, 0.1),0px 23px 36px 3px rgba(0, 0, 0, 0.04),0px 9px 44px 8px rgba(0, 0, 0, 0.02)","0px 11px 15px -7px rgba(0, 0, 0, 0.1),0px 24px 38px 3px rgba(0, 0, 0, 0.04),0px 9px 46px 8px rgba(0, 0, 0, 0.02)",]},u=(0,i.createMuiTheme)(s)},66289(e,t,n){"use strict";function r(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function a(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&f(i,n.prototype),i}).apply(null,arguments)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}function c(e){return -1!==Function.toString.call(e).indexOf("[native code]")}function l(e,t){return t&&("object"===p(t)||"function"==typeof t)?t:r(e)}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{V0:()=>B,_7:()=>v});var d,h,p=function(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};function b(e){var t="function"==typeof Map?new Map:void 0;return(b=function(e){if(null===e||!c(e))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return o(e,arguments,s(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,e)})(e)}function m(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}function g(e){var t=m();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}var v=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"AuthenticationError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e},],r}return n}(b(Error)),y=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"BadRequestError")).errors=a,r}return n}(b(Error)),w=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnprocessableEntityError")).errors=e,r}return n}(b(Error)),_=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"ServerError")).errors=e,r}return n}(b(Error)),E=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"ConflictError")).errors=a,r}return n}(b(Error)),S=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnknownResponseError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e.statusText},],r}return n}(b(Error));function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2e4;return Promise.race([fetch(e,t),new Promise(function(e,t){return setTimeout(function(){return t(Error("timeout"))},n)}),])}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=200&&e.status<300))return[3,2];return[2,e.json()];case 2:if(400!==e.status)return[3,3];return[2,e.json().then(function(e){throw new y(e)})];case 3:if(401!==e.status)return[3,4];throw new v(e);case 4:if(422!==e.status)return[3,6];return[4,$(e)];case 5:throw n=i.sent(),new w(n);case 6:if(409!==e.status)return[3,7];return[2,e.json().then(function(e){throw new E(e)})];case 7:if(!(e.status>=500))return[3,9];return[4,$(e)];case 8:throw r=i.sent(),new _(r);case 9:throw new S(e);case 10:return[2]}})})).apply(this,arguments)}function $(e){return z.apply(this,arguments)}function z(){return(z=j(function(e){return Y(this,function(t){return[2,e.json().then(function(t){return t.errors?t.errors.map(function(t){return{status:e.status,detail:t.detail}}):G(e)}).catch(function(){return G(e)})]})})).apply(this,arguments)}function G(e){return[{status:e.status,detail:e.statusText},]}},50109(e,t,n){"use strict";n.d(t,{LK:()=>o,U2:()=>i,eT:()=>s,t8:()=>a});var r=n(12795);function i(e){return r.ZP.getItem("chainlink.".concat(e))}function a(e,t){r.ZP.setItem("chainlink.".concat(e),t)}function o(e){var t=i(e),n={};if(t)try{return JSON.parse(t)}catch(r){}return n}function s(e,t){a(e,JSON.stringify(t))}},9541(e,t,n){"use strict";n.d(t,{Ks:()=>u,Tp:()=>a,iR:()=>o,pm:()=>s});var r=n(50109),i="persistURL";function a(){return r.U2(i)||""}function o(e){r.t8(i,e)}function s(){return r.LK("authentication")}function u(e){r.eT("authentication",e)}},67121(e,t,n){"use strict";function r(e){var t,n=e.Symbol;return"function"==typeof n?n.observable?t=n.observable:(t=n("observable"),n.observable=t):t="@@observable",t}n.r(t),n.d(t,{default:()=>o}),e=n.hmd(e),i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:e;var i,a=r(i);let o=a},2177(e,t,n){"use strict";n.d(t,{Z:()=>o});var r=!0,i="Invariant failed";function a(e,t){if(!e){if(r)throw Error(i);throw Error(i+": "+(t||""))}}let o=a},11742(e){e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;ru,ZT:()=>i,_T:()=>o,ev:()=>c,mG:()=>s,pi:()=>a});var r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)};function i(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(n[r[i]]=e[r[i]]);return n}function s(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,a){function o(e){try{u(r.next(e))}catch(t){a(t)}}function s(e){try{u(r.throw(e))}catch(t){a(t)}}function u(e){e.done?n(e.value):i(e.value).then(o,s)}u((r=r.apply(e,t||[])).next())})}function u(e,t){var n,r,i,a,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(e){return function(t){return u([e,t])}}function u(a){if(n)throw TypeError("Generator is already executing.");for(;o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!(i=(i=o.trys).length>0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]r})},94927(e,t,n){function r(e,t){if(i("noDeprecation"))return e;var n=!1;function r(){if(!n){if(i("throwDeprecation"))throw Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}return r}function i(e){try{if(!n.g.localStorage)return!1}catch(t){return!1}var r=n.g.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=r},42473(e){"use strict";var t=function(){};e.exports=t},84763(e){e.exports=Worker},47529(e){e.exports=n;var t=Object.prototype.hasOwnProperty;function n(){for(var e={},n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},7071(e){function t(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},94993(e,t,n){var r=n(18698).default,i=n(66115);function a(e,t){if(t&&("object"===r(t)||"function"==typeof t))return t;if(void 0!==t)throw TypeError("Derived constructors may only return object or undefined");return i(e)}e.exports=a,e.exports.__esModule=!0,e.exports.default=e.exports},6015(e){function t(n,r){return e.exports=t=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n,r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},861(e,t,n){var r=n(63405),i=n(79498),a=n(86116),o=n(42281);function s(e){return r(e)||i(e)||a(e)||o()}e.exports=s,e.exports.__esModule=!0,e.exports.default=e.exports},18698(e){function t(n){return e.exports=t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},86116(e,t,n){var r=n(73897);function i(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},1644(e,t,n){"use strict";var r,i;function a(e){return!!e&&e<7}n.d(t,{I:()=>r,O:()=>a}),(i=r||(r={}))[i.loading=1]="loading",i[i.setVariables=2]="setVariables",i[i.fetchMore=3]="fetchMore",i[i.refetch=4]="refetch",i[i.poll=6]="poll",i[i.ready=7]="ready",i[i.error=8]="error"},30990(e,t,n){"use strict";n.d(t,{MS:()=>s,YG:()=>a,cA:()=>c,ls:()=>o});var r=n(70655);n(83952);var i=n(13154),a=Symbol();function o(e){return!!e.extensions&&Array.isArray(e.extensions[a])}function s(e){return e.hasOwnProperty("graphQLErrors")}var u=function(e){var t=(0,r.ev)((0,r.ev)((0,r.ev)([],e.graphQLErrors,!0),e.clientErrors,!0),e.protocolErrors,!0);return e.networkError&&t.push(e.networkError),t.map(function(e){return(0,i.s)(e)&&e.message||"Error message not found."}).join("\n")},c=function(e){function t(n){var r=n.graphQLErrors,i=n.protocolErrors,a=n.clientErrors,o=n.networkError,s=n.errorMessage,c=n.extraInfo,l=e.call(this,s)||this;return l.name="ApolloError",l.graphQLErrors=r||[],l.protocolErrors=i||[],l.clientErrors=a||[],l.networkError=o||null,l.message=s||u(l),l.extraInfo=c,l.__proto__=t.prototype,l}return(0,r.ZT)(t,e),t}(Error)},85317(e,t,n){"use strict";n.d(t,{K:()=>a});var r=n(67294),i=n(30320).aS?Symbol.for("__APOLLO_CONTEXT__"):"__APOLLO_CONTEXT__";function a(){var e=r.createContext[i];return e||(Object.defineProperty(r.createContext,i,{value:e=r.createContext({}),enumerable:!1,writable:!1,configurable:!0}),e.displayName="ApolloContext"),e}},21436(e,t,n){"use strict";n.d(t,{O:()=>i,k:()=>r});var r=Array.isArray;function i(e){return Array.isArray(e)&&e.length>0}},30320(e,t,n){"use strict";n.d(t,{DN:()=>s,JC:()=>l,aS:()=>o,mr:()=>i,sy:()=>a});var r=n(83952),i="function"==typeof WeakMap&&"ReactNative"!==(0,r.wY)(function(){return navigator.product}),a="function"==typeof WeakSet,o="function"==typeof Symbol&&"function"==typeof Symbol.for,s=o&&Symbol.asyncIterator,u="function"==typeof(0,r.wY)(function(){return window.document.createElement}),c=(0,r.wY)(function(){return navigator.userAgent.indexOf("jsdom")>=0})||!1,l=u&&!c},53712(e,t,n){"use strict";function r(){for(var e=[],t=0;tr})},10542(e,t,n){"use strict";n.d(t,{J:()=>o}),n(83952);var r=n(13154);function i(e){var t=new Set([e]);return t.forEach(function(e){(0,r.s)(e)&&a(e)===e&&Object.getOwnPropertyNames(e).forEach(function(n){(0,r.s)(e[n])&&t.add(e[n])})}),e}function a(e){if(__DEV__&&!Object.isFrozen(e))try{Object.freeze(e)}catch(t){if(t instanceof TypeError)return null;throw t}return e}function o(e){return __DEV__&&i(e),e}},14012(e,t,n){"use strict";n.d(t,{J:()=>a});var r=n(70655),i=n(53712);function a(e,t){return(0,i.o)(e,t,t.variables&&{variables:(0,r.pi)((0,r.pi)({},e&&e.variables),t.variables)})}},13154(e,t,n){"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{s:()=>r})},83952(e,t,n){"use strict";n.d(t,{ej:()=>u,kG:()=>c,wY:()=>h});var r,i=n(70655),a="Invariant Violation",o=Object.setPrototypeOf,s=void 0===o?function(e,t){return e.__proto__=t,e}:o,u=function(e){function t(n){void 0===n&&(n=a);var r=e.call(this,"number"==typeof n?a+": "+n+" (see https://github.com/apollographql/invariant-packages)":n)||this;return r.framesToPop=1,r.name=a,s(r,t.prototype),r}return(0,i.ZT)(t,e),t}(Error);function c(e,t){if(!e)throw new u(t)}var l=["debug","log","warn","error","silent"],f=l.indexOf("log");function d(e){return function(){if(l.indexOf(e)>=f)return(console[e]||console.log).apply(console,arguments)}}function h(e){try{return e()}catch(t){}}(r=c||(c={})).debug=d("debug"),r.log=d("log"),r.warn=d("warn"),r.error=d("error");let p=h(function(){return globalThis})||h(function(){return window})||h(function(){return self})||h(function(){return global})||h(function(){return h.constructor("return this")()});var b="__",m=[b,b].join("DEV");function g(){try{return Boolean(__DEV__)}catch(e){return Object.defineProperty(p,m,{value:"production"!==h(function(){return"production"}),enumerable:!1,configurable:!0,writable:!0}),p[m]}}let v=g();function y(e){try{return e()}catch(t){}}var w=y(function(){return globalThis})||y(function(){return window})||y(function(){return self})||y(function(){return global})||y(function(){return y.constructor("return this")()}),_=!1;function E(){!w||y(function(){return"production"})||y(function(){return process})||(Object.defineProperty(w,"process",{value:{env:{NODE_ENV:"production"}},configurable:!0,enumerable:!1,writable:!0}),_=!0)}function S(){_&&(delete w.process,_=!1)}E();var k=n(10143);function x(){return k.H,S()}function T(){__DEV__?c("boolean"==typeof v,v):c("boolean"==typeof v,39)}x(),T()},4942(e,t,n){"use strict";function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}n.d(t,{Z:()=>r})},87462(e,t,n){"use strict";function r(){return(r=Object.assign?Object.assign.bind():function(e){for(var t=1;tr})},51721(e,t,n){"use strict";function r(e,t){return(r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e})(e,t)}function i(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>i})},63366(e,t,n){"use strict";function r(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}n.d(t,{Z:()=>r})},25821(e,t,n){"use strict";n.d(t,{Z:()=>s});var r=n(45695);function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=10,o=2;function s(e){return u(e,[])}function u(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":if(null===e)return"null";return c(e,t);default:return String(e)}}function c(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=d(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:u(i,n)}else if(Array.isArray(e))return f(e,n);return l(e,n)}function l(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>o?"["+h(e)+"]":"{ "+n.map(function(n){var r=u(e[n],t);return n+": "+r}).join(", ")+" }"}function f(e,t){if(0===e.length)return"[]";if(t.length>o)return"[Array]";for(var n=Math.min(a,e.length),r=e.length-n,i=[],s=0;s1&&i.push("... ".concat(r," more items")),"["+i.join(", ")+"]"}function d(e){var t=e[String(r.Z)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}function h(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}},45695(e,t,n){"use strict";n.d(t,{Z:()=>i});var r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;let i=r},25217(e,t,n){"use strict";function r(e,t){if(!Boolean(e))throw Error(null!=t?t:"Unexpected invariant triggered.")}n.d(t,{Ye:()=>o,WU:()=>s,UG:()=>u});var i=n(45695);function a(e){var t=e.prototype.toJSON;"function"==typeof t||r(0),e.prototype.inspect=t,i.Z&&(e.prototype[i.Z]=t)}var o=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();a(o);var s=function(){function e(e,t,n,r,i,a,o){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=i,this.value=o,this.prev=a,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();function u(e){return null!=e&&"string"==typeof e.kind}a(s)},87392(e,t,n){"use strict";function r(e){var t=e.split(/\r\n|[\n\r]/g),n=a(e);if(0!==n)for(var r=1;ro&&i(t[s-1]);)--s;return t.slice(o,s).join("\n")}function i(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),i=" "===e[0]||" "===e[0],a='"'===e[e.length-1],o="\\"===e[e.length-1],s=!r||a||o||n,u="";return s&&!(r&&i)&&(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}n.d(t,{LZ:()=>o,W7:()=>r})},97359(e,t,n){"use strict";n.d(t,{h:()=>r});var r=Object.freeze({NAME:"Name",DOCUMENT:"Document",OPERATION_DEFINITION:"OperationDefinition",VARIABLE_DEFINITION:"VariableDefinition",SELECTION_SET:"SelectionSet",FIELD:"Field",ARGUMENT:"Argument",FRAGMENT_SPREAD:"FragmentSpread",INLINE_FRAGMENT:"InlineFragment",FRAGMENT_DEFINITION:"FragmentDefinition",VARIABLE:"Variable",INT:"IntValue",FLOAT:"FloatValue",STRING:"StringValue",BOOLEAN:"BooleanValue",NULL:"NullValue",ENUM:"EnumValue",LIST:"ListValue",OBJECT:"ObjectValue",OBJECT_FIELD:"ObjectField",DIRECTIVE:"Directive",NAMED_TYPE:"NamedType",LIST_TYPE:"ListType",NON_NULL_TYPE:"NonNullType",SCHEMA_DEFINITION:"SchemaDefinition",OPERATION_TYPE_DEFINITION:"OperationTypeDefinition",SCALAR_TYPE_DEFINITION:"ScalarTypeDefinition",OBJECT_TYPE_DEFINITION:"ObjectTypeDefinition",FIELD_DEFINITION:"FieldDefinition",INPUT_VALUE_DEFINITION:"InputValueDefinition",INTERFACE_TYPE_DEFINITION:"InterfaceTypeDefinition",UNION_TYPE_DEFINITION:"UnionTypeDefinition",ENUM_TYPE_DEFINITION:"EnumTypeDefinition",ENUM_VALUE_DEFINITION:"EnumValueDefinition",INPUT_OBJECT_TYPE_DEFINITION:"InputObjectTypeDefinition",DIRECTIVE_DEFINITION:"DirectiveDefinition",SCHEMA_EXTENSION:"SchemaExtension",SCALAR_TYPE_EXTENSION:"ScalarTypeExtension",OBJECT_TYPE_EXTENSION:"ObjectTypeExtension",INTERFACE_TYPE_EXTENSION:"InterfaceTypeExtension",UNION_TYPE_EXTENSION:"UnionTypeExtension",ENUM_TYPE_EXTENSION:"EnumTypeExtension",INPUT_OBJECT_TYPE_EXTENSION:"InputObjectTypeExtension"})},10143(e,t,n){"use strict";n.d(t,{H:()=>c,T:()=>l});var r=n(99763),i=n(25821);function a(e,t){if(!Boolean(e))throw Error(t)}let o=function(e,t){return e instanceof t};function s(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||a(0,"Body must be a string. Received: ".concat((0,i.Z)(e),".")),this.body=e,this.name=t,this.locationOffset=n,this.locationOffset.line>0||a(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||a(0,"column in locationOffset is 1-indexed and must be positive.")}return u(e,[{key:r.YF,get:function(){return"Source"}}]),e}();function l(e){return o(e,c)}},99763(e,t,n){"use strict";n.d(t,{YF:()=>r});var r="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag"},37452(e){"use strict";e.exports=JSON.parse('{"AElig":"\xc6","AMP":"&","Aacute":"\xc1","Acirc":"\xc2","Agrave":"\xc0","Aring":"\xc5","Atilde":"\xc3","Auml":"\xc4","COPY":"\xa9","Ccedil":"\xc7","ETH":"\xd0","Eacute":"\xc9","Ecirc":"\xca","Egrave":"\xc8","Euml":"\xcb","GT":">","Iacute":"\xcd","Icirc":"\xce","Igrave":"\xcc","Iuml":"\xcf","LT":"<","Ntilde":"\xd1","Oacute":"\xd3","Ocirc":"\xd4","Ograve":"\xd2","Oslash":"\xd8","Otilde":"\xd5","Ouml":"\xd6","QUOT":"\\"","REG":"\xae","THORN":"\xde","Uacute":"\xda","Ucirc":"\xdb","Ugrave":"\xd9","Uuml":"\xdc","Yacute":"\xdd","aacute":"\xe1","acirc":"\xe2","acute":"\xb4","aelig":"\xe6","agrave":"\xe0","amp":"&","aring":"\xe5","atilde":"\xe3","auml":"\xe4","brvbar":"\xa6","ccedil":"\xe7","cedil":"\xb8","cent":"\xa2","copy":"\xa9","curren":"\xa4","deg":"\xb0","divide":"\xf7","eacute":"\xe9","ecirc":"\xea","egrave":"\xe8","eth":"\xf0","euml":"\xeb","frac12":"\xbd","frac14":"\xbc","frac34":"\xbe","gt":">","iacute":"\xed","icirc":"\xee","iexcl":"\xa1","igrave":"\xec","iquest":"\xbf","iuml":"\xef","laquo":"\xab","lt":"<","macr":"\xaf","micro":"\xb5","middot":"\xb7","nbsp":"\xa0","not":"\xac","ntilde":"\xf1","oacute":"\xf3","ocirc":"\xf4","ograve":"\xf2","ordf":"\xaa","ordm":"\xba","oslash":"\xf8","otilde":"\xf5","ouml":"\xf6","para":"\xb6","plusmn":"\xb1","pound":"\xa3","quot":"\\"","raquo":"\xbb","reg":"\xae","sect":"\xa7","shy":"\xad","sup1":"\xb9","sup2":"\xb2","sup3":"\xb3","szlig":"\xdf","thorn":"\xfe","times":"\xd7","uacute":"\xfa","ucirc":"\xfb","ugrave":"\xf9","uml":"\xa8","uuml":"\xfc","yacute":"\xfd","yen":"\xa5","yuml":"\xff"}')},93580(e){"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},67946(e){"use strict";e.exports=JSON.parse('{"locale":"en","long":{"year":{"previous":"last year","current":"this year","next":"next year","past":{"one":"{0} year ago","other":"{0} years ago"},"future":{"one":"in {0} year","other":"in {0} years"}},"quarter":{"previous":"last quarter","current":"this quarter","next":"next quarter","past":{"one":"{0} quarter ago","other":"{0} quarters ago"},"future":{"one":"in {0} quarter","other":"in {0} quarters"}},"month":{"previous":"last month","current":"this month","next":"next month","past":{"one":"{0} month ago","other":"{0} months ago"},"future":{"one":"in {0} month","other":"in {0} months"}},"week":{"previous":"last week","current":"this week","next":"next week","past":{"one":"{0} week ago","other":"{0} weeks ago"},"future":{"one":"in {0} week","other":"in {0} weeks"}},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":{"one":"{0} hour ago","other":"{0} hours ago"},"future":{"one":"in {0} hour","other":"in {0} hours"}},"minute":{"current":"this minute","past":{"one":"{0} minute ago","other":"{0} minutes ago"},"future":{"one":"in {0} minute","other":"in {0} minutes"}},"second":{"current":"now","past":{"one":"{0} second ago","other":"{0} seconds ago"},"future":{"one":"in {0} second","other":"in {0} seconds"}}},"short":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"narrow":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"now":{"now":{"current":"now","future":"in a moment","past":"just now"}},"mini":{"year":"{0}yr","month":"{0}mo","week":"{0}wk","day":"{0}d","hour":"{0}h","minute":"{0}m","second":"{0}s","now":"now"},"short-time":{"year":"{0} yr.","month":"{0} mo.","week":"{0} wk.","day":{"one":"{0} day","other":"{0} days"},"hour":"{0} hr.","minute":"{0} min.","second":"{0} sec."},"long-time":{"year":{"one":"{0} year","other":"{0} years"},"month":{"one":"{0} month","other":"{0} months"},"week":{"one":"{0} week","other":"{0} weeks"},"day":{"one":"{0} day","other":"{0} days"},"hour":{"one":"{0} hour","other":"{0} hours"},"minute":{"one":"{0} minute","other":"{0} minutes"},"second":{"one":"{0} second","other":"{0} seconds"}}}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;__webpack_require__.t=function(n,r){if(1&r&&(n=this(n)),8&r||"object"==typeof n&&n&&(4&r&&n.__esModule||16&r&&"function"==typeof n.then))return n;var i=Object.create(null);__webpack_require__.r(i);var a={};e=e||[null,t({}),t([]),t(t)];for(var o=2&r&&n;"object"==typeof o&&!~e.indexOf(o);o=t(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,__webpack_require__.d(i,a),i}})(),__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set(){throw Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__.p="/assets/",__webpack_require__.nc=void 0;var __webpack_exports__={};(()=>{"use strict";var e,t,n,r,i=__webpack_require__(32316),a=__webpack_require__(8126),o=__webpack_require__(5690),s=__webpack_require__(30381),u=__webpack_require__.n(s),c=__webpack_require__(67294),l=__webpack_require__(73935),f=__webpack_require__.n(l),d=__webpack_require__(57209),h=__webpack_require__(37703),p=__webpack_require__(97779),b=__webpack_require__(28500);function m(e){return function(t){var n=t.dispatch,r=t.getState;return function(t){return function(i){return"function"==typeof i?i(n,r,e):t(i)}}}}var g=m();g.withExtraArgument=m;let v=g;var y=__webpack_require__(76489);function w(e){return function(t){return function(n){return function(r){n(r);var i=e||document&&document.cookie||"",a=t.getState();if("MATCH_ROUTE"===r.type&&"/signin"!==a.notifications.currentUrl){var o=(0,y.Q)(i);if(o.explorer)try{var s=JSON.parse(o.explorer);if("error"===s.status){var u=_(s.url);n({type:"NOTIFY_ERROR_MSG",msg:u})}}catch(c){n({type:"NOTIFY_ERROR_MSG",msg:"Invalid explorer status"})}}}}}}function _(e){var t="Can't connect to explorer: ".concat(e);return e.match(/^wss?:.+/)?t:"".concat(t,". You must use a websocket.")}var E=__webpack_require__(16353);function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ei(e,t){if(e){if("string"==typeof e)return ea(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ea(e,t)}}function ea(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1,i=!1,a=arguments[1],o=a;return new n(function(n){return t.subscribe({next:function(t){var a=!i;if(i=!0,!a||r)try{o=e(o,t)}catch(s){return n.error(s)}else o=t},error:function(e){n.error(e)},complete:function(){if(!i&&!r)return n.error(TypeError("Cannot reduce an empty sequence"));n.next(o),n.complete()}})})},t.concat=function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r=0&&i.splice(e,1),o()}});i.push(s)},error:function(e){r.error(e)},complete:function(){o()}});function o(){a.closed&&0===i.length&&r.complete()}return function(){i.forEach(function(e){return e.unsubscribe()}),a.unsubscribe()}})},t[ed]=function(){return this},e.from=function(t){var n="function"==typeof this?this:e;if(null==t)throw TypeError(t+" is not an object");var r=ep(t,ed);if(r){var i=r.call(t);if(Object(i)!==i)throw TypeError(i+" is not an object");return em(i)&&i.constructor===n?i:new n(function(e){return i.subscribe(e)})}if(ec("iterator")&&(r=ep(t,ef)))return new n(function(e){ev(function(){if(!e.closed){for(var n,i=er(r.call(t));!(n=i()).done;){var a=n.value;if(e.next(a),e.closed)return}e.complete()}})});if(Array.isArray(t))return new n(function(e){ev(function(){if(!e.closed){for(var n=0;n0))return n.connection.key;var r=n.connection.filter?n.connection.filter:[];r.sort();var i={};return r.forEach(function(e){i[e]=t[e]}),"".concat(n.connection.key,"(").concat(eV(i),")")}var a=e;if(t){var o=eV(t);a+="(".concat(o,")")}return n&&Object.keys(n).forEach(function(e){-1===eW.indexOf(e)&&(n[e]&&Object.keys(n[e]).length?a+="@".concat(e,"(").concat(eV(n[e]),")"):a+="@".concat(e))}),a},{setStringify:function(e){var t=eV;return eV=e,t}}),eV=function(e){return JSON.stringify(e,eq)};function eq(e,t){return(0,eO.s)(t)&&!Array.isArray(t)&&(t=Object.keys(t).sort().reduce(function(e,n){return e[n]=t[n],e},{})),t}function eZ(e,t){if(e.arguments&&e.arguments.length){var n={};return e.arguments.forEach(function(e){var r;return ez(n,e.name,e.value,t)}),n}return null}function eX(e){return e.alias?e.alias.value:e.name.value}function eJ(e,t,n){for(var r,i=0,a=t.selections;it.indexOf(i))throw __DEV__?new Q.ej("illegal argument: ".concat(i)):new Q.ej(27)}return e}function tt(e,t){return t?t(e):eT.of()}function tn(e){return"function"==typeof e?new ta(e):e}function tr(e){return e.request.length<=1}var ti=function(e){function t(t,n){var r=e.call(this,t)||this;return r.link=n,r}return(0,en.ZT)(t,e),t}(Error),ta=function(){function e(e){e&&(this.request=e)}return e.empty=function(){return new e(function(){return eT.of()})},e.from=function(t){return 0===t.length?e.empty():t.map(tn).reduce(function(e,t){return e.concat(t)})},e.split=function(t,n,r){var i=tn(n),a=tn(r||new e(tt));return new e(tr(i)&&tr(a)?function(e){return t(e)?i.request(e)||eT.of():a.request(e)||eT.of()}:function(e,n){return t(e)?i.request(e,n)||eT.of():a.request(e,n)||eT.of()})},e.execute=function(e,t){return e.request(eM(t.context,e7(te(t))))||eT.of()},e.concat=function(t,n){var r=tn(t);if(tr(r))return __DEV__&&Q.kG.warn(new ti("You are calling concat on a terminating link, which will have no effect",r)),r;var i=tn(n);return new e(tr(i)?function(e){return r.request(e,function(e){return i.request(e)||eT.of()})||eT.of()}:function(e,t){return r.request(e,function(e){return i.request(e,t)||eT.of()})||eT.of()})},e.prototype.split=function(t,n,r){return this.concat(e.split(t,n,r||new e(tt)))},e.prototype.concat=function(t){return e.concat(this,t)},e.prototype.request=function(e,t){throw __DEV__?new Q.ej("request is not implemented"):new Q.ej(22)},e.prototype.onError=function(e,t){if(t&&t.error)return t.error(e),!1;throw e},e.prototype.setOnError=function(e){return this.onError=e,this},e}(),to=__webpack_require__(25821),ts=__webpack_require__(25217),tu={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},tc=Object.freeze({});function tl(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:tu,r=void 0,i=Array.isArray(e),a=[e],o=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],d=[],h=e;do{var p,b=++o===a.length,m=b&&0!==s.length;if(b){if(c=0===d.length?void 0:f[f.length-1],u=l,l=d.pop(),m){if(i)u=u.slice();else{for(var g={},v=0,y=Object.keys(u);v1)for(var r=new tB,i=1;i=0;--a){var o=i[a],s=isNaN(+o)?{}:[];s[o]=t,t=s}n=r.merge(n,t)}),n}var tW=Object.prototype.hasOwnProperty;function tK(e,t){var n,r,i,a,o;return(0,en.mG)(this,void 0,void 0,function(){var s,u,c,l,f,d,h,p,b,m,g,v,y,w,_,E,S,k,x,T,M,O,A;return(0,en.Jh)(this,function(L){switch(L.label){case 0:if(void 0===TextDecoder)throw Error("TextDecoder must be defined in the environment: please import a polyfill.");s=new TextDecoder("utf-8"),u=null===(n=e.headers)||void 0===n?void 0:n.get("content-type"),c="boundary=",l=(null==u?void 0:u.includes(c))?null==u?void 0:u.substring((null==u?void 0:u.indexOf(c))+c.length).replace(/['"]/g,"").replace(/\;(.*)/gm,"").trim():"-",f="\r\n--".concat(l),d="",h=tI(e),p=!0,L.label=1;case 1:if(!p)return[3,3];return[4,h.next()];case 2:for(m=(b=L.sent()).value,g=b.done,v="string"==typeof m?m:s.decode(m),y=d.length-f.length+1,p=!g,d+=v,w=d.indexOf(f,y);w>-1;){if(_=void 0,_=(O=[d.slice(0,w),d.slice(w+f.length),])[0],d=O[1],E=_.indexOf("\r\n\r\n"),(k=(S=tV(_.slice(0,E)))["content-type"])&&-1===k.toLowerCase().indexOf("application/json"))throw Error("Unsupported patch content type: application/json is required.");if(x=_.slice(E))try{T=tq(e,x),Object.keys(T).length>1||"data"in T||"incremental"in T||"errors"in T||"payload"in T?tz(T)?(M={},"payload"in T&&(M=(0,en.pi)({},T.payload)),"errors"in T&&(M=(0,en.pi)((0,en.pi)({},M),{extensions:(0,en.pi)((0,en.pi)({},"extensions"in M?M.extensions:null),((A={})[tN.YG]=T.errors,A))})),null===(r=t.next)||void 0===r||r.call(t,M)):null===(i=t.next)||void 0===i||i.call(t,T):1===Object.keys(T).length&&"hasNext"in T&&!T.hasNext&&(null===(a=t.complete)||void 0===a||a.call(t))}catch(C){tZ(C,t)}w=d.indexOf(f)}return[3,1];case 3:return null===(o=t.complete)||void 0===o||o.call(t),[2]}})})}function tV(e){var t={};return e.split("\n").forEach(function(e){var n=e.indexOf(":");if(n>-1){var r=e.slice(0,n).trim().toLowerCase(),i=e.slice(n+1).trim();t[r]=i}}),t}function tq(e,t){e.status>=300&&tD(e,function(){try{return JSON.parse(t)}catch(e){return t}}(),"Response not successful: Received status code ".concat(e.status));try{return JSON.parse(t)}catch(n){var r=n;throw r.name="ServerParseError",r.response=e,r.statusCode=e.status,r.bodyText=t,r}}function tZ(e,t){var n,r;"AbortError"!==e.name&&(e.result&&e.result.errors&&e.result.data&&(null===(n=t.next)||void 0===n||n.call(t,e.result)),null===(r=t.error)||void 0===r||r.call(t,e))}function tX(e,t,n){tJ(t)(e).then(function(e){var t,r;null===(t=n.next)||void 0===t||t.call(n,e),null===(r=n.complete)||void 0===r||r.call(n)}).catch(function(e){return tZ(e,n)})}function tJ(e){return function(t){return t.text().then(function(e){return tq(t,e)}).then(function(n){return t.status>=300&&tD(t,n,"Response not successful: Received status code ".concat(t.status)),Array.isArray(n)||tW.call(n,"data")||tW.call(n,"errors")||tD(t,n,"Server response was missing for query '".concat(Array.isArray(e)?e.map(function(e){return e.operationName}):e.operationName,"'.")),n})}}var tQ=function(e){if(!e&&"undefined"==typeof fetch)throw __DEV__?new Q.ej("\n\"fetch\" has not been found globally and no fetcher has been configured. To fix this, install a fetch package (like https://www.npmjs.com/package/cross-fetch), instantiate the fetcher, and pass it into your HttpLink constructor. For example:\n\nimport fetch from 'cross-fetch';\nimport { ApolloClient, HttpLink } from '@apollo/client';\nconst client = new ApolloClient({\n link: new HttpLink({ uri: '/graphql', fetch })\n});\n "):new Q.ej(23)},t1=__webpack_require__(87392);function t0(e){return tl(e,{leave:t3})}var t2=80,t3={Name:function(e){return e.value},Variable:function(e){return"$"+e.name},Document:function(e){return t6(e.definitions,"\n\n")+"\n"},OperationDefinition:function(e){var t=e.operation,n=e.name,r=t8("(",t6(e.variableDefinitions,", "),")"),i=t6(e.directives," "),a=e.selectionSet;return n||i||r||"query"!==t?t6([t,t6([n,r]),i,a]," "):a},VariableDefinition:function(e){var t=e.variable,n=e.type,r=e.defaultValue,i=e.directives;return t+": "+n+t8(" = ",r)+t8(" ",t6(i," "))},SelectionSet:function(e){return t5(e.selections)},Field:function(e){var t=e.alias,n=e.name,r=e.arguments,i=e.directives,a=e.selectionSet,o=t8("",t,": ")+n,s=o+t8("(",t6(r,", "),")");return s.length>t2&&(s=o+t8("(\n",t9(t6(r,"\n")),"\n)")),t6([s,t6(i," "),a]," ")},Argument:function(e){var t;return e.name+": "+e.value},FragmentSpread:function(e){var t;return"..."+e.name+t8(" ",t6(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,n=e.directives,r=e.selectionSet;return t6(["...",t8("on ",t),t6(n," "),r]," ")},FragmentDefinition:function(e){var t=e.name,n=e.typeCondition,r=e.variableDefinitions,i=e.directives,a=e.selectionSet;return"fragment ".concat(t).concat(t8("(",t6(r,", "),")")," ")+"on ".concat(n," ").concat(t8("",t6(i," ")," "))+a},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var n=e.value;return e.block?(0,t1.LZ)(n,"description"===t?"":" "):JSON.stringify(n)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+t6(e.values,", ")+"]"},ObjectValue:function(e){return"{"+t6(e.fields,", ")+"}"},ObjectField:function(e){var t;return e.name+": "+e.value},Directive:function(e){var t;return"@"+e.name+t8("(",t6(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:t4(function(e){var t=e.directives,n=e.operationTypes;return t6(["schema",t6(t," "),t5(n)]," ")}),OperationTypeDefinition:function(e){var t;return e.operation+": "+e.type},ScalarTypeDefinition:t4(function(e){var t;return t6(["scalar",e.name,t6(e.directives," ")]," ")}),ObjectTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),FieldDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.type,i=e.directives;return t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+": "+r+t8(" ",t6(i," "))}),InputValueDefinition:t4(function(e){var t=e.name,n=e.type,r=e.defaultValue,i=e.directives;return t6([t+": "+n,t8("= ",r),t6(i," ")]," ")}),InterfaceTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),UnionTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.types;return t6(["union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")}),EnumTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.values;return t6(["enum",t,t6(n," "),t5(r)]," ")}),EnumValueDefinition:t4(function(e){var t;return t6([e.name,t6(e.directives," ")]," ")}),InputObjectTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["input",t,t6(n," "),t5(r)]," ")}),DirectiveDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.repeatable,i=e.locations;return"directive @"+t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+(r?" repeatable":"")+" on "+t6(i," | ")}),SchemaExtension:function(e){var t=e.directives,n=e.operationTypes;return t6(["extend schema",t6(t," "),t5(n)]," ")},ScalarTypeExtension:function(e){var t;return t6(["extend scalar",e.name,t6(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},InterfaceTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},UnionTypeExtension:function(e){var t=e.name,n=e.directives,r=e.types;return t6(["extend union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,n=e.directives,r=e.values;return t6(["extend enum",t,t6(n," "),t5(r)]," ")},InputObjectTypeExtension:function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["extend input",t,t6(n," "),t5(r)]," ")}};function t4(e){return function(t){return t6([t.description,e(t)],"\n")}}function t6(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter(function(e){return e}).join(n))&&void 0!==t?t:""}function t5(e){return t8("{\n",t9(t6(e,"\n")),"\n}")}function t8(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+n:""}function t9(e){return t8(" ",e.replace(/\n/g,"\n "))}function t7(e){return -1!==e.indexOf("\n")}function ne(e){return null!=e&&e.some(t7)}var nt,nn,nr,ni={http:{includeQuery:!0,includeExtensions:!1,preserveHeaderCase:!1},headers:{accept:"*/*","content-type":"application/json"},options:{method:"POST"}},na=function(e,t){return t(e)};function no(e,t){for(var n=[],r=2;rObject.create(null),{forEach:nv,slice:ny}=Array.prototype,{hasOwnProperty:nw}=Object.prototype;class n_{constructor(e=!0,t=ng){this.weakness=e,this.makeData=t}lookup(...e){return this.lookupArray(e)}lookupArray(e){let t=this;return nv.call(e,e=>t=t.getChildTrie(e)),nw.call(t,"data")?t.data:t.data=this.makeData(ny.call(e))}peek(...e){return this.peekArray(e)}peekArray(e){let t=this;for(let n=0,r=e.length;t&&n=0;--o)t.definitions[o].kind===nL.h.OPERATION_DEFINITION&&++a;var s=nN(e),u=e.some(function(e){return e.remove}),c=function(e){return u&&e&&e.some(s)},l=new Map,f=!1,d={enter:function(e){if(c(e.directives))return f=!0,null}},h=tl(t,{Field:d,InlineFragment:d,VariableDefinition:{enter:function(){return!1}},Variable:{enter:function(e,t,n,r,a){var o=i(a);o&&o.variables.add(e.name.value)}},FragmentSpread:{enter:function(e,t,n,r,a){if(c(e.directives))return f=!0,null;var o=i(a);o&&o.fragmentSpreads.add(e.name.value)}},FragmentDefinition:{enter:function(e,t,n,r){l.set(JSON.stringify(r),e)},leave:function(e,t,n,i){return e===l.get(JSON.stringify(i))?e:a>0&&e.selectionSet.selections.every(function(e){return e.kind===nL.h.FIELD&&"__typename"===e.name.value})?(r(e.name.value).removed=!0,f=!0,null):void 0}},Directive:{leave:function(e){if(s(e))return f=!0,null}}});if(!f)return t;var p=function(e){return e.transitiveVars||(e.transitiveVars=new Set(e.variables),e.removed||e.fragmentSpreads.forEach(function(t){p(r(t)).transitiveVars.forEach(function(t){e.transitiveVars.add(t)})})),e},b=new Set;h.definitions.forEach(function(e){e.kind===nL.h.OPERATION_DEFINITION?p(n(e.name&&e.name.value)).fragmentSpreads.forEach(function(e){b.add(e)}):e.kind!==nL.h.FRAGMENT_DEFINITION||0!==a||r(e.name.value).removed||b.add(e.name.value)}),b.forEach(function(e){p(r(e)).fragmentSpreads.forEach(function(e){b.add(e)})});var m=function(e){return!!(!b.has(e)||r(e).removed)},g={enter:function(e){if(m(e.name.value))return null}};return nD(tl(h,{FragmentSpread:g,FragmentDefinition:g,OperationDefinition:{leave:function(e){if(e.variableDefinitions){var t=p(n(e.name&&e.name.value)).transitiveVars;if(t.size0},t.prototype.tearDownQuery=function(){this.isTornDown||(this.concast&&this.observer&&(this.concast.removeObserver(this.observer),delete this.concast,delete this.observer),this.stopPolling(),this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions.clear(),this.queryManager.stopQuery(this.queryId),this.observers.clear(),this.isTornDown=!0)},t}(eT);function n4(e){var t=e.options,n=t.fetchPolicy,r=t.nextFetchPolicy;return"cache-and-network"===n||"network-only"===n?e.reobserve({fetchPolicy:"cache-first",nextFetchPolicy:function(){return(this.nextFetchPolicy=r,"function"==typeof r)?r.apply(this,arguments):n}}):e.reobserve()}function n6(e){__DEV__&&Q.kG.error("Unhandled error",e.message,e.stack)}function n5(e){__DEV__&&e&&__DEV__&&Q.kG.debug("Missing cache result fields: ".concat(JSON.stringify(e)),e)}function n8(e){return"network-only"===e||"no-cache"===e||"standby"===e}nK(n3);function n9(e){return e.kind===nL.h.FIELD||e.kind===nL.h.FRAGMENT_SPREAD||e.kind===nL.h.INLINE_FRAGMENT}function n7(e){return e.kind===Kind.SCALAR_TYPE_DEFINITION||e.kind===Kind.OBJECT_TYPE_DEFINITION||e.kind===Kind.INTERFACE_TYPE_DEFINITION||e.kind===Kind.UNION_TYPE_DEFINITION||e.kind===Kind.ENUM_TYPE_DEFINITION||e.kind===Kind.INPUT_OBJECT_TYPE_DEFINITION}function re(e){return e.kind===Kind.SCALAR_TYPE_EXTENSION||e.kind===Kind.OBJECT_TYPE_EXTENSION||e.kind===Kind.INTERFACE_TYPE_EXTENSION||e.kind===Kind.UNION_TYPE_EXTENSION||e.kind===Kind.ENUM_TYPE_EXTENSION||e.kind===Kind.INPUT_OBJECT_TYPE_EXTENSION}var rt=function(){return Object.create(null)},rn=Array.prototype,rr=rn.forEach,ri=rn.slice,ra=function(){function e(e,t){void 0===e&&(e=!0),void 0===t&&(t=rt),this.weakness=e,this.makeData=t}return e.prototype.lookup=function(){for(var e=[],t=0;tclass{constructor(){this.id=["slot",rc++,Date.now(),Math.random().toString(36).slice(2),].join(":")}hasValue(){for(let e=rs;e;e=e.parent)if(this.id in e.slots){let t=e.slots[this.id];if(t===ru)break;return e!==rs&&(rs.slots[this.id]=t),!0}return rs&&(rs.slots[this.id]=ru),!1}getValue(){if(this.hasValue())return rs.slots[this.id]}withValue(e,t,n,r){let i={__proto__:null,[this.id]:e},a=rs;rs={parent:a,slots:i};try{return t.apply(r,n)}finally{rs=a}}static bind(e){let t=rs;return function(){let n=rs;try{return rs=t,e.apply(this,arguments)}finally{rs=n}}}static noContext(e,t,n){if(!rs)return e.apply(n,t);{let r=rs;try{return rs=null,e.apply(n,t)}finally{rs=r}}}};function rf(e){try{return e()}catch(t){}}let rd="@wry/context:Slot",rh=rf(()=>globalThis)||rf(()=>global)||Object.create(null),rp=rh,rb=rp[rd]||Array[rd]||function(e){try{Object.defineProperty(rp,rd,{value:e,enumerable:!1,writable:!1,configurable:!0})}finally{return e}}(rl()),{bind:rm,noContext:rg}=rb;function rv(){}var ry=function(){function e(e,t){void 0===e&&(e=1/0),void 0===t&&(t=rv),this.max=e,this.dispose=t,this.map=new Map,this.newest=null,this.oldest=null}return e.prototype.has=function(e){return this.map.has(e)},e.prototype.get=function(e){var t=this.getNode(e);return t&&t.value},e.prototype.getNode=function(e){var t=this.map.get(e);if(t&&t!==this.newest){var n=t.older,r=t.newer;r&&(r.older=n),n&&(n.newer=r),t.older=this.newest,t.older.newer=t,t.newer=null,this.newest=t,t===this.oldest&&(this.oldest=r)}return t},e.prototype.set=function(e,t){var n=this.getNode(e);return n?n.value=t:(n={key:e,value:t,newer:null,older:this.newest},this.newest&&(this.newest.newer=n),this.newest=n,this.oldest=this.oldest||n,this.map.set(e,n),n.value)},e.prototype.clean=function(){for(;this.oldest&&this.map.size>this.max;)this.delete(this.oldest.key)},e.prototype.delete=function(e){var t=this.map.get(e);return!!t&&(t===this.newest&&(this.newest=t.older),t===this.oldest&&(this.oldest=t.newer),t.newer&&(t.newer.older=t.older),t.older&&(t.older.newer=t.newer),this.map.delete(e),this.dispose(t.value,e),!0)},e}(),rw=new rb,r_=Object.prototype.hasOwnProperty,rE=void 0===(n=Array.from)?function(e){var t=[];return e.forEach(function(e){return t.push(e)}),t}:n;function rS(e){var t=e.unsubscribe;"function"==typeof t&&(e.unsubscribe=void 0,t())}var rk=[],rx=100;function rT(e,t){if(!e)throw Error(t||"assertion failure")}function rM(e,t){var n=e.length;return n>0&&n===t.length&&e[n-1]===t[n-1]}function rO(e){switch(e.length){case 0:throw Error("unknown value");case 1:return e[0];case 2:throw e[1]}}function rA(e){return e.slice(0)}var rL=function(){function e(t){this.fn=t,this.parents=new Set,this.childValues=new Map,this.dirtyChildren=null,this.dirty=!0,this.recomputing=!1,this.value=[],this.deps=null,++e.count}return e.prototype.peek=function(){if(1===this.value.length&&!rN(this))return rC(this),this.value[0]},e.prototype.recompute=function(e){return rT(!this.recomputing,"already recomputing"),rC(this),rN(this)?rI(this,e):rO(this.value)},e.prototype.setDirty=function(){this.dirty||(this.dirty=!0,this.value.length=0,rR(this),rS(this))},e.prototype.dispose=function(){var e=this;this.setDirty(),rH(this),rF(this,function(t,n){t.setDirty(),r$(t,e)})},e.prototype.forget=function(){this.dispose()},e.prototype.dependOn=function(e){e.add(this),this.deps||(this.deps=rk.pop()||new Set),this.deps.add(e)},e.prototype.forgetDeps=function(){var e=this;this.deps&&(rE(this.deps).forEach(function(t){return t.delete(e)}),this.deps.clear(),rk.push(this.deps),this.deps=null)},e.count=0,e}();function rC(e){var t=rw.getValue();if(t)return e.parents.add(t),t.childValues.has(e)||t.childValues.set(e,[]),rN(e)?rY(t,e):rB(t,e),t}function rI(e,t){return rH(e),rw.withValue(e,rD,[e,t]),rz(e,t)&&rP(e),rO(e.value)}function rD(e,t){e.recomputing=!0,e.value.length=0;try{e.value[0]=e.fn.apply(null,t)}catch(n){e.value[1]=n}e.recomputing=!1}function rN(e){return e.dirty||!!(e.dirtyChildren&&e.dirtyChildren.size)}function rP(e){e.dirty=!1,!rN(e)&&rj(e)}function rR(e){rF(e,rY)}function rj(e){rF(e,rB)}function rF(e,t){var n=e.parents.size;if(n)for(var r=rE(e.parents),i=0;i0&&e.childValues.forEach(function(t,n){r$(e,n)}),e.forgetDeps(),rT(null===e.dirtyChildren)}function r$(e,t){t.parents.delete(e),e.childValues.delete(t),rU(e,t)}function rz(e,t){if("function"==typeof e.subscribe)try{rS(e),e.unsubscribe=e.subscribe.apply(null,t)}catch(n){return e.setDirty(),!1}return!0}var rG={setDirty:!0,dispose:!0,forget:!0};function rW(e){var t=new Map,n=e&&e.subscribe;function r(e){var r=rw.getValue();if(r){var i=t.get(e);i||t.set(e,i=new Set),r.dependOn(i),"function"==typeof n&&(rS(i),i.unsubscribe=n(e))}}return r.dirty=function(e,n){var r=t.get(e);if(r){var i=n&&r_.call(rG,n)?n:"setDirty";rE(r).forEach(function(e){return e[i]()}),t.delete(e),rS(r)}},r}function rK(){var e=new ra("function"==typeof WeakMap);return function(){return e.lookupArray(arguments)}}var rV=rK(),rq=new Set;function rZ(e,t){void 0===t&&(t=Object.create(null));var n=new ry(t.max||65536,function(e){return e.dispose()}),r=t.keyArgs,i=t.makeCacheKey||rK(),a=function(){var a=i.apply(null,r?r.apply(null,arguments):arguments);if(void 0===a)return e.apply(null,arguments);var o=n.get(a);o||(n.set(a,o=new rL(e)),o.subscribe=t.subscribe,o.forget=function(){return n.delete(a)});var s=o.recompute(Array.prototype.slice.call(arguments));return n.set(a,o),rq.add(n),rw.hasValue()||(rq.forEach(function(e){return e.clean()}),rq.clear()),s};function o(e){var t=n.get(e);t&&t.setDirty()}function s(e){var t=n.get(e);if(t)return t.peek()}function u(e){return n.delete(e)}return Object.defineProperty(a,"size",{get:function(){return n.map.size},configurable:!1,enumerable:!1}),a.dirtyKey=o,a.dirty=function(){o(i.apply(null,arguments))},a.peekKey=s,a.peek=function(){return s(i.apply(null,arguments))},a.forgetKey=u,a.forget=function(){return u(i.apply(null,arguments))},a.makeCacheKey=i,a.getKey=r?function(){return i.apply(null,r.apply(null,arguments))}:i,Object.freeze(a)}var rX=new rb,rJ=new WeakMap;function rQ(e){var t=rJ.get(e);return t||rJ.set(e,t={vars:new Set,dep:rW()}),t}function r1(e){rQ(e).vars.forEach(function(t){return t.forgetCache(e)})}function r0(e){rQ(e).vars.forEach(function(t){return t.attachCache(e)})}function r2(e){var t=new Set,n=new Set,r=function(a){if(arguments.length>0){if(e!==a){e=a,t.forEach(function(e){rQ(e).dep.dirty(r),r3(e)});var o=Array.from(n);n.clear(),o.forEach(function(t){return t(e)})}}else{var s=rX.getValue();s&&(i(s),rQ(s).dep(r))}return e};r.onNextChange=function(e){return n.add(e),function(){n.delete(e)}};var i=r.attachCache=function(e){return t.add(e),rQ(e).vars.add(r),r};return r.forgetCache=function(e){return t.delete(e)},r}function r3(e){e.broadcastWatches&&e.broadcastWatches()}var r4=function(){function e(e){var t=e.cache,n=e.client,r=e.resolvers,i=e.fragmentMatcher;this.selectionsToResolveCache=new WeakMap,this.cache=t,n&&(this.client=n),r&&this.addResolvers(r),i&&this.setFragmentMatcher(i)}return e.prototype.addResolvers=function(e){var t=this;this.resolvers=this.resolvers||{},Array.isArray(e)?e.forEach(function(e){t.resolvers=tj(t.resolvers,e)}):this.resolvers=tj(this.resolvers,e)},e.prototype.setResolvers=function(e){this.resolvers={},this.addResolvers(e)},e.prototype.getResolvers=function(){return this.resolvers||{}},e.prototype.runResolvers=function(e){var t=e.document,n=e.remoteResult,r=e.context,i=e.variables,a=e.onlyRunForcedResolvers,o=void 0!==a&&a;return(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(e){return t?[2,this.resolveDocument(t,n.data,r,i,this.fragmentMatcher,o).then(function(e){return(0,en.pi)((0,en.pi)({},n),{data:e.result})})]:[2,n]})})},e.prototype.setFragmentMatcher=function(e){this.fragmentMatcher=e},e.prototype.getFragmentMatcher=function(){return this.fragmentMatcher},e.prototype.clientQuery=function(e){return tb(["client"],e)&&this.resolvers?e:null},e.prototype.serverQuery=function(e){return n$(e)},e.prototype.prepareContext=function(e){var t=this.cache;return(0,en.pi)((0,en.pi)({},e),{cache:t,getCacheKey:function(e){return t.identify(e)}})},e.prototype.addExportedVariables=function(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(r){return e?[2,this.resolveDocument(e,this.buildRootValueFromCache(e,t)||{},this.prepareContext(n),t).then(function(e){return(0,en.pi)((0,en.pi)({},t),e.exportedVariables)})]:[2,(0,en.pi)({},t)]})})},e.prototype.shouldForceResolvers=function(e){var t=!1;return tl(e,{Directive:{enter:function(e){if("client"===e.name.value&&e.arguments&&(t=e.arguments.some(function(e){return"always"===e.name.value&&"BooleanValue"===e.value.kind&&!0===e.value.value})))return tc}}}),t},e.prototype.buildRootValueFromCache=function(e,t){return this.cache.diff({query:nH(e),variables:t,returnPartialData:!0,optimistic:!1}).result},e.prototype.resolveDocument=function(e,t,n,r,i,a){return void 0===n&&(n={}),void 0===r&&(r={}),void 0===i&&(i=function(){return!0}),void 0===a&&(a=!1),(0,en.mG)(this,void 0,void 0,function(){var o,s,u,c,l,f,d,h,p,b,m;return(0,en.Jh)(this,function(g){return o=e8(e),s=e4(e),u=eL(s),c=this.collectSelectionsToResolve(o,u),f=(l=o.operation)?l.charAt(0).toUpperCase()+l.slice(1):"Query",d=this,h=d.cache,p=d.client,b={fragmentMap:u,context:(0,en.pi)((0,en.pi)({},n),{cache:h,client:p}),variables:r,fragmentMatcher:i,defaultOperationType:f,exportedVariables:{},selectionsToResolve:c,onlyRunForcedResolvers:a},m=!1,[2,this.resolveSelectionSet(o.selectionSet,m,t,b).then(function(e){return{result:e,exportedVariables:b.exportedVariables}})]})})},e.prototype.resolveSelectionSet=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c=this;return(0,en.Jh)(this,function(l){return i=r.fragmentMap,a=r.context,o=r.variables,s=[n],u=function(e){return(0,en.mG)(c,void 0,void 0,function(){var u,c;return(0,en.Jh)(this,function(l){return(t||r.selectionsToResolve.has(e))&&td(e,o)?eQ(e)?[2,this.resolveField(e,t,n,r).then(function(t){var n;void 0!==t&&s.push(((n={})[eX(e)]=t,n))})]:(e1(e)?u=e:(u=i[e.name.value],__DEV__?(0,Q.kG)(u,"No fragment named ".concat(e.name.value)):(0,Q.kG)(u,11)),u&&u.typeCondition&&(c=u.typeCondition.name.value,r.fragmentMatcher(n,c,a)))?[2,this.resolveSelectionSet(u.selectionSet,t,n,r).then(function(e){s.push(e)})]:[2]:[2]})})},[2,Promise.all(e.selections.map(u)).then(function(){return tF(s)})]})})},e.prototype.resolveField=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c,l,f,d,h=this;return(0,en.Jh)(this,function(p){return n?(i=r.variables,a=e.name.value,o=eX(e),s=a!==o,c=Promise.resolve(u=n[o]||n[a]),(!r.onlyRunForcedResolvers||this.shouldForceResolvers(e))&&(l=n.__typename||r.defaultOperationType,(f=this.resolvers&&this.resolvers[l])&&(d=f[s?a:o])&&(c=Promise.resolve(rX.withValue(this.cache,d,[n,eZ(e,i),r.context,{field:e,fragmentMap:r.fragmentMap},])))),[2,c.then(function(n){if(void 0===n&&(n=u),e.directives&&e.directives.forEach(function(e){"export"===e.name.value&&e.arguments&&e.arguments.forEach(function(e){"as"===e.name.value&&"StringValue"===e.value.kind&&(r.exportedVariables[e.value.value]=n)})}),!e.selectionSet||null==n)return n;var i,a,o=null!==(a=null===(i=e.directives)||void 0===i?void 0:i.some(function(e){return"client"===e.name.value}))&&void 0!==a&&a;return Array.isArray(n)?h.resolveSubSelectedArray(e,t||o,n,r):e.selectionSet?h.resolveSelectionSet(e.selectionSet,t||o,n,r):void 0})]):[2,null]})})},e.prototype.resolveSubSelectedArray=function(e,t,n,r){var i=this;return Promise.all(n.map(function(n){return null===n?null:Array.isArray(n)?i.resolveSubSelectedArray(e,t,n,r):e.selectionSet?i.resolveSelectionSet(e.selectionSet,t,n,r):void 0}))},e.prototype.collectSelectionsToResolve=function(e,t){var n=function(e){return!Array.isArray(e)},r=this.selectionsToResolveCache;function i(e){if(!r.has(e)){var a=new Set;r.set(e,a),tl(e,{Directive:function(e,t,r,i,o){"client"===e.name.value&&o.forEach(function(e){n(e)&&n9(e)&&a.add(e)})},FragmentSpread:function(e,r,o,s,u){var c=t[e.name.value];__DEV__?(0,Q.kG)(c,"No fragment named ".concat(e.name.value)):(0,Q.kG)(c,12);var l=i(c);l.size>0&&(u.forEach(function(e){n(e)&&n9(e)&&a.add(e)}),a.add(e),l.forEach(function(e){a.add(e)}))}})}return r.get(e)}return i(e)},e}(),r6=new(t_.mr?WeakMap:Map);function r5(e,t){var n=e[t];"function"==typeof n&&(e[t]=function(){return r6.set(e,(r6.get(e)+1)%1e15),n.apply(this,arguments)})}function r8(e){e.notifyTimeout&&(clearTimeout(e.notifyTimeout),e.notifyTimeout=void 0)}var r9=function(){function e(e,t){void 0===t&&(t=e.generateQueryId()),this.queryId=t,this.listeners=new Set,this.document=null,this.lastRequestId=1,this.subscriptions=new Set,this.stopped=!1,this.dirty=!1,this.observableQuery=null;var n=this.cache=e.cache;r6.has(n)||(r6.set(n,0),r5(n,"evict"),r5(n,"modify"),r5(n,"reset"))}return e.prototype.init=function(e){var t=e.networkStatus||nZ.I.loading;return this.variables&&this.networkStatus!==nZ.I.loading&&!(0,nm.D)(this.variables,e.variables)&&(t=nZ.I.setVariables),(0,nm.D)(e.variables,this.variables)||(this.lastDiff=void 0),Object.assign(this,{document:e.document,variables:e.variables,networkError:null,graphQLErrors:this.graphQLErrors||[],networkStatus:t}),e.observableQuery&&this.setObservableQuery(e.observableQuery),e.lastRequestId&&(this.lastRequestId=e.lastRequestId),this},e.prototype.reset=function(){r8(this),this.dirty=!1},e.prototype.getDiff=function(e){void 0===e&&(e=this.variables);var t=this.getDiffOptions(e);if(this.lastDiff&&(0,nm.D)(t,this.lastDiff.options))return this.lastDiff.diff;this.updateWatch(this.variables=e);var n=this.observableQuery;if(n&&"no-cache"===n.options.fetchPolicy)return{complete:!1};var r=this.cache.diff(t);return this.updateLastDiff(r,t),r},e.prototype.updateLastDiff=function(e,t){this.lastDiff=e?{diff:e,options:t||this.getDiffOptions()}:void 0},e.prototype.getDiffOptions=function(e){var t;return void 0===e&&(e=this.variables),{query:this.document,variables:e,returnPartialData:!0,optimistic:!0,canonizeResults:null===(t=this.observableQuery)||void 0===t?void 0:t.options.canonizeResults}},e.prototype.setDiff=function(e){var t=this,n=this.lastDiff&&this.lastDiff.diff;this.updateLastDiff(e),this.dirty||(0,nm.D)(n&&n.result,e&&e.result)||(this.dirty=!0,this.notifyTimeout||(this.notifyTimeout=setTimeout(function(){return t.notify()},0)))},e.prototype.setObservableQuery=function(e){var t=this;e!==this.observableQuery&&(this.oqListener&&this.listeners.delete(this.oqListener),this.observableQuery=e,e?(e.queryInfo=this,this.listeners.add(this.oqListener=function(){t.getDiff().fromOptimisticTransaction?e.observe():n4(e)})):delete this.oqListener)},e.prototype.notify=function(){var e=this;r8(this),this.shouldNotify()&&this.listeners.forEach(function(t){return t(e)}),this.dirty=!1},e.prototype.shouldNotify=function(){if(!this.dirty||!this.listeners.size)return!1;if((0,nZ.O)(this.networkStatus)&&this.observableQuery){var e=this.observableQuery.options.fetchPolicy;if("cache-only"!==e&&"cache-and-network"!==e)return!1}return!0},e.prototype.stop=function(){if(!this.stopped){this.stopped=!0,this.reset(),this.cancel(),this.cancel=e.prototype.cancel,this.subscriptions.forEach(function(e){return e.unsubscribe()});var t=this.observableQuery;t&&t.stopPolling()}},e.prototype.cancel=function(){},e.prototype.updateWatch=function(e){var t=this;void 0===e&&(e=this.variables);var n=this.observableQuery;if(!n||"no-cache"!==n.options.fetchPolicy){var r=(0,en.pi)((0,en.pi)({},this.getDiffOptions(e)),{watcher:this,callback:function(e){return t.setDiff(e)}});this.lastWatch&&(0,nm.D)(r,this.lastWatch)||(this.cancel(),this.cancel=this.cache.watch(this.lastWatch=r))}},e.prototype.resetLastWrite=function(){this.lastWrite=void 0},e.prototype.shouldWrite=function(e,t){var n=this.lastWrite;return!(n&&n.dmCount===r6.get(this.cache)&&(0,nm.D)(t,n.variables)&&(0,nm.D)(e.data,n.result.data))},e.prototype.markResult=function(e,t,n,r){var i=this,a=new tB,o=(0,tP.O)(e.errors)?e.errors.slice(0):[];if(this.reset(),"incremental"in e&&(0,tP.O)(e.incremental)){var s=tG(this.getDiff().result,e);e.data=s}else if("hasNext"in e&&e.hasNext){var u=this.getDiff();e.data=a.merge(u.result,e.data)}this.graphQLErrors=o,"no-cache"===n.fetchPolicy?this.updateLastDiff({result:e.data,complete:!0},this.getDiffOptions(n.variables)):0!==r&&(r7(e,n.errorPolicy)?this.cache.performTransaction(function(a){if(i.shouldWrite(e,n.variables))a.writeQuery({query:t,data:e.data,variables:n.variables,overwrite:1===r}),i.lastWrite={result:e,variables:n.variables,dmCount:r6.get(i.cache)};else if(i.lastDiff&&i.lastDiff.diff.complete){e.data=i.lastDiff.diff.result;return}var o=i.getDiffOptions(n.variables),s=a.diff(o);i.stopped||i.updateWatch(n.variables),i.updateLastDiff(s,o),s.complete&&(e.data=s.result)}):this.lastWrite=void 0)},e.prototype.markReady=function(){return this.networkError=null,this.networkStatus=nZ.I.ready},e.prototype.markError=function(e){return this.networkStatus=nZ.I.error,this.lastWrite=void 0,this.reset(),e.graphQLErrors&&(this.graphQLErrors=e.graphQLErrors),e.networkError&&(this.networkError=e.networkError),e},e}();function r7(e,t){void 0===t&&(t="none");var n="ignore"===t||"all"===t,r=!nO(e);return!r&&n&&e.data&&(r=!0),r}var ie=Object.prototype.hasOwnProperty,it=function(){function e(e){var t=e.cache,n=e.link,r=e.defaultOptions,i=e.queryDeduplication,a=void 0!==i&&i,o=e.onBroadcast,s=e.ssrMode,u=void 0!==s&&s,c=e.clientAwareness,l=void 0===c?{}:c,f=e.localState,d=e.assumeImmutableResults;this.clientAwareness={},this.queries=new Map,this.fetchCancelFns=new Map,this.transformCache=new(t_.mr?WeakMap:Map),this.queryIdCounter=1,this.requestIdCounter=1,this.mutationIdCounter=1,this.inFlightLinkObservables=new Map,this.cache=t,this.link=n,this.defaultOptions=r||Object.create(null),this.queryDeduplication=a,this.clientAwareness=l,this.localState=f||new r4({cache:t}),this.ssrMode=u,this.assumeImmutableResults=!!d,(this.onBroadcast=o)&&(this.mutationStore=Object.create(null))}return e.prototype.stop=function(){var e=this;this.queries.forEach(function(t,n){e.stopQueryNoBroadcast(n)}),this.cancelPendingFetches(__DEV__?new Q.ej("QueryManager stopped while query was in flight"):new Q.ej(14))},e.prototype.cancelPendingFetches=function(e){this.fetchCancelFns.forEach(function(t){return t(e)}),this.fetchCancelFns.clear()},e.prototype.mutate=function(e){var t,n,r=e.mutation,i=e.variables,a=e.optimisticResponse,o=e.updateQueries,s=e.refetchQueries,u=void 0===s?[]:s,c=e.awaitRefetchQueries,l=void 0!==c&&c,f=e.update,d=e.onQueryUpdated,h=e.fetchPolicy,p=void 0===h?(null===(t=this.defaultOptions.mutate)||void 0===t?void 0:t.fetchPolicy)||"network-only":h,b=e.errorPolicy,m=void 0===b?(null===(n=this.defaultOptions.mutate)||void 0===n?void 0:n.errorPolicy)||"none":b,g=e.keepRootFields,v=e.context;return(0,en.mG)(this,void 0,void 0,function(){var e,t,n,s,c,h;return(0,en.Jh)(this,function(b){switch(b.label){case 0:if(__DEV__?(0,Q.kG)(r,"mutation option is required. You must specify your GraphQL document in the mutation option."):(0,Q.kG)(r,15),__DEV__?(0,Q.kG)("network-only"===p||"no-cache"===p,"Mutations support only 'network-only' or 'no-cache' fetchPolicy strings. The default `network-only` behavior automatically writes mutation results to the cache. Passing `no-cache` skips the cache write."):(0,Q.kG)("network-only"===p||"no-cache"===p,16),e=this.generateMutationId(),n=(t=this.transform(r)).document,s=t.hasClientExports,r=this.cache.transformForLink(n),i=this.getVariables(r,i),!s)return[3,2];return[4,this.localState.addExportedVariables(r,i,v)];case 1:i=b.sent(),b.label=2;case 2:return c=this.mutationStore&&(this.mutationStore[e]={mutation:r,variables:i,loading:!0,error:null}),a&&this.markMutationOptimistic(a,{mutationId:e,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,updateQueries:o,update:f,keepRootFields:g}),this.broadcastQueries(),h=this,[2,new Promise(function(t,n){return nM(h.getObservableFromLink(r,(0,en.pi)((0,en.pi)({},v),{optimisticResponse:a}),i,!1),function(t){if(nO(t)&&"none"===m)throw new tN.cA({graphQLErrors:nA(t)});c&&(c.loading=!1,c.error=null);var n=(0,en.pi)({},t);return"function"==typeof u&&(u=u(n)),"ignore"===m&&nO(n)&&delete n.errors,h.markMutationResult({mutationId:e,result:n,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,update:f,updateQueries:o,awaitRefetchQueries:l,refetchQueries:u,removeOptimistic:a?e:void 0,onQueryUpdated:d,keepRootFields:g})}).subscribe({next:function(e){h.broadcastQueries(),"hasNext"in e&&!1!==e.hasNext||t(e)},error:function(t){c&&(c.loading=!1,c.error=t),a&&h.cache.removeOptimistic(e),h.broadcastQueries(),n(t instanceof tN.cA?t:new tN.cA({networkError:t}))}})})]}})})},e.prototype.markMutationResult=function(e,t){var n=this;void 0===t&&(t=this.cache);var r=e.result,i=[],a="no-cache"===e.fetchPolicy;if(!a&&r7(r,e.errorPolicy)){if(tU(r)||i.push({result:r.data,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}),tU(r)&&(0,tP.O)(r.incremental)){var o=t.diff({id:"ROOT_MUTATION",query:this.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0}),s=void 0;o.result&&(s=tG(o.result,r)),void 0!==s&&(r.data=s,i.push({result:s,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}))}var u=e.updateQueries;u&&this.queries.forEach(function(e,a){var o=e.observableQuery,s=o&&o.queryName;if(s&&ie.call(u,s)){var c,l=u[s],f=n.queries.get(a),d=f.document,h=f.variables,p=t.diff({query:d,variables:h,returnPartialData:!0,optimistic:!1}),b=p.result;if(p.complete&&b){var m=l(b,{mutationResult:r,queryName:d&&e3(d)||void 0,queryVariables:h});m&&i.push({result:m,dataId:"ROOT_QUERY",query:d,variables:h})}}})}if(i.length>0||e.refetchQueries||e.update||e.onQueryUpdated||e.removeOptimistic){var c=[];if(this.refetchQueries({updateCache:function(t){a||i.forEach(function(e){return t.write(e)});var o=e.update,s=!t$(r)||tU(r)&&!r.hasNext;if(o){if(!a){var u=t.diff({id:"ROOT_MUTATION",query:n.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0});u.complete&&("incremental"in(r=(0,en.pi)((0,en.pi)({},r),{data:u.result}))&&delete r.incremental,"hasNext"in r&&delete r.hasNext)}s&&o(t,r,{context:e.context,variables:e.variables})}a||e.keepRootFields||!s||t.modify({id:"ROOT_MUTATION",fields:function(e,t){var n=t.fieldName,r=t.DELETE;return"__typename"===n?e:r}})},include:e.refetchQueries,optimistic:!1,removeOptimistic:e.removeOptimistic,onQueryUpdated:e.onQueryUpdated||null}).forEach(function(e){return c.push(e)}),e.awaitRefetchQueries||e.onQueryUpdated)return Promise.all(c).then(function(){return r})}return Promise.resolve(r)},e.prototype.markMutationOptimistic=function(e,t){var n=this,r="function"==typeof e?e(t.variables):e;return this.cache.recordOptimisticTransaction(function(e){try{n.markMutationResult((0,en.pi)((0,en.pi)({},t),{result:{data:r}}),e)}catch(i){__DEV__&&Q.kG.error(i)}},t.mutationId)},e.prototype.fetchQuery=function(e,t,n){return this.fetchQueryObservable(e,t,n).promise},e.prototype.getQueryStore=function(){var e=Object.create(null);return this.queries.forEach(function(t,n){e[n]={variables:t.variables,networkStatus:t.networkStatus,networkError:t.networkError,graphQLErrors:t.graphQLErrors}}),e},e.prototype.resetErrors=function(e){var t=this.queries.get(e);t&&(t.networkError=void 0,t.graphQLErrors=[])},e.prototype.transform=function(e){var t=this.transformCache;if(!t.has(e)){var n=this.cache.transformDocument(e),r=nY(n),i=this.localState.clientQuery(n),a=r&&this.localState.serverQuery(r),o={document:n,hasClientExports:tm(n),hasForcedResolvers:this.localState.shouldForceResolvers(n),clientQuery:i,serverQuery:a,defaultVars:e9(e2(n)),asQuery:(0,en.pi)((0,en.pi)({},n),{definitions:n.definitions.map(function(e){return"OperationDefinition"===e.kind&&"query"!==e.operation?(0,en.pi)((0,en.pi)({},e),{operation:"query"}):e})})},s=function(e){e&&!t.has(e)&&t.set(e,o)};s(e),s(n),s(i),s(a)}return t.get(e)},e.prototype.getVariables=function(e,t){return(0,en.pi)((0,en.pi)({},this.transform(e).defaultVars),t)},e.prototype.watchQuery=function(e){void 0===(e=(0,en.pi)((0,en.pi)({},e),{variables:this.getVariables(e.query,e.variables)})).notifyOnNetworkStatusChange&&(e.notifyOnNetworkStatusChange=!1);var t=new r9(this),n=new n3({queryManager:this,queryInfo:t,options:e});return this.queries.set(n.queryId,t),t.init({document:n.query,observableQuery:n,variables:n.variables}),n},e.prototype.query=function(e,t){var n=this;return void 0===t&&(t=this.generateQueryId()),__DEV__?(0,Q.kG)(e.query,"query option is required. You must specify your GraphQL document in the query option."):(0,Q.kG)(e.query,17),__DEV__?(0,Q.kG)("Document"===e.query.kind,'You must wrap the query string in a "gql" tag.'):(0,Q.kG)("Document"===e.query.kind,18),__DEV__?(0,Q.kG)(!e.returnPartialData,"returnPartialData option only supported on watchQuery."):(0,Q.kG)(!e.returnPartialData,19),__DEV__?(0,Q.kG)(!e.pollInterval,"pollInterval option only supported on watchQuery."):(0,Q.kG)(!e.pollInterval,20),this.fetchQuery(t,e).finally(function(){return n.stopQuery(t)})},e.prototype.generateQueryId=function(){return String(this.queryIdCounter++)},e.prototype.generateRequestId=function(){return this.requestIdCounter++},e.prototype.generateMutationId=function(){return String(this.mutationIdCounter++)},e.prototype.stopQueryInStore=function(e){this.stopQueryInStoreNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryInStoreNoBroadcast=function(e){var t=this.queries.get(e);t&&t.stop()},e.prototype.clearStore=function(e){return void 0===e&&(e={discardWatches:!0}),this.cancelPendingFetches(__DEV__?new Q.ej("Store reset while query was in flight (not completed in link chain)"):new Q.ej(21)),this.queries.forEach(function(e){e.observableQuery?e.networkStatus=nZ.I.loading:e.stop()}),this.mutationStore&&(this.mutationStore=Object.create(null)),this.cache.reset(e)},e.prototype.getObservableQueries=function(e){var t=this;void 0===e&&(e="active");var n=new Map,r=new Map,i=new Set;return Array.isArray(e)&&e.forEach(function(e){"string"==typeof e?r.set(e,!1):eN(e)?r.set(t.transform(e).document,!1):(0,eO.s)(e)&&e.query&&i.add(e)}),this.queries.forEach(function(t,i){var a=t.observableQuery,o=t.document;if(a){if("all"===e){n.set(i,a);return}var s=a.queryName;if("standby"===a.options.fetchPolicy||"active"===e&&!a.hasObservers())return;("active"===e||s&&r.has(s)||o&&r.has(o))&&(n.set(i,a),s&&r.set(s,!0),o&&r.set(o,!0))}}),i.size&&i.forEach(function(e){var r=nG("legacyOneTimeQuery"),i=t.getQuery(r).init({document:e.query,variables:e.variables}),a=new n3({queryManager:t,queryInfo:i,options:(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"network-only"})});(0,Q.kG)(a.queryId===r),i.setObservableQuery(a),n.set(r,a)}),__DEV__&&r.size&&r.forEach(function(e,t){!e&&__DEV__&&Q.kG.warn("Unknown query ".concat("string"==typeof t?"named ":"").concat(JSON.stringify(t,null,2)," requested in refetchQueries options.include array"))}),n},e.prototype.reFetchObservableQueries=function(e){var t=this;void 0===e&&(e=!1);var n=[];return this.getObservableQueries(e?"all":"active").forEach(function(r,i){var a=r.options.fetchPolicy;r.resetLastResults(),(e||"standby"!==a&&"cache-only"!==a)&&n.push(r.refetch()),t.getQuery(i).setDiff(null)}),this.broadcastQueries(),Promise.all(n)},e.prototype.setObservableQuery=function(e){this.getQuery(e.queryId).setObservableQuery(e)},e.prototype.startGraphQLSubscription=function(e){var t=this,n=e.query,r=e.fetchPolicy,i=e.errorPolicy,a=e.variables,o=e.context,s=void 0===o?{}:o;n=this.transform(n).document,a=this.getVariables(n,a);var u=function(e){return t.getObservableFromLink(n,s,e).map(function(a){"no-cache"!==r&&(r7(a,i)&&t.cache.write({query:n,result:a.data,dataId:"ROOT_SUBSCRIPTION",variables:e}),t.broadcastQueries());var o=nO(a),s=(0,tN.ls)(a);if(o||s){var u={};throw o&&(u.graphQLErrors=a.errors),s&&(u.protocolErrors=a.extensions[tN.YG]),new tN.cA(u)}return a})};if(this.transform(n).hasClientExports){var c=this.localState.addExportedVariables(n,a,s).then(u);return new eT(function(e){var t=null;return c.then(function(n){return t=n.subscribe(e)},e.error),function(){return t&&t.unsubscribe()}})}return u(a)},e.prototype.stopQuery=function(e){this.stopQueryNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryNoBroadcast=function(e){this.stopQueryInStoreNoBroadcast(e),this.removeQuery(e)},e.prototype.removeQuery=function(e){this.fetchCancelFns.delete(e),this.queries.has(e)&&(this.getQuery(e).stop(),this.queries.delete(e))},e.prototype.broadcastQueries=function(){this.onBroadcast&&this.onBroadcast(),this.queries.forEach(function(e){return e.notify()})},e.prototype.getLocalState=function(){return this.localState},e.prototype.getObservableFromLink=function(e,t,n,r){var i,a,o=this;void 0===r&&(r=null!==(i=null==t?void 0:t.queryDeduplication)&&void 0!==i?i:this.queryDeduplication);var s=this.transform(e).serverQuery;if(s){var u=this,c=u.inFlightLinkObservables,l=u.link,f={query:s,variables:n,operationName:e3(s)||void 0,context:this.prepareContext((0,en.pi)((0,en.pi)({},t),{forceFetch:!r}))};if(t=f.context,r){var d=c.get(s)||new Map;c.set(s,d);var h=nx(n);if(!(a=d.get(h))){var p=new nq([np(l,f)]);d.set(h,a=p),p.beforeNext(function(){d.delete(h)&&d.size<1&&c.delete(s)})}}else a=new nq([np(l,f)])}else a=new nq([eT.of({data:{}})]),t=this.prepareContext(t);var b=this.transform(e).clientQuery;return b&&(a=nM(a,function(e){return o.localState.runResolvers({document:b,remoteResult:e,context:t,variables:n})})),a},e.prototype.getResultsFromLink=function(e,t,n){var r=e.lastRequestId=this.generateRequestId(),i=this.cache.transformForLink(this.transform(e.document).document);return nM(this.getObservableFromLink(i,n.context,n.variables),function(a){var o=nA(a),s=o.length>0;if(r>=e.lastRequestId){if(s&&"none"===n.errorPolicy)throw e.markError(new tN.cA({graphQLErrors:o}));e.markResult(a,i,n,t),e.markReady()}var u={data:a.data,loading:!1,networkStatus:nZ.I.ready};return s&&"ignore"!==n.errorPolicy&&(u.errors=o,u.networkStatus=nZ.I.error),u},function(t){var n=(0,tN.MS)(t)?t:new tN.cA({networkError:t});throw r>=e.lastRequestId&&e.markError(n),n})},e.prototype.fetchQueryObservable=function(e,t,n){return this.fetchConcastWithInfo(e,t,n).concast},e.prototype.fetchConcastWithInfo=function(e,t,n){var r,i,a=this;void 0===n&&(n=nZ.I.loading);var o=this.transform(t.query).document,s=this.getVariables(o,t.variables),u=this.getQuery(e),c=this.defaultOptions.watchQuery,l=t.fetchPolicy,f=void 0===l?c&&c.fetchPolicy||"cache-first":l,d=t.errorPolicy,h=void 0===d?c&&c.errorPolicy||"none":d,p=t.returnPartialData,b=void 0!==p&&p,m=t.notifyOnNetworkStatusChange,g=void 0!==m&&m,v=t.context,y=void 0===v?{}:v,w=Object.assign({},t,{query:o,variables:s,fetchPolicy:f,errorPolicy:h,returnPartialData:b,notifyOnNetworkStatusChange:g,context:y}),_=function(e){w.variables=e;var r=a.fetchQueryByPolicy(u,w,n);return"standby"!==w.fetchPolicy&&r.sources.length>0&&u.observableQuery&&u.observableQuery.applyNextFetchPolicy("after-fetch",t),r},E=function(){return a.fetchCancelFns.delete(e)};if(this.fetchCancelFns.set(e,function(e){E(),setTimeout(function(){return r.cancel(e)})}),this.transform(w.query).hasClientExports)r=new nq(this.localState.addExportedVariables(w.query,w.variables,w.context).then(_).then(function(e){return e.sources})),i=!0;else{var S=_(w.variables);i=S.fromLink,r=new nq(S.sources)}return r.promise.then(E,E),{concast:r,fromLink:i}},e.prototype.refetchQueries=function(e){var t=this,n=e.updateCache,r=e.include,i=e.optimistic,a=void 0!==i&&i,o=e.removeOptimistic,s=void 0===o?a?nG("refetchQueries"):void 0:o,u=e.onQueryUpdated,c=new Map;r&&this.getObservableQueries(r).forEach(function(e,n){c.set(n,{oq:e,lastDiff:t.getQuery(n).getDiff()})});var l=new Map;return n&&this.cache.batch({update:n,optimistic:a&&s||!1,removeOptimistic:s,onWatchUpdated:function(e,t,n){var r=e.watcher instanceof r9&&e.watcher.observableQuery;if(r){if(u){c.delete(r.queryId);var i=u(r,t,n);return!0===i&&(i=r.refetch()),!1!==i&&l.set(r,i),i}null!==u&&c.set(r.queryId,{oq:r,lastDiff:n,diff:t})}}}),c.size&&c.forEach(function(e,n){var r,i=e.oq,a=e.lastDiff,o=e.diff;if(u){if(!o){var s=i.queryInfo;s.reset(),o=s.getDiff()}r=u(i,o,a)}u&&!0!==r||(r=i.refetch()),!1!==r&&l.set(i,r),n.indexOf("legacyOneTimeQuery")>=0&&t.stopQueryNoBroadcast(n)}),s&&this.cache.removeOptimistic(s),l},e.prototype.fetchQueryByPolicy=function(e,t,n){var r=this,i=t.query,a=t.variables,o=t.fetchPolicy,s=t.refetchWritePolicy,u=t.errorPolicy,c=t.returnPartialData,l=t.context,f=t.notifyOnNetworkStatusChange,d=e.networkStatus;e.init({document:this.transform(i).document,variables:a,networkStatus:n});var h=function(){return e.getDiff(a)},p=function(t,n){void 0===n&&(n=e.networkStatus||nZ.I.loading);var o=t.result;!__DEV__||c||(0,nm.D)(o,{})||n5(t.missing);var s=function(e){return eT.of((0,en.pi)({data:e,loading:(0,nZ.O)(n),networkStatus:n},t.complete?null:{partial:!0}))};return o&&r.transform(i).hasForcedResolvers?r.localState.runResolvers({document:i,remoteResult:{data:o},context:l,variables:a,onlyRunForcedResolvers:!0}).then(function(e){return s(e.data||void 0)}):"none"===u&&n===nZ.I.refetch&&Array.isArray(t.missing)?s(void 0):s(o)},b="no-cache"===o?0:n===nZ.I.refetch&&"merge"!==s?1:2,m=function(){return r.getResultsFromLink(e,b,{variables:a,context:l,fetchPolicy:o,errorPolicy:u})},g=f&&"number"==typeof d&&d!==n&&(0,nZ.O)(n);switch(o){default:case"cache-first":var v=h();if(v.complete)return{fromLink:!1,sources:[p(v,e.markReady())]};if(c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-and-network":var v=h();if(v.complete||c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-only":return{fromLink:!1,sources:[p(h(),e.markReady())]};case"network-only":if(g)return{fromLink:!0,sources:[p(h()),m()]};return{fromLink:!0,sources:[m()]};case"no-cache":if(g)return{fromLink:!0,sources:[p(e.getDiff()),m(),]};return{fromLink:!0,sources:[m()]};case"standby":return{fromLink:!1,sources:[]}}},e.prototype.getQuery=function(e){return e&&!this.queries.has(e)&&this.queries.set(e,new r9(this,e)),this.queries.get(e)},e.prototype.prepareContext=function(e){void 0===e&&(e={});var t=this.localState.prepareContext(e);return(0,en.pi)((0,en.pi)({},t),{clientAwareness:this.clientAwareness})},e}(),ir=__webpack_require__(14012),ii=!1,ia=function(){function e(e){var t=this;this.resetStoreCallbacks=[],this.clearStoreCallbacks=[];var n=e.uri,r=e.credentials,i=e.headers,a=e.cache,o=e.ssrMode,s=void 0!==o&&o,u=e.ssrForceFetchDelay,c=void 0===u?0:u,l=e.connectToDevTools,f=void 0===l?"object"==typeof window&&!window.__APOLLO_CLIENT__&&__DEV__:l,d=e.queryDeduplication,h=void 0===d||d,p=e.defaultOptions,b=e.assumeImmutableResults,m=void 0!==b&&b,g=e.resolvers,v=e.typeDefs,y=e.fragmentMatcher,w=e.name,_=e.version,E=e.link;if(E||(E=n?new nh({uri:n,credentials:r,headers:i}):ta.empty()),!a)throw __DEV__?new Q.ej("To initialize Apollo Client, you must specify a 'cache' property in the options object. \nFor more information, please visit: https://go.apollo.dev/c/docs"):new Q.ej(9);if(this.link=E,this.cache=a,this.disableNetworkFetches=s||c>0,this.queryDeduplication=h,this.defaultOptions=p||Object.create(null),this.typeDefs=v,c&&setTimeout(function(){return t.disableNetworkFetches=!1},c),this.watchQuery=this.watchQuery.bind(this),this.query=this.query.bind(this),this.mutate=this.mutate.bind(this),this.resetStore=this.resetStore.bind(this),this.reFetchObservableQueries=this.reFetchObservableQueries.bind(this),f&&"object"==typeof window&&(window.__APOLLO_CLIENT__=this),!ii&&f&&__DEV__&&(ii=!0,"undefined"!=typeof window&&window.document&&window.top===window.self&&!window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__)){var S=window.navigator,k=S&&S.userAgent,x=void 0;"string"==typeof k&&(k.indexOf("Chrome/")>-1?x="https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm":k.indexOf("Firefox/")>-1&&(x="https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/")),x&&__DEV__&&Q.kG.log("Download the Apollo DevTools for a better development experience: "+x)}this.version=nb,this.localState=new r4({cache:a,client:this,resolvers:g,fragmentMatcher:y}),this.queryManager=new it({cache:this.cache,link:this.link,defaultOptions:this.defaultOptions,queryDeduplication:h,ssrMode:s,clientAwareness:{name:w,version:_},localState:this.localState,assumeImmutableResults:m,onBroadcast:f?function(){t.devToolsHookCb&&t.devToolsHookCb({action:{},state:{queries:t.queryManager.getQueryStore(),mutations:t.queryManager.mutationStore||{}},dataWithOptimisticResults:t.cache.extract(!0)})}:void 0})}return e.prototype.stop=function(){this.queryManager.stop()},e.prototype.watchQuery=function(e){return this.defaultOptions.watchQuery&&(e=(0,ir.J)(this.defaultOptions.watchQuery,e)),this.disableNetworkFetches&&("network-only"===e.fetchPolicy||"cache-and-network"===e.fetchPolicy)&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.watchQuery(e)},e.prototype.query=function(e){return this.defaultOptions.query&&(e=(0,ir.J)(this.defaultOptions.query,e)),__DEV__?(0,Q.kG)("cache-and-network"!==e.fetchPolicy,"The cache-and-network fetchPolicy does not work with client.query, because client.query can only return a single result. Please use client.watchQuery to receive multiple results from the cache and the network, or consider using a different fetchPolicy, such as cache-first or network-only."):(0,Q.kG)("cache-and-network"!==e.fetchPolicy,10),this.disableNetworkFetches&&"network-only"===e.fetchPolicy&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.query(e)},e.prototype.mutate=function(e){return this.defaultOptions.mutate&&(e=(0,ir.J)(this.defaultOptions.mutate,e)),this.queryManager.mutate(e)},e.prototype.subscribe=function(e){return this.queryManager.startGraphQLSubscription(e)},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!1),this.cache.readQuery(e,t)},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!1),this.cache.readFragment(e,t)},e.prototype.writeQuery=function(e){var t=this.cache.writeQuery(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.writeFragment=function(e){var t=this.cache.writeFragment(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.__actionHookForDevTools=function(e){this.devToolsHookCb=e},e.prototype.__requestRaw=function(e){return np(this.link,e)},e.prototype.resetStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!1})}).then(function(){return Promise.all(e.resetStoreCallbacks.map(function(e){return e()}))}).then(function(){return e.reFetchObservableQueries()})},e.prototype.clearStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!0})}).then(function(){return Promise.all(e.clearStoreCallbacks.map(function(e){return e()}))})},e.prototype.onResetStore=function(e){var t=this;return this.resetStoreCallbacks.push(e),function(){t.resetStoreCallbacks=t.resetStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.onClearStore=function(e){var t=this;return this.clearStoreCallbacks.push(e),function(){t.clearStoreCallbacks=t.clearStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.reFetchObservableQueries=function(e){return this.queryManager.reFetchObservableQueries(e)},e.prototype.refetchQueries=function(e){var t=this.queryManager.refetchQueries(e),n=[],r=[];t.forEach(function(e,t){n.push(t),r.push(e)});var i=Promise.all(r);return i.queries=n,i.results=r,i.catch(function(e){__DEV__&&Q.kG.debug("In client.refetchQueries, Promise.all promise rejected with error ".concat(e))}),i},e.prototype.getObservableQueries=function(e){return void 0===e&&(e="active"),this.queryManager.getObservableQueries(e)},e.prototype.extract=function(e){return this.cache.extract(e)},e.prototype.restore=function(e){return this.cache.restore(e)},e.prototype.addResolvers=function(e){this.localState.addResolvers(e)},e.prototype.setResolvers=function(e){this.localState.setResolvers(e)},e.prototype.getResolvers=function(){return this.localState.getResolvers()},e.prototype.setLocalStateFragmentMatcher=function(e){this.localState.setFragmentMatcher(e)},e.prototype.setLink=function(e){this.link=this.queryManager.link=e},e}(),io=function(){function e(){this.getFragmentDoc=rZ(eA)}return e.prototype.batch=function(e){var t,n=this,r="string"==typeof e.optimistic?e.optimistic:!1===e.optimistic?null:void 0;return this.performTransaction(function(){return t=e.update(n)},r),t},e.prototype.recordOptimisticTransaction=function(e,t){this.performTransaction(e,t)},e.prototype.transformDocument=function(e){return e},e.prototype.transformForLink=function(e){return e},e.prototype.identify=function(e){},e.prototype.gc=function(){return[]},e.prototype.modify=function(e){return!1},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{rootId:e.id||"ROOT_QUERY",optimistic:t}))},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{query:this.getFragmentDoc(e.fragment,e.fragmentName),rootId:e.id,optimistic:t}))},e.prototype.writeQuery=function(e){var t=e.id,n=e.data,r=(0,en._T)(e,["id","data"]);return this.write(Object.assign(r,{dataId:t||"ROOT_QUERY",result:n}))},e.prototype.writeFragment=function(e){var t=e.id,n=e.data,r=e.fragment,i=e.fragmentName,a=(0,en._T)(e,["id","data","fragment","fragmentName"]);return this.write(Object.assign(a,{query:this.getFragmentDoc(r,i),dataId:t,result:n}))},e.prototype.updateQuery=function(e,t){return this.batch({update:function(n){var r=n.readQuery(e),i=t(r);return null==i?r:(n.writeQuery((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e.prototype.updateFragment=function(e,t){return this.batch({update:function(n){var r=n.readFragment(e),i=t(r);return null==i?r:(n.writeFragment((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e}(),is=function(e){function t(n,r,i,a){var o,s=e.call(this,n)||this;if(s.message=n,s.path=r,s.query=i,s.variables=a,Array.isArray(s.path)){s.missing=s.message;for(var u=s.path.length-1;u>=0;--u)s.missing=((o={})[s.path[u]]=s.missing,o)}else s.missing=s.path;return s.__proto__=t.prototype,s}return(0,en.ZT)(t,e),t}(Error),iu=__webpack_require__(10542),ic=Object.prototype.hasOwnProperty;function il(e){return null==e}function id(e,t){var n=e.__typename,r=e.id,i=e._id;if("string"==typeof n&&(t&&(t.keyObject=il(r)?il(i)?void 0:{_id:i}:{id:r}),il(r)&&!il(i)&&(r=i),!il(r)))return"".concat(n,":").concat("number"==typeof r||"string"==typeof r?r:JSON.stringify(r))}var ih={dataIdFromObject:id,addTypename:!0,resultCaching:!0,canonizeResults:!1};function ip(e){return(0,n1.o)(ih,e)}function ib(e){var t=e.canonizeResults;return void 0===t?ih.canonizeResults:t}function im(e,t){return eD(t)?e.get(t.__ref,"__typename"):t&&t.__typename}var ig=/^[_a-z][_0-9a-z]*/i;function iv(e){var t=e.match(ig);return t?t[0]:e}function iy(e,t,n){return!!(0,eO.s)(t)&&((0,tP.k)(t)?t.every(function(t){return iy(e,t,n)}):e.selections.every(function(e){if(eQ(e)&&td(e,n)){var r=eX(e);return ic.call(t,r)&&(!e.selectionSet||iy(e.selectionSet,t[r],n))}return!0}))}function iw(e){return(0,eO.s)(e)&&!eD(e)&&!(0,tP.k)(e)}function i_(){return new tB}function iE(e,t){var n=eL(e4(e));return{fragmentMap:n,lookupFragment:function(e){var r=n[e];return!r&&t&&(r=t.lookup(e)),r||null}}}var iS=Object.create(null),ik=function(){return iS},ix=Object.create(null),iT=function(){function e(e,t){var n=this;this.policies=e,this.group=t,this.data=Object.create(null),this.rootIds=Object.create(null),this.refs=Object.create(null),this.getFieldValue=function(e,t){return(0,iu.J)(eD(e)?n.get(e.__ref,t):e&&e[t])},this.canRead=function(e){return eD(e)?n.has(e.__ref):"object"==typeof e},this.toReference=function(e,t){if("string"==typeof e)return eI(e);if(eD(e))return e;var r=n.policies.identify(e)[0];if(r){var i=eI(r);return t&&n.merge(r,e),i}}}return e.prototype.toObject=function(){return(0,en.pi)({},this.data)},e.prototype.has=function(e){return void 0!==this.lookup(e,!0)},e.prototype.get=function(e,t){if(this.group.depend(e,t),ic.call(this.data,e)){var n=this.data[e];if(n&&ic.call(n,t))return n[t]}return"__typename"===t&&ic.call(this.policies.rootTypenamesById,e)?this.policies.rootTypenamesById[e]:this instanceof iL?this.parent.get(e,t):void 0},e.prototype.lookup=function(e,t){return(t&&this.group.depend(e,"__exists"),ic.call(this.data,e))?this.data[e]:this instanceof iL?this.parent.lookup(e,t):this.policies.rootTypenamesById[e]?Object.create(null):void 0},e.prototype.merge=function(e,t){var n,r=this;eD(e)&&(e=e.__ref),eD(t)&&(t=t.__ref);var i="string"==typeof e?this.lookup(n=e):e,a="string"==typeof t?this.lookup(n=t):t;if(a){__DEV__?(0,Q.kG)("string"==typeof n,"store.merge expects a string ID"):(0,Q.kG)("string"==typeof n,1);var o=new tB(iI).merge(i,a);if(this.data[n]=o,o!==i&&(delete this.refs[n],this.group.caching)){var s=Object.create(null);i||(s.__exists=1),Object.keys(a).forEach(function(e){if(!i||i[e]!==o[e]){s[e]=1;var t=iv(e);t===e||r.policies.hasKeyArgs(o.__typename,t)||(s[t]=1),void 0!==o[e]||r instanceof iL||delete o[e]}}),s.__typename&&!(i&&i.__typename)&&this.policies.rootTypenamesById[n]===o.__typename&&delete s.__typename,Object.keys(s).forEach(function(e){return r.group.dirty(n,e)})}}},e.prototype.modify=function(e,t){var n=this,r=this.lookup(e);if(r){var i=Object.create(null),a=!1,o=!0,s={DELETE:iS,INVALIDATE:ix,isReference:eD,toReference:this.toReference,canRead:this.canRead,readField:function(t,r){return n.policies.readField("string"==typeof t?{fieldName:t,from:r||eI(e)}:t,{store:n})}};if(Object.keys(r).forEach(function(u){var c=iv(u),l=r[u];if(void 0!==l){var f="function"==typeof t?t:t[u]||t[c];if(f){var d=f===ik?iS:f((0,iu.J)(l),(0,en.pi)((0,en.pi)({},s),{fieldName:c,storeFieldName:u,storage:n.getStorage(e,u)}));d===ix?n.group.dirty(e,u):(d===iS&&(d=void 0),d!==l&&(i[u]=d,a=!0,l=d))}void 0!==l&&(o=!1)}}),a)return this.merge(e,i),o&&(this instanceof iL?this.data[e]=void 0:delete this.data[e],this.group.dirty(e,"__exists")),!0}return!1},e.prototype.delete=function(e,t,n){var r,i=this.lookup(e);if(i){var a=this.getFieldValue(i,"__typename"),o=t&&n?this.policies.getStoreFieldName({typename:a,fieldName:t,args:n}):t;return this.modify(e,o?((r={})[o]=ik,r):ik)}return!1},e.prototype.evict=function(e,t){var n=!1;return e.id&&(ic.call(this.data,e.id)&&(n=this.delete(e.id,e.fieldName,e.args)),this instanceof iL&&this!==t&&(n=this.parent.evict(e,t)||n),(e.fieldName||n)&&this.group.dirty(e.id,e.fieldName||"__exists")),n},e.prototype.clear=function(){this.replace(null)},e.prototype.extract=function(){var e=this,t=this.toObject(),n=[];return this.getRootIdSet().forEach(function(t){ic.call(e.policies.rootTypenamesById,t)||n.push(t)}),n.length&&(t.__META={extraRootIds:n.sort()}),t},e.prototype.replace=function(e){var t=this;if(Object.keys(this.data).forEach(function(n){e&&ic.call(e,n)||t.delete(n)}),e){var n=e.__META,r=(0,en._T)(e,["__META"]);Object.keys(r).forEach(function(e){t.merge(e,r[e])}),n&&n.extraRootIds.forEach(this.retain,this)}},e.prototype.retain=function(e){return this.rootIds[e]=(this.rootIds[e]||0)+1},e.prototype.release=function(e){if(this.rootIds[e]>0){var t=--this.rootIds[e];return t||delete this.rootIds[e],t}return 0},e.prototype.getRootIdSet=function(e){return void 0===e&&(e=new Set),Object.keys(this.rootIds).forEach(e.add,e),this instanceof iL?this.parent.getRootIdSet(e):Object.keys(this.policies.rootTypenamesById).forEach(e.add,e),e},e.prototype.gc=function(){var e=this,t=this.getRootIdSet(),n=this.toObject();t.forEach(function(r){ic.call(n,r)&&(Object.keys(e.findChildRefIds(r)).forEach(t.add,t),delete n[r])});var r=Object.keys(n);if(r.length){for(var i=this;i instanceof iL;)i=i.parent;r.forEach(function(e){return i.delete(e)})}return r},e.prototype.findChildRefIds=function(e){if(!ic.call(this.refs,e)){var t=this.refs[e]=Object.create(null),n=this.data[e];if(!n)return t;var r=new Set([n]);r.forEach(function(e){eD(e)&&(t[e.__ref]=!0),(0,eO.s)(e)&&Object.keys(e).forEach(function(t){var n=e[t];(0,eO.s)(n)&&r.add(n)})})}return this.refs[e]},e.prototype.makeCacheKey=function(){return this.group.keyMaker.lookupArray(arguments)},e}(),iM=function(){function e(e,t){void 0===t&&(t=null),this.caching=e,this.parent=t,this.d=null,this.resetCaching()}return e.prototype.resetCaching=function(){this.d=this.caching?rW():null,this.keyMaker=new n_(t_.mr)},e.prototype.depend=function(e,t){if(this.d){this.d(iO(e,t));var n=iv(t);n!==t&&this.d(iO(e,n)),this.parent&&this.parent.depend(e,t)}},e.prototype.dirty=function(e,t){this.d&&this.d.dirty(iO(e,t),"__exists"===t?"forget":"setDirty")},e}();function iO(e,t){return t+"#"+e}function iA(e,t){iD(e)&&e.group.depend(t,"__exists")}!function(e){var t=function(e){function t(t){var n=t.policies,r=t.resultCaching,i=void 0===r||r,a=t.seed,o=e.call(this,n,new iM(i))||this;return o.stump=new iC(o),o.storageTrie=new n_(t_.mr),a&&o.replace(a),o}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,t){return this.stump.addLayer(e,t)},t.prototype.removeLayer=function(){return this},t.prototype.getStorage=function(){return this.storageTrie.lookupArray(arguments)},t}(e);e.Root=t}(iT||(iT={}));var iL=function(e){function t(t,n,r,i){var a=e.call(this,n.policies,i)||this;return a.id=t,a.parent=n,a.replay=r,a.group=i,r(a),a}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,n){return new t(e,this,n,this.group)},t.prototype.removeLayer=function(e){var t=this,n=this.parent.removeLayer(e);return e===this.id?(this.group.caching&&Object.keys(this.data).forEach(function(e){var r=t.data[e],i=n.lookup(e);i?r?r!==i&&Object.keys(r).forEach(function(n){(0,nm.D)(r[n],i[n])||t.group.dirty(e,n)}):(t.group.dirty(e,"__exists"),Object.keys(i).forEach(function(n){t.group.dirty(e,n)})):t.delete(e)}),n):n===this.parent?this:n.addLayer(this.id,this.replay)},t.prototype.toObject=function(){return(0,en.pi)((0,en.pi)({},this.parent.toObject()),this.data)},t.prototype.findChildRefIds=function(t){var n=this.parent.findChildRefIds(t);return ic.call(this.data,t)?(0,en.pi)((0,en.pi)({},n),e.prototype.findChildRefIds.call(this,t)):n},t.prototype.getStorage=function(){for(var e=this.parent;e.parent;)e=e.parent;return e.getStorage.apply(e,arguments)},t}(iT),iC=function(e){function t(t){return e.call(this,"EntityStore.Stump",t,function(){},new iM(t.group.caching,t.group))||this}return(0,en.ZT)(t,e),t.prototype.removeLayer=function(){return this},t.prototype.merge=function(){return this.parent.merge.apply(this.parent,arguments)},t}(iL);function iI(e,t,n){var r=e[n],i=t[n];return(0,nm.D)(r,i)?r:i}function iD(e){return!!(e instanceof iT&&e.group.caching)}function iN(e){return[e.selectionSet,e.objectOrReference,e.context,e.context.canonizeResults,]}var iP=function(){function e(e){var t=this;this.knownResults=new(t_.mr?WeakMap:Map),this.config=(0,n1.o)(e,{addTypename:!1!==e.addTypename,canonizeResults:ib(e)}),this.canon=e.canon||new nk,this.executeSelectionSet=rZ(function(e){var n,r=e.context.canonizeResults,i=iN(e);i[3]=!r;var a=(n=t.executeSelectionSet).peek.apply(n,i);return a?r?(0,en.pi)((0,en.pi)({},a),{result:t.canon.admit(a.result)}):a:(iA(e.context.store,e.enclosingRef.__ref),t.execSelectionSetImpl(e))},{max:this.config.resultCacheMaxSize,keyArgs:iN,makeCacheKey:function(e,t,n,r){if(iD(n.store))return n.store.makeCacheKey(e,eD(t)?t.__ref:t,n.varString,r)}}),this.executeSubSelectedArray=rZ(function(e){return iA(e.context.store,e.enclosingRef.__ref),t.execSubSelectedArrayImpl(e)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var t=e.field,n=e.array,r=e.context;if(iD(r.store))return r.store.makeCacheKey(t,n,r.varString)}})}return e.prototype.resetCanon=function(){this.canon=new nk},e.prototype.diffQueryAgainstStore=function(e){var t,n=e.store,r=e.query,i=e.rootId,a=void 0===i?"ROOT_QUERY":i,o=e.variables,s=e.returnPartialData,u=void 0===s||s,c=e.canonizeResults,l=void 0===c?this.config.canonizeResults:c,f=this.config.cache.policies;o=(0,en.pi)((0,en.pi)({},e9(e6(r))),o);var d=eI(a),h=this.executeSelectionSet({selectionSet:e8(r).selectionSet,objectOrReference:d,enclosingRef:d,context:(0,en.pi)({store:n,query:r,policies:f,variables:o,varString:nx(o),canonizeResults:l},iE(r,this.config.fragments))});if(h.missing&&(t=[new is(iR(h.missing),h.missing,r,o)],!u))throw t[0];return{result:h.result,complete:!t,missing:t}},e.prototype.isFresh=function(e,t,n,r){if(iD(r.store)&&this.knownResults.get(e)===n){var i=this.executeSelectionSet.peek(n,t,r,this.canon.isKnown(e));if(i&&e===i.result)return!0}return!1},e.prototype.execSelectionSetImpl=function(e){var t,n=this,r=e.selectionSet,i=e.objectOrReference,a=e.enclosingRef,o=e.context;if(eD(i)&&!o.policies.rootTypenamesById[i.__ref]&&!o.store.has(i.__ref))return{result:this.canon.empty,missing:"Dangling reference to missing ".concat(i.__ref," object")};var s=o.variables,u=o.policies,c=o.store.getFieldValue(i,"__typename"),l=[],f=new tB;function d(e,n){var r;return e.missing&&(t=f.merge(t,((r={})[n]=e.missing,r))),e.result}this.config.addTypename&&"string"==typeof c&&!u.rootIdsByTypename[c]&&l.push({__typename:c});var h=new Set(r.selections);h.forEach(function(e){var r,p;if(td(e,s)){if(eQ(e)){var b=u.readField({fieldName:e.name.value,field:e,variables:o.variables,from:i},o),m=eX(e);void 0===b?nj.added(e)||(t=f.merge(t,((r={})[m]="Can't find field '".concat(e.name.value,"' on ").concat(eD(i)?i.__ref+" object":"object "+JSON.stringify(i,null,2)),r))):(0,tP.k)(b)?b=d(n.executeSubSelectedArray({field:e,array:b,enclosingRef:a,context:o}),m):e.selectionSet?null!=b&&(b=d(n.executeSelectionSet({selectionSet:e.selectionSet,objectOrReference:b,enclosingRef:eD(b)?b:a,context:o}),m)):o.canonizeResults&&(b=n.canon.pass(b)),void 0!==b&&l.push(((p={})[m]=b,p))}else{var g=eC(e,o.lookupFragment);if(!g&&e.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(e.name.value)):new Q.ej(5);g&&u.fragmentMatches(g,c)&&g.selectionSet.selections.forEach(h.add,h)}}});var p={result:tF(l),missing:t},b=o.canonizeResults?this.canon.admit(p):(0,iu.J)(p);return b.result&&this.knownResults.set(b.result,r),b},e.prototype.execSubSelectedArrayImpl=function(e){var t,n=this,r=e.field,i=e.array,a=e.enclosingRef,o=e.context,s=new tB;function u(e,n){var r;return e.missing&&(t=s.merge(t,((r={})[n]=e.missing,r))),e.result}return r.selectionSet&&(i=i.filter(o.store.canRead)),i=i.map(function(e,t){return null===e?null:(0,tP.k)(e)?u(n.executeSubSelectedArray({field:r,array:e,enclosingRef:a,context:o}),t):r.selectionSet?u(n.executeSelectionSet({selectionSet:r.selectionSet,objectOrReference:e,enclosingRef:eD(e)?e:a,context:o}),t):(__DEV__&&ij(o.store,r,e),e)}),{result:o.canonizeResults?this.canon.admit(i):i,missing:t}},e}();function iR(e){try{JSON.stringify(e,function(e,t){if("string"==typeof t)throw t;return t})}catch(t){return t}}function ij(e,t,n){if(!t.selectionSet){var r=new Set([n]);r.forEach(function(n){(0,eO.s)(n)&&(__DEV__?(0,Q.kG)(!eD(n),"Missing selection set for object of type ".concat(im(e,n)," returned for query field ").concat(t.name.value)):(0,Q.kG)(!eD(n),6),Object.values(n).forEach(r.add,r))})}}function iF(e){var t=nG("stringifyForDisplay");return JSON.stringify(e,function(e,n){return void 0===n?t:n}).split(JSON.stringify(t)).join("")}var iY=Object.create(null);function iB(e){var t=JSON.stringify(e);return iY[t]||(iY[t]=Object.create(null))}function iU(e){var t=iB(e);return t.keyFieldsFn||(t.keyFieldsFn=function(t,n){var r=function(e,t){return n.readField(t,e)},i=n.keyObject=i$(e,function(e){var i=iW(n.storeObject,e,r);return void 0===i&&t!==n.storeObject&&ic.call(t,e[0])&&(i=iW(t,e,iG)),__DEV__?(0,Q.kG)(void 0!==i,"Missing field '".concat(e.join("."),"' while extracting keyFields from ").concat(JSON.stringify(t))):(0,Q.kG)(void 0!==i,2),i});return"".concat(n.typename,":").concat(JSON.stringify(i))})}function iH(e){var t=iB(e);return t.keyArgsFn||(t.keyArgsFn=function(t,n){var r=n.field,i=n.variables,a=n.fieldName,o=JSON.stringify(i$(e,function(e){var n=e[0],a=n.charAt(0);if("@"===a){if(r&&(0,tP.O)(r.directives)){var o=n.slice(1),s=r.directives.find(function(e){return e.name.value===o}),u=s&&eZ(s,i);return u&&iW(u,e.slice(1))}return}if("$"===a){var c=n.slice(1);if(i&&ic.call(i,c)){var l=e.slice(0);return l[0]=c,iW(i,l)}return}if(t)return iW(t,e)}));return(t||"{}"!==o)&&(a+=":"+o),a})}function i$(e,t){var n=new tB;return iz(e).reduce(function(e,r){var i,a=t(r);if(void 0!==a){for(var o=r.length-1;o>=0;--o)a=((i={})[r[o]]=a,i);e=n.merge(e,a)}return e},Object.create(null))}function iz(e){var t=iB(e);if(!t.paths){var n=t.paths=[],r=[];e.forEach(function(t,i){(0,tP.k)(t)?(iz(t).forEach(function(e){return n.push(r.concat(e))}),r.length=0):(r.push(t),(0,tP.k)(e[i+1])||(n.push(r.slice(0)),r.length=0))})}return t.paths}function iG(e,t){return e[t]}function iW(e,t,n){return n=n||iG,iK(t.reduce(function e(t,r){return(0,tP.k)(t)?t.map(function(t){return e(t,r)}):t&&n(t,r)},e))}function iK(e){return(0,eO.s)(e)?(0,tP.k)(e)?e.map(iK):i$(Object.keys(e).sort(),function(t){return iW(e,t)}):e}function iV(e){return void 0!==e.args?e.args:e.field?eZ(e.field,e.variables):null}eK.setStringify(nx);var iq=function(){},iZ=function(e,t){return t.fieldName},iX=function(e,t,n){return(0,n.mergeObjects)(e,t)},iJ=function(e,t){return t},iQ=function(){function e(e){this.config=e,this.typePolicies=Object.create(null),this.toBeAdded=Object.create(null),this.supertypeMap=new Map,this.fuzzySubtypes=new Map,this.rootIdsByTypename=Object.create(null),this.rootTypenamesById=Object.create(null),this.usingPossibleTypes=!1,this.config=(0,en.pi)({dataIdFromObject:id},e),this.cache=this.config.cache,this.setRootTypename("Query"),this.setRootTypename("Mutation"),this.setRootTypename("Subscription"),e.possibleTypes&&this.addPossibleTypes(e.possibleTypes),e.typePolicies&&this.addTypePolicies(e.typePolicies)}return e.prototype.identify=function(e,t){var n,r,i=this,a=t&&(t.typename||(null===(n=t.storeObject)||void 0===n?void 0:n.__typename))||e.__typename;if(a===this.rootTypenamesById.ROOT_QUERY)return["ROOT_QUERY"];for(var o=t&&t.storeObject||e,s=(0,en.pi)((0,en.pi)({},t),{typename:a,storeObject:o,readField:t&&t.readField||function(){var e=i0(arguments,o);return i.readField(e,{store:i.cache.data,variables:e.variables})}}),u=a&&this.getTypePolicy(a),c=u&&u.keyFn||this.config.dataIdFromObject;c;){var l=c((0,en.pi)((0,en.pi)({},e),o),s);if((0,tP.k)(l))c=iU(l);else{r=l;break}}return r=r?String(r):void 0,s.keyObject?[r,s.keyObject]:[r]},e.prototype.addTypePolicies=function(e){var t=this;Object.keys(e).forEach(function(n){var r=e[n],i=r.queryType,a=r.mutationType,o=r.subscriptionType,s=(0,en._T)(r,["queryType","mutationType","subscriptionType"]);i&&t.setRootTypename("Query",n),a&&t.setRootTypename("Mutation",n),o&&t.setRootTypename("Subscription",n),ic.call(t.toBeAdded,n)?t.toBeAdded[n].push(s):t.toBeAdded[n]=[s]})},e.prototype.updateTypePolicy=function(e,t){var n=this,r=this.getTypePolicy(e),i=t.keyFields,a=t.fields;function o(e,t){e.merge="function"==typeof t?t:!0===t?iX:!1===t?iJ:e.merge}o(r,t.merge),r.keyFn=!1===i?iq:(0,tP.k)(i)?iU(i):"function"==typeof i?i:r.keyFn,a&&Object.keys(a).forEach(function(t){var r=n.getFieldPolicy(e,t,!0),i=a[t];if("function"==typeof i)r.read=i;else{var s=i.keyArgs,u=i.read,c=i.merge;r.keyFn=!1===s?iZ:(0,tP.k)(s)?iH(s):"function"==typeof s?s:r.keyFn,"function"==typeof u&&(r.read=u),o(r,c)}r.read&&r.merge&&(r.keyFn=r.keyFn||iZ)})},e.prototype.setRootTypename=function(e,t){void 0===t&&(t=e);var n="ROOT_"+e.toUpperCase(),r=this.rootTypenamesById[n];t!==r&&(__DEV__?(0,Q.kG)(!r||r===e,"Cannot change root ".concat(e," __typename more than once")):(0,Q.kG)(!r||r===e,3),r&&delete this.rootIdsByTypename[r],this.rootIdsByTypename[t]=n,this.rootTypenamesById[n]=t)},e.prototype.addPossibleTypes=function(e){var t=this;this.usingPossibleTypes=!0,Object.keys(e).forEach(function(n){t.getSupertypeSet(n,!0),e[n].forEach(function(e){t.getSupertypeSet(e,!0).add(n);var r=e.match(ig);r&&r[0]===e||t.fuzzySubtypes.set(e,RegExp(e))})})},e.prototype.getTypePolicy=function(e){var t=this;if(!ic.call(this.typePolicies,e)){var n=this.typePolicies[e]=Object.create(null);n.fields=Object.create(null);var r=this.supertypeMap.get(e);r&&r.size&&r.forEach(function(e){var r=t.getTypePolicy(e),i=r.fields;Object.assign(n,(0,en._T)(r,["fields"])),Object.assign(n.fields,i)})}var i=this.toBeAdded[e];return i&&i.length&&i.splice(0).forEach(function(n){t.updateTypePolicy(e,n)}),this.typePolicies[e]},e.prototype.getFieldPolicy=function(e,t,n){if(e){var r=this.getTypePolicy(e).fields;return r[t]||n&&(r[t]=Object.create(null))}},e.prototype.getSupertypeSet=function(e,t){var n=this.supertypeMap.get(e);return!n&&t&&this.supertypeMap.set(e,n=new Set),n},e.prototype.fragmentMatches=function(e,t,n,r){var i=this;if(!e.typeCondition)return!0;if(!t)return!1;var a=e.typeCondition.name.value;if(t===a)return!0;if(this.usingPossibleTypes&&this.supertypeMap.has(a))for(var o=this.getSupertypeSet(t,!0),s=[o],u=function(e){var t=i.getSupertypeSet(e,!1);t&&t.size&&0>s.indexOf(t)&&s.push(t)},c=!!(n&&this.fuzzySubtypes.size),l=!1,f=0;f1?a:t}:(r=(0,en.pi)({},i),ic.call(r,"from")||(r.from=t)),__DEV__&&void 0===r.from&&__DEV__&&Q.kG.warn("Undefined 'from' passed to readField with arguments ".concat(iF(Array.from(e)))),void 0===r.variables&&(r.variables=n),r}function i2(e){return function(t,n){if((0,tP.k)(t)||(0,tP.k)(n))throw __DEV__?new Q.ej("Cannot automatically merge arrays"):new Q.ej(4);if((0,eO.s)(t)&&(0,eO.s)(n)){var r=e.getFieldValue(t,"__typename"),i=e.getFieldValue(n,"__typename");if(r&&i&&r!==i)return n;if(eD(t)&&iw(n))return e.merge(t.__ref,n),t;if(iw(t)&&eD(n))return e.merge(t,n.__ref),n;if(iw(t)&&iw(n))return(0,en.pi)((0,en.pi)({},t),n)}return n}}function i3(e,t,n){var r="".concat(t).concat(n),i=e.flavors.get(r);return i||e.flavors.set(r,i=e.clientOnly===t&&e.deferred===n?e:(0,en.pi)((0,en.pi)({},e),{clientOnly:t,deferred:n})),i}var i4=function(){function e(e,t,n){this.cache=e,this.reader=t,this.fragments=n}return e.prototype.writeToStore=function(e,t){var n=this,r=t.query,i=t.result,a=t.dataId,o=t.variables,s=t.overwrite,u=e2(r),c=i_();o=(0,en.pi)((0,en.pi)({},e9(u)),o);var l=(0,en.pi)((0,en.pi)({store:e,written:Object.create(null),merge:function(e,t){return c.merge(e,t)},variables:o,varString:nx(o)},iE(r,this.fragments)),{overwrite:!!s,incomingById:new Map,clientOnly:!1,deferred:!1,flavors:new Map}),f=this.processSelectionSet({result:i||Object.create(null),dataId:a,selectionSet:u.selectionSet,mergeTree:{map:new Map},context:l});if(!eD(f))throw __DEV__?new Q.ej("Could not identify object ".concat(JSON.stringify(i))):new Q.ej(7);return l.incomingById.forEach(function(t,r){var i=t.storeObject,a=t.mergeTree,o=t.fieldNodeSet,s=eI(r);if(a&&a.map.size){var u=n.applyMerges(a,s,i,l);if(eD(u))return;i=u}if(__DEV__&&!l.overwrite){var c=Object.create(null);o.forEach(function(e){e.selectionSet&&(c[e.name.value]=!0)});var f=function(e){return!0===c[iv(e)]},d=function(e){var t=a&&a.map.get(e);return Boolean(t&&t.info&&t.info.merge)};Object.keys(i).forEach(function(e){f(e)&&!d(e)&&at(s,i,e,l.store)})}e.merge(r,i)}),e.retain(f.__ref),f},e.prototype.processSelectionSet=function(e){var t=this,n=e.dataId,r=e.result,i=e.selectionSet,a=e.context,o=e.mergeTree,s=this.cache.policies,u=Object.create(null),c=n&&s.rootTypenamesById[n]||eJ(r,i,a.fragmentMap)||n&&a.store.get(n,"__typename");"string"==typeof c&&(u.__typename=c);var l=function(){var e=i0(arguments,u,a.variables);if(eD(e.from)){var t=a.incomingById.get(e.from.__ref);if(t){var n=s.readField((0,en.pi)((0,en.pi)({},e),{from:t.storeObject}),a);if(void 0!==n)return n}}return s.readField(e,a)},f=new Set;this.flattenFields(i,r,a,c).forEach(function(e,n){var i,a=r[eX(n)];if(f.add(n),void 0!==a){var d=s.getStoreFieldName({typename:c,fieldName:n.name.value,field:n,variables:e.variables}),h=i5(o,d),p=t.processFieldValue(a,n,n.selectionSet?i3(e,!1,!1):e,h),b=void 0;n.selectionSet&&(eD(p)||iw(p))&&(b=l("__typename",p));var m=s.getMergeFunction(c,n.name.value,b);m?h.info={field:n,typename:c,merge:m}:i7(o,d),u=e.merge(u,((i={})[d]=p,i))}else __DEV__&&!e.clientOnly&&!e.deferred&&!nj.added(n)&&!s.getReadFunction(c,n.name.value)&&__DEV__&&Q.kG.error("Missing field '".concat(eX(n),"' while writing result ").concat(JSON.stringify(r,null,2)).substring(0,1e3))});try{var d=s.identify(r,{typename:c,selectionSet:i,fragmentMap:a.fragmentMap,storeObject:u,readField:l}),h=d[0],p=d[1];n=n||h,p&&(u=a.merge(u,p))}catch(b){if(!n)throw b}if("string"==typeof n){var m=eI(n),g=a.written[n]||(a.written[n]=[]);if(g.indexOf(i)>=0||(g.push(i),this.reader&&this.reader.isFresh(r,m,i,a)))return m;var v=a.incomingById.get(n);return v?(v.storeObject=a.merge(v.storeObject,u),v.mergeTree=i8(v.mergeTree,o),f.forEach(function(e){return v.fieldNodeSet.add(e)})):a.incomingById.set(n,{storeObject:u,mergeTree:i9(o)?void 0:o,fieldNodeSet:f}),m}return u},e.prototype.processFieldValue=function(e,t,n,r){var i=this;return t.selectionSet&&null!==e?(0,tP.k)(e)?e.map(function(e,a){var o=i.processFieldValue(e,t,n,i5(r,a));return i7(r,a),o}):this.processSelectionSet({result:e,selectionSet:t.selectionSet,context:n,mergeTree:r}):__DEV__?nJ(e):e},e.prototype.flattenFields=function(e,t,n,r){void 0===r&&(r=eJ(t,e,n.fragmentMap));var i=new Map,a=this.cache.policies,o=new n_(!1);return function e(s,u){var c=o.lookup(s,u.clientOnly,u.deferred);c.visited||(c.visited=!0,s.selections.forEach(function(o){if(td(o,n.variables)){var s=u.clientOnly,c=u.deferred;if(!(s&&c)&&(0,tP.O)(o.directives)&&o.directives.forEach(function(e){var t=e.name.value;if("client"===t&&(s=!0),"defer"===t){var r=eZ(e,n.variables);r&&!1===r.if||(c=!0)}}),eQ(o)){var l=i.get(o);l&&(s=s&&l.clientOnly,c=c&&l.deferred),i.set(o,i3(n,s,c))}else{var f=eC(o,n.lookupFragment);if(!f&&o.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(o.name.value)):new Q.ej(8);f&&a.fragmentMatches(f,r,t,n.variables)&&e(f.selectionSet,i3(n,s,c))}}}))}(e,n),i},e.prototype.applyMerges=function(e,t,n,r,i){var a=this;if(e.map.size&&!eD(n)){var o,s,u=!(0,tP.k)(n)&&(eD(t)||iw(t))?t:void 0,c=n;u&&!i&&(i=[eD(u)?u.__ref:u]);var l=function(e,t){return(0,tP.k)(e)?"number"==typeof t?e[t]:void 0:r.store.getFieldValue(e,String(t))};e.map.forEach(function(e,t){var n=l(u,t),o=l(c,t);if(void 0!==o){i&&i.push(t);var f=a.applyMerges(e,n,o,r,i);f!==o&&(s=s||new Map).set(t,f),i&&(0,Q.kG)(i.pop()===t)}}),s&&(n=(0,tP.k)(c)?c.slice(0):(0,en.pi)({},c),s.forEach(function(e,t){n[t]=e}))}return e.info?this.cache.policies.runMergeFunction(t,n,e.info,r,i&&(o=r.store).getStorage.apply(o,i)):n},e}(),i6=[];function i5(e,t){var n=e.map;return n.has(t)||n.set(t,i6.pop()||{map:new Map}),n.get(t)}function i8(e,t){if(e===t||!t||i9(t))return e;if(!e||i9(e))return t;var n=e.info&&t.info?(0,en.pi)((0,en.pi)({},e.info),t.info):e.info||t.info,r=e.map.size&&t.map.size,i=r?new Map:e.map.size?e.map:t.map,a={info:n,map:i};if(r){var o=new Set(t.map.keys());e.map.forEach(function(e,n){a.map.set(n,i8(e,t.map.get(n))),o.delete(n)}),o.forEach(function(n){a.map.set(n,i8(t.map.get(n),e.map.get(n)))})}return a}function i9(e){return!e||!(e.info||e.map.size)}function i7(e,t){var n=e.map,r=n.get(t);r&&i9(r)&&(i6.push(r),n.delete(t))}var ae=new Set;function at(e,t,n,r){var i=function(e){var t=r.getFieldValue(e,n);return"object"==typeof t&&t},a=i(e);if(a){var o=i(t);if(!(!o||eD(a)||(0,nm.D)(a,o)||Object.keys(a).every(function(e){return void 0!==r.getFieldValue(o,e)}))){var s=r.getFieldValue(e,"__typename")||r.getFieldValue(t,"__typename"),u=iv(n),c="".concat(s,".").concat(u);if(!ae.has(c)){ae.add(c);var l=[];(0,tP.k)(a)||(0,tP.k)(o)||[a,o].forEach(function(e){var t=r.getFieldValue(e,"__typename");"string"!=typeof t||l.includes(t)||l.push(t)}),__DEV__&&Q.kG.warn("Cache data may be lost when replacing the ".concat(u," field of a ").concat(s," object.\n\nThis could cause additional (usually avoidable) network requests to fetch data that were otherwise cached.\n\nTo address this problem (which is not a bug in Apollo Client), ").concat(l.length?"either ensure all objects of type "+l.join(" and ")+" have an ID or a custom merge function, or ":"","define a custom merge function for the ").concat(c," field, so InMemoryCache can safely merge these objects:\n\n existing: ").concat(JSON.stringify(a).slice(0,1e3),"\n incoming: ").concat(JSON.stringify(o).slice(0,1e3),"\n\nFor more information about these options, please refer to the documentation:\n\n * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers\n * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects\n"))}}}}var an=function(e){function t(t){void 0===t&&(t={});var n=e.call(this)||this;return n.watches=new Set,n.typenameDocumentCache=new Map,n.makeVar=r2,n.txCount=0,n.config=ip(t),n.addTypename=!!n.config.addTypename,n.policies=new iQ({cache:n,dataIdFromObject:n.config.dataIdFromObject,possibleTypes:n.config.possibleTypes,typePolicies:n.config.typePolicies}),n.init(),n}return(0,en.ZT)(t,e),t.prototype.init=function(){var e=this.data=new iT.Root({policies:this.policies,resultCaching:this.config.resultCaching});this.optimisticData=e.stump,this.resetResultCache()},t.prototype.resetResultCache=function(e){var t=this,n=this.storeReader,r=this.config.fragments;this.storeWriter=new i4(this,this.storeReader=new iP({cache:this,addTypename:this.addTypename,resultCacheMaxSize:this.config.resultCacheMaxSize,canonizeResults:ib(this.config),canon:e?void 0:n&&n.canon,fragments:r}),r),this.maybeBroadcastWatch=rZ(function(e,n){return t.broadcastWatch(e,n)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var n=e.optimistic?t.optimisticData:t.data;if(iD(n)){var r=e.optimistic,i=e.id,a=e.variables;return n.makeCacheKey(e.query,e.callback,nx({optimistic:r,id:i,variables:a}))}}}),new Set([this.data.group,this.optimisticData.group,]).forEach(function(e){return e.resetCaching()})},t.prototype.restore=function(e){return this.init(),e&&this.data.replace(e),this},t.prototype.extract=function(e){return void 0===e&&(e=!1),(e?this.optimisticData:this.data).extract()},t.prototype.read=function(e){var t=e.returnPartialData,n=void 0!==t&&t;try{return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,config:this.config,returnPartialData:n})).result||null}catch(r){if(r instanceof is)return null;throw r}},t.prototype.write=function(e){try{return++this.txCount,this.storeWriter.writeToStore(this.data,e)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.modify=function(e){if(ic.call(e,"id")&&!e.id)return!1;var t=e.optimistic?this.optimisticData:this.data;try{return++this.txCount,t.modify(e.id||"ROOT_QUERY",e.fields)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.diff=function(e){return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,rootId:e.id||"ROOT_QUERY",config:this.config}))},t.prototype.watch=function(e){var t=this;return this.watches.size||r0(this),this.watches.add(e),e.immediate&&this.maybeBroadcastWatch(e),function(){t.watches.delete(e)&&!t.watches.size&&r1(t),t.maybeBroadcastWatch.forget(e)}},t.prototype.gc=function(e){nx.reset();var t=this.optimisticData.gc();return e&&!this.txCount&&(e.resetResultCache?this.resetResultCache(e.resetResultIdentities):e.resetResultIdentities&&this.storeReader.resetCanon()),t},t.prototype.retain=function(e,t){return(t?this.optimisticData:this.data).retain(e)},t.prototype.release=function(e,t){return(t?this.optimisticData:this.data).release(e)},t.prototype.identify=function(e){if(eD(e))return e.__ref;try{return this.policies.identify(e)[0]}catch(t){__DEV__&&Q.kG.warn(t)}},t.prototype.evict=function(e){if(!e.id){if(ic.call(e,"id"))return!1;e=(0,en.pi)((0,en.pi)({},e),{id:"ROOT_QUERY"})}try{return++this.txCount,this.optimisticData.evict(e,this.data)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.reset=function(e){var t=this;return this.init(),nx.reset(),e&&e.discardWatches?(this.watches.forEach(function(e){return t.maybeBroadcastWatch.forget(e)}),this.watches.clear(),r1(this)):this.broadcastWatches(),Promise.resolve()},t.prototype.removeOptimistic=function(e){var t=this.optimisticData.removeLayer(e);t!==this.optimisticData&&(this.optimisticData=t,this.broadcastWatches())},t.prototype.batch=function(e){var t,n=this,r=e.update,i=e.optimistic,a=void 0===i||i,o=e.removeOptimistic,s=e.onWatchUpdated,u=function(e){var i=n,a=i.data,o=i.optimisticData;++n.txCount,e&&(n.data=n.optimisticData=e);try{return t=r(n)}finally{--n.txCount,n.data=a,n.optimisticData=o}},c=new Set;return s&&!this.txCount&&this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e){return c.add(e),!1}})),"string"==typeof a?this.optimisticData=this.optimisticData.addLayer(a,u):!1===a?u(this.data):u(),"string"==typeof o&&(this.optimisticData=this.optimisticData.removeLayer(o)),s&&c.size?(this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e,t){var n=s.call(this,e,t);return!1!==n&&c.delete(e),n}})),c.size&&c.forEach(function(e){return n.maybeBroadcastWatch.dirty(e)})):this.broadcastWatches(e),t},t.prototype.performTransaction=function(e,t){return this.batch({update:e,optimistic:t||null!==t})},t.prototype.transformDocument=function(e){if(this.addTypename){var t=this.typenameDocumentCache.get(e);return t||(t=nj(e),this.typenameDocumentCache.set(e,t),this.typenameDocumentCache.set(t,t)),t}return e},t.prototype.transformForLink=function(e){var t=this.config.fragments;return t?t.transform(e):e},t.prototype.broadcastWatches=function(e){var t=this;this.txCount||this.watches.forEach(function(n){return t.maybeBroadcastWatch(n,e)})},t.prototype.broadcastWatch=function(e,t){var n=e.lastDiff,r=this.diff(e);(!t||(e.optimistic&&"string"==typeof t.optimistic&&(r.fromOptimisticTransaction=!0),!t.onWatchUpdated||!1!==t.onWatchUpdated.call(this,e,r,n)))&&(n&&(0,nm.D)(n.result,r.result)||e.callback(e.lastDiff=r,n))},t}(io),ar={possibleTypes:{ApproveJobProposalSpecPayload:["ApproveJobProposalSpecSuccess","JobAlreadyExistsError","NotFoundError"],BridgePayload:["Bridge","NotFoundError"],CancelJobProposalSpecPayload:["CancelJobProposalSpecSuccess","NotFoundError"],ChainPayload:["Chain","NotFoundError"],CreateAPITokenPayload:["CreateAPITokenSuccess","InputErrors"],CreateBridgePayload:["CreateBridgeSuccess"],CreateCSAKeyPayload:["CSAKeyExistsError","CreateCSAKeySuccess"],CreateFeedsManagerChainConfigPayload:["CreateFeedsManagerChainConfigSuccess","InputErrors","NotFoundError"],CreateFeedsManagerPayload:["CreateFeedsManagerSuccess","DuplicateFeedsManagerError","InputErrors","NotFoundError","SingleFeedsManagerError"],CreateJobPayload:["CreateJobSuccess","InputErrors"],CreateOCR2KeyBundlePayload:["CreateOCR2KeyBundleSuccess"],CreateOCRKeyBundlePayload:["CreateOCRKeyBundleSuccess"],CreateP2PKeyPayload:["CreateP2PKeySuccess"],DeleteAPITokenPayload:["DeleteAPITokenSuccess","InputErrors"],DeleteBridgePayload:["DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DeleteBridgeSuccess","NotFoundError"],DeleteCSAKeyPayload:["DeleteCSAKeySuccess","NotFoundError"],DeleteFeedsManagerChainConfigPayload:["DeleteFeedsManagerChainConfigSuccess","NotFoundError"],DeleteJobPayload:["DeleteJobSuccess","NotFoundError"],DeleteOCR2KeyBundlePayload:["DeleteOCR2KeyBundleSuccess","NotFoundError"],DeleteOCRKeyBundlePayload:["DeleteOCRKeyBundleSuccess","NotFoundError"],DeleteP2PKeyPayload:["DeleteP2PKeySuccess","NotFoundError"],DeleteVRFKeyPayload:["DeleteVRFKeySuccess","NotFoundError"],DismissJobErrorPayload:["DismissJobErrorSuccess","NotFoundError"],Error:["CSAKeyExistsError","DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DuplicateFeedsManagerError","InputError","JobAlreadyExistsError","NotFoundError","RunJobCannotRunError","SingleFeedsManagerError"],EthTransactionPayload:["EthTransaction","NotFoundError"],FeaturesPayload:["Features"],FeedsManagerPayload:["FeedsManager","NotFoundError"],GetSQLLoggingPayload:["SQLLogging"],GlobalLogLevelPayload:["GlobalLogLevel"],JobPayload:["Job","NotFoundError"],JobProposalPayload:["JobProposal","NotFoundError"],JobRunPayload:["JobRun","NotFoundError"],JobSpec:["BlockHeaderFeederSpec","BlockhashStoreSpec","BootstrapSpec","CronSpec","DirectRequestSpec","FluxMonitorSpec","GatewaySpec","KeeperSpec","OCR2Spec","OCRSpec","StandardCapabilitiesSpec","VRFSpec","WebhookSpec","WorkflowSpec"],NodePayload:["Node","NotFoundError"],PaginatedPayload:["BridgesPayload","ChainsPayload","EthTransactionAttemptsPayload","EthTransactionsPayload","JobRunsPayload","JobsPayload","NodesPayload"],RejectJobProposalSpecPayload:["NotFoundError","RejectJobProposalSpecSuccess"],RunJobPayload:["NotFoundError","RunJobCannotRunError","RunJobSuccess"],SetGlobalLogLevelPayload:["InputErrors","SetGlobalLogLevelSuccess"],SetSQLLoggingPayload:["SetSQLLoggingSuccess"],SetServicesLogLevelsPayload:["InputErrors","SetServicesLogLevelsSuccess"],UpdateBridgePayload:["NotFoundError","UpdateBridgeSuccess"],UpdateFeedsManagerChainConfigPayload:["InputErrors","NotFoundError","UpdateFeedsManagerChainConfigSuccess"],UpdateFeedsManagerPayload:["InputErrors","NotFoundError","UpdateFeedsManagerSuccess"],UpdateJobProposalSpecDefinitionPayload:["NotFoundError","UpdateJobProposalSpecDefinitionSuccess"],UpdatePasswordPayload:["InputErrors","UpdatePasswordSuccess"],VRFKeyPayload:["NotFoundError","VRFKeySuccess"]}};let ai=ar;var aa=(r=void 0,location.origin),ao=new nh({uri:"".concat(aa,"/query"),credentials:"include"}),as=new ia({cache:new an({possibleTypes:ai.possibleTypes}),link:ao});if(a.Z.locale(o),u().defaultFormat="YYYY-MM-DD h:mm:ss A","undefined"!=typeof document){var au,ac,al=f().hydrate;ac=X,al(c.createElement(et,{client:as},c.createElement(d.zj,null,c.createElement(i.MuiThemeProvider,{theme:J.r},c.createElement(ac,null)))),document.getElementById("root"))}})()})(); \ No newline at end of file diff --git a/core/web/assets/main.6f07a88cfc748f57e21d.js.gz b/core/web/assets/main.2f351fafaaf99deb7f66.js.gz similarity index 86% rename from core/web/assets/main.6f07a88cfc748f57e21d.js.gz rename to core/web/assets/main.2f351fafaaf99deb7f66.js.gz index 1a833982299df121160a1d6a5f4661e5553cf095..af628207a91ea97e9845bc34e3f5c706f70f9301 100644 GIT binary patch delta 160893 zcmV)2K+M1S|48G3Nq~d_gaU*Egam{Iga(8Mgb0KQgbIWUgbaiYgbuV1_`rXDeEjJ6 zXeVG8wLK%V?*7>`O#AfxZ)>vv6>;ywT3W6ZfCv8c==melnnHDn5m-k67b4^M`LpgL z)0z|i`sq{CTEO@8sPo*kCU}2z+z3BkV7_}c8|eszXeac z`?S+Ftrb4&937d~B?&AXA02<2)@!_f`uKU*v@Yz(IC}i#(R0(fg7?|;&XH-|P+pIY zo|x7rLi3(Idt_SgQ0}8Hyzg%IJz|HGH#r(DEDQUL2n~92+w=x;2l(ojqEx|TvVeWFTgUg{)f405FC`|QowVN~eYYBWGbTUT;VE4de^+Rps@zbAvO0+KOkbBa+=ZY+VE!_11t zX0=RK$g!hQTScNC5f^_4N=8*Ha=94 z>!tvShK4Z>85t_nK(TJl%>w$-Nm9mn)IOJB?1a`g29+74AcIWhtPOK*nAVwn|K-Eo z;6s6TDm+g|*me$AS+DHsHA37Xgs{JDlg$4hYR`7wX~gwJzQ%u8Nlv#GAF8OTO8Fag zb5dJiHtMA%RW}VNBiMlq?7rf;`vw#p+po-Bx;snP(spQ^H;P+v=GwxIlqZ-PAMB%w zuzRt4?RBk$1is5)3W){LPPNyyASGcXjYe7)9Eu?gw;|7^rT$8n_?R(+bGPN6e9(;i z1RQ$>sX*QmrIde~6%$Lx7J8>k*Q`C^sAIjcaRq%*x9SP&SgKFrEQ`asRS(1z;g#=Y z^SV`^3zdL3!TO5BW9uI~r{%k4M&18@LWWWk>nD5Ho-FhdbmJ%@gVvX*JVk{n3zA4n zUwGcGm#Hq`lA%L-8LPMy`@4#YNY2cs3?uK--WkjDgd~65__IVz6OqpCk48CIPWC0o z=|pL}a6C^}tU|i_eWQM?nBzTgKq)uh(VnVB9EuK7301@;Br(fHGrYaC^b(J_D8`CN z!?CVL|Mv(SX|)YTuoAYX8Ptu&MpaaV=co7AhC6U`%Vl`$eO?PFA1in9WcWQs@ojKWDB&>1N0D^-%?kcn{v2u6OEAp3J)5D%eb1+Q915M2 zcO}ghfP#SXp=um(aQ$B-uYk<%b*ywb!L@BxlGcAS9##Qx!HM6+9>`ED$0FNO67-S)-1o}{&{>5q%M{kkda^uOgAW$^p@hh_;fJ`5TiNPW`J9 zmn32GO8i`25;Kwg^izCO+$iAA&f3%f8093WuGEIVl|Od_Uqsojls3x4f2D6&zN&xG z*vo|kzgIlSze0~buEWIPVwu5A_-z2G2Ftg9HJ~OE`f9~AYx-^K8Y?EXlZ&R`<}R{Q z`>T;~9dXwQ0aa0wMpZ*GiErw}n3%*j7yeg2f=(2=wwyqVh>oHg zkBHfHOskZB*^EuTGh-}OdLBSEaAtoK+LQMFNt7(U$+%Hk3yNtsa%@F?aDOP)nWTnm za(!IWs>BB-ms_xL{>|WivZ!}JSYq1$Z#x0-i@*KlFNw35`);aOJA++Iw9E{of!h9V z-TR{-<~+uotQ$4?N&?vbEN5ujJX7*xM|*TN^3VQW`s{4*n<2~rW_b^DwfBF0k?wz% z=k5*7*jr+2@oe`=4H?ZiXG1h#C-Lgl`*$COo8hL*`zW{_Y=nE9g;|m+(5vhh!?Ese zdYN_Gi!3U3Ux*k8U1ledL zP$eNduB89|KIZ@+K@yUcOgn$OGdo{w5d?8L01nRmsIDVUWHO2b!95ts)s(3174cO; zV7Vg+`AUmf{ZJ@pRP&Qh5hIV0)GZ6sa;n7UjLqS^m?p(@Iu;MMu{_R8)$umPS|5Cd z1W|#iO(Z+epcRa!ePx>f|8>IsC*S%wC|PBddSgVd930~Mz#(jxnt6Ziy_!Oqgveh) z<8!zPyZh3(Dj+jE$_co9ld+k)&zYRJAcYj+JGjf=E9=#Xf=rYLmV@y`!oGi@RWZL+ zZBn8lzv3z=YD`gP7L!~m1tR6Z739TXYjJVM8pfdzbf@>c$9fH#S&GrNiTXiv=`3hS z6`=K}*LJwtG#LzlUete~5lx)~`RO_qt}UjSj;gK5O7;G)55L_obx^9rQ`RGmo3U&p zV({2#HAX4R03|7PvI{xns89c}(W6ETDxzr}aT=40+OVEEfCtK(#}R9I`YSJdrt}RZ zzFse3X9d$5_?QVC_3U762ec=g{-6eGTWn!VLF_6y6%3-u5{G{-{tf>s{7c|hl5iC0 zguuuZavTe|w(LeNK^4vg`&JXGpmaNzYShQ0D)`P-t#@4R))tw#(Pd}3F}Ol%%KUop z(WT6Rr1EIm!5lnZADTgVmT;$x-Ytwm^!mAahD=lr5(p0xWEfKTnN;o+I3ZQ^rZt~n zxoj4}23KXJt#^O5rFM~TW#uIO_Rj7R9` zUL>6f~0yY0(8^|gp}&If!1Rtcwh9f-I@JL8&j9*nO#4UUM+!-45rw}tV{uRgf#sT>jB{-+Ec2Rs1ZEj?Lac_9K1s zuva>DVG+({I%V%o;U4?eH~9e810wd;qun54KNs(Ri&pi*{t+`Jg=62u-r=Va%F}20QzIe0@Ai>iors9rA_+qrx&YKdrR?)?3+?x>YVL`R42U1 z6v;JeAl+D^wWkhf4!#q%v1-24yAX=j4m5iUhBAXaP@_hP!)Z^%Y;6oOp|viEUDrfz z=C;Sa_c@_!X%O*}KV9v^PSpuuJe_}vuK~A+X3trp)tIGi1_ zy(GH#VG>p+*QMDJ5f8OTf<+MksDWr2$4rYRiZ%@#MvzVqQm~kU>S*ihdaagB(`SpYo-cq^8^kLsU`B{R$_b7Ae(VkDrw^24Qce-(4rXzZ6<-J?k{~^pt;#k?Vp8VuCE17=&v19Y-`NKGDF5Bq{36^lkNB%zjc+ z{UM(8*iAAPT^6z52@F)q0gKpoGs4Jo4kC*{4S`bJu|i_?=S%JqnPG)ZjD`$v&b)D?mWBct(xw$BVNjysxyrxD)PcY zjTzey(<#_zg|;daBOl>?4jUUCxbo;vXd^IBZ<>PA6&OEjn7b9nM$mX}`4%@0cuJ^3 z6`rT~_C?8MLzWnYm~DR|l5#91P#zK6DX+v%)p5+AfHPzHtXBcq@H>i8xo;qtGZ$QP zI^YnKe+>e4gHd#;2CNtaY|ar#(JzX(%tn{F!)3&d}-=Z=9|!g31uDtPu6$jIZU>}K7lMC!`mJl2N?&!7x;ebo9kZ+ zzIN8aPpp#`X^lIx6zp}=V6Y8tHlMdJ~ zl?p8F$dcMyk^ZaVT$%i3I9F!>6gXFo>o^yNUcfs3N0&3mWuBP0%rYAhr%ohG)II9j9f2#6=TtQq2;r7_bKfkppRRnXWGa9Xus4; z{;1lfeMgHjxxF3aQgM&eMc@Jsr16^$Ia6OMJa!uUMIuDfr?_d4q7fN%wJwp^vTVNWMNih z)-H)@c!#Yh>$xm{F0AL0=`=F|!$nwvmk&74r7p6f99hO8-~mc#KB8_hq5&kVfP{{e z^g%SjSK_!!dhuX7?RP|&edME4aRQNBr_+_*bPBs^IvpFRQ3JIu!py1;5%+`gio;s; z%P@b-H%`o|`~M8dLAV*7I0A}p#N{`1VSXjGKn|-ZOTd?2#9DqD?0Hzz_!oJR-y(yM zXFr0QzES@d^}MK@UNL`xk6z@dZSGa4aDhiLCrj(|ATpmxiutT@Ca_`5OmNj8IXeIX z^98EymBo4m61}E+9TL5;Ge|5JmcR%Z!&HCN%&`uOX~RWdWB`ZmAQ7y90?5`3g$|p4 zt;Zx{3~v^wP?!~9&TWeOSzv#%s4B_qni|kKUU6&SS5_Eer)p!2WT1L4hkjM{>`)g0 zdin=>oNi|CXS5E~wk{`-yO9>pkP!*R(favxgi7;{UM#azS^}$AN()pgrzW+oA5wpu z4*fV5L#V}i5Yky?AYg5u7kYupwV3T?zQG(N%!N4&BKNE6^`!LNN%btFL8PR+sCDKo#)wd&`3axi|VH1&ZG2JaOJmTj%jwHpVn;!e?~7#5jg3N1Ld z@?kv1pH_C0FFBc{tRHE|jx*Musn&n%m;sHa=CHEz1~CMj;4Ge4cSgjzAvp3A``*Y4 ztxc7eS=$xLltPSHn;J@$s*04iG9XBJcSlDo@N=22X*ieX>VjE7O0fWe9;Uqy-${MJ>3r*+zc}BKpu) zz@baalT>~z*8H#_pPjOeP*XE%EHg88zRkS69>4dL>Rt|Gc|+uFER~L4f`|W$ot>Q* z0g>S1zrMY@xgHStfMM}l+dBb~;N`#5YVE>raP!}2x7W8V1)DtA!6B4}Sx%?2$jFY4 z%lT8qdD)~!2EHE|{?x>B>(qZ^3(1d~`z+s{mYUV7`^mC)g+Lv#(SBpLFQ-Af5tCe2 z#4}gZDZBLk`@hYzcU5FU;>L6068t8>wG2?HNxj5lo?8~I_(|-Gm}90&zz-TjChro6d1Q_Cq%2+esJvX&(od)I)cm-x zJ)w0mIyt-3c<0)5y|I6_-u%gUBU)*`OLX*F?=%BPajgLwtA>>33h<8Fq_`!7Q zoip{V8IIcb5J1oussj^(F4Lbp|C_%Tz30=TKuCWt+MTwyryJ{mzZV@0=y1e(I+6ER z&y_Y`1eK{OlYY7H&`(Whw+k5V)mX|zM3a6ZT)-#$ z;ZZ9`}N55jTA6gQ@FBw{K-2ntJR3{flWWR@(LP>2kza_OjxG?YrT0C%hMVy6PG%pGT+`o~4p^=^)A-(e9Fz|B(m@WnF&;Nx8ilktRJ$?Ymw3gYC^3 zfqrsgK7q;vFZqjbtpnAVAT~0o=PU!0t{SVT_xd^&R_4eeD;* zz}E)#&@6xBx1yXdqwxQ0cVyiaQ5q?_uxudZReler4YW9@;kL4gp2Be869fVDAz36w zO)5-M=O}0tHhJsPb}xXNeC517Q%eYWg*jM`8LN9pMeJ6IhCH`R*S>iJW}~ zCGy+9DUmOuMBe-pQ6fK=DUmZpiTq{=kXPo%n-YH|@@jcXLU)C~VZ-&D&Xc(UOTwB0+dB zN=X3)Zf_l_odV<^u~fFe@*9<;Z+$Z$@`LOArb!~BNq@jTeUl~+QQOEcH%M~N(*7WM zh`c-A>oMWY)S-T-PI5E>H>X?lc0Z^b_Tqny+4D1U1BpeJ`@DoJ00(>@FFx)p>@(TD z!!&dxjVGmXLSXCSu{I6}2VE+ed%#h4Q$C6Sy%`aZlc=_6-@rM%rzxjGMjiwikt`i@ zK_&Bu9y_R{f>}p?Zwms8xkR9~)WW=wXJ^`*Nw4yc4$Sx=@a6Z~OYwJbDB0TB);51L zzkotw)w`j)H#hzEHoNKXvUabvb;J5$c7JPGoXVdpiub2~a*Fr6r6}It!wVvR@+Vo^ zjpQ$c4rJsV+)*wDTzqVtjx>=s15Nm>BfqoPOQ`^?r7~y8D$+~#LoC0u;M^`5f#A9$ z91mX30YaMp5GE4w?PTF+U|h+S;#)IuFt}or1uzL?oSL1^ip;LzG`Z&`MP)& zD2beb(a02%lSUlSp0Jsv17(8DTJMZM%_6@mN-E9TA_N==qU-*}oR*3(Aj4oSO zS68NBq`z#F-fBCTqlLWmJc0=iE-xX;uiWt=LDZ`EH}8tTyU}HDwS9GURaisTJB9># zgG;{FzQS*;0rgcQa>pOrt>!gW)t9OVYm2Fb1nuNEsn5^eN=OD*6UkkI6lt`KE(UK_8A{ zUv7Z%P%OG#$ z*K-x*;@w!>YE&ol+$Jh%TVUhaj)>1#e}F?brG82*2gW=zMC#@<^1DqN%Zk!!4i=f6 z1M9KC>|B)1&c*+b&9~?kFn0{qLL$@lB11F91{Ia4qJswR(hQJ6HgZ8ULXQHhu{EC*~&p$qH^3rY~{*fL^;F$gAt8Wc_Z8(?v5 z4+rFIV-J5rV*YT9*v2C_VS-|9I=})=NoISwq1X)?s%5cw^lPTXX_W3=rdPUZq37%Z z9}9`!`?|f@AI7?&pxMkZ)o^bZU0!tt1-CmeL`sj`krBBeLvkDUA*;2_3Ox6Ni( zvBS5)tP2C{2INKy8FYtyk4G98`@OguOsDys($jxYNunMwds;Mc6OIxUgE=$A^d8My zxGT4CXIi+M%SS3n#|*}0gcDgzn@zq)=Y1o$eU3OT?{-w~c4WF8Eoh=9Y{4;%AVYKt5_HL{yu}J;NjNAuNxfJ^v?~S9$ zjLd)I5Jca<3CLu~vW(ucXi}oAXCwz)>5XdH0_%*x?3{Jr#f%iga#ku{H=8yaX}<}q zAYyQe%42QM&;T;4m8zwv73W*6_NH_et8d{RRHw7q%wTo9AA>#LO?fNOdRWObyo>&5 z;bj{TG4O97R6UL%?9vfvyU*dnii~^tImJ35dv}VD(eR{$T#({Pa!ay*xjC^R-6~@%JJAezpJho5)-7 z$m`SN5+H)XNP}pua6_oH^0v!FYw6uyR*an*O3>7p+^o*k5Au5 zUgVL(AKvdDpGRKok^PIv`)`lDI@>?^{_p~txGbK|BJWB)9m1Q5N8TO1JB+-kDLjk3 znMdC4pBzRWXxTh+^!6h1j=(YC&G9KTjuGKKa(;1k1miaw{MGU4!S~mu^wobL>3%e? z4o*)_4xyQYWH{9RJOZ+ywOj4Yjev-YD#(6#e|YwDr-zc_-anqM9{fB)+I z;Oyv~Dz~3J^5*F9_;uvrKaadQ+y4f-zkYrA=IHH_`oK|W)ihA96aX-ekKP_$oASu3 z6nNyv{j;O}SI38?-W-Jsgg2Q7Q4r z{@FM0YjbrJ;<6r|z1crFggNM+9(n&3zrcSUIeh#6B=X>|`hET5{_*=mRib`FJMZ3K zT${1lPv%{H-0pJR6(^WHZ{r2T+d7>ePFvHPaBR=R5AS{PF+4wgLv%ZkY@*VGp-+gW zyO^E&{UZ}5*0Ho7K>rfAi{Ix!qQtG4mFGec#f9jd_U;#Drm*_UdnB zVaE*Q*<1P+g1#wGN9<*LeP^$d%~i9CU=DV02X+lT4F4QG^M3tx{LEY@zSnAbs|7FX zx3_~(ChtchmLAXyg6C>=*xF`5o_Wt~?(d)~Ma{1|$eF9vkLFTFCr2iF9r}`Y)Fw*e zH0%F6!swzZRzE+heubC=rV4=EeW5wH5$a!(tNtz%f*?s=$l?W(`&hU$f*?hBV5b?|#Yc6`^)sklKTbq(`i5}A zA=7hNENaK$WiL0@o6Q$M@HCt4mj1ti1W>NE1jASkbQQp_5r-Ds086mL0HQw#<6&Z ztzkUWQtv8yDqg5C_^xs}sSS`UY$723Hh?^vPTQ?E&eXK!Z*G9N)ivkoRKYBm2ec>p zRD+&Q#d`=Ku^4IiA6Vu+dU zYW&Q5W>cA)J5cC7_w2$K>sa{fujSHRReDn@#k&-W`{iP|8c}jsDc)4YX{C4@i~nDx zbSHu}9>n5}U!D^f4OU9lYb6`Cl1&B1!OND~{QVquuz1Pp7Jmpg7Oxb`x^%=E8KiZ9 zh`)_re;wz`)z_Q0yBfP#)qMGt1)D)nqm+xBp(`_WHes z;;_s2-EZZa#T+#I&Rg9e<2cjd(>;TrmmD1H1%LL zHb@OoZ<&m@1b?M)hpukuS@~|-_1{ES0DebKK@<%q-LLaQoH7)BFEj` z144kTu2MyYQH#6If~dWr>R{a(AoeoFozMRs(ZFW|(p|n0?D-YYu0HcT?-|Kf<4suW z0LC&a!{*7I^ro8UuOWW+S@7~@dwnW?_GR$$%-g?xWU_Si*&M;7^022 z?~V-a4*$iL3YR}tBOJpB@d-vZei^@L;S-E({4#E@uLqrAbv1L6;Gi9_h(DTN-(}M8 zy#*NT9yk(LJ%PY+NTKu`gy6}>7)G!>7RnduKO0UMXf=?@

    l8np*6qgN_aDuZ0Zj^0w3#_tLhJk0lAkn>kmo+Z<Y=Z++@tpTbdW9ad3(<1fbbk&zkPpvT>qjR)ZVHN z)~`>%cxJ$(ExR#YNL@fu@Jq9&gd!#Qe=Z}kXv=6lL|OEB1DAL04>f;((#Ta~idAtA zT$x9cKGdiW{m>rx;S$5HFhTPXA`yQl*{lYx47b$L1SL}P?djWVK++34 zi&zfAyr(Z>$lywQt-AV5v5ZULJ!c3t@%f%TGRq?%a>}`F)Qn7&Q{HKm7WLa4U%0d! zO0nVi0A9fS>K`cu$Q%;M{fVV0seN~3-nl>3I+faI?}e5UJ9K{~sCub=aVW;adBZ~m zjbmt|v0OB-McSMk6WO0FmKvA$$dfWOyqqDnZb>#|UEG1CsdF~_8OogsL0Awfm96!; z;+#^q9T(%HcXd!xn^fevTHZHbm|0RTlm+SL?sZ5`(Ob*raz<#VA|)f_#|zt?Nfv(R&Afx-;%qFa|F6=oI-#K8_M@>lE+L}Kn4`aww!T;4LS z)dpX@+N8@%t|=jF2_29p&bwhkUbBAo^aa5eunP1u@MzW7*M0g6 zrYTi-3Ab^;f}?Lw>dSTNNZuj;`kM8fI;v8QrFgT_a+DX!p^yCX)#xmtC$CtG)U-t% zWofwlswzKjbOfKbw%Wj?SWjEG&lW7N%@WUH3I6I6L7LRpNDUjv016zujmo#x?rQrt9%4? z#`Vu%DCC*{-gSb3;z@sEmt#DM&tEDn`(3bBt^q82Kh&@CytOB;b4R_u^h$pUO&8%h z{v;k|t{mjAz{ntq`Fl4a4tRe#d|SjX`GOs(u`GWAbc=}O&)bqUlBKp89rnPBSIHui z|1?RXWs1DCpt1JNlXAw|7fXv7YhOMoWvqSigpkoOwxwi@wh{M}7N!+of2M6uf%}zh zc}Ys|mcGgP$4?*Dr?>DjQaIlCTPj0>_TGXgVZzHVHYlje?hb#tIDCJ5jwjl(lc);o zmXc%r)v&fCS#_H?GGF*4|?f=ft}1n=16vZc7g^u~~xCD$9@!N}i)oN!f@|44mt^2bJR`r|9w6#C~-xLvDrhS)%1) zL<%wMFwS&|#mPrAk7avGqEl-rnBU14dP3OA7R1G+wo$ywH9Va~e8eE>)-9z<>MuE8 zVIz&gMusBECx5ttYOb;)`OoN`ZF8L_P-dxAMK;WhAzZlx>sH2^Uqy2uYkx0g0G7wp z#OxjmZ75|Cf}=iUB2|2I;vJeGGDQT2Z!mfjY4jocW~0d6CjRiHiHVVqy(B>V)8|n1 zqmScf_n^fBkZ%U}nNEx1=uP<#F9Wn^1<>-KnT$NkL4WpaIgowMlyVc!1=E6H)=n_4 zw6OQ$FgdzZQCTtm>b%aM*hyB{F>lWNsd$X5xkPGso)wu8Qcydu%okS&ogmc;=OS4{ zVP=^^pEieI>)aR=xmssIp6KKXRNKy;ba=7_Lk#l47;XIwGw3Y|ia&J(M3ygrxSZi* z0VwpftAEBJ=8t0$H1kAl)nL7U*sRn8-pa zPDVZdo6c5WchvGQ+`e)=G2zRA6wwCuJcf~DFnkDR_C01lN`nqk+jH!ckG(}0E{nd7S0po5gr-eZG(;+f3CU&SrtQ~7JbXyn%Rx{P!{IG@$XuFiBa1-XvrB ztH4xOI*MX1>1I*mPRddA{CSVvhjf$-21$=f8g`T6^KO!|=cd~%ypzMhf2fAna134$ z(dkrtj~Sp+fQwoX2#-a3J)eU!iGs~^>VHd9rcVnqq5AUYSpXrGWGfu;z%PDHAdN7Y z*zr%q%-#||)V73Q+6IuM%C!@i%6QOY114DmpGZ0LWBs!tx*aCHYc{Q1yDBwO3U?4p zHHBP(22o(^R+1-Q_bSvzSEN*4#zYTG%Gv7L);xdF$=X)L2L!PU^5l&Wjc2mZ`+qMI zzZ1(s$Mt@uTc1un6TZd+`cxeeMHJ`^V{a4LpbZtzN@oLtt%cu&UeFOAaDzx9e(=S2 zfPahB8z1l>mEwZ7s$K;|#O;o#C#-}77V=W8wXdvHmEx-7DI8L)2tz}POLk>$56HAy zP!RPbk$Cqso5jpgmJKuCOIKqgx_@oF6+t0MS7A@Asywmna?Gi9KbVLQVRyi23Ow=m z=BHI>1M2)3uh_ArHlghIc%@~PZR@hO!q{6x?8cMZ-v^Osk(6aj9?K8@eJ0} ztgpsKStK?H6Y%D6@h;gkEj&?gd)D#ARxDc6sV`bFWbg`ae;>qR7yc2k6@OX-gHr1e z-p&~()SUAQzFJ}m(83bctT8;<+%oluXocEvCKf6&l6V1$5;k6JL8646Soj;QjdhTL zuo%)~%D5knGj{$cx*)Ad1s$BrBxU8CV?}ID=?9(b>(_@rUSBtxD=BL>Q%Ke4gUwKi z`8D&m;zjuJn~v6!9uA!aGja(@&E!>{Na*R8!1oVM0v9ir5cm%k z2@eo!CvIKE-Vc{A_z!+D4>W5C$0h0otN9i5HtDgj@iT;{rjHH5R09yA`k6&BKEq6& zBEjUILniMMtkzA$J(u424{U#TfP%zrBN2l~$h&F?dzs{m`K-a!o_J&u^3RTvRI;Al z0Fc0yi|%0Dg8=0?InuBP3cJ9}3lcm(u)(0bx=RjqV>2N2iJDJV%@?cYgO_oecqyY@ zxu$ptHAg*x%spD7($D4thJ3Z(o*sk^Z`CUuoI7eu-?AK@*eGWivEF|c(8gnA_m?%O zutYNBqNW)_7UD+$>@F4Rly#HgD9P9}Sf$?*4taD3l8*+=I#8(V!i%$k)kXDGEr#62 z7N|>1ojrs73PeX-i{(S6WgD-l+xf0&D2q((y>ZlaU@nMXewTw`!TKeFHHtHCtyF!P zthFneZrIHEUj*aQWHx`c6*NZi9nkzT9)*smCDZBU6;`{6C#Zkm@d&y9W>Y0qgLIin z9Dq!~$Px`i9`MVa@uj-YsbV?H#co}lBl#vEH`ZO#vm>73%|p^S9e{+8!+#NC`d`O_ zsW-rt5bta(fFy3vVii*2HB$Ebn5Q5pXlR^LUX&Ch+7Ke0TBm=86Ay2rF~lD?>LbqxFuJOJz#sZj<%sX7XecRX*!Ymr5!Ou;%psw73|174m;1QO-=)bt@3Hi2 zVw!@N>fHf$iNJpV=`nnG)d3!jxQO+hw*z*jWc2s7qwZ2}Q?6AOQ9V+RScAtWDc zZ*FV{B+c^y7b%nPXm8WZ6pOtd^{6blj8kXw+|@P^;Hg@ZhxxIGbBVK>mq|f~ z^D!CcvMhbA7{J~cvQaSRbQFFU_>)0Gdm!vvX%RpPChin+UgkkC`H-X^VS?i+*qyUatUH$K2-LMc+FGH*)T-wh zd^OLA(M2ZsD$-R9SRa5d!&XmC5Ng~?cpN`eU;4$)`Zh^Enon}|hBC#x$yj<1do4_v zdSLt60buG(supgUJiWP=V*jsU31q%s}*8>8tYAmMHbY36+-`A znhbw=#{9a1It?{NcEkJ$q&F<3I+vgfR=e8TAPnvvd-wXnhS4pP2MUwuw;*REfbl`7 zy0{@31T)2_+k3^J$~g+jjs}G2u~g4ATX^+V>ME#>!J<|z9V;1gz>9o#3S}dGApN`# zIvCtQ+Gf8J5}?wNVOp(PDu%Hu-iA5dfSG^mAnmO9I`=PPB4vxCenW8y`QXb^NwW#i z;Nj~41oW_%Qnk&%^Al(!-AxMkx)@uYhe)8=L5GK9QEZ<8#Uw(>6pv}98&QTX!rEty zfJ_$hVGp1_G!-YnR<5MCN^?hvcWb4y2ajSU>82f(xY$6ad)Imk6r@z!_N1TnggY z&&0YAjp*~O8sZx!QGRTd$14#v-GA_AM2?0eeSN$>{+6D3ut@ai`(# zsT^a2U<(nyrge;&)aT)8ncGm+(0+fX*anag!d#2>>memvyE_*+%+z*a{sjo1EWq?) z9;O!t(~Hl+^ro{!9B9Pai>3WEo!X$cUYPIjWZ^gXt6ComiSO8odVq`eV$f`^v`r+# z>Z$?l)@-iKdH0cz_U!4psl90a*V8E^qX)7rkEK{!^boi0yJWz-kB;7|lwW`3+jZhO zW72S`)T*|X@5J(QmQPB3chxV5%PV8UW>!LxW@d`Tr1Mh@H-j>e2#6biYs zt_-P+F6sfT)_H7a^*x@N5sYNzaiSbx;#X$B!~(_A`}fjXji z0vH~F?-?xlTFv%NQO^$|P9U2yN`2_Sdetc}MoK32I#GY#NwPQ)CJhzPR3=>|!;7sshZHx$hWe-s+MY9G+w!Y&(CgJ5@e$?(|9I+1x?_U$OT(@L z;VEn~2Q=kIOWUbDW&6gm&uX=nx}WCPsFUS$%zleijhzR|QHaXF^RuG;ImClm^`eXN zTpB_pvWS-aE!I6rQfBr6 z{LbHwk!k!v^VQZI2Me}x6l8U;j&120mfUg0Jk!xyR zLCJNM@e&I<8XPdtWN^>?Ae47Z*n3~><>aa_f{5vvm*`&2&<3+0R4RIVU@p-XQ*4(# z#nR9mw(~&Y48wm@V4jgD%z`}>t!80&-=CB?*T__Xn4X%0tlj{nZ8Xn6BDHDEIZIWe zWEV?i?0r!MfW^nn+k$lgrlp{lh1Z0!yHj$8*k|B$0oP}Rcv9*cPrn4ZsB~l<-6>@b z3TA7@ik8_TGW%ji43}C)wE>wZY#mvcn-q|XDv-1_OBH_@=Whr|F<38Jz~m77q(-%~ zI|~A`BGrab(wg#ygY&L_$4hKIbXX`|o^yHmxNMlIS3{$;+Dt~JZ=22HtT&r*@B#GG zDUb>!droykjq_NusmTQ-XjkHR4xeDt7|o_%rWF~n<^E3LJAOVZHbKGKD=7wuDa!`n z>9tbFXc~VBj^Ed;7`6`oth+^u*yLP8V)+zmI_iHLq};m&ZUFUUoxGlDe_Q(V>&gz{6db%`+lZ{ zgz3y^JLt>;+(#eON>BlPF_j&j$^S~FWWy1fe)L!-({WdhQ`QiPSVQPQ>UpDj41fJq z9D#prM~|i2%-hr<_yvXKYbbl_X4UjlNyCWyV>;DKKb@v0 z=Eq0day7jueI>!x8~9vIG71tSePa44V}CGne$;l+T29U~I7umeFeZfMZy>ms?FFDm z0?^kM{WY84+{r_oC4C*#l&vz+sgCuw(!+n=C2MWGP`p!P-VM4h28wdEOo$)hez8i> zEFd7>2_4}F)2VmP)VF3h>Zn0pW$@O44)Q4D`jh8>^Y^0ne0mfJ>F-6m)AsgsV?FTq zqJse)j#w|)!$!V(9!i!;+n+^E)!uxkIZu*a_?O%TiN1Q$O(E>{sDgO5IZj3BnLF z(qYV}Q=cot;)C=3*z0E0BXk(PvHFNT?D2Z29<{~cek@u(z`@3^#|2H1-uvl3nUvW1 zlB8o6C=x=%=_lW^c!iuSpv{j3D5!sFEG(PWIToaaTV{!aRj>^UfCh2w8IXHH#VC>k z1R}bip>9TP8@2{7fob8V_L>EieBuAh`|9-*bz#glMtN&6 z$%30q`vf}fGxMf&t2xemsmpi&zEZ#JNA2za;(`1eYO6lhWVy^^B;eyoBy4; z@L!o9XQi9p&ZUkgZaT$-q`rWEzm@90TK?KT_`h>)ALwfv@2mIm<)!!hx8x@Ci1!`* zyCRp~^K>kr;0*p@LHCYwEILp>uuvpD24!#YKNj7jymyO*ukK)4TMnv7v+Bu?|b;C29bz9zlA~IkFm1Rga!hVeig58wn+MiD@A2E zq5~$Sa(T!`w9Cb9Czo>EXf4aRe1u$e{$$9+m`gT{CL`KIW^3cWL^u{4!gge%0ey@- z%z@<1NH3)iEPY2uER7~$9&ww36Z%0iNYY4xW8*Lp;lmx5jOf-bl2L!OV;X$mJ$VEsMJA*?R0>pS|!EZ(qaWF_S24akAn_iFKdt@T%&5`J_PZ8L;3|Qpd zjHLvp5crgLKe|4BFk*g?fzT{_i#E4m0q+?}zYUjh2M`p0y6EU5dyE88g9BDQHwBIA zWM{P*`3ITYrK|vHK$gGnn#&=8c9ilV1yk)A+8kMPGCLQni%8OJE*Rn8IW|NZ*F6p> z^=2%=eC3JJ0(xn@E`2b6_#|C&@MhhqyP+qB1UtQPI+idLFyIPE`r%JNAa_a1|46`D z?=8L0PcxkRmO%oqe-bH^Vbq$DQspB=J2{r&V!#FSDwU48_!v#P8pUL+n}{AwAHyN# z!bUPV)++az7lX;zYt~InUVD)U=8;P0YYNkm8>9zx6JC}8LD3$4D!*`|J+B$vCHE}# zqKT`nUJM-lY(^*sxv9<4u0@`12C(M$4y^gXjWx?yQCL_pe|-W6Dm&u4@Z#IR55f_Z zcW}MW!w{c}EsSDRAtMibdfT3L3K7*UiN-`&+8HyFzJCIfr3#bL&%tCVncL%$^OOOa zP#+?)u)ja`!K%Nup9xoLw(J9!U}^=Hzoo4Z%m`H{bRlN=f`QJ%XG;xQdq!oxqXFk6 z>Sz!I*Y!CKe?sH4Mu3YUf8w0K#TJA5i(~b|pu!)QMTK}u{=kcQ0am1=(JT5im89B< z(r}pc=wPiqBQi+_H}Iv#W5=v7qpb>ZI|Di+FI5=ecLxUe@k=lO%4-giv5-h6DbfLq zZYdWmMM5bNXDs7?Fp|~is4*PAx-6#~kKrWt9Jpyodjf5@*nV5x_QFL z+L0Z?#b)mW1#Y4csIkZK$SBEF+F*~~WXWJGnFH6zTLQ}Wlx24(Ne{e^*iAAPUFH#8 zd`2aU)?07^t9eHWQ3|_n8Lq@i%hBwQTJ(jW1p1{`<)eFB>n%`kvWL?)D*+S%9q?NL zJ3ouOe=Y+{eQ(ZZNaL@x$fqo7w@EgPw#l#;Z7#$TE@1sYCW?$-Z?%Asc)GW|v)yH8 z^xHU-y#E+^{Q>*52C)$rPpJO(9^MXn??=wJj|I#g(LvJUIZVqt9>1WN{zFW}KoC zDcGv0ORB>yo%RSck%&HjaVXU*Q!U{g@F2rDDXd4VQzF}Fw2}@Y7K%jjzOI`YSEl#r zU^XM^Pi`H)yboU=2L7ZxNck8ZogjN$a)|a zY23So6^KP%6;aE;X-))BIJzlOjvy)Ky}3-UVsV*X6&^&h01)UvnKTvgAp<2g*>v2D z2*jgSfKf>2(}eyUX}$C(=+v36hdmyif9zize0zO%`u^gOmE6^1TKTVeWb z;B-Qpv#n-9uva|`cj5jAl5VKDM?qA7J-8+lnMB@mSSc>R>QHTt?Ks_3+h7Z0L9Dkn z1Cs8-+HY-Q{0E3a@}kw+f&BqdNOsnDcQ*pU8Mr65w>H`V;S%cau0wsE!tb5-f6i7w zIK-FO-rZe?Iuuj7)&M*w%x-wKmwEkZ?Ra24p0P^)_gm)7W zO@=hR@(NA48SqMl}I z4ZDcNHUPWvL0w(wn(@HmS$Q{nwSW1d)w*&s+G+|1ddw3y+pR{@a}wg+e>**#vqkInt7o=J>$BEP`4v}OrolXq{I*ya+)Z^lgrCfTQrvyN}#vZ|R!0CxB!S!aE zE*+OROA8<~0$y^6X!xDuFbx8q_q3nr$nkzW=di*4wgEQx*rio^I!zu3$}!wz%#NFI zg)?CD_VUgnSvMK6$V-z4e+MDQ@5&7zR5kIbr0~ykuX-8s9!B=$JqI;p4GE99)WNBG zxjw^JlnTFbQ7Yy%<-+K#>hYY-2p=xJHRnNEOLj{@EB1ii0=JGOz6pFj)LY*Tu_d>Gj6`zo4bpQ&n1ezVEzbWpbQ=7?Ng1Quc7r*ag}CCk)}F{0+SptlTe zX}l_ABIy9)vjAWHaT}QIB<3f!RMqoPs+z?KNL9yi0#eoPQ$9uzk(Cc5OMQOqXF7s3 z=p`>R2;(@He>}W(OXX{~)-qR>G~Rft_R_r}p{?`gu=(_%l*B~wgam@dJxh&E9~e+jk{F|Y@4%#BO6T}zrr(nYZ& z2j)9_2euiv5Vq8M(tZ)qWqL*6ltyB$o$nB=UJh)puT;ao?7=s2!Njb#iPs!~MQv{W zlfnr!EuLB9u!D*q{d&|*#4EH0&_r2Tf(_m#YtWxJBXH9{Q5~x2>e?cJ@Yha^g-$0% z(5Dbme`<*UbElp?Uxp=z6=!U46{f~=Qiae#I*ro294g(Uho-yl-|oM^`1bVd=$FIS z9=JTCSI}elT~`G_Gr-s4JLLG>JeWQV7$&6QL7D`XW%L%rg79ia_*)FLO6%_<||fg3C_a)$jr!r zKHtKZ=$57k*B?P*0K>70w$1>b3QZvMmq=Ou}IZL^^QIQe6Dp!9p$+O4gm_6Yi|JFQ~$Lv zf1_^O&wrk0+g}XkRedlXsX8pEQTbmb{eH$|1Yy5O<10+yfe(QhlEQ1gsi!|64P8}z z5)|$X${Vrd-w=l30w7cz8X7=;Q`lK{6G$UH?fSr9%>xe-Xz#&;0TwGD{9F9}3St|* z4+#INzDcXvnXg;TW}aTEP|vik_Uwmfe^NxNy!ZLHsE6Wz)SKtOf!}Uy(p37&`O-rS z4G#EikF+tHY^?@MvBFkM)ktIhl|Lz*8YgAkW%#4|B4-NsT-moY12=OC zIw0KX{O(H3SRBWB`HJ~naDIDcY*F5!h3bCPd?o+g&)KUZAqU}WDj7trdXuC>D#JYP zF{CCNuEtv%mHdJ;om9cHPg<(=zbhe@=5WZ zz#|=b1@D$gBdoNW(`%w*ieLjo){s6Cx#WJ`SsLFc!mD&8{{6D8b30A^$y zV+04^iXu}w#E|?3(iEB#tdU5E#q4r?Ragwn6yN1Rg3?8>tbtF)Ms!Nl?q??3OeNP$ zk(f<}qhzF#YwBOrUZW(IB&)zT3CK8ZktELck|>!E-wgkbzmAhKe|)=fayc%+cN`}! z_;%y51>Y_i#NCd8-AWwuUwnEwxI$U$<=_fqEzuZ$<^s@5eif&)*;SxC)lmb~j`ec!~moYEba@?e`78X&T-%ep&~QFzKwWdUtgPLk)IiRPR(sx%Bwy68{yv=FFe)M z_P^wXzGZ`N7ZS{|2*3}JFS$J8%Y1Y;#)YcWDSuI}{=!nV%|iy;fDE3x&XEX(O`w(m zOkcJ(Te~{}p)3}m@cE8)F<>BjwR^EcbL{lMTNNdZdB4^se_Y2R>xh?e+A+Eh>9b27 zpHO)h_6JFl`hL19g6HeORi5BD&n&_*&&bP`_7;x$YCHHkEpi27d@*>H#(b?EycESN zoEsI3?sSv2kfd-GbI3hp!l&g*8H}|GMzb!AwBo0+pTt>BOQWS4iLIp(B`r-_(b8}j z0rAwu&K_UqVe&9 znZcekjVGo!i!QGS?e!ve#2dJRO!%q%6GM#|1fBTh_dsI^9XlR7?{afzYwi`++nOB~*g6h@DV?W_EQJa_}HH zh4@VNH*NcivHeAL&GUT@nAu50RAvYPZXxJkx%g|b*N)a89{{3C)J3swm-hqE2{ zm#QSYqwq8tasl5(tQ(5)@P?&C5eNGj6e-Fif8^PjO19Bc87!^uLCgp>VaT8P>AbE@ zbD!C*^Rugf(18O8`2Z{JW|EDvNR^>>`m`VTv>RBB5|rGVN{brJ8^~V-SEZKF5T*c@ z8gBo8zo9ary?@`q|I6>-0`J_}s{(|+y%|`rf>)%%UTN@k+zRrn5Q{emQyT5eA?O-D6$0LLpd9|dJhs!iSWOMht`ZsVe=V5EXEwr*hTO0V8+$&y0*>rWvCjS$dOX46bl;14d)TvtqHx zFg8&Cydv`x{MPgH zh*zCmQG|2zh^MBL|A3;}tUTh?=HwBtJR=-&_oH_ekjE!Y8hXv9e-~f&t^#tG=UVy@ z{$d5b__<5kd+PkzI))c8J8p_ z6aCFa@;1NKG3s9O5CK&H8z~a{+Tb(r=c7G;4Ajve?kdl|uH|FfhfvP9(QrELPp8{# zlUxo6TkT&dmkyGWA!L9g4_5&>f2<}&I?S^hT_YIJD}cWymsbJ#2m?5W0ep%-!T>Jf zk6;9IQcZRADIlj%_XO(h$EQ&DI6j5C2T)$AjuhWfd;ry6#|KdDZFPj^Q8~6$bA;R) z-1;`32u(3<^~9zv9RUdPnIlcBsm$n@lqs#~V&=*Vk@sf!i5a=PRn9XDe+HX>6%^l> zBFQ54ulMRTDyS$VS8Ic|pmVIusxGe=_w(9^Z3oMS3;J&UNtzQS>Vb=1@{sfK>;5CT z!E;G&t^#uQceXd$8~HMb-s#gzM Kz@s>>Zy#-KE@seMU;icqNBYtlOswa(kPjc z`+)2Rz;|M zkyvg5SjrSQU>^1m4LI}e?3cCMMO8z}ymrfIU?F)y%J+>Mj(VI9e@Fnu?t`H!%fK|O zG%a3gQx%r@0-&^!c`qPXy;`kl*jKDQgBhVCV`zmhSy1^ant9Buki5%H-($G#9U{Yk!{G2OJVlpL9wlIVw+x_9+ z!)+gj`|3f^Cvf2zGLyEyu=lH4lt-0SeYYJD`hY@R`WO&;e+|X$?X8l4_s}H#Gk`*3 ze{Y`pQ5w5TK??n*iqummH{sbRGtmhkVj%q&wwVh(|2#HT8PVI!>Yn`&O=d+Z5sYyx zf{sJ{t!qFYfPzg?oEK1CX`C9WbWu%T1jaPiA%by!`I@P;v=BKRvQHM!L-WV9ZhHr! zD7`wcS!Whse~qjB@#zp4ceIy0D91bbI7-mi@3FJUNAUJeUg!--&wa~9)e2(+d`3z$ zdBHwOVuIj+tBR>XZjw*u*moo@*Eg?bBn|JjQAkKXx$VW_SSi0Hg9p;5ZRY4Tn6arN zX~pj{Cnyc=`OIcSzyL1lCVTW_;L}e5p(n9hcSIlje*moZH3<&QoIdSbX3$$2=VU)* zjU-%g5oi|#nmk$~UFZ$TXQ5JDG9cq~!=xHnLN5#)=n2wAHI$Z(sL*DVGzcK_0Nn>C z(v26pHaa*i%t+|*Kes15J&2buN%pe)TaVCV5a|I`H0h4h3>?lz3D*HSv^VbNcHxT) zzwbGFe|VLAio8~%)!5u_Kv|!I%a96I^=UW|S>)YGIf|Y?e|UHZA2z}yy?wskYPFt2 zx8T-ZU#TunyTF)F(#Tt1_lV_VJft$^pZsNNe{iR@({AlF>Oa=au(dMrIouE&CL_EeX_z*{yYNz59oFu+g*SJ=o}P|Mp<}A`dqD=AXxdjs9FRi^lyi zf1T>3pH8WXOAB+dzFI!ctlrrF7d+VXRJEDF`(;B$wy*_GT<2m zlz75XS_h_$(6@RYqDh%3rZWPmk{~X|TY9hDNK9*rnJ^AFo0w|pv$5_lJ44M>1LHf)ln~+ zz<~OLdX3D zSdnkd{hqQRgf8ZEklgCf#X~O4>-FsxEYFaBs+Mq}e9pb?9aE)TPzOpWmcT~sf2=`r zDhLh(Ik_<|!w1#nR;y*tcEdec739?UO7FL7e_e<#Tt2x9VxQ3igi`1y#gNhVz6Nk> zGMiha$!yo!!$^nFAWa!9VU%@u-8^cHrr=D}mKo_W$dXl_AxvVk9$RNDzDsV(HS-9u z?#d^nzH5t(ks|1~PNt2|jTT)EE_CUgkGox#Wf0=vv7zSEQ!X~(lm=aV6+absLLXDb z;9|@dkbkMh(9Z@$U_V!v{T~n*e{SMY9{DR|qNn1Tni%G50K1e!*z|x5=Tv1q4p~ZX zAt<(U|q zd8B5qGzAL>&WQIxJw=U+JDxT66^W_60ba4jdjVwrQ!d^0q0ysq)DsI4=8+xeuHD?2 zmL<^kIB=Ut5OkBlc=-A7TN=9M=qw5ulf@vP5pS)ba#?e6+mLrmh2Gw;K9`80drC2mD1t?%P|UjPd7USqQj zj|kGOyYO4F4!!w7Mlqs6`79Zb{Fz8@PEdx=U4s&?R1DB^9XrBoe}5Tz(^v7#gk6HHcXI{qZdD=~r4m>PU)0-v>VZLy1@D2UO6t zwp#(A-$U@xt*y;~&>x@HDfIX~?_s`_l1|}^si+V0B7-b_pfDPu>qye?^U%vPLVsUA z5F+I6`KOJ8h>3^nFo@RqLa7(TM68xA6Clw(r--&*f96*ifAR+q(t-XG&x5;SQQ+4b z)Ng_ry-{_FxeD{YHeSwWWvXzaO;{*z2{8W&T^;^-(kKG_{6o4#&d&=LhX`6p|6%cg za3iVkK%s}q?Iq&_(ci83K+uW_52Up=KgIMHg+af2Vh1b6I*r{CsB1?FB+4Q0&7O*> zCF;PNPxWkme<2+;KQ0yhkxcXrfEdnPQ}v2JkqH7LlB77yn3V~kSttm8_{XTT+Ml7$ zYAK@!&}0!xk^ogc%379P(ktaHoM}H^r6}qK6XACaewt;daN3jpIEboQ?Z-N;eF}y< zMW^eo2y+$Zvs}U4vCNKj`^EN#hP9%M8TB+6?dN?Zf6x_e`4nfEkc?n(C$HpYl+`Pt zrV48%+6NR&Dy%td{96zBWqQEPeExz^&!=fIs}-(F6Wq z>j8J;a%i~x7y%NBC+N);wMbUUM#uYpyU8zGS9*(a%dQ@N&xlMP(asZ$LNBlKJBG#+ zI2KXnf43kC2E>!k{B}Up>nQWrff1SSweHi}mT^Q+0@MX0U#E;&=El-&jQvXn;U%r} zG1h@CL_HSBH%u6JrK~{*kh%4-!9KC>Si&ap)UDA;Isu$lXd`X|v*7c1y$Pc1y;L9A zNIzj0)2Z)6L?iVoXf`!YNdwXfq7?B-&}^<0f7m7^AQ3kxCU+s%DWg+}-T@$sFIBgM zE7Svybg*_RqjW36f9;6J)Xp2d8R-U-5VyhVsxgB^F+6k$47aMh6&1BoC8wt`nBV_@ z_TGiPZ5wG6{wuP+yguXxV#PZp7po`txXrD(wspKdj6_9DXwv0HiEZio?dO>pfCMGV ze|EZU_w3ny5>q4y;xYgRbHfY}32|CQl+7Q9JTtPhLO99D445bM&}5Y%r_nP@%(a+P zK3#EY6(7a*xqI|o;lVNbqv7#tWr;gozs&fsE_NNyHCw#e-`Doy)e74A_ZXky_WStA z#;>R=*bRaReCyTUiud2cOmA|-6RTkee_zCER;!iOI%Wb6uqDWV-D`LOA6)~Xb;wJ3 z%q-Kzeo^R`AwTk10Y?jm^+u5Lm=B>fF3tgYaIaag^`L@Nup{$W9uuGe9>PiPaJ1zL zjFqHadGj0`;z{+6@V|KLt_-vSlfhHH!lIrg<~hZ@%K>KDMiw|a)8#le;-R&5e>kZ| zECJcWsf$~zgOZ?LPj}%E*J1G^V`&lnj7O^BM$?ZE#CoW41DbxV-)mU(=q~UhkfTPniu^YVGjE+ynS{#e;fCoT9##4 zJsV6Ky=35f1IIQ-%R%59K_Z@dzSqN4NW3^5_}0Mj49iS>tLK=8JL*9S+`P4hW-_2B zZ$PiTWndd-aB*sxwqctC-!n#LGH`~*&>vW~VLD4J&P$pkyNCBZykFwmi_?Ma;d|F` zoCNQC*3by-o=AuLCD!aEe*-0LpyXZR>kH9q({eGhQt?}Nqbbf-Q~Y*Qp2)JyM5*+x z8yK!9-r2t4JBiW`3)|sdJPn3MFzQ)D->{q~4!r4^fn%84AaS0Umf16H-v}H5k*AJB zADBj<0_2Hl`jo1I!!)sF)>bpTi&IK6gTV0GL-W=inp=&qho%68e`ta2xLftxj!U(V zcGmvZc3e3Wj!VS{7LL9>?0|qW63$!49`2kHmNF%*w|1b;2S0dX24F_qvjY$M?_bpR zyY|!>PQ8}ZFWx4wNe*au2DWXOmfmS=tS&3lGXk#%{jt3;Fl@7j7g)aLz%hKcXBw8* z8yP`B7kc9w!(d<eS7U>VkEU>lBAT88Jq-6*jP&l;G9XNIO}m{yOj zSV+$`JR9EGy^-OYbdhhMUVHSLWjIdHG+eW18Lro}4bv|NmN5)^_F`ZRg9Ivt3T!`w zhV<|*QHCHJ}?6R;xsVqo;fu9Q9__K z4ae%aM&M(62A*Mh1KS8-G_WO}rQ|bh!}kY);X5zivDb49f7eY0u3-lN7<=Hr%rFgmU>UZBQ0$ojEEdHk#=50>f!#wT+QG zFo$Alm_z7ia7|GI8wYH-fN#tpfHhDn8u$oVb7Yuqf8rT7)`AlYhS_umf#JCT0%u1{ z1H-Ung}&jyU^|{bl(1lJujlvt8gp8R4qy%X7G2~U(;MI$A8;LB zL?O7smIEMALLVTE7s8cd`FVzqe-eS3jwq|wf22{(CbZ9`izoscxg`2$0C;I&8&>GT z1i*{Ln`S_$5NDWO<2Yzoy#jrcF7gd5X+m6{OP9JdoKM!0>hht5euKQ}t-D!b&j#!- zSG%~#H)f3_U5_pe4u+N^46Tb(7oY%3C-e;yKw(Ny072*&0W33%E|iXo+%WybFnz=H ze?uQyftUI_v*#GW(y&}86o72XeN?`*2=C&B-UNnk0!kbJOCJ?i;#f1`sw*e*21>NzmyoOL$VhQM;^BIZ31TYx(q zYN0J(*oF^tY-GW>n{<(d*)WTT-jXP6Tr7s=g`Q!!6 z7C?98&_%8Y*8`|oNNmGJq{IAOy2i)~E!wDkTTbkr3E;75wU~9X;f{#tac#Ot(!z29 zfQTS0y3|t$`Xc8U>=D=oD+JoAXExLmZ0oo>H|GKn00YAx_28czU)Lkh+r4H+TP6^V zqn>TJ4qa;40uhO&sw9y~`;!UFf5wFwgBSTGK=1@m5dJCS1cS3QhW=t8dJ@2F3nT_2 z(i8!12Xv7G;X^lJ)NH!Qbk8yz#6IF8LE;gaX9@~Q;wpf=iKL(B(M67f=>X!dA%#8c zAxTw33ceiC=-K!JF7-ly!5#HH!?Nfi0ghe7aq;OQNcjOa%Qk%ctBWyVe-QzQEW>v~ zt5?s50C#klTKJjWAm(6%q+738U&6p@_R0D4U2*0AkheP$-oCT#qwcB+m>N^i;-cEmbSU@j9@uh z3_QahEzO}ZG8Y4L2pbUme*nQf9E_F&(?yEgL~z4{yTE&p48U{-dU!eLAb@#!ASgK&gR}3U{1Ql)QeNw#zi|F4o0x)I*9mSJA%BXP4~sX zG?9RSUrYhqDsM4keLwJw0DkcK;?yx=R-2At2R8c~j^Oe@q)WEhjLBfWW;G zA#mUD+=XY1LJu&3*PsIjmLT$eu7RsZq|?qjvJ#+)jbQ*E0`240b6tG67&y=>U~Lyp zXahTE*E}7pYi~e|lZk)z#7Ca8nc#rNamREP183xre_VhrY+5dEbuL}R{%2T7zHV%0&Nr< z0O$$Jql<*B1zg$CTL5{#gsaLk6^ZJ;72pd^KQ4TcSsgE;V`tw2u8TNImt~IVB3{^lI31uWKwtyC2UWT*qCSHo(H|xy{7&i1fxG$BSHiv=an9MEZD< zQyQo(3y`Mg(xs;Ld@BKAkVWL9N&*j&v_|Qz;RST5cOsxAV6Z*9$c1e?10r91hc1%F zL7r%d1Zn6HzLXR`Y=#~|-a*o{*=t8Ofz`F?Qq!);f7-&zvhlB`c6}h1fxfmIirs{% zZMt<+EJ^0M_*c_s06Y+H^;BAJKvc@eq|2~b_4aZANH(-dpkp>`aR`(b@dN=~8Y*)j zmb68enlMFaAL3G%F3nuE4I7C3g)s#35IG;9c0-l7pwWko#JbbwM;!p54Wx!M3LBQx z1UaEYf6Ly&KZ&4Vry~*uDNV@_^&H|SJ;1Qmh%U;)2NBg05Y%JGahAr=3svke?2)v> zMbZ%e>M3LQHjBj7jtQPmmwG-r10!$}6W4R-5iBGtH~_-Q1g60Z=pv_o0A$<6=>X=Z z2^cX1EZ?)_et@WT1if|uS34464{@8a3=2B6e{c<)Ss{v=ZMmWWUppv*w8cf12*O1B z;?(pEkj9u+LWF8C3LRKWj$BYU8US?{F@i-Gi7g26IVkmRMgur*m@>ePx;|ZM+SNtj z=rS-YXECtfI<^^Zay$adwpRfRyf+{*!*E2Gdg=nj0@aF3ElRL@=5l1XCeakOF$Bcr ze_xz}G!du@$N9Hn^}YYgS^cNZ2-P8$4N{}g!h#LgGRy#XKX>UveWswpg4PymdW2-~ zB3GqN>{^>!C7#&=BFd7K6r?%;z64kjpio1bri3jQnlXZjtL|0903c?=HfPs+-M}(j zpvfFTL)4Vo$bvcK6UDL|V6UvVj%5S)f8ii+j5M|tAnA)czRb2nrAXK&NgTrkniLS6 z@6kn2vH_@j60-+_D+49)!2ntXRIN*btQtL&Y=k7Q&8Ps&NchagKam&tQ`cKUYZjK_ z`Ssvt|6Lq^q#Voyi8Ktm89F3haz-lQB;bJLy=T|rUnhWCe_;c{ zzj}`c6^R+Zlnfl?fZsYmU;s8gZU7g$1Vo3kK{p`D?Ex-upkSxb zN}$$A(ym*wT1maC3(W$i%&IZDF9;~dp-WA^njPe80J2=0bdN)~PA3A@K>`-EsR|bk zINK*FV+Z-_3i7orv_qy{kgwi|E^=|2l6<{51;HEYKW!2#Em1aD3zn=ue?>>+j!2b1 z1R`}Y0+Hgl!ddj zZ4?D=*LJN9gacE@0#eake^8^B&SOfxQPb^V&m6(Z>{&iYn{M26YdA6-`$|wp|z3iT)%QW&lq_<(*vnIfA-N@T8}aDW_8+V zR5LOh(?N43E4aRoo)5Hu={rUM@-ftWqKL#K^#E9D$V9slp487E>U0e|1RWSE!tm2! zuX$GA2zi~0my6R8Y@(pB{}_ydM0vdX3eXCOHN_n zWA=hxP_qzVzhK!*!wKuu0WLVe4Iq6bk*a3^e_;cE(Wq5HwhR)Zg$>fl(CbOQa5yln z1rQFSgh-2FupAh!)npm?2HHxEl7ZoaEObDULLa5XUXQMVf0`JQxX-qiW`Y88)RGNA z`u}GPpA80Po@-dx2QUQ$X(dpPk8Ky9P#=vi&BQirG|ySU6N;-%7me4jsXi(zkhnqt z5pd_`#VLx;P%=*6g19{#0UbS(#56DuM08meT_j;@S)gnH%OSc52G${+JMa)5U8E8u zAU$YX9%X{0f0qhURR`t(l#0*}-=m8pMt$F)Q8m#_1n#`x;uMB{06eX;Fh)+;7JCng zCP(cTiTlk)AL|UzzzINO*0M9=zdaQH;-8pn7U;7*QZJhgr(k%%J%N>=Y12h6aLXQm zh>j#~E=*~EDF@0omw1O#_1d1)9)i_S0HWYPYW#sEf44xB1`-C#Mb(&ztau>slS$T$ zOMJQgF|cRwHQ*@61=~o6=uautvqcKQM;opVTxGfPv=H zfjS+kf0*WN5DY*|j`~p72g`#Ia?JJqLd|v!H)v^90#GHoCJY>miszALZiE8sreCm} zU_qPqz_!51{toDr{T^M#N(Sw$+Z&lv*yH>GvS?LUXuG2d)9usW6x@ zk`gPqYT3QaUaMJ@txjQh?I@&c{5JiA+1Ox|`FbnZ}UI_d3s7F`AMFGMR ze+=%YjgHbp8$W>R2*!q{3CapkISN=U0IXqQU0ADVqS;tLS^m_4F?7KID?lt^0l(~` z-3Ih6v_Y0=*M>JRRYu0h{gYOZ3*8BZ25|pqgeuyLmJ}ul3}m`!4Nz1=L41Kl4+_)j zbpfUZs2&oj(#~)IikCmD53bz{Y?y1xf1DVYXszihgJAWBOC<@j^>FhZc!upRVE=ZS zmq3FoHj{c5%A(NB(QelV_y_+aUKWf_HHGqR=oA_T4BlOsUqBx;qJ634=XqoMk^cSbUk2VBwy#rUTM^{0Pf66am zQrWiQjR2noXuTqe81~c@xO(C$TI^y4kn*Phu5RLVKvugToOI1WAbzoHg@^}b1_ z`(7Y^G3`}=2+nq_j^0mkIub&4NqjGEv74`a)Hm49u>N*f;QN6uSUIQ~A%YgoCZ1Sm zlKnp$L=JAQ10U!Xu*;!4f)VVGe*!K|D&CR_58eqFp}pQN7~%1SA({Pq&^0;$KoAO0 z)6{|xydHRD%w#(PKDfgWeCpIc89ZA^3WR0~im`gbx3*($AgMp2Nh7~!TVSXD*mF=@ zsN$)|BYzX`k-lzZjDp9WZ`jrbs%t#;sNfno#>h?v zJ{ScK9AMU$0}!*05+$hz_fC&q)7ycP)FJKBudUnzKEeWiRTyUie^v@nI_Wp8zc8}2 zP|+RGrB(tW;b!(WsYx=*GSSd+M3>se%956Q>d6veq=dVV1EifJ?dU;yj$#LBh(niJ zQ*4p4vpIC*kf6ds`&E$L*|1hEAh0a3ox($1(q;y&3I-(AupGKbwbzKweOYAKU!NNU z3~u$Do>S|h9H96~e`^Wy>LJ+2LcyaYY%2@Ix^3{F6%w94wCFfj%@LqUYH!oR3#1Sh z9qsa6y3}^~-oWsEG=H^l`31(%4uSpajT+$shO(% zms+U$BRc2#Z*8M$kI+WdBsFs=4v^PQe?URLPi;aK&FGoUQgeQrpn^-=iSp24u}13dqQ$Ld_VG?v`* zoGjW~f1a@gL}&$csZSIDmNYv|ywI-PZcv&@(oY~`mjN1E1)D_JKzK8N>50w-Y_Ekm zu}hY?sD@o0nUvX$ih|BTEk}kpF*;hVrK03FHx+;xYeA zBK=+x$wCRPgBCw%faZd!CHw%F0Lm;|njo5%e>B2`RSCKc`(I?k|JVnCNMKmjUul5} zlN&X@4tcvUO?m8lB+VnijG4>@Z0lR$Y5nWqNqFyH08W6WOWZu1{sbyoArA#?znwe; z0UPuWj(I)yZO`x$V0A$$*2rOSqa(p59N!!n!x8vT0pW}7D#wp;m$H(8+zz>c@(Ofy zf1ZtB<6m9L!h(|2Gt5Kug#xPSn@DY>sAN8$H?dK(lxHQnf6el3hoYBB_A!GP%V!X` z^?&*-fmmRD7jC<&bcg@LdINj-KYE{?WkpP3c)|}wmQ-cb2d9czd{xw}onhK%@v`5J z7XghEZrs4vYdq^i1i*5DzQ_j(<=~u? zW#n74sK0+1&2{ZEj|%V-8nRPS&Eaf3WO4B{tI`sR9oA*lS;i5gfI`K%Tfg?FH8~$kGT=r0inVE1We7Nf%jo!Hn&r_;OfOcey(VuB z!qqC%HjChw^;ivA1P*a)hoNB^f699~vh@&zHPCL~Zi;M14jgDjXJR?JKEXvtz;8rY(OB|HZIxzbi0F!sg&7jHPZxWr#dUwx*VkKzvJA3ubeWjUL|_qNtMVH}a*DemGv&q^ z1@OF<@XL*<46~W)tlaj8-0_8ID~7LH>nuC#BtbDA+pcC`e-p#)V^x-QbZH3J0+T8G zaD9+3T+-iCsfZ7hW;lRY6$G(cv+VTdgV$<;3|O0A*PJcLrba!v*54G|sH+4DJX)?+ zISi75CqMorVQaGG&BNAY=l_kq^1Gt1WMBS$qOW8pt>`N_KUOO-^s80&K;C>&qpyhM zn?zp`6Z=0QfBK5(Dn(z(UUj0y4|zQMNWlQJlp>_EoM$I$j0Eze-VsVcEilv~Nzc6w z^N$gr;zE^fgjCL&RcdOg=}f-ag#oh#yOiWcH+JlF=YQUyLKz%3V|_r11B}toANL`; z_24v0t1h8MQb$+Zw!ArkC}UwdU1a%#WE?XLlYKYKf08InwOFqsVi()xmd`|(Spt14 zlwmw$GW2&xgQmNpmSx56raq7#^&eol9i4fw4XEmys;_QRJx#7Yh5NiV#@kH-yRqVQ z?6A|>*y(8P8M{O>VN9V3JItrD50bVoaiOkn6pyv8G`Ot zoR+ntO5(h%s~fcSdV`mR>-{EFJcirrh+Iwm_=^3w*S&9LvvZ=Ofi6iXSU3hi&uI^a zS*4`Lo2d^{pju`q(mV~nz60i#WhCPQ)XfUI$KqKfgkM+yo5Issl(PAC3`}?*rZ4Ue zf75zX$e65f9Cl3MI}m~rLe)pF&(AWHAf9((#2pcY*BE|!-m#Xl*EKfYq>swUR_3RK zlk146FY@?Q#v>k=9i>01LwFY33}W_qdzUGiX!TG*ADPRWd{{Lf%1vWdM{hk7?PLOq zv+>?uyk_}oB~eqq9ilTk{A+lf``^Ipe?0pyuk-tOofrQ`yw1xuuXCSxooAB8c_?pQ zw0NCQt*^?}3MVM>DMMXnf~T41QFIY$U4qRxDzu1Q=HZvI*!kMu0MDSSRX)5qdv*Aq z!(JT<_Nsx?FEUab&pv5K{r73FHy1(6dUuiBe-WO8aQ)ZV}e-THmnuLbzM?3a#MmeE>@tnc!4s6l^pmc98F&he$n zIqsR;eB-XI^1AqLGD7st!$X_i?+XtdpUdFxJ7UM*q>$_tyCe{eOC|v{-UfN7?G16c zb?w*p1nm$rLDW()V$Oi*dUihUf8WWY-g#E_ib~vk2~&aNFgJv8>rq=KeYQm#)f9W5 z)g;b1Wt)W6xKFeY=EA$~-k5|ului95jiPaZjaVYkP zY<7O)X`bw$%(SP^$-?z8F`#0L#e{ApVw`gyFB)9ap^5$J@e{X+#^NsfL zf6hkxSe0Y`wiO`+%XP^x^`Wd)EY5p*@adz zH0sbNT4}WGI*fUiKL}M@1-VTE0A)a$zaVN00Kjw6*D^|rP36C8)RfI4o%8;iXLsJb ze*FC9;ja(w_w~yd4Rg+oAEr8N$$vSm%l>y@N))Gk*^f2oKtX{@IA@1#96G3aH}X_ZGaWSiJg%u1FY>+Et7rn4lHc2`*PI9;ol|JT0; z^Z)z}nEwaT|I4uBIwB~jxZu%Ic&ueQt9U^OPoT9ah^ePFj0;4MlTxenv44z{n@2^K zEF-NFhC?}v)n)xtS4410N@0{$C7^3<7!!TziSnD71qBPVUdR4rsj9exsKTYh0z|jahX*$acm?!kmWEG;^aXiei`y3j}<`54(q)qhN+d_ENXZZ7573Jr>hfz6QkmNzT70<@K!~1)>lv|N_L4)L5@vKhn^-fM;nK$CB zUe7R$ZMm0t(SIc*lNr_<1w6~jhj8iuSFT!)AZIteTX)F7++8xT1}eceRHW5$kEAiX zKr&O`ZUaX2LM`J}HJwI9q4wp&7L*zpVGAh#By>94BZw4Gp#L+)fJ`Zgr{zB}P{EbL z$`J}HU070gb(Z<~7yzSGMBCgVvVw1(>zWSs7NyD>rhf`+2*S+YG~MXnazLQD)UuJ# zyM0KaVtg6T#?hM2k&qdC#$$N|f)zZb(*msGnWbf!miam}bwH!>T+8%bcAGEBu;Kv8 z%w3u8vr95+FT}xzDVuX`%Cn!ejo#zl&k8oJA?s<#f7JOB{Zi~P31PH)E2(QItOdyJ zXvi$aY=5xVc37opS_UUij2bGOpu#d;KRys!ktm%=YpvjtJ&w5+^27jg1c~{u3{@UE zmOL_8vNm%|m&t|EU>a(2zhi0j$E9SQh51ciXQ^O%e=BvZFVGTw3oNg)Z}wY@sz2VU zWplxFWN9si{y0?_?xJDD1tW1}Gg|=8lJL*9X@3JIrsS|ijw9x`#!R52*#vw8M~eU8qB;SgJZd3UFZKKC2tburD(B4P6|%}&p< zG=D@yE` zy@{ipZ}Od`Z7g^)+q@nzprz#vvfZbrUfVkH1|L49rL%2H*agviB>Ptyr{P(L#edz_ zEHBD>UyN{5iG(%kx~qb?q)Aq9A87wPh2wMMnC01*;zg9d2tP*STzz^jP8J{K#|&2E zI31Xv$6bUeuv;G$%{1b~aDz&kz(>5p%eGPWSspFrNpg^jTz``tvWV=cMORhNMfTUD_@Y7a*)?o*q20>nb2!@A zJ4{Q~yOqSJF+FTB)`ccBiZ57CM>A0K=@I|dPXxmwl9_ro%hiN!}~98R-S zeubP_2$|(uimT`uf-#nnPRZ>PH10k#Xx5l?unvPk)s@E|pxH>d48_ z@%T~^Ll@^NcG@#RH)TwdERFW}@lbS>e~e(}611R%;(>-$F!*q+0{6?tx#pPKbAN3nj{ zRbP1&gFHAoijODxQGa~Qiw7D!FnGaIeN2hxns{F8Oi>dT4`ko86!a`0sX&bxR>M=} zVYMp0u#Oh+j*9eCCdq~_2gK)F z+HMm63Pr{|&Wo}qdHi0n$f{%pD#I}CVRg09Ko8W{vudhnnSUc?A|cpPJX(9X*4Nn8 z;uS9*pf8u=GcR5#tK@5I!>tQc=B0)jtMwYce$9)oRN_-!yp|jA$EbWEF~jq@m@PWh z_na3`>5DtOMgx@NxX+3w{Gq6`K`yMgw}o(6amb4&HQHgteO}xH6Rzi9QhEHJ70-Ba zNEk`Bq3P)hp?`VYi^y&_x~E0@9xv|bay?5AEYAU-2?aNxDw$y@bdtq=s-t9mMVHvu z0ShPz5+!b9wse0#RgKNS0$;Q{)j2Po5wKtK;)T+IPpFrUL2w3p#mNb%+%chuFCspq zj~?>klk(9ot?`Wr^G18%cBb6pC4F<37r!XqyrFLz3x5x3^>L661_wHbHt%X++W~s4 zvess%a()g>D)uoi-q6tB63eOCKZ-M;>6A(@n$4!wNtW{Bu~s%-U-q>0`=O4yTwd0C zr%6eAnQ?JT4o=EUoec&xgculZV#6Ns;zFtV-A$|RrQZ*0(;w)+c}xZV$cuMMfp1l$ z{a9-k8h`13mjL>W7jKo%epNjvwLi+CC8^Sq{QKcVyM4RqTq-2Is5{li=}`{N<0Z}z zs_tiA{Hj#RqOF-@W{*Ytzix6AL-1G(G425~@5h)NA@hQVT3 zU$2WFl(EK-dGV07Qb{Vzi%0F`k5S2sAKPh*uz%piZ|$@K^8HLW<|khKpmfaKS}0(e zQ~b2OScbeXl@G1m6QLCCZAhJ7Q(7s8fC{yFVJU?=%4BGjiezvkrliLUNBPLz`OzXQ z>W>0mxU|4V4Q{@M)X9;r^WM+@WEqyEXsG|QvGr{bhogn2YOIq4tc zKvyBJV#=Gbs^D6c@$ZiQVI1GS^_>Aqf2|7l_p1;ImHNgwd~ovO<@49iSF3(s*C&0V zBDEr)>L;erzg=bHzS_A;C6X&Bs6eMP)PLS7uPSOo(y@2dJCstMw0R+esfbM2q_smL zDQKZOF7?Z`@;`h9B4j8}7N%YuJ*^#1)nZW({OJ<;@|_s5s()$w;9 zS#`$0`^S4ZkjCxFy=H@Ye|+mZR(AQ9ztD3ISjlWH_34j0oy{4~v^DKuBP{OhP z-AC5HWg35*^!3~QTYY7#uf8Y)D5mIYRZU^0?(b_=4&+>QKCaGmvdF1$5)(*Ic=bgo z>cN)bIiN_f2LS$~uU_%$f%4U76@QagugIWDj`)d|>XTHc_UZGly!uSz_?lN=HCP5@ zlte^S^^{ky>HTwfPea4{#DvOBcX;(&X~UB(ELh!{RCnm?{`hjeg$=8Fyn3P(aJYdD z3G?jlE2k9dvX7$UEwnh`<-{BhnONudd38vAc*grDCrLI7i^a(TF10P<$$v?oRWG)= z&GrOQ+W2w@#zuc_cj~=VXK<#Q3L>Jq-%bW1qWaWM10tfj+fD-_qPj)P=Mk?I zqOf`=mk+HF)?P}NFa%>DE2>BAG(3Y_t$Mmz6+h{WOdG{pVw|cUd8JT@)mvq12*HbF z7aGIJ)vBLXryrtRJQTQZiH8s5yaJvk{gV^y)5%GHkMn3O7#Fc&{eQ+Qh03g2RA#h2 zDSy*SeUct^oH&+A<39Ahe>_e>QbCpc%qxYqtQ6X^`kB<%k$wdUwSg;s;*~ zDa9%DQ#It3LdjKD_ZJHBRN1^z$h697q3rq-mh%)_*vM62nnGTtEF{Xqd5+7dSuGx~ z6tb>z|IF3mZm*UfS$`{4u9lzL$+%jE?KE61b~_DMi$|*^;1!Xc)receq0&cxHv$40 zNacHrpJcbvR;E2zNx6W?_tj`%N**&;xg2E&yM3ER0Fw?j>P7Ou3bb6BX><-ES4zOa zn?}6yn~tIUtP7nB?gFOuCQGnxZ4`nJ8nRZZd*)!xd8;KJEB<9nc?3F@Q5g<=wL@I64_ROdV zufS1lzYnr07AZ9ES|c)Mn(?V(EIciw5KuvK9FF)*v&l3gkB^(a9owECr9a3nkB`)^ zicbsb*YxJw`+qcPi(YYMPN&iq6wHH*yIRh`dRVLX`E<1+50?6BHLaw~5L+?l(?ltL zCJ(*{OEA8d9;D!)6rBajK@DM0vsw^xaQk-neI~F)!ONrYm{mNVbOz+LG(vM~W2rP0pvMRM?VFKT=`m+g!}_3!k2EvMtjSNIVmd zhsA?>0K3#VBORcT3)|#$Qrps}Mz+N9fu$#HKIQ^gKL=w3khq za0dpdpZJExicKFjNhq<0v|l`;AhW4SKO=hB+Ne^uDGX zbllsU+DC{~j@MKBs11&~++#kqkEXxT&#(0JGyVKPKR?lrNk2pSv5w*J8r(gjgctPl zBmKOjpSSe$iGCi^&oA_Imww*R&tv+zMSnjR^z(>*-W|hXJX{_gpDL8-)V=x;4%tcI zhXJ1wr8gacf98>I1G@3~bY%RxzYkXByqD}Q)4 znSQ9po6!Q&;e-^NBvt5e>^1GyTDe*!sl?b*9S{FxfDu`onn{Jy8n4gy(euKqNfTrmWJTLSe)`ZHzZ?gp!yiM3yDt7H}14 zW{Tb4#>uz?ML(o$>&a3gVJxDysE+dl_#H-k6w3!`>P7>r#vCyYXbfO z9V-}lim*9pQBg?rwt0E9VSgh!IM;~~&JXl*^L)G*geN??qZEGchAbS5`4CR|9n12u zJsH(dY8jIJcw{raefyYadUNs_t3Bk&J*C?FHJy7z0`BA)Pwo>CI>fV`gmdzeH|7D# z+#&5t!IDorc{%Bznq}{fj>pNNmb}y=-b`NBu~{WA8m4QlugA$VLVr3Bd7`MoleQ{+ zy3it)JcOxPih;h%6GaW4yy=8}*+9I_KOgAPQG6TN8)a09aZVodgf!vFtt)}j0*9;^ zmvwZYC!mYQ7V9h$RtojxsXKkalUqtB9(8p3LhbZBo;*_W|JY_~OQjOrfG7Dlc??`_ ztuaa7^5jRQgx}P42!H-jl2evE6nTH;$!|*DpSSXUWyyue`vXsYCZPS)C`BZpDwH0H z$&;Tb)3C`TyfDZ-7Ej1@Be9!2aL!x2cX(pcd#`yfC}^3-<%vgmf=%i^8FdiyiQiJ6 zLUWG$Y#wb=^7FEbXrHH@r1?DO)l5rFoy}votDfp?9%7oMvwwMpcaF~H1>U)^T6lEt zKugU1{duKS>*?daCd7Bv`Ey3)2#-cA5dX6MwZzoTgL< zN&w2hZPHvwL&kAlbsavqNBcs_c`}-`=n;ADHRtK1nrW#H3fg$C<+?miEl#=3b9tg@ zp3srMMYyj2dh^c`}sEzFY~#2%tGLd6lI02 zt}13{;LvKzEdri$p4Y@oKTc=S*FM_678W}n-wjf{q5)m6_Y^E0pv1hJ}k0)I3`o7()8&lMVH{;?%@n9NV1 zRGfej z(J_*+C=Uh5>wDS96F&b!l|JCn$4T_DnIm#G&tLKRgUS2>o&0}3mm;{PaViZnernbsaoulRx?E6J@L)6b{p#^ z9@b@@G>P}SN_tV}1QJNBz_)zIZ{4v~vso@ztN%Qb9u z^MBtYFEs~^>_ODv6J82KR9wl8RdAC*Ae^+;s?2}pb45Qp|3MM5*6e=m2&y$9Rx4!S zCYS5+{AUfxPJtMH;`1K}0_MhgS85t=3)|*X6xYwm3UY4oIgw{`yDe0D8lJJa!{;_g zljgQQo?FxzkIx}q4a*6L-%(@5J4+uYcXR zd-i$hf!g|nG9yRYS9&>|MX+4k|=BY*v6$5-Gt zFvH?wR(~1GFR@u?d^)Kn$q(b?*Ksugq3dBfPEOeeo=E$)GnIdjwGXRR#M*Uy*x%Pc zc^z}`5jmY}8SAQ$W$W4D(JVaX@Keyw3H>~vpNf8_^z({-KGV-v`gu)1Pw8htKWFsw zfqqWu=Og_r>F1n&p3~1A`hR&sKlf0d0(S`|%<1P#t^1fg<1-Ro&0cUt2{L=BY!NeX z<34*qTifgtpS@HvKD@aYPD=WuP$(vicVko`XC77b3!gotrrqWJ2Vc*kX&KFWVNDw;caTL~De0FPpKb4kOELx*@LiDpGr=30GvkR*49h#sY zy+1y_y?TG7O~%?_@_&AITbqpE8}Dbg^@+aHj{5)WSl8g)WbeJDAN}L~`{UL7_lEwr ziT>Ww-yg5E3CAy1?~mRe>&@-zmJXKAvmg0)@84_h-|G{2ddp{zI-H~&)pAD%JfuMc z!!W;>&7wP{Hq>jKN58MLsJ6bIy<_S*GKN?|X0dx5w2gdbzd9lpM_6r6J^y?0n4cBF+c1Unl*+us;^y|AEg)HaPnU zs$?^B7t=i(@|iiAnYH2i7S}zquJuWYvm7@-nKA=u^32k2lVGaVnb~kM8%mZPBv;q< z?Wb1XY(7&A6Mtt;hiJUtAJ1&5)0laDreZZ!wM#NvYU~gC7@Ii(Q{&``Hv3JR!Tux2 z`B}hcr0AWE_?`+Mzd6G=8}0A!MN-hve;4K{fV9`YT^@9~lm$K_OF*weH^!GRhtq}V zAXYv9n9B1HIoN_>gBB5=`3I>Mc>YN2!zDM_B2{ttB7fh+;fr#$5GGZNm@jfAZ&<4} zv_-8drTFfvRk!HfJSe}f(V>+0m$z?A5Y+F$`m3ehO7&}Gh2p>;%R!hI9p%Ry4sF$% znFx-%c6xtmIwagBsH|U$71fm5Va+SHhz*0sBL-%`!nlqrp6?e$J@R7aH7si5SNL+x zYG8_E#eWEioDUE3@1-N(gZ%bwJ>?;Iv?xhp`5ZiY{+$n3D=n7lFlB#ino)@bTHC5c zVmEsk&7(X@r_viJMow6SMf$(W-iIgx#b;c`VGsF`{Xv5E z7N?5gqa5%YsnlU(_Zah8fMSvT{rr3Be)K?(fRa7RZ{I$yx58%9Oj7j({^FyQg4N5G z&woCVT}jSDK4h7wBm6$A&zT;Ca_tv9BkM|Ra3-CUu<*92BcA{Um5aGn>8n+H;(#?r z%;O`VqCaVseo%8vQz-Mcd3+#VFJ{_Q-`^JlI)%j|oD!@h+XS9aC($_8kDxin7@9sB zYf7Mcab72;3}f-jQ-vwWm>F40tN;>oar$OM_SGrVZi!Xd}ZoJ5|Wju@2z2rpoPl@3O>Teh44SzOS ztriqkN1b`%P??mp8i=0BDc`FHuTS3IdGhALtJ0Ry)2qeD&(h-KU4IUmreuw153&T)e72oW>=%b>8*;+dEGV@88+={abML81DZ5 z;o*ZP_X+qrVGl@y)He!@j5)aFQJ%?<{dU>c4iXkG9)3spIGo$1i-E$zH^=vyvR^*H z(x1P4x>am5MU-YdfBE$AM;!eIhIK|MW$)8CpWJ!<`oYr|ude{dvVk_N^?%kJ05@{@ zbPt_rMTYWp+g!J+dU)sX$(xrCgnv(w`0CBQdk{wOPgkoP!(TR8o_GJ%7f-j4*=c%Sh5h7ZIB_Usn736~@QRQtCXLaisr_`kU?U zvwpjktpsdSpY_`<=(GNI{e9M#we^p6w%{-Vo3)Ko)~;0+3J|keEneyDbVr`oG&@(T#b=#;+>z-OB7ZuaE!*#5Cpd2> z!3HT4D58ztaok`jgLQ+jOBL8O>E?RPj*f{_`l8eUu3~asTRdp6SQ{KnB8Y7$uzD$W z^qvW9zR~H8Wooh(>fJM2%XYZd*$MvwBBclX3%G56)oiF?l7Rm?)gP>S7`rRpigI3N zQ7;rae=UN8Oj2#}N`D_OK4`H%i7EVxN}{G(gyX+%ONxM+1-W?)CT8rYDg0PxpRa8) zF^ly_ahATCE~3+r<$RIgd2p@N$0^9$_V@F;>^tQ|eZYgkHe0)PH-#i4g+6JO#@_avKHU{(7vlr`N!{12{*ofr;9lC=;-5L9)CC@8lIF zb@f#2nysi{(UDd2b;W0@4e9%1cG>vk8ZVw~&eo`-J?u4m#XcYF>^WaN>*`d)IU<}+ z1Sz7k2ihfy7`MqzCP*DTW5}L@hqYZpSYz(}eeEU%nty9>{HN*Ki6r9S3}Nd_LC)9T zL~9&S{puYi+uz@VUMda3dd}oC+uT0)_n$X!0nQnFE;gP!H(H-~{(zu4kvHR}zLYXh zHz)FD{6S`z)OXu^*5w-J34AWLu1S42KCKHl-7cWs*e=&#+Y2So{x*>}k(CG?|MWxNK@>Dxy;I`E`OOmlu1hA1pp- znLf#A?S%R`)JTEbgBw`ZtwCp-1jy!?9$z{CH-9Jp-nFw|o9^#78TckSbqAyHwigLB zd&;(QGF&_!*&A+9MHfI+l^C*x+{@J#|P`p=F_X++3?fthKq56mY;67 zTqQYMO_%)icH5Otwi;hgir>}xkK3&mwEq5n^OA2)$yU3CbY#2PlzFSgyQeiQq9>c% zSARTj5i=-f?WS%dK3<$Q%MWd`chOOz zBo6nN5Xj|*o9J5C$J#g7fT21!Nw~BQ{L$+mcWw-w&noc$Y)BnN$KMF7&0d4<_udUT zp0b`i2kMmKHJ1;7MZ*5@8p1(HrqxpD!+-nj>924bSK|uM?rVylqj+5EljrqNbocw& zHLbjk9HS<`*lsfEA3!0ZPa>rewb->)vXBthCFdJ`NvSV+cPCz6J9xiq0aD*SZT79< zN_ri|lDPHCb=`CwWe4Qb zLL;lnD1ZF==@S+j8M*%l)49+%t&%c6OQM4uy=Jdg6^r?IM1HMu5Rr+%l9@iygr9Y^ zdeo*MGJO_416KyUOo1Hc=7JUhshfxZi;L-9;HxTa-CcaL@U_;&#Hjeh{@8v^RB zYmgLSnKmp{!M%#G#y7~;6+l3ugNtuLn45G_jW8d5ODQcq(so(zS^)0AO>N}_ct6*6 zi6?+lRUKL(U5t1nCEI`vZ|mY*&83J%TF*+Y7;z441cLlp)%I$7cFtdR_;`~Jx8$w`*Cx&BcllsMWVD6Az*}^ zKs!<2&IcBI#IQHpgGcZzKfDhQ#FUO-FwwU7GkhA2Z?UEu<9BQJ zTlWf@t1SFlXTSbmHnw*Vv;TY}fu;x@v%wcp2oOxHMR2v0Wp58(NbN1yktn=AeAS2) znwPKDuTMKNJdkyMP=8(m&0M#ksZ-gTf4EsU<)}9}T-|{`N&jT(RO!rlSItRH?%1bZ zig4FRNZe&Fk9GFbjpT)BF9f!@6AHF8hB#&F;G|%+bBV7~vGM11aHH`rEF;a~V-!M_ zGGu*3L|Vp$3=%b`VS(Dxn(FFHlBv&|aEqMtY!XWXj_>W|V}DJ3)Y=v)VB+`x=e5;a zrt32PGtcyKKM!YdM#U?o)M=-9X)2h zs8b|rOjn*pr&)*AaZ?gj(@bl2w4Dk?me&>8s};`0B#I_-5^wL8@{Qay$LO7~z!hKU zlR{hQ<6?aC?|;|qs9;gV>SeQNYz;~Af5I+X(m6#S-4c5>a_G%Pe7gDK)rQ=d(QZL= zQ9RUhlpawSI{sBW38nUrOx-XxcZ4>ozR8xbxrzLaEkfB5uG_(cRCx@i>f*dSA4d_Z z(meVY7iE-Fu0z&-zQ;a_W>OHbpX%qQQ5lYZt{)#q34c)E;~%cF66mlb5QYP4FrCF~ z1><}rj02XkB6b^6^;2Qui0(h~D4j)QlM$zBl)sGT2hDLNSOtftXK)xVUPg~`JasMX z2=iL5g)FiaRZ70wUB;z^A}?aR#@b^ByaPnGhoj z!~*C9Tz~2L)28Qi{8aP^i9s@Q#b-&u%7yb0I1l42EEg=Qqv0N?kwfq^wi#;&@%50U z$kL}rBCb@N9Ho=mV&>I( zI_;0^$NsSvv&-;9mX{C0JUIu0i78nYf|y5X$(?4*x+7P$U1LQMxaCGB>2R=GN~DB! zajGAnIDDfbuvede>X^grj<{7_AL^@BfoBo07vnzqt)9q38*6dEFgce2q{TsmxrzhZIQ)Eq)oNqPadpj3wZ>Wp}$A7D(Ya8i8MHp5E^ zt5l2^Rgyldy9^O5>$3=!1^EZ2ScF7D0F5ksA(tCrvljQZEY^V)!C+rI?H|C8aDr#g z);q(G2_mUA2M;BL;rNW=l6>R*j5y~E;D4c^06K;5nGD?50=n6XjRmI?Fv57GoD~53 zXEc`XA&b3Q^~=19ggerCm=t*5QEB5~1zZEhlUxQ{O96T2jqP?59aE&CHTPJU3g72l zXI#F-=`8yq?Wp%Srvzh`P4UFW?l)~@KEWO1NqC-BC26F_igrpdDty)~{FWtIgMVNa z_f^WPthG|nx>0&{(A$kEe8e{oy|A=)=F8}0M?^YAqYL~OA;DPLOJ~di|3!Cw&v426_+`zmKd@MIQk+K~O9vmP6&opN<2<&z&4<%2H z7LB9<8A~kCnn8^2GbIO5O|a{J;6gsSU~{0>rfc%6R0pdkTKEIIgqW1$vo)P%SR~5v z&UikB^_C_4Yf#Y>`3;+rq zr}IjXp%z^O*k)-w?d+ z$vu-?d2a8E;-%cDYA>4`lI9(IcoT$IU+WzwSpVnsLs&R6)Hls#WyvHL``F;sUUeAH4YZwgriTC?UEVt<39{g{%4 zj3LyepM7x0G0Etq6o1z>Z|i+~s#O@Gir43lrg#EOn>Hy3`m{FYuFbde3ARvH4Zi#9 zr}`8S<*8c$n!fsxj3&w5YUk<1t>Njgdu^uX;thCFJz9Xr+hcvr_Dr^CVg-b7UhJr5 zdv_EbU{UUw8pW6JjCY$CU(vuuR=Icx4$m+^>fVqvZ?Z|Rc7GP#)hK9)kZ7{hIL(&P zKh>;HJDc@%XVG2Ff`&BBiqj&>%YUk2ztj!ukm)Xd0TBR2&b~f_(y7BM8rIb<>PXWu z;g{f_>e<}}h&gJ&F@7noVUs!mjM z?kY-GfVj0JTJgYcv?La9a49r14+VMo5gf+>DX5^$P)s7ovyx| zjuCRC1b@0`0wGbFcwk~dQKEQYG%7M9me=giV-X`zKC^lWwcccBtl2`t^zy8uX8GZD>;2ugJKqX_)VM)XjsqKA@X6B#gE zrI_f~OA88K)6K|~W(?W&usLM3OUPea-pT681u9=cwy(iY~F$5uUf}y3e#Vv>sVp_wI&K4Iu)kdc80?GP_ zrZH%lf-rmSb3j=42`If}$0Q_&Iw{O>R5MmI6 zmw$?|Dm}iLj}{OLqmPytyt~K8inEYiK3WuU-ES(du1MuY5QH0wx>;1@+6vR>A2K7&Tgzy_gWvD`@Ev5=2&qGnbzc5k)C zTR7XC$6;EI=Z3hGCMB#Xc)Xa*#tD;+84Is&6FTLLs!d9oPNwakV{!t3I}mEadVdWf zk+~{u{aFQjjnPsGgIYLxrEn|$V*JXWLucG3WN6#NnsH5-Yshg#e0tr; z!57T{Dk^^(kPaw^Z764x>}F7IIcEB)p-MXyyN?_A{Xj0bns3dPd0_*;yoMjxlnVHT z0D`;)zpN8}MF;$-+n39$VT&w}4(uiWbmg z1?XW7^iYSWgbm<^*8u%i19Wo}=$1NVpM)Qxq*)XAc=du~Eb z)%jk6N#UbBtIqmtF}gbMA%7^s?t)_+bjuj>r{S5fL0|a#sRhUTnP zYykG6)k?aqQ(e<`Il*f=*Nlubn?>NA7J{{bfyJ|I7WI)ruI&%%bZu{l6mQG;9^9tu zild49==lTa*w^tXM6KESg4~(QZ|F%ldETLT=|!knIZH89xWC^jFMm|4e;S@?s`-Tx zrDYyR1=#tcwshm;O#S#(RJK1RA&UIA^`Qu~Cw;a?(#E3g2~si3LO!UDs>Y%^TCg#X z(-}rJ>2hdMf(6P^e7qJmF2&ym<^;kDk6{W(OO?jETFoOhQ>CSff_ZavjK%=qtn)12 z?S7D*#T?BQJKu$zhJUW}W!7o4LF~*#*qv>EH`a9i_kN$975uw@P_FlyX8cWmuftW1 zD03#gQ$~CIww!?dXW_FxddDrf@E~D+7kytVdP?&6+V9_1!83)G1a@SK$IaCW?Wf=u zO@L$t{o54uTZ!BYn(X>ieq#rN4Q#8qo0sL}fA?=)M(h6n9)D8-%0jJk^^g7!dtct? zrqLw)|9%RF$2)WW7&;I_Zx*HmV=CB>_ zlXsJ21Wn&vU0qdOhlnMhsCP9cH{5PjHwc5vRk%)6{jNIZH|Z=WaH;)Jc#q75#TuZS?Ly`!rxoKI|!q4@PvnTM67t1{rDcJu-JT!WEf%XMY0&g0xfd)He$A-d;TMjXN`f$bQBy+@ z-nJIN_Zn7VQ-UT#X&$aUjJ<^y2=j?JW3%NsY+~ZW!x-k6xXyck-+T|=86ibDqEctgorc6O%yj!=qgGtdBqc|Bz>##QvsK22;!MVk_#MO-vW`B2&L1bme+} zO+yMoy@H=rvW~CF^Y+zKm8{p^?20UJpFC7a8hfj{JdnPkGlk<&;)mxn25*9One&f% z_J4I0?az)M6*+%KqNTH`U5^Ex=dqG5-9QOrh5oU2eE=Y~K6@6$r%6&<#J$K=0$<-O z-QcQn05S>e+f^9T`pl)S-Pu6KOeIm6c%T7aH*)b!;pY|!=)&EXS$xYg!^T?BxF&C) z@NY1aQDr6(2^J$Pb$NFN%emcDp>FJZQhyPc!Hh%`hxr&?(|u(*?!(+GXA^{PgVP{9 z-|5-XO_X(zM0D!SJvviBrw1_Snq|lGi~VC-x@Wt))=TLs**`KYa}|t;3icrutf0Uu zEO&NPRu(H$q^J=;sD*nf^D zA{@#Y+%oigO-m=yC71(f(HSExqH~8j-=PKJyLVpl+d5*GGVk6UO?@{>l<3{26bF!d zJ?B?q^TeSC1tgDV7zWjy@2Ek~Xnd)`#3MO)B<3flfiUNWQOT5DmZA`YJ%x_T zatveJWBR3gJ*tPp5blEmp_vd$HqvOv!CoYqEniM#=%AB8PU8OMq<1QU=zpYKM7fj9 zg1hggb9)UPG^P2V`85$Gc^A=d#Zk%BV7rYa5}#4@2hlmijow+~Vy)O76rooH`M{ZQ zNn5d)5f)z|dgMg!BtGVKeGFz<*H9vWPm621==84}O93b1!nt>H=VWt|e5;+D-_=i& zZ%?v&3xOKmDD(mdxP&nc=zqi7o5Idnxy%r+1XqR+lAP@}MSCK!QCND3nkzmYI1c-Q ziZaouh87`=1`fbqUriK}VG*q*x**6pINwFS29c(9-L4a^3}KyZn(@wh3Gb*J>%7kO zCu8oi3NmE&PCR@9!-N5flBzYZZ_Fq)<=P`|x^x2ej1ekg_RQ|(z<&~iYb^v6?LrU^ zbHg0!e7A|-7)AewnpB#}FaSviYfrhd;xUKdk`>#KzuFKjY^PQh;|4V>m_e8$XW{-o ztsyWQJLws72aqV?6pbKe@8$Z@*)2*lrf!t3WBNLEr>AdXcS;Wr_k3W08@&;G_Zb{$ z9CaQDeKME{0F4dPhJQIQ31vxoCS6EJFLHR@&|t=_%mM=bU=llq&5?Twv|XWG8j>W8 zLCG5db)7ljJUV&?8lHZxen#dFQ(F$55N(kU{5-InnDZ&d2aeuoA*!hA_7u@AahZGy zBhfhK(X6;+o&koya4t?fnvIW^nnx;H(_DAD1Sq0q;LTljKYy;5Etwpb@Q?F+$-TMO zX!!qhOssLv`*3)uC5MM|1Lip!l1!8U)~Q+4|oZWo8X9= zMP$*h>1|N%B(=** zbgUsXLY3aN7~GrcMT1seE#^4Ogj_by`u-K2YaI1L4*h*`)WN6HL6=kgujo9JXqe{`4fFi}gLqKU%YTb_ zP0_2W^?wJ4;*Idkfrp6as478X39bm4$1~7zDarj3l3WH;IB-%pa9-kFE>@!w6{=B* z>a(jemDd4JavdsBp$@qDWae=`o^|$|L~iV^5_?AY32!gqT-z{kwxitcdXhO|ael7k zON@txfVZK6J3rrw9qIbVs>IjPrqrzE|M%+T5%daaWc zFiZS|iQX6`dQ{LX+wGF1I*CatjPwEUwp(9{!pQ1#QW79(appkB*b0$+DsX4|gkQU& z($a$PZEdgiFJDHcjB{NxuUAzUR&xgRXCx+PI(KKaOY^}dwCRvttb-5yKwD_&6rSBk zUVp-+`=!__IE-_=%LJ%@2koCbrIuSZup#$gby6GiA-8p<1pU4|8&d%h3iYA;zT?wm=d zXr2=zmZ6MDwDDd{!y}l6M>&-t&EYxB;eWYqpNly>&*v~V*M0Hw&65|;UxTP4iylg7 zsz9C)7ZAyi4=7IoAJ0h|YbK$2fGk}kTDkyRK%~D!ay}MZgu~A>kGLc(Zo@QoJaVcZ z1SVQS)?})4BG-4;!{`I(xF#4sm^uXr3k&H zZT>j&$K?UMDXtY}Ax-e624>Bz>7q7wJ#c?$=BAJmX3F`}n=aWsQV!?Tc*g);FL%^u z9nHIuxsFdlXN@;)3AFtx(_K4<+6;EyuX!5UM`38 zy(D$`Rk|d*<2Um_V<`~ywM>#=DGUaCw~!CPt4yl^6j5Mw1i!*ifGDn0;g>;V7?FQq zEOJ1NB1d2pwMr_*X~>ig>YO+ftq7L3`VqTaXbWTzd7A1Q`Jj@92GOg52mqW~OaLpB zF_*jhON;MNfm}Q|M@MV$;^GjV4 znjMHM_5&+Jb&-6*@TB}LpXL&PNb`S+k#P$^DJB(+H&)=PV@Ha}+bLHqOE3aHqoVTq zZ)r`rd@AAdZc*uTAQQF^B*ON=Uzf1u`}=K~rR5uZMx#P{R7gYfq<7~_FQxe^N5App ziSJHNcarJF)L$pw8GQp{5U1{@f=RIOvuGoY-5>$Nt4KQc(&e*t%A5{rD2#s*k}rmg zqq)IvzH)&vJm)9E^f z5y6YNM}}+>_!0}I)aC@U>#G^rX&f5T5ltedui!~U{`diP*korveB04t)4yA-Q%N_A z9v+sjh4O)+JH@4!aK)MOA{2jS2`>elyFd zx&+ht$2<*kFc<{Xl6Q-*9$3{O>r&{a)?r9i1rwAbxe0DW_-#<`Z>)dpX)JHWfV><) zuBaPwITbJ~zF?3S2rUF1F74R-K1zn%Bl$(pz=6YrvU*AGA~FFtm0z0(%}BTh!y-}% zru+y%dEgX)dw9rqy_~osVtfBvxE3Vo$$Q?Me)68vdfy~Kn9RI621!nldc%w4Vhby7 zFjIh>!?*XkG_lP29S48OSim4#>42e!f`>$qh)E!AFO1VF?>^}TOlB+FjAgIx$7%`| zEN?tku)0I5DdiSR6&w6imy#eLc3!^RW~u6;Xr4smdNA?@?lZpMNKoC|)y+$s z+~V4+_;jSfEOF4$t7o%=_Tk+12#SV)lF2V8@eI&)qv%B8*-c0$b4f~mjmz=^j55xT zqGbi@!N1GpnZ;!*i?NOF+z>s`7(~P-dUxX!80$je40QcKX&w~7KxkdrgKu&zv2YH1 zOI-UgRl7`?hHHO+CUoOaxhxHt&e57OmM?KrFPVEZk=4I)Rx1#!mZAK|f4FH1LUcM~ znerd+?`rM=#5Q~%(`4-zP~NGWuvpm`FffNho} z(?DzKYmv+ZiS#JhZnY`L@;Dz;0^q}d0b-v305N>%I~=N}qHjXnl~(&Em{Xh|Cd4Z` zf$xNmk_|6oS7sH;B)?Xwr0b-PK&j-eBFs8srBbAdDx(+L2Co5qQW-e!Ji9BLll=N{ zoe@AvcolyqLjvfzPW2R}*DTtTYsTP{GR#yiMda;|m+1lrIgV$nVD<|%Eh5^ZorKTD0|-*HYbM386|Czw0X zKMI_bqkI%e?%vsy;-50vDsUulFU;zyyD&YljtYMd{k-a8R3KEXYa-7q%pl8)@TrUh)z-wzQ(3bKrnj3blSU>O^yczf?Fi zpb~#J;(~)Rj{~aE7A86I0bC+pi%{pg;*iYX*kGz+tPSy2ZiJ7w;4DQpHPd&c@^dsy(klHi8XYB{;Z+@(_IyP|I}DT3tUX5Tc+ zwY1sl*368=fAeY0PuS~NCFv;UN(v;+a8iFH^|_-;G!aW;q3Rq)0Pi#0u=O69;|%}W zO}P}iE5rD!JfAhrY$-KgKZwoBvoy!xKbCy}1*cqhhJhzWcaZL0a$N)l6E*sgko>-4 z#DEu86gA5Aqg^>1Fe|S>F~yUKYf#97zVo<#RXTjczK$80n}0)1OI+riu00ZY@X~*V zYvDz4c;?Mer#tZeSX1Ra6n?LGGa97c{1PsJfXIU)sp%_?~loIlKbJMUOL)B2k{JS2UcQw^e?T8ZUpmjw3(!3V#2|GVFpcw>P9c^`xQjX>ZzT}RF zYK718{K-5omot}`SxHo1!;+WgA?5RcJt*ct#yhku(&rN`29?)+lryFVzaM{)j^it5 zN<^ZVO}qL{gwDaz{+ zQ}idz5Xz4EVRfw}4KpJpvU3Mk+S(h=?hy0|9AplYA(Pl)UV;O`4>4T=5qkyg$Y^`|n$1R%aS`s7>yFu8>xED|iJ>?)LF;kqf+ zvm9e(nYajyeo(@>7QNlQI~V2#pp#kWCW=J?80)%Rcm!5wKV9zA zL+S}8)XkjeF=N%SRIZODy6%pmAI2J((t-6ZV><#OR|?uE=-4$M;vIh_oR3tr4gpOY zFHy(kPDgjfPH75oiHiz8Vg*5%f@|(DqC4e3R>}(?I4al5>9?J{g8pNQ3g0`?TS*V$ zSIM~_oD<(?(XT~uC;DFU(1+!J0!0VTc1ZR7QmN+;aaZ+6t}I@;wi4>oT*poL$`@Ba z`>u_0DzWM(m}~!u0|tN6?)|q0{_wY!e&?RYi0s@HR=RFwIniDI*1RgKCEd_vdhK7Y?x!;|8|E+1-$Zdao9B)r%+tI;4PVW5Y z;WsDWp4>fYoZNFxhA031?)~OuoBhvtJ33jL=6$nqvVPcm{P<-3cwoZIM*LIb~5}b!-5JQ znXHcfT(8?O4 z{=l7-Q^d2?%(f=~r&04q{KJss&rU(+Fh+^n21S;mfpopF-;juCvqD5S1rgo6ArUQ{ zC43?cT_&No+r2)YxHu#CuUhyC8d7O!cHuf2Op|}CAx84K5#`LPs3DwpL~Ql<0XQvX zc{unV6~f$%{V<8hEWf(nPw)z{1GPf^iN8iw@X4RNg(`AR?2vy~T! z{;a&5*y?nPZMc-!tprR}13c`w|H>wEFf`d*-46!}j6 zzyg0`9Vv2|Cj6>Nfk`&lqZxe!hIQO?6&4kpi`mqH#l9Uosiefn2j+o(A!}VNN^Q3| zADEmE58bhd0oo~Uco-Sl|3PTA?Y6-*DiZ3(Q)WS%p>q~sv}OiAmZw+@Jo=s6=BV76 zOTl^73=ytGvvtg?UB~+>{g!Ds!Iqemo+$asH!%FYa(yOx&%)Z_^g&gCyE^P+Em}e#KLzbhP0!fGd;_l)v$K* z*DD%BR6k@6x1K`&V<@igYmp%_P_v+WZXC;Jhg>Hti}0Pp*G9bFu!C(VN3$10qJ)Cs6ovoj3{)4-X=6 z2U{E^%Rl=lx%v!Q?mI(vn%_B1Zgzi$)E*wfd6Vdac>lbPKrL7Gq;4L#W2k&G`1@xr zNEp+rR-~pQ!mAYEi=`pnD)?M<)+AKVglj2QLcCRMgTy>z3GQEt72q%X$p_($N;)no zn1zA8;U!N*#X4#UtU;-FNBzDI*O^<;l?>OxOm-kXQl}ISRCVr$aCxa>4)A~M4OOdn z;mx06!{>GgaFMGQrrc#bzuod`biLdy(Oak$L)Hel>2UR|*u7DI5%`zf7aLcwL-#~% zNV?+2pb&XCkZ!cfy4S_52;yXz+Rxl{Iih3c2PkUGc)Ba$Y4pL+0siS^wrOYE(cP2A z_++-}X1X@C8$(ELmY)<;_?m*-}3Fc|=Z(F}zwNFQ@&kZ#8U2uPFqXfUA=Z zjJ~w2Bz8s?X_F4=k{+>4Vp$MTmsv78QOBScbc*)^!c+%BUzz6~J6vvW81*BgK`3G@QnC&8!(7|JH}qq%|uEL<}$hR52lcmzd2 zI16({WjyrTyHf_xe%b zR0f9UUImMN2Ejt*;}PlA3c(VT36_WvERtTtPXFACoAvKT6wPk` z{#n<*Y?2yJp8s63@=9^QZR$cYAILM7Bak@gFGsbofMJ_#`BP`}&J$s|UPIui(h z?17`5{-8O~$;5wU$(~LoA&W)SZ0Tf@u;frDlQl#!YIj?ZJY~sic}JojU}rQIi#!?w zY91FkJdHv~c@{vPS-C?zvJ}E~kIeDW|HSzT>FV1p59;pfcLL6;=ukNyFLa;%=;~=;-Vtoo7I&!aQC*Mz@et3Tv77ABGPYapT2v@hGbNsA= z1{OGF40V=AU^E{i;@duE}JlY}d(Vca9< zI~KMT4gWcD;&CTxIfddCbcU`UI8MXL-Kjg^wioqYigssGI02^f!MoDH-$3r;vM{Ed zEdSb`?k0ax=?r2`-TD-o$ct8TB*P8=bA%y(Om#_3u}T~2ynicaGSfz5oqMyIEcTsi zv~sX<*_b%mSU>ig@xB93UXPduy2*;CK?DNHewfR1W{+kIdcA$`J|T0BJ3r8&rw+OX z7vuw1nNRf%MKN=>@3_T}IuWrSlcgImJ+%5Gb`pOvP0bn&;KB?DwTW1GW_FHpX>yI> z6nLrBD{i53-S>S*u27UZV)j(h0uh%B)xlJVX_|4LxVms~#SGVkt6UN~(pm{02r`(( zJ76XkkN^(CM{P2)b|%Z*2P5h|CFGs3#sC>!YRIpk#*yh{3QqR~>h%>C<(|10@xTej z%t3!F91|aBWzHSgk;sWh{`hFke28fbiJ=cce98>8)w=8BR81TeMz4B-Hh1QQzZ0fr zQn)9|9c>9u8lcoRoa5Aq@Y5@YVa|y_m=kVeaFjcXs(gy{&D5E0w?3ey_z0Ttf;G)@ zf?HcU<+(XLTn%A(_M8!6@C+{gzFSZh4MhwGn!8BT) z4$$>WjZ#mXkfi9V!*L1UWL4v$X>R7T>(X$$P3o+xV%dA)!Fszrm_*uC2WLR>$Q*xf zx9IUFH`mS3JL8m_w#mCg=uZah)MeYX!E6b{&H>Ht;aNa}_8S;G8YRu2uP8p+4b4Ag&ew+BqN%9d9o7CN>3Wa8s0rUZQhuoFmH5=bnc zLp5g;WRlLaoxY}$C3>lIA{7H>v2Nr(YhvP!i@1>@c8%O&R+)?R$5DPfxI+v|>DjI< z)Q#RA9(vUT7QWIG{cvSxR6ECP%FjA*W?CFNkK=Il8qRBC_9!8#~G zV>&*fqjc=3{8k2FF&GA=!;K?SID0ELYuv<8Dw|`EA>ZV?7Gk_#vK?9Ns6?~;pfB+n z70ZgUw}U_&v5XZKugpkarhaCX;}adx@C)Mdjd%(U6VSwCl#X?Anj_ZGMwFyu-T4lK zaWsIV2Bx?QywwD;^j^O5f!Kcp69~6a%@0I;qAlyhO$19RQ(SSOxyX9CL2=%D2O+#EeGeS-`$j}M(It?ROjvoMKp|m3to61>s!_4V!nT@lJ(@xt~;y3vEq(z zj5=O;hsg~}a34O^2xFJ)NVxY2m`{E5 zEmS*Jm?BwgbMbGbwJ8M!O}E=<0ry?){qSWb)dPDIF1*+Y7wZ;~1H_(+htC7I2%y4m!_XdFg|7nuY;{p(Y+T zFn%Zkdb>_8Z1oNgb2hCK{aRbTA)8WLEQ%&~QqD||?a3n|T8Dt5wf&XCf$wX}Hy+3C zVkN>oke$A~A{)>$a2v3VyqRjNlh~UrXoCd~4?^xf9d=%}Q+#IpPBz>#HH~3&CXqV@ zF}#1(-IE(!Z$rk5#I~AbHM4uW8J91i)>RY+aA+?7MIa6&OtmV^^YNJ(sH@NMC68q8 z7Ex6XOfp~l{;%FFUBU}Q(*A+^5shI1fv`{P>hPiJ#u76%KuE8Gqna-~6x45)RGs-i z9^lNg*q5loxeWao#7jhTHv8T^_49_dj{ScxII_=M`JdIe!rAS~%i_Y(4| z#W_{`l~3q1_E{0%l{`afdQG)FmmUOI=TivhotfQedh0uL`x(FK)J(%*?m-X<7Da>2 zNF|X^#Bn*bI{K1=@)wzlQa5&{;B&w(JQXK3IAn`GH%PHL1jCt1rlB9kwi?CW%8h?7 z#n>3~mas%hz)!rb`fj`cOsLyjrtFy zG+pe1uz1h*A$M<4kJR_?%(i(`tZZ4tU)Y1)>~Y8Vy}sGRhni9^^{K5snt7?h5SmI{ zoK3r0z`f5pD&RW(NR~03+v+_w*~x!BHK(WyZ>DENJ%;-TA5Za}+J4>FvB_&@10oJ; z2G{Zd97~5SsUGyU`Wm98^1&eZqKl1Oti$PAA=m^h=iDDMlb)7XOeTpkNz570R6h#- znH~jq@9MFL(^GgWDVll1Ipw`}Z&Kc8B7g_M$Q{fPAT*qydXX0DWbJUr{ak;5GXbN?{a*1BDd0<-4c31i~P;;k1FiI;C7*^3jA1aL=^98CCd%nQYZ4i*(sH4;cl zEg>{Dd8WBI!jL3Hg@6Mpkp+m!ZYJafF;~b{B+wwF7{h%bvlj$3>S+zRY>-j4LL!J+ zHzEK!4c03fGp}(b+tG`4{(gTRdntd;bQ`a)0wS;2QwBsu+$Z5Y5q@oT9S9$Qxf8b6 zm#azWA0E;XdosL~#%>zM2@o^P=P&}eiY(e0f(!#zDb~=*jZ;7)ZKr-L}(0|aK>>w zgU$7JE1p2-jOT=FXU@ULnGh|y@`@c}2$2el|0G~6Ja@ngx}P)3`eT^ zn8i3b37$YO>_z#XPhdU`V2^dM+ z(wXATHS5rW3vPe5^}UgmpPBHSku<(cY(R1m{Nyy0>udm@*@=dM9OLlZPBcp=?6aL{ zO&~LN_mDugn!B^t9jRY(yhNS2N9D7qdNvl|xaK$V5@K6xF1s$>6<~f(1J*Wr+Vo@U z&Mp-&Az6bg0DL)OAfE6D?`zP;#3C`;Q#21jE zn7YkE`hWpIaZJR-9a&>>Hstrz$+-uZKXy#w;obCzHA_5pW{hydXXF6NIr*9!jrQ$OIe#^ z!smhMm5V~7Cf0w=3}r4v3_x5&LU99_=o{A=bxD5$I`w9Lf(MT0n9!RJ!T^V6x7e`x zqMG9&Bnur#w!mg42Sc8G$o&LQo@*oZBv6zUztU9RMj)tSbh>uOo7u{fhX+KtgFLKV z`uqfv4s>M$6)4JDE(rzicryqHhviuLJg=e{hM`oNd%d1cX_6Fq6ov6Ha*CpOv*Ili zk6C}E-sfTZ7;NZpv&-eVXuMJmf3lN6E!1QtA8K$C%?M>U_puY08qB0lCco8-LT8^U zP*ju14OI3`<+B0;g-briAfK(4Nk5X!UdB&H&;A*iJa8&J1qF?orSbNKuIYw1gHRPF zxo{{Oic4=6`6qVbGcA7{aPh&!r-{AsW)Pqbd=SS5NHT~EQL;mK z1`(A*CuX6*N#aZ%YGJ5N9+OQ>=QN!ze_m5iwX;W?Kh`w9w8H_}sTWimEi@nTz?@?r zJO2u&4bR(fZ>EQ2gMG2XjFAg#GIg}IGkGDgPi%tl427_aWS&FDE2f^1XPxOAj;()Z z3^(LRnU|RH{f{;*CTSAV8tY`#CW)qLA?TtT`FI^1FOwPBlP7Q)8tWMeb$xuqaXfEq z&Dk5kt(xo14D^Bm2Z@`4y-Tj2=oJg|4lIQ|(+|a?~O%J|Rsp z&7d=$&jOKhw0I8i)r~P@YKZUk9?cV-U(%PRkqtwf(d_eFe4g)4A(wmD`=;lVY;xhr zl(5?Ed8XG+%$`a@mxI1Ic_qL3Sw<#rxu8u|QOKsM`y^~2%`6Mk%#2Kas6~HrqSt># z@!E5GUI?UaDGDo#z9w%A*;iU4`#Q$*S4h9^d>!f6$6H9hzW?8le*OBjrC;CQMEdpp zt)yQ+{clOXe)(Ja^=Ze*G=|`dj*SL+O`UNWXrpO1~JPo=d-&>`G3o z$h@X<{%b^Cay6eL>QWRhn1(AaSiA{OX>bEcmU*QltBH~<6D3)#J(4U`*(f#pC#s7 z4MT}~FQDhDzAHkRw3#qT-&18xO}00?M`vDITit_CsjjZ3gkD`!d91Xif+?>6=Dgzs zTD#vi!PQZpxjF*ZNdqU)n(e*?&pmLG)NS?$lI&nbzlywOmEM0`Ub8COC~&i)!^5lC z{!|d6OE-DKS=jOL;Gi}g9KMyDmZnnU@!z6{PZB+>yuXggo7xS-N%{SHweVw9jQPKqejTnM7a4`62%npasE>I($ zM4B97xkvLkou+^C5xN4eUz48kt_Rz|pISr zUR{z<=G?&!vW%?OyAxU!k^uvjTbdLiG32A9H<Xk!{|i?LtL0a|LRigiaD`CL zblnxgD*F34{j}qB@)tTzSLNe$&W_VaoT3ZyFex3Ui<=*({{Nlh)R&Lbv%dwxe+z{F z76|_>5Was(AWT-5&Pbin$$9}HeS>+Z67}4T1C^*qWvXMcI(K&ODK(Q!IQ92Bz4U3K zYa3>pmDrn^mqfmMX{&ReUZ~{5I!V3xB`DaSVhyA=D1;(dx$(ja-h`2DbiReC(Wv}l ztOGC2h#xMV(lhE827+LyFA6mJAci8VcMf(1q?v!BBdc?LN646>>=wP?&;*UJ%Qo6F z??7BcPkNORo<;W z4Hth4kSiYx^$kg_7A0Eo9swj^5#A5ch3NxbbDx8Q>Dy|vrTYYu`$du}vsN#}k}el- zb3@IFb*j(C$!y$r#cbX=>TJzyHK9J8rVU&?HTTwmFC{BkmJgn|!R^yu%P)k*eic?^kTb48m^~HI%Aa`9`ZoWn#zY7ac% z)D!^s`sb$#3SDr+z&uXY3ndKvOTA7@a5XJf3UMqrQm_MK7lmhJ7kr?x8v#$v@~M-U ziCSttp%|vrAAUmZ?o(zzoC__kGx>jZOCB>a!j*$nwEHHjM>UeH6(F-hn5A={f>cW4{DJMQ4dL+)ml674i67f-Po0t9OdV=BoQm2^qel1-Pl~`fUarfKX=)+y{A8lQi8Qwnfm z%)Mat1e|NtASv~GKb*L}it*f$j;PioV1AU2(XUJOdlf;uHF<8_n06KwG``+zvJWW*3M1d>cY|2r>%C`ll)~ zbCTnBTFl8Fgmm;kgxymNFiU#Qpn@KrI3G1 zA^(;_{w;;PS_=8(h9X98koVAY{cvG#&QWU8HqDGMKlR7d_w9{(X#0O|k~XGG&!4IG zCUR%M6}|En%ha}ZMUA5LlW7>(n|Tj4Fi_5T*nob zE67={pq}Llu27~#iQIpaa~+}pRC%mGNbVpQN1pi;C5R7kNoEQ-^fGTeH0w}xY~2_qWVA>mNP_L0I{2QXo?rV>!ivDN!A zRW8G|0)C9~;oJ>4UCttZ_`Y12&GiYwME9FiTQFY{`Ef?KPRA=e|-l=F1Oq;Zyyx zSj?-KV;;r-6fE6QeD|&%IPNGOlLM`Y85-!{ zIi`MixWj*CM7-7~$)ntUP@M7ss>2CkLvAhTN!-qZuOrlWdyP;7`XMu6KM3aQ3QnB+ zzOLcN#g`ISUc)Apn!Iy!zVE@mE8j=IIN$ex^L@oUeY~LrAc=s**~k3<*}VVv66=Q0 zx7{L8ZMU${@bgjA88`bYD9R7oO&KNp^x3A!Y>|I8IZgjECdo{pm6Izm`I=VAdyJ9+ zH~z|TC~++L0q5q~AI19XOz))|Uo`oeZrn4lUMoO?*B$HLq);bzKv!>zZiYdM2&UFVXt! zO>ljQ*7Xo^+csLCfPy}|MC-FRvvupavaTJudFv9*FOOo(Tkk;Y6Sm}S+i2aojoWWh z^YcqIug4U($1S&Qqj~E#zQ_@LTU2p-=)QjmM*D1}_ysVS^$7>*pFyzP{YeX>`B*LPftOphF9y z2_wck6|Jn9AS(I^oq}-L1PHW>k^L-5M8xbUC0UXsX*oD~=VWiX;;QT}T-ld3p;5<4 zbi>p(5DwjrNrE?xOG;Cll669#1ipV4@GDU}C7>CtPQw{(Boyz@8aW^ZL~Rr>;-TKV zET1!Fp$fEy_m)L_ELa`963@vUp2WjVX2+8dbz&S1xO6B$0pbr3lTn zf+=+D1M%h)4Ejjf?Pm(t1vDe0u}&sVV&qpdhlkQjQIrFkJ{<8Uh~-FD<&qPzB61ab zVfP>^s;8hoc{FnvkS6j~(duVymAj>3Fk`QNl$#)>u-90DSX`ZjcBOtom3_5KHR;@6 z^uk$cse!lbF%9-!e@+QV{eFJ|sUPa`hZ&jaWT9snM4VhTo!S*^SOA=C>TF&aPZmE$7}zaBm@@x^`)su26Yl)snYqwHyy3@3gTn4Fo(O7?ai=_`Ylr(N& zArV%Mt!|ApI3C8Dr`vHRohBYpPtcWtJOLef0swiidkChtfUf`-F}q-3-icq=;DNax zx+&PP%pnk-tYx8EW^|znJi$87Y6y!OT)-qQNouEl?_5IvRI*`{umjTpXrPi+SKHva z+7NykgVbsFPJ%o4h^l|;0u{it@VN}hZU^k7=1@`~PFn&PHieA>aHtG8BXt_CSZ$bHK+4SkYRqRL&4}2{_K5cq z5p!;MGnS8!o^bKYBZ@nP;h%@6LSy2G(^K@Y&Fq_2eJ#+dfI@#)DuGt+m+s`(35{Pf zTPQUM1FGgKehfW%by|FMNO@S>yq61F0(Cw-1a!Z=&5Kt7>eRrPen~1J1OVq`8J@Fq zulT?YKc71}O-NFJc?e)0lC{tYLS#HGzONzV@0$3$X1UI}Lyhy;jh==KG7~a$YQ~)m z;Q+J~I2~t2BhG)61c!(GxLi7`o)+W&I7*FmkSx7=P-*(YTgktS#FdmkG%c>a!ii|D^K8I!Ees6pu>; ziiebp9x(b~LA6b>WxTPpC0E~Tpz8ISvLMd7euT#>sO^6hM<&1gPjh4~kxkNhdlWc< z$g)VK3cx5b*S-#M6x2}0!tNq;;={u^@6TO0v}+EC;#^D_)sY=>mXp`Ac6_em zFuQA!WzL(F_faD6BU-y90QpRvm9~b(nX}C}?EM#GUG3<9wB(nbIKi$Zqo51A18fEwdGxlm}J7bycxIo9w$YrSq0?vnXTbnwgv494yuP`NZ`5cesb36{ulR9R#!jN7?v{xBz zDl^)_4x=5H8EtmnNw83&uNR)of=K(G8aWMif1QR>30EGTo20o703%g62gFJ88KX|P zHsWzOqrZslz3}qw?K-O_vyu{05PpUQL#}_5?GaHihw{vJhiTDA4KYqy?z9%`8Q2|& zQ|IuIl|7Iumg|TCT?t3;UdFY_!<-tmow}1X@C-c*xG^8+XBIxOtIfI+VEKc&Liz3wk`(?K1O?v{N|x2C9D? zVc~BbsoeOR@&2#hl;2Dp3(=AgKURc$2_UC2D2yp;&pTdCJbhVguD>l)`Q-8;sYI3M2E25?bY5<^O!WN0nGAP~ZaY$-Bt|HnlU!0^&)Kfu zZZVWsK}W`h!So$B5?KT{J6UBSB>~_1ExYN@`43VggnMU?M z=JUClk>8w!r@hpND%7H)6M=tZ^&wHo17|thkyE_dE5Ue7)_SJfbtMWE^r|@3hXqaY z8~B;bi7F|NZvRI1GzX2r!Ex|%U!b_BB1>S1TU&GdgG?xXvM{5Uu~ z)P7*JuJe`&DepKuK@cOC(W8@{CN#f?Se23;y?f>812_ zA7)3pHSDt@~O8H6Xy9rUAg@HQ_ ziSo_;VCMQ1-otN*^3B`HI!M>zbrl97*jw>x(6(wv?89V;)hQ$AVLW@yW1^`6SQGdx z@d4Pgm6Lvr-Ka=`3HpI@8I#db$+Pg|8+XE5Z>!{m{E|w~ztVrnsh9q687*m$h>3X? zeypUdl1jp|^qP^qNaU(z_{Y36Z_drXSK`a9gpfD#kun!zwrX_fN-^XU~;DxXv5zHR>%L9F8m_)V;O*Av9xng>kHKJ|X6O_Pv6a1f0f;BP zv{j?WI)MfVQUSB0W*~j8CQX<>vuZM<5v!?aOyf!;=jne5nn+YrnSI=BCo?W{C{^Aa zm|(C7es~%%CbjyBnGaP{r%QLIlF8chQ!l6{dqG0uQeRj)Op{yc%fRi@mRkn5W#YS< zNfh%xiDH@X*XV$!HX5W}X_9YTmQ2@i0%gE$oSI>z)lcezniF=7X_6=gUaE6%>FTFe ziNw?wsmp&&w8mfCeJRSS(2Ku8~MfB z3A91KJLu?SF~x8qi?x1)|_X+1-Ctf_kpCkn4oegCYyIwF~14*Y&@ESAk+9ZY!O%muJR5dm~9Js(;Pa~MUX?&TaI6u>5>Bg9pu)j%zUZgS0 zo8Vs{hkzTO!T)ZY;?D*AUAjKhG4pVyW*^*O0UezMN#kP}(8kN57eCAKvFKU`=@N zz~NsQgPe7`j=l7<0lN%p209IX!Z?lLeo>u^!Ov4@f5De$G0UfJL1)tty0KW&_|$_! z3tZxbkE^j*;a?c_B6g!C!q6fP!!rPgrHh}Lr^Jbif|RA3oKl}9UqEZiDZa4!meGGH z^kz=lp1J&oK{0>g zzyojjXz?X=r>79g8o!3VhrfTo9|<%*Bn_~?gp-)P^12y7!%v6*M)+H@6bpkl>Ds++>RToIQ95snOKEz$zmeMn2`U6ww$nE~8?Zqh-YY zvgM8Z1VZ-WYQ>-SYE(1e6+?Yf$y2M}HGqDGQio;3B zPXl;N=drt@=V1)!H(pOL{~GfrI2DPDKnSzw;_s5KC_b=sn1DtCW5>3WmFs)_*H2yl zls(7kB|bpklhF5O9!m)QH5_CDVji z6y`7MAf~RLzn-yaI-9U_@{Ic7l#TU_#vTKUGqxSh5Z2GUWbOJ5vGC_^9OadrvpsU| zox+q}&@hI&FIIko!R3EN_yOShLV)BY+Z>nd$oS|j)G?zi=FTG27E?_pi$p(K%#CCn z0j)!4xssr>@ENf&a~5+}Y6-p^+MSXwheh<&;}|a{`5pZt;z2iY#L8ouPM6Ge=`YPZ ztR}vnHH&DNpcEyZDSC4C&gkBVmy5|&5ib`jhHPaT@xsBR8;HplGdUWO3$P?ReynSU}c}sebs><~o(d7y%g3*h}4Q6x(l67yNV104Py5OMzKHZz`j5#Ac za<^N}b<{U6o;`n6nQ%Libnck4U3PSBaHiT7TfGF=Gd#;9-g{8h-O2b0GP3cZ!>pa| zE;&@_8F6cTMSp@uRp6Z2w5HqxauA~cqHkz}BEgK+Y0SL-D{(-teTnZr(c8T#H7 zZtH<#Xt=?w5zrKmh7A2JqhnllvCfw`Us>TVnR_`AfjfUuLkoAKk#9WRan$Gc?yJMw z`T(Dy3-FY#z|H$bVq4AZQ=Q%dER>z>*IhF#&hrAlG&x>TX6sdCtK1Ph8*VIy8;kH{ zginwi5LgR)|Fi&ZLbac|fr^>GO$ z#Pis7%O~WQ55hDJSG9iop!L&TpL~ngH9q+yk9>g~DDVo;=mGZ~_wZ*356F!kxI4eI zfvznc8PCamDBYkD*Z@I1H)!-ZbE`y2m)vE>?YaYwI1{~ppf6q+54;7_S^@81Gw;ls(bgJmVWX8?AnSe%&kNlbwRuz!36S9BcD$w5q>n=XI}a@41Tv3`VCH@N-?`G+pwX+pXGYsGr}9r%#^$bko*-FF55{hl{6L zDM7b?d4E{Mq4=)#&y*`4?M9Pue-hl1&PqrUiYH%RLh-PWP(0xhiaCcvg>P`NzhAnS zKtR5GMH8SmAA8iFB}y15kJ9B&^ioJIIFN9W2BLvnp5e_T;f10UOUmB8;yi(fn9Hku(QQGmc7Fp&zAyUoH62=sN3I9Pq=^b?9NhyUX&w~N(6)aD%3uU)K=DUbI`?Qm_*e?Nq zHh8GNz8cQ#Ul&7gN`sWfYE~0+?K#xB6Q&JUv5`bx5TFSyI{0qG{ygBkz9&}JE4-S2 z!oha%?>C?7^H6blt?rrY`LIb4UC>tyj;y@2cS7ZY&puKr7ZvOz7Kln4ZP1IYoh;18TYYg#?i)XCy)EpA;U zi`*7x_@%|jC_Ki#W@PchrwAbIX02%9PK{{chbu)3N4eX9GcWNbKKQUUB;5uyqVeRvu0aq_m3^pfb5E? zw0cHUF_mWfHKxInVkXVDg0Ibgw$f}j_+ta#KCaA0yM1i6l(y1V@Tb{M21?V+|7*Zo zqiMcwb?~dw{-~0<2Vt^6UjuGK!D_DN_*17|JcVn@&Gf=FCGHa&Xf-UOX;=-*==+U-uF+{&*0f=? z8%DojVKQVGG%QTQgs#zrB*ijXP@=71iI&l2RksXFu^_9_F`#+Nu#CaSRnM>*9iszv zD`vy!VH>>$v}&{)Eu%d(p*tODRbee#36$+9JOwf;m{EbUEu-HsdPe`_%7m{|qpRRU zQQ*w5AaA$9l0?l34ve*b1pn_g-2Av|^bAYs82xF(Qp`rPVRRc!%+rBKi@moRhSg{p zEuYPs(VXJcG-3RWrqVL3MiVQAIcXXlW1!#@8;s5Zg*jk`|Uw5|IkEKax9XYN>h=Z+sDm3 zr%1-Cly>)bxc7_0Q);W+@`1fFPa$_)|Js5PadEB&&UQ4_+6>DI$+wBfC z(YAUW#p)Ry6K1Go^sIjO*yd zW~bFxnwDV=tS(e*HqC+3Y#E*IV1Ui^`W>a&G5TFL_Ey(_Qks3k>hzmfd$-jEtlI2$ zENHc7^*c(-G6vY2p3&;HT1u;Bbb3t-d*8R3N~>*j2R&@I*X#6Q;;c@qeT)M)amu^q zz*3rBquuV~#I}0vCbZi%2OTI6-8ycWMz3dfu>O8?ptPDs7iOi^G|X!p z7A|b9|e`@OCO)j}g3qu(F2#9PbgbdK@aYC#7FgHDrmr~^ls(e89QxYCw|%VAoB zW9X07?c!?mo2))|Jdpq zJ+p;>?RHuKF{aV#L%FumZ9zLtquFd@JI$WeM+oXbyDej2!uO6b=(2v9gEscNJ1`M) z`xZ>iz-U`+T%9I>glY5#Y}~yT%!6eNTCk=2Msv_^9k-gspx42L@3VDAAnEo7;)TIa z%jh&=VPJTzK1_F~)oj5uwh^b8Mz7mMa-`XR?DUSCePb|a;W7*cJp}yDfR!5z+C5xg zXyK`}tOZu--0#A{hOfCbglY6TH$XI9obzt`hi20l{L*Y2z1Gv_z_2XV*QYI0Y4)D7 zjLnwOZ~ubXZ`QatXn%JWe@F-IzodiqUw`p~_QzWswExmDxO)`Sxp(pI-Bb6H#_ueD zmB)i(TKp=eD%LH|;TfGLYCUTuOvkxWlxTVCCyf?6^#3t2;oqz_fciour5?ZWRh{Fq-{kvv0KeXZZIANc{y;udM5unP?jw zMwxV%4a?~D&w7SA@ViD6X!>5u=p#wrZFG!Qv(YlF?pdR2G(Yld5r#5;b{0Q>N+`pU zP=@svM;YcVP==*#{zUAsa+A}_CU8}9VFNYUA(yt*B`l0)(;`b|>SJ{XlzJO@X=1DB zi4V;1UIcHGtM*O}qn2}Ja|SlpsA6@OP3z3+EE`Sh7pu#F;tFI_nw{&g4eig}xm63< zi+ythSOP|DtLxa;{*ljqDy zsQ_Ko=s~W&VRrmR)93-i+w8kcydX+9jc(VlfDi8TKbWpSTGQw@eZw38iO@F8K5)?G z;=p)!8ir*}TSlu7?0Q@27`;IQ@QFES42&jr7`b+iomiugGT?v2IDkEW@8%0>^`_mP zRmYRd`?~2YOs06&RqIdJ*UF#K-JEi}M;f-0vozbz@(r-?cK>zHExRIu>`4X<_ZkfyGG=O-mq#n!h$oq}RD z89UUjB(i>qRCdkKt+{4sU#G!Hjd=Z;iuol?{A+I&)R}jtR&?&z>fR_XTihDeua*Gc zR$o9sAad883cFPo%aq+hP399-)x0IyEMq#i)q4<1^}D);)vJ-$vOvab8D)&c82cD*)Y?cT7w zH|rGyvE8quxub3Kf^5<-^iwZFwXuMIpWRQHx{gGScE0{)cE7mH?o_pJUQxIK{4tzB z80EdXH|)E(z!v&7uJ2>?O`(M&#>`&lUf?Cm;+<_i_6!k!f9utCD!1GHD{r?4c)Q(4 z?VH{gIB4c!n1cTXhSaP0oTUP)R>5%&9s;U-YBcLHcvD8pXS4<__iBT^Gp~#sHGAUr z-IZ?NLs_i|{GG4d3s^^Rb@Q3J4%Q!2b=kjh%KW0RIPR{{& zRQ(I7p)c-#kPW{kw%s}lhL6Q}u7CrP>~~agJ}`h6N>+J@1E-{l#T9lO$1!0np%UY6 zQCu-OH63_MHmhV|hnY@9`@yZ+4@9ou7CJUvvWeFL)3LFc1`X)!6b-Ft>H_>2X_&hH zcge2u(c;0E(*1`Rt+0`55Ty(>EL?a6V1DuFx$+EutapX>dx1O8(yxv?&k9AEvvjW_ zPzi}@cf$ERp{cDr2~wim@x7JDUUY%;_@ZbcBQHS|o|l!;uhSs99(PythZIGCfm{

    n1D%|?wdzJ^9zSR&;AU>aC&46a@Mm#G{w!srGx{mY zNJPSas?a^a;^7VTfw=2kR3x_;BC6u13bVdZ!R6&Hm*A>olY$@l z)K=e3d^b2%NlZ~V3LY0|tbp5%IgQazDZ_K%tRu1S-CKC+at%RxR`<~0AJ~W3ou;Q= zdT%N^b&oYKQ__VwP>G!?mKfG`rh> z_Zhj{9kn@vM#%P#QF88O?~(6&QQ{?Rr@hF1?@^vE`{P@Bvl$IIkWXuXe0@EW{2`ot zO(ywkvYXzF!x`Xa07;=7ofkX`Po%-K~rR{(4f&u+KDXE3R^XYbTw z#>v!RfNMCt3cccgeR^eH&@294Uhn^ZvG*q2Z6e#h=vR@sxxR3^td`^<32u&WVk?O= z*=;#VcijGKAt+fy5-1EBB5AGnHQv{IpX9Aw0~An5$Vr@&6Lze3OTE! zyLu$q)x8bRSn;{aOC*f1JX6u}hcOPsUGGYYiJ8RrFP+>e=Ng;0F z_%J49VyJ3pY-?ydlOG?(D~}IC-7P>t)%Z4+5$AIj=zb2%5 zJWE2V^A7_a?uf?i5`#US@ZjljvrO@JT)btt>Z6B^T{z(OQ(`tVGGbj~><^X=wb00B4RbMH+WTX&lFJEAWww#?DAl z9u>?rE*7%q;REb>r6m1YOv|)qnnRPu&U;m7r{Y2UmC*MBXsr;}r@Q z7*vK)5LSBT7+1_nt{bWbnxdX(SH*mjLRRFlXXP{Po)`u`MM>Eo@MFW#&3o1 zl3lS_kTthhjL+$RpHo#F_47E799x$RTsX;3DQ+PYQa~Bk$ax}h00HWQgf%9|JVHBl z0u`pvH%Kn0?QN2zH35Duw?z1l#So0+%=0OWV*r>_mHDLnjFgp zz&i;BB%X%Ycg?{|uXB0=0I+88+M(K|uIEooA0&h)gMl{zE#Ea?#^blpQQ$S7q(&{T z6JUQ#GzU^s=!!zbbJ&THAQO$B{g{!G^zH9dON7*4<0*sBcDleHSZ1$8 z3b#ml3MQ+m$}`g$V4F}!{uZ$>0-jcdU{{4bTKqrN*YP$_{P8L7&CGtI&GVIV8pFpaXF$64sD?@X7X$Jih4gsd2@iSHlT`+b; z5H#_4cud2gp~xrTh=(0WesNeNMQrdLu4LrU8>!C$a;umtXfh_!9>@VDYjjSQ*`UeXJLj_J9D9Jl)z?4AzT?^A9gY$~2ZId)0k$0s(yzpKgjd42`LY3e zh4BbW#%7br1H#H5$-Z%Re6jK16BQrPMniwRD3lI9ze6$ZvMVS3^pfE3`sdzYa0-@> zF@+bGm1#vCV7MJD6iiQ6@YM6dAoR`AIVL!N#(g|{8Ucznc`neur1_)9Xxxb38_~37 zBye=-0Q%0FA#8lpF(l3W`r-2||5d8zL%P`<_onIEBhPUQd+xJcK>i+cto6|#x^dh~ z%FXDH_*oZYn-Zs_kHYvB(5?3u&(8iJ-M4q5W(ULFzo=x1&{C|i=^8$GejjXIYpR&AVq^&T58;yR^-R^R&;-MjeQb_@%#Jf~ zK%=~Nq=!S(Wr93K359ys1oeTT!-Bwt-4&j4Gku~k2W^9^*=F&uvU zKHO40uyHt57f(Y~)2g=TVi+BNlLB(NG{dBZw!+22WaG7E7@>9u6>Ep=XcTGl06yd! z(X#8f=3p=*=P8eBqYT5T(%}HyFlKSn;*w5R4K%8J^5g8;rjRyy{H3IJ%EnYV5c&9r zsi>Z(3^rtaEEa6)7mM)+e(@!xV);;B#q#dgQL(%eRV=Ths)$cshuBbmJokj;EknLB zey$SVo>pjvnCuA+H8kWH{#ET7nTCH=hmDagwpAyE0>gtsk>NohEA>fJ#Z@cv0qfv)5a!**=`nZPP|~@F+@*K zRwIXoRmWbIGONWOTn*JqPJ$~xIqs`rP9wHq8}?VWp~njvye1-BA9iutf&H-Xyr3(%Q;0QeK?3u27FntK+(<_%fC#X>3RIyCg z^+MpMkqbh^mO{;cUjFcD6o#IAiKijS>kGFOpb_*^Pr=e_C;~#fL>4gXLF!dd>N#-%VF#viL6 z(fBWrtFee%7oJxAcS{W=*mxog=J?OMHHeb_)X}(B(v>uSG&_Mlr+JXU19UIz;z=KI z2hhCRbK0Xcb~Q~j^@(fhjgMzn%5JTuTx;O%Y~SD{KvbzEujKqpmC+Oos2pbXsT9) zKyx70C^Cou_683`_Mr|qiYLn|^z_urh_)+rPr_}4y2LfeYD;d3^$B-Z z)|h+p9>$AoFYX2GbEjD{IZDPQ-M+y~#FxLu8%2MM4Ptk`wlQWt)-~H42;R^i!#^}` zRA?4|{1O{QelMy2{4Ql$do__!?cI$|<6r}w#{Rud<90fYM?aBH<8fN2aX@t%`&^ar zkY7AX=`^LgfWC9} zg-aD15)=sUjHDE#%8kp}$Ri1sXVL?A0Yt(QDd)}z4;&X)PTf%yO8n6U9Zp(vL)s^Q zavG;9OfTYE30EQp?8Zt4$>HxZ?dI=PQ>#uA!!yagz?U8xf)x^a2jac&O#=NO3BK_n zNT&=2Oo><%Q<*@;RT}BW2=-EToc5+g3KbgZ8-G+3rO5C^lpWLHaKdwEE*uW`9_{Z7 zJa^{b3D2E5<$3PRyyv;M;<+>L=i#}3vmnKD$@*9<*wil;vxr}KBF|;F%kW&buzv-f z%eu;VuC+Q#4$XDz8?!)S9!S{`iulOPtsZ-$*`;?pa7G=^^le0WU!NZ$;4P$d};;u1fWrMKBXI z5+vOR8Qty*OV^chW>F&)Nktc{g^}{w48lqaV{rd{Lt}uH>&+*i7!<|9>+w0V!Ec2s zNHG?fB-ed{h025sW9=_H%s2VPs0Zj9Z>w~((!$yEpr;%x2id$xwz^j zGpnsFzE0VXMP>gts4W`VrE9}gn?){=Jg7^yuI-Yi9fnSFZ2Go7PvYjyDD;#ia_nP* z8Nl!-_6Ve15SqhL>i#ajA4UOvAYfo%@J&e-EWpJ3wkQImm2v%~kfaEI1q&3)6z348 zuzSVNFLMXD-y4}OJQ{Kx`i1PY$i}nlggXpDPeCzY0zsF+I}|s8oKY{qgR|@T zLkN)^IiWcK|E?us@RRx+PI5QC7rAy87=je34xkaa11WtrG#!^rDlt{9sA}K@;WDbFK&bV@;Z;nGokrh*U8IX&O3I3i^q! z!fNQf_9oarHUq3`*9Cx^GfC|G%q|7{7*M2^UbTOaAhlHF;pnlgg#yN`;TrB&vx}G~ zd@Z^|N<&O1k}?`FD$qkh2V=M5M{Z??LpYlv-u!>pwzo@j*o66i5VH-FYplo*h{76t z8zIvmD)wUV>FF(tt%wO0#&TIYhc%_x>4aEciGO)}=t*3Fu`}Z3NH%6{88>(6rLQ~Zc z!o=Jvwr_Bd5D~ZPdN$n1?H(3o<=8q#G?CY-9RPw{CR9@ZVW>_F!vH&c!A`{0G1zz0 zk)1TYlr#g>I>L@t!>SpEzSD_992iLv1g98sWE~r>`gpH@ez2#Z*=*JE^@U>u7+l9!&P^8AHvRP(w)&3 zcSh@O)R6su4b+g+do|?k)R31yks9(%S`FE!YRD=0}8j=ifO?!>8o`-q6cy0Zk$G`w^+qA>+?1rPdFb8zGN zPS_hlT!4R5#gK?Jz*TrQfUG@4!3@7_0tNu;YF&BVe0IrhvqEH7orBO0;{YHEW{7WQ zimtRyVU=V`Par55h^viT zlM}(fn1j9;!Y!=}404crgP(Lm?4S7F2qszIs)Oi0Fh>-3aI22!>c%#BEinIo4#1pv z<^ieSs-Z4Ku{?1d8pO$i?{!ExMIL?hyrCYaoAQ2x)GN+Sk0>fn@QshLF5KZ62kV4s zahzo3f7!e6uY$Us%Tl^11S^@|At2E82D$#g^18U5KZJl08i`LSUR91(|zLFWF$%DunnFAV<7(a0&@3%5=BN0Sw;<| zt&SE^&pOx*|3*=K{nzqv6>>IZhZD!Oy-C%y?dF)Ewge$i2vs3NGV~xvQddL5i|h@b zJY4nClI?EWkVC23o<)Rpz|msd`04D_Ru!g4+p%|dte)wI32TK|aw1xiY8+q_rctjQ zhDP+85A{3+?K}WJkP*0l06|-$`MrK~{>@tMxGr1fN72rjw{}cD`VEvd){6Qm3CVnb zZmT0}XWe@{rf&UaBA-H%SJ|R7=ut|oYw;7{m5S)d4#5fWQ^G-$$6@C2ms8iq)1=lV z1U}}E9Jid4kSNBa9jJjVR@R1{x|ZnO3KUgL4-SOlnK^U@GhGRPOgGpGu5UOqfk<^NLfT zr)-YF7#sL((Lu!XwQx}(4L+CAau#u$-Ua{ zc51t~Katw*{2nNCEl?)kf`vetvx~IylVW7D4YXLyKJkmUDdp#<^2*QGzmD?rwW$1j zCN*LuiYFQukOh+jjp&7_5nbhzDOHOCb=uxmlr88r&<3i1C!O5@Cnfy5G8e@mNG%Qn z5o&P^uTeYn|KRL`AW<^G5khqj!z%|gb1ZUKwCl~zA>7sxJIM-b+R{|#0=M7UK}x?PflV7!SdZER*bSCJ%HBa9`lilrJOZOK&O9xZ3bRQx;BIZ)L4b7kingjaAg4I% z%xCU9t>7awXBdl9fFhk*s%t4rw#k7-#a_&Hm0W$PIm6@`(;p*>d9OV`(P4 zARAJTH$11h(D;o{mW ze(^kiCAYmQFSot;b>y}eqTKdg$|(u<1EkCpxKZNAi5vm^0hxx2CzW>>uUpvkt=_rm zo5MhLssZ^4ah=fB4U((w45Kiugz)Kbma&>k-%9+NZE$w8H&bl zS=y4usgkOhrt`m#udf3=D`wC!!?k638AB>Bq#VeQ1pp+vlsS{g)N|~g!xFQ^U)(%; zRj;AOKH9ILdaZU%mYE*y)Z@Ta@@Cr0y33Yq_**?$mKKZ)f9XQ_Y6@M5y;+wm=X5N8 zEM3V^A|F{7&|LdNa z-;SBT{E3+PpJ`_PkuvkYI1jJ!i8Ucd9aX{;rsD>VTmt}+`mnO46t3^^#Cfz_$eU(ZP z8ocnlD1$|k>yD?fkTo)s#Ug29E=9$fwr7%6WN!=UDYB1RYep5)bY{|3=n5O=^DaxuhV0eB(}K4j0y$EbhA}_gVqS-2c(UmxBpU$-W$9g#1|Yt}^I&A@osbM8 zo_To!jMU?N7L20DsZ>WZ%vNvTF7iH!U=Yu5T5C&vTqtiK)XN{tq$%#0>TTYyZK<8AN zcL3kYWO|RaRP-m+DM?blS1O4LO48`v^^M*u*J#?BRI|w~-f#itg5D4yJf!W8Q8XmY z-do@7gM71DYVPzOSzl6ry~vI{91`hO3c{RqDr@MGb}f~HlHLkqfhLo$jNatgDA|-| z6H>BjQ|mc_dgphl)oSL@nA$0z_WRn@jb;J}jXWthbU-Zv51w*3XcQT`XF!`!yo7WY00#md z?Xhho$bfxIjM@X%BN?hBtrJg8E2Pf!xym^zl%(SBS5-_+`I2hi^BIV(ZMs?Z6B4I_ z*}J5fl3HdV%LHMqK$+{(WDR83>rUF`b`su+xnSa!Hy2EQeCqE9mI7oVkLLWP!9w`T zyau3HFbNW6FH^)@ke0&Y6n7aAh5k{fMw))^dqXDx@)mf5F;*iMrsX3?&7j=LMC>^V5>veg`9j1J zKuUQmVKNDS+e-Ry4>)=|JImxJ0vw&B0Y}NkS}Z0UaCBnvixlAKB)W4u3u{RkI}0O1 zzk;2Gb(Q*QOa>X~uXyJI-7{EzgBl9JOrCa+t#3P5wQC+{FGyW*y+oluBVqPnI=;G& zV{J@h4m(i~NNf(gs|O^`h&4zjMIkH_g)*u`?~r&7LmfsP!Afw9#x|gl zANh<%=*k;HXO0o3Ejoru&41Y1`Xd34!wwfSPlv#>byW?)yd!++9`E zxT2qbMGmEQ*BXMKG%mkVBRFoAy6zaJkj=BQ$D`K0Dp>}<{l+6p2$DK{Qs1i6RGgK4 zJt^f=sCCo0s$Cy~*zC9wro|rW01n}eg6hZ{sT%UCuukZYq$rP?ce*NcR&@+oPQ*fT zt{nDjr+y6t{lG8?()(i3U{{(phcIGZ?b7Lgs=Msb_O`m^EEdqte>>ziT>jx)?UJ`> zS4cPLh`_rC@w@E#AF$Gs((nt#V+e0JV$nvbXyY2OaR4r4YW$_E2C09|2rW$`WV8r* z+z&j^=B9CVfP!n}8?~7CxQ1iYpf&qs4Y1X0CL1=M)Y|nC+}0^)XA@joipf$Z-B_=G zFp1K7h0hW8XO(9lbH4OC>I28tE2k%0h@YkP%BdS7c9JGP;^XuuucJco2ac_+Il*VN z68ZCR!I_)A`qm4HgL_IhL(k*{2Um6iPamZx-L=Y>iJc#$VH6U5Mui@V#1YaG9T9(& z9}I4c=0#cz4nyd|r}VHSDx1_me1{Q#u~#VdIDke@av7AC_& zn6k3Rc!do{HyR9PT-n6ku@!>*l}pa}CH9j}Ll#o}42He6M3WmMhm}J#67SAHBjMPH ze`1K!}|=uw@}7h8~%#{r4okkUqH3U4tio|)94zT6^V}Oa7DTk; z5Y*5+o;#R))PatwIyoQYN=G=DYB#Jyw2BWnhMUBg!IJuyRUZ9E*qoP>2GBw@F?<>1H5!Iv(Ft3AZK6+Y2aj9fGsBJ-^<;W2zF z?FRyepKo^}x!x2ue3FrW<45Y8Z&)mDSU`$IZIP%YC2OqAqz8qXZ24JyC0U@@O`}3J z`Lkwzl|j0cBHW`1raGmjpx|pt9dBbT;+ScVW?T=bPb3<_HV1pktgnK0cqXGFa)jc^ zI3H%^MDj2zuJmT%R);IGc9Vb}x9WQn)C25tX<8sTR;ydJ0Hw8m7@JQY8dy$(<9v2Og5w-AMIgeN;-T0xCM`*l#yHLnBI=N}@+drcq6XE_ zcZMn)EUs3BkCnFPf0Yp*B;BBt`F>f#v*1${gid#+E8PK}?m+sP)s5REb(a|Sos#`r z3?ifQ7EgG8mcuep;F2L}ausoqq-=~332y{9d;o)@Dh!guLKZ3iz4A@1m19p&N=U5= zNY7=;fs|3ET$51%Lh8#kfhY1RlLG6z=f2uqBIR!{A|j6a|NTGzZy4*}Om{{zmCSHh zt+xF1U^3w$uc)*LbdrF#CN7$Hcsze);vjMsMA%3hd?c5 zZ}=9jesa0(>)ib^Lej}fA?Ym!JD*eyg(CK?R6p$IOHlnVK!4JB zc;pj*#qisdVwkI#LQpZeOnv08(Fuczljwv^!;f{sp5arSaBL_(DpL9C-chll*IR13 zlY2fnCir?8KZ*U;h3*3!S62u#3_67_l z^)3#N)Ee^5>Pt-xQG8R=LliJ5H#ogBOnt7*^QvS^Y1`ZM24G+vxjH^{cm;-s%=kJW zr@F}SXR6;*Lx6~;7_b@&s0APj=r9m%XstSOG~sFvI&d@(`k;`Bn+OhTUBlwgF&%<` z?MWzY)uGWg&yqE^SVXXDPbl9K9;h0!`DxP(0_Vn6Ei{KiCO|ifUqiik5JBurq1AHb z4mRdX6y`DW4f`s*J|qB&vea1Y8;gY+U-LH6RZ5gD8j3(Xx9~f%Y*doWORnu*B2Y6q z#^mDA{exSQSMS9%?o!<#V{_#`NGz97@C;wFrt<_Mkrk5$DMP9&b>>EYitdKMp23BGi$cLxiRNH7n>;XFwXxfP{9KbSBtO^Wfrci}jm{YS z0D9&Kt8>WptdD9W72W5^@v*Hc7wk&Ws7jF~gpRe;muGKYD<~)8Wj8xGN5yI@wo_yH}a z2bdyFP45!TQ`P7pBE6=uL?mEHpFBsrVj^V9niA0G;D<+ALWpc^jq|s+ebuePz)Jk# zFVH-bbo-On*@48f3Ua;ov^ls~T_lYVsUIwFrAq0Yi-*zPUksNURs^-O(QE3U2`Z=x z(c!8v)|!I&vLeYSqQQWFCI^573J~iIP}%SU&arx({(WOk^~Qbzpy@^7fS8gHq{ra- zWp%~tb`|u@^M^0+V1)fklFW`CAk%{f4czIGLOT$!LJpE;zy*i4{xClvUSE<}j}N(> zPv{AZiok#l9hzR4M1h0kOEAI*fRd!dX*FZL7umzF3|HN+)oZYShu<4;7z!K;{-FqB z`e$+F5s3x4QqZzcqlYRn&?J^Hj?~GkYWPT&8K-to1O%w zOx|lCcDdWzz}J?4n*kAt=;~RDhY=^@Ea*at% zVv6z&m$=Fs?s}B)1Qn~Gu zZ0~O9*ue&LZ2z8)-Hwhu`ibb+<1`&Rpmc1Xldp&T;!%o@JuFYh_I@2YwkOcBHeM(5 zO&+hKW!%G@>-uCWm&q4ZmZ%FtQTw z-$^jA6_;cM=?nRg;JAWs77|Qa(#)Wa<#EUeCZ!qn#NU~qVd_e5oSxb%tK;1@E?BfS(@?R|c0`M)N!v)`V3CCesEcgWLnG8dBy<+d&?KIx zZYChI9S20Vv;l8G}M@Y4+j%{?o@eDjwZB0wX%L;ok9W5J6z@!AYp?m7&h1wN^XAiD3?5dZH zb!ry&d4X|KU=|P0$Ov*{GU9#ag*wKFIM0cNI=oOP_Pm?KwGNGOuGV3;)*EA(tM!I| z7rKdSoo#PVwzp@D>-{l_{h!;W+CzR&wVr54snG+&X&@s4ohYnWUNo>Pt`}B__g)2* zu8xKEit<}8G5qVU+9MIje3%akBalT0AzT#8TSUCtSWtVIB#w7jfKHI$B^DaoH-pK; zNFmPH61=%~hq`5IwW+eZY+B114Mz(Bc>Els=$U{%}72bq?oa@o?UkxO~Ynuy#nK zgFYv@XZ6NI)WZOr3RgqNeUbby{Ts(68CP*S89jY+K?Sy2fB+KBdlWAMrQKBIoi{m*weZS4*fKQ zvW9%^H>FywD!+-hIcM21#V!8kZWz+p1`O%Rk1#8|zH76>lQL$7CmWd+j_*17?Kt`A zPsGVj(wzK^a`I!&z~AzV(-bFvTb`4@`E@w?8cd0)$I3b_Iovd`zkd%YG0HT z_!D1~IXJuA_<#m>Onk%vrDA}?5NP3W=(*KN&j~RanKp!?>ihr7NdD}>Q!fm?p^iEPIlcsJ+f2nH%S2`Re=wb4{TLvxzFpHn7-?{HxNlc4^bcJC--YLvA4VO&R%+>qDO4Tvfs1d z%<_~S2*nZG;0sISxLq%4GCB9<23+XO-hQex0JA_$zX!SchMsK>APXoke>iqdRUEg6 zeJ6y8A~1OARzt(~auxZJ`_k*AOR|yJEhzjZ_3hjQE>q5>?N8~9;YrRh67FMCxETTf z1AOAG=UNz<#ylyfyNH$2eH53`9b|SOzo@I@D!W3MChya6m0iXB+j(9cH{j#1@GPj3 zEvcFmt)~4dN-t#=4U`4tuZgj0^*ZHFZQ|k7=||R339n z&h;8U*n5PcqkwX(NLJ9TIss37nooLzdXjf&WN|}7BclgJJ4O$R4vX7yV+^6-*cd{= zS*pvp3Lp~L<&oB^hWhFV-H<%@6LHMD>XwxTn#9_?lSxiaKqke*f1bK^qb*TOycdvm zjmiHztUKMzPzYh8M7=cHuT#;1u{A8Vc%5e~UO{pY_!L9DChOdA z>AD1ij>k8K;l^9UOE!psp#)v@MuLgkN@1mFmbH$gn2>)>0;r_WAiu=CGTS7?Z=ElzsJ;@Ze3@^Ukmcz# z#KS;WI%a@@g)0e26f^+Q#(bRu$;f6xViT`!UH3ePG}?4jdU zK}Nvq{=;$8#Y_aS#nk^*f3C1ilQ&Th>Ip>K(Wp|EIaiVSRNqP4ok`O6m{by&9UkB5Lh^B6Nt)kI zn*SD0L(uwIxH2@|$Q)EWwnQr`1rsp`+K=m;I5CX!=O^YS=~*-B*%MkE(qL8?E(Qf* zG|7?+Drywq3fLVgmKnjVEqO;*5VaKP0f1!~=9uuXe;XT6K2d;O3tDGGkNr##?-D5# z9EAkxNo9QNY6ziHL$5U1S~ z;`I0Ze>B-u#pxUap3aeQaJsFQsQpx8x4h8Q_TL(6zsnzjz*fY~mT>ALj)HH38a8x%s#n!faYT-e{cZg$dt_F&6ni4${oT&W?U0;U(myM z4DKeniiNxsN5s?&!>Gx=^$yL4!3_WdApR+Lqffc9>skh(Qm`83_{38*r&a100a#@i zCpqvaT4hTA^5X8pL>?qQ%`dVD*3HWoFc^g()=kng?l)|T0MS%tk3EXHck)t-W}Ogh ze};%1^C$XS;1&|6;soB6>t7nZGQkWIBLJoSKof6rU2g*%d~oU$8_x-=7kK@nyW5| z){L_VpYsmFMbf^Dz8Anjku2&yMcnJ)59jg?0#dq<_)gQyvUDVxOwf_@Xs_gfH6eUHhUn%J`x+ zHu6Q=yZ1%AoiEzKPvncXpY}zoe^FnwJ??_`m|q;Ee9<1=y?pSvy!%`I*KvQVi|%g^ z@7>?--QVur-|pSt%0-zsadPB(RH&?AXRkP>oC=lelohK^Z0nU3O}tjq(hT#B&xFXQ zPlcA`UM2vZK9t13(@x(a44&55oH{`m+&(*YGhB6AZMtw;g~>$iml|sNf8-}gY1?$Z zCUV>#t4%iz&A(wH4ipdyNWGXMqrDHI=uMvok6R>od{@o2k+7`zto|_LG2_KC;$A_F zcu@}JNX_QW<%yD=IF=a0S;{L6;Kuyqgsb9;(voAB5Vvg@h9X&73Y>(*49M&}%(azZ z7Yi~eiQ@ovS2dI7ZJ4xpfAe_ZKNAg^Ni}3nRzoJ_{NNfguJzC@k_Fh5s>u3y25gw9 z@A`N~fOZdKXIyD=XdYOdU?d<#uOx|%0LdLSy;YxE^97!MTKodj7A#RSFkH1>JJ@Y# zs2Lfq`na~c`$$7g%W&1*z1qQ^hMI$t&cy>K2*EObPPHl-FUzctepnfJNJZ0(vK|$59P*!N@;YQXpeEG9x}~qsyow*nOeV@`WyLJZ!N>$Z9v3pC z^SR7vVcbG3jL-nkf5Es&){J6$r$f?0GF)()PWyW) zx0~JK;a55eQ{(};JU!7X3Q01(PSfq!;JK0v_|;lZ-eZzOrIP3i>8EIFm2<9H&aa-l zOR#eT9%vP2?WNTahaAUc&)B09m7R6FJJc4OZJ5{Xk_ST5f3BCST?6LCJ4aW1a4uhK z`FByyvxcJJ53%h;5C@>pb)lqHg3aEYs05p%@+!e*=Le_+o5MR+2{t<=RD$V3>r{fx zn|qbutyF@|@z0|YY|c{3J+iSD3pVwOMUx{=K%a!SCZ+Xrj3WFB`Z?BBs-J7N@AY%{ z`nh}k+`WEoe`R=Tv-uV7k^JP%oDZl(h9aXm6MxF}{+X<-fu+HduGzF}e1G zxAB{7+GtJ>x3S+O-!>9w=dKFSpxTmoKID}X$1FB&e{0K1qMEnre2vnI`P$`kjX+C~ z+aJvUHV+jFtffY?dip~e{Xn9I=^+)O&H$2$TxH$mgx>8MuYx(8_G1_sk{Lw)jQts)LvX? z3|c=vC2Szml{Sz|V)W<}qsJR^JykW-ywp(h?ECnyHs8QGSy+@$?nck?dILSj@sH4R zoZhvbSW$s=T9V) zhyPwL-alQ@NqQ0$+o?WqY`t=NlH?Du^JSpO1INy%5Xsl~o%;QBD8V=RYd4?kd06EMLDk5?f^@FmE<~i|$ddK~s zy8O-ye#Ztsq~@tAX*A(z@n}5DqX{vp8OVL3f+F82E9V``Pm%y$921WeG`L`9xezUn1?{8pY- zs0TwQPGzjqB{PWvWEIZlAfC;Ed^QI~v)NTu)y!oxu_5DuspTfxGZHKKEYIWy}le;4p! z3G&WzcA|Og5tpnl_pUez_yH^j=7R&j;b#elnQ!LCbLJK~-nd!6oBv8Lp67Re?ER34 zFV7_^*G4&=Yol1{%Gc2<9jq%=!OAqV89C*{dim^CzJpTrYeTAkZEU1~ZG623_SO0x zz0db3FL5@?h@6d0WX{I-7CPUrfA9L|6oBC+f7^3%yOJ?1~N`TNqZ32!AeXvN2n zjfW<)D|iAv$==8hWueW2J#>qnm6?Oj>*wHOY7YKSvXh?UkbL@?IdlebAO{spR05w? zQBsqj2t$h9Xh>wq)Y!pW1+D%+LaRTnJg)pjjwm0<5ru#b08K#6zckeRf0O)tPaf6D z^=EQjBiA3vb>lmkHeM2Fj^?hU?Ql%_6CUmrJgmdRgYVR^TE^zGe>XOlM;q8&9^ab| zZf81p`16(R9FWm(t_!|2lg7eL;`ka-~O}pyy2}M|*{5 zCj{e{oPPowUV1k-1Dt*6e~YeAj?u!R_Y<@Df&Y_ffYub0HlXwjjOKw#O`=?dV;KQc z;dEK%O6Y#HSa2VS+?h+UoiRNb(dkRaQ+Rp&>Yhj|U5ZuB=%NV_%cizOBcmWaXf& zESIylnGU+atOb~M1=9c;xrYv^NJ&3p2z~mNDLC%*Zs#H6(j;jjS8Vxr!WCOid9K(p ze}E@K%e!MwgqB&te-j~HXq_iQE4UXYZY55%qMt~duu|d#*;tDOoBG9~HQ*OfN}L#! z7AF`*_!Yzn)>S4>bno2)?%e|J-2(320#-&`wCwc}7yLkAig6X0h>Mmb4YG)gfTCSM zl33Ku6k|DaY@-W>dPeuBiNwegrXI%vX8{_G^${A4&0{ngf4^FkhVyk%8jV|qX{-*# zXncoQj4zwSVp!#4F{0J67>&(>F{0AJ7%fi{jM3_D6pRtcgE34sk_2N|-!mA)ii0t7 zW8HFziILi|JtWcB=r$_S)_}D;b$-1Y#DLZYhykrmYT?o|Q@Fjo>iiXQQLbkOr|c|o zeYCYDy{}?Te@~7aUbhkoA0OVI0dIE(y!naFfaCNTkVf6Jsb4HwGk$TCIs?wip8EugZBebUD1j0AD>N|3U#@{cNb|unuvhILfM=kXeld~Eq5wC$U2KJF`rt@s zqt#JEX?HKVOrD8b}t-;TCw}ftOlp z;~hff^fM8%43F+U7}QuYhzzTWry+I&$gUwW>WDMysA_pOxM(Tw-adJE`Qq&2^kefx z(dIn6-|I6?Ro=N~6!tvd`GRd!84WP-mw|Uvaa@`#YDBy}K(lLOH+0Ma_TBKQ<_3JK^&|AG{kzt) zw#w*PTN~+Fr}sSec0Bg-C*rYh(mb|FdF+(4f7Ua8ahc+=XXSZp``6*IZIQ=5x!1Ga z>sjyhtoM4>)q2*~C8BUzlQ;?|5xgJ-r?Dyo2eDWk-Cq@qlRy!--l)x8H31@q-+O8j zkfUOw)h~?Mu+V^0qSlj)Hm4hFbGq`FjczeI@mIubbT^9GNR)TT+AL_JQ5>~lm5$o5 zf3#Hy$G$p9x>GJ{BP z^7+&7bQkzB#r9*1mB*~rjZ6j&?jUs7;BW&yBZqx>EH&7d# z{|L3g#a*in&daC`&NosUe7aW~+)i!q>?cwi{GC=CyrpUbjt|p%$}gU!)CNz>f2$2n zejT;JiKsSscds_MR~y``4er$jtJMZCz5^g`>+kF2Z_Bw- z(bLwQK;5qR)NLHATBm4EtNiZ(xous@{HoslSApEN9^5(NLhDQ7A@LxKxNzP$UzvlQ zKF{S~CujJz`Pf@u)&_UCp645ve@9DTt>n#M`)D0L!m7Tlk4$epUlrrs`TzmjFti$K zy&~7oRSmU1XsGr6`-DliUZumNTc7Vnv`z9QR6& zdnHFXXxi36BIh>Ja&88pHZ5^ml6x6ADEd%>14YH;G!9frvA7g=Q|n;8c)!2C+w@>b zTU7)d#-6Uh4Eu2-vA^=H@Q9ob4*2=tG5NXAe?I&=5Zl&!bwi-qRt;cjTaOaI7#utI;n%#~e!t1v;r4c}f9noUQVx?9=9NYM zYt^Y9x1JQPm_A1Hg6Y&TSpu$vALVMH>Ut>dOIHk8gF#Uv)|o??+L%T?$&3(6G+=H- zVR@amGH?_I*YsPMpPZ@0)Ys;CBU% z+GVAlgh%TeniSS_WoJjx($LL)hP{>W9f;M#M>72n2`A<2f5t@sE=Ltx&`k;g8^ymT zz7w+RrKaPn@Y-;hAlvs)KPc&68Je9ypASv{#&Ivbk-qmYTn$F11?T+8bpVPE9zFHK z&>QNF>VEclhiKy1bEQ6-Rss)ndhz-=6u3}``l}!1-97uk zdUsF9=7Fh~FEmxFj?AzJTL*!x6b1MV9(p-RoKq@T1|S|qadVOKyC1p2K6Nz>k<}8B zR_C81<@Zm4=Yr2KUZN}ax{&dVKf?y0>&Qo>6K?@4e=n@UbR);L9ShVu$611qtLP;+ z4+nG9YJ{1EFPzd_Hbp}u9*@h<8QjDs5Lca7bHT20tm zcC7wXKx>G%x5?j-DT)+@sXO~U70d`H;A?<26kms0Jc9j^`o;`<)$YLaeAWHE-_?+K z1oW#Nu`r2o(2pJ1`0 z{nPsW21y||L+{;a#4B5}QMf_<@ok*WZ6_EF%$crq2Y9L!d7g6unW0?EC9=HX2&8^{ zl}CC&PeRoJxL7Rdv10WbqzEtXM=qozT~&T!`cQg1u)%7N-7OQ>*EE5QNcad|g zA>L>t3Y>UCj$bu zI~Vy2EUT5`zF0U}V2L+>Z(muW{*Z7(Gk+-SchH>7q3$E>+PazIZo--(&NEBxe^Bk; z7}jE;T0~x`zI*%X?b(O7fU-a?6x6?|o;Tl~oW6Z-DC~mVBvWh9874RQ+#B&KVDiMI zh`hq0gY`$ok}SU-hTX^Q7a`N+SaIEY!3^It_>8!S)}i}I0Ug8+Sic-w(G^Z-cKpcQ zaV*bOmf9h!pY)=z@>lCCC)7q(e={4h!n*%lU-t;RKtWTrXSPYM+K=n2WmSmPikklZ z-QY*`H^7hRx9+_QZslFj@BcjB1^sDCNbFM>1UB`HMgNjt^hNIicDszJzyIsNAoN8T zg#Me7(w*;ld9kkO80+73Otpq8?7wQgp&crSA6oMV)r@qQuGaNjtPqiqf612cZM}{l zF0ecBCc0uqp%+(QAeVtNF%kAa5_>_ZUvd=Km!F-v7czO#lEp*rLp&sr=(t?Snk`ib zfUY3hFf$B&rxOuyIep&s-0%Z!T}rS^?!P9YD3R>WB$C}5iDXCkDSRhLPAoVe!kq1e zrzaF4Gzv#iNF30qT@Ad?e_`=+`WzbG5od}D5Fo`c%%g;vB@B7J%;Q&KJuOjjCW73f z{)7lIAXbHlva!7y=VN;{nYK{!S+rm~s;H=nx zaCo|Jjius{*yJPehdy5-pASnP z&tSD3N_@9ii5naWy`j=Tu)VGNhR=!fs**&}T2#-RT?KK|_j*8tj*S!kbM!kQ^Mh|}FXUEm% zMVsDT_W`DK)3^=bt@KnHnnC{}a_PC$>jc;z6EBsP7x@-OzFZ5!25WW$e2B2|%3Rb- zFBMHrhFyage@JZE1c#JkgW{H$$jJF5mh4W{{;@hIWOGjVy^a%t8h}xsXidUmC3vD0 z@r&)2IA`JMpP~M1_%f!%A2bQXy1yhg$#cV14|X5!)-}|>Fx;xE_Rlrc|75u8(UK!Ha^ytcAl<*Tw#e%Qvs} zdAr>UhXcKT0eT{ERLz{!eH@0f9b$z@CB5lC_)#qE%RR+kPw^kDqxjGNn<@T>A4>6` z-vz}_e>(dr))O$@5u>Q{$>c6Kdf>Kj!uAN%ge!fvV^#9;0phN$+-!#`Sul#GY zrG{0Q+F7j1D?h5m;0bdwJA@Jjnf1O+5WE&=o+A;dC)DT@Mw4j0%R!l(( zFQkCOJMa|HshI{?P^%-;55U~XG;kg`PtRlRS^tCD{{mdj(a@aM3~)`fX5B@+W3=qcCBlMX6kviSCq`t>rY-M3A0F& zh>K~pbEiWgtbz{_tBoo%*?6&;NyUDwf113)XpMejRkTKb7s4}O$!Ms*N3I)iRNB>0 z|6m0(CLUZ5o^lVa6tk`R*p4i$Nc;r2p8=9 z8>@m{a=@G?4(K(gGoEwCg0{Eir*P`ZnLp9fvw4nM@L@Uhui*53Z6xgzj@eq=e>ee| zgS}A@5kSjpi$&6R;(>o_zjefH40`?Gb}sDBjKQ6}^g0#TRsTx?!OoUBmi8Sq_ahe$ z{rP7R$*4>HdB25=@!s-#dF}USiGhJTBE+6Ay5L-k5*ne4uB^*jI^EBnfnb+egL={0 zOcol5nPnV(AAPeS%kL}*y37rve~;$WyebNU-E34xf@4 z{v0nx*_8+ZelO&1}h6VNae>Bv8D2Zbk ztNq8!qZ4ApbRcttO};w=HtE=qbS&h6U#@`h<#Q8jN_m^3z!xkdyVF(u!a^r(s{t(_ zr*`iCB5)TvLEL|8Rm33m*P}C`6uA-g59ls(m_L(}nvKHOJd^cD>dcp{|0%xn^$%V; zY+9#SE$i5LF%woS{R1WVm~v@`CIQRAFW5JK8$9vQ<Q%SChu-6cvT39(G8hj&cZ-eKuNAnpzjUm4PO8Y^_d{SqtTCw1q5%Y z20FKy8G>!5@l~D>5k<@hpJf50X2-J(n-dN(A6%+*}OHTk8 zDZlHEEjS; zsAC&A4fivh_P9G8^D(uZKwfZ^DJVLl5@*;wBK1tid2i9_jXVx0UJ2MH(i!s@UE?5; zxbeBny)z#QJRO2e0p6^Hws4n8@zqo>Wkjp9wuNAJx(IKT`A%4ke1|Rre|daUdd7o0z$baU=HwwZM=7DA+by9? zM4zG{bh?bf?O@kdRyVXLaZS84<2Xn~SheAo!WHOZSi}TlJkv=<({8DVEIvhjXT)*X za?1L}2M`ir6qG4>+0EXe1@xQ(X=fAHZ!JnCgGn{ zmIrGXQ@Dh&Ebnj=SsV^`RHO;eofTrfBjcD8G|x~Tom$}meJrQ7Nl9-pp1XkQ48iAD z*F>mj8lADKRfC>6!s;BzygsUtSoF`4f8%3YRW8_-qM^ulRy>UmlbfsjNhwhg_Eyke|;y ze^~hG3pCF-iIOqj8PY-DfxvKO`OVFI1u!|ib8*-8{z8teD=?J`A`{B484LxXCq{_R z4%FR^1_K7DUqjIE7kDtjJ_HnVjY+z*P~T3E6xso?ifB&Om%u6!Cx2%-P6dvLB$~9; z;6%Q&`PgjM<9Mg>ehW8P?*;DgBL*RE&~1i70%jyjQ^GfrBu|O$1Qc*Aj8m4lOQg_^ zPQi+R`1PfvD7N=-%7J`?QbsBV6Ea97MSO9-N-gWEE?xx z|36fDKz!qMNug7Cka!42`C6E_AgZuBXkGc-2l=`s84$V>GicUHKkKNUGK8{33TbmF ztD(RsO8?3Db;&X+Z0xjHsaT$ki)tZ5OI@YJI&khzr2=+w@ptY!=`WQ^1~L7#(#HCX z*jPUi8|&W%9)APeKN5waXIc525L3HMPKfCVWPO-EV_6@7<9cOWEra#0mH~6MwAg{d zCst~y;2a|H%6h~;1MHpV#~C2kahHoz$BbB>`aF?@iEgtV;-X)e0P^h^xP;3pMw za2ud5iUIPc7n%GCy%@!@m&u<1BOhS41QB~`)H8VzdVgYig*w_rXpg2>h*VV_NYX1< z#OaR^gXt*^`Bkj5W&^Iouplt&@T8seIk z8-5MBs#-(gtok|B)U1($Q8O?}2wXYqKg(-)eWs~ho)IDahCl?;<>ONtDFLPrQ=Pm} zyBe4JuYY#YUMAl|#aHcQ0Fh8)uQ(%wAoq7S%?UB>GwZ6A=z#1LGQ#xf-JdMpC2a6% z-X$kl1?}UW>Cm*UH*!xLp+GLM4j%DXI`ZR^MaoqwrbS#UpV&4FuruwU;|f2M=jTx; zW>eikG=1Z_PU!hBy-xbGl?tYr6Vg#=mS1026n_}sQ_l;7&^Jf1UtTl_9W!naNj-Ef zWJ|47`glfj=ki<0CmY}9lU>iBn4nL9alk=PzA2T;Xb{~vZi-7<-f-v$+?$I0SY*z& zW4hvR-->)eMDTIP9DuUJFTp+Etqp*jzR0h`YyhOV*j77(eFNvOWHG0s6Ibtv;vsmk zet!ral--Iiy$)=5FE9sbk9>Z&cpUIF#J+0|UV0tAKzuy(Lj3L>|1EmuGq_bs!0D}l z3CHl(2wTax|2NbW%P=ILh*P5=5n*_)>ysoUgB!&UbmHg@*}yTbI( zyRqfeH?ZZ@5--hZ?Y{uRZ`!ywb==O>vHKI5I`+!o^-K@`yHJW)e|`{3QPPZbRDUj^ zHj4$@cZ|?Sx6q0H&^`m>zFJ46wMWnC9e2N>uvkZlhd~(K@GI-ZM)SxKYM-p zgxp!8>BE%Y89P?3a4w6_S}V#32dr|X=rN3zg~bUg8+23r+_s_?ID@_6XB%2>0`~ta z1)i{ccK};u`SsJ}SfpHoL$oeOWq;h>1_$*Xc8k9&G;^71GkoW~aZZm=->f}bU)P{l z$r0{9q)Cm!IcuaE)VQNLYZT7et=sdJ1GHk!epHi=$r=Bg9R7JG$2+9a?zuU_ev(`+pMRD~TcXQQ z>hwnF>k~>E!6}IdD_2VDHURGVMz5{XaKdb^!xSIQ-aEEAoBphK9LBSLQW% zvq=k@TZR!A-riON)unEHihrV^E;Il_%1sm?djFd8@LmCuuz!O?+Vw-lih|G^lI&|o zYFFK=X-KSH(^XP`ax(-kxdN@~p!$rd0jLY!*7UJzO5o&s=V)3ZAi-!J-~pzwmsCY+ z9q~5lUK~peiFeC;(1*=53_Pxybgi;a#J>q>61@b!dQ{xpyaTJSMt`^qYw8wrVr{x1 z_A4_l^11S~!oH|bQ-j?3ln%j@q{1CiSXrhVUN3t%TWci>unihY;;lecXT|Qb%fddd z$bztLIH*V>85I724GrsEg%Og<#{Rz0eX2qPO)KfNe4xv?`{vr2bNdC#E9^arDm_>Tt zgtc>$^l`SmJzE|7K)bFxDD9bRO2Qx>CYBm69|i%V%&56zbbnX4w6Q@XMo*Uy==Sy& zL{XeDpX*|~QMs@QvLi^$0w8DYMdi|3+a{nOrXs`J;XFcmp=kscyp0R43s^VaJlb$6fSSl5qNom~fXN zLj0XH=|R!0IVKCdn=0rv8E2mV_}L(u zR@f`I?`c7EQYwYj?KnHWfX^ehD!e3#c6AE!cNUzxHsM7QM8~Z7|Bc5+Jgl!7pVNTu zbJw$Rg(YFFm_fy?ba)k&5yt)zokTi}LNfhF-=OJq52uuDiqIS3CTp~Cr}REPJHDvI z?^Px}$Ldu)-?Rpp>}{|DP-`XZaTfnum%cI)90NxXVwc@A5i%ve!m|p!dE3E!v|yWOgEkx1R{djwivfVFCbXgrli`moqaFYJVd3w%w>j$!p)EQ4-tVx(3l#zE5NF zX2tcbA@6LWN7;zgX6=?DrOH3!=Y9SlHd3e_k&4WLrmUt@v6FbLYXMIdf=hD7a7Zdi z^~atY`lc0@r(4-J=gk#F44ssLYlgvm`1Oz_bb=}Nkb(k&j5q*mqmlzI(a@zF5gf2i zyng^w@RAXB2^M#3191eaDp+kFWU#K77_;NKgPF3_cz9O(RS8TiS~xIT?@JesjOJPC z!j{o&lrG#gVuvC{5j=;e!d&zcQWU}2M^PlcL5hO%nl6Ac5_CuWry%L_TZy}gqGWt@ z*bUL&g5GMRt8L_~ZDgx$WUFmRs+GA>uz&ib{u2CK632-6k;DUnJu4ve{Bh0`LQ$5; zHq0ZFnw5$%=VMb8WTb&`_Wz%~chPPW$@)iMMWOrngGq(x<{NItpJO|TJCWtFmGq=N z{(E6jl86zg0r}E0YyDs2yxw_|vvysefC6F1ad%I9E-`|-*RHBv`|{fp)8F=W9Dhwf z#m2M2hnX2}hg@+dez-8_+jFL~qob7hJT-^gLp?K!;`cK3mbC|a16zZDJT$|e;c z8*6xJ2mXwr5y|vBejoC)&O4F91pSC$_V#?+a?Tn1c@dssSKLf8qy*Nr$ zi2>p|Rm0|MCp0FA4Y@HxOfPC&aDSoMq>sbMfc-?@5hd~A6w#n?AP3n!~5*V^ZV?_!~5*VqkHVf z#4R?`gcuXVz{XB@=_oNEs@klhjA>E2Z%2CaEZM*_x#&CDjvnbUKRlf|xPN7K`$*3? z;APT?dv!jY;2oDc8}ca=r@7pbkx!TS%oR?Od`iKYE_1|?bZu#0+J(NfOZ(E!^`%|X zmv*i%?UKH<3w>#q_eFND6-uXfJ)OD>mY;cL`IuW_>48|5k9r@LAC~3$NaD(qv@CDx z&?rA?^ZD`~nK3(2?|Tl@<9}9i4%6dSat~V zkJi9`a;yo~k~(f-Y!muBxP`H>0)G8O81y#qJr!t{#fr;35Gu7}$9fyIsOe zmO%8V6qA92*;S^cxOR{sL5~<#mc0bsuCg)-(A}_zEL6m~`|k#z8(b_!4;f4=Xkib# zxO~0}$RT!Raw(KZV}DsKf3As@jq!B(7>_H)xCoslTW@rvv#YN%r)2fbD{EQ`GFcj- zy0RV53sXuo<0=H3!4&|}z%H$!!7X{7lILskJSNZQHC1y>5d!H%xTEuL2p)dHq@a>y^ea>MO45)Iti^jcvK%)QA`D)*{_s+X zA(RoYiMxr(AR8AFA5dvmjS3UA=u^w_G$e!-e6@j?r!e`sk!{4zkcRusMLXo7!Js81 z##0g@42`Xs5P!upKdwlb-6$G$LEblO*ab;6?cvlQF=SRHLc3WK?IJb!lZ3eNFF3D> zQ_*xxbU7z=TJ-=Myn3xZY9DdixMl55MCCQDJ?b@pn+-3oUl71E&(2GUXXkl|XD8E* zR`n-yb(rKv-f# zNx>diQIls)F%*TG`DN1#_SHx;1}ADH4D#T4kPCy{e)Li9)f{Ci&=%abEjsSh341yQ ztzIbNL(j|cp@-&RBmsyRnM05>Ow1u%hG)4%1pOJ3U6?aSHZ^CEY+RP?${a(oYjX_A zvTVz>ihns;#DJhZXfZkwS)*%OPK>hQqoyiA=nce_Q=YOXVXasIzl#|4p_#s~4zAE5 zz(lG3uQ?7J92%!Lzn;Ym0vmng>29mj?ecWj)#(mQH8KbDviU?-!WzzU=+eUkU3!>9 zmu5MJB7AfcwGrx2_~^c>szCuhny~i^5#{k<&wuc_Qp>;+`vCS1o-po+Lm^-UFc|A+EHd5Zv4+e zp?^jLit#@wb6sM0fc^(5%v3-z{zuEEml+&D25KWvOfRuBpvkGNuOxlZzyLC&_5j5^ zCAI}fiOUd+gek~>+m^qk$4QKW1Ps2F1A})GF!%^`YQs`6_=w}ZM|!2)F2RL&in#D~ zWOj-XiZJjyHUvfljcDTH#XKb{f#5>{*nizgf#6dl_f7(ipJ)rLwD(9z(J4oA7h(~V z;JBkb7}W=D^nS9@`|^$6FWcxpN;i5N&=hJDf?tOaDkXeXgiuGumm>t4#eNDh@E=MB zUMU$InriUaWB{6!3oU8YmR}N2!Y_*_v0FkX7im0+#q;_8e7--Q?|+^1z5NK=dVi&6 zplVyMBl=g26BS_jgsq*0c6sEjy%4LVu(j8S)sk%O!F?mOkodrY>;bggz+6G${iNwyYJL?UdC%xI~NLXq;s%6VrQ1$%7l7A>+UyOF0ly zwuO`rbd)a$sv=TtbZMDZlBvQ*}ioNa#3atFEI^YmVHm9{{N}vw+*1S0hoQ$ z>zG2lb>YY?Qsf{&3vvdGlC8g3#{{IzacWL~5NoKXO6Ysw&@sQD=Soja50pWg{Sfqt zf>HFK|1^f^JNGa|e~zvGKzr)HP;B+VLDrsnhuTx~sNjP={*Z|Z&VOFlGH&kweT z3L;z$tROPh5cU9pshIElhJ`H^a@7TOs@L}8qus`*QtFov~hy zFlx{cgCrcsk_>|YX-;9yTtR7|L^{_s8{QvSWZNcqd(N2L5k6e+(m7fnMs+CSVoIDDs|mZ5w)+S?iI zpD3tpC_6_-$NkUydkX3p%JKfs`?~}9(KVFaox|Pzk00UJs-f)df7~Zu)*#vE{)hcN zB}Ri^YJWOrM%G1m48{VbZkIpc4fwATqYKL(<22Z)(rnc7{rez~tLcCAuW_(zg;-6j zS)^!VnUuQY4c)noLjuu)2A^dvd_`0ag~g>F{H8{LIV9o`{Fd3p%)tjWf^es&L2?!AT_J@lto4Kzv>ze+rC zez^zp1wHst)I~IjBEm5PP()Z}0E!4dmj(i(wlx%*J|vo(J|r4aw8|cy`f3hD3Y!Z? zw?-2&sx_L3)2z`%oMMe8O6b*SB1Www0iji+nW#5Bz@^)_h7(nsKW79oU-6cvF;g?F zvwxajzC@885-B>f2ul`^fpz};@}+3jl`bL!>&cI7nq<`(Sm)2#6nya+SZ9y<66k^? z1(3&=FXLp%gZUe4H|$*O^~;yBhH#7^tUVgZ=YWsccCuxdra5?b>YQzRmBAcy*WJNq zHPk>`uj!#52tjl+_)1b1<&~Usi8Z6T1%I@^yt&`038!Z9| z3!e|8go7S@MT=y8893JHAx)BQ9d6B$`O3k z;@Xjm3mpGG*L{R(P~th7xz-R*eAmW-p`2hV7)}~r{fkD@5}6)_STss&x%v%mHh;7p zCv&mkry6oR+Zh6PvzxO)OInqsH;W!Cg_?d%#XyB`pC#g5dRB6m`5|B1nMRT%D2G+g z7U(PTkwH6y`{v^}iIMN}CQ-ZGFl`duJ;LwPEKa)1+hxsWfq#YVv|&5!&G%^;U%1O# z7T~W$VVkz>n7#QvElc*0^?e%0HninUqi#Jy!gufeU$j?q%=cLcOTz~X^2UEi{45O=H-L?a^5(aNNh$5bN+iGtEZduTz5 zGJ=>247kWia3c|Y%C|CJDSu9d4@u6=qs-#UVyz^3M30klPU~MOngxNNpwU9eDHsgEn za2Y?8V?1`k2nUVavX`-i)-Rv_lCt}Qhp;!FQpqXMbb>_AeqRSp#GYf# zz^Bof>1ELMHlJnT50izj|8->HJq#4d_khT3ZACvN3xbW{R`l{EBLkC8S(4&3I@=b1 z7>gJMT;hF+Z$pqcOMd{1S&A`^`qv&OUfSYtWkn6lfQwj^}>RH1w|$is9dfA9-=3LBL?N*h>qEd0NJnS7m@uI zBp|(UGm2A$Kg(3HIaq%c)o2!N0NkJEXoy@iO8VpEP=D-1KW67pe|*!@L(Ik=*(I1i zb{Xc6qpIpq4g%Q2>LP|49U7LxiMR=zNNB2a(=LS*3Au>Qv-$ztW|ztW}0666F`o`6TUglmXD4J?a)C7R!02IyhoL@lJX>-XO|{nqdx9DaloNAm~Ek?PjG|i|Q3yH<=JqM+lAh_l^G5&w9oEvZ3;}*mQYf45U-E;o{ z@o#VR#NywcTSNStO;jTOCES<&EQxrQL_A9(o+S}gk_gnB)HBnVSu-3^!{}?rjwZ%> zvq>y9dNcFlO4ammV$HC+AOdEGfa1-Xs-_3{x49EwTUCzP6ER=uT@>v*dJ`$IzF^o3 zs`HE{lZAhir!nR&F|@qT0?wClNs~cdDH{7K#r;*2@ayD$Sb=z#7M?&Iw9>x#7z)rxZ$^cFfART z;}Vx08eJNYO#B4E#7VLC2&ovJo{&uZ_z|Wjt4V)&X<)m+;PrlSr6)(gVR4_W$-j|f zgT)mmUIkG@0`U#=dQIv}@wohXG8BI_Qdn#vL-G7zYPkv;&0Y5wvfPLf5q90(2_9Y=%E)pFw<)<3M7C)smxOf=byLhtT+1O9NH z(PUpfy(arcxHOPOes@RKE^Q?I+0Qg_P+NcV&33WBgXWucRa{fORGoFn)LA3u836}1 zH@iHC12lZ=VAl>ok0E@5FI;oMbxP?eOn*};5`AWJ15xY6ltejQMXyp<(I>i!9?@0o z)btf(RS)3SyCkCGjQOV2pnj%5FETaIUEiE9EP%ws)Hh0B_Rrz1eOH3Wubo^ zNojRjNI3tG=7RYg7&*C5L$upf5X5=p-yCmDF7X*hm&Uc@x(xzf)(GaF2Z<~qOZnPRJ;3&Sh~<|*%q5rqjQGBKet_?CICNf~}}P2jwKh=;ysa|f~#{Nf9hIRGi-u;9)=iiW1TV}sM@%1Ywq2cE-; z4`|}!94BlRJx zrOb2WN!HAk;5&Oie_8>pcbvoZ5kz3}co6w85MT!3A;A0b9yz|ljU0auNMH+Nq%Z{- z3CK{2l9P=TL8p$-flT|moy-goQ9&C7aa7__E#$bn6R0UuQX;%ci;^ho3fTCOF5zjb z#)vv}ad4-GQUeM|#Q#|y!~(RM61F+6(-*4@+h3A4!#&5SNv~?E2xG8p)V1sy4y9{2 zeDH}^zFKDx!X=GGpxu9CY=kafsR@x1P>@hIJ!2av+8fWUF*cOQpSlX7u}j8b!3)>7 zF~8GbJ-zNxSJFcFcbWK^N~VS^Uj1;p_wjVdntP@*2AOfgxsQ}XCL;xoEx|OW0u{r% z(maf(;(MLpsY3wc5)F&kDPsi1PmBRF9Qr99F(`9>(ReeDB6fe10PkFnN);(n9*<#Sp|rwyO|1;0BrJ#Bj~Htc7*=^ntmepmy9)SiJ(I;qs)phGVF##a5?P{@^-g&dt4Dv73lcqhYaIHJ@9EJisY{s$=NR;vsRu4X0pubNn@8b&Ed-JR)dYGc<(_eo`QS?5mf%!_68E?4ag`*Qf zpM+dLKK=1s9}tmkLVpX5%CYE6`0m+)@7aRy*@Excg0H48;Vu$Oub3dlGreEZR{1xLZuNhs%rCb>%$uR@s{*tfdHRrsX+Qg&NP2kJv{ zpc1D`$_{_$6w-UiWmu&Z^O57fsB7htywpV#vLu5#Us4;J1k_mKyt$-ii6>`qGQY!I zd{{mgpDX5qUS4v&DpGAAO;)5|)-P$Pk`W38ON642Yy2ID?ep?s`>kTw*hQ~w+)(4k zksl1P(O`k-k|DC>851I8*=Y9Sz{>0WQ;qCz%SV6q*NTy)*XE@JIg}IrYLLKT0Jy%uLD)>U%G&~1A_e9aOs2_-9WNE1teb!0ZPn@JZU{i;s zPSQdQktOGG;xX+PJ*Mj&!HN-yF4Dx>jaGk}_lwRsHb;V^vY$FOr=H23#8*7=Ob*jd zBOyhn)H6A~ht0~|3(&2pUObFM<_U?+pMBavYliQHrU=XK^^%1TttdKEJvo9iF} zzJ2`3o_0qa!GfzPpw&80wOZGy-s?82;JSa}0Rip_Z!0xkLcPv|fj5>}yFD1vqSxlo6EW&_ zrMh6xxAD`0M^wj*-v8Wd>;istV>yNc!I`cJEd8Pd4S3O_5Dr>R%-*%iw!R+>j+O_w zR=|8G(kD?g`*i$qJ9#qhfwQo*DZiZ5Zpd{=n?e4{5f;{-UIVn6UbNTpz9N5zzKxl{ z@I1BIfVX*LjZ}g~Xd}Jf@&xQ!%cg+-AOn#aVz2^2?Ad+KWuRn4ODDMtuU6iLH^{|y zm0WB$@4ft%#u2%7Atv@-z^>IpY>!tE>ps}Jv2YPWI ziMU9q>~)c(zn{RSkE@8Z9|3=n!f>G8hKBlH@fZuP)P962@$dgE`1WKy-2>O&#^ub# zCZkv9QTc>^P(OeyR9`2M1&v~w4O?;l;HBQT1~2t8!Aqg>8E_&p@NxMjl8+9W9`JS2 zlC8T|LbkDQD<|wpF_a@_L0zW+au#f}zlL(Sqh#$L`_7ZtN%gJzc2a+R|JmHVgcWmnK?)ol&2t{+B{_yF~UbnWn4_ixr2Xi0RRgw5c$r0Qi%9!Gi zvk=EPoV!t2%^X*=#3|o$UnaOes^l+h!e5Ml3GPq6W3>;VN0tl7w5cM?H~aI4 z1|UsbMOie1{!9(^C~&4Kkpi5CU_ABB_S@fPv`t9&q4AsU5j~L%{r#dQ1{-Bx99;S( zC@n1?(jM5P8azf;3Q{9Ip_4iZ;Sj5nt`AFHYP23~^4@|Zb;y5C=Av6ttx;K&Gn?S? zb~3X(0Nhj#eL9(q5%AwYI>VeNV5uKqKR^rc_an=g@bfq(@#Bm07*R4$T132`hW^}( z42R%09pT^z9GC*}SARxf7fypS1S{L{UbPa+B*}A8G`WD7^k^Hhm?@Y1vW1kD84gTE zOa!A6G z7jEqR@zZk+SLtauuDr2_>W}_t6ynHe9C#6G{OCI1rvyJTclc1{$yj>SU@2)1;cg$$ z16Fd2m!H9f+x!$q7Tk`-63EtHRx0h({d~L@aJFvBplpjB?osyIJiq9AsO8B1b%uYpdwBI zgVlKGWxl_U7SRpU2#R#sdwRO;r*zpXy8Hpn{e$Y`zFeE}kaIsh?b8#TAJftUJ-6*u;;i%u&I z;vm&fA~;Kx2)JJ1L7`|tY8+X?7&FNN2#lf9Css@xKm8H+H9g{vYu+5{s3>yO^{vW^ zI*09}sx7`&o}h2Z2@0Bt{-K8YU%rFdqP;3=E#BT=YcaHj6a32Z>{m>GQD1*`u}nWv z*o}_R0!lR;#L6_RqGAHzp8Ie93~Gmu->P;9-n{B>Iek=ccT4NlbBBhrbm#KOpjt75g_W4jk5e^^*~K# z@Gl6nb&NyU#-;431AGOt0}JfilA2{umCDp|JcXbFWVtsJ#|%_=F|%wqLts1uNyN3F zrT==wu5UF!f7vX>_XrIgtQ9=gUP}Z%SNmn>h^zo|;}2zWqu;BF$>e{2ZIHhQwxk$q zy+$z?fn$%ctQ8k)by@)s!(&PAaj!=1f>Wu)&t_h;9PT+OEu>Sg5Lw>yX^p(WTso0A zbsB$(Z)JHey&8F$O<<89Ij@mfycWsIcvDqIdWrNcdTr6-Ef+_P{%^p)&GhR}nu;~G zAj|E4(A55C;sd<4(QSY8_#VnU#0{W?VWez%x~)cN;anT4X8!XNigw7ukLbfk^6(xV z&`+Py-oMDhFKGCNJPgpsK6&V&Xq7x%qTeF&aD#pxl80UNah*JTLHjiE8zw_10EDKe zuC288=Kte(2IzS(JOTY#E(cc%v6;;nz_2Z!fJ$NhK5`zI%+ z;&?!iV+h!zAV+8T>E{QByZs(K?Dh}e9vt^}1_%Aa6H{R@$>)wY^r!GJq|n_KogATr z-TvX>{w`!oa}9mZ!&Fo+qnY0*u{$cR4-scxCsugCSmCqn7cZpm zRje5)$Lx<9QCj!-$-_`y{Urhv-U>uDAsjyqQFu-My%K*}{p;GCzWujh^lbs1_WT)~ z_8FY^8JzYRoVGH&{Jtr>`7U5>8WEzhQ4&jLcu9YeH6NoBX}*RSVSTE4$kNZ(we16P z6sr5Ghrlx{Mwb<}y86LHKkN?<-hMeh`Lw&ce{v$&D_|0-Gc+J(`Hf6^QC7xz@8lht zhGPI2M1y~t^%EX4Q#&0IsJ&OKc2Yv7?tVqS-lcxLzq^0%dH?+6;N9WDVKM^N99Xc( z8G=U6psH-$is+>ihkE9F9HX7$-dSGB+ns}tqR-vO>Mb==Ge!OD)BeeT6%}h}t~)#q zD-J{2P0Bw?JcA;&4@_;W>6Fq%`hkdQoP_vx+k}6}X_OAx9>FD}$@|mhnQjvkIBgNB zJF1rOxWyFu*ANCM*F0MH3ooCaGu46l^GW|uCn^qAQY|rg(r5Dv*BO4mw_wNOLSwPH zCx5RY@wMf;{`GEvZJ1BX4fT;9>|5gCU~K`eQ|6wENw6XfrRZtal{1C|4Ca8Bpe-yH z2a$iO?D}&Tc)O@!QSj0JBkCn(E~p20<)N|fUtAY@Pmfy z4=s1%hmo#mC^yowRuDzdBI&0g^f{JK0iW6YM9@j_5Is`EneT;|V1^2-zz_B~fauV5 zuouBkm^TzcF6;WhMnlulLuc$+Am~P}>41NHGI&qGO3{eUGUY0r(X9#y8(@xvNM_?u z4K+m8fv3YC#9Lx43e7MMRZBzJb{L0nEla954%MNC()x`5&^AD;Z^qzX`VSCx%T#P*{v#QK9mT$b_qQS`(D-ne3(mweGTV*@c@3jDhVaH`qC1O(!6k{`{0Y{`=SmyOd0eA@_w3=N8n-M}7+C*FIzbAEhuu-C9W zoBik?AG|v_Y+&!o34D)OdnSL@7Y!@GjSxrre>~+S_^*-i`)cwn`Rgp% zM~>0k3Wiq5M#E_)8##sgMqgwA5x{@O=#Aw1e-NWjlGn$o7NhrtaNBtnHb`CtYNmyh zg{3VdEbLXAS|5k}5Fti~MH+@m)VFZ7qCmYQVoUj?ou~nl4F^3cV0V8G)Pd?DOb`;#l?}beIcoxB2wAfCJ_)1*GFz*)66~5QVWNqxO_R~zLNb9+F1`n$Oevv&eG-rf zr5FW`%gN%Rd@m|YnILL8{zxItj;z3%hFcLFH`udP#jH8Pt3z!DTvB})FhE6@d^1JW4J@dkjnASxo}KDAInFxU(VP_RntoWp=JM+)oYZ?N|E}e^V8Q}J8aJPYGMePuEdR|-b~N~Wng2|7 z1@ftv{{&|f`Es8B!s(xU{h0rXucm(=@GZ?cPCv%zn7j(~&rNl4VTG7ke8d|1O1^~Z zv4-A~$0PMvi&3kyxlwhW{FPiIZSfkp-rnqjV8l~9?M`b=BeupHowd#ewKd-Cw!n6l z+Zu}(B2FsmoZI19A!tDF?!*Pg1z?fc+KPV43&FOcmoGV;rZTVSEU~r?K-((eX$3>S zi52#*J?2n)OO0$mX1KDV;?v;F^iG2_9-OIxW35D9KyP6(UzTSP6n_P=q1^RdKQNRZ z-t6!0?5!zCSuqHphhi+iLw6hi4hc;Z5gC*3>DLn{!bqO~!oNA0Shjy{D9uKDcGKw2 zZW_%-Fut(VCTg`isJ*(1ntF3hLk*guEv6vZK#fJVZG1;k~78Pm{bwx&~z%Yq;;WzKOatLKbdPfb2>8?fq(A_({yE-ORCTVgmAkY|KgImQKIB75T8hIROZ z#Da}!j9~k-HGd6VnW3tw_NjMU=nk65u>r_jdm4lXvREeY?Ew!qO;6U zQ%72iR#!V~RY%Q$95utLqb5B|tn@6g{@Q1WZ^}*z%X6ky1o~(40C9DdaOQZ8ZrFg8 z0BSCegsugE2IYS*@$D$ErZ{XsD#cg;K=A*g7z^SbHGlGhDZqUY*UQdY)5c@iBw`JP z(sd99LxPiY?by+T5d8!@<4J^whlU#w(&wZdLWY^+p*dSMFHAFBSqaN1NpYrQ1uep0 zXhbL_qWQM3^Ij_ovfRk95NUwnAzD2stztAUQkbuSG1gGVrsr#)BMayk6Fbz-=4!K& z`#EAhSASnWkcX=h;#^;Eb|@dzU0vH;Cw!3Zf!H_%-l*MfcB#+RdaK)BgO(<2l1ow! znXeILsO&2CLJw(J%e%Wp%wibO_t#e7Io=rFbNgSy0&>UGk9ZUnTz3)scudB(;Mj{; zWwJvpciMYVV1>~D-$XI9k}c#(+e%M8+X^mO34i%d+45M|iY0oPgsd!&G!1rnNo)%; zWUN;ylpUdQRtq6=PTan@ZznRX?Z~uvAx1!c(Jnj01I*$@X~{lfQMmL>VgGx8Voz__3qR&hDopyAu1(%a%S zGvE6l7n4u<dkqv&KAZT--MN8HT1bECneIr7)n1rJx1HxP!2S zq4E0l*oh|d3pnOqhf^zvDBTUCODCc-Wq-iMd+mhb9EYzx3`ly)#eCcd@XQYYE{XPb zY)&&`&m;m$!Fy>N&h2EnwuNUElTi=Bb0p`lOr2db{#5zkDGkqj)XIv3H&bYMhbZPc z)9aEjERiz;OHNP^mYo(C9H9jWKO#_4x8Qes{!K+Dbe%0!jWQZAYlNC_%*z;UcAJ|u4$-em&(77&b$WF2a}W+s5Kz#wlO3aQc6OT0wI=n{ zWhW|}o@>q3b`wrdPwi}Ow7MFaK!2(0?dB%v0X>!YYHR3%Bv@@~XbRs~J8K#mr)T#S zIg!V-hqtDu&t58Oc+&9m+sDF~eQ#aSw z*Eh9{+faprirPdc`rf|AoFO@-Zc$0Sr*5uxTf$YM_cQ=U_3@2%p5cui1aI{5uY+#1 zn*}!_-pxA<(ddBv{U~}nAJq1C?)`1NoqKXrqrEavBMRTMVEYZdAjfEE1@OaE=ZMzhj`h>1SAkw!Ugfx#8lS@H^*xbkBA;h=se*c`I&IN zT@aEc*cIA_i#3HbqkofCmnokx+ETt7G5xFIDj(?U?ES3t62yoNa58#qO zz@4-Q(ZYzNu?@BZA&Q-$?9*R#e>D`(52lu@AnJ7QrI9eFD$A&`jXNE4B++n;=C1n- zp@|nYX`-UV$)?B~eU!W)8Ui7KHIMvVhKeM0gri>AG04Knt5<^@=TiCGs~q zKJ+|L(q1IWDu1NxP>;KvApxJJ>*=<5Rj(pjDxQNg{v^?8#Ylnk2jo+Zr|Y_+F=#S$ zBx7y(>0@Nh9>@36b19D=kV{8A&asUuzkh84xfPdW)eSX2C(gT9ym9xnfO#CCb zP2+7Dx!G9x&?m^LuHqsVsZcYKLN03w`W9SOk;!Ni;xmZ+nL1VZLmEFYJR>Vdn-`%Ko zcZo|~rn|@^mt^i|je?|aUYxg)=TylEAli;#s+ZImZkHpbFUtxZUxv%Zj<|mnX2#PN zWy`}`Rz7!#WB}tfnwUe-zAe~}ljs!)stoe=8GppY7Ih>XO*_9@fL%$njp^EGiVLNA zW`N6FA!|!WlYruIXr+j#^qJpSSOG;~$Wx@4Ee563q_0s9q$PnR*FV4-LnD=p4Mv`Z z7U`(autd^|z(LBOlr4;Cw%|Z0IH+4N@j)`mhk$;kzLupmJ3`G)S~D|w3GePm8*=fJ zaDU9TLbI(bQr{o2Ymc9I?WMc+bjhxL^ zzE#K6U<9#201@cii(a;3&5-9Ly_V$cS%1+)pISF6E88|+ z@&4Yy@&4|hn4fHR2BsVBiMgL{w3mO-Mtk$T(JtL+FPChzga6`Y-P2nf517n_k7MRJ?9RVoO6f&#pm47A9>ClKGivQY=W|r zA7o!2?I1gTgoBK8%|?P-x5xLo$OjJFPj^ZAxqp|E8gEhJ@MwI|e~q=RHwlykRcag@9t;k4KAxWp zb_V+jlc;|(9sO#PwCcV2CPqYdE)~ruK}HBF(;N+vi$=)iBKw00k<>e=cS#;B^rcB2 zLVsjae3}4#oskD0tQ@&HpgPZ9E$K|ag^@l1qK+`&rXu`MkUBJ-yF1mPxwGfHsbqgE zXei+T@~PmRkdmCLNgDDi|20!e@4iG`UXlZj z>q2sPDM`!vC3~AsEr>s}8H5kAJd!Gs*MAC9N2Y&wr}}(!ijZO%S1_cVtH@0U^!{Vk@TZA(*dD62FDEj>*^ ze?tn2d`Bbvy!&*#Lu2*G-U_K1^i`6M{Vt|B$tO7x(hQDw4o`M=Gc^kDNNq@ys zQ(UnmW%^1%s%?gMcWOv!upAW5RLZ|8$gY4%ljKakNpn*8Gf6i3L5UGLFshWNU+5-_ zs2BHKu)xkMMx8&1BetG7;-wt1Bj<>z^WY-E9t6waOV7Xd6vRLW(>E~+AC1lOA1G!u zO*5!Q65J-Pc~Oejpm8bX+zewxB7bpJk^3QKE)p`A0*EGs$1z&(bh?!#29kx-0ndRP z{K4vG3;Yeh_+YiuCg=wXb{Fl!0s#($nCw^v*1O+|1FO1SrCITNn z^7C{Z;;Cn<3G~}0bGlDm{CIh9-@bkGww1JVG#ag4NZM)H?R6_PiRHORBipjAG8vTVHOdcmr#)(qN;;id)qffZV1x3*XmzwU+E9=+o4v7ubl_qX5%XC-&V+Y|YOtrN zf&ONP4uig~38Sg}u+iGURtEwWI$?A~W7nNf3`oJO7wW~Mb-bEb3jHv`!;9{aW#r~s zwlpi=99g5(2k?h3w!53F1Q%gq%`nF|IJRtO9vXR~1VRcN8&eXdp?}|*M}1Ys*KIN& zgVgQV^F8oU1{d^?V2_)aKl5-jBj1ZiEN%8%Fv8B3jk0#r@{i2TRsNB?x#l`cmf!%k z;a%*y&_DauSS0OIS^=Ia)GE91nl%3xYE#~AHsiu_7KeK(^r+i+P9- z@lEuZTC0JZ9O>m-YwEbShVlx882A;%mPc>E=ci{4Psq==z89fm|H6-a^d7rc7%s19 zCvYqmg_ak-3UT0!6m-D|N=7V57-GFmhMw5VWyW4_N=6@nfq&t9Zs4zX*ShUZNX3>w zey}&zH3g9!G&o_q^DDheYilp5ZM9GvxS~C@w$`Cwgbz8@_9kl3|7(R_=1EX!M@wHV z?a>44fR?Y;tjBi3nQOsR@m+`QbV7M;z13b_K6<>c$4CwX~Xcbu}Bc>S=X4oercD zR+92cZ?>!J?tfI(-O+1Q+-Y`J*Y96(S0Kz*SE%A6DY(Ptj=t+*+nG-Zv8FGN@p$f9 z0c}#To=K~kNN5+=@*V7CJJ^cRq+O?=j=sKHqpVJ?vX+c`OK(C4yLHN{L#8dgwH~9% zYMt_0`ts5`9qELuiF;8~-zb!``dE7rJ1+<)R-;SHiGO^xgqXwm1>tjBk5NxcUtg`N zq!t~f+g$lB-_lptB^42l%J#28`9)7Kr8&E4z$xDWgr?a|@toHXPtqz$0^ZI|2J!@H zUbSS2+L}0M9bQ{|X>A+TwRJdz)sose%WLCkSkfV2)paZS&#NQD-7HI# zRM%leRex2tS}_2b>bj3o-CAYK#rigu*2hOmI_RvvbzWa<8D*}OB}(dB<@I&S>)WVP zUx$xpdue@ZOX}N%qS|%pTU%P+T8;W>-?~dG?D7fhEUgeG=vB9(LP89yH7aa3msYsW zW~j14GMejUqt#89O`9+0Z>*3^&t{zpyR|CZTz^&}8Ld{G3fGoaxWOx2t*9^=t*QzM zfo`yxt1Bc_SXtv5AFgFJcAE8SY%QyCosZYj8rw^2+^kjO1|P7h8lhR8E~|P;jZn_3 zwTc=Ek#5$hacyaht%UZgs-%m$RkpIb>8{(^V0C|Um87;#jVim%npJj}RSDzSS*=rL zdw+SA$#MN^y`stvpQfrRVXnJfR`;?hSC>`U<YxZhuL+)FK+lU2 zi4P+ch9}yZfT2$$=$M!Ravb9k4zM@ms2cz))0kMH_dgJ35PJ(YO&Ku7 zixvU8D5{-~0{`ZgCu$O?71r53E5fBH9fitNNRCd=kf7256QdVR2DFmsJ0L)6(pf*N z<5PXpQnl?u=|(<`9#wsug6{2XD-g|?0**A|0Hn0~mSxm09M5J+!0RXt2C=d-QhyyV zh2mY+kdt5$5ua}XizsP$n081Fxq2_e08&Rw>5sNkb(`?kkZOR=&q?*?=XZC~Tmb40 zUaPSrlutUV3HVO5vciIAL`7;m0ZMP+n^{1k5mB%h>_ihB0Im$=1S3h2Jhuc=;Jsxq z^%03r%0CkSXAZ_xF41Gg-ikA;ARtBUL%| ztjM{-jiGPjGjUD1StGWU6;<&QP??zu&^D5_5oz0z5oAU^;}ofmIHlD~?*oSO9H6g-Mtu!cv4$(YQ>L4qsb{i=pGsp0S1}S0O&rkFQnGYi;3bP9Yo^dzwnRomJD=MGrhk&N;*IaS*b>Hq;@k8` zWv2zpaQ_2ioYLr2m4&Kg5PxMRH@=N{08Ys)Zh2<0X@M~F4vQe}nSmUfjyHe?X8>{{ zHV{{t6)`7M$6{cQ!Tv*_Io6$ED~X%RN`*(m~)Mjyo%KP%hvVV{9Z*v?*q(&ue ztyR*Z>+dn7pS)S%gUtXew0$pfqT76Xa7la4zejscaBzi#x=q;s&XWWYL|kWBdx}oJ z&lC}Jp<@>P`Z35}$Wyukat??E{7Y_R)Rx*OwMF}+_L7B1HHRhvbYIwxG<2rL`AAdW8CP;pA6K&Xj4Syd zT*>}l2Ul_@L&O7uE7?o%BB&-v(FmhT%$DHRhd4u2!s_KcrT`iDB5Dra;H z=poX|7>;CUEC8x%78wdKR*b26{WXMGkP1WLdj-U;NK(XN)b72EP=KhmJj*UxSoLE2UvIjyP5}X12Cc*;38^@A=6O<5cEwUa5_?qM*7pz z(mTS+3L{SJMSlUfKY0>wri8DB1(S!Y+$w=&ceVpP6k>ex_?RAYG=m>Z6^VrCm|7Z` zD~LUHqe-BxRok50-O)?3CY%v`T(*3|B_$e_hKsK5B%na{>;FitkFZTRqYZ; ztRn(weJC8W$8;8XXmyS3mXIqn@u_vD`hd6{(%qL$=zmaKK$r?PHgQPy>g`CKYesU) z;?Q@musUZ!J zsvw+~DP__S`Xq^bcC{rD>ysRBzefryIhkIU}{T;+!_mSj|pK zw&XcR5Pu9FoN~c-`1CAsleWwSjD-=ZO^78I_}50LwlqXP8=>0PVkEhaa!x?C3MY{y zL<3A`tRZVlCc={-b~ongDMn!5F3Q|2D&Hs$?mO(!y1}K`aszDHw+(!QhjZ9RbcHfh zTmF^?bPZ*gEd=L`W42c;FlY}L8(^?sq>8&cReyC%{z+R|VVp{!p(a4F!oX=OD=$(W zCP3C{>x?rleEhk0VPG~91O&0nQ(7%@=#o0q5d36*hfNB!)G{2?+PVm^b(sxo-|%%p z1}|T7rwgbQL6rn^i6mY%(o}&-5?JPG^K1)DoE>kDX|i?0GJV~jLG;;~sv%zoI-x(( zq<`G%nUK0;s*Xw1X@aAGbLy~PuUcoov#pt?3B9_zYqKX!Tli)(DK>USYKMJVSy5j& zcX!ave>&thJpSaIc1SMT719klB9M12$;-a~1eBhphF>TdL&)KXN!yvE?K8y20T@k7 zgptpWyii+M=II&=&wo&0HWT*JGaa)Dtyv{Bz^K_u7i==A;AoLL zPp}DYf^F^_agAl8UcSvnz4T|q9h67D%tRrjkw+;r@zw%H>sBR<49g1#&XOeAkfrj} za7wY{yP}Bsm;)yijubElrjUNG?xL4@{PUouX9<6XzR&^UWlcpk$L+s(%IE z4h39PcBE&Z3u*!9a)Lo?!ZKq3!m z!nHZv4h`35xSxLDj3I6pBH^cYiLQn>;8Jx3eg%zy$D+r&L_Ge9s7!!TajXgl@h2h8 z`;v$gN#gfu0FC$NS5*?Z2_+(oFMqU{B#o1VEp+G-Pxe-4q_&$~64{(eBG@*4+Cj+* zJZ+=MT*PNvd?O}DJWKyiv)ydMm4*KNsncv~X&G&y46FmctZJ;BHk8wCHl=lUB>9TN zOZN(3f^NwOvywZs3`_Jfv8k) zat(A!60FgNY)T7Vzh@Ws#V)SrCt)=+?3?liZ?Faj*#@7h0c-H4k=A#Tj7_U)@RpuI zNK8#zMyo#xg#G)n#J{J6{d48?{>*(jRT0`_M?O$E#V1FE=)n=5wU`%#^v?`{_XdbtBJQ#8guvXmrSJer5$B zoal_32(*O+AS9%%fX3uR01*jj2*}4(qxT`C4vlCqW6%uFF&od>lz$GRFnVM%z}Hck zfkSB+eLDWA$YO9d0{v54bwIPLePczbt$W;FK ze}xn%iakA0LFi29fPZt>9RDH>Ujid7k-~=99c{xuQW@>F+8z{fBOkFyl6t}KTHg6%eF}l*o%m@NTiSa;XG6c zgSXjT>vV|IKA-qV)Y)*I2C|qM!vnAA1^AysfLO8)hGZ)w^AJfzb1;oVYE1w)Ca`Q^ zzu>Z+ks~sVRm1abtTzS|9AF|8@EUXB3xF9!6AX4|Gk@2Cz>xMBhafrEw!&Ahwlx1V zJiEJdReTzrp^z{QCpb!&VL^~VtXqJ42MXsF50sTB(on}#5Uumt3Jv9DZkxu!ZP76m zCC>C__jc$y!-kDPWQe`tt@6^*VqrLPy?+ayzL}otjh=N09StyO7-oTg<=EJ6fE>#4 zu0TF#lYfMv-VnzQ7Gt5QbV2z5Jg|U&%@<9w8;s03v+cOMV?#yGG*ca!f?$56ae)Es z;g(GzG}%5GEZZENzIqj%ZMmwAhNLuG15m8%30#CCEnpWo7%}Vg)hp0|iGt`{EIrl? zL^Wuf3b(wU0-`}d1@je@|IO!3M} zwtu{g#aNs-D@!!AWGkr`ei4R&gkSW|%;?lR)3_Ddmc+94zJ`UnM5K&wBJ9~=gNTqC z%1d@%kF=KxY=aZWI~=)tw*`BEgpzqehks0tU>e|^)txDa&XfZ)<(vsd$YuAOt*lus zKmP>&f<)@X^%{Ulq|W9)qr|?FMDB#3ohF3u)Kc|2m?GW}(Iy=qvJospKXiTy_y9XE zUuu~~!Pq1UwzNw#R?0!RpP1Pt9iw@mFQ?8K=>S|nqrVRPO>Kg6w;M!cW6~R2M(g5j zV}pNCSB8Cws3a;?AF1Bmo$8rPiKJ-)q9L+`ddOu34)D23CH>_3N6%_<`x zD5EkGP5UW71~knEI(LpH=L6V;H4!wF@Be>4S>z0O5v;7x!xiv32}UPnlhY%B*!%F) zw22%*GbX4jSGDLckko-D4H?5Sj3Fg z0CycOtMlRpweT;EwrQ#k6Is4)HJf)$4W$B1!x8NxnZ%R7L-W8j!1#<>R(?AENO6Co ziW_0xnj*~vG-@%raQ%xK1;KE=as3PRG%fNBEFOn0klQ>pG6KXs zNr6_3m@SUvqaUL&j%1EH;VDQ_KKj>OigFgCi51FydNK)tQbRCXN_ep$ymEAZhCMZ6 zD!aQoWsJcp1ib)2H{JJK-?GJ-cYuFM0s#u^HAQp^RZS1@%mtg$*Z)V=|FNwZr~l_a zC;#!z{-K`!C;ZRJ**~_mA778BDDO$d>>498$~GAG4D#hPLf)B%0L#!M=!WpmO9d$} zJ;NhdxpQCwNNb6(-wcpL0_*Lj_FraV|7DtlN#`Hnrb)Y?fqo=n)K9ym4%2_nr$gX4 zL4{(gkq%a8)RGd|k8)vV0I_j5yPNGqu$W({u)(T|=kMWJfVs3c^;n@S^oy3bz^OFI z<9W$en9VLqL?Ueq5`n#MCeb$BZG0E&Q80&@G}+xQ(6Y26T-bvcb=%!_ zBAzP%Hb-Vg3YzAMVzkj+U+ZLLuD|%fC58gmSKFJ}PaZ38$;~Ev!{jRw!~W`-%`LA8 z^qELbg3KLmD|5dKw1{(3>7|WaGE!*F7_GKDYc1#~2rOG`&DE?Erl*olZyw9lwYANrZ0;Y=obQ|4xUsq3-jKCXpgkZs$#RJZeLt1)#S&cZz=l(|S~f{2KtSE(mHfqF8!qPfc*6j7OfQ!Br|EQjXGsl_b4_ z7O8(;i-ZjjHlK%$ZD*s~S}Tt2(;*&zGj+6@-A*^x1AzfbO3zBvwllwoW45XpQYqU~ z@MRHcIVPfjgBIQy+pk;z+OW3g=GA1Csm!8w#Jl5--jb?v-C3;nZUB?++Hu(4Q zNq^WFsooCv=j3z%CW7tWY-h+mGAzjkWc9qg^oyBFKVh zu$U3^qsMCUT6d$fR^$*;|9LEwwvAJ0WgI`kdR=X=b@Bt&+F0A%(0KA9$0VWBU$AxA zvu2vWgKwp}H1>ZLdEzhbm+wen1GYUQ%DIsXb`sIbN^W2>-utO%KL=2FVVc0ti5h?x zc}Fc_VA+MrA=jdj>aDDJIUjwG`{+{z%_2s=DJA_x=wF6spBxAwReQhyvz9=!Ly6Wv zt_TU4IvuQCmxoyjHG|C3d}T!?O6j}1Iqb$-$w6*Gz#4zeuuel@*Tb{K-!COAM8=6i z7FZgx1oE^VNS>SB%?&B{T;+7h)IAc{Oa3L}fGP2e!;i4@ciZiaR)OuP;|>|lK+0a` z3Hf~-A-{bmX|`L%J6ChPB|Yev11(>9Y{4OFZAIKAYegjUm+IuG=WKJ!`N3Jnf%m^S(MdqNld_6;?}~V88t&Yp%CSu3aUA2SVsYjI4ZYHy8qHl*K)P zsX>-$od#zpHvkX_D(Oz5<@$E=*z9g@E;(pOXb5s&)?~(UIXs-891kbKQORMg6xQAz z4jeG+5f1jSF@^Qxxwj22XC+kv7nN=~>BwZaiU)sgbHJhGnP%ZySetDQm$1zhFh37v zk>Nu7?f3V!R)J{)5e|(OLJk2MEo5V@1%X2#S_s)*HM!C=AO=eHOXbzc0hU%)@C*K&?sO8^r9bfIMCQ7N5U-{e ze(-;1^}@%G?S;=SCf|Mpwbr_oVGOsj!Kj#s{snO6Kdp1bumcviu+MGM5a|7rXoaBJ z_6cmd**Y^7_N*XKd54$=(ztMOXtvKxMSMY%5I4P^A7Ha{W-7@q`Z2)dh1oqb74}R& z%zW21*Un4@9(Y>IzBSiLO3S{bFR7wvhoI@pUcugHHI z9QtnhGSzu|IJ)+OOY(_`Ca49u_!?|HT-Znjyl*iO%on`;`x{3Nf%=0UJc@=|P~$@caLvGqqbBJ7#rx4^w+!mkE$FBp8z+IpyW++B6+F0$hDt#(G6#SD|`Z?kSWRMQqPSr9?^xB-7ljD#rf z?o{~&IhO}HT<%>cPF;X#z64gURS>GdDq#^!4u#ofg()EA2d|WFXRT@o`^;|mG8gJC zvuVivz496|SWnzIDTY0<)2`eT_YT>f`13A#aFKPwjF+bYYgTw$m}0sog7Zv~y zl@;X}Tf^v(AZmiRgwWXa7fpZSgXdXS&KOuMAWeHdjKFHHtZ*=i_bd6hvQI#MC^Y?* z753W-Z@u9GWAD&hQfNh^sdti|INVS|Vh%SkxP;W|@jS%A&KL?vU`W4)wm((i&KGM$ z&*hr)m6aF67_D~JTkU1`L!x5(^bAF2vrGv>G&va+NQMbxQdeRnk#2weGVd0gT+Z3m zR_cdC$p@2q_}z~%Y0!)S3^6q1aqh%V?Jru*)o#1e244ugES%Rta$e_FPsYDOJ;mvL zTJF3LLrsHIZu8E%= z-(^mszFg9PLNl>j@V9G877QQFt5_*soJTHF7N1Fx?NPk>^a2N>uc<}dAibALLk%%* zOrmHO8n0iEooF(@09=UI7C9yfFZ7%H+Tp!?HM547))~ySw8SU9LaoP8;l%s2fh# z?1bBH@flZz4Iz%zz#QJ)sY43JMfzsiD(fVK>UDkcf^>fY&MqtP;5X?vyr9=ETV+E) zeQ#%`%&&gz`WKcvASUp4cazcswCpQ52bX=LWtV-Oh&O&!5sdK_P1V>^yD*jWa|KP! z(+hNQ#;zB8`=7^YYWSGNzPuB7{!wot2IYU#~&!sn73#5GZpLn4LGCI8n95`O1n) zeMKABI;)xVS&R2oO2C)E+%#L=jxf_VX`e3j_vn8_M8zCHv6OPRhpKWxi8)o{)Tyoyq@~>rGROZB29FEo2dJRB{ z<^HFSpv%y5FrklZ@sa7f1ASlXbk^2t_5F|0-W6x7y}HqEEl05sF-^LwYh{Qqs`KBY z@gRRTC)B8;)kMD8maCY+h4A#O=u^nSv8V^B`<$YBL}?hJ7AW4g*=I%9^+u~P^#fvr zGF3Dq_-6||In&Px%?3zGQ-+GBAs9d>GXQ5o|Ls(Qf={^vhyJT}Rt`WEZAXUWHP#(3 zoZ(@#ojh?2;p~m3#5bd$8cbc7{&RoIj00XHMG-!n{YYNq6o-*?+sbTLDHu#%owy}a zZh9*#3b6QzTG30fEn-AA?B#pBlkD*im3C(2?tqE%HPq*kx%w%!_zXZ9I z4Hm(j2qWwNXYcKn+eo%GvFmvYux1;oI!r+Xsoz3Zqtz1Ct=$r-7ODP&Fq|TgAgc*x zp|cXA*Z>?84u>DW_J!@R9kzcjeB}#Y+K#Y&wS6;hF)!d(aIBU8RavC8d+!rx#-}4% zL{(*Ft;}4RxpMt{iwg-L$Q5oWWz!50yr;yLI4&Y4z+rzagBw1`G8G%>-gnLl%(-2>T(-Z=D*Fh@>TT=xX44E*pwJ5M~-q3;4ZF zj@bntKiYe;`>9B6zzmCdA>w=Q`Fpk=y=U+F_}&>r>E&vBMT|2Wxt#R}+(yQLXery z@)-$cx?T5*@a%3Md&=lBVa&nA*Fgw2gfxi$h5k+Q>`rtCFQ^4T0K44#_fg|^m2L6$ zI$y8BUJZ6OBkF%v03-pC_|S99?F_!UEfTWa&OjUM+smt8^!D<|3GjWi_uxi^&hwgS*0;K>4xYZ=Pa`n>MCAG5 zvv;re502C5xv~sKpa>&P9p;u2>wju#moIy&(r8dLFdzmJbn9(B1yY4MdZcX zr{BQ6lcP6p_n$&po}a;^BXn_&$jgIQFAw%lbh$Ko387|%d-W=f4wmz| zy0L%o?sXc0Q?R=6>gCaK8oeqiUH#$Lf8Kv~oGKyEyLqB|Pd-w8`26Kt=3$??x`)bLL+;Rt?B-Gxuen+JynCqRFwE?zPqSUx*?_U-=br(RDUP0s0M z?)IbQBB&wEN>H80CC{F|diu8c!qFt3=e%B8wZBM1Gu7D6u2ZmzYVUK<7N9K>TS56PKQ`RNcDQn4e%GL(ODejGl z^M*4dPH8hDPDwi;PC-2$9u4&__Q>#h*uExR2m1H-Zd%#DRhC$Z**ABzYEPa#dblUe z)u@vTy1uuad_%&5SGiZwc;I+O(qOZ&8wG81og#aE|tk-!SrxFl^r9qKxoo_tUS9r{AK17WSwPZBdGF^JJ~ocA(;eYyH`;8* zN$q4dcTQ#iOgKSQ@F$NR-Z-&;eo>RzZqT7f30>(*v{vajKN~i0rO{VkIhWvg{OJCJ z-3B~~b@6tP(C@6Gr~C8bEJ~yIA18kgBN9D*{U%DIF8s53e*v|}-yXg_kOkrLokIn5$vaC0^uara3h2Oh<}1+BpPiSXV{&^2uc7KGl~kMpdD8-LoAG)E^-`zp@G`Y+hkm6_>)^Xo z$g!M3UDUJy`h3RoNq<*Qa6cuk6g3LD!egr+~^* zH*^O4vdDQZ-^Hu>vbukiEN}{BEx?6eeh8@gZ7JJ;(~O%gI)yIcid%5jRcI=ME9i&n zTyYtUQng(4#k?dCj?7fn!qi+cM{Z2I9?F7@_qvjOT^pbhHDZOyQi*IJ_A$HrWi z40eTPQ{;n2L-cL88Twwc5%?s~1iXJ+19Y`D^5wfo{1v4aA=>eNgLHM*rCi-=5)Kan zbi?i2$X0)K)~Loek?3iDU8DJ$R)TW4@6lY!JBnUWUX~nlkp{?}=GOsgr}_15#L7?9 zXodHX)bnzQY+ma~yd5F~9t7xs+qV&->a0QfDJ)Z2fMkr{URl8YNxR^AINta#H~SMiQ) zgIqXyPf@PPGYcc{MYpVqBJ@#p*IN&T^I2~(6z22ZN+@{MyKNbib=KEFc=NUeuoqhX zdX2@e)>D^dTTemJn^vuhzz5|`Z_T=>eemj{?SoMCKfD!3t|_hjcrN+zQx^=qAhZrz z!LWb6+h)3+$!+z(BWxneu~Ywfj{fr;{pUIQPj!yU39A0oD|27VJC~)j=IU?!3Tj*^ zsKl1SPIdVHHFT0(X#Y681U2F0O_}RiC@-GG$nv1c~qtX!=i1uIMR52A*6Z zILgT+pPbW^6U`U!-R)eVoqX_M} z827YEr>zQYDLEiM60spMl$S^hL}Wo!*CEZmY=e7EDSX?6gbYF-bTHkS%1PMoN+=&# zTmemoJnnJ}AnE$tfb^l57CM#KsC(dfC8-L z2p!cVkc5awkdH4G$=LDJ+eP{Y4f4xwck4g4{#Ru(C^PhByCKfJv~lJ%`!WZ9gb`wH zNV|oB#787N$_3y;7Mo2HC*cwqnx?Za>uKXcg-ewuZY%syg7dW*oEcg9abSO7F9drx z*z-dbo@IVqZKG#x9AnamY#ca&k-%T;^$T5DBka(`dxkzDLm?ACFmltF4)>0zi_M=nl! zVF6e@jX?Der1P$#o&BTN>Q;ZJx@IE(NYIag=3wyNroCdC0M0NCx4G0D^ogLUB3uo} zwe2R5(WcS1o!OdYO{}i$rRXN$WV^qVQ)X3I_leCR;*{rQA2=I^IAIGj88mXg}TC-2;ffJoxZ&e;0q@|3c3mJbVIK zg~FBY>^<%$WSIrq5?6qu5_(Ue49$ZNAMHKadytS>OQrLKOv8je+J)rc=V3}8J=)nz z$Rhag$)iV)o+RWn_;B~}gPk46q2aP63!D@-1VReIQbTwq(?N?|m`ys6HqP8Cj5kGd zt1E^DY^a1LsfY{6dyId6IcM2roD9w|-_AZDMrjw(>~f%D$&od#!yWzb{^KW3%dT$D zZ|6o})o<}+1^=iWn6B3vSf|^y5IbdgQ2El~&W=Mt&8_ph$1 zYMA!6?8zxm-&BA6QWG&J{ha%E<*4Jq1#?A7q~X!@UP?^!m}?Gjomk z%Ec|oWsW>#^N;^npw?cT{vU^;{ySk&8!BHr6a4~lTtDK!hxqTY3p{Z6$v~h-|5SlM z+20xn^hg1LLQ|h+qYvaNPRN+Ng5~G5_pSsuBWGqjtHFOGEqbqyA(Z}Ayy#s{6%c^R zm-sq<4ao+RL{7bzfxM*8;{Dz)Z^+YRgG>DL>?QX3L3n4|+k>6$P0L<-kdU|Gy|jOS z_kKctZF%o)LSBF*@&dx{C>L3Dj$sEcdR4*B=2VoJH4W(cIeQZ)@vm`0UL=EG<3y$x zlV|g7ozxAr+DI`lcrE#OLe{)2F)}4MpCE~yj-EO=? zzUvil5m-R3JHG^`OTAU+z25=&OO%|ZzcoATN7Y-hl|N;_V8wrKVbs0*dkOhIEK*C9 zMM{6ePXU=TAyfnaU^Sd8!BtP4DhLN&q_p>461TD%?>#G71xHB9JOQS)+0h_IHe1Ow zG5V8R7)@=@weoC<=xk&qi-0l-4mT2uCf*_6_b$FkVng&DiK6+2m*6kRJ6E~P`o4g3 z&lGc&K{>nIbzbKev{NlP?Oc~jEC;%YYp{RktFj-8yd%zOCz96@VE!z6capUE`Q0Z? zM&>LsFk<16mH5Hd)1AAh1~-WlAwi-hLSW_-jTgoM$X0HNGNraeWRZJT zUCP14;S@12)@zxor2*k)#H9!_*^>T+uMKR z&1Ul{@{MdQ{m0Fr)l}zTq3-;>g?3v0dl48zt7c>jklqN5p;8I@ z*Ch_by)KZ>xi!FHL+B)!%4r!V-L8&cl4U`2ydiWREI)~9GBo8N6e8NDn}Muni%vi* zT2cN1V?1H_)nv1GHEg<9P|h7X%jkbRj?5~T5IV&>Zc#$d@g5*G6tr^D`sl)4VG(6k z0qtyMtSvhhYos0l+{!|3I9_fxgX7^0_o=t#+G#rQwo17rsyJ~-lsuy6V>vlwfrNNL z;q=(~gsUs^!p6K(X9&UziFeP2@();BDk_ePOIj|4D=Ntb(~Y~@eSr7tNwR-cer@+v ze!cS01L+w=x_MPyyM1yp0oGbBYGyWER?S1z3uH^%-v%oCa4?08h?4=}3+ZuQfC^&C zj8qsU159?MvaV}w3P)mLwmP(4$t1uhlEWz1l+fPEZ%ewQ&NXOOXckT8WkshB8V)`2 z+KaCt01#H(Qj1JvFbJ<^u;+j711pc%xF^>P_=QVULNo<{sG#ag2HV>#8MqDG*Xxk; z%_U>7ff*22)9Qg%Z57a)9QHDWsvs0lmUP!B06<8kDQ1a-lc3aIfNO zU)6mJ&IJH*7^UhhTfZ5$9EUAWHoD!JZTAp)Ej2B39wB;*-`g&a9_fGX0VWG{DBeF^ z&SsR?Dz>94p_HV4PACC~nKRr5YLFk^s=ckKvejF58`Y~D6Z#ue_zG*9nh*H!LMH2-1%TNSGi``JYlLu2pR;u@h6JS%6{p zD+XvL`&C#mT^jVb25^64ob|x%3umnTdg+xUn@|a;2>Ix7GnZkD`n{IWMa!B_ttOC> z(2wo0uj&O!>;mp*a)bAPj4Uz>qUCtV>ql|34&`7)Ai=6opuL~)lEO8XZ|T|T(%$l( znaF>v*PJ?=eR$l`hdSLgI$pWkV<6-8p%ElH6Pf(_l&Zws^~`_QgO-%9H&$wRmvSdK z*s0WO=qcryxM{2dENpQdZTd_bnruJ?<-r_yAf*IHHFblgi5{@jjeiF8e3-!(v7Y{x zP~-^ZX%NsixIo=dhms`Xh9^fb$LEU2wm)fD{4#5u145Lna(AM~fc~!mBAwogWk|cy@a$ zMFvyEF102{s#$Rvt|?GRwbgBtE(c43=>caVGP6v?C~?g~Hi-D_^gr^|Z_Y zQ_OH<)#&I-A%~Wk_-pzZ#lw`_t7^@6inKa=ae?EOv-2dss-?o(aYKK$jRyHx+|s|f3%VMc!;)}%DM`z?P&TtszP&w8u;VOvLqc3Z0F^EN60WPo z_h2!Z=i>F>Z>9AoN(=8BFx=6Y+_tr#!mzRO=2lUvIysj+733Jh?h?t31IKR~IDX5( zN#-n!YhjfP=$F|J9Jc_HZ~`ZTenLv*@__=0t^R+iPpLW_u7q7$ihA8HSPcqu%;oO% z3S`I#rs6TezQ0iiwr*gb5uJ_$79ALDNT3NlpEW&jLVAbuq8h?KsguUMDGdsT&2)a+ z$mC4{RRx`*Y+1)wcGD`yMY5G;MWgZ}T)FO%%NRiPiWBn4 z#j}4pIGCY|@L6L0WE&Ow$5h-|)u=m4TT*0{$EL-}U@L}9?vRS4WOSf64<>aT15^?r z+vhSvAy%i)y!ExYY3&eylwM!S3`!PD66jxz}5e<#<$Vh+B!-qvVW1G-G^tG$=1@k5|$)KQf8Wnj( zSYllC!-{wTVGBa1^Yfi+wNcBHP(n)w9omo9K2HF`6>X4h&(Wc_mAJFph~wzCFZJ^+ zwuWP(Rq{3|X_S~OClZA}rBiZVR^lxMCsO3(l%8#x2@$0x|1j+DRZGQ2pSpu52+w~; zHkqTOvyjI7&_;l!vjBo7D(e8GSFNAg&J1h7_dWV+9K8TUl1}cT_LsUM5_Qb)DDh$a zhfxRqOgndKc>fA>IJyI<{}DLE0cQF^X{)L_Ij5a`J}SUq^2qN?m^2Yk_Cx3 z4=h=|&cD{bAsXRdTL>^|D_0GL&>pJSJajvmUw8VZ8URI0!$jPF0O-hkv@>?PIUz06 zg(hU>FpZj3nDkb{MTY@b%^0N-c78-E2TCgi5o$iK= zH=x*cIUJJfdRCNIDChc~7NfD8UIP54ZcN80MlNHHGm6WAt^Jvo5kpNEsp_wxyqcUB zQe|IjWvVgp?Z*afb{oBr$HtvNbi2Ya_cj=k6PQD0e#p6JIFh++!^!=J3E@%&R!^LP z;Nni}Us?%hb#lV#EDfdBpwE9DLCK&zhEf3rVZyOucSH}o{KxcA=aaNB!OpC$=Zkh& z#jW#=t<%HFH8nY9-#TSI^xRP4U!B4Rr8iXYg;UT$?+q3G*(qv(fI|hpb_%-iyrHu1 zoU#_(H&pUlr=$f24wd|qQ_^Azhf4mgf%4_K@7EZz7Sb2Mn{*`f>^pxz|C(5dwaOj_ z<=@KkZ))YW{Aqjxkxx`*6%SRf&fv3nfEtN$9#KRkNl}#0H(cTXKZZx zcaG0NKaXgcT14(dcZ`1*yXvMpQKy`BV3a%29kcy2nPlJ&fQd(HBdeAR5QXTphoMm> z(Ws7yf_iG-tH4#M{6P7nyrd}6cIL%pA#nHc_Vou3+*$sOD<;X7_NE#oxI!l(*#4Y* z!A*hHHU)gg&<3tY_Mp*t-#M=$U*#EBW8w^|{{c)MAuzM80o8v6;?2(0@@-=U=QR?8 zt-@Y$h~Rb32MQ8Gzw>1^FicBh>5thcQo#@?4@3o<%$JDtSX~qgfG?0PgMd#5__8Y4 zE+S(>zpJ@9x@f=3zAP{*6;z4(8~zn|5y?ZAcULOW*Xyk~aNFegwkOwVCkMudGyGCmYKmDQT@_f~uzt zSykY8tWt-i0gv1t43GW*=5>sd{2}CIRnJ03=x>P==uUrstHlCHNkV`FR$cvpE=F#f zLCJ`NtjrHCzgh)9_~4-*9ibZnnPNTJ@fYhDdGiboEc~A^m$|n~1m-efZe9(Cu%A5j zU_LMMYN-D9l>e!-0yr=JSs{w%U_}04a+Pa73gM0zsIa2ApD-3 zfDi~@0-1lIbdN5kgXvFknT+LL%7^NVRwgOWM&)=DbT{qUdJ`wRqP{1UiZ;>94q0Y= zP<^p9312MHOUNBI$*|${SzHp9^xQ)aQSmNy8YcR~6IV|D-W35cSwcuu>U$EUcg6@6 zM?B1?i+E66CU^ERwUj(hV_@F2qhY~K>|o~&<>!C-qCyvOM(GrG<13yo&@UX1ehSCC zgTN@!*>CfxBl5E$X0T50-J6z^swY!dS0bNWIH|1f%01%Vq~x@BE-vT)^6a;{=UpDA z{Qe_-q^l`Ba9IurccIh%mg&EwA$zrHNw#j&lH8FA1~A=Y$01FspOqq`VAyd5t$H0) z7^HuWOhv8Ko=xm3(PKar9@VkFqrHcXQAXho}8Z=C5$hEf2;Z6{uZ?EOS zj=!Tl2(C5%o-Q;YvLEz=;WqB@I) zJRm)*G^H&x-CWUwJ)aF8qv>NuXZF=;$aXLzr$hRHeZd=n2So6QG8Ai?5>*#VR&xHEg^^C)NiOC<_vLDEgt=D3`jzw0WVb7}I25p-0eVwAQ!QGN= z0VF_AJJQi)l8)yN2*4q^tKN0awfEii;7KF3rwh0Pv1=e!erV*rvaV)ulG4XT78EHB z(h(|gx?TD^m@-YJTD)`%B{gN~BTIkg${h1kTSo;d6Jm`gDL|;`3w&mV8Wh2)V{L$I zg1wp29{$}}_dl-`jH7=i)8d(RPLx#)>0YdUChN7-A*WH~H42et99!N<>%JrJ8xcgt zs8-^^*BFSv=~Ee=#%hw(GWFg(OLo4rxr&RV)l^f==kzR}8x@KJQBb&2#qNJ2Co{Tj zrSP)uh@n6Xs^eZca|6_cyPJjVckmgJJCTm2my{a!K~&G*;MHM!9YpX&NL6*b+ezl@m{rR2n$!_-j_|JA1UMvXvr64 z-+UdT3mQy4LLbF~%3yz68=(ysHHX&(Q?4cg{2CK~3+{Gd-|SuG5LJH)JYU2SKzo4s z5m*#N7Fl-(l3;ZN<(CD^Q62&|C7rADVshTOD&})3IIyxqXEQLD5S}E251cUz3{Yrf zxYKJv7nacIv<#H^D{93l8K@U~+D06NS=8}fu*V{q1{O=W3|p(PF^GZbAy*9lJw3(! zX16V{siHGpo7o+zN6x> zQK8>?`h(InUFPm3A`CYrv$YXXwLIO0xOuV6R=6FH#zc$E=_qpKyl6}UqFg$Pn7=bR zf(a(M(Mov43w5l7fBl}4xjp~?m6rmCf z;8i8%MhkZfy*hB%Z8Oj`CcYimKKE$#)ja74+xM(wQ)PL-@!L(g_O_n?oZ7Wb6Gq>f zE#b;Bqr#b zS{BebMpYL>A)9|()ZVOT6h(Ho2a8&dm2OH=Z!-9KEZzE>IYk@a2r)`1J!adBg-$xz zU|!R^wJfAk9`>iUG4+mgZb541CoqHC^C|pup3%XyM7kE_G~3=TK^ddf&6n9}w+lp7#!fVgPf;qGWN;pu z>hq8~lh1!fGbcy-GMkfmHtj9SMVydJe6L8B*-`<9sHk^+Wlcr*YP3Iwgzp#f zSARSx0NCMfc7hSxD(3KF7%z1&!4U)#oNR9=>2iN`G|nzIn=<3_w2yuRKq#pImt$Ip ziWK+|M~3i>_aKP?TE=A0&4t)&yi)>GJ)e!!IpF| z?{;U>v^J3@=Z_j170m5EPb?D^NV-Er)qD3%0(U&%T#Zrl^ys*AP)@0zlnWhf6R{6p`R?tgv`l|Op^r8%#%b$$OA24$o?qFI!#tH z$r=OQyp3_iG1K8=w;NZo#iI%NI8Mmcsce^R*2g4SW*-$ZHLBcfOhHLC1v8}-KtId_yfGi?J_ zDj9_y!j)%65Io#`OCM|55L90I2bu!rjG(;58M3hYTZ3egXKYB-+tj|DCoMo2MhAbK z540s(k{l>o>awMaej%nFUW(&Bq)z5rY`xyn3fA>nd;pIN`hoK6fP0toJ}S(MnLa&W zpy43k_@_LGaM*`&A^k!1P1ljAVIeTXT@W)Z^`W4{>5Os+=0p4BSB`Ir>#N-{*TETz1p#)M*f>|19pV2a~7tT;sXuUM~*D;8WjHGHr&I1vM2EYN@RowkJx z;MXnB8j%5c)*+_Ba;)3!JMoXecaxGsM|UKC8aVt}Prq5o(cEX*kGJz&z3%&c?S;j_ zPS&8MKuWvasF+F1lFQfzN=9sTakNl@+RJ^76lsaf};=(Nwi<92-0|!?zuddnTrN;krm!^+? z)s^5hzjU4-`_B<&@N2~JaSFZm3oVL;Yc)DFYZn+e!z3Aa&RAr%P+%u!9wY656~mRZ zhP}Eg=~KIsVicbAFD8E+paE34^JrX)F-L(2|Ky&hpUCoFbzaOw9E`<;&3(s!U&HTM zLunEP6A1yRCS1u~4gf0Lqf*UFTE15%+I%;Sn z%TTQo-&EGXJaIR6HiUqcv@jMi{hdO0neBs=+sAb>>b)q)Y;j6!1?Kdaa)MPJ3jUF&t3*KV1oK!&F; zc*ibSdBr+Fv~;5c35U~aQL>8aUg>q-%xPXxiCUa@BuRhjAR~+FEDGXzR*x@`Cjtdr zslP8nG_vRj!QA%cL<57TtS$rSQkf{?SvjSE7=jnF2;_+pgl~vAXxXfvKr$EcCTv{m z-`{(f5b-v>Gb~X?ds;Uy~y14~j3?V0*hrLy2VF(fr395;A7U=*@ z$q;}|ifk8r-Rr$yAVP0(ch~LzLifKHhv0-a4X_(5aeE#$H6tHbTr^}I2^T;K?$#RyO3#%^{R99Tz*zAu3wb=wH%@(85QHK zOr$>TwsJrX=D12l&4}H6CxqMPhJJ3>4)ds?=s!=)41QA)aVP;`rI-&)? z^W$eMn%_CChlE`uC*{EP5W55qXqePW{Lsb>9~G#w>SuCJ7UYy%k~8vwT$3wuLiWiK zxga0OF?mf6$y2ZXKcB1mO^vTiK>4fQJU^v#8ByNZNsWp+%d%toQ9P%UatbMx-0gqT zd0>wE3L_sA4W82uWgiM&GU*7oklSW)iTUXA&Z3-O&x-lH7bOF^5IQx+(NfIrK8_&K zm^L54c5sfHe&yN^m^RNam`kzrb7bN!ns^}_S#%1K4mrQhA~Meu6wp$?wd^USRTWQ? zWY~BLuCg-PJoKh?h@2$J_C%kpdYpeQ=J|xi_eOW3@x3z=Mb5qVgSht($-T2nye)Wf z87FCUHzKnvde7gpyLXM|0JEM&5joFL#v%)lLe)@ZeT?t#^kJ;F7D}oa?U6mb!jJBg zb9Lk#%d)#E%#h10KFwbBD#((MBuZ0smYpJ`5BZQaf`~4Mmuc0T;<&_@3AukZcCowK z9JbvD;?Br)JNrPcvZ?8q8M#gdS6|-k4{+Bw(I&c+EI!OeQ@uixtAyx_t8HCtLdFpD zK&IItK;7+UC#GKPD)>K2NPLmSN16B`J~7qpCrL8$83D``7-)FW6XmP&it=Z91qVx0 zCG1Qp`^ddtE5xv@iH9bHxPyP$-a6_7C@ZF&`um{uQGynLfWXf9G1D~eCx|(AoCydI z{AeI!aN9jj4Cvo_ZI32E%{V)j9%vPL znqVxjUH~Aw9&off`}umU@u|pb(4VQYMWAf4UKhITagqWz1iQW4b+^dlZg=arr*6P8 zO??5v4K+TJ`;~mX&JALgQXoD{R^pfV8SEb3^w3_tqdn4Bvvkiz!GQ0SE#E2E>r#J* z037VbLnIMDI443UqEml5Ge$6V+T*h`o7Of;CGWB?@Aj<&w4P~9uVMbI!mU@9VcUIO zW*`9Ys@T*HkSah{A8WqM_I7r&buSVJjSHtM7Iz6f2|H*__ z)oeLWJ8$WP79Z$T<=*SSy5>R)sXTzm;Fd31`%dr}_r~aKKk0r52Fbk8rI zYyo@zuV85Ah>|1njEL9nIBUuqUPH()7oIG6?I2wSf;6hG1L)uy2I7Hye>5MXU- z|4E;;#GhjU;$c%$B2}w=VACzI22qfuL}lLw;n)(xf-}R?!>rOJ)G`k@6%CSe zjUEFNIb9YN0$+hHLXcH}nIT}7Oe{UW?&NguY;7MH(P7!#<<+?(*Ss_sg{ zRZUD3kUa^+W<>)*nq+b;NS-B1nIY?2Ar`L+cF}S340T>$`sW;GL;9Y*XG+eNv_aHI z=Z^E$I|F}HV%3r9yPnBxTDJO)dhIJ2$#_p%is4QCu+G$#p*G#EBVN5{9Skr?@tLkM zUUindNIQ45jp+_i^lg&&kct6b>vTLv_B{Y%K%Ku(#Pq`n)gJ9V*>#V?JMKIL-NZ_| zXNWy*>fg;C?+~%4JjsK6DuZpU-*zB?_D_&I8zXnECwgdqDR}4ySrXty21s-7A#Y#E zS3Q&&&c?xN;4Vlr{5X!{h~Osz-qj=`ok#*;kRp?W7;h00!LuCp9>>Yru@DyPHD9k) zgqh57^DrI>_}YjOK2G5HI>u_!d=v7L54A&+iOs+?DJo9Wc;KSc(C}*Mi0uf{m9uSV zbSLXTXo~!QjU7-RA<4#ftPhRHgV<>@z~xGZ?hvu)fbVv=>w4gm+2~19;_yU75Fk9+ zW~9o>Z98P#86Mq8<1Hz6!6!_Yf6pQ!p2YGcV4ej2B=8qTqp}^KM`UB802&P&cyZ;j zTMft8LIm1gj(WYG=6`1t8Vr_f>hT1je)eJji0{>ZguNbOQD`}mLE!r(0}8M|nCuCz zdm<2%5F!GHm^G;3S$J;UGW@!qOt7=vtBu7!%nL~MHa5ukK;b?2HHYVAKX2z78y<1f zlIFxs+*HgBs0ce3_&8F%(|I|$0GATc@4fmZL1}|}@y}uyMQMa9d(FjyB^y6vqn)y0 zB>0klMrkz5=M{}MPH0CnR|$xS(Z&h*xT(c95+tzLkD_h0%7PQM9IfqW3=6muD-w8d zrCyX?)cVDZd9h{jxp9t$J;l7~`IR?0^&VjtFUxKlCp4uMd}3pRRl=PkXN~L;H;N@# zqb#}=ZJMzy;(i>Oo6baI?q-M{{@#L6VU5^-ULmK4co4Hhtp!PIILr+rV7{h@0qEa^ z<7Pti*XV<{A`OugS~D%Jp} zWEBvUl)QrdD#aB`h3USw@S?x@D4Q4l`k@X5F5O0FZ66nn`MP8n@*~`hTgGE(9D*VA z-nJrY-9fNsLsK9a>N81_E4oJ$Kyv#ei3c%HypMhg`?!^U%6xB+u=>n41;>A}6gM?0 z6qogRlbO>6%`xREGNFms(tDEi3H>U6+Ww={JLbcvW4{;yRK|7$0q)2vh2oV>(ufxO zWBUtgt*4!vx0ztX+0FZcsrOU2hhVJQ-*(MVH2skcqAeos??UJwUgJW+cYkboQcH47K8w3>eW4V&JO7w?+t`~1J zw^lGhvF}DG_Qz=y4IIOsRarca zqm^AEsk20G+ytrO@!uc?NSdpy|jBTZ?`QIZ*)7B1A*ZbDy zxYdU^H_V*+ExHqc%?dm;iSjN;SNUW@7b1=R;od)JC#7I!n550Z#s6V%rU-Wmq|sog5W)gIUWjss0rF~J$r3| z9=x(W30dhbX)A3!GKh7~*kCFdPNx)<+H*j>F5K(PdkU(^mfA6m5DY6+X+DM3soxo^ z>;=ht&4E?1on=-xH~<;e5>1wlwxze_?^%A0B?R^Rr2DjVEG)oRp(H~&u(-))hD)&CoP!Qd_>1R_dDYZZz)Jk zQpjawnfdvXLS`nkyFyS6FXwZrV@X#Na|ad{02R;Yu$aiiI_TGbRC|-at|9Y987EmX2W-HUp^}@7bOED4I&shScc%U)$MY9Ni-xK zso~gRnHuU`tq8nhCW(%nQjy%4$TNd;_t7f!(F#B6;^~!g2U>!M)+D23?rvrOGD-%xz0JGbc&Tzc z3Jxw^6MMBo=4y4CW$2qUu{8{%WEc&jH0tVIdBy0}ySFdX$@XlUNl7B=M#=WlT_NV~ zrU^(@$9~9-%?7A8&{>ATcUM0r0pvI|&cPZm_0u`}&d;lVjYSMy@`A9;8t#WSo-7qo zEQC6xYbGz4Ah|7F3|XEQq{N=AEvC3!H&=IDwwD$CX8-s_$-kG_#@NTIhIedP(WzlC zgA%coWs`1qLS}03IXO-s4|cTV1t4Dlkr9cIM4Mt@-^EjG5)+ZAPKtfEMo2VH1_s4V ze2-9gGue-S)0!ybh%RMFa;dERF_YbUC@+b#%ce7T&oz?HOz)i=7u`+d0T+!T6IbXj zfdk|Q7?KJkj$#&Ibg~NAsinsaKp-?N zvmnnig+F~Aj4lW7tZNJ%?{?kq`u>70LF78P`O3;WPDxBYfs6Ilnc4s~+6i062|3BG zdUhv&B>UNw-X>#_oq%(=el6RVqkBXyvd;(J_V9Wgv2a5^f-5Ni3+uhFt*RqkRUPX0 z$X1t-;|xRWrvPvOf%U3Z82n|oyQQu@AZ9$?T*$V{!$cN+vws{V8V@g6%WvOQalMZVa#r^gldh0Ct7Sdg~4tW8m zc&;@PJmeH#(_<9f?!A9yIOn}&oqI)30G?)%48?aC=a`D0z_*QjqEnscyb19e`6;F{ zQJF;9c`MScBVh;(B-9cH^PqRx6fEk0D)7Dr!^`xFn+cPDq>02U@`SKOCUTADO4w-@ z?e!k@`i~;QF2im|yM4e&pHtCcXIY$NUxvW2S87R2*$0A-uqnIVs30K|E<#p*yhzHf zHjS8)!DJ3DVC-b&_zWqGlGT*SRz zuZGbnA86;jjeog<2CAgpx>G;spf8$zDKd;*dUjsSr^md&cq_uLv>&K)I2=l+(^US+ zJknxzt?EmX&4SX40Euwh5a?dG-fWNmwmx84KS82GOwq)UAB+$en2GL zOfkN+WM=~bQ=-6`g9Y@IM>d9khHPprcc`h=pA5}SfCSgSahLy*<`=K?MUvue`E6ZD zUSTmPLYVAsCkq1ur`U=jI5C!EC$UF>&j{#S>6{c0vq8oGm@MovrKC!jn3}xV8C4)x z_}IWlC{OjR9o0WueW(7TV0hS2#&=yLe>6farSkl8(GsJnrUgdyLhk^7s6=%=gf0j7 zup=sTkX>2MP4}JjF1Zc9t5krd8Yg)l!Hq=^j=V2Xx$$Q{y(|Pk6TDKOT7v*^n(|Hy1IX?^S;4|IC2=qX%_O0S_O@I+WP>uA#3XUal(Z@CPPwn{fbqA zgUq%&@DxdnQ5`5|sRbR(%Ye3oBGXSMl0^p!r888ItJB8Y> z;NF%!5S-*LIkA9-OI5llptEG9UKNU8aivQ(8Zs!{X%&v?R^F3;YlIy7d8V&x`nnP# z+`S&1C#0PwRAkK|PhB;dY@_zErQ7FbYUwX;TKL%ZR)CrP3nY+-`D3X~{L z;yqpm4HC&9mL;>=dV!OICrVOrAHZznM7_0=B&UMFkU~aqBXME@g{93twxu#;{%U~9 zLLH3_J2s@NX%2XQ{DsRQZ>ph zK!}mc^Ccgul{SSf&)G{}*8=wIqPLsu5^(kbv=S9v1b{4chzOBM*0%a&lC41I4*95s zQ9fL|O$?L7)y>X*=>MVn+V*y(B-a2Q2gDK$CfP(D02l^;Q`N&t?%u5k3L_{faagjK zfRd>j1qlQ^;1LLefR|`cNYA_7+*Y;m(DrR3VZd#njnq&|SP_uzz(j;vQ3xZ+6QXHx z{VS6J+*tBjUIOk zJD^FX09Da{Q6PoLUsf2g7?gXXNT2MN@H7K2$C@hImrT`EixJnUVpvl;);CbW8 zqrC@D62hKkGCMhY)jRLKc)9=Txtp^b?;bpTy|2tDZdOCjknqyw)-AeT``*irgM0uw z(#SLLO^6mlTHZeW=Jo!;@yXGfxBE|@cf0ImTuW$wF4M|dBHUEnK+&#D2JryXx4nun zt(gkOc2l^p183N!nv5_PQm|zRfRdq*APRT^;YV<~g)Br8zX~tCQ>!x{sbdStDM}BjElX!83 z>}}nDr(a5|g>K78yw(z*-@Xh|) zr^hc34^E!%zj%4@5`G#{(ZCwIc!szO7h%?G*1==%-AyoainNAA&&uU|ib}5;WRf-- zJisf|y&1{4Lol!JK!isiecIjrpp@VeW#T=5AC==<+urSNZ%b&{DnmX;(}vGue*PlB z@7jPtDe!#R?OJaM2z8m8)5;8Xz-hKZ$l5yM=*06nGiXUO1i*skZvc(}QA?%&`m`S9 zF%887)jwv|pZ>-PwQ7(gbF~u-)e+~(05=rF_0FU=3ha6)%MJB@LX!veZ`bD6jTGE} z&<7?H{TwHAL$HFam&gFN+B=11gDlJDxIENeFOp# z%R=+I<_tZzrm#2G2Rr23u!uQW(`%J~2aDDzK;}_7*8$w;RFgC~_p^Bh_qE&Bl;I*~ zv5pY;h9|kbVKiBtD%>Fq*M*O5wXeJDHF}q=*DZ{&UY`bLNZ7Y9WU3vuD35(jB!3t7>p-g1Hv)@%2wwKp#4b)YN4 z#?iO1IAGpj*7?d(g$@W zq;{%+A=}y#Ql+Cu*uQE$*syo1ZtpDj?h`&(R46URV5ZyJ5*{PRqQS{1|H2uo+m-F9 zXS;X5?;_ioth|^U*qY*hhcuOIMR4_PuKl;p4pVcgzKQJblJ%!XUUC?+Cetg*6%2o! zJ&D|;0Ed>0K_bMZ@pp5KwBP&2Ib;5=^zZ9+-|SMqD_fD+?kB`^6HJ`|WAEy9F3x*A zXVX#w{K&}Qc<*7NbS1mqK>X-~oQ}qW@OfN!%1Dg6U2gEB6T)wQD<0Qa@4KeuSnV0o zdsEw0kuVL&du$b|;-r@!b-N1u7Uv*vq=@}H2@!Gh)mQ2&^77BKAN-sOp?tKc)srLl z+f7FAhJ`z%p9Ep&@DzQ(Fh^quXdZbij$aY@Ui2smSinvxM3QY}vvxVoiNpuhF!at-3157`fpE;nyQCz6eG zHL!NvK+2cT^YHWZZ_}IIt{h33Km%`$cE&@)S%y6z=TB;HyWOojGHUj>eFQ5qkzi79 z5ywh{ox3bQ$=QU?y;kMo@= zofjV{f0b9_wM=kPH(5(J6dY~Wz--w9b1sPS05iuc=M%RCq=iyG3YK)kUkHY#$#Z{$ zIl&{0rm+V>H6w+kTKma z%9#_)7J?N7X32nQH_)~c&O8bkn2k1Y#=&~kycPYo=Pob>)lLj6ynV;BG~ zD#Bnj9(a_<27fLo^-!QTuZ0Gk+($X3NtkIyOp=U9>?jrv6!1c7O#D)q3d4du*n8C9 zO$giZ^#_FQ>Kne(9btR73S}x5=5@~UGs*#fe@otY$z~;*&b5Dc-YUO=o2ibHIB|Vu zdnbBMgU8yI3emuG5&p{9LkDtFMPs1{hPx6B^2VB@++uRnGU&lTTQb(G4WFbzd5=@|*|=eD#@)}k%EQZAqbX3WpgDhDUNMZ5iyiqj4+yS* zMqW`apZ2~Pq>Sq;HHH}@dG9JO#EX(2UNO1GWbAQVNSFUN<-C|&W5ix{Tyh4)z^bGn z?G;O^$bjAzG#!a0Rc67nO8^ru6Sqo}xirhNY8XxO$vM3{D|jWM6e3r=@0)NH2o4%9 zQ;1h7dU$Zn=P#UcQ(JB}i~vq>dWr{s;rVcx&eIw6o9dnRxX)Fy;&e(Ja?<%GF}*s? zxc&u-wKG_pb0H%eUrv>e$$3V1<6Qf_8=oD#hDfpOyxTojYRq#tcUc}5W5UNfXVE4) zd~J0`gIQl-S8*9Zs!L}jzm(gY>Lx{UZ>j+PHUwhkDMv#UxR5AVNO`@p`6SYRoS?Ov z$kQa4;)l8F+ z@L8g$9U{n%Iq6YfNu$G<8Dqvp;#K&>2ea$|D;m`BxMad_0`c|I1cqJ1VceJ=(Uo?|iA1xQtT+knJ zFHkv<<)T?DcSgnYVm6DD0mO|du~pHlX_DOfCg-p$p%-(v3t2J2m%KE88xeHjW$$^S zo{-hXDJDA!g1z)NhOr7w;t(MMH9HSMBjpVP98+OP)p&u5-|cG&_^oc0Y>tbrBGa$O zWeie#6B8yQSVlsM3T-B!0BTfBAYC*|R->*z6I+}#@fC4k9wbzV%)t>tS&27OaZ~Va|zjBMcIKKHchaz5%I8TK7|Cm`su1;YuqG5Q102athSCc#3zE5 zS!e!d;c~6pb+9xz=qPQE-PFt!{gD@-gwa{S^dX56wGBvr>~DYK;Jw!+r!8?8gtbwq zgsLG;Z^n0NZB{~7SVL;tgGsZ9<6ro>z2jVfcgxB>NZ2_E2mGwL)-;Y2S`@P9ZkTr7 z7CR_HTdwI#U|QSjasOf8Q*)*#Q_>@fgQ)(fYF zlA&z+4qNHFDU`}XNv`YQr%-K@-VCr~=GX2Sr9=gPnMO!iui1U+#O15m^)cnRym?YL znF=-Z-#~!%_pgo|-G**3HRn>N%^rS{3?5EtPyN~?&atU^y3bJi8av#k-0M0}m1o4|Fy;cXJyCECWOJ zF%;{Qw4Uk~jCtWbkdi=c$*@Mdx0ri11(Z_`i*Dos={7Y$oZl}F3%1N5Upvb(8Vj}h zP2q&;Zf)La*JV<_Q$JxzOY~`G)mF2k3B6_F1%%_vQ5(;Fd zVR*yk<4rlA!x6J-T++u#M-QjJn2pMqe`{py3vmt-oOg&Mv~lA1_@+gliCB0|!Ycl{oHq7ZzH*~a5qtdb*u zPCS{@oNFB=>k0WQA?|70snhIM#@)1kP?ZASYqHYWi4Yy+;+q5@U!MvAq2qLlZh$ax zWo}HUQ=Qtb3UD)Y@9S!N5r)p|%KCc=iJ3M}JA?s(Mq-G`xH1hnT}s{JkbYOIC25=b zGa2SF_=UG@3f_^N-mpCko%6YWB3GLQ5T*p_oaC_9<#lENqnblM7}ET)6L#!>%+Jix zKNm!p?g3c5JVx)4CO6)q0PEC{OKOTHV)QdNo;9IBg0Zt85;xg9ud3xGeR&BuMyGQn zI#)xQqJ7%kJT|But%W?U*L7`?ik3Ckb%l-^;ir|F!L3TTK~wFdquBHzhHJH@XdG*t zdoY@H?YG^Y^LDj(2|dgDz0%iz1`rA`Nf1iUhh@rk{D);S*y7sJp|)KS^c-=ax{M^| zO5EU~ZFY{WEc2-9cD>6?rnr_+1%dr94lMWpSXN`MrYNNq5_KKD{#eN1=~1Te2t7PZ zCUr&?jLi%cDUE8t|C<2rfYVJr+L}8F=5q9;W(O3#WR}hKN60jrqoWajWDFzc0dK-3 zx`J^EuI);1P01wa73da~Ckia7V>e*Tr@C*{_iKJO>QX(ddsccyRp0B*n)!lscAk)# z=e!9wS|-{J8*pcC0RKh=2Nq|H{<_4Kw;H!a(~0TEPQk|U|)OgN#R z$#beyqSx(xFrDQ>tc`554}wrNZb61KVyQq`<7WRoO`vY=p0zID%L;P-{f!J@MR6Wk1|Go9Flk8(^ew3Ht$-; zdKI|a=8kn?vmR#m{k(v3?`ocb8iK#h!x6Nmu=Uy(yYTSTF4wuIDpLDU)1$%q4!Y+% z9`cIi$&hP!1Q6IwKu?mg&BhlsUB5fT_P<3xq%CT_OX;Xd@Q^&YaO-*C)kEusmnl76 zp2g8?l@ArWp(90qw2sVmkapVbFc{8jzxCKL1Jyg9!hpEK^Lp(bN$CcB8uwhjcye>> zF8E{I0N7A}{PN({%Y*$BUCN>QQRqA06>Qo&diM0y)3+zbKfl@cVnY2=hhP7B|Jm_v zrCuH!@4tQV^x6Jx1>YS&?A|Sf_7C2@zWs}D-W{KWsk6<0=k$}BzyH(m{=v~Lt#2(< zYkX@tr|qp}Y}0S}T)pL{sPr@xfz2U+ceo*(HP8(?&$#hSCA@$ubYdkuZ-H%-J8i>F zr!M(&jox+x>|p?VO@cakpH`?A6#V-|28b4ogbQMOI{_zjC*6V=4{iWbB+YN)vo<(2 ztx4zF<{Z+09XH_?Q5PuPJ>np~A}@>!a*Zgrrp#5uJCd8lG2|u2Cj3os3?XMXI1>vO z&V(sEI*#S&Eii^$B4F9|kC%TJEJMI_1TRwvUg1l~tidN)pYS!QEZA>vL5JWRx4d?(e$1ea&8=+Rz zcRK~JJAAs*h?MGbq)Lo28XWYROVtZ{mVkl^4sD2oq;p!ZsfF<5RREDnf{XIXt(XI}EDg&m?uXdMe2JAB)7Obg=T%}> zDp?sw_5=JTZ+;W|!7b^2i$esqGcRV^@!TMeX-{&ItTvLtr&;vX6~DfxErv&ubI&tA zi-FH&g7jlh>#o<{y=1)(A>Z;v#?J{q&G=$}#HZu+8rMGgv+fWd_L=1i!lx!)v*!B> zR+LshSlbyUQXuAYJc_|Er~HzbK}h-8CgZ10cYTPpfBp4mY)}1rf&J-2qL;0YdTW{% z)uOCuCiIhq4tik;gTDk7(veZW&h9b%|ySw8r8u%}k~q`2!1hJY{Oo zw3^TrZ(7G{s({ZF9^Mh8lV9N+=ck09G~>%^aY%gMS|VfSgj^=WX4l;YdS|wOKO0^z zHYsyfyCYYb;OIIAEdi@uAw?+xHJ4m6FEA_7$E?4z<9y`UW~`zKVpDdMXUBRS0aP%@ za(au=j+EuTA(NTZwVCwOw-U(3$?8y##)v~7uB{$BP-WsGpW8;{l zx(noWl#(ic-+g;>GqhxD72? z@C*eY?6quJeLV*isErzsEq)-)!AA0X=9-7G@Mvf3uN9h38rs|Vu`>35I;|m5K1Z+m zj&l=W4E4t}6+`|~%4sx7`C)8nNE$2tbL_ghN)tQO#Qu7{>oy!f=-=vZAE_RwEr?1K z2%EI!xk*t0i^#XSwimUqLKGr}SN2aBC$*`4a8`0}>o+ZuYgc2vUQjkY^fAh*getS+ z2mE3qp%+!gFM5k|5hpT#jMO5m!$S?x6`<-lyn91W!0R9w?AuSZq?pr7o>`$cE(KcE z3S=VgwW+Pf|41eBf3{OUX+E=yCco<0^A3tSR*+XSSfRTS;m%$YMDE{}8}(?63`>(C z{~1Rzjn8F`)L$od z2(7U;o<^vdyO7U|>B9)FJWi;pF4iAsY*VY*$rOOiwTq^jWm{V@^_MoV!g@EPXPQ&d z8_B0?YWB$%R^9FLU%fzW{uV#@0($9Z_x`W;{@3pP7yeG92N%O`5#e5Ik$A@UV^aWJ zmUjll7i_S-T_hrZ=A&ZlX@U9AY8;Pa+TaiYnvUZbRGa=K)j1YuB)uI(dO1*|N zuL(+^-qQC@+WOi?{hdFGUNZ;stf8gZgh;X!`~kmE1b)GPKX$u%{lIX@=H}}{BH_$j z)mnw7Gz6n??l#vmMAZ6|&ZXlnmNE9N)@Ich!TI=~WP^oaSSz{uAGgg`o#a&VyAj}m z$VNsWOi;~mBrA6XMW;;LLSY3aJDOYljnT;A)cPh{>Br!UskScoDSHOa|IR}FV*_#- z{6Y~8)d;$OwzMwHo2$BUls6y*Bhi0BCs#>kL&fr z2M_ihlAxj2ia{8Q0w>s~{H#KUQP4X-154a@^m@HU>Kfi>5QyTiHaBKWymZW%_9y25 z(=Evx8bJR&13Cc14=BXzbu3lpIgt@6{1uuQOUvAuu)j$e5C9FXkQ(+}qo-CFS*xV* zxMtITk!KpoZk9l+{?Jsx7;49Qe&uL^*Xx-7cC+0bbrNzge$!GLL}FN8C|$%aH769L zpX_ppxZ{mADfpD@fi`Rq|o8CV%?0 zRhkyW&jORHll4zV$?|8{9_6eZ-#cRapKE!v#CpyDticfxPv1i6Pw67%Kg#vdSquBf zAW$iIM^!hUMr8kCS4fazThGqt)RPO5PtJq&?1s`J=wFT>lLS1k8#uq*k>Vr3H$z^3 zmYj(21VuupbRiiMgT?od6tzG(AYm*SFmvK6Z)}*#mSBJas*L~S?!lPvJ%;1&_i=^a zhpaO;-OqscN(K&;GLA2615K=fCAt%PGtlW{oK6lZ*L6kCpuruCn>PkccgVxF*iU36KxK7*H&LhA zH5J>E-PDs#Y$3}eRGm;R=Eyn9P>6ivdSpY?-u(LQlGWftNNH1UL;9hC3+!|Gjdasi z1~mPr=|+a7|9qab0;7uIXqUK6f38{qM=2Rp%1I$h)YzSrNgM8Bi@PUF$O1QpaEuU9ha;%~s-+(|3e#@@=je7Y>=)3;@RDfdnAsaB!_ z0nlx|uJ~OK(z*Ct-WPDfr}f^_{9h{?nhocWZ3h>Lo0g$116?hVyPbp~!CVb32->iB z8i5A~>{F29^Z8YNT{Y{9zAj5RonRkp)DF;(%530UJI<{d)P6@y03n>z?8_~~c0&L_ zGq4pQ(A}t?&k0|xn_oPC=E@p5a|+0s6GnRXW&+ys{aXd*h-&5l+Hng(Tuct}B%eHk zQ1&DhS&|8vlNp(kbFv_(r4Q|YNd!4ZWZ^oTndx6<2wU7n*E3J@KWdMr0%-Ys!Aarswl}j@DRKmbU&qJpG zjSk!GifK$qnG7-eNqvWsDIau?HnZHLmTq8VLjV_-n)O&NCL{V&Op|dY6Fwy4G^TLy z9xgMQ#>=dzr5J1k*DgtPP@4R09Vk1s9{PULoYZ-%-%l`q$>y>L{PL`1Q^a$EkkYJn z&qb`{bRLzE~Luxtt>0aB&)+pEHgGL$Llp4 z<>Q3JTfF6ez@kFULUM}a`goqPp3U=vsC$7ml*F^z5wtE(kLF{jZko+T)i6&>ylN88 ze{xK_Rt6wbGGc^+Uc3PNgI+UM7>$xr;%*(@60;%W1Y$);yJS-14QWcO?d(fs>M}W7 z+^gULx+U{aO&W7Wv0yEENCuN$(=8%c%$xhb$P>wb#u;W2NywI;8E?IoCbe3^a%9|0 zC0&T~Oyi~%nU^-uK~F0*dRoycU$$g>0p<#wl{>!Lf+fRqvz9DR<#Ix&N~b}@dR^i) zP5lNsFS!d4tt~+2ZI!Dp87FwKUC!q>?4~s`0&9k{qB#K%?y`mI@gRD<>~AKM!8SUg zxTzz5g1u0DQZM*jQ1_Z_l?a2rqJeC5bv={;LTppIS!H&i4m?|2@59OnWuVHGG8+)V zYDXt;R6v+7lU3`%sSM6ZhQ@UaIRl_>lX|b7bkhZ*mn*-dbCT6^0}mP-_vEkIxF@8) zD>c#ctcWMcU~X*f@$z$;LiA4(PU&n*q9Vb6XnmzwVPnzFj2Gy`mK5iXh2nwdod5ww zEhc1)L~3s3{Gl54m_JmMZ1)jXG3qE9wa2h4csDfI zu2fAw`6MTLp$_E@z&{ULajJbI=Z)MG(s@fCSgrr#9Al+_ThdCroM!z%_^w|CMC>kq zAYp0W^PlXyA-e|WCNr5~nWL@J%Ju<&h;x&nx$~h)*1VGt{vc)~q92M0EJ7kixk`=#e$f4At2!}?h1yfiLRjsm3zz@65!423<%a1p+nHfv!P8$~< z9IzcVJ~TUCO%d>7 zlO(B!@nLE8d##@0%Flb@t(o#{f1rk-(KWZaE8Mj5x^>qACAM77+p2wk6up^s@G-1$ z27;}*Rr}e%?0j=tTz_^8#5#gcY~j)ofC+&IhBoV%>9<>yi(q?|V5L??BW9Vv6p)TI zb`oae^RF`Ra5CvJNWl{l2JE^7bet$D~2SM50-E;m)ED{7kybK02&pcy)?!>lMxmbfIV~HiO zhz?Mco5kwt2?mMexjJ&$wx^zYRQl?&Rg4jppm!bo748IAR9r?VwnB>vk*ELWYe|0> z@crpbU$u!y%jOHC(dh*^;$`?$@NBr;{rtE?ClgiQF<$4R*@40t|@Sfn|U<1h`shvDOiJqcb)6=-FP+~-vBwc;%L*Tf_ zPcITZo(-s5`|&I>k$M95PPg&?CL0jYX)V!TM?oR9@;IMlBe9*&^ou}->@affi>Tda zR8}Pf+Dd7EJK`5*C2;j(eDHRQe-e=o%hyhTxEPORI2dgx;tYTyNZ?H3?9MoA-uw~F z)v06obW@bM9MK@2av!XSI`m)_^0l!z9kqm%K!w^F<~F1O@Wlw|>d3 z6(q%YEJcK@9>qf?IXYFw6SB#fM;N)Y@7c_fz@ii6IhDQ8W7lzyA0eq^wjq#s-qDiC zm3{BhzPG&RdrSRZU-iPXQOQQxl3e6$a>>{Z&~*r8sL8d(FHiqChCwRcH7UsE4%otf z((p|zCtJE?TSGU&*GY^8UQeHaJjxAtJy02qSChdnkTa{Tn?b!}1z&%JBwE6xJkh2+ zSV+x=4T7pdiugaLU8GEhf^rv7Q0~a+m8!NL)a?!&>;ot~_{4qmlR+g0pXdia88{PS zAjvT6$>80F4bsb&%u&y=ryl@#DKOm)$Ii{R` zf?J7%8P~)!L7NAkR{}OWz~yptA~H^uL;%oZs0qX7pOH^B3(WlUaAS&MnxO`Na-A+T zu?f$YlNvz8DNz$O|5P)aC^@M>klr>F-J9lYk>BbonQ%@P-0~Tp=uEBvBTor6^g`lN zcd9iDCY0P-(EaLhlOQG%E_T1h|?0 z1iBix@G9BB=vl?(xgs@B1nIGV%3P=9w!2$E3J}5xU}A%uN#*MVh#jQF%k%t7QS6{C z;QLAOIJxybU*%)WQ#CEXv+E=wC56s44jRQYq`F2ZwbyBy~+T-heAYYk#QK0k!;3jCr>141Q!6&9=nffU}k;HfrmC0--aeTr|Yr zRkKxO9vw@%#nRhNY>EYTlHn=XUbV4gzi%Y0pp!wXcSIXpWg8`F!Vdy>NVFMc(qJA& zP>O&63TD%+$()(xd086;hDaBOE=H(3*!}q-Lb2 z$Ks1b5Kr|;B|qhliAceJh=9mSZ4yyAgyEkTt8Dc4_3L-%uYP>@7`T8(%fUdsDEl*cYc0TK^E_uyPeo59}ZH>|rtt+1*o}OL;s_(5$C_6On3c zzC5JrtjaYBx~=|qdrX2x+E6i`wrY#$J+T1LNp)w(2~X<00w9xr$u|#kq8^XA3Sn_az1Z!uP_X<%y-%%#@ETtu~02# z)2{Muva~y)N|Y#w`KW9)9<$Gql~Ir7EsKrc9Mb6(80x$syYh$ZhaaE4{Y8(L_Z<+P zdq@w`?59G8fqcbd7ng8F4jugEOGjDS7d;vd=9!}13U$&-v^RLdj>4)v%6fMrZK*ak z*&K-KeAxU67rt7e5=RHp71~ir#}zeZ>AO~F`9HQir>$$P49xRMuWLu>*u>VvCfY67 z6GPr!Bb+jqn*kDYfA%YTw`3yn81>IgQeK)Qj%?ZuQUe+hv5NZnlaLCyjOm2^A&6Rt z$*B%Q4l&n~Qi#XXL2#L^)2f*v9i7SK+ZXz2jYU|@s`jd!O~MnvcWj>Zu2C*x((7a! zK4Pkymy7&1o|iWOwE3O`A0^j#_WKYo=Q{+juOmL#Fok?Ke?_O>QzczX;=j~5ECP4L zd=ZS3k+*%X@-5XeMWBb3E~AHU8&Qii^}jf$aOYU3j#_Y<(1urCw#DW1~Q=5#EKaAgzOXXV8C z^6lm^(dr(k%tR^lEEoSkFO#D!l<;v zw8nrS=%N~Uw`yRFF)D(BYlllU9{+t;Omv{8rxT~&Q%r2>z6OyE5nPvH|7H1+jtO$Z zdKMz(lM0isA5VO4aNW`S5R5yuaZlPJ@Scp{f(eI=M~Z>3$LYv(Z&1iXwcA$$tSLTw71gJzed_H zWZlece*kF@F6ll(3$ijNv(=y~2X51zxQu)0I zi{^;8lxQ{;SjRLH%&!QfK;;OD_*EY~=&8)2%X`UTd{69y2l0xmo%@c4bzHcewwX?N zQ3iStbAW+v3D@(;dQGy&-{RD9f4xM)|B?t(f4=B8Jr2FTUGci0Vx`EMq_yRbcuw&} z15~T}9j1e%teSy7BVzg&aDWer4drF(x>G+rb;D_RPtaz^d@^G(w23z6Gu=-qxu=UD z>b@r4fuWA?%03*Lv-+OU$`QrDw~@;U3D5yy{^B-nE*5JEDn*( ze`AuxS+dv$x`DPOK{?poUr*{(z3II~Z*v=scGn?*>-fK>WBoz{qk0*r!4hw#aWxPD zhs^^{4;PIEXe-ZR=BA&cF|;Xwb!11&o*z;#!K6w4Gfmub`#mI=Ld^|gfhzr@!XRtg zHiE_AR}HxpNTq*P@DuFLge$JzxLHVAmxu)tJ%3N{h9gl3`hzYK1c*I}IS&ifQ6gqY zZPMFeC-3166(yunl$jBv7&5__okh^hMk-!28;#PQbchW`6O&IDV<&uuAfNkSX8FjUe`V4fOewq&#KcV~J5*ncbrMfZ-5e$xp~qp@+F zU7CtUDZgh9h`&G7M=wDUKv#GGDWM+trgGToY6~{007q9%%g||GI+B@2yzeE5$sjwn zYjch}djT-QQvc9Q(_0V0uVBO!lZZDO{(p`pY)$c`9ilYio;v&S>$4|sU%Zi)R7Xr9 zt#fzW4WaOBkP|f`#=oCz>lDa^!3MtH*V_Jldzea}a)n{kzG;SPggHp)q?JQlR9k!d zL&M4%CjY$oe)7vViQzEDfL za}7g!jlH%*i(wKmmX1?bPHiSZuMuqhz7`tZFKaA_Nl zFKg%Coxr>xiIP@tv=Ju>#7nAFO~16MBxskC2NI@H%WqO;XOy_# z3fPUytf63Z)S1Iyf0VCHT5>~51N3wbqBrjFpb?>JMZs(a0bon)P!M!3Ng5*9?4H}| zk`Y}uOgzLlj1<$xvxv?_dzDCgcnE(=NOPRq7tfNE9A#z@Ixd+>mbhTW+~^h4IhhE( z-`?wNqUs^e*pM4NtJIn0yq5?SawW+TfUS||!;`7WpKz9+CpT_5InU3KZ{ekkWK*p? z(=|8@Rtml#-};O^OA+@2A_$3NWfd9k1Yo;Hn`4J~2hW8^d1cqZW4wjsL}P#GI-nfy zKu>32-18eU()4YB_3lQ&6xsqj)eiiqttXm231n}fSe@I zg_2A2b|(i0y_2a?&C$E!^=TKHG!yqY-EsePC)-*bjH0sj#;Auw9NN~q3)U)zUmFA< zgx{QjTA3hP9X@crj>o=p&vyB&R-CtK2L7i5S^9y01=Z{%>((|xatct8>e*@bDY=Rf zGe(Z82_s7v$3vYyah1Z#Qwm!+gWi=kJhH_fk88B5Lh*f&46!Q#1 zyL{amrrLGBk+}}9Eq8;WPBWYS@RTThA)D`#YyUKuE>Ht2_WO(OgD2jDDY;6Z__1QL zgws|pmx`#b#kj2gXI?J@SdaI}CP}+}f_3;|uza1|)kxew{!lZ`OubL_R>aBIko&)v zVhs}i0j8H?4ib?8>X-Bm5Kwpt@O!f4<;tZdd~Zv=j}}lw6wcqBB320G z!S6`X9^k~$yKXh0kMu3nq;H|-^4THh$jE5_B&9<-zA2yGETU}n3mzPVnT+$uiUR10o3VyM@TraPd z<@#!rISqKu1zT4iWD9@BlP71PN`c3&0BBlyDM3QK5v4mh6Ky&^ip3tZA4Ss5%k!%s%X3PL&1A2BQZb6t$ZY zj(NH4Fz)ztJ5(n+lCetW;Be8&bo9{$(`lF%)&^%vMc!kxYk+?U%8W1~zVOH*0)=!X zPqrayp9J=nKrgt3oglj*>Ql4x1F>Hj27i$FhLl|q$90{pXCB|`N_GCcT!Wf)-6O zgcF?MK)x5TQD=WZqu|}1fD6|{)9brH1u;1xTui=IT&(?m4x^Vw_XG&z3<*bA)brt< zc)~)dZqdDfgzjnYkVaO3)BKJG{r-=1+57wT)_c=Y-4KR2^Q>on8okqWE^axGYGzfj zdH~R9yaTCo26FAGcMq1Vpl!{(tAm27zyR%T7=UG9%M^dz%w+IJDmBi7w&#G0MzDhM zYarm+HhgCutOsyRa#(0+DJ7(8Isww0qAF{?Vq(xDhYcNog^~%7kM740>bBSnXgzR7 z6&`mdmCtW;j~+ceIX-8PPuc(QWPBf;hY|9vBNI`UzI!Iha{gJ;7i6r9UDQyn-o^yN zC=PXufTw@x>W4^}Qam;ZxL`b6uzDDu=~k>$v;3=d>*piYTXxc;d0br@_@eT}dm^Pg?U`MKOoVQYO}39a~ap>X~l9A^4GKUaw8xAZ2OPj_ce zNTfT9jN;!zgB}kN?+q(welJ)HLedFwIYqvko_c@$40RDBMNd@e0QtI)RNN2!?t=1S zAw2(Ey>oK^-ierL?&=-?J28B|GY@=YQIIRVGaQPpfOz_3%(xW2I$85=!$g#K5!Tuv zB=N4wC-L~Io+iioDB9$h%`1BK4>$QWC->@oo`?wV3o`Tr zs!^EpEE63dGed1+U#?67h~y+=LIDA4Xb9^q(LU;BT` zYcP$A?&O^>g7XOy8^sbmp8i{E{?HvoW3i>H%ZSXNokPoR)w5 zobazS&SAClmqucpCB*&-nE#YGUv&H%jvhwvaqx2?SXt9&oxe*HM&={F8j%s)87+L8 z3K@pwLpp_I*m|*oL|$GOYud_q(~f_fQo`0b-NAFeLkR6{I~nPM&Y$qieZGnw8y5uOJOv~NZGs9)Pl8170gRE4fu6v?IWWJ+!$Y>Tm6IoKa$I2tK4v{Aup^_MY6>0ME zss9IB?Hn)fY`7`=huV(&j=wLPjRz2khzM691js9nREH9Tnaad-7@{+|Vs(E_FIZlZ zda|RSzNt}Btq=m1$vVT2!^PTQ~Ylj*~UZE7D& zk_uD3%cApkvB=F$pzy&+7WXYs%mfik&d+fi!JlMDl+*{;NB`@)6gfIbb4XNn3f{(@ z?k9i#9GvdOT`44-WV~DVXpVma%xqFszVfoVIyu87{B?zE`<$;-kiEab1DZ$DWL>h4 zvPC%u4SdG82~Tx6*X=o9W&DrB`{p1~9bzOd+8Q+A3vc{?H%3J*GDTICe0u}*t`MWKh2o~pt`6!uPQ*;n5-bp zI&cK08QLl!-4x(!4%!uyzZwKNU@ue#Tzs3kI@R00?rL+INLV^QSt#_pw4tyUjwa9m ziGxgRCSYgchePa4*i=gDccw{~e1A@6Me`J!4LxG+(0N1kqy;9G&hfq5Np>ntR&2*g zxxo=50(4VIK(z?hVAaUfy}CHW73%IR=gr~}<#cWA1K!NWd8+r7`fG?8U@G-me~~#` zpnmJdK=7C9De%lIVnCRNv4nxLzv8o6I}U>W8J(ZA54>*bQBOzB+%CGSby#M=8kMf> z=(o-yt2FvuI2&UWc`8%IRLS0i<$9eF+!!TSp1PzAh7oEcce0f^OEWmeMA&2ea`26c zxTxza?&wQoghny>Er=^Ani~ALlIHHkQ_nNnef*cC7!q`U11zp{&KCQ<@F(Sduf7`Y zLPSpOR0Ml8gl;*PG^Y2+bS)QvwD+n}?{Mq(I;K9#x-9fkgp9jMNid}EaEIxp!+z|^ z$<&kTu|1FiWVZqoTbUDhEAMhD&k!#ZgDS(lfg84@yoCDt)Y>1Nhs&AeUg_szV($JUyMVGR*wmot8r zVf2es9=2&;9u-J-Za=Ib_!-a5g%&T+3znhgaVCExjI`iQn*y&E{{UKvGkM@3 zSn)bHB!Re#EdUqi?IK^n=%0{nzJe2x`RMUDslcxe%Y>$`O+ktm2F8_2(VoPAWWU-Q z)Jwf|*y@%mZ*+^DjVC3;lSAAjDJ$!XEsxB8OE}lj_7d)&j39VyJT8MxS@pRck>plC zl2PK$NGdKcUMp)n>y_e>XQY}Xi9iEFwaED;5oyLR)1D7y*Sv^l9vPlajrzq`FqqwK zdcs%8N~a^;W#}=S;hDov&nD1+WCbYkM^ehap){YWYSf;NElZ^MErABi)(97TwL%VV z@Z$a68|*UT`0k+Q1lw(Cp~Ti5E-cqguE|5RdYVZ8V#u5J7Ecjp5J4Hu!>9Y09aHGA zN3?4aXy24I3C$ws=dYfJ2)M39BUvd!3pajmpL;owZ&s^+?zX-}(rNPn z(yXTE1jcGI*XRSS>=>NoWw6WMB~`&6WdwzQO&&S|ju7sLo9EQnHk8Xmm|ed$-0Jl& zs>2^hn(^FpnJA9o{3jStyI1b(Xkq-Ly|UE$@yUHRZbplgc~X2 zaT4{VyCpii-YR#0UpEs!CuwFY*WV~vGR|d&<1|#5;9%cl8(HbsB>Xkr(Zr(s8tAo3 zx&OOGN)11ipRA8bQo=Y!mOzZ79uRY{uXOcFRZ#74v_Uk1kJgpAV9h8SAzP?uK915b zX}5aR%!LP||1)~vTBIMVkAJGzi#^Ln<0_zsVRzf@@nAWZOC1tXe=RTt6%3;3a4H7X zcy;*Y?Qy1WEjypsyO5g$sQPRI`%B&&68>(#Pxw1fw3UhHW$)k-bU^AOf;SX)IC(G@ zbi!A8L#ST%C84sjKjwl^WxM7?K+n^Et>;VMIgm&>LrUl1bf3NtNp0N4>OA1MM_8^* zt$a00x>g}y)F0D2e~tg4F^4{$m+skYCT2pKr0&uw%k69Op#x~=}y$NveK>&)rrI&UOomRb{~Uz*L1E%&uUJoXHswO zqg{A5BVA*tO*LJYnK@rJ>8w8)&k+U3Szk?>N}7+m#DUhwf0*0aDbs(XVB*#Km_v)A zYLX;gkap3R82nvI_>&_--PC29JbG3(ypd65lQR&8Bht74-h&q3jlXJ$`mKff-7?{i zO47g}?h8>hz*t80hjYEtGcVme^+mwSgsU%a=H10g}wMyp*@t2UfHVJ99b& zV49)SEhRNVPfze1`*+IcpDpsCn99u$tUR&$)5(spe@iuQO2Um;pfk}Y1*lDVr(Qpy zt1I3lROv+^sA-mfN@kjgc2D4^E{kmi0GhXKt(`ZrWp1-xTf2Cc~#mDO+RxeG}!ZaUM>X^eN4hKPgiTsWR0J5okd5 zMy*}SPcL9A)MCPs)8h6Ic1lpI>X`fWOHXH5qzBsU5bB5N4BUA&m0cx*t`f1X!p^mw z;}VNU&O)UN#Z?CdxhUjX2+tPlHG=9MUr>-RJz*L6mu4UmAb_?gNfqYoybvH-_=cg#87vQ>2p0?+TpxR40RvE%4;lm9H85E9hXJ$n6N+ zY(?A&nXL>Zl+zmJj!~Is1<|d~)(({xa*WDJk(D3dToZQ1_CWYE;Ouj{LqlL{h@^md zxY3|HJgCoc8-K17{?^`r%;6fUCrFhp$goWn1qoo6G`dEKt&Pqptr?rLVMEmOSreRY zdHr0ldXx7_6TL*#S=ZfH6crGVb!j(U-#DQh1{4Aj&OR~W^>|<1y&)I>se6 zprsx+Lqx0|1NH}-F;W(GwqrO+x%0!#ZK04U0QMVJ$AA2*Tv?m2oD?a5n^BjwxG~#| z?GU7xF=I7)O3RBac+`b%AA~=v+cqeNYpk52iy5T{#cWqOOTW!+n@N%Dh8=e+Z6Tg% zt^D*>w^}*ek5+Yc=kZz@(i@^3N97`Cb{fMn*BRyy?)q?4jq$kSNG-(nCjYO4J{+Mid8eDs8tpELtFsSNOCgHLRv zmfMoiCy;y3;!klF&(yqmVCIbmbPYxi0^ljvi9&=@9Ju znJsHy{epOf;C~rDPQVR9wS4`c>>%1AFn@k#RCkkj{z?E(|P^fI-+_r=Iw_}3}wjn#D z@>g^~OS88*$#5X2rh}@g!f6;CQ1FGHEb!4{L&bmNCOJU`X7qnCZz&2Wfegvb8(>Hl z;E-S#>|duQ<<6wu@`5F&kax!|frj^jek;Yl=w;83UvV0(~XltH5K?%WuX)Ej_v$pkr#yjoN%&rtJjCtft;cUbJU>q z{eFLRdjM9b3T82VkdLy_g9`j??qL7P#mg!6Lf82_AQS{!wFPr`cblP1hC#YGP-?vp zRW59ZU?oEYtCZ$R!ch+q^J=lkAvfZb<)r~aQEToxkUPZB@8L|9TNT6-){e6oej1_- z){|@3jj~Gk?@4nMfoyVhdPEiagY%O#ON4)6-mq%VoIf}PcU)qg*F)_+>;gPw^PP|W z#t&kH@CtkL=O9T@nV0)L|Az4Ik|rF=0dt|new3M~&^d3zCk_}HCxOWj%<2xwchMNH znXCCRtetS$ZI}rZ&o}5wO_K*`@em3+CLIe1>J=Gov|DoRv zs{k7pYqeiQTbRbZ3%k%UnF|@4tUMYnO1d_HT78CC7u& zJTq2*QRL2hQ`I$JZrMA0>+m%6C%J!_6M{I^gNFPm%HfW=Sbebs-swgqBb`S&e)pAP z#Oy8L^1_YK+3S9SI%3k*%KNe;CO>OSF78X;xuQY!upNekD ze$QmK+dk%Y2ZioDmQ_x)1=eYP?)M#tCO@%I8t@nx?4ngsnGUSr$_s%AfS&Z?2h=C1 z%~52=6SI65kmsUBwYik8a6Mzg2|g{RT5~9l5Dru+sd0leqIjF8Mb3Xrwy8`qCGzcb zDHy#pL5m_6Gbs}jp~K5aZ54m;*<83k7uj4aI=n^hJnh41--U_{z3Pfj5~?PUiCeSN z;ssDVYG>`?#oB>s3o;*>=SO7ZK0P9%@L9lebDVN<0Rg8_8oh5s1Qe;FMLZz^#moW3 z3TaZpmTZ2`%Z1b)Y5?1~m-BhOh|^%$$#rK$ls^?E+l4*8As!F+y4rspEGt=;23PdN z01Z`){@*2$Q8VM;X6lhc1#T<(H)ujQ?Q<-~XZ*c29Dy16M=+E`-U0b-)uS*Tcg5LR zD~54O=x-(sgv}D3Qvl(D8XtLEDsbuN+@@%QL{sWiMA}@622y~13_fh?eOEo>zuNDr z(;5F83~1y{^{h7E6}f-iLYTU2N}Ces$Ra(+3xFBMS7Qn=XH0o3F9-NWNYL=Y-rt zC}OC>nby?KFmWBsTo98z0Vm-D7$L5Zj|H4QG19d0bw8EAbxfF~lQsZE7@6$5rlS{9u)XP8`K*M&zW>lF=t% zDv7`M$U>tC%&e|a1=2R5f1XY?j@m2jn4DzpaxHa^Mi`bU|1c0Wgqc*F- z@s_{b>FRu5El3+#pgblpPSdH>!Eu?Kd{vwD6u=u$o47tw-=Q8{%@UhcKYCfi4U&lYutZV`fCivU;f_jlWmx?;)aS6NJ!UAAU!}W-)Q%a29OKu zf$1#A-b#M~4TQpwVrcDjWmZ$0LdF;fSgws(Ydr39;Hdbk0zPaDVm$KgM^annjS{}h zmA%b)++yTUUkt1b{O?~KF)ioRED#*0QYr^sA@0ZZ_CUrw5-e-w<+=3;#Tngc^{xEPWHVEV1tZ>I?72#G&vU;C?|H!Kk5GlZgjlm2D!FjZj^5EEy*K zRg5c%=>ez5C4R()Nt%JNb1VkNDSa>wOuxiFn+tD8>c)CA9Lwv3V{~}W8+htuBKKya zojrdP=LOo@CCh=z=&C3PPIUkfOkn3dCfpxfdb3g?P2rX1urB^S0hVFe7$+r6OXd|R z7RGE+9U_dkboE?~#=p442DrfBgF3ap0wq0Ky`Rjr=LMj87+qg4Xg(g7=)Ov#`*NA4 z=8+D?vS`a=O>!fFw4VoDEM^F6ZO}KAelUOM|32fN8ib!@y20z;&KfY6SJzA+eIkbS zY959fU#Ul3*&wV`s2r(4yJ#ra{32YTAPA492}{#%wA^X;t0O`Y9LW_d0Gi_Wo0kDY zi;Ig>Jpd*ij}K&)W27V=QNK2Tc{Z{J=sLhb;2OL$X9l?L^plXDLb?3d{B(gB7^NGS6!t#4fzL$l zz~Z<>yH#JE&S=&gvP9&bIgDE~ivT{=>S_e4gh0ufH`dKN9@}6K!)duWZ{2=M{%#vATNBY8Ad$ATkg&>CBo^zPaQ{y?~ZkM zIphJ-KgzTh;iZn=v~4O#{RchuaUkiJ5R&7i_xoJ$qz-4HMSa*T<^EpK1kg{O-?bk} zH!mNLF&56m8z`78yq4d<3oQ;xBA*mowM>Zw;@@Cd+$K6@NvT5yN~f$_Z@&|nxitGn z=}zs>d@*jl^NmqEOZk^hE)pwNHfxA}3|W5(mz(_O{lVVwDULIRS%PRLbX>PVo#$oD z6@gOzT@{8ObnTHQ_CQAoqxn%@PZI%VbfAws8U@hW2!L(8m^A7$ z0#%pKE)p9a=DV`tuqM1Lsw-YzfaxjI?l)&hho^Q-;dCXZjxLu7FA^MoU;9olmfcGd$1vxYvyBc zy2&l3TERgWf?HlF`~w}2DR{NzsaBmbN*M`;id3CYQWHRLC~?(lc{1gB3s4TTuMD?# z9&4pHX2+`H926mTvzWVoKo(@AP!QU6jMp9mZsy1@w>Xeh#3Eq6)ibaRzOJe*qmnFf z0!d@_|4PL?Oz(;)hQLzE1G~ciXahhS!pK%D4C#RxdQFaWJc{)uF_B*DFjaJCj`zoW zGc8#}t|74~YQ5P_9Y8K9CU%0`p`!G+6ClvkDHSBd-iRAf?VH@@oAT$$&A|L zPG@_J1urD6^AkMfJo`s!)GTNuF0Ip$Q`qoTQ|=%T;$Qqa5gL z-U>uoH4k58Xjw|*q^vy;EJSv%wKY##*VkJLVq5yJ5>5o6q)3k#VF1}A=IrlDnM%4k zWgaIk%t;xjj*^~#6^@2pb`K|IpKq9Ka{lL}BCC|_Bm+83Vn;Qiz<=SRo>9*jp2Bf3 zV`P((rA}#Eh9ZGIO<+Fpn`8%vz+{?g) zRuZQNb)$oLoXi(0*Cl9p&J*lLmQ;Giyf;jJii)g1hPsW-OqcxXaa09ib&!$W$| z&NS5AG1E}e583=X;*vF36Qr?>i~_09kI)n*a0Ok^(szDBPT6M|e+S@gJ#h@FupsV? z@pe{DTncMXAb3cI);XeWasI5}{Ittg^V7u?L0}uQ19^~B)Ajzk*$VuT05BPA5tsLZOwoKlAwl*X@Nd4D{A9mRE~Igor>@$l48-z>juA`* zxx$PGMoYiKNqHR;KBdL?&XQ|ahL{ibu97w-*H(7t{IAKiyVs{=eGLA0?P&ri9uRz) z1x>3_PT%@NW%VQeWl|Zwe{IQ-b!KY_3(_*KjqYlHJ#5?^w}io{`Eo!8JLN0_&U32M z87F|tt0RZx+xVXo0pny&EMMSnQXMpv@exgv`7_>cq|q5mr`N?FVsg!E z-mukwexI1Xk#IH^5@o)tk}OrLq#};h$*>Z8uLGNtejzI1Nj)AHse_)bT=X=MBe_uN z9(O31!hO%xNWN3id?z&$p^fm(c+FS^euZtj$P zNtI5wSa}VhaNbuIaK-d2;kXhj!aqw&QUlhP8#59te=j?Ln@9%71ZG|5JaWXMt6iDQ zoM>c<25rl!2xzrK$Bra*ibm=b4G^Deuvn3o(-xAJpe1^a2cKE1Z1e4+qmcT^1dLSb zBrs`afXGm9$wbuKz=*=GHEDX7%CCthNt9~pHfh0(Q{~&FAdRng!WsiNmGW$=^Aq(> zc#M>!f5MKOuHg|mH6<$vh!mWI4Oypz<9d_$6h7HOUUOU&NVknFvgYH9bXFLUc;@NM z1#olsWPJqBI@@3LESsc*B zfLAT!Ml;n-aZjjy+$^#bu!rFPnfwhf7}+_wyFwcCH+W-as`;5MBDdBI%MqI2LLIQL z(Ot$54*Pgz!s=v|mz*>b9R?1!2Ex4Rm%lU;D}U5yG%7I>HT17`(jhv`Q-ZqNmFS2H zqd<0&jDSJo0Ip3HU}6=bL~Rnu5We!M#3N{uCrYZ+7|}Ecv73q~j9my@R>`Oyy_t6# z?im5V)pXp<-hzj!1OtRMMArl&)AX-aeiW4?5)hU|5zdwv^T8a6Nu_+Eu15jBcuq;R zIDeuk-0=m*j4?F*zu%(;Z`-bzlo(rwI6CHzK`xyE*m4F}^y6U32HUD`1~(g44kXnh z9Oasgg9&NLNF4#I^?*9(yV}rPO#V^+qkIR%!3CNo3)%8eBq{6IV8`+0bTi!+!)DRLzEo8%T(Y;&~1BBK_v!sP_%VZT`7-{9%BOcM%ieDiXJanUu!`O z)Wz;M4J>s3lR;e#UX-ucRV6;kfh=e_sOg#+7gV!hHPh|RprZx@B0@?2t%Xa;m`a!-ua_@>6_F zeV5TT5-VNrf7q7%eajvy>jGz@mX$w+A%V)HLvo~UC|Bm&dqYeelffAvK$^L4F4Gq2=U8!S0llCl+I%^T*;GF~_tL$+Ui=A{U=RmsvLw zFn?RlyG&dFrY+-MMMa30967=7rbUF3ah`FRBn&_39Wuctw}x-ZBR3E7`NjFsczFSK zEx2b>xB|-;Qi!!zJBQr)tz}h9I-IQj{X2+RQ5$`W<{}L<5BaX9w&2g;N|9^@{By;r z8Ppx(Vh$CVjPv{?5e$*mCG$fn1U< zahw$ZK8>LA2TO^uq{SsEKP0zK?qES6X{KXWrw4f=CWfoRtO3cXNg{Js-B}zB0e@y8 zV|jN4r|gRI)PNvn1~ay;dl`BCcpm(O#46Gr1t4%FIT|T`al2GFy(re z-~aC1>`&g_owb;J+nZx3+k1j%yzJkyBk-)f--{EeQxWf;^i_au;@IJ5nAZ2TkPMr)Mp^PpP%f$}u zaOMmmmqVRm7S}|)f-g{QZaBiX<2Q7yg)@IF87q>Ehw?PY%j0I2yh}zacmwOm=rB9a zAFC9f?$jEI5SKPKFFmR>-hXyveNVDf%P|!>sW;&~2vd1Uza&bfh`_RviseTZD_>>q ziaVr-<03kkXC{f4<&OVP3o4vH_gUat|2OLc)CUlBbwR~SRj;xU=v8?{g}G~y2BHJg zjX_|i1Y@VlyVw0Z@ai{>@_sLwki!o}LgcE%cmIgBtRhiY9P(u3T<#p;c=bPJ z`rv^%*~0iIr8?4ePGG6GN^=3`UpsegC8`2SI#oab#cotzw5n?znv_06O^re>9*7pIU`|KvZ{ zH^f0y*<1^7S;u?;eSQhAHXAf4vG)qKITy!Cjbh?JW%rP|J)+;jI(y!Z39yR26SS;p zEM~?PYPjN(Te+$-Mx5iE($Qg|hsUc1>V}tSLr^qTopWUOB!5fPiWDFk8)U*Qf77S2 zo`-6cR{E|o4J7igN$*(C=RB{(OI}{~iNubXLpK%}B6J-J6XA)qV9<`nqni!w_(oD5 z-$-;~-Xrbk32@uex_QdiYi-*B{Tv1+0XJXbO5F%&bK~7sK^;~EyK@pi3Bx83$gqvW zgbOZvD^5UmFMmuMik@8Q@hJ^CtY#Dk-VnyNT_+cu|D+lKPed4C#y#)=_g_VJq+@2X4YmiMmP z*SsiqZG#Wj=IQVY-K+XZUG~Y@q!X$uSi!EOCn$6iTBXS}@FMxN7+fq@U&@NKm`J}|GJy#4e$_VMes zTx~n!XtBF$_a=zBbk|coQzUZp9yJ}S=-%~&Q^>t~ z*RwypeI9vMUOnA6DRlHjL7J1TYg(DW$5AC zw!B;TJZm=2Zf?8AzaHt5=ZrS3V6}ZjU%{I($?9H>)c6f+&VG3Lvbq3QseQ^`gEHG{ zNw+VniS@%Z|bmu)p?tm&KSzLwD`=+zNjPVQyDG!xgnV70EQKJwB| zSzD9T^~3Eu>AmtTmV)5;x)t*m$MA4~B1eL+kpc5`U|{ zHv6UQ)8P&pHpAab7l*@i%bEe@IaQhaC~#pYWb(Eu5PdVL1i#=w;i$m;V2Thtv+y`d z$>`C0#RXdkhW2f`t+SCrrHvp?O<_c+!HBS%0WFi@WJkFV{5Yg!%gf7*Rx&7-PJW$0 z%eD*>e6>jmAa>ero975J%16Ka@_)-O4`01{`1I*ulU-e9bv<}IA|sOvz~bgK#z?`s zTS5y$xA{6rC!3EeK^r!uMgDg}w@IOb6Q6AvJdvx&=JZV=R!|DV#<&B%Yd*%BkB52#-j|v& zZv_O-`MGLgw}}Wm3o zOH?(Htb?H66<)Xz79};2Cu>C0tx9a!#yq8|OxLtUVPpbIq*C-sGco-RZ>WO%_28k* z;$Q0{8_jTSSyXgbD=$H7QLExAS1+Th-L-kK>v+0Uz~G*V0K}j(r<6^N6*d32I+a@} z=*#ATjX~Rri>N%mlD4@hdp-QSmF?&IX56?s&>UeQcONYkPY(Hnxv8i@hau(3`OmIjmk7IbnbY_?YSW9p=+^m!y(v!%*O@QLiA58byjVIML0eU&`YmaYy9AXP=VK$Y ztN`8#YnU3nEeeOy`<$KC@8UOaONhx38Mp(fW(z2)1kl`lEvM!tm12*MN@1 z`-U}DR8^!|?aG}2Mn+qvI4S)o+!SWeA=1_6ci#em;PK?{s>2%<5j&9(=%67eEpnSU zO{pbtcxb*MZ2N41gHDP2T-(WhQ`l&!)@Oh={XB(xa=+ej8JtDJ>&SPl+j03slwwz* zzIXq2^?h{4=FKrn<)yD6F>h(;eSEux3cd$oi#vKO|A~TDN#*xMFvP+FR({)sMHPIz z`EH`&2rc9A_n#tCRJI42!LhDp&yjn65>PJSH$BRtc!}#ru?kXpivPF@ugW?j{_G+~ zwep{UoeH9hBQF5D^2D@fbGa>SL{W&kD26kv$dt=Gg5wQ+&k!kNbOWjCubS%l9|15i zU55~q*w8DRZ@1zG6%35Mx3jO7J*3S|7o1I>f`4G0qZ0<*S+kb!1Vs&aJ>|?>c@sWB zD@9H$SUP-;z@6RbF1T8`+)abS=+7haC;~uPLJX6u?3YcsuK$+6k!^v9%#|e&7ohJs zd*30uV9aM#Z)20Zzj6|_TdH?$x%fW%x7|}@uXAgJm$S-f=b@4?LiFg+K&An*kl5I- z0v8&8^BZfNZnx2wfX+bimtBr~$x|#af&)bV*S=>1^m%66S}$~K^32MDsJ{EIteUUc zB_TGiVerqy>D83U3&=JbL{%`~NSSr=o$yPl^fDja1C?*UiQv~Rk`WIIr=*1)*Ut74 zHBbMova7X(2WWLrdfL;DJt-E2G%Kw`=LOHHd?aD46kPQQ_Jy4;p7|-@?As&W6VNwT(IBb5~Cf*y8Ds zL_9KFElpnMBJ4(1R2zEqeH@dPTDP+D^4y0*5c8dJnq(x`k({5##au5OVJY+Hf{70u z(fwmyCcvP0lWmRJ)_v6D`%fs4&t$|`P77N@pC)7Y)i%<^U$ksp@5yqhrVU#f?0k_% zX|JH%6DJ1#u zopN!)2D5X!wq-qP0G@C~|NWH_qIFbgr!LEMc0f+&NVLqwVbNJzM@-Gqw=KE8l)k&D zutsXA%CfTjeh%*)1?Amz*w1o8A!?W-1C=tVX^Fz<;YE(*dgG5NIZx~)nJFj1B5kP= zr&&tf6t-MiKD07o?pi4DzN80;N)p4w>X^C`Y`7kWuctyZMHKB$S-F?3PxP;u_AY4r z2va{7$ktv!e@=j$p85E*p$PK1?*x34+owP7&7qx{G5&|j@Bn60*xIM}@_ib?6XQ&E zBB{`u{P`p_iL=f*oBFvrPiPSL+0>UI$cOi73F8{5vpuMPGpa0-jdq0Y(KphgmZ+(+at6xNe_j4r2QEFRnwJYXu0)F8UuGj zfr<6?)9_Mz<*=bWP_P3eaqWWZ2*(+JQ8wv`KVWyf;%><+tGyTpmrIP31k*rmJdl0A zxp74TK_w^A87~1g@ijdRV~QYWfbZ^ZDh)-+OC}MwLz8u6qqg*r_R_-8dyJdRx6xXOa#h#{xi0Kn?i(jd-)%5_i)TmRC-{h?Qkhn}djc~Of z%`K&PKr@_JIn`cxQXVi%5=s34o^N~>-MlJ^QTOdG%=yx*FHFs}$8A*%vg*59`j8TF zG!s*%$#SK_CHU>8-Q4mFjE*{kuV}&NkMS?sbs}tXOzWH?Le`9VkdT#N&EJn91ht$B zP~e4F?&d&owG-ihcVzf~n2YjK%j)K(K0p5=b{sQ#sWtX#E|Nx`v^h~(ysVpXi&HHE zlT$g@!th;|%7Lq=Dr8U?bItMGal;Z0+DiC;!MCOdBRTlL(y#N4t^f^`u6 zfJfyy! zM{#-~+)1#1HLQkmXPz9#`GE?C-$~U9AET#TjQr+lW78(KJ_?6LfWYgi%CWGjH}jP- z5@8)+x{zP4T}|=^QNM0lt?!^?O5bguN|p4MKc7J577E+@cq46q7dzV#KgBbI?7yO7 z{`7D{pbTn-6u44I%T2vWa|C}_ZHDa*-dC^VM+ELO;6ug~DTn2z9ZikFbk^*K=gBA# zhadn$s{P4`R7ZD&FV0pUtJ-f_?y?|HtPeCAp$|i`#Rr`~b`J#O;|*GoVADPIG7Pt( zmSnZ^uhT_l*~VdBGnSdEc;|N=(@N};B$1FQ(4>B>wi9iS?*F6Rs~I7v#D{MG9q7%l z`paiIsA8B-)?goL$>yni)Odic!X|i~sh*z24PVeVcdnc66@O?Sg|{6`#tIJgAQMRA z6tDt0{krnplowbJdOoQ0FIkOw15FN1j)0ClWx~iD5~1NhS~Rf==lNfZj?q(uCFsW0 zl@+K7+31@^+g_c?Z=!{Rp7=Fsf1%ihk+;EHUYv>yE*8A13{MVt!~sH653Q&QrBwlR z+yle`!J$jbgsnpgtVc@Kz&2uMYZjmp0P3az0Ak=VE~szv3-Pn`r7Rt@rn%Xj20+Q% z%G$*RMV9Wdk>Pu8hjNw*c!jA!Rea#LjIhlnI>9T_K4=k3Y)B{*TV9cv60B@h+~1rz zn)YIDzlY&th~CCQfIa${6h2$+Rhs)wxH<}!Z5>r4^FVF*vP`)OVd%+*VFq?z;%6Fo zBqiJtTaIcDN~MK6pDdFuGe2ETW)f7s_0UijKToBlwdV9N;6AbXIdE{~HD*Yk*Mk>8 zI!|p^jLe!oYjS-1Zu+c~UTS~}S zt;f1s>^loBef>nrci&f~2YL|{)89%<+r{pvBMdRPer;mmK9(bMQ!u>|#Q1cOON}VP zLPg6cefYjH2}NR)Cta9~OlTz1&FWvzd++$@6l;9a1LCI*MefP`AL_AqT}@D?EqE<% z_W+8|$*<{&nD9K*)MJqwinuZuAnWj&>@63+%SjP5hfqGf1?Bz>3!H7iuXP-`bZ3)U~jhkRbn4=lvbVJaKv}TC9^~MZaodPIb zLqP$why_cafK&uo^VyhSSE# zFA?KHRV3}9-U5^rkE*l)h#%Ae-S`Z~W&tw$9!1{igscAoS%Cau?b^>-GrdwfHxFkO zgWSwCXD!+!r$I(cr$f&4dQX*MsD72-8Y4-7;QSb{HdJqpK$o&Y{{i-O{qTtH*i(e# zDyu=lI|4M3Xqdgt)$B4lS0Vt`^<+)KY1yrS;7)%sQ?Xx=u2~}s z`xWNKb#?W$FAW+fiWlVVvxuJh=kKe|;AZVBNAQU2WLvxQUo}yTs#E^qwpm$1yv8Bw zA$v4nQmPqE(0$~pqBn&{Re%{3WG>F2RS(=)_>L;Vgg;_KZpUu&B4|Y7ryX)Ro_&!V zhw(76p=-Qwbbv~?1!w2f7XusR4lYRU^NZV=LZzFbrbFmv1i;(&>Rzj&fJwn%!Vis? z`S;Yp&iH#gf5bTFDpew+xz|R>4)Fo;E7%KAQ!l1l#i7lT9?))rZ+7b3-NpQcsPYOXQayz(}l z*m&i}jeM#|*i}5UZ|rG6iv+V4OIOg&vtZ#Hw6k5qr_BE{;aRTdFrms}-LsiGB_~IO z5#vSL0D^H>7`N@LkSr!EtB!FktqJ)_ThmB_uk?;iP`5%aF_1=Ne38gOC-ok9X2Hsj zUqKvxQFzo?^vQ7?3adP#mPqUku1_B~S8BG|ku_iO&ftO&q~*(`q%=pfh9z-rdFzFE zUo%kZx7f6Rz6|PL-hCj1Z+guFEUGa#H=ziLH=6?%m~~q{x4Pa0A!I{J6>Qc>V_HgBUL|LSx2;Au=1<4#Eyy#+q#pOey!C0XEuAr*!mlbvId;R^S{jh#r#5Q&rdQN(wZU;)Y& z1EfONqy%{}sF2&;c@54K%IkB=78`KOs)B3l6KJug^x0XTCp*o<) zn`P|xRmoF-DnauOFxsF3EW$`UsyIiap{ib74z)C9s!>n?p6!ku(&B84%wyGEJB*Vb7xdbzoP~946lspYE zu$5=;-&hs;F>8j$cvC6^`k4d7E`3#oO0u(g>P%*n9h%SRTvVfwT>m(_zA0|@mhfZq zSRd#NsssK|K_5iOs@=R9-zo+fudTotbUE+RUZXoin}#C5sjFA+E{SCC8x+t zyeD~Fa+`f++4cbAapt^ik?82^P{jVi&g@6ITZz};1rrH1+{AUyt*d)ywHW-Crx}WD zsr;>8StadF2Ob>i+2%F`CX{iO9q#J=hcOefL|jk%O7{>pRrOAIiU4sIM6-xEPY74v z`W(+K(pB0g5qp3A6%mBBI?$%nARPHsRQE5a;Zm?%jzcPtxCr0?iQn1GFLN|%It_ro zU!&Q8;ovA9VP#W0*_fKVxZ_i*ygp)1|0ljZq~{jwp9D$Eo|5A~?y%^OE*R>Kg|Gj%9N$JjP70W7nH{9X;~duf)WIxoh_sIP-Ey(#_qkBWA2KH z5J{@0{J{(Oplyu&%Ff5u<* z6BS8z`R7qq?=-j3wIp*fkm;yxZ?8Bh3gJuz9#`S3`oLCDM^DLaHV^RYN}Gej<$wdy zx3N$x`lmZD$?k*0vZUBjEC}jso~93L`nfYM2S z{TlLD3e(qk%K$5#F)@Ovrb3_OJ+=JKZ?bL@4=_0t#+`37>ZGRGLh*nfE{c1L)Uj$H zsqA3}D}_rLb5Q_mqrm#+>l-=s{5-?EULSOCdrdgHq;aCE+d(wj=+4ZYjh0x zEhgn&+6*)mIssCdu=%p*u#jKYyS1Z?|68^*h}ZFN2w!vIv+kng8&Z3Y#D!iG-Sx#xdKZw18%(`5q z`RWiuTr-*I9l2ODj}8;>)Sia|=v>DS!Y0Mnj@vT>G3oN=sIUXRDzb3YzkDyGuh5Bq zVoMt#(|0QI{V#GrlWq)7xD-%v6yCv~&$`$<64oWdJ4BNC(x0Kn{SUY94HICU%8;J) z+>?u8+j+JM+df2&>am=FQ~3o+c4KsnncX4cSO2zG=@$A)QS07elDPXuF+_fA5*lA{BnMKs5tH5Qrn|80 z?wcLBl|*&pSPxhcy!G@L%0e15r16MpCK)yonZ5Nuo_LJIK>Q=1f!6lrc*mUhXl-k? z4>#Xx71a63;P3>l*W3HUJEgn3@y}~guJ@Xt@wDe%A>zqyV5Cqck0=4&4f5X+nGKUDUl4XfG?E8U~ zqhcs&)Ta!116{pQ&vM3@$6RV1-VSKK9d;3L#(TsnzYBm$A78N~mUw_++#!-wzFrv3 zcPdI?EEfun{ZiWK<^FA|O?1IZHqC zfjM$Hud@TrIWmUlukj><^Anrp6}@5Er&K#xU?O>?Pyn3sFQ7{$5d9SuC>0hR(xDOw{KT8`ywd?fS;C)3WVpo;1MX%GSmEA}n zi*}3X1dPpZC6XVF`Eu$bfmX2y8lt>`nYm6|4W=xXXMJ_(?0)q^XWb3AVODNEukl95 z2`OOa-_WtYjYN>)lDjG^8!Fn{E1D&ANdbgUzyHAJK&>?q6^+-B{kZxo!60HXKWN)P z&VWFPmOlpBgEbNRn1^RAHYTt!EBjxn?GBOo%3p&{a}oF@cgKq=gZOm^ZvR_PEjjhsYY@T0DzxZ!LY4>tYL7lbj9;&oMeeR=M+W(V+r{ zuLjCZLnt+pIIaB&_V#Mv)7P7rcoDqus+XDx&&11J^j003!zwu@3lwW%j$(4Wo4Q=) z^ix-mEx+BR_>0Q?+nuaj@_D-7XNs#e2%AbzD`*pOxbm;qR8&3N?Om>wmdj|c6%&+D z)lvGGXD;E7Tc>KyxSK8=*hZO2l3^vVdH$Yqr)<1Df>?jtP#k3!BRiC8!eeX)2Z>g<(uIy*^u|s+IID41hL^67J#<^$$xLiG zz0vyy?bAnW*+;jB&N7l$citIU2^7c|@=fS=eDCx8HqdOKh- z#Y@nSfQ@cB1A%9!$h!LP-|U}tMf&i5e_a-8xk{&Jmf=}dSbh_{AN`^K&Be1R5c?uL z*ph8jeXz&G&3hRKee?P+GL3+XoaA9P!nnd_Lu(GtYi|_l8QxM$(x_b753=J>)2JFan0HA*?trb5_CfAi9EH+hyNu5fsE&Fx*k}t~o;K+U&+JqJXG4Qb( z&8qYw&0MFJ^_&Hrn%*#9<-8e7wvgqk0EA~huA^Gv3loajTgLa|unY&`p}&3M%1_+k z^>R{$SAr1$Ce?KdU)Kqsdj{zVb_PxosdsSch`T`|K^9YNLu-e?F&ProIo5iLLA-0c3$%M4LyNrC$HM8#MqH5fw&S#04ZD5!HJ)F7VTEEuVJ zQQgzCqOdq2WOV`SGt~ptNqHUV&D+~qwUdBLWFO$}CFYB3M`Al#$}pdh=%zqon~QKw z$Q#dFA)$Lqh|drBu*ZGx_wYe~50;SIC&0G}#PK%4_Bq^re0@|nlpy5!yxaP|^FACV zT;Ftc$g$RxiQQo$|dO0IC@TzG9(}% z?2G+>C$y|Sc0^u?3<-OAeOyZff1&GgAg0nmg2Wyab43uzdmn1R@!v0gug!nQ91N;D z#fv875&^pf`PUNopNR5boUtl?2zmVPzV`Yh4l93rG>>G|W%(O{&s$yV`UGL^H4#>I z&j2J7r1x^E?Vf(7+X5-1oo>D;{@3aN;H%Bg>(*~tmA>D3Z8wa9nGNeo#|HkJ*DjkF zRGIuv2RK6;ym>^5dW$)~>}LmGZv5_8_=Wr>-1rjhixxtDD@B%dW#+wok)ctpG&BKy)P}-1?X4A$E2i@^sZ|>Y@l3r{5Csr^@CEJyJ{&%W^r?FP*?Lz)GF`N_g(y?rNRp)!&LIS! z*t)N-TMFlUDcN7&6w*pe*YQecRWBzTt4dNyQThpYo;O^{6^ME9jPadW2 zea%G)FQL{!u6`E?=1X0toWKOgYXc*2+EY9a0s9U#mn$I1Sr5+b$+uM++_WE zkAfgk_voEZay8?0}_a8C#LdD8X8nu_=2PgBLYPfP{ z19xpWHyFNv;IM`IcCg_M_^0f1uC#jZ{6hJ|AD}40-E;6oaaP!BE51~jusD^C-dx|< zRLMFM1XwbFI;lk3w)L)vfoZFiYoJ}Wp zD~iCx8xF}4@|V=P;~>sozMtWfP*>nydMdC3S;6(`8nI?~n0kX=6{Xu6kLumZCbtGh zE~}h}!I}V?MjW*!xoDGuHRuLpi?cl{7Q$q1l7sfJR{y+1p6SKj^APU%N`WK@ zdQy~xI1WNQ&s*}{Wx*Nnmp>!wgREpS!V~8BvX+tLxFKm!UFNF3-X_-}AMw z*_DRdww;O6uByjQ^=MBT^q0xuUmQh;^{U;K(TlQooR~j-vS*4AcKngUbbb6(%(ykF zHUDHeZ7Fi#Vna?CTHZc*E{*S!ml=S_j`W5!>F#Hd9IVn8ASgh*zAw(1jOscr2Tu-< zhMJH-^6I;?{NkwVdq{y}f=(Y6Jj?Xq>gsWOO~;?Sv8yLv#9@<+o35Qnt{5Kc=e)K~ zkrC&z!E#?is>#yPH<63W|>Jf&XXMv&^*MLy5<vR7sZ~+3Evbp@ILt_cmH`?MP1j3TUi_X83e5-!Qho77b+@b1mNvIw>>8B7vVET0kZe?PL}NO!85N4aFhQT>jx#!Ez~w@ z>-95Wjr`l&r_x#_O_I~T)2lh;_u!Q-#I0K}5ChW0X}nK{V#hf8}2A~1e z%dkHK5Fj%t0hDosl|id8dT6ECF#s7^X8>kUyNro501;?<#`zh54nIP^(Zrv>;`4^# z^K@<%`ZcV#r5Rb*SYvfp04#&$96&&59wwIhAQXCe2SqwiGK zOCZDk93TKzaGp_p4u}Np%wWF&$b!~o051S;pcomC7XUhlAc0M)HnK|q45&PlqEZ6j zW#{yFUGrw~^SfIj!=1P9%t_!azEPjIr=R{$5&qJ471Byw!e1}Tzr_q)EC$jB!m77& zO{1Zt6t6%=vPSDkYXNbcM=!(-&no~2(8%Vniewu?&&zQbd3?;PY3MiB@Le z8%$DUUy8jZxK{YaIT%`uj8*F{7|oyJRf5Iy`zke3%onC$MdCEOyaP>eu?9NAL^}SG?dt%_N?mulx2#O z@z-|-*>?Xyz}GxoO879jQ4Nt1+;2mgp;M=m0DqJEDdGZIE zoQmql^;ownu*#jbWp*2ufx_byD69OW`mwJZ8}Sex0f##}Cu!DUZ5Y$c!$a99q({%e zc#|Y$VeQ2uX1|qeKi1g}E~j>4|IC)khY?&)tWK+U;X2Gy>d419B6V|KSjJg7=GxNj z)XUsdqE8LKFuiq=m|N7AK0W>vjUu&R*(3hjx?ej?g_p>E3TN^}w62OrARAcsuh8oE z$qZN+&aOloqYUj7J!WJGf%akDDpBOnCfj33GJbovg?=?+uUCsqMuxtc=*k3>t~K=g z>wAXf4M3Xw!^}gh3vj}eU|_b$+9Z>;o+pNWRnU$2H?&LgXWfP9VC+RYW8vn%x>nBk zya7-H>q3#n$WFGHNtkqmd_RMC;k6;(alD$(FD?YXAQw}sxe?|16_U>LHAN*6Cl9e<(byuCsss85JM_q0TSBwVj=egtOBEqs0VFc1wdoTi{)= z2X^6MxS~>dfe?zCCl9yNtekW$9~c6n23YoP-f0PiGwlIiVWRnOHwIML)cKE69y}u{ zub-t0jXRKbN4S3*U&Ov>XZ3s!c|Dgtyn!Zx|y1RUs%Q>$p|DJStA&M(U3{N!`?u3To_y;`#Uk1oJ=yptt-O3=t&~iNe96(vhrxeT*{SuZd?&j%;MC0yke9anVm5>a?d6YT@Ni&RNlLImR<-52 zHUd+M5qfv|HM5t{o56Aqzy|iA+F$q$m}1-U*Mp28J>C90DTDiJ-dF&aw@=?~o?tZ( zNj{-gSLHNC2S4$-7CG`7r}5$EY%nsIOw`-+OSkU8P7u=4-5QLm|cA-{SEJ9 zwV_`Qo2o;rk%Z`K2BXE;-<^6jj;~R(L zJD$!G!T>mPWJn{66=0PtmKLE*{_7<>7^pYF*Heq2=iZ z*>0?*AStyPM~Vny7uOb;K=n|F+-XP&o4KH~dT zMSsm{qIkG>!U6|~aUE%7$6t{Af5y_D4Ud~a-MnR64I4+fZp z5UsJ3dH(ny@=D`e39zqH<&V>UDr^c1rU^mWC2zB5o&u?CGAt0KSJSybjjRyY6;kL! z0>f;;UBI2)eZ_VM>>{Pcez2Pq!Ev1sQc^ii-C5K7VCCIQi>aTJ9Wgl^OYtR?3Z7RD zq@~7<6CW!|Ot^3auPAAJZ9At2^my<;BW%48M|UAn@)U;wnV__g?G=zgx7yAB9(cG@ zs8{97dx7j0@6F6;RZPHqNMu!+)&Ug2=l(y41(=j5f*f~%f*S7YE`n*U(o&PYGWAI$dIj$6yEplb)pV#60%1Y z@{jc;xwU^BrXRHOY8)iGrI06ym9}B#y(r;(et@KR&<*r%`ZrdcPiISPdv^SVO3NrJ z;z2Xa&y-1s>&kaEZk)ucx~~eSkOX&xT#@AaQbvA&*EZ>%J3@de4Wo7SxrVU#=5?gc zfULAJ3DdCd$Aqi~%^%+U0g~ZpX7-YHbFJg&K>2D&NEId2C{Lv(ohf{aHRgvNHx9|7 z4d93#3VN~|#`93s1lk7UXs+%{NR$_m2Xt)NU$h_N09|*^!WpHzXaYT3w2ALXEnUsE zRz^Fz*dB=?NB)jCGvp{t8J&?s(5vkM+&?LVv&I6`@3!`-5~d-{piW3wH^~Z%17uIF zRs=@&!$ll!&%)f8nQ4D>3~xP!&h z3~C9HniYsvroU0iqO20BO%B#D$z@lg!usadwV`ofVn_taVn6n{%}xMC@C(`MbNwCi zs+u!AnnNq80dsG+dq;apM1t%&bToFHYSPOmA=ApyZyXP8`#P_8U5S-VKF*W4G^mp! z;A_(Fad?!okOUTOQTFC-87eOTAr_)b6SdJt5}e7w03tsQ21{Ksi)@Qe$=B4WGfLvh zzlrTpgh+XiY%Z`e(}x=Q(x-PB{VxDTFss=Nlve;IYyz?!m7~G%c0va8DX%q z1rI5Zp@cw>b=kuBW*x@7mGm#?dl{qN&&DUKH|B4HB>qi{xi;Pm0XgF4S*VAG>-swd zkIKK()L+=$DTm~4#zy=Um93;Xja7Xda^jrhMN@3hQRW59AtewrC7@fhFnbIh?$=VM z1Q-Z!J5NKJVQ49J(m_(PPi>0Tb^^j%AFwojOya6*lV&-qEFzG=-;sfMWWc#kbdLW@ zHNS+dS-63X;O_(v5J$~uMum;Lc4Q?RoQD;{tI4!8If z(>eerK~!of`Rwr?uG(M}ZAs|XD|8dsRGC~Q(kV}YBur^+9tA}Tc(s^)RoyyLZ^%6| zZTmBm9XxZaUNPZgJ8Pi!}?kpLLk{A$8Ui#spDDC4hiv7nxjfVQrAfVC&K$w{k$*ZdbdXRSnUrh*ap7b2ckU zj>1&81)+QObQygbDKH%RKjD^mD0hPaZUzTF7;{1qdO|=Zhw^F-yaC@44m6=2S|y1d z-j4H8PuCx*Wb?kZ#e=z3uO0vTTpjEf(wUwtDI9#ujCIvX?^Q=IzCl={#&+d}>jQj_ z6aN-Key(kXDTF}tgyUg)AkOSoT1a5-cg8F|xTRhym~IZ|0)C81og_zZKMj5ot`{tW z%VH~hu=XEmIgr7}M~x3Fa?8JLv%RC-FBHtF2ruL_MfHZ>;~!6#!C-*H(i=35i($i# ziL@l>O24G@2h5=q1Lm{z{V7xwQ%Evk1A?6)%2m!# zP=_r4Y2}0o=^EYc>8&?$8$1jeAb)2V!+|ySL#|?Ul!oe;zdL(2WT|k87i}yCCGnwO zW}C(|^iS)Avo)))(2yII9l^gPEyxpHlO~cDx(Pvo`j^9U;bxwxS)Cqjav9xb zqR3@@4CIyOqwAgdipi8-+ppMB))y6gZB$>d2V?hoWd#8hxGYt7V7vWAn`; z(T0Dv^ykfcpEysB9fub*A77;yr~>%~mClwC%>B&Pz$i}k?pGZC8ZDE$V+c8fpWoOWJAkC5J*&t8p3nUzA2DqW{+%7vj49+o+ag-pP#`MuL^hl z28g}^f-0J6*AO635^Cpp0v3_A&N$TvvX=sxX*f0bIAH8^$CJ73mL3Tnr|sL&Tu`Ql z_qYQ8K#))W2?f-+FeAAm&{F~Ynm0tqo=$6xGS@cXDBSul^4tjC&*uvmaJ67f|M>8R znLi4*9yOrb#Sred`se%yF8b&7((Yq`eqDo+A;fKd~m^J#mV1`#s5|By7EP&=h3u^Vd(5wB&yR!O5jb zG6>nvP?#oF6TCFxUqczZhUnUM4MesbS^3E2C++fd`F)xg#&IbvX{1~2$L&ZJ0J@$o?>s4>^*I0T8 zi9{PKi&Z7!tv7U^h)GJ8=}}AtdM01aQK(s-mWJ#6a0Ak)8Bz}fN{z4RjElN*+VkdahUp3 zOd4N)k8+y;$@%WQw34Dfwh!8_2)lM5W{26?TFNd47TrU^@lenR>^Pe&LNG@RXwTbN zzC0c0F~p`m#}u7fY|Z`jFlo`-gqd>9!{{3pN)7Dn5m)@m+=I73^h~Qm*d}9uM77T9 z)(aKI3aW$8)4c_!ag0us!>x}9$_1ds1j<1nAsPUciL#wetpbgEb#U6*r z<#lQ<$ukbO!QUqxlKj;7kwvB;Mp^s_SMj6DtrF?yq?iLe13L-LiHV-eXd zvEU`7KvUttyWb%WKK`hxZ=A&&CtcW{MMYq5<^W z$@aan#AN7;CGWhnKyeZ6;h@-|Bik^wH`(|C(T|Z52Qn&2kmW12K`4ty$hOOxfyxRe zw-tJj4vw0ElW|E=_}E=|aG z_z@{4ORi>%%50r_7jvm(m_FrhxaO5Hxe*UP3|Zhd80_SCC5q>Pb^KhoCfJ;)^IjUh z^VWW^ARwVQSQcBcm;nC~pEX#F$MDiJx3YlUzBQ+Trqs@IB-Bt6%aXxNrE)>7@L}ka zkA{EK6;h|neilzCzN-fjzkQZ4BR(3e-$0=8`UtVuC45fGKg?B4Pvny0bqb|nP|6GZ zCigL18Us0nFbfNTWexTAx+mI+n2uQ#NSghe^dPuH4OYU}kQl|%NXU_=!Qq`aEe@-= z-4JDA1?zU0>i1DlNYag;-jdV|!1*fuK{^JdnWRJ`51-Qr6_tQXNiQ{+M@c_^yAUDl1fG>kL zzx@myko*qz{bgA7WBO+IvHLUA;$K+j&|SAZoRP7;xRY`*MYjENdlRkiqqNu%7|iw> z0lB3&(QqpK^;b0M5j(Y~|3}*`?|vH*vv;nqUb{@)T%7{tDbmwK$S{d6xi@~%==0IQ z5f`QyjBx_^pIf_CLL^1;4*(DOOJrtI42uXs{zYlHW1sY>q!m5!OB`BW_UJw_&N?F| zN0ITUeML9j^$n!s{Bt}piY3DyTS2lpVrpds81;*uJM?Ny68s(6I}?07C&^IuM&~^} zUK>~8FaJIzB-LYxd16Tt#OR0#>A;5`BhGxS0eLaddX(L3*7u%MwvUBDB)+6*X9Xc{ zyf?-2G$=NkW#|ZX zA-;?EjMLB=Houkj7~2QuKl1?+UY;kocQMdgQQHd8$88W6LuC|4cTN`92 zF;6HU8${&YT<}gT`MzV3GG`BA-@};r!Ufs9SpjLiD^C4b7oi-iBFQbyO@N!f zkJHd6G5BwtXDA29L9lJM|E^Pn+aU|VJKj_6_E7(S3n)NNy`6Bz)kNB zz01!rocNYG{x1?KlVQ}Fky7O&L^wHq;bOoA^D32&x%e1Ox*EA;tec1)O&`J`<-$fU zIle0QnSU39vDi!2O-x36kqG9IO6O||$B}EK1auQ#mH;Wy9(^jma3Vaf8Qms#EcK#^ ztFB%Q9Q|xYD2BJG&C;$#9&ZNliljb6~l$s*NGl!n8k zM}G%v?HQ3tGPs5>HTpVceHm?4aM~FV7I~>U_kc@>yx=7IqU}a0W zU@1~Yi8x~!|C5odMmUY(%+-ZA-FOTKupf^v+gIc^PLKVvup}U(lEZ+%(#FT-6q*E+9tzZw7C#DxPbK|nJBt_z10Hx;ql(`&UTlX(SPsb zO!EFiumTkxfjmP(;vvBbod}d>VkVVx>Y2atFLow^W*@ejy}I5lf``yn^THLq~N2X zE~yT;blM|OJtF%2)uBbNOtpk}z<*^71Ea7Wu}+C>qm@cJh*&5R$@{u)W_*|4rGwdw zq(8fr_VO-#c^LSU@*w3ycz6n-ZDu6>9qE617*Wh1cVHfoMh8+Ga?X= zS^AQZo~ceB;8Pfj(>uv{(A6%Ok@&yPhq9F05e0iIkw|;Q*DDS4F0g*+6+j# z3v0i%i2)xV?8viLYX|lRgdN#g-`(8^2xs7r*xuS`2ZT$gzq=0gc?!RG+B;hT;Sf+_ zdv|vo>QMAq+*yY@iF=#ZsEv_Z29wh-IiE0q>&j3O(fWVoR82+11AoZZn-ShkL^K)F z^o9#XbCf?o%7bV1gToUy<)P_}dG|W!t{V}efTE0~R-KmV02#u79T#oEfgpM5oq)IV z8VdGuj}AKE@}Z$(cD-PddWhKgc*!N`vcaIl^wxk|=0~fqXCzJTqX|k2`$-DiW|t0_ z-wxmcM6S?lM$t9vCx0pPBE_@WuY+vsUZM&0ni29OyAm+}ySrNzX}$cW?QimuktLO|9mu zj{-d)T##zjj3!d6I7E`gbUHPB=QvKLQ;&;VmU8KJ9+UX+8h>L1(*Z9hvIMi6X}WY= zVkj+u%m}!}A)?{8j>9wveBRTJp(Drp@tng3``ZTC++&wk>FG4NCn&yflQBDP!WGVd z&C<(Tk7V6s#3C4YtK+Dg}CFHqnd!)Rp5;f0&@O!xOT3ZmAi+@-W#{z0Wn?7?V z&Bdh{D!o|E_9m&`jUF=KMv!+#dwiTln+imS4iJ4ZGgc5OZOT`UCyo5nIZ<9ff zrHGkI!9^cugY8DeEYJObU zYI$9}j9OlA?EedDc|BF7mgoDSyTD3D^R}etE`GV z3{pIu@&jLj+`x(^$PcX3tp{?+Lf*Ryvt-D8zJHG~4sa?*@m#V@-54WkZVP(D;FiX# zLMD<9ARr6y)gQNk$xdQ^VoOy$52dPEoPbny948=E?LOvI1R+@YK(f^5$9|?mMuR%? zGK08{bIHRSw^Y7%Yb|qCIc}*;%hSH>>j%x#Y3qzHZRXHKsmzKSYh1eO^gY+m_8<;6 zGk@LEvcdYB-Fa^~oBJl6+ggR#Rda6~z4RU@j6E&(^IS5;^qJ`rEc&~7Dwr=C+GIW_ z01VOjh>B=q1|~Ebq$-C2tYEjM&YQP2M@r=e2asSZ5d#AN$K1G7+qI-{BwZ9ca$vr* zw_uEM193{NC+!FkU8YwAPH808+W8K_>VM@(_WDXS{L3DE6BkU(YMXe?5tz{C_C6_` zK-1!xH4Zz92-2@d-9)@VBLGd5l_l8VUa|)Lc{2hx{Ug<(imt8=0SJHT#8~KMVg!8( zA*GfGF!$ow^JQ4_P;mwWS8-`9uT+Q?r1K`tOPbP6dT6Wr?#=$Yi`S=TN53Av^nbv| z8Qp*$!tc8(;+X-y7T+Pq=jOrmVZgW`4G;1nuq>lDAQpsIGs53s1lQf|?SSyNE~Zg2 zSc(&I@E|uS?^P@tP^@ND97YwdhJ2wCwBCHro;&K$QH_(i=tJ634CD7A0wSO0LY3I0nyGyY0@1LVO+)kXD|J^*|^=omW6RSi4<6fW21|GcOEYhgy+ zn4kYL&zQd$%!~S9JW};gP^0p{N&5Ya$q3?nk;XTeu>&6hGbDxAd{a+?)>HZ>yzhq<=C0#-9{kj1#?9zFcbu|0Rf8DKR69TrnUprgF!iMdT@r z>VUU_nG&t(SooPD=c1(k>Lr<|NKDBrh&`_Ywy)e-Mx|+LK*TM!WJkh znq8vE=UI-%zXL(j&NGM>$=`$Sro9dr{fF2yD^PG>h7b2L{84?8Gk=A9u5??Pft$Gm z9T4Aies?8iERN&6e8v1OIKMqJwkYq=LUliBzLNjp=j_#ykc03gl?=jEy-Ly{m0=#} z7;=#fSau2w>1FH6!Ww@R!bMADk&hi(-Lqaq{0AS(f*_7#ld8ixYsYxhY5etHXGsYE zd4BlILhCEy7KoqhJbxP|?EuQ5LP(~mby1(#h=Wz1^qFaeeEq)4U0d`kpD1X`sr2we&8$0fg7{(Ua!Sn&(F zOww;i6Y0$o@f=VAk!L}a0l|g`7#0@d>E`RB8R{SB05zEK?|+r@nrZJ}^f!(t`K0*I z;DV04f_KBD5mwsG={3U0oz6#pjQ7O8oar&t#A%Vc%+3WMOFw_8#b@0p5;67C@YGct}b zWP@*ojVT>s$bWVNc?r!4)<~qoVs<&cDl7(Oitq9uBk3Yo*1#uYBRVB&_cN1TrjlHy z$iybYQ8H55H1#iPuTc_9l2zcF1Y{hyND^mzNtDcoZ-#%z-^NK9zTG&v9GBobjuRJr zyYbk9ZZpXlGC64*8KD``Vp{(_CaD~B@XbeAd0e|Qvzlzh@>?%;M>8Jr}$NWd7 z>uI6)Key6>@%7?p*=T-_Fw7{wW?GWSH&yiO@6S))gi89z`wuD-Hg6$8p+AB14HC>& zI2xAdjy?OyEA96LSmRz*o;-mkR@*TKg+;(45QjP67F?2^YP zRNjXDL6W4tpRS7F>3VRLXEe@JiEvCT^1P+pgMVYb+77-=i{yY9Pz+wBF<)y3&qeVH z=SIb%JKdxyBq?0Q9Fh&0cxky(27{}D(X0z2t@vr|CvjHO(rBqhVrywcNlTMfv@{%s zKr33Bl@!9Eswow}$_g58!m#ESr*M%44po>8ihwY@?^osrMm356u_`ibs`FJeK3*_0 z*ng9z@x&Bo(d8APyb!B`xQ8OSS9hEh&L?jG@-u)2>f2c2 zUQ=Dd5e_Kzb^P_BJC&Ulue;fdWRS9I41e)JKgo;AAPVwHg*-ELdr&c^%rEIASO}Bw zA=Fm2QH+$ULXp|+mm0O|k{a|u_0xsnt0bZ2k(Bf~lowlq3dK@G)0lnU59$tZ7?nu9 zg{*-U2*#GuSS?&I!7d2w2-pX(pNNf$X<{P~I#zl=kS3ypN{|+@GYHVkuFgUZ9)AR< z5Rl3Krfq*Qw!f&ZdA`p9Gdqch$_yc*EkqeC7k?}E+R+*$06g zQk7)46rLtSF5tU}bwe>8UbB=a;$T06B1M^mJUdg_HF_##rS(0C8KEW&`7=MA*R^Tx zGrM(ub`=mhZ~!46V5QwmvQZYPGJn)gpY{Wvb_1(Xf|7evX;Gtj1Nn>Ks?-u1!W6(# z!|ng?H&iCH_wPISfB79;;GJ80Re;d9Hv~ z5QK&FMkUv9s-3v{V;DbDmXZ&ZX&EZr@kF5MsKyT9c!lPp;Ep5t2z{M$^?xB5D-#Os z6xEGcc%RbIh+(uoRi$4Pq5_WeRB~E6VB|LcnUPVKHuwzu`Do7{19dcryUMe#Yq{3;A$IdkG@MTR)9E(b zB$oriR{K}VrGuno2q_=Q{Z&8?t67i^^K?cZ5RB&)z<(f@aTyR50?logh#3$af5rz; z?M-!r=21DeRFi_-7~J|Mp9oDcPxZv6EgcaD@|hz|tEtTBn3O54=wjwd1d;b<_=y?0 zyiv|G3kI8i6%^l>LdPQYulMQ)R8UdKrq%{+LFZVRRb75q+|NrNwjC@RF6i6&CuvSt zsCzDY$$iepulo<=8qX!Uz6!|Mf8W{OXm8}pAbP7$FBy@yR{{AwuBxXpLi-qO6ckYw z8jFth&P-A$jYy+pM(zT#ACOmZcRC%LbMdOC^LmAi&Pbn3+)d5`@_P{dKBFVJ6-RJK zXR#Uu8~8y%2l|)zY;NPzz7H)01WOg2TP6Y(o>r}B@=>F1Ri>#(->MK8e_ViN*GV!U z`Q;MPfuSp{7Oi_GvPNRL31BHx;DCA9Lp0#byR%=`ZWmPzDf8Mbqk)Cw1u5S*ZaC_3 zIv@cQyAOt{ECbW9(zJM~O;uRp3xLu_=DmPm^=h@IVPCQK3}%FmjG-02j3;L4AX9AK z61~eoxYBX}WpdBh#~zrbe+&|F;}QIcY9`+G$S@J$HKblWFq&HLZj-V7IOJk1S>&y+ z_4o~!9#H{0iUKXN03$&Pq9(P^F7%`XVr5y)+fF7DZrghsp5Jl$hf#vYeh-~RK7u#5@vphJ7(Zf+O8xbXXqv-=mxr^stHT8+)^29)(VxD2TnRiB0fkwxCEl%weB)BF4T z@O~pq(wnF2tyb$PbPI0n^_A-Kv*A6$gTU(ZM@ou=i-rjWe)(Ur8JMGp^qyA$p z|JB|O+Z!7jjrHAdcVja!kob@7-R)Pq3kUQm@-|xG#>U2mM;;{{C+dwlDHv zqp$vXJlN#OAh%j%8&f5C%IPgR=3*$!C1G+4V zAL*`5mTp!#R2}uA2@I$|NbV!=miKy0cnFo#yp#M3y7i? zf3fz~+G=ZaUaBwaZ(&7VoBKUwLx@$(=^(k$v5JRWnAhvuEm)o*{ZuXCLiwC~+dHO8 zxu6b|QY?Xu+F65aR1h2nl5k^OhWDz=tyasP?S^}@Dz>TfmELdF{<;uQxO{RI#6F`3 z2&K?ZiXo%zeGTB&WHz@-li9Adhmj7Ue?giuTEZyn?z(x@7)`;Ms4X+nV~`fBJVTho zW<9pfSbU#cmuu#MVcnHaN`2QB8zV)~*G{I5&kYY<4Rq<9kGox#Wf0=vp`qr}Q!X~( zlm=aV6F(MrLLXDb;9|@dkbkMh(9Z@$V82uq9Xc>$5>rrhWHAL*$9R6las24oxnubNACEar+x~aS0>L$%2EW!}j+BK8+3^w#xR z#MIsZFIeN905bnEm+tz|=utW9iG>LB$c}T@Zf;D=5@>rIxJ@Joy2)TX{CxN=4c&5d z7KMz-Vvx^>x7JX}tGT#o$Xljy%8)()D?uBO9WHICylYYSAXqXmg%$&)#`ir9sgxn^j+Z7Kb3fezDEUJYr7Q?`U3t1CokEY_ z@g62fDd`lxn2LHoFEYr|2MVJhx{f6MArHMgBlM5u10h1Po`2dnh?r@}4ufc&FO+&g zOvGy0G653pbBbu|f8}R>l_7rsAsy(i@jSRI76pF2Lj5L~(Hm8#n5!`VYvbj7R)PvQ z+JuGjmH_it=<4vNlSUEX=O5A~a(-U0I7HA&`VWf_gd0hP2MRq@ZZ8=hi2h;42ZB~i zcp$B{`8lS)Dh&GlBRg0z)@kgHKwUdZAW;r^Z}wPBEl~&Fe|)NE^9$*y`EjY}Ph_HR z0K{{Bq@DLP$uMVPBNpXCbXj%9YN+b^~^ zG^`b6%&4cqe`r7ND}k(l`LS8j18yy^2mJB>jvnwwTMxJ!mqWwl#|V&6JV9@+s710$ z`Z?bB+f9Diy3$*WTXyyEdq!mXfOei>6nc4;-!U|vf55SbGQR~;Fd&|M=C=c)UPqa~ z4vffruXUf+wu~cs5}+<1`8s9HGB=iHW9(lt2rp@!kFgGHA?mR}zGK3;D`gEjfK;sy z4fct3#}YP)r*4f-(h1rD`4@1^>{M*0c6m`;5kA{wbzL9?lGN*a(> z5T%Gue}ZOnrNA~R0g1RlF}Vx5&JmqL^bP=7e5tx6T%jItq=U6nDWqEw{%c1(rgoy} z%}6(xgt!e>SB)7Yis7M4V7OJ~t*EG#Dmguk!TkRJv-d9SZQDqr@L!Sj<@F&q5G&p( zxmZ29$8B!SwXNgzVI(SILX$2pN^DEtZ$Hn>e*h#XQMS`Xt* zNQl!aqHO*+t$9h3z1db$gTxDJaS z8B2@kXFO63H=2HYAl5^T8}L+9foEPQ{JYMMtm8FC@$7Kjw!=J6za}31RHO4JY{z>^ z)4{MGQPYK6v5!$HT;stJS|s#3SODBa@k|W%!I;PCtUFjuJOe)f&^;tu{a-Y7HGGuML&aJ@iyEWP zEc*90`pn9k8+~RGDkS?)!t*FUG5d@hVggOl7pXn7wnPj}8_Wo#A);$}h6@QTGf+Pm z8l#}+nwAk*JM24W(Y)yI2y@tnf8p)3%h|a9)UqtY>e*n@=p_T+8#uNxS`Gr=2omws z^SvIXLgK~gz_$jDXIN(9TRq1#+))ow;O4D0G?M{6c>{XwEd$#ygNswkv<=%F_?|H` zlYuidhW@~^4bxd-abD6S**(1P;r$ZdUYrhW58u0n<0N?BvxY`s_e46}e=o6SFBvFl z110YgUtfq`o0f~2m5SfG8%=Sxn&P*c@F;J`iA8^ao|nQ3>?GU28r{;w9KAq`$pghh&**1`oJ^-6(CPc)2CDw9Hxmav$mSy zU7S*q83cyc9-6oI(A;W-e?2q>AVdpn$K9&mc3i4`w6pfNw&Tj7a9k=ruyFM4VFv`1 zk#OER_HgHvu#_oby|n{%KKQ{CGXOK#iPGq7#L zwDe9}V|7`Xo)LIG=#TA%fnl3Hyuk7`2ae&pJ=3tf-pB|7y3iZfe;5V>({SzI2A1KN z1JiIu1Iw^R1KV({(lR^;?na4ac-Fu)JTo*+!?b#I#X@?n;o0!c?u`uJq>Fq5_1dG~ zEW>enrs0}B%W%D(ZJ2&Ju#92Qvljzn7$i_BRABodG^B@@Ar(Un3woAe`*gt<&{zjv zxINdfMs%S!wqd&if5YzuhGo-5rh66u!i4%fXpv`ywh{O}yig{qX91{8W8~09Hp7J4 zp;PvVF7(1OM)oGw=-48`wqwqk%2) zEG3_58@@jX3>R880${)wL$_xezTJawq3vc5(gv7T=eszCe~-PMW4LZIa1A>Ez}N!^ zW`=3l1Iw^2gksMOV6nJ{?LilPcU){F-$XYZ~+*u1uYm2 z93$`^Tad-a6Wlgo=9ojnbO*)==DiQg!wUv5>VA)w zoevWb2HiA#=i;dY>& z{F4aOe{@7yy(W!nHlckkT|^Ps$R*J~1HelI+pt0xCIDU}-ZTS3g*e0P8plDy>J{jl zbdhghNfYAoT)Nby;e4`|RF@Ae^c&<&Z{5ujdp2Nyx!T1=zA3Vc&a4@tSVQ5{P zx&Q@OI-zfv018ur0tiCK2w<66bfI)yNT6Hwv+C=bIl;ZqoY({4V6_L$3oVYwHlb`Q#T0r%jAx(C}d%+;O+ zX;$;XffXW{n-xkb%wF0yrWXf2~&$5D5d*umHLvhc0qOxE?^wLSh>(A|2-M z(ltg_XwgRP+j3&}OaPBftHrF74R=IDk89IKk`|T=07L{~(WRb3&=)z+V2{8ySRv3> zJ+q;nU|Yx4xj7er02mnls0aV#__`i}-tILs+A@J?9QAC&b?8#V7KlhJRV9f`f7+i+ zST-)q7`(_g0fHxhg78lnCm5WiG4vM$(USmXTOctIk){Z6JD`gk2p_r$qh`}ZrhAs* zAodX#2@;RUJX26e5?2A_O(gw1k1lc?Oa~Bu4Jqtl4@s&TQt;)7M$g67KH zYgh~{2Z=_YO9no$DV7g2+O`bSTZ{~Qw6x8IX9Ua9V&ED6XlV|Ok+~R{e?!=S;0Flq z;b62Jm@ZP>CW0Ft+y&l)WB{f!(8JT=z;s~5M#wQDLboi#b?LsaETGM34#F*_4o2b^ zb2j(R0CUnUre2)dHZI!fa4>>R*FnSw+Y#h7ZMrW8rilau{9+2=R(XpV>-&Lc1n`5; z7pIO1v)XhFJGe3M{81P5f6SXgZ(!QUX*q#01O)Dl2!Z>C=Po>B6ncOOyapXOumq9! za}8WQBAs^Lk(B^VYzzbV5NIE_p6lYn#lV490c*Q(LL1mQyXNU&U3&v!oJ{)NDjytBa7&uGMuj{>+;i~~V+7dl_bg9uJpmpqzDaR48Bcxd_Vqpid4GacgYs+n;e#GrT zK$jZ91MWil(WFbge@FLlOK=Pm|71xH;wyIv{6h$HvxgTkye0w#xGZx-7xBUd#OVN4 z0RkK7Jh3vqpmG{W5nTId5HM-Ft;cEV=*SUnOMjBL6{`T!oGPTV8vEt((* zh`+|gK+@t80y<>i7?vLf0N$Xrb@~IBmcJv1igw2VR_dT&e+n)Q>0=; zr(mQ3mo7D}=UWK~gDfH+ zRT6lJq%}%!4KJWey%PZ~0fX()MJ{aH84&s6J9LpW4)R1xBuGPt@TH{iVKejy@(z-o z&0agQ39PP7f0vqeMb;KpmW_Wkwd(`94D_|#Q0yj5ZPTrrVo5U3#lM<91K@#ptEbX( z1ENw!CS8Wjs<)Q|K(e7t0v)qii$kEih$jf>(omTLv7{}!)PyNY`w*A9bZO?QZP-BM zFN`6OhsgN=wHvCu1&uyzB-WiaKk5JgZ6GzAQP{AgedkdMs!gYK8UE6fS?{bjdv10dTjP6seQO~8mDVELXU_X9+&Bj~jQxZ05j zdx+bVe`Q$Ep@nPU%nDJ|Y|9l5_}W1cq%AJ8L=Yz07pJCYfHcOm5+YQCQRu*0a^!-- z(EzBsh!HHhNNhof&q1koGaA5g!;}GT)b;67)2=QGN0)(NIg5e)*0IfSlj9Lsw!I2q z;JpEf8HOXe)KeEI7N}NSYEgpKGnXU7HHoIMe~lp^F8|^bq=`UPIL^NntMC0^&gwsP zMyL+4Y>*m_78Y!{mSG0C`?*UW>N5o$7PPil(<3B<7r82JV%OT-D)Gz~5K)$-q#)G+ z@Fl>K0EHUbG$m}g(2NmGTy?J+1^_V|wmG}r>jswL0!`)!8ltAuMi$H=pD32)0DEP< ze|0PyxDN+;W2CXI07+lm@nyCpDn-IJN#YnT(4>Iie2*@Ik_|xJlbAgaTp1{V4+hXG zplV$bWYy@IWFsVbZAJxHM#5({{)xQEpSs=>TC=bW&#wo^^O1VDk)N~fB!lG)CwCA{?&Uts7TBJrexqC2mICn0u#tO zyCx`mM3}<9t`Lr%;Jp2SE;Yvv^9}mti%TPQMfuQjFfyEAVH4r^*tL=RbZy+X{xv%Y zEWUrmCgP277r{yEJ7ECpFsKEUr15e|P`NEc9H0Yd}a46&jDeJvkYLUKqzvP8ogo93IHH(&$gfd``Y?UFTfoi zY$V);gGx8c{Dulm3+xDjo@K)#y}mww1j9c9pe&rFZKEh~yS8g>ARL%Fe-@C6?t&V< zbRJXkjhb!`d*%pMX3z3L+H~WlTf>pz*jIw;x`KeN?^z?@c@_WxYw0}3#BZ5bCN#PS zYT4_X9=J$dxS&>EpdfH*J;uZv)#$pYwF4T>=>Zsq{tfCJBH82OPGBuvl+)a7Y+N5i z;x^!053P-C=lYf7dB(`=f0-Ug<*|>}(t3=EH>=Y|qneT7m=2mNS;6&v^n9QNOy4mA zkdL9}6GbE@sRzJHLnhjd@T7hQQKxIzA?UzR5r&@*d(E@@M#$@2yj+})U=sy}{lB1Q zkjR!@eRj$4A=zh+J=U=u$FdUe|QU6alz91R{UZI zL$v7dt;N6wNoPnnS7Emt7qqax(=(AvGizQATyhEnAF~(qf|`W@`vuEh8ctZJ4sgK% zZUE^kiBvrU_zN5Oi$<*qvSpAMEo_iZhF(wdg~NeqEr4(sB}7^bgXO?*ttQLBH_%pU zlne|XWT69+6#6J7fA)HG71YF##C^8CG!qn%qn2y{(*HkW_-rsR^IXHiK7c78NGpMQ zd~Cb;g!*WFX(qN|qj}B(o={wEx@f$HP4!V(fy5OGh=4mcFHTW(hLUmm7R2r02yg7pE}v1K??$g)wr%w%B_}G&yR&NZfBW`dDXx22KDPvzDC^ z|Lvjp7yrauvp}Eik$Tx|I0eH4?g^{}O`9%qfm`+fM06x^b74yROF2-!xx_n^s@L|U z_7JRw0uTiUe^TQQEV%`mG>|Y@E~>^%WW@u4pG>l5T;j{^kAXdduK`CnF4#soB-fVO z4rD0td1-k@kibGPK#~b`^GIN_5fbYOEfS!UJtOEU2-(xopJSeCp|y_#RvsX?_Y6CP zsS=1b;tc5xm+%7ikCBTefHf-i{edww|D>jo01Pyje-6~?P{lNFgJ1w!a@2>qK3E=% zkYld*7izX^xIs&+5`ZevHDTajR6LI~b0ZX3H~oU;1Pj`<2et)9_IE(1?Dyy@Rx)U3 z-QLKY!XD=jphaMLF+^?>M$_jI&clJPKCjQDeuur2Z0=@c?y(eJK_mnG~b3M zTD6+4f5JwZf+P0+9N^my2rWh+RhxocDoh2mW^llg9z;_hngjXE2n8^sMgkLnZW}c2 z{uKCQz?&nR3{^c){(?v>00Tr2*poTR2n;4ceFtXGJzP*`uMujY(XZ=H(b95&g_|BI z%H4s9*3quvf+zxnBOo}igjtB+^Fr9KM?Ja{e=Z6TmSAu{ZFH0-+V}xfM=&-tO;A>V z%2B{-0bmUa>%v+^6V1i~%JQcUjG+q#SOH=Q3;1Oh?KYrqp$)P`yEeRmsWLJ~?w_=R zT$P`vzEeQ@nw ze_+F0Q|83LL~Bi783e00Tq;SJt%sZUz%y)j0sFVpyaXC#v6kfu-DsYyg7vbV!+^kuK^r1+rm9gye?7Via#Vf^lghRYZv^-(K1G3r$;iPL00`ZGoD?B87srOAX-S-0Vi)pU{L~yoab@YCU(~%IW zOX7QRi`{(XqrSm*hV{3@0^bjO!OB6^2obbsHu1zllkET5AaZbX9r!@EfL#vVe-Vse ze-vGV7;SQXn)_P>j_ZzO@~514;cEO&a+<+X6fF$DV`QLKROv9{HPikMwmTV-!60e8aXj zP^IM?<`%9*y^J|BMj$Q%T6yD}e~lzWuMV6vf&+!Fvm98X#Igrg05*J}UW0>TOB;*^ zlL00`wWEtui-vM&_=#y5K8&OjytN!Svw_b~EMRy%&^G|J>Ry}tjMSGc5P)UlsAp~$YWjnb z(E(Bu%#u2w`A5zC@}hRk*Wp7=T^Ih)Lj~8!F-CSW@WCi>-~h9}9Dta0lqg9(xOaN= zn%)kSqz-A1er@F*@DUd9f2+bc6R=W<(n-Hz{e_XGg^KQgF0~R62{*I1NllVbmWhUr zBf8W!R+hBfQ%{x%BPHB@93br+X-5yra}+y3Lmax)nqrHToz0;ehXfTC+OLA_&W5#W z0fA+K?GzsBk~TAFRWKl_hUL&js=Y>Z?#m*>{`%Y?U~sGF^qg83f8_whPg+ZmR}aBH z7789MVOv=s)@_3at&s5ap+(2JYK{O+QhS>gULb|A=xCSk(xtY;_XdXVqxq|a%P%m7 zb_ncWZ`2r{?lx3~HMwo7>IqBLo^vA`RU+U2P0dv8ztlq2AJI9_e`_06dxSQsCaIZ2 zaezcBVL|!<+^?;Ce?t;ZHy{HQG7DCZ)S_Y=&-`v02grj%HZrpgUD_6iAY(Q?y3~b% zYTHLEL<=lTFppyTim%Z)g*3#qz#7eRdJgIA9YtLav)GkKOuQf@DU56fG@pWb*lWbrXu`3CHaF64OxwZ~@?$W31Is_#fAB!wXafrJg~I!-HMEU@ z6y6|aFc%=*P0;Cqy8s3{8K6yq*CUId1)k}?I5h(#o`;6lY4i2gGDrVUnS2okFO0ry zJlJIX`y3d2YngwrofMS#hnh(Zya2pT4B>`8J!k8TnhBkA z49BWZoB?H_?sG#rt&hUr_6&w)AK>{fJXYt@rLp9e=VZ~|8aJQDiYAb>mJ`sW@h(6G z+GGOeHAn*Nk^s$GbQ#vG!}lNi<`7gD_6Q`2U_OnOe{7zDCGm_cAVMpkOMRjMu%y{x z;)QnQc7xJPl70diyA06SD%d2#2Ev;GOiy$!V0$ghiCwb9MK$d5$fV3}R1|a$YB@5* ziP6!*Uc%Hsj0U1Flwsfe7*98KR3GH|Pau!r6p#5|66yDnNES+P9klpC12h**E#U{a z1W;z#f6@few4@OxtV+;r*#9CM{>MHDL;}OI{z?l>nB1uGb;#R=Y06{YBWWH9X3S(R zU|Zh`PwQU?Pr`fu0&oH}UE=29^e0f!3VA4C`|ac*2-u*1aLntmZ+nK90ILg1u|^Jq z8yyKg;rQmr7>>Yy3J70pS2=!+yOfm#IeBui&$$q(=3l(VtTP!?KOF85Uy64wpj$ftjB7|B5;UXe>)5f z%TV6Sk*$Xytbum>c2i_Ca^T=|$nwzmLDymy)y^_Q$`fhRP0yB%w_;wRM@ts-(!drK zEa5Tu&z1gSC*ZU^FO2CO?GgjR|MUcX`4-?JQnVTTELWWKuGa1E?@ikPqsr&}vgxTZ zhY=LH08i4u;GhG@;L&%;^4Peqe{TVs&Gr5Ljxm^%%MiS?HIY z^CG(zLt@znb@*Pzb8M@089i>h5^ykobu;*$xuz~0RZKxec~nH@c)DhxeoS6S3!ZB3 zXz2Mm%PO8~R^V8H&ax>_HPbW$PiI*Ifqw$mwAF28PO%Rf_ub$!HJS+IO#b_&qg2c) zTo$J+N~=@yG>`KHV>wp!fAg0-F2(&?A4f;!F;7`Ujh)>v05SzvY-0V+lL!N?LUc~W zC9P$+U6Ff-eVuIw`L(;UDp7vz&cgco8hS{vKA{<7vkn+P9R5$g36z}8H6_yMKr^?> z(_5iyx55hRYZe*kk@_r)!PjkdruB={KI}cscf)pw+pcQXI)k_$e|I7BunZPF?we;{ zdlYv#|M(%)EX!fN=3?p_QEDTjScGShp(fT)wRXpe-HH+`TSB2?Ww_LLd3ZMNhw1s3 zMU+PrG&NgvkVCWX$V~$3A_9vDTb17+l2hCjnJG8UD1hg+gkNqy zTQPjqT4&i=Ckcx2f7o_4`Yb`LSAwp>BcyWHtWr}`O=t4W zE)1A0*rg;ly0K%YJOA?r70TeS8S4X59AJ!w{UXy z=_1P?B;%N2f0*pMS(Zd$s>OO85xdwfw|pkT%o6BZp$y|0lcB#m8Z_M%wJa-kH}!%1 zsQ&=V?dZ&dZ9rAuRDE@m>S=QIDct9^G2U(x*o_sZV~3s2#!g3T&)6lB31bRP*kL}E zeUP+$i3@doqj;=!rNNbzzIplNx;m>o`Nk@*?&tHWfBcw1cbe6pa2GoM%>@0f*0Jk>@)06glQZ8CA2C%nwF ztQ=noe|7`diY@L+Xm^&K#` zEF&2gpl(*sJr>U@A^gGu*c6`5qLj_AV_?Gje=vPU65UM_U zeSVgq1o6BRBkqVGyvFd;^NzKYy{@tGCVf;+wlY5@oLomleUZnfG9K}`>?r+79m2EN zW)QQ_+q+EBM5~7i`p8_~%90k;&ooOd7b;j>pYVz&O>?gqQ&ccYJF9%RyaY4PZ{bu6Fkj4 zkD`l6>k@3nQK3cbG7rCu#m?9M26zTtt@7c`*{j3<9QNu^uvZP7evy&lc=ky<>c3BW zy}1Zl*1L=3{)_M&gzF~{<0zRGy(|^!f4xh{-0Q_N`h~91U6m(v(;}59sYS$5Qa1$y z@7C|rel5W7WxsU9vW(VJWPO*XLk;?)v+T{caE>ok&T-G&<{NiymDk00lM$kC9v<5C zeqVU#_*@2e-w`|hCWU0L*d>8zTrvru@ixdqZEuLnt!ux&CuoP538I#Y5pxDaf7i3~ zasN&p_0F@ZS5)HWOPC5Ahq)n)TaVf@>9Z}`sHWKatR`{BDcdBh#(koNFc;o+_r@gT zp=_^@|C;Uf);Dag7cCr0dttf1f7QNPO02#Ji$k$T98dQ4I@7gCA2(YG&{s<3kN&&2 z|GvHb-M`V^{$qP@zeRidBe|u&f0Z}yT6_E3n{Tv_|8q9l$EqCjx2^E7Jo|Ag>TAg( z*m6=Hfv7U4P_dsqUDL_j<&JSU)V1rvq}GT*%PzE%p;3oE(MqFb*I~@F{6VPND#&dT z08v{20G^A!mQh-4D*siZrfdLTK%l=C>74i9JiGJe_2cI+4}X1dzpr1$XqaWEp9dFdWKRtS;-Hx*~#0QVOH2 zDgj+lSTm{&&~7ivvTCku(fO1e?3R)+WN&&)}z4+lBlRR^qtOhC0J< z$AxCN}>rZ+?u5wEGl42utYs*BePB9+DykvJBnC&tm3jt3$dT6 zzO^nNMJd(Yi;G^E~?|(&KqiI#bB0*m2^vjSRd8`0Z zc3AH{DUbOOTI1pz5VJXK7HmDJ!{Z4g*VfZGz{7QmSaTbC+7`mAKEt2iswhA2J&elf zf+P>xt#~%>9p2y5rQC|d3mPQfif46luXl0+%e)b1^?HV3Y=6tW#EUK=nar@>DBxLE zK7>;TxN_BU1Ub9$-MT{t=I)Y#HBbq*p(3r0dnAq71(KQib{jCF7it-=s_8T;3bijE zwxHC=2wOn;C!y2X9zmpl0{x#U24qS}JT3o;feNk^R*q0u>B5q_tFz3<#{d|mBHHE_ zkrjONT-S84w|^*A)-Y9ALl9>Ers+lpmjeRLrIw9^-t9vY730fzHjdVGj)ctEGakz$ z5Uk)aofcpf&nzv=w9MC;sRJ5~=US%kvfF$~h7|`$X70*#pIwqsdm#=!Oxc`kQ=a{# zZS)@Zepaw)4Ove^{-e&9=$B%TNeH9WTS;9zVJ$#zM}I?RF=m6kw!~YMskS7L^BS_4LWvKGVvE-4#lC_yzx=b#N2GdZJ`yETG zKQ1NfEX;5EI!gu9`&+4NeSwzfTVQ#WeY4+MRQ>T*Et?CbBTH*B^v9{fa2E|DE*Oa; zo7nC{)5(d&E)IZ zHn@dQdc4bu>rE{XpD6IY^tSGmQ9^$Io8duR@TxUF;ql!T> zpUtx`>~nN342ReP%)2{P^tsh(P@2)HL)mRL424#C@`sn%QfB?(rFSdA^tOp}k^bduYmwKxP?2^k2n$L4 zh_hdRjH2+STEQZ}YNIV;*jb?yIxE5}w1RX%0ZxOWIS$;siZ3Fx!YQ*dOjxLFyF1t2 zH-BsVZ0mZB-)OhOPoS`(e*>MLeFGy#_Ngk$crL7;22nceU){d#x8WUl-5h?1rdc{e z>y`$Eloy+*A&tI(8PK!ni&PbM>KAXK$IRVbW}kVm>rEW(e3S1iZDYZc+2-|#0WB?W zknKJ__1e~nH~8==EuC#s!Y+vBBiX;wIDZY#IxOzCW_eN8`(lKfN+hgN*IgCFB~7w= z`#}5WDIA|0$1Kmj6fdIuMffoq=jzjQakBU*KW4BR$LYWXJ?V-h8tAU z1U}-;j&s{&{r$5j=gmQ~98DxekuQ~oC7u`V>3QGCIA zA}@WT@Rf8JwdiE5yEm6D9_}%_O zyR$GaqQkV*BI9F({v-j3tyX=r&wtDzaB5pQqMR}eDMt=GT2ZxlGyz1d9GLpwQbr(5 z*K7`B@*+#(={ZcO@=KO~9%N~94)($zw?l?5uWfwLCY_S${F-spgH` z(NJf_jHgDb6?2^xi;lCZz2Zy*&B|W!L5o`J>#WJNw-@d2_cJLimtuHjWqfD|g=@v| z0<8TbDzNu5`uO1M*)fR7%hjq*z8{v6Oe{V^<8Ydt@+;)bLdZPN@=0^6_46p4mPSM) z(AUS_&>Y%IS3fH7h>TmesDD&Aj()22ajE3mR7XyZj>ngZ7`ixDvD2Ojx+!CtWNEa& zkB6e8{9^<&m!JhD6c044g29Jl6}VqE&NW9huGV+$L|A_cYQCnJ6Il$vG3S@HbU*EE z(Eh#{$SIbg*TnN$XNsD*cp&?xrJ!d4Nd;=muo|8!535!2g>|%mcciUW#o~aV)gJJ& zMvD0!=UbDZAkFPKpQts9CXVZYSQihBFiAFaIUqjY(sq;hS12;(abA=?$>aBmMOGy< zP#K14538$<26~{ro_|$SMavv16A8hV;?dg6wZ6u#7O!~m0DZX>pLy|0StVav8*W{o zGA}jMSgqIi^=n>yr4pa=;KSt#Xi5Z^H#ca{3zURDnN?+XJH5#BC$9+~j;SWWf z4RT?{y)A^pibGyJsnHHA?(^avm~cJ+lFH-%ta!$YL&8Y14S!8fUkJ_PUPN}g(LF8F z_jqwfm+M)2V0jMsOenYkRmluPp_44`QynGiE4swK4p=}*kSK8*v!(m{scLKn7Wksw zsm^)vjDY=;7cZ0!d_ui+41zP*D^5;8<&FtOd=c>>ee{qQpOlY&X^n40m^a!3w=?A) zFX@}Ry!b`==6?-+(^z;&tB-?pFgVabw0Tzp+YZoUm9;iAmGg68Qn8PD@rH)}mRL^B z{!yF(O{Y|P(QG!YPO_92kF~P#`m(2`-w$=vTEEmA;iFN z6C3u37Z*y^?`~RkFa3U4oBlxm&0{L?M_#;B3Vf>~?SIEwyU6{!{ZR6j9|{_QFo_tnl-Dv?}4 zL4O50ouT$lc~wyxl8(Kr-l3H8q|FN%OhshECaoP3NkI$Maj9RfmG{x@eqX#v^-F26 z)bCSUX1tnHTNeDgqxbLsam)DI?TMxzy+6KOua3X_$f`5`-9O&Tfi!MU?ll|K`{P^R zvFbzD4qTmX@4(eZUVUhG;A+XM)6E^YI)CRx`D^`u^lw*!J*bwtkw<4qIE}Pw!TRst z-`ejtN#C^#S=DrnZv1VcP5Arw?=^kZn`b$6fD(@N?>@5rEz|hhq_5xZ-|8z{ef32d zKruyEt7-}}b$?&0avJpk|@ef5f04}X-e zKC76#dPN3Ja>P%xRG*|mwNIaa<<(~z$Jf02s=+cKqa-4ts;9hqP4Az>dm0+nCni*8 zy2GpIN*kVRVZrLoq`E_A_s5s(Eo@lbF~ta`D{ZMG+f(#DrNFgE&YyHoF_O7l|A zdG)OJ-X$#ns~3`Ni1Z2MZ;j6K3maE7e{6iGM^yb+JW6 zRQFgbRS*%?{dO`C5!I)58W0iH-F6xf5!EePK96{%5QWt{xqN7au=Y~AgdrFMSy4S= zr{NjgYSq)#s`yD~WZEd+65~|;$SZ|Htllb9LkM0ZyU-X$u2%iDI{gsk;-SEOOFVoa z=N0fY>7SfnpH5Etdz?pO!GE}j4eK{vDO6_FqB5iHN%@;r>XY=S8 zk_xKiXI?3^Wu?%T)z759j`S-?s10246R#A4t}+#BNGVRCpQ<6R6iTkLy1!6}r^@D) zLZ($t3uV`zu$-sZ!bYwF(-iVDWg$@>&U0Kw&1&&@rI2-%`)95ecYk}e{K#6Va<%-_ zPR7+TY^ULBvD<05T0B}U0k4SktVY}#4wXLoyAcr3Kq}u`{3N@TwleL(O3DR9zOP0D zQ}UR(%H=3K*zMai0+@8LQ7@AJRiNe4OrvuUxl#fS-ZbKs-*gP+XIaPReV}dzkjAT-`=N5Tl9)6b2^o_ zpkN+c+|_ah*27x8&!?*ud9c)1t7#==hS-WZpC(H2GkNeuSc37r^dJQXrRXeJ4r&O4 zn$?1kgWI>m?=yid3SJ(C$E@P{B-hfT;+REnDR6M5W7~SCuYfe>kV9wjWLjw{D_EtE zr*m;vFCJ>{f`3nEN^{RTC!3UY;uMPx=vWX46q{o~Sl9B&|qx!az;;?oDz{(sMHF*LpY%BRFEOwo_c$OrA& z^eG<=hrT%)S+3(d!_mlO)8`z|CJa|c=3sREe)c#0)^`dd@3b&=n+)08(@HK~cu${> zVLEFKIg&Qy$R3=tm_8>?3OTIk?*nsxKl&e&^Wpw}^gV6r($}x_P7Qe5>Sg#gj=n(hZ%VI{EG#{zhSsmmtAE3^4C?fsTj{1(zxbi`!nW!cKQ%Aj z#A;FI#tU(VrhY$czgOzA+HaJ~Y|x7}GtB8&qW3lBpyS@&)ILI_a=f0}M{RJ_i?NhQXf>Uj7k1Dr_t`&lQC!+;Q=%0n)VG$nm)hdM7A8`GN*B{Qy=!sGQ zCOoeT03zXuHf5C#6$&HnX=A*BBb3BEA+jt9w}7iaGgIvTHcrMJDEc9-Lt#~dYJaOP zbG1rBqFIuHCmB^;Df&Q=y0)}{$&@D~G)U%y=?any^sTiICrJVG9%}(${A^StwtBQ0>UT_F|I6 z;A$e7)nA$WmVcaTr7nd+$&x3EcsV(5#`Q=!m>cOkAhWCIUwCp( zV|4NjWAva)6VOY(G-HH=$5M5ya#~caQQ;gGa=BXVB{gM~>-uUXG+TM2g`@Vq;)x=2 zO+I(R8kBzHh%!hEw?^u?P?a8QyQp=F!$0M8Z?c2vZ)0>me zSnVNC?kUyYuj$+)5^yKacygbB&>^1fB%G6%yfF_@<_>9J3YL80$;(Lx)hv5=bUaQD zwdAE1@n-U}j?F50(J)9@#K+`|Hn2{TPl^{20Y2f$z$MZYmG_rmM1?dC4c;;u0!yTlAN;S zp~(9yPkvMK{=AjAql6KqoV$*6;nPyCkp6q<9~XY**2lAo7dMEgALB+chJ zuVz|e>TDjvUG-FF^M4T2ES=3WymNFmFYwNV)xx8D2U=q8@6Rg@1XYQNKME_LnYym; z@p-yhRZr`D)l+?sC&6l!SeTYrwbKm9o%pL&;xwf?Py$c}ZjXdR_FDe@QIas~o*w4R#c$v@DV-^Buq$n$FbyYDt1BX^yZV~X5^SmZz`f)mo zzV^}n#lU+W(J$D)rDs)%&u3Ms3wwn5jL%6)JYS%K-Dnst>fafkD@4m&G5g$ZZDceg ztFC%JnV*4WAb*He#S@?@+SKN!e6G+q^N%gL!(@I6rQ%f7$MQ}sy4`}5Q5%R#W~~NM zbxS@c`Oo~EfA{{&-&CQ;{L9t7E3zt|Mr?jg_5_jMjE<3nMR_PdUf;_;p78k>s`LSm zK2D;K%^Z=ldH#yeA57*C=;Z(NxfH=QjZJH#OKTRX%c^NXv+AoEAN#31u`JH#N$ zY}wf4+kdQ}z_6vnurF)OcnZV-B|axd74th|Wm4tZ?K;D!`l}_fU?TaU`0f|+dsqCv z5x*{Y%@&&od3M%;kY^t{DB0O*2bP|F+{DteWe1j? zop)gA*_SSocXqN1ch4Sl;_lh2ow$4Ud4DJFo_+1c-Luy_aQE!#4%|I^z5{p9?p%$# zXHRzF?%BOvBJ9~=ON2eUuX@E3%swl4xj#!;1wT2P!cUCyAn=FC;|ZJ-pby5#zOh;> zS^Kld4z@%<*d)S9qNu%F6g0a9;dK7SS) zd9B_AD1447tiW0z?+5xMT&*AwW-RKhR;w9eqo3OKSCix&u#iu+i~*^X+=ZtlJyENm zbF;&v`El)_X%dYu*9RG&1NS*+g}z>gtCbcaZk>wYvRG0TovHkLtbJImBG#_s!~VVo%IlbekI3m<%UD;1EL+bGk7nU9 zho6FePUza#>$dp3DLB)7=hugfjh zX|uc1$KJ-7&b)DL2~l$=rGM&#B!@#==o=iAA=5C|NV$mAK6QZ9jIqmEbpIuOW@6ZJO=>75W?bZ7uZGSS>29x)*+uCIO z-grN|txxoocGUl0$GQgZCVTHK{pcU>-yg5uzc=*1P4xGc{{DESO*nqBdVlo(SZ{7u zw{);{p8d$bd;ea0|6ZTK(_21!)ZrxMsFpiA;2{kn7>4=1Y!=-qwV__?Jo>X3jkuk&yB4<8{n}2*ig1vQLAE&ET1Qv>&di3B*-*0VAi27(Z$GvAW`FaUVwgB{Iz;3B{&;3f zoyN@LGZm|;s$G)VQe%J6$JopXm>MTfwApXk4E7&E&d&lqBSr6Q#P?MA_{|x{*=T=% zFOq_W{<|R6%tUb9wbT1k(;?w5L1q0~tf;2c z4r^YqMQj*69x*Tj7RGg4@qE81>X8>SuVGOezrvSmR(}Ii94kghnRVxqeV#)%je+H^Y47PT4}LVhbjAG(~L?i(Aril61&;UXddNJI+fl)F>=BpEYkl~ z_C7=rC_dvd4wJZuX1zhLsLrBX(_1+xh_+&%h$qq))2?Innq zr$=kHn1AyfsxPqM?mU>!7F}_v1+%3+4a>s+aFXjlnMWRLMe_QoYusBr=ALW4ONTm)NyT_Q%0u+nv z@8{o3_oD}T1eEMie*5-uy%jc-W|FEW@E0GY6o0H`HPL@*&Ga9pU#`ea`eC zlxx4>8Ch3igEQ%*goU?F9r*+>s9emoN?)zo69=q0Vjdp>75z!8^n;pXnnIbk&Eo^{ zdNI?c`u@Hc&?zhy;gn!4*(UIWI*G=yegw@q#?bW9SW^Pki}N}$Wf+TJo-+JaIqQ+u zXMcNg%ENLM*(^K8CB<{Nz$*z(UNV*Sn5o99q@>)Dzj?3h-TeiJ$U)@ z`O8;*@a|j8G+m3xM@qr!+zN%ZSu$nqF8I~!JFnk#bfGB2vfA;@;j33~?mj(y{eSxK z*`w_*m6>@85!}$8h)e4-X$axlh2~341^qq`pyLWX!=W zkMc}@?6=Flc95`m@$fs!$Kl*AT?`Z!zB#_vl>PDnmj3+Z)2(8gDWWvv`OBw=KjP>& zFsw65DSMyB`Q*;)*AJe)czp#pmVXVjVXe330JxFEr+es3D>9U)+vd7m)x$f7Pu{$I zApCoZ#8+?b-Fxur)irZ%56aqbUm2~}i*o~x(t^1Q(Wb9}5L$e0$>|nfRVDC}CSdej zINf3?Z_e4RR;7$BFEZUtDj=^Ke7aiY82+-!@)SDDGF}Vv!u|aaBVoqHA%BrRIO{PU zW`q$mUq+H9x`^1c`Lf#IuP{DlmQv^0j3fPb)Zc7(pY_|VY$afu`mEn>L7(-v>+iF^ ztgU~nvjv9{*sN`wvUY9bm~GTH&X_D`JYTb!&dzGA{4$#B+QNwIwp3A}vkyDoQ-GM& zYVk^Er#tezrrEh#Ek5h)9j^hSP8LS(GU8=yQ zNjKMPc63af(if!;a21p5+TuZj#oFLt5H{7O9xtAwW#pA%XNYav=$w8TY3+`|v8uOqlgO1XP<80ha1v>Y zr{Mc%3|3z_Wbq9{RdAT zynb-<%kwuU?+%|lIl24bwCR*cw>R0bD+5Y|>^ipXM)^jGG z+2;1SzyG{>3vkZZbFuN^9KaYiM$y%^`(@7x;c?I;}0^!q`uqUvo6;#PvCR0 zbxrEK@o8Pa>2?A2#&)>|+g>Pv_P2?=8Go$5|G51Spqk)iv^*)n9Y+ zX45)NTaTzhd)FhnL7IXK$GttE_L@|=o2T{Ooy(0nW|D>6*pr)bn$$LRjo@e!_V>5X z=Be)|t*7x29NeSs)X378Q4y7r�SxxCn0{b2Dy%k)V`YbVslp+*Ya9^AmPZVfuy zBtSOD^nduu`M){&_pY7&+H`-v$-p;zxQs)@s#!CIZ&q*uep2xEE4vI*ANau zGJma>LLc65Pk)8mxEfc0c3)Hc9L3{OpFFRJqPySEu4(0U3y}KuX|rz)SJLY!mc*@BuIr{_`6M0Z(6Plw zWyt`8)!EO7H=Cqzs0%1QG<{pZflt(^Mt^w`7bVa=;#SiSWFXfv%s)mz7ci6dGAoM)~8{PoJ>R$jJRan9ha9 zX_b`mSrQ%O=rwz_s#wgwBl2sNgNRH7mdx~tCj6|U)uT2Ak?FJW8Q|)Ef1K*$?|-n$ z582n|lf|K?qW@fH37hKU*<^7~o9pB0I^W;_L;-Ty(I+M|9_#Fvj*W-lxBFoELvn6* z@DSxG?C#cVNw?Xr50-nqDcJ^Wcv~0e zYA!`A(t1{ECI3y+_N!j9x=fWv;0)kF<3Wr z`YpfAf#rqd@tsR7{6Py-?~@OTxH?cI{Wqiva!8`nEmG) z2{c9Mm<_&&LV#dmErP41EPH$SLTYcpjzr=0;j2cZ(7b%Detp`J;eUaw^MmpdXy&>N zO`Xc#{KL(qXPQiQukLgFrad91UaZX_>6dm*sJ zolvl)F~liT2PXxqolAU`ij6<7gBy*1VHs%-AEOYelp*UQBGNK0WRR#i4GYwk)>Kzt zl1zQxgj?jCXOmbGaDRMnFCS~_qt>=a0TaLfKd-IcGF_MPpLwQ_`*}EvGb&ywC5K8{ z`HCnJq0PZ5H3YF1FU9X_bp(N>Wz&IVTG!@u?C3H3MV%s1W4iJ*I?Xz?j+>IOnr2$F zqwQ2Evb?UyUafF0CQ&qzlX!c#lyBswIY#e<1+Mr)pA_0cAAc9)n}5G%M+J)_Rxg`H zV{1r?{}XoElFlgt>6X~5kwb4T;?vC+uQueyjCKo}i{hc4qx6Wv(DAS0Nhq~{Wa@^o zxg)eu^-Z>f%}wNYY!S+iaNQ0jq{?GBRTt;w`8bMLmFCgMxG1BXaviev^F8)aG?Rje z{Zv0cjmmKRbASE#I7)!}9{+Hal|Y9jfiN6UgXt_@D;Vc1VH~iO6|vips-FrIM|A&@ zN9imgn~XS3qx@wwKWL6K!74aBJ%ht|@iKahC*VrYpEfSJA63|i~xE5#zt(x}cTa3dP~L6GP0U~#IIEW=jo=$!|O{s3AP;_#*e}n;g0IAFo~ zcE4#O^9k-4Pr~!8DoGH`cO)r^{I?L>&p`QtREKeEWZXD#EOGuH=9B^RlA%`1rKDO^QqAyTz}Y% zPmK-Y<_6|{;A6SbiInYN@ZbOmc&0gfpWzzsQnE!xh-ttR)9j~bn4mG@#{aL+ zLYmm1nNS!FR8Xj_#uYv410egXb!<+%tPO7q2AwULu;&TKu0?Ot>K4vZ}cI$p2z%e_=ezhPwtuI%5!^P6ffmIReRaokTmbu z!Ayi^7|2>+N<9}$)hIP9YVxl&c7tA?Y-0SOuR-HA9FQv#uh6vPlw3vhs)<)fBLc~i(D(3&;R5c?Y(?Z=cXWDKD${p^D~j( zQ?0@fRlGibG{qBO+O$bQ(5JOAcWu6%Pq2luYVh4(Kh>vzC{Nu2(Dc=hWHd?cRy$88 zZVgX|-D@*77jM9e>d^u`-X7~~wr8?E6DuHu^I}Ie+qU{;6ht+S#n9JB#jW7Br-3R-6`5 zUj9=J`=xGJhfH_z3y1(Ha`yEZlujL9(Xg&=QAe7N3BLsYRL|}->~MTJFb{6lOc5Ig4(uxoiyCX~`yuMaYq<<;Du0_5rr=8#z^`l?V@lX8 zrrH)(TWFlqb0F;gG-^A zc__%skKi~CNI?Z{hGG&yrbS3DO6*Fr@~k}*koCP`V;UPb<*=_7fiMuu6+arz16gTA zPykMJt6qKyyWE%nSQQI)mYs>G?2N%?Lr-wW0FLwscYlnKBPGy169|dY!~+uxiW0>G zqfwC=vAkx79*Y=(@|o33sP!g0W6c(-zJX`fY-8%Hr%g?VO8eCm*22c>dy&Licty=1 zl9-A#+66$$nu%y$L{Or;A4T9_Hll}86+M(Bo5+CSD#b*G-JrFhs`0Q zT|)i>q<{OlR)DywgG2=dK!Gyly!L2`aZmOUg7Tq;9YqLy`}F1BaLttb z>OHY;k0A(=6AUe#Ep9=C5YrltbhfzQsWviw7f9AeJk?BdwZ&tbww&Kf*{;bBo8X&;olq2Dd;sOm7;fDiTj}X|Eg!mRbJTiv8$FIs^sGk8`f(OiOf}L>(46KYmAmk7}UbiD}`I} z7von39a^)+uSn{YY8^lPAw%09){JYyTtki{;?wI!4!&pxP*M5QfOJ4PY(qJlWH*Cy z%Q4eW4OQBy*nQl~p;{n7ACCx7WU zV}K3HC_jx;5N7YSWmv-gS>NBM^VrfJx&`!NQnY{`D?krxpocm{C2RmUyawpE8lan- zK)2K>`y~7jCC!?^$Ez2_;zE=Ss@gnD#@9C>g$Cf^;HDM!pR#aj#8=!H)BR-&#kpq8 z9!dH{0?ytXIZuTdfeENM(d8VvTz|H}6m!7}DJvnAkhvi^T0M^^@wn|lpy_#D_Z(_b z+wES{^LNc;@izM${Kw6c(KXQeadVyo1hd7@+d7B%^V6`5@;FT19Kw$Kkh-?`>FTVn z&|OoXErwU;yC>}h*}}S6&UbOSASA;U&NYo76F|0bug>=pObQ?6S#{QDi+|D8c@IGm zb{8Dupj*a}KMl`>4f?{@FV~Qm@mEnP62VzjGc;$VVgs-jtya=?o$8vl%L!h~xn^Xf z*(?I@v=FQf3@n~yv#5_0a&3Q5r)zsdqj zFeeaJcnniOTBAW;XPsyHZuf)iEaqsg*njyhtl;1MgL1vsG~;jjdmXN7M42<`oif_vx8(%vKMSAr(K~L* zg$D`qyXgB`(NmJg*M9%D3Z5yfB(Nh>JZ`R5Xg>wNXaXcF=-;NG-%8|O&}7%A@*6uC zY+zf>-MlO(|GR(dGJjh4|M!>*P!?*PtAF%=*!%K6H;pFY|MyccJl+Y!EeyKFJVa}c z?Zk<%_(+~aqqULLlJFoPfab8oe)jiQ)!on_G>7eYpS+tKBWU{W>guZMIz%i1MZK#r zx#4!JxUY&Kze#67flKX&!h2*cB##oJvRT#cSbsW?u@yT}oabcPH+|Bu z#0dkTzd*kSF4@qiP2So=m=7D)@5$>ITxSjR%5s-B@pijwsWVhZ>fOi_jlv*omBA8g zC~|W*z9>B@mWoB2+pra23s-Qt%!?-w!#}=$@!Vk3?#(Yt-lqX$@?lR=d@!Qp-AdqI zGRR1i?~%E)5r3}8)H@qcSj-eJQM}-cIoXQoA8RkBv(i^r5y=Wa#lrx?59N7Q>jb=^ zDq%nsxbR#;h%Da^&%I!w@M}ip4!>~BR1$>gi<%mO@V2!8zSpn{n-Vk`O7n2-VeBou zK$uU&8JjK7VG|P{9>y@o#C6^S{N`hDm6P{(HfeV9UVlMuN13cs))%OZ^#jawY|Iyd z175gmJ9+>9uI3HjE85gexbY5@V)=R2m}k|E_qJ-NrM2Q}pzdAgo0C9!GFMbcRoUvK zAVi!gZlbt>LRV3G$t#{vC0WN*Nke7j#;4e1g7QMh{N8{%fS%Iy_uuHm%?QV2yK5&< zTt=dqBY&>tcXH7ScbfW_${n5~Q@};IJ56bvsAS~@yG7ho@hQy7oz2P%Dh1q&+5)SP z<##Wt`P1o=CiXX_GMHM17h6&9Y+|~g7n%AEp)1$(YZ_7z>J|K~l68DVp0}@_s${+P zW>;i+`{bcY(%4(o<$?4SohclL5|#|EA)@G>jMC>_1Uv1K24I^BJM?|68QRN=>}Jo1CU8z->$-#)@Lqt?al@= zW-5uo!~+fZx{-@-3O~0#(mmVVwO&eB$^MaHnX6z#RIm@RUp8y?n@^hV*5WlLO7Z-wH z7JCp~YPyz!J4{vIiNT@1_Y(U(oDszd9mdN0bFk{w--G-7nTM_bRHWbzQZ)EIJbye$ zjWAu(_}okAZmraVZ_0bfYrlupe4ppOadSRRHy*l?f?8ry)Zk@KO58eCDIj??!!W4s zd`As>M&nBjCLYPbBQZZY4TL#2j7p~LvJ{0F>?w3ymSY&(9@8(~>rp)%hHxJo2+f30 zvXMqR4)!9^Z258`LkFD%auWA1Cx5+D5kx2DBFdd)7TkR|o!e{ZpefA<&98|l$-9Vt zD~?L02HR~ck@$?FKZwpDZuHI?7i-1#pa{Jp$Oq1ZOWKOXjIj6$(IY2%C-E__>tis> zx`q+~d|F)7MW=t=SPD217tXztJ13iyvo-RWeDqR(~Ni4OL#}+Sm$-FKN)kERgfXGcjDm_7$yu*lvJ&O zePc$cDc2rx)1?!zXN*u0vwvrHF9((&Tx%hqXcvNTm>cF$=etex#whwf)TGi(h5<-I zSbNHq6^}Utm#o-^{MCkNVLP?57&oY4!3@G2IScpyX$^td*h$ZrJAgz9r)UH*doS0I z&TdhfF?FMK9n;sTJ3W09yHk32xaR`{+~|$iyU*Z2wPhpzR9f(vT!!3`*VzsO!uD=h4wK(D3wg^)oVe znA&paglLO=;OBwm#GFqtK5+C#3sFT?x2K41iOb|u7>UL)k7mUs^9(QqhI4V^(QJIQ z)I3trn&!IGB|s4^1AlMsviotpY{}%fgnyjpOYY6JM#KN7V`7bS-iO0OEjc`#8!!i2 zqLVOBpXVSL!ihC6zUiCFP@y5=;6scV{G_0+e{>&oA-Y|&t&`{}BVO+7Bsz8it<&js zO-{%>aW=vlP`#t_RZ1=MA&QCi=l8RfWbQept{n6&Q#kdy_=R zJYCoF4@?yev44ykIp|C{%jpm0C4)k#cJ zVWba$x83?u6h>B`lac^Qi!%p0##V^rQ-M3vC;ZwKm6jHSZ)rfWfx_Og=v2BKsqTG2^C|#GDC>sV0g>ey&Tpo2b__##@*yj;HDE9} zS1*I@uwI-1B`9S9{4)apz1rMf02(u?%HIqK)@r8XmzkJj$sI zX@3sSVGhrA`&`W7c|M1^x$cXXZ=Sq({u)FbS@cjsQw8#bxPVB8d_Z{$_;^mzSThOD z17ztU(b6T7^ReI}9Dbg8#3cY{K$yQ_aT}(w&WQ3Tly`y54e=z%>XMA0w&{{8xRn&RlQ5JCox1CULV8R=5EF#_CcuST z3Q>chyw{IB2lVnloqRMO6DoXZz)(=KH03w$Oy?unZu7^HKQ0g8O>wO-3u%HkH85*# zO&5Q)x$A*LGdG2lFjLN#-gL?Ck#abv#ybY+dby)M>uBDM%yoPcI%~XXOV|aQq25h0 zoorZ#Y+9@udw2<*aWmcC)O|>aD3@iNBdeL;&E_Vggv1jJe$1Us`;J3gqH>xeUSrmt?8< z9a9B=#xY7DL}jJ^;|v}hXaP9Ul$^U9fiII(m|yCW(Ck25u^(6&s*B_ch9~83`80o* z07RNsjEq|VN-?Qmys-jT9XnD)-cGq{S%MMp85Nb+e@ko1ftcZ*7&1DUXWAQ83? z{*C%rpgdMV9UIr@z!PkeWJx|2*Vrv5td&gdHugE)0J z6-;?%CUPaQmmoA^JQ|5nkP(xvikbE&@9L)`W^PLNrP%I`$c0qeEQcd4( zRlFhLqBXb`a-s*?2Ds=5qba4aH%;M5b{b@om`>L*j0j%DJu+mAz?WDsr8Xy+U0=<} zPUFy!j%X4weFaY<^2ZOT!zMfX;oFWDoBrKuol3e{^zg8JEtC%o-6<};ge!l}loz2e zOL!^Z>;-E;mmK=wROVeIDLbcd=2>#_4j*$Ek#m$2AzKbJa<+0}skUlG0!5VSs#YUq zsz4*GcUA|dkeBTP!!Yt)0SueGA;h;L4RUZu79a5y(*d595!?IU z!nGhtPu}z9^pp3T*83&_!er*nF-UTX)EizT7h70ygP8*49KOBRrHOxK&hI!##sUV} zN(T%*6g(t?L`(u{dtsbbdG|>#U@}|TW-NPkKUPz)V0q)Qg4G>bO)0lns@UMCx|9R~ zvGelfHcM3(Me`&g*MpHSaG&x0MuO_zu5NY`l#h_q`3{x`K9w#-ScMuDY#Vbe9AsXC zN>v3yJ}9=1I0c051!#X27D!QG^5V8s-U}%El~717{p|?E=V@MM|MV1x_Q@Qo^e^84^Ixb*djhg{(|L zYY^T-xn|LxTr&orlwqcFDI#xwyi6B3ASVoKRaIi+U8Pc6j!&rt#M7Pcs=09A08Soy zs1}U=7mMzJH&1D6m1u)2`dMlu|BiElA%aA!IKkY3{!!qh9Oa`(a`(=r6#taTR)Hgd zdtp{r-GzVYfpt`P=;u`zqXMC7T@!f@0vrHJBbh~r)I_k;M380gWbD9M^Ck>r) zUr!pd+(;Y0^OBdyv85ILoC62MQmFN-Q74)k{H1@wsR5O+5f>bkc^puMwlK+w58x8< zT7){^6^CR7#|BdsV{M4HawB}a1!pO;shPe*&ZK+#l$Y7|48R?EpP<}Q^w-xYm>Nf9I$H~XepuBFXZw`OJ}{+my0e!^bIDoIB% zS5kiAMMKFfLVD3iYcB< zT!TUu^qt4`tJ2{k_I1q2-25AATH-SAbnSnU$b*+QTnjIX!!vJ&I^BWy$C@hdq40af zo6#Wk=9h2*1VkPbQKdy@J=6B}$~icYI#qBL!49OBffMOlX03DJ!9BS62*tpS(KjlyWpT@FjOVR4aUz=TGK&xtzJg%u1sA8kW2? z4=JAq>_IUHGTxzOkv^YjF{r%mqnv*+HTeC2bR1tfQzCk;kzbJ*A3`tCRHCRlpRgbk z)=6T{#QUwLt(c->+KQ>HOj||xP&aL&6UEHcOi^Bsn4&*vhER6Q536e>X_y%)k)1oR z($?N^c88!(;2?9D44K3Z^Aa2geu(K3h}bJ=M@Gw&E1D?`&1e~D^9+os5C?xY$12?fw(I@8ufXOWkVUb`#Wmlmb3)fAlp5+)T%fv-s^n()4wdn2c-MKI~ z0G-S_H&HAKz*yJi!XvOc`ysoZz8_cI$_fF9xFL<@8&Xd&p>F0xj~T0urE+~N(RFte z{V>+Rln$(S8QT#Mxl+(RLC1ft`4I0Y;e4c`bqHwMc!@eLcRIQ=c1lx#OI%d&5i1D7 z6kKzM5#1^Ou~J?D!BM$ZPQUHs74#odRQTSB-b#81ze>*i;GFnAi+(MNJJI)&hdwO- z6DT@xwnM7tmr6Z`_qY$Yd?KXMi#f=AYC;2m zpfUz^LMNICEykO0E?&~$>R%-;p@aZ!78fAP8Jg%PBv_awHL|sjVfcSi<17-vZtE6r zJ&S&kVeXGA%>C}%`)_|u(?)LN<9K^A+l~(YadPKB55GD2_T=tKfh>HO*^@0 zHg!$I2XlLJVGi_fwUY~Tc5-35x;~WB@9INM8=YL3R^#Nt?4N&Jn3IzWb9!=N(#FY! zH9xuN&Bxo5i>9?5om@0qjgyPc1iEz5nKe!>dh|Bk+iE8#MPmc0F|2ETo4Rye|Mtcs z#0k;$|0=EIExP?FrHV3*?TN8{xBZ`66#n*8TGaIuL%%CJ`w8Rw%7eSj$nM$DNRFKG z*4DrMFW4y>EQr+@j8A4;>tuE^+crmLqYbak&d6+Z#`=lzRWrfr{SDNAO`tw8hPq~- z%)Zr!x`truW@CUQ`&lD@ZfA{=)#!}#gjUuV^#|^xoFbmBX0|o?KaH9{;va@2 ze|8EohcQarHYljVNbUMGfJ+BVwz+55Q?D%frF{s1W96?1xE2X8G0qeu7ts zEm+PyqwEyG~riG3QV%W9?j?@ zFs$RAtFWl(T+F5pEcWf#NhKvlJ}?jT3t8)GQEI!z`M~6Sc<7Er4A4$-!^6nX{trT{ zZMO}kQISwLo-zyC44tz8qct<|u{_0M;L-2gHb>>oTnf&sW{7Ylnyq7A?K<99>Ays! z>-c|WRj$1muXF9q_Eh>~Ug;VPmb?&B_ybk<8 zP4!`FqoK`XKXg-6lep1Q_#B5-a}?&T?Zi=dcz6(jJJ{kVS^n8a$<=4ba^D%U)BJzV zX>zkOr1tO-&YMIZ#QW!U1ZugeCw23{9Yf`l!QVe~LBg0`wIVeg5niPLUn~vrR>9|@ zvnHW>CR|Ig65_358zkl#OK|^EtN?%6Pd*55RMK%#!7L2y4KH~jD%Md;U=2#WJL>m! zxX#>yu4K3lX0ikEkvgStpsI5}gv)Um-L8b63c>! zy3CT%i8=8^9;5(8Ga>rP#Vq*Wsb&IbHMHU}Tx&yTJ%%MZGIp z!mnn-12Y8&S~K3hIo{jiT~BILXW^Q8F+A3W#Um&J!daLrD&wg?aPogqsj5z*9#8@5 zh*9yFK8Bv{b$TmYj}{;xxk^BqVUlv1VUpgEX24s=PofxVj(Eg6fB^d#R+Bkp)rZl* zF5EBcR~-9MkFlw{?p(7drf>`S63zfwoe~rZ3tL1za45!umbF2dax-_AR#9%RaisM= zcNbdtDuJ$p*R+zB_SAoc1pqq>XaKA%P>&n(zSoZeCwF)p6!b{M=n+W~rZO-*_bOQI zGYA$cACE|{RtT1$Ot3_ZV3G79cKYXD+^l~$qG)#e_s_ciWs}r+^8A#6DpzZiL_tfOC>X6^GSd~hx*-)P9`yW)R{m4WDgwe^ap> zdt{D}{wK~)NLSx(c~Ey(C;wA;-FOdL{tZ;+*SA~lxqIXh7vgC1dv%vZ6M_u_9tXj# z5$jXv(2;vZJNbWp3iZRouu!-fdRoYwM!32io#ST}G_b%adk9%k9ZS-i@mQ;3A55m2 zZlHO*7Lx!hI?iZ}98)oUb6MnJ-7^b)oFrUP4dWg;-?6Z*X!y^G6OTJl%PADEpfhy+ zz;PN@?oQnSx4o$MQnWjh!U-^)58jmq{swX%mxVFyWch#B_H;LiN@oyj>ei>wL|(L# zBN=Y^pCb(UW2#GPidEWB=lxqblbJRe>)e~wWU=pDqm_e=%f`gf#`>|}jQ1UQ@_NKP z&`nl64I&Uo_QPDBGkY{!(Ch7c_X(M6-1&hHJ$2AExF8?6%6zJCD2kc0ea9_+)QO1w zm@M6h>7jqsAF-2&X=>JJ02gLJs7=JeGqZD)OOtC1r@%|4UU3VR>%Q+ha)qMQ5woX~ z7Kpf9s1Bw=Ow)|}#MOm^D`vPRT;-C`k=9E1K#;*K-T^bYfCO+5K5CPZwKG}fJ{VE& zDIxEKH3rD=QbT?PHI7UtQ*gQ`P_M7BDEG|0hzEa8FlG*7;h6Y1D|7C^jzms8^2bMO z=0i+lNDO@l;!|dzt=3&1r)uJ;FnZMsw7D}c{GBj0lfpew?r2MR(g3Bl;T)$G+4yY&Gr#YfPD7p!TP6WrR;DbLN};c5uOv*(NmgJ*E@ z2i|}4M*i4Yaw>XuczEE7M98Ec!6WD+kNhzPy9Ph&!hhc|vEzL;A!U6+R2ZBl1l70ccW57yi5!6eeAIyip=ibv*nyG4&bxw&qJ-WjLdv`yX}LVq$~ zr!L#B4Q5Lqb`EHE5BCBtwckr7kZLw!!6nA;Nh0t25mU5J4i5`mNH0(leIpqyO(7tH zv^gcKz})G9DL{T&UGfnfXF7@VL9;MJdd7^=IKVLV(Zb42L{cxz&l2YMvU+GR)kuFn zc4nZKyFFmCRkpk$vCygICleo6F(v35fSo|nl0ahl9I82+Ad_^S?esO3EYVAy6R8+5 zi*+OSSrZd)T*QqOv1{ZGv&vkgKaTR_!5v~yO3!v>p>Fi{@X)I!u<(_h=!YviquM!U zQ-0QgGt=VGc^rqU*O)GJk~dk|9-n_fwxCi|4%R^l8q@I+9i?MO<+m~bi@`7`9c~q;#QrR4P4EZMCwGiX|lI_T9Mcx6WVGW9d7 z9G~cjhF=huZ^Tn@n1Ci8qjao`(;TseHlidQ>&|x=jH3Y@H890h;H@TzrT2gGl@G)w zm_WFVYJMQ%Bacxy43am6YI2}(r>4ci25_2ymt?1$TIOi^6qaEQ@Svb);k=<7{=h0Y z3s+uMhhMD2?p9J_&Az5CYSFrceU0es`!%8a-rJTt`ldLO>&^q9WgPDLaFu%&4f`?qNgB>%9 zvhRyx#117vw!Ugc#$kH}{bb7g0$R99 zUegGb++I!2WD8l4k1k3+>nE2ICx7|>fxp+ud3C_=V8D|zSyZ-=ZaFwt{qCk*HA-)C zraE^&D57EfTkyjBSl@rDHW%|{m8>UkcHLPOjum%&W7P4&J4|i>>iy-Ka`6-AsShmT zIRQH?nFIfg#17}hxcHh(E@is6LR8<`1ljm~;od;;m_rjS2AoQ~0z1V+&#rg4fpAL1 z5dbU`aNw806ex8j_gh!`My7&W2M0R^=L7*dYB?%j<#{m3n`PX2a_>{E>lV-sj@!Aliv#oU>1w?eYPKutKVzo|oe z5;;5TJIluJ$;2r`LA1;E#DsYqomJSM`Dg}l8okkM>~P-^>w>ddk_j9(IU^J@c1G~C zvEYN;f)AQ~}p2;8Q&`~v2-^LoNg z#A2a!QG5_j8sQv*=p^e&gZuEQMi{$XN5Z{Nz|7LFpKlu0p*XNP;ziUk8YqQ$fcwZCFT~SS$PWr;j(vsR_L^PCmF1r;+vkkG^u3C zlO=~Fl`PVSESsFmM9{m6s>kG!Gda_A&R#L51N700I#gjts_Gb7aPQYlCzIEXOzDWg z++N_N9>;&k%$;5suz=encF=kD%1a-t(=-eq3^nn%f$>8T(A#x#VXJp|n6qh>=-1lv z4cV01Vo@}?lX7NyY)>8$(K-Yat?jQA4t!r*zVSGA7b_9&f$a3<71@B6f!ly>9F&%o#Hd&ce3H0sc8(GGl_rPDTv{%?w;J>dK)rcB(~KgtC`)~ z&A5CCwXUKtfJ1ZnF9LBOVX9SOo{!JWKwW)~FL@+$w}`5GV3PUT_kZM`6$_;`x%)b{JXj!j-O8xV0&Gq{!y;8;3rN%f$&)z=U$l@A8N z7hP=RVjWJ`3c)65Ip_Y6ne?>8VlqjTNn*}`rutFv&-5s`dsmM|oSwp4Nzu$3&MEJ; zdz11$69GI3M($va0HNUo)r+)HCu@I)JMQNKoGCEP#jRt4p8JQXw$|-x6qq&lP8btU z7H_?fNW6Rt$zGg@B!D}THt z*h~3yrrUUZ6%cvFo-!aR;ywxIiSTQy>p=Jb%$=~kzFbX0|L~BG*puOA!gfoug8Eme%Tk!-sXFMldJ97>`&V*>u zl~?Q-Lx@yZ{3iip;kg4|(EXfICO3un?GW7#XJ_IU#w^CkN$>=MDbFB;PY99#k%wRj z7CVNiE+umCW@TpuG+kNIbQ#VJRo)>_ZYQl~OD4;#hw_WP$%=bKybga1^rITxp~4lv zB+h0%PEZONS2S~Kb811Zs#BwATwC%Xa+DE>ssloGqu3&VMM>d2F0U}vH)0FIrDZ0G z*Na(vSdt?kUfgc^2HI{XFU7-gNq6yiS^B_y-|=vOrmhn{f_Y5o$2@#NX~TPH^0|rK zbKyItTqb2sEsG|L_-=oD1?plD>%p0X&)f(LY`5xb%F61yA#4KHz&9>Dxx!e zh?U&A$K*P>Gg&cI7DsdPs^lt5!hdjVIowH^Nx(?jmd+G!u33MF9$av`}8R?|F3e9{jO`C$<2#MEsT(gzFxien-s?#LR8vmw8y zPR>2R{IO#a5AUW&tXbl*Gh?h1c-1#x!Ks)w{#dr>xJQ$ix~E5&(6)N%69Xz{QExv(u>^iM)Em?5}us3S<2cR6Fv`2uUr%wHL?C{W+-zZVgTYI z5{etZMBjh7&ZtWg(5W}`6FhJ{$AsQ=5C%9jyTyjh7u6gOAzA1^vIRCXIT-TfL+&Sd z@?0CKCxN1@_?4#eHUdEvqtmrJ-pp2>JUk%E9pqu{(&s0Tbf7C6s6bKHa!Dw7$D2Vw zI4sA?=Xn*yFbt*A-0SspN|U6>qbQ7rky8}Kn-za=nRv`9^*#^N$6!N;n_Vu?MdOun z_>-LkYM~}G`A~zCXhtZ*xsRQ|)L*_A-7tdiKxAvERDA>bWJzB8HB1Z$$jIAsiR&`_=lz&OE;MLR9t$q z$UlFv6Q60}fQt_%K27Y6H-i9m;Db0eK$1aRh>{(;Gl-}hIx!0cP7-JGPzytC@|bL5 zI;ZJ$`SY5Bs+~RB{IRC-r5z5)PQ9SoXrcLt2j(36*!fpDZFt^>dow*G8|;f6W{g}| zlc}SvoyiM{ePR=YXDEbaB=a0HUNQBAJnMf<-*9X_W4Iwl%Dlvk?|-ymF-en<)>tQ_ zHc2#13qcp%$j9s8c$v(|o;-oe&{)q%sO#e+j^lY_YtG&PZq;08W}p`oI7r+S>|JvG zM6a+IkvA!s;=MT5u@+g@#yh;8LHY)Vq1NnC)lMONWqN6(9bMbqCp*%E-v|tA%_V<8 zhBpH#(Nx!^vq~-P*`kG~FLZ4!oNDL#lA{)B@d;^)X$GC~d=`k5qs4Q8uWpPPQ$u{O z_h_Ez{F1&jjcgd=jAozb;`4lW3c1|F-Zwp`WRnX|ri9gQ&ojMtV)j%Lx*YVy$t(HI z&oVN3%LQ$!ib6J3-6vrKX=YiNW@dk6@6TSW`ir1dg^FknXOHo)^^fh@~$iC7V z+1D|aze4(T=j%wnKHft5_5J^b^y}BJE&clbCep9(ZzcWu>3>W5^~>MVuTPVH{qYx) ze*ONp^y_-**H70;zy4L0etl%puU~}F>u2%sM@jniUP zTl)34^y_cw*Wc2w8%n>-Li+V%Rr?U7`m%0{W#FE86-`DT0~PA**Ylf+zCw+PjO2}eGM zipy3ag+bYhN&*y=wRZ$%w-A4gP5y=QttJ;(5f6NfO@7s?bIW8)2}qanwX!O*rFkw} zn%B#g=KEwzajk5LiIslW&?K)cRuYP(WwFxyCSoOdACNVOl{hP#h&+ib6mc9!t=SIh z;o&XCN-Y#CC52dtlz`Mu%0LT3r*&C0BngkE#aM49JSq-fx=(ntZ<~Kievl+S9;!@r z_sC}NJOJ4&SS##RhBe}3k7}xM|5vi17p}0NNSC&nZx~9{djUOH^<5Flq|Jm$`kpFl zYO=lAJv#H!+Ug#BN_BNLCG_f=%44N96-;>rFy|d7(AxdB39gR%%+(RNP8v9Y)@=7J zcF zv^13(kN*}ue3Iy4<^6R;4=c9>VF;YtEnoWWb`^>TPiC5V@=Z8czN`K(aIk!+jDuYz zyO@9FYQC{f=<5`Hi;^bzZ^RI!frG(EV|F;4c7Yo4B+}#v%RPUZ&*?OkkI)r({hIWQ zcRkn!9zSP)oa!3NQE*qN_rNX~-1F%f8F?fn@tCcL>!ic$&trAwoe4?{VcAxRs;C6p zW`VYcd3;nGEnpcmc=Jm%__24}!0QV^=d)WoUe|H1^y-p?GUpC`(L<1SS`Qu6~bzEgDZq`rt7W{R?*+b>8Bm1lfTe$x+)*1 zb9S6Y;uKwohe_!;UEKUQ_5bf2r@nlgp8YKl{#zjYw?KdRZ-MYt0%5YcbVlloPSy(u z=^M;Lm8j=#9H>M^DpMVk)w#2KPpO$?!l}R4>7`E-UE46*ti;~Tyd?77OIw}$^g<;c z)=BEkFG0Zu6>A{1K_L{u%8eIZ@Ft9Gqw_69jYj1cV;y*DM*MK`l%7$)Fc1VoeNmv% z2Qd^`y>oxCDX zi|~GkE=(Wjn)@6aOy5?UE!`)O+%J+;nYDT$mUOvzn;U9YtW$k9PG;l2D`xY~QD3 zg9U%h$H88iqZivX(r`Up(iyAl@Q?>`)?B8h${W$ive<;`i!&O>-VD6sQ|0N4@83Or z^vk2C3JuP@I1FIiijcJ{+B!%*Ux{gwx^b$jfN{_jQq5}Z+;TiB_{mdxX;VG{G$WHf z^D`zSrQn^oI`pBcXgo<*!AGfHXEHq* z+pRx0FXq@8`1A6@Pr-EvcqtIcMRD}k4yBx(QhVS5r=|e7*FQg1Q0Rgi2Ig_HUMOMU zU+Q&Qf~#q~I3B@p_{_qoOcb_u*;aq=c zah=JxTk@EZ5w0ApqTM%HJ*tsptpJ%7!YrNpB(ITZtrCrCk26JaP#-S~dQgj8hc+0DX>-xG3H1Ml^SzxP=D^qalv z3AdnWalGxEZYkV8mT&P4H%()2vQB?t@6hV4Pt;uua-aJWO7dV6UDRCgE6NR_^eRIbo(AJKoO_8*y^vUta zl#?4VnaYGl0@~`e=XR+1H@i68=i3m%Ly%E8)<0E|nUfs1(_&8cAP=rZPSStF!yRPz zZpZ0PR#s$Qz5Y5<$kSU$Aus+nq>yjEwiNQ>CQ`_YTS+0G{Vj$3G%4hZzmOF2epw26 z%A}Cbgz!-qgu|GmQcrI#g?#;gM+*5`mO>u?ErtAB3i-Db@^2~R)l$eOHxw~)gS>~H z>xT<_bBnS>!T7*-a!FnEsrQP`)>9@c0d8&reFT4V z%H&c(sD;slzBD^E{7-+}-`9b7u*e>=!}g`CpXa=N!AmblxFUQ z4?O<8rqeK(fnX*h>Q9tL3659+LI!6DcD-^=>1my)Nb2^+^}R)4t1(~%mB=EZ0*~xU zi7tx@!r<8Vrl&P}EQtmothk(bdZ~f{52|cXHVusr;iSP9YS(`w;TjEsce(?JNlXO0 zmf_a3yEPn>O&HO@4he@UwvQCvI)DkAHI;yBj;-F0sd5>v74Tz>59e;c>2enN!}sOF zY{u7-l7_O5KKmzEU3JePo`?>1X)6~*akJTsD9@ffd!{@LmEV5*?Kh$J@=KeF<*X=3!mzj#bRbXsuqe)7HuAF=)KDAYEeYf6FO;&INL!XpwPYq>SQ=9rGyur(o%h;=6bCz;Q?Mm>g(D%+Nsp&M|-W!^0geBjU9_Ngn0)gW{AA zP#sPP8**zwPvUkSd>x_2+iQdx&<~jj`#~^YS8(Fo_jL_FF20nw@)|a&)a0F;^L-Eg zUHLxx#reJmobM~<>EjJ007(Qa&OYY<&*uHVmsmH1zU>x)YP*GnhM$j`&bZlMK~a9t zZptX(r_X;jMP`ev$!YqRF-c|$t(;tm$=9?>-eZ&uxbatx8+T2Uagu)lgxqU)OSAlk zY>6fCA1ek%IO%qa0Y8V-ZsP9Gzeo@Bv@m;l)uPA;x|7$oSu?EL&+u($=JtOBy>@w;*Nz+kA^py2@4x{awZ1ek z>||(tacHrwYvS|4sd-%!t?Qa-UDrhG)-!2+eu>s+Z-VPfw62GU+qTjA1QhhyC0d`o znXOyTm38gN&0Cjfet8sQ-g*aGpRgrw+eYiwZQOp7nx9{yc|E4MJ#M*e8_ip{@kNf{ z+oFGp+e7zFFxqD$#V>%ttWP*d{|tiV_NVn{&Nn}Ss=X0=!b6558~r;*$j%w) ze{oqAaLY80e{4x_xz^B;;ImoeW4Lb?;*o#fN9lOG)$rFrrd%iZBFR&JELim&b5pC< z+|-iYv03PjE!ZvFlrlBNSo5C!OQZYc7b^NS0UcTpO&BrWsc2=*1X0mX=oEy@CP1K7 zjO=GgA|hr-Dan#7Nz1{>J12Y76<1|<;mW?O35_~Vq8p~RfpF+{OcK0lTvD3al&pUf z`XunZfM1E)DFMxBbsElSBcXVI*2n=VAZnw45fAm=W%-;b3ss;sytgdcW5Md+m3U6> z@FX5?GCM}S#Y%5T=ui+=u|Tr9uQv!MYosiUY-*(L0`4}*+)0_X0LmdTpp)Y`YXOCG zNS?Cp&B)SOSz16`ow+^6)TkmJyK;Y7QzMCdFGXms6-=RHABZ=fV9-a(Za-7FE}$71 zjde0{5+lEwIXskJilQ9Q^x=pidH{s ztK2OOgBg4Equc~3g}ufK#Nz5Kv@7)!s_d&>s!8Ymq8H9mOAWkbk7=;?`g4CuKC~=R!#Y6R&^H^1dbb#~>lYB~2#f_n=I z)wN68bcMF>dpJNEKVh0qFTFcf8V!L}zdUvloDDHd- zN3TMA4ar@Tbp5Et)Sae{vG3yH95Y;|j-!SOKGJl&2n=``_( zdV;PD4Rr;-hugdLa;Km(Pmy4nWU)rRoX7^F_ScM^Zxxkpr07pMTH zh0kS3b~|7vB`1`tzI2`xXLWvuqY3RHq8iN(U6sy-fehL_#5!dIQVGY1Hiwb|aoQ5V zuqkX5fJ0@#8L887#cIRs0#a@UP-8v|X-33mwnw~|h?sN3o3VU+^n{CF9#PyW4F5bl z6&e#ioSveGZD!xJ>T7?2UIi4oQVFzjzjPoX1ZB{zfWxop8x>b5NcYpp{BMv`EX> zXP-zhj>feVV{O^yxJ*cnP@nB6{wI|$);UtAqj+2*P&}k$^nlR^3#x63E#r-)ExGz$ z168lrlm&6t^&@{gUO{cII5PR=f0`p}iENV2+oQk0nA_Xjf^ z*4UKz4otdG5}$*@`OIlpWa*g2Au9Raa6f%w#g;8i6D7q?vr|&pc6LH`HXWenx-DmW zB;Rm$AkDo?DjUg;NogC|Yxy{wT64bd!!B z`8erQsx9wY#3U2e?G0N^82p*D(iS8nbPqP*<2}=}qU0r(Ja<;w<@F`cK@*D1oMpDW zdpA2;{?iwzPhV)rW6cg6$CoA$nm8*ho}X*`cyoX4?C|hRyz}mq!38>YMlMS|5O6-6 z+uGC_jRiDteT6BR%jbA3pW|_Op42g`6^8UGqP@y!Q<>2Yb{Orr%xJUoPJ)FJeZBBx z7DU?j)W~VD`|C86O1Sdy+$7Cy02rylIUr7w&lq*WwGofQ8U00U?}e9dZ`WBhnU$1~ zg7AMcEEsZ~Y>$YFIh1F%J4}l{YKU>ta;LRe&%o|LoH~bxtn7hQv0O(C=t?+x_cE?c z9_G|={z00Ju(U?9<}yRBK`|p99F6&L2#UYEYzF#9gM8~G4Ofi3TNfD;AkY#r#Y1*R z-?$4#!_A8<)1kx-$3s;#U(n;RZkL&Fq@91l(Kk@#2n&DfNae=gjQ4;2Ca;xzqmIAP z$9iT@$;=6ML@vvskF)J|Mk1Jj3KcnVasZ4D4V5BaRxu@bSCwwo8L7W~Qo{~4bR3nwsQ8q8=+V{+dKjF&O2EO}bwygyW4~JzXMNc1sv4`#156Md>C~xCe&gwTUAftSdRiX;GRf&o~14#vl!kYw+ zDp4zo55>w$%~N(378|H8Bj*+C)~tW@Nu=bfBc8?D@Z6%8V%AlnvN>0Y$|si(NhPX0 zH{hlFrSo#TWuoT~&Sbb_blZ^vB{4$roaB-Ud(L+Kc8j6B3S#n69bbP*3WSC9S)5BTE|&eAR1beU`)#HlaUb13$+b!h`Oftu;|&9c`SX28_e zP3*zq@bCk9p>2TBu|LYBNw`CrEYbWNg{h0g+3Y`X>_$ZjOwbRM%b1Lg zN}h!u-?$UjdRrwgl+Qu&-Z_igh(qfX^d7`$zN;i>$>v-qVa@RNV)vx6|zqL}K+cghub zy%vS!aBm>sPtb_sl{@p+iLDwfNRxLt->wOrn_oNfgV3zeWcGkJCq&63oN-N-N2PM{6?-9bkuiz$W^S*-OVBu{;3 zq`DI~0tSC@63pR;xnx5_B6yv-@OQy}eE1Wje%ywK$OV^oAuAT)w8b~^Ig4dXN*CsJ^Xp%q&p~8QuhfltDid?=Qeptu&v~pQWIG@vE zWWdm^THq2dd|Zvi3je~W7qJ^H5r!6V z7@h$@EM5G}JS9$C6r?QO`2t#7PVs+*)whgJp+Czc#k^?>Z{Bq2Ey54(3ZD^V zJUUIF8{Q%aap}SNZoKN@lLvpHOCR8W_sr!#42t;^2OfCKM~g41J3WO^*7!B_J^cLx z{z#zlA!&g9C7i_UmDkMx8h$$bH^Sd?tqDNShqdoP&ra#(3RmMaOnsbTsP%&VrYL_) zq6rfc`Ik`$j(=6(`(y2~2LxN+J1fB5_s?La{Lts?$sh*y1_#KM8=ua?^MF6DBQY2c zVT`5WL+ZN#ek+8}mG{vF5L<=8BAiXw6WjW$P{Klig;hw$?xbF5f8eFBUT>Mbh>1&OMhwRVKwpntXV|E1f?kPOwp68cSiR{ zyj)DKig>wLLBvbwl1_gXi`s~n;(B7AD&CD;#B8Q{fFd*Ba1WVdQU-%1@|k%LJ5(@tnYLJw%^Y^p%h30xa9a-?L&FVbjew?jG-T*+86D%Y zi*>%l`N|4^$=rX-i3r?@8d|s;jeO(jj-x)mcV8Xe)(7|uU4W-_1#aFi65DEKpX&4$ zV4>_}zwVl0ah@0WrOEM%GFz`ATjh@6*>Gbq+*pJsBYcAFfWTVV`=WCNx%(h)%t^2fo?=wAmv9f#82kUe%>X0vr_$L;CV9oakS$ zcR9%KEHG@wN8mN7-EX#ZvUq({M}Fw2k4peqK&HPaA)d#sTRtJbd=RE-xT^Kr2d$s( z`s7=@uJOqydE^V^K!I0yMi02}xQ9POctCFSz}@+s4Rmes$aqff8|QC7*Yn$RAmG2I z-!|zcIW?xW&d#cTUfh16F;d32bKqv}b>J2oXRO9LH)em z8C#~4#l;N>7;o`qa9^^rttMH`?0)tsbuHeB5WqKVrk(v+=z4LwFP!mBO0S-OR_RA# z8W=Wva}yHuLJ&BMXE(|ICeQu?JV>?MElVeh`;JAeK3P0}t-+b-1%2_tc;GFV)(UtB zn|Wv6jLsfhYK!~eF!Zr^L1$VY>OHO{V8Jqu+4L-3FL?40$(*G(qd%Z`$u|JtpBlnm zMqmf=;h}neIt|xBsyuLgaNJdPV|ff6P@X(g)Vsm09Q2Ccr|FXC+-}uIL;d_-Jbm)~r<=C!d%-EsI$S(|)k+Dv&HKY54#jt^f2LgdXg8XK z`;*|7bXG!=P(1ni5{id~gyIR8P|P_TDtv>B{r%Ft1OoEiE1Cek`PifWEK$Nhd6X`H zqL)Hy!GVN}G!PBs@(gb#2`?0-SW@=xB@cPT9riBGagDU&;g!;k=P2!Xh|-Riwa7B( z36W}lewHw%P%wxh?t?@gQygakK`>wfhzl0?QZ!@7@gQ`HxIC3_;*%;l= zOYfi)Pf96Fc^(XKuV8tCT`0Q^GT%ky*{7YX#eN9@w82CD_0@1@|GF50QyQc+RiU6b`n7f4})upNEReYjw|D&xcKd z7zZ5k%VzPezTfm=hfFyZan_)y?T+Y}aKgc+q(U~>2L~yJ^N|tOtFMo+J`@P+6-QVq zsY+HWm`flazJUvT#CLL$peTl6+yw850@;3P?1wAy(__R>A3(7ETqld)>IGbnznFl3 zYj^cuk_~F(1j!!IpHM&U8`H6x23K1Bdw zH)}-;cWOinKU^tVILh4)oOy{i@#!ZImI=l!( zzT>-j=_ZmdT;{f>At{j70Z^J;Tlat8;^Jm}+viP|4zZZFA<)^9SJt zCi{fJqVKp`WkQ> z3RZJ9$Dca&;wfBHZl)J@vrVR#@He)bCNKXFkj~A`+OpCpt*+5mTBb4hp=C{tj$$fS z!)Pg%(QFufqt!6FMyp{NO~Yz`SVrG(bd65KvZf8A-7xwM3zH$kpkZMWCUlK1Bq^5B zf)Z^7OSFtGtGZ=aiUnDXjseYEhGh&su6l;m=olTSTQM6(58LQ9pjD&YXc_IP3Ek;H zs|st`N}y~<;VF<&!Hf!&Z5jQB(KGrVS0;R&8eIh+iUMbb1$ny-mLzI_PHTI{{mFsw$)X!&g3jOG-lrU~P3G?kWNHJVr{ z%t_Pe7y|{LAirW^r#rmMtTGs01Meak~qP+;0zh`G+Q=l4FtFRGNzP+&*sRIYly7rL?=h!@XY|o>E)omJjTe zc@k0E*P#Naq>HwqiAnL8sj+K49C&A{jA%UH%M3@|<}xE7JZw z2f;`EN5_vIU*A2$?7^UW&EuwJ^jhMrsaOM}-EMcFiMG}2C|1wtm@q>vqi6NI$5zMa zbh=H&>KLXq=qXm)Fxyr~0p!>1LpH13>q0eVbI^yuG&`-n(zFa~V0EEdvuO^LX3OYw z2Lo)T*Y7CJj?wRbvaz?imeTASR;S;@+PkeTVAW=~V?nDutKU&tmNCHI^o&-o)lyn5 zqtk0z*!#ZKR9bDLJLqAvyx1w_7ml&0en! z{b8%tF|1y{ecZB)RvUH%j2FgZ8fL4H%hNRbZ8lD;57XbZ+Joa}&#=1f9$Ov@m!sQk z_Yo+p9za=t4luvq-`_b5wOWR09XFeXH5jlL7(%OuJ?eCtiq$vz767?rw5?7LR;=0S zb51@w~qt$|1dWO|Ao5xlgdWe(QZd*8_cC*{ZX>1KT@ZK9(Y^6;g z5n!bO5C=xTJ7{D5on9aMVf9;mn88-x>@#>Z`^Q#)-{_ewY`4<_h%t>;AIi0jZVTFJ z8qH=K+iCW!K0;6j+HDyF6TWwhL6`N*9JI0D-GPaa+qYn921eUr+=E(1I=9H=2WX>$uf42E7h0e4ni|0!g>GnY3zuOq=po>D2CUp*(C*;^Lkmx(Wi7Bu=YAIsHhj&kAxxv! zxdEc-;+%KeKQx=h;Fo6G=(V0U2Zm*_zCLZ4O0)NrWo)*Le)|{9ezV5KLHoP2_(M8q z|0Nx?|N4s`v_IbBp#7JI!QG>n&b^Cw@1DAUmo$E7sXQJO)8bb#Rk3by4$tU3QR`VN zVLHy0qD0G6KWVhsq5qGG3IArb0n`^NDfRe`x1tSD?5T-QRgmd&2>`YR+>`Dj-A(vc z=3Lc?2FQ(~GIVyUZZ(>f$-J_|)oNZZ-H6s@2EgVQtL@e#O5npx~R9(Hyt~quo{T4^&~{W1~pqUx14l7;Sw0c-4NF zNj&K9!07dqfzj+Qn|-6zKf}L2KD(gfgtZILa_@fif&@^Cx15m7APa zHi4^>3md4(4!N|gE@5Fbn-*CzQy;5Cpw!#IOA}i~Pkdm8_ab_}W1$=Oy|G{(x(wauM=^N$%NQAaw_JM;g7YD|>(=aS++A>;wVAtD9$LI|j zfKSXpV_-C~!^pLB?8F*{lmY*LBgO&jc{g83t2gcTtU8`t-q%fMVKT+*R;@rWN!@hK z6cZ5im|6nDo`@}+vY4dm@r!3KpFVo?=%H%wlUp|lj{_SB_>Dlr-F?qXn3uEgNHPAJwGX_Dz?52>J${K$=IQGC6V<@q_S&&Az0Vt6w>yODn3vXd(oaupzW&o4%Q(0^)1ASSS_fPxXP z{1cVjq+Ub(R=L+V?(uaRk#*gFwGLSKvFo)FYxjoby;-jyi0ytI%^hu<7i5!$p`UsY zs*MHw`|N(o)O93swDa{Zv-`zmcBiU+^NPX^;E&-1!YJ?6yk!@Vu;yew_x<^|-sDKcpxE4CI;+BCgjoIt#AC#b>e8A!i;SWSBFu z80h58tyMQV^Y}qK0XK6SJ_#magFlNi@@FX{ozYK!QAQ#XR)y{X77uTz55(0DB|m6F z;U?D+sHT23EPV9jMpv$}@{|G+-P?le91(tA_Use7z>nUXHdflBODvBXGk zN;X58PR`c1(pQt|odQsC1(eXqf?n}| z_wsuGkG(hHZWG!5MZb#7&Gm)TWwj&^NpN#~6I)4~$!^O@y5sg=3qi>ul0ae55J_vj zukpU#`y_Ae8lZqeLQdkGoVdGJ8$nUjxc9C-{PxO&UiOp+GaxzOWrTz7O5wmJazPgk zYU5tMq?9t5zD*s&IelWJ1H!T>v>5q+^V*zwQOH>(-PI$>uI_Dk#){8XULs+9<(Z0( zKa6o8?s~tP^tI@il#;GVzn8Z>HF;lmYP#i-X)xof2ZY~X#lgv3dvN+@r>3!m=AXPy z>eQ6k!JWI`!NX(+ch;XcN**`9-C5(dfePc{N(ylU$A>W?6GK%)V_QSxnf&;FFkX3l zxcQF9htX|g8OD=44B(yyve50ZSvH*cI|gL`{WT%g<5?0?oqrhca7Q$5ml*8vga=QL zn`Mf(@({v*OEeSVa*4)M!&UcdjfRHCmxil8eDtvXNJHZ{1UPei zDblzzO5->-&0-P$8z-@9gy8X)BG#<+Q3(CoNUS$ z=-LyODmb0o0&5(f2-+di!Ph(wASb@yUxANgGiJ#bSI;|D3AgsGrAq znq|(EMA$R1;u1@4~qV@0kQMgmrYoMO0ANqfU zBt4^hVa_FqPLK$9_%_CO9O zS)+5Z%mz*7-Z_^&9|t`^2bXoj_5r`f44W=NauDu+w34Caw=PWA_J${TV9v55;MfBU zuD<>`_8rd_?{Jg|Iv8va2(ay7kbWh;BfJvE&6f?(D~v~2GB%q`9uQXkNcN4hv8+Yp$+Ktx z&Z$5F5{i?3^4tvGM4%cTIAn2Jy~yo@)sU36`d+tt>N=rg4tO)z-8bfx-vJT9goBMk zAkoKu_iW;>UZhW9z4gqX*8+I^@`L`qF7D{$cBA0-`5+3CM-$Tt$(IQPyXW~G$<9b)k97lJg+bP1eyC~{^jxCM2{^fmEPTrQt8DSrIL8=evl-eCmHOSaRJlQ(JF0^ zOwW_i@WAnw>N^~sCi&_bc?Q^Ojjj42oNu6`j^Xg*_u-c6fsMndx_BC@npU-cJr~31 zm=uu9r5PqQv=uHECL6CU!w9uQs8~B>N25ra2k;@^h?ZT)H3x$kIZt_18)X9iVP15S*cH&Dy~|Q4_Ggk#05uNqLkIyRGEstXN;e!p;k=@ z)NRp7y&jsgR8qP;WI+1bEO9yT+~a{`^>sMd`i{9XFgtjl=p;eQ&JeqQk;I+c8^qv^ zxo2S;EF~s!{Amt!2a>V5`cs;ZPIWW{AM^sOcR8LZBv*gtSy6CG%`5rug>S*BL2%BqCQb9AQcWXkT%nMEzTd<~1~AA6fP!3Ki6MG=vKl!wtUC6xlvyqQ;A*H=auQtm z$#Gu|a~iP?+pxc~4Nay!B~B^pMu0RYrElG|F?%Z;!(4(28X;X%SzndSz}@4@6)+kFfs$IphV z)*BBW?`dfK5$^9l+zguc3!NwC| zFvox1twEIZr;f&dwUVx+q1g%aIn9F%9-wx0isGRc_rs(s*I*!AlH_M>bPzMi-j5(^QER;jq6qL8-?I_qjqg5 z{D*?Zb$ED^u*CYcp(HpLepk+MxTCaNfLQ}OW1eyb}Mv*}Tus3+Glm?BEI}J-YEK8Y!JKiwT&_Jv98(XK=6kC82+Juaic=B;Fs7a@_R}B=XWX7+N+6- zYVU4z8V4KbH1_Xx8n@GFJo<@r8jsUDjRUIF*ypN@hy3DEN~iI#yiQ~9*U@S02|A4# zE-BjBjydpdj$_mb0VpCDssh0TrjJdX;ScQ90I&j%6)MjlD9 zJd+-{3m_7fNI7>#c;L9Wa_WwvP~wj+=y1}1nj6wSk<&O;VR{kQO1Kg+U^iAWNDhCO zX*YkTnp$;|7@kS?1-|sq5Uh~UI}q=EZxZMSN$`yqK{{nHU`oWAn92kyuF^<1MzEK% z6{?3s?=_l9bXR79!q{vJ;akVv$ieoOLOGL@Xxe4f z)uq*?iDHm|+<5LAFADH$Y>rn|NL?p?X9LL?j-RT;98<>ZQ8HdlJYN=|fXpm$cxDQs z@i9wnqik#fn`Qy?R96JCek+1TN4^X9zE#a3&BawOnOSXZ@pa06EGqlIL2c2kt&Hn`Cxs+MC|ICSrZ|T%h21NDewjPK{ocrQA@?{1<_;)Q4gP+vraFV<6 zy~wq*z!0QJbpVaX9Z2c3q3O6}Qi-W*MO6bQ2+t{MbBhdpH7T2`J71W8lvtt|h;!Yi zj(NdyAIlbJpL0FfA8XP)&4f62LZpfzNYl`vQqWI)6;?y)Lr>xYB#)xT$DHLGPd%x3BdCuQN8hLej0LWqfmOYUt2rRGO(r@~p1lyKv}IYEZCo znGFB+TO`@AP_cwibePW@MvAUz1SX5ab@)cAGXgqCf{$>8uQe&Gm*7qp=J`aqj-1E9 zL50l@3H?DXaOepr9Cvs3b~Q9>8?L&$`w(_UlkSYRxHDRRccX^vZ=i;p-m4*Rr-r=z ziPVs9(rU;)RYOj>_VJ8gT&C2JXXVw9tzSnC*%H-|PYekflz}OqIstO-8?!f}4syPf z=pY3Y!<-L|gj0}Jy;Vn!LFr+5X*=)zOLr!=!r)h722q z5df9rmYijOvaft-fs@%+A>UVCystdzzVg|=a+b>_ArLY9CZncbT_XUDg9|`*xVlCT zu*AH`9MWN?WP$L0;=hXE^uFQ@8t7N>^O}7-(67R4`1X=+BLNzJG$GFhRte|f!Q>g(pak&BFW{g8 zz7-Sr(#Ob^i7bSqJE0l$cl^jDIg)mQ$g*${R8n^p1bt_ZlCnv_JOOtXGhVFBcTxCp zqAHMmnmkzX;mpZbmJp-xqbx;~?6W+3RN;r0%R?7W)LB#2z>#i1kmu-1A=QD(V24Kuf27zY4RFhhJZQ*@c=Iy;|!+{Bfq0OdX(q=*m^-jg0*ossLs!xuBS}e#W0xc>3gDxx{1?v~UV6`*5Yls9yvz0nSPcM{zVU24I0L3E_U!zk z`K)gZfVf0b(o{Q4 z;Qbu>(G-y1Vi8K3Iosa${ur5l0Fn9dWmK<$VCNaxo16#+#vJs;5N>H*V332{8~mgj zV*kYVMli|xRvkq5fjOeMgIje(S2wnQ!E1r}cL3(ZGY?4pRt&78e6K^o zDe~x}=MD8Z-IVtmq+W4udPGrqf^U3`b>R-rI9Ml4i{m6K|I6Nme-+gAT$a*BAy~=u z4grC#H^}t|mev=GgHFn(WY=lCj%GL&qgo)m;ROW3y4& zD>W*Fn&k(jez0m(;zupg-_!sT#~kkXt~2bNjfSzthLKfE!HmU`ZLp8To?D?e0(e@_ z#?k>DneG$UCL>8Ihi&j27z6Qtw-=DRmnbr7$TDguZFRJWde*^i_&18;>%W$VtB|uP zJDfPK?M)tk`!7+U;6;2892V!I2i&;= zyy^+(vEw^YNN)6&NIBW9kYNCQW?3D-pnOy8-5oxneLUOAoE%6~iwB&ZF6hw6+(W%M zJ1z%a7XxJcn~tg0P=)CtnBN#i*GFcoOp%=379SBu8GNKdO+Il%=-B zg8)}j<==W0K!~dlslW0J*ew)9S0E{y*An}2IiE~YDTwEPRA)tno}oG2A;PV)((RHY z1mjIyX=5|fxr!vo8euGXRV>vQX-mG^*%LI6wdy)6wxlj;e;fN~_EetDcWt)5LZ7iv z?kg6`e8fV*W9Oa3b>?ZQWH88=$I`~;Z(m6ECbxl;s^W}_BpS!DX($eNJK!*{jtya$ z{I2d$pRGWDcTtjaQODKf2X|}Z4g#dRSF}~d0XfB4XLcKyl*vk}HYsm8|U9 zh-AGBbV!@Q#yFGbZuWP6L2l^ll23G)%9ayHA4@aY4S6QJ+mF}m8Il0|x_SD%%p|Xv zy|^2(`@sfc_m_L=_jc0n^Pfoi{g9U19#FaM3m4aaUh#|PDY@-cdAaSyuOqj;5aqV_ zQcg**A0TC>z>N|=PUHyS56CoJJgL09c-_LLZ}rYi-y8<2Qw_*Zi0hnvNEy9H5JeGd z`Arb~RRwM;+F}8gnR-n_@S7+JvIPTz83_ezq~tP<@)cC!O=PhPr~-8f_E(W%JyauP zQ86liLKYFDq~-kBeQi#=rYlGAi3H9nLdrHY&rmde%hHxKPL)*6G@bu_e0?40Suul- z8LlnM%NSC5A>}}ZEC3+UrOcT`rk-Q}9F~|R{^I7*t9lJJ_R)R~)oZnDvdr{oryd8c zk~h;{)?Kz_!{6%3vb11a_)8bUS5xRh?9IA=WI3l}Vd+X<5>48v<+(KS7Y@T<(M<&l zk9<7dA=_n%fWxdQ4nxT7OnyklsS*39&Fa|Z??W(BOsVMHwuTTz5Q;g{+a8EEY)< zb15p;v^|roB70j%Pmz7pS~IGUrZbbSBKLqogA1d=MuXqUWv|FRNY@aidz~J$B(cRU zW>i2Zm(|S@S|kc`R*QIoatR*d zIm+d?C>YSjh9jCZ>stpSj?yGQ_+mkdnup(Oi7`cC>)ng>HRjx5(j zGK~4@7V|nJ!;?)nA=wBxC`<2>Gyw4(o(CgK?}TI+@yyE;V5A=BvtSfGPNl+si2KX) zVPu+fJIJ0jGS8A!4*X6!pF?U>W%D)^&svhf zp%kUW^0o?DCz7>aoP1+tnK=JL;mBq)Y5a!_ZgJX-?=buY`7~kysVJ#Nx#`Ocx|nk# z&uNpErs!cYL6uO-wX9%67Afa{5MoO4Y$t`Z97z{bSvX2nBj)Bv>Pb>@WbY7ClD#Rb zxF|D+I3FYthcF;(8lBFWJZlu?Oisl4-E!hQ1UjeEyaV`FCewSYrJ_HnPDzsby;4b3 zP?ARPu5a{Sxkl60q?%1`@rDa97xabz;UR5zjG`fF_TKttALN_OQgf$&|H%51>P2?s z;gCqLQV`~>Q&~fgv}>spl=M~@3pAO0W%MS`M#-i$n~;)Kn_ABa)H}aZtyVLK#?(#$ zwcppK9+$4-Ov3R>h3gi@mx-EDmYTf6aAlIh>F=C)% zCD)J1^&Yu?NUjf54bAp{(d-eLJ=V|!ugtWOpgQ|v-VG;4Z!{A?Xyi%3p#y3Wc<_|N zL8Hi+{VBoQvWy56^<5)cfw#3zom@Jt`9|jD#}Yuq84vM=1-e)$J3C4V!|N`0yc7Ux zNT3RMIi|895&WY}%7eUlc^&d$e$8|l`WOHrD$?ZUuMnW}5Ck)SI^V?Poh#NLKCuw3 zgan9iJpId>!>{Xw905}lvXpe0xK?dwwV$>e69?4K8X`Og# zS|N3&&sEM*p(GV|zp7$t%9m98p3gvRZPU%NpO82e%-$uwCq2)>J%0Nv0aDIA1s5iwi^o>W-C()hTSy)TT*jX46`W5UftgF;dV=~Am>^P840ro)A7}H9BX45bJ&S`Kw@*?T|FRiM&z*` zs10q2Bo5<$oJ^=@Zk0+zTcDN@R(hBwW?AAI3K@Z}Faq!HWc5U0UcJs!30Rmn2=?Kd7-LXgzqlloSjrsAyZ>q#k}Lam#|Rqgr^#Ae5hFfH~_ z2XF{)6jVpvNY#*6g>^!IBt?1Dywg>ov#Mjzav~OzbLFsKJN0WI=m&;Dklq)I2D{R< zIfM~^^JAjB$2AXVJDcFzQcRYAI_buGg-MjwD}0WyKdU?gne(OBQ6D(A zUO7G4Li{YPS5Dm!v6D3U5g(^Nc^wssKX7bq%?UoEmB^om3(nl^)wf8@42Oziw14Wp3gGb;2@B#w}l=!p2E{9tfnG%wO(a2P@tKBb2xQQ4$_ z2I4!6h`ma=FzFflXfgur0W2Ogd#IsFhy1ibu`n4H!jzRg#w%f zuUvA*FR`C=8nTe$XE5xoC7RqAIjkI_k$86o8VScnB#*_D>S+yp7G2Ss(HB!$QP)1? z7~W?HzBR#o_=c?sGW5t??Y}4Sh4jIHh3*h09Ee+7tc<6ucondjcXu^^%yhoFYu@!Y`-{NODkqKI={BdWsw zble+c8xcL`qmdEC3ZRZL2~^KhCmjvdHDDc1SM6#=n3WeaJp~l93k#hf8s`FkUVucl z8=@ODHq@apak3ytK1e($KvBG|2Q+bBT+WJ-Q7uZxV+P9Juo$fdl73Y~4TN^DHFULy zI;yIAki4xLk17QcTp~}?t`8XlP9g57fsvrqsit97K?oy97&A2Gkag9VglPO;ASS(} zKs;F@qUbKi?}VTMMMDARmQKlkQVdnKhQe9(bEv85tw+C3x1JcHtu0ZbR!gM{Pmvu( z=XJh5(^PQ2B%~+K-+i@COs(BWXsRuE6D=IZWUbM#5ywn>G~;?eeIn5awmH~SW_=a3!!sEbks}mO#`!QSCz6L*aiup4w>n&jwVMR= zxK-bqpdMhCOVa|$v0B}Kss$*m#n|)`m2)p$0U)d(X{b<&1+GPKhY(4s#y+BdbfU~& z`<^r@@A}uWnRCAyuRfjXRt!p-%NP zBxPfSNO&W-;R6^HRbh}M7P3hB@0D+AtsHxLQbKA~Kzc4y4y24S<(iBF5K>>R2|STk znG{&xJ@?h_5-ERs5fO3R|L_0#f5TY+X1X()sbq%3YK1nsViHBxC$A${%fTT13-Ni_35sT`ZPsVOD514B0-hy z5%z^hUte1n5US1ZAigv0vT=I%vgS!5L!GWNJOpYfd&9SI^^?nOU+3c;+WDkvC={`8rTSqvUxMm~0s51F#=|3@D2Csr6vJG_6oQJ$W$Gh$ zjZPR$oJ1#V8h)%3_6(ougkwYTQIX15_l}Acz1~vOo!s-uG0`^#x=wqTKrnrUY}B@e1ik2Uf^zwk|5qNvo~NcsdsUBq}GscR$pprh~k@?9-@Fj zxxwk3Vd`^bo>wJXO55J1Hvj|c$kp+o!z(a6WX9J4In_mmKU4jl8UjQ##emgNKrH}K zK!<^7Lu=KMqX}1Y(1D|Q&lzk+hmPqGY)?XIs}7B}d6ulP#Ug@LdqVk^ z@Icj&%}<+V5I8rkYN0tCG6A|-{2J=Tg9u`03ayqacd#*EqA-t{Z`fDi^&tUJl%>XE z-&icv_?owgu2Q0O(NF~9xrN`6Wuua0UUF^k5`mh@F(wy>?jPI=PV`Kn>JS9&gi>68 zCBM?+V56Rfu6Un$K6EW}G~n&UM+H-dH8dA@JHz^>%c`k_^wVCF+(Wk)f^DTZ+=&KI_>!_dTZhY_{h zF+$-YKkl3>bnabRTw`k>JPKj9*L*ZMDi+_?y{d+qrca)-(Su+4*>Sab(H?QveSmni zg0h0iLoW=e{)f4g``C^wtV;adjF7|@Bzffi$8kqd_|NaZL(;fd7<;Eq{$@0PZ}JQ- zToeknN;C(v+2n!Ys*T+SUA+Zgj@r2hcM|Se-+zXMI#7spvjOj*o3s zxnNg{MpcR|A#|*zzC3<0uDxFT2^nIV$Gc$=0rk`@D9oD+Jwo~lL<5$QFJB_aVs z`s6v{6%!#-)|7xg2R}U05<+BSYn;Em?W=AT23Fz^e}U$iq}!jo&JHA=Rgmkwr_I5| z>LO``Nc~`WD^*JGTs(~S{$jY?up+3Hjb2j+O;ABqhz?hUvDOsCmla8WMiC7LG&uky zP=HuxfXap+aE{gM^zR#UsyFr%08K9n2gH^X)11>nU^@sTZ@%oa)dVI+3d_qrPR0IZe=+N}SBnliPUxE=n z0F)#pPOBN~y~rMZWw`2peyv`EJ^bE)!%*N*@DD{0(?5$Vk4P-Ym4cRq8a-5rfhMtp zaimUORl`T>lJ@CZD-Tm2*iV z2QpcGF)_UQCu-DcPj|?llYgRT&1cW9X+F(E+VmtaW%6DFvCG|m-Uhz5+&rm#3Rsit zBUeJj=FWN_vZTaM$OeQZB_l&ZQBsPHzwXB5`*H)5@1OT3-`kmd>pzjnx0W{fzN9AK zKe?s1!7u75lW(KE{q?V3$Nu`47~im4U^^TRkZVk85>u3KxWrZ7aMz=RC&1vb02OM7 z5=RxI6rfseCo;c9dG6QCm{=-YCTU4NOPV|#Z)#|}22WBd1X>~?hQ(N9Fj z9;fNp0i|R6oP0gx7mreO>|uF2w)gAMu|0u~wedQcZ}NB@E#n^MT-PU4xlF#OvP4}F znz}^$HE?oYqATZ4Oz!j~@F-t!@)6C8Bs#PF8DmdU^DYyA!2M;$nP=RnJDGp0^yJPd{7!;_t+*sBNMFc@1jiM8vyfoY zl4b^VERRD*Fe%NjC;rX^4O3Tg8yA06;`G#B8Bg5qfzwl)#16Mda(k5h)se%+QNv({ zVFhbmbu$5x?KmK^Esu}&46_9v7 zIL1f$l0wyKE4c${GFVwCWJbQ4RVOPCmtW&eF&kKx`0<(B{Mn;eulM(MT zFVrzc#Cc9E)Zv9XvFF_+u61aPbF~h$wcZ$i!(6R5ywFWt>uh^_vb{ZHTEP6HVc=tN<~@}hxValNoYy!R@gbagDOSCrp+iQ!*&)gFmJ=EHnY z7=bK02;rhw-Xh}F#)8_zByqgM0(61|FR{?zz8Op&MhbDpmf+2`JJc;xD_@iD*s_{` zCO4~VN<-CQNd@Pu0vMYc!&M*c)*tQ)8in@wZnQYF4YW9udwsy|^a1UkNFUHl>jP#~ zA28u+fEK@Kr}P1>@`v;BuX8vbi-+^R#N|ttfwe;-9rQWLJ*zh!q8EAdm$+(Ks$>`~m3sNxsXo(yP>h5}fZb;n7>yJo!v-UI(AJFcv&(cbq<9(yul;GSJ zd2;J(jH=12~#{*~7@l4-F1Tt24A(F%!%_I<=CPQ}3Ia;&@hm2!yFdQOPZ$h098Rp0+tM)GG5o_b;E4fWa*kyJycwmt{gE=akfD?P`yv8x~u zv(MtYcrb8AffFbYp>0DvIQ_(&RY}enje_sdqekwja6;KBcu3#OKLvk(esOLMS zOJqCdz`Hp&M=(&yNl4i}sEwuy8k*DW9ml1y1j@lfUL<`ZKPVl-kS|Qzi2{B1U)j^s z#PnUqy@5yqdWiZ!Ke=D4iM`#GclOd76+L1zmi?XuXO^ezKq!vb247er$L)GalgYU+ zH{e2N_V!bqImp#F^lWo~09inRG@WB`ChgPqW81c~v2ELSHa0fS6>DSLwr$(C?Tz{7 z|I~X|^-T3l&4-zqFMame$M5K?b1vU+<-6n|mPPaLlWD=hX-=sajoD1mr__s&8nhGI z<0!K~p>RlZqPGP|o5LwMMaMZ1CiG7s0b%W;+VidSkFp+1aczlJCSDh`MqU#&fWC_9 z;cKj+_p^HBL|0tW9Pdp3J8uOh1O%H4CD}+V6Jg3V2_I4jFYalB*;eDd#8b)2eKUi!94(eS|&O~mR0?3SS2_ZPh9aTgOh zMM(eR;^1KOQLQt1D!OQHM&p`5fsYI$!AvXb4XXjg_0q>QsNSuZow&jGGY^$|Y zvd)q%A7{xrIRQYJsR^DIt8i_@wfDRH8m(o&c8s>p%tC}UGd^X}u7CT-^ZD*E>l2+9 z&G}|UAVgLf)eT+nn%u#}2lkd=?Xzi}gvhLrW4Z8lGr@6eljzqA!NHNA=5q)i-W}QX zLhGV*WDZM()Uv}j0pSTY((sY8OVZ&Ez#uWt7LtT1?Cu+E>dl)0)w}2SO+^jOMlAeVku)ojZ&irX-8R-J{)KyZf zk3t)T(jexE+C1^Hi=wO*UGYd?W`hY3&P1(f`UN&3Ete@bAHtIjD-;oEL6wm;eXyii z)WyJcMTyF7N(vd~uq`;Fb`M08$5aqmiuYW*bOUf#0oQT}woUI0_f%9MT8|b_s-J9& zm@IjdU%!@(ZyqU(@4dWzk;jaWd6%C5_%r{};*JxrJkp<(cP4(EyI)7Htwfy~#x?7! zdombqlqev;#3414E;W-qyB`bD(C@%R1yvxGtgEP00Ho1-tynh+WoJ9a(;iS-B#8+0 zYXHDF5)`_%>USRwa;ZJbjq7=79^jrLnYT+trlGp{KXg( zQk&Rii*HUI_!G&o@|Ittu+v>$i>`~%#_TfO>U8#4*D>bBv}qbHl(%UP&;0voYzhF% zO3336N+eNiN@3qkHlucpgu#4}9{V0Z&~4(tF{k$Hu!xhS*bGZt?y1Vnf*;Nf2n*;= zp$*q(JW6kc87e7YiE4y0JD;mcc?7DLW`J|dUt*3%b%g;fLIfWb~eFJU#0+DZ=VO#Y5?M>U6>rv_cZ^Y^yG__CZ z-KYEQiIxrgrC76gX@IBL`i7CgG)v70vp$}8_Czc7z11sz>vm;)>o)$WmMTNdH_Hl?v65MeJb=g=jzk>RvqpDLF z(ZnPB==S$nZBaAu%(w`bj3Xcp<+k|OFBD7&(2!@JO;2SHa2UHmpUzcyG|?;qc4)I_ z+yyp!hu_Cyz90Qt6S^m+a=lh$BC;R&QG1;W3?>7W$cwN zSSC1J&GPp^=8IaoJ{HLa{~1jKPnNvVsjk(i9v z5!7lsz=$?Bue?h}W+rHMVpLrP)}a|IC4~oB+fknOv;G|@9LgAh{Z6wOl`SWBuE${} zK7m|`b*u`ti~H4EtSYuV!eTfe>a#M!0@CP(#d9E?Ao8#G9E=p0+LK($1x)g~^sMS_ zGo9h~VPPLLwb?K{{bv#VxZY~L1rn57Of zTuNhJmRC%-#fKk{5x*C(;Ih6W)3$Yqf!H&zluCj)dUO`9uOu0N=9+Fd0x^?h+FP^i zc~6jlN0TIKASocGQjzIA<>dQ#s27lhdn;JMXw6U+!gmDVq%q91vzp8Ndk?Tn$TJg<|t`ElR$Mm!tvB z&LbfBlWo^Y*RE0Lp~zxtm!Q~eZ&rZW7opfh0|=4~os*TX3EJHZ)BZp z)KxhqXnPv7Gj-LFG;uBcAGjr(vNwsN zC^hEqD3VZBY8?t~w%T6X)?%gr@Kfr`d{;l8rIi{iZ)IFoS)nanC1`&f{czbV>qf+c z^RTj^So|t~1TR>&eHT*lw9joa`*ufd1e#Xe=&y@XAd!Q`w;g*?R-SiU6q0VfGXiLO zg_s`e&-ZrX@Qhx;J>`l91Z5vQR6pX4{C>b2!9C-WzkdAjU~umI41WONomldXSeKu0 z?wv;|eC*pw&p0|hcb=$tER81^NHpDxs#fuKXjE-hs9&qmK9?uOS1SN0<8OjDy(B5B zb%GU`vqg=O!v&Nm|6OwfNYZ#eo;~lr&LZUJ6G~U*AN@@(k`@xk0AX1Spkf4^fB1tX zySr}|Z%SxqfN#Pszc~P0kex&;3S*C;;iPCzVj5IEtLWoQ>E`EF0#pkQrGKVb@Q8s% zjeHf6<0?uC6MwVLgcC0ETthA$x#{2Xu)h$qDX2*mKui3UIM5=H3sagByv9XGdllE> z+9{PDr>0>IxR+Pj=LXuWCRcXeqgEE69s>cfr`E7dFSl}{Bp?MSJ&mcl!7!V|kPH}g z!|swB224}X+*jVKF`ON=+*br2OOil0u*m=o=U z;c!j1W=A#Wis1%Kq-mMA`60^0x+OQDPMO5Cn)XpH$7pF~)QWGvunAhCn zCzc!FDt}s=kb>JBT(H&FEI*(6bW3=IHz&2wx z$S0pMeWy+Br1;9Y)0PR*@`u>)vZm?vq25Y8iThH)+G1Sh={!_U;(6-}KoY7r-vZ*Z z9`HgB7k;MMSi(TLN)7W-UK%6f)4{~BlrP0aNMwqK5w>Y89>0;bKOK)8j~JXpUj?J7 zz+8YVK&${?MR~_LhbLb5rSjDR2^TnRUy{|hJ7bM^@q*5*ZsfM1CgVA`4mG<*_yh#r zB_T`9>?xleb#1)sy~p=2+b#|~3w;AQBQCT3mJ5BPR@}RN^Hs4K2m}$upnp0N2>{;{Xuhm5cj4I%sFy;Nh+(ynms{R@x`Pyn`$9%6F42S=smU%z_cTG&|E+mLbWW}hc zZsRY@STR#Dv@4MK!F;=7tcf%eTs^8qmUaO-GVyH2M@|e**jbCpm{|*e4MD-&%ThjT zX3gJui%n)(6IUwn1D-)+?=>=v0UE-;$W_rp7B(1>$Vmvp79R12k?L**hLMs4kw)cl zWLN`l*?m~*c#(0q7s)cRk&Dq+#NplIElP3C5S3eH|1P$OAR5^P;VfL0VN>e~9&7c0*m)djFp)S`8N#=k zEoGu;)j#%Kj}BuTwME$F9esubyB5gZwoOz60VWPmmB-}@@rf!sYAWxd;X-29bQ7Y$ z#<8nXMVM!PwbPW{q$WPIzAib#-E~sea!{8dfE?qKa9k$`7&j@&Y|6g-JAoF%M>}J( z(Ss0U`5RUGfIt^Gi>Pm^sC%36D*?j zQQY>r92$w~V_PM`4-Xx;%GYQzBp4zSr77FAk!wpcVN4_Dl3s8Bpu#q*sJPlmlH9Ja>AjEn5i zHo%FDU_g5>6XP9fflH1t{>~m|DdEY)EnQi2sT*g@=tFKId2oje#*}y#BHvnjgxo)! zZlOi1*;SI&euK5CuD%L!l4!HebGlbOh;oAYWdf`c@QUomme8De+?S#=Lf)H#ODg&A zct?o}>AjKP{8I)fc?A+W%jB|winxWle^r1_E9E9Nd7V|83SaqvLh8EF9#`tX9!-iA z&q#;Tt$^LV!+(AEL!uO({#x7CL0{a~p*wDUccE*2_m5Sexxi0;)40A%r-tj`ow}^z zd-n@a#O|)GZ|iV>Q3@|F+SJ$K)ztU%^v|6dcFihw_d9$bM;*X-3-Eq6$MnLr`lWcC zGdisUqPxy?Qbcz1HQ4!|p%S|T%_VLzXYC^ZJhEwcKft&gea#cMg% z%`zm^YDnIa;stt}Z?#qFqmW3|^A4qK`y&lL#nziQ2To`Vt_9xL8!}F4id&WAOGV`H zUQHA$0$|%3&#uI=^jj1sR9pMtHqHv~>o6ij&sRyo5)a31hUw1)Ef@bcw{-MOJ|N!Y zMt{t)=CD=6X_J;~Txg*g0fnn2F4>s{s>w2ZBYtzDS7 zl47@;ftMShbKoWx%S1v1J~hWVeGDPfcm_=_dsnw_(FZJTAod(zJ-y3q0}xtTob}w? zdF}wv^WB-{9Iopus)z zu{OGn?ca;v^=4&{LQGxU0vf~}W zSw>s~w$Gb`m*{C9$#}JQW(#YJX?b`el0)pSSuU%BZUid{_~Xw207*`20}gr+2d?tf z06S%*RjRN5SR4kyD!3vzK6R-WG2h(Ozd!4_$ygD@JBI&J&4hP(_#9 z(=yDEZAE+4=Y|;`QPh!a+Q+#@6!+YPzbgjASITQuONrLD;oQYOfv7WbMaiA>qrRfp za_A8a#ZPfcm?#7Eh3f*r-#ht)V1|4(zs2}NWZ?N#9!6((t z^%~-GhZi?HqHLFUUYWM5X$apcHW+?1a>Qrg9%M&>dAo#^1!9&r$TJvI@(v z%H*&{?r%Km9smq4rnm1MieB4FaHRPMHanD_1V0HN%NLBA*-U0bOkPk!BwHYC#ZeY^wx7XR1@+Q-cug_k**-xO$lI#x2V`-eMzur z)xTVC@>l|*Ez;Q~_Z1?mR7fSewRTfxD9#CN09u*%!o9eUd>OOIVYXWF2QvGl;`-*Z zI%E)l``xkg*(G53{Ob~KwCa0{FzjvBm!S%zdi$q7!!}lX@3OzzT~yesQc4%58k^=q zsg9dhVbxP=Os$4h5GjOPP|zy`ix3|Zl0dkCHchXzxm+L2A=Rf6yO17k_JWM4?f)P@ z-x$P7APE=324_xec`Ya5mU5a>mRf z%ut_!4Q+^%=)W~rdm8dg;w6oK`%DXRidj*yTSu-R1f|K~g%00Q?(ZO8)Ds_E8`~%{ zw>x^doO-=D{{2ssnEQ8;hoj>k;2vYZ5^I~!-SySRLd(p-hM;YEHHT7@<|D0Pn&525 z-%M+G4{`US;+FnLV`TNU2Rr)x48pKOT>BXobmQCLBlz{D&WuU=bcHaTu|5JF@OD}r zY^2()wowB^ttzzVq5d%tna)?Q_i>cR&>-COR}rnAz++PcSHhp(?G&0D>M|O@Fd29OYW z4E;n8JBf+c-ZK+_UByN;zl%-E*;I|b)h^(#6oo!!(*;V+3I|-8s!ssM!C^tN%|Z4T zu3(P-TmBq#=qxZ@t#2T0aGBxZwUF_vu+pFL1-;!Lmy=zwV}Fx>5jYX<6NihA90@Pm zlnDd5fUkw58J+TEh51dK{i{9+A+)$q4$yP@W z`Hjz%;w>S~FTaHC?ZF*tsvUQAVa{l3EHi6uXoGzwHLAdd^nls~mHmmJG% zHi=QzhP9?5+8Uk&7m~)^DbYqNH6EyqfRh!D^tC^(%nQeJCOlmH_N{LXqhz#v>Gbb&Q)rSQ~d{HY~G=AaiIX>7S|@YSjX6 zKJ=B)p@vLB=!>s|zxZW6O*08(*oOh@DA@*thVwXZ8&jEbY4oyTFKdOIX*zJBX?LF| zQk{Gt_Ok}aXzc`8Cz7^}LIQ&tysm_J9T`|pXe!Rb$o`QEjpnfag&sOcK^QLZ@QU*4 zt@-8-QE{cX-!UY;xvO{zp9B$bWxK@TEuX286jZe73PJqzTZ^gCK6|(KK1&G-hbE}W zsvb`=HpJk{({}-k5w4FklA(px0TNZ51A9nC2u{wG5ETN@U5@%taR`*?_w%5)`Fz zoUiX$X5j>2zQh?6G@hW~EX2b_YZ(+3pQfxcb<2N>S>htjaPGfx%|u!RihL8bM!}%% zL#+xkuxT0Of>rp2do&nGVIu#^l_FaHB(Iao#;x|OeRpW7&ie}9Q`c(({3Mh=o9Q># z{N9y$Uo4*Q2_bKQfveCCNO<_iocRrab?NtXDu4m;{iZw`*HC~J&9DOIyr%*p+KZ(( zPa>D*eMVL8N{i^dYmVn9S~QvT*sLrzTBcD`EdfBN@-Iy4Pn{I{OZ;lfZiBjd1Y`bJr<48EEp~X1z(%c$3>k*yeCL zBk)&JT8kD#wVrC^S?pmVN706Bx>OXB41 ziF=+^g_Uz&36qD;++2$V!Nf=ZS;2#8{OiOU|IJPp)E$*k`+G1ac_RK%AeO+~`|Irx zSqL@iY^vF!vK=Kjb2zR0Met0oUQFe$Isy!VM*h;eZwvAaGNniWvaV1n_sQcHa%)oAHhX|!ZxIF zVIc0r7z79Y57NZnO~up=Vgxx&{-s&iDd77qDTnA!=YJ3v(JvP^U=0MP8q;h6Lq+dA zu3`T!{k4M86bOlAv+ZHm-N5Xz!Z*Kk@ToUQFLA?fx>12VT`hbKO&a|ns`(8 zvw*vx9@;$?u~?8tS>EU z7+4y@<9cO4pD%JsuS6pi_FJ2;)1>_gK?W1V(ajG?B&^Z$1w^xS1`L`Y%2)Llk-H4t zP5lAo+!{sH^q(%S6KRNaftH!fMpryTwM~Tz%1}VU(51Tq-IpPmo^8 zS3Ng?%^9#Cq=ZP!uL2hJCaeD&bPfC{h_NDzJa#^OSyfMh{ZnK?b)SW*;QBt^#}KIf{}XKDBT{ zj0p;I|1a$X5mvy*{}}uI52gvvDmF^2IzR%_SUd5EV?_~7^yO(<3}WdWmaDnCSCuAA zma4-H*~NYgk)KD=jROY`3&R3lsK;RUrvZxu+ZXQB-k`YiztK}*L|);Cl@u~MWJ-WW zcAu^~)o!%`Fofvl?$5g(@?^wJntet+W8XA61U~YO72Sb`5ZO)JLI|S-(urssXGnt7 z*zf=kNkN$u{&ovTYag?WWJBt%PJ|m8QI%(lwO1_1LJ4&h1{ttAz|DU#u?MCw6MrzCh_7K>xamf^0axd48ZI|gdhge2bQUjM za!bS{F7c|JYJ{T((8O=7=AE?bwu4@+cK4JPxsISLxLl)h=8n&fQO}7bGcV+IzZrhI zlODRa(N%@T*0xGQz36S@NrEXg9NKBSDeO^&adY=V&kh{L zv(>{|Oz4?#qXrGWxJV+nf-Z_N$zMFkK@7KG20}kFGj=mF0h>*r)|H6!fzE88D*0Ym zVCHp^Ilc-40`9GmH&}?#7BCz+!B~VN-#2De^wF$1LcSm2*cd&7Z+k!*?XyLPUaLDi z%p--%3xUvpn_`QLMdo5tA$6oKSS(#*L39k4wGa`$zAjkguAF4IA8$-j$ znYbw^YRD?wh>N+@`$wGGq6G2#yc-||@$>bp@HU9H6m2gQ2DC228d6Rz)fzG?J* z)fvxHB2fP0^xOlTf1A)hAVkJTfm(nN zFS-7&Q}W(~y#3>2zO*2=exEeumQ)Uv1^7AzmYjwW^e3@kE9ygENf)SWGW6?MK>s-N z(W}eaz?wF#lHZl|%D-^rLSc2+I>M#;+8J7hk7amBbSbjHe!|*3qpk`@Vdb^eJJ@!G z$J!+R>^S)e$o9w+jp{5eM8;g+nSXv!3y>Fit#wyHtPWK26_60Byur@M@gQ7uSRl4Blo%L=s^OV=Gqa?5ABzMAu!B zWQA;mgc5xBbs>%i%RpWN${73IJNR^e{FW0rO&&@q!XFS#!xDXM<3)Smyq$LOAnub` z{@LCAb}i$0WIB(yTX0b(yzx>U{J;@tdsi3ubR*^DXSL>y>ajieWXe!M z?}qORpZ=++gH&PTMYg}C!XeOh!K76suLZ?euT{tdQ(SB12e4?_4JcqNm#t0-`BcIrk8C!ku?AG9o721$> zCcZ)MNt_P4e!M6FH#jyG%(Py{EeSM*kow2>un8%_@=D~4rQmbh#ae6se3a7*sY60&ykUw8J2Eqw2(z{4 zzve*132wEC6}iCK(MwS{djaHVe1!m$0Wi*Hj01n~lyY`tD*%YwB=F0|3vLsY$CVeW zwDG&n3ens6v!(2IWotLvVV2wj6>i;n<(6`x>Z|!j=M3SXILs2Mavaxe;*v`_ZqK+Y z-R_t$$l{Eqq$hb9!M*ZZF?w=|&Kmp46uKx}Rw6K7z>l={aqhw;fEp|~0K|_#3Bu4; z)rsj6C*3!e65!+z1F7$4iT4iG0VYS&?9UmXhF;l>xaa}n5gg9Mlg*P#EfdA#+hXv0 zd<;q3Vz1Yti$RZ*Io-SnR!6)+soh~E3_k)*>=rK{#(7RgQVGnQP%Q2Rf*NMrx*cdv zcozRIC!lb`p8T33BK~g9h(isb-^V>VmU99Px+vpv{MT&8|3-glnxCUa{qg-5zC zfr1G2ROvVSZ-h$$N=%DngE2<-$HYrq?ysDZUm1*&6W;*OeL3f)e|S_61fsaO1DeA? z)=RF5s04Du+MJR!9|6vCoSIxz{!8a*=kIJFTSG4-K`QapB|W>_A1Z*)#+c;BQ!kl8?maWY)PI#CZGYSe zAY^+Jhfsw5b$wB|SNdaQk{t?_kyG(I`aDdoxqgShVaW7<#ABHcqtB1=ihe08q6M^@ z@FNdoIED1u4<_d9AVGOQB}Cc(8~ZgzyOSs#9H+$ulIes_ES~8E%XEvk>i3cn`wTb~ z7jBRd4FTw9NSM7b^&m8Om<|q67zC`jriea{+k5DY zlC~m#h%Gj542+PLhR(h%?s&KVAMlOeE$GerApCKS|4kQ=5mO5r{mKfHwvCgTn`#wR zn-nR7aA6qv*?YISzxQJO=>X{brHfpFAx?bVVUuNgtdcpP(2s@5;P)Ym=JtB@M*pp~ zdITp;Bmw!d8`P!CGC>Mq)~*6^rM283paCMV2z@(X4)UQ$xmzN|h z+HiiZF{BtCUQVi;6bqGgYiag@2oWa^J_e#Rbrqj0Jf=EaQlCxmo*RI+3;x`zrEJ*$ z?uN?uWf6FKHzELHc)OenaZO<3exLG?IsdlIhPBP((9-v}Rl)^|=9 z$DAFi%!atVSn>Hw;55SAAvEUIOkLKXTJlkIl4{B3S6A(7d>C>mkOx&-)7J)Pi(Bi``TQGCPX>`phTyKW8JQSPq)+!i|0jS2f{0ks7y?1>fiU(jjCW?NK@U~H*aEz{ zE>*j4^=|u3=}_UXAF_p+hoRXYF)V~+Y0If=oIJ!z85~#194-22lFAK)K~!kg{ zwPe~BHBKKew(KO%a2twqi-T3HJHIu`)Y`9b{&?*znSkgQjm+i2GT+podV{-P>1ZUO+H8m@j6c zDNjT?uXRKo)#5ULh8d$0=@i!Fq9oSg-2@RPMBC?-#B1>}m5P6}UzYKlV~Hfy0#oX8 z5Xr~CPP{J<3j|(h>4j0efJ}gqF@isK_7Tb)XO%6yUK)!eJDYi|jc)SgFrG-gjx*dC zJqzS_RRovmf}bG0B@;KQRDq7Rd}KAtYcWkofubze5w%w_uh~t6rT$PU;?#qWD`TRe zmK*9XYnQ==wxzQt_jV=Mb`h1R$&RS{S5b9g9BnR_Q=g5^D)cmLb*fx5e56bA`aDARTMO8Tqg;E0=3)Tp@$@t5C>dZ$WCwU@s!IBeqR0BlxR5 z&;7~+ceqllUt5cl;k7)-F@e9lttQMdfn(>BWKH4*dF!=2@(Q3UdQzTA7aREIU#U6 zh48_5O$b27cWUd$THb~9!3~?I+^^AubUymx1nX~Bmt%tcqM!$%f5yzozO<{u06JT! zYbjOH{2A|#5y60iWDIH@1VN zRp=iB0o%rqerrGiF8{r9cn_p-hW(_kP{)xX+W4$@j0Yf!^A%5-MV`Qw|Jdzivnz!h z*4c5ZJ1XPA+3&_SUm{BB)C1YzCnlOOFUOEcXZ__`uu5xx2|NR4moPbiqvhI1TTD5- z1lAnD#;4?2**I?r>n*^HmlgJmd`!Ixn=LY5bw;f!#Da%F&cc^{yN%957!;ef{u(yv zxeZO)zzv|BmL)ks(bW@<6~TsGxx0ldcT?h?TEp-4B{R$w7ZC~{6=c3%V0hIdrr{?5 zOr+n*ekqf$%%J) zd?c1hPZT=QU51hWGj2twn>XaZI*pPXP8wc#*at{7A9ZgVRgMl$v?V@5owI@oIKON* zeCsvlw@!KQJVKEDW2YCWo7h$;_0f?0dq;yBO5xo1H)y>#P`5@Rz6zCT$mQk>I^8HZ zqxAHrF*qs`(@2@fMqXvE!KtRf+}H)!|tUP+%n|KBm6R?8^fO!g@z7-kKoH{FKk$=dVT_e z)kOhbxVI0Z*t(AE74`r#*!P}3sC3sPY@r*BM}B56Ea99ZI67n2!Y`ZDc>PHaSBEjn zynjt*|41Nqj6M1Tb%lYj_KO(?cMD{qn4$q>(%pJ(G;DWu1I@BU+9Hq8d{IiOvuy}= zdl-_kc8LyFZPk*vo}R@ij>!2A4n2)wADU_j>DV>r7=AgROVAvpniO!f50X+L;!KG? zc_hL5FkZ^72pGOV9>=+qOR5mX5|*;eh;_L8@-LxL*G+c7%}nWNPq!Q z;%@DipZ9hGetlyUu2eJZ?LC4Aj3G;U`DMvkZP5Z74k(ip-Xg$<2f* zltfbC;|UQ}nxf;x>AQscfcbZJQr7~PhaZID4evD0cQtGs;en*(P59%Sg(omNM5`lV zUqE^J#cNHvd5j1zz_gu%*e_eZpN#?Z4-U@e>X|Yi%Ngwy`$J1`q3jklLz?{qiYGU&EqpFn4>7<>d#3GHnrV_b2F?=AdADF`^g9w z(~S}7VD@1U5=jes>Pnt1p`XPP%ZqW7^g8eEn`%q)Rh3?6fiKM z{JHvmJ-_RS%;V{LT|2E=p>IbOx4rLb=o6A2#cNr~FR@=6ymOhjPzVSTS89^D%UJBL z9~+9gueg7pG1(QpX-|9ncUz-raY8eR>6||}5D%la=~b3QAW=1#;0JWPyT2%CG;9-N zqsD`S3sGCR6U4ypP`gk^o{)fdhLXXFl9 zLAS)Rn!B_M`fvRA(6E>f(r*k%FZHmc!BwdUs0^tx zp6%JJ4NfvBev4cE<2`^Dn5|M++Q7iTt_B;3Bn@)${>mh^8N!z$DU=jIzFJ0be;>&^ z?DaWTO-w!B&*J#X9VjX%v#d=A0!VulInk?zSOW2rS{*d1I>LagJ%f-?$Xf_;JHj)R zLW!Hx3`iPs0#5L3_her1_N_TYcp+5O`R5RcpxPc#F`&!s0MM_}Bq_yAGNP3Y=>}cGaq@AIrhB;o)5W_PGrinilPQ86WYm7V-Ja-_Is}!ZS{-|b z#x(|A5o|#KlOKeLUreS8!b{i{nM8<{ z=At)py`3Ye1!>mscY|)Wcv$1u%>jF0wY<1eGNztr#-#@i4O+W9hCH^b^j`mbw1+va?~}n_V3k&j z>3DwIcPmW9vzU4;gn+4Tp>H&g82IE2*MZu4ER?RK%rYLQKX#cVWLCOT{2T6>o+kGY z^1hC%icVd;TrhzPM9D~IXIXpI6MpicA%3R-L|a3yR+!X~Hu$79Hc+rm`h~jex6mXc zU(sk{mNB_ne_9SNPV=G0BIm?FIKR1DO}_RKXxGwX&8d(MA=-s?S&R-$Fn&0S<|6en z5BNHb^)yTe6fyxv`Z}2dknNu&G3)BF8z%(*8ctcE%02W!0y%|Ec0A(rxyPD|vwA83 z48^$xRd}|sxXcPsU1)bRL91lRJfxTGV@Ijw8e=dDsRqK!TzZ+gT8^r!Jv||$d7yvw zD-pU$qW}%F(oyX3sB2W^Kd#%KrPq-aTcU1tku^)f0$u0d!8)r;6LhN~#di4dqQ9ts zj=0o(+t6D;>~8_h&x-%aD)86^VoAdSRK>cR1p*R-&I+2xo7~KGIf_kS+e}PoeZj<% z9l5!OOeiBAVlOfe8C!hm9-ADAO~bKDOmCg7vhe3tBS=_wJPD{R{~;^SKji=+@t^Xt z2)^X%ffDg%SWpYPry%H#gR|q+_`8`p%si7(AAs`)b-gA^3x(TK#(ebq?m)-`2D443 zdQawp&wl%%tr#4xDv3fA2N>nR2bF{F5uy1bQJ$JuBn4y~4ciA7wt`W=>aD6l?MM zOhu+0Ae@icwcFA2U#twc-4tCO7@BZ(cW5J=$SW1n-fj>guG0et5l98dq9f-G`RP6g zNVzjZEM~$h4-X8Ei6kWj?Un;&^E-FeWt@$#2q}I`0BJpU(g27q^nv`AYVp_>ouz|t zS1wdri6yytk$ae_MrvFpJ7{qZvnA@>Q2Zq`UNr2Kh$Rx=|UuOE1MZ>3@FGnX3zLXgs|D zrGw?ZTp2%0#w!JR{z8kBFtdPnc z4`Lek{{W3Za=(^(`$2Upfp7wKl#XmoARK`W7%qdt8SOk?3YUMCz(pW|E4rEf1H2xY zOvwfjUC$~xMSgs%shSRzm5JM&v0Rch(RY6Z;1z2afeZqQ5TMmDQi!}z;(FL~$~+fk zMPi9W_@9p{AloM5X(?&c-4S=7h*8g%$|boFnh1)+86JlE$nk6m!&N|8L@RQ{1arvz4C- z&n{zT&2T_1p>G{Kniw0+CQ;Y+M&{Lxs_EgxnqhT8q|golNt`uRO%L$zb0@&Is+_VX zVz1J(iv}G%R~l$Ru;dK@kwsK@k`N3GAcKTp;B+bp!vIJcWmM8+kk_0Bh>-Mzu{|43 z@YFJTqf~#HszzpSE;qmI4RdUsm#}%B6hr#Fi!4&YMUKDo7<+&mRYNj%z*~-e9V0oA z4ebXUV`Lmd^7EY^OiPF8w8TeepWv4POo^YMlQ=2%B3UYirzcBB1|QjnGHfRVR&|g> zh>}vJQX`!;g#oM)vI{I+Wfmd+piFZ|Ae75G1zvoY9V8vx9{%EAISXGAN`N7n3 z6*QW=?yqFK5vw8Wx_c8myf&1P<%U>FviWzVC@F_HGi7FEM|Ti!&5< z!P|cqvDvka2=VHI7%6leGVo8)g{wDt7UP88tiEwV?`la}XtPK&PPzK5LJ3Y)r7~4G z|B_LNOB7w1D#tI{_$O)OdpCa_ZG7*(W?RDcJ0H1VvqdYpfqV*d^5an@CFPhBVSz}_X(d5xGW1YFeI z)bbK8(D0puT{{H*iSP-&aE%F9Jf*iV{Y|Av^qI*GMAaD6B;|A@*OfYwJE9}GCOVQq zP3J&X^+13bEQ_!?V@~Y5kr2=lP!Ek3fhpY00dD{RHI#i)9VF8#30b)$&?ty43+;bM zN~_aCLizX11#>bma&n)BXsfFrfD`239B)jR_>5;u7^yeDSaJ z#;?1l$KXuYI2<)Bl5rl=a&RNGrnmuANMH@4hQ%P2Q`X%HqYyQmh*oihS$t%>afL^I zfRpN=EU3`;untg^gbGUfMTsJ5x0ru_Kt;c3jid%%8|l_=fE)Mzyb;dX!>#3!Q=C>_ zEN(}M5p|w0QY%vUDIf2$;%O1m;$zh7OE|N^at}-2V{=cq3*V!|!WcB#O2(m4{}|Zk zgi9l`Zxo6m@wwT%m108<%{d4=M&_KzDRRkJ;Jk@xL!y~!L!zsk7;L0607!oW1I-`7 zN}g7_5&C+7?fDSPnLo@Wmw%7=(+;M^p8FRX8dsLxJ5c><&puY>>!hBfcN@X5D3b`z}w~wNssqWa|<+-|=`1OISaN_it z`1fVrel1^8*;00(@usphEpLCTDYnX6hL!ZB(SB+-=n2AmQOeQ@tTij1XwHER9Kh+2 zo?}+X4^F+Y$B!r6fXz#3WOBq=-o1FlftN;Im&>mmo~I1Q6KC=nMy=q5?Tpl??3OYk ziD%g}+k&&~;~Z!ODBf`n$VU)?$>W3M!-9a>f`Z>Ac&(97iuBL!-KGzG9@L#tF$PIvaWz^9qAI9wrY&1 z6BkEwYA7|Ze?-8ab`j%)e#BLcQD1KrDkm1lz@rdD+b4KIsJc<}6$*+GW#A#^BG$z@LgVVFw z;7lqafXrwFkgNhk)ZI*lNdPh#?j9jxh!tniw|cwJFTy!WMGd=5)S#eJiNlF?4>pNX zkwaeGkTH&+uTt9)`uj`ziSREOliLzOhhV;$6=7t^4T~`^o0fc z{hOG0Dw9c9N|Dr`T&K*Txz`uFiO6a+EXGyyxrML-d<9T-3_V#qBu=>D6bx_npGPHg z{0NoI$)8~hbo$)3KqqxHUNmR%yk2~wEmt3!kt2U4(E3RMGFKMZg5efxMgrXyC{2hnw{qkY^wPM&9qgOU=sPW^- z4~E!iuqboM5Lxn!$s%OgX!hd3%Ip2N8rff$kL-Uh6(dX8=A{dAC{0$nAf=`LTMgSU zl@h2=L<03ANTBvK)cc+M{DYX%{6?PNljnbu=U>V5&*b?R^8AkyXTpzta3*wY>XpnL zkv-90xzZ~+xKVqbn1CD{VvU7k1ISnnSLNPk;;Q_6(N($kDREUsL!R!p>U1NX?w{4^ zY@UDa=gM^7!$o?AuFw>X(T%Cj%-(6i+QXwv2TEicy$?B?cTr+4vw3d}Mc?HnY9rK1 zeV46*@3KwfanO5D6itizfjCB%mRiwgotpi`so4WEby(`uECdZ%avy7{`*Xp=x!x75 z7?J4JOsw5#rFm!OoV#))xF7qeyK?Gp+)00YyAyxoFzqxFQgq7wjZ+OlnR@}cH`S}B zEs=S$MCS4(GA~;q!?Gpvi20w_nSUuMQ8nvT#Dr|Fg9PdJ+fVlVsgr$GI@!0TI(_cR zwx4UVrPp-TWLI6(vdJE%(82#kvpp@H?MqV~%VwL+HJX2i(|@F@sxO;uM5#@%1n_@L zr#(!j-7!_G;*59rv^u(+%1!1yEY5o+VXJ_vlN`Vz#L>W+Vt*bgqz|$NQ$5oQbn-m+xU5r zBdQ}rAAIUH2+nU~Ie-HJmad5;z0!gPth6Y8gH{vMcfGQ$9|nVy<>9Oqu-%FDNfgaK zo*wNaPsSra7M3>U*R$FUxeaME$X_|ULi_pEKb@4zZs#3Ej(r<5Y2jsRumOK>^OhQ^ z_=>EJl)2>z7*ETlfc_u@ky>G}0z&NBea~gEWkf|MVT3!CjBuB5wH?CMu0MMFEsYxT zXj6-?#h0hi?4O9V-fN--bXNjH-CKM91-F?lxV2K@IIOXvI0t(17;(6`QrYX`lKzg; zn$5~ZxiSLnI#yG`-;Kq$Njpt%U4g-%-xklVT_*%zS^kP66aD*kOMS z<#<=g8b9`&y#F@`p#d+)~9b}Zc(y69v;}#KRon9{@{qVK7Ie$ z?_SoDI<`J+Fa0;z`mnBwi*KG>!F^vw6o;IIIHkCx)x>c%Nu1Ixk0pZp^D6qHKLq*$ zx}u@J`yFGO_D7G4ZQ6gg3$ac6ws1_chVZziFh1ad!mgwX8ius*s*y%Rk@hF06h4bN zYK^HgEIdFoD`H_C`H|%!OVncdX5V^hxY5KtVkMHHe_V{jV6*ItgG;{zrKRNq*aMkVC(wOH3Q~U~Jy|Dp62c``CtV-5 zy3}Gl*y6nfG3t=r%tfE1TBEWkCpN*|?QCXwfVQa|`*boJBcQ)w=?rsjfTd1=eT)|1 z>_@gSq33Z-qQw{IF`~;nX%TUK8v1iDG8_Whbb^Bu@LmeUU;P=yTsRLd5bSKjd)-P_ zCP|))naQQYq(^@{ki|@?jQV z3b1Uii2xpgWd``>HPolX2*|D_$sq|#Uf|gKv*)K8uF~6ZR>`r4>W}_t6ynHe9C{II z{OCI1qy#@QJbb9~WGp>uu#_~1z}qw6ZwVJKzk>_h{1ksj7I4R63FPQs&cFAsD(}}R zxnBWsy+71Ye_Z6>oi7B+eP#tAKJ+3LL#!KBAycb8JSZ&%wVGf_QAh!203>KOX_5eB z0sU!47Qn_(jb693zj=s`pckV|NIVt@@3jx?R!rh+Q(=K+28po1Hv=Xt;FS1InWVt* zcgp1heyo2PPT_lhLizd7aOkDX(cI~-jS#<<4G)o-Nz(DTqjxogYz9^y^>3am@t^2H zSS9O!gouCRE8(vD<5Wk`zn9Zzch90Bs1$Gy?!3kaE1WFT2~4bTQeUWEt&8{`dWbsp zJ_Yu~EcW8WL%WqtJ^(KqWTFfzMQLwyUrzS@7XxC_D zz+YBdk;X#&6TM_g2_A37q9iZES@k-M1PPsQ3tOry3QLbWe>? zE7W;v-8MepJ86wmE>N7{yRWZl--@j2YKRF$j*Po~elqSdCF5@MLXCrHG6*a$q%QUa zAMJna=ft|UQmz5Lrcbb$=@XyeRx0h{q)oLz~^89 zBoy3bB?WgtD7Z@^Avt^G4gCB{Kt-GahNOWBL; z3RHiD)sj^X;%o|gA36C*)+5cTELnv>VYNE;-HQ^TV?AQ&^V%ZuNCvuFZdV z%Dtc7_UVnzuW9Lpo;&s`L00+%WCi-Bp}rhpMS7GG6@VkE07Sw6^J1#hz2nK{?nwl^ z?9fF~@mrm`{xl(cB1)(s2Y-wZo-mYkWbl5SRFoU9k&y7tOGNeRl8Y{pg>l0K(=?mk zQKr8hBjvL{Ckk%w|NFoHZ^V(B3HE=Xc+xlSF~KFP-GLlBU{tOc=##q`6DYvw2|9sd z8?u7JjLN`~stj69)LuhtP1I^Onf4&4sXY(}sfH54S*k?9^$HIPMGI2n$O^`oNftn0 z43$2!Vq*XKuejs%ircTrIn+^6W4A2XJ7Kh`&6 zd-vaC#`cbxv0>BGCsP}iEIEJh|B#qx5$*-(Di$td;LnU^Hd@76K3WAxJl>nt;RpI3 zMEj{GF`o)dkH9LK9tAuiDAXkfWjSZ{L``NuVkV#B5RP#vdFlXNf$YEn`?jQJ8BV1# zwH!|&kN{cg&BQT7)LqOh8}1Mo&p;AxEokY#oiO&T2I4Q9r5M$}P=bH;g2&n$iNNRP zpzI!z6+k%tP$oC}qpFxp?l%VcduU6Fu{LTHa}_xD7|U95wO*$cfG<3j-#?;gmpuH4emNo!AJ8HF^a<_%gFO6-hHuHk03G$oLk~r3 z zdg}VdR;R6P176<4gBpNyx27K+U!I)y-=7|wotcW`!Gat^s2&A5IzvvsJUrg(_uyf# zfBf$7w6{Ar>>r<*3Ij;KbiAQIg@+*p?Y8LT2qo@2V3-R|L$=x}#beWXTerl@~>JUAP$qGAorb%%dPV8vlbyGiLsiCa*l_JOF4HJz?> zas5CnHNJ%SaodELX>=X3GlGjnllSM%3*9F6Z`vYKcU3K+af>PRFCh$2u6eZX6)&Hk z6V-wF^I88`C;AOlQZ2D}(r5E4*BSnT@4<-0g~noYU;bW0;%m!w{oB0&+c2M&8|ouJ zIIw@j!NJ-B{HDx(6_YSU8cK1~tQ%(x7Z}U|FF{*aE)F79+4JWv&~{P7qOhfDqDDBs z3h%=RPaBR$!rxtiY7_^0qX%@{6=u;~0bb{<;Rg-ZA6o9j4tHW}pD=GIgk09`p^b*7qleDe zvp~v?T+;#JWblE&l%f%xWlB{#qk9$LHNX}Lk<7-i8fu8_15bxPh_}R86q;citCohc z?J$mkEla95j@6-t()x{Kl|+u(PP}Yy@f8&8!PYlN-)NsVF)RoP#SZ@z^>PIt-&jR2cp}AD;Z^q}oq)PnC^L z#Ll3Iok0tlkgr0x(4r+hP1?3EwC$tgMVkT}U`0MK(@5%DJ)BsaC*yy}~Oy?Qf7 z%4S9RgA zU0tpIUgt2DpMG?&iU(jM9)RgMol-9B&py)mGEX+tO*=V)^ea4eykGGBDIR}2VH6Mv zpSp<451+-XV$$-54hQ8dIJO3q8{tA4428Y&;|}F+moAy})#n@6p!d-z|L}9ILjm8u}KH1Aiy|QJ-zT&a=LrDi$_ZXsb&Wgu!qA*el!De zBuma;Hcr3b`$iySXi!w_2KIkQB=O$6-OJOH!~KTk+3ZLE^zi-RaRYldPT+gQ)H5-? zXjlPmggDawDca*W z^s|3;I`=+NI6=v#RKIA*QLlMxq`h&FY)z!SanyktB)$1#83ssl$?niQ*1+mOmEMQb za2!)EGQIfUr(;AN2$X-1Cuawz1CXahI|?6=)PhDciZ3I2e&5CPRgbNGl@LIt1^PnX3Xu=sT*l8_QtG`B?vOhJDNmxRVhC|vVOtq@tF z5ZP#g2n0UQa+$+79w+$5;~c&*h=~Dnn(Dd8A#b|+=cfMdV6gY$^6kgNqy5Xn<9Gc_ zwlEI%QJ{fYnc74n{a8~89xp&3BS#Q)t1L(@=ynV6FdSl;81Y*mp}L4 zUY>qDK2!L>yVv_9fc)v)3x%Kb6b@0SYMQ#Bfo6^Kfa@(U5Q{hP7LWXZ!lT59=xi&s z%|sLY1>LmC!#l1LPSnBasp%vNlod6rr_zdo@jc4}S_~wU4XZ({P#RX)u#zK2p`&A& z%A1ffT%msgC!g>uOh&E&=DKuy6IJ21L#G8O`H2(i*32;@`j}yHWkc_A%9@}ULY6Gw zCm|O+o*mQp!nDG$4nJQ=^T(dT}kwvreaT%44 z%NR$5;0vXT$MI}@ms>g{`J|Ul(6?k@fEaY>GnrxPY90y`f((ZK5h)s1e zWwuspC)hQ2!bB5WnTXD+N(GkeVdYgnZZohR_!Cu~$Mq_D18k%k-79qr8d|WqRs0 z=gC%4ps5)G{^onk{5_p{ViAXKg~Q<<4hMgT(sgK4n>PrlQMw#%mRwDon=0FkGd~2f ze?co0wj+Ef-DkIGr77->gYPjyXLN*If2;^9xxxq>RGpJY{&Yac4 zgN#GS_ZY)nI)+q^cgclg3OXtu&3-vyBau(m8!V|XPM&o(kJ5bk@ym|#E^Fd!UcTjb z#UbAN9z%S{iATq^FCA~>D`>xbboWX}m+VQ|I)z@nKNzTox%2(_d-Ucc*Yx8GGMBTb za8vKA{JWN?f(Z!>Y217oN@$XAv;2QIH#yPZ^L73+ITgsKUj7r@P2|gE{tI9K0WD=Wmz;v?437xE=kPc`(8Jf5hhT8vtqt<5Ta@;Aap z+9Dgd(cbEUV8l~9?M`c5Beuqyo%PNpwKd-Aw!n6l+Zu}u5nn3moZI19A!vU(M4iy8-TXM(+Y-u6D#cBdd!>jo*LPJ%y4y8#pl6= z>754`JTg-Q$6ATJfO26nN0*u9;wa+sEVYRe1ue50UvTrM#TBuk-1A*OFq9wO9_;Pz zuPaDdH3*uAVl2QtcN_o+2~B?#5gC*3>9-Rn!bqO~%D+3CShjy_D9uKDcGu|6?i$TT zFut8Ne({IS!SrIBP~X2 zYn}C~t7bs1nqk#dlinp(dY4##?YqP`WjBT8Ia4bF{WE!hh`LHRbG$}3Y`{(cHJ3+% z)&e?%^1s*keiT?!95x`8Vk`h1`2SIi1@Vs>`N0&hK8W9CXT53TF&q-HhC=B+2!kO3 z$+>mxXhIhK1UrA@NrZ@ph8vNk&zE)x8D@@$=4{ujm}a=T8kVgj#hH#3vdPJl3^hiC!ilE6XEIgHv7-`+*D@>s5+l zN7gv2g)Dz^zPNqy+)iX#JCSMeLX3d?qFr`~2bjf+(vYias-?p`ARk;a1bKADA`P=Z zZxf>M{e5l)G|*~cO{XY7$&GpC+xP9{x^%n=4xC6qIn10Gr56$SKF)YaY^Dj>9(|1{gi%YCdiRc;*Lyl|*|xHm4b} zXA*z@q~N`@1NU|^T|2_Fipi*l;5m|WR;JFb8GovL2)R~()N7Jfu`VoIRlNn<%$Bo?Z@O~wIDkMn05SI;d>;Cvf zQ_nQ@KqIU9&b*G%R=2rT;}ZR{^zK~S+Mrh_zX##+1OWxTJJ~e~cW0;BTyIiOU3R0w z?YZ7uYd7Kc^wiGQW~-~A36#3gZf=1d&{K)8wuY`qg0-fGrtp2Ov#z0WdUxND8+m_B zdw6ep`s|gmHCnefJ8eAL+Q6ILtvyruqQgs)UNW zC&U^B<%3hO(VsD=R7z)UUy8Q`CFyQdP50*0D;#jzE`38!$^-Lqn<^2*@NbGi9XY3iu5PN?S!I!DY zU%7;5PcfX@1@?}l1J;R42=hg7PU=`f8SMcsN{|3LX*?pHXGRp#DFVM)zck&1M$Vhj z$a&Lchr5EOmgABzfvc+yAT|rImKsuKRv6y;fz49P@+sn2u=;=kVPD`Iu+XPG4_GGZ z;rt3rIi0b0=&1`*rQso7wlRMJ3B--SAl{pp>iU3lyan-y=%Iuz6Z(jQl-(^P;-e51rgn!AXA^<^GL&gec_9LR#Tav0%hn7$K4b$XIp1kVbVfoC;Q zI5pNGnnxG8W21xaT%#@HL>Uro{=+cK(cb97wksB+fWS%t3ilHn-XMPxT4^HRJ0p{0 zj7u6Ug$CQK(Yy9z3am3+?aYuTySbS205O7StqFMJ->zU+A`_Ub0auz(X8?DEE(IRr zvK*$jM#C7(CtDJWz;Z(3ua{{)*%+~Otwefb4k5(v1H_N28i zB57=coj{0UXDA2s7d?Mp4aM_=spTq&I^BC|7|f~4GHUGLPRATcG#sP3>;6jC#7fOI zQPJY$P~?q1NnQ{QfsnwONB$l|MH1i3`!~t-FG>A;U98xkg+sA=#}>a5`5PS{dLJlh zFA`-HQg*4w-R_VePt*N$Uu4y*mMs;}!5x2=XtZLa!2JXADaU`)bzRXIG#NUPkv9DH zF*0|L<9q47lt&N9r6V5a*hZCdf*7m|5*fe=x>Fb8U1`kpqm5Y8)MLsxf1&8NDS(=v z5%KM7DtO4E)_P~HQ$u?20R(GmX#hb9?|Cv9+e&t9Iu>BwqW8P0XL0zWO&m= zbjEQ}JcPaZl(K&Su+%7A;5_+#8#obrjx__HM;E4t1eR|2IL@CkXd?f=BmOWJF$y?s z50N4F$ z9$}KXpEU}SzIk!pMxL)qwg94?2&Q^To#9S7T>7%C;PGX+Z0v~pS7By6ZBe#8yk+Hc zhe(DlZlj4g1nt{`oj8eJfuPDDU!OrhY*9zTp|tb61;~{|+nDZ+rnpg>7Y4Y@6|%O3 zGzlmUhgN@zh)SRNjfE9Z1cp3CirHe&m74T5%7L^bnB@8|u*c9yC1Zn;r=dkUDl{gM zv?6ejGU&<{Ml@S+AQT+bEtvQq8RbJjzf)h!(wZHiW+$zgnY@G#52Ovb;7K^x` zEk7;bB|SFiOX??W3LevhkURKhhy7*!!#+V7fjzfF|L7$8SNN+FP1Jz*Oxw9v$JAg1 zu|WV4=-i85wPMYX=On$BH2o;x)`*~u@mFW>AU zJN*V18K;_!1h;OVpLLNB6t?0ZQLxULJy;iV)k z>zC|pKD8kJ%w`Zi$nr?4NM0*{NFAB}!-MMc(J4a8rCG(d3L2Gw5*E@YZ5v4e_|o*^ zTS@9d`Puhkj*ln%lJ<*lC8-PLXW!EtBD`O^dgyO41#MfJf?NA^}o&7iN6bnJIA#aTYdnUH31x_f-KyO*g^cqdPJCQB-RmYU*sOL?T6TNGN=;&U?$OA$Y%9&(?RGlr3T=(@ zgWYM5+M|+Ar&hIpMgrKN{4iP@t&cVpWX)!8tsot^7)8Winm7A zDD?sSp^NSA)*8V@m{>E+@eNKb+nI+(eo?|g3LG2LB~0UgzB7;ds*G>iWIzU~+p*_+ z;G+yK=tp3Wo0vcIa5N*|i%1}C_FFK*&X$d`cGL2Y%*|E)k-NF(I!m_T0FL23?7GlD z``%b2?NV9+o+{KTyYQMc|5s{L-fcGH!gdyijI~^8&F&hZ4}J*@yP?7Ur?=Xg5+lBy zQ`_y=ZDxpnN4wBO%4*~9e^Yo8((87yU*Y^}!rGCRr56Vv26I4m;24W}h>!7I^od%l zftwuZeMQ0$*8yVCUme{r>r{5w57K;Vl-K+Q(jA7 zURtLkosf0$ENbeTg>u%u)mg;u3qpz2=+g3kMZQ+Dn8W!Mp>tc`qMnw%u~t<{t#z0l zbLFReOJCcNR75B$+rI_n7rnuh=IpKkw|oZ>nr3&!dtO64Nvk9Ycsn;4$P=V_-I670 zYeH>n)wLy%Q5Cgycx~;awQW|{*5MFVOKR&ZuZ^Q&Nr!+{*RAM3uZ|3Nvn)|kU56Ea zRaMwc5!)+<{s*0;H|K0Z>?L1*=C@cLTIR_1zHqNKhxUSFrYzRf!Ib@+I; zm)5twq`oaEs$HkP^`-T#*Qk&7t-GYcE}y{8(h6aMUUw@hB#U9KMuqL>(h4`&3{_T0 zMsuTVw7TiGY4h#;l@*fd*{V}vw^oIJTgxgWqt&WY;rh}FH+h9?6%{6I%s!tgLaJ57)99JI#7EwwBen!N+T9jqRm1Zq=%BlMh%`jnJ%4msP!_Mkwd?dPR+7 zk#5zgaeZlxtz_+2RY^B>t88a?(^I#z$?E>i{@%M{VlYx;0P>K|PQzg+6o#K&;htb2s3VTYCFCHEWuk>(YO&Ku7N{awp z6xB{Afq!?;6Ez9c3hV5?72#5pjzVQBBuD2LNKom3iP1`v0j(tZ4hWE%bk@)6_*CDt zRBfkFx{(i~M^zu^pnJR64n#AifFq4K04c4$V;S`;$Fo@y@H$F^L9DKSj#LLsp?Fs{ zq#B^hOH%#i<->zC7l68h*J>;Y z<&(~80=^TiuCm}6QE@e%!Afu7yIDY^5mB%h>_ihB0Im$=1S3gtd2S0!f%lfd)JG&f zDgQ|PpE($d!8Ed1)Vbz=^|1i?8NnnFH8feB!3lyWAtQygWYf(70GDytl17h zjJIZ4U8;IzmIP3Jcvu;Vcv9Q))r!B-8cl8ivhJZF5nzxBEg;*9m{Y=(ft{c*w*sCc z981ZrMPSbK`jzRwg9 zbD>if{rX!hdm&Hh4#+tm7Vs~*kx^S}pVSuZliC+X8+Un6PXd4Hgjf$CBKFb1l z^eJ5VW4ukb5ZgZFPvdq1f*&B^0qklXxDCLFYJiKVDTYi(4M5O0g}~`ZF&gPlOG|l# z)m65CII$N6;Qr)EyqOZZ7B);CvU0lwlHJ(}^iYWL$>U>s$k7abF;yfIqGM`lV6Gtc z)XgS=wpML(^6)@IZ)>o^OuCS4{iF{d3-B-b1%5B4LjJ&SZs^Yp{K+0Y23yrGfy6o? zfY!&tHG4{Dk%v~-$Y}|=LKB}`7pf14+aW!Fec6N#wFQK!U}F=9PiwxG2PXi@L(n~!N7|HHwD3`6SB&atMNgf}nI#n&wKX6eZ(NYzJ z^D?DO8nQk~BA>CgBw~G%|3LEv;l7&T|4wpN|<<^`+SNtZ2u zd5#eTg9oQvupK_XNZh0?a{*&vglZFF$p!wc5vnZ>(a%PxwzU{Z*ilXis8-=7l7wi0 z>5MgGZOcS>62$JtTs_AK?At||n?>at#ld}#Jz6)o6kBe9E&INK@9=OA=ZLOQf@<5} z)?i&j8D!_|RSOK-14afI>=&tj;^9G69g~03R#zFN5@@IiP^>U;+Un{`O2Y)m zI&WQY!iA4N_bv>~CW3$~+W_h%4&cBX2`*I}K1&>v}1 zZuLx-x?`%2Nz-Y9qkwbnuwSoR7eKSEo2Ci9dU$BFCrw-UW-}=^c1CK4eOg^rSDc3j zXy@M@@*5t1a?U#>7wrn^1|1Q|yPo7_-+zLYo~DLhC>cY@;fP7wnWXIt#Kr*#O-tjM z&fBE?B_kADoNvO&=T}~+EiChYd>w@sC@`A|dFh#s*@V`tku|_pvz2bxWKzM=B6Xf% z6Wj#b+_&N$%SOF?myLSq&xkuHk9?VlLP{f#Qextr1%%eUN(dR27cQJ7NwOhJ<*DJ8 zV#&$1wJcFKT5m~mxaxSJ3$z^y zxTx$z)d+xr<6y#u|rw!SX7P|4sE*^+o+{jPDT4va{WDazC zp%v*m`uU>P5WP=-`&U;w7{_R>*{Y5vbo2}JY5mw{C$Nww*0OG{ z0;KtGC!nGNtbA2TVtDDPyi?0q3Q#5;GKH0yGQ7Q?UIb7#^2|j{H6?;Zhj8;VD+u96 zXVgTXEhGRTA#DXTCMN=jNI*kCKCT+QUqb58hz2tT&ETAWvhkcv=`aeTMFnAKR(}nq4K=_dt&}RVT-K3HgqGQI#ypg_2dgLlJmTNQ6j0hxLtC zyH&$xB@O*Yxfjmj7a1LI$J70*5C=CPmfML;@u#6irU&Y5{z3s-hjBtBt{k>!B7&USu-z_Cq5iGe0cd>kz! z0CHY|0Oyq&!IFWcn>4J|+UT}n&ajT}AaQF1n8{+NM+dL@--0f~SUOVzYavhk>?cgV|u==Kh9=2*t0^cYAlrU;ql4G0Sk^iIQZva_w-;_F(UoSod+soK@#SRqW`26XMm^v z4c>KsT~cibG+Ej!WzPzzgp`IP270BKLF~=LgC})1$GTaKS>#A%;Td?e~@xK0CEOpW1zSM&n>&mll8*#|>%6q0#}q@p>P#v!#P0FDVP8`v*k zwli`>rm<>xzK!+9V1ffogaTe;E_?wngJ^<(!R~D4IuIDr9^()s=h}Ao`t`QvpNAI@ z53Y*O!wVD=qTvij2{9}PGKh5xQ17t9xy1t|<%u-ZF%?AXytP6@d6he+vA``lrlQ1| z-t65EU1!*^F^CMYH@sI~Ia(|XN3Qqpz|%L=Q@zo%uA!p=1`We3@NXO&+YOLIIo=I_ z$meX5Fw`63*uiEjG?i{BAAkoI@UOYjB&Wg1oHN^whX*!P0A;L4npId2vY&@X@;zb@5>+4ywdiBB7IdmmcTNwC}EHcCs zw8R9hOoB1Xq!rs6#aZg6b{m;l4qzmvd}kC(j$JHhKH(SKy(mei6RnjQ#b~3szP46% zsr)=)uWQtlfC^HLF7l{QJ!D|!*wq%NbS68#; zWh}3KQ4jV*-)KFeA zem&A&DR2ye2-<20nl&)vf-;qifdFt}Alwmb*l3{V0g{z}%o93fas<-=@1pKZIdrBRm?`H%FhVZlbGEZ)wfz1Q z=nE356W411CXqUue~%LTN)ovff_9n^zEexp>tKrbI7FLte8@qt4E@mgDc}R_yn3Z& z8U|2%~&ai;Xz_%mvoHgfxetO7oA&GI~)NWmHC@X+NdM zU`?}u&fTNQ{Qx#$O#}^p<>&uT7P$jfg4I=exdJ{X!RVx9a(V?2dmnzAHjx8pX2t82 zOUZ(VhpGaIEUUe?xxU;VDT9|AJv=O8xpAMMae?pu>>YiGq8YP`Ma)LYA6+88jffm$t0fq9hwKO0mf(4vhw5Ue-XuvDjtM+ zYl<`zl&i%E#KDixM{k%^(x}Dg%Jr{m6a>Td*7dK{^R&nduy`E0u-xXUkr5#7NeZ-L z#B6aSAN?4OaU^rp3C}@_a^&A~Dau8RCRQl->B%I7l^TNCQbLOj;gzHNGwi7mQ`tQ{ zC}Rv(A!r2v-E`k`eajYSf8GHi2?Qvt*A&qyR5d-oGZ$=1-~1m{|J#mcod2JHo&C$Z z_?vqEukc@I7k}H)eta{YqP!;+vuljZDBEB-Gsu_o2zeJ80xUz5pc}$JuN0)b@(hn) z<<5Z!Agv|BeltK039Pr5+JBje{g-JHBAtH#PLp;)1N}(ERzK~Qe>zM*pAUiJ1Qm*{ zMmkuXQATb0Y!D4=+!U3x)p1+T00p`-))MJH`&?_x*gHvgc$Mce- zFq>VJh(y{pBm#TiOrjm&ZG0E&N4w+^QRNh9^K4!TwM zEb;?uj1w1+lrBu(e=reyF2^}eNHR+72dk?}6wF~JO~%^=T6XOS40{lxZo9id#B&9} z=E%%QLDO7Oj5fO)>z%C3^;bW*#!%qKT6-(|$z$a$;cT)TCf|t|&R5TDZhJ+b&qQ(( zWO%sk41X7B5vQb5rj0NeDKut`*4mx*7IYK@maTR2w9(nzf7+0VF29e7wlKniu;lU* zhdtk(yBI|3>3g=3%;Zgs);rziTGk2EQ%NWC8m$WZZ{kvyHpO{jQ`TFpwfxXMqbu-N zkLB9>`c_jm_utN(@2lImxwX;Wl(kVrolS#5)oo=oN0s)kio|UNWWPTCHY*jO)Qnsbw%OcWp zR?6kolX7`P%B6xp%LLJuaAH4YOh9@sy{Er=tT#HFf6e?(^r{BCjx)M!@E_%q{Boe>n%aD&#$8OW@}CR7P9PrLnrwsoKn&1DkXEj{<_`RT;HfS+7+W9f-Hyziy1LL z`c_R|?{0S1ixfiYKaYjdc5n)C#Vx{$+Uf$%PP7wFe9^YY8+vlxPj)ija`0 z)4|$xd6=b8GsrB>S65Y{lzw=a!)dIQT;vu6f2`3A>pTQK=*fCI6Cfz?68#;csyAciZjFR)OrO;|>|lK+0a`3Hf~- zA;114X|`KMo~yahl3sMoftK$)w&4)9wj%D5wIY)FOLcP8bGEtd{N#(eInVUZoeQ+0 zf2JxrPy4&se5{U+=&3Ev!fL4#?APC9&5c$G+f_1nAcS7T$jZldgCU?sS=)pyQhTGX-R7^y_0+jhr8yqq0ki{+RbDJ~-djBL^A!xRJ0-J8O zE=+|zD+pBHA*O*eu3Q|N?F&;8U(h7PO|Rz%*z8=GO7e?-3@~|Nb}vkYJ<|^}-*wIP z3sZpyp4PJO%?*;$vhV3jswmpLe=rsDq{OJx+yZH6xuIU~j2Yp5e$V^_hP%u@&kb{y z;Xog)udQj@p1RrDT5BhWfNHDLTI<4*N4Kb&chOFUS|@gF!1{-)t2s%w@a^2XkfQ=N z^2~&)kWeQ7I3ibM$egX`68Ai{i2@zpXln5RLK^Fta)_o7>qFPUUX*!7fA-+echi@t z&fCM$tsh*IPee39Ey%^!VB;wd2u(j7={oDt7NH@$xQhY{LTw?}!~)Jx z2zIW5Tck^l8dKSYh3r!Ve*;j1luGp#U`2z4Fy|?`Z2^-75rmIBf3U=0#bhPO6hjitA?=8?1ry%q24lwhTPvP zuOWl|#Ep|;I1@YV$}@5Qn4O6~?~w-=S!c|6c^a^0h4+Oire`8J&lJfUCPP|XRZg)r zjE)JSCWuSO8oT|he@T4sJnP081BnGo)1D6_u$n6?98BWa?Sbb z>dG)iYn_c&dzt-^sF*&#K#|!jQ-TmpPDTZiA;Or{l~_rne@DN}y9FoAIb&_5emHdb zU{Vj~{Roi;%?Q8{Lqi^?PW;sVqSajMwkvJ$g}}?geH|qCb#C`${43ORobuCh=N&SU z?7{+q3M7~%(nB~0=D12;GPFCe;)-H|AA9i9LAW7I^cx6&WM63=N(Cc(hKBFBWVV4_=Hof)or$F%!ySX zsmR4Z)^SmmAdm+>@hd=)e#6Pi)zwAvY><(hIgGM_2Z&D&$6u006EhQ6enb{S4cE$y zy$Z2TPox_O|HZl)rpuJ9ys9C=Uzn@N^?OEm-qL8ce-l1Rl&hxWWQnecpB&$1PNKeC z(ttuUv0LzWYDpFhAI+;sDPEjM7%7X-q)7HC-h6t61JT#iqHd7hE2W`^7&j(SGz*P4 zZ^lkEnO^}e#2brTlY|!f-F@TmUcR1L!)t4dLrpQf96c52qX4$nz(4V4V8=}9D+`5y z*e&XXe}Y(8Mn#%tJ8MSDy*pDM`Z?ISLr-1vT(R-he5@eF_2FMItWpqTIgk=MF7_hj z0*y>JJ-s2RP>U_ch;l}1ng?rtH%Dw+s?3V(9A7*A0E^p1>+)pGi{Z15<>O5K6yd9e*kxv6?pKQ^c!AKw#!!85K!OSnJM$D zAG`jQC(kZ;JoWlExDZHsvZ-587G{{F$`!SSce)W&gPs!E}{XUM;gzDxUbt$#pge}^*4n56D6!oC^c(0h zv>Z(6H@5i5^xc8JuXj4@>$Up+=V^HL>Sfi&(U}gf149( z)X{1p-)zfOOyELzeo^!(?T?X4KdmX=QO=VZ1UPZ{ zgp>=AXeHk-6j~BvA`HO}hOIS)I56{NK?&2u|BSt5w(?lZdqR=5OG2DP0!7J7KHqbK zA%w=gP#AZAev!h^0`H4}qQlwne;0{kQIH^8gR{bl(BvYNtYgd}5)O-bP+`D5BKr9> z_CYp|hATQB=k^@SLbwvP>2{Pw42UC4?&a?&=gKP}%U&rLilHok7s(2u6EX3eLItFt z7#`(af<)kq8VdNG$4ViDi!)M*i8!~W=fi!W5Zs8QImrhy2p5WAb>Fk1e~CVI01z)J zMnE-q?IDM{Z#B2WpSOL>^!t9B{g6ueD1A z|B{Pyg|kLEFc&I7A+!I{!*@_4wi^k*--rTdJjMYgc22D8pD`0afB*WC$)-P2X~{fJ zwQ%_x&l1*TW`V$&zAamk4-bLb%#svrOw0)620(SC-_9NVw+oZW1^g1^QZ`rwcOs0e zAff<*0mCiDo^1kxw~f*i1OFO(CQcI2-z)<|`SfH6owR2Xmrhcwk=B5)XB)hD4rXbo zJ{`-jsw)DNHsrr{e>|Hvm3B|)m`5KWth5<0TvgwlPd(G2zX*wM`t-*vz&EBvpTV6x z2MblBo6r~|X%?akL|PGvZ*3$^`v2K`yXCl%ZB6WY-lB-vE&+$B5{uMN3)SdqwnVA5 zTO`#Y)qkZL4p@~%qFDsk36v;yRXHXc4nKhH3)^8kY+v}we;2;A9bx-w`)1x^Ucj&5 zSS$Zl0tr&uz4wVT7Jx)zW#-DvmFwqQOwtk)x*E8ii-zJ4gqeoZ0)B6uVs^nV zp6oo`{#2wkV1}!CR)r7Vi}(3z^ge$t#t+UQN-tI0D`K44$mOIz5H>OfM9T`!0q~D< zg2-(Q7lfD>f2K4jYO7H(jt0@@W?}tUZ5VX2m8*^jzi=oSr>3Gtcce_IrL;HktU*x8OZH?ta+ndo*m zP%$bcxpcM4zD&{QFv(yS-{`MhHF8)bDTS?tWpT@ks@O;p)AuHc>C+@J{c#)w>@yO~ zbi4G5iR6ACd&=lBVa&nA*Fgw2gfs~Lh5pUb zUJZ6Oe=%>Sw(EInSfMa_U-rigEOWc#+;S5bj0ojL2z$#VG9RA z@ZgNyd;cCDM4R|rZ!fQZ(c8-t65#t}=h3YQo#!>vtZQ{y9_;S##Q~Up0`~my*}MI{ zgX1`Ot}KHAJAAYEcK7(z;lauCy%(l8?Q&v{w&p{=UN$vg*yKi6Ze)D?I zDXCp+Xu+es*L%;f&ZE8KI53cb;LpTfyxM#HJPuxDd_E1>?%S7&B<;!+uorK4U&6hU zqc?B&cA>0D&*0G!x;O{y)xqmm2YV;FTpYXtR8X#qks2ta`mwJ`wjEGA)>!?3;d<=F zf9u2D<2ZORFH(K$==klcgO_n2MLc!$o5RD`d%Fj5pac$e`{3Q{*Ku&Ln9tRXy@PlA zaR5%i>c;C=N5^sSIxBVchu{2p@7Zyzgh1!!iRwN1NcG|KS8t)af7pwI=b7LLt{5;F z_~$3bKfh7KKgEP2_%(GGJ}GY=93Gqif1$c~kpsc<+0nCa_x5+4o;;eI^UIX>qvax~ z!Ou!iox>&1c3R*yYVFOA*gjz07iErRHfCqL}Ie&<&BD!*FD zPIpTm@4bDo`)sdC!K=LDVwO&Lorre_-VS+}dpZNSqFEHU#9OjSwqdAd8{4`Le_QJB zKf_Ya3x>PgVMPAe`{{V^;E1rtp7tYiN7^Z;2bz?n#FDa>Oj5QsD5SVECgcq=B&4(% z5mM3)2q~z?!=a(x#SR%x58KzI>p=hE&TT9Ex5^SLG5h93tM>HilgB&KT#Y(8uj_l; z$)}1G`m0|p>cnQR2X!puf8xQ>e~Y?;zuPUH;Ap^}zT){I4z>ny&6xy-XQA(#VIGoK&UYS#sa~DrEUu`K$-~tQ^ZW%xXf9u~zQ4WAo z^Qj^Bswgv9U3x*}tz0(VR4*_8$`7omMi!8CV$u8gg^P`2>~u$X+6~t0aa22*&B@6O zfC(pv3jXxT<69^8&o62++bud2DWNM}iPkC|r)R_FtvLAlYjO#W$4?$U+HSy;SQl@C zgnn-s?C#C8vmg%Mf1ErHe^{`)|0aloF8oR-i;Bx9eYl=vVj?fM;qpwRAJpS5xR$DG zxO@bcRW_fh$2)MnxSY$Yhma2K@XgP7l|F^537=-_>63s3d&l46#T4q@BV<6~JxfLk zmxPQj;M#oWG+@EY;~);c3Rv)p)G~!@TMLIvQp*IcO)ay41+Sr&e=h?T9N0!pp-T>J zty5^^p{aEWtvs}~PNB;V%XwO!%WI(ZkW>eKcBsEPg^~FF-64Dz4h<}LyZ2J|7f^fr z?cv)4Sr9JY5h|cd-dQT358e?fpab8TuRu$GCND$Br1qLa6H`+e-^NS*^b}f{a?Ly( zNKWmiIE-C-d8L>se>L2}p{1#9Ifsr*HBB69Jry5LQz6?6)lMvbaNrMndHMxj=9MfA z6i$k(8_Qagg%CWK*HHD8ODax*ylDow&3HY7dO2x3yv%Lep%4PiHe?)#Jg~7=PMNn-fcO0x1 z7&kLS!PPwdZBfXVfyQ~IxcV}ksLqB`m)S(fQm2pbayl(kmC#4|X?Z0JL#uQ3D21=* zc2H+PU18fYgF!A#TV^m6g(ZFl16PRYOjef4t4sM+ys|TA23=o}PXU#MZs-j760gi}F&kf50h_bp6 z4^rr%h3OF(nj2CR5PYNO1a#hwDLM<*_dxrw^XQAMe^1^(wt_hLfB*0QGhjh~`->nB z{@s7_zrgPuxc~3|&3}Wxp?ChD{~UjAHp@xf5YFh#{UU^Ka$P(FYtFCfB%>G8>;`e`068U#(ye{Lo@z@ls}SR{Xg(GeDyD~ z5~Te9!k_S+zx;2q(;q*1`tb25cRB)^!GQ7{odIEST?RKCmd#}V>g=po04vSYvg+V{ zy%+)$BVLrci)kBU{G)GOrLc-DgCd7dEVtJ9f1s0|6*%|KxgfVoypQO#kd@cIm*pK@ zhP+1Zmf)Ba{I*C%#l3XvM-9^L14_NU+iZY(=4pd^a#u5K<+YaR_pvdTMGm_{vnldH zqape>ZHB(rYy>{>Gy(75)c{>>jePko5`WG4g^zZ;-ymJxrIf2%O~T=UhiJCK5eOZ)!B(@Ur3p?mILW@{XdnDlQ9wxkx?aPSYC?wbS(GE@I^;YP7<8Na}g9 zKsK*+B;NLs0S`QM!0o#TQFYcR!8awJW;t#M4Pw*-FZbaiAN%2hJNZx7TxUS}Hj-8H zNdcQPB`a?kBw5x&j(l(zIqFjla@5<9e~}q>`9f5;uB@WxSy=I=v##PD*#^0Aik_le zlV=u2(F^Wa6)WFI)m>*jtjK4b#jrA;cUHnml)bx_L0M;g4TLxES^#^#<*(OR{AxXQ zS+w;O6uoWLy6}8Z-gMTii`oaTFWNo`MgPNFapaoP%8%!gA3t@$&tf1acNJV*a|j{Z}fqjG|(KlRG!YiZ}Qkk(xNjbA~H3k8+flG&*a z-@k!QQVb2(mq3VQH@Lh8*%6rmu3)>D-3?dgf$cJUHLy*F>oQQ3!HKh}Wf7c~d4v|Z)>TY=&tWjA%%K46Q0bLntXAbXqgHCK$ z)c1+`WLAE9^Xt;EPZD-Hzb>x&MOBx(>oTQZo&<^T9%%YcPOkYWLE&0zlxK>rJwLt$Ys}%>CM0Cw`yjz|&s9#sepf>Iz~TyMI_!(C zumF-w zv~6d$W?2)fD|;!p4LI4ZF(xb&ViWyrnyWGAy{oi3FB61fY9H&CUc5?z2WeUIs(cXm zKQmD{0Jt#O5^5~vzA4x726C8j`%ZlO>CW~JK>VfNhhOx!e-ZxA_w3Q*r;t_1U+LD) z7yXDW5^r0=5^z*}?pHKGQzCC<5Q;Ss9r;o4e8c~&cx;7X$op}x0$|k~;-jjQ|L=yiTB7SjI*7L>Ge%}>i>a>1*f0;${cGEe{U&LbMVe)RXuTw}g+aYu5Q zBL~_1<3ARtwG*fR$DyeIPFU22%6&4?FA&G|BmR4c{~lA|fx}M*0zLYt3Iv+}t${#~ z6c8vhbvGG(VAo;9#_TmLKc~HS1;81RnenU!e~)z4+dqa-`q$xA?{cbu093xj{csh(_#BE$dbPVZ?s-_tHZU9A47SmH=$w7TfEIZ==wg zB1P~ix_kF3z#i4%-!7C~_)YJJ?-(8{>rcMz{elmo#*=qFQTpF`*W3M(E&0cEQo#uU zWYO4ck?ThB-+@!`8xi1ZHEWxnuw_-me|#Oad}>l$UKKfH?)_8mmo@Mua@~)~OB})P z{QddpVLxI&B!)8fTk<@N2EX;n#VO=UIOSoZuYV&FLF-08;1Y1)hi*6AV&C<$w}>ks zmz`fcv!&ju^WN`(`&AW!$G_^pGvXwt2zhK3GZsF6NhdUAb-Y-#0kVVe@e@_9J zGh)2*;J<1#SB8t8I#e(LyvTX)yC`gBHPL%ktP&ChQ?Z8EaxX=)5| z=o%mkAb(NrA6W?>Y#rSN1vR)$n()aHH3xbDfw??-cr!UI!l>KT0Zg(iD2~^R&%Na*A&-Wp97I9{n|wWx^=$A7C`C&yK46F^ z48NLe_O3=vcM8h6!)FPfe}{otxU8Cosu$RXHopy2@?mcVnJSD1057D+`3f`;i`+ne*;z?<>Q`QGvF64Q4!M=0HA`ZFB)ua=FxyQY)`L4jAA}|R`>jkh@*rhCsXh8&nQt+zuEjSkd z!eJ1rw`~1p*isy}G+OI+C$`-~Zp`=x4_+lQo&A;>ZmCb;7ww=f3d*HE z_2f-64OC#F%f9lKqF(1a{@t*YOd!ZVA|7FcJmr2$Ww=(g<&mA3D$4>4yIV0JGuf}g zib-kEnkVvt|8QkcD;@REWxmT&3VNoj9+&rIY$)@!8B zW*;86^r6mnjeb{jd-No{J~V6v&Bny@sZ3mNh!IcCG1~fO@|6;6d-)h|GP-M+SDlAR5>dD6dWUg&=K-`dR zf8$<0uI}jHlwz)i=CD+eUW(!(%#_J&lx}X0BkVYf-4HP<2%xgXUBY#>_#P}K^R(Lk z`>nL@L}}rDgM~X9v%9tyR2Vi^-qb2eRVSx%r-Bq?*j-h0>%fWI22R{DaFRJQ<5^fn z1O8RA1;;HwB%Hv>pdYaUxqP57V#~kke^aUs!j-T~OHr@e1*<`3j=6$PFHeFDZzdii z?7JJaXX^&`8S&}ZW6^=ZhWwe(^GVYI$ESBV&&nbE6O%0FO=++qY^KxG1}1F^s4Dmr zWy?CeGR>+SX3<8HWR1!*f91MIE}-26BRmHON;tKG7SHP7e_)0x z!e^0nlWkP!9#e5=RijRnwk%7y2u+Kl!A1y)+#wT5k@JDxJaVb)7@(2}**=vC3b8tU z=B=;IO>0N>N9lEy%%EhkB!Nz*LDis1)h!%C^_swq#mu*>{E_X1$V#{KboAMsBT+x| z8tSL&9LVSO37w-(i)d(+M@D|`e?KhB8QVk#;`>zR3+Bz-;6wY-+UFS{xS|cR?K%3>wi0)C7jXi;_N9Kl#ny1lv`XIQ zBn={y{%J1(+!{5Wg+BxaoBc zA<4OZ;=J4oqS!R$;lpU)e?#0feE^%R%*+Z~q?6C9VSh&edA-D_PO=#B=7A-v*ZJ4_ zHv}X6Yl{FTZRM(=5ZS}^nul&D^P5iJR0Ei3v7d;Cj{qE5jJC$4n#n1x0>S!ai3_WBf4XZnUV~znayaDH zb*w0_QOAr<1fO!DQCf(?t_jp>@8obviJ) zrY2JMEh+1O=lTl&N(vj0USGi%q#yzB^%eb@6g4=&zJlM7f)t(CSN0t#Yr%beCBG#l zEiSOH7;Lr7Z4UjT3NQKe_!0s7a3e@d)X_An^_R+fKLE3f5W zQ|=ompw0`+^&s!f0A{yrNv;iKK~{N8M5Fg6f$2rYNW0 zM2vsu%4%Skmd4T_lTn~zAy6I&vV1aMAkbrZkzE0Lfpi%JcshWWRk3yf8#Df0&CQX5 z{VMx%g+ZyHO4Q$QufU5)9L7Lho2{#z{+e?UqS6*yqk)gS0$MB5BXMjT{iexUqn z75w0XhkkU7uNfqYb!5k1tYhTuGuX56f5KcA&Mx7Z%Pgm9H3(rpIqJc5o~7kb{p~6L zQ?de(7yqnht4X|~QjS2TLoMhJGMnTt)9!{vl8!QTGvnW5(h(4TPfkDxgfD^2P|%}` zf9YWUQ&>b}xtEHeI-?a)ERs<%UVGh5d$!()Bv;h;q*Br5dD&u%L=4I=7bf3}C3*p= z!zKwfoIeW-mPb8$=wT|{rB1^{e|SRWr)Bc9(zo;R5wP{H^M5f|ae`=yC zi!ZFk+D5!IMp|oKzfAfp*u6Z>&KAX@Y>a9QVT@Ip<)u9sR#sJE^)HT+fmZ(TDd-d} z<89MbWDAqsf8xm8s*GAkqpdOd%#O2I{S7|Q?QU$y_07WtPToqj{zaJ3r?!SZ{42=1 zP5ZApcS{0uQnT!WRa&D5W!{Ws{}ku2#Y2 zLY@irHT8_cdyz>W+_E3YkF8eKY86&VhK4<>f*Z7H#`koF#s+swwgrp;J?&UWlgT=c zJ0ReOq*T32&b1HedhoQ7*^}b!K~ zQY~K6LQzdw`oxmCG{^kdf7Vfg%7j_tNel=o`U0Psp$0{8OsoxX&9FCP-ow9Z>;C7I zf^l^3Bw9SP&WW;$A>Rqr&uF!hI^;MAoJJwg46)^nwC+1_z7arVjA|twe2sw!oIaJ| zX{;tmEm807vt;Wlo2odAT1_?Ce9q6(xly4Igo2Dp728ipVszWef67U^Qw=MGpgQgq zGa8>>(cR2vzk|jf+^7wtE>H*J(v%!im>3dO&%cB+wbu=X|dEFYxdpe0?DeRDrV7c`i9j6Vr0 zE@S;|ZHzZu)CjLtxpFnBz^^fKx8QCU_RZdP3Q?uN^H~@Gf3gRdAAv%!t2otA;B z{)$?0N_y(Wp0*JOeikL(3-(wfv%q2r%CNNx8-wVX9&*KS-_ujvZFbuNt4eG0YzF=r zu+Z`;-M6>5e`_Bp^1WJ6fzk13SwRiRW=hUuknlSp-YzbGyj0%_3QVQ3` z9tao4j0hLT`iNr+hA?0tYrc#}fi&Bh+j?|reQWYR+DCT4#>`|HwJe}hjH)h%LN>Rk zy;)Bve~RpG4;Hl^D`-YhXEL~HENT7Cl%kDq_!z~P9kcDlOy`_zFt6#|S`yN>n&>Rh zGtXt;W{T3bx;|m%wj?n91MT#rIQ@j~mc+vQ&Ag|d^txegPcqa`8t&GNsGszC(|k{! z)K3{|oyM>hq8~lg~yok|KSP zf6UoDnf9)Vt1x1h_+Az*l7#{cQBm*u%zg&O@ej!syKxTQi)irS%NtF=2Yv9qPHsjY z#)Grb^*C9KuE*;|a<GA_oLsEee?=nXX&?OtfKXNfF2^*hN|xb692q7O(SsZU zXc?0|Hy>uhB2GueIM$)V3Q1v+%!l*QWE`IxJx7uxiwKTKS-#+ddAB>0rnQMQIe*m1 zs9(>=4yc&$%b{*qa!jH+ZI`p#zo3J^Xv1t^+nRyb)2zj6d4A~zgS*Ou*CRt;ko3}QuIA%J0 z>~_Oaws54WIq8ghH1~$@CrmLJ5A@^ z?o<*q2k6&Dw7x#i=G^vxId;&A*zJbrNjWO*Y#a5*5j!W!oSC)(E0v5w4-v{U!;2km zzNL?~`4CiI=?5MI=1j#!i!)?q^|uDeB2DrkS8sFsb{e$+VHh27I?$GAe@U{ZY@y2* z6#b%_I(R9>eMp_mH}chLLn~NUtLg)IT<{NE+<4r($or@;&u04cfPsbskK>>6Ai`lE zhMDvS)i?v$l`1**O=hYm&8s3Cc`4O)WF(VPZGW*@e zjKhMmvk(9s=x`?Y0c-8189tue}Z-~pN=`R%Nb5|G!Y>O-qdEY^hbmM&^)QTa*;TEIlN7M+ySqy z3vr>7*>`4XHU}S53b(A4btM;wHi7z}j&)cQy-Qw}=^1w{BoB2gS|*{Zr9Mrt%(zpn zS#|AeO~QLN&?t<03y~S!?P}%q_Lr6xn8FXvz=HVO975cxf0H%@_-%@gUhUa+1)LgA zi|GxS{YUQ8GhV&r>68<+xaxuy39FOd^8e;TZlSB}idu~h&DsS9PCrQoo-?eHS|~7yna4;wU`2l=tzoZpCEc|vDMsN* z|6(Qp8bF0Re~-qs7;_Ye@K5S^`c+BVE6=l86?$VaVRPRy*w^qo)KHpC!9+p;stH%J zRF*QdjwDaZP0n%oDn? z=R*isi8Esn)8EN-m)Smug?(HnL*7W0OwL&~21A5{e@3825)1*C#Rm?$L7sCF2Gg`k z16D+yM+*3-^ge_9Obg!=(7Kf8Ee|pD6P{sYYwmm=F6k%n+I$ACoT}l5sSbCbdF!;8 zz>F~BkevA8{PSi=#E45&_1aF6jXuj;zg!LL_<3z(7*?3T$;UGav(3fbgMcpIT#0%b zyk;GFe_EY?ZmS8nPW6m9J+w3!8k$ah{ato+tJA0(l}(z?J&@GDIT@ju6ak zPfj#2c*^P$fG(AJBAyjf4u~OmA&WqosEUa-s}5Q=>!*;*rF!ExuJs@8JdRlPHn}6m z583U1bs$tmVw3RIwYdo)KQzR>GSYwb!pWh4mzs;v(GlXQ4HhjzIDFMN?$Yv5 ze^q_MvZO!AzRU-kn^{yPAV`Tb0E*(H%;wWllHbpb(VzxP`6js1BYY!BKi{-FXw)J- ztDhsL{53$P%jOo7FDqrwCgArkZ$aY5XT?>cdQN&p zWj@Fm3HF7-$i_^-Q9BwG@M^aUiMH}yd5)gT&x)&?7lqiDLli}$Y@8I4)TiB54yeHt zS8-J{VmIIM;kMDx&yCvf!5j${dRtv%J>*Ju*`jy>OOr}3ZcDj`fzkC3rPC=ie+U9R zTtJ1222^JGM4&f7ItOfID#p@i%JZ~508g+C58-m7uND6jwdcP>R}HL!6#2a^KK3fT zfwYJ9DxIh}&^gH|Jg{F;yjZ>I9fHp{X$=UY^x7*9TJJdCgEj$r31;qMsR6OM-yfu3 zC0m30_YHeyqjb#5Br6ZngK)Eme}>C7gjbcLVw_a0O3HO^7M5H`wBUDs{ES8OJJNc{ z*Tqs+45)|LC3rx?q*mgGHfFe}K&4ebvvYREPT3_pV;|TJyJjbBj~%fK_K_X4eRjxp zo%;WLuIe{6zBU2nuY2?Kl+R^Ed1os&D(WOjj`_#xIiD0$$f!iOOY*=RfAtkcKIR!b z=N+DZ$V8D#N5Ct&ZDyC4jxOz774w@}HlO!`Xdo9tQezk_s@eT70?0F_%?Gd@oa3fn zQu{%!%`-X7rBM1g=GA>P@j^1P;1nVqQgM?6Y@R46poM;G(NjvRGMq%wu<;aJWo5Lv z?@j3tIfy z8FHC~r^)MH30V@NNNI}Bl2e5AVIPu45YgrEGA?^l9GCDiVmHPve|BG+!#4Xs+!>p0 zCLh>!GBq7DV>i*@`m6i>0qzw36*c7z?Zy07$L} z98G7xSgkZZ725~>nJSxk%4Vxorpq2jF>r&o+q+%5MILv%8^=9$1CD9x3lMIo@sa3P z($y+8h*?U3_$*phzl6_V_i(0%_Uaw&u)dn5I}`;2zEiY(r&z5D{T&8yuxkgAr22uJ z2uVbzbY=`-f9kZyXD2qRZ4gV|&A+)HWQ z1<2}S%~#3J)>gM$J*S?Y5&)D&+{$!*70K~xqyvMjVMrZqpXE``_f5Hxkr#aF+zc`Y^AlNOOe0SEFw2xDIpx3d*(>KT4^YLrr)bgLFp~pG6x~R+S2}$K512d4l583 zo0<}-S``DEZXs_F1zAc|@@)`~Eit)wW>|W1t90=>s{VqG-OjA}^X>UCtDe%SH`<{K z{Dz&df3BBs;8<&X4xYt-Ex%TVUzvLX0f+VKN8M|37jbW?Wgc!S8YJf$Jq9Lny39%h zz5-o{3@Wl{TAnjcYb2u+r?QS3Q8mFmFaywdZVPMSk%e@0mu7g!XFX~Z-z>KqrHS@se21u~Ix zI-f)66ui>`%}RR4JK;RL;20TL#t$A`Utjm~tIJJChY>40I?{g(*OWGjnqjQgZ_1?gg ze^_>8`mSd(o0hG9tzP?DMlwE-mST7lKddu#C8$lOb%e|Jc?SawVtl4+440jS$l}gD zZDYE}6n*RHJ)~lQ*E$`?k$ndgF@1kRwI@4Ix9L%Mi_SyPO)RB*Mzy0&{oBbGTddkq zp5$IWmBF^wZ`%_<`zJ`9jgh<76WzBIe>`@BEE(`(4oGwFA#b10SKXHx&c?xN;4a8A z{6!dq0mDytysKHjI)MbhU|AvwG2S99fM+S}J;ceHSO~M#N~~5Y!c6A4c^r-^_}VCE zVjRKob&S=->DuQd?`wx96Ptl)QdFF#@xVo?q2blisWt=1R-SJ{qdQ3lLQ~{#f9!w^ z35nLOW4&)Y9)+aI0GBHrx_!i=13v9=>U!Xk+2~1D;P3>jVnBGbnX@t}HtmoJGCaDG z##^%52A=?3K%&1eUH*L@uuLTcqtIZmXkCvd@b$A31HfFbCV%X8AB#fEkqidkFLIy&`y-bRQ9@V2TkJMTawT8poG6LpndKiHIwLfmgM}Lhz zcq`BlNxn7H(&`JgXz3xddf5;IxwG23Va1Yc=ujksU@BZiO(0<@*K=5Sx*fI82-BaL zrLi8ha~FB8>mCXKZTo$g1J3fWwgcww4j5bh&IwmXa;$_$LWuk!LU$4VS%0z$2uey` z!G4wEilxGIUt4(5-+YwK3xEAk`vRBlqO-P-SB?3)$T8%nq8qo2$Iv(gL+HItMbxT; zV9kamPcYPHk|bAjhbDmJc1fxpg(7l3`YG%~EB%!D-X3A~nQiip|J9+Xtk0Xw zf?x3zQ=TFdnusmECt07+uYZHhKRUfbF$_BPivd7oYz7eEj=Yj7URg(tXt6)Gzo6E7 z+PQt3@kX58zAu=1KXrTX#;W~o*9=9|AK4( zbb*sp-M-GX#|i$yrO1rdtt%1@rFeLUIu^Fu9yx6=P|%O%Nt z85JrrY#eXFat0z*Smsc#$SuR+fB})WjTPkb*_XyIovBlK&p0zn{^dZg- zGpBxw?gU`70uN25ybI!GI+^gRDh~eP!9Qr^ByC8Jn}%WljFQO(mNGMa9K1O^Iu6!r zmZvR&L*Pqe`8;o=OCODyNVW%}>DZ+*$GDDNCKcHdg7+lmxPLF8#%s%U?6nzs@XGc? zY^l4Xt+esTVAeTfjj3b=pK?%Y&jIl|qt}V^6jYHdwPP9~7*?p#dRxk@HwlId(wAWxXaAYQ5NT8)X%AQyN zzminpgjHKn#DA8Wl`;kf!I&mO$V&s;vSB8>2Z^ngBL|J!DpM7Y{J!`A>+V=^#~4y+ ze4T{%JD>3Z(fq)&5ZPIlr*rI9okJNvyVmhkpV&GPwP0S05g+&Hcg6|cQjnS~lgr2= zaq}nn%uHx^g`gTy%;#Lkk}fCa4lFDHDxS_^F_DRN(0{L~_9lZ}Qx+UFE8)71if)AY zgf8&7IJoOdE<+3giiw>NOza%YhVS0KdRAOs6*(Ab5W$FG8G_GNw=47|(~xwmhGU0i zYN&IyBJhrxBsz9VMRH>z&jivTk?Ce)zRJ#JdKEOX@GWfwRGhBYBBU^P3N4XLHSO9* zK3T|5l79&w*qQ2lwDf(n#E()uy+ZCl3-HjIB%ICZR`xH0Xn@<>yxR>ID#v3bz@=+q zueR7+txmH9eUm1(hG7s5gJBQ{UA-$WbAJ8q?W=gQIor&oBoTCjXmdeVh&kOf0jcWP z4Y{$|0M!OMOECEE`sc`l9EZj^SOcbRI!D*}d4IXKh@lISu{^Pc`=N~|iz_J>LY>kz zQ)GF?Qd>G3=4qU<0(-KynBsEXT-|ZmUX=Xh-tmh^@A5^-r-r=@O2kHz zOuF3(o2k9$S14IK1 zSqTzHHVccMv7GLa{T^JLQdzy-8#Fay)qD3JDM#WxB-_r8Qq zN@fu|zonF_DHtc`lEJUqWQ#Ilg%w^-RezrsC~lbkEZY0C@b>4`nq4L+&7~~Q7@$b7 zv*c0>RO~}?iH<(dTOaHK*zIo2WnbNxaB;f7k)q(3G!M0Ovh>)grN<3GAT%wrAkXIt zfBME7T@Kz^HyAqJ?b7eM{(_VscH`ZAW#t`G5|dBhV!d&uHb9Mbk}txDog~*iyMGh1 zz2sVNlVO#dfOEKhE!mT!d&Dl1&j;Ri@Op_@xMm;0l@x%5_1@Q3)se2M4)uFvtBcri zf+6-(062iadQ~e7{-WF6P}dF+Gahd)WLxE7A_-pZ9S0FRUadYx%QGYSnqLqrgA2!g z5?n6kRd$t%>cM69kxvJ~;A6LY+<)zQ03(BaUG_e0MA?}ZG+|EXYe{~@J`VRci8HmD zc?0_L(G{O0{oWR9oRMO5CEZM9XJEPQt?litFSZ{x3rEZ}t|yOT$v!4ofSyQ_M0btk zp2H-cgc0qNijCnbmoAAeZzMtRB- z=S}NXF_Y{+^kal@pYIm%-QX4I#yPytv9;bMrH4?(- z6kpS0WZmwAe`Pr5y=0vSS+4>-%`6&L-(j3%T>S*TZR``B>Kx}yh~G$0F_nqRB$}VM zBJC0hqryN!En(yi^lm-{i+{QbysyFV=6c0VDwBVtiNsr_5zDWVD%EJNEI&7&m z3?_4M0n1O8#NR9A5DZWy`58ckW@Yc1rx&oX>aerR^nyQ6t2C+B^M9haSX_m@UayAH zDIaL(y|sI}ga)dl-MUjh=%6p2d{reFyY%cln@^8LhVfP`zt(=B%HeP*olaxxe1Wq`Zw^sOW(1;lJn@joUDyG$vm5+=qbZ+5~J$Q3>| z@Da*WePc`Y&qklrf8-4h8_M{ui|CI=$i-ZqUoKi=G}W}gh<{$_9RQUmZ-&t2;2w6w zD;;E46m!#kC%sEygYQZepsB`5-UoT?n;URr(SsxJOH^+BnNBaW3Lx@)VVzm|9ny41 zsG+4^1sS@*i$Go7KbE|2Fd~i!!;oen->6m4sHdF|U>lOAz8@!??_)9~RoAar6*$Oj zy8}m&)EL!)Vt+=V!q94KC2(V-QxscD1%q@xwj+S!f=J_foShXf(;c&s%3yJgxh_8d z5tr&gl9_ZICMB7|LChjh>R~Avz5x>^#$WYy{H_KRtvv%!Y6Soe%9Q~_kiJu>{R-}F z(F4Ir?vfJ=Xt+?Nn*w?sE!C@);#XYhqP2z$@^@N^V}H7l_T(BNhkl;u>zclP@d`FDL0$<;6q0yP z)Io!)Xb{ShNo~ErNg*O7sn7>78wFEuEhWiu#b8JwBe;<`v4FzT&Of%LGR)o80F#9h zjZJ=RNPkz;9Ps!vwZ90nTv)XX?0S;KtlnAxi8p{m9^XC?UU?Pg#}qFVC|F9>Xnp}g zj9i{C#ZaxZF>HBcFWIjJ?AJwan(PvA_5rjK6;<4? z>PA5V0S9;l!XV%!?iJG0Za1}6tsS&|+ejF2TWBpcloD11WIHesp;i>aNYaRDTBsl9 z0_4+;vfC}XT@|J#qV<|hmHKlcvQr+;47WAAXWCojwj>@KEJqv?9Hd>l$Jyv{T9|+) znSTOYMMr@YB7a$7#A4K8=sO8Y=e3}8erHfRH&Iv;rAz@JKyZ~Jz(AAbuf6Aur%!es zJ&joYERosC^Vhxe-iudzubyxrS<-tFeE!hc#qbD37w5kw)f4Q9qNAwwc2!`n3D~K_S5j5b82FrwCA zevXs5Ay~oI%VYps?VZfBL6RhMTpnt#XHhidar)I3GQl5Q-(j!mc58WZ-Q1MJP`G`d z_;U)qXu49t;ccyHB*U`aMjRD995uObEk*H}O^qjwJpO0{k>+IvANe5#HF;RSWubYg zIYZB_DeR5)!S?w!T!jLx>3_A#y+!L3AoHl4>j3U^s!1B0yV*Rw``TS=%J3@8LmeUR z3{P}-!+5kjRk%YKt_vUAXkT|%EA%c~ty&miwL108l!%>rzYJaa`BbXI>!pVsHa5bI zQ+4P@8VzC5nw_<*hLL zPWjXu00xWIGlVIBkt{*t_IMP7tt#geYoBdEj>7>p+#o>+s};R!?Trh5|V7VZ1Q)iZs#ob?h`(kl_)KSV5ZyHs2oNPs|F{d{0nESZdbOap6#A~ zpCa3tth|^U*ngVhhdh>Rg?IIBuKjn;4pVcizKQHl$@)_xFF6cZlj#-Z3WmSVo=k31 zfJ4j1AQ9ry_`5kq+V8z2XUyM~{(ZITn_cR6Wh<&S`w?^81Y;6l>|E`q)p<{(`LvJ# zKQb~n+<6=+UCFjH5I?#gr=#(}e;(JJGOEVit}yt~5q}eR6%T8y_g&L+to97)y{YZ0 zNSFrXJ+=zf>ZF$*b-N1u7Uv*vWEHx1B36aL*I%ovz{x+K|KR3S@a3aLt)3jY-)=K{ zH!R#f{UiuGho|TRhB+F2NaK=eNU8O@X&+ZlORGr%wK*t0lXiIQT!SSioWXBY`h#i# z3>x`#4uAF4@P`2lT>2U0p!tJEp*K%q9weh6$Be{$%<^7dRB&?9w<4DR7!op>c>ty` zR6jQN4*bGEeGYvGy4{jj$Jr$>7L~^tqpB$xp&{ksRDr8oIu-gg5-MAbGujZXpEs#C zPolL~QL5a8rBm?YRDvE93o*f~`fy$^;sCYqT{U8qPB80XctSdz*H*?#Q6o-}Vu#$V`Gsy+s@= z4R%ghev;-BK6hrNJHl!#z~|cbg`<8q^TwlZUq{TBZUMboM#_v)MdOI&KZF%HBHS`^ zRevf_wMglZSX{AwT1BniF4QIlW&Iw#(!z+dR2ds(>!mRk@PI;%PV4Cl!0I92neut| zfs5B^S?$XN7j=`hbVI?>rUquq7MOFP8V@jYymCIFB_J)7@=>s)8~#EtG)*4;4dw)g zRI;cht~mvA*=p`G=SN9+vwfy>>?;bn*MI$-yFlOeMeU-gT>|VAJks^mZ7*ZeFUpzY z%@%?ccxK5U*KVL~CCEJT8JLYWm!tl_M$svs6@mk(qQ^3enTP!!#U8bv0S#IOBLYey zj@Rg4R;@#R91ZgC!u&VoJ@$*&zS4jE@L|OApPFF4TH+y67KMk)zjpwU;SxGkxqmU_ zKN;sH=~Xk5hHB~8Fh=j1umWg1?c<|e0?cBnoG7$hpzTuw3nVAKeN@RmSmy~)aP@C66gHGY1obt%eG^1RSj7aP#77i5fLTpU@Qke3?f<4-K(%+6) zzUArvLQ?W4nX@8!caRK;S^2V!tR-oxz`*)|U@*B9B>L`g5>NDFr z(Q_I+);3g#2A+%XSCT&_kdrDJ3q3ICN-#(pYmRb@Nm0w72Lo-%Sg$sG!n!E!Aer7y zu#kn5%n|rh{tfj5jAKrFf~(Jl4RbT@e&j0kFKdmaK(!T5#q;7i$2hr=$bYY?M{qUr zigNk1_st+BLSLydOmdd?uG6e~QHaCqT&^)m{zaHcm;X1#Je%BL#9nz^h#ZK4RY^nI zE0$D|0ljNzIugsu#DZrR0482Uv`Uk?G)a;~Dgu>Yetu&t8uc!a+_1#q)6^f6~Nz`LCicCXs7}g5(Nt>uYb4JpF|o7TDy%r zO@b+Y_s3n~0(rS{#&FJmt;uZU`cgZ?0fH-d3GwC>7Vce`z+g9Vx>$-kaxQbtG!gTk zC9>Kff^C@tU%r;W!se-vTRmw!IOZ;d;JFeTZVO!7*wTS(*zIS$0#Q!B7lPhO$wp=s z>E$xp+Yv&pu2!fvc9BZ4lx>^+av z6SiEFVzQGU*h_z77^=`D0TCilGkFLaDQ6hqmd60v~DO*Lh6iV4?@&@U-c{|bj4Ps!az1KK-;~i8kxiK z&RUGlsD5fJDK#Zs;uTAqj?l@6i0tC244331us9%PPJfNfg#%xa1w%5KrwuZZFPo=2 zNX7<1n}`hbA)UutYY?Sd7B~z|m-8ykr}x!l!aT&ooEA((9OT7)Eb4n~AI9|uvQ9Z~ zt*0OB=&{PUyEXhv0F&$bJe!#Km6td@Tn0C$< zJIH)nuIW{yKR(P4Xt8JKX@16C{aUC|W3)R?>+u1rm!hp;YIw~j>ki!|QI)q!$O5o# zynix?sTUz|+#+ejYIS1&_D)d{Tgt6IZo15KB?aKO2iZ{2>riur3OBdRKzHhflm@s< zz!8^OS!EN1R`Tq585m?uljNQTnT9}wBVMiK7z8E?(YuDJ<&c**$fKJ*1|Z6M;j~cX zD4V{+R=REqh4N66>pJ);l(2(bSC^%2o+=mv9hE+uVt@QY;daLjw^*E%A{rsnBRJH1d|5OBJo%-}_`5-^HX z|AGvV`&mVX{?@E_mGX8fa+EE=u}%GiU>fEf+}IR1a}(zYrE|nM1C2Hcxn1snu@^ zCrrAvIj3F9q;98v!jcy0)6BB1mVb2wb}K_mbKUY#G;PeDT9vHoor)rzPSUbcATtfa z8!jJjiuoLlm`&r7K1LEzTo1eKYxQc_sJ6Ij)OuT`Tc1!V#>0RWh;U5pjE5eKxm(0) z=BZ9ZBqS}Ms}splPw(MQM~@=nY(Ukg0OjB_;MU0*I&>tB=b?a5xD*2VxPL*HshFHj zsK&#+z@vao*HLUw3il@{tW5F5Q2QuE+22Zp^?RY^JThntW?^%i;?<#Pf#hr%bK4>& zJ%h7HS^bz*=ODp3he*a7Cw_--TJ)KSh1Vpk6#K=rvCkrRX89S4kHVU59InMG1p?@V zlQ~a?)=}oYO8$x%J#CXZ&3|rX+)Xo8Dd4?EOP!qv(LpX=MgaM`TU8J`&Zp=G2oqQ4 z#)LZ6sqH!gH$!?~SKA9PbY551--%e5Yx6WA3=lLTLrfx+X^3T**h)E#U+1r2{=Zlb0s>L zLms1jnrr5T`}|=p-^2$5~C6~ zcxaoQVOlK zqY}nuhKiI%HQ@iv0C#|NlZ&=SC&65fp49AsqL7CVz8uG=hv_?A+r`xIkAh z!NIj%>8&}Nc)bE?QF)@kk~($+#(b*#Mt#5LXQM9F!@6gsQ&jc6?yQ+BNGInJn>o&# zaHD0S-Le5UCnJ{8K4@-*jp~%N=5(IcJv(-@aHAj9)#P4{N4X6&B1l?1O<4xLZRb5YS8+F^V?HUk4AtyY!*gUD}iSVH12{j3Y&x9ojhqezoP+;J9csILvMV zS{!McU*Ts=FuHG<^@7~1O+|8G(W+SYV1JvxdBd00^M5|d7@<$zg-=_F*xI~n9qUv; zx6Licy-Vq+$?%XoxuEqta_ZrA!^@PPF3!SW zU*$u^Zhz=V5v?P09mJh>I}C>N+HZY9%s}YS&?A{%P_72|d-~Gim?~YIW)PLFL3;s#X-}~u!@8IZ;*0&a_HNLeR zX?trK+w@yLS8ur~Dm@J=&*tF4J6to7H_#1*NQCiBWg>$sbYf*9ZGml*J8i>Fr!M&l zjox+(?4bvHO@cZ(pH`?A9Q^yM1Q0D62^Xr(%?O;(NxFq zn}4%UcieWX86aFSRhLE!xoQW$6XOb&C zI)UZ*9WaJMB4F9|PZWO_EJMI_1TRwvUJ(n(tRW^zpNTnwej+NT1Iei+pJ_4*%6U-* zOiVU6+4Hml_xtNGVxJID$HofUJr1Jvd4F1BwlT%1KoCzvIp71x9DfB^+6c9xzT3%w z-Qm-vMx<1iBUNII(cqxhT&P~qvjh}WaA-puB>F~DMa=X{r=^ToL~NrEsF<2wO_gne z0cNScy$1c3EMze;5U-P9LE#kPLy=b-aA>WFtM4U5mntzC^k(iEGD_r~J&$>gr-)B}_F)=mqnl;~7u%fj3 z!P?F+kpiKZ<53KTITn}93_>i<)`>VJ-Sr{V{`EJXu|4%4c=o3ckzTew>aA&-l~+Z{ zlS)6iasfnhehsmPIKc9hFrVrhzRm1BZ8tJrrdM9r&@(n&srkGoP=CP!)Djr1%G;Hwm%zQU#;Vu ztae9KnLu#acwG&YV&s=Gj5 zM=7av_l;>LsvDH%1<%RKhxZXBUTS>7nS4=6r*o~@g@p8$uLrjunrG3M3;xE=kV?=Jpr$SV6bOD)skXPFL`E#UQ-IRsujpY z+-p-?jsKBKv%V7#WsFL-8|? zWGueXK<$=_SFQ&hAmA`@-J|Cy@tln~tDw5yv2?d9-hW`Z!_XjZ*&3hA8o9epY%yMA zZ9I)|Gj}1MSFR5uxbl!tRb8wA}UYTSU0mS|pK(z0ec@m*uTN z_GLcU+<(lXDiot^>}Y|-&uScxL*C$!3N#(ZA*^1Jjsceq8lbnN(-q2t((N8qi*iZ9 z7_M58=9C@OD^VPrce~hag!pgnCVs=A-Yuq-KwA<9L}o(fjTuofv8zQZh?LrgGp`9s z;Lg(bPTKm~M*W>TicT{J@~oky*@#K96#Rj>P=5q|DL!_)di}s~$mZrtA(3!qE^Dnq zQyPL%kh{(G3=y^dq;u)e#WKXc)!M8YBan~(NjA7L3~MD<_v5zNs*^}1zZ(J0i)>^B z!U)w2N3wD%D3UU53xyS!>}YQE*G40UQ|o22)Q`azQ*B-FQ}zs;|H(rAV*_#-{6Y~8 z)qe=OwzMuRnyb2Tls6ykZNg5!jdM$JOfbqenZB znb**3#UPADffMYmI4jX%6!gx|z!LWzzgex2x`y`|1fmeu7RHQ;m&A-|e`5YW-IBDS z0d(IppaU@cfI_@lg;HgnG8v&FUZaVzu*{uQ_BSg$0-(VaQp28V^wbg~Yn2op)_-g| z@=PPy%@SzUADSu{L+w~Eu89_SwF<>=x7*!OCm{#pH!Zb6B!=aMf+BvYIiVm8^#Wo! zxAYXI(prT_8v4ez|C0<K}Lw{bDlvVx- ziiA%2m1IZ^7T-Zq)B;67!t!X4n-f=YYr|Bw1OpUMCgLZ$2V=hX5RSj!hb4X=vd-9a zKLgP#a&VxOaePS|Xkra4kxuOOK&Ou(o$OVv>x#&r!5xg7HwH~Qy>LGsX5PGMw1PH6x{i5LrQA#K|7DUz zvr^mYhkos8MQiyrB$udMiR&NwHFWPVk5b7`eXS<#O6YW#$BN^rtbgt%N}63$u`Tl3 zdXmHz=81%=tCWj5a*i?-BHvJtY>3*M-@IMqHTV!#*p%ClerP~}eJ)>0H*IA=(|?+7 zWLWyo=TR##YBd~fGurg$suggQl0l_{WwJz#-B}T};V!ngd*%^aVx*Qv+kwEwaXi{) z`FP#XzBPHg$pST!l7FVnt+fhw;A<7t%{?$Lo1t{N0?1aZkch|3U=A8yf(Qf5f#S9f zTp3&IL?Gl^@-j^B85TJ-q?#)9D^U zrIQTpNgYGpAK?K(1vSX)rHs1x8?d(^X~o*uTbY+n7ukIJwtpz(z6n0nN>pF~x~&ivdT(j|uNC#phI7cagNwv%%g}~_u9nE%Bw>g*S3?VeHtd~7;K2d= z6r}icex2Tw&ANhbiULk2*vA^R1N5UZ8~DZ+xmAPO?^F{&2xm3>a?7yY5&+N)Y()rk z8ujxz;j4A?i+{shNh4=Y23d3bNbk-}KwG|hE5jU7%^W~mv=GF_q!3T?$ukILPgb%8 zo3J^Xu_-%eSL~Es4sM@YXQmy6go|fof{Di<@zQG$I45c$f^_tg>ZmCWg#}wc@JcvO z3X=DIIPXo)Q?XlxTj1sO?&^w*XDKKcHs{JH*pK4idw&U3HD17)b_KZazbGuD{mF~spSJ0YGh|HdDu zYjz2G_}a=v^L2!U3+;c&Dt6ksBI$@Y?ji29xhAdGzV*jLMbb>l^m#%G9v@iB6dzKz z&NlX&+kewy>!DmsM*OFcN8>~$e2B(z$l>5UTqHaW z7fDu2G1v&MU9jMwF!|d$PAWquU7de9Y-wO z5PvNP78PpdlT#$uhw~)w**rgpy60I#Svad5LF@ALXg-GOrpatn4%4{6t0v*%Ct}*Q zG60*hQO-E%#WS!!=rv=B(I_!zbn9@Im^B+m5Gy*`W|JCkNK;~MXJ05&m&w^eue=B7 zmdrynX^e_u-da+h3?{v%TSTx>H1~m#BY%>O6U-tKu?;sf-fAUHYPE#r$he70x)7#` z#!br-Cv6}>Ps=oVTGlFGwq$z&=JK7DJFeOykA~-FEm@q(<%Ca_PJ>meRe{qqb{j}u zq6-kOEkNdNm8&lrM|iMZ%;&f4rZqA=YlgC-k$?xfY@vGGiyklgJD15|8y%6|)_)P+ zUdTSF7u+tWdrh`VgkE1!Pd2)`9?AeAwkh4LGCNZTo(-Y*VP%9eP-RM)4Txa1qmwf# zAj}uhvi0Cpc;{q}#&rxi1E6k`das^zlLFDpm0!|1Nou))2aSz;@>gx#6V~6Bn&^3w zg_CG7H@5b0@i|Rl`X}?Jbhaf?k$+&czS69)w&-TY3-obIigRM2c;t8|K!8z;2^k}i znp?SetVTT)j};}G{pdgH^Zq07{q=__P#eM*DpfKfltd*{|_1?hd9X#8qzfz8dZTcbrC_oz`6 z-ga0}+eTcztQC?>-`HYn_SY{QKTO4^4TUlG=q>Q)wZW)Cp~Kq>%T8O&=};lQhhh%q zJTZ`>krN`RpMv6wLK;Y*aF>?EWIgfCJ%#b?#7O5pEEq+=(xlzm=zp&@8cj`;R=EIy z7Ht6`$^|GrYpQg&NNwMDxtb4`@DYmqrOp_&evZ~!;_!{74_Oe$Y*5$7dB@j5c=gSo zyS0W}Y?9_hp8c*NhhmE&>>H^TOkq7#waV5WKkPaOH()a@Kih#zjoLw+ROh&yTgZQO5;!!RbqpB^(uvH}X(4!H1iV;BQS4xR zSX$j)tEaef^IkY>raapps3B-{&7JNFx2?Ri?pmP42Iahs+J8sUn^^}R!y0EG*qU3l zn+?p)H`3zzvpXQx5qx3;mktk12s|*fS;tJb-BoerZLbon)T(I2EEAXl(vika!fbr* zRpOky@YWxNa-myYeRGk1WE422wl38(21ZNY#(>*e+pPVBjkta5+sG+C$VS`Vr+h~5 zz$r9E=Qqudpjtze8^ z33}JTtNKoGnTiV!#8zFS!sO|{`bNUv)$smwrmxaOq<_Vuv61NX1Pro#A~*;I={(2~ zSf5ly9x8=HnN%-B%12>j^Lq?r84GZG)~)XwYpx2f-KZBseq)N)Y5mqzZtxP zpzQAMIe-5o7GFTT4hA#NJafU4))Xzf>Cn~T^NIv2;o9YAji>^~og@dss);A@1>%ll znt_cDy_{bFMqBo+=iIZMGh(t0S<<{0>k1`CbV<_H$36s(d;Ihw(c{^G zx}_h_5)&yWVDEG*?{BgJ0iD(o{dE*PgjOD>Nj4JOX{P@OWXKL9=e~&AeMV(fLZGdb zwtpjjQC0$1FUALNxA-R!`LKNL1c;0AScZeqh9b@YD1rpeB+l-Pv*yho!Ax#}h7ua+ zXZ%C>8!pGEY}M|zyg&q2nIk?W&ngBih^!o1~399gg77U)PI3ungR{N@V(>?_hX4AOEd1o&&%MRNgHNB zpb?9vXR|{Y!i2WH32o#Eu0yS%?>aYl`FzVSHVrU=+VfCQEsZ@@+H`rTi4pwq0w(Vm zTZyf&H;w>;j`g0lEt>w%*D`iae4c11nxP7m!<@GY(it73d^lVYb!xKHB(GAv%zt$6 zV3ww6xJ%4Z7%JmoP^}vMp13n+=?lNFOr?_2oP4CR_J);UC`4jERwvqy58d&@g#DIC zgo|QC94M&`NrSdbGh5RdNQ>4u%%e0jubzJ1@wr4k8G%uH6ZpOdx!^5@TMqA zdw#dn-}O~5JR6m4lr70c&L)?P?EqbeK!%!JTm16$k7F35;$4%1Z0>+9EPoB(#B#Ew zOSUz16MUV-Sm5>a8OWpDfY$?+(Rei(`~o?%+PWFkJ67=ZM@XV2Ov)2&%7cZ}Y}gp|V_z`;I%hXn-h_7sw4t{9z#tSHvf!#s###>pNAV$6w?ePkbmoRp@~g+zMRwm zB2I~#sQIUw;Y7(v1%mXpq3GT;XN&w+U&(}Xvf!4__(W%N1sHissG%1Um%3A}SummG z)+z@XBgO^fm+sQj?ua7|vMU3aye6K!%_^cZVi8|PWEXl@=%!gwm?gl?^e52OxP@2A z21d^+F3%OIc_K)URe$C>CAZz(0#bkwP5=`dZ2{j;ipR;V z@A)bpW1gyM0iIna2`MRbu5r*PrXkfeLb)}GaMvx}f`>hClQIP>f>GhG#^dreCQVZ2 zTP3M$vhfC75nB60tq!Q=e`3tDb!YG+yJ)s0{sx@2M6pp@7k>zyG3BBm{;ry>BJ=22 z(k+(WZemj`u#*f=!SFM;40fFNfR~*+#%6wlu3hm7(pol0w|bG zvnF$9mgi+{6c{319J&~x?qK)lkBH^Zkj96p&QYc;K^&NiXddJl39Q>gIv$HJ54}CAAuhf^744 zUN6WxFU_}PyggavYg_$IzIM8KXNFL=bLBK|bFVNAvdnkdBF5Lr&aqG}W!0|oZL+jG zp-Pk}h-p-|8jsm$$;zn5@|MNMZw~473Ji7LkX`vh_QQ|Q-u|M;%WDUO=N{67H2bNL zVIW`e#bPB~kwXW6`O;B7?Ta1_2lGtPZh<;!CE6Q2VMk%r9%a3|k+xJDn`{n5bv|tV zgbQCSQHi4i=?e9zq~nSjv-DjnwEQ1ip3~N~RtDzzq}R10bZla4ViWBa?1>?7uMy5O zmwEycbAPs#y<0L7d5rpJCMhpX5=S=e2B`s!h*(Aa{7Fa!T*h?5{t!eh#Ns_N<#H82BHhjcXH!m0Y zZ9Fe;0BG|)2R=%!@$B~@Ue0$2U|&akuwe@MZhwkSy{AgLmc;+4aaaWIi1{KICnInB zKIL1gWr{!#D_uqp-!`HaY3hG*PT|h6+6keC2WW1PHTD@NBpSF5s@#GXOA?v_vIgif z;Bpv0*C{p@ky56_sZz#?^YM)8;J%-L)r5VSuut)nrZ%TzVT3E2$UZA4&MzORZ(|xv z?0?Hs^Q=_KWnjh#w@XBl*igyYk-%>AP^Mmm6fp8|;ZHI+CF${1BtRIIc9_-}5CmOR z1MgN1j4?( z!t_a;HKQ68DED5PTrW*HDgFL_-x2EGne#~M#t16CV?EVpcuR?9 zQ-O6%Bf$lAH@s948^+o_xBgcoI?2Qdd2 z=sw|k9$BwR_V`zvGVZUJNcdk8VSmaO-Kxi-*S9NP7gVeiS(CK3{1MM7erSMdRlmb@ zkd#$3&}T$U{{jy1L9wB{OkH>Cr>AZ>4etrs?3hnxEQU7G#(bvxDJA!G5k%eB#5*w5 z@m<-6LvvQ&6IwZ<82C1FIUxZ$Ak1If#?8fIEkUJ-b3~1#^mLCzI`VFKnrmiEvN%f? z+dwzawj_8Cw)fYQI#pkKFVWlFMx)(z2;e&YujyF7(7>oZ25PXxn`vAPM8IM7fYZZ8 zV*%RAvzWQ*=V%OV3Sb@C(X!`<)JrgFlK)H-_qqKZl1riH2C+bu{!w9&wXGY$$CptC z5>kJrcf*k=1pPr52?E5P#GHqP>L?L2q&Dg8u#@-jhKdqWDaykyCq~U1G8Bkb~5F6Lg@B~9y`mc%!t>TtWUJb2W zcgjrI43|)5giE(Cg2gKhW>Z6yS2%sxGfRs=Vd{a4W zb+rYXRDh$are)}~FCEEDBi{EC#AJ{i+qF5zoxK1UVX1#;rs=JR;8!qWib=#94S#<} z6Sk&!(hgA?aZjE7`1RS7w=dpEOR6KLkk+|7?uJnKHOPq?5#!%awsi{R!e9g6?`v)U zzCBE(Pr1S{YTq4){h?uH4U>P~d_Vc+n?*{j2eCDWae7D(#tGmJ zNN6lEG356FJCuZyT3Jk6%TWv|2H#L6-MNM#y~bYKp~WzX7)!^gE2lP-px21D4a4aN zpIAF>3+9Np`g%k={$W%FZk^{FU#MdAUorWSuV3=?V+j5Ss5&vYRZ~8kQQ=*qJ3OJ-0XDx8WwPS^@V*h=VDBc?I+31|TOdV)v}v(EYh;&a2@;(K$||JTFsPRb3KBpA zz7V{ZO$ri91of4C-ItpR5*dF!e>EOok?XuMEBK?W$u*oSuE|aAvzNf8qq!Fp-7-P_(B{@>Z?83;-k8s@g6tEkYSwq3-s56JZ{wP12wB&}A2I%P=L~q>TK_f!d zih|h;0>GBop&;m7k~BoH**&+#B_q0Sn0Sa^7%8TWXAzx=_9~I~@DP7IAl2fbE8*G=VT)EetWO8i7JOUV?%EAtWsx|^IjrU$dx2V0JcV+4^O5h zf5KUQp4_r(GnB7j8!-%$It(BttKfK(C4 zQcbE7Jq;S6)Tarl;C>g_E53x?PTh#n4G2^&T4=CZZ^9URRN9OdV*IT?;22u6XU|53 zP-Z?JZ@c#Ia10V8e;O-vV>zJm$_X!5?8EDI+zkCyexiL(@yNT{n<*V6cb$@LpO&H}e2465@j1xjBd&^g_j`FSTM`vKxqvc4OvK)t59-j-tOeUpm#DgsyTXByguzhlV;)`r#tSS z?qpr7gHcqr-Wc_8h(q0acfnf4@N0trgz%d)P%9HetHTG**YVhQ?%6J%)r#{r&A|V3 zAWJ{6f1sM3WZlw6NKOF?QawA(J|$N%V#df(HDP4w;&`ajC$3Uhc}igmr;v+$4d=Y} zYRQE4x~#_I)lg1LI|HUF1hGnQm13SjXqT^B!&JM@H!|1ZwdHP5)M;kZAD$AWFJ$vw za_yf6(*YA)X$ay}lf z9mGij67PhJ+ES)hU5$oenW{*wW||AYc#`MpN6ohDh@5!(?5B6HU%xy%|K{cEuOGiW z|J&==-<_W;Z_Sy0xun;B{DL->AeZ^scziZ#YbG9Fz+(BJBPKh*m&@@uxwI#|CmT^+ zu}7oytB0qv5BW&1fda2jE~@Hc3j*-!(G6SHFf@-=tf74SNG_3wa>IDIV%Ka7i|}Fd z=(pA7WqEnIWXmPp@$E&$ilX2b+spOxYFVzYMwwHA=UlLL^+DEuU_4HoI?&Y$as1Wq ze7mKSN?bf*<-;G(9<9|o_<*j6Qv(puk49-qK7=5lZFK=y;hPdpA}A`9kkOKTum)O( z!ICu%69ZKyf}Yuj9n7h+VA){w;De%eQ^GMXmmS6(pKgchL`O1K$s8OmI+>0>x?nmD z)56l=OsU9wY<3NQ5J8y{M#L8$Swx_auH?x!MD3Hn-V*2qx3CjrH$*ixJ3kQH$}sqY z#5bhuia4(8Y(4Y%R#&R?|5jC(PnKX^@UJAdG8hXpJK>xZ0~f|?m)QU-uc0pNLnCO>BttmC84l!o5gT=X1~dxZ?FqPWJv6<(3sex3 z6T-#hTgAoN@8>XjX>?D3FwT&0ghf3c?ujRSDAhH(7m(0B?H$s{3UI35(V*Y|kuH0G zzutOpI;tDO5NDqC%ul0tn$E?2&ZC-HRjeKWG#c+f>YRaGd+OVRB`auKGw}io-J6tjPG;{ z)~Q+k)w1>bk>V{o>Crr{E{mzzGZ<;?E|Ye7glAugxL zchggUj-R0}Vx;JaDjgtS_mP78q2FClUMz&?f2(&+?%z8RGtFJSoC z!aKvE=n9CZPsWT((W{d+-!@D{c^6@=9YPZCs(ccUuj;9CtdF8qj@i7TSO0L8?-g>; zyD{|6+U}CRhj%?J+oMro5UV?15CO)%rYG)yLj@H8`odCGDF3cIJ%vHJaZ4dfxN>sU zxgbCm-2`}9|FF1X%l0A}y(qOF6)<$T>tUcU2?N1?!{lyKpF_WhlM@VMLiisH8;i&8 znW&D4QVgWEs{;moJkH;Dtz(;j4aJ4%J@G{fp`>Mw@ZzE*%_n%fpE`Cke zT%(SU#jvNQSK!D@f$!b+M+cj92Y{$SEbP zozopW_dA5p-nx^Ke$e?7-nmb!=&|8JxR!2oe={w2U(XDe@k$=b%?+|rk-F}Q7Loam z-XWt|_)KI;=^iVO%sND#aD+-?09K^R$EW@usI_yvytCrw**{cw+;{wa*=#(3NJK=q z3L!vVailtwAk0)Ip2HBG$rY=AYkI-*lGKwOZ8o_e+W*9fn~skXA2%Z(Pa!M00?_29 zwCTDMiHr`Ak134s!_#T|Remyk_^?gwYe`aJs(1P5yj?7Ea}y|hFp|an3Or_l2qx#} zIF8^?vLj0BgX^RJ^<9b_9i%xVDmw*l<4*UJKYtER_u{S;5>7JSt$Q>-#{p(GsVZN2 zSzVo+;S&D3!nJ+QS1QQf-{1kwBWbcO*+*HUoP!2F& ztsy>_z!nl2e^*P)L>9zz3&q~aH@OmwfOL{o&iIPZ)#{yUI6zCJ^Z*#J;)D*f3PPSn z+lf2d#ei-)om6SUH(>j)&n*4q9bR!=exDiNgb!tnQ`(ic_}NnkC1Enf6WV9i#HAff zGYs>zS7cvY+mx&h= z9AyWC?Amj&fYNLxxzruZ8*jiZJI0VbmH(TTdUN31A>F}bSkAp?-a>qtFvu*JTHKR9 zBJ8q~Y^&gG>6ZsydQ4@+2@*tJ{C3Jf>j;|bXH3AmRed(nn8ZBc>}zEnllGLby0O* z6@aiYSwNa~;0R1Jv{gX5DZtkp)GH=`H3)LRUZ@PX_%(BNs<(aJ)#fyjuylU1Q0RGS zLt!r*O`ri12btJRz|O=EhuE30sg%_3Op`A8f1J#U<|#HCdc@qJ^M>k43rs4V<9oN0 z>{Obp*p8KQgCj-+=&F!_Y7wr%s*$OC_2Up%sJpYAH;Y4*)3vcLcrzR4soq!WuOViD zsnl!zkIdNu^;Phw39!LSQTLFr#&Tl1Gb;i%gi|>DW{PM-q$MEX|;kDU`GWL`>8&ekU zR77omnY$MfJZi!&>ktZ~18;$09kl(dpO=0b5;A{JtYehY&8*3qdAr!}n|Xn+tu+tB z8Y0RrXZ$R~=ohIxY}39xDv<2lHmo4njOXS;ix=nx%TV(;lRpwhTJWY#fme%v0IkHC zJa98h@YWfuc%2)PK-|R^fQ$2Xk*{F%Pslc3!HLK;dOS`l@T^l(;jJiVKX_${NplrFi5Ssb)zc(11`aa(+ofn(@oDr=jec7xBy^!_%oz zzxWCUv%5`C_zGF+bfmisJ%%$pbNK1m1gd|m044rNO8GaG=2KOS+S9RSi4?yj(16(z z;exML$iWRhyx)6+T}B+=9n_p)yDcr0*t)}o<+{l=d5Bg|6X{*iu)w6ex^INQ~{2UMg*Oh1_D`jZm#`gBPmjn4`wd#Lv z?Moz`HVu$wH9aRVR+G6#AE;%=;4CkLUG^@i3jQb~C?~(#)+xDvW=B58j`^Ls%gRa=u{k2=eWc8U|9=-m}kEQc}HD#B|GTq=A_!>R)1%UsA|_e%npA`vz=>m zfShK@yabm^oM%@ZrJA`qN-Z#fv1jY@#w9L5m4KNyi>Y}PHVc8=u_ba29DJM)HZ9Bs zaw!=ZzGJ-^t>w;h$v(cKm*4?MZ9uvLsJKA)Y;8OfuZ~)&d>^7?HByHpZLX5@!Pu*u zJlY61QpV#X>PvT@=fvaEXaXOtD{;Y^Q8q%h zP|@=}=AvXt5_1OgWm%KS7{M~+^@OPkSD-+Ml-oYd2fYe6> zZz$|=@?b3Jgs<|3P`&I+LS<)v%mty!cFl=^o~Qp>&zHV)Adzy0l+MBFK7AjO+PI6= zdBJgyuw0p1`D&JQtwO%2Kc;nm8vjFM4t+c?-Lu(D%!D*a-KA5O>8+ul5MZw2uwQ`| z>mMP}OO!PI2TM%d<;hHJ_hry>0FJT z)tpk#q~6>|yYOsAy2MbMYPv2nbG~fSS${H~BMOeQzM3?ZG#__~1FesLF}Jo;rvFI6 z#H;l&hZaSZBuTs=?V>L+_`8(wCr5<3Da%%Q^sH=nBcsYDXCMqmq;Ubf2Q9uEf7KB6 zTMPBOWx^koq=7-)7ouu_@fp=0&h<{uyma@}7Xd31uD-mPmkUcRpcW?K=}ctY*>Ima z(6V8|JWcwY-GQ~m*?IGSd;8`*aK}R42blSD_#De|7@okXNt6 z1}k^h+0Tq#g75Ve-Dz#GD%boXH~xM`ZaolzjM#84bua`732?G*RHa4+NHW**Qr==8 zSkX4@%;^w-X@*j_l+*}4J;8JA-zlGew#bKKDmOo{^2EwdCp*S}F4ep#2{&Sa&P1OS zpf=^5`uv2hu6UDBr5Ayqrda|inW-k)J%OLPEVdN@Xx_55cHYRExz&1cwcAQE<=ZRz zA#=vTQN7qJ`r(ZK&d8Ytc~^eO_a07c{yRyr!-Ukq)aiS z%2YE%paInzwRR~_TfkPR#e^fL#qA&Ll%Q1AG5712p3bmH5471K)DP1cxbtc%yGjII zC1PELoohSCB^HmIg-RESs}2fsQOLCro-NjE1l2vhpdev-!ZNUzL?IF&fBkyD2O8-P zwufx(GsVmunou4Tz&GaI2OPcDNT*eA4C9vx`wL>HNF|lu6*%*$P6i)a;K{8kUo-Ys z(7`;B+Yz|gintRpTNz3yr#8wRqcYD5qHCY69V#v47?qPED?h-wChUssf$(R*+2?eJ zhQQPiNdfb4qd|9gP@m&Ae_SX0t-S%6!!=Y-kSbk}VVf!n62LBLbd3^Q8=X^HGd5+z zhN$1(r&uGaY8u^C<>0$q%7=g$8eHz=ZBlyLLpNC>^H2AfB9FrvNqv!QltQG zMqSq8#%wdTLy%&|jMeBVEibm%&ns#^a77wHS|w zt+pe7{ZT(TFBZT6e<`zW+XiHXVIb7jLg4`M(&?uE@JDutLx7gnsYU3?yUVBx@-U;QL=WvIpEH|AQK^r`U#0P139iw>GSo zq9YRM66@=g+`n+eT??0W7A{L?to!wsoFo!eF;@nVArrWz)D{6v__$+^7IKAiA2ZEC z<=F}!mz*zhcd{E$J z9UD}z4cQ@;zoG+Ln!U|Qh66b@9aL2nPQ&Pcf-n4Jfv*-DDt{g~$q6bjqyLL}OHn`x zWJqq_07J3>hXli5|2j1(cP90g7c4o2ygTj_Xn5~Q0%l|e;8zcjA*CLV*{@0M*!J4- znE#x#gqaU$d(8pr_$O6IiJ!E!PzO*w-8d;!Re?WMK6GNfv7MhR@`CW66Hc~n@%qp@ zkW&<4jvBPS-+zy855Njl!7Qc^@=-Q=P=TM#9qd23csZqB=rVr?go0qJwqWk=ZZnk0 zFh~~%O05^7%7qOPtYnB_mC`&(IO-u{UM&_m4YRz2-a)tAbd< z+Hp3+PeYW!dUEZ$QC126J!y_2kWH>mkElX7I6q0VM1L6O4XgId`GZq%$0g={J=EUI zF2F-p-)ZzWeh?dkSJ<0B2T6*`yxi~kH-vweG~rMVmHNDi<9|v5JdDKnkyv=!&(e*adZBYa#R6a?SaT--%aoEmW4~(r zC2>rY5`QFeVBbxU>_!Ws@`G}Szt26d75}xz>u;snf$+cgr!Es;P#CU5$mVHt-fZD;k@7fNZn#c?2f&nJCjsf=Hh98|NY}xyM&vy zf2(6DIUbDWnX&pGMee*eRbBJtmc7HT4o^dWl7E{yA&65wXvm+U9PXHlRf{F?PFE@! z={(Z$yRQ@@X72+oFWd;7y>1iK5tFV~Udxi;F?i1%Q~TOG=W60V6!jQHC^4L1AcY7A znT{A-tvG;4qV43FUe&2y;@)HZC0gr*fE?O0p>A(uEyby>0 z=t(brKz)MR97Se4G0S%Wc`jO1n@i~m*E2Sp;L~ENHHYE|;Xsv=8aGHIinnQ6{#$U8u;=tFHJY zp=bh`xHUU1UI4|TcGezVtR0xPAoG!Ve?&&^+aodx-vul;$0-*V5O4~m(fdY3z#~=k z5l=|KW99&2g)}K)OEy2}B>sG0F^Gxf@$0=Jd?8#E!D_BlSrXZ*c29Dy16M=+E`z5)4d z)vGWbcg5LRD~54O=r)rE!e$B2DS&W6jgNdS6}a?sZd0^DqA7JMB5f{311Z2h1`V5f z?W$+|SKF>So$1|Nnbbkrke2t|? z^7Se>C*&SN5knQuw5E23iR)nIf|%?HI0;|C2yulhpX!8i4r|4DEa3Esk*1BW`>Fgb zZ`sAO4?B4TisZ|Vik>h+$H(uxx=a{x?%wOc^G}tHAs&%yQ=@r0u5vG9gH;YXaTKc= zk&{A8MxTJGB>vtb9~v!EV}Ewk532Wp5=fc!a$jF}0&6f1S4T~8v=-t?vS*@%`+&l0 zl31s9#?XKQF~82CMTJ@9Dgh-ZV5f&BGxj1 z0MImb)Mhm}-tw0_U7gRX1!*G-l*a_dX*!iUI4+ZuuWFN?0(b*z6W2$Id^k*WCd@!~ z@ZT9Y{D-Gxou5qC|E-hGP9Hol@xk?cjr;FPx5i-n7;<=U9F#^Wvrj*7o3pkZ4O zNo|=oO87EY_BP{ji;+KlF|ao9zkhYaw4773KyaK&sT_2LxF6Ts0~zy3u&kArM?Vi| zPM{>GmQM1NDN&Pi=f6FkDXhoLr2 zY0m$awCXU_<4_z@c>X$Hp5u^1Sq^uahV{Sy0bF1#J78|%$*EUy!e(cwK` z;Hi^|+?$Pd_J2^E7iepjEC(v1tD+z{)d4^-ft~M|aDQ;=%}Rwdg-@Epy7>D9ScYX~ zoRlyvnOCG(7_&)rh%nyL)pIo(|KbuG-~xjNbxMB)N_w<-KbdRK2SD{Oy1rh}d^|4E zeU(J_MsV1Lg4ea1gE2tUbmgV(>EHDE5U zu9-mkL=5ZIJPb8{QjfZ_L0G9!IZ}ak(NM1WMYuvi5FSkvmZsfkxzlc|BSH}z$rUUB znqvFS$AF>5#l@)}027bL2eQpu4Xe-)OEh5fpP*>jp3)O|w&_*Kg+aZH^han(3PYN~ ziOiLxvws0Z{Wk&6-1&h}<)WacgD~z^7VWjX;$UC|UEyx_QTA8;poI)H5;dvriIDg?)+$%K53%_cH5zp|JyR%G*a60f) z#}VSYW8Ga2d4TkfGVMipsiQY-n+j6@K~H@gNcts&`!&zuiA2v(5zZWzC z^podz?MKqh%g1Akg){L63MLDm4oXvX?9`5-V0WYlwagS$_$aoBZef!QRjm$C<(`K{OLO zuG^r_^D^d&Kq>#O3d0Y&_DBZxBd5@6@y$^aMN{HI>018;gspui7|U+2fOu1V*XF{Ofe3)TS|1TXRl8kbwlD3t z(onEbKaRzbN?%y?#Ki5fnET(J;yu_9%r(;(oNjW9sa9|hhTwme7YhGC$72d!ZF#Cy zr;JiYf}tW+CzR9#&>KozwOXD`dENq)!|W@=t)0hO>5bX3syGKlh}|saE|3KoDHMcu z9pkmffSWn;%PkIM6|o4Iwt5DZ!Pix_WmJ+SP9SNl{$Ht>hv{7r#SmC3d0l zlh*b1mV(%p{;Px&K`1HGBSsiNHiDDYqSsAtqOhNo~G%oy3EWT{iymZ3;sPZO9={3hAKAuw6y z+r*tq5JP`}Gv!LQ&pQex1@W4)Os7|~4X$*hf@dXhdO&WBSBH#$AzReyMU%8dW5HI7 zd_o#_&We^>xpAXg#~eEjJJQYa^g~0dji2jGPKSSZHx0~1?Q(- zzM7vdrU(MtkR8Z_oSM#uND+wuUrLa7sW#)~Axc{>=lm7ydSyy3ayn585eluu{h7}f zxNa|uVVI|134 zyGnoBlw4cco%6pY*X~}QlJzn8-?gU+pm;#=WfoMeMmc@!50%xA_?Jm#`2MveLzbDX zAuLGCxHh`0^{{bw+!6+(=F0&Y?3A+zIL|3gXPf{ouZ|p&U*msH1dNk8v3!BQNp;Xv z#z!C2h5MeXk^H8j`A%viLL1?i@tP^I z3j7M&uB&c{@fc0zV#3$Z52&z$s`o=u8HhA`rIIS0Zn5whLgBntm+CVTJb#uQz)d8B zV*<0Ta~?Tj(bcX@W==FRMT55GR0Oozp<_pqIz=OOiUx?!HCU|3%V`TqOVAQM$AizT zRkrzd(NReKWCBJibrP5~GeBghuVfik5#6CNWaseiB|r)zjcPEE;50wM+HU_;g^;ke!;K7~(qkk=d+1=4LJ zi>zsUkiF@x|&5~SjX0n3>5NtXbf^3Ym;r4E~o;v z4d{s^N#I`qVsC9LsyH7GXJXybVC-d z{eB4fNWM%OCyN7`81SlP+-Rn{D((rjkDEn41?(aCeQKB}9WC*Q%D)9)K6n?J;ns? zjk3`Q6+K?Ez6WYCP#3%3RIt$fPX={0cu~G$SC#lE2eP2$pr&hPTu{x1)lAnrgN_;u zkhc&l>HTMOn(B=d&*NkS@9E>(k@u?Zd;ch(S3;srLB@$IDn-w-Y8zcWgml+rutOqk z$*BUv4-H?bzGV-Ub%8Tc%fg?+kU-(lAvsbuJO~AsRr#=l zrf&J~Z1qr8?jPj{RZc06%VXTHK6vK#kebcdAU^~8&~kF4V0TK&6N@p>`D1a8m}6Rr zWLiH_k&92^mpM2RFn{};cbT{VO#6&`6%`>~a^wWRn-&qCjPs1kBw^T~cgO^r+#0?q zkK8=S=NIQk2R|8_wOKPMQ!vgnu|2dJmkBY z+6R9ISBhjS;GZi_&7c%{^Nk*084BeP6S_fH65`fjh`WnGE`LH~=)9rWyfS7YsQ@g5 z*NhFY#ypThna-~0$0hq(RCHC)y7?LNOnWqWP8eu2S$Ypj@bACRdsq7DsGDF8WYSlw z=hvH_#Kdq_m^C0d zHA!UdsymCLA%DOuWGwGa>7xnX)mmnn)*HU7iKtb)qF>;V{PRId1b~DkDmPa+B9@3) zXR7bio35gXjJrgBWp0zsjmHg|w?j^9wZP)sgU8%K%IogUuVW1&at^!mnRKd*AO|(g zRW3(q0+$SQelDy!by#es($XUies7_h*3U6-I^n?s34gAan-B>Fk_UtEGRGa(yaY}1 zR%O*tCG7Vq1H4(xDl*Vt+^kO0pq7z5=CCGBq7z6pjfprR8;%E2Z}R((z_h>VCbdsD zd$|Ix*8lld!<6e?e*e33vp;!zch+L^ZEudDZ0`x4@v?u*j=;0_elJd>PDQ+X(pLet zjjJoR;(xT!0w}Vdz=JNks42uSe2>S&#{2AeEKWheYGUP0WNrfRl>~g&h1b0DgOsgF zI(0I5gfhBFEEhY}!-cBj-xgt)Y^dFfH5@qe}>>wA)=T8^p6Nxcc@L72)*`Xx~+ zMFf_WR4hNTSotb*SKJ{z92e2SJTpnWEO-2WT2SHqxz7UE`oCEppgw@0s|zYts(6)+ zK(ERpD$HGrG!Pw_ZVUoDB^WzZ-o0+~$Qw~z@fsUeZLcHRK5(|bHvQbw^l&7CJPeJ_ zb${zWrqb<&#}PHS-O2`aTgHX0OWG$x=_I48)ni>&11TAYCinl1`>JLq<5^RInOKcl9!i#BC%uU(3J&-2wjH4M0jE? z7__7D=w?GZzLAv2Hxiwg_eec@0^GK=Zl3b>THAI&KZk)yz|EJqQa8fc+<3QDP=^)4 z?wkZr!mtShGHl~8;eyNFiW89C3xCswq9<2+d`d$Os~N??_oXcriEUPnuger7K*%QY zTi-}{`*^n#)iwLJTD}q0uBz$wY{!Z>^y9Xot86}s-#=>$fZ2@5=-X=fcnb&lkIyil z&ocnKjmYTxs(D_uFEZ&a3UU3UK_JRAAN=9eAyx4kg`rm`G4L$Y5NJ44{z414nRlefoS?0rr^0#VUWM`8@}kjw z>)v}&Uehf{NO0_S|C*6cg;UhMde^&mPS2x{-Br3bLCmGQ-s+hmk(>7@=~zMcE+?Eq z?$x{A{ps!V$h-3Dk#~6wq|e`0OT6N|?%(Jy0srq2SpUYvwDbPnTYm}}y=}{HtECJe zeA||H%a>=(#@Ul?>;3DIRzGL7X$7n8EBXrFjLAp$YNW((SabHn%a_#!I6UoJ_8L61 zt(J8AvbuQ5uG!W;PFC=`u#*yrTX(J0zuzOB!jy4eA|9_Rh7J{bgAFa zhTYJQ>eqLS?aT*ZJ=;IkUuO+1S5&N?&>da!Et=TWt)JdLSAYG?mYb@&)W0fmx!zVc z_;W!3F>N~penq+n<4tn+Ecw^nc!WZpcCLFF3!Tist8n zyk+1g?$xb23oQ1y-Q48*JMwybeag$Wm^0S&&2(Rp=sf6^5nWF1W&dd=u6e;~T~vMK zqn&4MNm64Ecj&Mq+^52K@7yYnD^o`cIrgo8{R3gC!TgZu4`0B>3+;U|{K6Yr*Ef|| z_0`#b%Dx?Ll7C?}{OxjaI83*!8Bm^6m4A-{qlLm3Z>s_^G?Pm33l2n#3X%^71;H~5 za-)=t9=%tLu7zM|rKa0D8!2qr2%^mt(t{eL2fG>2G6~LSl>6|FLrS*1yv%4NLtE+O z*9p{Y%OFixo1_3mr|q_Rj!>a|^vf^5{POVCtA|gY4u3Y;)m2v4gU2H>GK~Hf{icyZ z3Y^^%S`fO;*GW3rd|V0IuqiF_zZ1Gm3Ke4bY|G${gf%+SJEQf1gtu3d-+z%5 diff --git a/operator_ui/TAG b/operator_ui/TAG index bd6882b0f5..89f930d5e7 100644 --- a/operator_ui/TAG +++ b/operator_ui/TAG @@ -1 +1 @@ -v0.8.0-094d250 +v0.8.0-f55d4fd From 39a6f91fcaba4c51e41a33afc3cdb572af8343dd Mon Sep 17 00:00:00 2001 From: jlaveracll Date: Tue, 3 Sep 2024 14:33:23 -0300 Subject: [PATCH 276/432] [SHIP-3004] ZKSync: implement uptime feed validator (#14245) * intial commit * cleanup * Update ZKSyncValidator.sol * Update ZKSyncValidator.sol * initial commit * address feedback * Update ZKSyncSequencerUptimeFeed.sol * Update ZKSyncSequencerUptimeFeed.sol * Update ZKSyncSequencerUptimeFeed.sol * Update ZKSyncValidator.sol * Update ZKSyncValidator.sol * tmp * Add ZKSync L2EP validator contract * Update smart-peas-brake.md * cleanup * combine branches into a single one * Update ZKSyncValidator.sol * fix zksync contracts version * Revert "fix zksync contracts version" This reverts commit 9503a3195a24c7006372a4afdc783a8f18808733. * cleanup * Update ZKSyncSequencerUptimeFeed.sol * cleanup * [Bot] Update changeset file with jira issue * test update foundry solc version * try again! * cleanup unused params * l2ep auto detect solc * Fixes l2 tx request logic and adds payable * address feedback * lint * Fix zksync contracts verision * Update package.json * Update pnpm-lock.yaml * Address more feedback * Update ZKSyncValidator.sol * temp adding tests * add zksync l2ep tests * update foundry.toml * update llo-feeds gas snapshot * share interface * interface starts with I * more interfaces start with I * extract base BaseSequencerUptimeFeed * let scroll use the BaseSequencerUptimeFeed * golf base impl * let opt use base * reduce custom version to minimum * extract BaseValidator * enforce ITypeAndVersion at BaseSequencerUptimeFeed level * improve compile script * address feedback * Update BaseSequencerUptimeFeed.sol * cleaning up solidity versions * Update .gas-snapshot * temporarily adding tolerance * Adds new gas snapshot and removing tolerance * L2EP gas snapshot * Modify gas-snapshot * Modifies gas snapshot * Reverting some change * refer to internal addressaliashelper * Update l2ep.gas-snapshot * Update hardhat.config.ts * Updates gas snapshot * Updates gas snapshot * bump to 0.8.24 * rm zksync npm * Revert "rm zksync npm" This reverts commit b680be0db64dcfa3463bd3caebb7d486ba086b74. * fix versions --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> Co-authored-by: Mohamed Mehany <7327188+mohamed-mehany@users.noreply.github.com> Co-authored-by: Chris De Leon Co-authored-by: Chris De Leon <147140544+chris-de-leon-cll@users.noreply.github.com> Co-authored-by: Rens Rooimans --- .github/workflows/solidity-foundry.yml | 2 +- contracts/.changeset/heavy-balloons-cheat.md | 9 + contracts/.gas-snapshot | 254 ++++++++------- contracts/foundry.toml | 2 +- contracts/gas-snapshots/l2ep.gas-snapshot | 206 +++++++------ contracts/package.json | 1 + contracts/pnpm-lock.yaml | 9 + contracts/remappings.txt | 1 + .../scripts/native_solc_compile_all_l2ep | 39 +-- .../l2ep/dev/CrossDomainDelegateForwarder.sol | 4 +- .../v0.8/l2ep/dev/CrossDomainForwarder.sol | 4 +- .../src/v0.8/l2ep/dev/CrossDomainOwnable.sol | 4 +- contracts/src/v0.8/l2ep/dev/Flags.sol | 6 +- .../arbitrum/ArbitrumCrossDomainForwarder.sol | 12 +- .../arbitrum/ArbitrumCrossDomainGovernor.sol | 14 +- .../arbitrum/ArbitrumSequencerUptimeFeed.sol | 18 +- .../l2ep/dev/arbitrum/ArbitrumValidator.sol | 12 +- .../interfaces/DelegateForwarderInterface.sol | 13 - .../dev/interfaces/ForwarderInterface.sol | 13 - ...eInterface.sol => ICrossDomainOwnable.sol} | 5 +- .../dev/interfaces/IDelegateForwarder.sol | 10 + .../{FlagsInterface.sol => IFlags.sol} | 5 +- .../v0.8/l2ep/dev/interfaces/IForwarder.sol | 10 + ...Interface.sol => ISequencerUptimeFeed.sol} | 3 +- .../OptimismSequencerUptimeFeedInterface.sol | 7 - .../ScrollSequencerUptimeFeedInterface.sol | 7 - .../optimism/OptimismCrossDomainForwarder.sol | 12 +- .../optimism/OptimismCrossDomainGovernor.sol | 12 +- .../optimism/OptimismSequencerUptimeFeed.sol | 253 +-------------- .../l2ep/dev/optimism/OptimismValidator.sol | 94 ++---- .../dev/scroll/ScrollCrossDomainForwarder.sol | 10 +- .../dev/scroll/ScrollCrossDomainGovernor.sol | 14 +- .../dev/scroll/ScrollSequencerUptimeFeed.sol | 218 +------------ .../v0.8/l2ep/dev/scroll/ScrollValidator.sol | 56 +--- .../dev/shared/BaseSequencerUptimeFeed.sol | 231 ++++++++++++++ .../v0.8/l2ep/dev/shared/BaseValidator.sol | 59 ++++ .../dev/zksync/ZKSyncSequencerUptimeFeed.sol | 25 ++ .../v0.8/l2ep/dev/zksync/ZKSyncValidator.sol | 104 +++++++ .../l2ep/test/mocks/MockAggregatorV2V3.sol | 2 +- .../MockScrollL1CrossDomainMessenger.sol | 2 +- .../mocks/scroll/MockScrollL1MessageQueue.sol | 2 +- .../MockScrollL2CrossDomainMessenger.sol | 2 +- .../test/mocks/zksync/MockZKSyncL1Bridge.sol | 147 +++++++++ .../src/v0.8/l2ep/test/v1_0_0/L2EPTest.t.sol | 17 +- .../ArbitrumCrossDomainForwarder.t.sol | 2 +- .../ArbitrumCrossDomainGovernor.t.sol | 2 +- .../ArbitrumSequencerUptimeFeed.t.sol | 2 +- .../v1_0_0/arbitrum/ArbitrumValidator.t.sol | 2 +- .../OptimismCrossDomainForwarder.t.sol | 2 +- .../OptimismCrossDomainGovernor.t.sol | 2 +- .../OptimismSequencerUptimeFeed.t.sol | 13 +- .../v1_0_0/optimism/OptimismValidator.t.sol | 8 +- .../scroll/ScrollCrossDomainForwarder.t.sol | 2 +- .../scroll/ScrollCrossDomainGovernor.t.sol | 2 +- .../scroll/ScrollSequencerUptimeFeed.t.sol | 13 +- .../test/v1_0_0/scroll/ScrollValidator.t.sol | 8 +- .../zksync/ZKSyncSequencerUptimeFeed.t.sol | 291 ++++++++++++++++++ .../test/v1_0_0/zksync/ZKSyncValidator.t.sol | 149 +++++++++ 58 files changed, 1466 insertions(+), 962 deletions(-) create mode 100644 contracts/.changeset/heavy-balloons-cheat.md delete mode 100644 contracts/src/v0.8/l2ep/dev/interfaces/DelegateForwarderInterface.sol delete mode 100644 contracts/src/v0.8/l2ep/dev/interfaces/ForwarderInterface.sol rename contracts/src/v0.8/l2ep/dev/interfaces/{CrossDomainOwnableInterface.sol => ICrossDomainOwnable.sol} (65%) create mode 100644 contracts/src/v0.8/l2ep/dev/interfaces/IDelegateForwarder.sol rename contracts/src/v0.8/l2ep/dev/interfaces/{FlagsInterface.sol => IFlags.sol} (82%) create mode 100644 contracts/src/v0.8/l2ep/dev/interfaces/IForwarder.sol rename contracts/src/v0.8/l2ep/dev/interfaces/{ArbitrumSequencerUptimeFeedInterface.sol => ISequencerUptimeFeed.sol} (54%) delete mode 100644 contracts/src/v0.8/l2ep/dev/interfaces/OptimismSequencerUptimeFeedInterface.sol delete mode 100644 contracts/src/v0.8/l2ep/dev/interfaces/ScrollSequencerUptimeFeedInterface.sol create mode 100644 contracts/src/v0.8/l2ep/dev/shared/BaseSequencerUptimeFeed.sol create mode 100644 contracts/src/v0.8/l2ep/dev/shared/BaseValidator.sol create mode 100644 contracts/src/v0.8/l2ep/dev/zksync/ZKSyncSequencerUptimeFeed.sol create mode 100644 contracts/src/v0.8/l2ep/dev/zksync/ZKSyncValidator.sol create mode 100644 contracts/src/v0.8/l2ep/test/mocks/zksync/MockZKSyncL1Bridge.sol create mode 100644 contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncSequencerUptimeFeed.t.sol create mode 100644 contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncValidator.t.sol diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index 582503b034..4b2d7b9b96 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -31,7 +31,7 @@ jobs: { "name": "ccip", "setup": { "run-coverage": true, "min-coverage": 97.6, "run-gas-snapshot": true, "run-forge-fmt": true }}, { "name": "functions", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "keystone", "setup": { "run-coverage": true, "min-coverage": 72.8, "run-gas-snapshot": false, "run-forge-fmt": false }}, - { "name": "l2ep", "setup": { "run-coverage": true, "min-coverage": 63.4, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "l2ep", "setup": { "run-coverage": true, "min-coverage": 61.0, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "liquiditymanager", "setup": { "run-coverage": true, "min-coverage": 46.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "llo-feeds", "setup": { "run-coverage": true, "min-coverage": 49.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "operatorforwarder", "setup": { "run-coverage": true, "min-coverage": 55.7, "run-gas-snapshot": true, "run-forge-fmt": false }}, diff --git a/contracts/.changeset/heavy-balloons-cheat.md b/contracts/.changeset/heavy-balloons-cheat.md new file mode 100644 index 0000000000..c0aedb266e --- /dev/null +++ b/contracts/.changeset/heavy-balloons-cheat.md @@ -0,0 +1,9 @@ +--- +"chainlink": patch +--- + +#added Add ZKSync L2EP SequencerUptimeFeed contract +#added Add ZKSync L2EP Validator contract + + +SHIP-3004 \ No newline at end of file diff --git a/contracts/.gas-snapshot b/contracts/.gas-snapshot index 3a0354d539..e793f8ce54 100644 --- a/contracts/.gas-snapshot +++ b/contracts/.gas-snapshot @@ -1,112 +1,142 @@ -CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_NoConfigurationContract() (gas: 154832) -CapabilitiesRegistry_AddCapabilitiesTest:test_AddCapability_WithConfiguration() (gas: 178813) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 24723) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_CapabilityExists() (gas: 145703) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractDoesNotMatchInterface() (gas: 94606) -CapabilitiesRegistry_AddCapabilitiesTest:test_RevertWhen_ConfigurationContractNotDeployed() (gas: 92961) -CapabilitiesRegistry_AddDONTest:test_AddDON() (gas: 372302) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19273) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 169752) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 239789) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 249596) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 116890) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_FaultToleranceIsZero() (gas: 43358) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeAlreadyBelongsToWorkflowDON() (gas: 343924) -CapabilitiesRegistry_AddDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 180150) -CapabilitiesRegistry_AddNodeOperatorsTest:test_AddNodeOperators() (gas: 184135) -CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_CalledByNonAdmin() (gas: 17602) -CapabilitiesRegistry_AddNodeOperatorsTest:test_RevertWhen_NodeOperatorAdminAddressZero() (gas: 18498) -CapabilitiesRegistry_AddNodesTest:test_AddsNodeParams() (gas: 358448) -CapabilitiesRegistry_AddNodesTest:test_OwnerCanAddNodes() (gas: 358414) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingDuplicateP2PId() (gas: 301229) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 55174) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithInvalidNodeOperator() (gas: 24895) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_AddingNodeWithoutCapabilities() (gas: 27669) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25108) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 27408) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 27047) -CapabilitiesRegistry_AddNodesTest:test_RevertWhen_SignerAddressNotUnique() (gas: 309679) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_DeprecatesCapability() (gas: 89807) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_EmitsEvent() (gas: 89935) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CalledByNonAdmin() (gas: 22944) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 16231) -CapabilitiesRegistry_DeprecateCapabilitiesTest:test_RevertWhen_CapabilityIsDeprecated() (gas: 91264) -CapabilitiesRegistry_GetCapabilitiesTest:test_ReturnsCapabilities() (gas: 135553) -CapabilitiesRegistry_GetDONsTest:test_CorrectlyFetchesDONs() (gas: 65468) -CapabilitiesRegistry_GetDONsTest:test_DoesNotIncludeRemovedDONs() (gas: 64924) -CapabilitiesRegistry_GetHashedCapabilityTest:test_CorrectlyGeneratesHashedCapabilityId() (gas: 11428) -CapabilitiesRegistry_GetHashedCapabilityTest:test_DoesNotCauseIncorrectClashes() (gas: 13087) -CapabilitiesRegistry_GetNodeOperatorsTest:test_CorrectlyFetchesNodeOperators() (gas: 36407) -CapabilitiesRegistry_GetNodeOperatorsTest:test_DoesNotIncludeRemovedNodeOperators() (gas: 38692) -CapabilitiesRegistry_GetNodesTest:test_CorrectlyFetchesNodes() (gas: 65288) -CapabilitiesRegistry_GetNodesTest:test_DoesNotIncludeRemovedNodes() (gas: 73533) -CapabilitiesRegistry_RemoveDONsTest:test_RemovesDON() (gas: 54761) -CapabilitiesRegistry_RemoveDONsTest:test_RevertWhen_CalledByNonAdmin() (gas: 15647) -CapabilitiesRegistry_RemoveDONsTest:test_RevertWhen_DONDoesNotExist() (gas: 16550) -CapabilitiesRegistry_RemoveNodeOperatorsTest:test_RemovesNodeOperator() (gas: 36122) -CapabilitiesRegistry_RemoveNodeOperatorsTest:test_RevertWhen_CalledByNonOwner() (gas: 15816) -CapabilitiesRegistry_RemoveNodesTest:test_CanAddNodeWithSameSignerAddressAfterRemoving() (gas: 115151) -CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenDONDeleted() (gas: 287716) -CapabilitiesRegistry_RemoveNodesTest:test_CanRemoveWhenNodeNoLongerPartOfDON() (gas: 561023) -CapabilitiesRegistry_RemoveNodesTest:test_OwnerCanRemoveNodes() (gas: 73376) -CapabilitiesRegistry_RemoveNodesTest:test_RemovesNode() (gas: 75211) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 25053) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 18418) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_NodePartOfCapabilitiesDON() (gas: 385369) -CapabilitiesRegistry_RemoveNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 18408) -CapabilitiesRegistry_TypeAndVersionTest:test_TypeAndVersion() (gas: 9796) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CalledByNonAdmin() (gas: 19415) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_CapabilityDoesNotExist() (gas: 152914) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DONDoesNotExist() (gas: 17835) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DeprecatedCapabilityAdded() (gas: 222996) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateCapabilityAdded() (gas: 232804) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_DuplicateNodeAdded() (gas: 107643) -CapabilitiesRegistry_UpdateDONTest:test_RevertWhen_NodeDoesNotSupportCapability() (gas: 163357) -CapabilitiesRegistry_UpdateDONTest:test_UpdatesDON() (gas: 371909) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_CalledByNonAdminAndNonOwner() (gas: 20728) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorAdminIsZeroAddress() (gas: 20052) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorDoesNotExist() (gas: 19790) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_RevertWhen_NodeOperatorIdAndParamLengthsMismatch() (gas: 15430) -CapabilitiesRegistry_UpdateNodeOperatorTest:test_UpdatesNodeOperator() (gas: 37034) -CapabilitiesRegistry_UpdateNodesTest:test_CanUpdateParamsIfNodeSignerAddressNoLongerUsed() (gas: 256371) -CapabilitiesRegistry_UpdateNodesTest:test_OwnerCanUpdateNodes() (gas: 162166) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_AddingNodeWithInvalidCapability() (gas: 35873) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByAnotherNodeOperatorAdmin() (gas: 29200) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_CalledByNonNodeOperatorAdminAndNonOwner() (gas: 29377) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeDoesNotExist() (gas: 29199) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_NodeSignerAlreadyAssignedToAnotherNode() (gas: 31326) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_P2PIDEmpty() (gas: 29165) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByCapabilityDON() (gas: 470910) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredByWorkflowDON() (gas: 341191) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 29058) -CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 27587) -CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162220) -KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 2002057) -KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() (gas: 128934) -KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverNotContract() (gas: 130621) -KeystoneForwarder_ReportTest:test_Report_SuccessfulDelivery() (gas: 359123) -KeystoneForwarder_ReportTest:test_Report_SuccessfulRetryWithMoreGas() (gas: 423982) -KeystoneForwarder_ReportTest:test_RevertWhen_AnySignatureIsInvalid() (gas: 86348) -KeystoneForwarder_ReportTest:test_RevertWhen_AnySignerIsInvalid() (gas: 118486) -KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasDuplicateSignatures() (gas: 94516) -KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasIncorrectDON() (gas: 75930) -KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasInexistentConfigVersion() (gas: 76320) -KeystoneForwarder_ReportTest:test_RevertWhen_ReportIsMalformed() (gas: 45585) -KeystoneForwarder_ReportTest:test_RevertWhen_RetryingInvalidContractTransmission() (gas: 143354) -KeystoneForwarder_ReportTest:test_RevertWhen_RetryingSuccessfulTransmission() (gas: 353272) -KeystoneForwarder_ReportTest:test_RevertWhen_TooFewSignatures() (gas: 55292) -KeystoneForwarder_ReportTest:test_RevertWhen_TooManySignatures() (gas: 56050) -KeystoneForwarder_SetConfigTest:test_RevertWhen_ExcessSigners() (gas: 20184) -KeystoneForwarder_SetConfigTest:test_RevertWhen_FaultToleranceIsZero() (gas: 88057) -KeystoneForwarder_SetConfigTest:test_RevertWhen_InsufficientSigners() (gas: 14533) -KeystoneForwarder_SetConfigTest:test_RevertWhen_NotOwner() (gas: 88766) -KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingDuplicateSigners() (gas: 114570) -KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingZeroAddressSigner() (gas: 114225) -KeystoneForwarder_SetConfigTest:test_SetConfig_FirstTime() (gas: 1540541) -KeystoneForwarder_SetConfigTest:test_SetConfig_WhenSignersAreRemoved() (gas: 1535211) -KeystoneForwarder_TypeAndVersionTest:test_TypeAndVersion() (gas: 9641) -KeystoneRouter_SetConfigTest:test_AddForwarder_RevertWhen_NotOwner() (gas: 10978) -KeystoneRouter_SetConfigTest:test_RemoveForwarder_RevertWhen_NotOwner() (gas: 10923) -KeystoneRouter_SetConfigTest:test_RemoveForwarder_Success() (gas: 17599) -KeystoneRouter_SetConfigTest:test_Route_RevertWhen_UnauthorizedForwarder() (gas: 18552) -KeystoneRouter_SetConfigTest:test_Route_Success() (gas: 76407) \ No newline at end of file +ArbitrumCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 37568) +ArbitrumCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 12963) +ArbitrumCrossDomainForwarder_Constructor:test_InitialState() (gas: 22163) +ArbitrumCrossDomainForwarder_Forward:test_Forward() (gas: 47867) +ArbitrumCrossDomainForwarder_Forward:test_ForwardRevert() (gas: 22181) +ArbitrumCrossDomainForwarder_Forward:test_NotCallableByUnknownAddress() (gas: 16056) +ArbitrumCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 41453) +ArbitrumCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 19290) +ArbitrumCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 18637) +ArbitrumCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 13242) +ArbitrumCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 37568) +ArbitrumCrossDomainGovernor_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 12963) +ArbitrumCrossDomainGovernor_Constructor:test_InitialState() (gas: 22186) +ArbitrumCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 50003) +ArbitrumCrossDomainGovernor_Forward:test_Forward() (gas: 47896) +ArbitrumCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 24326) +ArbitrumCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 18233) +ArbitrumCrossDomainGovernor_ForwardDelegate:test_BubbleUpRevert() (gas: 19386) +ArbitrumCrossDomainGovernor_ForwardDelegate:test_CallableByCrossDomainMessengerAddressOrL1Owner() (gas: 60874) +ArbitrumCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 63003) +ArbitrumCrossDomainGovernor_ForwardDelegate:test_NotCallableByUnknownAddress() (gas: 18245) +ArbitrumCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 64368) +ArbitrumCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 41453) +ArbitrumCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 19290) +ArbitrumCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 18637) +ArbitrumCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 13242) +ArbitrumSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 104862) +ArbitrumSequencerUptimeFeed_AggregatorV3Interface:test_Return0WhenRoundDoesNotExistYet() (gas: 19967) +ArbitrumSequencerUptimeFeed_Constants:test_InitialState() (gas: 8518) +ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 604370) +ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574432) +ArbitrumSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 99629) +ArbitrumSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 15447) +ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 114625) +ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 114708) +ArbitrumValidator_Validate:test_PostSequencerOffline() (gas: 69086) +OptimismCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47160) +OptimismCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22160) +OptimismCrossDomainForwarder_Constructor:test_InitialState() (gas: 21998) +OptimismCrossDomainForwarder_Forward:test_Forward() (gas: 58281) +OptimismCrossDomainForwarder_Forward:test_ForwardRevert() (gas: 32560) +OptimismCrossDomainForwarder_Forward:test_NotCallableByUnknownAddress() (gas: 13867) +OptimismCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 48933) +OptimismCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28753) +OptimismCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16448) +OptimismCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11053) +OptimismCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47160) +OptimismCrossDomainGovernor_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22160) +OptimismCrossDomainGovernor_Constructor:test_InitialState() (gas: 22021) +OptimismCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 47846) +OptimismCrossDomainGovernor_Forward:test_Forward() (gas: 58330) +OptimismCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 32619) +OptimismCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 16047) +OptimismCrossDomainGovernor_ForwardDelegate:test_BubbleUpRevert() (gas: 29189) +OptimismCrossDomainGovernor_ForwardDelegate:test_CallableByCrossDomainMessengerAddressOrL1Owner() (gas: 72942) +OptimismCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 72947) +OptimismCrossDomainGovernor_ForwardDelegate:test_NotCallableByUnknownAddress() (gas: 16059) +OptimismCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 76156) +OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 48933) +OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28753) +OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16448) +OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11053) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72400) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17653) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17893) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17642) +OptimismSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22050) +OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601594) +OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574437) +OptimismSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67873) +OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13079) +OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23542) +OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77322) +OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 96182) +OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 96265) +OptimismValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18671) +OptimismValidator_Validate:test_PostSequencerOffline() (gas: 74790) +OptimismValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 74869) +OptimismValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15571) +ScrollCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47255) +ScrollCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22212) +ScrollCrossDomainForwarder_Constructor:test_InitialState() (gas: 21674) +ScrollCrossDomainForwarder_Forward:test_Forward() (gas: 58348) +ScrollCrossDomainForwarder_Forward:test_ForwardRevert() (gas: 32618) +ScrollCrossDomainForwarder_Forward:test_NotCallableByUnknownAddress() (gas: 13867) +ScrollCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 48999) +ScrollCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28819) +ScrollCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16448) +ScrollCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11053) +ScrollCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47255) +ScrollCrossDomainGovernor_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22212) +ScrollCrossDomainGovernor_Constructor:test_InitialState() (gas: 21697) +ScrollCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 47841) +ScrollCrossDomainGovernor_Forward:test_Forward() (gas: 58392) +ScrollCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 32674) +ScrollCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 16044) +ScrollCrossDomainGovernor_ForwardDelegate:test_BubbleUpRevert() (gas: 29250) +ScrollCrossDomainGovernor_ForwardDelegate:test_CallableByCrossDomainMessengerAddressOrL1Owner() (gas: 73009) +ScrollCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 73014) +ScrollCrossDomainGovernor_ForwardDelegate:test_NotCallableByUnknownAddress() (gas: 16056) +ScrollCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 76224) +ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 48999) +ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28819) +ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16448) +ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11053) +ScrollSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72423) +ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17653) +ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17893) +ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17642) +ScrollSequencerUptimeFeed_Constructor:test_InitialState() (gas: 173935) +ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601594) +ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574437) +ScrollSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67919) +ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13079) +ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23542) +ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77368) +ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 96228) +ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 96311) +ScrollValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18805) +ScrollValidator_Validate:test_PostSequencerOffline() (gas: 78326) +ScrollValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 78411) +ScrollValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15571) +ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 67166) +ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17653) +ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17893) +ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17642) +ZKSyncSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22054) +ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601614) +ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574443) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 61924) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13035) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 71379) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 90241) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 90324) +ZKSyncValidator_Constructor:test_ConstructingRevertedWithInvalidChainId() (gas: 103725) +ZKSyncValidator_Constructor:test_ConstructingRevertedWithZeroL1BridgeAddress() (gas: 81440) +ZKSyncValidator_Constructor:test_ConstructingRevertedWithZeroL2UpdateFeedAddress() (gas: 81497) +ZKSyncValidator_GetChainId:test_CorrectlyGetsTheChainId() (gas: 8350) +ZKSyncValidator_GetSetL2GasPerPubdataByteLimit:test_CorrectlyGetsAndUpdatesTheGasPerPubdataByteLimit() (gas: 18915) +ZKSyncValidator_Validate:test_PostSequencerOffline() (gas: 52255) +ZKSyncValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 52355) +ZKSyncValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15644) \ No newline at end of file diff --git a/contracts/foundry.toml b/contracts/foundry.toml index c755ba6437..cab8b05ba9 100644 --- a/contracts/foundry.toml +++ b/contracts/foundry.toml @@ -54,10 +54,10 @@ src = 'src/v0.8/automation' test = 'src/v0.8/automation/test' [profile.l2ep] +solc_version = '0.8.24' optimizer_runs = 1_000_000 src = 'src/v0.8/l2ep' test = 'src/v0.8/l2ep/test' -solc_version = '0.8.19' [profile.llo-feeds] optimizer_runs = 1_000_000 diff --git a/contracts/gas-snapshots/l2ep.gas-snapshot b/contracts/gas-snapshots/l2ep.gas-snapshot index 42a9aa0b35..e793f8ce54 100644 --- a/contracts/gas-snapshots/l2ep.gas-snapshot +++ b/contracts/gas-snapshots/l2ep.gas-snapshot @@ -1,122 +1,142 @@ -ArbitrumCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 37613) +ArbitrumCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 37568) ArbitrumCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 12963) -ArbitrumCrossDomainForwarder_Constructor:test_InitialState() (gas: 22196) +ArbitrumCrossDomainForwarder_Constructor:test_InitialState() (gas: 22163) ArbitrumCrossDomainForwarder_Forward:test_Forward() (gas: 47867) ArbitrumCrossDomainForwarder_Forward:test_ForwardRevert() (gas: 22181) ArbitrumCrossDomainForwarder_Forward:test_NotCallableByUnknownAddress() (gas: 16056) -ArbitrumCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 41430) -ArbitrumCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 19312) -ArbitrumCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 18671) -ArbitrumCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 13219) -ArbitrumCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 37613) +ArbitrumCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 41453) +ArbitrumCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 19290) +ArbitrumCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 18637) +ArbitrumCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 13242) +ArbitrumCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 37568) ArbitrumCrossDomainGovernor_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 12963) -ArbitrumCrossDomainGovernor_Constructor:test_InitialState() (gas: 22219) -ArbitrumCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 49980) -ArbitrumCrossDomainGovernor_Forward:test_Forward() (gas: 47918) -ArbitrumCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 24348) -ArbitrumCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 18255) +ArbitrumCrossDomainGovernor_Constructor:test_InitialState() (gas: 22186) +ArbitrumCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 50003) +ArbitrumCrossDomainGovernor_Forward:test_Forward() (gas: 47896) +ArbitrumCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 24326) +ArbitrumCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 18233) ArbitrumCrossDomainGovernor_ForwardDelegate:test_BubbleUpRevert() (gas: 19386) ArbitrumCrossDomainGovernor_ForwardDelegate:test_CallableByCrossDomainMessengerAddressOrL1Owner() (gas: 60874) -ArbitrumCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 62980) +ArbitrumCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 63003) ArbitrumCrossDomainGovernor_ForwardDelegate:test_NotCallableByUnknownAddress() (gas: 18245) -ArbitrumCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 64379) -ArbitrumCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 41430) -ArbitrumCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 19312) -ArbitrumCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 18671) -ArbitrumCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 13219) -ArbitrumSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 104994) -ArbitrumSequencerUptimeFeed_AggregatorV3Interface:test_Return0WhenRoundDoesNotExistYet() (gas: 20033) -ArbitrumSequencerUptimeFeed_Constants:test_InitialState() (gas: 8530) -ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 604414) -ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574476) -ArbitrumSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 99662) -ArbitrumSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 15424) -ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 114647) -ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 114707) +ArbitrumCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 64368) +ArbitrumCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 41453) +ArbitrumCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 19290) +ArbitrumCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 18637) +ArbitrumCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 13242) +ArbitrumSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 104862) +ArbitrumSequencerUptimeFeed_AggregatorV3Interface:test_Return0WhenRoundDoesNotExistYet() (gas: 19967) +ArbitrumSequencerUptimeFeed_Constants:test_InitialState() (gas: 8518) +ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 604370) +ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574432) +ArbitrumSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 99629) +ArbitrumSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 15447) +ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 114625) +ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 114708) ArbitrumValidator_Validate:test_PostSequencerOffline() (gas: 69086) -OptimismCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47206) +OptimismCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47160) OptimismCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22160) -OptimismCrossDomainForwarder_Constructor:test_InitialState() (gas: 22031) +OptimismCrossDomainForwarder_Constructor:test_InitialState() (gas: 21998) OptimismCrossDomainForwarder_Forward:test_Forward() (gas: 58281) OptimismCrossDomainForwarder_Forward:test_ForwardRevert() (gas: 32560) OptimismCrossDomainForwarder_Forward:test_NotCallableByUnknownAddress() (gas: 13867) -OptimismCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 48910) -OptimismCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28775) -OptimismCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16482) -OptimismCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11030) -OptimismCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47206) +OptimismCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 48933) +OptimismCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28753) +OptimismCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16448) +OptimismCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11053) +OptimismCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47160) OptimismCrossDomainGovernor_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22160) -OptimismCrossDomainGovernor_Constructor:test_InitialState() (gas: 22054) -OptimismCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 47823) -OptimismCrossDomainGovernor_Forward:test_Forward() (gas: 58352) -OptimismCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 32641) -OptimismCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 16069) +OptimismCrossDomainGovernor_Constructor:test_InitialState() (gas: 22021) +OptimismCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 47846) +OptimismCrossDomainGovernor_Forward:test_Forward() (gas: 58330) +OptimismCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 32619) +OptimismCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 16047) OptimismCrossDomainGovernor_ForwardDelegate:test_BubbleUpRevert() (gas: 29189) OptimismCrossDomainGovernor_ForwardDelegate:test_CallableByCrossDomainMessengerAddressOrL1Owner() (gas: 72942) -OptimismCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 72924) +OptimismCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 72947) OptimismCrossDomainGovernor_ForwardDelegate:test_NotCallableByUnknownAddress() (gas: 16059) -OptimismCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 76167) -OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 48910) -OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28775) -OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16482) -OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11030) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 74304) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17679) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17897) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17603) -OptimismSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22110) -OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601843) -OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574481) -OptimismSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 69730) -OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13214) -OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23632) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 79637) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 100045) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 100105) -OptimismValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18695) -OptimismValidator_Validate:test_PostSequencerOffline() (gas: 74813) +OptimismCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 76156) +OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 48933) +OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28753) +OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16448) +OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11053) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72400) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17653) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17893) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17642) +OptimismSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22050) +OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601594) +OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574437) +OptimismSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67873) +OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13079) +OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23542) +OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77322) +OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 96182) +OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 96265) +OptimismValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18671) +OptimismValidator_Validate:test_PostSequencerOffline() (gas: 74790) OptimismValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 74869) OptimismValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15571) -ScrollCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47300) +ScrollCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47255) ScrollCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22212) -ScrollCrossDomainForwarder_Constructor:test_InitialState() (gas: 21707) +ScrollCrossDomainForwarder_Constructor:test_InitialState() (gas: 21674) ScrollCrossDomainForwarder_Forward:test_Forward() (gas: 58348) ScrollCrossDomainForwarder_Forward:test_ForwardRevert() (gas: 32618) ScrollCrossDomainForwarder_Forward:test_NotCallableByUnknownAddress() (gas: 13867) -ScrollCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 48976) -ScrollCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28841) -ScrollCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16482) -ScrollCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11030) -ScrollCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47300) +ScrollCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 48999) +ScrollCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28819) +ScrollCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16448) +ScrollCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11053) +ScrollCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47255) ScrollCrossDomainGovernor_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22212) -ScrollCrossDomainGovernor_Constructor:test_InitialState() (gas: 21730) -ScrollCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 47818) -ScrollCrossDomainGovernor_Forward:test_Forward() (gas: 58414) -ScrollCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 32696) -ScrollCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 16066) +ScrollCrossDomainGovernor_Constructor:test_InitialState() (gas: 21697) +ScrollCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 47841) +ScrollCrossDomainGovernor_Forward:test_Forward() (gas: 58392) +ScrollCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 32674) +ScrollCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 16044) ScrollCrossDomainGovernor_ForwardDelegate:test_BubbleUpRevert() (gas: 29250) ScrollCrossDomainGovernor_ForwardDelegate:test_CallableByCrossDomainMessengerAddressOrL1Owner() (gas: 73009) -ScrollCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 72991) +ScrollCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 73014) ScrollCrossDomainGovernor_ForwardDelegate:test_NotCallableByUnknownAddress() (gas: 16056) -ScrollCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 76235) -ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 48976) -ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28841) -ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16482) -ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11030) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72590) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17675) +ScrollCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 76224) +ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 48999) +ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28819) +ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16448) +ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11053) +ScrollSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72423) +ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17653) ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17893) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17599) -ScrollSequencerUptimeFeed_Constructor:test_InitialState() (gas: 103508) -ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601694) -ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574481) -ScrollSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67615) -ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13214) -ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23632) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77220) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 95908) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 95968) -ScrollValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18829) -ScrollValidator_Validate:test_PostSequencerOffline() (gas: 78349) +ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17642) +ScrollSequencerUptimeFeed_Constructor:test_InitialState() (gas: 173935) +ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601594) +ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574437) +ScrollSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67919) +ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13079) +ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23542) +ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77368) +ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 96228) +ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 96311) +ScrollValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18805) +ScrollValidator_Validate:test_PostSequencerOffline() (gas: 78326) ScrollValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 78411) -ScrollValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15571) \ No newline at end of file +ScrollValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15571) +ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 67166) +ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17653) +ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17893) +ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17642) +ZKSyncSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22054) +ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601614) +ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574443) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 61924) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13035) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 71379) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 90241) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 90324) +ZKSyncValidator_Constructor:test_ConstructingRevertedWithInvalidChainId() (gas: 103725) +ZKSyncValidator_Constructor:test_ConstructingRevertedWithZeroL1BridgeAddress() (gas: 81440) +ZKSyncValidator_Constructor:test_ConstructingRevertedWithZeroL2UpdateFeedAddress() (gas: 81497) +ZKSyncValidator_GetChainId:test_CorrectlyGetsTheChainId() (gas: 8350) +ZKSyncValidator_GetSetL2GasPerPubdataByteLimit:test_CorrectlyGetsAndUpdatesTheGasPerPubdataByteLimit() (gas: 18915) +ZKSyncValidator_Validate:test_PostSequencerOffline() (gas: 52255) +ZKSyncValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 52355) +ZKSyncValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15644) \ No newline at end of file diff --git a/contracts/package.json b/contracts/package.json index 26fbd88570..ea700c87d4 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -86,6 +86,7 @@ "@openzeppelin/contracts": "4.9.3", "@openzeppelin/contracts-upgradeable": "4.9.3", "@scroll-tech/contracts": "0.1.0", + "@zksync/contracts": "git+https://github.com/matter-labs/era-contracts.git#446d391d34bdb48255d5f8fef8a8248925fc98b9", "semver": "^7.6.3" } } diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index 5c45da8ab0..237b334fc4 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -35,6 +35,9 @@ importers: '@scroll-tech/contracts': specifier: 0.1.0 version: 0.1.0 + '@zksync/contracts': + specifier: git+https://github.com/matter-labs/era-contracts.git#446d391d34bdb48255d5f8fef8a8248925fc98b9 + version: era-contracts@https://codeload.github.com/matter-labs/era-contracts/tar.gz/446d391d34bdb48255d5f8fef8a8248925fc98b9 semver: specifier: ^7.6.3 version: 7.6.3 @@ -1380,6 +1383,10 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + era-contracts@https://codeload.github.com/matter-labs/era-contracts/tar.gz/446d391d34bdb48255d5f8fef8a8248925fc98b9: + resolution: {tarball: https://codeload.github.com/matter-labs/era-contracts/tar.gz/446d391d34bdb48255d5f8fef8a8248925fc98b9} + version: 0.1.0 + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -4961,6 +4968,8 @@ snapshots: env-paths@2.2.1: {} + era-contracts@https://codeload.github.com/matter-labs/era-contracts/tar.gz/446d391d34bdb48255d5f8fef8a8248925fc98b9: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 diff --git a/contracts/remappings.txt b/contracts/remappings.txt index ec64b1b211..4ed0fcfd9a 100644 --- a/contracts/remappings.txt +++ b/contracts/remappings.txt @@ -5,3 +5,4 @@ forge-std/=src/v0.8/vendor/forge-std/src/ hardhat/=node_modules/hardhat/ @eth-optimism/=node_modules/@eth-optimism/ @scroll-tech/=node_modules/@scroll-tech/ +@zksync/=node_modules/@zksync/ diff --git a/contracts/scripts/native_solc_compile_all_l2ep b/contracts/scripts/native_solc_compile_all_l2ep index 1b9f5fb611..1f67115806 100755 --- a/contracts/scripts/native_solc_compile_all_l2ep +++ b/contracts/scripts/native_solc_compile_all_l2ep @@ -1,59 +1,38 @@ #!/usr/bin/env bash -########### -# Logging # -########### - set -e echo " ┌──────────────────────────────────────────────┐" echo " │ Compiling L2EP contracts... │" echo " └──────────────────────────────────────────────┘" -###################### -# Helper Variable(s) # -###################### - -export SOLC_VERSION="0.8.19" +SOLC_VERSION="0.8.24" +OPTIMIZE_RUNS=1000000 -SCRIPTPATH="$( - cd "$(dirname "$0")" >/dev/null 2>&1 - pwd -P -)" +SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +python3 -m pip install --require-hashes -r $SCRIPTPATH/requirements.txt +solc-select install $SOLC_VERSION +solc-select use $SOLC_VERSION ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1 cd ../ && pwd -P )" -###################### -# Helper Function(s) # -###################### - compileContract() { - local optimize_runs=1000000 local version="$1" local srcpath="$2" solc \ @openzeppelin/=$ROOT/node_modules/@openzeppelin/ \ @eth-optimism/=$ROOT/node_modules/@eth-optimism/ \ @scroll-tech/=$ROOT/node_modules/@scroll-tech/ \ - --overwrite --optimize --optimize-runs $optimize_runs --metadata-hash none \ + --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ -o $ROOT/solc/v$SOLC_VERSION/l2ep/"$version" \ - --abi --bin \ - --allow-paths $ROOT/src/v0.8,$ROOT/node_modules \ + --abi --bin --allow-paths $ROOT/src/v0.8,$ROOT/node_modules \ + --evm-version paris \ $ROOT/src/v0.8/l2ep/"$srcpath" } -################# -# Version 1.0.0 # -################# - -python3 -m pip install --require-hashes -r $SCRIPTPATH/requirements.txt - -solc-select install $SOLC_VERSION -solc-select use $SOLC_VERSION - compileContract v1_0_0 dev/arbitrum/ArbitrumValidator.sol compileContract v1_0_0 dev/arbitrum/ArbitrumSequencerUptimeFeed.sol compileContract v1_0_0 dev/arbitrum/ArbitrumCrossDomainForwarder.sol diff --git a/contracts/src/v0.8/l2ep/dev/CrossDomainDelegateForwarder.sol b/contracts/src/v0.8/l2ep/dev/CrossDomainDelegateForwarder.sol index 5dc73619af..859c6f0e7f 100644 --- a/contracts/src/v0.8/l2ep/dev/CrossDomainDelegateForwarder.sol +++ b/contracts/src/v0.8/l2ep/dev/CrossDomainDelegateForwarder.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import {CrossDomainOwnable} from "./CrossDomainOwnable.sol"; -import {DelegateForwarderInterface} from "./interfaces/DelegateForwarderInterface.sol"; +import {IDelegateForwarder} from "./interfaces/IDelegateForwarder.sol"; /** * @title CrossDomainDelegateForwarder - L1 xDomain account representation (with delegatecall support) @@ -10,4 +10,4 @@ import {DelegateForwarderInterface} from "./interfaces/DelegateForwarderInterfac * @dev Any other L2 contract which uses this contract's address as a privileged position, * can consider that position to be held by the `l1Owner` */ -abstract contract CrossDomainDelegateForwarder is DelegateForwarderInterface, CrossDomainOwnable {} +abstract contract CrossDomainDelegateForwarder is IDelegateForwarder, CrossDomainOwnable {} diff --git a/contracts/src/v0.8/l2ep/dev/CrossDomainForwarder.sol b/contracts/src/v0.8/l2ep/dev/CrossDomainForwarder.sol index 8f218f66b8..c097057f8a 100644 --- a/contracts/src/v0.8/l2ep/dev/CrossDomainForwarder.sol +++ b/contracts/src/v0.8/l2ep/dev/CrossDomainForwarder.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import {CrossDomainOwnable} from "./CrossDomainOwnable.sol"; -import {ForwarderInterface} from "./interfaces/ForwarderInterface.sol"; +import {IForwarder} from "./interfaces/IForwarder.sol"; /** * @title CrossDomainForwarder - L1 xDomain account representation @@ -10,4 +10,4 @@ import {ForwarderInterface} from "./interfaces/ForwarderInterface.sol"; * @dev Any other L2 contract which uses this contract's address as a privileged position, * can consider that position to be held by the `l1Owner` */ -abstract contract CrossDomainForwarder is ForwarderInterface, CrossDomainOwnable {} +abstract contract CrossDomainForwarder is IForwarder, CrossDomainOwnable {} diff --git a/contracts/src/v0.8/l2ep/dev/CrossDomainOwnable.sol b/contracts/src/v0.8/l2ep/dev/CrossDomainOwnable.sol index f861da32a7..c85762b6fc 100644 --- a/contracts/src/v0.8/l2ep/dev/CrossDomainOwnable.sol +++ b/contracts/src/v0.8/l2ep/dev/CrossDomainOwnable.sol @@ -2,13 +2,13 @@ pragma solidity ^0.8.0; import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; -import {CrossDomainOwnableInterface} from "./interfaces/CrossDomainOwnableInterface.sol"; +import {ICrossDomainOwnable} from "./interfaces/ICrossDomainOwnable.sol"; /** * @title The CrossDomainOwnable contract * @notice A contract with helpers for cross-domain contract ownership. */ -contract CrossDomainOwnable is CrossDomainOwnableInterface, ConfirmedOwner { +contract CrossDomainOwnable is ICrossDomainOwnable, ConfirmedOwner { address internal s_l1Owner; address internal s_l1PendingOwner; diff --git a/contracts/src/v0.8/l2ep/dev/Flags.sol b/contracts/src/v0.8/l2ep/dev/Flags.sol index 0fcd095ac8..2dc030d7d5 100644 --- a/contracts/src/v0.8/l2ep/dev/Flags.sol +++ b/contracts/src/v0.8/l2ep/dev/Flags.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.6; +pragma solidity ^0.8.24; import {SimpleReadAccessController} from "../../shared/access/SimpleReadAccessController.sol"; import {AccessControllerInterface} from "../../shared/interfaces/AccessControllerInterface.sol"; import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; /* dev dependencies - to be re/moved after audit */ -import {FlagsInterface} from "./interfaces/FlagsInterface.sol"; +import {IFlags} from "./interfaces/IFlags.sol"; /** * @title The Flags contract @@ -18,7 +18,7 @@ import {FlagsInterface} from "./interfaces/FlagsInterface.sol"; * FlagOn events you should filter for addresses you care about. */ // solhint-disable gas-custom-errors -contract Flags is ITypeAndVersion, FlagsInterface, SimpleReadAccessController { +contract Flags is ITypeAndVersion, IFlags, SimpleReadAccessController { AccessControllerInterface public raisingAccessController; AccessControllerInterface public loweringAccessController; diff --git a/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainForwarder.sol b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainForwarder.sol index 158ffcc304..0db657ee71 100644 --- a/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainForwarder.sol +++ b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainForwarder.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.24; -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; // solhint-disable-next-line no-unused-import -import {ForwarderInterface} from "../interfaces/ForwarderInterface.sol"; +import {IForwarder} from "../interfaces/IForwarder.sol"; import {CrossDomainForwarder} from "../CrossDomainForwarder.sol"; import {CrossDomainOwnable} from "../CrossDomainOwnable.sol"; @@ -17,7 +17,7 @@ import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/ut * @dev Any other L2 contract which uses this contract's address as a privileged position, * can be considered to be owned by the `l1Owner` */ -contract ArbitrumCrossDomainForwarder is TypeAndVersionInterface, CrossDomainForwarder { +contract ArbitrumCrossDomainForwarder is ITypeAndVersion, CrossDomainForwarder { /** * @notice creates a new Arbitrum xDomain Forwarder contract * @param l1OwnerAddr the L1 owner address that will be allowed to call the forward fn @@ -31,7 +31,7 @@ contract ArbitrumCrossDomainForwarder is TypeAndVersionInterface, CrossDomainFor * - ArbitrumCrossDomainForwarder 0.1.0: initial release * - ArbitrumCrossDomainForwarder 1.0.0: Use OZ Address, CrossDomainOwnable * - * @inheritdoc TypeAndVersionInterface + * @inheritdoc ITypeAndVersion */ function typeAndVersion() external pure virtual override returns (string memory) { return "ArbitrumCrossDomainForwarder 1.0.0"; @@ -46,7 +46,7 @@ contract ArbitrumCrossDomainForwarder is TypeAndVersionInterface, CrossDomainFor /** * @dev forwarded only if L2 Messenger calls with `xDomainMessageSender` being the L1 owner address - * @inheritdoc ForwarderInterface + * @inheritdoc IForwarder */ function forward(address target, bytes memory data) external virtual override onlyL1Owner { Address.functionCall(target, data, "Forwarder call reverted"); diff --git a/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainGovernor.sol b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainGovernor.sol index ebf579b849..60d9cc5266 100644 --- a/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainGovernor.sol +++ b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainGovernor.sol @@ -2,10 +2,10 @@ pragma solidity ^0.8.0; // solhint-disable-next-line no-unused-import -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; // solhint-disable-next-line no-unused-import -import {ForwarderInterface} from "../interfaces/ForwarderInterface.sol"; -import {DelegateForwarderInterface} from "../interfaces/DelegateForwarderInterface.sol"; +import {IForwarder} from "../interfaces/IForwarder.sol"; +import {IDelegateForwarder} from "../interfaces/IDelegateForwarder.sol"; import {ArbitrumCrossDomainForwarder} from "./ArbitrumCrossDomainForwarder.sol"; @@ -17,7 +17,7 @@ import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/ut * @dev Any other L2 contract which uses this contract's address as a privileged position, * can be considered to be simultaneously owned by the `l1Owner` and L2 `owner` */ -contract ArbitrumCrossDomainGovernor is DelegateForwarderInterface, ArbitrumCrossDomainForwarder { +contract ArbitrumCrossDomainGovernor is IDelegateForwarder, ArbitrumCrossDomainForwarder { /** * @notice creates a new Arbitrum xDomain Forwarder contract * @param l1OwnerAddr the L1 owner address that will be allowed to call the forward fn @@ -30,7 +30,7 @@ contract ArbitrumCrossDomainGovernor is DelegateForwarderInterface, ArbitrumCros * * - ArbitrumCrossDomainGovernor 1.0.0: initial release * - * @inheritdoc TypeAndVersionInterface + * @inheritdoc ITypeAndVersion */ function typeAndVersion() external pure virtual override returns (string memory) { return "ArbitrumCrossDomainGovernor 1.0.0"; @@ -38,7 +38,7 @@ contract ArbitrumCrossDomainGovernor is DelegateForwarderInterface, ArbitrumCros /** * @dev forwarded only if L2 Messenger calls with `msg.sender` being the L1 owner address, or called by the L2 owner - * @inheritdoc ForwarderInterface + * @inheritdoc IForwarder */ function forward(address target, bytes memory data) external override onlyLocalOrCrossDomainOwner { Address.functionCall(target, data, "Governor call reverted"); @@ -46,7 +46,7 @@ contract ArbitrumCrossDomainGovernor is DelegateForwarderInterface, ArbitrumCros /** * @dev forwarded only if L2 Messenger calls with `msg.sender` being the L1 owner address, or called by the L2 owner - * @inheritdoc DelegateForwarderInterface + * @inheritdoc IDelegateForwarder */ function forwardDelegate(address target, bytes memory data) external override onlyLocalOrCrossDomainOwner { Address.functionDelegateCall(target, data, "Governor delegatecall reverted"); diff --git a/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol index 63952ab7ba..678bef3a85 100644 --- a/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; +pragma solidity ^0.8.24; import {AddressAliasHelper} from "../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; import {AggregatorInterface} from "../../../shared/interfaces/AggregatorInterface.sol"; import {AggregatorV3Interface} from "../../../shared/interfaces/AggregatorV3Interface.sol"; import {AggregatorV2V3Interface} from "../../../shared/interfaces/AggregatorV2V3Interface.sol"; -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; -import {FlagsInterface} from "../interfaces/FlagsInterface.sol"; -import {ArbitrumSequencerUptimeFeedInterface} from "../interfaces/ArbitrumSequencerUptimeFeedInterface.sol"; +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; +import {IFlags} from "../interfaces/IFlags.sol"; +import {ISequencerUptimeFeed} from "../interfaces/ISequencerUptimeFeed.sol"; import {SimpleReadAccessController} from "../../../shared/access/SimpleReadAccessController.sol"; /** @@ -18,8 +18,8 @@ import {SimpleReadAccessController} from "../../../shared/access/SimpleReadAcces */ contract ArbitrumSequencerUptimeFeed is AggregatorV2V3Interface, - ArbitrumSequencerUptimeFeedInterface, - TypeAndVersionInterface, + ISequencerUptimeFeed, + ITypeAndVersion, SimpleReadAccessController { /// @dev Round info (for uptime history) @@ -62,7 +62,7 @@ contract ArbitrumSequencerUptimeFeed is /// @dev Flags contract to raise/lower flags on, during status transitions // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i - FlagsInterface public immutable FLAGS; + IFlags public immutable FLAGS; /// @dev L1 address address private s_l1Sender; /// @dev s_latestRoundId == 0 means this contract is uninitialized. @@ -76,7 +76,7 @@ contract ArbitrumSequencerUptimeFeed is constructor(address flagsAddress, address l1SenderAddress) { _setL1Sender(l1SenderAddress); - FLAGS = FlagsInterface(flagsAddress); + FLAGS = IFlags(flagsAddress); } /** @@ -120,7 +120,7 @@ contract ArbitrumSequencerUptimeFeed is * * - ArbitrumSequencerUptimeFeed 1.0.0: initial release * - * @inheritdoc TypeAndVersionInterface + * @inheritdoc ITypeAndVersion */ function typeAndVersion() external pure virtual override returns (string memory) { return "ArbitrumSequencerUptimeFeed 1.0.0"; diff --git a/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumValidator.sol b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumValidator.sol index edcb62cae9..05f9349eb6 100644 --- a/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumValidator.sol +++ b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumValidator.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.24; import {AggregatorValidatorInterface} from "../../../shared/interfaces/AggregatorValidatorInterface.sol"; -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol"; import {SimpleWriteAccessController} from "../../../shared/access/SimpleWriteAccessController.sol"; /* ./dev dependencies - to be moved from ./dev after audit */ -import {ArbitrumSequencerUptimeFeedInterface} from "../interfaces/ArbitrumSequencerUptimeFeedInterface.sol"; +import {ISequencerUptimeFeed} from "../interfaces/ISequencerUptimeFeed.sol"; import {IArbitrumDelayedInbox} from "../interfaces/IArbitrumDelayedInbox.sol"; import {AddressAliasHelper} from "../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; import {ArbSys} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; @@ -20,7 +20,7 @@ import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/ut * - Gas configuration is controlled by a configurable external SimpleWriteAccessController * - Funds on the contract are managed by the owner */ -contract ArbitrumValidator is TypeAndVersionInterface, AggregatorValidatorInterface, SimpleWriteAccessController { +contract ArbitrumValidator is ITypeAndVersion, AggregatorValidatorInterface, SimpleWriteAccessController { enum PaymentStrategy { L1, L2 @@ -124,7 +124,7 @@ contract ArbitrumValidator is TypeAndVersionInterface, AggregatorValidatorInterf * - ArbitrumValidator 2.0.0: change how maxSubmissionCost is calculated when sending cross chain messages * - now calls `calculateRetryableSubmissionFee` instead of inlining equation to estimate * the maxSubmissionCost required to send the message to L2 - * @inheritdoc TypeAndVersionInterface + * @inheritdoc ITypeAndVersion */ function typeAndVersion() external pure virtual override returns (string memory) { return "ArbitrumValidator 2.0.0"; @@ -264,7 +264,7 @@ contract ArbitrumValidator is TypeAndVersionInterface, AggregatorValidatorInterf // Excess gas on L2 will be sent to the L2 xDomain alias address of this contract address refundAddr = L2_ALIAS; // Encode the ArbitrumSequencerUptimeFeed call - bytes4 selector = ArbitrumSequencerUptimeFeedInterface.updateStatus.selector; + bytes4 selector = ISequencerUptimeFeed.updateStatus.selector; bool status = currentAnswer == ANSWER_SEQ_OFFLINE; uint64 timestamp = uint64(block.timestamp); // Encode `status` and `timestamp` diff --git a/contracts/src/v0.8/l2ep/dev/interfaces/DelegateForwarderInterface.sol b/contracts/src/v0.8/l2ep/dev/interfaces/DelegateForwarderInterface.sol deleted file mode 100644 index 498dee586c..0000000000 --- a/contracts/src/v0.8/l2ep/dev/interfaces/DelegateForwarderInterface.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -/// @title DelegateForwarderInterface - forwards a delegatecall to a target, under some conditions -// solhint-disable-next-line interface-starts-with-i -interface DelegateForwarderInterface { - /** - * @notice forward delegatecalls the `target` with `data` - * @param target contract address to be delegatecalled - * @param data to send to target contract - */ - function forwardDelegate(address target, bytes memory data) external; -} diff --git a/contracts/src/v0.8/l2ep/dev/interfaces/ForwarderInterface.sol b/contracts/src/v0.8/l2ep/dev/interfaces/ForwarderInterface.sol deleted file mode 100644 index a6db32b923..0000000000 --- a/contracts/src/v0.8/l2ep/dev/interfaces/ForwarderInterface.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -/// @title ForwarderInterface - forwards a call to a target, under some conditions -// solhint-disable-next-line interface-starts-with-i -interface ForwarderInterface { - /** - * @notice forward calls the `target` with `data` - * @param target contract address to be called - * @param data to send to target contract - */ - function forward(address target, bytes memory data) external; -} diff --git a/contracts/src/v0.8/l2ep/dev/interfaces/CrossDomainOwnableInterface.sol b/contracts/src/v0.8/l2ep/dev/interfaces/ICrossDomainOwnable.sol similarity index 65% rename from contracts/src/v0.8/l2ep/dev/interfaces/CrossDomainOwnableInterface.sol rename to contracts/src/v0.8/l2ep/dev/interfaces/ICrossDomainOwnable.sol index ddcfded9ca..d5a01386e3 100644 --- a/contracts/src/v0.8/l2ep/dev/interfaces/CrossDomainOwnableInterface.sol +++ b/contracts/src/v0.8/l2ep/dev/interfaces/ICrossDomainOwnable.sol @@ -1,9 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -/// @title CrossDomainOwnableInterface - A contract with helpers for cross-domain contract ownership -// solhint-disable-next-line interface-starts-with-i -interface CrossDomainOwnableInterface { +/// @title A contract with helpers for cross-domain contract ownership +interface ICrossDomainOwnable { event L1OwnershipTransferRequested(address indexed from, address indexed to); event L1OwnershipTransferred(address indexed from, address indexed to); diff --git a/contracts/src/v0.8/l2ep/dev/interfaces/IDelegateForwarder.sol b/contracts/src/v0.8/l2ep/dev/interfaces/IDelegateForwarder.sol new file mode 100644 index 0000000000..3df532b94c --- /dev/null +++ b/contracts/src/v0.8/l2ep/dev/interfaces/IDelegateForwarder.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title Forwards a delegatecall to a target, under some conditions +interface IDelegateForwarder { + /// @notice forward delegatecalls the `target` with `data` + /// @param target contract address to be delegatecalled + /// @param data to send to target contract + function forwardDelegate(address target, bytes memory data) external; +} diff --git a/contracts/src/v0.8/l2ep/dev/interfaces/FlagsInterface.sol b/contracts/src/v0.8/l2ep/dev/interfaces/IFlags.sol similarity index 82% rename from contracts/src/v0.8/l2ep/dev/interfaces/FlagsInterface.sol rename to contracts/src/v0.8/l2ep/dev/interfaces/IFlags.sol index b6491a9d60..6ae5a3a3f3 100644 --- a/contracts/src/v0.8/l2ep/dev/interfaces/FlagsInterface.sol +++ b/contracts/src/v0.8/l2ep/dev/interfaces/IFlags.sol @@ -1,8 +1,7 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.6; +pragma solidity ^0.8.0; -// solhint-disable-next-line interface-starts-with-i -interface FlagsInterface { +interface IFlags { function getFlag(address) external view returns (bool); function getFlags(address[] calldata) external view returns (bool[] memory); diff --git a/contracts/src/v0.8/l2ep/dev/interfaces/IForwarder.sol b/contracts/src/v0.8/l2ep/dev/interfaces/IForwarder.sol new file mode 100644 index 0000000000..374e381064 --- /dev/null +++ b/contracts/src/v0.8/l2ep/dev/interfaces/IForwarder.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title Forwards a call to a target, under some conditions +interface IForwarder { + /// @notice forward calls the `target` with `data` + /// @param target contract address to be called + /// @param data to send to target contract + function forward(address target, bytes memory data) external; +} diff --git a/contracts/src/v0.8/l2ep/dev/interfaces/ArbitrumSequencerUptimeFeedInterface.sol b/contracts/src/v0.8/l2ep/dev/interfaces/ISequencerUptimeFeed.sol similarity index 54% rename from contracts/src/v0.8/l2ep/dev/interfaces/ArbitrumSequencerUptimeFeedInterface.sol rename to contracts/src/v0.8/l2ep/dev/interfaces/ISequencerUptimeFeed.sol index 57b507bae8..879dc06d37 100644 --- a/contracts/src/v0.8/l2ep/dev/interfaces/ArbitrumSequencerUptimeFeedInterface.sol +++ b/contracts/src/v0.8/l2ep/dev/interfaces/ISequencerUptimeFeed.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -// solhint-disable-next-line interface-starts-with-i -interface ArbitrumSequencerUptimeFeedInterface { +interface ISequencerUptimeFeed { function updateStatus(bool status, uint64 timestamp) external; } diff --git a/contracts/src/v0.8/l2ep/dev/interfaces/OptimismSequencerUptimeFeedInterface.sol b/contracts/src/v0.8/l2ep/dev/interfaces/OptimismSequencerUptimeFeedInterface.sol deleted file mode 100644 index a08a1b2620..0000000000 --- a/contracts/src/v0.8/l2ep/dev/interfaces/OptimismSequencerUptimeFeedInterface.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -// solhint-disable-next-line interface-starts-with-i -interface OptimismSequencerUptimeFeedInterface { - function updateStatus(bool status, uint64 timestamp) external; -} diff --git a/contracts/src/v0.8/l2ep/dev/interfaces/ScrollSequencerUptimeFeedInterface.sol b/contracts/src/v0.8/l2ep/dev/interfaces/ScrollSequencerUptimeFeedInterface.sol deleted file mode 100644 index 89327fbc3a..0000000000 --- a/contracts/src/v0.8/l2ep/dev/interfaces/ScrollSequencerUptimeFeedInterface.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.19; - -// solhint-disable-next-line interface-starts-with-i -interface ScrollSequencerUptimeFeedInterface { - function updateStatus(bool status, uint64 timestamp) external; -} diff --git a/contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainForwarder.sol b/contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainForwarder.sol index 37d9260b47..1d03788696 100644 --- a/contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainForwarder.sol +++ b/contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainForwarder.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.24; -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; // solhint-disable-next-line no-unused-import -import {ForwarderInterface} from "../interfaces/ForwarderInterface.sol"; +import {IForwarder} from "../interfaces/IForwarder.sol"; /* ./dev dependencies - to be moved from ./dev after audit */ import {CrossDomainForwarder} from "../CrossDomainForwarder.sol"; @@ -18,7 +18,7 @@ import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/ut * @dev Any other L2 contract which uses this contract's address as a privileged position, * can be considered to be owned by the `l1Owner` */ -contract OptimismCrossDomainForwarder is TypeAndVersionInterface, CrossDomainForwarder { +contract OptimismCrossDomainForwarder is ITypeAndVersion, CrossDomainForwarder { // OVM_L2CrossDomainMessenger is a precompile usually deployed to 0x4200000000000000000000000000000000000007 // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i iOVM_CrossDomainMessenger private immutable OVM_CROSS_DOMAIN_MESSENGER; @@ -40,7 +40,7 @@ contract OptimismCrossDomainForwarder is TypeAndVersionInterface, CrossDomainFor * - OptimismCrossDomainForwarder 0.1.0: initial release * - OptimismCrossDomainForwarder 1.0.0: Use OZ Address, CrossDomainOwnable * - * @inheritdoc TypeAndVersionInterface + * @inheritdoc ITypeAndVersion */ function typeAndVersion() external pure virtual override returns (string memory) { return "OptimismCrossDomainForwarder 1.0.0"; @@ -48,7 +48,7 @@ contract OptimismCrossDomainForwarder is TypeAndVersionInterface, CrossDomainFor /** * @dev forwarded only if L2 Messenger calls with `xDomainMessageSender` being the L1 owner address - * @inheritdoc ForwarderInterface + * @inheritdoc IForwarder */ function forward(address target, bytes memory data) external virtual override onlyL1Owner { Address.functionCall(target, data, "Forwarder call reverted"); diff --git a/contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainGovernor.sol b/contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainGovernor.sol index ad78094691..6a41bd98f0 100644 --- a/contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainGovernor.sol +++ b/contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainGovernor.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.24; -import {DelegateForwarderInterface} from "../interfaces/DelegateForwarderInterface.sol"; +import {IDelegateForwarder} from "../interfaces/IDelegateForwarder.sol"; // solhint-disable-next-line no-unused-import -import {ForwarderInterface} from "../interfaces/ForwarderInterface.sol"; +import {IForwarder} from "../interfaces/IForwarder.sol"; import {OptimismCrossDomainForwarder} from "./OptimismCrossDomainForwarder.sol"; @@ -16,7 +16,7 @@ import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/ut * @dev Any other L2 contract which uses this contract's address as a privileged position, * can be considered to be simultaneously owned by the `l1Owner` and L2 `owner` */ -contract OptimismCrossDomainGovernor is DelegateForwarderInterface, OptimismCrossDomainForwarder { +contract OptimismCrossDomainGovernor is IDelegateForwarder, OptimismCrossDomainForwarder { /** * @notice creates a new Optimism xDomain Forwarder contract * @param crossDomainMessengerAddr the xDomain bridge messenger (Optimism bridge L2) contract address @@ -39,7 +39,7 @@ contract OptimismCrossDomainGovernor is DelegateForwarderInterface, OptimismCros /** * @dev forwarded only if L2 Messenger calls with `msg.sender` being the L1 owner address, or called by the L2 owner - * @inheritdoc ForwarderInterface + * @inheritdoc IForwarder */ function forward(address target, bytes memory data) external override onlyLocalOrCrossDomainOwner { Address.functionCall(target, data, "Governor call reverted"); @@ -47,7 +47,7 @@ contract OptimismCrossDomainGovernor is DelegateForwarderInterface, OptimismCros /** * @dev forwarded only if L2 Messenger calls with `msg.sender` being the L1 owner address, or called by the L2 owner - * @inheritdoc DelegateForwarderInterface + * @inheritdoc IDelegateForwarder */ function forwardDelegate(address target, bytes memory data) external override onlyLocalOrCrossDomainOwner { Address.functionDelegateCall(target, data, "Governor delegatecall reverted"); diff --git a/contracts/src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol index 947b1b0bf5..0e6f9c52f2 100644 --- a/contracts/src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol @@ -1,12 +1,8 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; +pragma solidity ^0.8.19; + +import {BaseSequencerUptimeFeed} from "../shared/BaseSequencerUptimeFeed.sol"; -import {AggregatorInterface} from "../../../shared/interfaces/AggregatorInterface.sol"; -import {AggregatorV3Interface} from "../../../shared/interfaces/AggregatorV3Interface.sol"; -import {AggregatorV2V3Interface} from "../../../shared/interfaces/AggregatorV2V3Interface.sol"; -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; -import {OptimismSequencerUptimeFeedInterface} from "./../interfaces/OptimismSequencerUptimeFeedInterface.sol"; -import {SimpleReadAccessController} from "../../../shared/access/SimpleReadAccessController.sol"; import {IL2CrossDomainMessenger} from "@eth-optimism/contracts/L2/messaging/IL2CrossDomainMessenger.sol"; /** @@ -14,50 +10,8 @@ import {IL2CrossDomainMessenger} from "@eth-optimism/contracts/L2/messaging/IL2C * @notice L2 contract that receives status updates from a specific L1 address, * records a new answer if the status changed */ -contract OptimismSequencerUptimeFeed is - AggregatorV2V3Interface, - OptimismSequencerUptimeFeedInterface, - TypeAndVersionInterface, - SimpleReadAccessController -{ - /// @dev Round info (for uptime history) - struct Round { - bool status; - uint64 startedAt; - uint64 updatedAt; - } - - /// @dev Packed state struct to save sloads - struct FeedState { - uint80 latestRoundId; - bool latestStatus; - uint64 startedAt; - uint64 updatedAt; - } - - /// @notice Sender is not the L2 messenger - error InvalidSender(); - /// @notice Replacement for AggregatorV3Interface "No data present" - error NoDataPresent(); - - event L1SenderTransferred(address indexed from, address indexed to); - /// @dev Emitted when an `updateStatus` call is ignored due to unchanged status or stale timestamp - event UpdateIgnored(bool latestStatus, uint64 latestTimestamp, bool incomingStatus, uint64 incomingTimestamp); - /// @dev Emitted when a updateStatus is called without the status changing - event RoundUpdated(int256 status, uint64 updatedAt); - - // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables - uint8 public constant override decimals = 0; - // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables - string public constant override description = "L2 Sequencer Uptime Status Feed"; - // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables - uint256 public constant override version = 1; - - /// @dev L1 address - address private s_l1Sender; - /// @dev s_latestRoundId == 0 means this contract is uninitialized. - FeedState private s_feedState = FeedState({latestRoundId: 0, latestStatus: false, startedAt: 0, updatedAt: 0}); - mapping(uint80 => Round) private s_rounds; +contract OptimismSequencerUptimeFeed is BaseSequencerUptimeFeed { + string public constant override typeAndVersion = "OptimismSequencerUptimeFeed 1.1.0-dev"; // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i IL2CrossDomainMessenger private immutable s_l2CrossDomainMessenger; @@ -67,202 +21,19 @@ contract OptimismSequencerUptimeFeed is * @param l2CrossDomainMessengerAddr Address of the L2CrossDomainMessenger contract * @param initialStatus The initial status of the feed */ - constructor(address l1SenderAddress, address l2CrossDomainMessengerAddr, bool initialStatus) { - _setL1Sender(l1SenderAddress); + constructor( + address l1SenderAddress, + address l2CrossDomainMessengerAddr, + bool initialStatus + ) BaseSequencerUptimeFeed(l1SenderAddress, initialStatus) { s_l2CrossDomainMessenger = IL2CrossDomainMessenger(l2CrossDomainMessengerAddr); - uint64 timestamp = uint64(block.timestamp); - - // Initialise roundId == 1 as the first round - _recordRound(1, initialStatus, timestamp); - } - - /** - * @notice Check if a roundId is valid in this current contract state - * @dev Mainly used for AggregatorV2V3Interface functions - * @param roundId Round ID to check - */ - function _isValidRound(uint256 roundId) private view returns (bool) { - return roundId > 0 && roundId <= type(uint80).max && s_feedState.latestRoundId >= roundId; - } - - /** - * @notice versions: - * - * - OptimismSequencerUptimeFeed 1.0.0: initial release - * - * @inheritdoc TypeAndVersionInterface - */ - function typeAndVersion() external pure virtual override returns (string memory) { - return "OptimismSequencerUptimeFeed 1.0.0"; - } - - /// @return L1 sender address - function l1Sender() public view virtual returns (address) { - return s_l1Sender; - } - - /** - * @notice Set the allowed L1 sender for this contract to a new L1 sender - * @dev Can be disabled by setting the L1 sender as `address(0)`. Accessible only by owner. - * @param to new L1 sender that will be allowed to call `updateStatus` on this contract - */ - function transferL1Sender(address to) external virtual onlyOwner { - _setL1Sender(to); - } - - /// @notice internal method that stores the L1 sender - function _setL1Sender(address to) private { - address from = s_l1Sender; - if (from != to) { - s_l1Sender = to; - emit L1SenderTransferred(from, to); - } - } - - /** - * @dev Returns an AggregatorV2V3Interface compatible answer from status flag - * - * @param status The status flag to convert to an aggregator-compatible answer - */ - function _getStatusAnswer(bool status) private pure returns (int256) { - return status ? int256(1) : int256(0); - } - - /** - * @notice Helper function to record a round and set the latest feed state. - * - * @param roundId The round ID to record - * @param status Sequencer status - * @param timestamp The L1 block timestamp of status update - */ - function _recordRound(uint80 roundId, bool status, uint64 timestamp) private { - uint64 updatedAt = uint64(block.timestamp); - Round memory nextRound = Round(status, timestamp, updatedAt); - FeedState memory feedState = FeedState(roundId, status, timestamp, updatedAt); - - s_rounds[roundId] = nextRound; - s_feedState = feedState; - - emit NewRound(roundId, msg.sender, timestamp); - emit AnswerUpdated(_getStatusAnswer(status), roundId, timestamp); } - /** - * @notice Helper function to update when a round was last updated - * - * @param roundId The round ID to update - * @param status Sequencer status - */ - function _updateRound(uint80 roundId, bool status) private { - uint64 updatedAt = uint64(block.timestamp); - s_rounds[roundId].updatedAt = updatedAt; - s_feedState.updatedAt = updatedAt; - emit RoundUpdated(_getStatusAnswer(status), updatedAt); - } - - /** - * @notice Record a new status and timestamp if it has changed since the last round. - * @dev This function will revert if not called from `l1Sender` via the L1->L2 messenger. - * - * @param status Sequencer status - * @param timestamp Block timestamp of status update - */ - function updateStatus(bool status, uint64 timestamp) external override { - FeedState memory feedState = s_feedState; + function _validateSender(address l1Sender) internal view override { if ( - msg.sender != address(s_l2CrossDomainMessenger) || s_l2CrossDomainMessenger.xDomainMessageSender() != s_l1Sender + msg.sender != address(s_l2CrossDomainMessenger) || s_l2CrossDomainMessenger.xDomainMessageSender() != l1Sender ) { revert InvalidSender(); } - - // Ignore if latest recorded timestamp is newer - if (feedState.startedAt > timestamp) { - emit UpdateIgnored(feedState.latestStatus, feedState.startedAt, status, timestamp); - return; - } - - if (feedState.latestStatus == status) { - _updateRound(feedState.latestRoundId, status); - } else { - feedState.latestRoundId += 1; - _recordRound(feedState.latestRoundId, status, timestamp); - } - } - - /// @inheritdoc AggregatorInterface - function latestAnswer() external view override checkAccess returns (int256) { - FeedState memory feedState = s_feedState; - return _getStatusAnswer(feedState.latestStatus); - } - - /// @inheritdoc AggregatorInterface - function latestTimestamp() external view override checkAccess returns (uint256) { - FeedState memory feedState = s_feedState; - return feedState.startedAt; - } - - /// @inheritdoc AggregatorInterface - function latestRound() external view override checkAccess returns (uint256) { - FeedState memory feedState = s_feedState; - return feedState.latestRoundId; - } - - /// @inheritdoc AggregatorInterface - function getAnswer(uint256 roundId) external view override checkAccess returns (int256) { - if (_isValidRound(roundId)) { - return _getStatusAnswer(s_rounds[uint80(roundId)].status); - } - - revert NoDataPresent(); - } - - /// @inheritdoc AggregatorInterface - function getTimestamp(uint256 roundId) external view override checkAccess returns (uint256) { - if (_isValidRound(roundId)) { - return s_rounds[uint80(roundId)].startedAt; - } - - revert NoDataPresent(); - } - - /// @inheritdoc AggregatorV3Interface - function getRoundData( - uint80 _roundId - ) - public - view - override - checkAccess - returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) - { - if (_isValidRound(_roundId)) { - Round memory round = s_rounds[_roundId]; - answer = _getStatusAnswer(round.status); - startedAt = uint256(round.startedAt); - roundId = _roundId; - updatedAt = uint256(round.updatedAt); - answeredInRound = roundId; - } else { - revert NoDataPresent(); - } - return (roundId, answer, startedAt, updatedAt, answeredInRound); - } - - /// @inheritdoc AggregatorV3Interface - function latestRoundData() - external - view - override - checkAccess - returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) - { - FeedState memory feedState = s_feedState; - - roundId = feedState.latestRoundId; - answer = _getStatusAnswer(feedState.latestStatus); - startedAt = feedState.startedAt; - updatedAt = feedState.updatedAt; - answeredInRound = roundId; - return (roundId, answer, startedAt, updatedAt, answeredInRound); } } diff --git a/contracts/src/v0.8/l2ep/dev/optimism/OptimismValidator.sol b/contracts/src/v0.8/l2ep/dev/optimism/OptimismValidator.sol index a54a56ee60..cf5222f017 100644 --- a/contracts/src/v0.8/l2ep/dev/optimism/OptimismValidator.sol +++ b/contracts/src/v0.8/l2ep/dev/optimism/OptimismValidator.sol @@ -1,82 +1,28 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; -import {AggregatorValidatorInterface} from "../../../shared/interfaces/AggregatorValidatorInterface.sol"; -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; -import {OptimismSequencerUptimeFeedInterface} from "./../interfaces/OptimismSequencerUptimeFeedInterface.sol"; +import {ISequencerUptimeFeed} from "./../interfaces/ISequencerUptimeFeed.sol"; -import {SimpleWriteAccessController} from "../../../shared/access/SimpleWriteAccessController.sol"; +import {BaseValidator} from "../shared/BaseValidator.sol"; import {IL1CrossDomainMessenger} from "@eth-optimism/contracts/L1/messaging/IL1CrossDomainMessenger.sol"; -/** - * @title OptimismValidator - makes cross chain call to update the Sequencer Uptime Feed on L2 - */ -contract OptimismValidator is TypeAndVersionInterface, AggregatorValidatorInterface, SimpleWriteAccessController { - int256 private constant ANSWER_SEQ_OFFLINE = 1; - uint32 private s_gasLimit; - - // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i - address public immutable L1_CROSS_DOMAIN_MESSENGER_ADDRESS; - // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i - address public immutable L2_UPTIME_FEED_ADDR; - - /** - * @notice emitted when gas cost to spend on L2 is updated - * @param gasLimit updated gas cost - */ - event GasLimitUpdated(uint32 gasLimit); - - /** - * @param l1CrossDomainMessengerAddress address the L1CrossDomainMessenger contract address - * @param l2UptimeFeedAddr the address of the OptimismSequencerUptimeFeed contract address - * @param gasLimit the gasLimit to use for sending a message from L1 to L2 - */ - constructor(address l1CrossDomainMessengerAddress, address l2UptimeFeedAddr, uint32 gasLimit) { - // solhint-disable-next-line gas-custom-errors - require(l1CrossDomainMessengerAddress != address(0), "Invalid xDomain Messenger address"); - // solhint-disable-next-line gas-custom-errors - require(l2UptimeFeedAddr != address(0), "Invalid OptimismSequencerUptimeFeed contract address"); - L1_CROSS_DOMAIN_MESSENGER_ADDRESS = l1CrossDomainMessengerAddress; - L2_UPTIME_FEED_ADDR = l2UptimeFeedAddr; - s_gasLimit = gasLimit; - } - - /** - * @notice versions: - * - * - OptimismValidator 0.1.0: initial release - * - OptimismValidator 1.0.0: change target of L2 sequencer status update - * - now calls `updateStatus` on an L2 OptimismSequencerUptimeFeed contract instead of - * directly calling the Flags contract - * - * @inheritdoc TypeAndVersionInterface - */ - function typeAndVersion() external pure virtual override returns (string memory) { - return "OptimismValidator 1.0.0"; - } - - /** - * @notice sets the new gas cost to spend when sending cross chain message - * @param gasLimit the updated gas cost - */ - function setGasLimit(uint32 gasLimit) external onlyOwner { - s_gasLimit = gasLimit; - emit GasLimitUpdated(gasLimit); - } - - /** - * @notice fetches the gas cost of sending a cross chain message - */ - function getGasLimit() external view returns (uint32) { - return s_gasLimit; - } - - /** - * @notice validate method sends an xDomain L2 tx to update Uptime Feed contract on L2. - * @dev A message is sent using the L1CrossDomainMessenger. This method is accessed controlled. - * @param currentAnswer new aggregator answer - value of 1 considers the sequencer offline. - */ +/// @title OptimismValidator - makes cross chain call to update the Sequencer Uptime Feed on L2 +contract OptimismValidator is BaseValidator { + string public constant override typeAndVersion = "OptimismValidator 1.1.0-dev"; + + /// @param l1CrossDomainMessengerAddress address the L1CrossDomainMessenger contract address + /// @param l2UptimeFeedAddr the address of the OptimismSequencerUptimeFeed contract address + /// @param gasLimit the gasLimit to use for sending a message from L1 to L2 + constructor( + address l1CrossDomainMessengerAddress, + address l2UptimeFeedAddr, + uint32 gasLimit + ) BaseValidator(l1CrossDomainMessengerAddress, l2UptimeFeedAddr, gasLimit) {} + + /// @notice validate method sends an xDomain L2 tx to update Uptime Feed contract on L2. + /// @dev A message is sent using the L1CrossDomainMessenger. This method is accessed controlled. + /// @param currentAnswer new aggregator answer - value of 1 considers the sequencer offline. function validate( uint256 /* previousRoundId */, int256 /* previousAnswer */, @@ -84,7 +30,7 @@ contract OptimismValidator is TypeAndVersionInterface, AggregatorValidatorInterf int256 currentAnswer ) external override checkAccess returns (bool) { // Encode the OptimismSequencerUptimeFeed call - bytes4 selector = OptimismSequencerUptimeFeedInterface.updateStatus.selector; + bytes4 selector = ISequencerUptimeFeed.updateStatus.selector; bool status = currentAnswer == ANSWER_SEQ_OFFLINE; uint64 timestamp = uint64(block.timestamp); // Encode `status` and `timestamp` diff --git a/contracts/src/v0.8/l2ep/dev/scroll/ScrollCrossDomainForwarder.sol b/contracts/src/v0.8/l2ep/dev/scroll/ScrollCrossDomainForwarder.sol index 4ec51fc693..c70bc794af 100644 --- a/contracts/src/v0.8/l2ep/dev/scroll/ScrollCrossDomainForwarder.sol +++ b/contracts/src/v0.8/l2ep/dev/scroll/ScrollCrossDomainForwarder.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; -import {ForwarderInterface} from "../interfaces/ForwarderInterface.sol"; +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; +import {IForwarder} from "../interfaces/IForwarder.sol"; import {CrossDomainForwarder} from "../CrossDomainForwarder.sol"; import {CrossDomainOwnable} from "../CrossDomainOwnable.sol"; @@ -14,7 +14,7 @@ import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/ut /// @notice L2 Contract which receives messages from a specific L1 address and transparently forwards them to the destination. /// @dev Any other L2 contract which uses this contract's address as a privileged position, /// can be considered to be owned by the `l1Owner` -contract ScrollCrossDomainForwarder is TypeAndVersionInterface, CrossDomainForwarder { +contract ScrollCrossDomainForwarder is ITypeAndVersion, CrossDomainForwarder { string public constant override typeAndVersion = "ScrollCrossDomainForwarder 1.0.0"; address internal immutable i_scrollCrossDomainMessenger; @@ -28,7 +28,7 @@ contract ScrollCrossDomainForwarder is TypeAndVersionInterface, CrossDomainForwa } /// @dev forwarded only if L2 Messenger calls with `xDomainMessageSender` being the L1 owner address - /// @inheritdoc ForwarderInterface + /// @inheritdoc IForwarder function forward(address target, bytes memory data) external override onlyL1Owner { Address.functionCall(target, data, "Forwarder call reverted"); } diff --git a/contracts/src/v0.8/l2ep/dev/scroll/ScrollCrossDomainGovernor.sol b/contracts/src/v0.8/l2ep/dev/scroll/ScrollCrossDomainGovernor.sol index f7d13059fe..dae621e9b0 100644 --- a/contracts/src/v0.8/l2ep/dev/scroll/ScrollCrossDomainGovernor.sol +++ b/contracts/src/v0.8/l2ep/dev/scroll/ScrollCrossDomainGovernor.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; -import {DelegateForwarderInterface} from "../interfaces/DelegateForwarderInterface.sol"; +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; +import {IDelegateForwarder} from "../interfaces/IDelegateForwarder.sol"; // solhint-disable-next-line no-unused-import -import {ForwarderInterface} from "../interfaces/ForwarderInterface.sol"; +import {IForwarder} from "../interfaces/IForwarder.sol"; import {CrossDomainForwarder} from "../CrossDomainForwarder.sol"; import {CrossDomainOwnable} from "../CrossDomainOwnable.sol"; @@ -16,7 +16,7 @@ import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/ut /// @notice L2 Contract which receives messages from a specific L1 address and transparently forwards them to the destination. /// @dev Any other L2 contract which uses this contract's address as a privileged position, /// can be considered to be simultaneously owned by the `l1Owner` and L2 `owner` -contract ScrollCrossDomainGovernor is DelegateForwarderInterface, TypeAndVersionInterface, CrossDomainForwarder { +contract ScrollCrossDomainGovernor is IDelegateForwarder, ITypeAndVersion, CrossDomainForwarder { string public constant override typeAndVersion = "ScrollCrossDomainGovernor 1.0.0"; address internal immutable i_scrollCrossDomainMessenger; @@ -29,13 +29,13 @@ contract ScrollCrossDomainGovernor is DelegateForwarderInterface, TypeAndVersion i_scrollCrossDomainMessenger = address(crossDomainMessengerAddr); } - /// @inheritdoc ForwarderInterface + /// @inheritdoc IForwarder /// @dev forwarded only if L2 Messenger calls with `msg.sender` being the L1 owner address, or called by the L2 owner function forward(address target, bytes memory data) external override onlyLocalOrCrossDomainOwner { Address.functionCall(target, data, "Governor call reverted"); } - /// @inheritdoc DelegateForwarderInterface + /// @inheritdoc IDelegateForwarder /// @dev forwarded only if L2 Messenger calls with `msg.sender` being the L1 owner address, or called by the L2 owner function forwardDelegate(address target, bytes memory data) external override onlyLocalOrCrossDomainOwner { Address.functionDelegateCall(target, data, "Governor delegatecall reverted"); diff --git a/contracts/src/v0.8/l2ep/dev/scroll/ScrollSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/dev/scroll/ScrollSequencerUptimeFeed.sol index e60e8703b7..40f2941aa6 100644 --- a/contracts/src/v0.8/l2ep/dev/scroll/ScrollSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/dev/scroll/ScrollSequencerUptimeFeed.sol @@ -1,66 +1,16 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; -import {ScrollSequencerUptimeFeedInterface} from "../interfaces/ScrollSequencerUptimeFeedInterface.sol"; -import {AggregatorInterface} from "../../../shared/interfaces/AggregatorInterface.sol"; -import {AggregatorV3Interface} from "../../../shared/interfaces/AggregatorV3Interface.sol"; -import {AggregatorV2V3Interface} from "../../../shared/interfaces/AggregatorV2V3Interface.sol"; -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; - -import {SimpleReadAccessController} from "../../../shared/access/SimpleReadAccessController.sol"; +import {BaseSequencerUptimeFeed} from "../shared/BaseSequencerUptimeFeed.sol"; import {IL2ScrollMessenger} from "@scroll-tech/contracts/L2/IL2ScrollMessenger.sol"; /// @title ScrollSequencerUptimeFeed - L2 sequencer uptime status aggregator /// @notice L2 contract that receives status updates, and records a new answer if the status changed -contract ScrollSequencerUptimeFeed is - AggregatorV2V3Interface, - ScrollSequencerUptimeFeedInterface, - TypeAndVersionInterface, - SimpleReadAccessController -{ - string public constant override typeAndVersion = "ScrollSequencerUptimeFeed 1.0.0"; - - /// @dev Round info (for uptime history) - struct Round { - bool status; - uint64 startedAt; - uint64 updatedAt; - } - - /// @dev Packed state struct to save sloads - struct FeedState { - uint80 latestRoundId; - bool latestStatus; - uint64 startedAt; - uint64 updatedAt; - } - - /// @notice Sender is not the L2 messenger - error InvalidSender(); - /// @notice Replacement for AggregatorV3Interface "No data present" - error NoDataPresent(); - /// @notice Address must not be the zero address +contract ScrollSequencerUptimeFeed is BaseSequencerUptimeFeed { error ZeroAddress(); - event L1SenderTransferred(address indexed from, address indexed to); - /// @dev Emitted when an `updateStatus` call is ignored due to unchanged status or stale timestamp - event UpdateIgnored(bool latestStatus, uint64 latestTimestamp, bool incomingStatus, uint64 incomingTimestamp); - /// @dev Emitted when a updateStatus is called without the status changing - event RoundUpdated(int256 status, uint64 updatedAt); - - // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables - uint8 public constant override decimals = 0; - // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables - string public constant override description = "L2 Sequencer Uptime Status Feed"; - // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables - uint256 public constant override version = 1; - - /// @dev L1 address - address private s_l1Sender; - /// @dev s_latestRoundId == 0 means this contract is uninitialized. - FeedState private s_feedState = FeedState({latestRoundId: 0, latestStatus: false, startedAt: 0, updatedAt: 0}); - mapping(uint80 roundId => Round round) private s_rounds; + string public constant override typeAndVersion = "ScrollSequencerUptimeFeed 1.1.0-dev"; // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i IL2ScrollMessenger private immutable s_l2CrossDomainMessenger; @@ -68,169 +18,23 @@ contract ScrollSequencerUptimeFeed is /// @param l1SenderAddress Address of the L1 contract that is permissioned to call this contract /// @param l2CrossDomainMessengerAddr Address of the L2CrossDomainMessenger contract /// @param initialStatus The initial status of the feed - constructor(address l1SenderAddress, address l2CrossDomainMessengerAddr, bool initialStatus) { + constructor( + address l1SenderAddress, + address l2CrossDomainMessengerAddr, + bool initialStatus + ) BaseSequencerUptimeFeed(l1SenderAddress, initialStatus) { if (l2CrossDomainMessengerAddr == address(0)) { revert ZeroAddress(); } - _setL1Sender(l1SenderAddress); s_l2CrossDomainMessenger = IL2ScrollMessenger(l2CrossDomainMessengerAddr); - - // Initialise roundId == 1 as the first round - _recordRound(1, initialStatus, uint64(block.timestamp)); - } - - /// @notice Check if a roundId is valid in this current contract state - /// @dev Mainly used for AggregatorV2V3Interface functions - /// @param roundId Round ID to check - function _isValidRound(uint256 roundId) private view returns (bool) { - return roundId > 0 && roundId <= type(uint80).max && s_feedState.latestRoundId >= roundId; - } - - /// @return L1 sender address - function l1Sender() public view virtual returns (address) { - return s_l1Sender; } - /// @notice Set the allowed L1 sender for this contract to a new L1 sender - /// @dev Can be disabled by setting the L1 sender as `address(0)`. Accessible only by owner. - /// @param to new L1 sender that will be allowed to call `updateStatus` on this contract - function transferL1Sender(address to) external virtual onlyOwner { - _setL1Sender(to); - } - - /// @notice internal method that stores the L1 sender - function _setL1Sender(address to) private { - address from = s_l1Sender; - if (from != to) { - s_l1Sender = to; - emit L1SenderTransferred(from, to); - } - } - - /// @dev Returns an AggregatorV2V3Interface compatible answer from status flag - /// @param status The status flag to convert to an aggregator-compatible answer - function _getStatusAnswer(bool status) private pure returns (int256) { - return status ? int256(1) : int256(0); - } - - /// @notice Helper function to record a round and set the latest feed state. - /// @param roundId The round ID to record - /// @param status Sequencer status - /// @param timestamp The L1 block timestamp of status update - function _recordRound(uint80 roundId, bool status, uint64 timestamp) private { - s_feedState = FeedState(roundId, status, timestamp, uint64(block.timestamp)); - s_rounds[roundId] = Round(status, timestamp, uint64(block.timestamp)); - - emit NewRound(roundId, msg.sender, timestamp); - emit AnswerUpdated(_getStatusAnswer(status), roundId, timestamp); - } - - /// @notice Helper function to update when a round was last updated - /// @param roundId The round ID to update - /// @param status Sequencer status - function _updateRound(uint80 roundId, bool status) private { - s_feedState.updatedAt = uint64(block.timestamp); - s_rounds[roundId].updatedAt = uint64(block.timestamp); - emit RoundUpdated(_getStatusAnswer(status), uint64(block.timestamp)); - } - - /// @notice Record a new status and timestamp if it has changed since the last round. - /// @dev This function will revert if not called from `l1Sender` via the L1->L2 messenger. - /// - /// @param status Sequencer status - /// @param timestamp Block timestamp of status update - function updateStatus(bool status, uint64 timestamp) external override { - FeedState memory feedState = s_feedState; - + function _validateSender(address l1Sender) internal view override { if ( - msg.sender != address(s_l2CrossDomainMessenger) || s_l2CrossDomainMessenger.xDomainMessageSender() != s_l1Sender + msg.sender != address(s_l2CrossDomainMessenger) || s_l2CrossDomainMessenger.xDomainMessageSender() != l1Sender ) { revert InvalidSender(); } - - // Ignore if latest recorded timestamp is newer - if (feedState.startedAt > timestamp) { - emit UpdateIgnored(feedState.latestStatus, feedState.startedAt, status, timestamp); - return; - } - - if (feedState.latestStatus == status) { - _updateRound(feedState.latestRoundId, status); - } else { - feedState.latestRoundId += 1; - _recordRound(feedState.latestRoundId, status, timestamp); - } - } - - /// @inheritdoc AggregatorInterface - function latestAnswer() external view override checkAccess returns (int256) { - return _getStatusAnswer(s_feedState.latestStatus); - } - - /// @inheritdoc AggregatorInterface - function latestTimestamp() external view override checkAccess returns (uint256) { - return s_feedState.startedAt; - } - - /// @inheritdoc AggregatorInterface - function latestRound() external view override checkAccess returns (uint256) { - return s_feedState.latestRoundId; - } - - /// @inheritdoc AggregatorInterface - function getAnswer(uint256 roundId) external view override checkAccess returns (int256) { - if (!_isValidRound(roundId)) { - revert NoDataPresent(); - } - - return _getStatusAnswer(s_rounds[uint80(roundId)].status); - } - - /// @inheritdoc AggregatorInterface - function getTimestamp(uint256 roundId) external view override checkAccess returns (uint256) { - if (!_isValidRound(roundId)) { - revert NoDataPresent(); - } - - return s_rounds[uint80(roundId)].startedAt; - } - - /// @inheritdoc AggregatorV3Interface - function getRoundData( - uint80 _roundId - ) - public - view - override - checkAccess - returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) - { - if (!_isValidRound(_roundId)) { - revert NoDataPresent(); - } - - Round memory round = s_rounds[_roundId]; - - return (_roundId, _getStatusAnswer(round.status), uint256(round.startedAt), uint256(round.updatedAt), _roundId); - } - - /// @inheritdoc AggregatorV3Interface - function latestRoundData() - external - view - override - checkAccess - returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) - { - FeedState memory feedState = s_feedState; - - return ( - feedState.latestRoundId, - _getStatusAnswer(feedState.latestStatus), - feedState.startedAt, - feedState.updatedAt, - feedState.latestRoundId - ); } } diff --git a/contracts/src/v0.8/l2ep/dev/scroll/ScrollValidator.sol b/contracts/src/v0.8/l2ep/dev/scroll/ScrollValidator.sol index 9df4a12ac6..b009c80fdf 100644 --- a/contracts/src/v0.8/l2ep/dev/scroll/ScrollValidator.sol +++ b/contracts/src/v0.8/l2ep/dev/scroll/ScrollValidator.sol @@ -1,71 +1,31 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; -import {AggregatorValidatorInterface} from "../../../shared/interfaces/AggregatorValidatorInterface.sol"; -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; -import {ScrollSequencerUptimeFeedInterface} from "../interfaces/ScrollSequencerUptimeFeedInterface.sol"; +import {ISequencerUptimeFeed} from "../interfaces/ISequencerUptimeFeed.sol"; -import {SimpleWriteAccessController} from "../../../shared/access/SimpleWriteAccessController.sol"; +import {BaseValidator} from "../shared/BaseValidator.sol"; import {IL1MessageQueue} from "@scroll-tech/contracts/L1/rollup/IL1MessageQueue.sol"; import {IL1ScrollMessenger} from "@scroll-tech/contracts/L1/IL1ScrollMessenger.sol"; /// @title ScrollValidator - makes cross chain call to update the Sequencer Uptime Feed on L2 -contract ScrollValidator is TypeAndVersionInterface, AggregatorValidatorInterface, SimpleWriteAccessController { - // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i - address public immutable L1_CROSS_DOMAIN_MESSENGER_ADDRESS; - // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i - address public immutable L2_UPTIME_FEED_ADDR; +contract ScrollValidator is BaseValidator { + string public constant override typeAndVersion = "ScrollValidator 1.1.0-dev"; + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i address public immutable L1_MSG_QUEUE_ADDR; - string public constant override typeAndVersion = "ScrollValidator 1.0.0"; - int256 private constant ANSWER_SEQ_OFFLINE = 1; - uint32 private s_gasLimit; - - /// @notice emitted when gas cost to spend on L2 is updated - /// @param gasLimit updated gas cost - event GasLimitUpdated(uint32 gasLimit); - - /// @param l1CrossDomainMessengerAddress address the L1CrossDomainMessenger contract address - /// @param l2UptimeFeedAddr the address of the ScrollSequencerUptimeFeed contract address - /// @param gasLimit the gasLimit to use for sending a message from L1 to L2 constructor( address l1CrossDomainMessengerAddress, address l2UptimeFeedAddr, address l1MessageQueueAddr, uint32 gasLimit - ) { - // solhint-disable-next-line gas-custom-errors - require(l1CrossDomainMessengerAddress != address(0), "Invalid xDomain Messenger address"); + ) BaseValidator(l1CrossDomainMessengerAddress, l2UptimeFeedAddr, gasLimit) { // solhint-disable-next-line gas-custom-errors require(l1MessageQueueAddr != address(0), "Invalid L1 message queue address"); - // solhint-disable-next-line gas-custom-errors - require(l2UptimeFeedAddr != address(0), "Invalid ScrollSequencerUptimeFeed contract address"); - L1_CROSS_DOMAIN_MESSENGER_ADDRESS = l1CrossDomainMessengerAddress; - L2_UPTIME_FEED_ADDR = l2UptimeFeedAddr; L1_MSG_QUEUE_ADDR = l1MessageQueueAddr; - s_gasLimit = gasLimit; - } - - /// @notice sets the new gas cost to spend when sending cross chain message - /// @param gasLimit the updated gas cost - function setGasLimit(uint32 gasLimit) external onlyOwner { - s_gasLimit = gasLimit; - emit GasLimitUpdated(gasLimit); } - /// @notice fetches the gas cost of sending a cross chain message - function getGasLimit() external view returns (uint32) { - return s_gasLimit; - } - - /// @notice makes this contract payable - /// @dev receives funds: - /// - to use them (if configured) to pay for L2 execution on L1 - /// - when withdrawing funds from L2 xDomain alias address (pay for L2 execution on L2) - receive() external payable {} - /// @notice validate method sends an xDomain L2 tx to update Uptime Feed contract on L2. /// @dev A message is sent using the L1CrossDomainMessenger. This method is accessed controlled. /// @param currentAnswer new aggregator answer - value of 1 considers the sequencer offline. @@ -82,7 +42,7 @@ contract ScrollValidator is TypeAndVersionInterface, AggregatorValidatorInterfac L2_UPTIME_FEED_ADDR, 0, abi.encodeWithSelector( - ScrollSequencerUptimeFeedInterface.updateStatus.selector, + ISequencerUptimeFeed.updateStatus.selector, currentAnswer == ANSWER_SEQ_OFFLINE, uint64(block.timestamp) ), diff --git a/contracts/src/v0.8/l2ep/dev/shared/BaseSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/dev/shared/BaseSequencerUptimeFeed.sol new file mode 100644 index 0000000000..15c2050456 --- /dev/null +++ b/contracts/src/v0.8/l2ep/dev/shared/BaseSequencerUptimeFeed.sol @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; +import {AggregatorInterface} from "../../../shared/interfaces/AggregatorInterface.sol"; +import {AggregatorV3Interface} from "../../../shared/interfaces/AggregatorV3Interface.sol"; +import {AggregatorV2V3Interface} from "../../../shared/interfaces/AggregatorV2V3Interface.sol"; +import {ISequencerUptimeFeed} from "./../interfaces/ISequencerUptimeFeed.sol"; + +import {SimpleReadAccessController} from "../../../shared/access/SimpleReadAccessController.sol"; + +/// @title L2 sequencer uptime status aggregator +/// @notice L2 contract that receives status updates from a specific L1 address, +/// records a new answer if the status changed +abstract contract BaseSequencerUptimeFeed is + ITypeAndVersion, + AggregatorV2V3Interface, + ISequencerUptimeFeed, + SimpleReadAccessController +{ + /// @dev Round info for uptime history + struct Round { + uint64 startedAt; // ─╮ The timestamp at which the round started + uint64 updatedAt; // │ The timestamp at which the round was updated + bool status; // ──────╯ The sequencer status for the round + } + + struct FeedState { + uint80 latestRoundId; // ─╮ The ID of the latest round + uint64 startedAt; // │ The date at which the latest round started + uint64 updatedAt; // │ The date at which the latest round was updated + bool latestStatus; // ────╯ The status of the latest round + } + + /// @notice Sender is not the L2 messenger + error InvalidSender(); + /// @notice Replacement for AggregatorV3Interface "No data present" + error NoDataPresent(); + + event L1SenderTransferred(address indexed from, address indexed to); + /// @dev Emitted when an `updateStatus` call is ignored due to unchanged status or stale timestamp + event UpdateIgnored(bool latestStatus, uint64 latestTimestamp, bool incomingStatus, uint64 incomingTimestamp); + /// @dev Emitted when a updateStatus is called without the status changing + event RoundUpdated(int256 status, uint64 updatedAt); + + // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables + uint8 public constant override decimals = 0; + // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables + string public constant override description = "L2 Sequencer Uptime Status Feed"; + // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables + uint256 public constant override version = 1; + + /// @dev L1 address + address private s_l1Sender; + /// @dev s_latestRoundId == 0 means this contract is uninitialized. + FeedState private s_feedState = FeedState({latestRoundId: 0, latestStatus: false, startedAt: 0, updatedAt: 0}); + mapping(uint80 roundId => Round round) private s_rounds; + + /// @param l1SenderAddress Address of the L1 contract that is permissioned to call this contract + /// @param initialStatus The initial status of the feed + constructor(address l1SenderAddress, bool initialStatus) { + // We neet to allow l1SenderAddress to be zero because this contract is deployed first + // After deploying the validator contract, this contract will be updated with the correct L1 sender address + _setL1Sender(l1SenderAddress); + + // Initialise roundId == 1 as the first round + _recordRound(1, initialStatus, uint64(block.timestamp)); + } + + /// @notice Check if a roundId is valid in this current contract state + /// @dev Mainly used for AggregatorV2V3Interface functions + /// @param roundId Round ID to check + function _isValidRound(uint256 roundId) private view returns (bool) { + return roundId > 0 && roundId <= type(uint80).max && s_feedState.latestRoundId >= roundId; + } + + /// @return L1 sender address + function l1Sender() public view virtual returns (address) { + return s_l1Sender; + } + + /// @notice Set the allowed L1 sender for this contract to a new L1 sender + /// @dev Can be disabled by setting the L1 sender as `address(0)`. Accessible only by owner. + /// @param to new L1 sender that will be allowed to call `updateStatus` on this contract + function transferL1Sender(address to) external virtual onlyOwner { + _setL1Sender(to); + } + + /// @notice internal method that stores the L1 sender + function _setL1Sender(address newSender) internal { + address oldSender = s_l1Sender; + if (oldSender != newSender) { + s_l1Sender = newSender; + emit L1SenderTransferred(oldSender, newSender); + } + } + + /// @dev Returns an AggregatorV2V3Interface compatible answer from status flag + /// @param status The status flag to convert to an aggregator-compatible answer + function _getStatusAnswer(bool status) internal pure returns (int256) { + return status ? int256(1) : int256(0); + } + + /// @notice Helper function to record a round and set the latest feed state. + /// @param roundId The round ID to record + /// @param status Sequencer status + /// @param timestamp The L1 block timestamp of status update + function _recordRound(uint80 roundId, bool status, uint64 timestamp) internal { + s_rounds[roundId] = Round({status: status, startedAt: timestamp, updatedAt: uint64(block.timestamp)}); + s_feedState = FeedState({ + latestRoundId: roundId, + latestStatus: status, + startedAt: timestamp, + updatedAt: uint64(block.timestamp) + }); + + emit NewRound(roundId, msg.sender, timestamp); + emit AnswerUpdated(_getStatusAnswer(status), roundId, timestamp); + } + + /// @notice Helper function to update when a round was last updated + /// @param roundId The round ID to update + /// @param status Sequencer status + function _updateRound(uint80 roundId, bool status) internal { + s_rounds[roundId].updatedAt = uint64(block.timestamp); + s_feedState.updatedAt = uint64(block.timestamp); + emit RoundUpdated(_getStatusAnswer(status), uint64(block.timestamp)); + } + + function _getFeedState() internal view returns (FeedState memory) { + return s_feedState; + } + + /// @inheritdoc AggregatorInterface + function latestAnswer() external view override checkAccess returns (int256) { + return _getStatusAnswer(s_feedState.latestStatus); + } + + /// @inheritdoc AggregatorInterface + function latestTimestamp() external view override checkAccess returns (uint256) { + return s_feedState.startedAt; + } + + /// @inheritdoc AggregatorInterface + function latestRound() external view override checkAccess returns (uint256) { + return s_feedState.latestRoundId; + } + + /// @inheritdoc AggregatorInterface + function getAnswer(uint256 roundId) external view override checkAccess returns (int256) { + if (!_isValidRound(roundId)) { + revert NoDataPresent(); + } + + return _getStatusAnswer(s_rounds[uint80(roundId)].status); + } + + /// @inheritdoc AggregatorInterface + function getTimestamp(uint256 roundId) external view override checkAccess returns (uint256) { + if (!_isValidRound(roundId)) { + revert NoDataPresent(); + } + + return s_rounds[uint80(roundId)].startedAt; + } + + /** + * @notice Record a new status and timestamp if it has changed since the last round. + * @dev This function will revert if not called from `l1Sender` via the L1->L2 messenger. + * + * @param status Sequencer status + * @param timestamp Block timestamp of status update + */ + function updateStatus(bool status, uint64 timestamp) external override { + _validateSender(s_l1Sender); + + FeedState memory feedState = _getFeedState(); + // Ignore if latest recorded timestamp is newer + if (feedState.startedAt > timestamp) { + emit UpdateIgnored(feedState.latestStatus, feedState.startedAt, status, timestamp); + return; + } + + if (feedState.latestStatus == status) { + _updateRound(feedState.latestRoundId, status); + } else { + feedState.latestRoundId += 1; + _recordRound(feedState.latestRoundId, status, timestamp); + } + } + + function _validateSender(address l1Sender) internal virtual; + + /// @inheritdoc AggregatorV3Interface + function getRoundData( + uint80 _roundId + ) + public + view + override + checkAccess + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) + { + if (!_isValidRound(_roundId)) { + revert NoDataPresent(); + } + + Round storage round = s_rounds[_roundId]; + + return (_roundId, _getStatusAnswer(round.status), uint256(round.startedAt), uint256(round.updatedAt), _roundId); + } + + /// @inheritdoc AggregatorV3Interface + function latestRoundData() + external + view + override + checkAccess + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) + { + FeedState storage feedState = s_feedState; + + return ( + feedState.latestRoundId, + _getStatusAnswer(feedState.latestStatus), + feedState.startedAt, + feedState.updatedAt, + feedState.latestRoundId + ); + } +} diff --git a/contracts/src/v0.8/l2ep/dev/shared/BaseValidator.sol b/contracts/src/v0.8/l2ep/dev/shared/BaseValidator.sol new file mode 100644 index 0000000000..9b05b88e98 --- /dev/null +++ b/contracts/src/v0.8/l2ep/dev/shared/BaseValidator.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {AggregatorValidatorInterface} from "../../../shared/interfaces/AggregatorValidatorInterface.sol"; +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; + +import {SimpleWriteAccessController} from "../../../shared/access/SimpleWriteAccessController.sol"; + +abstract contract BaseValidator is SimpleWriteAccessController, AggregatorValidatorInterface, ITypeAndVersion { + /// @notice emitted when gas cost to spend on L2 is updated + /// @param gasLimit updated gas cost + event GasLimitUpdated(uint32 gasLimit); + + error L1CrossDomainMessengerAddressZero(); + error L2UptimeFeedAddrZero(); + + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i + address public immutable L1_CROSS_DOMAIN_MESSENGER_ADDRESS; + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i + address public immutable L2_UPTIME_FEED_ADDR; + + int256 internal constant ANSWER_SEQ_OFFLINE = 1; + + uint32 internal s_gasLimit; + + /// @param l1CrossDomainMessengerAddress address the L1CrossDomainMessenger contract address + /// @param l2UptimeFeedAddr the address of the ScrollSequencerUptimeFeed contract address + /// @param gasLimit the gasLimit to use for sending a message from L1 to L2 + constructor(address l1CrossDomainMessengerAddress, address l2UptimeFeedAddr, uint32 gasLimit) { + if (l1CrossDomainMessengerAddress == address(0)) { + revert L1CrossDomainMessengerAddressZero(); + } + if (l2UptimeFeedAddr == address(0)) { + revert L2UptimeFeedAddrZero(); + } + + L1_CROSS_DOMAIN_MESSENGER_ADDRESS = l1CrossDomainMessengerAddress; + L2_UPTIME_FEED_ADDR = l2UptimeFeedAddr; + s_gasLimit = gasLimit; + } + + /// @notice fetches the gas cost of sending a cross chain message + function getGasLimit() external view returns (uint32) { + return s_gasLimit; + } + + /// @notice sets the new gas cost to spend when sending cross chain message + /// @param gasLimit the updated gas cost + function setGasLimit(uint32 gasLimit) external onlyOwner { + s_gasLimit = gasLimit; + emit GasLimitUpdated(gasLimit); + } + + /// @notice makes this contract payable + /// @dev receives funds: + /// - to use them (if configured) to pay for L2 execution on L1 + /// - when withdrawing funds from L2 xDomain alias address (pay for L2 execution on L2) + receive() external payable {} +} diff --git a/contracts/src/v0.8/l2ep/dev/zksync/ZKSyncSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/dev/zksync/ZKSyncSequencerUptimeFeed.sol new file mode 100644 index 0000000000..0074a0277d --- /dev/null +++ b/contracts/src/v0.8/l2ep/dev/zksync/ZKSyncSequencerUptimeFeed.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {BaseSequencerUptimeFeed} from "../shared/BaseSequencerUptimeFeed.sol"; + +import {AddressAliasHelper} from "../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; + +/// @title ZKSyncSequencerUptimeFeed - L2 sequencer uptime status aggregator +/// @notice L2 contract that receives status updates from a specific L1 address, +/// records a new answer if the status changed +contract ZKSyncSequencerUptimeFeed is BaseSequencerUptimeFeed { + string public constant override typeAndVersion = "ZKSyncSequencerUptimeFeed 1.1.0-dev"; + + /// @param l1SenderAddress Address of the L1 contract that is permissioned to call this contract + /// @param initialStatus The initial status of the feed + constructor(address l1SenderAddress, bool initialStatus) BaseSequencerUptimeFeed(l1SenderAddress, initialStatus) {} + + function _validateSender(address l1Sender) internal view override { + address aliasedL1Sender = AddressAliasHelper.applyL1ToL2Alias(l1Sender); + + if (msg.sender != aliasedL1Sender) { + revert InvalidSender(); + } + } +} diff --git a/contracts/src/v0.8/l2ep/dev/zksync/ZKSyncValidator.sol b/contracts/src/v0.8/l2ep/dev/zksync/ZKSyncValidator.sol new file mode 100644 index 0000000000..10f68ce286 --- /dev/null +++ b/contracts/src/v0.8/l2ep/dev/zksync/ZKSyncValidator.sol @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {ISequencerUptimeFeed} from "./../interfaces/ISequencerUptimeFeed.sol"; + +import {BaseValidator} from "../shared/BaseValidator.sol"; + +import {IBridgehub, L2TransactionRequestDirect} from "@zksync/contracts/l1-contracts/contracts/bridgehub/IBridgehub.sol"; + +/// @title ZKSyncValidator - makes cross chain call to update the Sequencer Uptime Feed on L2 +contract ZKSyncValidator is BaseValidator { + /// Contract state variables + string public constant override typeAndVersion = "ZKSyncValidator 1.1.0-dev"; + uint32 private constant ZKSYNC_TEST_NET_CHAIN_ID = 300; + uint32 private constant ZKSYNC_MAIN_NET_CHAIN_ID = 324; + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i + uint32 private immutable CHAIN_ID; + /// @dev how much l2 gas each byte of pubdata costs + uint32 private s_l2GasPerPubdataByteLimit; + + /// @notice emitted when the gas per pubdata byte limit is updated + /// @param l2GasPerPubdataByteLimit updated gas per pubdata byte limit + event GasPerPubdataByteLimitUpdated(uint32 l2GasPerPubdataByteLimit); + + /// @notice ChainID is not a valid value + error InvalidChainID(); + + /// @param l1CrossDomainMessengerAddress address the Bridgehub contract address + /// @param l2UptimeFeedAddr the address of the SequencerUptimeFeedInterface contract address + /// @param gasLimit the gasLimit to use for sending a message from L1 to L2 + constructor( + address l1CrossDomainMessengerAddress, + address l2UptimeFeedAddr, + uint32 gasLimit, + uint32 chainId, + uint32 l2GasPerPubdataByteLimit + ) BaseValidator(l1CrossDomainMessengerAddress, l2UptimeFeedAddr, gasLimit) { + if (chainId != ZKSYNC_TEST_NET_CHAIN_ID && chainId != ZKSYNC_MAIN_NET_CHAIN_ID) { + revert InvalidChainID(); + } + + s_l2GasPerPubdataByteLimit = l2GasPerPubdataByteLimit; + CHAIN_ID = chainId; + } + + /// @notice sets the l2GasPerPubdataByteLimit for the L2 transaction request + /// @param l2GasPerPubdataByteLimit the updated l2GasPerPubdataByteLimit + function setL2GasPerPubdataByteLimit(uint32 l2GasPerPubdataByteLimit) external onlyOwner { + if (s_l2GasPerPubdataByteLimit != l2GasPerPubdataByteLimit) { + s_l2GasPerPubdataByteLimit = l2GasPerPubdataByteLimit; + emit GasPerPubdataByteLimitUpdated(l2GasPerPubdataByteLimit); + } + } + + /// @notice fetches the l2GasPerPubdataByteLimit for the L2 transaction request + function getL2GasPerPubdataByteLimit() external view returns (uint32) { + return s_l2GasPerPubdataByteLimit; + } + + /// @notice fetches the chain id + function getChainId() external view returns (uint32) { + return CHAIN_ID; + } + + /// @notice validate method sends an xDomain L2 tx to update Uptime Feed contract on L2. + /// @dev A message is sent using the Bridgehub. This method is accessed controlled. + /// @param currentAnswer new aggregator answer - value of 1 considers the sequencer offline. + function validate( + uint256 /* previousRoundId */, + int256 /* previousAnswer */, + uint256 /* currentRoundId */, + int256 currentAnswer + ) external override checkAccess returns (bool) { + IBridgehub bridgeHub = IBridgehub(L1_CROSS_DOMAIN_MESSENGER_ADDRESS); + + uint256 transactionBaseCostEstimate = bridgeHub.l2TransactionBaseCost( + CHAIN_ID, + tx.gasprice, + s_gasLimit, + s_l2GasPerPubdataByteLimit + ); + + L2TransactionRequestDirect memory l2TransactionRequestDirect = L2TransactionRequestDirect({ + chainId: CHAIN_ID, + mintValue: transactionBaseCostEstimate, + l2Contract: L2_UPTIME_FEED_ADDR, + l2Value: 0, + l2Calldata: abi.encodeWithSelector( + ISequencerUptimeFeed.updateStatus.selector, + currentAnswer == ANSWER_SEQ_OFFLINE, + uint64(block.timestamp) + ), + l2GasLimit: s_gasLimit, + l2GasPerPubdataByteLimit: s_l2GasPerPubdataByteLimit, + factoryDeps: new bytes[](0), + refundRecipient: msg.sender + }); + + // Make the xDomain call + bridgeHub.requestL2TransactionDirect{value: transactionBaseCostEstimate}(l2TransactionRequestDirect); + + return true; + } +} diff --git a/contracts/src/v0.8/l2ep/test/mocks/MockAggregatorV2V3.sol b/contracts/src/v0.8/l2ep/test/mocks/MockAggregatorV2V3.sol index c4e2f71030..52019324f5 100644 --- a/contracts/src/v0.8/l2ep/test/mocks/MockAggregatorV2V3.sol +++ b/contracts/src/v0.8/l2ep/test/mocks/MockAggregatorV2V3.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.9; +pragma solidity ^0.8.24; import {AggregatorV2V3Interface} from "../../../shared/interfaces/AggregatorV2V3Interface.sol"; diff --git a/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL1CrossDomainMessenger.sol b/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL1CrossDomainMessenger.sol index e63847d655..42147fbd91 100644 --- a/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL1CrossDomainMessenger.sol +++ b/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL1CrossDomainMessenger.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.9; +pragma solidity ^0.8.24; import {IL1ScrollMessenger} from "@scroll-tech/contracts/L1/IL1ScrollMessenger.sol"; diff --git a/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL1MessageQueue.sol b/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL1MessageQueue.sol index 1700bcbe16..e43f1bf136 100644 --- a/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL1MessageQueue.sol +++ b/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL1MessageQueue.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; import {IL1MessageQueue} from "@scroll-tech/contracts/L1/rollup/IL1MessageQueue.sol"; diff --git a/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL2CrossDomainMessenger.sol b/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL2CrossDomainMessenger.sol index 66400b7d30..af0e0b5ca5 100644 --- a/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL2CrossDomainMessenger.sol +++ b/contracts/src/v0.8/l2ep/test/mocks/scroll/MockScrollL2CrossDomainMessenger.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.9; +pragma solidity ^0.8.24; import {IL2ScrollMessenger} from "@scroll-tech/contracts/L2/IL2ScrollMessenger.sol"; diff --git a/contracts/src/v0.8/l2ep/test/mocks/zksync/MockZKSyncL1Bridge.sol b/contracts/src/v0.8/l2ep/test/mocks/zksync/MockZKSyncL1Bridge.sol new file mode 100644 index 0000000000..b46b9d9fdf --- /dev/null +++ b/contracts/src/v0.8/l2ep/test/mocks/zksync/MockZKSyncL1Bridge.sol @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {IBridgehub, L2TransactionRequestDirect, L2TransactionRequestTwoBridgesOuter} from "@zksync/contracts/l1-contracts/contracts/bridgehub/IBridgehub.sol"; +import {IL1SharedBridge} from "@zksync/contracts/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol"; +import {L2Message, L2Log, TxStatus} from "@zksync/contracts/l1-contracts/contracts/common/Messaging.sol"; + +contract MockBridgehub is IBridgehub { + address public pendingAdmin; + address public admin; + address public sharedBridgeAddr; + + mapping(address stateTransitionManager => bool stateTransitionManagerIsRegistered) + public registeredStateTransitionManagers; + mapping(uint256 chainId => address stateTransitionManagerAddress) public stateTransitionManagers; + mapping(address baseToken => bool tokenIsRegistered) public registeredTokens; + mapping(uint256 chainId => address baseToken) public baseTokens; + mapping(uint256 chainId => address hyperChain) public hyperchains; + + /// Generic error for unauthorized actions + error NotAuthorized(string msg); + + /// Fake event that will get emitted when `requestL2TransactionDirect` is called + event SentMessage(address indexed sender, bytes message); + + /// Admin functions + function setPendingAdmin(address _newPendingAdmin) external override { + emit NewPendingAdmin(pendingAdmin, _newPendingAdmin); + pendingAdmin = _newPendingAdmin; + } + + function acceptAdmin() external override { + if (msg.sender != pendingAdmin) { + revert NotAuthorized("Only pending admin can accept"); + } + + emit NewAdmin(admin, pendingAdmin); + admin = pendingAdmin; + pendingAdmin = address(0); + } + + /// Getters + function stateTransitionManagerIsRegistered(address _stateTransitionManager) external view override returns (bool) { + return registeredStateTransitionManagers[_stateTransitionManager]; + } + + function stateTransitionManager(uint256 _chainId) external view override returns (address) { + return stateTransitionManagers[_chainId]; + } + + function tokenIsRegistered(address _baseToken) external view override returns (bool) { + return registeredTokens[_baseToken]; + } + + function baseToken(uint256 _chainId) external view override returns (address) { + return baseTokens[_chainId]; + } + + function sharedBridge() external view override returns (IL1SharedBridge) { + return IL1SharedBridge(sharedBridgeAddr); + } + + function getHyperchain(uint256 _chainId) external view override returns (address) { + return hyperchains[_chainId]; + } + + /// Mailbox forwarder + function proveL2MessageInclusion( + uint256, + uint256, + uint256, + L2Message calldata, + bytes32[] calldata + ) external pure override returns (bool) { + return true; + } + + function proveL2LogInclusion( + uint256, + uint256, + uint256, + L2Log memory, + bytes32[] calldata + ) external pure override returns (bool) { + return true; + } + + function proveL1ToL2TransactionStatus( + uint256, + bytes32, + uint256, + uint256, + uint16, + bytes32[] calldata, + TxStatus + ) external pure override returns (bool) { + return true; + } + + function requestL2TransactionDirect( + L2TransactionRequestDirect calldata txRequest + ) external payable override returns (bytes32) { + emit SentMessage(msg.sender, txRequest.l2Calldata); + return keccak256(abi.encodePacked("L2TransactionDirect")); + } + + function requestL2TransactionTwoBridges( + L2TransactionRequestTwoBridgesOuter calldata + ) external payable override returns (bytes32) { + return keccak256(abi.encodePacked("L2TransactionTwoBridges")); + } + + function l2TransactionBaseCost(uint256, uint256, uint256, uint256) external pure override returns (uint256) { + return 0; + } + + /// Registry + function createNewChain( + uint256 _chainId, + address _stateTransitionManager, + address _baseToken, + uint256, + address, + bytes calldata + ) external override returns (uint256 chainId) { + hyperchains[_chainId] = _stateTransitionManager; + baseTokens[_chainId] = _baseToken; + emit NewChain(_chainId, _stateTransitionManager, address(this)); + return _chainId; + } + + function addStateTransitionManager(address _stateTransitionManager) external override { + registeredStateTransitionManagers[_stateTransitionManager] = true; + } + + function removeStateTransitionManager(address _stateTransitionManager) external override { + registeredStateTransitionManagers[_stateTransitionManager] = false; + } + + function addToken(address _token) external override { + registeredTokens[_token] = true; + } + + function setSharedBridge(address _sharedBridgeAddr) external override { + sharedBridgeAddr = _sharedBridgeAddr; + } +} diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/L2EPTest.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/L2EPTest.t.sol index 561e32be1a..93640f4bcb 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/L2EPTest.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/L2EPTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity ^0.8.24; import {Greeter} from "../../../tests/Greeter.sol"; @@ -13,21 +13,6 @@ contract L2EPTest is Test { address internal s_eoaValidator = vm.addr(0x3); address internal s_deployerAddr = vm.addr(0x4); - /// @param expectedGasUsage - the expected gas usage - /// @param startGasUsage - the gas usage before the code of interest is run - /// @param finalGasUsage - the gas usage after the code of interest is run - /// @param deviation - the amount of gas that the actual usage is allowed to deviate by (e.g. (expectedGas - deviation) <= actualGasUsage <= (expectedGas + deviation)) - function assertGasUsageIsCloseTo( - uint256 expectedGasUsage, - uint256 startGasUsage, - uint256 finalGasUsage, - uint256 deviation - ) public { - uint256 gasUsed = (startGasUsage - finalGasUsage) * tx.gasprice; - assertLe(gasUsed, expectedGasUsage + deviation); - assertGe(gasUsed, expectedGasUsage - deviation); - } - /// @param selector - the function selector /// @param greeterAddr - the address of the Greeter contract /// @param message - the new greeting message, which will be passed as an argument to Greeter#setGreeting diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumCrossDomainForwarder.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumCrossDomainForwarder.t.sol index be3851c5b5..cff9b953e2 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumCrossDomainForwarder.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumCrossDomainForwarder.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; import {ArbitrumCrossDomainForwarder} from "../../../dev/arbitrum/ArbitrumCrossDomainForwarder.sol"; import {Greeter} from "../../../../tests/Greeter.sol"; diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumCrossDomainGovernor.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumCrossDomainGovernor.t.sol index c5b8adaf7d..610f49f16c 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumCrossDomainGovernor.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumCrossDomainGovernor.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; import {ArbitrumCrossDomainGovernor} from "../../../dev/arbitrum/ArbitrumCrossDomainGovernor.sol"; import {Greeter} from "../../../../tests/Greeter.sol"; diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumSequencerUptimeFeed.t.sol index 5565409709..e308ead343 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumSequencerUptimeFeed.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumSequencerUptimeFeed.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; import {SimpleWriteAccessController} from "../../../../shared/access/SimpleWriteAccessController.sol"; import {ArbitrumSequencerUptimeFeed} from "../../../dev/arbitrum/ArbitrumSequencerUptimeFeed.sol"; diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumValidator.t.sol index 504635540c..ab87299174 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumValidator.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumValidator.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismCrossDomainForwarder.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismCrossDomainForwarder.t.sol index d5c482dce9..c0e82ab8d5 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismCrossDomainForwarder.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismCrossDomainForwarder.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; import {OptimismCrossDomainForwarder} from "../../../dev/optimism/OptimismCrossDomainForwarder.sol"; import {MockOVMCrossDomainMessenger} from "../../mocks/optimism/MockOVMCrossDomainMessenger.sol"; diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismCrossDomainGovernor.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismCrossDomainGovernor.t.sol index e1a5aef95a..8f8fb9d7e7 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismCrossDomainGovernor.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismCrossDomainGovernor.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; import {OptimismCrossDomainGovernor} from "../../../dev/optimism/OptimismCrossDomainGovernor.sol"; import {MockOVMCrossDomainMessenger} from "../../mocks/optimism/MockOVMCrossDomainMessenger.sol"; diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol index 071d6e5b42..eec9657ac1 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol @@ -1,9 +1,10 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; import {MockOptimismL1CrossDomainMessenger} from "../../../../tests/MockOptimismL1CrossDomainMessenger.sol"; import {MockOptimismL2CrossDomainMessenger} from "../../../../tests/MockOptimismL2CrossDomainMessenger.sol"; import {OptimismSequencerUptimeFeed} from "../../../dev/optimism/OptimismSequencerUptimeFeed.sol"; +import {BaseSequencerUptimeFeed} from "../../../dev/shared/BaseSequencerUptimeFeed.sol"; import {FeedConsumer} from "../../../../tests/FeedConsumer.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; @@ -61,7 +62,7 @@ contract OptimismSequencerUptimeFeed_UpdateStatus is OptimismSequencerUptimeFeed vm.startPrank(s_strangerAddr, s_strangerAddr); // Tries to update the status from an unauthorized account - vm.expectRevert(OptimismSequencerUptimeFeed.InvalidSender.selector); + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); s_optimismSequencerUptimeFeed.updateStatus(true, uint64(1)); } @@ -74,7 +75,7 @@ contract OptimismSequencerUptimeFeed_UpdateStatus is OptimismSequencerUptimeFeed s_mockOptimismL2CrossDomainMessenger.setSender(s_strangerAddr); // Tries to update the status from an unauthorized account - vm.expectRevert(OptimismSequencerUptimeFeed.InvalidSender.selector); + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); s_optimismSequencerUptimeFeed.updateStatus(true, uint64(1)); } @@ -257,7 +258,7 @@ contract OptimismSequencerUptimeFeed_AggregatorV3Interface is OptimismSequencerU vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); // Gets data from a round that has not happened yet - vm.expectRevert(OptimismSequencerUptimeFeed.NoDataPresent.selector); + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); s_optimismSequencerUptimeFeed.getRoundData(2); } @@ -267,7 +268,7 @@ contract OptimismSequencerUptimeFeed_AggregatorV3Interface is OptimismSequencerU vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); // Gets data from a round that has not happened yet - vm.expectRevert(OptimismSequencerUptimeFeed.NoDataPresent.selector); + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); s_optimismSequencerUptimeFeed.getAnswer(2); } @@ -277,7 +278,7 @@ contract OptimismSequencerUptimeFeed_AggregatorV3Interface is OptimismSequencerU vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); // Gets data from a round that has not happened yet - vm.expectRevert(OptimismSequencerUptimeFeed.NoDataPresent.selector); + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); s_optimismSequencerUptimeFeed.getTimestamp(2); } } diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismValidator.t.sol index 9364396817..59395bf5d8 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismValidator.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismValidator.t.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; + +import {ISequencerUptimeFeed} from "../../../dev/interfaces/ISequencerUptimeFeed.sol"; import {MockOptimismL1CrossDomainMessenger} from "../../../../tests/MockOptimismL1CrossDomainMessenger.sol"; import {MockOptimismL2CrossDomainMessenger} from "../../../../tests/MockOptimismL2CrossDomainMessenger.sol"; @@ -73,7 +75,7 @@ contract OptimismValidator_Validate is OptimismValidatorTest { emit SentMessage( L2_SEQ_STATUS_RECORDER_ADDRESS, // target address(s_optimismValidator), // sender - abi.encodeWithSelector(OptimismSequencerUptimeFeed.updateStatus.selector, false, futureTimestampInSeconds), // message + abi.encodeWithSelector(ISequencerUptimeFeed.updateStatus.selector, false, futureTimestampInSeconds), // message 0, // nonce INIT_GAS_LIMIT // gas limit ); @@ -97,7 +99,7 @@ contract OptimismValidator_Validate is OptimismValidatorTest { emit SentMessage( L2_SEQ_STATUS_RECORDER_ADDRESS, // target address(s_optimismValidator), // sender - abi.encodeWithSelector(OptimismSequencerUptimeFeed.updateStatus.selector, true, futureTimestampInSeconds), // message + abi.encodeWithSelector(ISequencerUptimeFeed.updateStatus.selector, true, futureTimestampInSeconds), // message 0, // nonce INIT_GAS_LIMIT // gas limit ); diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainForwarder.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainForwarder.t.sol index f921fa9242..e34e84f400 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainForwarder.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainForwarder.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; import {MockScrollCrossDomainMessenger} from "../../mocks/scroll/MockScrollCrossDomainMessenger.sol"; import {ScrollCrossDomainForwarder} from "../../../dev/scroll/ScrollCrossDomainForwarder.sol"; diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainGovernor.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainGovernor.t.sol index 9c44460494..8c3d56d156 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainGovernor.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainGovernor.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; import {MockScrollCrossDomainMessenger} from "../../mocks/scroll/MockScrollCrossDomainMessenger.sol"; import {ScrollCrossDomainGovernor} from "../../../dev/scroll/ScrollCrossDomainGovernor.sol"; diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol index 3aac50e7c1..0968c69415 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol @@ -1,9 +1,10 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; import {MockScrollL1CrossDomainMessenger} from "../../mocks/scroll/MockScrollL1CrossDomainMessenger.sol"; import {MockScrollL2CrossDomainMessenger} from "../../mocks/scroll/MockScrollL2CrossDomainMessenger.sol"; import {ScrollSequencerUptimeFeed} from "../../../dev/scroll/ScrollSequencerUptimeFeed.sol"; +import {BaseSequencerUptimeFeed} from "../../../dev/shared/BaseSequencerUptimeFeed.sol"; import {FeedConsumer} from "../../../../tests/FeedConsumer.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; @@ -65,7 +66,7 @@ contract ScrollSequencerUptimeFeed_UpdateStatus is ScrollSequencerUptimeFeedTest vm.startPrank(s_strangerAddr, s_strangerAddr); // Tries to update the status from an unauthorized account - vm.expectRevert(ScrollSequencerUptimeFeed.InvalidSender.selector); + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); s_scrollSequencerUptimeFeed.updateStatus(true, uint64(1)); } @@ -78,7 +79,7 @@ contract ScrollSequencerUptimeFeed_UpdateStatus is ScrollSequencerUptimeFeedTest s_mockScrollL2CrossDomainMessenger.setSender(s_strangerAddr); // Tries to update the status from an unauthorized account - vm.expectRevert(ScrollSequencerUptimeFeed.InvalidSender.selector); + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); s_scrollSequencerUptimeFeed.updateStatus(true, uint64(1)); } @@ -261,7 +262,7 @@ contract ScrollSequencerUptimeFeed_AggregatorV3Interface is ScrollSequencerUptim vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); // Gets data from a round that has not happened yet - vm.expectRevert(ScrollSequencerUptimeFeed.NoDataPresent.selector); + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); s_scrollSequencerUptimeFeed.getRoundData(2); } @@ -271,7 +272,7 @@ contract ScrollSequencerUptimeFeed_AggregatorV3Interface is ScrollSequencerUptim vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); // Gets data from a round that has not happened yet - vm.expectRevert(ScrollSequencerUptimeFeed.NoDataPresent.selector); + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); s_scrollSequencerUptimeFeed.getAnswer(2); } @@ -281,7 +282,7 @@ contract ScrollSequencerUptimeFeed_AggregatorV3Interface is ScrollSequencerUptim vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); // Gets data from a round that has not happened yet - vm.expectRevert(ScrollSequencerUptimeFeed.NoDataPresent.selector); + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); s_scrollSequencerUptimeFeed.getTimestamp(2); } } diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol index f425ca1c6e..3d5298d518 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.24; + +import {ISequencerUptimeFeed} from "../../../dev/interfaces/ISequencerUptimeFeed.sol"; import {MockScrollL1CrossDomainMessenger} from "../../mocks/scroll/MockScrollL1CrossDomainMessenger.sol"; import {MockScrollL2CrossDomainMessenger} from "../../mocks/scroll/MockScrollL2CrossDomainMessenger.sol"; @@ -87,7 +89,7 @@ contract ScrollValidator_Validate is ScrollValidatorTest { 0, // value 0, // nonce INIT_GAS_LIMIT, // gas limit - abi.encodeWithSelector(ScrollSequencerUptimeFeed.updateStatus.selector, false, futureTimestampInSeconds) // message + abi.encodeWithSelector(ISequencerUptimeFeed.updateStatus.selector, false, futureTimestampInSeconds) // message ); // Runs the function (which produces the event to test) @@ -112,7 +114,7 @@ contract ScrollValidator_Validate is ScrollValidatorTest { 0, // value 0, // nonce INIT_GAS_LIMIT, // gas limit - abi.encodeWithSelector(ScrollSequencerUptimeFeed.updateStatus.selector, true, futureTimestampInSeconds) // message + abi.encodeWithSelector(ISequencerUptimeFeed.updateStatus.selector, true, futureTimestampInSeconds) // message ); // Runs the function (which produces the event to test) diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncSequencerUptimeFeed.t.sol new file mode 100644 index 0000000000..6d90b3973e --- /dev/null +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncSequencerUptimeFeed.t.sol @@ -0,0 +1,291 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {AddressAliasHelper} from "../../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; +import {ZKSyncSequencerUptimeFeed} from "../../../dev/zksync/ZKSyncSequencerUptimeFeed.sol"; +import {BaseSequencerUptimeFeed} from "../../../dev/shared/BaseSequencerUptimeFeed.sol"; +import {FeedConsumer} from "../../../../tests/FeedConsumer.sol"; +import {L2EPTest} from "../L2EPTest.t.sol"; + +contract ZKSyncSequencerUptimeFeedTest is L2EPTest { + /// Helper Variables + address internal s_aliasedL1OwnerAddress = AddressAliasHelper.applyL1ToL2Alias(s_l1OwnerAddr); + + /// L2EP contracts + ZKSyncSequencerUptimeFeed internal s_zksyncSequencerUptimeFeed; + + /// Events + event UpdateIgnored(bool latestStatus, uint64 latestTimestamp, bool incomingStatus, uint64 incomingTimestamp); + event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); + event RoundUpdated(int256 status, uint64 updatedAt); + + /// Setup + function setUp() public { + // Deploys contracts + s_zksyncSequencerUptimeFeed = new ZKSyncSequencerUptimeFeed(s_l1OwnerAddr, false); + } +} + +contract ZKSyncSequencerUptimeFeed_Constructor is ZKSyncSequencerUptimeFeedTest { + /// @notice it should have been deployed with the correct initial state + function test_InitialState() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + // Checks L1 sender + address actualL1Addr = s_zksyncSequencerUptimeFeed.l1Sender(); + assertEq(actualL1Addr, s_l1OwnerAddr); + + // Checks latest round data + (uint80 roundId, int256 answer, , , ) = s_zksyncSequencerUptimeFeed.latestRoundData(); + assertEq(roundId, 1); + assertEq(answer, 0); + } +} + +contract ZKSyncSequencerUptimeFeed_UpdateStatus is ZKSyncSequencerUptimeFeedTest { + /// @notice it should revert if called by an unauthorized account + function test_RevertIfNotL2CrossDomainMessengerAddr() public { + // Sets msg.sender and tx.origin to an unauthorized address + vm.startPrank(s_strangerAddr, s_strangerAddr); + + // Tries to update the status from an unauthorized account + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); + s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(1)); + } + + /// @notice it should update status when status has not changed and incoming timestamp is the same as latest + function test_UpdateStatusWhenNoChange() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Fetches the latest timestamp + uint256 timestamp = s_zksyncSequencerUptimeFeed.latestTimestamp(); + + // Submits a status update + vm.expectEmit(); + emit AnswerUpdated(1, 2, timestamp); + s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Stores the current round data before updating it + ( + uint80 roundIdBeforeUpdate, + int256 answerBeforeUpdate, + uint256 startedAtBeforeUpdate, + , + uint80 answeredInRoundBeforeUpdate + ) = s_zksyncSequencerUptimeFeed.latestRoundData(); + + // Submit another status update with the same status + vm.expectEmit(); + emit RoundUpdated(1, uint64(block.timestamp)); + s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp + 200)); + assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Stores the current round data after updating it + ( + uint80 roundIdAfterUpdate, + int256 answerAfterUpdate, + uint256 startedAtAfterUpdate, + uint256 updatedAtAfterUpdate, + uint80 answeredInRoundAfterUpdate + ) = s_zksyncSequencerUptimeFeed.latestRoundData(); + + // Verifies the latest round data has been properly updated + assertEq(roundIdAfterUpdate, roundIdBeforeUpdate); + assertEq(answerAfterUpdate, answerBeforeUpdate); + assertEq(startedAtAfterUpdate, startedAtBeforeUpdate); + assertEq(answeredInRoundAfterUpdate, answeredInRoundBeforeUpdate); + assertEq(updatedAtAfterUpdate, block.timestamp); + } + + /// @notice it should update status when status has changed and incoming timestamp is newer than the latest + function test_UpdateStatusWhenStatusChangeAndTimeChange() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Submits a status update + uint256 timestamp = s_zksyncSequencerUptimeFeed.latestTimestamp(); + vm.expectEmit(); + emit AnswerUpdated(1, 2, timestamp); + s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Submit another status update, different status, newer timestamp should update + timestamp = timestamp + 200; + vm.expectEmit(); + emit AnswerUpdated(0, 3, timestamp); + s_zksyncSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); + assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 0); + assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + } + + /// @notice it should update status when status has changed and incoming timestamp is the same as latest + function test_UpdateStatusWhenStatusChangeAndNoTimeChange() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Fetches the latest timestamp + uint256 timestamp = s_zksyncSequencerUptimeFeed.latestTimestamp(); + + // Submits a status update + vm.expectEmit(); + emit AnswerUpdated(1, 2, timestamp); + s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Submit another status update, different status, same timestamp should update + vm.expectEmit(); + emit AnswerUpdated(0, 3, timestamp); + s_zksyncSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); + assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 0); + assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + } + + /// @notice it should ignore out-of-order updates + function test_IgnoreOutOfOrderUpdates() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Submits a status update + uint256 timestamp = s_zksyncSequencerUptimeFeed.latestTimestamp() + 10000; + vm.expectEmit(); + emit AnswerUpdated(1, 2, timestamp); + s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Update with different status, but stale timestamp, should be ignored + timestamp = timestamp - 1000; + vm.expectEmit(false, false, false, false); + emit UpdateIgnored(true, 0, true, 0); // arguments are dummy values + // TODO: how can we check that an AnswerUpdated event was NOT emitted + s_zksyncSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); + } +} + +contract ZKSyncSequencerUptimeFeed_AggregatorV3Interface is ZKSyncSequencerUptimeFeedTest { + /// @notice it should return valid answer from getRoundData and latestRoundData + function test_AggregatorV3Interface() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Defines helper variables + uint80 roundId; + int256 answer; + uint256 startedAt; + uint256 updatedAt; + uint80 answeredInRound; + + // Checks initial state + (roundId, answer, startedAt, updatedAt, answeredInRound) = s_zksyncSequencerUptimeFeed.latestRoundData(); + assertEq(roundId, 1); + assertEq(answer, 0); + assertEq(answeredInRound, roundId); + assertEq(startedAt, updatedAt); + + // Submits status update with different status and newer timestamp, should update + uint256 timestamp = startedAt + 1000; + s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + (roundId, answer, startedAt, updatedAt, answeredInRound) = s_zksyncSequencerUptimeFeed.getRoundData(2); + assertEq(roundId, 2); + assertEq(answer, 1); + assertEq(answeredInRound, roundId); + assertEq(startedAt, timestamp); + assertLe(updatedAt, startedAt); + + // Saves round 2 data + uint80 roundId2 = roundId; + int256 answer2 = answer; + uint256 startedAt2 = startedAt; + uint256 updatedAt2 = updatedAt; + uint80 answeredInRound2 = answeredInRound; + + // Checks that last round is still returning the correct data + (roundId, answer, startedAt, updatedAt, answeredInRound) = s_zksyncSequencerUptimeFeed.getRoundData(1); + assertEq(roundId, 1); + assertEq(answer, 0); + assertEq(answeredInRound, roundId); + assertEq(startedAt, updatedAt); + + // Assert latestRoundData corresponds to latest round id + (roundId, answer, startedAt, updatedAt, answeredInRound) = s_zksyncSequencerUptimeFeed.latestRoundData(); + assertEq(roundId2, roundId); + assertEq(answer2, answer); + assertEq(startedAt2, startedAt); + assertEq(updatedAt2, updatedAt); + assertEq(answeredInRound2, answeredInRound); + } + + /// @notice it should revert from #getRoundData when round does not yet exist (future roundId) + function test_RevertGetRoundDataWhenRoundDoesNotExistYet() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + // Gets data from a round that has not happened yet + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); + s_zksyncSequencerUptimeFeed.getRoundData(2); + } + + /// @notice it should revert from #getAnswer when round does not yet exist (future roundId) + function test_RevertGetAnswerWhenRoundDoesNotExistYet() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + // Gets data from a round that has not happened yet + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); + s_zksyncSequencerUptimeFeed.getAnswer(2); + } + + /// @notice it should revert from #getTimestamp when round does not yet exist (future roundId) + function test_RevertGetTimestampWhenRoundDoesNotExistYet() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + // Gets data from a round that has not happened yet + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); + s_zksyncSequencerUptimeFeed.getTimestamp(2); + } +} + +contract ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions is ZKSyncSequencerUptimeFeedTest { + /// @notice it should disallow reads on AggregatorV2V3Interface functions when consuming contract is not whitelisted + function test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() public { + // Deploys a FeedConsumer contract + FeedConsumer feedConsumer = new FeedConsumer(address(s_zksyncSequencerUptimeFeed)); + + // Sanity - consumer is not whitelisted + assertEq(s_zksyncSequencerUptimeFeed.checkEnabled(), true); + assertEq(s_zksyncSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), false); + + // Asserts reads are not possible from consuming contract + vm.expectRevert("No access"); + feedConsumer.latestAnswer(); + vm.expectRevert("No access"); + feedConsumer.latestRoundData(); + } + + /// @notice it should allow reads on AggregatorV2V3Interface functions when consuming contract is whitelisted + function test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() public { + // Deploys a FeedConsumer contract + FeedConsumer feedConsumer = new FeedConsumer(address(s_zksyncSequencerUptimeFeed)); + + // Whitelist consumer + s_zksyncSequencerUptimeFeed.addAccess(address(feedConsumer)); + + // Sanity - consumer is whitelisted + assertEq(s_zksyncSequencerUptimeFeed.checkEnabled(), true); + assertEq(s_zksyncSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), true); + + // Asserts reads are possible from consuming contract + (uint80 roundId, int256 answer, , , ) = feedConsumer.latestRoundData(); + assertEq(feedConsumer.latestAnswer(), 0); + assertEq(roundId, 1); + assertEq(answer, 0); + } +} diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncValidator.t.sol new file mode 100644 index 0000000000..0bea147c8c --- /dev/null +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncValidator.t.sol @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {MockBridgehub} from "../../mocks/zksync/MockZKSyncL1Bridge.sol"; +import {ISequencerUptimeFeed} from "../../../dev/interfaces/ISequencerUptimeFeed.sol"; +import {ZKSyncValidator} from "../../../dev/zksync/ZKSyncValidator.sol"; +import {BaseValidator} from "../../../dev/shared/BaseValidator.sol"; +import {L2EPTest} from "../L2EPTest.t.sol"; + +contract ZKSyncValidatorTest is L2EPTest { + address internal constant L2_SEQ_STATUS_RECORDER_ADDRESS = address(0x491B1dDA0A8fa069bbC1125133A975BF4e85a91b); + address internal constant DUMMY_L1_XDOMAIN_MSNGR_ADDR = address(0xa04Fc18f012B1a5A8231c7Ee4b916Dd6dbd271b6); + address internal constant DUMMY_L2_UPTIME_FEED_ADDR = address(0xFe31891940A2e5f04B76eD8bD1038E44127d1512); + uint32 internal constant INIT_GAS_PER_PUBDATA_BYTE_LIMIT = 800; + uint32 internal constant INIT_GAS_LIMIT = 1900000; + uint32 internal constant MAIN_NET_CHAIN_ID = 300; + uint32 internal constant BAD_CHAIN_ID = 0; + + ISequencerUptimeFeed internal s_zksyncSequencerUptimeFeed; + MockBridgehub internal s_mockZKSyncL1Bridge; + ZKSyncValidator internal s_zksyncValidator; + + /// Fake event that will get emitted when `requestL2TransactionDirect` is called + /// Definition is taken from MockZKSyncL1Bridge + event SentMessage(address indexed sender, bytes message); + + /// Setup + function setUp() public { + s_mockZKSyncL1Bridge = new MockBridgehub(); + + s_zksyncValidator = new ZKSyncValidator( + address(s_mockZKSyncL1Bridge), + DUMMY_L2_UPTIME_FEED_ADDR, + INIT_GAS_LIMIT, + MAIN_NET_CHAIN_ID, + INIT_GAS_PER_PUBDATA_BYTE_LIMIT + ); + } +} + +contract ZKSyncValidator_Constructor is ZKSyncValidatorTest { + /// @notice it correctly validates that the chain id is valid + function test_ConstructingRevertedWithInvalidChainId() public { + vm.expectRevert(ZKSyncValidator.InvalidChainID.selector); + new ZKSyncValidator( + DUMMY_L1_XDOMAIN_MSNGR_ADDR, + DUMMY_L2_UPTIME_FEED_ADDR, + INIT_GAS_LIMIT, + BAD_CHAIN_ID, + INIT_GAS_PER_PUBDATA_BYTE_LIMIT + ); + } + + /// @notice it correctly validates that the L1 bridge address is not zero + function test_ConstructingRevertedWithZeroL1BridgeAddress() public { + vm.expectRevert(BaseValidator.L1CrossDomainMessengerAddressZero.selector); + new ZKSyncValidator( + address(0), + DUMMY_L2_UPTIME_FEED_ADDR, + INIT_GAS_LIMIT, + MAIN_NET_CHAIN_ID, + INIT_GAS_PER_PUBDATA_BYTE_LIMIT + ); + } + + /// @notice it correctly validates that the L2 Uptime feed address is not zero + function test_ConstructingRevertedWithZeroL2UpdateFeedAddress() public { + vm.expectRevert(BaseValidator.L2UptimeFeedAddrZero.selector); + new ZKSyncValidator( + DUMMY_L1_XDOMAIN_MSNGR_ADDR, + address(0), + INIT_GAS_LIMIT, + MAIN_NET_CHAIN_ID, + INIT_GAS_PER_PUBDATA_BYTE_LIMIT + ); + } +} + +contract ZKSyncValidator_GetSetL2GasPerPubdataByteLimit is ZKSyncValidatorTest { + /// @notice it correctly updates the gas limit per pubdata byte + function test_CorrectlyGetsAndUpdatesTheGasPerPubdataByteLimit() public { + assertEq(s_zksyncValidator.getL2GasPerPubdataByteLimit(), INIT_GAS_PER_PUBDATA_BYTE_LIMIT); + + uint32 newGasPerPubDataByteLimit = 2000000; + s_zksyncValidator.setL2GasPerPubdataByteLimit(newGasPerPubDataByteLimit); + assertEq(s_zksyncValidator.getL2GasPerPubdataByteLimit(), newGasPerPubDataByteLimit); + } +} + +contract ZKSyncValidator_GetChainId is ZKSyncValidatorTest { + /// @notice it correctly gets the chain id + function test_CorrectlyGetsTheChainId() public { + assertEq(s_zksyncValidator.getChainId(), MAIN_NET_CHAIN_ID); + } +} + +contract ZKSyncValidator_Validate is ZKSyncValidatorTest { + /// @notice it reverts if called by account with no access + function test_RevertsIfCalledByAnAccountWithNoAccess() public { + vm.startPrank(s_strangerAddr); + vm.expectRevert("No access"); + s_zksyncValidator.validate(0, 0, 1, 1); + } + + /// @notice it posts sequencer status when there is not status change + function test_PostSequencerStatusWhenThereIsNotStatusChange() public { + // Gives access to the s_eoaValidator + s_zksyncValidator.addAccess(s_eoaValidator); + + // Sets block.timestamp to a later date + uint256 futureTimestampInSeconds = block.timestamp + 5000; + vm.startPrank(s_eoaValidator); + vm.warp(futureTimestampInSeconds); + + // Sets up the expected event data + bytes memory message = abi.encodeWithSelector( + ISequencerUptimeFeed.updateStatus.selector, + false, + futureTimestampInSeconds + ); + + vm.expectEmit(false, false, false, true); + emit SentMessage(address(s_zksyncValidator), message); + + // Runs the function (which produces the event to test) + s_zksyncValidator.validate(0, 0, 0, 0); + } + + /// @notice it post sequencer offline + function test_PostSequencerOffline() public { + // Gives access to the s_eoaValidator + s_zksyncValidator.addAccess(s_eoaValidator); + + // Sets block.timestamp to a later date + uint256 futureTimestampInSeconds = block.timestamp + 10000; + vm.startPrank(s_eoaValidator); + vm.warp(futureTimestampInSeconds); + + // Sets up the expected event data + vm.expectEmit(false, false, false, true); + emit SentMessage( + address(s_zksyncValidator), + abi.encodeWithSelector(ISequencerUptimeFeed.updateStatus.selector, true, futureTimestampInSeconds) + ); + + // Runs the function (which produces the event to test) + s_zksyncValidator.validate(0, 0, 1, 1); + } +} From 7b7af642812af9c15b7905530ec8f9b084f39f47 Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:33:45 -0500 Subject: [PATCH 277/432] Update EstimateGasLimit config name to EstimateLimit (#14297) * Updated EstimateGasLimit config name to EstimateLimit * Updated mocks * Fixed linting * Updated changeset --- .changeset/loud-windows-call.md | 2 +- .../ocrimpls/contract_transmitter_test.go | 2 +- .../evm/config/chain_scoped_gas_estimator.go | 4 +- core/chains/evm/config/config.go | 2 +- core/chains/evm/config/config_test.go | 1 + core/chains/evm/config/mocks/gas_estimator.go | 22 +-- core/chains/evm/config/toml/config.go | 16 +-- .../evm/config/toml/defaults/fallback.toml | 2 +- core/chains/evm/gas/helpers_test.go | 6 +- core/chains/evm/gas/models.go | 10 +- core/chains/evm/gas/models_test.go | 12 +- core/chains/evm/txmgr/broadcaster_test.go | 2 +- core/chains/evm/txmgr/test_helpers.go | 2 +- core/config/docs/chains-evm.toml | 4 +- core/services/chainlink/config_test.go | 4 +- .../chainlink/testdata/config-full.toml | 2 +- .../config-multi-chain-effective.toml | 6 +- core/web/resolver/testdata/config-full.toml | 2 +- .../config-multi-chain-effective.toml | 6 +- docs/CONFIG.md | 130 +++++++++--------- .../node/validate/defaults-override.txtar | 2 +- .../disk-based-logging-disabled.txtar | 2 +- .../validate/disk-based-logging-no-dir.txtar | 2 +- .../node/validate/disk-based-logging.txtar | 2 +- testdata/scripts/node/validate/invalid.txtar | 2 +- testdata/scripts/node/validate/valid.txtar | 2 +- 26 files changed, 125 insertions(+), 124 deletions(-) diff --git a/.changeset/loud-windows-call.md b/.changeset/loud-windows-call.md index e05bed706a..6dc8d6fac7 100644 --- a/.changeset/loud-windows-call.md +++ b/.changeset/loud-windows-call.md @@ -2,4 +2,4 @@ "chainlink": minor --- -Added gas limit estimation feature to EVM gas estimators #added +Added gas limit estimation feature to EVM gas estimators. Introduced a new config `EVM.GasEstimator.EstimateLimit` to toggle this feature. #added diff --git a/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go b/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go index 6c39990643..26fc717146 100644 --- a/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go +++ b/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go @@ -613,7 +613,7 @@ func (g *TestGasEstimatorConfig) LimitJobType() evmconfig.LimitJobType { func (g *TestGasEstimatorConfig) PriceMaxKey(addr common.Address) *assets.Wei { return assets.GWei(1) } -func (g *TestGasEstimatorConfig) EstimateGasLimit() bool { return false } +func (g *TestGasEstimatorConfig) EstimateLimit() bool { return false } func (e *TestEvmConfig) GasEstimator() evmconfig.GasEstimator { return &TestGasEstimatorConfig{bumpThreshold: e.BumpThreshold} diff --git a/core/chains/evm/config/chain_scoped_gas_estimator.go b/core/chains/evm/config/chain_scoped_gas_estimator.go index 4f2d8872d8..6f43839b01 100644 --- a/core/chains/evm/config/chain_scoped_gas_estimator.go +++ b/core/chains/evm/config/chain_scoped_gas_estimator.go @@ -108,8 +108,8 @@ func (g *gasEstimatorConfig) LimitJobType() LimitJobType { return &limitJobTypeConfig{c: g.c.LimitJobType} } -func (g *gasEstimatorConfig) EstimateGasLimit() bool { - return *g.c.EstimateGasLimit +func (g *gasEstimatorConfig) EstimateLimit() bool { + return *g.c.EstimateLimit } type limitJobTypeConfig struct { diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index 6d7e7efc09..1a33b08aa3 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -137,7 +137,7 @@ type GasEstimator interface { PriceMin() *assets.Wei Mode() string PriceMaxKey(gethcommon.Address) *assets.Wei - EstimateGasLimit() bool + EstimateLimit() bool } type LimitJobType interface { diff --git a/core/chains/evm/config/config_test.go b/core/chains/evm/config/config_test.go index 678d04425b..6543013927 100644 --- a/core/chains/evm/config/config_test.go +++ b/core/chains/evm/config/config_test.go @@ -243,6 +243,7 @@ func TestChainScopedConfig_GasEstimator(t *testing.T) { assert.Equal(t, assets.GWei(100), ge.FeeCapDefault()) assert.Equal(t, assets.NewWeiI(1), ge.TipCapDefault()) assert.Equal(t, assets.NewWeiI(1), ge.TipCapMin()) + assert.Equal(t, false, ge.EstimateLimit()) } func TestChainScopedConfig_BSCDefaults(t *testing.T) { diff --git a/core/chains/evm/config/mocks/gas_estimator.go b/core/chains/evm/config/mocks/gas_estimator.go index 40c10757b8..96ffff08ae 100644 --- a/core/chains/evm/config/mocks/gas_estimator.go +++ b/core/chains/evm/config/mocks/gas_estimator.go @@ -298,12 +298,12 @@ func (_c *GasEstimator_EIP1559DynamicFees_Call) RunAndReturn(run func() bool) *G return _c } -// EstimateGasLimit provides a mock function with given fields: -func (_m *GasEstimator) EstimateGasLimit() bool { +// EstimateLimit provides a mock function with given fields: +func (_m *GasEstimator) EstimateLimit() bool { ret := _m.Called() if len(ret) == 0 { - panic("no return value specified for EstimateGasLimit") + panic("no return value specified for EstimateLimit") } var r0 bool @@ -316,29 +316,29 @@ func (_m *GasEstimator) EstimateGasLimit() bool { return r0 } -// GasEstimator_EstimateGasLimit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EstimateGasLimit' -type GasEstimator_EstimateGasLimit_Call struct { +// GasEstimator_EstimateLimit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EstimateLimit' +type GasEstimator_EstimateLimit_Call struct { *mock.Call } -// EstimateGasLimit is a helper method to define mock.On call -func (_e *GasEstimator_Expecter) EstimateGasLimit() *GasEstimator_EstimateGasLimit_Call { - return &GasEstimator_EstimateGasLimit_Call{Call: _e.mock.On("EstimateGasLimit")} +// EstimateLimit is a helper method to define mock.On call +func (_e *GasEstimator_Expecter) EstimateLimit() *GasEstimator_EstimateLimit_Call { + return &GasEstimator_EstimateLimit_Call{Call: _e.mock.On("EstimateLimit")} } -func (_c *GasEstimator_EstimateGasLimit_Call) Run(run func()) *GasEstimator_EstimateGasLimit_Call { +func (_c *GasEstimator_EstimateLimit_Call) Run(run func()) *GasEstimator_EstimateLimit_Call { _c.Call.Run(func(args mock.Arguments) { run() }) return _c } -func (_c *GasEstimator_EstimateGasLimit_Call) Return(_a0 bool) *GasEstimator_EstimateGasLimit_Call { +func (_c *GasEstimator_EstimateLimit_Call) Return(_a0 bool) *GasEstimator_EstimateLimit_Call { _c.Call.Return(_a0) return _c } -func (_c *GasEstimator_EstimateGasLimit_Call) RunAndReturn(run func() bool) *GasEstimator_EstimateGasLimit_Call { +func (_c *GasEstimator_EstimateLimit_Call) RunAndReturn(run func() bool) *GasEstimator_EstimateLimit_Call { _c.Call.Return(run) return _c } diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index c7f7228606..1db5a0dcad 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -554,12 +554,12 @@ type GasEstimator struct { PriceMax *assets.Wei PriceMin *assets.Wei - LimitDefault *uint64 - LimitMax *uint64 - LimitMultiplier *decimal.Decimal - LimitTransfer *uint64 - LimitJobType GasLimitJobType `toml:",omitempty"` - EstimateGasLimit *bool + LimitDefault *uint64 + LimitMax *uint64 + LimitMultiplier *decimal.Decimal + LimitTransfer *uint64 + LimitJobType GasLimitJobType `toml:",omitempty"` + EstimateLimit *bool BumpMin *assets.Wei BumpPercent *uint16 @@ -647,8 +647,8 @@ func (e *GasEstimator) setFrom(f *GasEstimator) { if v := f.LimitTransfer; v != nil { e.LimitTransfer = v } - if v := f.EstimateGasLimit; v != nil { - e.EstimateGasLimit = v + if v := f.EstimateLimit; v != nil { + e.EstimateLimit = v } if v := f.PriceDefault; v != nil { e.PriceDefault = v diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index a01d0801cc..e2587ed744 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -47,7 +47,7 @@ EIP1559DynamicFees = false FeeCapDefault = '100 gwei' TipCapDefault = '1' TipCapMin = '1' -EstimateGasLimit = false +EstimateLimit = false [GasEstimator.BlockHistory] BatchSize = 25 diff --git a/core/chains/evm/gas/helpers_test.go b/core/chains/evm/gas/helpers_test.go index d6af645fe8..ae93d9e8c7 100644 --- a/core/chains/evm/gas/helpers_test.go +++ b/core/chains/evm/gas/helpers_test.go @@ -157,7 +157,7 @@ type MockGasEstimatorConfig struct { FeeCapDefaultF *assets.Wei LimitMaxF uint64 ModeF string - EstimateGasLimitF bool + EstimateLimitF bool } func NewMockGasConfig() *MockGasEstimatorConfig { @@ -216,6 +216,6 @@ func (m *MockGasEstimatorConfig) Mode() string { return m.ModeF } -func (m *MockGasEstimatorConfig) EstimateGasLimit() bool { - return m.EstimateGasLimitF +func (m *MockGasEstimatorConfig) EstimateLimit() bool { + return m.EstimateLimitF } diff --git a/core/chains/evm/gas/models.go b/core/chains/evm/gas/models.go index 00062d8462..fda9425c22 100644 --- a/core/chains/evm/gas/models.go +++ b/core/chains/evm/gas/models.go @@ -26,7 +26,7 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) -// EstimateGasBuffer is a multiplier applied to estimated gas when the EstimateGasLimit feature is enabled +// EstimateGasBuffer is a multiplier applied to estimated gas when the EstimateLimit feature is enabled const EstimateGasBuffer = float32(1.15) // EvmFeeEstimator provides a unified interface that wraps EvmEstimator and can determine if legacy or dynamic fee estimation should be used @@ -74,7 +74,7 @@ func NewEstimator(lggr logger.Logger, ethClient feeEstimatorClient, cfg Config, "tipCapMin", geCfg.TipCapMin(), "priceMax", geCfg.PriceMax(), "priceMin", geCfg.PriceMin(), - "estimateGasLimit", geCfg.EstimateGasLimit(), + "estimateLimit", geCfg.EstimateLimit(), ) df := geCfg.EIP1559DynamicFees() @@ -352,8 +352,8 @@ func (e *evmFeeEstimator) estimateFeeLimit(ctx context.Context, feeLimit uint64, if err != nil { return estimatedFeeLimit, err } - // Use provided fee limit by default if EstimateGasLimit is disabled - if !e.geCfg.EstimateGasLimit() { + // Use provided fee limit by default if EstimateLimit is disabled + if !e.geCfg.EstimateLimit() { return providedGasLimit, nil } // Create call msg for gas limit estimation @@ -417,7 +417,7 @@ type GasEstimatorConfig interface { PriceMin() *assets.Wei PriceMax() *assets.Wei Mode() string - EstimateGasLimit() bool + EstimateLimit() bool } type BlockHistoryConfig interface { diff --git a/core/chains/evm/gas/models_test.go b/core/chains/evm/gas/models_test.go index ea5e53c228..f2afc26c85 100644 --- a/core/chains/evm/gas/models_test.go +++ b/core/chains/evm/gas/models_test.go @@ -261,7 +261,7 @@ func TestWrappedEvmEstimator(t *testing.T) { lggr := logger.Test(t) // expect legacy fee data dynamicFees := false - geCfg.EstimateGasLimitF = true + geCfg.EstimateLimitF = true ethClient := testutils.NewEthClientMockWithDefaultChain(t) ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Twice() estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) @@ -288,7 +288,7 @@ func TestWrappedEvmEstimator(t *testing.T) { lggr := logger.Test(t) // expect legacy fee data dynamicFees := false - geCfg.EstimateGasLimitF = true + geCfg.EstimateLimitF = true ethClient := testutils.NewEthClientMockWithDefaultChain(t) ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Twice() estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) @@ -306,7 +306,7 @@ func TestWrappedEvmEstimator(t *testing.T) { estimatedGasLimit := uint64(15) // same as provided limit lggr := logger.Test(t) dynamicFees := false // expect legacy fee data - geCfg.EstimateGasLimitF = true + geCfg.EstimateLimitF = true ethClient := testutils.NewEthClientMockWithDefaultChain(t) ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Twice() estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) @@ -331,7 +331,7 @@ func TestWrappedEvmEstimator(t *testing.T) { lggr := logger.Test(t) // expect legacy fee data dynamicFees := false - geCfg.EstimateGasLimitF = true + geCfg.EstimateLimitF = true ethClient := testutils.NewEthClientMockWithDefaultChain(t) ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(uint64(0), errors.New("something broke")).Twice() estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) @@ -362,7 +362,7 @@ func TestWrappedEvmEstimator(t *testing.T) { lggr := logger.Test(t) // expect legacy fee data dynamicFees := false - geCfg.EstimateGasLimitF = true + geCfg.EstimateLimitF = true ethClient := testutils.NewEthClientMockWithDefaultChain(t) ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(estimatedGasLimit, nil).Twice() estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) @@ -392,7 +392,7 @@ func TestWrappedEvmEstimator(t *testing.T) { lggr := logger.Test(t) // expect legacy fee data dynamicFees := false - geCfg.EstimateGasLimitF = true + geCfg.EstimateLimitF = true ethClient := testutils.NewEthClientMockWithDefaultChain(t) ethClient.On("EstimateGas", mock.Anything, mock.Anything).Return(uint64(0), errors.New("something broke")).Twice() estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg, ethClient) diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 41f50f4434..514d533159 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -1676,7 +1676,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_GasEstimationError(t *testing.T) db := pgtest.NewSqlxDB(t) cfg := configtest.NewTestGeneralConfig(t) - cfg.EVMConfigs()[0].GasEstimator.EstimateGasLimit = ptr(true) // Enabled gas limit estimation + cfg.EVMConfigs()[0].GasEstimator.EstimateLimit = ptr(true) // Enabled gas limit estimation limitMultiplier := float32(1.25) cfg.EVMConfigs()[0].GasEstimator.LimitMultiplier = ptr(decimal.NewFromFloat32(limitMultiplier)) // Set LimitMultiplier for the buffer txStore := cltest.NewTestTxStore(t, db) diff --git a/core/chains/evm/txmgr/test_helpers.go b/core/chains/evm/txmgr/test_helpers.go index 3dea024352..48b2432fd0 100644 --- a/core/chains/evm/txmgr/test_helpers.go +++ b/core/chains/evm/txmgr/test_helpers.go @@ -92,7 +92,7 @@ func (g *TestGasEstimatorConfig) LimitTransfer() uint64 { return 42 } func (g *TestGasEstimatorConfig) PriceMax() *assets.Wei { return assets.NewWeiI(42) } func (g *TestGasEstimatorConfig) PriceMin() *assets.Wei { return assets.NewWeiI(42) } func (g *TestGasEstimatorConfig) Mode() string { return "FixedPrice" } -func (g *TestGasEstimatorConfig) EstimateGasLimit() bool { return false } +func (g *TestGasEstimatorConfig) EstimateLimit() bool { return false } func (g *TestGasEstimatorConfig) LimitJobType() evmconfig.LimitJobType { return &TestLimitJobTypeConfig{} } diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index fceffe539e..d6d6bdf9f5 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -193,8 +193,8 @@ LimitMax = 500_000 # Default LimitMultiplier = '1.0' # Default # LimitTransfer is the gas limit used for an ordinary ETH transfer. LimitTransfer = 21_000 # Default -# EstimateGasLimit enables estimating gas limits for transactions. This feature respects the gas limit provided during transaction creation as an upper bound. -EstimateGasLimit = false # Default +# EstimateLimit enables estimating gas limits for transactions. This feature respects the gas limit provided during transaction creation as an upper bound. +EstimateLimit = false # Default # BumpMin is the minimum fixed amount of wei by which gas is bumped on each transaction attempt. BumpMin = '5 gwei' # Default # BumpPercent is the percentage by which to bump gas on a transaction that has exceeded `BumpThreshold`. The larger of `BumpPercent` and `BumpMin` is taken for gas bumps. diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 52ad0487d5..583e7cb1f4 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -531,7 +531,7 @@ func TestConfig_Marshal(t *testing.T) { LimitMax: ptr[uint64](17), LimitMultiplier: mustDecimal("1.234"), LimitTransfer: ptr[uint64](100), - EstimateGasLimit: ptr(false), + EstimateLimit: ptr(false), TipCapDefault: assets.NewWeiI(2), TipCapMin: assets.NewWeiI(1), PriceDefault: assets.NewWeiI(math.MaxInt64), @@ -1041,7 +1041,7 @@ LimitDefault = 12 LimitMax = 17 LimitMultiplier = '1.234' LimitTransfer = 100 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 wei' BumpPercent = 10 BumpThreshold = 6 diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 77f60ef550..0a5678b2e4 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -327,7 +327,7 @@ LimitDefault = 12 LimitMax = 17 LimitMultiplier = '1.234' LimitTransfer = 100 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 wei' BumpPercent = 10 BumpThreshold = 6 diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index e7d0244606..065cdfe0cb 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -314,7 +314,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -418,7 +418,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -516,7 +516,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '20 gwei' BumpPercent = 20 BumpThreshold = 5 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 426caf39eb..f9befd487d 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -327,7 +327,7 @@ LimitDefault = 12 LimitMax = 17 LimitMultiplier = '1.234' LimitTransfer = 100 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 wei' BumpPercent = 10 BumpThreshold = 6 diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 658d364d10..3d13f2b64c 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -314,7 +314,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -418,7 +418,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -516,7 +516,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '20 gwei' BumpPercent = 20 BumpThreshold = 5 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index d10da596e7..d7e7c0af0a 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1879,7 +1879,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -1977,7 +1977,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2075,7 +2075,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2173,7 +2173,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2272,7 +2272,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -2370,7 +2370,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2468,7 +2468,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2567,7 +2567,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2665,7 +2665,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -2762,7 +2762,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2859,7 +2859,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -2957,7 +2957,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -3056,7 +3056,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -3154,7 +3154,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -3252,7 +3252,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '20 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -3350,7 +3350,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '20 mwei' BumpPercent = 40 BumpThreshold = 3 @@ -3448,7 +3448,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 mwei' BumpPercent = 40 BumpThreshold = 3 @@ -3546,7 +3546,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -3644,7 +3644,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -3742,7 +3742,7 @@ LimitDefault = 100000000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -3840,7 +3840,7 @@ LimitDefault = 100000000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -3938,7 +3938,7 @@ LimitDefault = 100000000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -4037,7 +4037,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -4135,7 +4135,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -4232,7 +4232,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -4330,7 +4330,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -4428,7 +4428,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 mwei' BumpPercent = 40 BumpThreshold = 3 @@ -4526,7 +4526,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -4624,7 +4624,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -4721,7 +4721,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 0 @@ -4819,7 +4819,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '20 mwei' BumpPercent = 40 BumpThreshold = 3 @@ -4917,7 +4917,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -5015,7 +5015,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '20 mwei' BumpPercent = 40 BumpThreshold = 3 @@ -5113,7 +5113,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -5210,7 +5210,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -5308,7 +5308,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -5406,7 +5406,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -5505,7 +5505,7 @@ LimitDefault = 500000 LimitMax = 1000000000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -5604,7 +5604,7 @@ LimitDefault = 500000 LimitMax = 1000000000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -5703,7 +5703,7 @@ LimitDefault = 500000 LimitMax = 1000000000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -5801,7 +5801,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '2 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -5899,7 +5899,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -5997,7 +5997,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -6095,7 +6095,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '2 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -6192,7 +6192,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 40 BumpThreshold = 3 @@ -6289,7 +6289,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -6386,7 +6386,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 40 BumpThreshold = 3 @@ -6484,7 +6484,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -6582,7 +6582,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '20 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -6679,7 +6679,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '20 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -6777,7 +6777,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -6875,7 +6875,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -6974,7 +6974,7 @@ LimitDefault = 500000 LimitMax = 1000000000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -7073,7 +7073,7 @@ LimitDefault = 500000 LimitMax = 1000000000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -7171,7 +7171,7 @@ LimitDefault = 500000 LimitMax = 1000000000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 5 @@ -7269,7 +7269,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '1 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -7367,7 +7367,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '1 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -7465,7 +7465,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -7563,7 +7563,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '100 wei' BumpPercent = 20 BumpThreshold = 3 @@ -7661,7 +7661,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -7759,7 +7759,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 @@ -8124,7 +8124,7 @@ LimitDefault = 500_000 # Default LimitMax = 500_000 # Default LimitMultiplier = '1.0' # Default LimitTransfer = 21_000 # Default -EstimateGasLimit = false # Default +EstimateLimit = false # Default BumpMin = '5 gwei' # Default BumpPercent = 20 # Default BumpThreshold = 3 # Default @@ -8219,11 +8219,11 @@ LimitTransfer = 21_000 # Default ``` LimitTransfer is the gas limit used for an ordinary ETH transfer. -### EstimateGasLimit +### EstimateLimit ```toml -EstimateGasLimit = false # Default +EstimateLimit = false # Default ``` -EstimateGasLimit enables estimating gas limits for transactions. This feature respects the gas limit provided during transaction creation as an upper bound. +EstimateLimit enables estimating gas limits for transactions. This feature respects the gas limit provided during transaction creation as an upper bound. ### BumpMin ```toml diff --git a/testdata/scripts/node/validate/defaults-override.txtar b/testdata/scripts/node/validate/defaults-override.txtar index 3accd1584b..f02605a49e 100644 --- a/testdata/scripts/node/validate/defaults-override.txtar +++ b/testdata/scripts/node/validate/defaults-override.txtar @@ -387,7 +387,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index 26544e5801..3cb365afa1 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -370,7 +370,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 17d86ef41e..083aca41b0 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -370,7 +370,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index e8eb6b93d0..34911e3e48 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -370,7 +370,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 4bfa96d302..aa4b7960bd 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -360,7 +360,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index cea4c1b4f8..bf21436c2e 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -367,7 +367,7 @@ LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 -EstimateGasLimit = false +EstimateLimit = false BumpMin = '5 gwei' BumpPercent = 20 BumpThreshold = 3 From a234e14ebd266269b4d5893b0d2aeeb01bc58a70 Mon Sep 17 00:00:00 2001 From: Joe Huang Date: Tue, 3 Sep 2024 14:41:22 -0500 Subject: [PATCH 278/432] Bci 3621/try new estimation for insufficient fund error instead of retry (#14234) * update insufficient fund error to retry new estimation * add comment * add change set * modify * fix test * rewrite unit test to modify chain config locally in the unit test * remove a previous change * remove unrelated comment * extra * rephrase * update comments * refactor * revert unit test * update comments * refactor func call args * rename * modify test * fix * revert function param * changeset * changeset * rephrase * address comments, refactor * refactor func name * modify retrycount * fix unit tests * rename * rename * small refactor * nit * update error * modify test * add comments * rm unused * comments * fix * adding returned retryable * return true for retryable * one more * address comments * revert changes in unit test, just update comment * update comment --- .changeset/pretty-trees-smile.md | 5 ++ common/txmgr/broadcaster.go | 74 +++++++++++++---------- core/chains/evm/txmgr/broadcaster_test.go | 2 +- 3 files changed, 47 insertions(+), 34 deletions(-) create mode 100644 .changeset/pretty-trees-smile.md diff --git a/.changeset/pretty-trees-smile.md b/.changeset/pretty-trees-smile.md new file mode 100644 index 0000000000..2019ff0a58 --- /dev/null +++ b/.changeset/pretty-trees-smile.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +use new estimation for insufficient fund instead of retry to overcome gas spike #internal diff --git a/common/txmgr/broadcaster.go b/common/txmgr/broadcaster.go index 1606f58ce0..86475c2e0e 100644 --- a/common/txmgr/broadcaster.go +++ b/common/txmgr/broadcaster.go @@ -558,21 +558,33 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand eb.sequenceTracker.GenerateNextSequence(etx.FromAddress, *etx.Sequence) return err, true case client.Underpriced: - return eb.tryAgainBumpingGas(ctx, lgr, err, etx, attempt, initialBroadcastAt, retryCount+1) + bumpedAttempt, retryable, replaceErr := eb.replaceAttemptWithBumpedGas(ctx, lgr, err, etx, attempt) + if replaceErr != nil { + return replaceErr, retryable + } + + return eb.handleInProgressTx(ctx, etx, bumpedAttempt, initialBroadcastAt, retryCount+1) case client.InsufficientFunds: - // NOTE: This bails out of the entire cycle and essentially "blocks" on - // any transaction that gets insufficient_funds. This is OK if a - // transaction with a large VALUE blocks because this always comes last - // in the processing list. - // If it blocks because of a transaction that is expensive due to large - // gas limit, we could have smaller transactions "above" it that could - // theoretically be sent, but will instead be blocked. + // NOTE: This can occur due to either insufficient funds or a gas spike + // combined with a high gas limit. Regardless of the cause, we need to obtain a new estimate, + // replace the current attempt, and retry after the backoff duration. + // The new attempt must be replaced immediately because of a database constraint. eb.SvcErrBuffer.Append(err) - fallthrough + if _, _, replaceErr := eb.replaceAttemptWithNewEstimation(ctx, lgr, etx, attempt); replaceErr != nil { + return replaceErr, true + } + return err, true case client.Retryable: return err, true case client.FeeOutOfValidRange: - return eb.tryAgainWithNewEstimation(ctx, lgr, err, etx, attempt, initialBroadcastAt) + replacementAttempt, retryable, replaceErr := eb.replaceAttemptWithNewEstimation(ctx, lgr, etx, attempt) + if replaceErr != nil { + return replaceErr, retryable + } + + lgr.Warnw("L2 rejected transaction due to incorrect fee, re-estimated and will try again", + "etxID", etx.ID, "err", err, "newGasPrice", replacementAttempt.TxFee, "newGasLimit", replacementAttempt.ChainSpecificFeeLimit) + return eb.handleInProgressTx(ctx, etx, *replacementAttempt, initialBroadcastAt, 0) case client.Unsupported: return err, false case client.ExceedsMaxFee: @@ -680,7 +692,8 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) next return etx, nil } -func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryAgainBumpingGas(ctx context.Context, lgr logger.Logger, txError error, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time, retry int) (err error, retryable bool) { +// replaceAttemptWithBumpedGas performs the replacement of the existing tx attempt with a new bumped fee attempt. +func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) replaceAttemptWithBumpedGas(ctx context.Context, lgr logger.Logger, txError error, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) (replacedAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], retryable bool, err error) { // This log error is not applicable to Hedera since the action required would not be needed for its gas estimator if eb.chainType != hederaChainType { logger.With(lgr, @@ -694,37 +707,32 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryA attempt.TxFee, txError.Error(), eb.feeConfig.FeePriceDefault()) } - replacementAttempt, bumpedFee, bumpedFeeLimit, retryable, err := eb.NewBumpTxAttempt(ctx, etx, attempt, nil, lgr) + bumpedAttempt, bumpedFee, bumpedFeeLimit, retryable, err := eb.NewBumpTxAttempt(ctx, etx, attempt, nil, lgr) if err != nil { - return fmt.Errorf("tryAgainBumpFee failed: %w", err), retryable + return bumpedAttempt, retryable, err } - return eb.saveTryAgainAttempt(ctx, lgr, etx, attempt, replacementAttempt, initialBroadcastAt, bumpedFee, bumpedFeeLimit, retry) -} - -func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryAgainWithNewEstimation(ctx context.Context, lgr logger.Logger, txError error, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time) (err error, retryable bool) { - if attempt.TxType == 0x2 { - err = fmt.Errorf("re-estimation is not supported for EIP-1559 transactions. Node returned error: %v. This is a bug", txError.Error()) - logger.Sugared(eb.lggr).AssumptionViolation(err.Error()) - return err, false + if err = eb.txStore.SaveReplacementInProgressAttempt(ctx, attempt, &bumpedAttempt); err != nil { + return bumpedAttempt, true, err } - replacementAttempt, fee, feeLimit, retryable, err := eb.NewTxAttemptWithType(ctx, etx, lgr, attempt.TxType, feetypes.OptForceRefetch) + lgr.Debugw("Bumped fee on initial send", "oldFee", attempt.TxFee.String(), "newFee", bumpedFee.String(), "newFeeLimit", bumpedFeeLimit) + return bumpedAttempt, true, err +} + +// replaceAttemptWithNewEstimation performs the replacement of the existing tx attempt with a new estimated fee attempt. +func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) replaceAttemptWithNewEstimation(ctx context.Context, lgr logger.Logger, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) (updatedAttempt *txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], retryable bool, err error) { + newEstimatedAttempt, fee, feeLimit, retryable, err := eb.NewTxAttemptWithType(ctx, etx, lgr, attempt.TxType, feetypes.OptForceRefetch) if err != nil { - return fmt.Errorf("tryAgainWithNewEstimation failed to build new attempt: %w", err), retryable + return &newEstimatedAttempt, retryable, err } - lgr.Warnw("L2 rejected transaction due to incorrect fee, re-estimated and will try again", - "etxID", etx.ID, "err", err, "newGasPrice", fee, "newGasLimit", feeLimit) - return eb.saveTryAgainAttempt(ctx, lgr, etx, attempt, replacementAttempt, initialBroadcastAt, fee, feeLimit, 0) -} - -func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) saveTryAgainAttempt(ctx context.Context, lgr logger.Logger, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], replacementAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time, newFee FEE, newFeeLimit uint64, retry int) (err error, retyrable bool) { - if err = eb.txStore.SaveReplacementInProgressAttempt(ctx, attempt, &replacementAttempt); err != nil { - return fmt.Errorf("tryAgainWithNewFee failed: %w", err), true + if err = eb.txStore.SaveReplacementInProgressAttempt(ctx, attempt, &newEstimatedAttempt); err != nil { + return &newEstimatedAttempt, true, err } - lgr.Debugw("Bumped fee on initial send", "oldFee", attempt.TxFee.String(), "newFee", newFee.String(), "newFeeLimit", newFeeLimit) - return eb.handleInProgressTx(ctx, etx, replacementAttempt, initialBroadcastAt, retry) + + lgr.Debugw("new estimated fee on initial send", "oldFee", attempt.TxFee.String(), "newFee", fee.String(), "newFeeLimit", feeLimit) + return &newEstimatedAttempt, true, err } func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) saveFatallyErroredTransaction(lgr logger.Logger, etx *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) error { diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 514d533159..10e9002eab 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -1524,7 +1524,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { pgtest.MustExec(t, db, `DELETE FROM evm.txes WHERE nonce = $1`, localNextNonce) }) - t.Run("eth tx is left in progress if eth node returns insufficient eth", func(t *testing.T) { + t.Run("tx is left in progress and its attempt gets replaced with a new re-estimated attempt if node returns insufficient eth", func(t *testing.T) { insufficientEthError := "insufficient funds for transfer" localNextNonce := getLocalNextNonce(t, nonceTracker, fromAddress) etx := mustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, testutils.FixtureChainID) From 1ea9f79793f646977b44e38a34b2e70c28b2849e Mon Sep 17 00:00:00 2001 From: Dimitris Grigoriou Date: Wed, 4 Sep 2024 05:13:55 +0300 Subject: [PATCH 279/432] FeeHistory estimator (#13833) * Introduce universal estimator * Fixes * Use WeiMin to cap bump price * Update connectivity logic * Fix error * Fixes * Cover an edge case when enforcing limits * Add changeset * Update mempool check logic * Update config names * Convert Universal Estimator to service * Client changes to support UE * Introduce configs * Update mocks * Fix lint * Fix test cases * Fix mockery * Fix test cases * Update comment * Fix Start/Close sync issue * Address feedback * Fix lint * Fix lint * More changes * Add more comments * Fix merge conflicts * Update CONFIG * Rename to FeeHistory estimator * Rename * Exclude zero priced priority fees * Remove HasMempool * Remove testing commit * Fixes * Add DefaultJitter * Add optimizations * Fix testscripts * Fix name * Update error messages --- .changeset/shiny-hornets-pretend.md | 5 + .mockery.yaml | 3 + common/fee/models.go | 2 +- common/fee/utils.go | 2 +- .../ocrimpls/contract_transmitter_test.go | 8 + core/chains/evm/client/chain_client.go | 9 + core/chains/evm/client/mocks/client.go | 60 ++ core/chains/evm/client/mocks/rpc_client.go | 60 ++ core/chains/evm/client/null_client.go | 4 + core/chains/evm/client/rpc_client.go | 25 + .../evm/client/simulated_backend_client.go | 4 + .../evm/config/chain_scoped_gas_estimator.go | 14 + core/chains/evm/config/config.go | 5 + core/chains/evm/config/config_test.go | 7 + core/chains/evm/config/mocks/gas_estimator.go | 47 ++ core/chains/evm/config/toml/config.go | 12 + .../evm/config/toml/defaults/fallback.toml | 3 + core/chains/evm/gas/fee_history_estimator.go | 440 +++++++++++++++ .../evm/gas/fee_history_estimator_test.go | 513 ++++++++++++++++++ .../evm/gas/mocks/fee_estimator_client.go | 118 ++++ .../gas/mocks/fee_history_estimator_client.go | 157 ++++++ core/chains/evm/gas/models.go | 14 + core/chains/evm/txmgr/test_helpers.go | 10 + core/config/docs/chains-evm.toml | 9 + core/services/chainlink/config_test.go | 6 + .../chainlink/testdata/config-full.toml | 3 + .../config-multi-chain-effective.toml | 9 + core/web/resolver/testdata/config-full.toml | 3 + .../config-multi-chain-effective.toml | 9 + docs/CONFIG.md | 201 +++++++ .../node/validate/defaults-override.txtar | 3 + .../disk-based-logging-disabled.txtar | 3 + .../validate/disk-based-logging-no-dir.txtar | 3 + .../node/validate/disk-based-logging.txtar | 3 + testdata/scripts/node/validate/invalid.txtar | 3 + testdata/scripts/node/validate/valid.txtar | 3 + 36 files changed, 1778 insertions(+), 2 deletions(-) create mode 100644 .changeset/shiny-hornets-pretend.md create mode 100644 core/chains/evm/gas/fee_history_estimator.go create mode 100644 core/chains/evm/gas/fee_history_estimator_test.go create mode 100644 core/chains/evm/gas/mocks/fee_history_estimator_client.go diff --git a/.changeset/shiny-hornets-pretend.md b/.changeset/shiny-hornets-pretend.md new file mode 100644 index 0000000000..ff9946f4e7 --- /dev/null +++ b/.changeset/shiny-hornets-pretend.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Introduce new gas estimator #internal diff --git a/.mockery.yaml b/.mockery.yaml index d21fbb467f..8d9e6de4ee 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -69,6 +69,9 @@ packages: feeEstimatorClient: config: mockname: FeeEstimatorClient + feeHistoryEstimatorClient: + config: + mockname: FeeHistoryEstimatorClient EvmEstimator: github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups: interfaces: diff --git a/common/fee/models.go b/common/fee/models.go index 0496d3929c..0cc479d356 100644 --- a/common/fee/models.go +++ b/common/fee/models.go @@ -64,7 +64,7 @@ func CalculateBumpedFee( // Returns highest bumped fee price of originalFeePrice bumped by fixed units or percentage. func MaxBumpedFee(originalFeePrice *big.Int, feeBumpPercent uint16, feeBumpUnits *big.Int) *big.Int { return bigmath.Max( - addPercentage(originalFeePrice, feeBumpPercent), + AddPercentage(originalFeePrice, feeBumpPercent), new(big.Int).Add(originalFeePrice, feeBumpUnits), ) } diff --git a/common/fee/utils.go b/common/fee/utils.go index 26323e11e2..3d4b001e83 100644 --- a/common/fee/utils.go +++ b/common/fee/utils.go @@ -18,7 +18,7 @@ func ApplyMultiplier(feeLimit uint64, multiplier float32) (uint64, error) { } // Returns the input value increased by the given percentage. -func addPercentage(value *big.Int, percentage uint16) *big.Int { +func AddPercentage(value *big.Int, percentage uint16) *big.Int { bumped := new(big.Int) bumped.Mul(value, big.NewInt(int64(100+percentage))) bumped.Div(bumped, big.NewInt(100)) diff --git a/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go b/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go index 26fc717146..eae7abae9d 100644 --- a/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go +++ b/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go @@ -591,6 +591,10 @@ func (g *TestGasEstimatorConfig) BlockHistory() evmconfig.BlockHistory { return &TestBlockHistoryConfig{} } +func (g *TestGasEstimatorConfig) FeeHistory() evmconfig.FeeHistory { + return &TestFeeHistoryConfig{} +} + func (g *TestGasEstimatorConfig) EIP1559DynamicFees() bool { return false } func (g *TestGasEstimatorConfig) LimitDefault() uint64 { return 1e6 } func (g *TestGasEstimatorConfig) BumpPercent() uint16 { return 2 } @@ -639,6 +643,10 @@ func (b *TestBlockHistoryConfig) BlockHistorySize() uint16 { return 42 func (b *TestBlockHistoryConfig) EIP1559FeeCapBufferBlocks() uint16 { return 42 } func (b *TestBlockHistoryConfig) TransactionPercentile() uint16 { return 42 } +type TestFeeHistoryConfig struct { + evmconfig.FeeHistory +} + type transactionsConfig struct { evmconfig.Transactions e *TestEvmConfig diff --git a/core/chains/evm/client/chain_client.go b/core/chains/evm/client/chain_client.go index c27d294ebf..310528424d 100644 --- a/core/chains/evm/client/chain_client.go +++ b/core/chains/evm/client/chain_client.go @@ -84,6 +84,7 @@ type Client interface { SuggestGasPrice(ctx context.Context) (*big.Int, error) SuggestGasTipCap(ctx context.Context) (*big.Int, error) LatestBlockHeight(ctx context.Context) (*big.Int, error) + FeeHistory(ctx context.Context, blockCount uint64, rewardPercentiles []float64) (feeHistory *ethereum.FeeHistory, err error) HeaderByNumber(ctx context.Context, n *big.Int) (*types.Header, error) HeaderByHash(ctx context.Context, h common.Hash) (*types.Header, error) @@ -353,6 +354,14 @@ func (c *chainClient) LatestFinalizedBlock(ctx context.Context) (*evmtypes.Head, return c.multiNode.LatestFinalizedBlock(ctx) } +func (c *chainClient) FeeHistory(ctx context.Context, blockCount uint64, rewardPercentiles []float64) (feeHistory *ethereum.FeeHistory, err error) { + rpc, err := c.multiNode.SelectNodeRPC() + if err != nil { + return feeHistory, err + } + return rpc.FeeHistory(ctx, blockCount, rewardPercentiles) +} + func (c *chainClient) CheckTxValidity(ctx context.Context, from common.Address, to common.Address, data []byte) *SendError { msg := ethereum.CallMsg{ From: from, diff --git a/core/chains/evm/client/mocks/client.go b/core/chains/evm/client/mocks/client.go index 7b5220033b..da034d9577 100644 --- a/core/chains/evm/client/mocks/client.go +++ b/core/chains/evm/client/mocks/client.go @@ -780,6 +780,66 @@ func (_c *Client_EstimateGas_Call) RunAndReturn(run func(context.Context, ethere return _c } +// FeeHistory provides a mock function with given fields: ctx, blockCount, rewardPercentiles +func (_m *Client) FeeHistory(ctx context.Context, blockCount uint64, rewardPercentiles []float64) (*ethereum.FeeHistory, error) { + ret := _m.Called(ctx, blockCount, rewardPercentiles) + + if len(ret) == 0 { + panic("no return value specified for FeeHistory") + } + + var r0 *ethereum.FeeHistory + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, []float64) (*ethereum.FeeHistory, error)); ok { + return rf(ctx, blockCount, rewardPercentiles) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, []float64) *ethereum.FeeHistory); ok { + r0 = rf(ctx, blockCount, rewardPercentiles) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*ethereum.FeeHistory) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, []float64) error); ok { + r1 = rf(ctx, blockCount, rewardPercentiles) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Client_FeeHistory_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FeeHistory' +type Client_FeeHistory_Call struct { + *mock.Call +} + +// FeeHistory is a helper method to define mock.On call +// - ctx context.Context +// - blockCount uint64 +// - rewardPercentiles []float64 +func (_e *Client_Expecter) FeeHistory(ctx interface{}, blockCount interface{}, rewardPercentiles interface{}) *Client_FeeHistory_Call { + return &Client_FeeHistory_Call{Call: _e.mock.On("FeeHistory", ctx, blockCount, rewardPercentiles)} +} + +func (_c *Client_FeeHistory_Call) Run(run func(ctx context.Context, blockCount uint64, rewardPercentiles []float64)) *Client_FeeHistory_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].([]float64)) + }) + return _c +} + +func (_c *Client_FeeHistory_Call) Return(feeHistory *ethereum.FeeHistory, err error) *Client_FeeHistory_Call { + _c.Call.Return(feeHistory, err) + return _c +} + +func (_c *Client_FeeHistory_Call) RunAndReturn(run func(context.Context, uint64, []float64) (*ethereum.FeeHistory, error)) *Client_FeeHistory_Call { + _c.Call.Return(run) + return _c +} + // FilterLogs provides a mock function with given fields: ctx, q func (_m *Client) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) { ret := _m.Called(ctx, q) diff --git a/core/chains/evm/client/mocks/rpc_client.go b/core/chains/evm/client/mocks/rpc_client.go index 06f79efd55..5567b3f897 100644 --- a/core/chains/evm/client/mocks/rpc_client.go +++ b/core/chains/evm/client/mocks/rpc_client.go @@ -889,6 +889,66 @@ func (_c *RPCClient_EstimateGas_Call) RunAndReturn(run func(context.Context, int return _c } +// FeeHistory provides a mock function with given fields: ctx, blockCount, rewardPercentiles +func (_m *RPCClient) FeeHistory(ctx context.Context, blockCount uint64, rewardPercentiles []float64) (*ethereum.FeeHistory, error) { + ret := _m.Called(ctx, blockCount, rewardPercentiles) + + if len(ret) == 0 { + panic("no return value specified for FeeHistory") + } + + var r0 *ethereum.FeeHistory + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, []float64) (*ethereum.FeeHistory, error)); ok { + return rf(ctx, blockCount, rewardPercentiles) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, []float64) *ethereum.FeeHistory); ok { + r0 = rf(ctx, blockCount, rewardPercentiles) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*ethereum.FeeHistory) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, []float64) error); ok { + r1 = rf(ctx, blockCount, rewardPercentiles) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RPCClient_FeeHistory_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FeeHistory' +type RPCClient_FeeHistory_Call struct { + *mock.Call +} + +// FeeHistory is a helper method to define mock.On call +// - ctx context.Context +// - blockCount uint64 +// - rewardPercentiles []float64 +func (_e *RPCClient_Expecter) FeeHistory(ctx interface{}, blockCount interface{}, rewardPercentiles interface{}) *RPCClient_FeeHistory_Call { + return &RPCClient_FeeHistory_Call{Call: _e.mock.On("FeeHistory", ctx, blockCount, rewardPercentiles)} +} + +func (_c *RPCClient_FeeHistory_Call) Run(run func(ctx context.Context, blockCount uint64, rewardPercentiles []float64)) *RPCClient_FeeHistory_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].([]float64)) + }) + return _c +} + +func (_c *RPCClient_FeeHistory_Call) Return(feeHistory *ethereum.FeeHistory, err error) *RPCClient_FeeHistory_Call { + _c.Call.Return(feeHistory, err) + return _c +} + +func (_c *RPCClient_FeeHistory_Call) RunAndReturn(run func(context.Context, uint64, []float64) (*ethereum.FeeHistory, error)) *RPCClient_FeeHistory_Call { + _c.Call.Return(run) + return _c +} + // FilterEvents provides a mock function with given fields: ctx, query func (_m *RPCClient) FilterEvents(ctx context.Context, query ethereum.FilterQuery) ([]coretypes.Log, error) { ret := _m.Called(ctx, query) diff --git a/core/chains/evm/client/null_client.go b/core/chains/evm/client/null_client.go index 3129bcff9b..5b1a4d7e1b 100644 --- a/core/chains/evm/client/null_client.go +++ b/core/chains/evm/client/null_client.go @@ -235,3 +235,7 @@ func (nc *NullClient) LatestFinalizedBlock(_ context.Context) (*evmtypes.Head, e func (nc *NullClient) CheckTxValidity(_ context.Context, _ common.Address, _ common.Address, _ []byte) *SendError { return nil } + +func (nc *NullClient) FeeHistory(ctx context.Context, blockCount uint64, rewardPercentiles []float64) (feeHistory *ethereum.FeeHistory, err error) { + return nil, nil +} diff --git a/core/chains/evm/client/rpc_client.go b/core/chains/evm/client/rpc_client.go index 53ab46a696..0752def994 100644 --- a/core/chains/evm/client/rpc_client.go +++ b/core/chains/evm/client/rpc_client.go @@ -103,6 +103,7 @@ type RPCClient interface { SuggestGasTipCap(ctx context.Context) (t *big.Int, err error) TransactionReceiptGeth(ctx context.Context, txHash common.Hash) (r *types.Receipt, err error) GetInterceptedChainInfo() (latest, highestUserObservations commonclient.ChainInfo) + FeeHistory(ctx context.Context, blockCount uint64, rewardPercentiles []float64) (feeHistory *ethereum.FeeHistory, err error) } const rpcSubscriptionMethodNewHeads = "newHeads" @@ -599,6 +600,7 @@ func (r *rpcClient) TransactionReceiptGeth(ctx context.Context, txHash common.Ha return } + func (r *rpcClient) TransactionByHash(ctx context.Context, txHash common.Hash) (tx *types.Transaction, err error) { ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) defer cancel() @@ -1119,6 +1121,29 @@ func (r *rpcClient) BalanceAt(ctx context.Context, account common.Address, block return } +func (r *rpcClient) FeeHistory(ctx context.Context, blockCount uint64, rewardPercentiles []float64) (feeHistory *ethereum.FeeHistory, err error) { + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx, r.rpcTimeout) + defer cancel() + lggr := r.newRqLggr().With("blockCount", blockCount, "rewardPercentiles", rewardPercentiles) + + lggr.Debug("RPC call: evmclient.Client#FeeHistory") + start := time.Now() + if http != nil { + feeHistory, err = http.geth.FeeHistory(ctx, blockCount, nil, rewardPercentiles) + err = r.wrapHTTP(err) + } else { + feeHistory, err = ws.geth.FeeHistory(ctx, blockCount, nil, rewardPercentiles) + err = r.wrapWS(err) + } + duration := time.Since(start) + + r.logResult(lggr, err, duration, r.getRPCDomain(), "FeeHistory", + "feeHistory", feeHistory, + ) + + return +} + // CallArgs represents the data used to call the balance method of a contract. // "To" is the address of the ERC contract. "Data" is the message sent // to the contract. "From" is the sender address. diff --git a/core/chains/evm/client/simulated_backend_client.go b/core/chains/evm/client/simulated_backend_client.go index 9f8da08e80..6c569b16b8 100644 --- a/core/chains/evm/client/simulated_backend_client.go +++ b/core/chains/evm/client/simulated_backend_client.go @@ -156,6 +156,10 @@ func (c *SimulatedBackendClient) LINKBalance(ctx context.Context, address common panic("not implemented") } +func (c *SimulatedBackendClient) FeeHistory(ctx context.Context, blockCount uint64, rewardPercentiles []float64) (feeHistory *ethereum.FeeHistory, err error) { + panic("not implemented") +} + // TransactionReceipt returns the transaction receipt for the given transaction hash. func (c *SimulatedBackendClient) TransactionReceipt(ctx context.Context, receipt common.Hash) (*types.Receipt, error) { return c.b.TransactionReceipt(ctx, receipt) diff --git a/core/chains/evm/config/chain_scoped_gas_estimator.go b/core/chains/evm/config/chain_scoped_gas_estimator.go index 6f43839b01..54c7c36063 100644 --- a/core/chains/evm/config/chain_scoped_gas_estimator.go +++ b/core/chains/evm/config/chain_scoped_gas_estimator.go @@ -1,6 +1,8 @@ package config import ( + "time" + gethcommon "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" @@ -36,6 +38,10 @@ func (g *gasEstimatorConfig) BlockHistory() BlockHistory { return &blockHistoryConfig{c: g.c.BlockHistory, blockDelay: g.blockDelay, bumpThreshold: g.c.BumpThreshold} } +func (g *gasEstimatorConfig) FeeHistory() FeeHistory { + return &feeHistoryConfig{c: g.c.FeeHistory} +} + func (g *gasEstimatorConfig) EIP1559DynamicFees() bool { return *g.c.EIP1559DynamicFees } @@ -176,3 +182,11 @@ func (b *blockHistoryConfig) TransactionPercentile() uint16 { func (b *blockHistoryConfig) BlockDelay() uint16 { return *b.blockDelay } + +type feeHistoryConfig struct { + c toml.FeeHistoryEstimator +} + +func (u *feeHistoryConfig) CacheTimeout() time.Duration { + return u.c.CacheTimeout.Duration() +} diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index 1a33b08aa3..ea3efcdbde 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -118,6 +118,7 @@ type AutoPurgeConfig interface { type GasEstimator interface { BlockHistory() BlockHistory + FeeHistory() FeeHistory LimitJobType() LimitJobType EIP1559DynamicFees() bool @@ -159,6 +160,10 @@ type BlockHistory interface { TransactionPercentile() uint16 } +type FeeHistory interface { + CacheTimeout() time.Duration +} + type Workflow interface { FromAddress() *types.EIP55Address ForwarderAddress() *types.EIP55Address diff --git a/core/chains/evm/config/config_test.go b/core/chains/evm/config/config_test.go index 6543013927..3e843fea37 100644 --- a/core/chains/evm/config/config_test.go +++ b/core/chains/evm/config/config_test.go @@ -220,6 +220,13 @@ func TestChainScopedConfig_BlockHistory(t *testing.T) { assert.Equal(t, uint16(1), bh.BlockDelay()) assert.Equal(t, uint16(4), bh.EIP1559FeeCapBufferBlocks()) } +func TestChainScopedConfig_FeeHistory(t *testing.T) { + t.Parallel() + cfg := testutils.NewTestChainScopedConfig(t, nil) + + u := cfg.EVM().GasEstimator().FeeHistory() + assert.Equal(t, 10*time.Second, u.CacheTimeout()) +} func TestChainScopedConfig_GasEstimator(t *testing.T) { t.Parallel() diff --git a/core/chains/evm/config/mocks/gas_estimator.go b/core/chains/evm/config/mocks/gas_estimator.go index 96ffff08ae..70b9c18d0b 100644 --- a/core/chains/evm/config/mocks/gas_estimator.go +++ b/core/chains/evm/config/mocks/gas_estimator.go @@ -390,6 +390,53 @@ func (_c *GasEstimator_FeeCapDefault_Call) RunAndReturn(run func() *assets.Wei) return _c } +// FeeHistory provides a mock function with given fields: +func (_m *GasEstimator) FeeHistory() config.FeeHistory { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for FeeHistory") + } + + var r0 config.FeeHistory + if rf, ok := ret.Get(0).(func() config.FeeHistory); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(config.FeeHistory) + } + } + + return r0 +} + +// GasEstimator_FeeHistory_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FeeHistory' +type GasEstimator_FeeHistory_Call struct { + *mock.Call +} + +// FeeHistory is a helper method to define mock.On call +func (_e *GasEstimator_Expecter) FeeHistory() *GasEstimator_FeeHistory_Call { + return &GasEstimator_FeeHistory_Call{Call: _e.mock.On("FeeHistory")} +} + +func (_c *GasEstimator_FeeHistory_Call) Run(run func()) *GasEstimator_FeeHistory_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *GasEstimator_FeeHistory_Call) Return(_a0 config.FeeHistory) *GasEstimator_FeeHistory_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GasEstimator_FeeHistory_Call) RunAndReturn(run func() config.FeeHistory) *GasEstimator_FeeHistory_Call { + _c.Call.Return(run) + return _c +} + // LimitDefault provides a mock function with given fields: func (_m *GasEstimator) LimitDefault() uint64 { ret := _m.Called() diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 1db5a0dcad..999146b818 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -573,6 +573,7 @@ type GasEstimator struct { TipCapMin *assets.Wei BlockHistory BlockHistoryEstimator `toml:",omitempty"` + FeeHistory FeeHistoryEstimator `toml:",omitempty"` } func (e *GasEstimator) ValidateConfig() (err error) { @@ -667,6 +668,7 @@ func (e *GasEstimator) setFrom(f *GasEstimator) { } e.LimitJobType.setFrom(&f.LimitJobType) e.BlockHistory.setFrom(&f.BlockHistory) + e.FeeHistory.setFrom(&f.FeeHistory) } type GasLimitJobType struct { @@ -729,6 +731,16 @@ func (e *BlockHistoryEstimator) setFrom(f *BlockHistoryEstimator) { } } +type FeeHistoryEstimator struct { + CacheTimeout *commonconfig.Duration +} + +func (u *FeeHistoryEstimator) setFrom(f *FeeHistoryEstimator) { + if v := f.CacheTimeout; v != nil { + u.CacheTimeout = v + } +} + type KeySpecificConfig []KeySpecific func (ks KeySpecificConfig) ValidateConfig() (err error) { diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index e2587ed744..56f750ee7b 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -56,6 +56,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 diff --git a/core/chains/evm/gas/fee_history_estimator.go b/core/chains/evm/gas/fee_history_estimator.go new file mode 100644 index 0000000000..ba3192be10 --- /dev/null +++ b/core/chains/evm/gas/fee_history_estimator.go @@ -0,0 +1,440 @@ +package gas + +import ( + "context" + "fmt" + "math/big" + "strconv" + "sync" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" + bigmath "github.com/smartcontractkit/chainlink-common/pkg/utils/big_math" + + commonfee "github.com/smartcontractkit/chainlink/v2/common/fee" + feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" +) + +// metrics are thread safe +var ( + promFeeHistoryEstimatorGasPrice = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "gas_price_updater", + Help: "Sets latest gas price (in Wei)", + }, + []string{"evmChainID"}, + ) + promFeeHistoryEstimatorBaseFee = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "base_fee_updater", + Help: "Sets latest BaseFee (in Wei)", + }, + []string{"evmChainID"}, + ) + promFeeHistoryEstimatorMaxPriorityFeePerGas = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "max_priority_fee_per_gas_updater", + Help: "Sets latest MaxPriorityFeePerGas (in Wei)", + }, + []string{"evmChainID"}, + ) + promFeeHistoryEstimatorMaxFeePerGas = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "max_fee_per_gas_updater", + Help: "Sets latest MaxFeePerGas (in Wei)", + }, + []string{"evmChainID"}, + ) +) + +const ( + MinimumBumpPercentage = 10 // based on geth's spec + ConnectivityPercentile = 85 + BaseFeeBufferPercentage = 40 +) + +type FeeHistoryEstimatorConfig struct { + BumpPercent uint16 + CacheTimeout time.Duration + + EIP1559 bool + BlockHistorySize uint64 + RewardPercentile float64 +} + +type feeHistoryEstimatorClient interface { + SuggestGasPrice(ctx context.Context) (*big.Int, error) + FeeHistory(ctx context.Context, blockCount uint64, rewardPercentiles []float64) (feeHistory *ethereum.FeeHistory, err error) +} + +type FeeHistoryEstimator struct { + services.StateMachine + + client feeHistoryEstimatorClient + logger logger.Logger + config FeeHistoryEstimatorConfig + chainID *big.Int + + gasPriceMu sync.RWMutex + gasPrice *assets.Wei + + dynamicPriceMu sync.RWMutex + dynamicPrice DynamicFee + + priorityFeeThresholdMu sync.RWMutex + priorityFeeThreshold *assets.Wei + + l1Oracle rollups.L1Oracle + + wg *sync.WaitGroup + stopCh services.StopChan + refreshCh chan struct{} +} + +func NewFeeHistoryEstimator(lggr logger.Logger, client feeHistoryEstimatorClient, cfg FeeHistoryEstimatorConfig, chainID *big.Int, l1Oracle rollups.L1Oracle) *FeeHistoryEstimator { + return &FeeHistoryEstimator{ + client: client, + logger: logger.Named(lggr, "FeeHistoryEstimator"), + config: cfg, + chainID: chainID, + l1Oracle: l1Oracle, + wg: new(sync.WaitGroup), + stopCh: make(chan struct{}), + refreshCh: make(chan struct{}), + } +} + +func (f *FeeHistoryEstimator) Start(context.Context) error { + return f.StartOnce("FeeHistoryEstimator", func() error { + if f.config.BumpPercent < MinimumBumpPercentage { + return fmt.Errorf("BumpPercent: %s is less than minimum allowed percentage: %s", + strconv.FormatUint(uint64(f.config.BumpPercent), 10), strconv.Itoa(MinimumBumpPercentage)) + } + if f.config.EIP1559 && f.config.RewardPercentile > ConnectivityPercentile { + return fmt.Errorf("RewardPercentile: %s is greater than maximum allowed percentile: %s", + strconv.FormatUint(uint64(f.config.RewardPercentile), 10), strconv.Itoa(ConnectivityPercentile)) + } + f.wg.Add(1) + go f.run() + + return nil + }) +} + +func (f *FeeHistoryEstimator) Close() error { + return f.StopOnce("FeeHistoryEstimator", func() error { + close(f.stopCh) + f.wg.Wait() + return nil + }) +} + +func (f *FeeHistoryEstimator) run() { + defer f.wg.Done() + + t := services.TickerConfig{ + JitterPct: services.DefaultJitter, + }.NewTicker(f.config.CacheTimeout) + + for { + select { + case <-f.stopCh: + return + case <-f.refreshCh: + t.Reset() + case <-t.C: + if f.config.EIP1559 { + if err := f.RefreshDynamicPrice(); err != nil { + f.logger.Error(err) + } + } else { + if _, err := f.RefreshGasPrice(); err != nil { + f.logger.Error(err) + } + } + } + } +} + +// GetLegacyGas will fetch the cached gas price value. +func (f *FeeHistoryEstimator) GetLegacyGas(ctx context.Context, _ []byte, gasLimit uint64, maxPrice *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { + chainSpecificGasLimit = gasLimit + if gasPrice, err = f.getGasPrice(); err != nil { + return + } + + if gasPrice.Cmp(maxPrice) > 0 { + f.logger.Warnf("estimated gas price: %s is greater than the maximum gas price configured: %s, returning the maximum price instead.", gasPrice, maxPrice) + return maxPrice, chainSpecificGasLimit, nil + } + return +} + +// RefreshGasPrice will use eth_gasPrice to fetch and cache the latest gas price from the RPC. +func (f *FeeHistoryEstimator) RefreshGasPrice() (*assets.Wei, error) { + ctx, cancel := f.stopCh.CtxCancel(evmclient.ContextWithDefaultTimeout()) + defer cancel() + + gasPrice, err := f.client.SuggestGasPrice(ctx) + if err != nil { + return nil, err + } + + promFeeHistoryEstimatorGasPrice.WithLabelValues(f.chainID.String()).Set(float64(gasPrice.Int64())) + + gasPriceWei := assets.NewWei(gasPrice) + + f.logger.Debugf("fetched new gas price: %v", gasPriceWei) + + f.gasPriceMu.Lock() + defer f.gasPriceMu.Unlock() + f.gasPrice = gasPriceWei + return f.gasPrice, nil +} + +func (f *FeeHistoryEstimator) getGasPrice() (*assets.Wei, error) { + f.gasPriceMu.RLock() + defer f.gasPriceMu.RUnlock() + if f.gasPrice == nil { + return f.gasPrice, fmt.Errorf("gas price not set") + } + return f.gasPrice, nil +} + +// GetDynamicFee will fetch the cached dynamic prices. +func (f *FeeHistoryEstimator) GetDynamicFee(ctx context.Context, maxPrice *assets.Wei) (fee DynamicFee, err error) { + if fee, err = f.getDynamicPrice(); err != nil { + return + } + + if fee.FeeCap.Cmp(maxPrice) > 0 { + f.logger.Warnf("estimated maxFeePerGas: %v is greater than the maximum price configured: %v, returning the maximum price instead.", + fee.FeeCap, maxPrice) + fee.FeeCap = maxPrice + if fee.TipCap.Cmp(maxPrice) > 0 { + f.logger.Warnf("estimated maxPriorityFeePerGas: %v is greater than the maximum price configured: %v, returning the maximum price instead.", + fee.TipCap, maxPrice) + fee.TipCap = maxPrice + } + } + + return +} + +// RefreshDynamicPrice uses eth_feeHistory to fetch the baseFee of the next block and the Nth maxPriorityFeePerGas percentiles +// of the past X blocks. It also fetches the highest 85th maxPriorityFeePerGas percentile of the past X blocks, which represents +// the highest percentile we're willing to pay. A buffer is added on top of the latest baseFee to catch fluctuations in the next +// blocks. On Ethereum the increase is baseFee * 1.125 per block, however in some chains that may vary. +func (f *FeeHistoryEstimator) RefreshDynamicPrice() error { + ctx, cancel := f.stopCh.CtxCancel(evmclient.ContextWithDefaultTimeout()) + defer cancel() + + // RewardPercentile will be used for maxPriorityFeePerGas estimations and connectivityPercentile to set the highest threshold for bumping. + feeHistory, err := f.client.FeeHistory(ctx, max(f.config.BlockHistorySize, 1), []float64{f.config.RewardPercentile, ConnectivityPercentile}) + if err != nil { + return err + } + + // eth_feeHistory doesn't return the latest baseFee of the range but rather the latest + 1, because it can be derived from the existing + // values. Source: https://github.com/ethereum/go-ethereum/blob/b0f66e34ca2a4ea7ae23475224451c8c9a569826/eth/gasprice/feehistory.go#L235 + // nextBlock is the latest returned + 1 to be aligned with the base fee value. + nextBaseFee := assets.NewWei(feeHistory.BaseFee[len(feeHistory.BaseFee)-1]) + nextBlock := big.NewInt(0).Add(feeHistory.OldestBlock, big.NewInt(int64(f.config.BlockHistorySize))) + + // If BlockHistorySize is 0 it means priority fees will be ignored from the calculations, so we set them to 0. + // If it's not we exclude 0 priced priority fees from the RPC response, even though some networks allow them. For empty blocks, eth_feeHistory + // returns priority fees with 0 values so it's safer to discard them in order to pick values from a more representative sample. + maxPriorityFeePerGas := assets.NewWeiI(0) + priorityFeeThresholdWei := assets.NewWeiI(0) + if f.config.BlockHistorySize > 0 { + var nonZeroRewardsLen int64 = 0 + priorityFee := big.NewInt(0) + priorityFeeThreshold := big.NewInt(0) + for _, reward := range feeHistory.Reward { + // reward needs to have values for two percentiles + if len(reward) < 2 { + return fmt.Errorf("reward size incorrect: %d", len(reward)) + } + // We'll calculate the average of non-zero priority fees + if reward[0].Cmp(big.NewInt(0)) > 0 { + priorityFee = priorityFee.Add(priorityFee, reward[0]) + nonZeroRewardsLen += 1 + } + // We take the max value for the bumping threshold + if reward[1].Cmp(big.NewInt(0)) > 0 { + priorityFeeThreshold = bigmath.Max(priorityFeeThreshold, reward[1]) + } + } + + if nonZeroRewardsLen == 0 || priorityFeeThreshold.Cmp(big.NewInt(0)) == 0 { + return nil + } + priorityFeeThresholdWei = assets.NewWei(priorityFeeThreshold) + maxPriorityFeePerGas = assets.NewWei(priorityFee.Div(priorityFee, big.NewInt(nonZeroRewardsLen))) + } + // baseFeeBufferPercentage is added on top as a safety to catch fluctuations in the next blocks. + maxFeePerGas := nextBaseFee.AddPercentage(BaseFeeBufferPercentage).Add(maxPriorityFeePerGas) + + promFeeHistoryEstimatorBaseFee.WithLabelValues(f.chainID.String()).Set(float64(nextBaseFee.Int64())) + promFeeHistoryEstimatorMaxPriorityFeePerGas.WithLabelValues(f.chainID.String()).Set(float64(maxPriorityFeePerGas.Int64())) + promFeeHistoryEstimatorMaxFeePerGas.WithLabelValues(f.chainID.String()).Set(float64(maxFeePerGas.Int64())) + + f.logger.Debugf("Fetched new dynamic prices, nextBlock#: %v - oldestBlock#: %v - nextBaseFee: %v - maxFeePerGas: %v - maxPriorityFeePerGas: %v - maxPriorityFeeThreshold: %v", + nextBlock, feeHistory.OldestBlock, nextBaseFee, maxFeePerGas, maxPriorityFeePerGas, priorityFeeThresholdWei) + + f.priorityFeeThresholdMu.Lock() + f.priorityFeeThreshold = priorityFeeThresholdWei + f.priorityFeeThresholdMu.Unlock() + + f.dynamicPriceMu.Lock() + defer f.dynamicPriceMu.Unlock() + f.dynamicPrice.FeeCap = maxFeePerGas + f.dynamicPrice.TipCap = maxPriorityFeePerGas + return nil +} + +func (f *FeeHistoryEstimator) getDynamicPrice() (fee DynamicFee, err error) { + f.dynamicPriceMu.RLock() + defer f.dynamicPriceMu.RUnlock() + if f.dynamicPrice.FeeCap == nil || f.dynamicPrice.TipCap == nil { + return fee, fmt.Errorf("dynamic price not set") + } + return f.dynamicPrice, nil +} + +// BumpLegacyGas provides a bumped gas price value by bumping the previous one by BumpPercent. +// If the original value is higher than the max price it returns an error as there is no room for bumping. +// It aggregates the market, bumped, and max gas price to provide a correct value. +func (f *FeeHistoryEstimator) BumpLegacyGas(ctx context.Context, originalGasPrice *assets.Wei, gasLimit uint64, maxPrice *assets.Wei, _ []EvmPriorAttempt) (*assets.Wei, uint64, error) { + // Sanitize original fee input + if originalGasPrice == nil || originalGasPrice.Cmp(maxPrice) >= 0 { + return nil, 0, fmt.Errorf("%w: error while retrieving original gas price: originalGasPrice: %s. Maximum price configured: %s", + commonfee.ErrBump, originalGasPrice, maxPrice) + } + + currentGasPrice, err := f.RefreshGasPrice() + if err != nil { + return nil, 0, err + } + f.IfStarted(func() { f.refreshCh <- struct{}{} }) + + bumpedGasPrice := originalGasPrice.AddPercentage(f.config.BumpPercent) + bumpedGasPrice, err = LimitBumpedFee(originalGasPrice, currentGasPrice, bumpedGasPrice, maxPrice) + if err != nil { + return nil, 0, fmt.Errorf("failed to limit gas price: %w", err) + } + + f.logger.Debugw("bumped gas price", "originalGasPrice", originalGasPrice, "marketGasPrice", currentGasPrice, "bumpedGasPrice", bumpedGasPrice) + + return bumpedGasPrice, gasLimit, nil +} + +// BumpDynamicFee provides a bumped dynamic fee by bumping the previous one by BumpPercent. +// If the original values are higher than the max price it returns an error as there is no room for bumping. If maxPriorityFeePerGas is bumped +// above the priority fee threshold then there is a good chance there is a connectivity issue and we shouldn't bump. +// Both maxFeePerGas as well as maxPriorityFeePerGas need to be bumped otherwise the RPC won't accept the transaction and throw an error. +// See: https://github.com/ethereum/go-ethereum/issues/24284 +// It aggregates the market, bumped, and max price to provide a correct value, for both maxFeePerGas as well as maxPriorityFerPergas. +func (f *FeeHistoryEstimator) BumpDynamicFee(ctx context.Context, originalFee DynamicFee, maxPrice *assets.Wei, _ []EvmPriorAttempt) (bumped DynamicFee, err error) { + // For chains that don't have a mempool there is no concept of gas bumping so we force-call RefreshDynamicPrice to update the underlying base fee value + if f.config.BlockHistorySize == 0 { + if !f.IfStarted(func() { + if refreshErr := f.RefreshDynamicPrice(); refreshErr != nil { + err = refreshErr + return + } + f.refreshCh <- struct{}{} + bumped, err = f.GetDynamicFee(ctx, maxPrice) + }) { + return bumped, fmt.Errorf("estimator not started") + } + return bumped, err + } + + // Sanitize original fee input + // According to geth's spec we need to bump both maxFeePerGas and maxPriorityFeePerGas for the new attempt to be accepted by the RPC + if originalFee.FeeCap == nil || + originalFee.TipCap == nil || + ((originalFee.TipCap.Cmp(originalFee.FeeCap)) > 0) || + (originalFee.FeeCap.Cmp(maxPrice) >= 0) { + return bumped, fmt.Errorf("%w: error while retrieving original dynamic fees: (originalFeePerGas: %s - originalPriorityFeePerGas: %s). Maximum price configured: %s", + commonfee.ErrBump, originalFee.FeeCap, originalFee.TipCap, maxPrice) + } + + currentDynamicPrice, err := f.getDynamicPrice() + if err != nil { + return + } + + bumpedMaxPriorityFeePerGas := originalFee.TipCap.AddPercentage(f.config.BumpPercent) + bumpedMaxFeePerGas := originalFee.FeeCap.AddPercentage(f.config.BumpPercent) + + bumpedMaxPriorityFeePerGas, err = LimitBumpedFee(originalFee.TipCap, currentDynamicPrice.TipCap, bumpedMaxPriorityFeePerGas, maxPrice) + if err != nil { + return bumped, fmt.Errorf("failed to limit maxPriorityFeePerGas: %w", err) + } + + priorityFeeThreshold, e := f.getPriorityFeeThreshold() + if e != nil { + return bumped, e + } + + if bumpedMaxPriorityFeePerGas.Cmp(priorityFeeThreshold) > 0 { + return bumped, fmt.Errorf("bumpedMaxPriorityFeePerGas: %s is above market's %sth percentile: %s, bumping is halted", + bumpedMaxPriorityFeePerGas, strconv.Itoa(ConnectivityPercentile), priorityFeeThreshold) + } + + bumpedMaxFeePerGas, err = LimitBumpedFee(originalFee.FeeCap, currentDynamicPrice.FeeCap, bumpedMaxFeePerGas, maxPrice) + if err != nil { + return bumped, fmt.Errorf("failed to limit maxFeePerGas: %w", err) + } + + bumpedFee := DynamicFee{FeeCap: bumpedMaxFeePerGas, TipCap: bumpedMaxPriorityFeePerGas} + f.logger.Debugw("bumped dynamic fee", "originalFee", originalFee, "marketFee", currentDynamicPrice, "bumpedFee", bumpedFee) + + return bumpedFee, nil +} + +// LimitBumpedFee selects the maximum value between the bumped attempt and the current fee, if there is one. If the result is higher than the max price it gets capped. +// Geth's implementation has a hard 10% minimum limit for the bumped values, otherwise it rejects the transaction with an error. +// See: https://github.com/ethereum/go-ethereum/blob/bff330335b94af3643ac2fb809793f77de3069d4/core/tx_list.go#L298 +// +// Note: for chains that support EIP-1559 but we still choose to send Legacy transactions to them, the limit is still enforcable due to the fact that Legacy transactions +// are treated the same way as Dynamic transactions under the hood. For chains that don't support EIP-1559 at all, the limit isn't enforcable but a 10% minimum bump percentage +// makes sense anyway. +func LimitBumpedFee(originalFee *assets.Wei, currentFee *assets.Wei, bumpedFee *assets.Wei, maxPrice *assets.Wei) (*assets.Wei, error) { + if currentFee != nil { + bumpedFee = assets.WeiMax(currentFee, bumpedFee) + } + bumpedFee = assets.WeiMin(bumpedFee, maxPrice) + + // The first check is added for the following edge case: + // If originalFee is below 10 wei, then adding the minimum bump percentage won't have any effect on the final value because of rounding down. + // Similarly for bumpedFee, it can have the exact same value as the originalFee, even if we bumped, given an originalFee of less than 10 wei + // and a small enough BumpPercent. + if bumpedFee.Cmp(originalFee) == 0 || + bumpedFee.Cmp(originalFee.AddPercentage(MinimumBumpPercentage)) < 0 { + return nil, fmt.Errorf("%w: %s is bumped less than minimum allowed percentage(%s) from originalFee: %s - maxPrice: %s", + commonfee.ErrBump, bumpedFee, strconv.Itoa(MinimumBumpPercentage), originalFee, maxPrice) + } + return bumpedFee, nil +} + +func (f *FeeHistoryEstimator) getPriorityFeeThreshold() (*assets.Wei, error) { + f.priorityFeeThresholdMu.RLock() + defer f.priorityFeeThresholdMu.RUnlock() + if f.priorityFeeThreshold == nil { + return f.priorityFeeThreshold, fmt.Errorf("priorityFeeThreshold not set") + } + return f.priorityFeeThreshold, nil +} + +func (f *FeeHistoryEstimator) Name() string { return f.logger.Name() } +func (f *FeeHistoryEstimator) L1Oracle() rollups.L1Oracle { return f.l1Oracle } +func (f *FeeHistoryEstimator) HealthReport() map[string]error { return map[string]error{f.Name(): nil} } +func (f *FeeHistoryEstimator) OnNewLongestChain(context.Context, *evmtypes.Head) {} diff --git a/core/chains/evm/gas/fee_history_estimator_test.go b/core/chains/evm/gas/fee_history_estimator_test.go new file mode 100644 index 0000000000..6e42e0e209 --- /dev/null +++ b/core/chains/evm/gas/fee_history_estimator_test.go @@ -0,0 +1,513 @@ +package gas_test + +import ( + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" +) + +func TestFeeHistoryEstimatorLifecycle(t *testing.T) { + t.Parallel() + var gasLimit uint64 = 21000 + maxPrice := assets.NewWeiI(100) + chainID := big.NewInt(0) + + t.Run("fails if you fetch gas price before the estimator starts", func(t *testing.T) { + cfg := gas.FeeHistoryEstimatorConfig{ + BumpPercent: 20, + RewardPercentile: 60, + EIP1559: false, + } + + u := gas.NewFeeHistoryEstimator(logger.Test(t), nil, cfg, chainID, nil) + _, _, err := u.GetLegacyGas(tests.Context(t), nil, gasLimit, maxPrice) + assert.ErrorContains(t, err, "gas price not set") + }) + + t.Run("fails to start if BumpPercent is lower than the minimum cap", func(t *testing.T) { + cfg := gas.FeeHistoryEstimatorConfig{BumpPercent: 9} + + u := gas.NewFeeHistoryEstimator(logger.Test(t), nil, cfg, chainID, nil) + assert.ErrorContains(t, u.Start(tests.Context(t)), "BumpPercent") + }) + + t.Run("fails to start if RewardPercentile is higher than ConnectivityPercentile in EIP-1559", func(t *testing.T) { + cfg := gas.FeeHistoryEstimatorConfig{ + BumpPercent: 20, + RewardPercentile: 99, + EIP1559: true, + } + + u := gas.NewFeeHistoryEstimator(logger.Test(t), nil, cfg, chainID, nil) + assert.ErrorContains(t, u.Start(tests.Context(t)), "RewardPercentile") + }) + + t.Run("starts if configs are correct", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + client.On("SuggestGasPrice", mock.Anything).Return(big.NewInt(10), nil).Maybe() + + cfg := gas.FeeHistoryEstimatorConfig{ + BumpPercent: 20, + RewardPercentile: 10, + CacheTimeout: 10 * time.Second, + } + + u := gas.NewFeeHistoryEstimator(logger.Test(t), nil, cfg, chainID, nil) + err := u.Start(tests.Context(t)) + assert.NoError(t, err) + err = u.Close() + assert.NoError(t, err) + }) +} + +func TestFeeHistoryEstimatorGetLegacyGas(t *testing.T) { + t.Parallel() + + var gasLimit uint64 = 21000 + maxPrice := assets.NewWeiI(100) + chainID := big.NewInt(0) + + t.Run("fetches a new gas price when first called", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + client.On("SuggestGasPrice", mock.Anything).Return(big.NewInt(10), nil).Once() + + cfg := gas.FeeHistoryEstimatorConfig{} + + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + _, err := u.RefreshGasPrice() + assert.NoError(t, err) + gasPrice, _, err := u.GetLegacyGas(tests.Context(t), nil, gasLimit, maxPrice) + assert.NoError(t, err) + assert.Equal(t, assets.NewWeiI(10), gasPrice) + }) + + t.Run("will return max price if estimation exceeds it", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + client.On("SuggestGasPrice", mock.Anything).Return(big.NewInt(10), nil).Once() + + cfg := gas.FeeHistoryEstimatorConfig{} + + maxPrice := assets.NewWeiI(1) + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + _, err := u.RefreshGasPrice() + assert.NoError(t, err) + gas1, _, err := u.GetLegacyGas(tests.Context(t), nil, gasLimit, maxPrice) + assert.NoError(t, err) + assert.Equal(t, maxPrice, gas1) + }) + + t.Run("fails if gas price has not been set yet", func(t *testing.T) { + cfg := gas.FeeHistoryEstimatorConfig{} + + maxPrice := assets.NewWeiI(1) + u := gas.NewFeeHistoryEstimator(logger.Test(t), nil, cfg, chainID, nil) + _, _, err := u.GetLegacyGas(tests.Context(t), nil, gasLimit, maxPrice) + assert.Error(t, err) + assert.ErrorContains(t, err, "gas price not set") + }) +} + +func TestFeeHistoryEstimatorBumpLegacyGas(t *testing.T) { + t.Parallel() + + var gasLimit uint64 = 21000 + maxPrice := assets.NewWeiI(100) + chainID := big.NewInt(0) + + t.Run("bumps a previous attempt by BumpPercent", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + originalGasPrice := assets.NewWeiI(10) + client.On("SuggestGasPrice", mock.Anything).Return(big.NewInt(10), nil) + + cfg := gas.FeeHistoryEstimatorConfig{BumpPercent: 50, CacheTimeout: 5 * time.Second} + + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + servicetest.RunHealthy(t, u) + gasPrice, _, err := u.BumpLegacyGas(tests.Context(t), originalGasPrice, gasLimit, maxPrice, nil) + assert.NoError(t, err) + assert.Equal(t, assets.NewWeiI(15), gasPrice) + }) + + t.Run("fails if the original attempt is nil, or equal or higher than the max price", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + + cfg := gas.FeeHistoryEstimatorConfig{} + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + + var originalPrice *assets.Wei + _, _, err := u.BumpLegacyGas(tests.Context(t), originalPrice, gasLimit, maxPrice, nil) + assert.Error(t, err) + + originalPrice = assets.NewWeiI(100) + _, _, err = u.BumpLegacyGas(tests.Context(t), originalPrice, gasLimit, maxPrice, nil) + assert.Error(t, err) + }) + + t.Run("returns market gas price if bumped original fee is lower", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + client.On("SuggestGasPrice", mock.Anything).Return(big.NewInt(80), nil).Once() + originalGasPrice := assets.NewWeiI(10) + + cfg := gas.FeeHistoryEstimatorConfig{} + + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + gas, _, err := u.BumpLegacyGas(tests.Context(t), originalGasPrice, gasLimit, maxPrice, nil) + assert.NoError(t, err) + assert.Equal(t, assets.NewWeiI(80), gas) + }) + + t.Run("returns max gas price if bumped original fee is higher", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + client.On("SuggestGasPrice", mock.Anything).Return(big.NewInt(1), nil).Once() + originalGasPrice := assets.NewWeiI(10) + + cfg := gas.FeeHistoryEstimatorConfig{BumpPercent: 50} + + maxPrice := assets.NewWeiI(14) + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + gas, _, err := u.BumpLegacyGas(tests.Context(t), originalGasPrice, gasLimit, maxPrice, nil) + assert.NoError(t, err) + assert.Equal(t, maxPrice, gas) + }) + + t.Run("returns max gas price if the aggregation of max and original bumped fee is higher", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + client.On("SuggestGasPrice", mock.Anything).Return(big.NewInt(1), nil).Once() + originalGasPrice := assets.NewWeiI(10) + + cfg := gas.FeeHistoryEstimatorConfig{BumpPercent: 50} + + maxPrice := assets.NewWeiI(14) + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + gas, _, err := u.BumpLegacyGas(tests.Context(t), originalGasPrice, gasLimit, maxPrice, nil) + assert.NoError(t, err) + assert.Equal(t, maxPrice, gas) + }) + + t.Run("fails if the bumped gas price is lower than the minimum bump percentage", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + client.On("SuggestGasPrice", mock.Anything).Return(big.NewInt(100), nil).Once() + originalGasPrice := assets.NewWeiI(100) + + cfg := gas.FeeHistoryEstimatorConfig{BumpPercent: 20} + + // Price will be capped by the max price + maxPrice := assets.NewWeiI(101) + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + _, _, err := u.BumpLegacyGas(tests.Context(t), originalGasPrice, gasLimit, maxPrice, nil) + assert.Error(t, err) + }) +} + +func TestFeeHistoryEstimatorGetDynamicFee(t *testing.T) { + t.Parallel() + + maxPrice := assets.NewWeiI(100) + chainID := big.NewInt(0) + + t.Run("fetches a new dynamic fee when first called", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + baseFee := big.NewInt(5) + maxPriorityFeePerGas1 := big.NewInt(33) + maxPriorityFeePerGas2 := big.NewInt(20) + + feeHistoryResult := ðereum.FeeHistory{ + OldestBlock: big.NewInt(1), + Reward: [][]*big.Int{{maxPriorityFeePerGas1, big.NewInt(5)}, {maxPriorityFeePerGas2, big.NewInt(5)}}, // first one represents market price and second one connectivity price + BaseFee: []*big.Int{baseFee, baseFee}, + GasUsedRatio: nil, + } + client.On("FeeHistory", mock.Anything, mock.Anything, mock.Anything).Return(feeHistoryResult, nil).Once() + + blockHistoryLength := 2 + cfg := gas.FeeHistoryEstimatorConfig{BlockHistorySize: uint64(blockHistoryLength)} + avrgPriorityFee := big.NewInt(0) + avrgPriorityFee.Add(maxPriorityFeePerGas1, maxPriorityFeePerGas2).Div(avrgPriorityFee, big.NewInt(int64(blockHistoryLength))) + maxFee := (*assets.Wei)(baseFee).AddPercentage(gas.BaseFeeBufferPercentage).Add((*assets.Wei)(avrgPriorityFee)) + + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + err := u.RefreshDynamicPrice() + assert.NoError(t, err) + dynamicFee, err := u.GetDynamicFee(tests.Context(t), maxPrice) + assert.NoError(t, err) + assert.Equal(t, maxFee, dynamicFee.FeeCap) + assert.Equal(t, (*assets.Wei)(avrgPriorityFee), dynamicFee.TipCap) + }) + + t.Run("fails if dynamic prices have not been set yet", func(t *testing.T) { + cfg := gas.FeeHistoryEstimatorConfig{} + + maxPrice := assets.NewWeiI(1) + u := gas.NewFeeHistoryEstimator(logger.Test(t), nil, cfg, chainID, nil) + _, err := u.GetDynamicFee(tests.Context(t), maxPrice) + assert.Error(t, err) + assert.ErrorContains(t, err, "dynamic price not set") + }) + + t.Run("will return max price if tip cap or fee cap exceed it", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + baseFee := big.NewInt(1) + maxPriorityFeePerGas := big.NewInt(3) + maxPrice := assets.NewWeiI(2) + + feeHistoryResult := ðereum.FeeHistory{ + OldestBlock: big.NewInt(1), + Reward: [][]*big.Int{{maxPriorityFeePerGas, big.NewInt(5)}}, // first one represents market price and second one connectivity price + BaseFee: []*big.Int{baseFee}, + GasUsedRatio: nil, + } + client.On("FeeHistory", mock.Anything, mock.Anything, mock.Anything).Return(feeHistoryResult, nil).Once() + + cfg := gas.FeeHistoryEstimatorConfig{BlockHistorySize: 1} + + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + err := u.RefreshDynamicPrice() + assert.NoError(t, err) + dynamicFee, err := u.GetDynamicFee(tests.Context(t), maxPrice) + assert.NoError(t, err) + assert.Equal(t, maxPrice, dynamicFee.FeeCap) + assert.Equal(t, maxPrice, dynamicFee.TipCap) + }) +} + +func TestFeeHistoryEstimatorBumpDynamicFee(t *testing.T) { + t.Parallel() + + globalMaxPrice := assets.NewWeiI(100) + chainID := big.NewInt(0) + + t.Run("bumps a previous attempt by BumpPercent", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + originalFee := gas.DynamicFee{ + FeeCap: assets.NewWeiI(20), + TipCap: assets.NewWeiI(10), + } + + // These values will be ignored because they are lower prices than the originalFee + feeHistoryResult := ðereum.FeeHistory{ + OldestBlock: big.NewInt(1), + Reward: [][]*big.Int{{big.NewInt(5), big.NewInt(50)}}, // first one represents market price and second one connectivity price + BaseFee: []*big.Int{big.NewInt(5)}, + GasUsedRatio: nil, + } + client.On("FeeHistory", mock.Anything, mock.Anything, mock.Anything).Return(feeHistoryResult, nil).Once() + + cfg := gas.FeeHistoryEstimatorConfig{ + BlockHistorySize: 2, + BumpPercent: 50, + } + + expectedFeeCap := originalFee.FeeCap.AddPercentage(cfg.BumpPercent) + expectedTipCap := originalFee.TipCap.AddPercentage(cfg.BumpPercent) + + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + err := u.RefreshDynamicPrice() + assert.NoError(t, err) + dynamicFee, err := u.BumpDynamicFee(tests.Context(t), originalFee, globalMaxPrice, nil) + assert.NoError(t, err) + assert.Equal(t, expectedFeeCap, dynamicFee.FeeCap) + assert.Equal(t, expectedTipCap, dynamicFee.TipCap) + }) + + t.Run("fails if the original attempt is invalid", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + maxPrice := assets.NewWeiI(20) + cfg := gas.FeeHistoryEstimatorConfig{BlockHistorySize: 1} + + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + // nil original fee + var originalFee gas.DynamicFee + _, err := u.BumpDynamicFee(tests.Context(t), originalFee, maxPrice, nil) + assert.Error(t, err) + + // tip cap is higher than fee cap + originalFee = gas.DynamicFee{ + FeeCap: assets.NewWeiI(10), + TipCap: assets.NewWeiI(11), + } + _, err = u.BumpDynamicFee(tests.Context(t), originalFee, maxPrice, nil) + assert.Error(t, err) + + // fee cap is equal or higher to max price + originalFee = gas.DynamicFee{ + FeeCap: assets.NewWeiI(20), + TipCap: assets.NewWeiI(10), + } + _, err = u.BumpDynamicFee(tests.Context(t), originalFee, maxPrice, nil) + assert.Error(t, err) + }) + + t.Run("returns market prices if bumped original fee is lower", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + originalFee := gas.DynamicFee{ + FeeCap: assets.NewWeiI(20), + TipCap: assets.NewWeiI(10), + } + + // Market fees + baseFee := big.NewInt(5) + maxPriorityFeePerGas := big.NewInt(33) + feeHistoryResult := ðereum.FeeHistory{ + OldestBlock: big.NewInt(1), + Reward: [][]*big.Int{{maxPriorityFeePerGas, big.NewInt(100)}}, // first one represents market price and second one connectivity price + BaseFee: []*big.Int{baseFee}, + GasUsedRatio: nil, + } + client.On("FeeHistory", mock.Anything, mock.Anything, mock.Anything).Return(feeHistoryResult, nil).Once() + + maxFee := (*assets.Wei)(baseFee).AddPercentage(gas.BaseFeeBufferPercentage).Add((*assets.Wei)(maxPriorityFeePerGas)) + + cfg := gas.FeeHistoryEstimatorConfig{ + BlockHistorySize: 1, + BumpPercent: 50, + } + + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + err := u.RefreshDynamicPrice() + assert.NoError(t, err) + bumpedFee, err := u.BumpDynamicFee(tests.Context(t), originalFee, globalMaxPrice, nil) + assert.NoError(t, err) + assert.Equal(t, (*assets.Wei)(maxPriorityFeePerGas), bumpedFee.TipCap) + assert.Equal(t, maxFee, bumpedFee.FeeCap) + }) + + t.Run("fails if connectivity percentile value is reached", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + originalFee := gas.DynamicFee{ + FeeCap: assets.NewWeiI(20), + TipCap: assets.NewWeiI(10), + } + + // Market fees + baseFee := big.NewInt(5) + maxPriorityFeePerGas := big.NewInt(33) + feeHistoryResult := ðereum.FeeHistory{ + OldestBlock: big.NewInt(1), + Reward: [][]*big.Int{{maxPriorityFeePerGas, big.NewInt(30)}}, // first one represents market price and second one connectivity price + BaseFee: []*big.Int{baseFee}, + GasUsedRatio: nil, + } + client.On("FeeHistory", mock.Anything, mock.Anything, mock.Anything).Return(feeHistoryResult, nil).Once() + + cfg := gas.FeeHistoryEstimatorConfig{ + BlockHistorySize: 1, + BumpPercent: 50, + } + + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + err := u.RefreshDynamicPrice() + assert.NoError(t, err) + _, err = u.BumpDynamicFee(tests.Context(t), originalFee, globalMaxPrice, nil) + assert.Error(t, err) + }) + + t.Run("returns max price if the aggregation of max and original bumped fee is higher", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + originalFee := gas.DynamicFee{ + FeeCap: assets.NewWeiI(20), + TipCap: assets.NewWeiI(18), + } + + maxPrice := assets.NewWeiI(25) + // Market fees + baseFee := big.NewInt(1) + maxPriorityFeePerGas := big.NewInt(1) + feeHistoryResult := ðereum.FeeHistory{ + OldestBlock: big.NewInt(1), + Reward: [][]*big.Int{{maxPriorityFeePerGas, big.NewInt(30)}}, // first one represents market price and second one connectivity price + BaseFee: []*big.Int{baseFee}, + GasUsedRatio: nil, + } + client.On("FeeHistory", mock.Anything, mock.Anything, mock.Anything).Return(feeHistoryResult, nil).Once() + + cfg := gas.FeeHistoryEstimatorConfig{ + BlockHistorySize: 1, + BumpPercent: 50, + } + + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + err := u.RefreshDynamicPrice() + assert.NoError(t, err) + bumpedFee, err := u.BumpDynamicFee(tests.Context(t), originalFee, maxPrice, nil) + assert.NoError(t, err) + assert.Equal(t, maxPrice, bumpedFee.TipCap) + assert.Equal(t, maxPrice, bumpedFee.FeeCap) + }) + + t.Run("fails if the bumped gas price is lower than the minimum bump percentage", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + originalFee := gas.DynamicFee{ + FeeCap: assets.NewWeiI(20), + TipCap: assets.NewWeiI(18), + } + + maxPrice := assets.NewWeiI(21) + // Market fees + baseFee := big.NewInt(1) + maxPriorityFeePerGas := big.NewInt(1) + feeHistoryResult := ðereum.FeeHistory{ + OldestBlock: big.NewInt(1), + Reward: [][]*big.Int{{maxPriorityFeePerGas, big.NewInt(30)}}, // first one represents market price and second one connectivity price + BaseFee: []*big.Int{baseFee}, + GasUsedRatio: nil, + } + client.On("FeeHistory", mock.Anything, mock.Anything, mock.Anything).Return(feeHistoryResult, nil).Once() + + cfg := gas.FeeHistoryEstimatorConfig{ + BlockHistorySize: 1, + BumpPercent: 50, + } + + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + err := u.RefreshDynamicPrice() + assert.NoError(t, err) + _, err = u.BumpDynamicFee(tests.Context(t), originalFee, maxPrice, nil) + assert.Error(t, err) + }) + + t.Run("ignores maxPriorityFeePerGas if there is no mempool and forces refetch", func(t *testing.T) { + client := mocks.NewFeeHistoryEstimatorClient(t) + originalFee := gas.DynamicFee{ + FeeCap: assets.NewWeiI(40), + TipCap: assets.NewWeiI(0), + } + + // Market fees + baseFee := big.NewInt(10) + maxPriorityFeePerGas := big.NewInt(0) + feeHistoryResult := ðereum.FeeHistory{ + OldestBlock: big.NewInt(1), + Reward: [][]*big.Int{{maxPriorityFeePerGas, big.NewInt(0)}}, // first one represents market price and second one connectivity price + BaseFee: []*big.Int{baseFee}, + GasUsedRatio: nil, + } + client.On("FeeHistory", mock.Anything, mock.Anything, mock.Anything).Return(feeHistoryResult, nil) + + cfg := gas.FeeHistoryEstimatorConfig{ + BlockHistorySize: 0, + BumpPercent: 20, + CacheTimeout: 10 * time.Second, + EIP1559: true, + } + + maxFeePerGas := assets.NewWei(baseFee).AddPercentage(gas.BaseFeeBufferPercentage) + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) + servicetest.RunHealthy(t, u) + bumpedFee, err := u.BumpDynamicFee(tests.Context(t), originalFee, globalMaxPrice, nil) + assert.NoError(t, err) + assert.Equal(t, assets.NewWeiI(0), (*assets.Wei)(maxPriorityFeePerGas)) + assert.Equal(t, maxFeePerGas, bumpedFee.FeeCap) + }) +} diff --git a/core/chains/evm/gas/mocks/fee_estimator_client.go b/core/chains/evm/gas/mocks/fee_estimator_client.go index ab99eb7b0d..f5ca52ec92 100644 --- a/core/chains/evm/gas/mocks/fee_estimator_client.go +++ b/core/chains/evm/gas/mocks/fee_estimator_client.go @@ -298,6 +298,66 @@ func (_c *FeeEstimatorClient_EstimateGas_Call) RunAndReturn(run func(context.Con return _c } +// FeeHistory provides a mock function with given fields: ctx, blockCount, rewardPercentiles +func (_m *FeeEstimatorClient) FeeHistory(ctx context.Context, blockCount uint64, rewardPercentiles []float64) (*ethereum.FeeHistory, error) { + ret := _m.Called(ctx, blockCount, rewardPercentiles) + + if len(ret) == 0 { + panic("no return value specified for FeeHistory") + } + + var r0 *ethereum.FeeHistory + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, []float64) (*ethereum.FeeHistory, error)); ok { + return rf(ctx, blockCount, rewardPercentiles) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, []float64) *ethereum.FeeHistory); ok { + r0 = rf(ctx, blockCount, rewardPercentiles) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*ethereum.FeeHistory) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, []float64) error); ok { + r1 = rf(ctx, blockCount, rewardPercentiles) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeEstimatorClient_FeeHistory_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FeeHistory' +type FeeEstimatorClient_FeeHistory_Call struct { + *mock.Call +} + +// FeeHistory is a helper method to define mock.On call +// - ctx context.Context +// - blockCount uint64 +// - rewardPercentiles []float64 +func (_e *FeeEstimatorClient_Expecter) FeeHistory(ctx interface{}, blockCount interface{}, rewardPercentiles interface{}) *FeeEstimatorClient_FeeHistory_Call { + return &FeeEstimatorClient_FeeHistory_Call{Call: _e.mock.On("FeeHistory", ctx, blockCount, rewardPercentiles)} +} + +func (_c *FeeEstimatorClient_FeeHistory_Call) Run(run func(ctx context.Context, blockCount uint64, rewardPercentiles []float64)) *FeeEstimatorClient_FeeHistory_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].([]float64)) + }) + return _c +} + +func (_c *FeeEstimatorClient_FeeHistory_Call) Return(feeHistory *ethereum.FeeHistory, err error) *FeeEstimatorClient_FeeHistory_Call { + _c.Call.Return(feeHistory, err) + return _c +} + +func (_c *FeeEstimatorClient_FeeHistory_Call) RunAndReturn(run func(context.Context, uint64, []float64) (*ethereum.FeeHistory, error)) *FeeEstimatorClient_FeeHistory_Call { + _c.Call.Return(run) + return _c +} + // HeadByNumber provides a mock function with given fields: ctx, n func (_m *FeeEstimatorClient) HeadByNumber(ctx context.Context, n *big.Int) (*types.Head, error) { ret := _m.Called(ctx, n) @@ -357,6 +417,64 @@ func (_c *FeeEstimatorClient_HeadByNumber_Call) RunAndReturn(run func(context.Co return _c } +// SuggestGasPrice provides a mock function with given fields: ctx +func (_m *FeeEstimatorClient) SuggestGasPrice(ctx context.Context) (*big.Int, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for SuggestGasPrice") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*big.Int, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *big.Int); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeEstimatorClient_SuggestGasPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SuggestGasPrice' +type FeeEstimatorClient_SuggestGasPrice_Call struct { + *mock.Call +} + +// SuggestGasPrice is a helper method to define mock.On call +// - ctx context.Context +func (_e *FeeEstimatorClient_Expecter) SuggestGasPrice(ctx interface{}) *FeeEstimatorClient_SuggestGasPrice_Call { + return &FeeEstimatorClient_SuggestGasPrice_Call{Call: _e.mock.On("SuggestGasPrice", ctx)} +} + +func (_c *FeeEstimatorClient_SuggestGasPrice_Call) Run(run func(ctx context.Context)) *FeeEstimatorClient_SuggestGasPrice_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *FeeEstimatorClient_SuggestGasPrice_Call) Return(_a0 *big.Int, _a1 error) *FeeEstimatorClient_SuggestGasPrice_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeEstimatorClient_SuggestGasPrice_Call) RunAndReturn(run func(context.Context) (*big.Int, error)) *FeeEstimatorClient_SuggestGasPrice_Call { + _c.Call.Return(run) + return _c +} + // NewFeeEstimatorClient creates a new instance of FeeEstimatorClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewFeeEstimatorClient(t interface { diff --git a/core/chains/evm/gas/mocks/fee_history_estimator_client.go b/core/chains/evm/gas/mocks/fee_history_estimator_client.go new file mode 100644 index 0000000000..7486214501 --- /dev/null +++ b/core/chains/evm/gas/mocks/fee_history_estimator_client.go @@ -0,0 +1,157 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + big "math/big" + + ethereum "github.com/ethereum/go-ethereum" + + mock "github.com/stretchr/testify/mock" +) + +// FeeHistoryEstimatorClient is an autogenerated mock type for the feeHistoryEstimatorClient type +type FeeHistoryEstimatorClient struct { + mock.Mock +} + +type FeeHistoryEstimatorClient_Expecter struct { + mock *mock.Mock +} + +func (_m *FeeHistoryEstimatorClient) EXPECT() *FeeHistoryEstimatorClient_Expecter { + return &FeeHistoryEstimatorClient_Expecter{mock: &_m.Mock} +} + +// FeeHistory provides a mock function with given fields: ctx, blockCount, rewardPercentiles +func (_m *FeeHistoryEstimatorClient) FeeHistory(ctx context.Context, blockCount uint64, rewardPercentiles []float64) (*ethereum.FeeHistory, error) { + ret := _m.Called(ctx, blockCount, rewardPercentiles) + + if len(ret) == 0 { + panic("no return value specified for FeeHistory") + } + + var r0 *ethereum.FeeHistory + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, []float64) (*ethereum.FeeHistory, error)); ok { + return rf(ctx, blockCount, rewardPercentiles) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, []float64) *ethereum.FeeHistory); ok { + r0 = rf(ctx, blockCount, rewardPercentiles) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*ethereum.FeeHistory) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, []float64) error); ok { + r1 = rf(ctx, blockCount, rewardPercentiles) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeHistoryEstimatorClient_FeeHistory_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FeeHistory' +type FeeHistoryEstimatorClient_FeeHistory_Call struct { + *mock.Call +} + +// FeeHistory is a helper method to define mock.On call +// - ctx context.Context +// - blockCount uint64 +// - rewardPercentiles []float64 +func (_e *FeeHistoryEstimatorClient_Expecter) FeeHistory(ctx interface{}, blockCount interface{}, rewardPercentiles interface{}) *FeeHistoryEstimatorClient_FeeHistory_Call { + return &FeeHistoryEstimatorClient_FeeHistory_Call{Call: _e.mock.On("FeeHistory", ctx, blockCount, rewardPercentiles)} +} + +func (_c *FeeHistoryEstimatorClient_FeeHistory_Call) Run(run func(ctx context.Context, blockCount uint64, rewardPercentiles []float64)) *FeeHistoryEstimatorClient_FeeHistory_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].([]float64)) + }) + return _c +} + +func (_c *FeeHistoryEstimatorClient_FeeHistory_Call) Return(feeHistory *ethereum.FeeHistory, err error) *FeeHistoryEstimatorClient_FeeHistory_Call { + _c.Call.Return(feeHistory, err) + return _c +} + +func (_c *FeeHistoryEstimatorClient_FeeHistory_Call) RunAndReturn(run func(context.Context, uint64, []float64) (*ethereum.FeeHistory, error)) *FeeHistoryEstimatorClient_FeeHistory_Call { + _c.Call.Return(run) + return _c +} + +// SuggestGasPrice provides a mock function with given fields: ctx +func (_m *FeeHistoryEstimatorClient) SuggestGasPrice(ctx context.Context) (*big.Int, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for SuggestGasPrice") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*big.Int, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *big.Int); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FeeHistoryEstimatorClient_SuggestGasPrice_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SuggestGasPrice' +type FeeHistoryEstimatorClient_SuggestGasPrice_Call struct { + *mock.Call +} + +// SuggestGasPrice is a helper method to define mock.On call +// - ctx context.Context +func (_e *FeeHistoryEstimatorClient_Expecter) SuggestGasPrice(ctx interface{}) *FeeHistoryEstimatorClient_SuggestGasPrice_Call { + return &FeeHistoryEstimatorClient_SuggestGasPrice_Call{Call: _e.mock.On("SuggestGasPrice", ctx)} +} + +func (_c *FeeHistoryEstimatorClient_SuggestGasPrice_Call) Run(run func(ctx context.Context)) *FeeHistoryEstimatorClient_SuggestGasPrice_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *FeeHistoryEstimatorClient_SuggestGasPrice_Call) Return(_a0 *big.Int, _a1 error) *FeeHistoryEstimatorClient_SuggestGasPrice_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *FeeHistoryEstimatorClient_SuggestGasPrice_Call) RunAndReturn(run func(context.Context) (*big.Int, error)) *FeeHistoryEstimatorClient_SuggestGasPrice_Call { + _c.Call.Return(run) + return _c +} + +// NewFeeHistoryEstimatorClient creates a new instance of FeeHistoryEstimatorClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewFeeHistoryEstimatorClient(t interface { + mock.TestingT + Cleanup(func()) +}) *FeeHistoryEstimatorClient { + mock := &FeeHistoryEstimatorClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/chains/evm/gas/models.go b/core/chains/evm/gas/models.go index fda9425c22..b2f3bf02fd 100644 --- a/core/chains/evm/gas/models.go +++ b/core/chains/evm/gas/models.go @@ -50,6 +50,8 @@ type feeEstimatorClient interface { ConfiguredChainID() *big.Int HeadByNumber(ctx context.Context, n *big.Int) (*evmtypes.Head, error) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) + SuggestGasPrice(ctx context.Context) (*big.Int, error) + FeeHistory(ctx context.Context, blockCount uint64, rewardPercentiles []float64) (feeHistory *ethereum.FeeHistory, err error) } // NewEstimator returns the estimator for a given config @@ -109,6 +111,18 @@ func NewEstimator(lggr logger.Logger, ethClient feeEstimatorClient, cfg Config, newEstimator = func(l logger.Logger) EvmEstimator { return NewSuggestedPriceEstimator(lggr, ethClient, geCfg, l1Oracle) } + case "FeeHistory": + newEstimator = func(l logger.Logger) EvmEstimator { + ccfg := FeeHistoryEstimatorConfig{ + BumpPercent: geCfg.BumpPercent(), + CacheTimeout: geCfg.FeeHistory().CacheTimeout(), + EIP1559: geCfg.EIP1559DynamicFees(), + BlockHistorySize: uint64(geCfg.BlockHistory().BlockHistorySize()), + RewardPercentile: float64(geCfg.BlockHistory().TransactionPercentile()), + } + return NewFeeHistoryEstimator(lggr, ethClient, ccfg, ethClient.ConfiguredChainID(), l1Oracle) + } + default: lggr.Warnf("GasEstimator: unrecognised mode '%s', falling back to FixedPriceEstimator", s) newEstimator = func(l logger.Logger) EvmEstimator { diff --git a/core/chains/evm/txmgr/test_helpers.go b/core/chains/evm/txmgr/test_helpers.go index 48b2432fd0..a66727ce13 100644 --- a/core/chains/evm/txmgr/test_helpers.go +++ b/core/chains/evm/txmgr/test_helpers.go @@ -76,6 +76,10 @@ func (g *TestGasEstimatorConfig) BlockHistory() evmconfig.BlockHistory { return &TestBlockHistoryConfig{} } +func (g *TestGasEstimatorConfig) FeeHistory() evmconfig.FeeHistory { + return &TestFeeHistoryConfig{} +} + func (g *TestGasEstimatorConfig) EIP1559DynamicFees() bool { return false } func (g *TestGasEstimatorConfig) LimitDefault() uint64 { return 42 } func (g *TestGasEstimatorConfig) BumpPercent() uint16 { return 42 } @@ -124,6 +128,12 @@ func (b *TestBlockHistoryConfig) BlockHistorySize() uint16 { return 42 func (b *TestBlockHistoryConfig) EIP1559FeeCapBufferBlocks() uint16 { return 42 } func (b *TestBlockHistoryConfig) TransactionPercentile() uint16 { return 42 } +type TestFeeHistoryConfig struct { + evmconfig.FeeHistory +} + +func (b *TestFeeHistoryConfig) CacheTimeout() time.Duration { return 0 * time.Second } + type transactionsConfig struct { evmconfig.Transactions e *TestEvmConfig diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index d6d6bdf9f5..dae8e5b8aa 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -311,6 +311,15 @@ EIP1559FeeCapBufferBlocks = 13 # Example # Setting it lower will tend to set lower gas prices. TransactionPercentile = 60 # Default +[EVM.GasEstimator.FeeHistory] +# CacheTimeout is the time to wait in order to refresh the cached values stored in the FeeHistory estimator. A small jitter is applied so the timeout won't be exactly the same each time. +# +# You want this value to be close to the block time. For slower chains, like Ethereum, you can set it to 12s, the same as the block time. For faster chains you can skip a block or two +# and set it to two times the block time i.e. on Optimism you can set it to 4s. Ideally, you don't want to go lower than 1s since the RTT times of the RPC requests will be comparable to +# the timeout. The estimator is already adding a buffer to account for a potential increase in prices within one or two blocks. On the other hand, slower frequency will fail to refresh +# the prices and end up in stale values. +CacheTimeout = '10s' # Default + # The head tracker continually listens for new heads from the chain. # # In addition to these settings, it log warnings if `EVM.NoNewHeadsThreshold` is exceeded without any new blocks being emitted. diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 583e7cb1f4..7b91583308 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -555,6 +555,9 @@ func TestConfig_Marshal(t *testing.T) { EIP1559FeeCapBufferBlocks: ptr[uint16](13), TransactionPercentile: ptr[uint16](15), }, + FeeHistory: evmcfg.FeeHistoryEstimator{ + CacheTimeout: &second, + }, }, KeySpecific: []evmcfg.KeySpecific{ @@ -1067,6 +1070,9 @@ CheckInclusionPercentile = 19 EIP1559FeeCapBufferBlocks = 13 TransactionPercentile = 15 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '1s' + [EVM.HeadTracker] HistoryDepth = 15 MaxBufferSize = 17 diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 0a5678b2e4..80d2ca7fbb 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -353,6 +353,9 @@ CheckInclusionPercentile = 19 EIP1559FeeCapBufferBlocks = 13 TransactionPercentile = 15 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '1s' + [EVM.HeadTracker] HistoryDepth = 15 MaxBufferSize = 17 diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 065cdfe0cb..6a1cda457e 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -330,6 +330,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' + [EVM.HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -434,6 +437,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' + [EVM.HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -532,6 +538,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' + [EVM.HeadTracker] HistoryDepth = 2000 MaxBufferSize = 3 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index f9befd487d..c10f68dd24 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -352,6 +352,9 @@ CheckInclusionPercentile = 19 EIP1559FeeCapBufferBlocks = 13 TransactionPercentile = 15 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '1s' + [EVM.HeadTracker] HistoryDepth = 15 MaxBufferSize = 17 diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 3d13f2b64c..d7513ada26 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -330,6 +330,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' + [EVM.HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -434,6 +437,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' + [EVM.HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -532,6 +538,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' + [EVM.HeadTracker] HistoryDepth = 2000 MaxBufferSize = 3 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index d7e7c0af0a..66ce21a21e 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1895,6 +1895,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -1993,6 +1996,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -2091,6 +2097,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -2189,6 +2198,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -2288,6 +2300,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 300 MaxBufferSize = 3 @@ -2386,6 +2401,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -2484,6 +2502,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -2583,6 +2604,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -2681,6 +2705,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -2778,6 +2805,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -2875,6 +2905,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -2973,6 +3006,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -3072,6 +3108,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -3170,6 +3209,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -3268,6 +3310,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 2000 MaxBufferSize = 3 @@ -3366,6 +3411,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 2000 MaxBufferSize = 3 @@ -3464,6 +3512,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 2000 MaxBufferSize = 3 @@ -3562,6 +3613,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -3660,6 +3714,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 400 MaxBufferSize = 3 @@ -3758,6 +3815,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 50 MaxBufferSize = 3 @@ -3856,6 +3916,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 50 MaxBufferSize = 3 @@ -3954,6 +4017,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 50 MaxBufferSize = 3 @@ -4053,6 +4119,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 300 MaxBufferSize = 3 @@ -4151,6 +4220,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -4248,6 +4320,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -4346,6 +4421,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -4444,6 +4522,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 2000 MaxBufferSize = 3 @@ -4542,6 +4623,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -4640,6 +4724,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -4737,6 +4824,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 10 MaxBufferSize = 100 @@ -4835,6 +4925,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 2000 MaxBufferSize = 3 @@ -4933,6 +5026,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 400 MaxBufferSize = 3 @@ -5031,6 +5127,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 2000 MaxBufferSize = 3 @@ -5129,6 +5228,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -5226,6 +5328,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -5324,6 +5429,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 300 MaxBufferSize = 3 @@ -5422,6 +5530,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -5521,6 +5632,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -5620,6 +5734,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -5719,6 +5836,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -5817,6 +5937,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 50 MaxBufferSize = 3 @@ -5915,6 +6038,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -6013,6 +6139,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -6111,6 +6240,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 50 MaxBufferSize = 3 @@ -6208,6 +6340,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -6305,6 +6440,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 1000 MaxBufferSize = 3 @@ -6402,6 +6540,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 350 MaxBufferSize = 3 @@ -6500,6 +6641,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -6598,6 +6742,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 2000 MaxBufferSize = 3 @@ -6695,6 +6842,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 2000 MaxBufferSize = 3 @@ -6793,6 +6943,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 300 MaxBufferSize = 3 @@ -6891,6 +7044,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 300 MaxBufferSize = 3 @@ -6990,6 +7146,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -7089,6 +7248,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -7187,6 +7349,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -7285,6 +7450,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 50 MaxBufferSize = 3 @@ -7383,6 +7551,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 50 MaxBufferSize = 3 @@ -7481,6 +7652,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -7579,6 +7753,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 300 MaxBufferSize = 3 @@ -7677,6 +7854,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -7775,6 +7955,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + [HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 @@ -8438,6 +8621,24 @@ Setting this number higher will cause the Chainlink node to select higher gas pr Setting it lower will tend to set lower gas prices. +## EVM.GasEstimator.FeeHistory +```toml +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' # Default +``` + + +### CacheTimeout +```toml +CacheTimeout = '10s' # Default +``` +CacheTimeout is the time to wait in order to refresh the cached values stored in the FeeHistory estimator. A small jitter is applied so the timeout won't be exactly the same each time. + +You want this value to be close to the block time. For slower chains, like Ethereum, you can set it to 12s, the same as the block time. For faster chains you can skip a block or two +and set it to two times the block time i.e. on Optimism you can set it to 4s. Ideally, you don't want to go lower than 1s since the RTT times of the RPC requests will be comparable to +the timeout. The estimator is already adding a buffer to account for a potential increase in prices within one or two blocks. On the other hand, slower frequency will fail to refresh +the prices and end up in stale values. + ## EVM.HeadTracker ```toml [EVM.HeadTracker] diff --git a/testdata/scripts/node/validate/defaults-override.txtar b/testdata/scripts/node/validate/defaults-override.txtar index f02605a49e..d419443711 100644 --- a/testdata/scripts/node/validate/defaults-override.txtar +++ b/testdata/scripts/node/validate/defaults-override.txtar @@ -403,6 +403,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' + [EVM.HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index 3cb365afa1..c180178920 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -386,6 +386,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' + [EVM.HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 083aca41b0..72832f3783 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -386,6 +386,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' + [EVM.HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 34911e3e48..7921d124c4 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -386,6 +386,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' + [EVM.HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index aa4b7960bd..66ca83e03e 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -376,6 +376,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' + [EVM.HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index bf21436c2e..166db265d5 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -383,6 +383,9 @@ CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 50 +[EVM.GasEstimator.FeeHistory] +CacheTimeout = '10s' + [EVM.HeadTracker] HistoryDepth = 100 MaxBufferSize = 3 From f7fec9c8ce89c672595c298014614eb963cd5a29 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 4 Sep 2024 05:42:20 +0200 Subject: [PATCH 280/432] core/services/chainlink: normalize feature config (#14324) --- core/config/app_config.go | 2 - core/services/chainlink/application.go | 1 + core/services/chainlink/config_general.go | 4 -- .../chainlink/mocks/general_config.go | 45 ------------------- core/services/feeds/config.go | 5 ++- core/services/feeds/service.go | 7 ++- core/services/feeds/service_test.go | 2 +- 7 files changed, 11 insertions(+), 55 deletions(-) diff --git a/core/config/app_config.go b/core/config/app_config.go index 27d56bb4cb..112e242636 100644 --- a/core/config/app_config.go +++ b/core/config/app_config.go @@ -56,8 +56,6 @@ type AppConfig interface { Threshold() Threshold WebServer() WebServer Tracing() Tracing - - FeatureMultiFeedsManagers() bool } type DatabaseBackupMode string diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 6df51045c0..244d5da13d 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -577,6 +577,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { jobSpawner, keyStore, cfg, + cfg.Feature(), cfg.Insecure(), cfg.JobPipeline(), cfg.OCR(), diff --git a/core/services/chainlink/config_general.go b/core/services/chainlink/config_general.go index d329fb0fac..79c92f8214 100644 --- a/core/services/chainlink/config_general.go +++ b/core/services/chainlink/config_general.go @@ -282,10 +282,6 @@ func (g *generalConfig) FeatureFeedsManager() bool { return *g.c.Feature.FeedsManager } -func (g *generalConfig) FeatureMultiFeedsManagers() bool { - return *g.c.Feature.MultiFeedsManagers -} - func (g *generalConfig) OCR() config.OCR { return &ocrConfig{c: g.c.OCR} } diff --git a/core/services/chainlink/mocks/general_config.go b/core/services/chainlink/mocks/general_config.go index 2339cf9656..f4594a4322 100644 --- a/core/services/chainlink/mocks/general_config.go +++ b/core/services/chainlink/mocks/general_config.go @@ -694,51 +694,6 @@ func (_c *GeneralConfig_Feature_Call) RunAndReturn(run func() config.Feature) *G return _c } -// FeatureMultiFeedsManagers provides a mock function with given fields: -func (_m *GeneralConfig) FeatureMultiFeedsManagers() bool { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for FeatureMultiFeedsManagers") - } - - var r0 bool - if rf, ok := ret.Get(0).(func() bool); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(bool) - } - - return r0 -} - -// GeneralConfig_FeatureMultiFeedsManagers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FeatureMultiFeedsManagers' -type GeneralConfig_FeatureMultiFeedsManagers_Call struct { - *mock.Call -} - -// FeatureMultiFeedsManagers is a helper method to define mock.On call -func (_e *GeneralConfig_Expecter) FeatureMultiFeedsManagers() *GeneralConfig_FeatureMultiFeedsManagers_Call { - return &GeneralConfig_FeatureMultiFeedsManagers_Call{Call: _e.mock.On("FeatureMultiFeedsManagers")} -} - -func (_c *GeneralConfig_FeatureMultiFeedsManagers_Call) Run(run func()) *GeneralConfig_FeatureMultiFeedsManagers_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *GeneralConfig_FeatureMultiFeedsManagers_Call) Return(_a0 bool) *GeneralConfig_FeatureMultiFeedsManagers_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *GeneralConfig_FeatureMultiFeedsManagers_Call) RunAndReturn(run func() bool) *GeneralConfig_FeatureMultiFeedsManagers_Call { - _c.Call.Return(run) - return _c -} - // FluxMonitor provides a mock function with given fields: func (_m *GeneralConfig) FluxMonitor() config.FluxMonitor { ret := _m.Called() diff --git a/core/services/feeds/config.go b/core/services/feeds/config.go index 690117a510..626dc862e9 100644 --- a/core/services/feeds/config.go +++ b/core/services/feeds/config.go @@ -10,7 +10,10 @@ import ( type GeneralConfig interface { OCR() coreconfig.OCR Insecure() coreconfig.Insecure - FeatureMultiFeedsManagers() bool +} + +type FeatureConfig interface { + MultiFeedsManagers() bool } type JobConfig interface { diff --git a/core/services/feeds/service.go b/core/services/feeds/service.go index 9671900309..0ccba8ff2a 100644 --- a/core/services/feeds/service.go +++ b/core/services/feeds/service.go @@ -124,6 +124,7 @@ type service struct { ocr2KeyStore keystore.OCR2 jobSpawner job.Spawner gCfg GeneralConfig + featCfg FeatureConfig insecureCfg InsecureConfig jobCfg JobConfig ocrCfg OCRConfig @@ -143,6 +144,7 @@ func NewService( jobSpawner job.Spawner, keyStore keystore.Master, gCfg GeneralConfig, + fCfg FeatureConfig, insecureCfg InsecureConfig, jobCfg JobConfig, ocrCfg OCRConfig, @@ -163,6 +165,7 @@ func NewService( ocr1KeyStore: keyStore.OCR(), ocr2KeyStore: keyStore.OCR2(), gCfg: gCfg, + featCfg: fCfg, insecureCfg: insecureCfg, jobCfg: jobCfg, ocrCfg: ocrCfg, @@ -187,7 +190,7 @@ type RegisterManagerParams struct { // RegisterManager registers a new ManagerService and attempts to establish a // connection. func (s *service) RegisterManager(ctx context.Context, params RegisterManagerParams) (int64, error) { - if s.gCfg.FeatureMultiFeedsManagers() { + if s.featCfg.MultiFeedsManagers() { exists, err := s.orm.ManagerExists(ctx, params.PublicKey) if err != nil { return 0, err @@ -1034,7 +1037,7 @@ func (s *service) Start(ctx context.Context) error { return nil } - if s.gCfg.FeatureMultiFeedsManagers() { + if s.featCfg.MultiFeedsManagers() { s.lggr.Infof("starting connection to %d feeds managers", len(mgrs)) for _, mgr := range mgrs { s.connectFeedManager(ctx, mgr, privkey) diff --git a/core/services/feeds/service_test.go b/core/services/feeds/service_test.go index 41c62ea5e0..1dc9904fd5 100644 --- a/core/services/feeds/service_test.go +++ b/core/services/feeds/service_test.go @@ -194,7 +194,7 @@ func setupTestServiceCfg(t *testing.T, overrideCfg func(c *chainlink.Config, s * keyStore.On("P2P").Return(p2pKeystore) keyStore.On("OCR").Return(ocr1Keystore) keyStore.On("OCR2").Return(ocr2Keystore) - svc := feeds.NewService(orm, jobORM, db, spawner, keyStore, gcfg, gcfg.Insecure(), gcfg.JobPipeline(), gcfg.OCR(), gcfg.OCR2(), legacyChains, lggr, "1.0.0", nil) + svc := feeds.NewService(orm, jobORM, db, spawner, keyStore, gcfg, gcfg.Feature(), gcfg.Insecure(), gcfg.JobPipeline(), gcfg.OCR(), gcfg.OCR2(), legacyChains, lggr, "1.0.0", nil) svc.SetConnectionsManager(connMgr) return &TestService{ From 1a2b7b61cbd22256e4e29e891a74228fa453fc9d Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Wed, 4 Sep 2024 05:23:49 -0500 Subject: [PATCH 281/432] Mark terminally stuck transaction pending task runs as failure (#14282) * Updated Confirmer to resume pending task runs with failure for terminally stuck txs * Updated resume callback error message * Added CallbackCompleted check before resuming pending task --- .changeset/flat-emus-act.md | 5 ++++ common/txmgr/broadcaster.go | 2 +- common/txmgr/confirmer.go | 29 +++++++++++++++++++++- common/txmgr/types/stuck_tx_detector.go | 2 +- core/chains/evm/txmgr/confirmer_test.go | 9 ++++++- core/chains/evm/txmgr/stuck_tx_detector.go | 5 ++-- 6 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 .changeset/flat-emus-act.md diff --git a/.changeset/flat-emus-act.md b/.changeset/flat-emus-act.md new file mode 100644 index 0000000000..a4cbae1287 --- /dev/null +++ b/.changeset/flat-emus-act.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Updated TXM Confirmer logic to resume pending task runs with failure if transaction is terminally stuck #internal diff --git a/common/txmgr/broadcaster.go b/common/txmgr/broadcaster.go index 86475c2e0e..8ecd6dbf46 100644 --- a/common/txmgr/broadcaster.go +++ b/common/txmgr/broadcaster.go @@ -756,7 +756,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) save // Now we have an errored pipeline even though the tx succeeded. This case // is relatively benign and probably nobody will ever run into it in // practice, but something to be aware of. - if etx.PipelineTaskRunID.Valid && eb.resumeCallback != nil && etx.SignalCallback { + if etx.PipelineTaskRunID.Valid && eb.resumeCallback != nil && etx.SignalCallback && !etx.CallbackCompleted { err := eb.resumeCallback(ctx, etx.PipelineTaskRunID.UUID, nil, fmt.Errorf("fatal error while sending transaction: %s", etx.Error.String)) if errors.Is(err, sql.ErrNoRows) { lgr.Debugw("callback missing or already resumed", "etxID", etx.ID) diff --git a/common/txmgr/confirmer.go b/common/txmgr/confirmer.go index d67bd45122..bbf1d3b27b 100644 --- a/common/txmgr/confirmer.go +++ b/common/txmgr/confirmer.go @@ -2,6 +2,7 @@ package txmgr import ( "context" + "database/sql" "encoding/hex" "errors" "fmt" @@ -514,6 +515,13 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Pro errMu.Unlock() return } + // Resume pending task runs with failure for stuck transactions + if err := ec.resumeFailedTaskRuns(ctx, tx); err != nil { + errMu.Lock() + errorList = append(errorList, fmt.Errorf("failed to resume pending task run for transaction: %w", err)) + errMu.Unlock() + return + } }(tx) } wg.Wait() @@ -584,7 +592,8 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) fet return fmt.Errorf("saveFetchedReceipts failed: %w", err) } // Save the receipts but mark the associated transactions as Fatal Error since the original transaction was purged - if err := ec.txStore.SaveFetchedReceipts(ctx, purgeReceipts, TxFatalError, ec.stuckTxDetector.StuckTxFatalError(), ec.chainID); err != nil { + stuckTxFatalErrMsg := ec.stuckTxDetector.StuckTxFatalError() + if err := ec.txStore.SaveFetchedReceipts(ctx, purgeReceipts, TxFatalError, &stuckTxFatalErrMsg, ec.chainID); err != nil { return fmt.Errorf("saveFetchedReceipts failed: %w", err) } promNumConfirmedTxs.WithLabelValues(ec.chainID.String()).Add(float64(len(receipts))) @@ -616,6 +625,24 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) sep return } +func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) resumeFailedTaskRuns(ctx context.Context, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) error { + if !etx.PipelineTaskRunID.Valid || ec.resumeCallback == nil || !etx.SignalCallback || etx.CallbackCompleted { + return nil + } + err := ec.resumeCallback(ctx, etx.PipelineTaskRunID.UUID, nil, errors.New(ec.stuckTxDetector.StuckTxFatalError())) + if errors.Is(err, sql.ErrNoRows) { + ec.lggr.Debugw("callback missing or already resumed", "etxID", etx.ID) + } else if err != nil { + return fmt.Errorf("failed to resume pipeline: %w", err) + } else { + // Mark tx as having completed callback + if err = ec.txStore.UpdateTxCallbackCompleted(ctx, etx.PipelineTaskRunID.UUID, ec.chainID); err != nil { + return err + } + } + return nil +} + func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) getMinedSequenceForAddress(ctx context.Context, from ADDR) (SEQ, error) { return ec.client.SequenceAt(ctx, from, nil) } diff --git a/common/txmgr/types/stuck_tx_detector.go b/common/txmgr/types/stuck_tx_detector.go index c4ca94b87f..dc09eea980 100644 --- a/common/txmgr/types/stuck_tx_detector.go +++ b/common/txmgr/types/stuck_tx_detector.go @@ -22,5 +22,5 @@ type StuckTxDetector[ // Sets the last purged block num after a transaction has been successfully purged with receipt SetPurgeBlockNum(fromAddress ADDR, blockNum int64) // Returns the error message to set in the transaction error field to mark it as terminally stuck - StuckTxFatalError() *string + StuckTxFatalError() string } diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index a9dec223bf..dc8e30f5f4 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -3235,6 +3235,11 @@ func TestEthConfirmer_ProcessStuckTransactions(t *testing.T) { stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), evmcfg.EVM().Transactions().AutoPurge(), feeEstimator, txStore, ethClient) ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(ge), evmcfg.EVM().Transactions(), cfg.Database(), ethKeyStore, txBuilder, lggr, stuckTxDetector, ht) + fn := func(ctx context.Context, id uuid.UUID, result interface{}, err error) error { + require.ErrorContains(t, err, client.TerminallyStuckMsg) + return nil + } + ec.SetResumeCallback(fn) servicetest.Run(t, ec) ctx := tests.Context(t) @@ -3246,7 +3251,8 @@ func TestEthConfirmer_ProcessStuckTransactions(t *testing.T) { // Create autoPurgeMinAttempts number of attempts to ensure the broadcast attempt count check is not being triggered // Create attempts broadcasted autoPurgeThreshold block ago to ensure broadcast block num check is not being triggered tx := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, nonce, fromAddress, autoPurgeMinAttempts, blockNum-int64(autoPurgeThreshold), marketGasPrice.Add(oneGwei)) - + // Update tx to signal callback once it is identified as terminally stuck + pgtest.MustExec(t, db, `UPDATE evm.txes SET pipeline_task_run_id = $1, signal_callback = TRUE WHERE id = $2`, uuid.New(), tx.ID) head := evmtypes.Head{ Hash: testutils.NewHash(), Number: blockNum, @@ -3307,6 +3313,7 @@ func TestEthConfirmer_ProcessStuckTransactions(t *testing.T) { require.NotNil(t, dbTx) require.Equal(t, txmgrcommon.TxFatalError, dbTx.State) require.Equal(t, client.TerminallyStuckMsg, dbTx.Error.String) + require.Equal(t, true, dbTx.CallbackCompleted) }) } diff --git a/core/chains/evm/txmgr/stuck_tx_detector.go b/core/chains/evm/txmgr/stuck_tx_detector.go index 362bb6c0a5..26d7643c15 100644 --- a/core/chains/evm/txmgr/stuck_tx_detector.go +++ b/core/chains/evm/txmgr/stuck_tx_detector.go @@ -409,7 +409,6 @@ func (d *stuckTxDetector) SetPurgeBlockNum(fromAddress common.Address, blockNum d.purgeBlockNumMap[fromAddress] = blockNum } -func (d *stuckTxDetector) StuckTxFatalError() *string { - errorMsg := client.TerminallyStuckMsg - return &errorMsg +func (d *stuckTxDetector) StuckTxFatalError() string { + return client.TerminallyStuckMsg } From 8490c9610b1208f3efafe29587032679e5727247 Mon Sep 17 00:00:00 2001 From: martin-cll <121895364+martin-cll@users.noreply.github.com> Date: Wed, 4 Sep 2024 23:12:15 +1000 Subject: [PATCH 282/432] MERC-6190: Remove bid/ask fields from Mercury v4 schema (#14252) * Remove bid/ask fields from Mercury v4 schema * Add changeset * make generate * Add #internal changeset tag * Update chainlink-data-streams dep --- .changeset/neat-yaks-switch.md | 5 +++ core/scripts/go.mod | 13 +++++-- core/scripts/go.sum | 8 ++-- .../ocr2/plugins/mercury/helpers_test.go | 34 ++++------------- .../ocr2/plugins/mercury/integration_test.go | 8 +--- core/services/ocrcommon/telemetry.go | 8 +--- .../relay/evm/mercury/v4/data_source.go | 38 ++----------------- .../relay/evm/mercury/v4/data_source_test.go | 36 ++---------------- .../mercury/v4/reportcodec/report_codec.go | 8 +--- .../v4/reportcodec/report_codec_test.go | 12 +----- .../relay/evm/mercury/v4/types/types.go | 4 -- .../synchronization/telem/telem.pb.go | 5 +-- .../telem/telem_automation_custom.pb.go | 5 +-- .../telem/telem_enhanced_ea.pb.go | 5 +-- .../telem/telem_enhanced_ea_mercury.pb.go | 5 +-- .../telem/telem_functions_request.pb.go | 5 +-- .../telem/telem_head_report.pb.go | 15 ++++---- .../synchronization/telem/telem_wsrpc.pb.go | 1 - go.md | 1 + go.mod | 13 +++++-- go.sum | 8 ++-- integration-tests/go.mod | 7 +++- integration-tests/go.sum | 8 ++-- integration-tests/load/go.mod | 7 +++- integration-tests/load/go.sum | 8 ++-- 25 files changed, 86 insertions(+), 181 deletions(-) create mode 100644 .changeset/neat-yaks-switch.md diff --git a/.changeset/neat-yaks-switch.md b/.changeset/neat-yaks-switch.md new file mode 100644 index 0000000000..141c6dbddf --- /dev/null +++ b/.changeset/neat-yaks-switch.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Remove bid/ask fields for Mercury v4 schema #internal diff --git a/core/scripts/go.mod b/core/scripts/go.mod index aafcfb8ed7..5215cc0e91 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 @@ -272,7 +272,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect @@ -363,5 +363,10 @@ require ( sigs.k8s.io/yaml v1.4.0 // indirect ) -// replicating the replace directive on cosmos SDK -replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 +replace ( + // until merged upstream: https://github.com/omissis/go-jsonschema/pull/264 + github.com/atombender/go-jsonschema => github.com/nolag/go-jsonschema v0.16.0-rtinianov + + // replicating the replace directive on cosmos SDK + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 +) diff --git a/core/scripts/go.sum b/core/scripts/go.sum index f0db4b0929..d4d8962634 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1190,12 +1190,12 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e h1:kxMSsv/RaTlH0Up9YTC6FE4K9n5QWcSKxbtiTS+JHzU= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= diff --git a/core/services/ocr2/plugins/mercury/helpers_test.go b/core/services/ocr2/plugins/mercury/helpers_test.go index 6a01bcf8c0..ecfedf2935 100644 --- a/core/services/ocr2/plugins/mercury/helpers_test.go +++ b/core/services/ocr2/plugins/mercury/helpers_test.go @@ -478,8 +478,6 @@ func addV4MercuryJob( bootstrapPeerID string, bootstrapNodePort int, bmBridge, - bidBridge, - askBridge, marketStatusBridge string, servers map[string]string, clientPubKey ed25519.PublicKey, @@ -497,11 +495,11 @@ func addV4MercuryJob( node.AddJob(t, fmt.Sprintf(` type = "offchainreporting2" schemaVersion = 1 -name = "mercury-%[1]d-%[11]s" +name = "mercury-%[1]d-%[9]s" forwardingAllowed = false maxTaskDuration = "1s" contractID = "%[2]s" -feedID = "0x%[10]x" +feedID = "0x%[8]x" contractConfigTrackerPollInterval = "1s" ocrKeyBundleID = "%[3]s" p2pv2Bootstrappers = [ @@ -509,7 +507,7 @@ p2pv2Bootstrappers = [ ] relay = "evm" pluginType = "mercury" -transmitterID = "%[9]x" +transmitterID = "%[7]x" observationSource = """ // Benchmark Price price1 [type=bridge name="%[5]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; @@ -518,31 +516,17 @@ observationSource = """ price1 -> price1_parse -> price1_multiply; - // Bid - bid [type=bridge name="%[6]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; - bid_parse [type=jsonparse path="result"]; - bid_multiply [type=multiply times=100000000 index=1]; - - bid -> bid_parse -> bid_multiply; - - // Ask - ask [type=bridge name="%[7]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; - ask_parse [type=jsonparse path="result"]; - ask_multiply [type=multiply times=100000000 index=2]; - - ask -> ask_parse -> ask_multiply; - // Market Status - marketstatus [type=bridge name="%[14]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; - marketstatus_parse [type=jsonparse path="result" index=3]; + marketstatus [type=bridge name="%[12]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; + marketstatus_parse [type=jsonparse path="result" index=1]; marketstatus -> marketstatus_parse; """ [pluginConfig] -servers = %[8]s -linkFeedID = "0x%[12]x" -nativeFeedID = "0x%[13]x" +servers = %[6]s +linkFeedID = "0x%[10]x" +nativeFeedID = "0x%[11]x" [relayConfig] chainID = 1337 @@ -552,8 +536,6 @@ chainID = 1337 node.KeyBundle.ID(), fmt.Sprintf("%s@127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), bmBridge, - bidBridge, - askBridge, serversStr, clientPubKey, feedID, diff --git a/core/services/ocr2/plugins/mercury/integration_test.go b/core/services/ocr2/plugins/mercury/integration_test.go index 6f9f373256..a8d49150b8 100644 --- a/core/services/ocr2/plugins/mercury/integration_test.go +++ b/core/services/ocr2/plugins/mercury/integration_test.go @@ -1105,7 +1105,7 @@ func integration_MercuryV4(t *testing.T) { k := csakey.MustNewV2XXXTestingOnly(big.NewInt(int64(-(i + 1)))) reqs := make(chan request, 100) srv := NewMercuryServer(t, ed25519.PrivateKey(k.Raw()), reqs, func() []byte { - report, err := (&reportcodecv4.ReportCodec{}).BuildReport(v4.ReportFields{BenchmarkPrice: big.NewInt(234567), Bid: big.NewInt(1), Ask: big.NewInt(1), LinkFee: big.NewInt(1), NativeFee: big.NewInt(1), MarketStatus: 1}) + report, err := (&reportcodecv4.ReportCodec{}).BuildReport(v4.ReportFields{BenchmarkPrice: big.NewInt(234567), LinkFee: big.NewInt(1), NativeFee: big.NewInt(1), MarketStatus: 1}) if err != nil { panic(err) } @@ -1205,8 +1205,6 @@ func integration_MercuryV4(t *testing.T) { for i, node := range nodes { for j, feed := range feeds { bmBridge := createBridge(fmt.Sprintf("benchmarkprice-%d", j), i, feed.baseBenchmarkPrice, 0, node.App.BridgeORM()) - bidBridge := createBridge(fmt.Sprintf("bid-%d", j), i, feed.baseBid, 0, node.App.BridgeORM()) - askBridge := createBridge(fmt.Sprintf("ask-%d", j), i, feed.baseAsk, 0, node.App.BridgeORM()) marketStatusBridge := createBridge(fmt.Sprintf("marketstatus-%d", j), i, nil, feed.baseMarketStatus, node.App.BridgeORM()) addV4MercuryJob( @@ -1217,8 +1215,6 @@ func integration_MercuryV4(t *testing.T) { bootstrapPeerID, bootstrapNodePort, bmBridge, - bidBridge, - askBridge, marketStatusBridge, servers, clientPubKeys[i], @@ -1312,8 +1308,6 @@ func integration_MercuryV4(t *testing.T) { assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp)) assert.InDelta(t, feed.baseBenchmarkPrice.Int64(), reportElems["benchmarkPrice"].(*big.Int).Int64(), 5000000) - assert.InDelta(t, feed.baseBid.Int64(), reportElems["bid"].(*big.Int).Int64(), 5000000) - assert.InDelta(t, feed.baseAsk.Int64(), reportElems["ask"].(*big.Int).Int64(), 5000000) assert.NotZero(t, reportElems["validFromTimestamp"].(uint32)) assert.GreaterOrEqual(t, reportElems["observationsTimestamp"].(uint32), reportElems["validFromTimestamp"].(uint32)) assert.Equal(t, expectedExpiresAt, reportElems["expiresAt"].(uint32)) diff --git a/core/services/ocrcommon/telemetry.go b/core/services/ocrcommon/telemetry.go index 2cb4fda910..7db29aaacb 100644 --- a/core/services/ocrcommon/telemetry.go +++ b/core/services/ocrcommon/telemetry.go @@ -294,7 +294,7 @@ func (e *EnhancedTelemetryService[T]) collectMercuryEnhancedTelemetry(d Enhanced var bn int64 var bh string var bt uint64 - // v1+v2+v3 fields + // v1+v2+v3+v4 fields bp := big.NewInt(0) // v1+v3 fields bid := big.NewInt(0) @@ -373,12 +373,6 @@ func (e *EnhancedTelemetryService[T]) collectMercuryEnhancedTelemetry(d Enhanced if obs.BenchmarkPrice.Err == nil && obs.BenchmarkPrice.Val != nil { bp = obs.BenchmarkPrice.Val } - if obs.Bid.Err == nil && obs.Bid.Val != nil { - bid = obs.Bid.Val - } - if obs.Ask.Err == nil && obs.Ask.Val != nil { - ask = obs.Ask.Val - } if obs.MarketStatus.Err == nil { marketStatus = telem.MarketStatus(obs.MarketStatus.Val) } diff --git a/core/services/relay/evm/mercury/v4/data_source.go b/core/services/relay/evm/mercury/v4/data_source.go index f9c2c2d5de..05ec44dc78 100644 --- a/core/services/relay/evm/mercury/v4/data_source.go +++ b/core/services/relay/evm/mercury/v4/data_source.go @@ -104,8 +104,6 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam return } obs.BenchmarkPrice = parsed.benchmarkPrice - obs.Bid = parsed.bid - obs.Ask = parsed.ask obs.MarketStatus = parsed.marketStatus }() @@ -188,8 +186,6 @@ func toBigInt(val interface{}) (*big.Int, error) { type parseOutput struct { benchmarkPrice mercury.ObsResult[*big.Int] - bid mercury.ObsResult[*big.Int] - ask mercury.ObsResult[*big.Int] marketStatus mercury.ObsResult[uint32] } @@ -204,15 +200,13 @@ func (ds *datasource) parse(trrs pipeline.TaskRunResults) (o parseOutput, merr e // pipeline.TaskRunResults comes ordered asc by index, this is guaranteed // by the pipeline executor - if len(finaltrrs) != 4 { - return o, fmt.Errorf("invalid number of results, expected: 4, got: %d", len(finaltrrs)) + if len(finaltrrs) != 2 { + return o, fmt.Errorf("invalid number of results, expected: 2, got: %d", len(finaltrrs)) } merr = errors.Join( setBenchmarkPrice(&o, finaltrrs[0].Result), - setBid(&o, finaltrrs[1].Result), - setAsk(&o, finaltrrs[2].Result), - setMarketStatus(&o, finaltrrs[3].Result), + setMarketStatus(&o, finaltrrs[1].Result), ) return o, merr @@ -231,32 +225,6 @@ func setBenchmarkPrice(o *parseOutput, res pipeline.Result) error { return nil } -func setBid(o *parseOutput, res pipeline.Result) error { - if res.Error != nil { - o.bid.Err = res.Error - return res.Error - } - val, err := toBigInt(res.Value) - if err != nil { - return fmt.Errorf("failed to parse Bid: %w", err) - } - o.bid.Val = val - return nil -} - -func setAsk(o *parseOutput, res pipeline.Result) error { - if res.Error != nil { - o.ask.Err = res.Error - return res.Error - } - val, err := toBigInt(res.Value) - if err != nil { - return fmt.Errorf("failed to parse Ask: %w", err) - } - o.ask.Val = val - return nil -} - func setMarketStatus(o *parseOutput, res pipeline.Result) error { if res.Error != nil { o.marketStatus.Err = res.Error diff --git a/core/services/relay/evm/mercury/v4/data_source_test.go b/core/services/relay/evm/mercury/v4/data_source_test.go index bce9c3c608..7b50a922c8 100644 --- a/core/services/relay/evm/mercury/v4/data_source_test.go +++ b/core/services/relay/evm/mercury/v4/data_source_test.go @@ -86,16 +86,6 @@ func Test_Datasource(t *testing.T) { Result: pipeline.Result{Value: "122.345"}, Task: &mercurymocks.MockTask{}, }, - { - // bid - Result: pipeline.Result{Value: "121.993"}, - Task: &mercurymocks.MockTask{}, - }, - { - // ask - Result: pipeline.Result{Value: "123.111"}, - Task: &mercurymocks.MockTask{}, - }, { // marketStatus Result: pipeline.Result{Value: "1"}, @@ -193,10 +183,6 @@ func Test_Datasource(t *testing.T) { assert.Equal(t, big.NewInt(122), obs.BenchmarkPrice.Val) assert.NoError(t, obs.BenchmarkPrice.Err) - assert.Equal(t, big.NewInt(121), obs.Bid.Val) - assert.NoError(t, obs.Bid.Err) - assert.Equal(t, big.NewInt(123), obs.Ask.Val) - assert.NoError(t, obs.Ask.Err) assert.Equal(t, int64(123123), obs.MaxFinalizedTimestamp.Val) assert.NoError(t, obs.MaxFinalizedTimestamp.Err) assert.Equal(t, big.NewInt(122), obs.LinkPrice.Val) @@ -239,17 +225,7 @@ func Test_Datasource(t *testing.T) { badTrrs := []pipeline.TaskRunResult{ { // benchmark price - Result: pipeline.Result{Value: "122.345"}, - Task: &mercurymocks.MockTask{}, - }, - { - // bid - Result: pipeline.Result{Value: "121.993"}, - Task: &mercurymocks.MockTask{}, - }, - { - // ask - Result: pipeline.Result{Error: errors.New("some error with ask")}, + Result: pipeline.Result{Error: errors.New("some error with bp")}, Task: &mercurymocks.MockTask{}, }, { @@ -265,7 +241,7 @@ func Test_Datasource(t *testing.T) { } _, err := ds.Observe(ctx, repts, false) - assert.EqualError(t, err, "Observe failed while parsing run results: some error with ask") + assert.EqualError(t, err, "Observe failed while parsing run results: some error with bp") }) t.Run("when run execution succeeded", func(t *testing.T) { @@ -282,10 +258,6 @@ func Test_Datasource(t *testing.T) { assert.Equal(t, big.NewInt(122), obs.BenchmarkPrice.Val) assert.NoError(t, obs.BenchmarkPrice.Err) - assert.Equal(t, big.NewInt(121), obs.Bid.Val) - assert.NoError(t, obs.Bid.Err) - assert.Equal(t, big.NewInt(123), obs.Ask.Val) - assert.NoError(t, obs.Ask.Err) assert.Equal(t, int64(0), obs.MaxFinalizedTimestamp.Val) assert.NoError(t, obs.MaxFinalizedTimestamp.Err) assert.Equal(t, big.NewInt(122), obs.LinkPrice.Val) @@ -333,15 +305,13 @@ func buildSamplev4Report() []byte { feedID := sampleFeedID timestamp := uint32(124) bp := big.NewInt(242) - bid := big.NewInt(243) - ask := big.NewInt(244) validFromTimestamp := uint32(123) expiresAt := uint32(456) linkFee := big.NewInt(3334455) nativeFee := big.NewInt(556677) marketStatus := uint32(1) - b, err := reportcodecv4.ReportTypes.Pack(feedID, validFromTimestamp, timestamp, nativeFee, linkFee, expiresAt, bp, bid, ask, marketStatus) + b, err := reportcodecv4.ReportTypes.Pack(feedID, validFromTimestamp, timestamp, nativeFee, linkFee, expiresAt, bp, marketStatus) if err != nil { panic(err) } diff --git a/core/services/relay/evm/mercury/v4/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v4/reportcodec/report_codec.go index 9c4cb0e509..dd98ef272e 100644 --- a/core/services/relay/evm/mercury/v4/reportcodec/report_codec.go +++ b/core/services/relay/evm/mercury/v4/reportcodec/report_codec.go @@ -35,12 +35,6 @@ func (r *ReportCodec) BuildReport(rf v4.ReportFields) (ocrtypes.Report, error) { if rf.BenchmarkPrice == nil { merr = errors.Join(merr, errors.New("benchmarkPrice may not be nil")) } - if rf.Bid == nil { - merr = errors.Join(merr, errors.New("bid may not be nil")) - } - if rf.Ask == nil { - merr = errors.Join(merr, errors.New("ask may not be nil")) - } if rf.LinkFee == nil { merr = errors.Join(merr, errors.New("linkFee may not be nil")) } else if rf.LinkFee.Cmp(zero) < 0 { @@ -54,7 +48,7 @@ func (r *ReportCodec) BuildReport(rf v4.ReportFields) (ocrtypes.Report, error) { if merr != nil { return nil, merr } - reportBytes, err := ReportTypes.Pack(r.feedID, rf.ValidFromTimestamp, rf.Timestamp, rf.NativeFee, rf.LinkFee, rf.ExpiresAt, rf.BenchmarkPrice, rf.Bid, rf.Ask, rf.MarketStatus) + reportBytes, err := ReportTypes.Pack(r.feedID, rf.ValidFromTimestamp, rf.Timestamp, rf.NativeFee, rf.LinkFee, rf.ExpiresAt, rf.BenchmarkPrice, rf.MarketStatus) return ocrtypes.Report(reportBytes), pkgerrors.Wrap(err, "failed to pack report blob") } diff --git a/core/services/relay/evm/mercury/v4/reportcodec/report_codec_test.go b/core/services/relay/evm/mercury/v4/reportcodec/report_codec_test.go index b62f42ef57..7be81bf279 100644 --- a/core/services/relay/evm/mercury/v4/reportcodec/report_codec_test.go +++ b/core/services/relay/evm/mercury/v4/reportcodec/report_codec_test.go @@ -15,8 +15,6 @@ func newValidReportFields() v4.ReportFields { return v4.ReportFields{ Timestamp: 242, BenchmarkPrice: big.NewInt(243), - Bid: big.NewInt(244), - Ask: big.NewInt(245), ValidFromTimestamp: 123, ExpiresAt: 20, LinkFee: big.NewInt(456), @@ -49,15 +47,13 @@ func Test_ReportCodec_BuildReport(t *testing.T) { assert.Equal(t, int(reportElems["observationsTimestamp"].(uint32)), 242) assert.Equal(t, reportElems["benchmarkPrice"].(*big.Int).Int64(), int64(243)) - assert.Equal(t, reportElems["bid"].(*big.Int).Int64(), int64(244)) - assert.Equal(t, reportElems["ask"].(*big.Int).Int64(), int64(245)) assert.Equal(t, reportElems["validFromTimestamp"].(uint32), uint32(123)) assert.Equal(t, reportElems["expiresAt"].(uint32), uint32(20)) assert.Equal(t, reportElems["linkFee"].(*big.Int).Int64(), int64(456)) assert.Equal(t, reportElems["nativeFee"].(*big.Int).Int64(), int64(457)) assert.Equal(t, reportElems["marketStatus"].(uint32), uint32(1)) - assert.Equal(t, types.Report{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, report) + assert.Equal(t, types.Report{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, report) max, err := r.MaxReportLength(4) require.NoError(t, err) assert.LessOrEqual(t, len(report), max) @@ -70,8 +66,6 @@ func Test_ReportCodec_BuildReport(t *testing.T) { assert.Equal(t, uint32(242), decoded.ObservationsTimestamp) assert.Equal(t, big.NewInt(243), decoded.BenchmarkPrice) - assert.Equal(t, big.NewInt(244), decoded.Bid) - assert.Equal(t, big.NewInt(245), decoded.Ask) assert.Equal(t, uint32(123), decoded.ValidFromTimestamp) assert.Equal(t, uint32(20), decoded.ExpiresAt) assert.Equal(t, big.NewInt(456), decoded.LinkFee) @@ -108,15 +102,13 @@ func buildSampleReport(ts int64) []byte { feedID := [32]byte{'f', 'o', 'o'} timestamp := uint32(ts) bp := big.NewInt(242) - bid := big.NewInt(243) - ask := big.NewInt(244) validFromTimestamp := uint32(123) expiresAt := uint32(456) linkFee := big.NewInt(3334455) nativeFee := big.NewInt(556677) marketStatus := uint32(1) - b, err := ReportTypes.Pack(feedID, validFromTimestamp, timestamp, nativeFee, linkFee, expiresAt, bp, bid, ask, marketStatus) + b, err := ReportTypes.Pack(feedID, validFromTimestamp, timestamp, nativeFee, linkFee, expiresAt, bp, marketStatus) if err != nil { panic(err) } diff --git a/core/services/relay/evm/mercury/v4/types/types.go b/core/services/relay/evm/mercury/v4/types/types.go index 3abdd262a6..584836c1e9 100644 --- a/core/services/relay/evm/mercury/v4/types/types.go +++ b/core/services/relay/evm/mercury/v4/types/types.go @@ -25,8 +25,6 @@ func GetSchema() abi.Arguments { {Name: "linkFee", Type: mustNewType("uint192")}, {Name: "expiresAt", Type: mustNewType("uint32")}, {Name: "benchmarkPrice", Type: mustNewType("int192")}, - {Name: "bid", Type: mustNewType("int192")}, - {Name: "ask", Type: mustNewType("int192")}, {Name: "marketStatus", Type: mustNewType("uint32")}, }) } @@ -35,8 +33,6 @@ type Report struct { FeedId [32]byte ObservationsTimestamp uint32 BenchmarkPrice *big.Int - Bid *big.Int - Ask *big.Int ValidFromTimestamp uint32 ExpiresAt uint32 LinkFee *big.Int diff --git a/core/services/synchronization/telem/telem.pb.go b/core/services/synchronization/telem/telem.pb.go index ec1ac5ee52..d51b9628e2 100644 --- a/core/services/synchronization/telem/telem.pb.go +++ b/core/services/synchronization/telem/telem.pb.go @@ -7,11 +7,10 @@ package telem import ( - reflect "reflect" - sync "sync" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) const ( diff --git a/core/services/synchronization/telem/telem_automation_custom.pb.go b/core/services/synchronization/telem/telem_automation_custom.pb.go index 118e76d680..30ddce6f79 100644 --- a/core/services/synchronization/telem/telem_automation_custom.pb.go +++ b/core/services/synchronization/telem/telem_automation_custom.pb.go @@ -7,11 +7,10 @@ package telem import ( - reflect "reflect" - sync "sync" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) const ( diff --git a/core/services/synchronization/telem/telem_enhanced_ea.pb.go b/core/services/synchronization/telem/telem_enhanced_ea.pb.go index c78cd65848..c8983a06fe 100644 --- a/core/services/synchronization/telem/telem_enhanced_ea.pb.go +++ b/core/services/synchronization/telem/telem_enhanced_ea.pb.go @@ -7,11 +7,10 @@ package telem import ( - reflect "reflect" - sync "sync" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) const ( diff --git a/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go b/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go index 325c6708f9..856619e193 100644 --- a/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go +++ b/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go @@ -7,11 +7,10 @@ package telem import ( - reflect "reflect" - sync "sync" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) const ( diff --git a/core/services/synchronization/telem/telem_functions_request.pb.go b/core/services/synchronization/telem/telem_functions_request.pb.go index 85cf6915d8..89aa9e3fe3 100644 --- a/core/services/synchronization/telem/telem_functions_request.pb.go +++ b/core/services/synchronization/telem/telem_functions_request.pb.go @@ -7,11 +7,10 @@ package telem import ( - reflect "reflect" - sync "sync" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) const ( diff --git a/core/services/synchronization/telem/telem_head_report.pb.go b/core/services/synchronization/telem/telem_head_report.pb.go index a53eb6ca1d..87fa42a57e 100644 --- a/core/services/synchronization/telem/telem_head_report.pb.go +++ b/core/services/synchronization/telem/telem_head_report.pb.go @@ -1,17 +1,16 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 +// protoc-gen-go v1.34.2 // protoc v4.25.1 // source: core/services/synchronization/telem/telem_head_report.proto package telem import ( - reflect "reflect" - sync "sync" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) const ( @@ -190,7 +189,7 @@ func file_core_services_synchronization_telem_telem_head_report_proto_rawDescGZI } var file_core_services_synchronization_telem_telem_head_report_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_core_services_synchronization_telem_telem_head_report_proto_goTypes = []interface{}{ +var file_core_services_synchronization_telem_telem_head_report_proto_goTypes = []any{ (*HeadReportRequest)(nil), // 0: telem.HeadReportRequest (*Block)(nil), // 1: telem.Block } @@ -210,7 +209,7 @@ func file_core_services_synchronization_telem_telem_head_report_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*HeadReportRequest); i { case 0: return &v.state @@ -222,7 +221,7 @@ func file_core_services_synchronization_telem_telem_head_report_proto_init() { return nil } } - file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*Block); i { case 0: return &v.state @@ -235,7 +234,7 @@ func file_core_services_synchronization_telem_telem_head_report_proto_init() { } } } - file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[0].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/core/services/synchronization/telem/telem_wsrpc.pb.go b/core/services/synchronization/telem/telem_wsrpc.pb.go index 344ace7169..e4028b4de4 100644 --- a/core/services/synchronization/telem/telem_wsrpc.pb.go +++ b/core/services/synchronization/telem/telem_wsrpc.pb.go @@ -7,7 +7,6 @@ package telem import ( context "context" - wsrpc "github.com/smartcontractkit/wsrpc" ) diff --git a/go.md b/go.md index 3f7549d6ea..b0128221ef 100644 --- a/go.md +++ b/go.md @@ -63,6 +63,7 @@ flowchart LR chainlink-cosmos --> libocr chainlink-data-streams --> chainlink-common chainlink-data-streams --> libocr + chainlink-data-streams --> grpc-proxy chainlink-feeds --> chainlink-common chainlink-feeds --> libocr chainlink-solana --> chainlink-common diff --git a/go.mod b/go.mod index 6d1af95e05..c48e24e0b7 100644 --- a/go.mod +++ b/go.mod @@ -75,9 +75,9 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 @@ -349,5 +349,10 @@ require ( sigs.k8s.io/yaml v1.4.0 // indirect ) -// replicating the replace directive on cosmos SDK -replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 +replace ( + // until merged upstream: https://github.com/omissis/go-jsonschema/pull/264 + github.com/atombender/go-jsonschema => github.com/nolag/go-jsonschema v0.16.0-rtinianov + + // replicating the replace directive on cosmos SDK + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 +) diff --git a/go.sum b/go.sum index 864a33678b..f4c6e50a7b 100644 --- a/go.sum +++ b/go.sum @@ -1147,12 +1147,12 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e h1:kxMSsv/RaTlH0Up9YTC6FE4K9n5QWcSKxbtiTS+JHzU= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index aa66fb3b02..c3b9d51542 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -37,7 +37,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 github.com/smartcontractkit/chainlink-testing-framework v1.35.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 @@ -404,7 +404,7 @@ require ( github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect @@ -513,6 +513,9 @@ require ( exclude github.com/chaos-mesh/chaos-mesh/api/v1alpha1 v0.0.0-20220226050744-799408773657 replace ( + // until merged upstream: https://github.com/omissis/go-jsonschema/pull/264 + github.com/atombender/go-jsonschema => github.com/nolag/go-jsonschema v0.16.0-rtinianov + github.com/go-kit/log => github.com/go-kit/log v0.2.1 // replicating the replace directive on cosmos SDK diff --git a/integration-tests/go.sum b/integration-tests/go.sum index b624ebeea0..daa3de116a 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1425,12 +1425,12 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e h1:kxMSsv/RaTlH0Up9YTC6FE4K9n5QWcSKxbtiTS+JHzU= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 8eda875851..1f1637bb99 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 github.com/smartcontractkit/chainlink-testing-framework v1.35.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 @@ -394,7 +394,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect @@ -510,6 +510,9 @@ require ( ) replace ( + // until merged upstream: https://github.com/omissis/go-jsonschema/pull/264 + github.com/atombender/go-jsonschema => github.com/nolag/go-jsonschema v0.16.0-rtinianov + github.com/go-kit/log => github.com/go-kit/log v0.2.1 // replicating the replace directive on cosmos SDK diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index b298e59726..da213f2b20 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1395,12 +1395,12 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e h1:kxMSsv/RaTlH0Up9YTC6FE4K9n5QWcSKxbtiTS+JHzU= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240830180817-6a0f3d1e0f9e/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2 h1:KH6tpCw5hu8u6UTtgll7a8mE4sIbHCbmtzHJdKuRwBw= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240820130645-cf4b159fbba2/go.mod h1:V/86loaFSH0dqqUEHqyXVbyNqDRSjvcf9BRomWFTljU= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= From 74fa74f8b08ab956596bb69afe2ecab0d335e56b Mon Sep 17 00:00:00 2001 From: momentmaker Date: Wed, 4 Sep 2024 09:55:52 -0500 Subject: [PATCH 283/432] add docker image and binary attestation and gen sboms (#14267) * add docker image and binary attestation and gen sboms * temp remove all other gha workflows for testing * temp comment out docker-build job * temp comment out check job * fix typo * fix getting the right docker image digest * fix docker image digest parse issue and output * add attestation to regular docker image build * get back deleted workflows * refactor --- .../goreleaser-build-sign-publish/action.yml | 2 + .../workflows/build-publish-develop-pr.yml | 3 +- .github/workflows/build-publish.yml | 83 ++++++- .goreleaser.production.yaml | 221 ++++++++++++++++++ 4 files changed, 301 insertions(+), 8 deletions(-) create mode 100644 .goreleaser.production.yaml diff --git a/.github/actions/goreleaser-build-sign-publish/action.yml b/.github/actions/goreleaser-build-sign-publish/action.yml index 69630e8e5f..0d4958387a 100644 --- a/.github/actions/goreleaser-build-sign-publish/action.yml +++ b/.github/actions/goreleaser-build-sign-publish/action.yml @@ -101,6 +101,8 @@ runs: run: | echo "GOOS=linux" | tee -a $GITHUB_ENV echo "GOARCH=${{ inputs.goreleaser-split-arch }}" | tee -a $GITHUB_ENV + - name: Install syft + uses: anchore/sbom-action/download-syft@61119d458adab75f756bc0b9e4bde25725f86a7a # v0.17.2 - name: Run goreleaser release shell: bash env: diff --git a/.github/workflows/build-publish-develop-pr.yml b/.github/workflows/build-publish-develop-pr.yml index 0b75b6c477..3a05078d3e 100644 --- a/.github/workflows/build-publish-develop-pr.yml +++ b/.github/workflows/build-publish-develop-pr.yml @@ -95,8 +95,7 @@ jobs: cat dist/linux_${{ matrix.goarch }}/artifacts.json fi echo "### Docker Images" | tee -a "$GITHUB_STEP_SUMMARY" - jq -r '.[] | select(.type == "Docker Image") | "`\(.goarch)-image`: \(.name)"' ${artifact_path} >> output.txt - jq -r '.[] | select(.type == "Archive") | "`\(.goarch)-digest`: \(.extra.Checksum)"' ${artifact_path} >> output.txt + jq -r '.[] | select(.type == "Docker Image") | "\(.name)"' ${artifact_path} >> output.txt while read -r line; do echo "$line" | tee -a "$GITHUB_STEP_SUMMARY" done < output.txt diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index fa01d27e7c..ba274730bf 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -33,7 +33,8 @@ jobs: environment: build-publish permissions: id-token: write - contents: read + contents: write + attestations: write outputs: docker-image-tag: ${{ steps.build-sign-publish.outputs.docker-image-tag }} docker-image-digest: ${{ steps.build-sign-publish.outputs.docker-image-digest }} @@ -56,6 +57,13 @@ jobs: sign-images: true verify-signature: true + - name: Attest Docker image + uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # v1.4.2 + with: + subject-digest: ${{ steps.build-sign-publish.outputs.docker-image-digest }} + subject-name: ${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }} + push-to-registry: true + - name: Collect Metrics if: always() id: collect-gha-metrics @@ -75,7 +83,8 @@ jobs: environment: build-publish permissions: id-token: write - contents: read + contents: write + attestations: write steps: - name: Checkout repository uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 @@ -97,23 +106,85 @@ jobs: docker-image-name: ${{ env.ECR_IMAGE_NAME }} docker-image-tag: ${{ github.ref_name }} goreleaser-exec: ./tools/bin/goreleaser_wrapper - goreleaser-config: .goreleaser.develop.yaml + goreleaser-config: .goreleaser.production.yaml goreleaser-key: ${{ secrets.GORELEASER_KEY }} zig-version: 0.11.0 enable-cosign: true cosign-version: "v2.4.0" - name: Output image name and digest - shell: sh + id: get-image-name-digest + shell: bash run: | artifact_path="dist/artifacts.json" + jq -r '.[] | select(.type == "Docker Image") | "\(.name)"' ${artifact_path} >> output.txt + echo "### Docker Images" | tee -a "$GITHUB_STEP_SUMMARY" - jq -r '.[] | select(.type == "Docker Image") | "`\(.goarch)-image`: \(.name)"' ${artifact_path} >> output.txt - jq -r '.[] | select(.type == "Archive") | "`\(.goarch)-digest`: \(.extra.Checksum)"' ${artifact_path} >> output.txt while read -r line; do echo "$line" | tee -a "$GITHUB_STEP_SUMMARY" done < output.txt + core_amd64_name="${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }}:${{ github.ref_name }}-amd64" + plugins_amd64_name="${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }}:${{ github.ref_name }}-plugins-amd64" + core_arm64_name="${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }}:${{ github.ref_name }}-arm64" + plugins_arm64_name="${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }}:${{ github.ref_name }}-plugins-arm64" + + echo "core_amd64_digest=$(jq -r --arg name "$core_amd64_name" '.[]|select(.type=="Published Docker Image" and .name==$name)|.extra.Digest' ${artifact_path})" | tee -a "$GITHUB_OUTPUT" "$GITHUB_STEP_SUMMARY" + echo "plugins_amd64_digest=$(jq -r --arg name "$plugins_amd64_name" '.[]|select(.type=="Published Docker Image" and .name==$name)|.extra.Digest' ${artifact_path})" | tee -a "$GITHUB_OUTPUT" "$GITHUB_STEP_SUMMARY" + echo "core_arm64_digest=$(jq -r --arg name "$core_amd64_name" '.[]|select(.type=="Published Docker Image" and .name==$name)|.extra.Digest' ${artifact_path})" | tee -a "$GITHUB_OUTPUT" "$GITHUB_STEP_SUMMARY" + echo "plugins_arm64_digest=$(jq -r --arg name "$plugins_amd64_name" '.[]|select(.type=="Published Docker Image" and .name==$name)|.extra.Digest' ${artifact_path})" | tee -a "$GITHUB_OUTPUT" "$GITHUB_STEP_SUMMARY" + + - name: Attest tarballs + uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # v1.4.2 + with: + subject-path: "dist/*.tar.gz" + + - name: Attest Docker image (core-amd64) + uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # v1.4.2 + with: + subject-digest: ${{ steps.get-image-name-digest.outputs.core_amd64_digest }} + subject-name: ${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }} + push-to-registry: true + + - name: Attest Docker image (plugins-amd64) + uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # v1.4.2 + with: + subject-digest: ${{ steps.get-image-name-digest.outputs.plugins_amd64_digest }} + subject-name: ${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }} + push-to-registry: true + + - name: Attest Docker image (core-arm64) + uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # v1.4.2 + with: + subject-digest: ${{ steps.get-image-name-digest.outputs.core_arm64_digest }} + subject-name: ${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }} + push-to-registry: true + + - name: Attest Docker image (plugins-arm64) + uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # v1.4.2 + with: + subject-digest: ${{ steps.get-image-name-digest.outputs.plugins_arm64_digest }} + subject-name: ${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }} + push-to-registry: true + + - name: Upload SBOMs + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + with: + name: goreleaser-sboms + path: dist/*.sbom.json + + - name: Print SBOM artifact to job summary + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + shell: bash + run: | + ARTIFACTS=$(gh api -X GET repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts) + ARTIFACT_ID=$(echo "$ARTIFACTS" | jq '.artifacts[] | select(.name=="goreleaser-sboms") | .id') + echo "Artifact ID: $ARTIFACT_ID" + echo "### SBOM Artifact" | tee -a "$GITHUB_STEP_SUMMARY" + artifact_url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/$ARTIFACT_ID" + echo "[Artifact URL]($artifact_url)" | tee -a $GITHUB_STEP_SUMMARY + - name: Collect Metrics if: always() id: collect-gha-metrics diff --git a/.goreleaser.production.yaml b/.goreleaser.production.yaml new file mode 100644 index 0000000000..0274f1322b --- /dev/null +++ b/.goreleaser.production.yaml @@ -0,0 +1,221 @@ +project_name: chainlink + +version: 2 + +env: + - ZIG_EXEC={{ if index .Env "ZIG_EXEC" }}{{ .Env.ZIG_EXEC }}{{ else }}zig{{ end }} + - IMAGE_PREFIX={{ if index .Env "IMAGE_PREFIX" }}{{ .Env.IMAGE_PREFIX }}{{ else }}localhost:5001{{ end }} + - IMAGE_NAME={{ if index .Env "IMAGE_NAME" }}{{ .Env.IMAGE_NAME }}{{ else }}chainlink{{ end }} + - IMAGE_TAG={{ if index .Env "IMAGE_TAG" }}{{ .Env.IMAGE_TAG }}{{ else }}develop{{ end }} + - IMAGE_LABEL_DESCRIPTION="node of the decentralized oracle network, bridging on and off-chain computation" + - IMAGE_LABEL_LICENSES="MIT" + - IMAGE_LABEL_SOURCE="https://github.com/smartcontractkit/{{ .ProjectName }}" + +before: + hooks: + - go mod tidy + - ./tools/bin/goreleaser_utils before_hook + +# See https://goreleaser.com/customization/build/ +builds: + - binary: chainlink + id: linux-arm64 + goos: + - linux + goarch: + - arm64 + hooks: + post: ./tools/bin/goreleaser_utils build_post_hook {{ dir .Path }} {{ .Os }} {{ .Arch }} + env: + - CGO_ENABLED=1 + - CC=$ZIG_EXEC cc -target aarch64-linux-gnu + - CCX=$ZIG_EXEC c++ -target aarch64-linux-gnu + flags: + - -trimpath + - -buildmode=pie + ldflags: + - -s -w -r=$ORIGIN/libs + - -X github.com/smartcontractkit/chainlink/v2/core/static.Version={{ .Env.CHAINLINK_VERSION }} + - -X github.com/smartcontractkit/chainlink/v2/core/static.Sha={{ .FullCommit }} + - binary: chainlink + id: linux-amd64 + goos: + - linux + goarch: + - amd64 + hooks: + post: ./tools/bin/goreleaser_utils build_post_hook {{ dir .Path }} {{ .Os }} {{ .Arch }} + env: + - CGO_ENABLED=1 + - CC=$ZIG_EXEC cc -target x86_64-linux-gnu + - CCX=$ZIG_EXEC c++ -target x86_64-linux-gnu + flags: + - -trimpath + - -buildmode=pie + ldflags: + - -s -w -r=$ORIGIN/libs + - -X github.com/smartcontractkit/chainlink/v2/core/static.Version={{ .Env.CHAINLINK_VERSION }} + - -X github.com/smartcontractkit/chainlink/v2/core/static.Sha={{ .FullCommit }} + +# See https://goreleaser.com/customization/docker/ +dockers: + - id: linux-amd64 + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: amd64 + extra_files: + - tmp/linux_amd64/libs + - tools/bin/ldd_fix + build_flag_templates: + - "--platform=linux/amd64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-amd64" + - id: linux-arm64 + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: arm64 + extra_files: + - tmp/linux_arm64/libs + - tools/bin/ldd_fix + build_flag_templates: + - "--platform=linux/arm64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-arm64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-arm64" + - id: linux-amd64-plugins + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: amd64 + extra_files: + - tmp/linux_amd64/libs + - tmp/linux_amd64/plugins + - tools/bin/ldd_fix + build_flag_templates: + - "--platform=linux/amd64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--build-arg=CL_MEDIAN_CMD=chainlink-feeds" + - "--build-arg=CL_MERCURY_CMD=chainlink-mercury" + - "--build-arg=CL_SOLANA_CMD=chainlink-solana" + - "--build-arg=CL_STARKNET_CMD=chainlink-starknet" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-amd64" + - id: linux-arm64-plugins + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: arm64 + extra_files: + - tmp/linux_arm64/libs + - tmp/linux_arm64/plugins + - tools/bin/ldd_fix + build_flag_templates: + - "--platform=linux/arm64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--build-arg=CL_MEDIAN_CMD=chainlink-feeds" + - "--build-arg=CL_MERCURY_CMD=chainlink-mercury" + - "--build-arg=CL_SOLANA_CMD=chainlink-solana" + - "--build-arg=CL_STARKNET_CMD=chainlink-starknet" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-arm64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-arm64" + +# See https://goreleaser.com/customization/docker_manifest/ +docker_manifests: + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-arm64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-arm64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-arm64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-arm64" + +# See https://goreleaser.com/customization/docker_sign/ +docker_signs: + - artifacts: all + args: + - "sign" + - "${artifact}" + - "--yes" + +checksum: + name_template: "checksums.txt" + +# See https://goreleaser.com/customization/sbom +sboms: + - artifacts: archive + +snapshot: + version_template: "{{ .Env.CHAINLINK_VERSION }}-{{ .ShortCommit }}" + +partial: + by: target + +# See https://goreleaser.com/customization/release/ +release: + disable: true + +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" +# modelines, feel free to remove those if you don't want/use them: +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj From 0befa701d3869e834f5be6303b70764b5a46e8fa Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 4 Sep 2024 16:59:38 +0200 Subject: [PATCH 284/432] golangci-lint: fix some issues (#14322) --- .../capabilities/targets/write_target_test.go | 1 + core/chains/evm/client/rpc_client_test.go | 1 - core/chains/evm/gas/helpers_test.go | 2 +- core/internal/cltest/cltest.go | 7 +++++- core/services/feeds/orm.go | 3 ++- core/services/feeds/service_test.go | 1 + core/services/llo/data_source.go | 2 +- .../llo/evm/report_codec_premium_legacy.go | 5 +--- .../llo/onchain_channel_definition_cache.go | 3 +-- .../onchain_channel_definition_cache_test.go | 15 +++++++++--- .../ocr2/plugins/ccip/exportinternal.go | 2 +- .../ocr2/plugins/llo/integration_test.go | 3 +-- core/services/relay/evm/evm.go | 23 ++++++++++++------- .../evm/mercury/verifier/verifier_test.go | 4 ++-- core/services/versioning/orm_test.go | 1 - 15 files changed, 45 insertions(+), 28 deletions(-) diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go index 9f7b6a2de2..7f589e335d 100644 --- a/core/capabilities/targets/write_target_test.go +++ b/core/capabilities/targets/write_target_test.go @@ -154,6 +154,7 @@ func TestWriteTarget(t *testing.T) { configGasLimit, err = values.NewMap(map[string]any{ "Address": forwarderAddr, }) + require.NoError(t, err) req = capabilities.CapabilityRequest{ Metadata: validMetadata, Config: configGasLimit, diff --git a/core/chains/evm/client/rpc_client_test.go b/core/chains/evm/client/rpc_client_test.go index eafbea5cd5..07e097727a 100644 --- a/core/chains/evm/client/rpc_client_test.go +++ b/core/chains/evm/client/rpc_client_test.go @@ -156,7 +156,6 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { }() wg.Wait() } - }) t.Run("Block's chain ID matched configured", func(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) diff --git a/core/chains/evm/gas/helpers_test.go b/core/chains/evm/gas/helpers_test.go index ae93d9e8c7..0c9a74a18d 100644 --- a/core/chains/evm/gas/helpers_test.go +++ b/core/chains/evm/gas/helpers_test.go @@ -157,7 +157,7 @@ type MockGasEstimatorConfig struct { FeeCapDefaultF *assets.Wei LimitMaxF uint64 ModeF string - EstimateLimitF bool + EstimateLimitF bool } func NewMockGasConfig() *MockGasEstimatorConfig { diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 371cada330..23469cbb80 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -212,7 +212,12 @@ type TestApplication struct { func NewApplicationEVMDisabled(t *testing.T) *TestApplication { t.Helper() - c := configtest.NewGeneralConfig(t, nil) + c := configtest.NewGeneralConfig(t, func(config *chainlink.Config, secrets *chainlink.Secrets) { + f := false + for _, c := range config.EVM { + c.Enabled = &f + } + }) return NewApplicationWithConfig(t, c) } diff --git a/core/services/feeds/orm.go b/core/services/feeds/orm.go index a49882ccf5..82d1114a23 100644 --- a/core/services/feeds/orm.go +++ b/core/services/feeds/orm.go @@ -9,9 +9,10 @@ import ( "github.com/google/uuid" "github.com/lib/pq" "github.com/pkg/errors" - "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + + "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" ) type ORM interface { diff --git a/core/services/feeds/service_test.go b/core/services/feeds/service_test.go index 1dc9904fd5..9098d439eb 100644 --- a/core/services/feeds/service_test.go +++ b/core/services/feeds/service_test.go @@ -374,6 +374,7 @@ func Test_Service_RegisterManager_DuplicateFeedsManager(t *testing.T) { var pubKeyHex = "0f17c3bf72de8beef6e2d17a14c0a972f5d7e0e66e70722373f12b88382d40f9" var pubKey crypto.PublicKey _, err := hex.Decode([]byte(pubKeyHex), pubKey) + require.NoError(t, err) var ( mgr = feeds.FeedsManager{ diff --git a/core/services/llo/data_source.go b/core/services/llo/data_source.go index 4f6e91675c..3d265de261 100644 --- a/core/services/llo/data_source.go +++ b/core/services/llo/data_source.go @@ -149,7 +149,7 @@ func (d *dataSource) Observe(ctx context.Context, streamValues llo.StreamValues, if opts.VerboseLogging() { successes := make([]streams.StreamID, 0, len(streamValues)) - for strmID, _ := range streamValues { + for strmID := range streamValues { successes = append(successes, strmID) } sort.Slice(successes, func(i, j int) bool { return successes[i] < successes[j] }) diff --git a/core/services/llo/evm/report_codec_premium_legacy.go b/core/services/llo/evm/report_codec_premium_legacy.go index a062f77b65..da14aceab6 100644 --- a/core/services/llo/evm/report_codec_premium_legacy.go +++ b/core/services/llo/evm/report_codec_premium_legacy.go @@ -51,10 +51,7 @@ func (r *ReportFormatEVMPremiumLegacyOpts) Decode(opts []byte) error { // special case if opts are unspecified, just use the zero options rather than erroring return nil } - if err := json.Unmarshal(opts, r); err != nil { - return err - } - return nil + return json.Unmarshal(opts, r) } func (r ReportCodecPremiumLegacy) Encode(report llo.Report, cd llotypes.ChannelDefinition) ([]byte, error) { diff --git a/core/services/llo/onchain_channel_definition_cache.go b/core/services/llo/onchain_channel_definition_cache.go index 51cfae964d..752dc3196e 100644 --- a/core/services/llo/onchain_channel_definition_cache.go +++ b/core/services/llo/onchain_channel_definition_cache.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "maps" "math/big" "net/http" @@ -385,7 +384,7 @@ func (c *channelDefinitionCache) fetchChannelDefinitions(ctx context.Context, ur // logs with potentially huge messages body := http.MaxBytesReader(nil, reader, 1024) defer body.Close() - bodyBytes, err := ioutil.ReadAll(body) + bodyBytes, err := io.ReadAll(body) if err != nil { return nil, fmt.Errorf("got error from %s: (status code: %d, error reading response body: %w, response body: %s)", url, statusCode, err, bodyBytes) } diff --git a/core/services/llo/onchain_channel_definition_cache_test.go b/core/services/llo/onchain_channel_definition_cache_test.go index 5bd7eedbb1..d2b976ddde 100644 --- a/core/services/llo/onchain_channel_definition_cache_test.go +++ b/core/services/llo/onchain_channel_definition_cache_test.go @@ -96,7 +96,6 @@ func makeDonIDTopic(donID uint32) []byte { func Test_ChannelDefinitionCache(t *testing.T) { donID := rand.Uint32() - ctx := tests.Context(t) t.Run("Definitions", func(t *testing.T) { // NOTE: this is covered more thoroughly in the integration tests @@ -277,11 +276,12 @@ func Test_ChannelDefinitionCache(t *testing.T) { } t.Run("nil ctx returns error", func(t *testing.T) { - _, err := cdc.fetchChannelDefinitions(nil, "notvalid://foos", [32]byte{}) + _, err := cdc.fetchChannelDefinitions(nil, "notvalid://foos", [32]byte{}) //nolint assert.EqualError(t, err, "failed to create http.Request; net/http: nil Context") }) t.Run("networking error while making request returns error", func(t *testing.T) { + ctx := tests.Context(t) c.resp = nil c.err = errors.New("http request failed") @@ -290,6 +290,7 @@ func Test_ChannelDefinitionCache(t *testing.T) { }) t.Run("server returns 500 returns error", func(t *testing.T) { + ctx := tests.Context(t) c.err = nil c.resp = &http.Response{StatusCode: 500, Body: io.NopCloser(bytes.NewReader([]byte{1, 2, 3}))} @@ -303,6 +304,7 @@ func Test_ChannelDefinitionCache(t *testing.T) { } t.Run("server returns 404 returns error (and does not log entirety of huge response body)", func(t *testing.T) { + ctx := tests.Context(t) c.err = nil c.resp = &http.Response{StatusCode: 404, Body: io.NopCloser(bytes.NewReader(largeBody))} @@ -314,6 +316,7 @@ func Test_ChannelDefinitionCache(t *testing.T) { c.resp.Body = io.NopCloser(bytes.NewReader(hugeBody)) t.Run("server returns body that is too large", func(t *testing.T) { + ctx := tests.Context(t) c.err = nil c.resp = &http.Response{StatusCode: 200, Body: io.NopCloser(bytes.NewReader(hugeBody))} @@ -322,6 +325,7 @@ func Test_ChannelDefinitionCache(t *testing.T) { }) t.Run("server returns invalid JSON returns error", func(t *testing.T) { + ctx := tests.Context(t) c.err = nil c.resp = &http.Response{StatusCode: 200, Body: io.NopCloser(bytes.NewReader([]byte{1, 2, 3}))} @@ -330,6 +334,7 @@ func Test_ChannelDefinitionCache(t *testing.T) { }) t.Run("SHA mismatch returns error", func(t *testing.T) { + ctx := tests.Context(t) c.err = nil c.resp = &http.Response{StatusCode: 200, Body: io.NopCloser(bytes.NewReader([]byte(`{"foo":"bar"}`)))} @@ -338,6 +343,7 @@ func Test_ChannelDefinitionCache(t *testing.T) { }) t.Run("valid JSON matching SHA returns channel definitions", func(t *testing.T) { + ctx := tests.Context(t) chainSelector := 4949039107694359620 // arbitrum mainnet feedID := [32]byte{00, 03, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} expirationWindow := 3600 @@ -363,7 +369,7 @@ func Test_ChannelDefinitionCache(t *testing.T) { cd, err := cdc.fetchChannelDefinitions(ctx, "http://example.com/definitions.json", common.HexToHash("0x367bbc75f7b6c9fc66a98ea99f837ea7ac4a3c2d6a9ee284de018bd02c41b52d")) assert.NoError(t, err) - assert.Equal(t, llotypes.ChannelDefinitions(llotypes.ChannelDefinitions{0x2a: llotypes.ChannelDefinition{ReportFormat: 0x1, Streams: []llotypes.Stream{llotypes.Stream{StreamID: 0x34, Aggregator: 0x1}, llotypes.Stream{StreamID: 0x35, Aggregator: 0x1}, llotypes.Stream{StreamID: 0x37, Aggregator: 0x3}}, Opts: llotypes.ChannelOpts{0x7b, 0x22, 0x62, 0x61, 0x73, 0x65, 0x55, 0x53, 0x44, 0x46, 0x65, 0x65, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x22, 0x2c, 0x22, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 0x3a, 0x33, 0x36, 0x30, 0x30, 0x2c, 0x22, 0x66, 0x65, 0x65, 0x64, 0x49, 0x64, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x30, 0x30, 0x33, 0x36, 0x62, 0x34, 0x61, 0x61, 0x37, 0x65, 0x35, 0x37, 0x63, 0x61, 0x37, 0x62, 0x36, 0x38, 0x61, 0x65, 0x31, 0x62, 0x66, 0x34, 0x35, 0x36, 0x35, 0x33, 0x66, 0x35, 0x36, 0x62, 0x36, 0x35, 0x36, 0x66, 0x64, 0x33, 0x61, 0x61, 0x33, 0x33, 0x35, 0x65, 0x66, 0x37, 0x66, 0x61, 0x65, 0x36, 0x39, 0x36, 0x62, 0x36, 0x36, 0x33, 0x66, 0x31, 0x62, 0x38, 0x34, 0x37, 0x32, 0x22, 0x2c, 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x7d}}}), cd) + assert.Equal(t, llotypes.ChannelDefinitions{0x2a: llotypes.ChannelDefinition{ReportFormat: 0x1, Streams: []llotypes.Stream{llotypes.Stream{StreamID: 0x34, Aggregator: 0x1}, llotypes.Stream{StreamID: 0x35, Aggregator: 0x1}, llotypes.Stream{StreamID: 0x37, Aggregator: 0x3}}, Opts: llotypes.ChannelOpts{0x7b, 0x22, 0x62, 0x61, 0x73, 0x65, 0x55, 0x53, 0x44, 0x46, 0x65, 0x65, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x22, 0x2c, 0x22, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 0x3a, 0x33, 0x36, 0x30, 0x30, 0x2c, 0x22, 0x66, 0x65, 0x65, 0x64, 0x49, 0x64, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x30, 0x30, 0x33, 0x36, 0x62, 0x34, 0x61, 0x61, 0x37, 0x65, 0x35, 0x37, 0x63, 0x61, 0x37, 0x62, 0x36, 0x38, 0x61, 0x65, 0x31, 0x62, 0x66, 0x34, 0x35, 0x36, 0x35, 0x33, 0x66, 0x35, 0x36, 0x62, 0x36, 0x35, 0x36, 0x66, 0x64, 0x33, 0x61, 0x61, 0x33, 0x33, 0x35, 0x65, 0x66, 0x37, 0x66, 0x61, 0x65, 0x36, 0x39, 0x36, 0x62, 0x36, 0x36, 0x33, 0x66, 0x31, 0x62, 0x38, 0x34, 0x37, 0x32, 0x22, 0x2c, 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x7d}}}, cd) }) }) @@ -384,6 +390,7 @@ func Test_ChannelDefinitionCache(t *testing.T) { } t.Run("does nothing if persisted version is up-to-date", func(t *testing.T) { + ctx := tests.Context(t) cdc.definitionsVersion = 42 cdc.persistedVersion = 42 @@ -398,6 +405,7 @@ func Test_ChannelDefinitionCache(t *testing.T) { cdc.orm = orm t.Run("returns error on db failure and does not update persisted version", func(t *testing.T) { + ctx := tests.Context(t) cdc.persistedVersion = 42 cdc.definitionsVersion = 43 orm.err = errors.New("test error") @@ -410,6 +418,7 @@ func Test_ChannelDefinitionCache(t *testing.T) { }) t.Run("updates persisted version on success", func(t *testing.T) { + ctx := tests.Context(t) cdc.definitionsVersion = 43 orm.err = nil diff --git a/core/services/ocr2/plugins/ccip/exportinternal.go b/core/services/ocr2/plugins/ccip/exportinternal.go index e6c41a28b2..aecf1a0b16 100644 --- a/core/services/ocr2/plugins/ccip/exportinternal.go +++ b/core/services/ocr2/plugins/ccip/exportinternal.go @@ -6,8 +6,8 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" diff --git a/core/services/ocr2/plugins/llo/integration_test.go b/core/services/ocr2/plugins/llo/integration_test.go index 4cebe3bf22..f5c2869442 100644 --- a/core/services/ocr2/plugins/llo/integration_test.go +++ b/core/services/ocr2/plugins/llo/integration_test.go @@ -43,7 +43,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" lloevm "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" - mercury "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" reportcodecv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" mercuryverifier "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/verifier" ) @@ -428,7 +428,6 @@ channelDefinitionsContractFromBlock = %d`, serverURL, donID, serverPubKey, confi t.Run(fmt.Sprintf("test on-chain verification - node %x", req.pk), func(t *testing.T) { _, err = verifierProxy.Verify(steve, req.req.Payload, []byte{}) require.NoError(t, err) - }) t.Logf("oracle %x reported for 0x%x", req.pk, feedID) diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 5156f98185..f2b4cbc7a9 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -10,6 +10,7 @@ import ( "math/big" "net/http" "strings" + "sync" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -144,8 +145,7 @@ type Relayer struct { triggerCapability *triggers.MercuryTriggerService // LLO/data streams - cdcFactory llo.ChannelDefinitionCacheFactory - lloORM llo.ORM + cdcFactory func() (llo.ChannelDefinitionCacheFactory, error) } type CSAETHKeystore interface { @@ -185,11 +185,15 @@ func NewRelayer(lggr logger.Logger, chain legacyevm.Chain, opts RelayerOpts) (*R return nil, fmt.Errorf("cannot create evm relayer: %w", err) } sugared := logger.Sugared(lggr).Named("Relayer") - mercuryORM := mercury.NewORM(opts.DS) - chainSelector, err := chainselectors.SelectorFromChainId(chain.ID().Uint64()) - lloORM := llo.NewORM(opts.DS, chainSelector) - cdcFactory := llo.NewChannelDefinitionCacheFactory(sugared, lloORM, chain.LogPoller(), opts.HTTPClient) + cdcFactory := sync.OnceValues(func() (llo.ChannelDefinitionCacheFactory, error) { + chainSelector, err := chainselectors.SelectorFromChainId(chain.ID().Uint64()) + if err != nil { + return nil, fmt.Errorf("failed to get chain selector for chain id %s: %w", chain.ID(), err) + } + lloORM := llo.NewORM(opts.DS, chainSelector) + return llo.NewChannelDefinitionCacheFactory(sugared, lloORM, chain.LogPoller(), opts.HTTPClient), nil + }) relayer := &Relayer{ ds: opts.DS, chain: chain, @@ -197,7 +201,6 @@ func NewRelayer(lggr logger.Logger, chain legacyevm.Chain, opts RelayerOpts) (*R ks: opts.CSAETHKeystore, mercuryPool: opts.MercuryPool, cdcFactory: cdcFactory, - lloORM: lloORM, mercuryORM: mercuryORM, transmitterCfg: opts.TransmitterConfig, capabilitiesRegistry: opts.CapabilitiesRegistry, @@ -446,7 +449,11 @@ func (r *Relayer) NewLLOProvider(rargs commontypes.RelayArgs, pargs commontypes. transmitter = llo.NewTransmitter(r.lggr, client, privKey.PublicKey) } - cdc, err := r.cdcFactory.NewCache(lloCfg) + cdcFactory, err := r.cdcFactory() + if err != nil { + return nil, err + } + cdc, err := cdcFactory.NewCache(lloCfg) if err != nil { return nil, err } diff --git a/core/services/relay/evm/mercury/verifier/verifier_test.go b/core/services/relay/evm/mercury/verifier/verifier_test.go index 4cc9dcc9bf..abe891b583 100644 --- a/core/services/relay/evm/mercury/verifier/verifier_test.go +++ b/core/services/relay/evm/mercury/verifier/verifier_test.go @@ -5,8 +5,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/test-go/testify/assert" - "github.com/test-go/testify/require" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" ) diff --git a/core/services/versioning/orm_test.go b/core/services/versioning/orm_test.go index e2f05e3903..44c63f60d0 100644 --- a/core/services/versioning/orm_test.go +++ b/core/services/versioning/orm_test.go @@ -174,7 +174,6 @@ func TestORM_CheckVersion_CCIP(t *testing.T) { require.NoError(t, err) } }) - } } From b71e692e7ba8523ec57ea5e10c5d9c6810e038e5 Mon Sep 17 00:00:00 2001 From: ferglor Date: Wed, 4 Sep 2024 16:08:11 +0100 Subject: [PATCH 285/432] Automation - Lock reads and writes from and to the ConfigDigest (#14313) * Lock reads and writes from and to the ConfigDigest * Add a changeset * Update core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/autotelemetry21/custom_telemetry.go Co-authored-by: Jordan Krage * Lock the config digest check --------- Co-authored-by: Jordan Krage --- .changeset/curvy-months-wave.md | 5 +++++ .../v21/autotelemetry21/custom_telemetry.go | 21 +++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 .changeset/curvy-months-wave.md diff --git a/.changeset/curvy-months-wave.md b/.changeset/curvy-months-wave.md new file mode 100644 index 0000000000..9e2552fed5 --- /dev/null +++ b/.changeset/curvy-months-wave.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Use a lock to sync access to the ConfigDigest #internal diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/autotelemetry21/custom_telemetry.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/autotelemetry21/custom_telemetry.go index 53303553db..2c997a2d38 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/autotelemetry21/custom_telemetry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/autotelemetry21/custom_telemetry.go @@ -3,6 +3,7 @@ package autotelemetry21 import ( "context" "encoding/hex" + "sync" "time" "google.golang.org/protobuf/proto" @@ -29,6 +30,7 @@ type AutomationCustomTelemetryService struct { lggr logger.Logger configDigest [32]byte contractConfigTracker types.ContractConfigTracker + mu sync.RWMutex } // NewAutomationCustomTelemetryService creates a telemetry service for new blocks and node version @@ -66,8 +68,15 @@ func (e *AutomationCustomTelemetryService) Start(ctx context.Context) error { if err != nil { e.lggr.Errorf("Error occurred while getting newestConfigDetails in configDigest loop %s", err) } + configChanged := false + e.mu.Lock() if newConfigDigest != e.configDigest { e.configDigest = newConfigDigest + configChanged = true + } + e.mu.Unlock() + + if configChanged { e.sendNodeVersionMsg() } case <-hourTicker.C: @@ -121,10 +130,14 @@ func (e *AutomationCustomTelemetryService) Close() error { } func (e *AutomationCustomTelemetryService) sendNodeVersionMsg() { + e.mu.RLock() + configDigest := e.configDigest + e.mu.RUnlock() + vMsg := &telem.NodeVersion{ Timestamp: uint64(time.Now().UTC().UnixMilli()), NodeVersion: static.Version, - ConfigDigest: e.configDigest[:], + ConfigDigest: configDigest[:], } wrappedVMsg := &telem.AutomationTelemWrapper{ Msg: &telem.AutomationTelemWrapper_NodeVersion{ @@ -141,11 +154,15 @@ func (e *AutomationCustomTelemetryService) sendNodeVersionMsg() { } func (e *AutomationCustomTelemetryService) sendBlockNumberMsg(blockKey ocr2keepers.BlockKey) { + e.mu.RLock() + configDigest := e.configDigest + e.mu.RUnlock() + blockNumMsg := &telem.BlockNumber{ Timestamp: uint64(time.Now().UTC().UnixMilli()), BlockNumber: uint64(blockKey.Number), BlockHash: hex.EncodeToString(blockKey.Hash[:]), - ConfigDigest: e.configDigest[:], + ConfigDigest: configDigest[:], } wrappedBlockNumMsg := &telem.AutomationTelemWrapper{ Msg: &telem.AutomationTelemWrapper_BlockNumber{ From 544ded0afa685de146da215a949ad08b3667bb99 Mon Sep 17 00:00:00 2001 From: Will Winder Date: Wed, 4 Sep 2024 12:09:41 -0400 Subject: [PATCH 286/432] [CCIP-3087] Set nonce manager config for chain reader. Tests. (#14318) * Set nonce manager config for chain reader. Tests. Update chainlink-ccip. Add changeset file. * Update core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go --- .changeset/sharp-pianos-watch.md | 5 ++ .../ccip/test/helpers/CCIPReaderTester.sol | 13 ++++ .../ccipreader/ccipreader_test.go | 59 +++++++++++++++++++ .../ccip/configs/evm/contract_reader.go | 33 +++++++---- .../ccip_reader_tester/ccip_reader_tester.go | 42 ++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 14 files changed, 153 insertions(+), 25 deletions(-) create mode 100644 .changeset/sharp-pianos-watch.md diff --git a/.changeset/sharp-pianos-watch.md b/.changeset/sharp-pianos-watch.md new file mode 100644 index 0000000000..4b60371b4b --- /dev/null +++ b/.changeset/sharp-pianos-watch.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal ccip reader nonces work. diff --git a/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol b/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol index c2acddc796..cebff11fcb 100644 --- a/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol +++ b/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol @@ -9,6 +9,7 @@ contract CCIPReaderTester { mapping(uint64 sourceChainSelector => OffRamp.SourceChainConfig sourceChainConfig) internal s_sourceChainConfigs; mapping(uint64 destChainSelector => uint64 sequenceNumber) internal s_destChainSeqNrs; + mapping(uint64 sourceChainSelector => mapping(bytes sender => uint64 nonce)) internal s_senderNonce; /// @notice Gets the next sequence number to be used in the onRamp /// @param destChainSelector The destination chain selector @@ -24,6 +25,18 @@ contract CCIPReaderTester { s_destChainSeqNrs[destChainSelector] = sequenceNumber; } + /// @notice Returns the inbound nonce for a given sender on a given source chain. + /// @param sourceChainSelector The source chain selector. + /// @param sender The encoded sender address. + /// @return inboundNonce The inbound nonce. + function getInboundNonce(uint64 sourceChainSelector, bytes calldata sender) external view returns (uint64) { + return s_senderNonce[sourceChainSelector][sender]; + } + + function setInboundNonce(uint64 sourceChainSelector, uint64 testNonce, bytes calldata sender) external { + s_senderNonce[sourceChainSelector][sender] = testNonce; + } + function getSourceChainConfig(uint64 sourceChainSelector) external view returns (OffRamp.SourceChainConfig memory) { return s_sourceChainConfigs[sourceChainSelector]; } diff --git a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go index 05a91eb289..6d75fd22ff 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go @@ -353,6 +353,65 @@ func TestCCIPReader_GetExpectedNextSequenceNumber(t *testing.T) { require.Equal(t, cciptypes.SeqNum(25)+1, seqNum) } +func TestCCIPReader_Nonces(t *testing.T) { + ctx := testutils.Context(t) + var nonces = map[cciptypes.ChainSelector]map[common.Address]uint64{ + chainS1: { + utils.RandomAddress(): 10, + utils.RandomAddress(): 20, + }, + chainS2: { + utils.RandomAddress(): 30, + utils.RandomAddress(): 40, + }, + chainS3: { + utils.RandomAddress(): 50, + utils.RandomAddress(): 60, + }, + } + + cfg := evmtypes.ChainReaderConfig{ + Contracts: map[string]evmtypes.ChainContractReader{ + consts.ContractNameNonceManager: { + ContractABI: ccip_reader_tester.CCIPReaderTesterABI, + Configs: map[string]*evmtypes.ChainReaderDefinition{ + consts.MethodNameGetInboundNonce: { + ChainSpecificName: "getInboundNonce", + ReadType: evmtypes.Method, + }, + }, + }, + }, + } + + s := testSetup(ctx, t, chainD, chainD, nil, cfg) + + // Add some nonces. + for chain, addrs := range nonces { + for addr, nonce := range addrs { + _, err := s.contract.SetInboundNonce(s.auth, uint64(chain), nonce, addr.Bytes()) + assert.NoError(t, err) + } + } + s.sb.Commit() + + for sourceChain, addrs := range nonces { + + var addrQuery []string + for addr := range addrs { + addrQuery = append(addrQuery, addr.String()) + } + addrQuery = append(addrQuery, utils.RandomAddress().String()) + + results, err := s.reader.Nonces(ctx, sourceChain, chainD, addrQuery) + assert.NoError(t, err) + assert.Len(t, results, len(addrQuery)) + for addr, nonce := range addrs { + assert.Equal(t, nonce, results[addr.String()]) + } + } +} + func testSetup(ctx context.Context, t *testing.T, readerChain, destChain cciptypes.ChainSelector, onChainSeqNums map[cciptypes.ChainSelector]cciptypes.SeqNum, cfg evmtypes.ChainReaderConfig) *testSetupData { const chainID = 1337 diff --git a/core/capabilities/ccip/configs/evm/contract_reader.go b/core/capabilities/ccip/configs/evm/contract_reader.go index cd89e96337..cb19ede0e8 100644 --- a/core/capabilities/ccip/configs/evm/contract_reader.go +++ b/core/capabilities/ccip/configs/evm/contract_reader.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/smartcontractkit/chainlink-ccip/pkg/consts" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -22,6 +23,7 @@ var ( capabilitiesRegsitryABI = evmtypes.MustGetABI(kcr.CapabilitiesRegistryABI) ccipConfigABI = evmtypes.MustGetABI(ccip_config.CCIPConfigABI) priceRegistryABI = evmtypes.MustGetABI(fee_quoter.FeeQuoterABI) + nonceManagerABI = evmtypes.MustGetABI(nonce_manager.NonceManagerABI) ) // MustSourceReaderConfig returns a ChainReaderConfig that can be used to read from the onramp. @@ -98,6 +100,19 @@ var DestReaderConfig = evmrelaytypes.ChainReaderConfig{ }, }, }, + consts.ContractNameNonceManager: { + ContractABI: nonce_manager.NonceManagerABI, + Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ + consts.MethodNameGetInboundNonce: { + ChainSpecificName: mustGetMethodName("getInboundNonce", nonceManagerABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameGetOutboundNonce: { + ChainSpecificName: mustGetMethodName("getOutboundNonce", nonceManagerABI), + ReadType: evmrelaytypes.Method, + }, + }, + }, }, } @@ -140,37 +155,35 @@ var SourceReaderConfig = evmrelaytypes.ChainReaderConfig{ consts.ContractNamePriceRegistry: { ContractABI: fee_quoter.FeeQuoterABI, Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ - // TODO: update with the consts from https://github.com/smartcontractkit/chainlink-ccip/pull/39 - // in a followup. - "GetStaticConfig": { + consts.MethodNamePriceRegistryGetStaticConfig: { ChainSpecificName: mustGetMethodName("getStaticConfig", priceRegistryABI), ReadType: evmrelaytypes.Method, }, - "GetDestChainConfig": { + consts.MethodNameGetDestChainConfig: { ChainSpecificName: mustGetMethodName("getDestChainConfig", priceRegistryABI), ReadType: evmrelaytypes.Method, }, - "GetPremiumMultiplierWeiPerEth": { + consts.MethodNameGetPremiumMultiplierWeiPerEth: { ChainSpecificName: mustGetMethodName("getPremiumMultiplierWeiPerEth", priceRegistryABI), ReadType: evmrelaytypes.Method, }, - "GetTokenTransferFeeConfig": { + consts.MethodNameGetTokenTransferFeeConfig: { ChainSpecificName: mustGetMethodName("getTokenTransferFeeConfig", priceRegistryABI), ReadType: evmrelaytypes.Method, }, - "ProcessMessageArgs": { + consts.MethodNameProcessMessageArgs: { ChainSpecificName: mustGetMethodName("processMessageArgs", priceRegistryABI), ReadType: evmrelaytypes.Method, }, - "ProcessPoolReturnData": { + consts.MethodNameProcessPoolReturnData: { ChainSpecificName: mustGetMethodName("processPoolReturnData", priceRegistryABI), ReadType: evmrelaytypes.Method, }, - "GetValidatedTokenPrice": { + consts.MethodNameGetValidatedTokenPrice: { ChainSpecificName: mustGetMethodName("getValidatedTokenPrice", priceRegistryABI), ReadType: evmrelaytypes.Method, }, - "GetFeeTokens": { + consts.MethodNameGetFeeTokens: { ChainSpecificName: mustGetMethodName("getFeeTokens", priceRegistryABI), ReadType: evmrelaytypes.Method, }, diff --git a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go index cce56e0d80..cf2ff7d133 100644 --- a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go +++ b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go @@ -96,8 +96,8 @@ type OffRampSourceChainConfig struct { } var CCIPReaderTesterMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPSendRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"setDestChainSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061129d806100206000396000f3fe608060405234801561001057600080fd5b506004361061006d5760003560e01c80634cf66e361461007257806385096da9146100875780639041be3d1461009a578063c1a5a355146100ca578063e44302b714610106578063e83eabba14610119578063e9d68a8e1461012c575b600080fd5b610085610080366004610571565b61014c565b005b6100856100953660046107e9565b6101a1565b6100ad6100a8366004610917565b6101e6565b6040516001600160401b0390911681526020015b60405180910390f35b6100856100d8366004610939565b6001600160401b03918216600090815260016020526040902080546001600160401b03191691909216179055565b610085610114366004610adc565b610215565b610085610127366004610c46565b61024f565b61013f61013a366004610917565b6102db565b6040516100c19190610d47565b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df28585604051610192929190610d9f565b60405180910390a45050505050565b816001600160401b03167fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140826040516101da9190610ea2565b60405180910390a25050565b6001600160401b038082166000908152600160208190526040822054919261020f921690610fa4565b92915050565b7f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d816040516102449190611091565b60405180910390a150565b6001600160401b0380831660009081526020818152604091829020845181549286015193860151909416600160a81b02600160a81b600160e81b0319931515600160a01b026001600160a81b03199093166001600160a01b03909516949094179190911791909116919091178155606082015182919060018201906102d490826111d1565b5050505050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b038781168452838352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b90920490921694830194909452600184018054939492939184019161036690611146565b80601f016020809104026020016040519081016040528092919081815260200182805461039290611146565b80156103df5780601f106103b4576101008083540402835291602001916103df565b820191906000526020600020905b8154815290600101906020018083116103c257829003601f168201915b5050505050815250509050919050565b80356001600160401b038116811461040657600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156104435761044361040b565b60405290565b60405161010081016001600160401b03811182821017156104435761044361040b565b604080519081016001600160401b03811182821017156104435761044361040b565b604051606081016001600160401b03811182821017156104435761044361040b565b604051608081016001600160401b03811182821017156104435761044361040b565b604051601f8201601f191681016001600160401b03811182821017156104fa576104fa61040b565b604052919050565b600082601f83011261051357600080fd5b81356001600160401b0381111561052c5761052c61040b565b61053f601f8201601f19166020016104d2565b81815284602083860101111561055457600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561058957600080fd5b610592866103ef565b94506105a0602087016103ef565b9350604086013592506060860135600481106105bb57600080fd5b915060808601356001600160401b038111156105d657600080fd5b6105e288828901610502565b9150509295509295909350565b600060a0828403121561060157600080fd5b610609610421565b90508135815261061b602083016103ef565b602082015261062c604083016103ef565b604082015261063d606083016103ef565b606082015261064e608083016103ef565b608082015292915050565b6001600160a01b038116811461066e57600080fd5b50565b803561040681610659565b60006001600160401b038211156106955761069561040b565b5060051b60200190565b600082601f8301126106b057600080fd5b813560206106c56106c08361067c565b6104d2565b82815260059290921b840181019181810190868411156106e457600080fd5b8286015b848110156107de5780356001600160401b03808211156107085760008081fd5b9088019060a0828b03601f19018113156107225760008081fd5b61072a610421565b878401358381111561073c5760008081fd5b61074a8d8a83880101610502565b825250604080850135848111156107615760008081fd5b61076f8e8b83890101610502565b8a84015250606080860135858111156107885760008081fd5b6107968f8c838a0101610502565b838501525060809150818601358184015250828501359250838311156107bc5760008081fd5b6107ca8d8a85880101610502565b9082015286525050509183019183016106e8565b509695505050505050565b600080604083850312156107fc57600080fd5b610805836103ef565b915060208301356001600160401b038082111561082157600080fd5b90840190610180828703121561083657600080fd5b61083e610449565b61084887846105ef565b815261085660a08401610671565b602082015260c08301358281111561086d57600080fd5b61087988828601610502565b60408301525060e08301358281111561089157600080fd5b61089d88828601610502565b606083015250610100830135828111156108b657600080fd5b6108c288828601610502565b6080830152506108d56101208401610671565b60a082015261014083013560c0820152610160830135828111156108f857600080fd5b6109048882860161069f565b60e0830152508093505050509250929050565b60006020828403121561092957600080fd5b610932826103ef565b9392505050565b6000806040838503121561094c57600080fd5b610955836103ef565b9150610963602084016103ef565b90509250929050565b80356001600160e01b038116811461040657600080fd5b600082601f83011261099457600080fd5b813560206109a46106c08361067c565b82815260069290921b840181019181810190868411156109c357600080fd5b8286015b848110156107de57604081890312156109e05760008081fd5b6109e861046c565b6109f1826103ef565b81526109fe85830161096c565b818601528352918301916040016109c7565b600082601f830112610a2157600080fd5b81356020610a316106c08361067c565b82815260079290921b84018101918181019086841115610a5057600080fd5b8286015b848110156107de578088036080811215610a6e5760008081fd5b610a7661048e565b610a7f836103ef565b8152604080601f1984011215610a955760008081fd5b610a9d61046c565b9250610aaa8785016103ef565b8352610ab78185016103ef565b8388015281870192909252606083013591810191909152835291830191608001610a54565b60006020808385031215610aef57600080fd5b82356001600160401b0380821115610b0657600080fd5b81850191506040808388031215610b1c57600080fd5b610b2461046c565b833583811115610b3357600080fd5b84016040818a031215610b4557600080fd5b610b4d61046c565b813585811115610b5c57600080fd5b8201601f81018b13610b6d57600080fd5b8035610b7b6106c08261067c565b81815260069190911b8201890190898101908d831115610b9a57600080fd5b928a01925b82841015610bea5787848f031215610bb75760008081fd5b610bbf61046c565b8435610bca81610659565b8152610bd7858d0161096c565b818d0152825292870192908a0190610b9f565b845250505081870135935084841115610c0257600080fd5b610c0e8a858401610983565b8188015282525083850135915082821115610c2857600080fd5b610c3488838601610a10565b85820152809550505050505092915050565b60008060408385031215610c5957600080fd5b610c62836103ef565b915060208301356001600160401b0380821115610c7e57600080fd5b9084019060808287031215610c9257600080fd5b610c9a6104b0565b8235610ca581610659565b815260208301358015158114610cba57600080fd5b6020820152610ccb604084016103ef565b6040820152606083013582811115610ce257600080fd5b610cee88828601610502565b6060830152508093505050509250929050565b6000815180845260005b81811015610d2757602081850181015186830182015201610d0b565b506000602082860101526020601f19601f83011685010191505092915050565b602080825282516001600160a01b03168282015282015115156040808301919091528201516001600160401b0316606080830191909152820151608080830152600090610d9760a0840182610d01565b949350505050565b600060048410610dbf57634e487b7160e01b600052602160045260246000fd5b83825260406020830152610d976040830184610d01565b6001600160a01b03169052565b600082825180855260208086019550808260051b84010181860160005b84811015610e9557601f19868403018952815160a08151818652610e2682870182610d01565b9150508582015185820387870152610e3e8282610d01565b91505060408083015186830382880152610e588382610d01565b92505050606080830151818701525060808083015192508582038187015250610e818183610d01565b9a86019a9450505090830190600101610e00565b5090979650505050505050565b60208152610eef602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b60006020830151610f0360c0840182610dd6565b5060408301516101808060e0850152610f206101a0850183610d01565b91506060850151601f198086850301610100870152610f3f8483610d01565b9350608087015191508086850301610120870152610f5d8483610d01565b935060a08701519150610f74610140870183610dd6565b60c087015161016087015260e0870151915080868503018387015250610f9a8382610de3565b9695505050505050565b6001600160401b03818116838216019080821115610fd257634e487b7160e01b600052601160045260246000fd5b5092915050565b60008151808452602080850194506020840160005b8381101561102757815180516001600160401b031688528301516001600160e01b03168388015260409096019590820190600101610fee565b509495945050505050565b600081518084526020808501945080840160005b8381101561102757815180516001600160401b0390811689528482015180518216868b0152850151166040898101919091520151606088015260809096019590820190600101611046565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b808310156110ff57835180516001600160a01b031683528701516001600160e01b0316878301529286019260019290920191908401906110c4565b5093850151878503605f190160808901529361111b8186610fd9565b945050505050818501519150601f1984820301604085015261113d8183611032565b95945050505050565b600181811c9082168061115a57607f821691505b60208210810361117a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156111cc576000816000526020600020601f850160051c810160208610156111a95750805b601f850160051c820191505b818110156111c8578281556001016111b5565b5050505b505050565b81516001600160401b038111156111ea576111ea61040b565b6111fe816111f88454611146565b84611180565b602080601f831160018114611233576000841561121b5750858301515b600019600386901b1c1916600185901b1785556111c8565b600085815260208120601f198616915b8281101561126257888601518255948401946001909101908401611243565b50858210156112805787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPSendRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"getInboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"setDestChainSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"testNonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"setInboundNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061148e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100835760003560e01c80634cf66e361461008857806385096da91461009d5780639041be3d146100b057806393df2867146100e0578063c1a5a355146100f3578063c92236251461012f578063e44302b714610142578063e83eabba14610155578063e9d68a8e14610168575b600080fd5b61009b610096366004610658565b610188565b005b61009b6100ab3660046108d0565b6101dd565b6100c36100be3660046109fe565b610222565b6040516001600160401b0390911681526020015b60405180910390f35b61009b6100ee366004610a68565b610251565b61009b610101366004610ac8565b6001600160401b03918216600090815260016020526040902080546001600160401b03191691909216179055565b6100c361013d366004610afb565b6102b2565b61009b610150366004610cbd565b6102fc565b61009b610163366004610e27565b610336565b61017b6101763660046109fe565b6103c2565b6040516100d79190610f28565b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df285856040516101ce929190610f80565b60405180910390a45050505050565b816001600160401b03167fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140826040516102169190611083565b60405180910390a25050565b6001600160401b038082166000908152600160208190526040822054919261024b921690611185565b92915050565b6001600160401b03841660009081526002602052604090819020905184919061027d90859085906111ba565b90815260405190819003602001902080546001600160401b03929092166001600160401b031990921691909117905550505050565b6001600160401b03831660009081526002602052604080822090516102da90859085906111ba565b908152604051908190036020019020546001600160401b031690509392505050565b7f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161032b9190611282565b60405180910390a150565b6001600160401b0380831660009081526020818152604091829020845181549286015193860151909416600160a81b02600160a81b600160e81b0319931515600160a01b026001600160a81b03199093166001600160a01b03909516949094179190911791909116919091178155606082015182919060018201906103bb90826113c2565b5050505050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b038781168452838352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b90920490921694830194909452600184018054939492939184019161044d90611337565b80601f016020809104026020016040519081016040528092919081815260200182805461047990611337565b80156104c65780601f1061049b576101008083540402835291602001916104c6565b820191906000526020600020905b8154815290600101906020018083116104a957829003601f168201915b5050505050815250509050919050565b80356001600160401b03811681146104ed57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b038111828210171561052a5761052a6104f2565b60405290565b60405161010081016001600160401b038111828210171561052a5761052a6104f2565b604080519081016001600160401b038111828210171561052a5761052a6104f2565b604051606081016001600160401b038111828210171561052a5761052a6104f2565b604051608081016001600160401b038111828210171561052a5761052a6104f2565b604051601f8201601f191681016001600160401b03811182821017156105e1576105e16104f2565b604052919050565b600082601f8301126105fa57600080fd5b81356001600160401b03811115610613576106136104f2565b610626601f8201601f19166020016105b9565b81815284602083860101111561063b57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561067057600080fd5b610679866104d6565b9450610687602087016104d6565b9350604086013592506060860135600481106106a257600080fd5b915060808601356001600160401b038111156106bd57600080fd5b6106c9888289016105e9565b9150509295509295909350565b600060a082840312156106e857600080fd5b6106f0610508565b905081358152610702602083016104d6565b6020820152610713604083016104d6565b6040820152610724606083016104d6565b6060820152610735608083016104d6565b608082015292915050565b6001600160a01b038116811461075557600080fd5b50565b80356104ed81610740565b60006001600160401b0382111561077c5761077c6104f2565b5060051b60200190565b600082601f83011261079757600080fd5b813560206107ac6107a783610763565b6105b9565b82815260059290921b840181019181810190868411156107cb57600080fd5b8286015b848110156108c55780356001600160401b03808211156107ef5760008081fd5b9088019060a0828b03601f19018113156108095760008081fd5b610811610508565b87840135838111156108235760008081fd5b6108318d8a838801016105e9565b825250604080850135848111156108485760008081fd5b6108568e8b838901016105e9565b8a840152506060808601358581111561086f5760008081fd5b61087d8f8c838a01016105e9565b838501525060809150818601358184015250828501359250838311156108a35760008081fd5b6108b18d8a858801016105e9565b9082015286525050509183019183016107cf565b509695505050505050565b600080604083850312156108e357600080fd5b6108ec836104d6565b915060208301356001600160401b038082111561090857600080fd5b90840190610180828703121561091d57600080fd5b610925610530565b61092f87846106d6565b815261093d60a08401610758565b602082015260c08301358281111561095457600080fd5b610960888286016105e9565b60408301525060e08301358281111561097857600080fd5b610984888286016105e9565b6060830152506101008301358281111561099d57600080fd5b6109a9888286016105e9565b6080830152506109bc6101208401610758565b60a082015261014083013560c0820152610160830135828111156109df57600080fd5b6109eb88828601610786565b60e0830152508093505050509250929050565b600060208284031215610a1057600080fd5b610a19826104d6565b9392505050565b60008083601f840112610a3257600080fd5b5081356001600160401b03811115610a4957600080fd5b602083019150836020828501011115610a6157600080fd5b9250929050565b60008060008060608587031215610a7e57600080fd5b610a87856104d6565b9350610a95602086016104d6565b925060408501356001600160401b03811115610ab057600080fd5b610abc87828801610a20565b95989497509550505050565b60008060408385031215610adb57600080fd5b610ae4836104d6565b9150610af2602084016104d6565b90509250929050565b600080600060408486031215610b1057600080fd5b610b19846104d6565b925060208401356001600160401b03811115610b3457600080fd5b610b4086828701610a20565b9497909650939450505050565b80356001600160e01b03811681146104ed57600080fd5b600082601f830112610b7557600080fd5b81356020610b856107a783610763565b82815260069290921b84018101918181019086841115610ba457600080fd5b8286015b848110156108c55760408189031215610bc15760008081fd5b610bc9610553565b610bd2826104d6565b8152610bdf858301610b4d565b81860152835291830191604001610ba8565b600082601f830112610c0257600080fd5b81356020610c126107a783610763565b82815260079290921b84018101918181019086841115610c3157600080fd5b8286015b848110156108c5578088036080811215610c4f5760008081fd5b610c57610575565b610c60836104d6565b8152604080601f1984011215610c765760008081fd5b610c7e610553565b9250610c8b8785016104d6565b8352610c988185016104d6565b8388015281870192909252606083013591810191909152835291830191608001610c35565b60006020808385031215610cd057600080fd5b82356001600160401b0380821115610ce757600080fd5b81850191506040808388031215610cfd57600080fd5b610d05610553565b833583811115610d1457600080fd5b84016040818a031215610d2657600080fd5b610d2e610553565b813585811115610d3d57600080fd5b8201601f81018b13610d4e57600080fd5b8035610d5c6107a782610763565b81815260069190911b8201890190898101908d831115610d7b57600080fd5b928a01925b82841015610dcb5787848f031215610d985760008081fd5b610da0610553565b8435610dab81610740565b8152610db8858d01610b4d565b818d0152825292870192908a0190610d80565b845250505081870135935084841115610de357600080fd5b610def8a858401610b64565b8188015282525083850135915082821115610e0957600080fd5b610e1588838601610bf1565b85820152809550505050505092915050565b60008060408385031215610e3a57600080fd5b610e43836104d6565b915060208301356001600160401b0380821115610e5f57600080fd5b9084019060808287031215610e7357600080fd5b610e7b610597565b8235610e8681610740565b815260208301358015158114610e9b57600080fd5b6020820152610eac604084016104d6565b6040820152606083013582811115610ec357600080fd5b610ecf888286016105e9565b6060830152508093505050509250929050565b6000815180845260005b81811015610f0857602081850181015186830182015201610eec565b506000602082860101526020601f19601f83011685010191505092915050565b602080825282516001600160a01b03168282015282015115156040808301919091528201516001600160401b0316606080830191909152820151608080830152600090610f7860a0840182610ee2565b949350505050565b600060048410610fa057634e487b7160e01b600052602160045260246000fd5b83825260406020830152610f786040830184610ee2565b6001600160a01b03169052565b600082825180855260208086019550808260051b84010181860160005b8481101561107657601f19868403018952815160a0815181865261100782870182610ee2565b915050858201518582038787015261101f8282610ee2565b915050604080830151868303828801526110398382610ee2565b925050506060808301518187015250608080830151925085820381870152506110628183610ee2565b9a86019a9450505090830190600101610fe1565b5090979650505050505050565b602081526110d0602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b600060208301516110e460c0840182610fb7565b5060408301516101808060e08501526111016101a0850183610ee2565b91506060850151601f1980868503016101008701526111208483610ee2565b935060808701519150808685030161012087015261113e8483610ee2565b935060a08701519150611155610140870183610fb7565b60c087015161016087015260e087015191508086850301838701525061117b8382610fc4565b9695505050505050565b6001600160401b038181168382160190808211156111b357634e487b7160e01b600052601160045260246000fd5b5092915050565b8183823760009101908152919050565b60008151808452602080850194506020840160005b8381101561121857815180516001600160401b031688528301516001600160e01b031683880152604090960195908201906001016111df565b509495945050505050565b600081518084526020808501945080840160005b8381101561121857815180516001600160401b0390811689528482015180518216868b0152850151166040898101919091520151606088015260809096019590820190600101611237565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b808310156112f057835180516001600160a01b031683528701516001600160e01b0316878301529286019260019290920191908401906112b5565b5093850151878503605f190160808901529361130c81866111ca565b945050505050818501519150601f1984820301604085015261132e8183611223565b95945050505050565b600181811c9082168061134b57607f821691505b60208210810361136b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156113bd576000816000526020600020601f850160051c8101602086101561139a5750805b601f850160051c820191505b818110156113b9578281556001016113a6565b5050505b505050565b81516001600160401b038111156113db576113db6104f2565b6113ef816113e98454611337565b84611371565b602080601f831160018114611424576000841561140c5750858301515b600019600386901b1c1916600185901b1785556113b9565b600085815260208120601f198616915b8281101561145357888601518255948401946001909101908401611434565b50858210156114715787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", } var CCIPReaderTesterABI = CCIPReaderTesterMetaData.ABI @@ -258,6 +258,28 @@ func (_CCIPReaderTester *CCIPReaderTesterCallerSession) GetExpectedNextSequenceN return _CCIPReaderTester.Contract.GetExpectedNextSequenceNumber(&_CCIPReaderTester.CallOpts, destChainSelector) } +func (_CCIPReaderTester *CCIPReaderTesterCaller) GetInboundNonce(opts *bind.CallOpts, sourceChainSelector uint64, sender []byte) (uint64, error) { + var out []interface{} + err := _CCIPReaderTester.contract.Call(opts, &out, "getInboundNonce", sourceChainSelector, sender) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CCIPReaderTester *CCIPReaderTesterSession) GetInboundNonce(sourceChainSelector uint64, sender []byte) (uint64, error) { + return _CCIPReaderTester.Contract.GetInboundNonce(&_CCIPReaderTester.CallOpts, sourceChainSelector, sender) +} + +func (_CCIPReaderTester *CCIPReaderTesterCallerSession) GetInboundNonce(sourceChainSelector uint64, sender []byte) (uint64, error) { + return _CCIPReaderTester.Contract.GetInboundNonce(&_CCIPReaderTester.CallOpts, sourceChainSelector, sender) +} + func (_CCIPReaderTester *CCIPReaderTesterCaller) GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (OffRampSourceChainConfig, error) { var out []interface{} err := _CCIPReaderTester.contract.Call(opts, &out, "getSourceChainConfig", sourceChainSelector) @@ -328,6 +350,18 @@ func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) SetDestChainSeqNr(de return _CCIPReaderTester.Contract.SetDestChainSeqNr(&_CCIPReaderTester.TransactOpts, destChainSelector, sequenceNumber) } +func (_CCIPReaderTester *CCIPReaderTesterTransactor) SetInboundNonce(opts *bind.TransactOpts, sourceChainSelector uint64, testNonce uint64, sender []byte) (*types.Transaction, error) { + return _CCIPReaderTester.contract.Transact(opts, "setInboundNonce", sourceChainSelector, testNonce, sender) +} + +func (_CCIPReaderTester *CCIPReaderTesterSession) SetInboundNonce(sourceChainSelector uint64, testNonce uint64, sender []byte) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.SetInboundNonce(&_CCIPReaderTester.TransactOpts, sourceChainSelector, testNonce, sender) +} + +func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) SetInboundNonce(sourceChainSelector uint64, testNonce uint64, sender []byte) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.SetInboundNonce(&_CCIPReaderTester.TransactOpts, sourceChainSelector, testNonce, sender) +} + func (_CCIPReaderTester *CCIPReaderTesterTransactor) SetSourceChainConfig(opts *bind.TransactOpts, sourceChainSelector uint64, sourceChainConfig OffRampSourceChainConfig) (*types.Transaction, error) { return _CCIPReaderTester.contract.Transact(opts, "setSourceChainConfig", sourceChainSelector, sourceChainConfig) } @@ -765,6 +799,8 @@ func (_CCIPReaderTester *CCIPReaderTester) Address() common.Address { type CCIPReaderTesterInterface interface { GetExpectedNextSequenceNumber(opts *bind.CallOpts, destChainSelector uint64) (uint64, error) + GetInboundNonce(opts *bind.CallOpts, sourceChainSelector uint64, sender []byte) (uint64, error) + GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (OffRampSourceChainConfig, error) EmitCCIPSendRequested(opts *bind.TransactOpts, destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) @@ -775,6 +811,8 @@ type CCIPReaderTesterInterface interface { SetDestChainSeqNr(opts *bind.TransactOpts, destChainSelector uint64, sequenceNumber uint64) (*types.Transaction, error) + SetInboundNonce(opts *bind.TransactOpts, sourceChainSelector uint64, testNonce uint64, sender []byte) (*types.Transaction, error) + SetSourceChainConfig(opts *bind.TransactOpts, sourceChainSelector uint64, sourceChainConfig OffRampSourceChainConfig) (*types.Transaction, error) FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*CCIPReaderTesterCCIPSendRequestedIterator, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index afbdd51c79..b18205944a 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -5,7 +5,7 @@ burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoo burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6333d0314d0bd29e75ea5e05fe62a4516ade0c6db91c30b6f93645035db52ed8 burn_with_from_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin 08ed1235dda921ce8841b26aa18d0c0f36db4884779dd7670857159801b6d597 ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 213d4adc8634671aea16fb4207989375b1aac919b04d608f4767c29592affbf5 -ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin d8d70fe111bacc7702c7c263f8c4733dcb2fff77e52c9f60c30d303731bc97c1 +ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin baf432c39ed2aa95dd25d1ae1d22c34ec9353b007e5127f8aea742125144e0e9 commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin 274d87db70b643e00ab0a7e7845bb4b791f3b613bfc87708d33fc5a8369e2a41 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin f7128dcc2ee6dbcbc976288abcc16970ffb19b59412c5202ef6b259d2007f801 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 5215cc0e91..0ca0d83225 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -270,7 +270,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index d4d8962634..f30b5b4ced 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1188,8 +1188,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 h1:gZsXQ//TbsaD9bcvR2wOdao7AgNDIS/Uml0FEF0vJuI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/go.mod b/go.mod index c48e24e0b7..4173b33c8a 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 diff --git a/go.sum b/go.sum index f4c6e50a7b..d50ac5d0f2 100644 --- a/go.sum +++ b/go.sum @@ -1145,8 +1145,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 h1:gZsXQ//TbsaD9bcvR2wOdao7AgNDIS/Uml0FEF0vJuI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index c3b9d51542..7e8f0fc9d3 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -36,7 +36,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 github.com/smartcontractkit/chainlink-testing-framework v1.35.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index daa3de116a..76cab97718 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1423,8 +1423,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 h1:gZsXQ//TbsaD9bcvR2wOdao7AgNDIS/Uml0FEF0vJuI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 1f1637bb99..a56f535c34 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -59,7 +59,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index da213f2b20..d9ffd17aa4 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1393,8 +1393,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b h1:v1RnZVfUoHIm/lwIqRAH4eDRNTu+N+AtQE5Ik4U9hsU= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240828115624-442f1cff195b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 h1:gZsXQ//TbsaD9bcvR2wOdao7AgNDIS/Uml0FEF0vJuI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= From 3ba567d984a2ba0a437806debe0d1e7d2f28d40f Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Wed, 4 Sep 2024 18:43:40 +0200 Subject: [PATCH 287/432] [TT-1600] corrected handling of tags (#14312) * strip 'v' prefix only from Docker image, not from github release tag, if compatibility pipeline is triggered by tag * comment out Slack notification * ping another user if compat fails * fail cron test on purpose * do not fail test on purpose * use image version from input, not env, as it doesn't work for tags --- .../actions/build-chainlink-image/action.yml | 2 +- .../workflows/client-compatibility-tests.yml | 25 ++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/.github/actions/build-chainlink-image/action.yml b/.github/actions/build-chainlink-image/action.yml index 9cd90432e9..4934e579ae 100644 --- a/.github/actions/build-chainlink-image/action.yml +++ b/.github/actions/build-chainlink-image/action.yml @@ -51,4 +51,4 @@ runs: shell: sh run: | echo "### Chainlink node image tag used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY + echo "\`${{inputs.git_commit_sha}}\`" >>$GITHUB_STEP_SUMMARY diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 58ec0ff94e..af57575068 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -125,6 +125,7 @@ jobs: outputs: evm_implementations: ${{ steps.select-implementations.outputs.evm_implementations }} chainlink_version: ${{ steps.select-chainlink-version.outputs.chainlink_version }} + chainlink_image_version: ${{ steps.select-chainlink-version.outputs.chainlink_image_version }} latest_image_count: ${{ steps.get-image-count.outputs.image_count }} chainlink_ref_path: ${{ steps.select-chainlink-version.outputs.cl_ref_path }} steps: @@ -197,35 +198,43 @@ jobs: echo "Fetching latest Chainlink stable version" implementations_arr=() # we use 100 days since we really want the latest one, and it's highly improbable there won't be a release in last 100 days - chainlink_version=$(ghlatestreleasechecker "smartcontractkit/chainlink" 100) + chainlink_version=$(ghlatestreleasechecker "smartcontractkit/chainlink" 100) + chainlink_image_version=$chainlink_version cl_ref_path="releases" elif [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then echo "Fetching Chainlink version from input" if [ -n "${{ github.event.inputs.chainlinkVersion }}" ]; then echo "Chainlink version provided in input" - chainlink_version="${{ github.event.inputs.chainlinkVersion }}" + chainlink_version="${{ github.event.inputs.chainlinkVersion }}" if [[ "$chainlink_version" =~ ^[0-9a-f]{40}$ ]]; then cl_ref_path="commit" + chainlink_image_version=$chainlink_version else cl_ref_path="releases" + # strip the 'v' from the version, because we tag our Docker images without it + chainlink_image_version="${chainlink_version#v}" fi else echo "Chainlink version not provided in input. Using latest commit SHA." chainlink_version=${{ github.sha }} + chainlink_image_version=$chainlink_version cl_ref_path="commit" fi elif [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then echo "Fetching Chainlink version from PR's head commit" chainlink_version="${{ github.event.pull_request.head.sha }}" + chainlink_image_version=$chainlink_version cl_ref_path="commit" elif [ "$GITHUB_EVENT_NAME" = "merge_queue" ]; then echo "Fetching Chainlink version from merge queue's head commit" chainlink_version="${{ github.event.merge_group.head_sha }}" + chainlink_image_version=$chainlink_version cl_ref_path="commit" elif [ "$GITHUB_REF_TYPE" = "tag" ]; then echo "Fetching Chainlink version from tag" chainlink_version="${{ github.ref_name }}" - chainlink_version=${chainlink_version#v} + # strip the 'v' from the version, because we tag our Docker images without it + chainlink_image_version="${chainlink_version#v}" cl_ref_path="releases" else echo "Unsupported trigger event. It's probably an issue with the pipeline definition. Please reach out to the Test Tooling team." @@ -233,6 +242,8 @@ jobs: fi echo "Will use following Chainlink version: $chainlink_version" echo "chainlink_version=$chainlink_version" >> $GITHUB_OUTPUT + echo "Will use following Chainlink Docker image version: $chainlink_image_version" + echo "chainlink_image_version=$chainlink_image_version" >> $GITHUB_OUTPUT echo "cl_ref_path=$cl_ref_path" >> $GITHUB_OUTPUT - name: Get image count id: get-image-count @@ -315,7 +326,9 @@ jobs: with: tag_suffix: "" dockerfile: core/chainlink.Dockerfile - git_commit_sha: ${{ needs.select-versions.outputs.chainlink_version }} + # for tagged releases Docker image version is different from the Chainlink version (v2.13.0 -> 2.13.0) + # for all other cases (PRs, commits, etc.) Docker image version is the same as the Chainlink version + git_commit_sha: ${{ needs.select-versions.outputs.chainlink_image_version }} check_image_exists: "true" AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} @@ -629,7 +642,7 @@ jobs: with: test_command_to_run: cd ./integration-tests && touch .root_dir && go test -timeout 30m -count=1 -json ${{ matrix.evm_node.run }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_config_chainlink_version: ${{ needs.select-versions.outputs.chainlink_version }} + test_config_chainlink_version: ${{ needs.select-versions.outputs.chainlink_image_version }} test_config_selected_networks: ${{ env.SELECTED_NETWORKS}} test_config_logging_run_id: ${{ github.run_id }} test_config_test_log_collect: ${{ vars.TEST_LOG_COLLECT }} @@ -710,7 +723,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "${{ contains(join(needs.*.result, ','), 'failure') && format('Some tests failed, notifying ', secrets.COMPAT_SLACK_NOTIFICATION_HANDLE) || 'All Good!' }}" + "text": "${{ contains(join(needs.*.result, ','), 'failure') && format('Some tests failed, notifying ', secrets.COMPAT_SLACK_NOTIFICATION_HANDLE) || 'All Good!' }}" } }, { From 8853040b957b78491ac8bac69ab4affb97dde602 Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:05:11 -0400 Subject: [PATCH 288/432] Fix linting in CI for new issues (#14335) --- .github/actions/golangci-lint/action.yml | 14 +++++++------- .github/workflows/ci-core.yml | 7 +++++++ .github/workflows/ci-scripts.yml | 6 ++++++ .tool-versions | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/.github/actions/golangci-lint/action.yml b/.github/actions/golangci-lint/action.yml index ffcfeea3d0..86e15f80b2 100644 --- a/.github/actions/golangci-lint/action.yml +++ b/.github/actions/golangci-lint/action.yml @@ -10,7 +10,8 @@ inputs: required: true go-directory: description: Go directory to run commands from - default: "." + # XXX: Don't use `.` here due to issues with the golangci-lint-action. + default: "" # setup-go inputs only-modules: description: Set to 'true' to only cache modules @@ -36,6 +37,9 @@ runs: using: composite steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + # We only need a full clone on merge_group events for golangci-lint. + fetch-depth: ${{ github.event_name == 'merge_group' && '0' || '1' }}" - name: Setup Go uses: ./.github/actions/setup-go with: @@ -51,13 +55,9 @@ runs: shell: bash run: go build ./... - name: golangci-lint - uses: golangci/golangci-lint-action@3cfe3a4abbb849e10058ce4af15d205b6da42804 # v4.0.0 + uses: golangci/golangci-lint-action@38e1018663fa5173f3968ea0777460d3de38f256 # v5.3.0 with: - version: v1.59.1 - # We already cache these directories in setup-go - skip-pkg-cache: true - skip-build-cache: true - # only-new-issues is only applicable to PRs, otherwise it is always set to false + version: v1.60.3 only-new-issues: true args: --out-format colored-line-number,checkstyle:golangci-lint-report.xml working-directory: ${{ inputs.go-directory }} diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index dd79493d13..9a1a707c19 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -57,6 +57,12 @@ jobs: # We don't directly merge dependabot PRs, so let's not waste the resources if: ${{ (github.event_name == 'pull_request' || github.event_name == 'schedule') && github.actor != 'dependabot[bot]' }} name: lint + permissions: + # For golangci-lint-actions to annotate code in the PR. + checks: write + contents: read + # For golangci-lint-action's `only-new-issues` option. + pull-requests: read runs-on: ubuntu22.04-8cores-32GB needs: [filter] steps: @@ -70,6 +76,7 @@ jobs: gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }} gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + - name: Notify Slack if: ${{ failure() && github.event.schedule != '' }} uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 diff --git a/.github/workflows/ci-scripts.yml b/.github/workflows/ci-scripts.yml index 73e72eced5..8fa27f6627 100644 --- a/.github/workflows/ci-scripts.yml +++ b/.github/workflows/ci-scripts.yml @@ -9,6 +9,12 @@ jobs: # We don't directly merge dependabot PRs, so let's not waste the resources if: ${{ (github.event_name == 'pull_request' || github.event_name == 'schedule') && github.actor != 'dependabot[bot]' }} runs-on: ubuntu-latest + permissions: + # For golangci-lint-actions to annotate code in the PR. + checks: write + contents: read + # For golangci-lint-action's `only-new-issues` option. + pull-requests: read steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Golang Lint diff --git a/.tool-versions b/.tool-versions index 7d237b0a4a..6cd01e3f91 100644 --- a/.tool-versions +++ b/.tool-versions @@ -5,5 +5,5 @@ pnpm 9.4.0 postgres 15.1 helm 3.10.3 zig 0.11.0 -golangci-lint 1.59.1 +golangci-lint 1.60.3 protoc 25.1 From 33e6a0c1e44b805064fe423b5570a40c07daed41 Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:54:20 -0400 Subject: [PATCH 289/432] Bump version and update CHANGELOG fore core v2.16.0 (#14264) Signed-off-by: chainchad <96362174+chainchad@users.noreply.github.com> --- .changeset/afraid-buckets-yell.md | 5 - .changeset/beige-eels-teach.md | 5 - .changeset/big-dots-report.md | 5 - .changeset/big-kiwis-cross.md | 5 - .changeset/big-students-rush.md | 5 - .changeset/blue-roses-brush.md | 5 - .changeset/bright-rings-knock.md | 5 + .changeset/calm-badgers-jump.md | 5 - .changeset/chatty-spiders-double.md | 5 - .changeset/chilly-cars-attend.md | 5 - .changeset/cool-mirrors-beg.md | 5 - .changeset/cuddly-eels-lay.md | 5 - .changeset/curly-birds-guess.md | 5 - .changeset/early-glasses-rhyme.md | 5 - .changeset/eight-bees-speak.md | 5 - .changeset/eight-radios-hear.md | 5 - .changeset/eight-rocks-notice.md | 5 - .changeset/fast-insects-shout.md | 5 - .changeset/flat-mirrors-confess.md | 5 - .changeset/friendly-impalas-sniff.md | 5 - .changeset/great-timers-agree.md | 5 - .changeset/happy-adults-wash.md | 5 - .changeset/hip-crabs-agree.md | 5 - .changeset/hot-laws-deny.md | 5 - .changeset/itchy-bugs-clean.md | 5 - .changeset/late-stingrays-promise.md | 5 - .changeset/lucky-boats-run.md | 5 - .changeset/many-knives-play.md | 5 - .changeset/mean-brooms-agree.md | 5 - .changeset/mighty-points-switch.md | 5 - .changeset/new-eagles-marry.md | 5 - .changeset/nice-turtles-begin.md | 5 - .changeset/ninety-cougars-tease.md | 5 - .changeset/ninety-ways-run.md | 5 - .changeset/odd-eagles-shave.md | 5 - .changeset/odd-hats-repeat.md | 5 - .changeset/pink-fans-sparkle.md | 5 - .changeset/polite-crabs-pretend.md | 5 - .changeset/poor-pumas-occur.md | 5 - .changeset/proud-jokes-exercise.md | 5 - .changeset/rich-chairs-hug.md | 5 - .changeset/seven-kiwis-run.md | 5 - .changeset/shy-windows-juggle.md | 5 - .changeset/slimy-cars-sparkle.md | 5 - .changeset/slimy-forks-wait.md | 5 - .changeset/small-seas-stare.md | 5 - .changeset/smart-pumas-collect.md | 5 - .changeset/strong-dogs-smash.md | 5 - .changeset/sweet-pumas-refuse.md | 5 - .changeset/swift-pumas-taste.md | 5 - .changeset/tall-poems-swim.md | 5 - .changeset/tasty-dogs-arrive.md | 5 - .changeset/tasty-walls-collect.md | 5 - .changeset/tasty-windows-own.md | 5 - .changeset/tender-wombats-juggle.md | 5 - .changeset/thick-mails-applaud.md | 5 - .changeset/thin-rings-count.md | 5 - .changeset/thirty-olives-marry.md | 5 - .changeset/twelve-balloons-turn.md | 5 - .changeset/two-mugs-complain.md | 5 - .changeset/violet-clouds-rhyme.md | 5 - .changeset/warm-houses-build.md | 5 - .changeset/weak-rabbits-sell.md | 5 - .changeset/wild-seals-look.md | 5 - .changeset/wise-snakes-protect.md | 5 - .changeset/yellow-cougars-act.md | 5 - .changeset/young-mice-invent.md | 5 - CHANGELOG.md | 140 +++++++++++++++++++++++++++ package.json | 2 +- 69 files changed, 146 insertions(+), 331 deletions(-) delete mode 100644 .changeset/afraid-buckets-yell.md delete mode 100644 .changeset/beige-eels-teach.md delete mode 100644 .changeset/big-dots-report.md delete mode 100644 .changeset/big-kiwis-cross.md delete mode 100644 .changeset/big-students-rush.md delete mode 100644 .changeset/blue-roses-brush.md create mode 100644 .changeset/bright-rings-knock.md delete mode 100644 .changeset/calm-badgers-jump.md delete mode 100644 .changeset/chatty-spiders-double.md delete mode 100644 .changeset/chilly-cars-attend.md delete mode 100644 .changeset/cool-mirrors-beg.md delete mode 100644 .changeset/cuddly-eels-lay.md delete mode 100644 .changeset/curly-birds-guess.md delete mode 100644 .changeset/early-glasses-rhyme.md delete mode 100644 .changeset/eight-bees-speak.md delete mode 100644 .changeset/eight-radios-hear.md delete mode 100644 .changeset/eight-rocks-notice.md delete mode 100644 .changeset/fast-insects-shout.md delete mode 100644 .changeset/flat-mirrors-confess.md delete mode 100644 .changeset/friendly-impalas-sniff.md delete mode 100644 .changeset/great-timers-agree.md delete mode 100644 .changeset/happy-adults-wash.md delete mode 100644 .changeset/hip-crabs-agree.md delete mode 100644 .changeset/hot-laws-deny.md delete mode 100644 .changeset/itchy-bugs-clean.md delete mode 100644 .changeset/late-stingrays-promise.md delete mode 100644 .changeset/lucky-boats-run.md delete mode 100644 .changeset/many-knives-play.md delete mode 100644 .changeset/mean-brooms-agree.md delete mode 100644 .changeset/mighty-points-switch.md delete mode 100644 .changeset/new-eagles-marry.md delete mode 100644 .changeset/nice-turtles-begin.md delete mode 100644 .changeset/ninety-cougars-tease.md delete mode 100644 .changeset/ninety-ways-run.md delete mode 100644 .changeset/odd-eagles-shave.md delete mode 100644 .changeset/odd-hats-repeat.md delete mode 100644 .changeset/pink-fans-sparkle.md delete mode 100644 .changeset/polite-crabs-pretend.md delete mode 100644 .changeset/poor-pumas-occur.md delete mode 100644 .changeset/proud-jokes-exercise.md delete mode 100644 .changeset/rich-chairs-hug.md delete mode 100644 .changeset/seven-kiwis-run.md delete mode 100644 .changeset/shy-windows-juggle.md delete mode 100644 .changeset/slimy-cars-sparkle.md delete mode 100644 .changeset/slimy-forks-wait.md delete mode 100644 .changeset/small-seas-stare.md delete mode 100644 .changeset/smart-pumas-collect.md delete mode 100644 .changeset/strong-dogs-smash.md delete mode 100644 .changeset/sweet-pumas-refuse.md delete mode 100644 .changeset/swift-pumas-taste.md delete mode 100644 .changeset/tall-poems-swim.md delete mode 100644 .changeset/tasty-dogs-arrive.md delete mode 100644 .changeset/tasty-walls-collect.md delete mode 100644 .changeset/tasty-windows-own.md delete mode 100644 .changeset/tender-wombats-juggle.md delete mode 100644 .changeset/thick-mails-applaud.md delete mode 100644 .changeset/thin-rings-count.md delete mode 100644 .changeset/thirty-olives-marry.md delete mode 100644 .changeset/twelve-balloons-turn.md delete mode 100644 .changeset/two-mugs-complain.md delete mode 100644 .changeset/violet-clouds-rhyme.md delete mode 100644 .changeset/warm-houses-build.md delete mode 100644 .changeset/weak-rabbits-sell.md delete mode 100644 .changeset/wild-seals-look.md delete mode 100644 .changeset/wise-snakes-protect.md delete mode 100644 .changeset/yellow-cougars-act.md delete mode 100644 .changeset/young-mice-invent.md diff --git a/.changeset/afraid-buckets-yell.md b/.changeset/afraid-buckets-yell.md deleted file mode 100644 index 88e9469208..0000000000 --- a/.changeset/afraid-buckets-yell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Exposed Confirmed state to ChainWriter GetTransactionStatus method diff --git a/.changeset/beige-eels-teach.md b/.changeset/beige-eels-teach.md deleted file mode 100644 index 3a3c59ec26..0000000000 --- a/.changeset/beige-eels-teach.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Fix bhe datarace #internal diff --git a/.changeset/big-dots-report.md b/.changeset/big-dots-report.md deleted file mode 100644 index 01475010f0..0000000000 --- a/.changeset/big-dots-report.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Updated ZK overflow detection to skip transactions with non-broadcasted attempts. Delayed detection for zkEVM using the MinAttempts config. Updated XLayer to use the same detection logic as zkEVM. #internal diff --git a/.changeset/big-kiwis-cross.md b/.changeset/big-kiwis-cross.md deleted file mode 100644 index 3bc450c20e..0000000000 --- a/.changeset/big-kiwis-cross.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Initialize start of v2.16.0 release diff --git a/.changeset/big-students-rush.md b/.changeset/big-students-rush.md deleted file mode 100644 index 914205cdf7..0000000000 --- a/.changeset/big-students-rush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#bugfix Fixes test flake diff --git a/.changeset/blue-roses-brush.md b/.changeset/blue-roses-brush.md deleted file mode 100644 index 57dc796c03..0000000000 --- a/.changeset/blue-roses-brush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#added Allow workflows to run without external registry configured diff --git a/.changeset/bright-rings-knock.md b/.changeset/bright-rings-knock.md new file mode 100644 index 0000000000..a3667ed20e --- /dev/null +++ b/.changeset/bright-rings-knock.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Bump to start the next version diff --git a/.changeset/calm-badgers-jump.md b/.changeset/calm-badgers-jump.md deleted file mode 100644 index 76f6e5d312..0000000000 --- a/.changeset/calm-badgers-jump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -add error handling when arbitrum sequencer is not accessible #added diff --git a/.changeset/chatty-spiders-double.md b/.changeset/chatty-spiders-double.md deleted file mode 100644 index 750a11628f..0000000000 --- a/.changeset/chatty-spiders-double.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -remove dependency on FinalityDepth in EVM TXM code. #internal diff --git a/.changeset/chilly-cars-attend.md b/.changeset/chilly-cars-attend.md deleted file mode 100644 index 2cb8323ab3..0000000000 --- a/.changeset/chilly-cars-attend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -add error handle for gnosis chiado for seen tx #added diff --git a/.changeset/cool-mirrors-beg.md b/.changeset/cool-mirrors-beg.md deleted file mode 100644 index a030ac7e3a..0000000000 --- a/.changeset/cool-mirrors-beg.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#added L3X Config diff --git a/.changeset/cuddly-eels-lay.md b/.changeset/cuddly-eels-lay.md deleted file mode 100644 index 25b38d3164..0000000000 --- a/.changeset/cuddly-eels-lay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Improve TXM performance by optimizing Confirmer and Finalizer queries to stop pulling EVM receipt. #internal diff --git a/.changeset/curly-birds-guess.md b/.changeset/curly-birds-guess.md deleted file mode 100644 index c66bd54178..0000000000 --- a/.changeset/curly-birds-guess.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Fixed deadlock in RPCClient causing CL Node to stop performing RPC requests for the affected chain #bugfix diff --git a/.changeset/early-glasses-rhyme.md b/.changeset/early-glasses-rhyme.md deleted file mode 100644 index aa35bf897e..0000000000 --- a/.changeset/early-glasses-rhyme.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -use FilteredLogs in EventBinding GetLatestValue instead of manual filtering. #internal diff --git a/.changeset/eight-bees-speak.md b/.changeset/eight-bees-speak.md deleted file mode 100644 index 9c8ebe428d..0000000000 --- a/.changeset/eight-bees-speak.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#bugfix head reporter non-zero reporting period diff --git a/.changeset/eight-radios-hear.md b/.changeset/eight-radios-hear.md deleted file mode 100644 index b422f37832..0000000000 --- a/.changeset/eight-radios-hear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#added merging core/capabilities/ccip from https://github.com/smartcontractkit/ccip diff --git a/.changeset/eight-rocks-notice.md b/.changeset/eight-rocks-notice.md deleted file mode 100644 index 230abaec48..0000000000 --- a/.changeset/eight-rocks-notice.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -New Mercury v4 report schema #added diff --git a/.changeset/fast-insects-shout.md b/.changeset/fast-insects-shout.md deleted file mode 100644 index 847fc8d057..0000000000 --- a/.changeset/fast-insects-shout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Change CapabilityType to string; remove possiblity of a panic diff --git a/.changeset/flat-mirrors-confess.md b/.changeset/flat-mirrors-confess.md deleted file mode 100644 index 7c0a6a92a3..0000000000 --- a/.changeset/flat-mirrors-confess.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#updated Sync feeds-manager wsrpc proto diff --git a/.changeset/friendly-impalas-sniff.md b/.changeset/friendly-impalas-sniff.md deleted file mode 100644 index 8a041a338b..0000000000 --- a/.changeset/friendly-impalas-sniff.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Added nonce validation immediately after broadcast for Hedera #internal diff --git a/.changeset/great-timers-agree.md b/.changeset/great-timers-agree.md deleted file mode 100644 index bfa27761fb..0000000000 --- a/.changeset/great-timers-agree.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Updated gas limit estimation feature to set From address #internal diff --git a/.changeset/happy-adults-wash.md b/.changeset/happy-adults-wash.md deleted file mode 100644 index 738f8998b2..0000000000 --- a/.changeset/happy-adults-wash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal fix to keystone e2e test dispatcher to correctly mock duplicate registration error diff --git a/.changeset/hip-crabs-agree.md b/.changeset/hip-crabs-agree.md deleted file mode 100644 index 5085899e3d..0000000000 --- a/.changeset/hip-crabs-agree.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#added Add Astar TerminallyUnderpriced error mapping diff --git a/.changeset/hot-laws-deny.md b/.changeset/hot-laws-deny.md deleted file mode 100644 index d71783d1b7..0000000000 --- a/.changeset/hot-laws-deny.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal log info on missed finalized head instead of returning an error diff --git a/.changeset/itchy-bugs-clean.md b/.changeset/itchy-bugs-clean.md deleted file mode 100644 index beeed8ace1..0000000000 --- a/.changeset/itchy-bugs-clean.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Introduced finalized transaction state. Added a finalizer component to the TXM to mark transactions as finalized. #internal diff --git a/.changeset/late-stingrays-promise.md b/.changeset/late-stingrays-promise.md deleted file mode 100644 index 39ca570f58..0000000000 --- a/.changeset/late-stingrays-promise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Separate price updates schedule for token prices in CCIP #updated diff --git a/.changeset/lucky-boats-run.md b/.changeset/lucky-boats-run.md deleted file mode 100644 index c5864a6e37..0000000000 --- a/.changeset/lucky-boats-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Reporting all the token prices from the job spec for CCIP #updated diff --git a/.changeset/many-knives-play.md b/.changeset/many-knives-play.md deleted file mode 100644 index 8c1f5da1a4..0000000000 --- a/.changeset/many-knives-play.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#updated Adds DB syncing for registry syncer diff --git a/.changeset/mean-brooms-agree.md b/.changeset/mean-brooms-agree.md deleted file mode 100644 index 0dd2ba7bd3..0000000000 --- a/.changeset/mean-brooms-agree.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Custom (30s) timeout for Hedera RPC requests with large payloads (SendTransaction, CallContext, etc.) #internal diff --git a/.changeset/mighty-points-switch.md b/.changeset/mighty-points-switch.md deleted file mode 100644 index c42913ad11..0000000000 --- a/.changeset/mighty-points-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal allow gas limit to be specified when submitting transaction diff --git a/.changeset/new-eagles-marry.md b/.changeset/new-eagles-marry.md deleted file mode 100644 index 9577c2bbe0..0000000000 --- a/.changeset/new-eagles-marry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal prevent editing whether or not a DON accepts workflows diff --git a/.changeset/nice-turtles-begin.md b/.changeset/nice-turtles-begin.md deleted file mode 100644 index 70753dfe04..0000000000 --- a/.changeset/nice-turtles-begin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Further development of LLO plugin (parallel composition) #wip diff --git a/.changeset/ninety-cougars-tease.md b/.changeset/ninety-cougars-tease.md deleted file mode 100644 index ab12a57191..0000000000 --- a/.changeset/ninety-cougars-tease.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal restore common version to head of develop diff --git a/.changeset/ninety-ways-run.md b/.changeset/ninety-ways-run.md deleted file mode 100644 index 0b4508bdd2..0000000000 --- a/.changeset/ninety-ways-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal speed up keystone e2e tests diff --git a/.changeset/odd-eagles-shave.md b/.changeset/odd-eagles-shave.md deleted file mode 100644 index 0c68bc1573..0000000000 --- a/.changeset/odd-eagles-shave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Add hexutil Bytes encoding to batchcall data diff --git a/.changeset/odd-hats-repeat.md b/.changeset/odd-hats-repeat.md deleted file mode 100644 index ce80b45caf..0000000000 --- a/.changeset/odd-hats-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal fix the mock trigger to ensure events are sent diff --git a/.changeset/pink-fans-sparkle.md b/.changeset/pink-fans-sparkle.md deleted file mode 100644 index c182e6dea3..0000000000 --- a/.changeset/pink-fans-sparkle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#bugfix Bump BSC PriceMin to 3 gwei to match BSC node's required gas price. This value can be pushed back down to 1 gwei to enable cheaper transactions if the GasPrice field under the Eth.Miner header in the BSC node's config is also pushed down to 1000000000 diff --git a/.changeset/polite-crabs-pretend.md b/.changeset/polite-crabs-pretend.md deleted file mode 100644 index f8ea63b45c..0000000000 --- a/.changeset/polite-crabs-pretend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal ensure remote target request hash is deterministic diff --git a/.changeset/poor-pumas-occur.md b/.changeset/poor-pumas-occur.md deleted file mode 100644 index df3e1e2f5f..0000000000 --- a/.changeset/poor-pumas-occur.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#bugfix More robust error handling in LogPoller, including no more misleading CRITICAL errors emitted under non-critical conditions diff --git a/.changeset/proud-jokes-exercise.md b/.changeset/proud-jokes-exercise.md deleted file mode 100644 index 4e36d139de..0000000000 --- a/.changeset/proud-jokes-exercise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#added Report new heads as a telemetry to OTI diff --git a/.changeset/rich-chairs-hug.md b/.changeset/rich-chairs-hug.md deleted file mode 100644 index 0408383bd0..0000000000 --- a/.changeset/rich-chairs-hug.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal diff --git a/.changeset/seven-kiwis-run.md b/.changeset/seven-kiwis-run.md deleted file mode 100644 index 3b56117c46..0000000000 --- a/.changeset/seven-kiwis-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Added custom client error messages for Mantle to capture InsufficientEth and Fatal errors. #added diff --git a/.changeset/shy-windows-juggle.md b/.changeset/shy-windows-juggle.md deleted file mode 100644 index 0408383bd0..0000000000 --- a/.changeset/shy-windows-juggle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal diff --git a/.changeset/slimy-cars-sparkle.md b/.changeset/slimy-cars-sparkle.md deleted file mode 100644 index aa7658ae90..0000000000 --- a/.changeset/slimy-cars-sparkle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal ks-404 validate ids before using as seed of transmission schedule diff --git a/.changeset/slimy-forks-wait.md b/.changeset/slimy-forks-wait.md deleted file mode 100644 index 0408383bd0..0000000000 --- a/.changeset/slimy-forks-wait.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal diff --git a/.changeset/small-seas-stare.md b/.changeset/small-seas-stare.md deleted file mode 100644 index 22e447bbc8..0000000000 --- a/.changeset/small-seas-stare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal Adding deployment package as new pattern for product deployment/configuration diff --git a/.changeset/smart-pumas-collect.md b/.changeset/smart-pumas-collect.md deleted file mode 100644 index 0748f170b9..0000000000 --- a/.changeset/smart-pumas-collect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#bugfix Fix incorrect error handling when registering a new feed manager diff --git a/.changeset/strong-dogs-smash.md b/.changeset/strong-dogs-smash.md deleted file mode 100644 index a34a418e65..0000000000 --- a/.changeset/strong-dogs-smash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -error handling for Treasure #added \ No newline at end of file diff --git a/.changeset/sweet-pumas-refuse.md b/.changeset/sweet-pumas-refuse.md deleted file mode 100644 index fd642a9c94..0000000000 --- a/.changeset/sweet-pumas-refuse.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#bugfix Addresses 2 minor issues with the pruning of LogPoller's db tables: logs not matching any filter will now be pruned, and rows deleted are now properly reported for observability diff --git a/.changeset/swift-pumas-taste.md b/.changeset/swift-pumas-taste.md deleted file mode 100644 index eb08662e20..0000000000 --- a/.changeset/swift-pumas-taste.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal add head report chain_id diff --git a/.changeset/tall-poems-swim.md b/.changeset/tall-poems-swim.md deleted file mode 100644 index 0408383bd0..0000000000 --- a/.changeset/tall-poems-swim.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal diff --git a/.changeset/tasty-dogs-arrive.md b/.changeset/tasty-dogs-arrive.md deleted file mode 100644 index 1e149f7081..0000000000 --- a/.changeset/tasty-dogs-arrive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -remove chainReader from the Relayer struct. #internal diff --git a/.changeset/tasty-walls-collect.md b/.changeset/tasty-walls-collect.md deleted file mode 100644 index eefe444150..0000000000 --- a/.changeset/tasty-walls-collect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#updated Update Polygon configs to match PIP-35 diff --git a/.changeset/tasty-windows-own.md b/.changeset/tasty-windows-own.md deleted file mode 100644 index bd81338cb4..0000000000 --- a/.changeset/tasty-windows-own.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#bugfix balance shutdown deadlock diff --git a/.changeset/tender-wombats-juggle.md b/.changeset/tender-wombats-juggle.md deleted file mode 100644 index 08f256f4be..0000000000 --- a/.changeset/tender-wombats-juggle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal topeerid should validate []byte length diff --git a/.changeset/thick-mails-applaud.md b/.changeset/thick-mails-applaud.md deleted file mode 100644 index ceec9e64fd..0000000000 --- a/.changeset/thick-mails-applaud.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Simplify how token and gas prices are stored in the database - user upsert instead of insert/delete flow #db_update diff --git a/.changeset/thin-rings-count.md b/.changeset/thin-rings-count.md deleted file mode 100644 index 20f4b54311..0000000000 --- a/.changeset/thin-rings-count.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Add evm Chain Reader GetLatestValue support for filtering on indexed topic types that get hashed. diff --git a/.changeset/thirty-olives-marry.md b/.changeset/thirty-olives-marry.md deleted file mode 100644 index 8be272b935..0000000000 --- a/.changeset/thirty-olives-marry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Change ChainReader Block primitive field from int to string. #internal diff --git a/.changeset/twelve-balloons-turn.md b/.changeset/twelve-balloons-turn.md deleted file mode 100644 index f4f0e2670e..0000000000 --- a/.changeset/twelve-balloons-turn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal fix data race in syncer launcher diff --git a/.changeset/two-mugs-complain.md b/.changeset/two-mugs-complain.md deleted file mode 100644 index 77cdcbfe9e..0000000000 --- a/.changeset/two-mugs-complain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Edited the Optimism Stack L1 Oracle to add support for Mantle #added diff --git a/.changeset/violet-clouds-rhyme.md b/.changeset/violet-clouds-rhyme.md deleted file mode 100644 index b6db0e85c4..0000000000 --- a/.changeset/violet-clouds-rhyme.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Updated AutoPurge.Threshold and AutoPurge.MinAttempts configs to only be required for heuristic and added content-type header for Scroll API #internal diff --git a/.changeset/warm-houses-build.md b/.changeset/warm-houses-build.md deleted file mode 100644 index 6ce6215a88..0000000000 --- a/.changeset/warm-houses-build.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Added custom finality calculation for Astar #internal diff --git a/.changeset/weak-rabbits-sell.md b/.changeset/weak-rabbits-sell.md deleted file mode 100644 index 3f0785d3d5..0000000000 --- a/.changeset/weak-rabbits-sell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal prevent reentrancy when configuring DON in Capabilities Registry diff --git a/.changeset/wild-seals-look.md b/.changeset/wild-seals-look.md deleted file mode 100644 index 3cd854f0e6..0000000000 --- a/.changeset/wild-seals-look.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Added new health check that ensures RPC provides new finalized heads at least every `NoNewFinalizedHeadsThreshold` #added diff --git a/.changeset/wise-snakes-protect.md b/.changeset/wise-snakes-protect.md deleted file mode 100644 index ebc0ec4091..0000000000 --- a/.changeset/wise-snakes-protect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Formalize trigger API #internal diff --git a/.changeset/yellow-cougars-act.md b/.changeset/yellow-cougars-act.md deleted file mode 100644 index 61ed62607a..0000000000 --- a/.changeset/yellow-cougars-act.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Added client error classification for terminally stuck transactions in the TXM #internal diff --git a/.changeset/young-mice-invent.md b/.changeset/young-mice-invent.md deleted file mode 100644 index ba9c67198a..0000000000 --- a/.changeset/young-mice-invent.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Added CCIP plugins code from https://github.com/smartcontractkit/ccip/ #added diff --git a/CHANGELOG.md b/CHANGELOG.md index 780c68003f..c3130723e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,145 @@ # Changelog Chainlink Core +## 2.16.0 - UNRELEASED + +### Minor Changes + +- [#14138](https://github.com/smartcontractkit/chainlink/pull/14138) [`69335dc6b0`](https://github.com/smartcontractkit/chainlink/commit/69335dc6b0837ba9726a2772bf1dc98174c03310) Thanks [@silaslenihan](https://github.com/silaslenihan)! - #internal Exposed Confirmed state to ChainWriter GetTransactionStatus method + +- [#14157](https://github.com/smartcontractkit/chainlink/pull/14157) [`1852353bbf`](https://github.com/smartcontractkit/chainlink/commit/1852353bbf6ae4726287cb376bc7a323f657c92a) Thanks [@dimriou](https://github.com/dimriou)! - Fix bhe datarace #internal + +- [#14132](https://github.com/smartcontractkit/chainlink/pull/14132) [`2e314cddf0`](https://github.com/smartcontractkit/chainlink/commit/2e314cddf0f4dbd29cad4a43926dc1a5390cc70f) Thanks [@amit-momin](https://github.com/amit-momin)! - Updated ZK overflow detection to skip transactions with non-broadcasted attempts. Delayed detection for zkEVM using the MinAttempts config. Updated XLayer to use the same detection logic as zkEVM. #internal + +- [#13948](https://github.com/smartcontractkit/chainlink/pull/13948) [`3b4c2b58c3`](https://github.com/smartcontractkit/chainlink/commit/3b4c2b58c3ebb04a2261108e758a3419de436a71) Thanks [@chainchad](https://github.com/chainchad)! - Initialize start of v2.16.0 release + +- [#14100](https://github.com/smartcontractkit/chainlink/pull/14100) [`6a9528db29`](https://github.com/smartcontractkit/chainlink/commit/6a9528db29dadd231ec592f10d655e5367301d8f) Thanks [@huangzhen1997](https://github.com/huangzhen1997)! - add error handling when arbitrum sequencer is not accessible #added + +- [#13794](https://github.com/smartcontractkit/chainlink/pull/13794) [`c330defde2`](https://github.com/smartcontractkit/chainlink/commit/c330defde2211aa4a0d8392f867400a829220b2f) Thanks [@Farber98](https://github.com/Farber98)! - remove dependency on FinalityDepth in EVM TXM code. #internal + +- [#14099](https://github.com/smartcontractkit/chainlink/pull/14099) [`1d1af81c51`](https://github.com/smartcontractkit/chainlink/commit/1d1af81c51d78a7e1406d3e182b8740a2ae43c9c) Thanks [@huangzhen1997](https://github.com/huangzhen1997)! - add error handle for gnosis chiado for seen tx #added + +- [#14039](https://github.com/smartcontractkit/chainlink/pull/14039) [`b0e31e08d5`](https://github.com/smartcontractkit/chainlink/commit/b0e31e08d5a635521afc48570a4b2a01e1daa0fb) Thanks [@huangzhen1997](https://github.com/huangzhen1997)! - Improve TXM performance by optimizing Confirmer and Finalizer queries to stop pulling EVM receipt. #internal + +- [#14096](https://github.com/smartcontractkit/chainlink/pull/14096) [`3f0fad643d`](https://github.com/smartcontractkit/chainlink/commit/3f0fad643d554d2445273a67f58974cb6a785ec4) Thanks [@Farber98](https://github.com/Farber98)! - use FilteredLogs in EventBinding GetLatestValue instead of manual filtering. #internal + +- [#14068](https://github.com/smartcontractkit/chainlink/pull/14068) [`6ab3eb5b67`](https://github.com/smartcontractkit/chainlink/commit/6ab3eb5b67739ff88d3c4cf8ea125fd8273bc2b1) Thanks [@asoliman92](https://github.com/asoliman92)! - #added merging core/capabilities/ccip from https://github.com/smartcontractkit/ccip + +- [#14095](https://github.com/smartcontractkit/chainlink/pull/14095) [`aa4e981c8f`](https://github.com/smartcontractkit/chainlink/commit/aa4e981c8f51692ae19f57569260171736a3e4d9) Thanks [@cedric-cordenier](https://github.com/cedric-cordenier)! - #internal Change CapabilityType to string; remove possiblity of a panic + +- [#13957](https://github.com/smartcontractkit/chainlink/pull/13957) [`20dbba8e76`](https://github.com/smartcontractkit/chainlink/commit/20dbba8e76604a2488b0717d53d706ee11b11a9c) Thanks [@amit-momin](https://github.com/amit-momin)! - Added nonce validation immediately after broadcast for Hedera #internal + +- [#13638](https://github.com/smartcontractkit/chainlink/pull/13638) [`2312827156`](https://github.com/smartcontractkit/chainlink/commit/2312827156f24fa4a6e420aec12e5a3aeac81e2b) Thanks [@amit-momin](https://github.com/amit-momin)! - Introduced finalized transaction state. Added a finalizer component to the TXM to mark transactions as finalized. #internal + +- [#14041](https://github.com/smartcontractkit/chainlink/pull/14041) [`8d818ea265`](https://github.com/smartcontractkit/chainlink/commit/8d818ea265ff08887e61ace4f83364a3ee149ef0) Thanks [@amit-momin](https://github.com/amit-momin)! - Added gas limit estimation feature to EVM gas estimators #added + +- [#14165](https://github.com/smartcontractkit/chainlink/pull/14165) [`e76463cfa9`](https://github.com/smartcontractkit/chainlink/commit/e76463cfa9a0fbe6e35a74cbb3f7d63c85efcd88) Thanks [@silaslenihan](https://github.com/silaslenihan)! - #internal Add hexutil Bytes encoding to batchcall data + +- [#11654](https://github.com/smartcontractkit/chainlink/pull/11654) [`bf2b72d164`](https://github.com/smartcontractkit/chainlink/commit/bf2b72d164f8cc714cfbf57df59a3f3bf952b153) Thanks [@reductionista](https://github.com/reductionista)! - #bugfix More robust error handling in LogPoller, including no more misleading CRITICAL errors emitted under non-critical conditions + +- [#13647](https://github.com/smartcontractkit/chainlink/pull/13647) [`a41b353a20`](https://github.com/smartcontractkit/chainlink/commit/a41b353a20d73aa2d3fe3e8e979a0bcacc46fafe) Thanks [@bukata-sa](https://github.com/bukata-sa)! - #added Report new heads as a telemetry to OTI + +- [#13981](https://github.com/smartcontractkit/chainlink/pull/13981) [`6ef1d6eb44`](https://github.com/smartcontractkit/chainlink/commit/6ef1d6eb449ee1dc1d7d10d50990de7da55561ee) Thanks [@amaechiokolobi](https://github.com/amaechiokolobi)! - error handling for Treasure #added + +- [#14057](https://github.com/smartcontractkit/chainlink/pull/14057) [`e0850a6a31`](https://github.com/smartcontractkit/chainlink/commit/e0850a6a31843606015d1c49d52b5a6ad8727378) Thanks [@reductionista](https://github.com/reductionista)! - #bugfix Addresses 2 minor issues with the pruning of LogPoller's db tables: logs not matching any filter will now be pruned, and rows deleted are now properly reported for observability + +- [#14146](https://github.com/smartcontractkit/chainlink/pull/14146) [`d0d2f3046d`](https://github.com/smartcontractkit/chainlink/commit/d0d2f3046d44dc929b97bfff69b2daf4de2d4c8e) Thanks [@Farber98](https://github.com/Farber98)! - remove chainReader from the Relayer struct. #internal + +- [#14016](https://github.com/smartcontractkit/chainlink/pull/14016) [`8b9f2b6b90`](https://github.com/smartcontractkit/chainlink/commit/8b9f2b6b9098e8ec2368773368239106d066e4e3) Thanks [@ilija42](https://github.com/ilija42)! - #internal Add evm Chain Reader GetLatestValue support for filtering on indexed topic types that get hashed. + +- [#14033](https://github.com/smartcontractkit/chainlink/pull/14033) [`375e17b70f`](https://github.com/smartcontractkit/chainlink/commit/375e17b70fe6f17483556a491370e72218896dbc) Thanks [@Farber98](https://github.com/Farber98)! - Change ChainReader Block primitive field from int to string. #internal + +- [#14160](https://github.com/smartcontractkit/chainlink/pull/14160) [`c98feb205d`](https://github.com/smartcontractkit/chainlink/commit/c98feb205d5eef64d71c42b43516a87b83796a1d) Thanks [@ma33r](https://github.com/ma33r)! - Edited the Optimism Stack L1 Oracle to add support for Mantle #added + +- [#13999](https://github.com/smartcontractkit/chainlink/pull/13999) [`2a032e83a5`](https://github.com/smartcontractkit/chainlink/commit/2a032e83a5e09ae128e8c751779a7d1eebb729ea) Thanks [@amit-momin](https://github.com/amit-momin)! - Updated AutoPurge.Threshold and AutoPurge.MinAttempts configs to only be required for heuristic and added content-type header for Scroll API #internal + +- [#14021](https://github.com/smartcontractkit/chainlink/pull/14021) [`bd648bd73d`](https://github.com/smartcontractkit/chainlink/commit/bd648bd73df2a1de91a463a988f4c5b61e74b240) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - Added custom finality calculation for Astar #internal + +- [#14145](https://github.com/smartcontractkit/chainlink/pull/14145) [`567ce229ed`](https://github.com/smartcontractkit/chainlink/commit/567ce229ed434a74b09124feadf3265017ec5313) Thanks [@cedric-cordenier](https://github.com/cedric-cordenier)! - Formalize trigger API #internal + +- [#14127](https://github.com/smartcontractkit/chainlink/pull/14127) [`5e99bdb764`](https://github.com/smartcontractkit/chainlink/commit/5e99bdb764171f584df1fc6e10495c8ec0a3bb63) Thanks [@amit-momin](https://github.com/amit-momin)! - Added client error classification for terminally stuck transactions in the TXM #internal + +- [#14043](https://github.com/smartcontractkit/chainlink/pull/14043) [`55e7c8b505`](https://github.com/smartcontractkit/chainlink/commit/55e7c8b5055c975665a59199d5eda9fa21801a07) Thanks [@asoliman92](https://github.com/asoliman92)! - Added CCIP plugins code from https://github.com/smartcontractkit/ccip/ #added + +### Patch Changes + +- [#14148](https://github.com/smartcontractkit/chainlink/pull/14148) [`0ceb9b5fc6`](https://github.com/smartcontractkit/chainlink/commit/0ceb9b5fc67199b850d16b6a5ab1848327e91a5b) Thanks [@vyzaldysanchez](https://github.com/vyzaldysanchez)! - #bugfix Fixes test flake + +- [#14174](https://github.com/smartcontractkit/chainlink/pull/14174) [`b9a433bff5`](https://github.com/smartcontractkit/chainlink/commit/b9a433bff513223378b8b29c6f694446d00c345b) Thanks [@DeividasK](https://github.com/DeividasK)! - #added Allow workflows to run without external registry configured + +- [#13987](https://github.com/smartcontractkit/chainlink/pull/13987) [`c1bd103e9b`](https://github.com/smartcontractkit/chainlink/commit/c1bd103e9b134a90e0bd5f77b6e54797c7c881a8) Thanks [@KodeyThomas](https://github.com/KodeyThomas)! - #added L3X Config + +- [#14236](https://github.com/smartcontractkit/chainlink/pull/14236) [`0294e1f381`](https://github.com/smartcontractkit/chainlink/commit/0294e1f3813c0643b61af828ec438307dcab3123) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - Fixed deadlock in RPCClient causing CL Node to stop performing RPC requests for the affected chain #bugfix + +- [#14206](https://github.com/smartcontractkit/chainlink/pull/14206) [`621e87538c`](https://github.com/smartcontractkit/chainlink/commit/621e87538c931d5d3996974589dc27a0ab43f758) Thanks [@bukata-sa](https://github.com/bukata-sa)! - #bugfix head reporter non-zero reporting period + +- [#13862](https://github.com/smartcontractkit/chainlink/pull/13862) [`05ef7fdbb1`](https://github.com/smartcontractkit/chainlink/commit/05ef7fdbb115f55a85bcbbc5402350818501e1f5) Thanks [@martin-cll](https://github.com/martin-cll)! - New Mercury v4 report schema #added + +- [#14112](https://github.com/smartcontractkit/chainlink/pull/14112) [`1b584366d6`](https://github.com/smartcontractkit/chainlink/commit/1b584366d6bedc114946d0c8e202e95d031d5d37) Thanks [@giogam](https://github.com/giogam)! - #updated Sync feeds-manager wsrpc proto + +- [#14246](https://github.com/smartcontractkit/chainlink/pull/14246) [`f1bc2e7ad3`](https://github.com/smartcontractkit/chainlink/commit/f1bc2e7ad3610339145930991bf6a3c9ef94fa52) Thanks [@amit-momin](https://github.com/amit-momin)! - Updated gas limit estimation feature to set From address #internal + +- [#14018](https://github.com/smartcontractkit/chainlink/pull/14018) [`82accfff5c`](https://github.com/smartcontractkit/chainlink/commit/82accfff5c445fd1d29a26607234eba73e6b30fd) Thanks [@ettec](https://github.com/ettec)! - #internal fix to keystone e2e test dispatcher to correctly mock duplicate registration error + +- [#13990](https://github.com/smartcontractkit/chainlink/pull/13990) [`98fc8813dd`](https://github.com/smartcontractkit/chainlink/commit/98fc8813dd7f46e86a15fc3e838bbb681f835d0b) Thanks [@flodesi](https://github.com/flodesi)! - #added Add Astar TerminallyUnderpriced error mapping + +- [#14179](https://github.com/smartcontractkit/chainlink/pull/14179) [`633eb41a44`](https://github.com/smartcontractkit/chainlink/commit/633eb41a4467f91506e05e7fda6873c7b34f4731) Thanks [@bukata-sa](https://github.com/bukata-sa)! - #internal log info on missed finalized head instead of returning an error + +- [#14154](https://github.com/smartcontractkit/chainlink/pull/14154) [`a937d5c577`](https://github.com/smartcontractkit/chainlink/commit/a937d5c577d8ba13dc7542a757359339442ae33f) Thanks [@mateusz-sekara](https://github.com/mateusz-sekara)! - Separate price updates schedule for token prices in CCIP #updated + +- [#14185](https://github.com/smartcontractkit/chainlink/pull/14185) [`b563d77dd3`](https://github.com/smartcontractkit/chainlink/commit/b563d77dd30ad96253ae6586c06fd34a66d61936) Thanks [@mateusz-sekara](https://github.com/mateusz-sekara)! - Reporting all the token prices from the job spec for CCIP #updated + +- [#13756](https://github.com/smartcontractkit/chainlink/pull/13756) [`c92a7212ee`](https://github.com/smartcontractkit/chainlink/commit/c92a7212ee77b08c40d62925216e5081278a4e3f) Thanks [@vyzaldysanchez](https://github.com/vyzaldysanchez)! - #updated Adds DB syncing for registry syncer + +- [#13876](https://github.com/smartcontractkit/chainlink/pull/13876) [`15dc74cabd`](https://github.com/smartcontractkit/chainlink/commit/15dc74cabd3a83041ca97df54ea0fbb7e76e2a0a) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - Custom (30s) timeout for Hedera RPC requests with large payloads (SendTransaction, CallContext, etc.) #internal + +- [#14214](https://github.com/smartcontractkit/chainlink/pull/14214) [`32a2ccd2ba`](https://github.com/smartcontractkit/chainlink/commit/32a2ccd2ba4cbe59e46779c82ec35c909141ba2a) Thanks [@ettec](https://github.com/ettec)! - #internal allow gas limit to be specified when submitting transaction + +- [#14092](https://github.com/smartcontractkit/chainlink/pull/14092) [`3399dd6d7f`](https://github.com/smartcontractkit/chainlink/commit/3399dd6d7fee12bd8d099b74397edcc4dc56c11d) Thanks [@cds95](https://github.com/cds95)! - #internal prevent editing whether or not a DON accepts workflows + +- [#13780](https://github.com/smartcontractkit/chainlink/pull/13780) [`af335c1a52`](https://github.com/smartcontractkit/chainlink/commit/af335c1a522769c8c29858d8d6510330af3204cf) Thanks [@samsondav](https://github.com/samsondav)! - Further development of LLO plugin (parallel composition) #wip + +- [#14030](https://github.com/smartcontractkit/chainlink/pull/14030) [`d90bb66934`](https://github.com/smartcontractkit/chainlink/commit/d90bb66934a46bb1c6d376b000d860e1588d91c7) Thanks [@ettec](https://github.com/ettec)! - #internal restore common version to head of develop + +- [#14105](https://github.com/smartcontractkit/chainlink/pull/14105) [`eb31cf7970`](https://github.com/smartcontractkit/chainlink/commit/eb31cf7970bef1615b10b5a734c16879b448f30a) Thanks [@ettec](https://github.com/ettec)! - #internal speed up keystone e2e tests + +- [#14047](https://github.com/smartcontractkit/chainlink/pull/14047) [`d963b0aaac`](https://github.com/smartcontractkit/chainlink/commit/d963b0aaac2117902742cf1d6fc8471e82ae711b) Thanks [@ettec](https://github.com/ettec)! - #internal fix the mock trigger to ensure events are sent + +- [#13853](https://github.com/smartcontractkit/chainlink/pull/13853) [`0f557ae1e0`](https://github.com/smartcontractkit/chainlink/commit/0f557ae1e08040c931f6f3e5c6a96b93b1ca2182) Thanks [@flodesi](https://github.com/flodesi)! - #bugfix Bump BSC PriceMin to 3 gwei to match BSC node's required gas price. This value can be pushed back down to 1 gwei to enable cheaper transactions if the GasPrice field under the Eth.Miner header in the BSC node's config is also pushed down to 1000000000 + +- [#13935](https://github.com/smartcontractkit/chainlink/pull/13935) [`7ec99efc64`](https://github.com/smartcontractkit/chainlink/commit/7ec99efc64832750825f8bc6711fb9794d6e40df) Thanks [@ettec](https://github.com/ettec)! - #internal ensure remote target request hash is deterministic + +- [#14017](https://github.com/smartcontractkit/chainlink/pull/14017) [`1257d33913`](https://github.com/smartcontractkit/chainlink/commit/1257d33913d243c146bccbf4bda67a2bb1c7d5af) Thanks [@DeividasK](https://github.com/DeividasK)! - #internal + +- [#14053](https://github.com/smartcontractkit/chainlink/pull/14053) [`4f0f7802a8`](https://github.com/smartcontractkit/chainlink/commit/4f0f7802a884e831cd76d9578ee5c4a7134034db) Thanks [@DylanTinianov](https://github.com/DylanTinianov)! - Added custom client error messages for Mantle to capture InsufficientEth and Fatal errors. #added + +- [#14059](https://github.com/smartcontractkit/chainlink/pull/14059) [`40f4becb1e`](https://github.com/smartcontractkit/chainlink/commit/40f4becb1eab96920d8bfd59019cdb9358a94122) Thanks [@DeividasK](https://github.com/DeividasK)! - #internal + +- [#14116](https://github.com/smartcontractkit/chainlink/pull/14116) [`7fdc0c8e95`](https://github.com/smartcontractkit/chainlink/commit/7fdc0c8e95c4157dd9e3ce3f9a4efe370554a19c) Thanks [@ettec](https://github.com/ettec)! - #internal ks-404 validate ids before using as seed of transmission schedule + +- [#13993](https://github.com/smartcontractkit/chainlink/pull/13993) [`f5e0bd614a`](https://github.com/smartcontractkit/chainlink/commit/f5e0bd614a6c42d195c4ad74a10f7070970d01d5) Thanks [@DeividasK](https://github.com/DeividasK)! - #internal + +- [#14209](https://github.com/smartcontractkit/chainlink/pull/14209) [`c00ac968e6`](https://github.com/smartcontractkit/chainlink/commit/c00ac968e651fd7b09f473d20f0fe4755ba57367) Thanks [@AnieeG](https://github.com/AnieeG)! - #internal Adding deployment package as new pattern for product deployment/configuration + +- [#14183](https://github.com/smartcontractkit/chainlink/pull/14183) [`35f68c806b`](https://github.com/smartcontractkit/chainlink/commit/35f68c806b10cc0fe4a565293e32e2f5581bfeb5) Thanks [@graham-chainlink](https://github.com/graham-chainlink)! - #bugfix Fix incorrect error handling when registering a new feed manager + +- [#14212](https://github.com/smartcontractkit/chainlink/pull/14212) [`25d2961154`](https://github.com/smartcontractkit/chainlink/commit/25d29611543c3d43484c168e7efc23a7bf83f035) Thanks [@bukata-sa](https://github.com/bukata-sa)! - #internal add head report chain_id + +- [#14066](https://github.com/smartcontractkit/chainlink/pull/14066) [`98b9054397`](https://github.com/smartcontractkit/chainlink/commit/98b90543972d37e4c00196f3f00bcf5f380ea04d) Thanks [@DeividasK](https://github.com/DeividasK)! - #internal + +- [#14014](https://github.com/smartcontractkit/chainlink/pull/14014) [`c2c31c05ac`](https://github.com/smartcontractkit/chainlink/commit/c2c31c05ac3fe19d4df8313af25eb740953b935a) Thanks [@Madalosso](https://github.com/Madalosso)! - #updated Update Polygon configs to match PIP-35 + +- [#14125](https://github.com/smartcontractkit/chainlink/pull/14125) [`8fa8c3a075`](https://github.com/smartcontractkit/chainlink/commit/8fa8c3a07512bb8358abdabc3fdcc8ae310c6c1c) Thanks [@bukata-sa](https://github.com/bukata-sa)! - #bugfix balance shutdown deadlock + +- [#14181](https://github.com/smartcontractkit/chainlink/pull/14181) [`ee57b4f940`](https://github.com/smartcontractkit/chainlink/commit/ee57b4f940b8a9d9d7bba41a74e4757874755f5f) Thanks [@ettec](https://github.com/ettec)! - #internal topeerid should validate []byte length + +- [#14074](https://github.com/smartcontractkit/chainlink/pull/14074) [`a865709ea1`](https://github.com/smartcontractkit/chainlink/commit/a865709ea18bfc792db758b60de6f03e953f141f) Thanks [@mateusz-sekara](https://github.com/mateusz-sekara)! - Simplify how token and gas prices are stored in the database - user upsert instead of insert/delete flow #db_update + +- [#14050](https://github.com/smartcontractkit/chainlink/pull/14050) [`537d2ec1ad`](https://github.com/smartcontractkit/chainlink/commit/537d2ec1ad846898f820874442c3f69915096bad) Thanks [@ettec](https://github.com/ettec)! - #internal fix data race in syncer launcher + +- [#13970](https://github.com/smartcontractkit/chainlink/pull/13970) [`cefbb09797`](https://github.com/smartcontractkit/chainlink/commit/cefbb09797249309ac18e4ef81147e30f7c24360) Thanks [@cds95](https://github.com/cds95)! - #internal prevent reentrancy when configuring DON in Capabilities Registry + +- [#13907](https://github.com/smartcontractkit/chainlink/pull/13907) [`1eaf5e087a`](https://github.com/smartcontractkit/chainlink/commit/1eaf5e087a5ac204e0b472e1c307722887104678) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - Added new health check that ensures RPC provides new finalized heads at least every `NoNewFinalizedHeadsThreshold` #added + ## 2.15.0 - 2024-08-21 ### Minor Changes diff --git a/package.json b/package.json index e8bda4e61a..2e5bd3899a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chainlink", - "version": "2.15.0", + "version": "2.16.0", "description": "node of the decentralized oracle network, bridging on and off-chain computation", "main": "index.js", "scripts": { From 2761cd5bc5ed91bc17d4d67265ddc8fa03b84540 Mon Sep 17 00:00:00 2001 From: Juan Farber Date: Wed, 4 Sep 2024 17:16:00 -0300 Subject: [PATCH 290/432] [BCI-3988] - FilteredLogs receive []Expression instead of whole KeyFilter (#14109) * FilteredLogs receive []Expression instead of whole KeyFilter * remove key from query.Where KeyFilter creation * add changeset * remove brackets from changeset * fix usage * fix comment lint * remove todo * refactor based on comments * add where func inside logpoller without key * fix reference --- .changeset/brown-geese-boil.md | 5 + core/chains/evm/logpoller/disabled.go | 2 +- core/chains/evm/logpoller/log_poller.go | 23 +++- core/chains/evm/logpoller/log_poller_test.go | 38 ++++++ core/chains/evm/logpoller/mocks/log_poller.go | 16 +-- core/chains/evm/logpoller/observability.go | 2 +- core/chains/evm/logpoller/orm.go | 7 +- core/chains/evm/logpoller/orm_test.go | 110 ++++++++---------- .../internal/ccipdata/v1_0_0/commit_store.go | 3 +- .../internal/ccipdata/v1_2_0/commit_store.go | 3 +- core/services/relay/evm/event_binding.go | 5 +- 11 files changed, 131 insertions(+), 83 deletions(-) create mode 100644 .changeset/brown-geese-boil.md diff --git a/.changeset/brown-geese-boil.md b/.changeset/brown-geese-boil.md new file mode 100644 index 0000000000..fa7f65f733 --- /dev/null +++ b/.changeset/brown-geese-boil.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +FilteredLogs receive Expression instead of whole KeyFilter. #internal diff --git a/core/chains/evm/logpoller/disabled.go b/core/chains/evm/logpoller/disabled.go index f30837bcfe..a29dd5ea11 100644 --- a/core/chains/evm/logpoller/disabled.go +++ b/core/chains/evm/logpoller/disabled.go @@ -118,7 +118,7 @@ func (d disabled) LogsDataWordBetween(ctx context.Context, eventSig common.Hash, return nil, ErrDisabled } -func (d disabled) FilteredLogs(_ context.Context, _ query.KeyFilter, _ query.LimitAndSort, _ string) ([]Log, error) { +func (d disabled) FilteredLogs(_ context.Context, _ []query.Expression, _ query.LimitAndSort, _ string) ([]Log, error) { return nil, ErrDisabled } diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index a4560c967c..2a551c1237 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -69,7 +69,7 @@ type LogPoller interface { LogsDataWordBetween(ctx context.Context, eventSig common.Hash, address common.Address, wordIndexMin, wordIndexMax int, wordValue common.Hash, confs evmtypes.Confirmations) ([]Log, error) // chainlink-common query filtering - FilteredLogs(ctx context.Context, filter query.KeyFilter, limitAndSort query.LimitAndSort, queryName string) ([]Log, error) + FilteredLogs(ctx context.Context, filter []query.Expression, limitAndSort query.LimitAndSort, queryName string) ([]Log, error) } type LogPollerTest interface { @@ -1518,6 +1518,25 @@ func EvmWord(i uint64) common.Hash { return common.BytesToHash(b) } -func (lp *logPoller) FilteredLogs(ctx context.Context, queryFilter query.KeyFilter, limitAndSort query.LimitAndSort, queryName string) ([]Log, error) { +func (lp *logPoller) FilteredLogs(ctx context.Context, queryFilter []query.Expression, limitAndSort query.LimitAndSort, queryName string) ([]Log, error) { return lp.orm.FilteredLogs(ctx, queryFilter, limitAndSort, queryName) } + +// Where is a query.Where wrapper that ignores the Key and returns a slice of query.Expression rather than query.KeyFilter. +// If no expressions are provided, or an error occurs, an empty slice is returned. +func Where(expressions ...query.Expression) ([]query.Expression, error) { + filter, err := query.Where( + "", + expressions..., + ) + + if err != nil { + return []query.Expression{}, err + } + + if filter.Expressions == nil { + return []query.Expression{}, nil + } + + return filter.Expressions, nil +} diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index 73302877f9..6ad76030bb 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -26,6 +26,8 @@ import ( "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/types/query" + "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils" htMocks "github.com/smartcontractkit/chainlink/v2/common/headtracker/mocks" @@ -2091,3 +2093,39 @@ func TestFindLCA(t *testing.T) { }) } } + +func TestWhere(t *testing.T) { + address := common.HexToAddress("0x1234567890abcdef1234567890abcdef12345678") + eventSig := common.HexToHash("0xabcdef1234567890abcdef1234567890abcdef1234") + ts := time.Now() + + expr1 := logpoller.NewAddressFilter(address) + expr2 := logpoller.NewEventSigFilter(eventSig) + expr3 := query.Timestamp(uint64(ts.Unix()), primitives.Gte) + expr4 := logpoller.NewConfirmationsFilter(evmtypes.Confirmations(0)) + + t.Run("Valid combination of filters", func(t *testing.T) { + result, err := logpoller.Where(expr1, expr2, expr3, expr4) + assert.NoError(t, err) + assert.Equal(t, []query.Expression{expr1, expr2, expr3, expr4}, result) + }) + + t.Run("No expressions (should return empty slice)", func(t *testing.T) { + result, err := logpoller.Where() + assert.NoError(t, err) + assert.Equal(t, []query.Expression{}, result) + }) + + t.Run("Invalid boolean expression", func(t *testing.T) { + invalidExpr := query.Expression{ + BoolExpression: query.BoolExpression{ + Expressions: []query.Expression{}, + }, + } + + result, err := logpoller.Where(invalidExpr) + assert.Error(t, err) + assert.EqualError(t, err, "all boolean expressions should have at least 2 expressions") + assert.Equal(t, []query.Expression{}, result) + }) +} diff --git a/core/chains/evm/logpoller/mocks/log_poller.go b/core/chains/evm/logpoller/mocks/log_poller.go index 4ce68839d1..9ae4d9767c 100644 --- a/core/chains/evm/logpoller/mocks/log_poller.go +++ b/core/chains/evm/logpoller/mocks/log_poller.go @@ -124,7 +124,7 @@ func (_c *LogPoller_DeleteLogsAndBlocksAfter_Call) RunAndReturn(run func(context } // FilteredLogs provides a mock function with given fields: ctx, filter, limitAndSort, queryName -func (_m *LogPoller) FilteredLogs(ctx context.Context, filter query.KeyFilter, limitAndSort query.LimitAndSort, queryName string) ([]logpoller.Log, error) { +func (_m *LogPoller) FilteredLogs(ctx context.Context, filter []query.Expression, limitAndSort query.LimitAndSort, queryName string) ([]logpoller.Log, error) { ret := _m.Called(ctx, filter, limitAndSort, queryName) if len(ret) == 0 { @@ -133,10 +133,10 @@ func (_m *LogPoller) FilteredLogs(ctx context.Context, filter query.KeyFilter, l var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(context.Context, query.KeyFilter, query.LimitAndSort, string) ([]logpoller.Log, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, []query.Expression, query.LimitAndSort, string) ([]logpoller.Log, error)); ok { return rf(ctx, filter, limitAndSort, queryName) } - if rf, ok := ret.Get(0).(func(context.Context, query.KeyFilter, query.LimitAndSort, string) []logpoller.Log); ok { + if rf, ok := ret.Get(0).(func(context.Context, []query.Expression, query.LimitAndSort, string) []logpoller.Log); ok { r0 = rf(ctx, filter, limitAndSort, queryName) } else { if ret.Get(0) != nil { @@ -144,7 +144,7 @@ func (_m *LogPoller) FilteredLogs(ctx context.Context, filter query.KeyFilter, l } } - if rf, ok := ret.Get(1).(func(context.Context, query.KeyFilter, query.LimitAndSort, string) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, []query.Expression, query.LimitAndSort, string) error); ok { r1 = rf(ctx, filter, limitAndSort, queryName) } else { r1 = ret.Error(1) @@ -160,16 +160,16 @@ type LogPoller_FilteredLogs_Call struct { // FilteredLogs is a helper method to define mock.On call // - ctx context.Context -// - filter query.KeyFilter +// - filter []query.Expression // - limitAndSort query.LimitAndSort // - queryName string func (_e *LogPoller_Expecter) FilteredLogs(ctx interface{}, filter interface{}, limitAndSort interface{}, queryName interface{}) *LogPoller_FilteredLogs_Call { return &LogPoller_FilteredLogs_Call{Call: _e.mock.On("FilteredLogs", ctx, filter, limitAndSort, queryName)} } -func (_c *LogPoller_FilteredLogs_Call) Run(run func(ctx context.Context, filter query.KeyFilter, limitAndSort query.LimitAndSort, queryName string)) *LogPoller_FilteredLogs_Call { +func (_c *LogPoller_FilteredLogs_Call) Run(run func(ctx context.Context, filter []query.Expression, limitAndSort query.LimitAndSort, queryName string)) *LogPoller_FilteredLogs_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(query.KeyFilter), args[2].(query.LimitAndSort), args[3].(string)) + run(args[0].(context.Context), args[1].([]query.Expression), args[2].(query.LimitAndSort), args[3].(string)) }) return _c } @@ -179,7 +179,7 @@ func (_c *LogPoller_FilteredLogs_Call) Return(_a0 []logpoller.Log, _a1 error) *L return _c } -func (_c *LogPoller_FilteredLogs_Call) RunAndReturn(run func(context.Context, query.KeyFilter, query.LimitAndSort, string) ([]logpoller.Log, error)) *LogPoller_FilteredLogs_Call { +func (_c *LogPoller_FilteredLogs_Call) RunAndReturn(run func(context.Context, []query.Expression, query.LimitAndSort, string) ([]logpoller.Log, error)) *LogPoller_FilteredLogs_Call { _c.Call.Return(run) return _c } diff --git a/core/chains/evm/logpoller/observability.go b/core/chains/evm/logpoller/observability.go index 782307e7d0..e0ed0cc478 100644 --- a/core/chains/evm/logpoller/observability.go +++ b/core/chains/evm/logpoller/observability.go @@ -262,7 +262,7 @@ func (o *ObservedORM) SelectIndexedLogsTopicRange(ctx context.Context, address c }) } -func (o *ObservedORM) FilteredLogs(ctx context.Context, filter query.KeyFilter, limitAndSort query.LimitAndSort, queryName string) ([]Log, error) { +func (o *ObservedORM) FilteredLogs(ctx context.Context, filter []query.Expression, limitAndSort query.LimitAndSort, queryName string) ([]Log, error) { return withObservedQueryAndResults(o, queryName, func() ([]Log, error) { return o.ORM.FilteredLogs(ctx, filter, limitAndSort, queryName) }) diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index 22870efccf..1c119c9f9a 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -64,7 +64,7 @@ type ORM interface { SelectLogsDataWordBetween(ctx context.Context, address common.Address, eventSig common.Hash, wordIndexMin int, wordIndexMax int, wordValue common.Hash, confs evmtypes.Confirmations) ([]Log, error) // FilteredLogs accepts chainlink-common filtering DSL. - FilteredLogs(ctx context.Context, filter query.KeyFilter, limitAndSort query.LimitAndSort, queryName string) ([]Log, error) + FilteredLogs(ctx context.Context, filter []query.Expression, limitAndSort query.LimitAndSort, queryName string) ([]Log, error) } type DSORM struct { @@ -964,9 +964,8 @@ func (o *DSORM) SelectIndexedLogsWithSigsExcluding(ctx context.Context, sigA, si return logs, nil } -// TODO flaky BCF-3258 -func (o *DSORM) FilteredLogs(ctx context.Context, filter query.KeyFilter, limitAndSort query.LimitAndSort, _ string) ([]Log, error) { - qs, args, err := (&pgDSLParser{}).buildQuery(o.chainID, filter.Expressions, limitAndSort) +func (o *DSORM) FilteredLogs(ctx context.Context, filter []query.Expression, limitAndSort query.LimitAndSort, _ string) ([]Log, error) { + qs, args, err := (&pgDSLParser{}).buildQuery(o.chainID, filter, limitAndSort) if err != nil { return nil, err } diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index ab8d126e10..f5f44acf3d 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -631,7 +631,7 @@ func TestORM_IndexedLogs(t *testing.T) { require.Equal(t, 1, len(lgs)) assert.Equal(t, logpoller.EvmWord(1).Bytes(), lgs[0].GetTopics()[1].Bytes()) - lgs, err = o1.FilteredLogs(ctx, standardFilter(1, []uint64{1}), limiter, "") + lgs, err = o1.FilteredLogs(ctx, standardFilter(1, []uint64{1}).Expressions, limiter, "") require.NoError(t, err) require.Equal(t, 1, len(lgs)) assert.Equal(t, logpoller.EvmWord(1).Bytes(), lgs[0].GetTopics()[1].Bytes()) @@ -640,19 +640,17 @@ func TestORM_IndexedLogs(t *testing.T) { require.NoError(t, err) assert.Equal(t, 2, len(lgs)) - lgs, err = o1.FilteredLogs(ctx, standardFilter(1, []uint64{1, 2}), limiter, "") + lgs, err = o1.FilteredLogs(ctx, standardFilter(1, []uint64{1, 2}).Expressions, limiter, "") require.NoError(t, err) assert.Equal(t, 2, len(lgs)) - blockRangeFilter := func(start, end string, topicIdx uint64, topicValues []uint64) query.KeyFilter { - return query.KeyFilter{ - Expressions: []query.Expression{ - logpoller.NewAddressFilter(addr), - logpoller.NewEventSigFilter(eventSig), - filtersForTopics(topicIdx, topicValues), - query.Block(start, primitives.Gte), - query.Block(end, primitives.Lte), - }, + blockRangeFilter := func(start, end string, topicIdx uint64, topicValues []uint64) []query.Expression { + return []query.Expression{ + logpoller.NewAddressFilter(addr), + logpoller.NewEventSigFilter(eventSig), + filtersForTopics(topicIdx, topicValues), + query.Block(start, primitives.Gte), + query.Block(end, primitives.Lte), } } @@ -711,23 +709,21 @@ func TestORM_IndexedLogs(t *testing.T) { }, } - lgs, err = o1.FilteredLogs(ctx, filter, limiter, "") + lgs, err = o1.FilteredLogs(ctx, filter.Expressions, limiter, "") require.NoError(t, err) assert.Equal(t, 2, len(lgs)) - rangeFilter := func(topicIdx uint64, min, max uint64) query.KeyFilter { - return query.KeyFilter{ - Expressions: []query.Expression{ - logpoller.NewAddressFilter(addr), - logpoller.NewEventSigFilter(eventSig), - logpoller.NewEventByTopicFilter(topicIdx, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(min).Hex(), Operator: primitives.Gte}, - }), - logpoller.NewEventByTopicFilter(topicIdx, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(max).Hex(), Operator: primitives.Lte}, - }), - query.Confidence(primitives.Unconfirmed), - }, + rangeFilter := func(topicIdx uint64, min, max uint64) []query.Expression { + return []query.Expression{ + logpoller.NewAddressFilter(addr), + logpoller.NewEventSigFilter(eventSig), + logpoller.NewEventByTopicFilter(topicIdx, []primitives.ValueComparator{ + {Value: logpoller.EvmWord(min).Hex(), Operator: primitives.Gte}, + }), + logpoller.NewEventByTopicFilter(topicIdx, []primitives.ValueComparator{ + {Value: logpoller.EvmWord(max).Hex(), Operator: primitives.Lte}, + }), + query.Confidence(primitives.Unconfirmed), } } @@ -835,7 +831,7 @@ func TestORM_SelectIndexedLogsByTxHash(t *testing.T) { }, } - retrievedLogs, err = o1.FilteredLogs(ctx, filter, limiter, "") + retrievedLogs, err = o1.FilteredLogs(ctx, filter.Expressions, limiter, "") require.NoError(t, err) require.Equal(t, 2, len(retrievedLogs)) @@ -876,19 +872,17 @@ func TestORM_DataWords(t *testing.T) { }, })) - wordFilter := func(wordIdx uint8, word1, word2 uint64) query.KeyFilter { - return query.KeyFilter{ - Expressions: []query.Expression{ - logpoller.NewAddressFilter(addr), - logpoller.NewEventSigFilter(eventSig), - logpoller.NewEventByWordFilter(eventSig, wordIdx, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(word1).Hex(), Operator: primitives.Gte}, - }), - logpoller.NewEventByWordFilter(eventSig, wordIdx, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(word2).Hex(), Operator: primitives.Lte}, - }), - query.Confidence(primitives.Unconfirmed), - }, + wordFilter := func(wordIdx uint8, word1, word2 uint64) []query.Expression { + return []query.Expression{ + logpoller.NewAddressFilter(addr), + logpoller.NewEventSigFilter(eventSig), + logpoller.NewEventByWordFilter(eventSig, wordIdx, []primitives.ValueComparator{ + {Value: logpoller.EvmWord(word1).Hex(), Operator: primitives.Gte}, + }), + logpoller.NewEventByWordFilter(eventSig, wordIdx, []primitives.ValueComparator{ + {Value: logpoller.EvmWord(word2).Hex(), Operator: primitives.Lte}, + }), + query.Confidence(primitives.Unconfirmed), } } @@ -947,15 +941,13 @@ func TestORM_DataWords(t *testing.T) { require.NoError(t, err) assert.Equal(t, 2, len(lgs)) - filter := query.KeyFilter{ - Expressions: []query.Expression{ - logpoller.NewAddressFilter(addr), - logpoller.NewEventSigFilter(eventSig), - logpoller.NewEventByWordFilter(eventSig, 0, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(1).Hex(), Operator: primitives.Gte}, - }), - query.Confidence(primitives.Unconfirmed), - }, + filter := []query.Expression{ + logpoller.NewAddressFilter(addr), + logpoller.NewEventSigFilter(eventSig), + logpoller.NewEventByWordFilter(eventSig, 0, []primitives.ValueComparator{ + {Value: logpoller.EvmWord(1).Hex(), Operator: primitives.Gte}, + }), + query.Confidence(primitives.Unconfirmed), } lgs, err = o1.FilteredLogs(ctx, filter, limiter, "") @@ -1099,7 +1091,7 @@ func TestORM_SelectLogsWithSigsByBlockRangeFilter(t *testing.T) { }) assertion(t, logs, err, startBlock, endBlock) - logs, err = th.ORM.FilteredLogs(ctx, filter([]common.Hash{topic, topic2}, strconv.Itoa(int(startBlock)), strconv.Itoa(int(endBlock))), limiter, "") + logs, err = th.ORM.FilteredLogs(ctx, filter([]common.Hash{topic, topic2}, strconv.Itoa(int(startBlock)), strconv.Itoa(int(endBlock))).Expressions, limiter, "") assertion(t, logs, err, startBlock, endBlock) } @@ -1161,14 +1153,12 @@ func TestLogPoller_Logs(t *testing.T) { assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000005", lgs[4].BlockHash.String()) assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000005", lgs[5].BlockHash.String()) - logFilter := func(start, end string, address common.Address) query.KeyFilter { - return query.KeyFilter{ - Expressions: []query.Expression{ - logpoller.NewAddressFilter(address), - logpoller.NewEventSigFilter(event1), - query.Block(start, primitives.Gte), - query.Block(end, primitives.Lte), - }, + logFilter := func(start, end string, address common.Address) []query.Expression { + return []query.Expression{ + logpoller.NewAddressFilter(address), + logpoller.NewEventSigFilter(event1), + query.Block(start, primitives.Gte), + query.Block(end, primitives.Lte), } } @@ -1722,7 +1712,7 @@ func TestSelectLogsCreatedAfter(t *testing.T) { assertion(t, logs, err, tt.expectedLogs) - logs, err = th.ORM.FilteredLogs(ctx, filter(tt.after, tt.confs, 0, nil), limiter, "") + logs, err = th.ORM.FilteredLogs(ctx, filter(tt.after, tt.confs, 0, nil).Expressions, limiter, "") assertion(t, logs, err, tt.expectedLogs) }) @@ -1735,7 +1725,7 @@ func TestSelectLogsCreatedAfter(t *testing.T) { assertion(t, logs, err, tt.expectedLogs) - logs, err = th.ORM.FilteredLogs(ctx, filter(tt.after, tt.confs, 1, []common.Hash{event}), limiter, "") + logs, err = th.ORM.FilteredLogs(ctx, filter(tt.after, tt.confs, 1, []common.Hash{event}).Expressions, limiter, "") assertion(t, logs, err, tt.expectedLogs) }) @@ -1991,7 +1981,7 @@ func TestSelectLogsDataWordBetween(t *testing.T) { assertion(t, logs, err, tt.expectedLogs) - logs, err = th.ORM.FilteredLogs(ctx, wordFilter(tt.wordValue), limiter, "") + logs, err = th.ORM.FilteredLogs(ctx, wordFilter(tt.wordValue).Expressions, limiter, "") assertion(t, logs, err, tt.expectedLogs) }) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go index f6e957746e..f53e44a289 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0/commit_store.go @@ -337,8 +337,7 @@ func (c *CommitStore) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, return nil, err } - reportsQuery, err := query.Where( - c.address.String(), + reportsQuery, err := logpoller.Where( logpoller.NewAddressFilter(c.address), logpoller.NewEventSigFilter(c.reportAcceptedSig), query.Timestamp(uint64(ts.Unix()), primitives.Gte), diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go index 2b87a7913a..d330cab3a5 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0/commit_store.go @@ -349,8 +349,7 @@ func (c *CommitStore) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, return nil, err } - reportsQuery, err := query.Where( - c.address.String(), + reportsQuery, err := logpoller.Where( logpoller.NewAddressFilter(c.address), logpoller.NewEventSigFilter(c.reportAcceptedSig), query.Timestamp(uint64(ts.Unix()), primitives.Gte), diff --git a/core/services/relay/evm/event_binding.go b/core/services/relay/evm/event_binding.go index 7b62d862b3..ae67fae9fc 100644 --- a/core/services/relay/evm/event_binding.go +++ b/core/services/relay/evm/event_binding.go @@ -169,7 +169,7 @@ func (e *eventBinding) QueryKey(ctx context.Context, filter query.KeyFilter, lim } remapped.Expressions = append(defaultExpressions, remapped.Expressions...) - logs, err := e.lp.FilteredLogs(ctx, remapped, limitAndSort, e.contractName+"-"+e.address.String()+"-"+e.eventName) + logs, err := e.lp.FilteredLogs(ctx, remapped.Expressions, limitAndSort, e.contractName+"-"+e.address.String()+"-"+e.eventName) if err != nil { return nil, err } @@ -229,8 +229,7 @@ func (e *eventBinding) getLatestValueWithFilters( // Create limiter and filter for the query. limiter := query.NewLimitAndSort(query.CountLimit(1), query.NewSortBySequence(query.Desc)) - filter, err := query.Where( - "", + filter, err := logpoller.Where( logpoller.NewAddressFilter(e.address), logpoller.NewEventSigFilter(e.hash), logpoller.NewConfirmationsFilter(confs), From c97838d904aa7ac07fc4a48cd05db4c4859e5355 Mon Sep 17 00:00:00 2001 From: Aaron Lu <50029043+aalu1418@users.noreply.github.com> Date: Wed, 4 Sep 2024 16:28:03 -0600 Subject: [PATCH 291/432] bump solana e2e tests (#14332) * bump solana e2e tests * adjust to use secrets passed via env * bump to merged commit --- .github/workflows/integration-tests.yml | 4 +++- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 9 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 7e2b5bc7c4..e3a0a68280 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -659,7 +659,6 @@ jobs: run: | # https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md cat << EOF > config.toml [ChainlinkImage] - image="${{ env.CHAINLINK_IMAGE }}" version="${{ inputs.evm-ref || github.sha }}" [Common] user="${{ github.actor }}" @@ -696,6 +695,9 @@ jobs: run_setup: false go_coverage_src_dir: /var/tmp/go-coverage go_coverage_dest_dir: ${{ github.workspace }}/.covdata + env: + E2E_TEST_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} + E2E_TEST_SOLANA_SECRET: thisisatestingonlysecret - name: Upload Coverage Data uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 0ca0d83225..eede7f478c 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -274,7 +274,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index f30b5b4ced..d7c3fee4f1 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1198,8 +1198,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e401698 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a h1:0zbG9reudNAJC/Rwe3tYX7kshVtOEXXAhk0uLg/62Y4= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= diff --git a/go.mod b/go.mod index 4173b33c8a..7c2ac71a61 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 diff --git a/go.sum b/go.sum index d50ac5d0f2..aae278aadd 100644 --- a/go.sum +++ b/go.sum @@ -1155,8 +1155,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e401698 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a h1:0zbG9reudNAJC/Rwe3tYX7kshVtOEXXAhk0uLg/62Y4= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 7e8f0fc9d3..b75967fa4b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -406,7 +406,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 76cab97718..3d5f8f9032 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1433,8 +1433,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e401698 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a h1:0zbG9reudNAJC/Rwe3tYX7kshVtOEXXAhk0uLg/62Y4= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/chainlink-testing-framework v1.35.0 h1:5FzS4YOwzjRe59VMM7MmEyjgJCq4/aXR1fzdEJEPiL8= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index a56f535c34..383821cd23 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -396,7 +396,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index d9ffd17aa4..616403adf5 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1403,8 +1403,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e401698 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f h1:b0Ifwk7eK3fwJ0R69Ovhv5XvZ1/TUAfHkU5Jp7wbNZ0= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240821170223-a2f5c39f457f/go.mod h1:Ml88TJTwZCj6yHDkAEN/EhxVutzSlk+kDZgfibRIqF0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a h1:0zbG9reudNAJC/Rwe3tYX7kshVtOEXXAhk0uLg/62Y4= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/chainlink-testing-framework v1.35.0 h1:5FzS4YOwzjRe59VMM7MmEyjgJCq4/aXR1fzdEJEPiL8= From 9ce13a13a1c03cdab26896e37b25c9e247ef6095 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Thu, 5 Sep 2024 09:32:44 +0200 Subject: [PATCH 292/432] bump Seth to v1.50.1 (#14342) --- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index b75967fa4b..ee2d0ad2d1 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -41,7 +41,7 @@ require ( github.com/smartcontractkit/chainlink-testing-framework v1.35.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 - github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 + github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 3d5f8f9032..932d85d08b 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1443,8 +1443,8 @@ github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 h1:1/r1wQ github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 h1:eHsvf2SklyyZ5fTHJIsIZ3eUnfO0TJU2BSZ7j8kLvzM= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 h1:GRAAvtn2+jhO/8Z3lig10eQXVcV4VuOI4UgCyoPdJBg= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 383821cd23..6df47603b3 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -18,7 +18,7 @@ require ( github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 github.com/smartcontractkit/chainlink-testing-framework v1.35.0 - github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 + github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 616403adf5..53977f3ab3 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1413,8 +1413,8 @@ github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.2024080 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 h1:eHsvf2SklyyZ5fTHJIsIZ3eUnfO0TJU2BSZ7j8kLvzM= github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1 h1:GRAAvtn2+jhO/8Z3lig10eQXVcV4VuOI4UgCyoPdJBg= -github.com/smartcontractkit/chainlink-testing-framework/seth v1.2.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= From c83c68735bdee6bbd8510733b7415797cd08ecbd Mon Sep 17 00:00:00 2001 From: Makram Date: Thu, 5 Sep 2024 16:58:11 +0300 Subject: [PATCH 293/432] [CCIP-3360] contracts/src/v0.8/ccip: merge latest changes from the ccip repo (#14345) * Misc golfs and fixes (#1402) Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> * Increase max signers (#1405) Improve tests and error checks --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> * rename CCIPSendRequested to CCIPMessageSent (#1409) * Skip report execution on curse (#1408) ## Motivation The goal of this PR is to remove reverts on lane cursing for DON execution transactions. If a lane is cursed, reverting will cause the whole execution transaction to fail so any execution reports for other lanes will be blocked. ## Solution For DON execution transactions the behavior is now to skip the report and emit a `SkippedReportExecution`. For manual execution we still revert, otherwise the transaction will silently fail for the users. --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> * remove bootstrapP2PIds (#1388) ## Motivation Bootstrap P2P IDs are no longer needed in the OCR config in CCIPConfig. See #1348's description for more details. ## Solution Remove bootstrap P2P IDs from the OCR config in CCIPConfig. ## Related PRs https://github.com/smartcontractkit/chainlink-ccip/pull/89 * fixes * Integrate RMNRemote and OffRamp (#1360) Remove the requirement for self-transmitted RMN blessings Allow the commit DON to include RMN blessings at commitment time This PR has a dependency on changes to [chainlink-ccip](https://github.com/smartcontractkit/chainlink-ccip/pull/84) --------- Co-authored-by: Makram * contracts/scripts: reduce offramp optimizations (#1414) ## Motivation The offramp was failing to deploy due to too many optimizations causing a max code size exceeded error. ## Solution Reduce the number of optimizations by 1. Also, add a test that deploys v1.6 contracts and ensures that they are deployable on the simulated backend. * more fixes * remove isBlessed from contract reader cfg * deploy RMNRemote instead of MockRMN * bump chainlink-ccip * bump chainlink-ccip and add changesets --------- Co-authored-by: Rens Rooimans Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> Co-authored-by: Suryansh <39276431+0xsuryansh@users.noreply.github.com> Co-authored-by: Ryan <80392855+RayXpub@users.noreply.github.com> Co-authored-by: Ryan Hall --- .changeset/plenty-glasses-rest.md | 5 + contracts/.changeset/flat-turkeys-rule.md | 5 + contracts/.solhintignore | 3 +- contracts/gas-snapshots/ccip.gas-snapshot | 815 +++++++++-------- contracts/package.json | 2 +- contracts/pnpm-lock.yaml | 22 +- .../scripts/native_solc_compile_all_ccip | 3 +- contracts/src/v0.8/ccip/FeeQuoter.sol | 6 +- .../src/v0.8/ccip/capability/CCIPConfig.sol | 74 +- .../capability/libraries/CCIPConfigTypes.sol | 2 - contracts/src/v0.8/ccip/interfaces/IRMNV2.sol | 22 + .../src/v0.8/ccip/libraries/Internal.sol | 10 + contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol | 33 +- contracts/src/v0.8/ccip/offRamp/OffRamp.sol | 122 +-- contracts/src/v0.8/ccip/onRamp/OnRamp.sol | 35 +- contracts/src/v0.8/ccip/{ => rmn}/RMNHome.sol | 2 +- .../src/v0.8/ccip/{ => rmn}/RMNRemote.sol | 41 +- contracts/src/v0.8/ccip/test/BaseTest.t.sol | 21 + .../src/v0.8/ccip/test/NonceManager.t.sol | 8 +- .../MultiOnRampTokenPoolReentrancy.t.sol | 4 +- .../ccip/test/capability/CCIPConfig.t.sol | 400 ++------- .../v0.8/ccip/test/e2e/MultiRampsEnd2End.sol | 28 +- .../ccip/test/helpers/CCIPReaderTester.sol | 6 +- .../v0.8/ccip/test/ocr/MultiOCR3Base.t.sol | 4 +- .../src/v0.8/ccip/test/offRamp/OffRamp.t.sol | 608 +++++++------ .../v0.8/ccip/test/offRamp/OffRampSetup.t.sol | 51 +- .../src/v0.8/ccip/test/onRamp/OnRamp.t.sol | 35 +- .../v0.8/ccip/test/onRamp/OnRampSetup.t.sol | 4 +- .../ccipreader/ccipreader_test.go | 20 +- .../ccip/ccip_integration_tests/helpers.go | 9 +- .../integrationhelpers/integration_helpers.go | 1 - .../ccip_integration_tests/ping_pong_test.go | 4 +- core/capabilities/ccip/ccipevm/commitcodec.go | 16 +- .../ccip/ccipevm/commitcodec_test.go | 24 + .../ccip/configs/evm/contract_reader.go | 10 +- .../ccip/deployment_test/deployment_test.go | 97 ++ .../ccip/generated/ccip_config/ccip_config.go | 5 +- .../ccip_reader_tester/ccip_reader_tester.go | 99 +- .../ccip/generated/fee_quoter/fee_quoter.go | 2 +- .../multi_ocr3_helper/multi_ocr3_helper.go | 2 +- .../ocr3_config_encoder.go | 3 +- .../ccip/generated/offramp/offramp.go | 209 +++-- .../ccip/generated/onramp/onramp.go | 56 +- .../generated/report_codec/report_codec.go | 35 +- .../ccip/generated/rmn_remote/rmn_remote.go | 842 ++++++++++++++++++ ...rapper-dependency-versions-do-not-edit.txt | 17 +- core/gethwrappers/ccip/go_generate.go | 1 + core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- .../ccip/changeset/2_initial_deploy_test.go | 4 +- integration-tests/deployment/ccip/deploy.go | 29 +- .../deployment/ccip/deploy_home_chain.go | 1 - integration-tests/deployment/ccip/state.go | 10 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 59 files changed, 2373 insertions(+), 1518 deletions(-) create mode 100644 .changeset/plenty-glasses-rest.md create mode 100644 contracts/.changeset/flat-turkeys-rule.md create mode 100644 contracts/src/v0.8/ccip/interfaces/IRMNV2.sol rename contracts/src/v0.8/ccip/{ => rmn}/RMNHome.sol (98%) rename contracts/src/v0.8/ccip/{ => rmn}/RMNRemote.sol (79%) create mode 100644 core/gethwrappers/ccip/deployment_test/deployment_test.go create mode 100644 core/gethwrappers/ccip/generated/rmn_remote/rmn_remote.go diff --git a/.changeset/plenty-glasses-rest.md b/.changeset/plenty-glasses-rest.md new file mode 100644 index 0000000000..fd06cbd997 --- /dev/null +++ b/.changeset/plenty-glasses-rest.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal merge ccip contracts diff --git a/contracts/.changeset/flat-turkeys-rule.md b/contracts/.changeset/flat-turkeys-rule.md new file mode 100644 index 0000000000..2dedbe653e --- /dev/null +++ b/contracts/.changeset/flat-turkeys-rule.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +#internal merge ccip contracts diff --git a/contracts/.solhintignore b/contracts/.solhintignore index 446f91f84f..5ae38e28d9 100644 --- a/contracts/.solhintignore +++ b/contracts/.solhintignore @@ -43,5 +43,4 @@ ./node_modules/ # Ignore RMN contracts temporarily -./src/v0.8/ccip/RMNRemote.sol -./src/v0.8/ccip/RMNHome.sol \ No newline at end of file +./src/v0.8/ccip/rmn \ No newline at end of file diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 1658bd8dcb..d684185072 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -14,85 +14,79 @@ AggregateTokenLimiter_getTokenValue:test_GetTokenValue_Success() (gas: 19668) AggregateTokenLimiter_getTokenValue:test_NoTokenPrice_Reverts() (gas: 21253) AggregateTokenLimiter_rateLimitValue:test_AggregateValueMaxCapacityExceeded_Revert() (gas: 16418) AggregateTokenLimiter_rateLimitValue:test_RateLimitValueSuccess_gas() (gas: 18306) -AggregateTokenLimiter_setAdmin:test_OnlyOwnerOrAdmin_Revert() (gas: 13047) +AggregateTokenLimiter_setAdmin:test_OnlyOwnerOrAdmin_Revert() (gas: 13048) AggregateTokenLimiter_setAdmin:test_Owner_Success() (gas: 18989) -AggregateTokenLimiter_setRateLimiterConfig:test_OnlyOnlyCallableByAdminOrOwner_Revert() (gas: 17479) +AggregateTokenLimiter_setRateLimiterConfig:test_OnlyOnlyCallableByAdminOrOwner_Revert() (gas: 17480) AggregateTokenLimiter_setRateLimiterConfig:test_Owner_Success() (gas: 30062) AggregateTokenLimiter_setRateLimiterConfig:test_TokenLimitAdmin_Success() (gas: 32071) -BurnFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28761) +BurnFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28773) BurnFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) -BurnFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243491) +BurnFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243529) BurnFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 23947) -BurnMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 27522) +BurnMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 27534) BurnMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) -BurnMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 241381) +BurnMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 241420) BurnMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 17677) BurnMintTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 28757) BurnMintTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56190) BurnMintTokenPool_releaseOrMint:test_PoolMint_Success() (gas: 112319) -BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28761) +BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28773) BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55115) -BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243517) +BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 243556) BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 23951) -CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2132684) -CCIPConfigSetup:test_getCapabilityConfiguration_Success() (gas: 9517) -CCIPConfig_ConfigStateMachine:test__computeConfigDigest_Success() (gas: 70831) -CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_InitToRunning_Success() (gas: 363664) -CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_RunningToStaging_Success() (gas: 488826) -CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_StagingToRunning_Success() (gas: 453439) -CCIPConfig_ConfigStateMachine:test__groupByPluginType_TooManyOCR3Configs_Reverts() (gas: 37049) -CCIPConfig_ConfigStateMachine:test__groupByPluginType_threeCommitConfigs_Reverts() (gas: 61065) -CCIPConfig_ConfigStateMachine:test__groupByPluginType_threeExecutionConfigs_Reverts() (gas: 60985) -CCIPConfig_ConfigStateMachine:test__stateFromConfigLength_Success() (gas: 11635) -CCIPConfig_ConfigStateMachine:test__validateConfigStateTransition_Success() (gas: 8831) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_InitToRunning_Success() (gas: 312055) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_InitToRunning_WrongConfigCount_Reverts() (gas: 49727) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_NonExistentConfigTransition_Reverts() (gas: 32320) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_Success() (gas: 376678) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_WrongConfigCount_Reverts() (gas: 121045) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_WrongConfigDigestBlueGreen_Reverts() (gas: 157245) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_StagingToRunning_Success() (gas: 376454) -CCIPConfig_ConfigStateMachine:test__validateConfigTransition_StagingToRunning_WrongConfigDigest_Reverts() (gas: 157312) -CCIPConfig_ConfigStateMachine:test_getCapabilityConfiguration_Success() (gas: 9605) -CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_CommitAndExecConfig_Success() (gas: 1851094) -CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_CommitConfigOnly_Success() (gas: 1068315) -CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_ExecConfigOnly_Success() (gas: 1068346) +CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2132690) +CCIPConfigSetup:test_getCapabilityConfiguration_Success() (gas: 9539) +CCIPConfig_ConfigStateMachine:test__computeConfigDigest_Success() (gas: 66088) +CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_InitToRunning_Success() (gas: 357846) +CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_RunningToStaging_Success() (gas: 474512) +CCIPConfig_ConfigStateMachine:test__computeNewConfigWithMeta_StagingToRunning_Success() (gas: 441765) +CCIPConfig_ConfigStateMachine:test__groupByPluginType_TooManyOCR3Configs_Reverts() (gas: 33798) +CCIPConfig_ConfigStateMachine:test__groupByPluginType_threeCommitConfigs_Reverts() (gas: 56870) +CCIPConfig_ConfigStateMachine:test__groupByPluginType_threeExecutionConfigs_Reverts() (gas: 56790) +CCIPConfig_ConfigStateMachine:test__stateFromConfigLength_Success() (gas: 11701) +CCIPConfig_ConfigStateMachine:test__validateConfigStateTransition_Success() (gas: 8762) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_InitToRunning_Success() (gas: 309581) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_InitToRunning_WrongConfigCount_Reverts() (gas: 45877) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_NonExistentConfigTransition_Reverts() (gas: 29698) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_Success() (gas: 369916) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_WrongConfigCount_Reverts() (gas: 111436) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_RunningToStaging_WrongConfigDigestBlueGreen_Reverts() (gas: 145550) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_StagingToRunning_Success() (gas: 369692) +CCIPConfig_ConfigStateMachine:test__validateConfigTransition_StagingToRunning_WrongConfigDigest_Reverts() (gas: 145617) +CCIPConfig_ConfigStateMachine:test_getCapabilityConfiguration_Success() (gas: 9627) +CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_CommitAndExecConfig_Success() (gas: 1752378) +CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_CommitConfigOnly_Success() (gas: 1018901) +CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_ExecConfigOnly_Success() (gas: 1018932) CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_OnlyCapabilitiesRegistryCanCall_Reverts() (gas: 9599) -CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_ZeroLengthConfig_Success() (gas: 16070) -CCIPConfig_beforeCapabilityConfigSet:test_getCapabilityConfiguration_Success() (gas: 9605) -CCIPConfig_chainConfig:test__applyChainConfigUpdates_FChainNotPositive_Reverts() (gas: 184703) -CCIPConfig_chainConfig:test_applyChainConfigUpdates_addChainConfigs_Success() (gas: 344881) -CCIPConfig_chainConfig:test_applyChainConfigUpdates_nodeNotInRegistry_Reverts() (gas: 20258) -CCIPConfig_chainConfig:test_applyChainConfigUpdates_removeChainConfigs_Success() (gas: 267558) -CCIPConfig_chainConfig:test_applyChainConfigUpdates_selectorNotFound_Reverts() (gas: 14829) -CCIPConfig_chainConfig:test_getCapabilityConfiguration_Success() (gas: 9626) -CCIPConfig_chainConfig:test_getPaginatedCCIPConfigs_Success() (gas: 370235) -CCIPConfig_constructor:test_constructor_Success() (gas: 3612901) -CCIPConfig_constructor:test_constructor_ZeroAddressNotAllowed_Revert() (gas: 61777) -CCIPConfig_updatePluginConfig:test__updatePluginConfig_InitToRunning_Success() (gas: 1057368) -CCIPConfig_updatePluginConfig:test__updatePluginConfig_InvalidConfigLength_Reverts() (gas: 27561) -CCIPConfig_updatePluginConfig:test__updatePluginConfig_InvalidConfigStateTransition_Reverts() (gas: 23127) -CCIPConfig_updatePluginConfig:test__updatePluginConfig_RunningToStaging_Success() (gas: 2009285) -CCIPConfig_updatePluginConfig:test__updatePluginConfig_StagingToRunning_Success() (gas: 2616133) -CCIPConfig_updatePluginConfig:test_getCapabilityConfiguration_Success() (gas: 9605) -CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsHasDuplicates_Reverts() (gas: 294893) -CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsNotASubsetOfP2PIds_Reverts() (gas: 298325) -CCIPConfig_validateConfig:test__validateConfig_BootstrapP2PIdsNotSorted_Reverts() (gas: 295038) -CCIPConfig_validateConfig:test__validateConfig_ChainSelectorNotFound_Reverts() (gas: 294357) -CCIPConfig_validateConfig:test__validateConfig_ChainSelectorNotSet_Reverts() (gas: 291431) -CCIPConfig_validateConfig:test__validateConfig_FMustBePositive_Reverts() (gas: 292396) -CCIPConfig_validateConfig:test__validateConfig_FTooHigh_Reverts() (gas: 292540) -CCIPConfig_validateConfig:test__validateConfig_NodeNotInRegistry_Reverts() (gas: 299420) -CCIPConfig_validateConfig:test__validateConfig_NotEnoughTransmitters_Reverts() (gas: 1160094) -CCIPConfig_validateConfig:test__validateConfig_OfframpAddressCannotBeZero_Reverts() (gas: 291260) -CCIPConfig_validateConfig:test__validateConfig_P2PIdsHasDuplicates_Reverts() (gas: 295907) -CCIPConfig_validateConfig:test__validateConfig_P2PIdsLengthNotMatching_Reverts() (gas: 293229) -CCIPConfig_validateConfig:test__validateConfig_P2PIdsNotSorted_Reverts() (gas: 295623) -CCIPConfig_validateConfig:test__validateConfig_Success() (gas: 302186) -CCIPConfig_validateConfig:test__validateConfig_TooManyBootstrapP2PIds_Reverts() (gas: 294539) -CCIPConfig_validateConfig:test__validateConfig_TooManySigners_Reverts() (gas: 1215861) -CCIPConfig_validateConfig:test__validateConfig_TooManyTransmitters_Reverts() (gas: 1214264) -CCIPConfig_validateConfig:test_getCapabilityConfiguration_Success() (gas: 9584) +CCIPConfig_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_ZeroLengthConfig_Success() (gas: 15984) +CCIPConfig_beforeCapabilityConfigSet:test_getCapabilityConfiguration_Success() (gas: 9627) +CCIPConfig_chainConfig:test__applyChainConfigUpdates_FChainNotPositive_Reverts() (gas: 184705) +CCIPConfig_chainConfig:test_applyChainConfigUpdates_addChainConfigs_Success() (gas: 344873) +CCIPConfig_chainConfig:test_applyChainConfigUpdates_nodeNotInRegistry_Reverts() (gas: 20307) +CCIPConfig_chainConfig:test_applyChainConfigUpdates_removeChainConfigs_Success() (gas: 267534) +CCIPConfig_chainConfig:test_applyChainConfigUpdates_selectorNotFound_Reverts() (gas: 14807) +CCIPConfig_chainConfig:test_getCapabilityConfiguration_Success() (gas: 9648) +CCIPConfig_chainConfig:test_getPaginatedCCIPConfigs_Success() (gas: 370227) +CCIPConfig_constructor:test_constructor_Success() (gas: 3397350) +CCIPConfig_constructor:test_constructor_ZeroAddressNotAllowed_Revert() (gas: 61507) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_InitToRunning_Success() (gas: 1008218) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_InvalidConfigLength_Reverts() (gas: 25563) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_InvalidConfigStateTransition_Reverts() (gas: 21781) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_RunningToStaging_Success() (gas: 1895343) +CCIPConfig_updatePluginConfig:test__updatePluginConfig_StagingToRunning_Success() (gas: 2464900) +CCIPConfig_updatePluginConfig:test_getCapabilityConfiguration_Success() (gas: 9627) +CCIPConfig_validateConfig:test__validateConfig_ABIEncodedAddress_OfframpAddressCannotBeZero_Reverts() (gas: 290657) +CCIPConfig_validateConfig:test__validateConfig_ChainSelectorNotFound_Reverts() (gas: 293370) +CCIPConfig_validateConfig:test__validateConfig_ChainSelectorNotSet_Reverts() (gas: 290290) +CCIPConfig_validateConfig:test__validateConfig_FMustBePositive_Reverts() (gas: 291497) +CCIPConfig_validateConfig:test__validateConfig_FTooHigh_Reverts() (gas: 291595) +CCIPConfig_validateConfig:test__validateConfig_NodeNotInRegistry_Reverts() (gas: 344569) +CCIPConfig_validateConfig:test__validateConfig_NotEnoughTransmitters_Reverts() (gas: 1207267) +CCIPConfig_validateConfig:test__validateConfig_OfframpAddressCannotBeZero_Reverts() (gas: 290373) +CCIPConfig_validateConfig:test__validateConfig_P2PIdsLengthNotMatching_Reverts() (gas: 292270) +CCIPConfig_validateConfig:test__validateConfig_Success() (gas: 299419) +CCIPConfig_validateConfig:test__validateConfig_TooManySigners_Reverts() (gas: 492913) +CCIPConfig_validateConfig:test_getCapabilityConfiguration_Success() (gas: 9606) CommitStore_constructor:test_Constructor_Success() (gas: 3091326) CommitStore_isUnpausedAndRMNHealthy:test_RMN_Success() (gas: 73420) CommitStore_report:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 28670) @@ -114,9 +108,9 @@ CommitStore_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 143718) CommitStore_setDynamicConfig:test_InvalidCommitStoreConfig_Revert() (gas: 37263) CommitStore_setDynamicConfig:test_OnlyOwner_Revert() (gas: 37399) CommitStore_setDynamicConfig:test_PriceEpochCleared_Success() (gas: 129098) -CommitStore_setLatestPriceEpochAndRound:test_OnlyOwner_Revert() (gas: 11047) +CommitStore_setLatestPriceEpochAndRound:test_OnlyOwner_Revert() (gas: 11048) CommitStore_setLatestPriceEpochAndRound:test_SetLatestPriceEpochAndRound_Success() (gas: 20642) -CommitStore_setMinSeqNr:test_OnlyOwner_Revert() (gas: 11046) +CommitStore_setMinSeqNr:test_OnlyOwner_Revert() (gas: 11047) CommitStore_verify:test_Blessed_Success() (gas: 96389) CommitStore_verify:test_NotBlessed_Success() (gas: 61374) CommitStore_verify:test_Paused_Revert() (gas: 18496) @@ -124,73 +118,73 @@ CommitStore_verify:test_TooManyLeaves_Revert() (gas: 36785) DefensiveExampleTest:test_HappyPath_Success() (gas: 200018) DefensiveExampleTest:test_Recovery() (gas: 424256) E2E:test_E2E_3MessagesSuccess_gas() (gas: 1100023) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37797) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103733) -EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85258) -EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 36786) -EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 94302) -EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 39768) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_NotACompatiblePool_Revert() (gas: 37782) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_Success() (gas: 103730) +EVM2EVMOffRamp__releaseOrMintToken:test__releaseOrMintToken_TokenHandlingError_transfer_Revert() (gas: 85255) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 36789) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 94299) +EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 39765) EVM2EVMOffRamp__releaseOrMintToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 86559) EVM2EVMOffRamp__releaseOrMintTokens:test_OverValueWithARLOff_Success() (gas: 385246) -EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 141896) +EVM2EVMOffRamp__releaseOrMintTokens:test_PriceNotFoundForToken_Reverts() (gas: 141905) EVM2EVMOffRamp__releaseOrMintTokens:test_RateLimitErrors_Reverts() (gas: 803071) EVM2EVMOffRamp__releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 179244) -EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 29240) +EVM2EVMOffRamp__releaseOrMintTokens:test__releaseOrMintTokens_NotACompatiblePool_Reverts() (gas: 29243) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 66444) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 43320) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 210968) EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 222232) -EVM2EVMOffRamp__report:test_Report_Success() (gas: 126637) +EVM2EVMOffRamp__report:test_Report_Success() (gas: 126640) EVM2EVMOffRamp__trialExecute:test_RateLimitError_Success() (gas: 237791) EVM2EVMOffRamp__trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 246391) EVM2EVMOffRamp__trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 329828) EVM2EVMOffRamp__trialExecute:test_trialExecute_Success() (gas: 312265) -EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17030) +EVM2EVMOffRamp_ccipReceive:test_Reverts() (gas: 17033) EVM2EVMOffRamp_constructor:test_CommitStoreAlreadyInUse_Revert() (gas: 153727) -EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5665947) +EVM2EVMOffRamp_constructor:test_Constructor_Success() (gas: 5665956) EVM2EVMOffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 144461) -EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21318) -EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36432) +EVM2EVMOffRamp_execute:test_EmptyReport_Revert() (gas: 21315) +EVM2EVMOffRamp_execute:test_InvalidMessageId_Revert() (gas: 36429) EVM2EVMOffRamp_execute:test_InvalidSourceChain_Revert() (gas: 51598) EVM2EVMOffRamp_execute:test_InvalidSourcePoolAddress_Success() (gas: 473329) EVM2EVMOffRamp_execute:test_ManualExecutionNotYetEnabled_Revert() (gas: 47668) -EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152359) +EVM2EVMOffRamp_execute:test_MessageTooLarge_Revert() (gas: 152356) EVM2EVMOffRamp_execute:test_Paused_Revert() (gas: 102842) -EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 163804) +EVM2EVMOffRamp_execute:test_ReceiverError_Success() (gas: 163810) EVM2EVMOffRamp_execute:test_RetryFailedMessageWithoutManualExecution_Success() (gas: 178205) EVM2EVMOffRamp_execute:test_RootNotCommitted_Revert() (gas: 42539) EVM2EVMOffRamp_execute:test_SingleMessageNoTokensUnordered_Success() (gas: 157347) EVM2EVMOffRamp_execute:test_SingleMessageNoTokens_Success() (gas: 172692) EVM2EVMOffRamp_execute:test_SingleMessageToNonCCIPReceiver_Success() (gas: 247069) -EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 113842) +EVM2EVMOffRamp_execute:test_SingleMessagesNoTokensSuccess_gas() (gas: 113839) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 407451) EVM2EVMOffRamp_execute:test_SkippedIncorrectNonce_Success() (gas: 54096) -EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 131047) -EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52090) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 563385) -EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 494182) -EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35383) +EVM2EVMOffRamp_execute:test_StrictUntouchedToSuccess_Success() (gas: 131053) +EVM2EVMOffRamp_execute:test_TokenDataMismatch_Revert() (gas: 52087) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensAndGE_Success() (gas: 563391) +EVM2EVMOffRamp_execute:test_TwoMessagesWithTokensSuccess_gas() (gas: 494179) +EVM2EVMOffRamp_execute:test_UnexpectedTokenData_Revert() (gas: 35380) EVM2EVMOffRamp_execute:test_Unhealthy_Revert() (gas: 544641) -EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64326) +EVM2EVMOffRamp_execute:test_UnsupportedNumberOfTokens_Revert() (gas: 64323) EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 122322) EVM2EVMOffRamp_execute:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 142532) -EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 427337) +EVM2EVMOffRamp_execute:test_execute_RouterYULCall_Success() (gas: 427328) EVM2EVMOffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18502) -EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 278097) -EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 18659) +EVM2EVMOffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 278106) +EVM2EVMOffRamp_executeSingleMessage:test_NonContract_Success() (gas: 18668) EVM2EVMOffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 223921) EVM2EVMOffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 47881) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 47352) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 313917) EVM2EVMOffRamp_executeSingleMessage:test_executeSingleMessage_ZeroGasZeroData_Success() (gas: 70008) -EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 229319) +EVM2EVMOffRamp_execute_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 229325) EVM2EVMOffRamp_execute_upgrade:test_V2NonceStartsAtV1Nonce_Success() (gas: 276790) EVM2EVMOffRamp_execute_upgrade:test_V2OffRampNonceSkipsIfMsgInFlight_Success() (gas: 258696) EVM2EVMOffRamp_execute_upgrade:test_V2SenderNoncesReadsPreviousRamp_Success() (gas: 226253) EVM2EVMOffRamp_execute_upgrade:test_V2_Success() (gas: 130745) EVM2EVMOffRamp_getAllRateLimitTokens:test_GetAllRateLimitTokens_Success() (gas: 38446) -EVM2EVMOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3247348) -EVM2EVMOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 83333) +EVM2EVMOffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3251974) +EVM2EVMOffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 83387) EVM2EVMOffRamp_manuallyExecute:test_ManualExecFailedTx_Revert() (gas: 185829) EVM2EVMOffRamp_manuallyExecute:test_ManualExecForkedChain_Revert() (gas: 27049) EVM2EVMOffRamp_manuallyExecute:test_ManualExecGasLimitMismatch_Revert() (gas: 45155) @@ -198,29 +192,29 @@ EVM2EVMOffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 274 EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithMultipleMessagesAndSourceTokens_Success() (gas: 530151) EVM2EVMOffRamp_manuallyExecute:test_ManualExecWithSourceTokens_Success() (gas: 345758) EVM2EVMOffRamp_manuallyExecute:test_ManualExec_Success() (gas: 187324) -EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2321906) +EVM2EVMOffRamp_manuallyExecute:test_ReentrancyManualExecuteFails_Success() (gas: 2321912) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DestinationGasAmountCountMismatch_Revert() (gas: 362965) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 143900) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_InvalidTokenGasOverride_Revert() (gas: 366104) -EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimitManualExec_Success() (gas: 482691) +EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_LowGasLimitManualExec_Success() (gas: 482682) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 189727) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithInvalidReceiverExecutionGasOverride_Revert() (gas: 153641) EVM2EVMOffRamp_manuallyExecute:test_manuallyExecute_WithInvalidSourceTokenDataCount_Revert() (gas: 59894) -EVM2EVMOffRamp_metadataHash:test_MetadataHash_Success() (gas: 8838) -EVM2EVMOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 40153) -EVM2EVMOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 38236) -EVM2EVMOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 141962) -EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_AddsAndRemoves_Success() (gas: 162525) -EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_NonOwner_Revert() (gas: 16690) -EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_Success() (gas: 197721) -EVM2EVMOnRamp_constructor:test_Constructor_Success() (gas: 5579769) +EVM2EVMOffRamp_metadataHash:test_MetadataHash_Success() (gas: 8865) +EVM2EVMOffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 40156) +EVM2EVMOffRamp_setDynamicConfig:test_RouterZeroAddress_Revert() (gas: 38239) +EVM2EVMOffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 141923) +EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_AddsAndRemoves_Success() (gas: 162528) +EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_NonOwner_Revert() (gas: 16693) +EVM2EVMOffRamp_updateRateLimitTokens:test_updateRateLimitTokens_Success() (gas: 197728) +EVM2EVMOnRamp_constructor:test_Constructor_Success() (gas: 5579757) EVM2EVMOnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 35778) -EVM2EVMOnRamp_forwardFromRouter:test_EnforceOutOfOrder_Revert() (gas: 98428) -EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 114198) -EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 114240) -EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 130207) -EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 138653) -EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 129829) +EVM2EVMOnRamp_forwardFromRouter:test_EnforceOutOfOrder_Revert() (gas: 98446) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 114204) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 114246) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 130213) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 138659) +EVM2EVMOnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 129838) EVM2EVMOnRamp_forwardFromRouter:test_InvalidAddressEncodePacked_Revert() (gas: 38257) EVM2EVMOnRamp_forwardFromRouter:test_InvalidAddress_Revert() (gas: 38440) EVM2EVMOnRamp_forwardFromRouter:test_InvalidChainSelector_Revert() (gas: 25489) @@ -242,7 +236,7 @@ EVM2EVMOnRamp_forwardFromRouter:test_TooManyTokens_Revert() (gas: 30187) EVM2EVMOnRamp_forwardFromRouter:test_Unhealthy_Revert() (gas: 43300) EVM2EVMOnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 109305) EVM2EVMOnRamp_forwardFromRouter:test_ZeroAddressReceiver_Revert() (gas: 312579) -EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_ShouldStoreLinkFees_Success() (gas: 112322) +EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_ShouldStoreLinkFees_Success() (gas: 112331) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 72206) EVM2EVMOnRamp_forwardFromRouter:test_forwardFromRouter_correctSourceTokenData_Success() (gas: 712975) EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2NonceNewSenderStartsAtZero_Success() (gas: 147664) @@ -251,14 +245,14 @@ EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2SenderNoncesReadsPreviousRamp_Suc EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2_Success() (gas: 95349) EVM2EVMOnRamp_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 20544) EVM2EVMOnRamp_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20912) -EVM2EVMOnRamp_getFee:test_EmptyMessage_Success() (gas: 78230) +EVM2EVMOnRamp_getFee:test_EmptyMessage_Success() (gas: 78233) EVM2EVMOnRamp_getFee:test_GetFeeOfZeroForTokenMessage_Success() (gas: 81762) -EVM2EVMOnRamp_getFee:test_HighGasMessage_Success() (gas: 234078) +EVM2EVMOnRamp_getFee:test_HighGasMessage_Success() (gas: 234081) EVM2EVMOnRamp_getFee:test_MessageGasLimitTooHigh_Revert() (gas: 16715) EVM2EVMOnRamp_getFee:test_MessageTooLarge_Revert() (gas: 95271) -EVM2EVMOnRamp_getFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 159436) +EVM2EVMOnRamp_getFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 159439) EVM2EVMOnRamp_getFee:test_NotAFeeToken_Revert() (gas: 24089) -EVM2EVMOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 117922) +EVM2EVMOnRamp_getFee:test_SingleTokenMessage_Success() (gas: 117925) EVM2EVMOnRamp_getFee:test_TooManyTokens_Revert() (gas: 19902) EVM2EVMOnRamp_getFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 64648) EVM2EVMOnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10460) @@ -281,7 +275,7 @@ EVM2EVMOnRamp_payNops:test_NoFeesToPay_Revert() (gas: 127367) EVM2EVMOnRamp_payNops:test_NoNopsToPay_Revert() (gas: 133251) EVM2EVMOnRamp_payNops:test_NopPayNops_Success() (gas: 146446) EVM2EVMOnRamp_payNops:test_OwnerPayNops_Success() (gas: 141021) -EVM2EVMOnRamp_payNops:test_PayNopsSuccessAfterSetNops() (gas: 297510) +EVM2EVMOnRamp_payNops:test_PayNopsSuccessAfterSetNops() (gas: 297519) EVM2EVMOnRamp_payNops:test_WrongPermissions_Revert() (gas: 15294) EVM2EVMOnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 42365) EVM2EVMOnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 21246) @@ -347,16 +341,16 @@ FeeQuoter_applyTokenTransferFeeConfigUpdates:test_OnlyCallableByOwnerOrAdmin_Rev FeeQuoter_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 107046) FeeQuoter_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 111396) FeeQuoter_constructor:test_InvalidStalenessThreshold_Revert() (gas: 111449) -FeeQuoter_constructor:test_Setup_Success() (gas: 5358690) +FeeQuoter_constructor:test_Setup_Success() (gas: 5355882) FeeQuoter_convertTokenAmount:test_ConvertTokenAmount_Success() (gas: 72739) FeeQuoter_convertTokenAmount:test_LinkTokenNotSupported_Revert() (gas: 30963) FeeQuoter_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 94303) FeeQuoter_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCostUnsupportedDestChainSelector_Success() (gas: 14614) FeeQuoter_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20410) -FeeQuoter_getTokenAndGasPrices:test_GetFeeTokenAndGasPrices_Success() (gas: 70443) +FeeQuoter_getTokenAndGasPrices:test_GetFeeTokenAndGasPrices_Success() (gas: 70458) FeeQuoter_getTokenAndGasPrices:test_StaleGasPrice_Revert() (gas: 16838) FeeQuoter_getTokenAndGasPrices:test_UnsupportedChain_Revert() (gas: 16140) -FeeQuoter_getTokenAndGasPrices:test_ZeroGasPrice_Success() (gas: 45750) +FeeQuoter_getTokenAndGasPrices:test_ZeroGasPrice_Success() (gas: 45765) FeeQuoter_getTokenPrice:test_GetTokenPriceFromFeed_Success() (gas: 62252) FeeQuoter_getTokenPrices:test_GetTokenPrices_Success() (gas: 84800) FeeQuoter_getTokenTransferCost:test_CustomTokenBpsFee_Success() (gas: 41227) @@ -369,17 +363,17 @@ FeeQuoter_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_S FeeQuoter_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 40013) FeeQuoter_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29299) FeeQuoter_getValidatedFee:test_DestinationChainNotEnabled_Revert() (gas: 18180) -FeeQuoter_getValidatedFee:test_EmptyMessage_Success() (gas: 85936) -FeeQuoter_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 56735) -FeeQuoter_getValidatedFee:test_HighGasMessage_Success() (gas: 242354) +FeeQuoter_getValidatedFee:test_EmptyMessage_Success() (gas: 85919) +FeeQuoter_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 54345) +FeeQuoter_getValidatedFee:test_HighGasMessage_Success() (gas: 242337) FeeQuoter_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 22390) -FeeQuoter_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 34187) +FeeQuoter_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 31797) FeeQuoter_getValidatedFee:test_MessageTooLarge_Revert() (gas: 100133) -FeeQuoter_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 147715) +FeeQuoter_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 147680) FeeQuoter_getValidatedFee:test_NotAFeeToken_Revert() (gas: 21043) -FeeQuoter_getValidatedFee:test_SingleTokenMessage_Success() (gas: 116743) +FeeQuoter_getValidatedFee:test_SingleTokenMessage_Success() (gas: 116708) FeeQuoter_getValidatedFee:test_TooManyTokens_Revert() (gas: 22526) -FeeQuoter_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 64374) +FeeQuoter_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 64364) FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Above18Decimals_Success() (gas: 2094539) FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Below18Decimals_Success() (gas: 2094497) FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt0Decimals_Success() (gas: 2074616) @@ -432,53 +426,53 @@ FeeQuoter_validatePoolReturnData:test_InvalidEVMAddressDestToken_Revert() (gas: FeeQuoter_validatePoolReturnData:test_ProcessPoolReturnData_Success() (gas: 73252) FeeQuoter_validatePoolReturnData:test_SourceTokenDataTooLarge_Revert() (gas: 107744) FeeQuoter_validatePoolReturnData:test_TokenAmountArraysMismatching_Revert() (gas: 40091) -HybridUSDCTokenPoolMigrationTests:test_LockOrBurn_LocKReleaseMechanism_then_switchToPrimary_Success() (gas: 208137) -HybridUSDCTokenPoolMigrationTests:test_LockOrBurn_PrimaryMechanism_Success() (gas: 135392) -HybridUSDCTokenPoolMigrationTests:test_LockOrBurn_WhileMigrationPause_Revert() (gas: 106624) -HybridUSDCTokenPoolMigrationTests:test_LockOrBurn_onLockReleaseMechanism_Success() (gas: 143884) -HybridUSDCTokenPoolMigrationTests:test_MintOrRelease_OnLockReleaseMechanism_Success() (gas: 230399) -HybridUSDCTokenPoolMigrationTests:test_MintOrRelease_OnLockReleaseMechanism_then_switchToPrimary_Success() (gas: 438259) -HybridUSDCTokenPoolMigrationTests:test_MintOrRelease_incomingMessageWithPrimaryMechanism() (gas: 269968) +HybridUSDCTokenPoolMigrationTests:test_LockOrBurn_LocKReleaseMechanism_then_switchToPrimary_Success() (gas: 208156) +HybridUSDCTokenPoolMigrationTests:test_LockOrBurn_PrimaryMechanism_Success() (gas: 135401) +HybridUSDCTokenPoolMigrationTests:test_LockOrBurn_WhileMigrationPause_Revert() (gas: 106633) +HybridUSDCTokenPoolMigrationTests:test_LockOrBurn_onLockReleaseMechanism_Success() (gas: 143893) +HybridUSDCTokenPoolMigrationTests:test_MintOrRelease_OnLockReleaseMechanism_Success() (gas: 230396) +HybridUSDCTokenPoolMigrationTests:test_MintOrRelease_OnLockReleaseMechanism_then_switchToPrimary_Success() (gas: 438277) +HybridUSDCTokenPoolMigrationTests:test_MintOrRelease_incomingMessageWithPrimaryMechanism() (gas: 269985) HybridUSDCTokenPoolMigrationTests:test_burnLockedUSDC_invalidPermissions_Revert() (gas: 39124) HybridUSDCTokenPoolMigrationTests:test_cancelExistingCCTPMigrationProposal() (gas: 31124) HybridUSDCTokenPoolMigrationTests:test_cannotCancelANonExistentMigrationProposal() (gas: 12628) -HybridUSDCTokenPoolMigrationTests:test_cannotModifyLiquidityWithoutPermissions_Revert() (gas: 17133) -HybridUSDCTokenPoolMigrationTests:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 252432) +HybridUSDCTokenPoolMigrationTests:test_cannotModifyLiquidityWithoutPermissions_Revert() (gas: 17134) +HybridUSDCTokenPoolMigrationTests:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 252452) HybridUSDCTokenPoolMigrationTests:test_transferLiquidity_Success() (gas: 157049) HybridUSDCTokenPoolMigrationTests:test_withdrawLiquidity_Success() (gas: 140780) -HybridUSDCTokenPoolTests:test_LockOrBurn_LocKReleaseMechanism_then_switchToPrimary_Success() (gas: 208102) -HybridUSDCTokenPoolTests:test_LockOrBurn_PrimaryMechanism_Success() (gas: 135365) -HybridUSDCTokenPoolTests:test_LockOrBurn_WhileMigrationPause_Revert() (gas: 106589) -HybridUSDCTokenPoolTests:test_LockOrBurn_onLockReleaseMechanism_Success() (gas: 143832) -HybridUSDCTokenPoolTests:test_MintOrRelease_OnLockReleaseMechanism_Success() (gas: 230365) -HybridUSDCTokenPoolTests:test_MintOrRelease_OnLockReleaseMechanism_then_switchToPrimary_Success() (gas: 438171) -HybridUSDCTokenPoolTests:test_MintOrRelease_incomingMessageWithPrimaryMechanism() (gas: 269912) +HybridUSDCTokenPoolTests:test_LockOrBurn_LocKReleaseMechanism_then_switchToPrimary_Success() (gas: 208121) +HybridUSDCTokenPoolTests:test_LockOrBurn_PrimaryMechanism_Success() (gas: 135375) +HybridUSDCTokenPoolTests:test_LockOrBurn_WhileMigrationPause_Revert() (gas: 106610) +HybridUSDCTokenPoolTests:test_LockOrBurn_onLockReleaseMechanism_Success() (gas: 143841) +HybridUSDCTokenPoolTests:test_MintOrRelease_OnLockReleaseMechanism_Success() (gas: 230362) +HybridUSDCTokenPoolTests:test_MintOrRelease_OnLockReleaseMechanism_then_switchToPrimary_Success() (gas: 438237) +HybridUSDCTokenPoolTests:test_MintOrRelease_incomingMessageWithPrimaryMechanism() (gas: 269968) HybridUSDCTokenPoolTests:test_withdrawLiquidity_Success() (gas: 140774) -LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Revert() (gas: 10970) +LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Revert() (gas: 10971) LockReleaseTokenPoolAndProxy_setRebalancer:test_SetRebalancer_Success() (gas: 17992) -LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3368110) -LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3364509) -LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_Unauthorized_Revert() (gas: 11380) +LockReleaseTokenPoolPoolAndProxy_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3368113) +LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3364513) +LockReleaseTokenPoolPoolAndProxy_provideLiquidity:test_Unauthorized_Revert() (gas: 11381) LockReleaseTokenPoolPoolAndProxy_supportsInterface:test_SupportsInterface_Success() (gas: 9977) LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60043) -LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11355) -LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3124819) -LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29942) +LockReleaseTokenPoolPoolAndProxy_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11356) +LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3124822) +LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29954) LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Success() (gas: 79844) LockReleaseTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 59464) -LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3121261) -LockReleaseTokenPool_provideLiquidity:test_Unauthorized_Revert() (gas: 11380) -LockReleaseTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 72644) +LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3121265) +LockReleaseTokenPool_provideLiquidity:test_Unauthorized_Revert() (gas: 11381) +LockReleaseTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 72654) LockReleaseTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56196) -LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 225108) -LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Revert() (gas: 10992) +LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 225137) +LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Revert() (gas: 10993) LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Success() (gas: 18058) LockReleaseTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 9977) LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_Success() (gas: 83171) LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_transferTooMuch_Revert() (gas: 55878) LockReleaseTokenPool_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60043) -LockReleaseTokenPool_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11355) -LockRelease_setRateLimitAdmin:test_SetRateLimitAdmin_Revert() (gas: 11029) +LockReleaseTokenPool_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11356) +LockRelease_setRateLimitAdmin:test_SetRateLimitAdmin_Revert() (gas: 11030) LockRelease_setRateLimitAdmin:test_SetRateLimitAdmin_Success() (gas: 35030) MerkleMultiProofTest:test_CVE_2023_34459() (gas: 5451) MerkleMultiProofTest:test_EmptyLeaf_Revert() (gas: 3552) @@ -487,7 +481,7 @@ MerkleMultiProofTest:test_MerkleRootSingleLeaf_Success() (gas: 3649) MerkleMultiProofTest:test_SpecSync_gas() (gas: 34123) MockRouterTest:test_ccipSendWithInsufficientNativeTokens_Revert() (gas: 33965) MockRouterTest:test_ccipSendWithInvalidMsgValue_Revert() (gas: 60758) -MockRouterTest:test_ccipSendWithLinkFeeTokenAndValidMsgValue_Success() (gas: 126294) +MockRouterTest:test_ccipSendWithLinkFeeTokenAndValidMsgValue_Success() (gas: 126306) MockRouterTest:test_ccipSendWithLinkFeeTokenbutInsufficientAllowance_Revert() (gas: 63302) MockRouterTest:test_ccipSendWithSufficientNativeFeeTokens_Success() (gas: 43853) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_MultipleConfigsBothLanes_Success() (gas: 132031) @@ -535,53 +529,53 @@ MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_AddsA MultiAggregateRateLimiter_updateRateLimitTokens:test_UpdateRateLimitTokens_RemoveNonExistentToken_Success() (gas: 28703) MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroDestToken_Revert() (gas: 18287) MultiAggregateRateLimiter_updateRateLimitTokens:test_ZeroSourceToken_Revert() (gas: 18216) -MultiOCR3Base_setOCR3Configs:test_FMustBePositive_Revert() (gas: 59331) -MultiOCR3Base_setOCR3Configs:test_FTooHigh_Revert() (gas: 44298) -MultiOCR3Base_setOCR3Configs:test_RepeatSignerAddress_Revert() (gas: 283711) -MultiOCR3Base_setOCR3Configs:test_RepeatTransmitterAddress_Revert() (gas: 422848) -MultiOCR3Base_setOCR3Configs:test_SetConfigIgnoreSigners_Success() (gas: 511694) -MultiOCR3Base_setOCR3Configs:test_SetConfigWithSigners_Success() (gas: 829593) -MultiOCR3Base_setOCR3Configs:test_SetConfigWithoutSigners_Success() (gas: 457446) +MultiOCR3Base_setOCR3Configs:test_FMustBePositive_Revert() (gas: 59228) +MultiOCR3Base_setOCR3Configs:test_FTooHigh_Revert() (gas: 43602) +MultiOCR3Base_setOCR3Configs:test_RepeatSignerAddress_Revert() (gas: 283585) +MultiOCR3Base_setOCR3Configs:test_RepeatTransmitterAddress_Revert() (gas: 422210) +MultiOCR3Base_setOCR3Configs:test_SetConfigIgnoreSigners_Success() (gas: 511089) +MultiOCR3Base_setOCR3Configs:test_SetConfigWithSigners_Success() (gas: 828371) +MultiOCR3Base_setOCR3Configs:test_SetConfigWithoutSigners_Success() (gas: 456841) MultiOCR3Base_setOCR3Configs:test_SetConfigsZeroInput_Success() (gas: 12376) -MultiOCR3Base_setOCR3Configs:test_SetMultipleConfigs_Success() (gas: 2143220) -MultiOCR3Base_setOCR3Configs:test_SignerCannotBeZeroAddress_Revert() (gas: 141744) -MultiOCR3Base_setOCR3Configs:test_StaticConfigChange_Revert() (gas: 808478) -MultiOCR3Base_setOCR3Configs:test_TooManySigners_Revert() (gas: 171331) -MultiOCR3Base_setOCR3Configs:test_TooManyTransmitters_Revert() (gas: 30298) -MultiOCR3Base_setOCR3Configs:test_TransmitterCannotBeZeroAddress_Revert() (gas: 254454) -MultiOCR3Base_setOCR3Configs:test_UpdateConfigSigners_Success() (gas: 861521) -MultiOCR3Base_setOCR3Configs:test_UpdateConfigTransmittersWithoutSigners_Success() (gas: 475825) -MultiOCR3Base_transmit:test_ConfigDigestMismatch_Revert() (gas: 42837) -MultiOCR3Base_transmit:test_ForkedChain_Revert() (gas: 48442) -MultiOCR3Base_transmit:test_InsufficientSignatures_Revert() (gas: 76930) -MultiOCR3Base_transmit:test_NonUniqueSignature_Revert() (gas: 66127) -MultiOCR3Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 33419) -MultiOCR3Base_transmit:test_TooManySignatures_Revert() (gas: 79521) -MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 34020) -MultiOCR3Base_transmit:test_TransmitWithExtraCalldataArgs_Revert() (gas: 47114) -MultiOCR3Base_transmit:test_TransmitWithLessCalldataArgs_Revert() (gas: 25682) -MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18714) -MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) -MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) -MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) -MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) -MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 414301) -MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1501445) +MultiOCR3Base_setOCR3Configs:test_SetMultipleConfigs_Success() (gas: 2139958) +MultiOCR3Base_setOCR3Configs:test_SignerCannotBeZeroAddress_Revert() (gas: 141702) +MultiOCR3Base_setOCR3Configs:test_StaticConfigChange_Revert() (gas: 807256) +MultiOCR3Base_setOCR3Configs:test_TooManySigners_Revert() (gas: 158772) +MultiOCR3Base_setOCR3Configs:test_TooManyTransmitters_Revert() (gas: 112266) +MultiOCR3Base_setOCR3Configs:test_TransmitterCannotBeZeroAddress_Revert() (gas: 254068) +MultiOCR3Base_setOCR3Configs:test_UpdateConfigSigners_Success() (gas: 859969) +MultiOCR3Base_setOCR3Configs:test_UpdateConfigTransmittersWithoutSigners_Success() (gas: 475059) +MultiOCR3Base_transmit:test_ConfigDigestMismatch_Revert() (gas: 42833) +MultiOCR3Base_transmit:test_ForkedChain_Revert() (gas: 48438) +MultiOCR3Base_transmit:test_InsufficientSignatures_Revert() (gas: 76928) +MultiOCR3Base_transmit:test_NonUniqueSignature_Revert() (gas: 65768) +MultiOCR3Base_transmit:test_SignatureOutOfRegistration_Revert() (gas: 33417) +MultiOCR3Base_transmit:test_TooManySignatures_Revert() (gas: 79519) +MultiOCR3Base_transmit:test_TransmitSigners_gas_Success() (gas: 33631) +MultiOCR3Base_transmit:test_TransmitWithExtraCalldataArgs_Revert() (gas: 47110) +MultiOCR3Base_transmit:test_TransmitWithLessCalldataArgs_Revert() (gas: 25678) +MultiOCR3Base_transmit:test_TransmitWithoutSignatureVerification_gas_Success() (gas: 18712) +MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24189) +MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61131) +MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39888) +MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32971) +MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 411393) +MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1526613) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) -NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) -NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) -NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71847) -NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 260262) -NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 262359) -NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 326051) -NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 298263) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244814) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 233069) -NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 153186) -NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 168681) -NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 220836) -NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) -NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 107910) +NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23703) +NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38790) +NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71874) +NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 259788) +NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 263930) +NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 326647) +NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 298821) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244682) +NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 232797) +NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 152756) +NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 168320) +NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 220111) +NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125079) +NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 107546) NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 122943) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOffRamp_Revert() (gas: 42959) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRampAndOffRamp_Revert() (gas: 64282) @@ -614,178 +608,175 @@ OCR2Base_transmit:test_Transmit2SignersSuccess_gas() (gas: 51674) OCR2Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 23484) OCR2Base_transmit:test_UnauthorizedSigner_Revert() (gas: 39665) OCR2Base_transmit:test_WrongNumberOfSignatures_Revert() (gas: 20557) -OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 40149) -OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 107130) -OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 88331) -OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 39848) +OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 40170) +OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 107133) +OffRamp__releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 88356) +OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 39873) OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 97399) -OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 42843) -OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 89579) -OffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 467917) -OffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99183) -OffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12395) -OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 93181) -OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 109824) -OffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13263) -OffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17988) -OffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15300) -OffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 322171) -OffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 263506) -OffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 169162) -OffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 188589) -OffRamp_batchExecute:test_SingleReport_Success() (gas: 156230) -OffRamp_batchExecute:test_Unhealthy_Revert() (gas: 533834) -OffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10461) -OffRamp_ccipReceive:test_Reverts() (gas: 15773) -OffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67458) -OffRamp_commit:test_InvalidInterval_Revert() (gas: 59778) -OffRamp_commit:test_InvalidRootRevert() (gas: 58858) -OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6560573) -OffRamp_commit:test_NoConfig_Revert() (gas: 6143711) -OffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 106317) -OffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 116369) -OffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 106338) -OffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 351652) -OffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 159342) -OffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 136480) -OffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 136880) -OffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 59126) -OffRamp_commit:test_StaleReportWithRoot_Success() (gas: 225582) -OffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 117632) -OffRamp_commit:test_Unhealthy_Revert() (gas: 77674) -OffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 205066) -OffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6554962) -OffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 47832) -OffRamp_constructor:test_Constructor_Success() (gas: 6147616) -OffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137128) -OffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103845) -OffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101716) -OffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139680) -OffRamp_constructor:test_ZeroRMNProxy_Revert() (gas: 101593) -OffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101660) -OffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17305) -OffRamp_execute:test_LargeBatch_Success() (gas: 1828972) -OffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 358063) -OffRamp_execute:test_MultipleReports_Success() (gas: 285617) -OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6611685) -OffRamp_execute:test_NoConfig_Revert() (gas: 6194563) -OffRamp_execute:test_NonArray_Revert() (gas: 27809) -OffRamp_execute:test_SingleReport_Success() (gas: 175620) -OffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147848) -OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6973803) -OffRamp_execute:test_ZeroReports_Revert() (gas: 17225) -OffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18257) -OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 249037) -OffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20517) -OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 210176) -OffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48779) -OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48302) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229565) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86203) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 280859) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92437) -OffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 35104) -OffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 23923) -OffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 492333) -OffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 54457) -OffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 35927) -OffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154493) -OffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 35338) -OffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 187911) -OffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 199215) -OffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 48096) -OffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 447759) -OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 251078) -OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 193345) -OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 212938) -OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 266576) -OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 141191) -OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 423378) -OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 65877) -OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 80932) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 587410) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 535220) -OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 35743) -OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 532474) -OffRamp_executeSingleReport:test_Unhealthy_Revert() (gas: 529798) -OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 495040) -OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 136580) -OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 165799) -OffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3742124) -OffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118836) -OffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 88048) -OffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75551) +OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 42865) +OffRamp__releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 89601) +OffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 467980) +OffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 99186) +OffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 12392) +OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChainOnRamp_Revert() (gas: 93184) +OffRamp_applySourceChainConfigUpdates:test_ReplaceExistingChain_Success() (gas: 109891) +OffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13260) +OffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 17994) +OffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15349) +OffRamp_batchExecute:test_MultipleReportsDifferentChainsSkipCursedChain_Success() (gas: 176779) +OffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 332397) +OffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 275765) +OffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 167867) +OffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187343) +OffRamp_batchExecute:test_SingleReport_Success() (gas: 155847) +OffRamp_batchExecute:test_Unhealthy_Success() (gas: 572707) +OffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10440) +OffRamp_ccipReceive:test_Reverts() (gas: 15705) +OffRamp_commit:test_FailedRMNVerification_Reverts() (gas: 64218) +OffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 67373) +OffRamp_commit:test_InvalidInterval_Revert() (gas: 59676) +OffRamp_commit:test_InvalidRootRevert() (gas: 58728) +OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6572843) +OffRamp_commit:test_NoConfig_Revert() (gas: 6156722) +OffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 113211) +OffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 121156) +OffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 113232) +OffRamp_commit:test_PriceSequenceNumberCleared_Success() (gas: 354911) +OffRamp_commit:test_ReportAndPriceUpdate_Success() (gas: 166399) +OffRamp_commit:test_ReportOnlyRootSuccess_gas() (gas: 141496) +OffRamp_commit:test_RootAlreadyCommitted_Revert() (gas: 142440) +OffRamp_commit:test_SourceChainNotEnabled_Revert() (gas: 59004) +OffRamp_commit:test_StaleReportWithRoot_Success() (gas: 239068) +OffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 122234) +OffRamp_commit:test_Unhealthy_Revert() (gas: 57761) +OffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 211577) +OffRamp_commit:test_WrongConfigWithoutSigners_Revert() (gas: 6569232) +OffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 51147) +OffRamp_constructor:test_Constructor_Success() (gas: 6157449) +OffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137102) +OffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103831) +OffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101702) +OffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 139743) +OffRamp_constructor:test_ZeroRMNRemote_Revert() (gas: 101631) +OffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101646) +OffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17281) +OffRamp_execute:test_LargeBatch_Success() (gas: 3374948) +OffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 372169) +OffRamp_execute:test_MultipleReports_Success() (gas: 298074) +OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6620946) +OffRamp_execute:test_NoConfig_Revert() (gas: 6204499) +OffRamp_execute:test_NonArray_Revert() (gas: 27718) +OffRamp_execute:test_SingleReport_Success() (gas: 175099) +OffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147327) +OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6982447) +OffRamp_execute:test_ZeroReports_Revert() (gas: 17156) +OffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18212) +OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 248992) +OffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20494) +OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 210134) +OffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48734) +OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 48212) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 229531) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 86169) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 280811) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithValidation_Success() (gas: 92403) +OffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 28225) +OffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 21854) +OffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 501555) +OffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 47569) +OffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 33855) +OffRamp_executeSingleReport:test_MismatchingOnRampRoot_Revert() (gas: 154807) +OffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 28459) +OffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 187481) +OffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 197900) +OffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 40076) +OffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 447326) +OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 247718) +OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 191985) +OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 211578) +OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 259646) +OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 140761) +OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 424145) +OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 58992) +OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 74047) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 595794) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 543647) +OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 33671) +OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 568625) +OffRamp_executeSingleReport:test_Unhealthy_Success() (gas: 568639) +OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 474070) +OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 135265) +OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 164484) +OffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3635486) +OffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 118398) +OffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 87417) +OffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 75545) OffRamp_manuallyExecute:test_ManualExecInvalidGasLimit_Revert() (gas: 26439) -OffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 171639) -OffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 205796) -OffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 25993) -OffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152822) -OffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 524603) -OffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2388943) -OffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 208553) -OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 219343) -OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 663643) -OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 330148) -OffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 165822) -OffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 24603) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 66285) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 41316) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 83291) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 177934) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 191136) -OffRamp_resetUnblessedRoots:test_OnlyOwner_Revert() (gas: 11423) -OffRamp_resetUnblessedRoots:test_ResetUnblessedRoots_Success() (gas: 215373) -OffRamp_setDynamicConfig:test_FeeQuoterZeroAddress_Revert() (gas: 11585) -OffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14152) -OffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49115) -OffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27037) -OffRamp_trialExecute:test_RateLimitError_Success() (gas: 225795) -OffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 234416) -OffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 309206) -OffRamp_trialExecute:test_trialExecute_Success() (gas: 283994) -OffRamp_verify:test_Blessed_Success() (gas: 176664) -OffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178754) -OffRamp_verify:test_NotBlessed_Success() (gas: 141593) -OffRamp_verify:test_TooManyLeaves_Revert() (gas: 51510) +OffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 171175) +OffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 210959) +OffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 25990) +OffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 152828) +OffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 529679) +OffRamp_manuallyExecute:test_manuallyExecute_MultipleReportsWithSingleCursedLane_Revert() (gas: 310107) +OffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2389581) +OffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 223886) +OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 224461) +OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 767127) +OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 342767) +OffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 165844) +OffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 24622) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 66304) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidEVMAddress_Revert() (gas: 41335) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 83310) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 177953) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 191164) +OffRamp_setDynamicConfig:test_FeeQuoterZeroAddress_Revert() (gas: 11604) +OffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14171) +OffRamp_setDynamicConfig:test_SetDynamicConfigWithValidator_Success() (gas: 49156) +OffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 27101) +OffRamp_trialExecute:test_RateLimitError_Success() (gas: 225708) +OffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 234329) +OffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 308936) +OffRamp_trialExecute:test_trialExecute_Success() (gas: 283904) OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 390336) -OnRamp_allowListConfigUpdates:test_applyAllowList_Revert() (gas: 66509) -OnRamp_allowListConfigUpdates:test_applyAllowList_Success() (gas: 323566) -OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 64501) +OnRamp_allowListConfigUpdates:test_applyAllowList_Revert() (gas: 66512) +OnRamp_allowListConfigUpdates:test_applyAllowList_Success() (gas: 323568) +OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 64504) OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInvalidChainSelector_Revert() (gas: 13242) -OnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94878) -OnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92812) -OnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97827) -OnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92870) -OnRamp_constructor:test_Constructor_Success() (gas: 2866937) -OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 115250) -OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 146019) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 145615) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 143816) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 145847) -OnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 145216) -OnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 140359) +OnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94851) +OnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92785) +OnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97811) +OnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92843) +OnRamp_constructor:test_Constructor_Success() (gas: 2852084) +OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 114886) +OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 145654) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 145257) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 143482) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 145482) +OnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 144861) +OnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 140001) OnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 28810) -OnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 138683) +OnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 138698) OnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 26910) -OnRamp_forwardFromRouter:test_MultiCannotSendZeroTokens_Revert() (gas: 74456) +OnRamp_forwardFromRouter:test_MultiCannotSendZeroTokens_Revert() (gas: 74122) OnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12918) OnRamp_forwardFromRouter:test_Paused_Revert() (gas: 37224) OnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 18179) -OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 185252) -OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 211543) -OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 125128) -OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 146530) -OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3894232) +OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 184142) +OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 210451) +OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 124773) +OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 146166) +OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3882038) OnRamp_forwardFromRouter:test_UnAllowedOriginalSender_Revert() (gas: 18609) -OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 111118) -OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 76545) -OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 281240) -OnRamp_getFee:test_EmptyMessage_Success() (gas: 110107) -OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 75610) -OnRamp_getFee:test_GetFeeOfZeroForTokenMessage_Success() (gas: 95456) -OnRamp_getFee:test_NotAFeeTokenButPricedToken_Revert() (gas: 41814) -OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 125476) -OnRamp_getFee:test_Unhealthy_Revert() (gas: 43669) +OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 110785) +OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 76212) +OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 280890) +OnRamp_getFee:test_EmptyMessage_Success() (gas: 102302) +OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 66336) +OnRamp_getFee:test_GetFeeOfZeroForTokenMessage_Success() (gas: 87668) +OnRamp_getFee:test_NotAFeeTokenButPricedToken_Revert() (gas: 34930) +OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 117635) +OnRamp_getFee:test_Unhealthy_Revert() (gas: 17009) OnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10438) OnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35204) OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11402) @@ -793,7 +784,7 @@ OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeQuoterEqAddressZero_Revert OnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11359) OnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 16385) OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 55321) -OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97107) +OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97095) PingPong_ccipReceive:test_CcipReceive_Success() (gas: 152669) PingPong_plumbing:test_OutOfOrderExecution_Success() (gas: 20277) PingPong_plumbing:test_Pausing_Success() (gas: 17777) @@ -877,24 +868,24 @@ RegistryModuleOwnerCustom_registerAdminViaOwner:test_registerAdminViaOwner_Rever RegistryModuleOwnerCustom_registerAdminViaOwner:test_registerAdminViaOwner_Success() (gas: 129731) Router_applyRampUpdates:test_OffRampMismatch_Revert() (gas: 89288) Router_applyRampUpdates:test_OffRampUpdatesWithRouting() (gas: 10642128) -Router_applyRampUpdates:test_OnRampDisable() (gas: 55913) +Router_applyRampUpdates:test_OnRampDisable() (gas: 55935) Router_applyRampUpdates:test_OnlyOwner_Revert() (gas: 12311) Router_ccipSend:test_CCIPSendLinkFeeNoTokenSuccess_gas() (gas: 113880) Router_ccipSend:test_CCIPSendLinkFeeOneTokenSuccess_gas() (gas: 201336) Router_ccipSend:test_CCIPSendNativeFeeNoTokenSuccess_gas() (gas: 128515) Router_ccipSend:test_CCIPSendNativeFeeOneTokenSuccess_gas() (gas: 215973) -Router_ccipSend:test_FeeTokenAmountTooLow_Revert() (gas: 66269) +Router_ccipSend:test_FeeTokenAmountTooLow_Revert() (gas: 66281) Router_ccipSend:test_InvalidMsgValue() (gas: 31963) -Router_ccipSend:test_NativeFeeTokenInsufficientValue() (gas: 68740) +Router_ccipSend:test_NativeFeeTokenInsufficientValue() (gas: 68737) Router_ccipSend:test_NativeFeeTokenOverpay_Success() (gas: 173606) Router_ccipSend:test_NativeFeeTokenZeroValue() (gas: 56031) Router_ccipSend:test_NativeFeeToken_Success() (gas: 172200) -Router_ccipSend:test_NonLinkFeeToken_Success() (gas: 242714) +Router_ccipSend:test_NonLinkFeeToken_Success() (gas: 242717) Router_ccipSend:test_UnsupportedDestinationChain_Revert() (gas: 24749) Router_ccipSend:test_WhenNotHealthy_Revert() (gas: 44724) -Router_ccipSend:test_WrappedNativeFeeToken_Success() (gas: 174416) +Router_ccipSend:test_WrappedNativeFeeToken_Success() (gas: 174386) Router_ccipSend:test_ZeroFeeAndGasPrice_Success() (gas: 244854) -Router_constructor:test_Constructor_Success() (gas: 13074) +Router_constructor:test_Constructor_Success() (gas: 13070) Router_getArmProxy:test_getArmProxy() (gas: 10561) Router_getFee:test_GetFeeSupportedChain_Success() (gas: 46458) Router_getFee:test_UnsupportedDestinationChain_Revert() (gas: 17138) @@ -905,11 +896,11 @@ Router_recoverTokens:test_RecoverTokensNonOwner_Revert() (gas: 11159) Router_recoverTokens:test_RecoverTokensValueReceiver_Revert() (gas: 422138) Router_recoverTokens:test_RecoverTokens_Success() (gas: 52437) Router_routeMessage:test_AutoExec_Success() (gas: 42684) -Router_routeMessage:test_ExecutionEvent_Success() (gas: 157980) +Router_routeMessage:test_ExecutionEvent_Success() (gas: 157989) Router_routeMessage:test_ManualExec_Success() (gas: 35381) Router_routeMessage:test_OnlyOffRamp_Revert() (gas: 25116) Router_routeMessage:test_WhenNotHealthy_Revert() (gas: 44724) -Router_setWrappedNative:test_OnlyOwner_Revert() (gas: 10985) +Router_setWrappedNative:test_OnlyOwner_Revert() (gas: 10986) SelfFundedPingPong_ccipReceive:test_FundingIfNotANop_Revert() (gas: 55531) SelfFundedPingPong_ccipReceive:test_Funding_Success() (gas: 419466) SelfFundedPingPong_setCountIncrBeforeFunding:test_setCountIncrBeforeFunding() (gas: 20151) @@ -921,33 +912,33 @@ TokenAdminRegistry_getAllConfiguredTokens:test_getAllConfiguredTokens_outOfBound TokenAdminRegistry_getPool:test_getPool_Success() (gas: 17581) TokenAdminRegistry_getPools:test_getPools_Success() (gas: 39902) TokenAdminRegistry_isAdministrator:test_isAdministrator_Success() (gas: 105922) -TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_AlreadyRegistered_Revert() (gas: 104001) -TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_OnlyRegistryModule_Revert() (gas: 15481) -TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_ZeroAddress_Revert() (gas: 15026) -TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_module_Success() (gas: 112536) -TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_owner_Success() (gas: 107656) -TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_reRegisterWhileUnclaimed_Success() (gas: 115686) +TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_AlreadyRegistered_Revert() (gas: 104037) +TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_OnlyRegistryModule_Revert() (gas: 15493) +TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_ZeroAddress_Revert() (gas: 15038) +TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_module_Success() (gas: 112548) +TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_owner_Success() (gas: 107668) +TokenAdminRegistry_proposeAdministrator:test_proposeAdministrator_reRegisterWhileUnclaimed_Success() (gas: 115698) TokenAdminRegistry_removeRegistryModule:test_removeRegistryModule_OnlyOwner_Revert() (gas: 12585) TokenAdminRegistry_removeRegistryModule:test_removeRegistryModule_Success() (gas: 54473) -TokenAdminRegistry_setPool:test_setPool_InvalidTokenPoolToken_Revert() (gas: 19148) +TokenAdminRegistry_setPool:test_setPool_InvalidTokenPoolToken_Revert() (gas: 19154) TokenAdminRegistry_setPool:test_setPool_OnlyAdministrator_Revert() (gas: 18020) -TokenAdminRegistry_setPool:test_setPool_Success() (gas: 35943) -TokenAdminRegistry_setPool:test_setPool_ZeroAddressRemovesPool_Success() (gas: 30617) +TokenAdminRegistry_setPool:test_setPool_Success() (gas: 35949) +TokenAdminRegistry_setPool:test_setPool_ZeroAddressRemovesPool_Success() (gas: 30623) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_OnlyAdministrator_Revert() (gas: 18043) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_Success() (gas: 49390) -TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6070353) -TokenPoolAndProxy:test_lockOrBurn_burnWithFromMint_Success() (gas: 6101826) -TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6319594) +TokenPoolAndProxy:test_lockOrBurn_burnMint_Success() (gas: 6070356) +TokenPoolAndProxy:test_lockOrBurn_burnWithFromMint_Success() (gas: 6101829) +TokenPoolAndProxy:test_lockOrBurn_lockRelease_Success() (gas: 6319597) TokenPoolAndProxy:test_setPreviousPool_Success() (gas: 3387124) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6916278) -TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7100303) -TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2209837) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_2() (gas: 6916281) +TokenPoolAndProxyMigration:test_tokenPoolMigration_Success_1_4() (gas: 7100309) +TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2209840) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12089) -TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23324) -TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowList_Success() (gas: 177568) -TokenPoolWithAllowList_getAllowList:test_GetAllowList_Success() (gas: 23670) +TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23464) +TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowList_Success() (gas: 177792) +TokenPoolWithAllowList_getAllowList:test_GetAllowList_Success() (gas: 23740) TokenPoolWithAllowList_getAllowListEnabled:test_GetAllowListEnabled_Success() (gas: 8363) -TokenPoolWithAllowList_setRouter:test_SetRouter_Success() (gas: 24831) +TokenPoolWithAllowList_setRouter:test_SetRouter_Success() (gas: 24843) TokenPool_applyChainUpdates:test_applyChainUpdates_DisabledNonZeroRateLimit_Revert() (gas: 271305) TokenPool_applyChainUpdates:test_applyChainUpdates_InvalidRateLimitRate_Revert() (gas: 541162) TokenPool_applyChainUpdates:test_applyChainUpdates_NonExistentChain_Revert() (gas: 18344) @@ -957,14 +948,14 @@ TokenPool_applyChainUpdates:test_applyChainUpdates_ZeroAddressNotAllowed_Revert( TokenPool_constructor:test_ZeroAddressNotAllowed_Revert() (gas: 70721) TokenPool_constructor:test_immutableFields_Success() (gas: 20544) TokenPool_getRemotePool:test_getRemotePool_Success() (gas: 273962) -TokenPool_onlyOffRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 276909) -TokenPool_onlyOffRamp:test_ChainNotAllowed_Revert() (gas: 289406) -TokenPool_onlyOffRamp:test_onlyOffRamp_Success() (gas: 349720) -TokenPool_onlyOnRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 276643) -TokenPool_onlyOnRamp:test_ChainNotAllowed_Revert() (gas: 253432) -TokenPool_onlyOnRamp:test_onlyOnRamp_Success() (gas: 304761) -TokenPool_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 17061) -TokenPool_setChainRateLimiterConfig:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 15062) +TokenPool_onlyOffRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 276921) +TokenPool_onlyOffRamp:test_ChainNotAllowed_Revert() (gas: 289432) +TokenPool_onlyOffRamp:test_onlyOffRamp_Success() (gas: 349729) +TokenPool_onlyOnRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 276655) +TokenPool_onlyOnRamp:test_ChainNotAllowed_Revert() (gas: 253458) +TokenPool_onlyOnRamp:test_onlyOnRamp_Success() (gas: 304770) +TokenPool_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 17073) +TokenPool_setChainRateLimiterConfig:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 15074) TokenPool_setRemotePool:test_setRemotePool_NonExistentChain_Reverts() (gas: 15620) TokenPool_setRemotePool:test_setRemotePool_OnlyOwner_Reverts() (gas: 13195) TokenPool_setRemotePool:test_setRemotePool_Success() (gas: 281912) @@ -977,16 +968,16 @@ TokenProxy_ccipSend:test_CcipSend_Success() (gas: 261558) TokenProxy_constructor:test_Constructor() (gas: 13812) TokenProxy_getFee:test_GetFeeGasShouldBeZero_Revert() (gas: 16827) TokenProxy_getFee:test_GetFeeInvalidToken_Revert() (gas: 12658) -TokenProxy_getFee:test_GetFeeNoDataAllowed_Revert() (gas: 15849) +TokenProxy_getFee:test_GetFeeNoDataAllowed_Revert() (gas: 15852) TokenProxy_getFee:test_GetFee_Success() (gas: 86690) -USDCTokenPool__validateMessage:test_ValidateInvalidMessage_Revert() (gas: 25290) -USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35322) -USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 30073) -USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 133102) -USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 477183) -USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 268111) -USDCTokenPool_releaseOrMint:test_TokenMaxCapacityExceeded_Revert() (gas: 50676) -USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 98591) -USDCTokenPool_setDomains:test_InvalidDomain_Revert() (gas: 66150) +USDCTokenPool__validateMessage:test_ValidateInvalidMessage_Revert() (gas: 25338) +USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35352) +USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 30094) +USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 133112) +USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 477240) +USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 268166) +USDCTokenPool_releaseOrMint:test_TokenMaxCapacityExceeded_Revert() (gas: 50700) +USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 98609) +USDCTokenPool_setDomains:test_InvalidDomain_Revert() (gas: 66174) USDCTokenPool_setDomains:test_OnlyOwner_Revert() (gas: 11333) USDCTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 9876) \ No newline at end of file diff --git a/contracts/package.json b/contracts/package.json index ea700c87d4..d80e94159a 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -70,7 +70,7 @@ "moment": "^2.30.1", "prettier": "^3.3.3", "prettier-plugin-solidity": "^1.3.1", - "solhint": "^5.0.3", + "solhint": "^5.0.1", "solhint-plugin-chainlink-solidity": "git+https://github.com/smartcontractkit/chainlink-solhint-rules.git#v1.2.1", "solhint-plugin-prettier": "^0.1.0", "ts-node": "^10.9.2", diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index 237b334fc4..f087dd7cd4 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -145,8 +145,8 @@ importers: specifier: ^1.3.1 version: 1.3.1(prettier@3.3.3) solhint: - specifier: ^5.0.3 - version: 5.0.3 + specifier: ^5.0.1 + version: 5.0.1 solhint-plugin-chainlink-solidity: specifier: git+https://github.com/smartcontractkit/chainlink-solhint-rules.git#v1.2.1 version: '@chainlink/solhint-plugin-chainlink-solidity@https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c' @@ -1700,7 +1700,6 @@ packages: glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} - deprecated: Glob versions prior to v9 are no longer supported globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} @@ -2071,6 +2070,9 @@ packages: resolution: {integrity: sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==} engines: {node: '>=10.0.0'} + keyv@4.5.0: + resolution: {integrity: sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -2747,8 +2749,8 @@ packages: prettier: ^3.0.0 prettier-plugin-solidity: ^1.0.0 - solhint@5.0.3: - resolution: {integrity: sha512-OLCH6qm/mZTCpplTXzXTJGId1zrtNuDYP5c2e6snIv/hdRVxPfBBz/bAlL91bY/Accavkayp2Zp2BaDSrLVXTQ==} + solhint@5.0.1: + resolution: {integrity: sha512-QeQLS9HGCnIiibt+xiOa/+MuP7BWz9N7C5+Mj9pLHshdkNhuo3AzCpWmjfWVZBUuwIUO3YyCRVIcYLR3YOKGfg==} hasBin: true solidity-ast@0.4.56: @@ -4611,7 +4613,7 @@ snapshots: clone-response: 1.0.2 get-stream: 5.1.0 http-cache-semantics: 4.0.3 - keyv: 4.5.4 + keyv: 4.5.0 lowercase-keys: 2.0.0 normalize-url: 6.1.0 responselike: 2.0.1 @@ -5967,6 +5969,10 @@ snapshots: node-gyp-build: 4.5.0 readable-stream: 3.6.0 + keyv@4.5.0: + dependencies: + json-buffer: 3.0.1 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -6666,7 +6672,7 @@ snapshots: prettier-linter-helpers: 1.0.0 prettier-plugin-solidity: 1.3.1(prettier@3.3.3) - solhint@5.0.3: + solhint@5.0.1: dependencies: '@solidity-parser/parser': 0.18.0 ajv: 6.12.6 @@ -6677,7 +6683,7 @@ snapshots: cosmiconfig: 8.2.0 fast-diff: 1.2.0 glob: 8.1.0 - ignore: 5.3.1 + ignore: 5.2.4 js-yaml: 4.1.0 latest-version: 7.0.0 lodash: 4.17.21 diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index 7b2c580b3c..64fcd9f435 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -10,7 +10,7 @@ SOLC_VERSION="0.8.24" OPTIMIZE_RUNS=26000 OPTIMIZE_RUNS_OFFRAMP=18000 OPTIMIZE_RUNS_ONRAMP=4100 -OPTIMIZE_RUNS_MULTI_OFFRAMP=2000 +OPTIMIZE_RUNS_MULTI_OFFRAMP=1999 SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" @@ -59,6 +59,7 @@ compileContract () { # Contracts should be ordered in reverse-import-complexity-order to minimize overwrite risks. compileContract ccip/offRamp/EVM2EVMOffRamp.sol compileContract ccip/offRamp/OffRamp.sol +compileContract ccip/rmn/RMNRemote.sol compileContract ccip/applications/PingPongDemo.sol compileContract ccip/applications/SelfFundedPingPong.sol compileContract ccip/applications/EtherSenderReceiver.sol diff --git a/contracts/src/v0.8/ccip/FeeQuoter.sol b/contracts/src/v0.8/ccip/FeeQuoter.sol index 970485e90f..957d146f45 100644 --- a/contracts/src/v0.8/ccip/FeeQuoter.sol +++ b/contracts/src/v0.8/ccip/FeeQuoter.sol @@ -467,8 +467,6 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, uint256 numberOfTokens = message.tokenAmounts.length; _validateMessage(destChainConfig, message.data.length, numberOfTokens, message.receiver); - uint64 premiumMultiplierWeiPerEth = s_premiumMultiplierWeiPerEth[message.feeToken]; - // The below call asserts that feeToken is a supported token (uint224 feeTokenPrice, uint224 packedGasPrice) = getTokenAndGasPrices(message.feeToken, destChainSelector); @@ -511,7 +509,6 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, // NOTE: when supporting non-EVM chains, revisit how generic this fee logic can be // NOTE: revisit parsing non-EVM args - uint256 executionCost = uint112(packedGasPrice) * ( destChainConfig.destGasOverhead + (message.data.length * destChainConfig.destGasPerPayloadByte) + tokenTransferGas @@ -521,7 +518,8 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, // Calculate number of fee tokens to charge. // Total USD fee is in 36 decimals, feeTokenPrice is in 18 decimals USD for 1e18 smallest token denominations. // Result of the division is the number of smallest token denominations. - return ((premiumFee * premiumMultiplierWeiPerEth) + executionCost + dataAvailabilityCost) / feeTokenPrice; + return ((premiumFee * s_premiumMultiplierWeiPerEth[message.feeToken]) + executionCost + dataAvailabilityCost) + / feeTokenPrice; } /// @notice Sets the fee configuration for a token. diff --git a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol index ae1e4cc597..463a710335 100644 --- a/contracts/src/v0.8/ccip/capability/CCIPConfig.sol +++ b/contracts/src/v0.8/ccip/capability/CCIPConfig.sol @@ -6,8 +6,6 @@ import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; import {ICapabilitiesRegistry} from "./interfaces/ICapabilitiesRegistry.sol"; import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; - -import {SortedSetValidationUtil} from "../../shared/util/SortedSetValidationUtil.sol"; import {Internal} from "../libraries/Internal.sol"; import {CCIPConfigTypes} from "./libraries/CCIPConfigTypes.sol"; @@ -26,7 +24,6 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator /// @param chainSelector The chain selector. /// @param chainConfig The chain configuration. event ChainConfigSet(uint64 chainSelector, CCIPConfigTypes.ChainConfig chainConfig); - /// @notice Emitted when a chain's configuration is removed. /// @param chainSelector The chain selector. event ChainConfigRemoved(uint64 chainSelector); @@ -37,8 +34,6 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator error ChainSelectorNotSet(); error TooManyOCR3Configs(); error TooManySigners(); - error TooManyTransmitters(); - error TooManyBootstrapP2PIds(); error P2PIdsLengthNotMatching(uint256 p2pIdsLength, uint256 signersLength, uint256 transmittersLength); error NotEnoughTransmitters(uint256 got, uint256 minimum); error FMustBePositive(); @@ -62,6 +57,15 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator /// @notice The canonical capabilities registry address. address internal immutable i_capabilitiesRegistry; + uint8 internal constant MAX_OCR3_CONFIGS_PER_PLUGIN = 2; + uint8 internal constant MAX_OCR3_CONFIGS_PER_DON = 4; + uint256 internal constant CONFIG_DIGEST_PREFIX_MASK = type(uint256).max << (256 - 16); // 0xFFFF00..0 + /// @dev must be equal to libocr multi role: https://github.com/smartcontractkit/libocr/blob/ae747ca5b81236ffdbf1714318c652e923a5ff4d/offchainreporting2plus/types/config_digest.go#L28 + uint256 internal constant CONFIG_DIGEST_PREFIX = 0x000a << (256 - 16); // 0x000a00..00 + bytes32 internal constant EMPTY_ENCODED_ADDRESS_HASH = keccak256(abi.encode(address(0))); + /// @dev 256 is the hard limit due to the bit encoding of their indexes into a uint256. + uint256 internal constant MAX_NUM_ORACLES = 256; + /// @notice chain configuration for each chain that CCIP is deployed on. mapping(uint64 chainSelector => CCIPConfigTypes.ChainConfig chainConfig) internal s_chainConfigurations; @@ -75,13 +79,6 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator uint32 donId => mapping(Internal.OCRPluginType pluginType => CCIPConfigTypes.OCR3ConfigWithMeta[] ocr3Configs) ) internal s_ocr3Configs; - uint8 internal constant MAX_OCR3_CONFIGS_PER_PLUGIN = 2; - uint8 internal constant MAX_OCR3_CONFIGS_PER_DON = 4; - uint8 internal constant MAX_NUM_ORACLES = 31; - uint256 internal constant CONFIG_DIGEST_PREFIX_MASK = type(uint256).max << (256 - 16); // 0xFFFF00..0 - /// @dev must be equal to libocr multi role: https://github.com/smartcontractkit/libocr/blob/ae747ca5b81236ffdbf1714318c652e923a5ff4d/offchainreporting2plus/types/config_digest.go#L28 - uint256 internal constant CONFIG_DIGEST_PREFIX = 0x000a << (256 - 16); // 0x000a00..00 - /// @param capabilitiesRegistry the canonical capabilities registry address. constructor(address capabilitiesRegistry) { if (capabilitiesRegistry == address(0)) { @@ -172,9 +169,8 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator revert OnlyCapabilitiesRegistryCanCall(); } - CCIPConfigTypes.OCR3Config[] memory ocr3Configs = abi.decode(config, (CCIPConfigTypes.OCR3Config[])); (CCIPConfigTypes.OCR3Config[] memory commitConfigs, CCIPConfigTypes.OCR3Config[] memory execConfigs) = - _groupByPluginType(ocr3Configs); + _groupByPluginType(abi.decode(config, (CCIPConfigTypes.OCR3Config[]))); if (commitConfigs.length > 0) { _updatePluginConfig(donId, Internal.OCRPluginType.Commit, commitConfigs); } @@ -363,8 +359,8 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator // access in the for loop below. commitConfigs = new CCIPConfigTypes.OCR3Config[](MAX_OCR3_CONFIGS_PER_PLUGIN); execConfigs = new CCIPConfigTypes.OCR3Config[](MAX_OCR3_CONFIGS_PER_PLUGIN); - uint256 commitCount; - uint256 execCount; + uint256 commitCount = 0; + uint256 execCount = 0; for (uint256 i = 0; i < ocr3Configs.length; ++i) { if (ocr3Configs[i].pluginType == Internal.OCRPluginType.Commit) { commitConfigs[commitCount] = ocr3Configs[i]; @@ -391,36 +387,26 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator if (cfg.pluginType != Internal.OCRPluginType.Commit && cfg.pluginType != Internal.OCRPluginType.Execution) { revert InvalidPluginType(); } - // TODO: can we do more sophisticated validation than this? - if (cfg.offrampAddress.length == 0) revert OfframpAddressCannotBeZero(); + if (cfg.offrampAddress.length == 0 || keccak256(cfg.offrampAddress) == EMPTY_ENCODED_ADDRESS_HASH) { + revert OfframpAddressCannotBeZero(); + } if (!s_remoteChainSelectors.contains(cfg.chainSelector)) revert ChainSelectorNotFound(cfg.chainSelector); - // Some of these checks below are done in OCR2/3Base config validation, so we do them again here. - // Role DON OCR configs will have all the Role DON signers but only a subset of transmitters. - if (cfg.signers.length > MAX_NUM_ORACLES) revert TooManySigners(); - if (cfg.transmitters.length > MAX_NUM_ORACLES) revert TooManyTransmitters(); - // We check for chain config presence above, so fChain here must be non-zero. uint256 minTransmittersLength = 3 * s_chainConfigurations[cfg.chainSelector].fChain + 1; if (cfg.transmitters.length < minTransmittersLength) { revert NotEnoughTransmitters(cfg.transmitters.length, minTransmittersLength); } - if (cfg.F == 0) revert FMustBePositive(); - if (cfg.signers.length <= 3 * cfg.F) revert FTooHigh(); - - if (cfg.p2pIds.length != cfg.signers.length || cfg.p2pIds.length != cfg.transmitters.length) { + uint256 numberOfSigners = cfg.signers.length; + if (numberOfSigners > MAX_NUM_ORACLES) revert TooManySigners(); + if (numberOfSigners != cfg.p2pIds.length || numberOfSigners != cfg.transmitters.length) { revert P2PIdsLengthNotMatching(cfg.p2pIds.length, cfg.signers.length, cfg.transmitters.length); } - if (cfg.bootstrapP2PIds.length > cfg.p2pIds.length) revert TooManyBootstrapP2PIds(); - - // check for duplicate p2p ids and bootstrapP2PIds. - // check that p2p ids in cfg.bootstrapP2PIds are included in cfg.p2pIds. - SortedSetValidationUtil._checkIsValidUniqueSubset(cfg.bootstrapP2PIds, cfg.p2pIds); + if (cfg.F == 0) revert FMustBePositive(); + if (numberOfSigners <= 3 * cfg.F) revert FTooHigh(); // Check that the readers are in the capabilities registry. - for (uint256 i = 0; i < cfg.signers.length; ++i) { - _ensureInRegistry(cfg.p2pIds[i]); - } + _ensureInRegistry(cfg.p2pIds); } /// @notice Computes the digest of the provided configuration. @@ -445,7 +431,6 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator ocr3Config.pluginType, ocr3Config.offrampAddress, configCount, - ocr3Config.bootstrapP2PIds, ocr3Config.p2pIds, ocr3Config.signers, ocr3Config.transmitters, @@ -486,13 +471,10 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator // Process additions next. for (uint256 i = 0; i < chainConfigAdds.length; ++i) { CCIPConfigTypes.ChainConfig memory chainConfig = chainConfigAdds[i].chainConfig; - bytes32[] memory readers = chainConfig.readers; uint64 chainSelector = chainConfigAdds[i].chainSelector; // Verify that the provided readers are present in the capabilities registry. - for (uint256 j = 0; j < readers.length; j++) { - _ensureInRegistry(readers[j]); - } + _ensureInRegistry(chainConfig.readers); // Verify that fChain is positive. if (chainConfig.fChain == 0) { @@ -507,11 +489,13 @@ contract CCIPConfig is ITypeAndVersion, ICapabilityConfiguration, OwnerIsCreator } /// @notice Helper function to ensure that a node is in the capabilities registry. - /// @param p2pId The P2P ID of the node to check. - function _ensureInRegistry(bytes32 p2pId) internal view { - ICapabilitiesRegistry.NodeInfo memory node = ICapabilitiesRegistry(i_capabilitiesRegistry).getNode(p2pId); - if (node.p2pId == bytes32("")) { - revert NodeNotInRegistry(p2pId); + /// @param p2pIds The P2P IDs of the node to check. + function _ensureInRegistry(bytes32[] memory p2pIds) internal view { + for (uint256 i = 0; i < p2pIds.length; ++i) { + // TODO add a method that does the validation in the ICapabilitiesRegistry contract + if (ICapabilitiesRegistry(i_capabilitiesRegistry).getNode(p2pIds[i]).p2pId == bytes32("")) { + revert NodeNotInRegistry(p2pIds[i]); + } } } } diff --git a/contracts/src/v0.8/ccip/capability/libraries/CCIPConfigTypes.sol b/contracts/src/v0.8/ccip/capability/libraries/CCIPConfigTypes.sol index 99adef84b1..2148f991c8 100644 --- a/contracts/src/v0.8/ccip/capability/libraries/CCIPConfigTypes.sol +++ b/contracts/src/v0.8/ccip/capability/libraries/CCIPConfigTypes.sol @@ -37,8 +37,6 @@ library CCIPConfigTypes { uint8 F; // | The "big F" parameter for the role DON. uint64 offchainConfigVersion; // ─────────────╯ The version of the offchain configuration. bytes offrampAddress; // The remote chain offramp address. - // NOTE: bootstrapP2PIds and p2pIds should be sent as sorted sets - bytes32[] bootstrapP2PIds; // The bootstrap P2P IDs of the oracles that are part of the role DON. // len(p2pIds) == len(signers) == len(transmitters) == 3 * F + 1 // NOTE: indexes matter here! The p2p ID at index i corresponds to the signer at index i and the transmitter at index i. // This is crucial in order to build the oracle ID <-> peer ID mapping offchain. diff --git a/contracts/src/v0.8/ccip/interfaces/IRMNV2.sol b/contracts/src/v0.8/ccip/interfaces/IRMNV2.sol new file mode 100644 index 0000000000..9af3de6cab --- /dev/null +++ b/contracts/src/v0.8/ccip/interfaces/IRMNV2.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Internal} from "../libraries/Internal.sol"; + +/// @notice This interface contains the only RMN-related functions that might be used on-chain by other CCIP contracts. +interface IRMNV2 { + /// @notice signature components from RMN nodes + struct Signature { + bytes32 r; + bytes32 s; + } + + function verify(Internal.MerkleRoot[] memory merkleRoots, Signature[] memory signatures) external view; + + /// @notice If there is an active global or legacy curse, this function returns true. + function isCursed() external view returns (bool); + + /// @notice If there is an active global curse, or an active curse for `subject`, this function returns true. + /// @param subject To check whether a particular chain is cursed, set to bytes16(uint128(chainSelector)). + function isCursed(bytes16 subject) external view returns (bool); +} diff --git a/contracts/src/v0.8/ccip/libraries/Internal.sol b/contracts/src/v0.8/ccip/libraries/Internal.sol index 9b251eedcf..58ae6279b8 100644 --- a/contracts/src/v0.8/ccip/libraries/Internal.sol +++ b/contracts/src/v0.8/ccip/libraries/Internal.sol @@ -338,4 +338,14 @@ library Internal { // bytes4(keccak256("CCIP ChainFamilySelector EVM")) bytes4 public constant CHAIN_FAMILY_SELECTOR_EVM = 0x2812d52c; + + /// @dev Struct to hold a merkle root and an interval for a source chain so that an array of these can be passed in the CommitReport. + /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + struct MerkleRoot { + uint64 sourceChainSelector; // ──╮ Remote source chain selector that the Merkle Root is scoped to + uint64 minSeqNr; // | Minimum sequence number, inclusive + uint64 maxSeqNr; // ─────────────╯ Maximum sequence number, inclusive + bytes32 merkleRoot; // Merkle root covering the interval & source chain messages + bytes onRampAddress; // Generic onramp address, to support arbitrary sources; for EVM, use abi.encode + } } diff --git a/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol b/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol index 0b90f88c11..c9fff4d624 100644 --- a/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol +++ b/contracts/src/v0.8/ccip/ocr/MultiOCR3Base.sol @@ -8,7 +8,7 @@ import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; /// with multiple OCR plugin support. abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { // Maximum number of oracles the offchain reporting protocol is designed for - uint256 internal constant MAX_NUM_ORACLES = 31; + uint256 internal constant MAX_NUM_ORACLES = 256; /// @notice Triggers a new run of the offchain reporting protocol /// @param ocrPluginType OCR plugin type for which the config was set @@ -146,10 +146,7 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { } address[] memory transmitters = ocrConfigArgs.transmitters; - // Transmitters are expected to never exceed 255 (since this is bounded by MAX_NUM_ORACLES) - uint8 newTransmittersLength = uint8(transmitters.length); - - if (newTransmittersLength > MAX_NUM_ORACLES) revert InvalidConfig(InvalidConfigErrorType.TOO_MANY_TRANSMITTERS); + if (transmitters.length > MAX_NUM_ORACLES) revert InvalidConfig(InvalidConfigErrorType.TOO_MANY_TRANSMITTERS); _clearOracleRoles(ocrPluginType, ocrConfig.transmitters); @@ -157,13 +154,12 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { _clearOracleRoles(ocrPluginType, ocrConfig.signers); address[] memory signers = ocrConfigArgs.signers; - ocrConfig.signers = signers; - uint8 signersLength = uint8(signers.length); - configInfo.n = signersLength; + if (signers.length > MAX_NUM_ORACLES) revert InvalidConfig(InvalidConfigErrorType.TOO_MANY_SIGNERS); + if (signers.length <= 3 * ocrConfigArgs.F) revert InvalidConfig(InvalidConfigErrorType.F_TOO_HIGH); - if (signersLength > MAX_NUM_ORACLES) revert InvalidConfig(InvalidConfigErrorType.TOO_MANY_SIGNERS); - if (signersLength <= 3 * ocrConfigArgs.F) revert InvalidConfig(InvalidConfigErrorType.F_TOO_HIGH); + configInfo.n = uint8(signers.length); + ocrConfig.signers = signers; _assignOracleRoles(ocrPluginType, signers, Role.Signer); } @@ -198,13 +194,13 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { /// @param oracleAddresses Oracle addresses to assign roles to. /// @param role Role to assign. function _assignOracleRoles(uint8 ocrPluginType, address[] memory oracleAddresses, Role role) internal { - for (uint8 i = 0; i < oracleAddresses.length; ++i) { + for (uint256 i = 0; i < oracleAddresses.length; ++i) { address oracle = oracleAddresses[i]; if (s_oracles[ocrPluginType][oracle].role != Role.Unset) { revert InvalidConfig(InvalidConfigErrorType.REPEATED_ORACLE_ADDRESS); } if (oracle == address(0)) revert OracleCannotBeZeroAddress(); - s_oracles[ocrPluginType][oracle] = Oracle(i, role); + s_oracles[ocrPluginType][oracle] = Oracle(uint8(i), role); } } @@ -291,21 +287,20 @@ abstract contract MultiOCR3Base is ITypeAndVersion, OwnerIsCreator { bytes32 hashedReport, bytes32[] memory rs, bytes32[] memory ss, - bytes32 rawVs // signatures + bytes32 rawVs ) internal view { - // Verify signatures attached to report - bool[MAX_NUM_ORACLES] memory signed; + // Verify signatures attached to report. Using a uint256 means we can only verify up to 256 oracles. + uint256 signed = 0; uint256 numberOfSignatures = rs.length; for (uint256 i; i < numberOfSignatures; ++i) { // Safe from ECDSA malleability here since we check for duplicate signers. address signer = ecrecover(hashedReport, uint8(rawVs[i]) + 27, rs[i], ss[i]); - // Since we disallow address(0) as a valid signer address, it can - // never have a signer role. + // Since we disallow address(0) as a valid signer address, it can never have a signer role. Oracle memory oracle = s_oracles[ocrPluginType][signer]; if (oracle.role != Role.Signer) revert UnauthorizedSigner(); - if (signed[oracle.index]) revert NonUniqueSignatures(); - signed[oracle.index] = true; + if (signed & (0x1 << oracle.index) != 0) revert NonUniqueSignatures(); + signed |= 0x1 << oracle.index; } } diff --git a/contracts/src/v0.8/ccip/offRamp/OffRamp.sol b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol index d594597d18..10bde4c251 100644 --- a/contracts/src/v0.8/ccip/offRamp/OffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol @@ -3,12 +3,11 @@ pragma solidity 0.8.24; import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; import {IAny2EVMMessageReceiver} from "../interfaces/IAny2EVMMessageReceiver.sol"; - import {IFeeQuoter} from "../interfaces/IFeeQuoter.sol"; import {IMessageInterceptor} from "../interfaces/IMessageInterceptor.sol"; import {INonceManager} from "../interfaces/INonceManager.sol"; import {IPoolV1} from "../interfaces/IPool.sol"; -import {IRMN} from "../interfaces/IRMN.sol"; +import {IRMNV2} from "../interfaces/IRMNV2.sol"; import {IRouter} from "../interfaces/IRouter.sol"; import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol"; @@ -56,7 +55,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { error InvalidNewState(uint64 sourceChainSelector, uint64 sequenceNumber, Internal.MessageExecutionState newState); error InvalidStaticConfig(uint64 sourceChainSelector); error StaleCommitReport(); - error InvalidInterval(uint64 sourceChainSelector, Interval interval); + error InvalidInterval(uint64 sourceChainSelector, uint64 min, uint64 max); error ZeroAddressNotAllowed(); error InvalidMessageDestChainSelector(uint64 messageDestChainSelector); @@ -80,12 +79,16 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @dev RMN depends on this event, if changing, please notify the RMN maintainers. event CommitReportAccepted(CommitReport report); event RootRemoved(bytes32 root); + event SkippedReportExecution(uint64 sourceChainSelector); /// @notice Struct that contains the static configuration /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. + /// @dev not sure why solhint complains about this, seems like a buggy detector + /// https://github.com/protofire/solhint/issues/597 + // solhint-disable-next-line gas-struct-packing struct StaticConfig { uint64 chainSelector; // ───╮ Destination chainSelector - address rmnProxy; // ───────╯ RMN proxy address + IRMNV2 rmn; // ─────────────╯ RMN Verification Contract address tokenAdminRegistry; // Token admin registry address address nonceManager; // Nonce manager address } @@ -117,39 +120,20 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { address messageValidator; // Optional message validator to validate incoming messages (zero address = no validator) } - /// @notice a sequenceNumber interval - /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. - struct Interval { - uint64 min; // ───╮ Minimum sequence number, inclusive - uint64 max; // ───╯ Maximum sequence number, inclusive - } - - /// @dev Struct to hold a merkle root and an interval for a source chain so that an array of these can be passed in the CommitReport. - struct MerkleRoot { - uint64 sourceChainSelector; // Remote source chain selector that the Merkle Root is scoped to - Interval interval; // Report interval of the merkle root - bytes32 merkleRoot; // Merkle root covering the interval & source chain messages - } - /// @notice Report that is committed by the observing DON at the committing phase /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. struct CommitReport { Internal.PriceUpdates priceUpdates; // Collection of gas and price updates to commit - MerkleRoot[] merkleRoots; // Collection of merkle roots per source chain to commit - } - - /// @dev Struct to hold a merkle root for a source chain so that an array of these can be passed in the resetUblessedRoots function. - struct UnblessedRoot { - uint64 sourceChainSelector; // Remote source chain selector that the Merkle Root is scoped to - bytes32 merkleRoot; // Merkle root of a single remote source chain + Internal.MerkleRoot[] merkleRoots; // Collection of merkle roots per source chain to commit + IRMNV2.Signature[] rmnSignatures; // RMN signatures on the merkle roots } // STATIC CONFIG string public constant override typeAndVersion = "OffRamp 1.6.0-dev"; /// @dev ChainSelector of this chain uint64 internal immutable i_chainSelector; - /// @dev The address of the RMN proxy - address internal immutable i_rmnProxy; + /// @dev The RMN verification contract + IRMNV2 internal immutable i_rmn; /// @dev The address of the token admin registry address internal immutable i_tokenAdminRegistry; /// @dev The address of the nonce manager @@ -180,7 +164,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { SourceChainConfigArgs[] memory sourceChainConfigs ) MultiOCR3Base() { if ( - staticConfig.rmnProxy == address(0) || staticConfig.tokenAdminRegistry == address(0) + address(staticConfig.rmn) == address(0) || staticConfig.tokenAdminRegistry == address(0) || staticConfig.nonceManager == address(0) ) { revert ZeroAddressNotAllowed(); @@ -191,7 +175,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { } i_chainSelector = staticConfig.chainSelector; - i_rmnProxy = staticConfig.rmnProxy; + i_rmn = staticConfig.rmn; i_tokenAdminRegistry = staticConfig.tokenAdminRegistry; i_nonceManager = staticConfig.nonceManager; emit StaticConfigSet(staticConfig); @@ -342,9 +326,18 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { uint256[] memory manualExecGasLimits ) internal { uint64 sourceChainSelector = report.sourceChainSelector; - _whenNotCursed(sourceChainSelector); + bool manualExecution = manualExecGasLimits.length != 0; + if (i_rmn.isCursed(bytes16(uint128(sourceChainSelector)))) { + if (manualExecution) { + // For manual execution we don't want to silently fail so we revert + revert CursedByRMN(sourceChainSelector); + } + // For DON execution we do not revert as a single lane curse can revert the entire batch + emit SkippedReportExecution(sourceChainSelector); + return; + } - SourceChainConfig storage sourceChainConfig = _getEnabledSourceChainConfig(sourceChainSelector); + bytes memory onRamp = _getEnabledSourceChainConfig(sourceChainSelector).onRamp; uint256 numMsgs = report.messages.length; if (numMsgs == 0) revert EmptyReport(); @@ -365,7 +358,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { // over the same data, which increases gas cost. // Hashing all of the message fields ensures that the message being executed is correct and not tampered with. // Including the known OnRamp ensures that the message originates from the correct on ramp version - hashedLeaves[i] = Internal._hash(message, sourceChainConfig.onRamp); + hashedLeaves[i] = Internal._hash(message, onRamp); } // SECURITY CRITICAL CHECK @@ -374,7 +367,6 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { if (timestampCommitted == 0) revert RootNotCommitted(sourceChainSelector); // Execute messages - bool manualExecution = manualExecGasLimits.length != 0; for (uint256 i = 0; i < numMsgs; ++i) { uint256 gasStart = gasleft(); Internal.Any2EVMRampMessage memory message = report.messages[i]; @@ -445,7 +437,6 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { } _setExecutionState(sourceChainSelector, message.header.sequenceNumber, Internal.MessageExecutionState.IN_PROGRESS); - (Internal.MessageExecutionState newState, bytes memory returnData) = _trialExecute(message, offchainTokenData); _setExecutionState(sourceChainSelector, message.header.sequenceNumber, newState); @@ -477,6 +468,8 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { hashedLeaves[i], newState, returnData, + // This emit covers not only the execution through the router, but also all of the overhead in executing the + // message. This gives the most accurate representation of the gas used in the execution. gasStart - gasleft() ); } @@ -583,15 +576,20 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { ) external { CommitReport memory commitReport = abi.decode(report, (CommitReport)); + // Verify RMN signatures + if (commitReport.merkleRoots.length > 0) { + i_rmn.verify(commitReport.merkleRoots, commitReport.rmnSignatures); + } + // Check if the report contains price updates if (commitReport.priceUpdates.tokenPriceUpdates.length > 0 || commitReport.priceUpdates.gasPriceUpdates.length > 0) { - uint64 sequenceNumber = uint64(uint256(reportContext[1])); + uint64 ocrSequenceNumber = uint64(uint256(reportContext[1])); // Check for price staleness based on the epoch and round - if (s_latestPriceSequenceNumber < sequenceNumber) { + if (s_latestPriceSequenceNumber < ocrSequenceNumber) { // If prices are not stale, update the latest epoch and round - s_latestPriceSequenceNumber = sequenceNumber; + s_latestPriceSequenceNumber = ocrSequenceNumber; // And update the prices in the fee quoter IFeeQuoter(s_dynamicConfig.feeQuoter).updatePrices(commitReport.priceUpdates); } else { @@ -603,17 +601,19 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { } for (uint256 i = 0; i < commitReport.merkleRoots.length; ++i) { - MerkleRoot memory root = commitReport.merkleRoots[i]; + Internal.MerkleRoot memory root = commitReport.merkleRoots[i]; uint64 sourceChainSelector = root.sourceChainSelector; - _whenNotCursed(sourceChainSelector); + if (i_rmn.isCursed(bytes16(uint128(sourceChainSelector)))) { + revert CursedByRMN(sourceChainSelector); + } + SourceChainConfig storage sourceChainConfig = _getEnabledSourceChainConfig(sourceChainSelector); - if (sourceChainConfig.minSeqNr != root.interval.min || root.interval.min > root.interval.max) { - revert InvalidInterval(root.sourceChainSelector, root.interval); + if (sourceChainConfig.minSeqNr != root.minSeqNr || root.minSeqNr > root.maxSeqNr) { + revert InvalidInterval(root.sourceChainSelector, root.minSeqNr, root.maxSeqNr); } - // TODO: confirm how RMN offchain blessing impacts commit report bytes32 merkleRoot = root.merkleRoot; if (merkleRoot == bytes32(0)) revert InvalidRoot(); // If we reached this section, the report should contain a valid root @@ -623,7 +623,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { revert RootAlreadyCommitted(root.sourceChainSelector, merkleRoot); } - sourceChainConfig.minSeqNr = root.interval.max + 1; + sourceChainConfig.minSeqNr = root.maxSeqNr + 1; s_roots[root.sourceChainSelector][merkleRoot] = block.timestamp; } @@ -648,28 +648,6 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { return s_roots[sourceChainSelector][root]; } - /// @notice Returns if a root is blessed or not. - /// @param root The merkle root to check the blessing status for. - /// @return blessed Whether the root is blessed or not. - function isBlessed(bytes32 root) public view returns (bool) { - // TODO: update RMN to also consider the source chain selector for blessing - return IRMN(i_rmnProxy).isBlessed(IRMN.TaggedRoot({commitStore: address(this), root: root})); - } - - /// @notice Used by the owner in case an invalid sequence of roots has been - /// posted and needs to be removed. The interval in the report is trusted. - /// @param rootToReset The roots that will be reset. This function will only - /// reset roots that are not blessed. - function resetUnblessedRoots(UnblessedRoot[] calldata rootToReset) external onlyOwner { - for (uint256 i = 0; i < rootToReset.length; ++i) { - UnblessedRoot memory root = rootToReset[i]; - if (!isBlessed(root.merkleRoot)) { - delete s_roots[root.sourceChainSelector][root.merkleRoot]; - emit RootRemoved(root.merkleRoot); - } - } - } - /// @notice Returns timestamp of when root was accepted or 0 if verification fails. /// @dev This method uses a merkle tree within a merkle tree, with the hashedLeaves, /// proofs and proofFlagBits being used to get the root of the inner tree. @@ -682,10 +660,6 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { uint256 proofFlagBits ) internal view virtual returns (uint256 timestamp) { bytes32 root = MerkleMultiProof.merkleRoot(hashedLeaves, proofs, proofFlagBits); - // Only return non-zero if present and blessed. - if (!isBlessed(root)) { - return 0; - } return s_roots[sourceChainSelector][root]; } @@ -711,7 +685,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { function getStaticConfig() external view returns (StaticConfig memory) { return StaticConfig({ chainSelector: i_chainSelector, - rmnProxy: i_rmnProxy, + rmn: i_rmn, tokenAdminRegistry: i_tokenAdminRegistry, nonceManager: i_nonceManager }); @@ -958,12 +932,4 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { // solhint-disable-next-line revert(); } - - /// @notice Validates that the source chain -> this chain lane, and reverts if it is cursed - /// @param sourceChainSelector Source chain selector to check for cursing - function _whenNotCursed(uint64 sourceChainSelector) internal view { - if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(sourceChainSelector)))) { - revert CursedByRMN(sourceChainSelector); - } - } } diff --git a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol index 3587854e90..cc449feaed 100644 --- a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol @@ -7,7 +7,7 @@ import {IFeeQuoter} from "../interfaces/IFeeQuoter.sol"; import {IMessageInterceptor} from "../interfaces/IMessageInterceptor.sol"; import {INonceManager} from "../interfaces/INonceManager.sol"; import {IPoolV1} from "../interfaces/IPool.sol"; -import {IRMN} from "../interfaces/IRMN.sol"; +import {IRMNV2} from "../interfaces/IRMNV2.sol"; import {IRouter} from "../interfaces/IRouter.sol"; import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol"; @@ -48,7 +48,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { event FeePaid(address indexed feeToken, uint256 feeValueJuels); event FeeTokenWithdrawn(address indexed feeAggregator, address indexed feeToken, uint256 amount); /// RMN depends on this event, if changing, please notify the RMN maintainers. - event CCIPSendRequested(uint64 indexed destChainSelector, Internal.EVM2AnyRampMessage message); + event CCIPMessageSent(uint64 indexed destChainSelector, Internal.EVM2AnyRampMessage message); event AllowListAdminSet(address indexed allowListAdmin); event AllowListSendersAdded(uint64 indexed destChainSelector, address[] senders); event AllowListSendersRemoved(uint64 indexed destChainSelector, address[] senders); @@ -58,7 +58,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { // solhint-disable-next-line gas-struct-packing struct StaticConfig { uint64 chainSelector; // ─────╮ Source chain selector - address rmnProxy; // ─────────╯ RMN proxy address + IRMNV2 rmn; // ───────────────╯ RMN remote address address nonceManager; // Nonce manager address address tokenAdminRegistry; // Token admin registry address } @@ -99,7 +99,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { //solhint-disable gas-struct-packing struct AllowListConfigArgs { uint64 destChainSelector; // ─────────────╮ Destination chain selector - // │ destChainSelector and allowListEnabled are packed in the same slot + // │ destChainSelector and allowListEnabled are packed in the same slot bool allowListEnabled; // ────────────────╯ boolean indicator to specify if allowList check is enabled. address[] addedAllowlistedSenders; // list of senders to be added to the allowedSendersList address[] removedAllowlistedSenders; // list of senders to be removed from the allowedSendersList @@ -109,8 +109,8 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { string public constant override typeAndVersion = "OnRamp 1.6.0-dev"; /// @dev The chain ID of the source chain that this contract is deployed to uint64 internal immutable i_chainSelector; - /// @dev The address of the rmn proxy - address internal immutable i_rmnProxy; + /// @dev The rmn contract + IRMNV2 internal immutable i_rmn; /// @dev The address of the nonce manager address internal immutable i_nonceManager; /// @dev The address of the token admin registry @@ -129,14 +129,14 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { DestChainConfigArgs[] memory destChainConfigArgs ) { if ( - staticConfig.chainSelector == 0 || staticConfig.rmnProxy == address(0) || staticConfig.nonceManager == address(0) - || staticConfig.tokenAdminRegistry == address(0) + staticConfig.chainSelector == 0 || address(staticConfig.rmn) == address(0) + || staticConfig.nonceManager == address(0) || staticConfig.tokenAdminRegistry == address(0) ) { revert InvalidConfig(); } i_chainSelector = staticConfig.chainSelector; - i_rmnProxy = staticConfig.rmnProxy; + i_rmn = staticConfig.rmn; i_nonceManager = staticConfig.nonceManager; i_tokenAdminRegistry = staticConfig.tokenAdminRegistry; @@ -208,7 +208,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { }), sender: originalSender, data: message.data, - extraArgs: message.extraArgs, + extraArgs: convertedExtraArgs, receiver: message.receiver, feeToken: message.feeToken, feeTokenAmount: feeTokenAmount, @@ -232,9 +232,6 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { newMessage.tokenAmounts[i].destExecData = destExecDataPerToken[i]; } - // Override extraArgs with latest version - newMessage.extraArgs = convertedExtraArgs; - // Hash only after all fields have been set newMessage.header.messageId = Internal._hash( newMessage, @@ -246,7 +243,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { // Emit message request // This must happen after any pool events as some tokens (e.g. USDC) emit events that we expect to precede this // event in the offchain code. - emit CCIPSendRequested(destChainSelector, newMessage); + emit CCIPMessageSent(destChainSelector, newMessage); return newMessage.header.messageId; } @@ -302,7 +299,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { function getStaticConfig() external view returns (StaticConfig memory) { return StaticConfig({ chainSelector: i_chainSelector, - rmnProxy: i_rmnProxy, + rmn: i_rmn, nonceManager: i_nonceManager, tokenAdminRegistry: i_tokenAdminRegistry }); @@ -336,7 +333,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { emit ConfigSet( StaticConfig({ chainSelector: i_chainSelector, - rmnProxy: i_rmnProxy, + rmn: i_rmn, nonceManager: i_nonceManager, tokenAdminRegistry: i_tokenAdminRegistry }), @@ -425,8 +422,8 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { } } - for (uint256 k = 0; k < allowListConfigArgs.removedAllowlistedSenders.length; ++k) { - destChainConfig.allowedSendersList.remove(allowListConfigArgs.removedAllowlistedSenders[k]); + for (uint256 j = 0; j < allowListConfigArgs.removedAllowlistedSenders.length; ++j) { + destChainConfig.allowedSendersList.remove(allowListConfigArgs.removedAllowlistedSenders[j]); } if (allowListConfigArgs.removedAllowlistedSenders.length > 0) { @@ -464,7 +461,7 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { uint64 destChainSelector, Client.EVM2AnyMessage calldata message ) external view returns (uint256 feeTokenAmount) { - if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(destChainSelector)))) revert CursedByRMN(destChainSelector); + if (i_rmn.isCursed(bytes16(uint128(destChainSelector)))) revert CursedByRMN(destChainSelector); return IFeeQuoter(s_dynamicConfig.feeQuoter).getValidatedFee(destChainSelector, message); } diff --git a/contracts/src/v0.8/ccip/RMNHome.sol b/contracts/src/v0.8/ccip/rmn/RMNHome.sol similarity index 98% rename from contracts/src/v0.8/ccip/RMNHome.sol rename to contracts/src/v0.8/ccip/rmn/RMNHome.sol index f28a5da95b..0d3d7d9803 100644 --- a/contracts/src/v0.8/ccip/RMNHome.sol +++ b/contracts/src/v0.8/ccip/rmn/RMNHome.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.24; import "@openzeppelin/contracts/access/Ownable2Step.sol"; -import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; /// @notice Stores the home configuration for RMN, that is referenced by CCIP oracles, RMN nodes, and the RMNRemote /// contracts. diff --git a/contracts/src/v0.8/ccip/RMNRemote.sol b/contracts/src/v0.8/ccip/rmn/RMNRemote.sol similarity index 79% rename from contracts/src/v0.8/ccip/RMNRemote.sol rename to contracts/src/v0.8/ccip/rmn/RMNRemote.sol index 19b7f89e1b..3ebbf4af80 100644 --- a/contracts/src/v0.8/ccip/RMNRemote.sol +++ b/contracts/src/v0.8/ccip/rmn/RMNRemote.sol @@ -1,14 +1,16 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; -import "@openzeppelin/contracts/access/Ownable2Step.sol"; - -import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; +import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol"; +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; +import {IRMNV2} from "../interfaces/IRMNV2.sol"; +import {Internal} from "../libraries/Internal.sol"; bytes32 constant RMN_V1_6_ANY2EVM_REPORT = keccak256("RMN_V1_6_ANY2EVM_REPORT"); +/// @dev XXX DO NOT USE THIS CONTRACT, NOT PRODUCTION READY XXX /// @notice This contract supports verification of RMN reports for any Any2EVM OffRamp. -contract RMNRemote is Ownable2Step, ITypeAndVersion { +contract RMNRemote is OwnerIsCreator, ITypeAndVersion, IRMNV2 { /// @dev temp placeholder to exclude this contract from coverage function test() public {} @@ -85,27 +87,13 @@ contract RMNRemote is Ownable2Step, ITypeAndVersion { return VersionedConfig({version: s_configCount, config: s_config}); } - /// @notice The part of the LaneUpdate for a fixed destination chain and OffRamp, to avoid verbosity in Report - struct DestLaneUpdate { - uint64 sourceChainSelector; - bytes onrampAddress; // generic, to support arbitrary sources; for EVM2EVM, use abi.encodePacked - uint64 minMsgNr; - uint64 maxMsgNr; - bytes32 root; - } - struct Report { uint256 destChainId; // to guard against chain selector misconfiguration uint64 destChainSelector; address rmnRemoteContractAddress; address offrampAddress; bytes32 rmnHomeContractConfigDigest; - DestLaneUpdate[] destLaneUpdates; - } - - struct Signature { - bytes32 r; - bytes32 s; + Internal.MerkleRoot[] destLaneUpdates; } /// @notice Verifies signatures of RMN nodes, on dest lane updates as provided in the CommitReport @@ -113,7 +101,9 @@ contract RMNRemote is Ownable2Step, ITypeAndVersion { /// @param signatures must be sorted in ascending order by signer address /// @dev Will revert if verification fails. Needs to be called by the OffRamp for which the signatures are produced, /// otherwise verification will fail. - function verify(DestLaneUpdate[] memory destLaneUpdates, Signature[] memory signatures) external view { + function verify(Internal.MerkleRoot[] memory destLaneUpdates, Signature[] memory signatures) external view { + return; // XXX temporary workaround to fix integration tests while we wait to productionize this contract + if (s_configCount == 0) { revert ConfigNotSet(); } @@ -146,6 +136,17 @@ contract RMNRemote is Ownable2Step, ITypeAndVersion { if (numSigners < s_config.minSigners) revert ThresholdNotMet(); } + /// @notice If there is an active global or legacy curse, this function returns true. + function isCursed() external view returns (bool) { + return false; // XXX temporary workaround + } + + /// @notice If there is an active global curse, or an active curse for `subject`, this function returns true. + /// @param subject To check whether a particular chain is cursed, set to bytes16(uint128(chainSelector)). + function isCursed(bytes16 subject) external view returns (bool) { + return false; // XXX temporary workaround + } + /// /// Events /// diff --git a/contracts/src/v0.8/ccip/test/BaseTest.t.sol b/contracts/src/v0.8/ccip/test/BaseTest.t.sol index 2eb44ec485..e8003cab15 100644 --- a/contracts/src/v0.8/ccip/test/BaseTest.t.sol +++ b/contracts/src/v0.8/ccip/test/BaseTest.t.sol @@ -3,6 +3,8 @@ pragma solidity 0.8.24; // Imports to any non-library are not allowed due to the significant cascading // compile time increase they cause when imported into this base test. + +import {IRMNV2} from "../interfaces/IRMNV2.sol"; import {Internal} from "../libraries/Internal.sol"; import {RateLimiter} from "../libraries/RateLimiter.sol"; import {MockRMN} from "./mocks/MockRMN.sol"; @@ -69,6 +71,7 @@ contract BaseTest is Test { address internal constant ADMIN = 0x11118e64e1FB0c487f25dD6D3601FF6aF8d32E4e; MockRMN internal s_mockRMN; + IRMNV2 internal s_mockRMNRemote; function setUp() public virtual { // BaseTest.setUp is often called multiple times from tests' setUp due to inheritance. @@ -84,7 +87,25 @@ contract BaseTest is Test { // Set the block time to a constant known value vm.warp(BLOCK_TIME); + // setup mock RMN & RMNRemote s_mockRMN = new MockRMN(); + s_mockRMNRemote = IRMNV2(makeAddr("MOCK RMN REMOTE")); + vm.etch(address(s_mockRMNRemote), bytes("fake bytecode")); + vm.mockCall(address(s_mockRMNRemote), abi.encodeWithSelector(IRMNV2.verify.selector), bytes("")); + _setMockRMNGlobalCurse(false); + vm.mockCall(address(s_mockRMNRemote), abi.encodeWithSignature("isCursed(bytes16)"), abi.encode(false)); // no curses by defaule + } + + function _setMockRMNGlobalCurse(bool isCursed) internal { + vm.mockCall(address(s_mockRMNRemote), abi.encodeWithSignature("isCursed()"), abi.encode(isCursed)); + } + + function _setMockRMNChainCurse(uint64 chainSelector, bool isCursed) internal { + vm.mockCall( + address(s_mockRMNRemote), + abi.encodeWithSignature("isCursed(bytes16)", bytes16(uint128(chainSelector))), + abi.encode(isCursed) + ); } function _getOutboundRateLimiterConfig() internal pure returns (RateLimiter.Config memory) { diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol index 69afc7104e..8c61ba5d21 100644 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ b/contracts/src/v0.8/ccip/test/NonceManager.t.sol @@ -265,7 +265,7 @@ contract NonceManager_OnRampUpgrade is OnRampSetup { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, OWNER)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); } @@ -292,14 +292,14 @@ contract NonceManager_OnRampUpgrade is OnRampSetup { // new onramp nonce should start from 2, while sequence number start from 1 vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, startNonce + 2, FEE_AMOUNT, OWNER)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, startNonce + 2, FEE_AMOUNT, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); assertEq(startNonce + 2, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); // after another send, nonce should be 3, and sequence number be 2 vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 2, startNonce + 3, FEE_AMOUNT, OWNER)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, 2, startNonce + 3, FEE_AMOUNT, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); assertEq(startNonce + 3, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); @@ -314,7 +314,7 @@ contract NonceManager_OnRampUpgrade is OnRampSetup { address newSender = address(1234567); // new onramp nonce should start from 1 for new sender vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, newSender)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, FEE_AMOUNT, newSender)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, newSender); } } diff --git a/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol b/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol index 0eea71eacc..5161aba883 100644 --- a/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol +++ b/contracts/src/v0.8/ccip/test/attacks/onRamp/MultiOnRampTokenPoolReentrancy.t.sol @@ -107,9 +107,9 @@ contract MultiOnRampTokenPoolReentrancy is OnRampSetup { Internal.EVM2AnyRampMessage memory msgEvent2 = _messageToEvent(message2, 2, 2, expectedFee, address(s_facadeClient)); vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, msgEvent2); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, msgEvent2); vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, msgEvent1); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, msgEvent1); s_facadeClient.send(amount); } diff --git a/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol b/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol index ca7f2114a6..721f5d3463 100644 --- a/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol +++ b/contracts/src/v0.8/ccip/test/capability/CCIPConfig.t.sol @@ -334,17 +334,13 @@ contract CCIPConfig_chainConfig is CCIPConfigSetup { } contract CCIPConfig_validateConfig is CCIPConfigSetup { - // Successes. - - function test__validateConfig_Success() public { + function _getCorrectOCR3Config() internal returns (CCIPConfigTypes.OCR3Config memory) { (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); - // Config is for 4 nodes, so f == 1. - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ + return CCIPConfigTypes.OCR3Config({ pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -352,239 +348,110 @@ contract CCIPConfig_validateConfig is CCIPConfigSetup { offchainConfigVersion: 30, offchainConfig: bytes("offchainConfig") }); - s_ccipCC.validateConfig(config); + } + + // Successes. + + function test__validateConfig_Success() public { + s_ccipCC.validateConfig(_getCorrectOCR3Config()); } // Reverts. function test__validateConfig_ChainSelectorNotSet_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); - - // Config is for 4 nodes, so f == 1. - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 0, // invalid - bootstrapP2PIds: _subset(p2pIds, 0, 1), - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); + CCIPConfigTypes.OCR3Config memory config = _getCorrectOCR3Config(); + config.chainSelector = 0; // invalid vm.expectRevert(CCIPConfig.ChainSelectorNotSet.selector); s_ccipCC.validateConfig(config); } function test__validateConfig_OfframpAddressCannotBeZero_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); - - // Config is for 4 nodes, so f == 1. - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: bytes(""), // invalid - chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); + CCIPConfigTypes.OCR3Config memory config = _getCorrectOCR3Config(); + config.offrampAddress = ""; // invalid vm.expectRevert(CCIPConfig.OfframpAddressCannotBeZero.selector); s_ccipCC.validateConfig(config); } - function test__validateConfig_ChainSelectorNotFound_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); - - // Config is for 4 nodes, so f == 1. - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 2, // not set - bootstrapP2PIds: _subset(p2pIds, 0, 1), - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); - - vm.expectRevert(abi.encodeWithSelector(CCIPConfig.ChainSelectorNotFound.selector, 2)); - s_ccipCC.validateConfig(config); - } + function test__validateConfig_ABIEncodedAddress_OfframpAddressCannotBeZero_Reverts() public { + CCIPConfigTypes.OCR3Config memory config = _getCorrectOCR3Config(); + config.offrampAddress = abi.encode(address(0)); // invalid - function test__validateConfig_TooManySigners_Reverts() public { - // 32 > 31 (max num oracles) - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(32); - - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); - - vm.expectRevert(CCIPConfig.TooManySigners.selector); + vm.expectRevert(CCIPConfig.OfframpAddressCannotBeZero.selector); s_ccipCC.validateConfig(config); } - function test__validateConfig_TooManyTransmitters_Reverts() public { - // 32 > 31 (max num oracles) - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(32); - - // truncate signers but keep transmitters > 31 - assembly { - mstore(signers, 30) - } - - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); + function test__validateConfig_ChainSelectorNotFound_Reverts() public { + CCIPConfigTypes.OCR3Config memory config = _getCorrectOCR3Config(); + config.chainSelector = 2; // not set - vm.expectRevert(CCIPConfig.TooManyTransmitters.selector); + vm.expectRevert(abi.encodeWithSelector(CCIPConfig.ChainSelectorNotFound.selector, 2)); s_ccipCC.validateConfig(config); } function test__validateConfig_NotEnoughTransmitters_Reverts() public { + CCIPConfigTypes.OCR3Config memory config = _getCorrectOCR3Config(); + uint256 numberOfTransmitters = 3; + // 32 > 31 (max num oracles) (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(31); // truncate transmitters to < 3 * fChain + 1 // since fChain is 1 in this case, we need to truncate to 3 transmitters. assembly { - mstore(transmitters, 3) + mstore(transmitters, numberOfTransmitters) } - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); + config.transmitters = transmitters; + config.p2pIds = p2pIds; + config.signers = signers; - vm.expectRevert(abi.encodeWithSelector(CCIPConfig.NotEnoughTransmitters.selector, 3, 4)); + vm.expectRevert(abi.encodeWithSelector(CCIPConfig.NotEnoughTransmitters.selector, numberOfTransmitters, 4)); s_ccipCC.validateConfig(config); } - function test__validateConfig_FMustBePositive_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + function test__validateConfig_TooManySigners_Reverts() public { + CCIPConfigTypes.OCR3Config memory config = _getCorrectOCR3Config(); + config.signers = new bytes[](257); - // Config is for 4 nodes, so f == 1. - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 0, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); + vm.expectRevert(CCIPConfig.TooManySigners.selector); + s_ccipCC.validateConfig(config); + } + + function test__validateConfig_FMustBePositive_Reverts() public { + CCIPConfigTypes.OCR3Config memory config = _getCorrectOCR3Config(); + config.F = 0; // not positive vm.expectRevert(CCIPConfig.FMustBePositive.selector); s_ccipCC.validateConfig(config); } function test__validateConfig_FTooHigh_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); - - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 2, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); + CCIPConfigTypes.OCR3Config memory config = _getCorrectOCR3Config(); + config.F = 2; // too high vm.expectRevert(CCIPConfig.FTooHigh.selector); s_ccipCC.validateConfig(config); } function test__validateConfig_P2PIdsLengthNotMatching_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); - // truncate the p2pIds length - assembly { - mstore(p2pIds, 3) - } + CCIPConfigTypes.OCR3Config memory config = _getCorrectOCR3Config(); - // Config is for 4 nodes, so f == 1. - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); + uint256 expectedNumberOfP2pIds = config.signers.length; + uint256 wrongNumberOfP2pIds = expectedNumberOfP2pIds - 1; + config.p2pIds = new bytes32[](wrongNumberOfP2pIds); // Not enough vm.expectRevert( - abi.encodeWithSelector(CCIPConfig.P2PIdsLengthNotMatching.selector, uint256(3), uint256(4), uint256(4)) + abi.encodeWithSelector( + CCIPConfig.P2PIdsLengthNotMatching.selector, wrongNumberOfP2pIds, expectedNumberOfP2pIds, expectedNumberOfP2pIds + ) ); s_ccipCC.validateConfig(config); } - function test__validateConfig_TooManyBootstrapP2PIds_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); - - // Config is for 4 nodes, so f == 1. - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: _makeBytes32Array(5, 0), // too many bootstrap p2pIds, 5 > 4 - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); - - vm.expectRevert(CCIPConfig.TooManyBootstrapP2PIds.selector); - s_ccipCC.validateConfig(config); - } - function test__validateConfig_NodeNotInRegistry_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); + (bytes32[] memory p2pIds,,) = _addChainConfig(4); bytes32 nonExistentP2PId = keccak256("notInRegistry"); p2pIds[0] = nonExistentP2PId; @@ -603,148 +470,12 @@ contract CCIPConfig_validateConfig is CCIPConfigSetup { }) ) ); - - // Config is for 4 nodes, so f == 1. - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); + CCIPConfigTypes.OCR3Config memory config = _getCorrectOCR3Config(); + config.p2pIds = p2pIds; vm.expectRevert(abi.encodeWithSelector(CCIPConfig.NodeNotInRegistry.selector, nonExistentP2PId)); s_ccipCC.validateConfig(config); } - - function test__validateConfig_P2PIdsNotSorted_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); - // Config is for 4 nodes, so f == 1. - - //swapping two adjacent p2pIds to make it unsorted - (p2pIds[2], p2pIds[3]) = (p2pIds[3], p2pIds[2]); - - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); - - vm.expectRevert(abi.encodeWithSelector(SortedSetValidationUtil.NotASortedSet.selector, p2pIds)); - s_ccipCC.validateConfig(config); - } - - function test__validateConfig_BootstrapP2PIdsNotSorted_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); - // Config is for 4 nodes, so f == 1. - - bytes32[] memory bootstrapP2PIds = _subset(p2pIds, 0, 2); - - //swapping bootstrapP2PIds to make it unsorted - (bootstrapP2PIds[0], bootstrapP2PIds[1]) = (bootstrapP2PIds[1], bootstrapP2PIds[0]); - - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: bootstrapP2PIds, - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); - - vm.expectRevert(abi.encodeWithSelector(SortedSetValidationUtil.NotASortedSet.selector, bootstrapP2PIds)); - s_ccipCC.validateConfig(config); - } - - function test__validateConfig_P2PIdsHasDuplicates_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); - // Config is for 4 nodes, so f == 1. - - //forcing duplicate p2pIds - p2pIds[1] = p2pIds[2]; - - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 2), - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); - - vm.expectRevert(abi.encodeWithSelector(SortedSetValidationUtil.NotASortedSet.selector, p2pIds)); - s_ccipCC.validateConfig(config); - } - - function test__validateConfig_BootstrapP2PIdsHasDuplicates_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); - // Config is for 4 nodes, so f == 1. - - bytes32[] memory bootstrapP2PIds = _subset(p2pIds, 0, 2); - //forcing duplicate bootstrapP2PIds - bootstrapP2PIds[1] = bootstrapP2PIds[0]; - - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: bootstrapP2PIds, - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); - - vm.expectRevert(abi.encodeWithSelector(SortedSetValidationUtil.NotASortedSet.selector, bootstrapP2PIds)); - s_ccipCC.validateConfig(config); - } - - function test__validateConfig_BootstrapP2PIdsNotASubsetOfP2PIds_Reverts() public { - (bytes32[] memory p2pIds, bytes[] memory signers, bytes[] memory transmitters) = _addChainConfig(4); - // Config is for 4 nodes, so f == 1. - - //forcing invalid bootstrapP2PIds where the bootstrapP2PIds is sorted, but one of the element is not in the p2pIdsSet - bytes32[] memory bootstrapP2PIds = _subset(p2pIds, 0, 2); - p2pIds[1] = bytes32(uint256(p2pIds[0]) + 100); - - CCIPConfigTypes.OCR3Config memory config = CCIPConfigTypes.OCR3Config({ - pluginType: Internal.OCRPluginType.Commit, - offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), - chainSelector: 1, - bootstrapP2PIds: bootstrapP2PIds, - p2pIds: p2pIds, - signers: signers, - transmitters: transmitters, - F: 1, - offchainConfigVersion: 30, - offchainConfig: bytes("offchainConfig") - }); - - vm.expectRevert(abi.encodeWithSelector(SortedSetValidationUtil.NotASubset.selector, bootstrapP2PIds, p2pIds)); - s_ccipCC.validateConfig(config); - } } contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { @@ -784,7 +515,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -829,7 +559,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -843,7 +572,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Execution, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -876,7 +604,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -909,7 +636,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -921,7 +647,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -987,7 +712,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -999,7 +723,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1047,7 +770,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1074,7 +796,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1086,7 +807,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1124,7 +844,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1136,7 +855,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1185,7 +903,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1208,7 +925,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Execution, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1233,7 +949,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), p2pIds: _makeBytes32Array(4, 0), signers: _makeBytesArray(4, 10), transmitters: _makeBytesArray(4, 20), @@ -1260,7 +975,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), p2pIds: _makeBytes32Array(4, 0), signers: _makeBytesArray(4, 10), transmitters: _makeBytesArray(4, 20), @@ -1272,7 +986,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), p2pIds: _makeBytes32Array(4, 0), signers: _makeBytesArray(4, 10), transmitters: _makeBytesArray(4, 20), @@ -1316,7 +1029,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), p2pIds: _makeBytes32Array(4, 0), signers: _makeBytesArray(4, 10), transmitters: _makeBytesArray(4, 20), @@ -1328,7 +1040,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), p2pIds: _makeBytes32Array(4, 0), signers: _makeBytesArray(4, 10), transmitters: _makeBytesArray(4, 20), @@ -1366,7 +1077,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), p2pIds: _makeBytes32Array(4, 0), signers: _makeBytesArray(4, 10), transmitters: _makeBytesArray(4, 20), @@ -1378,7 +1088,6 @@ contract CCIPConfig_ConfigStateMachine is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(_makeBytes32Array(4, 0), 0, 1), p2pIds: _makeBytes32Array(4, 0), signers: _makeBytesArray(4, 10), transmitters: _makeBytesArray(4, 20), @@ -1434,7 +1143,6 @@ contract CCIPConfig_updatePluginConfig is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1463,7 +1171,6 @@ contract CCIPConfig_updatePluginConfig is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1480,7 +1187,6 @@ contract CCIPConfig_updatePluginConfig is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1518,7 +1224,6 @@ contract CCIPConfig_updatePluginConfig is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1535,7 +1240,6 @@ contract CCIPConfig_updatePluginConfig is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1616,7 +1320,6 @@ contract CCIPConfig_beforeCapabilityConfigSet is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1648,7 +1351,6 @@ contract CCIPConfig_beforeCapabilityConfigSet is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Execution, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1682,7 +1384,6 @@ contract CCIPConfig_beforeCapabilityConfigSet is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Commit, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, @@ -1694,7 +1395,6 @@ contract CCIPConfig_beforeCapabilityConfigSet is CCIPConfigSetup { pluginType: Internal.OCRPluginType.Execution, offrampAddress: abi.encodePacked(keccak256(abi.encode("offramp"))), chainSelector: 1, - bootstrapP2PIds: _subset(p2pIds, 0, 1), p2pIds: p2pIds, signers: signers, transmitters: transmitters, diff --git a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol index b22e4db9d4..39a80808a3 100644 --- a/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol +++ b/contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; import {NonceManager} from "../../NonceManager.sol"; +import {IRMNV2} from "../../interfaces/IRMNV2.sol"; import {LockReleaseTokenPool} from "../../pools/LockReleaseTokenPool.sol"; import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol"; import "../helpers/MerkleHelper.sol"; @@ -82,7 +83,7 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup { s_sourceRouter2.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), new Router.OffRamp[](0)); // Deploy offramp - _deployOffRamp(s_mockRMN, s_inboundNonceManager); + _deployOffRamp(s_mockRMNRemote, s_inboundNonceManager); // Enable source chains on offramp OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](2); @@ -146,20 +147,27 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup { merkleRoots[0] = MerkleHelper.getMerkleRoot(hashedMessages1); merkleRoots[1] = MerkleHelper.getMerkleRoot(hashedMessages2); - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](2); - roots[0] = OffRamp.MerkleRoot({ + // TODO make these real sigs :) + IRMNV2.Signature[] memory rmnSignatures = new IRMNV2.Signature[](0); + + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](2); + roots[0] = Internal.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: OffRamp.Interval(messages1[0].header.sequenceNumber, messages1[1].header.sequenceNumber), - merkleRoot: merkleRoots[0] + minSeqNr: messages1[0].header.sequenceNumber, + maxSeqNr: messages1[1].header.sequenceNumber, + merkleRoot: merkleRoots[0], + onRampAddress: abi.encode(address(s_onRamp)) }); - roots[1] = OffRamp.MerkleRoot({ + roots[1] = Internal.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR + 1, - interval: OffRamp.Interval(messages2[0].header.sequenceNumber, messages2[0].header.sequenceNumber), - merkleRoot: merkleRoots[1] + minSeqNr: messages2[0].header.sequenceNumber, + maxSeqNr: messages2[0].header.sequenceNumber, + merkleRoot: merkleRoots[1], + onRampAddress: abi.encode(address(s_onRamp)) }); OffRamp.CommitReport memory report = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: rmnSignatures}); vm.resumeGasMetering(); _commit(report, ++s_latestSequenceNumber); @@ -251,7 +259,7 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup { ); vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, msgEvent); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, msgEvent); vm.resumeGasMetering(); router.ccipSend(DEST_CHAIN_SELECTOR, message); diff --git a/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol b/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol index cebff11fcb..be3aa9f4b3 100644 --- a/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol +++ b/contracts/src/v0.8/ccip/test/helpers/CCIPReaderTester.sol @@ -5,7 +5,7 @@ import {Internal} from "../../libraries/Internal.sol"; import {OffRamp} from "../../offRamp/OffRamp.sol"; contract CCIPReaderTester { - event CCIPSendRequested(uint64 indexed destChainSelector, Internal.EVM2AnyRampMessage message); + event CCIPMessageSent(uint64 indexed destChainSelector, Internal.EVM2AnyRampMessage message); mapping(uint64 sourceChainSelector => OffRamp.SourceChainConfig sourceChainConfig) internal s_sourceChainConfigs; mapping(uint64 destChainSelector => uint64 sequenceNumber) internal s_destChainSeqNrs; @@ -48,8 +48,8 @@ contract CCIPReaderTester { s_sourceChainConfigs[sourceChainSelector] = sourceChainConfig; } - function emitCCIPSendRequested(uint64 destChainSelector, Internal.EVM2AnyRampMessage memory message) external { - emit CCIPSendRequested(destChainSelector, message); + function emitCCIPMessageSent(uint64 destChainSelector, Internal.EVM2AnyRampMessage memory message) external { + emit CCIPMessageSent(destChainSelector, message); } event ExecutionStateChanged( diff --git a/contracts/src/v0.8/ccip/test/ocr/MultiOCR3Base.t.sol b/contracts/src/v0.8/ccip/test/ocr/MultiOCR3Base.t.sol index 5b784bf721..8867d1b127 100644 --- a/contracts/src/v0.8/ccip/test/ocr/MultiOCR3Base.t.sol +++ b/contracts/src/v0.8/ccip/test/ocr/MultiOCR3Base.t.sol @@ -878,7 +878,7 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { function test_TooManyTransmitters_Revert() public { address[] memory signers = new address[](0); - address[] memory transmitters = new address[](32); + address[] memory transmitters = new address[](257); MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ @@ -899,7 +899,7 @@ contract MultiOCR3Base_setOCR3Configs is MultiOCR3BaseSetup { } function test_TooManySigners_Revert() public { - address[] memory signers = new address[](32); + address[] memory signers = new address[](257); MultiOCR3Base.OCRConfigArgs[] memory ocrConfigs = new MultiOCR3Base.OCRConfigArgs[](1); ocrConfigs[0] = MultiOCR3Base.OCRConfigArgs({ diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol index ec8ac65008..8db8be3d11 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol @@ -3,7 +3,8 @@ pragma solidity 0.8.24; import {IFeeQuoter} from "../../interfaces/IFeeQuoter.sol"; import {IMessageInterceptor} from "../../interfaces/IMessageInterceptor.sol"; -import {IRMN} from "../../interfaces/IRMN.sol"; +import {IPriceRegistry} from "../../interfaces/IPriceRegistry.sol"; +import {IRMNV2} from "../../interfaces/IRMNV2.sol"; import {IRouter} from "../../interfaces/IRouter.sol"; import {ITokenAdminRegistry} from "../../interfaces/ITokenAdminRegistry.sol"; @@ -34,7 +35,7 @@ contract OffRamp_constructor is OffRampSetup { function test_Constructor_Success() public { OffRamp.StaticConfig memory staticConfig = OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, - rmnProxy: address(s_mockRMN), + rmn: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }); @@ -103,7 +104,7 @@ contract OffRamp_constructor is OffRampSetup { // Static config OffRamp.StaticConfig memory gotStaticConfig = s_offRamp.getStaticConfig(); assertEq(staticConfig.chainSelector, gotStaticConfig.chainSelector); - assertEq(staticConfig.rmnProxy, gotStaticConfig.rmnProxy); + assertEq(address(staticConfig.rmn), address(gotStaticConfig.rmn)); assertEq(staticConfig.tokenAdminRegistry, gotStaticConfig.tokenAdminRegistry); // Dynamic config @@ -155,7 +156,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, - rmnProxy: address(s_mockRMN), + rmn: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), @@ -181,7 +182,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, - rmnProxy: address(s_mockRMN), + rmn: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), @@ -190,7 +191,7 @@ contract OffRamp_constructor is OffRampSetup { ); } - function test_ZeroRMNProxy_Revert() public { + function test_ZeroRMNRemote_Revert() public { uint64[] memory sourceChainSelectors = new uint64[](1); sourceChainSelectors[0] = SOURCE_CHAIN_SELECTOR_1; @@ -201,7 +202,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, - rmnProxy: ZERO_ADDRESS, + rmn: IRMNV2(ZERO_ADDRESS), tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), @@ -221,7 +222,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: 0, - rmnProxy: address(s_mockRMN), + rmn: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), @@ -241,7 +242,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, - rmnProxy: address(s_mockRMN), + rmn: s_mockRMNRemote, tokenAdminRegistry: ZERO_ADDRESS, nonceManager: address(s_inboundNonceManager) }), @@ -261,7 +262,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, - rmnProxy: address(s_mockRMN), + rmn: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: ZERO_ADDRESS }), @@ -604,7 +605,11 @@ contract OffRamp_executeSingleReport is OffRampSetup { vm.resumeGasMetering(); vm.recordLogs(); s_offRamp.executeSingleReport(report, new uint256[](0)); + + Vm.Log[] memory logs = vm.getRecordedLogs(); + assertExecutionStateChangedEventLogs( + logs, SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -614,6 +619,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { ); assertExecutionStateChangedEventLogs( + logs, SOURCE_CHAIN_SELECTOR_1, messages[1].header.sequenceNumber, messages[1].header.messageId, @@ -636,7 +642,11 @@ contract OffRamp_executeSingleReport is OffRampSetup { s_offRamp.executeSingleReport( _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), _getGasLimitsFromMessages(messages) ); + + Vm.Log[] memory logs = vm.getRecordedLogs(); + assertExecutionStateChangedEventLogs( + logs, SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -645,6 +655,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { "" ); assertExecutionStateChangedEventLogs( + logs, SOURCE_CHAIN_SELECTOR_1, messages[1].header.sequenceNumber, messages[1].header.messageId, @@ -679,6 +690,9 @@ contract OffRamp_executeSingleReport is OffRampSetup { s_offRamp.executeSingleReport( _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), _getGasLimitsFromMessages(messages) ); + + Vm.Log[] memory logs = vm.getRecordedLogs(); + // all executions should succeed. for (uint256 i = 0; i < orderings.length; ++i) { assertEq( @@ -687,6 +701,7 @@ contract OffRamp_executeSingleReport is OffRampSetup { ); assertExecutionStateChangedEventLogs( + logs, SOURCE_CHAIN_SELECTOR_1, messages[i].header.sequenceNumber, messages[i].header.messageId, @@ -727,13 +742,37 @@ contract OffRamp_executeSingleReport is OffRampSetup { } function test_WithCurseOnAnotherSourceChain_Success() public { - s_mockRMN.setChainCursed(SOURCE_CHAIN_SELECTOR_2, true); + _setMockRMNChainCurse(SOURCE_CHAIN_SELECTOR_2, true); + s_offRamp.executeSingleReport( + _generateReportFromMessages( + SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) + ), + new uint256[](0) + ); + } + + function test_Unhealthy_Success() public { + _setMockRMNChainCurse(SOURCE_CHAIN_SELECTOR_1, true); + + vm.expectEmit(); + emit OffRamp.SkippedReportExecution(SOURCE_CHAIN_SELECTOR_1); + s_offRamp.executeSingleReport( + _generateReportFromMessages( + SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) + ), + new uint256[](0) + ); + + _setMockRMNChainCurse(SOURCE_CHAIN_SELECTOR_1, false); + vm.recordLogs(); s_offRamp.executeSingleReport( _generateReportFromMessages( SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) ), new uint256[](0) ); + + _assertNoEmit(OffRamp.SkippedReportExecution.selector); } // Reverts @@ -770,42 +809,26 @@ contract OffRamp_executeSingleReport is OffRampSetup { s_offRamp.executeSingleReport(executionReport, new uint256[](0)); } - function test_Unhealthy_Revert() public { - s_mockRMN.setGlobalCursed(true); - vm.expectRevert(abi.encodeWithSelector(OffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_1)); - s_offRamp.executeSingleReport( - _generateReportFromMessages( - SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) - ), - new uint256[](0) - ); - // Uncurse should succeed - s_mockRMN.setGlobalCursed(false); - s_offRamp.executeSingleReport( - _generateReportFromMessages( - SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) - ), - new uint256[](0) - ); - } - function test_UnhealthySingleChainCurse_Revert() public { - s_mockRMN.setChainCursed(SOURCE_CHAIN_SELECTOR_1, true); - vm.expectRevert(abi.encodeWithSelector(OffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_1)); + _setMockRMNChainCurse(SOURCE_CHAIN_SELECTOR_1, true); + vm.expectEmit(); + emit OffRamp.SkippedReportExecution(SOURCE_CHAIN_SELECTOR_1); s_offRamp.executeSingleReport( _generateReportFromMessages( SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) ), new uint256[](0) ); + vm.recordLogs(); // Uncurse should succeed - s_mockRMN.setChainCursed(SOURCE_CHAIN_SELECTOR_1, false); + _setMockRMNChainCurse(SOURCE_CHAIN_SELECTOR_1, false); s_offRamp.executeSingleReport( _generateReportFromMessages( SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) ), new uint256[](0) ); + _assertNoEmit(OffRamp.SkippedReportExecution.selector); } function test_UnexpectedTokenData_Revert() public { @@ -947,15 +970,20 @@ contract OffRamp_executeSingleReport is OffRampSetup { } function _constructCommitReport(bytes32 merkleRoot) internal view returns (OffRamp.CommitReport memory) { - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = OffRamp.MerkleRoot({ + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](1); + roots[0] = Internal.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: OffRamp.Interval(1, 2), - merkleRoot: merkleRoot + minSeqNr: 1, + maxSeqNr: 2, + merkleRoot: merkleRoot, + onRampAddress: abi.encode(ON_RAMP_ADDRESS_1) }); - return - OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); + return OffRamp.CommitReport({ + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots, + rmnSignatures: s_rmnSignatures + }); } } @@ -1149,7 +1177,11 @@ contract OffRamp_batchExecute is OffRampSetup { uint64 nonceBefore = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages1[0].sender); vm.recordLogs(); s_offRamp.batchExecute(reports, new uint256[][](2)); + + Vm.Log[] memory logs = vm.getRecordedLogs(); + assertExecutionStateChangedEventLogs( + logs, messages1[0].header.sourceChainSelector, messages1[0].header.sequenceNumber, messages1[0].header.messageId, @@ -1159,6 +1191,7 @@ contract OffRamp_batchExecute is OffRampSetup { ); assertExecutionStateChangedEventLogs( + logs, messages1[1].header.sourceChainSelector, messages1[1].header.sequenceNumber, messages1[1].header.messageId, @@ -1168,6 +1201,7 @@ contract OffRamp_batchExecute is OffRampSetup { ); assertExecutionStateChangedEventLogs( + logs, messages2[0].header.sourceChainSelector, messages2[0].header.sequenceNumber, messages2[0].header.messageId, @@ -1195,7 +1229,10 @@ contract OffRamp_batchExecute is OffRampSetup { s_offRamp.batchExecute(reports, new uint256[][](2)); + Vm.Log[] memory logs = vm.getRecordedLogs(); + assertExecutionStateChangedEventLogs( + logs, messages1[0].header.sourceChainSelector, messages1[0].header.sequenceNumber, messages1[0].header.messageId, @@ -1205,6 +1242,7 @@ contract OffRamp_batchExecute is OffRampSetup { ); assertExecutionStateChangedEventLogs( + logs, messages1[1].header.sourceChainSelector, messages1[1].header.sequenceNumber, messages1[1].header.messageId, @@ -1214,10 +1252,11 @@ contract OffRamp_batchExecute is OffRampSetup { ); assertExecutionStateChangedEventLogs( + logs, messages2[0].header.sourceChainSelector, messages2[0].header.sequenceNumber, messages2[0].header.messageId, - Internal._hash(messages2[0], ON_RAMP_ADDRESS_1), + Internal._hash(messages2[0], ON_RAMP_ADDRESS_3), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1230,6 +1269,45 @@ contract OffRamp_batchExecute is OffRampSetup { assertGt(nonceChain3, 0); } + function test_MultipleReportsDifferentChainsSkipCursedChain_Success() public { + _setMockRMNChainCurse(SOURCE_CHAIN_SELECTOR_1, true); + + Internal.Any2EVMRampMessage[] memory messages1 = new Internal.Any2EVMRampMessage[](2); + Internal.Any2EVMRampMessage[] memory messages2 = new Internal.Any2EVMRampMessage[](1); + + messages1[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 1); + messages1[1] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, 2); + messages2[0] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_3, ON_RAMP_ADDRESS_3, 1); + + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); + reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages1); + reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messages2); + + vm.recordLogs(); + + vm.expectEmit(); + emit OffRamp.SkippedReportExecution(SOURCE_CHAIN_SELECTOR_1); + + s_offRamp.batchExecute(reports, new uint256[][](2)); + + Vm.Log[] memory logs = vm.getRecordedLogs(); + + for (uint256 i = 0; i < logs.length; ++i) { + if (logs[i].topics[0] == OffRamp.ExecutionStateChanged.selector) { + uint64 logSourceChainSelector = uint64(uint256(logs[i].topics[1])); + uint64 logSequenceNumber = uint64(uint256(logs[i].topics[2])); + bytes32 logMessageId = bytes32(logs[i].topics[3]); + (bytes32 logMessageHash, uint8 logState,,) = abi.decode(logs[i].data, (bytes32, uint8, bytes, uint256)); + assertEq(logMessageId, messages2[0].header.messageId); + assertEq(logSourceChainSelector, messages2[0].header.sourceChainSelector); + assertEq(logSequenceNumber, messages2[0].header.sequenceNumber); + assertEq(logMessageId, messages2[0].header.messageId); + assertEq(logMessageHash, Internal._hash(messages2[0], ON_RAMP_ADDRESS_3)); + assertEq(logState, uint8(Internal.MessageExecutionState.SUCCESS)); + } + } + } + function test_MultipleReportsSkipDuplicate_Success() public { Internal.Any2EVMRampMessage[] memory messages = _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); @@ -1253,29 +1331,34 @@ contract OffRamp_batchExecute is OffRampSetup { ); } - // Reverts - function test_ZeroReports_Revert() public { - vm.expectRevert(OffRamp.EmptyReport.selector); - s_offRamp.batchExecute(new Internal.ExecutionReportSingleChain[](0), new uint256[][](1)); - } - - function test_Unhealthy_Revert() public { - s_mockRMN.setGlobalCursed(true); - vm.expectRevert(abi.encodeWithSelector(OffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_1)); + function test_Unhealthy_Success() public { + _setMockRMNChainCurse(SOURCE_CHAIN_SELECTOR_1, true); + vm.expectEmit(); + emit OffRamp.SkippedReportExecution(SOURCE_CHAIN_SELECTOR_1); s_offRamp.batchExecute( _generateBatchReportFromMessages( SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) ), new uint256[][](1) ); - // Uncurse should succeed - s_mockRMN.setGlobalCursed(false); + + _setMockRMNChainCurse(SOURCE_CHAIN_SELECTOR_1, false); + + vm.recordLogs(); s_offRamp.batchExecute( _generateBatchReportFromMessages( SOURCE_CHAIN_SELECTOR_1, _generateMessagesWithTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1) ), new uint256[][](1) ); + + _assertNoEmit(OffRamp.SkippedReportExecution.selector); + } + + // Reverts + function test_ZeroReports_Revert() public { + vm.expectRevert(OffRamp.EmptyReport.selector); + s_offRamp.batchExecute(new Internal.ExecutionReportSingleChain[](0), new uint256[][](1)); } function test_OutOfBoundsGasLimitsAccess_Revert() public { @@ -1315,6 +1398,8 @@ contract OffRamp_manuallyExecute is OffRampSetup { uint256[][] memory gasLimitOverrides = new uint256[][](1); gasLimitOverrides[0] = new uint256[](messages.length); + + vm.recordLogs(); s_offRamp.manuallyExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), gasLimitOverrides); assertExecutionStateChangedEventLogs( SOURCE_CHAIN_SELECTOR_1, @@ -1419,10 +1504,14 @@ contract OffRamp_manuallyExecute is OffRampSetup { gasLimitOverrides[1][i] += 1; } + vm.recordLogs(); s_offRamp.manuallyExecute(reports, gasLimitOverrides); + Vm.Log[] memory logs = vm.getRecordedLogs(); + for (uint256 j = 0; j < 3; ++j) { assertExecutionStateChangedEventLogs( + logs, SOURCE_CHAIN_SELECTOR_1, messages1[j].header.sequenceNumber, messages1[j].header.messageId, @@ -1434,10 +1523,11 @@ contract OffRamp_manuallyExecute is OffRampSetup { for (uint256 k = 0; k < 2; ++k) { assertExecutionStateChangedEventLogs( - SOURCE_CHAIN_SELECTOR_1, + logs, + SOURCE_CHAIN_SELECTOR_3, messages2[k].header.sequenceNumber, messages2[k].header.messageId, - Internal._hash(messages2[k], ON_RAMP_ADDRESS_1), + Internal._hash(messages2[k], ON_RAMP_ADDRESS_3), Internal.MessageExecutionState.SUCCESS, "" ); @@ -1457,7 +1547,10 @@ contract OffRamp_manuallyExecute is OffRampSetup { vm.recordLogs(); s_offRamp.batchExecute(_generateBatchReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new uint256[][](1)); + Vm.Log[] memory logs = vm.getRecordedLogs(); + assertExecutionStateChangedEventLogs( + logs, SOURCE_CHAIN_SELECTOR_1, messages[0].header.sequenceNumber, messages[0].header.messageId, @@ -1467,6 +1560,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { ); assertExecutionStateChangedEventLogs( + logs, SOURCE_CHAIN_SELECTOR_1, messages[1].header.sequenceNumber, messages[1].header.messageId, @@ -1479,6 +1573,7 @@ contract OffRamp_manuallyExecute is OffRampSetup { ); assertExecutionStateChangedEventLogs( + logs, SOURCE_CHAIN_SELECTOR_1, messages[2].header.sequenceNumber, messages[2].header.messageId, @@ -1738,6 +1833,37 @@ contract OffRamp_manuallyExecute is OffRampSetup { // Since the tx failed we don't release the tokens assertEq(tokenToAbuse.balanceOf(address(receiver)), balancePre + tokenAmount); } + + function test_manuallyExecute_MultipleReportsWithSingleCursedLane_Revert() public { + Internal.Any2EVMRampMessage[] memory messages1 = new Internal.Any2EVMRampMessage[](3); + Internal.Any2EVMRampMessage[] memory messages2 = new Internal.Any2EVMRampMessage[](2); + + for (uint64 i = 0; i < 3; ++i) { + messages1[i] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1, i + 1); + messages1[i].receiver = address(s_reverting_receiver); + messages1[i].header.messageId = Internal._hash(messages1[i], ON_RAMP_ADDRESS_1); + } + + for (uint64 i = 0; i < 2; ++i) { + messages2[i] = _generateAny2EVMMessageNoTokens(SOURCE_CHAIN_SELECTOR_3, ON_RAMP_ADDRESS_3, i + 1); + messages2[i].receiver = address(s_reverting_receiver); + messages2[i].header.messageId = Internal._hash(messages2[i], ON_RAMP_ADDRESS_3); + } + + Internal.ExecutionReportSingleChain[] memory reports = new Internal.ExecutionReportSingleChain[](2); + reports[0] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages1); + reports[1] = _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messages2); + + uint256[][] memory gasLimitOverrides = new uint256[][](2); + gasLimitOverrides[0] = _getGasLimitsFromMessages(messages1); + gasLimitOverrides[1] = _getGasLimitsFromMessages(messages2); + + _setMockRMNChainCurse(SOURCE_CHAIN_SELECTOR_3, true); + + vm.expectRevert(abi.encodeWithSelector(OffRamp.CursedByRMN.selector, SOURCE_CHAIN_SELECTOR_3)); + + s_offRamp.manuallyExecute(reports, gasLimitOverrides); + } } contract OffRamp_execute is OffRampSetup { @@ -1792,7 +1918,11 @@ contract OffRamp_execute is OffRampSetup { vm.recordLogs(); _execute(reports); + + Vm.Log[] memory logs = vm.getRecordedLogs(); + assertExecutionStateChangedEventLogs( + logs, messages1[0].header.sourceChainSelector, messages1[0].header.sequenceNumber, messages1[0].header.messageId, @@ -1802,6 +1932,7 @@ contract OffRamp_execute is OffRampSetup { ); assertExecutionStateChangedEventLogs( + logs, messages1[1].header.sourceChainSelector, messages1[1].header.sequenceNumber, messages1[1].header.messageId, @@ -1811,6 +1942,7 @@ contract OffRamp_execute is OffRampSetup { ); assertExecutionStateChangedEventLogs( + logs, messages2[0].header.sourceChainSelector, messages2[0].header.sequenceNumber, messages2[0].header.messageId, @@ -1839,9 +1971,12 @@ contract OffRamp_execute is OffRampSetup { vm.recordLogs(); _execute(reports); + Vm.Log[] memory logs = vm.getRecordedLogs(); + for (uint64 i = 0; i < reports.length; ++i) { for (uint64 j = 0; j < reports[i].messages.length; ++j) { assertExecutionStateChangedEventLogs( + logs, reports[i].messages[j].header.sourceChainSelector, reports[i].messages[j].header.sequenceNumber, reports[i].messages[j].header.messageId, @@ -1877,7 +2012,11 @@ contract OffRamp_execute is OffRampSetup { vm.recordLogs(); _execute(reports); + + Vm.Log[] memory logs = vm.getRecordedLogs(); + assertExecutionStateChangedEventLogs( + logs, messages1[0].header.sourceChainSelector, messages1[0].header.sequenceNumber, messages1[0].header.messageId, @@ -1890,6 +2029,7 @@ contract OffRamp_execute is OffRampSetup { ); assertExecutionStateChangedEventLogs( + logs, messages1[1].header.sourceChainSelector, messages1[1].header.sequenceNumber, messages1[1].header.messageId, @@ -1899,6 +2039,7 @@ contract OffRamp_execute is OffRampSetup { ); assertExecutionStateChangedEventLogs( + logs, messages2[0].header.sourceChainSelector, messages2[0].header.sequenceNumber, messages2[0].header.messageId, @@ -2974,15 +3115,17 @@ contract OffRamp_commit is OffRampSetup { uint64 max1 = 931; bytes32 root = "Only a single root"; - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = OffRamp.MerkleRoot({ + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](1); + roots[0] = Internal.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: OffRamp.Interval(1, max1), - merkleRoot: root + minSeqNr: 1, + maxSeqNr: max1, + merkleRoot: root, + onRampAddress: abi.encode(ON_RAMP_ADDRESS_1) }); OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures}); vm.expectEmit(); emit OffRamp.CommitReportAccepted(commitReport); @@ -3001,14 +3144,16 @@ contract OffRamp_commit is OffRampSetup { uint64 maxSeq = 12; uint224 tokenStartPrice = IFeeQuoter(s_offRamp.getDynamicConfig().feeQuoter).getTokenPrice(s_sourceFeeToken).value; - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = OffRamp.MerkleRoot({ + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](1); + roots[0] = Internal.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: OffRamp.Interval(1, maxSeq), - merkleRoot: "stale report 1" + minSeqNr: 1, + maxSeqNr: maxSeq, + merkleRoot: "stale report 1", + onRampAddress: abi.encode(ON_RAMP_ADDRESS_1) }); OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures}); vm.expectEmit(); emit OffRamp.CommitReportAccepted(commitReport); @@ -3021,7 +3166,8 @@ contract OffRamp_commit is OffRampSetup { assertEq(maxSeq + 1, s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR).minSeqNr); assertEq(0, s_offRamp.getLatestPriceSequenceNumber()); - commitReport.merkleRoots[0].interval = OffRamp.Interval(maxSeq + 1, maxSeq * 2); + commitReport.merkleRoots[0].minSeqNr = maxSeq + 1; + commitReport.merkleRoots[0].maxSeqNr = maxSeq * 2; commitReport.merkleRoots[0].merkleRoot = "stale report 2"; vm.expectEmit(); @@ -3038,9 +3184,15 @@ contract OffRamp_commit is OffRampSetup { } function test_OnlyTokenPriceUpdates_Success() public { - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](0); - OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); + // force RMN verification to fail + vm.mockCallRevert(address(s_mockRMNRemote), abi.encodeWithSelector(IRMNV2.verify.selector), bytes("")); + + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](0); + OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({ + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots, + rmnSignatures: s_rmnSignatures + }); vm.expectEmit(); emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); @@ -3054,9 +3206,15 @@ contract OffRamp_commit is OffRampSetup { } function test_OnlyGasPriceUpdates_Success() public { - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](0); - OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); + // force RMN verification to fail + vm.mockCallRevert(address(s_mockRMNRemote), abi.encodeWithSelector(IRMNV2.verify.selector), bytes("")); + + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](0); + OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({ + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots, + rmnSignatures: s_rmnSignatures + }); vm.expectEmit(); emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); @@ -3069,9 +3227,12 @@ contract OffRamp_commit is OffRampSetup { } function test_PriceSequenceNumberCleared_Success() public { - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](0); - OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](0); + OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({ + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots, + rmnSignatures: s_rmnSignatures + }); vm.expectEmit(); emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); @@ -3118,10 +3279,11 @@ contract OffRamp_commit is OffRampSetup { uint64 maxSeq = 12; uint224 tokenPrice1 = 4e18; uint224 tokenPrice2 = 5e18; - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](0); + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](0); OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({ priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice1), - merkleRoots: roots + merkleRoots: roots, + rmnSignatures: s_rmnSignatures }); vm.expectEmit(); @@ -3133,11 +3295,13 @@ contract OffRamp_commit is OffRampSetup { _commit(commitReport, s_latestSequenceNumber); assertEq(s_latestSequenceNumber, s_offRamp.getLatestPriceSequenceNumber()); - roots = new OffRamp.MerkleRoot[](1); - roots[0] = OffRamp.MerkleRoot({ + roots = new Internal.MerkleRoot[](1); + roots[0] = Internal.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: OffRamp.Interval(1, maxSeq), - merkleRoot: "stale report" + minSeqNr: 1, + maxSeqNr: maxSeq, + merkleRoot: "stale report", + onRampAddress: abi.encode(ON_RAMP_ADDRESS_1) }); commitReport.priceUpdates = _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice2); commitReport.merkleRoots = roots; @@ -3229,74 +3393,109 @@ contract OffRamp_commit is OffRampSetup { _commit(commitReport, s_latestSequenceNumber); } + function test_FailedRMNVerification_Reverts() public { + // force RMN verification to fail + vm.mockCallRevert(address(s_mockRMNRemote), abi.encodeWithSelector(IRMNV2.verify.selector), bytes("")); + + OffRamp.CommitReport memory commitReport = _constructCommitReport(); + vm.expectRevert(); + _commit(commitReport, s_latestSequenceNumber); + } + function test_Unhealthy_Revert() public { - s_mockRMN.setGlobalCursed(true); - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = OffRamp.MerkleRoot({ + _setMockRMNChainCurse(SOURCE_CHAIN_SELECTOR_1, true); + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](1); + roots[0] = Internal.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: OffRamp.Interval(1, 2), - merkleRoot: "Only a single root" + minSeqNr: 1, + maxSeqNr: 2, + merkleRoot: "Only a single root", + onRampAddress: abi.encode(ON_RAMP_ADDRESS_1) }); OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures}); vm.expectRevert(abi.encodeWithSelector(OffRamp.CursedByRMN.selector, roots[0].sourceChainSelector)); _commit(commitReport, s_latestSequenceNumber); } function test_InvalidRootRevert() public { - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = OffRamp.MerkleRoot({ + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](1); + roots[0] = Internal.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: OffRamp.Interval(1, 4), - merkleRoot: bytes32(0) + minSeqNr: 1, + maxSeqNr: 4, + merkleRoot: bytes32(0), + onRampAddress: abi.encode(ON_RAMP_ADDRESS_1) }); OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures}); vm.expectRevert(OffRamp.InvalidRoot.selector); _commit(commitReport, s_latestSequenceNumber); } function test_InvalidInterval_Revert() public { - OffRamp.Interval memory interval = OffRamp.Interval(2, 2); - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = - OffRamp.MerkleRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, interval: interval, merkleRoot: bytes32(0)}); + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](1); + roots[0] = Internal.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + minSeqNr: 2, + maxSeqNr: 2, + merkleRoot: bytes32(0), + onRampAddress: abi.encode(ON_RAMP_ADDRESS_1) + }); OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures}); - vm.expectRevert(abi.encodeWithSelector(OffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, interval)); + vm.expectRevert( + abi.encodeWithSelector( + OffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, roots[0].minSeqNr, roots[0].maxSeqNr + ) + ); _commit(commitReport, s_latestSequenceNumber); } function test_InvalidIntervalMinLargerThanMax_Revert() public { s_offRamp.getSourceChainConfig(SOURCE_CHAIN_SELECTOR); - OffRamp.Interval memory interval = OffRamp.Interval(1, 0); - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = - OffRamp.MerkleRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, interval: interval, merkleRoot: bytes32(0)}); + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](1); + roots[0] = Internal.MerkleRoot({ + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + minSeqNr: 1, + maxSeqNr: 0, + merkleRoot: bytes32(0), + onRampAddress: abi.encode(ON_RAMP_ADDRESS_1) + }); OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures}); - vm.expectRevert(abi.encodeWithSelector(OffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, interval)); + vm.expectRevert( + abi.encodeWithSelector( + OffRamp.InvalidInterval.selector, roots[0].sourceChainSelector, roots[0].minSeqNr, roots[0].maxSeqNr + ) + ); _commit(commitReport, s_latestSequenceNumber); } function test_ZeroEpochAndRound_Revert() public { - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](0); - OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](0); + OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({ + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots, + rmnSignatures: s_rmnSignatures + }); vm.expectRevert(OffRamp.StaleCommitReport.selector); _commit(commitReport, 0); } function test_OnlyPriceUpdateStaleReport_Revert() public { - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](0); - OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](0); + OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({ + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots, + rmnSignatures: s_rmnSignatures + }); vm.expectEmit(); emit FeeQuoter.UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); @@ -3307,29 +3506,37 @@ contract OffRamp_commit is OffRampSetup { } function test_SourceChainNotEnabled_Revert() public { - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = - OffRamp.MerkleRoot({sourceChainSelector: 0, interval: OffRamp.Interval(1, 2), merkleRoot: "Only a single root"}); + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](1); + roots[0] = Internal.MerkleRoot({ + sourceChainSelector: 0, + minSeqNr: 1, + maxSeqNr: 2, + merkleRoot: "Only a single root", + onRampAddress: abi.encode(ON_RAMP_ADDRESS_1) + }); OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures}); vm.expectRevert(abi.encodeWithSelector(OffRamp.SourceChainNotEnabled.selector, 0)); _commit(commitReport, s_latestSequenceNumber); } function test_RootAlreadyCommitted_Revert() public { - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = OffRamp.MerkleRoot({ + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](1); + roots[0] = Internal.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: OffRamp.Interval(1, 2), - merkleRoot: "Only a single root" + minSeqNr: 1, + maxSeqNr: 2, + merkleRoot: "Only a single root", + onRampAddress: abi.encode(ON_RAMP_ADDRESS_1) }); OffRamp.CommitReport memory commitReport = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); + OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures}); _commit(commitReport, s_latestSequenceNumber); - commitReport.merkleRoots[0].interval = OffRamp.Interval(3, 3); + commitReport.merkleRoots[0].minSeqNr = 3; + commitReport.merkleRoots[0].maxSeqNr = 3; vm.expectRevert( abi.encodeWithSelector(OffRamp.RootAlreadyCommitted.selector, roots[0].sourceChainSelector, roots[0].merkleRoot) @@ -3338,164 +3545,19 @@ contract OffRamp_commit is OffRampSetup { } function _constructCommitReport() internal view returns (OffRamp.CommitReport memory) { - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = OffRamp.MerkleRoot({ + Internal.MerkleRoot[] memory roots = new Internal.MerkleRoot[](1); + roots[0] = Internal.MerkleRoot({ sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - interval: OffRamp.Interval(1, s_maxInterval), - merkleRoot: "test #2" + minSeqNr: 1, + maxSeqNr: s_maxInterval, + merkleRoot: "test #2", + onRampAddress: abi.encode(ON_RAMP_ADDRESS_1) }); - return - OffRamp.CommitReport({priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), merkleRoots: roots}); - } -} - -contract OffRamp_resetUnblessedRoots is OffRampSetup { - function setUp() public virtual override { - super.setUp(); - _setupRealRMN(); - _deployOffRamp(s_realRMN, s_inboundNonceManager); - _setupMultipleOffRamps(); - } - - function test_ResetUnblessedRoots_Success() public { - OffRamp.UnblessedRoot[] memory rootsToReset = new OffRamp.UnblessedRoot[](3); - rootsToReset[0] = OffRamp.UnblessedRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR, merkleRoot: "1"}); - rootsToReset[1] = OffRamp.UnblessedRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR, merkleRoot: "2"}); - rootsToReset[2] = OffRamp.UnblessedRoot({sourceChainSelector: SOURCE_CHAIN_SELECTOR, merkleRoot: "3"}); - - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](3); - roots[0] = OffRamp.MerkleRoot({ - sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: OffRamp.Interval(1, 2), - merkleRoot: rootsToReset[0].merkleRoot - }); - roots[1] = OffRamp.MerkleRoot({ - sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: OffRamp.Interval(3, 4), - merkleRoot: rootsToReset[1].merkleRoot - }); - roots[2] = OffRamp.MerkleRoot({ - sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: OffRamp.Interval(5, 5), - merkleRoot: rootsToReset[2].merkleRoot + return OffRamp.CommitReport({ + priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + merkleRoots: roots, + rmnSignatures: s_rmnSignatures }); - - OffRamp.CommitReport memory report = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); - - _commit(report, ++s_latestSequenceNumber); - - IRMN.TaggedRoot[] memory blessedTaggedRoots = new IRMN.TaggedRoot[](1); - blessedTaggedRoots[0] = IRMN.TaggedRoot({commitStore: address(s_offRamp), root: rootsToReset[1].merkleRoot}); - - vm.startPrank(BLESS_VOTE_ADDR); - s_realRMN.voteToBless(blessedTaggedRoots); - - vm.expectEmit(false, false, false, true); - emit OffRamp.RootRemoved(rootsToReset[0].merkleRoot); - - vm.expectEmit(false, false, false, true); - emit OffRamp.RootRemoved(rootsToReset[2].merkleRoot); - - vm.startPrank(OWNER); - s_offRamp.resetUnblessedRoots(rootsToReset); - - assertEq(0, s_offRamp.getMerkleRoot(SOURCE_CHAIN_SELECTOR, rootsToReset[0].merkleRoot)); - assertEq(BLOCK_TIME, s_offRamp.getMerkleRoot(SOURCE_CHAIN_SELECTOR, rootsToReset[1].merkleRoot)); - assertEq(0, s_offRamp.getMerkleRoot(SOURCE_CHAIN_SELECTOR, rootsToReset[2].merkleRoot)); - } - - // Reverts - - function test_OnlyOwner_Revert() public { - vm.stopPrank(); - vm.expectRevert("Only callable by owner"); - OffRamp.UnblessedRoot[] memory rootsToReset = new OffRamp.UnblessedRoot[](0); - s_offRamp.resetUnblessedRoots(rootsToReset); - } -} - -contract OffRamp_verify is OffRampSetup { - function setUp() public virtual override { - super.setUp(); - _setupRealRMN(); - _deployOffRamp(s_realRMN, s_inboundNonceManager); - _setupMultipleOffRamps(); - } - - function test_NotBlessed_Success() public { - bytes32[] memory leaves = new bytes32[](1); - leaves[0] = "root"; - - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = OffRamp.MerkleRoot({ - sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: OffRamp.Interval(1, 2), - merkleRoot: leaves[0] - }); - OffRamp.CommitReport memory report = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); - _commit(report, ++s_latestSequenceNumber); - bytes32[] memory proofs = new bytes32[](0); - // We have not blessed this root, should return 0. - uint256 timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR, leaves, proofs, 0); - assertEq(uint256(0), timestamp); - } - - function test_Blessed_Success() public { - bytes32[] memory leaves = new bytes32[](1); - leaves[0] = "root"; - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = OffRamp.MerkleRoot({ - sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: OffRamp.Interval(1, 2), - merkleRoot: leaves[0] - }); - OffRamp.CommitReport memory report = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); - _commit(report, ++s_latestSequenceNumber); - // Bless that root. - IRMN.TaggedRoot[] memory taggedRoots = new IRMN.TaggedRoot[](1); - taggedRoots[0] = IRMN.TaggedRoot({commitStore: address(s_offRamp), root: leaves[0]}); - vm.startPrank(BLESS_VOTE_ADDR); - s_realRMN.voteToBless(taggedRoots); - bytes32[] memory proofs = new bytes32[](0); - uint256 timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR, leaves, proofs, 0); - assertEq(BLOCK_TIME, timestamp); - } - - function test_NotBlessedWrongChainSelector_Success() public { - bytes32[] memory leaves = new bytes32[](1); - leaves[0] = "root"; - OffRamp.MerkleRoot[] memory roots = new OffRamp.MerkleRoot[](1); - roots[0] = OffRamp.MerkleRoot({ - sourceChainSelector: SOURCE_CHAIN_SELECTOR, - interval: OffRamp.Interval(1, 2), - merkleRoot: leaves[0] - }); - - OffRamp.CommitReport memory report = - OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots}); - _commit(report, ++s_latestSequenceNumber); - - // Bless that root. - IRMN.TaggedRoot[] memory taggedRoots = new IRMN.TaggedRoot[](1); - taggedRoots[0] = IRMN.TaggedRoot({commitStore: address(s_offRamp), root: leaves[0]}); - vm.startPrank(BLESS_VOTE_ADDR); - s_realRMN.voteToBless(taggedRoots); - - bytes32[] memory proofs = new bytes32[](0); - uint256 timestamp = s_offRamp.verify(SOURCE_CHAIN_SELECTOR + 1, leaves, proofs, 0); - assertEq(uint256(0), timestamp); - } - - // Reverts - - function test_TooManyLeaves_Revert() public { - bytes32[] memory leaves = new bytes32[](258); - bytes32[] memory proofs = new bytes32[](0); - vm.expectRevert(MerkleMultiProof.InvalidProof.selector); - s_offRamp.verify(SOURCE_CHAIN_SELECTOR, leaves, proofs, 0); } } diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol index ae9fc044ac..2d65ee735c 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRampSetup.t.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.24; import {IAny2EVMMessageReceiver} from "../../interfaces/IAny2EVMMessageReceiver.sol"; import {ICommitStore} from "../../interfaces/ICommitStore.sol"; import {IRMN} from "../../interfaces/IRMN.sol"; +import {IRMNV2} from "../../interfaces/IRMNV2.sol"; import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol"; import {NonceManager} from "../../NonceManager.sol"; @@ -29,8 +30,6 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { uint64 internal constant SOURCE_CHAIN_SELECTOR_1 = SOURCE_CHAIN_SELECTOR; uint64 internal constant SOURCE_CHAIN_SELECTOR_2 = 6433500567565415381; uint64 internal constant SOURCE_CHAIN_SELECTOR_3 = 4051577828743386545; - bytes32 internal constant EXECUTION_STATE_CHANGE_TOPIC_HASH = - keccak256("ExecutionStateChanged(uint64,uint64,bytes32,bytes32,uint8,bytes,uint256)"); bytes internal constant ON_RAMP_ADDRESS_1 = abi.encode(ON_RAMP_ADDRESS); bytes internal constant ON_RAMP_ADDRESS_2 = abi.encode(0xaA3f843Cf8E33B1F02dd28303b6bD87B1aBF8AE4); @@ -57,6 +56,8 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { uint64 internal s_latestSequenceNumber; + IRMNV2.Signature[] internal s_rmnSignatures; + function setUp() public virtual override(FeeQuoterSetup, MultiOCR3BaseSetup) { FeeQuoterSetup.setUp(); MultiOCR3BaseSetup.setUp(); @@ -69,16 +70,16 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { s_maybeRevertingPool = MaybeRevertingBurnMintTokenPool(s_destPoolByToken[s_destTokens[1]]); s_inboundNonceManager = new NonceManager(new address[](0)); - _deployOffRamp(s_mockRMN, s_inboundNonceManager); + _deployOffRamp(s_mockRMNRemote, s_inboundNonceManager); } - function _deployOffRamp(IRMN rmnProxy, NonceManager nonceManager) internal { + function _deployOffRamp(IRMNV2 rmn, NonceManager nonceManager) internal { OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](0); s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, - rmnProxy: address(rmnProxy), + rmn: rmn, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(nonceManager) }), @@ -427,7 +428,7 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, - rmnProxy: address(s_mockRMN), + rmn: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) }), @@ -484,7 +485,35 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { ) public { Vm.Log[] memory logs = vm.getRecordedLogs(); for (uint256 i = 0; i < logs.length; ++i) { - if (logs[i].topics[0] == EXECUTION_STATE_CHANGE_TOPIC_HASH) { + if (logs[i].topics[0] == OffRamp.ExecutionStateChanged.selector) { + uint64 logSourceChainSelector = uint64(uint256(logs[i].topics[1])); + uint64 logSequenceNumber = uint64(uint256(logs[i].topics[2])); + bytes32 logMessageId = bytes32(logs[i].topics[3]); + (bytes32 logMessageHash, uint8 logState, bytes memory logReturnData,) = + abi.decode(logs[i].data, (bytes32, uint8, bytes, uint256)); + if (logMessageId == messageId) { + assertEq(logSourceChainSelector, sourceChainSelector); + assertEq(logSequenceNumber, sequenceNumber); + assertEq(logMessageId, messageId); + assertEq(logMessageHash, messageHash); + assertEq(logState, uint8(state)); + assertEq(logReturnData, returnData); + } + } + } + } + + function assertExecutionStateChangedEventLogs( + Vm.Log[] memory logs, + uint64 sourceChainSelector, + uint64 sequenceNumber, + bytes32 messageId, + bytes32 messageHash, + Internal.MessageExecutionState state, + bytes memory returnData + ) public pure { + for (uint256 i = 0; i < logs.length; ++i) { + if (logs[i].topics[0] == OffRamp.ExecutionStateChanged.selector) { uint64 logSourceChainSelector = uint64(uint256(logs[i].topics[1])); uint64 logSequenceNumber = uint64(uint256(logs[i].topics[2])); bytes32 logMessageId = bytes32(logs[i].topics[3]); @@ -501,4 +530,12 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { } } } + + function _assertNoEmit(bytes32 eventSelector) internal { + Vm.Log[] memory logs = vm.getRecordedLogs(); + + for (uint256 i = 0; i < logs.length; i++) { + assertTrue(logs[i].topics[0] != eventSelector); + } + } } diff --git a/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol index a6f4205ee1..d989c15651 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.24; import {IMessageInterceptor} from "../../interfaces/IMessageInterceptor.sol"; +import {IRMNV2} from "../../interfaces/IRMNV2.sol"; import {IRouter} from "../../interfaces/IRouter.sol"; import {BurnMintERC677} from "../../../shared/token/ERC677/BurnMintERC677.sol"; @@ -21,7 +22,7 @@ contract OnRamp_constructor is OnRampSetup { function test_Constructor_Success() public { OnRamp.StaticConfig memory staticConfig = OnRamp.StaticConfig({ chainSelector: SOURCE_CHAIN_SELECTOR, - rmnProxy: address(s_mockRMN), + rmn: s_mockRMNRemote, nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }); @@ -52,7 +53,7 @@ contract OnRamp_constructor is OnRampSetup { new OnRampHelper( OnRamp.StaticConfig({ chainSelector: 0, - rmnProxy: address(s_mockRMN), + rmn: s_mockRMNRemote, nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }), @@ -66,7 +67,7 @@ contract OnRamp_constructor is OnRampSetup { s_onRamp = new OnRampHelper( OnRamp.StaticConfig({ chainSelector: SOURCE_CHAIN_SELECTOR, - rmnProxy: address(0), + rmn: IRMNV2(address(0)), nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(s_tokenAdminRegistry) }), @@ -80,7 +81,7 @@ contract OnRamp_constructor is OnRampSetup { new OnRampHelper( OnRamp.StaticConfig({ chainSelector: SOURCE_CHAIN_SELECTOR, - rmnProxy: address(s_mockRMN), + rmn: s_mockRMNRemote, nonceManager: address(0), tokenAdminRegistry: address(s_tokenAdminRegistry) }), @@ -94,7 +95,7 @@ contract OnRamp_constructor is OnRampSetup { new OnRampHelper( OnRamp.StaticConfig({ chainSelector: SOURCE_CHAIN_SELECTOR, - rmnProxy: address(s_mockRMN), + rmn: s_mockRMNRemote, nonceManager: address(s_outboundNonceManager), tokenAdminRegistry: address(0) }), @@ -144,7 +145,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -180,7 +181,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { vm.expectEmit(); // We expect the message to be emitted with strict = false. - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -193,7 +194,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { vm.expectEmit(); // We expect the message to be emitted with strict = false. - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -205,7 +206,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -219,7 +220,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -233,7 +234,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { IERC20(s_sourceFeeToken).transferFrom(OWNER, address(s_onRamp), feeAmount); vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -246,7 +247,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { uint64 sequenceNumberBefore = s_onRamp.getExpectedNextSequenceNumber(DEST_CHAIN_SELECTOR) - 1; vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, i, i, 0, OWNER)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, i, i, 0, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); @@ -268,7 +269,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { uint64 sequenceNumberBefore = s_onRamp.getExpectedNextSequenceNumber(DEST_CHAIN_SELECTOR) - 1; vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, i, i, 0, OWNER)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, i, i, 0, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); @@ -353,7 +354,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { vm.expectEmit(); emit OnRamp.FeePaid(s_sourceFeeToken, feeTokenAmount); vm.expectEmit(false, false, false, true); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, expectedEvent); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, expectedEvent); // Assert the message Id is correct assertEq( @@ -375,7 +376,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { s_outboundMessageValidator.setMessageIdValidationState(keccak256(abi.encode(message)), false); vm.expectEmit(); - emit OnRamp.CCIPSendRequested(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, _messageToEvent(message, 1, 1, feeAmount, OWNER)); s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } @@ -497,7 +498,7 @@ contract OnRamp_forwardFromRouter is OnRampSetup { vm.startPrank(OWNER); MaybeRevertingBurnMintTokenPool newPool = new MaybeRevertingBurnMintTokenPool( - BurnMintERC677(sourceETH), new address[](0), address(s_mockRMN), address(s_sourceRouter) + BurnMintERC677(sourceETH), new address[](0), address(s_mockRMNRemote), address(s_sourceRouter) ); BurnMintERC677(sourceETH).grantMintAndBurnRoles(address(newPool)); deal(address(sourceETH), address(newPool), type(uint256).max); @@ -632,7 +633,7 @@ contract OnRamp_getFee is OnRampSetup { // Reverts function test_Unhealthy_Revert() public { - s_mockRMN.setGlobalCursed(true); + _setMockRMNChainCurse(DEST_CHAIN_SELECTOR, true); vm.expectRevert(abi.encodeWithSelector(OnRamp.CursedByRMN.selector, DEST_CHAIN_SELECTOR)); s_onRamp.getFee(DEST_CHAIN_SELECTOR, _generateEmptyMessage()); } diff --git a/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol index f43bce6a99..4c43c16f59 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol @@ -117,7 +117,7 @@ contract OnRampSetup is FeeQuoterFeeSetup { OnRampHelper onRamp = new OnRampHelper( OnRamp.StaticConfig({ chainSelector: sourceChainSelector, - rmnProxy: address(s_mockRMN), + rmn: s_mockRMNRemote, nonceManager: nonceManager, tokenAdminRegistry: tokenAdminRegistry }), @@ -161,7 +161,7 @@ contract OnRampSetup is FeeQuoterFeeSetup { function _assertStaticConfigsEqual(OnRamp.StaticConfig memory a, OnRamp.StaticConfig memory b) internal pure { assertEq(a.chainSelector, b.chainSelector); - assertEq(a.rmnProxy, b.rmnProxy); + assertEq(address(a.rmn), address(b.rmn)); assertEq(a.tokenAdminRegistry, b.tokenAdminRegistry); } diff --git a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go index 6d75fd22ff..8f4cd023ce 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go @@ -86,14 +86,12 @@ func TestCCIPReader_CommitReportsGTETimestamp(t *testing.T) { }, }, }, - MerkleRoots: []ccip_reader_tester.OffRampMerkleRoot{ + MerkleRoots: []ccip_reader_tester.InternalMerkleRoot{ { SourceChainSelector: uint64(chainS1), - Interval: ccip_reader_tester.OffRampInterval{ - Min: 10, - Max: 20, - }, - MerkleRoot: [32]byte{i + 1}, + MinSeqNr: 10, + MaxSeqNr: 20, + MerkleRoot: [32]byte{i + 1}, }, }, }) @@ -205,12 +203,12 @@ func TestCCIPReader_MsgsBetweenSeqNums(t *testing.T) { Contracts: map[string]evmtypes.ChainContractReader{ consts.ContractNameOnRamp: { ContractPollingFilter: evmtypes.ContractPollingFilter{ - GenericEventNames: []string{consts.EventNameCCIPSendRequested}, + GenericEventNames: []string{consts.EventNameCCIPMessageSent}, }, ContractABI: ccip_reader_tester.CCIPReaderTesterABI, Configs: map[string]*evmtypes.ChainReaderDefinition{ - consts.EventNameCCIPSendRequested: { - ChainSpecificName: consts.EventNameCCIPSendRequested, + consts.EventNameCCIPMessageSent: { + ChainSpecificName: "CCIPMessageSent", ReadType: evmtypes.Event, }, }, @@ -220,7 +218,7 @@ func TestCCIPReader_MsgsBetweenSeqNums(t *testing.T) { s := testSetup(ctx, t, chainS1, chainD, nil, cfg) - _, err := s.contract.EmitCCIPSendRequested(s.auth, uint64(chainD), ccip_reader_tester.InternalEVM2AnyRampMessage{ + _, err := s.contract.EmitCCIPMessageSent(s.auth, uint64(chainD), ccip_reader_tester.InternalEVM2AnyRampMessage{ Header: ccip_reader_tester.InternalRampMessageHeader{ MessageId: [32]byte{1, 0, 0, 0, 0}, SourceChainSelector: uint64(chainS1), @@ -237,7 +235,7 @@ func TestCCIPReader_MsgsBetweenSeqNums(t *testing.T) { }) assert.NoError(t, err) - _, err = s.contract.EmitCCIPSendRequested(s.auth, uint64(chainD), ccip_reader_tester.InternalEVM2AnyRampMessage{ + _, err = s.contract.EmitCCIPMessageSent(s.auth, uint64(chainD), ccip_reader_tester.InternalEVM2AnyRampMessage{ Header: ccip_reader_tester.InternalRampMessageHeader{ MessageId: [32]byte{1, 0, 0, 0, 1}, SourceChainSelector: uint64(chainS1), diff --git a/core/capabilities/ccip/ccip_integration_tests/helpers.go b/core/capabilities/ccip/ccip_integration_tests/helpers.go index 829c32f7f1..15c603c647 100644 --- a/core/capabilities/ccip/ccip_integration_tests/helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/helpers.go @@ -47,7 +47,7 @@ import ( var ( homeChainID = chainsel.GETH_TESTNET.EvmChainID - ccipSendRequestedTopic = onramp.OnRampCCIPSendRequested{}.Topic() + ccipMessageSentTopic = onramp.OnRampCCIPMessageSent{}.Topic() commitReportAcceptedTopic = offramp.OffRampCommitReportAccepted{}.Topic() executionStateChangedTopic = offramp.OffRampExecutionStateChanged{}.Topic() ) @@ -195,7 +195,7 @@ func createUniverses( backend, onramp.OnRampStaticConfig{ ChainSelector: getSelector(chainID), - RmnProxy: rmnProxy.Address(), + Rmn: rmnProxy.Address(), NonceManager: nonceManager.Address(), TokenAdminRegistry: tokenAdminRegistry.Address(), }, @@ -221,7 +221,7 @@ func createUniverses( backend, offramp.OffRampStaticConfig{ ChainSelector: getSelector(chainID), - RmnProxy: rmnProxy.Address(), + Rmn: rmnProxy.Address(), TokenAdminRegistry: tokenAdminRegistry.Address(), NonceManager: nonceManager.Address(), }, @@ -292,7 +292,7 @@ func createUniverses( // print out topic hashes of relevant events for debugging purposes t.Logf("Topic hash of CommitReportAccepted: %s", commitReportAcceptedTopic.Hex()) t.Logf("Topic hash of ExecutionStateChanged: %s", executionStateChangedTopic.Hex()) - t.Logf("Topic hash of CCIPSendRequested: %s", ccipSendRequestedTopic.Hex()) + t.Logf("Topic hash of CCIPMessageSent: %s", ccipMessageSentTopic.Hex()) return homeChainUniverse, universes } @@ -532,7 +532,6 @@ func (h *homeChain) AddDON( F: configF, OffchainConfigVersion: offchainConfigVersion, OfframpAddress: uni.offramp.Address().Bytes(), - BootstrapP2PIds: [][32]byte{bootstrapP2PID}, P2pIds: p2pIDs, Signers: signersBytes, Transmitters: transmittersBytes, diff --git a/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go b/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go index 40323574b1..e6eb3aa6e0 100644 --- a/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go @@ -271,7 +271,6 @@ func (t *TestUniverse) AddDONToRegistry( F: f, OffchainConfigVersion: 30, OfframpAddress: testutils.NewAddress().Bytes(), - BootstrapP2PIds: [][32]byte{bootstrapP2PID}, P2pIds: p2pIDs, Signers: signers, Transmitters: transmitters, diff --git a/core/capabilities/ccip/ccip_integration_tests/ping_pong_test.go b/core/capabilities/ccip/ccip_integration_tests/ping_pong_test.go index 8a65ff5167..57d2e09f22 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ping_pong_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ping_pong_test.go @@ -18,7 +18,7 @@ import ( * A ---deploy+start---> (pingPongB, pingPongC) * B ---deploy+start---> (pingPongA, pingPongC) * C ---deploy+start---> (pingPongA, pingPongB) -* and then checks that each ping pong contract emitted `CCIPSendRequested` event from the expected source to destination. +* and then checks that each ping pong contract emitted `CCIPMessageSent` event from the expected source to destination. * Test fails if any wiring between contracts is not correct. */ func TestPingPong(t *testing.T) { @@ -31,7 +31,7 @@ func TestPingPong(t *testing.T) { require.NoError(t, err) universe.backend.Commit() - logIter, err := universe.onramp.FilterCCIPSendRequested(&bind.FilterOpts{Start: 0}, nil) + logIter, err := universe.onramp.FilterCCIPMessageSent(&bind.FilterOpts{Start: 0}, nil) require.NoError(t, err) // Iterate until latest event for logIter.Next() { diff --git a/core/capabilities/ccip/ccipevm/commitcodec.go b/core/capabilities/ccip/ccipevm/commitcodec.go index 2346c9f141..ca515ff211 100644 --- a/core/capabilities/ccip/ccipevm/commitcodec.go +++ b/core/capabilities/ccip/ccipevm/commitcodec.go @@ -32,15 +32,13 @@ func NewCommitPluginCodecV1() *CommitPluginCodecV1 { } func (c *CommitPluginCodecV1) Encode(ctx context.Context, report cciptypes.CommitPluginReport) ([]byte, error) { - merkleRoots := make([]offramp.OffRampMerkleRoot, 0, len(report.MerkleRoots)) + merkleRoots := make([]offramp.InternalMerkleRoot, 0, len(report.MerkleRoots)) for _, root := range report.MerkleRoots { - merkleRoots = append(merkleRoots, offramp.OffRampMerkleRoot{ + merkleRoots = append(merkleRoots, offramp.InternalMerkleRoot{ SourceChainSelector: uint64(root.ChainSel), - Interval: offramp.OffRampInterval{ - Min: uint64(root.SeqNumsRange.Start()), - Max: uint64(root.SeqNumsRange.End()), - }, - MerkleRoot: root.MerkleRoot, + MinSeqNr: uint64(root.SeqNumsRange.Start()), + MaxSeqNr: uint64(root.SeqNumsRange.End()), + MerkleRoot: root.MerkleRoot, }) } @@ -102,8 +100,8 @@ func (c *CommitPluginCodecV1) Decode(ctx context.Context, bytes []byte) (cciptyp merkleRoots = append(merkleRoots, cciptypes.MerkleRootChain{ ChainSel: cciptypes.ChainSelector(root.SourceChainSelector), SeqNumsRange: cciptypes.NewSeqNumRange( - cciptypes.SeqNum(root.Interval.Min), - cciptypes.SeqNum(root.Interval.Max), + cciptypes.SeqNum(root.MinSeqNr), + cciptypes.SeqNum(root.MaxSeqNr), ), MerkleRoot: root.MerkleRoot, }) diff --git a/core/capabilities/ccip/ccipevm/commitcodec_test.go b/core/capabilities/ccip/ccipevm/commitcodec_test.go index 737f7be1d6..22dd0bfd12 100644 --- a/core/capabilities/ccip/ccipevm/commitcodec_test.go +++ b/core/capabilities/ccip/ccipevm/commitcodec_test.go @@ -5,12 +5,15 @@ import ( "math/rand" "testing" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" ) @@ -133,3 +136,24 @@ func BenchmarkCommitPluginCodecV1_Decode(b *testing.B) { require.NoError(b, err) } } + +func TestDecodeCommitReport(t *testing.T) { + report := hexutil.MustDecode("0x2d04ab76000a61cae2575edd7bc451a34fdad33f7d577226b7ab6015122590d6abc4e450000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000380010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000c9f9284461c852b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001dc7b58803f528bba0ff4fed53b1309d3ea5319201eb7b74e1d7952985966a09000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002023d96f990f8e5a2cfb69307999265fc1af26b85b5b979c5dffdb45fe41ca29d326001361e4a8bf3b3de5719b2441501ca1d82521ad87b98c805c65f77afa272000000000000000000000000000000000000000000000000000000000000000224b0ec1abc40a8b57b7caa1f952b03b99ff2997236cd91a667463faf172f781023e5abc6a3a5c2fc9ae829869c73387f438bd81697696313efaad61f39a480d8") + tabi, err := offramp.OffRampMetaData.GetAbi() + require.NoError(t, err) + unpacked, err := tabi.Methods["commit"].Inputs.Unpack(report[4:]) + require.NoError(t, err) + require.Len(t, unpacked, 5) + + reportBytes := *abi.ConvertType(unpacked[1], &[]byte{}).(*[]byte) + t.Log("reportBytes: ", hexutil.Encode(reportBytes)) + + unpackedReportRaw, err := tabi.Events["CommitReportAccepted"].Inputs.Unpack(reportBytes) + require.NoError(t, err) + + unpackedReport := *abi.ConvertType(unpackedReportRaw[0], &offramp.OffRampCommitReport{}).(*offramp.OffRampCommitReport) + + t.Log("roots: ", unpackedReport.MerkleRoots) + t.Log("price updates: ", unpackedReport.PriceUpdates) + t.Log("rmn sigs: ", unpackedReport.RmnSignatures) +} diff --git a/core/capabilities/ccip/configs/evm/contract_reader.go b/core/capabilities/ccip/configs/evm/contract_reader.go index cb19ede0e8..f85395e2c2 100644 --- a/core/capabilities/ccip/configs/evm/contract_reader.go +++ b/core/capabilities/ccip/configs/evm/contract_reader.go @@ -70,10 +70,6 @@ var DestReaderConfig = evmrelaytypes.ChainReaderConfig{ ChainSpecificName: mustGetMethodName("getMerkleRoot", offrampABI), ReadType: evmrelaytypes.Method, }, - consts.MethodNameIsBlessed: { - ChainSpecificName: mustGetMethodName("isBlessed", offrampABI), - ReadType: evmrelaytypes.Method, - }, consts.MethodNameGetLatestPriceSequenceNumber: { ChainSpecificName: mustGetMethodName("getLatestPriceSequenceNumber", offrampABI), ReadType: evmrelaytypes.Method, @@ -123,7 +119,7 @@ var SourceReaderConfig = evmrelaytypes.ChainReaderConfig{ ContractABI: onramp.OnRampABI, ContractPollingFilter: evmrelaytypes.ContractPollingFilter{ GenericEventNames: []string{ - mustGetEventName(consts.EventNameCCIPSendRequested, onrampABI), + consts.EventNameCCIPMessageSent, }, }, Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ @@ -141,8 +137,8 @@ var SourceReaderConfig = evmrelaytypes.ChainReaderConfig{ ChainSpecificName: mustGetMethodName("getDynamicConfig", onrampABI), ReadType: evmrelaytypes.Method, }, - consts.EventNameCCIPSendRequested: { - ChainSpecificName: mustGetEventName(consts.EventNameCCIPSendRequested, onrampABI), + consts.EventNameCCIPMessageSent: { + ChainSpecificName: mustGetEventName("CCIPMessageSent", onrampABI), ReadType: evmrelaytypes.Event, EventDefinitions: &evmrelaytypes.EventDefinitions{ GenericDataWordNames: map[string]uint8{ diff --git a/core/gethwrappers/ccip/deployment_test/deployment_test.go b/core/gethwrappers/ccip/deployment_test/deployment_test.go new file mode 100644 index 0000000000..c89ca23917 --- /dev/null +++ b/core/gethwrappers/ccip/deployment_test/deployment_test.go @@ -0,0 +1,97 @@ +package deploymenttest + +import ( + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" +) + +// This tests ensures that all of the compiled contracts can be +// deployed to an actual blockchain (i.e no "max code size exceeded" errors). +// It does not attempt to correctly set up the contracts, so bogus inputs are used. +func TestDeployAllV1_6(t *testing.T) { + owner := testutils.MustNewSimTransactor(t) + chain := backends.NewSimulatedBackend(core.GenesisAlloc{ + owner.From: {Balance: assets.Ether(100).ToInt()}, + }, 30e6) + + // router + _, _, _, err := router.DeployRouter(owner, chain, common.HexToAddress("0x1"), common.HexToAddress("0x2")) + require.NoError(t, err) + chain.Commit() + + // nonce manager + _, _, _, err = nonce_manager.DeployNonceManager(owner, chain, []common.Address{common.HexToAddress("0x1")}) + require.NoError(t, err) + chain.Commit() + + // offramp + _, _, _, err = offramp.DeployOffRamp(owner, chain, offramp.OffRampStaticConfig{ + ChainSelector: 1, + Rmn: common.HexToAddress("0x1"), + TokenAdminRegistry: common.HexToAddress("0x2"), + NonceManager: common.HexToAddress("0x3"), + }, offramp.OffRampDynamicConfig{ + FeeQuoter: common.HexToAddress("0x4"), + PermissionLessExecutionThresholdSeconds: uint32((8 * time.Hour).Seconds()), + MaxTokenTransferGas: 50_000, + MaxPoolReleaseOrMintGas: 50_000, + MessageValidator: common.HexToAddress("0x5"), + }, nil) + require.NoError(t, err) + chain.Commit() + + // onramp + _, _, _, err = onramp.DeployOnRamp(owner, chain, onramp.OnRampStaticConfig{ + ChainSelector: 1, + Rmn: common.HexToAddress("0x1"), + NonceManager: common.HexToAddress("0x2"), + TokenAdminRegistry: common.HexToAddress("0x3"), + }, onramp.OnRampDynamicConfig{ + FeeQuoter: common.HexToAddress("0x4"), + MessageValidator: common.HexToAddress("0x5"), + FeeAggregator: common.HexToAddress("0x6"), + AllowListAdmin: common.HexToAddress("0x7"), + }, nil) + require.NoError(t, err) + chain.Commit() + + // fee quoter + _, _, _, err = fee_quoter.DeployFeeQuoter( + owner, + chain, + fee_quoter.FeeQuoterStaticConfig{ + MaxFeeJuelsPerMsg: big.NewInt(1e18), + LinkToken: common.HexToAddress("0x1"), + StalenessThreshold: 10, + }, + []common.Address{common.HexToAddress("0x1")}, + []common.Address{common.HexToAddress("0x2")}, + []fee_quoter.FeeQuoterTokenPriceFeedUpdate{}, + []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs{}, + []fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs{}, + []fee_quoter.FeeQuoterDestChainConfigArgs{}) + require.NoError(t, err) + chain.Commit() + + // token admin registry + _, _, _, err = token_admin_registry.DeployTokenAdminRegistry(owner, chain) + require.NoError(t, err) + chain.Commit() + + // TODO: add rmn home and rmn remote +} diff --git a/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go b/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go index 19588a8009..3c2d44cd30 100644 --- a/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go +++ b/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go @@ -47,7 +47,6 @@ type CCIPConfigTypesOCR3Config struct { F uint8 OffchainConfigVersion uint64 OfframpAddress []byte - BootstrapP2PIds [][32]byte P2pIds [][32]byte Signers [][]byte Transmitters [][]byte @@ -61,8 +60,8 @@ type CCIPConfigTypesOCR3ConfigWithMeta struct { } var CCIPConfigMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidConfigLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"currentState\",\"type\":\"uint8\"},{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"proposedState\",\"type\":\"uint8\"}],\"name\":\"InvalidConfigStateTransition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeNotInRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonExistentConfigTransition\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"set\",\"type\":\"bytes32[]\"}],\"name\":\"NotASortedSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"subset\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"superset\",\"type\":\"bytes32[]\"}],\"name\":\"NotASubset\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"NotEnoughTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfframpAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p2pIdsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"signersLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transmittersLength\",\"type\":\"uint256\"}],\"name\":\"P2PIdsLengthNotMatching\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyBootstrapP2PIds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOCR3Configs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyTransmitters\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"}],\"name\":\"WrongConfigCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigestBlueGreen\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapabilityConfigurationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"chainSelectorRemoves\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pageIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"name\":\"getAllChainConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilityRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getOCRConfig\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"bootstrapP2PIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"internalType\":\"structCCIPConfigTypes.OCR3ConfigWithMeta[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620044b7380380620044b78339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e9576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b6080516142b6620002016000396000818160f801528181610f3001526111c501526142b66000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638318ed5d11610081578063f2fde38b1161005b578063f2fde38b1461020f578063f442c89a14610222578063fba64a7c1461023557600080fd5b80638318ed5d146101b05780638da5cb5b146101d1578063b74b2356146101ef57600080fd5b8063181f5a77116100b2578063181f5a771461013d5780634bd0473f1461018657806379ba5097146101a657600080fd5b806301ffc9a7146100ce578063020330e6146100f6575b600080fd5b6100e16100dc366004613060565b610248565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b6101796040518060400160405280601481526020017f43434950436f6e66696720312e362e302d64657600000000000000000000000081525081565b6040516100ed9190613106565b61019961019436600461314a565b6102e1565b6040516100ed9190613269565b6101ae6107b1565b005b6101796101be366004613446565b5060408051602081019091526000815290565b60005473ffffffffffffffffffffffffffffffffffffffff16610118565b6102026101fd366004613463565b6108b3565b6040516100ed91906134c9565b6101ae61021d366004613559565b610b34565b6101ae6102303660046135db565b610b48565b6101ae61024336600461365f565b610f18565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea7210000000000000000000000000000000000000000000000000000000014806102db57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b63ffffffff8216600090815260056020526040812060609183600181111561030b5761030b61317f565b600181111561031c5761031c61317f565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156107a557600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff16600181111561038f5761038f61317f565b60018111156103a0576103a061317f565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916103f89061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546104249061371c565b80156104715780601f1061044657610100808354040283529160200191610471565b820191906000526020600020905b81548152906001019060200180831161045457829003601f168201915b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156104c957602002820191906000526020600020905b8154815260200190600101908083116104b5575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561052157602002820191906000526020600020905b81548152602001906001019080831161050d575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156105fb57838290600052602060002001805461056e9061371c565b80601f016020809104026020016040519081016040528092919081815260200182805461059a9061371c565b80156105e75780601f106105bc576101008083540402835291602001916105e7565b820191906000526020600020905b8154815290600101906020018083116105ca57829003601f168201915b50505050508152602001906001019061054f565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156106d45783829060005260206000200180546106479061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546106739061371c565b80156106c05780601f10610695576101008083540402835291602001916106c0565b820191906000526020600020905b8154815290600101906020018083116106a357829003601f168201915b505050505081526020019060010190610628565b5050505081526020016006820180546106ec9061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546107189061371c565b80156107655780601f1061073a57610100808354040283529160200191610765565b820191906000526020600020905b81548152906001019060200180831161074857829003601f168201915b505050919092525050508152600782015467ffffffffffffffff16602080830191909152600890920154604090910152908252600192909201910161034a565b50505050905092915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610837576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b606060006108c16003610fd9565b905060006108cf848661379e565b90508315806108de5750818110155b1561091e576040805160008082526020820190925290610914565b610901612df1565b8152602001906001900390816108f95790505b50925050506102db565b600061092a85836137e4565b9050828111156109375750815b600061094383836137f7565b67ffffffffffffffff81111561095b5761095b6137b5565b60405190808252806020026020018201604052801561099457816020015b610981612df1565b8152602001906001900390816109795790505b50905060006109a36003610fe3565b9050835b83811015610b275760008282815181106109c3576109c361380a565b60209081029190910181015160408051808201825267ffffffffffffffff831680825260009081526002855282902082518154608081880283018101909552606082018181529597509295860194909391928492849190840182828015610a4957602002820191906000526020600020905b815481526020019060010190808311610a35575b5050509183525050600182015460ff166020820152600282018054604090920191610a739061371c565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9f9061371c565b8015610aec5780601f10610ac157610100808354040283529160200191610aec565b820191906000526020600020905b815481529060010190602001808311610acf57829003601f168201915b50505091909252505050905284610b0388856137f7565b81518110610b1357610b1361380a565b6020908102919091010152506001016109a7565b5090979650505050505050565b610b3c610ff7565b610b458161107a565b50565b610b50610ff7565b60005b83811015610d3657610b97858583818110610b7057610b7061380a565b9050602002016020810190610b859190613839565b60039067ffffffffffffffff1661116f565b610c0157848482818110610bad57610bad61380a565b9050602002016020810190610bc29190613839565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161082e565b60026000868684818110610c1757610c1761380a565b9050602002016020810190610c2c9190613839565b67ffffffffffffffff1681526020810191909152604001600090812090610c538282612e39565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610c8b600283016000612e57565b5050610cc9858583818110610ca257610ca261380a565b9050602002016020810190610cb79190613839565b60039067ffffffffffffffff16611187565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110610cfd57610cfd61380a565b9050602002016020810190610d129190613839565b60405167ffffffffffffffff909116815260200160405180910390a1600101610b53565b5060005b81811015610f11576000838383818110610d5657610d5661380a565b9050602002810190610d689190613854565b610d76906020810190613892565b610d7f90613a94565b80519091506000858585818110610d9857610d9861380a565b9050602002810190610daa9190613854565b610db8906020810190613839565b905060005b8251811015610df057610de8838281518110610ddb57610ddb61380a565b6020026020010151611193565b600101610dbd565b50826020015160ff16600003610e32576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120845180518693610e62928492910190612e91565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560408201516002820190610eaf9082613b7b565b50610ec991506003905067ffffffffffffffff83166112ac565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e08184604051610efb929190613c95565b60405180910390a1505050806001019050610d3a565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610f87576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610f9584860186613d40565b9050600080610fa3836112b8565b8151919350915015610fbb57610fbb84600084611511565b805115610fce57610fce84600183611511565b505050505050505050565b60006102db825490565b60606000610ff083611cf2565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611078576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161082e565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036110f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161082e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515610ff0565b6000610ff08383611d4e565b6040517f50c946fe000000000000000000000000000000000000000000000000000000008152600481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906350c946fe90602401600060405180830381865afa158015611221573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526112679190810190613fb1565b60808101519091506112a8576040517f8907a4fa0000000000000000000000000000000000000000000000000000000081526004810183905260240161082e565b5050565b6000610ff08383611e48565b606080600460ff16835111156112fa576040517f8854586400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160028082526060820190925290816020015b61137e6040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161131057505060408051600280825260608201909252919350602082015b6114166040805161014081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff1681526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b8152602001906001900390816113a857905050905060008060005b855181101561150457600086828151811061144e5761144e61380a565b602002602001015160000151600181111561146b5761146b61317f565b036114b8578581815181106114825761148261380a565b602002602001015185848151811061149c5761149c61380a565b6020026020010181905250826114b190614089565b92506114fc565b8581815181106114ca576114ca61380a565b60200260200101518483815181106114e4576114e461380a565b6020026020010181905250816114f990614089565b91505b600101611431565b5090835281529092909150565b63ffffffff83166000908152600560205260408120818460018111156115395761153961317f565b600181111561154a5761154a61317f565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156119d357600084815260209020604080516101a08101909152600984029091018054829060608201908390829060ff1660018111156115bd576115bd61317f565b60018111156115ce576115ce61317f565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916116269061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546116529061371c565b801561169f5780601f106116745761010080835404028352916020019161169f565b820191906000526020600020905b81548152906001019060200180831161168257829003601f168201915b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156116f757602002820191906000526020600020905b8154815260200190600101908083116116e3575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561174f57602002820191906000526020600020905b81548152602001906001019080831161173b575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b8282101561182957838290600052602060002001805461179c9061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546117c89061371c565b80156118155780601f106117ea57610100808354040283529160200191611815565b820191906000526020600020905b8154815290600101906020018083116117f857829003601f168201915b50505050508152602001906001019061177d565b50505050815260200160058201805480602002602001604051908101604052809291908181526020016000905b828210156119025783829060005260206000200180546118759061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546118a19061371c565b80156118ee5780601f106118c3576101008083540402835291602001916118ee565b820191906000526020600020905b8154815290600101906020018083116118d157829003601f168201915b505050505081526020019060010190611856565b50505050815260200160068201805461191a9061371c565b80601f01602080910402602001604051908101604052809291908181526020018280546119469061371c565b80156119935780601f1061196857610100808354040283529160200191611993565b820191906000526020600020905b81548152906001019060200180831161197657829003601f168201915b505050919092525050508152600782015467ffffffffffffffff166020808301919091526008909201546040909101529082526001929092019101611578565b50505050905060006119e58251611e97565b905060006119f38451611e97565b90506119ff8282611ee9565b6000611a0e8785878686611fa5565b9050611a1a8482612391565b63ffffffff8716600090815260056020526040812090876001811115611a4257611a4261317f565b6001811115611a5357611a5361317f565b81526020019081526020016000206000611a6d9190612edc565b60005b8151811015611ce85763ffffffff8816600090815260056020526040812090886001811115611aa157611aa161317f565b6001811115611ab257611ab261317f565b8152602001908152602001600020828281518110611ad257611ad261380a565b6020908102919091018101518254600181810185556000948552929093208151805160099095029091018054929490939192849283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908381811115611b3c57611b3c61317f565b021790555060208201518154604084015160608501517fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90921661010067ffffffffffffffff948516027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1617690100000000000000000060ff90921691909102177fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a0100000000000000000000929091169190910217815560808201516001820190611c0b9082613b7b565b5060a08201518051611c27916002840191602090910190612e91565b5060c08201518051611c43916003840191602090910190612e91565b5060e08201518051611c5f916004840191602090910190612efd565b506101008201518051611c7c916005840191602090910190612efd565b506101208201516006820190611c929082613b7b565b50505060208201516007820180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff909216919091179055604090910151600890910155600101611a70565b5050505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611d4257602002820191906000526020600020905b815481526020019060010190808311611d2e575b50505050509050919050565b60008181526001830160205260408120548015611e37576000611d726001836137f7565b8554909150600090611d86906001906137f7565b9050808214611deb576000866000018281548110611da657611da661380a565b9060005260206000200154905080876000018481548110611dc957611dc961380a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611dfc57611dfc6140c1565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506102db565b60009150506102db565b5092915050565b6000818152600183016020526040812054611e8f575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556102db565b5060006102db565b60006002821115611ed7576040517f3e4785260000000000000000000000000000000000000000000000000000000081526004810183905260240161082e565b8160028111156102db576102db61317f565b6000826002811115611efd57611efd61317f565b826002811115611f0f57611f0f61317f565b611f1991906140f0565b90508060011480611f655750807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff148015611f6557506002836002811115611f6357611f6361317f565b145b15611f6f57505050565b82826040517f0a6b675b00000000000000000000000000000000000000000000000000000000815260040161082e929190614120565b60606000845167ffffffffffffffff811115611fc357611fc36137b5565b604051908082528060200260200182016040528015611fec578160200160208202803683370190505b50905060008460028111156120035761200361317f565b1480156120215750600183600281111561201f5761201f61317f565b145b156120625760018160008151811061203b5761203b61380a565b602002602001019067ffffffffffffffff16908167ffffffffffffffff16815250506121ca565b60018460028111156120765761207661317f565b148015612094575060028360028111156120925761209261317f565b145b1561212b57856000815181106120ac576120ac61380a565b602002602001015160200151816000815181106120cb576120cb61380a565b602002602001019067ffffffffffffffff16908167ffffffffffffffff1681525050856000815181106121005761210061380a565b6020026020010151602001516001612118919061413b565b8160018151811061203b5761203b61380a565b600284600281111561213f5761213f61317f565b14801561215d5750600183600281111561215b5761215b61317f565b145b1561219457856001815181106121755761217561380a565b6020026020010151602001518160008151811061203b5761203b61380a565b83836040517f0a6b675b00000000000000000000000000000000000000000000000000000000815260040161082e929190614120565b6000855167ffffffffffffffff8111156121e6576121e66137b5565b60405190808252806020026020018201604052801561229c57816020015b604080516101a081018252600060608083018281526080840183905260a0840183905260c0840183905260e084018290526101008401829052610120840182905261014084018290526101608401829052610180840191909152825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816122045790505b50905060005b8251811015612385576122cd8782815181106122c0576122c061380a565b6020026020010151612710565b60405180606001604052808883815181106122ea576122ea61380a565b602002602001015181526020018483815181106123095761230961380a565b602002602001015167ffffffffffffffff16815260200161235d8b8685815181106123365761233661380a565b60200260200101518b86815181106123505761235061380a565b6020026020010151612b16565b8152508282815181106123725761237261380a565b60209081029190910101526001016122a2565b50979650505050505050565b81518151811580156123a35750806001145b1561244557826000815181106123bb576123bb61380a565b60200260200101516020015167ffffffffffffffff1660011461243f57826000815181106123eb576123eb61380a565b60209081029190910181015101516040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526001602482015260440161082e565b50505050565b8160011480156124555750806002145b1561260b578360008151811061246d5761246d61380a565b6020026020010151604001518360008151811061248c5761248c61380a565b6020026020010151604001511461251857826000815181106124b0576124b061380a565b602002602001015160400151846000815181106124cf576124cf61380a565b6020026020010151604001516040517fc7ccdd7f00000000000000000000000000000000000000000000000000000000815260040161082e929190918252602082015260400190565b8360008151811061252b5761252b61380a565b6020026020010151602001516001612543919061413b565b67ffffffffffffffff16836001815181106125605761256061380a565b60200260200101516020015167ffffffffffffffff161461243f578260018151811061258e5761258e61380a565b602002602001015160200151846000815181106125ad576125ad61380a565b60200260200101516020015160016125c5919061413b565b6040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff92831660048201529116602482015260440161082e565b81600214801561261b5750806001145b156126de57836001815181106126335761263361380a565b602002602001015160400151836000815181106126525761265261380a565b6020026020010151604001511461243f57826000815181106126765761267661380a565b602002602001015160400151846001815181106126955761269561380a565b6020026020010151604001516040517f9e97567000000000000000000000000000000000000000000000000000000000815260040161082e929190918252602082015260400190565b6040517f1f1b2bb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015167ffffffffffffffff16600003612758576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008151600181111561276d5761276d61317f565b1415801561278e575060018151600181111561278b5761278b61317f565b14155b156127c5576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806080015151600003612804576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015161281f9060039067ffffffffffffffff1661116f565b6128675760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161082e565b60e081015151601f10156128a7576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010081015151601f10156128e8576040517f645960ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015167ffffffffffffffff166000908152600290915260408120600101546129189060ff16600361415c565b612923906001614178565b60ff1690508082610100015151101561297a57610100820151516040517f548dd21f00000000000000000000000000000000000000000000000000000000815260048101919091526024810182905260440161082e565b816040015160ff166000036129bb576040517f39d1a4d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516129cb90600361415c565b60ff168260e001515111612a0b576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160e00151518260c0015151141580612a2f5750816101000151518260c001515114155b15612a8a5760c08201515160e083015151610100840151516040517fba900f6d00000000000000000000000000000000000000000000000000000000815260048101939093526024830191909152604482015260640161082e565b8160c00151518260a00151511115612ace576040517f8473d80700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612ae08260a001518360c00151612beb565b60005b8260e0015151811015612b1157612b098360c001518281518110610ddb57610ddb61380a565b600101612ae3565b505050565b60008082602001518584600001518560800151878760a001518860c001518960e001518a61010001518b604001518c606001518d6101200151604051602001612b6a9c9b9a99989796959493929190614191565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0a000000000000000000000000000000000000000000000000000000000000179150509392505050565b81511580612bf857508051155b15612c2f576040517fe249684100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c3882612d66565b612c4181612d66565b6000805b835182108015612c555750825181105b15612d2757828181518110612c6c57612c6c61380a565b6020026020010151848381518110612c8657612c8661380a565b60200260200101511115612ca457612c9d81614089565b9050612c45565b828181518110612cb657612cb661380a565b6020026020010151848381518110612cd057612cd061380a565b602002602001015103612cf157612ce682614089565b9150612c9d81614089565b83836040517fd671700c00000000000000000000000000000000000000000000000000000000815260040161082e929190614271565b835182101561243f5783836040517fd671700c00000000000000000000000000000000000000000000000000000000815260040161082e929190614271565b60015b81518110156112a85781612d7e6001836137f7565b81518110612d8e57612d8e61380a565b6020026020010151828281518110612da857612da861380a565b602002602001015111612de957816040517f1bc41b4200000000000000000000000000000000000000000000000000000000815260040161082e9190614296565b600101612d69565b6040518060400160405280600067ffffffffffffffff168152602001612e34604051806060016040528060608152602001600060ff168152602001606081525090565b905290565b5080546000825590600052602060002090810190610b459190612f4f565b508054612e639061371c565b6000825580601f10612e73575050565b601f016020900490600052602060002090810190610b459190612f4f565b828054828255906000526020600020908101928215612ecc579160200282015b82811115612ecc578251825591602001919060010190612eb1565b50612ed8929150612f4f565b5090565b5080546000825560090290600052602060002090810190610b459190612f64565b828054828255906000526020600020908101928215612f43579160200282015b82811115612f435782518290612f339082613b7b565b5091602001919060010190612f1d565b50612ed8929150613025565b5b80821115612ed85760008155600101612f50565b80821115612ed85780547fffffffffffffffffffffffffffff00000000000000000000000000000000000016815560008181612fa36001830182612e57565b612fb1600283016000612e39565b612fbf600383016000612e39565b612fcd600483016000613042565b612fdb600583016000613042565b612fe9600683016000612e57565b5050506007810180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560006008820155600901612f64565b80821115612ed85760006130398282612e57565b50600101613025565b5080546000825590600052602060002090810190610b459190613025565b60006020828403121561307257600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ff057600080fd5b6000815180845260005b818110156130c8576020818501810151868301820152016130ac565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610ff060208301846130a2565b63ffffffff81168114610b4557600080fd5b803561313681613119565b919050565b80356002811061313657600080fd5b6000806040838503121561315d57600080fd5b823561316881613119565b91506131766020840161313b565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106131be576131be61317f565b9052565b60008151808452602080850194506020840160005b838110156131f3578151875295820195908201906001016131d7565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015610b27577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189526132578383516130a2565b9884019892509083019060010161321d565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015613438577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08984030185528151606081518186526132d782870182516131ae565b8981015160806132f28189018367ffffffffffffffff169052565b8a830151915060a0613308818a018460ff169052565b938301519360c092506133268984018667ffffffffffffffff169052565b818401519450610140915060e082818b01526133466101a08b01876130a2565b95508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0610100818c890301818d015261338588856131c2565b97508587015195506101209350818c890301848d01526133a588876131c2565b9750828701519550818c890301858d01526133c088876131fe565b975080870151955050808b8803016101608c01526133de87866131fe565b9650828601519550808b8803016101808c0152505050505061340082826130a2565b9150508882015161341c8a87018267ffffffffffffffff169052565b5090870151938701939093529386019390860190600101613292565b509098975050505050505050565b60006020828403121561345857600080fd5b8135610ff081613119565b6000806040838503121561347657600080fd5b50508035926020909101359150565b600081516060845261349a60608501826131c2565b905060ff6020840151166020850152604083015184820360408601526134c082826130a2565b95945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015613438578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff16845287015187840187905261354687850182613485565b95880195935050908601906001016134f2565b60006020828403121561356b57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610ff057600080fd5b60008083601f8401126135a157600080fd5b50813567ffffffffffffffff8111156135b957600080fd5b6020830191508360208260051b85010111156135d457600080fd5b9250929050565b600080600080604085870312156135f157600080fd5b843567ffffffffffffffff8082111561360957600080fd5b6136158883890161358f565b9096509450602087013591508082111561362e57600080fd5b5061363b8782880161358f565b95989497509550505050565b803567ffffffffffffffff8116811461313657600080fd5b6000806000806000806080878903121561367857600080fd5b863567ffffffffffffffff8082111561369057600080fd5b61369c8a838b0161358f565b909850965060208901359150808211156136b557600080fd5b818901915089601f8301126136c957600080fd5b8135818111156136d857600080fd5b8a60208285010111156136ea57600080fd5b60208301965080955050505061370260408801613647565b91506137106060880161312b565b90509295509295509295565b600181811c9082168061373057607f821691505b602082108103613769577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176102db576102db61376f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b808201808211156102db576102db61376f565b818103818111156102db576102db61376f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561384b57600080fd5b610ff082613647565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261388857600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261388857600080fd5b604051610140810167ffffffffffffffff811182821017156138ea576138ea6137b5565b60405290565b60405160e0810167ffffffffffffffff811182821017156138ea576138ea6137b5565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561395a5761395a6137b5565b604052919050565b600067ffffffffffffffff82111561397c5761397c6137b5565b5060051b60200190565b600082601f83011261399757600080fd5b813560206139ac6139a783613962565b613913565b8083825260208201915060208460051b8701019350868411156139ce57600080fd5b602086015b848110156139ea57803583529183019183016139d3565b509695505050505050565b803560ff8116811461313657600080fd5b600082601f830112613a1757600080fd5b813567ffffffffffffffff811115613a3157613a316137b5565b613a6260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613913565b818152846020838601011115613a7757600080fd5b816020850160208301376000918101602001919091529392505050565b600060608236031215613aa657600080fd5b6040516060810167ffffffffffffffff8282108183111715613aca57613aca6137b5565b816040528435915080821115613adf57600080fd5b613aeb36838701613986565b8352613af9602086016139f5565b60208401526040850135915080821115613b1257600080fd5b50613b1f36828601613a06565b60408301525092915050565b601f821115612b11576000816000526020600020601f850160051c81016020861015613b545750805b601f850160051c820191505b81811015613b7357828155600101613b60565b505050505050565b815167ffffffffffffffff811115613b9557613b956137b5565b613ba981613ba3845461371c565b84613b2b565b602080601f831160018114613bfc5760008415613bc65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b73565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613c4957888601518255948401946001909101908401613c2a565b5085821015613c8557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83168152604060208201526000613cb86040830184613485565b949350505050565b600082601f830112613cd157600080fd5b81356020613ce16139a783613962565b82815260059290921b84018101918181019086841115613d0057600080fd5b8286015b848110156139ea57803567ffffffffffffffff811115613d245760008081fd5b613d328986838b0101613a06565b845250918301918301613d04565b60006020808385031215613d5357600080fd5b823567ffffffffffffffff80821115613d6b57600080fd5b818501915085601f830112613d7f57600080fd5b8135613d8d6139a782613962565b81815260059190911b83018401908481019088831115613dac57600080fd5b8585015b83811015613f3a57803585811115613dc757600080fd5b8601610140818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215613dfc57600080fd5b613e046138c6565b613e0f89830161313b565b8152613e1d60408301613647565b89820152613e2d606083016139f5565b6040820152613e3e60808301613647565b606082015260a082013587811115613e5557600080fd5b613e638d8b83860101613a06565b60808301525060c082013587811115613e7b57600080fd5b613e898d8b83860101613986565b60a08301525060e082013587811115613ea157600080fd5b613eaf8d8b83860101613986565b60c0830152506101008083013588811115613ec957600080fd5b613ed78e8c83870101613cc0565b60e0840152506101208084013589811115613ef157600080fd5b613eff8f8d83880101613cc0565b8385015250610140840135915088821115613f1957600080fd5b613f278e8c84870101613a06565b9083015250845250918601918601613db0565b5098975050505050505050565b805161313681613119565b600082601f830112613f6357600080fd5b81516020613f736139a783613962565b8083825260208201915060208460051b870101935086841115613f9557600080fd5b602086015b848110156139ea5780518352918301918301613f9a565b600060208284031215613fc357600080fd5b815167ffffffffffffffff80821115613fdb57600080fd5b9083019060e08286031215613fef57600080fd5b613ff76138f0565b61400083613f47565b815261400e60208401613f47565b602082015261401f60408401613f47565b6040820152606083015160608201526080830151608082015260a08301518281111561404a57600080fd5b61405687828601613f52565b60a08301525060c08301518281111561406e57600080fd5b61407a87828601613f52565b60c08301525095945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140ba576140ba61376f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8181036000831280158383131683831282161715611e4157611e4161376f565b600381106131be576131be61317f565b6040810161412e8285614110565b610ff06020830184614110565b67ffffffffffffffff818116838216019080821115611e4157611e4161376f565b60ff8181168382160290811690818114611e4157611e4161376f565b60ff81811683821601908111156102db576102db61376f565b67ffffffffffffffff8d16815263ffffffff8c1660208201526141b7604082018c6131ae565b610180606082015260006141cf61018083018c6130a2565b67ffffffffffffffff8b16608084015282810360a08401526141f1818b6131c2565b905082810360c0840152614205818a6131c2565b905082810360e084015261421981896131fe565b905082810361010084015261422e81886131fe565b60ff8716610120850152905067ffffffffffffffff851661014084015282810361016084015261425e81856130a2565b9f9e505050505050505050505050505050565b60408152600061428460408301856131c2565b82810360208401526134c081856131c2565b602081526000610ff060208301846131c256fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidConfigLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"currentState\",\"type\":\"uint8\"},{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"proposedState\",\"type\":\"uint8\"}],\"name\":\"InvalidConfigStateTransition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeNotInRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonExistentConfigTransition\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"NotEnoughTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfframpAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p2pIdsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"signersLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transmittersLength\",\"type\":\"uint256\"}],\"name\":\"P2PIdsLengthNotMatching\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOCR3Configs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"}],\"name\":\"WrongConfigCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigestBlueGreen\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapabilityConfigurationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"chainSelectorRemoves\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pageIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"name\":\"getAllChainConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilityRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getOCRConfig\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"internalType\":\"structCCIPConfigTypes.OCR3ConfigWithMeta[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162004080380380620040808339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e9576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051613e7f620002016000396000818160f801528181610ea701526111170152613e7f6000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638318ed5d11610081578063f2fde38b1161005b578063f2fde38b1461020f578063f442c89a14610222578063fba64a7c1461023557600080fd5b80638318ed5d146101b05780638da5cb5b146101d1578063b74b2356146101ef57600080fd5b8063181f5a77116100b2578063181f5a771461013d5780634bd0473f1461018657806379ba5097146101a657600080fd5b806301ffc9a7146100ce578063020330e6146100f6575b600080fd5b6100e16100dc366004612cbd565b610248565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b6101796040518060400160405280601481526020017f43434950436f6e66696720312e362e302d64657600000000000000000000000081525081565b6040516100ed9190612d63565b610199610194366004612da7565b6102e1565b6040516100ed9190612ec6565b6101ae610759565b005b6101796101be366004613082565b5060408051602081019091526000815290565b60005473ffffffffffffffffffffffffffffffffffffffff16610118565b6102026101fd36600461309f565b61085b565b6040516100ed9190613105565b6101ae61021d366004613195565b610adc565b6101ae610230366004613217565b610af0565b6101ae61024336600461329b565b610e8f565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea7210000000000000000000000000000000000000000000000000000000014806102db57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b63ffffffff8216600090815260056020526040812060609183600181111561030b5761030b612ddc565b600181111561031c5761031c612ddc565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561074d57600084815260209020604080516101808101909152600884029091018054829060608201908390829060ff16600181111561038f5761038f612ddc565b60018111156103a0576103a0612ddc565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916103f890613358565b80601f016020809104026020016040519081016040528092919081815260200182805461042490613358565b80156104715780601f1061044657610100808354040283529160200191610471565b820191906000526020600020905b81548152906001019060200180831161045457829003601f168201915b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156104c957602002820191906000526020600020905b8154815260200190600101908083116104b5575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b828210156105a357838290600052602060002001805461051690613358565b80601f016020809104026020016040519081016040528092919081815260200182805461054290613358565b801561058f5780601f106105645761010080835404028352916020019161058f565b820191906000526020600020905b81548152906001019060200180831161057257829003601f168201915b5050505050815260200190600101906104f7565b50505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b8282101561067c5783829060005260206000200180546105ef90613358565b80601f016020809104026020016040519081016040528092919081815260200182805461061b90613358565b80156106685780601f1061063d57610100808354040283529160200191610668565b820191906000526020600020905b81548152906001019060200180831161064b57829003601f168201915b5050505050815260200190600101906105d0565b50505050815260200160058201805461069490613358565b80601f01602080910402602001604051908101604052809291908181526020018280546106c090613358565b801561070d5780601f106106e25761010080835404028352916020019161070d565b820191906000526020600020905b8154815290600101906020018083116106f057829003601f168201915b505050919092525050508152600682015467ffffffffffffffff16602080830191909152600790920154604090910152908252600192909201910161034a565b50505050905092915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b606060006108696003610f4a565b9050600061087784866133da565b90508315806108865750818110155b156108c65760408051600080825260208201909252906108bc565b6108a9612a5c565b8152602001906001900390816108a15790505b50925050506102db565b60006108d28583613420565b9050828111156108df5750815b60006108eb8383613433565b67ffffffffffffffff811115610903576109036133f1565b60405190808252806020026020018201604052801561093c57816020015b610929612a5c565b8152602001906001900390816109215790505b509050600061094b6003610f54565b9050835b83811015610acf57600082828151811061096b5761096b613446565b60209081029190910181015160408051808201825267ffffffffffffffff8316808252600090815260028552829020825181546080818802830181019095526060820181815295975092958601949093919284928491908401828280156109f157602002820191906000526020600020905b8154815260200190600101908083116109dd575b5050509183525050600182015460ff166020820152600282018054604090920191610a1b90613358565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4790613358565b8015610a945780601f10610a6957610100808354040283529160200191610a94565b820191906000526020600020905b815481529060010190602001808311610a7757829003601f168201915b50505091909252505050905284610aab8885613433565b81518110610abb57610abb613446565b60209081029190910101525060010161094f565b5090979650505050505050565b610ae4610f68565b610aed81610feb565b50565b610af8610f68565b60005b83811015610cde57610b3f858583818110610b1857610b18613446565b9050602002016020810190610b2d9190613475565b60039067ffffffffffffffff166110e0565b610ba957848482818110610b5557610b55613446565b9050602002016020810190610b6a9190613475565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d6565b60026000868684818110610bbf57610bbf613446565b9050602002016020810190610bd49190613475565b67ffffffffffffffff1681526020810191909152604001600090812090610bfb8282612aa4565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610c33600283016000612ac2565b5050610c71858583818110610c4a57610c4a613446565b9050602002016020810190610c5f9190613475565b60039067ffffffffffffffff166110f8565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110610ca557610ca5613446565b9050602002016020810190610cba9190613475565b60405167ffffffffffffffff909116815260200160405180910390a1600101610afb565b5060005b81811015610e88576000838383818110610cfe57610cfe613446565b9050602002810190610d109190613490565b610d1e9060208101906134ce565b610d27906136d0565b90506000848484818110610d3d57610d3d613446565b9050602002810190610d4f9190613490565b610d5d906020810190613475565b9050610d6c8260000151611104565b816020015160ff16600003610dad576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120835180518593610ddd928492910190612afc565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560408201516002820190610e2a90826137b7565b50610e4491506003905067ffffffffffffffff8316611250565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e08183604051610e769291906138d1565b60405180910390a15050600101610ce2565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610efe576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610f15610f108688018861397c565b61125c565b8151919350915015610f2d57610f2d836000846114a7565b805115610f4057610f40836001836114a7565b5050505050505050565b60006102db825490565b60606000610f6183611c09565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610fe9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107d6565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361106a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107d6565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515610f61565b6000610f618383611c65565b60005b815181101561124c5760008019167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166350c946fe84848151811061116357611163613446565b60200260200101516040518263ffffffff1660e01b815260040161118991815260200190565b600060405180830381865afa1580156111a6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111ec9190810190613bc7565b60800151036112445781818151811061120757611207613446565b60200260200101516040517f8907a4fa0000000000000000000000000000000000000000000000000000000081526004016107d691815260200190565b600101611107565b5050565b6000610f618383611d5f565b606080600460ff168351111561129e576040517f8854586400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160028082526060820190925290816020015b61131b6040805161012081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff16815260200160608152602001606081526020016060815260200160608152602001606081525090565b8152602001906001900390816112b457505060408051600280825260608201909252919350602082015b6113ac6040805161012081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff16815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161134557905050905060008060005b855181101561149a5760008682815181106113e4576113e4613446565b602002602001015160000151600181111561140157611401612ddc565b0361144e5785818151811061141857611418613446565b602002602001015185848151811061143257611432613446565b60200260200101819052508261144790613c9f565b9250611492565b85818151811061146057611460613446565b602002602001015184838151811061147a5761147a613446565b60200260200101819052508161148f90613c9f565b91505b6001016113c7565b5090835281529092909150565b63ffffffff83166000908152600560205260408120818460018111156114cf576114cf612ddc565b60018111156114e0576114e0612ddc565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561191157600084815260209020604080516101808101909152600884029091018054829060608201908390829060ff16600181111561155357611553612ddc565b600181111561156457611564612ddc565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916115bc90613358565b80601f01602080910402602001604051908101604052809291908181526020018280546115e890613358565b80156116355780601f1061160a57610100808354040283529160200191611635565b820191906000526020600020905b81548152906001019060200180831161161857829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561168d57602002820191906000526020600020905b815481526020019060010190808311611679575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b828210156117675783829060005260206000200180546116da90613358565b80601f016020809104026020016040519081016040528092919081815260200182805461170690613358565b80156117535780601f1061172857610100808354040283529160200191611753565b820191906000526020600020905b81548152906001019060200180831161173657829003601f168201915b5050505050815260200190600101906116bb565b50505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156118405783829060005260206000200180546117b390613358565b80601f01602080910402602001604051908101604052809291908181526020018280546117df90613358565b801561182c5780601f106118015761010080835404028352916020019161182c565b820191906000526020600020905b81548152906001019060200180831161180f57829003601f168201915b505050505081526020019060010190611794565b50505050815260200160058201805461185890613358565b80601f016020809104026020016040519081016040528092919081815260200182805461188490613358565b80156118d15780601f106118a6576101008083540402835291602001916118d1565b820191906000526020600020905b8154815290600101906020018083116118b457829003601f168201915b505050919092525050508152600682015467ffffffffffffffff16602080830191909152600790920154604090910152908252600192909201910161150e565b50505050905060006119238251611dae565b905060006119318451611dae565b905061193d8282611e00565b600061194c8785878686611ebc565b905061195884826122a0565b63ffffffff871660009081526005602052604081209087600181111561198057611980612ddc565b600181111561199157611991612ddc565b815260200190815260200160002060006119ab9190612b47565b60005b8151811015610f405763ffffffff88166000908152600560205260408120908860018111156119df576119df612ddc565b60018111156119f0576119f0612ddc565b8152602001908152602001600020828281518110611a1057611a10613446565b6020908102919091018101518254600181810185556000948552929093208151805160089095029091018054929490939192849283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908381811115611a7a57611a7a612ddc565b021790555060208201518154604084015160608501517fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90921661010067ffffffffffffffff948516027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1617690100000000000000000060ff90921691909102177fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a0100000000000000000000929091169190910217815560808201516001820190611b4990826137b7565b5060a08201518051611b65916002840191602090910190612afc565b5060c08201518051611b81916003840191602090910190612b68565b5060e08201518051611b9d916004840191602090910190612b68565b506101008201516005820190611bb390826137b7565b50505060208201516006820180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9092169190911790556040909101516007909101556001016119ae565b606081600001805480602002602001604051908101604052809291908181526020018280548015611c5957602002820191906000526020600020905b815481526020019060010190808311611c45575b50505050509050919050565b60008181526001830160205260408120548015611d4e576000611c89600183613433565b8554909150600090611c9d90600190613433565b9050808214611d02576000866000018281548110611cbd57611cbd613446565b9060005260206000200154905080876000018481548110611ce057611ce0613446565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611d1357611d13613cd7565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506102db565b60009150506102db565b5092915050565b6000818152600183016020526040812054611da6575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556102db565b5060006102db565b60006002821115611dee576040517f3e478526000000000000000000000000000000000000000000000000000000008152600481018390526024016107d6565b8160028111156102db576102db612ddc565b6000826002811115611e1457611e14612ddc565b826002811115611e2657611e26612ddc565b611e309190613d06565b90508060011480611e7c5750807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff148015611e7c57506002836002811115611e7a57611e7a612ddc565b145b15611e8657505050565b82826040517f0a6b675b0000000000000000000000000000000000000000000000000000000081526004016107d6929190613d36565b60606000845167ffffffffffffffff811115611eda57611eda6133f1565b604051908082528060200260200182016040528015611f03578160200160208202803683370190505b5090506000846002811115611f1a57611f1a612ddc565b148015611f3857506001836002811115611f3657611f36612ddc565b145b15611f7957600181600081518110611f5257611f52613446565b602002602001019067ffffffffffffffff16908167ffffffffffffffff16815250506120e1565b6001846002811115611f8d57611f8d612ddc565b148015611fab57506002836002811115611fa957611fa9612ddc565b145b156120425785600081518110611fc357611fc3613446565b60200260200101516020015181600081518110611fe257611fe2613446565b602002602001019067ffffffffffffffff16908167ffffffffffffffff16815250508560008151811061201757612017613446565b602002602001015160200151600161202f9190613d51565b81600181518110611f5257611f52613446565b600284600281111561205657612056612ddc565b1480156120745750600183600281111561207257612072612ddc565b145b156120ab578560018151811061208c5761208c613446565b60200260200101516020015181600081518110611f5257611f52613446565b83836040517f0a6b675b0000000000000000000000000000000000000000000000000000000081526004016107d6929190613d36565b6000855167ffffffffffffffff8111156120fd576120fd6133f1565b6040519080825280602002602001820160405280156121ab57816020015b6040805161018081018252600060608083018281526080840183905260a0840183905260c0840183905260e08401829052610100840182905261012084018290526101408401829052610160840191909152825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161211b5790505b50905060005b8251811015612294576121dc8782815181106121cf576121cf613446565b602002602001015161261f565b60405180606001604052808883815181106121f9576121f9613446565b6020026020010151815260200184838151811061221857612218613446565b602002602001015167ffffffffffffffff16815260200161226c8b86858151811061224557612245613446565b60200260200101518b868151811061225f5761225f613446565b602002602001015161298e565b81525082828151811061228157612281613446565b60209081029190910101526001016121b1565b50979650505050505050565b81518151811580156122b25750806001145b1561235457826000815181106122ca576122ca613446565b60200260200101516020015167ffffffffffffffff1660011461234e57826000815181106122fa576122fa613446565b60209081029190910181015101516040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152600160248201526044016107d6565b50505050565b8160011480156123645750806002145b1561251a578360008151811061237c5761237c613446565b6020026020010151604001518360008151811061239b5761239b613446565b6020026020010151604001511461242757826000815181106123bf576123bf613446565b602002602001015160400151846000815181106123de576123de613446565b6020026020010151604001516040517fc7ccdd7f0000000000000000000000000000000000000000000000000000000081526004016107d6929190918252602082015260400190565b8360008151811061243a5761243a613446565b60200260200101516020015160016124529190613d51565b67ffffffffffffffff168360018151811061246f5761246f613446565b60200260200101516020015167ffffffffffffffff161461234e578260018151811061249d5761249d613446565b602002602001015160200151846000815181106124bc576124bc613446565b60200260200101516020015160016124d49190613d51565b6040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9283166004820152911660248201526044016107d6565b81600214801561252a5750806001145b156125ed578360018151811061254257612542613446565b6020026020010151604001518360008151811061256157612561613446565b6020026020010151604001511461234e578260008151811061258557612585613446565b602002602001015160400151846001815181106125a4576125a4613446565b6020026020010151604001516040517f9e9756700000000000000000000000000000000000000000000000000000000081526004016107d6929190918252602082015260400190565b6040517f1f1b2bb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015167ffffffffffffffff16600003612667576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008151600181111561267c5761267c612ddc565b1415801561269d575060018151600181111561269a5761269a612ddc565b14155b156126d4576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080810151511580612711575060408051600060208201520160405160208183030381529060405280519060200120816080015180519060200120145b15612748576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101516127639060039067ffffffffffffffff166110e0565b6127ab5760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d6565b60208082015167ffffffffffffffff166000908152600290915260408120600101546127db9060ff166003613d72565b6127e6906001613d8e565b60ff169050808260e0015151101561283b5760e0820151516040517f548dd21f0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107d6565b60c08201515161010081111561287d576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260a00151518114158061289657508260e00151518114155b156128f05760a08301515160c08401515160e0850151516040517fba900f6d0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016107d6565b826040015160ff16600003612931576040517f39d1a4d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040830151612941906003613d72565b60ff16811161297c576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129898360a00151611104565b505050565b60008082602001518584600001518560800151878760a001518860c001518960e001518a604001518b606001518c61010001516040516020016129db9b9a99989796959493929190613da7565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0a000000000000000000000000000000000000000000000000000000000000179150509392505050565b6040518060400160405280600067ffffffffffffffff168152602001612a9f604051806060016040528060608152602001600060ff168152602001606081525090565b905290565b5080546000825590600052602060002090810190610aed9190612bba565b508054612ace90613358565b6000825580601f10612ade575050565b601f016020900490600052602060002090810190610aed9190612bba565b828054828255906000526020600020908101928215612b37579160200282015b82811115612b37578251825591602001919060010190612b1c565b50612b43929150612bba565b5090565b5080546000825560080290600052602060002090810190610aed9190612bcf565b828054828255906000526020600020908101928215612bae579160200282015b82811115612bae5782518290612b9e90826137b7565b5091602001919060010190612b88565b50612b43929150612c82565b5b80821115612b435760008155600101612bbb565b80821115612b435780547fffffffffffffffffffffffffffff00000000000000000000000000000000000016815560008181612c0e6001830182612ac2565b612c1c600283016000612aa4565b612c2a600383016000612c9f565b612c38600483016000612c9f565b612c46600583016000612ac2565b5050506006810180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560006007820155600801612bcf565b80821115612b43576000612c968282612ac2565b50600101612c82565b5080546000825590600052602060002090810190610aed9190612c82565b600060208284031215612ccf57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f6157600080fd5b6000815180845260005b81811015612d2557602081850181015186830182015201612d09565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610f616020830184612cff565b63ffffffff81168114610aed57600080fd5b8035612d9381612d76565b919050565b803560028110612d9357600080fd5b60008060408385031215612dba57600080fd5b8235612dc581612d76565b9150612dd360208401612d98565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110612e1b57612e1b612ddc565b9052565b60008151808452602080850194506020840160005b83811015612e5057815187529582019590820190600101612e34565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015610acf577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952612eb4838351612cff565b98840198925090830190600101612e7a565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015613074577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0898403018552815160608151818652612f348287018251612e0b565b898101516080612f4f8189018367ffffffffffffffff169052565b8a830151915060a0612f65818a018460ff169052565b938301519360c09250612f838984018667ffffffffffffffff169052565b818401519450610120915060e082818b0152612fa36101808b0187612cff565b95508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0610100818c890301818d0152612fe28885612e1f565b958701518c87038301868e0152959750612ffc8887612e5b565b9750828701519550818c8903016101408d01526130198887612e5b565b975080870151965050808b8803016101608c0152505050505061303c8282612cff565b915050888201516130588a87018267ffffffffffffffff169052565b5090870151938701939093529386019390860190600101612eef565b509098975050505050505050565b60006020828403121561309457600080fd5b8135610f6181612d76565b600080604083850312156130b257600080fd5b50508035926020909101359150565b60008151606084526130d66060850182612e1f565b905060ff6020840151166020850152604083015184820360408601526130fc8282612cff565b95945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015613074578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff168452870151878401879052613182878501826130c1565b958801959350509086019060010161312e565b6000602082840312156131a757600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f6157600080fd5b60008083601f8401126131dd57600080fd5b50813567ffffffffffffffff8111156131f557600080fd5b6020830191508360208260051b850101111561321057600080fd5b9250929050565b6000806000806040858703121561322d57600080fd5b843567ffffffffffffffff8082111561324557600080fd5b613251888389016131cb565b9096509450602087013591508082111561326a57600080fd5b50613277878288016131cb565b95989497509550505050565b803567ffffffffffffffff81168114612d9357600080fd5b600080600080600080608087890312156132b457600080fd5b863567ffffffffffffffff808211156132cc57600080fd5b6132d88a838b016131cb565b909850965060208901359150808211156132f157600080fd5b818901915089601f83011261330557600080fd5b81358181111561331457600080fd5b8a602082850101111561332657600080fd5b60208301965080955050505061333e60408801613283565b915061334c60608801612d88565b90509295509295509295565b600181811c9082168061336c57607f821691505b6020821081036133a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176102db576102db6133ab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b808201808211156102db576102db6133ab565b818103818111156102db576102db6133ab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561348757600080fd5b610f6182613283565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126134c457600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126134c457600080fd5b604051610120810167ffffffffffffffff81118282101715613526576135266133f1565b60405290565b60405160e0810167ffffffffffffffff81118282101715613526576135266133f1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613596576135966133f1565b604052919050565b600067ffffffffffffffff8211156135b8576135b86133f1565b5060051b60200190565b600082601f8301126135d357600080fd5b813560206135e86135e38361359e565b61354f565b8083825260208201915060208460051b87010193508684111561360a57600080fd5b602086015b84811015613626578035835291830191830161360f565b509695505050505050565b803560ff81168114612d9357600080fd5b600082601f83011261365357600080fd5b813567ffffffffffffffff81111561366d5761366d6133f1565b61369e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161354f565b8181528460208386010111156136b357600080fd5b816020850160208301376000918101602001919091529392505050565b6000606082360312156136e257600080fd5b6040516060810167ffffffffffffffff8282108183111715613706576137066133f1565b81604052843591508082111561371b57600080fd5b613727368387016135c2565b835261373560208601613631565b6020840152604085013591508082111561374e57600080fd5b5061375b36828601613642565b60408301525092915050565b601f821115612989576000816000526020600020601f850160051c810160208610156137905750805b601f850160051c820191505b818110156137af5782815560010161379c565b505050505050565b815167ffffffffffffffff8111156137d1576137d16133f1565b6137e5816137df8454613358565b84613767565b602080601f83116001811461383857600084156138025750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556137af565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561388557888601518255948401946001909101908401613866565b50858210156138c157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff831681526040602082015260006138f460408301846130c1565b949350505050565b600082601f83011261390d57600080fd5b8135602061391d6135e38361359e565b82815260059290921b8401810191818101908684111561393c57600080fd5b8286015b8481101561362657803567ffffffffffffffff8111156139605760008081fd5b61396e8986838b0101613642565b845250918301918301613940565b6000602080838503121561398f57600080fd5b823567ffffffffffffffff808211156139a757600080fd5b818501915085601f8301126139bb57600080fd5b81356139c96135e38261359e565b81815260059190911b830184019084810190888311156139e857600080fd5b8585015b83811015613b5057803585811115613a0357600080fd5b8601610120818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001811315613a3957600080fd5b613a41613502565b613a4c8a8401612d98565b8152613a5a60408401613283565b8a820152613a6a60608401613631565b6040820152613a7b60808401613283565b606082015260a083013588811115613a9257600080fd5b613aa08e8c83870101613642565b60808301525060c083013588811115613ab857600080fd5b613ac68e8c838701016135c2565b60a08301525060e083013588811115613adf5760008081fd5b613aed8e8c838701016138fc565b60c0830152506101008084013589811115613b085760008081fd5b613b168f8d838801016138fc565b60e084015250918301359188831115613b2f5760008081fd5b613b3d8e8c85870101613642565b90820152855250509186019186016139ec565b5098975050505050505050565b8051612d9381612d76565b600082601f830112613b7957600080fd5b81516020613b896135e38361359e565b8083825260208201915060208460051b870101935086841115613bab57600080fd5b602086015b848110156136265780518352918301918301613bb0565b600060208284031215613bd957600080fd5b815167ffffffffffffffff80821115613bf157600080fd5b9083019060e08286031215613c0557600080fd5b613c0d61352c565b613c1683613b5d565b8152613c2460208401613b5d565b6020820152613c3560408401613b5d565b6040820152606083015160608201526080830151608082015260a083015182811115613c6057600080fd5b613c6c87828601613b68565b60a08301525060c083015182811115613c8457600080fd5b613c9087828601613b68565b60c08301525095945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613cd057613cd06133ab565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8181036000831280158383131683831282161715611d5857611d586133ab565b60038110612e1b57612e1b612ddc565b60408101613d448285613d26565b610f616020830184613d26565b67ffffffffffffffff818116838216019080821115611d5857611d586133ab565b60ff8181168382160290811690818114611d5857611d586133ab565b60ff81811683821601908111156102db576102db6133ab565b600061016067ffffffffffffffff8e16835263ffffffff8d166020840152613dd2604084018d612e0b565b806060840152613de48184018c612cff565b67ffffffffffffffff8b166080850152905082810360a0840152613e08818a612e1f565b905082810360c0840152613e1c8189612e5b565b905082810360e0840152613e308188612e5b565b60ff8716610100850152905067ffffffffffffffff8516610120840152828103610140840152613e608185612cff565b9e9d505050505050505050505050505056fea164736f6c6343000818000a", } var CCIPConfigABI = CCIPConfigMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go index cf2ff7d133..8d824d8d0e 100644 --- a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go +++ b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go @@ -30,6 +30,11 @@ var ( _ = abi.ConvertType ) +type IRMNV2Signature struct { + R [32]byte + S [32]byte +} + type InternalEVM2AnyRampMessage struct { Header InternalRampMessageHeader Sender common.Address @@ -46,6 +51,14 @@ type InternalGasPriceUpdate struct { UsdPerUnitGas *big.Int } +type InternalMerkleRoot struct { + SourceChainSelector uint64 + MinSeqNr uint64 + MaxSeqNr uint64 + MerkleRoot [32]byte + OnRampAddress []byte +} + type InternalPriceUpdates struct { TokenPriceUpdates []InternalTokenPriceUpdate GasPriceUpdates []InternalGasPriceUpdate @@ -73,19 +86,9 @@ type InternalTokenPriceUpdate struct { } type OffRampCommitReport struct { - PriceUpdates InternalPriceUpdates - MerkleRoots []OffRampMerkleRoot -} - -type OffRampInterval struct { - Min uint64 - Max uint64 -} - -type OffRampMerkleRoot struct { - SourceChainSelector uint64 - Interval OffRampInterval - MerkleRoot [32]byte + PriceUpdates InternalPriceUpdates + MerkleRoots []InternalMerkleRoot + RmnSignatures []IRMNV2Signature } type OffRampSourceChainConfig struct { @@ -96,8 +99,8 @@ type OffRampSourceChainConfig struct { } var CCIPReaderTesterMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPSendRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"getInboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"setDestChainSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"testNonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"setInboundNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061148e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100835760003560e01c80634cf66e361461008857806385096da91461009d5780639041be3d146100b057806393df2867146100e0578063c1a5a355146100f3578063c92236251461012f578063e44302b714610142578063e83eabba14610155578063e9d68a8e14610168575b600080fd5b61009b610096366004610658565b610188565b005b61009b6100ab3660046108d0565b6101dd565b6100c36100be3660046109fe565b610222565b6040516001600160401b0390911681526020015b60405180910390f35b61009b6100ee366004610a68565b610251565b61009b610101366004610ac8565b6001600160401b03918216600090815260016020526040902080546001600160401b03191691909216179055565b6100c361013d366004610afb565b6102b2565b61009b610150366004610cbd565b6102fc565b61009b610163366004610e27565b610336565b61017b6101763660046109fe565b6103c2565b6040516100d79190610f28565b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df285856040516101ce929190610f80565b60405180910390a45050505050565b816001600160401b03167fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140826040516102169190611083565b60405180910390a25050565b6001600160401b038082166000908152600160208190526040822054919261024b921690611185565b92915050565b6001600160401b03841660009081526002602052604090819020905184919061027d90859085906111ba565b90815260405190819003602001902080546001600160401b03929092166001600160401b031990921691909117905550505050565b6001600160401b03831660009081526002602052604080822090516102da90859085906111ba565b908152604051908190036020019020546001600160401b031690509392505050565b7f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d8160405161032b9190611282565b60405180910390a150565b6001600160401b0380831660009081526020818152604091829020845181549286015193860151909416600160a81b02600160a81b600160e81b0319931515600160a01b026001600160a81b03199093166001600160a01b03909516949094179190911791909116919091178155606082015182919060018201906103bb90826113c2565b5050505050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b038781168452838352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b90920490921694830194909452600184018054939492939184019161044d90611337565b80601f016020809104026020016040519081016040528092919081815260200182805461047990611337565b80156104c65780601f1061049b576101008083540402835291602001916104c6565b820191906000526020600020905b8154815290600101906020018083116104a957829003601f168201915b5050505050815250509050919050565b80356001600160401b03811681146104ed57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b038111828210171561052a5761052a6104f2565b60405290565b60405161010081016001600160401b038111828210171561052a5761052a6104f2565b604080519081016001600160401b038111828210171561052a5761052a6104f2565b604051606081016001600160401b038111828210171561052a5761052a6104f2565b604051608081016001600160401b038111828210171561052a5761052a6104f2565b604051601f8201601f191681016001600160401b03811182821017156105e1576105e16104f2565b604052919050565b600082601f8301126105fa57600080fd5b81356001600160401b03811115610613576106136104f2565b610626601f8201601f19166020016105b9565b81815284602083860101111561063b57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561067057600080fd5b610679866104d6565b9450610687602087016104d6565b9350604086013592506060860135600481106106a257600080fd5b915060808601356001600160401b038111156106bd57600080fd5b6106c9888289016105e9565b9150509295509295909350565b600060a082840312156106e857600080fd5b6106f0610508565b905081358152610702602083016104d6565b6020820152610713604083016104d6565b6040820152610724606083016104d6565b6060820152610735608083016104d6565b608082015292915050565b6001600160a01b038116811461075557600080fd5b50565b80356104ed81610740565b60006001600160401b0382111561077c5761077c6104f2565b5060051b60200190565b600082601f83011261079757600080fd5b813560206107ac6107a783610763565b6105b9565b82815260059290921b840181019181810190868411156107cb57600080fd5b8286015b848110156108c55780356001600160401b03808211156107ef5760008081fd5b9088019060a0828b03601f19018113156108095760008081fd5b610811610508565b87840135838111156108235760008081fd5b6108318d8a838801016105e9565b825250604080850135848111156108485760008081fd5b6108568e8b838901016105e9565b8a840152506060808601358581111561086f5760008081fd5b61087d8f8c838a01016105e9565b838501525060809150818601358184015250828501359250838311156108a35760008081fd5b6108b18d8a858801016105e9565b9082015286525050509183019183016107cf565b509695505050505050565b600080604083850312156108e357600080fd5b6108ec836104d6565b915060208301356001600160401b038082111561090857600080fd5b90840190610180828703121561091d57600080fd5b610925610530565b61092f87846106d6565b815261093d60a08401610758565b602082015260c08301358281111561095457600080fd5b610960888286016105e9565b60408301525060e08301358281111561097857600080fd5b610984888286016105e9565b6060830152506101008301358281111561099d57600080fd5b6109a9888286016105e9565b6080830152506109bc6101208401610758565b60a082015261014083013560c0820152610160830135828111156109df57600080fd5b6109eb88828601610786565b60e0830152508093505050509250929050565b600060208284031215610a1057600080fd5b610a19826104d6565b9392505050565b60008083601f840112610a3257600080fd5b5081356001600160401b03811115610a4957600080fd5b602083019150836020828501011115610a6157600080fd5b9250929050565b60008060008060608587031215610a7e57600080fd5b610a87856104d6565b9350610a95602086016104d6565b925060408501356001600160401b03811115610ab057600080fd5b610abc87828801610a20565b95989497509550505050565b60008060408385031215610adb57600080fd5b610ae4836104d6565b9150610af2602084016104d6565b90509250929050565b600080600060408486031215610b1057600080fd5b610b19846104d6565b925060208401356001600160401b03811115610b3457600080fd5b610b4086828701610a20565b9497909650939450505050565b80356001600160e01b03811681146104ed57600080fd5b600082601f830112610b7557600080fd5b81356020610b856107a783610763565b82815260069290921b84018101918181019086841115610ba457600080fd5b8286015b848110156108c55760408189031215610bc15760008081fd5b610bc9610553565b610bd2826104d6565b8152610bdf858301610b4d565b81860152835291830191604001610ba8565b600082601f830112610c0257600080fd5b81356020610c126107a783610763565b82815260079290921b84018101918181019086841115610c3157600080fd5b8286015b848110156108c5578088036080811215610c4f5760008081fd5b610c57610575565b610c60836104d6565b8152604080601f1984011215610c765760008081fd5b610c7e610553565b9250610c8b8785016104d6565b8352610c988185016104d6565b8388015281870192909252606083013591810191909152835291830191608001610c35565b60006020808385031215610cd057600080fd5b82356001600160401b0380821115610ce757600080fd5b81850191506040808388031215610cfd57600080fd5b610d05610553565b833583811115610d1457600080fd5b84016040818a031215610d2657600080fd5b610d2e610553565b813585811115610d3d57600080fd5b8201601f81018b13610d4e57600080fd5b8035610d5c6107a782610763565b81815260069190911b8201890190898101908d831115610d7b57600080fd5b928a01925b82841015610dcb5787848f031215610d985760008081fd5b610da0610553565b8435610dab81610740565b8152610db8858d01610b4d565b818d0152825292870192908a0190610d80565b845250505081870135935084841115610de357600080fd5b610def8a858401610b64565b8188015282525083850135915082821115610e0957600080fd5b610e1588838601610bf1565b85820152809550505050505092915050565b60008060408385031215610e3a57600080fd5b610e43836104d6565b915060208301356001600160401b0380821115610e5f57600080fd5b9084019060808287031215610e7357600080fd5b610e7b610597565b8235610e8681610740565b815260208301358015158114610e9b57600080fd5b6020820152610eac604084016104d6565b6040820152606083013582811115610ec357600080fd5b610ecf888286016105e9565b6060830152508093505050509250929050565b6000815180845260005b81811015610f0857602081850181015186830182015201610eec565b506000602082860101526020601f19601f83011685010191505092915050565b602080825282516001600160a01b03168282015282015115156040808301919091528201516001600160401b0316606080830191909152820151608080830152600090610f7860a0840182610ee2565b949350505050565b600060048410610fa057634e487b7160e01b600052602160045260246000fd5b83825260406020830152610f786040830184610ee2565b6001600160a01b03169052565b600082825180855260208086019550808260051b84010181860160005b8481101561107657601f19868403018952815160a0815181865261100782870182610ee2565b915050858201518582038787015261101f8282610ee2565b915050604080830151868303828801526110398382610ee2565b925050506060808301518187015250608080830151925085820381870152506110628183610ee2565b9a86019a9450505090830190600101610fe1565b5090979650505050505050565b602081526110d0602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b600060208301516110e460c0840182610fb7565b5060408301516101808060e08501526111016101a0850183610ee2565b91506060850151601f1980868503016101008701526111208483610ee2565b935060808701519150808685030161012087015261113e8483610ee2565b935060a08701519150611155610140870183610fb7565b60c087015161016087015260e087015191508086850301838701525061117b8382610fc4565b9695505050505050565b6001600160401b038181168382160190808211156111b357634e487b7160e01b600052601160045260246000fd5b5092915050565b8183823760009101908152919050565b60008151808452602080850194506020840160005b8381101561121857815180516001600160401b031688528301516001600160e01b031683880152604090960195908201906001016111df565b509495945050505050565b600081518084526020808501945080840160005b8381101561121857815180516001600160401b0390811689528482015180518216868b0152850151166040898101919091520151606088015260809096019590820190600101611237565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b808310156112f057835180516001600160a01b031683528701516001600160e01b0316878301529286019260019290920191908401906112b5565b5093850151878503605f190160808901529361130c81866111ca565b945050505050818501519150601f1984820301604085015261132e8183611223565b95945050505050565b600181811c9082168061134b57607f821691505b60208210810361136b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156113bd576000816000526020600020601f850160051c8101602086101561139a5750805b601f850160051c820191505b818110156113b9578281556001016113a6565b5050505b505050565b81516001600160401b038111156113db576113db6104f2565b6113ef816113e98454611337565b84611371565b602080601f831160018114611424576000841561140c5750858301515b600019600386901b1c1916600185901b1785556113b9565b600085815260208120601f198616915b8281101561145357888601518255948401946001909101908401611434565b50858210156114715787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPMessageSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"onRampAddress\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMNV2.Signature[]\",\"name\":\"rmnSignatures\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPMessageSent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"onRampAddress\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMNV2.Signature[]\",\"name\":\"rmnSignatures\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"getInboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"setDestChainSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"testNonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"setInboundNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506115e2806100206000396000f3fe608060405234801561001057600080fd5b50600436106100835760003560e01c806344f38be5146100885780634cf66e361461009d5780639041be3d146100b057806393df2867146100e0578063a4b0d27c146100f3578063c1a5a35514610106578063c922362514610142578063e83eabba14610155578063e9d68a8e14610168575b600080fd5b61009b6100963660046108c9565b610188565b005b61009b6100ab366004610a53565b6101c2565b6100c36100be366004610ad1565b610217565b6040516001600160401b0390911681526020015b60405180910390f35b61009b6100ee366004610b3b565b610246565b61009b610101366004610d3f565b6102a7565b61009b610114366004610e6d565b6001600160401b03918216600090815260016020526040902080546001600160401b03191691909216179055565b6100c3610150366004610ea0565b6102ec565b61009b610163366004610ef2565b610336565b61017b610176366004610ad1565b6103c2565b6040516100d79190610ff3565b7fd7868a16facbdde7b5c020620136316b3c266fffcb4e1e41cb6a662fe14ba3e1816040516101b79190611189565b60405180910390a150565b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df2858560405161020892919061125b565b60405180910390a45050505050565b6001600160401b0380821660009081526001602081905260408220549192610240921690611292565b92915050565b6001600160401b03841660009081526002602052604090819020905184919061027290859085906112c7565b90815260405190819003602001902080546001600160401b03929092166001600160401b031990921691909117905550505050565b816001600160401b03167ff6e86ef8896c7a0d629406168f396e883280680c99e649b9e2d36466fbc9f9e5826040516102e09190611389565b60405180910390a25050565b6001600160401b038316600090815260026020526040808220905161031490859085906112c7565b908152604051908190036020019020546001600160401b031690509392505050565b6001600160401b0380831660009081526020818152604091829020845181549286015193860151909416600160a81b02600160a81b600160e81b0319931515600160a01b026001600160a81b03199093166001600160a01b03909516949094179190911791909116919091178155606082015182919060018201906103bb9082611516565b5050505050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b038781168452838352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b90920490921694830194909452600184018054939492939184019161044d9061148b565b80601f01602080910402602001604051908101604052809291908181526020018280546104799061148b565b80156104c65780601f1061049b576101008083540402835291602001916104c6565b820191906000526020600020905b8154815290600101906020018083116104a957829003601f168201915b5050505050815250509050919050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561050e5761050e6104d6565b60405290565b60405160a081016001600160401b038111828210171561050e5761050e6104d6565b604051606081016001600160401b038111828210171561050e5761050e6104d6565b60405161010081016001600160401b038111828210171561050e5761050e6104d6565b604051608081016001600160401b038111828210171561050e5761050e6104d6565b604051601f8201601f191681016001600160401b03811182821017156105c5576105c56104d6565b604052919050565b60006001600160401b038211156105e6576105e66104d6565b5060051b60200190565b6001600160a01b038116811461060557600080fd5b50565b8035610613816105f0565b919050565b80356001600160e01b038116811461061357600080fd5b80356001600160401b038116811461061357600080fd5b600082601f83011261065757600080fd5b8135602061066c610667836105cd565b61059d565b82815260069290921b8401810191818101908684111561068b57600080fd5b8286015b848110156106d857604081890312156106a85760008081fd5b6106b06104ec565b6106b98261062f565b81526106c6858301610618565b8186015283529183019160400161068f565b509695505050505050565b600082601f8301126106f457600080fd5b81356001600160401b0381111561070d5761070d6104d6565b610720601f8201601f191660200161059d565b81815284602083860101111561073557600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261076357600080fd5b81356020610773610667836105cd565b82815260059290921b8401810191818101908684111561079257600080fd5b8286015b848110156106d85780356001600160401b03808211156107b65760008081fd5b9088019060a0828b03601f19018113156107d05760008081fd5b6107d8610514565b6107e388850161062f565b815260406107f281860161062f565b89830152606061080381870161062f565b8284015260809150818601358184015250828501359250838311156108285760008081fd5b6108368d8a858801016106e3565b908201528652505050918301918301610796565b600082601f83011261085b57600080fd5b8135602061086b610667836105cd565b82815260069290921b8401810191818101908684111561088a57600080fd5b8286015b848110156106d857604081890312156108a75760008081fd5b6108af6104ec565b81358152848201358582015283529183019160400161088e565b600060208083850312156108dc57600080fd5b82356001600160401b03808211156108f357600080fd5b908401906060828703121561090757600080fd5b61090f610536565b82358281111561091e57600080fd5b8301604081890381131561093157600080fd5b6109396104ec565b82358581111561094857600080fd5b8301601f81018b1361095957600080fd5b8035610967610667826105cd565b81815260069190911b8201890190898101908d83111561098657600080fd5b928a01925b828410156109d65785848f0312156109a35760008081fd5b6109ab6104ec565b84356109b6816105f0565b81526109c3858d01610618565b818d0152825292850192908a019061098b565b8452505050828701359150848211156109ee57600080fd5b6109fa8a838501610646565b81880152835250508284013582811115610a1357600080fd5b610a1f88828601610752565b85830152506040830135935081841115610a3857600080fd5b610a448785850161084a565b60408201529695505050505050565b600080600080600060a08688031215610a6b57600080fd5b610a748661062f565b9450610a826020870161062f565b935060408601359250606086013560048110610a9d57600080fd5b915060808601356001600160401b03811115610ab857600080fd5b610ac4888289016106e3565b9150509295509295909350565b600060208284031215610ae357600080fd5b610aec8261062f565b9392505050565b60008083601f840112610b0557600080fd5b5081356001600160401b03811115610b1c57600080fd5b602083019150836020828501011115610b3457600080fd5b9250929050565b60008060008060608587031215610b5157600080fd5b610b5a8561062f565b9350610b686020860161062f565b925060408501356001600160401b03811115610b8357600080fd5b610b8f87828801610af3565b95989497509550505050565b600060a08284031215610bad57600080fd5b610bb5610514565b905081358152610bc76020830161062f565b6020820152610bd86040830161062f565b6040820152610be96060830161062f565b6060820152610bfa6080830161062f565b608082015292915050565b600082601f830112610c1657600080fd5b81356020610c26610667836105cd565b82815260059290921b84018101918181019086841115610c4557600080fd5b8286015b848110156106d85780356001600160401b0380821115610c695760008081fd5b9088019060a0828b03601f1901811315610c835760008081fd5b610c8b610514565b8784013583811115610c9d5760008081fd5b610cab8d8a838801016106e3565b82525060408085013584811115610cc25760008081fd5b610cd08e8b838901016106e3565b8a8401525060608086013585811115610ce95760008081fd5b610cf78f8c838a01016106e3565b83850152506080915081860135818401525082850135925083831115610d1d5760008081fd5b610d2b8d8a858801016106e3565b908201528652505050918301918301610c49565b60008060408385031215610d5257600080fd5b610d5b8361062f565b915060208301356001600160401b0380821115610d7757600080fd5b908401906101808287031215610d8c57600080fd5b610d94610558565b610d9e8784610b9b565b8152610dac60a08401610608565b602082015260c083013582811115610dc357600080fd5b610dcf888286016106e3565b60408301525060e083013582811115610de757600080fd5b610df3888286016106e3565b60608301525061010083013582811115610e0c57600080fd5b610e18888286016106e3565b608083015250610e2b6101208401610608565b60a082015261014083013560c082015261016083013582811115610e4e57600080fd5b610e5a88828601610c05565b60e0830152508093505050509250929050565b60008060408385031215610e8057600080fd5b610e898361062f565b9150610e976020840161062f565b90509250929050565b600080600060408486031215610eb557600080fd5b610ebe8461062f565b925060208401356001600160401b03811115610ed957600080fd5b610ee586828701610af3565b9497909650939450505050565b60008060408385031215610f0557600080fd5b610f0e8361062f565b915060208301356001600160401b0380821115610f2a57600080fd5b9084019060808287031215610f3e57600080fd5b610f4661057b565b8235610f51816105f0565b815260208301358015158114610f6657600080fd5b6020820152610f776040840161062f565b6040820152606083013582811115610f8e57600080fd5b610f9a888286016106e3565b6060830152508093505050509250929050565b6000815180845260005b81811015610fd357602081850181015186830182015201610fb7565b506000602082860101526020601f19601f83011685010191505092915050565b602080825282516001600160a01b03168282015282015115156040808301919091528201516001600160401b031660608083019190915282015160808083015260009061104360a0840182610fad565b949350505050565b6001600160a01b03169052565b60008151808452602080850194506020840160005b838110156110a657815180516001600160401b031688528301516001600160e01b0316838801526040909601959082019060010161106d565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b8481101561114057858303601f19018952815180516001600160401b03908116855285820151811686860152604080830151909116908501526060808201519085015260809081015160a09185018290529061112c81860183610fad565b9a86019a94505050908301906001016110ce565b5090979650505050505050565b60008151808452602080850194506020840160005b838110156110a6578151805188528301518388015260409096019590820190600101611162565b602080825282516060838301528051604060808501819052815160c086018190526000949392840191859160e08801905b808410156111f557845180516001600160a01b031683528701516001600160e01b0316878301529386019360019390930192908201906111ba565b5093850151878503607f190160a0890152936112118186611058565b945050505050818501519150601f198085830301604086015261123482846110b1565b9250604086015191508085840301606086015250611252828261114d565b95945050505050565b60006004841061127b57634e487b7160e01b600052602160045260246000fd5b838252604060208301526110436040830184610fad565b6001600160401b038181168382160190808211156112c057634e487b7160e01b600052601160045260246000fd5b5092915050565b8183823760009101908152919050565b600082825180855260208086019550808260051b84010181860160005b8481101561114057601f19868403018952815160a0815181865261131a82870182610fad565b91505085820151858203878701526113328282610fad565b9150506040808301518683038288015261134c8382610fad565b925050506060808301518187015250608080830151925085820381870152506113758183610fad565b9a86019a94505050908301906001016112f4565b602081526113d6602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b600060208301516113ea60c084018261104b565b5060408301516101808060e08501526114076101a0850183610fad565b91506060850151601f1980868503016101008701526114268483610fad565b93506080870151915080868503016101208701526114448483610fad565b935060a0870151915061145b61014087018361104b565b60c087015161016087015260e087015191508086850301838701525061148183826112d7565b9695505050505050565b600181811c9082168061149f57607f821691505b6020821081036114bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115611511576000816000526020600020601f850160051c810160208610156114ee5750805b601f850160051c820191505b8181101561150d578281556001016114fa565b5050505b505050565b81516001600160401b0381111561152f5761152f6104d6565b6115438161153d845461148b565b846114c5565b602080601f83116001811461157857600084156115605750858301515b600019600386901b1c1916600185901b17855561150d565b600085815260208120601f198616915b828110156115a757888601518255948401946001909101908401611588565b50858210156115c55787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", } var CCIPReaderTesterABI = CCIPReaderTesterMetaData.ABI @@ -302,16 +305,16 @@ func (_CCIPReaderTester *CCIPReaderTesterCallerSession) GetSourceChainConfig(sou return _CCIPReaderTester.Contract.GetSourceChainConfig(&_CCIPReaderTester.CallOpts, sourceChainSelector) } -func (_CCIPReaderTester *CCIPReaderTesterTransactor) EmitCCIPSendRequested(opts *bind.TransactOpts, destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) { - return _CCIPReaderTester.contract.Transact(opts, "emitCCIPSendRequested", destChainSelector, message) +func (_CCIPReaderTester *CCIPReaderTesterTransactor) EmitCCIPMessageSent(opts *bind.TransactOpts, destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) { + return _CCIPReaderTester.contract.Transact(opts, "emitCCIPMessageSent", destChainSelector, message) } -func (_CCIPReaderTester *CCIPReaderTesterSession) EmitCCIPSendRequested(destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) { - return _CCIPReaderTester.Contract.EmitCCIPSendRequested(&_CCIPReaderTester.TransactOpts, destChainSelector, message) +func (_CCIPReaderTester *CCIPReaderTesterSession) EmitCCIPMessageSent(destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.EmitCCIPMessageSent(&_CCIPReaderTester.TransactOpts, destChainSelector, message) } -func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) EmitCCIPSendRequested(destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) { - return _CCIPReaderTester.Contract.EmitCCIPSendRequested(&_CCIPReaderTester.TransactOpts, destChainSelector, message) +func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) EmitCCIPMessageSent(destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) { + return _CCIPReaderTester.Contract.EmitCCIPMessageSent(&_CCIPReaderTester.TransactOpts, destChainSelector, message) } func (_CCIPReaderTester *CCIPReaderTesterTransactor) EmitCommitReportAccepted(opts *bind.TransactOpts, report OffRampCommitReport) (*types.Transaction, error) { @@ -374,8 +377,8 @@ func (_CCIPReaderTester *CCIPReaderTesterTransactorSession) SetSourceChainConfig return _CCIPReaderTester.Contract.SetSourceChainConfig(&_CCIPReaderTester.TransactOpts, sourceChainSelector, sourceChainConfig) } -type CCIPReaderTesterCCIPSendRequestedIterator struct { - Event *CCIPReaderTesterCCIPSendRequested +type CCIPReaderTesterCCIPMessageSentIterator struct { + Event *CCIPReaderTesterCCIPMessageSent contract *bind.BoundContract event string @@ -386,7 +389,7 @@ type CCIPReaderTesterCCIPSendRequestedIterator struct { fail error } -func (it *CCIPReaderTesterCCIPSendRequestedIterator) Next() bool { +func (it *CCIPReaderTesterCCIPMessageSentIterator) Next() bool { if it.fail != nil { return false @@ -395,7 +398,7 @@ func (it *CCIPReaderTesterCCIPSendRequestedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(CCIPReaderTesterCCIPSendRequested) + it.Event = new(CCIPReaderTesterCCIPMessageSent) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -410,7 +413,7 @@ func (it *CCIPReaderTesterCCIPSendRequestedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(CCIPReaderTesterCCIPSendRequested) + it.Event = new(CCIPReaderTesterCCIPMessageSent) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -425,43 +428,43 @@ func (it *CCIPReaderTesterCCIPSendRequestedIterator) Next() bool { } } -func (it *CCIPReaderTesterCCIPSendRequestedIterator) Error() error { +func (it *CCIPReaderTesterCCIPMessageSentIterator) Error() error { return it.fail } -func (it *CCIPReaderTesterCCIPSendRequestedIterator) Close() error { +func (it *CCIPReaderTesterCCIPMessageSentIterator) Close() error { it.sub.Unsubscribe() return nil } -type CCIPReaderTesterCCIPSendRequested struct { +type CCIPReaderTesterCCIPMessageSent struct { DestChainSelector uint64 Message InternalEVM2AnyRampMessage Raw types.Log } -func (_CCIPReaderTester *CCIPReaderTesterFilterer) FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*CCIPReaderTesterCCIPSendRequestedIterator, error) { +func (_CCIPReaderTester *CCIPReaderTesterFilterer) FilterCCIPMessageSent(opts *bind.FilterOpts, destChainSelector []uint64) (*CCIPReaderTesterCCIPMessageSentIterator, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) } - logs, sub, err := _CCIPReaderTester.contract.FilterLogs(opts, "CCIPSendRequested", destChainSelectorRule) + logs, sub, err := _CCIPReaderTester.contract.FilterLogs(opts, "CCIPMessageSent", destChainSelectorRule) if err != nil { return nil, err } - return &CCIPReaderTesterCCIPSendRequestedIterator{contract: _CCIPReaderTester.contract, event: "CCIPSendRequested", logs: logs, sub: sub}, nil + return &CCIPReaderTesterCCIPMessageSentIterator{contract: _CCIPReaderTester.contract, event: "CCIPMessageSent", logs: logs, sub: sub}, nil } -func (_CCIPReaderTester *CCIPReaderTesterFilterer) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *CCIPReaderTesterCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) { +func (_CCIPReaderTester *CCIPReaderTesterFilterer) WatchCCIPMessageSent(opts *bind.WatchOpts, sink chan<- *CCIPReaderTesterCCIPMessageSent, destChainSelector []uint64) (event.Subscription, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) } - logs, sub, err := _CCIPReaderTester.contract.WatchLogs(opts, "CCIPSendRequested", destChainSelectorRule) + logs, sub, err := _CCIPReaderTester.contract.WatchLogs(opts, "CCIPMessageSent", destChainSelectorRule) if err != nil { return nil, err } @@ -471,8 +474,8 @@ func (_CCIPReaderTester *CCIPReaderTesterFilterer) WatchCCIPSendRequested(opts * select { case log := <-logs: - event := new(CCIPReaderTesterCCIPSendRequested) - if err := _CCIPReaderTester.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + event := new(CCIPReaderTesterCCIPMessageSent) + if err := _CCIPReaderTester.contract.UnpackLog(event, "CCIPMessageSent", log); err != nil { return err } event.Raw = log @@ -493,9 +496,9 @@ func (_CCIPReaderTester *CCIPReaderTesterFilterer) WatchCCIPSendRequested(opts * }), nil } -func (_CCIPReaderTester *CCIPReaderTesterFilterer) ParseCCIPSendRequested(log types.Log) (*CCIPReaderTesterCCIPSendRequested, error) { - event := new(CCIPReaderTesterCCIPSendRequested) - if err := _CCIPReaderTester.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { +func (_CCIPReaderTester *CCIPReaderTesterFilterer) ParseCCIPMessageSent(log types.Log) (*CCIPReaderTesterCCIPMessageSent, error) { + event := new(CCIPReaderTesterCCIPMessageSent) + if err := _CCIPReaderTester.contract.UnpackLog(event, "CCIPMessageSent", log); err != nil { return nil, err } event.Raw = log @@ -768,8 +771,8 @@ func (_CCIPReaderTester *CCIPReaderTesterFilterer) ParseExecutionStateChanged(lo func (_CCIPReaderTester *CCIPReaderTester) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _CCIPReaderTester.abi.Events["CCIPSendRequested"].ID: - return _CCIPReaderTester.ParseCCIPSendRequested(log) + case _CCIPReaderTester.abi.Events["CCIPMessageSent"].ID: + return _CCIPReaderTester.ParseCCIPMessageSent(log) case _CCIPReaderTester.abi.Events["CommitReportAccepted"].ID: return _CCIPReaderTester.ParseCommitReportAccepted(log) case _CCIPReaderTester.abi.Events["ExecutionStateChanged"].ID: @@ -780,12 +783,12 @@ func (_CCIPReaderTester *CCIPReaderTester) ParseLog(log types.Log) (generated.Ab } } -func (CCIPReaderTesterCCIPSendRequested) Topic() common.Hash { - return common.HexToHash("0xcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140") +func (CCIPReaderTesterCCIPMessageSent) Topic() common.Hash { + return common.HexToHash("0xf6e86ef8896c7a0d629406168f396e883280680c99e649b9e2d36466fbc9f9e5") } func (CCIPReaderTesterCommitReportAccepted) Topic() common.Hash { - return common.HexToHash("0x3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d") + return common.HexToHash("0xd7868a16facbdde7b5c020620136316b3c266fffcb4e1e41cb6a662fe14ba3e1") } func (CCIPReaderTesterExecutionStateChanged) Topic() common.Hash { @@ -803,7 +806,7 @@ type CCIPReaderTesterInterface interface { GetSourceChainConfig(opts *bind.CallOpts, sourceChainSelector uint64) (OffRampSourceChainConfig, error) - EmitCCIPSendRequested(opts *bind.TransactOpts, destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) + EmitCCIPMessageSent(opts *bind.TransactOpts, destChainSelector uint64, message InternalEVM2AnyRampMessage) (*types.Transaction, error) EmitCommitReportAccepted(opts *bind.TransactOpts, report OffRampCommitReport) (*types.Transaction, error) @@ -815,11 +818,11 @@ type CCIPReaderTesterInterface interface { SetSourceChainConfig(opts *bind.TransactOpts, sourceChainSelector uint64, sourceChainConfig OffRampSourceChainConfig) (*types.Transaction, error) - FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*CCIPReaderTesterCCIPSendRequestedIterator, error) + FilterCCIPMessageSent(opts *bind.FilterOpts, destChainSelector []uint64) (*CCIPReaderTesterCCIPMessageSentIterator, error) - WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *CCIPReaderTesterCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) + WatchCCIPMessageSent(opts *bind.WatchOpts, sink chan<- *CCIPReaderTesterCCIPMessageSent, destChainSelector []uint64) (event.Subscription, error) - ParseCCIPSendRequested(log types.Log) (*CCIPReaderTesterCCIPSendRequested, error) + ParseCCIPMessageSent(log types.Log) (*CCIPReaderTesterCCIPMessageSent, error) FilterCommitReportAccepted(opts *bind.FilterOpts) (*CCIPReaderTesterCommitReportAcceptedIterator, error) diff --git a/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go b/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go index 807a932da6..d8f616053a 100644 --- a/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go +++ b/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go @@ -155,7 +155,7 @@ type KeystoneFeedsPermissionHandlerPermission struct { var FeeQuoterMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structFeeQuoter.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structFeeQuoter.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"FeeTokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"}],\"name\":\"ReportForwarderUnauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feedTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"storedTimeStamp\",\"type\":\"uint256\"}],\"name\":\"StaleKeystoneUpdate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"reportId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission\",\"name\":\"permission\",\"type\":\"tuple\"}],\"name\":\"ReportPermissionSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structFeeQuoter.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structFeeQuoter.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"processPoolReturnData\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"destExecDataPerToken\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission[]\",\"name\":\"permissions\",\"type\":\"tuple[]\"}],\"name\":\"setReportPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b506040516200775238038062007752833981016040819052620000349162001834565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a5a565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b26565b5050505050505062001ae5565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001953565b60209081029190910101519050620002f560028262000e5f565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001953565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000e7f565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001953565b6020026020010151600b62000e7f60201b90919060201c565b1562000499578281815181106200045b576200045b62001953565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001953565b6020026020010151600b62000e9660201b90919060201c565b156200053b57818181518110620004fd57620004fd62001953565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001953565b6020908102919091018101518051818301516001600160a01b0380831660008181526007875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001953565b6020026020010151905060008383815181106200065f576200065f62001953565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061016081015163ffffffff16155b80620006ba57506101e08101516001600160e01b031916630a04b54b60e21b14155b80620006da5750806060015163ffffffff1681610160015163ffffffff16115b15620007055760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260096020526040812060010154600160881b900460e01b6001600160e01b03191690036200078557816001600160401b03167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb7248260405162000777919062001969565b60405180910390a2620007c9565b816001600160401b03167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab2082604051620007c0919062001969565b60405180910390a25b8060096000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a8154816001600160401b0302191690836001600160401b031602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000a7e5762000a7e62001953565b6020026020010151600001519050600083838151811062000aa35762000aa362001953565b6020908102919091018101518101516001600160a01b03841660008181526008845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a5d565b60005b825181101562000d9957600083828151811062000b4a5762000b4a62001953565b6020026020010151905060008160000151905060005b82602001515181101562000d8a5760008360200151828151811062000b895762000b8962001953565b602002602001015160200151905060008460200151838151811062000bb25762000bb262001953565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c115760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000d77908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000b60565b50505080600101905062000b29565b5060005b81518110156200054457600082828151811062000dbe5762000dbe62001953565b6020026020010151600001519050600083838151811062000de35762000de362001953565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000d9d565b600062000e76836001600160a01b03841662000ead565b90505b92915050565b600062000e76836001600160a01b03841662000fb1565b600062000e76836001600160a01b03841662001003565b6000818152600183016020526040812054801562000fa657600062000ed460018362001aad565b855490915060009062000eea9060019062001aad565b905081811462000f5657600086600001828154811062000f0e5762000f0e62001953565b906000526020600020015490508087600001848154811062000f345762000f3462001953565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f6a5762000f6a62001acf565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e79565b600091505062000e79565b600081815260018301602052604081205462000ffa5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e79565b50600062000e79565b6000818152600183016020526040812054801562000fa65760006200102a60018362001aad565b8554909150600090620010409060019062001aad565b905080821462000f5657600086600001828154811062000f0e5762000f0e62001953565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200109f576200109f62001064565b60405290565b60405160c081016001600160401b03811182821017156200109f576200109f62001064565b60405161020081016001600160401b03811182821017156200109f576200109f62001064565b604051601f8201601f191681016001600160401b03811182821017156200111b576200111b62001064565b604052919050565b80516001600160a01b03811681146200113b57600080fd5b919050565b805163ffffffff811681146200113b57600080fd5b6000606082840312156200116857600080fd5b604051606081016001600160401b03811182821017156200118d576200118d62001064565b604052825190915081906001600160601b0381168114620011ad57600080fd5b8152620011bd6020840162001123565b6020820152620011d06040840162001140565b60408201525092915050565b60006001600160401b03821115620011f857620011f862001064565b5060051b60200190565b600082601f8301126200121457600080fd5b815160206200122d6200122783620011dc565b620010f0565b8083825260208201915060208460051b8701019350868411156200125057600080fd5b602086015b848110156200127757620012698162001123565b835291830191830162001255565b509695505050505050565b600082601f8301126200129457600080fd5b81516020620012a76200122783620011dc565b82815260609283028501820192828201919087851115620012c757600080fd5b8387015b858110156200135a5780890382811215620012e65760008081fd5b620012f06200107a565b620012fb8362001123565b8152604080601f1984011215620013125760008081fd5b6200131c6200107a565b92506200132b88850162001123565b835283015160ff81168114620013415760008081fd5b82880152808701919091528452928401928101620012cb565b5090979650505050505050565b80516001600160401b03811681146200113b57600080fd5b805161ffff811681146200113b57600080fd5b805180151581146200113b57600080fd5b600082601f830112620013b557600080fd5b81516020620013c86200122783620011dc565b82815260059290921b84018101918181019086841115620013e857600080fd5b8286015b84811015620012775780516001600160401b03808211156200140d57600080fd5b908801906040601f19838c0381018213156200142857600080fd5b620014326200107a565b6200143f89860162001367565b815282850151848111156200145357600080fd5b8086019550508c603f8601126200146957600080fd5b8885015193506200147e6200122785620011dc565b84815260e09094028501830193898101908e8611156200149d57600080fd5b958401955b858710156200157657868f0360e0811215620014bd57600080fd5b620014c76200107a565b620014d28962001123565b815260c08683011215620014e557600080fd5b620014ef620010a5565b9150620014fe8d8a0162001140565b82526200150d878a0162001140565b8d8301526200151f60608a016200137f565b878301526200153160808a0162001140565b60608301526200154460a08a0162001140565b60808301526200155760c08a0162001392565b60a0830152808d0191909152825260e09690960195908a0190620014a2565b828b015250875250505092840192508301620013ec565b600082601f8301126200159f57600080fd5b81516020620015b26200122783620011dc565b82815260069290921b84018101918181019086841115620015d257600080fd5b8286015b84811015620012775760408189031215620015f15760008081fd5b620015fb6200107a565b620016068262001123565b81526200161585830162001367565b81860152835291830191604001620015d6565b80516001600160e01b0319811681146200113b57600080fd5b600082601f8301126200165357600080fd5b81516020620016666200122783620011dc565b82815261022092830285018201928282019190878511156200168757600080fd5b8387015b858110156200135a5780890382811215620016a65760008081fd5b620016b06200107a565b620016bb8362001367565b815261020080601f1984011215620016d35760008081fd5b620016dd620010ca565b9250620016ec88850162001392565b83526040620016fd8186016200137f565b8985015260606200171081870162001140565b82860152608091506200172582870162001140565b9085015260a06200173886820162001140565b8286015260c091506200174d8287016200137f565b9085015260e06200176086820162001140565b828601526101009150620017768287016200137f565b908501526101206200178a8682016200137f565b828601526101409150620017a08287016200137f565b90850152610160620017b486820162001140565b828601526101809150620017ca82870162001140565b908501526101a0620017de86820162001367565b828601526101c09150620017f482870162001140565b908501526101e06200180886820162001392565b828601526200181983870162001628565b9085015250508087019190915284529284019281016200168b565b6000806000806000806000610120888a0312156200185157600080fd5b6200185d898962001155565b60608901519097506001600160401b03808211156200187b57600080fd5b620018898b838c0162001202565b975060808a0151915080821115620018a057600080fd5b620018ae8b838c0162001202565b965060a08a0151915080821115620018c557600080fd5b620018d38b838c0162001282565b955060c08a0151915080821115620018ea57600080fd5b620018f88b838c01620013a3565b945060e08a01519150808211156200190f57600080fd5b6200191d8b838c016200158d565b93506101008a01519150808211156200193557600080fd5b50620019448a828b0162001641565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610200810160208301516200198a602084018261ffff169052565b506040830151620019a3604084018263ffffffff169052565b506060830151620019bc606084018263ffffffff169052565b506080830151620019d5608084018263ffffffff169052565b5060a0830151620019ec60a084018261ffff169052565b5060c083015162001a0560c084018263ffffffff169052565b5060e083015162001a1c60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501516001600160401b0316908401526101a080850151909116908301526101c0808401511515908301526101e0928301516001600160e01b031916929091019190915290565b8181038181111562000e7957634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051615c1362001b3f600039600081816102ef0152818161220b01526122740152600081816102b301528181611917015261197701526000818161027f015281816119a00152611a100152615c136000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c806379ba509711610104578063a69c64c0116100a2578063d02641a011610071578063d02641a014610a81578063d8694ccd14610a94578063f2fde38b14610aa7578063ffdb4b3714610aba57600080fd5b8063a69c64c014610997578063bf78e03f146109aa578063c4276bfc14610a57578063cdc73d5114610a7957600080fd5b806382b49eb0116100de57806382b49eb0146107d95780638da5cb5b1461094957806391a2749a146109715780639ea600261461098457600080fd5b806379ba5097146107ab5780637afac322146107b3578063805f2132146107c657600080fd5b8063407e1086116101715780634ab35b0b1161014b5780634ab35b0b14610441578063514e8cff146104815780636def4ce714610524578063770e2dc41461079857600080fd5b8063407e1086146103fb57806341ed29e71461040e57806345ac924d1461042157600080fd5b8063085318f8116101ad578063085318f814610368578063181f5a77146103885780632451a627146103d15780633937306f146103e657600080fd5b806241e5be146101d3578063061877e3146101f957806306285c6914610252575b600080fd5b6101e66101e13660046142ca565b610b02565b6040519081526020015b60405180910390f35b610239610207366004614306565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101f0565b61031c604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101f0565b61037b61037636600461437e565b610b70565b6040516101f09190614490565b6103c46040518060400160405280601381526020017f46656551756f74657220312e362e302d6465760000000000000000000000000081525081565b6040516101f09190614512565b6103d9610ee2565b6040516101f09190614525565b6103f96103f436600461457f565b610ef3565b005b6103f9610409366004614721565b6111a8565b6103f961041c366004614853565b6111bc565b61043461042f36600461498e565b6111fe565b6040516101f091906149d0565b61045461044f366004614306565b6112c9565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b61051761048f366004614a4b565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101f09190614a66565b61078b610532366004614a4b565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101919091525067ffffffffffffffff908116600090815260096020908152604091829020825161020081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a085015271010000000000000000000000000000000000808404881660c086015275010000000000000000000000000000000000000000008404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b01000000000000000000000000000000000000000000000000000000909204861661014084015260019093015480861661016084015264010000000081049096166101808301526c0100000000000000000000000086049094166101a0820152700100000000000000000000000000000000850490911615156101c08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b166101e082015290565b6040516101f09190614aa1565b6103f96107a6366004614cb8565b6112d4565b6103f96112e6565b6103f96107c1366004614fd2565b6113e3565b6103f96107d4366004615078565b6113f5565b6108e96107e73660046150e4565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff919091166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101f09190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6103f961097f36600461510e565b6118dd565b6103f96109923660046151cf565b6118ee565b6103f96109a53660046153dc565b6118ff565b610a236109b8366004614306565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526007825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101f0565b610a6a610a653660046154a1565b611910565b6040516101f093929190615510565b6103d9611b06565b610517610a8f366004614306565b611b12565b6101e6610aa2366004615531565b611c0e565b6103f9610ab5366004614306565b612126565b610acd610ac8366004615586565b612137565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101f0565b6000610b0d826122c2565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b34856122c2565b610b5c907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16856155df565b610b6691906155f6565b90505b9392505050565b67ffffffffffffffff8086166000908152600960205260409020600101546060917101000000000000000000000000000000000090910460e01b908590811115610bbc57610bbc6145ba565b604051908082528060200260200182016040528015610bef57816020015b6060815260200190600190039081610bda5790505b50915060005b85811015610ed7576000858583818110610c1157610c11615631565b610c279260206040909202019081019150614306565b90506000888884818110610c3d57610c3d615631565b9050602002810190610c4f9190615660565b610c5d90604081019061569e565b9150506020811115610d125767ffffffffffffffff8a166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115610d12576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b610d82848a8a86818110610d2857610d28615631565b9050602002810190610d3a9190615660565b610d4890602081019061569e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061235c92505050565b67ffffffffffffffff8a166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320815160c081018352905463ffffffff8082168352640100000000820481168386015268010000000000000000820461ffff16838501526a01000000000000000000008204811660608401526e010000000000000000000000000000820481166080840152720100000000000000000000000000000000000090910460ff16151560a08301908152958552600990935290832054935190937b0100000000000000000000000000000000000000000000000000000090049091169190610e815781610e87565b82606001515b6040805163ffffffff8316602082015291925001604051602081830303815290604052888781518110610ebc57610ebc615631565b60200260200101819052505050505050806001019050610bf5565b505095945050505050565b6060610eee60026123b3565b905090565b610efb6123c0565b6000610f078280615703565b9050905060005b81811015611051576000610f228480615703565b83818110610f3257610f32615631565b905060400201803603810190610f489190615797565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600690975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926110409290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610f0e565b5060006110616020840184615703565b9050905060005b818110156111a257600061107f6020860186615703565b8381811061108f5761108f615631565b9050604002018036038101906110a591906157d4565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e926111919290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101611068565b50505050565b6111b0612405565b6111b981612486565b50565b6111c4612405565b60005b81518110156111fa576111f28282815181106111e5576111e5615631565b6020026020010151612584565b6001016111c7565b5050565b60608160008167ffffffffffffffff81111561121c5761121c6145ba565b60405190808252806020026020018201604052801561126157816020015b604080518082019091526000808252602082015281526020019060019003908161123a5790505b50905060005b828110156112be5761129986868381811061128457611284615631565b9050602002016020810190610a8f9190614306565b8282815181106112ab576112ab615631565b6020908102919091010152600101611267565b509150505b92915050565b60006112c3826122c2565b6112dc612405565b6111fa8282612756565b60015473ffffffffffffffffffffffffffffffffffffffff163314611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610d09565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6113eb612405565b6111fa8282612b63565b600080600061143987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612caa92505050565b92509250925061144b33838584612cc5565b6000611459858701876157f7565b905060005b81518110156118d25760006007600084848151811061147f5761147f615631565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160009081205474010000000000000000000000000000000000000000900460ff169150819003611540578282815181106114e9576114e9615631565b6020908102919091010151516040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b600061158960128386868151811061155a5761155a615631565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612e1d565b9050600660008585815181106115a1576115a1615631565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff1684848151811061161357611613615631565b60200260200101516040015163ffffffff16101561171d5783838151811061163d5761163d615631565b60200260200101516000015184848151811061165b5761165b615631565b6020026020010151604001516006600087878151811061167d5761167d615631565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260409081016000205490517f191ec70600000000000000000000000000000000000000000000000000000000815293909116600484015263ffffffff91821660248401527c01000000000000000000000000000000000000000000000000000000009004166044820152606401610d09565b6040518060400160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260200185858151811061175e5761175e615631565b60200260200101516040015163ffffffff168152506006600086868151811061178957611789615631565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179055835184908490811061182157611821615631565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff167f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a8286868151811061187757611877615631565b6020026020010151604001516040516118c09291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a2505060010161145e565b505050505050505050565b6118e5612405565b6111b981612ee3565b6118f6612405565b6111b98161306f565b611907612405565b6111b981613515565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036119705785925061199e565b61199b87877f0000000000000000000000000000000000000000000000000000000000000000610b02565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611a3d576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610d09565b67ffffffffffffffff881660009081526009602052604081206001015463ffffffff1690611a6c8787846135ff565b9050806020015193508484611af3836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b6060610eee600b6123b3565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600760209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff169082015290611c0557505073ffffffffffffffffffffffffffffffffffffffff166000908152600660209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b69816137a8565b67ffffffffffffffff8083166000908152600960209081526040808320815161020081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a086015271010000000000000000000000000000000000808504881660c087015275010000000000000000000000000000000000000000008504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b01000000000000000000000000000000000000000000000000000000909304861661014085015260019094015480861661016085015264010000000081049098166101808401526c0100000000000000000000000088049094166101a0830152700100000000000000000000000000000000870490931615156101c08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b166101e0840152909190611e28576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b611e43611e3b6080850160608601614306565b600b90613937565b611ea257611e576080840160608501614306565b6040517f2502348c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b6000611eb16040850185615703565b9150611f0d905082611ec6602087018761569e565b905083611ed3888061569e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061396692505050565b6000600881611f226080880160608901614306565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff16915080611f71611f6b6080890160608a01614306565b89612137565b9092509050600080808615611fb757611fab888c611f9560808e0160608f01614306565b888e8060400190611fa69190615703565b613a10565b91945092509050611fd7565b6101a0880151611fd49063ffffffff16662386f26fc100006155df565b92505b61010088015160009061ffff161561201b57612018896dffffffffffffffffffffffffffff607088901c1661200f60208f018f61569e565b90508b86613ce8565b90505b61018089015160009067ffffffffffffffff1661204461203e60808f018f61569e565b8d613d98565b600001518563ffffffff168c60a0015161ffff168f8060200190612068919061569e565b6120739291506155df565b8d6080015163ffffffff1661208891906158be565b61209291906158be565b61209c91906158be565b6120b6906dffffffffffffffffffffffffffff89166155df565b6120c091906155df565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff871682826120f767ffffffffffffffff8c16896155df565b61210191906158be565b61210b91906158be565b61211591906155f6565b9d9c50505050505050505050505050565b61212e612405565b6111b981613e59565b67ffffffffffffffff811660009081526005602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff16918101829052829182036121ef576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000816020015163ffffffff164261220791906158d1565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168111156122a8576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610d09565b6122b1866122c2565b9151919350909150505b9250929050565b6000806122ce83611b12565b9050806020015163ffffffff1660001480612306575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15612355576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610d09565b5192915050565b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016111fa576123ae81613f4e565b505050565b60606000610b6983614001565b6123cb600233613937565b612403576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610d09565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314612403576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d09565b60005b81518110156111fa5760008282815181106124a6576124a6615631565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526007875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a2505050806001019050612489565b600061263d82600001518360600151846020015185604001516040805173ffffffffffffffffffffffffffffffffffffffff80871660208301528516918101919091527fffffffffffffffffffff00000000000000000000000000000000000000000000831660608201527fffff0000000000000000000000000000000000000000000000000000000000008216608082015260009060a001604051602081830303815290604052805190602001209050949350505050565b60808301516000828152600460205260409081902080549215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316929092179091555190915081907f32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a39061274a908590600060a08201905073ffffffffffffffffffffffffffffffffffffffff8084511683527fffffffffffffffffffff0000000000000000000000000000000000000000000060208501511660208401527fffff00000000000000000000000000000000000000000000000000000000000060408501511660408401528060608501511660608401525060808301511515608083015292915050565b60405180910390a25050565b60005b8251811015612a7f57600083828151811061277657612776615631565b6020026020010151905060008160000151905060005b826020015151811015612a71576000836020015182815181106127b1576127b1615631565b60200260200101516020015190506000846020015183815181106127d7576127d7615631565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101561285a5760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610d09565b67ffffffffffffffff84166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b590612a5f908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010161278c565b505050806001019050612759565b5060005b81518110156123ae576000828281518110612aa057612aa0615631565b60200260200101516000015190506000838381518110612ac257612ac2615631565b60209081029190910181015181015167ffffffffffffffff84166000818152600a8452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612a83565b60005b8251811015612c0657612b9c838281518110612b8457612b84615631565b6020026020010151600b61405d90919063ffffffff16565b15612bfe57828181518110612bb357612bb3615631565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b600101612b66565b5060005b81518110156123ae57612c40828281518110612c2857612c28615631565b6020026020010151600b61407f90919063ffffffff16565b15612ca257818181518110612c5757612c57615631565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101612c0a565b6040810151604a820151605e90920151909260609290921c91565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602080840191909152908616828401527fffffffffffffffffffff00000000000000000000000000000000000000000000851660608301527fffff00000000000000000000000000000000000000000000000000000000000084166080808401919091528351808403909101815260a09092018352815191810191909120600081815260049092529190205460ff16612e16576040517f097e17ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8087166004830152851660248201527fffffffffffffffffffff00000000000000000000000000000000000000000000841660448201527fffff00000000000000000000000000000000000000000000000000000000000083166064820152608401610d09565b5050505050565b600080612e2a84866158e4565b9050600060248260ff161115612e6157612e456024836158fd565b612e5090600a615a36565b612e5a90856155f6565b9050612e84565b612e6c8260246158fd565b612e7790600a615a36565b612e8190856155df565b90505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612eda576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b95945050505050565b602081015160005b8151811015612f7e576000828281518110612f0857612f08615631565b60200260200101519050612f268160026140a190919063ffffffff16565b15612f755760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612eeb565b50815160005b81518110156111a2576000828281518110612fa157612fa1615631565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613011576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61301c60028261405d565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101612f84565b60005b81518110156111fa57600082828151811061308f5761308f615631565b6020026020010151905060008383815181106130ad576130ad615631565b60200260200101516000015190506000826020015190508167ffffffffffffffff16600014806130e6575061016081015163ffffffff16155b8061313857506101e08101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806131575750806060015163ffffffff1681610160015163ffffffff16115b1561319a576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610d09565b67ffffffffffffffff821660009081526009602052604081206001015471010000000000000000000000000000000000900460e01b7fffffffff0000000000000000000000000000000000000000000000000000000016900361323e578167ffffffffffffffff167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb724826040516132319190614aa1565b60405180910390a2613281565b8167ffffffffffffffff167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab20826040516132789190614aa1565b60405180910390a25b80600960008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050613072565b60005b81518110156111fa57600082828151811061353557613535615631565b6020026020010151600001519050600083838151811061355757613557615631565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526008845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a25050600101613518565b6040805180820190915260008082526020820152600083900361364057506040805180820190915267ffffffffffffffff8216815260006020820152610b69565b600061364c8486615a45565b9050600061365d8560048189615a8b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f000000000000000000000000000000000000000000000000000000000016136fa57808060200190518101906136f19190615ab5565b92505050610b69565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601613776576040518060400160405280828060200190518101906137629190615ae1565b815260006020909101529250610b69915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613812573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138369190615b14565b5050509150506000811215613877576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006138f68373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156138c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138eb9190615b64565b866020015184612e1d565b604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff4216602082015295945050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b69565b836040015163ffffffff168311156139bf5760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610d09565b836020015161ffff16821115613a01576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111a2846101e001518261235c565b6000808083815b81811015613cda576000878783818110613a3357613a33615631565b905060400201803603810190613a499190615b81565b67ffffffffffffffff8c166000908152600a60209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090613b69576101208d0151613b369061ffff16662386f26fc100006155df565b613b4090886158be565b96508c610140015186613b539190615bba565b9550613b60602086615bba565b94505050613cd2565b604081015160009061ffff1615613c225760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614613bc5578351613bbe906122c2565b9050613bc8565b508a5b620186a0836040015161ffff16613c0a8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166140c390919063ffffffff16565b613c1491906155df565b613c1e91906155f6565b9150505b6060820151613c319088615bba565b9650816080015186613c439190615bba565b8251909650600090613c629063ffffffff16662386f26fc100006155df565b905080821015613c8157613c76818a6158be565b985050505050613cd2565b6000836020015163ffffffff16662386f26fc10000613ca091906155df565b905080831115613cc057613cb4818b6158be565b99505050505050613cd2565b613cca838b6158be565b995050505050505b600101613a17565b505096509650969350505050565b60008063ffffffff8316613cfe610160866155df565b613d0a876101c06158be565b613d1491906158be565b613d1e91906158be565b905060008760c0015163ffffffff168860e0015161ffff1683613d4191906155df565b613d4b91906158be565b61010089015190915061ffff16613d726dffffffffffffffffffffffffffff8916836155df565b613d7c91906155df565b613d8c90655af3107a40006155df565b98975050505050505050565b60408051808201909152600080825260208201526000613dc4858585610160015163ffffffff166135ff565b9050826060015163ffffffff1681600001511115613e0e576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101c001518015613e2257508060200151155b15610b66576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603613ed8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d09565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008151602014613f8d57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614512565b600082806020019051810190613fa39190615ae1565b905073ffffffffffffffffffffffffffffffffffffffff811180613fc8575061040081105b156112c357826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614512565b60608160000180548060200260200160405190810160405280929190818152602001828054801561405157602002820191906000526020600020905b81548152602001906001019080831161403d575b50505050509050919050565b6000610b698373ffffffffffffffffffffffffffffffffffffffff8416614100565b6000610b698373ffffffffffffffffffffffffffffffffffffffff841661414f565b6000610b698373ffffffffffffffffffffffffffffffffffffffff8416614249565b6000670de0b6b3a76400006140f6837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166155df565b610b6991906155f6565b6000818152600183016020526040812054614147575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112c3565b5060006112c3565b600081815260018301602052604081205480156142385760006141736001836158d1565b8554909150600090614187906001906158d1565b90508082146141ec5760008660000182815481106141a7576141a7615631565b90600052602060002001549050808760000184815481106141ca576141ca615631565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806141fd576141fd615bd7565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112c3565b60009150506112c3565b5092915050565b6000818152600183016020526040812054801561423857600061426d6001836158d1565b8554909150600090614281906001906158d1565b90508181146141ec5760008660000182815481106141a7576141a7615631565b803573ffffffffffffffffffffffffffffffffffffffff811681146142c557600080fd5b919050565b6000806000606084860312156142df57600080fd5b6142e8846142a1565b9250602084013591506142fd604085016142a1565b90509250925092565b60006020828403121561431857600080fd5b610b69826142a1565b803567ffffffffffffffff811681146142c557600080fd5b60008083601f84011261434b57600080fd5b50813567ffffffffffffffff81111561436357600080fd5b6020830191508360208260051b85010111156122bb57600080fd5b60008060008060006060868803121561439657600080fd5b61439f86614321565b9450602086013567ffffffffffffffff808211156143bc57600080fd5b6143c889838a01614339565b909650945060408801359150808211156143e157600080fd5b818801915088601f8301126143f557600080fd5b81358181111561440457600080fd5b8960208260061b850101111561441957600080fd5b9699959850939650602001949392505050565b6000815180845260005b8181101561445257602081850181015186830182015201614436565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614505577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526144f385835161442c565b945092850192908501906001016144b9565b5092979650505050505050565b602081526000610b69602083018461442c565b6020808252825182820181905260009190848201906040850190845b8181101561457357835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614541565b50909695505050505050565b60006020828403121561459157600080fd5b813567ffffffffffffffff8111156145a857600080fd5b820160408185031215610b6957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561460c5761460c6145ba565b60405290565b60405160a0810167ffffffffffffffff8111828210171561460c5761460c6145ba565b60405160c0810167ffffffffffffffff8111828210171561460c5761460c6145ba565b604051610200810167ffffffffffffffff8111828210171561460c5761460c6145ba565b6040516060810167ffffffffffffffff8111828210171561460c5761460c6145ba565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156146e6576146e66145ba565b604052919050565b600067ffffffffffffffff821115614708576147086145ba565b5060051b60200190565b60ff811681146111b957600080fd5b6000602080838503121561473457600080fd5b823567ffffffffffffffff81111561474b57600080fd5b8301601f8101851361475c57600080fd5b803561476f61476a826146ee565b61469f565b8181526060918202830184019184820191908884111561478e57600080fd5b938501935b8385101561482e57848903818112156147ac5760008081fd5b6147b46145e9565b6147bd876142a1565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147f15760008081fd5b6147f96145e9565b92506148068989016142a1565b835287013561481481614712565b828901528088019190915283529384019391850191614793565b50979650505050505050565b80151581146111b957600080fd5b80356142c58161483a565b6000602080838503121561486657600080fd5b823567ffffffffffffffff81111561487d57600080fd5b8301601f8101851361488e57600080fd5b803561489c61476a826146ee565b81815260a091820283018401918482019190888411156148bb57600080fd5b938501935b8385101561482e5780858a0312156148d85760008081fd5b6148e0614612565b6148e9866142a1565b8152868601357fffffffffffffffffffff000000000000000000000000000000000000000000008116811461491e5760008081fd5b818801526040868101357fffff000000000000000000000000000000000000000000000000000000000000811681146149575760008081fd5b9082015260606149688782016142a1565b9082015260808681013561497b8161483a565b90820152835293840193918501916148c0565b600080602083850312156149a157600080fd5b823567ffffffffffffffff8111156149b857600080fd5b6149c485828601614339565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b82811015614a3e57614a2e84835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b92840192908501906001016149ed565b5091979650505050505050565b600060208284031215614a5d57600080fd5b610b6982614321565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff1690820152604081016112c3565b81511515815261020081016020830151614ac1602084018261ffff169052565b506040830151614ad9604084018263ffffffff169052565b506060830151614af1606084018263ffffffff169052565b506080830151614b09608084018263ffffffff169052565b5060a0830151614b1f60a084018261ffff169052565b5060c0830151614b3760c084018263ffffffff169052565b5060e0830151614b4d60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff90811691840191909152610160808501518216908401526101808085015167ffffffffffffffff16908401526101a080850151909116908301526101c0808401511515908301526101e0808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff811681146142c557600080fd5b803561ffff811681146142c557600080fd5b600082601f830112614c3157600080fd5b81356020614c4161476a836146ee565b82815260069290921b84018101918181019086841115614c6057600080fd5b8286015b84811015614cad5760408189031215614c7d5760008081fd5b614c856145e9565b614c8e82614321565b8152614c9b8583016142a1565b81860152835291830191604001614c64565b509695505050505050565b60008060408385031215614ccb57600080fd5b67ffffffffffffffff83351115614ce157600080fd5b83601f843585010112614cf357600080fd5b614d0361476a84358501356146ee565b8335840180358083526020808401939260059290921b90910101861015614d2957600080fd5b602085358601015b85358601803560051b01602001811015614f365767ffffffffffffffff81351115614d5b57600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a03011215614d9457600080fd5b614d9c6145e9565b614da860208301614321565b815267ffffffffffffffff60408301351115614dc357600080fd5b88603f604084013584010112614dd857600080fd5b614dee61476a60206040850135850101356146ee565b6020604084810135850182810135808552928401939260e00201018b1015614e1557600080fd5b6040808501358501015b6040858101358601602081013560e0020101811015614f175760e0818d031215614e4857600080fd5b614e506145e9565b614e59826142a1565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215614e8d57600080fd5b614e95614635565b614ea160208401614bfa565b8152614eaf60408401614bfa565b6020820152614ec060608401614c0e565b6040820152614ed160808401614bfa565b6060820152614ee260a08401614bfa565b6080820152614ef460c084013561483a565b60c083013560a0820152602082810191909152908452929092019160e001614e1f565b5080602084015250508085525050602083019250602081019050614d31565b5092505067ffffffffffffffff60208401351115614f5357600080fd5b614f638460208501358501614c20565b90509250929050565b600082601f830112614f7d57600080fd5b81356020614f8d61476a836146ee565b8083825260208201915060208460051b870101935086841115614faf57600080fd5b602086015b84811015614cad57614fc5816142a1565b8352918301918301614fb4565b60008060408385031215614fe557600080fd5b823567ffffffffffffffff80821115614ffd57600080fd5b61500986838701614f6c565b9350602085013591508082111561501f57600080fd5b5061502c85828601614f6c565b9150509250929050565b60008083601f84011261504857600080fd5b50813567ffffffffffffffff81111561506057600080fd5b6020830191508360208285010111156122bb57600080fd5b6000806000806040858703121561508e57600080fd5b843567ffffffffffffffff808211156150a657600080fd5b6150b288838901615036565b909650945060208701359150808211156150cb57600080fd5b506150d887828801615036565b95989497509550505050565b600080604083850312156150f757600080fd5b61510083614321565b9150614f63602084016142a1565b60006020828403121561512057600080fd5b813567ffffffffffffffff8082111561513857600080fd5b908301906040828603121561514c57600080fd5b6151546145e9565b82358281111561516357600080fd5b61516f87828601614f6c565b82525060208301358281111561518457600080fd5b61519087828601614f6c565b60208301525095945050505050565b80357fffffffff00000000000000000000000000000000000000000000000000000000811681146142c557600080fd5b600060208083850312156151e257600080fd5b823567ffffffffffffffff8111156151f957600080fd5b8301601f8101851361520a57600080fd5b803561521861476a826146ee565b818152610220918202830184019184820191908884111561523857600080fd5b938501935b8385101561482e57848903818112156152565760008081fd5b61525e6145e9565b61526787614321565b8152610200807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08401121561529c5760008081fd5b6152a4614658565b92506152b1898901614848565b835260406152c0818a01614c0e565b8a85015260606152d1818b01614bfa565b82860152608091506152e4828b01614bfa565b9085015260a06152f58a8201614bfa565b8286015260c09150615308828b01614c0e565b9085015260e06153198a8201614bfa565b82860152610100915061532d828b01614c0e565b9085015261012061533f8a8201614c0e565b828601526101409150615353828b01614c0e565b908501526101606153658a8201614bfa565b828601526101809150615379828b01614bfa565b908501526101a061538b8a8201614321565b828601526101c0915061539f828b01614bfa565b908501526101e06153b18a8201614848565b828601526153c0838b0161519f565b908501525050808801919091528352938401939185019161523d565b600060208083850312156153ef57600080fd5b823567ffffffffffffffff81111561540657600080fd5b8301601f8101851361541757600080fd5b803561542561476a826146ee565b81815260069190911b8201830190838101908783111561544457600080fd5b928401925b8284101561549657604084890312156154625760008081fd5b61546a6145e9565b615473856142a1565b8152615480868601614321565b8187015282526040939093019290840190615449565b979650505050505050565b6000806000806000608086880312156154b957600080fd5b6154c286614321565b94506154d0602087016142a1565b935060408601359250606086013567ffffffffffffffff8111156154f357600080fd5b6154ff88828901615036565b969995985093965092949392505050565b8381528215156020820152606060408201526000612eda606083018461442c565b6000806040838503121561554457600080fd5b61554d83614321565b9150602083013567ffffffffffffffff81111561556957600080fd5b830160a0818603121561557b57600080fd5b809150509250929050565b6000806040838503121561559957600080fd5b6155a2836142a1565b9150614f6360208401614321565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176112c3576112c36155b0565b60008261562c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261569457600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126156d357600080fd5b83018035915067ffffffffffffffff8211156156ee57600080fd5b6020019150368190038213156122bb57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261573857600080fd5b83018035915067ffffffffffffffff82111561575357600080fd5b6020019150600681901b36038213156122bb57600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146142c557600080fd5b6000604082840312156157a957600080fd5b6157b16145e9565b6157ba836142a1565b81526157c86020840161576b565b60208201529392505050565b6000604082840312156157e657600080fd5b6157ee6145e9565b6157ba83614321565b6000602080838503121561580a57600080fd5b823567ffffffffffffffff81111561582157600080fd5b8301601f8101851361583257600080fd5b803561584061476a826146ee565b8181526060918202830184019184820191908884111561585f57600080fd5b938501935b8385101561482e5780858a03121561587c5760008081fd5b61588461467c565b61588d866142a1565b815261589a87870161576b565b8782015260406158ab818801614bfa565b9082015283529384019391850191615864565b808201808211156112c3576112c36155b0565b818103818111156112c3576112c36155b0565b60ff81811683821601908111156112c3576112c36155b0565b60ff82811682821603908111156112c3576112c36155b0565b600181815b8085111561596f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615955576159556155b0565b8085161561596257918102915b93841c939080029061591b565b509250929050565b600082615986575060016112c3565b81615993575060006112c3565b81600181146159a957600281146159b3576159cf565b60019150506112c3565b60ff8411156159c4576159c46155b0565b50506001821b6112c3565b5060208310610133831016604e8410600b84101617156159f2575081810a6112c3565b6159fc8383615916565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615a2e57615a2e6155b0565b029392505050565b6000610b6960ff841683615977565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015614bf25760049490940360031b84901b1690921692915050565b60008085851115615a9b57600080fd5b83861115615aa857600080fd5b5050820193919092039150565b600060408284031215615ac757600080fd5b615acf6145e9565b8251815260208301516157c88161483a565b600060208284031215615af357600080fd5b5051919050565b805169ffffffffffffffffffff811681146142c557600080fd5b600080600080600060a08688031215615b2c57600080fd5b615b3586615afa565b9450602086015193506040860151925060608601519150615b5860808701615afa565b90509295509295909350565b600060208284031215615b7657600080fd5b8151610b6981614712565b600060408284031215615b9357600080fd5b615b9b6145e9565b615ba4836142a1565b8152602083013560208201528091505092915050565b63ffffffff818116838216019080821115614242576142426155b0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + Bin: "0x60e06040523480156200001157600080fd5b506040516200774438038062007744833981016040819052620000349162001834565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a5a565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b26565b5050505050505062001ae5565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001953565b60209081029190910101519050620002f560028262000e5f565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001953565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000e7f565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001953565b6020026020010151600b62000e7f60201b90919060201c565b1562000499578281815181106200045b576200045b62001953565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001953565b6020026020010151600b62000e9660201b90919060201c565b156200053b57818181518110620004fd57620004fd62001953565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001953565b6020908102919091018101518051818301516001600160a01b0380831660008181526007875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001953565b6020026020010151905060008383815181106200065f576200065f62001953565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061016081015163ffffffff16155b80620006ba57506101e08101516001600160e01b031916630a04b54b60e21b14155b80620006da5750806060015163ffffffff1681610160015163ffffffff16115b15620007055760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260096020526040812060010154600160881b900460e01b6001600160e01b03191690036200078557816001600160401b03167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb7248260405162000777919062001969565b60405180910390a2620007c9565b816001600160401b03167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab2082604051620007c0919062001969565b60405180910390a25b8060096000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a8154816001600160401b0302191690836001600160401b031602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000a7e5762000a7e62001953565b6020026020010151600001519050600083838151811062000aa35762000aa362001953565b6020908102919091018101518101516001600160a01b03841660008181526008845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a5d565b60005b825181101562000d9957600083828151811062000b4a5762000b4a62001953565b6020026020010151905060008160000151905060005b82602001515181101562000d8a5760008360200151828151811062000b895762000b8962001953565b602002602001015160200151905060008460200151838151811062000bb25762000bb262001953565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c115760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000d77908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000b60565b50505080600101905062000b29565b5060005b81518110156200054457600082828151811062000dbe5762000dbe62001953565b6020026020010151600001519050600083838151811062000de35762000de362001953565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000d9d565b600062000e76836001600160a01b03841662000ead565b90505b92915050565b600062000e76836001600160a01b03841662000fb1565b600062000e76836001600160a01b03841662001003565b6000818152600183016020526040812054801562000fa657600062000ed460018362001aad565b855490915060009062000eea9060019062001aad565b905081811462000f5657600086600001828154811062000f0e5762000f0e62001953565b906000526020600020015490508087600001848154811062000f345762000f3462001953565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f6a5762000f6a62001acf565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e79565b600091505062000e79565b600081815260018301602052604081205462000ffa5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e79565b50600062000e79565b6000818152600183016020526040812054801562000fa65760006200102a60018362001aad565b8554909150600090620010409060019062001aad565b905080821462000f5657600086600001828154811062000f0e5762000f0e62001953565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200109f576200109f62001064565b60405290565b60405160c081016001600160401b03811182821017156200109f576200109f62001064565b60405161020081016001600160401b03811182821017156200109f576200109f62001064565b604051601f8201601f191681016001600160401b03811182821017156200111b576200111b62001064565b604052919050565b80516001600160a01b03811681146200113b57600080fd5b919050565b805163ffffffff811681146200113b57600080fd5b6000606082840312156200116857600080fd5b604051606081016001600160401b03811182821017156200118d576200118d62001064565b604052825190915081906001600160601b0381168114620011ad57600080fd5b8152620011bd6020840162001123565b6020820152620011d06040840162001140565b60408201525092915050565b60006001600160401b03821115620011f857620011f862001064565b5060051b60200190565b600082601f8301126200121457600080fd5b815160206200122d6200122783620011dc565b620010f0565b8083825260208201915060208460051b8701019350868411156200125057600080fd5b602086015b848110156200127757620012698162001123565b835291830191830162001255565b509695505050505050565b600082601f8301126200129457600080fd5b81516020620012a76200122783620011dc565b82815260609283028501820192828201919087851115620012c757600080fd5b8387015b858110156200135a5780890382811215620012e65760008081fd5b620012f06200107a565b620012fb8362001123565b8152604080601f1984011215620013125760008081fd5b6200131c6200107a565b92506200132b88850162001123565b835283015160ff81168114620013415760008081fd5b82880152808701919091528452928401928101620012cb565b5090979650505050505050565b80516001600160401b03811681146200113b57600080fd5b805161ffff811681146200113b57600080fd5b805180151581146200113b57600080fd5b600082601f830112620013b557600080fd5b81516020620013c86200122783620011dc565b82815260059290921b84018101918181019086841115620013e857600080fd5b8286015b84811015620012775780516001600160401b03808211156200140d57600080fd5b908801906040601f19838c0381018213156200142857600080fd5b620014326200107a565b6200143f89860162001367565b815282850151848111156200145357600080fd5b8086019550508c603f8601126200146957600080fd5b8885015193506200147e6200122785620011dc565b84815260e09094028501830193898101908e8611156200149d57600080fd5b958401955b858710156200157657868f0360e0811215620014bd57600080fd5b620014c76200107a565b620014d28962001123565b815260c08683011215620014e557600080fd5b620014ef620010a5565b9150620014fe8d8a0162001140565b82526200150d878a0162001140565b8d8301526200151f60608a016200137f565b878301526200153160808a0162001140565b60608301526200154460a08a0162001140565b60808301526200155760c08a0162001392565b60a0830152808d0191909152825260e09690960195908a0190620014a2565b828b015250875250505092840192508301620013ec565b600082601f8301126200159f57600080fd5b81516020620015b26200122783620011dc565b82815260069290921b84018101918181019086841115620015d257600080fd5b8286015b84811015620012775760408189031215620015f15760008081fd5b620015fb6200107a565b620016068262001123565b81526200161585830162001367565b81860152835291830191604001620015d6565b80516001600160e01b0319811681146200113b57600080fd5b600082601f8301126200165357600080fd5b81516020620016666200122783620011dc565b82815261022092830285018201928282019190878511156200168757600080fd5b8387015b858110156200135a5780890382811215620016a65760008081fd5b620016b06200107a565b620016bb8362001367565b815261020080601f1984011215620016d35760008081fd5b620016dd620010ca565b9250620016ec88850162001392565b83526040620016fd8186016200137f565b8985015260606200171081870162001140565b82860152608091506200172582870162001140565b9085015260a06200173886820162001140565b8286015260c091506200174d8287016200137f565b9085015260e06200176086820162001140565b828601526101009150620017768287016200137f565b908501526101206200178a8682016200137f565b828601526101409150620017a08287016200137f565b90850152610160620017b486820162001140565b828601526101809150620017ca82870162001140565b908501526101a0620017de86820162001367565b828601526101c09150620017f482870162001140565b908501526101e06200180886820162001392565b828601526200181983870162001628565b9085015250508087019190915284529284019281016200168b565b6000806000806000806000610120888a0312156200185157600080fd5b6200185d898962001155565b60608901519097506001600160401b03808211156200187b57600080fd5b620018898b838c0162001202565b975060808a0151915080821115620018a057600080fd5b620018ae8b838c0162001202565b965060a08a0151915080821115620018c557600080fd5b620018d38b838c0162001282565b955060c08a0151915080821115620018ea57600080fd5b620018f88b838c01620013a3565b945060e08a01519150808211156200190f57600080fd5b6200191d8b838c016200158d565b93506101008a01519150808211156200193557600080fd5b50620019448a828b0162001641565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610200810160208301516200198a602084018261ffff169052565b506040830151620019a3604084018263ffffffff169052565b506060830151620019bc606084018263ffffffff169052565b506080830151620019d5608084018263ffffffff169052565b5060a0830151620019ec60a084018261ffff169052565b5060c083015162001a0560c084018263ffffffff169052565b5060e083015162001a1c60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501516001600160401b0316908401526101a080850151909116908301526101c0808401511515908301526101e0928301516001600160e01b031916929091019190915290565b8181038181111562000e7957634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051615c0562001b3f600039600081816102ef015281816121fd01526122660152600081816102b301528181611917015261197701526000818161027f015281816119a00152611a100152615c056000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c806379ba509711610104578063a69c64c0116100a2578063d02641a011610071578063d02641a014610a81578063d8694ccd14610a94578063f2fde38b14610aa7578063ffdb4b3714610aba57600080fd5b8063a69c64c014610997578063bf78e03f146109aa578063c4276bfc14610a57578063cdc73d5114610a7957600080fd5b806382b49eb0116100de57806382b49eb0146107d95780638da5cb5b1461094957806391a2749a146109715780639ea600261461098457600080fd5b806379ba5097146107ab5780637afac322146107b3578063805f2132146107c657600080fd5b8063407e1086116101715780634ab35b0b1161014b5780634ab35b0b14610441578063514e8cff146104815780636def4ce714610524578063770e2dc41461079857600080fd5b8063407e1086146103fb57806341ed29e71461040e57806345ac924d1461042157600080fd5b8063085318f8116101ad578063085318f814610368578063181f5a77146103885780632451a627146103d15780633937306f146103e657600080fd5b806241e5be146101d3578063061877e3146101f957806306285c6914610252575b600080fd5b6101e66101e13660046142bc565b610b02565b6040519081526020015b60405180910390f35b6102396102073660046142f8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101f0565b61031c604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101f0565b61037b610376366004614370565b610b70565b6040516101f09190614482565b6103c46040518060400160405280601381526020017f46656551756f74657220312e362e302d6465760000000000000000000000000081525081565b6040516101f09190614504565b6103d9610ee2565b6040516101f09190614517565b6103f96103f4366004614571565b610ef3565b005b6103f9610409366004614713565b6111a8565b6103f961041c366004614845565b6111bc565b61043461042f366004614980565b6111fe565b6040516101f091906149c2565b61045461044f3660046142f8565b6112c9565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b61051761048f366004614a3d565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101f09190614a58565b61078b610532366004614a3d565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101919091525067ffffffffffffffff908116600090815260096020908152604091829020825161020081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a085015271010000000000000000000000000000000000808404881660c086015275010000000000000000000000000000000000000000008404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b01000000000000000000000000000000000000000000000000000000909204861661014084015260019093015480861661016084015264010000000081049096166101808301526c0100000000000000000000000086049094166101a0820152700100000000000000000000000000000000850490911615156101c08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b166101e082015290565b6040516101f09190614a93565b6103f96107a6366004614caa565b6112d4565b6103f96112e6565b6103f96107c1366004614fc4565b6113e3565b6103f96107d436600461506a565b6113f5565b6108e96107e73660046150d6565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff919091166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101f09190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6103f961097f366004615100565b6118dd565b6103f96109923660046151c1565b6118ee565b6103f96109a53660046153ce565b6118ff565b610a236109b83660046142f8565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526007825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101f0565b610a6a610a65366004615493565b611910565b6040516101f093929190615502565b6103d9611b06565b610517610a8f3660046142f8565b611b12565b6101e6610aa2366004615523565b611c0e565b6103f9610ab53660046142f8565b612118565b610acd610ac8366004615578565b612129565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101f0565b6000610b0d826122b4565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b34856122b4565b610b5c907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16856155d1565b610b6691906155e8565b90505b9392505050565b67ffffffffffffffff8086166000908152600960205260409020600101546060917101000000000000000000000000000000000090910460e01b908590811115610bbc57610bbc6145ac565b604051908082528060200260200182016040528015610bef57816020015b6060815260200190600190039081610bda5790505b50915060005b85811015610ed7576000858583818110610c1157610c11615623565b610c2792602060409092020190810191506142f8565b90506000888884818110610c3d57610c3d615623565b9050602002810190610c4f9190615652565b610c5d906040810190615690565b9150506020811115610d125767ffffffffffffffff8a166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115610d12576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b610d82848a8a86818110610d2857610d28615623565b9050602002810190610d3a9190615652565b610d48906020810190615690565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061234e92505050565b67ffffffffffffffff8a166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320815160c081018352905463ffffffff8082168352640100000000820481168386015268010000000000000000820461ffff16838501526a01000000000000000000008204811660608401526e010000000000000000000000000000820481166080840152720100000000000000000000000000000000000090910460ff16151560a08301908152958552600990935290832054935190937b0100000000000000000000000000000000000000000000000000000090049091169190610e815781610e87565b82606001515b6040805163ffffffff8316602082015291925001604051602081830303815290604052888781518110610ebc57610ebc615623565b60200260200101819052505050505050806001019050610bf5565b505095945050505050565b6060610eee60026123a5565b905090565b610efb6123b2565b6000610f0782806156f5565b9050905060005b81811015611051576000610f2284806156f5565b83818110610f3257610f32615623565b905060400201803603810190610f489190615789565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600690975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926110409290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610f0e565b50600061106160208401846156f5565b9050905060005b818110156111a257600061107f60208601866156f5565b8381811061108f5761108f615623565b9050604002018036038101906110a591906157c6565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e926111919290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101611068565b50505050565b6111b06123f7565b6111b981612478565b50565b6111c46123f7565b60005b81518110156111fa576111f28282815181106111e5576111e5615623565b6020026020010151612576565b6001016111c7565b5050565b60608160008167ffffffffffffffff81111561121c5761121c6145ac565b60405190808252806020026020018201604052801561126157816020015b604080518082019091526000808252602082015281526020019060019003908161123a5790505b50905060005b828110156112be5761129986868381811061128457611284615623565b9050602002016020810190610a8f91906142f8565b8282815181106112ab576112ab615623565b6020908102919091010152600101611267565b509150505b92915050565b60006112c3826122b4565b6112dc6123f7565b6111fa8282612748565b60015473ffffffffffffffffffffffffffffffffffffffff163314611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610d09565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6113eb6123f7565b6111fa8282612b55565b600080600061143987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c9c92505050565b92509250925061144b33838584612cb7565b6000611459858701876157e9565b905060005b81518110156118d25760006007600084848151811061147f5761147f615623565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160009081205474010000000000000000000000000000000000000000900460ff169150819003611540578282815181106114e9576114e9615623565b6020908102919091010151516040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b600061158960128386868151811061155a5761155a615623565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612e0f565b9050600660008585815181106115a1576115a1615623565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff1684848151811061161357611613615623565b60200260200101516040015163ffffffff16101561171d5783838151811061163d5761163d615623565b60200260200101516000015184848151811061165b5761165b615623565b6020026020010151604001516006600087878151811061167d5761167d615623565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260409081016000205490517f191ec70600000000000000000000000000000000000000000000000000000000815293909116600484015263ffffffff91821660248401527c01000000000000000000000000000000000000000000000000000000009004166044820152606401610d09565b6040518060400160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260200185858151811061175e5761175e615623565b60200260200101516040015163ffffffff168152506006600086868151811061178957611789615623565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179055835184908490811061182157611821615623565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff167f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a8286868151811061187757611877615623565b6020026020010151604001516040516118c09291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a2505060010161145e565b505050505050505050565b6118e56123f7565b6111b981612ed5565b6118f66123f7565b6111b981613061565b6119076123f7565b6111b981613507565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036119705785925061199e565b61199b87877f0000000000000000000000000000000000000000000000000000000000000000610b02565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611a3d576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610d09565b67ffffffffffffffff881660009081526009602052604081206001015463ffffffff1690611a6c8787846135f1565b9050806020015193508484611af3836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b6060610eee600b6123a5565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600760209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff169082015290611c0557505073ffffffffffffffffffffffffffffffffffffffff166000908152600660209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b698161379a565b67ffffffffffffffff8083166000908152600960209081526040808320815161020081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a086015271010000000000000000000000000000000000808504881660c087015275010000000000000000000000000000000000000000008504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b01000000000000000000000000000000000000000000000000000000909304861661014085015260019094015480861661016085015264010000000081049098166101808401526c0100000000000000000000000088049094166101a0830152700100000000000000000000000000000000870490931615156101c08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b166101e0840152909190611e28576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b611e43611e3b60808501606086016142f8565b600b90613929565b611ea257611e5760808401606085016142f8565b6040517f2502348c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b6000611eb160408501856156f5565b9150611f0d905082611ec66020870187615690565b905083611ed38880615690565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061395892505050565b600080611f29611f2360808801606089016142f8565b88612129565b9092509050600080808515611f6c57611f60878b611f4d60808d0160608e016142f8565b88611f5b60408f018f6156f5565b613a02565b91945092509050611f8c565b6101a0870151611f899063ffffffff16662386f26fc100006155d1565b92505b61010087015160009061ffff1615611fd057611fcd886dffffffffffffffffffffffffffff607088901c16611fc460208e018e615690565b90508a86613cda565b90505b61018088015160009067ffffffffffffffff16611ff9611ff360808e018e615690565b8c613d8a565b600001518563ffffffff168b60a0015161ffff168e806020019061201d9190615690565b6120289291506155d1565b8c6080015163ffffffff1661203d91906158b0565b61204791906158b0565b61205191906158b0565b61206b906dffffffffffffffffffffffffffff89166155d1565b61207591906155d1565b9050867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168282600860008f60600160208101906120af91906142f8565b73ffffffffffffffffffffffffffffffffffffffff1681526020810191909152604001600020546120ea9067ffffffffffffffff16896155d1565b6120f491906158b0565b6120fe91906158b0565b61210891906155e8565b9c9b505050505050505050505050565b6121206123f7565b6111b981613e4b565b67ffffffffffffffff811660009081526005602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff16918101829052829182036121e1576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000816020015163ffffffff16426121f991906158c3565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff1681111561229a576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610d09565b6122a3866122b4565b9151919350909150505b9250929050565b6000806122c083611b12565b9050806020015163ffffffff16600014806122f8575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15612347576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610d09565b5192915050565b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016111fa576123a081613f40565b505050565b60606000610b6983613ff3565b6123bd600233613929565b6123f5576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610d09565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d09565b60005b81518110156111fa57600082828151811061249857612498615623565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526007875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a250505080600101905061247b565b600061262f82600001518360600151846020015185604001516040805173ffffffffffffffffffffffffffffffffffffffff80871660208301528516918101919091527fffffffffffffffffffff00000000000000000000000000000000000000000000831660608201527fffff0000000000000000000000000000000000000000000000000000000000008216608082015260009060a001604051602081830303815290604052805190602001209050949350505050565b60808301516000828152600460205260409081902080549215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316929092179091555190915081907f32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a39061273c908590600060a08201905073ffffffffffffffffffffffffffffffffffffffff8084511683527fffffffffffffffffffff0000000000000000000000000000000000000000000060208501511660208401527fffff00000000000000000000000000000000000000000000000000000000000060408501511660408401528060608501511660608401525060808301511515608083015292915050565b60405180910390a25050565b60005b8251811015612a7157600083828151811061276857612768615623565b6020026020010151905060008160000151905060005b826020015151811015612a63576000836020015182815181106127a3576127a3615623565b60200260200101516020015190506000846020015183815181106127c9576127c9615623565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101561284c5760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610d09565b67ffffffffffffffff84166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b590612a51908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010161277e565b50505080600101905061274b565b5060005b81518110156123a0576000828281518110612a9257612a92615623565b60200260200101516000015190506000838381518110612ab457612ab4615623565b60209081029190910181015181015167ffffffffffffffff84166000818152600a8452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612a75565b60005b8251811015612bf857612b8e838281518110612b7657612b76615623565b6020026020010151600b61404f90919063ffffffff16565b15612bf057828181518110612ba557612ba5615623565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b600101612b58565b5060005b81518110156123a057612c32828281518110612c1a57612c1a615623565b6020026020010151600b61407190919063ffffffff16565b15612c9457818181518110612c4957612c49615623565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101612bfc565b6040810151604a820151605e90920151909260609290921c91565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602080840191909152908616828401527fffffffffffffffffffff00000000000000000000000000000000000000000000851660608301527fffff00000000000000000000000000000000000000000000000000000000000084166080808401919091528351808403909101815260a09092018352815191810191909120600081815260049092529190205460ff16612e08576040517f097e17ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8087166004830152851660248201527fffffffffffffffffffff00000000000000000000000000000000000000000000841660448201527fffff00000000000000000000000000000000000000000000000000000000000083166064820152608401610d09565b5050505050565b600080612e1c84866158d6565b9050600060248260ff161115612e5357612e376024836158ef565b612e4290600a615a28565b612e4c90856155e8565b9050612e76565b612e5e8260246158ef565b612e6990600a615a28565b612e7390856155d1565b90505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612ecc576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b95945050505050565b602081015160005b8151811015612f70576000828281518110612efa57612efa615623565b60200260200101519050612f1881600261409390919063ffffffff16565b15612f675760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612edd565b50815160005b81518110156111a2576000828281518110612f9357612f93615623565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613003576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61300e60028261404f565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101612f76565b60005b81518110156111fa57600082828151811061308157613081615623565b60200260200101519050600083838151811061309f5761309f615623565b60200260200101516000015190506000826020015190508167ffffffffffffffff16600014806130d8575061016081015163ffffffff16155b8061312a57506101e08101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806131495750806060015163ffffffff1681610160015163ffffffff16115b1561318c576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610d09565b67ffffffffffffffff821660009081526009602052604081206001015471010000000000000000000000000000000000900460e01b7fffffffff00000000000000000000000000000000000000000000000000000000169003613230578167ffffffffffffffff167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb724826040516132239190614a93565b60405180910390a2613273565b8167ffffffffffffffff167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab208260405161326a9190614a93565b60405180910390a25b80600960008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050613064565b60005b81518110156111fa57600082828151811061352757613527615623565b6020026020010151600001519050600083838151811061354957613549615623565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526008845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010161350a565b6040805180820190915260008082526020820152600083900361363257506040805180820190915267ffffffffffffffff8216815260006020820152610b69565b600061363e8486615a37565b9050600061364f8560048189615a7d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f000000000000000000000000000000000000000000000000000000000016136ec57808060200190518101906136e39190615aa7565b92505050610b69565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601613768576040518060400160405280828060200190518101906137549190615ad3565b815260006020909101529250610b69915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613804573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138289190615b06565b5050509150506000811215613869576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006138e88373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156138b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138dd9190615b56565b866020015184612e0f565b604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff4216602082015295945050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b69565b836040015163ffffffff168311156139b15760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610d09565b836020015161ffff168211156139f3576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111a2846101e001518261234e565b6000808083815b81811015613ccc576000878783818110613a2557613a25615623565b905060400201803603810190613a3b9190615b73565b67ffffffffffffffff8c166000908152600a60209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090613b5b576101208d0151613b289061ffff16662386f26fc100006155d1565b613b3290886158b0565b96508c610140015186613b459190615bac565b9550613b52602086615bac565b94505050613cc4565b604081015160009061ffff1615613c145760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614613bb7578351613bb0906122b4565b9050613bba565b508a5b620186a0836040015161ffff16613bfc8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166140b590919063ffffffff16565b613c0691906155d1565b613c1091906155e8565b9150505b6060820151613c239088615bac565b9650816080015186613c359190615bac565b8251909650600090613c549063ffffffff16662386f26fc100006155d1565b905080821015613c7357613c68818a6158b0565b985050505050613cc4565b6000836020015163ffffffff16662386f26fc10000613c9291906155d1565b905080831115613cb257613ca6818b6158b0565b99505050505050613cc4565b613cbc838b6158b0565b995050505050505b600101613a09565b505096509650969350505050565b60008063ffffffff8316613cf0610160866155d1565b613cfc876101c06158b0565b613d0691906158b0565b613d1091906158b0565b905060008760c0015163ffffffff168860e0015161ffff1683613d3391906155d1565b613d3d91906158b0565b61010089015190915061ffff16613d646dffffffffffffffffffffffffffff8916836155d1565b613d6e91906155d1565b613d7e90655af3107a40006155d1565b98975050505050505050565b60408051808201909152600080825260208201526000613db6858585610160015163ffffffff166135f1565b9050826060015163ffffffff1681600001511115613e00576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101c001518015613e1457508060200151155b15610b66576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603613eca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d09565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008151602014613f7f57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614504565b600082806020019051810190613f959190615ad3565b905073ffffffffffffffffffffffffffffffffffffffff811180613fba575061040081105b156112c357826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614504565b60608160000180548060200260200160405190810160405280929190818152602001828054801561404357602002820191906000526020600020905b81548152602001906001019080831161402f575b50505050509050919050565b6000610b698373ffffffffffffffffffffffffffffffffffffffff84166140f2565b6000610b698373ffffffffffffffffffffffffffffffffffffffff8416614141565b6000610b698373ffffffffffffffffffffffffffffffffffffffff841661423b565b6000670de0b6b3a76400006140e8837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166155d1565b610b6991906155e8565b6000818152600183016020526040812054614139575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112c3565b5060006112c3565b6000818152600183016020526040812054801561422a5760006141656001836158c3565b8554909150600090614179906001906158c3565b90508082146141de57600086600001828154811061419957614199615623565b90600052602060002001549050808760000184815481106141bc576141bc615623565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806141ef576141ef615bc9565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112c3565b60009150506112c3565b5092915050565b6000818152600183016020526040812054801561422a57600061425f6001836158c3565b8554909150600090614273906001906158c3565b90508181146141de57600086600001828154811061419957614199615623565b803573ffffffffffffffffffffffffffffffffffffffff811681146142b757600080fd5b919050565b6000806000606084860312156142d157600080fd5b6142da84614293565b9250602084013591506142ef60408501614293565b90509250925092565b60006020828403121561430a57600080fd5b610b6982614293565b803567ffffffffffffffff811681146142b757600080fd5b60008083601f84011261433d57600080fd5b50813567ffffffffffffffff81111561435557600080fd5b6020830191508360208260051b85010111156122ad57600080fd5b60008060008060006060868803121561438857600080fd5b61439186614313565b9450602086013567ffffffffffffffff808211156143ae57600080fd5b6143ba89838a0161432b565b909650945060408801359150808211156143d357600080fd5b818801915088601f8301126143e757600080fd5b8135818111156143f657600080fd5b8960208260061b850101111561440b57600080fd5b9699959850939650602001949392505050565b6000815180845260005b8181101561444457602081850181015186830182015201614428565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156144f7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526144e585835161441e565b945092850192908501906001016144ab565b5092979650505050505050565b602081526000610b69602083018461441e565b6020808252825182820181905260009190848201906040850190845b8181101561456557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614533565b50909695505050505050565b60006020828403121561458357600080fd5b813567ffffffffffffffff81111561459a57600080fd5b820160408185031215610b6957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156145fe576145fe6145ac565b60405290565b60405160a0810167ffffffffffffffff811182821017156145fe576145fe6145ac565b60405160c0810167ffffffffffffffff811182821017156145fe576145fe6145ac565b604051610200810167ffffffffffffffff811182821017156145fe576145fe6145ac565b6040516060810167ffffffffffffffff811182821017156145fe576145fe6145ac565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156146d8576146d86145ac565b604052919050565b600067ffffffffffffffff8211156146fa576146fa6145ac565b5060051b60200190565b60ff811681146111b957600080fd5b6000602080838503121561472657600080fd5b823567ffffffffffffffff81111561473d57600080fd5b8301601f8101851361474e57600080fd5b803561476161475c826146e0565b614691565b8181526060918202830184019184820191908884111561478057600080fd5b938501935b83851015614820578489038181121561479e5760008081fd5b6147a66145db565b6147af87614293565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147e35760008081fd5b6147eb6145db565b92506147f8898901614293565b835287013561480681614704565b828901528088019190915283529384019391850191614785565b50979650505050505050565b80151581146111b957600080fd5b80356142b78161482c565b6000602080838503121561485857600080fd5b823567ffffffffffffffff81111561486f57600080fd5b8301601f8101851361488057600080fd5b803561488e61475c826146e0565b81815260a091820283018401918482019190888411156148ad57600080fd5b938501935b838510156148205780858a0312156148ca5760008081fd5b6148d2614604565b6148db86614293565b8152868601357fffffffffffffffffffff00000000000000000000000000000000000000000000811681146149105760008081fd5b818801526040868101357fffff000000000000000000000000000000000000000000000000000000000000811681146149495760008081fd5b90820152606061495a878201614293565b9082015260808681013561496d8161482c565b90820152835293840193918501916148b2565b6000806020838503121561499357600080fd5b823567ffffffffffffffff8111156149aa57600080fd5b6149b68582860161432b565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b82811015614a3057614a2084835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b92840192908501906001016149df565b5091979650505050505050565b600060208284031215614a4f57600080fd5b610b6982614313565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff1690820152604081016112c3565b81511515815261020081016020830151614ab3602084018261ffff169052565b506040830151614acb604084018263ffffffff169052565b506060830151614ae3606084018263ffffffff169052565b506080830151614afb608084018263ffffffff169052565b5060a0830151614b1160a084018261ffff169052565b5060c0830151614b2960c084018263ffffffff169052565b5060e0830151614b3f60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff90811691840191909152610160808501518216908401526101808085015167ffffffffffffffff16908401526101a080850151909116908301526101c0808401511515908301526101e0808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff811681146142b757600080fd5b803561ffff811681146142b757600080fd5b600082601f830112614c2357600080fd5b81356020614c3361475c836146e0565b82815260069290921b84018101918181019086841115614c5257600080fd5b8286015b84811015614c9f5760408189031215614c6f5760008081fd5b614c776145db565b614c8082614313565b8152614c8d858301614293565b81860152835291830191604001614c56565b509695505050505050565b60008060408385031215614cbd57600080fd5b67ffffffffffffffff83351115614cd357600080fd5b83601f843585010112614ce557600080fd5b614cf561475c84358501356146e0565b8335840180358083526020808401939260059290921b90910101861015614d1b57600080fd5b602085358601015b85358601803560051b01602001811015614f285767ffffffffffffffff81351115614d4d57600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a03011215614d8657600080fd5b614d8e6145db565b614d9a60208301614313565b815267ffffffffffffffff60408301351115614db557600080fd5b88603f604084013584010112614dca57600080fd5b614de061475c60206040850135850101356146e0565b6020604084810135850182810135808552928401939260e00201018b1015614e0757600080fd5b6040808501358501015b6040858101358601602081013560e0020101811015614f095760e0818d031215614e3a57600080fd5b614e426145db565b614e4b82614293565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215614e7f57600080fd5b614e87614627565b614e9360208401614bec565b8152614ea160408401614bec565b6020820152614eb260608401614c00565b6040820152614ec360808401614bec565b6060820152614ed460a08401614bec565b6080820152614ee660c084013561482c565b60c083013560a0820152602082810191909152908452929092019160e001614e11565b5080602084015250508085525050602083019250602081019050614d23565b5092505067ffffffffffffffff60208401351115614f4557600080fd5b614f558460208501358501614c12565b90509250929050565b600082601f830112614f6f57600080fd5b81356020614f7f61475c836146e0565b8083825260208201915060208460051b870101935086841115614fa157600080fd5b602086015b84811015614c9f57614fb781614293565b8352918301918301614fa6565b60008060408385031215614fd757600080fd5b823567ffffffffffffffff80821115614fef57600080fd5b614ffb86838701614f5e565b9350602085013591508082111561501157600080fd5b5061501e85828601614f5e565b9150509250929050565b60008083601f84011261503a57600080fd5b50813567ffffffffffffffff81111561505257600080fd5b6020830191508360208285010111156122ad57600080fd5b6000806000806040858703121561508057600080fd5b843567ffffffffffffffff8082111561509857600080fd5b6150a488838901615028565b909650945060208701359150808211156150bd57600080fd5b506150ca87828801615028565b95989497509550505050565b600080604083850312156150e957600080fd5b6150f283614313565b9150614f5560208401614293565b60006020828403121561511257600080fd5b813567ffffffffffffffff8082111561512a57600080fd5b908301906040828603121561513e57600080fd5b6151466145db565b82358281111561515557600080fd5b61516187828601614f5e565b82525060208301358281111561517657600080fd5b61518287828601614f5e565b60208301525095945050505050565b80357fffffffff00000000000000000000000000000000000000000000000000000000811681146142b757600080fd5b600060208083850312156151d457600080fd5b823567ffffffffffffffff8111156151eb57600080fd5b8301601f810185136151fc57600080fd5b803561520a61475c826146e0565b818152610220918202830184019184820191908884111561522a57600080fd5b938501935b8385101561482057848903818112156152485760008081fd5b6152506145db565b61525987614313565b8152610200807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08401121561528e5760008081fd5b61529661464a565b92506152a389890161483a565b835260406152b2818a01614c00565b8a85015260606152c3818b01614bec565b82860152608091506152d6828b01614bec565b9085015260a06152e78a8201614bec565b8286015260c091506152fa828b01614c00565b9085015260e061530b8a8201614bec565b82860152610100915061531f828b01614c00565b908501526101206153318a8201614c00565b828601526101409150615345828b01614c00565b908501526101606153578a8201614bec565b82860152610180915061536b828b01614bec565b908501526101a061537d8a8201614313565b828601526101c09150615391828b01614bec565b908501526101e06153a38a820161483a565b828601526153b2838b01615191565b908501525050808801919091528352938401939185019161522f565b600060208083850312156153e157600080fd5b823567ffffffffffffffff8111156153f857600080fd5b8301601f8101851361540957600080fd5b803561541761475c826146e0565b81815260069190911b8201830190838101908783111561543657600080fd5b928401925b8284101561548857604084890312156154545760008081fd5b61545c6145db565b61546585614293565b8152615472868601614313565b818701528252604093909301929084019061543b565b979650505050505050565b6000806000806000608086880312156154ab57600080fd5b6154b486614313565b94506154c260208701614293565b935060408601359250606086013567ffffffffffffffff8111156154e557600080fd5b6154f188828901615028565b969995985093965092949392505050565b8381528215156020820152606060408201526000612ecc606083018461441e565b6000806040838503121561553657600080fd5b61553f83614313565b9150602083013567ffffffffffffffff81111561555b57600080fd5b830160a0818603121561556d57600080fd5b809150509250929050565b6000806040838503121561558b57600080fd5b61559483614293565b9150614f5560208401614313565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176112c3576112c36155a2565b60008261561e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261568657600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126156c557600080fd5b83018035915067ffffffffffffffff8211156156e057600080fd5b6020019150368190038213156122ad57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261572a57600080fd5b83018035915067ffffffffffffffff82111561574557600080fd5b6020019150600681901b36038213156122ad57600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146142b757600080fd5b60006040828403121561579b57600080fd5b6157a36145db565b6157ac83614293565b81526157ba6020840161575d565b60208201529392505050565b6000604082840312156157d857600080fd5b6157e06145db565b6157ac83614313565b600060208083850312156157fc57600080fd5b823567ffffffffffffffff81111561581357600080fd5b8301601f8101851361582457600080fd5b803561583261475c826146e0565b8181526060918202830184019184820191908884111561585157600080fd5b938501935b838510156148205780858a03121561586e5760008081fd5b61587661466e565b61587f86614293565b815261588c87870161575d565b87820152604061589d818801614bec565b9082015283529384019391850191615856565b808201808211156112c3576112c36155a2565b818103818111156112c3576112c36155a2565b60ff81811683821601908111156112c3576112c36155a2565b60ff82811682821603908111156112c3576112c36155a2565b600181815b8085111561596157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615947576159476155a2565b8085161561595457918102915b93841c939080029061590d565b509250929050565b600082615978575060016112c3565b81615985575060006112c3565b816001811461599b57600281146159a5576159c1565b60019150506112c3565b60ff8411156159b6576159b66155a2565b50506001821b6112c3565b5060208310610133831016604e8410600b84101617156159e4575081810a6112c3565b6159ee8383615908565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615a2057615a206155a2565b029392505050565b6000610b6960ff841683615969565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015614be45760049490940360031b84901b1690921692915050565b60008085851115615a8d57600080fd5b83861115615a9a57600080fd5b5050820193919092039150565b600060408284031215615ab957600080fd5b615ac16145db565b8251815260208301516157ba8161482c565b600060208284031215615ae557600080fd5b5051919050565b805169ffffffffffffffffffff811681146142b757600080fd5b600080600080600060a08688031215615b1e57600080fd5b615b2786615aec565b9450602086015193506040860151925060608601519150615b4a60808701615aec565b90509295509295909350565b600060208284031215615b6857600080fd5b8151610b6981614704565b600060408284031215615b8557600080fd5b615b8d6145db565b615b9683614293565b8152602083013560208201528091505092915050565b63ffffffff818116838216019080821115614234576142346155a2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var FeeQuoterABI = FeeQuoterMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/multi_ocr3_helper/multi_ocr3_helper.go b/core/gethwrappers/ccip/generated/multi_ocr3_helper/multi_ocr3_helper.go index d51e398b43..285aaaa338 100644 --- a/core/gethwrappers/ccip/generated/multi_ocr3_helper/multi_ocr3_helper.go +++ b/core/gethwrappers/ccip/generated/multi_ocr3_helper/multi_ocr3_helper.go @@ -59,7 +59,7 @@ type MultiOCR3BaseOracle struct { var MultiOCR3HelperMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"AfterConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"oracleAddress\",\"type\":\"address\"}],\"name\":\"getOracle\",\"outputs\":[{\"components\":[{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"enumMultiOCR3Base.Role\",\"name\":\"role\",\"type\":\"uint8\"}],\"internalType\":\"structMultiOCR3Base.Oracle\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"setTransmitOcrPluginType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmitWithSignatures\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"transmitWithoutSignatures\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000a9565b5050466080525062000154565b336001600160a01b03821603620001035760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b608051611db66200017760003960008181610efc0152610f480152611db66000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80637ac0aa1a11610076578063c673e5841161005b578063c673e584146101c5578063f2fde38b146101e5578063f716f99f146101f857600080fd5b80637ac0aa1a1461015b5780638da5cb5b1461019d57600080fd5b806334a9c92e116100a757806334a9c92e1461012057806344e65e551461014057806379ba50971461015357600080fd5b8063181f5a77146100c357806326bf9d261461010b575b600080fd5b604080518082018252601981527f4d756c74694f4352334261736548656c70657220312e302e300000000000000060208201529051610102919061153c565b60405180910390f35b61011e610119366004611603565b61020b565b005b61013361012e366004611691565b61023a565b60405161010291906116f3565b61011e61014e366004611766565b6102ca565b61011e61034d565b61011e610169366004611819565b600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610102565b6101d86101d3366004611819565b61044f565b604051610102919061188d565b61011e6101f3366004611920565b6105c7565b61011e610206366004611a8c565b6105db565b604080516000808252602082019092526004549091506102349060ff168585858580600061061d565b50505050565b6040805180820182526000808252602080830182905260ff86811683526003825284832073ffffffffffffffffffffffffffffffffffffffff871684528252918490208451808601909552805480841686529394939092918401916101009091041660028111156102ad576102ad6116c4565b60028111156102be576102be6116c4565b90525090505b92915050565b60045460408051602080880282810182019093528782526103439360ff16928c928c928c928c918c91829185019084908082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b9182918501908490808284376000920191909152508a925061061d915050565b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104926040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c08201529485529182018054845181840281018401909552808552929385830193909283018282801561054857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161051d575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156105b757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161058c575b5050505050815250509050919050565b6105cf6109a1565b6105d881610a24565b50565b6105e36109a1565b60005b81518110156106195761061182828151811061060457610604611bf5565b6020026020010151610b19565b6001016105e6565b5050565b60ff8781166000908152600260209081526040808320815160808101835281548152600190910154808616938201939093526101008304851691810191909152620100009091049092161515606083015287359061067c8760a4611c53565b90508260600151156106c4578451610695906020611c66565b86516106a2906020611c66565b6106ad9060a0611c53565b6106b79190611c53565b6106c19082611c53565b90505b368114610706576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016103ca565b508151811461074e5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016103ca565b610756610ef9565b60ff808a16600090815260036020908152604080832033845282528083208151808301909252805480861683529394919390928401916101009091041660028111156107a4576107a46116c4565b60028111156107b5576107b56116c4565b90525090506002816020015160028111156107d2576107d26116c4565b1480156108335750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff168154811061080e5761080e611bf5565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b610869576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5081606001511561094b576020820151610884906001611c7d565b60ff168551146108c0576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83518551146108fb576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000878760405161090d929190611c96565b604051908190038120610924918b90602001611ca6565b6040516020818303038152906040528051906020012090506109498a82888888610f7a565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103ca565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103ca565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff16600003610b5d5760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611cba565b60208082015160ff80821660009081526002909352604083206001810154929390928392169003610bca57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055610c1f565b6060840151600182015460ff6201000090910416151590151514610c1f576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016103ca565b60a08401518051601f60ff82161115610c675760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611cba565b610cda8585600301805480602002602001604051908101604052809291908181526020018280548015610cd057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ca5575b50505050506111b2565b856060015115610e4857610d558585600201805480602002602001604051908101604052809291908181526020018280548015610cd05760200282019190600052602060002090815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ca55750505050506111b2565b60808601518051610d6f906002870190602084019061147e565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f1015610de85760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611cba565b6040880151610df8906003611cd4565b60ff168160ff1611610e395760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611cba565b610e458783600161124a565b50505b610e548583600261124a565b8151610e69906003860190602085019061147e565b506040868101516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f54793610ee0938a939260028b01929190611cf7565b60405180910390a1610ef185611445565b505050505050565b467f000000000000000000000000000000000000000000000000000000000000000014610a22576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016103ca565b610f82611508565b835160005b81811015610343576000600188868460208110610fa657610fa6611bf5565b610fb391901a601b611c7d565b898581518110610fc557610fc5611bf5565b6020026020010151898681518110610fdf57610fdf611bf5565b60200260200101516040516000815260200160405260405161101d949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561103f573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015160ff808e1660009081526003602090815285822073ffffffffffffffffffffffffffffffffffffffff8516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156110cb576110cb6116c4565b60028111156110dc576110dc6116c4565b90525090506001816020015160028111156110f9576110f96116c4565b14611130576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061114757611147611bf5565b602002015115611183576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061119e5761119e611bf5565b911515602090920201525050600101610f87565b60005b81518110156112455760ff8316600090815260036020526040812083519091908490849081106111e7576111e7611bf5565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556001016111b5565b505050565b60005b82518160ff161015610234576000838260ff168151811061127057611270611bf5565b602002602001015190506000600281111561128d5761128d6116c4565b60ff808716600090815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915290205461010090041660028111156112d9576112d96116c4565b146113135760046040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611cba565b73ffffffffffffffffffffffffffffffffffffffff8116611360576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff168152602001846002811115611386576113866116c4565b905260ff808716600090815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282529091208351815493167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00841681178255918401519092909183917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561142b5761142b6116c4565b0217905550905050508061143e90611d8a565b905061124d565b60405160ff821681527f897ac1b2c12867721b284f3eb147bd4ab046d4eef1cf31c1d8988bfcfb962b539060200160405180910390a150565b8280548282559060005260206000209081019282156114f8579160200282015b828111156114f857825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061149e565b50611504929150611527565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b808211156115045760008155600101611528565b60006020808352835180602085015260005b8181101561156a5785810183015185820160400152820161154e565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b80606081018310156102c457600080fd5b60008083601f8401126115cc57600080fd5b50813567ffffffffffffffff8111156115e457600080fd5b6020830191508360208285010111156115fc57600080fd5b9250929050565b60008060006080848603121561161857600080fd5b61162285856115a9565b9250606084013567ffffffffffffffff81111561163e57600080fd5b61164a868287016115ba565b9497909650939450505050565b803560ff8116811461166857600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461166857600080fd5b600080604083850312156116a457600080fd5b6116ad83611657565b91506116bb6020840161166d565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b815160ff1681526020820151604082019060038110611714576117146116c4565b8060208401525092915050565b60008083601f84011261173357600080fd5b50813567ffffffffffffffff81111561174b57600080fd5b6020830191508360208260051b85010111156115fc57600080fd5b60008060008060008060008060e0898b03121561178257600080fd5b61178c8a8a6115a9565b9750606089013567ffffffffffffffff808211156117a957600080fd5b6117b58c838d016115ba565b909950975060808b01359150808211156117ce57600080fd5b6117da8c838d01611721565b909750955060a08b01359150808211156117f357600080fd5b506118008b828c01611721565b999c989b50969995989497949560c00135949350505050565b60006020828403121561182b57600080fd5b61183482611657565b9392505050565b60008151808452602080850194506020840160005b8381101561188257815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101611850565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a08401526118dc60e084018261183b565b905060408401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160c0850152611917828261183b565b95945050505050565b60006020828403121561193257600080fd5b6118348261166d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff8111828210171561198d5761198d61193b565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156119da576119da61193b565b604052919050565b600067ffffffffffffffff8211156119fc576119fc61193b565b5060051b60200190565b8035801515811461166857600080fd5b600082601f830112611a2757600080fd5b81356020611a3c611a37836119e2565b611993565b8083825260208201915060208460051b870101935086841115611a5e57600080fd5b602086015b84811015611a8157611a748161166d565b8352918301918301611a63565b509695505050505050565b60006020808385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b8135611ad9611a37826119e2565b81815260059190911b83018401908481019088831115611af857600080fd5b8585015b83811015611be857803585811115611b1357600080fd5b860160c0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215611b485760008081fd5b611b5061196a565b8882013581526040611b63818401611657565b8a8301526060611b74818501611657565b8284015260809150611b87828501611a06565b9083015260a08381013589811115611b9f5760008081fd5b611bad8f8d83880101611a16565b838501525060c0840135915088821115611bc75760008081fd5b611bd58e8c84870101611a16565b9083015250845250918601918601611afc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156102c4576102c4611c24565b80820281158282048414176102c4576102c4611c24565b60ff81811683821601908111156102c4576102c4611c24565b8183823760009101908152919050565b828152606082602083013760800192915050565b6020810160058310611cce57611cce6116c4565b91905290565b60ff8181168382160290811690818114611cf057611cf0611c24565b5092915050565b600060a0820160ff88168352602087602085015260a0604085015281875480845260c086019150886000526020600020935060005b81811015611d5e57845473ffffffffffffffffffffffffffffffffffffffff1683526001948501949284019201611d2c565b50508481036060860152611d72818861183b565b935050505060ff831660808301529695505050505050565b600060ff821660ff8103611da057611da0611c24565b6001019291505056fea164736f6c6343000818000a", + Bin: "0x60a06040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000a9565b5050466080525062000154565b336001600160a01b03821603620001035760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b608051611d386200017760003960008181610ef00152610f3c0152611d386000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80637ac0aa1a11610076578063c673e5841161005b578063c673e584146101c5578063f2fde38b146101e5578063f716f99f146101f857600080fd5b80637ac0aa1a1461015b5780638da5cb5b1461019d57600080fd5b806334a9c92e116100a757806334a9c92e1461012057806344e65e551461014057806379ba50971461015357600080fd5b8063181f5a77146100c357806326bf9d261461010b575b600080fd5b604080518082018252601981527f4d756c74694f4352334261736548656c70657220312e302e30000000000000006020820152905161010291906114dd565b60405180910390f35b61011e6101193660046115a4565b61020b565b005b61013361012e366004611632565b61023a565b6040516101029190611694565b61011e61014e366004611707565b6102ca565b61011e61034d565b61011e6101693660046117ba565b600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610102565b6101d86101d33660046117ba565b61044f565b604051610102919061182e565b61011e6101f33660046118c1565b6105c7565b61011e610206366004611a2d565b6105db565b604080516000808252602082019092526004549091506102349060ff168585858580600061061d565b50505050565b6040805180820182526000808252602080830182905260ff86811683526003825284832073ffffffffffffffffffffffffffffffffffffffff871684528252918490208451808601909552805480841686529394939092918401916101009091041660028111156102ad576102ad611665565b60028111156102be576102be611665565b90525090505b92915050565b60045460408051602080880282810182019093528782526103439360ff16928c928c928c928c918c91829185019084908082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b9182918501908490808284376000920191909152508a925061061d915050565b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104926040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c08201529485529182018054845181840281018401909552808552929385830193909283018282801561054857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161051d575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156105b757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161058c575b5050505050815250509050919050565b6105cf6109a1565b6105d881610a24565b50565b6105e36109a1565b60005b81518110156106195761061182828151811061060457610604611b96565b6020026020010151610b19565b6001016105e6565b5050565b60ff8781166000908152600260209081526040808320815160808101835281548152600190910154808616938201939093526101008304851691810191909152620100009091049092161515606083015287359061067c8760a4611bf4565b90508260600151156106c4578451610695906020611c07565b86516106a2906020611c07565b6106ad9060a0611bf4565b6106b79190611bf4565b6106c19082611bf4565b90505b368114610706576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016103ca565b508151811461074e5781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016103ca565b610756610eed565b60ff808a16600090815260036020908152604080832033845282528083208151808301909252805480861683529394919390928401916101009091041660028111156107a4576107a4611665565b60028111156107b5576107b5611665565b90525090506002816020015160028111156107d2576107d2611665565b1480156108335750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff168154811061080e5761080e611b96565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b610869576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5081606001511561094b576020820151610884906001611c1e565b60ff168551146108c0576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83518551146108fb576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000878760405161090d929190611c37565b604051908190038120610924918b90602001611c47565b6040516020818303038152906040528051906020012090506109498a82888888610f6e565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103ca565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610aa3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103ca565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff16600003610b5d5760006040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611c5b565b60208082015160ff80821660009081526002909352604083206001810154929390928392169003610bca57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055610c1f565b6060840151600182015460ff6201000090910416151590151514610c1f576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016103ca565b60a084015180516101001015610c645760016040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611c5b565b610cd78484600301805480602002602001604051908101604052809291908181526020018280548015610ccd57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ca2575b505050505061117e565b846060015115610e3d57610d528484600201805480602002602001604051908101604052809291908181526020018280548015610ccd5760200282019190600052602060002090815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ca257505050505061117e565b608085015180516101001015610d975760026040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611c5b565b6040860151610da7906003611c75565b60ff16815111610de65760036040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611c5b565b80516001840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841602179055610e2e906002860190602084019061143e565b50610e3b85826001611216565b505b610e4984826002611216565b8051610e5e906003850190602084019061143e565b506040858101516001840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff8316179055865180855560a088015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f54793610ed59389939260028a01929190611c98565b60405180910390a1610ee684611405565b5050505050565b467f000000000000000000000000000000000000000000000000000000000000000014610a22576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016103ca565b8251600090815b81811015610343576000600188868460208110610f9457610f94611b96565b610fa191901a601b611c1e565b898581518110610fb357610fb3611b96565b6020026020010151898681518110610fcd57610fcd611b96565b60200260200101516040516000815260200160405260405161100b949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561102d573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015160ff808e1660009081526003602090815285822073ffffffffffffffffffffffffffffffffffffffff8516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156110b9576110b9611665565b60028111156110ca576110ca611665565b90525090506001816020015160028111156110e7576110e7611665565b1461111e576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600160ff9091161b851615611161576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000015160ff166001901b851794505050806001019050610f75565b60005b81518110156112115760ff8316600090815260036020526040812083519091908490849081106111b3576111b3611b96565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055600101611181565b505050565b60005b825181101561023457600083828151811061123657611236611b96565b602002602001015190506000600281111561125357611253611665565b60ff808716600090815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900416600281111561129f5761129f611665565b146112d95760046040517f367f56a20000000000000000000000000000000000000000000000000000000081526004016103ca9190611c5b565b73ffffffffffffffffffffffffffffffffffffffff8116611326576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff16815260200184600281111561134c5761134c611665565b905260ff808716600090815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282529091208351815493167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00841681178255918401519092909183917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156113f1576113f1611665565b021790555090505050806001019050611219565b60405160ff821681527f897ac1b2c12867721b284f3eb147bd4ab046d4eef1cf31c1d8988bfcfb962b539060200160405180910390a150565b8280548282559060005260206000209081019282156114b8579160200282015b828111156114b857825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061145e565b506114c49291506114c8565b5090565b5b808211156114c457600081556001016114c9565b60006020808352835180602085015260005b8181101561150b578581018301518582016040015282016114ef565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b80606081018310156102c457600080fd5b60008083601f84011261156d57600080fd5b50813567ffffffffffffffff81111561158557600080fd5b60208301915083602082850101111561159d57600080fd5b9250929050565b6000806000608084860312156115b957600080fd5b6115c3858561154a565b9250606084013567ffffffffffffffff8111156115df57600080fd5b6115eb8682870161155b565b9497909650939450505050565b803560ff8116811461160957600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461160957600080fd5b6000806040838503121561164557600080fd5b61164e836115f8565b915061165c6020840161160e565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b815160ff16815260208201516040820190600381106116b5576116b5611665565b8060208401525092915050565b60008083601f8401126116d457600080fd5b50813567ffffffffffffffff8111156116ec57600080fd5b6020830191508360208260051b850101111561159d57600080fd5b60008060008060008060008060e0898b03121561172357600080fd5b61172d8a8a61154a565b9750606089013567ffffffffffffffff8082111561174a57600080fd5b6117568c838d0161155b565b909950975060808b013591508082111561176f57600080fd5b61177b8c838d016116c2565b909750955060a08b013591508082111561179457600080fd5b506117a18b828c016116c2565b999c989b50969995989497949560c00135949350505050565b6000602082840312156117cc57600080fd5b6117d5826115f8565b9392505050565b60008151808452602080850194506020840160005b8381101561182357815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016117f1565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a084015261187d60e08401826117dc565b905060408401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160c08501526118b882826117dc565b95945050505050565b6000602082840312156118d357600080fd5b6117d58261160e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff8111828210171561192e5761192e6118dc565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561197b5761197b6118dc565b604052919050565b600067ffffffffffffffff82111561199d5761199d6118dc565b5060051b60200190565b8035801515811461160957600080fd5b600082601f8301126119c857600080fd5b813560206119dd6119d883611983565b611934565b8083825260208201915060208460051b8701019350868411156119ff57600080fd5b602086015b84811015611a2257611a158161160e565b8352918301918301611a04565b509695505050505050565b60006020808385031215611a4057600080fd5b823567ffffffffffffffff80821115611a5857600080fd5b818501915085601f830112611a6c57600080fd5b8135611a7a6119d882611983565b81815260059190911b83018401908481019088831115611a9957600080fd5b8585015b83811015611b8957803585811115611ab457600080fd5b860160c0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215611ae95760008081fd5b611af161190b565b8882013581526040611b048184016115f8565b8a8301526060611b158185016115f8565b8284015260809150611b288285016119a7565b9083015260a08381013589811115611b405760008081fd5b611b4e8f8d838801016119b7565b838501525060c0840135915088821115611b685760008081fd5b611b768e8c848701016119b7565b9083015250845250918601918601611a9d565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156102c4576102c4611bc5565b80820281158282048414176102c4576102c4611bc5565b60ff81811683821601908111156102c4576102c4611bc5565b8183823760009101908152919050565b828152606082602083013760800192915050565b6020810160058310611c6f57611c6f611665565b91905290565b60ff8181168382160290811690818114611c9157611c91611bc5565b5092915050565b600060a0820160ff88168352602087602085015260a0604085015281875480845260c086019150886000526020600020935060005b81811015611cff57845473ffffffffffffffffffffffffffffffffffffffff1683526001948501949284019201611ccd565b50508481036060860152611d1381886117dc565b935050505060ff83166080830152969550505050505056fea164736f6c6343000818000a", } var MultiOCR3HelperABI = MultiOCR3HelperMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/ocr3_config_encoder/ocr3_config_encoder.go b/core/gethwrappers/ccip/generated/ocr3_config_encoder/ocr3_config_encoder.go index 399ae5dbd6..737a768dbe 100644 --- a/core/gethwrappers/ccip/generated/ocr3_config_encoder/ocr3_config_encoder.go +++ b/core/gethwrappers/ccip/generated/ocr3_config_encoder/ocr3_config_encoder.go @@ -34,7 +34,6 @@ type CCIPConfigTypesOCR3Config struct { F uint8 OffchainConfigVersion uint64 OfframpAddress []byte - BootstrapP2PIds [][32]byte P2pIds [][32]byte Signers [][]byte Transmitters [][]byte @@ -42,7 +41,7 @@ type CCIPConfigTypesOCR3Config struct { } var IOCR3ConfigEncoderMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"bootstrapP2PIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.OCR3Config[]\",\"name\":\"config\",\"type\":\"tuple[]\"}],\"name\":\"exposeOCR3Config\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.OCR3Config[]\",\"name\":\"config\",\"type\":\"tuple[]\"}],\"name\":\"exposeOCR3Config\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", } var IOCR3ConfigEncoderABI = IOCR3ConfigEncoderMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/offramp/offramp.go b/core/gethwrappers/ccip/generated/offramp/offramp.go index 65795e0626..51edddf954 100644 --- a/core/gethwrappers/ccip/generated/offramp/offramp.go +++ b/core/gethwrappers/ccip/generated/offramp/offramp.go @@ -43,6 +43,11 @@ type ClientEVMTokenAmount struct { Amount *big.Int } +type IRMNV2Signature struct { + R [32]byte + S [32]byte +} + type InternalAny2EVMRampMessage struct { Header InternalRampMessageHeader Sender []byte @@ -65,6 +70,14 @@ type InternalGasPriceUpdate struct { UsdPerUnitGas *big.Int } +type InternalMerkleRoot struct { + SourceChainSelector uint64 + MinSeqNr uint64 + MaxSeqNr uint64 + MerkleRoot [32]byte + OnRampAddress []byte +} + type InternalPriceUpdates struct { TokenPriceUpdates []InternalTokenPriceUpdate GasPriceUpdates []InternalGasPriceUpdate @@ -114,8 +127,9 @@ type MultiOCR3BaseOCRConfigArgs struct { } type OffRampCommitReport struct { - PriceUpdates InternalPriceUpdates - MerkleRoots []OffRampMerkleRoot + PriceUpdates InternalPriceUpdates + MerkleRoots []InternalMerkleRoot + RmnSignatures []IRMNV2Signature } type OffRampDynamicConfig struct { @@ -126,17 +140,6 @@ type OffRampDynamicConfig struct { MessageValidator common.Address } -type OffRampInterval struct { - Min uint64 - Max uint64 -} - -type OffRampMerkleRoot struct { - SourceChainSelector uint64 - Interval OffRampInterval - MerkleRoot [32]byte -} - type OffRampSourceChainConfig struct { Router common.Address IsEnabled bool @@ -153,19 +156,14 @@ type OffRampSourceChainConfigArgs struct { type OffRampStaticConfig struct { ChainSelector uint64 - RmnProxy common.Address + Rmn common.Address TokenAdminRegistry common.Address NonceManager common.Address } -type OffRampUnblessedRoot struct { - SourceChainSelector uint64 - MerkleRoot [32]byte -} - var OffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.UnblessedRoot[]\",\"name\":\"rootToReset\",\"type\":\"tuple[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162006c4a38038062006c4a8339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615f7462000cd6600039600081816102660152612a010152600081816102370152612f1d0152600081816102080152818161142b015261196d0152600081816101d801526125f00152600081816117f3015261183f0152615f746000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806385572ffb116100d8578063ccd37ba31161008c578063f2fde38b11610066578063f2fde38b14610583578063f716f99f14610596578063ff888fb1146105a957600080fd5b8063ccd37ba31461050b578063d2a15d3514610550578063e9d68a8e1461056357600080fd5b8063991a5018116100bd578063991a5018146104c5578063a80036b4146104d8578063c673e584146104eb57600080fd5b806385572ffb1461049c5780638da5cb5b146104aa57600080fd5b8063311cd5131161012f5780635e36480c116101145780635e36480c146103785780637437ff9f1461039857806379ba50971461049457600080fd5b8063311cd513146103495780633f4b04aa1461035c57600080fd5b806306285c691161016057806306285c69146101a4578063181f5a77146102ed5780632d04ab761461033657600080fd5b806304666f9c1461017c57806305d938b514610191575b600080fd5b61018f61018a3660046140d8565b6105cc565b005b61018f61019f366004614764565b6105e0565b61029660408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102e49190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103296040518060400160405280601181526020017f4f666652616d7020312e362e302d64657600000000000000000000000000000081525081565b6040516102e491906148df565b61018f61034436600461498a565b610785565b61018f610357366004614a3d565b610b5c565b60095460405167ffffffffffffffff90911681526020016102e4565b61038b610386366004614a91565b610bc5565b6040516102e49190614aee565b6104376040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102e49190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b61018f610c1b565b61018f610177366004614afc565b6000546040516001600160a01b0390911681526020016102e4565b61018f6104d3366004614b4b565b610cd9565b61018f6104e6366004614bbf565b610cea565b6104fe6104f9366004614c2c565b61105d565b6040516102e49190614c8c565b610542610519366004614d01565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102e4565b61018f61055e366004614d2b565b6111bb565b610576610571366004614da0565b611275565b6040516102e49190614dbb565b61018f610591366004614e09565b611382565b61018f6105a4366004614e8e565b611393565b6105bc6105b7366004614fcc565b6113d5565b60405190151581526020016102e4565b6105d4611496565b6105dd816114f2565b50565b6105e86117f0565b815181518114610624576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8181101561077557600084828151811061064357610643614fe5565b6020026020010151905060008160200151519050600085848151811061066b5761066b614fe5565b60200260200101519050805182146106af576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b828110156107665760008282815181106106ce576106ce614fe5565b602002602001015190508060001461075d57846020015182815181106106f6576106f6614fe5565b60200260200101516080015181101561075d5784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064015b60405180910390fd5b506001016106b2565b50505050806001019050610627565b506107808383611871565b505050565b60006107938789018961516b565b805151519091501515806107ac57508051602001515115155b156108ac5760095460208a01359067ffffffffffffffff8083169116101561086b576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f92610834929101615393565b600060405180830381600087803b15801561084e57600080fd5b505af1158015610862573d6000803e3d6000fd5b505050506108aa565b8160200151516000036108aa576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b816020015151811015610aa5576000826020015182815181106108d4576108d4614fe5565b602002602001015190506000816000015190506108f081611921565b60006108fb82611a23565b602084015151815491925067ffffffffffffffff908116600160a81b9092041614158061093f575060208084015190810151905167ffffffffffffffff9182169116115b1561097f57825160208401516040517feefb0cac0000000000000000000000000000000000000000000000000000000081526107549291906004016153a6565b6040830151806109bb576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff16600090815260086020908152604080832084845290915290205415610a2e5783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101829052604401610754565b6020808501510151610a419060016153f1565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff9283160217909255925116600090815260086020908152604080832094835293905291909120429055506001016108af565b507f3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d81604051610ad59190615419565b60405180910390a1610b5160008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b9250611a8a915050565b505050505050505050565b610b9c610b6b828401846154b6565b6040805160008082526020820190925290610b96565b6060815260200190600190039081610b815790505b50611871565b604080516000808252602082019092529050610bbf600185858585866000611a8a565b50505050565b6000610bd3600160046154eb565b6002610be0608085615514565b67ffffffffffffffff16610bf4919061553b565b610bfe8585611e01565b901c166003811115610c1257610c12614ac4565b90505b92915050565b6001546001600160a01b03163314610c755760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610754565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610ce1611496565b6105dd81611e48565b333014610d23576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281610d60565b6040805180820190915260008082526020820152815260200190600190039081610d395790505b5060a08501515190915015610d9457610d918460a00151856020015186606001518760000151602001518787611fae565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff1681830152808701518351600094840192610dd09291016148df565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015610edd576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a190610e4a9085906004016155f4565b600060405180830381600087803b158015610e6457600080fd5b505af1925050508015610e75575060015b610edd573d808015610ea3576040519150601f19603f3d011682016040523d82523d6000602084013e610ea8565b606091505b50806040517f09c2532500000000000000000000000000000000000000000000000000000000815260040161075491906148df565b604086015151158015610ef257506080860151155b80610f09575060608601516001600160a01b03163b155b80610f4957506060860151610f47906001600160a01b03167f85572ffb000000000000000000000000000000000000000000000000000000006120cd565b155b15610f5657505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf9798392610fce9289926113889291600401615607565b6000604051808303816000875af1158015610fed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110159190810190615643565b50915091508161105357806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161075491906148df565b5050505050505050565b6110a06040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c08201529485529182018054845181840281018401909552808552929385830193909283018282801561114957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161112b575b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156111ab57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161118d575b5050505050815250509050919050565b6111c3611496565b60005b818110156107805760008383838181106111e2576111e2614fe5565b9050604002018036038101906111f891906156d9565b905061120781602001516113d5565b61126c57805167ffffffffffffffff1660009081526008602090815260408083208285018051855290835281842093909355915191519182527f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12910160405180910390a15b506001016111c6565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b90920490921694830194909452600184018054939492939184019161130290615712565b80601f016020809104026020016040519081016040528092919081815260200182805461132e90615712565b80156111ab5780601f10611350576101008083540402835291602001916111ab565b820191906000526020600020905b81548152906001019060200180831161135e57505050919092525091949350505050565b61138a611496565b6105dd816120e9565b61139b611496565b60005b81518110156113d1576113c98282815181106113bc576113bc614fe5565b602002602001015161219f565b60010161139e565b5050565b6040805180820182523081526020810183815291517f4d61677100000000000000000000000000000000000000000000000000000000815290516001600160a01b039081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611472573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c15919061574c565b6000546001600160a01b031633146114f05760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610754565b565b60005b81518110156113d157600082828151811061151257611512614fe5565b602002602001015190506000816020015190508067ffffffffffffffff16600003611569576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b0316611591576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115bc90615712565b80601f01602080910402602001604051908101604052809291908181526020018280546115e890615712565b80156116355780601f1061160a57610100808354040283529160200191611635565b820191906000526020600020905b81548152906001019060200180831161161857829003601f168201915b5050505050905060008460600151905081516000036116ed578051600003611670576040516342bcdf7f60e11b815260040160405180910390fd5b6001830161167e82826157b1565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611740565b8080519060200120828051906020012014611740576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610754565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117d8908690615871565b60405180910390a250505050508060010190506114f5565b467f0000000000000000000000000000000000000000000000000000000000000000146114f0576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610754565b81516000036118ab576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b845181101561191a576119128582815181106118e0576118e0614fe5565b60200260200101518461190c578583815181106118ff576118ff614fe5565b60200260200101516124e3565b836124e3565b6001016118c2565b5050505050565b6040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608082901b77ffffffffffffffff000000000000000000000000000000001660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa1580156119bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e0919061574c565b156105dd576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610754565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610c15576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610754565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611ae98760a461593f565b9050826060015115611b31578451611b0290602061553b565b8651611b0f90602061553b565b611b1a9060a061593f565b611b24919061593f565b611b2e908261593f565b90505b368114611b73576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610754565b5081518114611bbb5781516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610754565b611bc36117f0565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611c1157611c11614ac4565b6002811115611c2257611c22614ac4565b9052509050600281602001516002811115611c3f57611c3f614ac4565b148015611c935750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611c7b57611c7b614fe5565b6000918252602090912001546001600160a01b031633145b611cc9576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611dab576020820151611ce4906001615952565b60ff16855114611d20576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611d5b576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611d6d92919061596b565b604051908190038120611d84918b9060200161597b565b604051602081830303815290604052805190602001209050611da98a82888888612caf565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b67ffffffffffffffff8216600090815260076020526040812081611e2660808561598f565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b80516001600160a01b0316611e70576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611fca57611fca613eef565b60405190808252806020026020018201604052801561200f57816020015b6040805180820190915260008082526020820152815260200190600190039081611fe85790505b50905060005b87518110156120c15761209c88828151811061203357612033614fe5565b602002602001015188888888888781811061205057612050614fe5565b905060200281019061206291906159b6565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612ebc92505050565b8282815181106120ae576120ae614fe5565b6020908102919091010152600101612015565b505b9695505050505050565b60006120d883613261565b8015610c125750610c1283836132c5565b336001600160a01b038216036121415760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610754565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036121ca576000604051631b3fab5160e11b81526004016107549190615a1b565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361223757606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff90921691909117905561228c565b6060840151600182015460ff620100009091041615159015151461228c576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff84166004820152602401610754565b60a08401518051601f60ff821611156122bb576001604051631b3fab5160e11b81526004016107549190615a1b565b612321858560030180548060200260200160405190810160405280929190818152602001828054801561231757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122f9575b5050505050613380565b8560600151156124505761238f8585600201805480602002602001604051908101604052809291908181526020018280548015612317576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116122f9575050505050613380565b608086015180516123a99060028701906020840190613e49565b5080516001850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff841690810291909117909155601f1015612409576002604051631b3fab5160e11b81526004016107549190615a1b565b6040880151612419906003615a35565b60ff168160ff1611612441576003604051631b3fab5160e11b81526004016107549190615a1b565b61244d878360016133e9565b50505b61245c858360026133e9565b81516124719060038601906020850190613e49565b5060408681015160018501805460ff191660ff8316179055875180865560a089015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936124ca938a939260028b01929190615a51565b60405180910390a16124db85613569565b505050505050565b81516124ee81611921565b60006124f982611a23565b602085015151909150600081900361253c576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846040015151811461257a576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561259557612595613eef565b6040519080825280602002602001820160405280156125be578160200160208202803683370190505b50905060005b82811015612733576000876020015182815181106125e4576125e4614fe5565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461267757805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610754565b61270d8186600101805461268a90615712565b80601f01602080910402602001604051908101604052809291908181526020018280546126b690615712565b80156127035780601f106126d857610100808354040283529160200191612703565b820191906000526020600020905b8154815290600101906020018083116126e657829003601f168201915b5050505050613585565b83838151811061271f5761271f614fe5565b6020908102919091010152506001016125c4565b50600061274a858389606001518a608001516136a7565b905080600003612792576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff86166004820152602401610754565b8551151560005b84811015610b515760005a905060008a6020015183815181106127be576127be614fe5565b6020026020010151905060006127dc8a836000015160600151610bc5565b905060008160038111156127f2576127f2614ac4565b148061280f5750600381600381111561280d5761280d614ac4565b145b612867578151606001516040805167ffffffffffffffff808e16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a1505050612ca7565b841561293757600454600090600160a01b900463ffffffff1661288a88426154eb565b11905080806128aa575060038260038111156128a8576128a8614ac4565b145b6128ec576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8c166004820152602401610754565b8b85815181106128fe576128fe614fe5565b6020026020010151600014612931578b858151811061291f5761291f614fe5565b60200260200101518360800181815250505b50612998565b600081600381111561294b5761294b614ac4565b14612998578151606001516040805167ffffffffffffffff808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612857565b81516080015167ffffffffffffffff1615612a875760008160038111156129c1576129c1614ac4565b03612a875781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612a38928f929190600401615afd565b6020604051808303816000875af1158015612a57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7b919061574c565b612a8757505050612ca7565b60008c604001518581518110612a9f57612a9f614fe5565b6020026020010151905080518360a001515114612b03578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808e1660048301529091166024820152604401610754565b612b178b84600001516060015160016136fd565b600080612b2485846137a5565b91509150612b3b8d866000015160600151846136fd565b8715612bab576003826003811115612b5557612b55614ac4565b03612bab576000846003811115612b6e57612b6e614ac4565b14612bab578451516040517f2b11b8d900000000000000000000000000000000000000000000000000000000815261075491908390600401615b2a565b6002826003811115612bbf57612bbf614ac4565b14612c19576003826003811115612bd857612bd8614ac4565b14612c19578451606001516040517f926c5a3e000000000000000000000000000000000000000000000000000000008152610754918f918590600401615b43565b84600001516000015185600001516060015167ffffffffffffffff168e67ffffffffffffffff167f05665fe9ad095383d018353f4cbcba77e84db27dd215081bbf7cdf9ae6fbe48b8d8b81518110612c7357612c73614fe5565b602002602001015186865a612c88908e6154eb565b604051612c989493929190615b69565b60405180910390a45050505050505b600101612799565b612cb7613ebb565b835160005b81811015611053576000600188868460208110612cdb57612cdb614fe5565b612ce891901a601b615952565b898581518110612cfa57612cfa614fe5565b6020026020010151898681518110612d1457612d14614fe5565b602002602001015160405160008152602001604052604051612d52949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612d74573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b03851683528152858220858701909652855480841686529397509095509293928401916101009004166002811115612dd557612dd5614ac4565b6002811115612de657612de6614ac4565b9052509050600181602001516002811115612e0357612e03614ac4565b14612e3a576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f8110612e5157612e51614fe5565b602002015115612e8d576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f8110612ea857612ea8614fe5565b911515602090920201525050600101612cbc565b60408051808201909152600080825260208201526000612edf876020015161386f565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f889190615ba0565b90506001600160a01b0381161580612fd05750612fce6001600160a01b0382167faff2afbf000000000000000000000000000000000000000000000000000000006120cd565b155b15613012576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610754565b60045460009081906130349089908690600160e01b900463ffffffff16613915565b9150915060008060006131016040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b8152506040516024016130b29190615bbd565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a43565b9250925092508261314057816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161075491906148df565b81516020146131885781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610754565b60008280602001905181019061319e9190615c8a565b9050866001600160a01b03168c6001600160a01b0316146132335760006131cf8d8a6131ca868a6154eb565b613915565b509050868110806131e95750816131e688836154eb565b14155b15613231576040517fa966e21f000000000000000000000000000000000000000000000000000000008152600481018390526024810188905260448101829052606401610754565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b600061328d827f01ffc9a7000000000000000000000000000000000000000000000000000000006132c5565b8015610c1557506132be827fffffffff000000000000000000000000000000000000000000000000000000006132c5565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015613369575060208210155b80156133755750600081115b979650505050505050565b60005b81518110156107805760ff8316600090815260036020526040812083519091908490849081106133b5576133b5614fe5565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613383565b60005b82518160ff161015610bbf576000838260ff168151811061340f5761340f614fe5565b602002602001015190506000600281111561342c5761342c614ac4565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561346b5761346b614ac4565b1461348c576004604051631b3fab5160e11b81526004016107549190615a1b565b6001600160a01b0381166134cc576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134f2576134f2614ac4565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561354f5761354f614ac4565b0217905550905050508061356290615ca3565b90506133ec565b60ff81166105dd576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936135cb937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615cc2565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976136149794969395929491939101615cf5565b604051602081830303815290604052805190602001208560400151805190602001208660a0015160405160200161364b9190615e07565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b6000806136b5858585613b69565b90506136c0816113d5565b6136ce5760009150506136f5565b67ffffffffffffffff86166000908152600860209081526040808320938352929052205490505b949350505050565b6000600261370c608085615514565b67ffffffffffffffff16613720919061553b565b9050600061372e8585611e01565b90508161373d600160046154eb565b901b19168183600381111561375457613754614ac4565b67ffffffffffffffff871660009081526007602052604081209190921b9290921791829161378360808861598f565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fa80036b4000000000000000000000000000000000000000000000000000000008152600090606090309063a80036b4906137e99087908790600401615e67565b600060405180830381600087803b15801561380357600080fd5b505af1925050508015613814575060015b613853573d808015613842576040519150601f19603f3d011682016040523d82523d6000602084013e613847565b606091505b50600392509050613868565b50506040805160208101909152600081526002905b9250929050565b600081516020146138ae57816040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161075491906148df565b6000828060200190518101906138c49190615c8a565b90506001600160a01b038111806138dc575061040081105b15610c1557826040517f8d666f6000000000000000000000000000000000000000000000000000000000815260040161075491906148df565b600080600080600061398f8860405160240161394091906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a43565b925092509250826139ce57816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161075491906148df565b6020825114613a165781516040517f78ef8024000000000000000000000000000000000000000000000000000000008152602060048201526024810191909152604401610754565b81806020019051810190613a2a9190615c8a565b613a3482886154eb565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a6657613a66613eef565b6040519080825280601f01601f191660200182016040528015613a90576020820181803683370190505b509150863b613ac3577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613af6577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613b2f577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b525750835b808352806000602085013e50955095509592505050565b8251825160009190818303613baa576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613bbe57506101018111155b613bdb576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613c05576040516309bde33960e01b815260040160405180910390fd5b80600003613c325786600081518110613c2057613c20614fe5565b60200260200101519350505050613e01565b60008167ffffffffffffffff811115613c4d57613c4d613eef565b604051908082528060200260200182016040528015613c76578160200160208202803683370190505b50905060008080805b85811015613da05760006001821b8b811603613cda5788851015613cc3578c5160018601958e918110613cb457613cb4614fe5565b60200260200101519050613cfc565b8551600185019487918110613cb457613cb4614fe5565b8b5160018401938d918110613cf157613cf1614fe5565b602002602001015190505b600089861015613d2c578d5160018701968f918110613d1d57613d1d614fe5565b60200260200101519050613d4e565b8651600186019588918110613d4357613d43614fe5565b602002602001015190505b82851115613d6f576040516309bde33960e01b815260040160405180910390fd5b613d798282613e08565b878481518110613d8b57613d8b614fe5565b60209081029190910101525050600101613c7f565b506001850382148015613db257508683145b8015613dbd57508581145b613dda576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613def57613def614fe5565b60200260200101519750505050505050505b9392505050565b6000818310613e2057613e1b8284613e26565b610c12565b610c1283835b604080516001602082015290810183905260608101829052600090608001613689565b828054828255906000526020600020908101928215613eab579160200282015b82811115613eab578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e69565b50613eb7929150613eda565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613eb75760008155600101613edb565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613f2857613f28613eef565b60405290565b60405160a0810167ffffffffffffffff81118282101715613f2857613f28613eef565b60405160c0810167ffffffffffffffff81118282101715613f2857613f28613eef565b6040805190810167ffffffffffffffff81118282101715613f2857613f28613eef565b6040516060810167ffffffffffffffff81118282101715613f2857613f28613eef565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fe357613fe3613eef565b604052919050565b600067ffffffffffffffff82111561400557614005613eef565b5060051b60200190565b6001600160a01b03811681146105dd57600080fd5b803567ffffffffffffffff8116811461403c57600080fd5b919050565b80151581146105dd57600080fd5b803561403c81614041565b600067ffffffffffffffff82111561407457614074613eef565b50601f01601f191660200190565b600082601f83011261409357600080fd5b81356140a66140a18261405a565b613fba565b8181528460208386010111156140bb57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156140eb57600080fd5b823567ffffffffffffffff8082111561410357600080fd5b818501915085601f83011261411757600080fd5b81356141256140a182613feb565b81815260059190911b8301840190848101908883111561414457600080fd5b8585015b838110156141ea578035858111156141605760008081fd5b86016080818c03601f19018113156141785760008081fd5b614180613f05565b8983013561418d8161400f565b8152604061419c848201614024565b8b8301526060808501356141af81614041565b838301529284013592898411156141c857600091508182fd5b6141d68f8d86880101614082565b908301525085525050918601918601614148565b5098975050505050505050565b600060a0828403121561420957600080fd5b614211613f2e565b90508135815261422360208301614024565b602082015261423460408301614024565b604082015261424560608301614024565b606082015261425660808301614024565b608082015292915050565b803561403c8161400f565b600082601f83011261427d57600080fd5b8135602061428d6140a183613feb565b82815260059290921b840181019181810190868411156142ac57600080fd5b8286015b848110156120c157803567ffffffffffffffff808211156142d15760008081fd5b818901915060a080601f19848d030112156142ec5760008081fd5b6142f4613f2e565b87840135838111156143065760008081fd5b6143148d8a83880101614082565b8252506040808501358481111561432b5760008081fd5b6143398e8b83890101614082565b8a84015250606080860135858111156143525760008081fd5b6143608f8c838a0101614082565b838501525060809150818601358184015250828501359250838311156143865760008081fd5b6143948d8a85880101614082565b9082015286525050509183019183016142b0565b600061014082840312156143bb57600080fd5b6143c3613f51565b90506143cf83836141f7565b815260a082013567ffffffffffffffff808211156143ec57600080fd5b6143f885838601614082565b602084015260c084013591508082111561441157600080fd5b61441d85838601614082565b604084015261442e60e08501614261565b6060840152610100840135608084015261012084013591508082111561445357600080fd5b506144608482850161426c565b60a08301525092915050565b600082601f83011261447d57600080fd5b8135602061448d6140a183613feb565b82815260059290921b840181019181810190868411156144ac57600080fd5b8286015b848110156120c157803567ffffffffffffffff8111156144d05760008081fd5b6144de8986838b01016143a8565b8452509183019183016144b0565b600082601f8301126144fd57600080fd5b8135602061450d6140a183613feb565b82815260059290921b8401810191818101908684111561452c57600080fd5b8286015b848110156120c157803567ffffffffffffffff8082111561455057600080fd5b818901915089603f83011261456457600080fd5b858201356145746140a182613feb565b81815260059190911b830160400190878101908c83111561459457600080fd5b604085015b838110156145cd578035858111156145b057600080fd5b6145bf8f6040838a0101614082565b845250918901918901614599565b50875250505092840192508301614530565b600082601f8301126145f057600080fd5b813560206146006140a183613feb565b8083825260208201915060208460051b87010193508684111561462257600080fd5b602086015b848110156120c15780358352918301918301614627565b600082601f83011261464f57600080fd5b8135602061465f6140a183613feb565b82815260059290921b8401810191818101908684111561467e57600080fd5b8286015b848110156120c157803567ffffffffffffffff808211156146a35760008081fd5b818901915060a080601f19848d030112156146be5760008081fd5b6146c6613f2e565b6146d1888501614024565b8152604080850135848111156146e75760008081fd5b6146f58e8b8389010161446c565b8a840152506060808601358581111561470e5760008081fd5b61471c8f8c838a01016144ec565b83850152506080915081860135858111156147375760008081fd5b6147458f8c838a01016145df565b9184019190915250919093013590830152508352918301918301614682565b600080604080848603121561477857600080fd5b833567ffffffffffffffff8082111561479057600080fd5b61479c8783880161463e565b94506020915081860135818111156147b357600080fd5b8601601f810188136147c457600080fd5b80356147d26140a182613feb565b81815260059190911b8201840190848101908a8311156147f157600080fd5b8584015b8381101561487d5780358681111561480d5760008081fd5b8501603f81018d1361481f5760008081fd5b8781013561482f6140a182613feb565b81815260059190911b82018a0190898101908f83111561484f5760008081fd5b928b01925b8284101561486d5783358252928a0192908a0190614854565b86525050509186019186016147f5565b50809750505050505050509250929050565b60005b838110156148aa578181015183820152602001614892565b50506000910152565b600081518084526148cb81602086016020860161488f565b601f01601f19169290920160200192915050565b602081526000610c1260208301846148b3565b8060608101831015610c1557600080fd5b60008083601f84011261491557600080fd5b50813567ffffffffffffffff81111561492d57600080fd5b60208301915083602082850101111561386857600080fd5b60008083601f84011261495757600080fd5b50813567ffffffffffffffff81111561496f57600080fd5b6020830191508360208260051b850101111561386857600080fd5b60008060008060008060008060e0898b0312156149a657600080fd5b6149b08a8a6148f2565b9750606089013567ffffffffffffffff808211156149cd57600080fd5b6149d98c838d01614903565b909950975060808b01359150808211156149f257600080fd5b6149fe8c838d01614945565b909750955060a08b0135915080821115614a1757600080fd5b50614a248b828c01614945565b999c989b50969995989497949560c00135949350505050565b600080600060808486031215614a5257600080fd5b614a5c85856148f2565b9250606084013567ffffffffffffffff811115614a7857600080fd5b614a8486828701614903565b9497909650939450505050565b60008060408385031215614aa457600080fd5b614aad83614024565b9150614abb60208401614024565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614aea57614aea614ac4565b9052565b60208101610c158284614ada565b600060208284031215614b0e57600080fd5b813567ffffffffffffffff811115614b2557600080fd5b820160a08185031215613e0157600080fd5b803563ffffffff8116811461403c57600080fd5b600060a08284031215614b5d57600080fd5b614b65613f2e565b8235614b708161400f565b8152614b7e60208401614b37565b6020820152614b8f60408401614b37565b6040820152614ba060608401614b37565b60608201526080830135614bb38161400f565b60808201529392505050565b600080600060408486031215614bd457600080fd5b833567ffffffffffffffff80821115614bec57600080fd5b614bf8878388016143a8565b94506020860135915080821115614c0e57600080fd5b50614a8486828701614945565b803560ff8116811461403c57600080fd5b600060208284031215614c3e57600080fd5b610c1282614c1b565b60008151808452602080850194506020840160005b83811015614c815781516001600160a01b031687529582019590820190600101614c5c565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614cdb60e0840182614c47565b90506040840151601f198483030160c0850152614cf88282614c47565b95945050505050565b60008060408385031215614d1457600080fd5b614d1d83614024565b946020939093013593505050565b60008060208385031215614d3e57600080fd5b823567ffffffffffffffff80821115614d5657600080fd5b818501915085601f830112614d6a57600080fd5b813581811115614d7957600080fd5b8660208260061b8501011115614d8e57600080fd5b60209290920196919550909350505050565b600060208284031215614db257600080fd5b610c1282614024565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136f560a08401826148b3565b600060208284031215614e1b57600080fd5b8135613e018161400f565b600082601f830112614e3757600080fd5b81356020614e476140a183613feb565b8083825260208201915060208460051b870101935086841115614e6957600080fd5b602086015b848110156120c1578035614e818161400f565b8352918301918301614e6e565b60006020808385031215614ea157600080fd5b823567ffffffffffffffff80821115614eb957600080fd5b818501915085601f830112614ecd57600080fd5b8135614edb6140a182613feb565b81815260059190911b83018401908481019088831115614efa57600080fd5b8585015b838110156141ea57803585811115614f1557600080fd5b860160c0818c03601f19011215614f2c5760008081fd5b614f34613f51565b8882013581526040614f47818401614c1b565b8a8301526060614f58818501614c1b565b8284015260809150614f6b82850161404f565b9083015260a08381013589811115614f835760008081fd5b614f918f8d83880101614e26565b838501525060c0840135915088821115614fab5760008081fd5b614fb98e8c84870101614e26565b9083015250845250918601918601614efe565b600060208284031215614fde57600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b80356001600160e01b038116811461403c57600080fd5b600082601f83011261502357600080fd5b813560206150336140a183613feb565b82815260069290921b8401810191818101908684111561505257600080fd5b8286015b848110156120c1576040818903121561506f5760008081fd5b615077613f74565b61508082614024565b815261508d858301614ffb565b81860152835291830191604001615056565b600082601f8301126150b057600080fd5b813560206150c06140a183613feb565b82815260079290921b840181019181810190868411156150df57600080fd5b8286015b848110156120c15780880360808112156150fd5760008081fd5b615105613f97565b61510e83614024565b8152604080601f19840112156151245760008081fd5b61512c613f74565b9250615139878501614024565b8352615146818501614024565b83880152818701929092526060830135918101919091528352918301916080016150e3565b6000602080838503121561517e57600080fd5b823567ffffffffffffffff8082111561519657600080fd5b818501915060408083880312156151ac57600080fd5b6151b4613f74565b8335838111156151c357600080fd5b84016040818a0312156151d557600080fd5b6151dd613f74565b8135858111156151ec57600080fd5b8201601f81018b136151fd57600080fd5b803561520b6140a182613feb565b81815260069190911b8201890190898101908d83111561522a57600080fd5b928a01925b8284101561527a5787848f0312156152475760008081fd5b61524f613f74565b843561525a8161400f565b8152615267858d01614ffb565b818d0152825292870192908a019061522f565b84525050508187013593508484111561529257600080fd5b61529e8a858401615012565b81880152825250838501359150828211156152b857600080fd5b6152c48883860161509f565b85820152809550505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b8181101561532d57835180516001600160a01b031684528501516001600160e01b03168584015292840192918501916001016152f6565b50508583015187820388850152805180835290840192506000918401905b80831015615387578351805167ffffffffffffffff1683528501516001600160e01b03168583015292840192600192909201919085019061534b565b50979650505050505050565b602081526000610c1260208301846152d6565b67ffffffffffffffff8316815260608101613e016020830184805167ffffffffffffffff908116835260209182015116910152565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff818116838216019080821115615412576154126153db565b5092915050565b60006020808352606084516040808487015261543860608701836152d6565b87850151878203601f19016040890152805180835290860193506000918601905b808310156141ea57845167ffffffffffffffff81511683528781015161549889850182805167ffffffffffffffff908116835260209182015116910152565b50840151828701529386019360019290920191608090910190615459565b6000602082840312156154c857600080fd5b813567ffffffffffffffff8111156154df57600080fd5b6136f58482850161463e565b81810381811115610c1557610c156153db565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff8084168061552f5761552f6154fe565b92169190910692915050565b8082028115828204841417610c1557610c156153db565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261558660a08701826148b3565b90506060850151868203606088015261559f82826148b3565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561538757835180516001600160a01b03168352860151868301529285019260019290920191908401906155c2565b602081526000610c126020830184615552565b60808152600061561a6080830187615552565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561565857600080fd5b835161566381614041565b602085015190935067ffffffffffffffff81111561568057600080fd5b8401601f8101861361569157600080fd5b805161569f6140a18261405a565b8181528760208385010111156156b457600080fd5b6156c582602083016020860161488f565b809450505050604084015190509250925092565b6000604082840312156156eb57600080fd5b6156f3613f74565b6156fc83614024565b8152602083013560208201528091505092915050565b600181811c9082168061572657607f821691505b60208210810361574657634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561575e57600080fd5b8151613e0181614041565b601f821115610780576000816000526020600020601f850160051c810160208610156157925750805b601f850160051c820191505b818110156124db5782815560010161579e565b815167ffffffffffffffff8111156157cb576157cb613eef565b6157df816157d98454615712565b84615769565b602080601f83116001811461581457600084156157fc5750858301515b600019600386901b1c1916600185901b1785556124db565b600085815260208120601f198616915b8281101561584357888601518255948401946001909101908401615824565b50858210156158615787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c166060850152506001808501608080860152600081546158c381615712565b8060a089015260c060018316600081146158e4576001811461590057615930565b60ff19841660c08b015260c083151560051b8b01019450615930565b85600052602060002060005b848110156159275781548c820185015290880190890161590c565b8b0160c0019550505b50929998505050505050505050565b80820180821115610c1557610c156153db565b60ff8181168382160190811115610c1557610c156153db565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff808416806159aa576159aa6154fe565b92169190910492915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126159eb57600080fd5b83018035915067ffffffffffffffff821115615a0657600080fd5b60200191503681900382131561386857600080fd5b6020810160058310615a2f57615a2f614ac4565b91905290565b60ff8181168382160290811690818114615412576154126153db565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615aa95784546001600160a01b031683526001948501949284019201615a84565b50508481036060860152865180825290820192508187019060005b81811015615ae95782516001600160a01b031685529383019391830191600101615ac4565b50505060ff851660808501525090506120c3565b600067ffffffffffffffff808616835280851660208401525060606040830152614cf860608301846148b3565b8281526040602082015260006136f560408301846148b3565b67ffffffffffffffff848116825283166020820152606081016136f56040830184614ada565b848152615b796020820185614ada565b608060408201526000615b8f60808301856148b3565b905082606083015295945050505050565b600060208284031215615bb257600080fd5b8151613e018161400f565b6020815260008251610100806020850152615bdc6101208501836148b3565b91506020850151615bf9604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615c3360a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615c5084836148b3565b935060c08701519150808685030160e0870152615c6d84836148b3565b935060e08701519150808685030183870152506120c383826148b3565b600060208284031215615c9c57600080fd5b5051919050565b600060ff821660ff8103615cb957615cb96153db565b60010192915050565b848152600067ffffffffffffffff8086166020840152808516604084015250608060608301526120c360808301846148b3565b86815260c060208201526000615d0e60c08301886148b3565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b84811015615dfa57601f19868403018952815160a08151818652615d8b828701826148b3565b9150508582015185820387870152615da382826148b3565b91505060408083015186830382880152615dbd83826148b3565b92505050606080830151818701525060808083015192508582038187015250615de681836148b3565b9a86019a9450505090830190600101615d65565b5090979650505050505050565b602081526000610c126020830184615d48565b60008282518085526020808601955060208260051b8401016020860160005b84811015615dfa57601f19868403018952615e558383516148b3565b98840198925090830190600101615e39565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615ecf6101808501836148b3565b915060408601517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08086850301610100870152615f0c84836148b3565b935060608801519150615f2b6101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615f528282615d48565b9150508281036020840152614cf88185615e1a56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRMNV2\",\"name\":\"rmn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"onRampAddress\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMNV2.Signature[]\",\"name\":\"rmnSignatures\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SkippedReportExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRMNV2\",\"name\":\"rmn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRMNV2\",\"name\":\"rmn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPoolReleaseOrMintGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162006c2638038062006c268339810160408190526200003591620008c7565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001fa565b5050466080525060208301516001600160a01b03161580620000ec575060408301516001600160a01b0316155b8062000103575060608301516001600160a01b0316155b1562000122576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b03166000036200014e5760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001e682620002a5565b620001f181620003c1565b50505062000c67565b336001600160a01b03821603620002545760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316620002ce576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c166001600160c01b0319909a168a17600160a01b63ffffffff98891602176001600160c01b0316600160c01b948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b018051600580546001600160a01b031916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b60005b815181101562000666576000828281518110620003e557620003e562000a1d565b60200260200101519050600081602001519050806001600160401b0316600003620004235760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166200044c576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600660205260408120600181018054919291620004789062000a33565b80601f0160208091040260200160405190810160405280929190818152602001828054620004a69062000a33565b8015620004f75780601f10620004cb57610100808354040283529160200191620004f7565b820191906000526020600020905b815481529060010190602001808311620004d957829003601f168201915b5050505050905060008460600151905081516000036200059e57805160000362000534576040516342bcdf7f60e11b815260040160405180910390fd5b6001830162000544828262000ac4565b508254600160a81b600160e81b031916600160a81b1783556040516001600160401b03851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620005d9565b8080519060200120828051906020012014620005d95760405163c39a620560e01b81526001600160401b038516600482015260240162000083565b604080860151845487516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b031990911617178455516001600160401b038516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906200064d90869062000b90565b60405180910390a25050505050806001019050620003c4565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620006a557620006a56200066a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006d657620006d66200066a565b604052919050565b80516001600160401b0381168114620006f657600080fd5b919050565b6001600160a01b03811681146200071157600080fd5b50565b805163ffffffff81168114620006f657600080fd5b6000601f83601f8401126200073d57600080fd5b825160206001600160401b03808311156200075c576200075c6200066a565b8260051b6200076d838201620006ab565b93845286810183019383810190898611156200078857600080fd5b84890192505b85831015620008ba57825184811115620007a85760008081fd5b89016080601f19828d038101821315620007c25760008081fd5b620007cc62000680565b88840151620007db81620006fb565b81526040620007ec858201620006de565b8a8301526060808601518015158114620008065760008081fd5b838301529385015193898511156200081e5760008081fd5b84860195508f603f8701126200083657600094508485fd5b8a8601519450898511156200084f576200084f6200066a565b620008608b858f88011601620006ab565b93508484528f82868801011115620008785760008081fd5b60005b8581101562000898578681018301518582018d01528b016200087b565b5060009484018b0194909452509182015283525091840191908401906200078e565b9998505050505050505050565b6000806000838503610140811215620008df57600080fd5b6080811215620008ee57600080fd5b620008f862000680565b6200090386620006de565b815260208601516200091581620006fb565b602082015260408601516200092a81620006fb565b604082015260608601516200093f81620006fb565b6060820152935060a0607f19820112156200095957600080fd5b5060405160a081016001600160401b0380821183831017156200098057620009806200066a565b81604052608087015191506200099682620006fb565b818352620009a760a0880162000714565b6020840152620009ba60c0880162000714565b6040840152620009cd60e0880162000714565b60608401526101008701519150620009e582620006fb565b608083018290526101208701519294508083111562000a0357600080fd5b505062000a138682870162000729565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4857607f821691505b60208210810362000a6957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000abf576000816000526020600020601f850160051c8101602086101562000a9a5750805b601f850160051c820191505b8181101562000abb5782815560010162000aa6565b5050505b505050565b81516001600160401b0381111562000ae05762000ae06200066a565b62000af88162000af1845462000a33565b8462000a6f565b602080601f83116001811462000b30576000841562000b175750858301515b600019600386901b1c1916600185901b17855562000abb565b600085815260208120601f198616915b8281101562000b615788860151825594840194600190910190840162000b40565b508582101562000b805787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000be58162000a33565b8060a089015260c0600183166000811462000c09576001811462000c265762000c58565b60ff19841660c08b015260c083151560051b8b0101945062000c58565b85600052602060002060005b8481101562000c4f5781548c820185015290880190890162000c32565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615f4962000cdd600039600081816102400152612a1a0152600081816102110152612f0e0152600081816101e20152818161077f01528181610986015261240c0152600081816101b201526126990152600081816117dd01526118290152615f496000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c806379ba5097116100cd578063c673e58411610081578063e9d68a8e11610066578063e9d68a8e1461052a578063f2fde38b1461054a578063f716f99f1461055d57600080fd5b8063c673e584146104c5578063ccd37ba3146104e557600080fd5b80638da5cb5b116100b25780638da5cb5b14610484578063991a50181461049f578063a80036b4146104b257600080fd5b806379ba50971461046e57806385572ffb1461047657600080fd5b80632d04ab76116101245780633f4b04aa116101095780633f4b04aa146103365780635e36480c146103525780637437ff9f1461037257600080fd5b80632d04ab7614610310578063311cd5131461032357600080fd5b806304666f9c1461015657806305d938b51461016b57806306285c691461017e578063181f5a77146102c7575b600080fd5b610169610164366004614086565b610570565b005b610169610179366004614710565b610584565b61027060408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040516102be9190815167ffffffffffffffff1681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6103036040518060400160405280601181526020017f4f666652616d7020312e362e302d64657600000000000000000000000000000081525081565b6040516102be919061488b565b61016961031e366004614936565b610729565b6101696103313660046149e9565b610cc1565b60095460405167ffffffffffffffff90911681526020016102be565b610365610360366004614a3d565b610d2a565b6040516102be9190614a9a565b6104116040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526004546001600160a01b03808216835263ffffffff600160a01b83048116602085015278010000000000000000000000000000000000000000000000008304811694840194909452600160e01b9091049092166060820152600554909116608082015290565b6040516102be9190600060a0820190506001600160a01b03808451168352602084015163ffffffff808216602086015280604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b610169610d80565b610169610151366004614aa8565b6000546040516001600160a01b0390911681526020016102be565b6101696104ad366004614af7565b610e3e565b6101696104c0366004614b6b565b610e4f565b6104d86104d3366004614bd8565b6111c2565b6040516102be9190614c38565b61051c6104f3366004614cad565b67ffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b6040519081526020016102be565b61053d610538366004614cd7565b611320565b6040516102be9190614cf2565b610169610558366004614d40565b61142d565b61016961056b366004614dc5565b61143e565b610578611480565b610581816114dc565b50565b61058c6117da565b8151815181146105c8576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156107195760008482815181106105e7576105e7614f03565b6020026020010151905060008160200151519050600085848151811061060f5761060f614f03565b6020026020010151905080518214610653576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8281101561070a57600082828151811061067257610672614f03565b6020026020010151905080600014610701578460200151828151811061069a5761069a614f03565b6020026020010151608001518110156107015784516040517fc8e9605100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260248101839052604481018290526064015b60405180910390fd5b50600101610656565b505050508060010190506105cb565b50610724838361185b565b505050565b600061073787890189615135565b602081015151909150156107e357602081015160408083015190517f30dfc3080000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926330dfc308926107b292600401615399565b60006040518083038186803b1580156107ca57600080fd5b505afa1580156107de573d6000803e3d6000fd5b505050505b805151511515806107f957508051602001515115155b156108f95760095460208a01359067ffffffffffffffff808316911610156108b8576009805467ffffffffffffffff191667ffffffffffffffff83161790556004805483516040517f3937306f0000000000000000000000000000000000000000000000000000000081526001600160a01b0390921692633937306f9261088192910161547b565b600060405180830381600087803b15801561089b57600080fd5b505af11580156108af573d6000803e3d6000fd5b505050506108f7565b8160200151516000036108f7576040517f2261116700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b60005b816020015151811015610c0a5760008260200151828151811061092157610921614f03565b602090810291909101015180516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608083901b166004820152919250906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa1580156109cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f1919061548e565b15610a34576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016106f8565b6000610a3f8261190b565b6020840151815491925067ffffffffffffffff908116600160a81b90920416141580610a865750826040015167ffffffffffffffff16836020015167ffffffffffffffff16115b15610ae7578251602084015160408086015190517fd5e0f0d600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff938416600482015291831660248301529190911660448201526064016106f8565b606083015180610b23576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835167ffffffffffffffff16600090815260086020908152604080832084845290915290205415610b965783516040517f32cf0cbf00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602481018290526044016106f8565b6040840151610ba69060016154c1565b82547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b67ffffffffffffffff9283160217909255925116600090815260086020908152604080832094835293905291909120429055506001016108fc565b507fd7868a16facbdde7b5c020620136316b3c266fffcb4e1e41cb6a662fe14ba3e181604051610c3a91906154e9565b60405180910390a1610cb660008a8a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c9182918501908490808284376000920191909152508b9250611972915050565b505050505050505050565b610d01610cd082840184615541565b6040805160008082526020820190925290610cfb565b6060815260200190600190039081610ce65790505b5061185b565b604080516000808252602082019092529050610d24600185858585866000611972565b50505050565b6000610d3860016004615576565b6002610d4560808561559f565b67ffffffffffffffff16610d5991906155c6565b610d638585611ce9565b901c166003811115610d7757610d77614a70565b90505b92915050565b6001546001600160a01b03163314610dda5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106f8565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e46611480565b61058181611d30565b333014610e88576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281610ec5565b6040805180820190915260008082526020820152815260200190600190039081610e9e5790505b5060a08501515190915015610ef957610ef68460a00151856020015186606001518760000151602001518787611e96565b90505b6040805160a0810182528551518152855160209081015167ffffffffffffffff1681830152808701518351600094840192610f3592910161488b565b60408051601f19818403018152918152908252878101516020830152018390526005549091506001600160a01b03168015611042576040517f08d450a10000000000000000000000000000000000000000000000000000000081526001600160a01b038216906308d450a190610faf90859060040161567f565b600060405180830381600087803b158015610fc957600080fd5b505af1925050508015610fda575060015b611042573d808015611008576040519150601f19603f3d011682016040523d82523d6000602084013e61100d565b606091505b50806040517f09c253250000000000000000000000000000000000000000000000000000000081526004016106f8919061488b565b60408601515115801561105757506080860151155b8061106e575060608601516001600160a01b03163b155b806110ae575060608601516110ac906001600160a01b03167f85572ffb00000000000000000000000000000000000000000000000000000000611fb5565b155b156110bb57505050505050565b855160209081015167ffffffffffffffff1660009081526006909152604080822054608089015160608a015192517f3cf9798300000000000000000000000000000000000000000000000000000000815284936001600160a01b0390931692633cf97983926111339289926113889291600401615692565b6000604051808303816000875af1158015611152573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261117a91908101906156ce565b5091509150816111b857806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016106f8919061488b565b5050505050505050565b6112056040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c0820152948552918201805484518184028101840190955280855292938583019390928301828280156112ae57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611290575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561131057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112f2575b5050505050815250509050919050565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff878116845260068352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b9092049092169483019490945260018401805493949293918401916113ad90615764565b80601f01602080910402602001604051908101604052809291908181526020018280546113d990615764565b80156113105780601f106113fb57610100808354040283529160200191611310565b820191906000526020600020905b81548152906001019060200180831161140957505050919092525091949350505050565b611435611480565b61058181611fd1565b611446611480565b60005b815181101561147c5761147482828151811061146757611467614f03565b6020026020010151612087565b600101611449565b5050565b6000546001600160a01b031633146114da5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106f8565b565b60005b815181101561147c5760008282815181106114fc576114fc614f03565b602002602001015190506000816020015190508067ffffffffffffffff16600003611553576040517fc656089500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516001600160a01b031661157b576040516342bcdf7f60e11b815260040160405180910390fd5b67ffffffffffffffff811660009081526006602052604081206001810180549192916115a690615764565b80601f01602080910402602001604051908101604052809291908181526020018280546115d290615764565b801561161f5780601f106115f45761010080835404028352916020019161161f565b820191906000526020600020905b81548152906001019060200180831161160257829003601f168201915b5050505050905060008460600151905081516000036116d757805160000361165a576040516342bcdf7f60e11b815260040160405180910390fd5b6001830161166882826157ee565b5082547fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff16600160a81b17835560405167ffffffffffffffff851681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a161172a565b808051906020012082805190602001201461172a576040517fc39a620500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024016106f8565b604080860151845487516001600160a01b031673ffffffffffffffffffffffffffffffffffffffff19921515600160a01b02929092167fffffffffffffffffffffff000000000000000000000000000000000000000000909116171784555167ffffffffffffffff8516907f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b906117c29086906158ae565b60405180910390a250505050508060010190506114df565b467f0000000000000000000000000000000000000000000000000000000000000000146114da576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016106f8565b8151600003611895576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160408051600080825260208201909252911591905b8451811015611904576118fc8582815181106118ca576118ca614f03565b6020026020010151846118f6578583815181106118e9576118e9614f03565b60200260200101516123b8565b836123b8565b6001016118ac565b5050505050565b67ffffffffffffffff811660009081526006602052604081208054600160a01b900460ff16610d7a576040517fed053c5900000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016106f8565b60ff878116600090815260026020908152604080832081516080810183528154815260019091015480861693820193909352610100830485169181019190915262010000909104909216151560608301528735906119d18760a461597c565b9050826060015115611a195784516119ea9060206155c6565b86516119f79060206155c6565b611a029060a061597c565b611a0c919061597c565b611a16908261597c565b90505b368114611a5b576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016106f8565b5081518114611aa35781516040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016106f8565b611aab6117da565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611af957611af9614a70565b6002811115611b0a57611b0a614a70565b9052509050600281602001516002811115611b2757611b27614a70565b148015611b7b5750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611b6357611b63614f03565b6000918252602090912001546001600160a01b031633145b611bb1576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50816060015115611c93576020820151611bcc90600161598f565b60ff16855114611c08576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351855114611c43576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008787604051611c559291906159a8565b604051908190038120611c6c918b906020016159b8565b604051602081830303815290604052805190602001209050611c918a82888888612cc8565b505b6040805182815260208a81013567ffffffffffffffff169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b67ffffffffffffffff8216600090815260076020526040812081611d0e6080856159cc565b67ffffffffffffffff1681526020810191909152604001600020549392505050565b80516001600160a01b0316611d58576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516060808b0180516001600160a01b039b8c167fffffffffffffffff000000000000000000000000000000000000000000000000909a168a17600160a01b63ffffffff988916021777ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000948816949094026001600160e01b031693909317600160e01b93871693909302929092179098556080808b0180516005805473ffffffffffffffffffffffffffffffffffffffff1916918d169190911790558451988952955185169688019690965290518316918601919091525116938301939093529151909216908201527fa55bd56595c45f517e5967a3067f3dca684445a3080e7c04a4e0d5a40cda627d9060a00160405180910390a150565b6060865167ffffffffffffffff811115611eb257611eb2613e9d565b604051908082528060200260200182016040528015611ef757816020015b6040805180820190915260008082526020820152815260200190600190039081611ed05790505b50905060005b8751811015611fa957611f84888281518110611f1b57611f1b614f03565b6020026020010151888888888887818110611f3857611f38614f03565b9050602002810190611f4a91906159f3565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612ead92505050565b828281518110611f9657611f96614f03565b6020908102919091010152600101611efd565b505b9695505050505050565b6000611fc083613252565b8015610d775750610d7783836132b6565b336001600160a01b038216036120295760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106f8565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036120b2576000604051631b3fab5160e11b81526004016106f89190615a3a565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361211f57606084015160018201805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055612174565b6060840151600182015460ff6201000090910416151590151514612174576040517f87f6037c00000000000000000000000000000000000000000000000000000000815260ff841660048201526024016106f8565b60a0840151805161010010156121a0576001604051631b3fab5160e11b81526004016106f89190615a3a565b61220684846003018054806020026020016040519081016040528092919081815260200182805480156121fc57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116121de575b5050505050613371565b84606001511561232d5761227484846002018054806020026020016040519081016040528092919081815260200182805480156121fc576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116121de575050505050613371565b6080850151805161010010156122a0576002604051631b3fab5160e11b81526004016106f89190615a3a565b60408601516122b0906003615a54565b60ff168151116122d6576003604051631b3fab5160e11b81526004016106f89190615a3a565b80516001840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff84160217905561231e9060028601906020840190613e16565b5061232b858260016133da565b505b612339848260026133da565b805161234e9060038501906020840190613e16565b5060408581015160018401805460ff191660ff8316179055865180855560a088015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936123a79389939260028a01929190615a70565b60405180910390a16119048461354e565b815181516040517f2cbc26bb000000000000000000000000000000000000000000000000000000008152608083901b77ffffffffffffffff00000000000000000000000000000000166004820152901515907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa15801561245b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247f919061548e565b1561250b5780156124c8576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff831660048201526024016106f8565b60405167ffffffffffffffff831681527faab522ed53d887e56ed53dd37398a01aeef6a58e0fa77c2173beb9512d8949339060200160405180910390a150505050565b60006125168361190b565b600101805461252490615764565b80601f016020809104026020016040519081016040528092919081815260200182805461255090615764565b801561259d5780601f106125725761010080835404028352916020019161259d565b820191906000526020600020905b81548152906001019060200180831161258057829003601f168201915b505050602088015151929350505060008190036125e5576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560400151518114612623576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff81111561263e5761263e613e9d565b604051908082528060200260200182016040528015612667578160200160208202803683370190505b50905060005b828110156127505760008860200151828151811061268d5761268d614f03565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681600001516040015167ffffffffffffffff161461272057805160409081015190517f38432a2200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016106f8565b61272a818661356a565b83838151811061273c5761273c614f03565b60209081029190910101525060010161266d565b50600061276786838a606001518b6080015161368c565b9050806000036127af576040517f7dd17a7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff871660048201526024016106f8565b60005b83811015610cb65760005a905060008a6020015183815181106127d7576127d7614f03565b6020026020010151905060006127f58a836000015160600151610d2a565b9050600081600381111561280b5761280b614a70565b14806128285750600381600381111561282657612826614a70565b145b612880578151606001516040805167ffffffffffffffff808e16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c91015b60405180910390a1505050612cc0565b881561295057600454600090600160a01b900463ffffffff166128a38742615576565b11905080806128c3575060038260038111156128c1576128c1614a70565b145b612905576040517fa9cfc86200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8c1660048201526024016106f8565b8b858151811061291757612917614f03565b602002602001015160001461294a578b858151811061293857612938614f03565b60200260200101518360800181815250505b506129b1565b600081600381111561296457612964614a70565b146129b1578151606001516040805167ffffffffffffffff808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe651209101612870565b81516080015167ffffffffffffffff1615612aa05760008160038111156129da576129da614a70565b03612aa05781516080015160208301516040517fe0e03cae0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612a51928f929190600401615b1c565b6020604051808303816000875af1158015612a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a94919061548e565b612aa057505050612cc0565b60008c604001518581518110612ab857612ab8614f03565b6020026020010151905080518360a001515114612b1c578251606001516040517f1cfe6d8b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808e16600483015290911660248201526044016106f8565b612b308b84600001516060015160016136ca565b600080612b3d8584613772565b91509150612b548d866000015160600151846136ca565b8b15612bc4576003826003811115612b6e57612b6e614a70565b03612bc4576000846003811115612b8757612b87614a70565b14612bc4578451516040517f2b11b8d90000000000000000000000000000000000000000000000000000000081526106f891908390600401615b49565b6002826003811115612bd857612bd8614a70565b14612c32576003826003811115612bf157612bf1614a70565b14612c32578451606001516040517f926c5a3e0000000000000000000000000000000000000000000000000000000081526106f8918f918590600401615b62565b84600001516000015185600001516060015167ffffffffffffffff168e67ffffffffffffffff167f05665fe9ad095383d018353f4cbcba77e84db27dd215081bbf7cdf9ae6fbe48b8c8b81518110612c8c57612c8c614f03565b602002602001015186865a612ca1908e615576565b604051612cb19493929190615b88565b60405180910390a45050505050505b6001016127b2565b8251600090815b818110156111b8576000600188868460208110612cee57612cee614f03565b612cfb91901a601b61598f565b898581518110612d0d57612d0d614f03565b6020026020010151898681518110612d2757612d27614f03565b602002602001015160405160008152602001604052604051612d65949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612d87573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b03851683528152858220858701909652855480841686529397509095509293928401916101009004166002811115612de857612de8614a70565b6002811115612df957612df9614a70565b9052509050600181602001516002811115612e1657612e16614a70565b14612e4d576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600160ff9091161b851615612e90576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000015160ff166001901b851794505050806001019050612ccf565b60408051808201909152600080825260208201526000612ed0876020015161383c565b6040517fbbe4f6db0000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063bbe4f6db90602401602060405180830381865afa158015612f55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f799190615bbf565b90506001600160a01b0381161580612fc15750612fbf6001600160a01b0382167faff2afbf00000000000000000000000000000000000000000000000000000000611fb5565b155b15613003576040517fae9b4ce90000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016106f8565b60045460009081906130259089908690600160e01b900463ffffffff166138e2565b9150915060008060006130f26040518061010001604052808e81526020018c67ffffffffffffffff1681526020018d6001600160a01b031681526020018f606001518152602001896001600160a01b031681526020018f6000015181526020018f6040015181526020018b8152506040516024016130a39190615bdc565b60408051601f198184030181529190526020810180516001600160e01b03167f390775370000000000000000000000000000000000000000000000000000000017905287866113886084613a10565b9250925092508261313157816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106f8919061488b565b81516020146131795781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106f8565b60008280602001905181019061318f9190615ca9565b9050866001600160a01b03168c6001600160a01b0316146132245760006131c08d8a6131bb868a615576565b6138e2565b509050868110806131da5750816131d78883615576565b14155b15613222576040517fa966e21f0000000000000000000000000000000000000000000000000000000081526004810183905260248101889052604481018290526064016106f8565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b600061327e827f01ffc9a7000000000000000000000000000000000000000000000000000000006132b6565b8015610d7a57506132af827fffffffff000000000000000000000000000000000000000000000000000000006132b6565b1592915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000082166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d9150600051905082801561335a575060208210155b80156133665750600081115b979650505050505050565b60005b81518110156107245760ff8316600090815260036020526040812083519091908490849081106133a6576133a6614f03565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613374565b60005b8251811015610d245760008382815181106133fa576133fa614f03565b602002602001015190506000600281111561341757613417614a70565b60ff80871660009081526003602090815260408083206001600160a01b0387168452909152902054610100900416600281111561345657613456614a70565b14613477576004604051631b3fab5160e11b81526004016106f89190615a3a565b6001600160a01b0381166134b7576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156134dd576134dd614a70565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561353a5761353a614a70565b0217905550905050508060010190506133dd565b60ff8116610581576009805467ffffffffffffffff1916905550565b8151602080820151604092830151925160009384936135b0937f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f93909291889101615cc2565b60408051601f1981840301815290829052805160209182012086518051888401516060808b0151908401516080808d015195015195976135f99794969395929491939101615cf5565b604051602081830303815290604052805190602001208560400151805190602001208660a001516040516020016136309190615dfa565b60408051601f198184030181528282528051602091820120908301969096528101939093526060830191909152608082015260a081019190915260c0015b60405160208183030381529060405280519060200120905092915050565b60008061369a858585613b36565b67ffffffffffffffff8716600090815260086020908152604080832093835292905220549150505b949350505050565b600060026136d960808561559f565b67ffffffffffffffff166136ed91906155c6565b905060006136fb8585611ce9565b90508161370a60016004615576565b901b19168183600381111561372157613721614a70565b67ffffffffffffffff871660009081526007602052604081209190921b929092179182916137506080886159cc565b67ffffffffffffffff1681526020810191909152604001600020555050505050565b6040517fa80036b4000000000000000000000000000000000000000000000000000000008152600090606090309063a80036b4906137b69087908790600401615e5a565b600060405180830381600087803b1580156137d057600080fd5b505af19250505080156137e1575060015b613820573d80801561380f576040519150601f19603f3d011682016040523d82523d6000602084013e613814565b606091505b50600392509050613835565b50506040805160208101909152600081526002905b9250929050565b6000815160201461387b57816040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106f8919061488b565b6000828060200190518101906138919190615ca9565b90506001600160a01b038111806138a9575061040081105b15610d7a57826040517f8d666f600000000000000000000000000000000000000000000000000000000081526004016106f8919061488b565b600080600080600061395c8860405160240161390d91906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03167f70a082310000000000000000000000000000000000000000000000000000000017905288886113886084613a10565b9250925092508261399b57816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016106f8919061488b565b60208251146139e35781516040517f78ef80240000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016106f8565b818060200190518101906139f79190615ca9565b613a018288615576565b94509450505050935093915050565b6000606060008361ffff1667ffffffffffffffff811115613a3357613a33613e9d565b6040519080825280601f01601f191660200182016040528015613a5d576020820181803683370190505b509150863b613a90577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a85811015613ac3577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b8590036040810481038710613afc577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d84811115613b1f5750835b808352806000602085013e50955095509592505050565b8251825160009190818303613b77576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590613b8b57506101018111155b613ba8576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613bd2576040516309bde33960e01b815260040160405180910390fd5b80600003613bff5786600081518110613bed57613bed614f03565b60200260200101519350505050613dce565b60008167ffffffffffffffff811115613c1a57613c1a613e9d565b604051908082528060200260200182016040528015613c43578160200160208202803683370190505b50905060008080805b85811015613d6d5760006001821b8b811603613ca75788851015613c90578c5160018601958e918110613c8157613c81614f03565b60200260200101519050613cc9565b8551600185019487918110613c8157613c81614f03565b8b5160018401938d918110613cbe57613cbe614f03565b602002602001015190505b600089861015613cf9578d5160018701968f918110613cea57613cea614f03565b60200260200101519050613d1b565b8651600186019588918110613d1057613d10614f03565b602002602001015190505b82851115613d3c576040516309bde33960e01b815260040160405180910390fd5b613d468282613dd5565b878481518110613d5857613d58614f03565b60209081029190910101525050600101613c4c565b506001850382148015613d7f57508683145b8015613d8a57508581145b613da7576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613dbc57613dbc614f03565b60200260200101519750505050505050505b9392505050565b6000818310613ded57613de88284613df3565b610d77565b610d7783835b60408051600160208201529081018390526060810182905260009060800161366e565b828054828255906000526020600020908101928215613e78579160200282015b82811115613e78578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613e36565b50613e84929150613e88565b5090565b5b80821115613e845760008155600101613e89565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613ed657613ed6613e9d565b60405290565b60405160a0810167ffffffffffffffff81118282101715613ed657613ed6613e9d565b60405160c0810167ffffffffffffffff81118282101715613ed657613ed6613e9d565b6040805190810167ffffffffffffffff81118282101715613ed657613ed6613e9d565b6040516060810167ffffffffffffffff81118282101715613ed657613ed6613e9d565b604051601f8201601f1916810167ffffffffffffffff81118282101715613f9157613f91613e9d565b604052919050565b600067ffffffffffffffff821115613fb357613fb3613e9d565b5060051b60200190565b6001600160a01b038116811461058157600080fd5b803567ffffffffffffffff81168114613fea57600080fd5b919050565b801515811461058157600080fd5b8035613fea81613fef565b600067ffffffffffffffff82111561402257614022613e9d565b50601f01601f191660200190565b600082601f83011261404157600080fd5b813561405461404f82614008565b613f68565b81815284602083860101111561406957600080fd5b816020850160208301376000918101602001919091529392505050565b6000602080838503121561409957600080fd5b823567ffffffffffffffff808211156140b157600080fd5b818501915085601f8301126140c557600080fd5b81356140d361404f82613f99565b81815260059190911b830184019084810190888311156140f257600080fd5b8585015b838110156141985780358581111561410e5760008081fd5b86016080818c03601f19018113156141265760008081fd5b61412e613eb3565b8983013561413b81613fbd565b8152604061414a848201613fd2565b8b83015260608085013561415d81613fef565b8383015292840135928984111561417657600091508182fd5b6141848f8d86880101614030565b9083015250855250509186019186016140f6565b5098975050505050505050565b600060a082840312156141b757600080fd5b6141bf613edc565b9050813581526141d160208301613fd2565b60208201526141e260408301613fd2565b60408201526141f360608301613fd2565b606082015261420460808301613fd2565b608082015292915050565b8035613fea81613fbd565b600082601f83011261422b57600080fd5b8135602061423b61404f83613f99565b82815260059290921b8401810191818101908684111561425a57600080fd5b8286015b84811015611fa957803567ffffffffffffffff8082111561427f5760008081fd5b9088019060a0828b03601f19018113156142995760008081fd5b6142a1613edc565b87840135838111156142b35760008081fd5b6142c18d8a83880101614030565b825250604080850135848111156142d85760008081fd5b6142e68e8b83890101614030565b8a84015250606080860135858111156142ff5760008081fd5b61430d8f8c838a0101614030565b838501525060809150818601358184015250828501359250838311156143335760008081fd5b6143418d8a85880101614030565b90820152865250505091830191830161425e565b6000610140828403121561436857600080fd5b614370613eff565b905061437c83836141a5565b815260a082013567ffffffffffffffff8082111561439957600080fd5b6143a585838601614030565b602084015260c08401359150808211156143be57600080fd5b6143ca85838601614030565b60408401526143db60e0850161420f565b6060840152610100840135608084015261012084013591508082111561440057600080fd5b5061440d8482850161421a565b60a08301525092915050565b600082601f83011261442a57600080fd5b8135602061443a61404f83613f99565b82815260059290921b8401810191818101908684111561445957600080fd5b8286015b84811015611fa957803567ffffffffffffffff81111561447d5760008081fd5b61448b8986838b0101614355565b84525091830191830161445d565b600082601f8301126144aa57600080fd5b813560206144ba61404f83613f99565b82815260059290921b840181019181810190868411156144d957600080fd5b8286015b84811015611fa957803567ffffffffffffffff808211156144fd57600080fd5b818901915089603f83011261451157600080fd5b8582013561452161404f82613f99565b81815260059190911b830160400190878101908c83111561454157600080fd5b604085015b8381101561457a5780358581111561455d57600080fd5b61456c8f6040838a0101614030565b845250918901918901614546565b508752505050928401925083016144dd565b600082601f83011261459d57600080fd5b813560206145ad61404f83613f99565b8083825260208201915060208460051b8701019350868411156145cf57600080fd5b602086015b84811015611fa957803583529183019183016145d4565b600082601f8301126145fc57600080fd5b8135602061460c61404f83613f99565b82815260059290921b8401810191818101908684111561462b57600080fd5b8286015b84811015611fa957803567ffffffffffffffff808211156146505760008081fd5b9088019060a0828b03601f190181131561466a5760008081fd5b614672613edc565b61467d888501613fd2565b8152604080850135848111156146935760008081fd5b6146a18e8b83890101614419565b8a84015250606080860135858111156146ba5760008081fd5b6146c88f8c838a0101614499565b83850152506080915081860135858111156146e35760008081fd5b6146f18f8c838a010161458c565b918401919091525091909301359083015250835291830191830161462f565b600080604080848603121561472457600080fd5b833567ffffffffffffffff8082111561473c57600080fd5b614748878388016145eb565b945060209150818601358181111561475f57600080fd5b8601601f8101881361477057600080fd5b803561477e61404f82613f99565b81815260059190911b8201840190848101908a83111561479d57600080fd5b8584015b83811015614829578035868111156147b95760008081fd5b8501603f81018d136147cb5760008081fd5b878101356147db61404f82613f99565b81815260059190911b82018a0190898101908f8311156147fb5760008081fd5b928b01925b828410156148195783358252928a0192908a0190614800565b86525050509186019186016147a1565b50809750505050505050509250929050565b60005b8381101561485657818101518382015260200161483e565b50506000910152565b6000815180845261487781602086016020860161483b565b601f01601f19169290920160200192915050565b602081526000610d77602083018461485f565b8060608101831015610d7a57600080fd5b60008083601f8401126148c157600080fd5b50813567ffffffffffffffff8111156148d957600080fd5b60208301915083602082850101111561383557600080fd5b60008083601f84011261490357600080fd5b50813567ffffffffffffffff81111561491b57600080fd5b6020830191508360208260051b850101111561383557600080fd5b60008060008060008060008060e0898b03121561495257600080fd5b61495c8a8a61489e565b9750606089013567ffffffffffffffff8082111561497957600080fd5b6149858c838d016148af565b909950975060808b013591508082111561499e57600080fd5b6149aa8c838d016148f1565b909750955060a08b01359150808211156149c357600080fd5b506149d08b828c016148f1565b999c989b50969995989497949560c00135949350505050565b6000806000608084860312156149fe57600080fd5b614a08858561489e565b9250606084013567ffffffffffffffff811115614a2457600080fd5b614a30868287016148af565b9497909650939450505050565b60008060408385031215614a5057600080fd5b614a5983613fd2565b9150614a6760208401613fd2565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b60048110614a9657614a96614a70565b9052565b60208101610d7a8284614a86565b600060208284031215614aba57600080fd5b813567ffffffffffffffff811115614ad157600080fd5b820160a08185031215613dce57600080fd5b803563ffffffff81168114613fea57600080fd5b600060a08284031215614b0957600080fd5b614b11613edc565b8235614b1c81613fbd565b8152614b2a60208401614ae3565b6020820152614b3b60408401614ae3565b6040820152614b4c60608401614ae3565b60608201526080830135614b5f81613fbd565b60808201529392505050565b600080600060408486031215614b8057600080fd5b833567ffffffffffffffff80821115614b9857600080fd5b614ba487838801614355565b94506020860135915080821115614bba57600080fd5b50614a30868287016148f1565b803560ff81168114613fea57600080fd5b600060208284031215614bea57600080fd5b610d7782614bc7565b60008151808452602080850194506020840160005b83811015614c2d5781516001600160a01b031687529582019590820190600101614c08565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614c8760e0840182614bf3565b90506040840151601f198483030160c0850152614ca48282614bf3565b95945050505050565b60008060408385031215614cc057600080fd5b614cc983613fd2565b946020939093013593505050565b600060208284031215614ce957600080fd5b610d7782613fd2565b602081526001600160a01b03825116602082015260208201511515604082015267ffffffffffffffff6040830151166060820152600060608301516080808401526136c260a084018261485f565b600060208284031215614d5257600080fd5b8135613dce81613fbd565b600082601f830112614d6e57600080fd5b81356020614d7e61404f83613f99565b8083825260208201915060208460051b870101935086841115614da057600080fd5b602086015b84811015611fa9578035614db881613fbd565b8352918301918301614da5565b60006020808385031215614dd857600080fd5b823567ffffffffffffffff80821115614df057600080fd5b818501915085601f830112614e0457600080fd5b8135614e1261404f82613f99565b81815260059190911b83018401908481019088831115614e3157600080fd5b8585015b8381101561419857803585811115614e4c57600080fd5b860160c0818c03601f19011215614e635760008081fd5b614e6b613eff565b8882013581526040614e7e818401614bc7565b8a8301526060614e8f818501614bc7565b8284015260809150614ea2828501613ffd565b9083015260a08381013589811115614eba5760008081fd5b614ec88f8d83880101614d5d565b838501525060c0840135915088821115614ee25760008081fd5b614ef08e8c84870101614d5d565b9083015250845250918601918601614e35565b634e487b7160e01b600052603260045260246000fd5b80356001600160e01b0381168114613fea57600080fd5b600082601f830112614f4157600080fd5b81356020614f5161404f83613f99565b82815260069290921b84018101918181019086841115614f7057600080fd5b8286015b84811015611fa95760408189031215614f8d5760008081fd5b614f95613f22565b614f9e82613fd2565b8152614fab858301614f19565b81860152835291830191604001614f74565b600082601f830112614fce57600080fd5b81356020614fde61404f83613f99565b82815260059290921b84018101918181019086841115614ffd57600080fd5b8286015b84811015611fa957803567ffffffffffffffff808211156150225760008081fd5b9088019060a0828b03601f190181131561503c5760008081fd5b615044613edc565b61504f888501613fd2565b8152604061505e818601613fd2565b89830152606061506f818701613fd2565b8284015260809150818601358184015250828501359250838311156150945760008081fd5b6150a28d8a85880101614030565b908201528652505050918301918301615001565b600082601f8301126150c757600080fd5b813560206150d761404f83613f99565b82815260069290921b840181019181810190868411156150f657600080fd5b8286015b84811015611fa957604081890312156151135760008081fd5b61511b613f22565b8135815284820135858201528352918301916040016150fa565b6000602080838503121561514857600080fd5b823567ffffffffffffffff8082111561516057600080fd5b908401906060828703121561517457600080fd5b61517c613f45565b82358281111561518b57600080fd5b8301604081890381131561519e57600080fd5b6151a6613f22565b8235858111156151b557600080fd5b8301601f81018b136151c657600080fd5b80356151d461404f82613f99565b81815260069190911b8201890190898101908d8311156151f357600080fd5b928a01925b828410156152435785848f0312156152105760008081fd5b615218613f22565b843561522381613fbd565b8152615230858d01614f19565b818d0152825292850192908a01906151f8565b84525050508287013591508482111561525b57600080fd5b6152678a838501614f30565b8188015283525050828401358281111561528057600080fd5b61528c88828601614fbd565b858301525060408301359350818411156152a557600080fd5b6152b1878585016150b6565b60408201529695505050505050565b600082825180855260208086019550808260051b84010181860160005b8481101561535057858303601f190189528151805167ffffffffffffffff908116855285820151811686860152604080830151909116908501526060808201519085015260809081015160a09185018290529061533c8186018361485f565b9a86019a94505050908301906001016152dd565b5090979650505050505050565b60008151808452602080850194506020840160005b83811015614c2d578151805188528301518388015260409096019590820190600101615372565b6040815260006153ac60408301856152c0565b8281036020840152614ca4818561535d565b805160408084528151848201819052600092602091908201906060870190855b8181101561541557835180516001600160a01b031684528501516001600160e01b03168584015292840192918501916001016153de565b50508583015187820388850152805180835290840192506000918401905b8083101561546f578351805167ffffffffffffffff1683528501516001600160e01b031685830152928401926001929092019190850190615433565b50979650505050505050565b602081526000610d7760208301846153be565b6000602082840312156154a057600080fd5b8151613dce81613fef565b634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156154e2576154e26154ab565b5092915050565b60208152600082516060602084015261550560808401826153be565b90506020840151601f198085840301604086015261552383836152c0565b9250604086015191508085840301606086015250614ca4828261535d565b60006020828403121561555357600080fd5b813567ffffffffffffffff81111561556a57600080fd5b6136c2848285016145eb565b81810381811115610d7a57610d7a6154ab565b634e487b7160e01b600052601260045260246000fd5b600067ffffffffffffffff808416806155ba576155ba615589565b92169190910692915050565b8082028115828204841417610d7a57610d7a6154ab565b805182526000602067ffffffffffffffff81840151168185015260408084015160a0604087015261561160a087018261485f565b90506060850151868203606088015261562a828261485f565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561546f57835180516001600160a01b031683528601518683015292850192600192909201919084019061564d565b602081526000610d7760208301846155dd565b6080815260006156a560808301876155dd565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b6000806000606084860312156156e357600080fd5b83516156ee81613fef565b602085015190935067ffffffffffffffff81111561570b57600080fd5b8401601f8101861361571c57600080fd5b805161572a61404f82614008565b81815287602083850101111561573f57600080fd5b61575082602083016020860161483b565b809450505050604084015190509250925092565b600181811c9082168061577857607f821691505b60208210810361579857634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610724576000816000526020600020601f850160051c810160208610156157c75750805b601f850160051c820191505b818110156157e6578281556001016157d3565b505050505050565b815167ffffffffffffffff81111561580857615808613e9d565b61581c816158168454615764565b8461579e565b602080601f83116001811461585157600084156158395750858301515b600019600386901b1c1916600185901b1785556157e6565b600085815260208120601f198616915b8281101561588057888601518255948401946001909101908401615861565b508582101561589e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080835283546001600160a01b038116602085015260ff8160a01c161515604085015267ffffffffffffffff8160a81c1660608501525060018085016080808601526000815461590081615764565b8060a089015260c06001831660008114615921576001811461593d5761596d565b60ff19841660c08b015260c083151560051b8b0101945061596d565b85600052602060002060005b848110156159645781548c8201850152908801908901615949565b8b0160c0019550505b50929998505050505050505050565b80820180821115610d7a57610d7a6154ab565b60ff8181168382160190811115610d7a57610d7a6154ab565b8183823760009101908152919050565b828152606082602083013760800192915050565b600067ffffffffffffffff808416806159e7576159e7615589565b92169190910492915050565b6000808335601e19843603018112615a0a57600080fd5b83018035915067ffffffffffffffff821115615a2557600080fd5b60200191503681900382131561383557600080fd5b6020810160058310615a4e57615a4e614a70565b91905290565b60ff81811683821602908116908181146154e2576154e26154ab565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615ac85784546001600160a01b031683526001948501949284019201615aa3565b50508481036060860152865180825290820192508187019060005b81811015615b085782516001600160a01b031685529383019391830191600101615ae3565b50505060ff85166080850152509050611fab565b600067ffffffffffffffff808616835280851660208401525060606040830152614ca4606083018461485f565b8281526040602082015260006136c2604083018461485f565b67ffffffffffffffff848116825283166020820152606081016136c26040830184614a86565b848152615b986020820185614a86565b608060408201526000615bae608083018561485f565b905082606083015295945050505050565b600060208284031215615bd157600080fd5b8151613dce81613fbd565b6020815260008251610100806020850152615bfb61012085018361485f565b91506020850151615c18604086018267ffffffffffffffff169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615c5260a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615c6f848361485f565b935060c08701519150808685030160e0870152615c8c848361485f565b935060e0870151915080868503018387015250611fab838261485f565b600060208284031215615cbb57600080fd5b5051919050565b848152600067ffffffffffffffff808616602084015280851660408401525060806060830152611fab608083018461485f565b86815260c060208201526000615d0e60c083018861485f565b6001600160a01b039690961660408301525067ffffffffffffffff9384166060820152608081019290925290911660a09091015292915050565b600082825180855260208086019550808260051b84010181860160005b8481101561535057601f19868403018952815160a08151818652615d8b8287018261485f565b9150508582015185820387870152615da3828261485f565b91505060408083015186830382880152615dbd838261485f565b92505050606080830151818701525060808083015192508582038187015250615de6818361485f565b9a86019a9450505090830190600101615d65565b602081526000610d776020830184615d48565b60008282518085526020808601955060208260051b8401016020860160005b8481101561535057601f19868403018952615e4883835161485f565b98840198925090830190600101615e2c565b604081526000835180516040840152602081015167ffffffffffffffff80821660608601528060408401511660808601528060608401511660a08601528060808401511660c086015250505060208401516101408060e0850152615ec261018085018361485f565b91506040860151603f198086850301610100870152615ee1848361485f565b935060608801519150615f006101208701836001600160a01b03169052565b60808801518387015260a0880151925080868503016101608701525050615f278282615d48565b9150508281036020840152614ca48185615e0d56fea164736f6c6343000818000a", } var OffRampABI = OffRampMetaData.ABI @@ -456,28 +454,6 @@ func (_OffRamp *OffRampCallerSession) GetStaticConfig() (OffRampStaticConfig, er return _OffRamp.Contract.GetStaticConfig(&_OffRamp.CallOpts) } -func (_OffRamp *OffRampCaller) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { - var out []interface{} - err := _OffRamp.contract.Call(opts, &out, "isBlessed", root) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_OffRamp *OffRampSession) IsBlessed(root [32]byte) (bool, error) { - return _OffRamp.Contract.IsBlessed(&_OffRamp.CallOpts, root) -} - -func (_OffRamp *OffRampCallerSession) IsBlessed(root [32]byte) (bool, error) { - return _OffRamp.Contract.IsBlessed(&_OffRamp.CallOpts, root) -} - func (_OffRamp *OffRampCaller) LatestConfigDetails(opts *bind.CallOpts, ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) { var out []interface{} err := _OffRamp.contract.Call(opts, &out, "latestConfigDetails", ocrPluginType) @@ -616,18 +592,6 @@ func (_OffRamp *OffRampTransactorSession) ManuallyExecute(reports []InternalExec return _OffRamp.Contract.ManuallyExecute(&_OffRamp.TransactOpts, reports, gasLimitOverrides) } -func (_OffRamp *OffRampTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset []OffRampUnblessedRoot) (*types.Transaction, error) { - return _OffRamp.contract.Transact(opts, "resetUnblessedRoots", rootToReset) -} - -func (_OffRamp *OffRampSession) ResetUnblessedRoots(rootToReset []OffRampUnblessedRoot) (*types.Transaction, error) { - return _OffRamp.Contract.ResetUnblessedRoots(&_OffRamp.TransactOpts, rootToReset) -} - -func (_OffRamp *OffRampTransactorSession) ResetUnblessedRoots(rootToReset []OffRampUnblessedRoot) (*types.Transaction, error) { - return _OffRamp.Contract.ResetUnblessedRoots(&_OffRamp.TransactOpts, rootToReset) -} - func (_OffRamp *OffRampTransactor) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig OffRampDynamicConfig) (*types.Transaction, error) { return _OffRamp.contract.Transact(opts, "setDynamicConfig", dynamicConfig) } @@ -1793,6 +1757,123 @@ func (_OffRamp *OffRampFilterer) ParseSkippedAlreadyExecutedMessage(log types.Lo return event, nil } +type OffRampSkippedReportExecutionIterator struct { + Event *OffRampSkippedReportExecution + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffRampSkippedReportExecutionIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffRampSkippedReportExecution) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(OffRampSkippedReportExecution) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *OffRampSkippedReportExecutionIterator) Error() error { + return it.fail +} + +func (it *OffRampSkippedReportExecutionIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffRampSkippedReportExecution struct { + SourceChainSelector uint64 + Raw types.Log +} + +func (_OffRamp *OffRampFilterer) FilterSkippedReportExecution(opts *bind.FilterOpts) (*OffRampSkippedReportExecutionIterator, error) { + + logs, sub, err := _OffRamp.contract.FilterLogs(opts, "SkippedReportExecution") + if err != nil { + return nil, err + } + return &OffRampSkippedReportExecutionIterator{contract: _OffRamp.contract, event: "SkippedReportExecution", logs: logs, sub: sub}, nil +} + +func (_OffRamp *OffRampFilterer) WatchSkippedReportExecution(opts *bind.WatchOpts, sink chan<- *OffRampSkippedReportExecution) (event.Subscription, error) { + + logs, sub, err := _OffRamp.contract.WatchLogs(opts, "SkippedReportExecution") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OffRampSkippedReportExecution) + if err := _OffRamp.contract.UnpackLog(event, "SkippedReportExecution", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_OffRamp *OffRampFilterer) ParseSkippedReportExecution(log types.Log) (*OffRampSkippedReportExecution, error) { + event := new(OffRampSkippedReportExecution) + if err := _OffRamp.contract.UnpackLog(event, "SkippedReportExecution", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type OffRampSourceChainConfigSetIterator struct { Event *OffRampSourceChainConfigSet @@ -2304,6 +2385,8 @@ func (_OffRamp *OffRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { return _OffRamp.ParseRootRemoved(log) case _OffRamp.abi.Events["SkippedAlreadyExecutedMessage"].ID: return _OffRamp.ParseSkippedAlreadyExecutedMessage(log) + case _OffRamp.abi.Events["SkippedReportExecution"].ID: + return _OffRamp.ParseSkippedReportExecution(log) case _OffRamp.abi.Events["SourceChainConfigSet"].ID: return _OffRamp.ParseSourceChainConfigSet(log) case _OffRamp.abi.Events["SourceChainSelectorAdded"].ID: @@ -2323,7 +2406,7 @@ func (OffRampAlreadyAttempted) Topic() common.Hash { } func (OffRampCommitReportAccepted) Topic() common.Hash { - return common.HexToHash("0x3a3950e13dd607cc37980db0ef14266c40d2bba9c01b2e44bfe549808883095d") + return common.HexToHash("0xd7868a16facbdde7b5c020620136316b3c266fffcb4e1e41cb6a662fe14ba3e1") } func (OffRampConfigSet) Topic() common.Hash { @@ -2354,6 +2437,10 @@ func (OffRampSkippedAlreadyExecutedMessage) Topic() common.Hash { return common.HexToHash("0x3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c") } +func (OffRampSkippedReportExecution) Topic() common.Hash { + return common.HexToHash("0xaab522ed53d887e56ed53dd37398a01aeef6a58e0fa77c2173beb9512d894933") +} + func (OffRampSourceChainConfigSet) Topic() common.Hash { return common.HexToHash("0x49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b") } @@ -2389,8 +2476,6 @@ type OffRampInterface interface { GetStaticConfig(opts *bind.CallOpts) (OffRampStaticConfig, error) - IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) - LatestConfigDetails(opts *bind.CallOpts, ocrPluginType uint8) (MultiOCR3BaseOCRConfig, error) Owner(opts *bind.CallOpts) (common.Address, error) @@ -2409,8 +2494,6 @@ type OffRampInterface interface { ManuallyExecute(opts *bind.TransactOpts, reports []InternalExecutionReportSingleChain, gasLimitOverrides [][]*big.Int) (*types.Transaction, error) - ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset []OffRampUnblessedRoot) (*types.Transaction, error) - SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig OffRampDynamicConfig) (*types.Transaction, error) SetOCR3Configs(opts *bind.TransactOpts, ocrConfigArgs []MultiOCR3BaseOCRConfigArgs) (*types.Transaction, error) @@ -2471,6 +2554,12 @@ type OffRampInterface interface { ParseSkippedAlreadyExecutedMessage(log types.Log) (*OffRampSkippedAlreadyExecutedMessage, error) + FilterSkippedReportExecution(opts *bind.FilterOpts) (*OffRampSkippedReportExecutionIterator, error) + + WatchSkippedReportExecution(opts *bind.WatchOpts, sink chan<- *OffRampSkippedReportExecution) (event.Subscription, error) + + ParseSkippedReportExecution(log types.Log) (*OffRampSkippedReportExecution, error) + FilterSourceChainConfigSet(opts *bind.FilterOpts, sourceChainSelector []uint64) (*OffRampSourceChainConfigSetIterator, error) WatchSourceChainConfigSet(opts *bind.WatchOpts, sink chan<- *OffRampSourceChainConfigSet, sourceChainSelector []uint64) (event.Subscription, error) diff --git a/core/gethwrappers/ccip/generated/onramp/onramp.go b/core/gethwrappers/ccip/generated/onramp/onramp.go index dd2428a143..776f945650 100644 --- a/core/gethwrappers/ccip/generated/onramp/onramp.go +++ b/core/gethwrappers/ccip/generated/onramp/onramp.go @@ -91,14 +91,14 @@ type OnRampDynamicConfig struct { type OnRampStaticConfig struct { ChainSelector uint64 - RmnProxy common.Address + Rmn common.Address NonceManager common.Address TokenAdminRegistry common.Address } var OnRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidAllowListRequest\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAllowlistAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"name\":\"AllowListAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"senders\",\"type\":\"address[]\"}],\"name\":\"AllowListSendersAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"senders\",\"type\":\"address[]\"}],\"name\":\"AllowListSendersRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowListEnabled\",\"type\":\"bool\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowListEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"addedAllowlistedSenders\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedAllowlistedSenders\",\"type\":\"address[]\"}],\"internalType\":\"structOnRamp.AllowListConfigArgs[]\",\"name\":\"allowListConfigArgsItems\",\"type\":\"tuple[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowListEnabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b506040516200407338038062004073833981016040819052620000359162000665565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000186565b505083516001600160401b031615905080620000e6575060208301516001600160a01b0316155b80620000fd575060408301516001600160a01b0316155b8062000114575060608301516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b82516001600160401b031660805260208301516001600160a01b0390811660a0526040840151811660c05260608401511660e052620001728262000231565b6200017d8162000390565b5050506200079f565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316158062000254575060408101516001600160a01b0316155b1562000273576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b0393841617909155602080840180516003805485169186169190911790556040808601805160048054871691881691909117905560608088018051600580549098169089161790965582516080808201855280516001600160401b031680835260a080518b16848a0190815260c080518d16868a0190815260e080518f169789019788528a5195865292518e169b85019b909b5299518c169783019790975292518a169381019390935289518916908301529351871693810193909352518516928201929092529151909216918101919091527f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32906101000160405180910390a150565b60005b8151811015620004cf576000828281518110620003b457620003b462000789565b602002602001015190506000838381518110620003d557620003d562000789565b6020026020010151600001519050806001600160401b03166000036200041a5760405163c35aa79d60e01b81526001600160401b038216600482015260240162000083565b6001600160401b03818116600081815260066020908152604091829020868201518154600160481b600160e81b0319811669010000000000000000006001600160a01b03909316928302908117808555865192891691909816178152928301526801000000000000000090940460ff161515918101919091527fd5ad72bc37dc7a80a8b9b9df20500046fd7341adb1be2258a540466fdd7dcef59060600160405180910390a250505080600101905062000393565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156200050e576200050e620004d3565b60405290565b604080519081016001600160401b03811182821017156200050e576200050e620004d3565b604051601f8201601f191681016001600160401b0381118282101715620005645762000564620004d3565b604052919050565b80516001600160401b03811681146200058457600080fd5b919050565b6001600160a01b03811681146200059f57600080fd5b50565b600082601f830112620005b457600080fd5b815160206001600160401b03821115620005d257620005d2620004d3565b620005e2818360051b0162000539565b82815260069290921b840181019181810190868411156200060257600080fd5b8286015b848110156200065a5760408189031215620006215760008081fd5b6200062b62000514565b62000636826200056c565b815284820151620006478162000589565b8186015283529183019160400162000606565b509695505050505050565b60008060008385036101208112156200067d57600080fd5b60808112156200068c57600080fd5b62000696620004e9565b620006a1866200056c565b81526020860151620006b38162000589565b60208201526040860151620006c88162000589565b60408201526060860151620006dd8162000589565b606082015293506080607f1982011215620006f757600080fd5b5062000702620004e9565b6080850151620007128162000589565b815260a0850151620007248162000589565b602082015260c0850151620007398162000589565b604082015260e08501516200074e8162000589565b60608201526101008501519092506001600160401b038111156200077157600080fd5b6200077f86828701620005a2565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e05161385b620008186000396000818161022c01528181610c790152611beb0152600081816101f0015281816112480152611bc40152600081816101b4015281816105de0152611b9a0152600081816101840152818161116e015281816116930152611b6d015261385b6000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c806379ba5097116100b2578063a6f3ab6c11610081578063df0aa9e911610066578063df0aa9e91461052d578063f2fde38b14610540578063fbca3b741461055357600080fd5b8063a6f3ab6c146104cd578063d77d5ed0146104e057600080fd5b806379ba50971461045b5780638da5cb5b146104635780639041be3d14610481578063972b4612146104ad57600080fd5b806334adf4941161010957806348a98aa4116100ee57806348a98aa4146103045780636def4ce71461033c5780637437ff9f146103db57600080fd5b806334adf494146102e95780633a019940146102fc57600080fd5b80630242cf601461013b57806306285c6914610150578063181f5a771461027f57806320487ded146102c8575b600080fd5b61014e6101493660046126e0565b610566565b005b61026960408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161027691906127a3565b60405180910390f35b6102bb6040518060400160405280601081526020017f4f6e52616d7020312e362e302d6465760000000000000000000000000000000081525081565b6040516102769190612868565b6102db6102d6366004612893565b61057a565b604051908152602001610276565b61014e6102f73660046128e3565b610733565b61014e610a06565b610317610312366004612958565b610c31565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610276565b61039f61034a366004612991565b67ffffffffffffffff9081166000908152600660205260409020549081169168010000000000000000820460ff16916901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b6040805167ffffffffffffffff9094168452911515602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610276565b61044e604080516080810182526000808252602082018190529181018290526060810191909152506040805160808101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454811692820192909252600554909116606082015290565b60405161027691906129ae565b61014e610ce6565b60005473ffffffffffffffffffffffffffffffffffffffff16610317565b61049461048f366004612991565b610de3565b60405167ffffffffffffffff9091168152602001610276565b6104c06104bb366004612991565b610e0c565b60405161027691906129f7565b61014e6104db366004612a61565b610e34565b6103176104ee366004612991565b67ffffffffffffffff166000908152600660205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b6102db61053b366004612ac8565b610e45565b61014e61054e366004612b34565b611748565b6104c0610561366004612991565b611759565b61056e61178d565b61057781611810565b50565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa158015610625573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106499190612b5f565b15610691576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6002546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd906106e99086908690600401612c90565b602060405180830381865afa158015610706573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072a9190612dd9565b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107a35760055473ffffffffffffffffffffffffffffffffffffffff1633146107a3576040517f905d7d9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610a015760008383838181106107c2576107c2612df2565b90506020028101906107d49190612e21565b6107dd90612ed2565b805167ffffffffffffffff1660009081526006602090815260409091209082015181547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000009115801592909202178255919250906109545760005b8260400151518110156108fd5760008360400151828151811061086757610867612df2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036108e65783516040517f463258ff00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610688565b6108f36001840182611987565b5050600101610842565b506040820151511561095457816000015167ffffffffffffffff167f330939f6eafe8bb516716892fe962ff19770570838686e6579dbc1cc51fc3281836040015160405161094b91906129f7565b60405180910390a25b60005b8260600151518110156109a0576109978360600151828151811061097d5761097d612df2565b6020026020010151836001016119a990919063ffffffff16565b50600101610957565b50606082015151156109f757816000015167ffffffffffffffff167fc237ec1921f855ccd5e9a5af9733f2d58943a5a8501ec5988e305d7a4d42158683606001516040516109ee91906129f7565b60405180910390a25b50506001016107a6565b505050565b600254604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610a75573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610abb9190810190612f65565b60045490915073ffffffffffffffffffffffffffffffffffffffff1660005b8251811015610a01576000838281518110610af757610af7612df2565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610b72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b969190612dd9565b90508015610c2757610bbf73ffffffffffffffffffffffffffffffffffffffff831685836119cb565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e83604051610c1e91815260200190565b60405180910390a35b5050600101610ada565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610cc2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072a9190612ff4565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610688565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff808216600090815260066020526040812054909161072d91166001613040565b67ffffffffffffffff8116600090815260066020526040902060609061072d90600101611a58565b610e3c61178d565b61057781611a6c565b67ffffffffffffffff8416600090815260066020526040812073ffffffffffffffffffffffffffffffffffffffff8316610eab576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805468010000000000000000900460ff1615610f1c57610ece6001820184611c4e565b610f1c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610688565b80546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610f79576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035473ffffffffffffffffffffffffffffffffffffffff16801561101f576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610fec908a908a90600401612c90565b600060405180830381600087803b15801561100657600080fd5b505af115801561101a573d6000803e3d6000fd5b505050505b506002546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a61105660808c0160608d01612b34565b8a61106460808e018e613061565b6040518663ffffffff1660e01b81526004016110849594939291906130c6565b600060405180830381865afa1580156110a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110e7919081019061318e565b919450925090506110fe6080890160608a01612b34565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f8460405161114591815260200190565b60405180910390a2604080516101a081019091526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528c811661014085015287549293928392916101608401918a9187916111ba91166131e8565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff168152602001866112ba576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015611291573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b5919061320f565b6112bd565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a80602001906112fb9190613061565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200161133f8b80613061565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200161138660808c018c613061565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050908252506020016113d060808c0160608d01612b34565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190611401919061322c565b905067ffffffffffffffff81111561141b5761141b6125ba565b60405190808252806020026020018201604052801561147e57816020015b61146b6040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b8152602001906001900390816114395790505b509052905060005b61149360408b018b61322c565b9050811015611542576115196114ac60408c018c61322c565b838181106114bc576114bc612df2565b9050604002018036038101906114d29190613294565b8c6114dd8d80613061565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e9250611c7d915050565b8260e00151828151811061152f5761152f612df2565b6020908102919091010152600101611486565b5060025460e082015160009173ffffffffffffffffffffffffffffffffffffffff169063085318f8908d9061157a60408f018f61322c565b6040518563ffffffff1660e01b815260040161159994939291906133ab565b600060405180830381865afa1580156115b6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526115fc91908101906133e1565b905060005b8260e00151518110156116555781818151811061162057611620612df2565b60200260200101518360e00151828151811061163e5761163e612df2565b602090810291909101015160800152600101611601565b506080808301849052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908d16606082015230918101919091526116ef90839060a00160405160208183030381529060405280519060200120611fa3565b82515260405167ffffffffffffffff8c16907fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c931409061172e908590613492565b60405180910390a25051519450505050505b949350505050565b61175061178d565b610577816120a3565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461180e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610688565b565b60005b815181101561198357600082828151811061183057611830612df2565b60200260200101519050600083838151811061184e5761184e612df2565b60200260200101516000015190508067ffffffffffffffff166000036118ac576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610688565b67ffffffffffffffff8181166000818152600660209081526040918290208682015181547fffffff0000000000000000000000000000000000000000ffffffffffffffffff8116690100000000000000000073ffffffffffffffffffffffffffffffffffffffff909316928302908117808555865192891691909816178152928301526801000000000000000090940460ff161515918101919091527fd5ad72bc37dc7a80a8b9b9df20500046fd7341adb1be2258a540466fdd7dcef59060600160405180910390a2505050806001019050611813565b5050565b600061072a8373ffffffffffffffffffffffffffffffffffffffff8416612198565b600061072a8373ffffffffffffffffffffffffffffffffffffffff84166121e7565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610a019084906122e1565b60606000611a65836123ed565b9392505050565b805173ffffffffffffffffffffffffffffffffffffffff161580611aa85750604081015173ffffffffffffffffffffffffffffffffffffffff16155b15611adf576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480548516918616919091179055606080860151600580549095169086161790935580516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008516928101929092527f00000000000000000000000000000000000000000000000000000000000000008416828201527f00000000000000000000000000000000000000000000000000000000000000009093169181019190915290517f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e3291611c439184906135e0565b60405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561072a565b611caf6040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b8460200151600003611ced576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611cfd858760000151610c31565b905073ffffffffffffffffffffffffffffffffffffffff81161580611dcd57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015611da7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dcb9190612b5f565b155b15611e1f5785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610688565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401611ebe919061367f565b6000604051808303816000875af1158015611edd573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611f2391908101906136f5565b6040805160a0810190915273ffffffffffffffffffffffffffffffffffffffff841660c08201529091508060e0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181526020016040518060200160405280600081525081525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c00151604051602001611fe596959493929190613786565b604051602081830303815290604052805190602001208560400151805190602001208660e0015160405160200161201c91906137e7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603612122576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610688565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120546121df5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561072d565b50600061072d565b600081815260018301602052604081205480156122d057600061220b6001836137fa565b855490915060009061221f906001906137fa565b905080821461228457600086600001828154811061223f5761223f612df2565b906000526020600020015490508087600001848154811061226257612262612df2565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806122955761229561380d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061072d565b600091505061072d565b5092915050565b6000612343826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166124499092919063ffffffff16565b805190915015610a0157808060200190518101906123619190612b5f565b610a01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610688565b60608160000180548060200260200160405190810160405280929190818152602001828054801561243d57602002820191906000526020600020905b815481526020019060010190808311612429575b50505050509050919050565b60606117408484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161247d919061383c565b60006040518083038185875af1925050503d80600081146124ba576040519150601f19603f3d011682016040523d82523d6000602084013e6124bf565b606091505b50915091506124d0878383876124db565b979650505050505050565b6060831561257157825160000361256a5773ffffffffffffffffffffffffffffffffffffffff85163b61256a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610688565b5081611740565b61174083838151156125865781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106889190612868565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561260c5761260c6125ba565b60405290565b6040516080810167ffffffffffffffff8111828210171561260c5761260c6125ba565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561267c5761267c6125ba565b604052919050565b600067ffffffffffffffff82111561269e5761269e6125ba565b5060051b60200190565b67ffffffffffffffff8116811461057757600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461057757600080fd5b600060208083850312156126f357600080fd5b823567ffffffffffffffff81111561270a57600080fd5b8301601f8101851361271b57600080fd5b803561272e61272982612684565b612635565b81815260069190911b8201830190838101908783111561274d57600080fd5b928401925b828410156124d0576040848903121561276b5760008081fd5b6127736125e9565b843561277e816126a8565b81528486013561278d816126be565b8187015282526040939093019290840190612752565b6080810161072d828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b838110156128155781810151838201526020016127fd565b50506000910152565b600081518084526128368160208601602086016127fa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061072a602083018461281e565b600060a0828403121561288d57600080fd5b50919050565b600080604083850312156128a657600080fd5b82356128b1816126a8565b9150602083013567ffffffffffffffff8111156128cd57600080fd5b6128d98582860161287b565b9150509250929050565b600080602083850312156128f657600080fd5b823567ffffffffffffffff8082111561290e57600080fd5b818501915085601f83011261292257600080fd5b81358181111561293157600080fd5b8660208260051b850101111561294657600080fd5b60209290920196919550909350505050565b6000806040838503121561296b57600080fd5b8235612976816126a8565b91506020830135612986816126be565b809150509250929050565b6000602082840312156129a357600080fd5b8135611a65816126a8565b6080810161072d8284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260408083015182169084015260609182015116910152565b6020808252825182820181905260009190848201906040850190845b81811015612a4557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612a13565b50909695505050505050565b8035612a5c816126be565b919050565b600060808284031215612a7357600080fd5b612a7b612612565b8235612a86816126be565b81526020830135612a96816126be565b60208201526040830135612aa9816126be565b60408201526060830135612abc816126be565b60608201529392505050565b60008060008060808587031215612ade57600080fd5b8435612ae9816126a8565b9350602085013567ffffffffffffffff811115612b0557600080fd5b612b118782880161287b565b935050604085013591506060850135612b29816126be565b939692955090935050565b600060208284031215612b4657600080fd5b8135611a65816126be565b801515811461057757600080fd5b600060208284031215612b7157600080fd5b8151611a6581612b51565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612bb157600080fd5b830160208101925035905067ffffffffffffffff811115612bd157600080fd5b803603821315612be057600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b85811015612c85578135612c53816126be565b73ffffffffffffffffffffffffffffffffffffffff168752818301358388015260409687019690910190600101612c40565b509495945050505050565b600067ffffffffffffffff808516835260406020840152612cb18485612b7c565b60a06040860152612cc660e086018284612be7565b915050612cd66020860186612b7c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080878503016060880152612d0c848385612be7565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1883603018312612d4557600080fd5b60209288019283019235915084821115612d5e57600080fd5b8160061b3603831315612d7057600080fd5b80878503016080880152612d85848385612c30565b9450612d9360608901612a51565b73ffffffffffffffffffffffffffffffffffffffff811660a08901529350612dbe6080890189612b7c565b94509250808786030160c088015250506124d0838383612be7565b600060208284031215612deb57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112612e5557600080fd5b9190910192915050565b600082601f830112612e7057600080fd5b81356020612e8061272983612684565b8083825260208201915060208460051b870101935086841115612ea257600080fd5b602086015b84811015612ec7578035612eba816126be565b8352918301918301612ea7565b509695505050505050565b600060808236031215612ee457600080fd5b612eec612612565b8235612ef7816126a8565b81526020830135612f0781612b51565b6020820152604083013567ffffffffffffffff80821115612f2757600080fd5b612f3336838701612e5f565b60408401526060850135915080821115612f4c57600080fd5b50612f5936828601612e5f565b60608301525092915050565b60006020808385031215612f7857600080fd5b825167ffffffffffffffff811115612f8f57600080fd5b8301601f81018513612fa057600080fd5b8051612fae61272982612684565b81815260059190911b82018301908381019087831115612fcd57600080fd5b928401925b828410156124d0578351612fe5816126be565b82529284019290840190612fd2565b60006020828403121561300657600080fd5b8151611a65816126be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156122da576122da613011565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261309657600080fd5b83018035915067ffffffffffffffff8211156130b157600080fd5b602001915036819003821315612be057600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff851660208201528360408201526080606082015260006124d0608083018486612be7565b600082601f83011261311d57600080fd5b815167ffffffffffffffff811115613137576131376125ba565b61316860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612635565b81815284602083860101111561317d57600080fd5b6117408260208301602087016127fa565b6000806000606084860312156131a357600080fd5b8351925060208401516131b581612b51565b604085015190925067ffffffffffffffff8111156131d257600080fd5b6131de8682870161310c565b9150509250925092565b600067ffffffffffffffff80831681810361320557613205613011565b6001019392505050565b60006020828403121561322157600080fd5b8151611a65816126a8565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261326157600080fd5b83018035915067ffffffffffffffff82111561327c57600080fd5b6020019150600681901b3603821315612be057600080fd5b6000604082840312156132a657600080fd5b6132ae6125e9565b82356132b9816126be565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b8481101561339e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160a0815181865261332f8287018261281e565b9150508582015185820387870152613347828261281e565b91505060408083015186830382880152613361838261281e565b9250505060608083015181870152506080808301519250858203818701525061338a818361281e565b9a86019a94505050908301906001016132eb565b5090979650505050505050565b67ffffffffffffffff851681526060602082015260006133ce60608301866132ce565b82810360408401526124d0818587612c30565b600060208083850312156133f457600080fd5b825167ffffffffffffffff8082111561340c57600080fd5b818501915085601f83011261342057600080fd5b815161342e61272982612684565b81815260059190911b8301840190848101908883111561344d57600080fd5b8585015b83811015613485578051858111156134695760008081fd5b6134778b89838a010161310c565b845250918601918601613451565b5098975050505050505050565b602081526134e360208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b6000602083015161350c60c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e08501526135296101a085018361281e565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301610100870152613566848361281e565b9350608087015191508086850301610120870152613584848361281e565b935060a087015191506135b061014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e08701519150808685030183870152506135d683826132ce565b9695505050505050565b6101008101613638828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a08401526040840151811660c084015260608401511660e0830152611a65565b602081526000825160a0602084015261369b60c084018261281e565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b60006020828403121561370757600080fd5b815167ffffffffffffffff8082111561371f57600080fd5b908301906040828603121561373357600080fd5b61373b6125e9565b82518281111561374a57600080fd5b6137568782860161310c565b82525060208301518281111561376b57600080fd5b6137778782860161310c565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c060208401526137b660c084018961281e565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b60208152600061072a60208301846132ce565b8181038181111561072d5761072d613011565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251612e558184602087016127fa56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRMNV2\",\"name\":\"rmn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidAllowListRequest\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAllowlistAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"name\":\"AllowListAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"senders\",\"type\":\"address[]\"}],\"name\":\"AllowListSendersAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"senders\",\"type\":\"address[]\"}],\"name\":\"AllowListSendersRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPMessageSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRMNV2\",\"name\":\"rmn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowListEnabled\",\"type\":\"bool\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowListEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"addedAllowlistedSenders\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedAllowlistedSenders\",\"type\":\"address[]\"}],\"internalType\":\"structOnRamp.AllowListConfigArgs[]\",\"name\":\"allowListConfigArgsItems\",\"type\":\"tuple[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowListEnabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRMNV2\",\"name\":\"rmn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b506040516200402938038062004029833981016040819052620000359162000665565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000186565b505083516001600160401b031615905080620000e6575060208301516001600160a01b0316155b80620000fd575060408301516001600160a01b0316155b8062000114575060608301516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b82516001600160401b031660805260208301516001600160a01b0390811660a0526040840151811660c05260608401511660e052620001728262000231565b6200017d8162000390565b5050506200079f565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316158062000254575060408101516001600160a01b0316155b1562000273576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b0393841617909155602080840180516003805485169186169190911790556040808601805160048054871691881691909117905560608088018051600580549098169089161790965582516080808201855280516001600160401b031680835260a080518b16848a0190815260c080518d16868a0190815260e080518f169789019788528a5195865292518e169b85019b909b5299518c169783019790975292518a169381019390935289518916908301529351871693810193909352518516928201929092529151909216918101919091527f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32906101000160405180910390a150565b60005b8151811015620004cf576000828281518110620003b457620003b462000789565b602002602001015190506000838381518110620003d557620003d562000789565b6020026020010151600001519050806001600160401b03166000036200041a5760405163c35aa79d60e01b81526001600160401b038216600482015260240162000083565b6001600160401b03818116600081815260066020908152604091829020868201518154600160481b600160e81b0319811669010000000000000000006001600160a01b03909316928302908117808555865192891691909816178152928301526801000000000000000090940460ff161515918101919091527fd5ad72bc37dc7a80a8b9b9df20500046fd7341adb1be2258a540466fdd7dcef59060600160405180910390a250505080600101905062000393565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156200050e576200050e620004d3565b60405290565b604080519081016001600160401b03811182821017156200050e576200050e620004d3565b604051601f8201601f191681016001600160401b0381118282101715620005645762000564620004d3565b604052919050565b80516001600160401b03811681146200058457600080fd5b919050565b6001600160a01b03811681146200059f57600080fd5b50565b600082601f830112620005b457600080fd5b815160206001600160401b03821115620005d257620005d2620004d3565b620005e2818360051b0162000539565b82815260069290921b840181019181810190868411156200060257600080fd5b8286015b848110156200065a5760408189031215620006215760008081fd5b6200062b62000514565b62000636826200056c565b815284820151620006478162000589565b8186015283529183019160400162000606565b509695505050505050565b60008060008385036101208112156200067d57600080fd5b60808112156200068c57600080fd5b62000696620004e9565b620006a1866200056c565b81526020860151620006b38162000589565b60208201526040860151620006c88162000589565b60408201526060860151620006dd8162000589565b606082015293506080607f1982011215620006f757600080fd5b5062000702620004e9565b6080850151620007128162000589565b815260a0850151620007248162000589565b602082015260c0850151620007398162000589565b604082015260e08501516200074e8162000589565b60608201526101008501519092506001600160401b038111156200077157600080fd5b6200077f86828701620005a2565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e051613811620008186000396000818161022c01528181610c790152611ba10152600081816101f0015281816112480152611b7a0152600081816101b4015281816105de0152611b500152600081816101840152818161116e0152818161164b0152611b2301526138116000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c806379ba5097116100b2578063a6f3ab6c11610081578063df0aa9e911610066578063df0aa9e91461052d578063f2fde38b14610540578063fbca3b741461055357600080fd5b8063a6f3ab6c146104cd578063d77d5ed0146104e057600080fd5b806379ba50971461045b5780638da5cb5b146104635780639041be3d14610481578063972b4612146104ad57600080fd5b806334adf4941161010957806348a98aa4116100ee57806348a98aa4146103045780636def4ce71461033c5780637437ff9f146103db57600080fd5b806334adf494146102e95780633a019940146102fc57600080fd5b80630242cf601461013b57806306285c6914610150578063181f5a771461027f57806320487ded146102c8575b600080fd5b61014e610149366004612696565b610566565b005b61026960408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102769190612759565b60405180910390f35b6102bb6040518060400160405280601081526020017f4f6e52616d7020312e362e302d6465760000000000000000000000000000000081525081565b604051610276919061281e565b6102db6102d6366004612849565b61057a565b604051908152602001610276565b61014e6102f7366004612899565b610733565b61014e610a06565b61031761031236600461290e565b610c31565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610276565b61039f61034a366004612947565b67ffffffffffffffff9081166000908152600660205260409020549081169168010000000000000000820460ff16916901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b6040805167ffffffffffffffff9094168452911515602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610276565b61044e604080516080810182526000808252602082018190529181018290526060810191909152506040805160808101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454811692820192909252600554909116606082015290565b6040516102769190612964565b61014e610ce6565b60005473ffffffffffffffffffffffffffffffffffffffff16610317565b61049461048f366004612947565b610de3565b60405167ffffffffffffffff9091168152602001610276565b6104c06104bb366004612947565b610e0c565b60405161027691906129ad565b61014e6104db366004612a17565b610e34565b6103176104ee366004612947565b67ffffffffffffffff166000908152600660205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b6102db61053b366004612a7e565b610e45565b61014e61054e366004612aea565b6116fe565b6104c0610561366004612947565b61170f565b61056e611743565b610577816117c6565b50565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa158015610625573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106499190612b15565b15610691576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6002546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd906106e99086908690600401612c46565b602060405180830381865afa158015610706573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072a9190612d8f565b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107a35760055473ffffffffffffffffffffffffffffffffffffffff1633146107a3576040517f905d7d9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610a015760008383838181106107c2576107c2612da8565b90506020028101906107d49190612dd7565b6107dd90612e88565b805167ffffffffffffffff1660009081526006602090815260409091209082015181547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000009115801592909202178255919250906109545760005b8260400151518110156108fd5760008360400151828151811061086757610867612da8565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036108e65783516040517f463258ff00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610688565b6108f3600184018261193d565b5050600101610842565b506040820151511561095457816000015167ffffffffffffffff167f330939f6eafe8bb516716892fe962ff19770570838686e6579dbc1cc51fc3281836040015160405161094b91906129ad565b60405180910390a25b60005b8260600151518110156109a0576109978360600151828151811061097d5761097d612da8565b60200260200101518360010161195f90919063ffffffff16565b50600101610957565b50606082015151156109f757816000015167ffffffffffffffff167fc237ec1921f855ccd5e9a5af9733f2d58943a5a8501ec5988e305d7a4d42158683606001516040516109ee91906129ad565b60405180910390a25b50506001016107a6565b505050565b600254604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610a75573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610abb9190810190612f1b565b60045490915073ffffffffffffffffffffffffffffffffffffffff1660005b8251811015610a01576000838281518110610af757610af7612da8565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610b72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b969190612d8f565b90508015610c2757610bbf73ffffffffffffffffffffffffffffffffffffffff83168583611981565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e83604051610c1e91815260200190565b60405180910390a35b5050600101610ada565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610cc2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072a9190612faa565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610688565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff808216600090815260066020526040812054909161072d91166001612ff6565b67ffffffffffffffff8116600090815260066020526040902060609061072d90600101611a0e565b610e3c611743565b61057781611a22565b67ffffffffffffffff8416600090815260066020526040812073ffffffffffffffffffffffffffffffffffffffff8316610eab576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805468010000000000000000900460ff1615610f1c57610ece6001820184611c04565b610f1c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610688565b80546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610f79576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035473ffffffffffffffffffffffffffffffffffffffff16801561101f576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610fec908a908a90600401612c46565b600060405180830381600087803b15801561100657600080fd5b505af115801561101a573d6000803e3d6000fd5b505050505b506002546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a61105660808c0160608d01612aea565b8a61106460808e018e613017565b6040518663ffffffff1660e01b815260040161108495949392919061307c565b600060405180830381865afa1580156110a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110e79190810190613144565b919450925090506110fe6080890160608a01612aea565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f8460405161114591815260200190565b60405180910390a2604080516101a081019091526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528c811661014085015287549293928392916101608401918a9187916111ba911661319e565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff168152602001866112ba576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015611291573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b591906131c5565b6112bd565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a80602001906112fb9190613017565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200161133f8b80613017565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050908252506020810184905260400161139060808c0160608d01612aea565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a80604001906113c191906131e2565b905067ffffffffffffffff8111156113db576113db612570565b60405190808252806020026020018201604052801561143e57816020015b61142b6040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b8152602001906001900390816113f95790505b509052905060005b61145360408b018b6131e2565b9050811015611502576114d961146c60408c018c6131e2565b8381811061147c5761147c612da8565b905060400201803603810190611492919061324a565b8c61149d8d80613017565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e9250611c33915050565b8260e0015182815181106114ef576114ef612da8565b6020908102919091010152600101611446565b5060025460e082015160009173ffffffffffffffffffffffffffffffffffffffff169063085318f8908d9061153a60408f018f6131e2565b6040518563ffffffff1660e01b81526004016115599493929190613361565b600060405180830381865afa158015611576573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526115bc9190810190613397565b905060005b8260e0015151811015611615578181815181106115e0576115e0612da8565b60200260200101518360e0015182815181106115fe576115fe612da8565b6020908102919091010151608001526001016115c1565b50604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908c1660608201523060808201526116a590839060a00160405160208183030381529060405280519060200120611f59565b82515260405167ffffffffffffffff8c16907ff6e86ef8896c7a0d629406168f396e883280680c99e649b9e2d36466fbc9f9e5906116e4908590613448565b60405180910390a25051519450505050505b949350505050565b611706611743565b61057781612059565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff1633146117c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610688565b565b60005b81518110156119395760008282815181106117e6576117e6612da8565b60200260200101519050600083838151811061180457611804612da8565b60200260200101516000015190508067ffffffffffffffff16600003611862576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610688565b67ffffffffffffffff8181166000818152600660209081526040918290208682015181547fffffff0000000000000000000000000000000000000000ffffffffffffffffff8116690100000000000000000073ffffffffffffffffffffffffffffffffffffffff909316928302908117808555865192891691909816178152928301526801000000000000000090940460ff161515918101919091527fd5ad72bc37dc7a80a8b9b9df20500046fd7341adb1be2258a540466fdd7dcef59060600160405180910390a25050508060010190506117c9565b5050565b600061072a8373ffffffffffffffffffffffffffffffffffffffff841661214e565b600061072a8373ffffffffffffffffffffffffffffffffffffffff841661219d565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610a01908490612297565b60606000611a1b836123a3565b9392505050565b805173ffffffffffffffffffffffffffffffffffffffff161580611a5e5750604081015173ffffffffffffffffffffffffffffffffffffffff16155b15611a95576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480548516918616919091179055606080860151600580549095169086161790935580516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008516928101929092527f00000000000000000000000000000000000000000000000000000000000000008416828201527f00000000000000000000000000000000000000000000000000000000000000009093169181019190915290517f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e3291611bf9918490613596565b60405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561072a565b611c656040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b8460200151600003611ca3576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611cb3858760000151610c31565b905073ffffffffffffffffffffffffffffffffffffffff81161580611d8357506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015611d5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d819190612b15565b155b15611dd55785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610688565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401611e749190613635565b6000604051808303816000875af1158015611e93573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611ed991908101906136ab565b6040805160a0810190915273ffffffffffffffffffffffffffffffffffffffff841660c08201529091508060e0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181526020016040518060200160405280600081525081525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c00151604051602001611f9b9695949392919061373c565b604051602081830303815290604052805190602001208560400151805190602001208660e00151604051602001611fd2919061379d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff8216036120d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610688565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120546121955750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561072d565b50600061072d565b600081815260018301602052604081205480156122865760006121c16001836137b0565b85549091506000906121d5906001906137b0565b905080821461223a5760008660000182815481106121f5576121f5612da8565b906000526020600020015490508087600001848154811061221857612218612da8565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061224b5761224b6137c3565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061072d565b600091505061072d565b5092915050565b60006122f9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166123ff9092919063ffffffff16565b805190915015610a0157808060200190518101906123179190612b15565b610a01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610688565b6060816000018054806020026020016040519081016040528092919081815260200182805480156123f357602002820191906000526020600020905b8154815260200190600101908083116123df575b50505050509050919050565b60606116f68484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161243391906137f2565b60006040518083038185875af1925050503d8060008114612470576040519150601f19603f3d011682016040523d82523d6000602084013e612475565b606091505b509150915061248687838387612491565b979650505050505050565b606083156125275782516000036125205773ffffffffffffffffffffffffffffffffffffffff85163b612520576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610688565b50816116f6565b6116f6838381511561253c5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610688919061281e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156125c2576125c2612570565b60405290565b6040516080810167ffffffffffffffff811182821017156125c2576125c2612570565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561263257612632612570565b604052919050565b600067ffffffffffffffff82111561265457612654612570565b5060051b60200190565b67ffffffffffffffff8116811461057757600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461057757600080fd5b600060208083850312156126a957600080fd5b823567ffffffffffffffff8111156126c057600080fd5b8301601f810185136126d157600080fd5b80356126e46126df8261263a565b6125eb565b81815260069190911b8201830190838101908783111561270357600080fd5b928401925b8284101561248657604084890312156127215760008081fd5b61272961259f565b84356127348161265e565b81528486013561274381612674565b8187015282526040939093019290840190612708565b6080810161072d828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b838110156127cb5781810151838201526020016127b3565b50506000910152565b600081518084526127ec8160208601602086016127b0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061072a60208301846127d4565b600060a0828403121561284357600080fd5b50919050565b6000806040838503121561285c57600080fd5b82356128678161265e565b9150602083013567ffffffffffffffff81111561288357600080fd5b61288f85828601612831565b9150509250929050565b600080602083850312156128ac57600080fd5b823567ffffffffffffffff808211156128c457600080fd5b818501915085601f8301126128d857600080fd5b8135818111156128e757600080fd5b8660208260051b85010111156128fc57600080fd5b60209290920196919550909350505050565b6000806040838503121561292157600080fd5b823561292c8161265e565b9150602083013561293c81612674565b809150509250929050565b60006020828403121561295957600080fd5b8135611a1b8161265e565b6080810161072d8284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260408083015182169084015260609182015116910152565b6020808252825182820181905260009190848201906040850190845b818110156129fb57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016129c9565b50909695505050505050565b8035612a1281612674565b919050565b600060808284031215612a2957600080fd5b612a316125c8565b8235612a3c81612674565b81526020830135612a4c81612674565b60208201526040830135612a5f81612674565b60408201526060830135612a7281612674565b60608201529392505050565b60008060008060808587031215612a9457600080fd5b8435612a9f8161265e565b9350602085013567ffffffffffffffff811115612abb57600080fd5b612ac787828801612831565b935050604085013591506060850135612adf81612674565b939692955090935050565b600060208284031215612afc57600080fd5b8135611a1b81612674565b801515811461057757600080fd5b600060208284031215612b2757600080fd5b8151611a1b81612b07565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612b6757600080fd5b830160208101925035905067ffffffffffffffff811115612b8757600080fd5b803603821315612b9657600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b85811015612c3b578135612c0981612674565b73ffffffffffffffffffffffffffffffffffffffff168752818301358388015260409687019690910190600101612bf6565b509495945050505050565b600067ffffffffffffffff808516835260406020840152612c678485612b32565b60a06040860152612c7c60e086018284612b9d565b915050612c8c6020860186612b32565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080878503016060880152612cc2848385612b9d565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1883603018312612cfb57600080fd5b60209288019283019235915084821115612d1457600080fd5b8160061b3603831315612d2657600080fd5b80878503016080880152612d3b848385612be6565b9450612d4960608901612a07565b73ffffffffffffffffffffffffffffffffffffffff811660a08901529350612d746080890189612b32565b94509250808786030160c08801525050612486838383612b9d565b600060208284031215612da157600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112612e0b57600080fd5b9190910192915050565b600082601f830112612e2657600080fd5b81356020612e366126df8361263a565b8083825260208201915060208460051b870101935086841115612e5857600080fd5b602086015b84811015612e7d578035612e7081612674565b8352918301918301612e5d565b509695505050505050565b600060808236031215612e9a57600080fd5b612ea26125c8565b8235612ead8161265e565b81526020830135612ebd81612b07565b6020820152604083013567ffffffffffffffff80821115612edd57600080fd5b612ee936838701612e15565b60408401526060850135915080821115612f0257600080fd5b50612f0f36828601612e15565b60608301525092915050565b60006020808385031215612f2e57600080fd5b825167ffffffffffffffff811115612f4557600080fd5b8301601f81018513612f5657600080fd5b8051612f646126df8261263a565b81815260059190911b82018301908381019087831115612f8357600080fd5b928401925b82841015612486578351612f9b81612674565b82529284019290840190612f88565b600060208284031215612fbc57600080fd5b8151611a1b81612674565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561229057612290612fc7565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261304c57600080fd5b83018035915067ffffffffffffffff82111561306757600080fd5b602001915036819003821315612b9657600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152608060608201526000612486608083018486612b9d565b600082601f8301126130d357600080fd5b815167ffffffffffffffff8111156130ed576130ed612570565b61311e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016125eb565b81815284602083860101111561313357600080fd5b6116f68260208301602087016127b0565b60008060006060848603121561315957600080fd5b83519250602084015161316b81612b07565b604085015190925067ffffffffffffffff81111561318857600080fd5b613194868287016130c2565b9150509250925092565b600067ffffffffffffffff8083168181036131bb576131bb612fc7565b6001019392505050565b6000602082840312156131d757600080fd5b8151611a1b8161265e565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261321757600080fd5b83018035915067ffffffffffffffff82111561323257600080fd5b6020019150600681901b3603821315612b9657600080fd5b60006040828403121561325c57600080fd5b61326461259f565b823561326f81612674565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b84811015613354577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160a081518186526132e5828701826127d4565b91505085820151858203878701526132fd82826127d4565b9150506040808301518683038288015261331783826127d4565b9250505060608083015181870152506080808301519250858203818701525061334081836127d4565b9a86019a94505050908301906001016132a1565b5090979650505050505050565b67ffffffffffffffff851681526060602082015260006133846060830186613284565b8281036040840152612486818587612be6565b600060208083850312156133aa57600080fd5b825167ffffffffffffffff808211156133c257600080fd5b818501915085601f8301126133d657600080fd5b81516133e46126df8261263a565b81815260059190911b8301840190848101908883111561340357600080fd5b8585015b8381101561343b5780518581111561341f5760008081fd5b61342d8b89838a01016130c2565b845250918601918601613407565b5098975050505050505050565b6020815261349960208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b600060208301516134c260c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e08501526134df6101a08501836127d4565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808685030161010087015261351c84836127d4565b935060808701519150808685030161012087015261353a84836127d4565b935060a0870151915061356661014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e087015191508086850301838701525061358c8382613284565b9695505050505050565b61010081016135ee828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a08401526040840151811660c084015260608401511660e0830152611a1b565b602081526000825160a0602084015261365160c08401826127d4565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b6000602082840312156136bd57600080fd5b815167ffffffffffffffff808211156136d557600080fd5b90830190604082860312156136e957600080fd5b6136f161259f565b82518281111561370057600080fd5b61370c878286016130c2565b82525060208301518281111561372157600080fd5b61372d878286016130c2565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c0602084015261376c60c08401896127d4565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b60208152600061072a6020830184613284565b8181038181111561072d5761072d612fc7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251612e0b8184602087016127b056fea164736f6c6343000818000a", } var OnRampABI = OnRampMetaData.ABI @@ -955,8 +955,8 @@ func (_OnRamp *OnRampFilterer) ParseAllowListSendersRemoved(log types.Log) (*OnR return event, nil } -type OnRampCCIPSendRequestedIterator struct { - Event *OnRampCCIPSendRequested +type OnRampCCIPMessageSentIterator struct { + Event *OnRampCCIPMessageSent contract *bind.BoundContract event string @@ -967,7 +967,7 @@ type OnRampCCIPSendRequestedIterator struct { fail error } -func (it *OnRampCCIPSendRequestedIterator) Next() bool { +func (it *OnRampCCIPMessageSentIterator) Next() bool { if it.fail != nil { return false @@ -976,7 +976,7 @@ func (it *OnRampCCIPSendRequestedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(OnRampCCIPSendRequested) + it.Event = new(OnRampCCIPMessageSent) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -991,7 +991,7 @@ func (it *OnRampCCIPSendRequestedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(OnRampCCIPSendRequested) + it.Event = new(OnRampCCIPMessageSent) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1006,43 +1006,43 @@ func (it *OnRampCCIPSendRequestedIterator) Next() bool { } } -func (it *OnRampCCIPSendRequestedIterator) Error() error { +func (it *OnRampCCIPMessageSentIterator) Error() error { return it.fail } -func (it *OnRampCCIPSendRequestedIterator) Close() error { +func (it *OnRampCCIPMessageSentIterator) Close() error { it.sub.Unsubscribe() return nil } -type OnRampCCIPSendRequested struct { +type OnRampCCIPMessageSent struct { DestChainSelector uint64 Message InternalEVM2AnyRampMessage Raw types.Log } -func (_OnRamp *OnRampFilterer) FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampCCIPSendRequestedIterator, error) { +func (_OnRamp *OnRampFilterer) FilterCCIPMessageSent(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampCCIPMessageSentIterator, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) } - logs, sub, err := _OnRamp.contract.FilterLogs(opts, "CCIPSendRequested", destChainSelectorRule) + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "CCIPMessageSent", destChainSelectorRule) if err != nil { return nil, err } - return &OnRampCCIPSendRequestedIterator{contract: _OnRamp.contract, event: "CCIPSendRequested", logs: logs, sub: sub}, nil + return &OnRampCCIPMessageSentIterator{contract: _OnRamp.contract, event: "CCIPMessageSent", logs: logs, sub: sub}, nil } -func (_OnRamp *OnRampFilterer) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *OnRampCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) { +func (_OnRamp *OnRampFilterer) WatchCCIPMessageSent(opts *bind.WatchOpts, sink chan<- *OnRampCCIPMessageSent, destChainSelector []uint64) (event.Subscription, error) { var destChainSelectorRule []interface{} for _, destChainSelectorItem := range destChainSelector { destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) } - logs, sub, err := _OnRamp.contract.WatchLogs(opts, "CCIPSendRequested", destChainSelectorRule) + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "CCIPMessageSent", destChainSelectorRule) if err != nil { return nil, err } @@ -1052,8 +1052,8 @@ func (_OnRamp *OnRampFilterer) WatchCCIPSendRequested(opts *bind.WatchOpts, sink select { case log := <-logs: - event := new(OnRampCCIPSendRequested) - if err := _OnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { + event := new(OnRampCCIPMessageSent) + if err := _OnRamp.contract.UnpackLog(event, "CCIPMessageSent", log); err != nil { return err } event.Raw = log @@ -1074,9 +1074,9 @@ func (_OnRamp *OnRampFilterer) WatchCCIPSendRequested(opts *bind.WatchOpts, sink }), nil } -func (_OnRamp *OnRampFilterer) ParseCCIPSendRequested(log types.Log) (*OnRampCCIPSendRequested, error) { - event := new(OnRampCCIPSendRequested) - if err := _OnRamp.contract.UnpackLog(event, "CCIPSendRequested", log); err != nil { +func (_OnRamp *OnRampFilterer) ParseCCIPMessageSent(log types.Log) (*OnRampCCIPMessageSent, error) { + event := new(OnRampCCIPMessageSent) + if err := _OnRamp.contract.UnpackLog(event, "CCIPMessageSent", log); err != nil { return nil, err } event.Raw = log @@ -1882,8 +1882,8 @@ func (_OnRamp *OnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { return _OnRamp.ParseAllowListSendersAdded(log) case _OnRamp.abi.Events["AllowListSendersRemoved"].ID: return _OnRamp.ParseAllowListSendersRemoved(log) - case _OnRamp.abi.Events["CCIPSendRequested"].ID: - return _OnRamp.ParseCCIPSendRequested(log) + case _OnRamp.abi.Events["CCIPMessageSent"].ID: + return _OnRamp.ParseCCIPMessageSent(log) case _OnRamp.abi.Events["ConfigSet"].ID: return _OnRamp.ParseConfigSet(log) case _OnRamp.abi.Events["DestChainConfigSet"].ID: @@ -1914,8 +1914,8 @@ func (OnRampAllowListSendersRemoved) Topic() common.Hash { return common.HexToHash("0xc237ec1921f855ccd5e9a5af9733f2d58943a5a8501ec5988e305d7a4d421586") } -func (OnRampCCIPSendRequested) Topic() common.Hash { - return common.HexToHash("0xcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140") +func (OnRampCCIPMessageSent) Topic() common.Hash { + return common.HexToHash("0xf6e86ef8896c7a0d629406168f396e883280680c99e649b9e2d36466fbc9f9e5") } func (OnRampConfigSet) Topic() common.Hash { @@ -2003,11 +2003,11 @@ type OnRampInterface interface { ParseAllowListSendersRemoved(log types.Log) (*OnRampAllowListSendersRemoved, error) - FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampCCIPSendRequestedIterator, error) + FilterCCIPMessageSent(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampCCIPMessageSentIterator, error) - WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *OnRampCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) + WatchCCIPMessageSent(opts *bind.WatchOpts, sink chan<- *OnRampCCIPMessageSent, destChainSelector []uint64) (event.Subscription, error) - ParseCCIPSendRequested(log types.Log) (*OnRampCCIPSendRequested, error) + ParseCCIPMessageSent(log types.Log) (*OnRampCCIPMessageSent, error) FilterConfigSet(opts *bind.FilterOpts) (*OnRampConfigSetIterator, error) diff --git a/core/gethwrappers/ccip/generated/report_codec/report_codec.go b/core/gethwrappers/ccip/generated/report_codec/report_codec.go index 0080cfc419..29333984cc 100644 --- a/core/gethwrappers/ccip/generated/report_codec/report_codec.go +++ b/core/gethwrappers/ccip/generated/report_codec/report_codec.go @@ -30,6 +30,11 @@ var ( _ = abi.ConvertType ) +type IRMNV2Signature struct { + R [32]byte + S [32]byte +} + type InternalAny2EVMRampMessage struct { Header InternalRampMessageHeader Sender []byte @@ -52,6 +57,14 @@ type InternalGasPriceUpdate struct { UsdPerUnitGas *big.Int } +type InternalMerkleRoot struct { + SourceChainSelector uint64 + MinSeqNr uint64 + MaxSeqNr uint64 + MerkleRoot [32]byte + OnRampAddress []byte +} + type InternalPriceUpdates struct { TokenPriceUpdates []InternalTokenPriceUpdate GasPriceUpdates []InternalGasPriceUpdate @@ -79,24 +92,14 @@ type InternalTokenPriceUpdate struct { } type OffRampCommitReport struct { - PriceUpdates InternalPriceUpdates - MerkleRoots []OffRampMerkleRoot -} - -type OffRampInterval struct { - Min uint64 - Max uint64 -} - -type OffRampMerkleRoot struct { - SourceChainSelector uint64 - Interval OffRampInterval - MerkleRoot [32]byte + PriceUpdates InternalPriceUpdates + MerkleRoots []InternalMerkleRoot + RmnSignatures []IRMNV2Signature } var ReportCodecMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportDecoded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"report\",\"type\":\"tuple[]\"}],\"name\":\"ExecuteReportDecoded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeCommitReport\",\"outputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structOffRamp.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structOffRamp.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeExecuteReport\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061126d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636fb349561461003b578063f816ec6014610064575b600080fd5b61004e61004936600461022c565b610084565b60405161005b91906104ed565b60405180910390f35b61007761007236600461022c565b6100a0565b60405161005b91906107a6565b60608180602001905181019061009a9190610de1565b92915050565b604080516080810182526060918101828152828201839052815260208101919091528180602001905181019061009a91906110f7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715610128576101286100d6565b60405290565b60405160c0810167ffffffffffffffff81118282101715610128576101286100d6565b6040805190810167ffffffffffffffff81118282101715610128576101286100d6565b6040516060810167ffffffffffffffff81118282101715610128576101286100d6565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156101de576101de6100d6565b604052919050565b600067ffffffffffffffff821115610200576102006100d6565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006020828403121561023e57600080fd5b813567ffffffffffffffff81111561025557600080fd5b8201601f8101841361026657600080fd5b8035610279610274826101e6565b610197565b81815285602083850101111561028e57600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b838110156102c75781810151838201526020016102af565b50506000910152565b600081518084526102e88160208601602086016102ac565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b848110156103ea577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160a0815181865261037b828701826102d0565b915050858201518582038787015261039382826102d0565b915050604080830151868303828801526103ad83826102d0565b925050506060808301518187015250608080830151925085820381870152506103d681836102d0565b9a86019a9450505090830190600101610337565b5090979650505050505050565b6000828251808552602080860195506005818360051b8501018287016000805b868110156104a2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe088850381018c5283518051808752908801908887019080891b88018a01865b8281101561048b57858a83030184526104798286516102d0565b948c0194938c0193915060010161045f565b509e8a019e97505050938701935050600101610417565b50919998505050505050505050565b60008151808452602080850194506020840160005b838110156104e2578151875295820195908201906001016104c6565b509495945050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156106d5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452815160a0860167ffffffffffffffff8083511688528883015160a08a8a015282815180855260c08b01915060c08160051b8c010194508b8301925060005b8181101561067e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408c87030183528351805180518852868f820151168f890152866040820151166040890152866060820151166060890152866080820151166080890152508d81015161014060a08901526106016101408901826102d0565b9050604082015188820360c08a015261061a82826102d0565b915050606082015161064460e08a018273ffffffffffffffffffffffffffffffffffffffff169052565b50608082015161010089015260a0820151915087810361012089015261066a818361031a565b97505050928c0192918c0191600101610581565b50505050506040820151878203604089015261069a82826103f7565b915050606082015187820360608901526106b482826104b1565b60809384015198909301979097525094509285019290850190600101610514565b5092979650505050505050565b60008151808452602080850194506020840160005b838110156104e2578151805167ffffffffffffffff1688528301517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683880152604090960195908201906001016106f7565b600081518084526020808501945080840160005b838110156104e2578151805167ffffffffffffffff90811689528482015180518216868b0152850151166040808a0191909152015160608801526080909601959082019060010161075a565b6000602080835283516040808386015260a0850182516040606088015281815180845260c0890191508683019350600092505b80831015610836578351805173ffffffffffffffffffffffffffffffffffffffff1683528701517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16878301529286019260019290920191908401906107d9565b50938501518785037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa00160808901529361087081866106e2565b9450505050508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08482030160408501526108b08183610746565b95945050505050565b600067ffffffffffffffff8211156108d3576108d36100d6565b5060051b60200190565b805167ffffffffffffffff811681146108f557600080fd5b919050565b600060a0828403121561090c57600080fd5b610914610105565b905081518152610926602083016108dd565b6020820152610937604083016108dd565b6040820152610948606083016108dd565b6060820152610959608083016108dd565b608082015292915050565b600082601f83011261097557600080fd5b8151610983610274826101e6565b81815284602083860101111561099857600080fd5b6109a98260208301602087016102ac565b949350505050565b805173ffffffffffffffffffffffffffffffffffffffff811681146108f557600080fd5b600082601f8301126109e657600080fd5b815160206109f6610274836108b9565b82815260059290921b84018101918181019086841115610a1557600080fd5b8286015b84811015610b2f57805167ffffffffffffffff80821115610a3a5760008081fd5b818901915060a0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610a735760008081fd5b610a7b610105565b8784015183811115610a8d5760008081fd5b610a9b8d8a83880101610964565b82525060408085015184811115610ab25760008081fd5b610ac08e8b83890101610964565b8a8401525060608086015185811115610ad95760008081fd5b610ae78f8c838a0101610964565b83850152506080915081860151818401525082850151925083831115610b0d5760008081fd5b610b1b8d8a85880101610964565b908201528652505050918301918301610a19565b509695505050505050565b600082601f830112610b4b57600080fd5b81516020610b5b610274836108b9565b82815260059290921b84018101918181019086841115610b7a57600080fd5b8286015b84811015610b2f57805167ffffffffffffffff80821115610b9f5760008081fd5b8189019150610140807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610bd95760008081fd5b610be161012e565b610bed8c8986016108fa565b815260c084015183811115610c025760008081fd5b610c108d8a83880101610964565b898301525060e084015183811115610c285760008081fd5b610c368d8a83880101610964565b604083015250610c4961010085016109b1565b60608201526101208401516080820152908301519082821115610c6c5760008081fd5b610c7a8c89848701016109d5565b60a08201528652505050918301918301610b7e565b600082601f830112610ca057600080fd5b81516020610cb0610274836108b9565b82815260059290921b84018101918181019086841115610ccf57600080fd5b8286015b84811015610b2f57805167ffffffffffffffff80821115610cf357600080fd5b818901915089603f830112610d0757600080fd5b85820151610d17610274826108b9565b81815260059190911b830160400190878101908c831115610d3757600080fd5b604085015b83811015610d7057805185811115610d5357600080fd5b610d628f6040838a0101610964565b845250918901918901610d3c565b50875250505092840192508301610cd3565b600082601f830112610d9357600080fd5b81516020610da3610274836108b9565b8083825260208201915060208460051b870101935086841115610dc557600080fd5b602086015b84811015610b2f5780518352918301918301610dca565b60006020808385031215610df457600080fd5b825167ffffffffffffffff80821115610e0c57600080fd5b818501915085601f830112610e2057600080fd5b8151610e2e610274826108b9565b81815260059190911b83018401908481019088831115610e4d57600080fd5b8585015b83811015610f4757805185811115610e6857600080fd5b860160a0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215610e9d5760008081fd5b610ea5610105565b610eb08983016108dd565b815260408083015188811115610ec65760008081fd5b610ed48e8c83870101610b3a565b8b8401525060608084015189811115610eed5760008081fd5b610efb8f8d83880101610c8f565b8385015250608091508184015189811115610f165760008081fd5b610f248f8d83880101610d82565b918401919091525060a09290920151918101919091528352918601918601610e51565b5098975050505050505050565b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146108f557600080fd5b600082601f830112610f9157600080fd5b81516020610fa1610274836108b9565b82815260069290921b84018101918181019086841115610fc057600080fd5b8286015b84811015610b2f5760408189031215610fdd5760008081fd5b610fe5610151565b610fee826108dd565b8152610ffb858301610f54565b81860152835291830191604001610fc4565b600082601f83011261101e57600080fd5b8151602061102e610274836108b9565b82815260079290921b8401810191818101908684111561104d57600080fd5b8286015b84811015610b2f57808803608081121561106b5760008081fd5b611073610174565b61107c836108dd565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156110b05760008081fd5b6110b8610151565b92506110c58785016108dd565b83526110d28185016108dd565b8388015281870192909252606083015191810191909152835291830191608001611051565b6000602080838503121561110a57600080fd5b825167ffffffffffffffff8082111561112257600080fd5b8185019150604080838803121561113857600080fd5b611140610151565b83518381111561114f57600080fd5b84016040818a03121561116157600080fd5b611169610151565b81518581111561117857600080fd5b8201601f81018b1361118957600080fd5b8051611197610274826108b9565b81815260069190911b8201890190898101908d8311156111b657600080fd5b928a01925b828410156112045787848f0312156111d35760008081fd5b6111db610151565b6111e4856109b1565b81526111f18c8601610f54565b818d0152825292870192908a01906111bb565b84525050508187015193508484111561121c57600080fd5b6112288a858401610f80565b818801528252508385015191508282111561124257600080fd5b61124e8883860161100d565b8582015280955050505050509291505056fea164736f6c6343000818000a", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"onRampAddress\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMNV2.Signature[]\",\"name\":\"rmnSignatures\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportDecoded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"report\",\"type\":\"tuple[]\"}],\"name\":\"ExecuteReportDecoded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeCommitReport\",\"outputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"onRampAddress\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMNV2.Signature[]\",\"name\":\"rmnSignatures\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"decodeExecuteReport\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReportSingleChain[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506113e6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636fb349561461003b578063f816ec6014610064575b600080fd5b61004e610049366004610231565b610084565b60405161005b91906104f2565b60405180910390f35b610077610072366004610231565b6100a0565b60405161005b9190610835565b60608180602001905181019061009a9190610e8d565b92915050565b6040805160a08101825260608082018181526080830182905282526020808301829052928201528251909161009a9184018101908401611250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561012d5761012d6100db565b60405290565b60405160c0810167ffffffffffffffff8111828210171561012d5761012d6100db565b6040805190810167ffffffffffffffff8111828210171561012d5761012d6100db565b6040516060810167ffffffffffffffff8111828210171561012d5761012d6100db565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156101e3576101e36100db565b604052919050565b600067ffffffffffffffff821115610205576102056100db565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006020828403121561024357600080fd5b813567ffffffffffffffff81111561025a57600080fd5b8201601f8101841361026b57600080fd5b803561027e610279826101eb565b61019c565b81815285602083850101111561029357600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b838110156102cc5781810151838201526020016102b4565b50506000910152565b600081518084526102ed8160208601602086016102b1565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b848110156103ef577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160a08151818652610380828701826102d5565b915050858201518582038787015261039882826102d5565b915050604080830151868303828801526103b283826102d5565b925050506060808301518187015250608080830151925085820381870152506103db81836102d5565b9a86019a945050509083019060010161033c565b5090979650505050505050565b6000828251808552602080860195506005818360051b8501018287016000805b868110156104a7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe088850381018c5283518051808752908801908887019080891b88018a01865b8281101561049057858a830301845261047e8286516102d5565b948c0194938c01939150600101610464565b509e8a019e9750505093870193505060010161041c565b50919998505050505050505050565b60008151808452602080850194506020840160005b838110156104e7578151875295820195908201906001016104cb565b509495945050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156106da577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452815160a0860167ffffffffffffffff8083511688528883015160a08a8a015282815180855260c08b01915060c08160051b8c010194508b8301925060005b81811015610683577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff408c87030183528351805180518852868f820151168f890152866040820151166040890152866060820151166060890152866080820151166080890152508d81015161014060a08901526106066101408901826102d5565b9050604082015188820360c08a015261061f82826102d5565b915050606082015161064960e08a018273ffffffffffffffffffffffffffffffffffffffff169052565b50608082015161010089015260a0820151915087810361012089015261066f818361031f565b97505050928c0192918c0191600101610586565b50505050506040820151878203604089015261069f82826103fc565b915050606082015187820360608901526106b982826104b6565b60809384015198909301979097525094509285019290850190600101610519565b5092979650505050505050565b60008151808452602080850194506020840160005b838110156104e7578151805167ffffffffffffffff1688528301517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683880152604090960195908201906001016106fc565b600082825180855260208086019550808260051b84010181860160005b848110156103ef578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00189528151805167ffffffffffffffff908116855285820151811686860152604080830151909116908501526060808201519085015260809081015160a0918501829052906107e5818601836102d5565b9a86019a9450505090830190600101610768565b60008151808452602080850194506020840160005b838110156104e757815180518852830151838801526040909601959082019060010161080e565b602080825282516060838301528051604060808501819052815160c086018190526000949392840191859160e08801905b808410156108c3578451805173ffffffffffffffffffffffffffffffffffffffff1683528701517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1687830152938601936001939093019290820190610866565b50938501518785037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800160a0890152936108fd81866106e7565b9450505050508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08085830301604086015261093e828461074b565b925060408601519150808584030160608601525061095c82826107f9565b95945050505050565b600067ffffffffffffffff82111561097f5761097f6100db565b5060051b60200190565b805167ffffffffffffffff811681146109a157600080fd5b919050565b600060a082840312156109b857600080fd5b6109c061010a565b9050815181526109d260208301610989565b60208201526109e360408301610989565b60408201526109f460608301610989565b6060820152610a0560808301610989565b608082015292915050565b600082601f830112610a2157600080fd5b8151610a2f610279826101eb565b818152846020838601011115610a4457600080fd5b610a558260208301602087016102b1565b949350505050565b805173ffffffffffffffffffffffffffffffffffffffff811681146109a157600080fd5b600082601f830112610a9257600080fd5b81516020610aa261027983610965565b82815260059290921b84018101918181019086841115610ac157600080fd5b8286015b84811015610bdb57805167ffffffffffffffff80821115610ae65760008081fd5b818901915060a0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610b1f5760008081fd5b610b2761010a565b8784015183811115610b395760008081fd5b610b478d8a83880101610a10565b82525060408085015184811115610b5e5760008081fd5b610b6c8e8b83890101610a10565b8a8401525060608086015185811115610b855760008081fd5b610b938f8c838a0101610a10565b83850152506080915081860151818401525082850151925083831115610bb95760008081fd5b610bc78d8a85880101610a10565b908201528652505050918301918301610ac5565b509695505050505050565b600082601f830112610bf757600080fd5b81516020610c0761027983610965565b82815260059290921b84018101918181019086841115610c2657600080fd5b8286015b84811015610bdb57805167ffffffffffffffff80821115610c4b5760008081fd5b8189019150610140807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610c855760008081fd5b610c8d610133565b610c998c8986016109a6565b815260c084015183811115610cae5760008081fd5b610cbc8d8a83880101610a10565b898301525060e084015183811115610cd45760008081fd5b610ce28d8a83880101610a10565b604083015250610cf56101008501610a5d565b60608201526101208401516080820152908301519082821115610d185760008081fd5b610d268c8984870101610a81565b60a08201528652505050918301918301610c2a565b600082601f830112610d4c57600080fd5b81516020610d5c61027983610965565b82815260059290921b84018101918181019086841115610d7b57600080fd5b8286015b84811015610bdb57805167ffffffffffffffff80821115610d9f57600080fd5b818901915089603f830112610db357600080fd5b85820151610dc361027982610965565b81815260059190911b830160400190878101908c831115610de357600080fd5b604085015b83811015610e1c57805185811115610dff57600080fd5b610e0e8f6040838a0101610a10565b845250918901918901610de8565b50875250505092840192508301610d7f565b600082601f830112610e3f57600080fd5b81516020610e4f61027983610965565b8083825260208201915060208460051b870101935086841115610e7157600080fd5b602086015b84811015610bdb5780518352918301918301610e76565b60006020808385031215610ea057600080fd5b825167ffffffffffffffff80821115610eb857600080fd5b818501915085601f830112610ecc57600080fd5b8151610eda61027982610965565b81815260059190911b83018401908481019088831115610ef957600080fd5b8585015b83811015610ff357805185811115610f1457600080fd5b860160a0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0011215610f495760008081fd5b610f5161010a565b610f5c898301610989565b815260408083015188811115610f725760008081fd5b610f808e8c83870101610be6565b8b8401525060608084015189811115610f995760008081fd5b610fa78f8d83880101610d3b565b8385015250608091508184015189811115610fc25760008081fd5b610fd08f8d83880101610e2e565b918401919091525060a09290920151918101919091528352918601918601610efd565b5098975050505050505050565b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146109a157600080fd5b600082601f83011261103d57600080fd5b8151602061104d61027983610965565b82815260069290921b8401810191818101908684111561106c57600080fd5b8286015b84811015610bdb57604081890312156110895760008081fd5b611091610156565b61109a82610989565b81526110a7858301611000565b81860152835291830191604001611070565b600082601f8301126110ca57600080fd5b815160206110da61027983610965565b82815260059290921b840181019181810190868411156110f957600080fd5b8286015b84811015610bdb57805167ffffffffffffffff8082111561111e5760008081fd5b818901915060a0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d030112156111575760008081fd5b61115f61010a565b61116a888501610989565b81526040611179818601610989565b89830152606061118a818701610989565b8284015260809150818601518184015250828501519250838311156111af5760008081fd5b6111bd8d8a85880101610a10565b9082015286525050509183019183016110fd565b600082601f8301126111e257600080fd5b815160206111f261027983610965565b82815260069290921b8401810191818101908684111561121157600080fd5b8286015b84811015610bdb576040818903121561122e5760008081fd5b611236610156565b815181528482015185820152835291830191604001611215565b6000602080838503121561126357600080fd5b825167ffffffffffffffff8082111561127b57600080fd5b908401906060828703121561128f57600080fd5b611297610179565b8251828111156112a657600080fd5b830160408189038113156112b957600080fd5b6112c1610156565b8251858111156112d057600080fd5b8301601f81018b136112e157600080fd5b80516112ef61027982610965565b81815260069190911b8201890190898101908d83111561130e57600080fd5b928a01925b8284101561135c5785848f03121561132b5760008081fd5b611333610156565b61133c85610a5d565b81526113498c8601611000565b818d0152825292850192908a0190611313565b84525050508287015191508482111561137457600080fd5b6113808a83850161102c565b8188015283525050828401518281111561139957600080fd5b6113a5888286016110b9565b858301525060408301519350818411156113be57600080fd5b6113ca878585016111d1565b6040820152969550505050505056fea164736f6c6343000818000a", } var ReportCodecABI = ReportCodecMetaData.ABI @@ -526,7 +529,7 @@ func (_ReportCodec *ReportCodec) ParseLog(log types.Log) (generated.AbigenLog, e } func (ReportCodecCommitReportDecoded) Topic() common.Hash { - return common.HexToHash("0x1b2cb5e9d31bdaabb2ae07532436ae669406f84003ca27179b4dfb72f127f7dc") + return common.HexToHash("0x83099d210b303f78572f4da1af1d1777cbf80cae42cdb9381f310dbdf21e8f89") } func (ReportCodecExecuteReportDecoded) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generated/rmn_remote/rmn_remote.go b/core/gethwrappers/ccip/generated/rmn_remote/rmn_remote.go new file mode 100644 index 0000000000..a380d77e10 --- /dev/null +++ b/core/gethwrappers/ccip/generated/rmn_remote/rmn_remote.go @@ -0,0 +1,842 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package rmn_remote + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type IRMNV2Signature struct { + R [32]byte + S [32]byte +} + +type InternalMerkleRoot struct { + SourceChainSelector uint64 + MinSeqNr uint64 + MaxSeqNr uint64 + MerkleRoot [32]byte + OnRampAddress []byte +} + +type RMNRemoteConfig struct { + RmnHomeContractConfigDigest [32]byte + Signers []RMNRemoteSigner + MinSigners uint64 +} + +type RMNRemoteSigner struct { + OnchainPublicKey common.Address + NodeIndex uint64 +} + +type RMNRemoteVersionedConfig struct { + Version uint32 + Config RMNRemoteConfig +} + +var RMNRemoteMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ConfigNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateOnchainPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignerOrder\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MinSignersTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OutOfOrderSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ThresholdNotMet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedSigner\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"rmnHomeContractConfigDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"onchainPublicKey\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"nodeIndex\",\"type\":\"uint64\"}],\"internalType\":\"structRMNRemote.Signer[]\",\"name\":\"signers\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"minSigners\",\"type\":\"uint64\"}],\"internalType\":\"structRMNRemote.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"structRMNRemote.VersionedConfig\",\"name\":\"versionedConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVersionedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"rmnHomeContractConfigDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"onchainPublicKey\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"nodeIndex\",\"type\":\"uint64\"}],\"internalType\":\"structRMNRemote.Signer[]\",\"name\":\"signers\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"minSigners\",\"type\":\"uint64\"}],\"internalType\":\"structRMNRemote.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structRMNRemote.VersionedConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes16\",\"name\":\"subject\",\"type\":\"bytes16\"}],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isCursed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"rmnHomeContractConfigDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"onchainPublicKey\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"nodeIndex\",\"type\":\"uint64\"}],\"internalType\":\"structRMNRemote.Signer[]\",\"name\":\"signers\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"minSigners\",\"type\":\"uint64\"}],\"internalType\":\"structRMNRemote.Config\",\"name\":\"newConfig\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"test\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"onRampAddress\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.MerkleRoot[]\",\"name\":\"destLaneUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMNV2.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"verify\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200182d3803806200182d83398101604081905262000034916200017e565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d3565b5050506001600160401b0316608052620001b0565b336001600160a01b038216036200012d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019157600080fd5b81516001600160401b0381168114620001a957600080fd5b9392505050565b608051611664620001c9600039600050506116646000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063397796f7116100765780638da5cb5b1161005b5780638da5cb5b14610184578063f2fde38b146101ac578063f8a8fd6d1461012857600080fd5b8063397796f71461017557806379ba50971461017c57600080fd5b80631add205f116100a75780631add205f1461012a5780632cbc26bb1461013f57806330dfc3081461016357600080fd5b8063181f5a77146100c3578063198f0f7714610115575b600080fd5b6100ff6040518060400160405280601381526020017f524d4e52656d6f746520312e362e302d6465760000000000000000000000000081525081565b60405161010c9190610c4b565b60405180910390f35b610128610123366004610c65565b6101bf565b005b6101326105f0565b60405161010c9190610ca0565b61015361014d366004610d58565b50600090565b604051901515815260200161010c565b610128610171366004610f60565b5050565b6000610153565b61012861090b565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010c565b6101286101ba36600461113d565b610a0d565b6101c7610a23565b60015b6101d7602083018361115a565b90508110156102a7576101ed602083018361115a565b828181106101fd576101fd6111c9565b905060400201602001602081019061021591906111f8565b67ffffffffffffffff1661022c602084018461115a565b610237600185611244565b818110610246576102466111c9565b905060400201602001602081019061025e91906111f8565b67ffffffffffffffff161061029f576040517f4485151700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001016101ca565b506102b5602082018261115a565b90506102c760608301604084016111f8565b67ffffffffffffffff161115610309576040517ffba0d9e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025b60018101541561040557600180820180546006926000929161032e9190611244565b8154811061033e5761033e6111c9565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600181018054806103a8576103a861125d565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffff0000000000000000000000000000000000000000000000000000000016905501905561030c565b5060005b610416602083018361115a565b905081101561054b5760066000610430602085018561115a565b84818110610440576104406111c9565b610456926020604090920201908101915061113d565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205460ff16156104b7576040517f28cae27d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600660006104ca602086018661115a565b858181106104da576104da6111c9565b6104f0926020604090920201908101915061113d565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055600101610409565b508060026105598282611345565b5050600580546000919082906105749063ffffffff16611480565b91906101000a81548163ffffffff021916908363ffffffff160217905590507f6cc65868ae41a007e6c3ed18ce591c123dd4e5864b421888c68ce92dae98cea460405180604001604052808363ffffffff168152602001846105d5906114a3565b90526040516105e49190610ca0565b60405180910390a15050565b6105f8610b99565b60408051808201825260055463ffffffff1681528151606081018352600280548252600380548551602082810282018101909752818152949580870195858201939092909160009084015b828210156106b1576000848152602090819020604080518082019091529084015473ffffffffffffffffffffffffffffffffffffffff8116825274010000000000000000000000000000000000000000900467ffffffffffffffff1681830152825260019092019101610643565b505050908252506002919091015467ffffffffffffffff166020909101529052919050565b84518110156108bd5760008582815181106106f3576106f36111c9565b602002602001015190506000600186601b8460000151856020015160405160008152602001604052604051610744949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610766573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166107de576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610610843576040517fbbe15e7f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526006602052604090205460ff166108a2576040517faaaa914100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250826108ae8561161f565b945050508060010190506106d6565b5060045467ffffffffffffffff16821015610904576040517f59fa4a9300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a15610a23565b610a1e81610aa4565b50565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610988565b3373ffffffffffffffffffffffffffffffffffffffff821603610b23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610988565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6040518060400160405280600063ffffffff168152602001610be260405180606001604052806000801916815260200160608152602001600067ffffffffffffffff1681525090565b905290565b6000815180845260005b81811015610c0d57602081850181015186830182015201610bf1565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610c5e6020830184610be7565b9392505050565b600060208284031215610c7757600080fd5b813567ffffffffffffffff811115610c8e57600080fd5b820160608185031215610c5e57600080fd5b6000602080835263ffffffff8451168184015280840151604080604086015260c0850182516060870152838301516060608088015281815180845260e0890191508683019350600092505b80831015610d34578351805173ffffffffffffffffffffffffffffffffffffffff16835287015167ffffffffffffffff1687830152928601926001929092019190840190610ceb565b50604085015167ffffffffffffffff811660a08a0152955098975050505050505050565b600060208284031215610d6a57600080fd5b81357fffffffffffffffffffffffffffffffff0000000000000000000000000000000081168114610c5e57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610dec57610dec610d9a565b60405290565b60405160a0810167ffffffffffffffff81118282101715610dec57610dec610d9a565b6040516060810167ffffffffffffffff81118282101715610dec57610dec610d9a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610e7f57610e7f610d9a565b604052919050565b600067ffffffffffffffff821115610ea157610ea1610d9a565b5060051b60200190565b67ffffffffffffffff81168114610a1e57600080fd5b8035610ecc81610eab565b919050565b600082601f830112610ee257600080fd5b81356020610ef7610ef283610e87565b610e38565b82815260069290921b84018101918181019086841115610f1657600080fd5b8286015b84811015610f555760408189031215610f335760008081fd5b610f3b610dc9565b813581528482013585820152835291830191604001610f1a565b509695505050505050565b60008060408385031215610f7357600080fd5b823567ffffffffffffffff80821115610f8b57600080fd5b818501915085601f830112610f9f57600080fd5b81356020610faf610ef283610e87565b82815260059290921b84018101918181019089841115610fce57600080fd5b8286015b848110156110ed57803586811115610fe957600080fd5b87017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060a0828e038201121561101e57600080fd5b611026610df2565b8683013561103381610eab565b8152604083013561104381610eab565b81880152606083013561105581610eab565b60408201526080830135606082015260a08301358981111561107657600080fd5b8084019350508d603f84011261108b57600080fd5b868301358981111561109f5761109f610d9a565b6110af8884601f84011601610e38565b92508083528e60408286010111156110c657600080fd5b80604085018985013760009083018801526080810191909152845250918301918301610fd2565b509650508601359250508082111561110457600080fd5b5061111185828601610ed1565b9150509250929050565b73ffffffffffffffffffffffffffffffffffffffff81168114610a1e57600080fd5b60006020828403121561114f57600080fd5b8135610c5e8161111b565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261118f57600080fd5b83018035915067ffffffffffffffff8211156111aa57600080fd5b6020019150600681901b36038213156111c257600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561120a57600080fd5b8135610c5e81610eab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561125757611257611215565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000813561125781610eab565b81356112a48161111b565b73ffffffffffffffffffffffffffffffffffffffff811690508154817fffffffffffffffffffffffff0000000000000000000000000000000000000000821617835560208401356112f481610eab565b7bffffffffffffffff00000000000000000000000000000000000000008160a01b16837fffffffff000000000000000000000000000000000000000000000000000000008416171784555050505050565b81358155600180820160208401357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe185360301811261138357600080fd5b8401803567ffffffffffffffff81111561139c57600080fd5b6020820191508060061b36038213156113b457600080fd5b680100000000000000008111156113cd576113cd610d9a565b825481845580821015611402576000848152602081208381019083015b808210156113fe57828255908701906113ea565b5050505b50600092835260208320925b81811015611432576114208385611299565b9284019260409290920191840161140e565b50505050506101716114466040840161128c565b6002830167ffffffffffffffff82167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000008254161781555050565b600063ffffffff80831681810361149957611499611215565b6001019392505050565b6000606082360312156114b557600080fd5b6114bd610e15565b8235815260208084013567ffffffffffffffff8111156114dc57600080fd5b840136601f8201126114ed57600080fd5b80356114fb610ef282610e87565b81815260069190911b8201830190838101903683111561151a57600080fd5b928401925b8284101561157057604084360312156115385760008081fd5b611540610dc9565b843561154b8161111b565b81528486013561155a81610eab565b818701528252604093909301929084019061151f565b8085870152505050505061158660408401610ec1565b604082015292915050565b8181101561160c578c89037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee00184528751805187168a528a81015187168b8b01528b81015187168c8b015287810151888b0152850151858a018490526115f9848b0182610be7565b9950509689019692890192600101611591565b50969d9c50505050505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361165057611650611215565b506001019056fea164736f6c6343000818000a", +} + +var RMNRemoteABI = RMNRemoteMetaData.ABI + +var RMNRemoteBin = RMNRemoteMetaData.Bin + +func DeployRMNRemote(auth *bind.TransactOpts, backend bind.ContractBackend, chainSelector uint64) (common.Address, *types.Transaction, *RMNRemote, error) { + parsed, err := RMNRemoteMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(RMNRemoteBin), backend, chainSelector) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &RMNRemote{address: address, abi: *parsed, RMNRemoteCaller: RMNRemoteCaller{contract: contract}, RMNRemoteTransactor: RMNRemoteTransactor{contract: contract}, RMNRemoteFilterer: RMNRemoteFilterer{contract: contract}}, nil +} + +type RMNRemote struct { + address common.Address + abi abi.ABI + RMNRemoteCaller + RMNRemoteTransactor + RMNRemoteFilterer +} + +type RMNRemoteCaller struct { + contract *bind.BoundContract +} + +type RMNRemoteTransactor struct { + contract *bind.BoundContract +} + +type RMNRemoteFilterer struct { + contract *bind.BoundContract +} + +type RMNRemoteSession struct { + Contract *RMNRemote + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type RMNRemoteCallerSession struct { + Contract *RMNRemoteCaller + CallOpts bind.CallOpts +} + +type RMNRemoteTransactorSession struct { + Contract *RMNRemoteTransactor + TransactOpts bind.TransactOpts +} + +type RMNRemoteRaw struct { + Contract *RMNRemote +} + +type RMNRemoteCallerRaw struct { + Contract *RMNRemoteCaller +} + +type RMNRemoteTransactorRaw struct { + Contract *RMNRemoteTransactor +} + +func NewRMNRemote(address common.Address, backend bind.ContractBackend) (*RMNRemote, error) { + abi, err := abi.JSON(strings.NewReader(RMNRemoteABI)) + if err != nil { + return nil, err + } + contract, err := bindRMNRemote(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &RMNRemote{address: address, abi: abi, RMNRemoteCaller: RMNRemoteCaller{contract: contract}, RMNRemoteTransactor: RMNRemoteTransactor{contract: contract}, RMNRemoteFilterer: RMNRemoteFilterer{contract: contract}}, nil +} + +func NewRMNRemoteCaller(address common.Address, caller bind.ContractCaller) (*RMNRemoteCaller, error) { + contract, err := bindRMNRemote(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &RMNRemoteCaller{contract: contract}, nil +} + +func NewRMNRemoteTransactor(address common.Address, transactor bind.ContractTransactor) (*RMNRemoteTransactor, error) { + contract, err := bindRMNRemote(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &RMNRemoteTransactor{contract: contract}, nil +} + +func NewRMNRemoteFilterer(address common.Address, filterer bind.ContractFilterer) (*RMNRemoteFilterer, error) { + contract, err := bindRMNRemote(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &RMNRemoteFilterer{contract: contract}, nil +} + +func bindRMNRemote(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := RMNRemoteMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_RMNRemote *RMNRemoteRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RMNRemote.Contract.RMNRemoteCaller.contract.Call(opts, result, method, params...) +} + +func (_RMNRemote *RMNRemoteRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RMNRemote.Contract.RMNRemoteTransactor.contract.Transfer(opts) +} + +func (_RMNRemote *RMNRemoteRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RMNRemote.Contract.RMNRemoteTransactor.contract.Transact(opts, method, params...) +} + +func (_RMNRemote *RMNRemoteCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RMNRemote.Contract.contract.Call(opts, result, method, params...) +} + +func (_RMNRemote *RMNRemoteTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RMNRemote.Contract.contract.Transfer(opts) +} + +func (_RMNRemote *RMNRemoteTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RMNRemote.Contract.contract.Transact(opts, method, params...) +} + +func (_RMNRemote *RMNRemoteCaller) GetVersionedConfig(opts *bind.CallOpts) (RMNRemoteVersionedConfig, error) { + var out []interface{} + err := _RMNRemote.contract.Call(opts, &out, "getVersionedConfig") + + if err != nil { + return *new(RMNRemoteVersionedConfig), err + } + + out0 := *abi.ConvertType(out[0], new(RMNRemoteVersionedConfig)).(*RMNRemoteVersionedConfig) + + return out0, err + +} + +func (_RMNRemote *RMNRemoteSession) GetVersionedConfig() (RMNRemoteVersionedConfig, error) { + return _RMNRemote.Contract.GetVersionedConfig(&_RMNRemote.CallOpts) +} + +func (_RMNRemote *RMNRemoteCallerSession) GetVersionedConfig() (RMNRemoteVersionedConfig, error) { + return _RMNRemote.Contract.GetVersionedConfig(&_RMNRemote.CallOpts) +} + +func (_RMNRemote *RMNRemoteCaller) IsCursed(opts *bind.CallOpts, subject [16]byte) (bool, error) { + var out []interface{} + err := _RMNRemote.contract.Call(opts, &out, "isCursed", subject) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_RMNRemote *RMNRemoteSession) IsCursed(subject [16]byte) (bool, error) { + return _RMNRemote.Contract.IsCursed(&_RMNRemote.CallOpts, subject) +} + +func (_RMNRemote *RMNRemoteCallerSession) IsCursed(subject [16]byte) (bool, error) { + return _RMNRemote.Contract.IsCursed(&_RMNRemote.CallOpts, subject) +} + +func (_RMNRemote *RMNRemoteCaller) IsCursed0(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _RMNRemote.contract.Call(opts, &out, "isCursed0") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_RMNRemote *RMNRemoteSession) IsCursed0() (bool, error) { + return _RMNRemote.Contract.IsCursed0(&_RMNRemote.CallOpts) +} + +func (_RMNRemote *RMNRemoteCallerSession) IsCursed0() (bool, error) { + return _RMNRemote.Contract.IsCursed0(&_RMNRemote.CallOpts) +} + +func (_RMNRemote *RMNRemoteCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _RMNRemote.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_RMNRemote *RMNRemoteSession) Owner() (common.Address, error) { + return _RMNRemote.Contract.Owner(&_RMNRemote.CallOpts) +} + +func (_RMNRemote *RMNRemoteCallerSession) Owner() (common.Address, error) { + return _RMNRemote.Contract.Owner(&_RMNRemote.CallOpts) +} + +func (_RMNRemote *RMNRemoteCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _RMNRemote.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_RMNRemote *RMNRemoteSession) TypeAndVersion() (string, error) { + return _RMNRemote.Contract.TypeAndVersion(&_RMNRemote.CallOpts) +} + +func (_RMNRemote *RMNRemoteCallerSession) TypeAndVersion() (string, error) { + return _RMNRemote.Contract.TypeAndVersion(&_RMNRemote.CallOpts) +} + +func (_RMNRemote *RMNRemoteCaller) Verify(opts *bind.CallOpts, destLaneUpdates []InternalMerkleRoot, signatures []IRMNV2Signature) error { + var out []interface{} + err := _RMNRemote.contract.Call(opts, &out, "verify", destLaneUpdates, signatures) + + if err != nil { + return err + } + + return err + +} + +func (_RMNRemote *RMNRemoteSession) Verify(destLaneUpdates []InternalMerkleRoot, signatures []IRMNV2Signature) error { + return _RMNRemote.Contract.Verify(&_RMNRemote.CallOpts, destLaneUpdates, signatures) +} + +func (_RMNRemote *RMNRemoteCallerSession) Verify(destLaneUpdates []InternalMerkleRoot, signatures []IRMNV2Signature) error { + return _RMNRemote.Contract.Verify(&_RMNRemote.CallOpts, destLaneUpdates, signatures) +} + +func (_RMNRemote *RMNRemoteTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RMNRemote.contract.Transact(opts, "acceptOwnership") +} + +func (_RMNRemote *RMNRemoteSession) AcceptOwnership() (*types.Transaction, error) { + return _RMNRemote.Contract.AcceptOwnership(&_RMNRemote.TransactOpts) +} + +func (_RMNRemote *RMNRemoteTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _RMNRemote.Contract.AcceptOwnership(&_RMNRemote.TransactOpts) +} + +func (_RMNRemote *RMNRemoteTransactor) SetConfig(opts *bind.TransactOpts, newConfig RMNRemoteConfig) (*types.Transaction, error) { + return _RMNRemote.contract.Transact(opts, "setConfig", newConfig) +} + +func (_RMNRemote *RMNRemoteSession) SetConfig(newConfig RMNRemoteConfig) (*types.Transaction, error) { + return _RMNRemote.Contract.SetConfig(&_RMNRemote.TransactOpts, newConfig) +} + +func (_RMNRemote *RMNRemoteTransactorSession) SetConfig(newConfig RMNRemoteConfig) (*types.Transaction, error) { + return _RMNRemote.Contract.SetConfig(&_RMNRemote.TransactOpts, newConfig) +} + +func (_RMNRemote *RMNRemoteTransactor) Test(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RMNRemote.contract.Transact(opts, "test") +} + +func (_RMNRemote *RMNRemoteSession) Test() (*types.Transaction, error) { + return _RMNRemote.Contract.Test(&_RMNRemote.TransactOpts) +} + +func (_RMNRemote *RMNRemoteTransactorSession) Test() (*types.Transaction, error) { + return _RMNRemote.Contract.Test(&_RMNRemote.TransactOpts) +} + +func (_RMNRemote *RMNRemoteTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _RMNRemote.contract.Transact(opts, "transferOwnership", to) +} + +func (_RMNRemote *RMNRemoteSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _RMNRemote.Contract.TransferOwnership(&_RMNRemote.TransactOpts, to) +} + +func (_RMNRemote *RMNRemoteTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _RMNRemote.Contract.TransferOwnership(&_RMNRemote.TransactOpts, to) +} + +type RMNRemoteConfigSetIterator struct { + Event *RMNRemoteConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RMNRemoteConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RMNRemoteConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RMNRemoteConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RMNRemoteConfigSetIterator) Error() error { + return it.fail +} + +func (it *RMNRemoteConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RMNRemoteConfigSet struct { + VersionedConfig RMNRemoteVersionedConfig + Raw types.Log +} + +func (_RMNRemote *RMNRemoteFilterer) FilterConfigSet(opts *bind.FilterOpts) (*RMNRemoteConfigSetIterator, error) { + + logs, sub, err := _RMNRemote.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &RMNRemoteConfigSetIterator{contract: _RMNRemote.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_RMNRemote *RMNRemoteFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *RMNRemoteConfigSet) (event.Subscription, error) { + + logs, sub, err := _RMNRemote.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RMNRemoteConfigSet) + if err := _RMNRemote.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_RMNRemote *RMNRemoteFilterer) ParseConfigSet(log types.Log) (*RMNRemoteConfigSet, error) { + event := new(RMNRemoteConfigSet) + if err := _RMNRemote.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RMNRemoteOwnershipTransferRequestedIterator struct { + Event *RMNRemoteOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RMNRemoteOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RMNRemoteOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RMNRemoteOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RMNRemoteOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *RMNRemoteOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RMNRemoteOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_RMNRemote *RMNRemoteFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RMNRemoteOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _RMNRemote.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &RMNRemoteOwnershipTransferRequestedIterator{contract: _RMNRemote.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_RMNRemote *RMNRemoteFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *RMNRemoteOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _RMNRemote.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RMNRemoteOwnershipTransferRequested) + if err := _RMNRemote.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_RMNRemote *RMNRemoteFilterer) ParseOwnershipTransferRequested(log types.Log) (*RMNRemoteOwnershipTransferRequested, error) { + event := new(RMNRemoteOwnershipTransferRequested) + if err := _RMNRemote.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RMNRemoteOwnershipTransferredIterator struct { + Event *RMNRemoteOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RMNRemoteOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RMNRemoteOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RMNRemoteOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RMNRemoteOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *RMNRemoteOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RMNRemoteOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_RMNRemote *RMNRemoteFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RMNRemoteOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _RMNRemote.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &RMNRemoteOwnershipTransferredIterator{contract: _RMNRemote.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_RMNRemote *RMNRemoteFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *RMNRemoteOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _RMNRemote.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RMNRemoteOwnershipTransferred) + if err := _RMNRemote.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_RMNRemote *RMNRemoteFilterer) ParseOwnershipTransferred(log types.Log) (*RMNRemoteOwnershipTransferred, error) { + event := new(RMNRemoteOwnershipTransferred) + if err := _RMNRemote.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_RMNRemote *RMNRemote) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _RMNRemote.abi.Events["ConfigSet"].ID: + return _RMNRemote.ParseConfigSet(log) + case _RMNRemote.abi.Events["OwnershipTransferRequested"].ID: + return _RMNRemote.ParseOwnershipTransferRequested(log) + case _RMNRemote.abi.Events["OwnershipTransferred"].ID: + return _RMNRemote.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (RMNRemoteConfigSet) Topic() common.Hash { + return common.HexToHash("0x6cc65868ae41a007e6c3ed18ce591c123dd4e5864b421888c68ce92dae98cea4") +} + +func (RMNRemoteOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (RMNRemoteOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_RMNRemote *RMNRemote) Address() common.Address { + return _RMNRemote.address +} + +type RMNRemoteInterface interface { + GetVersionedConfig(opts *bind.CallOpts) (RMNRemoteVersionedConfig, error) + + IsCursed(opts *bind.CallOpts, subject [16]byte) (bool, error) + + IsCursed0(opts *bind.CallOpts) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + Verify(opts *bind.CallOpts, destLaneUpdates []InternalMerkleRoot, signatures []IRMNV2Signature) error + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, newConfig RMNRemoteConfig) (*types.Transaction, error) + + Test(opts *bind.TransactOpts) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*RMNRemoteConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *RMNRemoteConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*RMNRemoteConfigSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RMNRemoteOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *RMNRemoteOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*RMNRemoteOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RMNRemoteOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *RMNRemoteOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*RMNRemoteOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index b18205944a..a6efa69b55 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -4,14 +4,14 @@ burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMint burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPoolAndProxy/BurnMintTokenPoolAndProxy.bin 717c079d5d13300cf3c3ee871c6e5bf9af904411f204fb081a9f3b263cca1391 burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6333d0314d0bd29e75ea5e05fe62a4516ade0c6db91c30b6f93645035db52ed8 burn_with_from_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin 08ed1235dda921ce8841b26aa18d0c0f36db4884779dd7670857159801b6d597 -ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 213d4adc8634671aea16fb4207989375b1aac919b04d608f4767c29592affbf5 -ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin baf432c39ed2aa95dd25d1ae1d22c34ec9353b007e5127f8aea742125144e0e9 +ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 75955a3dcfd66b308be07eda54d6036cc79e87d3cdcf3c5c3115813c55912af8 +ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin 82d93ae8cce97a0a72f9a849f01df99e3930aead0021573abfacbc412fc77a17 commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin 274d87db70b643e00ab0a7e7845bb4b791f3b613bfc87708d33fc5a8369e2a41 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin f7128dcc2ee6dbcbc976288abcc16970ffb19b59412c5202ef6b259d2007f801 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin b0d77babbe635cd6ba04c2af049badc9e9d28a4b6ed6bb75f830ad902a618beb evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 5c02c2b167946b3467636ff2bb58594cb4652fc63d8bdfee2488ed562e2a3e50 -fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin 920b7a293165fe8306fbed0cafd866bafc5943e8759486f7803bfbbd40309b6b +fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin 7fcb78bfc6f050c9d3bd3396a29fa58c6eceec3be6f9f6e807212e816f881a4c lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin e6a8ec9e8faccb1da7d90e0f702ed72975964f97dc3222b54cfcca0a0ba3fea2 lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin e632b08be0fbd1d013e8b3a9d75293d0d532b83071c531ff2be1deec1fa48ec1 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 @@ -20,17 +20,18 @@ mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMesse mock_usdc_token_transmitter: ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin be0dbc3e475741ea0b7a54ec2b935a321b428baa9f4ce18180a87fb38bb87de2 mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin 518e19efa2ff52b0fefd8e597b05765317ee7638189bfe34ca43de2f6599faf4 multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin 0b541232e49727e947dc164eadf35963c66e67576f21baa0ecaa06a8833148ed -multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin aa299e0c2659d53aad4eace4d66be0e734b1366008593669cf30361ff529da6a +multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin 6b56e0114a4d50797d30a34aecc2641ef340451d0c3fcb9d729bba4df2435122 nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 6f64e1083b356c06ee66b9138e398b9c97a4cd3e8c9ec38cf3010cebc79af536 -ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 -offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin a3b8a9644f0d450dbf53d3371555dcc4084fb2eaf138a3797ef5cf73ed665bae -onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 1ae9e3ebefc56d0382308c67c4ec066cdf3fa3eed2d31af8015d5d8db67f9c90 +ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin 9254b35a86f00fde7b7193a033ca58f6521a66e87b9cf9da6ce5660082e79f5d +offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin e6827d4a39ed916c3ffa5a7d08b6bfa03cf101bee7207e5c96723b6a9fc761b0 +onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin c37096aaa0369ad988e94c300ba62917e17fcc71a3c1aa3e9b8420f21c0591d2 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin c1c2f8a65c7ffd971899cae7fe62f2da57d09e936151e2b92163c4bebe699d6b price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin e7781d600c1bb7aa4620106af7f6e146a109b97f4cb6a7d06c9e15773340ecb2 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 75be86323c227917a9bbc3f799d7ed02f92db546653a36db30ed0ebe64461353 -report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin 3d7ebd8d4563b63cec83b141fe9f9ef5d8ab12a7c23ccd5e7e3434aba3cab66a +report_codec: ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin 4b9252c443c87ceb7f5ac3b9d100e572fead010f7c39543315052677a3a2c597 rmn_contract: ../../../contracts/solc/v0.8.24/RMN/RMN.abi ../../../contracts/solc/v0.8.24/RMN/RMN.bin 8b45b0fb08631c6b582fd3c0b4052a79cc2b4e091e6286af1ab131bef63661f9 rmn_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.bin b048d8e752e3c41113ebb305c1efa06737ad36b4907b93e627fb0a3113023454 +rmn_remote: ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.abi ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.bin be6840d9646195c37f6fa3f95e1cb67218d04d2cebf72e698377b0a7b9cd76f4 router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 2e4f0a7826c8abb49d882bb49fc5ff20a186dbd3137624b9097ffed903ae4888 self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 8ea5d75dbc3f8afd90d22c4a665a94e02892259cd16520c1c6b4cf0dc80c9148 token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 942be7d1681ac102e0615bee13f76838ebb0b261697cf1270d2bf82c12e57aeb diff --git a/core/gethwrappers/ccip/go_generate.go b/core/gethwrappers/ccip/go_generate.go index 5c316af1ac..ba51fe13fc 100644 --- a/core/gethwrappers/ccip/go_generate.go +++ b/core/gethwrappers/ccip/go_generate.go @@ -12,6 +12,7 @@ package ccip //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin OnRamp onramp //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin EVM2EVMOffRamp evm_2_evm_offramp //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin OffRamp offramp +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.abi ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.bin RMNRemote rmn_remote //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin MultiAggregateRateLimiter multi_aggregate_rate_limiter //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin Router router //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin FeeQuoter fee_quoter diff --git a/core/scripts/go.mod b/core/scripts/go.mod index eede7f478c..93e4b2daca 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -270,7 +270,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index d7c3fee4f1..0bf25bc5c2 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1188,8 +1188,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 h1:gZsXQ//TbsaD9bcvR2wOdao7AgNDIS/Uml0FEF0vJuI= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 h1:/NYLKZOQhOAPFszrq86gPBD47Rt6TF69GnZ8Vf7qdVQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/go.mod b/go.mod index 7c2ac71a61..4045bbcc87 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 diff --git a/go.sum b/go.sum index aae278aadd..106ac0c579 100644 --- a/go.sum +++ b/go.sum @@ -1145,8 +1145,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 h1:gZsXQ//TbsaD9bcvR2wOdao7AgNDIS/Uml0FEF0vJuI= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 h1:/NYLKZOQhOAPFszrq86gPBD47Rt6TF69GnZ8Vf7qdVQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go index 1e0ee39c20..1100978bc8 100644 --- a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go +++ b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go @@ -200,8 +200,8 @@ func waitForCommitWithInterval( // the expected range. for _, mr := range report.Report.MerkleRoots { if mr.SourceChainSelector == src.Selector && - uint64(expectedSeqNumRange.Start()) == mr.Interval.Min && - uint64(expectedSeqNumRange.End()) == mr.Interval.Max { + uint64(expectedSeqNumRange.Start()) == mr.MinSeqNr && + uint64(expectedSeqNumRange.End()) == mr.MaxSeqNr { t.Logf("Received commit report on selector %d from source selector %d expected seq nr range %s", dest.Selector, src.Selector, expectedSeqNumRange.String()) return diff --git a/integration-tests/deployment/ccip/deploy.go b/integration-tests/deployment/ccip/deploy.go index be546c2e66..01368c14a4 100644 --- a/integration-tests/deployment/ccip/deploy.go +++ b/integration-tests/deployment/ccip/deploy.go @@ -16,11 +16,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_remote" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" @@ -29,7 +29,7 @@ import ( ) var ( - MockARM deployment.ContractType = "MockRMN" + RMNRemote deployment.ContractType = "RMNRemote" LinkToken deployment.ContractType = "LinkToken" ARMProxy deployment.ContractType = "ARMProxy" WETH9 deployment.ContractType = "WETH9" @@ -55,7 +55,7 @@ type Contracts interface { *router.Router | *token_admin_registry.TokenAdminRegistry | *weth9.WETH9 | - *mock_rmn_contract.MockRMNContract | + *rmn_remote.RMNRemote | *owner_helpers.ManyChainMultiSig | *owner_helpers.RBACTimelock | *offramp.OffRamp | @@ -120,7 +120,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( return ab, err } if c.Chains[c.HomeChainSel].CapabilityRegistry == nil { - return ab, fmt.Errorf("Capability registry not found for home chain %d, needs to be deployed first", c.HomeChainSel) + return ab, fmt.Errorf("capability registry not found for home chain %d, needs to be deployed first", c.HomeChainSel) } cr, err := c.Chains[c.HomeChainSel].CapabilityRegistry.GetHashedCapabilityId( &bind.CallOpts{}, CapabilityLabelledName, CapabilityVersion) @@ -222,21 +222,22 @@ func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab d e.Logger.Infow("deployed receiver", "addr", ccipReceiver.Address) // TODO: Still waiting for RMNRemote/RMNHome contracts etc. - mockARM, err := deployContract(e.Logger, chain, ab, - func(chain deployment.Chain) ContractDeploy[*mock_rmn_contract.MockRMNContract] { - mockARMAddr, tx, mockARM, err2 := mock_rmn_contract.DeployMockRMNContract( + rmnRemote, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*rmn_remote.RMNRemote] { + rmnRemoteAddr, tx, rmnRemote, err2 := rmn_remote.DeployRMNRemote( chain.DeployerKey, chain.Client, + chain.Selector, ) - return ContractDeploy[*mock_rmn_contract.MockRMNContract]{ - mockARMAddr, mockARM, tx, deployment.NewTypeAndVersion(MockARM, deployment.Version1_0_0), err2, + return ContractDeploy[*rmn_remote.RMNRemote]{ + rmnRemoteAddr, rmnRemote, tx, deployment.NewTypeAndVersion(RMNRemote, deployment.Version1_0_0), err2, } }) if err != nil { - e.Logger.Errorw("Failed to deploy mockARM", "err", err) + e.Logger.Errorw("Failed to deploy RMNRemote", "err", err) return ab, err } - e.Logger.Infow("deployed mockARM", "addr", mockARM) + e.Logger.Infow("deployed RMNRemote", "addr", rmnRemote.Address) mcm, err := deployContract(e.Logger, chain, ab, func(chain deployment.Chain) ContractDeploy[*owner_helpers.ManyChainMultiSig] { @@ -282,7 +283,7 @@ func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab d rmnProxyAddr, tx, rmnProxy, err2 := rmn_proxy_contract.DeployRMNProxyContract( chain.DeployerKey, chain.Client, - mockARM.Address, + rmnRemote.Address, ) return ContractDeploy[*rmn_proxy_contract.RMNProxyContract]{ rmnProxyAddr, rmnProxy, tx, deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0), err2, @@ -419,7 +420,7 @@ func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab d chain.Client, onramp.OnRampStaticConfig{ ChainSelector: chain.Selector, - RmnProxy: rmnProxy.Address, + Rmn: rmnProxy.Address, NonceManager: nonceManager.Address, TokenAdminRegistry: tokenAdminRegistry.Address, }, @@ -446,7 +447,7 @@ func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab d chain.Client, offramp.OffRampStaticConfig{ ChainSelector: chain.Selector, - RmnProxy: rmnProxy.Address, + Rmn: rmnProxy.Address, NonceManager: nonceManager.Address, TokenAdminRegistry: tokenAdminRegistry.Address, }, diff --git a/integration-tests/deployment/ccip/deploy_home_chain.go b/integration-tests/deployment/ccip/deploy_home_chain.go index d5b33d5050..5eb03f1d23 100644 --- a/integration-tests/deployment/ccip/deploy_home_chain.go +++ b/integration-tests/deployment/ccip/deploy_home_chain.go @@ -292,7 +292,6 @@ func AddDON( F: configF, OffchainConfigVersion: offchainConfigVersion, OfframpAddress: offRamp.Address().Bytes(), - BootstrapP2PIds: [][32]byte{bootstrapP2PID}, P2pIds: p2pIDs, Signers: signersBytes, Transmitters: transmittersBytes, diff --git a/integration-tests/deployment/ccip/state.go b/integration-tests/deployment/ccip/state.go index f641d30ed4..f129650b30 100644 --- a/integration-tests/deployment/ccip/state.go +++ b/integration-tests/deployment/ccip/state.go @@ -14,11 +14,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_remote" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" @@ -35,7 +35,7 @@ type CCIPChainState struct { TokenAdminRegistry *token_admin_registry.TokenAdminRegistry Router *router.Router Weth9 *weth9.WETH9 - MockRmn *mock_rmn_contract.MockRMNContract + RMNRemote *rmn_remote.RMNRemote // TODO: May need to support older link too LinkToken *burn_mint_erc677.BurnMintERC677 // Note we only expect one of these (on the home chain) @@ -214,12 +214,12 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type return state, err } state.ArmProxy = armProxy - case deployment.NewTypeAndVersion(MockARM, deployment.Version1_0_0).String(): - mockARM, err := mock_rmn_contract.NewMockRMNContract(common.HexToAddress(address), chain.Client) + case deployment.NewTypeAndVersion(RMNRemote, deployment.Version1_0_0).String(): + rmnRemote, err := rmn_remote.NewRMNRemote(common.HexToAddress(address), chain.Client) if err != nil { return state, err } - state.MockRmn = mockARM + state.RMNRemote = rmnRemote case deployment.NewTypeAndVersion(WETH9, deployment.Version1_0_0).String(): weth9, err := weth9.NewWETH9(common.HexToAddress(address), chain.Client) if err != nil { diff --git a/integration-tests/go.mod b/integration-tests/go.mod index ee2d0ad2d1..a8b01de133 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -36,7 +36,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 github.com/smartcontractkit/chainlink-testing-framework v1.35.0 github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 932d85d08b..c2e3905ea6 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1423,8 +1423,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 h1:gZsXQ//TbsaD9bcvR2wOdao7AgNDIS/Uml0FEF0vJuI= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 h1:/NYLKZOQhOAPFszrq86gPBD47Rt6TF69GnZ8Vf7qdVQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 6df47603b3..797e172ec6 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -59,7 +59,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 53977f3ab3..47112aa61d 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1393,8 +1393,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098 h1:gZsXQ//TbsaD9bcvR2wOdao7AgNDIS/Uml0FEF0vJuI= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240902144105-70b5719fd098/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 h1:/NYLKZOQhOAPFszrq86gPBD47Rt6TF69GnZ8Vf7qdVQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= From 5d1bf6ea07e8a243972aed98ddbceb77effd5b0a Mon Sep 17 00:00:00 2001 From: Rafael Felix Correa Date: Thu, 5 Sep 2024 16:24:13 +0200 Subject: [PATCH 294/432] ran nix flake update (#14344) --- flake.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index c5097f5a47..77dddea406 100644 --- a/flake.lock +++ b/flake.lock @@ -26,11 +26,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1719997877, - "narHash": "sha256-/Edw+w0PiGgxwnCeJycM0VgH4HtlCi91v1d8xbi+REE=", + "lastModified": 1725354688, + "narHash": "sha256-KHHFemVt6C/hbGoMzIq7cpxmjdp+KZVZaqbvx02aliY=", "owner": "shazow", "repo": "foundry.nix", - "rev": "02febba4f1cf0606d790acdb24adcf7a64afb4e1", + "rev": "671672bd60a0d2e5f6757638fdf27e806df755a4", "type": "github" }, "original": { @@ -56,11 +56,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1720957393, - "narHash": "sha256-oedh2RwpjEa+TNxhg5Je9Ch6d3W1NKi7DbRO1ziHemA=", + "lastModified": 1725103162, + "narHash": "sha256-Ym04C5+qovuQDYL/rKWSR+WESseQBbNAe5DsXNx5trY=", "owner": "nixos", "repo": "nixpkgs", - "rev": "693bc46d169f5af9c992095736e82c3488bf7dbb", + "rev": "12228ff1752d7b7624a54e9c1af4b222b3c1073b", "type": "github" }, "original": { From 70223b96e9862c02e6779cf37cc5d358766b0ea2 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Thu, 5 Sep 2024 16:57:30 +0200 Subject: [PATCH 295/432] Switch CTF path to lib (#14319) * upgrade to last version * update to pre-switch version * upgrade after merge * try commit version * switch to first CTF lib version * trigger update for the same tag but different SHA * merge and update deps * update go mod * upgrade again * merge with main --- integration-tests/actions/actions.go | 14 ++++----- .../actions/automation_ocr_helpers.go | 2 +- .../actions/automationv2/actions.go | 6 ++-- integration-tests/actions/keeper_helpers.go | 4 +-- integration-tests/actions/ocr2_helpers.go | 2 +- .../actions/ocr2_helpers_local.go | 2 +- integration-tests/actions/ocr_helpers.go | 2 +- .../actions/ocr_helpers_local.go | 2 +- integration-tests/actions/private_network.go | 6 ++-- integration-tests/actions/refund.go | 2 +- .../actions/vrf/common/actions.go | 6 ++-- .../actions/vrf/vrfv2/contract_steps.go | 2 +- .../actions/vrf/vrfv2/setup_steps.go | 2 +- .../actions/vrf/vrfv2plus/contract_steps.go | 2 +- .../actions/vrf/vrfv2plus/setup_steps.go | 2 +- integration-tests/benchmark/keeper_test.go | 20 ++++++------- .../ccip-tests/actions/ccip_helpers.go | 18 +++++------ .../ccip-tests/chaos/ccip_test.go | 6 ++-- .../ccip-tests/contracts/contract_deployer.go | 2 +- .../ccip-tests/contracts/contract_models.go | 2 +- .../ccip-tests/contracts/lm_contracts.go | 2 +- .../ccip-tests/contracts/multicall.go | 2 +- .../ccip-tests/load/ccip_multicall_loadgen.go | 4 +-- .../ccip-tests/load/ccip_test.go | 6 ++-- integration-tests/ccip-tests/load/helper.go | 4 +-- .../ccip-tests/smoke/ccip_test.go | 4 +-- .../ccip-tests/testconfig/ccip.go | 4 +-- .../ccip-tests/testconfig/global.go | 12 ++++---- .../ccip-tests/testreporters/ccip.go | 4 +-- .../ccip-tests/testsetups/ccip.go | 18 +++++------ .../ccip-tests/testsetups/test_env.go | 26 ++++++++-------- .../ccip-tests/types/config/node/core.go | 4 +-- .../chaos/automation_chaos_test.go | 20 ++++++------- integration-tests/chaos/ocr_chaos_test.go | 28 ++++++++--------- integration-tests/client/chainlink_k8s.go | 2 +- .../ethereum_contracts_automation.go | 4 +-- .../contracts/ethereum_vrf_contracts.go | 2 +- integration-tests/crib/connect.go | 10 +++---- integration-tests/crib/ocr_test.go | 4 +-- .../docker/cmd/internal/commands.go | 4 +-- integration-tests/docker/test_env/cl_node.go | 10 +++---- integration-tests/docker/test_env/test_env.go | 14 ++++----- .../docker/test_env/test_env_builder.go | 18 +++++------ .../docker/test_env/test_env_config.go | 2 +- integration-tests/experiments/gas_test.go | 6 ++-- integration-tests/go.mod | 10 +++---- integration-tests/go.sum | 20 ++++++------- integration-tests/load/README.md | 1 + .../automationv2_1/automationv2_1_test.go | 18 +++++------ .../load/automationv2_1/helpers.go | 4 +-- .../load/functions/onchain_monitoring.go | 2 +- integration-tests/load/functions/setup.go | 6 ++-- integration-tests/load/go.mod | 11 +++---- integration-tests/load/go.sum | 20 ++++++------- integration-tests/load/ocr/ocr_test.go | 2 +- integration-tests/load/ocr/vu.go | 2 +- integration-tests/load/vrfv2/gun.go | 2 +- integration-tests/load/vrfv2/vrfv2_test.go | 8 ++--- integration-tests/load/vrfv2plus/gun.go | 2 +- .../load/vrfv2plus/vrfv2plus_test.go | 8 ++--- .../migration/upgrade_version_test.go | 2 +- .../reorg/automation_reorg_test.go | 10 +++---- integration-tests/runner_helpers.go | 2 +- integration-tests/smoke/automation_test.go | 6 ++-- integration-tests/smoke/cron_test.go | 2 +- integration-tests/smoke/flux_test.go | 4 +-- integration-tests/smoke/forwarder_ocr_test.go | 4 +-- .../smoke/forwarders_ocr2_test.go | 4 +-- integration-tests/smoke/keeper_test.go | 4 +-- integration-tests/smoke/log_poller_test.go | 6 ++-- integration-tests/smoke/ocr2_test.go | 6 ++-- integration-tests/smoke/ocr_test.go | 4 +-- .../smoke/reorg_above_finality_test.go | 4 +-- integration-tests/smoke/runlog_test.go | 4 +-- integration-tests/smoke/vrf_test.go | 4 +-- integration-tests/smoke/vrfv2_test.go | 12 ++++---- integration-tests/smoke/vrfv2plus_test.go | 12 ++++---- integration-tests/soak/forwarder_ocr_test.go | 2 +- integration-tests/soak/ocr_test.go | 8 ++--- .../testconfig/common/vrf/common.go | 2 +- .../testconfig/functions/config.go | 4 +-- integration-tests/testconfig/keeper/config.go | 2 +- .../testconfig/log_poller/config.go | 2 +- integration-tests/testconfig/ocr/ocr.go | 2 +- integration-tests/testconfig/ocr2/ocr2.go | 2 +- integration-tests/testconfig/testconfig.go | 12 ++++---- .../testconfig/testconfig_test.go | 4 +-- integration-tests/testreporters/keeper.go | 2 +- .../testreporters/keeper_benchmark.go | 2 +- integration-tests/testreporters/ocr.go | 2 +- integration-tests/testreporters/profile.go | 2 +- integration-tests/testreporters/vrfv2.go | 2 +- integration-tests/testreporters/vrfv2plus.go | 2 +- .../testsetups/keeper_benchmark.go | 12 ++++---- integration-tests/testsetups/ocr.go | 30 +++++++++---------- integration-tests/types/config/node/core.go | 4 +-- integration-tests/types/testconfigs.go | 4 +-- .../universal/log_poller/helpers.go | 10 +++---- integration-tests/utils/seth.go | 6 ++-- integration-tests/utils/templates/secrets.go | 2 +- integration-tests/wrappers/contract_caller.go | 2 +- 101 files changed, 324 insertions(+), 322 deletions(-) diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index d12970f379..c420f8e672 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -20,11 +20,11 @@ import ( "github.com/ethereum/go-ethereum/rpc" "go.uber.org/zap/zapcore" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" - "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/conversions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" ethContracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/smartcontractkit/chainlink/integration-tests/wrappers" @@ -45,8 +45,8 @@ import ( "github.com/pkg/errors" "github.com/test-go/testify/require" - ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/config" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index f524f95e8a..df9168e25d 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -26,7 +26,7 @@ import ( ocr2keepers20config "github.com/smartcontractkit/chainlink-automation/pkg/v2/config" ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/actions/automationv2/actions.go b/integration-tests/actions/automationv2/actions.go index e2785f21aa..0aebec546d 100644 --- a/integration-tests/actions/automationv2/actions.go +++ b/integration-tests/actions/automationv2/actions.go @@ -44,9 +44,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/store/models" - ctf_concurrency "github.com/smartcontractkit/chainlink-testing-framework/concurrency" - ctfTestEnv "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + ctf_concurrency "github.com/smartcontractkit/chainlink-testing-framework/lib/concurrency" + ctfTestEnv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" ) type NodeDetails struct { diff --git a/integration-tests/actions/keeper_helpers.go b/integration-tests/actions/keeper_helpers.go index d5994676e4..80822a95af 100644 --- a/integration-tests/actions/keeper_helpers.go +++ b/integration-tests/actions/keeper_helpers.go @@ -14,8 +14,8 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - ctf_concurrency "github.com/smartcontractkit/chainlink-testing-framework/concurrency" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + ctf_concurrency "github.com/smartcontractkit/chainlink-testing-framework/lib/concurrency" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/ethereum/go-ethereum/common" diff --git a/integration-tests/actions/ocr2_helpers.go b/integration-tests/actions/ocr2_helpers.go index 0f8dd9b29f..f487368dfd 100644 --- a/integration-tests/actions/ocr2_helpers.go +++ b/integration-tests/actions/ocr2_helpers.go @@ -18,7 +18,7 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" + ctfClient "github.com/smartcontractkit/chainlink-testing-framework/lib/client" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" diff --git a/integration-tests/actions/ocr2_helpers_local.go b/integration-tests/actions/ocr2_helpers_local.go index 733b690355..3667aa1ef0 100644 --- a/integration-tests/actions/ocr2_helpers_local.go +++ b/integration-tests/actions/ocr2_helpers_local.go @@ -19,7 +19,7 @@ import ( "gopkg.in/guregu/null.v4" "github.com/smartcontractkit/chainlink-common/pkg/codec" - "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/core/services/job" diff --git a/integration-tests/actions/ocr_helpers.go b/integration-tests/actions/ocr_helpers.go index b0292dc518..19cad817b7 100644 --- a/integration-tests/actions/ocr_helpers.go +++ b/integration-tests/actions/ocr_helpers.go @@ -17,7 +17,7 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" + ctfClient "github.com/smartcontractkit/chainlink-testing-framework/lib/client" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/actions/ocr_helpers_local.go b/integration-tests/actions/ocr_helpers_local.go index 0b415277f2..b546139dc3 100644 --- a/integration-tests/actions/ocr_helpers_local.go +++ b/integration-tests/actions/ocr_helpers_local.go @@ -10,7 +10,7 @@ import ( "github.com/google/uuid" "golang.org/x/sync/errgroup" - "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/actions/private_network.go b/integration-tests/actions/private_network.go index f10371d41a..40fe317ab3 100644 --- a/integration-tests/actions/private_network.go +++ b/integration-tests/actions/private_network.go @@ -3,9 +3,9 @@ package actions import ( "github.com/rs/zerolog" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/config/types" - ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/lib/config/types" + ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" ) func EthereumNetworkConfigFromConfig(l zerolog.Logger, config ctf_config.GlobalTestConfig) (network ctf_test_env.EthereumNetwork, err error) { diff --git a/integration-tests/actions/refund.go b/integration-tests/actions/refund.go index d49b74c699..1835d9a04a 100644 --- a/integration-tests/actions/refund.go +++ b/integration-tests/actions/refund.go @@ -19,7 +19,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" clClient "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/actions/vrf/common/actions.go b/integration-tests/actions/vrf/common/actions.go index 59ee324ea0..67d13264c1 100644 --- a/integration-tests/actions/vrf/common/actions.go +++ b/integration-tests/actions/vrf/common/actions.go @@ -20,9 +20,9 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/conversions" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" diff --git a/integration-tests/actions/vrf/vrfv2/contract_steps.go b/integration-tests/actions/vrf/vrfv2/contract_steps.go index 305024f72d..25239537f4 100644 --- a/integration-tests/actions/vrf/vrfv2/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2/contract_steps.go @@ -13,7 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/conversions" "github.com/smartcontractkit/chainlink/integration-tests/actions" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" "github.com/smartcontractkit/chainlink/integration-tests/client" diff --git a/integration-tests/actions/vrf/vrfv2/setup_steps.go b/integration-tests/actions/vrf/vrfv2/setup_steps.go index 97948c8a1f..f252f79ffc 100644 --- a/integration-tests/actions/vrf/vrfv2/setup_steps.go +++ b/integration-tests/actions/vrf/vrfv2/setup_steps.go @@ -14,7 +14,7 @@ import ( "github.com/google/uuid" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" testconfig "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2" diff --git a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go index f3f41a0e66..4dced9edf7 100644 --- a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go @@ -13,7 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/conversions" "github.com/smartcontractkit/chainlink/integration-tests/actions" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" "github.com/smartcontractkit/chainlink/integration-tests/client" diff --git a/integration-tests/actions/vrf/vrfv2plus/setup_steps.go b/integration-tests/actions/vrf/vrfv2plus/setup_steps.go index c937046434..c88c7fdb12 100644 --- a/integration-tests/actions/vrf/vrfv2plus/setup_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/setup_steps.go @@ -15,7 +15,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" diff --git a/integration-tests/benchmark/keeper_test.go b/integration-tests/benchmark/keeper_test.go index ab54885b28..5c7ce23761 100644 --- a/integration-tests/benchmark/keeper_test.go +++ b/integration-tests/benchmark/keeper_test.go @@ -9,16 +9,16 @@ import ( "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/config" - envclient "github.com/smartcontractkit/chainlink-testing-framework/k8s/client" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/reorg" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - sethutils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + envclient "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/client" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/reorg" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + sethutils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/ccip-tests/actions/ccip_helpers.go b/integration-tests/ccip-tests/actions/ccip_helpers.go index 0bffa84291..9ff12e6f33 100644 --- a/integration-tests/ccip-tests/actions/ccip_helpers.go +++ b/integration-tests/ccip-tests/actions/ccip_helpers.go @@ -31,19 +31,19 @@ import ( "golang.org/x/exp/rand" "golang.org/x/sync/errgroup" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" chainselectors "github.com/smartcontractkit/chain-selectors" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" - ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/foundry" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/mockserver" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/reorg" - "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + ctfClient "github.com/smartcontractkit/chainlink-testing-framework/lib/client" + ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/foundry" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/reorg" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts/laneconfig" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" diff --git a/integration-tests/ccip-tests/chaos/ccip_test.go b/integration-tests/ccip-tests/chaos/ccip_test.go index 4b1dda7a91..125e683dc5 100644 --- a/integration-tests/ccip-tests/chaos/ccip_test.go +++ b/integration-tests/ccip-tests/chaos/ccip_test.go @@ -7,9 +7,9 @@ import ( "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/chaos" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/chaos" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" diff --git a/integration-tests/ccip-tests/contracts/contract_deployer.go b/integration-tests/ccip-tests/contracts/contract_deployer.go index c051531fb9..211bbc1ebb 100644 --- a/integration-tests/ccip-tests/contracts/contract_deployer.go +++ b/integration-tests/ccip-tests/contracts/contract_deployer.go @@ -22,7 +22,7 @@ import ( ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2/types" "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/ccip-tests/contracts/contract_models.go b/integration-tests/ccip-tests/contracts/contract_models.go index 9b59ce4008..e3f6e45fad 100644 --- a/integration-tests/ccip-tests/contracts/contract_models.go +++ b/integration-tests/ccip-tests/contracts/contract_models.go @@ -17,7 +17,7 @@ import ( "github.com/rs/zerolog" "golang.org/x/exp/rand" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" "github.com/smartcontractkit/chainlink/integration-tests/wrappers" diff --git a/integration-tests/ccip-tests/contracts/lm_contracts.go b/integration-tests/ccip-tests/contracts/lm_contracts.go index 2ee5078aa7..521324c11b 100644 --- a/integration-tests/ccip-tests/contracts/lm_contracts.go +++ b/integration-tests/ccip-tests/contracts/lm_contracts.go @@ -11,7 +11,7 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/wrappers" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/liquiditymanager/generated/arbitrum_l1_bridge_adapter" diff --git a/integration-tests/ccip-tests/contracts/multicall.go b/integration-tests/ccip-tests/contracts/multicall.go index 7db7f37519..094a6152be 100644 --- a/integration-tests/ccip-tests/contracts/multicall.go +++ b/integration-tests/ccip-tests/contracts/multicall.go @@ -13,7 +13,7 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/erc20" diff --git a/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go b/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go index 85f0ac222a..04fcffaa4b 100644 --- a/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go +++ b/integration-tests/ccip-tests/load/ccip_multicall_loadgen.go @@ -15,8 +15,8 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/wasp" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts" diff --git a/integration-tests/ccip-tests/load/ccip_test.go b/integration-tests/ccip-tests/load/ccip_test.go index 0d14549ec9..a8297dd209 100644 --- a/integration-tests/ccip-tests/load/ccip_test.go +++ b/integration-tests/ccip-tests/load/ccip_test.go @@ -8,9 +8,9 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/chaos" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/chaos" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" diff --git a/integration-tests/ccip-tests/load/helper.go b/integration-tests/ccip-tests/load/helper.go index 8fd2c94c08..287bf2cf0f 100644 --- a/integration-tests/ccip-tests/load/helper.go +++ b/integration-tests/ccip-tests/load/helper.go @@ -20,8 +20,8 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/chaos" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/chaos" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" diff --git a/integration-tests/ccip-tests/smoke/ccip_test.go b/integration-tests/ccip-tests/smoke/ccip_test.go index 9a34044a5d..e411c17acd 100644 --- a/integration-tests/ccip-tests/smoke/ccip_test.go +++ b/integration-tests/ccip-tests/smoke/ccip_test.go @@ -9,8 +9,8 @@ import ( "github.com/AlekSi/pointer" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool" diff --git a/integration-tests/ccip-tests/testconfig/ccip.go b/integration-tests/ccip-tests/testconfig/ccip.go index 7d9419828e..f267669732 100644 --- a/integration-tests/ccip-tests/testconfig/ccip.go +++ b/integration-tests/ccip-tests/testconfig/ccip.go @@ -10,8 +10,8 @@ import ( "github.com/rs/zerolog" "github.com/smartcontractkit/chainlink-common/pkg/config" - ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/config" - ctfK8config "github.com/smartcontractkit/chainlink-testing-framework/k8s/config" + ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + ctfK8config "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" ccipcontracts "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts" testutils "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/utils" diff --git a/integration-tests/ccip-tests/testconfig/global.go b/integration-tests/ccip-tests/testconfig/global.go index c00bfdcfea..0095b4257c 100644 --- a/integration-tests/ccip-tests/testconfig/global.go +++ b/integration-tests/ccip-tests/testconfig/global.go @@ -15,15 +15,15 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-testing-framework/utils/osutil" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/osutil" "github.com/smartcontractkit/chainlink-common/pkg/config" - ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/config" + ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/lib/config" "github.com/smartcontractkit/chainlink/integration-tests/client" ) diff --git a/integration-tests/ccip-tests/testreporters/ccip.go b/integration-tests/ccip-tests/testreporters/ccip.go index b567f6a629..d9c2908304 100644 --- a/integration-tests/ccip-tests/testreporters/ccip.go +++ b/integration-tests/ccip-tests/testreporters/ccip.go @@ -13,8 +13,8 @@ import ( "github.com/rs/zerolog" "github.com/slack-go/slack" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/config" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" ) type Phase string diff --git a/integration-tests/ccip-tests/testsetups/ccip.go b/integration-tests/ccip-tests/testsetups/ccip.go index 207773aace..eee424d50d 100644 --- a/integration-tests/ccip-tests/testsetups/ccip.go +++ b/integration-tests/ccip-tests/testsetups/ccip.go @@ -27,15 +27,15 @@ import ( chainselectors "github.com/smartcontractkit/chain-selectors" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/config/types" - ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/config" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + ctfClient "github.com/smartcontractkit/chainlink-testing-framework/lib/client" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/lib/config/types" + ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" integrationactions "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" diff --git a/integration-tests/ccip-tests/testsetups/test_env.go b/integration-tests/ccip-tests/testsetups/test_env.go index 63018c9fe4..1ba54fc7a0 100644 --- a/integration-tests/ccip-tests/testsetups/test_env.go +++ b/integration-tests/ccip-tests/testsetups/test_env.go @@ -13,24 +13,24 @@ import ( "github.com/rs/zerolog" "github.com/stretchr/testify/require" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/config/types" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + ctf_config_types "github.com/smartcontractkit/chainlink-testing-framework/lib/config/types" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/conversions" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/foundry" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/foundry" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/mockserver-cfg" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver" + mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver-cfg" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/reorg" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/reorg" "github.com/smartcontractkit/chainlink-common/pkg/config" - k8config "github.com/smartcontractkit/chainlink-testing-framework/k8s/config" + k8config "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/types/config/node" diff --git a/integration-tests/ccip-tests/types/config/node/core.go b/integration-tests/ccip-tests/types/config/node/core.go index eb12598f94..5c9defbbb5 100644 --- a/integration-tests/ccip-tests/types/config/node/core.go +++ b/integration-tests/ccip-tests/types/config/node/core.go @@ -5,8 +5,8 @@ import ( "fmt" "math/big" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" "github.com/smartcontractkit/chainlink-common/pkg/config" diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go index 467f371ad1..59b52f8e0f 100644 --- a/integration-tests/chaos/automation_chaos_test.go +++ b/integration-tests/chaos/automation_chaos_test.go @@ -11,21 +11,21 @@ import ( ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" "github.com/smartcontractkit/chainlink/integration-tests/actions/automationv2" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" "github.com/onsi/gomega" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/chaos" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/chaos" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" diff --git a/integration-tests/chaos/ocr_chaos_test.go b/integration-tests/chaos/ocr_chaos_test.go index 200c97a795..7ef03d98c8 100644 --- a/integration-tests/chaos/ocr_chaos_test.go +++ b/integration-tests/chaos/ocr_chaos_test.go @@ -9,19 +9,19 @@ import ( "github.com/onsi/gomega" "github.com/stretchr/testify/require" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/chaos" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/mockserver-cfg" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + ctfClient "github.com/smartcontractkit/chainlink-testing-framework/lib/client" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/chaos" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver" + mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver-cfg" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" @@ -84,7 +84,7 @@ func TestOCRChaos(t *testing.T) { // and chaos.NewNetworkPartition method (https://chaos-mesh.org/docs/simulate-network-chaos-on-kubernetes/) // in order to regenerate Go bindings if k8s version will be updated // you can pull new CRD spec from your current cluster and check README here - // https://github.com/smartcontractkit/chainlink-testing-framework/k8s/blob/master/README.md + // https://github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/blob/master/README.md NetworkChaosFailMajorityNetwork: { ethereum.New(nil), chainlinkCfg, diff --git a/integration-tests/client/chainlink_k8s.go b/integration-tests/client/chainlink_k8s.go index 077b8f7ca4..4cdfa96c53 100644 --- a/integration-tests/client/chainlink_k8s.go +++ b/integration-tests/client/chainlink_k8s.go @@ -6,7 +6,7 @@ import ( "github.com/rs/zerolog/log" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" ) const ( diff --git a/integration-tests/contracts/ethereum_contracts_automation.go b/integration-tests/contracts/ethereum_contracts_automation.go index 068088eda6..d9d4a730c3 100644 --- a/integration-tests/contracts/ethereum_contracts_automation.go +++ b/integration-tests/contracts/ethereum_contracts_automation.go @@ -20,8 +20,8 @@ import ( cltypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" registrylogicc23 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_logic_c_wrapper_2_3" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/smartcontractkit/chainlink/integration-tests/testreporters" diff --git a/integration-tests/contracts/ethereum_vrf_contracts.go b/integration-tests/contracts/ethereum_vrf_contracts.go index 52b178d412..144de176ee 100644 --- a/integration-tests/contracts/ethereum_vrf_contracts.go +++ b/integration-tests/contracts/ethereum_vrf_contracts.go @@ -19,7 +19,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" "github.com/smartcontractkit/chainlink/integration-tests/wrappers" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_blockhash_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/blockhash_store" diff --git a/integration-tests/crib/connect.go b/integration-tests/crib/connect.go index 48507757d8..acc16b74f9 100644 --- a/integration-tests/crib/connect.go +++ b/integration-tests/crib/connect.go @@ -4,18 +4,18 @@ import ( "net/http" "time" - "github.com/smartcontractkit/chainlink-testing-framework/crib" + "github.com/smartcontractkit/chainlink-testing-framework/lib/crib" "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - msClient "github.com/smartcontractkit/chainlink-testing-framework/client" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + msClient "github.com/smartcontractkit/chainlink-testing-framework/lib/client" "github.com/smartcontractkit/chainlink/integration-tests/client" ) diff --git a/integration-tests/crib/ocr_test.go b/integration-tests/crib/ocr_test.go index 1c855fa8d5..69804e24d7 100644 --- a/integration-tests/crib/ocr_test.go +++ b/integration-tests/crib/ocr_test.go @@ -6,15 +6,15 @@ import ( "testing" "time" - "github.com/smartcontractkit/chainlink-testing-framework/client" "github.com/smartcontractkit/chainlink-testing-framework/havoc" + "github.com/smartcontractkit/chainlink-testing-framework/lib/client" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" ) // TestCRIBChaos an example of how we can run chaos tests with havoc and core CRIB diff --git a/integration-tests/docker/cmd/internal/commands.go b/integration-tests/docker/cmd/internal/commands.go index 9939765f7f..bd9d505a7e 100644 --- a/integration-tests/docker/cmd/internal/commands.go +++ b/integration-tests/docker/cmd/internal/commands.go @@ -8,8 +8,8 @@ import ( "github.com/rs/zerolog/log" "github.com/spf13/cobra" - ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" "github.com/smartcontractkit/chainlink/integration-tests/testconfig" ) diff --git a/integration-tests/docker/test_env/cl_node.go b/integration-tests/docker/test_env/cl_node.go index b28d954688..a37a6204f6 100644 --- a/integration-tests/docker/test_env/cl_node.go +++ b/integration-tests/docker/test_env/cl_node.go @@ -21,11 +21,11 @@ import ( tc "github.com/testcontainers/testcontainers-go" tcwait "github.com/testcontainers/testcontainers-go/wait" - "github.com/smartcontractkit/chainlink-testing-framework/docker" - "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/logstream" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/docker" + "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logstream" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" diff --git a/integration-tests/docker/test_env/test_env.go b/integration-tests/docker/test_env/test_env.go index fb72025a05..52ed5d9b68 100644 --- a/integration-tests/docker/test_env/test_env.go +++ b/integration-tests/docker/test_env/test_env.go @@ -13,13 +13,13 @@ import ( "github.com/rs/zerolog/log" tc "github.com/testcontainers/testcontainers-go" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - "github.com/smartcontractkit/chainlink-testing-framework/docker" - "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/logstream" - "github.com/smartcontractkit/chainlink-testing-framework/utils/runid" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/docker" + "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logstream" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/runid" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" d "github.com/smartcontractkit/chainlink/integration-tests/docker" diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go index 3540e0e877..a26c72a853 100644 --- a/integration-tests/docker/test_env/test_env_builder.go +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -15,15 +15,15 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/logstream" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" - "github.com/smartcontractkit/chainlink-testing-framework/testsummary" - "github.com/smartcontractkit/chainlink-testing-framework/utils/osutil" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logstream" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testsummary" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/osutil" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" ) diff --git a/integration-tests/docker/test_env/test_env_config.go b/integration-tests/docker/test_env/test_env_config.go index 9aefa9615c..b29cc3e8b5 100644 --- a/integration-tests/docker/test_env/test_env_config.go +++ b/integration-tests/docker/test_env/test_env_config.go @@ -3,7 +3,7 @@ package test_env import ( "encoding/json" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" env "github.com/smartcontractkit/chainlink/integration-tests/types/envcommon" ) diff --git a/integration-tests/experiments/gas_test.go b/integration-tests/experiments/gas_test.go index 4d1f459711..42e408a152 100644 --- a/integration-tests/experiments/gas_test.go +++ b/integration-tests/experiments/gas_test.go @@ -5,12 +5,12 @@ import ( "testing" "time" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" diff --git a/integration-tests/go.mod b/integration-tests/go.mod index a8b01de133..849a1928e8 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -6,7 +6,7 @@ go 1.22.5 replace github.com/smartcontractkit/chainlink/v2 => ../ require ( - dario.cat/mergo v1.0.0 + dario.cat/mergo v1.0.1 github.com/AlekSi/pointer v1.1.0 github.com/Khan/genqlient v0.7.0 github.com/Masterminds/semver/v3 v3.2.1 @@ -38,11 +38,11 @@ require ( github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 - github.com/smartcontractkit/chainlink-testing-framework v1.35.0 - github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 - github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 + github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 + github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 - github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 + github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.1 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index c2e3905ea6..9bd0fadcb6 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -64,8 +64,8 @@ cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= @@ -1437,16 +1437,16 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.35.0 h1:5FzS4YOwzjRe59VMM7MmEyjgJCq4/aXR1fzdEJEPiL8= -github.com/smartcontractkit/chainlink-testing-framework v1.35.0/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1 h1:1/r1wQZ4TOFpZ13w94r7amdF096Z96RuEnkOmrz1BGE= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.1/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= -github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 h1:eHsvf2SklyyZ5fTHJIsIZ3eUnfO0TJU2BSZ7j8kLvzM= -github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= +github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= +github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 h1:OBOOdlZzowUt1mKDGnMzskuVqOJHSQ49w/2fTYHZEiM= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0/go.mod h1:nLOy8QkAmofo7+HR6yOyKxdaA93tHjyjz4caM+eZAn4= +github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= +github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= -github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= -github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= +github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 h1:gfhfTn7HkbUHNooSF3c9vzQyN8meWJVGt6G/pNUbpYk= +github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0/go.mod h1:tqajhpUJA/9OaMCLitghBXjAgqYO4i27St0F4TUO3+M= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= diff --git a/integration-tests/load/README.md b/integration-tests/load/README.md index afcf633e5c..46ea491c21 100644 --- a/integration-tests/load/README.md +++ b/integration-tests/load/README.md @@ -84,4 +84,5 @@ wasp_jobs = "1" keep_jobs = true ``` + And run your tests using `go test -v -run TestClusterEntrypoint` diff --git a/integration-tests/load/automationv2_1/automationv2_1_test.go b/integration-tests/load/automationv2_1/automationv2_1_test.go index cc9bbb9291..cb2606f00b 100644 --- a/integration-tests/load/automationv2_1/automationv2_1_test.go +++ b/integration-tests/load/automationv2_1/automationv2_1_test.go @@ -29,15 +29,15 @@ import ( ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/wiremock" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" - - ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/wiremock" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" + + ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/lib/config" gowiremock "github.com/wiremock/go-wiremock" diff --git a/integration-tests/load/automationv2_1/helpers.go b/integration-tests/load/automationv2_1/helpers.go index f770ba7573..41fa9a0ce1 100644 --- a/integration-tests/load/automationv2_1/helpers.go +++ b/integration-tests/load/automationv2_1/helpers.go @@ -11,8 +11,8 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - ctf_concurrency "github.com/smartcontractkit/chainlink-testing-framework/concurrency" - reportModel "github.com/smartcontractkit/chainlink-testing-framework/testreporters" + ctf_concurrency "github.com/smartcontractkit/chainlink-testing-framework/lib/concurrency" + reportModel "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" diff --git a/integration-tests/load/functions/onchain_monitoring.go b/integration-tests/load/functions/onchain_monitoring.go index 942103a78b..39c4bdcf94 100644 --- a/integration-tests/load/functions/onchain_monitoring.go +++ b/integration-tests/load/functions/onchain_monitoring.go @@ -8,7 +8,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/wasp" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" ) /* Monitors on-chain stats of LoadConsumer and pushes them to Loki every second */ diff --git a/integration-tests/load/functions/setup.go b/integration-tests/load/functions/setup.go index 8151342021..46c2c12921 100644 --- a/integration-tests/load/functions/setup.go +++ b/integration-tests/load/functions/setup.go @@ -8,7 +8,7 @@ import ( "strconv" "time" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" "github.com/ethereum/go-ethereum/crypto" "github.com/go-resty/resty/v2" @@ -19,8 +19,8 @@ import ( chainlinkutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - "github.com/smartcontractkit/chainlink-testing-framework/networks" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/types" diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 797e172ec6..264e14140e 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,9 +17,9 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 - github.com/smartcontractkit/chainlink-testing-framework v1.35.0 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 - github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 + github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 @@ -59,9 +59,11 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sergi/go-diff v1.3.1 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 // indirect + github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 // indirect + github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/sourcegraph/conc v0.3.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect @@ -73,7 +75,7 @@ exclude github.com/hashicorp/consul v1.2.1 require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect - dario.cat/mergo v1.0.0 // indirect + dario.cat/mergo v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect @@ -398,7 +400,6 @@ require ( github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect - github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.8.1 // indirect github.com/soheilhy/cmux v0.1.5 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 47112aa61d..7c5c580d1e 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -64,8 +64,8 @@ cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= @@ -1407,16 +1407,16 @@ github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= -github.com/smartcontractkit/chainlink-testing-framework v1.35.0 h1:5FzS4YOwzjRe59VMM7MmEyjgJCq4/aXR1fzdEJEPiL8= -github.com/smartcontractkit/chainlink-testing-framework v1.35.0/go.mod h1:ekYJbRAxXcs/YgOjHsY9/tlvDvXzv3lxcZK2eFUZduc= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a h1:8GtvGJaGyKzx/ar1yX74GxrzIYWTZVTyv4pYB/1ln8w= -github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.2-0.20240805111647-acf86c1e347a/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= -github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0 h1:eHsvf2SklyyZ5fTHJIsIZ3eUnfO0TJU2BSZ7j8kLvzM= -github.com/smartcontractkit/chainlink-testing-framework/havoc v0.1.0/go.mod h1:7AOGJdlSPycsHxgbOLP9EJyHxRxB9+dD2Q7lJFMPwWk= +github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= +github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 h1:OBOOdlZzowUt1mKDGnMzskuVqOJHSQ49w/2fTYHZEiM= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0/go.mod h1:nLOy8QkAmofo7+HR6yOyKxdaA93tHjyjz4caM+eZAn4= +github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= +github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= -github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10 h1:s7e9YPU/ECQ9xCyLc60ApFbf0blMjg9LWi31CAEjaZY= -github.com/smartcontractkit/chainlink-testing-framework/wasp v0.4.10/go.mod h1:E7x2ICsT8vzy0nL6wwBphoQMoNwOMl0L9voQpEl1FoM= +github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 h1:gfhfTn7HkbUHNooSF3c9vzQyN8meWJVGt6G/pNUbpYk= +github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0/go.mod h1:tqajhpUJA/9OaMCLitghBXjAgqYO4i27St0F4TUO3+M= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= diff --git a/integration-tests/load/ocr/ocr_test.go b/integration-tests/load/ocr/ocr_test.go index b5c7fa97cd..281d2da2bb 100644 --- a/integration-tests/load/ocr/ocr_test.go +++ b/integration-tests/load/ocr/ocr_test.go @@ -9,7 +9,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/wasp" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink/integration-tests/crib" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" diff --git a/integration-tests/load/ocr/vu.go b/integration-tests/load/ocr/vu.go index 8e15344610..aece9cb74b 100644 --- a/integration-tests/load/ocr/vu.go +++ b/integration-tests/load/ocr/vu.go @@ -15,7 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/wasp" - client2 "github.com/smartcontractkit/chainlink-testing-framework/client" + client2 "github.com/smartcontractkit/chainlink-testing-framework/lib/client" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" diff --git a/integration-tests/load/vrfv2/gun.go b/integration-tests/load/vrfv2/gun.go index e9e7de9bef..20a20b4083 100644 --- a/integration-tests/load/vrfv2/gun.go +++ b/integration-tests/load/vrfv2/gun.go @@ -9,7 +9,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/vrfv2" diff --git a/integration-tests/load/vrfv2/vrfv2_test.go b/integration-tests/load/vrfv2/vrfv2_test.go index 8e2a42fd21..edf68c283e 100644 --- a/integration-tests/load/vrfv2/vrfv2_test.go +++ b/integration-tests/load/vrfv2/vrfv2_test.go @@ -13,10 +13,10 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/wasp" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/vrfv2" diff --git a/integration-tests/load/vrfv2plus/gun.go b/integration-tests/load/vrfv2plus/gun.go index 3c16bbafdc..4aac392751 100644 --- a/integration-tests/load/vrfv2plus/gun.go +++ b/integration-tests/load/vrfv2plus/gun.go @@ -10,7 +10,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" "github.com/smartcontractkit/chainlink/integration-tests/actions" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" diff --git a/integration-tests/load/vrfv2plus/vrfv2plus_test.go b/integration-tests/load/vrfv2plus/vrfv2plus_test.go index 30d33aa3c6..d3f985df14 100644 --- a/integration-tests/load/vrfv2plus/vrfv2plus_test.go +++ b/integration-tests/load/vrfv2plus/vrfv2plus_test.go @@ -13,10 +13,10 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/wasp" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/vrfv2plus" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/testreporters" diff --git a/integration-tests/migration/upgrade_version_test.go b/integration-tests/migration/upgrade_version_test.go index a17f00e179..12f0c2a1e7 100644 --- a/integration-tests/migration/upgrade_version_test.go +++ b/integration-tests/migration/upgrade_version_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index 87b3aee752..15b3b74582 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -14,17 +14,17 @@ import ( "go.uber.org/zap/zapcore" ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" - sethUtils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" + sethUtils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" "github.com/smartcontractkit/chainlink/integration-tests/actions/automationv2" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" "github.com/onsi/gomega" "github.com/stretchr/testify/require" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + ctfClient "github.com/smartcontractkit/chainlink-testing-framework/lib/client" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/runner_helpers.go b/integration-tests/runner_helpers.go index def2ebdc1d..bd3ebfa3e3 100644 --- a/integration-tests/runner_helpers.go +++ b/integration-tests/runner_helpers.go @@ -17,7 +17,7 @@ import ( "github.com/manifoldco/promptui" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" ) func waitForWorkflowRun(branch, ghUser string) (string, error) { diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 39a9f75492..7844435760 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -23,9 +23,9 @@ import ( ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" - ctfTestEnv "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + ctfTestEnv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions/automationv2" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/smoke/cron_test.go b/integration-tests/smoke/cron_test.go index 98c1fe0caf..51db721518 100644 --- a/integration-tests/smoke/cron_test.go +++ b/integration-tests/smoke/cron_test.go @@ -9,7 +9,7 @@ import ( "github.com/onsi/gomega" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" diff --git a/integration-tests/smoke/flux_test.go b/integration-tests/smoke/flux_test.go index d66cdbd284..259752a534 100644 --- a/integration-tests/smoke/flux_test.go +++ b/integration-tests/smoke/flux_test.go @@ -14,8 +14,8 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" diff --git a/integration-tests/smoke/forwarder_ocr_test.go b/integration-tests/smoke/forwarder_ocr_test.go index 1eff96cb7a..4441a59288 100644 --- a/integration-tests/smoke/forwarder_ocr_test.go +++ b/integration-tests/smoke/forwarder_ocr_test.go @@ -11,8 +11,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/smoke/forwarders_ocr2_test.go b/integration-tests/smoke/forwarders_ocr2_test.go index e3cced94fd..219df9ce43 100644 --- a/integration-tests/smoke/forwarders_ocr2_test.go +++ b/integration-tests/smoke/forwarders_ocr2_test.go @@ -12,8 +12,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/smoke/keeper_test.go b/integration-tests/smoke/keeper_test.go index 29602da34f..d9875b8db7 100644 --- a/integration-tests/smoke/keeper_test.go +++ b/integration-tests/smoke/keeper_test.go @@ -17,8 +17,8 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" diff --git a/integration-tests/smoke/log_poller_test.go b/integration-tests/smoke/log_poller_test.go index 18862e13b7..c7f5483ac1 100644 --- a/integration-tests/smoke/log_poller_test.go +++ b/integration-tests/smoke/log_poller_test.go @@ -15,9 +15,9 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index 03c0d81c46..3203037ae5 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -16,9 +16,9 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/logstream" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logstream" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/v2/core/config/env" diff --git a/integration-tests/smoke/ocr_test.go b/integration-tests/smoke/ocr_test.go index 41cc1fb641..cd9db0e974 100644 --- a/integration-tests/smoke/ocr_test.go +++ b/integration-tests/smoke/ocr_test.go @@ -11,8 +11,8 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/smoke/reorg_above_finality_test.go b/integration-tests/smoke/reorg_above_finality_test.go index 78132848e5..ea7757a9e7 100644 --- a/integration-tests/smoke/reorg_above_finality_test.go +++ b/integration-tests/smoke/reorg_above_finality_test.go @@ -4,12 +4,12 @@ import ( "testing" "time" - ctf_client "github.com/smartcontractkit/chainlink-testing-framework/client" + ctf_client "github.com/smartcontractkit/chainlink-testing-framework/lib/client" "github.com/pelletier/go-toml/v2" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" diff --git a/integration-tests/smoke/runlog_test.go b/integration-tests/smoke/runlog_test.go index 1558b44732..d081619fe6 100644 --- a/integration-tests/smoke/runlog_test.go +++ b/integration-tests/smoke/runlog_test.go @@ -13,8 +13,8 @@ import ( "github.com/onsi/gomega" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" diff --git a/integration-tests/smoke/vrf_test.go b/integration-tests/smoke/vrf_test.go index 76a4a06c6f..822276222a 100644 --- a/integration-tests/smoke/vrf_test.go +++ b/integration-tests/smoke/vrf_test.go @@ -11,9 +11,9 @@ import ( "github.com/rs/zerolog" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/vrfv1" diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index 0caff0910c..872d641303 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -20,12 +20,12 @@ import ( "go.uber.org/zap/zapcore" commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" - "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/conversions" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/vrfv2" diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index aa2db33fa5..72c83aa281 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -18,12 +18,12 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/vrfv2plus" diff --git a/integration-tests/soak/forwarder_ocr_test.go b/integration-tests/soak/forwarder_ocr_test.go index 9b12978366..292693d509 100644 --- a/integration-tests/soak/forwarder_ocr_test.go +++ b/integration-tests/soak/forwarder_ocr_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink/integration-tests/actions" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" diff --git a/integration-tests/soak/ocr_test.go b/integration-tests/soak/ocr_test.go index 998af1da73..56e462ef46 100644 --- a/integration-tests/soak/ocr_test.go +++ b/integration-tests/soak/ocr_test.go @@ -4,11 +4,11 @@ import ( "fmt" "testing" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "time" @@ -18,8 +18,8 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/havoc" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" "github.com/smartcontractkit/chainlink/integration-tests/actions" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" diff --git a/integration-tests/testconfig/common/vrf/common.go b/integration-tests/testconfig/common/vrf/common.go index 326f7c98c7..49cb7c4f25 100644 --- a/integration-tests/testconfig/common/vrf/common.go +++ b/integration-tests/testconfig/common/vrf/common.go @@ -4,7 +4,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" ) type Config struct { diff --git a/integration-tests/testconfig/functions/config.go b/integration-tests/testconfig/functions/config.go index 88c0e05295..03adc2f1ec 100644 --- a/integration-tests/testconfig/functions/config.go +++ b/integration-tests/testconfig/functions/config.go @@ -6,8 +6,8 @@ import ( "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-testing-framework/utils/net" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/net" ) const ( diff --git a/integration-tests/testconfig/keeper/config.go b/integration-tests/testconfig/keeper/config.go index 0e11266d39..60bdfd8697 100644 --- a/integration-tests/testconfig/keeper/config.go +++ b/integration-tests/testconfig/keeper/config.go @@ -3,7 +3,7 @@ package keeper import ( "errors" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" ) type Config struct { diff --git a/integration-tests/testconfig/log_poller/config.go b/integration-tests/testconfig/log_poller/config.go index f6e3249432..00b61f6b1b 100644 --- a/integration-tests/testconfig/log_poller/config.go +++ b/integration-tests/testconfig/log_poller/config.go @@ -5,7 +5,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" ) type GeneratorType = string diff --git a/integration-tests/testconfig/ocr/ocr.go b/integration-tests/testconfig/ocr/ocr.go index f23d647364..d8250d407f 100644 --- a/integration-tests/testconfig/ocr/ocr.go +++ b/integration-tests/testconfig/ocr/ocr.go @@ -3,7 +3,7 @@ package ocr import ( "errors" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" ) type Config struct { diff --git a/integration-tests/testconfig/ocr2/ocr2.go b/integration-tests/testconfig/ocr2/ocr2.go index 73c9cd1005..1e7f034e04 100644 --- a/integration-tests/testconfig/ocr2/ocr2.go +++ b/integration-tests/testconfig/ocr2/ocr2.go @@ -3,7 +3,7 @@ package ocr2 import ( "errors" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" ) type Config struct { diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index d0839d7239..7ce7a07cc8 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -19,12 +19,12 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - k8s_config "github.com/smartcontractkit/chainlink-testing-framework/k8s/config" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" - "github.com/smartcontractkit/chainlink-testing-framework/utils/osutil" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + k8s_config "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/conversions" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/osutil" a_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/automation" f_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/functions" diff --git a/integration-tests/testconfig/testconfig_test.go b/integration-tests/testconfig/testconfig_test.go index 09f5402bd1..6a025c35cc 100644 --- a/integration-tests/testconfig/testconfig_test.go +++ b/integration-tests/testconfig/testconfig_test.go @@ -9,8 +9,8 @@ import ( "github.com/pelletier/go-toml/v2" "github.com/test-go/testify/require" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" a_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/automation" ) diff --git a/integration-tests/testreporters/keeper.go b/integration-tests/testreporters/keeper.go index 0861203f31..64e3cfa3d6 100644 --- a/integration-tests/testreporters/keeper.go +++ b/integration-tests/testreporters/keeper.go @@ -13,7 +13,7 @@ import ( "github.com/rs/zerolog/log" "github.com/slack-go/slack" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" "github.com/smartcontractkit/chainlink/integration-tests/client" ) diff --git a/integration-tests/testreporters/keeper_benchmark.go b/integration-tests/testreporters/keeper_benchmark.go index 6d6221fac8..c85de92493 100644 --- a/integration-tests/testreporters/keeper_benchmark.go +++ b/integration-tests/testreporters/keeper_benchmark.go @@ -14,7 +14,7 @@ import ( "github.com/rs/zerolog/log" "github.com/slack-go/slack" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" "github.com/smartcontractkit/chainlink/integration-tests/client" ) diff --git a/integration-tests/testreporters/ocr.go b/integration-tests/testreporters/ocr.go index 9a9c4d0d4a..89e24fb796 100644 --- a/integration-tests/testreporters/ocr.go +++ b/integration-tests/testreporters/ocr.go @@ -12,7 +12,7 @@ import ( "github.com/rs/zerolog/log" "github.com/slack-go/slack" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" ) //TODO: This whole process can definitely be simplified and improved, but for some reason I'm getting brain block at the moment diff --git a/integration-tests/testreporters/profile.go b/integration-tests/testreporters/profile.go index 464cfd685e..967ae9eaed 100644 --- a/integration-tests/testreporters/profile.go +++ b/integration-tests/testreporters/profile.go @@ -10,7 +10,7 @@ import ( "github.com/slack-go/slack" "golang.org/x/sync/errgroup" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" "github.com/smartcontractkit/chainlink/integration-tests/client" ) diff --git a/integration-tests/testreporters/vrfv2.go b/integration-tests/testreporters/vrfv2.go index 5f4e9dcc1f..ba17859512 100644 --- a/integration-tests/testreporters/vrfv2.go +++ b/integration-tests/testreporters/vrfv2.go @@ -8,7 +8,7 @@ import ( "github.com/slack-go/slack" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" "github.com/smartcontractkit/chainlink/integration-tests/types" ) diff --git a/integration-tests/testreporters/vrfv2plus.go b/integration-tests/testreporters/vrfv2plus.go index cb65b0f3d4..b71c0b7d92 100644 --- a/integration-tests/testreporters/vrfv2plus.go +++ b/integration-tests/testreporters/vrfv2plus.go @@ -11,7 +11,7 @@ import ( "github.com/slack-go/slack" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" ) type VRFV2PlusTestReporter struct { diff --git a/integration-tests/testsetups/keeper_benchmark.go b/integration-tests/testsetups/keeper_benchmark.go index ffe71893ba..63a5938b17 100644 --- a/integration-tests/testsetups/keeper_benchmark.go +++ b/integration-tests/testsetups/keeper_benchmark.go @@ -26,12 +26,12 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - reportModel "github.com/smartcontractkit/chainlink-testing-framework/testreporters" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + reportModel "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" diff --git a/integration-tests/testsetups/ocr.go b/integration-tests/testsetups/ocr.go index 413e2518a4..3653b9d5fb 100644 --- a/integration-tests/testsetups/ocr.go +++ b/integration-tests/testsetups/ocr.go @@ -15,8 +15,8 @@ import ( "testing" "time" - "github.com/smartcontractkit/chainlink-testing-framework/grafana" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" + "github.com/smartcontractkit/chainlink-testing-framework/lib/grafana" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" geth "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" @@ -32,19 +32,19 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/havoc" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctf_client "github.com/smartcontractkit/chainlink-testing-framework/client" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/foundry" - "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/k8s/pkg/helm/mockserver-cfg" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" - reportModel "github.com/smartcontractkit/chainlink-testing-framework/testreporters" - "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + ctf_client "github.com/smartcontractkit/chainlink-testing-framework/lib/client" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/foundry" + "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver" + mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver-cfg" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + reportModel "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" diff --git a/integration-tests/types/config/node/core.go b/integration-tests/types/config/node/core.go index 181d57a17e..7b5230f401 100644 --- a/integration-tests/types/config/node/core.go +++ b/integration-tests/types/config/node/core.go @@ -14,8 +14,8 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/config" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" itutils "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" diff --git a/integration-tests/types/testconfigs.go b/integration-tests/types/testconfigs.go index ee8a614bae..ee9183589c 100644 --- a/integration-tests/types/testconfigs.go +++ b/integration-tests/types/testconfigs.go @@ -1,8 +1,8 @@ package types import ( - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" - "github.com/smartcontractkit/chainlink-testing-framework/testreporters" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" ) diff --git a/integration-tests/universal/log_poller/helpers.go b/integration-tests/universal/log_poller/helpers.go index 4f7451d866..ec40348947 100644 --- a/integration-tests/universal/log_poller/helpers.go +++ b/integration-tests/universal/log_poller/helpers.go @@ -29,11 +29,11 @@ import ( "github.com/scylladb/go-reflectx" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctf_concurrency "github.com/smartcontractkit/chainlink-testing-framework/concurrency" - ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" - "github.com/smartcontractkit/chainlink-testing-framework/logging" - "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + ctf_concurrency "github.com/smartcontractkit/chainlink-testing-framework/lib/concurrency" + ctf_test_env "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/utils/seth.go b/integration-tests/utils/seth.go index 123a7f325e..704d954772 100644 --- a/integration-tests/utils/seth.go +++ b/integration-tests/utils/seth.go @@ -4,10 +4,10 @@ import ( "fmt" "testing" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/config" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + seth_utils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" pkg_seth "github.com/smartcontractkit/chainlink-testing-framework/seth" - seth_utils "github.com/smartcontractkit/chainlink-testing-framework/utils/seth" ) // DynamicArtifactDirConfigFn returns a function that sets Seth's artifacts directory to a unique directory for the test diff --git a/integration-tests/utils/templates/secrets.go b/integration-tests/utils/templates/secrets.go index 45edf0d012..96a16bdb3e 100644 --- a/integration-tests/utils/templates/secrets.go +++ b/integration-tests/utils/templates/secrets.go @@ -3,7 +3,7 @@ package templates import ( "github.com/google/uuid" - "github.com/smartcontractkit/chainlink-testing-framework/utils/templates" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/templates" ) // NodeSecretsTemplate are used as text templates because of secret redacted fields of chainlink.Secrets diff --git a/integration-tests/wrappers/contract_caller.go b/integration-tests/wrappers/contract_caller.go index 9703a57295..14170c7dee 100644 --- a/integration-tests/wrappers/contract_caller.go +++ b/integration-tests/wrappers/contract_caller.go @@ -17,7 +17,7 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/seth" evmClient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" ) From 2f4f44686efb5adfb9bab9e5ec2e9a1cb4c883a6 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Thu, 5 Sep 2024 18:08:44 +0200 Subject: [PATCH 296/432] update enforce CTF version (#14351) * update enforce CTF version * update path in internal action --- .github/actions/build-test-image/action.yml | 4 ++-- .github/workflows/integration-tests.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/build-test-image/action.yml b/.github/actions/build-test-image/action.yml index dcc9fefda7..af6c33bd67 100644 --- a/.github/actions/build-test-image/action.yml +++ b/.github/actions/build-test-image/action.yml @@ -37,7 +37,7 @@ runs: uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/mod-version@fc3e0df622521019f50d772726d6bf8dc919dd38 # v2.3.19 with: go-project-path: ./integration-tests - module-name: github.com/smartcontractkit/chainlink-testing-framework + module-name: github.com/smartcontractkit/chainlink-testing-framework/lib enforce-semantic-tag: false - name: Get CTF sha if: steps.version.outputs.is_semantic == 'false' @@ -84,7 +84,7 @@ runs: BASE_IMAGE_NAME: ${{ inputs.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ inputs.QA_AWS_REGION }}.amazonaws.com/test-base-image:${{ steps.long_sha.outputs.long_sha }} with: tags: ${{ env.BASE_IMAGE_NAME }} - file: ctf/k8s/Dockerfile.base + file: ctf/lib/k8s/Dockerfile.base AWS_REGION: ${{ inputs.QA_AWS_REGION }} AWS_ROLE_TO_ASSUME: ${{ inputs.QA_AWS_ROLE_TO_ASSUME }} # End Base Image Logic diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index e3a0a68280..a8884c306f 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -74,7 +74,7 @@ jobs: uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/mod-version@fc3e0df622521019f50d772726d6bf8dc919dd38 # v2.3.19 with: go-project-path: ./integration-tests - module-name: github.com/smartcontractkit/chainlink-testing-framework + module-name: github.com/smartcontractkit/chainlink-testing-framework/lib enforce-semantic-tag: "true" changes: environment: integration @@ -656,7 +656,7 @@ jobs: yarn --cwd ./gauntlet build yarn --cwd ./gauntlet gauntlet - name: Generate config overrides - run: | # https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md + run: | # https://github.com/smartcontractkit/chainlink-testing-framework/lib/blob/main/config/README.md cat << EOF > config.toml [ChainlinkImage] version="${{ inputs.evm-ref || github.sha }}" From adb3c957993f9f022db395fd54e65528631c1030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Friedemann=20F=C3=BCrst?= <59653747+friedemannf@users.noreply.github.com> Date: Thu, 5 Sep 2024 18:57:08 +0200 Subject: [PATCH 297/432] Add node level OOC error (#14315) * Add node level OOC error * Add changeset --- .changeset/green-eagles-deliver.md | 5 +++++ core/chains/evm/client/errors.go | 2 +- core/chains/evm/client/errors_test.go | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 .changeset/green-eagles-deliver.md diff --git a/.changeset/green-eagles-deliver.md b/.changeset/green-eagles-deliver.md new file mode 100644 index 0000000000..179b93b108 --- /dev/null +++ b/.changeset/green-eagles-deliver.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Handle zkEVM node level OOC error as TerminallyStuck #internal diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index 76411cb040..6882cca524 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -255,7 +255,7 @@ var zkSync = ClientErrors{ } var zkEvm = ClientErrors{ - TerminallyStuck: regexp.MustCompile(`(?:: |^)not enough .* counters to continue the execution$`), + TerminallyStuck: regexp.MustCompile(`(?:: |^)(?:not enough .* counters to continue the execution|out of counters at node level (?:.*))$`), } var aStar = ClientErrors{ diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index 7d11279d32..e647806091 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -320,6 +320,8 @@ func Test_Eth_Errors(t *testing.T) { {"failed to add tx to the pool: not enough step counters to continue the execution", true, "Xlayer"}, {"failed to add tx to the pool: not enough keccak counters to continue the execution", true, "zkEVM"}, {"failed to add tx to the pool: not enough keccak counters to continue the execution", true, "Xlayer"}, + {"RPC error response: failed to add tx to the pool: out of counters at node level (Steps)", true, "zkEVM"}, + {"RPC error response: failed to add tx to the pool: out of counters at node level (GasUsed, KeccakHashes, PoseidonHashes, PoseidonPaddings, MemAligns, Arithmetics, Binaries, Steps, Sha256Hashes)", true, "Xlayer"}, } for _, test := range tests { From 920413c3ce2ca8effc138e69ec063b0ce5e94c6b Mon Sep 17 00:00:00 2001 From: Silas Lenihan <32529249+silaslenihan@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:48:47 -0400 Subject: [PATCH 298/432] Added ChainWriter to ChainComponents interface tests (#13735) --- .changeset/loud-months-act.md | 5 + core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- ...eader_test.go => chain_components_test.go} | 132 +++++++-- ..._reader_historical_client_wrapper_test.go} | 17 +- .../chain_writer_historical_wrapper_test.go | 39 +++ ...o => chain_components_interface_tester.go} | 279 +++++++++--------- .../relay/evm/evmtesting/run_tests.go | 68 +++-- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 14 files changed, 360 insertions(+), 204 deletions(-) create mode 100644 .changeset/loud-months-act.md rename core/services/relay/evm/{chain_reader_test.go => chain_components_test.go} (60%) rename core/services/relay/evm/{evmtesting/chain_reader_historical_client_wrapper.go => chain_reader_historical_client_wrapper_test.go} (89%) create mode 100644 core/services/relay/evm/chain_writer_historical_wrapper_test.go rename core/services/relay/evm/evmtesting/{chain_reader_interface_tester.go => chain_components_interface_tester.go} (59%) diff --git a/.changeset/loud-months-act.md b/.changeset/loud-months-act.md new file mode 100644 index 0000000000..d50254acb7 --- /dev/null +++ b/.changeset/loud-months-act.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#internal Added ChainWriter to ChainReader tests diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 93e4b2daca..aa53244892 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 0bf25bc5c2..61e784345f 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1190,8 +1190,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 h1:/NYLKZOQhOAPFszrq86gPBD47Rt6TF69GnZ8Vf7qdVQ= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d h1:VVtgseTBEJN0/NcewMcka1qwslKhY1HPXs4EEpZa7ek= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= diff --git a/core/services/relay/evm/chain_reader_test.go b/core/services/relay/evm/chain_components_test.go similarity index 60% rename from core/services/relay/evm/chain_reader_test.go rename to core/services/relay/evm/chain_components_test.go index f30bba0e44..841e2d0a7e 100644 --- a/core/services/relay/evm/chain_reader_test.go +++ b/core/services/relay/evm/chain_components_test.go @@ -2,6 +2,7 @@ package evm_test import ( "context" + "crypto/ecdsa" "fmt" "math" "math/big" @@ -18,26 +19,33 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types" . "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint common practice to import test mods with . - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" commontestutils "github.com/smartcontractkit/chainlink-common/pkg/loop/testutils" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtxmgr "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + keytypes "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" . "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/evmtesting" //nolint common practice to import test mods with . ) const commonGasLimitOnEvms = uint64(4712388) -func TestChainReaderEventsInitValidation(t *testing.T) { +func TestContractReaderEventsInitValidation(t *testing.T) { tests := []struct { name string chainContractReaders map[string]types.ChainContractReader @@ -143,43 +151,77 @@ func TestChainReaderEventsInitValidation(t *testing.T) { } } -func TestChainReader(t *testing.T) { +func TestChainComponents(t *testing.T) { t.Parallel() - it := &EVMChainReaderInterfaceTester[*testing.T]{Helper: &helper{}} + it := &EVMChainComponentsInterfaceTester[*testing.T]{Helper: &helper{}} + + it.Helper.Init(t) + // add new subtests here so that it can be run on real chains too - RunChainReaderEvmTests(t, it) - RunChainReaderInterfaceTests[*testing.T](t, commontestutils.WrapChainReaderTesterForLoop(it)) + RunChainComponentsEvmTests(t, it) + RunContractReaderInterfaceTests[*testing.T](t, commontestutils.WrapContractReaderTesterForLoop(it), false) } type helper struct { - sim *backends.SimulatedBackend - auth *bind.TransactOpts + sim *backends.SimulatedBackend + accounts []*bind.TransactOpts + deployerKey *ecdsa.PrivateKey + senderKey *ecdsa.PrivateKey + txm evmtxmgr.TxManager + client client.Client + db *sqlx.DB } -func (h *helper) MustGenerateRandomKey(t *testing.T) ethkey.KeyV2 { - return cltest.MustGenerateRandomKey(t) +func (h *helper) Init(t *testing.T) { + h.SetupKeys(t) + + h.accounts = h.Accounts(t) + + h.db = pgtest.NewSqlxDB(t) + + h.Backend() + h.client = h.Client(t) + + h.txm = h.TXM(t, h.client) + h.Commit() } -func (h *helper) GasPriceBufferPercent() int64 { - return 0 +func (h *helper) SetupKeys(t *testing.T) { + deployerPkey, err := crypto.GenerateKey() + require.NoError(t, err) + h.deployerKey = deployerPkey + + senderPkey, err := crypto.GenerateKey() + require.NoError(t, err) + h.senderKey = senderPkey } -func (h *helper) SetupAuth(t *testing.T) *bind.TransactOpts { - privateKey, err := crypto.GenerateKey() +func (h *helper) Accounts(t *testing.T) []*bind.TransactOpts { + if h.accounts != nil { + return h.accounts + } + deployer, err := bind.NewKeyedTransactorWithChainID(h.deployerKey, big.NewInt(1337)) require.NoError(t, err) - h.auth, err = bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1337)) + sender, err := bind.NewKeyedTransactorWithChainID(h.senderKey, big.NewInt(1337)) require.NoError(t, err) - h.Backend() - h.Commit() - return h.auth + return []*bind.TransactOpts{deployer, sender} +} + +func (h *helper) MustGenerateRandomKey(t *testing.T) ethkey.KeyV2 { + return cltest.MustGenerateRandomKey(t) +} + +func (h *helper) GasPriceBufferPercent() int64 { + return 0 } func (h *helper) Backend() bind.ContractBackend { if h.sim == nil { h.sim = backends.NewSimulatedBackend( - core.GenesisAlloc{h.auth.From: {Balance: big.NewInt(math.MaxInt64)}}, commonGasLimitOnEvms*5000) + core.GenesisAlloc{h.accounts[0].From: {Balance: big.NewInt(math.MaxInt64)}, h.accounts[1].From: {Balance: big.NewInt(math.MaxInt64)}}, commonGasLimitOnEvms*5000) + cltest.Mine(h.sim, 1*time.Second) } return h.sim @@ -190,6 +232,9 @@ func (h *helper) Commit() { } func (h *helper) Client(t *testing.T) client.Client { + if h.client != nil { + return h.client + } return client.NewSimulatedBackendClient(t, h.sim, big.NewInt(1337)) } @@ -205,6 +250,18 @@ func (h *helper) Context(t *testing.T) context.Context { return testutils.Context(t) } +func (h *helper) ChainReaderEVMClient(ctx context.Context, t *testing.T, ht logpoller.HeadTracker, conf types.ChainReaderConfig) client.Client { + // wrap the client so that we can mock historical contract state + cwh := &evm.ClientWithContractHistory{Client: h.Client(t), HT: ht} + require.NoError(t, cwh.Init(ctx, conf)) + return cwh +} + +func (h *helper) WrappedChainWriter(cw clcommontypes.ChainWriter, client client.Client) clcommontypes.ChainWriter { + cwhw := evm.NewChainWriterHistoricalWrapper(cw, client.(*evm.ClientWithContractHistory)) + return cwhw +} + func (h *helper) MaxWaitTimeForEvents() time.Duration { // From trial and error, when running on CI, sometimes the boxes get slow maxWaitTime := time.Second * 30 @@ -216,6 +273,41 @@ func (h *helper) MaxWaitTimeForEvents() time.Duration { } maxWaitTime = time.Second * time.Duration(waitS) } - return maxWaitTime } + +func (h *helper) TXM(t *testing.T, client client.Client) evmtxmgr.TxManager { + if h.txm != nil { + return h.txm + } + db := h.db + + clconfig := configtest.NewGeneralConfigSimulated(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.Database.Listener.FallbackPollInterval = commonconfig.MustNewDuration(100 * time.Millisecond) + c.EVM[0].GasEstimator.EIP1559DynamicFees = ptr(true) + }) + + clconfig.EVMConfigs()[0].GasEstimator.PriceMax = assets.GWei(100) + + app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, clconfig, h.sim, db, client) + err := app.Start(h.Context(t)) + require.NoError(t, err) + + keyStore := app.KeyStore.Eth() + + keyStore.XXXTestingOnlyAdd(h.Context(t), keytypes.FromPrivateKey(h.deployerKey)) + require.NoError(t, keyStore.Add(h.Context(t), h.accounts[0].From, h.ChainID())) + require.NoError(t, keyStore.Enable(h.Context(t), h.accounts[0].From, h.ChainID())) + + keyStore.XXXTestingOnlyAdd(h.Context(t), keytypes.FromPrivateKey(h.senderKey)) + require.NoError(t, keyStore.Add(h.Context(t), h.accounts[1].From, h.ChainID())) + require.NoError(t, keyStore.Enable(h.Context(t), h.accounts[1].From, h.ChainID())) + + chain, err := app.GetRelayers().LegacyEVMChains().Get((h.ChainID()).String()) + require.NoError(t, err) + + h.txm = chain.TxManager() + return h.txm +} + +func ptr[T any](v T) *T { return &v } diff --git a/core/services/relay/evm/evmtesting/chain_reader_historical_client_wrapper.go b/core/services/relay/evm/chain_reader_historical_client_wrapper_test.go similarity index 89% rename from core/services/relay/evm/evmtesting/chain_reader_historical_client_wrapper.go rename to core/services/relay/evm/chain_reader_historical_client_wrapper_test.go index b3d73be28f..a3ea97650e 100644 --- a/core/services/relay/evm/evmtesting/chain_reader_historical_client_wrapper.go +++ b/core/services/relay/evm/chain_reader_historical_client_wrapper_test.go @@ -1,4 +1,4 @@ -package evmtesting +package evm import ( "context" @@ -14,9 +14,9 @@ import ( clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types" . "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint common practice to import test mods with . + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -30,7 +30,7 @@ type ClientWithContractHistory struct { func (cwh *ClientWithContractHistory) Init(_ context.Context, config types.ChainReaderConfig) error { cwh.valsWithCall = make(map[int64]valWithCall) - parsedTypes := evm.ParsedTypes{ + parsedTypes := ParsedTypes{ EncoderDefs: make(map[string]types.CodecEntry), DecoderDefs: make(map[string]types.CodecEntry), } @@ -47,12 +47,12 @@ func (cwh *ClientWithContractHistory) Init(_ context.Context, config types.Chain continue } - inputMod, err := readDef.InputModifications.ToModifier(evm.DecoderHooks...) + inputMod, err := readDef.InputModifications.ToModifier(DecoderHooks...) if err != nil { return err } - outputMod, err := readDef.OutputModifications.ToModifier(evm.DecoderHooks...) + outputMod, err := readDef.OutputModifications.ToModifier(DecoderHooks...) if err != nil { return err } @@ -67,8 +67,8 @@ func (cwh *ClientWithContractHistory) Init(_ context.Context, config types.Chain return err } - parsedTypes.EncoderDefs[evm.WrapItemType(contractName, genericName, true)] = input - parsedTypes.DecoderDefs[evm.WrapItemType(contractName, genericName, false)] = output + parsedTypes.EncoderDefs[WrapItemType(contractName, genericName, true)] = input + parsedTypes.DecoderDefs[WrapItemType(contractName, genericName, false)] = output } } @@ -90,7 +90,6 @@ func (cwh *ClientWithContractHistory) SetUintLatestValue(ctx context.Context, va ExpectedGetLatestValueArgs: forCall, val: val, } - return nil } @@ -123,7 +122,7 @@ func (cwh *ClientWithContractHistory) CallContract(ctx context.Context, msg ethe } // encode the expected call to compare with the actual call - dataToCmp, err := cwh.codec.Encode(ctx, valAndCall.Params, evm.WrapItemType(valAndCall.ContractName, valAndCall.ReadName, true)) + dataToCmp, err := cwh.codec.Encode(ctx, valAndCall.Params, WrapItemType(valAndCall.ContractName, valAndCall.ReadName, true)) if err != nil { return nil, err } diff --git a/core/services/relay/evm/chain_writer_historical_wrapper_test.go b/core/services/relay/evm/chain_writer_historical_wrapper_test.go new file mode 100644 index 0000000000..c849d1f3d5 --- /dev/null +++ b/core/services/relay/evm/chain_writer_historical_wrapper_test.go @@ -0,0 +1,39 @@ +package evm + +import ( + "context" + "math/big" + + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + interfacetesttypes "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" + primitives "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" +) + +// This wrapper is required to enable the ChainReader to access historical data +// Since the geth simulated backend doesn't support historical data, we use this +// thin wrapper. +type ChainWriterHistoricalWrapper struct { + commontypes.ChainWriter + cwh *ClientWithContractHistory +} + +func NewChainWriterHistoricalWrapper(cw commontypes.ChainWriter, cwh *ClientWithContractHistory) *ChainWriterHistoricalWrapper { + return &ChainWriterHistoricalWrapper{ChainWriter: cw, cwh: cwh} +} + +func (cwhw *ChainWriterHistoricalWrapper) SubmitTransaction(ctx context.Context, contractName, method string, args any, transactionID string, toAddress string, meta *commontypes.TxMeta, value *big.Int) error { + if primArgs, ok := args.(interfacetesttypes.PrimitiveArgs); ok { + callArgs := interfacetesttypes.ExpectedGetLatestValueArgs{ + ContractName: contractName, + ReadName: "GetAlterablePrimitiveValue", + ConfidenceLevel: primitives.Unconfirmed, + Params: nil, + ReturnVal: nil, + } + err := cwhw.cwh.SetUintLatestValue(ctx, primArgs.Value, callArgs) + if err != nil { + return err + } + } + return cwhw.ChainWriter.SubmitTransaction(ctx, contractName, method, args, transactionID, toAddress, meta, value) +} diff --git a/core/services/relay/evm/evmtesting/chain_reader_interface_tester.go b/core/services/relay/evm/evmtesting/chain_components_interface_tester.go similarity index 59% rename from core/services/relay/evm/evmtesting/chain_reader_interface_tester.go rename to core/services/relay/evm/evmtesting/chain_components_interface_tester.go index 7812ab202b..c877f48784 100644 --- a/core/services/relay/evm/evmtesting/chain_reader_interface_tester.go +++ b/core/services/relay/evm/evmtesting/chain_components_interface_tester.go @@ -3,7 +3,6 @@ package evmtesting import ( "context" "encoding/json" - "fmt" "math/big" "time" @@ -16,10 +15,14 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/codec" clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types" . "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint common practice to import test mods with . - "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + primitives "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtxmgr "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/chain_reader_tester" _ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" // force binding for tx type @@ -38,8 +41,8 @@ const ( finalityDepth = 4 ) -type EVMChainReaderInterfaceTesterHelper[T TestingT[T]] interface { - SetupAuth(t T) *bind.TransactOpts +type EVMChainComponentsInterfaceTesterHelper[T TestingT[T]] interface { + Init(t T) Client(t T) client.Client Commit() Backend() bind.ContractBackend @@ -48,21 +51,31 @@ type EVMChainReaderInterfaceTesterHelper[T TestingT[T]] interface { NewSqlxDB(t T) *sqlx.DB MaxWaitTimeForEvents() time.Duration GasPriceBufferPercent() int64 + Accounts(t T) []*bind.TransactOpts + TXM(T, client.Client) evmtxmgr.TxManager + // To enable the historical wrappers required for Simulated Backend tests. + ChainReaderEVMClient(ctx context.Context, t T, ht logpoller.HeadTracker, conf types.ChainReaderConfig) client.Client + WrappedChainWriter(cw clcommontypes.ChainWriter, client client.Client) clcommontypes.ChainWriter } -type EVMChainReaderInterfaceTester[T TestingT[T]] struct { - Helper EVMChainReaderInterfaceTesterHelper[T] - client client.Client - address string - address2 string - contractTesters map[string]*chain_reader_tester.ChainReaderTester - chainConfig types.ChainReaderConfig - auth *bind.TransactOpts - cr evm.ChainReaderService - dirtyContracts bool +type EVMChainComponentsInterfaceTester[T TestingT[T]] struct { + Helper EVMChainComponentsInterfaceTesterHelper[T] + client client.Client + address string + address2 string + contractTesters map[string]*chain_reader_tester.ChainReaderTester + chainReaderConfig types.ChainReaderConfig + chainWriterConfig types.ChainWriterConfig + deployerAuth *bind.TransactOpts + senderAuth *bind.TransactOpts + cr evm.ChainReaderService + cw evm.ChainWriterService + dirtyContracts bool + txm evmtxmgr.TxManager + gasEstimator gas.EvmFeeEstimator } -func (it *EVMChainReaderInterfaceTester[T]) Setup(t T) { +func (it *EVMChainComponentsInterfaceTester[T]) Setup(t T) { t.Cleanup(func() { // DB may be closed by the test already, ignore errors if it.cr != nil { @@ -73,6 +86,11 @@ func (it *EVMChainReaderInterfaceTester[T]) Setup(t T) { if it.dirtyContracts { it.contractTesters = nil } + + if it.cw != nil { + _ = it.cw.Close() + } + it.cw = nil }) // can re-use the same chain for tests, just make new contract for each test @@ -81,7 +99,11 @@ func (it *EVMChainReaderInterfaceTester[T]) Setup(t T) { return } - it.auth = it.Helper.SetupAuth(t) + // Need to separate accounts to ensure the nonce doesn't get misaligned after the + // contract deployments. + accounts := it.Helper.Accounts(t) + it.deployerAuth = accounts[0] + it.senderAuth = accounts[1] testStruct := CreateTestStruct[T](0, it) @@ -92,7 +114,7 @@ func (it *EVMChainReaderInterfaceTester[T]) Setup(t T) { }, } - it.chainConfig = types.ChainReaderConfig{ + it.chainReaderConfig = types.ChainReaderConfig{ Contracts: map[string]types.ChainContractReader{ AnyContractName: { ContractABI: chain_reader_tester.ChainReaderTesterMetaData.ABI, @@ -182,23 +204,90 @@ func (it *EVMChainReaderInterfaceTester[T]) Setup(t T) { }, }, } - it.client = it.Helper.Client(t) + it.GetChainReader(t) + it.txm = it.Helper.TXM(t, it.client) + it.chainWriterConfig = types.ChainWriterConfig{ + Contracts: map[string]*types.ContractConfig{ + AnyContractName: { + ContractABI: chain_reader_tester.ChainReaderTesterMetaData.ABI, + Configs: map[string]*types.ChainWriterDefinition{ + "addTestStruct": { + ChainSpecificName: "addTestStruct", + FromAddress: it.Helper.Accounts(t)[1].From, + GasLimit: 2_000_000, + Checker: "simulate", + InputModifications: codec.ModifiersConfig{ + &codec.RenameModifierConfig{Fields: map[string]string{"NestedStruct.Inner.IntVal": "I"}}, + }, + }, + "setAlterablePrimitiveValue": { + ChainSpecificName: "setAlterablePrimitiveValue", + FromAddress: it.Helper.Accounts(t)[1].From, + GasLimit: 2_000_000, + Checker: "simulate", + }, + "triggerEvent": { + ChainSpecificName: "triggerEvent", + FromAddress: it.Helper.Accounts(t)[1].From, + GasLimit: 2_000_000, + Checker: "simulate", + InputModifications: codec.ModifiersConfig{ + &codec.RenameModifierConfig{Fields: map[string]string{"NestedStruct.Inner.IntVal": "I"}}, + }, + }, + "triggerEventWithDynamicTopic": { + ChainSpecificName: "triggerEventWithDynamicTopic", + FromAddress: it.Helper.Accounts(t)[1].From, + GasLimit: 2_000_000, + Checker: "simulate", + }, + "triggerWithFourTopics": { + ChainSpecificName: "triggerWithFourTopics", + FromAddress: it.Helper.Accounts(t)[1].From, + GasLimit: 2_000_000, + Checker: "simulate", + }, + "triggerWithFourTopicsWithHashed": { + ChainSpecificName: "triggerWithFourTopicsWithHashed", + FromAddress: it.Helper.Accounts(t)[1].From, + GasLimit: 2_000_000, + Checker: "simulate", + }, + }, + }, + AnySecondContractName: { + ContractABI: chain_reader_tester.ChainReaderTesterMetaData.ABI, + Configs: map[string]*types.ChainWriterDefinition{ + "addTestStruct": { + ChainSpecificName: "addTestStruct", + FromAddress: it.Helper.Accounts(t)[1].From, + GasLimit: 2_000_000, + Checker: "simulate", + InputModifications: codec.ModifiersConfig{ + &codec.RenameModifierConfig{Fields: map[string]string{"NestedStruct.Inner.IntVal": "I"}}, + }, + }, + }, + }, + }, + MaxGasPrice: assets.NewWei(big.NewInt(1000000000000000000)), + } it.deployNewContracts(t) } -func (it *EVMChainReaderInterfaceTester[T]) Name() string { +func (it *EVMChainComponentsInterfaceTester[T]) Name() string { return "EVM" } -func (it *EVMChainReaderInterfaceTester[T]) GetAccountBytes(i int) []byte { +func (it *EVMChainComponentsInterfaceTester[T]) GetAccountBytes(i int) []byte { account := [20]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} account[i%20] += byte(i) account[(i+3)%20] += byte(i + 3) return account[:] } -func (it *EVMChainReaderInterfaceTester[T]) GetChainReader(t T) clcommontypes.ContractReader { +func (it *EVMChainComponentsInterfaceTester[T]) GetChainReader(t T) clcommontypes.ContractReader { ctx := it.Helper.Context(t) if it.cr != nil { return it.cr @@ -213,20 +302,18 @@ func (it *EVMChainReaderInterfaceTester[T]) GetChainReader(t T) clcommontypes.Co RpcBatchSize: 1, KeepFinalizedBlocksDepth: 10000, } - ht := headtracker.NewSimulatedHeadTracker(it.client, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) - lp := logpoller.NewLogPoller(logpoller.NewORM(it.Helper.ChainID(), db, lggr), it.client, lggr, ht, lpOpts) + ht := headtracker.NewSimulatedHeadTracker(it.Helper.Client(t), lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + lp := logpoller.NewLogPoller(logpoller.NewORM(it.Helper.ChainID(), db, lggr), it.Helper.Client(t), lggr, ht, lpOpts) require.NoError(t, lp.Start(ctx)) // encode and decode the config to ensure the test covers type issues - confBytes, err := json.Marshal(it.chainConfig) + confBytes, err := json.Marshal(it.chainReaderConfig) require.NoError(t, err) conf, err := types.ChainReaderConfigFromBytes(confBytes) require.NoError(t, err) - // wrap the client so that we can mock historical contract state - cwh := &ClientWithContractHistory{Client: it.Helper.Client(t), HT: ht} - require.NoError(t, cwh.Init(ctx, conf)) + cwh := it.Helper.ChainReaderEVMClient(ctx, t, ht, conf) it.client = cwh cr, err := evm.NewChainReaderService(ctx, lggr, lp, ht, it.client, conf) @@ -236,136 +323,61 @@ func (it *EVMChainReaderInterfaceTester[T]) GetChainReader(t T) clcommontypes.Co return cr } -func (it *EVMChainReaderInterfaceTester[T]) SetTestStructLatestValue(t T, testStruct *TestStruct) { - it.sendTxWithTestStruct(t, it.address, testStruct, (*chain_reader_tester.ChainReaderTesterTransactor).AddTestStruct) +// This function is no longer necessary for Simulated Backend or Testnet tests. +func (it *EVMChainComponentsInterfaceTester[T]) GenerateBlocksTillConfidenceLevel(t T, contractName, readName string, confidenceLevel primitives.ConfidenceLevel) { } -func (it *EVMChainReaderInterfaceTester[T]) SetBatchLatestValues(t T, batchCallEntry BatchCallEntry) { - nameToAddress := make(map[string]string) - boundContracts := it.GetBindings(t) - for _, bc := range boundContracts { - nameToAddress[bc.Name] = bc.Address - } - - for contractName, contractBatch := range batchCallEntry { - require.Contains(t, nameToAddress, contractName) - for _, readEntry := range contractBatch { - val, isOk := readEntry.ReturnValue.(*TestStruct) - if !isOk { - require.Fail(t, "expected *TestStruct for contract: %s read: %s, but received %T", contractName, readEntry.Name, readEntry.ReturnValue) - } - it.sendTxWithTestStruct(t, nameToAddress[contractName], val, (*chain_reader_tester.ChainReaderTesterTransactor).AddTestStruct) - } - } -} - -// SetUintLatestValue is supposed to be used for testing confidence levels, but geth simulated backend doesn't support calling past state -func (it *EVMChainReaderInterfaceTester[T]) SetUintLatestValue(t T, val uint64, forCall ExpectedGetLatestValueArgs) { - cw, ok := it.client.(*ClientWithContractHistory) - if !ok { - require.True(t, ok, "SetUintLatestValue should always be used for tests involving finality") +func (it *EVMChainComponentsInterfaceTester[T]) GetChainWriter(t T) clcommontypes.ChainWriter { + ctx := it.Helper.Context(t) + if it.cw != nil { + return it.cw } - it.sendTxWithUintVal(t, it.address, val, (*chain_reader_tester.ChainReaderTesterTransactor).SetAlterablePrimitiveValue) - require.NoError(t, cw.SetUintLatestValue(it.Helper.Context(t), val, forCall)) -} - -func (it *EVMChainReaderInterfaceTester[T]) TriggerEvent(t T, testStruct *TestStruct) { - it.sendTxWithTestStruct(t, it.address, testStruct, (*chain_reader_tester.ChainReaderTesterTransactor).TriggerEvent) -} + cw, err := evm.NewChainWriterService(logger.NullLogger, it.client, it.txm, it.gasEstimator, it.chainWriterConfig) + require.NoError(t, err) + it.cw = it.Helper.WrappedChainWriter(cw, it.client) -// GenerateBlocksTillConfidenceLevel is supposed to be used for testing confidence levels, but geth simulated backend doesn't support calling past state -func (it *EVMChainReaderInterfaceTester[T]) GenerateBlocksTillConfidenceLevel(t T, contractName, readName string, confidenceLevel primitives.ConfidenceLevel) { - contractCfg, ok := it.chainConfig.Contracts[contractName] - if !ok { - t.Errorf("contract %s not found", contractName) - return - } - readCfg, ok := contractCfg.Configs[readName] - require.True(t, ok, fmt.Sprintf("readName: %s not found for contract: %s", readName, contractName)) - toEvmConf, err := evm.ConfirmationsFromConfig(readCfg.ConfidenceConfirmations) - require.True(t, ok, fmt.Errorf("failed to parse confidence level mapping:%s not found for contract: %s readName: %s, err:%w", confidenceLevel, readName, contractName, err)) - confirmations, ok := toEvmConf[confidenceLevel] - require.True(t, ok, fmt.Sprintf("confidence level mapping:%s not found for contract: %s readName: %s", confidenceLevel, readName, contractName)) - - if confirmations == evmtypes.Finalized { - for i := 0; i < finalityDepth; i++ { - it.Helper.Commit() - } - } + require.NoError(t, err) + require.NoError(t, cw.Start(ctx)) + return it.cw } -func (it *EVMChainReaderInterfaceTester[T]) GetBindings(_ T) []clcommontypes.BoundContract { +func (it *EVMChainComponentsInterfaceTester[T]) GetBindings(_ T) []clcommontypes.BoundContract { return []clcommontypes.BoundContract{ {Name: AnyContractName, Address: it.address}, {Name: AnySecondContractName, Address: it.address2}, } } -type uintFn = func(*chain_reader_tester.ChainReaderTesterTransactor, *bind.TransactOpts, uint64) (*gethtypes.Transaction, error) - -// sendTxWithUintVal is supposed to be used for testing confidence levels, but geth simulated backend doesn't support calling past state -func (it *EVMChainReaderInterfaceTester[T]) sendTxWithUintVal(t T, contractAddress string, val uint64, fn uintFn) { - tx, err := fn( - &it.contractTesters[contractAddress].ChainReaderTesterTransactor, - it.GetAuthWithGasSet(t), - val, - ) - - require.NoError(t, err) - it.Helper.Commit() - it.IncNonce() - it.AwaitTx(t, tx) - it.dirtyContracts = true -} - -type testStructFn = func(*chain_reader_tester.ChainReaderTesterTransactor, *bind.TransactOpts, int32, string, uint8, [32]uint8, common.Address, []common.Address, *big.Int, chain_reader_tester.MidLevelTestStruct) (*gethtypes.Transaction, error) - -func (it *EVMChainReaderInterfaceTester[T]) sendTxWithTestStruct(t T, contractAddress string, testStruct *TestStruct, fn testStructFn) { - tx, err := fn( - &it.contractTesters[contractAddress].ChainReaderTesterTransactor, - it.GetAuthWithGasSet(t), - *testStruct.Field, - testStruct.DifferentField, - uint8(testStruct.OracleID), - OracleIdsToBytes(testStruct.OracleIDs), - common.Address(testStruct.Account), - ConvertAccounts(testStruct.Accounts), - testStruct.BigField, - MidToInternalType(testStruct.NestedStruct), - ) - require.NoError(t, err) - it.Helper.Commit() - it.IncNonce() - it.AwaitTx(t, tx) +func (it *EVMChainComponentsInterfaceTester[T]) DirtyContracts() { it.dirtyContracts = true } -func (it *EVMChainReaderInterfaceTester[T]) GetAuthWithGasSet(t T) *bind.TransactOpts { +func (it *EVMChainComponentsInterfaceTester[T]) GetAuthWithGasSet(t T) *bind.TransactOpts { gasPrice, err := it.client.SuggestGasPrice(it.Helper.Context(t)) require.NoError(t, err) extra := new(big.Int).Mul(gasPrice, big.NewInt(it.Helper.GasPriceBufferPercent())) extra = extra.Div(extra, big.NewInt(100)) - it.auth.GasPrice = gasPrice.Add(gasPrice, extra) - return it.auth + it.deployerAuth.GasPrice = gasPrice.Add(gasPrice, extra) + return it.deployerAuth } -func (it *EVMChainReaderInterfaceTester[T]) IncNonce() { - if it.auth.Nonce == nil { - it.auth.Nonce = big.NewInt(1) +func (it *EVMChainComponentsInterfaceTester[T]) IncNonce() { + if it.deployerAuth.Nonce == nil { + it.deployerAuth.Nonce = big.NewInt(1) } else { - it.auth.Nonce = it.auth.Nonce.Add(it.auth.Nonce, big.NewInt(1)) + it.deployerAuth.Nonce = it.deployerAuth.Nonce.Add(it.deployerAuth.Nonce, big.NewInt(1)) } } -func (it *EVMChainReaderInterfaceTester[T]) AwaitTx(t T, tx *gethtypes.Transaction) { +func (it *EVMChainComponentsInterfaceTester[T]) AwaitTx(t T, tx *gethtypes.Transaction) { ctx := it.Helper.Context(t) receipt, err := bind.WaitMined(ctx, it.client, tx) require.NoError(t, err) require.Equal(t, gethtypes.ReceiptStatusSuccessful, receipt.Status) } -func (it *EVMChainReaderInterfaceTester[T]) deployNewContracts(t T) { +func (it *EVMChainComponentsInterfaceTester[T]) deployNewContracts(t T) { // First test deploy both contracts, otherwise only deploy contracts if cleanup decides that we need to. if it.address == "" || it.contractTesters == nil { it.contractTesters = make(map[string]*chain_reader_tester.ChainReaderTester, 2) @@ -374,13 +386,14 @@ func (it *EVMChainReaderInterfaceTester[T]) deployNewContracts(t T) { it.address, it.address2 = address, address2 it.contractTesters[it.address] = ts1 it.contractTesters[it.address2] = ts2 + it.dirtyContracts = false } } -func (it *EVMChainReaderInterfaceTester[T]) deployNewContract(t T) (string, *chain_reader_tester.ChainReaderTester) { +func (it *EVMChainComponentsInterfaceTester[T]) deployNewContract(t T) (string, *chain_reader_tester.ChainReaderTester) { // 105528 was in the error: gas too low: have 0, want 105528 // Not sure if there's a better way to get it. - it.auth.GasLimit = 10552800 + it.deployerAuth.GasLimit = 10552800 address, tx, ts, err := chain_reader_tester.DeployChainReaderTester(it.GetAuthWithGasSet(t), it.Helper.Backend()) require.NoError(t, err) @@ -391,16 +404,16 @@ func (it *EVMChainReaderInterfaceTester[T]) deployNewContract(t T) (string, *cha return address.String(), ts } -func (it *EVMChainReaderInterfaceTester[T]) MaxWaitTimeForEvents() time.Duration { +func (it *EVMChainComponentsInterfaceTester[T]) MaxWaitTimeForEvents() time.Duration { return it.Helper.MaxWaitTimeForEvents() } -func OracleIdsToBytes(oracleIDs [32]commontypes.OracleID) [32]byte { - convertedIds := [32]byte{} +func OracleIDsToBytes(oracleIDs [32]commontypes.OracleID) [32]byte { + convertedIDs := [32]byte{} for i, id := range oracleIDs { - convertedIds[i] = byte(id) + convertedIDs[i] = byte(id) } - return convertedIds + return convertedIDs } func ConvertAccounts(accounts [][]byte) []common.Address { @@ -416,7 +429,7 @@ func ToInternalType(testStruct TestStruct) chain_reader_tester.TestStruct { Field: *testStruct.Field, DifferentField: testStruct.DifferentField, OracleId: byte(testStruct.OracleID), - OracleIds: OracleIdsToBytes(testStruct.OracleIDs), + OracleIds: OracleIDsToBytes(testStruct.OracleIDs), Account: common.Address(testStruct.Account), Accounts: ConvertAccounts(testStruct.Accounts), BigField: testStruct.BigField, diff --git a/core/services/relay/evm/evmtesting/run_tests.go b/core/services/relay/evm/evmtesting/run_tests.go index caa24e8ae2..8aba7c1b05 100644 --- a/core/services/relay/evm/evmtesting/run_tests.go +++ b/core/services/relay/evm/evmtesting/run_tests.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/types" clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" @@ -17,23 +18,27 @@ import ( . "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint common practice to import test mods with . ) -func RunChainReaderEvmTests[T TestingT[T]](t T, it *EVMChainReaderInterfaceTester[T]) { - RunChainReaderInterfaceTests[T](t, it) +func RunChainComponentsEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfaceTester[T]) { + RunContractReaderEvmTests[T](t, it) + // Add ChainWriter tests here +} + +func RunContractReaderEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfaceTester[T]) { + RunContractReaderInterfaceTests[T](t, it, false) t.Run("Dynamically typed topics can be used to filter and have type correct in return", func(t T) { it.Setup(t) anyString := "foo" - it.dirtyContracts = true - tx, err := it.contractTesters[it.address].ChainReaderTesterTransactor.TriggerEventWithDynamicTopic(it.GetAuthWithGasSet(t), anyString) - require.NoError(t, err) - it.Helper.Commit() - it.IncNonce() - it.AwaitTx(t, tx) ctx := it.Helper.Context(t) cr := it.GetChainReader(t) require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) + contracts := it.GetBindings(t) + type DynamicEvent struct { + Field string + } + SubmitTransactionToCW(t, it, "triggerEventWithDynamicTopic", DynamicEvent{Field: anyString}, contracts[0], types.Unconfirmed) input := struct{ Field string }{Field: anyString} tp := cr.(clcommontypes.ContractTypeProvider) @@ -53,15 +58,15 @@ func RunChainReaderEvmTests[T TestingT[T]](t T, it *EVMChainReaderInterfaceTeste t.Run("Multiple topics can filter together", func(t T) { it.Setup(t) - it.dirtyContracts = true + ctx := it.Helper.Context(t) + cr := it.GetChainReader(t) + require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) + triggerFourTopics(t, it, int32(1), int32(2), int32(3)) triggerFourTopics(t, it, int32(2), int32(2), int32(3)) triggerFourTopics(t, it, int32(1), int32(3), int32(3)) triggerFourTopics(t, it, int32(1), int32(2), int32(4)) - ctx := it.Helper.Context(t) - cr := it.GetChainReader(t) - require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) var latest struct{ Field1, Field2, Field3 int32 } params := struct{ Field1, Field2, Field3 int32 }{Field1: 1, Field2: 2, Field3: 3} @@ -75,14 +80,15 @@ func RunChainReaderEvmTests[T TestingT[T]](t T, it *EVMChainReaderInterfaceTeste t.Run("Filtering can be done on indexed topics that get hashed", func(t T) { it.Setup(t) - it.dirtyContracts = true + + cr := it.GetChainReader(t) + ctx := it.Helper.Context(t) + require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) + triggerFourTopicsWithHashed(t, it, "1", [32]uint8{2}, [32]byte{5}) triggerFourTopicsWithHashed(t, it, "2", [32]uint8{2}, [32]byte{3}) triggerFourTopicsWithHashed(t, it, "1", [32]uint8{3}, [32]byte{3}) - ctx := it.Helper.Context(t) - cr := it.GetChainReader(t) - require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) var latest struct { Field3 [32]byte } @@ -111,20 +117,22 @@ func RunChainReaderEvmTests[T TestingT[T]](t T, it *EVMChainReaderInterfaceTeste }) } -func triggerFourTopics[T TestingT[T]](t T, it *EVMChainReaderInterfaceTester[T], i1, i2, i3 int32) { - tx, err := it.contractTesters[it.address].ChainReaderTesterTransactor.TriggerWithFourTopics(it.GetAuthWithGasSet(t), i1, i2, i3) - require.NoError(t, err) - require.NoError(t, err) - it.Helper.Commit() - it.IncNonce() - it.AwaitTx(t, tx) +func triggerFourTopics[T TestingT[T]](t T, it *EVMChainComponentsInterfaceTester[T], i1, i2, i3 int32) { + type DynamicEvent struct { + Field1 int32 + Field2 int32 + Field3 int32 + } + contracts := it.GetBindings(t) + SubmitTransactionToCW(t, it, "triggerWithFourTopics", DynamicEvent{Field1: i1, Field2: i2, Field3: i3}, contracts[0], types.Unconfirmed) } -func triggerFourTopicsWithHashed[T TestingT[T]](t T, it *EVMChainReaderInterfaceTester[T], i1 string, i2 [32]uint8, i3 [32]byte) { - tx, err := it.contractTesters[it.address].ChainReaderTesterTransactor.TriggerWithFourTopicsWithHashed(it.GetAuthWithGasSet(t), i1, i2, i3) - require.NoError(t, err) - require.NoError(t, err) - it.Helper.Commit() - it.IncNonce() - it.AwaitTx(t, tx) +func triggerFourTopicsWithHashed[T TestingT[T]](t T, it *EVMChainComponentsInterfaceTester[T], i1 string, i2 [32]uint8, i3 [32]byte) { + type DynamicEvent struct { + Field1 string + Field2 [32]uint8 + Field3 [32]byte + } + contracts := it.GetBindings(t) + SubmitTransactionToCW(t, it, "triggerWithFourTopicsWithHashed", DynamicEvent{Field1: i1, Field2: i2, Field3: i3}, contracts[0], types.Unconfirmed) } diff --git a/go.mod b/go.mod index 4045bbcc87..fa8b665d97 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index 106ac0c579..70600a5898 100644 --- a/go.sum +++ b/go.sum @@ -1147,8 +1147,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 h1:/NYLKZOQhOAPFszrq86gPBD47Rt6TF69GnZ8Vf7qdVQ= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d h1:VVtgseTBEJN0/NcewMcka1qwslKhY1HPXs4EEpZa7ek= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 849a1928e8..4c4ec200b9 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -37,7 +37,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 9bd0fadcb6..1682e41682 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1425,8 +1425,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 h1:/NYLKZOQhOAPFszrq86gPBD47Rt6TF69GnZ8Vf7qdVQ= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d h1:VVtgseTBEJN0/NcewMcka1qwslKhY1HPXs4EEpZa7ek= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 264e14140e..f60e0b5063 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 7c5c580d1e..6e674b834d 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1395,8 +1395,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 h1:/NYLKZOQhOAPFszrq86gPBD47Rt6TF69GnZ8Vf7qdVQ= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d h1:VVtgseTBEJN0/NcewMcka1qwslKhY1HPXs4EEpZa7ek= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= From 718e885a53d003e16f6bc2d1be5596e63ac88b24 Mon Sep 17 00:00:00 2001 From: Will Winder Date: Thu, 5 Sep 2024 15:00:36 -0400 Subject: [PATCH 299/432] Update chainlink-ccip. (#14352) --- .changeset/tame-rules-yell.md | 5 +++++ core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 9 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 .changeset/tame-rules-yell.md diff --git a/.changeset/tame-rules-yell.md b/.changeset/tame-rules-yell.md new file mode 100644 index 0000000000..91eb82442c --- /dev/null +++ b/.changeset/tame-rules-yell.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal update chainlink-ccip version diff --git a/core/scripts/go.mod b/core/scripts/go.mod index aa53244892..55c8a9553c 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -270,7 +270,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 61e784345f..79e9f53d15 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1188,8 +1188,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 h1:/NYLKZOQhOAPFszrq86gPBD47Rt6TF69GnZ8Vf7qdVQ= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b h1:/PQDTP/ETmEXCv3qokVs5JqMcHDFP8TWdkcQAzs/nQg= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d h1:VVtgseTBEJN0/NcewMcka1qwslKhY1HPXs4EEpZa7ek= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/go.mod b/go.mod index fa8b665d97..83e64fc534 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 diff --git a/go.sum b/go.sum index 70600a5898..cae2df4414 100644 --- a/go.sum +++ b/go.sum @@ -1145,8 +1145,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 h1:/NYLKZOQhOAPFszrq86gPBD47Rt6TF69GnZ8Vf7qdVQ= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b h1:/PQDTP/ETmEXCv3qokVs5JqMcHDFP8TWdkcQAzs/nQg= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d h1:VVtgseTBEJN0/NcewMcka1qwslKhY1HPXs4EEpZa7ek= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 4c4ec200b9..1651041794 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -36,7 +36,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 1682e41682..1d6a1e8ced 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1423,8 +1423,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 h1:/NYLKZOQhOAPFszrq86gPBD47Rt6TF69GnZ8Vf7qdVQ= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b h1:/PQDTP/ETmEXCv3qokVs5JqMcHDFP8TWdkcQAzs/nQg= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d h1:VVtgseTBEJN0/NcewMcka1qwslKhY1HPXs4EEpZa7ek= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index f60e0b5063..edf2a9a8d4 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -60,7 +60,7 @@ require ( github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sergi/go-diff v1.3.1 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 // indirect github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 6e674b834d..eca3c5ddcc 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1393,8 +1393,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870 h1:/NYLKZOQhOAPFszrq86gPBD47Rt6TF69GnZ8Vf7qdVQ= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905130411-ebd9328c9870/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b h1:/PQDTP/ETmEXCv3qokVs5JqMcHDFP8TWdkcQAzs/nQg= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d h1:VVtgseTBEJN0/NcewMcka1qwslKhY1HPXs4EEpZa7ek= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= From b1c59ddfe31d53be6669df8f1cf246b222fbe3b0 Mon Sep 17 00:00:00 2001 From: DavidOrchard Date: Thu, 5 Sep 2024 15:56:22 -0700 Subject: [PATCH 300/432] add gateway connector capability config (#14325) * add gateway connector capability config * use WsHandshakeTimeoutMillis * fixes, add docs and testdata * PR comments: add chainid and collapse workflowconnectorconfig * PR comments, remove Config from names etc * use WSHandshake. * use correct array initialization --- .changeset/four-eggs-invite.md | 5 ++ core/config/capabilities_config.go | 16 +++++ core/config/docs/core.toml | 20 ++++++ core/config/toml/types.go | 49 +++++++++++++ .../services/chainlink/config_capabilities.go | 56 ++++++++++++++- core/services/chainlink/config_test.go | 11 +++ .../testdata/config-empty-effective.toml | 12 ++++ .../chainlink/testdata/config-full.toml | 12 ++++ .../config-multi-chain-effective.toml | 12 ++++ .../testdata/config-empty-effective.toml | 12 ++++ core/web/resolver/testdata/config-full.toml | 12 ++++ .../config-multi-chain-effective.toml | 12 ++++ docs/CONFIG.md | 68 +++++++++++++++++++ testdata/scripts/node/db/help.txtar | 2 +- testdata/scripts/node/validate/default.txtar | 12 ++++ .../node/validate/defaults-override.txtar | 12 ++++ .../disk-based-logging-disabled.txtar | 12 ++++ .../validate/disk-based-logging-no-dir.txtar | 12 ++++ .../node/validate/disk-based-logging.txtar | 12 ++++ .../node/validate/invalid-ocr-p2p.txtar | 12 ++++ testdata/scripts/node/validate/invalid.txtar | 12 ++++ testdata/scripts/node/validate/valid.txtar | 12 ++++ testdata/scripts/node/validate/warnings.txtar | 12 ++++ 23 files changed, 404 insertions(+), 3 deletions(-) create mode 100644 .changeset/four-eggs-invite.md diff --git a/.changeset/four-eggs-invite.md b/.changeset/four-eggs-invite.md new file mode 100644 index 0000000000..46dac304a1 --- /dev/null +++ b/.changeset/four-eggs-invite.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +configuration updates diff --git a/core/config/capabilities_config.go b/core/config/capabilities_config.go index 8c10896d09..b7e5a3b86a 100644 --- a/core/config/capabilities_config.go +++ b/core/config/capabilities_config.go @@ -11,8 +11,24 @@ type CapabilitiesExternalRegistry interface { RelayID() types.RelayID } +type GatewayConnector interface { + ChainIDForNodeKey() string + NodeAddress() string + DonID() string + Gateways() []ConnectorGateway + WSHandshakeTimeoutMillis() uint32 + AuthMinChallengeLen() int + AuthTimestampToleranceSec() uint32 +} + +type ConnectorGateway interface { + ID() string + URL() string +} + type Capabilities interface { Peering() P2P Dispatcher() Dispatcher ExternalRegistry() CapabilitiesExternalRegistry + GatewayConnector() GatewayConnector } diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index e8524c2918..2f7ff847e4 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -509,6 +509,26 @@ DeltaReconcile = '1m' # Default # but the host and port must be fully specified and cannot be empty. You can specify `0.0.0.0` (IPv4) or `::` (IPv6) to listen on all interfaces, but that is not recommended. ListenAddresses = ['1.2.3.4:9999', '[a52d:0:a88:1274::abcd]:1337'] # Example +[Capabilities.GatewayConnector] +# ChainIDForNodeKey is the ChainID of the network associated with a private key to be used for authentication with Gateway nodes +ChainIDForNodeKey = '11155111' # Example +# NodeAddress is the address of the desired private key to be used for authentication with Gateway nodes +NodeAddress = '0x68902d681c28119f9b2531473a417088bf008e59' # Example +# DonID is the Id of the Don +DonID = 'example_don' # Example +# WSHandshakeTimeoutMillis is Websocket handshake timeout +WSHandshakeTimeoutMillis = 1000 # Example +# AuthMinChallengeLen is the minimum number of bytes in authentication challenge payload +AuthMinChallengeLen = 10 # Example +# AuthTimestampToleranceSec is Authentication timestamp tolerance +AuthTimestampToleranceSec = 10 # Example + +[[Capabilities.GatewayConnector.Gateways]] +# ID of the Gateway +ID = 'example_gateway' # Example +# URL of the Gateway +URL = 'wss://localhost:8081/node' # Example + [Keeper] # **ADVANCED** # DefaultTransactionQueueDepth controls the queue size for `DropOldestStrategy` in Keeper. Set to 0 to use `SendEvery` strategy instead. diff --git a/core/config/toml/types.go b/core/config/toml/types.go index 47c8cb46b7..f89ecab9c0 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -5,6 +5,7 @@ import ( "fmt" "net" "net/url" + "reflect" "regexp" "strings" @@ -25,6 +26,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/store/dialects" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" + configutils "github.com/smartcontractkit/chainlink/v2/core/utils/config" ) @@ -1478,16 +1480,63 @@ func (drl *DispatcherRateLimit) setFrom(f *DispatcherRateLimit) { } } +type GatewayConnector struct { + ChainIDForNodeKey *string + NodeAddress *string + DonID *string + Gateways []ConnectorGateway + WSHandshakeTimeoutMillis *uint32 + AuthMinChallengeLen *int + AuthTimestampToleranceSec *uint32 +} + +func (r *GatewayConnector) setFrom(f *GatewayConnector) { + if f.ChainIDForNodeKey != nil { + r.ChainIDForNodeKey = f.ChainIDForNodeKey + } + + if f.NodeAddress != nil { + r.NodeAddress = f.NodeAddress + } + + if f.DonID != nil { + r.DonID = f.DonID + } + + if f.Gateways != nil { + r.Gateways = f.Gateways + } + + if !reflect.ValueOf(f.WSHandshakeTimeoutMillis).IsZero() { + r.WSHandshakeTimeoutMillis = f.WSHandshakeTimeoutMillis + } + + if f.AuthMinChallengeLen != nil { + r.AuthMinChallengeLen = f.AuthMinChallengeLen + } + + if f.AuthTimestampToleranceSec != nil { + r.AuthTimestampToleranceSec = f.AuthTimestampToleranceSec + } +} + +type ConnectorGateway struct { + ID *string + URL *string +} + type Capabilities struct { Peering P2P `toml:",omitempty"` Dispatcher Dispatcher `toml:",omitempty"` ExternalRegistry ExternalRegistry `toml:",omitempty"` + GatewayConnector GatewayConnector `toml:",omitempty"` } func (c *Capabilities) setFrom(f *Capabilities) { c.Peering.setFrom(&f.Peering) c.ExternalRegistry.setFrom(&f.ExternalRegistry) c.Dispatcher.setFrom(&f.Dispatcher) + c.GatewayConnector.setFrom(&f.GatewayConnector) } type ThresholdKeyShareSecrets struct { diff --git a/core/services/chainlink/config_capabilities.go b/core/services/chainlink/config_capabilities.go index 734a5ae270..032eec58be 100644 --- a/core/services/chainlink/config_capabilities.go +++ b/core/services/chainlink/config_capabilities.go @@ -1,10 +1,9 @@ package chainlink import ( + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/config/toml" - - "github.com/smartcontractkit/chainlink-common/pkg/types" ) var _ config.Capabilities = (*capabilitiesConfig)(nil) @@ -63,6 +62,12 @@ func (r *dispatcherRateLimit) PerSenderBurst() int { return *r.r.PerSenderBurst } +func (c *capabilitiesConfig) GatewayConnector() config.GatewayConnector { + return &gatewayConnector{ + c: c.c.GatewayConnector, + } +} + type capabilitiesExternalRegistry struct { c toml.ExternalRegistry } @@ -82,3 +87,50 @@ func (c *capabilitiesExternalRegistry) ChainID() string { func (c *capabilitiesExternalRegistry) Address() string { return *c.c.Address } + +type gatewayConnector struct { + c toml.GatewayConnector +} + +func (c *gatewayConnector) ChainIDForNodeKey() string { + return *c.c.ChainIDForNodeKey +} +func (c *gatewayConnector) NodeAddress() string { + return *c.c.NodeAddress +} + +func (c *gatewayConnector) DonID() string { + return *c.c.DonID +} + +func (c *gatewayConnector) Gateways() []config.ConnectorGateway { + t := make([]config.ConnectorGateway, len(c.c.Gateways)) + for index, element := range c.c.Gateways { + t[index] = &connectorGateway{element} + } + return t +} + +func (c *gatewayConnector) WSHandshakeTimeoutMillis() uint32 { + return *c.c.WSHandshakeTimeoutMillis +} + +func (c *gatewayConnector) AuthMinChallengeLen() int { + return *c.c.AuthMinChallengeLen +} + +func (c *gatewayConnector) AuthTimestampToleranceSec() uint32 { + return *c.c.AuthTimestampToleranceSec +} + +type connectorGateway struct { + c toml.ConnectorGateway +} + +func (c *connectorGateway) ID() string { + return *c.c.ID +} + +func (c *connectorGateway) URL() string { + return *c.c.URL +} diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 7b91583308..cba3c9ea05 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -462,6 +462,17 @@ func TestConfig_Marshal(t *testing.T) { PerSenderBurst: ptr(50), }, }, + GatewayConnector: toml.GatewayConnector{ + ChainIDForNodeKey: ptr("11155111"), + NodeAddress: ptr("0x68902d681c28119f9b2531473a417088bf008e59"), + DonID: ptr("example_don"), + WSHandshakeTimeoutMillis: ptr[uint32](100), + AuthMinChallengeLen: ptr[int](10), + AuthTimestampToleranceSec: ptr[uint32](10), + Gateways: []toml.ConnectorGateway{ + {ID: ptr("example_gateway"), URL: ptr("wss://localhost:8081/node")}, + }, + }, } full.Keeper = toml.Keeper{ DefaultTransactionQueueDepth: ptr[uint32](17), diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index 6050401634..aff5075428 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -267,3 +267,15 @@ PerSenderBurst = 50 Address = '' NetworkID = 'evm' ChainID = '1' + +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 80d2ca7fbb..2202c60192 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -278,6 +278,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '11155111' +NodeAddress = '0x68902d681c28119f9b2531473a417088bf008e59' +DonID = 'example_don' +WSHandshakeTimeoutMillis = 100 +AuthMinChallengeLen = 10 +AuthTimestampToleranceSec = 10 + +[[Capabilities.GatewayConnector.Gateways]] +ID = 'example_gateway' +URL = 'wss://localhost:8081/node' + [[EVM]] ChainID = '1' Enabled = false diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 6a1cda457e..91d00841de 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -268,6 +268,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index 6050401634..aff5075428 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -267,3 +267,15 @@ PerSenderBurst = 50 Address = '' NetworkID = 'evm' ChainID = '1' + +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index c10f68dd24..f50e3c76ad 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -278,6 +278,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '11155111' +NodeAddress = '0x68902d681c28119f9b2531473a417088bf008e59' +DonID = 'example_don' +WSHandshakeTimeoutMillis = 100 +AuthMinChallengeLen = 10 +AuthTimestampToleranceSec = 10 + +[[Capabilities.GatewayConnector.Gateways]] +ID = 'example_gateway' +URL = 'wss://localhost:8081/node' + [[EVM]] ChainID = '1' Enabled = false diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index d7513ada26..5e68ba21d1 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -268,6 +268,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 66ce21a21e..e3d5058a3b 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1393,6 +1393,74 @@ ListenAddresses = ['1.2.3.4:9999', '[a52d:0:a88:1274::abcd]:1337'] # Example ListenAddresses is the addresses the peer will listen to on the network in `host:port` form as accepted by `net.Listen()`, but the host and port must be fully specified and cannot be empty. You can specify `0.0.0.0` (IPv4) or `::` (IPv6) to listen on all interfaces, but that is not recommended. +## Capabilities.GatewayConnector +```toml +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '11155111' # Example +NodeAddress = '0x68902d681c28119f9b2531473a417088bf008e59' # Example +DonID = 'example_don' # Example +WSHandshakeTimeoutMillis = 1000 # Example +AuthMinChallengeLen = 10 # Example +AuthTimestampToleranceSec = 10 # Example +``` + + +### ChainIDForNodeKey +```toml +ChainIDForNodeKey = '11155111' # Example +``` +ChainIDForNodeKey is the ChainID of the network associated with a private key to be used for authentication with Gateway nodes + +### NodeAddress +```toml +NodeAddress = '0x68902d681c28119f9b2531473a417088bf008e59' # Example +``` +NodeAddress is the address of the desired private key to be used for authentication with Gateway nodes + +### DonID +```toml +DonID = 'example_don' # Example +``` +DonID is the Id of the Don + +### WSHandshakeTimeoutMillis +```toml +WSHandshakeTimeoutMillis = 1000 # Example +``` +WSHandshakeTimeoutMillis is Websocket handshake timeout + +### AuthMinChallengeLen +```toml +AuthMinChallengeLen = 10 # Example +``` +AuthMinChallengeLen is the minimum number of bytes in authentication challenge payload + +### AuthTimestampToleranceSec +```toml +AuthTimestampToleranceSec = 10 # Example +``` +AuthTimestampToleranceSec is Authentication timestamp tolerance + +## Capabilities.GatewayConnector.Gateways +```toml +[[Capabilities.GatewayConnector.Gateways]] +ID = 'example_gateway' # Example +URL = 'wss://localhost:8081/node' # Example +``` + + +### ID +```toml +ID = 'example_gateway' # Example +``` +ID of the Gateway + +### URL +```toml +URL = 'wss://localhost:8081/node' # Example +``` +URL of the Gateway + ## Keeper ```toml [Keeper] diff --git a/testdata/scripts/node/db/help.txtar b/testdata/scripts/node/db/help.txtar index 4f2fe3e076..ccdf343178 100644 --- a/testdata/scripts/node/db/help.txtar +++ b/testdata/scripts/node/db/help.txtar @@ -20,4 +20,4 @@ COMMANDS: OPTIONS: --help, -h show help - \ No newline at end of file + diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index cca4f4ef5e..1177b0d97e 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -280,6 +280,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' + Invalid configuration: invalid secrets: 2 errors: - Database.URL: empty: must be provided and non-empty - Password.Keystore: empty: must be provided and non-empty diff --git a/testdata/scripts/node/validate/defaults-override.txtar b/testdata/scripts/node/validate/defaults-override.txtar index d419443711..47555b4bdd 100644 --- a/testdata/scripts/node/validate/defaults-override.txtar +++ b/testdata/scripts/node/validate/defaults-override.txtar @@ -341,6 +341,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index c180178920..43a7b5a1df 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -324,6 +324,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 72832f3783..f108e30356 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -324,6 +324,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 7921d124c4..f84ce5da40 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -324,6 +324,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar index 3fe384e487..a434f75048 100644 --- a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -309,6 +309,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' + Invalid configuration: invalid configuration: P2P.V2.Enabled: invalid value (false): P2P required for OCR or OCR2. Please enable P2P or disable OCR/OCR2. -- err.txt -- diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 66ca83e03e..016a02e088 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -314,6 +314,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index 166db265d5..c4d188bff0 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -321,6 +321,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index ed727815b3..f900bc9626 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -303,6 +303,18 @@ Address = '' NetworkID = 'evm' ChainID = '1' +[Capabilities.GatewayConnector] +ChainIDForNodeKey = '' +NodeAddress = '' +DonID = '' +WSHandshakeTimeoutMillis = 0 +AuthMinChallengeLen = 0 +AuthTimestampToleranceSec = 0 + +[[Capabilities.GatewayConnector.Gateways]] +ID = '' +URL = '' + # Configuration warning: Tracing.TLSCertPath: invalid value (something): must be empty when Tracing.Mode is 'unencrypted' Valid configuration. From 606e530522060cb0f02dc3b30360adc79eee08b3 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Fri, 6 Sep 2024 13:28:45 +0200 Subject: [PATCH 301/432] [TT-1609] Notify about compatibility pipeline failure if building image failed (#14358) * notify on slack if building chainlink image failed in compat pipeline * fail image build on purpose * change order of checks * remove failure on purpose * fail cron test on purpose * remove on-purpose test failure --- .github/workflows/client-compatibility-tests.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index af57575068..e61829c933 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -98,15 +98,21 @@ jobs: id: should-run run: | if [ "${{ needs.check-dependency-bump.outputs.dependency_changed }}" == "true" ]; then + echo "## Build trigger" >> $GITHUB_STEP_SUMMARY + echo "go-ethereum dependency bump" >> $GITHUB_STEP_SUMMARY echo "Will run tests, because go-ethereum dependency was bumped" echo "should_run=true" >> $GITHUB_OUTPUT elif [ "$GITHUB_EVENT_NAME" = "schedule" ]; then + echo "## Build trigger" >> $GITHUB_STEP_SUMMARY + echo "schedule" >> $GITHUB_STEP_SUMMARY echo "Will run tests, because trigger event was $GITHUB_EVENT_NAME" echo "should_run=true" >> $GITHUB_OUTPUT elif [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then echo "Will run tests, because trigger event was $GITHUB_EVENT_NAME" echo "should_run=true" >> $GITHUB_OUTPUT elif [ "$GITHUB_REF_TYPE" = "tag" ]; then + echo "## Build trigger" >> $GITHUB_STEP_SUMMARY + echo "new tag" >> $GITHUB_STEP_SUMMARY echo "Will run tests, because new tag was created" echo "should_run=true" >> $GITHUB_OUTPUT else @@ -696,7 +702,7 @@ jobs: id-token: write contents: read runs-on: ubuntu-latest - needs: [run-client-compatibility-matrix, should-run, select-versions] + needs: [run-client-compatibility-matrix, should-run, select-versions, build-chainlink, prepare-compatibility-matrix] steps: - name: Debug Result run: echo ${{ join(needs.*.result, ',') }} @@ -709,7 +715,7 @@ jobs: { "attachments": [ { - "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || '#2E7D32' }}", + "color": "${{ (contains(join(needs.*.result, ','), 'failure') || needs.build-chainlink.result == 'failure') && '#C62828' || '#2E7D32' }}", "blocks": [ { "type": "header", @@ -723,7 +729,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "${{ contains(join(needs.*.result, ','), 'failure') && format('Some tests failed, notifying ', secrets.COMPAT_SLACK_NOTIFICATION_HANDLE) || 'All Good!' }}" + "text": "${{ needs.prepare-compatibility-matrix.result == 'failure' && 'Failed to prepare test matrix, notifying ' || needs.build-chainlink.result == 'failure' && 'Failed to build Chainlink image, notifying ' || contains(join(needs.*.result, ','), 'failure') && format('Some tests failed, notifying ', secrets.COMPAT_SLACK_NOTIFICATION_HANDLE) || 'All Good!' }}" } }, { From 1633c8215f58d8bf1f7f62c9d0843b85d25841c0 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:08:35 +0200 Subject: [PATCH 302/432] Add E2E configs for VRFv2Plus tests and update related Github Workflows (#14328) * Update some test workflows to run with test config path * Fix summary * Fix * Update on-demand-ocr-soak-test.yml * Run vrfplus tests on ARBITRUM_SEPOLIA on existing env * Add config for staging release testing on arbitrum sepolia * Show test_secrets_override_key in summary * Generate hash of integration-tests/ for test runner image if tag not provided * test updating config but not rebuilding test image * Fix test_runner_hash * Commit all configs for staging * test config change * Update release configs * Do not rebuild test image when md or .github files were changed * Add wemix testnet config for ocrv2 soak test * Use chainlink version from config * Update reusable workflow inputs * Add soak/ocr_test.go:^TestOCRv2Soak$WemixTestnet to CI tests * Fix * Fix test image tag * Remove image from default.toml * Fix chainlink_version * Fix test image hash value * Fix summary * Update workflow * Update config overrides, read from default, env vars and then from BASE64_CONFIG_OVERRIDE if exists BASE64_CONFIG_OVERRIDE should be able to override everything that was already set in the test config * Build chainlink image sha if required * Fix * Add new workflow * Show test config path in reusable workflow * Update list of tests * Update run-selected-tests workflow * Fix * Rename steps * fix workflow * Add TestVRFv2Plus_LiveTestnets to CI tests definition * Fix * Run vrfv2plus tests on simulated network by default * Fix * fix * fix * Update test definition * Add TestVRFv2Plus_Release_Sepolia * Add workflow to run vrf e2e release tests * test new workflow with slack notification * fix * fix * fix * fix color * fix * revert if * revert test definition changes * Add test_secrets_override_key * fix for slack notification after test * TT-1550: reorganizing VRF V2 Plus configs * Use test_config_override_path instead of base64 in other VRFv2Plus workflows * Revert some changes * Add comment * Fix * Remove configs * Make chainlink_version not required * test custom_test_list_json * fix * Rename * Migrate on-demand-vrfv2plus-smoke-tests.yml to reusable workflow * add example for inline custom_test_list_json * TT-1550: increasing sub_billing_tolerance_wei for Optimism Sepolia VRF v2 plus CTF tests * TT-1550: increasing subscription_funding_amount_link for Optimism Sepolia VRF v2 plus CTF tests * bump gha --------- Co-authored-by: Ilja Pavlovs --- .github/actions/build-test-image/action.yml | 37 +- .github/e2e-tests.yml | 38 +- .../on-demand-vrfv2plus-eth2-clients-test.yml | 65 ++-- .../on-demand-vrfv2plus-performance-test.yml | 54 +-- .../on-demand-vrfv2plus-smoke-tests.yml | 161 ++++----- .../run-e2e-tests-reusable-workflow.yml | 218 ++++++++--- .github/workflows/run-selected-e2e-tests.yml | 12 +- .../ccip-tests/testconfig/global.go | 33 +- integration-tests/testconfig/default.toml | 3 +- integration-tests/testconfig/testconfig.go | 25 +- .../arbitrum_sepolia_release_test_config.toml | 5 + .../avalanche_fuji_release_test_config.toml | 5 + .../base_sepolia_release_test_config.toml | 5 + .../bsc_testnet_release_test_config.toml | 5 + .../nexon_dev_release_test_config.toml | 5 + .../nexon_qa_release_test_config.toml | 5 + .../nexon_stage_release_test_config.toml | 5 + .../nexon_test_release_test_config.toml | 5 + .../optimism_sepolia_release_test_config.toml | 5 + .../polygon_amoy_release_test_config.toml | 5 + .../sepolia_release_test_config.toml | 5 + .../arbitrum_sepolia_staging_test_config.toml | 36 ++ .../avalanche_fuji_staging_test_config.toml | 18 + .../base_sepolia_staging_test_config.toml | 20 ++ .../bsc_testnet_staging_test_config.toml | 18 + .../nexon_dev_staging_test_config.toml | 18 + .../staging/nexon_qa_staging_test_config.toml | 19 + .../nexon_stage_staging_test_config.toml | 15 + .../nexon_test_staging_test_config.toml | 19 + .../optimism_sepolia_staging_test_config.toml | 20 ++ .../polygon_amoy_staging_test_config.toml | 32 ++ .../staging/sepolia_staging_test_config.toml | 18 + .../testconfig/vrfv2plus/vrfv2plus.toml | 338 ++++++++++-------- 33 files changed, 868 insertions(+), 404 deletions(-) create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/release_testing/arbitrum_sepolia_release_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/release_testing/avalanche_fuji_release_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/release_testing/base_sepolia_release_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/release_testing/bsc_testnet_release_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_dev_release_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_qa_release_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_stage_release_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_test_release_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/release_testing/optimism_sepolia_release_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/release_testing/polygon_amoy_release_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/release_testing/sepolia_release_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/staging/arbitrum_sepolia_staging_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/staging/avalanche_fuji_staging_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/staging/base_sepolia_staging_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/staging/bsc_testnet_staging_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_dev_staging_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_qa_staging_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_stage_staging_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_test_staging_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/staging/optimism_sepolia_staging_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/staging/polygon_amoy_staging_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/staging/sepolia_staging_test_config.toml diff --git a/.github/actions/build-test-image/action.yml b/.github/actions/build-test-image/action.yml index af6c33bd67..bc81226b32 100644 --- a/.github/actions/build-test-image/action.yml +++ b/.github/actions/build-test-image/action.yml @@ -7,8 +7,7 @@ inputs: default: chainlink-tests required: false tag: - description: The tag to use by default and to use for checking image existance - default: ${{ github.sha }} + description: The tag to use by default and to use for checking image existance. If not provided, the hash of the integration-tests/ directory will be used required: false other_tags: description: Other tags to push if needed @@ -27,6 +26,17 @@ inputs: description: The AWS region the ECR repository is located in, should only be needed for public ECR repositories, used in configuring docker/login-action required: true +outputs: + test_image: + description: The full name of the test image that was built + value: ${{ steps.image_outputs.outputs.test_image }} + test_image_tag: + description: The tag of the test image that was built + value: ${{ steps.image_outputs.outputs.test_image_tag }} + test_image_repository: + description: The repository of the test image that was built + value: ${{ steps.image_outputs.outputs.test_image_repo }} + runs: using: composite steps: @@ -90,12 +100,22 @@ runs: # End Base Image Logic # Test Runner Logic + - name: Get hash of integration-tests/ for test runner image + id: test_runner_hash + if: ${{ inputs.tag == '' }} + # Do not include testconfig/ in the hash to avoid rebuilding the image when only testconfig/ changes + shell: sh + run: | + HASH_VALUE=$(find integration-tests -type f ! -path 'integration-tests/testconfig/overrides/*.toml' ! -path 'integration-tests/testconfig/overrides/*/*.toml' ! -path 'integration-tests/testconfig/*/overrides/*.toml' ! -path 'integration-tests/testconfig/*/overrides/*/*.toml' ! -path 'integration-tests/ccip-tests/testconfig/*/overrides/*.toml' ! -path 'integration-tests/ccip-tests/testconfig/*/overrides/*/*.toml' ! -path '.github/*/*' ! -path '*/*.md' ! -path '*/*.MD' ! -path 'integration-tests/*/__debug_bin*' ! -path '*/*.MD' ! -path 'integration-tests/*/tmp-manifest*.yaml' ! -path '*/*.MD' ! -path 'integration-tests/*/*.log' ! -path 'integration-tests/*/*_dump.sql' ! -path 'integration-tests/*/.test_summary/*' -exec sha256sum {} + | sort -k 2 | sha256sum | awk '{print $1}') + echo "Computed hash: $HASH_VALUE" + echo "hash_value=$HASH_VALUE" >> $GITHUB_OUTPUT + - name: Check if image exists id: check-image uses: smartcontractkit/chainlink-github-actions/docker/image-exists@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 with: repository: ${{ inputs.repository }} - tag: ${{ inputs.tag }} + tag: ${{ inputs.tag || steps.test_runner_hash.outputs.hash_value }} AWS_REGION: ${{ inputs.QA_AWS_REGION }} AWS_ROLE_TO_ASSUME: ${{ inputs.QA_AWS_ROLE_TO_ASSUME }} - name: Build and Publish Test Runner @@ -103,7 +123,7 @@ runs: uses: smartcontractkit/chainlink-github-actions/docker/build-push@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 with: tags: | - ${{ inputs.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ inputs.QA_AWS_REGION }}.amazonaws.com/${{ inputs.repository }}:${{ inputs.tag }} + ${{ inputs.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ inputs.QA_AWS_REGION }}.amazonaws.com/${{ inputs.repository }}:${{ inputs.tag || steps.test_runner_hash.outputs.hash_value }} ${{ inputs.other_tags }} file: ./integration-tests/test.Dockerfile build-args: | @@ -116,8 +136,15 @@ runs: shell: sh env: INPUTS_REPOSITORY: ${{ inputs.repository }} - INPUTS_TAG: ${{ inputs.tag }} + INPUTS_TAG: ${{ inputs.tag || steps.test_runner_hash.outputs.hash_value }} run: | echo "### ${INPUTS_REPOSITORY} image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY echo "\`${INPUTS_TAG}\`" >>$GITHUB_STEP_SUMMARY + - name: Set outputs + id: image_outputs + shell: sh + run: | + echo "test_image_repo=${{ inputs.repository }}" >> $GITHUB_OUTPUT + echo "test_image_tag=${{ inputs.tag || steps.test_runner_hash.outputs.hash_value }}" >> $GITHUB_OUTPUT + echo "test_image=${{ inputs.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ inputs.QA_AWS_REGION }}.amazonaws.com/${{ inputs.repository }}:${{ inputs.tag || steps.test_runner_hash.outputs.hash_value }}" >> $GITHUB_OUTPUT # End Test Runner Logic diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 16a5152f14..30d1bf28a8 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -41,6 +41,16 @@ runner-test-matrix: test_env_vars: TEST_SUITE: soak + - id: soak/ocr_test.go:TestOCRv2Soak_WemixTestnet + path: integration-tests/soak/ocr_test.go + test_env_type: k8s-remote-runner + runs_on: ubuntu-latest + test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRv2Soak$ -test.parallel=1 -timeout 30m -count=1 -json + test_config_override_path: integration-tests/testconfig/ocr2/overrides/wemix_testnet.toml + test_secrets_required: true + test_env_vars: + TEST_SUITE: soak + - id: soak/ocr_test.go:^TestForwarderOCRv1Soak$ path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner @@ -668,16 +678,6 @@ runner-test-matrix: workflows: - On Demand VRFV2 Performance Test - - id: smoke/vrfv2plus_test.go:^TestVRFv2Plus$/^Link_Billing$ - path: integration-tests/smoke/vrfv2plus_test.go - runs_on: ubuntu22.04-8cores-32GB - test_env_type: docker - test_cmd: cd integration-tests && go test -v -test.run ^TestVRFv2Plus$/^Link_Billing$ smoke/vrfv2plus_test.go -test.parallel=1 -timeout 30m -count=1 -json - test_config_override_required: true - test_secrets_required: true - workflows: - - On Demand VRFV2Plus Smoke Test (Ethereum clients) - - id: smoke/vrf_test.go:* path: integration-tests/smoke/vrf_test.go test_env_type: docker @@ -708,6 +708,24 @@ runner-test-matrix: test_cmd: cd integration-tests/ && go test smoke/vrfv2plus_test.go -timeout 30m -count=1 -test.parallel=9 -json pyroscope_env: ci-smoke-vrf2plus-evm-simulated + # VRFv2Plus tests on any live testnet (test_config_override_path required) + # Tests have to run in sequence because of a single private key used + - id: TestVRFv2Plus_LiveTestnets + path: integration-tests/smoke/vrfv2plus_test.go + runs_on: ubuntu-latest + test_env_type: docker + test_cmd: cd integration-tests/smoke && go test -v -test.run "TestVRFv2Plus$/(Link_Billing|Native_Billing|Direct_Funding)|TestVRFV2PlusWithBHS" -test.parallel=1 -timeout 2h -count=1 -json + + # VRFv2Plus release tests on Sepolia testnet + - id: TestVRFv2Plus_Release_Sepolia + path: integration-tests/smoke/vrfv2plus_test.go + runs_on: ubuntu-latest + test_env_type: docker + test_cmd: cd integration-tests/smoke && go test -v -test.run "TestVRFv2Plus$/(Link_Billing|Native_Billing|Direct_Funding)|TestVRFV2PlusWithBHS" -test.parallel=1 -timeout 2h -count=1 -json + test_config_override_path: integration-tests/testconfig/vrfv2plus/overrides/release_testing/sepolia_release_test_config.toml + workflows: + - VRF E2E Release Tests + # END: VRF tests # START: LogPoller tests diff --git a/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml b/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml index 652c51095f..0636a29944 100644 --- a/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml @@ -2,14 +2,19 @@ name: On Demand VRFV2Plus Smoke Test (Ethereum clients) on: workflow_dispatch: inputs: - base64Config: - description: base64-ed config - required: true - type: string + test_config_override_path: + description: Path to a test config file used to override the default test config + required: false + type: string test_secrets_override_key: description: 'Key to run tests with custom test secrets' required: false type: string + chainlink_version: + description: Chainlink image version to use + default: develop + required: true + type: string jobs: vrfv2plus_smoke_test: @@ -29,35 +34,36 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: fetch-depth: 0 - - name: Mask base64 config + - name: Show test config override path in summary + if: ${{ inputs.test_config_override_path }} run: | - BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64Config' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - name: Parse base64 config - uses: ./.github/actions/setup-parse-base64-config - with: - base64Config: ${{ env.BASE64_CONFIG_OVERRIDE }} - - name: Send details to Step Summary - shell: bash + echo "### Test config override path" >> $GITHUB_STEP_SUMMARY + echo "[${{ inputs.test_config_override_path }}]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/blob/${{ github.sha }}/${{ inputs.test_config_override_path }})" >> $GITHUB_STEP_SUMMARY + - name: Show test secrets override key in summary + if: ${{ inputs.test_secrets_override_key }} run: | - echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_IMAGE }}\`" >>$GITHUB_STEP_SUMMARY - echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY - echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - echo "### Execution client used" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.ETH2_EL_CLIENT }}\`" >>$GITHUB_STEP_SUMMARY + echo "### Test secrets override key" >> $GITHUB_STEP_SUMMARY + echo "${{ inputs.test_secrets_override_key }}" >> $GITHUB_STEP_SUMMARY + - name: Show chainlink version in summary + run: | + echo "### Chainlink version" >> $GITHUB_STEP_SUMMARY + echo "${{ inputs.chainlink_version }}" >> $GITHUB_STEP_SUMMARY - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 + env: + E2E_TEST_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + E2E_TEST_CHAINLINK_VERSION: ${{ inputs.chainlink_version }} # Default chainlink version if not overrided in the test config + E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" + E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -run ^TestVRFv2Plus$/^Link_Billing$ ./smoke/vrfv2plus_test.go 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} - test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ env.CHAINLINK_VERSION }} + test_config_override_path: ${{ inputs.test_config_override_path }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_name: vrfplus-test-logs artifacts_location: | @@ -69,11 +75,4 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: "" - env: - E2E_TEST_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" - E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + diff --git a/.github/workflows/on-demand-vrfv2plus-performance-test.yml b/.github/workflows/on-demand-vrfv2plus-performance-test.yml index 04e0c9318a..4cb99eed62 100644 --- a/.github/workflows/on-demand-vrfv2plus-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-performance-test.yml @@ -2,10 +2,6 @@ name: On Demand VRFV2 Plus Performance Test on: workflow_dispatch: inputs: - base64Config: - description: base64-ed config - required: true - type: string performanceTestType: description: Performance Test Type of test to run type: string @@ -14,10 +10,19 @@ on: description: "Regex for tests to run" required: false default: "(TestVRFV2PlusPerformance)" + test_config_override_path: + description: Path to a test config file used to override the default test config + required: false + type: string test_secrets_override_key: description: 'Key to run tests with custom test secrets' required: false type: string + chainlink_version: + description: Chainlink image version to use + default: develop + required: false + type: string jobs: vrfv2plus_performance_test: @@ -57,33 +62,36 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: fetch-depth: 0 - - name: Mask base64 config + - name: Show test config override path in summary + if: ${{ inputs.test_config_override_path }} run: | - BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64Config' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - name: Merge and export base64 config - uses: ./.github/actions/setup-merge-base64-config - with: - base64Config: ${{ env.BASE64_CONFIG_OVERRIDE }} - - name: Send details to Step Summary - shell: bash + echo "### Test config override path" >> $GITHUB_STEP_SUMMARY + echo "[${{ inputs.test_config_override_path }}]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/blob/${{ github.sha }}/${{ inputs.test_config_override_path }})" >> $GITHUB_STEP_SUMMARY + - name: Show test secrets override key in summary + if: ${{ inputs.test_secrets_override_key }} + run: | + echo "### Test secrets override key" >> $GITHUB_STEP_SUMMARY + echo "${{ inputs.test_secrets_override_key }}" >> $GITHUB_STEP_SUMMARY + - name: Show chainlink version in summary run: | - echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_IMAGE }}\`" >>$GITHUB_STEP_SUMMARY - echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY - echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY + echo "### Chainlink version" >> $GITHUB_STEP_SUMMARY + echo "${{ inputs.chainlink_version }}" >> $GITHUB_STEP_SUMMARY - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 + env: + E2E_TEST_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + E2E_TEST_CHAINLINK_VERSION: ${{ inputs.chainlink_version }} # Default chainlink version if not overrided in the test config + E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" + E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} with: test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run "${{ inputs.test_list_regex }}" ./vrfv2plus test_download_vendor_packages_command: cd ./integration-tests && go mod download test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} - test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ env.CHAINLINK_VERSION }} + test_config_override_path: ${{ inputs.test_config_override_path }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_name: vrf-test-logs artifacts_location: ./integration-tests/load/vrfv2plus/logs/ diff --git a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml index 1a62e0fe06..268bb7e7d7 100644 --- a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml +++ b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml @@ -2,14 +2,11 @@ name: On Demand VRFV2 Plus Smoke Tests on: workflow_dispatch: inputs: - base64Config: - description: base64-ed config - required: true - type: string test_suite: description: "Test Suite to run" required: true type: choice + default: "All Tests" options: - "All Tests" - "Selected Tests" @@ -17,101 +14,75 @@ on: description: "Regex for 'Selected Tests' to run" required: false default: "TestVRFv2Plus$/(Link_Billing|Native_Billing|Direct_Funding)|TestVRFV2PlusWithBHS" + test_config_override_path: + description: Path to a test config file used to override the default test config + required: false + type: string test_secrets_override_key: description: 'Key to run tests with custom test secrets' required: false type: string - + chainlink_version: + description: Chainlink image version to use + default: develop + required: false + type: string + jobs: - vrfv2plus_smoke_test: - name: VRFV2 Plus Smoke Test - environment: integration - runs-on: ubuntu22.04-8cores-32GB - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - env: - LOKI_URL: ${{ secrets.LOKI_URL }} - LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} - LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} - TEST_LOG_LEVEL: debug - REF_NAME: ${{ github.head_ref || github.ref_name }} - SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} - SLACK_CHANNEL: ${{ secrets.QA_VRF_SLACK_CHANNEL }} - GRAFANA_URL: "http://localhost:8080/primary" - GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - WASP_LOG_LEVEL: info + set-tests-to-run: + name: Set tests to run + runs-on: ubuntu-latest + outputs: + test_list: ${{ steps.set-tests.outputs.test_list }} steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: on-demand-vrfv2plus-smoke-tests - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ${{ inputs.network }} VRFV2 Plus Smoke Test - continue-on-error: true - - name: Checkout code - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Mask base64 config + - name: Generate Test List JSON + id: set-tests run: | - BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64Config' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - name: Merge and export base64 config - uses: ./.github/actions/setup-merge-base64-config - with: - base64Config: ${{ env.BASE64_CONFIG_OVERRIDE }} - - name: Send details to Step Summary - shell: bash - run: | - echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_IMAGE }}\`" >>$GITHUB_STEP_SUMMARY - echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY - echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - - name: Run Tests - if: ${{ github.event.inputs.test_suite == 'Selected Tests' }} - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 - with: - test_command_to_run: cd ./integration-tests/smoke && go test -v -count=1 -parallel=1 -timeout 2h -run "${{ inputs.test_list_regex }}" 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} - test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ env.CHAINLINK_VERSION }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: vrf-test-logs - artifacts_location: ./integration-tests/smoke/vrfv2plus/logs/ - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - should_cleanup: false - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Run Tests - if: ${{ github.event.inputs.test_suite == 'All Tests' }} - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 - with: - test_command_to_run: cd ./integration-tests/smoke && go test -v -count=1 -parallel=1 -timeout 3h vrfv2plus_test.go 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} - test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ env.CHAINLINK_VERSION }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: vrf-test-logs - artifacts_location: ./integration-tests/smoke/vrfv2plus/logs/ - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - should_cleanup: false - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + if [[ "${{ inputs.test_suite }}" == "All Tests" ]]; then + TEST_CMD="cd integration-tests/smoke && go test vrfv2plus_test.go -test.parallel=1 -timeout 3h -count=1 -json -v" + else + TEST_CMD='cd integration-tests/smoke && go test -test.run "${{ inputs.test_list_regex }}" -test.parallel=1 -timeout 2h -count=1 -json -v' + fi + TEST_CONFIG_OVERRIDE_PATH=${{ inputs.test_config_override_path }} + + TEST_LIST=$(jq -n -c \ + --arg test_cmd "$TEST_CMD" \ + --arg test_config_override_path "$TEST_CONFIG_OVERRIDE_PATH" \ + '{ + "tests": [ + { + "id": "TestVRFv2Plus_Smoke", + "path": "integration-tests/smoke/vrfv2plus_test.go", + "runs_on": "ubuntu-latest", + "test_env_type": "docker", + "test_cmd": $test_cmd, + "test_config_override_path": $test_config_override_path + } + ] + }') + + echo "test_list=$TEST_LIST" >> $GITHUB_OUTPUT + + run-e2e-tests-workflow: + name: Run E2E Tests + needs: set-tests-to-run + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} + chainlink_version: ${{ inputs.chainlink_version }} + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index de3f254539..c4ab54fc68 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -1,5 +1,9 @@ # This is a reusable workflow that runs E2E tests for Chainlink. # It is not meant to be run on its own. +# +# IMPORTANT NOTE: All workflow_call inputs appear as plain text in GitHub Logs (see https://github.com/actions/runner/issues/2988). +# Do not include any sensitive information in these inputs. Instead, for handling test secrets, refer to https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md#test-secrets +# name: Run E2E Tests on: workflow_call: @@ -25,15 +29,31 @@ on: description: 'Base64 encoded list of tests (YML objects) to run. Example in run-automation-ondemand-e2e-tests.yml' required: false type: string + custom_test_list_json: + description: 'Custom JSON list of tests to run' + required: false + type: string + # Example: + # custom_test_list_json: > + # { + # "tests": [ + # { + # "id": "TestVRFv2Plus", + # "path": "integration-tests/smoke/vrfv2plus_test.go", + # "runs_on": "ubuntu-latest", + # "test_env_type": "docker", + # "test_cmd": "cd integration-tests/smoke && go test vrfv2plus_test.go -test.parallel=1 -timeout 3h -count=1 -json -v" + # } + # ] + # } test_workflow: description: 'Run tests by workflow name. Example: "Run Nightly E2E Tests"' required: false type: string - # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 - # test_config_override_base64: - # required: false - # description: The base64-encoded test config override - # type: string + test_config_override_path: + description: 'Path to a test config file used to override the default test config' + required: false + type: string enable_check_test_configurations: description: 'Set to "true" to enable check-test-configurations job' required: false @@ -63,6 +83,10 @@ on: description: 'Name of the slack notification' required: false type: string + slack_notification_after_tests_notify_user_id_on_failure: + description: 'Set Slack user id to notify on test failure' + required: false + type: string test_log_upload_on_failure: description: 'Set to "true" to upload the test log on failure as Github artifact' required: false @@ -161,20 +185,35 @@ jobs: fi - name: Install jq run: sudo apt-get install jq + - name: Create matrix for required Chainlink image versions id: set-required-chainlink-image-versions-matrix run: | - if [[ "${{ inputs.require_chainlink_image_versions_in_qa_ecr }}" != '' ]]; then - image_versions=$(echo "${{ inputs.require_chainlink_image_versions_in_qa_ecr }}" | jq -Rc 'split(",") | if . == [""] then [] else . end') - echo "versions=$image_versions" >> $GITHUB_OUTPUT + image_versions="${{ inputs.require_chainlink_image_versions_in_qa_ecr }}" + default_version="${{ env.DEFAULT_CHAINLINK_VERSION }}" + current_sha="${{ github.sha }}" + + if [[ "$default_version" == "$current_sha" ]]; then + # Append the current SHA to required image versions + if [[ -z "$image_versions" ]]; then + image_versions="${{ github.sha }}" + else + image_versions+=",${{ github.sha }}" + fi fi + + # Convert the comma-separated string to a JSON array + image_versions=$(echo "$image_versions" | jq -Rc 'if . == "" then "" else split(",") | if . == [""] then "" else . end end') + + echo "Required Chainlink image versions: $image_versions" + echo "versions=$image_versions" >> $GITHUB_OUTPUT + - name: Create matrix for required Chainlink plugin versions id: set-required-chainlink-plugin-versions-matrix run: | - if [[ "${{ inputs.require_chainlink_plugin_versions_in_qa_ecr }}" != '' ]]; then - image_versions=$(echo "${{ inputs.require_chainlink_plugin_versions_in_qa_ecr }}" | jq -Rc 'split(",") | if . == [""] then [] else . end') - echo "versions=$image_versions" >> $GITHUB_OUTPUT - fi + image_versions=$(echo "${{ inputs.require_chainlink_plugin_versions_in_qa_ecr }}" | jq -Rc 'if . == "" then "" else split(",") | if . == [""] then "" else . end end') + echo "Required Chainlink plugin image versions: $image_versions" + echo "versions=$image_versions" >> $GITHUB_OUTPUT check-test-configurations: name: Check test configurations @@ -239,20 +278,39 @@ jobs: run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/citool@a49f2dff000fcf020ab9978b33e3726d7df5bf96 # v1.34.4 - name: Install jq run: sudo apt-get install jq + - name: Generate Docker Tests Matrix id: set-docker-matrix run: | - MATRIX_JSON=$(citool filter --file ${{ github.workspace }}/.github/e2e-tests.yml --test-env-type 'docker' --test-list '${{ inputs.test_list }}' --test-ids '${{ inputs.test_ids }}' --workflow '${{ inputs.test_workflow }}') + # Check if custom_test_list_json is provided and non-empty + if [[ -n '${{ inputs.custom_test_list_json }}' ]]; then + echo "Using custom test list JSON" + MATRIX_JSON=$(echo '${{ inputs.custom_test_list_json }}' | jq -c '{tests: [.tests[] | select(.test_env_type == "docker")]}') + else + echo "Using default test list" + MATRIX_JSON=$(citool filter --file ${{ github.workspace }}/.github/e2e-tests.yml --test-env-type 'docker' --test-list '${{ inputs.test_list }}' --test-ids '${{ inputs.test_ids }}' --workflow '${{ inputs.test_workflow }}') + fi + echo "Docker tests:" echo "$MATRIX_JSON" | jq echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT + - name: Generate K8s Tests Matrix id: set-k8s-runner-matrix run: | - MATRIX_JSON=$(citool filter --file ${{ github.workspace }}/.github/e2e-tests.yml --test-env-type 'k8s-remote-runner' --test-list '${{ inputs.test_list }}' --test-ids '${{ inputs.test_ids }}' --workflow '${{ inputs.test_workflow }}') + # Check if custom_test_list_json is provided and non-empty + if [[ -n '${{ inputs.custom_test_list_json }}' ]]; then + echo "Using custom test list JSON" + MATRIX_JSON=$(echo '${{ inputs.custom_test_list_json }}' | jq -c '{tests: [.tests[] | select(.test_env_type == "k8s-remote-runner")]}') + else + echo "Using default test list" + MATRIX_JSON=$(citool filter --file ${{ github.workspace }}/.github/e2e-tests.yml --test-env-type 'k8s-remote-runner' --test-list '${{ inputs.test_list }}' --test-ids '${{ inputs.test_ids }}' --workflow '${{ inputs.test_workflow }}') + fi + echo "K8s tests:" echo "$MATRIX_JSON" | jq echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT + - name: Check Test Matrices id: check-matrices run: | @@ -278,7 +336,7 @@ jobs: # Check if both matrices are empty if [[ "$DOCKER_MATRIX_EMPTY" == "true" ]] && [[ "$K8S_MATRIX_EMPTY" == "true" ]]; then - echo "No tests found for inputs: '${{ toJson(inputs) }}'. Both Docker and Kubernetes tests matrices are empty" + echo "No tests found for inputs. Both Docker and Kubernetes tests matrices are empty" exit 1 fi shell: bash @@ -286,13 +344,6 @@ jobs: - name: Check if test config override is required for any test shell: bash run: | - # Check if the test config override is provided and skip the checks if it is non-empty - # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 - # if [ -n "${{ inputs.test_config_override_base64 }}" ]; then - # echo "Test config override provided. Skipping checks for tests requiring config override." - # exit 0 - # fi - # Parse the JSON to check for test_config_override_required in Docker matrix DOCKER_TESTS_REQUIRING_CONFIG_OVERRIDE=$(echo '${{ steps.set-docker-matrix.outputs.matrix }}' | jq 'if .tests then .tests[] | select(has("test_config_override_required") and .test_config_override_required) | .id else empty end' -r) # Parse the JSON to check for test_config_override_required in Kubernetes matrix @@ -307,7 +358,7 @@ jobs: if [ ! -z "$K8S_TESTS_REQUIRING_CONFIG_OVERRIDE" ]; then echo $K8S_TESTS_REQUIRING_CONFIG_OVERRIDE fi - echo "::error::Error: Some of the tests require a test config override. Please see workflow logs and set 'test_config_override_base64' to run these tests." + echo "::error::Error: Some of the tests require a test config override. Please see workflow logs and set 'test_config_override_path' to run these tests." exit 1 else echo "No tests require a configuration override. Proceeding without overrides." @@ -347,11 +398,11 @@ jobs: run: echo "workflow_id=$(uuidgen)" >> $GITHUB_OUTPUT - # Build Chainlink images required for the tests + # Check if Chainlink images required for the tests exist. If not, build and push the images to QA ECR require-chainlink-image-versions-in-qa-ecr: - name: Build Chainlink image + name: Get Chainlink image needs: [validate-inputs, load-test-configurations] - if: ${{ needs.validate-inputs.outputs.require_chainlink_image_versions_in_qa_ecr_matrix != '' }} + if: ${{ fromJson(needs.validate-inputs.outputs.require_chainlink_image_versions_in_qa_ecr_matrix) != '' }} runs-on: ubuntu-latest environment: integration permissions: @@ -366,7 +417,7 @@ jobs: - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Build Chainlink image for ${{ matrix.version }} and push it to QA ECR + - name: Get Chainlink image uses: ./.github/actions/build-chainlink-image with: dockerfile: core/chainlink.Dockerfile @@ -376,11 +427,11 @@ jobs: AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - # Build Chainlink plugins required for the tests + # Check if Chainlink plugins required for the tests exist. If not, build and push the images to QA ECR require-chainlink-plugin-versions-in-qa-ecr: - name: Build Chainlink plugins + name: Get Chainlink plugins image needs: [validate-inputs, load-test-configurations] - if: ${{ needs.validate-inputs.outputs.require_chainlink_plugin_versions_in_qa_ecr_matrix != '' }} + if: ${{ fromJson(needs.validate-inputs.outputs.require_chainlink_plugin_versions_in_qa_ecr_matrix) != '' }} runs-on: ubuntu-latest environment: integration permissions: @@ -395,7 +446,7 @@ jobs: - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Build Chainlink plugins image for ${{ matrix.version }} + - name: Get Chainlink plugins image uses: ./.github/actions/build-chainlink-image with: dockerfile: plugins/chainlink.Dockerfile @@ -424,6 +475,7 @@ jobs: contents: read env: LATEST_CHAINLINK_RELEASE_VERSION: ${{ needs.get_latest_chainlink_release_version.outputs.latest_chainlink_release_version }} + TEST_CONFIG_OVERRIDE_PATH: ${{ matrix.tests.test_config_override_path || inputs.test_config_override_path }} steps: - name: Collect Metrics if: always() @@ -442,7 +494,19 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Install jq run: sudo apt-get install -y jq - - name: Show test configuration + + - name: Show test config override path in summary + if: ${{ env.TEST_CONFIG_OVERRIDE_PATH }} + run: | + echo "### Test config override path" >> $GITHUB_STEP_SUMMARY + echo "[${{ env.TEST_CONFIG_OVERRIDE_PATH }}]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/blob/${{ github.sha }}/${{ env.TEST_CONFIG_OVERRIDE_PATH }})" >> $GITHUB_STEP_SUMMARY + + - name: Show chainlink version in summary + run: | + echo "### Chainlink version" >> $GITHUB_STEP_SUMMARY + echo "${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }}" >> $GITHUB_STEP_SUMMARY + + - name: Show test configuration in logs run: echo '${{ toJson(matrix.tests) }}' | jq . - name: Setup GAP for Grafana @@ -483,18 +547,16 @@ jobs: - name: Run tests id: run_tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@4f377a6b1cc07f0eca82745782736b4908a1da30 # v2.3.32 env: DETACH_RUNNER: true - E2E_TEST_CHAINLINK_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || inputs.chainlink_version || github.sha }} + E2E_TEST_CHAINLINK_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }} E2E_TEST_CHAINLINK_UPGRADE_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_VERSION }} E2E_TEST_CHAINLINK_POSTGRES_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_POSTGRES_VERSION }} E2E_TEST_SELECTED_NETWORK: ${{ matrix.tests.test_env_vars.E2E_TEST_SELECTED_NETWORK || env.SELECTED_NETWORKS }} E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} E2E_TEST_LOG_STREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} E2E_TEST_LOG_COLLECT: ${{ vars.TEST_LOG_COLLECT }} - E2E_TEST_CHAINLINK_IMAGE: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_IMAGE || env.CHAINLINK_IMAGE }} - E2E_TEST_CHAINLINK_UPGRADE_IMAGE: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_IMAGE }} E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} @@ -509,11 +571,11 @@ jobs: test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd $(dirname ${{ matrix.tests.path }}) && go mod download test_secrets_override_base64: ${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }} - test_config_override_path: ${{ matrix.tests.test_config_override_path }} - # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 - # test_config_override_base64: ${{ inputs.test_config_override_base64 }} + test_config_override_path: ${{ env.TEST_CONFIG_OVERRIDE_PATH }} test_type: ${{ matrix.tests.test_env_vars.TEST_TYPE }} test_suite: ${{ matrix.tests.test_env_vars.TEST_SUITE }} + default_e2e_test_chainlink_image: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_IMAGE || env.CHAINLINK_IMAGE }} + default_e2e_test_chainlink_upgrade_image: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_IMAGE }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_name: ${{ matrix.tests.id_sanitized }}-test-logs artifacts_location: | @@ -608,6 +670,7 @@ jobs: - name: Checkout repository uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Build Test Runner Image + id: build-test-runner-image uses: ./.github/actions/build-test-image if: ${{ inputs.with_existing_remote_runner_version == '' }} with: @@ -618,7 +681,9 @@ jobs: id: set-remote-runner-version run: | if [[ -z "${{ inputs.with_existing_remote_runner_version }}" ]]; then - echo "remote-runner-version=${{ github.sha }}" >> $GITHUB_OUTPUT + echo "remote-runner-image=${{ steps.build-test-runner-image.outputs.test_image }}" >> $GITHUB_OUTPUT + echo "remote-runner-repository=${{ steps.build-test-runner-image.outputs.test_image_repository }}" >> $GITHUB_OUTPUT + echo "remote-runner-version=${{ steps.build-test-runner-image.outputs.test_image_tag }}" >> $GITHUB_OUTPUT else echo "remote-runner-version=${{ inputs.with_existing_remote_runner_version }}" >> $GITHUB_OUTPUT fi @@ -640,6 +705,7 @@ jobs: contents: read env: LATEST_CHAINLINK_RELEASE_VERSION: ${{ needs.get_latest_chainlink_release_version.outputs.latest_chainlink_release_version }} + TEST_CONFIG_OVERRIDE_PATH: ${{ matrix.tests.test_config_override_path || inputs.test_config_override_path }} steps: - name: Collect Metrics if: always() @@ -657,15 +723,30 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Install jq run: sudo apt-get install -y jq - - name: Show Test Configuration - run: echo '${{ toJson(matrix.tests) }}' | jq . - - name: Show Remote Runner Version + + - name: Show test config override path in summary + if: ${{ env.TEST_CONFIG_OVERRIDE_PATH }} + run: | + echo "### Test config override path" >> $GITHUB_STEP_SUMMARY + echo "[${{ env.TEST_CONFIG_OVERRIDE_PATH }}]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/blob/${{ github.sha }}/${{ env.TEST_CONFIG_OVERRIDE_PATH }})" >> $GITHUB_STEP_SUMMARY + + - name: Show chainlink version in summary + run: | + echo "### Chainlink version" >> $GITHUB_STEP_SUMMARY + echo "${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }}" >> $GITHUB_STEP_SUMMARY + + - name: Show remote runner version in summary run: | echo "Remote Runner Version: ${{ needs.prepare-remote-runner-test-image.outputs.remote-runner-version }}" + echo "### Remote Runner Version" >> $GITHUB_STEP_SUMMARY + echo "${{ needs.prepare-remote-runner-test-image.outputs.remote-runner-version }}" >> $GITHUB_STEP_SUMMARY + + - name: Show test configuration in logs + run: echo '${{ toJson(matrix.tests) }}' | jq . - name: Run tests id: run_tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@4f377a6b1cc07f0eca82745782736b4908a1da30 # v2.3.32 env: DETACH_RUNNER: true RR_MEM: ${{ matrix.tests.remote_runner_memory }} @@ -676,15 +757,13 @@ jobs: TEST_UPLOAD_CPU_PROFILE: true TEST_UPLOAD_MEM_PROFILE: true REF_NAME: ${{ github.head_ref || github.ref_name }} - E2E_TEST_CHAINLINK_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || inputs.chainlink_version || github.sha }} + E2E_TEST_CHAINLINK_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }} E2E_TEST_CHAINLINK_UPGRADE_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_VERSION }} E2E_TEST_CHAINLINK_POSTGRES_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_POSTGRES_VERSION }} E2E_TEST_SELECTED_NETWORK: ${{ matrix.tests.test_env_vars.E2E_TEST_SELECTED_NETWORK || env.SELECTED_NETWORKS }} E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} E2E_TEST_LOG_STREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} E2E_TEST_LOG_COLLECT: ${{ vars.TEST_LOG_COLLECT }} - E2E_TEST_CHAINLINK_IMAGE: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_IMAGE || env.CHAINLINK_IMAGE }} - E2E_TEST_CHAINLINK_UPGRADE_IMAGE: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_IMAGE }} E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} @@ -700,8 +779,11 @@ jobs: test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: make gomod test_secrets_override_base64: ${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }} + test_config_override_path: ${{ env.TEST_CONFIG_OVERRIDE_PATH }} test_type: ${{ matrix.tests.test_env_vars.TEST_TYPE }} test_suite: ${{ matrix.tests.test_env_vars.TEST_SUITE }} + default_e2e_test_chainlink_image: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_IMAGE || env.CHAINLINK_IMAGE }} + default_e2e_test_chainlink_upgrade_image: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_IMAGE }} token: ${{ secrets.GH_TOKEN }} should_cleanup: false cache_key_id: e2e-tests @@ -765,19 +847,45 @@ jobs: channel-id: ${{ inputs.slack_notification_after_tests_channel_id }} payload: | { - "blocks": [ + "attachments": [ { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "${{ inputs.slack_notification_after_tests_name }} - ${{ contains(join(needs.*.result, ','), 'failure') && 'Failed :x:' || contains(join(needs.*.result, ','), 'cancelled') && 'Cancelled :warning:' || 'Passed :white_check_mark:' }}" - } - }, + "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || contains(join(needs.*.result, ','), 'cancelled') && '#FFA000' || '#2E7D32' }}", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "${{ inputs.slack_notification_after_tests_name }} - ${{ contains(join(needs.*.result, ','), 'failure') && 'Failed :x:' || contains(join(needs.*.result, ','), 'cancelled') && 'Cancelled :warning:' || 'Passed :white_check_mark:' }}" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Build Details>" + } + } + ] + } + ] + } + + - name: Notify user in Slack message if tests failed + if: ${{ inputs.slack_notification_after_tests != '' && contains(join(needs.*.result, ','), 'failure') && inputs.slack_notification_after_tests_notify_user_id_on_failure != '' }} + uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + with: + channel-id: ${{ inputs.slack_notification_after_tests_channel_id }} + payload: | + { + "thread_ts": "${{ steps.slack.outputs.thread_ts }}", + "blocks": [ { "type": "section", "text": { "type": "mrkdwn", - "text": "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Build Details>" + "text": "Notifying <@${{ inputs.slack_notification_after_tests_notify_user_id_on_failure }}>, please check the test results." } } ] diff --git a/.github/workflows/run-selected-e2e-tests.yml b/.github/workflows/run-selected-e2e-tests.yml index ab064531fd..c204be6a56 100644 --- a/.github/workflows/run-selected-e2e-tests.yml +++ b/.github/workflows/run-selected-e2e-tests.yml @@ -16,11 +16,10 @@ on: description: 'Enter the secret key to override test secrets' required: false type: string - # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 - # test_config_override_base64: - # required: false - # description: The base64-encoded test config override - # type: string + test_config_override_path: + description: 'Path to a test config file used to override the default test config' + required: false + type: string enable_check_test_configurations: description: 'Set to "true" to enable check-test-configurations job' required: false @@ -45,8 +44,7 @@ jobs: with: chainlink_version: ${{ github.event.inputs.chainlink_version }} test_ids: ${{ github.event.inputs.test_ids }} - # TODO: Uncomment once Test Config does not have any secrets. Related ticket https://smartcontract-it.atlassian.net/browse/TT-1392 - # test_config_override_base64: ${{ github.event.inputs.test_config_override_base64 }} + test_config_override_path: ${{ github.event.inputs.test_config_override_path }} with_existing_remote_runner_version: ${{ github.event.inputs.with_existing_remote_runner_version }} # Use fromJSON to convert string to boolean. More info: https://github.com/actions/runner/issues/2206#issuecomment-1532246677 enable_check_test_configurations: ${{ fromJSON(github.event.inputs.enable_check_test_configurations) }} diff --git a/integration-tests/ccip-tests/testconfig/global.go b/integration-tests/ccip-tests/testconfig/global.go index 0095b4257c..c5b4a91fc0 100644 --- a/integration-tests/ccip-tests/testconfig/global.go +++ b/integration-tests/ccip-tests/testconfig/global.go @@ -113,6 +113,23 @@ func NewConfig() (*Config, error) { return nil, errors.Wrap(err, ErrReadConfig) } + // read secrets for all products + if cfg.CCIP != nil { + err := ctfconfig.LoadSecretEnvsFromFiles() + if err != nil { + return nil, errors.Wrap(err, "error loading testsecrets files") + } + err = cfg.CCIP.LoadFromEnv() + if err != nil { + return nil, errors.Wrap(err, "error loading env vars into CCIP config") + } + // validate all products + err = cfg.CCIP.Validate() + if err != nil { + return nil, err + } + } + // load config overrides from env var if specified // there can be multiple overrides separated by comma rawConfigs, _ := osutil.GetEnv(OVERIDECONFIG) @@ -137,22 +154,6 @@ func NewConfig() (*Config, error) { } } } - // read secrets for all products - if cfg.CCIP != nil { - err := ctfconfig.LoadSecretEnvsFromFiles() - if err != nil { - return nil, errors.Wrap(err, "error loading testsecrets files") - } - err = cfg.CCIP.LoadFromEnv() - if err != nil { - return nil, errors.Wrap(err, "error loading env vars into CCIP config") - } - // validate all products - err = cfg.CCIP.Validate() - if err != nil { - return nil, err - } - } return cfg, nil } diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index 2bb73f42ad..f1dd65c5a8 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -13,10 +13,9 @@ log_producer_retry_limit = 10 [ChainlinkImage] # postgres version to use postgres_version = "15.6" -# chainlink image to use -image = "public.ecr.aws/chainlink/chainlink" # chainlink image tag to use version = "2.12.0" +# Set chainlink image using E2E_TEST_CHAINLINK_IMAGE env, as it is a test secret [Common] # chainlink node funding in native token diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index 7ce7a07cc8..23d8d126c9 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -353,13 +353,19 @@ func GetConfig(configurationNames []string, product Product) (TestConfig, error) } } - // it needs some custom logic, so we do it separately - err := testConfig.readNetworkConfiguration() + logger.Info().Msg("Setting env vars from testsecrets dot-env files") + err := ctf_config.LoadSecretEnvsFromFiles() if err != nil { - return TestConfig{}, errors.Wrapf(err, "error reading network config") + return TestConfig{}, errors.Wrapf(err, "error reading test config values from ~/.testsecrets file") + } + + logger.Info().Msg("Reading config values from existing env vars") + err = testConfig.ReadFromEnvVar() + if err != nil { + return TestConfig{}, errors.Wrapf(err, "error reading test config values from env vars") } - logger.Info().Msg("Reading configs from Base64 override env var") + logger.Info().Msgf("Overriding config from %s env var", Base64OverrideEnvVarName) configEncoded, isSet := os.LookupEnv(Base64OverrideEnvVarName) if isSet && configEncoded != "" { logger.Debug().Msgf("Found base64 config override environment variable '%s' found", Base64OverrideEnvVarName) @@ -380,16 +386,9 @@ func GetConfig(configurationNames []string, product Product) (TestConfig, error) logger.Debug().Msg("Base64 config override from environment variable not found") } - logger.Info().Msg("Loading config values from default ~/.testsecrets env file") - err = ctf_config.LoadSecretEnvsFromFiles() + err = testConfig.readNetworkConfiguration() if err != nil { - return TestConfig{}, errors.Wrapf(err, "error reading test config values from ~/.testsecrets file") - } - - logger.Info().Msg("Reading values from environment variables") - err = testConfig.ReadFromEnvVar() - if err != nil { - return TestConfig{}, errors.Wrapf(err, "error reading test config values from env vars") + return TestConfig{}, errors.Wrapf(err, "error reading network config") } logger.Debug().Msg("Validating test config") diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/arbitrum_sepolia_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/arbitrum_sepolia_release_test_config.toml new file mode 100644 index 0000000000..a71e662cc4 --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/arbitrum_sepolia_release_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["ARBITRUM_SEPOLIA"] + +[ARBITRUM_SEPOLIA.VRFv2Plus.General] +use_existing_env = false \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/avalanche_fuji_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/avalanche_fuji_release_test_config.toml new file mode 100644 index 0000000000..5219ebe428 --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/avalanche_fuji_release_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["AVALANCHE_FUJI"] + +[AVALANCHE_FUJI.VRFv2Plus.General] +use_existing_env = false \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/base_sepolia_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/base_sepolia_release_test_config.toml new file mode 100644 index 0000000000..ffc209d2ad --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/base_sepolia_release_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["BASE_SEPOLIA"] + +[BASE_SEPOLIA.VRFv2Plus.General] +use_existing_env = false \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/bsc_testnet_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/bsc_testnet_release_test_config.toml new file mode 100644 index 0000000000..8a8ab538f2 --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/bsc_testnet_release_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["BSC_TESTNET"] + +[BSC_TESTNET.VRFv2Plus.General] +use_existing_env = false \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_dev_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_dev_release_test_config.toml new file mode 100644 index 0000000000..903e383886 --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_dev_release_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["NEXON_DEV"] + +[NEXON_DEV.VRFv2Plus.General] +use_existing_env = false \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_qa_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_qa_release_test_config.toml new file mode 100644 index 0000000000..ff5c62bf04 --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_qa_release_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["NEXON_QA"] + +[NEXON_QA.VRFv2Plus.General] +use_existing_env = false \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_stage_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_stage_release_test_config.toml new file mode 100644 index 0000000000..a504bd8c72 --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_stage_release_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["NEXON_STAGE"] + +[NEXON_STAGE.VRFv2Plus.General] +use_existing_env = false \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_test_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_test_release_test_config.toml new file mode 100644 index 0000000000..7551f348fb --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_test_release_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["NEXON_TEST"] + +[NEXON_TEST.VRFv2Plus.General] +use_existing_env = false \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/optimism_sepolia_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/optimism_sepolia_release_test_config.toml new file mode 100644 index 0000000000..6ccfa1c4ca --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/optimism_sepolia_release_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["OPTIMISM_SEPOLIA"] + +[OPTIMISM_SEPOLIA.VRFv2Plus.General] +use_existing_env = false \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/polygon_amoy_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/polygon_amoy_release_test_config.toml new file mode 100644 index 0000000000..e462be8acc --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/polygon_amoy_release_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["POLYGON_AMOY"] + +[POLYGON_AMOY.VRFv2Plus.General] +use_existing_env = false \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/sepolia_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/sepolia_release_test_config.toml new file mode 100644 index 0000000000..cef5136fec --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/release_testing/sepolia_release_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["SEPOLIA"] + +[SEPOLIA.VRFv2Plus.General] +use_existing_env = false \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/arbitrum_sepolia_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/arbitrum_sepolia_staging_test_config.toml new file mode 100644 index 0000000000..8ba2128f7a --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/arbitrum_sepolia_staging_test_config.toml @@ -0,0 +1,36 @@ +[Network] +selected_networks = ["ARBITRUM_SEPOLIA"] + +[ARBITRUM_SEPOLIA.VRFv2Plus.General] +use_existing_env = true + +[ARBITRUM_SEPOLIA.VRFv2Plus.ExistingEnv] +coordinator_address = "0xF7ba1Cf141F9729abC43c146dc2bf86EbcfD8603" +consumer_address = "" +sub_id = "" +key_hash = "0xe13aa26fe94bfcd2ae055911f4d3bf1aed54ca6cf77af34e17f918802fd69ba1" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 20 +node_sending_keys = [ + "0xbE21ae371FcA1aC2d8A152e707D21e68d7d99252", + "0xb13e9BA0aE94FD3b89B13b092e6d41614c805134", + "0x27aa703e585Ee165B7c977EAA652eCFa13b08294", + "0x9324643ACD2ec5b0813488E5EdAb64C3758ae4Ee", + "0x7CBA8c8e86f23f23363051650Fe5AE4DE78c3652", + "0x9A0143a4BAB55A826331A8ef82462557633aA016", + "0xD4259633F8e87949F683433a17e1fFcCE27865AC", + "0x5e47B71d6F95f68cd5538907ec6A9635b1Fe30Fa", + "0xa850a1a257FDF439c8f854ce3b89dd5b6F411827", + "0x7c82D56087c10aF2c3970f9a9Be7786B2850ce91", + "0x9545CB59956347d3debf27f5029754bBE1d398FA", + "0xEb8C69ac19709f27A97FB4A561f51AD2F9b34c5B", + # BHS + "0xf0e8cF7Fbd28Fc4D412B76B744CDA269df671F8e", + "0x317A02A658d12E5Bb4A6270171E7385928dD2d53", + "0x480f1dbcEc118Bd91e4dbb7e45bFa4A73180d21f", + "0x500a2662FaF981EC4669f791349D37Cbf1bE7d85", + "0x2ad350374B904c10B47c64ECdBD9e70BB0833Be2", + "0x0b946F0bF4e63C12b5157137f1c130f0788bC1b1", + # BHF + "0x571BBF4a5b07fc3F47Bd3B65CE2FE73739f86623" +] \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/avalanche_fuji_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/avalanche_fuji_staging_test_config.toml new file mode 100644 index 0000000000..9bf6c723cb --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/avalanche_fuji_staging_test_config.toml @@ -0,0 +1,18 @@ +[Network] +selected_networks = ["AVALANCHE_FUJI"] + +[AVALANCHE_FUJI.VRFv2Plus.General] +use_existing_env = true + +[AVALANCHE_FUJI.VRFv2Plus.ExistingEnv] +coordinator_address = "0xE122bf3Badd6545bDec5D4627a6DAd16352A1b36" +consumer_address = "" +sub_id = "" +key_hash = "0x5b03254a80ea3eb72139ff0423cb88be42612780c3dd25f1d95a5ba7708a4be1" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 30 +node_sending_keys = [ + "0x3D7Da5D6A23CA2240CE576C8638C1798a023920a", + # BHS + "0x72c8565279430F5179b0090d51ab8BB53Da323B5" +] \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/base_sepolia_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/base_sepolia_staging_test_config.toml new file mode 100644 index 0000000000..aaab02df7d --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/base_sepolia_staging_test_config.toml @@ -0,0 +1,20 @@ +[Network] +selected_networks = ["BASE_SEPOLIA"] + +[BASE_SEPOLIA.VRFv2Plus.General] +use_existing_env = true + +[BASE_SEPOLIA.VRFv2Plus.ExistingEnv] +coordinator_address = "0x2Cf7Bb5923FA4dBdf92981fDBbEe27d13A896705" +consumer_address = "" +sub_id = "" +key_hash = "0x01d1eb450e0271ac86d3b78c7cc799f80e7f80863a4875f6fc7b66629419c951" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 30 +node_sending_keys = [ + "0x5d621FF993B1a990d189936E70021c585e3B0880", + "0x87F701AD21BfAF99eF64596c5CE8762a5Cb9ED13", + "0xe8B0865e9Aae9DE628BE14965Bbd1C0c9C80d245", + # BHS + "0x65C853683beB6363869DDda8534b2aD45786d380", +] \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/bsc_testnet_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/bsc_testnet_staging_test_config.toml new file mode 100644 index 0000000000..d1716413f1 --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/bsc_testnet_staging_test_config.toml @@ -0,0 +1,18 @@ +[Network] +selected_networks = ["BSC_TESTNET"] + +[BSC_TESTNET.VRFv2Plus.General] +use_existing_env = true + +[BSC_TESTNET.VRFv2Plus.ExistingEnv] +coordinator_address = "0x84A477F6ebF33501eE3ACA86fEcB980b1fC99AC2" +consumer_address = "" +sub_id = "" +key_hash = "0x4d43763d3eff849a89cf578a42787baa32132d7a80032125710e95b3972cd214" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 30 +node_sending_keys = [ + "0x4EE2Cc6D50E8acb6BaEf673B03559525a6c92fB8", + # BHS + "0xAFB44568f7DAc218EA6e1C71c366692ED4758A07" +] \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_dev_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_dev_staging_test_config.toml new file mode 100644 index 0000000000..597abe13af --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_dev_staging_test_config.toml @@ -0,0 +1,18 @@ +[Network] +selected_networks = ["NEXON_DEV"] + +[NEXON_DEV.VRFv2Plus.General] +use_existing_env = true + +[NEXON_DEV.VRFv2Plus.ExistingEnv] +coordinator_address = "0x6901d7236A823E7B7911d90FBe46E6FA770CC823" +consumer_address = "" +sub_id = "" +key_hash = "0xdc023892a41e5fe74ec7c4c2e8c0a808b01aea7acaf2b2ae30f4e08df877c48b" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 30 +node_sending_keys = [ + "0xF3d9879a75BBD85890056D7c6cB37C555F9b41A3", + # BHS + "0xb544f9D7c16a30af0EEd0afcC4132D1c63bAF8AC", +] \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_qa_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_qa_staging_test_config.toml new file mode 100644 index 0000000000..5f5feab74a --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_qa_staging_test_config.toml @@ -0,0 +1,19 @@ +[Network] +selected_networks = ["NEXON_QA"] + +[NEXON_QA.VRFv2Plus.General] +use_existing_env = true + +[NEXON_QA.VRFv2Plus.ExistingEnv] +coordinator_address = "0xF1F0beBcc284591FCD28d8f2BAc9f30efdA3E0ea" +consumer_address = "" +sub_id = "" +key_hash = "0x7d5692e71807c4c02f5a109627a9ad2b12a361a346790a306983af9a5e3a186f" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 30 +node_sending_keys = [ + "0xB97c0C52A2B957b45DA213e652c76090DDd0FEc6", + "0xe205F5d4a99ca0f474d0b4d12f60a0153c786B4E", + # BHS + "0xf85E291edF0352435f2fD5e817030f6542375a99", +] diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_stage_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_stage_staging_test_config.toml new file mode 100644 index 0000000000..1a50876a73 --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_stage_staging_test_config.toml @@ -0,0 +1,15 @@ +[Network] +selected_networks = ["NEXON_STAGE"] + +[NEXON_STAGE.VRFv2Plus.General] +use_existing_env = true + +[NEXON_STAGE.VRFv2Plus.ExistingEnv] +coordinator_address = "0xF705dD3e7E717F32de0Cc5F833f8009f16122AD1" +consumer_address = "" +sub_id = "" +key_hash = "0xbc9f525e3e1d9e2336f7c77d5f33f5b60aab3765944617fed7f66a6afecac616" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 30 +node_sending_keys = [ +] diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_test_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_test_staging_test_config.toml new file mode 100644 index 0000000000..aeb4cbdb29 --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_test_staging_test_config.toml @@ -0,0 +1,19 @@ +[Network] +selected_networks = ["NEXON_TEST"] + +[NEXON_TEST.VRFv2Plus.General] +use_existing_env = true + +[NEXON_TEST.VRFv2Plus.ExistingEnv] +coordinator_address = "0xAa92Ba21168B48195cAdB87cfaB3eB70B2499F55" +consumer_address = "" +sub_id = "" +key_hash = "0x0cb2a18e8b762cb4c8f7b17a6cc02ac7b9d2a3346f048cfd2f5d37677f8747d8" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 30 +node_sending_keys = [ + "0xBFD780Af421e98C35918e10B9d6da7389C3e1D10", + "0xbf6c76024672F233aB8164EC00683e1AE774F6b0", + # BHS + "0x2a3900Ac77de110670E060DBFf4fCbe36c6f8170", +] \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/optimism_sepolia_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/optimism_sepolia_staging_test_config.toml new file mode 100644 index 0000000000..c707b83f8d --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/optimism_sepolia_staging_test_config.toml @@ -0,0 +1,20 @@ +[Network] +selected_networks = ["OPTIMISM_SEPOLIA"] + +[OPTIMISM_SEPOLIA.VRFv2Plus.General] +use_existing_env = true + +[OPTIMISM_SEPOLIA.VRFv2Plus.ExistingEnv] +coordinator_address = "0xA4a64A217bE85680e0ebB454CD5BF4A1c274Fc7B" +consumer_address = "" +sub_id = "" +key_hash = "0x4b4838bbf22a7c5a871ada8ceab6ded3c2de6cadc037371146ee70f6435325c1" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 30 +node_sending_keys = [ + "0x17509D615052DE3A81a684755Ec118d62C4e1Cd1", + "0x5118ece61294f4dFf4a1fb63b3f036969516dF0a", + "0x89554391652616ea06a408263b9B2b9a70E87204", + # BHS + "0x8DE6446b5022C68F38CD32d04AA0E3b8F4C1aaB6", +] \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/polygon_amoy_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/polygon_amoy_staging_test_config.toml new file mode 100644 index 0000000000..0b49f66ec3 --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/polygon_amoy_staging_test_config.toml @@ -0,0 +1,32 @@ +[Network] +selected_networks = ["POLYGON_AMOY"] + +[POLYGON_AMOY.VRFv2Plus.General] +use_existing_env = true + +[POLYGON_AMOY.VRFv2Plus.ExistingEnv] +coordinator_address = "0x7541EbaE23f32B4A1A2e7a8Cbf9da9582767A9B4" +consumer_address = "" +sub_id = "" +key_hash = "0xd360445bacd26df47086ccf255c4f932d297ed8d5c7334b51eed32f61c541601" +#key_hash = "0x2328cbee29e32d0b6662d6df82ff0fea7be300bd310561c92f515c9ee19464f1" +#key_hash = "0x25f4e2d0509f42ec77db5380f3433a89fe623fa75f65d5b398d5f498327be4dd" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 10 +node_sending_keys = [ + "0xD96013C241f1741C35a135321969f92Aae02A12F", + "0x0580E61a5523F5CAAC4968E4f8FE63b59596BdD7", + "0xd15FcEa6a6AA17085930Fbd5647A9F7fD2Ff58b8", + "0xB7277cBb6E7028AE65235b8ee9201AcBb14B11d4", + "0x6D36a1dC1eEd25C75961E989c4d01Cd4453bE465", + "0xd299Cd7C0073b71e620bf8A3bfD50F75c0b49af8", + "0x48BE7BAED0b65776D85DF971fA901c637cFC5e87", + # BHS + "0x638372de870eF0F8E675A3f67F18D5bd4A2fd804", + "0xF9eF03816411D037202d5ed4457dC1613e3bd729", + "0xCD66973f8fbaE787211EC20228c6bd90D83562A8", + "0x242ea1F4Bb72EF643B2D8EF22e18a89f00742F40", + "0xaA09B4F9B5710b239fdbf1D0f535dd7f86F91219", + "0xe6b72B647B8B45C5562F7a5259E187889C747d3b", + "0x2c1185C4d3B0B4a577d4079Ee193A4e293164D9d" +] \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/sepolia_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/sepolia_staging_test_config.toml new file mode 100644 index 0000000000..346b1d792c --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/sepolia_staging_test_config.toml @@ -0,0 +1,18 @@ +[Network] +selected_networks = ["SEPOLIA"] + +[SEPOLIA.VRFv2Plus.General] +use_existing_env = true + +[SEPOLIA.VRFv2Plus.ExistingEnv] +coordinator_address = "0x2F3b892710523Ee9A85c3155a42089fFe99Ca31e" +consumer_address = "" +sub_id = "" +key_hash = "0xf5b4a359df0598eef89872ea2170f2afa844dbf74b417e6d44d4bda9420aceb2" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 30 +node_sending_keys = [ + "0x0c0DC7f33A1256f0247c5ea75861d385fa5FED31", + # BHS + "0xEd8A4b792d16484f6c9B4df1e721e8280925Db80", +] \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml index 941f3a827d..c2b0bcfc00 100644 --- a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml +++ b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml @@ -1,4 +1,5 @@ # default config + [NodeConfig] BaseConfigTOML = """ [Feature] @@ -400,33 +401,6 @@ bhs_job_poll_period = "2s" bhs_job_run_timeout = "30s" # NEW ENV CONFIG END -[POLYGON_AMOY.VRFv2Plus.ExistingEnv] -coordinator_address = "0x7541EbaE23f32B4A1A2e7a8Cbf9da9582767A9B4" -consumer_address = "" -sub_id = "" -key_hash = "0xd360445bacd26df47086ccf255c4f932d297ed8d5c7334b51eed32f61c541601" -#key_hash = "0x2328cbee29e32d0b6662d6df82ff0fea7be300bd310561c92f515c9ee19464f1" -#key_hash = "0x25f4e2d0509f42ec77db5380f3433a89fe623fa75f65d5b398d5f498327be4dd" -create_fund_subs_and_add_consumers = true -node_sending_key_funding_min = 10 -node_sending_keys = [ - "0xD96013C241f1741C35a135321969f92Aae02A12F", - "0x0580E61a5523F5CAAC4968E4f8FE63b59596BdD7", - "0xd15FcEa6a6AA17085930Fbd5647A9F7fD2Ff58b8", - "0xB7277cBb6E7028AE65235b8ee9201AcBb14B11d4", - "0x6D36a1dC1eEd25C75961E989c4d01Cd4453bE465", - "0xd299Cd7C0073b71e620bf8A3bfD50F75c0b49af8", - "0x48BE7BAED0b65776D85DF971fA901c637cFC5e87", - # BHS - "0x638372de870eF0F8E675A3f67F18D5bd4A2fd804", - "0xF9eF03816411D037202d5ed4457dC1613e3bd729", - "0xCD66973f8fbaE787211EC20228c6bd90D83562A8", - "0x242ea1F4Bb72EF643B2D8EF22e18a89f00742F40", - "0xaA09B4F9B5710b239fdbf1D0f535dd7f86F91219", - "0xe6b72B647B8B45C5562F7a5259E187889C747d3b", - "0x2c1185C4d3B0B4a577d4079Ee193A4e293164D9d" -] - #SMOKE TEST CONFIG [POLYGON_AMOY-Smoke.VRFv2Plus.General] randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request @@ -519,36 +493,7 @@ bhs_job_poll_period = "300ms" bhs_job_run_timeout = "30s" # NEW ENV CONFIG END -[ARBITRUM_SEPOLIA.VRFv2Plus.ExistingEnv] -coordinator_address = "0xF7ba1Cf141F9729abC43c146dc2bf86EbcfD8603" -consumer_address = "" -sub_id = "" -key_hash = "0xe13aa26fe94bfcd2ae055911f4d3bf1aed54ca6cf77af34e17f918802fd69ba1" -create_fund_subs_and_add_consumers = true -node_sending_key_funding_min = 20 -node_sending_keys = [ - "0xbE21ae371FcA1aC2d8A152e707D21e68d7d99252", - "0xb13e9BA0aE94FD3b89B13b092e6d41614c805134", - "0x27aa703e585Ee165B7c977EAA652eCFa13b08294", - "0x9324643ACD2ec5b0813488E5EdAb64C3758ae4Ee", - "0x7CBA8c8e86f23f23363051650Fe5AE4DE78c3652", - "0x9A0143a4BAB55A826331A8ef82462557633aA016", - "0xD4259633F8e87949F683433a17e1fFcCE27865AC", - "0x5e47B71d6F95f68cd5538907ec6A9635b1Fe30Fa", - "0xa850a1a257FDF439c8f854ce3b89dd5b6F411827", - "0x7c82D56087c10aF2c3970f9a9Be7786B2850ce91", - "0x9545CB59956347d3debf27f5029754bBE1d398FA", - "0xEb8C69ac19709f27A97FB4A561f51AD2F9b34c5B", - # BHS - "0xf0e8cF7Fbd28Fc4D412B76B744CDA269df671F8e", - "0x317A02A658d12E5Bb4A6270171E7385928dD2d53", - "0x480f1dbcEc118Bd91e4dbb7e45bFa4A73180d21f", - "0x500a2662FaF981EC4669f791349D37Cbf1bE7d85", - "0x2ad350374B904c10B47c64ECdBD9e70BB0833Be2", - "0x0b946F0bF4e63C12b5157137f1c130f0788bC1b1", - # BHF - "0x571BBF4a5b07fc3F47Bd3B65CE2FE73739f86623" -] + #SMOKE TEST CONFIG [ARBITRUM_SEPOLIA-Smoke.VRFv2Plus.General] @@ -644,19 +589,6 @@ bhs_job_poll_period = "2s" bhs_job_run_timeout = "30s" # NEW ENV CONFIG END -[AVALANCHE_FUJI.VRFv2Plus.ExistingEnv] -coordinator_address = "0xE122bf3Badd6545bDec5D4627a6DAd16352A1b36" -consumer_address = "" -sub_id = "" -key_hash = "0x5b03254a80ea3eb72139ff0423cb88be42612780c3dd25f1d95a5ba7708a4be1" -create_fund_subs_and_add_consumers = true -node_sending_key_funding_min = 50 -node_sending_keys = [ - "0x3D7Da5D6A23CA2240CE576C8638C1798a023920a", - # BHS - "0x72c8565279430F5179b0090d51ab8BB53Da323B5" -] - #SMOKE TEST CONFIG [AVALANCHE_FUJI-Smoke.VRFv2Plus.General] randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request @@ -699,6 +631,197 @@ test_duration = "10m" rate_limit_unit_duration = "1m" rps = 1 +### BASE SEPOLIA Config +[BASE_SEPOLIA.Common] +chainlink_node_funding = 5 +[BASE_SEPOLIA.VRFv2Plus.General] +use_test_coordinator = false +#todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request +minimum_confirmations = 0 + +# Consumer Request config +subscription_billing_type = "LINK_AND_NATIVE" +callback_gas_limit = 1000000 + +# NEW ENV CONFIG +# CL Node config +cl_node_max_gas_price_gwei = 30 +number_of_sending_keys_to_create = 0 + +# Coordinator config +max_gas_limit_coordinator_config = 2500000 +fallback_wei_per_unit_link = "3962147213857640" +staleness_seconds = 172_800 +gas_after_payment_calculation = 42_500 +fulfillment_flat_fee_native_ppm = 0 +fulfillment_flat_fee_link_discount_ppm = 0 +native_premium_percentage = 60 +link_premium_percentage = 50 + +# Wrapper config +wrapped_gas_overhead = 13_400 +coordinator_gas_overhead_native = 128_500 +coordinator_gas_overhead_link = 150_400 +coordinator_gas_overhead_per_word = 435 +coordinator_native_premium_percentage = 60 +coordinator_link_premium_percentage = 50 +wrapper_max_number_of_words = 10 + +# VRF Job config +vrf_job_forwarding_allowed = false +vrf_job_estimate_gas_multiplier = 1.15 +vrf_job_batch_fulfillment_enabled = true +vrf_job_batch_fulfillment_gas_multiplier = 1.1 +vrf_job_poll_period = "2s" +vrf_job_request_timeout = "2h0m0s" +vrf_job_simulation_block = "pending" + +# BHS Job config +bhs_job_wait_blocks = 30 +bhs_job_lookback_blocks = 200 +bhs_job_poll_period = "2s" +bhs_job_run_timeout = "30s" +# NEW ENV CONFIG END + +#SMOKE TEST CONFIG +[BASE_SEPOLIA-Smoke.VRFv2Plus.General] +randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +number_of_sub_to_create = 1 +subscription_funding_amount_link = 3 +subscription_funding_amount_native = 1 +subscription_refunding_amount_link = 3 +subscription_refunding_amount_native = 1 +number_of_words = 1 +random_words_fulfilled_event_timeout = "1m30s" +wait_for_256_blocks_timeout = "10m" + +wrapper_consumer_funding_amount_native_token = 1.0 +wrapper_consumer_funding_amount_link = 5 + +[BASE_SEPOLIA-Soak.VRFv2Plus.General] +randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +number_of_sub_to_create = 1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native = 100 + +[BASE_SEPOLIA-Soak.VRFv2Plus.Performance] +test_duration = "2h" +rate_limit_unit_duration = "10s" +rps = 1 + +[BASE_SEPOLIA-Stress.VRFv2Plus.General] +randomness_request_count_per_request = 60 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +number_of_sub_to_create = 1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 + +[BASE_SEPOLIA-Stress.VRFv2Plus.Performance] +test_duration = "10m" +rate_limit_unit_duration = "1m" +rps = 1 + + +### OPTIMISM SEPOLIA Config +[OPTIMISM_SEPOLIA.Common] +chainlink_node_funding = 5 +[OPTIMISM_SEPOLIA.VRFv2Plus.General] +sub_billing_tolerance_wei = 1e16 +use_test_coordinator = false +#todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request +minimum_confirmations = 0 + +# Consumer Request config +subscription_billing_type = "LINK_AND_NATIVE" +callback_gas_limit = 1000000 + +# NEW ENV CONFIG +# CL Node config +cl_node_max_gas_price_gwei = 30 +number_of_sending_keys_to_create = 0 + +# Coordinator config +max_gas_limit_coordinator_config = 2500000 +fallback_wei_per_unit_link = "3896881047706782" +staleness_seconds = 172_800 +gas_after_payment_calculation = 42_500 +fulfillment_flat_fee_native_ppm = 0 +fulfillment_flat_fee_link_discount_ppm = 0 +native_premium_percentage = 60 +link_premium_percentage = 50 + +# Wrapper config +wrapped_gas_overhead = 13_400 +coordinator_gas_overhead_native = 128_500 +coordinator_gas_overhead_link = 150_400 +coordinator_gas_overhead_per_word = 435 +coordinator_native_premium_percentage = 60 +coordinator_link_premium_percentage = 50 +wrapper_max_number_of_words = 10 + +# VRF Job config +vrf_job_forwarding_allowed = false +vrf_job_estimate_gas_multiplier = 1.15 +vrf_job_batch_fulfillment_enabled = true +vrf_job_batch_fulfillment_gas_multiplier = 1.1 +vrf_job_poll_period = "2s" +vrf_job_request_timeout = "2h0m0s" +vrf_job_simulation_block = "pending" + +# BHS Job config +bhs_job_wait_blocks = 30 +bhs_job_lookback_blocks = 200 +bhs_job_poll_period = "2s" +bhs_job_run_timeout = "30s" +# NEW ENV CONFIG END + +#SMOKE TEST CONFIG +[OPTIMISM_SEPOLIA-Smoke.VRFv2Plus.General] +randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +number_of_sub_to_create = 1 +subscription_funding_amount_link = 10 +subscription_funding_amount_native = 1 +subscription_refunding_amount_link = 10 +subscription_refunding_amount_native = 1 +number_of_words = 1 +random_words_fulfilled_event_timeout = "1m30s" +wait_for_256_blocks_timeout = "10m" + +wrapper_consumer_funding_amount_native_token = 1.0 +wrapper_consumer_funding_amount_link = 5 + +[OPTIMISM_SEPOLIA-Soak.VRFv2Plus.General] +randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +number_of_sub_to_create = 1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native = 100 + +[OPTIMISM_SEPOLIA-Soak.VRFv2Plus.Performance] +test_duration = "2h" +rate_limit_unit_duration = "10s" +rps = 1 + +[OPTIMISM_SEPOLIA-Stress.VRFv2Plus.General] +randomness_request_count_per_request = 60 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +number_of_sub_to_create = 1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 + +[OPTIMISM_SEPOLIA-Stress.VRFv2Plus.Performance] +test_duration = "10m" +rate_limit_unit_duration = "1m" +rps = 1 + + ### ETH SEPOLIA Config [SEPOLIA.VRFv2Plus.General] use_test_coordinator = true @@ -749,19 +872,6 @@ bhs_job_poll_period = "30s" bhs_job_run_timeout = "1m0s" # NEW ENV CONFIG END -[SEPOLIA.VRFv2Plus.ExistingEnv] -coordinator_address = "0x2F3b892710523Ee9A85c3155a42089fFe99Ca31e" -consumer_address = "" -sub_id = "" -key_hash = "0xf5b4a359df0598eef89872ea2170f2afa844dbf74b417e6d44d4bda9420aceb2" -create_fund_subs_and_add_consumers = true -node_sending_key_funding_min = 50 -node_sending_keys = [ - "0x0c0DC7f33A1256f0247c5ea75861d385fa5FED31", - # BHS - "0xEd8A4b792d16484f6c9B4df1e721e8280925Db80", -] - #SMOKE TEST CONFIG [SEPOLIA-Smoke.VRFv2Plus.General] randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request @@ -854,19 +964,6 @@ bhs_job_poll_period = "2s" bhs_job_run_timeout = "30s" # NEW ENV CONFIG END -[BSC_TESTNET.VRFv2Plus.ExistingEnv] -coordinator_address = "0x84A477F6ebF33501eE3ACA86fEcB980b1fC99AC2" -consumer_address = "" -sub_id = "" -key_hash = "0x4d43763d3eff849a89cf578a42787baa32132d7a80032125710e95b3972cd214" -create_fund_subs_and_add_consumers = true -node_sending_key_funding_min = 150 -node_sending_keys = [ - "0x4EE2Cc6D50E8acb6BaEf673B03559525a6c92fB8", - # BHS - "0xAFB44568f7DAc218EA6e1C71c366692ED4758A07" -] - #SMOKE TEST CONFIG [BSC_TESTNET-Smoke.VRFv2Plus.General] randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request @@ -920,20 +1017,6 @@ generate_txs_on_chain = true subscription_billing_type = "LINK_AND_NATIVE" callback_gas_limit = 1000000 -[NEXON_QA.VRFv2Plus.ExistingEnv] -coordinator_address = "0xF1F0beBcc284591FCD28d8f2BAc9f30efdA3E0ea" -consumer_address = "" -sub_id = "" -key_hash = "0x7d5692e71807c4c02f5a109627a9ad2b12a361a346790a306983af9a5e3a186f" -create_fund_subs_and_add_consumers = true -node_sending_key_funding_min = 30 -node_sending_keys = [ - "0xB97c0C52A2B957b45DA213e652c76090DDd0FEc6", - "0xe205F5d4a99ca0f474d0b4d12f60a0153c786B4E", - # BHS - "0xf85E291edF0352435f2fD5e817030f6542375a99", -] - #SMOKE TEST CONFIG [NEXON_QA-Smoke.VRFv2Plus.General] randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request @@ -986,19 +1069,6 @@ generate_txs_on_chain = true subscription_billing_type = "LINK_AND_NATIVE" callback_gas_limit = 1000000 -[NEXON_DEV.VRFv2Plus.ExistingEnv] -coordinator_address = "0x6901d7236A823E7B7911d90FBe46E6FA770CC823" -consumer_address = "" -sub_id = "" -key_hash = "0xdc023892a41e5fe74ec7c4c2e8c0a808b01aea7acaf2b2ae30f4e08df877c48b" -create_fund_subs_and_add_consumers = true -node_sending_key_funding_min = 30 -node_sending_keys = [ - "0xF3d9879a75BBD85890056D7c6cB37C555F9b41A3", - # BHS - "0xb544f9D7c16a30af0EEd0afcC4132D1c63bAF8AC", -] - #SMOKE TEST CONFIG [NEXON_DEV-Smoke.VRFv2Plus.General] randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request @@ -1051,19 +1121,6 @@ generate_txs_on_chain = true subscription_billing_type = "LINK_AND_NATIVE" callback_gas_limit = 1000000 -[NEXON_TEST.VRFv2Plus.ExistingEnv] -coordinator_address = "0xAa92Ba21168B48195cAdB87cfaB3eB70B2499F55" -consumer_address = "" -sub_id = "" -key_hash = "0x0cb2a18e8b762cb4c8f7b17a6cc02ac7b9d2a3346f048cfd2f5d37677f8747d8" -create_fund_subs_and_add_consumers = true -node_sending_key_funding_min = 30 -node_sending_keys = [ - "0xBFD780Af421e98C35918e10B9d6da7389C3e1D10", - "0xbf6c76024672F233aB8164EC00683e1AE774F6b0", - # BHS - "0x2a3900Ac77de110670E060DBFf4fCbe36c6f8170", -] #SMOKE TEST CONFIG [NEXON_TEST-Smoke.VRFv2Plus.General] @@ -1118,15 +1175,6 @@ generate_txs_on_chain = true subscription_billing_type = "LINK_AND_NATIVE" callback_gas_limit = 1000000 -[NEXON_STAGE.VRFv2Plus.ExistingEnv] -coordinator_address = "0xF705dD3e7E717F32de0Cc5F833f8009f16122AD1" -consumer_address = "" -sub_id = "" -key_hash = "0xbc9f525e3e1d9e2336f7c77d5f33f5b60aab3765944617fed7f66a6afecac616" -create_fund_subs_and_add_consumers = true -node_sending_key_funding_min = 30 -node_sending_keys = [ -] #SMOKE TEST CONFIG [NEXON_STAGE-Smoke.VRFv2Plus.General] From 57cec53b3d38a501509f329b5e141554d295120b Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Fri, 6 Sep 2024 15:44:10 +0200 Subject: [PATCH 303/432] TT-1602 Add docs about E2E Github Workflows (#14330) * Add .github/README.md with information about E2E tests on GitHub CI * update * update * Add docs about test config and test secrets * more docs * mention ctf test config * use links * add slack_notification_after_tests_notify_user_id_on_failure * add How to Run Custom Tests with Reusable Workflow * add Client Compatibility Tests * format yml * fix --- .github/README.md | 139 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 .github/README.md diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 0000000000..f3a279338d --- /dev/null +++ b/.github/README.md @@ -0,0 +1,139 @@ +# E2E Tests on GitHub CI + +E2E tests are executed on GitHub CI using the [E2E Tests Reusable Workflow](#about-the-reusable-workflow) or dedicated workflows. + +## Automatic workflows + +These workflows are designed to run automatically at crucial stages of the software development process, such as on every commit in a PR, nightly or before release. + +### PR E2E Tests + +Run on every commit in a PR to ensure changes do not introduce regressions. + +[Link](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/integration-tests.yml) + +### Nightly E2E Tests + +Conducted nightly to catch issues that may develop over time or with accumulated changes. + +[Link](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/run-nightly-e2e-tests.yml) + +### Release E2E Tests + +This section contains automatic workflows triggering E2E tests at release. + +#### Client Compatibility Tests + +[Link](https://github.com/smartcontractkit/chainlink/actions/workflows/client-compatibility-tests.yml) + +## On-Demand Workflows + +Triggered manually by QA for specific testing needs. + +**Examples:** + +- [On-Demand Automation Tests](https://github.com/smartcontractkit/chainlink/actions/workflows/automation-ondemand-tests.yml) +- [CCIP Chaos Tests](https://github.com/smartcontractkit/chainlink/actions/workflows/ccip-chaos-tests.yml) +- [OCR Soak Tests](https://github.com/smartcontractkit/chainlink/actions/workflows/on-demand-ocr-soak-test.yml) +- [VRFv2Plus Smoke Tests](https://github.com/smartcontractkit/chainlink/actions/workflows/on-demand-vrfv2plus-smoke-tests.yml) + +## Test Configs + +E2E tests utilize TOML files to define their parameters. Each test is equipped with a default TOML config, which can be overridden by specifying an alternative TOML config. This allows for running tests with varied parameters, such as on a non-default blockchain network. For tests executed on GitHub CI, both the default configs and any override configs must reside within the git repository. The `test_config_override_path` workflow input is used to provide a path to an override config. + +Config overrides should be stored in `testconfig/*/overrides/*.toml`. Placing files here will not trigger a rebuild of the test runner image. + +**Important Note:** The use of `base64Config` input is deprecated in favor of `test_config_override_path`. For more details, refer to [the decision log](https://smartcontract-it.atlassian.net/wiki/spaces/TT/pages/927596563/Storing+All+Test+Configs+In+Git). + +To learn more about test configs see [CTF Test Config](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/lib/config/README.md). + +## Test Secrets + +For security reasons, test secrets and sensitive information are not stored directly within the test config TOML files. Instead, these secrets are securely injected into tests using environment variables. For a detailed explanation on managing test secrets, refer to our [Test Secrets documentation](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md#test-secrets). + +If you need to run a GitHub workflow using custom secrets, please refer to the [guide on running GitHub workflows with your test secrets](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md#run-github-workflow-with-your-test-secrets). + +## About the Reusable Workflow + +The [E2E Tests Reusable Workflow](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/run-e2e-tests-reusable-workflow.yml) is designed to run any type of E2E test on GitHub CI, including docker/testcontainers, old K8s tests, or tests in CRIB in the future. + +Our goal is to migrate all workflows to use this reusable workflow for executing E2E tests. This approach will streamline our CI and allow for the automatic execution of tests at different stages of the software development process. Learn more about the advantages of using reusable workflows [here](https://smartcontract-it.atlassian.net/wiki/spaces/TT/pages/815497220/CI+Workflows+for+E2E+Tests). + +**Examples of Workflows Utilizing the Reusable Workflow:** + +- [Integration Tests](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/integration-tests.yml) +- [Nightly E2E Tests](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/run-nightly-e2e-tests.yml) +- [Selected E2E Tests](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/run-selected-e2e-tests.yml) +- [On-Demand Automation Tests](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/automation-ondemand-tests.yml) +- [CCIP Chaos Tests](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/ccip-chaos-tests.yml) + +### E2E Test Configuration on GitHub CI + +The [e2e-tests.yml](https://github.com/smartcontractkit/chainlink/blob/develop/.github/e2e-tests.yml) file lists all E2E tests configured for execution on CI. Each entry specifies the type of GitHub Runner needed and the workflows in which the test is included (for example, `smoke/ocr_test.go:*` is executed both in PRs and nightly). + +### Slack Notification After Tests + +To configure Slack notifications after tests executed via the reusable workflow, follow these steps: + +- Set `slack_notification_after_tests` to either `always` or `on_failure` depending on when you want notifications to be sent. +- Assign `slack_notification_after_tests_channel_id` to the ID of the Slack channel where notifications should be sent. +- Provide a title for the notification by setting `slack_notification_after_tests_name`. +- Optionally use `slack_notification_after_tests_notify_user_id_on_failure` to reply in the thread and notify a user about the failed workflow + +**Example:** + +```yml +jobs: + call-run-e2e-tests-workflow: + name: Run E2E Tests + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + chainlink_version: develop + test_workflow: Nightly E2E Tests + slack_notification_after_tests: true + slack_notification_after_tests_channel_id: "#team-test-tooling-internal" + slack_notification_after_tests_name: Nightly E2E Tests + slack_notification_after_tests_notify_user_id_on_failure: U0XXXXXXX +``` + +## Guides + +### How to Run Selected Tests on GitHub CI + +The [Run Selected E2E Tests Workflow](https://github.com/smartcontractkit/chainlink/actions/workflows/run-selected-e2e-tests.yml) allows you to execute specific E2E tests as defined in the [e2e-tests.yml](https://github.com/smartcontractkit/chainlink/blob/develop/.github/e2e-tests.yml). This is useful for various purposes such as testing specific features on a particular branch or verifying that modifications to a test have not introduced any issues. + +For details on all available inputs that the workflow supports, refer to the [workflow definition](https://github.com/smartcontractkit/chainlink/actions/workflows/run-selected-e2e-tests.yml). + +**Example Usage:** + +To run a set of VRFv2Plus tests from a custom branch, use the following command: + +```bash +gh workflow run run-selected-e2e-tests.yml \ +-f test_ids="TestVRFv2Plus_LinkBilling,TestVRFv2Plus_NativeBilling,TestVRFv2Plus_DirectFunding,TestVRFV2PlusWithBHS" \ +-f chainlink_version=develop \ +--ref TT-1550-Provide-PoC-for-keeping-test-configs-in-git +``` + +### How to Run Custom Tests with Reusable Workflow + +To run a specific list of tests, utilize the `custom_test_list_json` input. This allows you to provide a customized list of tests. If your test list is dynamic, you can generate it during a preceding job and then reference it using: `custom_test_list_json: ${{ needs.gen_test_list.outputs.test_list }}`. + +```yml +run-e2e-tests-workflow: + name: Run E2E Tests + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + custom_test_list_json: > + { + "tests": [ + { + "id": "TestVRFv2Plus", + "path": "integration-tests/smoke/vrfv2plus_test.go", + "runs_on": "ubuntu-latest", + "test_env_type": "docker", + "test_cmd": "cd integration-tests/smoke && go test vrfv2plus_test.go" + } + ] + } +``` \ No newline at end of file From 792d85de854ea7aa3aa2c3b5f0fdb8071d688cbb Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Fri, 6 Sep 2024 16:53:24 +0200 Subject: [PATCH 304/432] Fix readme (#14363) --- .github/{README.md => E2E_TESTS_ON_GITHUB_CI.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{README.md => E2E_TESTS_ON_GITHUB_CI.md} (100%) diff --git a/.github/README.md b/.github/E2E_TESTS_ON_GITHUB_CI.md similarity index 100% rename from .github/README.md rename to .github/E2E_TESTS_ON_GITHUB_CI.md From 72f4cc8aaa128202fd5974c6dbfb29c6beb1be12 Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Fri, 6 Sep 2024 15:56:33 +0100 Subject: [PATCH 305/432] Core changes for changing Execute Capability API to sync (#14317) * changes required to move capability execute api from async channel to sync * lint --- .changeset/cold-suns-hope.md | 5 ++ core/capabilities/launcher_test.go | 4 +- core/capabilities/registry_test.go | 4 +- core/capabilities/remote/target/client.go | 15 ++++- .../capabilities/remote/target/client_test.go | 17 ++---- .../remote/target/endtoend_test.go | 57 +++++++------------ .../remote/target/request/client_request.go | 22 ++++--- .../target/request/client_request_test.go | 2 - .../remote/target/request/server_request.go | 7 +-- .../target/request/server_request_test.go | 17 +++--- core/capabilities/targets/write_target.go | 35 +++++------- .../capabilities/targets/write_target_test.go | 3 +- .../transmission/local_target_capability.go | 8 +-- .../local_target_capability_test.go | 12 ++-- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/relay/evm/write_target_test.go | 5 +- core/services/workflows/engine.go | 24 +------- core/services/workflows/engine_test.go | 19 ++----- core/services/workflows/models.go | 2 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 26 files changed, 116 insertions(+), 166 deletions(-) create mode 100644 .changeset/cold-suns-hope.md diff --git a/.changeset/cold-suns-hope.md b/.changeset/cold-suns-hope.md new file mode 100644 index 0000000000..a6abf7e078 --- /dev/null +++ b/.changeset/cold-suns-hope.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal changes required for capability api chance to sync diff --git a/core/capabilities/launcher_test.go b/core/capabilities/launcher_test.go index 220a7838db..425c6815a4 100644 --- a/core/capabilities/launcher_test.go +++ b/core/capabilities/launcher_test.go @@ -46,8 +46,8 @@ type mockCapability struct { capabilities.CapabilityInfo } -func (m *mockCapability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) { - return nil, nil +func (m *mockCapability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { + return capabilities.CapabilityResponse{}, nil } func (m *mockCapability) RegisterToWorkflow(ctx context.Context, request capabilities.RegisterToWorkflowRequest) error { diff --git a/core/capabilities/registry_test.go b/core/capabilities/registry_test.go index 77e5d9edcd..89f366da04 100644 --- a/core/capabilities/registry_test.go +++ b/core/capabilities/registry_test.go @@ -21,8 +21,8 @@ type mockCapability struct { capabilities.CapabilityInfo } -func (m *mockCapability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) { - return nil, nil +func (m *mockCapability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { + return capabilities.CapabilityResponse{}, nil } func (m *mockCapability) RegisterToWorkflow(ctx context.Context, request capabilities.RegisterToWorkflowRequest) error { diff --git a/core/capabilities/remote/target/client.go b/core/capabilities/remote/target/client.go index 8572efed15..64dcbd14f0 100644 --- a/core/capabilities/remote/target/client.go +++ b/core/capabilities/remote/target/client.go @@ -123,7 +123,17 @@ func (c *client) UnregisterFromWorkflow(ctx context.Context, request commoncap.U return nil } -func (c *client) Execute(ctx context.Context, capReq commoncap.CapabilityRequest) (<-chan commoncap.CapabilityResponse, error) { +func (c *client) Execute(ctx context.Context, capReq commoncap.CapabilityRequest) (commoncap.CapabilityResponse, error) { + req, err := c.executeRequest(ctx, capReq) + if err != nil { + return commoncap.CapabilityResponse{}, fmt.Errorf("failed to execute request: %w", err) + } + + resp := <-req.ResponseChan() + return resp.CapabilityResponse, resp.Err +} + +func (c *client) executeRequest(ctx context.Context, capReq commoncap.CapabilityRequest) (*request.ClientRequest, error) { c.mutex.Lock() defer c.mutex.Unlock() @@ -145,8 +155,7 @@ func (c *client) Execute(ctx context.Context, capReq commoncap.CapabilityRequest } c.messageIDToCallerRequest[messageID] = req - - return req.ResponseChan(), nil + return req, nil } func (c *client) Receive(ctx context.Context, msg *types.MessageBody) { diff --git a/core/capabilities/remote/target/client_test.go b/core/capabilities/remote/target/client_test.go index 2198636a7a..697cb6e383 100644 --- a/core/capabilities/remote/target/client_test.go +++ b/core/capabilities/remote/target/client_test.go @@ -35,9 +35,8 @@ func Test_Client_DonTopologies(t *testing.T) { }) require.NoError(t, err) - responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { + responseTest := func(t *testing.T, response commoncap.CapabilityResponse, responseError error) { require.NoError(t, responseError) - response := <-responseCh mp, err := response.Value.Unwrap() require.NoError(t, err) assert.Equal(t, "aValue1", mp.(map[string]any)["response"].(string)) @@ -66,9 +65,8 @@ func Test_Client_DonTopologies(t *testing.T) { func Test_Client_TransmissionSchedules(t *testing.T) { ctx := testutils.Context(t) - responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { + responseTest := func(t *testing.T, response commoncap.CapabilityResponse, responseError error) { require.NoError(t, responseError) - response := <-responseCh mp, err := response.Value.Unwrap() require.NoError(t, err) assert.Equal(t, "aValue1", mp.(map[string]any)["response"].(string)) @@ -104,10 +102,8 @@ func Test_Client_TransmissionSchedules(t *testing.T) { func Test_Client_TimesOutIfInsufficientCapabilityPeerResponses(t *testing.T) { ctx := testutils.Context(t) - responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { - require.NoError(t, responseError) - response := <-responseCh - assert.NotNil(t, response.Err) + responseTest := func(t *testing.T, response commoncap.CapabilityResponse, responseError error) { + assert.NotNil(t, responseError) } capability := &TestCapability{} @@ -126,7 +122,7 @@ func Test_Client_TimesOutIfInsufficientCapabilityPeerResponses(t *testing.T) { func testClient(ctx context.Context, t *testing.T, numWorkflowPeers int, workflowNodeResponseTimeout time.Duration, numCapabilityPeers int, capabilityDonF uint8, underlying commoncap.TargetCapability, transmissionSchedule *values.Map, - responseTest func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error)) { + responseTest func(t *testing.T, responseCh commoncap.CapabilityResponse, responseError error)) { lggr := logger.TestLogger(t) capabilityPeers := make([]p2ptypes.PeerID, numCapabilityPeers) @@ -261,8 +257,7 @@ func (t *clientTestServer) Receive(_ context.Context, msg *remotetypes.MessageBo panic(err) } - respCh, responseErr := t.targetCapability.Execute(context.Background(), capabilityRequest) - resp := <-respCh + resp, responseErr := t.targetCapability.Execute(context.Background(), capabilityRequest) for receiver := range t.messageIDToSenders[messageID] { var responseMsg = &remotetypes.MessageBody{ diff --git a/core/capabilities/remote/target/endtoend_test.go b/core/capabilities/remote/target/endtoend_test.go index 9abb6e99d5..3b077bbafe 100644 --- a/core/capabilities/remote/target/endtoend_test.go +++ b/core/capabilities/remote/target/endtoend_test.go @@ -29,10 +29,8 @@ import ( func Test_RemoteTargetCapability_InsufficientCapabilityResponses(t *testing.T) { ctx := testutils.Context(t) - responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { - require.NoError(t, responseError) - response := <-responseCh - assert.NotNil(t, response.Err) + responseTest := func(t *testing.T, responseCh commoncap.CapabilityResponse, responseError error) { + assert.NotNil(t, responseError) } capability := &TestCapability{} @@ -49,10 +47,8 @@ func Test_RemoteTargetCapability_InsufficientCapabilityResponses(t *testing.T) { func Test_RemoteTargetCapability_InsufficientWorkflowRequests(t *testing.T) { ctx := testutils.Context(t) - responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { - require.NoError(t, responseError) - response := <-responseCh - assert.NotNil(t, response.Err) + responseTest := func(t *testing.T, responseCh commoncap.CapabilityResponse, responseError error) { + assert.NotNil(t, responseError) } timeOut := 10 * time.Minute @@ -71,9 +67,8 @@ func Test_RemoteTargetCapability_InsufficientWorkflowRequests(t *testing.T) { func Test_RemoteTargetCapability_TransmissionSchedules(t *testing.T) { ctx := testutils.Context(t) - responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { + responseTest := func(t *testing.T, response commoncap.CapabilityResponse, responseError error) { require.NoError(t, responseError) - response := <-responseCh mp, err := response.Value.Unwrap() require.NoError(t, err) assert.Equal(t, "aValue1", mp.(map[string]any)["response"].(string)) @@ -103,9 +98,8 @@ func Test_RemoteTargetCapability_TransmissionSchedules(t *testing.T) { func Test_RemoteTargetCapability_DonTopologies(t *testing.T) { ctx := testutils.Context(t) - responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { + responseTest := func(t *testing.T, response commoncap.CapabilityResponse, responseError error) { require.NoError(t, responseError) - response := <-responseCh mp, err := response.Value.Unwrap() require.NoError(t, err) assert.Equal(t, "aValue1", mp.(map[string]any)["response"].(string)) @@ -138,10 +132,8 @@ func Test_RemoteTargetCapability_DonTopologies(t *testing.T) { func Test_RemoteTargetCapability_CapabilityError(t *testing.T) { ctx := testutils.Context(t) - responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { - require.NoError(t, responseError) - response := <-responseCh - assert.Equal(t, "failed to execute capability: an error", response.Err.Error()) + responseTest := func(t *testing.T, responseCh commoncap.CapabilityResponse, responseError error) { + assert.Equal(t, "failed to execute capability: an error", responseError.Error()) } capability := &TestErrorCapability{} @@ -158,10 +150,8 @@ func Test_RemoteTargetCapability_CapabilityError(t *testing.T) { func Test_RemoteTargetCapability_RandomCapabilityError(t *testing.T) { ctx := testutils.Context(t) - responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { - require.NoError(t, responseError) - response := <-responseCh - assert.Equal(t, "request expired", response.Err.Error()) + responseTest := func(t *testing.T, response commoncap.CapabilityResponse, responseError error) { + assert.Equal(t, "request expired", responseError.Error()) } capability := &TestRandomErrorCapability{} @@ -177,7 +167,7 @@ func Test_RemoteTargetCapability_RandomCapabilityError(t *testing.T) { func testRemoteTarget(ctx context.Context, t *testing.T, underlying commoncap.TargetCapability, numWorkflowPeers int, workflowDonF uint8, workflowNodeTimeout time.Duration, numCapabilityPeers int, capabilityDonF uint8, capabilityNodeResponseTimeout time.Duration, transmissionSchedule *values.Map, - responseTest func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error)) { + responseTest func(t *testing.T, response commoncap.CapabilityResponse, responseError error)) { lggr := logger.TestLogger(t) capabilityPeers := make([]p2ptypes.PeerID, numCapabilityPeers) @@ -258,7 +248,7 @@ func testRemoteTarget(ctx context.Context, t *testing.T, underlying commoncap.Ta for _, caller := range workflowNodes { go func(caller commoncap.TargetCapability) { defer wg.Done() - responseCh, err := caller.Execute(ctx, + response, err := caller.Execute(ctx, commoncap.CapabilityRequest{ Metadata: commoncap.RequestMetadata{ WorkflowID: workflowID1, @@ -268,7 +258,7 @@ func testRemoteTarget(ctx context.Context, t *testing.T, underlying commoncap.Ta Inputs: executeInputs, }) - responseTest(t, responseCh, err) + responseTest(t, response, err) }(caller) } @@ -404,36 +394,31 @@ type TestCapability struct { abstractTestCapability } -func (t TestCapability) Execute(ctx context.Context, request commoncap.CapabilityRequest) (<-chan commoncap.CapabilityResponse, error) { - ch := make(chan commoncap.CapabilityResponse, 1) - +func (t TestCapability) Execute(ctx context.Context, request commoncap.CapabilityRequest) (commoncap.CapabilityResponse, error) { value := request.Inputs.Underlying["executeValue1"] - response, err := values.NewMap(map[string]any{"response": value}) if err != nil { - return nil, err + return commoncap.CapabilityResponse{}, err } - ch <- commoncap.CapabilityResponse{ + return commoncap.CapabilityResponse{ Value: response, - } - - return ch, nil + }, nil } type TestErrorCapability struct { abstractTestCapability } -func (t TestErrorCapability) Execute(ctx context.Context, request commoncap.CapabilityRequest) (<-chan commoncap.CapabilityResponse, error) { - return nil, errors.New("an error") +func (t TestErrorCapability) Execute(ctx context.Context, request commoncap.CapabilityRequest) (commoncap.CapabilityResponse, error) { + return commoncap.CapabilityResponse{}, errors.New("an error") } type TestRandomErrorCapability struct { abstractTestCapability } -func (t TestRandomErrorCapability) Execute(ctx context.Context, request commoncap.CapabilityRequest) (<-chan commoncap.CapabilityResponse, error) { - return nil, errors.New(uuid.New().String()) +func (t TestRandomErrorCapability) Execute(ctx context.Context, request commoncap.CapabilityRequest) (commoncap.CapabilityResponse, error) { + return commoncap.CapabilityResponse{}, errors.New(uuid.New().String()) } func NewP2PPeerID(t *testing.T) p2ptypes.PeerID { diff --git a/core/capabilities/remote/target/request/client_request.go b/core/capabilities/remote/target/request/client_request.go index c9f76fb25a..1a0d707146 100644 --- a/core/capabilities/remote/target/request/client_request.go +++ b/core/capabilities/remote/target/request/client_request.go @@ -22,9 +22,14 @@ import ( p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) +type asyncCapabilityResponse struct { + capabilities.CapabilityResponse + Err error +} + type ClientRequest struct { cancelFn context.CancelFunc - responseCh chan commoncap.CapabilityResponse + responseCh chan asyncCapabilityResponse createdAt time.Time responseIDCount map[[32]byte]int errorCount map[string]int @@ -101,13 +106,13 @@ func NewClientRequest(ctx context.Context, lggr logger.Logger, req commoncap.Cap responseIDCount: make(map[[32]byte]int), errorCount: make(map[string]int), responseReceived: responseReceived, - responseCh: make(chan commoncap.CapabilityResponse, 1), + responseCh: make(chan asyncCapabilityResponse, 1), wg: wg, lggr: lggr, }, nil } -func (c *ClientRequest) ResponseChan() <-chan commoncap.CapabilityResponse { +func (c *ClientRequest) ResponseChan() <-chan asyncCapabilityResponse { return c.responseCh } @@ -121,11 +126,10 @@ func (c *ClientRequest) Cancel(err error) { c.mux.Lock() defer c.mux.Unlock() if !c.respSent { - c.sendResponse(commoncap.CapabilityResponse{Err: err}) + c.sendResponse(asyncCapabilityResponse{Err: err}) } } -// TODO OnMessage assumes that only one response is received from each peer, if streaming responses need to be supported this will need to be updated func (c *ClientRequest) OnMessage(_ context.Context, msg *types.MessageBody) error { c.mux.Lock() defer c.mux.Unlock() @@ -167,22 +171,22 @@ func (c *ClientRequest) OnMessage(_ context.Context, msg *types.MessageBody) err if c.responseIDCount[responseID] == c.requiredIdenticalResponses { capabilityResponse, err := pb.UnmarshalCapabilityResponse(msg.Payload) if err != nil { - c.sendResponse(commoncap.CapabilityResponse{Err: fmt.Errorf("failed to unmarshal capability response: %w", err)}) + c.sendResponse(asyncCapabilityResponse{Err: fmt.Errorf("failed to unmarshal capability response: %w", err)}) } else { - c.sendResponse(commoncap.CapabilityResponse{Value: capabilityResponse.Value}) + c.sendResponse(asyncCapabilityResponse{CapabilityResponse: commoncap.CapabilityResponse{Value: capabilityResponse.Value}}) } } } else { c.lggr.Warnw("received error response", "error", remote.SanitizeLogString(msg.ErrorMsg)) c.errorCount[msg.ErrorMsg]++ if c.errorCount[msg.ErrorMsg] == c.requiredIdenticalResponses { - c.sendResponse(commoncap.CapabilityResponse{Err: errors.New(msg.ErrorMsg)}) + c.sendResponse(asyncCapabilityResponse{Err: errors.New(msg.ErrorMsg)}) } } return nil } -func (c *ClientRequest) sendResponse(response commoncap.CapabilityResponse) { +func (c *ClientRequest) sendResponse(response asyncCapabilityResponse) { c.responseCh <- response close(c.responseCh) c.respSent = true diff --git a/core/capabilities/remote/target/request/client_request_test.go b/core/capabilities/remote/target/request/client_request_test.go index 7edb2f5e53..095c73e8ad 100644 --- a/core/capabilities/remote/target/request/client_request_test.go +++ b/core/capabilities/remote/target/request/client_request_test.go @@ -84,7 +84,6 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { require.NoError(t, err) capabilityResponse := commoncap.CapabilityResponse{ Value: m, - Err: nil, } rawResponse, err := pb.MarshalCapabilityResponse(capabilityResponse) @@ -117,7 +116,6 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { require.NoError(t, err) capabilityResponse2 := commoncap.CapabilityResponse{ Value: nm, - Err: nil, } rawResponse2, err := pb.MarshalCapabilityResponse(capabilityResponse2) diff --git a/core/capabilities/remote/target/request/server_request.go b/core/capabilities/remote/target/request/server_request.go index e16742a246..d23ba93a44 100644 --- a/core/capabilities/remote/target/request/server_request.go +++ b/core/capabilities/remote/target/request/server_request.go @@ -125,20 +125,19 @@ func (e *ServerRequest) executeRequest(ctx context.Context, payload []byte) erro } e.lggr.Debugw("executing capability", "metadata", capabilityRequest.Metadata) - capResponseCh, err := e.capability.Execute(ctxWithTimeout, capabilityRequest) + capResponse, err := e.capability.Execute(ctxWithTimeout, capabilityRequest) if err != nil { + e.lggr.Debugw("received execution error", "workflowExecutionID", capabilityRequest.Metadata.WorkflowExecutionID, "error", err) return fmt.Errorf("failed to execute capability: %w", err) } - // NOTE working on the assumption that the capability will only ever return one response from its channel - capResponse := <-capResponseCh responsePayload, err := pb.MarshalCapabilityResponse(capResponse) if err != nil { return fmt.Errorf("failed to marshal capability response: %w", err) } - e.lggr.Debugw("received execution results", "workflowExecutionID", capabilityRequest.Metadata.WorkflowExecutionID, "error", capResponse.Err) + e.lggr.Debugw("received execution results", "workflowExecutionID", capabilityRequest.Metadata.WorkflowExecutionID) e.setResult(responsePayload) return nil } diff --git a/core/capabilities/remote/target/request/server_request_test.go b/core/capabilities/remote/target/request/server_request_test.go index a35725d6b1..619142d0a6 100644 --- a/core/capabilities/remote/target/request/server_request_test.go +++ b/core/capabilities/remote/target/request/server_request_test.go @@ -240,28 +240,25 @@ type TestCapability struct { abstractTestCapability } -func (t TestCapability) Execute(ctx context.Context, request commoncap.CapabilityRequest) (<-chan commoncap.CapabilityResponse, error) { - ch := make(chan commoncap.CapabilityResponse, 1) - +func (t TestCapability) Execute(ctx context.Context, request commoncap.CapabilityRequest) (commoncap.CapabilityResponse, error) { value := request.Inputs.Underlying["executeValue1"] response, err := values.NewMap(map[string]any{"response": value}) if err != nil { - return nil, err - } - ch <- commoncap.CapabilityResponse{ - Value: response, + return commoncap.CapabilityResponse{}, err } - return ch, nil + return commoncap.CapabilityResponse{ + Value: response, + }, nil } type TestErrorCapability struct { abstractTestCapability } -func (t TestErrorCapability) Execute(ctx context.Context, request commoncap.CapabilityRequest) (<-chan commoncap.CapabilityResponse, error) { - return nil, errors.New("an error") +func (t TestErrorCapability) Execute(ctx context.Context, request commoncap.CapabilityRequest) (commoncap.CapabilityResponse, error) { + return commoncap.CapabilityResponse{}, errors.New("an error") } func NewP2PPeerID(t *testing.T) p2ptypes.PeerID { diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index eb3a390de4..a3ebe77c97 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -170,16 +170,7 @@ func evaluate(rawRequest capabilities.CapabilityRequest) (r Request, err error) return r, nil } -func success() <-chan capabilities.CapabilityResponse { - callback := make(chan capabilities.CapabilityResponse) - go func() { - callback <- capabilities.CapabilityResponse{} - close(callback) - }() - return callback -} - -func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) { +func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { // Bind to the contract address on the write path. // Bind() requires a connection to the node's RPCs and // cannot be run during initialization. @@ -190,7 +181,7 @@ func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.Cap Name: "forwarder", }}) if err != nil { - return nil, err + return capabilities.CapabilityResponse{}, err } cap.bound = true } @@ -199,12 +190,12 @@ func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.Cap request, err := evaluate(rawRequest) if err != nil { - return nil, err + return capabilities.CapabilityResponse{}, err } rawExecutionID, err := hex.DecodeString(request.Metadata.WorkflowExecutionID) if err != nil { - return nil, err + return capabilities.CapabilityResponse{}, err } // Check whether value was already transmitted on chain @@ -219,7 +210,7 @@ func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.Cap } var transmissionInfo TransmissionInfo if err = cap.cr.GetLatestValue(ctx, "forwarder", "getTransmissionInfo", primitives.Unconfirmed, queryInputs, &transmissionInfo); err != nil { - return nil, fmt.Errorf("failed to getTransmissionInfo latest value: %w", err) + return capabilities.CapabilityResponse{}, fmt.Errorf("failed to getTransmissionInfo latest value: %w", err) } switch { @@ -227,10 +218,10 @@ func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.Cap cap.lggr.Infow("non-empty report - transmission not attempted - attempting to push to txmgr", "request", request, "reportLen", len(request.Inputs.SignedReport.Report), "reportContextLen", len(request.Inputs.SignedReport.Context), "nSignatures", len(request.Inputs.SignedReport.Signatures), "executionID", request.Metadata.WorkflowExecutionID) case transmissionInfo.State == 1: // SUCCEEDED cap.lggr.Infow("returning without a transmission attempt - report already onchain ", "executionID", request.Metadata.WorkflowExecutionID) - return success(), nil + return capabilities.CapabilityResponse{}, nil case transmissionInfo.State == 2: // INVALID_RECEIVER cap.lggr.Infow("returning without a transmission attempt - transmission already attempted, receiver was marked as invalid", "executionID", request.Metadata.WorkflowExecutionID) - return success(), nil + return capabilities.CapabilityResponse{}, nil case transmissionInfo.State == 3: // FAILED receiverGasMinimum := cap.receiverGasMinimum if request.Config.GasLimit != nil { @@ -238,17 +229,17 @@ func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.Cap } if transmissionInfo.GasLimit.Uint64() > receiverGasMinimum { cap.lggr.Infow("returning without a transmission attempt - transmission already attempted and failed, sufficient gas was provided", "executionID", request.Metadata.WorkflowExecutionID, "receiverGasMinimum", receiverGasMinimum, "transmissionGasLimit", transmissionInfo.GasLimit) - return success(), nil + return capabilities.CapabilityResponse{}, nil } else { cap.lggr.Infow("non-empty report - retrying a failed transmission - attempting to push to txmgr", "request", request, "reportLen", len(request.Inputs.SignedReport.Report), "reportContextLen", len(request.Inputs.SignedReport.Context), "nSignatures", len(request.Inputs.SignedReport.Signatures), "executionID", request.Metadata.WorkflowExecutionID, "receiverGasMinimum", receiverGasMinimum, "transmissionGasLimit", transmissionInfo.GasLimit) } default: - return nil, fmt.Errorf("unexpected transmission state: %v", transmissionInfo.State) + return capabilities.CapabilityResponse{}, fmt.Errorf("unexpected transmission state: %v", transmissionInfo.State) } txID, err := uuid.NewUUID() // NOTE: CW expects us to generate an ID, rather than return one if err != nil { - return nil, err + return capabilities.CapabilityResponse{}, err } // Note: The codec that ChainWriter uses to encode the parameters for the contract ABI cannot handle @@ -284,15 +275,15 @@ func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.Cap if commontypes.ErrSettingTransactionGasLimitNotSupported.Is(err) { meta.GasLimit = nil if err := cap.cw.SubmitTransaction(ctx, "forwarder", "report", req, txID.String(), cap.forwarderAddress, &meta, value); err != nil { - return nil, fmt.Errorf("failed to submit transaction: %w", err) + return capabilities.CapabilityResponse{}, fmt.Errorf("failed to submit transaction: %w", err) } } else { - return nil, fmt.Errorf("failed to submit transaction: %w", err) + return capabilities.CapabilityResponse{}, fmt.Errorf("failed to submit transaction: %w", err) } } cap.lggr.Debugw("Transaction submitted", "request", request, "transaction", txID) - return success(), nil + return capabilities.CapabilityResponse{}, nil } func (cap *WriteTarget) RegisterToWorkflow(ctx context.Context, request capabilities.RegisterToWorkflowRequest) error { diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go index 7f589e335d..aa0717aa0e 100644 --- a/core/capabilities/targets/write_target_test.go +++ b/core/capabilities/targets/write_target_test.go @@ -97,9 +97,8 @@ func TestWriteTarget(t *testing.T) { Inputs: validInputs, } - ch, err2 := writeTarget.Execute(ctx, req) + response, err2 := writeTarget.Execute(ctx, req) require.NoError(t, err2) - response := <-ch require.NotNil(t, response) }) diff --git a/core/capabilities/transmission/local_target_capability.go b/core/capabilities/transmission/local_target_capability.go index 1240d3a0e7..637aea4523 100644 --- a/core/capabilities/transmission/local_target_capability.go +++ b/core/capabilities/transmission/local_target_capability.go @@ -27,7 +27,7 @@ func NewLocalTargetCapability(lggr logger.Logger, capabilityID string, localDON } } -func (l *LocalTargetCapability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) { +func (l *LocalTargetCapability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { if l.localNode.PeerID == nil || l.localNode.WorkflowDON.ID == 0 { l.lggr.Debugf("empty DON info, executing immediately") return l.TargetCapability.Execute(ctx, req) @@ -40,17 +40,17 @@ func (l *LocalTargetCapability) Execute(ctx context.Context, req capabilities.Ca peerIDToTransmissionDelay, err := GetPeerIDToTransmissionDelay(l.localNode.WorkflowDON.Members, req) if err != nil { - return nil, fmt.Errorf("capability id: %s failed to get peer ID to transmission delay map: %w", l.capabilityID, err) + return capabilities.CapabilityResponse{}, fmt.Errorf("capability id: %s failed to get peer ID to transmission delay map: %w", l.capabilityID, err) } delay, existsForPeerID := peerIDToTransmissionDelay[*l.localNode.PeerID] if !existsForPeerID { - return nil, nil + return capabilities.CapabilityResponse{}, nil } select { case <-ctx.Done(): - return nil, ctx.Err() + return capabilities.CapabilityResponse{}, ctx.Err() case <-time.After(delay): return l.TargetCapability.Execute(ctx, req) } diff --git a/core/capabilities/transmission/local_target_capability_test.go b/core/capabilities/transmission/local_target_capability_test.go index cdca854986..67f22753bd 100644 --- a/core/capabilities/transmission/local_target_capability_test.go +++ b/core/capabilities/transmission/local_target_capability_test.go @@ -162,7 +162,7 @@ func randKey() [32]byte { type mockCapability struct { capabilities.CapabilityInfo - capabilities.CallbackExecutable + capabilities.Executable response chan capabilities.CapabilityResponse transform func(capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) } @@ -175,18 +175,14 @@ func newMockCapability(info capabilities.CapabilityInfo, transform func(capabili } } -func (m *mockCapability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) { +func (m *mockCapability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { cr, err := m.transform(req) if err != nil { - return nil, err + return capabilities.CapabilityResponse{}, err } - ch := make(chan capabilities.CapabilityResponse, 10) - m.response <- cr - ch <- cr - close(ch) - return ch, nil + return cr, nil } func (m *mockCapability) RegisterToWorkflow(ctx context.Context, request capabilities.RegisterToWorkflowRequest) error { diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 55c8a9553c..af64d0a0b3 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 79e9f53d15..a536f2bdd9 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1190,8 +1190,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b h1:/PQDTP/ETmEXCv3qokVs5JqMcHDFP8TWdkcQAzs/nQg= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d h1:VVtgseTBEJN0/NcewMcka1qwslKhY1HPXs4EEpZa7ek= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f h1:a6zEDLYgTQ4G+9PgLX8G2bF40BdsOY5//5i+whYwLlQ= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= diff --git a/core/services/relay/evm/write_target_test.go b/core/services/relay/evm/write_target_test.go index e8a6afee06..795b23f80e 100644 --- a/core/services/relay/evm/write_target_test.go +++ b/core/services/relay/evm/write_target_test.go @@ -209,11 +209,8 @@ func TestEvmWrite(t *testing.T) { Inputs: validInputs, } - ch, err := capability.Execute(ctx, req) + _, err = capability.Execute(ctx, req) require.NoError(t, err) - - response := <-ch - require.Nil(t, response.Err) }) t.Run("fails with invalid config", func(t *testing.T) { diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index f4ab2b82bd..88fb198d15 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -182,7 +182,7 @@ func (e *Engine) initializeCapability(ctx context.Context, step *step) error { // We configure actions, consensus and targets here, and // they all satisfy the `CallbackCapability` interface - cc, ok := cp.(capabilities.CallbackCapability) + cc, ok := cp.(capabilities.ExecutableCapability) if !ok { return newCPErr("capability does not satisfy CallbackCapability") } @@ -762,12 +762,12 @@ func (e *Engine) executeStep(ctx context.Context, msg stepRequest) (*values.Map, }, } - output, err := executeSyncAndUnwrapSingleValue(ctx, step.capability, tr) + output, err := step.capability.Execute(ctx, tr) if err != nil { return inputsMap, nil, err } - return inputsMap, output, err + return inputsMap, output.Value, err } func (e *Engine) deregisterTrigger(ctx context.Context, t *triggerCapability, triggerIdx int) error { @@ -960,24 +960,6 @@ func NewEngine(cfg Config) (engine *Engine, err error) { return engine, nil } -// ExecuteSyncAndUnwrapSingleValue is a convenience method that executes a capability synchronously and unwraps the -// result if it is a single value otherwise returns the list. -func executeSyncAndUnwrapSingleValue(ctx context.Context, cap capabilities.CallbackCapability, req capabilities.CapabilityRequest) (values.Value, error) { - l, err := capabilities.ExecuteSync(ctx, cap, req) - if err != nil { - return nil, err - } - - // `ExecuteSync` returns a `values.List` even if there was - // just one return value. If that is the case, let's unwrap the - // single value to make it easier to use in -- for example -- variable interpolation. - if len(l.Underlying) > 1 { - return l, nil - } - - return l.Underlying[0], nil -} - // Logging keys const ( cIDKey = "capabilityID" diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index 5cb24b8aea..e7f83504e9 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -186,7 +186,7 @@ func getExecutionId(t *testing.T, eng *Engine, hooks *testHooks) string { type mockCapability struct { capabilities.CapabilityInfo - capabilities.CallbackExecutable + capabilities.Executable response chan capabilities.CapabilityResponse transform func(capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) } @@ -199,18 +199,14 @@ func newMockCapability(info capabilities.CapabilityInfo, transform func(capabili } } -func (m *mockCapability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) { +func (m *mockCapability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { cr, err := m.transform(req) if err != nil { - return nil, err + return capabilities.CapabilityResponse{}, err } - ch := make(chan capabilities.CapabilityResponse, 10) - m.response <- cr - ch <- cr - close(ch) - return ch, nil + return cr, nil } func (m *mockCapability) RegisterToWorkflow(ctx context.Context, request capabilities.RegisterToWorkflowRequest) error { @@ -276,11 +272,9 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { eid := getExecutionId(t, eng, testHooks) resp1 := <-target1.response - assert.NoError(t, resp1.Err) assert.Equal(t, cr.Event.Outputs, resp1.Value) resp2 := <-target2.response - assert.NoError(t, resp2.Err) assert.Equal(t, cr.Event.Outputs, resp2.Value) state, err := eng.executionStates.Get(ctx, eid) @@ -391,10 +385,9 @@ func mockConsensusWithEarlyTermination() *mockCapability { "an ocr3 consensus capability", ), func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { - return capabilities.CapabilityResponse{ + return capabilities.CapabilityResponse{}, // copy error object to make sure message comparison works as expected - Err: errors.New(capabilities.ErrStopExecution.Error()), - }, nil + errors.New(capabilities.ErrStopExecution.Error()) }, ) } diff --git a/core/services/workflows/models.go b/core/services/workflows/models.go index 1ff77225c4..461569e8c6 100644 --- a/core/services/workflows/models.go +++ b/core/services/workflows/models.go @@ -79,7 +79,7 @@ func (w *workflow) dependents(start string) ([]*step, error) { // step wraps a Vertex with additional context for execution that is mutated by the engine type step struct { workflows.Vertex - capability capabilities.CallbackCapability + capability capabilities.ExecutableCapability info capabilities.CapabilityInfo config *values.Map } diff --git a/go.mod b/go.mod index 83e64fc534..9c22104b60 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 diff --git a/go.sum b/go.sum index cae2df4414..41581f6ede 100644 --- a/go.sum +++ b/go.sum @@ -1147,8 +1147,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b h1:/PQDTP/ETmEXCv3qokVs5JqMcHDFP8TWdkcQAzs/nQg= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d h1:VVtgseTBEJN0/NcewMcka1qwslKhY1HPXs4EEpZa7ek= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f h1:a6zEDLYgTQ4G+9PgLX8G2bF40BdsOY5//5i+whYwLlQ= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 1651041794..8b06e6aca6 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -37,7 +37,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 1d6a1e8ced..095d822fca 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1425,8 +1425,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b h1:/PQDTP/ETmEXCv3qokVs5JqMcHDFP8TWdkcQAzs/nQg= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d h1:VVtgseTBEJN0/NcewMcka1qwslKhY1HPXs4EEpZa7ek= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f h1:a6zEDLYgTQ4G+9PgLX8G2bF40BdsOY5//5i+whYwLlQ= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index edf2a9a8d4..cfd0c02b66 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index eca3c5ddcc..507bc79df4 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1395,8 +1395,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b h1:/PQDTP/ETmEXCv3qokVs5JqMcHDFP8TWdkcQAzs/nQg= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d h1:VVtgseTBEJN0/NcewMcka1qwslKhY1HPXs4EEpZa7ek= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240905145927-2ff0f9628f4d/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f h1:a6zEDLYgTQ4G+9PgLX8G2bF40BdsOY5//5i+whYwLlQ= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= From 8f46d81e83e4db28dcb8889486eab79f4d20430a Mon Sep 17 00:00:00 2001 From: momentmaker Date: Mon, 9 Sep 2024 10:11:03 -0500 Subject: [PATCH 306/432] update README with section about cosign verify (#14338) * update README with section about cosign verify * update cosign installation instruction --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 58e6516f4c..e7c21c1e09 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,21 @@ External adapters are what make Chainlink easily extensible, providing simple in For more information on creating and using external adapters, please see our [external adapters page](https://docs.chain.link/docs/external-adapters). +## Verify Official Chainlink Releases + +We use `cosign` with OIDC keyless signing during the [Build, Sign and Publish Chainlink](https://github.com/smartcontractkit/chainlink/actions/workflows/build-publish.yml) workflow. + +It is encourage for any node operator building from the official Chainlink docker image to verify the tagged release version was did indeed built from this workflow. + +You will need `cosign` in order to do this verification. [Follow the instruction here to install cosign](https://docs.sigstore.dev/system_config/installation/). + +```bash +# tag is the tagged release version - ie. v2.16.0 +cosign verify public.ecr.aws/chainlink/chainlink:${tag} \ + --certificate-oidc-issuer https://token.actions.githubusercontent.com \ + --certificate-identity "https://github.com/smartcontractkit/chainlink/.github/workflows/build-publish.yml@refs/tags/${tag}" +``` + ## Development ### Running tests From cd8be702ffdaef0a9176da977411ab237e544da5 Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Mon, 9 Sep 2024 08:21:57 -0700 Subject: [PATCH 307/432] [CAPPL-20] Support per-method handlers in GatewayConnector (#14367) Making GatewayConnector compatible with the new design, where each capability is able to add its own handler independently. --- .changeset/thick-jobs-kneel.md | 5 ++ .../gateway/connector/run_connector.go | 8 +++- core/services/gateway/connector/connector.go | 40 ++++++++++++---- .../gateway/connector/connector_test.go | 35 +++++++++----- .../connector/mocks/gateway_connector.go | 48 +++++++++++++++++++ .../gateway_integration_test.go | 4 +- .../services/ocr2/plugins/functions/plugin.go | 25 ++++++---- .../ocr2/plugins/functions/plugin_test.go | 4 +- 8 files changed, 134 insertions(+), 35 deletions(-) create mode 100644 .changeset/thick-jobs-kneel.md diff --git a/.changeset/thick-jobs-kneel.md b/.changeset/thick-jobs-kneel.md new file mode 100644 index 0000000000..8bcda7faf5 --- /dev/null +++ b/.changeset/thick-jobs-kneel.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Support per-method handlers in GatewayConnector diff --git a/core/scripts/gateway/connector/run_connector.go b/core/scripts/gateway/connector/run_connector.go index 8d74bb88ae..2a2445c1d9 100644 --- a/core/scripts/gateway/connector/run_connector.go +++ b/core/scripts/gateway/connector/run_connector.go @@ -69,7 +69,13 @@ func main() { sampleKey, _ := crypto.HexToECDSA("cd47d3fafdbd652dd2b66c6104fa79b372c13cb01f4a4fbfc36107cce913ac1d") lggr, _ := logger.NewLogger() client := &client{privateKey: sampleKey, lggr: lggr} - connector, _ := connector.NewGatewayConnector(&cfg, client, client, clockwork.NewRealClock(), lggr) + // client acts as a signer here + connector, _ := connector.NewGatewayConnector(&cfg, client, clockwork.NewRealClock(), lggr) + err = connector.AddHandler([]string{"test_method"}, client) + if err != nil { + fmt.Println("error adding handler:", err) + return + } client.connector = connector ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt) diff --git a/core/services/gateway/connector/connector.go b/core/services/gateway/connector/connector.go index 64ae46e620..82ff1e9e13 100644 --- a/core/services/gateway/connector/connector.go +++ b/core/services/gateway/connector/connector.go @@ -26,6 +26,7 @@ type GatewayConnector interface { job.ServiceCtx network.ConnectionInitiator + AddHandler(methods []string, handler GatewayConnectorHandler) error SendToGateway(ctx context.Context, gatewayId string, msg *api.Message) error } @@ -51,7 +52,7 @@ type gatewayConnector struct { clock clockwork.Clock nodeAddress []byte signer Signer - handler GatewayConnectorHandler + handlers map[string]GatewayConnectorHandler gateways map[string]*gatewayState urlToId map[string]string closeWait sync.WaitGroup @@ -76,8 +77,8 @@ type gatewayState struct { wsClient network.WebSocketClient } -func NewGatewayConnector(config *ConnectorConfig, signer Signer, handler GatewayConnectorHandler, clock clockwork.Clock, lggr logger.Logger) (GatewayConnector, error) { - if config == nil || signer == nil || handler == nil || clock == nil || lggr == nil { +func NewGatewayConnector(config *ConnectorConfig, signer Signer, clock clockwork.Clock, lggr logger.Logger) (GatewayConnector, error) { + if config == nil || signer == nil || clock == nil || lggr == nil { return nil, errors.New("nil dependency") } if len(config.DonId) == 0 || len(config.DonId) > network.HandshakeDonIdLen { @@ -93,7 +94,7 @@ func NewGatewayConnector(config *ConnectorConfig, signer Signer, handler Gateway clock: clock, nodeAddress: addressBytes, signer: signer, - handler: handler, + handlers: make(map[string]GatewayConnectorHandler), shutdownCh: make(chan struct{}), lggr: lggr.Named("GatewayConnector"), } @@ -125,6 +126,22 @@ func NewGatewayConnector(config *ConnectorConfig, signer Signer, handler Gateway return connector, nil } +func (c *gatewayConnector) AddHandler(methods []string, handler GatewayConnectorHandler) error { + if handler == nil { + return errors.New("cannot add a nil handler") + } + for _, method := range methods { + if _, exists := c.handlers[method]; exists { + return fmt.Errorf("handler for method %s already exists", method) + } + } + // add all or nothing + for _, method := range methods { + c.handlers[method] = handler + } + return nil +} + func (c *gatewayConnector) SendToGateway(ctx context.Context, gatewayId string, msg *api.Message) error { data, err := c.codec.EncodeResponse(msg) if err != nil { @@ -159,7 +176,12 @@ func (c *gatewayConnector) readLoop(gatewayState *gatewayState) { c.lggr.Errorw("failed to validate message signature", "id", gatewayState.config.Id, "err", err) break } - c.handler.HandleGatewayMessage(ctx, gatewayState.config.Id, msg) + handler, exists := c.handlers[msg.Body.Method] + if !exists { + c.lggr.Errorw("no handler for method", "id", gatewayState.config.Id, "method", msg.Body.Method) + break + } + handler.HandleGatewayMessage(ctx, gatewayState.config.Id, msg) } } } @@ -194,9 +216,6 @@ func (c *gatewayConnector) reconnectLoop(gatewayState *gatewayState) { func (c *gatewayConnector) Start(ctx context.Context) error { return c.StartOnce("GatewayConnector", func() error { c.lggr.Info("starting gateway connector") - if err := c.handler.Start(ctx); err != nil { - return err - } for _, gatewayState := range c.gateways { gatewayState := gatewayState if err := gatewayState.conn.Start(ctx); err != nil { @@ -214,11 +233,12 @@ func (c *gatewayConnector) Close() error { return c.StopOnce("GatewayConnector", func() (err error) { c.lggr.Info("closing gateway connector") close(c.shutdownCh) + var errs error for _, gatewayState := range c.gateways { - gatewayState.conn.Close() + errs = errors.Join(errs, gatewayState.conn.Close()) } c.closeWait.Wait() - return c.handler.Close() + return errs }) } diff --git a/core/services/gateway/connector/connector_test.go b/core/services/gateway/connector/connector_test.go index 3dd782c626..16520a42f4 100644 --- a/core/services/gateway/connector/connector_test.go +++ b/core/services/gateway/connector/connector_test.go @@ -18,7 +18,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/gateway/network" ) -const defaultConfig = ` +const ( + defaultConfig = ` NodeAddress = "0x68902d681c28119f9b2531473a417088bf008e59" DonId = "example_don" AuthMinChallengeLen = 10 @@ -32,6 +33,9 @@ URL = "ws://localhost:8081/node" Id = "another_one" URL = "wss://example.com:8090/node_endpoint" ` + testMethod1 = "test_method_1" + testMethod2 = "test_method_2" +) func parseTOMLConfig(t *testing.T, tomlConfig string) *connector.ConnectorConfig { var cfg connector.ConnectorConfig @@ -40,12 +44,13 @@ func parseTOMLConfig(t *testing.T, tomlConfig string) *connector.ConnectorConfig return &cfg } -func newTestConnector(t *testing.T, config *connector.ConnectorConfig, now time.Time) (connector.GatewayConnector, *mocks.Signer, *mocks.GatewayConnectorHandler) { +func newTestConnector(t *testing.T, config *connector.ConnectorConfig) (connector.GatewayConnector, *mocks.Signer, *mocks.GatewayConnectorHandler) { signer := mocks.NewSigner(t) handler := mocks.NewGatewayConnectorHandler(t) clock := clockwork.NewFakeClock() - connector, err := connector.NewGatewayConnector(config, signer, handler, clock, logger.TestLogger(t)) + connector, err := connector.NewGatewayConnector(config, signer, clock, logger.TestLogger(t)) require.NoError(t, err) + require.NoError(t, connector.AddHandler([]string{testMethod1}, handler)) return connector, signer, handler } @@ -61,7 +66,7 @@ Id = "example_gateway" URL = "ws://localhost:8081/node" `) - newTestConnector(t, tomlConfig, time.Now()) + newTestConnector(t, tomlConfig) } func TestGatewayConnector_NewGatewayConnector_InvalidConfig(t *testing.T) { @@ -103,12 +108,11 @@ URL = "ws://localhost:8081/node" } signer := mocks.NewSigner(t) - handler := mocks.NewGatewayConnectorHandler(t) clock := clockwork.NewFakeClock() for name, config := range invalidCases { config := config t.Run(name, func(t *testing.T) { - _, err := connector.NewGatewayConnector(parseTOMLConfig(t, config), signer, handler, clock, logger.TestLogger(t)) + _, err := connector.NewGatewayConnector(parseTOMLConfig(t, config), signer, clock, logger.TestLogger(t)) require.Error(t, err) }) } @@ -117,9 +121,7 @@ URL = "ws://localhost:8081/node" func TestGatewayConnector_CleanStartAndClose(t *testing.T) { t.Parallel() - connector, signer, handler := newTestConnector(t, parseTOMLConfig(t, defaultConfig), time.Now()) - handler.On("Start", mock.Anything).Return(nil) - handler.On("Close").Return(nil) + connector, signer, _ := newTestConnector(t, parseTOMLConfig(t, defaultConfig)) signer.On("Sign", mock.Anything).Return(nil, errors.New("cannot sign")) servicetest.Run(t, connector) } @@ -127,7 +129,7 @@ func TestGatewayConnector_CleanStartAndClose(t *testing.T) { func TestGatewayConnector_NewAuthHeader_SignerError(t *testing.T) { t.Parallel() - connector, signer, _ := newTestConnector(t, parseTOMLConfig(t, defaultConfig), time.Now()) + connector, signer, _ := newTestConnector(t, parseTOMLConfig(t, defaultConfig)) signer.On("Sign", mock.Anything).Return(nil, errors.New("cannot sign")) url, err := url.Parse("ws://localhost:8081/node") @@ -141,7 +143,7 @@ func TestGatewayConnector_NewAuthHeader_Success(t *testing.T) { testSignature := make([]byte, network.HandshakeSignatureLen) testSignature[1] = 0xfa - connector, signer, _ := newTestConnector(t, parseTOMLConfig(t, defaultConfig), time.Now()) + connector, signer, _ := newTestConnector(t, parseTOMLConfig(t, defaultConfig)) signer.On("Sign", mock.Anything).Return(testSignature, nil) url, err := url.Parse("ws://localhost:8081/node") require.NoError(t, err) @@ -157,7 +159,7 @@ func TestGatewayConnector_ChallengeResponse(t *testing.T) { testSignature := make([]byte, network.HandshakeSignatureLen) testSignature[1] = 0xfa now := time.Now() - connector, signer, _ := newTestConnector(t, parseTOMLConfig(t, defaultConfig), now) + connector, signer, _ := newTestConnector(t, parseTOMLConfig(t, defaultConfig)) signer.On("Sign", mock.Anything).Return(testSignature, nil) url, err := url.Parse("ws://localhost:8081/node") require.NoError(t, err) @@ -191,3 +193,12 @@ func TestGatewayConnector_ChallengeResponse(t *testing.T) { _, err = connector.ChallengeResponse(url, network.PackChallenge(&badChallenge)) require.Equal(t, network.ErrAuthInvalidGateway, err) } + +func TestGatewayConnector_AddHandler(t *testing.T) { + t.Parallel() + + connector, _, _ := newTestConnector(t, parseTOMLConfig(t, defaultConfig)) + // testMethod1 already exists + require.Error(t, connector.AddHandler([]string{testMethod1}, mocks.NewGatewayConnectorHandler(t))) + require.NoError(t, connector.AddHandler([]string{testMethod2}, mocks.NewGatewayConnectorHandler(t))) +} diff --git a/core/services/gateway/connector/mocks/gateway_connector.go b/core/services/gateway/connector/mocks/gateway_connector.go index 931aac8c77..76e3ff5c86 100644 --- a/core/services/gateway/connector/mocks/gateway_connector.go +++ b/core/services/gateway/connector/mocks/gateway_connector.go @@ -4,6 +4,7 @@ package mocks import ( api "github.com/smartcontractkit/chainlink/v2/core/services/gateway/api" + connector "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" context "context" @@ -25,6 +26,53 @@ func (_m *GatewayConnector) EXPECT() *GatewayConnector_Expecter { return &GatewayConnector_Expecter{mock: &_m.Mock} } +// AddHandler provides a mock function with given fields: methods, handler +func (_m *GatewayConnector) AddHandler(methods []string, handler connector.GatewayConnectorHandler) error { + ret := _m.Called(methods, handler) + + if len(ret) == 0 { + panic("no return value specified for AddHandler") + } + + var r0 error + if rf, ok := ret.Get(0).(func([]string, connector.GatewayConnectorHandler) error); ok { + r0 = rf(methods, handler) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GatewayConnector_AddHandler_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddHandler' +type GatewayConnector_AddHandler_Call struct { + *mock.Call +} + +// AddHandler is a helper method to define mock.On call +// - methods []string +// - handler connector.GatewayConnectorHandler +func (_e *GatewayConnector_Expecter) AddHandler(methods interface{}, handler interface{}) *GatewayConnector_AddHandler_Call { + return &GatewayConnector_AddHandler_Call{Call: _e.mock.On("AddHandler", methods, handler)} +} + +func (_c *GatewayConnector_AddHandler_Call) Run(run func(methods []string, handler connector.GatewayConnectorHandler)) *GatewayConnector_AddHandler_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]string), args[1].(connector.GatewayConnectorHandler)) + }) + return _c +} + +func (_c *GatewayConnector_AddHandler_Call) Return(_a0 error) *GatewayConnector_AddHandler_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GatewayConnector_AddHandler_Call) RunAndReturn(run func([]string, connector.GatewayConnectorHandler) error) *GatewayConnector_AddHandler_Call { + _c.Call.Return(run) + return _c +} + // ChallengeResponse provides a mock function with given fields: _a0, challenge func (_m *GatewayConnector) ChallengeResponse(_a0 *url.URL, challenge []byte) ([]byte, error) { ret := _m.Called(_a0, challenge) diff --git a/core/services/gateway/integration_tests/gateway_integration_test.go b/core/services/gateway/integration_tests/gateway_integration_test.go index 38a6b6ebbc..59418819b6 100644 --- a/core/services/gateway/integration_tests/gateway_integration_test.go +++ b/core/services/gateway/integration_tests/gateway_integration_test.go @@ -152,8 +152,10 @@ func TestIntegration_Gateway_NoFullNodes_BasicConnectionAndMessage(t *testing.T) // Launch Connector client := &client{privateKey: nodeKeys.PrivateKey} - connector, err := connector.NewGatewayConnector(parseConnectorConfig(t, nodeConfigTemplate, nodeKeys.Address, nodeUrl), client, client, clockwork.NewRealClock(), lggr) + // client acts as a signer here + connector, err := connector.NewGatewayConnector(parseConnectorConfig(t, nodeConfigTemplate, nodeKeys.Address, nodeUrl), client, clockwork.NewRealClock(), lggr) require.NoError(t, err) + require.NoError(t, connector.AddHandler([]string{"test"}, client)) client.connector = connector servicetest.Run(t, connector) diff --git a/core/services/ocr2/plugins/functions/plugin.go b/core/services/ocr2/plugins/functions/plugin.go index d6ffa1a3f0..b36d3e37db 100644 --- a/core/services/ocr2/plugins/functions/plugin.go +++ b/core/services/ocr2/plugins/functions/plugin.go @@ -23,6 +23,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/functions" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" hc "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" + hf "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" gwAllowlist "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist" gwSubscriptions "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -174,11 +175,12 @@ func NewFunctionsServices(ctx context.Context, functionsOracleArgs, thresholdOra return nil, errors.Wrap(err, "failed to create a OnchainSubscriptions") } connectorLogger := conf.Logger.Named("GatewayConnector").With("jobName", conf.Job.PipelineSpec.JobName) - connector, err2 := NewConnector(ctx, &pluginConfig, conf.EthKeystore, conf.Chain.ID(), s4Storage, allowlist, rateLimiter, subscriptions, functionsListener, offchainTransmitter, connectorLogger) + connector, handler, err2 := NewConnector(ctx, &pluginConfig, conf.EthKeystore, conf.Chain.ID(), s4Storage, allowlist, rateLimiter, subscriptions, functionsListener, offchainTransmitter, connectorLogger) if err2 != nil { return nil, errors.Wrap(err, "failed to create a GatewayConnector") } allServices = append(allServices, connector) + allServices = append(allServices, handler) } else { listenerLogger.Warn("Insufficient config, GatewayConnector will not be enabled") } @@ -201,29 +203,34 @@ func NewFunctionsServices(ctx context.Context, functionsOracleArgs, thresholdOra return allServices, nil } -func NewConnector(ctx context.Context, pluginConfig *config.PluginConfig, ethKeystore keystore.Eth, chainID *big.Int, s4Storage s4.Storage, allowlist gwAllowlist.OnchainAllowlist, rateLimiter *hc.RateLimiter, subscriptions gwSubscriptions.OnchainSubscriptions, listener functions.FunctionsListener, offchainTransmitter functions.OffchainTransmitter, lggr logger.Logger) (connector.GatewayConnector, error) { +func NewConnector(ctx context.Context, pluginConfig *config.PluginConfig, ethKeystore keystore.Eth, chainID *big.Int, s4Storage s4.Storage, allowlist gwAllowlist.OnchainAllowlist, rateLimiter *hc.RateLimiter, subscriptions gwSubscriptions.OnchainSubscriptions, listener functions.FunctionsListener, offchainTransmitter functions.OffchainTransmitter, lggr logger.Logger) (connector.GatewayConnector, connector.GatewayConnectorHandler, error) { enabledKeys, err := ethKeystore.EnabledKeysForChain(ctx, chainID) if err != nil { - return nil, err + return nil, nil, err } configuredNodeAddress := common.HexToAddress(pluginConfig.GatewayConnectorConfig.NodeAddress) idx := slices.IndexFunc(enabledKeys, func(key ethkey.KeyV2) bool { return key.Address == configuredNodeAddress }) if idx == -1 { - return nil, errors.New("key for configured node address not found") + return nil, nil, errors.New("key for configured node address not found") } signerKey := enabledKeys[idx].ToEcdsaPrivKey() if enabledKeys[idx].ID() != pluginConfig.GatewayConnectorConfig.NodeAddress { - return nil, errors.New("node address mismatch") + return nil, nil, errors.New("node address mismatch") } handler, err := functions.NewFunctionsConnectorHandler(pluginConfig, signerKey, s4Storage, allowlist, rateLimiter, subscriptions, listener, offchainTransmitter, lggr) if err != nil { - return nil, err + return nil, nil, err } - connector, err := connector.NewGatewayConnector(pluginConfig.GatewayConnectorConfig, handler, handler, clockwork.NewRealClock(), lggr) + // handler acts as a signer here + connector, err := connector.NewGatewayConnector(pluginConfig.GatewayConnectorConfig, handler, clockwork.NewRealClock(), lggr) if err != nil { - return nil, err + return nil, nil, err + } + err = connector.AddHandler([]string{hf.MethodSecretsSet, hf.MethodSecretsList, hf.MethodHeartbeat}, handler) + if err != nil { + return nil, nil, err } handler.SetConnector(connector) - return connector, nil + return connector, handler, nil } diff --git a/core/services/ocr2/plugins/functions/plugin_test.go b/core/services/ocr2/plugins/functions/plugin_test.go index fdd20b0a93..b3a120894d 100644 --- a/core/services/ocr2/plugins/functions/plugin_test.go +++ b/core/services/ocr2/plugins/functions/plugin_test.go @@ -47,7 +47,7 @@ func TestNewConnector_Success(t *testing.T) { config := &config.PluginConfig{ GatewayConnectorConfig: gwcCfg, } - _, err = functions.NewConnector(ctx, config, ethKeystore, chainID, s4Storage, allowlist, rateLimiter, subscriptions, listener, offchainTransmitter, logger.TestLogger(t)) + _, _, err = functions.NewConnector(ctx, config, ethKeystore, chainID, s4Storage, allowlist, rateLimiter, subscriptions, listener, offchainTransmitter, logger.TestLogger(t)) require.NoError(t, err) } @@ -78,6 +78,6 @@ func TestNewConnector_NoKeyForConfiguredAddress(t *testing.T) { config := &config.PluginConfig{ GatewayConnectorConfig: gwcCfg, } - _, err = functions.NewConnector(ctx, config, ethKeystore, chainID, s4Storage, allowlist, rateLimiter, subscriptions, listener, offchainTransmitter, logger.TestLogger(t)) + _, _, err = functions.NewConnector(ctx, config, ethKeystore, chainID, s4Storage, allowlist, rateLimiter, subscriptions, listener, offchainTransmitter, logger.TestLogger(t)) require.Error(t, err) } From bf6618da8aa9695c747b81df172acdd43e379cb2 Mon Sep 17 00:00:00 2001 From: Joe Huang Date: Mon, 9 Sep 2024 12:02:54 -0500 Subject: [PATCH 308/432] LogBroadcaster feature flag (#14354) * adding feature flag for LogBroadcaster, true by default * fix test part 1 * fix test * fix more test * fix test * fix test * one more * edit changeset * update changeset --- .changeset/kind-numbers-melt.md | 13 ++++ core/chains/evm/config/chain_scoped.go | 4 ++ core/chains/evm/config/config.go | 1 + core/chains/evm/config/config_test.go | 19 ++++++ core/chains/evm/config/toml/config.go | 1 + core/chains/evm/config/toml/defaults.go | 3 + .../evm/config/toml/defaults/fallback.toml | 1 + core/chains/legacyevm/chain.go | 2 + core/config/docs/chains-evm.toml | 2 + core/services/chainlink/config_test.go | 2 + .../chainlink/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 3 + core/web/resolver/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 3 + docs/CONFIG.md | 67 +++++++++++++++++++ .../node/validate/defaults-override.txtar | 1 + .../disk-based-logging-disabled.txtar | 1 + .../validate/disk-based-logging-no-dir.txtar | 1 + .../node/validate/disk-based-logging.txtar | 1 + testdata/scripts/node/validate/invalid.txtar | 1 + testdata/scripts/node/validate/valid.txtar | 1 + 21 files changed, 129 insertions(+) create mode 100644 .changeset/kind-numbers-melt.md diff --git a/.changeset/kind-numbers-melt.md b/.changeset/kind-numbers-melt.md new file mode 100644 index 0000000000..43e647399c --- /dev/null +++ b/.changeset/kind-numbers-melt.md @@ -0,0 +1,13 @@ +--- +"chainlink": minor +--- + +Adding feature flag for `LogBroadcaster` called `LogBroadcasterEnabled`, which is `true` by default to support backwards compatibility. +Adding `LogBroadcasterEnabled` allows certain chains to completely disable the `LogBroadcaster` feature, which is an old feature (getting replaced by logPoller) that only few products are using it: +* OCR1 Median +* *OCR2 Median when ChainReader is disabled +* *pre-OCR2 Keeper +* Flux Monitor +* Direct RequestOCR1 Median + +#added diff --git a/core/chains/evm/config/chain_scoped.go b/core/chains/evm/config/chain_scoped.go index b9b19cdc2c..de89272b5e 100644 --- a/core/chains/evm/config/chain_scoped.go +++ b/core/chains/evm/config/chain_scoped.go @@ -176,6 +176,10 @@ func (e *EVMConfig) OperatorFactoryAddress() string { return e.C.OperatorFactoryAddress.String() } +func (e *EVMConfig) LogBroadcasterEnabled() bool { + return e.C.LogBroadcasterEnabled == nil || *e.C.LogBroadcasterEnabled +} + func (e *EVMConfig) LogPrunePageSize() uint32 { return *e.C.LogPrunePageSize } diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index ea3efcdbde..943616d963 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -43,6 +43,7 @@ type EVM interface { MinIncomingConfirmations() uint32 NonceAutoSync() bool OperatorFactoryAddress() string + LogBroadcasterEnabled() bool RPCDefaultBatchSize() uint32 NodeNoNewHeadsThreshold() time.Duration FinalizedBlockOffset() uint32 diff --git a/core/chains/evm/config/config_test.go b/core/chains/evm/config/config_test.go index 3e843fea37..dd6ecd0bf4 100644 --- a/core/chains/evm/config/config_test.go +++ b/core/chains/evm/config/config_test.go @@ -205,6 +205,25 @@ func TestChainScopedConfig(t *testing.T) { assert.Equal(t, val.String(), cfg3.EVM().OperatorFactoryAddress()) }) }) + + t.Run("LogBroadcasterEnabled", func(t *testing.T) { + t.Run("turn on LogBroadcasterEnabled by default", func(t *testing.T) { + assert.Equal(t, true, cfg.EVM().LogBroadcasterEnabled()) + }) + + t.Run("verify LogBroadcasterEnabled is set correctly", func(t *testing.T) { + val := false + cfg3 := testutils.NewTestChainScopedConfig(t, func(c *toml.EVMConfig) { + c.LogBroadcasterEnabled = ptr(val) + }) + + assert.Equal(t, false, cfg3.EVM().LogBroadcasterEnabled()) + }) + + t.Run("use Noop logBroadcaster when LogBroadcaster is disabled", func(t *testing.T) { + + }) + }) } func TestChainScopedConfig_BlockHistory(t *testing.T) { diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 999146b818..ecc278a7ec 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -356,6 +356,7 @@ type Chain struct { NonceAutoSync *bool NoNewHeadsThreshold *commonconfig.Duration OperatorFactoryAddress *types.EIP55Address + LogBroadcasterEnabled *bool RPCDefaultBatchSize *uint32 RPCBlockQueryDelay *uint16 FinalizedBlockOffset *uint32 diff --git a/core/chains/evm/config/toml/defaults.go b/core/chains/evm/config/toml/defaults.go index 4e1ebfb34d..0885d94e6d 100644 --- a/core/chains/evm/config/toml/defaults.go +++ b/core/chains/evm/config/toml/defaults.go @@ -224,6 +224,9 @@ func (c *Chain) SetFrom(f *Chain) { if v := f.OperatorFactoryAddress; v != nil { c.OperatorFactoryAddress = v } + if v := f.LogBroadcasterEnabled; v != nil { + c.LogBroadcasterEnabled = v + } if v := f.RPCDefaultBatchSize; v != nil { c.RPCDefaultBatchSize = v } diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index 56f750ee7b..2f9af4f85a 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -16,6 +16,7 @@ RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 NoNewFinalizedHeadsThreshold = '0' +LogBroadcasterEnabled = true [Transactions] ForwardersEnabled = false diff --git a/core/chains/legacyevm/chain.go b/core/chains/legacyevm/chain.go index 022f4cc531..0bfd0a5b1d 100644 --- a/core/chains/legacyevm/chain.go +++ b/core/chains/legacyevm/chain.go @@ -270,6 +270,8 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod var logBroadcaster log.Broadcaster if !opts.AppConfig.EVMRPCEnabled() { logBroadcaster = &log.NullBroadcaster{ErrMsg: fmt.Sprintf("Ethereum is disabled for chain %d", chainID)} + } else if !cfg.EVM().LogBroadcasterEnabled() { + logBroadcaster = &log.NullBroadcaster{ErrMsg: fmt.Sprintf("LogBroadcaster disabled for chain %d", chainID)} } else if opts.GenLogBroadcaster == nil { logORM := log.NewORM(opts.DS, *chainID) logBroadcaster = log.NewBroadcaster(logORM, client, cfg.EVM(), l, highestSeenHead, opts.MailMon) diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index dae8e5b8aa..ce85f242f5 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -97,6 +97,8 @@ RPCBlockQueryDelay = 1 # Default # Block 64 will be treated as finalized by CL Node only when chain's latest finalized block is 65. As chain finalizes blocks in batches of 32, # CL Node has to wait for a whole new batch to be finalized to treat block 64 as finalized. FinalizedBlockOffset = 0 # Default +# LogBroadcasterEnabled is a feature flag for LogBroadcaster, by default it's true. +LogBroadcasterEnabled = true # Default # NoNewFinalizedHeadsThreshold controls how long to wait for new finalized block before `NodePool` marks rpc endpoints as # out-of-sync. Only applicable if `FinalityTagEnabled=true` # diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index cba3c9ea05..71dc763ad6 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -591,6 +591,7 @@ func TestConfig_Marshal(t *testing.T) { NonceAutoSync: ptr(true), NoNewHeadsThreshold: &minute, OperatorFactoryAddress: mustAddress("0xa5B85635Be42F21f94F28034B7DA440EeFF0F418"), + LogBroadcasterEnabled: ptr(true), RPCDefaultBatchSize: ptr[uint32](17), RPCBlockQueryDelay: ptr[uint16](10), NoNewFinalizedHeadsThreshold: &hour, @@ -1027,6 +1028,7 @@ MinContractPayment = '9.223372036854775807 link' NonceAutoSync = true NoNewHeadsThreshold = '1m0s' OperatorFactoryAddress = '0xa5B85635Be42F21f94F28034B7DA440EeFF0F418' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 17 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 16 diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 2202c60192..0474a5a1e3 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -311,6 +311,7 @@ MinContractPayment = '9.223372036854775807 link' NonceAutoSync = true NoNewHeadsThreshold = '1m0s' OperatorFactoryAddress = '0xa5B85635Be42F21f94F28034B7DA440EeFF0F418' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 17 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 16 diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 91d00841de..5472be09bf 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -298,6 +298,7 @@ MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 12 @@ -405,6 +406,7 @@ MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' OperatorFactoryAddress = '0x8007e24251b1D2Fc518Eb843A701d9cD21fe0aA3' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -506,6 +508,7 @@ MinIncomingConfirmations = 5 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 0 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index f50e3c76ad..c01ab09b66 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -311,6 +311,7 @@ MinContractPayment = '9.223372036854775807 link' NonceAutoSync = true NoNewHeadsThreshold = '1m0s' OperatorFactoryAddress = '0xa5B85635Be42F21f94F28034B7DA440EeFF0F418' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 17 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 0 diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 5e68ba21d1..e631642e05 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -298,6 +298,7 @@ MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -405,6 +406,7 @@ MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' OperatorFactoryAddress = '0x8007e24251b1D2Fc518Eb843A701d9cD21fe0aA3' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -506,6 +508,7 @@ MinIncomingConfirmations = 5 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 0 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index e3d5058a3b..3b42bc3756 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1919,6 +1919,7 @@ MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -2020,6 +2021,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -2121,6 +2123,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -2222,6 +2225,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -2324,6 +2328,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '40s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -2425,6 +2430,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.001 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -2526,6 +2532,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.001 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -2628,6 +2635,7 @@ MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' OperatorFactoryAddress = '0x8007e24251b1D2Fc518Eb843A701d9cD21fe0aA3' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -2729,6 +2737,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 @@ -2829,6 +2838,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -2929,6 +2939,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -3030,6 +3041,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 @@ -3132,6 +3144,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -3233,6 +3246,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 @@ -3334,6 +3348,7 @@ MinIncomingConfirmations = 5 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 0 @@ -3435,6 +3450,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '12m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 15 FinalizedBlockOffset = 0 @@ -3536,6 +3552,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '6m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 15 FinalizedBlockOffset = 0 @@ -3637,6 +3654,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 @@ -3738,6 +3756,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '40s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -3839,6 +3858,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '1m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -3940,6 +3960,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '1m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -4041,6 +4062,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '1m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -4143,6 +4165,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '40s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -4244,6 +4267,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -4344,6 +4368,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -4445,6 +4470,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -4546,6 +4572,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '6m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 15 FinalizedBlockOffset = 0 @@ -4647,6 +4674,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -4748,6 +4776,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -4848,6 +4877,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '100' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -4949,6 +4979,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '12m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -5050,6 +5081,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '40s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -5151,6 +5183,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '12m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -5252,6 +5285,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 @@ -5352,6 +5386,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -5453,6 +5488,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '40s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -5554,6 +5590,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -5656,6 +5693,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -5758,6 +5796,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -5860,6 +5899,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -5961,6 +6001,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '1m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -6062,6 +6103,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 @@ -6163,6 +6205,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 2 FinalizedBlockOffset = 0 @@ -6264,6 +6307,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '1m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -6364,6 +6408,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -6464,6 +6509,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -6564,6 +6610,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -6665,6 +6712,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -6766,6 +6814,7 @@ MinIncomingConfirmations = 5 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 0 @@ -6866,6 +6915,7 @@ MinIncomingConfirmations = 5 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 100 RPCBlockQueryDelay = 10 FinalizedBlockOffset = 0 @@ -6967,6 +7017,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '40s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -7068,6 +7119,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '40s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -7170,6 +7222,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -7272,6 +7325,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -7373,6 +7427,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -7474,6 +7529,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -7575,6 +7631,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -7676,6 +7733,7 @@ MinIncomingConfirmations = 3 MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -7777,6 +7835,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '40s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -7878,6 +7937,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -7979,6 +8039,7 @@ MinIncomingConfirmations = 1 MinContractPayment = '0.00001 link' NonceAutoSync = true NoNewHeadsThreshold = '30s' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 @@ -8250,6 +8311,12 @@ The latest finalized block on chain is 64, so block 63 is the latest finalized f Block 64 will be treated as finalized by CL Node only when chain's latest finalized block is 65. As chain finalizes blocks in batches of 32, CL Node has to wait for a whole new batch to be finalized to treat block 64 as finalized. +### LogBroadcasterEnabled +```toml +LogBroadcasterEnabled = true # Default +``` +LogBroadcasterEnabled is a feature flag for LogBroadcaster, by default it's true. + ### NoNewFinalizedHeadsThreshold ```toml NoNewFinalizedHeadsThreshold = '0' # Default diff --git a/testdata/scripts/node/validate/defaults-override.txtar b/testdata/scripts/node/validate/defaults-override.txtar index 47555b4bdd..07bdea1ce1 100644 --- a/testdata/scripts/node/validate/defaults-override.txtar +++ b/testdata/scripts/node/validate/defaults-override.txtar @@ -371,6 +371,7 @@ MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index 43a7b5a1df..6555292405 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -354,6 +354,7 @@ MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index f108e30356..93769eb6c6 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -354,6 +354,7 @@ MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index f84ce5da40..eaf38bf2a5 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -354,6 +354,7 @@ MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 016a02e088..4838ddc61c 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -344,6 +344,7 @@ MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index c4d188bff0..f7349ed533 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -351,6 +351,7 @@ MinContractPayment = '0.1 link' NonceAutoSync = true NoNewHeadsThreshold = '3m0s' OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' +LogBroadcasterEnabled = true RPCDefaultBatchSize = 250 RPCBlockQueryDelay = 1 FinalizedBlockOffset = 0 From 0efcf380192837a64bbca946474866e8e1bdcec0 Mon Sep 17 00:00:00 2001 From: jlaveracll Date: Mon, 9 Sep 2024 14:22:06 -0300 Subject: [PATCH 309/432] [SHIP-3557] Update L2EP inline comment (#14371) * Update L2EP inline comment * Create few-parents-punch.md * [Bot] Update changeset file with jira issue --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/.changeset/few-parents-punch.md | 8 ++++++++ contracts/src/v0.8/l2ep/dev/shared/BaseValidator.sol | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 contracts/.changeset/few-parents-punch.md diff --git a/contracts/.changeset/few-parents-punch.md b/contracts/.changeset/few-parents-punch.md new file mode 100644 index 0000000000..b8ea2dd2d3 --- /dev/null +++ b/contracts/.changeset/few-parents-punch.md @@ -0,0 +1,8 @@ +--- +'@chainlink/contracts': patch +--- + +update comments + + +SHIP-3557 \ No newline at end of file diff --git a/contracts/src/v0.8/l2ep/dev/shared/BaseValidator.sol b/contracts/src/v0.8/l2ep/dev/shared/BaseValidator.sol index 9b05b88e98..33df388972 100644 --- a/contracts/src/v0.8/l2ep/dev/shared/BaseValidator.sol +++ b/contracts/src/v0.8/l2ep/dev/shared/BaseValidator.sol @@ -24,7 +24,7 @@ abstract contract BaseValidator is SimpleWriteAccessController, AggregatorValida uint32 internal s_gasLimit; /// @param l1CrossDomainMessengerAddress address the L1CrossDomainMessenger contract address - /// @param l2UptimeFeedAddr the address of the ScrollSequencerUptimeFeed contract address + /// @param l2UptimeFeedAddr the address of the SequencerUptimeFeed contract address /// @param gasLimit the gasLimit to use for sending a message from L1 to L2 constructor(address l1CrossDomainMessengerAddress, address l2UptimeFeedAddr, uint32 gasLimit) { if (l1CrossDomainMessengerAddress == address(0)) { From c1878f7374b7fb2de450c83b6dcae62d2a36f3bf Mon Sep 17 00:00:00 2001 From: Awbrey Hughlett Date: Mon, 9 Sep 2024 12:56:36 -0500 Subject: [PATCH 310/432] [BCF-3143] multiple address bindings (#13992) * complete support and implementation for multiple addresses * update feeds to pass contract downstream * address comments and errors * update ccip dep * update deps * update deps * update ccip dep * address comments * address more comments * Update core/capabilities/ccip/delegate.go Co-authored-by: Jordan Krage * fix issue from github commit --------- Co-authored-by: Jordan Krage --- .changeset/short-candles-love.md | 5 + .mockery.yaml | 11 +- .../ccipreader/ccipreader_test.go | 2 +- core/capabilities/ccip/delegate.go | 24 +- .../targets/mocks/chain_reader.go | 487 ------------- .../targets/mocks/contract_reader.go | 533 ++++++++++++++ core/capabilities/targets/write_target.go | 12 +- .../capabilities/targets/write_target_test.go | 22 +- core/scripts/go.mod | 6 +- core/scripts/go.sum | 12 +- .../functions/allowlist/allowlist_test.go | 4 +- core/services/ocr2/plugins/median/services.go | 4 +- core/services/registrysyncer/syncer.go | 59 +- core/services/relay/evm/binding.go | 18 - core/services/relay/evm/bindings.go | 120 ---- core/services/relay/evm/cap_encoder.go | 4 +- core/services/relay/evm/chain_reader.go | 183 ++--- ...n_reader_historical_client_wrapper_test.go | 20 +- core/services/relay/evm/chain_writer.go | 7 +- core/services/relay/evm/{ => codec}/codec.go | 15 +- .../relay/evm/{ => codec}/codec_fuzz_test.go | 2 +- .../relay/evm/{ => codec}/codec_test.go | 22 +- .../services/relay/evm/{ => codec}/decoder.go | 8 +- .../services/relay/evm/{ => codec}/encoder.go | 14 +- .../relay/evm/{ => codec}/parsed_types.go | 12 +- core/services/relay/evm/contract_binding.go | 100 --- core/services/relay/evm/event_binding.go | 476 ------------- core/services/relay/evm/evm.go | 3 +- .../relay/evm/evmtesting/run_tests.go | 47 +- core/services/relay/evm/method_binding.go | 130 ---- .../relay/evm/mocks/loop_relay_adapter.go | 14 +- .../evm/{batch_caller.go => read/batch.go} | 14 +- .../relay/evm/{ => read}/batch_caller_test.go | 23 +- core/services/relay/evm/read/bindings.go | 279 ++++++++ core/services/relay/evm/read/bindings_test.go | 112 +++ core/services/relay/evm/read/contract.go | 243 +++++++ core/services/relay/evm/read/event.go | 654 ++++++++++++++++++ core/services/relay/evm/read/filter.go | 107 +++ core/services/relay/evm/read/lookup.go | 84 +++ core/services/relay/evm/read/method.go | 203 ++++++ .../mocks}/batch_caller.go | 26 +- core/services/relay/evm/read/mocks/reader.go | 463 +++++++++++++ .../relay/evm/read/mocks/registrar.go | 177 +++++ core/services/relay/evm/write_target.go | 11 + core/services/relay/evm/write_target_test.go | 6 +- go.md | 1 + go.mod | 6 +- go.sum | 12 +- integration-tests/go.mod | 6 +- integration-tests/go.sum | 12 +- integration-tests/load/go.mod | 6 +- integration-tests/load/go.sum | 12 +- 52 files changed, 3203 insertions(+), 1630 deletions(-) create mode 100644 .changeset/short-candles-love.md delete mode 100644 core/capabilities/targets/mocks/chain_reader.go create mode 100644 core/capabilities/targets/mocks/contract_reader.go delete mode 100644 core/services/relay/evm/binding.go delete mode 100644 core/services/relay/evm/bindings.go rename core/services/relay/evm/{ => codec}/codec.go (92%) rename core/services/relay/evm/{ => codec}/codec_fuzz_test.go (92%) rename core/services/relay/evm/{ => codec}/codec_test.go (96%) rename core/services/relay/evm/{ => codec}/decoder.go (94%) rename core/services/relay/evm/{ => codec}/encoder.go (90%) rename core/services/relay/evm/{ => codec}/parsed_types.go (80%) delete mode 100644 core/services/relay/evm/contract_binding.go delete mode 100644 core/services/relay/evm/event_binding.go delete mode 100644 core/services/relay/evm/method_binding.go rename core/services/relay/evm/{batch_caller.go => read/batch.go} (96%) rename core/services/relay/evm/{ => read}/batch_caller_test.go (89%) create mode 100644 core/services/relay/evm/read/bindings.go create mode 100644 core/services/relay/evm/read/bindings_test.go create mode 100644 core/services/relay/evm/read/contract.go create mode 100644 core/services/relay/evm/read/event.go create mode 100644 core/services/relay/evm/read/filter.go create mode 100644 core/services/relay/evm/read/lookup.go create mode 100644 core/services/relay/evm/read/method.go rename core/services/relay/evm/{rpclibmocks => read/mocks}/batch_caller.go (69%) create mode 100644 core/services/relay/evm/read/mocks/reader.go create mode 100644 core/services/relay/evm/read/mocks/registrar.go diff --git a/.changeset/short-candles-love.md b/.changeset/short-candles-love.md new file mode 100644 index 0000000000..5923f9796c --- /dev/null +++ b/.changeset/short-candles-love.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal `ContractReader` interface update to accept `BoundContract` for all methods diff --git a/.mockery.yaml b/.mockery.yaml index 8d9e6de4ee..161348efbf 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -326,6 +326,13 @@ packages: interfaces: ExternalInitiatorManager: HTTPClient: + github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/read: + config: + dir: "{{ .InterfaceDir }}/mocks" + interfaces: + Registrar: + Reader: + BatchCaller: github.com/smartcontractkit/chainlink/v2/core/sessions: interfaces: BasicAdminUsersORM: @@ -341,7 +348,7 @@ packages: Codec: config: dir: core/services/relay/evm/mocks - ChainReader: + ContractReader: ChainWriter: github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp: config: @@ -581,4 +588,4 @@ packages: mockname: "Mock{{ .InterfaceName }}" github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer: interfaces: - ORM: \ No newline at end of file + ORM: diff --git a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go index 8f4cd023ce..788b93e836 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go @@ -488,7 +488,7 @@ func testSetup(ctx context.Context, t *testing.T, readerChain, destChain cciptyp contractReaders := map[cciptypes.ChainSelector]contractreader.Extended{readerChain: extendedCr} contractWriters := make(map[cciptypes.ChainSelector]types.ChainWriter) - reader := ccipreaderpkg.NewCCIPReaderWithExtendedContractReaders(lggr, contractReaders, contractWriters, destChain) + reader := ccipreaderpkg.NewCCIPReaderWithExtendedContractReaders(lggr, contractReaders, contractWriters, destChain, nil) t.Cleanup(func() { require.NoError(t, cr.Close()) diff --git a/core/capabilities/ccip/delegate.go b/core/capabilities/ccip/delegate.go index 7623a18af9..84f3e7c1b7 100644 --- a/core/capabilities/ccip/delegate.go +++ b/core/capabilities/ccip/delegate.go @@ -303,12 +303,12 @@ func bindReader(ctx context.Context, capabilityLabelledName, capabilityVersion string, ) (boundReader types.ContractReader, ccipConfigBinding types.BoundContract, err error) { - err = reader.Bind(ctx, []types.BoundContract{ - { - Address: capRegAddress, - Name: consts.ContractNameCapabilitiesRegistry, - }, - }) + boundContract := types.BoundContract{ + Address: capRegAddress, + Name: consts.ContractNameCapabilitiesRegistry, + } + + err = reader.Bind(ctx, []types.BoundContract{boundContract}) if err != nil { return nil, types.BoundContract{}, fmt.Errorf("failed to bind home chain contract reader: %w", err) } @@ -319,9 +319,15 @@ func bindReader(ctx context.Context, } var ccipCapabilityInfo kcr.CapabilitiesRegistryCapabilityInfo - err = reader.GetLatestValue(ctx, consts.ContractNameCapabilitiesRegistry, consts.MethodNameGetCapability, primitives.Unconfirmed, map[string]any{ - "hashedId": hid, - }, &ccipCapabilityInfo) + err = reader.GetLatestValue( + ctx, + boundContract.ReadIdentifier(consts.MethodNameGetCapability), + primitives.Unconfirmed, + map[string]any{ + "hashedId": hid, + }, + &ccipCapabilityInfo, + ) if err != nil { return nil, types.BoundContract{}, fmt.Errorf("failed to get CCIP capability info from chain reader: %w", err) } diff --git a/core/capabilities/targets/mocks/chain_reader.go b/core/capabilities/targets/mocks/chain_reader.go deleted file mode 100644 index 9c1c85ff60..0000000000 --- a/core/capabilities/targets/mocks/chain_reader.go +++ /dev/null @@ -1,487 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package mocks - -import ( - context "context" - - query "github.com/smartcontractkit/chainlink-common/pkg/types/query" - primitives "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" - mock "github.com/stretchr/testify/mock" - - types "github.com/smartcontractkit/chainlink-common/pkg/types" -) - -// ChainReader is an autogenerated mock type for the ChainReader type -type ChainReader struct { - mock.Mock -} - -type ChainReader_Expecter struct { - mock *mock.Mock -} - -func (_m *ChainReader) EXPECT() *ChainReader_Expecter { - return &ChainReader_Expecter{mock: &_m.Mock} -} - -// BatchGetLatestValues provides a mock function with given fields: ctx, request -func (_m *ChainReader) BatchGetLatestValues(ctx context.Context, request types.BatchGetLatestValuesRequest) (types.BatchGetLatestValuesResult, error) { - ret := _m.Called(ctx, request) - - if len(ret) == 0 { - panic("no return value specified for BatchGetLatestValues") - } - - var r0 types.BatchGetLatestValuesResult - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.BatchGetLatestValuesRequest) (types.BatchGetLatestValuesResult, error)); ok { - return rf(ctx, request) - } - if rf, ok := ret.Get(0).(func(context.Context, types.BatchGetLatestValuesRequest) types.BatchGetLatestValuesResult); ok { - r0 = rf(ctx, request) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(types.BatchGetLatestValuesResult) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, types.BatchGetLatestValuesRequest) error); ok { - r1 = rf(ctx, request) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ChainReader_BatchGetLatestValues_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BatchGetLatestValues' -type ChainReader_BatchGetLatestValues_Call struct { - *mock.Call -} - -// BatchGetLatestValues is a helper method to define mock.On call -// - ctx context.Context -// - request types.BatchGetLatestValuesRequest -func (_e *ChainReader_Expecter) BatchGetLatestValues(ctx interface{}, request interface{}) *ChainReader_BatchGetLatestValues_Call { - return &ChainReader_BatchGetLatestValues_Call{Call: _e.mock.On("BatchGetLatestValues", ctx, request)} -} - -func (_c *ChainReader_BatchGetLatestValues_Call) Run(run func(ctx context.Context, request types.BatchGetLatestValuesRequest)) *ChainReader_BatchGetLatestValues_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(types.BatchGetLatestValuesRequest)) - }) - return _c -} - -func (_c *ChainReader_BatchGetLatestValues_Call) Return(_a0 types.BatchGetLatestValuesResult, _a1 error) *ChainReader_BatchGetLatestValues_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *ChainReader_BatchGetLatestValues_Call) RunAndReturn(run func(context.Context, types.BatchGetLatestValuesRequest) (types.BatchGetLatestValuesResult, error)) *ChainReader_BatchGetLatestValues_Call { - _c.Call.Return(run) - return _c -} - -// Bind provides a mock function with given fields: ctx, bindings -func (_m *ChainReader) Bind(ctx context.Context, bindings []types.BoundContract) error { - ret := _m.Called(ctx, bindings) - - if len(ret) == 0 { - panic("no return value specified for Bind") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, []types.BoundContract) error); ok { - r0 = rf(ctx, bindings) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ChainReader_Bind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bind' -type ChainReader_Bind_Call struct { - *mock.Call -} - -// Bind is a helper method to define mock.On call -// - ctx context.Context -// - bindings []types.BoundContract -func (_e *ChainReader_Expecter) Bind(ctx interface{}, bindings interface{}) *ChainReader_Bind_Call { - return &ChainReader_Bind_Call{Call: _e.mock.On("Bind", ctx, bindings)} -} - -func (_c *ChainReader_Bind_Call) Run(run func(ctx context.Context, bindings []types.BoundContract)) *ChainReader_Bind_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].([]types.BoundContract)) - }) - return _c -} - -func (_c *ChainReader_Bind_Call) Return(_a0 error) *ChainReader_Bind_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ChainReader_Bind_Call) RunAndReturn(run func(context.Context, []types.BoundContract) error) *ChainReader_Bind_Call { - _c.Call.Return(run) - return _c -} - -// Close provides a mock function with given fields: -func (_m *ChainReader) Close() error { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for Close") - } - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ChainReader_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' -type ChainReader_Close_Call struct { - *mock.Call -} - -// Close is a helper method to define mock.On call -func (_e *ChainReader_Expecter) Close() *ChainReader_Close_Call { - return &ChainReader_Close_Call{Call: _e.mock.On("Close")} -} - -func (_c *ChainReader_Close_Call) Run(run func()) *ChainReader_Close_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *ChainReader_Close_Call) Return(_a0 error) *ChainReader_Close_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ChainReader_Close_Call) RunAndReturn(run func() error) *ChainReader_Close_Call { - _c.Call.Return(run) - return _c -} - -// GetLatestValue provides a mock function with given fields: ctx, contractName, method, confidenceLevel, params, returnVal -func (_m *ChainReader) GetLatestValue(ctx context.Context, contractName string, method string, confidenceLevel primitives.ConfidenceLevel, params interface{}, returnVal interface{}) error { - ret := _m.Called(ctx, contractName, method, confidenceLevel, params, returnVal) - - if len(ret) == 0 { - panic("no return value specified for GetLatestValue") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, string, primitives.ConfidenceLevel, interface{}, interface{}) error); ok { - r0 = rf(ctx, contractName, method, confidenceLevel, params, returnVal) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ChainReader_GetLatestValue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLatestValue' -type ChainReader_GetLatestValue_Call struct { - *mock.Call -} - -// GetLatestValue is a helper method to define mock.On call -// - ctx context.Context -// - contractName string -// - method string -// - confidenceLevel primitives.ConfidenceLevel -// - params interface{} -// - returnVal interface{} -func (_e *ChainReader_Expecter) GetLatestValue(ctx interface{}, contractName interface{}, method interface{}, confidenceLevel interface{}, params interface{}, returnVal interface{}) *ChainReader_GetLatestValue_Call { - return &ChainReader_GetLatestValue_Call{Call: _e.mock.On("GetLatestValue", ctx, contractName, method, confidenceLevel, params, returnVal)} -} - -func (_c *ChainReader_GetLatestValue_Call) Run(run func(ctx context.Context, contractName string, method string, confidenceLevel primitives.ConfidenceLevel, params interface{}, returnVal interface{})) *ChainReader_GetLatestValue_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(primitives.ConfidenceLevel), args[4].(interface{}), args[5].(interface{})) - }) - return _c -} - -func (_c *ChainReader_GetLatestValue_Call) Return(_a0 error) *ChainReader_GetLatestValue_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ChainReader_GetLatestValue_Call) RunAndReturn(run func(context.Context, string, string, primitives.ConfidenceLevel, interface{}, interface{}) error) *ChainReader_GetLatestValue_Call { - _c.Call.Return(run) - return _c -} - -// HealthReport provides a mock function with given fields: -func (_m *ChainReader) HealthReport() map[string]error { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for HealthReport") - } - - var r0 map[string]error - if rf, ok := ret.Get(0).(func() map[string]error); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[string]error) - } - } - - return r0 -} - -// ChainReader_HealthReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HealthReport' -type ChainReader_HealthReport_Call struct { - *mock.Call -} - -// HealthReport is a helper method to define mock.On call -func (_e *ChainReader_Expecter) HealthReport() *ChainReader_HealthReport_Call { - return &ChainReader_HealthReport_Call{Call: _e.mock.On("HealthReport")} -} - -func (_c *ChainReader_HealthReport_Call) Run(run func()) *ChainReader_HealthReport_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *ChainReader_HealthReport_Call) Return(_a0 map[string]error) *ChainReader_HealthReport_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ChainReader_HealthReport_Call) RunAndReturn(run func() map[string]error) *ChainReader_HealthReport_Call { - _c.Call.Return(run) - return _c -} - -// Name provides a mock function with given fields: -func (_m *ChainReader) Name() string { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for Name") - } - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// ChainReader_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' -type ChainReader_Name_Call struct { - *mock.Call -} - -// Name is a helper method to define mock.On call -func (_e *ChainReader_Expecter) Name() *ChainReader_Name_Call { - return &ChainReader_Name_Call{Call: _e.mock.On("Name")} -} - -func (_c *ChainReader_Name_Call) Run(run func()) *ChainReader_Name_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *ChainReader_Name_Call) Return(_a0 string) *ChainReader_Name_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ChainReader_Name_Call) RunAndReturn(run func() string) *ChainReader_Name_Call { - _c.Call.Return(run) - return _c -} - -// QueryKey provides a mock function with given fields: ctx, contractName, filter, limitAndSort, sequenceDataType -func (_m *ChainReader) QueryKey(ctx context.Context, contractName string, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceDataType interface{}) ([]types.Sequence, error) { - ret := _m.Called(ctx, contractName, filter, limitAndSort, sequenceDataType) - - if len(ret) == 0 { - panic("no return value specified for QueryKey") - } - - var r0 []types.Sequence - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, query.KeyFilter, query.LimitAndSort, interface{}) ([]types.Sequence, error)); ok { - return rf(ctx, contractName, filter, limitAndSort, sequenceDataType) - } - if rf, ok := ret.Get(0).(func(context.Context, string, query.KeyFilter, query.LimitAndSort, interface{}) []types.Sequence); ok { - r0 = rf(ctx, contractName, filter, limitAndSort, sequenceDataType) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]types.Sequence) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, string, query.KeyFilter, query.LimitAndSort, interface{}) error); ok { - r1 = rf(ctx, contractName, filter, limitAndSort, sequenceDataType) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ChainReader_QueryKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'QueryKey' -type ChainReader_QueryKey_Call struct { - *mock.Call -} - -// QueryKey is a helper method to define mock.On call -// - ctx context.Context -// - contractName string -// - filter query.KeyFilter -// - limitAndSort query.LimitAndSort -// - sequenceDataType interface{} -func (_e *ChainReader_Expecter) QueryKey(ctx interface{}, contractName interface{}, filter interface{}, limitAndSort interface{}, sequenceDataType interface{}) *ChainReader_QueryKey_Call { - return &ChainReader_QueryKey_Call{Call: _e.mock.On("QueryKey", ctx, contractName, filter, limitAndSort, sequenceDataType)} -} - -func (_c *ChainReader_QueryKey_Call) Run(run func(ctx context.Context, contractName string, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceDataType interface{})) *ChainReader_QueryKey_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(query.KeyFilter), args[3].(query.LimitAndSort), args[4].(interface{})) - }) - return _c -} - -func (_c *ChainReader_QueryKey_Call) Return(_a0 []types.Sequence, _a1 error) *ChainReader_QueryKey_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *ChainReader_QueryKey_Call) RunAndReturn(run func(context.Context, string, query.KeyFilter, query.LimitAndSort, interface{}) ([]types.Sequence, error)) *ChainReader_QueryKey_Call { - _c.Call.Return(run) - return _c -} - -// Ready provides a mock function with given fields: -func (_m *ChainReader) Ready() error { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for Ready") - } - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ChainReader_Ready_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Ready' -type ChainReader_Ready_Call struct { - *mock.Call -} - -// Ready is a helper method to define mock.On call -func (_e *ChainReader_Expecter) Ready() *ChainReader_Ready_Call { - return &ChainReader_Ready_Call{Call: _e.mock.On("Ready")} -} - -func (_c *ChainReader_Ready_Call) Run(run func()) *ChainReader_Ready_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *ChainReader_Ready_Call) Return(_a0 error) *ChainReader_Ready_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ChainReader_Ready_Call) RunAndReturn(run func() error) *ChainReader_Ready_Call { - _c.Call.Return(run) - return _c -} - -// Start provides a mock function with given fields: _a0 -func (_m *ChainReader) Start(_a0 context.Context) error { - ret := _m.Called(_a0) - - if len(ret) == 0 { - panic("no return value specified for Start") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ChainReader_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start' -type ChainReader_Start_Call struct { - *mock.Call -} - -// Start is a helper method to define mock.On call -// - _a0 context.Context -func (_e *ChainReader_Expecter) Start(_a0 interface{}) *ChainReader_Start_Call { - return &ChainReader_Start_Call{Call: _e.mock.On("Start", _a0)} -} - -func (_c *ChainReader_Start_Call) Run(run func(_a0 context.Context)) *ChainReader_Start_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *ChainReader_Start_Call) Return(_a0 error) *ChainReader_Start_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ChainReader_Start_Call) RunAndReturn(run func(context.Context) error) *ChainReader_Start_Call { - _c.Call.Return(run) - return _c -} - -// NewChainReader creates a new instance of ChainReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewChainReader(t interface { - mock.TestingT - Cleanup(func()) -}) *ChainReader { - mock := &ChainReader{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/capabilities/targets/mocks/contract_reader.go b/core/capabilities/targets/mocks/contract_reader.go new file mode 100644 index 0000000000..dd92195ec2 --- /dev/null +++ b/core/capabilities/targets/mocks/contract_reader.go @@ -0,0 +1,533 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + query "github.com/smartcontractkit/chainlink-common/pkg/types/query" + primitives "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + mock "github.com/stretchr/testify/mock" + + types "github.com/smartcontractkit/chainlink-common/pkg/types" +) + +// ContractReader is an autogenerated mock type for the ContractReader type +type ContractReader struct { + mock.Mock +} + +type ContractReader_Expecter struct { + mock *mock.Mock +} + +func (_m *ContractReader) EXPECT() *ContractReader_Expecter { + return &ContractReader_Expecter{mock: &_m.Mock} +} + +// BatchGetLatestValues provides a mock function with given fields: ctx, request +func (_m *ContractReader) BatchGetLatestValues(ctx context.Context, request types.BatchGetLatestValuesRequest) (types.BatchGetLatestValuesResult, error) { + ret := _m.Called(ctx, request) + + if len(ret) == 0 { + panic("no return value specified for BatchGetLatestValues") + } + + var r0 types.BatchGetLatestValuesResult + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, types.BatchGetLatestValuesRequest) (types.BatchGetLatestValuesResult, error)); ok { + return rf(ctx, request) + } + if rf, ok := ret.Get(0).(func(context.Context, types.BatchGetLatestValuesRequest) types.BatchGetLatestValuesResult); ok { + r0 = rf(ctx, request) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(types.BatchGetLatestValuesResult) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, types.BatchGetLatestValuesRequest) error); ok { + r1 = rf(ctx, request) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ContractReader_BatchGetLatestValues_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BatchGetLatestValues' +type ContractReader_BatchGetLatestValues_Call struct { + *mock.Call +} + +// BatchGetLatestValues is a helper method to define mock.On call +// - ctx context.Context +// - request types.BatchGetLatestValuesRequest +func (_e *ContractReader_Expecter) BatchGetLatestValues(ctx interface{}, request interface{}) *ContractReader_BatchGetLatestValues_Call { + return &ContractReader_BatchGetLatestValues_Call{Call: _e.mock.On("BatchGetLatestValues", ctx, request)} +} + +func (_c *ContractReader_BatchGetLatestValues_Call) Run(run func(ctx context.Context, request types.BatchGetLatestValuesRequest)) *ContractReader_BatchGetLatestValues_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(types.BatchGetLatestValuesRequest)) + }) + return _c +} + +func (_c *ContractReader_BatchGetLatestValues_Call) Return(_a0 types.BatchGetLatestValuesResult, _a1 error) *ContractReader_BatchGetLatestValues_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ContractReader_BatchGetLatestValues_Call) RunAndReturn(run func(context.Context, types.BatchGetLatestValuesRequest) (types.BatchGetLatestValuesResult, error)) *ContractReader_BatchGetLatestValues_Call { + _c.Call.Return(run) + return _c +} + +// Bind provides a mock function with given fields: ctx, bindings +func (_m *ContractReader) Bind(ctx context.Context, bindings []types.BoundContract) error { + ret := _m.Called(ctx, bindings) + + if len(ret) == 0 { + panic("no return value specified for Bind") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []types.BoundContract) error); ok { + r0 = rf(ctx, bindings) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ContractReader_Bind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bind' +type ContractReader_Bind_Call struct { + *mock.Call +} + +// Bind is a helper method to define mock.On call +// - ctx context.Context +// - bindings []types.BoundContract +func (_e *ContractReader_Expecter) Bind(ctx interface{}, bindings interface{}) *ContractReader_Bind_Call { + return &ContractReader_Bind_Call{Call: _e.mock.On("Bind", ctx, bindings)} +} + +func (_c *ContractReader_Bind_Call) Run(run func(ctx context.Context, bindings []types.BoundContract)) *ContractReader_Bind_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]types.BoundContract)) + }) + return _c +} + +func (_c *ContractReader_Bind_Call) Return(_a0 error) *ContractReader_Bind_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ContractReader_Bind_Call) RunAndReturn(run func(context.Context, []types.BoundContract) error) *ContractReader_Bind_Call { + _c.Call.Return(run) + return _c +} + +// Close provides a mock function with given fields: +func (_m *ContractReader) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ContractReader_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type ContractReader_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *ContractReader_Expecter) Close() *ContractReader_Close_Call { + return &ContractReader_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *ContractReader_Close_Call) Run(run func()) *ContractReader_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ContractReader_Close_Call) Return(_a0 error) *ContractReader_Close_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ContractReader_Close_Call) RunAndReturn(run func() error) *ContractReader_Close_Call { + _c.Call.Return(run) + return _c +} + +// GetLatestValue provides a mock function with given fields: ctx, readIdentifier, confidenceLevel, params, returnVal +func (_m *ContractReader) GetLatestValue(ctx context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params interface{}, returnVal interface{}) error { + ret := _m.Called(ctx, readIdentifier, confidenceLevel, params, returnVal) + + if len(ret) == 0 { + panic("no return value specified for GetLatestValue") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string, primitives.ConfidenceLevel, interface{}, interface{}) error); ok { + r0 = rf(ctx, readIdentifier, confidenceLevel, params, returnVal) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ContractReader_GetLatestValue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLatestValue' +type ContractReader_GetLatestValue_Call struct { + *mock.Call +} + +// GetLatestValue is a helper method to define mock.On call +// - ctx context.Context +// - readIdentifier string +// - confidenceLevel primitives.ConfidenceLevel +// - params interface{} +// - returnVal interface{} +func (_e *ContractReader_Expecter) GetLatestValue(ctx interface{}, readIdentifier interface{}, confidenceLevel interface{}, params interface{}, returnVal interface{}) *ContractReader_GetLatestValue_Call { + return &ContractReader_GetLatestValue_Call{Call: _e.mock.On("GetLatestValue", ctx, readIdentifier, confidenceLevel, params, returnVal)} +} + +func (_c *ContractReader_GetLatestValue_Call) Run(run func(ctx context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params interface{}, returnVal interface{})) *ContractReader_GetLatestValue_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string), args[2].(primitives.ConfidenceLevel), args[3].(interface{}), args[4].(interface{})) + }) + return _c +} + +func (_c *ContractReader_GetLatestValue_Call) Return(_a0 error) *ContractReader_GetLatestValue_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ContractReader_GetLatestValue_Call) RunAndReturn(run func(context.Context, string, primitives.ConfidenceLevel, interface{}, interface{}) error) *ContractReader_GetLatestValue_Call { + _c.Call.Return(run) + return _c +} + +// HealthReport provides a mock function with given fields: +func (_m *ContractReader) HealthReport() map[string]error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for HealthReport") + } + + var r0 map[string]error + if rf, ok := ret.Get(0).(func() map[string]error); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]error) + } + } + + return r0 +} + +// ContractReader_HealthReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HealthReport' +type ContractReader_HealthReport_Call struct { + *mock.Call +} + +// HealthReport is a helper method to define mock.On call +func (_e *ContractReader_Expecter) HealthReport() *ContractReader_HealthReport_Call { + return &ContractReader_HealthReport_Call{Call: _e.mock.On("HealthReport")} +} + +func (_c *ContractReader_HealthReport_Call) Run(run func()) *ContractReader_HealthReport_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ContractReader_HealthReport_Call) Return(_a0 map[string]error) *ContractReader_HealthReport_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ContractReader_HealthReport_Call) RunAndReturn(run func() map[string]error) *ContractReader_HealthReport_Call { + _c.Call.Return(run) + return _c +} + +// Name provides a mock function with given fields: +func (_m *ContractReader) Name() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Name") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// ContractReader_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' +type ContractReader_Name_Call struct { + *mock.Call +} + +// Name is a helper method to define mock.On call +func (_e *ContractReader_Expecter) Name() *ContractReader_Name_Call { + return &ContractReader_Name_Call{Call: _e.mock.On("Name")} +} + +func (_c *ContractReader_Name_Call) Run(run func()) *ContractReader_Name_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ContractReader_Name_Call) Return(_a0 string) *ContractReader_Name_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ContractReader_Name_Call) RunAndReturn(run func() string) *ContractReader_Name_Call { + _c.Call.Return(run) + return _c +} + +// QueryKey provides a mock function with given fields: ctx, contract, filter, limitAndSort, sequenceDataType +func (_m *ContractReader) QueryKey(ctx context.Context, contract types.BoundContract, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceDataType interface{}) ([]types.Sequence, error) { + ret := _m.Called(ctx, contract, filter, limitAndSort, sequenceDataType) + + if len(ret) == 0 { + panic("no return value specified for QueryKey") + } + + var r0 []types.Sequence + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, interface{}) ([]types.Sequence, error)); ok { + return rf(ctx, contract, filter, limitAndSort, sequenceDataType) + } + if rf, ok := ret.Get(0).(func(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, interface{}) []types.Sequence); ok { + r0 = rf(ctx, contract, filter, limitAndSort, sequenceDataType) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]types.Sequence) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, interface{}) error); ok { + r1 = rf(ctx, contract, filter, limitAndSort, sequenceDataType) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ContractReader_QueryKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'QueryKey' +type ContractReader_QueryKey_Call struct { + *mock.Call +} + +// QueryKey is a helper method to define mock.On call +// - ctx context.Context +// - contract types.BoundContract +// - filter query.KeyFilter +// - limitAndSort query.LimitAndSort +// - sequenceDataType interface{} +func (_e *ContractReader_Expecter) QueryKey(ctx interface{}, contract interface{}, filter interface{}, limitAndSort interface{}, sequenceDataType interface{}) *ContractReader_QueryKey_Call { + return &ContractReader_QueryKey_Call{Call: _e.mock.On("QueryKey", ctx, contract, filter, limitAndSort, sequenceDataType)} +} + +func (_c *ContractReader_QueryKey_Call) Run(run func(ctx context.Context, contract types.BoundContract, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceDataType interface{})) *ContractReader_QueryKey_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(types.BoundContract), args[2].(query.KeyFilter), args[3].(query.LimitAndSort), args[4].(interface{})) + }) + return _c +} + +func (_c *ContractReader_QueryKey_Call) Return(_a0 []types.Sequence, _a1 error) *ContractReader_QueryKey_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ContractReader_QueryKey_Call) RunAndReturn(run func(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, interface{}) ([]types.Sequence, error)) *ContractReader_QueryKey_Call { + _c.Call.Return(run) + return _c +} + +// Ready provides a mock function with given fields: +func (_m *ContractReader) Ready() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Ready") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ContractReader_Ready_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Ready' +type ContractReader_Ready_Call struct { + *mock.Call +} + +// Ready is a helper method to define mock.On call +func (_e *ContractReader_Expecter) Ready() *ContractReader_Ready_Call { + return &ContractReader_Ready_Call{Call: _e.mock.On("Ready")} +} + +func (_c *ContractReader_Ready_Call) Run(run func()) *ContractReader_Ready_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ContractReader_Ready_Call) Return(_a0 error) *ContractReader_Ready_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ContractReader_Ready_Call) RunAndReturn(run func() error) *ContractReader_Ready_Call { + _c.Call.Return(run) + return _c +} + +// Start provides a mock function with given fields: _a0 +func (_m *ContractReader) Start(_a0 context.Context) error { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for Start") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ContractReader_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start' +type ContractReader_Start_Call struct { + *mock.Call +} + +// Start is a helper method to define mock.On call +// - _a0 context.Context +func (_e *ContractReader_Expecter) Start(_a0 interface{}) *ContractReader_Start_Call { + return &ContractReader_Start_Call{Call: _e.mock.On("Start", _a0)} +} + +func (_c *ContractReader_Start_Call) Run(run func(_a0 context.Context)) *ContractReader_Start_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *ContractReader_Start_Call) Return(_a0 error) *ContractReader_Start_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ContractReader_Start_Call) RunAndReturn(run func(context.Context) error) *ContractReader_Start_Call { + _c.Call.Return(run) + return _c +} + +// Unbind provides a mock function with given fields: ctx, bindings +func (_m *ContractReader) Unbind(ctx context.Context, bindings []types.BoundContract) error { + ret := _m.Called(ctx, bindings) + + if len(ret) == 0 { + panic("no return value specified for Unbind") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []types.BoundContract) error); ok { + r0 = rf(ctx, bindings) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ContractReader_Unbind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Unbind' +type ContractReader_Unbind_Call struct { + *mock.Call +} + +// Unbind is a helper method to define mock.On call +// - ctx context.Context +// - bindings []types.BoundContract +func (_e *ContractReader_Expecter) Unbind(ctx interface{}, bindings interface{}) *ContractReader_Unbind_Call { + return &ContractReader_Unbind_Call{Call: _e.mock.On("Unbind", ctx, bindings)} +} + +func (_c *ContractReader_Unbind_Call) Run(run func(ctx context.Context, bindings []types.BoundContract)) *ContractReader_Unbind_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]types.BoundContract)) + }) + return _c +} + +func (_c *ContractReader_Unbind_Call) Return(_a0 error) *ContractReader_Unbind_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ContractReader_Unbind_Call) RunAndReturn(run func(context.Context, []types.BoundContract) error) *ContractReader_Unbind_Call { + _c.Call.Return(run) + return _c +} + +// NewContractReader creates a new instance of ContractReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewContractReader(t interface { + mock.TestingT + Cleanup(func()) +}) *ContractReader { + mock := &ContractReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index a3ebe77c97..83c39e3457 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -25,6 +25,7 @@ var ( type WriteTarget struct { cr commontypes.ContractReader cw commontypes.ChainWriter + binding commontypes.BoundContract forwarderAddress string // The minimum amount of gas that the receiver contract must get to process the forwarder report receiverGasMinimum uint64 @@ -59,6 +60,10 @@ func NewWriteTarget(lggr logger.Logger, id string, cr commontypes.ContractReader return &WriteTarget{ cr, cw, + commontypes.BoundContract{ + Address: forwarderAddress, + Name: "forwarder", + }, forwarderAddress, txGasLimit - FORWARDER_CONTRACT_LOGIC_GAS_COST, info, @@ -176,10 +181,7 @@ func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.Cap // cannot be run during initialization. if !cap.bound { cap.lggr.Debugw("Binding to forwarder address") - err := cap.cr.Bind(ctx, []commontypes.BoundContract{{ - Address: cap.forwarderAddress, - Name: "forwarder", - }}) + err := cap.cr.Bind(ctx, []commontypes.BoundContract{cap.binding}) if err != nil { return capabilities.CapabilityResponse{}, err } @@ -209,7 +211,7 @@ func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.Cap ReportId: request.Inputs.SignedReport.ID, } var transmissionInfo TransmissionInfo - if err = cap.cr.GetLatestValue(ctx, "forwarder", "getTransmissionInfo", primitives.Unconfirmed, queryInputs, &transmissionInfo); err != nil { + if err = cap.cr.GetLatestValue(ctx, cap.binding.ReadIdentifier("getTransmissionInfo"), primitives.Unconfirmed, queryInputs, &transmissionInfo); err != nil { return capabilities.CapabilityResponse{}, fmt.Errorf("failed to getTransmissionInfo latest value: %w", err) } diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go index aa0717aa0e..cdef0cc83b 100644 --- a/core/capabilities/targets/write_target_test.go +++ b/core/capabilities/targets/write_target_test.go @@ -14,7 +14,9 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" "github.com/smartcontractkit/chainlink-common/pkg/values" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/targets" "github.com/smartcontractkit/chainlink/v2/core/capabilities/targets/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" @@ -26,7 +28,7 @@ func TestWriteTarget(t *testing.T) { ctx := context.Background() cw := mocks.NewChainWriter(t) - cr := mocks.NewChainReader(t) + cr := mocks.NewContractReader(t) forwarderA := testutils.NewAddress() forwarderAddr := forwarderA.Hex() @@ -69,15 +71,15 @@ func TestWriteTarget(t *testing.T) { WorkflowExecutionID: hex.EncodeToString(reportMetadata.WorkflowExecutionID[:]), } - cr.On("Bind", mock.Anything, []types.BoundContract{ - { - Address: forwarderAddr, - Name: "forwarder", - }, - }).Return(nil) + binding := types.BoundContract{ + Address: forwarderAddr, + Name: "forwarder", + } + + cr.On("Bind", mock.Anything, []types.BoundContract{binding}).Return(nil) - cr.On("GetLatestValue", mock.Anything, "forwarder", "getTransmissionInfo", mock.Anything, mock.Anything, mock.Anything).Return(nil).Run(func(args mock.Arguments) { - transmissionInfo := args.Get(5).(*targets.TransmissionInfo) + cr.EXPECT().GetLatestValue(mock.Anything, binding.ReadIdentifier("getTransmissionInfo"), mock.Anything, mock.Anything, mock.Anything).Return(nil).Run(func(_ context.Context, _ string, _ primitives.ConfidenceLevel, _, retVal any) { + transmissionInfo := retVal.(*targets.TransmissionInfo) *transmissionInfo = targets.TransmissionInfo{ GasLimit: big.NewInt(0), InvalidReceiver: false, @@ -170,7 +172,7 @@ func TestWriteTarget(t *testing.T) { Config: config, Inputs: validInputs, } - cr.On("GetLatestValue", mock.Anything, "forwarder", "getTransmissionInfo", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("reader error")) + cr.EXPECT().GetLatestValue(mock.Anything, binding.ReadIdentifier("getTransmissionInfo"), mock.Anything, mock.Anything, mock.Anything).Return(errors.New("reader error")) _, err = writeTarget.Execute(ctx, req) require.Error(t, err) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index af64d0a0b3..1a19bf6927 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.0 @@ -270,10 +270,10 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect - github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index a536f2bdd9..5644fafbb2 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1188,16 +1188,16 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b h1:/PQDTP/ETmEXCv3qokVs5JqMcHDFP8TWdkcQAzs/nQg= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f h1:a6zEDLYgTQ4G+9PgLX8G2bF40BdsOY5//5i+whYwLlQ= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 h1:3VbeaqoBblboQ3ytpM7UZzL7MXoHctaaXGGkJ8XkDhY= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 h1:Q19HQPzISHKEIP0rNFGEiIFvMEeAgb1YRXEFnyBMnNM= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 h1:88ZNrxZd0Uxn9934G/3L5AABTX13iorQJdUXcSUewwg= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5/go.mod h1:/QPAcfj5RQ4pNmDBLJ/Or7EjMAvFU3Xb1pM9gl0jfao= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a h1:0zbG9reudNAJC/Rwe3tYX7kshVtOEXXAhk0uLg/62Y4= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go index 500985acc3..b8735bbf8a 100644 --- a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go @@ -21,7 +21,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist" amocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist/mocks" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -376,7 +376,7 @@ func encodeTypeAndVersionResponse(typeAndVersion string) ([]byte, error) { codecConfig := types.CodecConfig{Configs: map[string]types.ChainCodecConfig{ codecName: {TypeABI: evmEncoderConfig}, }} - encoder, err := evm.NewCodec(codecConfig) + encoder, err := codec.NewCodec(codecConfig) if err != nil { return nil, err } diff --git a/core/services/ocr2/plugins/median/services.go b/core/services/ocr2/plugins/median/services.go index 897531b82f..866044fcc9 100644 --- a/core/services/ocr2/plugins/median/services.go +++ b/core/services/ocr2/plugins/median/services.go @@ -167,11 +167,11 @@ func NewMedianServices(ctx context.Context, abort() return } - median := loop.NewMedianService(lggr, telem, cmdFn, medianProvider, dataSource, juelsPerFeeCoinSource, gasPriceSubunitsDataSource, errorLog) + median := loop.NewMedianService(lggr, telem, cmdFn, medianProvider, spec.ContractID, dataSource, juelsPerFeeCoinSource, gasPriceSubunitsDataSource, errorLog) argsNoPlugin.ReportingPluginFactory = median srvs = append(srvs, median) } else { - argsNoPlugin.ReportingPluginFactory, err = median.NewPlugin(lggr).NewMedianFactory(ctx, medianProvider, dataSource, juelsPerFeeCoinSource, gasPriceSubunitsDataSource, errorLog) + argsNoPlugin.ReportingPluginFactory, err = median.NewPlugin(lggr).NewMedianFactory(ctx, medianProvider, spec.ContractID, dataSource, juelsPerFeeCoinSource, gasPriceSubunitsDataSource, errorLog) if err != nil { err = fmt.Errorf("failed to create median factory: %w", err) abort() diff --git a/core/services/registrysyncer/syncer.go b/core/services/registrysyncer/syncer.go index ab50c448b5..1ef78b6edc 100644 --- a/core/services/registrysyncer/syncer.go +++ b/core/services/registrysyncer/syncer.go @@ -44,13 +44,13 @@ type RegistrySyncer interface { type registrySyncer struct { services.StateMachine - stopCh services.StopChan - launchers []Launcher - reader types.ContractReader - initReader func(ctx context.Context, lggr logger.Logger, relayer ContractReaderFactory, registryAddress string) (types.ContractReader, error) - relayer ContractReaderFactory - registryAddress string - getPeerID func() (p2ptypes.PeerID, error) + stopCh services.StopChan + launchers []Launcher + reader types.ContractReader + initReader func(ctx context.Context, lggr logger.Logger, relayer ContractReaderFactory, capabilitiesContract types.BoundContract) (types.ContractReader, error) + relayer ContractReaderFactory + capabilitiesContract types.BoundContract + getPeerID func() (p2ptypes.PeerID, error) orm ORM @@ -76,21 +76,24 @@ func New( orm ORM, ) (RegistrySyncer, error) { return ®istrySyncer{ - stopCh: make(services.StopChan), - updateChan: make(chan *LocalRegistry), - lggr: lggr.Named("RegistrySyncer"), - relayer: relayer, - registryAddress: registryAddress, - initReader: newReader, - orm: orm, - getPeerID: getPeerID, + stopCh: make(services.StopChan), + updateChan: make(chan *LocalRegistry), + lggr: lggr.Named("RegistrySyncer"), + relayer: relayer, + capabilitiesContract: types.BoundContract{ + Address: registryAddress, + Name: "CapabilitiesRegistry", + }, + initReader: newReader, + orm: orm, + getPeerID: getPeerID, }, nil } // NOTE: this can't be called while initializing the syncer and needs to be called in the sync loop. // This is because Bind() makes an onchain call to verify that the contract address exists, and if // called during initialization, this results in a "no live nodes" error. -func newReader(ctx context.Context, lggr logger.Logger, relayer ContractReaderFactory, remoteRegistryAddress string) (types.ContractReader, error) { +func newReader(ctx context.Context, lggr logger.Logger, relayer ContractReaderFactory, capabilitiesContract types.BoundContract) (types.ContractReader, error) { contractReaderConfig := evmrelaytypes.ChainReaderConfig{ Contracts: map[string]evmrelaytypes.ChainContractReader{ "CapabilitiesRegistry": { @@ -120,12 +123,7 @@ func newReader(ctx context.Context, lggr logger.Logger, relayer ContractReaderFa return nil, err } - err = cr.Bind(ctx, []types.BoundContract{ - { - Address: remoteRegistryAddress, - Name: "CapabilitiesRegistry", - }, - }) + err = cr.Bind(ctx, []types.BoundContract{capabilitiesContract}) return cr, err } @@ -197,8 +195,9 @@ func (s *registrySyncer) updateStateLoop() { } func (s *registrySyncer) localRegistry(ctx context.Context) (*LocalRegistry, error) { - var caps []kcr.CapabilitiesRegistryCapabilityInfo - err := s.reader.GetLatestValue(ctx, "CapabilitiesRegistry", "getCapabilities", primitives.Unconfirmed, nil, &caps) + caps := []kcr.CapabilitiesRegistryCapabilityInfo{} + + err := s.reader.GetLatestValue(ctx, s.capabilitiesContract.ReadIdentifier("getCapabilities"), primitives.Unconfirmed, nil, &caps) if err != nil { return nil, err } @@ -215,8 +214,9 @@ func (s *registrySyncer) localRegistry(ctx context.Context) (*LocalRegistry, err hashedIDsToCapabilityIDs[c.HashedId] = cid } - var dons []kcr.CapabilitiesRegistryDONInfo - err = s.reader.GetLatestValue(ctx, "CapabilitiesRegistry", "getDONs", primitives.Unconfirmed, nil, &dons) + dons := []kcr.CapabilitiesRegistryDONInfo{} + + err = s.reader.GetLatestValue(ctx, s.capabilitiesContract.ReadIdentifier("getDONs"), primitives.Unconfirmed, nil, &dons) if err != nil { return nil, err } @@ -241,8 +241,9 @@ func (s *registrySyncer) localRegistry(ctx context.Context) (*LocalRegistry, err } } - var nodes []kcr.CapabilitiesRegistryNodeInfo - err = s.reader.GetLatestValue(ctx, "CapabilitiesRegistry", "getNodes", primitives.Unconfirmed, nil, &nodes) + nodes := []kcr.CapabilitiesRegistryNodeInfo{} + + err = s.reader.GetLatestValue(ctx, s.capabilitiesContract.ReadIdentifier("getNodes"), primitives.Unconfirmed, nil, &nodes) if err != nil { return nil, err } @@ -271,7 +272,7 @@ func (s *registrySyncer) Sync(ctx context.Context, isInitialSync bool) error { } if s.reader == nil { - reader, err := s.initReader(ctx, s.lggr, s.relayer, s.registryAddress) + reader, err := s.initReader(ctx, s.lggr, s.relayer, s.capabilitiesContract) if err != nil { return err } diff --git a/core/services/relay/evm/binding.go b/core/services/relay/evm/binding.go deleted file mode 100644 index 412e33c609..0000000000 --- a/core/services/relay/evm/binding.go +++ /dev/null @@ -1,18 +0,0 @@ -package evm - -import ( - "context" - - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/smartcontractkit/chainlink-common/pkg/types/query" - "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" -) - -type readBinding interface { - Bind(ctx context.Context, binding commontypes.BoundContract) error - SetCodec(codec commontypes.RemoteCodec) - Register(ctx context.Context) error - Unregister(ctx context.Context) error - GetLatestValue(ctx context.Context, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) error - QueryKey(ctx context.Context, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceDataType any) ([]commontypes.Sequence, error) -} diff --git a/core/services/relay/evm/bindings.go b/core/services/relay/evm/bindings.go deleted file mode 100644 index 4d4760db52..0000000000 --- a/core/services/relay/evm/bindings.go +++ /dev/null @@ -1,120 +0,0 @@ -package evm - -import ( - "context" - "fmt" - - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" -) - -// bindings manage all contract bindings, key is contract name. - -type bindings struct { - contractBindings map[string]*contractBinding - BatchCaller -} - -func (b bindings) GetReadBinding(contractName, readName string) (readBinding, error) { - // GetReadBindings should only be called after Chain Reader init. - cb, cbExists := b.contractBindings[contractName] - if !cbExists { - return nil, fmt.Errorf("%w: no contract named %s", commontypes.ErrInvalidType, contractName) - } - - rb, rbExists := cb.readBindings[readName] - if !rbExists { - return nil, fmt.Errorf("%w: no readName named %s in contract %s", commontypes.ErrInvalidType, readName, contractName) - } - return rb, nil -} - -// AddReadBinding adds read bindings. Calling this outside of Chain Reader init is not thread safe. -func (b bindings) AddReadBinding(contractName, readName string, rb readBinding) { - cb, cbExists := b.contractBindings[contractName] - if !cbExists { - cb = &contractBinding{ - name: contractName, - readBindings: make(map[string]readBinding), - } - b.contractBindings[contractName] = cb - } - cb.readBindings[readName] = rb -} - -// Bind binds contract addresses to contract bindings and read bindings. -// Bind also registers the common contract polling filter and eventBindings polling filters. -func (b bindings) Bind(ctx context.Context, lp logpoller.LogPoller, boundContracts []commontypes.BoundContract) error { - for _, bc := range boundContracts { - cb, cbExists := b.contractBindings[bc.Name] - if !cbExists { - return fmt.Errorf("%w: no contract named %s", commontypes.ErrInvalidConfig, bc.Name) - } - - if err := cb.Bind(ctx, lp, bc); err != nil { - return err - } - - for _, rb := range cb.readBindings { - if err := rb.Bind(ctx, bc); err != nil { - return err - } - } - } - return nil -} - -func (b bindings) BatchGetLatestValues(ctx context.Context, request commontypes.BatchGetLatestValuesRequest) (commontypes.BatchGetLatestValuesResult, error) { - var batchCall BatchCall - toChainAgnosticMethodName := make(map[string]string) - for contractName, contractBatch := range request { - cb := b.contractBindings[contractName] - for i := range contractBatch { - req := contractBatch[i] - switch rb := cb.readBindings[req.ReadName].(type) { - case *methodBinding: - toChainAgnosticMethodName[rb.method] = req.ReadName - batchCall = append(batchCall, Call{ - ContractAddress: rb.address, - ContractName: cb.name, - MethodName: rb.method, - Params: req.Params, - ReturnVal: req.ReturnVal, - }) - // results here will have chain specific method names. - case *eventBinding: - // TODO Use FilteredLogs to batch? This isn't a priority right now, but should get implemented at some point. - return nil, fmt.Errorf("%w: events are not yet supported in batch get latest values", commontypes.ErrInvalidType) - default: - return nil, fmt.Errorf("%w: missing read binding type for contract: %s read: %s", commontypes.ErrInvalidType, contractName, req.ReadName) - } - } - } - - results, err := b.BatchCall(ctx, 0, batchCall) - if err != nil { - return nil, err - } - - // reconstruct results from batchCall and filteredLogs into common type while maintaining order from request. - batchGetLatestValuesResults := make(commontypes.BatchGetLatestValuesResult) - for contractName, contractResult := range results { - batchGetLatestValuesResults[contractName] = commontypes.ContractBatchResults{} - for _, methodResult := range contractResult { - brr := commontypes.BatchReadResult{ReadName: toChainAgnosticMethodName[methodResult.MethodName]} - brr.SetResult(methodResult.ReturnValue, methodResult.Err) - batchGetLatestValuesResults[contractName] = append(batchGetLatestValuesResults[contractName], brr) - } - } - - return batchGetLatestValuesResults, err -} - -func (b bindings) ForEach(ctx context.Context, fn func(context.Context, *contractBinding) error) error { - for _, cb := range b.contractBindings { - if err := fn(ctx, cb); err != nil { - return err - } - } - return nil -} diff --git a/core/services/relay/evm/cap_encoder.go b/core/services/relay/evm/cap_encoder.go index 790114e4c0..2a6f288a5d 100644 --- a/core/services/relay/evm/cap_encoder.go +++ b/core/services/relay/evm/cap_encoder.go @@ -10,7 +10,9 @@ import ( consensustypes "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3/types" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/values" + abiutil "github.com/smartcontractkit/chainlink/v2/core/chains/evm/abi" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -47,7 +49,7 @@ func NewEVMEncoder(config *values.Map) (consensustypes.Encoder, error) { codecConfig := types.CodecConfig{Configs: map[string]types.ChainCodecConfig{ encoderName: {TypeABI: string(jsonSelector)}, }} - c, err := NewCodec(codecConfig) + c, err := codec.NewCodec(codecConfig) if err != nil { return nil, err } diff --git a/core/services/relay/evm/chain_reader.go b/core/services/relay/evm/chain_reader.go index 0f1f6e72dd..c9cc18e34a 100644 --- a/core/services/relay/evm/chain_reader.go +++ b/core/services/relay/evm/chain_reader.go @@ -7,12 +7,12 @@ import ( "reflect" "slices" "strings" - "sync" "time" "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/chainlink-common/pkg/codec" + commoncodec "github.com/smartcontractkit/chainlink-common/pkg/codec" "github.com/smartcontractkit/chainlink-common/pkg/logger" commonservices "github.com/smartcontractkit/chainlink-common/pkg/services" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" @@ -23,6 +23,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/services" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/read" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -32,13 +34,13 @@ type ChainReaderService interface { } type chainReader struct { - lggr logger.Logger - ht logpoller.HeadTracker - lp logpoller.LogPoller - client evmclient.Client - parsed *ParsedTypes - bindings - codec commontypes.RemoteCodec + lggr logger.Logger + ht logpoller.HeadTracker + lp logpoller.LogPoller + client evmclient.Client + parsed *codec.ParsedTypes + bindings *read.BindingsRegistry + codec commontypes.RemoteCodec commonservices.StateMachine } @@ -53,8 +55,8 @@ func NewChainReaderService(ctx context.Context, lggr logger.Logger, lp logpoller ht: ht, lp: lp, client: client, - bindings: bindings{contractBindings: make(map[string]*contractBinding)}, - parsed: &ParsedTypes{EncoderDefs: map[string]types.CodecEntry{}, DecoderDefs: map[string]types.CodecEntry{}}, + bindings: read.NewBindingsRegistry(), + parsed: &codec.ParsedTypes{EncoderDefs: map[string]types.CodecEntry{}, DecoderDefs: map[string]types.CodecEntry{}}, } var err error @@ -66,21 +68,16 @@ func NewChainReaderService(ctx context.Context, lggr logger.Logger, lp logpoller return nil, err } - cr.bindings.BatchCaller = NewDynamicLimitedBatchCaller( + cr.bindings.SetBatchCaller(read.NewDynamicLimitedBatchCaller( cr.lggr, cr.codec, cr.client, - DefaultRpcBatchSizeLimit, - DefaultRpcBatchBackOffMultiplier, - DefaultMaxParallelRpcCalls, - ) - - err = cr.bindings.ForEach(ctx, func(c context.Context, cb *contractBinding) error { - for _, rb := range cb.readBindings { - rb.SetCodec(cr.codec) - } - return nil - }) + read.DefaultRpcBatchSizeLimit, + read.DefaultRpcBatchBackOffMultiplier, + read.DefaultMaxParallelRpcCalls, + )) + + cr.bindings.SetCodecAll(cr.codec) return cr, err } @@ -129,10 +126,13 @@ func (cr *chainReader) init(chainContractReaders map[string]types.ChainContractR } } - if cr.bindings.contractBindings[contractName] == nil { + if !cr.bindings.HasContractBinding(contractName) { return fmt.Errorf("%w: no read bindings added for contract: %s", commontypes.ErrInvalidConfig, contractName) } - cr.bindings.contractBindings[contractName].pollingFilter = chainContractReader.PollingFilter.ToLPFilter(eventSigsForContractFilter) + + if err := cr.bindings.SetFilter(contractName, chainContractReader.PollingFilter.ToLPFilter(eventSigsForContractFilter)); err != nil { + return err + } } return nil } @@ -142,14 +142,7 @@ func (cr *chainReader) Name() string { return cr.lggr.Name() } // Start registers polling filters if contracts are already bound. func (cr *chainReader) Start(ctx context.Context) error { return cr.StartOnce("ChainReader", func() error { - return cr.bindings.ForEach(ctx, func(c context.Context, cb *contractBinding) error { - for _, rb := range cb.readBindings { - if err := rb.Register(ctx); err != nil { - return err - } - } - return cb.Register(ctx, cr.lp) - }) + return cr.bindings.RegisterAll(ctx, cr.lp) }) } @@ -158,14 +151,8 @@ func (cr *chainReader) Close() error { return cr.StopOnce("ChainReader", func() error { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() - return cr.bindings.ForEach(ctx, func(c context.Context, cb *contractBinding) error { - for _, rb := range cb.readBindings { - if err := rb.Unregister(ctx); err != nil { - return err - } - } - return cb.Unregister(ctx, cr.lp) - }) + + return cr.bindings.UnregisterAll(ctx, cr.lp) }) } @@ -175,13 +162,13 @@ func (cr *chainReader) HealthReport() map[string]error { return map[string]error{cr.Name(): nil} } -func (cr *chainReader) GetLatestValue(ctx context.Context, contractName, method string, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) error { - b, err := cr.bindings.GetReadBinding(contractName, method) +func (cr *chainReader) GetLatestValue(ctx context.Context, readName string, confidenceLevel primitives.ConfidenceLevel, params any, returnVal any) error { + binding, address, err := cr.bindings.GetReader(readName) if err != nil { return err } - return b.GetLatestValue(ctx, confidenceLevel, params, returnVal) + return binding.GetLatestValue(ctx, common.HexToAddress(address), confidenceLevel, params, returnVal) } func (cr *chainReader) BatchGetLatestValues(ctx context.Context, request commontypes.BatchGetLatestValuesRequest) (commontypes.BatchGetLatestValuesResult, error) { @@ -192,17 +179,27 @@ func (cr *chainReader) Bind(ctx context.Context, bindings []commontypes.BoundCon return cr.bindings.Bind(ctx, cr.lp, bindings) } -func (cr *chainReader) QueryKey(ctx context.Context, contractName string, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceDataType any) ([]commontypes.Sequence, error) { - b, err := cr.bindings.GetReadBinding(contractName, filter.Key) +func (cr *chainReader) Unbind(ctx context.Context, bindings []commontypes.BoundContract) error { + return cr.bindings.Unbind(ctx, cr.lp, bindings) +} + +func (cr *chainReader) QueryKey( + ctx context.Context, + contract commontypes.BoundContract, + filter query.KeyFilter, + limitAndSort query.LimitAndSort, + sequenceDataType any, +) ([]commontypes.Sequence, error) { + binding, address, err := cr.bindings.GetReader(contract.ReadIdentifier(filter.Key)) if err != nil { return nil, err } - return b.QueryKey(ctx, filter, limitAndSort, sequenceDataType) + return binding.QueryKey(ctx, common.HexToAddress(address), filter, limitAndSort, sequenceDataType) } -func (cr *chainReader) CreateContractType(contractName, itemType string, forEncoding bool) (any, error) { - return cr.codec.CreateType(WrapItemType(contractName, itemType, forEncoding), forEncoding) +func (cr *chainReader) CreateContractType(readIdentifier string, forEncoding bool) (any, error) { + return cr.codec.CreateType(cr.bindings.ReadTypeIdentifier(readIdentifier, forEncoding), forEncoding) } func WrapItemType(contractName, itemType string, isParams bool) string { @@ -227,14 +224,7 @@ func (cr *chainReader) addMethod( return err } - cr.bindings.AddReadBinding(contractName, methodName, &methodBinding{ - lggr: cr.lggr, - contractName: contractName, - method: methodName, - ht: cr.ht, - client: cr.client, - confirmationsMapping: confirmations, - }) + cr.bindings.AddReader(contractName, methodName, read.NewMethodBinding(contractName, methodName, cr.client, cr.ht, confirmations, cr.lggr)) if err := cr.addEncoderDef(contractName, methodName, method.Inputs, method.ID, chainReaderDefinition.InputModifications); err != nil { return err @@ -278,65 +268,49 @@ func (cr *chainReader) addEvent(contractName, eventName string, a abi.ABI, chain return err } - eb := &eventBinding{ - contractName: contractName, - eventName: eventName, - lp: cr.lp, - hash: event.ID, - inputInfo: inputInfo, - inputModifier: inputModifier, - codecTopicInfo: codecTopicInfo, - topics: make(map[string]topicDetail), - eventDataWords: make(map[string]uint8), - confirmationsMapping: confirmations, - } - + eb := read.NewEventBinding(contractName, eventName, cr.lp, event.ID, inputInfo, inputModifier, codecTopicInfo, confirmations) if eventDefinitions := chainReaderDefinition.EventDefinitions; eventDefinitions != nil { if eventDefinitions.PollingFilter != nil { - eb.filterRegisterer = &filterRegisterer{ - pollingFilter: eventDefinitions.PollingFilter.ToLPFilter(evmtypes.HashArray{a.Events[event.Name].ID}), - filterLock: sync.Mutex{}, - } + eb.SetFilter(eventDefinitions.PollingFilter.ToLPFilter(evmtypes.HashArray{a.Events[event.Name].ID})) } if eventDefinitions.GenericDataWordNames != nil { - eb.eventDataWords = eventDefinitions.GenericDataWordNames + eb.SetDataWords(eventDefinitions.GenericDataWordNames) } cr.addQueryingReadBindings(contractName, eventDefinitions.GenericTopicNames, event.Inputs, eb) } - cr.bindings.AddReadBinding(contractName, eventName, eb) + cr.bindings.AddReader(contractName, eventName, eb) return cr.addDecoderDef(contractName, eventName, event.Inputs, chainReaderDefinition.OutputModifications) } // addQueryingReadBindings reuses the eventBinding and maps it to topic and dataWord keys used for QueryKey. -func (cr *chainReader) addQueryingReadBindings(contractName string, genericTopicNames map[string]string, eventInputs abi.Arguments, eb *eventBinding) { +func (cr *chainReader) addQueryingReadBindings(contractName string, genericTopicNames map[string]string, eventInputs abi.Arguments, eb *read.EventBinding) { // add topic readBindings for QueryKey for topicIndex, topic := range eventInputs { genericTopicName, ok := genericTopicNames[topic.Name] if ok { - eb.topics[genericTopicName] = topicDetail{ - Argument: topic, - Index: uint64(topicIndex), - } + eb.WithTopic(genericTopicName, topic, uint64(topicIndex)) } - cr.bindings.AddReadBinding(contractName, genericTopicName, eb) + + cr.bindings.AddReader(contractName, genericTopicName, eb) } // add data word readBindings for QueryKey - for genericDataWordName := range eb.eventDataWords { - cr.bindings.AddReadBinding(contractName, genericDataWordName, eb) + for genericDataWordName := range eb.GetDataWords() { + cr.bindings.AddReader(contractName, genericDataWordName, eb) } } // getEventInput returns codec entry for expected incoming event params and the modifier to be applied to the params. func (cr *chainReader) getEventInput(def types.ChainReaderDefinition, contractName, eventName string) ( - types.CodecEntry, codec.Modifier, error) { + types.CodecEntry, commoncodec.Modifier, error) { inputInfo := cr.parsed.EncoderDefs[WrapItemType(contractName, eventName, true)] + // TODO can this be simplified? Isn't this same as inputInfo.Modifier()? BCI-3909 - inMod, err := def.InputModifications.ToModifier(DecoderHooks...) + inMod, err := def.InputModifications.ToModifier(codec.DecoderHooks...) if err != nil { return nil, nil, err } @@ -349,18 +323,9 @@ func (cr *chainReader) getEventInput(def types.ChainReaderDefinition, contractNa return inputInfo, inMod, nil } -func verifyEventIndexedInputsUsed(eventName string, inputFields []string, indexArgNames map[string]bool) error { - for _, value := range inputFields { - if !indexArgNames[abi.ToCamelCase(value)] { - return fmt.Errorf("%w: %s is not an indexed argument of event %s", commontypes.ErrInvalidConfig, value, eventName) - } - } - return nil -} - -func (cr *chainReader) addEncoderDef(contractName, itemType string, args abi.Arguments, prefix []byte, inputModifications codec.ModifiersConfig) error { +func (cr *chainReader) addEncoderDef(contractName, itemType string, args abi.Arguments, prefix []byte, inputModifications commoncodec.ModifiersConfig) error { // ABI.Pack prepends the method.ID to the encodings, we'll need the encoder to do the same. - inputMod, err := inputModifications.ToModifier(DecoderHooks...) + inputMod, err := inputModifications.ToModifier(codec.DecoderHooks...) if err != nil { return err } @@ -374,16 +339,25 @@ func (cr *chainReader) addEncoderDef(contractName, itemType string, args abi.Arg return nil } -func (cr *chainReader) addDecoderDef(contractName, itemType string, outputs abi.Arguments, outputModifications codec.ModifiersConfig) error { - mod, err := outputModifications.ToModifier(DecoderHooks...) +func (cr *chainReader) addDecoderDef(contractName, itemType string, outputs abi.Arguments, outputModifications commoncodec.ModifiersConfig) error { + mod, err := outputModifications.ToModifier(codec.DecoderHooks...) if err != nil { return err } output := types.NewCodecEntry(outputs, nil, mod) - cr.parsed.DecoderDefs[WrapItemType(contractName, itemType, false)] = output + cr.parsed.DecoderDefs[read.WrapItemType(contractName, itemType, false)] = output return output.Init() } +func verifyEventIndexedInputsUsed(eventName string, inputFields []string, indexArgNames map[string]bool) error { + for _, value := range inputFields { + if !indexArgNames[abi.ToCamelCase(value)] { + return fmt.Errorf("%w: %s is not an indexed argument of event %s", commontypes.ErrInvalidConfig, value, eventName) + } + } + return nil +} + // setupEventInput returns abi args where indexed flag is set to false because we expect caller to filter with params that aren't hashed. // codecEntry has expected onchain types set, for e.g. indexed topics of type string or uint8[32] array are expected as common.Hash onchain. func setupEventInput(event abi.Event, inputFields []string) ([]abi.Argument, types.CodecEntry, map[string]bool) { @@ -441,12 +415,3 @@ func ConfirmationsFromConfig(values map[string]int) (map[primitives.ConfidenceLe return mappings, nil } - -// confidenceToConfirmations matches predefined chain agnostic confidence levels to predefined EVM finality. -func confidenceToConfirmations(confirmationsMapping map[primitives.ConfidenceLevel]evmtypes.Confirmations, confidenceLevel primitives.ConfidenceLevel) (evmtypes.Confirmations, error) { - confirmations, exists := confirmationsMapping[confidenceLevel] - if !exists { - return 0, fmt.Errorf("missing mapping for confidence level: %s", confidenceLevel) - } - return confirmations, nil -} diff --git a/core/services/relay/evm/chain_reader_historical_client_wrapper_test.go b/core/services/relay/evm/chain_reader_historical_client_wrapper_test.go index a3ea97650e..6779b5d020 100644 --- a/core/services/relay/evm/chain_reader_historical_client_wrapper_test.go +++ b/core/services/relay/evm/chain_reader_historical_client_wrapper_test.go @@ -17,6 +17,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/read" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -30,7 +32,7 @@ type ClientWithContractHistory struct { func (cwh *ClientWithContractHistory) Init(_ context.Context, config types.ChainReaderConfig) error { cwh.valsWithCall = make(map[int64]valWithCall) - parsedTypes := ParsedTypes{ + parsedTypes := codec.ParsedTypes{ EncoderDefs: make(map[string]types.CodecEntry), DecoderDefs: make(map[string]types.CodecEntry), } @@ -47,12 +49,12 @@ func (cwh *ClientWithContractHistory) Init(_ context.Context, config types.Chain continue } - inputMod, err := readDef.InputModifications.ToModifier(DecoderHooks...) + inputMod, err := readDef.InputModifications.ToModifier(codec.DecoderHooks...) if err != nil { return err } - outputMod, err := readDef.OutputModifications.ToModifier(DecoderHooks...) + outputMod, err := readDef.OutputModifications.ToModifier(codec.DecoderHooks...) if err != nil { return err } @@ -67,16 +69,18 @@ func (cwh *ClientWithContractHistory) Init(_ context.Context, config types.Chain return err } - parsedTypes.EncoderDefs[WrapItemType(contractName, genericName, true)] = input - parsedTypes.DecoderDefs[WrapItemType(contractName, genericName, false)] = output + parsedTypes.EncoderDefs[read.WrapItemType(contractName, genericName, true)] = input + parsedTypes.DecoderDefs[read.WrapItemType(contractName, genericName, false)] = output } } - codec, err := parsedTypes.ToCodec() + parsedCodec, err := parsedTypes.ToCodec() if err != nil { return err } - cwh.codec = codec + + cwh.codec = parsedCodec + return nil } @@ -122,7 +126,7 @@ func (cwh *ClientWithContractHistory) CallContract(ctx context.Context, msg ethe } // encode the expected call to compare with the actual call - dataToCmp, err := cwh.codec.Encode(ctx, valAndCall.Params, WrapItemType(valAndCall.ContractName, valAndCall.ReadName, true)) + dataToCmp, err := cwh.codec.Encode(ctx, valAndCall.Params, read.WrapItemType(valAndCall.ContractName, valAndCall.ReadName, true)) if err != nil { return nil, err } diff --git a/core/services/relay/evm/chain_writer.go b/core/services/relay/evm/chain_writer.go index 1e07003b88..fddd865dbb 100644 --- a/core/services/relay/evm/chain_writer.go +++ b/core/services/relay/evm/chain_writer.go @@ -20,6 +20,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" evmtxmgr "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/services" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -45,7 +46,7 @@ func NewChainWriterService(logger logger.Logger, client evmclient.Client, txm ev sendStrategy: txmgr.NewSendEveryStrategy(), contracts: config.Contracts, - parsedContracts: &ParsedTypes{EncoderDefs: map[string]types.CodecEntry{}, DecoderDefs: map[string]types.CodecEntry{}}, + parsedContracts: &codec.ParsedTypes{EncoderDefs: map[string]types.CodecEntry{}, DecoderDefs: map[string]types.CodecEntry{}}, } if config.SendStrategy != nil { @@ -75,7 +76,7 @@ type chainWriter struct { sendStrategy txmgrtypes.TxStrategy contracts map[string]*types.ContractConfig - parsedContracts *ParsedTypes + parsedContracts *codec.ParsedTypes encoder commontypes.Encoder } @@ -161,7 +162,7 @@ func (w *chainWriter) parseContracts() error { } // ABI.Pack prepends the method.ID to the encodings, we'll need the encoder to do the same. - inputMod, err := methodConfig.InputModifications.ToModifier(DecoderHooks...) + inputMod, err := methodConfig.InputModifications.ToModifier(codec.DecoderHooks...) if err != nil { return fmt.Errorf("%w: failed to create input mods", err) } diff --git a/core/services/relay/evm/codec.go b/core/services/relay/evm/codec/codec.go similarity index 92% rename from core/services/relay/evm/codec.go rename to core/services/relay/evm/codec/codec.go index 45810bb1ab..5cd606755c 100644 --- a/core/services/relay/evm/codec.go +++ b/core/services/relay/evm/codec/codec.go @@ -1,4 +1,4 @@ -package evm +package codec import ( "encoding/json" @@ -11,8 +11,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/go-viper/mapstructure/v2" - "github.com/smartcontractkit/chainlink-common/pkg/codec" - + commoncodec "github.com/smartcontractkit/chainlink-common/pkg/codec" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" @@ -33,10 +32,10 @@ import ( // it was a *big.Int var DecoderHooks = []mapstructure.DecodeHookFunc{ decodeAccountAndAllowArraySliceHook, - codec.BigIntHook, - codec.SliceToArrayVerifySizeHook, + commoncodec.BigIntHook, + commoncodec.SliceToArrayVerifySizeHook, sizeVerifyBigIntHook, - codec.NumberHook, + commoncodec.NumberHook, } // NewCodec creates a new [commontypes.RemoteCodec] for EVM. @@ -103,7 +102,7 @@ func sizeVerifyBigIntHook(from, to reflect.Type, data any) (any, error) { if from.Implements(types.SizedBigIntType()) && !to.Implements(types.SizedBigIntType()) && !reflect.PointerTo(to).Implements(types.SizedBigIntType()) { - return codec.BigIntHook(from, bigIntType, reflect.ValueOf(data).Convert(bigIntType).Interface()) + return commoncodec.BigIntHook(from, bigIntType, reflect.ValueOf(data).Convert(bigIntType).Interface()) } if !to.Implements(types.SizedBigIntType()) { @@ -111,7 +110,7 @@ func sizeVerifyBigIntHook(from, to reflect.Type, data any) (any, error) { } var err error - data, err = codec.BigIntHook(from, bigIntType, data) + data, err = commoncodec.BigIntHook(from, bigIntType, data) if err != nil { return nil, err } diff --git a/core/services/relay/evm/codec_fuzz_test.go b/core/services/relay/evm/codec/codec_fuzz_test.go similarity index 92% rename from core/services/relay/evm/codec_fuzz_test.go rename to core/services/relay/evm/codec/codec_fuzz_test.go index 5870e9d77a..1b65a1bc29 100644 --- a/core/services/relay/evm/codec_fuzz_test.go +++ b/core/services/relay/evm/codec/codec_fuzz_test.go @@ -1,4 +1,4 @@ -package evm_test +package codec_test import ( "testing" diff --git a/core/services/relay/evm/codec_test.go b/core/services/relay/evm/codec/codec_test.go similarity index 96% rename from core/services/relay/evm/codec_test.go rename to core/services/relay/evm/codec/codec_test.go index af3170abf0..d43f118010 100644 --- a/core/services/relay/evm/codec_test.go +++ b/core/services/relay/evm/codec/codec_test.go @@ -1,4 +1,4 @@ -package evm_test +package codec_test import ( "encoding/json" @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-common/pkg/codec" + commoncodec "github.com/smartcontractkit/chainlink-common/pkg/codec" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/evmtesting" looptestutils "github.com/smartcontractkit/chainlink-common/pkg/loop/testutils" //nolint common practice to import test mods with . @@ -21,7 +21,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/chain_reader_tester" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -45,7 +45,7 @@ func TestCodec(t *testing.T) { codecConfig := types.CodecConfig{Configs: map[string]types.ChainCodecConfig{ codecName: {TypeABI: evmEncoderConfig}, }} - c, err := evm.NewCodec(codecConfig) + c, err := codec.NewCodec(codecConfig) require.NoError(t, err) result, err := c.Encode(testutils.Context(t), encode, codecName) @@ -91,7 +91,7 @@ func TestCodec_SimpleEncode(t *testing.T) { codecConfig := types.CodecConfig{Configs: map[string]types.ChainCodecConfig{ codecName: {TypeABI: evmEncoderConfig}, }} - c, err := evm.NewCodec(codecConfig) + c, err := codec.NewCodec(codecConfig) require.NoError(t, err) result, err := c.Encode(testutils.Context(t), input, codecName) @@ -120,7 +120,7 @@ func TestCodec_EncodeTuple(t *testing.T) { codecConfig := types.CodecConfig{Configs: map[string]types.ChainCodecConfig{ codecName: {TypeABI: evmEncoderConfig}, }} - c, err := evm.NewCodec(codecConfig) + c, err := codec.NewCodec(codecConfig) require.NoError(t, err) result, err := c.Encode(testutils.Context(t), input, codecName) @@ -152,7 +152,7 @@ func TestCodec_EncodeTupleWithLists(t *testing.T) { codecConfig := types.CodecConfig{Configs: map[string]types.ChainCodecConfig{ codecName: {TypeABI: evmEncoderConfig}, }} - c, err := evm.NewCodec(codecConfig) + c, err := codec.NewCodec(codecConfig) require.NoError(t, err) result, err := c.Encode(testutils.Context(t), input, codecName) @@ -204,13 +204,13 @@ func (it *codecInterfaceTester) GetCodec(t *testing.T) commontypes.Codec { entry.TypeABI = string(defBytes) if k != sizeItemType && k != NilType { - entry.ModifierConfigs = codec.ModifiersConfig{ - &codec.RenameModifierConfig{Fields: map[string]string{"NestedStruct.Inner.IntVal": "I"}}, + entry.ModifierConfigs = commoncodec.ModifiersConfig{ + &commoncodec.RenameModifierConfig{Fields: map[string]string{"NestedStruct.Inner.IntVal": "I"}}, } } if k == TestItemWithConfigExtra { - hardCode := &codec.HardCodeModifierConfig{ + hardCode := &commoncodec.HardCodeModifierConfig{ OnChainValues: map[string]any{ "BigField": testStruct.BigField.String(), "Account": hexutil.Encode(testStruct.Account), @@ -222,7 +222,7 @@ func (it *codecInterfaceTester) GetCodec(t *testing.T) commontypes.Codec { codecConfig.Configs[k] = entry } - c, err := evm.NewCodec(codecConfig) + c, err := codec.NewCodec(codecConfig) require.NoError(t, err) return c } diff --git a/core/services/relay/evm/decoder.go b/core/services/relay/evm/codec/decoder.go similarity index 94% rename from core/services/relay/evm/decoder.go rename to core/services/relay/evm/codec/decoder.go index e86ade3ac7..70c0f1d668 100644 --- a/core/services/relay/evm/decoder.go +++ b/core/services/relay/evm/codec/decoder.go @@ -1,4 +1,4 @@ -package evm +package codec import ( "context" @@ -45,7 +45,7 @@ func (m *decoder) Decode(_ context.Context, raw []byte, into any, itemType strin iInto.Set(reflect.MakeSlice(iInto.Type(), length, length)) return setElements(length, rDecode, iInto) default: - return mapstructureDecode(decode, into) + return MapstructureDecode(decode, into) } } @@ -83,7 +83,7 @@ func extractDecoding(info types.CodecEntry, raw []byte) (any, error) { func setElements(length int, rDecode reflect.Value, iInto reflect.Value) error { for i := 0; i < length; i++ { - if err := mapstructureDecode(rDecode.Index(i).Interface(), iInto.Index(i).Addr().Interface()); err != nil { + if err := MapstructureDecode(rDecode.Index(i).Interface(), iInto.Index(i).Addr().Interface()); err != nil { return err } } @@ -91,7 +91,7 @@ func setElements(length int, rDecode reflect.Value, iInto reflect.Value) error { return nil } -func mapstructureDecode(src, dest any) error { +func MapstructureDecode(src, dest any) error { mDecoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ DecodeHook: mapstructure.ComposeDecodeHookFunc(DecoderHooks...), Result: dest, diff --git a/core/services/relay/evm/encoder.go b/core/services/relay/evm/codec/encoder.go similarity index 90% rename from core/services/relay/evm/encoder.go rename to core/services/relay/evm/codec/encoder.go index ae60e4ab35..b7facde328 100644 --- a/core/services/relay/evm/encoder.go +++ b/core/services/relay/evm/codec/encoder.go @@ -1,4 +1,4 @@ -package evm +package codec import ( "context" @@ -52,13 +52,13 @@ func encode(item reflect.Value, info types.CodecEntry) ([]byte, error) { } switch item.Kind() { case reflect.Array, reflect.Slice: - native, err := representArray(item, info) + native, err := RepresentArray(item, info) if err != nil { return nil, err } return pack(info, native) case reflect.Struct, reflect.Map: - values, err := unrollItem(item, info) + values, err := UnrollItem(item, info) if err != nil { return nil, err } @@ -68,7 +68,7 @@ func encode(item reflect.Value, info types.CodecEntry) ([]byte, error) { } } -func representArray(item reflect.Value, info types.CodecEntry) (any, error) { +func RepresentArray(item reflect.Value, info types.CodecEntry) (any, error) { length := item.Len() checkedType := info.CheckedType() checked := reflect.New(checkedType) @@ -87,7 +87,7 @@ func representArray(item reflect.Value, info types.CodecEntry) (any, error) { checkedElm := checkedType.Elem() for i := 0; i < length; i++ { tmp := reflect.New(checkedElm) - if err := mapstructureDecode(item.Index(i).Interface(), tmp.Interface()); err != nil { + if err := MapstructureDecode(item.Index(i).Interface(), tmp.Interface()); err != nil { return nil, err } iChecked.Index(i).Set(tmp.Elem()) @@ -100,7 +100,7 @@ func representArray(item reflect.Value, info types.CodecEntry) (any, error) { return native.Elem().Interface(), nil } -func unrollItem(item reflect.Value, info types.CodecEntry) ([]any, error) { +func UnrollItem(item reflect.Value, info types.CodecEntry) ([]any, error) { checkedType := info.CheckedType() if item.CanAddr() { item = item.Addr() @@ -114,7 +114,7 @@ func unrollItem(item reflect.Value, info types.CodecEntry) ([]any, error) { } else if !info.IsNativePointer(item.Type()) { var err error checked := reflect.New(checkedType) - if err = mapstructureDecode(item.Interface(), checked.Interface()); err != nil { + if err = MapstructureDecode(item.Interface(), checked.Interface()); err != nil { return nil, err } if item, err = info.ToNative(checked); err != nil { diff --git a/core/services/relay/evm/parsed_types.go b/core/services/relay/evm/codec/parsed_types.go similarity index 80% rename from core/services/relay/evm/parsed_types.go rename to core/services/relay/evm/codec/parsed_types.go index 902c182e1d..31c95caf4d 100644 --- a/core/services/relay/evm/parsed_types.go +++ b/core/services/relay/evm/codec/parsed_types.go @@ -1,10 +1,10 @@ -package evm +package codec import ( "fmt" "reflect" - "github.com/smartcontractkit/chainlink-common/pkg/codec" + commoncodec "github.com/smartcontractkit/chainlink-common/pkg/codec" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" @@ -16,7 +16,7 @@ type ParsedTypes struct { } func (parsed *ParsedTypes) ToCodec() (commontypes.RemoteCodec, error) { - modByTypeName := map[string]codec.Modifier{} + modByTypeName := map[string]commoncodec.Modifier{} if err := AddEntries(parsed.EncoderDefs, modByTypeName); err != nil { return nil, err } @@ -24,7 +24,7 @@ func (parsed *ParsedTypes) ToCodec() (commontypes.RemoteCodec, error) { return nil, err } - mod, err := codec.NewByItemTypeModifier(modByTypeName) + mod, err := commoncodec.NewByItemTypeModifier(modByTypeName) if err != nil { return nil, err } @@ -33,12 +33,12 @@ func (parsed *ParsedTypes) ToCodec() (commontypes.RemoteCodec, error) { decoder: &decoder{Definitions: parsed.DecoderDefs}, ParsedTypes: parsed, } - return codec.NewModifierCodec(underlying, mod, DecoderHooks...) + return commoncodec.NewModifierCodec(underlying, mod, DecoderHooks...) } // AddEntries extracts the mods from codecEntry and adds them to modByTypeName use with codec.NewByItemTypeModifier // Since each input/output can have its own modifications, we need to keep track of them by type name -func AddEntries(defs map[string]types.CodecEntry, modByTypeName map[string]codec.Modifier) error { +func AddEntries(defs map[string]types.CodecEntry, modByTypeName map[string]commoncodec.Modifier) error { for k, def := range defs { modByTypeName[k] = def.Modifier() _, err := def.Modifier().RetypeToOffChain(reflect.PointerTo(def.CheckedType()), k) diff --git a/core/services/relay/evm/contract_binding.go b/core/services/relay/evm/contract_binding.go deleted file mode 100644 index da2d7ed9bd..0000000000 --- a/core/services/relay/evm/contract_binding.go +++ /dev/null @@ -1,100 +0,0 @@ -package evm - -import ( - "context" - "fmt" - "sync" - - "github.com/ethereum/go-ethereum/common" - "github.com/google/uuid" - - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" -) - -type filterRegisterer struct { - pollingFilter logpoller.Filter - filterLock sync.Mutex - // registerCalled is used to determine if Register was called during Chain Reader service Start. - // This is done to avoid calling Register while the service is not running because log poller is most likely also not running. - registerCalled bool -} - -// contractBinding stores read bindings and manages the common contract event filter. -type contractBinding struct { - name string - // filterRegisterer is used to manage polling filter registration for the common contract filter. - // The common contract filter should be used by events that share filtering args. - filterRegisterer - // key is read name method, event or event keys used for queryKey. - readBindings map[string]readBinding - // bound determines if address is set to the contract binding. - bound bool - bindLock sync.Mutex -} - -// Bind binds contract addresses to contract binding and registers the common contract polling filter. -func (cb *contractBinding) Bind(ctx context.Context, lp logpoller.LogPoller, boundContract commontypes.BoundContract) error { - // it's enough to just lock bound here since Register/Unregister are only called from here and from Start/Close - // even if they somehow happen at the same time it will be fine because of filter lock and hasFilter check - cb.bindLock.Lock() - defer cb.bindLock.Unlock() - - if cb.bound { - // we are changing contract address reference, so we need to unregister old filter it exists - if err := cb.Unregister(ctx, lp); err != nil { - return err - } - } - - cb.pollingFilter.Addresses = evmtypes.AddressArray{common.HexToAddress(boundContract.Address)} - cb.pollingFilter.Name = logpoller.FilterName(boundContract.Name+"."+uuid.NewString(), boundContract.Address) - cb.bound = true - - if cb.registerCalled { - return cb.Register(ctx, lp) - } - - return nil -} - -// Register registers the common contract filter. -func (cb *contractBinding) Register(ctx context.Context, lp logpoller.LogPoller) error { - cb.filterLock.Lock() - defer cb.filterLock.Unlock() - - cb.registerCalled = true - // can't be true before filters params are set so there is no race with a bad filter outcome - if !cb.bound { - return nil - } - - if len(cb.pollingFilter.EventSigs) > 0 && !lp.HasFilter(cb.pollingFilter.Name) { - if err := lp.RegisterFilter(ctx, cb.pollingFilter); err != nil { - return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) - } - } - - return nil -} - -// Unregister unregisters the common contract filter. -func (cb *contractBinding) Unregister(ctx context.Context, lp logpoller.LogPoller) error { - cb.filterLock.Lock() - defer cb.filterLock.Unlock() - - if !cb.bound { - return nil - } - - if !lp.HasFilter(cb.pollingFilter.Name) { - return nil - } - - if err := lp.UnregisterFilter(ctx, cb.pollingFilter.Name); err != nil { - return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) - } - - return nil -} diff --git a/core/services/relay/evm/event_binding.go b/core/services/relay/evm/event_binding.go deleted file mode 100644 index ae67fae9fc..0000000000 --- a/core/services/relay/evm/event_binding.go +++ /dev/null @@ -1,476 +0,0 @@ -package evm - -import ( - "context" - "fmt" - "reflect" - "strings" - "sync" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/google/uuid" - - "github.com/smartcontractkit/chainlink-common/pkg/codec" - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/smartcontractkit/chainlink-common/pkg/types/query" - "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" -) - -type eventBinding struct { - address common.Address - contractName string - eventName string - lp logpoller.LogPoller - // filterRegisterer in eventBinding is to be used as an override for lp filter defined in the contract binding. - // If filterRegisterer is nil, this event should be registered with the lp filter defined in the contract binding. - *filterRegisterer - hash common.Hash - codec commontypes.RemoteCodec - // bound determines if address is set to the contract binding. - bound bool - bindLock sync.Mutex - inputInfo types.CodecEntry - inputModifier codec.Modifier - codecTopicInfo types.CodecEntry - // topics maps a generic topic name (key) to topic data - topics map[string]topicDetail - // eventDataWords maps a generic name to a word index - // key is a predefined generic name for evm log event data word - // for e.g. first evm data word(32bytes) of USDC log event is value so the key can be called value - eventDataWords map[string]uint8 - confirmationsMapping map[primitives.ConfidenceLevel]evmtypes.Confirmations -} - -type topicDetail struct { - abi.Argument - Index uint64 -} - -var _ readBinding = &eventBinding{} - -func (e *eventBinding) SetCodec(codec commontypes.RemoteCodec) { - e.codec = codec -} - -func (e *eventBinding) Bind(ctx context.Context, binding commontypes.BoundContract) error { - // it's enough to just lock bound here since Register/Unregister are only called from here and from Start/Close - // even if they somehow happen at the same time it will be fine because of filter lock and hasFilter check - e.bindLock.Lock() - defer e.bindLock.Unlock() - - if e.bound { - // we are changing contract address reference, so we need to unregister old filter it exists - if err := e.Unregister(ctx); err != nil { - return err - } - } - - e.address = common.HexToAddress(binding.Address) - - // filterRegisterer isn't required here because the event can also be polled for by the contractBinding common filter. - if e.filterRegisterer != nil { - id := fmt.Sprintf("%s.%s.%s", e.contractName, e.eventName, uuid.NewString()) - e.pollingFilter.Name = logpoller.FilterName(id, e.address) - e.pollingFilter.Addresses = evmtypes.AddressArray{e.address} - e.bound = true - if e.registerCalled { - return e.Register(ctx) - } - } - e.bound = true - return nil -} - -func (e *eventBinding) Register(ctx context.Context) error { - if e.filterRegisterer == nil { - return nil - } - - e.filterLock.Lock() - defer e.filterLock.Unlock() - - e.registerCalled = true - // can't be true before filters params are set so there is no race with a bad filter outcome - if !e.bound { - return nil - } - - if e.lp.HasFilter(e.pollingFilter.Name) { - return nil - } - - if err := e.lp.RegisterFilter(ctx, e.pollingFilter); err != nil { - return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) - } - - return nil -} - -func (e *eventBinding) Unregister(ctx context.Context) error { - if e.filterRegisterer == nil { - return nil - } - - e.filterLock.Lock() - defer e.filterLock.Unlock() - - if !e.bound { - return nil - } - - if !e.lp.HasFilter(e.pollingFilter.Name) { - return nil - } - - if err := e.lp.UnregisterFilter(ctx, e.pollingFilter.Name); err != nil { - return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) - } - - return nil -} - -func (e *eventBinding) GetLatestValue(ctx context.Context, confidenceLevel primitives.ConfidenceLevel, params, into any) error { - if err := e.validateBound(); err != nil { - return err - } - - confirmations, err := confidenceToConfirmations(e.confirmationsMapping, confidenceLevel) - if err != nil { - return err - } - - if len(e.inputInfo.Args()) == 0 { - return e.getLatestValueWithoutFilters(ctx, confirmations, into) - } - - return e.getLatestValueWithFilters(ctx, confirmations, params, into) -} - -func (e *eventBinding) QueryKey(ctx context.Context, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceDataType any) ([]commontypes.Sequence, error) { - if err := e.validateBound(); err != nil { - return nil, err - } - - remapped, err := e.remap(filter) - if err != nil { - return nil, err - } - - // filter should always use the address and event sig - defaultExpressions := []query.Expression{ - logpoller.NewAddressFilter(e.address), - logpoller.NewEventSigFilter(e.hash), - } - remapped.Expressions = append(defaultExpressions, remapped.Expressions...) - - logs, err := e.lp.FilteredLogs(ctx, remapped.Expressions, limitAndSort, e.contractName+"-"+e.address.String()+"-"+e.eventName) - if err != nil { - return nil, err - } - - // no need to return an error. an empty list is fine - if len(logs) == 0 { - return []commontypes.Sequence{}, nil - } - - return e.decodeLogsIntoSequences(ctx, logs, sequenceDataType) -} - -func (e *eventBinding) validateBound() error { - if !e.bound { - return fmt.Errorf( - "%w: event %s that belongs to contract: %s, not bound", - commontypes.ErrInvalidType, - e.eventName, - e.contractName, - ) - } - return nil -} - -func (e *eventBinding) getLatestValueWithoutFilters(ctx context.Context, confs evmtypes.Confirmations, into any) error { - log, err := e.lp.LatestLogByEventSigWithConfs(ctx, e.hash, e.address, confs) - if err = wrapInternalErr(err); err != nil { - return err - } - - return e.decodeLog(ctx, log, into) -} - -func (e *eventBinding) getLatestValueWithFilters( - ctx context.Context, confs evmtypes.Confirmations, params, into any) error { - offChain, err := e.convertToOffChainType(params) - if err != nil { - return err - } - - // convert caller chain agnostic params types to types representing onchain abi types, for e.g. bytes32. - checkedParams, err := e.inputModifier.TransformToOnChain(offChain, "" /* unused */) - if err != nil { - return err - } - - // convert onchain params to native types similarly to generated abi wrappers, for e.g. fixed bytes32 abi type to [32]uint8. - nativeParams, err := e.inputInfo.ToNative(reflect.ValueOf(checkedParams)) - if err != nil { - return err - } - - filtersAndIndices, err := e.encodeParams(nativeParams) - if err != nil { - return err - } - - // Create limiter and filter for the query. - limiter := query.NewLimitAndSort(query.CountLimit(1), query.NewSortBySequence(query.Desc)) - filter, err := logpoller.Where( - logpoller.NewAddressFilter(e.address), - logpoller.NewEventSigFilter(e.hash), - logpoller.NewConfirmationsFilter(confs), - createTopicFilters(filtersAndIndices), - ) - if err != nil { - return wrapInternalErr(err) - } - - // Gets the latest log that matches the filter and limiter. - logs, err := e.lp.FilteredLogs(ctx, filter, limiter, e.contractName+"-"+e.address.String()+"-"+e.eventName) - if err != nil { - return wrapInternalErr(err) - } - - if len(logs) == 0 { - return fmt.Errorf("%w: no events found", commontypes.ErrNotFound) - } - - return e.decodeLog(ctx, &logs[0], into) -} - -func createTopicFilters(filtersAndIndices []common.Hash) query.Expression { - var expressions []query.Expression - for topicID, fai := range filtersAndIndices { - // first topic index is 1-based, so we add 1. - expressions = append(expressions, logpoller.NewEventByTopicFilter( - uint64(topicID+1), []primitives.ValueComparator{{Value: fai.Hex(), Operator: primitives.Eq}}, - )) - } - return query.And(expressions...) -} - -// convertToOffChainType creates a struct based on contract abi with applied codec modifiers. -// Created type shouldn't have hashed types for indexed topics since incoming params wouldn't be hashed. -func (e *eventBinding) convertToOffChainType(params any) (any, error) { - offChain, err := e.codec.CreateType(WrapItemType(e.contractName, e.eventName, true), true) - if err != nil { - return nil, err - } - - if err = mapstructureDecode(params, offChain); err != nil { - return nil, err - } - - return offChain, nil -} - -// encodeParams accepts nativeParams and encodes them to match onchain topics. -func (e *eventBinding) encodeParams(nativeParams reflect.Value) ([]common.Hash, error) { - for nativeParams.Kind() == reflect.Pointer { - nativeParams = reflect.Indirect(nativeParams) - } - - var params []any - switch nativeParams.Kind() { - case reflect.Array, reflect.Slice: - native, err := representArray(nativeParams, e.inputInfo) - if err != nil { - return nil, err - } - params = []any{native} - case reflect.Struct, reflect.Map: - var err error - if params, err = unrollItem(nativeParams, e.inputInfo); err != nil { - return nil, err - } - default: - return nil, fmt.Errorf("%w: cannot encode kind %v", commontypes.ErrInvalidType, nativeParams.Kind()) - } - - // abi params allow you to Pack a pointers, but makeTopics doesn't work with pointers. - if err := e.derefTopics(params); err != nil { - return nil, err - } - - return e.makeTopics(params) -} - -func (e *eventBinding) derefTopics(topics []any) error { - for i, topic := range topics { - rTopic := reflect.ValueOf(topic) - if rTopic.Kind() == reflect.Pointer { - if rTopic.IsNil() { - return fmt.Errorf( - "%w: input topic %s cannot be nil", commontypes.ErrInvalidType, e.inputInfo.Args()[i].Name) - } - topics[i] = rTopic.Elem().Interface() - } - } - return nil -} - -// makeTopics encodes and hashes params filtering values to match onchain indexed topics. -func (e *eventBinding) makeTopics(params []any) ([]common.Hash, error) { - // make topic value for non-fixed bytes array manually because geth MakeTopics doesn't support it - for i, topic := range params { - if abiArg := e.inputInfo.Args()[i]; abiArg.Type.T == abi.ArrayTy && (abiArg.Type.Elem != nil && abiArg.Type.Elem.T == abi.UintTy) { - packed, err := abi.Arguments{abiArg}.Pack(topic) - if err != nil { - return nil, err - } - params[i] = crypto.Keccak256Hash(packed) - } - } - - hashes, err := abi.MakeTopics(params) - if err != nil { - return nil, wrapInternalErr(err) - } - - if len(hashes) != 1 { - return nil, fmt.Errorf("%w: expected 1 filter set, got %d", commontypes.ErrInternal, len(hashes)) - } - - return hashes[0], nil -} - -func (e *eventBinding) decodeLog(ctx context.Context, log *logpoller.Log, into any) error { - // decode non indexed topics and apply output modifiers - if err := e.codec.Decode(ctx, log.Data, into, WrapItemType(e.contractName, e.eventName, false)); err != nil { - return err - } - - // decode indexed topics which is rarely useful since most indexed topic types get Keccak256 hashed and should be just used for log filtering. - topics := make([]common.Hash, len(e.codecTopicInfo.Args())) - if len(log.Topics) < len(topics)+1 { - return fmt.Errorf("%w: not enough topics to decode", commontypes.ErrInvalidType) - } - - for i := 0; i < len(topics); i++ { - topics[i] = common.Hash(log.Topics[i+1]) - } - - topicsInto := map[string]any{} - if err := abi.ParseTopicsIntoMap(topicsInto, e.codecTopicInfo.Args(), topics); err != nil { - return fmt.Errorf("%w: %w", commontypes.ErrInvalidType, err) - } - - return mapstructureDecode(topicsInto, into) -} - -func (e *eventBinding) decodeLogsIntoSequences(ctx context.Context, logs []logpoller.Log, into any) ([]commontypes.Sequence, error) { - sequences := make([]commontypes.Sequence, len(logs)) - - for idx := range logs { - sequences[idx] = commontypes.Sequence{ - Cursor: fmt.Sprintf("%s-%s-%d", logs[idx].BlockHash, logs[idx].TxHash, logs[idx].LogIndex), - Head: commontypes.Head{ - Identifier: fmt.Sprint(logs[idx].BlockNumber), - Hash: logs[idx].BlockHash.Bytes(), - Timestamp: uint64(logs[idx].BlockTimestamp.Unix()), - }, - } - - var typeVal reflect.Value - - typeInto := reflect.TypeOf(into) - if typeInto.Kind() == reflect.Pointer { - typeVal = reflect.New(typeInto.Elem()) - } else { - typeVal = reflect.Indirect(reflect.New(typeInto)) - } - - // create a new value of the same type as 'into' for the data to be extracted to - sequences[idx].Data = typeVal.Interface() - - if err := e.decodeLog(ctx, &logs[idx], sequences[idx].Data); err != nil { - return nil, err - } - } - - return sequences, nil -} - -func (e *eventBinding) remap(filter query.KeyFilter) (query.KeyFilter, error) { - remapped := query.KeyFilter{} - - for _, expression := range filter.Expressions { - remappedExpression, err := e.remapExpression(filter.Key, expression) - if err != nil { - return query.KeyFilter{}, err - } - - remapped.Expressions = append(remapped.Expressions, remappedExpression) - } - - return remapped, nil -} - -func (e *eventBinding) remapExpression(key string, expression query.Expression) (query.Expression, error) { - if !expression.IsPrimitive() { - remappedBoolExpressions := make([]query.Expression, len(expression.BoolExpression.Expressions)) - - for i := range expression.BoolExpression.Expressions { - remapped, err := e.remapExpression(key, expression.BoolExpression.Expressions[i]) - if err != nil { - return query.Expression{}, err - } - - remappedBoolExpressions[i] = remapped - } - - if expression.BoolExpression.BoolOperator == query.AND { - return query.And(remappedBoolExpressions...), nil - } - - return query.Or(remappedBoolExpressions...), nil - } - - return e.remapPrimitive(key, expression) -} - -// remap chain agnostic primitives to chain specific -func (e *eventBinding) remapPrimitive(key string, expression query.Expression) (query.Expression, error) { - switch primitive := expression.Primitive.(type) { - // TODO comparator primitive should undergo codec transformations and do hashed types handling similarly to how GetLatestValue handles it BCI-3910 - case *primitives.Comparator: - if val, ok := e.eventDataWords[primitive.Name]; ok { - return logpoller.NewEventByWordFilter(e.hash, val, primitive.ValueComparators), nil - } - return logpoller.NewEventByTopicFilter(e.topics[key].Index, primitive.ValueComparators), nil - case *primitives.Confidence: - confirmations, err := confidenceToConfirmations(e.confirmationsMapping, primitive.ConfidenceLevel) - if err != nil { - return query.Expression{}, err - } - return logpoller.NewConfirmationsFilter(confirmations), nil - default: - return expression, nil - } -} - -func wrapInternalErr(err error) error { - if err == nil { - return nil - } - - errStr := err.Error() - if strings.Contains(errStr, "not found") || strings.Contains(errStr, "no rows") { - return fmt.Errorf("%w: %w", commontypes.ErrNotFound, err) - } - return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) -} diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index f2b4cbc7a9..e708233fdc 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -49,6 +49,7 @@ import ( lloconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/llo/config" mercuryconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/functions" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" @@ -798,7 +799,7 @@ func (r *Relayer) NewMedianProvider(rargs commontypes.RelayArgs, pargs commontyp medianProvider.chainReader = chainReaderService if relayConfig.Codec != nil { - medianProvider.codec, err = NewCodec(*relayConfig.Codec) + medianProvider.codec, err = codec.NewCodec(*relayConfig.Codec) if err != nil { return nil, err } diff --git a/core/services/relay/evm/evmtesting/run_tests.go b/core/services/relay/evm/evmtesting/run_tests.go index 8aba7c1b05..85ed9f8675 100644 --- a/core/services/relay/evm/evmtesting/run_tests.go +++ b/core/services/relay/evm/evmtesting/run_tests.go @@ -13,7 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types" clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/read" . "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint common practice to import test mods with . ) @@ -33,21 +33,28 @@ func RunContractReaderEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfa ctx := it.Helper.Context(t) cr := it.GetChainReader(t) - require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) - contracts := it.GetBindings(t) + bindings := it.GetBindings(t) + require.NoError(t, cr.Bind(ctx, bindings)) + type DynamicEvent struct { Field string } - SubmitTransactionToCW(t, it, "triggerEventWithDynamicTopic", DynamicEvent{Field: anyString}, contracts[0], types.Unconfirmed) + SubmitTransactionToCW(t, it, "triggerEventWithDynamicTopic", DynamicEvent{Field: anyString}, bindings[0], types.Unconfirmed) input := struct{ Field string }{Field: anyString} tp := cr.(clcommontypes.ContractTypeProvider) - output, err := tp.CreateContractType(AnyContractName, triggerWithDynamicTopic, false) + + readName := types.BoundContract{ + Address: bindings[0].Address, + Name: AnyContractName, + }.ReadIdentifier(triggerWithDynamicTopic) + + output, err := tp.CreateContractType(readName, false) require.NoError(t, err) rOutput := reflect.Indirect(reflect.ValueOf(output)) require.Eventually(t, func() bool { - return cr.GetLatestValue(ctx, AnyContractName, triggerWithDynamicTopic, primitives.Unconfirmed, input, output) == nil + return cr.GetLatestValue(ctx, readName, primitives.Unconfirmed, input, output) == nil }, it.MaxWaitTimeForEvents(), 100*time.Millisecond) assert.Equal(t, &anyString, rOutput.FieldByName("Field").Interface()) @@ -60,19 +67,28 @@ func RunContractReaderEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfa it.Setup(t) ctx := it.Helper.Context(t) cr := it.GetChainReader(t) - require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) + bindings := it.GetBindings(t) + + require.NoError(t, cr.Bind(ctx, bindings)) triggerFourTopics(t, it, int32(1), int32(2), int32(3)) triggerFourTopics(t, it, int32(2), int32(2), int32(3)) triggerFourTopics(t, it, int32(1), int32(3), int32(3)) triggerFourTopics(t, it, int32(1), int32(2), int32(4)) + var bound types.BoundContract + for idx := range bindings { + if bindings[idx].Name == AnyContractName { + bound = bindings[idx] + } + } + var latest struct{ Field1, Field2, Field3 int32 } params := struct{ Field1, Field2, Field3 int32 }{Field1: 1, Field2: 2, Field3: 3} time.Sleep(it.MaxWaitTimeForEvents()) - require.NoError(t, cr.GetLatestValue(ctx, AnyContractName, triggerWithAllTopics, primitives.Unconfirmed, params, &latest)) + require.NoError(t, cr.GetLatestValue(ctx, bound.ReadIdentifier(triggerWithAllTopics), primitives.Unconfirmed, params, &latest)) assert.Equal(t, int32(1), latest.Field1) assert.Equal(t, int32(2), latest.Field2) assert.Equal(t, int32(3), latest.Field3) @@ -83,12 +99,21 @@ func RunContractReaderEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfa cr := it.GetChainReader(t) ctx := it.Helper.Context(t) - require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) + bindings := it.GetBindings(t) + + require.NoError(t, cr.Bind(ctx, bindings)) triggerFourTopicsWithHashed(t, it, "1", [32]uint8{2}, [32]byte{5}) triggerFourTopicsWithHashed(t, it, "2", [32]uint8{2}, [32]byte{3}) triggerFourTopicsWithHashed(t, it, "1", [32]uint8{3}, [32]byte{3}) + var bound types.BoundContract + for idx := range bindings { + if bindings[idx].Name == AnyContractName { + bound = bindings[idx] + } + } + var latest struct { Field3 [32]byte } @@ -99,7 +124,7 @@ func RunContractReaderEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfa }{Field1: "1", Field2: [32]uint8{2}, Field3: [32]byte{5}} time.Sleep(it.MaxWaitTimeForEvents()) - require.NoError(t, cr.GetLatestValue(ctx, AnyContractName, triggerWithAllTopicsWithHashed, primitives.Unconfirmed, params, &latest)) + require.NoError(t, cr.GetLatestValue(ctx, bound.ReadIdentifier(triggerWithAllTopicsWithHashed), primitives.Unconfirmed, params, &latest)) // only checking Field3 topic makes sense since it isn't hashed, to check other fields we'd have to replicate solidity encoding and hashing assert.Equal(t, [32]uint8{5}, latest.Field3) }) @@ -113,7 +138,7 @@ func RunContractReaderEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfa ctx := it.Helper.Context(t) err := reader.Bind(ctx, []clcommontypes.BoundContract{{Name: AnyContractName, Address: addr.Hex()}}) - require.ErrorIs(t, err, evm.NoContractExistsError{Address: addr}) + require.ErrorIs(t, err, read.NoContractExistsError{Address: addr}) }) } diff --git a/core/services/relay/evm/method_binding.go b/core/services/relay/evm/method_binding.go deleted file mode 100644 index 9ff57fd934..0000000000 --- a/core/services/relay/evm/method_binding.go +++ /dev/null @@ -1,130 +0,0 @@ -package evm - -import ( - "context" - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common" - - "github.com/smartcontractkit/chainlink-common/pkg/logger" - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/smartcontractkit/chainlink-common/pkg/types/query" - "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" - - evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" -) - -type NoContractExistsError struct { - Address common.Address -} - -func (e NoContractExistsError) Error() string { - return fmt.Sprintf("contract does not exist at address: %s", e.Address) -} - -type methodBinding struct { - lggr logger.Logger - ht logpoller.HeadTracker - address common.Address - contractName string - method string - client evmclient.Client - codec commontypes.Codec - bound bool - confirmationsMapping map[primitives.ConfidenceLevel]evmtypes.Confirmations -} - -var _ readBinding = &methodBinding{} - -func (m *methodBinding) SetCodec(codec commontypes.RemoteCodec) { - m.codec = codec -} - -func (m *methodBinding) Bind(ctx context.Context, binding commontypes.BoundContract) error { - addr := common.HexToAddress(binding.Address) - - // check for contract byte code at the latest block and provided address - byteCode, err := m.client.CodeAt(ctx, addr, nil) - if err != nil { - return err - } - - if len(byteCode) == 0 { - return NoContractExistsError{Address: addr} - } - - m.address = addr - m.bound = true - - return nil -} - -func (m *methodBinding) Register(_ context.Context) error { - return nil -} - -func (m *methodBinding) Unregister(_ context.Context) error { - return nil -} - -func (m *methodBinding) GetLatestValue(ctx context.Context, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) error { - if !m.bound { - return fmt.Errorf("%w: method not bound", commontypes.ErrInvalidType) - } - - data, err := m.codec.Encode(ctx, params, WrapItemType(m.contractName, m.method, true)) - if err != nil { - return err - } - - callMsg := ethereum.CallMsg{ - To: &m.address, - From: m.address, - Data: data, - } - - block, err := m.blockNumberFromConfidence(ctx, confidenceLevel) - if err != nil { - return err - } - - bytes, err := m.client.CallContract(ctx, callMsg, block) - if err != nil { - return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) - } - - return m.codec.Decode(ctx, bytes, returnVal, WrapItemType(m.contractName, m.method, false)) -} - -func (m *methodBinding) QueryKey(_ context.Context, _ query.KeyFilter, _ query.LimitAndSort, _ any) ([]commontypes.Sequence, error) { - return nil, nil -} - -func (m *methodBinding) blockNumberFromConfidence(ctx context.Context, confidenceLevel primitives.ConfidenceLevel) (*big.Int, error) { - confirmations, err := confidenceToConfirmations(m.confirmationsMapping, confidenceLevel) - if err != nil { - err = fmt.Errorf("%w for contract: %s, method: %s", err, m.contractName, m.method) - if confidenceLevel == primitives.Unconfirmed { - m.lggr.Errorf("%v, now falling back to default contract call behaviour that calls latest state", err) - return nil, nil - } - return nil, err - } - - _, finalized, err := m.ht.LatestAndFinalizedBlock(ctx) - if err != nil { - return nil, err - } - - if confirmations == evmtypes.Finalized { - return big.NewInt(finalized.Number), nil - } else if confirmations == evmtypes.Unconfirmed { - return nil, nil - } - - return nil, fmt.Errorf("unknown evm confirmations: %v for contract: %s, method: %s", confirmations, m.contractName, m.method) -} diff --git a/core/services/relay/evm/mocks/loop_relay_adapter.go b/core/services/relay/evm/mocks/loop_relay_adapter.go index 50b1dd5f39..c770b52c88 100644 --- a/core/services/relay/evm/mocks/loop_relay_adapter.go +++ b/core/services/relay/evm/mocks/loop_relay_adapter.go @@ -459,23 +459,23 @@ func (_c *LoopRelayAdapter_NewConfigProvider_Call) RunAndReturn(run func(context } // NewContractReader provides a mock function with given fields: ctx, contractReaderConfig -func (_m *LoopRelayAdapter) NewContractReader(ctx context.Context, contractReaderConfig []byte) (types.ChainReader, error) { +func (_m *LoopRelayAdapter) NewContractReader(ctx context.Context, contractReaderConfig []byte) (types.ContractReader, error) { ret := _m.Called(ctx, contractReaderConfig) if len(ret) == 0 { panic("no return value specified for NewContractReader") } - var r0 types.ChainReader + var r0 types.ContractReader var r1 error - if rf, ok := ret.Get(0).(func(context.Context, []byte) (types.ChainReader, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, []byte) (types.ContractReader, error)); ok { return rf(ctx, contractReaderConfig) } - if rf, ok := ret.Get(0).(func(context.Context, []byte) types.ChainReader); ok { + if rf, ok := ret.Get(0).(func(context.Context, []byte) types.ContractReader); ok { r0 = rf(ctx, contractReaderConfig) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.ChainReader) + r0 = ret.Get(0).(types.ContractReader) } } @@ -507,12 +507,12 @@ func (_c *LoopRelayAdapter_NewContractReader_Call) Run(run func(ctx context.Cont return _c } -func (_c *LoopRelayAdapter_NewContractReader_Call) Return(_a0 types.ChainReader, _a1 error) *LoopRelayAdapter_NewContractReader_Call { +func (_c *LoopRelayAdapter_NewContractReader_Call) Return(_a0 types.ContractReader, _a1 error) *LoopRelayAdapter_NewContractReader_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *LoopRelayAdapter_NewContractReader_Call) RunAndReturn(run func(context.Context, []byte) (types.ChainReader, error)) *LoopRelayAdapter_NewContractReader_Call { +func (_c *LoopRelayAdapter_NewContractReader_Call) RunAndReturn(run func(context.Context, []byte) (types.ContractReader, error)) *LoopRelayAdapter_NewContractReader_Call { _c.Call.Return(run) return _c } diff --git a/core/services/relay/evm/batch_caller.go b/core/services/relay/evm/read/batch.go similarity index 96% rename from core/services/relay/evm/batch_caller.go rename to core/services/relay/evm/read/batch.go index ce5a2bd722..412d9a1138 100644 --- a/core/services/relay/evm/batch_caller.go +++ b/core/services/relay/evm/read/batch.go @@ -1,4 +1,4 @@ -package evm +package read import ( "context" @@ -38,6 +38,7 @@ const ( type BatchResult map[string]ContractResults type ContractResults []MethodCallResult type MethodCallResult struct { + Address string MethodName string ReturnValue any Err error @@ -164,6 +165,7 @@ func (c *defaultEvmBatchCaller) batchCall(ctx context.Context, blockNumber uint6 results := make([]dataAndErr, len(batchCall)) for i, call := range batchCall { results[i] = dataAndErr{ + address: call.ContractAddress.Hex(), contractName: call.ContractName, methodName: call.MethodName, returnVal: call.ReturnVal, @@ -226,6 +228,7 @@ func (c *defaultEvmBatchCaller) batchCallDynamicLimitRetries(ctx context.Context } type dataAndErr struct { + address string contractName, methodName string returnVal any err error @@ -296,6 +299,7 @@ func convertToBatchResult(data []dataAndErr) BatchResult { batchResult := make(BatchResult) for _, d := range data { methodCall := MethodCallResult{ + Address: d.address, MethodName: d.methodName, ReturnValue: d.returnVal, Err: d.err, @@ -310,3 +314,11 @@ func convertToBatchResult(data []dataAndErr) BatchResult { return batchResult } + +func WrapItemType(contractName, itemType string, isParams bool) string { + if isParams { + return fmt.Sprintf("params.%s.%s", contractName, itemType) + } + + return fmt.Sprintf("return.%s.%s", contractName, itemType) +} diff --git a/core/services/relay/evm/batch_caller_test.go b/core/services/relay/evm/read/batch_caller_test.go similarity index 89% rename from core/services/relay/evm/batch_caller_test.go rename to core/services/relay/evm/read/batch_caller_test.go index 048df90dab..4f50bdc691 100644 --- a/core/services/relay/evm/batch_caller_test.go +++ b/core/services/relay/evm/read/batch_caller_test.go @@ -1,4 +1,4 @@ -package evm_test +package read_test import ( "fmt" @@ -16,8 +16,9 @@ import ( chainmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/read" evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -31,8 +32,8 @@ func TestDefaultEvmBatchCaller_BatchCallDynamicLimit(t *testing.T) { }{ { name: "defaults", - maxBatchSize: evm.DefaultRpcBatchSizeLimit, - backOffMultiplier: evm.DefaultRpcBatchBackOffMultiplier, + maxBatchSize: read.DefaultRpcBatchSizeLimit, + backOffMultiplier: read.DefaultRpcBatchBackOffMultiplier, numCalls: 200, expectedBatchSizesOnEachRetry: []int{100, 20, 4, 1}, }, @@ -92,12 +93,12 @@ func TestDefaultEvmBatchCaller_BatchCallDynamicLimit(t *testing.T) { batchSizes = append(batchSizes, len(evmCalls)) }).Return(errors.New("some error")) - calls := make(evm.BatchCall, tc.numCalls) + calls := make(read.BatchCall, tc.numCalls) for i := range calls { - calls[i] = evm.Call{} + calls[i] = read.Call{} } - bc := evm.NewDynamicLimitedBatchCaller(logger.TestLogger(t), mockCodec, ec, tc.maxBatchSize, tc.backOffMultiplier, 1) + bc := read.NewDynamicLimitedBatchCaller(logger.TestLogger(t), mockCodec, ec, tc.maxBatchSize, tc.backOffMultiplier, 1) _, _ = bc.BatchCall(testutils.Context(t), 123, calls) assert.Equal(t, tc.expectedBatchSizesOnEachRetry, batchSizes) }) @@ -131,7 +132,7 @@ func TestDefaultEvmBatchCaller_batchCallLimit(t *testing.T) { for i, tc := range testCases { t.Run(fmt.Sprintf("%v", tc), func(t *testing.T) { ec := chainmocks.NewClient(t) - calls := make(evm.BatchCall, tc.numCalls) + calls := make(read.BatchCall, tc.numCalls) for j := range calls { contractName := fmt.Sprintf("testCase_%d", i) methodName := fmt.Sprintf("method_%d", j) @@ -140,7 +141,7 @@ func TestDefaultEvmBatchCaller_batchCallLimit(t *testing.T) { params := MethodParam{A: uint64(j)} var returnVal MethodReturn - calls[j] = evm.Call{ + calls[j] = read.Call{ ContractName: contractName, MethodName: methodName, Params: ¶ms, @@ -159,9 +160,9 @@ func TestDefaultEvmBatchCaller_batchCallLimit(t *testing.T) { } }).Return(nil) - testCodec, err := evm.NewCodec(codecConfig) + testCodec, err := codec.NewCodec(codecConfig) require.NoError(t, err) - bc := evm.NewDynamicLimitedBatchCaller(logger.TestLogger(t), testCodec, ec, tc.batchSize, 99999, tc.parallelRpcCallsLimit) + bc := read.NewDynamicLimitedBatchCaller(logger.TestLogger(t), testCodec, ec, tc.batchSize, 99999, tc.parallelRpcCallsLimit) // make the call and make sure the results are there results, err := bc.BatchCall(ctx, 0, calls) diff --git a/core/services/relay/evm/read/bindings.go b/core/services/relay/evm/read/bindings.go new file mode 100644 index 0000000000..0b6ea31110 --- /dev/null +++ b/core/services/relay/evm/read/bindings.go @@ -0,0 +1,279 @@ +package read + +import ( + "context" + "errors" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/common" + + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/query" + "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" +) + +type Reader interface { + BatchCall(address common.Address, params, retVal any) (Call, error) + GetLatestValue(ctx context.Context, addr common.Address, confidence primitives.ConfidenceLevel, params, returnVal any) error + QueryKey(context.Context, common.Address, query.KeyFilter, query.LimitAndSort, any) ([]commontypes.Sequence, error) + + Bind(context.Context, ...common.Address) error + Unbind(context.Context, ...common.Address) error + SetCodec(commontypes.RemoteCodec) + + Register(context.Context) error + Unregister(context.Context) error +} + +type BindingsRegistry struct { + // dependencies + batch BatchCaller + + // private state + mu sync.RWMutex + contractBindings map[string]*contractBinding + contractLookup *lookup +} + +func NewBindingsRegistry() *BindingsRegistry { + return &BindingsRegistry{ + contractBindings: make(map[string]*contractBinding), + contractLookup: newLookup(), + } +} + +func (b *BindingsRegistry) SetBatchCaller(caller BatchCaller) { + b.mu.Lock() + defer b.mu.Unlock() + + b.batch = caller +} + +func (b *BindingsRegistry) HasContractBinding(contractName string) bool { + b.mu.RLock() + defer b.mu.RUnlock() + + _, ok := b.contractBindings[contractName] + + return ok +} + +// GetReader should only be called after Chain Reader is started. +func (b *BindingsRegistry) GetReader(readName string) (Reader, string, error) { + b.mu.RLock() + defer b.mu.RUnlock() + + values, ok := b.contractLookup.getContractForReadName(readName) + if !ok { + return nil, "", fmt.Errorf("%w: no reader for read name %s", commontypes.ErrInvalidType, readName) + } + + cb, cbExists := b.contractBindings[values.contract] + if !cbExists { + return nil, "", fmt.Errorf("%w: no contract named %s", commontypes.ErrInvalidType, values.contract) + } + + binding, rbExists := cb.GetReaderNamed(values.readName) + if !rbExists { + return nil, "", fmt.Errorf("%w: no reader named %s in contract %s", commontypes.ErrInvalidType, values.readName, values.contract) + } + + return binding, values.address, nil +} + +func (b *BindingsRegistry) AddReader(contractName, readName string, rdr Reader) { + b.mu.Lock() + defer b.mu.Unlock() + + b.contractLookup.addReadNameForContract(contractName, readName) + + cb, cbExists := b.contractBindings[contractName] + if !cbExists { + cb = newContractBinding(contractName) + b.contractBindings[contractName] = cb + } + + cb.AddReaderNamed(readName, rdr) +} + +// Bind binds contract addresses to contract bindings and read bindings. +// Bind also registers the common contract polling filter and eventBindings polling filters. +func (b *BindingsRegistry) Bind(ctx context.Context, reg Registrar, bindings []commontypes.BoundContract) error { + b.mu.RLock() + defer b.mu.RUnlock() + + for _, binding := range bindings { + contract, exists := b.contractBindings[binding.Name] + if !exists { + return fmt.Errorf("%w: no contract named %s", commontypes.ErrInvalidConfig, binding.Name) + } + + b.contractLookup.bindAddressForContract(binding.Name, binding.Address) + + if err := errors.Join( + contract.Bind(ctx, reg, common.HexToAddress(binding.Address)), + contract.BindReaders(ctx, common.HexToAddress(binding.Address)), + ); err != nil { + return err + } + } + + return nil +} + +func (b *BindingsRegistry) BatchGetLatestValues(ctx context.Context, request commontypes.BatchGetLatestValuesRequest) (commontypes.BatchGetLatestValuesResult, error) { + b.mu.RLock() + defer b.mu.RUnlock() + + var batchCall BatchCall + + for binding, contractBatch := range request { + cb := b.contractBindings[binding.Name] + + for i := range contractBatch { + req := contractBatch[i] + + values, ok := b.contractLookup.getContractForReadName(binding.ReadIdentifier(req.ReadName)) + if !ok { + return nil, fmt.Errorf("%w: no method for read name %s", commontypes.ErrInvalidType, binding.ReadIdentifier(req.ReadName)) + } + + rdr, exists := cb.GetReaderNamed(values.readName) + if !exists { + return nil, fmt.Errorf("%w: no contract read binding for %s", commontypes.ErrInvalidType, values.readName) + } + + call, err := rdr.BatchCall(common.HexToAddress(values.address), req.Params, req.ReturnVal) + if err != nil { + return nil, err + } + + batchCall = append(batchCall, call) + } + } + + results, err := b.batch.BatchCall(ctx, 0, batchCall) + if err != nil { + return nil, err + } + + // reconstruct results from batchCall and filteredLogs into common type while maintaining order from request. + batchGetLatestValuesResults := make(commontypes.BatchGetLatestValuesResult) + for contractName, contractResult := range results { + for _, methodResult := range contractResult { + binding := commontypes.BoundContract{ + Name: contractName, + Address: methodResult.Address, + } + + brr := commontypes.BatchReadResult{ + ReadName: methodResult.MethodName, + } + + brr.SetResult(methodResult.ReturnValue, methodResult.Err) + + if _, ok := batchGetLatestValuesResults[binding]; !ok { + batchGetLatestValuesResults[binding] = make(commontypes.ContractBatchResults, 0) + } + + batchGetLatestValuesResults[binding] = append(batchGetLatestValuesResults[binding], brr) + } + } + + return batchGetLatestValuesResults, err +} + +// Unbind unbinds contract addresses to contract bindings and read bindings. +func (b *BindingsRegistry) Unbind(ctx context.Context, reg Registrar, bindings []commontypes.BoundContract) error { + b.mu.RLock() + defer b.mu.RUnlock() + + for _, binding := range bindings { + contract, exists := b.contractBindings[binding.Name] + if !exists { + return fmt.Errorf("%w: no contract named %s", commontypes.ErrInvalidConfig, binding.Name) + } + + b.contractLookup.unbindAddressForContract(binding.Name, binding.Address) + + if err := errors.Join( + contract.Unbind(ctx, reg, common.HexToAddress(binding.Address)), + contract.UnbindReaders(ctx, common.HexToAddress(binding.Address)), + ); err != nil { + return err + } + } + + return nil +} + +func (b *BindingsRegistry) RegisterAll(ctx context.Context, reg Registrar) error { + b.mu.RLock() + defer b.mu.RUnlock() + + for _, cb := range b.contractBindings { + if err := errors.Join(cb.RegisterReaders(ctx), cb.Register(ctx, reg)); err != nil { + return err + } + } + + return nil +} + +func (b *BindingsRegistry) UnregisterAll(ctx context.Context, reg Registrar) error { + b.mu.RLock() + defer b.mu.RUnlock() + + for _, cb := range b.contractBindings { + if err := errors.Join(cb.UnregisterReaders(ctx), cb.Unregister(ctx, reg)); err != nil { + return err + } + } + + return nil +} + +func (b *BindingsRegistry) SetCodecAll(codec commontypes.RemoteCodec) { + b.mu.RLock() + defer b.mu.RUnlock() + + for _, cb := range b.contractBindings { + cb.SetCodecAll(codec) + } +} + +func (b *BindingsRegistry) SetFilter(name string, filter logpoller.Filter) error { + b.mu.RLock() + defer b.mu.RUnlock() + + contract, ok := b.contractBindings[name] + if !ok { + return fmt.Errorf("%w: no contract binding for %s", commontypes.ErrInvalidConfig, name) + } + + contract.SetFilter(filter) + + return nil +} + +func (b *BindingsRegistry) ReadTypeIdentifier(readName string, forEncoding bool) string { + values, ok := b.contractLookup.getContractForReadName(readName) + if !ok { + return "" + } + + return WrapItemType(values.contract, values.readName, forEncoding) +} + +// confidenceToConfirmations matches predefined chain agnostic confidence levels to predefined EVM finality. +func confidenceToConfirmations(confirmationsMapping map[primitives.ConfidenceLevel]evmtypes.Confirmations, confidenceLevel primitives.ConfidenceLevel) (evmtypes.Confirmations, error) { + confirmations, exists := confirmationsMapping[confidenceLevel] + if !exists { + return 0, fmt.Errorf("missing mapping for confidence level: %s", confidenceLevel) + } + return confirmations, nil +} diff --git a/core/services/relay/evm/read/bindings_test.go b/core/services/relay/evm/read/bindings_test.go new file mode 100644 index 0000000000..a60cc2933e --- /dev/null +++ b/core/services/relay/evm/read/bindings_test.go @@ -0,0 +1,112 @@ +package read_test + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/read" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/read/mocks" +) + +var ( + contractName1 = "Contract1" + methodName1 = "Method1" + methodName2 = "Method2" + eventName0 = "EventName0" + filterWithSigs = logpoller.Filter{ + Name: eventName0, + EventSigs: []common.Hash{common.HexToHash("0x25"), common.HexToHash("0x29")}, + } +) + +func TestBindingsRegistry(t *testing.T) { + t.Parallel() + + t.Run("readers are addable, bindable, and retrievable", func(t *testing.T) { + t.Parallel() + + mBatch := new(mocks.BatchCaller) + mRdr := new(mocks.Reader) + mReg := new(mocks.Registrar) + + mRdr.EXPECT().Bind(mock.Anything, mock.Anything).Return(nil) + + named := read.NewBindingsRegistry() + named.SetBatchCaller(mBatch) + + named.AddReader(contractName1, methodName1, mRdr) + + bindings := []commontypes.BoundContract{{Address: "0x24", Name: contractName1}} + _ = named.Bind(context.Background(), mReg, bindings) + + rdr, _, err := named.GetReader(bindings[0].ReadIdentifier(methodName1)) + + require.NoError(t, err) + require.NotNil(t, rdr) + }) + + t.Run("register all before bind", func(t *testing.T) { + t.Parallel() + + mBatch := new(mocks.BatchCaller) + mRdr0 := new(mocks.Reader) + mRdr1 := new(mocks.Reader) + mReg := new(mocks.Registrar) + + named := read.NewBindingsRegistry() + named.SetBatchCaller(mBatch) + + // register is called once through RegisterAll and again in Bind + mRdr0.EXPECT().Register(mock.Anything).Return(nil) + mRdr1.EXPECT().Register(mock.Anything).Return(nil) + + mRdr0.EXPECT().Bind(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) + mRdr1.EXPECT().Bind(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) + + mReg.EXPECT().HasFilter(mock.Anything).Return(false) + mReg.EXPECT().RegisterFilter(mock.Anything, mock.Anything).Return(nil) + mRdr0.EXPECT().GetLatestValue(mock.Anything, common.HexToAddress("0x25"), mock.Anything, mock.Anything, mock.Anything).Return(nil) + mRdr0.EXPECT().GetLatestValue(mock.Anything, common.HexToAddress("0x24"), mock.Anything, mock.Anything, mock.Anything).Return(nil) + mRdr1.EXPECT().GetLatestValue(mock.Anything, common.HexToAddress("0x26"), mock.Anything, mock.Anything, mock.Anything).Return(nil) + + // part of the init phase of chain reader + named.AddReader(contractName1, methodName1, mRdr0) + named.AddReader(contractName1, methodName2, mRdr1) + _ = named.SetFilter(contractName1, filterWithSigs) + + // run within the start phase of chain reader + require.NoError(t, named.RegisterAll(context.Background(), mReg)) + + bindings := []commontypes.BoundContract{ + {Address: "0x24", Name: contractName1}, + {Address: "0x25", Name: contractName1}, + {Address: "0x26", Name: contractName1}, + } + + // calling bind will also call register for each reader + _ = named.Bind(context.Background(), mReg, bindings) + + rdr1, _, err := named.GetReader(bindings[0].ReadIdentifier(methodName1)) + require.NoError(t, err) + + rdr2, _, err := named.GetReader(bindings[0].ReadIdentifier(methodName2)) + require.NoError(t, err) + + require.NoError(t, rdr1.GetLatestValue(context.Background(), common.HexToAddress("0x25"), primitives.Finalized, nil, nil)) + require.NoError(t, rdr1.GetLatestValue(context.Background(), common.HexToAddress("0x24"), primitives.Finalized, nil, nil)) + require.NoError(t, rdr2.GetLatestValue(context.Background(), common.HexToAddress("0x26"), primitives.Finalized, nil, nil)) + + mBatch.AssertExpectations(t) + mRdr0.AssertExpectations(t) + mRdr1.AssertExpectations(t) + mReg.AssertExpectations(t) + }) +} diff --git a/core/services/relay/evm/read/contract.go b/core/services/relay/evm/read/contract.go new file mode 100644 index 0000000000..1b47c9ee87 --- /dev/null +++ b/core/services/relay/evm/read/contract.go @@ -0,0 +1,243 @@ +package read + +import ( + "context" + "errors" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/google/uuid" + + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" +) + +// contractBinding stores read bindings and manages the common contract event filter. +type contractBinding struct { + // filterRegistrar is used to manage polling filter registration for the common contract filter. + // The common contract filter should be used by events that share filtering args. + registrar *syncedFilter + + // registered is used to determine if Register was called during Chain Reader service Start. + // This is done to avoid calling Register while the service is not running because log poller is most likely also not running. + registerCalled bool + + // internal properties + name string + readers map[string]Reader // key is read name method, event or event keys used for queryKey. + bound map[common.Address]bool // bound determines if address is set to the contract binding. + mu sync.RWMutex +} + +func newContractBinding(name string) *contractBinding { + return &contractBinding{ + name: name, + readers: make(map[string]Reader), + bound: make(map[common.Address]bool), + registrar: newSyncedFilter(), + } +} + +// GetReaderNamed returns a reader for the provided contract name. This method is thread safe. +func (cb *contractBinding) GetReaderNamed(name string) (Reader, bool) { + cb.mu.RLock() + defer cb.mu.RUnlock() + + binding, exists := cb.readers[name] + + return binding, exists +} + +// AddReaderNamed adds a new reader to the contract bindings for the provided contract name. This +// method is thread safe. +func (cb *contractBinding) AddReaderNamed(name string, rdr Reader) { + cb.mu.Lock() + defer cb.mu.Unlock() + + cb.readers[name] = rdr +} + +// Bind binds contract addresses to contract binding and registers the common contract polling filter. +func (cb *contractBinding) Bind(ctx context.Context, registrar Registrar, bindings ...common.Address) error { + if cb.isBound() { + if err := cb.Unregister(ctx, registrar); err != nil { + return err + } + } + + for _, binding := range bindings { + if cb.bindingExists(binding) { + continue + } + + cb.registrar.SetName(logpoller.FilterName(cb.name + "." + uuid.NewString())) + cb.registrar.AddAddress(binding) + cb.addBinding(binding) + } + + // registerCalled during ChainReader start + if cb.registered() { + return cb.Register(ctx, registrar) + } + + return nil +} + +func (cb *contractBinding) BindReaders(ctx context.Context, addresses ...common.Address) error { + cb.mu.RLock() + defer cb.mu.RUnlock() + + var err error + + for _, reader := range cb.readers { + err = errors.Join(err, reader.Bind(ctx, addresses...)) + } + + return err +} + +// Unbind unbinds contract addresses from contract binding and unregisters the common contract polling filter. +func (cb *contractBinding) Unbind(ctx context.Context, registrar Registrar, bindings ...common.Address) error { + for _, binding := range bindings { + if !cb.bindingExists(binding) { + continue + } + + cb.registrar.RemoveAddress(binding) + cb.removeBinding(binding) + } + + // we are changing contract address reference, so we need to unregister old filter or re-register existing filter + if cb.registrar.Count() == 0 { + cb.registrar.SetName("") + + return cb.Unregister(ctx, registrar) + } else if cb.registered() { + return cb.Register(ctx, registrar) + } + + return nil +} + +func (cb *contractBinding) UnbindReaders(ctx context.Context, addresses ...common.Address) error { + cb.mu.RLock() + defer cb.mu.RUnlock() + + var err error + + for _, reader := range cb.readers { + err = errors.Join(reader.Unbind(ctx, addresses...)) + } + + return err +} + +func (cb *contractBinding) SetCodecAll(codec commontypes.RemoteCodec) { + cb.mu.RLock() + defer cb.mu.RUnlock() + + for _, binding := range cb.readers { + binding.SetCodec(codec) + } +} + +// Register registers the common contract filter. +func (cb *contractBinding) Register(ctx context.Context, registrar Registrar) error { + cb.setRegistered() + + if !cb.isBound() { + return nil + } + + if cb.registrar.HasEventSigs() { + if err := cb.registrar.Register(ctx, registrar); err != nil { + return err + } + } + + return nil +} + +func (cb *contractBinding) RegisterReaders(ctx context.Context) error { + cb.mu.RLock() + defer cb.mu.RUnlock() + + for _, binding := range cb.readers { + if err := binding.Register(ctx); err != nil { + return err + } + } + + return nil +} + +// Unregister unregisters the common contract filter. +func (cb *contractBinding) Unregister(ctx context.Context, registrar Registrar) error { + if !cb.isBound() { + return nil + } + + return cb.registrar.Unregister(ctx, registrar) +} + +func (cb *contractBinding) UnregisterReaders(ctx context.Context) error { + cb.mu.RLock() + defer cb.mu.RUnlock() + + for _, binding := range cb.readers { + if err := binding.Unregister(ctx); err != nil { + return err + } + } + + return nil +} + +func (cb *contractBinding) SetFilter(filter logpoller.Filter) { + cb.registrar.SetFilter(filter) +} + +func (cb *contractBinding) isBound() bool { + cb.mu.RLock() + defer cb.mu.RUnlock() + + return len(cb.bound) > 0 +} + +func (cb *contractBinding) bindingExists(binding common.Address) bool { + cb.mu.RLock() + defer cb.mu.RUnlock() + + bound, exists := cb.bound[binding] + + return exists && bound +} + +func (cb *contractBinding) addBinding(binding common.Address) { + cb.mu.Lock() + defer cb.mu.Unlock() + + cb.bound[binding] = true +} + +func (cb *contractBinding) removeBinding(binding common.Address) { + cb.mu.Lock() + defer cb.mu.Unlock() + + delete(cb.bound, binding) +} + +func (cb *contractBinding) registered() bool { + cb.mu.RLock() + defer cb.mu.RUnlock() + + return cb.registerCalled +} + +func (cb *contractBinding) setRegistered() { + cb.mu.Lock() + defer cb.mu.Unlock() + + cb.registerCalled = true +} diff --git a/core/services/relay/evm/read/event.go b/core/services/relay/evm/read/event.go new file mode 100644 index 0000000000..693a8d5bd7 --- /dev/null +++ b/core/services/relay/evm/read/event.go @@ -0,0 +1,654 @@ +package read + +import ( + "context" + "fmt" + "reflect" + "strings" + "sync" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/google/uuid" + + commoncodec "github.com/smartcontractkit/chainlink-common/pkg/codec" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/query" + "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" +) + +type EventBinding struct { + // read-only properties + contractName string + eventName string + hash common.Hash + inputInfo types.CodecEntry + inputModifier commoncodec.Modifier + codecTopicInfo types.CodecEntry + + // dependencies + // filterRegistrar in EventBinding is to be used as an override for lp filter defined in the contract binding. + // If filterRegisterer is nil, this event should be registered with the lp filter defined in the contract binding. + registrar *syncedFilter + registerCalled bool + lp logpoller.LogPoller + + // internal properties / state + codec commontypes.RemoteCodec + bound map[common.Address]bool // bound determines if address is set to the contract binding. + mu sync.RWMutex + topics map[string]topicDetail // topics maps a generic topic name (key) to topic data + // eventDataWords maps a generic name to a word index + // key is a predefined generic name for evm log event data word + // for e.g. first evm data word(32bytes) of USDC log event is value so the key can be called value + eventDataWords map[string]uint8 + confirmationsMapping map[primitives.ConfidenceLevel]evmtypes.Confirmations +} + +func NewEventBinding( + contract, event string, + poller logpoller.LogPoller, + hash common.Hash, + inputInfo types.CodecEntry, + inputModifier commoncodec.Modifier, + codecTopicInfo types.CodecEntry, + confirmations map[primitives.ConfidenceLevel]evmtypes.Confirmations, +) *EventBinding { + return &EventBinding{ + contractName: contract, + eventName: event, + lp: poller, + hash: hash, + inputInfo: inputInfo, + inputModifier: inputModifier, + codecTopicInfo: codecTopicInfo, + confirmationsMapping: confirmations, + topics: make(map[string]topicDetail), + eventDataWords: make(map[string]uint8), + bound: make(map[common.Address]bool), + } +} + +type topicDetail struct { + abi.Argument + Index uint64 +} + +var _ Reader = &EventBinding{} + +func (b *EventBinding) SetCodec(codec commontypes.RemoteCodec) { + b.mu.Lock() + defer b.mu.Unlock() + + b.codec = codec +} + +func (b *EventBinding) Bind(ctx context.Context, bindings ...common.Address) error { + if b.hasBindings() { + // we are changing contract address reference, so we need to unregister old filter if it exists + if err := b.Unregister(ctx); err != nil { + return err + } + } + + // filterRegisterer isn't required here because the event can also be polled for by the contractBinding common filter. + if b.registrar != nil { + b.registrar.SetName(logpoller.FilterName(fmt.Sprintf("%s.%s.%s", b.contractName, b.eventName, uuid.NewString()))) + } + + for _, binding := range bindings { + if b.isBound(binding) { + continue + } + + if b.registrar != nil { + b.registrar.AddAddress(binding) + } + + b.addBinding(binding) + } + + if b.registered() { + return b.Register(ctx) + } + + return nil +} + +func (b *EventBinding) Unbind(ctx context.Context, bindings ...common.Address) error { + for _, binding := range bindings { + if !b.isBound(binding) { + continue + } + + if b.registrar != nil { + b.registrar.RemoveAddress(binding) + } + + b.removeBinding(binding) + } + + if err := b.Unregister(ctx); err != nil { + return err + } + + // we are changing contract address reference, so we need to unregister old filter or re-register existing filter + if b.registrar != nil { + if b.registrar.Count() == 0 { + b.registrar.SetName("") + + return b.Unregister(ctx) + } else if b.registered() { + return b.Register(ctx) + } + } + + return nil +} + +func (b *EventBinding) Register(ctx context.Context) error { + b.mu.Lock() + defer b.mu.Unlock() + + if b.registrar == nil { + return nil + } + + b.registerCalled = true + + // can't be true before filters params are set so there is no race with a bad filter outcome + if len(b.bound) == 0 { + return nil + } + + return b.registrar.Register(ctx, b.lp) +} + +func (b *EventBinding) Unregister(ctx context.Context) error { + b.mu.Lock() + defer b.mu.Unlock() + + if b.registrar == nil { + return nil + } + + if len(b.bound) == 0 { + return nil + } + + return b.registrar.Unregister(ctx, b.lp) +} + +func (b *EventBinding) BatchCall(_ common.Address, _, _ any) (Call, error) { + return Call{}, fmt.Errorf("%w: events are not yet supported in batch get latest values", commontypes.ErrInvalidType) +} + +func (b *EventBinding) GetLatestValue(ctx context.Context, address common.Address, confidenceLevel primitives.ConfidenceLevel, params, into any) error { + if err := b.validateBound(address); err != nil { + return err + } + + confirmations, err := confidenceToConfirmations(b.confirmationsMapping, confidenceLevel) + if err != nil { + return err + } + + if len(b.inputInfo.Args()) == 0 { + return b.getLatestValueWithoutFilters(ctx, address, confirmations, into) + } + + return b.getLatestValueWithFilters(ctx, address, confirmations, params, into) +} + +func (b *EventBinding) QueryKey( + ctx context.Context, + address common.Address, + filter query.KeyFilter, + limitAndSort query.LimitAndSort, + sequenceDataType any, +) ([]commontypes.Sequence, error) { + if err := b.validateBound(address); err != nil { + return nil, err + } + + remapped, err := b.remap(filter) + if err != nil { + return nil, err + } + + // filter should always use the address and event sig + defaultExpressions := []query.Expression{ + logpoller.NewAddressFilter(address), + logpoller.NewEventSigFilter(b.hash), + } + + remapped.Expressions = append(defaultExpressions, remapped.Expressions...) + + logs, err := b.lp.FilteredLogs(ctx, remapped.Expressions, limitAndSort, b.contractName+"-"+address.String()+""+b.eventName) + if err != nil { + return nil, err + } + + // no need to return an error. an empty list is fine + if len(logs) == 0 { + return []commontypes.Sequence{}, nil + } + + return b.decodeLogsIntoSequences(ctx, logs, sequenceDataType) +} + +func (b *EventBinding) SetFilter(filter logpoller.Filter) { + b.mu.Lock() + defer b.mu.Unlock() + + b.registrar = newSyncedFilter() + b.registrar.SetFilter(filter) +} + +func (b *EventBinding) WithTopic(name string, topic abi.Argument, index uint64) { + b.mu.Lock() + defer b.mu.Unlock() + + b.topics[name] = topicDetail{ + Argument: topic, + Index: index, + } +} + +func (b *EventBinding) SetDataWords(eventDataWords map[string]uint8) { + b.mu.Lock() + defer b.mu.Unlock() + + b.eventDataWords = eventDataWords +} + +func (b *EventBinding) GetDataWords() map[string]uint8 { + b.mu.RLock() + defer b.mu.RUnlock() + + return b.eventDataWords +} + +func (b *EventBinding) validateBound(address common.Address) error { + b.mu.Lock() + defer b.mu.Unlock() + + bound, exists := b.bound[address] + if !exists || !bound { + return fmt.Errorf( + "%w: event %s that belongs to contract: %s, not bound", + commontypes.ErrInvalidType, + b.eventName, + b.contractName, + ) + } + + return nil +} + +func (b *EventBinding) getLatestValueWithoutFilters( + ctx context.Context, + address common.Address, + confs evmtypes.Confirmations, + into any, +) error { + log, err := b.lp.LatestLogByEventSigWithConfs(ctx, b.hash, address, confs) + if err = wrapInternalErr(err); err != nil { + return err + } + + return b.decodeLog(ctx, log, into) +} + +func (b *EventBinding) getLatestValueWithFilters( + ctx context.Context, + address common.Address, + confs evmtypes.Confirmations, + params, into any, +) error { + offChain, err := b.convertToOffChainType(params) + if err != nil { + return err + } + + checkedParams, err := b.inputModifier.TransformToOnChain(offChain, "" /* unused */) + if err != nil { + return err + } + + nativeParams, err := b.inputInfo.ToNative(reflect.ValueOf(checkedParams)) + if err != nil { + return err + } + + filtersAndIndices, err := b.encodeParams(nativeParams) + if err != nil { + return err + } + + remainingFilters := filtersAndIndices[1:] + + // Create limiter and filter for the query. + limiter := query.NewLimitAndSort(query.CountLimit(1), query.NewSortBySequence(query.Desc)) + filter, err := query.Where( + "", + logpoller.NewAddressFilter(address), + logpoller.NewEventSigFilter(b.hash), + logpoller.NewConfirmationsFilter(confs), + createTopicFilters(filtersAndIndices), + ) + if err != nil { + return wrapInternalErr(err) + } + + // Gets the latest log that matches the filter and limiter. + logs, err := b.lp.FilteredLogs(ctx, filter.Expressions, limiter, b.contractName+"-"+address.String()+"-"+b.eventName) + if err != nil { + return wrapInternalErr(err) + } + + // TODO: there should be a better way to ask log poller to filter these + // First, you should be able to ask for as many topics to match + // Second, you should be able to get the latest only + var logToUse *logpoller.Log + for _, log := range logs { + tmp := log + if compareLogs(&tmp, logToUse) > 0 && matchesRemainingFilters(&tmp, remainingFilters) { + // copy so that it's not pointing to the changing variable + logToUse = &tmp + } + } + + if logToUse == nil { + return fmt.Errorf("%w: no events found", commontypes.ErrNotFound) + } + + return b.decodeLog(ctx, logToUse, into) +} + +func (b *EventBinding) convertToOffChainType(params any) (any, error) { + offChain, err := b.codec.CreateType(WrapItemType(b.contractName, b.eventName, true), true) + if err != nil { + return nil, err + } + + if err = codec.MapstructureDecode(params, offChain); err != nil { + return nil, err + } + + return offChain, nil +} + +func (b *EventBinding) encodeParams(item reflect.Value) ([]common.Hash, error) { + for item.Kind() == reflect.Pointer { + item = reflect.Indirect(item) + } + + var params []any + switch item.Kind() { + case reflect.Array, reflect.Slice: + native, err := codec.RepresentArray(item, b.inputInfo) + if err != nil { + return nil, err + } + params = []any{native} + case reflect.Struct, reflect.Map: + var err error + if params, err = codec.UnrollItem(item, b.inputInfo); err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("%w: cannot encode kind %v", commontypes.ErrInvalidType, item.Kind()) + } + + // abi params allow you to Pack a pointers, but MakeTopics doesn't work with pointers. + if err := b.derefTopics(params); err != nil { + return nil, err + } + + return b.makeTopics(params) +} + +func (b *EventBinding) derefTopics(topics []any) error { + for i, topic := range topics { + rTopic := reflect.ValueOf(topic) + if rTopic.Kind() == reflect.Pointer { + if rTopic.IsNil() { + return fmt.Errorf( + "%w: input topic %s cannot be nil", commontypes.ErrInvalidType, b.inputInfo.Args()[i].Name) + } + + topics[i] = rTopic.Elem().Interface() + } + } + + return nil +} + +// makeTopics encodes and hashes params filtering values to match onchain indexed topics. +func (b *EventBinding) makeTopics(params []any) ([]common.Hash, error) { + // make topic value for non-fixed bytes array manually because geth MakeTopics doesn't support it + for i, topic := range params { + if abiArg := b.inputInfo.Args()[i]; abiArg.Type.T == abi.ArrayTy && (abiArg.Type.Elem != nil && abiArg.Type.Elem.T == abi.UintTy) { + packed, err := abi.Arguments{abiArg}.Pack(topic) + if err != nil { + return nil, err + } + params[i] = crypto.Keccak256Hash(packed) + } + } + + hashes, err := abi.MakeTopics(params) + if err != nil { + return nil, wrapInternalErr(err) + } + + if len(hashes) != 1 { + return nil, fmt.Errorf("%w: expected 1 filter set, got %d", commontypes.ErrInternal, len(hashes)) + } + + return hashes[0], nil +} + +func (b *EventBinding) decodeLog(ctx context.Context, log *logpoller.Log, into any) error { + if err := b.codec.Decode(ctx, log.Data, into, WrapItemType(b.contractName, b.eventName, false)); err != nil { + return err + } + + topics := make([]common.Hash, len(b.codecTopicInfo.Args())) + if len(log.Topics) < len(topics)+1 { + return fmt.Errorf("%w: not enough topics to decode", commontypes.ErrInvalidType) + } + + for i := 0; i < len(topics); i++ { + topics[i] = common.Hash(log.Topics[i+1]) + } + + topicsInto := map[string]any{} + if err := abi.ParseTopicsIntoMap(topicsInto, b.codecTopicInfo.Args(), topics); err != nil { + return fmt.Errorf("%w: %w", commontypes.ErrInvalidType, err) + } + + return codec.MapstructureDecode(topicsInto, into) +} + +func (b *EventBinding) decodeLogsIntoSequences(ctx context.Context, logs []logpoller.Log, into any) ([]commontypes.Sequence, error) { + sequences := make([]commontypes.Sequence, len(logs)) + + for idx := range logs { + sequences[idx] = commontypes.Sequence{ + Cursor: fmt.Sprintf("%s-%s-%d", logs[idx].BlockHash, logs[idx].TxHash, logs[idx].LogIndex), + Head: commontypes.Head{ + Identifier: fmt.Sprint(logs[idx].BlockNumber), + Hash: logs[idx].BlockHash.Bytes(), + Timestamp: uint64(logs[idx].BlockTimestamp.Unix()), + }, + } + + var typeVal reflect.Value + + typeInto := reflect.TypeOf(into) + if typeInto.Kind() == reflect.Pointer { + typeVal = reflect.New(typeInto.Elem()) + } else { + typeVal = reflect.Indirect(reflect.New(typeInto)) + } + + // create a new value of the same type as 'into' for the data to be extracted to + sequences[idx].Data = typeVal.Interface() + + if err := b.decodeLog(ctx, &logs[idx], sequences[idx].Data); err != nil { + return nil, err + } + } + + return sequences, nil +} + +func (b *EventBinding) remap(filter query.KeyFilter) (query.KeyFilter, error) { + remapped := query.KeyFilter{} + + for _, expression := range filter.Expressions { + remappedExpression, err := b.remapExpression(filter.Key, expression) + if err != nil { + return query.KeyFilter{}, err + } + + remapped.Expressions = append(remapped.Expressions, remappedExpression) + } + + return remapped, nil +} + +func (b *EventBinding) remapExpression(key string, expression query.Expression) (query.Expression, error) { + if !expression.IsPrimitive() { + remappedBoolExpressions := make([]query.Expression, len(expression.BoolExpression.Expressions)) + + for i := range expression.BoolExpression.Expressions { + remapped, err := b.remapExpression(key, expression.BoolExpression.Expressions[i]) + if err != nil { + return query.Expression{}, err + } + + remappedBoolExpressions[i] = remapped + } + + if expression.BoolExpression.BoolOperator == query.AND { + return query.And(remappedBoolExpressions...), nil + } + + return query.Or(remappedBoolExpressions...), nil + } + + return b.remapPrimitive(key, expression) +} + +// remap chain agnostic primitives to chain specific +func (b *EventBinding) remapPrimitive(key string, expression query.Expression) (query.Expression, error) { + switch primitive := expression.Primitive.(type) { + case *primitives.Comparator: + if val, ok := b.eventDataWords[primitive.Name]; ok { + return logpoller.NewEventByWordFilter(b.hash, val, primitive.ValueComparators), nil + } + + return logpoller.NewEventByTopicFilter(b.topics[key].Index, primitive.ValueComparators), nil + case *primitives.Confidence: + confirmations, err := confidenceToConfirmations(b.confirmationsMapping, primitive.ConfidenceLevel) + if err != nil { + return query.Expression{}, err + } + + return logpoller.NewConfirmationsFilter(confirmations), nil + default: + return expression, nil + } +} + +func (b *EventBinding) hasBindings() bool { + b.mu.RLock() + defer b.mu.RUnlock() + + return len(b.bound) > 0 +} + +func (b *EventBinding) isBound(binding common.Address) bool { + b.mu.RLock() + defer b.mu.RUnlock() + + _, exists := b.bound[binding] + + return exists +} + +func (b *EventBinding) addBinding(binding common.Address) { + b.mu.Lock() + defer b.mu.Unlock() + + b.bound[binding] = true +} + +func (b *EventBinding) removeBinding(binding common.Address) { + b.mu.Lock() + defer b.mu.Unlock() + + delete(b.bound, binding) +} + +func (b *EventBinding) registered() bool { + b.mu.RLock() + defer b.mu.RUnlock() + + return b.registerCalled +} + +func compareLogs(log, use *logpoller.Log) int64 { + if use == nil { + return 1 + } + + if log.BlockNumber != use.BlockNumber { + return log.BlockNumber - use.BlockNumber + } + + return log.LogIndex - use.LogIndex +} + +func matchesRemainingFilters(log *logpoller.Log, filters []common.Hash) bool { + for i, rfai := range filters { + if !reflect.DeepEqual(rfai[:], log.Topics[i+2]) { + return false + } + } + + return true +} + +func wrapInternalErr(err error) error { + if err == nil { + return nil + } + + errStr := err.Error() + if strings.Contains(errStr, "not found") || strings.Contains(errStr, "no rows") { + return fmt.Errorf("%w: %w", commontypes.ErrNotFound, err) + } + + return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) +} + +func createTopicFilters(filtersAndIndices []common.Hash) query.Expression { + var expressions []query.Expression + for topicID, fai := range filtersAndIndices { + // first topic index is 1-based, so we add 1. + expressions = append(expressions, logpoller.NewEventByTopicFilter( + uint64(topicID+1), []primitives.ValueComparator{{Value: fai.Hex(), Operator: primitives.Eq}}, + )) + } + return query.And(expressions...) +} diff --git a/core/services/relay/evm/read/filter.go b/core/services/relay/evm/read/filter.go new file mode 100644 index 0000000000..08f45729ec --- /dev/null +++ b/core/services/relay/evm/read/filter.go @@ -0,0 +1,107 @@ +package read + +import ( + "context" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/common" + + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" +) + +type Registrar interface { + HasFilter(string) bool + RegisterFilter(context.Context, logpoller.Filter) error + UnregisterFilter(context.Context, string) error +} + +type syncedFilter struct { + // internal state properties + mu sync.RWMutex + filter logpoller.Filter +} + +func newSyncedFilter() *syncedFilter { + return &syncedFilter{} +} + +func (r *syncedFilter) Register(ctx context.Context, registrar Registrar) error { + r.mu.RLock() + defer r.mu.RUnlock() + + if !registrar.HasFilter(r.filter.Name) { + if err := registrar.RegisterFilter(ctx, r.filter); err != nil { + return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) + } + } + + return nil +} + +func (r *syncedFilter) Unregister(ctx context.Context, registrar Registrar) error { + r.mu.RLock() + defer r.mu.RUnlock() + + if !registrar.HasFilter(r.filter.Name) { + return nil + } + + if err := registrar.UnregisterFilter(ctx, r.filter.Name); err != nil { + return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) + } + + return nil +} + +func (r *syncedFilter) SetFilter(filter logpoller.Filter) { + r.mu.Lock() + defer r.mu.Unlock() + + r.filter = filter +} + +func (r *syncedFilter) SetName(name string) { + r.mu.Lock() + defer r.mu.Unlock() + + r.filter.Name = name +} + +func (r *syncedFilter) AddAddress(address common.Address) { + r.mu.Lock() + defer r.mu.Unlock() + + r.filter.Addresses = append(r.filter.Addresses, address) +} + +func (r *syncedFilter) RemoveAddress(address common.Address) { + r.mu.Lock() + defer r.mu.Unlock() + + var addrIdx int + for idx, addr := range r.filter.Addresses { + if addr.Hex() == address.Hex() { + addrIdx = idx + } + } + + r.filter.Addresses[addrIdx] = r.filter.Addresses[len(r.filter.Addresses)-1] + r.filter.Addresses = r.filter.Addresses[:len(r.filter.Addresses)-1] +} + +func (r *syncedFilter) Count() int { + r.mu.RLock() + defer r.mu.RUnlock() + + return len(r.filter.Addresses) +} + +func (r *syncedFilter) HasEventSigs() bool { + r.mu.RLock() + defer r.mu.RUnlock() + + return len(r.filter.EventSigs) > 0 && len(r.filter.Addresses) > 0 +} diff --git a/core/services/relay/evm/read/lookup.go b/core/services/relay/evm/read/lookup.go new file mode 100644 index 0000000000..5679d8cee0 --- /dev/null +++ b/core/services/relay/evm/read/lookup.go @@ -0,0 +1,84 @@ +package read + +import ( + "sync" + + "github.com/smartcontractkit/chainlink-common/pkg/types" +) + +type readValues struct { + address string + contract string + readName string +} + +// lookup provides basic utilities for mapping a complete readIdentifier to +// finite contract read information +type lookup struct { + mu sync.RWMutex + // contractReadNames maps a contract name to all available readNames (method, log, event, etc.) + contractReadNames map[string][]string + // readIdentifiers maps from a complete readIdentifier string to finite read data + // a readIdentifier is a combination of address, contract, and readName as a concatenated string + readIdentifiers map[string]readValues +} + +func newLookup() *lookup { + return &lookup{ + contractReadNames: make(map[string][]string), + readIdentifiers: make(map[string]readValues), + } +} + +func (l *lookup) addReadNameForContract(contract, readName string) { + l.mu.Lock() + defer l.mu.Unlock() + + readNames, exists := l.contractReadNames[contract] + if !exists { + readNames = []string{} + } + + l.contractReadNames[contract] = append(readNames, readName) +} + +func (l *lookup) bindAddressForContract(contract, address string) { + l.mu.Lock() + defer l.mu.Unlock() + + for _, readName := range l.contractReadNames[contract] { + readIdentifier := types.BoundContract{ + Address: address, + Name: contract, + }.ReadIdentifier(readName) + + l.readIdentifiers[readIdentifier] = readValues{ + address: address, + contract: contract, + readName: readName, + } + } +} + +func (l *lookup) unbindAddressForContract(contract, address string) { + l.mu.Lock() + defer l.mu.Unlock() + + for _, readName := range l.contractReadNames[contract] { + readIdentifier := types.BoundContract{ + Address: address, + Name: contract, + }.ReadIdentifier(readName) + + delete(l.readIdentifiers, readIdentifier) + } +} + +func (l *lookup) getContractForReadName(readName string) (readValues, bool) { + l.mu.RLock() + defer l.mu.RUnlock() + + contract, ok := l.readIdentifiers[readName] + + return contract, ok +} diff --git a/core/services/relay/evm/read/method.go b/core/services/relay/evm/read/method.go new file mode 100644 index 0000000000..3f29b00ce9 --- /dev/null +++ b/core/services/relay/evm/read/method.go @@ -0,0 +1,203 @@ +package read + +import ( + "context" + "fmt" + "math/big" + "sync" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/query" + "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + + evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" +) + +type NoContractExistsError struct { + Address common.Address +} + +func (e NoContractExistsError) Error() string { + return fmt.Sprintf("contract does not exist at address: %s", e.Address) +} + +type MethodBinding struct { + // read-only properties + contractName string + method string + + // dependencies + client evmclient.Client + ht logpoller.HeadTracker + lggr logger.Logger + confirmationsMapping map[primitives.ConfidenceLevel]evmtypes.Confirmations + + // internal state properties + codec commontypes.Codec + bindings map[common.Address]struct{} + mu sync.RWMutex +} + +func NewMethodBinding( + name, method string, + client evmclient.Client, + heads logpoller.HeadTracker, + confs map[primitives.ConfidenceLevel]evmtypes.Confirmations, + lggr logger.Logger, +) *MethodBinding { + return &MethodBinding{ + contractName: name, + method: method, + client: client, + ht: heads, + lggr: lggr, + confirmationsMapping: confs, + bindings: make(map[common.Address]struct{}), + } +} + +var _ Reader = &MethodBinding{} + +func (b *MethodBinding) Bind(ctx context.Context, bindings ...common.Address) error { + for _, binding := range bindings { + if b.isBound(binding) { + continue + } + + // check for contract byte code at the latest block and provided address + byteCode, err := b.client.CodeAt(ctx, binding, nil) + if err != nil { + return err + } + + if len(byteCode) == 0 { + return NoContractExistsError{Address: binding} + } + + b.setBinding(binding) + } + + return nil +} + +func (b *MethodBinding) Unbind(ctx context.Context, bindings ...common.Address) error { + b.mu.Lock() + defer b.mu.Unlock() + + for _, binding := range bindings { + delete(b.bindings, binding) + } + + return nil +} + +func (b *MethodBinding) SetCodec(codec commontypes.RemoteCodec) { + b.mu.Lock() + defer b.mu.Unlock() + + b.codec = codec +} + +func (b *MethodBinding) BatchCall(address common.Address, params, retVal any) (Call, error) { + if !b.isBound(address) { + return Call{}, fmt.Errorf("%w: address (%s) not bound to method (%s) for contract (%s)", commontypes.ErrInvalidConfig, address.Hex(), b.method, b.contractName) + } + + return Call{ + ContractAddress: address, + ContractName: b.contractName, + MethodName: b.method, + Params: params, + ReturnVal: retVal, + }, nil +} + +func (b *MethodBinding) GetLatestValue(ctx context.Context, addr common.Address, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) error { + if !b.isBound(addr) { + return fmt.Errorf("%w: method not bound", commontypes.ErrInvalidType) + } + + data, err := b.codec.Encode(ctx, params, WrapItemType(b.contractName, b.method, true)) + if err != nil { + return err + } + + callMsg := ethereum.CallMsg{ + To: &addr, + From: addr, + Data: data, + } + + block, err := b.blockNumberFromConfidence(ctx, confidenceLevel) + if err != nil { + return err + } + + bytes, err := b.client.CallContract(ctx, callMsg, block) + if err != nil { + return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) + } + + return b.codec.Decode(ctx, bytes, returnVal, WrapItemType(b.contractName, b.method, false)) +} + +func (b *MethodBinding) QueryKey( + _ context.Context, + _ common.Address, + _ query.KeyFilter, + _ query.LimitAndSort, + _ any, +) ([]commontypes.Sequence, error) { + return nil, nil +} + +func (b *MethodBinding) Register(_ context.Context) error { return nil } +func (b *MethodBinding) Unregister(_ context.Context) error { return nil } + +func (b *MethodBinding) blockNumberFromConfidence(ctx context.Context, confidenceLevel primitives.ConfidenceLevel) (*big.Int, error) { + confirmations, err := confidenceToConfirmations(b.confirmationsMapping, confidenceLevel) + if err != nil { + err = fmt.Errorf("%w for contract: %s, method: %s", err, b.contractName, b.method) + if confidenceLevel == primitives.Unconfirmed { + b.lggr.Errorf("%v, now falling back to default contract call behaviour that calls latest state", err) + return nil, nil + } + return nil, err + } + + _, finalized, err := b.ht.LatestAndFinalizedBlock(ctx) + if err != nil { + return nil, err + } + + if confirmations == evmtypes.Finalized { + return big.NewInt(finalized.Number), nil + } else if confirmations == evmtypes.Unconfirmed { + return nil, nil + } + + return nil, fmt.Errorf("unknown evm confirmations: %v for contract: %s, method: %s", confirmations, b.contractName, b.method) +} + +func (b *MethodBinding) isBound(binding common.Address) bool { + b.mu.RLock() + defer b.mu.RUnlock() + + _, exists := b.bindings[binding] + + return exists +} + +func (b *MethodBinding) setBinding(binding common.Address) { + b.mu.Lock() + defer b.mu.Unlock() + + b.bindings[binding] = struct{}{} +} diff --git a/core/services/relay/evm/rpclibmocks/batch_caller.go b/core/services/relay/evm/read/mocks/batch_caller.go similarity index 69% rename from core/services/relay/evm/rpclibmocks/batch_caller.go rename to core/services/relay/evm/read/mocks/batch_caller.go index 0bb2c7f4fa..5f1144b5d8 100644 --- a/core/services/relay/evm/rpclibmocks/batch_caller.go +++ b/core/services/relay/evm/read/mocks/batch_caller.go @@ -1,11 +1,11 @@ // Code generated by mockery v2.43.2. DO NOT EDIT. -package rpclibmocks +package mocks import ( context "context" - evm "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + read "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/read" mock "github.com/stretchr/testify/mock" ) @@ -23,27 +23,27 @@ func (_m *BatchCaller) EXPECT() *BatchCaller_Expecter { } // BatchCall provides a mock function with given fields: ctx, blockNumber, batchRequests -func (_m *BatchCaller) BatchCall(ctx context.Context, blockNumber uint64, batchRequests evm.BatchCall) (evm.BatchResult, error) { +func (_m *BatchCaller) BatchCall(ctx context.Context, blockNumber uint64, batchRequests read.BatchCall) (read.BatchResult, error) { ret := _m.Called(ctx, blockNumber, batchRequests) if len(ret) == 0 { panic("no return value specified for BatchCall") } - var r0 evm.BatchResult + var r0 read.BatchResult var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, evm.BatchCall) (evm.BatchResult, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, uint64, read.BatchCall) (read.BatchResult, error)); ok { return rf(ctx, blockNumber, batchRequests) } - if rf, ok := ret.Get(0).(func(context.Context, uint64, evm.BatchCall) evm.BatchResult); ok { + if rf, ok := ret.Get(0).(func(context.Context, uint64, read.BatchCall) read.BatchResult); ok { r0 = rf(ctx, blockNumber, batchRequests) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(evm.BatchResult) + r0 = ret.Get(0).(read.BatchResult) } } - if rf, ok := ret.Get(1).(func(context.Context, uint64, evm.BatchCall) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, uint64, read.BatchCall) error); ok { r1 = rf(ctx, blockNumber, batchRequests) } else { r1 = ret.Error(1) @@ -60,24 +60,24 @@ type BatchCaller_BatchCall_Call struct { // BatchCall is a helper method to define mock.On call // - ctx context.Context // - blockNumber uint64 -// - batchRequests evm.BatchCall +// - batchRequests read.BatchCall func (_e *BatchCaller_Expecter) BatchCall(ctx interface{}, blockNumber interface{}, batchRequests interface{}) *BatchCaller_BatchCall_Call { return &BatchCaller_BatchCall_Call{Call: _e.mock.On("BatchCall", ctx, blockNumber, batchRequests)} } -func (_c *BatchCaller_BatchCall_Call) Run(run func(ctx context.Context, blockNumber uint64, batchRequests evm.BatchCall)) *BatchCaller_BatchCall_Call { +func (_c *BatchCaller_BatchCall_Call) Run(run func(ctx context.Context, blockNumber uint64, batchRequests read.BatchCall)) *BatchCaller_BatchCall_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(uint64), args[2].(evm.BatchCall)) + run(args[0].(context.Context), args[1].(uint64), args[2].(read.BatchCall)) }) return _c } -func (_c *BatchCaller_BatchCall_Call) Return(_a0 evm.BatchResult, _a1 error) *BatchCaller_BatchCall_Call { +func (_c *BatchCaller_BatchCall_Call) Return(_a0 read.BatchResult, _a1 error) *BatchCaller_BatchCall_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *BatchCaller_BatchCall_Call) RunAndReturn(run func(context.Context, uint64, evm.BatchCall) (evm.BatchResult, error)) *BatchCaller_BatchCall_Call { +func (_c *BatchCaller_BatchCall_Call) RunAndReturn(run func(context.Context, uint64, read.BatchCall) (read.BatchResult, error)) *BatchCaller_BatchCall_Call { _c.Call.Return(run) return _c } diff --git a/core/services/relay/evm/read/mocks/reader.go b/core/services/relay/evm/read/mocks/reader.go new file mode 100644 index 0000000000..6bb9dd70cc --- /dev/null +++ b/core/services/relay/evm/read/mocks/reader.go @@ -0,0 +1,463 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" + + primitives "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + + query "github.com/smartcontractkit/chainlink-common/pkg/types/query" + + read "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/read" + + types "github.com/smartcontractkit/chainlink-common/pkg/types" +) + +// Reader is an autogenerated mock type for the Reader type +type Reader struct { + mock.Mock +} + +type Reader_Expecter struct { + mock *mock.Mock +} + +func (_m *Reader) EXPECT() *Reader_Expecter { + return &Reader_Expecter{mock: &_m.Mock} +} + +// BatchCall provides a mock function with given fields: address, params, retVal +func (_m *Reader) BatchCall(address common.Address, params interface{}, retVal interface{}) (read.Call, error) { + ret := _m.Called(address, params, retVal) + + if len(ret) == 0 { + panic("no return value specified for BatchCall") + } + + var r0 read.Call + var r1 error + if rf, ok := ret.Get(0).(func(common.Address, interface{}, interface{}) (read.Call, error)); ok { + return rf(address, params, retVal) + } + if rf, ok := ret.Get(0).(func(common.Address, interface{}, interface{}) read.Call); ok { + r0 = rf(address, params, retVal) + } else { + r0 = ret.Get(0).(read.Call) + } + + if rf, ok := ret.Get(1).(func(common.Address, interface{}, interface{}) error); ok { + r1 = rf(address, params, retVal) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Reader_BatchCall_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BatchCall' +type Reader_BatchCall_Call struct { + *mock.Call +} + +// BatchCall is a helper method to define mock.On call +// - address common.Address +// - params interface{} +// - retVal interface{} +func (_e *Reader_Expecter) BatchCall(address interface{}, params interface{}, retVal interface{}) *Reader_BatchCall_Call { + return &Reader_BatchCall_Call{Call: _e.mock.On("BatchCall", address, params, retVal)} +} + +func (_c *Reader_BatchCall_Call) Run(run func(address common.Address, params interface{}, retVal interface{})) *Reader_BatchCall_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(common.Address), args[1].(interface{}), args[2].(interface{})) + }) + return _c +} + +func (_c *Reader_BatchCall_Call) Return(_a0 read.Call, _a1 error) *Reader_BatchCall_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Reader_BatchCall_Call) RunAndReturn(run func(common.Address, interface{}, interface{}) (read.Call, error)) *Reader_BatchCall_Call { + _c.Call.Return(run) + return _c +} + +// Bind provides a mock function with given fields: _a0, _a1 +func (_m *Reader) Bind(_a0 context.Context, _a1 ...common.Address) error { + _va := make([]interface{}, len(_a1)) + for _i := range _a1 { + _va[_i] = _a1[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for Bind") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, ...common.Address) error); ok { + r0 = rf(_a0, _a1...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Reader_Bind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bind' +type Reader_Bind_Call struct { + *mock.Call +} + +// Bind is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 ...common.Address +func (_e *Reader_Expecter) Bind(_a0 interface{}, _a1 ...interface{}) *Reader_Bind_Call { + return &Reader_Bind_Call{Call: _e.mock.On("Bind", + append([]interface{}{_a0}, _a1...)...)} +} + +func (_c *Reader_Bind_Call) Run(run func(_a0 context.Context, _a1 ...common.Address)) *Reader_Bind_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]common.Address, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(common.Address) + } + } + run(args[0].(context.Context), variadicArgs...) + }) + return _c +} + +func (_c *Reader_Bind_Call) Return(_a0 error) *Reader_Bind_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Reader_Bind_Call) RunAndReturn(run func(context.Context, ...common.Address) error) *Reader_Bind_Call { + _c.Call.Return(run) + return _c +} + +// GetLatestValue provides a mock function with given fields: ctx, addr, confidence, params, returnVal +func (_m *Reader) GetLatestValue(ctx context.Context, addr common.Address, confidence primitives.ConfidenceLevel, params interface{}, returnVal interface{}) error { + ret := _m.Called(ctx, addr, confidence, params, returnVal) + + if len(ret) == 0 { + panic("no return value specified for GetLatestValue") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, common.Address, primitives.ConfidenceLevel, interface{}, interface{}) error); ok { + r0 = rf(ctx, addr, confidence, params, returnVal) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Reader_GetLatestValue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLatestValue' +type Reader_GetLatestValue_Call struct { + *mock.Call +} + +// GetLatestValue is a helper method to define mock.On call +// - ctx context.Context +// - addr common.Address +// - confidence primitives.ConfidenceLevel +// - params interface{} +// - returnVal interface{} +func (_e *Reader_Expecter) GetLatestValue(ctx interface{}, addr interface{}, confidence interface{}, params interface{}, returnVal interface{}) *Reader_GetLatestValue_Call { + return &Reader_GetLatestValue_Call{Call: _e.mock.On("GetLatestValue", ctx, addr, confidence, params, returnVal)} +} + +func (_c *Reader_GetLatestValue_Call) Run(run func(ctx context.Context, addr common.Address, confidence primitives.ConfidenceLevel, params interface{}, returnVal interface{})) *Reader_GetLatestValue_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(common.Address), args[2].(primitives.ConfidenceLevel), args[3].(interface{}), args[4].(interface{})) + }) + return _c +} + +func (_c *Reader_GetLatestValue_Call) Return(_a0 error) *Reader_GetLatestValue_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Reader_GetLatestValue_Call) RunAndReturn(run func(context.Context, common.Address, primitives.ConfidenceLevel, interface{}, interface{}) error) *Reader_GetLatestValue_Call { + _c.Call.Return(run) + return _c +} + +// QueryKey provides a mock function with given fields: _a0, _a1, _a2, _a3, _a4 +func (_m *Reader) QueryKey(_a0 context.Context, _a1 common.Address, _a2 query.KeyFilter, _a3 query.LimitAndSort, _a4 interface{}) ([]types.Sequence, error) { + ret := _m.Called(_a0, _a1, _a2, _a3, _a4) + + if len(ret) == 0 { + panic("no return value specified for QueryKey") + } + + var r0 []types.Sequence + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Address, query.KeyFilter, query.LimitAndSort, interface{}) ([]types.Sequence, error)); ok { + return rf(_a0, _a1, _a2, _a3, _a4) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Address, query.KeyFilter, query.LimitAndSort, interface{}) []types.Sequence); ok { + r0 = rf(_a0, _a1, _a2, _a3, _a4) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]types.Sequence) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Address, query.KeyFilter, query.LimitAndSort, interface{}) error); ok { + r1 = rf(_a0, _a1, _a2, _a3, _a4) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Reader_QueryKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'QueryKey' +type Reader_QueryKey_Call struct { + *mock.Call +} + +// QueryKey is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 common.Address +// - _a2 query.KeyFilter +// - _a3 query.LimitAndSort +// - _a4 interface{} +func (_e *Reader_Expecter) QueryKey(_a0 interface{}, _a1 interface{}, _a2 interface{}, _a3 interface{}, _a4 interface{}) *Reader_QueryKey_Call { + return &Reader_QueryKey_Call{Call: _e.mock.On("QueryKey", _a0, _a1, _a2, _a3, _a4)} +} + +func (_c *Reader_QueryKey_Call) Run(run func(_a0 context.Context, _a1 common.Address, _a2 query.KeyFilter, _a3 query.LimitAndSort, _a4 interface{})) *Reader_QueryKey_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(common.Address), args[2].(query.KeyFilter), args[3].(query.LimitAndSort), args[4].(interface{})) + }) + return _c +} + +func (_c *Reader_QueryKey_Call) Return(_a0 []types.Sequence, _a1 error) *Reader_QueryKey_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Reader_QueryKey_Call) RunAndReturn(run func(context.Context, common.Address, query.KeyFilter, query.LimitAndSort, interface{}) ([]types.Sequence, error)) *Reader_QueryKey_Call { + _c.Call.Return(run) + return _c +} + +// Register provides a mock function with given fields: _a0 +func (_m *Reader) Register(_a0 context.Context) error { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for Register") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Reader_Register_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Register' +type Reader_Register_Call struct { + *mock.Call +} + +// Register is a helper method to define mock.On call +// - _a0 context.Context +func (_e *Reader_Expecter) Register(_a0 interface{}) *Reader_Register_Call { + return &Reader_Register_Call{Call: _e.mock.On("Register", _a0)} +} + +func (_c *Reader_Register_Call) Run(run func(_a0 context.Context)) *Reader_Register_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *Reader_Register_Call) Return(_a0 error) *Reader_Register_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Reader_Register_Call) RunAndReturn(run func(context.Context) error) *Reader_Register_Call { + _c.Call.Return(run) + return _c +} + +// SetCodec provides a mock function with given fields: _a0 +func (_m *Reader) SetCodec(_a0 types.RemoteCodec) { + _m.Called(_a0) +} + +// Reader_SetCodec_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetCodec' +type Reader_SetCodec_Call struct { + *mock.Call +} + +// SetCodec is a helper method to define mock.On call +// - _a0 types.RemoteCodec +func (_e *Reader_Expecter) SetCodec(_a0 interface{}) *Reader_SetCodec_Call { + return &Reader_SetCodec_Call{Call: _e.mock.On("SetCodec", _a0)} +} + +func (_c *Reader_SetCodec_Call) Run(run func(_a0 types.RemoteCodec)) *Reader_SetCodec_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.RemoteCodec)) + }) + return _c +} + +func (_c *Reader_SetCodec_Call) Return() *Reader_SetCodec_Call { + _c.Call.Return() + return _c +} + +func (_c *Reader_SetCodec_Call) RunAndReturn(run func(types.RemoteCodec)) *Reader_SetCodec_Call { + _c.Call.Return(run) + return _c +} + +// Unbind provides a mock function with given fields: _a0, _a1 +func (_m *Reader) Unbind(_a0 context.Context, _a1 ...common.Address) error { + _va := make([]interface{}, len(_a1)) + for _i := range _a1 { + _va[_i] = _a1[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for Unbind") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, ...common.Address) error); ok { + r0 = rf(_a0, _a1...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Reader_Unbind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Unbind' +type Reader_Unbind_Call struct { + *mock.Call +} + +// Unbind is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 ...common.Address +func (_e *Reader_Expecter) Unbind(_a0 interface{}, _a1 ...interface{}) *Reader_Unbind_Call { + return &Reader_Unbind_Call{Call: _e.mock.On("Unbind", + append([]interface{}{_a0}, _a1...)...)} +} + +func (_c *Reader_Unbind_Call) Run(run func(_a0 context.Context, _a1 ...common.Address)) *Reader_Unbind_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]common.Address, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(common.Address) + } + } + run(args[0].(context.Context), variadicArgs...) + }) + return _c +} + +func (_c *Reader_Unbind_Call) Return(_a0 error) *Reader_Unbind_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Reader_Unbind_Call) RunAndReturn(run func(context.Context, ...common.Address) error) *Reader_Unbind_Call { + _c.Call.Return(run) + return _c +} + +// Unregister provides a mock function with given fields: _a0 +func (_m *Reader) Unregister(_a0 context.Context) error { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for Unregister") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Reader_Unregister_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Unregister' +type Reader_Unregister_Call struct { + *mock.Call +} + +// Unregister is a helper method to define mock.On call +// - _a0 context.Context +func (_e *Reader_Expecter) Unregister(_a0 interface{}) *Reader_Unregister_Call { + return &Reader_Unregister_Call{Call: _e.mock.On("Unregister", _a0)} +} + +func (_c *Reader_Unregister_Call) Run(run func(_a0 context.Context)) *Reader_Unregister_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *Reader_Unregister_Call) Return(_a0 error) *Reader_Unregister_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Reader_Unregister_Call) RunAndReturn(run func(context.Context) error) *Reader_Unregister_Call { + _c.Call.Return(run) + return _c +} + +// NewReader creates a new instance of Reader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewReader(t interface { + mock.TestingT + Cleanup(func()) +}) *Reader { + mock := &Reader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/relay/evm/read/mocks/registrar.go b/core/services/relay/evm/read/mocks/registrar.go new file mode 100644 index 0000000000..670c29317a --- /dev/null +++ b/core/services/relay/evm/read/mocks/registrar.go @@ -0,0 +1,177 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + logpoller "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + mock "github.com/stretchr/testify/mock" +) + +// Registrar is an autogenerated mock type for the Registrar type +type Registrar struct { + mock.Mock +} + +type Registrar_Expecter struct { + mock *mock.Mock +} + +func (_m *Registrar) EXPECT() *Registrar_Expecter { + return &Registrar_Expecter{mock: &_m.Mock} +} + +// HasFilter provides a mock function with given fields: _a0 +func (_m *Registrar) HasFilter(_a0 string) bool { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for HasFilter") + } + + var r0 bool + if rf, ok := ret.Get(0).(func(string) bool); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// Registrar_HasFilter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HasFilter' +type Registrar_HasFilter_Call struct { + *mock.Call +} + +// HasFilter is a helper method to define mock.On call +// - _a0 string +func (_e *Registrar_Expecter) HasFilter(_a0 interface{}) *Registrar_HasFilter_Call { + return &Registrar_HasFilter_Call{Call: _e.mock.On("HasFilter", _a0)} +} + +func (_c *Registrar_HasFilter_Call) Run(run func(_a0 string)) *Registrar_HasFilter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *Registrar_HasFilter_Call) Return(_a0 bool) *Registrar_HasFilter_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Registrar_HasFilter_Call) RunAndReturn(run func(string) bool) *Registrar_HasFilter_Call { + _c.Call.Return(run) + return _c +} + +// RegisterFilter provides a mock function with given fields: _a0, _a1 +func (_m *Registrar) RegisterFilter(_a0 context.Context, _a1 logpoller.Filter) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for RegisterFilter") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, logpoller.Filter) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Registrar_RegisterFilter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RegisterFilter' +type Registrar_RegisterFilter_Call struct { + *mock.Call +} + +// RegisterFilter is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 logpoller.Filter +func (_e *Registrar_Expecter) RegisterFilter(_a0 interface{}, _a1 interface{}) *Registrar_RegisterFilter_Call { + return &Registrar_RegisterFilter_Call{Call: _e.mock.On("RegisterFilter", _a0, _a1)} +} + +func (_c *Registrar_RegisterFilter_Call) Run(run func(_a0 context.Context, _a1 logpoller.Filter)) *Registrar_RegisterFilter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(logpoller.Filter)) + }) + return _c +} + +func (_c *Registrar_RegisterFilter_Call) Return(_a0 error) *Registrar_RegisterFilter_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Registrar_RegisterFilter_Call) RunAndReturn(run func(context.Context, logpoller.Filter) error) *Registrar_RegisterFilter_Call { + _c.Call.Return(run) + return _c +} + +// UnregisterFilter provides a mock function with given fields: _a0, _a1 +func (_m *Registrar) UnregisterFilter(_a0 context.Context, _a1 string) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for UnregisterFilter") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Registrar_UnregisterFilter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UnregisterFilter' +type Registrar_UnregisterFilter_Call struct { + *mock.Call +} + +// UnregisterFilter is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 string +func (_e *Registrar_Expecter) UnregisterFilter(_a0 interface{}, _a1 interface{}) *Registrar_UnregisterFilter_Call { + return &Registrar_UnregisterFilter_Call{Call: _e.mock.On("UnregisterFilter", _a0, _a1)} +} + +func (_c *Registrar_UnregisterFilter_Call) Run(run func(_a0 context.Context, _a1 string)) *Registrar_UnregisterFilter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string)) + }) + return _c +} + +func (_c *Registrar_UnregisterFilter_Call) Return(_a0 error) *Registrar_UnregisterFilter_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Registrar_UnregisterFilter_Call) RunAndReturn(run func(context.Context, string) error) *Registrar_UnregisterFilter_Call { + _c.Call.Return(run) + return _c +} + +// NewRegistrar creates a new instance of Registrar. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewRegistrar(t interface { + mock.TestingT + Cleanup(func()) +}) *Registrar { + mock := &Registrar{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/relay/evm/write_target.go b/core/services/relay/evm/write_target.go index 6d54336057..8c71030f8a 100644 --- a/core/services/relay/evm/write_target.go +++ b/core/services/relay/evm/write_target.go @@ -6,6 +6,7 @@ import ( "fmt" chainselectors "github.com/smartcontractkit/chain-selectors" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/logger" @@ -47,6 +48,16 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain return nil, err } + err = cr.Bind(ctx, []commontypes.BoundContract{ + { + Name: "forwarder", + Address: config.ForwarderAddress().String(), + }, + }) + if err != nil { + return nil, err + } + chainWriterConfig := relayevmtypes.ChainWriterConfig{ Contracts: map[string]*relayevmtypes.ContractConfig{ "forwarder": { diff --git a/core/services/relay/evm/write_target_test.go b/core/services/relay/evm/write_target_test.go index 795b23f80e..3721eec62a 100644 --- a/core/services/relay/evm/write_target_test.go +++ b/core/services/relay/evm/write_target_test.go @@ -21,6 +21,7 @@ import ( evmcapabilities "github.com/smartcontractkit/chainlink/v2/core/capabilities" evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" gasmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" + pollermocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" txmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -101,6 +102,7 @@ func TestEvmWrite(t *testing.T) { chain := evmmocks.NewChain(t) txManager := txmmocks.NewMockEvmTxManager(t) evmClient := evmclimocks.NewClient(t) + poller := pollermocks.NewLogPoller(t) // This is a very error-prone way to mock an on-chain response to a GetLatestValue("getTransmissionInfo") call // It's a bit of a hack, but it's the best way to do it without a lot of refactoring @@ -111,7 +113,7 @@ func TestEvmWrite(t *testing.T) { chain.On("ID").Return(big.NewInt(11155111)) chain.On("TxManager").Return(txManager) - chain.On("LogPoller").Return(nil) + chain.On("LogPoller").Return(poller) ht := mocks.NewHeadTracker[*types.Head, common.Hash](t) ht.On("LatestAndFinalizedBlock", mock.Anything).Return(&types.Head{}, &types.Head{}, nil) @@ -119,6 +121,8 @@ func TestEvmWrite(t *testing.T) { chain.On("Client").Return(evmClient) + poller.EXPECT().HasFilter(mock.Anything).Return(false) + cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { a := testutils.NewAddress() addr, err2 := types.NewEIP55Address(a.Hex()) diff --git a/go.md b/go.md index b0128221ef..21f43e0d26 100644 --- a/go.md +++ b/go.md @@ -66,6 +66,7 @@ flowchart LR chainlink-data-streams --> grpc-proxy chainlink-feeds --> chainlink-common chainlink-feeds --> libocr + chainlink-feeds --> grpc-proxy chainlink-solana --> chainlink-common chainlink-solana --> libocr chainlink-starknet/relayer --> chainlink-common diff --git a/go.mod b/go.mod index 9c22104b60..da25f470f0 100644 --- a/go.mod +++ b/go.mod @@ -74,11 +74,11 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 - github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 diff --git a/go.sum b/go.sum index 41581f6ede..748b5fb1e9 100644 --- a/go.sum +++ b/go.sum @@ -1145,16 +1145,16 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b h1:/PQDTP/ETmEXCv3qokVs5JqMcHDFP8TWdkcQAzs/nQg= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f h1:a6zEDLYgTQ4G+9PgLX8G2bF40BdsOY5//5i+whYwLlQ= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 h1:3VbeaqoBblboQ3ytpM7UZzL7MXoHctaaXGGkJ8XkDhY= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 h1:Q19HQPzISHKEIP0rNFGEiIFvMEeAgb1YRXEFnyBMnNM= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 h1:88ZNrxZd0Uxn9934G/3L5AABTX13iorQJdUXcSUewwg= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5/go.mod h1:/QPAcfj5RQ4pNmDBLJ/Or7EjMAvFU3Xb1pM9gl0jfao= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a h1:0zbG9reudNAJC/Rwe3tYX7kshVtOEXXAhk0uLg/62Y4= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 8b06e6aca6..f36a2ccb8f 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -36,8 +36,8 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 @@ -405,7 +405,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect - github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 095d822fca..642679410e 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1423,16 +1423,16 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b h1:/PQDTP/ETmEXCv3qokVs5JqMcHDFP8TWdkcQAzs/nQg= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f h1:a6zEDLYgTQ4G+9PgLX8G2bF40BdsOY5//5i+whYwLlQ= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 h1:3VbeaqoBblboQ3ytpM7UZzL7MXoHctaaXGGkJ8XkDhY= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 h1:Q19HQPzISHKEIP0rNFGEiIFvMEeAgb1YRXEFnyBMnNM= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 h1:88ZNrxZd0Uxn9934G/3L5AABTX13iorQJdUXcSUewwg= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5/go.mod h1:/QPAcfj5RQ4pNmDBLJ/Or7EjMAvFU3Xb1pM9gl0jfao= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a h1:0zbG9reudNAJC/Rwe3tYX7kshVtOEXXAhk0uLg/62Y4= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index cfd0c02b66..22c44365bc 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 @@ -60,7 +60,7 @@ require ( github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sergi/go-diff v1.3.1 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 // indirect github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect @@ -397,7 +397,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect - github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 // indirect + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 507bc79df4..07b7724340 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1393,16 +1393,16 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b h1:/PQDTP/ETmEXCv3qokVs5JqMcHDFP8TWdkcQAzs/nQg= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240905153234-86019f205c9b/go.mod h1:Z9lQ5t20kRk28pzRLnqAJZUVOw8E6/siA3P3MLyKqoM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f h1:a6zEDLYgTQ4G+9PgLX8G2bF40BdsOY5//5i+whYwLlQ= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240906132254-14a5c7af361f/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 h1:3VbeaqoBblboQ3ytpM7UZzL7MXoHctaaXGGkJ8XkDhY= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 h1:Q19HQPzISHKEIP0rNFGEiIFvMEeAgb1YRXEFnyBMnNM= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827 h1:BCHu4pNP6arrcHLEWx61XjLaonOd2coQNyL0NTUcaMc= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240710170203-5b41615da827/go.mod h1:OPX+wC2TWQsyLNpR7daMt2vMpmsNcoBxbZyGTHr6tiA= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 h1:88ZNrxZd0Uxn9934G/3L5AABTX13iorQJdUXcSUewwg= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5/go.mod h1:/QPAcfj5RQ4pNmDBLJ/Or7EjMAvFU3Xb1pM9gl0jfao= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a h1:0zbG9reudNAJC/Rwe3tYX7kshVtOEXXAhk0uLg/62Y4= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= From 01b64059741b05ee3e333118cc881f5b9a5bdeac Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 9 Sep 2024 16:09:49 -0500 Subject: [PATCH 311/432] integration-tests/load: sort go.mod (#14349) --- integration-tests/load/go.mod | 77 +++++++++++++++++------------------ 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 22c44365bc..0fee042f5a 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -30,51 +30,12 @@ require ( ) require ( + contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.4 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/math v1.3.0 // indirect - github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect - github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect - github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.28 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 // indirect - github.com/aws/smithy-go v1.20.4 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect - github.com/containerd/errdefs v0.1.0 // indirect - github.com/go-viper/mapstructure/v2 v2.1.0 // indirect - github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect - github.com/linxGnu/grocksdb v1.7.16 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect - github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/sergi/go-diff v1.3.1 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect - github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 // indirect - github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect - github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect - github.com/sourcegraph/conc v0.3.0 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect - k8s.io/apimachinery v0.31.0 // indirect -) - -// avoids ambigious imports of indirect dependencies -exclude github.com/hashicorp/consul v1.2.1 - -require ( - contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect dario.cat/mergo v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -105,15 +66,31 @@ require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/avast/retry-go v3.0.0+incompatible // indirect github.com/avast/retry-go/v4 v4.6.0 // indirect + github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect github.com/aws/aws-sdk-go v1.45.25 // indirect + github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect + github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.28 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.32.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 // indirect github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect github.com/aws/jsii-runtime-go v1.75.0 // indirect + github.com/aws/smithy-go v1.20.4 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect github.com/blendle/zapdriver v1.3.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/buger/jsonparser v1.1.1 // indirect @@ -141,6 +118,7 @@ require ( github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/containerd/containerd v1.7.18 // indirect github.com/containerd/continuity v0.4.3 // indirect + github.com/containerd/errdefs v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect @@ -221,6 +199,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/go-viper/mapstructure/v2 v2.1.0 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect github.com/goccy/go-json v0.10.2 // indirect @@ -235,6 +214,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/btree v1.1.2 // indirect + github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-github/v41 v41.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect @@ -323,6 +303,7 @@ require ( github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect + github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -330,6 +311,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.56 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect @@ -384,26 +366,36 @@ require ( github.com/rivo/uniseg v0.4.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/scylladb/go-reflectx v1.0.1 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/segmentio/ksuid v1.0.4 // indirect github.com/sercand/kuberesolver/v5 v5.1.1 // indirect + github.com/sergi/go-diff v1.3.1 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect + github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 // indirect + github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect + github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.8.1 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cobra v1.8.1 // indirect @@ -484,6 +476,7 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/guregu/null.v4 v4.0.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect @@ -492,6 +485,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.31.0 // indirect k8s.io/apiextensions-apiserver v0.31.0 // indirect + k8s.io/apimachinery v0.31.0 // indirect k8s.io/cli-runtime v0.31.0 // indirect k8s.io/client-go v1.5.2 // indirect k8s.io/component-base v0.31.0 // indirect @@ -510,6 +504,9 @@ require ( sigs.k8s.io/yaml v1.4.0 // indirect; indirect nhooyr.io/websocket v1.8.7 // indirect ) +// avoids ambigious imports of indirect dependencies +exclude github.com/hashicorp/consul v1.2.1 + replace ( // until merged upstream: https://github.com/omissis/go-jsonschema/pull/264 github.com/atombender/go-jsonschema => github.com/nolag/go-jsonschema v0.16.0-rtinianov From 340d0dd87569cac3a3f09bc48b025c597335c2f5 Mon Sep 17 00:00:00 2001 From: Graham Goh Date: Tue, 10 Sep 2024 17:41:07 +1000 Subject: [PATCH 312/432] test(smoke): register multiple job distributors (#14327) Now that we are supporting multiple job distributors per node, I want to have a smoke test that verifies this behaviour. We do need to enable the `MultiFeedsManagers` feature tag. --- .github/e2e-tests.yml | 10 ++++ integration-tests/docker/test_env/cl_node.go | 27 +++++++-- integration-tests/load/go.mod | 3 +- integration-tests/load/go.sum | 6 ++ .../smoke/job_distributor_test.go | 59 +++++++++++++++++++ .../job_distributor/job_distributor.toml | 46 +++++++++++++++ 6 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 integration-tests/smoke/job_distributor_test.go create mode 100644 integration-tests/testconfig/job_distributor/job_distributor.toml diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 30d1bf28a8..b08de2074e 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -868,6 +868,16 @@ runner-test-matrix: E2E_TEST_CHAINLINK_UPGRADE_IMAGE: '{{ env.QA_CHAINLINK_IMAGE }}' E2E_TEST_CHAINLINK_UPGRADE_VERSION: '{{ env.DEFAULT_CHAINLINK_VERSION }}' + - id: smoke/job_distributor_test.go:* + path: integration-tests/smoke/job_distributor_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E Core Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ && go test smoke/job_distributor_test.go -timeout 30m -count=1 -json + pyroscope_env: ci-smoke-jd-evm-simulated + # END: Other tests # START: CCIP tests diff --git a/integration-tests/docker/test_env/cl_node.go b/integration-tests/docker/test_env/cl_node.go index a37a6204f6..02179403ac 100644 --- a/integration-tests/docker/test_env/cl_node.go +++ b/integration-tests/docker/test_env/cl_node.go @@ -33,11 +33,13 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/client" it_utils "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/smartcontractkit/chainlink/integration-tests/utils/templates" + grapqlClient "github.com/smartcontractkit/chainlink/integration-tests/web/sdk/client" ) var ( - ErrConnectNodeClient = "could not connect Node HTTP Client" - ErrStartCLNodeContainer = "failed to start CL node container" + ErrConnectNodeClient = "could not connect Node HTTP Client" + ErrConnectNodeGraphqlClient = "could not connect Node Graphql Client" + ErrStartCLNodeContainer = "failed to start CL node container" ) const ( @@ -54,6 +56,7 @@ type ClNode struct { UserEmail string `json:"userEmail"` UserPassword string `json:"userPassword"` AlwaysPullImage bool `json:"-"` + GraphqlAPI grapqlClient.Client `json:"-"` t *testing.T l zerolog.Logger } @@ -339,19 +342,25 @@ func (n *ClNode) containerStartOrRestart(restartDb bool) error { Str("userEmail", n.UserEmail). Str("userPassword", n.UserPassword). Msg("Started Chainlink Node container") - clClient, err := client.NewChainlinkClient(&client.ChainlinkConfig{ + config := &client.ChainlinkConfig{ URL: clEndpoint, Email: n.UserEmail, Password: n.UserPassword, InternalIP: ip, - }, - n.l) + } + clClient, err := client.NewChainlinkClient(config, n.l) if err != nil { return fmt.Errorf("%s err: %w", ErrConnectNodeClient, err) } + graphqlClient, err := newChainLinkGraphqlClient(config) + if err != nil { + return fmt.Errorf("%s err: %w", ErrConnectNodeGraphqlClient, err) + } + n.Container = container n.API = clClient + n.GraphqlAPI = graphqlClient return nil } @@ -491,3 +500,11 @@ func (n *ClNode) getContainerRequest(secrets string) ( }, }, nil } + +func newChainLinkGraphqlClient(c *client.ChainlinkConfig) (grapqlClient.Client, error) { + nodeClient, err := grapqlClient.New(c.URL, grapqlClient.Credentials{Email: c.Email, Password: c.Password}) + if err != nil { + return nil, err + } + return nodeClient, nil +} diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 0fee042f5a..10c81574b6 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -51,6 +51,7 @@ require ( github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect github.com/K-Phoen/sdk v0.12.4 // indirect + github.com/Khan/genqlient v0.7.0 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect @@ -375,7 +376,6 @@ require ( github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/segmentio/ksuid v1.0.4 // indirect github.com/sercand/kuberesolver/v5 v5.1.1 // indirect - github.com/sergi/go-diff v1.3.1 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect @@ -426,6 +426,7 @@ require ( github.com/umbracle/ethgo v0.1.3 // indirect github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 // indirect github.com/valyala/fastjson v1.4.1 // indirect + github.com/vektah/gqlparser/v2 v2.5.11 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 07b7724340..ebcf84f2e6 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -129,6 +129,8 @@ github.com/K-Phoen/grabana v0.22.1 h1:b/O+C3H2H6VNYSeMCYUO4X4wYuwFXgBcRkvYa+fjpQ github.com/K-Phoen/grabana v0.22.1/go.mod h1:3LTXrTzQzTKTgvKSXdRjlsJbizSOW/V23Q3iX00R5bU= github.com/K-Phoen/sdk v0.12.4 h1:j2EYuBJm3zDTD0fGKACVFWxAXtkR0q5QzfVqxmHSeGQ= github.com/K-Phoen/sdk v0.12.4/go.mod h1:qmM0wO23CtoDux528MXPpYvS4XkRWkWX6rvX9Za8EVU= +github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= +github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -179,6 +181,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -1547,6 +1551,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE= github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= +github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/wiremock/go-wiremock v1.9.0 h1:9xcU4/IoEfgCaH4TGhQTtiQyBh2eMtu9JB6ppWduK+E= diff --git a/integration-tests/smoke/job_distributor_test.go b/integration-tests/smoke/job_distributor_test.go new file mode 100644 index 0000000000..09ad7c2812 --- /dev/null +++ b/integration-tests/smoke/job_distributor_test.go @@ -0,0 +1,59 @@ +package smoke + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink/integration-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + graphqlClient "github.com/smartcontractkit/chainlink/integration-tests/web/sdk/client" +) + +func TestRegisteringMultipleJobDistributor(t *testing.T) { + t.Parallel() + + l := logging.GetTestLogger(t) + + config, err := tc.GetConfig([]string{"Smoke"}, "job_distributor") + require.NoError(t, err, "Error getting config") + + privateNetwork, err := actions.EthereumNetworkConfigFromConfig(l, &config) + require.NoError(t, err, "Error building ethereum network config") + + env, err := test_env.NewCLTestEnvBuilder(). + WithTestConfig(&config). + WithTestInstance(t). + WithStandardCleanup(). + WithPrivateEthereumNetwork(privateNetwork.EthereumNetworkConfig). + WithCLNodes(1). + WithStandardCleanup(). + Build() + require.NoError(t, err) + + ctx := context.Background() + err = env.ClCluster.Nodes[0].GraphqlAPI.CreateJobDistributor(ctx, graphqlClient.FeedsManagerInput{ + Name: "job-distributor-1", + Uri: "http://job-distributor-1:8080", + PublicKey: "54227538d9352e0a24550a80ab6a7af6e4f1ffbb8a604e913cbb81c484a7f97d", + }) + require.NoError(t, err, "Creating first job distributor in chainlink node shouldn't fail") + + err = env.ClCluster.Nodes[0].GraphqlAPI.CreateJobDistributor(ctx, graphqlClient.FeedsManagerInput{ + Name: "job-distributor-2", + Uri: "http://job-distributor-2:8080", + PublicKey: "37346b7ea98af21e1309847e00f772826ac3689fe990b1920d01efc58ad2f250", + }) + require.NoError(t, err, "Creating second job distributor in chainlink node shouldn't fail") + + distributors, err := env.ClCluster.Nodes[0].GraphqlAPI.ListJobDistributors(ctx) + require.NoError(t, err, "Listing job distributors in chainlink node shouldn't fail") + require.Len(t, distributors.FeedsManagers.Results, 2, "There should be 2 job distributors") + + assert.Equal(t, "job-distributor-1", distributors.FeedsManagers.Results[0].Name) + assert.Equal(t, "job-distributor-2", distributors.FeedsManagers.Results[1].Name) +} diff --git a/integration-tests/testconfig/job_distributor/job_distributor.toml b/integration-tests/testconfig/job_distributor/job_distributor.toml new file mode 100644 index 0000000000..6dae45fb14 --- /dev/null +++ b/integration-tests/testconfig/job_distributor/job_distributor.toml @@ -0,0 +1,46 @@ +[NodeConfig] +BaseConfigTOML = """ +[Feature] +FeedsManager = true +LogPoller = true +UICSAKeys = true +MultiFeedsManagers = true + +[Log] +Level = 'debug' +JSONConsole = true + +[Log.File] +MaxSize = '0b' + +[WebServer] +AllowOrigins = '*' +HTTPPort = 6688 +SecureCookies = false +HTTPWriteTimeout = '3m' +SessionTimeout = '999h0m0s' + +[WebServer.RateLimit] +Authenticated = 2000 +Unauthenticated = 1000 + +[WebServer.TLS] +HTTPSPort = 0 + +[Database] +MaxIdleConns = 20 +MaxOpenConns = 40 +MigrateOnStartup = true + +[OCR] +Enabled = true +DefaultTransactionQueueDepth = 0 + +[P2P] +[P2P.V2] +Enabled = true +ListenAddresses = ['0.0.0.0:6690'] +AnnounceAddresses = ['0.0.0.0:6690'] +DeltaDial = '500ms' +DeltaReconcile = '5s' +""" From 0220e6938993aae883c3565c4ed55bf7fcd48eb7 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Tue, 10 Sep 2024 10:36:32 +0200 Subject: [PATCH 313/432] bump ctf (#14380) --- integration-tests/go.mod | 12 ++++++------ integration-tests/go.sum | 24 ++++++++++++------------ integration-tests/load/go.mod | 12 ++++++------ integration-tests/load/go.sum | 24 ++++++++++++------------ 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index f36a2ccb8f..da13887e67 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -39,7 +39,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 - github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 @@ -53,10 +53,10 @@ require ( go.uber.org/atomic v1.11.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.26.0 + golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa golang.org/x/sync v0.8.0 - golang.org/x/text v0.17.0 + golang.org/x/text v0.18.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 gopkg.in/guregu/null.v4 v4.0.0 @@ -473,10 +473,10 @@ require ( go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect + golang.org/x/net v0.29.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/term v0.24.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.24.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 642679410e..129a7e2fd3 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1439,8 +1439,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202407 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 h1:OBOOdlZzowUt1mKDGnMzskuVqOJHSQ49w/2fTYHZEiM= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0/go.mod h1:nLOy8QkAmofo7+HR6yOyKxdaA93tHjyjz4caM+eZAn4= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 h1:Owb1MQZn0NZHwtZAnPZE6TVoTx6xLrfPaUdeOYswE9M= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5/go.mod h1:hS4yNF94C1lkS9gvtFXW8Km8K9NzGeR20aNfkqo5qbE= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= @@ -1738,8 +1738,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1833,8 +1833,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1947,8 +1947,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1960,8 +1960,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1975,8 +1975,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 10c81574b6..105af4be52 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,7 +17,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 - github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c @@ -459,15 +459,15 @@ require ( go.uber.org/zap v1.27.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.26.0 // indirect + golang.org/x/crypto v0.27.0 // indirect golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect + golang.org/x/net v0.29.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/term v0.24.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.24.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index ebcf84f2e6..c6d5b2eb29 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1413,8 +1413,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202407 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0 h1:OBOOdlZzowUt1mKDGnMzskuVqOJHSQ49w/2fTYHZEiM= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.0/go.mod h1:nLOy8QkAmofo7+HR6yOyKxdaA93tHjyjz4caM+eZAn4= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 h1:Owb1MQZn0NZHwtZAnPZE6TVoTx6xLrfPaUdeOYswE9M= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5/go.mod h1:hS4yNF94C1lkS9gvtFXW8Km8K9NzGeR20aNfkqo5qbE= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= @@ -1712,8 +1712,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1807,8 +1807,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1919,8 +1919,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1932,8 +1932,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1947,8 +1947,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 915b01b3ad0c1710f4381650f0119d1ac3237647 Mon Sep 17 00:00:00 2001 From: Makram Date: Tue, 10 Sep 2024 13:22:53 +0400 Subject: [PATCH 314/432] bump chainlink-ccip and fix tests (#14374) * bump chainlink-ccip and fix tests * integration-test: bump ctf/lib to v1.50.2 --- core/capabilities/ccip/ccip_integration_tests/helpers.go | 1 - .../ccip/ccip_integration_tests/home_chain_test.go | 1 - core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/deployment/ccip/deploy_home_chain.go | 1 - integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 11 files changed, 12 insertions(+), 15 deletions(-) diff --git a/core/capabilities/ccip/ccip_integration_tests/helpers.go b/core/capabilities/ccip/ccip_integration_tests/helpers.go index 15c603c647..25baddfb48 100644 --- a/core/capabilities/ccip/ccip_integration_tests/helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/helpers.go @@ -436,7 +436,6 @@ func AddChainConfig( encodedExtraChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ GasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(1000), DAGasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(0), - FinalityDepth: 10, OptimisticConfirmations: 1, }) require.NoError(t, err) diff --git a/core/capabilities/ccip/ccip_integration_tests/home_chain_test.go b/core/capabilities/ccip/ccip_integration_tests/home_chain_test.go index c8b261eba1..f0921cc8f4 100644 --- a/core/capabilities/ccip/ccip_integration_tests/home_chain_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/home_chain_test.go @@ -41,7 +41,6 @@ func TestHomeChainReader(t *testing.T) { encodedChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ GasPriceDeviationPPB: cciptypes.NewBigIntFromInt64(1000), DAGasPriceDeviationPPB: cciptypes.NewBigIntFromInt64(1_000_000), - FinalityDepth: -1, OptimisticConfirmations: 1, }) require.NoError(t, err) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 1a19bf6927..72117d7b0c 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -270,7 +270,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 5644fafbb2..1a3c4da4cd 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1188,8 +1188,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 h1:3VbeaqoBblboQ3ytpM7UZzL7MXoHctaaXGGkJ8XkDhY= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1:siC6AoTs4889FwiqgEp0sC6S8nFlDzVTZAmUX7cV7aM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 h1:Q19HQPzISHKEIP0rNFGEiIFvMEeAgb1YRXEFnyBMnNM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/go.mod b/go.mod index da25f470f0..5f112a9eb5 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 diff --git a/go.sum b/go.sum index 748b5fb1e9..24d270bc8b 100644 --- a/go.sum +++ b/go.sum @@ -1145,8 +1145,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 h1:3VbeaqoBblboQ3ytpM7UZzL7MXoHctaaXGGkJ8XkDhY= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1:siC6AoTs4889FwiqgEp0sC6S8nFlDzVTZAmUX7cV7aM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 h1:Q19HQPzISHKEIP0rNFGEiIFvMEeAgb1YRXEFnyBMnNM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/deployment/ccip/deploy_home_chain.go b/integration-tests/deployment/ccip/deploy_home_chain.go index 5eb03f1d23..33e9c14f8b 100644 --- a/integration-tests/deployment/ccip/deploy_home_chain.go +++ b/integration-tests/deployment/ccip/deploy_home_chain.go @@ -172,7 +172,6 @@ func AddChainConfig( encodedExtraChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ GasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(1000), DAGasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(0), - FinalityDepth: 10, OptimisticConfirmations: 1, }) if err != nil { diff --git a/integration-tests/go.mod b/integration-tests/go.mod index da13887e67..83a2b11f7d 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -36,7 +36,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 129a7e2fd3..e9e31afc42 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1423,8 +1423,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 h1:3VbeaqoBblboQ3ytpM7UZzL7MXoHctaaXGGkJ8XkDhY= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1:siC6AoTs4889FwiqgEp0sC6S8nFlDzVTZAmUX7cV7aM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 h1:Q19HQPzISHKEIP0rNFGEiIFvMEeAgb1YRXEFnyBMnNM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 105af4be52..7085cbd228 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -382,7 +382,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index c6d5b2eb29..87a8c082f0 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1397,8 +1397,8 @@ github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1Wo github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6 h1:3VbeaqoBblboQ3ytpM7UZzL7MXoHctaaXGGkJ8XkDhY= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240909152240-a6969c1002e6/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1:siC6AoTs4889FwiqgEp0sC6S8nFlDzVTZAmUX7cV7aM= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 h1:Q19HQPzISHKEIP0rNFGEiIFvMEeAgb1YRXEFnyBMnNM= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= From b09fdb75c9efe3a1edc9f582531dc4af96085b6e Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 10 Sep 2024 11:51:30 +0200 Subject: [PATCH 315/432] add missing $ before variable name (#14379) --- .github/workflows/client-compatibility-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index e61829c933..761759193e 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -170,7 +170,7 @@ jobs: implementations_arr+=("nethermind") fi new_reth=$(ghlatestreleasechecker "paradigmxyz/reth" $RELEASED_DAYS_AGO) - if [ "new_reth" != "none" ]; then + if [ "$new_reth" != "none" ]; then echo "New reth release found: $new_reth" implementations_arr+=("reth") fi From ed6736e58fb0597a07473cd3c2d6eced97bd5018 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 10 Sep 2024 14:02:38 +0200 Subject: [PATCH 316/432] fix changes step name (#14381) --- .github/workflows/solidity-foundry-artifacts.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/solidity-foundry-artifacts.yml b/.github/workflows/solidity-foundry-artifacts.yml index 613272e091..b8f56d977e 100644 --- a/.github/workflows/solidity-foundry-artifacts.yml +++ b/.github/workflows/solidity-foundry-artifacts.yml @@ -39,8 +39,8 @@ jobs: outputs: product_changes: ${{ steps.changes-transform.outputs.product_changes }} product_files: ${{ steps.changes-transform.outputs.product_files }} - changeset_changes: ${{ steps.changes.outputs.changeset }} - changeset_files: ${{ steps.changes.outputs.changeset_files }} + changeset_changes: ${{ steps.changes-dorny.outputs.changeset }} + changeset_files: ${{ steps.changes-dorny.outputs.changeset_files }} steps: - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 From 5c37f41d9cdedbc80b5e5c9515d6c4f7ee270d5a Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:32:03 +0200 Subject: [PATCH 317/432] TT-1307 Refactor other VRFv2 Plus Github Workflows to use E2E Reusable Workflow (#14368) * Refactor on-demand-vrfv2plus-performance-test.yml * Add slack notification for on-demand-vrfv2plus-smoke-tests.yml * Fix * fix 2 * remove debug info * update color of slack notification * Migrate on-demand-vrfv2-eth2-clients-test * fix * Use ubuntu-latest * Update workflow slack notifications * Fix test id when running custom tests * Use notify_user_id_on_failure * Fix SLACK_BOT_TOKEN * Fix SLACK_NOTIFICATION_AFTER_TESTS_CHANNEL_ID --- .../on-demand-vrfv2plus-eth2-clients-test.yml | 93 +++++------- .../on-demand-vrfv2plus-performance-test.yml | 143 +++++++++--------- .../on-demand-vrfv2plus-smoke-tests.yml | 11 +- .../run-e2e-tests-reusable-workflow.yml | 53 +++++-- 4 files changed, 154 insertions(+), 146 deletions(-) diff --git a/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml b/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml index 0636a29944..f3921a814f 100644 --- a/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml @@ -17,62 +17,37 @@ on: type: string jobs: - vrfv2plus_smoke_test: - name: VRFV2Plus Smoke Test with custom EL client - environment: integration - runs-on: ubuntu22.04-8cores-32GB - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - env: - TEST_LOG_LEVEL: debug - REF_NAME: ${{ github.head_ref || github.ref_name }} - steps: - - name: Checkout code - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Show test config override path in summary - if: ${{ inputs.test_config_override_path }} - run: | - echo "### Test config override path" >> $GITHUB_STEP_SUMMARY - echo "[${{ inputs.test_config_override_path }}]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/blob/${{ github.sha }}/${{ inputs.test_config_override_path }})" >> $GITHUB_STEP_SUMMARY - - name: Show test secrets override key in summary - if: ${{ inputs.test_secrets_override_key }} - run: | - echo "### Test secrets override key" >> $GITHUB_STEP_SUMMARY - echo "${{ inputs.test_secrets_override_key }}" >> $GITHUB_STEP_SUMMARY - - name: Show chainlink version in summary - run: | - echo "### Chainlink version" >> $GITHUB_STEP_SUMMARY - echo "${{ inputs.chainlink_version }}" >> $GITHUB_STEP_SUMMARY - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 - env: - E2E_TEST_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - E2E_TEST_CHAINLINK_VERSION: ${{ inputs.chainlink_version }} # Default chainlink version if not overrided in the test config - E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" - E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - with: - test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -run ^TestVRFv2Plus$/^Link_Billing$ ./smoke/vrfv2plus_test.go 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} - test_config_override_path: ${{ inputs.test_config_override_path }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: vrfplus-test-logs - artifacts_location: | - ./integration-tests/smoke/logs/ - ./integration-tests/smoke/db_dumps/ - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - should_cleanup: false - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: "" - + run-e2e-tests-workflow: + name: Run E2E Tests + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + custom_test_list_json: > + { + "tests": [ + { + "id": "TestVRFv2Plus", + "path": "integration-tests/smoke/vrfv2plus_test.go", + "runs_on": "ubuntu-latest", + "test_env_type": "docker", + "test_cmd": "cd integration-tests/smoke && go test -timeout 30m -count=1 -json -run ^TestVRFv2Plus$/^Link_Billing$ .vrfv2plus_test.go + } + ] + } + test_config_override_path: ${{ inputs.test_config_override_path }} + chainlink_version: ${{ inputs.chainlink_version }} + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} diff --git a/.github/workflows/on-demand-vrfv2plus-performance-test.yml b/.github/workflows/on-demand-vrfv2plus-performance-test.yml index 4cb99eed62..0744a93b26 100644 --- a/.github/workflows/on-demand-vrfv2plus-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-performance-test.yml @@ -22,82 +22,75 @@ on: description: Chainlink image version to use default: develop required: false + type: string + notify_user_id_on_failure: + description: 'Enter Slack user ID to notify on test failure' + required: false type: string jobs: - vrfv2plus_performance_test: - name: VRFV2 Plus Performance Test - environment: integration - runs-on: ubuntu22.04-8cores-32GB - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - env: - LOKI_URL: ${{ secrets.LOKI_URL }} - LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} - LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} - TEST_TYPE: ${{ inputs.performanceTestType }} - TEST_LOG_LEVEL: debug - REF_NAME: ${{ github.head_ref || github.ref_name }} - SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} - SLACK_CHANNEL: ${{ secrets.QA_VRF_SLACK_CHANNEL }} - GRAFANA_URL: "http://localhost:8080/primary" - GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - WASP_LOG_LEVEL: info - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: on-demand-vrfv2-plus-performance-test - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ${{ inputs.network }} VRFV2 Plus Performance Test - continue-on-error: true - - name: Checkout code - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Show test config override path in summary - if: ${{ inputs.test_config_override_path }} - run: | - echo "### Test config override path" >> $GITHUB_STEP_SUMMARY - echo "[${{ inputs.test_config_override_path }}]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/blob/${{ github.sha }}/${{ inputs.test_config_override_path }})" >> $GITHUB_STEP_SUMMARY - - name: Show test secrets override key in summary - if: ${{ inputs.test_secrets_override_key }} - run: | - echo "### Test secrets override key" >> $GITHUB_STEP_SUMMARY - echo "${{ inputs.test_secrets_override_key }}" >> $GITHUB_STEP_SUMMARY - - name: Show chainlink version in summary + set-tests-to-run: + name: Set tests to run + runs-on: ubuntu-latest + outputs: + test_list: ${{ steps.set-tests.outputs.test_list }} + steps: + - name: Generate Test List JSON + id: set-tests run: | - echo "### Chainlink version" >> $GITHUB_STEP_SUMMARY - echo "${{ inputs.chainlink_version }}" >> $GITHUB_STEP_SUMMARY - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 - env: - E2E_TEST_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - E2E_TEST_CHAINLINK_VERSION: ${{ inputs.chainlink_version }} # Default chainlink version if not overrided in the test config - E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" - E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - with: - test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run "${{ inputs.test_list_regex }}" ./vrfv2plus - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} - test_config_override_path: ${{ inputs.test_config_override_path }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: vrf-test-logs - artifacts_location: ./integration-tests/load/vrfv2plus/logs/ - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - should_cleanup: false - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + TEST_CMD='cd integration-tests/load && go test -v -count=1 -timeout 24h -run "${{ inputs.test_list_regex }}" ./vrfv2plus' + TEST_CONFIG_OVERRIDE_PATH=${{ inputs.test_config_override_path }} + TEST_TYPE=${{ inputs.performanceTestType }} + + TEST_LIST=$(jq -n -c \ + --arg test_cmd "$TEST_CMD" \ + --arg test_config_override_path "$TEST_CONFIG_OVERRIDE_PATH" \ + --arg TEST_TYPE "$TEST_TYPE" \ + '{ + "tests": [ + { + "id": "TestVRFv2Plus_Performance", + "path": "integration-tests/load/vrfv2plus/vrfv2plus_test.go", + "runs_on": "ubuntu-latest", + "test_env_type": "docker", + "test_cmd": $test_cmd, + "test_config_override_path": $test_config_override_path, + "test_env_vars": { + "TEST_TYPE": $TEST_TYPE + } + } + ] + }') + + echo "test_list=$TEST_LIST" >> $GITHUB_OUTPUT + + run-e2e-tests-workflow: + name: Run E2E Tests + needs: set-tests-to-run + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} + chainlink_version: ${{ inputs.chainlink_version }} + slack_notification_after_tests: always + slack_notification_after_tests_name: "VRF V2 Plus Performance Tests with test config: ${{ inputs.test_config_override_path || 'default' }}" + slack_notification_after_tests_notify_user_id_on_failure: ${{ inputs.notify_user_id_on_failure }} + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + SLACK_NOTIFICATION_AFTER_TESTS_CHANNEL_ID: ${{ secrets.QA_VRF_SLACK_CHANNEL }} + SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} + SLACK_CHANNEL: ${{ secrets.QA_VRF_SLACK_CHANNEL }} diff --git a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml index 268bb7e7d7..5330edf294 100644 --- a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml +++ b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml @@ -26,7 +26,11 @@ on: description: Chainlink image version to use default: develop required: false - type: string + type: string + notify_user_id_on_failure: + description: 'Enter Slack user ID to notify on test failure' + required: false + type: string jobs: set-tests-to-run: @@ -70,6 +74,9 @@ jobs: with: custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} chainlink_version: ${{ inputs.chainlink_version }} + slack_notification_after_tests: always + slack_notification_after_tests_name: "VRF V2 Plus Smoke Tests with test config: ${{ inputs.test_config_override_path || 'default' }}" + slack_notification_after_tests_notify_user_id_on_failure: ${{ inputs.notify_user_id_on_failure }} secrets: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} @@ -86,3 +93,5 @@ jobs: AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + SLACK_NOTIFICATION_AFTER_TESTS_CHANNEL_ID: ${{ secrets.QA_VRF_SLACK_CHANNEL }} diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index c4ab54fc68..e7d71ee828 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -153,6 +153,15 @@ on: required: true SLACK_BOT_TOKEN: required: false + # Use instead of slack_notification_after_tests_channel_id if channel id is secret + SLACK_NOTIFICATION_AFTER_TESTS_CHANNEL_ID: + required: false + # Used in some tests to send slack notifications + SLACK_API_KEY: + required: false + # Used in some tests to send slack notifications + SLACK_CHANNEL: + required: false env: CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink @@ -165,6 +174,8 @@ env: MOD_CACHE_VERSION: 1 TEST_LOG_LEVEL: ${{ inputs.test_log_level }} METRICS_COLLECTION_ID: chainlink-e2e-tests + SLACK_API_KEY: ${{ secrets.SLACK_API_KEY }} + SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }} jobs: validate-inputs: @@ -476,13 +487,14 @@ jobs: env: LATEST_CHAINLINK_RELEASE_VERSION: ${{ needs.get_latest_chainlink_release_version.outputs.latest_chainlink_release_version }} TEST_CONFIG_OVERRIDE_PATH: ${{ matrix.tests.test_config_override_path || inputs.test_config_override_path }} + TEST_ID: ${{ matrix.tests.id_sanitized || matrix.tests.id }} steps: - name: Collect Metrics if: always() id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 with: - id: e2e_tests_${{ matrix.tests.id_sanitized }} + id: e2e_tests_${{ env.TEST_ID }} org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} @@ -577,12 +589,12 @@ jobs: default_e2e_test_chainlink_image: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_IMAGE || env.CHAINLINK_IMAGE }} default_e2e_test_chainlink_upgrade_image: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_IMAGE }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: ${{ matrix.tests.id_sanitized }}-test-logs + artifacts_name: ${{ env.TEST_ID }}-test-logs artifacts_location: | ./integration-tests/smoke/logs/ ./integration-tests/smoke/db_dumps/ /tmp/gotest.log - publish_check_name: ${{ matrix.tests.id_sanitized }} + publish_check_name: ${{ env.TEST_ID }} token: ${{ secrets.GH_TOKEN }} cache_key_id: e2e-tests go_mod_path: ./integration-tests/go.mod @@ -614,7 +626,7 @@ jobs: uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 if: inputs.test_log_upload_on_failure && failure() with: - name: test_log_${{ matrix.tests.id_sanitized }} + name: test_log_${{ env.TEST_ID }} path: /tmp/gotest.log retention-days: ${{ inputs.test_log_upload_retention_days }} continue-on-error: true @@ -625,7 +637,7 @@ jobs: timeout-minutes: 2 continue-on-error: true with: - name: ${{ inputs.upload_cl_node_coverage_artifact_prefix }}${{ matrix.tests.id_sanitized }} + name: ${{ inputs.upload_cl_node_coverage_artifact_prefix }}${{ env.TEST_ID }} path: .covdata retention-days: 1 @@ -639,10 +651,18 @@ jobs: - name: Upload test result as artifact uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: - name: test_result_${{ needs.load-test-configurations.outputs.workflow_id }}_${{ matrix.tests.id_sanitized }} + name: test_result_${{ needs.load-test-configurations.outputs.workflow_id }}_${{ env.TEST_ID }} path: test_result.json retention-days: 1 + - name: Upload custom test artifacts + if: failure() && matrix.tests.test_artifacts_on_failure != '' + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: custom_test_artifacts_${{ env.TEST_ID }}_${{ needs.load-test-configurations.outputs.workflow_id }} + path: ${{ matrix.tests.test_artifacts_on_failure }} + retention-days: 1 + - name: Print failed test summary if: always() uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@70ccaef155381025e411cf7cd1fa5ef8f668ed75 # v2.3.25 @@ -706,13 +726,14 @@ jobs: env: LATEST_CHAINLINK_RELEASE_VERSION: ${{ needs.get_latest_chainlink_release_version.outputs.latest_chainlink_release_version }} TEST_CONFIG_OVERRIDE_PATH: ${{ matrix.tests.test_config_override_path || inputs.test_config_override_path }} + TEST_ID: ${{ matrix.tests.id_sanitized || matrix.tests.id }} steps: - name: Collect Metrics if: always() id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 with: - id: e2e_tests_${{ matrix.tests.id_sanitized }} + id: e2e_tests_${{ env.TEST_ID }} org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} @@ -796,11 +817,19 @@ jobs: uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 if: inputs.test_log_upload_on_failure && failure() with: - name: test_log_${{ matrix.tests.id_sanitized }} + name: test_log_${{ env.TEST_ID }} path: /tmp/gotest.log retention-days: ${{ inputs.test_log_upload_retention_days }} continue-on-error: true + - name: Upload custom test artifacts + if: failure() && matrix.tests.test_artifacts_on_failure != '' + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: custom_test_artifacts_${{ env.TEST_ID }}_${{ needs.load-test-configurations.outputs.workflow_id }} + path: ${{ matrix.tests.test_artifacts_on_failure }} + retention-days: 1 + # TODO: move to run-tests GHA - name: Print failed test summary if: always() @@ -811,6 +840,8 @@ jobs: if: always() name: After tests runs-on: ubuntu-latest + # Set to access secrets like secrets.QA_SLACK_API_KEY that are set in the "integration" environment + environment: integration outputs: test_results: ${{ steps.set_test_results.outputs.results }} steps: @@ -844,12 +875,12 @@ jobs: env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} with: - channel-id: ${{ inputs.slack_notification_after_tests_channel_id }} + channel-id: ${{ inputs.slack_notification_after_tests_channel_id || secrets.SLACK_NOTIFICATION_AFTER_TESTS_CHANNEL_ID }} payload: | { "attachments": [ { - "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || contains(join(needs.*.result, ','), 'cancelled') && '#FFA000' || '#2E7D32' }}", + "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || contains(join(needs.*.result, ','), 'cancelled') && '#FFA000' || '2E7D32' }}", "blocks": [ { "type": "section", @@ -876,7 +907,7 @@ jobs: env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} with: - channel-id: ${{ inputs.slack_notification_after_tests_channel_id }} + channel-id: ${{ inputs.slack_notification_after_tests_channel_id || secrets.SLACK_NOTIFICATION_AFTER_TESTS_CHANNEL_ID }} payload: | { "thread_ts": "${{ steps.slack.outputs.thread_ts }}", From 7ec7f55c56625ef5c4db6bbe787e6ec6eafa7d49 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 10 Sep 2024 09:37:40 -0500 Subject: [PATCH 318/432] golangci-lint: fix issues (#14384) --- .../ccipreader/ccipreader_test.go | 1 - core/capabilities/targets/write_target.go | 11 ++-- core/chains/evm/gas/fee_history_estimator.go | 4 +- .../evm/report_codec_premium_legacy_test.go | 2 - .../services/ocr2/plugins/llo/helpers_test.go | 59 ------------------- .../ocr2/plugins/llo/integration_test.go | 16 +---- ...annel_definition_cache_integration_test.go | 16 ----- core/services/relay/evm/write_target.go | 2 +- 8 files changed, 9 insertions(+), 102 deletions(-) diff --git a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go index 788b93e836..00498ecb66 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go @@ -394,7 +394,6 @@ func TestCCIPReader_Nonces(t *testing.T) { s.sb.Commit() for sourceChain, addrs := range nonces { - var addrQuery []string for addr := range addrs { addrQuery = append(addrQuery, addr.String()) diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index 83c39e3457..c77dc06199 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -274,12 +274,11 @@ func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.Cap value := big.NewInt(0) if err := cap.cw.SubmitTransaction(ctx, "forwarder", "report", req, txID.String(), cap.forwarderAddress, &meta, value); err != nil { - if commontypes.ErrSettingTransactionGasLimitNotSupported.Is(err) { - meta.GasLimit = nil - if err := cap.cw.SubmitTransaction(ctx, "forwarder", "report", req, txID.String(), cap.forwarderAddress, &meta, value); err != nil { - return capabilities.CapabilityResponse{}, fmt.Errorf("failed to submit transaction: %w", err) - } - } else { + if !commontypes.ErrSettingTransactionGasLimitNotSupported.Is(err) { + return capabilities.CapabilityResponse{}, fmt.Errorf("failed to submit transaction: %w", err) + } + meta.GasLimit = nil + if err := cap.cw.SubmitTransaction(ctx, "forwarder", "report", req, txID.String(), cap.forwarderAddress, &meta, value); err != nil { return capabilities.CapabilityResponse{}, fmt.Errorf("failed to submit transaction: %w", err) } } diff --git a/core/chains/evm/gas/fee_history_estimator.go b/core/chains/evm/gas/fee_history_estimator.go index ba3192be10..53af03ac7a 100644 --- a/core/chains/evm/gas/fee_history_estimator.go +++ b/core/chains/evm/gas/fee_history_estimator.go @@ -252,7 +252,7 @@ func (f *FeeHistoryEstimator) RefreshDynamicPrice() error { maxPriorityFeePerGas := assets.NewWeiI(0) priorityFeeThresholdWei := assets.NewWeiI(0) if f.config.BlockHistorySize > 0 { - var nonZeroRewardsLen int64 = 0 + var nonZeroRewardsLen int64 priorityFee := big.NewInt(0) priorityFeeThreshold := big.NewInt(0) for _, reward := range feeHistory.Reward { @@ -263,7 +263,7 @@ func (f *FeeHistoryEstimator) RefreshDynamicPrice() error { // We'll calculate the average of non-zero priority fees if reward[0].Cmp(big.NewInt(0)) > 0 { priorityFee = priorityFee.Add(priorityFee, reward[0]) - nonZeroRewardsLen += 1 + nonZeroRewardsLen++ } // We take the max value for the bumping threshold if reward[1].Cmp(big.NewInt(0)) > 0 { diff --git a/core/services/llo/evm/report_codec_premium_legacy_test.go b/core/services/llo/evm/report_codec_premium_legacy_test.go index 2b864af555..dab2a8cf3f 100644 --- a/core/services/llo/evm/report_codec_premium_legacy_test.go +++ b/core/services/llo/evm/report_codec_premium_legacy_test.go @@ -18,8 +18,6 @@ import ( "github.com/smartcontractkit/chainlink-data-streams/llo" ) -const ethMainnetChainSelector uint64 = 5009297550715157269 - func newValidPremiumLegacyReport() llo.Report { return llo.Report{ ConfigDigest: types.ConfigDigest{1, 2, 3}, diff --git a/core/services/ocr2/plugins/llo/helpers_test.go b/core/services/ocr2/plugins/llo/helpers_test.go index 4097294ba0..b3a0294fef 100644 --- a/core/services/ocr2/plugins/llo/helpers_test.go +++ b/core/services/ocr2/plugins/llo/helpers_test.go @@ -330,49 +330,6 @@ transmitterID = "%x" )) } -func addOCRJobs( - t *testing.T, - streams []Stream, - serverPubKey ed25519.PublicKey, - serverURL string, - configuratorAddress common.Address, - bootstrapPeerID string, - bootstrapNodePort int, - nodes []Node, - configStoreAddress common.Address, - clientPubKeys []ed25519.PublicKey, - pluginConfig, - relayType, - relayConfig string) (streamJobIDs []int32) { - - // Add OCR jobs - one per feed on each node - for i, node := range nodes { - for j, strm := range streams { - bmBridge := createBridge(t, fmt.Sprintf("benchmarkprice-%d-%d", strm.id, j), i, strm.baseBenchmarkPrice, node.App.BridgeORM()) - jobID := addSingleDecimalStreamJob( - t, - node, - strm.id, - bmBridge, - ) - streamJobIDs = append(streamJobIDs, jobID) - } - addLLOJob( - t, - node, - configuratorAddress, - bootstrapPeerID, - bootstrapNodePort, - clientPubKeys[i], - "feed-1", - pluginConfig, - relayType, - relayConfig, - ) - } - return streamJobIDs -} - func createBridge(t *testing.T, name string, i int, p decimal.Decimal, borm bridges.ORM) (bridgeName string) { ctx := testutils.Context(t) bridge := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { @@ -397,22 +354,6 @@ func createBridge(t *testing.T, name string, i int, p decimal.Decimal, borm brid return bridgeName } -func createErroringBridge(t *testing.T, name string, i int, borm bridges.ORM) (bridgeName string) { - ctx := testutils.Context(t) - bridge := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { - res.WriteHeader(http.StatusInternalServerError) - })) - t.Cleanup(bridge.Close) - u, _ := url.Parse(bridge.URL) - bridgeName = fmt.Sprintf("bridge-%s-%d", name, i) - require.NoError(t, borm.CreateBridgeType(ctx, &bridges.BridgeType{ - Name: bridges.BridgeName(bridgeName), - URL: models.WebURL(*u), - })) - - return bridgeName -} - func addOCRJobsEVMPremiumLegacy( t *testing.T, streams []Stream, diff --git a/core/services/ocr2/plugins/llo/integration_test.go b/core/services/ocr2/plugins/llo/integration_test.go index f5c2869442..50d580fe25 100644 --- a/core/services/ocr2/plugins/llo/integration_test.go +++ b/core/services/ocr2/plugins/llo/integration_test.go @@ -88,14 +88,11 @@ type Stream struct { baseBenchmarkPrice decimal.Decimal baseBid decimal.Decimal baseAsk decimal.Decimal - strmType string } const ( - btcStreamID = 51 ethStreamID = 52 linkStreamID = 53 - dogeStreamID = 54 quoteStreamID1 = 55 quoteStreamID2 = 56 ) @@ -103,12 +100,7 @@ const ( var ( quoteStreamFeedID1 = common.HexToHash(`0x0003111111111111111111111111111111111111111111111111111111111111`) quoteStreamFeedID2 = common.HexToHash(`0x0003222222222222222222222222222222222222222222222222222222222222`) - - btcStream = Stream{ - id: 51, - baseBenchmarkPrice: decimal.NewFromFloat32(56_114.41), - } - ethStream = Stream{ + ethStream = Stream{ id: 52, baseBenchmarkPrice: decimal.NewFromFloat32(2_976.39), } @@ -116,10 +108,6 @@ var ( id: 53, baseBenchmarkPrice: decimal.NewFromFloat32(13.25), } - dogeStream = Stream{ - id: 54, - baseBenchmarkPrice: decimal.NewFromFloat32(0.10960935), - } quoteStream1 = Stream{ id: 55, baseBenchmarkPrice: decimal.NewFromFloat32(1000.1212), @@ -146,8 +134,6 @@ func generateConfig(t *testing.T, oracles []confighelper.OracleIdentityExtra) ( reportingPluginConfig, err := rawReportingPluginConfig.Encode() require.NoError(t, err) - offchainConfig = []byte{} - signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, err = ocr3confighelper.ContractSetConfigArgsForTests( 2*time.Second, // DeltaProgress 20*time.Second, // DeltaResend diff --git a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go index 6067887681..ec918e2375 100644 --- a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go +++ b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go @@ -2,7 +2,6 @@ package llo_test import ( "bytes" - "context" "encoding/json" "errors" "fmt" @@ -13,7 +12,6 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/stretchr/testify/assert" @@ -368,17 +366,3 @@ func Test_ChannelDefinitionCache_Integration(t *testing.T) { assert.Equal(t, uint32(5), pd.Version) }) } - -type mockLogPoller struct { - logpoller.LogPoller - LatestBlockFn func(ctx context.Context) (int64, error) - LogsWithSigsFn func(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) -} - -func (p *mockLogPoller) LogsWithSigs(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) { - return p.LogsWithSigsFn(ctx, start, end, eventSigs, address) -} -func (p *mockLogPoller) LatestBlock(ctx context.Context) (logpoller.LogPollerBlock, error) { - block, err := p.LatestBlockFn(ctx) - return logpoller.LogPollerBlock{BlockNumber: block}, err -} diff --git a/core/services/relay/evm/write_target.go b/core/services/relay/evm/write_target.go index 8c71030f8a..03b1130f8e 100644 --- a/core/services/relay/evm/write_target.go +++ b/core/services/relay/evm/write_target.go @@ -6,9 +6,9 @@ import ( "fmt" chainselectors "github.com/smartcontractkit/chain-selectors" - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/logger" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/capabilities/targets" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" From fffc2a443c19b30ab9209b903693710ec8785d8e Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Tue, 10 Sep 2024 17:25:00 +0200 Subject: [PATCH 319/432] Fix test image version (#14386) * Fix test image version * Fix other workflows * Fix --- .github/workflows/automation-benchmark-tests.yml | 3 ++- .github/workflows/automation-load-tests.yml | 3 ++- .github/workflows/on-demand-ocr-soak-test.yml | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/automation-benchmark-tests.yml b/.github/workflows/automation-benchmark-tests.yml index 8867a1250f..85172bc98a 100644 --- a/.github/workflows/automation-benchmark-tests.yml +++ b/.github/workflows/automation-benchmark-tests.yml @@ -64,6 +64,7 @@ jobs: echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - name: Build Test Image + id: build-test-image uses: ./.github/actions/build-test-image with: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} @@ -76,7 +77,7 @@ jobs: DETACH_RUNNER: true TEST_SUITE: benchmark TEST_ARGS: -test.timeout 720h - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ github.sha }} + ENV_JOB_IMAGE: ${{ steps.build-test-image.outputs.test_image }} INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com TEST_TYPE: ${{ github.event.inputs.testType }} TEST_TEST_TYPE: ${{ github.event.inputs.testType }} diff --git a/.github/workflows/automation-load-tests.yml b/.github/workflows/automation-load-tests.yml index 45a1dc422b..95368825e3 100644 --- a/.github/workflows/automation-load-tests.yml +++ b/.github/workflows/automation-load-tests.yml @@ -79,6 +79,7 @@ jobs: echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - name: Build Test Image + id: build-test-image uses: ./.github/actions/build-test-image with: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} @@ -93,7 +94,7 @@ jobs: DETACH_RUNNER: true TEST_SUITE: automationv2_1 TEST_ARGS: -test.timeout 720h - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ github.sha }} + ENV_JOB_IMAGE: ${{ steps.build-test-image.outputs.test_image }} INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com PYROSCOPE_SERVER: ${{ secrets.QA_PYROSCOPE_INSTANCE }} PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} diff --git a/.github/workflows/on-demand-ocr-soak-test.yml b/.github/workflows/on-demand-ocr-soak-test.yml index 3b827032b1..ffd4f6887a 100644 --- a/.github/workflows/on-demand-ocr-soak-test.yml +++ b/.github/workflows/on-demand-ocr-soak-test.yml @@ -87,6 +87,7 @@ jobs: echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - name: Build Image + id: build-test-image uses: ./.github/actions/build-test-image with: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} @@ -98,7 +99,7 @@ jobs: DETACH_RUNNER: true TEST_SUITE: soak TEST_ARGS: -test.timeout 900h -test.memprofile memprofile.out -test.cpuprofile profile.out - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ github.sha }} + ENV_JOB_IMAGE: ${{ steps.build-test-image.outputs.test_image }} # We can comment these out when we have a stable soak test and aren't worried about resource consumption TEST_UPLOAD_CPU_PROFILE: true TEST_UPLOAD_MEM_PROFILE: true From 72ea6b688fb5f0c3dbd9481e58ab868df9c1f1d1 Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 10 Sep 2024 13:05:36 -0400 Subject: [PATCH 320/432] bumping wsrpc to v0.8.2 (#14372) * bumping wsrpc to v0.8.2 * bumping CTF * minor bump CTF * fixing test usage * fixing no err check * lint --- core/scripts/go.mod | 83 ++-- core/scripts/go.sum | 416 ++++------------- core/services/feeds/connection_manager.go | 9 +- .../services/ocr2/plugins/llo/helpers_test.go | 2 +- .../ocr2/plugins/mercury/helpers_test.go | 2 +- .../relay/evm/mercury/wsrpc/client.go | 7 +- .../relay/evm/mercury/wsrpc/mocks/mocks.go | 10 +- go.mod | 88 ++-- go.sum | 428 +++++------------- integration-tests/go.mod | 8 +- integration-tests/go.sum | 8 +- integration-tests/load/go.mod | 8 +- integration-tests/load/go.sum | 8 +- 13 files changed, 318 insertions(+), 759 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 72117d7b0c..50cfec556e 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -7,26 +7,26 @@ replace github.com/smartcontractkit/chainlink/v2 => ../../ require ( github.com/docker/docker v24.0.7+incompatible - github.com/docker/go-connections v0.4.0 + github.com/docker/go-connections v0.5.0 github.com/ethereum/go-ethereum v1.13.8 github.com/gkampitakis/go-snaps v0.5.4 github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 github.com/jmoiron/sqlx v1.4.0 - github.com/joho/godotenv v1.4.0 + github.com/joho/godotenv v1.5.1 github.com/jonboulle/clockwork v0.4.0 github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f github.com/montanaflynn/stats v0.7.1 github.com/olekukonko/tablewriter v0.0.5 - github.com/pelletier/go-toml/v2 v2.2.0 - github.com/prometheus/client_golang v1.17.0 + github.com/pelletier/go-toml/v2 v2.2.2 + github.com/prometheus/client_golang v1.20.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 - github.com/spf13/cobra v1.8.0 - github.com/spf13/viper v1.15.0 + github.com/spf13/cobra v1.8.1 + github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.9.0 github.com/umbracle/ethgo v0.1.3 github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 @@ -41,14 +41,14 @@ require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect - cosmossdk.io/depinject v1.0.0-alpha.3 // indirect - cosmossdk.io/errors v1.0.0 // indirect - cosmossdk.io/math v1.0.1 // indirect + cosmossdk.io/depinject v1.0.0-alpha.4 // indirect + cosmossdk.io/errors v1.0.1 // indirect + cosmossdk.io/math v1.3.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect - github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/CosmWasm/wasmd v0.40.1 // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect @@ -77,26 +77,26 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/errors v1.10.0 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.37.2 // indirect + github.com/cometbft/cometbft v0.37.5 // indirect github.com/cometbft/cometbft-db v0.7.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect - github.com/cosmos/cosmos-sdk v0.47.4 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect + github.com/cosmos/cosmos-sdk v0.47.11 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.11 // indirect - github.com/cosmos/iavl v0.20.0 // indirect + github.com/cosmos/iavl v0.20.1 // indirect github.com/cosmos/ibc-go/v7 v7.0.1 // indirect github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect - github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect + github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/danieljoos/wincred v1.1.2 // indirect @@ -117,8 +117,8 @@ require ( github.com/esote/minmaxheap v1.0.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fatih/color v1.16.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/fxamacker/cbor/v2 v2.6.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/solana-go v1.8.4 // indirect @@ -126,7 +126,7 @@ require ( github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 // indirect - github.com/getsentry/sentry-go v0.19.0 // indirect + github.com/getsentry/sentry-go v0.23.0 // indirect github.com/gin-contrib/cors v1.5.0 // indirect github.com/gin-contrib/expvar v0.0.1 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect @@ -166,7 +166,7 @@ require ( github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect + github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect github.com/gorilla/context v1.1.1 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/sessions v1.2.2 // indirect @@ -214,7 +214,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -230,7 +230,6 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mfridman/interpolate v0.0.2 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -254,15 +253,17 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/pressly/goose/v3 v3.21.1 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/prometheus v0.48.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/scylladb/go-reflectx v1.0.1 // indirect @@ -279,15 +280,15 @@ require ( github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect - github.com/smartcontractkit/wsrpc v0.7.3 // indirect - github.com/spf13/afero v1.9.5 // indirect + github.com/smartcontractkit/wsrpc v0.8.2 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/subosito/gotenv v1.4.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect @@ -311,8 +312,8 @@ require ( github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zondax/hid v0.9.1 // indirect - github.com/zondax/ledger-go v0.14.1 // indirect + github.com/zondax/hid v0.9.2 // indirect + github.com/zondax/ledger-go v0.14.3 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.dedis.ch/kyber/v3 v3.1.0 // indirect go.etcd.io/bbolt v1.3.7 // indirect @@ -331,16 +332,16 @@ require ( go.uber.org/ratelimit v0.3.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.26.0 // indirect + golang.org/x/crypto v0.27.0 // indirect golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect + golang.org/x/net v0.29.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect - golang.org/x/time v0.5.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/term v0.24.0 // indirect + golang.org/x/text v0.18.0 // indirect + golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.24.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect @@ -355,8 +356,8 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.120.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect - pgregory.net/rapid v0.5.5 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect + pgregory.net/rapid v1.1.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 1a3c4da4cd..41fcbf17fd 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -4,20 +4,12 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= @@ -27,9 +19,6 @@ cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute v1.27.2 h1:5cE5hdrwJV/92ravlwIFRGnyH9CpLGhh4N0ZDVTU+BA= cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= @@ -41,13 +30,9 @@ cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNc cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= @@ -58,14 +43,14 @@ cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= -cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= -cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= -cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= -cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= -cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca h1:msenprh2BLLRwNT7zN56TbBHOGk/7ARQckXHxXyvjoQ= -cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c= -cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= -cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= +cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= +cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= +cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= +cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= +cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= +cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= +cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= +cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -78,7 +63,6 @@ github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo8 github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= @@ -86,10 +70,8 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzS github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= +github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= github.com/CosmWasm/wasmd v0.40.1/go.mod h1:6EOwnv7MpuFaEqxcUOdFV9i4yvrdOciaY6VQ1o7A3yg= github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= @@ -101,7 +83,6 @@ github.com/Depado/ginprom v1.8.0 h1:zaaibRLNI1dMiiuj1MKzatm8qrcHzikMlCc1anqOdyo= github.com/Depado/ginprom v1.8.0/go.mod h1:XBaKzeNBqPF4vxJpNLincSQZeMDnZp1tIbU0FU0UKgg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= @@ -116,7 +97,6 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= @@ -124,10 +104,7 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/ github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= -github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -153,7 +130,6 @@ github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -234,33 +210,27 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= -github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= -github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/errors v1.10.0 h1:lfxS8zZz1+OjtV4MtNWgboi/W5tyLEB6VQZBXN+0VUU= +github.com/cockroachdb/errors v1.10.0/go.mod h1:lknhIsEVQ9Ss/qKDBQS/UqFSvPQjOwNq2qyKAxtHRqE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= -github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= -github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= +github.com/cometbft/cometbft v0.37.5 h1:/U/TlgMh4NdnXNo+YU9T2NMCWyhXNDF34Mx582jlvq0= +github.com/cometbft/cometbft v0.37.5/go.mod h1:QC+mU0lBhKn8r9qvmnq53Dmf3DWBt4VtkcKw2C81wxY= github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= @@ -282,10 +252,10 @@ github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= -github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.47.4 h1:FVUpEprm58nMmBX4xkRdMDaIG5Nr4yy92HZAfGAw9bg= -github.com/cosmos/cosmos-sdk v0.47.4/go.mod h1:R5n+uM7vguVPFap4pgkdvQCT1nVo/OtPwrlAU40rvok= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= +github.com/cosmos/cosmos-sdk v0.47.11 h1:0Qx7eORw0RJqPv+mvDuU8NQ1LV3nJJKJnPoYblWHolc= +github.com/cosmos/cosmos-sdk v0.47.11/go.mod h1:ADjORYzUQqQv/FxDi0H0K5gW/rAk1CiDR3ZKsExfJV0= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -293,21 +263,21 @@ github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiK github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= -github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/iavl v0.20.1 h1:rM1kqeG3/HBT85vsZdoSNsehciqUQPWrR4BYmqE2+zg= +github.com/cosmos/iavl v0.20.1/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= github.com/cosmos/ibc-go/v7 v7.0.1 h1:NIBNRWjlOoFvFQu1ZlgwkaSeHO5avf4C1YQiWegt8jw= github.com/cosmos/ibc-go/v7 v7.0.1/go.mod h1:vEaapV6nuLPQlS+g8IKmxMo6auPi0i7HMv1PhViht/E= github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= -github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= -github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw= +github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M= github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= @@ -316,10 +286,6 @@ github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJF github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= -github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= -github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= -github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -344,7 +310,6 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFM github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70/go.mod h1:EoK/8RFbMEteaCaz89uessDTnCWjbbcr+DXcBh4el5o= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= @@ -359,8 +324,8 @@ github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m3 github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucVPgCo= @@ -370,19 +335,15 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo= github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/esote/minmaxheap v1.0.0 h1:rgA7StnXXpZG6qlM0S7pUmEv1KpWe32rYT4x8J8ntaA= github.com/esote/minmaxheap v1.0.0/go.mod h1:Ln8+i7fS1k3PLgZI2JAo0iA1as95QnIYiGCrqSJ5FZk= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= @@ -393,13 +354,11 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojt github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -411,10 +370,10 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= -github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= @@ -425,16 +384,14 @@ github.com/gagliardetto/solana-go v1.8.4 h1:vmD/JmTlonyXGy39bAo0inMhmbdAwV7rXZtL github.com/gagliardetto/solana-go v1.8.4/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.19.0 h1:BcCH3CN5tXt5aML+gwmbFwVptLLQA+eT866fCO9wVOM= -github.com/getsentry/sentry-go v0.19.0/go.mod h1:y3+lGEFEFexZtpbG1GUE2WD/f9zGyKYwpEqryTOC/nE= +github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE= +github.com/getsentry/sentry-go v0.23.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= @@ -459,8 +416,6 @@ github.com/gkampitakis/go-snaps v0.5.4 h1:GX+dkKmVsRenz7SoTbdIEL4KQARZctkMiZ8ZKp github.com/gkampitakis/go-snaps v0.5.4/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -487,7 +442,6 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= @@ -522,9 +476,6 @@ github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6l github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= @@ -535,12 +486,8 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= @@ -558,9 +505,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -568,7 +513,6 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -588,7 +532,6 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -599,18 +542,14 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= @@ -618,8 +557,6 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -627,30 +564,23 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= -github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.1 h1:SBWmZhjUDRorQxrN0nwzf+AHBxnbFjViHQS4P0yVpmQ= -github.com/googleapis/enterprise-certificate-proxy v0.3.1/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -663,7 +593,6 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= @@ -732,7 +661,6 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= @@ -766,12 +694,10 @@ github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -779,11 +705,6 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -844,8 +765,8 @@ github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= -github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= -github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= @@ -862,30 +783,20 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -899,8 +810,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= @@ -931,12 +840,9 @@ github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -944,7 +850,6 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -957,14 +862,9 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= @@ -1005,7 +905,6 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= @@ -1013,10 +912,6 @@ github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ib github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -1033,7 +928,6 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= @@ -1048,8 +942,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.31.0 h1:54UJxxj6cPInHS3a35wm6BK/F9nHYueZ1NVujHDrnXE= -github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= @@ -1070,8 +964,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= -github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= @@ -1082,7 +976,6 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -1095,26 +988,26 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= +github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= +github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/prometheus v0.48.1 h1:CTszphSNTXkuCG6O0IfpKdHcJkvvnAAE1GbELKS+NFk= github.com/prometheus/prometheus v0.48.1/go.mod h1:SRw624aMAxTfryAcP8rOjg4S/sHHaetx2lyJJ2nM83g= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= @@ -1122,8 +1015,6 @@ github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= -github.com/regen-network/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= @@ -1138,7 +1029,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= @@ -1147,24 +1037,25 @@ github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= -github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= @@ -1210,35 +1101,35 @@ github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235- github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= -github.com/smartcontractkit/wsrpc v0.7.3 h1:CKYZfawZShZGfvsQep1F9oBansnFk9ByZPCdTMpLphw= -github.com/smartcontractkit/wsrpc v0.7.3/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= +github.com/smartcontractkit/wsrpc v0.8.2 h1:XB/xcn/MMseHW+8JE8+a/rceA86ck7Ur6cEa9LiUC8M= +github.com/smartcontractkit/wsrpc v0.8.2/go.mod h1:2u/wfnhl5R4RlSXseN4n6HHIWk8w1Am3AT6gWftQbNg= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= -github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= @@ -1265,8 +1156,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= @@ -1308,10 +1199,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2 github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= @@ -1329,14 +1218,10 @@ github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE= github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -1344,31 +1229,23 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= -github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= -github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= +github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= +github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= @@ -1443,7 +1320,6 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -1458,26 +1334,21 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1503,7 +1374,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1512,8 +1382,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -1530,62 +1398,44 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1595,9 +1445,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1640,47 +1488,32 @@ golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1688,8 +1521,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1697,8 +1530,8 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1711,22 +1544,19 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1759,28 +1589,11 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= @@ -1805,16 +1618,8 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -1823,9 +1628,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1845,37 +1647,18 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1888,15 +1671,9 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1907,7 +1684,6 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -1933,10 +1709,8 @@ gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:a gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1952,21 +1726,19 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= -gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= @@ -1978,8 +1750,8 @@ k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= @@ -1997,8 +1769,8 @@ modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= -pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/core/services/feeds/connection_manager.go b/core/services/feeds/connection_manager.go index ad7e1318e7..aadfc41bd5 100644 --- a/core/services/feeds/connection_manager.go +++ b/core/services/feeds/connection_manager.go @@ -5,9 +5,9 @@ import ( "sync" "github.com/pkg/errors" + "google.golang.org/grpc/connectivity" "github.com/smartcontractkit/wsrpc" - "github.com/smartcontractkit/wsrpc/connectivity" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -110,7 +110,12 @@ func (mgr *connectionsManager) Connect(opts ConnectOpts) { return } - defer clientConn.Close() + defer func() { + cerr := clientConn.Close() + if cerr != nil { + mgr.lggr.Warnf("Error closing wsrpc client connection: %v", cerr) + } + }() mgr.lggr.Infow("Connected to Feeds Manager", "feedsManagerID", opts.FeedsManagerID) diff --git a/core/services/ocr2/plugins/llo/helpers_test.go b/core/services/ocr2/plugins/llo/helpers_test.go index b3a0294fef..bd73dcccfc 100644 --- a/core/services/ocr2/plugins/llo/helpers_test.go +++ b/core/services/ocr2/plugins/llo/helpers_test.go @@ -94,7 +94,7 @@ func startMercuryServer(t *testing.T, srv *mercuryServer, pubKeys []ed25519.Publ t.Fatalf("[MAIN] failed to listen: %v", err) } serverURL = lis.Addr().String() - s := wsrpc.NewServer(wsrpc.Creds(srv.privKey, pubKeys)) + s := wsrpc.NewServer(wsrpc.WithCreds(srv.privKey, pubKeys)) // Register mercury implementation with the wsrpc server pb.RegisterMercuryServer(s, srv) diff --git a/core/services/ocr2/plugins/mercury/helpers_test.go b/core/services/ocr2/plugins/mercury/helpers_test.go index ecfedf2935..48d320c8de 100644 --- a/core/services/ocr2/plugins/mercury/helpers_test.go +++ b/core/services/ocr2/plugins/mercury/helpers_test.go @@ -104,7 +104,7 @@ func startMercuryServer(t *testing.T, srv *mercuryServer, pubKeys []ed25519.Publ t.Fatalf("[MAIN] failed to listen: %v", err) } serverURL = lis.Addr().String() - s := wsrpc.NewServer(wsrpc.Creds(srv.privKey, pubKeys)) + s := wsrpc.NewServer(wsrpc.WithCreds(srv.privKey, pubKeys)) // Register mercury implementation with the wsrpc server pb.RegisterMercuryServer(s, srv) diff --git a/core/services/relay/evm/mercury/wsrpc/client.go b/core/services/relay/evm/mercury/wsrpc/client.go index b5d784face..3720751065 100644 --- a/core/services/relay/evm/mercury/wsrpc/client.go +++ b/core/services/relay/evm/mercury/wsrpc/client.go @@ -11,6 +11,7 @@ import ( "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + grpc_connectivity "google.golang.org/grpc/connectivity" "github.com/smartcontractkit/wsrpc" "github.com/smartcontractkit/wsrpc/connectivity" @@ -70,8 +71,8 @@ type Client interface { type Conn interface { WaitForReady(ctx context.Context) bool - GetState() connectivity.State - Close() + GetState() grpc_connectivity.State + Close() error } type client struct { @@ -230,7 +231,7 @@ func (w *client) Healthy() (err error) { return err } state := w.conn.GetState() - if state != connectivity.Ready { + if state != grpc_connectivity.Ready { return errors.Errorf("client state should be %s; got %s", connectivity.Ready, state) } return nil diff --git a/core/services/relay/evm/mercury/wsrpc/mocks/mocks.go b/core/services/relay/evm/mercury/wsrpc/mocks/mocks.go index 61912c26b0..3a51af02d1 100644 --- a/core/services/relay/evm/mercury/wsrpc/mocks/mocks.go +++ b/core/services/relay/evm/mercury/wsrpc/mocks/mocks.go @@ -2,8 +2,7 @@ package mocks import ( "context" - - "github.com/smartcontractkit/wsrpc/connectivity" + grpc_connectivity "google.golang.org/grpc/connectivity" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" ) @@ -29,15 +28,16 @@ func (m *MockWSRPCClient) ServerURL() string { return "mock server url" } func (m *MockWSRPCClient) RawClient() pb.MercuryClient { return nil } type MockConn struct { - State connectivity.State + State grpc_connectivity.State Ready bool Closed bool } -func (m *MockConn) Close() { +func (m *MockConn) Close() error { m.Closed = true + return nil } func (m MockConn) WaitForReady(ctx context.Context) bool { return m.Ready } -func (m MockConn) GetState() connectivity.State { return m.State } +func (m MockConn) GetState() grpc_connectivity.State { return m.State } diff --git a/go.mod b/go.mod index 5f112a9eb5..f33f7f0e7b 100644 --- a/go.mod +++ b/go.mod @@ -11,17 +11,17 @@ require ( github.com/XSAM/otelsql v0.27.0 github.com/avast/retry-go/v4 v4.6.0 github.com/btcsuite/btcd/btcec/v2 v2.3.2 - github.com/cometbft/cometbft v0.37.2 - github.com/cosmos/cosmos-sdk v0.47.4 + github.com/cometbft/cometbft v0.37.5 + github.com/cosmos/cosmos-sdk v0.47.11 github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e github.com/deckarep/golang-set/v2 v2.6.0 github.com/dominikbraun/graph v0.23.0 github.com/esote/minmaxheap v1.0.0 github.com/ethereum/go-ethereum v1.13.8 github.com/fatih/color v1.16.0 - github.com/fxamacker/cbor/v2 v2.5.0 + github.com/fxamacker/cbor/v2 v2.7.0 github.com/gagliardetto/solana-go v1.8.4 - github.com/getsentry/sentry-go v0.19.0 + github.com/getsentry/sentry-go v0.23.0 github.com/gin-contrib/cors v1.5.0 github.com/gin-contrib/expvar v0.0.1 github.com/gin-contrib/sessions v0.0.5 @@ -30,7 +30,7 @@ require ( github.com/go-ldap/ldap/v3 v3.4.6 github.com/go-viper/mapstructure/v2 v2.1.0 github.com/go-webauthn/webauthn v0.9.4 - github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b + github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 github.com/google/uuid v1.6.0 github.com/gorilla/securecookie v1.1.2 github.com/gorilla/sessions v1.2.2 @@ -56,19 +56,19 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/mr-tron/base58 v1.2.0 github.com/olekukonko/tablewriter v0.0.5 - github.com/onsi/gomega v1.30.0 + github.com/onsi/gomega v1.33.1 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pelletier/go-toml v1.9.5 - github.com/pelletier/go-toml/v2 v2.2.0 + github.com/pelletier/go-toml/v2 v2.2.2 github.com/pkg/errors v0.9.1 github.com/pressly/goose/v3 v3.21.1 - github.com/prometheus/client_golang v1.17.0 - github.com/prometheus/client_model v0.5.0 - github.com/prometheus/common v0.45.0 + github.com/prometheus/client_golang v1.20.0 + github.com/prometheus/client_model v0.6.1 + github.com/prometheus/common v0.59.1 github.com/prometheus/prometheus v0.48.1 github.com/robfig/cron/v3 v3.0.1 github.com/rogpeppe/go-internal v1.12.0 - github.com/rs/zerolog v1.30.0 + github.com/rs/zerolog v1.32.0 github.com/scylladb/go-reflectx v1.0.1 github.com/shirou/gopsutil/v3 v3.24.3 github.com/shopspring/decimal v1.4.0 @@ -84,7 +84,7 @@ require ( github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 - github.com/smartcontractkit/wsrpc v0.7.3 + github.com/smartcontractkit/wsrpc v0.8.2 github.com/spf13/cast v1.6.0 github.com/stretchr/testify v1.9.0 github.com/test-go/testify v1.1.4 @@ -102,21 +102,21 @@ require ( go.opentelemetry.io/otel v1.28.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.26.0 + golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa golang.org/x/mod v0.20.0 - golang.org/x/net v0.28.0 + golang.org/x/net v0.29.0 golang.org/x/sync v0.8.0 - golang.org/x/term v0.23.0 - golang.org/x/text v0.17.0 - golang.org/x/time v0.5.0 + golang.org/x/term v0.24.0 + golang.org/x/text v0.18.0 + golang.org/x/time v0.6.0 golang.org/x/tools v0.24.0 gonum.org/v1/gonum v0.15.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 gopkg.in/guregu/null.v4 v4.0.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 - k8s.io/utils v0.0.0-20230711102312-30195339c3c7 + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 ) require ( @@ -128,14 +128,14 @@ require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect - cosmossdk.io/depinject v1.0.0-alpha.3 // indirect - cosmossdk.io/errors v1.0.0 // indirect - cosmossdk.io/math v1.0.1 // indirect + cosmossdk.io/depinject v1.0.0-alpha.4 // indirect + cosmossdk.io/errors v1.0.1 // indirect + cosmossdk.io/math v1.3.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect - github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/CosmWasm/wasmd v0.40.1 // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect @@ -157,24 +157,24 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/errors v1.10.0 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/cometbft/cometbft-db v0.7.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.11 // indirect - github.com/cosmos/iavl v0.20.0 // indirect + github.com/cosmos/iavl v0.20.1 // indirect github.com/cosmos/ibc-go/v7 v7.0.1 // indirect github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect - github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect + github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/danieljoos/wincred v1.1.2 // indirect @@ -185,11 +185,11 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect + github.com/docker/go-connections v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect @@ -254,8 +254,9 @@ require ( github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jmhodges/levigo v1.0.0 // indirect + github.com/joho/godotenv v1.5.1 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -267,7 +268,6 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mfridman/interpolate v0.0.2 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect @@ -279,30 +279,34 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect github.com/mtibben/percent v0.2.1 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/run v1.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc5 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect - github.com/spf13/afero v1.9.5 // indirect - github.com/spf13/cobra v1.8.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.15.0 // indirect + github.com/spf13/viper v1.18.2 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/subosito/gotenv v1.4.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect @@ -319,8 +323,8 @@ require ( github.com/valyala/fastjson v1.4.1 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zondax/hid v0.9.1 // indirect - github.com/zondax/ledger-go v0.14.1 // indirect + github.com/zondax/hid v0.9.2 // indirect + github.com/zondax/ledger-go v0.14.3 // indirect go.dedis.ch/protobuf v1.0.11 // indirect go.etcd.io/bbolt v1.3.7 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect @@ -335,7 +339,7 @@ require ( go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/ratelimit v0.3.0 // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect + golang.org/x/sys v0.25.0 // indirect google.golang.org/api v0.188.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect @@ -344,7 +348,7 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - pgregory.net/rapid v0.5.5 // indirect + pgregory.net/rapid v1.1.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 24d270bc8b..830ae2e7f0 100644 --- a/go.sum +++ b/go.sum @@ -4,20 +4,12 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= @@ -27,9 +19,6 @@ cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= @@ -40,13 +29,9 @@ cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNc cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= @@ -57,14 +42,14 @@ cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= -cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= -cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= -cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= -cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= -cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca h1:msenprh2BLLRwNT7zN56TbBHOGk/7ARQckXHxXyvjoQ= -cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c= -cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= -cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= +cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= +cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= +cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= +cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= +cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= +cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= +cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= +cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -77,7 +62,6 @@ github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo8 github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= @@ -85,10 +69,8 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzS github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= +github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= github.com/CosmWasm/wasmd v0.40.1/go.mod h1:6EOwnv7MpuFaEqxcUOdFV9i4yvrdOciaY6VQ1o7A3yg= github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= @@ -100,7 +82,6 @@ github.com/Depado/ginprom v1.8.0 h1:zaaibRLNI1dMiiuj1MKzatm8qrcHzikMlCc1anqOdyo= github.com/Depado/ginprom v1.8.0/go.mod h1:XBaKzeNBqPF4vxJpNLincSQZeMDnZp1tIbU0FU0UKgg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= @@ -120,17 +101,13 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= -github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -156,7 +133,6 @@ github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -219,33 +195,27 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= -github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= -github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/errors v1.10.0 h1:lfxS8zZz1+OjtV4MtNWgboi/W5tyLEB6VQZBXN+0VUU= +github.com/cockroachdb/errors v1.10.0/go.mod h1:lknhIsEVQ9Ss/qKDBQS/UqFSvPQjOwNq2qyKAxtHRqE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= -github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= -github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= +github.com/cometbft/cometbft v0.37.5 h1:/U/TlgMh4NdnXNo+YU9T2NMCWyhXNDF34Mx582jlvq0= +github.com/cometbft/cometbft v0.37.5/go.mod h1:QC+mU0lBhKn8r9qvmnq53Dmf3DWBt4VtkcKw2C81wxY= github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= @@ -268,10 +238,10 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= -github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.47.4 h1:FVUpEprm58nMmBX4xkRdMDaIG5Nr4yy92HZAfGAw9bg= -github.com/cosmos/cosmos-sdk v0.47.4/go.mod h1:R5n+uM7vguVPFap4pgkdvQCT1nVo/OtPwrlAU40rvok= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= +github.com/cosmos/cosmos-sdk v0.47.11 h1:0Qx7eORw0RJqPv+mvDuU8NQ1LV3nJJKJnPoYblWHolc= +github.com/cosmos/cosmos-sdk v0.47.11/go.mod h1:ADjORYzUQqQv/FxDi0H0K5gW/rAk1CiDR3ZKsExfJV0= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -279,21 +249,21 @@ github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiK github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= -github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/iavl v0.20.1 h1:rM1kqeG3/HBT85vsZdoSNsehciqUQPWrR4BYmqE2+zg= +github.com/cosmos/iavl v0.20.1/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= github.com/cosmos/ibc-go/v7 v7.0.1 h1:NIBNRWjlOoFvFQu1ZlgwkaSeHO5avf4C1YQiWegt8jw= github.com/cosmos/ibc-go/v7 v7.0.1/go.mod h1:vEaapV6nuLPQlS+g8IKmxMo6auPi0i7HMv1PhViht/E= github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= -github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= -github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw= +github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M= github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= @@ -302,10 +272,6 @@ github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJF github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= -github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= -github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= -github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -326,7 +292,6 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFM github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70/go.mod h1:EoK/8RFbMEteaCaz89uessDTnCWjbbcr+DXcBh4el5o= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= @@ -339,8 +304,8 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUn github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucVPgCo= @@ -350,17 +315,13 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo= github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/esote/minmaxheap v1.0.0 h1:rgA7StnXXpZG6qlM0S7pUmEv1KpWe32rYT4x8J8ntaA= github.com/esote/minmaxheap v1.0.0/go.mod h1:Ln8+i7fS1k3PLgZI2JAo0iA1as95QnIYiGCrqSJ5FZk= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= @@ -371,13 +332,11 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojt github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -389,10 +348,10 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE= -github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= @@ -403,16 +362,14 @@ github.com/gagliardetto/solana-go v1.8.4 h1:vmD/JmTlonyXGy39bAo0inMhmbdAwV7rXZtL github.com/gagliardetto/solana-go v1.8.4/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ= github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.19.0 h1:BcCH3CN5tXt5aML+gwmbFwVptLLQA+eT866fCO9wVOM= -github.com/getsentry/sentry-go v0.19.0/go.mod h1:y3+lGEFEFexZtpbG1GUE2WD/f9zGyKYwpEqryTOC/nE= +github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE= +github.com/getsentry/sentry-go v0.23.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= @@ -431,8 +388,6 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -459,7 +414,6 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -477,18 +431,16 @@ github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QX github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-viper/mapstructure/v2 v2.1.0 h1:gHnMa2Y/pIxElCH2GlZZ1lZSsn6XMtufpGyP1XxdC/w= github.com/go-viper/mapstructure/v2 v2.1.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6lpIc2g= github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= @@ -500,12 +452,8 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= @@ -523,9 +471,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -533,7 +479,6 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -553,7 +498,6 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -562,18 +506,14 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= @@ -581,8 +521,6 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -590,21 +528,15 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= -github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -614,7 +546,6 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA= github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -627,7 +558,6 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= @@ -696,7 +626,6 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= @@ -733,13 +662,11 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -747,11 +674,6 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -811,8 +733,8 @@ github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= -github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= -github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= @@ -827,29 +749,19 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -863,8 +775,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= @@ -893,12 +803,9 @@ github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9 github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -906,11 +813,11 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -919,14 +826,9 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= @@ -967,16 +869,13 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -992,24 +891,23 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= +github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= -github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= +github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= +github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -1026,8 +924,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= -github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= @@ -1038,7 +936,6 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -1051,26 +948,26 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= +github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= +github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/prometheus v0.48.1 h1:CTszphSNTXkuCG6O0IfpKdHcJkvvnAAE1GbELKS+NFk= github.com/prometheus/prometheus v0.48.1/go.mod h1:SRw624aMAxTfryAcP8rOjg4S/sHHaetx2lyJJ2nM83g= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= @@ -1078,8 +975,6 @@ github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= -github.com/regen-network/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= @@ -1094,7 +989,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= @@ -1104,24 +998,25 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= -github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= @@ -1167,36 +1062,36 @@ github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235- github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= -github.com/smartcontractkit/wsrpc v0.7.3 h1:CKYZfawZShZGfvsQep1F9oBansnFk9ByZPCdTMpLphw= -github.com/smartcontractkit/wsrpc v0.7.3/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= +github.com/smartcontractkit/wsrpc v0.8.2 h1:XB/xcn/MMseHW+8JE8+a/rceA86ck7Ur6cEa9LiUC8M= +github.com/smartcontractkit/wsrpc v0.8.2/go.mod h1:2u/wfnhl5R4RlSXseN4n6HHIWk8w1Am3AT6gWftQbNg= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= -github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= @@ -1223,8 +1118,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= @@ -1261,10 +1156,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2 github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= @@ -1282,14 +1175,10 @@ github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE= github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -1297,31 +1186,23 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= -github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= -github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= +github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= +github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= @@ -1397,7 +1278,6 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -1411,27 +1291,22 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1457,7 +1332,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1466,8 +1340,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -1483,44 +1355,30 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -1528,17 +1386,13 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1548,9 +1402,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1593,45 +1445,30 @@ golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1640,8 +1477,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1650,8 +1487,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1665,22 +1502,19 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1713,28 +1547,11 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= @@ -1759,16 +1576,8 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -1777,9 +1586,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1799,37 +1605,18 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1842,15 +1629,9 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1861,7 +1642,6 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -1885,10 +1665,8 @@ gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1904,24 +1682,22 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= -gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= -k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= @@ -1939,8 +1715,8 @@ modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= -pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 83a2b11f7d..4e3d159df1 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -27,7 +27,7 @@ require ( github.com/onsi/gomega v1.33.1 github.com/pelletier/go-toml/v2 v2.2.2 github.com/pkg/errors v0.9.1 - github.com/prometheus/common v0.55.0 + github.com/prometheus/common v0.59.1 github.com/rs/zerolog v1.33.0 github.com/scylladb/go-reflectx v1.0.1 github.com/segmentio/ksuid v1.0.4 @@ -321,7 +321,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -382,7 +382,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/alertmanager v0.26.0 // indirect - github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_golang v1.20.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 // indirect @@ -411,7 +411,7 @@ require ( github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect - github.com/smartcontractkit/wsrpc v0.8.1 // indirect + github.com/smartcontractkit/wsrpc v0.8.2 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index e9e31afc42..c6ab275494 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1062,8 +1062,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -1455,8 +1455,8 @@ github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235- github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= -github.com/smartcontractkit/wsrpc v0.8.1 h1:kk0SXLqWrWaZ3J6c7n8D0NZ2uTMBBBpG5dZZXZX8UGE= -github.com/smartcontractkit/wsrpc v0.8.1/go.mod h1:yfg8v8fPLXkb6Mcnx6Pm/snP6jJ0r5Kf762Yd1a/KpA= +github.com/smartcontractkit/wsrpc v0.8.2 h1:XB/xcn/MMseHW+8JE8+a/rceA86ck7Ur6cEa9LiUC8M= +github.com/smartcontractkit/wsrpc v0.8.2/go.mod h1:2u/wfnhl5R4RlSXseN4n6HHIWk8w1Am3AT6gWftQbNg= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 7085cbd228..a666bd9f8b 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -294,7 +294,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -356,9 +356,9 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/alertmanager v0.26.0 // indirect - github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_golang v1.20.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.59.1 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 // indirect github.com/prometheus/procfs v0.15.1 // indirect @@ -392,7 +392,7 @@ require ( github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect - github.com/smartcontractkit/wsrpc v0.8.1 // indirect + github.com/smartcontractkit/wsrpc v0.8.2 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 87a8c082f0..274e20d9c9 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1048,8 +1048,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -1429,8 +1429,8 @@ github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235- github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= -github.com/smartcontractkit/wsrpc v0.8.1 h1:kk0SXLqWrWaZ3J6c7n8D0NZ2uTMBBBpG5dZZXZX8UGE= -github.com/smartcontractkit/wsrpc v0.8.1/go.mod h1:yfg8v8fPLXkb6Mcnx6Pm/snP6jJ0r5Kf762Yd1a/KpA= +github.com/smartcontractkit/wsrpc v0.8.2 h1:XB/xcn/MMseHW+8JE8+a/rceA86ck7Ur6cEa9LiUC8M= +github.com/smartcontractkit/wsrpc v0.8.2/go.mod h1:2u/wfnhl5R4RlSXseN4n6HHIWk8w1Am3AT6gWftQbNg= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= From e2522fdc1ec929c11b5ec5ead1c7a47ae0208a5b Mon Sep 17 00:00:00 2001 From: ilija42 <57732589+ilija42@users.noreply.github.com> Date: Tue, 10 Sep 2024 19:56:03 +0200 Subject: [PATCH 321/432] BCF-3380 Rename ChainReader imports to ContractReader to match common (#14383) * Rename ChainReader imports to ContractReader to match common * Update Solana refs * Update relayer refs * Update common, solana and feeds refs * Update Starknet relayer * run generate --- core/scripts/go.mod | 18 +++++++--- core/scripts/go.sum | 34 +++++++++++++------ .../ocr2/plugins/mercury/plugin_test.go | 2 +- core/services/relay/evm/commit_provider.go | 4 +-- core/services/relay/evm/evm.go | 2 +- .../chain_components_interface_tester.go | 4 +-- .../relay/evm/evmtesting/run_tests.go | 8 ++--- core/services/relay/evm/exec_provider.go | 4 +-- core/services/relay/evm/functions.go | 2 +- core/services/relay/evm/mercury_provider.go | 2 +- core/services/relay/evm/ocr2keeper.go | 2 +- core/services/relay/evm/plugin_provider.go | 2 +- go.md | 2 ++ go.mod | 18 +++++++--- go.sum | 34 +++++++++++++------ integration-tests/go.mod | 18 +++++++--- integration-tests/go.sum | 34 +++++++++++++------ integration-tests/load/go.mod | 21 +++++++++--- integration-tests/load/go.sum | 34 +++++++++++++------ plugins/medianpoc/plugin_test.go | 2 +- 20 files changed, 170 insertions(+), 77 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 50cfec556e..d3888520a3 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.20.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.1 @@ -272,11 +272,11 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect - github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a // indirect - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd // indirect + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect @@ -322,10 +322,18 @@ require ( go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 // indirect + go.opentelemetry.io/otel/log v0.4.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.4.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 41fcbf17fd..6dd991a958 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1081,18 +1081,18 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1:siC6AoTs4889FwiqgEp0sC6S8nFlDzVTZAmUX7cV7aM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 h1:Q19HQPzISHKEIP0rNFGEiIFvMEeAgb1YRXEFnyBMnNM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 h1:9SkeP9lpTMDqtqDd+BKPQhkPcylSoYi63L9YFdbzbEo= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 h1:JM6P74E9WvLif/PX+eeY1CNZ7u8Dh3PIQej3rB3XHG8= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5/go.mod h1:IYU8HDfJ8BJAXrWpRILYlEkyrLlZIbAwKEcYq+ImudI= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 h1:88ZNrxZd0Uxn9934G/3L5AABTX13iorQJdUXcSUewwg= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5/go.mod h1:/QPAcfj5RQ4pNmDBLJ/Or7EjMAvFU3Xb1pM9gl0jfao= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a h1:0zbG9reudNAJC/Rwe3tYX7kshVtOEXXAhk0uLg/62Y4= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd h1:+RFI4mgXSGEcn847e7bavhQCqaBiW142g1XfGzijFoY= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd/go.mod h1:Ou79geDZKg87CgRi0BTQpRhUT3U6LcrQWuGQveDRvlg= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 h1:Tkl0/SB1hxjBgphslHf1E6iXp+4QAejuCLIT+8zvX3Y= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3/go.mod h1:mkuwCChesVqzMQpYQWRwckmQobJLwG4XCsw7KB8UCKY= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= @@ -1280,14 +1280,28 @@ go.opentelemetry.io/contrib/propagators/b3 v1.24.0 h1:n4xwCdTx3pZqZs2CjS/CUZAs03 go.opentelemetry.io/contrib/propagators/b3 v1.24.0/go.mod h1:k5wRxKRU2uXx2F8uNJ4TaonuEO/V7/5xoz7kdsDACT8= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 h1:UiRNKd1OgqsLbFwE+wkAWTdiAxXtCBqKIHeBIse4FUA= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9/go.mod h1:eqZlW3pJWhjyexnDPrdQxix1pn0wwhI4AO4GKpP/bMI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 h1:U2guen0GhqH8o/G2un8f/aG/y++OuW6MyCo6hT9prXk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0/go.mod h1:yeGZANgEcpdx/WK0IvvRFC+2oLiMS2u4L/0Rj2M2Qr0= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 h1:0MH3f8lZrflbUWXVxyBg/zviDFdGE062uKh5+fu8Vv0= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0/go.mod h1:Vh68vYiHY5mPdekTr0ox0sALsqjoVy0w3Os278yX5SQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 h1:BJee2iLkfRfl9lc7aFmBwkWxY/RI1RDdXepSF6y8TPE= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0/go.mod h1:DIzlHs3DRscCIBU3Y9YSzPfScwnYnzfnCd4g8zA7bZc= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 h1:EVSnY9JbEEW92bEkIYOVMw4q1WJxIAGoFTrtYOzWuRQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0/go.mod h1:Ea1N1QQryNXpCD0I1fdLibBAIpQuBkznMmkdKrapk1Y= +go.opentelemetry.io/otel/log v0.4.0 h1:/vZ+3Utqh18e8TPjuc3ecg284078KWrR8BRz+PQAj3o= +go.opentelemetry.io/otel/log v0.4.0/go.mod h1:DhGnQvky7pHy82MIRV43iXh3FlKN8UUKftn0KbLOq6I= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/sdk/log v0.4.0 h1:1mMI22L82zLqf6KtkjrRy5BbagOTWdJsqMY/HSqILAA= +go.opentelemetry.io/otel/sdk/log v0.4.0/go.mod h1:AYJ9FVF0hNOgAVzUG/ybg/QttnXhUePWAupmCqtdESo= go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= diff --git a/core/services/ocr2/plugins/mercury/plugin_test.go b/core/services/ocr2/plugins/mercury/plugin_test.go index f9bef4a3f1..50ff548935 100644 --- a/core/services/ocr2/plugins/mercury/plugin_test.go +++ b/core/services/ocr2/plugins/mercury/plugin_test.go @@ -236,7 +236,7 @@ func newServicesTestWrapper(t *testing.T, pluginConfig job.JSONConfig, feedID ut type testProvider struct{} // ChainReader implements types.MercuryProvider. -func (*testProvider) ChainReader() commontypes.ContractReader { panic("unimplemented") } +func (*testProvider) ContractReader() commontypes.ContractReader { panic("unimplemented") } // Close implements types.MercuryProvider. func (*testProvider) Close() error { return nil } diff --git a/core/services/relay/evm/commit_provider.go b/core/services/relay/evm/commit_provider.go index f41df16a4f..501e1ae0ef 100644 --- a/core/services/relay/evm/commit_provider.go +++ b/core/services/relay/evm/commit_provider.go @@ -151,7 +151,7 @@ func (P *SrcCommitProvider) ContractTransmitter() ocrtypes.ContractTransmitter { return UnimplementedContractTransmitter{} } -func (P *SrcCommitProvider) ChainReader() commontypes.ContractReader { +func (P *SrcCommitProvider) ContractReader() commontypes.ContractReader { return nil } @@ -209,7 +209,7 @@ func (P *DstCommitProvider) ContractTransmitter() ocrtypes.ContractTransmitter { return P.contractTransmitter } -func (P *DstCommitProvider) ChainReader() commontypes.ContractReader { +func (P *DstCommitProvider) ContractReader() commontypes.ContractReader { return nil } diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index e708233fdc..273926136e 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -1031,7 +1031,7 @@ func (p *medianProvider) ContractConfigTracker() ocrtypes.ContractConfigTracker return p.configWatcher.ContractConfigTracker() } -func (p *medianProvider) ChainReader() commontypes.ContractReader { +func (p *medianProvider) ContractReader() commontypes.ContractReader { return p.chainReader } diff --git a/core/services/relay/evm/evmtesting/chain_components_interface_tester.go b/core/services/relay/evm/evmtesting/chain_components_interface_tester.go index c877f48784..facef2bb7e 100644 --- a/core/services/relay/evm/evmtesting/chain_components_interface_tester.go +++ b/core/services/relay/evm/evmtesting/chain_components_interface_tester.go @@ -204,7 +204,7 @@ func (it *EVMChainComponentsInterfaceTester[T]) Setup(t T) { }, }, } - it.GetChainReader(t) + it.GetContractReader(t) it.txm = it.Helper.TXM(t, it.client) it.chainWriterConfig = types.ChainWriterConfig{ @@ -287,7 +287,7 @@ func (it *EVMChainComponentsInterfaceTester[T]) GetAccountBytes(i int) []byte { return account[:] } -func (it *EVMChainComponentsInterfaceTester[T]) GetChainReader(t T) clcommontypes.ContractReader { +func (it *EVMChainComponentsInterfaceTester[T]) GetContractReader(t T) clcommontypes.ContractReader { ctx := it.Helper.Context(t) if it.cr != nil { return it.cr diff --git a/core/services/relay/evm/evmtesting/run_tests.go b/core/services/relay/evm/evmtesting/run_tests.go index 85ed9f8675..cb68a1b887 100644 --- a/core/services/relay/evm/evmtesting/run_tests.go +++ b/core/services/relay/evm/evmtesting/run_tests.go @@ -32,7 +32,7 @@ func RunContractReaderEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfa anyString := "foo" ctx := it.Helper.Context(t) - cr := it.GetChainReader(t) + cr := it.GetContractReader(t) bindings := it.GetBindings(t) require.NoError(t, cr.Bind(ctx, bindings)) @@ -66,7 +66,7 @@ func RunContractReaderEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfa t.Run("Multiple topics can filter together", func(t T) { it.Setup(t) ctx := it.Helper.Context(t) - cr := it.GetChainReader(t) + cr := it.GetContractReader(t) bindings := it.GetBindings(t) require.NoError(t, cr.Bind(ctx, bindings)) @@ -97,7 +97,7 @@ func RunContractReaderEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfa t.Run("Filtering can be done on indexed topics that get hashed", func(t T) { it.Setup(t) - cr := it.GetChainReader(t) + cr := it.GetContractReader(t) ctx := it.Helper.Context(t) bindings := it.GetBindings(t) @@ -133,7 +133,7 @@ func RunContractReaderEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfa it.Setup(t) addr := common.BigToAddress(big.NewInt(42)) - reader := it.GetChainReader(t) + reader := it.GetContractReader(t) ctx := it.Helper.Context(t) err := reader.Bind(ctx, []clcommontypes.BoundContract{{Name: AnyContractName, Address: addr.Hex()}}) diff --git a/core/services/relay/evm/exec_provider.go b/core/services/relay/evm/exec_provider.go index db10f31f35..e0a9b378f2 100644 --- a/core/services/relay/evm/exec_provider.go +++ b/core/services/relay/evm/exec_provider.go @@ -151,7 +151,7 @@ func (s *SrcExecProvider) ContractTransmitter() ocrtypes.ContractTransmitter { return UnimplementedContractTransmitter{} } -func (s *SrcExecProvider) ChainReader() commontypes.ContractReader { +func (s *SrcExecProvider) ContractReader() commontypes.ContractReader { return nil } @@ -331,7 +331,7 @@ func (d *DstExecProvider) ContractTransmitter() ocrtypes.ContractTransmitter { return d.contractTransmitter } -func (d *DstExecProvider) ChainReader() commontypes.ContractReader { +func (d *DstExecProvider) ContractReader() commontypes.ContractReader { return nil } diff --git a/core/services/relay/evm/functions.go b/core/services/relay/evm/functions.go index 1f1554eb11..98928241fd 100644 --- a/core/services/relay/evm/functions.go +++ b/core/services/relay/evm/functions.go @@ -71,7 +71,7 @@ func (p *functionsProvider) ContractConfigTracker() ocrtypes.ContractConfigTrack return p.configWatcher.ContractConfigTracker() } -func (p *functionsProvider) ChainReader() commontypes.ContractReader { +func (p *functionsProvider) ContractReader() commontypes.ContractReader { return nil } diff --git a/core/services/relay/evm/mercury_provider.go b/core/services/relay/evm/mercury_provider.go index 807ace6ce1..85f633e063 100644 --- a/core/services/relay/evm/mercury_provider.go +++ b/core/services/relay/evm/mercury_provider.go @@ -128,7 +128,7 @@ func (p *mercuryProvider) MercuryServerFetcher() mercurytypes.ServerFetcher { return p.transmitter } -func (p *mercuryProvider) ChainReader() commontypes.ContractReader { +func (p *mercuryProvider) ContractReader() commontypes.ContractReader { return nil } diff --git a/core/services/relay/evm/ocr2keeper.go b/core/services/relay/evm/ocr2keeper.go index 2300f54b6e..625ee71c18 100644 --- a/core/services/relay/evm/ocr2keeper.go +++ b/core/services/relay/evm/ocr2keeper.go @@ -196,7 +196,7 @@ func (c *ocr2keeperProvider) ContractTransmitter() ocrtypes.ContractTransmitter return c.contractTransmitter } -func (c *ocr2keeperProvider) ChainReader() commontypes.ContractReader { +func (c *ocr2keeperProvider) ContractReader() commontypes.ContractReader { return nil } diff --git a/core/services/relay/evm/plugin_provider.go b/core/services/relay/evm/plugin_provider.go index 780b134074..b8ce56ff12 100644 --- a/core/services/relay/evm/plugin_provider.go +++ b/core/services/relay/evm/plugin_provider.go @@ -65,7 +65,7 @@ func (p *pluginProvider) ContractConfigTracker() ocrtypes.ContractConfigTracker return p.configWatcher.configPoller } -func (p *pluginProvider) ChainReader() types.ContractReader { +func (p *pluginProvider) ContractReader() types.ContractReader { return p.chainReader } diff --git a/go.md b/go.md index 21f43e0d26..dabb3fc92e 100644 --- a/go.md +++ b/go.md @@ -69,8 +69,10 @@ flowchart LR chainlink-feeds --> grpc-proxy chainlink-solana --> chainlink-common chainlink-solana --> libocr + chainlink-solana --> grpc-proxy chainlink-starknet/relayer --> chainlink-common chainlink-starknet/relayer --> libocr + chainlink-starknet/relayer --> grpc-proxy tdh2/go/ocr2/decryptionplugin --> libocr tdh2/go/ocr2/decryptionplugin --> tdh2/go/tdh2 ``` diff --git a/go.mod b/go.mod index f33f7f0e7b..71c1adc029 100644 --- a/go.mod +++ b/go.mod @@ -75,12 +75,12 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 - github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 @@ -331,10 +331,18 @@ require ( go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 // indirect + go.opentelemetry.io/otel/log v0.4.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.4.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/ratelimit v0.3.0 // indirect diff --git a/go.sum b/go.sum index 830ae2e7f0..bfc16c5ada 100644 --- a/go.sum +++ b/go.sum @@ -1042,18 +1042,18 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1:siC6AoTs4889FwiqgEp0sC6S8nFlDzVTZAmUX7cV7aM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 h1:Q19HQPzISHKEIP0rNFGEiIFvMEeAgb1YRXEFnyBMnNM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 h1:9SkeP9lpTMDqtqDd+BKPQhkPcylSoYi63L9YFdbzbEo= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 h1:JM6P74E9WvLif/PX+eeY1CNZ7u8Dh3PIQej3rB3XHG8= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5/go.mod h1:IYU8HDfJ8BJAXrWpRILYlEkyrLlZIbAwKEcYq+ImudI= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 h1:88ZNrxZd0Uxn9934G/3L5AABTX13iorQJdUXcSUewwg= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5/go.mod h1:/QPAcfj5RQ4pNmDBLJ/Or7EjMAvFU3Xb1pM9gl0jfao= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a h1:0zbG9reudNAJC/Rwe3tYX7kshVtOEXXAhk0uLg/62Y4= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd h1:+RFI4mgXSGEcn847e7bavhQCqaBiW142g1XfGzijFoY= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd/go.mod h1:Ou79geDZKg87CgRi0BTQpRhUT3U6LcrQWuGQveDRvlg= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 h1:Tkl0/SB1hxjBgphslHf1E6iXp+4QAejuCLIT+8zvX3Y= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3/go.mod h1:mkuwCChesVqzMQpYQWRwckmQobJLwG4XCsw7KB8UCKY= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= @@ -1238,14 +1238,28 @@ go.opentelemetry.io/contrib/propagators/b3 v1.24.0 h1:n4xwCdTx3pZqZs2CjS/CUZAs03 go.opentelemetry.io/contrib/propagators/b3 v1.24.0/go.mod h1:k5wRxKRU2uXx2F8uNJ4TaonuEO/V7/5xoz7kdsDACT8= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 h1:UiRNKd1OgqsLbFwE+wkAWTdiAxXtCBqKIHeBIse4FUA= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9/go.mod h1:eqZlW3pJWhjyexnDPrdQxix1pn0wwhI4AO4GKpP/bMI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 h1:U2guen0GhqH8o/G2un8f/aG/y++OuW6MyCo6hT9prXk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0/go.mod h1:yeGZANgEcpdx/WK0IvvRFC+2oLiMS2u4L/0Rj2M2Qr0= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 h1:0MH3f8lZrflbUWXVxyBg/zviDFdGE062uKh5+fu8Vv0= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0/go.mod h1:Vh68vYiHY5mPdekTr0ox0sALsqjoVy0w3Os278yX5SQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 h1:BJee2iLkfRfl9lc7aFmBwkWxY/RI1RDdXepSF6y8TPE= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0/go.mod h1:DIzlHs3DRscCIBU3Y9YSzPfScwnYnzfnCd4g8zA7bZc= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 h1:EVSnY9JbEEW92bEkIYOVMw4q1WJxIAGoFTrtYOzWuRQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0/go.mod h1:Ea1N1QQryNXpCD0I1fdLibBAIpQuBkznMmkdKrapk1Y= +go.opentelemetry.io/otel/log v0.4.0 h1:/vZ+3Utqh18e8TPjuc3ecg284078KWrR8BRz+PQAj3o= +go.opentelemetry.io/otel/log v0.4.0/go.mod h1:DhGnQvky7pHy82MIRV43iXh3FlKN8UUKftn0KbLOq6I= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/sdk/log v0.4.0 h1:1mMI22L82zLqf6KtkjrRy5BbagOTWdJsqMY/HSqILAA= +go.opentelemetry.io/otel/sdk/log v0.4.0/go.mod h1:AYJ9FVF0hNOgAVzUG/ybg/QttnXhUePWAupmCqtdESo= go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 4e3d159df1..15af3f0b7c 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -37,7 +37,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 @@ -403,11 +403,11 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect - github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a // indirect - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd // indirect + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect @@ -461,10 +461,18 @@ require ( go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 // indirect + go.opentelemetry.io/otel/log v0.4.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.4.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index c6ab275494..21b260d21b 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1425,18 +1425,18 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1:siC6AoTs4889FwiqgEp0sC6S8nFlDzVTZAmUX7cV7aM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 h1:Q19HQPzISHKEIP0rNFGEiIFvMEeAgb1YRXEFnyBMnNM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 h1:9SkeP9lpTMDqtqDd+BKPQhkPcylSoYi63L9YFdbzbEo= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 h1:JM6P74E9WvLif/PX+eeY1CNZ7u8Dh3PIQej3rB3XHG8= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5/go.mod h1:IYU8HDfJ8BJAXrWpRILYlEkyrLlZIbAwKEcYq+ImudI= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 h1:88ZNrxZd0Uxn9934G/3L5AABTX13iorQJdUXcSUewwg= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5/go.mod h1:/QPAcfj5RQ4pNmDBLJ/Or7EjMAvFU3Xb1pM9gl0jfao= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a h1:0zbG9reudNAJC/Rwe3tYX7kshVtOEXXAhk0uLg/62Y4= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd h1:+RFI4mgXSGEcn847e7bavhQCqaBiW142g1XfGzijFoY= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd/go.mod h1:Ou79geDZKg87CgRi0BTQpRhUT3U6LcrQWuGQveDRvlg= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 h1:Tkl0/SB1hxjBgphslHf1E6iXp+4QAejuCLIT+8zvX3Y= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3/go.mod h1:mkuwCChesVqzMQpYQWRwckmQobJLwG4XCsw7KB8UCKY= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 h1:Owb1MQZn0NZHwtZAnPZE6TVoTx6xLrfPaUdeOYswE9M= @@ -1660,16 +1660,30 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIX go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 h1:UiRNKd1OgqsLbFwE+wkAWTdiAxXtCBqKIHeBIse4FUA= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9/go.mod h1:eqZlW3pJWhjyexnDPrdQxix1pn0wwhI4AO4GKpP/bMI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 h1:U2guen0GhqH8o/G2un8f/aG/y++OuW6MyCo6hT9prXk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0/go.mod h1:yeGZANgEcpdx/WK0IvvRFC+2oLiMS2u4L/0Rj2M2Qr0= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 h1:0MH3f8lZrflbUWXVxyBg/zviDFdGE062uKh5+fu8Vv0= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0/go.mod h1:Vh68vYiHY5mPdekTr0ox0sALsqjoVy0w3Os278yX5SQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 h1:BJee2iLkfRfl9lc7aFmBwkWxY/RI1RDdXepSF6y8TPE= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0/go.mod h1:DIzlHs3DRscCIBU3Y9YSzPfScwnYnzfnCd4g8zA7bZc= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 h1:EVSnY9JbEEW92bEkIYOVMw4q1WJxIAGoFTrtYOzWuRQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0/go.mod h1:Ea1N1QQryNXpCD0I1fdLibBAIpQuBkznMmkdKrapk1Y= +go.opentelemetry.io/otel/log v0.4.0 h1:/vZ+3Utqh18e8TPjuc3ecg284078KWrR8BRz+PQAj3o= +go.opentelemetry.io/otel/log v0.4.0/go.mod h1:DhGnQvky7pHy82MIRV43iXh3FlKN8UUKftn0KbLOq6I= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/sdk/log v0.4.0 h1:1mMI22L82zLqf6KtkjrRy5BbagOTWdJsqMY/HSqILAA= +go.opentelemetry.io/otel/sdk/log v0.4.0/go.mod h1:AYJ9FVF0hNOgAVzUG/ybg/QttnXhUePWAupmCqtdESo= go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index a666bd9f8b..f9f903fc34 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 @@ -29,6 +29,17 @@ require ( go.uber.org/ratelimit v0.3.0 ) +require ( + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 // indirect + go.opentelemetry.io/otel/log v0.4.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.4.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect +) + require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect cosmossdk.io/api v0.3.1 // indirect @@ -383,11 +394,11 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect - github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a // indirect - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 // indirect + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd // indirect + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 // indirect github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 // indirect github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 274e20d9c9..a9d6785672 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1399,18 +1399,18 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1:siC6AoTs4889FwiqgEp0sC6S8nFlDzVTZAmUX7cV7aM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293 h1:Q19HQPzISHKEIP0rNFGEiIFvMEeAgb1YRXEFnyBMnNM= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240909141252-663388d38293/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45 h1:NBQLtqk8zsyY4qTJs+NElI3aDFTcAo83JHvqD04EvB0= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240710121324-3ed288aa9b45/go.mod h1:LV0h7QBQUpoC2UUi6TcUvcIFm1xjP/DtEcqV8+qeLUs= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 h1:9SkeP9lpTMDqtqDd+BKPQhkPcylSoYi63L9YFdbzbEo= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 h1:JM6P74E9WvLif/PX+eeY1CNZ7u8Dh3PIQej3rB3XHG8= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5/go.mod h1:IYU8HDfJ8BJAXrWpRILYlEkyrLlZIbAwKEcYq+ImudI= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5 h1:88ZNrxZd0Uxn9934G/3L5AABTX13iorQJdUXcSUewwg= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240909142234-299749c4c0b5/go.mod h1:/QPAcfj5RQ4pNmDBLJ/Or7EjMAvFU3Xb1pM9gl0jfao= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a h1:0zbG9reudNAJC/Rwe3tYX7kshVtOEXXAhk0uLg/62Y4= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240904154226-abc1ed5c962a/go.mod h1:4jS7gAEHONm1dE7SkiUV16FXzuCMycG8X/9WXwNAHQI= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799 h1:HyLTySm7BR+oNfZqDTkVJ25wnmcTtxBBD31UkFL+kEM= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240709043547-03612098f799/go.mod h1:UVFRacRkP7O7TQAzFmR52v5mUlxf+G1ovMlCQAB/cHU= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd h1:+RFI4mgXSGEcn847e7bavhQCqaBiW142g1XfGzijFoY= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd/go.mod h1:Ou79geDZKg87CgRi0BTQpRhUT3U6LcrQWuGQveDRvlg= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 h1:Tkl0/SB1hxjBgphslHf1E6iXp+4QAejuCLIT+8zvX3Y= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3/go.mod h1:mkuwCChesVqzMQpYQWRwckmQobJLwG4XCsw7KB8UCKY= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 h1:Owb1MQZn0NZHwtZAnPZE6TVoTx6xLrfPaUdeOYswE9M= @@ -1634,16 +1634,30 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIX go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 h1:UiRNKd1OgqsLbFwE+wkAWTdiAxXtCBqKIHeBIse4FUA= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9/go.mod h1:eqZlW3pJWhjyexnDPrdQxix1pn0wwhI4AO4GKpP/bMI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 h1:U2guen0GhqH8o/G2un8f/aG/y++OuW6MyCo6hT9prXk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0/go.mod h1:yeGZANgEcpdx/WK0IvvRFC+2oLiMS2u4L/0Rj2M2Qr0= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 h1:0MH3f8lZrflbUWXVxyBg/zviDFdGE062uKh5+fu8Vv0= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0/go.mod h1:Vh68vYiHY5mPdekTr0ox0sALsqjoVy0w3Os278yX5SQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 h1:BJee2iLkfRfl9lc7aFmBwkWxY/RI1RDdXepSF6y8TPE= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0/go.mod h1:DIzlHs3DRscCIBU3Y9YSzPfScwnYnzfnCd4g8zA7bZc= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 h1:EVSnY9JbEEW92bEkIYOVMw4q1WJxIAGoFTrtYOzWuRQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0/go.mod h1:Ea1N1QQryNXpCD0I1fdLibBAIpQuBkznMmkdKrapk1Y= +go.opentelemetry.io/otel/log v0.4.0 h1:/vZ+3Utqh18e8TPjuc3ecg284078KWrR8BRz+PQAj3o= +go.opentelemetry.io/otel/log v0.4.0/go.mod h1:DhGnQvky7pHy82MIRV43iXh3FlKN8UUKftn0KbLOq6I= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/sdk/log v0.4.0 h1:1mMI22L82zLqf6KtkjrRy5BbagOTWdJsqMY/HSqILAA= +go.opentelemetry.io/otel/sdk/log v0.4.0/go.mod h1:AYJ9FVF0hNOgAVzUG/ybg/QttnXhUePWAupmCqtdESo= go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= diff --git a/plugins/medianpoc/plugin_test.go b/plugins/medianpoc/plugin_test.go index 22e4c095d6..d2d17db32a 100644 --- a/plugins/medianpoc/plugin_test.go +++ b/plugins/medianpoc/plugin_test.go @@ -73,7 +73,7 @@ func (p provider) OnchainConfigCodec() median.OnchainConfigCodec { return mockOnchainConfigCodec{} } -func (p provider) ChainReader() types.ContractReader { +func (p provider) ContractReader() types.ContractReader { return nil } From 0e03149d686002815737e3383dea01d2ab0b3492 Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 10 Sep 2024 15:51:02 -0400 Subject: [PATCH 322/432] updating codeowners so CCIP is aware of updates to ccip smoke tests + data-streams (#14339) * updating codeowners so CCIP is aware of updates to ccip smoke tests * mercury-team --> data-streams-engineers in CODEOWNERS --- .github/CODEOWNERS | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index fb066e5347..bafde6de0e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -24,9 +24,9 @@ /core/services/pg @smartcontractkit/foundations @samsondav /core/services/pipeline @smartcontractkit/foundations @smartcontractkit/bix-framework /core/services/telemetry @smartcontractkit/realtime -/core/services/relay/evm/mercury @smartcontractkit/mercury-team +/core/services/relay/evm/mercury @smartcontractkit/data-streams-engineers /core/services/webhook @smartcontractkit/foundations @smartcontractkit/bix-framework -/core/services/llo @smartcontractkit/mercury-team +/core/services/llo @smartcontractkit/data-streams-engineers # VRF-related services /core/services/vrf @smartcontractkit/vrf-team @@ -63,7 +63,7 @@ core/scripts/gateway @smartcontractkit/functions /contracts/**/*upkeep* @smartcontractkit/keepers /contracts/**/*automation* @smartcontractkit/keepers /contracts/**/*functions* @smartcontractkit/functions -/contracts/**/*llo-feeds* @smartcontractkit/mercury-team +/contracts/**/*llo-feeds* @smartcontractkit/data-streams-engineers /contracts/**/*vrf* @smartcontractkit/vrf-team /contracts/**/*l2ep* @smartcontractkit/bix-ship /contracts/**/*keystone* @smartcontractkit/keystone @@ -72,7 +72,7 @@ core/scripts/gateway @smartcontractkit/functions /contracts/src/v0.8/functions @smartcontractkit/functions # TODO: interfaces folder, folder should be removed and files moved to the correct folders /contracts/src/v0.8/l2ep @chris-de-leon-cll -/contracts/src/v0.8/llo-feeds @smartcontractkit/mercury-team +/contracts/src/v0.8/llo-feeds @smartcontractkit/data-streams-engineers # TODO: mocks folder, folder should be removed and files moved to the correct folders /contracts/src/v0.8/operatorforwarder @smartcontractkit/data-feeds-engineers /contracts/src/v0.8/shared @RensR @matYang @RayXpub @elatoskinas @@ -90,6 +90,7 @@ core/scripts/gateway @smartcontractkit/functions # Tests /integration-tests/ @smartcontractkit/test-tooling-team +/integration-tests/ccip-tests @smartcontractkit/ccip-offchain /integration-tests/**/*keeper* @smartcontractkit/keepers /integration-tests/**/*automation* @smartcontractkit/keepers From 150634e5880d6e5d10c11fbe824134da875b4893 Mon Sep 17 00:00:00 2001 From: ilija42 <57732589+ilija42@users.noreply.github.com> Date: Wed, 11 Sep 2024 00:05:28 +0200 Subject: [PATCH 323/432] Bump cosmos (#14393) * Bump cosmos * run generate --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.md | 1 + go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 9 files changed, 13 insertions(+), 12 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index d3888520a3..21687a7cc4 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -272,7 +272,7 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 6dd991a958..a65014a9d1 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1083,8 +1083,8 @@ github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 h1:9SkeP9lpTMDqtqDd+BKPQhkPcylSoYi63L9YFdbzbEo= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 h1:JM6P74E9WvLif/PX+eeY1CNZ7u8Dh3PIQej3rB3XHG8= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5/go.mod h1:IYU8HDfJ8BJAXrWpRILYlEkyrLlZIbAwKEcYq+ImudI= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 h1:xow5cYrWxRmzTwhz2AjWOlnI9WRF4O5b84bXm1k292E= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227/go.mod h1:DUFantPYoBGwBSkNVt2k4ZJi0jPKRRrZVVlAzcZwreA= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= diff --git a/go.md b/go.md index dabb3fc92e..9d11c19168 100644 --- a/go.md +++ b/go.md @@ -61,6 +61,7 @@ flowchart LR chainlink-common --> libocr chainlink-cosmos --> chainlink-common chainlink-cosmos --> libocr + chainlink-cosmos --> grpc-proxy chainlink-data-streams --> chainlink-common chainlink-data-streams --> libocr chainlink-data-streams --> grpc-proxy diff --git a/go.mod b/go.mod index 71c1adc029..32959272ea 100644 --- a/go.mod +++ b/go.mod @@ -76,7 +76,7 @@ require ( github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd diff --git a/go.sum b/go.sum index bfc16c5ada..adc46fa723 100644 --- a/go.sum +++ b/go.sum @@ -1044,8 +1044,8 @@ github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 h1:9SkeP9lpTMDqtqDd+BKPQhkPcylSoYi63L9YFdbzbEo= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 h1:JM6P74E9WvLif/PX+eeY1CNZ7u8Dh3PIQej3rB3XHG8= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5/go.mod h1:IYU8HDfJ8BJAXrWpRILYlEkyrLlZIbAwKEcYq+ImudI= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 h1:xow5cYrWxRmzTwhz2AjWOlnI9WRF4O5b84bXm1k292E= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227/go.mod h1:DUFantPYoBGwBSkNVt2k4ZJi0jPKRRrZVVlAzcZwreA= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 15af3f0b7c..4effcf9f2f 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -403,7 +403,7 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 21b260d21b..18538f1b98 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1427,8 +1427,8 @@ github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 h1:9SkeP9lpTMDqtqDd+BKPQhkPcylSoYi63L9YFdbzbEo= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 h1:JM6P74E9WvLif/PX+eeY1CNZ7u8Dh3PIQej3rB3XHG8= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5/go.mod h1:IYU8HDfJ8BJAXrWpRILYlEkyrLlZIbAwKEcYq+ImudI= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 h1:xow5cYrWxRmzTwhz2AjWOlnI9WRF4O5b84bXm1k292E= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227/go.mod h1:DUFantPYoBGwBSkNVt2k4ZJi0jPKRRrZVVlAzcZwreA= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index f9f903fc34..d3d6d8452a 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -394,7 +394,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index a9d6785672..e781103a2d 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1401,8 +1401,8 @@ github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 h1:9SkeP9lpTMDqtqDd+BKPQhkPcylSoYi63L9YFdbzbEo= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5 h1:JM6P74E9WvLif/PX+eeY1CNZ7u8Dh3PIQej3rB3XHG8= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910130914-fd4a45b0a3f5/go.mod h1:IYU8HDfJ8BJAXrWpRILYlEkyrLlZIbAwKEcYq+ImudI= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 h1:xow5cYrWxRmzTwhz2AjWOlnI9WRF4O5b84bXm1k292E= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227/go.mod h1:DUFantPYoBGwBSkNVt2k4ZJi0jPKRRrZVVlAzcZwreA= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= From f202bcfe45648cc803b38650a7aaf6fecb91969d Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Tue, 10 Sep 2024 23:09:22 -0400 Subject: [PATCH 324/432] DEVSVCS-98: update contract versions and small fixes (#14390) * DEVSVCS-98: update contract versions and small fixes * add changeset * lock the version --- contracts/.changeset/rich-lamps-do.md | 5 +++++ .../generate-zksync-automation-master-interface-v2_3.ts | 2 +- contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol | 2 +- .../interfaces/zksync/IZKSyncAutomationRegistryMaster2_3.sol | 2 +- .../automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol | 4 +++- 5 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 contracts/.changeset/rich-lamps-do.md diff --git a/contracts/.changeset/rich-lamps-do.md b/contracts/.changeset/rich-lamps-do.md new file mode 100644 index 0000000000..3f432d3de6 --- /dev/null +++ b/contracts/.changeset/rich-lamps-do.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +update zksync automation contract version and small fixes diff --git a/contracts/scripts/generate-zksync-automation-master-interface-v2_3.ts b/contracts/scripts/generate-zksync-automation-master-interface-v2_3.ts index 1b91fd3636..385d1fb45b 100644 --- a/contracts/scripts/generate-zksync-automation-master-interface-v2_3.ts +++ b/contracts/scripts/generate-zksync-automation-master-interface-v2_3.ts @@ -46,7 +46,7 @@ const checksum = utils.id(abis.join('')) fs.writeFileSync(`${tmpDest}`, JSON.stringify(combinedABI)) const cmd = ` -cat ${tmpDest} | pnpm abi-to-sol --solidity-version ^0.8.4 --license MIT > ${srcDest} IZKSyncAutomationRegistryMaster2_3; +cat ${tmpDest} | pnpm abi-to-sol --solidity-version ^0.8.19 --license MIT > ${srcDest} IZKSyncAutomationRegistryMaster2_3; echo "// solhint-disable \n// abi-checksum: ${checksum}" | cat - ${srcDest} > ${tmpDest} && mv ${tmpDest} ${srcDest}; pnpm prettier --write ${srcDest}; ` diff --git a/contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol b/contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol index fd6eb3dee9..f4616ba132 100644 --- a/contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol +++ b/contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.16; +pragma solidity 0.8.19; import {IAutomationRegistryConsumer} from "./interfaces/IAutomationRegistryConsumer.sol"; import {GAS_BOUND_CALLER, IGasBoundCaller} from "./interfaces/zksync/IGasBoundCaller.sol"; diff --git a/contracts/src/v0.8/automation/interfaces/zksync/IZKSyncAutomationRegistryMaster2_3.sol b/contracts/src/v0.8/automation/interfaces/zksync/IZKSyncAutomationRegistryMaster2_3.sol index 26b8a7d5c5..8943721559 100644 --- a/contracts/src/v0.8/automation/interfaces/zksync/IZKSyncAutomationRegistryMaster2_3.sol +++ b/contracts/src/v0.8/automation/interfaces/zksync/IZKSyncAutomationRegistryMaster2_3.sol @@ -2,7 +2,7 @@ // abi-checksum: 0x5857a77a981fcb60dbdac0700e68420cbe544249b20d9326d51c5ef8584c5dd7 // SPDX-License-Identifier: MIT // !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.6.6. SEE SOURCE BELOW. !! -pragma solidity ^0.8.4; +pragma solidity ^0.8.19; interface IZKSyncAutomationRegistryMaster2_3 { error ArrayHasNoEntries(); diff --git a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol index 67a9a56b3d..5d5bf23aa2 100644 --- a/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol +++ b/contracts/src/v0.8/automation/v2_3_zksync/ZKSyncAutomationRegistry2_3.sol @@ -164,8 +164,10 @@ contract ZKSyncAutomationRegistry2_3 is ZKSyncAutomationRegistryBase2_3, OCR2Abs if (upkeepTransmitInfo[i].triggerType == Trigger.CONDITION) { gasOverhead += REGISTRY_CONDITIONAL_OVERHEAD; - } else { + } else if (upkeepTransmitInfo[i].triggerType == Trigger.LOG) { gasOverhead += REGISTRY_LOG_OVERHEAD; + } else { + revert InvalidTriggerType(); } } // No upkeeps to be performed in this report From 070b272f30054be6d4239d078121ca3b3054fc33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Wed, 11 Sep 2024 15:33:21 +0300 Subject: [PATCH 325/432] Updates to the Write Target capability (#14350) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use ERC165Checker in the forwarder * Bump gas for routing + move Transmission struct * Generate things * Validate report ID in the inputs matches one in Report bytes * Match report IDs * Fix error message * Fix report ID check * Change validation * Convert hex to bytes * Fix all tests 🤞 * Incorporate Blaz's changes * Remoe poller expectation * Remove unused import --- .changeset/clever-months-brake.md | 5 ++ contracts/.changeset/quiet-lamps-walk.md | 5 ++ contracts/gas-snapshots/keystone.gas-snapshot | 26 +++++----- .../v0.8/keystone/KeystoneFeedsConsumer.sol | 4 +- .../src/v0.8/keystone/KeystoneForwarder.sol | 47 ++++++++++++------- .../src/v0.8/keystone/interfaces/IRouter.sol | 16 ------- .../src/v0.8/keystone/test/mocks/Receiver.sol | 4 +- .../integration_tests/streams_test.go | 2 +- core/capabilities/targets/write_target.go | 23 +++++++-- .../capabilities/targets/write_target_test.go | 5 +- .../feeds_consumer/feeds_consumer.go | 2 +- .../keystone/generated/forwarder/forwarder.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 4 +- core/services/relay/evm/write_target.go | 12 ----- core/services/relay/evm/write_target_test.go | 7 ++- 15 files changed, 86 insertions(+), 78 deletions(-) create mode 100644 .changeset/clever-months-brake.md create mode 100644 contracts/.changeset/quiet-lamps-walk.md diff --git a/.changeset/clever-months-brake.md b/.changeset/clever-months-brake.md new file mode 100644 index 0000000000..0408383bd0 --- /dev/null +++ b/.changeset/clever-months-brake.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal diff --git a/contracts/.changeset/quiet-lamps-walk.md b/contracts/.changeset/quiet-lamps-walk.md new file mode 100644 index 0000000000..93fba83b55 --- /dev/null +++ b/contracts/.changeset/quiet-lamps-walk.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +#internal diff --git a/contracts/gas-snapshots/keystone.gas-snapshot b/contracts/gas-snapshots/keystone.gas-snapshot index 0f3af9a543..3768721ab4 100644 --- a/contracts/gas-snapshots/keystone.gas-snapshot +++ b/contracts/gas-snapshots/keystone.gas-snapshot @@ -82,11 +82,11 @@ CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_RemovingCapabilityRequiredB CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_SignerAddressEmpty() (gas: 29080) CapabilitiesRegistry_UpdateNodesTest:test_RevertWhen_UpdatingNodeWithoutCapabilities() (gas: 27609) CapabilitiesRegistry_UpdateNodesTest:test_UpdatesNodeParams() (gas: 162264) -KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 2003568) -KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() (gas: 124908) +KeystoneForwarder_ReportTest:test_Report_ConfigVersion() (gas: 2006044) +KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverInterfaceNotSupported() (gas: 124668) KeystoneForwarder_ReportTest:test_Report_FailedDeliveryWhenReceiverNotContract() (gas: 126927) -KeystoneForwarder_ReportTest:test_Report_SuccessfulDelivery() (gas: 361243) -KeystoneForwarder_ReportTest:test_Report_SuccessfulRetryWithMoreGas() (gas: 501084) +KeystoneForwarder_ReportTest:test_Report_SuccessfulDelivery() (gas: 362419) +KeystoneForwarder_ReportTest:test_Report_SuccessfulRetryWithMoreGas() (gas: 483436) KeystoneForwarder_ReportTest:test_RevertWhen_AnySignatureIsInvalid() (gas: 86326) KeystoneForwarder_ReportTest:test_RevertWhen_AnySignerIsInvalid() (gas: 118521) KeystoneForwarder_ReportTest:test_RevertWhen_AttemptingTransmissionWithInsufficientGas() (gas: 96279) @@ -95,20 +95,20 @@ KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasIncorrectDON() (gas: 75930 KeystoneForwarder_ReportTest:test_RevertWhen_ReportHasInexistentConfigVersion() (gas: 76298) KeystoneForwarder_ReportTest:test_RevertWhen_ReportIsMalformed() (gas: 45563) KeystoneForwarder_ReportTest:test_RevertWhen_RetryingInvalidContractTransmission() (gas: 143591) -KeystoneForwarder_ReportTest:test_RevertWhen_RetryingSuccessfulTransmission() (gas: 354042) +KeystoneForwarder_ReportTest:test_RevertWhen_RetryingSuccessfulTransmission() (gas: 355218) KeystoneForwarder_ReportTest:test_RevertWhen_TooFewSignatures() (gas: 55292) KeystoneForwarder_ReportTest:test_RevertWhen_TooManySignatures() (gas: 56050) KeystoneForwarder_SetConfigTest:test_RevertWhen_ExcessSigners() (gas: 20184) KeystoneForwarder_SetConfigTest:test_RevertWhen_FaultToleranceIsZero() (gas: 88057) KeystoneForwarder_SetConfigTest:test_RevertWhen_InsufficientSigners() (gas: 14533) KeystoneForwarder_SetConfigTest:test_RevertWhen_NotOwner() (gas: 88766) -KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingDuplicateSigners() (gas: 114570) -KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingZeroAddressSigner() (gas: 114225) -KeystoneForwarder_SetConfigTest:test_SetConfig_FirstTime() (gas: 1540541) -KeystoneForwarder_SetConfigTest:test_SetConfig_WhenSignersAreRemoved() (gas: 1535211) +KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingDuplicateSigners() (gas: 114578) +KeystoneForwarder_SetConfigTest:test_RevertWhen_ProvidingZeroAddressSigner() (gas: 114233) +KeystoneForwarder_SetConfigTest:test_SetConfig_FirstTime() (gas: 1540665) +KeystoneForwarder_SetConfigTest:test_SetConfig_WhenSignersAreRemoved() (gas: 1535361) KeystoneForwarder_TypeAndVersionTest:test_TypeAndVersion() (gas: 9641) -KeystoneRouter_SetConfigTest:test_AddForwarder_RevertWhen_NotOwner() (gas: 10978) -KeystoneRouter_SetConfigTest:test_RemoveForwarder_RevertWhen_NotOwner() (gas: 10923) -KeystoneRouter_SetConfigTest:test_RemoveForwarder_Success() (gas: 17599) +KeystoneRouter_SetConfigTest:test_AddForwarder_RevertWhen_NotOwner() (gas: 10982) +KeystoneRouter_SetConfigTest:test_RemoveForwarder_RevertWhen_NotOwner() (gas: 10927) +KeystoneRouter_SetConfigTest:test_RemoveForwarder_Success() (gas: 17603) KeystoneRouter_SetConfigTest:test_Route_RevertWhen_UnauthorizedForwarder() (gas: 18552) -KeystoneRouter_SetConfigTest:test_Route_Success() (gas: 79379) \ No newline at end of file +KeystoneRouter_SetConfigTest:test_Route_Success() (gas: 80568) \ No newline at end of file diff --git a/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol b/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol index ba1a7c6a8c..306b211f33 100644 --- a/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol +++ b/contracts/src/v0.8/keystone/KeystoneFeedsConsumer.sol @@ -99,7 +99,7 @@ contract KeystoneFeedsConsumer is IReceiver, OwnerIsCreator, IERC165 { return (report.Price, report.Timestamp); } - function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { - return interfaceId == this.onReport.selector; + function supportsInterface(bytes4 interfaceId) public pure returns (bool) { + return interfaceId == type(IReceiver).interfaceId || interfaceId == type(IERC165).interfaceId; } } diff --git a/contracts/src/v0.8/keystone/KeystoneForwarder.sol b/contracts/src/v0.8/keystone/KeystoneForwarder.sol index f92295cab9..3fb85b0fb7 100644 --- a/contracts/src/v0.8/keystone/KeystoneForwarder.sol +++ b/contracts/src/v0.8/keystone/KeystoneForwarder.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {ERC165Checker} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol"; import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol"; @@ -66,6 +66,22 @@ contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { mapping(address signer => uint256 position) _positions; // 1-indexed to detect unset values } + struct Transmission { + address transmitter; + // This is true if the receiver is not a contract or does not implement the + // `IReceiver` interface. + bool invalidReceiver; + // Whether the transmission attempt was successful. If `false`, the + // transmission can be retried with an increased gas limit. + bool success; + // The amount of gas allocated for the `IReceiver.onReport` call. uint80 + // allows storing gas for known EVM block gas limits. + // Ensures that the minimum gas requested by the user is available during + // the transmission attempt. If the transmission fails (indicated by a + // `false` success state), it can be retried with an increased gas limit. + uint80 gasLimit; + } + /// @notice Contains the configuration for each DON ID // @param configId (uint64(donId) << 32) | configVersion mapping(uint64 configId => OracleSet oracleSet) internal s_configs; @@ -94,7 +110,7 @@ contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { /// @dev The gas we require to revert in case of a revert in the call to the /// receiver. This is more than enough and does not attempt to be exact. - uint256 internal constant REQUIRED_GAS_FOR_ROUTING = 40_000; + uint256 internal constant REQUIRED_GAS_FOR_ROUTING = 60_000; // ================================================================ // │ Router │ @@ -131,29 +147,24 @@ contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { s_transmissions[transmissionId].transmitter = transmitter; s_transmissions[transmissionId].gasLimit = uint80(gasLimit); - if (receiver.code.length == 0) { + if (!ERC165Checker.supportsInterface(receiver, type(IReceiver).interfaceId)) { s_transmissions[transmissionId].invalidReceiver = true; return false; } - try IERC165(receiver).supportsInterface(type(IReceiver).interfaceId) { - bool success; - bytes memory payload = abi.encodeCall(IReceiver.onReport, (metadata, validatedReport)); + bool success; + bytes memory payload = abi.encodeCall(IReceiver.onReport, (metadata, validatedReport)); - assembly { - // call and return whether we succeeded. ignore return data - // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) - success := call(gasLimit, receiver, 0, add(payload, 0x20), mload(payload), 0x0, 0x0) - } + assembly { + // call and return whether we succeeded. ignore return data + // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) + success := call(gasLimit, receiver, 0, add(payload, 0x20), mload(payload), 0x0, 0x0) + } - if (success) { - s_transmissions[transmissionId].success = true; - } - return success; - } catch { - s_transmissions[transmissionId].invalidReceiver = true; - return false; + if (success) { + s_transmissions[transmissionId].success = true; } + return success; } function getTransmissionId( diff --git a/contracts/src/v0.8/keystone/interfaces/IRouter.sol b/contracts/src/v0.8/keystone/interfaces/IRouter.sol index e40f331867..3209ae5831 100644 --- a/contracts/src/v0.8/keystone/interfaces/IRouter.sol +++ b/contracts/src/v0.8/keystone/interfaces/IRouter.sol @@ -19,22 +19,6 @@ interface IRouter { FAILED } - struct Transmission { - address transmitter; - // This is true if the receiver is not a contract or does not implement the - // `IReceiver` interface. - bool invalidReceiver; - // Whether the transmission attempt was successful. If `false`, the - // transmission can be retried with an increased gas limit. - bool success; - // The amount of gas allocated for the `IReceiver.onReport` call. uint80 - // allows storing gas for known EVM block gas limits. - // Ensures that the minimum gas requested by the user is available during - // the transmission attempt. If the transmission fails (indicated by a - // `false` success state), it can be retried with an increased gas limit. - uint80 gasLimit; - } - struct TransmissionInfo { bytes32 transmissionId; TransmissionState state; diff --git a/contracts/src/v0.8/keystone/test/mocks/Receiver.sol b/contracts/src/v0.8/keystone/test/mocks/Receiver.sol index 3c1f157bc4..d4005950ad 100644 --- a/contracts/src/v0.8/keystone/test/mocks/Receiver.sol +++ b/contracts/src/v0.8/keystone/test/mocks/Receiver.sol @@ -18,7 +18,7 @@ contract Receiver is IReceiver, IERC165 { emit MessageReceived(metadata, mercuryReports); } - function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { - return interfaceId == this.onReport.selector; + function supportsInterface(bytes4 interfaceId) public pure returns (bool) { + return interfaceId == type(IReceiver).interfaceId || interfaceId == type(IERC165).interfaceId; } } diff --git a/core/capabilities/integration_tests/streams_test.go b/core/capabilities/integration_tests/streams_test.go index 8c8f51914c..06c56f722f 100644 --- a/core/capabilities/integration_tests/streams_test.go +++ b/core/capabilities/integration_tests/streams_test.go @@ -73,7 +73,7 @@ func waitForConsumerReports(ctx context.Context, t *testing.T, consumer *feeds_c feedToReport[report.FeedID] = report } - ctxWithTimeout, cancel := context.WithTimeout(ctx, 5*time.Minute) + ctxWithTimeout, cancel := context.WithTimeout(ctx, 1*time.Minute) defer cancel() feedCount := 0 for { diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index c77dc06199..c8f33ff823 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -165,11 +165,24 @@ func evaluate(rawRequest capabilities.CapabilityRequest) (r Request, err error) return r, fmt.Errorf("unsupported report version: %d", reportMetadata.Version) } - if hex.EncodeToString(reportMetadata.WorkflowExecutionID[:]) != rawRequest.Metadata.WorkflowExecutionID || - hex.EncodeToString(reportMetadata.WorkflowOwner[:]) != rawRequest.Metadata.WorkflowOwner || - hex.EncodeToString(reportMetadata.WorkflowName[:]) != rawRequest.Metadata.WorkflowName || - hex.EncodeToString(reportMetadata.WorkflowCID[:]) != rawRequest.Metadata.WorkflowID { - return r, fmt.Errorf("report metadata does not match request metadata. reportMetadata: %+v, requestMetadata: %+v", reportMetadata, rawRequest.Metadata) + if hex.EncodeToString(reportMetadata.WorkflowExecutionID[:]) != rawRequest.Metadata.WorkflowExecutionID { + return r, fmt.Errorf("WorkflowExecutionID in the report does not match WorkflowExecutionID in the request metadata. Report WorkflowExecutionID: %+v, request WorkflowExecutionID: %+v", reportMetadata.WorkflowExecutionID, rawRequest.Metadata.WorkflowExecutionID) + } + + if hex.EncodeToString(reportMetadata.WorkflowOwner[:]) != rawRequest.Metadata.WorkflowOwner { + return r, fmt.Errorf("WorkflowOwner in the report does not match WorkflowOwner in the request metadata. Report WorkflowOwner: %+v, request WorkflowOwner: %+v", reportMetadata.WorkflowOwner, rawRequest.Metadata.WorkflowOwner) + } + + if hex.EncodeToString(reportMetadata.WorkflowName[:]) != rawRequest.Metadata.WorkflowName { + return r, fmt.Errorf("WorkflowName in the report does not match WorkflowName in the request metadata. Report WorkflowName: %+v, request WorkflowName: %+v", reportMetadata.WorkflowName, rawRequest.Metadata.WorkflowName) + } + + if hex.EncodeToString(reportMetadata.WorkflowCID[:]) != rawRequest.Metadata.WorkflowID { + return r, fmt.Errorf("WorkflowID in the report does not match WorkflowID in the request metadata. Report WorkflowID: %+v, request WorkflowID: %+v", reportMetadata.WorkflowCID, rawRequest.Metadata.WorkflowID) + } + + if !bytes.Equal(reportMetadata.ReportID[:], r.Inputs.SignedReport.ID) { + return r, fmt.Errorf("ReportID in the report does not match ReportID in the inputs. reportMetadata.ReportID: %x, Inputs.SignedReport.ID: %x", reportMetadata.ReportID, r.Inputs.SignedReport.ID) } return r, nil diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go index cdef0cc83b..1dd5323d0f 100644 --- a/core/capabilities/targets/write_target_test.go +++ b/core/capabilities/targets/write_target_test.go @@ -41,6 +41,7 @@ func TestWriteTarget(t *testing.T) { }) require.NoError(t, err) + reportID := [2]byte{0x00, 0x01} reportMetadata := targets.ReportV1Metadata{ Version: 1, WorkflowExecutionID: [32]byte{}, @@ -50,7 +51,7 @@ func TestWriteTarget(t *testing.T) { WorkflowCID: [32]byte{}, WorkflowName: [10]byte{}, WorkflowOwner: [20]byte{}, - ReportID: [2]byte{}, + ReportID: reportID, } reportMetadataBytes, err := reportMetadata.Encode() @@ -60,6 +61,8 @@ func TestWriteTarget(t *testing.T) { "signed_report": map[string]any{ "report": reportMetadataBytes, "signatures": [][]byte{}, + "context": []byte{4, 5}, + "id": reportID[:], }, }) require.NoError(t, err) diff --git a/core/gethwrappers/keystone/generated/feeds_consumer/feeds_consumer.go b/core/gethwrappers/keystone/generated/feeds_consumer/feeds_consumer.go index 2951835c8d..8b618fbddb 100644 --- a/core/gethwrappers/keystone/generated/feeds_consumer/feeds_consumer.go +++ b/core/gethwrappers/keystone/generated/feeds_consumer/feeds_consumer.go @@ -32,7 +32,7 @@ var ( var KeystoneFeedsConsumerMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"}],\"name\":\"UnauthorizedWorkflowName\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"}],\"name\":\"UnauthorizedWorkflowOwner\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint224\",\"name\":\"price\",\"type\":\"uint224\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"name\":\"FeedReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"getPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_allowedSendersList\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_allowedWorkflowOwnersList\",\"type\":\"address[]\"},{\"internalType\":\"bytes10[]\",\"name\":\"_allowedWorkflowNamesList\",\"type\":\"bytes10[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611281806101576000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063805f21321161005b578063805f2132146101ab5780638da5cb5b146101be578063e3401711146101e6578063f2fde38b146101f957600080fd5b806301ffc9a71461008257806331d98b3f146100ec57806379ba5097146101a1575b600080fd5b6100d7610090366004610dd4565b7fffffffff00000000000000000000000000000000000000000000000000000000167f805f2132000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b6101686100fa366004610e1d565b6000908152600260209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168084527c010000000000000000000000000000000000000000000000000000000090910463ffffffff169290910182905291565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909316835263ffffffff9091166020830152016100e3565b6101a961020c565b005b6101a96101b9366004610e7f565b61030e565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e3565b6101a96101f4366004610f30565b61068d565b6101a9610207366004610fca565b610acd565b60015473ffffffffffffffffffffffffffffffffffffffff163314610292576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3360009081526004602052604090205460ff16610359576040517f3fcc3f17000000000000000000000000000000000000000000000000000000008152336004820152602401610289565b60008061039b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ae192505050565b7fffffffffffffffffffff000000000000000000000000000000000000000000008216600090815260086020526040902054919350915060ff1661042f576040517f4b942f800000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffff0000000000000000000000000000000000000000000083166004820152602401610289565b73ffffffffffffffffffffffffffffffffffffffff811660009081526006602052604090205460ff166104a6576040517fbf24162300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610289565b60006104b4848601866110a7565b905060005b81518110156106835760405180604001604052808383815181106104df576104df6111b9565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152602001838381518110610520576105206111b9565b60200260200101516040015163ffffffff168152506002600084848151811061054b5761054b6111b9565b602090810291909101810151518252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117905581518290829081106105cd576105cd6111b9565b6020026020010151600001517f2c30f5cb3caf4239d0f994ce539d7ef24817fa550169c388e3a110f02e40197d83838151811061060c5761060c6111b9565b60200260200101516020015184848151811061062a5761062a6111b9565b6020026020010151604001516040516106739291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a26001016104b9565b5050505050505050565b610695610af7565b60005b60035463ffffffff821610156107365760006004600060038463ffffffff16815481106106c7576106c76111b9565b60009182526020808320919091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905561072f816111e8565b9050610698565b5060005b63ffffffff81168611156107de5760016004600089898563ffffffff16818110610766576107666111b9565b905060200201602081019061077b9190610fca565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556107d7816111e8565b905061073a565b506107eb60038787610c6f565b5060005b60055463ffffffff8216101561088d5760006006600060058463ffffffff168154811061081e5761081e6111b9565b60009182526020808320919091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055610886816111e8565b90506107ef565b5060005b63ffffffff81168411156109355760016006600087878563ffffffff168181106108bd576108bd6111b9565b90506020020160208101906108d29190610fca565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905561092e816111e8565b9050610891565b5061094260058585610c6f565b5060005b60075463ffffffff82161015610a035760006008600060078463ffffffff1681548110610975576109756111b9565b600091825260208083206003808404909101549206600a026101000a90910460b01b7fffffffffffffffffffff00000000000000000000000000000000000000000000168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556109fc816111e8565b9050610946565b5060005b63ffffffff8116821115610ab75760016008600085858563ffffffff16818110610a3357610a336111b9565b9050602002016020810190610a489190611232565b7fffffffffffffffffffff00000000000000000000000000000000000000000000168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055610ab0816111e8565b9050610a07565b50610ac460078383610cf7565b50505050505050565b610ad5610af7565b610ade81610b7a565b50565b6040810151604a90910151909160609190911c90565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610289565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610bf9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610289565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610ce7579160200282015b82811115610ce75781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff843516178255602090920191600190910190610c8f565b50610cf3929150610dbf565b5090565b82805482825590600052602060002090600201600390048101928215610ce75791602002820160005b83821115610d8057833575ffffffffffffffffffffffffffffffffffffffffffff191683826101000a81548169ffffffffffffffffffff021916908360b01c02179055509260200192600a01602081600901049283019260010302610d20565b8015610db65782816101000a81549069ffffffffffffffffffff0219169055600a01602081600901049283019260010302610d80565b5050610cf39291505b5b80821115610cf35760008155600101610dc0565b600060208284031215610de657600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e1657600080fd5b9392505050565b600060208284031215610e2f57600080fd5b5035919050565b60008083601f840112610e4857600080fd5b50813567ffffffffffffffff811115610e6057600080fd5b602083019150836020828501011115610e7857600080fd5b9250929050565b60008060008060408587031215610e9557600080fd5b843567ffffffffffffffff80821115610ead57600080fd5b610eb988838901610e36565b90965094506020870135915080821115610ed257600080fd5b50610edf87828801610e36565b95989497509550505050565b60008083601f840112610efd57600080fd5b50813567ffffffffffffffff811115610f1557600080fd5b6020830191508360208260051b8501011115610e7857600080fd5b60008060008060008060608789031215610f4957600080fd5b863567ffffffffffffffff80821115610f6157600080fd5b610f6d8a838b01610eeb565b90985096506020890135915080821115610f8657600080fd5b610f928a838b01610eeb565b90965094506040890135915080821115610fab57600080fd5b50610fb889828a01610eeb565b979a9699509497509295939492505050565b600060208284031215610fdc57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610e1657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561105257611052611000565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561109f5761109f611000565b604052919050565b600060208083850312156110ba57600080fd5b823567ffffffffffffffff808211156110d257600080fd5b818501915085601f8301126110e657600080fd5b8135818111156110f8576110f8611000565b611106848260051b01611058565b8181528481019250606091820284018501918883111561112557600080fd5b938501935b828510156111ad5780858a0312156111425760008081fd5b61114a61102f565b85358152868601357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461117d5760008081fd5b8188015260408681013563ffffffff8116811461119a5760008081fd5b908201528452938401939285019261112a565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff808316818103611228577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6001019392505050565b60006020828403121561124457600080fd5b81357fffffffffffffffffffff0000000000000000000000000000000000000000000081168114610e1657600080fdfea164736f6c6343000818000a", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6112d8806101576000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063805f21321161005b578063805f2132146101695780638da5cb5b1461017c578063e3401711146101a4578063f2fde38b146101b757600080fd5b806301ffc9a71461008257806331d98b3f146100aa57806379ba50971461015f575b600080fd5b610095610090366004610e2b565b6101ca565b60405190151581526020015b60405180910390f35b6101266100b8366004610e74565b6000908152600260209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168084527c010000000000000000000000000000000000000000000000000000000090910463ffffffff169290910182905291565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909316835263ffffffff9091166020830152016100a1565b610167610263565b005b610167610177366004610ed6565b610365565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a1565b6101676101b2366004610f87565b6106e4565b6101676101c5366004611021565b610b24565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f805f213200000000000000000000000000000000000000000000000000000000148061025d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146102e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3360009081526004602052604090205460ff166103b0576040517f3fcc3f170000000000000000000000000000000000000000000000000000000081523360048201526024016102e0565b6000806103f286868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610b3892505050565b7fffffffffffffffffffff000000000000000000000000000000000000000000008216600090815260086020526040902054919350915060ff16610486576040517f4b942f800000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffff00000000000000000000000000000000000000000000831660048201526024016102e0565b73ffffffffffffffffffffffffffffffffffffffff811660009081526006602052604090205460ff166104fd576040517fbf24162300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016102e0565b600061050b848601866110fe565b905060005b81518110156106da57604051806040016040528083838151811061053657610536611210565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260200183838151811061057757610577611210565b60200260200101516040015163ffffffff16815250600260008484815181106105a2576105a2611210565b602090810291909101810151518252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179055815182908290811061062457610624611210565b6020026020010151600001517f2c30f5cb3caf4239d0f994ce539d7ef24817fa550169c388e3a110f02e40197d83838151811061066357610663611210565b60200260200101516020015184848151811061068157610681611210565b6020026020010151604001516040516106ca9291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a2600101610510565b5050505050505050565b6106ec610b4e565b60005b60035463ffffffff8216101561078d5760006004600060038463ffffffff168154811061071e5761071e611210565b60009182526020808320919091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556107868161123f565b90506106ef565b5060005b63ffffffff81168611156108355760016004600089898563ffffffff168181106107bd576107bd611210565b90506020020160208101906107d29190611021565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905561082e8161123f565b9050610791565b5061084260038787610cc6565b5060005b60055463ffffffff821610156108e45760006006600060058463ffffffff168154811061087557610875611210565b60009182526020808320919091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556108dd8161123f565b9050610846565b5060005b63ffffffff811684111561098c5760016006600087878563ffffffff1681811061091457610914611210565b90506020020160208101906109299190611021565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556109858161123f565b90506108e8565b5061099960058585610cc6565b5060005b60075463ffffffff82161015610a5a5760006008600060078463ffffffff16815481106109cc576109cc611210565b600091825260208083206003808404909101549206600a026101000a90910460b01b7fffffffffffffffffffff00000000000000000000000000000000000000000000168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055610a538161123f565b905061099d565b5060005b63ffffffff8116821115610b0e5760016008600085858563ffffffff16818110610a8a57610a8a611210565b9050602002016020810190610a9f9190611289565b7fffffffffffffffffffff00000000000000000000000000000000000000000000168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055610b078161123f565b9050610a5e565b50610b1b60078383610d4e565b50505050505050565b610b2c610b4e565b610b3581610bd1565b50565b6040810151604a90910151909160609190911c90565b60005473ffffffffffffffffffffffffffffffffffffffff163314610bcf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102e0565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610c50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102e0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610d3e579160200282015b82811115610d3e5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff843516178255602090920191600190910190610ce6565b50610d4a929150610e16565b5090565b82805482825590600052602060002090600201600390048101928215610d3e5791602002820160005b83821115610dd757833575ffffffffffffffffffffffffffffffffffffffffffff191683826101000a81548169ffffffffffffffffffff021916908360b01c02179055509260200192600a01602081600901049283019260010302610d77565b8015610e0d5782816101000a81549069ffffffffffffffffffff0219169055600a01602081600901049283019260010302610dd7565b5050610d4a9291505b5b80821115610d4a5760008155600101610e17565b600060208284031215610e3d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e6d57600080fd5b9392505050565b600060208284031215610e8657600080fd5b5035919050565b60008083601f840112610e9f57600080fd5b50813567ffffffffffffffff811115610eb757600080fd5b602083019150836020828501011115610ecf57600080fd5b9250929050565b60008060008060408587031215610eec57600080fd5b843567ffffffffffffffff80821115610f0457600080fd5b610f1088838901610e8d565b90965094506020870135915080821115610f2957600080fd5b50610f3687828801610e8d565b95989497509550505050565b60008083601f840112610f5457600080fd5b50813567ffffffffffffffff811115610f6c57600080fd5b6020830191508360208260051b8501011115610ecf57600080fd5b60008060008060008060608789031215610fa057600080fd5b863567ffffffffffffffff80821115610fb857600080fd5b610fc48a838b01610f42565b90985096506020890135915080821115610fdd57600080fd5b610fe98a838b01610f42565b9096509450604089013591508082111561100257600080fd5b5061100f89828a01610f42565b979a9699509497509295939492505050565b60006020828403121561103357600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610e6d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156110a9576110a9611057565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156110f6576110f6611057565b604052919050565b6000602080838503121561111157600080fd5b823567ffffffffffffffff8082111561112957600080fd5b818501915085601f83011261113d57600080fd5b81358181111561114f5761114f611057565b61115d848260051b016110af565b8181528481019250606091820284018501918883111561117c57600080fd5b938501935b828510156112045780858a0312156111995760008081fd5b6111a1611086565b85358152868601357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146111d45760008081fd5b8188015260408681013563ffffffff811681146111f15760008081fd5b9082015284529384019392850192611181565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff80831681810361127f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6001019392505050565b60006020828403121561129b57600080fd5b81357fffffffffffffffffffff0000000000000000000000000000000000000000000081168114610e6d57600080fdfea164736f6c6343000818000a", } var KeystoneFeedsConsumerABI = KeystoneFeedsConsumerMetaData.ABI diff --git a/core/gethwrappers/keystone/generated/forwarder/forwarder.go b/core/gethwrappers/keystone/generated/forwarder/forwarder.go index a7a78ab67f..37340c8137 100644 --- a/core/gethwrappers/keystone/generated/forwarder/forwarder.go +++ b/core/gethwrappers/keystone/generated/forwarder/forwarder.go @@ -41,7 +41,7 @@ type IRouterTransmissionInfo struct { var KeystoneForwarderMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"DuplicateSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"}],\"name\":\"InsufficientGasForRouting\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"configId\",\"type\":\"uint64\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"received\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedForwarder\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"ForwarderAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"ForwarderRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"result\",\"type\":\"bool\"}],\"name\":\"ReportProcessed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"addForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"}],\"name\":\"clearConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmissionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmissionInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"},{\"internalType\":\"enumIRouter.TransmissionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"invalidReceiver\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint80\",\"name\":\"gasLimit\",\"type\":\"uint80\"}],\"internalType\":\"structIRouter.TransmissionInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmitter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"isForwarder\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"removeForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"reportContext\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"signatures\",\"type\":\"bytes[]\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"validatedReport\",\"type\":\"bytes\"}],\"name\":\"route\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000bf565b5050306000908152600360205260409020805460ff19166001179055506200016a565b336001600160a01b03821603620001195760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b612141806200017a6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379ba50971161008c578063abcef55411610066578063abcef5541461035d578063ee59d26c14610396578063ef6e17a0146103a9578063f2fde38b146103bc57600080fd5b806379ba50971461025e5780638864b864146102665780638da5cb5b1461033f57600080fd5b8063272cbd93116100c8578063272cbd9314610179578063354bdd66146101995780634d93172d146102385780635c41d2fe1461024b57600080fd5b806311289565146100ef578063181f5a7714610104578063233fd52d14610156575b600080fd5b6101026100fd3660046119df565b6103cf565b005b6101406040518060400160405280601a81526020017f466f7277617264657220616e6420526f7574657220312e302e3000000000000081525081565b60405161014d9190611a8a565b60405180910390f35b610169610164366004611af7565b610989565b604051901515815260200161014d565b61018c610187366004611b7f565b610e4a565b60405161014d9190611c13565b61022a6101a7366004611b7f565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018390527fffff000000000000000000000000000000000000000000000000000000000000821660548201526000906056016040516020818303038152906040528051906020012090509392505050565b60405190815260200161014d565b610102610246366004611cbb565b611050565b610102610259366004611cbb565b6110cc565b61010261114b565b61031a610274366004611b7f565b6040805160609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660208086019190915260348501939093527fffff000000000000000000000000000000000000000000000000000000000000919091166054840152805160368185030181526056909301815282519282019290922060009081526004909152205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014d565b60005473ffffffffffffffffffffffffffffffffffffffff1661031a565b61016961036b366004611cbb565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6101026103a4366004611cf1565b611248565b6101026103b7366004611d6f565b611625565b6101026103ca366004611cbb565b6116c5565b606d85101561040a576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600061044e89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116d992505050565b67ffffffffffffffff8216600090815260026020526040812080549497509195509193509160ff16908190036104c1576040517fdf3b81ea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b856104cd826001611dd1565b60ff161461051f576104e0816001611dd1565b6040517fd6022e8e00000000000000000000000000000000000000000000000000000000815260ff9091166004820152602481018790526044016104b8565b60008b8b604051610531929190611df0565b60405190819003812061054a918c908c90602001611e00565b60405160208183030381529060405280519060200120905061056a61186c565b60005b888110156107ec573660008b8b8481811061058a5761058a611e1a565b905060200281019061059c9190611e49565b9092509050604181146105df5781816040517f2adfdc300000000000000000000000000000000000000000000000000000000081526004016104b8929190611ef7565b6000600186848460408181106105f7576105f7611e1a565b61060992013560f81c9050601b611dd1565b610617602060008789611f13565b61062091611f3d565b61062e60406020888a611f13565b61063791611f3d565b6040805160008152602081018083529590955260ff909316928401929092526060830152608082015260a0016020604051602081039080840390855afa158015610685573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8116600090815260028c0160205291822054909350915081900361072b576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b600086826020811061073f5761073f611e1a565b602002015173ffffffffffffffffffffffffffffffffffffffff16146107a9576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b818682602081106107bc576107bc611e1a565b73ffffffffffffffffffffffffffffffffffffffff909216602092909202015250506001909201915061056d9050565b50506040805160608f901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602080830191909152603482018990527fffff0000000000000000000000000000000000000000000000000000000000008816605483015282516036818403018152605690920190925280519101206000945030935063233fd52d92509050338d8d8d602d90606d9261088e93929190611f13565b8f8f606d9080926108a193929190611f13565b6040518863ffffffff1660e01b81526004016108c39796959493929190611f79565b6020604051808303816000875af11580156108e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109069190611fda565b9050817dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916838b73ffffffffffffffffffffffffffffffffffffffff167f3617b009e9785c42daebadb6d3fb553243a4bf586d07ea72d65d80013ce116b584604051610975911515815260200190565b60405180910390a450505050505050505050565b3360009081526003602052604081205460ff166109d2576040517fd79e123d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005a9050619c40811015610a16576040517f0bfecd63000000000000000000000000000000000000000000000000000000008152600481018a90526024016104b8565b6000898152600460209081526040918290208251608081018452905473ffffffffffffffffffffffffffffffffffffffff8116825274010000000000000000000000000000000000000000810460ff90811615159383019390935275010000000000000000000000000000000000000000008104909216151592810183905276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660608201529080610ace575080602001515b15610b08576040517fa53dc8ca000000000000000000000000000000000000000000000000000000008152600481018b90526024016104b8565b6000610b16619c4084611ffc565b905089600460008d815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600460008d815260200190815260200160002060000160166101000a81548169ffffffffffffffffffff021916908369ffffffffffffffffffff1602179055508873ffffffffffffffffffffffffffffffffffffffff163b600003610c2257505050600088815260046020526040812080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790559050610e3f565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f805f213200000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8a16906301ffc9a790602401602060405180830381865afa925050508015610ce6575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610ce391810190611fda565b60015b610d3f57505050600088815260046020526040812080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790559050610e3f565b5060008089898989604051602401610d5a949392919061200f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f805f21320000000000000000000000000000000000000000000000000000000017815281519192506000918291828f88f191508115610e335760008d815260046020526040902080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b509350610e3f92505050565b979650505050505050565b6040805160c0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905284519088901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001681830152603481018790527fffff000000000000000000000000000000000000000000000000000000000000861660548201528451603681830301815260568201808752815191840191909120808552600490935285842060d68301909652945473ffffffffffffffffffffffffffffffffffffffff811680875274010000000000000000000000000000000000000000820460ff9081161515607685015275010000000000000000000000000000000000000000008304161515609684015276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660b69092019190915292939092909190610fa857506000610fd0565b816020015115610fba57506002610fd0565b8160400151610fca576003610fcd565b60015b90505b6040518060c00160405280848152602001826003811115610ff357610ff3611be4565b8152602001836000015173ffffffffffffffffffffffffffffffffffffffff168152602001836020015115158152602001836040015115158152602001836060015169ffffffffffffffffffff1681525093505050509392505050565b6110586116f4565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fb96d15bf9258c7b8df062753a6a262864611fc7b060a5ee2e57e79b85f898d389190a250565b6110d46116f4565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f0ea0ce2c048ff45a4a95f2947879de3fb94abec2f152190400cab2d1272a68e79190a250565b60015473ffffffffffffffffffffffffffffffffffffffff1633146111cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016104b8565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6112506116f4565b8260ff1660000361128d576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8111156112d2576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101829052601f60248201526044016104b8565b6112dd836003612036565b60ff16811161133b57806112f2846003612036565b6112fd906001611dd1565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260ff1660248201526044016104b8565b67ffffffff00000000602086901b1663ffffffff85161760005b67ffffffffffffffff82166000908152600260205260409020600101548110156113eb5767ffffffffffffffff82166000908152600260208190526040822060018101805491909201929190849081106113b1576113b1611e1a565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812055600101611355565b5060005b8281101561156757600084848381811061140b5761140b611e1a565b90506020020160208101906114209190611cbb565b905073ffffffffffffffffffffffffffffffffffffffff8116611487576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b67ffffffffffffffff8316600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff86168552909201905290205415611513576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b61151e826001612052565b67ffffffffffffffff8416600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff909616845294909101905291909120556001016113ef565b5067ffffffffffffffff8116600090815260026020526040902061158f90600101848461188b565b5067ffffffffffffffff81166000908152600260205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff87161790555163ffffffff86811691908816907f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a4559061161590889088908890612065565b60405180910390a3505050505050565b61162d6116f4565b63ffffffff818116602084811b67ffffffff00000000168217600090815260028252604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558051828152928301905291928516917f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a455916040516116b99291906120cb565b60405180910390a35050565b6116cd6116f4565b6116d681611777565b50565b60218101516045820151608b90920151909260c09290921c91565b60005473ffffffffffffffffffffffffffffffffffffffff163314611775576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104b8565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036117f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104b8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6040518061040001604052806020906020820280368337509192915050565b828054828255906000526020600020908101928215611903579160200282015b828111156119035781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8435161782556020909201916001909101906118ab565b5061190f929150611913565b5090565b5b8082111561190f5760008155600101611914565b803573ffffffffffffffffffffffffffffffffffffffff8116811461194c57600080fd5b919050565b60008083601f84011261196357600080fd5b50813567ffffffffffffffff81111561197b57600080fd5b60208301915083602082850101111561199357600080fd5b9250929050565b60008083601f8401126119ac57600080fd5b50813567ffffffffffffffff8111156119c457600080fd5b6020830191508360208260051b850101111561199357600080fd5b60008060008060008060006080888a0312156119fa57600080fd5b611a0388611928565b9650602088013567ffffffffffffffff80821115611a2057600080fd5b611a2c8b838c01611951565b909850965060408a0135915080821115611a4557600080fd5b611a518b838c01611951565b909650945060608a0135915080821115611a6a57600080fd5b50611a778a828b0161199a565b989b979a50959850939692959293505050565b60006020808352835180602085015260005b81811015611ab857858101830151858201604001528201611a9c565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600080600080600080600060a0888a031215611b1257600080fd5b87359650611b2260208901611928565b9550611b3060408901611928565b9450606088013567ffffffffffffffff80821115611b4d57600080fd5b611b598b838c01611951565b909650945060808a0135915080821115611b7257600080fd5b50611a778a828b01611951565b600080600060608486031215611b9457600080fd5b611b9d84611928565b92506020840135915060408401357fffff00000000000000000000000000000000000000000000000000000000000081168114611bd957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81518152602082015160c082019060048110611c58577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8060208401525073ffffffffffffffffffffffffffffffffffffffff604084015116604083015260608301511515606083015260808301511515608083015260a0830151611cb460a084018269ffffffffffffffffffff169052565b5092915050565b600060208284031215611ccd57600080fd5b611cd682611928565b9392505050565b803563ffffffff8116811461194c57600080fd5b600080600080600060808688031215611d0957600080fd5b611d1286611cdd565b9450611d2060208701611cdd565b9350604086013560ff81168114611d3657600080fd5b9250606086013567ffffffffffffffff811115611d5257600080fd5b611d5e8882890161199a565b969995985093965092949392505050565b60008060408385031215611d8257600080fd5b611d8b83611cdd565b9150611d9960208401611cdd565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff8181168382160190811115611dea57611dea611da2565b92915050565b8183823760009101908152919050565b838152818360208301376000910160200190815292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611e7e57600080fd5b83018035915067ffffffffffffffff821115611e9957600080fd5b60200191503681900382131561199357600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000611f0b602083018486611eae565b949350505050565b60008085851115611f2357600080fd5b83861115611f3057600080fd5b5050820193919092039150565b80356020831015611dea577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525060a06060830152611fb960a083018688611eae565b8281036080840152611fcc818587611eae565b9a9950505050505050505050565b600060208284031215611fec57600080fd5b81518015158114611cd657600080fd5b81810381811115611dea57611dea611da2565b604081526000612023604083018688611eae565b8281036020840152610e3f818587611eae565b60ff8181168382160290811690818114611cb457611cb4611da2565b80820180821115611dea57611dea611da2565b60ff8416815260406020808301829052908201839052600090849060608401835b868110156120bf5773ffffffffffffffffffffffffffffffffffffffff6120ac85611928565b1682529282019290820190600101612086565b50979650505050505050565b60006040820160ff8516835260206040602085015281855180845260608601915060208701935060005b8181101561212757845173ffffffffffffffffffffffffffffffffffffffff16835293830193918301916001016120f5565b509097965050505050505056fea164736f6c6343000818000a", + Bin: "0x60806040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000bf565b5050306000908152600360205260409020805460ff19166001179055506200016a565b336001600160a01b03821603620001195760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b612150806200017a6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379ba50971161008c578063abcef55411610066578063abcef5541461035d578063ee59d26c14610396578063ef6e17a0146103a9578063f2fde38b146103bc57600080fd5b806379ba50971461025e5780638864b864146102665780638da5cb5b1461033f57600080fd5b8063272cbd93116100c8578063272cbd9314610179578063354bdd66146101995780634d93172d146102385780635c41d2fe1461024b57600080fd5b806311289565146100ef578063181f5a7714610104578063233fd52d14610156575b600080fd5b6101026100fd3660046119f4565b6103cf565b005b6101406040518060400160405280601a81526020017f466f7277617264657220616e6420526f7574657220312e302e3000000000000081525081565b60405161014d9190611a9f565b60405180910390f35b610169610164366004611b0c565b610989565b604051901515815260200161014d565b61018c610187366004611b94565b610d0b565b60405161014d9190611c28565b61022a6101a7366004611b94565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018390527fffff000000000000000000000000000000000000000000000000000000000000821660548201526000906056016040516020818303038152906040528051906020012090509392505050565b60405190815260200161014d565b610102610246366004611cd0565b610f11565b610102610259366004611cd0565b610f8d565b61010261100c565b61031a610274366004611b94565b6040805160609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660208086019190915260348501939093527fffff000000000000000000000000000000000000000000000000000000000000919091166054840152805160368185030181526056909301815282519282019290922060009081526004909152205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014d565b60005473ffffffffffffffffffffffffffffffffffffffff1661031a565b61016961036b366004611cd0565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6101026103a4366004611cff565b611109565b6101026103b7366004611d7d565b6114e6565b6101026103ca366004611cd0565b611586565b606d85101561040a576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600061044e89898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159a92505050565b67ffffffffffffffff8216600090815260026020526040812080549497509195509193509160ff16908190036104c1576040517fdf3b81ea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b856104cd826001611ddf565b60ff161461051f576104e0816001611ddf565b6040517fd6022e8e00000000000000000000000000000000000000000000000000000000815260ff9091166004820152602481018790526044016104b8565b60008b8b604051610531929190611df8565b60405190819003812061054a918c908c90602001611e08565b60405160208183030381529060405280519060200120905061056a611881565b60005b888110156107ec573660008b8b8481811061058a5761058a611e22565b905060200281019061059c9190611e51565b9092509050604181146105df5781816040517f2adfdc300000000000000000000000000000000000000000000000000000000081526004016104b8929190611eff565b6000600186848460408181106105f7576105f7611e22565b61060992013560f81c9050601b611ddf565b610617602060008789611f1b565b61062091611f45565b61062e60406020888a611f1b565b61063791611f45565b6040805160008152602081018083529590955260ff909316928401929092526060830152608082015260a0016020604051602081039080840390855afa158015610685573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8116600090815260028c0160205291822054909350915081900361072b576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b600086826020811061073f5761073f611e22565b602002015173ffffffffffffffffffffffffffffffffffffffff16146107a9576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b818682602081106107bc576107bc611e22565b73ffffffffffffffffffffffffffffffffffffffff909216602092909202015250506001909201915061056d9050565b50506040805160608f901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602080830191909152603482018990527fffff0000000000000000000000000000000000000000000000000000000000008816605483015282516036818403018152605690920190925280519101206000945030935063233fd52d92509050338d8d8d602d90606d9261088e93929190611f1b565b8f8f606d9080926108a193929190611f1b565b6040518863ffffffff1660e01b81526004016108c39796959493929190611f81565b6020604051808303816000875af11580156108e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109069190611fe2565b9050817dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916838b73ffffffffffffffffffffffffffffffffffffffff167f3617b009e9785c42daebadb6d3fb553243a4bf586d07ea72d65d80013ce116b584604051610975911515815260200190565b60405180910390a450505050505050505050565b3360009081526003602052604081205460ff166109d2576040517fd79e123d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005a905061ea60811015610a16576040517f0bfecd63000000000000000000000000000000000000000000000000000000008152600481018a90526024016104b8565b6000898152600460209081526040918290208251608081018452905473ffffffffffffffffffffffffffffffffffffffff8116825274010000000000000000000000000000000000000000810460ff90811615159383019390935275010000000000000000000000000000000000000000008104909216151592810183905276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660608201529080610ace575080602001515b15610b08576040517fa53dc8ca000000000000000000000000000000000000000000000000000000008152600481018b90526024016104b8565b6000610b1661ea608461200b565b60008c8152600460205260409020805469ffffffffffffffffffff83167601000000000000000000000000000000000000000000000275ffff000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff8e16171790559050610bad897f805f2132000000000000000000000000000000000000000000000000000000006115b5565b610c0657505050600088815260046020526040812080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790559050610d00565b60008089898989604051602401610c20949392919061201e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f805f21320000000000000000000000000000000000000000000000000000000017815281519192506000918291828f88f191508115610cf95760008d815260046020526040902080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b5093505050505b979650505050505050565b6040805160c0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905284519088901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001681830152603481018790527fffff000000000000000000000000000000000000000000000000000000000000861660548201528451603681830301815260568201808752815191840191909120808552600490935285842060d68301909652945473ffffffffffffffffffffffffffffffffffffffff811680875274010000000000000000000000000000000000000000820460ff9081161515607685015275010000000000000000000000000000000000000000008304161515609684015276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660b69092019190915292939092909190610e6957506000610e91565b816020015115610e7b57506002610e91565b8160400151610e8b576003610e8e565b60015b90505b6040518060c00160405280848152602001826003811115610eb457610eb4611bf9565b8152602001836000015173ffffffffffffffffffffffffffffffffffffffff168152602001836020015115158152602001836040015115158152602001836060015169ffffffffffffffffffff1681525093505050509392505050565b610f196115da565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fb96d15bf9258c7b8df062753a6a262864611fc7b060a5ee2e57e79b85f898d389190a250565b610f956115da565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f0ea0ce2c048ff45a4a95f2947879de3fb94abec2f152190400cab2d1272a68e79190a250565b60015473ffffffffffffffffffffffffffffffffffffffff16331461108d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016104b8565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6111116115da565b8260ff1660000361114e576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f811115611193576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101829052601f60248201526044016104b8565b61119e836003612045565b60ff1681116111fc57806111b3846003612045565b6111be906001611ddf565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260ff1660248201526044016104b8565b67ffffffff00000000602086901b1663ffffffff85161760005b67ffffffffffffffff82166000908152600260205260409020600101548110156112ac5767ffffffffffffffff821660009081526002602081905260408220600181018054919092019291908490811061127257611272611e22565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812055600101611216565b5060005b828110156114285760008484838181106112cc576112cc611e22565b90506020020160208101906112e19190611cd0565b905073ffffffffffffffffffffffffffffffffffffffff8116611348576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b67ffffffffffffffff8316600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff861685529092019052902054156113d4576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b6113df826001612061565b67ffffffffffffffff8416600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff909616845294909101905291909120556001016112b0565b5067ffffffffffffffff811660009081526002602052604090206114509060010184846118a0565b5067ffffffffffffffff81166000908152600260205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff87161790555163ffffffff86811691908816907f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a455906114d690889088908890612074565b60405180910390a3505050505050565b6114ee6115da565b63ffffffff818116602084811b67ffffffff00000000168217600090815260028252604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558051828152928301905291928516917f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a4559160405161157a9291906120da565b60405180910390a35050565b61158e6115da565b6115978161165d565b50565b60218101516045820151608b90920151909260c09290921c91565b60006115c083611752565b80156115d157506115d183836117b6565b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104b8565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036116dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104b8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061177e827f01ffc9a7000000000000000000000000000000000000000000000000000000006117b6565b80156115d457506117af827fffffffff000000000000000000000000000000000000000000000000000000006117b6565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561186e575060208210155b8015610d00575015159695505050505050565b6040518061040001604052806020906020820280368337509192915050565b828054828255906000526020600020908101928215611918579160200282015b828111156119185781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8435161782556020909201916001909101906118c0565b50611924929150611928565b5090565b5b808211156119245760008155600101611929565b803573ffffffffffffffffffffffffffffffffffffffff8116811461196157600080fd5b919050565b60008083601f84011261197857600080fd5b50813567ffffffffffffffff81111561199057600080fd5b6020830191508360208285010111156119a857600080fd5b9250929050565b60008083601f8401126119c157600080fd5b50813567ffffffffffffffff8111156119d957600080fd5b6020830191508360208260051b85010111156119a857600080fd5b60008060008060008060006080888a031215611a0f57600080fd5b611a188861193d565b9650602088013567ffffffffffffffff80821115611a3557600080fd5b611a418b838c01611966565b909850965060408a0135915080821115611a5a57600080fd5b611a668b838c01611966565b909650945060608a0135915080821115611a7f57600080fd5b50611a8c8a828b016119af565b989b979a50959850939692959293505050565b60006020808352835180602085015260005b81811015611acd57858101830151858201604001528201611ab1565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600080600080600080600060a0888a031215611b2757600080fd5b87359650611b376020890161193d565b9550611b456040890161193d565b9450606088013567ffffffffffffffff80821115611b6257600080fd5b611b6e8b838c01611966565b909650945060808a0135915080821115611b8757600080fd5b50611a8c8a828b01611966565b600080600060608486031215611ba957600080fd5b611bb28461193d565b92506020840135915060408401357fffff00000000000000000000000000000000000000000000000000000000000081168114611bee57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81518152602082015160c082019060048110611c6d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8060208401525073ffffffffffffffffffffffffffffffffffffffff604084015116604083015260608301511515606083015260808301511515608083015260a0830151611cc960a084018269ffffffffffffffffffff169052565b5092915050565b600060208284031215611ce257600080fd5b6115d18261193d565b803563ffffffff8116811461196157600080fd5b600080600080600060808688031215611d1757600080fd5b611d2086611ceb565b9450611d2e60208701611ceb565b9350604086013560ff81168114611d4457600080fd5b9250606086013567ffffffffffffffff811115611d6057600080fd5b611d6c888289016119af565b969995985093965092949392505050565b60008060408385031215611d9057600080fd5b611d9983611ceb565b9150611da760208401611ceb565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff81811683821601908111156115d4576115d4611db0565b8183823760009101908152919050565b838152818360208301376000910160200190815292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611e8657600080fd5b83018035915067ffffffffffffffff821115611ea157600080fd5b6020019150368190038213156119a857600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000611f13602083018486611eb6565b949350505050565b60008085851115611f2b57600080fd5b83861115611f3857600080fd5b5050820193919092039150565b803560208310156115d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525060a06060830152611fc160a083018688611eb6565b8281036080840152611fd4818587611eb6565b9a9950505050505050505050565b600060208284031215611ff457600080fd5b8151801515811461200457600080fd5b9392505050565b818103818111156115d4576115d4611db0565b604081526000612032604083018688611eb6565b8281036020840152610d00818587611eb6565b60ff8181168382160290811690818114611cc957611cc9611db0565b808201808211156115d4576115d4611db0565b60ff8416815260406020808301829052908201839052600090849060608401835b868110156120ce5773ffffffffffffffffffffffffffffffffffffffff6120bb8561193d565b1682529282019290820190600101612095565b50979650505050505050565b60006040820160ff8516835260206040602085015281855180845260608601915060208701935060005b8181101561213657845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101612104565b509097965050505050505056fea164736f6c6343000818000a", } var KeystoneForwarderABI = KeystoneForwarderMetaData.ABI diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index dc179a7112..d8b3b03042 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,5 +1,5 @@ GETH_VERSION: 1.13.8 capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin cb3e79280a928979bc37de154b12b876996bdbe10f1827e683ee2bfa7a429a6c -feeds_consumer: ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin 8c3a2b18a80be41e7c40d2bc3a4c8d1b5e18d55c1fd20ad5af68cebb66109fc5 -forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin 45d9b866c64b41c1349a90b6764aee42a6d078b454d38f369b5fe02b23b9d16e +feeds_consumer: ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin 6ac5b12eff3b022a35c3c40d5ed0285bf9bfec0e3669a4b12307332a216048ca +forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin 0da2ce239c9d4521005428f2d42a67dbee2ae6dd7160fd9e4f4322fb51d4f6ba ocr3_capability: ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.bin 8bf0f53f222efce7143dea6134552eb26ea1eef845407b4475a0d79b7d7ba9f8 diff --git a/core/services/relay/evm/write_target.go b/core/services/relay/evm/write_target.go index 03b1130f8e..14e6d1bf34 100644 --- a/core/services/relay/evm/write_target.go +++ b/core/services/relay/evm/write_target.go @@ -8,7 +8,6 @@ import ( chainselectors "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-common/pkg/logger" - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/capabilities/targets" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" @@ -48,16 +47,6 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain return nil, err } - err = cr.Bind(ctx, []commontypes.BoundContract{ - { - Name: "forwarder", - Address: config.ForwarderAddress().String(), - }, - }) - if err != nil { - return nil, err - } - chainWriterConfig := relayevmtypes.ChainWriterConfig{ Contracts: map[string]*relayevmtypes.ContractConfig{ "forwarder": { @@ -65,7 +54,6 @@ func NewWriteTarget(ctx context.Context, relayer *Relayer, chain legacyevm.Chain Configs: map[string]*relayevmtypes.ChainWriterDefinition{ "report": { ChainSpecificName: "report", - Checker: "simulate", FromAddress: config.FromAddress().Address(), GasLimit: gasLimitDefault, }, diff --git a/core/services/relay/evm/write_target_test.go b/core/services/relay/evm/write_target_test.go index 3721eec62a..94b2367b6d 100644 --- a/core/services/relay/evm/write_target_test.go +++ b/core/services/relay/evm/write_target_test.go @@ -121,8 +121,6 @@ func TestEvmWrite(t *testing.T) { chain.On("Client").Return(evmClient) - poller.EXPECT().HasFilter(mock.Anything).Return(false) - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { a := testutils.NewAddress() addr, err2 := types.NewEIP55Address(a.Hex()) @@ -151,6 +149,7 @@ func TestEvmWrite(t *testing.T) { }) require.NoError(t, err) + reportID := [2]byte{0x00, 0x01} reportMetadata := targets.ReportV1Metadata{ Version: 1, WorkflowExecutionID: [32]byte{}, @@ -160,7 +159,7 @@ func TestEvmWrite(t *testing.T) { WorkflowCID: [32]byte{}, WorkflowName: [10]byte{}, WorkflowOwner: [20]byte{}, - ReportID: [2]byte{}, + ReportID: reportID, } reportMetadataBytes, err := reportMetadata.Encode() @@ -173,7 +172,7 @@ func TestEvmWrite(t *testing.T) { "report": reportMetadataBytes, "signatures": signatures, "context": []byte{4, 5}, - "id": []byte{9, 9}, + "id": reportID[:], }, }) require.NoError(t, err) From cd72f932624e59652b591953a965ecbce66d2e5d Mon Sep 17 00:00:00 2001 From: momentmaker Date: Wed, 11 Sep 2024 07:34:02 -0500 Subject: [PATCH 326/432] fix: golangci-lint-action working directory bug (#14387) --- .github/actions/golangci-lint/action.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/actions/golangci-lint/action.yml b/.github/actions/golangci-lint/action.yml index 86e15f80b2..a90a764ef2 100644 --- a/.github/actions/golangci-lint/action.yml +++ b/.github/actions/golangci-lint/action.yml @@ -10,8 +10,7 @@ inputs: required: true go-directory: description: Go directory to run commands from - # XXX: Don't use `.` here due to issues with the golangci-lint-action. - default: "" + default: "." # setup-go inputs only-modules: description: Set to 'true' to only cache modules @@ -54,13 +53,23 @@ runs: working-directory: ${{ inputs.go-directory }} shell: bash run: go build ./... + - name: Set golangci-lint working directory + shell: bash + id: set-working-directory + # XXX: Don't use `.` default working directory here due to issues with the golangci-lint-action. + run: | + if [ "${{ inputs.go-directory }}" == "." ]; then + echo "golangci-lint-working-directory=" | tee -a $GITHUB_OUTPUT + else + echo "golangci-lint-working-directory=${{ inputs.go-directory }}" | tee -a $GITHUB_OUTPUT + fi - name: golangci-lint uses: golangci/golangci-lint-action@38e1018663fa5173f3968ea0777460d3de38f256 # v5.3.0 with: version: v1.60.3 only-new-issues: true args: --out-format colored-line-number,checkstyle:golangci-lint-report.xml - working-directory: ${{ inputs.go-directory }} + working-directory: ${{ steps.set-working-directory.outputs.golangci-lint-working-directory }} - name: Print lint report artifact if: failure() shell: bash From 356c70cb8079b1052faa45d0c53fa1d8212db355 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 11 Sep 2024 09:30:04 -0400 Subject: [PATCH 327/432] Productionize LLO transmitter (#14355) This mostly copies over similar patterns and structure from the battle-tested mercury transmitter, with a few modifications to generalize it to LLO --- .changeset/strange-swans-yawn.md | 21 ++ core/cmd/forwarders_commands_test.go | 2 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- .../llo/mercurytransmitter/helpers_test.go | 47 ++++ core/services/llo/mercurytransmitter/orm.go | 196 +++++++++++++ .../llo/mercurytransmitter/orm_test.go | 89 ++++++ .../mercurytransmitter/persistence_manager.go | 143 ++++++++++ .../persistence_manager_test.go | 127 +++++++++ core/services/llo/mercurytransmitter/queue.go | 250 +++++++++++++++++ .../llo/mercurytransmitter/queue_test.go | 105 +++++++ .../services/llo/mercurytransmitter/server.go | 240 ++++++++++++++++ .../llo/mercurytransmitter/transmitter.go | 254 +++++++++++++++++ .../mercurytransmitter/transmitter_test.go | 258 ++++++++++++++++++ core/services/llo/transmitter.go | 87 +++--- core/services/llo/transmitter_test.go | 7 - .../ocr2/plugins/llo/config/config.go | 65 +++-- .../ocr2/plugins/llo/config/config_test.go | 62 +++-- .../ocr2/plugins/llo/integration_test.go | 5 +- core/services/relay/dummy/llo_provider.go | 10 +- core/services/relay/evm/evm.go | 27 +- core/services/relay/evm/llo_provider.go | 11 +- .../relay/evm/mercury/config_poller.go | 1 - .../0252_add_llo_transmit_requests.sql | 21 ++ go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 30 files changed, 1934 insertions(+), 118 deletions(-) create mode 100644 .changeset/strange-swans-yawn.md create mode 100644 core/services/llo/mercurytransmitter/helpers_test.go create mode 100644 core/services/llo/mercurytransmitter/orm.go create mode 100644 core/services/llo/mercurytransmitter/orm_test.go create mode 100644 core/services/llo/mercurytransmitter/persistence_manager.go create mode 100644 core/services/llo/mercurytransmitter/persistence_manager_test.go create mode 100644 core/services/llo/mercurytransmitter/queue.go create mode 100644 core/services/llo/mercurytransmitter/queue_test.go create mode 100644 core/services/llo/mercurytransmitter/server.go create mode 100644 core/services/llo/mercurytransmitter/transmitter.go create mode 100644 core/services/llo/mercurytransmitter/transmitter_test.go delete mode 100644 core/services/llo/transmitter_test.go create mode 100644 core/store/migrate/migrations/0252_add_llo_transmit_requests.sql diff --git a/.changeset/strange-swans-yawn.md b/.changeset/strange-swans-yawn.md new file mode 100644 index 0000000000..d18c743a8a --- /dev/null +++ b/.changeset/strange-swans-yawn.md @@ -0,0 +1,21 @@ +--- +"chainlink": patch +--- + +#changed + +Productionize transmitter for LLO + +Note that some minor changes to prometheus metrics will occur in the transition to LLO. Since feed IDs no longer apply, the metrics for transmissions change as follows: + +``` +"mercury_transmit_*" +[]string{"feedID", ...}, +``` + +Will change to: + +``` +"llo_mercury_transmit_*" +[]string{"donID", ...}, +``` diff --git a/core/cmd/forwarders_commands_test.go b/core/cmd/forwarders_commands_test.go index b5a96a73aa..dfd8272d8a 100644 --- a/core/cmd/forwarders_commands_test.go +++ b/core/cmd/forwarders_commands_test.go @@ -22,7 +22,7 @@ func TestEVMForwarderPresenter_RenderTable(t *testing.T) { t.Parallel() var ( - id = "1" + id = "ID:" address = utils.RandomAddress() evmChainID = big.NewI(4) createdAt = time.Now() diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 21687a7cc4..f4f2e3a32f 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -273,7 +273,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index a65014a9d1..cac4c2cb3d 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1085,8 +1085,8 @@ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de732 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 h1:xow5cYrWxRmzTwhz2AjWOlnI9WRF4O5b84bXm1k292E= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227/go.mod h1:DUFantPYoBGwBSkNVt2k4ZJi0jPKRRrZVVlAzcZwreA= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd h1:+RFI4mgXSGEcn847e7bavhQCqaBiW142g1XfGzijFoY= diff --git a/core/services/llo/mercurytransmitter/helpers_test.go b/core/services/llo/mercurytransmitter/helpers_test.go new file mode 100644 index 0000000000..060c07bef4 --- /dev/null +++ b/core/services/llo/mercurytransmitter/helpers_test.go @@ -0,0 +1,47 @@ +package mercurytransmitter + +import ( + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" +) + +func makeSampleReport() ocr3types.ReportWithInfo[llotypes.ReportInfo] { + return ocr3types.ReportWithInfo[llotypes.ReportInfo]{ + Report: ocrtypes.Report{1, 2, 3}, + Info: llotypes.ReportInfo{ + LifeCycleStage: llotypes.LifeCycleStage("production"), + ReportFormat: llotypes.ReportFormatEVMPremiumLegacy, + }, + } +} + +func makeSampleConfigDigest() ocrtypes.ConfigDigest { + return ocrtypes.ConfigDigest{1, 2, 3, 4, 5, 6} +} +func makeSampleTransmission(seqNr uint64) *Transmission { + // valid with seqnr of 3 + return &Transmission{ + ServerURL: "wss://example.com/mercury", + ConfigDigest: types.ConfigDigest{0x0, 0x9, 0x57, 0xdd, 0x2f, 0x63, 0x56, 0x69, 0x34, 0xfd, 0xc2, 0xe1, 0xcd, 0xc1, 0xe, 0x3e, 0x25, 0xb9, 0x26, 0x5a, 0x16, 0x23, 0x91, 0xa6, 0x53, 0x16, 0x66, 0x59, 0x51, 0x0, 0x28, 0x7c}, + SeqNr: seqNr, + Report: ocr3types.ReportWithInfo[llotypes.ReportInfo]{ + Report: ocrtypes.Report{0x0, 0x3, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xde, 0xf5, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xde, 0xf5, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x8e, 0x95, 0xcf, 0xb5, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xd0, 0x1c, 0x67, 0xa9, 0xcf, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xdf, 0x3, 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x1c, 0x93, 0x6d, 0xa4, 0xf2, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x14, 0x8d, 0x9a, 0xc1, 0xd9, 0x6f, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x40, 0x5c, 0xcf, 0xa1, 0xbc, 0x63, 0xc0, 0x0}, + Info: llotypes.ReportInfo{ + LifeCycleStage: llotypes.LifeCycleStage("production"), + ReportFormat: llotypes.ReportFormatEVMPremiumLegacy, + }, + }, + Sigs: []types.AttributedOnchainSignature{types.AttributedOnchainSignature{Signature: []uint8{0x9d, 0xab, 0x8f, 0xa7, 0xca, 0x7, 0x62, 0x57, 0xf7, 0x11, 0x2c, 0xb7, 0xf3, 0x49, 0x37, 0x12, 0xbd, 0xe, 0x14, 0x27, 0xfc, 0x32, 0x5c, 0xec, 0xa6, 0xb9, 0x7f, 0xf9, 0xd7, 0x7b, 0xa6, 0x36, 0x30, 0x9d, 0x84, 0x29, 0xbf, 0xd4, 0xeb, 0xc5, 0xc9, 0x29, 0xef, 0xdd, 0xd3, 0x2f, 0xa6, 0x25, 0x63, 0xda, 0xd9, 0x2c, 0xa1, 0x4a, 0xba, 0x75, 0xb2, 0x85, 0x25, 0x8f, 0x2b, 0x84, 0xcd, 0x99, 0x1}, Signer: 0x1}, types.AttributedOnchainSignature{Signature: []uint8{0x9a, 0x47, 0x4a, 0x3, 0x1a, 0x95, 0xcf, 0x46, 0x10, 0xaf, 0xcc, 0x90, 0x49, 0xb2, 0xce, 0xbf, 0x63, 0xaa, 0xc7, 0x25, 0x4d, 0x2a, 0x8, 0x36, 0xda, 0xd5, 0x9f, 0x9d, 0x63, 0x69, 0x22, 0xb3, 0x36, 0xd9, 0x6e, 0xf, 0xae, 0x7b, 0xd1, 0x61, 0x59, 0xf, 0x36, 0x4a, 0x22, 0xec, 0xde, 0x45, 0x32, 0xe0, 0x5b, 0x5c, 0xe3, 0x14, 0x29, 0x4, 0x60, 0x7b, 0xce, 0xa3, 0x89, 0x6b, 0xbb, 0xe0, 0x0}, Signer: 0x3}}, + } +} + +func makeSampleTransmissions() []*Transmission { + return []*Transmission{ + makeSampleTransmission(1001), + makeSampleTransmission(1002), + makeSampleTransmission(1003), + } +} diff --git a/core/services/llo/mercurytransmitter/orm.go b/core/services/llo/mercurytransmitter/orm.go new file mode 100644 index 0000000000..d73722c82a --- /dev/null +++ b/core/services/llo/mercurytransmitter/orm.go @@ -0,0 +1,196 @@ +package mercurytransmitter + +import ( + "context" + "errors" + "fmt" + "math" + + "github.com/lib/pq" + + "github.com/smartcontractkit/libocr/commontypes" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" +) + +// ORM is scoped to a single DON ID +type ORM interface { + DonID() uint32 + Insert(ctx context.Context, transmissions []*Transmission) error + Delete(ctx context.Context, hashes [][32]byte) error + Get(ctx context.Context, serverURL string) ([]*Transmission, error) + Prune(ctx context.Context, serverURL string, maxSize int) error +} + +type orm struct { + ds sqlutil.DataSource + donID uint32 +} + +func NewORM(ds sqlutil.DataSource, donID uint32) ORM { + return &orm{ds: ds, donID: donID} +} + +func (o *orm) DonID() uint32 { + return o.donID +} + +// Insert inserts the transmissions, ignoring duplicates +func (o *orm) Insert(ctx context.Context, transmissions []*Transmission) error { + if len(transmissions) == 0 { + return nil + } + + type transmission struct { + DonID uint32 `db:"don_id"` + ServerURL string `db:"server_url"` + ConfigDigest ocrtypes.ConfigDigest `db:"config_digest"` + SeqNr int64 `db:"seq_nr"` + Report []byte `db:"report"` + LifecycleStage string `db:"lifecycle_stage"` + ReportFormat uint32 `db:"report_format"` + Signatures [][]byte `db:"signatures"` + Signers []uint8 `db:"signers"` + TransmissionHash []byte `db:"transmission_hash"` + } + records := make([]transmission, len(transmissions)) + for i, t := range transmissions { + signatures := make([][]byte, len(t.Sigs)) + signers := make([]uint8, len(t.Sigs)) + for j, sig := range t.Sigs { + signatures[j] = sig.Signature + signers[j] = uint8(sig.Signer) + } + h := t.Hash() + if t.SeqNr > math.MaxInt64 { + // this is to appease the linter but shouldn't ever happen + return fmt.Errorf("seqNr is too large (got: %d, max: %d)", t.SeqNr, math.MaxInt64) + } + records[i] = transmission{ + DonID: o.donID, + ServerURL: t.ServerURL, + ConfigDigest: t.ConfigDigest, + SeqNr: int64(t.SeqNr), //nolint + Report: t.Report.Report, + LifecycleStage: string(t.Report.Info.LifeCycleStage), + ReportFormat: uint32(t.Report.Info.ReportFormat), + Signatures: signatures, + Signers: signers, + TransmissionHash: h[:], + } + } + + _, err := o.ds.NamedExecContext(ctx, ` + INSERT INTO llo_mercury_transmit_queue (don_id, server_url, config_digest, seq_nr, report, lifecycle_stage, report_format, signatures, signers, transmission_hash) + VALUES (:don_id, :server_url, :config_digest, :seq_nr, :report, :lifecycle_stage, :report_format, :signatures, :signers, :transmission_hash) + ON CONFLICT (transmission_hash) DO NOTHING + `, records) + + if err != nil { + return fmt.Errorf("llo orm: failed to insert transmissions: %w", err) + } + return nil +} + +// Delete deletes the given transmissions +func (o *orm) Delete(ctx context.Context, hashes [][32]byte) error { + if len(hashes) == 0 { + return nil + } + + var pqHashes pq.ByteaArray + for _, hash := range hashes { + pqHashes = append(pqHashes, hash[:]) + } + + _, err := o.ds.ExecContext(ctx, ` + DELETE FROM llo_mercury_transmit_queue + WHERE transmission_hash = ANY($1) + `, pqHashes) + if err != nil { + return fmt.Errorf("llo orm: failed to delete transmissions: %w", err) + } + return nil +} + +// Get returns all transmissions in chronologically descending order +func (o *orm) Get(ctx context.Context, serverURL string) ([]*Transmission, error) { + // The priority queue uses seqnr to sort transmissions so order by + // the same fields here for optimal insertion into the pq. + rows, err := o.ds.QueryContext(ctx, ` + SELECT config_digest, seq_nr, report, lifecycle_stage, report_format, signatures, signers + FROM llo_mercury_transmit_queue + WHERE don_id = $1 AND server_url = $2 + ORDER BY seq_nr DESC, transmission_hash DESC + `, o.donID, serverURL) + if err != nil { + return nil, fmt.Errorf("llo orm: failed to get transmissions: %w", err) + } + defer rows.Close() + + var transmissions []*Transmission + for rows.Next() { + transmission := Transmission{ + ServerURL: serverURL, + } + var digest []byte + var signatures pq.ByteaArray + var signers pq.Int32Array + + err := rows.Scan( + &digest, + &transmission.SeqNr, + &transmission.Report.Report, + &transmission.Report.Info.LifeCycleStage, + &transmission.Report.Info.ReportFormat, + &signatures, + &signers, + ) + if err != nil { + return nil, fmt.Errorf("llo orm: failed to scan transmission: %w", err) + } + transmission.ConfigDigest = ocrtypes.ConfigDigest(digest) + if len(signatures) != len(signers) { + return nil, errors.New("signatures and signers must have the same length") + } + for i, sig := range signatures { + if signers[i] > math.MaxUint8 { + // this is to appease the linter but shouldn't ever happen + return nil, fmt.Errorf("signer is too large (got: %d, max: %d)", signers[i], math.MaxUint8) + } + transmission.Sigs = append(transmission.Sigs, ocrtypes.AttributedOnchainSignature{ + Signature: sig, + Signer: commontypes.OracleID(signers[i]), //nolint + }) + } + + transmissions = append(transmissions, &transmission) + } + if err := rows.Err(); err != nil { + return nil, fmt.Errorf("llo orm: failed to scan transmissions: %w", err) + } + + return transmissions, nil +} + +// Prune keeps at most maxSize rows for the given job ID, +// deleting the oldest transactions. +func (o *orm) Prune(ctx context.Context, serverURL string, maxSize int) error { + // Prune the oldest requests by epoch and round. + _, err := o.ds.ExecContext(ctx, ` + DELETE FROM llo_mercury_transmit_queue + WHERE don_id = $1 AND server_url = $2 AND + transmission_hash NOT IN ( + SELECT transmission_hash + FROM llo_mercury_transmit_queue + WHERE don_id = $1 AND server_url = $2 + ORDER BY seq_nr DESC, transmission_hash DESC + LIMIT $3 + ) + `, o.donID, serverURL, maxSize) + if err != nil { + return fmt.Errorf("llo orm: failed to prune transmissions: %w", err) + } + return nil +} diff --git a/core/services/llo/mercurytransmitter/orm_test.go b/core/services/llo/mercurytransmitter/orm_test.go new file mode 100644 index 0000000000..73d5760a9a --- /dev/null +++ b/core/services/llo/mercurytransmitter/orm_test.go @@ -0,0 +1,89 @@ +package mercurytransmitter + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" +) + +var ( + sURL = "wss://example.com/mercury" + sURL2 = "wss://mercuryserver.test" + sURL3 = "wss://mercuryserver.example/foo" +) + +func TestORM(t *testing.T) { + ctx := testutils.Context(t) + db := pgtest.NewSqlxDB(t) + + donID := uint32(654321) + orm := NewORM(db, donID) + + t.Run("DonID", func(t *testing.T) { + assert.Equal(t, donID, orm.DonID()) + }) + + transmissions := makeSampleTransmissions()[:2] + + t.Run("Insert", func(t *testing.T) { + err := orm.Insert(ctx, transmissions) + require.NoError(t, err) + }) + t.Run("Get", func(t *testing.T) { + result, err := orm.Get(ctx, sURL) + require.NoError(t, err) + + assert.ElementsMatch(t, transmissions, result) + + result, err = orm.Get(ctx, "other server url") + require.NoError(t, err) + + assert.Empty(t, result) + }) + t.Run("Delete", func(t *testing.T) { + err := orm.Delete(ctx, [][32]byte{transmissions[0].Hash()}) + require.NoError(t, err) + + result, err := orm.Get(ctx, sURL) + require.NoError(t, err) + + require.Len(t, result, 1) + assert.Equal(t, transmissions[1], result[0]) + + err = orm.Delete(ctx, [][32]byte{transmissions[1].Hash()}) + require.NoError(t, err) + + result, err = orm.Get(ctx, sURL) + require.NoError(t, err) + require.Len(t, result, 0) + }) + t.Run("Prune", func(t *testing.T) { + err := orm.Insert(ctx, transmissions) + require.NoError(t, err) + + err = orm.Prune(ctx, sURL, 1) + require.NoError(t, err) + + result, err := orm.Get(ctx, sURL) + require.NoError(t, err) + require.Len(t, result, 1) + assert.Equal(t, transmissions[1], result[0]) + + err = orm.Prune(ctx, sURL, 1) + require.NoError(t, err) + result, err = orm.Get(ctx, sURL) + require.NoError(t, err) + require.Len(t, result, 1) + assert.Equal(t, transmissions[1], result[0]) + + err = orm.Prune(ctx, sURL, 0) + require.NoError(t, err) + result, err = orm.Get(ctx, sURL) + require.NoError(t, err) + require.Len(t, result, 0) + }) +} diff --git a/core/services/llo/mercurytransmitter/persistence_manager.go b/core/services/llo/mercurytransmitter/persistence_manager.go new file mode 100644 index 0000000000..eb36a7d1b8 --- /dev/null +++ b/core/services/llo/mercurytransmitter/persistence_manager.go @@ -0,0 +1,143 @@ +package mercurytransmitter + +import ( + "context" + "sync" + "time" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" +) + +var ( + flushDeletesFrequency = time.Second + pruneFrequency = time.Hour +) + +// persistenceManager scopes an ORM to a single serverURL and handles cleanup +// and asynchronous deletion +type persistenceManager struct { + lggr logger.Logger + orm ORM + serverURL string + + once services.StateMachine + stopCh services.StopChan + wg sync.WaitGroup + + deleteMu sync.Mutex + deleteQueue [][32]byte + + maxTransmitQueueSize int + flushDeletesFrequency time.Duration + pruneFrequency time.Duration +} + +func NewPersistenceManager(lggr logger.Logger, orm ORM, serverURL string, maxTransmitQueueSize int, flushDeletesFrequency, pruneFrequency time.Duration) *persistenceManager { + return &persistenceManager{ + orm: orm, + lggr: logger.Sugared(lggr).Named("LLOPersistenceManager").With("serverURL", serverURL), + serverURL: serverURL, + stopCh: make(services.StopChan), + maxTransmitQueueSize: maxTransmitQueueSize, + flushDeletesFrequency: flushDeletesFrequency, + pruneFrequency: pruneFrequency, + } +} + +func (pm *persistenceManager) Start(ctx context.Context) error { + return pm.once.StartOnce("LLOMercuryPersistenceManager", func() error { + pm.wg.Add(2) + go pm.runFlushDeletesLoop() + go pm.runPruneLoop() + return nil + }) +} + +func (pm *persistenceManager) Close() error { + return pm.once.StopOnce("LLOMercuryPersistenceManager", func() error { + close(pm.stopCh) + pm.wg.Wait() + return nil + }) +} + +func (pm *persistenceManager) DonID() uint32 { + return pm.orm.DonID() +} + +func (pm *persistenceManager) AsyncDelete(hash [32]byte) { + pm.addToDeleteQueue(hash) +} + +func (pm *persistenceManager) Load(ctx context.Context) ([]*Transmission, error) { + return pm.orm.Get(ctx, pm.serverURL) +} + +func (pm *persistenceManager) runFlushDeletesLoop() { + defer pm.wg.Done() + + ctx, cancel := pm.stopCh.Ctx(context.Background()) + defer cancel() + + ticker := services.NewTicker(pm.flushDeletesFrequency) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + queuedTransmissionHashes := pm.resetDeleteQueue() + if len(queuedTransmissionHashes) == 0 { + continue + } + if err := pm.orm.Delete(ctx, queuedTransmissionHashes); err != nil { + pm.lggr.Errorw("Failed to delete queued transmit requests", "err", err) + pm.addToDeleteQueue(queuedTransmissionHashes...) + } else { + pm.lggr.Debugw("Deleted queued transmit requests") + } + } + } +} + +func (pm *persistenceManager) runPruneLoop() { + defer pm.wg.Done() + + ctx, cancel := pm.stopCh.NewCtx() + defer cancel() + + ticker := services.NewTicker(pm.pruneFrequency) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + func(ctx context.Context) { + ctx, cancelPrune := context.WithTimeout(sqlutil.WithoutDefaultTimeout(ctx), time.Minute) + defer cancelPrune() + if err := pm.orm.Prune(ctx, pm.serverURL, pm.maxTransmitQueueSize); err != nil { + pm.lggr.Errorw("Failed to prune transmit requests table", "err", err) + } else { + pm.lggr.Debugw("Pruned transmit requests table") + } + }(ctx) + } + } +} + +func (pm *persistenceManager) addToDeleteQueue(hashes ...[32]byte) { + pm.deleteMu.Lock() + defer pm.deleteMu.Unlock() + pm.deleteQueue = append(pm.deleteQueue, hashes...) +} + +func (pm *persistenceManager) resetDeleteQueue() [][32]byte { + pm.deleteMu.Lock() + defer pm.deleteMu.Unlock() + queue := pm.deleteQueue + pm.deleteQueue = nil + return queue +} diff --git a/core/services/llo/mercurytransmitter/persistence_manager_test.go b/core/services/llo/mercurytransmitter/persistence_manager_test.go new file mode 100644 index 0000000000..b05de429ad --- /dev/null +++ b/core/services/llo/mercurytransmitter/persistence_manager_test.go @@ -0,0 +1,127 @@ +package mercurytransmitter + +import ( + "testing" + "time" + + "github.com/jmoiron/sqlx" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" + + "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func bootstrapPersistenceManager(t *testing.T, donID uint32, db *sqlx.DB) (*persistenceManager, *observer.ObservedLogs) { + t.Helper() + lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.DebugLevel) + orm := NewORM(db, donID) + return NewPersistenceManager(lggr, orm, "wss://example.com/mercury", 2, 5*time.Millisecond, 5*time.Millisecond), observedLogs +} + +func TestPersistenceManager(t *testing.T) { + donID1 := uint32(1234) + donID2 := uint32(2345) + + ctx := testutils.Context(t) + db := pgtest.NewSqlxDB(t) + pm, _ := bootstrapPersistenceManager(t, donID1, db) + + transmissions := makeSampleTransmissions() + err := pm.orm.Insert(ctx, transmissions) + require.NoError(t, err) + + result, err := pm.Load(ctx) + require.NoError(t, err) + assert.ElementsMatch(t, transmissions, result) + + err = pm.orm.Delete(ctx, [][32]byte{transmissions[0].Hash()}) + require.NoError(t, err) + + t.Run("scopes load to only transmissions with matching don ID", func(t *testing.T) { + pm2, _ := bootstrapPersistenceManager(t, donID2, db) + result, err = pm2.Load(ctx) + require.NoError(t, err) + + assert.Len(t, result, 0) + }) +} + +func TestPersistenceManagerAsyncDelete(t *testing.T) { + ctx := testutils.Context(t) + donID := uint32(1234) + db := pgtest.NewSqlxDB(t) + pm, observedLogs := bootstrapPersistenceManager(t, donID, db) + + transmissions := makeSampleTransmissions() + err := pm.orm.Insert(ctx, transmissions) + require.NoError(t, err) + + servicetest.Run(t, pm) + + pm.AsyncDelete(transmissions[0].Hash()) + + // Wait for next poll. + observedLogs.TakeAll() + testutils.WaitForLogMessage(t, observedLogs, "Deleted queued transmit requests") + + result, err := pm.Load(ctx) + require.NoError(t, err) + require.Len(t, result, 2) + assert.ElementsMatch(t, transmissions[1:], result) +} + +func TestPersistenceManagerPrune(t *testing.T) { + donID1 := uint32(123456) + donID2 := uint32(654321) + db := pgtest.NewSqlxDB(t) + + ctx := testutils.Context(t) + + transmissions := make([]*Transmission, 45) + for i := uint64(0); i < 45; i++ { + transmissions[i] = makeSampleTransmission(i) + } + + pm, _ := bootstrapPersistenceManager(t, donID1, db) + err := pm.orm.Insert(ctx, transmissions[:25]) + require.NoError(t, err) + + pm2, _ := bootstrapPersistenceManager(t, donID2, db) + err = pm2.orm.Insert(ctx, transmissions[25:]) + require.NoError(t, err) + + pm, observedLogs := bootstrapPersistenceManager(t, donID1, db) + + err = pm.Start(ctx) + require.NoError(t, err) + + // Wait for next poll. + observedLogs.TakeAll() + testutils.WaitForLogMessage(t, observedLogs, "Pruned transmit requests table") + + result, err := pm.Load(ctx) + require.NoError(t, err) + require.ElementsMatch(t, transmissions[23:25], result) + + // Test pruning stops after Close. + err = pm.Close() + require.NoError(t, err) + + err = pm.orm.Insert(ctx, transmissions) + require.NoError(t, err) + + result, err = pm.Load(ctx) + require.NoError(t, err) + require.Len(t, result, 25) + + t.Run("prune was scoped to don ID", func(t *testing.T) { + result, err = pm2.Load(ctx) + require.NoError(t, err) + assert.Len(t, result, 20) + }) +} diff --git a/core/services/llo/mercurytransmitter/queue.go b/core/services/llo/mercurytransmitter/queue.go new file mode 100644 index 0000000000..a5a606c5b3 --- /dev/null +++ b/core/services/llo/mercurytransmitter/queue.go @@ -0,0 +1,250 @@ +package mercurytransmitter + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + heap "github.com/esote/minmaxheap" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" +) + +type asyncDeleter interface { + AsyncDelete(hash [32]byte) + DonID() uint32 +} + +var _ services.Service = (*transmitQueue)(nil) + +var transmitQueueLoad = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "llo_transmit_queue_load", + Help: "Current count of items in the transmit queue", +}, + []string{"donID", "serverURL", "capacity"}, +) + +// Prometheus' default interval is 15s, set this to under 7.5s to avoid +// aliasing (see: https://en.wikipedia.org/wiki/Nyquist_frequency) +const promInterval = 6500 * time.Millisecond + +// TransmitQueue is the high-level package that everything outside of this file should be using +// It stores pending transmissions, yielding the latest (highest priority) first to the caller +type transmitQueue struct { + services.StateMachine + + cond sync.Cond + lggr logger.SugaredLogger + asyncDeleter asyncDeleter + mu *sync.RWMutex + + pq *priorityQueue + maxlen int + closed bool + + // monitor loop + stopMonitor func() + transmitQueueLoad prometheus.Gauge +} + +type TransmitQueue interface { + services.Service + + BlockingPop() (t *Transmission) + Push(t *Transmission) (ok bool) + Init(ts []*Transmission) + IsEmpty() bool +} + +// maxlen controls how many items will be stored in the queue +// 0 means unlimited - be careful, this can cause memory leaks +func NewTransmitQueue(lggr logger.Logger, serverURL string, maxlen int, asyncDeleter asyncDeleter) TransmitQueue { + mu := new(sync.RWMutex) + return &transmitQueue{ + services.StateMachine{}, + sync.Cond{L: mu}, + logger.Sugared(lggr).Named("TransmitQueue"), + asyncDeleter, + mu, + nil, // pq needs to be initialized by calling tq.Init before use + maxlen, + false, + nil, + transmitQueueLoad.WithLabelValues(fmt.Sprintf("%d", asyncDeleter.DonID()), serverURL, fmt.Sprintf("%d", maxlen)), + } +} + +func (tq *transmitQueue) Init(ts []*Transmission) { + pq := priorityQueue(ts) + heap.Init(&pq) // ensure the heap is ordered + tq.pq = &pq +} + +func (tq *transmitQueue) Push(t *Transmission) (ok bool) { + tq.cond.L.Lock() + defer tq.cond.L.Unlock() + + if tq.closed { + return false + } + + if tq.maxlen != 0 && tq.pq.Len() == tq.maxlen { + // evict oldest entry to make room + tq.lggr.Criticalf("Transmit queue is full; dropping oldest transmission (reached max length of %d)", tq.maxlen) + removed := heap.PopMax(tq.pq) + if removed, ok := removed.(*Transmission); ok { + tq.asyncDeleter.AsyncDelete(removed.Hash()) + } + } + + heap.Push(tq.pq, t) + tq.cond.Signal() + + return true +} + +// BlockingPop will block until at least one item is in the heap, and then return it +// If the queue is closed, it will immediately return nil +func (tq *transmitQueue) BlockingPop() (t *Transmission) { + tq.cond.L.Lock() + defer tq.cond.L.Unlock() + if tq.closed { + return nil + } + for t = tq.pop(); t == nil; t = tq.pop() { + tq.cond.Wait() + if tq.closed { + return nil + } + } + return t +} + +func (tq *transmitQueue) IsEmpty() bool { + tq.mu.RLock() + defer tq.mu.RUnlock() + return tq.pq.Len() == 0 +} + +func (tq *transmitQueue) Start(context.Context) error { + return tq.StartOnce("TransmitQueue", func() error { + t := services.NewTicker(promInterval) + wg := new(sync.WaitGroup) + chStop := make(chan struct{}) + tq.stopMonitor = func() { + t.Stop() + close(chStop) + wg.Wait() + } + wg.Add(1) + go tq.monitorLoop(t.C, chStop, wg) + return nil + }) +} + +func (tq *transmitQueue) Close() error { + return tq.StopOnce("TransmitQueue", func() error { + tq.cond.L.Lock() + tq.closed = true + tq.cond.L.Unlock() + tq.cond.Broadcast() + tq.stopMonitor() + return nil + }) +} + +func (tq *transmitQueue) monitorLoop(c <-chan time.Time, chStop <-chan struct{}, wg *sync.WaitGroup) { + defer wg.Done() + + for { + select { + case <-c: + tq.report() + case <-chStop: + return + } + } +} + +func (tq *transmitQueue) report() { + tq.mu.RLock() + length := tq.pq.Len() + tq.mu.RUnlock() + tq.transmitQueueLoad.Set(float64(length)) +} + +func (tq *transmitQueue) Ready() error { + return nil +} +func (tq *transmitQueue) Name() string { return tq.lggr.Name() } +func (tq *transmitQueue) HealthReport() map[string]error { + report := map[string]error{tq.Name(): errors.Join( + tq.status(), + )} + return report +} + +func (tq *transmitQueue) status() (merr error) { + tq.mu.RLock() + length := tq.pq.Len() + closed := tq.closed + tq.mu.RUnlock() + if tq.maxlen != 0 && length > (tq.maxlen/2) { + merr = errors.Join(merr, fmt.Errorf("transmit priority queue is greater than 50%% full (%d/%d)", length, tq.maxlen)) + } + if closed { + merr = errors.New("transmit queue is closed") + } + return merr +} + +// pop latest Transmission from the heap +// Not thread-safe +func (tq *transmitQueue) pop() *Transmission { + if tq.pq.Len() == 0 { + return nil + } + return heap.Pop(tq.pq).(*Transmission) +} + +// HEAP +// Adapted from https://pkg.go.dev/container/heap#example-package-PriorityQueue + +// WARNING: None of these methods are thread-safe, caller must synchronize + +var _ heap.Interface = &priorityQueue{} + +type priorityQueue []*Transmission + +func (pq priorityQueue) Len() int { return len(pq) } + +func (pq priorityQueue) Less(i, j int) bool { + // We want Pop to give us the latest round, so we use greater than here + // i.e. a later seqNr is "less" than an earlier one + return pq[i].SeqNr > pq[j].SeqNr +} + +func (pq priorityQueue) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] +} + +func (pq *priorityQueue) Pop() any { + n := len(*pq) + if n == 0 { + return nil + } + old := *pq + item := old[n-1] + old[n-1] = nil // avoid memory leak + *pq = old[0 : n-1] + return item +} + +func (pq *priorityQueue) Push(x any) { + *pq = append(*pq, x.(*Transmission)) +} diff --git a/core/services/llo/mercurytransmitter/queue_test.go b/core/services/llo/mercurytransmitter/queue_test.go new file mode 100644 index 0000000000..d19d140d6b --- /dev/null +++ b/core/services/llo/mercurytransmitter/queue_test.go @@ -0,0 +1,105 @@ +package mercurytransmitter + +import ( + "sync" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +var _ asyncDeleter = &mockAsyncDeleter{} + +type mockAsyncDeleter struct { + donID uint32 + hashes [][32]byte +} + +func (m *mockAsyncDeleter) AsyncDelete(hash [32]byte) { + m.hashes = append(m.hashes, hash) +} +func (m *mockAsyncDeleter) DonID() uint32 { + return m.donID +} + +func Test_Queue(t *testing.T) { + t.Parallel() + lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.ErrorLevel) + testTransmissions := makeSampleTransmissions() + deleter := &mockAsyncDeleter{} + transmitQueue := NewTransmitQueue(lggr, sURL, 7, deleter) + transmitQueue.Init([]*Transmission{}) + + t.Run("successfully add transmissions to transmit queue", func(t *testing.T) { + for _, tt := range testTransmissions { + ok := transmitQueue.Push(tt) + require.True(t, ok) + } + report := transmitQueue.HealthReport() + assert.Nil(t, report[transmitQueue.Name()]) + }) + + t.Run("transmit queue is more than 50% full", func(t *testing.T) { + transmitQueue.Push(testTransmissions[2]) + report := transmitQueue.HealthReport() + assert.Equal(t, report[transmitQueue.Name()].Error(), "transmit priority queue is greater than 50% full (4/7)") + }) + + t.Run("transmit queue pops the highest priority transmission", func(t *testing.T) { + tr := transmitQueue.BlockingPop() + assert.Equal(t, testTransmissions[2], tr) + }) + + t.Run("transmit queue is full and evicts the oldest transmission", func(t *testing.T) { + // add 5 more transmissions to overflow the queue by 1 + for i := 0; i < 5; i++ { + transmitQueue.Push(testTransmissions[1]) + } + + // expecting testTransmissions[0] to get evicted and not present in the queue anymore + testutils.WaitForLogMessage(t, observedLogs, "Transmit queue is full; dropping oldest transmission (reached max length of 7)") + var transmissions []*Transmission + for i := 0; i < 7; i++ { + tr := transmitQueue.BlockingPop() + transmissions = append(transmissions, tr) + } + + assert.NotContains(t, transmissions, testTransmissions[0]) + require.Len(t, deleter.hashes, 1) + assert.Equal(t, testTransmissions[0].Hash(), deleter.hashes[0]) + }) + + t.Run("transmit queue blocks when empty and resumes when tranmission available", func(t *testing.T) { + assert.True(t, transmitQueue.IsEmpty()) + + var wg sync.WaitGroup + wg.Add(2) + go func() { + defer wg.Done() + tr := transmitQueue.BlockingPop() + assert.Equal(t, tr, testTransmissions[0]) + }() + go func() { + defer wg.Done() + transmitQueue.Push(testTransmissions[0]) + }() + wg.Wait() + }) + + t.Run("initializes transmissions", func(t *testing.T) { + expected := makeSampleTransmission(1) + transmissions := []*Transmission{ + expected, + } + transmitQueue := NewTransmitQueue(lggr, sURL, 7, deleter) + transmitQueue.Init(transmissions) + + transmission := transmitQueue.BlockingPop() + assert.Equal(t, expected, transmission) + assert.True(t, transmitQueue.IsEmpty()) + }) +} diff --git a/core/services/llo/mercurytransmitter/server.go b/core/services/llo/mercurytransmitter/server.go new file mode 100644 index 0000000000..d025e65efa --- /dev/null +++ b/core/services/llo/mercurytransmitter/server.go @@ -0,0 +1,240 @@ +package mercurytransmitter + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/jpillora/backoff" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +var ( + transmitQueueDeleteErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "llo_mercury_transmit_queue_delete_error_count", + Help: "Running count of DB errors when trying to delete an item from the queue DB", + }, + []string{"donID", "serverURL"}, + ) + transmitQueueInsertErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "llo_mercury_transmit_queue_insert_error_count", + Help: "Running count of DB errors when trying to insert an item into the queue DB", + }, + []string{"donID", "serverURL"}, + ) + transmitQueuePushErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "llo_mercury_transmit_queue_push_error_count", + Help: "Running count of DB errors when trying to push an item onto the queue", + }, + []string{"donID", "serverURL"}, + ) + transmitServerErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "llo_mercury_transmit_server_error_count", + Help: "Number of errored transmissions that failed due to an error returned by the mercury server", + }, + []string{"donID", "serverURL", "code"}, + ) +) + +// A server handles the queue for a given mercury server + +type server struct { + lggr logger.SugaredLogger + + transmitTimeout time.Duration + + c wsrpc.Client + pm *persistenceManager + q TransmitQueue + + deleteQueue chan [32]byte + + url string + + transmitSuccessCount prometheus.Counter + transmitDuplicateCount prometheus.Counter + transmitConnectionErrorCount prometheus.Counter + transmitQueueDeleteErrorCount prometheus.Counter + transmitQueueInsertErrorCount prometheus.Counter + transmitQueuePushErrorCount prometheus.Counter +} + +type QueueConfig interface { + TransmitQueueMaxSize() uint32 + TransmitTimeout() commonconfig.Duration +} + +func newServer(lggr logger.Logger, cfg QueueConfig, client wsrpc.Client, orm ORM, serverURL string) *server { + pm := NewPersistenceManager(lggr, orm, serverURL, int(cfg.TransmitQueueMaxSize()), flushDeletesFrequency, pruneFrequency) + donIDStr := fmt.Sprintf("%d", pm.DonID()) + return &server{ + logger.Sugared(lggr), + cfg.TransmitTimeout().Duration(), + client, + pm, + NewTransmitQueue(lggr, serverURL, int(cfg.TransmitQueueMaxSize()), pm), + make(chan [32]byte, int(cfg.TransmitQueueMaxSize())), + serverURL, + transmitSuccessCount.WithLabelValues(donIDStr, serverURL), + transmitDuplicateCount.WithLabelValues(donIDStr, serverURL), + transmitConnectionErrorCount.WithLabelValues(donIDStr, serverURL), + transmitQueueDeleteErrorCount.WithLabelValues(donIDStr, serverURL), + transmitQueueInsertErrorCount.WithLabelValues(donIDStr, serverURL), + transmitQueuePushErrorCount.WithLabelValues(donIDStr, serverURL), + } +} + +func (s *server) HealthReport() map[string]error { + report := map[string]error{} + services.CopyHealth(report, s.c.HealthReport()) + services.CopyHealth(report, s.q.HealthReport()) + return report +} + +func (s *server) runDeleteQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup) { + defer wg.Done() + runloopCtx, cancel := stopCh.Ctx(context.Background()) + defer cancel() + + // Exponential backoff for very rarely occurring errors (DB disconnect etc) + b := backoff.Backoff{ + Min: 1 * time.Second, + Max: 120 * time.Second, + Factor: 2, + Jitter: true, + } + + for { + select { + case hash := <-s.deleteQueue: + for { + if err := s.pm.orm.Delete(runloopCtx, [][32]byte{hash}); err != nil { + s.lggr.Errorw("Failed to delete transmission record", "err", err, "transmissionHash", hash) + s.transmitQueueDeleteErrorCount.Inc() + select { + case <-time.After(b.Duration()): + // Wait a backoff duration before trying to delete again + continue + case <-stopCh: + // abort and return immediately on stop even if items remain in queue + return + } + } + break + } + // success + b.Reset() + case <-stopCh: + // abort and return immediately on stop even if items remain in queue + return + } + } +} + +func (s *server) runQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup, donIDStr string) { + defer wg.Done() + // Exponential backoff with very short retry interval (since latency is a priority) + // 5ms, 10ms, 20ms, 40ms etc + b := backoff.Backoff{ + Min: 5 * time.Millisecond, + Max: 1 * time.Second, + Factor: 2, + Jitter: true, + } + runloopCtx, cancel := stopCh.Ctx(context.Background()) + defer cancel() + for { + t := s.q.BlockingPop() + if t == nil { + // queue was closed + return + } + ctx, cancel := context.WithTimeout(runloopCtx, utils.WithJitter(s.transmitTimeout)) + res, err := s.transmit(ctx, t) + cancel() + if runloopCtx.Err() != nil { + // runloop context is only canceled on transmitter close so we can + // exit the runloop here + return + } else if err != nil { + s.transmitConnectionErrorCount.Inc() + s.lggr.Errorw("Transmit report failed", "err", err, "transmission", t) + if ok := s.q.Push(t); !ok { + s.lggr.Error("Failed to push report to transmit queue; queue is closed") + return + } + // Wait a backoff duration before pulling the most recent transmission + // the heap + select { + case <-time.After(b.Duration()): + continue + case <-stopCh: + return + } + } + + b.Reset() + if res.Error == "" { + s.transmitSuccessCount.Inc() + s.lggr.Debugw("Transmit report success", "transmission", t, "response", res) + } else { + // We don't need to retry here because the mercury server + // has confirmed it received the report. We only need to retry + // on networking/unknown errors + switch res.Code { + case DuplicateReport: + s.transmitSuccessCount.Inc() + s.transmitDuplicateCount.Inc() + s.lggr.Debugw("Transmit report success; duplicate report", "transmission", t, "response", res) + default: + transmitServerErrorCount.WithLabelValues(donIDStr, s.url, fmt.Sprintf("%d", res.Code)).Inc() + s.lggr.Errorw("Transmit report failed; mercury server returned error", "response", res, "transmission", t, "err", res.Error, "code", res.Code) + } + } + + select { + case s.deleteQueue <- t.Hash(): + default: + s.lggr.Criticalw("Delete queue is full", "transmission", t) + } + } +} + +func (s *server) transmit(ctx context.Context, t *Transmission) (*pb.TransmitResponse, error) { + var payload []byte + var err error + + switch t.Report.Info.ReportFormat { + case llotypes.ReportFormatJSON: + // TODO: exactly how to handle JSON here? + // https://smartcontract-it.atlassian.net/browse/MERC-3659 + fallthrough + case llotypes.ReportFormatEVMPremiumLegacy: + payload, err = evm.ReportCodecPremiumLegacy{}.Pack(t.ConfigDigest, t.SeqNr, t.Report.Report, t.Sigs) + default: + return nil, fmt.Errorf("Transmit failed; unsupported report format: %q", t.Report.Info.ReportFormat) + } + + if err != nil { + return nil, fmt.Errorf("Transmit: encode failed; %w", err) + } + + req := &pb.TransmitRequest{ + Payload: payload, + ReportFormat: uint32(t.Report.Info.ReportFormat), + } + + return s.c.Transmit(ctx, req) +} diff --git a/core/services/llo/mercurytransmitter/transmitter.go b/core/services/llo/mercurytransmitter/transmitter.go new file mode 100644 index 0000000000..dc032a054d --- /dev/null +++ b/core/services/llo/mercurytransmitter/transmitter.go @@ -0,0 +1,254 @@ +package mercurytransmitter + +import ( + "context" + "crypto/ed25519" + "crypto/sha256" + "encoding/binary" + "errors" + "fmt" + "io" + "sync" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "golang.org/x/sync/errgroup" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" +) + +const ( + // Mercury server error codes + DuplicateReport = 2 +) + +var ( + transmitSuccessCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "llo_mercury_transmit_success_count", + Help: "Number of successful transmissions (duplicates are counted as success)", + }, + []string{"donID", "serverURL"}, + ) + transmitDuplicateCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "llo_mercury_transmit_duplicate_count", + Help: "Number of transmissions where the server told us it was a duplicate", + }, + []string{"donID", "serverURL"}, + ) + transmitConnectionErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "llo_mercury_transmit_connection_error_count", + Help: "Number of errored transmissions that failed due to problem with the connection", + }, + []string{"donID", "serverURL"}, + ) +) + +type Transmission struct { + ServerURL string + ConfigDigest types.ConfigDigest + SeqNr uint64 + Report ocr3types.ReportWithInfo[llotypes.ReportInfo] + Sigs []types.AttributedOnchainSignature +} + +// Hash takes sha256 hash of all fields +func (t Transmission) Hash() [32]byte { + h := sha256.New() + h.Write([]byte(t.ServerURL)) + h.Write(t.ConfigDigest[:]) + if err := binary.Write(h, binary.BigEndian, t.SeqNr); err != nil { + // This should never happen + panic(err) + } + h.Write(t.Report.Report) + h.Write([]byte(t.Report.Info.LifeCycleStage)) + if err := binary.Write(h, binary.BigEndian, t.Report.Info.ReportFormat); err != nil { + // This should never happen + panic(err) + } + for _, sig := range t.Sigs { + h.Write(sig.Signature) + if err := binary.Write(h, binary.BigEndian, sig.Signer); err != nil { + // This should never happen + panic(err) + } + } + var result [32]byte + h.Sum(result[:0]) + return result +} + +type Transmitter interface { + llotypes.Transmitter + services.Service +} + +var _ Transmitter = (*transmitter)(nil) + +type Config interface { + TransmitQueueMaxSize() uint32 + TransmitTimeout() commonconfig.Duration +} + +type transmitter struct { + services.StateMachine + lggr logger.SugaredLogger + cfg Config + + orm ORM + servers map[string]*server + + donID uint32 + fromAccount string + + stopCh services.StopChan + wg *sync.WaitGroup +} + +type Opts struct { + Lggr logger.Logger + Cfg Config + Clients map[string]wsrpc.Client + FromAccount ed25519.PublicKey + DonID uint32 + ORM ORM +} + +func New(opts Opts) Transmitter { + return newTransmitter(opts) +} + +func newTransmitter(opts Opts) *transmitter { + sugared := logger.Sugared(opts.Lggr).Named("LLOMercuryTransmitter") + servers := make(map[string]*server, len(opts.Clients)) + for serverURL, client := range opts.Clients { + sLggr := sugared.Named(serverURL).With("serverURL", serverURL) + servers[serverURL] = newServer(sLggr, opts.Cfg, client, opts.ORM, serverURL) + } + return &transmitter{ + services.StateMachine{}, + sugared.Named("LLOMercuryTransmitter").With("donID", opts.ORM.DonID()), + opts.Cfg, + opts.ORM, + servers, + opts.DonID, + fmt.Sprintf("%x", opts.FromAccount), + make(services.StopChan), + &sync.WaitGroup{}, + } +} + +func (mt *transmitter) Start(ctx context.Context) (err error) { + return mt.StartOnce("LLOMercuryTransmitter", func() error { + mt.lggr.Debugw("Loading transmit requests from database") + + { + var startClosers []services.StartClose + for _, s := range mt.servers { + transmissions, err := s.pm.Load(ctx) + if err != nil { + return err + } + s.q.Init(transmissions) + // starting pm after loading from it is fine because it simply spawns some garbage collection/prune goroutines + startClosers = append(startClosers, s.c, s.q, s.pm) + + mt.wg.Add(2) + go s.runDeleteQueueLoop(mt.stopCh, mt.wg) + go s.runQueueLoop(mt.stopCh, mt.wg, fmt.Sprintf("%d", mt.donID)) + } + if err := (&services.MultiStart{}).Start(ctx, startClosers...); err != nil { + return err + } + } + + return nil + }) +} + +func (mt *transmitter) Close() error { + return mt.StopOnce("LLOMercuryTransmitter", func() error { + // Drain all the queues first + var qs []io.Closer + for _, s := range mt.servers { + qs = append(qs, s.q) + } + if err := services.CloseAll(qs...); err != nil { + return err + } + + close(mt.stopCh) + mt.wg.Wait() + + // Close all the persistence managers + // Close all the clients + var closers []io.Closer + for _, s := range mt.servers { + closers = append(closers, s.pm) + closers = append(closers, s.c) + } + return services.CloseAll(closers...) + }) +} + +func (mt *transmitter) Name() string { return mt.lggr.Name() } + +func (mt *transmitter) HealthReport() map[string]error { + report := map[string]error{mt.Name(): mt.Healthy()} + for _, s := range mt.servers { + services.CopyHealth(report, s.HealthReport()) + } + return report +} + +// Transmit enqueues the report for transmission to the Mercury servers +func (mt *transmitter) Transmit( + ctx context.Context, + digest types.ConfigDigest, + seqNr uint64, + report ocr3types.ReportWithInfo[llotypes.ReportInfo], + sigs []types.AttributedOnchainSignature) error { + transmissions := make([]*Transmission, 0, len(mt.servers)) + for serverURL := range mt.servers { + transmissions = append(transmissions, &Transmission{ + ServerURL: serverURL, + ConfigDigest: digest, + SeqNr: seqNr, + Report: report, + Sigs: sigs, + }) + } + if err := mt.orm.Insert(ctx, transmissions); err != nil { + return err + } + + g := new(errgroup.Group) + for i := range transmissions { + t := transmissions[i] + mt.lggr.Debugw("LLOMercuryTransmit", "digest", digest.Hex(), "seqNr", seqNr, "reportFormat", report.Info.ReportFormat, "reportLifeCycleStage", report.Info.LifeCycleStage, "transmissionHash", t.Hash()) + g.Go(func() error { + s := mt.servers[t.ServerURL] + if ok := s.q.Push(t); !ok { + s.transmitQueuePushErrorCount.Inc() + return errors.New("transmit queue is closed") + } + return nil + }) + } + + return g.Wait() +} + +// FromAccount returns the stringified (hex) CSA public key +func (mt *transmitter) FromAccount() (ocrtypes.Account, error) { + return ocrtypes.Account(mt.fromAccount), nil +} diff --git a/core/services/llo/mercurytransmitter/transmitter_test.go b/core/services/llo/mercurytransmitter/transmitter_test.go new file mode 100644 index 0000000000..db3d0d2e58 --- /dev/null +++ b/core/services/llo/mercurytransmitter/transmitter_test.go @@ -0,0 +1,258 @@ +package mercurytransmitter + +import ( + "context" + "crypto/ed25519" + "sync" + "testing" + "time" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" +) + +type mockCfg struct{} + +func (m mockCfg) TransmitQueueMaxSize() uint32 { + return 10_000 +} + +func (m mockCfg) TransmitTimeout() commonconfig.Duration { + return *commonconfig.MustNewDuration(1 * time.Hour) +} + +func Test_Transmitter_Transmit(t *testing.T) { + lggr := logger.TestLogger(t) + db := pgtest.NewSqlxDB(t) + donID := uint32(123456) + orm := NewORM(db, donID) + clients := map[string]wsrpc.Client{} + + t.Run("with multiple mercury servers", func(t *testing.T) { + t.Run("transmission successfully enqueued", func(t *testing.T) { + c := &mocks.MockWSRPCClient{} + clients[sURL] = c + clients[sURL2] = c + clients[sURL3] = c + + mt := newTransmitter(Opts{ + Lggr: lggr, + Cfg: mockCfg{}, + Clients: clients, + FromAccount: ed25519.PublicKey{}, + DonID: donID, + ORM: orm, + }) + // init the queue since we skipped starting transmitter + mt.servers[sURL].q.Init([]*Transmission{}) + mt.servers[sURL2].q.Init([]*Transmission{}) + mt.servers[sURL3].q.Init([]*Transmission{}) + + seqNr := uint64(55) + report := makeSampleReport() + digest := makeSampleConfigDigest() + sigs := []types.AttributedOnchainSignature{{ + Signature: []byte{22}, + Signer: commontypes.OracleID(43), + }} + err := mt.Transmit(testutils.Context(t), digest, seqNr, report, sigs) + require.NoError(t, err) + + // ensure it was added to the queue + require.Equal(t, mt.servers[sURL].q.(*transmitQueue).pq.Len(), 1) + assert.Equal(t, &Transmission{ + ServerURL: sURL, + ConfigDigest: digest, + SeqNr: seqNr, + Report: report, + Sigs: sigs, + }, mt.servers[sURL].q.(*transmitQueue).pq.Pop().(*Transmission)) + require.Equal(t, mt.servers[sURL2].q.(*transmitQueue).pq.Len(), 1) + assert.Equal(t, &Transmission{ + ServerURL: sURL2, + ConfigDigest: digest, + SeqNr: seqNr, + Report: report, + Sigs: sigs, + }, mt.servers[sURL2].q.(*transmitQueue).pq.Pop().(*Transmission)) + require.Equal(t, mt.servers[sURL3].q.(*transmitQueue).pq.Len(), 1) + assert.Equal(t, &Transmission{ + ServerURL: sURL3, + ConfigDigest: digest, + SeqNr: seqNr, + Report: report, + Sigs: sigs, + }, mt.servers[sURL3].q.(*transmitQueue).pq.Pop().(*Transmission)) + }) + }) +} + +type mockQ struct { + ch chan *Transmission +} + +func newMockQ() *mockQ { + return &mockQ{make(chan *Transmission, 100)} +} + +func (m *mockQ) Start(context.Context) error { return nil } +func (m *mockQ) Close() error { + m.ch <- nil + return nil +} +func (m *mockQ) Ready() error { return nil } +func (m *mockQ) HealthReport() map[string]error { return nil } +func (m *mockQ) Name() string { return "" } +func (m *mockQ) BlockingPop() (t *Transmission) { + val := <-m.ch + return val +} +func (m *mockQ) Push(t *Transmission) (ok bool) { + m.ch <- t + return true +} +func (m *mockQ) Init(transmissions []*Transmission) {} +func (m *mockQ) IsEmpty() bool { return false } + +func Test_Transmitter_runQueueLoop(t *testing.T) { + donIDStr := "555" + lggr := logger.TestLogger(t) + c := &mocks.MockWSRPCClient{} + db := pgtest.NewSqlxDB(t) + donID := uint32(123456) + orm := NewORM(db, donID) + cfg := mockCfg{} + + s := newServer(lggr, cfg, c, orm, sURL) + + t.Run("pulls from queue and transmits successfully", func(t *testing.T) { + transmit := make(chan *pb.TransmitRequest, 1) + c.TransmitF = func(ctx context.Context, in *pb.TransmitRequest) (*pb.TransmitResponse, error) { + transmit <- in + return &pb.TransmitResponse{Code: 0, Error: ""}, nil + } + q := newMockQ() + s.q = q + wg := &sync.WaitGroup{} + wg.Add(1) + + go s.runQueueLoop(nil, wg, donIDStr) + + transmission := makeSampleTransmission(1) + q.Push(transmission) + + select { + case tr := <-transmit: + assert.Equal(t, []byte{0x0, 0x9, 0x57, 0xdd, 0x2f, 0x63, 0x56, 0x69, 0x34, 0xfd, 0xc2, 0xe1, 0xcd, 0xc1, 0xe, 0x3e, 0x25, 0xb9, 0x26, 0x5a, 0x16, 0x23, 0x91, 0xa6, 0x53, 0x16, 0x66, 0x59, 0x51, 0x0, 0x28, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x3, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xde, 0xf5, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xde, 0xf5, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x8e, 0x95, 0xcf, 0xb5, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xd0, 0x1c, 0x67, 0xa9, 0xcf, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xdf, 0x3, 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x1c, 0x93, 0x6d, 0xa4, 0xf2, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x14, 0x8d, 0x9a, 0xc1, 0xd9, 0x6f, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x40, 0x5c, 0xcf, 0xa1, 0xbc, 0x63, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x9d, 0xab, 0x8f, 0xa7, 0xca, 0x7, 0x62, 0x57, 0xf7, 0x11, 0x2c, 0xb7, 0xf3, 0x49, 0x37, 0x12, 0xbd, 0xe, 0x14, 0x27, 0xfc, 0x32, 0x5c, 0xec, 0xa6, 0xb9, 0x7f, 0xf9, 0xd7, 0x7b, 0xa6, 0x36, 0x9a, 0x47, 0x4a, 0x3, 0x1a, 0x95, 0xcf, 0x46, 0x10, 0xaf, 0xcc, 0x90, 0x49, 0xb2, 0xce, 0xbf, 0x63, 0xaa, 0xc7, 0x25, 0x4d, 0x2a, 0x8, 0x36, 0xda, 0xd5, 0x9f, 0x9d, 0x63, 0x69, 0x22, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x30, 0x9d, 0x84, 0x29, 0xbf, 0xd4, 0xeb, 0xc5, 0xc9, 0x29, 0xef, 0xdd, 0xd3, 0x2f, 0xa6, 0x25, 0x63, 0xda, 0xd9, 0x2c, 0xa1, 0x4a, 0xba, 0x75, 0xb2, 0x85, 0x25, 0x8f, 0x2b, 0x84, 0xcd, 0x99, 0x36, 0xd9, 0x6e, 0xf, 0xae, 0x7b, 0xd1, 0x61, 0x59, 0xf, 0x36, 0x4a, 0x22, 0xec, 0xde, 0x45, 0x32, 0xe0, 0x5b, 0x5c, 0xe3, 0x14, 0x29, 0x4, 0x60, 0x7b, 0xce, 0xa3, 0x89, 0x6b, 0xbb, 0xe0}, tr.Payload) + assert.Equal(t, int(transmission.Report.Info.ReportFormat), int(tr.ReportFormat)) + case <-time.After(testutils.WaitTimeout(t)): + t.Fatal("expected a transmit request to be sent") + } + + q.Close() + wg.Wait() + }) + + t.Run("on duplicate, success", func(t *testing.T) { + transmit := make(chan *pb.TransmitRequest, 1) + c.TransmitF = func(ctx context.Context, in *pb.TransmitRequest) (*pb.TransmitResponse, error) { + transmit <- in + return &pb.TransmitResponse{Code: DuplicateReport, Error: ""}, nil + } + q := newMockQ() + s.q = q + wg := &sync.WaitGroup{} + wg.Add(1) + + go s.runQueueLoop(nil, wg, donIDStr) + + transmission := makeSampleTransmission(1) + q.Push(transmission) + + select { + case tr := <-transmit: + assert.Equal(t, []byte{0x0, 0x9, 0x57, 0xdd, 0x2f, 0x63, 0x56, 0x69, 0x34, 0xfd, 0xc2, 0xe1, 0xcd, 0xc1, 0xe, 0x3e, 0x25, 0xb9, 0x26, 0x5a, 0x16, 0x23, 0x91, 0xa6, 0x53, 0x16, 0x66, 0x59, 0x51, 0x0, 0x28, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x3, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xde, 0xf5, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xde, 0xf5, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x8e, 0x95, 0xcf, 0xb5, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xd0, 0x1c, 0x67, 0xa9, 0xcf, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xdf, 0x3, 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x1c, 0x93, 0x6d, 0xa4, 0xf2, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x14, 0x8d, 0x9a, 0xc1, 0xd9, 0x6f, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x40, 0x5c, 0xcf, 0xa1, 0xbc, 0x63, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x9d, 0xab, 0x8f, 0xa7, 0xca, 0x7, 0x62, 0x57, 0xf7, 0x11, 0x2c, 0xb7, 0xf3, 0x49, 0x37, 0x12, 0xbd, 0xe, 0x14, 0x27, 0xfc, 0x32, 0x5c, 0xec, 0xa6, 0xb9, 0x7f, 0xf9, 0xd7, 0x7b, 0xa6, 0x36, 0x9a, 0x47, 0x4a, 0x3, 0x1a, 0x95, 0xcf, 0x46, 0x10, 0xaf, 0xcc, 0x90, 0x49, 0xb2, 0xce, 0xbf, 0x63, 0xaa, 0xc7, 0x25, 0x4d, 0x2a, 0x8, 0x36, 0xda, 0xd5, 0x9f, 0x9d, 0x63, 0x69, 0x22, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x30, 0x9d, 0x84, 0x29, 0xbf, 0xd4, 0xeb, 0xc5, 0xc9, 0x29, 0xef, 0xdd, 0xd3, 0x2f, 0xa6, 0x25, 0x63, 0xda, 0xd9, 0x2c, 0xa1, 0x4a, 0xba, 0x75, 0xb2, 0x85, 0x25, 0x8f, 0x2b, 0x84, 0xcd, 0x99, 0x36, 0xd9, 0x6e, 0xf, 0xae, 0x7b, 0xd1, 0x61, 0x59, 0xf, 0x36, 0x4a, 0x22, 0xec, 0xde, 0x45, 0x32, 0xe0, 0x5b, 0x5c, 0xe3, 0x14, 0x29, 0x4, 0x60, 0x7b, 0xce, 0xa3, 0x89, 0x6b, 0xbb, 0xe0}, tr.Payload) + assert.Equal(t, int(transmission.Report.Info.ReportFormat), int(tr.ReportFormat)) + case <-time.After(testutils.WaitTimeout(t)): + t.Fatal("expected a transmit request to be sent") + } + + q.Close() + wg.Wait() + }) + t.Run("on server-side error, does not retry", func(t *testing.T) { + transmit := make(chan *pb.TransmitRequest, 1) + c.TransmitF = func(ctx context.Context, in *pb.TransmitRequest) (*pb.TransmitResponse, error) { + transmit <- in + return &pb.TransmitResponse{Code: DuplicateReport, Error: ""}, nil + } + q := newMockQ() + s.q = q + wg := &sync.WaitGroup{} + wg.Add(1) + + go s.runQueueLoop(nil, wg, donIDStr) + + transmission := makeSampleTransmission(1) + q.Push(transmission) + + select { + case tr := <-transmit: + assert.Equal(t, []byte{0x0, 0x9, 0x57, 0xdd, 0x2f, 0x63, 0x56, 0x69, 0x34, 0xfd, 0xc2, 0xe1, 0xcd, 0xc1, 0xe, 0x3e, 0x25, 0xb9, 0x26, 0x5a, 0x16, 0x23, 0x91, 0xa6, 0x53, 0x16, 0x66, 0x59, 0x51, 0x0, 0x28, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x3, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xde, 0xf5, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xde, 0xf5, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x8e, 0x95, 0xcf, 0xb5, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xd0, 0x1c, 0x67, 0xa9, 0xcf, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xdf, 0x3, 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x1c, 0x93, 0x6d, 0xa4, 0xf2, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x14, 0x8d, 0x9a, 0xc1, 0xd9, 0x6f, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x40, 0x5c, 0xcf, 0xa1, 0xbc, 0x63, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x9d, 0xab, 0x8f, 0xa7, 0xca, 0x7, 0x62, 0x57, 0xf7, 0x11, 0x2c, 0xb7, 0xf3, 0x49, 0x37, 0x12, 0xbd, 0xe, 0x14, 0x27, 0xfc, 0x32, 0x5c, 0xec, 0xa6, 0xb9, 0x7f, 0xf9, 0xd7, 0x7b, 0xa6, 0x36, 0x9a, 0x47, 0x4a, 0x3, 0x1a, 0x95, 0xcf, 0x46, 0x10, 0xaf, 0xcc, 0x90, 0x49, 0xb2, 0xce, 0xbf, 0x63, 0xaa, 0xc7, 0x25, 0x4d, 0x2a, 0x8, 0x36, 0xda, 0xd5, 0x9f, 0x9d, 0x63, 0x69, 0x22, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x30, 0x9d, 0x84, 0x29, 0xbf, 0xd4, 0xeb, 0xc5, 0xc9, 0x29, 0xef, 0xdd, 0xd3, 0x2f, 0xa6, 0x25, 0x63, 0xda, 0xd9, 0x2c, 0xa1, 0x4a, 0xba, 0x75, 0xb2, 0x85, 0x25, 0x8f, 0x2b, 0x84, 0xcd, 0x99, 0x36, 0xd9, 0x6e, 0xf, 0xae, 0x7b, 0xd1, 0x61, 0x59, 0xf, 0x36, 0x4a, 0x22, 0xec, 0xde, 0x45, 0x32, 0xe0, 0x5b, 0x5c, 0xe3, 0x14, 0x29, 0x4, 0x60, 0x7b, 0xce, 0xa3, 0x89, 0x6b, 0xbb, 0xe0}, tr.Payload) + assert.Equal(t, int(transmission.Report.Info.ReportFormat), int(tr.ReportFormat)) + case <-time.After(testutils.WaitTimeout(t)): + t.Fatal("expected a transmit request to be sent") + } + + q.Close() + wg.Wait() + }) + t.Run("on transmit error, retries", func(t *testing.T) { + transmit := make(chan *pb.TransmitRequest, 1) + c.TransmitF = func(ctx context.Context, in *pb.TransmitRequest) (*pb.TransmitResponse, error) { + transmit <- in + return &pb.TransmitResponse{}, errors.New("transmission error") + } + q := newMockQ() + s.q = q + wg := &sync.WaitGroup{} + wg.Add(1) + stopCh := make(chan struct{}, 1) + + go s.runQueueLoop(stopCh, wg, donIDStr) + + transmission := makeSampleTransmission(1) + q.Push(transmission) + + cnt := 0 + Loop: + for { + select { + case tr := <-transmit: + assert.Equal(t, []byte{0x0, 0x9, 0x57, 0xdd, 0x2f, 0x63, 0x56, 0x69, 0x34, 0xfd, 0xc2, 0xe1, 0xcd, 0xc1, 0xe, 0x3e, 0x25, 0xb9, 0x26, 0x5a, 0x16, 0x23, 0x91, 0xa6, 0x53, 0x16, 0x66, 0x59, 0x51, 0x0, 0x28, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x3, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xde, 0xf5, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xde, 0xf5, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x8e, 0x95, 0xcf, 0xb5, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xd0, 0x1c, 0x67, 0xa9, 0xcf, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xdf, 0x3, 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x1c, 0x93, 0x6d, 0xa4, 0xf2, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x14, 0x8d, 0x9a, 0xc1, 0xd9, 0x6f, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x40, 0x5c, 0xcf, 0xa1, 0xbc, 0x63, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x9d, 0xab, 0x8f, 0xa7, 0xca, 0x7, 0x62, 0x57, 0xf7, 0x11, 0x2c, 0xb7, 0xf3, 0x49, 0x37, 0x12, 0xbd, 0xe, 0x14, 0x27, 0xfc, 0x32, 0x5c, 0xec, 0xa6, 0xb9, 0x7f, 0xf9, 0xd7, 0x7b, 0xa6, 0x36, 0x9a, 0x47, 0x4a, 0x3, 0x1a, 0x95, 0xcf, 0x46, 0x10, 0xaf, 0xcc, 0x90, 0x49, 0xb2, 0xce, 0xbf, 0x63, 0xaa, 0xc7, 0x25, 0x4d, 0x2a, 0x8, 0x36, 0xda, 0xd5, 0x9f, 0x9d, 0x63, 0x69, 0x22, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x30, 0x9d, 0x84, 0x29, 0xbf, 0xd4, 0xeb, 0xc5, 0xc9, 0x29, 0xef, 0xdd, 0xd3, 0x2f, 0xa6, 0x25, 0x63, 0xda, 0xd9, 0x2c, 0xa1, 0x4a, 0xba, 0x75, 0xb2, 0x85, 0x25, 0x8f, 0x2b, 0x84, 0xcd, 0x99, 0x36, 0xd9, 0x6e, 0xf, 0xae, 0x7b, 0xd1, 0x61, 0x59, 0xf, 0x36, 0x4a, 0x22, 0xec, 0xde, 0x45, 0x32, 0xe0, 0x5b, 0x5c, 0xe3, 0x14, 0x29, 0x4, 0x60, 0x7b, 0xce, 0xa3, 0x89, 0x6b, 0xbb, 0xe0}, tr.Payload) + assert.Equal(t, int(transmission.Report.Info.ReportFormat), int(tr.ReportFormat)) + if cnt > 2 { + break Loop + } + cnt++ + case <-time.After(testutils.WaitTimeout(t)): + t.Fatal("expected 3 transmit requests to be sent") + } + } + + close(stopCh) + wg.Wait() + }) +} diff --git a/core/services/llo/transmitter.go b/core/services/llo/transmitter.go index fe6f26c317..3b7ef66e6a 100644 --- a/core/services/llo/transmitter.go +++ b/core/services/llo/transmitter.go @@ -2,24 +2,24 @@ package llo import ( "context" - "crypto/ed25519" - "fmt" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "golang.org/x/sync/errgroup" + + "github.com/smartcontractkit/chainlink/v2/core/services/llo/mercurytransmitter" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" - - "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" ) // LLO Transmitter implementation, based on // core/services/relay/evm/mercury/transmitter.go +// +// If you need to "fan-out" transmits and send reports to a new destination, +// add a new subTransmitter // TODO: prom metrics (common with mercury/transmitter.go?) // https://smartcontract-it.atlassian.net/browse/MERC-3659 @@ -42,30 +42,57 @@ type Transmitter interface { type transmitter struct { services.StateMachine lggr logger.Logger - rpcClient wsrpc.Client fromAccount string + + subTransmitters []Transmitter } -func NewTransmitter(lggr logger.Logger, rpcClient wsrpc.Client, fromAccount ed25519.PublicKey) Transmitter { +type TransmitterOpts struct { + Lggr logger.Logger + FromAccount string + MercuryTransmitterOpts mercurytransmitter.Opts +} + +// The transmitter will handle starting and stopping the subtransmitters +func NewTransmitter(opts TransmitterOpts) Transmitter { + subTransmitters := []Transmitter{ + mercurytransmitter.New(opts.MercuryTransmitterOpts), + } return &transmitter{ services.StateMachine{}, - lggr, - rpcClient, - fmt.Sprintf("%x", fromAccount), + opts.Lggr, + opts.FromAccount, + subTransmitters, } } func (t *transmitter) Start(ctx context.Context) error { - return nil + return t.StartOnce("llo.Transmitter", func() error { + for _, st := range t.subTransmitters { + if err := st.Start(ctx); err != nil { + return err + } + } + return nil + }) } func (t *transmitter) Close() error { - return nil + return t.StopOnce("llo.Transmitter", func() error { + for _, st := range t.subTransmitters { + if err := st.Close(); err != nil { + return err + } + } + return nil + }) } func (t *transmitter) HealthReport() map[string]error { report := map[string]error{t.Name(): t.Healthy()} - services.CopyHealth(report, t.rpcClient.HealthReport()) + for _, st := range t.subTransmitters { + services.CopyHealth(report, st.HealthReport()) + } return report } @@ -78,32 +105,14 @@ func (t *transmitter) Transmit( report ocr3types.ReportWithInfo[llotypes.ReportInfo], sigs []types.AttributedOnchainSignature, ) (err error) { - var payload []byte - - switch report.Info.ReportFormat { - case llotypes.ReportFormatJSON: - // TODO: exactly how to handle JSON here? - // https://smartcontract-it.atlassian.net/browse/MERC-3659 - fallthrough - case llotypes.ReportFormatEVMPremiumLegacy: - payload, err = evm.ReportCodecPremiumLegacy{}.Pack(digest, seqNr, report.Report, sigs) - default: - return fmt.Errorf("Transmit failed; unsupported report format: %q", report.Info.ReportFormat) + g := new(errgroup.Group) + for _, st := range t.subTransmitters { + st := st + g.Go(func() error { + return st.Transmit(ctx, digest, seqNr, report, sigs) + }) } - - if err != nil { - return fmt.Errorf("Transmit: encode failed; %w", err) - } - - req := &pb.TransmitRequest{ - Payload: payload, - ReportFormat: uint32(report.Info.ReportFormat), - } - - // TODO: persistenceManager and queueing, error handling, retry etc - // https://smartcontract-it.atlassian.net/browse/MERC-3659 - _, err = t.rpcClient.Transmit(ctx, req) - return err + return g.Wait() } // FromAccount returns the stringified (hex) CSA public key diff --git a/core/services/llo/transmitter_test.go b/core/services/llo/transmitter_test.go deleted file mode 100644 index eb231494c0..0000000000 --- a/core/services/llo/transmitter_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package llo - -import "testing" - -func Test_Transmitter(t *testing.T) { - // TODO: https://smartcontract-it.atlassian.net/browse/MERC-3659 -} diff --git a/core/services/ocr2/plugins/llo/config/config.go b/core/services/ocr2/plugins/llo/config/config.go index 2460fecd72..7bd36b4ff8 100644 --- a/core/services/ocr2/plugins/llo/config/config.go +++ b/core/services/ocr2/plugins/llo/config/config.go @@ -9,19 +9,18 @@ import ( "fmt" "net/url" "regexp" + "sort" "github.com/ethereum/go-ethereum/common" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + mercuryconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury/config" "github.com/smartcontractkit/chainlink/v2/core/utils" ) type PluginConfig struct { - RawServerURL string `json:"serverURL" toml:"serverURL"` - ServerPubKey utils.PlainHexBytes `json:"serverPubKey" toml:"serverPubKey"` - ChannelDefinitionsContractAddress common.Address `json:"channelDefinitionsContractAddress" toml:"channelDefinitionsContractAddress"` ChannelDefinitionsContractFromBlock int64 `json:"channelDefinitionsContractFromBlock" toml:"channelDefinitionsContractFromBlock"` @@ -41,31 +40,40 @@ type PluginConfig struct { KeyBundleIDs map[string]string `json:"keyBundleIDs" toml:"keyBundleIDs"` DonID uint32 `json:"donID" toml:"donID"` + + // Mercury servers + Servers map[string]utils.PlainHexBytes `json:"servers" toml:"servers"` } func (p *PluginConfig) Unmarshal(data []byte) error { return json.Unmarshal(data, p) } +func (p PluginConfig) GetServers() (servers []mercuryconfig.Server) { + for url, pubKey := range p.Servers { + servers = append(servers, mercuryconfig.Server{URL: wssRegexp.ReplaceAllString(url, ""), PubKey: pubKey}) + } + sort.Slice(servers, func(i, j int) bool { + return servers[i].URL < servers[j].URL + }) + return +} + func (p PluginConfig) Validate() (merr error) { if p.DonID == 0 { merr = errors.Join(merr, errors.New("llo: DonID must be specified and not zero")) } - if p.RawServerURL == "" { - merr = errors.Join(merr, errors.New("llo: ServerURL must be specified")) + if len(p.Servers) == 0 { + merr = errors.Join(merr, errors.New("llo: At least one Mercury server must be specified")) } else { - var normalizedURI string - if schemeRegexp.MatchString(p.RawServerURL) { - normalizedURI = p.RawServerURL - } else { - normalizedURI = fmt.Sprintf("wss://%s", p.RawServerURL) - } - uri, err := url.ParseRequestURI(normalizedURI) - if err != nil { - merr = errors.Join(merr, fmt.Errorf("llo: invalid value for ServerURL: %w", err)) - } else if uri.Scheme != "wss" { - merr = errors.Join(merr, fmt.Errorf(`llo: invalid scheme specified for MercuryServer, got: %q (scheme: %q) but expected a websocket url e.g. "192.0.2.2:4242" or "wss://192.0.2.2:4242"`, p.RawServerURL, uri.Scheme)) + for serverName, serverPubKey := range p.Servers { + if err := validateURL(serverName); err != nil { + merr = errors.Join(merr, fmt.Errorf("llo: invalid value for ServerURL: %w", err)) + } + if len(serverPubKey) != 32 { + merr = errors.Join(merr, errors.New("llo: ServerPubKey must be a 32-byte hex string")) + } } } @@ -88,15 +96,28 @@ func (p PluginConfig) Validate() (merr error) { } } - if len(p.ServerPubKey) != 32 { - merr = errors.Join(merr, errors.New("llo: ServerPubKey is required and must be a 32-byte hex string")) - } - merr = errors.Join(merr, validateKeyBundleIDs(p.KeyBundleIDs)) return merr } +func validateURL(rawServerURL string) error { + var normalizedURI string + if schemeRegexp.MatchString(rawServerURL) { + normalizedURI = rawServerURL + } else { + normalizedURI = fmt.Sprintf("wss://%s", rawServerURL) + } + uri, err := url.ParseRequestURI(normalizedURI) + if err != nil { + return fmt.Errorf(`llo: invalid value for ServerURL, got: %q`, rawServerURL) + } + if uri.Scheme != "wss" { + return fmt.Errorf(`llo: invalid scheme specified for MercuryServer, got: %q (scheme: %q) but expected a websocket url e.g. "192.0.2.2:4242" or "wss://192.0.2.2:4242"`, rawServerURL, uri.Scheme) + } + return nil +} + func validateKeyBundleIDs(keyBundleIDs map[string]string) error { for k, v := range keyBundleIDs { if k == "" { @@ -117,7 +138,3 @@ func validateKeyBundleIDs(keyBundleIDs map[string]string) error { var schemeRegexp = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9+.-]*://`) var wssRegexp = regexp.MustCompile(`^wss://`) - -func (p PluginConfig) ServerURL() string { - return wssRegexp.ReplaceAllString(p.RawServerURL, "") -} diff --git a/core/services/ocr2/plugins/llo/config/config_test.go b/core/services/ocr2/plugins/llo/config/config_test.go index 5152dc839b..096543b252 100644 --- a/core/services/ocr2/plugins/llo/config/config_test.go +++ b/core/services/ocr2/plugins/llo/config/config_test.go @@ -7,6 +7,8 @@ import ( "github.com/pelletier/go-toml/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/utils" ) func Test_Config(t *testing.T) { @@ -31,8 +33,7 @@ func Test_Config(t *testing.T) { t.Run("with all possible values set", func(t *testing.T) { rawToml := fmt.Sprintf(` - ServerURL = "example.com:80" - ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" + Servers = { "example.com:80" = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", "example2.invalid:1234" = "524ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" } BenchmarkMode = true ChannelDefinitionsContractAddress = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" ChannelDefinitionsContractFromBlock = 1234 @@ -44,8 +45,8 @@ func Test_Config(t *testing.T) { err := toml.Unmarshal([]byte(rawToml), &mc) require.NoError(t, err) - assert.Equal(t, "example.com:80", mc.RawServerURL) - assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) + assert.Len(t, mc.Servers, 2) + assert.Equal(t, map[string]utils.PlainHexBytes{"example.com:80": utils.PlainHexBytes{0x72, 0x4f, 0xf6, 0xea, 0xe9, 0xe9, 0x0, 0x27, 0xe, 0xdf, 0xff, 0x23, 0x3e, 0x16, 0x32, 0x2a, 0x70, 0xec, 0x6, 0xe1, 0xa6, 0xe6, 0x2a, 0x81, 0xef, 0x13, 0x92, 0x1f, 0x39, 0x8f, 0x6c, 0x93}, "example2.invalid:1234": utils.PlainHexBytes{0x52, 0x4f, 0xf6, 0xea, 0xe9, 0xe9, 0x0, 0x27, 0xe, 0xdf, 0xff, 0x23, 0x3e, 0x16, 0x32, 0x2a, 0x70, 0xec, 0x6, 0xe1, 0xa6, 0xe6, 0x2a, 0x81, 0xef, 0x13, 0x92, 0x1f, 0x39, 0x8f, 0x6c, 0x93}}, mc.Servers) assert.Equal(t, "0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF", mc.ChannelDefinitionsContractAddress.Hex()) assert.Equal(t, int64(1234), mc.ChannelDefinitionsContractFromBlock) assert.JSONEq(t, cdjson, mc.ChannelDefinitions) @@ -60,8 +61,7 @@ func Test_Config(t *testing.T) { t.Run("with only channelDefinitions", func(t *testing.T) { rawToml := fmt.Sprintf(` - ServerURL = "example.com:80" - ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" + Servers = { "example.com:80" = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" } DonID = 12345 ChannelDefinitions = """ %s @@ -71,8 +71,7 @@ func Test_Config(t *testing.T) { err := toml.Unmarshal([]byte(rawToml), &mc) require.NoError(t, err) - assert.Equal(t, "example.com:80", mc.RawServerURL) - assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) + assert.Len(t, mc.Servers, 1) assert.JSONEq(t, cdjson, mc.ChannelDefinitions) assert.Equal(t, uint32(12345), mc.DonID) assert.False(t, mc.BenchmarkMode) @@ -82,17 +81,15 @@ func Test_Config(t *testing.T) { }) t.Run("with only channelDefinitions contract details", func(t *testing.T) { rawToml := ` + Servers = { "example.com:80" = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" } DonID = 12345 - ServerURL = "example.com:80" - ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" ChannelDefinitionsContractAddress = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"` var mc PluginConfig err := toml.Unmarshal([]byte(rawToml), &mc) require.NoError(t, err) - assert.Equal(t, "example.com:80", mc.RawServerURL) - assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) + assert.Len(t, mc.Servers, 1) assert.Equal(t, "0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF", mc.ChannelDefinitionsContractAddress.Hex()) assert.Equal(t, uint32(12345), mc.DonID) assert.False(t, mc.BenchmarkMode) @@ -102,17 +99,15 @@ func Test_Config(t *testing.T) { }) t.Run("with missing ChannelDefinitionsContractAddress", func(t *testing.T) { rawToml := ` - ServerURL = "example.com:80" - ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" DonID = 12345 + Servers = { "example.com:80" = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" } ` var mc PluginConfig err := toml.Unmarshal([]byte(rawToml), &mc) require.NoError(t, err) - assert.Equal(t, "example.com:80", mc.RawServerURL) - assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) + assert.Len(t, mc.Servers, 1) assert.Equal(t, uint32(12345), mc.DonID) assert.False(t, mc.BenchmarkMode) @@ -142,8 +137,39 @@ func Test_Config(t *testing.T) { err = mc.Validate() require.Error(t, err) - assert.Contains(t, err.Error(), `invalid scheme specified for MercuryServer, got: "http://example.com" (scheme: "http") but expected a websocket url e.g. "192.0.2.2:4242" or "wss://192.0.2.2:4242"`) - assert.Contains(t, err.Error(), `ServerPubKey is required and must be a 32-byte hex string`) + assert.Contains(t, err.Error(), `DonID must be specified and not zero`) + assert.Contains(t, err.Error(), `At least one Mercury server must be specified`) + assert.Contains(t, err.Error(), `ChannelDefinitionsContractAddress is required if ChannelDefinitions is not specified`) }) }) } + +func Test_PluginConfig_Validate(t *testing.T) { + t.Run("with invalid URLs or keys", func(t *testing.T) { + servers := map[string]utils.PlainHexBytes{ + "not a valid url": utils.PlainHexBytes([]byte{1, 2, 3}), + "mercuryserver.invalid:1234/foo": nil, + } + pc := PluginConfig{Servers: servers} + + err := pc.Validate() + assert.Contains(t, err.Error(), "ServerPubKey must be a 32-byte hex string") + assert.Contains(t, err.Error(), "invalid value for ServerURL: llo: invalid value for ServerURL, got: \"not a valid url\"") + }) +} + +func Test_PluginConfig_GetServers(t *testing.T) { + t.Run("with multiple servers", func(t *testing.T) { + servers := map[string]utils.PlainHexBytes{ + "example.com:80": utils.PlainHexBytes([]byte{1, 2, 3}), + "mercuryserver.invalid:1234/foo": utils.PlainHexBytes([]byte{4, 5, 6}), + } + pc := PluginConfig{Servers: servers} + + require.Len(t, pc.GetServers(), 2) + assert.Equal(t, "example.com:80", pc.GetServers()[0].URL) + assert.Equal(t, utils.PlainHexBytes{1, 2, 3}, pc.GetServers()[0].PubKey) + assert.Equal(t, "mercuryserver.invalid:1234/foo", pc.GetServers()[1].URL) + assert.Equal(t, utils.PlainHexBytes{4, 5, 6}, pc.GetServers()[1].PubKey) + }) +} diff --git a/core/services/ocr2/plugins/llo/integration_test.go b/core/services/ocr2/plugins/llo/integration_test.go index 50d580fe25..62c43eaf4d 100644 --- a/core/services/ocr2/plugins/llo/integration_test.go +++ b/core/services/ocr2/plugins/llo/integration_test.go @@ -321,11 +321,10 @@ lloDonID = %d require.NoError(t, err) backend.Commit() - pluginConfig := fmt.Sprintf(`serverURL = "%s" + pluginConfig := fmt.Sprintf(`servers = { "%s" = "%x" } donID = %d -serverPubKey = "%x" channelDefinitionsContractAddress = "0x%x" -channelDefinitionsContractFromBlock = %d`, serverURL, donID, serverPubKey, configStoreAddress, fromBlock) +channelDefinitionsContractFromBlock = %d`, serverURL, serverPubKey, donID, configStoreAddress, fromBlock) addOCRJobsEVMPremiumLegacy(t, streams, serverPubKey, serverURL, configuratorAddress, bootstrapPeerID, bootstrapNodePort, nodes, configStoreAddress, clientPubKeys, pluginConfig, relayType, relayConfig) // Set config on configurator diff --git a/core/services/relay/dummy/llo_provider.go b/core/services/relay/dummy/llo_provider.go index 887fa13430..88f7258815 100644 --- a/core/services/relay/dummy/llo_provider.go +++ b/core/services/relay/dummy/llo_provider.go @@ -11,14 +11,18 @@ import ( relaytypes "github.com/smartcontractkit/chainlink-common/pkg/types" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/llo" ) var _ commontypes.LLOProvider = (*lloProvider)(nil) +type Transmitter interface { + services.Service + llotypes.Transmitter +} + type lloProvider struct { cp commontypes.ConfigProvider - transmitter llo.Transmitter + transmitter Transmitter logger logger.Logger channelDefinitionCache llotypes.ChannelDefinitionCache @@ -28,7 +32,7 @@ type lloProvider struct { func NewLLOProvider( lggr logger.Logger, cp commontypes.ConfigProvider, - transmitter llo.Transmitter, + transmitter Transmitter, channelDefinitionCache llotypes.ChannelDefinitionCache, ) relaytypes.LLOProvider { return &lloProvider{ diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 273926136e..579e8b6788 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -41,6 +41,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/llo" "github.com/smartcontractkit/chainlink/v2/core/services/llo/bm" + "github.com/smartcontractkit/chainlink/v2/core/services/llo/mercurytransmitter" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/ccipcommit" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/ccipexec" @@ -437,17 +438,31 @@ func (r *Relayer) NewLLOProvider(rargs commontypes.RelayArgs, pargs commontypes. // FIXME: Remove after benchmarking is done // https://smartcontract-it.atlassian.net/browse/MERC-3487 - var transmitter llo.Transmitter + var transmitter LLOTransmitter if lloCfg.BenchmarkMode { r.lggr.Info("Benchmark mode enabled, using dummy transmitter. NOTE: THIS WILL NOT TRANSMIT ANYTHING") transmitter = bm.NewTransmitter(r.lggr, fmt.Sprintf("%x", privKey.PublicKey)) } else { - var client wsrpc.Client - client, err = r.mercuryPool.Checkout(context.Background(), privKey, lloCfg.ServerPubKey, lloCfg.ServerURL()) - if err != nil { - return nil, err + clients := make(map[string]wsrpc.Client) + for _, server := range lloCfg.GetServers() { + client, err2 := r.mercuryPool.Checkout(context.Background(), privKey, server.PubKey, server.URL) + if err2 != nil { + return nil, err2 + } + clients[server.URL] = client } - transmitter = llo.NewTransmitter(r.lggr, client, privKey.PublicKey) + transmitter = llo.NewTransmitter(llo.TransmitterOpts{ + Lggr: r.lggr, + FromAccount: fmt.Sprintf("%x", privKey.PublicKey), // NOTE: This may need to change if we support e.g. multiple tranmsmitters, to be a composite of all keys + MercuryTransmitterOpts: mercurytransmitter.Opts{ + Lggr: r.lggr, + Cfg: r.transmitterCfg, + Clients: clients, + FromAccount: privKey.PublicKey, + DonID: relayConfig.LLODONID, + ORM: mercurytransmitter.NewORM(r.ds, relayConfig.LLODONID), + }, + }) } cdcFactory, err := r.cdcFactory() diff --git a/core/services/relay/evm/llo_provider.go b/core/services/relay/evm/llo_provider.go index 55b80bd58e..2cf6163047 100644 --- a/core/services/relay/evm/llo_provider.go +++ b/core/services/relay/evm/llo_provider.go @@ -11,15 +11,18 @@ import ( commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" relaytypes "github.com/smartcontractkit/chainlink-common/pkg/types" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" - - "github.com/smartcontractkit/chainlink/v2/core/services/llo" ) var _ commontypes.LLOProvider = (*lloProvider)(nil) +type LLOTransmitter interface { + services.Service + llotypes.Transmitter +} + type lloProvider struct { cp commontypes.ConfigProvider - transmitter llo.Transmitter + transmitter LLOTransmitter logger logger.Logger channelDefinitionCache llotypes.ChannelDefinitionCache @@ -28,7 +31,7 @@ type lloProvider struct { func NewLLOProvider( cp commontypes.ConfigProvider, - transmitter llo.Transmitter, + transmitter LLOTransmitter, lggr logger.Logger, channelDefinitionCache llotypes.ChannelDefinitionCache, ) relaytypes.LLOProvider { diff --git a/core/services/relay/evm/mercury/config_poller.go b/core/services/relay/evm/mercury/config_poller.go index 111c432e6f..7bb5d2af7b 100644 --- a/core/services/relay/evm/mercury/config_poller.go +++ b/core/services/relay/evm/mercury/config_poller.go @@ -99,7 +99,6 @@ func FilterName(addr common.Address, feedID common.Hash) string { // NewConfigPoller creates a new Mercury ConfigPoller func NewConfigPoller(ctx context.Context, lggr logger.Logger, destChainPoller logpoller.LogPoller, addr common.Address, feedId common.Hash) (*ConfigPoller, error) { - fmt.Println("TRASH RegisterFilter", FilterName(addr, feedId)) err := destChainPoller.RegisterFilter(ctx, logpoller.Filter{Name: FilterName(addr, feedId), EventSigs: []common.Hash{FeedScopedConfigSet}, Addresses: []common.Address{addr}}) if err != nil { return nil, err diff --git a/core/store/migrate/migrations/0252_add_llo_transmit_requests.sql b/core/store/migrate/migrations/0252_add_llo_transmit_requests.sql new file mode 100644 index 0000000000..d08ae0c921 --- /dev/null +++ b/core/store/migrate/migrations/0252_add_llo_transmit_requests.sql @@ -0,0 +1,21 @@ +-- +goose Up + +CREATE TABLE llo_mercury_transmit_queue ( + don_id BIGINT NOT NULL, + server_url TEXT NOT NULL, + config_digest BYTEA NOT NULL, + seq_nr BIGINT NOT NULL, + report BYTEA NOT NULL, + lifecycle_stage TEXT NOT NULL, + report_format BIGINT NOT NULL, + signatures BYTEA[] NOT NULL, + signers SMALLINT[] NOT NULL, + transmission_hash BYTEA NOT NULL, + PRIMARY KEY (transmission_hash) +); + + CREATE INDEX idx_llo_mercury_transmit_queue_don_id_server_url_seq_nr ON llo_mercury_transmit_queue (don_id, server_url, seq_nr DESC); + +-- +goose Down + +DROP TABLE llo_mercury_transmit_queue; diff --git a/go.mod b/go.mod index 32959272ea..4803a35b9d 100644 --- a/go.mod +++ b/go.mod @@ -77,7 +77,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 diff --git a/go.sum b/go.sum index adc46fa723..aea2168da8 100644 --- a/go.sum +++ b/go.sum @@ -1046,8 +1046,8 @@ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de732 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 h1:xow5cYrWxRmzTwhz2AjWOlnI9WRF4O5b84bXm1k292E= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227/go.mod h1:DUFantPYoBGwBSkNVt2k4ZJi0jPKRRrZVVlAzcZwreA= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd h1:+RFI4mgXSGEcn847e7bavhQCqaBiW142g1XfGzijFoY= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 4effcf9f2f..53aa0f475b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -404,7 +404,7 @@ require ( github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 18538f1b98..02208bcf8a 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1429,8 +1429,8 @@ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de732 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 h1:xow5cYrWxRmzTwhz2AjWOlnI9WRF4O5b84bXm1k292E= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227/go.mod h1:DUFantPYoBGwBSkNVt2k4ZJi0jPKRRrZVVlAzcZwreA= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd h1:+RFI4mgXSGEcn847e7bavhQCqaBiW142g1XfGzijFoY= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index d3d6d8452a..6d2658d24a 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -395,7 +395,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.21 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index e781103a2d..592984aca4 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1403,8 +1403,8 @@ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de732 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 h1:xow5cYrWxRmzTwhz2AjWOlnI9WRF4O5b84bXm1k292E= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227/go.mod h1:DUFantPYoBGwBSkNVt2k4ZJi0jPKRRrZVVlAzcZwreA= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652 h1:0aZ3HiEz2bMM5ywHAyKlFMN95qTzpNDn7uvnHLrFX6s= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240904093355-e40169857652/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd h1:+RFI4mgXSGEcn847e7bavhQCqaBiW142g1XfGzijFoY= From 51cb378ed8c1a723ade4b19b9fe881ed924cc455 Mon Sep 17 00:00:00 2001 From: DavidOrchard Date: Wed, 11 Sep 2024 06:49:38 -0700 Subject: [PATCH 328/432] [CAPPL-19] Gateway Connector service wrapper (#14356) * service wrapper * PR updates: simplify connector into signer and consolidate files * keep signer as handler with empty methods for now * lint * PR comments except for unit test * package lint * unit test v1 * fix unit tests * PR Review: fix config, separate tests * PR review: clean up pointers, service wrapper generation. * fix mocks return args issue * add logs to figure out Sign issue * fix keys issues * typos * remove redundant named import * update order of deps to try to fix strange lint error * remove handlegatewaymessage * change name to gwcommon * remove unused funcs and clean up var reuse * add clock to servicewrapper * fix bug in configs * fix Ready and healthreport * remove connectorSigner struct * remove privateKey from constructor, keep initialization in Start * lint --------- Co-authored-by: Bolek <1416262+bolekk@users.noreply.github.com> --- .../gateway_connector/service_wrapper.go | 114 ++++++++++++++++++ .../gateway_connector/service_wrapper_test.go | 80 ++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 core/capabilities/gateway_connector/service_wrapper.go create mode 100644 core/capabilities/gateway_connector/service_wrapper_test.go diff --git a/core/capabilities/gateway_connector/service_wrapper.go b/core/capabilities/gateway_connector/service_wrapper.go new file mode 100644 index 0000000000..824c92b4f8 --- /dev/null +++ b/core/capabilities/gateway_connector/service_wrapper.go @@ -0,0 +1,114 @@ +package gatewayconnector + +import ( + "context" + "crypto/ecdsa" + "errors" + "math/big" + "slices" + + "github.com/ethereum/go-ethereum/common" + "github.com/jonboulle/clockwork" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink/v2/core/config" + "github.com/smartcontractkit/chainlink/v2/core/logger" + gwcommon "github.com/smartcontractkit/chainlink/v2/core/services/gateway/common" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/network" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" +) + +type ServiceWrapper struct { + services.StateMachine + + config config.GatewayConnector + keystore keystore.Eth + connector connector.GatewayConnector + signerKey *ecdsa.PrivateKey + lggr logger.Logger + clock clockwork.Clock +} + +func translateConfigs(f config.GatewayConnector) connector.ConnectorConfig { + r := connector.ConnectorConfig{} + r.NodeAddress = f.NodeAddress() + r.DonId = f.DonID() + + if len(f.Gateways()) != 0 { + r.Gateways = make([]connector.ConnectorGatewayConfig, len(f.Gateways())) + for index, element := range f.Gateways() { + r.Gateways[index] = connector.ConnectorGatewayConfig{Id: element.ID(), URL: element.URL()} + } + } + + r.WsClientConfig = network.WebSocketClientConfig{HandshakeTimeoutMillis: f.WSHandshakeTimeoutMillis()} + r.AuthMinChallengeLen = f.AuthMinChallengeLen() + r.AuthTimestampToleranceSec = f.AuthTimestampToleranceSec() + return r +} + +// NOTE: this wrapper is needed to make sure that our services are started after Keystore. +func NewGatewayConnectorServiceWrapper(config config.GatewayConnector, keystore keystore.Eth, clock clockwork.Clock, lggr logger.Logger) *ServiceWrapper { + return &ServiceWrapper{ + config: config, + keystore: keystore, + clock: clock, + lggr: lggr, + } +} + +func (e *ServiceWrapper) Start(ctx context.Context) error { + return e.StartOnce("GatewayConnectorServiceWrapper", func() error { + conf := e.config + nodeAddress := conf.NodeAddress() + chainID, _ := new(big.Int).SetString(conf.ChainIDForNodeKey(), 0) + enabledKeys, err := e.keystore.EnabledKeysForChain(ctx, chainID) + if err != nil { + return err + } + if len(enabledKeys) == 0 { + return errors.New("no available keys found") + } + configuredNodeAddress := common.HexToAddress(nodeAddress) + idx := slices.IndexFunc(enabledKeys, func(key ethkey.KeyV2) bool { return key.Address == configuredNodeAddress }) + + if idx == -1 { + return errors.New("key for configured node address not found") + } + e.signerKey = enabledKeys[idx].ToEcdsaPrivKey() + if enabledKeys[idx].ID() != nodeAddress { + return errors.New("node address mismatch") + } + + translated := translateConfigs(conf) + e.connector, err = connector.NewGatewayConnector(&translated, e, e.clock, e.lggr) + if err != nil { + return err + } + return e.connector.Start(ctx) + }) +} + +func (e *ServiceWrapper) Sign(data ...[]byte) ([]byte, error) { + return gwcommon.SignData(e.signerKey, data...) +} + +func (e *ServiceWrapper) Close() error { + return e.StopOnce("GatewayConnectorServiceWrapper", func() (err error) { + return e.connector.Close() + }) +} + +func (e *ServiceWrapper) HealthReport() map[string]error { + return map[string]error{e.Name(): e.Healthy()} +} + +func (e *ServiceWrapper) Name() string { + return "GatewayConnectorServiceWrapper" +} + +func (e *ServiceWrapper) GetGatewayConnector() connector.GatewayConnector { + return e.connector +} diff --git a/core/capabilities/gateway_connector/service_wrapper_test.go b/core/capabilities/gateway_connector/service_wrapper_test.go new file mode 100644 index 0000000000..ecbb896a8e --- /dev/null +++ b/core/capabilities/gateway_connector/service_wrapper_test.go @@ -0,0 +1,80 @@ +package gatewayconnector + +import ( + "crypto/ecdsa" + "testing" + + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" + ksmocks "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" +) + +func generateWrapper(t *testing.T, privateKey *ecdsa.PrivateKey, keystoreKey *ecdsa.PrivateKey) (*ServiceWrapper, error) { + logger := logger.TestLogger(t) + privateKeyV2 := ethkey.FromPrivateKey(privateKey) + addr := privateKeyV2.Address + keystoreKeyV2 := ethkey.FromPrivateKey(keystoreKey) + + config, err := chainlink.GeneralConfigOpts{ + Config: chainlink.Config{ + Core: toml.Core{ + Capabilities: toml.Capabilities{ + GatewayConnector: toml.GatewayConnector{ + ChainIDForNodeKey: ptr("1"), + NodeAddress: ptr(addr.Hex()), + DonID: ptr("5"), + WSHandshakeTimeoutMillis: ptr[uint32](100), + AuthMinChallengeLen: ptr[int](0), + AuthTimestampToleranceSec: ptr[uint32](10), + Gateways: []toml.ConnectorGateway{{ID: ptr("example_gateway"), URL: ptr("wss://localhost:8081/node")}}, + }, + }, + }, + }, + }.New() + ethKeystore := ksmocks.NewEth(t) + ethKeystore.On("EnabledKeysForChain", mock.Anything, mock.Anything).Return([]ethkey.KeyV2{keystoreKeyV2}, nil) + gc := config.Capabilities().GatewayConnector() + wrapper := NewGatewayConnectorServiceWrapper(gc, ethKeystore, clockwork.NewFakeClock(), logger) + require.NoError(t, err) + return wrapper, err +} + +func TestGatewayConnectorServiceWrapper_CleanStartClose(t *testing.T) { + t.Parallel() + + key, _ := testutils.NewPrivateKeyAndAddress(t) + wrapper, err := generateWrapper(t, key, key) + require.NoError(t, err) + + ctx := testutils.Context(t) + err = wrapper.Start(ctx) + require.NoError(t, err) + + t.Cleanup(func() { + assert.NoError(t, wrapper.Close()) + }) +} + +func TestGatewayConnectorServiceWrapper_NonexistentKey(t *testing.T) { + t.Parallel() + + key, _ := testutils.NewPrivateKeyAndAddress(t) + keystoreKey, _ := testutils.NewPrivateKeyAndAddress(t) + wrapper, err := generateWrapper(t, key, keystoreKey) + require.NoError(t, err) + + ctx := testutils.Context(t) + err = wrapper.Start(ctx) + require.Error(t, err) +} + +func ptr[T any](t T) *T { return &t } From 65924811dc53a211613927c814d7f04fd85439a4 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Wed, 11 Sep 2024 09:49:47 -0400 Subject: [PATCH 329/432] Fix CCIP Load Tests in Core Repo (#14268) * Fix CCIP Load Tests in Core Repo * Test debugging * Dirty fix * Callout ccip-load specifically * Error debugging * Build to directory * Target just ccip load test * Typo * Properly add Chainlink version * fix secrets * try increasing loki timeout * Fix loki creds * Typo * Put back PR debug * Remove debugs * Remove more debugs * Review comments * Remove Skipped test --- .github/workflows/ccip-load-tests.yml | 21 ++++++++++++------- integration-tests/ccip-tests/load/helper.go | 2 +- .../ccip-tests/smoke/ccip_test.go | 1 - .../contracts/ethereum_contracts.go | 4 ++-- integration-tests/load/README.md | 5 +++-- integration-tests/scripts/buildTests | 8 +++++-- integration-tests/test.Dockerfile | 1 + integration-tests/testconfig/README.md | 12 +++++++++-- integration-tests/testconfig/default.toml | 6 +++--- 9 files changed, 39 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ccip-load-tests.yml b/.github/workflows/ccip-load-tests.yml index fdf77067a5..93f18a3531 100644 --- a/.github/workflows/ccip-load-tests.yml +++ b/.github/workflows/ccip-load-tests.yml @@ -81,7 +81,7 @@ jobs: id-token: write contents: read name: Build Test Image - runs-on: ubuntu20.04-16cores-64GB + runs-on: ubuntu20.04-8cores-32GB steps: - name: Collect Metrics id: collect-gha-metrics @@ -102,6 +102,7 @@ jobs: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + suites: ccip-load ccip-load-test: environment: integration @@ -127,10 +128,11 @@ jobs: - name: stable-load run: ^TestLoadCCIPStableRPS$ os: ubuntu-latest - - name: load-with-arm-curse-uncurse - run: ^TestLoadCCIPStableRPSAfterARMCurseAndUncurse$ - config_path: ./integration-tests/ccip-tests/testconfig/tomls/load-with-arm-curse-uncurse.toml - os: ubuntu-latest + # Enable when CCIP-2277 is resolved + # - name: load-with-arm-curse-uncurse + # run: ^TestLoadCCIPStableRPSAfterARMCurseAndUncurse$ + # config_path: ./integration-tests/ccip-tests/testconfig/tomls/load-with-arm-curse-uncurse.toml + # os: ubuntu-latest runs-on: ${{ matrix.type.os }} name: CCIP ${{ matrix.type.name }} steps: @@ -189,13 +191,16 @@ jobs: RR_CPU: 4 TEST_TRIGGERED_BY: ccip-load-test-ci-${{ matrix.type.name }} BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} - TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} + TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }},${{ steps.set_override_config.outputs.base_64_override }} + E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} E2E_TEST_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - E2E_TEST_LOKI_TENANT_ID: ${{ vars.LOKI_TENANT_ID }} + E2E_TEST_CHAINLINK_VERSION: ${{ env.CHAINLINK_VERSION }} + E2E_TEST_LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} E2E_TEST_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} E2E_TEST_GRAFANA_BASE_URL: ${{ vars.GRAFANA_URL }} E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" + E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} with: test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 70m -count=1 -json -run ${{ matrix.type.run }} ./load 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -295,4 +300,4 @@ jobs: slack_bot_token: ${{ secrets.QA_SLACK_API_KEY }} slack_thread_ts: ${{ needs.start-slack-thread.outputs.thread_ts }} - # End Reporting Jobs \ No newline at end of file + # End Reporting Jobs diff --git a/integration-tests/ccip-tests/load/helper.go b/integration-tests/ccip-tests/load/helper.go index 287bf2cf0f..e4ee4573b2 100644 --- a/integration-tests/ccip-tests/load/helper.go +++ b/integration-tests/ccip-tests/load/helper.go @@ -308,7 +308,7 @@ func (l *LoadArgs) TriggerLoadByLane() { } waspCfg.LokiConfig.Timeout = time.Minute loadRunner, err := wasp.NewGenerator(waspCfg) - require.NoError(l.TestCfg.Test, err, "initiating loadgen for lane %s --> %s", + require.NoError(l.TestCfg.Test, err, "error while initiating loadgen for lane %s --> %s", lane.SourceNetworkName, lane.DestNetworkName) loadRunner.Run(false) l.AddToRunnerGroup(loadRunner) diff --git a/integration-tests/ccip-tests/smoke/ccip_test.go b/integration-tests/ccip-tests/smoke/ccip_test.go index e411c17acd..db6972c9e7 100644 --- a/integration-tests/ccip-tests/smoke/ccip_test.go +++ b/integration-tests/ccip-tests/smoke/ccip_test.go @@ -1004,5 +1004,4 @@ func testOffRampRateLimits(t *testing.T, rateLimiterConfig contracts.RateLimiter require.NoError(t, err, "Error manually executing transaction after rate limit is lifted") }) } - } diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index c77b5e9bd8..c2f86286fa 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -715,9 +715,9 @@ func (e *EthereumOffchainAggregatorV2) SetConfig(ocrConfig *OCRv2Config) error { Interface("Signers", ocrConfig.Signers). Interface("Transmitters", ocrConfig.Transmitters). Uint8("F", ocrConfig.F). - Bytes("OnchainConfig", ocrConfig.OnchainConfig). + Str("OnchainConfig", string(ocrConfig.OnchainConfig)). Uint64("OffchainConfigVersion", ocrConfig.OffchainConfigVersion). - Bytes("OffchainConfig", ocrConfig.OffchainConfig). + Str("OffchainConfig", string(ocrConfig.OffchainConfig)). Msg("Setting OCRv2 Config") _, err := e.client.Decode(e.contract.SetConfig( diff --git a/integration-tests/load/README.md b/integration-tests/load/README.md index 46ea491c21..359de3c6d4 100644 --- a/integration-tests/load/README.md +++ b/integration-tests/load/README.md @@ -70,8 +70,10 @@ Gun should be working with one instance of your product. VU(Virtual user) creates a new instance of your product and works with it in `Call()` ### Cluster mode (k8s) + Add configuration to `overrides.toml` -``` + +```toml [WaspAutoBuild] namespace = "wasp" update_image = true @@ -84,5 +86,4 @@ wasp_jobs = "1" keep_jobs = true ``` - And run your tests using `go test -v -run TestClusterEntrypoint` diff --git a/integration-tests/scripts/buildTests b/integration-tests/scripts/buildTests index b6033c1c41..04e9cea94b 100755 --- a/integration-tests/scripts/buildTests +++ b/integration-tests/scripts/buildTests @@ -8,7 +8,7 @@ set -ex # get this scripts directory SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) -cd "$SCRIPT_DIR"/../ || exit 1 +cd "$SCRIPT_DIR"/../ || { echo "Error: Failed to change directory to $SCRIPT_DIR/../"; exit 1; } helm repo update @@ -23,7 +23,11 @@ for x in $tosplit do if [ "$x" = "load" ]; then echo "Changing directory and executing go test -c ./... for 'load' package" - pushd "./load" && go test -c -tags embed -o .. ./... + pushd "./load" && go test -c -tags embed -o ../ ./... + popd + elif [ "$x" = "ccip-load" ]; then + echo "Changing directory and executing go test -c ./... for 'ccip-load' package" + pushd "./ccip-tests/load" && go test -c -tags embed -o ../ ./... popd else go test -c -tags embed ./"${x}" diff --git a/integration-tests/test.Dockerfile b/integration-tests/test.Dockerfile index 2e928ab29f..41fe331583 100644 --- a/integration-tests/test.Dockerfile +++ b/integration-tests/test.Dockerfile @@ -13,6 +13,7 @@ FROM ${BASE_IMAGE}:${IMAGE_VERSION} RUN mkdir -p /go/testdir/integration-tests/scripts COPY --from=build-env /go/pkg /go/pkg COPY --from=build-env /go/testdir/integration-tests/*.test /go/testdir/integration-tests/ +COPY --from=build-env /go/testdir/integration-tests/ccip-tests/*.test /go/testdir/integration-tests/ COPY --from=build-env /go/testdir/integration-tests/scripts /go/testdir/integration-tests/scripts/ ENTRYPOINT ["/go/testdir/integration-tests/scripts/entrypoint"] diff --git a/integration-tests/testconfig/README.md b/integration-tests/testconfig/README.md index 9055cff2cb..2959c1af02 100644 --- a/integration-tests/testconfig/README.md +++ b/integration-tests/testconfig/README.md @@ -23,9 +23,11 @@ The order of precedence for overrides is as follows: * [Environment variable `BASE64_CONFIG_OVERRIDE`](#base64_config_override) ### default.toml + That file is envisioned to contain fundamental and universally applicable settings, such as logging configurations, private Ethereum network settings or Seth networks settings for known networks. ### Product-specific configurations + Product-specific configurations, such as those in `[product_name].toml`, house the bulk of default and variant settings, supporting default configurations like the following in `log_poller.toml`, which should be used by all Log Poller tests: ```toml @@ -47,6 +49,7 @@ max_emit_wait_time_ms = 500 ``` ### overrides.toml + This file is recommended for local use to adjust dynamic variables or modify predefined settings. At the very minimum it should contain the Chainlink image and version, as shown in the example below: ```toml @@ -55,6 +58,7 @@ version = "your tag" ``` ### `BASE64_CONFIG_OVERRIDE` + This environment variable is primarily intended for use in continuous integration environments, enabling the substitution of default settings with confidential or user-specific parameters. For instance: ```bash @@ -78,6 +82,7 @@ BASE64_CONFIG_OVERRIDE=$(cat config.toml | base64 -w 0) echo ::add-mask::$BASE64_CONFIG_OVERRIDE echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV ``` + **It is highly recommended to use reusable GHA actions present in [.actions](../../../.github/.actions) to generate and apply the base64-encoded configuration.** Own implementation of `BASE64_CONFIG_OVERRIDE` generation is discouraged and should be used only if existing actions do not cover the use case. But even in that case it might be a better idea to extend existing actions. This variable is automatically relayed to Kubernetes-based tests, eliminating the need for manual intervention in test scripts. @@ -89,7 +94,7 @@ For detailed instructions on how to set test secrets both locally and within CI ### All test secrets -See [All E2E Test Secrets in CTF](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md#all-e2e-test-secrets). +See [All E2E Test Secrets in CTF](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md#all-e2e-test-secrets). ### Core repo specific test secrets @@ -99,7 +104,6 @@ See [All E2E Test Secrets in CTF](https://github.com/smartcontractkit/chainlink- | Data Streams Username | `E2E_TEST_DATA_STREAMS_USERNAME` | `E2E_TEST_DATA_STREAMS_USERNAME=username` | Required by some automation tests to connect to data streams. | | Data Streams Password | `E2E_TEST_DATA_STREAMS_PASSWORD` | `E2E_TEST_DATA_STREAMS_PASSWORD=password` | Required by some automation tests to connect to data streams. | - ## Named Configurations Named configurations allow for the customization of settings through unique identifiers, such as a test name or type, acting as specific overrides. Here's how you can define and use these configurations: @@ -127,6 +131,7 @@ When processing TOML files, the system initially searches for a general (unnamed Find default node config in `testconfig/default.toml` To set custom config for Chainlink Node use `NodeConfig.BaseConfigTOML` in TOML. Example: + ```toml [NodeConfig] BaseConfigTOML = """ @@ -147,12 +152,14 @@ Enabled = true DefaultTransactionQueueDepth = 0 """ ``` + Note that you cannot override individual values in BaseConfigTOML. You must provide the entire configuration. This corresponds to [Config struct](../../core/services/chainlink/config.go) in Chainlink Node that excludes all chain-specific configuration, which is built based on selected_networks and either Chainlink Node's defaults for each network, or `ChainConfigTOMLByChainID` (if an entry with matching chain id is defined) or `CommonChainConfigTOML` (if no entry with matching chain id is defined). If BaseConfigTOML is empty, then default base config provided by the Chainlink Node is used. If tracing is enabled unique id will be generated and shared between all Chainlink nodes in the same test. To set base config for EVM chains use `NodeConfig.CommonChainConfigTOML`. Example: + ```toml CommonChainConfigTOML = """ AutoCreateKey = true @@ -169,6 +176,7 @@ FeeCapDefault = '200 gwei' This is the default configuration used for all EVM chains unless `ChainConfigTOMLByChainID` is specified. Do remember that if either `ChainConfigTOMLByChainID` or `CommonChainConfigTOML` is defined, it will override any defaults that Chainlink Node might have for the given network. Part of the configuration that defines blockchain node URLs is always dynamically generated based on the EVMNetwork configuration. To set custom per-chain config use `[NodeConfig.ChainConfigTOMLByChainID]`. Example: + ```toml [NodeConfig.ChainConfigTOMLByChainID] # applicable only to arbitrum-goerli chain diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index f1dd65c5a8..5ce1f2b3f6 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -322,11 +322,11 @@ eip_1559_dynamic_fees = true # automated gas estimation for live networks # if set to true we will dynamically estimate gas for every transaction (based on suggested values, priority and congestion rate for last X blocks) - gas_price_estimation_enabled = true +gas_price_estimation_enabled = true # number of blocks to use for congestion rate estimation (it will determine buffer added on top of suggested values) - gas_price_estimation_blocks = 100 +gas_price_estimation_blocks = 100 # transaction priority, which determines adjustment factor multiplier applied to suggested values (fast - 1.2x, standard - 1x, slow - 0.8x) - gas_price_estimation_tx_priority = "standard" +gas_price_estimation_tx_priority = "standard" # URLs # if set they will overwrite URLs from EVMNetwork that Seth uses, can be either WS(S) or HTTP(S) From b9d95c5fb1cd49c2f195bff992dcf5fb1d75e0ad Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Wed, 11 Sep 2024 16:35:31 +0200 Subject: [PATCH 330/432] Update STYLE_GUIDE.md (#14402) --- contracts/STYLE_GUIDE.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/STYLE_GUIDE.md b/contracts/STYLE_GUIDE.md index c5dc20abea..f29c129bd0 100644 --- a/contracts/STYLE_GUIDE.md +++ b/contracts/STYLE_GUIDE.md @@ -219,7 +219,8 @@ The original error will not be human-readable in an off-chain explorer because i - Otherwise, Solidity contracts should have a pragma that is locked to a specific version. - Example: Most concrete contracts. - Avoid changing pragmas after the audit. Unless there is a bug that affects your contract, then you should try to stick to a known good pragma. In practice, this means we typically only support one (occasionally two) pragma for any “major”(minor by Semver naming) Solidity version. -- The current advised pragma is `0.8.19` or higher, lower versions should be avoided when starting a new project. Newer versions can be considered. +- The current advised pragma is `0.8.24`, lower versions should be avoided when starting a new project. Newer versions can be considered. + - Explicitly use the `Paris` hardfork when compiling with 0.8.24 to keep the bytecode compatible with all chains. - All contracts should have an SPDX license identifier. If unsure about which one to pick, please consult with legal. Most older contracts have been MIT, but some of the newer products have been using BUSL-1.1 @@ -263,8 +264,8 @@ contract SuperDuperAggregator is ITypeAndVersion { All contracts will expose a `typeAndVersion` constant. The string has the following format: `-` with the `-dev` part only being applicable to contracts that have not been fully released. Try to fit it into 32 bytes to keep the impact on contract sizes minimal. -Solhint will complain about a public constant variable that isn’t FULL_CAPS without the solhint-disable comment. +Note that `ITypeAndVersion` should be used, not `TypeAndVersionInterface`. From bfb66fa59524e111c52c4a92d7e7e83106dec396 Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Wed, 11 Sep 2024 08:27:05 -0700 Subject: [PATCH 331/432] [CAPPL-20] Pass GatewayConnector to standard capability Delegate (#14397) Add a placeholder for one of the new Web API capabilities. --- .../gateway_connector/service_wrapper_test.go | 7 ++-- core/capabilities/webapi/trigger.go | 18 +++++++++ core/services/chainlink/application.go | 15 ++++++- .../services/standardcapabilities/delegate.go | 40 ++++++++++++++----- 4 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 core/capabilities/webapi/trigger.go diff --git a/core/capabilities/gateway_connector/service_wrapper_test.go b/core/capabilities/gateway_connector/service_wrapper_test.go index ecbb896a8e..c88622fcd2 100644 --- a/core/capabilities/gateway_connector/service_wrapper_test.go +++ b/core/capabilities/gateway_connector/service_wrapper_test.go @@ -1,4 +1,4 @@ -package gatewayconnector +package gatewayconnector_test import ( "crypto/ecdsa" @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + gatewayconnector "github.com/smartcontractkit/chainlink/v2/core/capabilities/gateway_connector" "github.com/smartcontractkit/chainlink/v2/core/config/toml" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -17,7 +18,7 @@ import ( ksmocks "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" ) -func generateWrapper(t *testing.T, privateKey *ecdsa.PrivateKey, keystoreKey *ecdsa.PrivateKey) (*ServiceWrapper, error) { +func generateWrapper(t *testing.T, privateKey *ecdsa.PrivateKey, keystoreKey *ecdsa.PrivateKey) (*gatewayconnector.ServiceWrapper, error) { logger := logger.TestLogger(t) privateKeyV2 := ethkey.FromPrivateKey(privateKey) addr := privateKeyV2.Address @@ -43,7 +44,7 @@ func generateWrapper(t *testing.T, privateKey *ecdsa.PrivateKey, keystoreKey *ec ethKeystore := ksmocks.NewEth(t) ethKeystore.On("EnabledKeysForChain", mock.Anything, mock.Anything).Return([]ethkey.KeyV2{keystoreKeyV2}, nil) gc := config.Capabilities().GatewayConnector() - wrapper := NewGatewayConnectorServiceWrapper(gc, ethKeystore, clockwork.NewFakeClock(), logger) + wrapper := gatewayconnector.NewGatewayConnectorServiceWrapper(gc, ethKeystore, clockwork.NewFakeClock(), logger) require.NoError(t, err) return wrapper, err } diff --git a/core/capabilities/webapi/trigger.go b/core/capabilities/webapi/trigger.go new file mode 100644 index 0000000000..db0df7d141 --- /dev/null +++ b/core/capabilities/webapi/trigger.go @@ -0,0 +1,18 @@ +package webapi + +import ( + "github.com/smartcontractkit/chainlink-common/pkg/types/core" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" + "github.com/smartcontractkit/chainlink/v2/core/services/job" +) + +func NewTrigger(config string, registry core.CapabilitiesRegistry, connector connector.GatewayConnector, lggr logger.Logger) (job.ServiceCtx, error) { + // TODO (CAPPL-22, CAPPL-24): + // - decode config + // - create an implementation of the capability API and add it to the Registry + // - create a handler and register it with Gateway Connector + // - manage trigger subscriptions + // - process incoming trigger events and related metadata + return nil, nil +} diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 244d5da13d..1c498f4073 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -28,6 +28,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/build" "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip" + gatewayconnector "github.com/smartcontractkit/chainlink/v2/core/capabilities/gateway_connector" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -265,6 +266,17 @@ func NewApplication(opts ApplicationOpts) (Application, error) { opts.CapabilitiesRegistry.SetLocalRegistry(&capabilities.TestMetadataRegistry{}) } + var gatewayConnectorWrapper *gatewayconnector.ServiceWrapper + if cfg.Capabilities().GatewayConnector().DonID() != "" { + globalLogger.Debugw("Creating GatewayConnector wrapper", "donID", cfg.Capabilities().GatewayConnector().DonID()) + gatewayConnectorWrapper = gatewayconnector.NewGatewayConnectorServiceWrapper( + cfg.Capabilities().GatewayConnector(), + keyStore.Eth(), + clockwork.NewRealClock(), + globalLogger) + srvcs = append(srvcs, gatewayConnectorWrapper) + } + // LOOPs can be created as options, in the case of LOOP relayers, or // as OCR2 job implementations, in the case of Median today. // We will have a non-nil registry here in LOOP relayers are being used, otherwise @@ -445,7 +457,8 @@ func NewApplication(opts ApplicationOpts) (Application, error) { loopRegistrarConfig, telemetryManager, pipelineRunner, - opts.RelayerChainInteroperators), + opts.RelayerChainInteroperators, + gatewayConnectorWrapper), } webhookJobRunner = delegates[job.Webhook].(*webhook.Delegate).WebhookJobRunner() ) diff --git a/core/services/standardcapabilities/delegate.go b/core/services/standardcapabilities/delegate.go index d072c94846..64134995b2 100644 --- a/core/services/standardcapabilities/delegate.go +++ b/core/services/standardcapabilities/delegate.go @@ -12,6 +12,8 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" + gatewayconnector "github.com/smartcontractkit/chainlink/v2/core/capabilities/gateway_connector" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/webapi" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/generic" @@ -26,23 +28,28 @@ type RelayGetter interface { } type Delegate struct { - logger logger.Logger - ds sqlutil.DataSource - jobORM job.ORM - registry core.CapabilitiesRegistry - cfg plugins.RegistrarConfig - monitoringEndpointGen telemetry.MonitoringEndpointGenerator - pipelineRunner pipeline.Runner - relayers RelayGetter + logger logger.Logger + ds sqlutil.DataSource + jobORM job.ORM + registry core.CapabilitiesRegistry + cfg plugins.RegistrarConfig + monitoringEndpointGen telemetry.MonitoringEndpointGenerator + pipelineRunner pipeline.Runner + relayers RelayGetter + gatewayConnectorWrapper *gatewayconnector.ServiceWrapper isNewlyCreatedJob bool } +const ( + commandOverrideForWebAPITrigger = "__builtin_web-api-trigger" +) + func NewDelegate(logger logger.Logger, ds sqlutil.DataSource, jobORM job.ORM, registry core.CapabilitiesRegistry, cfg plugins.RegistrarConfig, monitoringEndpointGen telemetry.MonitoringEndpointGenerator, pipelineRunner pipeline.Runner, - relayers RelayGetter) *Delegate { + relayers RelayGetter, gatewayConnectorWrapper *gatewayconnector.ServiceWrapper) *Delegate { return &Delegate{logger: logger, ds: ds, jobORM: jobORM, registry: registry, cfg: cfg, monitoringEndpointGen: monitoringEndpointGen, pipelineRunner: pipelineRunner, - relayers: relayers, isNewlyCreatedJob: false} + relayers: relayers, isNewlyCreatedJob: false, gatewayConnectorWrapper: gatewayConnectorWrapper} } func (d *Delegate) JobType() job.Type { @@ -67,6 +74,19 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) ([]job.Ser return nil, fmt.Errorf("failed to create relayer set: %w", err) } + // NOTE: special cases for built-in capabilities (to be moved into LOOPPs in the future) + if spec.StandardCapabilitiesSpec.Command == commandOverrideForWebAPITrigger { + if d.gatewayConnectorWrapper == nil { + return nil, errors.New("gateway connector is required for web API Trigger capability") + } + connector := d.gatewayConnectorWrapper.GetGatewayConnector() + triggerSrvc, err := webapi.NewTrigger(spec.StandardCapabilitiesSpec.Config, d.registry, connector, log) + if err != nil { + return nil, fmt.Errorf("failed to create a Web API Trigger service: %w", err) + } + return []job.ServiceCtx{triggerSrvc}, nil + } + standardCapability := newStandardCapabilities(log, spec.StandardCapabilitiesSpec, d.cfg, telemetryService, kvStore, d.registry, errorLog, pr, relayerSet) From bd62d0d0d03cf74e361d2246d7817ffdb1423d0d Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Wed, 11 Sep 2024 11:09:06 -0700 Subject: [PATCH 332/432] Add better error handling (#14395) --- .github/scripts/jira/axios.ts | 97 +++++++++++++++++++ .../scripts/jira/create-jira-traceability.ts | 26 +++-- .github/scripts/jira/enforce-jira-issue.ts | 4 +- .github/scripts/jira/lib.ts | 18 +++- .github/scripts/jira/package.json | 3 + .github/scripts/jira/pnpm-lock.yaml | 11 ++- .github/scripts/jira/tsconfig.json | 2 +- 7 files changed, 145 insertions(+), 16 deletions(-) create mode 100644 .github/scripts/jira/axios.ts diff --git a/.github/scripts/jira/axios.ts b/.github/scripts/jira/axios.ts new file mode 100644 index 0000000000..3a91279771 --- /dev/null +++ b/.github/scripts/jira/axios.ts @@ -0,0 +1,97 @@ +import { + AxiosRequestConfig, + AxiosResponse, + AxiosError, + InternalAxiosRequestConfig, +} from "axios"; +import { Readable } from "stream"; + +interface AxiosErrorFormat { + config: Pick; + code?: string; + response: Partial, (typeof RESPONSE_KEYS)[number]>>; + isAxiosError: boolean; +} + +interface AxiosErrorFormatError + extends Error, + AxiosErrorFormat {} + +export function formatAxiosError( + origErr: AxiosError +): AxiosErrorFormatError { + const { message, name, stack, code, config, response, isAxiosError } = + origErr; + + const err: AxiosErrorFormatError = { + ...new Error(message), + name, + stack, + code, + isAxiosError, + config: {}, + response: {}, + }; + + for (const k of CONFIG_KEYS) { + if (config?.[k] === undefined) { + continue; + } + + err.config[k] = formatValue(config[k], k); + } + + for (const k of RESPONSE_KEYS) { + if (response?.[k] === undefined) { + continue; + } + + err.response[k] = formatValue(response[k], k); + } + + return err as any; +} + +const CONFIG_KEYS: (keyof InternalAxiosRequestConfig)[] = [ + "url", + "method", + "baseURL", + "params", + "data", + "timeout", + "timeoutErrorMessage", + "withCredentials", + "auth", + "responseType", + "xsrfCookieName", + "xsrfHeaderName", + "maxContentLength", + "maxBodyLength", + "maxRedirects", + "socketPath", + "proxy", + "decompress", +] as const; + +const RESPONSE_KEYS: (keyof AxiosResponse)[] = [ + "data", + "status", + "statusText", +] as const; + +function formatValue( + value: any, + key: (typeof CONFIG_KEYS)[number] | (typeof RESPONSE_KEYS)[number] +): any { + if (key !== "data") { + return value; + } + + if (process.env.BROWSER !== "true") { + if (value instanceof Readable) { + return "[Readable]"; + } + } + + return value; +} diff --git a/.github/scripts/jira/create-jira-traceability.ts b/.github/scripts/jira/create-jira-traceability.ts index b151c9d5ea..cda038a7cc 100644 --- a/.github/scripts/jira/create-jira-traceability.ts +++ b/.github/scripts/jira/create-jira-traceability.ts @@ -5,6 +5,7 @@ import { generateIssueLabel, generateJiraIssuesLink, getJiraEnvVars, + handleError, } from "./lib"; import * as core from "@actions/core"; @@ -191,15 +192,24 @@ async function main() { const client = createJiraClient(); const label = generateIssueLabel(product, baseRef, headRef); - await addTraceabillityToJiraIssues( - client, - jiraIssueNumbers, - label, - artifactUrl - ); + try { + await addTraceabillityToJiraIssues( + client, + jiraIssueNumbers, + label, + artifactUrl + ); + } catch (e) { + handleError(e); - const { jiraHost } = getJiraEnvVars() - core.summary.addLink("Jira Issues", generateJiraIssuesLink(`${jiraHost}/issues/`, label)); + process.exit(1); + } + + const { jiraHost } = getJiraEnvVars(); + core.summary.addLink( + "Jira Issues", + generateJiraIssuesLink(`${jiraHost}/issues/`, label) + ); core.summary.write(); } main(); diff --git a/.github/scripts/jira/enforce-jira-issue.ts b/.github/scripts/jira/enforce-jira-issue.ts index 9d8c6e490e..153f397e02 100644 --- a/.github/scripts/jira/enforce-jira-issue.ts +++ b/.github/scripts/jira/enforce-jira-issue.ts @@ -1,6 +1,6 @@ import * as core from "@actions/core"; import jira from "jira.js"; -import { createJiraClient, getGitTopLevel, parseIssueNumberFrom } from "./lib"; +import { createJiraClient, getGitTopLevel, handleError, parseIssueNumberFrom } from "./lib"; import { promises as fs } from "fs"; import { join } from "path"; @@ -36,7 +36,7 @@ async function doesIssueExist( return true; } catch (e) { - core.debug(e as any); + handleError(e) return false; } } diff --git a/.github/scripts/jira/lib.ts b/.github/scripts/jira/lib.ts index 0d0983f5c3..8be295ab14 100644 --- a/.github/scripts/jira/lib.ts +++ b/.github/scripts/jira/lib.ts @@ -4,7 +4,8 @@ import * as jira from "jira.js"; import { exec } from "child_process"; import { promisify } from "util"; import { join } from "path"; - +import { isAxiosError } from "axios"; +import { formatAxiosError } from "./axios"; export function generateJiraIssuesLink(baseUrl: string, label: string) { // https://smartcontract-it.atlassian.net/issues/?jql=labels%20%3D%20%22review-artifacts-automation-base%3A8d818ea265ff08887e61ace4f83364a3ee149ef0-head%3A3c45b71f3610de28f429cef0163936eaa448e63c%22 const jqlQuery = `labels = "${label}"`; @@ -129,3 +130,18 @@ export function createJiraClient() { }, }); } + +export function handleError(e: unknown) { + if (e instanceof Error) { + if (isAxiosError(e)) { + core.error(formatAxiosError(e)); + } else if (isAxiosError(e.cause)) { + core.error(formatAxiosError(e.cause)); + } else { + core.error(e); + } + } else { + core.error(JSON.stringify(e)); + } + core.setFailed("Error adding traceability to Jira issues"); +} diff --git a/.github/scripts/jira/package.json b/.github/scripts/jira/package.json index 94a805314a..6081e48981 100644 --- a/.github/scripts/jira/package.json +++ b/.github/scripts/jira/package.json @@ -27,5 +27,8 @@ "@types/node": "^20.14.10", "typescript": "^5.5.3", "vitest": "^2.0.3" + }, + "peerDependencies": { + "axios": "^1.7.7" } } diff --git a/.github/scripts/jira/pnpm-lock.yaml b/.github/scripts/jira/pnpm-lock.yaml index 4deeef7f33..a52fa9dd0c 100644 --- a/.github/scripts/jira/pnpm-lock.yaml +++ b/.github/scripts/jira/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@actions/core': specifier: ^1.10.1 version: 1.10.1 + axios: + specifier: ^1.7.7 + version: 1.7.7 jira.js: specifier: ^4.0.1 version: 4.0.1 @@ -311,8 +314,8 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - axios@1.7.2: - resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} @@ -811,7 +814,7 @@ snapshots: asynckit@0.4.0: {} - axios@1.7.2: + axios@1.7.7: dependencies: follow-redirects: 1.15.6 form-data: 4.0.0 @@ -918,7 +921,7 @@ snapshots: jira.js@4.0.1: dependencies: - axios: 1.7.2 + axios: 1.7.7 form-data: 4.0.0 tslib: 2.6.3 transitivePeerDependencies: diff --git a/.github/scripts/jira/tsconfig.json b/.github/scripts/jira/tsconfig.json index 746f76774b..3e3216e6e0 100644 --- a/.github/scripts/jira/tsconfig.json +++ b/.github/scripts/jira/tsconfig.json @@ -11,7 +11,7 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "ES2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ From 28989b30d94bbd3490330cd8e50e7d9223d33cff Mon Sep 17 00:00:00 2001 From: ilija42 <57732589+ilija42@users.noreply.github.com> Date: Wed, 11 Sep 2024 22:33:22 +0200 Subject: [PATCH 333/432] [BCF-3381] - Implement changeset LatestHead #521 (#14394) * Implement ChainSet LatestHead * Update relayer references * lint * Add changest * Update Solana ref * Change Latest Head to use latestChain.BlockNumber() for Head Identifier * Handle potential nil value in LatestHead * Update common and feeds refs * Update ccip and common refs * Update relayers refs * Update solana ref * minor fix * minor fix * Update cosmos ref * Update relayers and common refs * run generate --- .changeset/polite-numbers-exercise.md | 5 ++ core/chains/chain_kv_test.go | 5 ++ core/chains/legacyevm/chain.go | 14 +++++ core/chains/legacyevm/mocks/chain.go | 56 +++++++++++++++++++ core/scripts/go.mod | 12 ++-- core/scripts/go.sum | 24 ++++---- .../ocr2/plugins/generic/relayerset_test.go | 4 ++ core/services/relay/dummy/relayer.go | 3 + .../relay/evm/mocks/loop_relay_adapter.go | 56 +++++++++++++++++++ core/services/relay/evm/read/event.go | 6 +- core/services/relay/evm/relayer_extender.go | 4 ++ core/web/testutils/mock_relayer.go | 5 ++ go.md | 1 + go.mod | 12 ++-- go.sum | 24 ++++---- integration-tests/go.mod | 12 ++-- integration-tests/go.sum | 24 ++++---- integration-tests/load/go.mod | 12 ++-- integration-tests/load/go.sum | 24 ++++---- 19 files changed, 228 insertions(+), 75 deletions(-) create mode 100644 .changeset/polite-numbers-exercise.md diff --git a/.changeset/polite-numbers-exercise.md b/.changeset/polite-numbers-exercise.md new file mode 100644 index 0000000000..2adcdf305b --- /dev/null +++ b/.changeset/polite-numbers-exercise.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#internal Implement LatestHead for ChainService diff --git a/core/chains/chain_kv_test.go b/core/chains/chain_kv_test.go index 205ee693d6..7c9336285e 100644 --- a/core/chains/chain_kv_test.go +++ b/core/chains/chain_kv_test.go @@ -89,6 +89,11 @@ func (s *testChainService) HealthReport() map[string]error { return map[string]error{} } +// Implement [types.LatestHead] interface +func (s *testChainService) LatestHead(_ context.Context) (head types.Head, err error) { + return +} + // Implement [types.ChainService] interface func (s *testChainService) GetChainStatus(ctx context.Context) (stat types.ChainStatus, err error) { return diff --git a/core/chains/legacyevm/chain.go b/core/chains/legacyevm/chain.go index 0bfd0a5b1d..f826e9576c 100644 --- a/core/chains/legacyevm/chain.go +++ b/core/chains/legacyevm/chain.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "math/big" + "strconv" gotoml "github.com/pelletier/go-toml/v2" "go.uber.org/multierr" @@ -393,6 +394,19 @@ func (c *chain) SendTx(ctx context.Context, from, to string, amount *big.Int, ba return c.Transact(ctx, from, to, amount, balanceCheck) } +func (c *chain) LatestHead(_ context.Context) (types.Head, error) { + latestChain := c.headTracker.LatestChain() + if latestChain == nil { + return types.Head{}, errors.New("latest chain not found") + } + + return types.Head{ + Height: strconv.FormatInt(latestChain.BlockNumber(), 10), + Hash: latestChain.Hash.Bytes(), + Timestamp: uint64(latestChain.Timestamp.Unix()), + }, nil +} + func (c *chain) GetChainStatus(ctx context.Context) (types.ChainStatus, error) { toml, err := c.cfg.EVM().TOMLString() if err != nil { diff --git a/core/chains/legacyevm/mocks/chain.go b/core/chains/legacyevm/mocks/chain.go index 777212108c..3c6bd97d7a 100644 --- a/core/chains/legacyevm/mocks/chain.go +++ b/core/chains/legacyevm/mocks/chain.go @@ -523,6 +523,62 @@ func (_c *Chain_ID_Call) RunAndReturn(run func() *big.Int) *Chain_ID_Call { return _c } +// LatestHead provides a mock function with given fields: ctx +func (_m *Chain) LatestHead(ctx context.Context) (types.Head, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for LatestHead") + } + + var r0 types.Head + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (types.Head, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) types.Head); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(types.Head) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Chain_LatestHead_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestHead' +type Chain_LatestHead_Call struct { + *mock.Call +} + +// LatestHead is a helper method to define mock.On call +// - ctx context.Context +func (_e *Chain_Expecter) LatestHead(ctx interface{}) *Chain_LatestHead_Call { + return &Chain_LatestHead_Call{Call: _e.mock.On("LatestHead", ctx)} +} + +func (_c *Chain_LatestHead_Call) Run(run func(ctx context.Context)) *Chain_LatestHead_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *Chain_LatestHead_Call) Return(_a0 types.Head, _a1 error) *Chain_LatestHead_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Chain_LatestHead_Call) RunAndReturn(run func(context.Context) (types.Head, error)) *Chain_LatestHead_Call { + _c.Call.Return(run) + return _c +} + // ListNodeStatuses provides a mock function with given fields: ctx, pageSize, pageToken func (_m *Chain) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) ([]types.NodeStatus, string, int, error) { ret := _m.Called(ctx, pageSize, pageToken) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index f4f2e3a32f..40c921d72c 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.20.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.1 @@ -270,13 +270,13 @@ require ( github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect - github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 // indirect + github.com/smartcontractkit/chain-selectors v1.0.23 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd // indirect - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 // indirect + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index cac4c2cb3d..ab7a6c118f 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1075,24 +1075,24 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1WonwhVOPtOStpqTmLC4E= -github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= +github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnjjIQAEBnutCtksPzVDY= +github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1:siC6AoTs4889FwiqgEp0sC6S8nFlDzVTZAmUX7cV7aM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 h1:9SkeP9lpTMDqtqDd+BKPQhkPcylSoYi63L9YFdbzbEo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 h1:xow5cYrWxRmzTwhz2AjWOlnI9WRF4O5b84bXm1k292E= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227/go.mod h1:DUFantPYoBGwBSkNVt2k4ZJi0jPKRRrZVVlAzcZwreA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 h1:BPuehkAQ8R112SlTitukSdKYRJMY3zkvaQS4VSTNn0Q= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa h1:vG4aRggHzNDFTmMFemhhUAzqTfG159w0+RYjO7/cJ5E= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd h1:+RFI4mgXSGEcn847e7bavhQCqaBiW142g1XfGzijFoY= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd/go.mod h1:Ou79geDZKg87CgRi0BTQpRhUT3U6LcrQWuGQveDRvlg= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 h1:Tkl0/SB1hxjBgphslHf1E6iXp+4QAejuCLIT+8zvX3Y= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3/go.mod h1:mkuwCChesVqzMQpYQWRwckmQobJLwG4XCsw7KB8UCKY= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 h1:JPs35oSO07PK3Qv7Kyv0GJHVLacIE1IkrvefaPyBjKs= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664/go.mod h1:iJ9DKYo0F64ue7IogAIELwU2DfrhEAh76eSmZOilT8A= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae h1:d+B8y2Nd/PrnPMNoaSPn3eDgUgxcVcIqAxGrvYu/gGw= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= diff --git a/core/services/ocr2/plugins/generic/relayerset_test.go b/core/services/ocr2/plugins/generic/relayerset_test.go index b5eb16682d..44ed216520 100644 --- a/core/services/ocr2/plugins/generic/relayerset_test.go +++ b/core/services/ocr2/plugins/generic/relayerset_test.go @@ -158,6 +158,10 @@ func (t *TestRelayer) NewContractReader(_ context.Context, _ []byte) (types.Cont panic("implement me") } +func (t *TestRelayer) LatestHead(_ context.Context) (types.Head, error) { + panic("implement me") +} + func (t *TestRelayer) GetChainStatus(ctx context.Context) (types.ChainStatus, error) { panic("implement me") } diff --git a/core/services/relay/dummy/relayer.go b/core/services/relay/dummy/relayer.go index cf3aa732c4..a9b90b9a2f 100644 --- a/core/services/relay/dummy/relayer.go +++ b/core/services/relay/dummy/relayer.go @@ -64,6 +64,9 @@ func (r *relayer) NewLLOProvider(ctx context.Context, rargs types.RelayArgs, par } return NewLLOProvider(r.lggr, cp, transmitter, cdc), nil } +func (r *relayer) LatestHead(_ context.Context) (types.Head, error) { + return types.Head{}, nil +} func (r *relayer) GetChainStatus(ctx context.Context) (types.ChainStatus, error) { return types.ChainStatus{}, nil } diff --git a/core/services/relay/evm/mocks/loop_relay_adapter.go b/core/services/relay/evm/mocks/loop_relay_adapter.go index c770b52c88..76579d4746 100644 --- a/core/services/relay/evm/mocks/loop_relay_adapter.go +++ b/core/services/relay/evm/mocks/loop_relay_adapter.go @@ -221,6 +221,62 @@ func (_c *LoopRelayAdapter_HealthReport_Call) RunAndReturn(run func() map[string return _c } +// LatestHead provides a mock function with given fields: ctx +func (_m *LoopRelayAdapter) LatestHead(ctx context.Context) (types.Head, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for LatestHead") + } + + var r0 types.Head + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (types.Head, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) types.Head); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(types.Head) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LoopRelayAdapter_LatestHead_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestHead' +type LoopRelayAdapter_LatestHead_Call struct { + *mock.Call +} + +// LatestHead is a helper method to define mock.On call +// - ctx context.Context +func (_e *LoopRelayAdapter_Expecter) LatestHead(ctx interface{}) *LoopRelayAdapter_LatestHead_Call { + return &LoopRelayAdapter_LatestHead_Call{Call: _e.mock.On("LatestHead", ctx)} +} + +func (_c *LoopRelayAdapter_LatestHead_Call) Run(run func(ctx context.Context)) *LoopRelayAdapter_LatestHead_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *LoopRelayAdapter_LatestHead_Call) Return(_a0 types.Head, _a1 error) *LoopRelayAdapter_LatestHead_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *LoopRelayAdapter_LatestHead_Call) RunAndReturn(run func(context.Context) (types.Head, error)) *LoopRelayAdapter_LatestHead_Call { + _c.Call.Return(run) + return _c +} + // ListNodeStatuses provides a mock function with given fields: ctx, pageSize, pageToken func (_m *LoopRelayAdapter) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) ([]types.NodeStatus, string, int, error) { ret := _m.Called(ctx, pageSize, pageToken) diff --git a/core/services/relay/evm/read/event.go b/core/services/relay/evm/read/event.go index 693a8d5bd7..1630265ea9 100644 --- a/core/services/relay/evm/read/event.go +++ b/core/services/relay/evm/read/event.go @@ -485,9 +485,9 @@ func (b *EventBinding) decodeLogsIntoSequences(ctx context.Context, logs []logpo sequences[idx] = commontypes.Sequence{ Cursor: fmt.Sprintf("%s-%s-%d", logs[idx].BlockHash, logs[idx].TxHash, logs[idx].LogIndex), Head: commontypes.Head{ - Identifier: fmt.Sprint(logs[idx].BlockNumber), - Hash: logs[idx].BlockHash.Bytes(), - Timestamp: uint64(logs[idx].BlockTimestamp.Unix()), + Height: fmt.Sprint(logs[idx].BlockNumber), + Hash: logs[idx].BlockHash.Bytes(), + Timestamp: uint64(logs[idx].BlockTimestamp.Unix()), }, } diff --git a/core/services/relay/evm/relayer_extender.go b/core/services/relay/evm/relayer_extender.go index f262948c9c..f447749157 100644 --- a/core/services/relay/evm/relayer_extender.go +++ b/core/services/relay/evm/relayer_extender.go @@ -74,6 +74,10 @@ type ChainRelayerExt struct { var _ EVMChainRelayerExtender = &ChainRelayerExt{} +func (s *ChainRelayerExt) LatestHead(ctx context.Context) (commontypes.Head, error) { + return s.chain.LatestHead(ctx) +} + func (s *ChainRelayerExt) GetChainStatus(ctx context.Context) (commontypes.ChainStatus, error) { return s.chain.GetChainStatus(ctx) } diff --git a/core/web/testutils/mock_relayer.go b/core/web/testutils/mock_relayer.go index 4c2e5661af..4666f9da6a 100644 --- a/core/web/testutils/mock_relayer.go +++ b/core/web/testutils/mock_relayer.go @@ -8,6 +8,7 @@ import ( ) type MockRelayer struct { + Head commontypes.Head ChainStatus commontypes.ChainStatus NodeStatuses []commontypes.NodeStatus } @@ -40,6 +41,10 @@ func (m MockRelayer) NewContractReader(_ context.Context, _ []byte) (commontypes panic("not implemented") } +func (m MockRelayer) LatestHead(_ context.Context) (commontypes.Head, error) { + return m.Head, nil +} + func (m MockRelayer) GetChainStatus(ctx context.Context) (commontypes.ChainStatus, error) { return m.ChainStatus, nil } diff --git a/go.md b/go.md index 9d11c19168..3100bd2db0 100644 --- a/go.md +++ b/go.md @@ -55,6 +55,7 @@ flowchart LR click wsrpc href "https://github.com/smartcontractkit/wsrpc" chainlink-automation --> chainlink-common chainlink-automation --> libocr + chainlink-ccip --> chain-selectors chainlink-ccip --> chainlink-common chainlink-ccip --> libocr chainlink-common --> grpc-proxy diff --git a/go.mod b/go.mod index 4803a35b9d..031da4b435 100644 --- a/go.mod +++ b/go.mod @@ -72,15 +72,15 @@ require ( github.com/scylladb/go-reflectx v1.0.1 github.com/shirou/gopsutil/v3 v3.24.3 github.com/shopspring/decimal v1.4.0 - github.com/smartcontractkit/chain-selectors v1.0.21 + github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 diff --git a/go.sum b/go.sum index aea2168da8..84988468ae 100644 --- a/go.sum +++ b/go.sum @@ -1036,24 +1036,24 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1WonwhVOPtOStpqTmLC4E= -github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= +github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnjjIQAEBnutCtksPzVDY= +github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1:siC6AoTs4889FwiqgEp0sC6S8nFlDzVTZAmUX7cV7aM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 h1:9SkeP9lpTMDqtqDd+BKPQhkPcylSoYi63L9YFdbzbEo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 h1:xow5cYrWxRmzTwhz2AjWOlnI9WRF4O5b84bXm1k292E= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227/go.mod h1:DUFantPYoBGwBSkNVt2k4ZJi0jPKRRrZVVlAzcZwreA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 h1:BPuehkAQ8R112SlTitukSdKYRJMY3zkvaQS4VSTNn0Q= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa h1:vG4aRggHzNDFTmMFemhhUAzqTfG159w0+RYjO7/cJ5E= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd h1:+RFI4mgXSGEcn847e7bavhQCqaBiW142g1XfGzijFoY= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd/go.mod h1:Ou79geDZKg87CgRi0BTQpRhUT3U6LcrQWuGQveDRvlg= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 h1:Tkl0/SB1hxjBgphslHf1E6iXp+4QAejuCLIT+8zvX3Y= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3/go.mod h1:mkuwCChesVqzMQpYQWRwckmQobJLwG4XCsw7KB8UCKY= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 h1:JPs35oSO07PK3Qv7Kyv0GJHVLacIE1IkrvefaPyBjKs= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664/go.mod h1:iJ9DKYo0F64ue7IogAIELwU2DfrhEAh76eSmZOilT8A= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae h1:d+B8y2Nd/PrnPMNoaSPn3eDgUgxcVcIqAxGrvYu/gGw= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 h1:e38V5FYE7DA1JfKXeD5Buo/7lczALuVXlJ8YNTAUxcw= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 53aa0f475b..a260dbba6e 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -34,10 +34,10 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 - github.com/smartcontractkit/chain-selectors v1.0.21 + github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 @@ -403,11 +403,11 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd // indirect - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 // indirect + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 02208bcf8a..53b707b5ae 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1419,24 +1419,24 @@ github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 h1:jakAsdhDxV4cMgRAcSvHraXjyePi8umG5SEUTGFvuy8= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685/go.mod h1:p7L/xNEQpHDdZtgFA6/FavuZHqvV3kYhQysxBywmq1k= -github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1WonwhVOPtOStpqTmLC4E= -github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= +github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnjjIQAEBnutCtksPzVDY= +github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1:siC6AoTs4889FwiqgEp0sC6S8nFlDzVTZAmUX7cV7aM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 h1:9SkeP9lpTMDqtqDd+BKPQhkPcylSoYi63L9YFdbzbEo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 h1:xow5cYrWxRmzTwhz2AjWOlnI9WRF4O5b84bXm1k292E= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227/go.mod h1:DUFantPYoBGwBSkNVt2k4ZJi0jPKRRrZVVlAzcZwreA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 h1:BPuehkAQ8R112SlTitukSdKYRJMY3zkvaQS4VSTNn0Q= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa h1:vG4aRggHzNDFTmMFemhhUAzqTfG159w0+RYjO7/cJ5E= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd h1:+RFI4mgXSGEcn847e7bavhQCqaBiW142g1XfGzijFoY= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd/go.mod h1:Ou79geDZKg87CgRi0BTQpRhUT3U6LcrQWuGQveDRvlg= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 h1:Tkl0/SB1hxjBgphslHf1E6iXp+4QAejuCLIT+8zvX3Y= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3/go.mod h1:mkuwCChesVqzMQpYQWRwckmQobJLwG4XCsw7KB8UCKY= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 h1:JPs35oSO07PK3Qv7Kyv0GJHVLacIE1IkrvefaPyBjKs= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664/go.mod h1:iJ9DKYo0F64ue7IogAIELwU2DfrhEAh76eSmZOilT8A= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae h1:d+B8y2Nd/PrnPMNoaSPn3eDgUgxcVcIqAxGrvYu/gGw= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 h1:Owb1MQZn0NZHwtZAnPZE6TVoTx6xLrfPaUdeOYswE9M= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 6d2658d24a..86d9f5444b 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 @@ -392,13 +392,13 @@ require ( github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chain-selectors v1.0.21 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 // indirect + github.com/smartcontractkit/chain-selectors v1.0.23 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd // indirect - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 // indirect + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae // indirect github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 // indirect github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 592984aca4..91a8b703af 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1393,24 +1393,24 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/smartcontractkit/chain-selectors v1.0.21 h1:KCR9SA7PhOexaBzFieHoLv1WonwhVOPtOStpqTmLC4E= -github.com/smartcontractkit/chain-selectors v1.0.21/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= +github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnjjIQAEBnutCtksPzVDY= +github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426 h1:siC6AoTs4889FwiqgEp0sC6S8nFlDzVTZAmUX7cV7aM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240910072312-810030689426/go.mod h1:v8hmGodMN1s1TQnvZepZ3Pbo+PyzWVdXag7JzJnvrkI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322 h1:9SkeP9lpTMDqtqDd+BKPQhkPcylSoYi63L9YFdbzbEo= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240910154010-ed9f50de7322/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227 h1:xow5cYrWxRmzTwhz2AjWOlnI9WRF4O5b84bXm1k292E= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240910210931-638ba8a76227/go.mod h1:DUFantPYoBGwBSkNVt2k4ZJi0jPKRRrZVVlAzcZwreA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 h1:BPuehkAQ8R112SlTitukSdKYRJMY3zkvaQS4VSTNn0Q= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa h1:vG4aRggHzNDFTmMFemhhUAzqTfG159w0+RYjO7/cJ5E= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd h1:+RFI4mgXSGEcn847e7bavhQCqaBiW142g1XfGzijFoY= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240910161529-a7050b5193cd/go.mod h1:Ou79geDZKg87CgRi0BTQpRhUT3U6LcrQWuGQveDRvlg= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3 h1:Tkl0/SB1hxjBgphslHf1E6iXp+4QAejuCLIT+8zvX3Y= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240910163253-2a5c9ab97de3/go.mod h1:mkuwCChesVqzMQpYQWRwckmQobJLwG4XCsw7KB8UCKY= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 h1:JPs35oSO07PK3Qv7Kyv0GJHVLacIE1IkrvefaPyBjKs= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664/go.mod h1:iJ9DKYo0F64ue7IogAIELwU2DfrhEAh76eSmZOilT8A= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae h1:d+B8y2Nd/PrnPMNoaSPn3eDgUgxcVcIqAxGrvYu/gGw= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 h1:Owb1MQZn0NZHwtZAnPZE6TVoTx6xLrfPaUdeOYswE9M= From 8454f46db1985c0a4968b4eb5e0a4a6b81dfef5c Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 11 Sep 2024 15:43:05 -0500 Subject: [PATCH 334/432] integrate beholder client (#14110) --- .changeset/shy-bulldogs-wink.md | 5 ++ .mockery.yaml | 1 - .../ccip_integration_tests/ocr_node_helper.go | 4 +- core/cmd/shell.go | 71 +++++++++++++---- core/cmd/shell_local.go | 3 +- core/cmd/shell_local_test.go | 2 +- core/cmd/shell_test.go | 4 +- core/config/app_config.go | 1 + core/config/docs/core.toml | 22 ++++++ core/config/telemetry_config.go | 10 +++ core/config/toml/types.go | 77 +++++++++++++++++-- core/internal/cltest/cltest.go | 4 +- core/scripts/go.mod | 8 +- core/scripts/go.sum | 21 ++--- core/services/chainlink/application.go | 13 +++- core/services/chainlink/cfgtest/cfgtest.go | 5 +- core/services/chainlink/config_general.go | 3 + core/services/chainlink/config_telemetry.go | 43 +++++++++++ core/services/chainlink/config_test.go | 8 ++ .../chainlink/mocks/general_config.go | 47 +++++++++++ .../relayer_chain_interoperators_test.go | 2 +- .../testdata/config-empty-effective.toml | 7 ++ .../chainlink/testdata/config-full.toml | 11 +++ .../config-multi-chain-effective.toml | 7 ++ .../ccip/testhelpers/integration/chainlink.go | 4 +- .../testhelpers_1_4_0/chainlink.go | 4 +- core/web/loop_registry_internal_test.go | 4 +- .../testdata/config-empty-effective.toml | 7 ++ core/web/resolver/testdata/config-full.toml | 11 +++ .../config-multi-chain-effective.toml | 7 ++ docs/CONFIG.md | 58 ++++++++++++++ go.mod | 10 +-- go.sum | 21 ++--- integration-tests/deployment/memory/node.go | 4 +- integration-tests/go.sum | 4 +- integration-tests/load/go.sum | 4 +- plugins/loop_registry.go | 23 ++++-- plugins/loop_registry_test.go | 65 +++++++++++----- testdata/scripts/node/validate/default.txtar | 7 ++ .../node/validate/defaults-override.txtar | 7 ++ .../disk-based-logging-disabled.txtar | 7 ++ .../validate/disk-based-logging-no-dir.txtar | 7 ++ .../node/validate/disk-based-logging.txtar | 7 ++ .../node/validate/invalid-ocr-p2p.txtar | 7 ++ testdata/scripts/node/validate/invalid.txtar | 7 ++ testdata/scripts/node/validate/valid.txtar | 7 ++ testdata/scripts/node/validate/warnings.txtar | 7 ++ 47 files changed, 568 insertions(+), 100 deletions(-) create mode 100644 .changeset/shy-bulldogs-wink.md create mode 100644 core/config/telemetry_config.go create mode 100644 core/services/chainlink/config_telemetry.go diff --git a/.changeset/shy-bulldogs-wink.md b/.changeset/shy-bulldogs-wink.md new file mode 100644 index 0000000000..a2ff2d21f1 --- /dev/null +++ b/.changeset/shy-bulldogs-wink.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#added Full Open Telemetry support, configurable via `Telemetry` diff --git a/.mockery.yaml b/.mockery.yaml index 161348efbf..599aa1e65e 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -559,7 +559,6 @@ packages: config: filename: evm_mock.go dir: "{{ .InterfaceDir }}/rpclibmocks" - github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices: config: dir: "{{ .InterfaceDir }}/" diff --git a/core/capabilities/ccip/ccip_integration_tests/ocr_node_helper.go b/core/capabilities/ccip/ccip_integration_tests/ocr_node_helper.go index d8bbd5eace..aff02cd55d 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ocr_node_helper.go +++ b/core/capabilities/ccip/ccip_integration_tests/ocr_node_helper.go @@ -135,7 +135,7 @@ func setupNodeOCR3( } relayerFactory := chainlink.RelayerFactory{ Logger: lggr, - LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), cfg.Tracing()), + LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), cfg.Tracing(), cfg.Telemetry()), GRPCOpts: loop.GRPCOpts{}, CapabilitiesRegistry: coretypes.NewCapabilitiesRegistry(t), } @@ -155,7 +155,7 @@ func setupNodeOCR3( RestrictedHTTPClient: &http.Client{}, AuditLogger: audit.NoopLogger, MailMon: mailMon, - LoopRegistry: plugins.NewLoopRegistry(lggr, cfg.Tracing()), + LoopRegistry: plugins.NewLoopRegistry(lggr, cfg.Tracing(), cfg.Telemetry()), }) require.NoError(t, err) require.NoError(t, app.GetKeyStore().Unlock(ctx, "password")) diff --git a/core/cmd/shell.go b/core/cmd/shell.go index ba3d56d748..c862b93614 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -23,14 +23,16 @@ import ( "github.com/Masterminds/semver/v3" "github.com/getsentry/sentry-go" "github.com/gin-gonic/gin" + "github.com/jmoiron/sqlx" "github.com/pkg/errors" "github.com/urfave/cli" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" "go.uber.org/multierr" "go.uber.org/zap/zapcore" "golang.org/x/sync/errgroup" - "github.com/jmoiron/sqlx" - + "github.com/smartcontractkit/chainlink-common/pkg/beholder" "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" @@ -63,20 +65,59 @@ var ( grpcOpts loop.GRPCOpts ) -func initGlobals(cfgProm config.Prometheus, cfgTracing config.Tracing, logger logger.Logger) error { +func initGlobals(cfgProm config.Prometheus, cfgTracing config.Tracing, cfgTelemetry config.Telemetry, lggr logger.Logger) error { // Avoid double initializations, but does not prevent relay methods from being called multiple times. var err error initGlobalsOnce.Do(func() { - prometheus = ginprom.New(ginprom.Namespace("service"), ginprom.Token(cfgProm.AuthToken())) - grpcOpts = loop.NewGRPCOpts(nil) // default prometheus.Registerer - err = loop.SetupTracing(loop.TracingConfig{ - Enabled: cfgTracing.Enabled(), - CollectorTarget: cfgTracing.CollectorTarget(), - NodeAttributes: cfgTracing.Attributes(), - SamplingRatio: cfgTracing.SamplingRatio(), - TLSCertPath: cfgTracing.TLSCertPath(), - OnDialError: func(error) { logger.Errorw("Failed to dial", "err", err) }, - }) + err = func() error { + prometheus = ginprom.New(ginprom.Namespace("service"), ginprom.Token(cfgProm.AuthToken())) + grpcOpts = loop.NewGRPCOpts(nil) // default prometheus.Registerer + + otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) { + lggr.Errorw("Telemetry error", "err", err) + })) + + tracingCfg := loop.TracingConfig{ + Enabled: cfgTracing.Enabled(), + CollectorTarget: cfgTracing.CollectorTarget(), + NodeAttributes: cfgTracing.Attributes(), + SamplingRatio: cfgTracing.SamplingRatio(), + TLSCertPath: cfgTracing.TLSCertPath(), + OnDialError: func(error) { lggr.Errorw("Failed to dial", "err", err) }, + } + if !cfgTelemetry.Enabled() { + return loop.SetupTracing(tracingCfg) + } + + var attributes []attribute.KeyValue + if tracingCfg.Enabled { + attributes = tracingCfg.Attributes() + } + for k, v := range cfgTelemetry.ResourceAttributes() { + attributes = append(attributes, attribute.String(k, v)) + } + clientCfg := beholder.Config{ + InsecureConnection: cfgTelemetry.InsecureConnection(), + CACertFile: cfgTelemetry.CACertFile(), + OtelExporterGRPCEndpoint: cfgTelemetry.OtelExporterGRPCEndpoint(), + ResourceAttributes: attributes, + TraceSampleRatio: cfgTelemetry.TraceSampleRatio(), + } + if tracingCfg.Enabled { + clientCfg.TraceSpanExporter, err = tracingCfg.NewSpanExporter() + if err != nil { + return err + } + } + var beholderClient *beholder.Client + beholderClient, err = beholder.NewClient(clientCfg) + if err != nil { + return err + } + beholder.SetClient(beholderClient) + beholder.SetGlobalOtelProviders() + return nil + }() }) return err } @@ -139,7 +180,7 @@ type ChainlinkAppFactory struct{} // NewApplication returns a new instance of the node with the given config. func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.GeneralConfig, appLggr logger.Logger, db *sqlx.DB) (app chainlink.Application, err error) { - err = initGlobals(cfg.Prometheus(), cfg.Tracing(), appLggr) + err = initGlobals(cfg.Prometheus(), cfg.Tracing(), cfg.Telemetry(), appLggr) if err != nil { appLggr.Errorf("Failed to initialize globals: %v", err) } @@ -159,7 +200,7 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G keyStore := keystore.New(ds, utils.GetScryptParams(cfg), appLggr) mailMon := mailbox.NewMonitor(cfg.AppID().String(), appLggr.Named("Mailbox")) - loopRegistry := plugins.NewLoopRegistry(appLggr, cfg.Tracing()) + loopRegistry := plugins.NewLoopRegistry(appLggr, cfg.Tracing(), cfg.Telemetry()) mercuryPool := wsrpc.NewPool(appLggr, cache.Config{ LatestReportTTL: cfg.Mercury().Cache().LatestReportTTL(), diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index 604daf7568..fedd83dec8 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -22,9 +22,8 @@ import ( gethCommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/fatih/color" - "github.com/lib/pq" - "github.com/kylelemons/godebug/diff" + "github.com/lib/pq" "github.com/pkg/errors" "github.com/urfave/cli" "go.uber.org/multierr" diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go index 783781723e..6f4907a5a6 100644 --- a/core/cmd/shell_local_test.go +++ b/core/cmd/shell_local_test.go @@ -46,7 +46,7 @@ import ( func genTestEVMRelayers(t *testing.T, opts legacyevm.ChainRelayExtenderConfig, ks evmrelayer.CSAETHKeystore) *chainlink.CoreRelayerChainInteroperators { f := chainlink.RelayerFactory{ Logger: opts.Logger, - LoopRegistry: plugins.NewLoopRegistry(opts.Logger, opts.AppConfig.Tracing()), + LoopRegistry: plugins.NewLoopRegistry(opts.Logger, opts.AppConfig.Tracing(), opts.AppConfig.Telemetry()), CapabilitiesRegistry: capabilities.NewRegistry(opts.Logger), } diff --git a/core/cmd/shell_test.go b/core/cmd/shell_test.go index 6ecdc4a34d..a93be2fb9e 100644 --- a/core/cmd/shell_test.go +++ b/core/cmd/shell_test.go @@ -351,7 +351,7 @@ func TestNewUserCache(t *testing.T) { func TestSetupSolanaRelayer(t *testing.T) { lggr := logger.TestLogger(t) - reg := plugins.NewLoopRegistry(lggr, nil) + reg := plugins.NewLoopRegistry(lggr, nil, nil) ks := mocks.NewSolana(t) // config 3 chains but only enable 2 => should only be 2 relayer @@ -466,7 +466,7 @@ func TestSetupSolanaRelayer(t *testing.T) { func TestSetupStarkNetRelayer(t *testing.T) { lggr := logger.TestLogger(t) - reg := plugins.NewLoopRegistry(lggr, nil) + reg := plugins.NewLoopRegistry(lggr, nil, nil) ks := mocks.NewStarkNet(t) // config 3 chains but only enable 2 => should only be 2 relayer nEnabledChains := 2 diff --git a/core/config/app_config.go b/core/config/app_config.go index 112e242636..4cb7f1f610 100644 --- a/core/config/app_config.go +++ b/core/config/app_config.go @@ -56,6 +56,7 @@ type AppConfig interface { Threshold() Threshold WebServer() WebServer Tracing() Tracing + Telemetry() Telemetry } type DatabaseBackupMode string diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index 2f7ff847e4..d29223a31e 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -689,3 +689,25 @@ TransmitQueueMaxSize = 10_000 # Default # when sending a message to the mercury server, before aborting and considering # the transmission to be failed. TransmitTimeout = "5s" # Default + +# Telemetry holds OTEL settings. +# This data includes open telemetry metrics, traces, & logs. +# It does not currently include prometheus metrics or standard out logs, but may in the future. +[Telemetry] +# Enabled turns telemetry collection on or off. +Enabled = false # Default +# Endpoint of the OTEL Collector. +Endpoint = 'example.com/collector' # Example +# CACertFile is the file path of the TLS certificate used for secure communication with the OTEL Collector. +# Required unless InescureConnection is true. +CACertFile = 'cert-file' # Example +# InsecureConnection bypasses the TLS CACertFile requirement and uses an insecure connection instead. +# Only available in dev mode. +InsecureConnection = false # Default +# TraceSampleRatio is the rate at which to sample traces. Must be between 0 and 1. +TraceSampleRatio = 0.01 # Default + +# ResourceAttributes are global metadata to include with all telemetry. +[Telemetry.ResourceAttributes] +# foo is an example resource attribute +foo = "bar" # Example diff --git a/core/config/telemetry_config.go b/core/config/telemetry_config.go new file mode 100644 index 0000000000..5440e70b43 --- /dev/null +++ b/core/config/telemetry_config.go @@ -0,0 +1,10 @@ +package config + +type Telemetry interface { + Enabled() bool + InsecureConnection() bool + CACertFile() string + OtelExporterGRPCEndpoint() string + ResourceAttributes() map[string]string + TraceSampleRatio() float64 +} diff --git a/core/config/toml/types.go b/core/config/toml/types.go index f89ecab9c0..2eb66d10a9 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -59,6 +59,7 @@ type Core struct { Tracing Tracing `toml:",omitempty"` Mercury Mercury `toml:",omitempty"` Capabilities Capabilities `toml:",omitempty"` + Telemetry Telemetry `toml:",omitempty"` } // SetFrom updates c with any non-nil values from f. (currently TOML field only!) @@ -95,11 +96,12 @@ func (c *Core) SetFrom(f *Core) { c.Sentry.setFrom(&f.Sentry) c.Insecure.setFrom(&f.Insecure) c.Tracing.setFrom(&f.Tracing) + c.Telemetry.setFrom(&f.Telemetry) } func (c *Core) ValidateConfig() (err error) { _, verr := parse.HomeDir(*c.RootDir) - if err != nil { + if verr != nil { err = multierr.Append(err, configutils.ErrInvalid{Name: "RootDir", Value: true, Msg: fmt.Sprintf("Failed to expand RootDir. Please use an explicit path: %s", verr)}) } @@ -107,6 +109,12 @@ func (c *Core) ValidateConfig() (err error) { err = multierr.Append(err, configutils.ErrInvalid{Name: "P2P.V2.Enabled", Value: false, Msg: "P2P required for OCR or OCR2. Please enable P2P or disable OCR/OCR2."}) } + if *c.Tracing.Enabled && *c.Telemetry.Enabled { + if c.Tracing.CollectorTarget == c.Telemetry.Endpoint { + err = multierr.Append(err, configutils.ErrInvalid{Name: "Tracing.CollectorTarget", Value: *c.Tracing.CollectorTarget, Msg: "Same as Telemetry.Endpoint. Must be different or disabled."}) + } + } + return err } @@ -1576,25 +1584,25 @@ type Tracing struct { func (t *Tracing) setFrom(f *Tracing) { if v := f.Enabled; v != nil { - t.Enabled = f.Enabled + t.Enabled = v } if v := f.CollectorTarget; v != nil { - t.CollectorTarget = f.CollectorTarget + t.CollectorTarget = v } if v := f.NodeID; v != nil { - t.NodeID = f.NodeID + t.NodeID = v } if v := f.Attributes; v != nil { - t.Attributes = f.Attributes + t.Attributes = v } if v := f.SamplingRatio; v != nil { - t.SamplingRatio = f.SamplingRatio + t.SamplingRatio = v } if v := f.Mode; v != nil { - t.Mode = f.Mode + t.Mode = v } if v := f.TLSCertPath; v != nil { - t.TLSCertPath = f.TLSCertPath + t.TLSCertPath = v } } @@ -1648,6 +1656,59 @@ func (t *Tracing) ValidateConfig() (err error) { return err } +type Telemetry struct { + Enabled *bool + CACertFile *string + Endpoint *string + InsecureConnection *bool + ResourceAttributes map[string]string `toml:",omitempty"` + TraceSampleRatio *float64 +} + +func (b *Telemetry) setFrom(f *Telemetry) { + if v := f.Enabled; v != nil { + b.Enabled = v + } + if v := f.CACertFile; v != nil { + b.CACertFile = v + } + if v := f.Endpoint; v != nil { + b.Endpoint = v + } + if v := f.InsecureConnection; v != nil { + b.InsecureConnection = v + } + if v := f.ResourceAttributes; v != nil { + b.ResourceAttributes = v + } + if v := f.TraceSampleRatio; v != nil { + b.TraceSampleRatio = v + } +} + +func (b *Telemetry) ValidateConfig() (err error) { + if b.Enabled == nil || !*b.Enabled { + return nil + } + if b.Endpoint == nil || *b.Endpoint == "" { + err = multierr.Append(err, configutils.ErrMissing{Name: "Endpoint", Msg: "must be set when Telemetry is enabled"}) + } + if b.InsecureConnection != nil && *b.InsecureConnection { + if build.IsProd() { + err = multierr.Append(err, configutils.ErrInvalid{Name: "InsecureConnection", Msg: "cannot be used in production builds"}) + } + } else { + if b.CACertFile == nil || *b.CACertFile == "" { + err = multierr.Append(err, configutils.ErrMissing{Name: "CACertFile", Msg: "must be set, unless InsecureConnection is used"}) + } + } + if ratio := b.TraceSampleRatio; ratio != nil && (*ratio < 0 || *ratio > 1) { + err = multierr.Append(err, configutils.ErrInvalid{Name: "TraceSampleRatio", Value: *ratio, Msg: "must be between 0 and 1"}) + } + + return err +} + var hostnameRegex = regexp.MustCompile(`^[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*$`) // Validates uri is valid external or local URI diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 23469cbb80..7d333d9401 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -379,7 +379,7 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn keyStore := keystore.NewInMemory(ds, utils.FastScryptParams, lggr) mailMon := mailbox.NewMonitor(cfg.AppID().String(), lggr.Named("Mailbox")) - loopRegistry := plugins.NewLoopRegistry(lggr, nil) + loopRegistry := plugins.NewLoopRegistry(lggr, nil, nil) mercuryPool := wsrpc.NewPool(lggr, cache.Config{ LatestReportTTL: cfg.Mercury().Cache().LatestReportTTL(), @@ -471,7 +471,7 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn RestrictedHTTPClient: c, UnrestrictedHTTPClient: c, SecretGenerator: MockSecretGenerator{}, - LoopRegistry: plugins.NewLoopRegistry(lggr, nil), + LoopRegistry: plugins.NewLoopRegistry(lggr, nil, nil), MercuryPool: mercuryPool, CapabilitiesRegistry: capabilitiesRegistry, CapabilitiesDispatcher: dispatcher, diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 40c921d72c..747c4f20ec 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -119,7 +119,7 @@ require ( github.com/fatih/color v1.16.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/solana-go v1.8.4 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect @@ -149,7 +149,7 @@ require ( github.com/go-openapi/swag v0.22.4 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.15.5 // indirect + github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-viper/mapstructure/v2 v2.1.0 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect @@ -174,7 +174,7 @@ require ( github.com/grafana/pyroscope-go v1.1.1 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/graph-gophers/dataloader v5.0.0+incompatible // indirect - github.com/graph-gophers/graphql-go v1.3.0 // indirect + github.com/graph-gophers/graphql-go v1.5.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect @@ -220,7 +220,7 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index ab7a6c118f..ad91e2472c 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -374,8 +374,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= @@ -438,6 +438,7 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -462,8 +463,8 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= -github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -547,6 +548,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -602,8 +604,8 @@ github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKt github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4= -github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= -github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/graph-gophers/graphql-go v1.5.0 h1:fDqblo50TEpD0LY7RXk/LFVYEVqo3+tXMNMPSVXA1yc= +github.com/graph-gophers/graphql-go v1.5.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= @@ -813,8 +815,8 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -1151,7 +1153,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -1278,6 +1279,7 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIX go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/contrib/propagators/b3 v1.24.0 h1:n4xwCdTx3pZqZs2CjS/CUZAs03y3dZcGhC/FepKtEUY= go.opentelemetry.io/contrib/propagators/b3 v1.24.0/go.mod h1:k5wRxKRU2uXx2F8uNJ4TaonuEO/V7/5xoz7kdsDACT8= +go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 h1:UiRNKd1OgqsLbFwE+wkAWTdiAxXtCBqKIHeBIse4FUA= @@ -1304,6 +1306,7 @@ go.opentelemetry.io/otel/sdk/log v0.4.0 h1:1mMI22L82zLqf6KtkjrRy5BbagOTWdJsqMY/H go.opentelemetry.io/otel/sdk/log v0.4.0/go.mod h1:AYJ9FVF0hNOgAVzUG/ybg/QttnXhUePWAupmCqtdESo= go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= +go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 1c498f4073..873f5080c6 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -14,6 +14,9 @@ import ( "github.com/grafana/pyroscope-go" "github.com/jonboulle/clockwork" "github.com/pkg/errors" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" "go.uber.org/multierr" "go.uber.org/zap/zapcore" @@ -283,7 +286,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { // we need to initialize in case we serve OCR2 LOOPs loopRegistry := opts.LoopRegistry if loopRegistry == nil { - loopRegistry = plugins.NewLoopRegistry(globalLogger, opts.Config.Tracing()) + loopRegistry = plugins.NewLoopRegistry(globalLogger, opts.Config.Tracing(), opts.Config.Telemetry()) } // If the audit logger is enabled @@ -662,6 +665,14 @@ func (app *ChainlinkApplication) Start(ctx context.Context) error { panic("application is already started") } + var span trace.Span + ctx, span = otel.Tracer("").Start(ctx, "Start", trace.WithAttributes( + attribute.String("app-id", app.ID().String()), + attribute.String("version", static.Version), + attribute.String("commit", static.Sha), + )) + defer span.End() + if app.FeedsService != nil { if err := app.FeedsService.Start(ctx); err != nil { app.logger.Errorf("[Feeds Service] Failed to start %v", err) diff --git a/core/services/chainlink/cfgtest/cfgtest.go b/core/services/chainlink/cfgtest/cfgtest.go index 3bf9545265..1dfba71d46 100644 --- a/core/services/chainlink/cfgtest/cfgtest.go +++ b/core/services/chainlink/cfgtest/cfgtest.go @@ -76,7 +76,7 @@ func assertValNotNil(t *testing.T, key string, val reflect.Value) error { t.Helper() k := val.Kind() switch k { //nolint:exhaustive - case reflect.Ptr, reflect.Map: + case reflect.Ptr: if val.IsNil() { return fmt.Errorf("%s: nil", key) } @@ -94,6 +94,9 @@ func assertValNotNil(t *testing.T, key string, val reflect.Value) error { } return assertFieldsNotNil(t, key, val) case reflect.Map: + if val.IsNil() { + return nil // not actually a problem + } return assertValuesNotNil(t, key, val) case reflect.Slice: if val.IsNil() { diff --git a/core/services/chainlink/config_general.go b/core/services/chainlink/config_general.go index 79c92f8214..dd0dc87b59 100644 --- a/core/services/chainlink/config_general.go +++ b/core/services/chainlink/config_general.go @@ -524,5 +524,8 @@ func (g *generalConfig) Threshold() coreconfig.Threshold { func (g *generalConfig) Tracing() coreconfig.Tracing { return &tracingConfig{s: g.c.Tracing} } +func (g *generalConfig) Telemetry() coreconfig.Telemetry { + return &telemetryConfig{s: g.c.Telemetry} +} var zeroSha256Hash = models.Sha256Hash{} diff --git a/core/services/chainlink/config_telemetry.go b/core/services/chainlink/config_telemetry.go new file mode 100644 index 0000000000..790f2a1995 --- /dev/null +++ b/core/services/chainlink/config_telemetry.go @@ -0,0 +1,43 @@ +package chainlink + +import ( + "github.com/smartcontractkit/chainlink/v2/core/config/toml" +) + +type telemetryConfig struct { + s toml.Telemetry +} + +func (b *telemetryConfig) Enabled() bool { return *b.s.Enabled } + +func (b *telemetryConfig) InsecureConnection() bool { + if b.s.InsecureConnection == nil { + return false + } + return *b.s.InsecureConnection +} + +func (b *telemetryConfig) CACertFile() string { + if b.s.CACertFile == nil { + return "" + } + return *b.s.CACertFile +} + +func (b *telemetryConfig) OtelExporterGRPCEndpoint() string { + if b.s.Endpoint == nil { + return "" + } + return *b.s.Endpoint +} + +func (b *telemetryConfig) ResourceAttributes() map[string]string { + return b.s.ResourceAttributes +} + +func (b *telemetryConfig) TraceSampleRatio() float64 { + if b.s.TraceSampleRatio == nil { + return 0.0 + } + return *b.s.TraceSampleRatio +} diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 71dc763ad6..1018778b32 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -513,6 +513,14 @@ func TestConfig_Marshal(t *testing.T) { Environment: ptr("dev"), Release: ptr("v1.2.3"), } + full.Telemetry = toml.Telemetry{ + Enabled: ptr(true), + CACertFile: ptr("cert-file"), + Endpoint: ptr("example.com/collector"), + InsecureConnection: ptr(true), + ResourceAttributes: map[string]string{"Baz": "test", "Foo": "bar"}, + TraceSampleRatio: ptr(0.01), + } full.EVM = []*evmcfg.EVMConfig{ { ChainID: ubig.NewI(1), diff --git a/core/services/chainlink/mocks/general_config.go b/core/services/chainlink/mocks/general_config.go index f4594a4322..63a846c6ed 100644 --- a/core/services/chainlink/mocks/general_config.go +++ b/core/services/chainlink/mocks/general_config.go @@ -1771,6 +1771,53 @@ func (_c *GeneralConfig_StarknetConfigs_Call) RunAndReturn(run func() chainlinkc return _c } +// Telemetry provides a mock function with given fields: +func (_m *GeneralConfig) Telemetry() config.Telemetry { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Telemetry") + } + + var r0 config.Telemetry + if rf, ok := ret.Get(0).(func() config.Telemetry); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(config.Telemetry) + } + } + + return r0 +} + +// GeneralConfig_Telemetry_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Telemetry' +type GeneralConfig_Telemetry_Call struct { + *mock.Call +} + +// Telemetry is a helper method to define mock.On call +func (_e *GeneralConfig_Expecter) Telemetry() *GeneralConfig_Telemetry_Call { + return &GeneralConfig_Telemetry_Call{Call: _e.mock.On("Telemetry")} +} + +func (_c *GeneralConfig_Telemetry_Call) Run(run func()) *GeneralConfig_Telemetry_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *GeneralConfig_Telemetry_Call) Return(_a0 config.Telemetry) *GeneralConfig_Telemetry_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GeneralConfig_Telemetry_Call) RunAndReturn(run func() config.Telemetry) *GeneralConfig_Telemetry_Call { + _c.Call.Return(run) + return _c +} + // TelemetryIngress provides a mock function with given fields: func (_m *GeneralConfig) TelemetryIngress() config.TelemetryIngress { ret := _m.Called() diff --git a/core/services/chainlink/relayer_chain_interoperators_test.go b/core/services/chainlink/relayer_chain_interoperators_test.go index 5aaf6e16dd..e83c2881c9 100644 --- a/core/services/chainlink/relayer_chain_interoperators_test.go +++ b/core/services/chainlink/relayer_chain_interoperators_test.go @@ -176,7 +176,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { factory := chainlink.RelayerFactory{ Logger: lggr, - LoopRegistry: plugins.NewLoopRegistry(lggr, nil), + LoopRegistry: plugins.NewLoopRegistry(lggr, nil, nil), GRPCOpts: loop.GRPCOpts{}, CapabilitiesRegistry: capabilities.NewRegistry(lggr), } diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index aff5075428..f78c98896d 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -279,3 +279,10 @@ AuthTimestampToleranceSec = 0 [[Capabilities.GatewayConnector.Gateways]] ID = '' URL = '' + +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 0474a5a1e3..e000ff82d4 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -290,6 +290,17 @@ AuthTimestampToleranceSec = 10 ID = 'example_gateway' URL = 'wss://localhost:8081/node' +[Telemetry] +Enabled = true +CACertFile = 'cert-file' +Endpoint = 'example.com/collector' +InsecureConnection = true +TraceSampleRatio = 0.01 + +[Telemetry.ResourceAttributes] +Baz = 'test' +Foo = 'bar' + [[EVM]] ChainID = '1' Enabled = false diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 5472be09bf..fc11ed10b1 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -280,6 +280,13 @@ AuthTimestampToleranceSec = 0 ID = '' URL = '' +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go index 676ae79e35..cecf99353c 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go @@ -458,7 +458,7 @@ func setupNodeCCIP( }, CSAETHKeystore: simEthKeyStore, } - loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing()) + loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing(), config.Telemetry()) relayerFactory := chainlink.RelayerFactory{ Logger: lggr, LoopRegistry: loopRegistry, @@ -488,7 +488,7 @@ func setupNodeCCIP( RestrictedHTTPClient: &http.Client{}, AuditLogger: audit.NoopLogger, MailMon: mailMon, - LoopRegistry: plugins.NewLoopRegistry(lggr, config.Tracing()), + LoopRegistry: plugins.NewLoopRegistry(lggr, config.Tracing(), config.Telemetry()), }) require.NoError(t, err) require.NoError(t, app.GetKeyStore().Unlock(ctx, "password")) diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go index 2569aa5324..bff08e8638 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go @@ -455,7 +455,7 @@ func setupNodeCCIP( }, CSAETHKeystore: simEthKeyStore, } - loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing()) + loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing(), config.Telemetry()) relayerFactory := chainlink.RelayerFactory{ Logger: lggr, LoopRegistry: loopRegistry, @@ -485,7 +485,7 @@ func setupNodeCCIP( RestrictedHTTPClient: &http.Client{}, AuditLogger: audit.NoopLogger, MailMon: mailMon, - LoopRegistry: plugins.NewLoopRegistry(lggr, config.Tracing()), + LoopRegistry: plugins.NewLoopRegistry(lggr, config.Tracing(), config.Telemetry()), }) ctx := testutils.Context(t) require.NoError(t, err) diff --git a/core/web/loop_registry_internal_test.go b/core/web/loop_registry_internal_test.go index 48cd75a5cf..a02fa20802 100644 --- a/core/web/loop_registry_internal_test.go +++ b/core/web/loop_registry_internal_test.go @@ -38,7 +38,7 @@ func TestLoopRegistryServer_CantWriteToResponse(t *testing.T) { l, o := logger.TestLoggerObserved(t, zap.ErrorLevel) s := &LoopRegistryServer{ exposedPromPort: 1, - registry: plugins.NewLoopRegistry(l, nil), + registry: plugins.NewLoopRegistry(l, nil, nil), logger: l.(logger.SugaredLogger), jsonMarshalFn: json.Marshal, } @@ -53,7 +53,7 @@ func TestLoopRegistryServer_CantMarshal(t *testing.T) { l, o := logger.TestLoggerObserved(t, zap.ErrorLevel) s := &LoopRegistryServer{ exposedPromPort: 1, - registry: plugins.NewLoopRegistry(l, nil), + registry: plugins.NewLoopRegistry(l, nil, nil), logger: l.(logger.SugaredLogger), jsonMarshalFn: func(any) ([]byte, error) { return []byte(""), errors.New("can't unmarshal") diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index aff5075428..f78c98896d 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -279,3 +279,10 @@ AuthTimestampToleranceSec = 0 [[Capabilities.GatewayConnector.Gateways]] ID = '' URL = '' + +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index c01ab09b66..a13a6b9db5 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -290,6 +290,17 @@ AuthTimestampToleranceSec = 10 ID = 'example_gateway' URL = 'wss://localhost:8081/node' +[Telemetry] +Enabled = true +CACertFile = 'cert-file' +Endpoint = 'example.com/collector' +InsecureConnection = true +TraceSampleRatio = 0.01 + +[Telemetry.ResourceAttributes] +Baz = 'test' +Foo = 'bar' + [[EVM]] ChainID = '1' Enabled = false diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index e631642e05..a3853dd2b4 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -280,6 +280,13 @@ AuthTimestampToleranceSec = 0 ID = '' URL = '' +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 3b42bc3756..2f339dfda4 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1897,6 +1897,64 @@ TransmitTimeout controls how long the transmitter will wait for a response when sending a message to the mercury server, before aborting and considering the transmission to be failed. +## Telemetry +```toml +[Telemetry] +Enabled = false # Default +Endpoint = 'example.com/collector' # Example +CACertFile = 'cert-file' # Example +InsecureConnection = false # Default +TraceSampleRatio = 0.01 # Default +``` +Telemetry holds OTEL settings. +This data includes open telemetry metrics, traces, & logs. +It does not currently include prometheus metrics or standard out logs, but may in the future. + +### Enabled +```toml +Enabled = false # Default +``` +Enabled turns telemetry collection on or off. + +### Endpoint +```toml +Endpoint = 'example.com/collector' # Example +``` +Endpoint of the OTEL Collector. + +### CACertFile +```toml +CACertFile = 'cert-file' # Example +``` +CACertFile is the file path of the TLS certificate used for secure communication with the OTEL Collector. +Required unless InescureConnection is true. + +### InsecureConnection +```toml +InsecureConnection = false # Default +``` +InsecureConnection bypasses the TLS CACertFile requirement and uses an insecure connection instead. +Only available in dev mode. + +### TraceSampleRatio +```toml +TraceSampleRatio = 0.01 # Default +``` +TraceSampleRatio is the rate at which to sample traces. Must be between 0 and 1. + +## Telemetry.ResourceAttributes +```toml +[Telemetry.ResourceAttributes] +foo = "bar" # Example +``` +ResourceAttributes are global metadata to include with all telemetry. + +### foo +```toml +foo = "bar" # Example +``` +foo is an example resource attribute + ## EVM EVM defaults depend on ChainID: diff --git a/go.mod b/go.mod index 031da4b435..6f9b0e2beb 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/gorilla/websocket v1.5.1 github.com/grafana/pyroscope-go v1.1.1 github.com/graph-gophers/dataloader v5.0.0+incompatible - github.com/graph-gophers/graphql-go v1.3.0 + github.com/graph-gophers/graphql-go v1.5.0 github.com/hashicorp/consul/sdk v0.16.0 github.com/hashicorp/go-envparse v0.1.0 github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 @@ -100,6 +100,7 @@ require ( go.dedis.ch/kyber/v3 v3.1.0 go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 go.opentelemetry.io/otel v1.28.0 + go.opentelemetry.io/otel/trace v1.28.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.27.0 @@ -190,7 +191,7 @@ require ( github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect @@ -207,7 +208,7 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.15.5 // indirect + github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-webauthn/x v0.1.5 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect @@ -260,7 +261,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -343,7 +344,6 @@ require ( go.opentelemetry.io/otel/sdk v1.28.0 // indirect go.opentelemetry.io/otel/sdk/log v0.4.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/ratelimit v0.3.0 // indirect golang.org/x/arch v0.8.0 // indirect diff --git a/go.sum b/go.sum index 84988468ae..2ef165dcb5 100644 --- a/go.sum +++ b/go.sum @@ -352,8 +352,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= @@ -410,6 +410,7 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -426,8 +427,8 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= -github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -511,6 +512,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -567,8 +569,8 @@ github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKt github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4= -github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= -github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/graph-gophers/graphql-go v1.5.0 h1:fDqblo50TEpD0LY7RXk/LFVYEVqo3+tXMNMPSVXA1yc= +github.com/graph-gophers/graphql-go v1.5.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= @@ -778,8 +780,8 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -1113,7 +1115,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -1236,6 +1237,7 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIX go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/contrib/propagators/b3 v1.24.0 h1:n4xwCdTx3pZqZs2CjS/CUZAs03y3dZcGhC/FepKtEUY= go.opentelemetry.io/contrib/propagators/b3 v1.24.0/go.mod h1:k5wRxKRU2uXx2F8uNJ4TaonuEO/V7/5xoz7kdsDACT8= +go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 h1:UiRNKd1OgqsLbFwE+wkAWTdiAxXtCBqKIHeBIse4FUA= @@ -1262,6 +1264,7 @@ go.opentelemetry.io/otel/sdk/log v0.4.0 h1:1mMI22L82zLqf6KtkjrRy5BbagOTWdJsqMY/H go.opentelemetry.io/otel/sdk/log v0.4.0/go.mod h1:AYJ9FVF0hNOgAVzUG/ybg/QttnXhUePWAupmCqtdESo= go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= +go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= diff --git a/integration-tests/deployment/memory/node.go b/integration-tests/deployment/memory/node.go index 2ca84ac6c5..6512788baf 100644 --- a/integration-tests/deployment/memory/node.go +++ b/integration-tests/deployment/memory/node.go @@ -167,7 +167,7 @@ func NewNode( // Build relayer factory with EVM. relayerFactory := chainlink.RelayerFactory{ Logger: lggr, - LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), cfg.Tracing()), + LoopRegistry: plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), cfg.Tracing(), cfg.Telemetry()), GRPCOpts: loop.GRPCOpts{}, CapabilitiesRegistry: coretypes.NewCapabilitiesRegistry(t), } @@ -187,7 +187,7 @@ func NewNode( RestrictedHTTPClient: &http.Client{}, AuditLogger: audit.NoopLogger, MailMon: mailMon, - LoopRegistry: plugins.NewLoopRegistry(lggr, cfg.Tracing()), + LoopRegistry: plugins.NewLoopRegistry(lggr, cfg.Tracing(), cfg.Telemetry()), }) require.NoError(t, err) t.Cleanup(func() { diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 53b707b5ae..1ba9feb496 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -838,8 +838,8 @@ github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4= -github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= -github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/graph-gophers/graphql-go v1.5.0 h1:fDqblo50TEpD0LY7RXk/LFVYEVqo3+tXMNMPSVXA1yc= +github.com/graph-gophers/graphql-go v1.5.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 91a8b703af..9e50850d34 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -826,8 +826,8 @@ github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4= -github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= -github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/graph-gophers/graphql-go v1.5.0 h1:fDqblo50TEpD0LY7RXk/LFVYEVqo3+tXMNMPSVXA1yc= +github.com/graph-gophers/graphql-go v1.5.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= diff --git a/plugins/loop_registry.go b/plugins/loop_registry.go index b796ddf87e..51c6310ffa 100644 --- a/plugins/loop_registry.go +++ b/plugins/loop_registry.go @@ -27,15 +27,17 @@ type LoopRegistry struct { mu sync.Mutex registry map[string]*RegisteredLoop - lggr logger.Logger - cfgTracing config.Tracing + lggr logger.Logger + cfgTracing config.Tracing + cfgTelemetry config.Telemetry } -func NewLoopRegistry(lggr logger.Logger, tracingConfig config.Tracing) *LoopRegistry { +func NewLoopRegistry(lggr logger.Logger, tracing config.Tracing, telemetry config.Telemetry) *LoopRegistry { return &LoopRegistry{ - registry: map[string]*RegisteredLoop{}, - lggr: logger.Named(lggr, "LoopRegistry"), - cfgTracing: tracingConfig, + registry: map[string]*RegisteredLoop{}, + lggr: logger.Named(lggr, "LoopRegistry"), + cfgTracing: tracing, + cfgTelemetry: telemetry, } } @@ -65,6 +67,15 @@ func (m *LoopRegistry) Register(id string) (*RegisteredLoop, error) { envCfg.TracingAttributes = m.cfgTracing.Attributes() } + if m.cfgTelemetry != nil { + envCfg.TelemetryEnabled = m.cfgTelemetry.Enabled() + envCfg.TelemetryEndpoint = m.cfgTelemetry.OtelExporterGRPCEndpoint() + envCfg.TelemetryInsecureConnection = m.cfgTelemetry.InsecureConnection() + envCfg.TelemetryCACertFile = m.cfgTelemetry.CACertFile() + envCfg.TelemetryAttributes = m.cfgTelemetry.ResourceAttributes() + envCfg.TelemetryTraceSampleRatio = m.cfgTelemetry.TraceSampleRatio() + } + m.registry[id] = &RegisteredLoop{Name: id, EnvCfg: envCfg} m.lggr.Debugf("Registered loopp %q with config %v, port %d", id, envCfg, envCfg.PrometheusPort) return m.registry[id], nil diff --git a/plugins/loop_registry_test.go b/plugins/loop_registry_test.go index b307469e09..84b6b0cefc 100644 --- a/plugins/loop_registry_test.go +++ b/plugins/loop_registry_test.go @@ -5,12 +5,13 @@ import ( "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestPluginPortManager(t *testing.T) { // register one - m := NewLoopRegistry(logger.TestLogger(t), nil) + m := NewLoopRegistry(logger.TestLogger(t), nil, nil) pFoo, err := m.Register("foo") require.NoError(t, err) require.Equal(t, "foo", pFoo.Name) @@ -26,37 +27,63 @@ func TestPluginPortManager(t *testing.T) { require.Equal(t, pFoo.EnvCfg.PrometheusPort+1, pBar.EnvCfg.PrometheusPort) } -// Mock tracing config -type MockCfgTracing struct{} +type mockCfgTracing struct{} -func (m *MockCfgTracing) Attributes() map[string]string { +func (m *mockCfgTracing) Attributes() map[string]string { return map[string]string{"attribute": "value"} } -func (m *MockCfgTracing) Enabled() bool { return true } -func (m *MockCfgTracing) NodeID() string { return "" } -func (m *MockCfgTracing) CollectorTarget() string { return "http://localhost:9000" } -func (m *MockCfgTracing) SamplingRatio() float64 { return 0.1 } -func (m *MockCfgTracing) TLSCertPath() string { return "/path/to/cert.pem" } -func (m *MockCfgTracing) Mode() string { return "tls" } +func (m *mockCfgTracing) Enabled() bool { return true } +func (m *mockCfgTracing) NodeID() string { return "" } +func (m *mockCfgTracing) CollectorTarget() string { return "http://localhost:9000" } +func (m *mockCfgTracing) SamplingRatio() float64 { return 0.1 } +func (m *mockCfgTracing) TLSCertPath() string { return "/path/to/cert.pem" } +func (m *mockCfgTracing) Mode() string { return "tls" } + +type mockCfgTelemetry struct{} + +func (m mockCfgTelemetry) Enabled() bool { return true } + +func (m mockCfgTelemetry) InsecureConnection() bool { return true } + +func (m mockCfgTelemetry) CACertFile() string { return "path/to/cert.pem" } + +func (m mockCfgTelemetry) OtelExporterGRPCEndpoint() string { return "http://localhost:9001" } + +func (m mockCfgTelemetry) ResourceAttributes() map[string]string { + return map[string]string{"foo": "bar"} +} + +func (m mockCfgTelemetry) TraceSampleRatio() float64 { return 0.42 } func TestLoopRegistry_Register(t *testing.T) { - mockCfgTracing := &MockCfgTracing{} + mockCfgTracing := &mockCfgTracing{} + mockCfgTelemetry := &mockCfgTelemetry{} registry := make(map[string]*RegisteredLoop) // Create a LoopRegistry instance with mockCfgTracing loopRegistry := &LoopRegistry{ - lggr: logger.TestLogger(t), - registry: registry, - cfgTracing: mockCfgTracing, + lggr: logger.TestLogger(t), + registry: registry, + cfgTracing: mockCfgTracing, + cfgTelemetry: mockCfgTelemetry, } // Test case 1: Register new loop registeredLoop, err := loopRegistry.Register("testID") require.Nil(t, err) require.Equal(t, "testID", registeredLoop.Name) - require.True(t, registeredLoop.EnvCfg.TracingEnabled) - require.Equal(t, "http://localhost:9000", registeredLoop.EnvCfg.TracingCollectorTarget) - require.Equal(t, map[string]string{"attribute": "value"}, registeredLoop.EnvCfg.TracingAttributes) - require.Equal(t, 0.1, registeredLoop.EnvCfg.TracingSamplingRatio) - require.Equal(t, "/path/to/cert.pem", registeredLoop.EnvCfg.TracingTLSCertPath) + + envCfg := registeredLoop.EnvCfg + require.True(t, envCfg.TracingEnabled) + require.Equal(t, "http://localhost:9000", envCfg.TracingCollectorTarget) + require.Equal(t, map[string]string{"attribute": "value"}, envCfg.TracingAttributes) + require.Equal(t, 0.1, envCfg.TracingSamplingRatio) + require.Equal(t, "/path/to/cert.pem", envCfg.TracingTLSCertPath) + + require.True(t, envCfg.TelemetryEnabled) + require.True(t, envCfg.TelemetryInsecureConnection) + require.Equal(t, "path/to/cert.pem", envCfg.TelemetryCACertFile) + require.Equal(t, "http://localhost:9001", envCfg.TelemetryEndpoint) + require.Equal(t, loop.OtelAttributes{"foo": "bar"}, envCfg.TelemetryAttributes) + require.Equal(t, 0.42, envCfg.TelemetryTraceSampleRatio) } diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index 1177b0d97e..9dcec7a45c 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -292,6 +292,13 @@ AuthTimestampToleranceSec = 0 ID = '' URL = '' +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 + Invalid configuration: invalid secrets: 2 errors: - Database.URL: empty: must be provided and non-empty - Password.Keystore: empty: must be provided and non-empty diff --git a/testdata/scripts/node/validate/defaults-override.txtar b/testdata/scripts/node/validate/defaults-override.txtar index 07bdea1ce1..3feb595be0 100644 --- a/testdata/scripts/node/validate/defaults-override.txtar +++ b/testdata/scripts/node/validate/defaults-override.txtar @@ -353,6 +353,13 @@ AuthTimestampToleranceSec = 0 ID = '' URL = '' +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index 6555292405..cd0e2f7fa1 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -336,6 +336,13 @@ AuthTimestampToleranceSec = 0 ID = '' URL = '' +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 93769eb6c6..07ed2c398a 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -336,6 +336,13 @@ AuthTimestampToleranceSec = 0 ID = '' URL = '' +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index eaf38bf2a5..3bb1179218 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -336,6 +336,13 @@ AuthTimestampToleranceSec = 0 ID = '' URL = '' +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar index a434f75048..5c9d676572 100644 --- a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -321,6 +321,13 @@ AuthTimestampToleranceSec = 0 ID = '' URL = '' +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 + Invalid configuration: invalid configuration: P2P.V2.Enabled: invalid value (false): P2P required for OCR or OCR2. Please enable P2P or disable OCR/OCR2. -- err.txt -- diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 4838ddc61c..e210c89382 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -326,6 +326,13 @@ AuthTimestampToleranceSec = 0 ID = '' URL = '' +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index f7349ed533..a11fd5f892 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -333,6 +333,13 @@ AuthTimestampToleranceSec = 0 ID = '' URL = '' +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 + [[EVM]] ChainID = '1' AutoCreateKey = true diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index f900bc9626..071da2d268 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -315,6 +315,13 @@ AuthTimestampToleranceSec = 0 ID = '' URL = '' +[Telemetry] +Enabled = false +CACertFile = '' +Endpoint = '' +InsecureConnection = false +TraceSampleRatio = 0.01 + # Configuration warning: Tracing.TLSCertPath: invalid value (something): must be empty when Tracing.Mode is 'unencrypted' Valid configuration. From 9a3e76aa604a425741b197f1424b74eff6ae1031 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 11 Sep 2024 16:04:08 -0500 Subject: [PATCH 335/432] .github/pull_request_template.md: shorter (#14404) --- .github/pull_request_template.md | 36 +++++++------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 291bfe4ce8..7e3ec81243 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,36 +1,16 @@ - -### Requires Dependencies - -### Resolves Dependencies - From a2514d725f66e2c4a66d9bd0dd211a617fa32367 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Thu, 12 Sep 2024 07:11:18 +0200 Subject: [PATCH 336/432] [TT-1546] change the parameter of chains' Confirm() function (#14388) * pass *types.Transaction instead of common.Hash to chain's Confirm() function * fix lints --- .../ccip/changeset/2_initial_deploy_test.go | 6 +++--- integration-tests/deployment/ccip/deploy.go | 2 +- .../deployment/ccip/deploy_home_chain.go | 2 +- integration-tests/deployment/environment.go | 4 ++-- .../deployment/memory/environment.go | 15 ++++++++++----- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go index 1100978bc8..8098ebaef2 100644 --- a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go +++ b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go @@ -101,21 +101,21 @@ func Test0002_InitialDeploy(t *testing.T) { Value: fee, }) require.NoError(t, err) - _, err = srcChain.Confirm(tx.Hash()) + _, err = srcChain.Confirm(tx) require.NoError(t, err) // TODO: should be able to avoid this by using native? tx, err = state.Chains[src].Weth9.Approve(e.Chains[src].DeployerKey, state.Chains[src].Router.Address(), fee) require.NoError(t, err) - _, err = srcChain.Confirm(tx.Hash()) + _, err = srcChain.Confirm(tx) require.NoError(t, err) t.Logf("Sending CCIP request from chain selector %d to chain selector %d", src, dest) tx, err = state.Chains[src].Router.CcipSend(e.Chains[src].DeployerKey, dest, msg) require.NoError(t, err) - _, err = srcChain.Confirm(tx.Hash()) + _, err = srcChain.Confirm(tx) require.NoError(t, err) } } diff --git a/integration-tests/deployment/ccip/deploy.go b/integration-tests/deployment/ccip/deploy.go index 01368c14a4..eb2ddae293 100644 --- a/integration-tests/deployment/ccip/deploy.go +++ b/integration-tests/deployment/ccip/deploy.go @@ -87,7 +87,7 @@ func deployContract[C Contracts]( lggr.Errorw("Failed to deploy contract", "err", contractDeploy.Err) return nil, contractDeploy.Err } - _, err := chain.Confirm(contractDeploy.Tx.Hash()) + _, err := chain.Confirm(contractDeploy.Tx) if err != nil { lggr.Errorw("Failed to confirm deployment", "err", err) return nil, err diff --git a/integration-tests/deployment/ccip/deploy_home_chain.go b/integration-tests/deployment/ccip/deploy_home_chain.go index 33e9c14f8b..1fe6bd5d56 100644 --- a/integration-tests/deployment/ccip/deploy_home_chain.go +++ b/integration-tests/deployment/ccip/deploy_home_chain.go @@ -143,7 +143,7 @@ func AddNodes( if err != nil { return err } - _, err = chain.Confirm(tx.Hash()) + _, err = chain.Confirm(tx) return err } diff --git a/integration-tests/deployment/environment.go b/integration-tests/deployment/environment.go index 2e28bff5ab..5dfa1cd24e 100644 --- a/integration-tests/deployment/environment.go +++ b/integration-tests/deployment/environment.go @@ -43,7 +43,7 @@ type Chain struct { Client OnchainClient // Note the Sign function can be abstract supporting a variety of key storage mechanisms (e.g. KMS etc). DeployerKey *bind.TransactOpts - Confirm func(tx common.Hash) (uint64, error) + Confirm func(tx *types.Transaction) (uint64, error) } type Environment struct { @@ -72,7 +72,7 @@ func ConfirmIfNoError(chain Chain, tx *types.Transaction, err error) (uint64, er } return 0, err } - return chain.Confirm(tx.Hash()) + return chain.Confirm(tx) } func MaybeDataErr(err error) error { diff --git a/integration-tests/deployment/memory/environment.go b/integration-tests/deployment/memory/environment.go index fcccdca373..30606f2e9e 100644 --- a/integration-tests/deployment/memory/environment.go +++ b/integration-tests/deployment/memory/environment.go @@ -2,15 +2,17 @@ package memory import ( "context" + "fmt" "testing" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/hashicorp/consul/sdk/freeport" - chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" "github.com/smartcontractkit/chainlink-common/pkg/logger" @@ -39,16 +41,19 @@ func NewMemoryChains(t *testing.T, numChains int) map[uint64]deployment.Chain { Selector: sel, Client: chain.Backend, DeployerKey: chain.DeployerKey, - Confirm: func(tx common.Hash) (uint64, error) { + Confirm: func(tx *types.Transaction) (uint64, error) { + if tx == nil { + return 0, fmt.Errorf("tx was nil, nothing to confirm") + } for { chain.Backend.Commit() - receipt, err := chain.Backend.TransactionReceipt(context.Background(), tx) + receipt, err := chain.Backend.TransactionReceipt(context.Background(), tx.Hash()) if err != nil { t.Log("failed to get receipt", err) continue } if receipt.Status == 0 { - t.Logf("Status (reverted) %d for txhash %s\n", receipt.Status, tx.String()) + t.Logf("Status (reverted) %d for txhash %s\n", receipt.Status, tx.Hash().Hex()) } return receipt.BlockNumber.Uint64(), nil } From 6f8de6031f40dd3ab28a10f8c5a19f74a5841d51 Mon Sep 17 00:00:00 2001 From: Dimitris Grigoriou Date: Thu, 12 Sep 2024 11:16:31 +0300 Subject: [PATCH 337/432] Add doc (#14359) * Add doc * Update docs * Fixes * Nit fixes * Update core/chains/evm/gas/docs/FEE_HISTORY_ESTIMATOR.md Co-authored-by: amit-momin <108959691+amit-momin@users.noreply.github.com> * Fixes --------- Co-authored-by: amit-momin <108959691+amit-momin@users.noreply.github.com> --- .../evm/gas/docs/FEE_HISTORY_ESTIMATOR.md | 56 +++++++++++++++++++ core/chains/evm/gas/fee_history_estimator.go | 2 +- 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 core/chains/evm/gas/docs/FEE_HISTORY_ESTIMATOR.md diff --git a/core/chains/evm/gas/docs/FEE_HISTORY_ESTIMATOR.md b/core/chains/evm/gas/docs/FEE_HISTORY_ESTIMATOR.md new file mode 100644 index 0000000000..7f541344a3 --- /dev/null +++ b/core/chains/evm/gas/docs/FEE_HISTORY_ESTIMATOR.md @@ -0,0 +1,56 @@ +# Fee History Estimator + +## Overview +`Fee History` estimator is an EVM-based gas estimator that utilizes RPC calls to make gas price estimations. The estimator heavily relies on two RPC calls: `eth_gasPrice` and `eth_feeHistory`. It is built as a service and caches the calculated results in order to minimize overhead. While bumping, it prioritizes using the latest result from most recent blocks if it exceeds the bumped gas price. `Fee History` estimator supports both Legacy and Dynamic(EIP-1559) transactions. It can also handle chains that don't have a mempool and process transactions on an FCFS basis. + +## Configs +- `BumpPercent`: is the percentage by which to bump gas on a transaction. This is used when the estimator's bumping API gets called. +- `CacheTimeout`: is the time to wait to refresh the cached values. A small jitter is applied so the timeout won't be exactly the same each time. +- `EIP1559`: enables EIP-1559 mode and deactivates Legacy estimations. This means the estimator will refresh prices and make estimations only for Dynamic transactions. + +The rest of the configs are only applicable when `EIP1559` is enabled + +- `BlockHistorySize`: controls the number of past blocks to include during gas calculations. If set to 0, the estimator will skip any priority fee calculation and calculate the underlying base fee. This config should be set to 0 for chains that don't have a mempool. +- `RewardPercentile`: specifies which fee percentile to pick from for each processed past block. + +### Validations +During startup, the estimator will perform two config checks: +- `BumpPercent` is equal to or higher than *MinimumBumpPercentage*. *MinimumBumpPercentage* is fixed at 10% and it's the minimum percentage allowed by Geth when bumping a transaction, to prevent spam attacks. Replacing a transaction with a price less than 10% from the previous one will result in an error on the RPC side. Even for chains that don't enforce that rule, a 10% bump seems reasonable. +- `RewardPercentile` is equal or lower than *ConnectivityPercentile*, when `EIP1559` is enabled. *ConnectivityPercentile* is fixed at the 85th percentile and it's the maximum percentile we're willing to bump a transaction's price. This is used as a sanity check method in order to avoid excessive gas bumping when an RPC is not responding. + +## As a Service +`Fee History` estimator is built as a service. This means it will periodically poll the RPC for new prices, perform off-chain calculations, and cache the result for future use. For simplicity, only one type of gas estimation can be enabled at a time, Legacy or Dynamic. The poll interval is controlled by `CacheTimeout`. This value should be close to the block time. For slower chains, like Ethereum, you can set it to 12s, the same as the block time. For faster chains, you can skip a block or two, as prices will be refreshed more frequently. Ideally, 1s should be the absolute minimum. + + +## Legacy Gas Price Estimations +### Fetching +Periodically, `Fee History` estimator will call `eth_gasPrice` RPC method to fetch the gas price reported by the RPC. The parameters of this call can not be controlled by the user, meaning the result can sometimes be stale, especially during sudden gas spikes. It is advisable to use EIP-1559 if the chain supports it. + +### Bumping +During bumping, `Fee History` will refresh the cached value by making a call to the RPC. The bumped value of the original price will be compared with the market price and the highest value will be returned. + +## Dynamic Price Estimations +### Fetching +`Fee History` estimator periodically calls `eth_feeHistory` method to get the most up-to-date information from the RPC (more information about the call can be found [here](https://ethereum.github.io/execution-apis/api-documentation/)). It fetches three things: +- Base Fee of the next block +- The Yth priority fee percentiles of the past X blocks, where Y is controlled by `RewardPercentile` and X by `BlockHistorySize`. +- The 85th priority fee percentiles of the past X blocks. + +The above values are used to construct and cache the following: +- **MaxPriorityFeePerGas**: the average of Yth priority fee percentiles, excluding zero values. +- **MaxFeePerGas**: `baseFee * BaseFeeBufferPercentage + MaxPriorityFeePerGas`. *BaseFeeBufferPercentage* is used as a safety to catch any fluctuations in the Base Fee during the next blocks. +- **PriorityFeeThreshold**: the max out of every 85th priority fee percentile. This value is used to stop the estimator from bumping a price above that threshold and represents the maximum allowed value. + +*Note*: for chains that don't have a mempool (activated with `BlockHistorySize=0`) **MaxPriorityFeePerGas** and **PriorityFeeThreshold** are set to 0 since there is no concept of gas bumping. + +### Bumping +For bumping, `Fee History` estimator bumps both maxPriorityFeePerGas and maxFeePerGas of the original transaction attempt. This is required by Geth, along with the 10% minimum bumping threshold. The bumped price is compared to the cached market prices stored in the estimator and the highest of the two is picked. Finally, the resulting maxPriorityFeePerGas gets compared to the cached PriorityFeeThreshold value. If the bumped value is higher, this indicates a potential connection issue with the RPC, and bumping is skipped, returning an error. + +*Note*: for chains that don't have a mempool (activated with `BlockHistorySize=0`) bumping works differently. Instead, we force-fetch the most up-to-date Base Fee value and embed it in the MaxFeePerGas. MaxPriorityFeePerGas remains 0. + +### Metrics +The following prometheus metrics are exposed: +- **gas_price_updater**: latest Gas Price stored +- **base_fee_updater**: Base Fee of the next block +- **max_priority_fee_per_gas_updater**: latest MaxPriorityFeePerGas stored +- **max_fee_per_gas_updater**: latest MaxFeePerGas stored \ No newline at end of file diff --git a/core/chains/evm/gas/fee_history_estimator.go b/core/chains/evm/gas/fee_history_estimator.go index 53af03ac7a..2b2bc66fcb 100644 --- a/core/chains/evm/gas/fee_history_estimator.go +++ b/core/chains/evm/gas/fee_history_estimator.go @@ -277,7 +277,7 @@ func (f *FeeHistoryEstimator) RefreshDynamicPrice() error { priorityFeeThresholdWei = assets.NewWei(priorityFeeThreshold) maxPriorityFeePerGas = assets.NewWei(priorityFee.Div(priorityFee, big.NewInt(nonZeroRewardsLen))) } - // baseFeeBufferPercentage is added on top as a safety to catch fluctuations in the next blocks. + // BaseFeeBufferPercentage is used as a safety to catch any fluctuations in the Base Fee during the next blocks. maxFeePerGas := nextBaseFee.AddPercentage(BaseFeeBufferPercentage).Add(maxPriorityFeePerGas) promFeeHistoryEstimatorBaseFee.WithLabelValues(f.chainID.String()).Set(float64(nextBaseFee.Int64())) From 3ad2953d26cd7a0bd2685e84d8999eef8fda754e Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs <5300706+iljapavlovs@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:53:55 +0300 Subject: [PATCH 338/432] Chore/devsvcs 499 (#14408) * DEVSVCS-499: adding VRF v2 test configs for CTF tests * DEVSVCS-499: improving formatting * Update vrfv2 workflows * DEVSVCS-499: removing unnecessary workflows; adding on demand workflow for VRF v2 smoke tests --------- Co-authored-by: lukaszcl <120112546+lukaszcl@users.noreply.github.com> --- .github/e2e-tests.yml | 2 +- .../on-demand-vrfv2-eth2-clients-test.yml | 79 ---------- .../on-demand-vrfv2-performance-test.yml | 147 +++++++++--------- .../workflows/on-demand-vrfv2-smoke-tests.yml | 97 ++++++++++++ .../on-demand-vrfv2plus-eth2-clients-test.yml | 53 ------- integration-tests/smoke/vrfv2_test.go | 54 +++---- .../arbitrum_sepolia_new_env_test_config.toml | 5 + .../avalanche_fuji_new_env_test_config.toml | 5 + .../bsc_testnet_new_env_test_config.toml | 5 + .../polygon_amoy_new_env_test_config.toml | 5 + .../new_env/sepolia_new_env_test_config.toml | 5 + .../polygon_amoy_staging_test_config.toml | 24 +++ ...arbitrum_sepolia_new_env_test_config.toml} | 2 +- .../avalanche_fuji_new_env_test_config.toml} | 2 +- .../base_sepolia_new_env_test_config.toml} | 2 +- .../bsc_testnet_new_env_test_config.toml} | 2 +- .../nexon_dev_new_env_test_config.toml} | 2 +- .../nexon_qa_new_env_test_config.toml} | 2 +- .../nexon_stage_new_env_test_config.toml} | 2 +- .../nexon_test_new_env_test_config.toml} | 2 +- ...optimism_sepolia_new_env_test_config.toml} | 2 +- .../polygon_amoy_new_env_test_config.toml} | 2 +- .../sepolia_new_env_test_config.toml} | 2 +- .../arbitrum_sepolia_staging_test_config.toml | 2 +- .../avalanche_fuji_staging_test_config.toml | 2 +- .../base_sepolia_staging_test_config.toml | 2 +- .../bsc_testnet_staging_test_config.toml | 2 +- .../nexon_dev_staging_test_config.toml | 2 +- .../staging/nexon_qa_staging_test_config.toml | 1 + .../nexon_test_staging_test_config.toml | 2 +- .../optimism_sepolia_staging_test_config.toml | 2 +- .../polygon_amoy_staging_test_config.toml | 2 +- .../staging/sepolia_staging_test_config.toml | 2 +- 33 files changed, 267 insertions(+), 255 deletions(-) delete mode 100644 .github/workflows/on-demand-vrfv2-eth2-clients-test.yml create mode 100644 .github/workflows/on-demand-vrfv2-smoke-tests.yml delete mode 100644 .github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml create mode 100644 integration-tests/testconfig/vrfv2/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2/overrides/new_env/avalanche_fuji_new_env_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2/overrides/new_env/bsc_testnet_new_env_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2/overrides/new_env/polygon_amoy_new_env_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2/overrides/new_env/sepolia_new_env_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2/overrides/staging/polygon_amoy_staging_test_config.toml rename integration-tests/testconfig/vrfv2plus/overrides/{release_testing/arbitrum_sepolia_release_test_config.toml => new_env/arbitrum_sepolia_new_env_test_config.toml} (78%) rename integration-tests/testconfig/vrfv2plus/overrides/{release_testing/avalanche_fuji_release_test_config.toml => new_env/avalanche_fuji_new_env_test_config.toml} (77%) rename integration-tests/testconfig/vrfv2plus/overrides/{release_testing/base_sepolia_release_test_config.toml => new_env/base_sepolia_new_env_test_config.toml} (76%) rename integration-tests/testconfig/vrfv2plus/overrides/{release_testing/bsc_testnet_release_test_config.toml => new_env/bsc_testnet_new_env_test_config.toml} (75%) rename integration-tests/testconfig/vrfv2plus/overrides/{release_testing/nexon_dev_release_test_config.toml => new_env/nexon_dev_new_env_test_config.toml} (75%) rename integration-tests/testconfig/vrfv2plus/overrides/{release_testing/nexon_qa_release_test_config.toml => new_env/nexon_qa_new_env_test_config.toml} (74%) rename integration-tests/testconfig/vrfv2plus/overrides/{release_testing/nexon_stage_release_test_config.toml => new_env/nexon_stage_new_env_test_config.toml} (75%) rename integration-tests/testconfig/vrfv2plus/overrides/{release_testing/nexon_test_release_test_config.toml => new_env/nexon_test_new_env_test_config.toml} (75%) rename integration-tests/testconfig/vrfv2plus/overrides/{release_testing/optimism_sepolia_release_test_config.toml => new_env/optimism_sepolia_new_env_test_config.toml} (78%) rename integration-tests/testconfig/vrfv2plus/overrides/{release_testing/polygon_amoy_release_test_config.toml => new_env/polygon_amoy_new_env_test_config.toml} (76%) rename integration-tests/testconfig/vrfv2plus/overrides/{release_testing/sepolia_release_test_config.toml => new_env/sepolia_new_env_test_config.toml} (73%) diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index b08de2074e..9ec19a48db 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -722,7 +722,7 @@ runner-test-matrix: runs_on: ubuntu-latest test_env_type: docker test_cmd: cd integration-tests/smoke && go test -v -test.run "TestVRFv2Plus$/(Link_Billing|Native_Billing|Direct_Funding)|TestVRFV2PlusWithBHS" -test.parallel=1 -timeout 2h -count=1 -json - test_config_override_path: integration-tests/testconfig/vrfv2plus/overrides/release_testing/sepolia_release_test_config.toml + test_config_override_path: integration-tests/testconfig/vrfv2plus/overrides/new_env/sepolia_new_env_test_config.toml workflows: - VRF E2E Release Tests diff --git a/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml b/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml deleted file mode 100644 index b949db0911..0000000000 --- a/.github/workflows/on-demand-vrfv2-eth2-clients-test.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: On Demand VRFV2 Smoke Test (Ethereum clients) -on: - workflow_dispatch: - inputs: - base64Config: - description: base64-ed config - required: true - type: string - test_secrets_override_key: - description: 'Key to run tests with custom test secrets' - required: false - type: string - -jobs: - vrfv2_smoke_test: - name: VRFV2 Smoke Test with custom EL client client - environment: integration - runs-on: ubuntu22.04-8cores-32GB - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - env: - TEST_LOG_LEVEL: debug - REF_NAME: ${{ github.head_ref || github.ref_name }} - steps: - - name: Checkout code - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Mask base64 config - run: | - BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64Config' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - name: Parse base64 config - uses: ./.github/actions/setup-parse-base64-config - with: - base64Config: ${{ env.BASE64_CONFIG_OVERRIDE }} - - name: Send details to Step Summary - shell: bash - run: | - echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_IMAGE }}\`" >>$GITHUB_STEP_SUMMARY - echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY - echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - echo "### Execution client used" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.ETH2_EL_CLIENT }}\`" >>$GITHUB_STEP_SUMMARY - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 - with: - test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -run TestVRFv2Basic ./smoke/vrfv2_test.go 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} - test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ env.CHAINLINK_VERSION }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: vrf-test-logs - artifacts_location: | - ./integration-tests/smoke/logs/ - ./integration-tests/smoke/db_dumps/ - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - should_cleanup: false - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: "" - env: - E2E_TEST_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" - E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} diff --git a/.github/workflows/on-demand-vrfv2-performance-test.yml b/.github/workflows/on-demand-vrfv2-performance-test.yml index b5a4c40d12..ad8640ccfa 100644 --- a/.github/workflows/on-demand-vrfv2-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2-performance-test.yml @@ -2,10 +2,6 @@ name: On Demand VRFV2 Performance Test on: workflow_dispatch: inputs: - base64Config: - description: base64-ed config - required: true - type: string performanceTestType: description: Performance Test Type of test to run type: choice @@ -19,82 +15,81 @@ on: description: "Regex for tests to run" required: false default: "(TestVRFV2Performance)" + test_config_override_path: + description: Path to a test config file used to override the default test config + required: false + type: string test_secrets_override_key: description: 'Key to run tests with custom test secrets' required: false type: string - + notify_user_id_on_failure: + description: 'Enter Slack user ID to notify on test failure' + required: false + type: string + jobs: - vrfv2_performance_test: - name: VRFV2 Performance Test - environment: integration - runs-on: ubuntu22.04-8cores-32GB - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - env: - LOKI_URL: ${{ secrets.LOKI_URL }} - LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} - LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} - TEST_TYPE: ${{ inputs.performanceTestType }} - TEST_LOG_LEVEL: debug - REF_NAME: ${{ github.head_ref || github.ref_name }} - SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} - SLACK_CHANNEL: ${{ secrets.QA_VRF_SLACK_CHANNEL }} - GRAFANA_URL: "http://localhost:8080/primary" - GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - WASP_LOG_LEVEL: info + set-tests-to-run: + name: Set tests to run + runs-on: ubuntu-latest + outputs: + test_list: ${{ steps.set-tests.outputs.test_list }} steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: on-demand-vrfv2-performance-test - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ${{ inputs.network }} VRFV2 Performance Test - continue-on-error: true - - name: Checkout code - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Mask base64 config + - name: Generate Test List JSON + id: set-tests run: | - BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64Config' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - name: Merge and export base64 config - uses: ./.github/actions/setup-merge-base64-config - with: - base64Config: ${{ env.BASE64_CONFIG_OVERRIDE }} - - name: Send details to Step Summary - shell: bash - run: | - echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_IMAGE }}\`" >>$GITHUB_STEP_SUMMARY - echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY - echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 - with: - test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run "${{ inputs.test_list_regex }}" ./vrfv2 - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} - test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ env.CHAINLINK_VERSION }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: vrf-test-logs - artifacts_location: ./integration-tests/load/vrfv2/logs/ - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - should_cleanup: false - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + TEST_CMD='cd integration-tests/load && go test -v -count=1 -timeout 24h -run "${{ inputs.test_list_regex }}" ./vrfv2' + TEST_CONFIG_OVERRIDE_PATH=${{ inputs.test_config_override_path }} + TEST_TYPE=${{ inputs.performanceTestType }} + + TEST_LIST=$(jq -n -c \ + --arg test_cmd "$TEST_CMD" \ + --arg test_config_override_path "$TEST_CONFIG_OVERRIDE_PATH" \ + --arg TEST_TYPE "$TEST_TYPE" \ + '{ + "tests": [ + { + "id": "TestVRFv2Plus_Performance", + "path": "integration-tests/load/vrfv2plus/vrfv2plus_test.go", + "runs_on": "ubuntu22.04-8cores-32GB", + "test_env_type": "docker", + "test_cmd": $test_cmd, + "test_config_override_path": $test_config_override_path, + "test_env_vars": { + "TEST_TYPE": $TEST_TYPE + } + } + ] + }') + + echo "test_list=$TEST_LIST" >> $GITHUB_OUTPUT + + run-e2e-tests-workflow: + name: Run E2E Tests + needs: set-tests-to-run + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} + chainlink_version: ${{ inputs.chainlink_version }} + slack_notification_after_tests: always + slack_notification_after_tests_name: "VRF V2 Performance Tests with test config: ${{ inputs.test_config_override_path || 'default' }}" + slack_notification_after_tests_notify_user_id_on_failure: ${{ inputs.notify_user_id_on_failure }} + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} + SLACK_CHANNEL: ${{ secrets.QA_VRF_SLACK_CHANNEL }} diff --git a/.github/workflows/on-demand-vrfv2-smoke-tests.yml b/.github/workflows/on-demand-vrfv2-smoke-tests.yml new file mode 100644 index 0000000000..ede71267b4 --- /dev/null +++ b/.github/workflows/on-demand-vrfv2-smoke-tests.yml @@ -0,0 +1,97 @@ +name: On Demand VRFV2 Smoke Tests +on: + workflow_dispatch: + inputs: + test_suite: + description: "Test Suite to run" + required: true + type: choice + default: "All Tests" + options: + - "All Tests" + - "Selected Tests" + test_list_regex: + description: "Regex for 'Selected Tests' to run" + required: false + default: "TestVRFv2Basic/(Request_Randomness|Direct_Funding)|TestVRFV2WithBHS" + test_config_override_path: + description: Path to a test config file used to override the default test config + required: false + type: string + test_secrets_override_key: + description: 'Key to run tests with custom test secrets' + required: false + type: string + chainlink_version: + description: Chainlink image version to use + default: develop + required: false + type: string + notify_user_id_on_failure: + description: 'Enter Slack user ID to notify on test failure' + required: false + type: string + +jobs: + set-tests-to-run: + name: Set tests to run + runs-on: ubuntu-latest + outputs: + test_list: ${{ steps.set-tests.outputs.test_list }} + steps: + - name: Generate Test List JSON + id: set-tests + run: | + if [[ "${{ inputs.test_suite }}" == "All Tests" ]]; then + TEST_CMD="cd integration-tests/smoke && go test vrfv2_test.go -test.parallel=1 -timeout 3h -count=1 -json -v" + else + TEST_CMD='cd integration-tests/smoke && go test -test.run "${{ inputs.test_list_regex }}" -test.parallel=1 -timeout 2h -count=1 -json -v' + fi + TEST_CONFIG_OVERRIDE_PATH=${{ inputs.test_config_override_path }} + + TEST_LIST=$(jq -n -c \ + --arg test_cmd "$TEST_CMD" \ + --arg test_config_override_path "$TEST_CONFIG_OVERRIDE_PATH" \ + '{ + "tests": [ + { + "id": "TestVRFv2_Smoke", + "path": "integration-tests/smoke/vrfv2_test.go", + "runs_on": "ubuntu-latest", + "test_env_type": "docker", + "test_cmd": $test_cmd, + "test_config_override_path": $test_config_override_path + } + ] + }') + + echo "test_list=$TEST_LIST" >> $GITHUB_OUTPUT + + run-e2e-tests-workflow: + name: Run E2E Tests + needs: set-tests-to-run + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} + chainlink_version: ${{ inputs.chainlink_version }} + slack_notification_after_tests: always + slack_notification_after_tests_name: "VRF V2 Smoke Tests with test config: ${{ inputs.test_config_override_path || 'default' }}" + slack_notification_after_tests_notify_user_id_on_failure: ${{ inputs.notify_user_id_on_failure }} + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + SLACK_NOTIFICATION_AFTER_TESTS_CHANNEL_ID: ${{ secrets.QA_VRF_SLACK_CHANNEL }} diff --git a/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml b/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml deleted file mode 100644 index f3921a814f..0000000000 --- a/.github/workflows/on-demand-vrfv2plus-eth2-clients-test.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: On Demand VRFV2Plus Smoke Test (Ethereum clients) -on: - workflow_dispatch: - inputs: - test_config_override_path: - description: Path to a test config file used to override the default test config - required: false - type: string - test_secrets_override_key: - description: 'Key to run tests with custom test secrets' - required: false - type: string - chainlink_version: - description: Chainlink image version to use - default: develop - required: true - type: string - -jobs: - run-e2e-tests-workflow: - name: Run E2E Tests - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml - with: - custom_test_list_json: > - { - "tests": [ - { - "id": "TestVRFv2Plus", - "path": "integration-tests/smoke/vrfv2plus_test.go", - "runs_on": "ubuntu-latest", - "test_env_type": "docker", - "test_cmd": "cd integration-tests/smoke && go test -timeout 30m -count=1 -json -run ^TestVRFv2Plus$/^Link_Billing$ .vrfv2plus_test.go - } - ] - } - test_config_override_path: ${{ inputs.test_config_override_path }} - chainlink_version: ${{ inputs.chainlink_version }} - secrets: - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} - QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} - GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index 872d641303..8390c27a4b 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -813,7 +813,6 @@ func TestVRFV2WithBHS(t *testing.T) { require.NoError(t, err, "Error getting config") vrfv2Config := config.VRFv2 chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID - configPtr := &config //decrease default span for checking blockhashes for unfulfilled requests @@ -840,7 +839,6 @@ func TestVRFV2WithBHS(t *testing.T) { } //BHS node should fill in blockhashes into BHS contract depending on the waitBlocks and lookBackBlocks settings configCopy := config.MustCopy().(tc.TestConfig) - //Underfund Subscription configCopy.VRFv2.General.SubscriptionFundingAmountLink = ptr.Ptr(float64(0)) consumers, subIDsForBHS, err := vrfv2.SetupNewConsumersAndSubs( @@ -944,9 +942,7 @@ func TestVRFV2WithBHS(t *testing.T) { SethRootKeyIndex, ) require.NoError(t, err, "error requesting randomness") - randRequestBlockNumber := randomWordsRequestedEvent.Raw.BlockNumber - _, err = vrfContracts.BHS.GetBlockHash(testcontext.Get(t), big.NewInt(int64(randRequestBlockNumber))) require.Error(t, err, "error not occurred when getting blockhash for a blocknumber which was not stored in BHS contract") @@ -967,30 +963,37 @@ func TestVRFV2WithBHS(t *testing.T) { metrics, err := consumers[0].GetLoadTestMetrics(testcontext.Get(t)) require.Equal(t, 0, metrics.RequestCount.Cmp(big.NewInt(1))) require.Equal(t, 0, metrics.FulfilmentCount.Cmp(big.NewInt(0))) - - var clNodeTxs *client.TransactionsData - var txHash string gom := gomega.NewGomegaWithT(t) - gom.Eventually(func(g gomega.Gomega) { - clNodeTxs, _, err = nodeTypeToNodeMap[vrfcommon.BHS].CLNode.API.ReadTransactions() - g.Expect(err).ShouldNot(gomega.HaveOccurred(), "error getting CL Node transactions") - l.Info().Int("Number of TXs", len(clNodeTxs.Data)).Msg("BHS Node txs") - g.Expect(len(clNodeTxs.Data)).Should(gomega.BeNumerically("==", 1), "Expected 1 tx posted by BHS Node, but found %d", len(clNodeTxs.Data)) - txHash = clNodeTxs.Data[0].Attributes.Hash - }, "2m", "1s").Should(gomega.Succeed()) - - require.Equal(t, strings.ToLower(vrfContracts.BHS.Address()), strings.ToLower(clNodeTxs.Data[0].Attributes.To)) - bhsStoreTx, _, err := sethClient.Client.TransactionByHash(testcontext.Get(t), common.HexToHash(txHash)) - require.NoError(t, err, "error getting tx from hash") - - bhsStoreTxInputData, err := actions.DecodeTxInputData(blockhash_store.BlockhashStoreABI, bhsStoreTx.Data()) - require.NoError(t, err, "error decoding tx input data") - l.Info(). - Str("Block Number", bhsStoreTxInputData["n"].(*big.Int).String()). - Msg("BHS Node's Store Blockhash for Blocknumber Method TX") - require.Equal(t, randRequestBlockNumber, bhsStoreTxInputData["n"].(*big.Int).Uint64()) + if !*configCopy.VRFv2.General.UseExistingEnv { + l.Info().Msg("Checking BHS Node's transactions") + var clNodeTxs *client.TransactionsData + var txHash string + gom.Eventually(func(g gomega.Gomega) { + clNodeTxs, _, err = nodeTypeToNodeMap[vrfcommon.BHS].CLNode.API.ReadTransactions() + g.Expect(err).ShouldNot(gomega.HaveOccurred(), "error getting CL Node transactions") + g.Expect(len(clNodeTxs.Data)).Should(gomega.BeNumerically("==", 1), "Expected 1 tx posted by BHS Node, but found %d", len(clNodeTxs.Data)) + txHash = clNodeTxs.Data[0].Attributes.Hash + l.Info(). + Str("TX Hash", txHash). + Int("Number of TXs", len(clNodeTxs.Data)). + Msg("BHS Node txs") + }, "2m", "1s").Should(gomega.Succeed()) + + require.Equal(t, strings.ToLower(vrfContracts.BHS.Address()), strings.ToLower(clNodeTxs.Data[0].Attributes.To)) + + bhsStoreTx, _, err := sethClient.Client.TransactionByHash(testcontext.Get(t), common.HexToHash(txHash)) + require.NoError(t, err, "error getting tx from hash") + bhsStoreTxInputData, err := actions.DecodeTxInputData(blockhash_store.BlockhashStoreABI, bhsStoreTx.Data()) + require.NoError(t, err, "error decoding tx input data") + l.Info(). + Str("Block Number", bhsStoreTxInputData["n"].(*big.Int).String()). + Msg("BHS Node's Store Blockhash for Blocknumber Method TX") + require.Equal(t, randRequestBlockNumber, bhsStoreTxInputData["n"].(*big.Int).Uint64()) + } else { + l.Warn().Msg("Skipping BHS Node's transactions check as existing env is used") + } var randRequestBlockHash [32]byte gom.Eventually(func(g gomega.Gomega) { randRequestBlockHash, err = vrfContracts.BHS.GetBlockHash(testcontext.Get(t), big.NewInt(int64(randRequestBlockNumber))) @@ -1440,5 +1443,4 @@ func TestVRFv2BatchFulfillmentEnabledDisabled(t *testing.T) { // verify that all fulfillments should be in separate txs require.Equal(t, int(randRequestCount), len(singleFulfillmentTxs)) }) - } diff --git a/integration-tests/testconfig/vrfv2/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml b/integration-tests/testconfig/vrfv2/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml new file mode 100644 index 0000000000..e383bf27da --- /dev/null +++ b/integration-tests/testconfig/vrfv2/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["ARBITRUM_SEPOLIA"] + +[ARBITRUM_SEPOLIA.VRFv2.General] +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2/overrides/new_env/avalanche_fuji_new_env_test_config.toml b/integration-tests/testconfig/vrfv2/overrides/new_env/avalanche_fuji_new_env_test_config.toml new file mode 100644 index 0000000000..7eb2215284 --- /dev/null +++ b/integration-tests/testconfig/vrfv2/overrides/new_env/avalanche_fuji_new_env_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["AVALANCHE_FUJI"] + +[AVALANCHE_FUJI.VRFv2.General] +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2/overrides/new_env/bsc_testnet_new_env_test_config.toml b/integration-tests/testconfig/vrfv2/overrides/new_env/bsc_testnet_new_env_test_config.toml new file mode 100644 index 0000000000..9652e94626 --- /dev/null +++ b/integration-tests/testconfig/vrfv2/overrides/new_env/bsc_testnet_new_env_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["BSC_TESTNET"] + +[BSC_TESTNET.VRFv2.General] +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2/overrides/new_env/polygon_amoy_new_env_test_config.toml b/integration-tests/testconfig/vrfv2/overrides/new_env/polygon_amoy_new_env_test_config.toml new file mode 100644 index 0000000000..39d4ba849e --- /dev/null +++ b/integration-tests/testconfig/vrfv2/overrides/new_env/polygon_amoy_new_env_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["POLYGON_AMOY"] + +[POLYGON_AMOY.VRFv2.General] +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2/overrides/new_env/sepolia_new_env_test_config.toml b/integration-tests/testconfig/vrfv2/overrides/new_env/sepolia_new_env_test_config.toml new file mode 100644 index 0000000000..914dc26627 --- /dev/null +++ b/integration-tests/testconfig/vrfv2/overrides/new_env/sepolia_new_env_test_config.toml @@ -0,0 +1,5 @@ +[Network] +selected_networks = ["SEPOLIA"] + +[SEPOLIA.VRFv2.General] +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2/overrides/staging/polygon_amoy_staging_test_config.toml b/integration-tests/testconfig/vrfv2/overrides/staging/polygon_amoy_staging_test_config.toml new file mode 100644 index 0000000000..acdff9ff4e --- /dev/null +++ b/integration-tests/testconfig/vrfv2/overrides/staging/polygon_amoy_staging_test_config.toml @@ -0,0 +1,24 @@ +[Network] +selected_networks = ["POLYGON_AMOY"] + +[POLYGON_AMOY.VRFv2.General] +use_existing_env = true + +[POLYGON_AMOY.VRFv2.ExistingEnv] +coordinator_address = "0x919BEF67CE94604A7Cd5747F2c0088C8EB8A93aa" +consumer_address = "" +sub_id = "" +key_hash = "0xcd9c54d52db91522b69fe8ddc40d1f78156795de0efb2adbc053a438b9ee14a6" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 10 +node_sending_keys = [ + "0xD4B787C4ce6E04c16b5FDce2c25956b8F4432195", + # BHS + "0x638372de870eF0F8E675A3f67F18D5bd4A2fd804", + "0xF9eF03816411D037202d5ed4457dC1613e3bd729", + "0xCD66973f8fbaE787211EC20228c6bd90D83562A8", + "0x242ea1F4Bb72EF643B2D8EF22e18a89f00742F40", + "0xaA09B4F9B5710b239fdbf1D0f535dd7f86F91219", + "0xe6b72B647B8B45C5562F7a5259E187889C747d3b", + "0x2c1185C4d3B0B4a577d4079Ee193A4e293164D9d" +] diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/arbitrum_sepolia_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml similarity index 78% rename from integration-tests/testconfig/vrfv2plus/overrides/release_testing/arbitrum_sepolia_release_test_config.toml rename to integration-tests/testconfig/vrfv2plus/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml index a71e662cc4..8f111a3ae0 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/arbitrum_sepolia_release_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml @@ -2,4 +2,4 @@ selected_networks = ["ARBITRUM_SEPOLIA"] [ARBITRUM_SEPOLIA.VRFv2Plus.General] -use_existing_env = false \ No newline at end of file +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/avalanche_fuji_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/avalanche_fuji_new_env_test_config.toml similarity index 77% rename from integration-tests/testconfig/vrfv2plus/overrides/release_testing/avalanche_fuji_release_test_config.toml rename to integration-tests/testconfig/vrfv2plus/overrides/new_env/avalanche_fuji_new_env_test_config.toml index 5219ebe428..8c7203ce7b 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/avalanche_fuji_release_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/avalanche_fuji_new_env_test_config.toml @@ -2,4 +2,4 @@ selected_networks = ["AVALANCHE_FUJI"] [AVALANCHE_FUJI.VRFv2Plus.General] -use_existing_env = false \ No newline at end of file +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/base_sepolia_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/base_sepolia_new_env_test_config.toml similarity index 76% rename from integration-tests/testconfig/vrfv2plus/overrides/release_testing/base_sepolia_release_test_config.toml rename to integration-tests/testconfig/vrfv2plus/overrides/new_env/base_sepolia_new_env_test_config.toml index ffc209d2ad..9cbf7e58b9 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/base_sepolia_release_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/base_sepolia_new_env_test_config.toml @@ -2,4 +2,4 @@ selected_networks = ["BASE_SEPOLIA"] [BASE_SEPOLIA.VRFv2Plus.General] -use_existing_env = false \ No newline at end of file +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/bsc_testnet_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/bsc_testnet_new_env_test_config.toml similarity index 75% rename from integration-tests/testconfig/vrfv2plus/overrides/release_testing/bsc_testnet_release_test_config.toml rename to integration-tests/testconfig/vrfv2plus/overrides/new_env/bsc_testnet_new_env_test_config.toml index 8a8ab538f2..c3c07966fa 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/bsc_testnet_release_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/bsc_testnet_new_env_test_config.toml @@ -2,4 +2,4 @@ selected_networks = ["BSC_TESTNET"] [BSC_TESTNET.VRFv2Plus.General] -use_existing_env = false \ No newline at end of file +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_dev_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_dev_new_env_test_config.toml similarity index 75% rename from integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_dev_release_test_config.toml rename to integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_dev_new_env_test_config.toml index 903e383886..5791b70660 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_dev_release_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_dev_new_env_test_config.toml @@ -2,4 +2,4 @@ selected_networks = ["NEXON_DEV"] [NEXON_DEV.VRFv2Plus.General] -use_existing_env = false \ No newline at end of file +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_qa_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_qa_new_env_test_config.toml similarity index 74% rename from integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_qa_release_test_config.toml rename to integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_qa_new_env_test_config.toml index ff5c62bf04..fb16e8d0c4 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_qa_release_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_qa_new_env_test_config.toml @@ -2,4 +2,4 @@ selected_networks = ["NEXON_QA"] [NEXON_QA.VRFv2Plus.General] -use_existing_env = false \ No newline at end of file +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_stage_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_stage_new_env_test_config.toml similarity index 75% rename from integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_stage_release_test_config.toml rename to integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_stage_new_env_test_config.toml index a504bd8c72..9802b4de24 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_stage_release_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_stage_new_env_test_config.toml @@ -2,4 +2,4 @@ selected_networks = ["NEXON_STAGE"] [NEXON_STAGE.VRFv2Plus.General] -use_existing_env = false \ No newline at end of file +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_test_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_test_new_env_test_config.toml similarity index 75% rename from integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_test_release_test_config.toml rename to integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_test_new_env_test_config.toml index 7551f348fb..ccaa4f332a 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/nexon_test_release_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_test_new_env_test_config.toml @@ -2,4 +2,4 @@ selected_networks = ["NEXON_TEST"] [NEXON_TEST.VRFv2Plus.General] -use_existing_env = false \ No newline at end of file +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/optimism_sepolia_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/optimism_sepolia_new_env_test_config.toml similarity index 78% rename from integration-tests/testconfig/vrfv2plus/overrides/release_testing/optimism_sepolia_release_test_config.toml rename to integration-tests/testconfig/vrfv2plus/overrides/new_env/optimism_sepolia_new_env_test_config.toml index 6ccfa1c4ca..1850365599 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/optimism_sepolia_release_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/optimism_sepolia_new_env_test_config.toml @@ -2,4 +2,4 @@ selected_networks = ["OPTIMISM_SEPOLIA"] [OPTIMISM_SEPOLIA.VRFv2Plus.General] -use_existing_env = false \ No newline at end of file +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/polygon_amoy_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/polygon_amoy_new_env_test_config.toml similarity index 76% rename from integration-tests/testconfig/vrfv2plus/overrides/release_testing/polygon_amoy_release_test_config.toml rename to integration-tests/testconfig/vrfv2plus/overrides/new_env/polygon_amoy_new_env_test_config.toml index e462be8acc..b5423bf6f7 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/polygon_amoy_release_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/polygon_amoy_new_env_test_config.toml @@ -2,4 +2,4 @@ selected_networks = ["POLYGON_AMOY"] [POLYGON_AMOY.VRFv2Plus.General] -use_existing_env = false \ No newline at end of file +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/sepolia_release_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/sepolia_new_env_test_config.toml similarity index 73% rename from integration-tests/testconfig/vrfv2plus/overrides/release_testing/sepolia_release_test_config.toml rename to integration-tests/testconfig/vrfv2plus/overrides/new_env/sepolia_new_env_test_config.toml index cef5136fec..3be47f7d07 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/release_testing/sepolia_release_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/sepolia_new_env_test_config.toml @@ -2,4 +2,4 @@ selected_networks = ["SEPOLIA"] [SEPOLIA.VRFv2Plus.General] -use_existing_env = false \ No newline at end of file +use_existing_env = false diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/arbitrum_sepolia_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/arbitrum_sepolia_staging_test_config.toml index 8ba2128f7a..66529bbed3 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/staging/arbitrum_sepolia_staging_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/arbitrum_sepolia_staging_test_config.toml @@ -33,4 +33,4 @@ node_sending_keys = [ "0x0b946F0bF4e63C12b5157137f1c130f0788bC1b1", # BHF "0x571BBF4a5b07fc3F47Bd3B65CE2FE73739f86623" -] \ No newline at end of file +] diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/avalanche_fuji_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/avalanche_fuji_staging_test_config.toml index 9bf6c723cb..c8566e59a7 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/staging/avalanche_fuji_staging_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/avalanche_fuji_staging_test_config.toml @@ -15,4 +15,4 @@ node_sending_keys = [ "0x3D7Da5D6A23CA2240CE576C8638C1798a023920a", # BHS "0x72c8565279430F5179b0090d51ab8BB53Da323B5" -] \ No newline at end of file +] diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/base_sepolia_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/base_sepolia_staging_test_config.toml index aaab02df7d..ad125ae46b 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/staging/base_sepolia_staging_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/base_sepolia_staging_test_config.toml @@ -17,4 +17,4 @@ node_sending_keys = [ "0xe8B0865e9Aae9DE628BE14965Bbd1C0c9C80d245", # BHS "0x65C853683beB6363869DDda8534b2aD45786d380", -] \ No newline at end of file +] diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/bsc_testnet_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/bsc_testnet_staging_test_config.toml index d1716413f1..48060a88cf 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/staging/bsc_testnet_staging_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/bsc_testnet_staging_test_config.toml @@ -15,4 +15,4 @@ node_sending_keys = [ "0x4EE2Cc6D50E8acb6BaEf673B03559525a6c92fB8", # BHS "0xAFB44568f7DAc218EA6e1C71c366692ED4758A07" -] \ No newline at end of file +] diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_dev_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_dev_staging_test_config.toml index 597abe13af..0121c02552 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_dev_staging_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_dev_staging_test_config.toml @@ -15,4 +15,4 @@ node_sending_keys = [ "0xF3d9879a75BBD85890056D7c6cB37C555F9b41A3", # BHS "0xb544f9D7c16a30af0EEd0afcC4132D1c63bAF8AC", -] \ No newline at end of file +] diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_qa_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_qa_staging_test_config.toml index 5f5feab74a..f45ecde0ed 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_qa_staging_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_qa_staging_test_config.toml @@ -17,3 +17,4 @@ node_sending_keys = [ # BHS "0xf85E291edF0352435f2fD5e817030f6542375a99", ] + diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_test_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_test_staging_test_config.toml index aeb4cbdb29..4f897f4e1d 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_test_staging_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/nexon_test_staging_test_config.toml @@ -16,4 +16,4 @@ node_sending_keys = [ "0xbf6c76024672F233aB8164EC00683e1AE774F6b0", # BHS "0x2a3900Ac77de110670E060DBFf4fCbe36c6f8170", -] \ No newline at end of file +] diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/optimism_sepolia_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/optimism_sepolia_staging_test_config.toml index c707b83f8d..e44085067c 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/staging/optimism_sepolia_staging_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/optimism_sepolia_staging_test_config.toml @@ -17,4 +17,4 @@ node_sending_keys = [ "0x89554391652616ea06a408263b9B2b9a70E87204", # BHS "0x8DE6446b5022C68F38CD32d04AA0E3b8F4C1aaB6", -] \ No newline at end of file +] diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/polygon_amoy_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/polygon_amoy_staging_test_config.toml index 0b49f66ec3..d2f9727483 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/staging/polygon_amoy_staging_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/polygon_amoy_staging_test_config.toml @@ -29,4 +29,4 @@ node_sending_keys = [ "0xaA09B4F9B5710b239fdbf1D0f535dd7f86F91219", "0xe6b72B647B8B45C5562F7a5259E187889C747d3b", "0x2c1185C4d3B0B4a577d4079Ee193A4e293164D9d" -] \ No newline at end of file +] diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/sepolia_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/sepolia_staging_test_config.toml index 346b1d792c..fd2e6f0bc1 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/staging/sepolia_staging_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/sepolia_staging_test_config.toml @@ -15,4 +15,4 @@ node_sending_keys = [ "0x0c0DC7f33A1256f0247c5ea75861d385fa5FED31", # BHS "0xEd8A4b792d16484f6c9B4df1e721e8280925Db80", -] \ No newline at end of file +] From f6443a14e836523dfa8a78b1b98a00999832f204 Mon Sep 17 00:00:00 2001 From: george-dorin <120329946+george-dorin@users.noreply.github.com> Date: Thu, 12 Sep 2024 16:36:17 +0300 Subject: [PATCH 339/432] Change TelemetryIngress.UniConn default to false (#14401) * Change TelemetryIngress.UniConn default to false * Add changeset --- .changeset/five-nails-fold.md | 5 +++++ core/config/docs/core.toml | 2 +- core/services/chainlink/config_telemetry_ingress_test.go | 2 +- core/services/chainlink/config_test.go | 4 ++-- core/services/chainlink/testdata/config-empty-effective.toml | 2 +- core/services/chainlink/testdata/config-full.toml | 2 +- .../chainlink/testdata/config-multi-chain-effective.toml | 2 +- core/web/resolver/testdata/config-empty-effective.toml | 2 +- core/web/resolver/testdata/config-full.toml | 2 +- core/web/resolver/testdata/config-multi-chain-effective.toml | 2 +- docs/CONFIG.md | 4 ++-- testdata/scripts/node/validate/default.txtar | 2 +- testdata/scripts/node/validate/defaults-override.txtar | 2 +- .../scripts/node/validate/disk-based-logging-disabled.txtar | 2 +- .../scripts/node/validate/disk-based-logging-no-dir.txtar | 2 +- testdata/scripts/node/validate/disk-based-logging.txtar | 2 +- testdata/scripts/node/validate/invalid-ocr-p2p.txtar | 2 +- testdata/scripts/node/validate/invalid.txtar | 2 +- testdata/scripts/node/validate/valid.txtar | 2 +- testdata/scripts/node/validate/warnings.txtar | 2 +- 20 files changed, 26 insertions(+), 21 deletions(-) create mode 100644 .changeset/five-nails-fold.md diff --git a/.changeset/five-nails-fold.md b/.changeset/five-nails-fold.md new file mode 100644 index 0000000000..8ddd72a71d --- /dev/null +++ b/.changeset/five-nails-fold.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#updated Changed TelemetryIngress.UniConn default to false diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index d29223a31e..dde898ed3b 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -89,7 +89,7 @@ LeaseRefreshInterval = '1s' # Default [TelemetryIngress] # UniConn toggles which ws connection style is used. -UniConn = true # Default +UniConn = false # Default # Logging toggles verbose logging of the raw telemetry messages being sent. Logging = false # Default # BufferSize is the number of telemetry messages to buffer before dropping new ones. diff --git a/core/services/chainlink/config_telemetry_ingress_test.go b/core/services/chainlink/config_telemetry_ingress_test.go index c371b465a2..64e85b5493 100644 --- a/core/services/chainlink/config_telemetry_ingress_test.go +++ b/core/services/chainlink/config_telemetry_ingress_test.go @@ -17,7 +17,7 @@ func TestTelemetryIngressConfig(t *testing.T) { ticfg := cfg.TelemetryIngress() assert.True(t, ticfg.Logging()) - assert.True(t, ticfg.UniConn()) + assert.False(t, ticfg.UniConn()) assert.Equal(t, uint(1234), ticfg.BufferSize()) assert.Equal(t, uint(4321), ticfg.MaxBatchSize()) assert.Equal(t, time.Minute, ticfg.SendInterval()) diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 1018778b32..8e157de904 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -290,7 +290,7 @@ func TestConfig_Marshal(t *testing.T) { }, } full.TelemetryIngress = toml.TelemetryIngress{ - UniConn: ptr(true), + UniConn: ptr(false), Logging: ptr(true), BufferSize: ptr[uint16](1234), MaxBatchSize: ptr[uint16](4321), @@ -840,7 +840,7 @@ LeaseDuration = '1m0s' LeaseRefreshInterval = '1s' `}, {"TelemetryIngress", Config{Core: toml.Core{TelemetryIngress: full.TelemetryIngress}}, `[TelemetryIngress] -UniConn = true +UniConn = false Logging = true BufferSize = 1234 MaxBatchSize = 4321 diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index f78c98896d..4cfe5e2086 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -35,7 +35,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index e000ff82d4..eb69cee8b7 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -35,7 +35,7 @@ LeaseDuration = '1m0s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = true BufferSize = 1234 MaxBatchSize = 4321 diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index fc11ed10b1..776481ed6a 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -35,7 +35,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index f78c98896d..4cfe5e2086 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -35,7 +35,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index a13a6b9db5..ee413a610e 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -35,7 +35,7 @@ LeaseDuration = '1m0s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = true BufferSize = 1234 MaxBatchSize = 4321 diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index a3853dd2b4..210894d616 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -35,7 +35,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 2f339dfda4..c9262577f1 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -256,7 +256,7 @@ LeaseRefreshInterval determines how often to refresh the lease lock. Also contro ## TelemetryIngress ```toml [TelemetryIngress] -UniConn = true # Default +UniConn = false # Default Logging = false # Default BufferSize = 100 # Default MaxBatchSize = 50 # Default @@ -268,7 +268,7 @@ UseBatchSend = true # Default ### UniConn ```toml -UniConn = true # Default +UniConn = false # Default ``` UniConn toggles which ws connection style is used. diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index 9dcec7a45c..ad923919e0 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -47,7 +47,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 diff --git a/testdata/scripts/node/validate/defaults-override.txtar b/testdata/scripts/node/validate/defaults-override.txtar index 3feb595be0..52eb86b3e6 100644 --- a/testdata/scripts/node/validate/defaults-override.txtar +++ b/testdata/scripts/node/validate/defaults-override.txtar @@ -108,7 +108,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index cd0e2f7fa1..b9f456c488 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -91,7 +91,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 07ed2c398a..9457ae718c 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -91,7 +91,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 3bb1179218..9a77ab1eac 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -91,7 +91,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar index 5c9d676572..d3e56f97fb 100644 --- a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -76,7 +76,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index e210c89382..af8fe17b87 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -81,7 +81,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index a11fd5f892..c020664740 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -88,7 +88,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index 071da2d268..ac8489f324 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -70,7 +70,7 @@ LeaseDuration = '10s' LeaseRefreshInterval = '1s' [TelemetryIngress] -UniConn = true +UniConn = false Logging = false BufferSize = 100 MaxBatchSize = 50 From 882cdce6811a952a38c61c3fb88349990d635d59 Mon Sep 17 00:00:00 2001 From: Dimitris Grigoriou Date: Thu, 12 Sep 2024 17:37:18 +0300 Subject: [PATCH 340/432] Remove PriceMin check from attempt builder (#14370) * Remove PriceMin check from attempt builder * Remove TipCapMin * Update changeset --- .changeset/warm-experts-promise.md | 5 +++++ core/chains/evm/txmgr/attempts.go | 19 ++++--------------- core/chains/evm/txmgr/attempts_test.go | 3 --- core/chains/evm/txmgr/broadcaster_test.go | 22 ++++------------------ 4 files changed, 13 insertions(+), 36 deletions(-) create mode 100644 .changeset/warm-experts-promise.md diff --git a/.changeset/warm-experts-promise.md b/.changeset/warm-experts-promise.md new file mode 100644 index 0000000000..4ee25d4b61 --- /dev/null +++ b/.changeset/warm-experts-promise.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Remove PriceMin and TipCapMin check from attempt builder #internal diff --git a/core/chains/evm/txmgr/attempts.go b/core/chains/evm/txmgr/attempts.go index c284ee77bd..2fc444071e 100644 --- a/core/chains/evm/txmgr/attempts.go +++ b/core/chains/evm/txmgr/attempts.go @@ -34,8 +34,6 @@ type evmTxAttemptBuilder struct { type evmTxAttemptBuilderFeeConfig interface { EIP1559DynamicFees() bool - TipCapMin() *assets.Wei - PriceMin() *assets.Wei PriceMaxKey(common.Address) *assets.Wei LimitDefault() uint64 } @@ -172,7 +170,7 @@ func (c *evmTxAttemptBuilder) NewEmptyTxAttempt(ctx context.Context, nonce evmty } func (c *evmTxAttemptBuilder) newDynamicFeeAttempt(ctx context.Context, etx Tx, fee gas.DynamicFee, gasLimit uint64) (attempt TxAttempt, err error) { - if err = validateDynamicFeeGas(c.feeConfig, c.feeConfig.TipCapMin(), fee, etx); err != nil { + if err = validateDynamicFeeGas(c.feeConfig, fee, etx); err != nil { return attempt, pkgerrors.Wrap(err, "error validating gas") } @@ -208,7 +206,7 @@ type keySpecificEstimator interface { // validateDynamicFeeGas is a sanity check - we have other checks elsewhere, but this // makes sure we _never_ create an invalid attempt -func validateDynamicFeeGas(kse keySpecificEstimator, tipCapMinimum *assets.Wei, fee gas.DynamicFee, etx Tx) error { +func validateDynamicFeeGas(kse keySpecificEstimator, fee gas.DynamicFee, etx Tx) error { gasTipCap, gasFeeCap := fee.TipCap, fee.FeeCap if gasTipCap == nil { @@ -235,11 +233,6 @@ func validateDynamicFeeGas(kse keySpecificEstimator, tipCapMinimum *assets.Wei, if gasFeeCap.Cmp(max) > 0 { return pkgerrors.Errorf("cannot create tx attempt: specified gas fee cap of %s would exceed max configured gas price of %s for key %s", gasFeeCap.String(), max.String(), etx.FromAddress.String()) } - // Tip must be above minimum - minTip := tipCapMinimum - if gasTipCap.Cmp(minTip) < 0 { - return pkgerrors.Errorf("cannot create tx attempt: specified gas tip cap of %s is below min configured gas tip of %s for key %s", gasTipCap.String(), minTip.String(), etx.FromAddress.String()) - } return nil } @@ -257,7 +250,7 @@ func newDynamicFeeTransaction(nonce uint64, to common.Address, value *big.Int, g } func (c *evmTxAttemptBuilder) newLegacyAttempt(ctx context.Context, etx Tx, gasPrice *assets.Wei, gasLimit uint64) (attempt TxAttempt, err error) { - if err = validateLegacyGas(c.feeConfig, c.feeConfig.PriceMin(), gasPrice, etx); err != nil { + if err = validateLegacyGas(c.feeConfig, gasPrice, etx); err != nil { return attempt, pkgerrors.Wrap(err, "error validating gas") } @@ -290,7 +283,7 @@ func (c *evmTxAttemptBuilder) newLegacyAttempt(ctx context.Context, etx Tx, gasP // validateLegacyGas is a sanity check - we have other checks elsewhere, but this // makes sure we _never_ create an invalid attempt -func validateLegacyGas(kse keySpecificEstimator, minGasPriceWei, gasPrice *assets.Wei, etx Tx) error { +func validateLegacyGas(kse keySpecificEstimator, gasPrice *assets.Wei, etx Tx) error { if gasPrice == nil { panic("gas price missing") } @@ -298,10 +291,6 @@ func validateLegacyGas(kse keySpecificEstimator, minGasPriceWei, gasPrice *asset if gasPrice.Cmp(max) > 0 { return pkgerrors.Errorf("cannot create tx attempt: specified gas price of %s would exceed max configured gas price of %s for key %s", gasPrice.String(), max.String(), etx.FromAddress.String()) } - min := minGasPriceWei - if gasPrice.Cmp(min) < 0 { - return pkgerrors.Errorf("cannot create tx attempt: specified gas price of %s is below min configured gas price of %s for key %s", gasPrice.String(), min.String(), etx.FromAddress.String()) - } return nil } diff --git a/core/chains/evm/txmgr/attempts_test.go b/core/chains/evm/txmgr/attempts_test.go index 5c43368fcc..df88835384 100644 --- a/core/chains/evm/txmgr/attempts_test.go +++ b/core/chains/evm/txmgr/attempts_test.go @@ -171,9 +171,6 @@ func TestTxm_NewDynamicFeeTx(t *testing.T) { {"ignores global min gas price", assets.GWei(5), assets.GWei(5), func(c *toml.EVMConfig) { c.GasEstimator.PriceMin = assets.GWei(6) }, ""}, - {"tip cap below min allowed", assets.GWei(5), assets.GWei(5), func(c *toml.EVMConfig) { - c.GasEstimator.TipCapMin = assets.GWei(6) - }, "specified gas tip cap of 5 gwei is below min configured gas tip of 6 gwei"}, } for _, tt := range cases { diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 10e9002eab..439076cfa8 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -1620,31 +1620,17 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { // configured for the transaction pool. // This is a configuration error by the node operator, since it means they set the base gas level too low. underpricedError := "transaction underpriced" - localNextNonce := getLocalNextNonce(t, nonceTracker, fromAddress) mustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, testutils.FixtureChainID) - // Check gas tip cap verification - evmcfg2 := evmtest.NewChainScopedConfig(t, configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.EIP1559DynamicFees = ptr(true) - c.EVM[0].GasEstimator.TipCapDefault = assets.NewWeiI(0) - })) - ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(localNextNonce, nil).Once() - eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg2, &testCheckerFactory{}, false, nonceTracker) - - retryable, err := eb2.ProcessUnstartedTxs(ctx, fromAddress) - require.Error(t, err) - require.Contains(t, err.Error(), "specified gas tip cap of 0 is below min configured gas tip of 1 wei for key") - assert.True(t, retryable) - gasTipCapDefault := assets.NewWeiI(42) - evmcfg2 = evmtest.NewChainScopedConfig(t, configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + evmcfg2 := evmtest.NewChainScopedConfig(t, configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].GasEstimator.EIP1559DynamicFees = ptr(true) c.EVM[0].GasEstimator.TipCapDefault = gasTipCapDefault })) - localNextNonce = getLocalNextNonce(t, nonceTracker, fromAddress) + localNextNonce := getLocalNextNonce(t, nonceTracker, fromAddress) ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(localNextNonce, nil).Once() - eb2 = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg2, &testCheckerFactory{}, false, nonceTracker) + eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg2, &testCheckerFactory{}, false, nonceTracker) // Second was underpriced but above minimum ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { @@ -1659,7 +1645,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { return tx.Nonce() == localNextNonce && tx.GasTipCap().Cmp(big.NewInt(0).Add(gasTipCapDefault.ToInt(), big.NewInt(0).Mul(evmcfg2.EVM().GasEstimator().BumpMin().ToInt(), big.NewInt(2)))) == 0 }), fromAddress).Return(commonclient.Successful, nil).Once() - retryable, err = eb2.ProcessUnstartedTxs(ctx, fromAddress) + retryable, err := eb2.ProcessUnstartedTxs(ctx, fromAddress) require.NoError(t, err) assert.False(t, retryable) From 814538b321fed7558206946fe0f32a690df70ffd Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs <5300706+iljapavlovs@users.noreply.github.com> Date: Thu, 12 Sep 2024 18:37:46 +0300 Subject: [PATCH 341/432] DEVSVCS-134: adding readme on how to run VRF CTF tests (#14409) * DEVSVCS-134: adding readme on how to run VRF CTF tests * DEVSVCS-134: minor updates --- integration-tests/docs/VRF.md | 65 +++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 integration-tests/docs/VRF.md diff --git a/integration-tests/docs/VRF.md b/integration-tests/docs/VRF.md new file mode 100644 index 0000000000..0e74d66da9 --- /dev/null +++ b/integration-tests/docs/VRF.md @@ -0,0 +1,65 @@ +# How To Run VRF Tests +* All test configs should be placed in the [integration-tests/testconfig](integration-tests/testconfig) folder +* All test configs for running tests in live testnets should be under [integration-tests/testconfig/vrfv2plus/overrides](integration-tests/testconfig/vrfv2plus/overrides) folder + + +## Functional Tests +### In CI - using On Demand Workflows +```bash +gh workflow run "on-demand-vrfv2plus-smoke-tests.yml" \ +--ref develop \ +-f=test_secrets_override_key= \ +-f test_config_override_path= \ +-f test_suite="Selected Tests" \ # Optional, Options - "All Tests", "Selected Tests". Default is "All Tests". If "Selected Tests" is selected, then `test_list_regex` should be provided +-f test_list_regex="" \ # Optional, default is "TestVRFv2Plus$/(Link_Billing|Native_Billing|Direct_Funding)|TestVRFV2PlusWithBHS" which are P0 tests +-f chainlink_version="<>" # Optional, default is image created from develop branch. Not needed if you run tests against existing environment +-f notify_user_id_on_failure= # Optional, default is empty. If provided, will notify the user on slack if the tests fail +``` + +#### Examples: +Run P0 tests against existing environment (Staging) on Arbitrum Sepolia +```bash +gh workflow run "on-demand-vrfv2plus-smoke-tests.yml" \ +--ref develop \ +-f=test_secrets_override_key= \ +-f test_config_override_path=integration-tests/testconfig/vrfv2plus/overrides/staging/arbitrum_sepolia_staging_test_config.toml \ +-f test_suite="Selected Tests" +``` + +Run all tests deploying all contracts, CL nodes with `2.15.0` version on Base Sepolia +```bash +gh workflow run "on-demand-vrfv2plus-smoke-tests.yml" \ +--ref develop \ +-f=test_secrets_override_key= \ +-f test_config_override_path=integration-tests/testconfig/vrfv2plus/overrides/new_env/base_sepolia_new_env_test_config.toml \ +-f test_suite="All Tests" \ +-f chainlink_version="2.15.0" +``` + +### Locally +```bash +cd integration-tests +TEST_LOG_LEVEL=debug \ +BASE64_CONFIG_OVERRIDE=$(cat | base64) \ +go test -v -timeout 15m -run "" ./smoke +``` + +## Performance Tests +```bash +gh workflow run "on-demand-vrfv2plus-performance-test.yml" \ +--ref develop \ +-f=test_secrets_override_key= \ +-f test_config_override_path= \ +-f performanceTestType=“Smoke” # Options - "Smoke", "Soak", "Stress", "Load". +-f test_list_regex="" # Optional, default is "TestVRFV2PlusPerformance" +``` + +#### Examples: +Run SOAK tests against existing environment (Staging) on Base Sepolia +```bash +gh workflow run "on-demand-vrfv2plus-performance-test.yml" \ +--ref develop \ +-f=test_secrets_override_key= \ +-f test_config_override_path=integration-tests/testconfig/vrfv2plus/overrides/staging/base_sepolia_staging_test_config.toml \ +-f performanceTestType=“Soak” +``` From 2a667241a68a0671c4edb39b835c023db50ba49f Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs <5300706+iljapavlovs@users.noreply.github.com> Date: Fri, 13 Sep 2024 17:27:06 +0300 Subject: [PATCH 342/432] DEVSVCS-134: minor updates to README and testconfig (#14419) --- integration-tests/docs/VRF.md | 4 ++-- .../new_env/arbitrum_sepolia_new_env_test_config.toml | 3 +++ .../overrides/new_env/avalanche_fuji_new_env_test_config.toml | 3 +++ .../overrides/new_env/bsc_testnet_new_env_test_config.toml | 3 +++ .../overrides/new_env/polygon_amoy_new_env_test_config.toml | 3 +++ .../vrfv2/overrides/new_env/sepolia_new_env_test_config.toml | 3 +++ .../new_env/arbitrum_sepolia_new_env_test_config.toml | 3 +++ .../overrides/new_env/avalanche_fuji_new_env_test_config.toml | 3 +++ .../overrides/new_env/base_sepolia_new_env_test_config.toml | 3 +++ .../overrides/new_env/bsc_testnet_new_env_test_config.toml | 3 +++ .../overrides/new_env/nexon_dev_new_env_test_config.toml | 3 +++ .../overrides/new_env/nexon_qa_new_env_test_config.toml | 3 +++ .../overrides/new_env/nexon_stage_new_env_test_config.toml | 3 +++ .../overrides/new_env/nexon_test_new_env_test_config.toml | 3 +++ .../new_env/optimism_sepolia_new_env_test_config.toml | 3 +++ .../overrides/new_env/polygon_amoy_new_env_test_config.toml | 3 +++ .../overrides/new_env/sepolia_new_env_test_config.toml | 3 +++ 17 files changed, 50 insertions(+), 2 deletions(-) diff --git a/integration-tests/docs/VRF.md b/integration-tests/docs/VRF.md index 0e74d66da9..745bec0586 100644 --- a/integration-tests/docs/VRF.md +++ b/integration-tests/docs/VRF.md @@ -1,6 +1,6 @@ # How To Run VRF Tests -* All test configs should be placed in the [integration-tests/testconfig](integration-tests/testconfig) folder -* All test configs for running tests in live testnets should be under [integration-tests/testconfig/vrfv2plus/overrides](integration-tests/testconfig/vrfv2plus/overrides) folder +* All test configs should be placed in the [integration-tests/testconfig](../testconfig) folder +* All test configs for running tests in live testnets should be under [integration-tests/testconfig/vrfv2plus/overrides](../testconfig/vrfv2plus/overrides) folder ## Functional Tests diff --git a/integration-tests/testconfig/vrfv2/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml b/integration-tests/testconfig/vrfv2/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml index e383bf27da..9181c0f51f 100644 --- a/integration-tests/testconfig/vrfv2/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["ARBITRUM_SEPOLIA"] [ARBITRUM_SEPOLIA.VRFv2.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2/overrides/new_env/avalanche_fuji_new_env_test_config.toml b/integration-tests/testconfig/vrfv2/overrides/new_env/avalanche_fuji_new_env_test_config.toml index 7eb2215284..cfeaa5a797 100644 --- a/integration-tests/testconfig/vrfv2/overrides/new_env/avalanche_fuji_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2/overrides/new_env/avalanche_fuji_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["AVALANCHE_FUJI"] [AVALANCHE_FUJI.VRFv2.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2/overrides/new_env/bsc_testnet_new_env_test_config.toml b/integration-tests/testconfig/vrfv2/overrides/new_env/bsc_testnet_new_env_test_config.toml index 9652e94626..ec938767ec 100644 --- a/integration-tests/testconfig/vrfv2/overrides/new_env/bsc_testnet_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2/overrides/new_env/bsc_testnet_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["BSC_TESTNET"] [BSC_TESTNET.VRFv2.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2/overrides/new_env/polygon_amoy_new_env_test_config.toml b/integration-tests/testconfig/vrfv2/overrides/new_env/polygon_amoy_new_env_test_config.toml index 39d4ba849e..6331647a88 100644 --- a/integration-tests/testconfig/vrfv2/overrides/new_env/polygon_amoy_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2/overrides/new_env/polygon_amoy_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["POLYGON_AMOY"] [POLYGON_AMOY.VRFv2.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2/overrides/new_env/sepolia_new_env_test_config.toml b/integration-tests/testconfig/vrfv2/overrides/new_env/sepolia_new_env_test_config.toml index 914dc26627..591f07e662 100644 --- a/integration-tests/testconfig/vrfv2/overrides/new_env/sepolia_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2/overrides/new_env/sepolia_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["SEPOLIA"] [SEPOLIA.VRFv2.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2plus/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml index 8f111a3ae0..271ef037bd 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/arbitrum_sepolia_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["ARBITRUM_SEPOLIA"] [ARBITRUM_SEPOLIA.VRFv2Plus.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2plus/overrides/new_env/avalanche_fuji_new_env_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/avalanche_fuji_new_env_test_config.toml index 8c7203ce7b..273d796ba6 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/new_env/avalanche_fuji_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/avalanche_fuji_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["AVALANCHE_FUJI"] [AVALANCHE_FUJI.VRFv2Plus.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2plus/overrides/new_env/base_sepolia_new_env_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/base_sepolia_new_env_test_config.toml index 9cbf7e58b9..f93c75cc38 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/new_env/base_sepolia_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/base_sepolia_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["BASE_SEPOLIA"] [BASE_SEPOLIA.VRFv2Plus.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2plus/overrides/new_env/bsc_testnet_new_env_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/bsc_testnet_new_env_test_config.toml index c3c07966fa..16cc9a6e53 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/new_env/bsc_testnet_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/bsc_testnet_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["BSC_TESTNET"] [BSC_TESTNET.VRFv2Plus.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_dev_new_env_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_dev_new_env_test_config.toml index 5791b70660..5d7b774108 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_dev_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_dev_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["NEXON_DEV"] [NEXON_DEV.VRFv2Plus.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_qa_new_env_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_qa_new_env_test_config.toml index fb16e8d0c4..0f761128af 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_qa_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_qa_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["NEXON_QA"] [NEXON_QA.VRFv2Plus.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_stage_new_env_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_stage_new_env_test_config.toml index 9802b4de24..5dcd771e9d 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_stage_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_stage_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["NEXON_STAGE"] [NEXON_STAGE.VRFv2Plus.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_test_new_env_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_test_new_env_test_config.toml index ccaa4f332a..d1263df34d 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_test_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/nexon_test_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["NEXON_TEST"] [NEXON_TEST.VRFv2Plus.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2plus/overrides/new_env/optimism_sepolia_new_env_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/optimism_sepolia_new_env_test_config.toml index 1850365599..8fd5b76379 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/new_env/optimism_sepolia_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/optimism_sepolia_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["OPTIMISM_SEPOLIA"] [OPTIMISM_SEPOLIA.VRFv2Plus.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2plus/overrides/new_env/polygon_amoy_new_env_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/polygon_amoy_new_env_test_config.toml index b5423bf6f7..10abe34bb5 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/new_env/polygon_amoy_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/polygon_amoy_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["POLYGON_AMOY"] [POLYGON_AMOY.VRFv2Plus.General] use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2plus/overrides/new_env/sepolia_new_env_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/sepolia_new_env_test_config.toml index 3be47f7d07..7df808c505 100644 --- a/integration-tests/testconfig/vrfv2plus/overrides/new_env/sepolia_new_env_test_config.toml +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/sepolia_new_env_test_config.toml @@ -3,3 +3,6 @@ selected_networks = ["SEPOLIA"] [SEPOLIA.VRFv2Plus.General] use_existing_env = false + +[Logging] +test_log_collect = true From 5ec7cbbd3e62f0327cee8f504709a5c0563abe09 Mon Sep 17 00:00:00 2001 From: Connor Stein Date: Fri, 13 Sep 2024 11:54:44 -0400 Subject: [PATCH 343/432] AddChain inbound CCIP integration test (#14377) * Port * Use mcms lib * Proposal signing working * Almost working. Just need ramps to make timelock owner first * Accept ownership proposal working * Fee quoter accept ownership * Fix existing tests * Enable to new chain traffic working * Mod tidy * Fix build * lint * More lint * Use Address() for MCM/Timelock * Rename * Self review cleanup * Clean up job management and bootstrap handling * Comments --- .../deployment/ccip/add_chain.go | 170 +++++++++++++++ .../deployment/ccip/add_chain_test.go | 157 +++++++++++++ integration-tests/deployment/ccip/add_lane.go | 32 +-- .../deployment/ccip/add_lane_test.go | 56 +++++ .../deployment/ccip/changeset/1_cap_reg.go | 4 +- .../ccip/changeset/2_initial_deploy.go | 10 +- .../ccip/changeset/2_initial_deploy_test.go | 109 ++------- integration-tests/deployment/ccip/deploy.go | 152 +++++++++---- .../deployment/ccip/deploy_home_chain.go | 206 ++++++++++-------- .../deployment/ccip/deploy_test.go | 1 + integration-tests/deployment/ccip/jobs.go | 88 +++----- integration-tests/deployment/ccip/propose.go | 186 +++++++++++++--- integration-tests/deployment/ccip/state.go | 58 +++-- .../deployment/ccip/test_helpers.go | 131 ++++++++++- integration-tests/deployment/changeset.go | 20 +- integration-tests/deployment/environment.go | 106 +++++++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- 18 files changed, 1093 insertions(+), 399 deletions(-) create mode 100644 integration-tests/deployment/ccip/add_chain.go create mode 100644 integration-tests/deployment/ccip/add_chain_test.go diff --git a/integration-tests/deployment/ccip/add_chain.go b/integration-tests/deployment/ccip/add_chain.go new file mode 100644 index 0000000000..bc997f0dc5 --- /dev/null +++ b/integration-tests/deployment/ccip/add_chain.go @@ -0,0 +1,170 @@ +package ccipdeployment + +import ( + "math/big" + + "github.com/smartcontractkit/ccip-owner-contracts/tools/proposal/mcms" + "github.com/smartcontractkit/ccip-owner-contracts/tools/proposal/timelock" + chainsel "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink-ccip/chainconfig" + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" +) + +// NewChainInboundProposal generates a proposal +// to connect the new chain to the existing chains. +func NewChainInboundProposal( + e deployment.Environment, + state CCIPOnChainState, + homeChainSel uint64, + newChainSel uint64, + sources []uint64, +) (*timelock.MCMSWithTimelockProposal, error) { + // Generate proposal which enables new destination (from test router) on all source chains. + var batches []timelock.BatchChainOperation + metaDataPerChain := make(map[mcms.ChainIdentifier]timelock.MCMSWithTimelockChainMetadata) + for _, source := range sources { + chain, _ := chainsel.ChainBySelector(source) + enableOnRampDest, err := state.Chains[source].OnRamp.ApplyDestChainConfigUpdates(SimTransactOpts(), []onramp.OnRampDestChainConfigArgs{ + { + DestChainSelector: newChainSel, + Router: state.Chains[source].TestRouter.Address(), + }, + }) + if err != nil { + return nil, err + } + enableFeeQuoterDest, err := state.Chains[source].FeeQuoter.ApplyDestChainConfigUpdates( + SimTransactOpts(), + []fee_quoter.FeeQuoterDestChainConfigArgs{ + { + DestChainSelector: newChainSel, + DestChainConfig: defaultFeeQuoterDestChainConfig(), + }, + }) + if err != nil { + return nil, err + } + initialPrices, err := state.Chains[source].FeeQuoter.UpdatePrices( + SimTransactOpts(), + fee_quoter.InternalPriceUpdates{ + TokenPriceUpdates: []fee_quoter.InternalTokenPriceUpdate{}, + GasPriceUpdates: []fee_quoter.InternalGasPriceUpdate{ + { + DestChainSelector: newChainSel, + // TODO: parameterize + UsdPerUnitGas: big.NewInt(2e12), + }, + }}) + if err != nil { + return nil, err + } + batches = append(batches, timelock.BatchChainOperation{ + ChainIdentifier: mcms.ChainIdentifier(chain.Selector), + Batch: []mcms.Operation{ + { + // Enable the source in on ramp + To: state.Chains[source].OnRamp.Address(), + Data: enableOnRampDest.Data(), + Value: big.NewInt(0), + }, + { + // Set initial dest prices to unblock testing. + To: state.Chains[source].FeeQuoter.Address(), + Data: initialPrices.Data(), + Value: big.NewInt(0), + }, + { + To: state.Chains[source].FeeQuoter.Address(), + Data: enableFeeQuoterDest.Data(), + Value: big.NewInt(0), + }, + }, + }) + metaDataPerChain[mcms.ChainIdentifier(chain.Selector)] = timelock.MCMSWithTimelockChainMetadata{ + ChainMetadata: mcms.ChainMetadata{ + NonceOffset: 0, + MCMAddress: state.Chains[source].Mcm.Address(), + }, + TimelockAddress: state.Chains[source].Timelock.Address(), + } + } + + // Home chain new don. + // - Add new DONs for destination to home chain + nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) + if err != nil { + return nil, err + } + encodedExtraChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ + GasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(1000), + DAGasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(0), + OptimisticConfirmations: 1, + }) + if err != nil { + return nil, err + } + chainConfig := SetupConfigInfo(newChainSel, nodes.NonBootstraps().PeerIDs(), + nodes.DefaultF(), encodedExtraChainConfig) + addChain, err := state.Chains[homeChainSel].CCIPConfig.ApplyChainConfigUpdates(SimTransactOpts(), nil, []ccip_config.CCIPConfigTypesChainConfigInfo{ + chainConfig, + }) + if err != nil { + return nil, err + } + + newDONArgs, err := BuildAddDONArgs(e.Logger, state.Chains[newChainSel].OffRamp, e.Chains[newChainSel], nodes.NonBootstraps()) + if err != nil { + return nil, err + } + addDON, err := state.Chains[homeChainSel].CapabilityRegistry.AddDON(SimTransactOpts(), + nodes.NonBootstraps().PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: CCIPCapabilityID, + Config: newDONArgs, + }, + }, false, false, nodes.NonBootstraps().DefaultF()) + if err != nil { + return nil, err + } + homeChain, _ := chainsel.ChainBySelector(homeChainSel) + metaDataPerChain[mcms.ChainIdentifier(homeChain.Selector)] = timelock.MCMSWithTimelockChainMetadata{ + ChainMetadata: mcms.ChainMetadata{ + NonceOffset: 0, + MCMAddress: state.Chains[homeChainSel].Mcm.Address(), + }, + TimelockAddress: state.Chains[homeChainSel].Timelock.Address(), + } + batches = append(batches, timelock.BatchChainOperation{ + ChainIdentifier: mcms.ChainIdentifier(homeChain.Selector), + Batch: []mcms.Operation{ + { + // Add the chain first, don needs it to be there. + To: state.Chains[homeChainSel].CCIPConfig.Address(), + Data: addChain.Data(), + Value: big.NewInt(0), + }, + { + To: state.Chains[homeChainSel].CapabilityRegistry.Address(), + Data: addDON.Data(), + Value: big.NewInt(0), + }, + }, + }) + return timelock.NewMCMSWithTimelockProposal( + "1", + 2004259681, // TODO: should be parameterized and based on current block timestamp. + []mcms.Signature{}, + false, + metaDataPerChain, + "blah", // TODO + batches, + timelock.Schedule, + "0s", // TODO: Should be parameterized. + ) +} diff --git a/integration-tests/deployment/ccip/add_chain_test.go b/integration-tests/deployment/ccip/add_chain_test.go new file mode 100644 index 0000000000..a484bda0f2 --- /dev/null +++ b/integration-tests/deployment/ccip/add_chain_test.go @@ -0,0 +1,157 @@ +package ccipdeployment + +import ( + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestAddChainInbound(t *testing.T) { + // 4 chains where the 4th is added after initial deployment. + e := NewEnvironmentWithCRAndJobs(t, logger.TestLogger(t), 4) + require.Equal(t, len(e.Nodes), 5) + state, err := LoadOnchainState(e.Env, e.Ab) + require.NoError(t, err) + // Take first non-home chain as the new chain. + newChain := e.Env.AllChainSelectorsExcluding([]uint64{e.HomeChainSel})[0] + // We deploy to the rest. + initialDeploy := e.Env.AllChainSelectorsExcluding([]uint64{newChain}) + + ab, err := DeployCCIPContracts(e.Env, DeployCCIPContractConfig{ + HomeChainSel: e.HomeChainSel, + ChainsToDeploy: initialDeploy, + CCIPOnChainState: state, + }) + require.NoError(t, err) + require.NoError(t, e.Ab.Merge(ab)) + state, err = LoadOnchainState(e.Env, e.Ab) + require.NoError(t, err) + + // Connect all the existing lanes. + for _, source := range initialDeploy { + for _, dest := range initialDeploy { + if source != dest { + require.NoError(t, AddLane(e.Env, state, source, dest)) + } + } + } + + // Deploy contracts to new chain + newAddresses, err := DeployChainContracts(e.Env, e.Env.Chains[newChain], deployment.NewMemoryAddressBook()) + require.NoError(t, err) + require.NoError(t, e.Ab.Merge(newAddresses)) + state, err = LoadOnchainState(e.Env, e.Ab) + require.NoError(t, err) + + // Transfer onramp/fq ownership to timelock. + // Enable the new dest on the test router. + for _, source := range initialDeploy { + tx, err := state.Chains[source].OnRamp.TransferOwnership(e.Env.Chains[source].DeployerKey, state.Chains[source].Timelock.Address()) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(e.Env.Chains[source], tx, err) + require.NoError(t, err) + tx, err = state.Chains[source].FeeQuoter.TransferOwnership(e.Env.Chains[source].DeployerKey, state.Chains[source].Timelock.Address()) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(e.Env.Chains[source], tx, err) + require.NoError(t, err) + tx, err = state.Chains[source].TestRouter.ApplyRampUpdates(e.Env.Chains[source].DeployerKey, []router.RouterOnRamp{ + { + DestChainSelector: newChain, + OnRamp: state.Chains[source].OnRamp.Address(), + }, + }, nil, nil) + _, err = deployment.ConfirmIfNoError(e.Env.Chains[source], tx, err) + require.NoError(t, err) + } + // Transfer CR contract ownership + tx, err := state.Chains[e.HomeChainSel].CapabilityRegistry.TransferOwnership(e.Env.Chains[e.HomeChainSel].DeployerKey, state.Chains[e.HomeChainSel].Timelock.Address()) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(e.Env.Chains[e.HomeChainSel], tx, err) + require.NoError(t, err) + tx, err = state.Chains[e.HomeChainSel].CCIPConfig.TransferOwnership(e.Env.Chains[e.HomeChainSel].DeployerKey, state.Chains[e.HomeChainSel].Timelock.Address()) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(e.Env.Chains[e.HomeChainSel], tx, err) + require.NoError(t, err) + + acceptOwnershipProposal, err := GenerateAcceptOwnershipProposal(state, e.HomeChainSel, initialDeploy) + require.NoError(t, err) + acceptOwnershipExec := SignProposal(t, e.Env, acceptOwnershipProposal) + // Apply the accept ownership proposal to all the chains. + for _, sel := range initialDeploy { + ExecuteProposal(t, e.Env, acceptOwnershipExec, state, sel) + } + for _, chain := range initialDeploy { + owner, err2 := state.Chains[chain].OnRamp.Owner(nil) + require.NoError(t, err2) + require.Equal(t, state.Chains[chain].Timelock.Address(), owner) + } + cfgOwner, err := state.Chains[e.HomeChainSel].CCIPConfig.Owner(nil) + require.NoError(t, err) + crOwner, err := state.Chains[e.HomeChainSel].CapabilityRegistry.Owner(nil) + require.NoError(t, err) + require.Equal(t, state.Chains[e.HomeChainSel].Timelock.Address(), cfgOwner) + require.Equal(t, state.Chains[e.HomeChainSel].Timelock.Address(), crOwner) + + // Generate and sign inbound proposal to new 4th chain. + chainInboundProposal, err := NewChainInboundProposal(e.Env, state, e.HomeChainSel, newChain, initialDeploy) + require.NoError(t, err) + chainInboundExec := SignProposal(t, e.Env, chainInboundProposal) + for _, sel := range initialDeploy { + ExecuteProposal(t, e.Env, chainInboundExec, state, sel) + } + + // Now configure the new chain using deployer key (not transferred to timelock yet). + var offRampEnables []offramp.OffRampSourceChainConfigArgs + for _, source := range initialDeploy { + offRampEnables = append(offRampEnables, offramp.OffRampSourceChainConfigArgs{ + Router: state.Chains[newChain].Router.Address(), + SourceChainSelector: source, + IsEnabled: true, + OnRamp: common.LeftPadBytes(state.Chains[source].OnRamp.Address().Bytes(), 32), + }) + } + tx, err = state.Chains[newChain].OffRamp.ApplySourceChainConfigUpdates(e.Env.Chains[newChain].DeployerKey, offRampEnables) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(e.Env.Chains[newChain], tx, err) + require.NoError(t, err) + // Set the OCR3 config on new 4th chain to enable the plugin. + latestDON, err := LatestCCIPDON(state.Chains[e.HomeChainSel].CapabilityRegistry) + require.NoError(t, err) + ocrConfigs, err := BuildSetOCR3ConfigArgs(latestDON.Id, state.Chains[e.HomeChainSel].CCIPConfig) + require.NoError(t, err) + tx, err = state.Chains[newChain].OffRamp.SetOCR3Configs(e.Env.Chains[newChain].DeployerKey, ocrConfigs) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(e.Env.Chains[newChain], tx, err) + require.NoError(t, err) + + // Assert the inbound lanes to the new chain are wired correctly. + state, err = LoadOnchainState(e.Env, e.Ab) + require.NoError(t, err) + for _, chain := range initialDeploy { + cfg, err2 := state.Chains[chain].OnRamp.GetDestChainConfig(nil, newChain) + require.NoError(t, err2) + assert.Equal(t, cfg.Router, state.Chains[chain].TestRouter.Address()) + fqCfg, err2 := state.Chains[chain].FeeQuoter.GetDestChainConfig(nil, newChain) + require.NoError(t, err2) + assert.True(t, fqCfg.IsEnabled) + s, err2 := state.Chains[newChain].OffRamp.GetSourceChainConfig(nil, chain) + require.NoError(t, err2) + assert.Equal(t, common.LeftPadBytes(state.Chains[chain].OnRamp.Address().Bytes(), 32), s.OnRamp) + } + // Ensure job related logs are up to date. + time.Sleep(30 * time.Second) + require.NoError(t, ReplayAllLogs(e.Nodes, e.Env.Chains)) + + // TODO: Send via all inbound lanes and use parallel helper + // Now that the proposal has been executed we expect to be able to send traffic to this new 4th chain. + seqNr := SendRequest(t, e.Env, state, initialDeploy[0], newChain, true) + ConfirmExecution(t, e.Env.Chains[initialDeploy[0]], e.Env.Chains[newChain], state.Chains[newChain].OffRamp, seqNr) +} diff --git a/integration-tests/deployment/ccip/add_lane.go b/integration-tests/deployment/ccip/add_lane.go index 7ea757f03a..0e7c01405b 100644 --- a/integration-tests/deployment/ccip/add_lane.go +++ b/integration-tests/deployment/ccip/add_lane.go @@ -7,8 +7,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink/integration-tests/deployment" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" ) @@ -18,13 +19,13 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) tx, err := state.Chains[from].Router.ApplyRampUpdates(e.Chains[from].DeployerKey, []router.RouterOnRamp{ { DestChainSelector: to, - OnRamp: state.Chains[from].EvmOnRampV160.Address(), + OnRamp: state.Chains[from].OnRamp.Address(), }, }, []router.RouterOffRamp{}, []router.RouterOffRamp{}) if _, err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { return err } - tx, err = state.Chains[from].EvmOnRampV160.ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, + tx, err = state.Chains[from].OnRamp.ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, []onramp.OnRampDestChainConfigArgs{ { DestChainSelector: to, @@ -35,7 +36,7 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) return err } - _, err = state.Chains[from].PriceRegistry.UpdatePrices( + _, err = state.Chains[from].FeeQuoter.UpdatePrices( e.Chains[from].DeployerKey, fee_quoter.InternalPriceUpdates{ TokenPriceUpdates: []fee_quoter.InternalTokenPriceUpdate{ { @@ -57,25 +58,25 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) return err } - // Enable dest in price registry - tx, err = state.Chains[from].PriceRegistry.ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, + // Enable dest in fee quoter + tx, err = state.Chains[from].FeeQuoter.ApplyDestChainConfigUpdates(e.Chains[from].DeployerKey, []fee_quoter.FeeQuoterDestChainConfigArgs{ { DestChainSelector: to, - DestChainConfig: defaultPriceRegistryDestChainConfig(), + DestChainConfig: defaultFeeQuoterDestChainConfig(), }, }) if _, err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { return err } - tx, err = state.Chains[to].EvmOffRampV160.ApplySourceChainConfigUpdates(e.Chains[to].DeployerKey, + tx, err = state.Chains[to].OffRamp.ApplySourceChainConfigUpdates(e.Chains[to].DeployerKey, []offramp.OffRampSourceChainConfigArgs{ { Router: state.Chains[to].Router.Address(), SourceChainSelector: from, IsEnabled: true, - OnRamp: common.LeftPadBytes(state.Chains[from].EvmOnRampV160.Address().Bytes(), 32), + OnRamp: common.LeftPadBytes(state.Chains[from].OnRamp.Address().Bytes(), 32), }, }) if _, err := deployment.ConfirmIfNoError(e.Chains[to], tx, err); err != nil { @@ -84,14 +85,14 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) tx, err = state.Chains[to].Router.ApplyRampUpdates(e.Chains[to].DeployerKey, []router.RouterOnRamp{}, []router.RouterOffRamp{}, []router.RouterOffRamp{ { SourceChainSelector: from, - OffRamp: state.Chains[to].EvmOffRampV160.Address(), + OffRamp: state.Chains[to].OffRamp.Address(), }, }) _, err = deployment.ConfirmIfNoError(e.Chains[to], tx, err) return err } -func defaultPriceRegistryDestChainConfig() fee_quoter.FeeQuoterDestChainConfig { +func defaultFeeQuoterDestChainConfig() fee_quoter.FeeQuoterDestChainConfig { // https://github.com/smartcontractkit/ccip/blob/c4856b64bd766f1ddbaf5d13b42d3c4b12efde3a/contracts/src/v0.8/ccip/libraries/Internal.sol#L337-L337 /* ```Solidity @@ -112,9 +113,10 @@ func defaultPriceRegistryDestChainConfig() fee_quoter.FeeQuoterDestChainConfig { DestGasPerDataAvailabilityByte: 100, DestDataAvailabilityMultiplierBps: 1, DefaultTokenDestGasOverhead: 125_000, - DefaultTxGasLimit: 200_000, - GasMultiplierWeiPerEth: 1, - NetworkFeeUSDCents: 1, - ChainFamilySelector: [4]byte(evmFamilySelector), + //DefaultTokenDestBytesOverhead: 32, + DefaultTxGasLimit: 200_000, + GasMultiplierWeiPerEth: 1, + NetworkFeeUSDCents: 1, + ChainFamilySelector: [4]byte(evmFamilySelector), } } diff --git a/integration-tests/deployment/ccip/add_lane_test.go b/integration-tests/deployment/ccip/add_lane_test.go index 567f5ca685..77b82348e4 100644 --- a/integration-tests/deployment/ccip/add_lane_test.go +++ b/integration-tests/deployment/ccip/add_lane_test.go @@ -1 +1,57 @@ package ccipdeployment + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +// TestAddLane covers the workflow of adding a lane +// between existing supported chains in CCIP. +func TestAddLane(t *testing.T) { + // TODO: The offchain code doesn't yet support partial lane + // enablement, need to address then re-enable this test. + t.Skip() + e := NewEnvironmentWithCRAndJobs(t, logger.TestLogger(t), 3) + // Here we have CR + nodes set up, but no CCIP contracts deployed. + state, err := LoadOnchainState(e.Env, e.Ab) + require.NoError(t, err) + // Set up CCIP contracts and a DON per chain. + ab, err := DeployCCIPContracts(e.Env, DeployCCIPContractConfig{ + HomeChainSel: e.HomeChainSel, + CCIPOnChainState: state, + }) + require.NoError(t, err) + require.NoError(t, e.Ab.Merge(ab)) + + // We expect no lanes available on any chain. + state, err = LoadOnchainState(e.Env, e.Ab) + require.NoError(t, err) + for _, chain := range state.Chains { + offRamps, err := chain.Router.GetOffRamps(nil) + require.NoError(t, err) + require.Len(t, offRamps, 0) + } + + // Add one lane and send traffic. + from, to := e.Env.AllChainSelectors()[0], e.Env.AllChainSelectors()[1] + require.NoError(t, AddLane(e.Env, state, from, to)) + + for sel, chain := range state.Chains { + offRamps, err := chain.Router.GetOffRamps(nil) + require.NoError(t, err) + if sel == to { + require.Len(t, offRamps, 1) + } else { + require.Len(t, offRamps, 0) + } + } + seqNum := SendRequest(t, e.Env, state, from, to, false) + require.Equal(t, uint64(1), seqNum) + ConfirmExecution(t, e.Env.Chains[from], e.Env.Chains[to], state.Chains[to].OffRamp, seqNum) + + // TODO: Add a second lane, then disable the first and + // ensure we can send on the second but not the first. +} diff --git a/integration-tests/deployment/ccip/changeset/1_cap_reg.go b/integration-tests/deployment/ccip/changeset/1_cap_reg.go index 1929aede02..5863491623 100644 --- a/integration-tests/deployment/ccip/changeset/1_cap_reg.go +++ b/integration-tests/deployment/ccip/changeset/1_cap_reg.go @@ -1,6 +1,8 @@ package changeset import ( + "github.com/smartcontractkit/ccip-owner-contracts/tools/proposal/timelock" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" ) @@ -14,7 +16,7 @@ func Apply0001(env deployment.Environment, homeChainSel uint64) (deployment.Chan return deployment.ChangesetOutput{}, err } return deployment.ChangesetOutput{ - Proposals: []deployment.Proposal{}, + Proposals: []timelock.MCMSWithTimelockProposal{}, AddressBook: ab, JobSpecs: nil, }, nil diff --git a/integration-tests/deployment/ccip/changeset/2_initial_deploy.go b/integration-tests/deployment/ccip/changeset/2_initial_deploy.go index b20ffb2d4a..93c408bf45 100644 --- a/integration-tests/deployment/ccip/changeset/2_initial_deploy.go +++ b/integration-tests/deployment/ccip/changeset/2_initial_deploy.go @@ -1,6 +1,8 @@ package changeset import ( + "github.com/smartcontractkit/ccip-owner-contracts/tools/proposal/timelock" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" @@ -14,18 +16,14 @@ func Apply0002(env deployment.Environment, c ccipdeployment.DeployCCIPContractCo ab, err := ccipdeployment.DeployCCIPContracts(env, c) if err != nil { env.Logger.Errorw("Failed to deploy CCIP contracts", "err", err, "addresses", ab) - return deployment.ChangesetOutput{}, err + return deployment.ChangesetOutput{}, deployment.MaybeDataErr(err) } js, err := ccipdeployment.NewCCIPJobSpecs(env.NodeIDs, env.Offchain) if err != nil { return deployment.ChangesetOutput{}, err } - proposal, err := ccipdeployment.GenerateAcceptOwnershipProposal(env, env.AllChainSelectors(), ab) - if err != nil { - return deployment.ChangesetOutput{}, err - } return deployment.ChangesetOutput{ - Proposals: []deployment.Proposal{proposal}, + Proposals: []timelock.MCMSWithTimelockProposal{}, AddressBook: ab, // Mapping of which nodes get which jobs. JobSpecs: js, diff --git a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go index 8098ebaef2..fa0fbb9141 100644 --- a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go +++ b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go @@ -8,27 +8,22 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/integration-tests/deployment" "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - - ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" - "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func Test0002_InitialDeploy(t *testing.T) { lggr := logger.TestLogger(t) ctx := ccipdeployment.Context(t) - tenv := ccipdeployment.NewDeployedTestEnvironment(t, lggr) + tenv := ccipdeployment.NewEnvironmentWithCR(t, lggr, 3) e := tenv.Env nodes := tenv.Nodes chains := e.Chains @@ -38,7 +33,8 @@ func Test0002_InitialDeploy(t *testing.T) { // Apply migration output, err := Apply0002(tenv.Env, ccipdeployment.DeployCCIPContractConfig{ - HomeChainSel: tenv.HomeChainSel, + HomeChainSel: tenv.HomeChainSel, + ChainsToDeploy: tenv.Env.AllChainSelectors(), // Capreg/config already exist. CCIPOnChainState: state, }) @@ -48,7 +44,7 @@ func Test0002_InitialDeploy(t *testing.T) { require.NoError(t, err) // Ensure capreg logs are up to date. - require.NoError(t, ReplayAllLogs(nodes, chains)) + require.NoError(t, ccipdeployment.ReplayAllLogs(nodes, chains)) // Apply the jobs. for nodeID, jobs := range output.JobSpecs { @@ -67,9 +63,8 @@ func Test0002_InitialDeploy(t *testing.T) { time.Sleep(30 * time.Second) // Ensure job related logs are up to date. - require.NoError(t, ReplayAllLogs(nodes, chains)) + require.NoError(t, ccipdeployment.ReplayAllLogs(nodes, chains)) - // Send a request from every router // Add all lanes for source := range e.Chains { for dest := range e.Chains { @@ -80,47 +75,19 @@ func Test0002_InitialDeploy(t *testing.T) { } // Send a message from each chain to every other chain. - for src, srcChain := range e.Chains { + expectedSeqNum := make(map[uint64]uint64) + for src := range e.Chains { for dest := range e.Chains { if src == dest { continue } - msg := router.ClientEVM2AnyMessage{ - Receiver: common.LeftPadBytes(state.Chains[dest].Receiver.Address().Bytes(), 32), - Data: []byte("hello"), - TokenAmounts: nil, // TODO: no tokens for now - FeeToken: state.Chains[src].Weth9.Address(), - ExtraArgs: nil, // TODO: no extra args for now, falls back to default - } - fee, err := state.Chains[src].Router.GetFee( - &bind.CallOpts{Context: context.Background()}, dest, msg) - require.NoError(t, err, deployment.MaybeDataErr(err)) - tx, err := state.Chains[src].Weth9.Deposit(&bind.TransactOpts{ - From: e.Chains[src].DeployerKey.From, - Signer: e.Chains[src].DeployerKey.Signer, - Value: fee, - }) - require.NoError(t, err) - _, err = srcChain.Confirm(tx) - require.NoError(t, err) - - // TODO: should be able to avoid this by using native? - tx, err = state.Chains[src].Weth9.Approve(e.Chains[src].DeployerKey, - state.Chains[src].Router.Address(), fee) - require.NoError(t, err) - _, err = srcChain.Confirm(tx) - require.NoError(t, err) - - t.Logf("Sending CCIP request from chain selector %d to chain selector %d", - src, dest) - tx, err = state.Chains[src].Router.CcipSend(e.Chains[src].DeployerKey, dest, msg) - require.NoError(t, err) - _, err = srcChain.Confirm(tx) - require.NoError(t, err) + seqNum := ccipdeployment.SendRequest(t, e, state, src, dest, false) + expectedSeqNum[dest] = seqNum } } // Wait for all commit reports to land. + cStart := time.Now() var wg sync.WaitGroup for src, srcChain := range e.Chains { for dest, dstChain := range e.Chains { @@ -132,11 +99,13 @@ func Test0002_InitialDeploy(t *testing.T) { wg.Add(1) go func(src, dest uint64) { defer wg.Done() - waitForCommitWithInterval(t, srcChain, dstChain, state.Chains[dest].EvmOffRampV160, ccipocr3.SeqNumRange{1, 1}) + waitForCommitWithInterval(t, srcChain, dstChain, state.Chains[dest].OffRamp, + ccipocr3.SeqNumRange{ccipocr3.SeqNum(expectedSeqNum[dest]), ccipocr3.SeqNum(expectedSeqNum[dest])}) }(src, dest) } } wg.Wait() + cEnd := time.Now() // Wait for all exec reports to land for src, srcChain := range e.Chains { @@ -149,26 +118,19 @@ func Test0002_InitialDeploy(t *testing.T) { wg.Add(1) go func(src, dest deployment.Chain) { defer wg.Done() - waitForExecWithSeqNr(t, src, dest, state.Chains[dest.Selector].EvmOffRampV160, 1) + ccipdeployment.ConfirmExecution(t, + src, dest, state.Chains[dest.Selector].OffRamp, + expectedSeqNum[dest.Selector]) }(srcChain, dstChain) } } wg.Wait() - + eEnd := time.Now() + t.Log("Commit time:", cEnd.Sub(cStart)) + t.Log("Exec time:", eEnd.Sub(cEnd)) // TODO: Apply the proposal. } -func ReplayAllLogs(nodes map[string]memory.Node, chains map[uint64]deployment.Chain) error { - for _, node := range nodes { - for sel := range chains { - if err := node.ReplayLogs(map[uint64]uint64{sel: 1}); err != nil { - return err - } - } - } - return nil -} - func waitForCommitWithInterval( t *testing.T, src deployment.Chain, @@ -211,34 +173,3 @@ func waitForCommitWithInterval( } } } - -func waitForExecWithSeqNr(t *testing.T, - source, dest deployment.Chain, - offramp *offramp.OffRamp, - expectedSeqNr uint64) { - tick := time.NewTicker(5 * time.Second) - defer tick.Stop() - for range tick.C { - // TODO: Clean this up - source.Client.(*backends.SimulatedBackend).Commit() - dest.Client.(*backends.SimulatedBackend).Commit() - scc, err := offramp.GetSourceChainConfig(nil, source.Selector) - require.NoError(t, err) - t.Logf("Waiting for ExecutionStateChanged on chain %d from chain %d with expected sequence number %d, current onchain minSeqNr: %d", - dest.Selector, source.Selector, expectedSeqNr, scc.MinSeqNr) - iter, err := offramp.FilterExecutionStateChanged(nil, - []uint64{source.Selector}, []uint64{expectedSeqNr}, nil) - require.NoError(t, err) - var count int - for iter.Next() { - if iter.Event.SequenceNumber == expectedSeqNr && iter.Event.SourceChainSelector == source.Selector { - count++ - } - } - if count == 1 { - t.Logf("Received ExecutionStateChanged on chain %d from chain %d with expected sequence number %d", - dest.Selector, source.Selector, expectedSeqNr) - return - } - } -} diff --git a/integration-tests/deployment/ccip/deploy.go b/integration-tests/deployment/ccip/deploy.go index eb2ddae293..72ab5d7d6e 100644 --- a/integration-tests/deployment/ccip/deploy.go +++ b/integration-tests/deployment/ccip/deploy.go @@ -1,20 +1,24 @@ package ccipdeployment import ( + "crypto/ecdsa" "fmt" "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" - owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" + "github.com/ethereum/go-ethereum/crypto" + "github.com/smartcontractkit/ccip-owner-contracts/tools/configwrappers" + owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/tools/gethwrappers" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/integration-tests/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" @@ -36,16 +40,28 @@ var ( Router deployment.ContractType = "Router" TokenAdminRegistry deployment.ContractType = "TokenAdminRegistry" NonceManager deployment.ContractType = "NonceManager" - PriceRegistry deployment.ContractType = "PriceRegistry" + FeeQuoter deployment.ContractType = "FeeQuoter" ManyChainMultisig deployment.ContractType = "ManyChainMultiSig" CCIPConfig deployment.ContractType = "CCIPConfig" RBACTimelock deployment.ContractType = "RBACTimelock" OnRamp deployment.ContractType = "OnRamp" OffRamp deployment.ContractType = "OffRamp" - CCIPReceiver deployment.ContractType = "CCIPReceiver" CapabilitiesRegistry deployment.ContractType = "CapabilitiesRegistry" + // Note test router maps to a regular router contract. + TestRouter deployment.ContractType = "TestRouter" + CCIPReceiver deployment.ContractType = "CCIPReceiver" + + TestXXXMCMSSigner *ecdsa.PrivateKey ) +func init() { + key, err := crypto.GenerateKey() + if err != nil { + panic(err) + } + TestXXXMCMSSigner = key +} + type Contracts interface { *capabilities_registry.CapabilitiesRegistry | *rmn_proxy_contract.RMNProxyContract | @@ -101,7 +117,8 @@ func deployContract[C Contracts]( } type DeployCCIPContractConfig struct { - HomeChainSel uint64 + HomeChainSel uint64 + ChainsToDeploy []uint64 // Existing contracts which we want to skip deployment // Leave empty if we want to deploy everything // TODO: Add skips to deploy function. @@ -128,17 +145,23 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( e.Logger.Errorw("Failed to get hashed capability id", "err", err) return ab, err } + if cr != CCIPCapabilityID { + return ab, fmt.Errorf("Capability registry does not support CCIP %s %s", hexutil.Encode(cr[:]), hexutil.Encode(CCIPCapabilityID[:])) + } // Signal to CR that our nodes support CCIP capability. if err := AddNodes( c.Chains[c.HomeChainSel].CapabilityRegistry, e.Chains[c.HomeChainSel], - nodes.PeerIDs(c.HomeChainSel), // Doesn't actually matter which sel here - [][32]byte{cr}, + nodes.NonBootstraps().PeerIDs(), ); err != nil { return ab, err } - for _, chain := range e.Chains { + for _, chainSel := range c.ChainsToDeploy { + chain, ok := e.Chains[chainSel] + if !ok { + return ab, fmt.Errorf("Chain %d not found", chainSel) + } ab, err = DeployChainContracts(e, chain, ab) if err != nil { return ab, err @@ -153,47 +176,28 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( e.Logger.Errorw("Failed to load chain state", "err", err) return ab, err } - // Enable ramps on price registry/nonce manager - tx, err := chainState.PriceRegistry.ApplyAuthorizedCallerUpdates(chain.DeployerKey, fee_quoter.AuthorizedCallersAuthorizedCallerArgs{ - // TODO: We enable the deployer initially to set prices - AddedCallers: []common.Address{chainState.EvmOffRampV160.Address(), chain.DeployerKey.From}, - }) - if _, err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { - e.Logger.Errorw("Failed to confirm price registry authorized caller update", "err", err) - return ab, err - } - - tx, err = chainState.NonceManager.ApplyAuthorizedCallerUpdates(chain.DeployerKey, nonce_manager.AuthorizedCallersAuthorizedCallerArgs{ - AddedCallers: []common.Address{chainState.EvmOffRampV160.Address(), chainState.EvmOnRampV160.Address()}, - }) - if _, err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { - e.Logger.Errorw("Failed to update nonce manager with ramps", "err", err) - return ab, err - } + // TODO: Do we want to extract this? // Add chain config for each chain. - _, err = AddChainConfig(e.Logger, + _, err = AddChainConfig( + e.Logger, e.Chains[c.HomeChainSel], c.Chains[c.HomeChainSel].CCIPConfig, chain.Selector, - nodes.PeerIDs(chain.Selector), - uint8(len(nodes)/3)) + nodes.NonBootstraps().PeerIDs()) if err != nil { return ab, err } - // For each chain, we create a DON on the home chain. - if err := AddDON(e.Logger, - cr, + // For each chain, we create a DON on the home chain (2 OCR instances) + if err := AddDON( + e.Logger, c.Chains[c.HomeChainSel].CapabilityRegistry, c.Chains[c.HomeChainSel].CCIPConfig, - chainState.EvmOffRampV160, + chainState.OffRamp, chain, e.Chains[c.HomeChainSel], - uint8(len(nodes)/3), - nodes.BootstrapPeerIDs(chain.Selector)[0], - nodes.PeerIDs(chain.Selector), - nodes, + nodes.NonBootstraps(), ); err != nil { e.Logger.Errorw("Failed to add DON", "err", err) return ab, err @@ -203,7 +207,11 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( return ab, nil } -func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab deployment.AddressBook) (deployment.AddressBook, error) { +func DeployChainContracts( + e deployment.Environment, + chain deployment.Chain, + ab deployment.AddressBook, +) (deployment.AddressBook, error) { ccipReceiver, err := deployContract(e.Logger, chain, ab, func(chain deployment.Chain) ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver] { receiverAddr, tx, receiver, err2 := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver( @@ -253,16 +261,37 @@ func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab d e.Logger.Errorw("Failed to deploy mcm", "err", err) return ab, err } - // TODO: Address soon + // TODO: Parameterize this. e.Logger.Infow("deployed mcm", "addr", mcm.Address) + publicKey := TestXXXMCMSSigner.Public().(*ecdsa.PublicKey) + // Convert the public key to an Ethereum address + address := crypto.PubkeyToAddress(*publicKey) + c, err := configwrappers.NewConfig(1, []common.Address{address}, []configwrappers.Config{}) + if err != nil { + e.Logger.Errorw("Failed to create config", "err", err) + return ab, err + } + groupQuorums, groupParents, signerAddresses, signerGroups := c.ExtractSetConfigInputs() + mcmsTx, err := mcm.Contract.SetConfig(chain.DeployerKey, + signerAddresses, + signerGroups, // Signer 1 is int group 0 (root group) with quorum 1. + groupQuorums, + groupParents, + false, + ) + if _, err := deployment.ConfirmIfNoError(chain, mcmsTx, err); err != nil { + e.Logger.Errorw("Failed to confirm mcm config", "err", err) + return ab, err + } - _, err = deployContract(e.Logger, chain, ab, + timelock, err := deployContract(e.Logger, chain, ab, func(chain deployment.Chain) ContractDeploy[*owner_helpers.RBACTimelock] { timelock, tx, cc, err2 := owner_helpers.DeployRBACTimelock( chain.DeployerKey, chain.Client, big.NewInt(0), // minDelay mcm.Address, + // TODO: Actual MCM groups need to be parameterized. []common.Address{mcm.Address}, // proposers []common.Address{chain.DeployerKey.From}, //executors []common.Address{mcm.Address}, // cancellers @@ -295,6 +324,8 @@ func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab d } e.Logger.Infow("deployed rmnProxy", "addr", rmnProxy.Address) + // TODO: Need general configuration for using pre-existing weth9 + // link tokens. weth9, err := deployContract(e.Logger, chain, ab, func(chain deployment.Chain) ContractDeploy[*weth9.WETH9] { weth9Addr, tx, weth9c, err2 := weth9.DeployWETH9( @@ -347,6 +378,24 @@ func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab d } e.Logger.Infow("deployed router", "addr", routerContract) + testRouterContract, err := deployContract(e.Logger, chain, ab, + func(chain deployment.Chain) ContractDeploy[*router.Router] { + routerAddr, tx, routerC, err2 := router.DeployRouter( + chain.DeployerKey, + chain.Client, + weth9.Address, + rmnProxy.Address, + ) + return ContractDeploy[*router.Router]{ + routerAddr, routerC, tx, deployment.NewTypeAndVersion(TestRouter, deployment.Version1_2_0), err2, + } + }) + if err != nil { + e.Logger.Errorw("Failed to deploy test router", "err", err) + return ab, err + } + e.Logger.Infow("deployed test router", "addr", testRouterContract.Address) + tokenAdminRegistry, err := deployContract(e.Logger, chain, ab, func(chain deployment.Chain) ContractDeploy[*token_admin_registry.TokenAdminRegistry] { tokenAdminRegistryAddr, tx, tokenAdminRegistry, err2 := token_admin_registry.DeployTokenAdminRegistry( @@ -388,7 +437,7 @@ func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab d LinkToken: linkToken.Address, StalenessThreshold: uint32(24 * 60 * 60), }, - []common.Address{}, // ramps added after + []common.Address{timelock.Address}, // timelock should be able to update, ramps added after []common.Address{weth9.Address, linkToken.Address}, // fee tokens []fee_quoter.FeeQuoterTokenPriceFeedUpdate{}, []fee_quoter.FeeQuoterTokenTransferFeeConfigArgs{}, // TODO: tokens @@ -405,11 +454,11 @@ func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab d []fee_quoter.FeeQuoterDestChainConfigArgs{}, ) return ContractDeploy[*fee_quoter.FeeQuoter]{ - prAddr, pr, tx, deployment.NewTypeAndVersion(PriceRegistry, deployment.Version1_6_0_dev), err2, + prAddr, pr, tx, deployment.NewTypeAndVersion(FeeQuoter, deployment.Version1_6_0_dev), err2, } }) if err != nil { - e.Logger.Errorw("Failed to deploy price registry", "err", err) + e.Logger.Errorw("Failed to deploy fee quoter", "err", err) return ab, err } @@ -468,5 +517,24 @@ func DeployChainContracts(e deployment.Environment, chain deployment.Chain, ab d return ab, err } e.Logger.Infow("deployed offramp", "addr", offRamp) + + // Basic wiring is always needed. + tx, err := feeQuoter.Contract.ApplyAuthorizedCallerUpdates(chain.DeployerKey, fee_quoter.AuthorizedCallersAuthorizedCallerArgs{ + // TODO: We enable the deployer initially to set prices + // Should be removed after. + AddedCallers: []common.Address{offRamp.Contract.Address(), chain.DeployerKey.From}, + }) + if _, err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { + e.Logger.Errorw("Failed to confirm fee quoter authorized caller update", "err", err) + return ab, err + } + + tx, err = nonceManager.Contract.ApplyAuthorizedCallerUpdates(chain.DeployerKey, nonce_manager.AuthorizedCallersAuthorizedCallerArgs{ + AddedCallers: []common.Address{offRamp.Contract.Address(), onRamp.Contract.Address()}, + }) + if _, err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { + e.Logger.Errorw("Failed to update nonce manager with ramps", "err", err) + return ab, err + } return ab, nil } diff --git a/integration-tests/deployment/ccip/deploy_home_chain.go b/integration-tests/deployment/ccip/deploy_home_chain.go index 1fe6bd5d56..ec078e4a9d 100644 --- a/integration-tests/deployment/ccip/deploy_home_chain.go +++ b/integration-tests/deployment/ccip/deploy_home_chain.go @@ -4,7 +4,7 @@ import ( "bytes" "context" "errors" - "sort" + "fmt" "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -17,9 +17,9 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" - "github.com/smartcontractkit/chainlink/integration-tests/deployment" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ocr3_config_encoder" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" @@ -52,6 +52,18 @@ const ( MaxDurationShouldTransmitAcceptedReport = 10 * time.Second ) +var ( + CCIPCapabilityID = utils.Keccak256Fixed(MustABIEncode(`[{"type": "string"}, {"type": "string"}]`, CapabilityLabelledName, CapabilityVersion)) +) + +func MustABIEncode(abiString string, args ...interface{}) []byte { + encoded, err := utils.ABIEncode(abiString, args...) + if err != nil { + panic(err) + } + return encoded +} + func DeployCapReg(lggr logger.Logger, chains map[uint64]deployment.Chain, chainSel uint64) (deployment.AddressBook, common.Address, error) { ab := deployment.NewMemoryAddressBook() chain := chains[chainSel] @@ -69,6 +81,7 @@ func DeployCapReg(lggr logger.Logger, chains map[uint64]deployment.Chain, chainS lggr.Errorw("Failed to deploy capreg", "err", err) return ab, common.Address{}, err } + lggr.Infow("deployed capreg", "addr", capReg.Address) ccipConfig, err := deployContract( lggr, chain, ab, @@ -115,27 +128,18 @@ func DeployCapReg(lggr logger.Logger, chains map[uint64]deployment.Chain, chainS return ab, capReg.Address, nil } -func sortP2PIDS(p2pIDs [][32]byte) { - sort.Slice(p2pIDs, func(i, j int) bool { - return bytes.Compare(p2pIDs[i][:], p2pIDs[j][:]) < 0 - }) -} - func AddNodes( capReg *capabilities_registry.CapabilitiesRegistry, chain deployment.Chain, p2pIDs [][32]byte, - capabilityIDs [][32]byte, ) error { - // Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail - sortP2PIDS(p2pIDs) var nodeParams []capabilities_registry.CapabilitiesRegistryNodeParams for _, p2pID := range p2pIDs { nodeParam := capabilities_registry.CapabilitiesRegistryNodeParams{ NodeOperatorId: NodeOperatorID, Signer: p2pID, // Not used in tests P2pId: p2pID, - HashedCapabilityIds: capabilityIDs, + HashedCapabilityIds: [][32]byte{CCIPCapabilityID}, } nodeParams = append(nodeParams, nodeParam) } @@ -164,10 +168,7 @@ func AddChainConfig( ccipConfig *ccip_config.CCIPConfig, chainSelector uint64, p2pIDs [][32]byte, - f uint8, ) (ccip_config.CCIPConfigTypesChainConfigInfo, error) { - // Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail - sortP2PIDS(p2pIDs) // First Add ChainConfig that includes all p2pIDs as readers encodedExtraChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ GasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(1000), @@ -177,11 +178,10 @@ func AddChainConfig( if err != nil { return ccip_config.CCIPConfigTypesChainConfigInfo{}, err } - chainConfig := SetupConfigInfo(chainSelector, p2pIDs, f, encodedExtraChainConfig) - inputConfig := []ccip_config.CCIPConfigTypesChainConfigInfo{ + chainConfig := SetupConfigInfo(chainSelector, p2pIDs, uint8(len(p2pIDs)/3), encodedExtraChainConfig) + tx, err := ccipConfig.ApplyChainConfigUpdates(h.DeployerKey, nil, []ccip_config.CCIPConfigTypesChainConfigInfo{ chainConfig, - } - tx, err := ccipConfig.ApplyChainConfigUpdates(h.DeployerKey, nil, inputConfig) + }) if _, err := deployment.ConfirmIfNoError(h, tx, err); err != nil { return ccip_config.CCIPConfigTypesChainConfigInfo{}, err } @@ -189,20 +189,13 @@ func AddChainConfig( return chainConfig, nil } -func AddDON( +func BuildAddDONArgs( lggr logger.Logger, - ccipCapabilityID [32]byte, - capReg *capabilities_registry.CapabilitiesRegistry, - ccipConfig *ccip_config.CCIPConfig, offRamp *offramp.OffRamp, dest deployment.Chain, - home deployment.Chain, - f uint8, - bootstrapP2PID [32]byte, - p2pIDs [][32]byte, - nodes []deployment.Node, -) error { - sortP2PIDS(p2pIDs) + nodes deployment.Nodes, +) ([]byte, error) { + p2pIDs := nodes.PeerIDs() // Get OCR3 Config from helper var schedule []int var oracles []confighelper2.OracleIdentityExtra @@ -221,7 +214,7 @@ func AddDON( tabi, err := ocr3_config_encoder.IOCR3ConfigEncoderMetaData.GetAbi() if err != nil { - return err + return nil, err } // Add DON on capability registry contract @@ -246,7 +239,7 @@ func AddDON( }) } if err2 != nil { - return err2 + return nil, err2 } signers, transmitters, configF, _, offchainConfigVersion, offchainConfig, err2 := ocr3confighelper.ContractSetConfigArgsForTests( DeltaProgress, @@ -264,11 +257,11 @@ func AddDON( MaxDurationObservation, MaxDurationShouldAcceptAttestedReport, MaxDurationShouldTransmitAcceptedReport, - int(f), + int(nodes.DefaultF()), []byte{}, // empty OnChainConfig ) if err2 != nil { - return err2 + return nil, err2 } signersBytes := make([][]byte, len(signers)) @@ -280,7 +273,7 @@ func AddDON( for i, transmitter := range transmitters { parsed, err2 := common.ParseHexOrString(string(transmitter)) if err2 != nil { - return err2 + return nil, err2 } transmittersBytes[i] = parsed } @@ -298,77 +291,100 @@ func AddDON( }) } + // TODO: Can just use utils.ABIEncode directly here. encodedCall, err := tabi.Pack("exposeOCR3Config", ocr3Configs) if err != nil { - return err + return nil, err } // Trim first four bytes to remove function selector. encodedConfigs := encodedCall[4:] + return encodedConfigs, nil +} - tx, err := capReg.AddDON(home.DeployerKey, p2pIDs, []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ - { - CapabilityId: ccipCapabilityID, - Config: encodedConfigs, - }, - }, false, false, f) - if _, err := deployment.ConfirmIfNoError(home, tx, err); err != nil { - return err - } - - latestBlock, err := home.Client.HeaderByNumber(context.Background(), nil) +func LatestCCIPDON(registry *capabilities_registry.CapabilitiesRegistry) (*capabilities_registry.CapabilitiesRegistryDONInfo, error) { + dons, err := registry.GetDONs(nil) if err != nil { - return err + return nil, err } - endBlock := latestBlock.Number.Uint64() - iter, err := capReg.FilterConfigSet(&bind.FilterOpts{ - Start: endBlock - 1, - End: &endBlock, - }, []uint32{}) - if err != nil { - return err - } - var donID uint32 - for iter.Next() { - donID = iter.Event.DonId - break - } - if donID == 0 { - return errors.New("failed to get donID") - } - - var signerAddresses []common.Address - for _, oracle := range oracles { - signerAddresses = append(signerAddresses, common.BytesToAddress(oracle.OnchainPublicKey)) - } - - var transmitterAddresses []common.Address - for _, oracle := range oracles { - transmitterAddresses = append(transmitterAddresses, common.HexToAddress(string(oracle.TransmitAccount))) + var ccipDON capabilities_registry.CapabilitiesRegistryDONInfo + for _, don := range dons { + if len(don.CapabilityConfigurations) == 1 && + don.CapabilityConfigurations[0].CapabilityId == CCIPCapabilityID && + don.Id > ccipDON.Id { + ccipDON = don + } } + return &ccipDON, nil +} - // get the config digest from the ccip config contract and set config on the offramp. +func BuildSetOCR3ConfigArgs( + donID uint32, + ccipConfig *ccip_config.CCIPConfig, +) ([]offramp.MultiOCR3BaseOCRConfigArgs, error) { var offrampOCR3Configs []offramp.MultiOCR3BaseOCRConfigArgs for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { ocrConfig, err2 := ccipConfig.GetOCRConfig(&bind.CallOpts{ Context: context.Background(), }, donID, uint8(pluginType)) if err2 != nil { - return err2 + return nil, err2 } if len(ocrConfig) != 1 { - return errors.New("expected exactly one OCR3 config") + return nil, errors.New("expected exactly one OCR3 config") + } + var signerAddresses []common.Address + for _, signer := range ocrConfig[0].Config.Signers { + signerAddresses = append(signerAddresses, common.BytesToAddress(signer)) + } + + var transmitterAddresses []common.Address + for _, transmitter := range ocrConfig[0].Config.Transmitters { + transmitterAddresses = append(transmitterAddresses, common.BytesToAddress(transmitter)) } offrampOCR3Configs = append(offrampOCR3Configs, offramp.MultiOCR3BaseOCRConfigArgs{ ConfigDigest: ocrConfig[0].ConfigDigest, OcrPluginType: uint8(pluginType), - F: f, + F: ocrConfig[0].Config.F, IsSignatureVerificationEnabled: pluginType == cctypes.PluginTypeCCIPCommit, Signers: signerAddresses, Transmitters: transmitterAddresses, }) } + return offrampOCR3Configs, nil +} + +func AddDON( + lggr logger.Logger, + capReg *capabilities_registry.CapabilitiesRegistry, + ccipConfig *ccip_config.CCIPConfig, + offRamp *offramp.OffRamp, + dest deployment.Chain, + home deployment.Chain, + nodes deployment.Nodes, +) error { + encodedConfigs, err := BuildAddDONArgs(lggr, offRamp, dest, nodes) + if err != nil { + return err + } + tx, err := capReg.AddDON(home.DeployerKey, nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: CCIPCapabilityID, + Config: encodedConfigs, + }, + }, false, false, nodes.DefaultF()) + if _, err := deployment.ConfirmIfNoError(home, tx, err); err != nil { + return err + } + don, err := LatestCCIPDON(capReg) + if err != nil { + return err + } + offrampOCR3Configs, err := BuildSetOCR3ConfigArgs(don.Id, ccipConfig) + if err != nil { + return err + } tx, err = offRamp.SetOCR3Configs(dest.DeployerKey, offrampOCR3Configs) if _, err := deployment.ConfirmIfNoError(dest, tx, err); err != nil { @@ -376,25 +392,37 @@ func AddDON( } for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { - _, err = offRamp.LatestConfigDetails(&bind.CallOpts{ + ocrConfig, err := offRamp.LatestConfigDetails(&bind.CallOpts{ Context: context.Background(), }, uint8(pluginType)) if err != nil { - //return err - return deployment.MaybeDataErr(err) + return err } // TODO: assertions to be done as part of full state // resprentation validation CCIP-3047 - //require.Equalf(t, offrampOCR3Configs[pluginType].ConfigDigest, ocrConfig.ConfigInfo.ConfigDigest, "%s OCR3 config digest mismatch", pluginType.String()) - //require.Equalf(t, offrampOCR3Configs[pluginType].F, ocrConfig.ConfigInfo.F, "%s OCR3 config F mismatch", pluginType.String()) - //require.Equalf(t, offrampOCR3Configs[pluginType].IsSignatureVerificationEnabled, ocrConfig.ConfigInfo.IsSignatureVerificationEnabled, "%s OCR3 config signature verification mismatch", pluginType.String()) - //if pluginType == cctypes.PluginTypeCCIPCommit { - // // only commit will set signers, exec doesn't need them. - // require.Equalf(t, offrampOCR3Configs[pluginType].Signers, ocrConfig.Signers, "%s OCR3 config signers mismatch", pluginType.String()) - //} - //require.Equalf(t, offrampOCR3Configs[pluginType].TransmittersByEVMChainID, ocrConfig.TransmittersByEVMChainID, "%s OCR3 config transmitters mismatch", pluginType.String()) + if offrampOCR3Configs[pluginType].ConfigDigest != ocrConfig.ConfigInfo.ConfigDigest { + return fmt.Errorf("%s OCR3 config digest mismatch", pluginType.String()) + } + if offrampOCR3Configs[pluginType].F != ocrConfig.ConfigInfo.F { + return fmt.Errorf("%s OCR3 config F mismatch", pluginType.String()) + } + if offrampOCR3Configs[pluginType].IsSignatureVerificationEnabled != ocrConfig.ConfigInfo.IsSignatureVerificationEnabled { + return fmt.Errorf("%s OCR3 config signature verification mismatch", pluginType.String()) + } + if pluginType == cctypes.PluginTypeCCIPCommit { + // only commit will set signers, exec doesn't need them. + for i, signer := range offrampOCR3Configs[pluginType].Signers { + if !bytes.Equal(signer.Bytes(), ocrConfig.Signers[i].Bytes()) { + return fmt.Errorf("%s OCR3 config signer mismatch", pluginType.String()) + } + } + } + for i, transmitter := range offrampOCR3Configs[pluginType].Transmitters { + if !bytes.Equal(transmitter.Bytes(), ocrConfig.Transmitters[i].Bytes()) { + return fmt.Errorf("%s OCR3 config transmitter mismatch", pluginType.String()) + } + } } - lggr.Infof("set ocr3 config on the offramp, signers: %+v, transmitters: %+v", signerAddresses, transmitterAddresses) return nil } diff --git a/integration-tests/deployment/ccip/deploy_test.go b/integration-tests/deployment/ccip/deploy_test.go index 7bc56f82f7..e2963b84a3 100644 --- a/integration-tests/deployment/ccip/deploy_test.go +++ b/integration-tests/deployment/ccip/deploy_test.go @@ -28,6 +28,7 @@ func TestDeployCCIPContracts(t *testing.T) { require.NoError(t, err) ab, err := DeployCCIPContracts(e, DeployCCIPContractConfig{ HomeChainSel: homeChain, + ChainsToDeploy: e.AllChainSelectors(), CCIPOnChainState: s, }) require.NoError(t, err) diff --git a/integration-tests/deployment/ccip/jobs.go b/integration-tests/deployment/ccip/jobs.go index c46ab7270f..49fb1e9542 100644 --- a/integration-tests/deployment/ccip/jobs.go +++ b/integration-tests/deployment/ccip/jobs.go @@ -1,11 +1,7 @@ package ccipdeployment import ( - "context" - "fmt" - "github.com/smartcontractkit/chainlink/integration-tests/deployment" - nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) @@ -13,67 +9,49 @@ import ( // In our case, the only address needed is the cap registry which is actually an env var. // and will pre-exist for our deployment. So the job specs only depend on the environment operators. func NewCCIPJobSpecs(nodeIds []string, oc deployment.OffchainClient) (map[string][]string, error) { + nodes, err := deployment.NodeInfo(nodeIds, oc) + if err != nil { + return nil, err + } // Generate a set of brand new job specs for CCIP for a specific environment // (including NOPs) and new addresses. // We want to assign one CCIP capability job to each node. And node with // an addr we'll list as bootstrapper. // Find the bootstrap nodes - bootstrapMp := make(map[string]struct{}) - for _, node := range nodeIds { - // TODO: Filter should accept multiple nodes - nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ - NodeIds: []string{node}, - }}) - if err != nil { - return nil, err - } - for _, chainConfig := range nodeChainConfigs.ChainConfigs { - if chainConfig.Ocr2Config.IsBootstrap { - bootstrapMp[fmt.Sprintf("%s@%s", - // p2p_12D3... -> 12D3... - chainConfig.Ocr2Config.P2PKeyBundle.PeerId[4:], chainConfig.Ocr2Config.Multiaddr)] = struct{}{} - } - } - } - var bootstraps []string - for b := range bootstrapMp { - bootstraps = append(bootstraps, b) - } - nodesToJobSpecs := make(map[string][]string) - for _, node := range nodeIds { - // TODO: Filter should accept multiple. - nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ - NodeIds: []string{node}, - }}) - if err != nil { - return nil, err - } - // only set P2PV2Bootstrappers in the job spec if the node is a plugin node. - var p2pV2Bootstrappers []string - for _, chainConfig := range nodeChainConfigs.ChainConfigs { - if !chainConfig.Ocr2Config.IsBootstrap { - p2pV2Bootstrappers = bootstraps - break - } + nodesToJobSpecs := make(map[string][]string) + for _, node := range nodes { + var spec string + var err error + if !node.IsBootstrap { + spec, err = validate.NewCCIPSpecToml(validate.SpecArgs{ + P2PV2Bootstrappers: nodes.BootstrapLocators(), + CapabilityVersion: CapabilityVersion, + CapabilityLabelledName: CapabilityLabelledName, + OCRKeyBundleIDs: map[string]string{ + // TODO: Validate that that all EVM chains are using the same keybundle. + relay.NetworkEVM: node.FirstOCRKeybundle().KeyBundleID, + }, + P2PKeyID: node.PeerID.String(), + RelayConfigs: nil, + PluginConfig: map[string]any{}, + }) + } else { + spec, err = validate.NewCCIPSpecToml(validate.SpecArgs{ + P2PV2Bootstrappers: []string{}, // Intentionally empty for bootstraps. + CapabilityVersion: CapabilityVersion, + CapabilityLabelledName: CapabilityLabelledName, + OCRKeyBundleIDs: map[string]string{}, + // TODO: validate that all EVM chains are using the same keybundle + P2PKeyID: node.PeerID.String(), + RelayConfigs: nil, + PluginConfig: map[string]any{}, + }) } - spec, err := validate.NewCCIPSpecToml(validate.SpecArgs{ - P2PV2Bootstrappers: p2pV2Bootstrappers, - CapabilityVersion: CapabilityVersion, - CapabilityLabelledName: CapabilityLabelledName, - OCRKeyBundleIDs: map[string]string{ - // TODO: Validate that that all EVM chains are using the same keybundle. - relay.NetworkEVM: nodeChainConfigs.ChainConfigs[0].Ocr2Config.OcrKeyBundle.BundleId, - }, - // TODO: validate that all EVM chains are using the same keybundle - P2PKeyID: nodeChainConfigs.ChainConfigs[0].Ocr2Config.P2PKeyBundle.PeerId, - RelayConfigs: nil, - PluginConfig: map[string]any{}, - }) if err != nil { return nil, err } - nodesToJobSpecs[node] = append(nodesToJobSpecs[node], spec) + nodesToJobSpecs[node.NodeID] = append(nodesToJobSpecs[node.NodeID], spec) } return nodesToJobSpecs, nil } diff --git a/integration-tests/deployment/ccip/propose.go b/integration-tests/deployment/ccip/propose.go index 4fc38965ea..eced93dde0 100644 --- a/integration-tests/deployment/ccip/propose.go +++ b/integration-tests/deployment/ccip/propose.go @@ -1,14 +1,20 @@ package ccipdeployment import ( + "bytes" + "context" "math/big" - "time" + "testing" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" + "github.com/ethereum/go-ethereum/crypto" + owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/tools/gethwrappers" + "github.com/smartcontractkit/ccip-owner-contracts/tools/proposal/mcms" + "github.com/smartcontractkit/ccip-owner-contracts/tools/proposal/timelock" chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/integration-tests/deployment" ) @@ -17,48 +23,160 @@ import ( func SimTransactOpts() *bind.TransactOpts { return &bind.TransactOpts{Signer: func(address common.Address, transaction *types.Transaction) (*types.Transaction, error) { return transaction, nil - }, From: common.HexToAddress("0x0"), NoSend: true, GasLimit: 200_000} + }, From: common.HexToAddress("0x0"), NoSend: true, GasLimit: 1_000_000} +} + +func SignProposal(t *testing.T, env deployment.Environment, proposal *timelock.MCMSWithTimelockProposal) *mcms.Executor { + executorClients := make(map[mcms.ChainIdentifier]mcms.ContractDeployBackend) + for _, chain := range env.Chains { + chainselc, exists := chainsel.ChainBySelector(chain.Selector) + require.True(t, exists) + chainSel := mcms.ChainIdentifier(chainselc.Selector) + executorClients[chainSel] = chain.Client + } + realProposal, err := proposal.ToMCMSOnlyProposal() + require.NoError(t, err) + executor, err := realProposal.ToExecutor(executorClients) + require.NoError(t, err) + payload, err := executor.SigningHash() + require.NoError(t, err) + // Sign the payload + sig, err := crypto.Sign(payload.Bytes(), TestXXXMCMSSigner) + require.NoError(t, err) + mcmSig, err := mcms.NewSignatureFromBytes(sig) + require.NoError(t, err) + executor.Proposal.Signatures = append(executor.Proposal.Signatures, mcmSig) + require.NoError(t, executor.Proposal.Validate()) + return executor +} + +func ExecuteProposal(t *testing.T, env deployment.Environment, executor *mcms.Executor, + state CCIPOnChainState, sel uint64) { + // Set the root. + tx, err2 := executor.SetRootOnChain(env.Chains[sel].DeployerKey, mcms.ChainIdentifier(sel)) + require.NoError(t, err2) + _, err2 = env.Chains[sel].Confirm(tx) + require.NoError(t, err2) + + // TODO: This sort of helper probably should move to the MCMS lib. + // Execute all the transactions in the proposal which are for this chain. + for _, chainOp := range executor.Operations[mcms.ChainIdentifier(sel)] { + for idx, op := range executor.ChainAgnosticOps { + if bytes.Equal(op.Data, chainOp.Data) && op.To == chainOp.To { + opTx, err3 := executor.ExecuteOnChain(env.Chains[sel].DeployerKey, idx) + require.NoError(t, err3) + block, err3 := env.Chains[sel].Confirm(opTx) + require.NoError(t, err3) + t.Log("executed", chainOp) + it, err3 := state.Chains[sel].Timelock.FilterCallScheduled(&bind.FilterOpts{ + Start: block, + End: &block, + Context: context.Background(), + }, nil, nil) + require.NoError(t, err3) + var calls []owner_helpers.RBACTimelockCall + var pred, salt [32]byte + for it.Next() { + // Note these are the same for the whole batch, can overwrite + pred = it.Event.Predecessor + salt = it.Event.Salt + t.Log("scheduled", it.Event) + calls = append(calls, owner_helpers.RBACTimelockCall{ + Target: it.Event.Target, + Data: it.Event.Data, + Value: it.Event.Value, + }) + } + tx, err := state.Chains[sel].Timelock.ExecuteBatch( + env.Chains[sel].DeployerKey, calls, pred, salt) + require.NoError(t, err) + _, err = env.Chains[sel].Confirm(tx) + require.NoError(t, err) + } + } + } } func GenerateAcceptOwnershipProposal( - e deployment.Environment, + state CCIPOnChainState, + homeChain uint64, chains []uint64, - ab deployment.AddressBook, -) (deployment.Proposal, error) { - state, err := LoadOnchainState(e, ab) - if err != nil { - return deployment.Proposal{}, err - } - // TODO: Just onramp as an example - var ops []owner_helpers.ManyChainMultiSigOp +) (*timelock.MCMSWithTimelockProposal, error) { + // TODO: Accept rest of contracts + var batches []timelock.BatchChainOperation + metaDataPerChain := make(map[mcms.ChainIdentifier]timelock.MCMSWithTimelockChainMetadata) for _, sel := range chains { - opCount, err := state.Chains[sel].Mcm.GetOpCount(nil) + chain, _ := chainsel.ChainBySelector(sel) + acceptOnRamp, err := state.Chains[sel].OnRamp.AcceptOwnership(SimTransactOpts()) if err != nil { - return deployment.Proposal{}, err + return nil, err } - - txData, err := state.Chains[sel].EvmOnRampV160.AcceptOwnership(SimTransactOpts()) + acceptFeeQuoter, err := state.Chains[sel].FeeQuoter.AcceptOwnership(SimTransactOpts()) if err != nil { - return deployment.Proposal{}, err + return nil, err } - evmID, err := chainsel.ChainIdFromSelector(sel) - if err != nil { - return deployment.Proposal{}, err + chainSel := mcms.ChainIdentifier(chain.Selector) + metaDataPerChain[chainSel] = timelock.MCMSWithTimelockChainMetadata{ + ChainMetadata: mcms.ChainMetadata{ + NonceOffset: 0, + MCMAddress: state.Chains[sel].Mcm.Address(), + }, + TimelockAddress: state.Chains[sel].Timelock.Address(), } - ops = append(ops, owner_helpers.ManyChainMultiSigOp{ - ChainId: big.NewInt(int64(evmID)), - MultiSig: state.Chains[sel].McmsAddr, - Nonce: opCount, - To: state.Chains[sel].EvmOnRampV160.Address(), - Value: big.NewInt(0), - Data: txData.Data(), + batches = append(batches, timelock.BatchChainOperation{ + ChainIdentifier: chainSel, + Batch: []mcms.Operation{ + { + To: state.Chains[sel].OnRamp.Address(), + Data: acceptOnRamp.Data(), + Value: big.NewInt(0), + }, + { + To: state.Chains[sel].FeeQuoter.Address(), + Data: acceptFeeQuoter.Data(), + Value: big.NewInt(0), + }, + }, }) } - // TODO: Real valid until. - return deployment.Proposal{ValidUntil: uint32(time.Now().Unix()), Ops: ops}, nil -} - -func ApplyProposal(env deployment.Environment, p deployment.Proposal, state CCIPOnChainState) error { - // TODO - return nil + acceptCR, err := state.Chains[homeChain].CapabilityRegistry.AcceptOwnership(SimTransactOpts()) + if err != nil { + return nil, err + } + acceptCCIPConfig, err := state.Chains[homeChain].CCIPConfig.AcceptOwnership(SimTransactOpts()) + if err != nil { + return nil, err + } + homeChainID := mcms.ChainIdentifier(homeChain) + metaDataPerChain[homeChainID] = timelock.MCMSWithTimelockChainMetadata{ + ChainMetadata: mcms.ChainMetadata{ + NonceOffset: 0, + MCMAddress: state.Chains[homeChain].Mcm.Address(), + }, + TimelockAddress: state.Chains[homeChain].Timelock.Address(), + } + batches = append(batches, timelock.BatchChainOperation{ + ChainIdentifier: homeChainID, + Batch: []mcms.Operation{ + { + To: state.Chains[homeChain].CapabilityRegistry.Address(), + Data: acceptCR.Data(), + Value: big.NewInt(0), + }, + { + To: state.Chains[homeChain].CCIPConfig.Address(), + Data: acceptCCIPConfig.Data(), + Value: big.NewInt(0), + }, + }, + }) + return timelock.NewMCMSWithTimelockProposal( + "1", + 2004259681, // TODO + []mcms.Signature{}, + false, + metaDataPerChain, + "blah", // TODO + batches, + timelock.Schedule, "0s") } diff --git a/integration-tests/deployment/ccip/state.go b/integration-tests/deployment/ccip/state.go index f129650b30..50ed396d9d 100644 --- a/integration-tests/deployment/ccip/state.go +++ b/integration-tests/deployment/ccip/state.go @@ -7,13 +7,15 @@ import ( "github.com/pkg/errors" chainsel "github.com/smartcontractkit/chain-selectors" - owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" - "github.com/smartcontractkit/chainlink/integration-tests/deployment" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" + + owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/tools/gethwrappers" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" @@ -22,14 +24,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" ) type CCIPChainState struct { - EvmOnRampV160 *onramp.OnRamp - EvmOffRampV160 *offramp.OffRamp - PriceRegistry *fee_quoter.FeeQuoter + OnRamp *onramp.OnRamp + OffRamp *offramp.OffRamp + FeeQuoter *fee_quoter.FeeQuoter ArmProxy *rmn_proxy_contract.RMNProxyContract NonceManager *nonce_manager.NonceManager TokenAdminRegistry *token_admin_registry.TokenAdminRegistry @@ -42,12 +42,11 @@ type CCIPChainState struct { CapabilityRegistry *capabilities_registry.CapabilitiesRegistry CCIPConfig *ccip_config.CCIPConfig Mcm *owner_wrappers.ManyChainMultiSig - // TODO: remove once we have Address() on wrappers - McmsAddr common.Address - Timelock *owner_wrappers.RBACTimelock + Timelock *owner_wrappers.RBACTimelock // Test contracts - Receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver + Receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver + TestRouter *router.Router } // Onchain state always derivable from an address book. @@ -140,6 +139,24 @@ func (s CCIPOnChainState) Snapshot(chains []uint64) (CCIPSnapShot, error) { AuthorizedCallers: authorizedCallers, } } + if nm != nil { + authorizedCallers, err := nm.GetAllAuthorizedCallers(nil) + if err != nil { + return snapshot, err + } + tv, err := nm.TypeAndVersion(nil) + if err != nil { + return snapshot, err + } + c.NonceManager = NonceManagerView{ + Contract: Contract{ + TypeAndVersion: tv, + Address: nm.Address(), + }, + // TODO: these can be resolved using an address book + AuthorizedCallers: authorizedCallers, + } + } snapshot.Chains[chainName] = c } return snapshot, nil @@ -189,7 +206,6 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type return state, err } state.Mcm = mcms - state.McmsAddr = common.HexToAddress(address) case deployment.NewTypeAndVersion(CapabilitiesRegistry, deployment.Version1_0_0).String(): cr, err := capabilities_registry.NewCapabilitiesRegistry(common.HexToAddress(address), chain.Client) if err != nil { @@ -201,13 +217,13 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type if err != nil { return state, err } - state.EvmOnRampV160 = onRampC + state.OnRamp = onRampC case deployment.NewTypeAndVersion(OffRamp, deployment.Version1_6_0_dev).String(): offRamp, err := offramp.NewOffRamp(common.HexToAddress(address), chain.Client) if err != nil { return state, err } - state.EvmOffRampV160 = offRamp + state.OffRamp = offRamp case deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0).String(): armProxy, err := rmn_proxy_contract.NewRMNProxyContract(common.HexToAddress(address), chain.Client) if err != nil { @@ -244,12 +260,18 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type return state, err } state.Router = r - case deployment.NewTypeAndVersion(PriceRegistry, deployment.Version1_6_0_dev).String(): - pr, err := fee_quoter.NewFeeQuoter(common.HexToAddress(address), chain.Client) + case deployment.NewTypeAndVersion(TestRouter, deployment.Version1_2_0).String(): + r, err := router.NewRouter(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + state.TestRouter = r + case deployment.NewTypeAndVersion(FeeQuoter, deployment.Version1_6_0_dev).String(): + fq, err := fee_quoter.NewFeeQuoter(common.HexToAddress(address), chain.Client) if err != nil { return state, err } - state.PriceRegistry = pr + state.FeeQuoter = fq case deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0).String(): lt, err := burn_mint_erc677.NewBurnMintERC677(common.HexToAddress(address), chain.Client) if err != nil { diff --git a/integration-tests/deployment/ccip/test_helpers.go b/integration-tests/deployment/ccip/test_helpers.go index 2ec837c9ee..779b29a749 100644 --- a/integration-tests/deployment/ccip/test_helpers.go +++ b/integration-tests/deployment/ccip/test_helpers.go @@ -2,12 +2,21 @@ package ccipdeployment import ( "context" + "sort" "testing" + "time" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" + jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" @@ -40,17 +49,21 @@ type DeployedTestEnvironment struct { // NewDeployedEnvironment creates a new CCIP environment // with capreg and nodes set up. -func NewDeployedTestEnvironment(t *testing.T, lggr logger.Logger) DeployedTestEnvironment { +func NewEnvironmentWithCR(t *testing.T, lggr logger.Logger, numChains int) DeployedTestEnvironment { ctx := Context(t) - chains := memory.NewMemoryChains(t, 3) - homeChainSel := uint64(0) - homeChainEVM := uint64(0) + chains := memory.NewMemoryChains(t, numChains) + // Lower chainSel is home chain. + var chainSels []uint64 // Say first chain is home chain. for chainSel := range chains { - homeChainEVM, _ = chainsel.ChainIdFromSelector(chainSel) - homeChainSel = chainSel - break + chainSels = append(chainSels, chainSel) } + sort.Slice(chainSels, func(i, j int) bool { + return chainSels[i] < chainSels[j] + }) + // Take lowest for determinism. + homeChainSel := chainSels[0] + homeChainEVM, _ := chainsel.ChainIdFromSelector(homeChainSel) ab, capReg, err := DeployCapReg(lggr, chains, homeChainSel) require.NoError(t, err) @@ -73,3 +86,107 @@ func NewDeployedTestEnvironment(t *testing.T, lggr logger.Logger) DeployedTestEn Nodes: nodes, } } + +func NewEnvironmentWithCRAndJobs(t *testing.T, lggr logger.Logger, numChains int) DeployedTestEnvironment { + ctx := Context(t) + e := NewEnvironmentWithCR(t, lggr, numChains) + jbs, err := NewCCIPJobSpecs(e.Env.NodeIDs, e.Env.Offchain) + require.NoError(t, err) + for nodeID, jobs := range jbs { + for _, job := range jobs { + // Note these auto-accept + _, err := e.Env.Offchain.ProposeJob(ctx, + &jobv1.ProposeJobRequest{ + NodeId: nodeID, + Spec: job, + }) + require.NoError(t, err) + } + } + // Wait for plugins to register filters? + // TODO: Investigate how to avoid. + time.Sleep(30 * time.Second) + + // Ensure job related logs are up to date. + require.NoError(t, ReplayAllLogs(e.Nodes, e.Env.Chains)) + return e +} + +func ReplayAllLogs(nodes map[string]memory.Node, chains map[uint64]deployment.Chain) error { + for _, node := range nodes { + for sel := range chains { + if err := node.ReplayLogs(map[uint64]uint64{sel: 1}); err != nil { + return err + } + } + } + return nil +} + +func SendRequest(t *testing.T, e deployment.Environment, state CCIPOnChainState, src, dest uint64, testRouter bool) uint64 { + msg := router.ClientEVM2AnyMessage{ + Receiver: common.LeftPadBytes(state.Chains[dest].Receiver.Address().Bytes(), 32), + Data: []byte("hello"), + TokenAmounts: nil, // TODO: no tokens for now + // Pay native. + FeeToken: common.HexToAddress("0x0"), + ExtraArgs: nil, // TODO: no extra args for now, falls back to default + } + router := state.Chains[src].Router + if testRouter { + router = state.Chains[src].TestRouter + } + fee, err := router.GetFee( + &bind.CallOpts{Context: context.Background()}, dest, msg) + require.NoError(t, err, deployment.MaybeDataErr(err)) + + t.Logf("Sending CCIP request from chain selector %d to chain selector %d", + src, dest) + e.Chains[src].DeployerKey.Value = fee + tx, err := router.CcipSend( + e.Chains[src].DeployerKey, + dest, + msg) + require.NoError(t, err) + blockNum, err := e.Chains[src].Confirm(tx) + require.NoError(t, err) + it, err := state.Chains[src].OnRamp.FilterCCIPMessageSent(&bind.FilterOpts{ + Start: blockNum, + End: &blockNum, + Context: context.Background(), + }, []uint64{dest}) + require.NoError(t, err) + require.True(t, it.Next()) + return it.Event.Message.Header.SequenceNumber +} + +func ConfirmExecution(t *testing.T, + source, dest deployment.Chain, + offramp *offramp.OffRamp, + expectedSeqNr uint64) { + tick := time.NewTicker(5 * time.Second) + defer tick.Stop() + for range tick.C { + // TODO: Clean this up + source.Client.(*backends.SimulatedBackend).Commit() + dest.Client.(*backends.SimulatedBackend).Commit() + scc, err := offramp.GetSourceChainConfig(nil, source.Selector) + require.NoError(t, err) + t.Logf("Waiting for ExecutionStateChanged on chain %d from chain %d with expected sequence number %d, current onchain minSeqNr: %d", + dest.Selector, source.Selector, expectedSeqNr, scc.MinSeqNr) + iter, err := offramp.FilterExecutionStateChanged(nil, + []uint64{source.Selector}, []uint64{expectedSeqNr}, nil) + require.NoError(t, err) + var count int + for iter.Next() { + if iter.Event.SequenceNumber == expectedSeqNr && iter.Event.SourceChainSelector == source.Selector { + count++ + } + } + if count == 1 { + t.Logf("Received ExecutionStateChanged on chain %d from chain %d with expected sequence number %d", + dest.Selector, source.Selector, expectedSeqNr) + return + } + } +} diff --git a/integration-tests/deployment/changeset.go b/integration-tests/deployment/changeset.go index d929022ed9..aeac3e8e72 100644 --- a/integration-tests/deployment/changeset.go +++ b/integration-tests/deployment/changeset.go @@ -1,28 +1,12 @@ package deployment import ( - owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers" + "github.com/smartcontractkit/ccip-owner-contracts/tools/proposal/timelock" ) -// TODO: Move to real MCM structs once available. -type Proposal struct { - // keccak256(abi.encode(root, validUntil)) is what is signed by MCMS - // signers. - ValidUntil uint32 - // Leaves are the items in the proposal. - // Uses these to generate the root as well as display whats in the root. - // These Ops may be destined for distinct chains. - Ops []owner_wrappers.ManyChainMultiSigOp -} - -func (p Proposal) String() string { - // TODO - return "" -} - // Services as input to CI/Async tasks type ChangesetOutput struct { JobSpecs map[string][]string - Proposals []Proposal + Proposals []timelock.MCMSWithTimelockProposal AddressBook AddressBook } diff --git a/integration-tests/deployment/environment.go b/integration-tests/deployment/environment.go index 5dfa1cd24e..692d7744b1 100644 --- a/integration-tests/deployment/environment.go +++ b/integration-tests/deployment/environment.go @@ -1,10 +1,12 @@ package deployment import ( + "bytes" "context" "errors" "fmt" "math/big" + "sort" "strconv" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -28,6 +30,7 @@ type OnchainClient interface { // For EVM specifically we can use existing geth interface // to abstract chain clients. bind.ContractBackend + bind.DeployBackend } type OffchainClient interface { @@ -62,6 +65,23 @@ func (e Environment) AllChainSelectors() []uint64 { return selectors } +func (e Environment) AllChainSelectorsExcluding(excluding []uint64) []uint64 { + var selectors []uint64 + for sel := range e.Chains { + excluded := false + for _, toExclude := range excluding { + if sel == toExclude { + excluded = true + } + } + if excluded { + continue + } + selectors = append(selectors, sel) + } + return selectors +} + func ConfirmIfNoError(chain Chain, tx *types.Transaction, err error) (uint64, error) { if err != nil { //revive:disable @@ -100,42 +120,68 @@ type OCRConfig struct { PeerID p2pkey.PeerID TransmitAccount types2.Account ConfigEncryptionPublicKey types3.ConfigEncryptionPublicKey - IsBootstrap bool - MultiAddr string // TODO: type + KeyBundleID string } +// Nodes includes is a group CL nodes. type Nodes []Node -func (n Nodes) PeerIDs(chainSel uint64) [][32]byte { +// PeerIDs returns peerIDs in a sorted list +func (n Nodes) PeerIDs() [][32]byte { var peerIDs [][32]byte for _, node := range n { - cfg := node.SelToOCRConfig[chainSel] - // NOTE: Assume same peerID for all chains. - // Might make sense to change proto as peerID is 1-1 with node? - peerIDs = append(peerIDs, cfg.PeerID) + peerIDs = append(peerIDs, node.PeerID) } + sort.Slice(peerIDs, func(i, j int) bool { + return bytes.Compare(peerIDs[i][:], peerIDs[j][:]) < 0 + }) return peerIDs } -func (n Nodes) BootstrapPeerIDs(chainSel uint64) [][32]byte { - var peerIDs [][32]byte +func (n Nodes) NonBootstraps() Nodes { + var nonBootstraps Nodes for _, node := range n { - cfg := node.SelToOCRConfig[chainSel] - if !cfg.IsBootstrap { + if node.IsBootstrap { continue } - peerIDs = append(peerIDs, cfg.PeerID) + nonBootstraps = append(nonBootstraps, node) } - return peerIDs + return nonBootstraps +} + +func (n Nodes) DefaultF() uint8 { + return uint8(len(n) / 3) +} + +func (n Nodes) BootstrapLocators() []string { + bootstrapMp := make(map[string]struct{}) + for _, node := range n { + if node.IsBootstrap { + bootstrapMp[fmt.Sprintf("%s@%s", + // p2p_12D3... -> 12D3... + node.PeerID.String()[4:], node.MultiAddr)] = struct{}{} + } + } + var locators []string + for b := range bootstrapMp { + locators = append(locators, b) + } + return locators } -// OffchainPublicKey types.OffchainPublicKey -// // For EVM-chains, this an *address*. -// OnchainPublicKey types.OnchainPublicKey -// PeerID string -// TransmitAccount types.Account type Node struct { + NodeID string SelToOCRConfig map[uint64]OCRConfig + PeerID p2pkey.PeerID + IsBootstrap bool + MultiAddr string +} + +func (n Node) FirstOCRKeybundle() OCRConfig { + for _, ocrConfig := range n.SelToOCRConfig { + return ocrConfig + } + return OCRConfig{} } func MustPeerIDFromString(s string) p2pkey.PeerID { @@ -150,20 +196,33 @@ func MustPeerIDFromString(s string) p2pkey.PeerID { // OCR config for example. func NodeInfo(nodeIDs []string, oc OffchainClient) (Nodes, error) { var nodes []Node - for _, node := range nodeIDs { + for _, nodeID := range nodeIDs { // TODO: Filter should accept multiple nodes nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ - NodeIds: []string{node}, + NodeIds: []string{nodeID}, }}) if err != nil { return nil, err } selToOCRConfig := make(map[uint64]OCRConfig) + bootstrap := false + var peerID p2pkey.PeerID + var multiAddr string for _, chainConfig := range nodeChainConfigs.ChainConfigs { if chainConfig.Chain.Type == nodev1.ChainType_CHAIN_TYPE_SOLANA { // Note supported for CCIP yet. continue } + // NOTE: Assume same peerID/multiAddr for all chains. + // Might make sense to change proto as peerID/multiAddr is 1-1 with nodeID? + peerID = MustPeerIDFromString(chainConfig.Ocr2Config.P2PKeyBundle.PeerId) + multiAddr = chainConfig.Ocr2Config.Multiaddr + if chainConfig.Ocr2Config.IsBootstrap { + // NOTE: Assume same peerID for all chains. + // Might make sense to change proto as peerID is 1-1 with nodeID? + bootstrap = true + break + } evmChainID, err := strconv.Atoi(chainConfig.Chain.Id) if err != nil { return nil, err @@ -186,12 +245,15 @@ func NodeInfo(nodeIDs []string, oc OffchainClient) (Nodes, error) { PeerID: MustPeerIDFromString(chainConfig.Ocr2Config.P2PKeyBundle.PeerId), TransmitAccount: types2.Account(chainConfig.AccountAddress), ConfigEncryptionPublicKey: cpk, - IsBootstrap: chainConfig.Ocr2Config.IsBootstrap, - MultiAddr: chainConfig.Ocr2Config.Multiaddr, + KeyBundleID: chainConfig.Ocr2Config.OcrKeyBundle.BundleId, } } nodes = append(nodes, Node{ + NodeID: nodeID, SelToOCRConfig: selToOCRConfig, + IsBootstrap: bootstrap, + PeerID: peerID, + MultiAddr: multiAddr, }) } diff --git a/integration-tests/go.mod b/integration-tests/go.mod index a260dbba6e..8d21fff89c 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -33,7 +33,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 - github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 + github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240910151738-3f318badcfb5 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 1ba9feb496..5d75436c1e 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1417,8 +1417,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685 h1:jakAsdhDxV4cMgRAcSvHraXjyePi8umG5SEUTGFvuy8= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240808195812-ae0378684685/go.mod h1:p7L/xNEQpHDdZtgFA6/FavuZHqvV3kYhQysxBywmq1k= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240910151738-3f318badcfb5 h1:m0HuGuVdRHqBBkHJpSR/QBV7gtLB+hFkXZQ9tEkjdzo= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240910151738-3f318badcfb5/go.mod h1:N60/wwocvZ5A3RGmYaMWo0fPFa5tTMlhI9lJ22DRktM= github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnjjIQAEBnutCtksPzVDY= github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= From a3f97b85764f5862437247ea4d03219279588586 Mon Sep 17 00:00:00 2001 From: Ivaylo Novakov Date: Fri, 13 Sep 2024 19:04:57 +0200 Subject: [PATCH 344/432] Update the code owner of `feeds` service from FMS group to OPCORE (#14230) * Update the code owner of `feeds` service from the old FMS group to the new OPCORE one. * Add missing key engineers. --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bafde6de0e..7bdec1a61f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -11,7 +11,7 @@ # Services /core/services/directrequest @smartcontractkit/keepers -/core/services/feeds @smartcontractkit/FMS +/core/services/feeds @smartcontractkit/op-core @eutopian @yevshev /core/services/synchronization/telem @smartcontractkit/realtime /core/capabilities/ccip @smartcontractkit/ccip-offchain From baf36ec4df51bb9218ca89988e9aa3ecb81af121 Mon Sep 17 00:00:00 2001 From: Awbrey Hughlett Date: Fri, 13 Sep 2024 13:09:06 -0500 Subject: [PATCH 345/432] added unimplemented contract reader (#14413) * added unimplemented contract reader * fix write targets test * update common --- .mockery.yaml | 4 +- .../targets/mocks/contract_reader.go | 533 ------------------ .../targets/mocks/contract_value_getter.go | 136 +++++ core/capabilities/targets/write_target.go | 16 +- .../capabilities/targets/write_target_test.go | 2 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/relay/evm/chain_reader.go | 1 + go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 14 files changed, 167 insertions(+), 549 deletions(-) delete mode 100644 core/capabilities/targets/mocks/contract_reader.go create mode 100644 core/capabilities/targets/mocks/contract_value_getter.go diff --git a/.mockery.yaml b/.mockery.yaml index 599aa1e65e..b22875e3f9 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -348,7 +348,6 @@ packages: Codec: config: dir: core/services/relay/evm/mocks - ContractReader: ChainWriter: github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp: config: @@ -588,3 +587,6 @@ packages: github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer: interfaces: ORM: + github.com/smartcontractkit/chainlink/v2/core/capabilities/targets: + interfaces: + ContractValueGetter: \ No newline at end of file diff --git a/core/capabilities/targets/mocks/contract_reader.go b/core/capabilities/targets/mocks/contract_reader.go deleted file mode 100644 index dd92195ec2..0000000000 --- a/core/capabilities/targets/mocks/contract_reader.go +++ /dev/null @@ -1,533 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package mocks - -import ( - context "context" - - query "github.com/smartcontractkit/chainlink-common/pkg/types/query" - primitives "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" - mock "github.com/stretchr/testify/mock" - - types "github.com/smartcontractkit/chainlink-common/pkg/types" -) - -// ContractReader is an autogenerated mock type for the ContractReader type -type ContractReader struct { - mock.Mock -} - -type ContractReader_Expecter struct { - mock *mock.Mock -} - -func (_m *ContractReader) EXPECT() *ContractReader_Expecter { - return &ContractReader_Expecter{mock: &_m.Mock} -} - -// BatchGetLatestValues provides a mock function with given fields: ctx, request -func (_m *ContractReader) BatchGetLatestValues(ctx context.Context, request types.BatchGetLatestValuesRequest) (types.BatchGetLatestValuesResult, error) { - ret := _m.Called(ctx, request) - - if len(ret) == 0 { - panic("no return value specified for BatchGetLatestValues") - } - - var r0 types.BatchGetLatestValuesResult - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.BatchGetLatestValuesRequest) (types.BatchGetLatestValuesResult, error)); ok { - return rf(ctx, request) - } - if rf, ok := ret.Get(0).(func(context.Context, types.BatchGetLatestValuesRequest) types.BatchGetLatestValuesResult); ok { - r0 = rf(ctx, request) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(types.BatchGetLatestValuesResult) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, types.BatchGetLatestValuesRequest) error); ok { - r1 = rf(ctx, request) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ContractReader_BatchGetLatestValues_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BatchGetLatestValues' -type ContractReader_BatchGetLatestValues_Call struct { - *mock.Call -} - -// BatchGetLatestValues is a helper method to define mock.On call -// - ctx context.Context -// - request types.BatchGetLatestValuesRequest -func (_e *ContractReader_Expecter) BatchGetLatestValues(ctx interface{}, request interface{}) *ContractReader_BatchGetLatestValues_Call { - return &ContractReader_BatchGetLatestValues_Call{Call: _e.mock.On("BatchGetLatestValues", ctx, request)} -} - -func (_c *ContractReader_BatchGetLatestValues_Call) Run(run func(ctx context.Context, request types.BatchGetLatestValuesRequest)) *ContractReader_BatchGetLatestValues_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(types.BatchGetLatestValuesRequest)) - }) - return _c -} - -func (_c *ContractReader_BatchGetLatestValues_Call) Return(_a0 types.BatchGetLatestValuesResult, _a1 error) *ContractReader_BatchGetLatestValues_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *ContractReader_BatchGetLatestValues_Call) RunAndReturn(run func(context.Context, types.BatchGetLatestValuesRequest) (types.BatchGetLatestValuesResult, error)) *ContractReader_BatchGetLatestValues_Call { - _c.Call.Return(run) - return _c -} - -// Bind provides a mock function with given fields: ctx, bindings -func (_m *ContractReader) Bind(ctx context.Context, bindings []types.BoundContract) error { - ret := _m.Called(ctx, bindings) - - if len(ret) == 0 { - panic("no return value specified for Bind") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, []types.BoundContract) error); ok { - r0 = rf(ctx, bindings) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ContractReader_Bind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bind' -type ContractReader_Bind_Call struct { - *mock.Call -} - -// Bind is a helper method to define mock.On call -// - ctx context.Context -// - bindings []types.BoundContract -func (_e *ContractReader_Expecter) Bind(ctx interface{}, bindings interface{}) *ContractReader_Bind_Call { - return &ContractReader_Bind_Call{Call: _e.mock.On("Bind", ctx, bindings)} -} - -func (_c *ContractReader_Bind_Call) Run(run func(ctx context.Context, bindings []types.BoundContract)) *ContractReader_Bind_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].([]types.BoundContract)) - }) - return _c -} - -func (_c *ContractReader_Bind_Call) Return(_a0 error) *ContractReader_Bind_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ContractReader_Bind_Call) RunAndReturn(run func(context.Context, []types.BoundContract) error) *ContractReader_Bind_Call { - _c.Call.Return(run) - return _c -} - -// Close provides a mock function with given fields: -func (_m *ContractReader) Close() error { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for Close") - } - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ContractReader_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' -type ContractReader_Close_Call struct { - *mock.Call -} - -// Close is a helper method to define mock.On call -func (_e *ContractReader_Expecter) Close() *ContractReader_Close_Call { - return &ContractReader_Close_Call{Call: _e.mock.On("Close")} -} - -func (_c *ContractReader_Close_Call) Run(run func()) *ContractReader_Close_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *ContractReader_Close_Call) Return(_a0 error) *ContractReader_Close_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ContractReader_Close_Call) RunAndReturn(run func() error) *ContractReader_Close_Call { - _c.Call.Return(run) - return _c -} - -// GetLatestValue provides a mock function with given fields: ctx, readIdentifier, confidenceLevel, params, returnVal -func (_m *ContractReader) GetLatestValue(ctx context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params interface{}, returnVal interface{}) error { - ret := _m.Called(ctx, readIdentifier, confidenceLevel, params, returnVal) - - if len(ret) == 0 { - panic("no return value specified for GetLatestValue") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, primitives.ConfidenceLevel, interface{}, interface{}) error); ok { - r0 = rf(ctx, readIdentifier, confidenceLevel, params, returnVal) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ContractReader_GetLatestValue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLatestValue' -type ContractReader_GetLatestValue_Call struct { - *mock.Call -} - -// GetLatestValue is a helper method to define mock.On call -// - ctx context.Context -// - readIdentifier string -// - confidenceLevel primitives.ConfidenceLevel -// - params interface{} -// - returnVal interface{} -func (_e *ContractReader_Expecter) GetLatestValue(ctx interface{}, readIdentifier interface{}, confidenceLevel interface{}, params interface{}, returnVal interface{}) *ContractReader_GetLatestValue_Call { - return &ContractReader_GetLatestValue_Call{Call: _e.mock.On("GetLatestValue", ctx, readIdentifier, confidenceLevel, params, returnVal)} -} - -func (_c *ContractReader_GetLatestValue_Call) Run(run func(ctx context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params interface{}, returnVal interface{})) *ContractReader_GetLatestValue_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(primitives.ConfidenceLevel), args[3].(interface{}), args[4].(interface{})) - }) - return _c -} - -func (_c *ContractReader_GetLatestValue_Call) Return(_a0 error) *ContractReader_GetLatestValue_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ContractReader_GetLatestValue_Call) RunAndReturn(run func(context.Context, string, primitives.ConfidenceLevel, interface{}, interface{}) error) *ContractReader_GetLatestValue_Call { - _c.Call.Return(run) - return _c -} - -// HealthReport provides a mock function with given fields: -func (_m *ContractReader) HealthReport() map[string]error { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for HealthReport") - } - - var r0 map[string]error - if rf, ok := ret.Get(0).(func() map[string]error); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[string]error) - } - } - - return r0 -} - -// ContractReader_HealthReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HealthReport' -type ContractReader_HealthReport_Call struct { - *mock.Call -} - -// HealthReport is a helper method to define mock.On call -func (_e *ContractReader_Expecter) HealthReport() *ContractReader_HealthReport_Call { - return &ContractReader_HealthReport_Call{Call: _e.mock.On("HealthReport")} -} - -func (_c *ContractReader_HealthReport_Call) Run(run func()) *ContractReader_HealthReport_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *ContractReader_HealthReport_Call) Return(_a0 map[string]error) *ContractReader_HealthReport_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ContractReader_HealthReport_Call) RunAndReturn(run func() map[string]error) *ContractReader_HealthReport_Call { - _c.Call.Return(run) - return _c -} - -// Name provides a mock function with given fields: -func (_m *ContractReader) Name() string { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for Name") - } - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// ContractReader_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' -type ContractReader_Name_Call struct { - *mock.Call -} - -// Name is a helper method to define mock.On call -func (_e *ContractReader_Expecter) Name() *ContractReader_Name_Call { - return &ContractReader_Name_Call{Call: _e.mock.On("Name")} -} - -func (_c *ContractReader_Name_Call) Run(run func()) *ContractReader_Name_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *ContractReader_Name_Call) Return(_a0 string) *ContractReader_Name_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ContractReader_Name_Call) RunAndReturn(run func() string) *ContractReader_Name_Call { - _c.Call.Return(run) - return _c -} - -// QueryKey provides a mock function with given fields: ctx, contract, filter, limitAndSort, sequenceDataType -func (_m *ContractReader) QueryKey(ctx context.Context, contract types.BoundContract, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceDataType interface{}) ([]types.Sequence, error) { - ret := _m.Called(ctx, contract, filter, limitAndSort, sequenceDataType) - - if len(ret) == 0 { - panic("no return value specified for QueryKey") - } - - var r0 []types.Sequence - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, interface{}) ([]types.Sequence, error)); ok { - return rf(ctx, contract, filter, limitAndSort, sequenceDataType) - } - if rf, ok := ret.Get(0).(func(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, interface{}) []types.Sequence); ok { - r0 = rf(ctx, contract, filter, limitAndSort, sequenceDataType) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]types.Sequence) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, interface{}) error); ok { - r1 = rf(ctx, contract, filter, limitAndSort, sequenceDataType) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ContractReader_QueryKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'QueryKey' -type ContractReader_QueryKey_Call struct { - *mock.Call -} - -// QueryKey is a helper method to define mock.On call -// - ctx context.Context -// - contract types.BoundContract -// - filter query.KeyFilter -// - limitAndSort query.LimitAndSort -// - sequenceDataType interface{} -func (_e *ContractReader_Expecter) QueryKey(ctx interface{}, contract interface{}, filter interface{}, limitAndSort interface{}, sequenceDataType interface{}) *ContractReader_QueryKey_Call { - return &ContractReader_QueryKey_Call{Call: _e.mock.On("QueryKey", ctx, contract, filter, limitAndSort, sequenceDataType)} -} - -func (_c *ContractReader_QueryKey_Call) Run(run func(ctx context.Context, contract types.BoundContract, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceDataType interface{})) *ContractReader_QueryKey_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(types.BoundContract), args[2].(query.KeyFilter), args[3].(query.LimitAndSort), args[4].(interface{})) - }) - return _c -} - -func (_c *ContractReader_QueryKey_Call) Return(_a0 []types.Sequence, _a1 error) *ContractReader_QueryKey_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *ContractReader_QueryKey_Call) RunAndReturn(run func(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, interface{}) ([]types.Sequence, error)) *ContractReader_QueryKey_Call { - _c.Call.Return(run) - return _c -} - -// Ready provides a mock function with given fields: -func (_m *ContractReader) Ready() error { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for Ready") - } - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ContractReader_Ready_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Ready' -type ContractReader_Ready_Call struct { - *mock.Call -} - -// Ready is a helper method to define mock.On call -func (_e *ContractReader_Expecter) Ready() *ContractReader_Ready_Call { - return &ContractReader_Ready_Call{Call: _e.mock.On("Ready")} -} - -func (_c *ContractReader_Ready_Call) Run(run func()) *ContractReader_Ready_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *ContractReader_Ready_Call) Return(_a0 error) *ContractReader_Ready_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ContractReader_Ready_Call) RunAndReturn(run func() error) *ContractReader_Ready_Call { - _c.Call.Return(run) - return _c -} - -// Start provides a mock function with given fields: _a0 -func (_m *ContractReader) Start(_a0 context.Context) error { - ret := _m.Called(_a0) - - if len(ret) == 0 { - panic("no return value specified for Start") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ContractReader_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start' -type ContractReader_Start_Call struct { - *mock.Call -} - -// Start is a helper method to define mock.On call -// - _a0 context.Context -func (_e *ContractReader_Expecter) Start(_a0 interface{}) *ContractReader_Start_Call { - return &ContractReader_Start_Call{Call: _e.mock.On("Start", _a0)} -} - -func (_c *ContractReader_Start_Call) Run(run func(_a0 context.Context)) *ContractReader_Start_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *ContractReader_Start_Call) Return(_a0 error) *ContractReader_Start_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ContractReader_Start_Call) RunAndReturn(run func(context.Context) error) *ContractReader_Start_Call { - _c.Call.Return(run) - return _c -} - -// Unbind provides a mock function with given fields: ctx, bindings -func (_m *ContractReader) Unbind(ctx context.Context, bindings []types.BoundContract) error { - ret := _m.Called(ctx, bindings) - - if len(ret) == 0 { - panic("no return value specified for Unbind") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, []types.BoundContract) error); ok { - r0 = rf(ctx, bindings) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ContractReader_Unbind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Unbind' -type ContractReader_Unbind_Call struct { - *mock.Call -} - -// Unbind is a helper method to define mock.On call -// - ctx context.Context -// - bindings []types.BoundContract -func (_e *ContractReader_Expecter) Unbind(ctx interface{}, bindings interface{}) *ContractReader_Unbind_Call { - return &ContractReader_Unbind_Call{Call: _e.mock.On("Unbind", ctx, bindings)} -} - -func (_c *ContractReader_Unbind_Call) Run(run func(ctx context.Context, bindings []types.BoundContract)) *ContractReader_Unbind_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].([]types.BoundContract)) - }) - return _c -} - -func (_c *ContractReader_Unbind_Call) Return(_a0 error) *ContractReader_Unbind_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *ContractReader_Unbind_Call) RunAndReturn(run func(context.Context, []types.BoundContract) error) *ContractReader_Unbind_Call { - _c.Call.Return(run) - return _c -} - -// NewContractReader creates a new instance of ContractReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewContractReader(t interface { - mock.TestingT - Cleanup(func()) -}) *ContractReader { - mock := &ContractReader{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/capabilities/targets/mocks/contract_value_getter.go b/core/capabilities/targets/mocks/contract_value_getter.go new file mode 100644 index 0000000000..2621de4587 --- /dev/null +++ b/core/capabilities/targets/mocks/contract_value_getter.go @@ -0,0 +1,136 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + primitives "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + mock "github.com/stretchr/testify/mock" + + types "github.com/smartcontractkit/chainlink-common/pkg/types" +) + +// ContractValueGetter is an autogenerated mock type for the ContractValueGetter type +type ContractValueGetter struct { + mock.Mock +} + +type ContractValueGetter_Expecter struct { + mock *mock.Mock +} + +func (_m *ContractValueGetter) EXPECT() *ContractValueGetter_Expecter { + return &ContractValueGetter_Expecter{mock: &_m.Mock} +} + +// Bind provides a mock function with given fields: _a0, _a1 +func (_m *ContractValueGetter) Bind(_a0 context.Context, _a1 []types.BoundContract) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for Bind") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []types.BoundContract) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ContractValueGetter_Bind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bind' +type ContractValueGetter_Bind_Call struct { + *mock.Call +} + +// Bind is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 []types.BoundContract +func (_e *ContractValueGetter_Expecter) Bind(_a0 interface{}, _a1 interface{}) *ContractValueGetter_Bind_Call { + return &ContractValueGetter_Bind_Call{Call: _e.mock.On("Bind", _a0, _a1)} +} + +func (_c *ContractValueGetter_Bind_Call) Run(run func(_a0 context.Context, _a1 []types.BoundContract)) *ContractValueGetter_Bind_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]types.BoundContract)) + }) + return _c +} + +func (_c *ContractValueGetter_Bind_Call) Return(_a0 error) *ContractValueGetter_Bind_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ContractValueGetter_Bind_Call) RunAndReturn(run func(context.Context, []types.BoundContract) error) *ContractValueGetter_Bind_Call { + _c.Call.Return(run) + return _c +} + +// GetLatestValue provides a mock function with given fields: _a0, _a1, _a2, _a3, _a4 +func (_m *ContractValueGetter) GetLatestValue(_a0 context.Context, _a1 string, _a2 primitives.ConfidenceLevel, _a3 interface{}, _a4 interface{}) error { + ret := _m.Called(_a0, _a1, _a2, _a3, _a4) + + if len(ret) == 0 { + panic("no return value specified for GetLatestValue") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string, primitives.ConfidenceLevel, interface{}, interface{}) error); ok { + r0 = rf(_a0, _a1, _a2, _a3, _a4) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ContractValueGetter_GetLatestValue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLatestValue' +type ContractValueGetter_GetLatestValue_Call struct { + *mock.Call +} + +// GetLatestValue is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 string +// - _a2 primitives.ConfidenceLevel +// - _a3 interface{} +// - _a4 interface{} +func (_e *ContractValueGetter_Expecter) GetLatestValue(_a0 interface{}, _a1 interface{}, _a2 interface{}, _a3 interface{}, _a4 interface{}) *ContractValueGetter_GetLatestValue_Call { + return &ContractValueGetter_GetLatestValue_Call{Call: _e.mock.On("GetLatestValue", _a0, _a1, _a2, _a3, _a4)} +} + +func (_c *ContractValueGetter_GetLatestValue_Call) Run(run func(_a0 context.Context, _a1 string, _a2 primitives.ConfidenceLevel, _a3 interface{}, _a4 interface{})) *ContractValueGetter_GetLatestValue_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string), args[2].(primitives.ConfidenceLevel), args[3].(interface{}), args[4].(interface{})) + }) + return _c +} + +func (_c *ContractValueGetter_GetLatestValue_Call) Return(_a0 error) *ContractValueGetter_GetLatestValue_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ContractValueGetter_GetLatestValue_Call) RunAndReturn(run func(context.Context, string, primitives.ConfidenceLevel, interface{}, interface{}) error) *ContractValueGetter_GetLatestValue_Call { + _c.Call.Return(run) + return _c +} + +// NewContractValueGetter creates a new instance of ContractValueGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewContractValueGetter(t interface { + mock.TestingT + Cleanup(func()) +}) *ContractValueGetter { + mock := &ContractValueGetter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index c8f33ff823..85c8011410 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -23,7 +23,7 @@ var ( ) type WriteTarget struct { - cr commontypes.ContractReader + cr ContractValueGetter cw commontypes.ChainWriter binding commontypes.BoundContract forwarderAddress string @@ -50,7 +50,19 @@ type TransmissionInfo struct { // TODO: Make this part of the on-chain capability configuration const FORWARDER_CONTRACT_LOGIC_GAS_COST = 100_000 -func NewWriteTarget(lggr logger.Logger, id string, cr commontypes.ContractReader, cw commontypes.ChainWriter, forwarderAddress string, txGasLimit uint64) *WriteTarget { +type ContractValueGetter interface { + Bind(context.Context, []commontypes.BoundContract) error + GetLatestValue(context.Context, string, primitives.ConfidenceLevel, any, any) error +} + +func NewWriteTarget( + lggr logger.Logger, + id string, + cr ContractValueGetter, + cw commontypes.ChainWriter, + forwarderAddress string, + txGasLimit uint64, +) *WriteTarget { info := capabilities.MustNewCapabilityInfo( id, capabilities.CapabilityTypeTarget, diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go index 1dd5323d0f..96df31bd3c 100644 --- a/core/capabilities/targets/write_target_test.go +++ b/core/capabilities/targets/write_target_test.go @@ -28,7 +28,7 @@ func TestWriteTarget(t *testing.T) { ctx := context.Background() cw := mocks.NewChainWriter(t) - cr := mocks.NewContractReader(t) + cr := mocks.NewContractValueGetter(t) forwarderA := testutils.NewAddress() forwarderAddr := forwarderA.Hex() diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 747c4f20ec..7057264864 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.20.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.1 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index ad91e2472c..a4d9587815 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1083,8 +1083,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 h1:BPuehkAQ8R112SlTitukSdKYRJMY3zkvaQS4VSTNn0Q= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa h1:vG4aRggHzNDFTmMFemhhUAzqTfG159w0+RYjO7/cJ5E= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= diff --git a/core/services/relay/evm/chain_reader.go b/core/services/relay/evm/chain_reader.go index c9cc18e34a..800631b858 100644 --- a/core/services/relay/evm/chain_reader.go +++ b/core/services/relay/evm/chain_reader.go @@ -34,6 +34,7 @@ type ChainReaderService interface { } type chainReader struct { + commontypes.UnimplementedContractReader lggr logger.Logger ht logpoller.HeadTracker lp logpoller.LogPoller diff --git a/go.mod b/go.mod index 6f9b0e2beb..e3c64fca6b 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f diff --git a/go.sum b/go.sum index 2ef165dcb5..5ee578f7b2 100644 --- a/go.sum +++ b/go.sum @@ -1044,8 +1044,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 h1:BPuehkAQ8R112SlTitukSdKYRJMY3zkvaQS4VSTNn0Q= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa h1:vG4aRggHzNDFTmMFemhhUAzqTfG159w0+RYjO7/cJ5E= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 8d21fff89c..75892f6947 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -37,7 +37,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 5d75436c1e..f435992ae6 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1425,8 +1425,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 h1:BPuehkAQ8R112SlTitukSdKYRJMY3zkvaQS4VSTNn0Q= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa h1:vG4aRggHzNDFTmMFemhhUAzqTfG159w0+RYjO7/cJ5E= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 86d9f5444b..89a1f05a46 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 9e50850d34..a8a8d86d3a 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1399,8 +1399,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 h1:BPuehkAQ8R112SlTitukSdKYRJMY3zkvaQS4VSTNn0Q= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa h1:vG4aRggHzNDFTmMFemhhUAzqTfG159w0+RYjO7/cJ5E= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240911181800-d00d5184ffaa/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= From 2c70edc8f6aba8a102016a6f0296e0a960d0d4bf Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Fri, 13 Sep 2024 17:31:14 -0700 Subject: [PATCH 346/432] Query exact wasmvm module rather than parsing all (#14425) --- tools/bin/goreleaser_utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/bin/goreleaser_utils b/tools/bin/goreleaser_utils index fa9553274c..979204d1e3 100755 --- a/tools/bin/goreleaser_utils +++ b/tools/bin/goreleaser_utils @@ -25,7 +25,7 @@ _get_arch() { _get_wasmvm_lib_path() { local -r platform="$1" local -r arch="$2" - wasmvm_dir=$(go list -json -m all | jq -r '. | select(.Path == "github.com/CosmWasm/wasmvm") | .Dir') + wasmvm_dir=$(go list -json -m github.com/CosmWasm/wasmvm | jq -r '.Dir') shared_lib_dir="$wasmvm_dir/internal/api" lib_name="libwasmvm" if [ "$platform" == "darwin" ]; then From 9328ed807fad56b9fd34a781f20b3c7da6e6bc8f Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Mon, 16 Sep 2024 10:14:18 +0200 Subject: [PATCH 347/432] Do not hide logs for passing tests (#14421) --- .github/workflows/automation-nightly-tests.yml | 2 +- .github/workflows/on-demand-keeper-smoke-tests.yml | 2 +- .github/workflows/run-e2e-tests-reusable-workflow.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/automation-nightly-tests.yml b/.github/workflows/automation-nightly-tests.yml index 59d1172895..d73df6a8c1 100644 --- a/.github/workflows/automation-nightly-tests.yml +++ b/.github/workflows/automation-nightly-tests.yml @@ -115,7 +115,7 @@ jobs: E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} with: - test_command_to_run: cd ./integration-tests && go test -timeout 60m -count=1 -json -test.parallel=${{ matrix.tests.nodes }} ${{ matrix.tests.command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs + test_command_to_run: cd ./integration-tests && go test -timeout 60m -count=1 -json -test.parallel=${{ matrix.tests.nodes }} ${{ matrix.tests.command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false test_download_vendor_packages_command: cd ./integration-tests && go mod download cl_repo: 'public.ecr.aws/chainlink/chainlink' cl_image_tag: 'latest' diff --git a/.github/workflows/on-demand-keeper-smoke-tests.yml b/.github/workflows/on-demand-keeper-smoke-tests.yml index 23626c2c98..a0ed71c0a0 100644 --- a/.github/workflows/on-demand-keeper-smoke-tests.yml +++ b/.github/workflows/on-demand-keeper-smoke-tests.yml @@ -136,7 +136,7 @@ jobs: - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 with: - test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs + test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false test_download_vendor_packages_command: cd ./integration-tests && go mod download test_config_chainlink_version: ${{ inputs.evm-ref || github.sha }} test_config_selected_networks: ${{ env.SELECTED_NETWORKS }} diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index e7d71ee828..f32d541c3d 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -580,7 +580,7 @@ jobs: E2E_TEST_PYROSCOPE_KEY: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_KEY || '' }} E2E_TEST_PYROSCOPE_ENABLED: ${{ matrix.tests.pyroscope_env != '' && 'true' || '' }} with: - test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs + test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false test_download_vendor_packages_command: cd $(dirname ${{ matrix.tests.path }}) && go mod download test_secrets_override_base64: ${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }} test_config_override_path: ${{ env.TEST_CONFIG_OVERRIDE_PATH }} @@ -797,7 +797,7 @@ jobs: E2E_TEST_PYROSCOPE_ENABLED: ${{ matrix.tests.pyroscope_env != '' && 'true' || '' }} DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable with: - test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs + test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false test_download_vendor_packages_command: make gomod test_secrets_override_base64: ${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }} test_config_override_path: ${{ env.TEST_CONFIG_OVERRIDE_PATH }} From 530207ec8a0e346375124752f0bb5040b99201d7 Mon Sep 17 00:00:00 2001 From: Ryan <80392855+RayXpub@users.noreply.github.com> Date: Mon, 16 Sep 2024 14:08:01 +0400 Subject: [PATCH 348/432] chore: udpate comments seciton in styleguide (#14435) --- contracts/STYLE_GUIDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/STYLE_GUIDE.md b/contracts/STYLE_GUIDE.md index f29c129bd0..0f1370be3d 100644 --- a/contracts/STYLE_GUIDE.md +++ b/contracts/STYLE_GUIDE.md @@ -33,6 +33,7 @@ We will be looking into `forge fmt`, but for now, we still use `prettier`. This will help massively during audits and onboarding new team members. - Headers should be used to group functionality, the following header style and length are recommended. - Don’t use headers for a single function, or to say “getters”. Group by functionality e.g. the `Tokens and pools`, or `fees` logic within the CCIP OnRamp. +- Comments should start with a capital letter and end with a period. ```solidity // ================================================================ @@ -419,4 +420,3 @@ function setConfig(uint64 _foo, uint64 _bar, uint64 _baz) external { ``` rule: `tbd` - From a2c03fc380ca5919bf2f33f771a6efd98a6f4103 Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Mon, 16 Sep 2024 15:26:42 +0200 Subject: [PATCH 349/432] Replacing TokenDataReader with Noop impl for chainlink-ccip (#14418) --- .changeset/two-pumas-lie.md | 5 ++++ .../capabilities/ccip/oraclecreator/plugin.go | 5 ++-- .../ccip/superfakes/token_data_reader.go | 23 ------------------- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 11 files changed, 20 insertions(+), 37 deletions(-) create mode 100644 .changeset/two-pumas-lie.md delete mode 100644 core/capabilities/ccip/superfakes/token_data_reader.go diff --git a/.changeset/two-pumas-lie.md b/.changeset/two-pumas-lie.md new file mode 100644 index 0000000000..fa8231fd19 --- /dev/null +++ b/.changeset/two-pumas-lie.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Updating CCIP OCR3 integration tests according to changes in the chainlink-ccip repo #internal diff --git a/core/capabilities/ccip/oraclecreator/plugin.go b/core/capabilities/ccip/oraclecreator/plugin.go index c87c4e97c1..936b9c2552 100644 --- a/core/capabilities/ccip/oraclecreator/plugin.go +++ b/core/capabilities/ccip/oraclecreator/plugin.go @@ -8,7 +8,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccipevm" evmconfig "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/configs/evm" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ocrimpls" - "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/superfakes" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/ethereum/go-ethereum/common" @@ -30,9 +29,11 @@ import ( commitocr3 "github.com/smartcontractkit/chainlink-ccip/commit" execocr3 "github.com/smartcontractkit/chainlink-ccip/execute" + "github.com/smartcontractkit/chainlink-ccip/execute/tokendata" ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -247,7 +248,7 @@ func (i *pluginOracleCreator) createFactoryAndTransmitter( ccipevm.NewExecutePluginCodecV1(), ccipevm.NewMessageHasherV1(), i.homeChainReader, - superfakes.NewNilTokenDataReader(), + &tokendata.NoopTokenDataObserver{}, ccipevm.NewGasEstimateProvider(), contractReaders, chainWriters, diff --git a/core/capabilities/ccip/superfakes/token_data_reader.go b/core/capabilities/ccip/superfakes/token_data_reader.go deleted file mode 100644 index ff6a88076c..0000000000 --- a/core/capabilities/ccip/superfakes/token_data_reader.go +++ /dev/null @@ -1,23 +0,0 @@ -package superfakes - -import ( - "context" - - "github.com/smartcontractkit/chainlink-ccip/execute/exectypes" - "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" -) - -// NewNilTokenDataReader returns a new nilTokenDataReader. -// This token data reader always returns nil for the token data. -func NewNilTokenDataReader() exectypes.TokenDataReader { - return &nilTokenDataReader{} -} - -type nilTokenDataReader struct{} - -// ReadTokenData implements exectypes.TokenDataReader. -func (t *nilTokenDataReader) ReadTokenData(ctx context.Context, srcChain ccipocr3.ChainSelector, num ccipocr3.SeqNum) (r [][]byte, err error) { - return nil, nil -} - -var _ exectypes.TokenDataReader = (*nilTokenDataReader)(nil) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 7057264864..738ff453a4 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -271,7 +271,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index a4d9587815..aee7a44b26 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1081,8 +1081,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 h1:BPuehkAQ8R112SlTitukSdKYRJMY3zkvaQS4VSTNn0Q= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 h1:v5w6IqCX2p6pDuwmvaGv+kxvbhKgVmxnGZ63409tuj0= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/go.mod b/go.mod index e3c64fca6b..6bc724ecd8 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc diff --git a/go.sum b/go.sum index 5ee578f7b2..b58bd4c9b7 100644 --- a/go.sum +++ b/go.sum @@ -1042,8 +1042,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 h1:BPuehkAQ8R112SlTitukSdKYRJMY3zkvaQS4VSTNn0Q= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 h1:v5w6IqCX2p6pDuwmvaGv+kxvbhKgVmxnGZ63409tuj0= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 75892f6947..6816cb32ba 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -36,7 +36,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240910151738-3f318badcfb5 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index f435992ae6..a14ba3bacb 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1423,8 +1423,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 h1:BPuehkAQ8R112SlTitukSdKYRJMY3zkvaQS4VSTNn0Q= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 h1:v5w6IqCX2p6pDuwmvaGv+kxvbhKgVmxnGZ63409tuj0= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 89a1f05a46..46b82a1e1a 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -393,7 +393,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index a8a8d86d3a..7bb8abfdb0 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1397,8 +1397,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978 h1:BPuehkAQ8R112SlTitukSdKYRJMY3zkvaQS4VSTNn0Q= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240911145028-d346e3ace978/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 h1:v5w6IqCX2p6pDuwmvaGv+kxvbhKgVmxnGZ63409tuj0= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= From 7a06f5f8ebd8a98fa2d7605eb1c8cd655a5fb3dc Mon Sep 17 00:00:00 2001 From: Balamurali Gopalswami <167726375+b-gopalswami@users.noreply.github.com> Date: Mon, 16 Sep 2024 09:38:26 -0400 Subject: [PATCH 350/432] CCIP-3391:Port reorg test from CCIP (#14385) * CCIP-3391:Port reorg test from CCIP * Add reorg test to the pipeline and fix lint * Fix lint * fix override config path * Debug config override * Fix override variable name as BASE64_CONFIG_OVERRIDE * log * Override should happen before validating it * clean up the logs * Remove chainlink image --- .github/e2e-tests.yml | 38 ++++- .github/workflows/ccip-load-tests.yml | 19 +-- .../plugins/ccip/clo_ccip_integration_test.go | 22 ++- .../ocr2/plugins/ccip/integration_test.go | 81 ++++++++- .../ccip/testhelpers/ccip_contracts.go | 6 +- .../ccip/testhelpers/integration/chainlink.go | 23 ++- core/services/ocr2/plugins/ccip/vars.go | 10 +- integration-tests/ccip-tests/Makefile | 12 +- integration-tests/ccip-tests/README.md | 8 +- .../ccip-tests/actions/ccip_helpers.go | 21 ++- .../ccip-tests/actions/reorg_helpers.go | 86 ++++++++++ .../ccip-tests/smoke/ccip_test.go | 160 ++++++++++++++++++ .../ccip-tests/testconfig/README.md | 2 +- .../ccip-tests/testconfig/ccip.go | 10 ++ .../ccip-tests/testconfig/global.go | 37 ++-- .../testconfig/tomls/ccip-reorg.toml | 64 +++++++ 16 files changed, 540 insertions(+), 59 deletions(-) create mode 100644 integration-tests/ccip-tests/actions/reorg_helpers.go create mode 100644 integration-tests/ccip-tests/testconfig/tomls/ccip-reorg.toml diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 9ec19a48db..8ee5b207a8 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -1004,7 +1004,43 @@ runner-test-matrix: - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPOffRampAggRateLimit$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: - E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + + - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPReorgBelowFinality$ + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPReorgBelowFinality$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/ccip-reorg.toml + + - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPReorgAboveFinalityAtDestination$ + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPReorgAboveFinalityAtDestination$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/ccip-reorg.toml + + - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPReorgAboveFinalityAtSource$ + path: integration-tests/ccip-tests/smoke/ccip_test.go + test_env_type: docker + runs_on: ubuntu-latest + workflows: + - PR E2E CCIP Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPReorgAboveFinalityAtSource$ -timeout 30m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/ccip-reorg.toml - id: ccip-tests/chaos/ccip_test.go path: integration-tests/ccip-tests/chaos/ccip_test.go diff --git a/.github/workflows/ccip-load-tests.yml b/.github/workflows/ccip-load-tests.yml index 93f18a3531..ec65c2af10 100644 --- a/.github/workflows/ccip-load-tests.yml +++ b/.github/workflows/ccip-load-tests.yml @@ -157,14 +157,14 @@ jobs: run: | # if the matrix.type.config_path is set, use it as the override config if [ -n "${{ matrix.type.config_path }}" ]; then - BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -w 0 -i ${{ matrix.type.config_path }}) - echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE - echo "base_64_override=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_OUTPUT + BASE64_CONFIG_OVERRIDE=$(base64 -w 0 -i ${{ matrix.type.config_path }}) + echo ::add-mask::$BASE64_CONFIG_OVERRIDE + echo "base_64_override=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_OUTPUT fi if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then - BASE64_CCIP_CONFIG_OVERRIDE=$(jq -r '.inputs.base64_test_input' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CCIP_CONFIG_OVERRIDE - echo "base_64_override=$BASE64_CCIP_CONFIG_OVERRIDE" >> $GITHUB_OUTPUT + BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64_test_input' $GITHUB_EVENT_PATH) + echo ::add-mask::$BASE64_CONFIG_OVERRIDE + echo "base_64_override=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_OUTPUT fi - name: step summary shell: bash @@ -190,9 +190,8 @@ jobs: RR_MEM: 8Gi RR_CPU: 4 TEST_TRIGGERED_BY: ccip-load-test-ci-${{ matrix.type.name }} - BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.set_override_config.outputs.base_64_override }},${{ steps.setup_create_base64_config_ccip.outputs.base64_config }} - TEST_BASE64_CCIP_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }},${{ steps.set_override_config.outputs.base_64_override }} - E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} + BASE64_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }},${{ steps.set_override_config.outputs.base_64_override }} + TEST_BASE64_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }},${{ steps.set_override_config.outputs.base_64_override }} E2E_TEST_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} E2E_TEST_CHAINLINK_VERSION: ${{ env.CHAINLINK_VERSION }} E2E_TEST_LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} @@ -300,4 +299,4 @@ jobs: slack_bot_token: ${{ secrets.QA_SLACK_API_KEY }} slack_thread_ts: ${{ needs.start-slack-thread.outputs.thread_ts }} - # End Reporting Jobs + # End Reporting Jobs \ No newline at end of file diff --git a/core/services/ocr2/plugins/ccip/clo_ccip_integration_test.go b/core/services/ocr2/plugins/ccip/clo_ccip_integration_test.go index 2fddd58ac8..0a7594324b 100644 --- a/core/services/ocr2/plugins/ccip/clo_ccip_integration_test.go +++ b/core/services/ocr2/plugins/ccip/clo_ccip_integration_test.go @@ -6,6 +6,8 @@ import ( "math/big" "testing" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" @@ -20,7 +22,15 @@ import ( ) func Test_CLOSpecApprovalFlow_pipeline(t *testing.T) { - ccipTH := integrationtesthelpers.SetupCCIPIntegrationTH(t, testhelpers.SourceChainID, testhelpers.SourceChainSelector, testhelpers.DestChainID, testhelpers.DestChainSelector) + ccipTH := integrationtesthelpers.SetupCCIPIntegrationTH( + t, + testhelpers.SourceChainID, + testhelpers.SourceChainSelector, + testhelpers.DestChainID, + testhelpers.DestChainSelector, + ccip.DefaultSourceFinalityDepth, + ccip.DefaultDestFinalityDepth, + ) tokenPricesUSDPipeline, linkUSD, ethUSD := ccipTH.CreatePricesPipeline(t) defer linkUSD.Close() @@ -30,7 +40,15 @@ func Test_CLOSpecApprovalFlow_pipeline(t *testing.T) { } func Test_CLOSpecApprovalFlow_dynamicPriceGetter(t *testing.T) { - ccipTH := integrationtesthelpers.SetupCCIPIntegrationTH(t, testhelpers.SourceChainID, testhelpers.SourceChainSelector, testhelpers.DestChainID, testhelpers.DestChainSelector) + ccipTH := integrationtesthelpers.SetupCCIPIntegrationTH( + t, + testhelpers.SourceChainID, + testhelpers.SourceChainSelector, + testhelpers.DestChainID, + testhelpers.DestChainSelector, + ccip.DefaultSourceFinalityDepth, + ccip.DefaultDestFinalityDepth, + ) //Set up the aggregators here to avoid modifying ccipTH. dstLinkAddr := ccipTH.Dest.LinkToken.Address() diff --git a/core/services/ocr2/plugins/ccip/integration_test.go b/core/services/ocr2/plugins/ccip/integration_test.go index bfd270fb66..d14de4e0ab 100644 --- a/core/services/ocr2/plugins/ccip/integration_test.go +++ b/core/services/ocr2/plugins/ccip/integration_test.go @@ -9,6 +9,9 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + "github.com/ethereum/go-ethereum/common" gethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/assert" @@ -46,7 +49,15 @@ func TestIntegration_CCIP(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - ccipTH := integrationtesthelpers.SetupCCIPIntegrationTH(t, testhelpers.SourceChainID, testhelpers.SourceChainSelector, testhelpers.DestChainID, testhelpers.DestChainSelector) + ccipTH := integrationtesthelpers.SetupCCIPIntegrationTH( + t, + testhelpers.SourceChainID, + testhelpers.SourceChainSelector, + testhelpers.DestChainID, + testhelpers.DestChainSelector, + ccip.DefaultSourceFinalityDepth, + ccip.DefaultDestFinalityDepth, + ) tokenPricesUSDPipeline := "" priceGetterConfigJson := "" @@ -629,3 +640,71 @@ func TestIntegration_CCIP(t *testing.T) { }) } } + +// TestReorg ensures that CCIP works even when a below finality depth reorg happens +func TestReorg(t *testing.T) { + // We need higher finality depth on the destination to perform reorg deep enough to revert commit and execution reports + destinationFinalityDepth := uint32(50) + ccipTH := integrationtesthelpers.SetupCCIPIntegrationTH( + t, + testhelpers.SourceChainID, + testhelpers.SourceChainSelector, + testhelpers.DestChainID, + testhelpers.DestChainSelector, + ccip.DefaultSourceFinalityDepth, + destinationFinalityDepth, + ) + testPricePipeline, linkUSD, ethUSD := ccipTH.CreatePricesPipeline(t) + defer linkUSD.Close() + defer ethUSD.Close() + ccipTH.SetUpNodesAndJobs(t, testPricePipeline, "", "") + + gasLimit := big.NewInt(200_00) + tokenAmount := big.NewInt(1) + + forkBlock, err := ccipTH.Dest.Chain.BlockByNumber(context.Background(), nil) + require.NoError(t, err, "Error while fetching the destination chain current block number") + + // Adjust time to start next blocks with timestamps two hours after the fork block. + // This is critical to have two forks with different block_timestamps. + err = ccipTH.Dest.Chain.AdjustTime(2 * time.Hour) + require.NoError(t, err, "Error while adjusting the destination chain time") + ccipTH.Dest.Chain.Commit() + + // Send request for the first time and make sure it's executed on the destination + ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) + ccipTH.Dest.User.GasLimit = 100000 + ccipTH.EventuallySendRequested(t, uint64(1)) + ccipTH.EventuallyReportCommitted(t, 1) + executionLog := ccipTH.AllNodesHaveExecutedSeqNums(t, 1, 1) + ccipTH.AssertExecState(t, executionLog[0], testhelpers.ExecutionStateSuccess) + + currentBlock, err := ccipTH.Dest.Chain.BlockByNumber(context.Background(), nil) + require.NoError(t, err, "Error while fetching the current block number of destination chain") + + // Reorg back to the `forkBlock`. Next blocks in the fork will have block_timestamps right after the fork, + // but before the 2 hours interval defined above for the canonical chain + require.NoError(t, ccipTH.Dest.Chain.Fork(testutils.Context(t), forkBlock.Hash()), + "Error while forking the chain") + // Make sure that fork is longer than the canonical chain to enforce switch + noOfBlocks := uint(currentBlock.NumberU64() - forkBlock.NumberU64()) + for i := uint(0); i < noOfBlocks+1; i++ { + ccipTH.Dest.Chain.Commit() + } + + // State of the chain (block_timestamps) after reorg: + // / --> block1 (02:01) --> block2 (02:02) --> commit report (02:03) --> ... + // forkBlock (00:00) --> block1' (00:01) --> block2' (00:02) --> commit report' (00:03) --> ... + + // CCIP should commit and executed messages that was reorged away + ccipTH.EventuallyReportCommitted(t, 1) + executionLog = ccipTH.AllNodesHaveExecutedSeqNums(t, 1, 1) + ccipTH.AssertExecState(t, executionLog[0], testhelpers.ExecutionStateSuccess) + + // Sending another message and make sure it's executed on the destination + ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) + ccipTH.EventuallySendRequested(t, uint64(2)) + ccipTH.EventuallyReportCommitted(t, 2) + executionLog = ccipTH.AllNodesHaveExecutedSeqNums(t, 1, 2) + ccipTH.AssertExecState(t, executionLog[0], testhelpers.ExecutionStateSuccess) +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go index e1aed59053..7b3351ce06 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -179,6 +179,7 @@ type Common struct { ARMProxy *rmn_proxy_contract.RMNProxyContract PriceRegistry *price_registry_1_2_0.PriceRegistry TokenAdminRegistry *token_admin_registry.TokenAdminRegistry + FinalityDepth uint32 } type SourceChain struct { @@ -652,7 +653,8 @@ func SetAdminAndRegisterPool(t *testing.T, chain.Commit() } -func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destChainID, destChainSelector uint64) CCIPContracts { +func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destChainID, destChainSelector uint64, + sourceFinalityDepth, destFinalityDepth uint32) CCIPContracts { sourceChain, sourceUser := SetupChain(t) destChain, destUser := SetupChain(t) @@ -1177,6 +1179,7 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh WrappedNative: sourceWrapped, WrappedNativePool: sourceWeth9Pool, TokenAdminRegistry: sourceTokenAdminRegistry, + FinalityDepth: sourceFinalityDepth, }, Router: sourceRouter, OnRamp: onRamp, @@ -1196,6 +1199,7 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh WrappedNative: destWrapped, WrappedNativePool: destWrappedPool, TokenAdminRegistry: destTokenAdminRegistry, + FinalityDepth: destFinalityDepth, }, CommitStoreHelper: commitStoreHelper, CommitStore: commitStore, diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go index cecf99353c..d34241a2d0 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go @@ -371,6 +371,7 @@ func setupNodeCCIP( sourceChainID *big.Int, destChainID *big.Int, bootstrapPeerID string, bootstrapPort int64, + sourceFinalityDepth, destFinalityDepth uint32, ) (chainlink.Application, string, common.Address, ocr2key.KeyBundle) { trueRef, falseRef := true, false @@ -404,7 +405,7 @@ func setupNodeCCIP( c.P2P.V2.ListenAddresses = &p2pAddresses c.P2P.V2.AnnounceAddresses = &p2pAddresses - c.EVM = []*v2.EVMConfig{createConfigV2Chain(sourceChainID), createConfigV2Chain(destChainID)} + c.EVM = []*v2.EVMConfig{createConfigV2Chain(sourceChainID, sourceFinalityDepth), createConfigV2Chain(destChainID, destFinalityDepth)} if bootstrapPeerID != "" { // Supply the bootstrap IP and port as a V2 peer address @@ -526,21 +527,20 @@ func setupNodeCCIP( return app, peerID.Raw(), transmitter, kb } -func createConfigV2Chain(chainId *big.Int) *v2.EVMConfig { +func createConfigV2Chain(chainID *big.Int, finalityDepth uint32) *v2.EVMConfig { // NOTE: For the executor jobs, the default of 500k is insufficient for a 3 message batch defaultGasLimit := uint64(5000000) tr := true - sourceC := v2.Defaults((*evmUtils.Big)(chainId)) + sourceC := v2.Defaults((*evmUtils.Big)(chainID)) sourceC.GasEstimator.LimitDefault = &defaultGasLimit fixedPrice := "FixedPrice" sourceC.GasEstimator.Mode = &fixedPrice d, _ := config.NewDuration(100 * time.Millisecond) sourceC.LogPollInterval = &d - fd := uint32(2) - sourceC.FinalityDepth = &fd + sourceC.FinalityDepth = &finalityDepth return &v2.EVMConfig{ - ChainID: (*evmUtils.Big)(chainId), + ChainID: (*evmUtils.Big)(chainID), Enabled: &tr, Chain: sourceC, Nodes: v2.EVMNodes{&v2.Node{}}, @@ -553,9 +553,11 @@ type CCIPIntegrationTestHarness struct { Bootstrap Node } -func SetupCCIPIntegrationTH(t *testing.T, sourceChainID, sourceChainSelector, destChainId, destChainSelector uint64) CCIPIntegrationTestHarness { +func SetupCCIPIntegrationTH(t *testing.T, sourceChainID, sourceChainSelector, destChainID, destChainSelector uint64, + sourceFinalityDepth, destFinalityDepth uint32) CCIPIntegrationTestHarness { return CCIPIntegrationTestHarness{ - CCIPContracts: testhelpers.SetupCCIPContracts(t, sourceChainID, sourceChainSelector, destChainId, destChainSelector), + CCIPContracts: testhelpers.SetupCCIPContracts(t, sourceChainID, sourceChainSelector, destChainID, + destChainSelector, sourceFinalityDepth, destFinalityDepth), } } @@ -928,7 +930,8 @@ func (c *CCIPIntegrationTestHarness) ConsistentlyReportNotCommitted(t *testing.T func (c *CCIPIntegrationTestHarness) SetupAndStartNodes(ctx context.Context, t *testing.T, bootstrapNodePort int64) (Node, []Node, int64) { appBootstrap, bootstrapPeerID, bootstrapTransmitter, bootstrapKb := setupNodeCCIP(t, c.Dest.User, bootstrapNodePort, "bootstrap_ccip", c.Source.Chain, c.Dest.Chain, big.NewInt(0).SetUint64(c.Source.ChainID), - big.NewInt(0).SetUint64(c.Dest.ChainID), "", 0) + big.NewInt(0).SetUint64(c.Dest.ChainID), "", 0, c.Source.FinalityDepth, + c.Dest.FinalityDepth) var ( oracles []confighelper.OracleIdentityExtra nodes []Node @@ -956,6 +959,8 @@ func (c *CCIPIntegrationTestHarness) SetupAndStartNodes(ctx context.Context, t * big.NewInt(0).SetUint64(c.Dest.ChainID), bootstrapPeerID, bootstrapNodePort, + c.Source.FinalityDepth, + c.Dest.FinalityDepth, ) nodes = append(nodes, Node{ App: app, diff --git a/core/services/ocr2/plugins/ccip/vars.go b/core/services/ocr2/plugins/ccip/vars.go index a44f5e41d6..82309ef783 100644 --- a/core/services/ocr2/plugins/ccip/vars.go +++ b/core/services/ocr2/plugins/ccip/vars.go @@ -5,10 +5,12 @@ import ( ) const ( - MaxQueryLength = 0 // empty for both plugins - MaxObservationLength = 250_000 // plugins's Observation should make sure to cap to this limit - CommitPluginLabel = "commit" - ExecPluginLabel = "exec" + MaxQueryLength = 0 // empty for both plugins + MaxObservationLength = 250_000 // plugins's Observation should make sure to cap to this limit + CommitPluginLabel = "commit" + ExecPluginLabel = "exec" + DefaultSourceFinalityDepth = uint32(2) + DefaultDestFinalityDepth = uint32(2) ) var ErrChainIsNotHealthy = errors.New("lane processing is stopped because of healthcheck failure, please see crit logs") diff --git a/integration-tests/ccip-tests/Makefile b/integration-tests/ccip-tests/Makefile index d33d956915..2702c36b02 100644 --- a/integration-tests/ccip-tests/Makefile +++ b/integration-tests/ccip-tests/Makefile @@ -4,10 +4,10 @@ set_config: if [ -s "$(override_toml)" ]; then \ echo "Overriding config with $(override_toml)"; \ - echo "export BASE64_CCIP_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" > ./testconfig/override/.env; \ - echo "export TEST_BASE64_CCIP_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" >> ./testconfig/override/.env; \ - echo "BASE64_CCIP_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" > ./testconfig/override/debug.env; \ - echo "TEST_BASE64_CCIP_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" >> ./testconfig/override/debug.env; \ + echo "export BASE64_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" > ./testconfig/override/.env; \ + echo "export TEST_BASE64_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" >> ./testconfig/override/.env; \ + echo "BASE64_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" > ./testconfig/override/debug.env; \ + echo "TEST_BASE64_CONFIG_OVERRIDE=$$(base64 -i $(override_toml))" >> ./testconfig/override/debug.env; \ else \ echo "No override config found, using default config"; \ echo > ./testconfig/override/.env; \ @@ -56,8 +56,8 @@ test_smoke_ccip: set_config test_smoke_ccip_default: set_config source ./testconfig/override/.env && \ DATABASE_URL=postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable \ - BASE64_CCIP_CONFIG_OVERRIDE="" \ - TEST_BASE64_CCIP_CONFIG_OVERRIDE="" \ + BASE64_CONFIG_OVERRIDE="" \ + TEST_BASE64_CONFIG_OVERRIDE="" \ ENV_JOB_IMAGE="" \ TEST_SUITE=smoke \ TEST_ARGS="-test.timeout 900h" \ diff --git a/integration-tests/ccip-tests/README.md b/integration-tests/ccip-tests/README.md index f7182338f7..1abca8552b 100644 --- a/integration-tests/ccip-tests/README.md +++ b/integration-tests/ccip-tests/README.md @@ -8,7 +8,7 @@ CCIP tests are designed to be highly configurable. Instead of writing many tests 1. Default test input - set via TOML - If no specific input is set; the tests will run with default inputs mentioned in [default.toml](./testconfig/tomls/ccip-default.toml). Please refer to the [testconfig README](../testconfig/README.md) for a more detailed look at how testconfig works. -2. If you want to run your test with a different config, you can override the default inputs. You can either write an [overrides.toml](../testconfig/README.md#configuration-and-overrides) file, or set the env var `BASE64_CCIP_CONFIG_OVERRIDE` containing the base64 encoded TOML file content with updated test input parameters. +2. If you want to run your test with a different config, you can override the default inputs. You can either write an [overrides.toml](../testconfig/README.md#configuration-and-overrides) file, or set the env var `BASE64_CONFIG_OVERRIDE` containing the base64 encoded TOML file content with updated test input parameters. For example, if you want to override the `Network` input in test and want to run your test on `avalanche testnet` and `arbitrum goerli` network, you need to: 1. Create a TOML file with the following content: @@ -20,10 +20,10 @@ For example, if you want to override the `Network` input in test and want to run ``` 2. Encode it using the `base64` command - 3. Set the env var `BASE64_CCIP_CONFIG_OVERRIDE` with the encoded content. + 3. Set the env var `BASE64_CONFIG_OVERRIDE` with the encoded content. ```bash - export BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -i ) + export BASE64_CONFIG_OVERRIDE=$(base64 -i ) ``` [mainnet.toml](./testconfig/override/mainnet.toml), [override.toml](./testconfig/examples/override.toml.example) are some of the sample override TOML files. @@ -31,7 +31,7 @@ For example, if you want to override the `Network` input in test and want to run For example - In order to run the smoke test (TestSmokeCCIPForBidirectionalLane) on mainnet, run the test with following env var set: ```bash - export BASE64_CCIP_CONFIG_OVERRIDE=$(base64 -i ./testconfig/override/mainnet.toml) + export BASE64_CONFIG_OVERRIDE=$(base64 -i ./testconfig/override/mainnet.toml) ``` 3. Secrets - You also need to set some secrets. This is a mandatory step needed to run the tests. Please refer to [.testsecrets.example](./examples/.testsecrets.example) for the list of secrets and instruction how to set them up. diff --git a/integration-tests/ccip-tests/actions/ccip_helpers.go b/integration-tests/ccip-tests/actions/ccip_helpers.go index 9ff12e6f33..429751e169 100644 --- a/integration-tests/ccip-tests/actions/ccip_helpers.go +++ b/integration-tests/ccip-tests/actions/ccip_helpers.go @@ -3046,6 +3046,7 @@ func (lane *CCIPLane) ExecuteManually(options ...ManualExecutionOption) error { // validationOptions are used in the ValidateRequests function to specify which phase is expected to fail and how type validationOptions struct { + expectAnyPhaseToFail bool phaseExpectedToFail testreporters.Phase // the phase expected to fail expectedErrorMessage string // if provided, we're looking for a specific error message timeout time.Duration // timeout for the validation @@ -3087,6 +3088,18 @@ func ExpectPhaseToFail(phase testreporters.Phase, phaseSpecificOptions ...PhaseS } } +// ExpectAnyPhaseToFail expects any phase in CCIP transaction to fail. +func ExpectAnyPhaseToFail(phaseSpecificOptions ...PhaseSpecificValidationOptionFunc) ValidationOptionFunc { + return func(opts *validationOptions) { + opts.expectAnyPhaseToFail = true + for _, f := range phaseSpecificOptions { + if f != nil { + f(opts) + } + } + } +} + // ValidateRequests validates all sent request events. // If you expect a specific phase to fail, you can pass a validationOptionFunc to specify exactly which one. // If not, just pass in nil. @@ -3210,6 +3223,11 @@ func isPhaseValid( opts validationOptions, err error, ) (shouldComplete bool, validationError error) { + if opts.expectAnyPhaseToFail && err != nil { + logmsg := logger.Info().Str("Failed with Error", err.Error()).Str("Phase", string(currentPhase)) + logmsg.Msg("Phase failed, as expected") + return true, nil + } // If no phase is expected to fail or the current phase is not the one expected to fail, we just return what we were given if opts.phaseExpectedToFail == "" || currentPhase != opts.phaseExpectedToFail { return err != nil, err @@ -3218,13 +3236,14 @@ func isPhaseValid( return true, fmt.Errorf("expected phase '%s' to fail, but it passed", opts.phaseExpectedToFail) } logmsg := logger.Info().Str("Failed with Error", err.Error()).Str("Phase", string(currentPhase)) + if opts.expectedErrorMessage != "" { if !strings.Contains(err.Error(), opts.expectedErrorMessage) { return true, fmt.Errorf("expected phase '%s' to fail with error message '%s' but got error '%s'", currentPhase, opts.expectedErrorMessage, err.Error()) } logmsg.Str("Expected Error Message", opts.expectedErrorMessage) } - logmsg.Msg("Expected phase to fail and it did") + logmsg.Msg("Phase failed, as expected") return true, nil } diff --git a/integration-tests/ccip-tests/actions/reorg_helpers.go b/integration-tests/ccip-tests/actions/reorg_helpers.go new file mode 100644 index 0000000000..017b8ffab6 --- /dev/null +++ b/integration-tests/ccip-tests/actions/reorg_helpers.go @@ -0,0 +1,86 @@ +package actions + +import ( + "fmt" + "testing" + "time" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink-testing-framework/lib/client" +) + +// ReorgSuite is a test suite that generates reorgs on source/dest chains +type ReorgSuite struct { + t *testing.T + Cfg *ReorgConfig + Logger *zerolog.Logger + SrcClient *client.RPCClient + DstClient *client.RPCClient +} + +// ReorgConfig is a configuration for reorg tests +type ReorgConfig struct { + // SrcGethHTTPURL source chain Geth HTTP URL + SrcGethHTTPURL string + // DstGethHTTPURL dest chain Geth HTTP URL + DstGethHTTPURL string + // SrcFinalityDepth source chain finality depth + SrcFinalityDepth uint64 + // DstGethHTTPURL dest chain finality depth + DstFinalityDepth uint64 + // FinalityDelta blocks to rewind below or above finality + FinalityDelta int +} + +// Validate validates ReorgConfig params +func (rc *ReorgConfig) Validate() error { + if rc.FinalityDelta >= int(rc.SrcFinalityDepth) || rc.FinalityDelta >= int(rc.DstFinalityDepth) { + return fmt.Errorf( + "finality delta can't be higher than source or dest chain finality, delta: %d, src: %d, dst: %d", + rc.FinalityDelta, rc.SrcFinalityDepth, rc.DstFinalityDepth, + ) + } + return nil +} + +// NewReorgSuite creates new reorg suite with source/dest RPC clients, works only with Geth +func NewReorgSuite(t *testing.T, lggr *zerolog.Logger, cfg *ReorgConfig) (*ReorgSuite, error) { + if err := cfg.Validate(); err != nil { + return nil, err + } + return &ReorgSuite{ + t: t, + Cfg: cfg, + Logger: lggr, + SrcClient: client.NewRPCClient(cfg.SrcGethHTTPURL, nil), + DstClient: client.NewRPCClient(cfg.DstGethHTTPURL, nil), + }, nil +} + +// RunReorg rollbacks given chain, for N blocks back +func (r *ReorgSuite) RunReorg(client *client.RPCClient, blocksBack int, network string, startDelay time.Duration) { + go func() { + time.Sleep(startDelay) + r.Logger.Info(). + Str("Network", network). + Str("URL", client.URL). + Int("BlocksBack", blocksBack). + Msg(fmt.Sprintf("Rewinding blocks on %s chain", network)) + blockNumber, err := client.BlockNumber() + assert.NoError(r.t, err, "error getting block number") + r.Logger.Info(). + Int64("Number", blockNumber). + Str("Network", network). + Msg("Block number before rewinding") + err = client.GethSetHead(blocksBack) + assert.NoError(r.t, err, "error setting block head") + blockNumber, err = client.BlockNumber() + assert.NoError(r.t, err, "error getting block number") + r.Logger.Info(). + Int64("Number", blockNumber). + Str("Network", network). + Msg("Block number after rewinding") + }() +} diff --git a/integration-tests/ccip-tests/smoke/ccip_test.go b/integration-tests/ccip-tests/smoke/ccip_test.go index db6972c9e7..0ed7f60dd3 100644 --- a/integration-tests/ccip-tests/smoke/ccip_test.go +++ b/integration-tests/ccip-tests/smoke/ccip_test.go @@ -6,6 +6,9 @@ import ( "testing" "time" + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/AlekSi/pointer" "github.com/stretchr/testify/require" @@ -855,6 +858,130 @@ func TestSmokeCCIPManuallyExecuteAfterExecutionFailingDueToInsufficientGas(t *te } } +// Test expects to generate below finality reorg in both source and destination and +// expect CCIP transactions to go through successful. +func TestSmokeCCIPReorgBelowFinality(t *testing.T) { + t.Parallel() + log := logging.GetTestLogger(t) + TestCfg := testsetups.NewCCIPTestConfig(t, log, testconfig.Smoke) + gasLimit := big.NewInt(*TestCfg.TestGroupInput.MsgDetails.DestGasLimit) + setUpOutput := testsetups.CCIPDefaultTestSetUp(t, &log, "smoke-ccip", nil, TestCfg) + require.False(t, len(setUpOutput.Lanes) == 0, "No lanes found.") + t.Cleanup(func() { + require.NoError(t, setUpOutput.TearDown()) + }) + + lane := setUpOutput.Lanes[0].ForwardLane + log.Info(). + Str("Source", lane.SourceNetworkName). + Str("Destination", lane.DestNetworkName). + Msg("Starting CCIP reorg test") + t.Run(fmt.Sprintf("CCIP reorg below finality test from network %s to network %s", + lane.SourceNetworkName, lane.DestNetworkName), func(t *testing.T) { + t.Parallel() + lane.Test = t + lane.RecordStateBeforeTransfer() + // sending multiple request and expect all should go through though there is below finality reorg + err := lane.SendRequests(5, gasLimit) + require.NoError(t, err, "Send requests failed") + rs := SetupReorgSuite(t, &log, setUpOutput) + // run below finality reorg in both source and destination chain + blocksBackSrc := int(rs.Cfg.SrcFinalityDepth) - rs.Cfg.FinalityDelta + blocksBackDst := int(rs.Cfg.DstFinalityDepth) - rs.Cfg.FinalityDelta + rs.RunReorg(rs.DstClient, blocksBackSrc, "Source", 2*time.Second) + rs.RunReorg(rs.DstClient, blocksBackDst, "Destination", 2*time.Second) + time.Sleep(1 * time.Minute) + lane.ValidateRequests() + }) +} + +// Test creates above finality reorg at destination and +// expects ccip transactions in-flight and the one initiated after reorg +// doesn't go through and verifies every node is able to detect reorg. +// Note: LogPollInterval interval is set as 1s to detect the reorg immediately +func TestSmokeCCIPReorgAboveFinalityAtDestination(t *testing.T) { + t.Parallel() + t.Run("Above finality reorg in destination chain", func(t *testing.T) { + performAboveFinalityReorgAndValidate(t, "Destination") + }) +} + +// Test creates above finality reorg at destination and +// expects ccip transactions in-flight doesn't go through, the transaction initiated after reorg +// shouldn't even get initiated and verifies every node is able to detect reorg. +// Note: LogPollInterval interval is set as 1s to detect the reorg immediately +func TestSmokeCCIPReorgAboveFinalityAtSource(t *testing.T) { + t.Parallel() + t.Run("Above finality reorg in source chain", func(t *testing.T) { + performAboveFinalityReorgAndValidate(t, "Source") + }) +} + +// performAboveFinalityReorgAndValidate is to perform the above finality reorg test +func performAboveFinalityReorgAndValidate(t *testing.T, network string) { + t.Helper() + + log := logging.GetTestLogger(t) + TestCfg := testsetups.NewCCIPTestConfig(t, log, testconfig.Smoke) + gasLimit := big.NewInt(*TestCfg.TestGroupInput.MsgDetails.DestGasLimit) + setUpOutput := testsetups.CCIPDefaultTestSetUp(t, &log, "smoke-ccip", nil, TestCfg) + require.False(t, len(setUpOutput.Lanes) == 0, "No lanes found.") + t.Cleanup(func() { + require.NoError(t, setUpOutput.TearDown()) + }) + rs := SetupReorgSuite(t, &log, setUpOutput) + lane := setUpOutput.Lanes[0].ForwardLane + log.Info(). + Str("Source", lane.SourceNetworkName). + Str("Destination", lane.DestNetworkName). + Msg("Starting ccip reorg test") + lane.Test = t + lane.RecordStateBeforeTransfer() + err := lane.SendRequests(1, gasLimit) + require.NoError(t, err, "Send requests failed") + logPollerName := "" + if network == "Destination" { + logPollerName = fmt.Sprintf("EVM.%d.LogPoller", lane.DestChain.GetChainID()) + rs.RunReorg(rs.DstClient, int(rs.Cfg.DstFinalityDepth)+rs.Cfg.FinalityDelta, network, 2*time.Second) + } else { + logPollerName = fmt.Sprintf("EVM.%d.LogPoller", lane.SourceChain.GetChainID()) + rs.RunReorg(rs.SrcClient, int(rs.Cfg.SrcFinalityDepth)+rs.Cfg.FinalityDelta, network, 2*time.Second) + } + clNodes := setUpOutput.Env.CLNodes + // assert every node is detecting the reorg (LogPollInterval is set as 1s for faster detection) + nodesDetectedViolation := make(map[string]bool) + assert.Eventually(t, func() bool { + for _, node := range clNodes { + if _, ok := nodesDetectedViolation[node.ChainlinkClient.URL()]; ok { + continue + } + resp, _, err := node.Health() + require.NoError(t, err) + for _, d := range resp.Data { + if d.Attributes.Name == logPollerName && d.Attributes.Output == "finality violated" && d.Attributes.Status == "failing" { + log.Debug().Msg("Finality violated is detected by node") + nodesDetectedViolation[node.ChainlinkClient.URL()] = true + } + } + } + return len(nodesDetectedViolation) == len(clNodes) + }, 3*time.Minute, 20*time.Second, "Reorg above finality depth is not detected by every node") + log.Debug().Interface("Nodes", nodesDetectedViolation).Msg("Violation detection details") + // send another request and verify it fails + err = lane.SendRequests(1, gasLimit) + if network == "Source" { + // if it is source chain reorg, the transaction will not even be initiated + require.Error(t, err, + "CCIP send transaction shouldn't be initiated as there is above finality depth reorg in source chain") + } else { + // if it is destination chain reorg, the transaction will be initiated and will fail in the process + require.NoError(t, err, + "CCIP send transaction should be initiated even when there above finality reorg in dest chain") + } + + lane.ValidateRequests(actions.ExpectAnyPhaseToFail(actions.WithTimeout(time.Minute))) +} + // add liquidity to pools on both networks func addLiquidity(t *testing.T, ccipCommon *actions.CCIPCommon, amount *big.Int) { t.Helper() @@ -1005,3 +1132,36 @@ func testOffRampRateLimits(t *testing.T, rateLimiterConfig contracts.RateLimiter }) } } + +// SetupReorgSuite defines the setup required to perform re-org step +func SetupReorgSuite(t *testing.T, lggr *zerolog.Logger, setupOutput *testsetups.CCIPTestSetUpOutputs) *actions.ReorgSuite { + var finalitySrc uint64 + var finalityDst uint64 + if setupOutput.Cfg.SelectedNetworks[0].FinalityTag { + finalitySrc = 10 + } else { + finalitySrc = setupOutput.Cfg.SelectedNetworks[0].FinalityDepth + } + if setupOutput.Cfg.SelectedNetworks[1].FinalityTag { + finalityDst = 10 + } else { + finalityDst = setupOutput.Cfg.SelectedNetworks[1].FinalityDepth + } + var srcGethHTTPURL, dstGethHTTPURL string + if setupOutput.Env.LocalCluster != nil { + srcGethHTTPURL = setupOutput.Env.LocalCluster.EVMNetworks[0].HTTPURLs[0] + dstGethHTTPURL = setupOutput.Env.LocalCluster.EVMNetworks[1].HTTPURLs[0] + } else { + srcGethHTTPURL = setupOutput.Env.K8Env.URLs["source-chain_http"][0] + dstGethHTTPURL = setupOutput.Env.K8Env.URLs["dest-chain_http"][0] + } + rs, err := actions.NewReorgSuite(t, lggr, &actions.ReorgConfig{ + SrcGethHTTPURL: srcGethHTTPURL, + DstGethHTTPURL: dstGethHTTPURL, + SrcFinalityDepth: finalitySrc, + DstFinalityDepth: finalityDst, + FinalityDelta: setupOutput.Cfg.TestGroupInput.ReorgProfile.FinalityDelta, + }) + require.NoError(t, err) + return rs +} diff --git a/integration-tests/ccip-tests/testconfig/README.md b/integration-tests/ccip-tests/testconfig/README.md index 51009e49a2..d464ae247f 100644 --- a/integration-tests/ccip-tests/testconfig/README.md +++ b/integration-tests/ccip-tests/testconfig/README.md @@ -6,7 +6,7 @@ The test config is read in following order: - The test reads the default configuration from [ccip-default.toml](./tomls/ccip-default.toml). - The default can be overridden by specifying the test config in a separate file. - - The file content needs to be encoded in base64 format and set in `BASE64_CCIP_CONFIG_OVERRIDE` environment variable. + - The file content needs to be encoded in base64 format and set in `BASE64_CONFIG_OVERRIDE` environment variable. - The config mentioned in this file will override the default config. - Example override file - [override.toml.example](./examples/override.toml.example) - If there are sensitive details like private keys, credentials in test config, they can be specified in a separate dotenv file as env vars diff --git a/integration-tests/ccip-tests/testconfig/ccip.go b/integration-tests/ccip-tests/testconfig/ccip.go index f267669732..19ebd304ce 100644 --- a/integration-tests/ccip-tests/testconfig/ccip.go +++ b/integration-tests/ccip-tests/testconfig/ccip.go @@ -251,6 +251,15 @@ func (l *LoadProfile) SetTestRunName(name string) { } } +type ReorgProfile struct { + FinalityDelta int `toml:",omitempty"` +} + +func (gp *ReorgProfile) Validate() error { + // FinalityDelta can be validated only relatively to CL nodes settings, see setupReorgSuite method + return nil +} + // CCIPTestGroupConfig defines configuration input to change how a particular CCIP test group should run type CCIPTestGroupConfig struct { Type string `toml:",omitempty"` @@ -280,6 +289,7 @@ type CCIPTestGroupConfig struct { CommitInflightExpiry *config.Duration `toml:",omitempty"` StoreLaneConfig *bool `toml:",omitempty"` LoadProfile *LoadProfile `toml:",omitempty"` + ReorgProfile *ReorgProfile `toml:",omitempty"` } func (c *CCIPTestGroupConfig) Validate() error { diff --git a/integration-tests/ccip-tests/testconfig/global.go b/integration-tests/ccip-tests/testconfig/global.go index c5b4a91fc0..d2b3f599b1 100644 --- a/integration-tests/ccip-tests/testconfig/global.go +++ b/integration-tests/ccip-tests/testconfig/global.go @@ -29,8 +29,7 @@ import ( ) const ( - OVERIDECONFIG = "BASE64_CCIP_CONFIG_OVERRIDE" - + OVERIDECONFIG = "BASE64_CONFIG_OVERRIDE" ErrReadConfig = "failed to read TOML config" ErrUnmarshalConfig = "failed to unmarshal TOML config" Load string = "load" @@ -113,23 +112,6 @@ func NewConfig() (*Config, error) { return nil, errors.Wrap(err, ErrReadConfig) } - // read secrets for all products - if cfg.CCIP != nil { - err := ctfconfig.LoadSecretEnvsFromFiles() - if err != nil { - return nil, errors.Wrap(err, "error loading testsecrets files") - } - err = cfg.CCIP.LoadFromEnv() - if err != nil { - return nil, errors.Wrap(err, "error loading env vars into CCIP config") - } - // validate all products - err = cfg.CCIP.Validate() - if err != nil { - return nil, err - } - } - // load config overrides from env var if specified // there can be multiple overrides separated by comma rawConfigs, _ := osutil.GetEnv(OVERIDECONFIG) @@ -155,6 +137,23 @@ func NewConfig() (*Config, error) { } } + // read secrets for all products + if cfg.CCIP != nil { + err := ctfconfig.LoadSecretEnvsFromFiles() + if err != nil { + return nil, errors.Wrap(err, "error loading testsecrets files") + } + err = cfg.CCIP.LoadFromEnv() + if err != nil { + return nil, errors.Wrap(err, "error loading env vars into CCIP config") + } + // validate all products + err = cfg.CCIP.Validate() + if err != nil { + return nil, err + } + } + return cfg, nil } diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip-reorg.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip-reorg.toml new file mode 100644 index 0000000000..afcba2247f --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/ccip-reorg.toml @@ -0,0 +1,64 @@ +[CCIP] +[CCIP.Env] +Mockserver = 'http://mockserver:1080' +[CCIP.Env.Network] +selected_networks= ['SIMULATED_1', 'SIMULATED_2'] + +[CCIP.Env.Network.EVMNetworks.SIMULATED_1] +evm_name = 'source-chain' +evm_chain_id = 1337 +evm_keys = ['59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d', '7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 10 + +[CCIP.Env.Network.EVMNetworks.SIMULATED_2] +evm_name = 'dest-chain' +evm_chain_id = 2337 +evm_keys = ['ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', '7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6'] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '3m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 10 + +[CCIP.Env.NewCLCluster] +NoOfNodes = 6 +NodeMemory = '4Gi' +NodeCPU = '2' +DBMemory = '4Gi' +DBCPU = '2' +DBCapacity = '10Gi' +IsStateful = true +DBArgs = ['shared_buffers=1536MB', 'effective_cache_size=4096MB', 'work_mem=64MB'] + +[CCIP.Env.NewCLCluster.Common] +CommonChainConfigTOML = """ +LogPollInterval = '1s' +[HeadTracker] +HistoryDepth = 30 + +[GasEstimator] +PriceMax = '200 gwei' +LimitDefault = 6000000 +FeeCapDefault = '200 gwei' +""" + +[CCIP.Groups.smoke] +PhaseTimeout = '3m' # Duration to wait for the each phase validation(SendRequested, Commit, RMN Blessing, Execution) to time-out. +LocalCluster = true + +[CCIP.Groups.smoke.ReorgProfile] +FinalityDelta = 5 + + From ac3523aaa4cee6f30b9ac0f25cc7cce559067594 Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Mon, 16 Sep 2024 07:12:37 -0700 Subject: [PATCH 351/432] CCIP-3055 Creating Local docker tests for ccip smoke (#14357) * ccip deployment local dev env * jd interface update * fix environment building * devenv set up * changes * delete non-required file * ccip common config * remove task * add docker env * delete * all changes * changes * adding ccip integration tests * move test to smoke * remove redundant * remove unnecessary changes * remove * fix go mod * fix lint * add jobtype * add ccip jobtype * add ccip job type in feeds service * add assertions * all changes * add changeset * lint fix * reduce flakey test * add changeset tag * revert unwanted * rename func * lint fix --- .changeset/unlucky-dolphins-flash.md | 5 + core/services/feeds/service.go | 11 + core/services/job/mocks/orm.go | 57 ++ core/services/job/orm.go | 13 + core/services/job/validate.go | 1 + core/web/jobs_controller.go | 4 +- core/web/resolver/mutation.go | 4 + integration-tests/.tool-versions | 1 + .../ccip-tests/testsetups/test_env.go | 14 +- integration-tests/client/chainlink.go | 4 +- .../deployment/ccip/add_chain_test.go | 7 +- .../deployment/ccip/add_lane_test.go | 6 +- .../ccip/changeset/2_initial_deploy_test.go | 117 +--- integration-tests/deployment/ccip/deploy.go | 1 + .../deployment/ccip/deploy_home_chain.go | 1 + .../deployment/ccip/test_assertions.go | 203 ++++++ .../deployment/ccip/test_helpers.go | 100 ++- .../deployment/devenv/.sample.env | 5 + .../deployment/devenv/build_env.go | 219 +++++++ integration-tests/deployment/devenv/chain.go | 121 ++++ integration-tests/deployment/devenv/don.go | 288 +++++++++ .../deployment/devenv/environment.go | 54 ++ integration-tests/deployment/devenv/jd.go | 71 ++ integration-tests/deployment/environment.go | 10 +- integration-tests/deployment/helpers.go | 82 +++ .../deployment/jd/node/v1/node.pb.go | 2 +- .../deployment/memory/environment.go | 9 +- integration-tests/deployment/memory/node.go | 8 +- .../deployment/memory/node_test.go | 4 +- integration-tests/go.mod | 5 +- integration-tests/load/go.mod | 2 + integration-tests/smoke/ccip_test.go | 89 +++ .../smoke/job_distributor_test.go | 5 +- integration-tests/testconfig/README.md | 2 +- integration-tests/testconfig/ccip/ccip.toml | 143 +++++ integration-tests/testconfig/ccip/config.go | 92 +++ integration-tests/testconfig/configs_embed.go | 2 + integration-tests/testconfig/testconfig.go | 12 + integration-tests/types/testconfigs.go | 7 + integration-tests/web/sdk/client/client.go | 108 +++- integration-tests/web/sdk/client/types.go | 16 +- .../web/sdk/client/types_test.go | 8 +- .../web/sdk/internal/generated/generated.go | 430 +++++++++++-- .../web/sdk/internal/genqlient.graphql | 606 ++++++++++-------- .../web/sdk/internal/schema.graphql | 11 +- 45 files changed, 2424 insertions(+), 536 deletions(-) create mode 100644 .changeset/unlucky-dolphins-flash.md create mode 100644 integration-tests/deployment/ccip/test_assertions.go create mode 100644 integration-tests/deployment/devenv/.sample.env create mode 100644 integration-tests/deployment/devenv/build_env.go create mode 100644 integration-tests/deployment/devenv/chain.go create mode 100644 integration-tests/deployment/devenv/don.go create mode 100644 integration-tests/deployment/devenv/environment.go create mode 100644 integration-tests/deployment/devenv/jd.go create mode 100644 integration-tests/deployment/helpers.go create mode 100644 integration-tests/smoke/ccip_test.go create mode 100644 integration-tests/testconfig/ccip/ccip.toml create mode 100644 integration-tests/testconfig/ccip/config.go diff --git a/.changeset/unlucky-dolphins-flash.md b/.changeset/unlucky-dolphins-flash.md new file mode 100644 index 0000000000..116b56c87a --- /dev/null +++ b/.changeset/unlucky-dolphins-flash.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal Add ccip JobType in feeds service and other jobtype validations diff --git a/core/services/feeds/service.go b/core/services/feeds/service.go index 0ccba8ff2a..87f0ae60f6 100644 --- a/core/services/feeds/service.go +++ b/core/services/feeds/service.go @@ -17,6 +17,8 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + + ccip "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" "github.com/smartcontractkit/chainlink/v2/plugins" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -818,6 +820,13 @@ func (s *service) ApproveSpec(ctx context.Context, id int64, force bool) error { return fmt.Errorf("failed while checking for existing workflow job: %w", txerr) } } + case job.CCIP: + existingJobID, txerr = tx.jobORM.FindJobIDByCapabilityNameAndVersion(ctx, *j.CCIPSpec) + // Return an error if the repository errors. If there is a not found + // error we want to continue with approving the job. + if txerr != nil && !errors.Is(txerr, sql.ErrNoRows) { + return fmt.Errorf("failed while checking for existing ccip job: %w", txerr) + } default: return errors.Errorf("unsupported job type when approving job proposal specs: %s", j.Type) } @@ -1202,6 +1211,8 @@ func (s *service) generateJob(ctx context.Context, spec string) (*job.Job, error js, err = fluxmonitorv2.ValidatedFluxMonitorSpec(s.jobCfg, spec) case job.Workflow: js, err = workflows.ValidatedWorkflowJobSpec(spec) + case job.CCIP: + js, err = ccip.ValidatedCCIPSpec(spec) default: return nil, errors.Errorf("unknown job type: %s", jobType) } diff --git a/core/services/job/mocks/orm.go b/core/services/job/mocks/orm.go index 0174d6208c..7d3e3de771 100644 --- a/core/services/job/mocks/orm.go +++ b/core/services/job/mocks/orm.go @@ -543,6 +543,63 @@ func (_c *ORM_FindJobIDByAddress_Call) RunAndReturn(run func(context.Context, ty return _c } +// FindJobIDByCapabilityNameAndVersion provides a mock function with given fields: ctx, spec +func (_m *ORM) FindJobIDByCapabilityNameAndVersion(ctx context.Context, spec job.CCIPSpec) (int32, error) { + ret := _m.Called(ctx, spec) + + if len(ret) == 0 { + panic("no return value specified for FindJobIDByCapabilityNameAndVersion") + } + + var r0 int32 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, job.CCIPSpec) (int32, error)); ok { + return rf(ctx, spec) + } + if rf, ok := ret.Get(0).(func(context.Context, job.CCIPSpec) int32); ok { + r0 = rf(ctx, spec) + } else { + r0 = ret.Get(0).(int32) + } + + if rf, ok := ret.Get(1).(func(context.Context, job.CCIPSpec) error); ok { + r1 = rf(ctx, spec) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ORM_FindJobIDByCapabilityNameAndVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindJobIDByCapabilityNameAndVersion' +type ORM_FindJobIDByCapabilityNameAndVersion_Call struct { + *mock.Call +} + +// FindJobIDByCapabilityNameAndVersion is a helper method to define mock.On call +// - ctx context.Context +// - spec job.CCIPSpec +func (_e *ORM_Expecter) FindJobIDByCapabilityNameAndVersion(ctx interface{}, spec interface{}) *ORM_FindJobIDByCapabilityNameAndVersion_Call { + return &ORM_FindJobIDByCapabilityNameAndVersion_Call{Call: _e.mock.On("FindJobIDByCapabilityNameAndVersion", ctx, spec)} +} + +func (_c *ORM_FindJobIDByCapabilityNameAndVersion_Call) Run(run func(ctx context.Context, spec job.CCIPSpec)) *ORM_FindJobIDByCapabilityNameAndVersion_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(job.CCIPSpec)) + }) + return _c +} + +func (_c *ORM_FindJobIDByCapabilityNameAndVersion_Call) Return(_a0 int32, _a1 error) *ORM_FindJobIDByCapabilityNameAndVersion_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ORM_FindJobIDByCapabilityNameAndVersion_Call) RunAndReturn(run func(context.Context, job.CCIPSpec) (int32, error)) *ORM_FindJobIDByCapabilityNameAndVersion_Call { + _c.Call.Return(run) + return _c +} + // FindJobIDByWorkflow provides a mock function with given fields: ctx, spec func (_m *ORM) FindJobIDByWorkflow(ctx context.Context, spec job.WorkflowSpec) (int32, error) { ret := _m.Called(ctx, spec) diff --git a/core/services/job/orm.go b/core/services/job/orm.go index ac3bb65530..5e7328b87d 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -79,6 +79,7 @@ type ORM interface { WithDataSource(source sqlutil.DataSource) ORM FindJobIDByWorkflow(ctx context.Context, spec WorkflowSpec) (int32, error) + FindJobIDByCapabilityNameAndVersion(ctx context.Context, spec CCIPSpec) (int32, error) } type ORMConfig interface { @@ -1123,6 +1124,18 @@ INNER JOIN workflow_specs ws on jobs.workflow_spec_id = ws.id AND ws.workflow_ow return } +func (o *orm) FindJobIDByCapabilityNameAndVersion(ctx context.Context, spec CCIPSpec) (jobID int32, err error) { + stmt := ` +SELECT jobs.id FROM jobs +INNER JOIN ccip_specs ccip on jobs.ccip_spec_id = ccip.id AND ccip.capability_labelled_name = $1 AND ccip.capability_version = $2 +` + err = o.ds.GetContext(ctx, &jobID, stmt, spec.CapabilityLabelledName, spec.CapabilityVersion) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + err = fmt.Errorf("error searching for job for CCIP (capabilityName,capabilityVersion) ('%s','%s'): %w", spec.CapabilityLabelledName, spec.CapabilityVersion, err) + } + return +} + // PipelineRunsByJobsIDs returns pipeline runs for multiple jobs, not preloading data func (o *orm) PipelineRunsByJobsIDs(ctx context.Context, ids []int32) (runs []pipeline.Run, err error) { err = o.transact(ctx, false, func(tx *orm) error { diff --git a/core/services/job/validate.go b/core/services/job/validate.go index 92a08823fc..7cd93b91f0 100644 --- a/core/services/job/validate.go +++ b/core/services/job/validate.go @@ -29,6 +29,7 @@ var ( Webhook: {}, Workflow: {}, StandardCapabilities: {}, + CCIP: {}, } ) diff --git a/core/web/jobs_controller.go b/core/web/jobs_controller.go index 2e005d6d23..1a80ca9693 100644 --- a/core/web/jobs_controller.go +++ b/core/web/jobs_controller.go @@ -12,6 +12,7 @@ import ( "github.com/google/uuid" "github.com/pkg/errors" + ccip "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" "github.com/smartcontractkit/chainlink/v2/core/services/blockhashstore" "github.com/smartcontractkit/chainlink/v2/core/services/blockheaderfeeder" @@ -258,7 +259,8 @@ func (jc *JobsController) validateJobSpec(ctx context.Context, tomlString string jb, err = workflows.ValidatedWorkflowJobSpec(tomlString) case job.StandardCapabilities: jb, err = standardcapabilities.ValidatedStandardCapabilitiesSpec(tomlString) - + case job.CCIP: + jb, err = ccip.ValidatedCCIPSpec(tomlString) default: return jb, http.StatusUnprocessableEntity, errors.Errorf("unknown job type: %s", jobType) } diff --git a/core/web/resolver/mutation.go b/core/web/resolver/mutation.go index a9c1f634dc..4c9e409cbb 100644 --- a/core/web/resolver/mutation.go +++ b/core/web/resolver/mutation.go @@ -14,8 +14,10 @@ import ( "gopkg.in/guregu/null.v4" "github.com/smartcontractkit/chainlink-common/pkg/assets" + "github.com/smartcontractkit/chainlink/v2/core/auth" "github.com/smartcontractkit/chainlink/v2/core/bridges" + ccip "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" "github.com/smartcontractkit/chainlink/v2/core/services/blockhashstore" "github.com/smartcontractkit/chainlink/v2/core/services/blockheaderfeeder" @@ -1066,6 +1068,8 @@ func (r *Resolver) CreateJob(ctx context.Context, args struct { jb, err = standardcapabilities.ValidatedStandardCapabilitiesSpec(args.Input.TOML) case job.Stream: jb, err = streams.ValidatedStreamSpec(args.Input.TOML) + case job.CCIP: + jb, err = ccip.ValidatedCCIPSpec(args.Input.TOML) default: return NewCreateJobPayload(r.App, nil, map[string]string{ "Job Type": fmt.Sprintf("unknown job type: %s", jbt), diff --git a/integration-tests/.tool-versions b/integration-tests/.tool-versions index d623afb283..7ca4249a79 100644 --- a/integration-tests/.tool-versions +++ b/integration-tests/.tool-versions @@ -3,3 +3,4 @@ k3d 5.4.6 kubectl 1.25.5 nodejs 20.13.1 golangci-lint 1.59.1 +task 3.35.1 diff --git a/integration-tests/ccip-tests/testsetups/test_env.go b/integration-tests/ccip-tests/testsetups/test_env.go index 1ba54fc7a0..4d968e8331 100644 --- a/integration-tests/ccip-tests/testsetups/test_env.go +++ b/integration-tests/ccip-tests/testsetups/test_env.go @@ -53,7 +53,7 @@ func SetResourceProfile(cpu, mem string) map[string]interface{} { } } -func setNodeConfig(nets []blockchain.EVMNetwork, nodeConfig, commonChain string, configByChain map[string]string) (*corechainlink.Config, string, error) { +func SetNodeConfig(nets []blockchain.EVMNetwork, nodeConfig, commonChain string, configByChain map[string]string) (*corechainlink.Config, string, error) { var tomlCfg *corechainlink.Config var err error var commonChainConfig *evmcfg.Chain @@ -122,7 +122,7 @@ func ChainlinkPropsForUpdate( chainConfigByChain = testInputs.EnvInput.NewCLCluster.Common.ChainConfigTOMLByChain } - _, tomlStr, err := setNodeConfig( + _, tomlStr, err := SetNodeConfig( testInputs.SelectedNetworks, nodeConfig, commonChainConfig, chainConfigByChain, ) @@ -150,7 +150,7 @@ func ChainlinkPropsForUpdate( "version": upgradeTag, }, } - _, tomlStr, err := setNodeConfig( + _, tomlStr, err := SetNodeConfig( testInputs.SelectedNetworks, testInputs.EnvInput.NewCLCluster.Common.BaseConfigTOML, testInputs.EnvInput.NewCLCluster.Common.CommonChainConfigTOML, @@ -216,7 +216,7 @@ func ChainlinkChart( chainConfigByChain = testInputs.EnvInput.NewCLCluster.Common.ChainConfigTOMLByChain } - _, tomlStr, err := setNodeConfig(nets, nodeConfig, commonChainConfig, chainConfigByChain) + _, tomlStr, err := SetNodeConfig(nets, nodeConfig, commonChainConfig, chainConfigByChain) require.NoError(t, err) nodesMap = append(nodesMap, map[string]any{ "name": clNode.Name, @@ -240,7 +240,7 @@ func ChainlinkChart( return chainlink.New(0, clProps) } clProps["replicas"] = pointer.GetInt(testInputs.EnvInput.NewCLCluster.NoOfNodes) - _, tomlStr, err := setNodeConfig( + _, tomlStr, err := SetNodeConfig( nets, testInputs.EnvInput.NewCLCluster.Common.BaseConfigTOML, testInputs.EnvInput.NewCLCluster.Common.CommonChainConfigTOML, @@ -335,7 +335,7 @@ func DeployLocalCluster( // if individual nodes are specified, then deploy them with specified configs if len(testInputs.EnvInput.NewCLCluster.Nodes) > 0 { for _, clNode := range testInputs.EnvInput.NewCLCluster.Nodes { - toml, _, err := setNodeConfig( + toml, _, err := SetNodeConfig( selectedNetworks, clNode.BaseConfigTOML, clNode.CommonChainConfigTOML, @@ -364,7 +364,7 @@ func DeployLocalCluster( } else { // if no individual nodes are specified, then deploy the number of nodes specified in the env input with common config for i := 0; i < noOfNodes; i++ { - toml, _, err := setNodeConfig( + toml, _, err := SetNodeConfig( selectedNetworks, testInputs.EnvInput.NewCLCluster.Common.BaseConfigTOML, testInputs.EnvInput.NewCLCluster.Common.CommonChainConfigTOML, diff --git a/integration-tests/client/chainlink.go b/integration-tests/client/chainlink.go index da17dcf0d7..ebfd97c48b 100644 --- a/integration-tests/client/chainlink.go +++ b/integration-tests/client/chainlink.go @@ -1112,7 +1112,9 @@ func CreateNodeKeysBundle(nodes []*ChainlinkClient, chainName string, chainId st if err != nil { return nil, nil, err } - + if len(p2pkeys.Data) == 0 { + return nil, nil, fmt.Errorf("found no P2P Keys on the Chainlink node. Node URL: %s", n.URL()) + } peerID := p2pkeys.Data[0].Attributes.PeerID // If there is already a txkey present for the chain skip creating a new one // otherwise the test logic will need multiple key management (like funding all the keys, diff --git a/integration-tests/deployment/ccip/add_chain_test.go b/integration-tests/deployment/ccip/add_chain_test.go index a484bda0f2..fdfbb6e69a 100644 --- a/integration-tests/deployment/ccip/add_chain_test.go +++ b/integration-tests/deployment/ccip/add_chain_test.go @@ -8,6 +8,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" @@ -152,6 +154,9 @@ func TestAddChainInbound(t *testing.T) { // TODO: Send via all inbound lanes and use parallel helper // Now that the proposal has been executed we expect to be able to send traffic to this new 4th chain. + startBlock, err := e.Env.Chains[newChain].LatestBlockNum(testcontext.Get(t)) + require.NoError(t, err) seqNr := SendRequest(t, e.Env, state, initialDeploy[0], newChain, true) - ConfirmExecution(t, e.Env.Chains[initialDeploy[0]], e.Env.Chains[newChain], state.Chains[newChain].OffRamp, seqNr) + require.NoError(t, + ConfirmExecWithSeqNr(t, e.Env.Chains[initialDeploy[0]], e.Env.Chains[newChain], state.Chains[newChain].OffRamp, &startBlock, seqNr)) } diff --git a/integration-tests/deployment/ccip/add_lane_test.go b/integration-tests/deployment/ccip/add_lane_test.go index 77b82348e4..63af3b69c4 100644 --- a/integration-tests/deployment/ccip/add_lane_test.go +++ b/integration-tests/deployment/ccip/add_lane_test.go @@ -5,6 +5,8 @@ import ( "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/smartcontractkit/chainlink/v2/core/logger" ) @@ -48,9 +50,11 @@ func TestAddLane(t *testing.T) { require.Len(t, offRamps, 0) } } + startBlock, err := e.Env.Chains[to].LatestBlockNum(testcontext.Get(t)) + require.NoError(t, err) seqNum := SendRequest(t, e.Env, state, from, to, false) require.Equal(t, uint64(1), seqNum) - ConfirmExecution(t, e.Env.Chains[from], e.Env.Chains[to], state.Chains[to].OffRamp, seqNum) + require.NoError(t, ConfirmExecWithSeqNr(t, e.Env.Chains[from], e.Env.Chains[to], state.Chains[to].OffRamp, &startBlock, seqNum)) // TODO: Add a second lane, then disable the first and // ensure we can send on the second but not the first. diff --git a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go index fa0fbb9141..8de2c4617b 100644 --- a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go +++ b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go @@ -1,22 +1,14 @@ package changeset import ( - "context" - "sync" "testing" - "time" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/integration-tests/deployment" - - "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/logger" ) @@ -58,118 +50,31 @@ func Test0002_InitialDeploy(t *testing.T) { require.NoError(t, err) } } - // Wait for plugins to register filters? - // TODO: Investigate how to avoid. - time.Sleep(30 * time.Second) - - // Ensure job related logs are up to date. - require.NoError(t, ccipdeployment.ReplayAllLogs(nodes, chains)) // Add all lanes - for source := range e.Chains { - for dest := range e.Chains { - if source != dest { - require.NoError(t, ccipdeployment.AddLane(e, state, source, dest)) - } - } - } - + require.NoError(t, ccipdeployment.AddLanesForAll(e, state)) + // Need to keep track of the block number for each chain so that event subscription can be done from that block. + startBlocks := make(map[uint64]*uint64) // Send a message from each chain to every other chain. expectedSeqNum := make(map[uint64]uint64) for src := range e.Chains { - for dest := range e.Chains { + for dest, destChain := range e.Chains { if src == dest { continue } + block, err := destChain.LatestBlockNum(testcontext.Get(t)) + require.NoError(t, err) + startBlocks[dest] = &block seqNum := ccipdeployment.SendRequest(t, e, state, src, dest, false) expectedSeqNum[dest] = seqNum } } // Wait for all commit reports to land. - cStart := time.Now() - var wg sync.WaitGroup - for src, srcChain := range e.Chains { - for dest, dstChain := range e.Chains { - if src == dest { - continue - } - srcChain := srcChain - dstChain := dstChain - wg.Add(1) - go func(src, dest uint64) { - defer wg.Done() - waitForCommitWithInterval(t, srcChain, dstChain, state.Chains[dest].OffRamp, - ccipocr3.SeqNumRange{ccipocr3.SeqNum(expectedSeqNum[dest]), ccipocr3.SeqNum(expectedSeqNum[dest])}) - }(src, dest) - } - } - wg.Wait() - cEnd := time.Now() + ccipdeployment.ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) // Wait for all exec reports to land - for src, srcChain := range e.Chains { - for dest, dstChain := range e.Chains { - if src == dest { - continue - } - srcChain := srcChain - dstChain := dstChain - wg.Add(1) - go func(src, dest deployment.Chain) { - defer wg.Done() - ccipdeployment.ConfirmExecution(t, - src, dest, state.Chains[dest.Selector].OffRamp, - expectedSeqNum[dest.Selector]) - }(srcChain, dstChain) - } - } - wg.Wait() - eEnd := time.Now() - t.Log("Commit time:", cEnd.Sub(cStart)) - t.Log("Exec time:", eEnd.Sub(cEnd)) - // TODO: Apply the proposal. -} + ccipdeployment.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) -func waitForCommitWithInterval( - t *testing.T, - src deployment.Chain, - dest deployment.Chain, - offRamp *offramp.OffRamp, - expectedSeqNumRange ccipocr3.SeqNumRange, -) { - sink := make(chan *offramp.OffRampCommitReportAccepted) - subscription, err := offRamp.WatchCommitReportAccepted(&bind.WatchOpts{ - Context: context.Background(), - }, sink) - require.NoError(t, err) - ticker := time.NewTicker(1 * time.Second) - defer ticker.Stop() - - //revive:disable - for { - select { - case <-ticker.C: - src.Client.(*backends.SimulatedBackend).Commit() - dest.Client.(*backends.SimulatedBackend).Commit() - t.Logf("Waiting for commit report on chain selector %d from source selector %d expected seq nr range %s", - dest.Selector, src.Selector, expectedSeqNumRange.String()) - case subErr := <-subscription.Err(): - t.Fatalf("Subscription error: %+v", subErr) - case report := <-sink: - if len(report.Report.MerkleRoots) > 0 { - // Check the interval of sequence numbers and make sure it matches - // the expected range. - for _, mr := range report.Report.MerkleRoots { - if mr.SourceChainSelector == src.Selector && - uint64(expectedSeqNumRange.Start()) == mr.MinSeqNr && - uint64(expectedSeqNumRange.End()) == mr.MaxSeqNr { - t.Logf("Received commit report on selector %d from source selector %d expected seq nr range %s", - dest.Selector, src.Selector, expectedSeqNumRange.String()) - return - } - } - } - } - } + // TODO: Apply the proposal. } diff --git a/integration-tests/deployment/ccip/deploy.go b/integration-tests/deployment/ccip/deploy.go index 72ab5d7d6e..dab50f5820 100644 --- a/integration-tests/deployment/ccip/deploy.go +++ b/integration-tests/deployment/ccip/deploy.go @@ -14,6 +14,7 @@ import ( owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/tools/gethwrappers" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/integration-tests/deployment" diff --git a/integration-tests/deployment/ccip/deploy_home_chain.go b/integration-tests/deployment/ccip/deploy_home_chain.go index ec078e4a9d..6ff2c25d2a 100644 --- a/integration-tests/deployment/ccip/deploy_home_chain.go +++ b/integration-tests/deployment/ccip/deploy_home_chain.go @@ -17,6 +17,7 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" diff --git a/integration-tests/deployment/ccip/test_assertions.go b/integration-tests/deployment/ccip/test_assertions.go new file mode 100644 index 0000000000..335b465d20 --- /dev/null +++ b/integration-tests/deployment/ccip/test_assertions.go @@ -0,0 +1,203 @@ +package ccipdeployment + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/stretchr/testify/require" + "golang.org/x/sync/errgroup" + + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" +) + +// ConfirmCommitForAllWithExpectedSeqNums waits for all chains in the environment to commit the given expectedSeqNums. +// expectedSeqNums is a map of destinationchain selector to expected sequence number +// startBlocks is a map of destination chain selector to start block number to start watching from. +// If startBlocks is nil, it will start watching from the latest block. +func ConfirmCommitForAllWithExpectedSeqNums( + t *testing.T, + e deployment.Environment, + state CCIPOnChainState, + expectedSeqNums map[uint64]uint64, + startBlocks map[uint64]*uint64, +) { + var wg errgroup.Group + for src, srcChain := range e.Chains { + for dest, dstChain := range e.Chains { + if src == dest { + continue + } + srcChain := srcChain + dstChain := dstChain + wg.Go(func() error { + return func(src, dest uint64) error { + var startBlock *uint64 + if startBlocks != nil { + startBlock = startBlocks[dest] + } + return ConfirmCommitWithExpectedSeqNumRange(t, srcChain, dstChain, state.Chains[dest].OffRamp, startBlock, + ccipocr3.SeqNumRange{ccipocr3.SeqNum(expectedSeqNums[dest]), ccipocr3.SeqNum(expectedSeqNums[dest])}) + }(src, dest) + }) + } + } + require.NoError(t, wg.Wait()) +} + +// ConfirmCommitWithExpectedSeqNumRange waits for a commit report on the destination chain with the expected sequence number range. +// startBlock is the block number to start watching from. +// If startBlock is nil, it will start watching from the latest block. +func ConfirmCommitWithExpectedSeqNumRange( + t *testing.T, + src deployment.Chain, + dest deployment.Chain, + offRamp *offramp.OffRamp, + startBlock *uint64, + expectedSeqNumRange ccipocr3.SeqNumRange, +) error { + sink := make(chan *offramp.OffRampCommitReportAccepted) + subscription, err := offRamp.WatchCommitReportAccepted(&bind.WatchOpts{ + Context: context.Background(), + Start: startBlock, + }, sink) + if err != nil { + return fmt.Errorf("error to subscribe CommitReportAccepted : %w", err) + } + + defer subscription.Unsubscribe() + timer := time.NewTimer(5 * time.Minute) + defer timer.Stop() + ticker := time.NewTicker(2 * time.Second) + defer ticker.Stop() + for { + select { + case <-ticker.C: + // if it's simulated backend, commit to ensure mining + if backend, ok := src.Client.(*backends.SimulatedBackend); ok { + backend.Commit() + } + if backend, ok := dest.Client.(*backends.SimulatedBackend); ok { + backend.Commit() + } + t.Logf("Waiting for commit report on chain selector %d from source selector %d expected seq nr range %s", + dest.Selector, src.Selector, expectedSeqNumRange.String()) + case subErr := <-subscription.Err(): + return fmt.Errorf("subscription error: %w", subErr) + case <-timer.C: + return fmt.Errorf("timed out waiting for commit report on chain selector %d from source selector %d expected seq nr range %s", + dest.Selector, src.Selector, expectedSeqNumRange.String()) + case report := <-sink: + if len(report.Report.MerkleRoots) > 0 { + // Check the interval of sequence numbers and make sure it matches + // the expected range. + for _, mr := range report.Report.MerkleRoots { + if mr.SourceChainSelector == src.Selector && + uint64(expectedSeqNumRange.Start()) == mr.MinSeqNr && + uint64(expectedSeqNumRange.End()) == mr.MaxSeqNr { + t.Logf("Received commit report on selector %d from source selector %d expected seq nr range %s", + dest.Selector, src.Selector, expectedSeqNumRange.String()) + return nil + } + } + } + } + } +} + +// ConfirmExecWithSeqNrForAll waits for all chains in the environment to execute the given expectedSeqNums. +// expectedSeqNums is a map of destinationchain selector to expected sequence number +// startBlocks is a map of destination chain selector to start block number to start watching from. +// If startBlocks is nil, it will start watching from the latest block. +func ConfirmExecWithSeqNrForAll( + t *testing.T, + e deployment.Environment, + state CCIPOnChainState, + expectedSeqNums map[uint64]uint64, + startBlocks map[uint64]*uint64, +) { + var wg errgroup.Group + for src, srcChain := range e.Chains { + for dest, dstChain := range e.Chains { + if src == dest { + continue + } + srcChain := srcChain + dstChain := dstChain + wg.Go(func() error { + return func(src, dest deployment.Chain) error { + var startBlock *uint64 + if startBlocks != nil { + startBlock = startBlocks[dest.Selector] + } + return ConfirmExecWithSeqNr( + t, src, dest, state.Chains[dest.Selector].OffRamp, startBlock, + expectedSeqNums[dstChain.Selector], + ) + }(srcChain, dstChain) + }) + } + } + require.NoError(t, wg.Wait()) +} + +// ConfirmExecWithSeqNr waits for an execution state change on the destination chain with the expected sequence number. +// startBlock is the block number to start watching from. +// If startBlock is nil, it will start watching from the latest block. +func ConfirmExecWithSeqNr( + t *testing.T, + source, dest deployment.Chain, + offRamp *offramp.OffRamp, + startBlock *uint64, + expectedSeqNr uint64, +) error { + timer := time.NewTimer(5 * time.Minute) + defer timer.Stop() + tick := time.NewTicker(5 * time.Second) + defer tick.Stop() + sink := make(chan *offramp.OffRampExecutionStateChanged) + subscription, err := offRamp.WatchExecutionStateChanged(&bind.WatchOpts{ + Context: context.Background(), + Start: startBlock, + }, sink, nil, nil, nil) + if err != nil { + return fmt.Errorf("error to subscribe ExecutionStateChanged : %w", err) + } + defer subscription.Unsubscribe() + for { + select { + case <-tick.C: + // TODO: Clean this up + // if it's simulated backend, commit to ensure mining + if backend, ok := source.Client.(*backends.SimulatedBackend); ok { + backend.Commit() + } + if backend, ok := dest.Client.(*backends.SimulatedBackend); ok { + backend.Commit() + } + scc, err := offRamp.GetSourceChainConfig(nil, source.Selector) + if err != nil { + return fmt.Errorf("error to get source chain config : %w", err) + } + t.Logf("Waiting for ExecutionStateChanged on chain %d from chain %d with expected sequence number %d, current onchain minSeqNr: %d", + dest.Selector, source.Selector, expectedSeqNr, scc.MinSeqNr) + case execEvent := <-sink: + if execEvent.SequenceNumber == expectedSeqNr && execEvent.SourceChainSelector == source.Selector { + t.Logf("Received ExecutionStateChanged on chain %d from chain %d with expected sequence number %d", + dest.Selector, source.Selector, expectedSeqNr) + return nil + } + case <-timer.C: + return fmt.Errorf("timed out waiting for ExecutionStateChanged on chain %d from chain %d with expected sequence number %d", + dest.Selector, source.Selector, expectedSeqNr) + case subErr := <-subscription.Err(): + return fmt.Errorf("Subscription error: %w", subErr) + } + } +} diff --git a/integration-tests/deployment/ccip/test_helpers.go b/integration-tests/deployment/ccip/test_helpers.go index 779b29a749..4458a49abc 100644 --- a/integration-tests/deployment/ccip/test_helpers.go +++ b/integration-tests/deployment/ccip/test_helpers.go @@ -7,20 +7,21 @@ import ( "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/integration-tests/deployment" "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" "github.com/smartcontractkit/chainlink-common/pkg/logger" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment/devenv" ) // Context returns a context with the test's deadline, if available. @@ -67,7 +68,7 @@ func NewEnvironmentWithCR(t *testing.T, lggr logger.Logger, numChains int) Deplo ab, capReg, err := DeployCapReg(lggr, chains, homeChainSel) require.NoError(t, err) - nodes := memory.NewNodes(t, zapcore.InfoLevel, chains, 4, 1, memory.RegistryConfig{ + nodes := memory.NewNodes(t, zapcore.InfoLevel, chains, 4, 1, deployment.CapabilityRegistryConfig{ EVMChainID: homeChainEVM, Contract: capReg, }) @@ -160,33 +161,74 @@ func SendRequest(t *testing.T, e deployment.Environment, state CCIPOnChainState, return it.Event.Message.Header.SequenceNumber } -func ConfirmExecution(t *testing.T, - source, dest deployment.Chain, - offramp *offramp.OffRamp, - expectedSeqNr uint64) { - tick := time.NewTicker(5 * time.Second) - defer tick.Stop() - for range tick.C { - // TODO: Clean this up - source.Client.(*backends.SimulatedBackend).Commit() - dest.Client.(*backends.SimulatedBackend).Commit() - scc, err := offramp.GetSourceChainConfig(nil, source.Selector) - require.NoError(t, err) - t.Logf("Waiting for ExecutionStateChanged on chain %d from chain %d with expected sequence number %d, current onchain minSeqNr: %d", - dest.Selector, source.Selector, expectedSeqNr, scc.MinSeqNr) - iter, err := offramp.FilterExecutionStateChanged(nil, - []uint64{source.Selector}, []uint64{expectedSeqNr}, nil) - require.NoError(t, err) - var count int - for iter.Next() { - if iter.Event.SequenceNumber == expectedSeqNr && iter.Event.SourceChainSelector == source.Selector { - count++ +// DeployedLocalDevEnvironment is a helper struct for setting up a local dev environment with docker +type DeployedLocalDevEnvironment struct { + Ab deployment.AddressBook + Env deployment.Environment + HomeChainSel uint64 + Nodes []devenv.Node +} + +func NewDeployedLocalDevEnvironment(t *testing.T, lggr logger.Logger) DeployedLocalDevEnvironment { + ctx := Context(t) + // create a local docker environment with simulated chains and job-distributor + // we cannot create the chainlink nodes yet as we need to deploy the capability registry first + envConfig, testEnv, cfg := devenv.CreateDockerEnv(t) + require.NotNil(t, envConfig) + require.NotEmpty(t, envConfig.Chains, "chainConfigs should not be empty") + require.NotEmpty(t, envConfig.JDConfig, "jdUrl should not be empty") + chains, err := devenv.NewChains(lggr, envConfig.Chains) + require.NoError(t, err) + homeChainSel := uint64(0) + homeChainEVM := uint64(0) + + // Say first chain is home chain. + for chainSel := range chains { + homeChainEVM, _ = chainsel.ChainIdFromSelector(chainSel) + homeChainSel = chainSel + break + } + // deploy the capability registry + ab, capReg, err := DeployCapReg(lggr, chains, homeChainSel) + require.NoError(t, err) + + // start the chainlink nodes with the CR address + err = devenv.StartChainlinkNodes(t, + envConfig, deployment.CapabilityRegistryConfig{ + EVMChainID: homeChainEVM, + Contract: capReg, + }, + testEnv, cfg) + require.NoError(t, err) + + e, don, err := devenv.NewEnvironment(ctx, lggr, *envConfig) + require.NoError(t, err) + require.NotNil(t, e) + require.NotNil(t, don) + + // fund the nodes + require.NoError(t, don.FundNodes(ctx, deployment.E18Mult(10), e.Chains)) + + return DeployedLocalDevEnvironment{ + Ab: ab, + Env: *e, + HomeChainSel: homeChainSel, + Nodes: don.Nodes, + } +} + +// AddLanesForAll adds densely connected lanes for all chains in the environment so that each chain +// is connected to every other chain except itself. +func AddLanesForAll(e deployment.Environment, state CCIPOnChainState) error { + for source := range e.Chains { + for dest := range e.Chains { + if source != dest { + err := AddLane(e, state, source, dest) + if err != nil { + return err + } } } - if count == 1 { - t.Logf("Received ExecutionStateChanged on chain %d from chain %d with expected sequence number %d", - dest.Selector, source.Selector, expectedSeqNr) - return - } } + return nil } diff --git a/integration-tests/deployment/devenv/.sample.env b/integration-tests/deployment/devenv/.sample.env new file mode 100644 index 0000000000..97d550079a --- /dev/null +++ b/integration-tests/deployment/devenv/.sample.env @@ -0,0 +1,5 @@ +E2E_JD_IMAGE= +E2E_JD_VERSION= + +E2E_TEST_CHAINLINK_IMAGE=public.ecr.aws/w0i8p0z9/chainlink-ccip +E2E_TEST_CHAINLINK_VERSION=2.14.0-ccip1.5.0 \ No newline at end of file diff --git a/integration-tests/deployment/devenv/build_env.go b/integration-tests/deployment/devenv/build_env.go new file mode 100644 index 0000000000..0373cf0b21 --- /dev/null +++ b/integration-tests/deployment/devenv/build_env.go @@ -0,0 +1,219 @@ +package devenv + +import ( + "fmt" + "math/big" + "os" + "strconv" + "testing" + + "github.com/AlekSi/pointer" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/crypto" + chainselectors "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" + "github.com/subosito/gotenv" + + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env/job_distributor" + "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" + + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" + clclient "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" +) + +// CreateDockerEnv creates a new test environment with simulated private ethereum networks and job distributor +// It returns the EnvironmentConfig which holds the chain config and JD config +// The test environment is then used to start chainlink nodes +func CreateDockerEnv(t *testing.T) ( + *EnvironmentConfig, + *test_env.CLClusterTestEnv, + tc.TestConfig, +) { + if _, err := os.Stat(".env"); err == nil || !os.IsNotExist(err) { + require.NoError(t, gotenv.Load(".env"), "Error loading .env file") + } + + cfg, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.CCIP) + require.NoError(t, err, "Error getting config") + + var privateEthereumNetworks []*ctf_config.EthereumNetworkConfig + for _, network := range cfg.CCIP.PrivateEthereumNetworks { + privateEthereumNetworks = append(privateEthereumNetworks, network) + } + env, err := test_env.NewCLTestEnvBuilder(). + WithTestConfig(&cfg). + WithTestInstance(t). + WithPrivateEthereumNetworks(privateEthereumNetworks). + WithStandardCleanup(). + Build() + require.NoError(t, err, "Error building test environment") + chains := CreateChainConfigFromPrivateEthereumNetworks(t, env, cfg.CCIP.PrivateEthereumNetworks, cfg.GetNetworkConfig()) + + var jdConfig JDConfig + // TODO : move this as a part of test_env setup with an input in testconfig + // if JD is not provided, we will spin up a new JD + if cfg.CCIP.GetJDGRPC() == "" && cfg.CCIP.GetJDWSRPC() == "" { + jdDB, err := ctftestenv.NewPostgresDb( + []string{env.DockerNetwork.Name}, + ctftestenv.WithPostgresDbName(cfg.CCIP.GetJDDBName()), + ctftestenv.WithPostgresImageVersion(cfg.CCIP.GetJDDBVersion()), + ) + require.NoError(t, err) + err = jdDB.StartContainer() + require.NoError(t, err) + + jd := job_distributor.New([]string{env.DockerNetwork.Name}, + job_distributor.WithImage(cfg.CCIP.GetJDImage()), + job_distributor.WithVersion(cfg.CCIP.GetJDVersion()), + job_distributor.WithDBURL(jdDB.InternalURL.String()), + ) + err = jd.StartContainer() + require.NoError(t, err) + jdConfig = JDConfig{ + GRPC: jd.Grpc, + // we will use internal wsrpc for nodes on same docker network to connect to JD + WSRPC: jd.InternalWSRPC, + } + } else { + jdConfig = JDConfig{ + GRPC: cfg.CCIP.GetJDGRPC(), + WSRPC: cfg.CCIP.GetJDWSRPC(), + } + } + require.NotEmpty(t, jdConfig, "JD config is empty") + + return &EnvironmentConfig{ + Chains: chains, + JDConfig: jdConfig, + }, env, cfg +} + +// StartChainlinkNodes starts docker containers for chainlink nodes on the existing test environment based on provided test config +// Once the nodes starts, it updates the devenv EnvironmentConfig with the node info +// which includes chainlink API URL, email, password and internal IP +func StartChainlinkNodes( + t *testing.T, + envConfig *EnvironmentConfig, + registryConfig deployment.CapabilityRegistryConfig, + env *test_env.CLClusterTestEnv, + cfg tc.TestConfig, +) error { + evmNetworks := networks.MustGetSelectedNetworkConfig(cfg.GetNetworkConfig()) + for i, net := range evmNetworks { + rpcProvider, err := env.GetRpcProvider(net.ChainID) + require.NoError(t, err, "Error getting rpc provider") + evmNetworks[i].HTTPURLs = rpcProvider.PrivateHttpUrls() + evmNetworks[i].URLs = rpcProvider.PrivateWsUrsl() + } + noOfNodes := pointer.GetInt(cfg.CCIP.CLNode.NoOfPluginNodes) + pointer.GetInt(cfg.CCIP.CLNode.NoOfBootstraps) + var nodeInfo []NodeInfo + for i := 1; i <= noOfNodes; i++ { + if i <= pointer.GetInt(cfg.CCIP.CLNode.NoOfBootstraps) { + nodeInfo = append(nodeInfo, NodeInfo{ + IsBootstrap: true, + Name: fmt.Sprintf("bootstrap-%d", i), + // TODO : make this configurable + P2PPort: "6690", + }) + } else { + nodeInfo = append(nodeInfo, NodeInfo{ + IsBootstrap: false, + Name: fmt.Sprintf("node-%d", i-1), + // TODO : make this configurable + P2PPort: "6690", + }) + } + toml, _, err := testsetups.SetNodeConfig( + evmNetworks, + cfg.NodeConfig.BaseConfigTOML, + cfg.NodeConfig.CommonChainConfigTOML, + cfg.NodeConfig.ChainConfigTOMLByChainID, + ) + + toml.Capabilities.ExternalRegistry.NetworkID = ptr.Ptr(relay.NetworkEVM) + toml.Capabilities.ExternalRegistry.ChainID = ptr.Ptr(strconv.FormatUint(registryConfig.EVMChainID, 10)) + toml.Capabilities.ExternalRegistry.Address = ptr.Ptr(registryConfig.Contract.String()) + + if err != nil { + return err + } + ccipNode, err := test_env.NewClNode( + []string{env.DockerNetwork.Name}, + pointer.GetString(cfg.GetChainlinkImageConfig().Image), + pointer.GetString(cfg.GetChainlinkImageConfig().Version), + toml, + env.LogStream, + test_env.WithPgDBOptions( + ctftestenv.WithPostgresImageVersion(pointer.GetString(cfg.GetChainlinkImageConfig().PostgresVersion)), + ), + ) + if err != nil { + return err + } + ccipNode.SetTestLogger(t) + env.ClCluster.Nodes = append(env.ClCluster.Nodes, ccipNode) + } + err := env.ClCluster.Start() + if err != nil { + return err + } + for i, n := range env.ClCluster.Nodes { + nodeInfo[i].CLConfig = clclient.ChainlinkConfig{ + URL: n.API.URL(), + Email: n.UserEmail, + Password: n.UserPassword, + InternalIP: n.API.InternalIP(), + } + } + + envConfig.nodeInfo = nodeInfo + return nil +} + +// CreateChainConfigFromPrivateEthereumNetworks creates a list of ChainConfig from the private ethereum networks created by the test environment. +// It uses the private keys from the network config to create the deployer key for each chain. +func CreateChainConfigFromPrivateEthereumNetworks( + t *testing.T, + env *test_env.CLClusterTestEnv, + privateEthereumNetworks map[string]*ctf_config.EthereumNetworkConfig, + networkConfig *ctf_config.NetworkConfig, +) []ChainConfig { + evmNetworks := networks.MustGetSelectedNetworkConfig(networkConfig) + networkPvtKeys := make(map[int64]string) + for _, net := range evmNetworks { + require.Greater(t, len(net.PrivateKeys), 0, "No private keys found for network") + networkPvtKeys[net.ChainID] = net.PrivateKeys[0] + } + var chains []ChainConfig + for _, networkCfg := range privateEthereumNetworks { + chainId := networkCfg.EthereumChainConfig.ChainID + chainName, err := chainselectors.NameFromChainId(uint64(chainId)) + require.NoError(t, err, "Error getting chain name") + rpcProvider, err := env.GetRpcProvider(int64(chainId)) + require.NoError(t, err, "Error getting rpc provider") + pvtKeyStr, exists := networkPvtKeys[int64(chainId)] + require.Truef(t, exists, "Private key not found for chain id %d", chainId) + pvtKey, err := crypto.HexToECDSA(pvtKeyStr) + require.NoError(t, err) + deployer, err := bind.NewKeyedTransactorWithChainID(pvtKey, big.NewInt(int64(chainId))) + require.NoError(t, err) + chains = append(chains, ChainConfig{ + ChainID: uint64(chainId), + ChainName: chainName, + ChainType: "EVM", + WSRPCs: rpcProvider.PublicWsUrls(), + HTTPRPCs: rpcProvider.PublicHttpUrls(), + PrivateHTTPRPCs: rpcProvider.PrivateHttpUrls(), + PrivateWSRPCs: rpcProvider.PrivateWsUrsl(), + DeployerKey: deployer, + }) + } + return chains +} diff --git a/integration-tests/deployment/devenv/chain.go b/integration-tests/deployment/devenv/chain.go new file mode 100644 index 0000000000..6374a2c213 --- /dev/null +++ b/integration-tests/deployment/devenv/chain.go @@ -0,0 +1,121 @@ +package devenv + +import ( + "context" + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/sethvargo/go-retry" + chainselectors "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" +) + +// ChainConfig holds the configuration for a with a deployer key which can be used to send transactions to the chain. +type ChainConfig struct { + ChainID uint64 // chain id as per EIP-155, mainly applicable for EVM chains + ChainName string // name of the chain populated from chainselector repo + ChainType string // should denote the chain family. Acceptable values are EVM, COSMOS, SOLANA, STARKNET, APTOS etc + WSRPCs []string // websocket rpcs to connect to the chain + HTTPRPCs []string // http rpcs to connect to the chain + PrivateWSRPCs []string // applicable for private chains spun up with docker/K8s only so that nodes within same cluster can connect internally + PrivateHTTPRPCs []string // applicable for private chains spun up with docker/K8s only so that nodes within same cluster can connect internally + DeployerKey *bind.TransactOpts // key to send transactions to the chain +} + +func NewChains(logger logger.Logger, configs []ChainConfig) (map[uint64]deployment.Chain, error) { + chains := make(map[uint64]deployment.Chain) + for _, chainCfg := range configs { + selector, err := chainselectors.SelectorFromChainId(chainCfg.ChainID) + if err != nil { + return nil, fmt.Errorf("failed to get selector from chain id %d: %w", chainCfg.ChainID, err) + } + // TODO : better client handling + var ec *ethclient.Client + for _, rpc := range chainCfg.WSRPCs { + ec, err = ethclient.Dial(rpc) + if err != nil { + logger.Warnf("failed to dial ws rpc %s", rpc) + continue + } + logger.Infof("connected to ws rpc %s", rpc) + break + } + if ec == nil { + return nil, fmt.Errorf("failed to connect to chain %s", chainCfg.ChainName) + } + chains[selector] = deployment.Chain{ + Selector: selector, + Client: ec, + DeployerKey: chainCfg.DeployerKey, + LatestBlockNum: ec.BlockNumber, + Confirm: func(tx *types.Transaction) (uint64, error) { + var blockNumber uint64 + if tx == nil { + return 0, fmt.Errorf("tx was nil, nothing to confirm") + } + err := retry.Do(context.Background(), + retry.WithMaxDuration(3*time.Minute, retry.NewFibonacci(1*time.Second)), + func(ctx context.Context) error { + receipt, err := ec.TransactionReceipt(ctx, tx.Hash()) + if err != nil { + return retry.RetryableError(fmt.Errorf("failed to get receipt: %w", err)) + } + if receipt != nil { + blockNumber = receipt.BlockNumber.Uint64() + } + if receipt.Status == 0 { + t, _, err := ec.TransactionByHash(context.Background(), tx.Hash()) + if err != nil { + return fmt.Errorf("tx %s reverted, failed to get transaction: %w", tx.Hash().Hex(), err) + } + errReason, err := deployment.GetErrorReasonFromTx(ec, chainCfg.DeployerKey.From, *t, receipt) + if err == nil && errReason != "" { + return fmt.Errorf("tx %s reverted,error reason: %s", tx.Hash().Hex(), errReason) + } + return fmt.Errorf("tx %s reverted, could not decode error reason", tx.Hash().Hex()) + } + return nil + }) + return blockNumber, err + }, + } + } + return chains, nil +} + +// TODO : Remove this when seth is integrated. +func FundAddress(ctx context.Context, from *bind.TransactOpts, to common.Address, amount *big.Int, c deployment.Chain) error { + nonce, err := c.Client.PendingNonceAt(ctx, from.From) + if err != nil { + return fmt.Errorf("failed to get nonce: %w", err) + } + gp, err := c.Client.SuggestGasPrice(ctx) + if err != nil { + return fmt.Errorf("failed to suggest gas price: %w", err) + } + rawTx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gp, + Gas: 21000, + To: &to, + Value: amount, + }) + signedTx, err := from.Signer(from.From, rawTx) + if err != nil { + return fmt.Errorf("failed to sign tx: %w", err) + } + err = c.Client.SendTransaction(ctx, signedTx) + if err != nil { + return fmt.Errorf("failed to send tx: %w", err) + } + _, err = c.Confirm(signedTx) + return err +} diff --git a/integration-tests/deployment/devenv/don.go b/integration-tests/deployment/devenv/don.go new file mode 100644 index 0000000000..663f4c3329 --- /dev/null +++ b/integration-tests/deployment/devenv/don.go @@ -0,0 +1,288 @@ +package devenv + +import ( + "context" + "fmt" + "math/big" + "strconv" + "strings" + + "github.com/AlekSi/pointer" + "github.com/ethereum/go-ethereum/common" + "github.com/hashicorp/go-multierror" + chainselectors "github.com/smartcontractkit/chain-selectors" + + clclient "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/shared/ptypes" + "github.com/smartcontractkit/chainlink/integration-tests/web/sdk/client" +) + +const ( + NodeLabelKeyType = "type" + NodeLabelValueBootstrap = "bootstrap" + NodeLabelValuePlugin = "plugin" +) + +// NodeInfo holds the information required to create a node +type NodeInfo struct { + CLConfig clclient.ChainlinkConfig // config to connect to chainlink node via API + P2PPort string // port for P2P communication + IsBootstrap bool // denotes if the node is a bootstrap node + Name string // name of the node, used to identify the node, helpful in logs + AdminAddr string // admin address to send payments to, applicable only for non-bootstrap nodes +} + +type DON struct { + Nodes []Node +} + +func (don *DON) NodeIds() []string { + var nodeIds []string + for _, node := range don.Nodes { + nodeIds = append(nodeIds, node.NodeId) + } + return nodeIds +} + +func (don *DON) FundNodes(ctx context.Context, amount *big.Int, chains map[uint64]deployment.Chain) error { + var err error + for sel, chain := range chains { + for _, node := range don.Nodes { + // if node is bootstrap, no need to fund it + if node.multiAddr != "" { + continue + } + accountAddr, ok := node.AccountAddr[sel] + if !ok { + err = multierror.Append(err, fmt.Errorf("node %s has no account address for chain %d", node.Name, sel)) + continue + } + if err1 := FundAddress(ctx, chain.DeployerKey, common.HexToAddress(accountAddr), amount, chain); err1 != nil { + err = multierror.Append(err, err1) + } + } + } + return err +} + +func (don *DON) CreateSupportedChains(ctx context.Context, chains []ChainConfig) error { + var err error + for i, node := range don.Nodes { + if err1 := node.CreateCCIPOCRSupportedChains(ctx, chains); err1 != nil { + err = multierror.Append(err, err1) + } + don.Nodes[i] = node + } + return err +} + +// NewRegisteredDON creates a DON with the given node info, registers the nodes with the job distributor +// and sets up the job distributor in the nodes +func NewRegisteredDON(ctx context.Context, nodeInfo []NodeInfo, jd JobDistributor) (*DON, error) { + don := &DON{ + Nodes: make([]Node, 0), + } + for i, info := range nodeInfo { + if info.Name == "" { + info.Name = fmt.Sprintf("node-%d", i) + } + node, err := NewNode(info) + if err != nil { + return nil, fmt.Errorf("failed to create node %d: %w", i, err) + } + // node Labels so that it's easier to query them + if info.IsBootstrap { + // create multi address for OCR2, applicable only for bootstrap nodes + + node.multiAddr = fmt.Sprintf("%s:%s", info.CLConfig.InternalIP, info.P2PPort) + // no need to set admin address for bootstrap nodes, as there will be no payment + node.adminAddr = "" + node.labels = append(node.labels, &ptypes.Label{ + Key: NodeLabelKeyType, + Value: pointer.ToString(NodeLabelValueBootstrap), + }) + } else { + // multi address is not applicable for non-bootstrap nodes + // explicitly set it to empty string to denote that + node.multiAddr = "" + node.labels = append(node.labels, &ptypes.Label{ + Key: NodeLabelKeyType, + Value: pointer.ToString(NodeLabelValuePlugin), + }) + } + // Set up Job distributor in node and register node with the job distributor + err = node.SetUpAndLinkJobDistributor(ctx, jd) + if err != nil { + return nil, fmt.Errorf("failed to set up job distributor in node %s: %w", info.Name, err) + } + + don.Nodes = append(don.Nodes, *node) + } + return don, nil +} + +func NewNode(nodeInfo NodeInfo) (*Node, error) { + gqlClient, err := client.New(nodeInfo.CLConfig.URL, client.Credentials{ + Email: nodeInfo.CLConfig.Email, + Password: nodeInfo.CLConfig.Password, + }) + if err != nil { + return nil, fmt.Errorf("failed to create FMS client: %w", err) + } + return &Node{ + gqlClient: gqlClient, + Name: nodeInfo.Name, + adminAddr: nodeInfo.AdminAddr, + }, nil +} + +type Node struct { + NodeId string // node id returned by job distributor after node is registered with it + JDId string // job distributor id returned by node after Job distributor is created in node + Name string // name of the node + AccountAddr map[uint64]string // chain selector to node's account address mapping for supported chains + gqlClient client.Client // graphql client to interact with the node + labels []*ptypes.Label // labels with which the node is registered with the job distributor + adminAddr string // admin address to send payments to, applicable only for non-bootstrap nodes + multiAddr string // multi address denoting node's FQN (needed for deriving P2PBootstrappers in OCR), applicable only for bootstrap nodes +} + +// CreateCCIPOCRSupportedChains creates a JobDistributorChainConfig for the node. +// It works under assumption that the node is already registered with the job distributor. +// It expects bootstrap nodes to have label with key "type" and value as "bootstrap". +// It fetches the account address, peer id, and OCR2 key bundle id and creates the JobDistributorChainConfig. +func (n *Node) CreateCCIPOCRSupportedChains(ctx context.Context, chains []ChainConfig) error { + for _, chain := range chains { + chainId := strconv.FormatUint(chain.ChainID, 10) + selector, err := chainselectors.SelectorFromChainId(chain.ChainID) + if err != nil { + return fmt.Errorf("failed to get selector from chain id %d: %w", chain.ChainID, err) + } + accountAddr, err := n.gqlClient.FetchAccountAddress(ctx, chainId) + if err != nil { + return fmt.Errorf("failed to fetch account address for node %s: %w", n.Name, err) + } + if accountAddr == nil { + return fmt.Errorf("no account address found for node %s", n.Name) + } + if n.AccountAddr == nil { + n.AccountAddr = make(map[uint64]string) + } + n.AccountAddr[selector] = *accountAddr + peerID, err := n.gqlClient.FetchP2PPeerID(ctx) + if err != nil { + return fmt.Errorf("failed to fetch peer id for node %s: %w", n.Name, err) + } + if peerID == nil { + return fmt.Errorf("no peer id found for node %s", n.Name) + } + + ocr2BundleId, err := n.gqlClient.FetchOCR2KeyBundleID(ctx, chain.ChainType) + if err != nil { + return fmt.Errorf("failed to fetch OCR2 key bundle id for node %s: %w", n.Name, err) + } + if ocr2BundleId == "" { + return fmt.Errorf("no OCR2 key bundle id found for node %s", n.Name) + } + // fetch node labels to know if the node is bootstrap or plugin + isBootstrap := false + for _, label := range n.labels { + if label.Key == NodeLabelKeyType && pointer.GetString(label.Value) == NodeLabelValueBootstrap { + isBootstrap = true + break + } + } + err = n.gqlClient.CreateJobDistributorChainConfig(ctx, client.JobDistributorChainConfigInput{ + JobDistributorID: n.JDId, + ChainID: chainId, + ChainType: chain.ChainType, + AccountAddr: pointer.GetString(accountAddr), + AdminAddr: n.adminAddr, + Ocr2Enabled: true, + Ocr2IsBootstrap: isBootstrap, + Ocr2Multiaddr: n.multiAddr, + Ocr2P2PPeerID: pointer.GetString(peerID), + Ocr2KeyBundleID: ocr2BundleId, + Ocr2Plugins: `{"commit":true,"execute":true,"median":false,"mercury":false}`, + }) + if err != nil { + return fmt.Errorf("failed to create CCIPOCR2SupportedChains for node %s: %w", n.Name, err) + } + } + return nil +} + +func (n *Node) AcceptJob(ctx context.Context, id string) error { + spec, err := n.gqlClient.ApproveJobProposalSpec(ctx, id, false) + if err != nil { + return err + } + if spec == nil { + return fmt.Errorf("no job proposal spec found for job id %s", id) + } + return nil +} + +// RegisterNodeToJobDistributor fetches the CSA public key of the node and registers the node with the job distributor +// it sets the node id returned by JobDistributor as a result of registration in the node struct +func (n *Node) RegisterNodeToJobDistributor(ctx context.Context, jd JobDistributor) error { + // Get the public key of the node + csaKeyRes, err := n.gqlClient.FetchCSAPublicKey(ctx) + if err != nil { + return err + } + if csaKeyRes == nil { + return fmt.Errorf("no csa key found for node %s", n.Name) + } + csaKey := strings.TrimPrefix(*csaKeyRes, "csa_") + // register the node in the job distributor + registerResponse, err := jd.RegisterNode(ctx, &nodev1.RegisterNodeRequest{ + PublicKey: csaKey, + Labels: n.labels, + Name: n.Name, + }) + + if err != nil { + return fmt.Errorf("failed to register node %s: %w", n.Name, err) + } + if registerResponse.GetNode().GetId() == "" { + return fmt.Errorf("no node id returned from job distributor for node %s", n.Name) + } + n.NodeId = registerResponse.GetNode().GetId() + return nil +} + +// CreateJobDistributor fetches the keypairs from the job distributor and creates the job distributor in the node +// and returns the job distributor id +func (n *Node) CreateJobDistributor(ctx context.Context, jd JobDistributor) (string, error) { + // Get the keypairs from the job distributor + csaKey, err := jd.GetCSAPublicKey(ctx) + if err != nil { + return "", err + } + // create the job distributor in the node with the csa key + return n.gqlClient.CreateJobDistributor(ctx, client.JobDistributorInput{ + Name: "Job Distributor", + Uri: jd.WSRPC, + PublicKey: csaKey, + }) +} + +// SetUpAndLinkJobDistributor sets up the job distributor in the node and registers the node with the job distributor +// it sets the job distributor id for node +func (n *Node) SetUpAndLinkJobDistributor(ctx context.Context, jd JobDistributor) error { + // register the node in the job distributor + err := n.RegisterNodeToJobDistributor(ctx, jd) + if err != nil { + return err + } + // now create the job distributor in the node + id, err := n.CreateJobDistributor(ctx, jd) + if err != nil { + return err + } + n.JDId = id + return nil +} diff --git a/integration-tests/deployment/devenv/environment.go b/integration-tests/deployment/devenv/environment.go new file mode 100644 index 0000000000..a62f7f5e84 --- /dev/null +++ b/integration-tests/deployment/devenv/environment.go @@ -0,0 +1,54 @@ +package devenv + +import ( + "context" + "fmt" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" +) + +const ( + DevEnv = "devenv" +) + +type EnvironmentConfig struct { + Chains []ChainConfig + nodeInfo []NodeInfo + JDConfig JDConfig +} + +func NewEnvironment(ctx context.Context, lggr logger.Logger, config EnvironmentConfig) (*deployment.Environment, *DON, error) { + chains, err := NewChains(lggr, config.Chains) + if err != nil { + return nil, nil, fmt.Errorf("failed to create chains: %w", err) + } + offChain, err := NewJDClient(config.JDConfig) + if err != nil { + return nil, nil, fmt.Errorf("failed to create JD client: %w", err) + } + + jd, ok := offChain.(JobDistributor) + if !ok { + return nil, nil, fmt.Errorf("offchain client does not implement JobDistributor") + } + don, err := NewRegisteredDON(ctx, config.nodeInfo, jd) + if err != nil { + return nil, nil, fmt.Errorf("failed to create registered DON: %w", err) + } + nodeIDs := don.NodeIds() + + err = don.CreateSupportedChains(ctx, config.Chains) + if err != nil { + return nil, nil, err + } + + return &deployment.Environment{ + Name: DevEnv, + Offchain: offChain, + NodeIDs: nodeIDs, + Chains: chains, + Logger: lggr, + }, don, nil +} diff --git a/integration-tests/deployment/devenv/jd.go b/integration-tests/deployment/devenv/jd.go new file mode 100644 index 0000000000..671e6e4cea --- /dev/null +++ b/integration-tests/deployment/devenv/jd.go @@ -0,0 +1,71 @@ +package devenv + +import ( + "context" + "fmt" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + csav1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/csa/v1" + jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" + nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1" +) + +type JDConfig struct { + GRPC string + WSRPC string + creds credentials.TransportCredentials +} + +func NewJDConnection(cfg JDConfig) (*grpc.ClientConn, error) { + var opts []grpc.DialOption + // TODO: add auth details + if cfg.creds != nil { + opts = append(opts, grpc.WithTransportCredentials(cfg.creds)) + } else { + opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) + + } + + conn, err := grpc.NewClient(cfg.GRPC, opts...) + if err != nil { + return nil, fmt.Errorf("failed to connect Job Distributor service. Err: %w", err) + } + + return conn, nil +} + +type JobDistributor struct { + WSRPC string + nodev1.NodeServiceClient + jobv1.JobServiceClient + csav1.CSAServiceClient +} + +func NewJDClient(cfg JDConfig) (deployment.OffchainClient, error) { + conn, err := NewJDConnection(cfg) + if err != nil { + return nil, fmt.Errorf("failed to connect Job Distributor service. Err: %w", err) + } + return JobDistributor{ + WSRPC: cfg.WSRPC, + NodeServiceClient: nodev1.NewNodeServiceClient(conn), + JobServiceClient: jobv1.NewJobServiceClient(conn), + CSAServiceClient: csav1.NewCSAServiceClient(conn), + }, err +} + +func (jd JobDistributor) GetCSAPublicKey(ctx context.Context) (string, error) { + keypairs, err := jd.ListKeypairs(ctx, &csav1.ListKeypairsRequest{}) + if err != nil { + return "", err + } + if keypairs == nil || len(keypairs.Keypairs) == 0 { + return "", fmt.Errorf("no keypairs found") + } + csakey := keypairs.Keypairs[0].PublicKey + return csakey, nil +} diff --git a/integration-tests/deployment/environment.go b/integration-tests/deployment/environment.go index 692d7744b1..8d8fc909a9 100644 --- a/integration-tests/deployment/environment.go +++ b/integration-tests/deployment/environment.go @@ -45,8 +45,9 @@ type Chain struct { Selector uint64 Client OnchainClient // Note the Sign function can be abstract supporting a variety of key storage mechanisms (e.g. KMS etc). - DeployerKey *bind.TransactOpts - Confirm func(tx *types.Transaction) (uint64, error) + DeployerKey *bind.TransactOpts + LatestBlockNum func(ctx context.Context) (uint64, error) + Confirm func(tx *types.Transaction) (uint64, error) } type Environment struct { @@ -259,3 +260,8 @@ func NodeInfo(nodeIDs []string, oc OffchainClient) (Nodes, error) { return nodes, nil } + +type CapabilityRegistryConfig struct { + EVMChainID uint64 // chain id of the chain the CR is deployed on + Contract common.Address // address of the CR contract +} diff --git a/integration-tests/deployment/helpers.go b/integration-tests/deployment/helpers.go new file mode 100644 index 0000000000..5e81eadd39 --- /dev/null +++ b/integration-tests/deployment/helpers.go @@ -0,0 +1,82 @@ +package deployment + +import ( + "bytes" + "context" + "encoding/hex" + "encoding/json" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" +) + +func GetErrorReasonFromTx(client bind.ContractBackend, from common.Address, tx types.Transaction, receipt *types.Receipt) (string, error) { + call := ethereum.CallMsg{ + From: from, + To: tx.To(), + Data: tx.Data(), + Value: tx.Value(), + Gas: tx.Gas(), + GasPrice: tx.GasPrice(), + } + _, err := client.CallContract(context.Background(), call, receipt.BlockNumber) + if err != nil { + errorReason, err := parseError(err) + if err == nil { + return errorReason, nil + } + } + return "", fmt.Errorf("tx %s reverted with no reason", tx.Hash().Hex()) +} + +func parseError(txError error) (string, error) { + b, err := json.Marshal(txError) + if err != nil { + return "", err + } + var callErr struct { + Code int + Data string `json:"data"` + Message string `json:"message"` + } + if json.Unmarshal(b, &callErr) != nil { + return "", err + } + + if callErr.Data == "" && strings.Contains(callErr.Message, "missing trie node") { + return "", errors.Errorf("please use an archive node") + } + + return callErr.Data, nil +} + +func ParseErrorFromABI(errorString string, contractABI string) (string, error) { + parsedAbi, err := abi.JSON(strings.NewReader(contractABI)) + if err != nil { + return "", errors.Wrap(err, "error loading ABI") + } + errorString = strings.TrimPrefix(errorString, "Reverted ") + errorString = strings.TrimPrefix(errorString, "0x") + + data, err := hex.DecodeString(errorString) + if err != nil { + return "", errors.Wrap(err, "error decoding error string") + } + for errorName, abiError := range parsedAbi.Errors { + if bytes.Equal(data[:4], abiError.ID.Bytes()[:4]) { + // Found a matching error + v, err3 := abiError.Unpack(data) + if err3 != nil { + return "", errors.Wrap(err3, "error unpacking data") + } + return fmt.Sprintf("error is \"%v\" args %v\n", errorName, v), nil + } + } + return "", errors.New("error not found in ABI") +} diff --git a/integration-tests/deployment/jd/node/v1/node.pb.go b/integration-tests/deployment/jd/node/v1/node.pb.go index 172e285645..224109b826 100644 --- a/integration-tests/deployment/jd/node/v1/node.pb.go +++ b/integration-tests/deployment/jd/node/v1/node.pb.go @@ -817,7 +817,7 @@ func (x *GetNodeResponse) GetNode() *Node { // * // ListNodesRequest is the request object for the ListNodes method. // -// Provide a filter to return a subset of data. Nodes can be filtered by: +// Provide a filter to return a subset of data. NodesByPeerID can be filtered by: // - ids - A list of node ids. // - archived - The archived state of the node. // - selectors - A list of selectors to filter nodes by their labels. diff --git a/integration-tests/deployment/memory/environment.go b/integration-tests/deployment/memory/environment.go index 30606f2e9e..5ae9446494 100644 --- a/integration-tests/deployment/memory/environment.go +++ b/integration-tests/deployment/memory/environment.go @@ -26,7 +26,7 @@ type MemoryEnvironmentConfig struct { Chains int Nodes int Bootstraps int - RegistryConfig RegistryConfig + RegistryConfig deployment.CapabilityRegistryConfig } // Needed for environment variables on the node which point to prexisitng addresses. @@ -41,6 +41,9 @@ func NewMemoryChains(t *testing.T, numChains int) map[uint64]deployment.Chain { Selector: sel, Client: chain.Backend, DeployerKey: chain.DeployerKey, + LatestBlockNum: func(ctx context.Context) (uint64, error) { + return chain.Backend.Blockchain().CurrentBlock().Number.Uint64(), nil + }, Confirm: func(tx *types.Transaction) (uint64, error) { if tx == nil { return 0, fmt.Errorf("tx was nil, nothing to confirm") @@ -63,7 +66,7 @@ func NewMemoryChains(t *testing.T, numChains int) map[uint64]deployment.Chain { return chains } -func NewNodes(t *testing.T, logLevel zapcore.Level, chains map[uint64]deployment.Chain, numNodes, numBootstraps int, registryConfig RegistryConfig) map[string]Node { +func NewNodes(t *testing.T, logLevel zapcore.Level, chains map[uint64]deployment.Chain, numNodes, numBootstraps int, registryConfig deployment.CapabilityRegistryConfig) map[string]Node { mchains := make(map[uint64]EVMChain) for _, chain := range chains { evmChainID, err := chainsel.ChainIdFromSelector(chain.Selector) @@ -114,7 +117,7 @@ func NewMemoryEnvironmentFromChainsNodes(t *testing.T, //func NewMemoryEnvironmentExistingChains(t *testing.T, lggr logger.Logger, // chains map[uint64]deployment.Chain, config MemoryEnvironmentConfig) deployment.Environment { -// nodes := NewNodes(t, chains, config.Nodes, config.Bootstraps, config.RegistryConfig) +// nodes := NewNodes(t, chains, config.Nodes, config.Bootstraps, config.CapabilityRegistryConfig) // var nodeIDs []string // for id := range nodes { // nodeIDs = append(nodeIDs, id) diff --git a/integration-tests/deployment/memory/node.go b/integration-tests/deployment/memory/node.go index 6512788baf..1befa38dc6 100644 --- a/integration-tests/deployment/memory/node.go +++ b/integration-tests/deployment/memory/node.go @@ -22,6 +22,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" v2toml "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -75,11 +76,6 @@ func (n Node) ReplayLogs(chains map[uint64]uint64) error { return nil } -type RegistryConfig struct { - EVMChainID uint64 - Contract common.Address -} - // Creates a CL node which is: // - Configured for OCR // - Configured for the chains specified @@ -90,7 +86,7 @@ func NewNode( chains map[uint64]EVMChain, logLevel zapcore.Level, bootstrap bool, - registryConfig RegistryConfig, + registryConfig deployment.CapabilityRegistryConfig, ) *Node { // Do not want to load fixtures as they contain a dummy chainID. // Create database and initial configuration. diff --git a/integration-tests/deployment/memory/node_test.go b/integration-tests/deployment/memory/node_test.go index d64c7717fc..4a791bfc1f 100644 --- a/integration-tests/deployment/memory/node_test.go +++ b/integration-tests/deployment/memory/node_test.go @@ -6,12 +6,14 @@ import ( "github.com/hashicorp/consul/sdk/freeport" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment" ) func TestNode(t *testing.T) { chains := GenerateChains(t, 3) ports := freeport.GetN(t, 1) - node := NewNode(t, ports[0], chains, zapcore.DebugLevel, false, RegistryConfig{}) + node := NewNode(t, ports[0], chains, zapcore.DebugLevel, false, deployment.CapabilityRegistryConfig{}) // We expect 3 transmitter keys keys, err := node.App.GetKeyStore().Eth().GetAll(Context(t)) require.NoError(t, err) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 6816cb32ba..d802c6eacc 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -20,6 +20,7 @@ require ( github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 github.com/hashicorp/consul/sdk v0.16.0 + github.com/hashicorp/go-multierror v1.1.1 github.com/jmoiron/sqlx v1.4.0 github.com/lib/pq v1.10.9 github.com/manifoldco/promptui v0.9.0 @@ -31,6 +32,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/scylladb/go-reflectx v1.0.1 github.com/segmentio/ksuid v1.0.4 + github.com/sethvargo/go-retry v0.2.4 github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240910151738-3f318badcfb5 @@ -47,6 +49,7 @@ require ( github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 + github.com/subosito/gotenv v1.6.0 github.com/test-go/testify v1.1.4 github.com/testcontainers/testcontainers-go v0.28.0 github.com/umbracle/ethgo v0.1.3 @@ -283,7 +286,6 @@ require ( github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-msgpack v0.5.5 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 // indirect github.com/hashicorp/go-retryablehttp v0.7.5 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect @@ -422,7 +424,6 @@ require ( github.com/status-im/keycard-go v0.2.0 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 46b82a1e1a..f08ac19424 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -29,6 +29,8 @@ require ( go.uber.org/ratelimit v0.3.0 ) +require github.com/AlekSi/pointer v1.1.0 // indirect + require ( go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect diff --git a/integration-tests/smoke/ccip_test.go b/integration-tests/smoke/ccip_test.go new file mode 100644 index 0000000000..d6c65f3c0e --- /dev/null +++ b/integration-tests/smoke/ccip_test.go @@ -0,0 +1,89 @@ +package smoke + +import ( + "strconv" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + + ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/changeset" + jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func Test0002_InitialDeployOnLocal(t *testing.T) { + lggr := logger.TestLogger(t) + ctx := ccipdeployment.Context(t) + tenv := ccipdeployment.NewDeployedLocalDevEnvironment(t, lggr) + e := tenv.Env + nodes := tenv.Nodes + + state, err := ccipdeployment.LoadOnchainState(tenv.Env, tenv.Ab) + require.NoError(t, err) + + // Apply migration + output, err := changeset.Apply0002(tenv.Env, ccipdeployment.DeployCCIPContractConfig{ + HomeChainSel: tenv.HomeChainSel, + ChainsToDeploy: tenv.Env.AllChainSelectors(), + // Capreg/config already exist. + CCIPOnChainState: state, + }) + require.NoError(t, err) + // Get new state after migration. + state, err = ccipdeployment.LoadOnchainState(e, output.AddressBook) + require.NoError(t, err) + + // Apply the jobs. + nodeIdToJobIds := make(map[string][]string) + for nodeID, jobs := range output.JobSpecs { + nodeIdToJobIds[nodeID] = make([]string, 0, len(jobs)) + for _, job := range jobs { + res, err := e.Offchain.ProposeJob(ctx, + &jobv1.ProposeJobRequest{ + NodeId: nodeID, + Spec: job, + }) + require.NoError(t, err) + require.NotNil(t, res.Proposal) + nodeIdToJobIds[nodeID] = append(nodeIdToJobIds[nodeID], res.Proposal.JobId) + } + } + + // Accept all the jobs for this node. + for _, n := range nodes { + jobsToAccept, exists := nodeIdToJobIds[n.NodeId] + require.True(t, exists, "node %s has no jobs to accept", n.NodeId) + for i, jobID := range jobsToAccept { + require.NoError(t, n.AcceptJob(ctx, strconv.Itoa(i+1)), "node -%s failed to accept job %s", n.Name, jobID) + } + } + t.Log("Jobs accepted") + + // Add all lanes + require.NoError(t, ccipdeployment.AddLanesForAll(e, state)) + // Need to keep track of the block number for each chain so that event subscription can be done from that block. + startBlocks := make(map[uint64]*uint64) + // Send a message from each chain to every other chain. + expectedSeqNum := make(map[uint64]uint64) + for src := range e.Chains { + for dest, destChain := range e.Chains { + if src == dest { + continue + } + block, err := destChain.LatestBlockNum(testcontext.Get(t)) + require.NoError(t, err) + startBlocks[dest] = &block + seqNum := ccipdeployment.SendRequest(t, e, state, src, dest, false) + expectedSeqNum[dest] = seqNum + } + } + + // Wait for all commit reports to land. + ccipdeployment.ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) + + // Wait for all exec reports to land + ccipdeployment.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) +} diff --git a/integration-tests/smoke/job_distributor_test.go b/integration-tests/smoke/job_distributor_test.go index 09ad7c2812..2d1657faf7 100644 --- a/integration-tests/smoke/job_distributor_test.go +++ b/integration-tests/smoke/job_distributor_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" @@ -36,14 +37,14 @@ func TestRegisteringMultipleJobDistributor(t *testing.T) { require.NoError(t, err) ctx := context.Background() - err = env.ClCluster.Nodes[0].GraphqlAPI.CreateJobDistributor(ctx, graphqlClient.FeedsManagerInput{ + _, err = env.ClCluster.Nodes[0].GraphqlAPI.CreateJobDistributor(ctx, graphqlClient.JobDistributorInput{ Name: "job-distributor-1", Uri: "http://job-distributor-1:8080", PublicKey: "54227538d9352e0a24550a80ab6a7af6e4f1ffbb8a604e913cbb81c484a7f97d", }) require.NoError(t, err, "Creating first job distributor in chainlink node shouldn't fail") - err = env.ClCluster.Nodes[0].GraphqlAPI.CreateJobDistributor(ctx, graphqlClient.FeedsManagerInput{ + _, err = env.ClCluster.Nodes[0].GraphqlAPI.CreateJobDistributor(ctx, graphqlClient.JobDistributorInput{ Name: "job-distributor-2", Uri: "http://job-distributor-2:8080", PublicKey: "37346b7ea98af21e1309847e00f772826ac3689fe990b1920d01efc58ad2f250", diff --git a/integration-tests/testconfig/README.md b/integration-tests/testconfig/README.md index 2959c1af02..c698281b76 100644 --- a/integration-tests/testconfig/README.md +++ b/integration-tests/testconfig/README.md @@ -230,7 +230,7 @@ For local testing, it is advisable to place these variables in the `overrides.to ## Embedded config -Because Go automatically excludes TOML files during the compilation of binaries, we must take deliberate steps to include our configuration files in the compiled binary. This can be accomplished by using a custom build tag `-o embed`. Implementing this tag will incorporate all the default configurations located in the `./testconfig` folder directly into the binary. Therefore, when executing tests from the binary, you'll only need to supply the `overrides.toml` file. This file should list only the settings you wish to modify; all other configurations will be sourced from the embedded configurations. You can access these embedded configurations [here](.integration-tests/testconfig/configs_embed.go). +Because Go automatically excludes TOML files during the compilation of binaries, we must take deliberate steps to include our configuration files in the compiled binary. This can be accomplished by using a custom build tag `-o embed`. Implementing this tag will incorporate all the default configurations located in the `./testconfig` folder directly into the binary. Therefore, when executing tests from the binary, you'll only need to supply the `overrides.toml` file. This file should list only the settings you wish to modify; all other configurations will be sourced from the embedded configurations. You can access these embedded configurations [here](./configs_embed.go). ## To bear in mind diff --git a/integration-tests/testconfig/ccip/ccip.toml b/integration-tests/testconfig/ccip/ccip.toml new file mode 100644 index 0000000000..cc8d82f246 --- /dev/null +++ b/integration-tests/testconfig/ccip/ccip.toml @@ -0,0 +1,143 @@ +[Network] +selected_networks = ['SIMULATED_1', 'SIMULATED_2'] + +[Network.EVMNetworks.SIMULATED_1] +evm_name = 'chain-1337' +evm_chain_id = 1337 +evm_keys = [ + "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", + "59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", +] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 50000 +evm_transaction_timeout = '2m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 1 + +[Network.EVMNetworks.SIMULATED_2] +evm_name = 'chain-2337' +evm_chain_id = 2337 +evm_keys = [ + "59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", + "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", +] +evm_simulated = true +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 50000 +evm_transaction_timeout = '2m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_depth = 1 + +[NodeConfig] +BaseConfigTOML = """ +[Feature] +FeedsManager = true +LogPoller = true +UICSAKeys = true + +[Log] +Level = 'debug' +JSONConsole = true + +[Log.File] +MaxSize = '0b' + +[WebServer] +AllowOrigins = '*' +HTTPPort = 6688 +SecureCookies = false +HTTPWriteTimeout = '3m' +SessionTimeout = '999h0m0s' + +[WebServer.RateLimit] +Authenticated = 2000 +Unauthenticated = 1000 + +[WebServer.TLS] +HTTPSPort = 0 + +[Database] +MaxIdleConns = 20 +MaxOpenConns = 40 +MigrateOnStartup = true + +[OCR2] +Enabled = true +ContractPollInterval = '5s' + +[OCR] +Enabled = false +DefaultTransactionQueueDepth = 200 + +[P2P] +[P2P.V2] +Enabled = true +ListenAddresses = ['0.0.0.0:6690'] +AnnounceAddresses = ['0.0.0.0:6690'] +DeltaDial = '500ms' +DeltaReconcile = '5s' +""" + +[CCIP] +[CCIP.CLNode] +NoOfPluginNodes = 4 +NoOfBootstraps = 1 + +[CCIP.PrivateEthereumNetworks.SIMULATED_1] +# either eth1 or eth2 (for post-Merge); for eth2 Prysm is used for consensus layer. +ethereum_version = "eth1" +# geth, besu, erigon or nethermind +execution_layer = "geth" +# eth2-only, if set to true environment startup will wait until at least 1 epoch has been finalised +wait_for_finalization=false + +[CCIP.PrivateEthereumNetworks.SIMULATED_1.EthereumChainConfig] +# eth2-only, the lower the value the faster the block production (3 is minimum) +seconds_per_slot = 3 +# eth2-only, the lower the value the faster the epoch finalisation (2 is minimum) +slots_per_epoch = 2 +# eht2-only, the lower tha value the faster the chain starts (10 is minimum) +genesis_delay = 15 +# eth2-only, number of validators +validator_count = 4 +chain_id = 1337 +# address that should be founded in genesis wih ETH +addresses_to_fund = [ + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", +] + +[CCIP.PrivateEthereumNetworks.SIMULATED_1.EthereumChainConfig.HardForkEpochs] +# eth2-only, epoch at which chain will upgrade do Dencun or Deneb/Cancun (1 is minimum) +Deneb = 500 + +#[CCIP.Env.PrivateEthereumNetworks.SIMULATED_1.CustomDockerImages] +# custom docker image that will be used for execution layer client. It has to be one of: hyperledger/besu, nethermind/nethermind, thorax/erigon or ethereum/client-go. +# instead of using a specific tag you can also use "latest_available" to use latest published tag in Github or "latest_stable" to use latest stable release from Github +# (if corresponding Docker image on Docker Hub has not been published environment creation will fail). +#execution_layer="hyperledger/besu:latest_stable" + +[CCIP.PrivateEthereumNetworks.SIMULATED_2] +ethereum_version = "eth1" +execution_layer = "geth" + +[CCIP.PrivateEthereumNetworks.SIMULATED_2.EthereumChainConfig] +seconds_per_slot = 3 +slots_per_epoch = 2 +genesis_delay = 15 +validator_count = 4 +chain_id = 2337 +addresses_to_fund = [ + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", +] + +[CCIP.PrivateEthereumNetworks.SIMULATED_2.EthereumChainConfig.HardForkEpochs] +Deneb = 500 \ No newline at end of file diff --git a/integration-tests/testconfig/ccip/config.go b/integration-tests/testconfig/ccip/config.go new file mode 100644 index 0000000000..a5b168bec2 --- /dev/null +++ b/integration-tests/testconfig/ccip/config.go @@ -0,0 +1,92 @@ +package ccip + +import ( + "github.com/AlekSi/pointer" + + ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + + "github.com/smartcontractkit/chainlink/integration-tests/client" +) + +const ( + E2E_JD_IMAGE = "E2E_JD_IMAGE" + E2E_JD_VERSION = "E2E_JD_VERSION" + E2E_JD_GRPC = "E2E_JD_GRPC" + E2E_JD_WSRPC = "E2E_JD_WSRPC" + DEFAULT_DB_NAME = "JD_DB" + DEFAULT_DB_VERSION = "14.1" +) + +type Config struct { + PrivateEthereumNetworks map[string]*ctfconfig.EthereumNetworkConfig `toml:",omitempty"` + CLNode *NodeConfig `toml:",omitempty"` + JobDistributorConfig JDConfig `toml:",omitempty"` +} + +type NodeConfig struct { + NoOfPluginNodes *int `toml:",omitempty"` + NoOfBootstraps *int `toml:",omitempty"` + ClientConfig *client.ChainlinkConfig `toml:",omitempty"` +} + +type JDConfig struct { + Image *string `toml:",omitempty"` + Version *string `toml:",omitempty"` + DBName *string `toml:",omitempty"` + DBVersion *string `toml:",omitempty"` + JDGRPC *string `toml:",omitempty"` + JDWSRPC *string `toml:",omitempty"` +} + +func (o *Config) Validate() error { + return nil +} + +// TODO: include all JD specific input in generic secret handling +func (o *Config) GetJDGRPC() string { + grpc := pointer.GetString(o.JobDistributorConfig.JDGRPC) + if grpc == "" { + return ctfconfig.MustReadEnvVar_String(E2E_JD_GRPC) + } + return grpc +} + +func (o *Config) GetJDWSRPC() string { + wsrpc := pointer.GetString(o.JobDistributorConfig.JDWSRPC) + if wsrpc == "" { + return ctfconfig.MustReadEnvVar_String(E2E_JD_WSRPC) + } + return wsrpc +} + +func (o *Config) GetJDImage() string { + image := pointer.GetString(o.JobDistributorConfig.Image) + if image == "" { + return ctfconfig.MustReadEnvVar_String(E2E_JD_IMAGE) + } + return image +} + +func (o *Config) GetJDVersion() string { + version := pointer.GetString(o.JobDistributorConfig.Version) + if version == "" { + return ctfconfig.MustReadEnvVar_String(E2E_JD_VERSION) + } + return version +} + +func (o *Config) GetJDDBName() string { + dbname := pointer.GetString(o.JobDistributorConfig.DBName) + if dbname == "" { + return DEFAULT_DB_NAME + } + return dbname +} + +func (o *Config) GetJDDBVersion() string { + dbversion := pointer.GetString(o.JobDistributorConfig.DBVersion) + if dbversion == "" { + return DEFAULT_DB_VERSION + } + return dbversion +} diff --git a/integration-tests/testconfig/configs_embed.go b/integration-tests/testconfig/configs_embed.go index 31303357a4..5de81acb7d 100644 --- a/integration-tests/testconfig/configs_embed.go +++ b/integration-tests/testconfig/configs_embed.go @@ -18,6 +18,8 @@ import "embed" //go:embed vrf/vrf.toml //go:embed vrfv2/vrfv2.toml //go:embed vrfv2plus/vrfv2plus.toml +//go:embed ccip/ccip.toml + var embeddedConfigsFs embed.FS func init() { diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index 23d8d126c9..fb692c56a7 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -27,6 +27,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/osutil" a_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/automation" + ccip_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/ccip" f_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/functions" keeper_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/keeper" lp_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/log_poller" @@ -72,6 +73,10 @@ type Ocr2TestConfig interface { GetOCR2Config() *ocr_config.Config } +type CCIPTestConfig interface { + GetCCIPConfig() *ccip_config.Config +} + const ( E2E_TEST_DATA_STREAMS_URL_ENV = "E2E_TEST_DATA_STREAMS_URL" E2E_TEST_DATA_STREAMS_USERNAME_ENV = "E2E_TEST_DATA_STREAMS_USERNAME" @@ -91,6 +96,7 @@ type TestConfig struct { VRF *vrf_config.Config `toml:"VRF"` VRFv2 *vrfv2_config.Config `toml:"VRFv2"` VRFv2Plus *vrfv2plus_config.Config `toml:"VRFv2Plus"` + CCIP *ccip_config.Config `toml:"CCIP"` ConfigurationNames []string `toml:"-"` } @@ -204,6 +210,10 @@ func (c TestConfig) GetOCRConfig() *ocr_config.Config { return c.OCR } +func (c TestConfig) GetCCIPConfig() *ccip_config.Config { + return c.CCIP +} + func (c TestConfig) GetConfigurationNames() []string { return c.ConfigurationNames } @@ -259,6 +269,8 @@ const ( VRF Product = "vrf" VRFv2 Product = "vrfv2" VRFv2Plus Product = "vrfv2plus" + + CCIP Product = "ccip" ) const TestTypeEnvVarName = "TEST_TYPE" diff --git a/integration-tests/types/testconfigs.go b/integration-tests/types/testconfigs.go index ee9183589c..e0b1f7cc03 100644 --- a/integration-tests/types/testconfigs.go +++ b/integration-tests/types/testconfigs.go @@ -3,6 +3,7 @@ package types import ( ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" ) @@ -51,3 +52,9 @@ type Ocr2TestConfig interface { tc.CommonTestConfig tc.Ocr2TestConfig } + +type CCIPTestConfig interface { + ctf_config.GlobalTestConfig + tc.CommonTestConfig + tc.CCIPTestConfig +} diff --git a/integration-tests/web/sdk/client/client.go b/integration-tests/web/sdk/client/client.go index 74be13562e..783a8a8856 100644 --- a/integration-tests/web/sdk/client/client.go +++ b/integration-tests/web/sdk/client/client.go @@ -7,6 +7,7 @@ import ( "net/http" "strings" + "github.com/AlekSi/pointer" "github.com/Khan/genqlient/graphql" "github.com/smartcontractkit/chainlink/integration-tests/web/sdk/client/doer" @@ -14,18 +15,19 @@ import ( ) type Client interface { - GetCSAKeys(ctx context.Context) (*generated.GetCSAKeysResponse, error) + FetchCSAPublicKey(ctx context.Context) (*string, error) + FetchP2PPeerID(ctx context.Context) (*string, error) + FetchAccountAddress(ctx context.Context, chainID string) (*string, error) + FetchOCR2KeyBundleID(ctx context.Context, chainType string) (string, error) GetJob(ctx context.Context, id string) (*generated.GetJobResponse, error) ListJobs(ctx context.Context, offset, limit int) (*generated.ListJobsResponse, error) - GetBridge(ctx context.Context, id string) (*generated.GetBridgeResponse, error) - ListBridges(ctx context.Context, offset, limit int) (*generated.ListBridgesResponse, error) GetJobDistributor(ctx context.Context, id string) (*generated.GetFeedsManagerResponse, error) ListJobDistributors(ctx context.Context) (*generated.ListFeedsManagersResponse, error) - CreateJobDistributor(ctx context.Context, cmd FeedsManagerInput) error - UpdateJobDistributor(ctx context.Context, id string, cmd FeedsManagerInput) error - CreateJobDistributorChainConfig(ctx context.Context, in CreateFeedsManagerChainConfigInput) error + CreateJobDistributor(ctx context.Context, cmd JobDistributorInput) (string, error) + UpdateJobDistributor(ctx context.Context, id string, cmd JobDistributorInput) error + CreateJobDistributorChainConfig(ctx context.Context, in JobDistributorChainConfigInput) error GetJobProposal(ctx context.Context, id string) (*generated.GetJobProposalResponse, error) - ApproveJobProposalSpec(ctx context.Context, id string, force bool) (*generated.ApproveJobProposalSpecResponse, error) + ApproveJobProposalSpec(ctx context.Context, id string, force bool) (*JobProposalApprovalSuccessSpec, error) CancelJobProposalSpec(ctx context.Context, id string) (*generated.CancelJobProposalSpecResponse, error) RejectJobProposalSpec(ctx context.Context, id string) (*generated.RejectJobProposalSpecResponse, error) UpdateJobProposalSpecDefinition(ctx context.Context, id string, cmd generated.UpdateJobProposalSpecDefinitionInput) (*generated.UpdateJobProposalSpecDefinitionResponse, error) @@ -70,8 +72,58 @@ func New(baseURI string, creds Credentials) (Client, error) { return c, nil } -func (c *client) GetCSAKeys(ctx context.Context) (*generated.GetCSAKeysResponse, error) { - return generated.GetCSAKeys(ctx, c.gqlClient) +func (c *client) FetchCSAPublicKey(ctx context.Context) (*string, error) { + keys, err := generated.FetchCSAKeys(ctx, c.gqlClient) + if err != nil { + return nil, err + } + if keys == nil || len(keys.CsaKeys.GetResults()) == 0 { + return nil, fmt.Errorf("no CSA keys found") + } + return &keys.CsaKeys.GetResults()[0].PublicKey, nil +} + +func (c *client) FetchP2PPeerID(ctx context.Context) (*string, error) { + keys, err := generated.FetchP2PKeys(ctx, c.gqlClient) + if err != nil { + return nil, err + } + if keys == nil || len(keys.P2pKeys.GetResults()) == 0 { + return nil, fmt.Errorf("no P2P keys found") + } + return &keys.P2pKeys.GetResults()[0].PeerID, nil +} + +func (c *client) FetchOCR2KeyBundleID(ctx context.Context, chainType string) (string, error) { + keyBundles, err := generated.FetchOCR2KeyBundles(ctx, c.gqlClient) + if err != nil { + return "", err + } + if keyBundles == nil || len(keyBundles.GetOcr2KeyBundles().Results) == 0 { + return "", fmt.Errorf("no ocr2 keybundle found, check if ocr2 is enabled") + } + for _, keyBundle := range keyBundles.GetOcr2KeyBundles().Results { + if keyBundle.ChainType == generated.OCR2ChainType(chainType) { + return keyBundle.GetId(), nil + } + } + return "", fmt.Errorf("no ocr2 keybundle found for chain type %s", chainType) +} + +func (c *client) FetchAccountAddress(ctx context.Context, chainID string) (*string, error) { + keys, err := generated.FetchAccounts(ctx, c.gqlClient) + if err != nil { + return nil, err + } + if keys == nil || len(keys.EthKeys.GetResults()) == 0 { + return nil, fmt.Errorf("no accounts found") + } + for _, keyDetail := range keys.EthKeys.GetResults() { + if keyDetail.GetChain().Enabled && keyDetail.GetChain().Id == chainID { + return pointer.ToString(keyDetail.Address), nil + } + } + return nil, fmt.Errorf("no account found for chain %s", chainID) } func (c *client) GetJob(ctx context.Context, id string) (*generated.GetJobResponse, error) { @@ -98,17 +150,25 @@ func (c *client) ListJobDistributors(ctx context.Context) (*generated.ListFeedsM return generated.ListFeedsManagers(ctx, c.gqlClient) } -func (c *client) CreateJobDistributor(ctx context.Context, in FeedsManagerInput) error { +func (c *client) CreateJobDistributor(ctx context.Context, in JobDistributorInput) (string, error) { var cmd generated.CreateFeedsManagerInput err := DecodeInput(in, &cmd) if err != nil { - return err + return "", err } - _, err = generated.CreateFeedsManager(ctx, c.gqlClient, cmd) - return err + response, err := generated.CreateFeedsManager(ctx, c.gqlClient, cmd) + if err != nil { + return "", err + } + // Access the FeedsManager ID + if success, ok := response.GetCreateFeedsManager().(*generated.CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess); ok { + feedsManager := success.GetFeedsManager() + return feedsManager.GetId(), nil + } + return "", fmt.Errorf("failed to create feeds manager") } -func (c *client) UpdateJobDistributor(ctx context.Context, id string, in FeedsManagerInput) error { +func (c *client) UpdateJobDistributor(ctx context.Context, id string, in JobDistributorInput) error { var cmd generated.UpdateFeedsManagerInput err := DecodeInput(in, &cmd) if err != nil { @@ -118,7 +178,7 @@ func (c *client) UpdateJobDistributor(ctx context.Context, id string, in FeedsMa return err } -func (c *client) CreateJobDistributorChainConfig(ctx context.Context, in CreateFeedsManagerChainConfigInput) error { +func (c *client) CreateJobDistributorChainConfig(ctx context.Context, in JobDistributorChainConfigInput) error { var cmd generated.CreateFeedsManagerChainConfigInput err := DecodeInput(in, &cmd) if err != nil { @@ -132,8 +192,22 @@ func (c *client) GetJobProposal(ctx context.Context, id string) (*generated.GetJ return generated.GetJobProposal(ctx, c.gqlClient, id) } -func (c *client) ApproveJobProposalSpec(ctx context.Context, id string, force bool) (*generated.ApproveJobProposalSpecResponse, error) { - return generated.ApproveJobProposalSpec(ctx, c.gqlClient, id, force) +func (c *client) ApproveJobProposalSpec(ctx context.Context, id string, force bool) (*JobProposalApprovalSuccessSpec, error) { + res, err := generated.ApproveJobProposalSpec(ctx, c.gqlClient, id, force) + if err != nil { + return nil, err + } + if success, ok := res.GetApproveJobProposalSpec().(*generated.ApproveJobProposalSpecApproveJobProposalSpecApproveJobProposalSpecSuccess); ok { + var cmd JobProposalApprovalSuccessSpec + if success.Spec.Status == generated.SpecStatusApproved { + err := DecodeInput(success.Spec, &cmd) + if err != nil { + return nil, fmt.Errorf("failed to decode job proposal spec: %w ; and job proposal spec not approved", err) + } + return &cmd, nil + } + } + return nil, fmt.Errorf("failed to approve job proposal spec") } func (c *client) CancelJobProposalSpec(ctx context.Context, id string) (*generated.CancelJobProposalSpecResponse, error) { diff --git a/integration-tests/web/sdk/client/types.go b/integration-tests/web/sdk/client/types.go index 49330ee621..d213ee161c 100644 --- a/integration-tests/web/sdk/client/types.go +++ b/integration-tests/web/sdk/client/types.go @@ -7,14 +7,14 @@ import ( "reflect" ) -type FeedsManagerInput struct { +type JobDistributorInput struct { Name string `json:"name"` Uri string `json:"uri"` PublicKey string `json:"publicKey"` } -type CreateFeedsManagerChainConfigInput struct { - FeedsManagerID string `json:"feedsManagerID"` +type JobDistributorChainConfigInput struct { + JobDistributorID string `json:"feedsManagerID"` ChainID string `json:"chainID"` ChainType string `json:"chainType"` AccountAddr string `json:"accountAddr"` @@ -35,6 +35,16 @@ type CreateFeedsManagerChainConfigInput struct { Ocr2Plugins string `json:"ocr2Plugins"` } +type JobProposalApprovalSuccessSpec struct { + Id string `json:"id"` + Definition string `json:"definition"` + Version int `json:"version"` + Status string `json:"status"` + StatusUpdatedAt string `json:"statusUpdatedAt"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +} + func DecodeInput(in, out any) error { if reflect.TypeOf(out).Kind() != reflect.Ptr || reflect.ValueOf(out).IsNil() { return fmt.Errorf("out type must be a non-nil pointer") diff --git a/integration-tests/web/sdk/client/types_test.go b/integration-tests/web/sdk/client/types_test.go index f67cb09954..dd9b48274d 100644 --- a/integration-tests/web/sdk/client/types_test.go +++ b/integration-tests/web/sdk/client/types_test.go @@ -19,7 +19,7 @@ func TestDecodeInput(t *testing.T) { }{ { name: "success", - args: args{&FeedsManagerInput{ + args: args{&JobDistributorInput{ Name: "name", Uri: "uri", PublicKey: "publicKey", @@ -29,7 +29,7 @@ func TestDecodeInput(t *testing.T) { }, { name: "non-pointer", - args: args{&FeedsManagerInput{ + args: args{&JobDistributorInput{ Name: "name", Uri: "uri", PublicKey: "publicKey", @@ -39,7 +39,7 @@ func TestDecodeInput(t *testing.T) { }, { name: "incorrect type", - args: args{&FeedsManagerInput{ + args: args{&JobDistributorInput{ Name: "name", Uri: "uri", PublicKey: "publicKey", @@ -49,7 +49,7 @@ func TestDecodeInput(t *testing.T) { }, { name: "success", - args: args{&FeedsManagerInput{ + args: args{&JobDistributorInput{ Name: "name", Uri: "uri", PublicKey: "publicKey", diff --git a/integration-tests/web/sdk/internal/generated/generated.go b/integration-tests/web/sdk/internal/generated/generated.go index b70fc15614..8efde4c453 100644 --- a/integration-tests/web/sdk/internal/generated/generated.go +++ b/integration-tests/web/sdk/internal/generated/generated.go @@ -1032,6 +1032,7 @@ func (v *CreateFeedsManagerChainConfigResponse) __premarshalJSON() (*__premarsha // // CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload is implemented by the following types: // CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess +// CreateFeedsManagerCreateFeedsManagerDuplicateFeedsManagerError // CreateFeedsManagerCreateFeedsManagerInputErrors // CreateFeedsManagerCreateFeedsManagerNotFoundError // CreateFeedsManagerCreateFeedsManagerSingleFeedsManagerError @@ -1043,6 +1044,8 @@ type CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload interface { func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess) implementsGraphQLInterfaceCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload() { } +func (v *CreateFeedsManagerCreateFeedsManagerDuplicateFeedsManagerError) implementsGraphQLInterfaceCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload() { +} func (v *CreateFeedsManagerCreateFeedsManagerInputErrors) implementsGraphQLInterfaceCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload() { } func (v *CreateFeedsManagerCreateFeedsManagerNotFoundError) implementsGraphQLInterfaceCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload() { @@ -1067,6 +1070,9 @@ func __unmarshalCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload(b case "CreateFeedsManagerSuccess": *v = new(CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess) return json.Unmarshal(b, *v) + case "DuplicateFeedsManagerError": + *v = new(CreateFeedsManagerCreateFeedsManagerDuplicateFeedsManagerError) + return json.Unmarshal(b, *v) case "InputErrors": *v = new(CreateFeedsManagerCreateFeedsManagerInputErrors) return json.Unmarshal(b, *v) @@ -1097,6 +1103,14 @@ func __marshalCreateFeedsManagerCreateFeedsManagerCreateFeedsManagerPayload(v *C *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccess }{typename, v} return json.Marshal(result) + case *CreateFeedsManagerCreateFeedsManagerDuplicateFeedsManagerError: + typename = "DuplicateFeedsManagerError" + + result := struct { + TypeName string `json:"__typename"` + *CreateFeedsManagerCreateFeedsManagerDuplicateFeedsManagerError + }{typename, v} + return json.Marshal(result) case *CreateFeedsManagerCreateFeedsManagerInputErrors: typename = "InputErrors" @@ -1239,6 +1253,16 @@ func (v *CreateFeedsManagerCreateFeedsManagerCreateFeedsManagerSuccessFeedsManag return &retval, nil } +// CreateFeedsManagerCreateFeedsManagerDuplicateFeedsManagerError includes the requested fields of the GraphQL type DuplicateFeedsManagerError. +type CreateFeedsManagerCreateFeedsManagerDuplicateFeedsManagerError struct { + Typename string `json:"__typename"` +} + +// GetTypename returns CreateFeedsManagerCreateFeedsManagerDuplicateFeedsManagerError.Typename, and is useful for accessing the field via an interface. +func (v *CreateFeedsManagerCreateFeedsManagerDuplicateFeedsManagerError) GetTypename() string { + return v.Typename +} + // CreateFeedsManagerCreateFeedsManagerInputErrors includes the requested fields of the GraphQL type InputErrors. type CreateFeedsManagerCreateFeedsManagerInputErrors struct { Typename string `json:"__typename"` @@ -1437,6 +1461,186 @@ func (v *FeedsManagerParts) GetIsConnectionActive() bool { return v.IsConnection // GetCreatedAt returns FeedsManagerParts.CreatedAt, and is useful for accessing the field via an interface. func (v *FeedsManagerParts) GetCreatedAt() string { return v.CreatedAt } +// FetchAccountsEthKeysEthKeysPayload includes the requested fields of the GraphQL type EthKeysPayload. +type FetchAccountsEthKeysEthKeysPayload struct { + Results []FetchAccountsEthKeysEthKeysPayloadResultsEthKey `json:"results"` +} + +// GetResults returns FetchAccountsEthKeysEthKeysPayload.Results, and is useful for accessing the field via an interface. +func (v *FetchAccountsEthKeysEthKeysPayload) GetResults() []FetchAccountsEthKeysEthKeysPayloadResultsEthKey { + return v.Results +} + +// FetchAccountsEthKeysEthKeysPayloadResultsEthKey includes the requested fields of the GraphQL type EthKey. +type FetchAccountsEthKeysEthKeysPayloadResultsEthKey struct { + Address string `json:"address"` + IsDisabled bool `json:"isDisabled"` + Chain FetchAccountsEthKeysEthKeysPayloadResultsEthKeyChain `json:"chain"` + EthBalance string `json:"ethBalance"` + LinkBalance string `json:"linkBalance"` +} + +// GetAddress returns FetchAccountsEthKeysEthKeysPayloadResultsEthKey.Address, and is useful for accessing the field via an interface. +func (v *FetchAccountsEthKeysEthKeysPayloadResultsEthKey) GetAddress() string { return v.Address } + +// GetIsDisabled returns FetchAccountsEthKeysEthKeysPayloadResultsEthKey.IsDisabled, and is useful for accessing the field via an interface. +func (v *FetchAccountsEthKeysEthKeysPayloadResultsEthKey) GetIsDisabled() bool { return v.IsDisabled } + +// GetChain returns FetchAccountsEthKeysEthKeysPayloadResultsEthKey.Chain, and is useful for accessing the field via an interface. +func (v *FetchAccountsEthKeysEthKeysPayloadResultsEthKey) GetChain() FetchAccountsEthKeysEthKeysPayloadResultsEthKeyChain { + return v.Chain +} + +// GetEthBalance returns FetchAccountsEthKeysEthKeysPayloadResultsEthKey.EthBalance, and is useful for accessing the field via an interface. +func (v *FetchAccountsEthKeysEthKeysPayloadResultsEthKey) GetEthBalance() string { return v.EthBalance } + +// GetLinkBalance returns FetchAccountsEthKeysEthKeysPayloadResultsEthKey.LinkBalance, and is useful for accessing the field via an interface. +func (v *FetchAccountsEthKeysEthKeysPayloadResultsEthKey) GetLinkBalance() string { + return v.LinkBalance +} + +// FetchAccountsEthKeysEthKeysPayloadResultsEthKeyChain includes the requested fields of the GraphQL type Chain. +type FetchAccountsEthKeysEthKeysPayloadResultsEthKeyChain struct { + Id string `json:"id"` + Enabled bool `json:"enabled"` +} + +// GetId returns FetchAccountsEthKeysEthKeysPayloadResultsEthKeyChain.Id, and is useful for accessing the field via an interface. +func (v *FetchAccountsEthKeysEthKeysPayloadResultsEthKeyChain) GetId() string { return v.Id } + +// GetEnabled returns FetchAccountsEthKeysEthKeysPayloadResultsEthKeyChain.Enabled, and is useful for accessing the field via an interface. +func (v *FetchAccountsEthKeysEthKeysPayloadResultsEthKeyChain) GetEnabled() bool { return v.Enabled } + +// FetchAccountsResponse is returned by FetchAccounts on success. +type FetchAccountsResponse struct { + EthKeys FetchAccountsEthKeysEthKeysPayload `json:"ethKeys"` +} + +// GetEthKeys returns FetchAccountsResponse.EthKeys, and is useful for accessing the field via an interface. +func (v *FetchAccountsResponse) GetEthKeys() FetchAccountsEthKeysEthKeysPayload { return v.EthKeys } + +// FetchCSAKeysCsaKeysCSAKeysPayload includes the requested fields of the GraphQL type CSAKeysPayload. +type FetchCSAKeysCsaKeysCSAKeysPayload struct { + Results []FetchCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey `json:"results"` +} + +// GetResults returns FetchCSAKeysCsaKeysCSAKeysPayload.Results, and is useful for accessing the field via an interface. +func (v *FetchCSAKeysCsaKeysCSAKeysPayload) GetResults() []FetchCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey { + return v.Results +} + +// FetchCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey includes the requested fields of the GraphQL type CSAKey. +type FetchCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey struct { + Id string `json:"id"` + PublicKey string `json:"publicKey"` + Version int `json:"version"` +} + +// GetId returns FetchCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey.Id, and is useful for accessing the field via an interface. +func (v *FetchCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey) GetId() string { return v.Id } + +// GetPublicKey returns FetchCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey.PublicKey, and is useful for accessing the field via an interface. +func (v *FetchCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey) GetPublicKey() string { return v.PublicKey } + +// GetVersion returns FetchCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey.Version, and is useful for accessing the field via an interface. +func (v *FetchCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey) GetVersion() int { return v.Version } + +// FetchCSAKeysResponse is returned by FetchCSAKeys on success. +type FetchCSAKeysResponse struct { + CsaKeys FetchCSAKeysCsaKeysCSAKeysPayload `json:"csaKeys"` +} + +// GetCsaKeys returns FetchCSAKeysResponse.CsaKeys, and is useful for accessing the field via an interface. +func (v *FetchCSAKeysResponse) GetCsaKeys() FetchCSAKeysCsaKeysCSAKeysPayload { return v.CsaKeys } + +// FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayload includes the requested fields of the GraphQL type OCR2KeyBundlesPayload. +type FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayload struct { + Results []FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle `json:"results"` +} + +// GetResults returns FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayload.Results, and is useful for accessing the field via an interface. +func (v *FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayload) GetResults() []FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle { + return v.Results +} + +// FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle includes the requested fields of the GraphQL type OCR2KeyBundle. +type FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle struct { + Id string `json:"id"` + ChainType OCR2ChainType `json:"chainType"` + ConfigPublicKey string `json:"configPublicKey"` + OnChainPublicKey string `json:"onChainPublicKey"` + OffChainPublicKey string `json:"offChainPublicKey"` +} + +// GetId returns FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle.Id, and is useful for accessing the field via an interface. +func (v *FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle) GetId() string { + return v.Id +} + +// GetChainType returns FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle.ChainType, and is useful for accessing the field via an interface. +func (v *FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle) GetChainType() OCR2ChainType { + return v.ChainType +} + +// GetConfigPublicKey returns FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle.ConfigPublicKey, and is useful for accessing the field via an interface. +func (v *FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle) GetConfigPublicKey() string { + return v.ConfigPublicKey +} + +// GetOnChainPublicKey returns FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle.OnChainPublicKey, and is useful for accessing the field via an interface. +func (v *FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle) GetOnChainPublicKey() string { + return v.OnChainPublicKey +} + +// GetOffChainPublicKey returns FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle.OffChainPublicKey, and is useful for accessing the field via an interface. +func (v *FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayloadResultsOCR2KeyBundle) GetOffChainPublicKey() string { + return v.OffChainPublicKey +} + +// FetchOCR2KeyBundlesResponse is returned by FetchOCR2KeyBundles on success. +type FetchOCR2KeyBundlesResponse struct { + Ocr2KeyBundles FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayload `json:"ocr2KeyBundles"` +} + +// GetOcr2KeyBundles returns FetchOCR2KeyBundlesResponse.Ocr2KeyBundles, and is useful for accessing the field via an interface. +func (v *FetchOCR2KeyBundlesResponse) GetOcr2KeyBundles() FetchOCR2KeyBundlesOcr2KeyBundlesOCR2KeyBundlesPayload { + return v.Ocr2KeyBundles +} + +// FetchP2PKeysP2pKeysP2PKeysPayload includes the requested fields of the GraphQL type P2PKeysPayload. +type FetchP2PKeysP2pKeysP2PKeysPayload struct { + Results []FetchP2PKeysP2pKeysP2PKeysPayloadResultsP2PKey `json:"results"` +} + +// GetResults returns FetchP2PKeysP2pKeysP2PKeysPayload.Results, and is useful for accessing the field via an interface. +func (v *FetchP2PKeysP2pKeysP2PKeysPayload) GetResults() []FetchP2PKeysP2pKeysP2PKeysPayloadResultsP2PKey { + return v.Results +} + +// FetchP2PKeysP2pKeysP2PKeysPayloadResultsP2PKey includes the requested fields of the GraphQL type P2PKey. +type FetchP2PKeysP2pKeysP2PKeysPayloadResultsP2PKey struct { + Id string `json:"id"` + PeerID string `json:"peerID"` + PublicKey string `json:"publicKey"` +} + +// GetId returns FetchP2PKeysP2pKeysP2PKeysPayloadResultsP2PKey.Id, and is useful for accessing the field via an interface. +func (v *FetchP2PKeysP2pKeysP2PKeysPayloadResultsP2PKey) GetId() string { return v.Id } + +// GetPeerID returns FetchP2PKeysP2pKeysP2PKeysPayloadResultsP2PKey.PeerID, and is useful for accessing the field via an interface. +func (v *FetchP2PKeysP2pKeysP2PKeysPayloadResultsP2PKey) GetPeerID() string { return v.PeerID } + +// GetPublicKey returns FetchP2PKeysP2pKeysP2PKeysPayloadResultsP2PKey.PublicKey, and is useful for accessing the field via an interface. +func (v *FetchP2PKeysP2pKeysP2PKeysPayloadResultsP2PKey) GetPublicKey() string { return v.PublicKey } + +// FetchP2PKeysResponse is returned by FetchP2PKeys on success. +type FetchP2PKeysResponse struct { + P2pKeys FetchP2PKeysP2pKeysP2PKeysPayload `json:"p2pKeys"` +} + +// GetP2pKeys returns FetchP2PKeysResponse.P2pKeys, and is useful for accessing the field via an interface. +func (v *FetchP2PKeysResponse) GetP2pKeys() FetchP2PKeysP2pKeysP2PKeysPayload { return v.P2pKeys } + // GetBridgeBridge includes the requested fields of the GraphQL type Bridge. type GetBridgeBridge struct { Typename string `json:"__typename"` @@ -1696,40 +1900,6 @@ func (v *GetBridgeResponse) __premarshalJSON() (*__premarshalGetBridgeResponse, return &retval, nil } -// GetCSAKeysCsaKeysCSAKeysPayload includes the requested fields of the GraphQL type CSAKeysPayload. -type GetCSAKeysCsaKeysCSAKeysPayload struct { - Results []GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey `json:"results"` -} - -// GetResults returns GetCSAKeysCsaKeysCSAKeysPayload.Results, and is useful for accessing the field via an interface. -func (v *GetCSAKeysCsaKeysCSAKeysPayload) GetResults() []GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey { - return v.Results -} - -// GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey includes the requested fields of the GraphQL type CSAKey. -type GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey struct { - Id string `json:"id"` - PublicKey string `json:"publicKey"` - Version int `json:"version"` -} - -// GetId returns GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey.Id, and is useful for accessing the field via an interface. -func (v *GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey) GetId() string { return v.Id } - -// GetPublicKey returns GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey.PublicKey, and is useful for accessing the field via an interface. -func (v *GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey) GetPublicKey() string { return v.PublicKey } - -// GetVersion returns GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey.Version, and is useful for accessing the field via an interface. -func (v *GetCSAKeysCsaKeysCSAKeysPayloadResultsCSAKey) GetVersion() int { return v.Version } - -// GetCSAKeysResponse is returned by GetCSAKeys on success. -type GetCSAKeysResponse struct { - CsaKeys GetCSAKeysCsaKeysCSAKeysPayload `json:"csaKeys"` -} - -// GetCsaKeys returns GetCSAKeysResponse.CsaKeys, and is useful for accessing the field via an interface. -func (v *GetCSAKeysResponse) GetCsaKeys() GetCSAKeysCsaKeysCSAKeysPayload { return v.CsaKeys } - // GetFeedsManagerFeedsManager includes the requested fields of the GraphQL type FeedsManager. type GetFeedsManagerFeedsManager struct { Typename string `json:"__typename"` @@ -3712,6 +3882,16 @@ type ListJobsResponse struct { // GetJobs returns ListJobsResponse.Jobs, and is useful for accessing the field via an interface. func (v *ListJobsResponse) GetJobs() ListJobsJobsJobsPayload { return v.Jobs } +type OCR2ChainType string + +const ( + OCR2ChainTypeEvm OCR2ChainType = "EVM" + OCR2ChainTypeCosmos OCR2ChainType = "COSMOS" + OCR2ChainTypeSolana OCR2ChainType = "SOLANA" + OCR2ChainTypeStarknet OCR2ChainType = "STARKNET" + OCR2ChainTypeAptos OCR2ChainType = "APTOS" +) + // #################### // Jobs and Job Proposals // #################### @@ -4962,44 +5142,35 @@ func CreateFeedsManagerChainConfig( return &data_, err_ } -// The query or mutation executed by GetBridge. -const GetBridge_Operation = ` -query GetBridge ($id: ID!) { - bridge(id: $id) { - __typename - ... BridgeParts - ... on NotFoundError { - message - code +// The query or mutation executed by FetchAccounts. +const FetchAccounts_Operation = ` +query FetchAccounts { + ethKeys { + results { + address + isDisabled + chain { + id + enabled + } + ethBalance + linkBalance } } } -fragment BridgeParts on Bridge { - id - name - url - confirmations - outgoingToken - minimumContractPayment - createdAt -} ` -func GetBridge( +func FetchAccounts( ctx_ context.Context, client_ graphql.Client, - id string, -) (*GetBridgeResponse, error) { +) (*FetchAccountsResponse, error) { req_ := &graphql.Request{ - OpName: "GetBridge", - Query: GetBridge_Operation, - Variables: &__GetBridgeInput{ - Id: id, - }, + OpName: "FetchAccounts", + Query: FetchAccounts_Operation, } var err_ error - var data_ GetBridgeResponse + var data_ FetchAccountsResponse resp_ := &graphql.Response{Data: &data_} err_ = client_.MakeRequest( @@ -5011,9 +5182,9 @@ func GetBridge( return &data_, err_ } -// The query or mutation executed by GetCSAKeys. -const GetCSAKeys_Operation = ` -query GetCSAKeys { +// The query or mutation executed by FetchCSAKeys. +const FetchCSAKeys_Operation = ` +query FetchCSAKeys { csaKeys { results { id @@ -5024,17 +5195,138 @@ query GetCSAKeys { } ` -func GetCSAKeys( +func FetchCSAKeys( + ctx_ context.Context, + client_ graphql.Client, +) (*FetchCSAKeysResponse, error) { + req_ := &graphql.Request{ + OpName: "FetchCSAKeys", + Query: FetchCSAKeys_Operation, + } + var err_ error + + var data_ FetchCSAKeysResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by FetchOCR2KeyBundles. +const FetchOCR2KeyBundles_Operation = ` +query FetchOCR2KeyBundles { + ocr2KeyBundles { + results { + id + chainType + configPublicKey + onChainPublicKey + offChainPublicKey + } + } +} +` + +func FetchOCR2KeyBundles( + ctx_ context.Context, + client_ graphql.Client, +) (*FetchOCR2KeyBundlesResponse, error) { + req_ := &graphql.Request{ + OpName: "FetchOCR2KeyBundles", + Query: FetchOCR2KeyBundles_Operation, + } + var err_ error + + var data_ FetchOCR2KeyBundlesResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by FetchP2PKeys. +const FetchP2PKeys_Operation = ` +query FetchP2PKeys { + p2pKeys { + results { + id + peerID + publicKey + } + } +} +` + +func FetchP2PKeys( ctx_ context.Context, client_ graphql.Client, -) (*GetCSAKeysResponse, error) { +) (*FetchP2PKeysResponse, error) { req_ := &graphql.Request{ - OpName: "GetCSAKeys", - Query: GetCSAKeys_Operation, + OpName: "FetchP2PKeys", + Query: FetchP2PKeys_Operation, } var err_ error - var data_ GetCSAKeysResponse + var data_ FetchP2PKeysResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetBridge. +const GetBridge_Operation = ` +query GetBridge ($id: ID!) { + bridge(id: $id) { + __typename + ... BridgeParts + ... on NotFoundError { + message + code + } + } +} +fragment BridgeParts on Bridge { + id + name + url + confirmations + outgoingToken + minimumContractPayment + createdAt +} +` + +func GetBridge( + ctx_ context.Context, + client_ graphql.Client, + id string, +) (*GetBridgeResponse, error) { + req_ := &graphql.Request{ + OpName: "GetBridge", + Query: GetBridge_Operation, + Variables: &__GetBridgeInput{ + Id: id, + }, + } + var err_ error + + var data_ GetBridgeResponse resp_ := &graphql.Response{Data: &data_} err_ = client_.MakeRequest( diff --git a/integration-tests/web/sdk/internal/genqlient.graphql b/integration-tests/web/sdk/internal/genqlient.graphql index c6307f916a..cd1912b88c 100644 --- a/integration-tests/web/sdk/internal/genqlient.graphql +++ b/integration-tests/web/sdk/internal/genqlient.graphql @@ -2,118 +2,168 @@ # CSA Keys ##################### -query GetCSAKeys { - csaKeys { - results { - id - publicKey - version +query FetchCSAKeys { + csaKeys { + results { + id + publicKey + version + } + } +} + +##################### +# P2P Keys +##################### + +query FetchP2PKeys { + p2pKeys { + results { + id + peerID + publicKey + } + } +} + +##################### +# ethKeys +##################### + +query FetchAccounts { + ethKeys { + results { + address + isDisabled + chain { + id + enabled + } + ethBalance + linkBalance + } } - } } +##################### +# ocr2KeyBundles +##################### + +query FetchOCR2KeyBundles { + ocr2KeyBundles { + results { + id + chainType + configPublicKey + onChainPublicKey + offChainPublicKey + } + } +} + + ##################### # Jobs and Job Proposals ##################### fragment OCR2Spec on OCR2Spec { - blockchainTimeout - contractID - contractConfigConfirmations - contractConfigTrackerPollInterval - createdAt - ocrKeyBundleID - monitoringEndpoint - p2pv2Bootstrappers - relay - relayConfig - transmitterID - pluginType - pluginConfig + blockchainTimeout + contractID + contractConfigConfirmations + contractConfigTrackerPollInterval + createdAt + ocrKeyBundleID + monitoringEndpoint + p2pv2Bootstrappers + relay + relayConfig + transmitterID + pluginType + pluginConfig } fragment JobParts on Job { - id - name - schemaVersion - gasLimit - forwardingAllowed - maxTaskDuration - externalJobID - type - spec { - ... on OCR2Spec { - ...OCR2Spec - } - } - observationSource - errors { id - description - occurrences - createdAt - updatedAt - } + name + schemaVersion + gasLimit + forwardingAllowed + maxTaskDuration + externalJobID + type + spec { + ... on OCR2Spec { + ...OCR2Spec + } + } + observationSource + errors { + id + description + occurrences + createdAt + updatedAt + } } query GetJob($id: ID!) { - job(id: $id) { - ...JobParts - ... on NotFoundError { - message - code + job(id: $id) { + ...JobParts + ... on NotFoundError { + message + code + } } - } } query ListJobs($offset: Int, $limit: Int) { - jobs(offset: $offset, limit: $limit) { - results { - ...JobParts - } - metadata { - total + jobs(offset: $offset, limit: $limit) { + results { + ...JobParts + } + metadata { + total + } } - } } query GetJobProposal($id: ID!) { - jobProposal(id: $id) { - ... on JobProposal { - id - name - status - remoteUUID - externalJobID - jobID - feedsManager { - ...FeedsManagerParts - } - multiAddrs - pendingUpdate - specs { - id - definition - version - status - statusUpdatedAt - createdAt - updatedAt - } - latestSpec { - id - definition - version - status - statusUpdatedAt - createdAt - updatedAt - } - } - ... on NotFoundError { - message - code + jobProposal(id: $id) { + ... on JobProposal { + id + name + status + remoteUUID + externalJobID + jobID + feedsManager { + ...FeedsManagerParts + } + multiAddrs + pendingUpdate + specs { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + latestSpec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on NotFoundError { + message + code + } } - } } ##################### @@ -121,34 +171,34 @@ query GetJobProposal($id: ID!) { ##################### fragment BridgeParts on Bridge { - id - name - url - confirmations - outgoingToken - minimumContractPayment - createdAt + id + name + url + confirmations + outgoingToken + minimumContractPayment + createdAt } query ListBridges($offset: Int, $limit: Int) { - bridges(offset: $offset, limit: $limit) { - results { - ...BridgeParts - } - metadata { - total + bridges(offset: $offset, limit: $limit) { + results { + ...BridgeParts + } + metadata { + total + } } - } } query GetBridge($id: ID!) { - bridge(id: $id) { - ...BridgeParts - ... on NotFoundError { - message - code + bridge(id: $id) { + ...BridgeParts + ... on NotFoundError { + message + code + } } - } } ##################### @@ -156,126 +206,126 @@ query GetBridge($id: ID!) { ##################### fragment FeedsManagerParts on FeedsManager { - id - name - uri - publicKey - isConnectionActive - createdAt + id + name + uri + publicKey + isConnectionActive + createdAt } query GetFeedsManager($id: ID!) { - feedsManager(id: $id) { - ...FeedsManagerParts - ... on NotFoundError { - message - code + feedsManager(id: $id) { + ...FeedsManagerParts + ... on NotFoundError { + message + code + } } - } } query ListFeedsManagers { - feedsManagers { - results { - ...FeedsManagerParts + feedsManagers { + results { + ...FeedsManagerParts + } } - } } mutation CreateFeedsManager($input: CreateFeedsManagerInput!) { - createFeedsManager(input: $input) { - ... on CreateFeedsManagerSuccess { - feedsManager { - ...FeedsManagerParts - } - } - ... on SingleFeedsManagerError { - message - code - } - ... on NotFoundError { - message - code - } - ... on InputErrors { - errors { - message - code - path - } + createFeedsManager(input: $input) { + ... on CreateFeedsManagerSuccess { + feedsManager { + ...FeedsManagerParts + } + } + ... on SingleFeedsManagerError { + message + code + } + ... on NotFoundError { + message + code + } + ... on InputErrors { + errors { + message + code + path + } + } } - } } mutation UpdateFeedsManager($id: ID!, $input: UpdateFeedsManagerInput!) { - updateFeedsManager(id: $id, input: $input) { - ... on UpdateFeedsManagerSuccess { - feedsManager { - ...FeedsManagerParts - } - } - ... on NotFoundError { - message - code - } - ... on InputErrors { - errors { - message - code - path - } + updateFeedsManager(id: $id, input: $input) { + ... on UpdateFeedsManagerSuccess { + feedsManager { + ...FeedsManagerParts + } + } + ... on NotFoundError { + message + code + } + ... on InputErrors { + errors { + message + code + path + } + } } - } } # createFeedsManagerChainConfig.graphql mutation CreateFeedsManagerChainConfig($input: CreateFeedsManagerChainConfigInput!) { - createFeedsManagerChainConfig(input: $input) { - ... on CreateFeedsManagerChainConfigSuccess { - chainConfig { - id - chainID - chainType - accountAddr - adminAddr - fluxMonitorJobConfig { - enabled - } - ocr1JobConfig { - enabled - isBootstrap - multiaddr - p2pPeerID - keyBundleID - } - ocr2JobConfig { - enabled - isBootstrap - multiaddr - forwarderAddress - p2pPeerID - keyBundleID - plugins { - commit - execute - median - mercury - rebalancer - } - } - } - } - ... on NotFoundError { - message - code - } - ... on InputErrors { - errors { - message - path - } + createFeedsManagerChainConfig(input: $input) { + ... on CreateFeedsManagerChainConfigSuccess { + chainConfig { + id + chainID + chainType + accountAddr + adminAddr + fluxMonitorJobConfig { + enabled + } + ocr1JobConfig { + enabled + isBootstrap + multiaddr + p2pPeerID + keyBundleID + } + ocr2JobConfig { + enabled + isBootstrap + multiaddr + forwarderAddress + p2pPeerID + keyBundleID + plugins { + commit + execute + median + mercury + rebalancer + } + } + } + } + ... on NotFoundError { + message + code + } + ... on InputErrors { + errors { + message + path + } + } } - } } @@ -284,88 +334,88 @@ mutation CreateFeedsManagerChainConfig($input: CreateFeedsManagerChainConfigInpu ##################### mutation ApproveJobProposalSpec($id: ID!, $force: Boolean) { - approveJobProposalSpec(id: $id, force: $force) { - ... on ApproveJobProposalSpecSuccess { - spec { - id - definition - version - status - statusUpdatedAt - createdAt - updatedAt - } - } - ... on JobAlreadyExistsError { - message - code - } - ... on NotFoundError { - message - code + approveJobProposalSpec(id: $id, force: $force) { + ... on ApproveJobProposalSpecSuccess { + spec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on JobAlreadyExistsError { + message + code + } + ... on NotFoundError { + message + code + } } - } } mutation CancelJobProposalSpec($id: ID!) { - cancelJobProposalSpec(id: $id) { - ... on CancelJobProposalSpecSuccess { - spec { - id - definition - version - status - statusUpdatedAt - createdAt - updatedAt - } - } - ... on NotFoundError { - message - code + cancelJobProposalSpec(id: $id) { + ... on CancelJobProposalSpecSuccess { + spec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on NotFoundError { + message + code + } } - } } mutation RejectJobProposalSpec($id: ID!) { - rejectJobProposalSpec(id: $id) { - ... on RejectJobProposalSpecSuccess { - spec { - id - definition - version - status - statusUpdatedAt - createdAt - updatedAt - } - } - ... on NotFoundError { - message - code + rejectJobProposalSpec(id: $id) { + ... on RejectJobProposalSpecSuccess { + spec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on NotFoundError { + message + code + } } - } } mutation UpdateJobProposalSpecDefinition( - $id: ID! - $input: UpdateJobProposalSpecDefinitionInput! + $id: ID! + $input: UpdateJobProposalSpecDefinitionInput! ) { - updateJobProposalSpecDefinition(id: $id, input: $input) { - ... on UpdateJobProposalSpecDefinitionSuccess { - spec { - id - definition - version - status - statusUpdatedAt - createdAt - updatedAt - } - } - ... on NotFoundError { - message - code + updateJobProposalSpecDefinition(id: $id, input: $input) { + ... on UpdateJobProposalSpecDefinitionSuccess { + spec { + id + definition + version + status + statusUpdatedAt + createdAt + updatedAt + } + } + ... on NotFoundError { + message + code + } } - } } diff --git a/integration-tests/web/sdk/internal/schema.graphql b/integration-tests/web/sdk/internal/schema.graphql index 64b7e479ab..be09d61ec7 100644 --- a/integration-tests/web/sdk/internal/schema.graphql +++ b/integration-tests/web/sdk/internal/schema.graphql @@ -287,6 +287,7 @@ type EthTransactionAttemptsPayload implements PaginatedPayload { type Features { csa: Boolean! feedsManager: Boolean! + multiFeedsManagers: Boolean! } # FeaturesPayload defines the response of fetching the features availability in the UI @@ -370,6 +371,13 @@ type CreateFeedsManagerSuccess { feedsManager: FeedsManager! } +type DuplicateFeedsManagerError implements Error { + message: String! + code: ErrorCode! +} + +# DEPRECATED: No longer used since we now support multiple feeds manager. +# Keeping this to avoid breaking change. type SingleFeedsManagerError implements Error { message: String! code: ErrorCode! @@ -377,7 +385,8 @@ type SingleFeedsManagerError implements Error { # CreateFeedsManagerPayload defines the response when creating a feeds manager union CreateFeedsManagerPayload = CreateFeedsManagerSuccess - | SingleFeedsManagerError + | DuplicateFeedsManagerError + | SingleFeedsManagerError # // TODO: delete once multiple feeds managers support is released | NotFoundError | InputErrors From d5b88d74a9ec3890f5ce998259ed2aac4ddc95b1 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 16 Sep 2024 09:15:07 -0500 Subject: [PATCH 352/432] fix make test-short (#14428) --- GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index de5511ce6d..23082a1f5a 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -178,7 +178,7 @@ modgraph: .PHONY: test-short test-short: ## Run 'go test -short' and suppress uninteresting output - go test -short ./... | grep -v "[no test files]" | grep -v "\(cached\)" + go test -short ./... | grep -v "no test files" | grep -v "\(cached\)" help: @echo "" From f6f7dc16d6120a393750880bb329dc7e86fc3eb2 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 16 Sep 2024 09:15:29 -0500 Subject: [PATCH 353/432] integration-tests/load: go.mod cleanup (#14429) --- integration-tests/load/go.mod | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index f08ac19424..48017e4437 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -31,17 +31,6 @@ require ( require github.com/AlekSi/pointer v1.1.0 // indirect -require ( - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 // indirect - go.opentelemetry.io/otel/log v0.4.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.4.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect -) - require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect cosmossdk.io/api v0.3.1 // indirect @@ -459,10 +448,18 @@ require ( go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 // indirect + go.opentelemetry.io/otel/log v0.4.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.4.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect From 6814bcef45a7157ac9835c25a9a5b95a135bdc01 Mon Sep 17 00:00:00 2001 From: Graham Goh Date: Tue, 17 Sep 2024 00:51:28 +1000 Subject: [PATCH 354/432] feat(ui): update to latest (#14438) Bring in changes for introducing peerId field for OCR2 bootstrap node in chain config page. Reference: https://github.com/smartcontractkit/operator-ui/pull/88 JIRA: https://smartcontract-it.atlassian.net/browse/OPCORE-948 --- .changeset/hot-roses-add.md | 5 +++++ core/web/assets/index.html | 2 +- core/web/assets/index.html.gz | Bin 418 -> 420 bytes ...eb7f66.js => main.84f90f8fc23465846aa7.js} | 2 +- ....js.gz => main.84f90f8fc23465846aa7.js.gz} | Bin 1196259 -> 1196279 bytes operator_ui/TAG | 2 +- 6 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/hot-roses-add.md rename core/web/assets/{main.2f351fafaaf99deb7f66.js => main.84f90f8fc23465846aa7.js} (93%) rename core/web/assets/{main.2f351fafaaf99deb7f66.js.gz => main.84f90f8fc23465846aa7.js.gz} (94%) diff --git a/.changeset/hot-roses-add.md b/.changeset/hot-roses-add.md new file mode 100644 index 0000000000..99f899666a --- /dev/null +++ b/.changeset/hot-roses-add.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#internal Update to latest UI - PeerId field is introduced for OCR2 bootstrap node in chain config page diff --git a/core/web/assets/index.html b/core/web/assets/index.html index 541bcfe5ac..d5411542a9 100644 --- a/core/web/assets/index.html +++ b/core/web/assets/index.html @@ -1 +1 @@ -Operator UIChainlink

    \ No newline at end of file +Operator UIChainlink
    \ No newline at end of file diff --git a/core/web/assets/index.html.gz b/core/web/assets/index.html.gz index 9793fdb18508508c1ac4410268256ed903cae2f9..4f63d9ebf444c265381d7c86449c1bf560256973 100644 GIT binary patch literal 420 zcmV;V0bBkbiwFP!000021C^3NYuqpph5w2w=&8Gwn{1M8keoxHkU}Xm%^}BGdAy!h z(imyh$^QFdd$Uj|lwKtCV7@o=H1=J~UXBB*USeqM=|pH78&N>{9&$l(`sv5#^;Vmc zoFJmpBjL-yS+w$;1d}-ZLap?!#gRO&=f{c?2|-vF4*}iBi6JBbn{NYV5YFo9!J0*~ zfzmIPF*sd%&f*WE$aB)F&)7NLiwxz~m=Yn&WSYTCMR8BBRYEbo2TBv8BF}el5O$v9 zkg=5a7xx|K2r@M=+x&^_I7zAY%=>^aP^mme<4d{gAW}HG@4RE-+snFMZR&b;RoD8| zs2l^99`V1((^PNhuOOHS!iNXXsr(CTIvA(wX+-_ktfmijnj-Acysl^M9QyrRLg&bf z&oqc?vBT{2d}&p(ciKQHD8)peRBboir@GsA{^D|TeYM?O1KdC7yXPfKHC&4M@c Os{RHA*3neJ0ssIZ&(ih) literal 418 zcmV;T0bTwdiwFP!000021C^3NYaB5Qh5w3c=&9N9Bx%wn*pow`kU}Xm&7nuFE$^tc zt-;n#vj4u!?q;D-D81PDfxag_%f1QhWjCQ3C8xn2PlPboi~`D!P#cQVPv1YSK5BE6 z3uJV9CVZZ_idLSBU=gREDahyo&g5~mf1FVvAxNv{A)z~87($Y8_&Q+);i{eIc`jOw6{FLm$kc9)X&I_4rWL$&lsEL!6%^w~pt3MJ@_YwdVdptd z6kskzy8GGmV9kLrSaVpMHHY0` z3m@elyj2A;C}D*K)(O>TnBnnYE3E3aC>g0Kn5NE}Q=ttsD+*3mW?6g!&4V=uyxFhn MZ}*9@?7#v50H2o41^@s6 diff --git a/core/web/assets/main.2f351fafaaf99deb7f66.js b/core/web/assets/main.84f90f8fc23465846aa7.js similarity index 93% rename from core/web/assets/main.2f351fafaaf99deb7f66.js rename to core/web/assets/main.84f90f8fc23465846aa7.js index 0d616c49de..f9770459be 100644 --- a/core/web/assets/main.2f351fafaaf99deb7f66.js +++ b/core/web/assets/main.84f90f8fc23465846aa7.js @@ -171,4 +171,4 @@ object-assign */ Object.defineProperty(t,"__esModule",{value:!0}),"undefined"==typeof window||"function"!=typeof MessageChannel){var n,r,i,a,o,s=null,u=null,c=function(){if(null!==s)try{var e=t.unstable_now();s(!0,e),s=null}catch(n){throw setTimeout(c,0),n}},l=Date.now();t.unstable_now=function(){return Date.now()-l},n=function(e){null!==s?setTimeout(n,0,e):(s=e,setTimeout(c,0))},r=function(e,t){u=setTimeout(e,t)},i=function(){clearTimeout(u)},a=function(){return!1},o=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,d=window.Date,h=window.setTimeout,p=window.clearTimeout;if("undefined"!=typeof console){var b=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof b&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var m=d.now();t.unstable_now=function(){return d.now()-m}}var g=!1,v=null,y=-1,w=5,_=0;a=function(){return t.unstable_now()>=_},o=function(){},t.unstable_forceFrameRate=function(e){0>e||125M(o,n))void 0!==u&&0>M(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[a]=n,r=a);else if(void 0!==u&&0>M(u,n))e[r]=u,e[s]=n,r=s;else break a}}return t}return null}function M(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var O=[],A=[],L=1,C=null,I=3,D=!1,N=!1,P=!1;function R(e){for(var t=x(A);null!==t;){if(null===t.callback)T(A);else if(t.startTime<=e)T(A),t.sortIndex=t.expirationTime,k(O,t);else break;t=x(A)}}function j(e){if(P=!1,R(e),!N){if(null!==x(O))N=!0,n(F);else{var t=x(A);null!==t&&r(j,t.startTime-e)}}}function F(e,n){N=!1,P&&(P=!1,i()),D=!0;var o=I;try{for(R(n),C=x(O);null!==C&&(!(C.expirationTime>n)||e&&!a());){var s=C.callback;if(null!==s){C.callback=null,I=C.priorityLevel;var u=s(C.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?C.callback=u:C===x(O)&&T(O),R(n)}else T(O);C=x(O)}if(null!==C)var c=!0;else{var l=x(A);null!==l&&r(j,l.startTime-n),c=!1}return c}finally{C=null,I=o,D=!1}}function Y(e){switch(e){case 1:return -1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var B=o;t.unstable_ImmediatePriority=1,t.unstable_UserBlockingPriority=2,t.unstable_NormalPriority=3,t.unstable_IdlePriority=5,t.unstable_LowPriority=4,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=I;I=e;try{return t()}finally{I=n}},t.unstable_next=function(e){switch(I){case 1:case 2:case 3:var t=3;break;default:t=I}var n=I;I=t;try{return e()}finally{I=n}},t.unstable_scheduleCallback=function(e,a,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0s?(e.sortIndex=u,k(A,e),null===x(O)&&e===x(A)&&(P?i():P=!0,r(j,u-s))):(e.sortIndex=o,k(O,e),N||D||(N=!0,n(F))),e},t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_wrapCallback=function(e){var t=I;return function(){var n=I;I=t;try{return e.apply(this,arguments)}finally{I=n}}},t.unstable_getCurrentPriorityLevel=function(){return I},t.unstable_shouldYield=function(){var e=t.unstable_now();R(e);var n=x(O);return n!==C&&null!==C&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function c(e,t,n){var r=t.length-1;if(r=0?(i>0&&(e.lastNeed=i-1),i):--r=0?(i>0&&(e.lastNeed=i-2),i):--r=0?(i>0&&(2===i?i=0:e.lastNeed=i-3),i):0}function l(e,t,n){if((192&t[0])!=128)return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if((192&t[1])!=128)return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&(192&t[2])!=128)return e.lastNeed=2,"�"}}function f(e){var t=this.lastTotal-this.lastNeed,n=l(this,e,t);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):void(e.copy(this.lastChar,t,0,e.length),this.lastNeed-=e.length)}function d(e,t){var n=c(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)}function h(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+"�":t}function p(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function b(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function m(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function g(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function v(e){return e.toString(this.encoding)}function y(e){return e&&e.length?this.write(e):""}t.s=s,s.prototype.write=function(e){var t,n;if(0===e.length)return"";if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n */ var r=n(48764),i=r.Buffer;function a(e,t){for(var n in e)t[n]=e[n]}function o(e,t,n){return i(e,t,n)}i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow?e.exports=r:(a(r,t),t.Buffer=o),o.prototype=Object.create(i.prototype),a(i,o),o.from=function(e,t,n){if("number"==typeof e)throw TypeError("Argument must not be a number");return i(e,t,n)},o.alloc=function(e,t,n){if("number"!=typeof e)throw TypeError("Argument must be a number");var r=i(e);return void 0!==t?"string"==typeof n?r.fill(t,n):r.fill(t):r.fill(0),r},o.allocUnsafe=function(e){if("number"!=typeof e)throw TypeError("Argument must be a number");return i(e)},o.allocUnsafeSlow=function(e){if("number"!=typeof e)throw TypeError("Argument must be a number");return r.SlowBuffer(e)}},93379(e,t,n){"use strict";var r,i,a=function(){return void 0===r&&(r=Boolean(window&&document&&document.all&&!window.atob)),r},o=(i={},function(e){if(void 0===i[e]){var t=document.querySelector(e);if(window.HTMLIFrameElement&&t instanceof window.HTMLIFrameElement)try{t=t.contentDocument.head}catch(n){t=null}i[e]=t}return i[e]}),s=[];function u(e){for(var t=-1,n=0;nOq});var r,i,a,o,s,u,c,l=n(67294),f=n.t(l,2),d=n(39814),h=n(5977),p=n(57209),b=n(32316),m=n(95880),g=n(17051),v=n(71381),y=n(81701),w=n(3022),_=n(60323),E=n(87591),S=n(25649),k=n(28902),x=n(71426),T=n(48884),M=n(94184),O=n.n(M),A=n(37703),L=n(73935),C=function(){if("undefined"!=typeof Map)return Map;function e(e,t){var n=-1;return e.some(function(e,r){return e[0]===t&&(n=r,!0)}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(t){var n=e(this.__entries__,t),r=this.__entries__[n];return r&&r[1]},t.prototype.set=function(t,n){var r=e(this.__entries__,t);~r?this.__entries__[r][1]=n:this.__entries__.push([t,n])},t.prototype.delete=function(t){var n=this.__entries__,r=e(n,t);~r&&n.splice(r,1)},t.prototype.has=function(t){return!!~e(this.__entries__,t)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(e,t){void 0===t&&(t=null);for(var n=0,r=this.__entries__;n0},e.prototype.connect_=function(){I&&!this.connected_&&(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),Y?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){I&&this.connected_&&(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(e){var t=e.propertyName,n=void 0===t?"":t;F.some(function(e){return!!~n.indexOf(e)})&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),U=function(e,t){for(var n=0,r=Object.keys(t);n0},e}(),er="undefined"!=typeof WeakMap?new WeakMap:new C,ei=function(){function e(t){if(!(this instanceof e))throw TypeError("Cannot call a class as a function.");if(!arguments.length)throw TypeError("1 argument required, but only 0 present.");var n=B.getInstance(),r=new en(t,n,this);er.set(this,r)}return e}();["observe","unobserve","disconnect"].forEach(function(e){ei.prototype[e]=function(){var t;return(t=er.get(this))[e].apply(t,arguments)}});var ea=void 0!==D.ResizeObserver?D.ResizeObserver:ei;let eo=ea;var es=function(e){var t=[],n=null,r=function(){for(var r=arguments.length,i=Array(r),a=0;a=t||n<0||f&&r>=a}function g(){var e=eb();if(m(e))return v(e);s=setTimeout(g,b(e))}function v(e){return(s=void 0,d&&r)?h(e):(r=i=void 0,o)}function y(){void 0!==s&&clearTimeout(s),c=0,r=u=i=s=void 0}function w(){return void 0===s?o:v(eb())}function _(){var e=eb(),n=m(e);if(r=arguments,i=this,u=e,n){if(void 0===s)return p(u);if(f)return clearTimeout(s),s=setTimeout(g,t),h(u)}return void 0===s&&(s=setTimeout(g,t)),o}return t=ez(t)||0,ed(n)&&(l=!!n.leading,a=(f="maxWait"in n)?eW(ez(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),_.cancel=y,_.flush=w,_}let eq=eV;var eZ="Expected a function";function eX(e,t,n){var r=!0,i=!0;if("function"!=typeof e)throw TypeError(eZ);return ed(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),eq(e,t,{leading:r,maxWait:t,trailing:i})}let eJ=eX;var eQ={debounce:eq,throttle:eJ},e1=function(e){return eQ[e]},e0=function(e){return"function"==typeof e},e2=function(){return"undefined"==typeof window},e3=function(e){return e instanceof Element||e instanceof HTMLDocument};function e4(e){return(e4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function e6(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function e5(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&l.createElement(tG.Z,{variant:"indeterminate",classes:r}))};tK.propTypes={fetchCount:el().number.isRequired};let tV=(0,b.withStyles)(tW)(tK);var tq=n(5536);let tZ=n.p+"ba8bbf16ebf8e1d05bef.svg";function tX(){return(tX=Object.assign||function(e){for(var t=1;t120){for(var d=Math.floor(u/80),h=u%80,p=[],b=0;b0},name:{enumerable:!1},nodes:{enumerable:!1},source:{enumerable:!1},positions:{enumerable:!1},originalError:{enumerable:!1}}),null!=s&&s.stack)?(Object.defineProperty(nf(b),"stack",{value:s.stack,writable:!0,configurable:!0}),nl(b)):(Error.captureStackTrace?Error.captureStackTrace(nf(b),n):Object.defineProperty(nf(b),"stack",{value:Error().stack,writable:!0,configurable:!0}),b)}return ns(n,[{key:"toString",value:function(){return nw(this)}},{key:t4.YF,get:function(){return"Object"}}]),n}(nd(Error));function ny(e){return void 0===e||0===e.length?void 0:e}function nw(e){var t=e.message;if(e.nodes)for(var n=0,r=e.nodes;n",EOF:"",BANG:"!",DOLLAR:"$",AMP:"&",PAREN_L:"(",PAREN_R:")",SPREAD:"...",COLON:":",EQUALS:"=",AT:"@",BRACKET_L:"[",BRACKET_R:"]",BRACE_L:"{",PIPE:"|",BRACE_R:"}",NAME:"Name",INT:"Int",FLOAT:"Float",STRING:"String",BLOCK_STRING:"BlockString",COMMENT:"Comment"}),nx=n(10143),nT=Object.freeze({QUERY:"QUERY",MUTATION:"MUTATION",SUBSCRIPTION:"SUBSCRIPTION",FIELD:"FIELD",FRAGMENT_DEFINITION:"FRAGMENT_DEFINITION",FRAGMENT_SPREAD:"FRAGMENT_SPREAD",INLINE_FRAGMENT:"INLINE_FRAGMENT",VARIABLE_DEFINITION:"VARIABLE_DEFINITION",SCHEMA:"SCHEMA",SCALAR:"SCALAR",OBJECT:"OBJECT",FIELD_DEFINITION:"FIELD_DEFINITION",ARGUMENT_DEFINITION:"ARGUMENT_DEFINITION",INTERFACE:"INTERFACE",UNION:"UNION",ENUM:"ENUM",ENUM_VALUE:"ENUM_VALUE",INPUT_OBJECT:"INPUT_OBJECT",INPUT_FIELD_DEFINITION:"INPUT_FIELD_DEFINITION"}),nM=n(87392),nO=function(){function e(e){var t=new nS.WU(nk.SOF,0,0,0,0,null);this.source=e,this.lastToken=t,this.token=t,this.line=1,this.lineStart=0}var t=e.prototype;return t.advance=function(){return this.lastToken=this.token,this.token=this.lookahead()},t.lookahead=function(){var e,t=this.token;if(t.kind!==nk.EOF)do t=null!==(e=t.next)&&void 0!==e?e:t.next=nC(this,t);while(t.kind===nk.COMMENT)return t},e}();function nA(e){return e===nk.BANG||e===nk.DOLLAR||e===nk.AMP||e===nk.PAREN_L||e===nk.PAREN_R||e===nk.SPREAD||e===nk.COLON||e===nk.EQUALS||e===nk.AT||e===nk.BRACKET_L||e===nk.BRACKET_R||e===nk.BRACE_L||e===nk.PIPE||e===nk.BRACE_R}function nL(e){return isNaN(e)?nk.EOF:e<127?JSON.stringify(String.fromCharCode(e)):'"\\u'.concat(("00"+e.toString(16).toUpperCase()).slice(-4),'"')}function nC(e,t){for(var n=e.source,r=n.body,i=r.length,a=t.end;a31||9===a))return new nS.WU(nk.COMMENT,t,s,n,r,i,o.slice(t+1,s))}function nN(e,t,n,r,i,a){var o=e.body,s=n,u=t,c=!1;if(45===s&&(s=o.charCodeAt(++u)),48===s){if((s=o.charCodeAt(++u))>=48&&s<=57)throw n_(e,u,"Invalid number, unexpected digit after 0: ".concat(nL(s),"."))}else u=nP(e,u,s),s=o.charCodeAt(u);if(46===s&&(c=!0,s=o.charCodeAt(++u),u=nP(e,u,s),s=o.charCodeAt(u)),(69===s||101===s)&&(c=!0,(43===(s=o.charCodeAt(++u))||45===s)&&(s=o.charCodeAt(++u)),u=nP(e,u,s),s=o.charCodeAt(u)),46===s||nU(s))throw n_(e,u,"Invalid number, expected digit but got: ".concat(nL(s),"."));return new nS.WU(c?nk.FLOAT:nk.INT,t,u,r,i,a,o.slice(t,u))}function nP(e,t,n){var r=e.body,i=t,a=n;if(a>=48&&a<=57){do a=r.charCodeAt(++i);while(a>=48&&a<=57)return i}throw n_(e,i,"Invalid number, expected digit but got: ".concat(nL(a),"."))}function nR(e,t,n,r,i){for(var a=e.body,o=t+1,s=o,u=0,c="";o=48&&e<=57?e-48:e>=65&&e<=70?e-55:e>=97&&e<=102?e-87:-1}function nB(e,t,n,r,i){for(var a=e.body,o=a.length,s=t+1,u=0;s!==o&&!isNaN(u=a.charCodeAt(s))&&(95===u||u>=48&&u<=57||u>=65&&u<=90||u>=97&&u<=122);)++s;return new nS.WU(nk.NAME,t,s,n,r,i,a.slice(t,s))}function nU(e){return 95===e||e>=65&&e<=90||e>=97&&e<=122}function nH(e,t){return new n$(e,t).parseDocument()}var n$=function(){function e(e,t){var n=(0,nx.T)(e)?e:new nx.H(e);this._lexer=new nO(n),this._options=t}var t=e.prototype;return t.parseName=function(){var e=this.expectToken(nk.NAME);return{kind:nE.h.NAME,value:e.value,loc:this.loc(e)}},t.parseDocument=function(){var e=this._lexer.token;return{kind:nE.h.DOCUMENT,definitions:this.many(nk.SOF,this.parseDefinition,nk.EOF),loc:this.loc(e)}},t.parseDefinition=function(){if(this.peek(nk.NAME))switch(this._lexer.token.value){case"query":case"mutation":case"subscription":return this.parseOperationDefinition();case"fragment":return this.parseFragmentDefinition();case"schema":case"scalar":case"type":case"interface":case"union":case"enum":case"input":case"directive":return this.parseTypeSystemDefinition();case"extend":return this.parseTypeSystemExtension()}else if(this.peek(nk.BRACE_L))return this.parseOperationDefinition();else if(this.peekDescription())return this.parseTypeSystemDefinition();throw this.unexpected()},t.parseOperationDefinition=function(){var e,t=this._lexer.token;if(this.peek(nk.BRACE_L))return{kind:nE.h.OPERATION_DEFINITION,operation:"query",name:void 0,variableDefinitions:[],directives:[],selectionSet:this.parseSelectionSet(),loc:this.loc(t)};var n=this.parseOperationType();return this.peek(nk.NAME)&&(e=this.parseName()),{kind:nE.h.OPERATION_DEFINITION,operation:n,name:e,variableDefinitions:this.parseVariableDefinitions(),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseOperationType=function(){var e=this.expectToken(nk.NAME);switch(e.value){case"query":return"query";case"mutation":return"mutation";case"subscription":return"subscription"}throw this.unexpected(e)},t.parseVariableDefinitions=function(){return this.optionalMany(nk.PAREN_L,this.parseVariableDefinition,nk.PAREN_R)},t.parseVariableDefinition=function(){var e=this._lexer.token;return{kind:nE.h.VARIABLE_DEFINITION,variable:this.parseVariable(),type:(this.expectToken(nk.COLON),this.parseTypeReference()),defaultValue:this.expectOptionalToken(nk.EQUALS)?this.parseValueLiteral(!0):void 0,directives:this.parseDirectives(!0),loc:this.loc(e)}},t.parseVariable=function(){var e=this._lexer.token;return this.expectToken(nk.DOLLAR),{kind:nE.h.VARIABLE,name:this.parseName(),loc:this.loc(e)}},t.parseSelectionSet=function(){var e=this._lexer.token;return{kind:nE.h.SELECTION_SET,selections:this.many(nk.BRACE_L,this.parseSelection,nk.BRACE_R),loc:this.loc(e)}},t.parseSelection=function(){return this.peek(nk.SPREAD)?this.parseFragment():this.parseField()},t.parseField=function(){var e,t,n=this._lexer.token,r=this.parseName();return this.expectOptionalToken(nk.COLON)?(e=r,t=this.parseName()):t=r,{kind:nE.h.FIELD,alias:e,name:t,arguments:this.parseArguments(!1),directives:this.parseDirectives(!1),selectionSet:this.peek(nk.BRACE_L)?this.parseSelectionSet():void 0,loc:this.loc(n)}},t.parseArguments=function(e){var t=e?this.parseConstArgument:this.parseArgument;return this.optionalMany(nk.PAREN_L,t,nk.PAREN_R)},t.parseArgument=function(){var e=this._lexer.token,t=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.ARGUMENT,name:t,value:this.parseValueLiteral(!1),loc:this.loc(e)}},t.parseConstArgument=function(){var e=this._lexer.token;return{kind:nE.h.ARGUMENT,name:this.parseName(),value:(this.expectToken(nk.COLON),this.parseValueLiteral(!0)),loc:this.loc(e)}},t.parseFragment=function(){var e=this._lexer.token;this.expectToken(nk.SPREAD);var t=this.expectOptionalKeyword("on");return!t&&this.peek(nk.NAME)?{kind:nE.h.FRAGMENT_SPREAD,name:this.parseFragmentName(),directives:this.parseDirectives(!1),loc:this.loc(e)}:{kind:nE.h.INLINE_FRAGMENT,typeCondition:t?this.parseNamedType():void 0,directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(e)}},t.parseFragmentDefinition=function(){var e,t=this._lexer.token;return(this.expectKeyword("fragment"),(null===(e=this._options)||void 0===e?void 0:e.experimentalFragmentVariables)===!0)?{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),variableDefinitions:this.parseVariableDefinitions(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}:{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseFragmentName=function(){if("on"===this._lexer.token.value)throw this.unexpected();return this.parseName()},t.parseValueLiteral=function(e){var t=this._lexer.token;switch(t.kind){case nk.BRACKET_L:return this.parseList(e);case nk.BRACE_L:return this.parseObject(e);case nk.INT:return this._lexer.advance(),{kind:nE.h.INT,value:t.value,loc:this.loc(t)};case nk.FLOAT:return this._lexer.advance(),{kind:nE.h.FLOAT,value:t.value,loc:this.loc(t)};case nk.STRING:case nk.BLOCK_STRING:return this.parseStringLiteral();case nk.NAME:switch(this._lexer.advance(),t.value){case"true":return{kind:nE.h.BOOLEAN,value:!0,loc:this.loc(t)};case"false":return{kind:nE.h.BOOLEAN,value:!1,loc:this.loc(t)};case"null":return{kind:nE.h.NULL,loc:this.loc(t)};default:return{kind:nE.h.ENUM,value:t.value,loc:this.loc(t)}}case nk.DOLLAR:if(!e)return this.parseVariable()}throw this.unexpected()},t.parseStringLiteral=function(){var e=this._lexer.token;return this._lexer.advance(),{kind:nE.h.STRING,value:e.value,block:e.kind===nk.BLOCK_STRING,loc:this.loc(e)}},t.parseList=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseValueLiteral(e)};return{kind:nE.h.LIST,values:this.any(nk.BRACKET_L,r,nk.BRACKET_R),loc:this.loc(n)}},t.parseObject=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseObjectField(e)};return{kind:nE.h.OBJECT,fields:this.any(nk.BRACE_L,r,nk.BRACE_R),loc:this.loc(n)}},t.parseObjectField=function(e){var t=this._lexer.token,n=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.OBJECT_FIELD,name:n,value:this.parseValueLiteral(e),loc:this.loc(t)}},t.parseDirectives=function(e){for(var t=[];this.peek(nk.AT);)t.push(this.parseDirective(e));return t},t.parseDirective=function(e){var t=this._lexer.token;return this.expectToken(nk.AT),{kind:nE.h.DIRECTIVE,name:this.parseName(),arguments:this.parseArguments(e),loc:this.loc(t)}},t.parseTypeReference=function(){var e,t=this._lexer.token;return(this.expectOptionalToken(nk.BRACKET_L)?(e=this.parseTypeReference(),this.expectToken(nk.BRACKET_R),e={kind:nE.h.LIST_TYPE,type:e,loc:this.loc(t)}):e=this.parseNamedType(),this.expectOptionalToken(nk.BANG))?{kind:nE.h.NON_NULL_TYPE,type:e,loc:this.loc(t)}:e},t.parseNamedType=function(){var e=this._lexer.token;return{kind:nE.h.NAMED_TYPE,name:this.parseName(),loc:this.loc(e)}},t.parseTypeSystemDefinition=function(){var e=this.peekDescription()?this._lexer.lookahead():this._lexer.token;if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaDefinition();case"scalar":return this.parseScalarTypeDefinition();case"type":return this.parseObjectTypeDefinition();case"interface":return this.parseInterfaceTypeDefinition();case"union":return this.parseUnionTypeDefinition();case"enum":return this.parseEnumTypeDefinition();case"input":return this.parseInputObjectTypeDefinition();case"directive":return this.parseDirectiveDefinition()}throw this.unexpected(e)},t.peekDescription=function(){return this.peek(nk.STRING)||this.peek(nk.BLOCK_STRING)},t.parseDescription=function(){if(this.peekDescription())return this.parseStringLiteral()},t.parseSchemaDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("schema");var n=this.parseDirectives(!0),r=this.many(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);return{kind:nE.h.SCHEMA_DEFINITION,description:t,directives:n,operationTypes:r,loc:this.loc(e)}},t.parseOperationTypeDefinition=function(){var e=this._lexer.token,t=this.parseOperationType();this.expectToken(nk.COLON);var n=this.parseNamedType();return{kind:nE.h.OPERATION_TYPE_DEFINITION,operation:t,type:n,loc:this.loc(e)}},t.parseScalarTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("scalar");var n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.SCALAR_TYPE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("type");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.OBJECT_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseImplementsInterfaces=function(){var e;if(!this.expectOptionalKeyword("implements"))return[];if((null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLImplementsInterfaces)===!0){var t=[];this.expectOptionalToken(nk.AMP);do t.push(this.parseNamedType());while(this.expectOptionalToken(nk.AMP)||this.peek(nk.NAME))return t}return this.delimitedMany(nk.AMP,this.parseNamedType)},t.parseFieldsDefinition=function(){var e;return(null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLEmptyFields)===!0&&this.peek(nk.BRACE_L)&&this._lexer.lookahead().kind===nk.BRACE_R?(this._lexer.advance(),this._lexer.advance(),[]):this.optionalMany(nk.BRACE_L,this.parseFieldDefinition,nk.BRACE_R)},t.parseFieldDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseArgumentDefs();this.expectToken(nk.COLON);var i=this.parseTypeReference(),a=this.parseDirectives(!0);return{kind:nE.h.FIELD_DEFINITION,description:t,name:n,arguments:r,type:i,directives:a,loc:this.loc(e)}},t.parseArgumentDefs=function(){return this.optionalMany(nk.PAREN_L,this.parseInputValueDef,nk.PAREN_R)},t.parseInputValueDef=function(){var e,t=this._lexer.token,n=this.parseDescription(),r=this.parseName();this.expectToken(nk.COLON);var i=this.parseTypeReference();this.expectOptionalToken(nk.EQUALS)&&(e=this.parseValueLiteral(!0));var a=this.parseDirectives(!0);return{kind:nE.h.INPUT_VALUE_DEFINITION,description:n,name:r,type:i,defaultValue:e,directives:a,loc:this.loc(t)}},t.parseInterfaceTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("interface");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.INTERFACE_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseUnionTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("union");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseUnionMemberTypes();return{kind:nE.h.UNION_TYPE_DEFINITION,description:t,name:n,directives:r,types:i,loc:this.loc(e)}},t.parseUnionMemberTypes=function(){return this.expectOptionalToken(nk.EQUALS)?this.delimitedMany(nk.PIPE,this.parseNamedType):[]},t.parseEnumTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("enum");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseEnumValuesDefinition();return{kind:nE.h.ENUM_TYPE_DEFINITION,description:t,name:n,directives:r,values:i,loc:this.loc(e)}},t.parseEnumValuesDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseEnumValueDefinition,nk.BRACE_R)},t.parseEnumValueDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.ENUM_VALUE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseInputObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("input");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseInputFieldsDefinition();return{kind:nE.h.INPUT_OBJECT_TYPE_DEFINITION,description:t,name:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInputFieldsDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseInputValueDef,nk.BRACE_R)},t.parseTypeSystemExtension=function(){var e=this._lexer.lookahead();if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaExtension();case"scalar":return this.parseScalarTypeExtension();case"type":return this.parseObjectTypeExtension();case"interface":return this.parseInterfaceTypeExtension();case"union":return this.parseUnionTypeExtension();case"enum":return this.parseEnumTypeExtension();case"input":return this.parseInputObjectTypeExtension()}throw this.unexpected(e)},t.parseSchemaExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("schema");var t=this.parseDirectives(!0),n=this.optionalMany(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);if(0===t.length&&0===n.length)throw this.unexpected();return{kind:nE.h.SCHEMA_EXTENSION,directives:t,operationTypes:n,loc:this.loc(e)}},t.parseScalarTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("scalar");var t=this.parseName(),n=this.parseDirectives(!0);if(0===n.length)throw this.unexpected();return{kind:nE.h.SCALAR_TYPE_EXTENSION,name:t,directives:n,loc:this.loc(e)}},t.parseObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("type");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.OBJECT_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInterfaceTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("interface");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.INTERFACE_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseUnionTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("union");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseUnionMemberTypes();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.UNION_TYPE_EXTENSION,name:t,directives:n,types:r,loc:this.loc(e)}},t.parseEnumTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("enum");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseEnumValuesDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.ENUM_TYPE_EXTENSION,name:t,directives:n,values:r,loc:this.loc(e)}},t.parseInputObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("input");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseInputFieldsDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.INPUT_OBJECT_TYPE_EXTENSION,name:t,directives:n,fields:r,loc:this.loc(e)}},t.parseDirectiveDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("directive"),this.expectToken(nk.AT);var n=this.parseName(),r=this.parseArgumentDefs(),i=this.expectOptionalKeyword("repeatable");this.expectKeyword("on");var a=this.parseDirectiveLocations();return{kind:nE.h.DIRECTIVE_DEFINITION,description:t,name:n,arguments:r,repeatable:i,locations:a,loc:this.loc(e)}},t.parseDirectiveLocations=function(){return this.delimitedMany(nk.PIPE,this.parseDirectiveLocation)},t.parseDirectiveLocation=function(){var e=this._lexer.token,t=this.parseName();if(void 0!==nT[t.value])return t;throw this.unexpected(e)},t.loc=function(e){var t;if((null===(t=this._options)||void 0===t?void 0:t.noLocation)!==!0)return new nS.Ye(e,this._lexer.lastToken,this._lexer.source)},t.peek=function(e){return this._lexer.token.kind===e},t.expectToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t;throw n_(this._lexer.source,t.start,"Expected ".concat(nG(e),", found ").concat(nz(t),"."))},t.expectOptionalToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t},t.expectKeyword=function(e){var t=this._lexer.token;if(t.kind===nk.NAME&&t.value===e)this._lexer.advance();else throw n_(this._lexer.source,t.start,'Expected "'.concat(e,'", found ').concat(nz(t),"."))},t.expectOptionalKeyword=function(e){var t=this._lexer.token;return t.kind===nk.NAME&&t.value===e&&(this._lexer.advance(),!0)},t.unexpected=function(e){var t=null!=e?e:this._lexer.token;return n_(this._lexer.source,t.start,"Unexpected ".concat(nz(t),"."))},t.any=function(e,t,n){this.expectToken(e);for(var r=[];!this.expectOptionalToken(n);)r.push(t.call(this));return r},t.optionalMany=function(e,t,n){if(this.expectOptionalToken(e)){var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r}return[]},t.many=function(e,t,n){this.expectToken(e);var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r},t.delimitedMany=function(e,t){this.expectOptionalToken(e);var n=[];do n.push(t.call(this));while(this.expectOptionalToken(e))return n},e}();function nz(e){var t=e.value;return nG(e.kind)+(null!=t?' "'.concat(t,'"'):"")}function nG(e){return nA(e)?'"'.concat(e,'"'):e}var nW=new Map,nK=new Map,nV=!0,nq=!1;function nZ(e){return e.replace(/[\s,]+/g," ").trim()}function nX(e){return nZ(e.source.body.substring(e.start,e.end))}function nJ(e){var t=new Set,n=[];return e.definitions.forEach(function(e){if("FragmentDefinition"===e.kind){var r=e.name.value,i=nX(e.loc),a=nK.get(r);a&&!a.has(i)?nV&&console.warn("Warning: fragment with name "+r+" already exists.\ngraphql-tag enforces all fragment names across your application to be unique; read more about\nthis in the docs: http://dev.apollodata.com/core/fragments.html#unique-names"):a||nK.set(r,a=new Set),a.add(i),t.has(i)||(t.add(i),n.push(e))}else n.push(e)}),(0,t0.pi)((0,t0.pi)({},e),{definitions:n})}function nQ(e){var t=new Set(e.definitions);t.forEach(function(e){e.loc&&delete e.loc,Object.keys(e).forEach(function(n){var r=e[n];r&&"object"==typeof r&&t.add(r)})});var n=e.loc;return n&&(delete n.startToken,delete n.endToken),e}function n1(e){var t=nZ(e);if(!nW.has(t)){var n=nH(e,{experimentalFragmentVariables:nq,allowLegacyFragmentVariables:nq});if(!n||"Document"!==n.kind)throw Error("Not a valid GraphQL document.");nW.set(t,nQ(nJ(n)))}return nW.get(t)}function n0(e){for(var t=[],n=1;n, or pass an ApolloClient instance in via options.'):(0,n9.kG)(!!n,32),n}var rp=n(10542),rb=n(53712),rm=n(21436),rg=Object.prototype.hasOwnProperty;function rv(e,t){return void 0===t&&(t=Object.create(null)),ry(rh(t.client),e).useQuery(t)}function ry(e,t){var n=(0,l.useRef)();n.current&&e===n.current.client&&t===n.current.query||(n.current=new rw(e,t,n.current));var r=n.current,i=(0,l.useState)(0),a=(i[0],i[1]);return r.forceUpdate=function(){a(function(e){return e+1})},r}var rw=function(){function e(e,t,n){this.client=e,this.query=t,this.ssrDisabledResult=(0,rp.J)({loading:!0,data:void 0,error:void 0,networkStatus:ru.I.loading}),this.skipStandbyResult=(0,rp.J)({loading:!1,data:void 0,error:void 0,networkStatus:ru.I.ready}),this.toQueryResultCache=new(n7.mr?WeakMap:Map),rd(t,r.Query);var i=n&&n.result,a=i&&i.data;a&&(this.previousData=a)}return e.prototype.forceUpdate=function(){__DEV__&&n9.kG.warn("Calling default no-op implementation of InternalState#forceUpdate")},e.prototype.executeQuery=function(e){var t,n=this;e.query&&Object.assign(this,{query:e.query}),this.watchQueryOptions=this.createWatchQueryOptions(this.queryHookOptions=e);var r=this.observable.reobserveAsConcast(this.getObsQueryOptions());return this.previousData=(null===(t=this.result)||void 0===t?void 0:t.data)||this.previousData,this.result=void 0,this.forceUpdate(),new Promise(function(e){var t;r.subscribe({next:function(e){t=e},error:function(){e(n.toQueryResult(n.observable.getCurrentResult()))},complete:function(){e(n.toQueryResult(t))}})})},e.prototype.useQuery=function(e){var t=this;this.renderPromises=(0,l.useContext)((0,ro.K)()).renderPromises,this.useOptions(e);var n=this.useObservableQuery(),r=rt((0,l.useCallback)(function(){if(t.renderPromises)return function(){};var e=function(){var e=t.result,r=n.getCurrentResult();!(e&&e.loading===r.loading&&e.networkStatus===r.networkStatus&&(0,ri.D)(e.data,r.data))&&t.setResult(r)},r=function(a){var o=n.last;i.unsubscribe();try{n.resetLastResults(),i=n.subscribe(e,r)}finally{n.last=o}if(!rg.call(a,"graphQLErrors"))throw a;var s=t.result;(!s||s&&s.loading||!(0,ri.D)(a,s.error))&&t.setResult({data:s&&s.data,error:a,loading:!1,networkStatus:ru.I.error})},i=n.subscribe(e,r);return function(){return setTimeout(function(){return i.unsubscribe()})}},[n,this.renderPromises,this.client.disableNetworkFetches,]),function(){return t.getCurrentResult()},function(){return t.getCurrentResult()});return this.unsafeHandlePartialRefetch(r),this.toQueryResult(r)},e.prototype.useOptions=function(t){var n,r=this.createWatchQueryOptions(this.queryHookOptions=t),i=this.watchQueryOptions;!(0,ri.D)(r,i)&&(this.watchQueryOptions=r,i&&this.observable&&(this.observable.reobserve(this.getObsQueryOptions()),this.previousData=(null===(n=this.result)||void 0===n?void 0:n.data)||this.previousData,this.result=void 0)),this.onCompleted=t.onCompleted||e.prototype.onCompleted,this.onError=t.onError||e.prototype.onError,(this.renderPromises||this.client.disableNetworkFetches)&&!1===this.queryHookOptions.ssr&&!this.queryHookOptions.skip?this.result=this.ssrDisabledResult:this.queryHookOptions.skip||"standby"===this.watchQueryOptions.fetchPolicy?this.result=this.skipStandbyResult:(this.result===this.ssrDisabledResult||this.result===this.skipStandbyResult)&&(this.result=void 0)},e.prototype.getObsQueryOptions=function(){var e=[],t=this.client.defaultOptions.watchQuery;return t&&e.push(t),this.queryHookOptions.defaultOptions&&e.push(this.queryHookOptions.defaultOptions),e.push((0,rb.o)(this.observable&&this.observable.options,this.watchQueryOptions)),e.reduce(ra.J)},e.prototype.createWatchQueryOptions=function(e){void 0===e&&(e={});var t,n=e.skip,r=Object.assign((e.ssr,e.onCompleted,e.onError,e.defaultOptions,(0,t0._T)(e,["skip","ssr","onCompleted","onError","defaultOptions"])),{query:this.query});if(this.renderPromises&&("network-only"===r.fetchPolicy||"cache-and-network"===r.fetchPolicy)&&(r.fetchPolicy="cache-first"),r.variables||(r.variables={}),n){var i=r.fetchPolicy,a=void 0===i?this.getDefaultFetchPolicy():i,o=r.initialFetchPolicy;Object.assign(r,{initialFetchPolicy:void 0===o?a:o,fetchPolicy:"standby"})}else r.fetchPolicy||(r.fetchPolicy=(null===(t=this.observable)||void 0===t?void 0:t.options.initialFetchPolicy)||this.getDefaultFetchPolicy());return r},e.prototype.getDefaultFetchPolicy=function(){var e,t;return(null===(e=this.queryHookOptions.defaultOptions)||void 0===e?void 0:e.fetchPolicy)||(null===(t=this.client.defaultOptions.watchQuery)||void 0===t?void 0:t.fetchPolicy)||"cache-first"},e.prototype.onCompleted=function(e){},e.prototype.onError=function(e){},e.prototype.useObservableQuery=function(){var e=this.observable=this.renderPromises&&this.renderPromises.getSSRObservable(this.watchQueryOptions)||this.observable||this.client.watchQuery(this.getObsQueryOptions());this.obsQueryFields=(0,l.useMemo)(function(){return{refetch:e.refetch.bind(e),reobserve:e.reobserve.bind(e),fetchMore:e.fetchMore.bind(e),updateQuery:e.updateQuery.bind(e),startPolling:e.startPolling.bind(e),stopPolling:e.stopPolling.bind(e),subscribeToMore:e.subscribeToMore.bind(e)}},[e]);var t=!(!1===this.queryHookOptions.ssr||this.queryHookOptions.skip);return this.renderPromises&&t&&(this.renderPromises.registerSSRObservable(e),e.getCurrentResult().loading&&this.renderPromises.addObservableQueryPromise(e)),e},e.prototype.setResult=function(e){var t=this.result;t&&t.data&&(this.previousData=t.data),this.result=e,this.forceUpdate(),this.handleErrorOrCompleted(e)},e.prototype.handleErrorOrCompleted=function(e){var t=this;if(!e.loading){var n=this.toApolloError(e);Promise.resolve().then(function(){n?t.onError(n):e.data&&t.onCompleted(e.data)}).catch(function(e){__DEV__&&n9.kG.warn(e)})}},e.prototype.toApolloError=function(e){return(0,rm.O)(e.errors)?new rs.cA({graphQLErrors:e.errors}):e.error},e.prototype.getCurrentResult=function(){return this.result||this.handleErrorOrCompleted(this.result=this.observable.getCurrentResult()),this.result},e.prototype.toQueryResult=function(e){var t=this.toQueryResultCache.get(e);if(t)return t;var n=e.data,r=(e.partial,(0,t0._T)(e,["data","partial"]));return this.toQueryResultCache.set(e,t=(0,t0.pi)((0,t0.pi)((0,t0.pi)({data:n},r),this.obsQueryFields),{client:this.client,observable:this.observable,variables:this.observable.variables,called:!this.queryHookOptions.skip,previousData:this.previousData})),!t.error&&(0,rm.O)(e.errors)&&(t.error=new rs.cA({graphQLErrors:e.errors})),t},e.prototype.unsafeHandlePartialRefetch=function(e){e.partial&&this.queryHookOptions.partialRefetch&&!e.loading&&(!e.data||0===Object.keys(e.data).length)&&"cache-only"!==this.observable.options.fetchPolicy&&(Object.assign(e,{loading:!0,networkStatus:ru.I.refetch}),this.observable.refetch())},e}();function r_(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:{};return rv(iH,e)},iz=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"50",10),r=i$({variables:{offset:(t-1)*n,limit:n},fetchPolicy:"network-only"}),i=r.data,a=r.loading,o=r.error;return a?l.createElement(iR,null):o?l.createElement(iD,{error:o}):i?l.createElement(iI,{chains:i.chains.results,page:t,pageSize:n,total:i.chains.metadata.total}):null},iG=n(67932),iW=n(8126),iK="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function iV(e){if(iq())return Intl.DateTimeFormat.supportedLocalesOf(e)[0]}function iq(){return("undefined"==typeof Intl?"undefined":iK(Intl))==="object"&&"function"==typeof Intl.DateTimeFormat}var iZ="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},iX=function(){function e(e,t){for(var n=0;n=i.length)break;s=i[o++]}else{if((o=i.next()).done)break;s=o.value}var s,u=s;if((void 0===e?"undefined":iZ(e))!=="object")return;e=e[u]}return e}},{key:"put",value:function(){for(var e=arguments.length,t=Array(e),n=0;n=o.length)break;c=o[u++]}else{if((u=o.next()).done)break;c=u.value}var c,l=c;"object"!==iZ(a[l])&&(a[l]={}),a=a[l]}return a[i]=r}}]),e}();let i1=iQ;var i0=new i1;function i2(e,t){if(!iq())return function(e){return e.toString()};var n=i4(e),r=JSON.stringify(t),i=i0.get(String(n),r)||i0.put(String(n),r,new Intl.DateTimeFormat(n,t));return function(e){return i.format(e)}}var i3={};function i4(e){var t=e.toString();return i3[t]?i3[t]:i3[t]=iV(e)}var i6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function i5(e){return i8(e)?e:new Date(e)}function i8(e){return e instanceof Date||i9(e)}function i9(e){return(void 0===e?"undefined":i6(e))==="object"&&"function"==typeof e.getTime}var i7=n(54087),ae=n.n(i7);function at(e,t){if(0===e.length)return 0;for(var n=0,r=e.length-1,i=void 0;n<=r;){var a=t(e[i=Math.floor((r+n)/2)]);if(0===a)return i;if(a<0){if((n=i+1)>r)return n}else if((r=i-1)=t.nextUpdateTime)aa(t,this.instances);else break}},scheduleNextTick:function(){var e=this;this.scheduledTick=ae()(function(){e.tick(),e.scheduleNextTick()})},start:function(){this.scheduleNextTick()},stop:function(){ae().cancel(this.scheduledTick)}};function ai(e){var t=an(e.getNextValue(),2),n=t[0],r=t[1];e.setValue(n),e.nextUpdateTime=r}function aa(e,t){ai(e),as(t,e),ao(t,e)}function ao(e,t){var n=au(e,t);e.splice(n,0,t)}function as(e,t){var n=e.indexOf(t);e.splice(n,1)}function au(e,t){var n=t.nextUpdateTime;return at(e,function(e){return e.nextUpdateTime===n?0:e.nextUpdateTime>n?1:-1})}var ac=(0,ec.oneOfType)([(0,ec.shape)({minTime:ec.number,formatAs:ec.string.isRequired}),(0,ec.shape)({test:ec.func,formatAs:ec.string.isRequired}),(0,ec.shape)({minTime:ec.number,format:ec.func.isRequired}),(0,ec.shape)({test:ec.func,format:ec.func.isRequired})]),al=(0,ec.oneOfType)([ec.string,(0,ec.shape)({steps:(0,ec.arrayOf)(ac).isRequired,labels:(0,ec.oneOfType)([ec.string,(0,ec.arrayOf)(ec.string)]).isRequired,round:ec.string})]),af=Object.assign||function(e){for(var t=1;t=0)&&Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function ap(e){var t=e.date,n=e.future,r=e.timeStyle,i=e.round,a=e.minTimeLeft,o=e.tooltip,s=e.component,u=e.container,c=e.wrapperComponent,f=e.wrapperProps,d=e.locale,h=e.locales,p=e.formatVerboseDate,b=e.verboseDateFormat,m=e.updateInterval,g=e.tick,v=ah(e,["date","future","timeStyle","round","minTimeLeft","tooltip","component","container","wrapperComponent","wrapperProps","locale","locales","formatVerboseDate","verboseDateFormat","updateInterval","tick"]),y=(0,l.useMemo)(function(){return d&&(h=[d]),h.concat(iW.Z.getDefaultLocale())},[d,h]),w=(0,l.useMemo)(function(){return new iW.Z(y)},[y]);t=(0,l.useMemo)(function(){return i5(t)},[t]);var _=(0,l.useCallback)(function(){var e=Date.now(),o=void 0;if(n&&e>=t.getTime()&&(e=t.getTime(),o=!0),void 0!==a){var s=t.getTime()-1e3*a;e>s&&(e=s,o=!0)}var u=w.format(t,r,{getTimeToNextUpdate:!0,now:e,future:n,round:i}),c=ad(u,2),l=c[0],f=c[1];return f=o?ag:m||f||6e4,[l,e+f]},[t,n,r,m,i,a,w]),E=(0,l.useRef)();E.current=_;var S=(0,l.useMemo)(_,[]),k=ad(S,2),x=k[0],T=k[1],M=(0,l.useState)(x),O=ad(M,2),A=O[0],L=O[1],C=ad((0,l.useState)(),2),I=C[0],D=C[1],N=(0,l.useRef)();(0,l.useEffect)(function(){if(g)return N.current=ar.add({getNextValue:function(){return E.current()},setValue:L,nextUpdateTime:T}),function(){return N.current.stop()}},[g]),(0,l.useEffect)(function(){if(N.current)N.current.forceUpdate();else{var e=_(),t=ad(e,1)[0];L(t)}},[_]),(0,l.useEffect)(function(){D(!0)},[]);var P=(0,l.useMemo)(function(){if("undefined"!=typeof window)return i2(y,b)},[y,b]),R=(0,l.useMemo)(function(){if("undefined"!=typeof window)return p?p(t):P(t)},[t,p,P]),j=l.createElement(s,af({date:t,verboseDate:I?R:void 0,tooltip:o},v),A),F=c||u;return F?l.createElement(F,af({},f,{verboseDate:I?R:void 0}),j):j}ap.propTypes={date:el().oneOfType([el().instanceOf(Date),el().number]).isRequired,locale:el().string,locales:el().arrayOf(el().string),future:el().bool,timeStyle:al,round:el().string,minTimeLeft:el().number,component:el().elementType.isRequired,tooltip:el().bool.isRequired,formatVerboseDate:el().func,verboseDateFormat:el().object,updateInterval:el().oneOfType([el().number,el().arrayOf(el().shape({threshold:el().number,interval:el().number.isRequired}))]),tick:el().bool,wrapperComponent:el().func,wrapperProps:el().object},ap.defaultProps={locales:[],component:av,tooltip:!0,verboseDateFormat:{weekday:"long",day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"2-digit",second:"2-digit"},tick:!0},ap=l.memo(ap);let ab=ap;var am,ag=31536e9;function av(e){var t=e.date,n=e.verboseDate,r=e.tooltip,i=e.children,a=ah(e,["date","verboseDate","tooltip","children"]),o=(0,l.useMemo)(function(){return t.toISOString()},[t]);return l.createElement("time",af({},a,{dateTime:o,title:r?n:void 0}),i)}av.propTypes={date:el().instanceOf(Date).isRequired,verboseDate:el().string,tooltip:el().bool.isRequired,children:el().string.isRequired};var ay=n(30381),aw=n.n(ay),a_=n(31657);function aE(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function aS(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0?new rs.cA({graphQLErrors:i}):void 0;if(u===s.current.mutationId&&!c.ignoreResults){var f={called:!0,loading:!1,data:r,error:l,client:a};s.current.isMounted&&!(0,ri.D)(s.current.result,f)&&o(s.current.result=f)}var d=e.onCompleted||(null===(n=s.current.options)||void 0===n?void 0:n.onCompleted);return null==d||d(t.data,c),t}).catch(function(t){if(u===s.current.mutationId&&s.current.isMounted){var n,r={loading:!1,error:t,data:void 0,called:!0,client:a};(0,ri.D)(s.current.result,r)||o(s.current.result=r)}var i=e.onError||(null===(n=s.current.options)||void 0===n?void 0:n.onError);if(i)return i(t,c),{data:void 0,errors:t};throw t})},[]),c=(0,l.useCallback)(function(){s.current.isMounted&&o({called:!1,loading:!1,client:n})},[]);return(0,l.useEffect)(function(){return s.current.isMounted=!0,function(){s.current.isMounted=!1}},[]),[u,(0,t0.pi)({reset:c},a)]}var os=n(59067),ou=n(28428),oc=n(11186),ol=n(78513);function of(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var od=function(e){return(0,b.createStyles)({paper:{display:"flex",margin:"".concat(2.5*e.spacing.unit,"px 0"),padding:"".concat(3*e.spacing.unit,"px ").concat(3.5*e.spacing.unit,"px")},content:{flex:1,width:"100%"},actions:of({marginTop:-(1.5*e.spacing.unit),marginLeft:-(4*e.spacing.unit)},e.breakpoints.up("sm"),{marginLeft:0,marginRight:-(1.5*e.spacing.unit)}),itemBlock:{border:"1px solid rgba(224, 224, 224, 1)",borderRadius:e.shape.borderRadius,padding:2*e.spacing.unit,marginTop:e.spacing.unit},itemBlockText:{overflowWrap:"anywhere"}})},oh=(0,b.withStyles)(od)(function(e){var t=e.actions,n=e.children,r=e.classes;return l.createElement(ii.default,{className:r.paper},l.createElement("div",{className:r.content},n),t&&l.createElement("div",{className:r.actions},t))}),op=function(e){var t=e.title;return l.createElement(x.default,{variant:"subtitle2",gutterBottom:!0},t)},ob=function(e){var t=e.children,n=e.value;return l.createElement(x.default,{variant:"body1",noWrap:!0},t||n)},om=(0,b.withStyles)(od)(function(e){var t=e.children,n=e.classes,r=e.value;return l.createElement("div",{className:n.itemBlock},l.createElement(x.default,{variant:"body1",className:n.itemBlockText},t||r))});function og(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]-1}let sq=sV;function sZ(e,t){var n=this.__data__,r=sH(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}let sX=sZ;function sJ(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e-1&&e%1==0&&e<=cC}let cD=cI;var cN="[object Arguments]",cP="[object Array]",cR="[object Boolean]",cj="[object Date]",cF="[object Error]",cY="[object Function]",cB="[object Map]",cU="[object Number]",cH="[object Object]",c$="[object RegExp]",cz="[object Set]",cG="[object String]",cW="[object WeakMap]",cK="[object ArrayBuffer]",cV="[object DataView]",cq="[object Float64Array]",cZ="[object Int8Array]",cX="[object Int16Array]",cJ="[object Int32Array]",cQ="[object Uint8Array]",c1="[object Uint8ClampedArray]",c0="[object Uint16Array]",c2="[object Uint32Array]",c3={};function c4(e){return eD(e)&&cD(e.length)&&!!c3[eC(e)]}c3["[object Float32Array]"]=c3[cq]=c3[cZ]=c3[cX]=c3[cJ]=c3[cQ]=c3[c1]=c3[c0]=c3[c2]=!0,c3[cN]=c3[cP]=c3[cK]=c3[cR]=c3[cV]=c3[cj]=c3[cF]=c3[cY]=c3[cB]=c3[cU]=c3[cH]=c3[c$]=c3[cz]=c3[cG]=c3[cW]=!1;let c6=c4;function c5(e){return function(t){return e(t)}}let c8=c5;var c9=n(79730),c7=c9.Z&&c9.Z.isTypedArray,le=c7?c8(c7):c6;let lt=le;var ln=Object.prototype.hasOwnProperty;function lr(e,t){var n=cx(e),r=!n&&cS(e),i=!n&&!r&&(0,cT.Z)(e),a=!n&&!r&&!i&<(e),o=n||r||i||a,s=o?cb(e.length,String):[],u=s.length;for(var c in e)(t||ln.call(e,c))&&!(o&&("length"==c||i&&("offset"==c||"parent"==c)||a&&("buffer"==c||"byteLength"==c||"byteOffset"==c)||cL(c,u)))&&s.push(c);return s}let li=lr;var la=Object.prototype;function lo(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||la)}let ls=lo;var lu=sT(Object.keys,Object);let lc=lu;var ll=Object.prototype.hasOwnProperty;function lf(e){if(!ls(e))return lc(e);var t=[];for(var n in Object(e))ll.call(e,n)&&"constructor"!=n&&t.push(n);return t}let ld=lf;function lh(e){return null!=e&&cD(e.length)&&!ur(e)}let lp=lh;function lb(e){return lp(e)?li(e):ld(e)}let lm=lb;function lg(e,t){return e&&ch(t,lm(t),e)}let lv=lg;function ly(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}let lw=ly;var l_=Object.prototype.hasOwnProperty;function lE(e){if(!ed(e))return lw(e);var t=ls(e),n=[];for(var r in e)"constructor"==r&&(t||!l_.call(e,r))||n.push(r);return n}let lS=lE;function lk(e){return lp(e)?li(e,!0):lS(e)}let lx=lk;function lT(e,t){return e&&ch(t,lx(t),e)}let lM=lT;var lO=n(42896);function lA(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n=0||(i[n]=e[n]);return i}function hu(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}var hc=function(e){return Array.isArray(e)&&0===e.length},hl=function(e){return"function"==typeof e},hf=function(e){return null!==e&&"object"==typeof e},hd=function(e){return String(Math.floor(Number(e)))===e},hh=function(e){return"[object String]"===Object.prototype.toString.call(e)},hp=function(e){return 0===l.Children.count(e)},hb=function(e){return hf(e)&&hl(e.then)};function hm(e,t,n,r){void 0===r&&(r=0);for(var i=d8(t);e&&r=0?[]:{}}}return(0===a?e:i)[o[a]]===n?e:(void 0===n?delete i[o[a]]:i[o[a]]=n,0===a&&void 0===n&&delete r[o[a]],r)}function hv(e,t,n,r){void 0===n&&(n=new WeakMap),void 0===r&&(r={});for(var i=0,a=Object.keys(e);i0?t.map(function(t){return x(t,hm(e,t))}):[Promise.resolve("DO_NOT_DELETE_YOU_WILL_BE_FIRED")]).then(function(e){return e.reduce(function(e,n,r){return"DO_NOT_DELETE_YOU_WILL_BE_FIRED"===n||n&&(e=hg(e,t[r],n)),e},{})})},[x]),M=(0,l.useCallback)(function(e){return Promise.all([T(e),h.validationSchema?k(e):{},h.validate?S(e):{}]).then(function(e){var t=e[0],n=e[1],r=e[2];return sk.all([t,n,r],{arrayMerge:hL})})},[h.validate,h.validationSchema,T,S,k]),O=hN(function(e){return void 0===e&&(e=_.values),E({type:"SET_ISVALIDATING",payload:!0}),M(e).then(function(e){return v.current&&(E({type:"SET_ISVALIDATING",payload:!1}),sd()(_.errors,e)||E({type:"SET_ERRORS",payload:e})),e})});(0,l.useEffect)(function(){o&&!0===v.current&&sd()(p.current,h.initialValues)&&O(p.current)},[o,O]);var A=(0,l.useCallback)(function(e){var t=e&&e.values?e.values:p.current,n=e&&e.errors?e.errors:b.current?b.current:h.initialErrors||{},r=e&&e.touched?e.touched:m.current?m.current:h.initialTouched||{},i=e&&e.status?e.status:g.current?g.current:h.initialStatus;p.current=t,b.current=n,m.current=r,g.current=i;var a=function(){E({type:"RESET_FORM",payload:{isSubmitting:!!e&&!!e.isSubmitting,errors:n,touched:r,status:i,values:t,isValidating:!!e&&!!e.isValidating,submitCount:e&&e.submitCount&&"number"==typeof e.submitCount?e.submitCount:0}})};if(h.onReset){var o=h.onReset(_.values,V);hb(o)?o.then(a):a()}else a()},[h.initialErrors,h.initialStatus,h.initialTouched]);(0,l.useEffect)(function(){!0===v.current&&!sd()(p.current,h.initialValues)&&(c&&(p.current=h.initialValues,A()),o&&O(p.current))},[c,h.initialValues,A,o,O]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(b.current,h.initialErrors)&&(b.current=h.initialErrors||hS,E({type:"SET_ERRORS",payload:h.initialErrors||hS}))},[c,h.initialErrors]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(m.current,h.initialTouched)&&(m.current=h.initialTouched||hk,E({type:"SET_TOUCHED",payload:h.initialTouched||hk}))},[c,h.initialTouched]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(g.current,h.initialStatus)&&(g.current=h.initialStatus,E({type:"SET_STATUS",payload:h.initialStatus}))},[c,h.initialStatus,h.initialTouched]);var L=hN(function(e){if(y.current[e]&&hl(y.current[e].validate)){var t=hm(_.values,e),n=y.current[e].validate(t);return hb(n)?(E({type:"SET_ISVALIDATING",payload:!0}),n.then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}}),E({type:"SET_ISVALIDATING",payload:!1})})):(E({type:"SET_FIELD_ERROR",payload:{field:e,value:n}}),Promise.resolve(n))}return h.validationSchema?(E({type:"SET_ISVALIDATING",payload:!0}),k(_.values,e).then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t[e]}}),E({type:"SET_ISVALIDATING",payload:!1})})):Promise.resolve()}),C=(0,l.useCallback)(function(e,t){var n=t.validate;y.current[e]={validate:n}},[]),I=(0,l.useCallback)(function(e){delete y.current[e]},[]),D=hN(function(e,t){return E({type:"SET_TOUCHED",payload:e}),(void 0===t?i:t)?O(_.values):Promise.resolve()}),N=(0,l.useCallback)(function(e){E({type:"SET_ERRORS",payload:e})},[]),P=hN(function(e,t){var r=hl(e)?e(_.values):e;return E({type:"SET_VALUES",payload:r}),(void 0===t?n:t)?O(r):Promise.resolve()}),R=(0,l.useCallback)(function(e,t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}})},[]),j=hN(function(e,t,r){return E({type:"SET_FIELD_VALUE",payload:{field:e,value:t}}),(void 0===r?n:r)?O(hg(_.values,e,t)):Promise.resolve()}),F=(0,l.useCallback)(function(e,t){var n,r=t,i=e;if(!hh(e)){e.persist&&e.persist();var a=e.target?e.target:e.currentTarget,o=a.type,s=a.name,u=a.id,c=a.value,l=a.checked,f=(a.outerHTML,a.options),d=a.multiple;r=t||s||u,i=/number|range/.test(o)?(n=parseFloat(c),isNaN(n)?"":n):/checkbox/.test(o)?hI(hm(_.values,r),l,c):d?hC(f):c}r&&j(r,i)},[j,_.values]),Y=hN(function(e){if(hh(e))return function(t){return F(t,e)};F(e)}),B=hN(function(e,t,n){return void 0===t&&(t=!0),E({type:"SET_FIELD_TOUCHED",payload:{field:e,value:t}}),(void 0===n?i:n)?O(_.values):Promise.resolve()}),U=(0,l.useCallback)(function(e,t){e.persist&&e.persist();var n,r=e.target,i=r.name,a=r.id;r.outerHTML,B(t||i||a,!0)},[B]),H=hN(function(e){if(hh(e))return function(t){return U(t,e)};U(e)}),$=(0,l.useCallback)(function(e){hl(e)?E({type:"SET_FORMIK_STATE",payload:e}):E({type:"SET_FORMIK_STATE",payload:function(){return e}})},[]),z=(0,l.useCallback)(function(e){E({type:"SET_STATUS",payload:e})},[]),G=(0,l.useCallback)(function(e){E({type:"SET_ISSUBMITTING",payload:e})},[]),W=hN(function(){return E({type:"SUBMIT_ATTEMPT"}),O().then(function(e){var t,n=e instanceof Error;if(!n&&0===Object.keys(e).length){try{if(void 0===(t=q()))return}catch(r){throw r}return Promise.resolve(t).then(function(e){return v.current&&E({type:"SUBMIT_SUCCESS"}),e}).catch(function(e){if(v.current)throw E({type:"SUBMIT_FAILURE"}),e})}if(v.current&&(E({type:"SUBMIT_FAILURE"}),n))throw e})}),K=hN(function(e){e&&e.preventDefault&&hl(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hl(e.stopPropagation)&&e.stopPropagation(),W().catch(function(e){console.warn("Warning: An unhandled error was caught from submitForm()",e)})}),V={resetForm:A,validateForm:O,validateField:L,setErrors:N,setFieldError:R,setFieldTouched:B,setFieldValue:j,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,setFormikState:$,submitForm:W},q=hN(function(){return f(_.values,V)}),Z=hN(function(e){e&&e.preventDefault&&hl(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hl(e.stopPropagation)&&e.stopPropagation(),A()}),X=(0,l.useCallback)(function(e){return{value:hm(_.values,e),error:hm(_.errors,e),touched:!!hm(_.touched,e),initialValue:hm(p.current,e),initialTouched:!!hm(m.current,e),initialError:hm(b.current,e)}},[_.errors,_.touched,_.values]),J=(0,l.useCallback)(function(e){return{setValue:function(t,n){return j(e,t,n)},setTouched:function(t,n){return B(e,t,n)},setError:function(t){return R(e,t)}}},[j,B,R]),Q=(0,l.useCallback)(function(e){var t=hf(e),n=t?e.name:e,r=hm(_.values,n),i={name:n,value:r,onChange:Y,onBlur:H};if(t){var a=e.type,o=e.value,s=e.as,u=e.multiple;"checkbox"===a?void 0===o?i.checked=!!r:(i.checked=!!(Array.isArray(r)&&~r.indexOf(o)),i.value=o):"radio"===a?(i.checked=r===o,i.value=o):"select"===s&&u&&(i.value=i.value||[],i.multiple=!0)}return i},[H,Y,_.values]),ee=(0,l.useMemo)(function(){return!sd()(p.current,_.values)},[p.current,_.values]),et=(0,l.useMemo)(function(){return void 0!==s?ee?_.errors&&0===Object.keys(_.errors).length:!1!==s&&hl(s)?s(h):s:_.errors&&0===Object.keys(_.errors).length},[s,ee,_.errors,h]);return ha({},_,{initialValues:p.current,initialErrors:b.current,initialTouched:m.current,initialStatus:g.current,handleBlur:H,handleChange:Y,handleReset:Z,handleSubmit:K,resetForm:A,setErrors:N,setFormikState:$,setFieldTouched:B,setFieldValue:j,setFieldError:R,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,submitForm:W,validateForm:O,validateField:L,isValid:et,dirty:ee,unregisterField:I,registerField:C,getFieldProps:Q,getFieldMeta:X,getFieldHelpers:J,validateOnBlur:i,validateOnChange:n,validateOnMount:o})}function hT(e){var t=hx(e),n=e.component,r=e.children,i=e.render,a=e.innerRef;return(0,l.useImperativeHandle)(a,function(){return t}),(0,l.createElement)(hw,{value:t},n?(0,l.createElement)(n,t):i?i(t):r?hl(r)?r(t):hp(r)?null:l.Children.only(r):null)}function hM(e){var t={};if(e.inner){if(0===e.inner.length)return hg(t,e.path,e.message);for(var n=e.inner,r=Array.isArray(n),i=0,n=r?n:n[Symbol.iterator]();;){if(r){if(i>=n.length)break;a=n[i++]}else{if((i=n.next()).done)break;a=i.value}var a,o=a;hm(t,o.path)||(t=hg(t,o.path,o.message))}}return t}function hO(e,t,n,r){void 0===n&&(n=!1),void 0===r&&(r={});var i=hA(e);return t[n?"validateSync":"validate"](i,{abortEarly:!1,context:r})}function hA(e){var t=Array.isArray(e)?[]:{};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var r=String(n);!0===Array.isArray(e[r])?t[r]=e[r].map(function(e){return!0===Array.isArray(e)||sR(e)?hA(e):""!==e?e:void 0}):sR(e[r])?t[r]=hA(e[r]):t[r]=""!==e[r]?e[r]:void 0}return t}function hL(e,t,n){var r=e.slice();return t.forEach(function(t,i){if(void 0===r[i]){var a=!1!==n.clone&&n.isMergeableObject(t);r[i]=a?sk(Array.isArray(t)?[]:{},t,n):t}else n.isMergeableObject(t)?r[i]=sk(e[i],t,n):-1===e.indexOf(t)&&r.push(t)}),r}function hC(e){return Array.from(e).filter(function(e){return e.selected}).map(function(e){return e.value})}function hI(e,t,n){if("boolean"==typeof e)return Boolean(t);var r=[],i=!1,a=-1;if(Array.isArray(e))r=e,i=(a=e.indexOf(n))>=0;else if(!n||"true"==n||"false"==n)return Boolean(t);return t&&n&&!i?r.concat(n):i?r.slice(0,a).concat(r.slice(a+1)):r}var hD="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?l.useLayoutEffect:l.useEffect;function hN(e){var t=(0,l.useRef)(e);return hD(function(){t.current=e}),(0,l.useCallback)(function(){for(var e=arguments.length,n=Array(e),r=0;re?t:e},0);return Array.from(ha({},e,{length:t+1}))};(function(e){function t(t){var n;return(n=e.call(this,t)||this).updateArrayField=function(e,t,r){var i=n.props,a=i.name;(0,i.formik.setFormikState)(function(n){var i="function"==typeof r?r:e,o="function"==typeof t?t:e,s=hg(n.values,a,e(hm(n.values,a))),u=r?i(hm(n.errors,a)):void 0,c=t?o(hm(n.touched,a)):void 0;return hc(u)&&(u=void 0),hc(c)&&(c=void 0),ha({},n,{values:s,errors:r?hg(n.errors,a,u):n.errors,touched:t?hg(n.touched,a,c):n.touched})})},n.push=function(e){return n.updateArrayField(function(t){return[].concat(hU(t),[hi(e)])},!1,!1)},n.handlePush=function(e){return function(){return n.push(e)}},n.swap=function(e,t){return n.updateArrayField(function(n){return hF(n,e,t)},!0,!0)},n.handleSwap=function(e,t){return function(){return n.swap(e,t)}},n.move=function(e,t){return n.updateArrayField(function(n){return hj(n,e,t)},!0,!0)},n.handleMove=function(e,t){return function(){return n.move(e,t)}},n.insert=function(e,t){return n.updateArrayField(function(n){return hY(n,e,t)},function(t){return hY(t,e,null)},function(t){return hY(t,e,null)})},n.handleInsert=function(e,t){return function(){return n.insert(e,t)}},n.replace=function(e,t){return n.updateArrayField(function(n){return hB(n,e,t)},!1,!1)},n.handleReplace=function(e,t){return function(){return n.replace(e,t)}},n.unshift=function(e){var t=-1;return n.updateArrayField(function(n){var r=n?[e].concat(n):[e];return t<0&&(t=r.length),r},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n}),t},n.handleUnshift=function(e){return function(){return n.unshift(e)}},n.handleRemove=function(e){return function(){return n.remove(e)}},n.handlePop=function(){return function(){return n.pop()}},n.remove=n.remove.bind(hu(n)),n.pop=n.pop.bind(hu(n)),n}ho(t,e);var n=t.prototype;return n.componentDidUpdate=function(e){this.props.validateOnChange&&this.props.formik.validateOnChange&&!sd()(hm(e.formik.values,e.name),hm(this.props.formik.values,this.props.name))&&this.props.formik.validateForm(this.props.formik.values)},n.remove=function(e){var t;return this.updateArrayField(function(n){var r=n?hU(n):[];return t||(t=r[e]),hl(r.splice)&&r.splice(e,1),r},!0,!0),t},n.pop=function(){var e;return this.updateArrayField(function(t){var n=t;return e||(e=n&&n.pop&&n.pop()),n},!0,!0),e},n.render=function(){var e={push:this.push,pop:this.pop,swap:this.swap,move:this.move,insert:this.insert,replace:this.replace,unshift:this.unshift,remove:this.remove,handlePush:this.handlePush,handlePop:this.handlePop,handleSwap:this.handleSwap,handleMove:this.handleMove,handleInsert:this.handleInsert,handleReplace:this.handleReplace,handleUnshift:this.handleUnshift,handleRemove:this.handleRemove},t=this.props,n=t.component,r=t.render,i=t.children,a=t.name,o=hs(t.formik,["validate","validationSchema"]),s=ha({},e,{form:o,name:a});return n?(0,l.createElement)(n,s):r?r(s):i?"function"==typeof i?i(s):hp(i)?null:l.Children.only(i):null},t})(l.Component).defaultProps={validateOnChange:!0},l.Component,l.Component;var hH=n(24802),h$=n(71209),hz=n(91750),hG=n(11970),hW=n(4689),hK=n(67598),hV=function(){return(hV=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&(n[r[i]]=e[r[i]]);return n}function hZ(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form,o=a.isSubmitting,s=a.touched,u=a.errors,c=e.onBlur,l=e.helperText,f=hq(e,["disabled","field","form","onBlur","helperText"]),d=hm(u,i.name),h=hm(s,i.name)&&!!d;return hV(hV({variant:f.variant,error:h,helperText:h?d:l,disabled:null!=t?t:o,onBlur:null!=c?c:function(e){r(null!=e?e:i.name)}},i),f)}function hX(e){var t=e.children,n=hq(e,["children"]);return(0,l.createElement)(iw.Z,hV({},hZ(n)),t)}function hJ(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=(e.type,e.onBlur),s=hq(e,["disabled","field","form","type","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function hQ(e){return(0,l.createElement)(hH.Z,hV({},hJ(e)))}function h1(e){var t,n=e.disabled,r=e.field,i=r.onBlur,a=hq(r,["onBlur"]),o=e.form.isSubmitting,s=(e.type,e.onBlur),u=hq(e,["disabled","field","form","type","onBlur"]);return hV(hV({disabled:null!=n?n:o,indeterminate:!Array.isArray(a.value)&&null==a.value,onBlur:null!=s?s:function(e){i(null!=e?e:a.name)}},a),u)}function h0(e){return(0,l.createElement)(h$.Z,hV({},h1(e)))}function h2(e){var t=e.Label,n=hq(e,["Label"]);return(0,l.createElement)(hz.Z,hV({control:(0,l.createElement)(h$.Z,hV({},h1(n)))},t))}function h3(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hq(e,["disabled","field","form","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h4(e){return(0,l.createElement)(hG.default,hV({},h3(e)))}function h6(e){var t=e.field,n=t.onBlur,r=hq(t,["onBlur"]),i=(e.form,e.onBlur),a=hq(e,["field","form","onBlur"]);return hV(hV({onBlur:null!=i?i:function(e){n(null!=e?e:r.name)}},r),a)}function h5(e){return(0,l.createElement)(hW.Z,hV({},h6(e)))}function h8(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hq(e,["disabled","field","form","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h9(e){return(0,l.createElement)(hK.default,hV({},h8(e)))}hX.displayName="FormikMaterialUITextField",hQ.displayName="FormikMaterialUISwitch",h0.displayName="FormikMaterialUICheckbox",h2.displayName="FormikMaterialUICheckboxWithLabel",h4.displayName="FormikMaterialUISelect",h5.displayName="FormikMaterialUIRadioGroup",h9.displayName="FormikMaterialUIInputBase";try{a=Map}catch(h7){}try{o=Set}catch(pe){}function pt(e,t,n){if(!e||"object"!=typeof e||"function"==typeof e)return e;if(e.nodeType&&"cloneNode"in e)return e.cloneNode(!0);if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return RegExp(e);if(Array.isArray(e))return e.map(pn);if(a&&e instanceof a)return new Map(Array.from(e.entries()));if(o&&e instanceof o)return new Set(Array.from(e.values()));if(e instanceof Object){t.push(e);var r=Object.create(e);for(var i in n.push(r),e){var s=t.findIndex(function(t){return t===e[i]});r[i]=s>-1?n[s]:pt(e[i],t,n)}return r}return e}function pn(e){return pt(e,[],[])}let pr=Object.prototype.toString,pi=Error.prototype.toString,pa=RegExp.prototype.toString,po="undefined"!=typeof Symbol?Symbol.prototype.toString:()=>"",ps=/^Symbol\((.*)\)(.*)$/;function pu(e){if(e!=+e)return"NaN";let t=0===e&&1/e<0;return t?"-0":""+e}function pc(e,t=!1){if(null==e||!0===e||!1===e)return""+e;let n=typeof e;if("number"===n)return pu(e);if("string"===n)return t?`"${e}"`:e;if("function"===n)return"[Function "+(e.name||"anonymous")+"]";if("symbol"===n)return po.call(e).replace(ps,"Symbol($1)");let r=pr.call(e).slice(8,-1);return"Date"===r?isNaN(e.getTime())?""+e:e.toISOString(e):"Error"===r||e instanceof Error?"["+pi.call(e)+"]":"RegExp"===r?pa.call(e):null}function pl(e,t){let n=pc(e,t);return null!==n?n:JSON.stringify(e,function(e,n){let r=pc(this[e],t);return null!==r?r:n},2)}let pf={default:"${path} is invalid",required:"${path} is a required field",oneOf:"${path} must be one of the following values: ${values}",notOneOf:"${path} must not be one of the following values: ${values}",notType({path:e,type:t,value:n,originalValue:r}){let i=null!=r&&r!==n,a=`${e} must be a \`${t}\` type, but the final value was: \`${pl(n,!0)}\``+(i?` (cast from the value \`${pl(r,!0)}\`).`:".");return null===n&&(a+='\n If "null" is intended as an empty value be sure to mark the schema as `.nullable()`'),a},defined:"${path} must be defined"},pd={length:"${path} must be exactly ${length} characters",min:"${path} must be at least ${min} characters",max:"${path} must be at most ${max} characters",matches:'${path} must match the following: "${regex}"',email:"${path} must be a valid email",url:"${path} must be a valid URL",uuid:"${path} must be a valid UUID",trim:"${path} must be a trimmed string",lowercase:"${path} must be a lowercase string",uppercase:"${path} must be a upper case string"},ph={min:"${path} must be greater than or equal to ${min}",max:"${path} must be less than or equal to ${max}",lessThan:"${path} must be less than ${less}",moreThan:"${path} must be greater than ${more}",positive:"${path} must be a positive number",negative:"${path} must be a negative number",integer:"${path} must be an integer"},pp={min:"${path} field must be later than ${min}",max:"${path} field must be at earlier than ${max}"},pb={isValue:"${path} field must be ${value}"},pm={noUnknown:"${path} field has unspecified keys: ${unknown}"},pg={min:"${path} field must have at least ${min} items",max:"${path} field must have less than or equal to ${max} items",length:"${path} must be have ${length} items"};Object.assign(Object.create(null),{mixed:pf,string:pd,number:ph,date:pp,object:pm,array:pg,boolean:pb});var pv=n(18721),py=n.n(pv);let pw=e=>e&&e.__isYupSchema__;class p_{constructor(e,t){if(this.refs=e,this.refs=e,"function"==typeof t){this.fn=t;return}if(!py()(t,"is"))throw TypeError("`is:` is required for `when()` conditions");if(!t.then&&!t.otherwise)throw TypeError("either `then:` or `otherwise:` is required for `when()` conditions");let{is:n,then:r,otherwise:i}=t,a="function"==typeof n?n:(...e)=>e.every(e=>e===n);this.fn=function(...e){let t=e.pop(),n=e.pop(),o=a(...e)?r:i;if(o)return"function"==typeof o?o(n):n.concat(o.resolve(t))}}resolve(e,t){let n=this.refs.map(e=>e.getValue(null==t?void 0:t.value,null==t?void 0:t.parent,null==t?void 0:t.context)),r=this.fn.apply(e,n.concat(e,t));if(void 0===r||r===e)return e;if(!pw(r))throw TypeError("conditions must return a schema object");return r.resolve(t)}}let pE=p_;function pS(e){return null==e?[]:[].concat(e)}function pk(){return(pk=Object.assign||function(e){for(var t=1;tpl(t[n])):"function"==typeof e?e(t):e}static isError(e){return e&&"ValidationError"===e.name}constructor(e,t,n,r){super(),this.name="ValidationError",this.value=t,this.path=n,this.type=r,this.errors=[],this.inner=[],pS(e).forEach(e=>{pT.isError(e)?(this.errors.push(...e.errors),this.inner=this.inner.concat(e.inner.length?e.inner:e)):this.errors.push(e)}),this.message=this.errors.length>1?`${this.errors.length} errors occurred`:this.errors[0],Error.captureStackTrace&&Error.captureStackTrace(this,pT)}}let pM=e=>{let t=!1;return(...n)=>{t||(t=!0,e(...n))}};function pO(e,t){let{endEarly:n,tests:r,args:i,value:a,errors:o,sort:s,path:u}=e,c=pM(t),l=r.length,f=[];if(o=o||[],!l)return o.length?c(new pT(o,a,u)):c(null,a);for(let d=0;d=0||(i[n]=e[n]);return i}function pR(e){function t(t,n){let{value:r,path:i="",label:a,options:o,originalValue:s,sync:u}=t,c=pP(t,["value","path","label","options","originalValue","sync"]),{name:l,test:f,params:d,message:h}=e,{parent:p,context:b}=o;function m(e){return pD.isRef(e)?e.getValue(r,p,b):e}function g(e={}){let t=pL()(pN({value:r,originalValue:s,label:a,path:e.path||i},d,e.params),m),n=new pT(pT.formatError(e.message||h,t),r,t.path,e.type||l);return n.params=t,n}let v=pN({path:i,parent:p,type:l,createError:g,resolve:m,options:o,originalValue:s},c);if(!u){try{Promise.resolve(f.call(v,r,v)).then(e=>{pT.isError(e)?n(e):e?n(null,e):n(g())})}catch(y){n(y)}return}let w;try{var _;if(w=f.call(v,r,v),"function"==typeof(null==(_=w)?void 0:_.then))throw Error(`Validation test of type: "${v.type}" returned a Promise during a synchronous validate. This test will finish after the validate call has returned`)}catch(E){n(E);return}pT.isError(w)?n(w):w?n(null,w):n(g())}return t.OPTIONS=e,t}pD.prototype.__isYupRef=!0;let pj=e=>e.substr(0,e.length-1).substr(1);function pF(e,t,n,r=n){let i,a,o;return t?((0,pC.forEach)(t,(s,u,c)=>{let l=u?pj(s):s;if((e=e.resolve({context:r,parent:i,value:n})).innerType){let f=c?parseInt(l,10):0;if(n&&f>=n.length)throw Error(`Yup.reach cannot resolve an array item at index: ${s}, in the path: ${t}. because there is no value at that index. `);i=n,n=n&&n[f],e=e.innerType}if(!c){if(!e.fields||!e.fields[l])throw Error(`The schema does not contain the path: ${t}. (failed at: ${o} which is a type: "${e._type}")`);i=n,n=n&&n[l],e=e.fields[l]}a=l,o=u?"["+s+"]":"."+s}),{schema:e,parent:i,parentPath:a}):{parent:i,parentPath:t,schema:e}}class pY{constructor(){this.list=new Set,this.refs=new Map}get size(){return this.list.size+this.refs.size}describe(){let e=[];for(let t of this.list)e.push(t);for(let[,n]of this.refs)e.push(n.describe());return e}toArray(){return Array.from(this.list).concat(Array.from(this.refs.values()))}add(e){pD.isRef(e)?this.refs.set(e.key,e):this.list.add(e)}delete(e){pD.isRef(e)?this.refs.delete(e.key):this.list.delete(e)}has(e,t){if(this.list.has(e))return!0;let n,r=this.refs.values();for(;!(n=r.next()).done;)if(t(n.value)===e)return!0;return!1}clone(){let e=new pY;return e.list=new Set(this.list),e.refs=new Map(this.refs),e}merge(e,t){let n=this.clone();return e.list.forEach(e=>n.add(e)),e.refs.forEach(e=>n.add(e)),t.list.forEach(e=>n.delete(e)),t.refs.forEach(e=>n.delete(e)),n}}function pB(){return(pB=Object.assign||function(e){for(var t=1;t{this.typeError(pf.notType)}),this.type=(null==e?void 0:e.type)||"mixed",this.spec=pB({strip:!1,strict:!1,abortEarly:!0,recursive:!0,nullable:!1,presence:"optional"},null==e?void 0:e.spec)}get _type(){return this.type}_typeCheck(e){return!0}clone(e){if(this._mutate)return e&&Object.assign(this.spec,e),this;let t=Object.create(Object.getPrototypeOf(this));return t.type=this.type,t._typeError=this._typeError,t._whitelistError=this._whitelistError,t._blacklistError=this._blacklistError,t._whitelist=this._whitelist.clone(),t._blacklist=this._blacklist.clone(),t.exclusiveTests=pB({},this.exclusiveTests),t.deps=[...this.deps],t.conditions=[...this.conditions],t.tests=[...this.tests],t.transforms=[...this.transforms],t.spec=pn(pB({},this.spec,e)),t}label(e){var t=this.clone();return t.spec.label=e,t}meta(...e){if(0===e.length)return this.spec.meta;let t=this.clone();return t.spec.meta=Object.assign(t.spec.meta||{},e[0]),t}withMutation(e){let t=this._mutate;this._mutate=!0;let n=e(this);return this._mutate=t,n}concat(e){if(!e||e===this)return this;if(e.type!==this.type&&"mixed"!==this.type)throw TypeError(`You cannot \`concat()\` schema's of different types: ${this.type} and ${e.type}`);let t=this,n=e.clone(),r=pB({},t.spec,n.spec);return n.spec=r,n._typeError||(n._typeError=t._typeError),n._whitelistError||(n._whitelistError=t._whitelistError),n._blacklistError||(n._blacklistError=t._blacklistError),n._whitelist=t._whitelist.merge(e._whitelist,e._blacklist),n._blacklist=t._blacklist.merge(e._blacklist,e._whitelist),n.tests=t.tests,n.exclusiveTests=t.exclusiveTests,n.withMutation(t=>{e.tests.forEach(e=>{t.test(e.OPTIONS)})}),n}isType(e){return!!this.spec.nullable&&null===e||this._typeCheck(e)}resolve(e){let t=this;if(t.conditions.length){let n=t.conditions;(t=t.clone()).conditions=[],t=(t=n.reduce((t,n)=>n.resolve(t,e),t)).resolve(e)}return t}cast(e,t={}){let n=this.resolve(pB({value:e},t)),r=n._cast(e,t);if(void 0!==e&&!1!==t.assert&&!0!==n.isType(r)){let i=pl(e),a=pl(r);throw TypeError(`The value of ${t.path||"field"} could not be cast to a value that satisfies the schema type: "${n._type}". attempted value: ${i} -`+(a!==i?`result of cast: ${a}`:""))}return r}_cast(e,t){let n=void 0===e?e:this.transforms.reduce((t,n)=>n.call(this,t,e,this),e);return void 0===n&&(n=this.getDefault()),n}_validate(e,t={},n){let{sync:r,path:i,from:a=[],originalValue:o=e,strict:s=this.spec.strict,abortEarly:u=this.spec.abortEarly}=t,c=e;s||(c=this._cast(c,pB({assert:!1},t)));let l={value:c,path:i,options:t,originalValue:o,schema:this,label:this.spec.label,sync:r,from:a},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),pO({args:l,value:c,path:i,sync:r,tests:f,endEarly:u},e=>{if(e)return void n(e,c);pO({tests:this.tests,args:l,path:i,sync:r,value:c,endEarly:u},n)})}validate(e,t,n){let r=this.resolve(pB({},t,{value:e}));return"function"==typeof n?r._validate(e,t,n):new Promise((n,i)=>r._validate(e,t,(e,t)=>{e?i(e):n(t)}))}validateSync(e,t){let n;return this.resolve(pB({},t,{value:e}))._validate(e,pB({},t,{sync:!0}),(e,t)=>{if(e)throw e;n=t}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,e=>{if(pT.isError(e))return!1;throw e})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(n){if(pT.isError(n))return!1;throw n}}_getDefault(){let e=this.spec.default;return null==e?e:"function"==typeof e?e.call(this):pn(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return 0===arguments.length?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return null!=e}defined(e=pf.defined){return this.test({message:e,name:"defined",exclusive:!0,test:e=>void 0!==e})}required(e=pf.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(e){return this.schema._isPresent(e)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(e=>"required"!==e.OPTIONS.name),e}nullable(e=!0){return this.clone({nullable:!1!==e})}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(void 0===(t=1===e.length?"function"==typeof e[0]?{test:e[0]}:e[0]:2===e.length?{name:e[0],test:e[1]}:{name:e[0],message:e[1],test:e[2]}).message&&(t.message=pf.default),"function"!=typeof t.test)throw TypeError("`test` is a required parameters");let n=this.clone(),r=pR(t),i=t.exclusive||t.name&&!0===n.exclusiveTests[t.name];if(t.exclusive&&!t.name)throw TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(n.exclusiveTests[t.name]=!!t.exclusive),n.tests=n.tests.filter(e=>e.OPTIONS.name!==t.name||!i&&e.OPTIONS.test!==r.OPTIONS.test),n.tests.push(r),n}when(e,t){Array.isArray(e)||"string"==typeof e||(t=e,e=".");let n=this.clone(),r=pS(e).map(e=>new pD(e));return r.forEach(e=>{e.isSibling&&n.deps.push(e.key)}),n.conditions.push(new pE(r,t)),n}typeError(e){var t=this.clone();return t._typeError=pR({message:e,name:"typeError",test(e){return!!(void 0===e||this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t}oneOf(e,t=pf.oneOf){var n=this.clone();return e.forEach(e=>{n._whitelist.add(e),n._blacklist.delete(e)}),n._whitelistError=pR({message:t,name:"oneOf",test(e){if(void 0===e)return!0;let t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}notOneOf(e,t=pf.notOneOf){var n=this.clone();return e.forEach(e=>{n._blacklist.add(e),n._whitelist.delete(e)}),n._blacklistError=pR({message:t,name:"notOneOf",test(e){let t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:n}=e.spec,r={meta:n,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(e=>({name:e.OPTIONS.name,params:e.OPTIONS.params})).filter((e,t,n)=>n.findIndex(t=>t.name===e.name)===t)};return r}}for(let pH of(pU.prototype.__isYupSchema__=!0,["validate","validateSync"]))pU.prototype[`${pH}At`]=function(e,t,n={}){let{parent:r,parentPath:i,schema:a}=pF(this,e,t,n.context);return a[pH](r&&r[i],pB({},n,{parent:r,path:e}))};for(let p$ of["equals","is"])pU.prototype[p$]=pU.prototype.oneOf;for(let pz of["not","nope"])pU.prototype[pz]=pU.prototype.notOneOf;pU.prototype.optional=pU.prototype.notRequired;let pG=pU;function pW(){return new pG}pW.prototype=pG.prototype;let pK=e=>null==e;function pV(){return new pq}class pq extends pU{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}isTrue(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test:e=>pK(e)||!0===e})}isFalse(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test:e=>pK(e)||!1===e})}}pV.prototype=pq.prototype;let pZ=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,pX=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,pJ=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,pQ=e=>pK(e)||e===e.trim(),p1=({}).toString();function p0(){return new p2}class p2 extends pU{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=null!=e&&e.toString?e.toString():e;return t===p1?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=pd.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t=pd.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t=pd.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}matches(e,t){let n=!1,r,i;return t&&("object"==typeof t?{excludeEmptyString:n=!1,message:r,name:i}=t:r=t),this.test({name:i||"matches",message:r||pd.matches,params:{regex:e},test:t=>pK(t)||""===t&&n||-1!==t.search(e)})}email(e=pd.email){return this.matches(pZ,{name:"email",message:e,excludeEmptyString:!0})}url(e=pd.url){return this.matches(pX,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=pd.uuid){return this.matches(pJ,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>null===e?"":e)}trim(e=pd.trim){return this.transform(e=>null!=e?e.trim():e).test({message:e,name:"trim",test:pQ})}lowercase(e=pd.lowercase){return this.transform(e=>pK(e)?e:e.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toLowerCase()})}uppercase(e=pd.uppercase){return this.transform(e=>pK(e)?e:e.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toUpperCase()})}}p0.prototype=p2.prototype;let p3=e=>e!=+e;function p4(){return new p6}class p6 extends pU{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!p3(e)}min(e,t=ph.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t>=this.resolve(e)}})}max(e,t=ph.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t<=this.resolve(e)}})}lessThan(e,t=ph.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(t){return pK(t)||tthis.resolve(e)}})}positive(e=ph.positive){return this.moreThan(0,e)}negative(e=ph.negative){return this.lessThan(0,e)}integer(e=ph.integer){return this.test({name:"integer",message:e,test:e=>pK(e)||Number.isInteger(e)})}truncate(){return this.transform(e=>pK(e)?e:0|e)}round(e){var t,n=["ceil","floor","round","trunc"];if("trunc"===(e=(null==(t=e)?void 0:t.toLowerCase())||"round"))return this.truncate();if(-1===n.indexOf(e.toLowerCase()))throw TypeError("Only valid options for round() are: "+n.join(", "));return this.transform(t=>pK(t)?t:Math[e](t))}}p4.prototype=p6.prototype;var p5=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function p8(e){var t,n,r=[1,4,5,6,7,10,11],i=0;if(n=p5.exec(e)){for(var a,o=0;a=r[o];++o)n[a]=+n[a]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(void 0===n[8]||""===n[8])&&(void 0===n[9]||""===n[9])?t=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):("Z"!==n[8]&&void 0!==n[9]&&(i=60*n[10]+n[11],"+"===n[9]&&(i=0-i)),t=Date.UTC(n[1],n[2],n[3],n[4],n[5]+i,n[6],n[7]))}else t=Date.parse?Date.parse(e):NaN;return t}let p9=new Date(""),p7=e=>"[object Date]"===Object.prototype.toString.call(e);function be(){return new bt}class bt extends pU{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=p8(e),isNaN(e)?p9:new Date(e))})})}_typeCheck(e){return p7(e)&&!isNaN(e.getTime())}prepareParam(e,t){let n;if(pD.isRef(e))n=e;else{let r=this.cast(e);if(!this._typeCheck(r))throw TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);n=r}return n}min(e,t=pp.min){let n=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(e){return pK(e)||e>=this.resolve(n)}})}max(e,t=pp.max){var n=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(e){return pK(e)||e<=this.resolve(n)}})}}bt.INVALID_DATE=p9,be.prototype=bt.prototype,be.INVALID_DATE=p9;var bn=n(11865),br=n.n(bn),bi=n(68929),ba=n.n(bi),bo=n(67523),bs=n.n(bo),bu=n(94633),bc=n.n(bu);function bl(e,t=[]){let n=[],r=[];function i(e,i){var a=(0,pC.split)(e)[0];~r.indexOf(a)||r.push(a),~t.indexOf(`${i}-${a}`)||n.push([i,a])}for(let a in e)if(py()(e,a)){let o=e[a];~r.indexOf(a)||r.push(a),pD.isRef(o)&&o.isSibling?i(o.path,a):pw(o)&&"deps"in o&&o.deps.forEach(e=>i(e,a))}return bc().array(r,n).reverse()}function bf(e,t){let n=1/0;return e.some((e,r)=>{var i;if((null==(i=t.path)?void 0:i.indexOf(e))!==-1)return n=r,!0}),n}function bd(e){return(t,n)=>bf(e,t)-bf(e,n)}function bh(){return(bh=Object.assign||function(e){for(var t=1;t"[object Object]"===Object.prototype.toString.call(e);function bb(e,t){let n=Object.keys(e.fields);return Object.keys(t).filter(e=>-1===n.indexOf(e))}let bm=bd([]);class bg extends pU{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=bm,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null}),e&&this.shape(e)})}_typeCheck(e){return bp(e)||"function"==typeof e}_cast(e,t={}){var n;let r=super._cast(e,t);if(void 0===r)return this.getDefault();if(!this._typeCheck(r))return r;let i=this.fields,a=null!=(n=t.stripUnknown)?n:this.spec.noUnknown,o=this._nodes.concat(Object.keys(r).filter(e=>-1===this._nodes.indexOf(e))),s={},u=bh({},t,{parent:s,__validating:t.__validating||!1}),c=!1;for(let l of o){let f=i[l],d=py()(r,l);if(f){let h,p=r[l];u.path=(t.path?`${t.path}.`:"")+l;let b="spec"in(f=f.resolve({value:p,context:t.context,parent:s}))?f.spec:void 0,m=null==b?void 0:b.strict;if(null==b?void 0:b.strip){c=c||l in r;continue}void 0!==(h=t.__validating&&m?r[l]:f.cast(r[l],u))&&(s[l]=h)}else d&&!a&&(s[l]=r[l]);s[l]!==r[l]&&(c=!0)}return c?s:r}_validate(e,t={},n){let r=[],{sync:i,from:a=[],originalValue:o=e,abortEarly:s=this.spec.abortEarly,recursive:u=this.spec.recursive}=t;a=[{schema:this,value:o},...a],t.__validating=!0,t.originalValue=o,t.from=a,super._validate(e,t,(e,c)=>{if(e){if(!pT.isError(e)||s)return void n(e,c);r.push(e)}if(!u||!bp(c)){n(r[0]||null,c);return}o=o||c;let l=this._nodes.map(e=>(n,r)=>{let i=-1===e.indexOf(".")?(t.path?`${t.path}.`:"")+e:`${t.path||""}["${e}"]`,s=this.fields[e];if(s&&"validate"in s){s.validate(c[e],bh({},t,{path:i,from:a,strict:!0,parent:c,originalValue:o[e]}),r);return}r(null)});pO({sync:i,tests:l,value:c,errors:r,endEarly:s,sort:this._sortErrors,path:t.path},n)})}clone(e){let t=super.clone(e);return t.fields=bh({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),n=t.fields;for(let[r,i]of Object.entries(this.fields)){let a=n[r];void 0===a?n[r]=i:a instanceof pU&&i instanceof pU&&(n[r]=i.concat(a))}return t.withMutation(()=>t.shape(n))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let n=this.fields[t];e[t]="default"in n?n.getDefault():void 0}),e}_getDefault(){return"default"in this.spec?super._getDefault():this._nodes.length?this.getDefaultFromShape():void 0}shape(e,t=[]){let n=this.clone(),r=Object.assign(n.fields,e);if(n.fields=r,n._sortErrors=bd(Object.keys(r)),t.length){Array.isArray(t[0])||(t=[t]);let i=t.map(([e,t])=>`${e}-${t}`);n._excludedEdges=n._excludedEdges.concat(i)}return n._nodes=bl(r,n._excludedEdges),n}pick(e){let t={};for(let n of e)this.fields[n]&&(t[n]=this.fields[n]);return this.clone().withMutation(e=>(e.fields={},e.shape(t)))}omit(e){let t=this.clone(),n=t.fields;for(let r of(t.fields={},e))delete n[r];return t.withMutation(()=>t.shape(n))}from(e,t,n){let r=(0,pC.getter)(e,!0);return this.transform(i=>{if(null==i)return i;let a=i;return py()(i,e)&&(a=bh({},i),n||delete a[e],a[t]=r(i)),a})}noUnknown(e=!0,t=pm.noUnknown){"string"==typeof e&&(t=e,e=!0);let n=this.test({name:"noUnknown",exclusive:!0,message:t,test(t){if(null==t)return!0;let n=bb(this.schema,t);return!e||0===n.length||this.createError({params:{unknown:n.join(", ")}})}});return n.spec.noUnknown=e,n}unknown(e=!0,t=pm.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&bs()(t,(t,n)=>e(n)))}camelCase(){return this.transformKeys(ba())}snakeCase(){return this.transformKeys(br())}constantCase(){return this.transformKeys(e=>br()(e).toUpperCase())}describe(){let e=super.describe();return e.fields=pL()(this.fields,e=>e.describe()),e}}function bv(e){return new bg(e)}function by(){return(by=Object.assign||function(e){for(var t=1;t{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let n=super._cast(e,t);if(!this._typeCheck(n)||!this.innerType)return n;let r=!1,i=n.map((e,n)=>{let i=this.innerType.cast(e,by({},t,{path:`${t.path||""}[${n}]`}));return i!==e&&(r=!0),i});return r?i:n}_validate(e,t={},n){var r,i;let a=[],o=t.sync,s=t.path,u=this.innerType,c=null!=(r=t.abortEarly)?r:this.spec.abortEarly,l=null!=(i=t.recursive)?i:this.spec.recursive,f=null!=t.originalValue?t.originalValue:e;super._validate(e,t,(e,r)=>{if(e){if(!pT.isError(e)||c)return void n(e,r);a.push(e)}if(!l||!u||!this._typeCheck(r)){n(a[0]||null,r);return}f=f||r;let i=Array(r.length);for(let d=0;du.validate(h,b,t)}pO({sync:o,path:s,value:r,errors:a,endEarly:c,tests:i},n)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!pw(e))throw TypeError("`array.of()` sub-schema must be a valid yup schema not: "+pl(e));return t.innerType=e,t}length(e,t=pg.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t){return t=t||pg.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t){return t=t||pg.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:null==t?[]:[].concat(t))}compact(e){let t=e?(t,n,r)=>!e(t,n,r):e=>!!e;return this.transform(e=>null!=e?e.filter(t):e)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}}bw.prototype=b_.prototype;var bE=bv().shape({name:p0().required("Required"),url:p0().required("Required")}),bS=function(e){var t=e.initialValues,n=e.onSubmit,r=e.submitButtonText,i=e.nameDisabled,a=void 0!==i&&i;return l.createElement(hT,{initialValues:t,validationSchema:bE,onSubmit:n},function(e){var t=e.isSubmitting;return l.createElement(l.Fragment,null,l.createElement(hR,{"data-testid":"bridge-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",disabled:a,required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"url",name:"url",label:"Bridge URL",placeholder:"https://",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"url-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"minimumContractPayment",name:"minimumContractPayment",label:"Minimum Contract Payment",placeholder:"0",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"minimumContractPayment-helper-text"}})),l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"confirmations",name:"confirmations",label:"Confirmations",placeholder:"0",type:"number",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"confirmations-helper-text"}})))),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},r)))))})},bk=function(e){var t=e.bridge,n=e.onSubmit,r={name:t.name,url:t.url,minimumContractPayment:t.minimumContractPayment,confirmations:t.confirmations};return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:40},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Bridge",action:l.createElement(aA.Z,{component:tz,href:"/bridges/".concat(t.id)},"Cancel")}),l.createElement(aW.Z,null,l.createElement(bS,{nameDisabled:!0,initialValues:r,onSubmit:n,submitButtonText:"Save Bridge"}))))))};function bx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]&&arguments[0],t=e?function(){return l.createElement(x.default,{variant:"body1"},"Loading...")}:function(){return null};return{isLoading:e,LoadingPlaceholder:t}},mc=n(76023);function ml(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function mB(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=4?[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]:void 0}var mZ={};function mX(e){if(0===e.length||1===e.length)return e;var t=e.join(".");return mZ[t]||(mZ[t]=mq(e)),mZ[t]}function mJ(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return mX(e.filter(function(e){return"token"!==e})).reduce(function(e,t){return mK({},e,n[t])},t)}function mQ(e){return e.join(" ")}function m1(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return m0({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(i)})})}}function m0(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,o=e.key,s=t.properties,u=t.type,c=t.tagName,f=t.value;if("text"===u)return f;if(c){var d,h=m1(n,a);if(a){var p=Object.keys(n).reduce(function(e,t){return t.split(".").forEach(function(t){e.includes(t)||e.push(t)}),e},[]),b=s.className&&s.className.includes("token")?["token"]:[],m=s.className&&b.concat(s.className.filter(function(e){return!p.includes(e)}));d=mK({},s,{className:mQ(m)||void 0,style:mJ(s.className,Object.assign({},s.style,i),n)})}else d=mK({},s,{className:mQ(s.className)});var g=h(t.children);return l.createElement(c,(0,mV.Z)({key:o},d),g)}}let m2=function(e,t){return -1!==e.listLanguages().indexOf(t)};var m3=/\n/g;function m4(e){return e.match(m3)}function m6(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return l.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof r?r(i):r},"".concat(i,"\n"))})}function m5(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,o=void 0===a?{}:a,s=e.startingLineNumber;return l.createElement("code",{style:Object.assign({},n,i)},m6({lines:t.replace(/\n$/,"").split("\n"),style:o,startingLineNumber:s}))}function m8(e){return"".concat(e.toString().length,".25em")}function m9(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function m7(e,t,n){var r,i={display:"inline-block",minWidth:m8(n),paddingRight:"1em",textAlign:"right",userSelect:"none"};return mK({},i,"function"==typeof e?e(t):e)}function ge(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=void 0===o?{}:o,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,f=e.wrapLongLines,d="function"==typeof s?s(n):s;if(d.className=c,n&&a){var h=m7(r,n,i);t.unshift(m9(n,h))}return f&l&&(d.style=mK({},d.style,{display:"flex"})),{type:"element",tagName:"span",properties:d,children:t}}function gt(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return ge({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:a,showLineNumbers:r,wrapLongLines:u})}function b(e,t){if(r&&t&&i){var n=m7(s,t,o);e.unshift(m9(t,n))}return e}function m(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||r.length>0?p(e,n,r):b(e,n)}for(var g=function(){var e=l[h],t=e.children[0].value;if(m4(t)){var n=t.split("\n");n.forEach(function(t,i){var o=r&&f.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===i){var u=l.slice(d+1,h).concat(ge({children:[s],className:e.properties.className})),c=m(u,o);f.push(c)}else if(i===n.length-1){if(l[h+1]&&l[h+1].children&&l[h+1].children[0]){var p={type:"text",value:"".concat(t)},b=ge({children:[p],className:e.properties.className});l.splice(h+1,0,b)}else{var g=[s],v=m(g,o,e.properties.className);f.push(v)}}else{var y=[s],w=m(y,o,e.properties.className);f.push(w)}}),d=h}h++};h code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}};var gu=n(98695),gc=n.n(gu);let gl=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];var gf=go(gc(),gs);gf.supportedLanguages=gl;let gd=gf;var gh=n(64566);function gp(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function gb(){var e=gp(["\n query FetchConfigV2 {\n configv2 {\n user\n effective\n }\n }\n"]);return gb=function(){return e},e}var gm=n0(gb()),gg=function(e){var t=e.children;return l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},t))},gv=function(){return l.createElement(gg,null,"...")},gy=function(e){var t=e.children;return l.createElement(gg,null,t)},gw=function(e){var t=e.loading,n=e.toml,r=e.error,i=void 0===r?"":r,a=e.title,o=e.expanded;if(i)return l.createElement(gy,null,i);if(t)return l.createElement(gv,null);a||(a="TOML");var s={display:"block"};return l.createElement(x.default,null,l.createElement(mP.Z,{defaultExpanded:o},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},a),l.createElement(mj.Z,{style:s},l.createElement(gd,{language:"toml",style:gs},n))))},g_=function(){var e=rv(gm,{fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return(null==t?void 0:t.configv2.effective)=="N/A"?l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"V2 config dump:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0})))):l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"User specified:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0,expanded:!0}),l.createElement(gw,{title:"Effective (with defaults):",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.effective,showHead:!0})))))},gE=n(34823),gS=function(e){return(0,b.createStyles)({cell:{paddingTop:1.5*e.spacing.unit,paddingBottom:1.5*e.spacing.unit}})},gk=(0,b.withStyles)(gS)(function(e){var t=e.classes,n=(0,A.I0)();(0,l.useEffect)(function(){n((0,ty.DQ)())});var r=(0,A.v9)(gE.N,A.wU);return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Node"}),l.createElement(r8.Z,null,l.createElement(r9.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"Version"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.version))),l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"SHA"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.commitSHA))))))}),gx=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,sm:12,md:8},l.createElement(d.Z,{container:!0},l.createElement(g_,null))),l.createElement(d.Z,{item:!0,sm:12,md:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gk,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mN,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mE,null))))))},gT=function(){return l.createElement(gx,null)},gM=function(){return l.createElement(gT,null)},gO=n(44431),gA=1e18,gL=function(e){return new gO.BigNumber(e).dividedBy(gA).toFixed(8)},gC=function(e){var t=e.keys,n=e.chainID,r=e.hideHeaderTitle;return l.createElement(l.Fragment,null,l.createElement(sl.Z,{title:!r&&"Account Balances",subheader:"Chain ID "+n}),l.createElement(aW.Z,null,l.createElement(w.default,{dense:!1,disablePadding:!0},t&&t.map(function(e,r){return l.createElement(l.Fragment,null,l.createElement(_.default,{disableGutters:!0,key:["acc-balance",n.toString(),r.toString()].join("-")},l.createElement(E.Z,{primary:l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(op,{title:"Address"}),l.createElement(ob,{value:e.address})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"Native Token Balance"}),l.createElement(ob,{value:e.ethBalance||"--"})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"LINK Balance"}),l.createElement(ob,{value:e.linkBalance?gL(e.linkBalance):"--"}))))})),r+1s&&l.createElement(gB.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:r.footer},l.createElement(aA.Z,{href:"/runs",component:tz},"View More"))))))});function vt(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vn(){var e=vt(["\n ","\n query FetchRecentJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...RecentJobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return vn=function(){return e},e}var vr=5,vi=n0(vn(),g9),va=function(){var e=rv(vi,{variables:{offset:0,limit:vr},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(ve,{data:t,errorMsg:null==r?void 0:r.message,loading:n,maxRunsSize:vr})},vo=function(e){return(0,b.createStyles)({style:{textAlign:"center",padding:2.5*e.spacing.unit,position:"fixed",left:"0",bottom:"0",width:"100%",borderRadius:0},bareAnchor:{color:e.palette.common.black,textDecoration:"none"}})},vs=(0,b.withStyles)(vo)(function(e){var t=e.classes,n=(0,A.v9)(gE.N,A.wU),r=(0,A.I0)();return(0,l.useEffect)(function(){r((0,ty.DQ)())}),l.createElement(ii.default,{className:t.style},l.createElement(x.default,null,"Chainlink Node ",n.version," at commit"," ",l.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/smartcontractkit/chainlink/commit/".concat(n.commitSHA),className:t.bareAnchor},n.commitSHA)))}),vu=function(e){return(0,b.createStyles)({cell:{borderColor:e.palette.divider,borderTop:"1px solid",borderBottom:"none",paddingTop:2*e.spacing.unit,paddingBottom:2*e.spacing.unit,paddingLeft:2*e.spacing.unit},block:{display:"block"},overflowEllipsis:{textOverflow:"ellipsis",overflow:"hidden"}})},vc=(0,b.withStyles)(vu)(function(e){var t=e.classes,n=e.job;return l.createElement(ir.Z,null,l.createElement(r7.default,{scope:"row",className:t.cell},l.createElement(d.Z,{container:!0,spacing:0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ih,{href:"/jobs/".concat(n.id),classes:{linkContent:t.block}},l.createElement(x.default,{className:t.overflowEllipsis,variant:"body1",component:"span",color:"primary"},n.name||n.id))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,{variant:"body1",color:"textSecondary"},"Created ",l.createElement(aO,{tooltip:!0},n.createdAt))))))});function vl(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vf(){var e=vl(["\n fragment RecentJobsPayload_ResultsFields on Job {\n id\n name\n createdAt\n }\n"]);return vf=function(){return e},e}var vd=n0(vf()),vh=function(){return(0,b.createStyles)({cardHeader:{borderBottom:0},table:{tableLayout:"fixed"}})},vp=(0,b.withStyles)(vh)(function(e){var t,n,r=e.classes,i=e.data,a=e.errorMsg,o=e.loading;return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Recent Jobs",className:r.cardHeader}),l.createElement(r8.Z,{className:r.table},l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(t=null==i?void 0:i.jobs.results)||void 0===t?void 0:t.length)===0},"No recently created jobs"),l.createElement(gU,{msg:a}),null===(n=null==i?void 0:i.jobs.results)||void 0===n?void 0:n.map(function(e,t){return l.createElement(vc,{job:e,key:t})}))))});function vb(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vm(){var e=vb(["\n ","\n query FetchRecentJobs($offset: Int, $limit: Int) {\n jobs(offset: $offset, limit: $limit) {\n results {\n ...RecentJobsPayload_ResultsFields\n }\n }\n }\n"]);return vm=function(){return e},e}var vg=5,vv=n0(vm(),vd),vy=function(){var e=rv(vv,{variables:{offset:0,limit:vg},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vp,{data:t,errorMsg:null==r?void 0:r.message,loading:n})},vw=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:8},l.createElement(va,null)),l.createElement(d.Z,{item:!0,xs:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gY,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(vy,null))))),l.createElement(vs,null))},v_=function(){return l.createElement(vw,null)},vE=function(){return l.createElement(v_,null)},vS=n(87239),vk=function(e){switch(e){case"DirectRequestSpec":return"Direct Request";case"FluxMonitorSpec":return"Flux Monitor";default:return e.replace(/Spec$/,"")}},vx=n(5022),vT=n(78718),vM=n.n(vT);function vO(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1?t-1:0),r=1;r1?t-1:0),r=1;re.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&n.map(function(e){return l.createElement(ir.Z,{key:e.id,style:{cursor:"pointer"},onClick:function(){return r.push("/runs/".concat(e.id))}},l.createElement(r7.default,{className:t.idCell,scope:"row"},l.createElement("div",{className:t.runDetails},l.createElement(x.default,{variant:"h5",color:"primary",component:"span"},e.id))),l.createElement(r7.default,{className:t.stampCell},l.createElement(x.default,{variant:"body1",color:"textSecondary",className:t.stamp},"Created ",l.createElement(aO,{tooltip:!0},e.createdAt))),l.createElement(r7.default,{className:t.statusCell,scope:"row"},l.createElement(x.default,{variant:"body1",className:O()(t.status,yh(t,e.status))},e.status.toLowerCase())))})))}),yb=n(16839),ym=n.n(yb);function yg(e){var t=e.replace(/\w+\s*=\s*<([^>]|[\r\n])*>/g,""),n=ym().read(t),r=n.edges();return n.nodes().map(function(e){var t={id:e,parentIds:r.filter(function(t){return t.w===e}).map(function(e){return e.v})};return Object.keys(n.node(e)).length>0&&(t.attributes=n.node(e)),t})}var yv=n(94164),yy=function(e){var t=e.data,n=[];return(null==t?void 0:t.attributes)&&Object.keys(t.attributes).forEach(function(e){var r;n.push(l.createElement("div",{key:e},l.createElement(x.default,{variant:"body1",color:"textSecondary",component:"div"},l.createElement("b",null,e,":")," ",null===(r=t.attributes)||void 0===r?void 0:r[e])))}),l.createElement("div",null,t&&l.createElement(x.default,{variant:"body1",color:"textPrimary"},l.createElement("b",null,t.id)),n)},yw=n(73343),y_=n(3379),yE=n.n(y_);function yS(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nwindow.innerWidth?u-r.getBoundingClientRect().width-a:u+a,n=c+r.getBoundingClientRect().height+i>window.innerHeight?c-r.getBoundingClientRect().height-a:c+a,r.style.opacity=String(1),r.style.top="".concat(n,"px"),r.style.left="".concat(t,"px"),r.style.zIndex=String(1)}},h=function(e){var t=document.getElementById("tooltip-d3-chart-".concat(e));t&&(t.style.opacity=String(0),t.style.zIndex=String(-1))};return l.createElement("div",{style:{fontFamily:"sans-serif",fontWeight:"normal"}},l.createElement(yv.kJ,{id:"task-list-graph-d3",data:i,config:s,onMouseOverNode:d,onMouseOutNode:h},"D3 chart"),n.map(function(e){return l.createElement("div",{key:"d3-tooltip-key-".concat(e.id),id:"tooltip-d3-chart-".concat(e.id),style:{position:"absolute",opacity:"0",border:"1px solid rgba(0, 0, 0, 0.1)",padding:yw.r.spacing.unit,background:"white",borderRadius:5,zIndex:-1,inlineSize:"min-content"}},l.createElement(yy,{data:e}))}))};function yL(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nyY&&l.createElement("div",{className:t.runDetails},l.createElement(aA.Z,{href:"/jobs/".concat(n.id,"/runs"),component:tz},"View more")))),l.createElement(d.Z,{item:!0,xs:12,sm:6},l.createElement(yF,{observationSource:n.observationSource})))});function yH(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:"";try{return vx.parse(e),!0}catch(t){return!1}})}),wW=function(e){var t=e.initialValues,n=e.onSubmit,r=e.onTOMLChange;return l.createElement(hT,{initialValues:t,validationSchema:wG,onSubmit:n},function(e){var t=e.isSubmitting,n=e.values;return r&&r(n.toml),l.createElement(hR,{"data-testid":"job-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"toml",name:"toml",label:"Job Spec (TOML)",required:!0,fullWidth:!0,multiline:!0,rows:10,rowsMax:25,variant:"outlined",autoComplete:"off",FormHelperTextProps:{"data-testid":"toml-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},"Create Job"))))})},wK=n(50109),wV="persistSpec";function wq(e){var t=e.query,n=new URLSearchParams(t).get("definition");return n?(wK.t8(wV,n),{toml:n}):{toml:wK.U2(wV)||""}}var wZ=function(e){var t=e.onSubmit,n=e.onTOMLChange,r=wq({query:(0,h.TH)().search}),i=function(e){var t=e.replace(/[\u200B-\u200D\uFEFF]/g,"");wK.t8("".concat(wV),t),n&&n(t)};return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"New Job"}),l.createElement(aW.Z,null,l.createElement(wW,{initialValues:r,onSubmit:t,onTOMLChange:i})))};function wX(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=t.start,r=void 0===n?6:n,i=t.end,a=void 0===i?4:i;return e.substring(0,r)+"..."+e.substring(e.length-a)}function _M(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(_W,e)},_V=function(){var e=_K({fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error,i=e.refetch;return l.createElement(_U,{loading:n,data:t,errorMsg:null==r?void 0:r.message,refetch:i})},_q=function(e){var t=e.csaKey;return l.createElement(ir.Z,{hover:!0},l.createElement(r7.default,null,l.createElement(x.default,{variant:"body1"},t.publicKey," ",l.createElement(_x,{data:t.publicKey}))))};function _Z(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function _X(){var e=_Z(["\n fragment CSAKeysPayload_ResultsFields on CSAKey {\n id\n publicKey\n }\n"]);return _X=function(){return e},e}var _J=n0(_X()),_Q=function(e){var t,n,r,i=e.data,a=e.errorMsg,o=e.loading,s=e.onCreate;return l.createElement(r5.Z,null,l.createElement(sl.Z,{action:(null===(t=null==i?void 0:i.csaKeys.results)||void 0===t?void 0:t.length)===0&&l.createElement(ok.default,{variant:"outlined",color:"primary",onClick:s},"New CSA Key"),title:"CSA Key",subheader:"Manage your CSA Key"}),l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Public Key"))),l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(n=null==i?void 0:i.csaKeys.results)||void 0===n?void 0:n.length)===0}),l.createElement(gU,{msg:a}),null===(r=null==i?void 0:i.csaKeys.results)||void 0===r?void 0:r.map(function(e,t){return l.createElement(_q,{csaKey:e,key:t})}))))};function _1(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EM,e)};function EA(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EJ,e)},E3=function(){return oo(EQ)},E4=function(){return oo(E1)},E6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(E0,e)};function E5(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(SK,e)};function Sq(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function kV(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}var kq=function(e){var t=e.run,n=l.useMemo(function(){var e=t.inputs,n=t.outputs,r=t.taskRuns,i=kK(t,["inputs","outputs","taskRuns"]),a={};try{a=JSON.parse(e)}catch(o){a={}}return kW(kz({},i),{inputs:a,outputs:n,taskRuns:r})},[t]);return l.createElement(r5.Z,null,l.createElement(aW.Z,null,l.createElement(kH,{object:n})))};function kZ(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kX(e){for(var t=1;t0&&l.createElement(kr,{errors:t.allErrors})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(h.rs,null,l.createElement(h.AW,{path:"".concat(n,"/json")},l.createElement(kq,{run:t})),l.createElement(h.AW,{path:n},t.taskRuns.length>0&&l.createElement(kN,{taskRuns:t.taskRuns,observationSource:t.job.observationSource}))))))))};function k5(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function k8(){var e=k5(["\n ","\n query FetchJobRun($id: ID!) {\n jobRun(id: $id) {\n __typename\n ... on JobRun {\n ...JobRunPayload_Fields\n }\n ... on NotFoundError {\n message\n }\n }\n }\n"]);return k8=function(){return e},e}var k9=n0(k8(),k4),k7=function(){var e=rv(k9,{variables:{id:(0,h.UO)().id}}),t=e.data,n=e.loading,r=e.error;if(n)return l.createElement(iR,null);if(r)return l.createElement(iD,{error:r});var i=null==t?void 0:t.jobRun;switch(null==i?void 0:i.__typename){case"JobRun":return l.createElement(k6,{run:i});case"NotFoundError":return l.createElement(oa,null);default:return null}};function xe(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xt(){var e=xe(["\n fragment JobRunsPayload_ResultsFields on JobRun {\n id\n allErrors\n createdAt\n finishedAt\n status\n job {\n id\n }\n }\n"]);return xt=function(){return e},e}var xn=n0(xt()),xr=function(e){var t=e.loading,n=e.data,r=e.page,i=e.pageSize,a=(0,h.k6)(),o=l.useMemo(function(){return null==n?void 0:n.jobRuns.results.map(function(e){var t,n=e.allErrors,r=e.id,i=e.createdAt;return{id:r,createdAt:i,errors:n,finishedAt:e.finishedAt,status:e.status}})},[n]);return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(iy,null,"Job Runs")),t&&l.createElement(iR,null),n&&o&&l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(yp,{runs:o}),l.createElement(it.Z,{component:"div",count:n.jobRuns.metadata.total,rowsPerPage:i,rowsPerPageOptions:[i],page:r-1,onChangePage:function(e,t){a.push("/runs?page=".concat(t+1,"&per=").concat(i))},onChangeRowsPerPage:function(){},backIconButtonProps:{"aria-label":"prev-page"},nextIconButtonProps:{"aria-label":"next-page"}})))))};function xi(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xa(){var e=xi(["\n ","\n query FetchJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...JobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return xa=function(){return e},e}var xo=n0(xa(),xn),xs=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"25",10),r=rv(xo,{variables:{offset:(t-1)*n,limit:n},fetchPolicy:"cache-and-network"}),i=r.data,a=r.loading,o=r.error;return o?l.createElement(iD,{error:o}):l.createElement(xr,{loading:a,data:i,page:t,pageSize:n})},xu=function(){var e=(0,h.$B)().path;return l.createElement(h.rs,null,l.createElement(h.AW,{exact:!0,path:e},l.createElement(xs,null)),l.createElement(h.AW,{path:"".concat(e,"/:id")},l.createElement(k7,null)))};function xc(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xl(){var e=xc(["\n fragment FetchFeedsManagersPayload_ResultsFields on FeedsManager {\n __typename\n id\n name\n uri\n publicKey\n isConnectionActive\n createdAt\n }\n query FetchFeedsManagers {\n feedsManagers {\n results {\n ...FetchFeedsManagersPayload_ResultsFields\n }\n }\n }\n"]);return xl=function(){return e},e}var xf=n0(xl()),xd=function(e){return rv(xf,e)},xh=n(47559),xp=n(83165),xb=n(47298),xm=n(81395),xg=function(){return(0,b.createStyles)({root:{display:"flex"},connectedIcon:{color:xh.default[500]},disconnectedIcon:{color:xp.default[500]},text:{marginLeft:4}})},xv=(0,b.withStyles)(xg)(function(e){var t=e.isConnected,n=e.classes;return l.createElement("div",{className:n.root},t?l.createElement(xm.Z,{fontSize:"small",className:n.connectedIcon}):l.createElement(xb.Z,{fontSize:"small",className:n.disconnectedIcon}),l.createElement(x.default,{variant:"body1",inline:!0,className:n.text},t?"Connected":"Disconnected"))}),xy=(0,b.withStyles)(iu)(function(e){var t=e.jobDistributor,n=e.classes;return l.createElement(ir.Z,{className:n.row,hover:!0},l.createElement(r7.default,{className:n.cell,component:"th",scope:"row"},l.createElement(ih,{className:n.link,href:"/job_distributors/".concat(t.id)},t.name)),l.createElement(r7.default,null,l.createElement(xv,{isConnected:t.isConnectionActive})),l.createElement(r7.default,null,_T(t.publicKey,{start:6,end:6}),l.createElement(_x,{data:t.publicKey})),l.createElement(r7.default,null,t.uri))}),xw=function(e){var t=e.jobDistributors;return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Distributors")),l.createElement(d.Z,{item:!0,xs:3},l.createElement(d.Z,{container:!0,justify:"flex-end"},l.createElement(d.Z,{item:!0},l.createElement(aA.Z,{variant:"secondary",component:tz,href:"/job_distributors/new"},"New Job Distributor")))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Name"),l.createElement(r7.default,null,"Status"),l.createElement(r7.default,null,"CSA Public Key"),l.createElement(r7.default,null,"RPC URL"))),l.createElement(r9.Z,null,0===t.length&&l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},"Job Distributors have not been registered")),t.map(function(e){return l.createElement(xy,{key:e.id,jobDistributor:e})})))))))},x_=function(){var e,t=xd({fetchPolicy:"cache-and-network"}),n=t.data,r=t.loading,i=t.error;return r?l.createElement(iR,null):i?l.createElement(iD,{error:i}):l.createElement(xw,{jobDistributors:null!==(e=null==n?void 0:n.feedsManagers.results)&&void 0!==e?e:[]})},xE=bv().shape({name:p0().required("Required"),uri:p0().required("Required"),publicKey:p0().required("Required")}),xS=function(e){var t=e.initialValues,n=e.onSubmit;return l.createElement(hT,{initialValues:t,validationSchema:xE,onSubmit:n},function(e){var t=e.isSubmitting,n=e.submitForm;return l.createElement(hR,{"data-testid":"feeds-manager-form"},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:!1,md:6}),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"uri",name:"uri",label:"URI",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"uri-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"publicKey",name:"publicKey",label:"Public Key",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"publicKey-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(ok.default,{variant:"contained",color:"primary",disabled:t,onClick:n},"Submit"))))})},xk=function(e){var t=e.data,n=e.onSubmit,r={name:t.name,uri:t.uri,publicKey:t.publicKey};return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Job Distributor"}),l.createElement(aW.Z,null,l.createElement(xS,{initialValues:r,onSubmit:n})))))};function xx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(xZ,e)},xJ=n(57234);function xQ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function x6(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}function x5(e,t){return x1(e)||x2(e,t)||x8(e,t)||x3()}function x8(e,t){if(e){if("string"==typeof e)return xQ(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return xQ(e,t)}}var x9=function(e){return"SN_MAIN"===e||"SN_SEPOLIA"===e},x7=bv().shape({chainID:p0().required("Required"),chainType:p0().required("Required"),accountAddr:p0().required("Required"),accountAddrPubKey:p0().nullable(),adminAddr:p0().required("Required"),ocr1Multiaddr:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr1P2PPeerID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr1KeyBundleID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2Multiaddr:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr2P2PPeerID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2KeyBundleID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2CommitPluginEnabled:pV().required("Required"),ocr2ExecutePluginEnabled:pV().required("Required"),ocr2MedianPluginEnabled:pV().required("Required"),ocr2MercuryPluginEnabled:pV().required("Required"),ocr2ForwarderAddress:p0().nullable()}),Te=function(e){return(0,b.createStyles)({supportedJobOptionsPaper:{padding:2*e.spacing.unit}})},Tt=function(e){var t=e.chainAccounts,n=x4(e,["chainAccounts"]),r=h_(),i=r.values,a=i.chainID,o=i.accountAddr,s=r.setFieldValue,u=x5(l.useState(!1),2),c=u[0],f=u[1],d=l.useRef();l.useEffect(function(){d.current=a},[a]),l.useEffect(function(){a!==d.current&&(s(n.name,""),f(!1))},[a,s,n.name]);var h=function(e){var t=e.target.value;"custom"===t?(f(!0),s(n.name,"")):(f(!1),s(n.name,t))};return l.createElement(l.Fragment,null,!x9(a)&&l.createElement(hP,x0({},n,{select:!0,value:c?"custom":o,onChange:h}),t.map(function(e){return l.createElement(tE.default,{key:e.address,value:e.address},e.address)})),x9(a)&&l.createElement(hP,{component:hX,id:"accountAddr",name:"accountAddr",label:"Enter your account address",inputProps:{"data-testid":"customAccountAddr-input"},helperText:"The account address used for this chain",required:!0,fullWidth:!0}),x9(a)&&l.createElement("div",null,l.createElement(hP,{component:hX,id:"accountAddrPubKey",name:"accountAddrPubKey",label:"Account Address Public Key",required:!0,fullWidth:!0,helperText:"The public key for your account address",FormHelperTextProps:{"data-testid":"accountAddrPubKey-helper-text"}})))},Tn=(0,b.withStyles)(Te)(function(e){var t=e.classes,n=e.editing,r=void 0!==n&&n,i=e.innerRef,a=e.initialValues,o=e.onSubmit,s=e.chainIDs,u=void 0===s?[]:s,c=e.accounts,f=void 0===c?[]:c,h=e.p2pKeys,p=void 0===h?[]:h,b=e.ocrKeys,m=void 0===b?[]:b,g=e.ocr2Keys,v=void 0===g?[]:g,y=e.showSubmit,w=void 0!==y&&y;return l.createElement(hT,{innerRef:i,initialValues:a,validationSchema:x7,onSubmit:o},function(e){var n=e.values,i=f.filter(function(e){return e.chain.id==n.chainID&&!e.isDisabled});return l.createElement(hR,{"data-testid":"feeds-manager-form",id:"chain-configuration-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"chainType",name:"chainType",label:"Chain Type",select:!0,required:!0,fullWidth:!0,disabled:!0},l.createElement(tE.default,{key:"EVM",value:"EVM"},"EVM"))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"chainID",name:"chainID",label:"Chain ID",required:!0,fullWidth:!0,select:!0,disabled:r,inputProps:{"data-testid":"chainID-input"},FormHelperTextProps:{"data-testid":"chainID-helper-text"}},u.map(function(e){return l.createElement(tE.default,{key:e,value:e},e)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(Tt,{component:hX,id:"accountAddr",name:"accountAddr",label:"Account Address",inputProps:{"data-testid":"accountAddr-input"},required:!0,fullWidth:!0,select:!0,helperText:"The account address used for this chain",chainAccounts:i,FormHelperTextProps:{"data-testid":"accountAddr-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"adminAddr",name:"adminAddr",label:"Admin Address",required:!0,fullWidth:!0,helperText:"The address used for LINK payments",FormHelperTextProps:{"data-testid":"adminAddr-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Job Types")),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"fluxMonitorEnabled",type:"checkbox",Label:{label:"Flux Monitor"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1Enabled",type:"checkbox",Label:{label:"OCR"}}),n.ocr1Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),n.ocr1IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr1Multiaddr",name:"ocr1Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr1Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1P2PPeerID",name:"ocr1P2PPeerID",label:"Peer ID",select:!0,required:!0,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1P2PPeerID-helper-text"}},p.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1KeyBundleID",name:"ocr1KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1KeyBundleID-helper-text"}},m.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)})))))))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2Enabled",type:"checkbox",Label:{label:"OCR2"}}),n.ocr2Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),n.ocr2IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr2Multiaddr",name:"ocr2Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR2 Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr2Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2P2PPeerID",name:"ocr2P2PPeerID",label:"Peer ID",select:!0,required:!0,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2P2PPeerID-helper-text"}},p.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2KeyBundleID",name:"ocr2KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR2 Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2KeyBundleID-helper-text"}},v.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)}))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Plugins")),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2CommitPluginEnabled",type:"checkbox",Label:{label:"Commit"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2ExecutePluginEnabled",type:"checkbox",Label:{label:"Execute"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2RebalancerPluginEnabled",type:"checkbox",Label:{label:"Rebalancer"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MedianPluginEnabled",type:"checkbox",Label:{label:"Median"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MercuryPluginEnabled",type:"checkbox",Label:{label:"Mercury"}})),l.createElement(d.Z,{item:!0,xs:12,md:12},l.createElement(hP,{component:hX,id:"ocr2ForwarderAddress",name:"ocr2ForwarderAddress",label:"Forwarder Address (optional)",fullWidth:!0,helperText:"The forwarder address from the Operator Forwarder Contract",FormHelperTextProps:{"data-testid":"ocr2ForwarderAddress-helper-text"}}))))))),w&&l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",size:"large"},"Submit"))))})}),Tr=function(e){var t=e.onClose,n=e.open,r=e.onSubmit,i=l.useRef(),a=i$({fetchPolicy:"network-only"}).data,o=_K({fetchPolicy:"cache-and-network"}).data,s=SV({fetchPolicy:"cache-and-network"}).data,u=EO({fetchPolicy:"cache-and-network"}).data,c=E2({fetchPolicy:"cache-and-network"}).data,f={chainID:"",chainType:"EVM",accountAddr:"",adminAddr:"",accountAddrPubKey:"",fluxMonitorEnabled:!1,ocr1Enabled:!1,ocr1IsBootstrap:!1,ocr1Multiaddr:"",ocr1P2PPeerID:"",ocr1KeyBundleID:"",ocr2Enabled:!1,ocr2IsBootstrap:!1,ocr2Multiaddr:"",ocr2P2PPeerID:"",ocr2KeyBundleID:"",ocr2CommitPluginEnabled:!1,ocr2ExecutePluginEnabled:!1,ocr2MedianPluginEnabled:!1,ocr2MercuryPluginEnabled:!1,ocr2RebalancerPluginEnabled:!1,ocr2ForwarderAddress:""},d=a?a.chains.results.map(function(e){return e.id}):[],h=o?o.ethKeys.results:[],p=s?s.p2pKeys.results:[],b=u?u.ocrKeyBundles.results:[],m=c?c.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:t,open:n,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"New Supported Chain")),l.createElement(oT.Z,null,l.createElement(Tn,{innerRef:i,initialValues:f,onSubmit:r,chainIDs:d,accounts:h,p2pKeys:p,ocrKeys:b,ocr2Keys:m})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:t},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))},Ti=function(e){var t=e.cfg,n=e.onClose,r=e.open,i=e.onSubmit,a=l.useRef(),o=i$({fetchPolicy:"network-only"}).data,s=_K({fetchPolicy:"cache-and-network"}).data,u=SV({fetchPolicy:"cache-and-network"}).data,c=EO({fetchPolicy:"cache-and-network"}).data,f=E2({fetchPolicy:"cache-and-network"}).data;if(!t)return null;var d={chainID:t.chainID,chainType:"EVM",accountAddr:t.accountAddr,adminAddr:t.adminAddr,accountAddrPubKey:t.accountAddrPubKey,fluxMonitorEnabled:t.fluxMonitorJobConfig.enabled,ocr1Enabled:t.ocr1JobConfig.enabled,ocr1IsBootstrap:t.ocr1JobConfig.isBootstrap,ocr1Multiaddr:t.ocr1JobConfig.multiaddr,ocr1P2PPeerID:t.ocr1JobConfig.p2pPeerID,ocr1KeyBundleID:t.ocr1JobConfig.keyBundleID,ocr2Enabled:t.ocr2JobConfig.enabled,ocr2IsBootstrap:t.ocr2JobConfig.isBootstrap,ocr2Multiaddr:t.ocr2JobConfig.multiaddr,ocr2P2PPeerID:t.ocr2JobConfig.p2pPeerID,ocr2KeyBundleID:t.ocr2JobConfig.keyBundleID,ocr2CommitPluginEnabled:t.ocr2JobConfig.plugins.commit,ocr2ExecutePluginEnabled:t.ocr2JobConfig.plugins.execute,ocr2MedianPluginEnabled:t.ocr2JobConfig.plugins.median,ocr2MercuryPluginEnabled:t.ocr2JobConfig.plugins.mercury,ocr2RebalancerPluginEnabled:t.ocr2JobConfig.plugins.rebalancer,ocr2ForwarderAddress:t.ocr2JobConfig.forwarderAddress},h=o?o.chains.results.map(function(e){return e.id}):[],p=s?s.ethKeys.results:[],b=u?u.p2pKeys.results:[],m=c?c.ocrKeyBundles.results:[],g=f?f.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:n,open:r,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"Edit Supported Chain")),l.createElement(oT.Z,null,l.createElement(Tn,{innerRef:a,initialValues:d,onSubmit:i,chainIDs:h,accounts:p,p2pKeys:b,ocrKeys:m,ocr2Keys:g,editing:!0})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:n},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))};function Ta(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);nt.version?e:t})},[o]),g=l.useMemo(function(){return Mx(o).sort(function(e,t){return t.version-e.version})},[o]),v=function(e,t,n){switch(e){case"PENDING":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"text",color:"secondary",onClick:function(){return b("reject",t)}},"Reject"),m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status&&l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve"),m.id===t&&"DELETED"===n.status&&n.pendingUpdate&&l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("cancel",t)}},"Cancel"),l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs")));case"APPROVED":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",onClick:function(){return b("cancel",t)}},"Cancel"),"DELETED"===n.status&&n.pendingUpdate&&l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs"));case"CANCELLED":if(m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status)return l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve");return null;default:return null}};return l.createElement("div",null,g.map(function(e,n){return l.createElement(mP.Z,{defaultExpanded:0===n,key:n},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},l.createElement(x.default,{className:t.versionText},"Version ",e.version),l.createElement(Es.Z,{label:e.status,color:"APPROVED"===e.status?"primary":"default",variant:"REJECTED"===e.status||"CANCELLED"===e.status?"outlined":"default"}),l.createElement("div",{className:t.proposedAtContainer},l.createElement(x.default,null,"Proposed ",l.createElement(aO,{tooltip:!0},e.createdAt)))),l.createElement(mj.Z,{className:t.expansionPanelDetails},l.createElement("div",{className:t.actions},l.createElement("div",{className:t.editContainer},0===n&&("PENDING"===e.status||"CANCELLED"===e.status)&&"DELETED"!==s.status&&"REVOKED"!==s.status&&l.createElement(ok.default,{variant:"contained",onClick:function(){return p(!0)}},"Edit")),l.createElement("div",{className:t.actionsContainer},v(e.status,e.id,s))),l.createElement(gd,{language:"toml",style:gs,"data-testid":"codeblock"},e.definition)))}),l.createElement(oC,{open:null!=c,title:c?ML[c.action].title:"",body:c?ML[c.action].body:"",onConfirm:function(){if(c){switch(c.action){case"approve":n(c.id);break;case"cancel":r(c.id);break;case"reject":i(c.id)}f(null)}},cancelButtonText:"Cancel",onCancel:function(){return f(null)}}),l.createElement(Mb,{open:h,onClose:function(){return p(!1)},initialValues:{definition:m.definition,id:m.id},onSubmit:a}))});function MI(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function MD(){var e=MI(["\n ","\n fragment JobProposalPayloadFields on JobProposal {\n id\n externalJobID\n remoteUUID\n jobID\n specs {\n ...JobProposal_SpecsFields\n }\n status\n pendingUpdate\n }\n"]);return MD=function(){return e},e}var MN=n0(MD(),MO),MP=function(e){var t=e.onApprove,n=e.onCancel,r=e.onReject,i=e.onUpdateSpec,a=e.proposal;return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Proposal #",a.id))),l.createElement(Mc,{proposal:a}),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(TJ,null,"Specs"))),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(MC,{proposal:a,specs:a.specs,onReject:r,onApprove:t,onCancel:n,onUpdateSpec:i}))))};function MR(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);nU,tA:()=>$,KL:()=>H,Iw:()=>V,DQ:()=>W,cB:()=>T,LO:()=>M,t5:()=>k,qt:()=>x,Jc:()=>C,L7:()=>Y,EO:()=>B});var r,i,a=n(66289),o=n(41800),s=n.n(o),u=n(67932);(i=r||(r={})).IN_PROGRESS="in_progress",i.PENDING_INCOMING_CONFIRMATIONS="pending_incoming_confirmations",i.PENDING_CONNECTION="pending_connection",i.PENDING_BRIDGE="pending_bridge",i.PENDING_SLEEP="pending_sleep",i.ERRORED="errored",i.COMPLETED="completed";var c=n(87013),l=n(19084),f=n(34823);function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]j,v2:()=>F});var r=n(66289);function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var a="/sessions",o="/sessions",s=function e(t){var n=this;i(this,e),this.api=t,this.createSession=function(e){return n.create(e)},this.destroySession=function(){return n.destroy()},this.create=this.api.createResource(a),this.destroy=this.api.deleteResource(o)};function u(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var c="/v2/bulk_delete_runs",l=function e(t){var n=this;u(this,e),this.api=t,this.bulkDeleteJobRuns=function(e){return n.destroy(e)},this.destroy=this.api.deleteResource(c)};function f(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var d="/v2/chains/evm",h="".concat(d,"/:id"),p=function e(t){var n=this;f(this,e),this.api=t,this.getChains=function(){return n.index()},this.createChain=function(e){return n.create(e)},this.destroyChain=function(e){return n.destroy(void 0,{id:e})},this.updateChain=function(e,t){return n.update(t,{id:e})},this.index=this.api.fetchResource(d),this.create=this.api.createResource(d),this.destroy=this.api.deleteResource(h),this.update=this.api.updateResource(h)};function b(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var m="/v2/keys/evm/chain",g=function e(t){var n=this;b(this,e),this.api=t,this.chain=function(e){var t=new URLSearchParams;t.append("address",e.address),t.append("evmChainID",e.evmChainID),null!==e.nextNonce&&t.append("nextNonce",e.nextNonce),null!==e.abandon&&t.append("abandon",String(e.abandon)),null!==e.enabled&&t.append("enabled",String(e.enabled));var r=m+"?"+t.toString();return n.api.createResource(r)()}};function v(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var y="/v2/jobs",w="".concat(y,"/:specId/runs"),_=function e(t){var n=this;v(this,e),this.api=t,this.createJobRunV2=function(e,t){return n.post(t,{specId:e})},this.post=this.api.createResource(w,!0)};function E(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var S="/v2/log",k=function e(t){var n=this;E(this,e),this.api=t,this.getLogConfig=function(){return n.show()},this.updateLogConfig=function(e){return n.update(e)},this.show=this.api.fetchResource(S),this.update=this.api.updateResource(S)};function x(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var T="/v2/nodes",M=function e(t){var n=this;x(this,e),this.api=t,this.getNodes=function(){return n.index()},this.createNode=function(e){return n.create(e)},this.index=this.api.fetchResource(T),this.create=this.api.createResource(T)};function O(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var A="/v2/enroll_webauthn",L=function e(t){var n=this;O(this,e),this.api=t,this.beginKeyRegistration=function(e){return n.create(e)},this.finishKeyRegistration=function(e){return n.put(e)},this.create=this.api.fetchResource(A),this.put=this.api.createResource(A)};function C(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var I="/v2/build_info",D=function e(t){var n=this;C(this,e),this.api=t,this.show=function(){return n.api.GET(I)()}};function N(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var P=function e(t){N(this,e),this.api=t,this.buildInfo=new D(this.api),this.bulkDeleteRuns=new l(this.api),this.chains=new p(this.api),this.logConfig=new k(this.api),this.nodes=new M(this.api),this.jobs=new _(this.api),this.webauthn=new L(this.api),this.evmKeys=new g(this.api)},R=new r.V0({base:void 0}),j=new s(R),F=new P(R)},1398(e,t,n){"use strict";n.d(t,{Z:()=>d});var r=n(67294),i=n(32316),a=n(83638),o=n(94184),s=n.n(o);function u(){return(u=Object.assign||function(e){for(var t=1;tc});var r=n(67294),i=n(32316);function a(){return(a=Object.assign||function(e){for(var t=1;tx,jK:()=>v});var r=n(67294),i=n(37703),a=n(45697),o=n.n(a),s=n(82204),u=n(71426),c=n(94184),l=n.n(c),f=n(32316),d=function(e){var t=e.palette.success||{},n=e.palette.warning||{};return{base:{paddingLeft:5*e.spacing.unit,paddingRight:5*e.spacing.unit},success:{backgroundColor:t.main,color:t.contrastText},error:{backgroundColor:e.palette.error.dark,color:e.palette.error.contrastText},warning:{backgroundColor:n.contrastText,color:n.main}}},h=function(e){var t,n=e.success,r=e.error,i=e.warning,a=e.classes,o=e.className;return n?t=a.success:r?t=a.error:i&&(t=a.warning),l()(a.base,o,t)},p=function(e){return r.createElement(s.Z,{className:h(e),square:!0},r.createElement(u.default,{variant:"body2",color:"inherit",component:"div"},e.children))};p.defaultProps={success:!1,error:!1,warning:!1},p.propTypes={success:o().bool,error:o().bool,warning:o().bool};let b=(0,f.withStyles)(d)(p);var m=function(){return r.createElement(r.Fragment,null,"Unhandled error. Please help us by opening a"," ",r.createElement("a",{href:"https://github.com/smartcontractkit/chainlink/issues/new"},"bug report"))};let g=m;function v(e){return"string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null)}function y(e,t){var n;return n="string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null),r.createElement("p",{key:t},n)}var w=function(e){var t=e.notifications;return r.createElement(b,{error:!0},t.map(y))},_=function(e){var t=e.notifications;return r.createElement(b,{success:!0},t.map(y))},E=function(e){var t=e.errors,n=e.successes;return r.createElement("div",null,(null==t?void 0:t.length)>0&&r.createElement(w,{notifications:t}),n.length>0&&r.createElement(_,{notifications:n}))},S=function(e){return{errors:e.notifications.errors,successes:e.notifications.successes}},k=(0,i.$j)(S)(E);let x=k},9409(e,t,n){"use strict";n.d(t,{ZP:()=>j});var r=n(67294),i=n(37703),a=n(5977),o=n(32316),s=n(1398),u=n(82204),c=n(30060),l=n(71426),f=n(60520),d=n(39814),h=n(57209),p=n(26842),b=n(3950),m=n(5536),g=n(45697),v=n.n(g);let y=n.p+"9f6d832ef97e8493764e.svg";function w(){return(w=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&_.map(function(e,t){return r.createElement(d.Z,{item:!0,xs:12,key:t},r.createElement(u.Z,{raised:!1,className:v.error},r.createElement(c.Z,null,r.createElement(l.default,{variant:"body1",className:v.errorText},(0,b.jK)(e)))))}),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"email",label:"Email",margin:"normal",value:n,onChange:m("email"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"password",label:"Password",type:"password",autoComplete:"password",margin:"normal",value:h,onChange:m("password"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(d.Z,{container:!0,spacing:0,justify:"center"},r.createElement(d.Z,{item:!0},r.createElement(s.Z,{type:"submit",variant:"primary"},"Access Account")))),y&&r.createElement(l.default,{variant:"body1",color:"textSecondary"},"Signing in...")))))))},P=function(e){return{fetching:e.authentication.fetching,authenticated:e.authentication.allowed,errors:e.notifications.errors}},R=(0,i.$j)(P,x({submitSignIn:p.L7}))(N);let j=(0,h.wU)(e)((0,o.withStyles)(D)(R))},16353(e,t,n){"use strict";n.d(t,{ZP:()=>H,rH:()=>U});var r,i=n(37703),a=n(97779),o=n(9541),s=n(19084);function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.Mk.RECEIVE_SIGNOUT_SUCCESS:case s.Mk.RECEIVE_SIGNIN_SUCCESS:var n={allowed:t.authenticated};return o.Ks(n),f(c({},e,n),{errors:[]});case s.Mk.RECEIVE_SIGNIN_FAIL:var r={allowed:!1};return o.Ks(r),f(c({},e,r),{errors:[]});case s.Mk.RECEIVE_SIGNIN_ERROR:case s.Mk.RECEIVE_SIGNOUT_ERROR:var i={allowed:!1};return o.Ks(i),f(c({},e,i),{errors:t.errors||[]});default:return e}};let b=p;function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;return t.type?t.type.startsWith(r.REQUEST)?y(g({},e),{count:e.count+1}):t.type.startsWith(r.RECEIVE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type.startsWith(r.RESPONSE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type===s.di.REDIRECT?y(g({},e),{count:0}):e:e};let S=E;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function x(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:O,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.MATCH_ROUTE:return M(x({},O),{currentUrl:t.pathname});case s.Ih.NOTIFY_SUCCESS:var n={component:t.component,props:t.props};return M(x({},e),{successes:[n],errors:[]});case s.Ih.NOTIFY_SUCCESS_MSG:return M(x({},e),{successes:[t.msg],errors:[]});case s.Ih.NOTIFY_ERROR:var r=t.error.errors,i=null==r?void 0:r.map(function(e){return L(t,e)});return M(x({},e),{successes:[],errors:i});case s.Ih.NOTIFY_ERROR_MSG:return M(x({},e),{successes:[],errors:[t.msg]});case s.Mk.RECEIVE_SIGNIN_FAIL:return M(x({},e),{successes:[],errors:["Your email or password is incorrect. Please try again"]});default:return e}};function L(e,t){return{component:e.component,props:{msg:t.detail}}}let C=A;function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:R,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.REDIRECT:return P(D({},e),{to:t.to});case s.di.MATCH_ROUTE:return P(D({},e),{to:void 0});default:return e}};let F=j;var Y=n(87013),B=(0,a.UY)({authentication:b,fetching:S,notifications:C,redirect:F,buildInfo:Y.Z});B(void 0,{type:"INITIAL_STATE"});var U=i.v9;let H=B},19084(e,t,n){"use strict";var r,i,a,o,s,u,c,l,f,d;n.d(t,{Ih:()=>i,Mk:()=>a,Y0:()=>s,di:()=>r,jp:()=>o}),n(67294),(u=r||(r={})).REDIRECT="REDIRECT",u.MATCH_ROUTE="MATCH_ROUTE",(c=i||(i={})).NOTIFY_SUCCESS="NOTIFY_SUCCESS",c.NOTIFY_SUCCESS_MSG="NOTIFY_SUCCESS_MSG",c.NOTIFY_ERROR="NOTIFY_ERROR",c.NOTIFY_ERROR_MSG="NOTIFY_ERROR_MSG",(l=a||(a={})).REQUEST_SIGNIN="REQUEST_SIGNIN",l.RECEIVE_SIGNIN_SUCCESS="RECEIVE_SIGNIN_SUCCESS",l.RECEIVE_SIGNIN_FAIL="RECEIVE_SIGNIN_FAIL",l.RECEIVE_SIGNIN_ERROR="RECEIVE_SIGNIN_ERROR",l.RECEIVE_SIGNOUT_SUCCESS="RECEIVE_SIGNOUT_SUCCESS",l.RECEIVE_SIGNOUT_ERROR="RECEIVE_SIGNOUT_ERROR",(f=o||(o={})).RECEIVE_CREATE_ERROR="RECEIVE_CREATE_ERROR",f.RECEIVE_CREATE_SUCCESS="RECEIVE_CREATE_SUCCESS",f.RECEIVE_DELETE_ERROR="RECEIVE_DELETE_ERROR",f.RECEIVE_DELETE_SUCCESS="RECEIVE_DELETE_SUCCESS",f.RECEIVE_UPDATE_ERROR="RECEIVE_UPDATE_ERROR",f.RECEIVE_UPDATE_SUCCESS="RECEIVE_UPDATE_SUCCESS",f.REQUEST_CREATE="REQUEST_CREATE",f.REQUEST_DELETE="REQUEST_DELETE",f.REQUEST_UPDATE="REQUEST_UPDATE",f.UPSERT_CONFIGURATION="UPSERT_CONFIGURATION",f.UPSERT_JOB_RUN="UPSERT_JOB_RUN",f.UPSERT_JOB_RUNS="UPSERT_JOB_RUNS",f.UPSERT_TRANSACTION="UPSERT_TRANSACTION",f.UPSERT_TRANSACTIONS="UPSERT_TRANSACTIONS",f.UPSERT_BUILD_INFO="UPSERT_BUILD_INFO",(d=s||(s={})).FETCH_BUILD_INFO_REQUESTED="FETCH_BUILD_INFO_REQUESTED",d.FETCH_BUILD_INFO_SUCCEEDED="FETCH_BUILD_INFO_SUCCEEDED",d.FETCH_BUILD_INFO_FAILED="FETCH_BUILD_INFO_FAILED"},87013(e,t,n){"use strict";n.d(t,{Y:()=>o,Z:()=>u});var r=n(19084);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:o,t=arguments.length>1?arguments[1]:void 0;return t.type===r.Y0.FETCH_BUILD_INFO_SUCCEEDED?a({},t.buildInfo):e};let u=s},34823(e,t,n){"use strict";n.d(t,{N:()=>r});var r=function(e){return e.buildInfo}},73343(e,t,n){"use strict";n.d(t,{r:()=>u});var r=n(19350),i=n(32316),a=n(59114),o=n(5324),s={props:{MuiGrid:{spacing:3*o.default.unit},MuiCardHeader:{titleTypographyProps:{color:"secondary"}}},palette:{action:{hoverOpacity:.3},primary:{light:"#E5F1FF",main:"#3c40c6",contrastText:"#fff"},secondary:{main:"#3d5170"},success:{light:"#e8faf1",main:r.ek.A700,dark:r.ek[700],contrastText:r.y0.white},warning:{light:"#FFFBF1",main:"#fff6b6",contrastText:"#fad27a"},error:{light:"#ffdada",main:"#f44336",dark:"#d32f2f",contrastText:"#fff"},background:{default:"#f5f6f8",appBar:"#3c40c6"},text:{primary:(0,a.darken)(r.BA.A700,.7),secondary:"#818ea3"},listPendingStatus:{background:"#fef7e5",color:"#fecb4c"},listCompletedStatus:{background:"#e9faf2",color:"#4ed495"}},shape:{borderRadius:o.default.unit},overrides:{MuiButton:{root:{borderRadius:o.default.unit/2,textTransform:"none"},sizeLarge:{padding:void 0,fontSize:void 0,paddingTop:o.default.unit,paddingBottom:o.default.unit,paddingLeft:5*o.default.unit,paddingRight:5*o.default.unit}},MuiTableCell:{body:{fontSize:"1rem"},head:{fontSize:"1rem",fontWeight:400}},MuiCardHeader:{root:{borderBottom:"1px solid rgba(0, 0, 0, 0.12)"},action:{marginTop:-2,marginRight:0,"& >*":{marginLeft:2*o.default.unit}},subheader:{marginTop:.5*o.default.unit}}},typography:{useNextVariants:!0,fontFamily:"-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif",button:{textTransform:"none",fontSize:"1.2em"},body1:{fontSize:"1.0rem",fontWeight:400,lineHeight:"1.46429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body2:{fontSize:"1.0rem",fontWeight:500,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body1Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"1rem",lineHeight:1.5,letterSpacing:-.4},body2Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"0.875rem",lineHeight:1.5,letterSpacing:-.4},display1:{color:"#818ea3",fontSize:"2.125rem",fontWeight:400,lineHeight:"1.20588em",letterSpacing:-.4},display2:{color:"#818ea3",fontSize:"2.8125rem",fontWeight:400,lineHeight:"1.13333em",marginLeft:"-.02em",letterSpacing:-.4},display3:{color:"#818ea3",fontSize:"3.5rem",fontWeight:400,lineHeight:"1.30357em",marginLeft:"-.02em",letterSpacing:-.4},display4:{fontSize:14,fontWeightLight:300,fontWeightMedium:500,fontWeightRegular:400,letterSpacing:-.4},h1:{color:"rgb(29, 29, 29)",fontSize:"6rem",fontWeight:300,lineHeight:1},h2:{color:"rgb(29, 29, 29)",fontSize:"3.75rem",fontWeight:300,lineHeight:1},h3:{color:"rgb(29, 29, 29)",fontSize:"3rem",fontWeight:400,lineHeight:1.04},h4:{color:"rgb(29, 29, 29)",fontSize:"2.125rem",fontWeight:400,lineHeight:1.17},h5:{color:"rgb(29, 29, 29)",fontSize:"1.5rem",fontWeight:400,lineHeight:1.33,letterSpacing:-.4},h6:{fontSize:"0.8rem",fontWeight:450,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},subheading:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:"1.5em",letterSpacing:-.4},subtitle1:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:1.75,letterSpacing:-.4},subtitle2:{color:"rgb(29, 29, 29)",fontSize:"0.875rem",fontWeight:500,lineHeight:1.57,letterSpacing:-.4}},shadows:["none","0px 1px 3px 0px rgba(0, 0, 0, 0.1),0px 1px 1px 0px rgba(0, 0, 0, 0.04),0px 2px 1px -1px rgba(0, 0, 0, 0.02)","0px 1px 5px 0px rgba(0, 0, 0, 0.1),0px 2px 2px 0px rgba(0, 0, 0, 0.04),0px 3px 1px -2px rgba(0, 0, 0, 0.02)","0px 1px 8px 0px rgba(0, 0, 0, 0.1),0px 3px 4px 0px rgba(0, 0, 0, 0.04),0px 3px 3px -2px rgba(0, 0, 0, 0.02)","0px 2px 4px -1px rgba(0, 0, 0, 0.1),0px 4px 5px 0px rgba(0, 0, 0, 0.04),0px 1px 10px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 5px 8px 0px rgba(0, 0, 0, 0.04),0px 1px 14px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 6px 10px 0px rgba(0, 0, 0, 0.04),0px 1px 18px 0px rgba(0, 0, 0, 0.02)","0px 4px 5px -2px rgba(0, 0, 0, 0.1),0px 7px 10px 1px rgba(0, 0, 0, 0.04),0px 2px 16px 1px rgba(0, 0, 0, 0.02)","0px 5px 5px -3px rgba(0, 0, 0, 0.1),0px 8px 10px 1px rgba(0, 0, 0, 0.04),0px 3px 14px 2px rgba(0, 0, 0, 0.02)","0px 5px 6px -3px rgba(0, 0, 0, 0.1),0px 9px 12px 1px rgba(0, 0, 0, 0.04),0px 3px 16px 2px rgba(0, 0, 0, 0.02)","0px 6px 6px -3px rgba(0, 0, 0, 0.1),0px 10px 14px 1px rgba(0, 0, 0, 0.04),0px 4px 18px 3px rgba(0, 0, 0, 0.02)","0px 6px 7px -4px rgba(0, 0, 0, 0.1),0px 11px 15px 1px rgba(0, 0, 0, 0.04),0px 4px 20px 3px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 12px 17px 2px rgba(0, 0, 0, 0.04),0px 5px 22px 4px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 13px 19px 2px rgba(0, 0, 0, 0.04),0px 5px 24px 4px rgba(0, 0, 0, 0.02)","0px 7px 9px -4px rgba(0, 0, 0, 0.1),0px 14px 21px 2px rgba(0, 0, 0, 0.04),0px 5px 26px 4px rgba(0, 0, 0, 0.02)","0px 8px 9px -5px rgba(0, 0, 0, 0.1),0px 15px 22px 2px rgba(0, 0, 0, 0.04),0px 6px 28px 5px rgba(0, 0, 0, 0.02)","0px 8px 10px -5px rgba(0, 0, 0, 0.1),0px 16px 24px 2px rgba(0, 0, 0, 0.04),0px 6px 30px 5px rgba(0, 0, 0, 0.02)","0px 8px 11px -5px rgba(0, 0, 0, 0.1),0px 17px 26px 2px rgba(0, 0, 0, 0.04),0px 6px 32px 5px rgba(0, 0, 0, 0.02)","0px 9px 11px -5px rgba(0, 0, 0, 0.1),0px 18px 28px 2px rgba(0, 0, 0, 0.04),0px 7px 34px 6px rgba(0, 0, 0, 0.02)","0px 9px 12px -6px rgba(0, 0, 0, 0.1),0px 19px 29px 2px rgba(0, 0, 0, 0.04),0px 7px 36px 6px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 20px 31px 3px rgba(0, 0, 0, 0.04),0px 8px 38px 7px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 21px 33px 3px rgba(0, 0, 0, 0.04),0px 8px 40px 7px rgba(0, 0, 0, 0.02)","0px 10px 14px -6px rgba(0, 0, 0, 0.1),0px 22px 35px 3px rgba(0, 0, 0, 0.04),0px 8px 42px 7px rgba(0, 0, 0, 0.02)","0px 11px 14px -7px rgba(0, 0, 0, 0.1),0px 23px 36px 3px rgba(0, 0, 0, 0.04),0px 9px 44px 8px rgba(0, 0, 0, 0.02)","0px 11px 15px -7px rgba(0, 0, 0, 0.1),0px 24px 38px 3px rgba(0, 0, 0, 0.04),0px 9px 46px 8px rgba(0, 0, 0, 0.02)",]},u=(0,i.createMuiTheme)(s)},66289(e,t,n){"use strict";function r(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function a(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&f(i,n.prototype),i}).apply(null,arguments)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}function c(e){return -1!==Function.toString.call(e).indexOf("[native code]")}function l(e,t){return t&&("object"===p(t)||"function"==typeof t)?t:r(e)}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{V0:()=>B,_7:()=>v});var d,h,p=function(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};function b(e){var t="function"==typeof Map?new Map:void 0;return(b=function(e){if(null===e||!c(e))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return o(e,arguments,s(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,e)})(e)}function m(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}function g(e){var t=m();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}var v=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"AuthenticationError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e},],r}return n}(b(Error)),y=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"BadRequestError")).errors=a,r}return n}(b(Error)),w=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnprocessableEntityError")).errors=e,r}return n}(b(Error)),_=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"ServerError")).errors=e,r}return n}(b(Error)),E=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"ConflictError")).errors=a,r}return n}(b(Error)),S=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnknownResponseError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e.statusText},],r}return n}(b(Error));function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2e4;return Promise.race([fetch(e,t),new Promise(function(e,t){return setTimeout(function(){return t(Error("timeout"))},n)}),])}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=200&&e.status<300))return[3,2];return[2,e.json()];case 2:if(400!==e.status)return[3,3];return[2,e.json().then(function(e){throw new y(e)})];case 3:if(401!==e.status)return[3,4];throw new v(e);case 4:if(422!==e.status)return[3,6];return[4,$(e)];case 5:throw n=i.sent(),new w(n);case 6:if(409!==e.status)return[3,7];return[2,e.json().then(function(e){throw new E(e)})];case 7:if(!(e.status>=500))return[3,9];return[4,$(e)];case 8:throw r=i.sent(),new _(r);case 9:throw new S(e);case 10:return[2]}})})).apply(this,arguments)}function $(e){return z.apply(this,arguments)}function z(){return(z=j(function(e){return Y(this,function(t){return[2,e.json().then(function(t){return t.errors?t.errors.map(function(t){return{status:e.status,detail:t.detail}}):G(e)}).catch(function(){return G(e)})]})})).apply(this,arguments)}function G(e){return[{status:e.status,detail:e.statusText},]}},50109(e,t,n){"use strict";n.d(t,{LK:()=>o,U2:()=>i,eT:()=>s,t8:()=>a});var r=n(12795);function i(e){return r.ZP.getItem("chainlink.".concat(e))}function a(e,t){r.ZP.setItem("chainlink.".concat(e),t)}function o(e){var t=i(e),n={};if(t)try{return JSON.parse(t)}catch(r){}return n}function s(e,t){a(e,JSON.stringify(t))}},9541(e,t,n){"use strict";n.d(t,{Ks:()=>u,Tp:()=>a,iR:()=>o,pm:()=>s});var r=n(50109),i="persistURL";function a(){return r.U2(i)||""}function o(e){r.t8(i,e)}function s(){return r.LK("authentication")}function u(e){r.eT("authentication",e)}},67121(e,t,n){"use strict";function r(e){var t,n=e.Symbol;return"function"==typeof n?n.observable?t=n.observable:(t=n("observable"),n.observable=t):t="@@observable",t}n.r(t),n.d(t,{default:()=>o}),e=n.hmd(e),i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:e;var i,a=r(i);let o=a},2177(e,t,n){"use strict";n.d(t,{Z:()=>o});var r=!0,i="Invariant failed";function a(e,t){if(!e){if(r)throw Error(i);throw Error(i+": "+(t||""))}}let o=a},11742(e){e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;ru,ZT:()=>i,_T:()=>o,ev:()=>c,mG:()=>s,pi:()=>a});var r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)};function i(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(n[r[i]]=e[r[i]]);return n}function s(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,a){function o(e){try{u(r.next(e))}catch(t){a(t)}}function s(e){try{u(r.throw(e))}catch(t){a(t)}}function u(e){e.done?n(e.value):i(e.value).then(o,s)}u((r=r.apply(e,t||[])).next())})}function u(e,t){var n,r,i,a,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(e){return function(t){return u([e,t])}}function u(a){if(n)throw TypeError("Generator is already executing.");for(;o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!(i=(i=o.trys).length>0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]r})},94927(e,t,n){function r(e,t){if(i("noDeprecation"))return e;var n=!1;function r(){if(!n){if(i("throwDeprecation"))throw Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}return r}function i(e){try{if(!n.g.localStorage)return!1}catch(t){return!1}var r=n.g.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=r},42473(e){"use strict";var t=function(){};e.exports=t},84763(e){e.exports=Worker},47529(e){e.exports=n;var t=Object.prototype.hasOwnProperty;function n(){for(var e={},n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},7071(e){function t(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},94993(e,t,n){var r=n(18698).default,i=n(66115);function a(e,t){if(t&&("object"===r(t)||"function"==typeof t))return t;if(void 0!==t)throw TypeError("Derived constructors may only return object or undefined");return i(e)}e.exports=a,e.exports.__esModule=!0,e.exports.default=e.exports},6015(e){function t(n,r){return e.exports=t=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n,r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},861(e,t,n){var r=n(63405),i=n(79498),a=n(86116),o=n(42281);function s(e){return r(e)||i(e)||a(e)||o()}e.exports=s,e.exports.__esModule=!0,e.exports.default=e.exports},18698(e){function t(n){return e.exports=t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},86116(e,t,n){var r=n(73897);function i(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},1644(e,t,n){"use strict";var r,i;function a(e){return!!e&&e<7}n.d(t,{I:()=>r,O:()=>a}),(i=r||(r={}))[i.loading=1]="loading",i[i.setVariables=2]="setVariables",i[i.fetchMore=3]="fetchMore",i[i.refetch=4]="refetch",i[i.poll=6]="poll",i[i.ready=7]="ready",i[i.error=8]="error"},30990(e,t,n){"use strict";n.d(t,{MS:()=>s,YG:()=>a,cA:()=>c,ls:()=>o});var r=n(70655);n(83952);var i=n(13154),a=Symbol();function o(e){return!!e.extensions&&Array.isArray(e.extensions[a])}function s(e){return e.hasOwnProperty("graphQLErrors")}var u=function(e){var t=(0,r.ev)((0,r.ev)((0,r.ev)([],e.graphQLErrors,!0),e.clientErrors,!0),e.protocolErrors,!0);return e.networkError&&t.push(e.networkError),t.map(function(e){return(0,i.s)(e)&&e.message||"Error message not found."}).join("\n")},c=function(e){function t(n){var r=n.graphQLErrors,i=n.protocolErrors,a=n.clientErrors,o=n.networkError,s=n.errorMessage,c=n.extraInfo,l=e.call(this,s)||this;return l.name="ApolloError",l.graphQLErrors=r||[],l.protocolErrors=i||[],l.clientErrors=a||[],l.networkError=o||null,l.message=s||u(l),l.extraInfo=c,l.__proto__=t.prototype,l}return(0,r.ZT)(t,e),t}(Error)},85317(e,t,n){"use strict";n.d(t,{K:()=>a});var r=n(67294),i=n(30320).aS?Symbol.for("__APOLLO_CONTEXT__"):"__APOLLO_CONTEXT__";function a(){var e=r.createContext[i];return e||(Object.defineProperty(r.createContext,i,{value:e=r.createContext({}),enumerable:!1,writable:!1,configurable:!0}),e.displayName="ApolloContext"),e}},21436(e,t,n){"use strict";n.d(t,{O:()=>i,k:()=>r});var r=Array.isArray;function i(e){return Array.isArray(e)&&e.length>0}},30320(e,t,n){"use strict";n.d(t,{DN:()=>s,JC:()=>l,aS:()=>o,mr:()=>i,sy:()=>a});var r=n(83952),i="function"==typeof WeakMap&&"ReactNative"!==(0,r.wY)(function(){return navigator.product}),a="function"==typeof WeakSet,o="function"==typeof Symbol&&"function"==typeof Symbol.for,s=o&&Symbol.asyncIterator,u="function"==typeof(0,r.wY)(function(){return window.document.createElement}),c=(0,r.wY)(function(){return navigator.userAgent.indexOf("jsdom")>=0})||!1,l=u&&!c},53712(e,t,n){"use strict";function r(){for(var e=[],t=0;tr})},10542(e,t,n){"use strict";n.d(t,{J:()=>o}),n(83952);var r=n(13154);function i(e){var t=new Set([e]);return t.forEach(function(e){(0,r.s)(e)&&a(e)===e&&Object.getOwnPropertyNames(e).forEach(function(n){(0,r.s)(e[n])&&t.add(e[n])})}),e}function a(e){if(__DEV__&&!Object.isFrozen(e))try{Object.freeze(e)}catch(t){if(t instanceof TypeError)return null;throw t}return e}function o(e){return __DEV__&&i(e),e}},14012(e,t,n){"use strict";n.d(t,{J:()=>a});var r=n(70655),i=n(53712);function a(e,t){return(0,i.o)(e,t,t.variables&&{variables:(0,r.pi)((0,r.pi)({},e&&e.variables),t.variables)})}},13154(e,t,n){"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{s:()=>r})},83952(e,t,n){"use strict";n.d(t,{ej:()=>u,kG:()=>c,wY:()=>h});var r,i=n(70655),a="Invariant Violation",o=Object.setPrototypeOf,s=void 0===o?function(e,t){return e.__proto__=t,e}:o,u=function(e){function t(n){void 0===n&&(n=a);var r=e.call(this,"number"==typeof n?a+": "+n+" (see https://github.com/apollographql/invariant-packages)":n)||this;return r.framesToPop=1,r.name=a,s(r,t.prototype),r}return(0,i.ZT)(t,e),t}(Error);function c(e,t){if(!e)throw new u(t)}var l=["debug","log","warn","error","silent"],f=l.indexOf("log");function d(e){return function(){if(l.indexOf(e)>=f)return(console[e]||console.log).apply(console,arguments)}}function h(e){try{return e()}catch(t){}}(r=c||(c={})).debug=d("debug"),r.log=d("log"),r.warn=d("warn"),r.error=d("error");let p=h(function(){return globalThis})||h(function(){return window})||h(function(){return self})||h(function(){return global})||h(function(){return h.constructor("return this")()});var b="__",m=[b,b].join("DEV");function g(){try{return Boolean(__DEV__)}catch(e){return Object.defineProperty(p,m,{value:"production"!==h(function(){return"production"}),enumerable:!1,configurable:!0,writable:!0}),p[m]}}let v=g();function y(e){try{return e()}catch(t){}}var w=y(function(){return globalThis})||y(function(){return window})||y(function(){return self})||y(function(){return global})||y(function(){return y.constructor("return this")()}),_=!1;function E(){!w||y(function(){return"production"})||y(function(){return process})||(Object.defineProperty(w,"process",{value:{env:{NODE_ENV:"production"}},configurable:!0,enumerable:!1,writable:!0}),_=!0)}function S(){_&&(delete w.process,_=!1)}E();var k=n(10143);function x(){return k.H,S()}function T(){__DEV__?c("boolean"==typeof v,v):c("boolean"==typeof v,39)}x(),T()},4942(e,t,n){"use strict";function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}n.d(t,{Z:()=>r})},87462(e,t,n){"use strict";function r(){return(r=Object.assign?Object.assign.bind():function(e){for(var t=1;tr})},51721(e,t,n){"use strict";function r(e,t){return(r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e})(e,t)}function i(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>i})},63366(e,t,n){"use strict";function r(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}n.d(t,{Z:()=>r})},25821(e,t,n){"use strict";n.d(t,{Z:()=>s});var r=n(45695);function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=10,o=2;function s(e){return u(e,[])}function u(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":if(null===e)return"null";return c(e,t);default:return String(e)}}function c(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=d(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:u(i,n)}else if(Array.isArray(e))return f(e,n);return l(e,n)}function l(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>o?"["+h(e)+"]":"{ "+n.map(function(n){var r=u(e[n],t);return n+": "+r}).join(", ")+" }"}function f(e,t){if(0===e.length)return"[]";if(t.length>o)return"[Array]";for(var n=Math.min(a,e.length),r=e.length-n,i=[],s=0;s1&&i.push("... ".concat(r," more items")),"["+i.join(", ")+"]"}function d(e){var t=e[String(r.Z)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}function h(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}},45695(e,t,n){"use strict";n.d(t,{Z:()=>i});var r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;let i=r},25217(e,t,n){"use strict";function r(e,t){if(!Boolean(e))throw Error(null!=t?t:"Unexpected invariant triggered.")}n.d(t,{Ye:()=>o,WU:()=>s,UG:()=>u});var i=n(45695);function a(e){var t=e.prototype.toJSON;"function"==typeof t||r(0),e.prototype.inspect=t,i.Z&&(e.prototype[i.Z]=t)}var o=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();a(o);var s=function(){function e(e,t,n,r,i,a,o){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=i,this.value=o,this.prev=a,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();function u(e){return null!=e&&"string"==typeof e.kind}a(s)},87392(e,t,n){"use strict";function r(e){var t=e.split(/\r\n|[\n\r]/g),n=a(e);if(0!==n)for(var r=1;ro&&i(t[s-1]);)--s;return t.slice(o,s).join("\n")}function i(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),i=" "===e[0]||" "===e[0],a='"'===e[e.length-1],o="\\"===e[e.length-1],s=!r||a||o||n,u="";return s&&!(r&&i)&&(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}n.d(t,{LZ:()=>o,W7:()=>r})},97359(e,t,n){"use strict";n.d(t,{h:()=>r});var r=Object.freeze({NAME:"Name",DOCUMENT:"Document",OPERATION_DEFINITION:"OperationDefinition",VARIABLE_DEFINITION:"VariableDefinition",SELECTION_SET:"SelectionSet",FIELD:"Field",ARGUMENT:"Argument",FRAGMENT_SPREAD:"FragmentSpread",INLINE_FRAGMENT:"InlineFragment",FRAGMENT_DEFINITION:"FragmentDefinition",VARIABLE:"Variable",INT:"IntValue",FLOAT:"FloatValue",STRING:"StringValue",BOOLEAN:"BooleanValue",NULL:"NullValue",ENUM:"EnumValue",LIST:"ListValue",OBJECT:"ObjectValue",OBJECT_FIELD:"ObjectField",DIRECTIVE:"Directive",NAMED_TYPE:"NamedType",LIST_TYPE:"ListType",NON_NULL_TYPE:"NonNullType",SCHEMA_DEFINITION:"SchemaDefinition",OPERATION_TYPE_DEFINITION:"OperationTypeDefinition",SCALAR_TYPE_DEFINITION:"ScalarTypeDefinition",OBJECT_TYPE_DEFINITION:"ObjectTypeDefinition",FIELD_DEFINITION:"FieldDefinition",INPUT_VALUE_DEFINITION:"InputValueDefinition",INTERFACE_TYPE_DEFINITION:"InterfaceTypeDefinition",UNION_TYPE_DEFINITION:"UnionTypeDefinition",ENUM_TYPE_DEFINITION:"EnumTypeDefinition",ENUM_VALUE_DEFINITION:"EnumValueDefinition",INPUT_OBJECT_TYPE_DEFINITION:"InputObjectTypeDefinition",DIRECTIVE_DEFINITION:"DirectiveDefinition",SCHEMA_EXTENSION:"SchemaExtension",SCALAR_TYPE_EXTENSION:"ScalarTypeExtension",OBJECT_TYPE_EXTENSION:"ObjectTypeExtension",INTERFACE_TYPE_EXTENSION:"InterfaceTypeExtension",UNION_TYPE_EXTENSION:"UnionTypeExtension",ENUM_TYPE_EXTENSION:"EnumTypeExtension",INPUT_OBJECT_TYPE_EXTENSION:"InputObjectTypeExtension"})},10143(e,t,n){"use strict";n.d(t,{H:()=>c,T:()=>l});var r=n(99763),i=n(25821);function a(e,t){if(!Boolean(e))throw Error(t)}let o=function(e,t){return e instanceof t};function s(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||a(0,"Body must be a string. Received: ".concat((0,i.Z)(e),".")),this.body=e,this.name=t,this.locationOffset=n,this.locationOffset.line>0||a(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||a(0,"column in locationOffset is 1-indexed and must be positive.")}return u(e,[{key:r.YF,get:function(){return"Source"}}]),e}();function l(e){return o(e,c)}},99763(e,t,n){"use strict";n.d(t,{YF:()=>r});var r="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag"},37452(e){"use strict";e.exports=JSON.parse('{"AElig":"\xc6","AMP":"&","Aacute":"\xc1","Acirc":"\xc2","Agrave":"\xc0","Aring":"\xc5","Atilde":"\xc3","Auml":"\xc4","COPY":"\xa9","Ccedil":"\xc7","ETH":"\xd0","Eacute":"\xc9","Ecirc":"\xca","Egrave":"\xc8","Euml":"\xcb","GT":">","Iacute":"\xcd","Icirc":"\xce","Igrave":"\xcc","Iuml":"\xcf","LT":"<","Ntilde":"\xd1","Oacute":"\xd3","Ocirc":"\xd4","Ograve":"\xd2","Oslash":"\xd8","Otilde":"\xd5","Ouml":"\xd6","QUOT":"\\"","REG":"\xae","THORN":"\xde","Uacute":"\xda","Ucirc":"\xdb","Ugrave":"\xd9","Uuml":"\xdc","Yacute":"\xdd","aacute":"\xe1","acirc":"\xe2","acute":"\xb4","aelig":"\xe6","agrave":"\xe0","amp":"&","aring":"\xe5","atilde":"\xe3","auml":"\xe4","brvbar":"\xa6","ccedil":"\xe7","cedil":"\xb8","cent":"\xa2","copy":"\xa9","curren":"\xa4","deg":"\xb0","divide":"\xf7","eacute":"\xe9","ecirc":"\xea","egrave":"\xe8","eth":"\xf0","euml":"\xeb","frac12":"\xbd","frac14":"\xbc","frac34":"\xbe","gt":">","iacute":"\xed","icirc":"\xee","iexcl":"\xa1","igrave":"\xec","iquest":"\xbf","iuml":"\xef","laquo":"\xab","lt":"<","macr":"\xaf","micro":"\xb5","middot":"\xb7","nbsp":"\xa0","not":"\xac","ntilde":"\xf1","oacute":"\xf3","ocirc":"\xf4","ograve":"\xf2","ordf":"\xaa","ordm":"\xba","oslash":"\xf8","otilde":"\xf5","ouml":"\xf6","para":"\xb6","plusmn":"\xb1","pound":"\xa3","quot":"\\"","raquo":"\xbb","reg":"\xae","sect":"\xa7","shy":"\xad","sup1":"\xb9","sup2":"\xb2","sup3":"\xb3","szlig":"\xdf","thorn":"\xfe","times":"\xd7","uacute":"\xfa","ucirc":"\xfb","ugrave":"\xf9","uml":"\xa8","uuml":"\xfc","yacute":"\xfd","yen":"\xa5","yuml":"\xff"}')},93580(e){"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},67946(e){"use strict";e.exports=JSON.parse('{"locale":"en","long":{"year":{"previous":"last year","current":"this year","next":"next year","past":{"one":"{0} year ago","other":"{0} years ago"},"future":{"one":"in {0} year","other":"in {0} years"}},"quarter":{"previous":"last quarter","current":"this quarter","next":"next quarter","past":{"one":"{0} quarter ago","other":"{0} quarters ago"},"future":{"one":"in {0} quarter","other":"in {0} quarters"}},"month":{"previous":"last month","current":"this month","next":"next month","past":{"one":"{0} month ago","other":"{0} months ago"},"future":{"one":"in {0} month","other":"in {0} months"}},"week":{"previous":"last week","current":"this week","next":"next week","past":{"one":"{0} week ago","other":"{0} weeks ago"},"future":{"one":"in {0} week","other":"in {0} weeks"}},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":{"one":"{0} hour ago","other":"{0} hours ago"},"future":{"one":"in {0} hour","other":"in {0} hours"}},"minute":{"current":"this minute","past":{"one":"{0} minute ago","other":"{0} minutes ago"},"future":{"one":"in {0} minute","other":"in {0} minutes"}},"second":{"current":"now","past":{"one":"{0} second ago","other":"{0} seconds ago"},"future":{"one":"in {0} second","other":"in {0} seconds"}}},"short":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"narrow":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"now":{"now":{"current":"now","future":"in a moment","past":"just now"}},"mini":{"year":"{0}yr","month":"{0}mo","week":"{0}wk","day":"{0}d","hour":"{0}h","minute":"{0}m","second":"{0}s","now":"now"},"short-time":{"year":"{0} yr.","month":"{0} mo.","week":"{0} wk.","day":{"one":"{0} day","other":"{0} days"},"hour":"{0} hr.","minute":"{0} min.","second":"{0} sec."},"long-time":{"year":{"one":"{0} year","other":"{0} years"},"month":{"one":"{0} month","other":"{0} months"},"week":{"one":"{0} week","other":"{0} weeks"},"day":{"one":"{0} day","other":"{0} days"},"hour":{"one":"{0} hour","other":"{0} hours"},"minute":{"one":"{0} minute","other":"{0} minutes"},"second":{"one":"{0} second","other":"{0} seconds"}}}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;__webpack_require__.t=function(n,r){if(1&r&&(n=this(n)),8&r||"object"==typeof n&&n&&(4&r&&n.__esModule||16&r&&"function"==typeof n.then))return n;var i=Object.create(null);__webpack_require__.r(i);var a={};e=e||[null,t({}),t([]),t(t)];for(var o=2&r&&n;"object"==typeof o&&!~e.indexOf(o);o=t(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,__webpack_require__.d(i,a),i}})(),__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set(){throw Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__.p="/assets/",__webpack_require__.nc=void 0;var __webpack_exports__={};(()=>{"use strict";var e,t,n,r,i=__webpack_require__(32316),a=__webpack_require__(8126),o=__webpack_require__(5690),s=__webpack_require__(30381),u=__webpack_require__.n(s),c=__webpack_require__(67294),l=__webpack_require__(73935),f=__webpack_require__.n(l),d=__webpack_require__(57209),h=__webpack_require__(37703),p=__webpack_require__(97779),b=__webpack_require__(28500);function m(e){return function(t){var n=t.dispatch,r=t.getState;return function(t){return function(i){return"function"==typeof i?i(n,r,e):t(i)}}}}var g=m();g.withExtraArgument=m;let v=g;var y=__webpack_require__(76489);function w(e){return function(t){return function(n){return function(r){n(r);var i=e||document&&document.cookie||"",a=t.getState();if("MATCH_ROUTE"===r.type&&"/signin"!==a.notifications.currentUrl){var o=(0,y.Q)(i);if(o.explorer)try{var s=JSON.parse(o.explorer);if("error"===s.status){var u=_(s.url);n({type:"NOTIFY_ERROR_MSG",msg:u})}}catch(c){n({type:"NOTIFY_ERROR_MSG",msg:"Invalid explorer status"})}}}}}}function _(e){var t="Can't connect to explorer: ".concat(e);return e.match(/^wss?:.+/)?t:"".concat(t,". You must use a websocket.")}var E=__webpack_require__(16353);function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ei(e,t){if(e){if("string"==typeof e)return ea(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ea(e,t)}}function ea(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1,i=!1,a=arguments[1],o=a;return new n(function(n){return t.subscribe({next:function(t){var a=!i;if(i=!0,!a||r)try{o=e(o,t)}catch(s){return n.error(s)}else o=t},error:function(e){n.error(e)},complete:function(){if(!i&&!r)return n.error(TypeError("Cannot reduce an empty sequence"));n.next(o),n.complete()}})})},t.concat=function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r=0&&i.splice(e,1),o()}});i.push(s)},error:function(e){r.error(e)},complete:function(){o()}});function o(){a.closed&&0===i.length&&r.complete()}return function(){i.forEach(function(e){return e.unsubscribe()}),a.unsubscribe()}})},t[ed]=function(){return this},e.from=function(t){var n="function"==typeof this?this:e;if(null==t)throw TypeError(t+" is not an object");var r=ep(t,ed);if(r){var i=r.call(t);if(Object(i)!==i)throw TypeError(i+" is not an object");return em(i)&&i.constructor===n?i:new n(function(e){return i.subscribe(e)})}if(ec("iterator")&&(r=ep(t,ef)))return new n(function(e){ev(function(){if(!e.closed){for(var n,i=er(r.call(t));!(n=i()).done;){var a=n.value;if(e.next(a),e.closed)return}e.complete()}})});if(Array.isArray(t))return new n(function(e){ev(function(){if(!e.closed){for(var n=0;n0))return n.connection.key;var r=n.connection.filter?n.connection.filter:[];r.sort();var i={};return r.forEach(function(e){i[e]=t[e]}),"".concat(n.connection.key,"(").concat(eV(i),")")}var a=e;if(t){var o=eV(t);a+="(".concat(o,")")}return n&&Object.keys(n).forEach(function(e){-1===eW.indexOf(e)&&(n[e]&&Object.keys(n[e]).length?a+="@".concat(e,"(").concat(eV(n[e]),")"):a+="@".concat(e))}),a},{setStringify:function(e){var t=eV;return eV=e,t}}),eV=function(e){return JSON.stringify(e,eq)};function eq(e,t){return(0,eO.s)(t)&&!Array.isArray(t)&&(t=Object.keys(t).sort().reduce(function(e,n){return e[n]=t[n],e},{})),t}function eZ(e,t){if(e.arguments&&e.arguments.length){var n={};return e.arguments.forEach(function(e){var r;return ez(n,e.name,e.value,t)}),n}return null}function eX(e){return e.alias?e.alias.value:e.name.value}function eJ(e,t,n){for(var r,i=0,a=t.selections;it.indexOf(i))throw __DEV__?new Q.ej("illegal argument: ".concat(i)):new Q.ej(27)}return e}function tt(e,t){return t?t(e):eT.of()}function tn(e){return"function"==typeof e?new ta(e):e}function tr(e){return e.request.length<=1}var ti=function(e){function t(t,n){var r=e.call(this,t)||this;return r.link=n,r}return(0,en.ZT)(t,e),t}(Error),ta=function(){function e(e){e&&(this.request=e)}return e.empty=function(){return new e(function(){return eT.of()})},e.from=function(t){return 0===t.length?e.empty():t.map(tn).reduce(function(e,t){return e.concat(t)})},e.split=function(t,n,r){var i=tn(n),a=tn(r||new e(tt));return new e(tr(i)&&tr(a)?function(e){return t(e)?i.request(e)||eT.of():a.request(e)||eT.of()}:function(e,n){return t(e)?i.request(e,n)||eT.of():a.request(e,n)||eT.of()})},e.execute=function(e,t){return e.request(eM(t.context,e7(te(t))))||eT.of()},e.concat=function(t,n){var r=tn(t);if(tr(r))return __DEV__&&Q.kG.warn(new ti("You are calling concat on a terminating link, which will have no effect",r)),r;var i=tn(n);return new e(tr(i)?function(e){return r.request(e,function(e){return i.request(e)||eT.of()})||eT.of()}:function(e,t){return r.request(e,function(e){return i.request(e,t)||eT.of()})||eT.of()})},e.prototype.split=function(t,n,r){return this.concat(e.split(t,n,r||new e(tt)))},e.prototype.concat=function(t){return e.concat(this,t)},e.prototype.request=function(e,t){throw __DEV__?new Q.ej("request is not implemented"):new Q.ej(22)},e.prototype.onError=function(e,t){if(t&&t.error)return t.error(e),!1;throw e},e.prototype.setOnError=function(e){return this.onError=e,this},e}(),to=__webpack_require__(25821),ts=__webpack_require__(25217),tu={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},tc=Object.freeze({});function tl(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:tu,r=void 0,i=Array.isArray(e),a=[e],o=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],d=[],h=e;do{var p,b=++o===a.length,m=b&&0!==s.length;if(b){if(c=0===d.length?void 0:f[f.length-1],u=l,l=d.pop(),m){if(i)u=u.slice();else{for(var g={},v=0,y=Object.keys(u);v1)for(var r=new tB,i=1;i=0;--a){var o=i[a],s=isNaN(+o)?{}:[];s[o]=t,t=s}n=r.merge(n,t)}),n}var tW=Object.prototype.hasOwnProperty;function tK(e,t){var n,r,i,a,o;return(0,en.mG)(this,void 0,void 0,function(){var s,u,c,l,f,d,h,p,b,m,g,v,y,w,_,E,S,k,x,T,M,O,A;return(0,en.Jh)(this,function(L){switch(L.label){case 0:if(void 0===TextDecoder)throw Error("TextDecoder must be defined in the environment: please import a polyfill.");s=new TextDecoder("utf-8"),u=null===(n=e.headers)||void 0===n?void 0:n.get("content-type"),c="boundary=",l=(null==u?void 0:u.includes(c))?null==u?void 0:u.substring((null==u?void 0:u.indexOf(c))+c.length).replace(/['"]/g,"").replace(/\;(.*)/gm,"").trim():"-",f="\r\n--".concat(l),d="",h=tI(e),p=!0,L.label=1;case 1:if(!p)return[3,3];return[4,h.next()];case 2:for(m=(b=L.sent()).value,g=b.done,v="string"==typeof m?m:s.decode(m),y=d.length-f.length+1,p=!g,d+=v,w=d.indexOf(f,y);w>-1;){if(_=void 0,_=(O=[d.slice(0,w),d.slice(w+f.length),])[0],d=O[1],E=_.indexOf("\r\n\r\n"),(k=(S=tV(_.slice(0,E)))["content-type"])&&-1===k.toLowerCase().indexOf("application/json"))throw Error("Unsupported patch content type: application/json is required.");if(x=_.slice(E))try{T=tq(e,x),Object.keys(T).length>1||"data"in T||"incremental"in T||"errors"in T||"payload"in T?tz(T)?(M={},"payload"in T&&(M=(0,en.pi)({},T.payload)),"errors"in T&&(M=(0,en.pi)((0,en.pi)({},M),{extensions:(0,en.pi)((0,en.pi)({},"extensions"in M?M.extensions:null),((A={})[tN.YG]=T.errors,A))})),null===(r=t.next)||void 0===r||r.call(t,M)):null===(i=t.next)||void 0===i||i.call(t,T):1===Object.keys(T).length&&"hasNext"in T&&!T.hasNext&&(null===(a=t.complete)||void 0===a||a.call(t))}catch(C){tZ(C,t)}w=d.indexOf(f)}return[3,1];case 3:return null===(o=t.complete)||void 0===o||o.call(t),[2]}})})}function tV(e){var t={};return e.split("\n").forEach(function(e){var n=e.indexOf(":");if(n>-1){var r=e.slice(0,n).trim().toLowerCase(),i=e.slice(n+1).trim();t[r]=i}}),t}function tq(e,t){e.status>=300&&tD(e,function(){try{return JSON.parse(t)}catch(e){return t}}(),"Response not successful: Received status code ".concat(e.status));try{return JSON.parse(t)}catch(n){var r=n;throw r.name="ServerParseError",r.response=e,r.statusCode=e.status,r.bodyText=t,r}}function tZ(e,t){var n,r;"AbortError"!==e.name&&(e.result&&e.result.errors&&e.result.data&&(null===(n=t.next)||void 0===n||n.call(t,e.result)),null===(r=t.error)||void 0===r||r.call(t,e))}function tX(e,t,n){tJ(t)(e).then(function(e){var t,r;null===(t=n.next)||void 0===t||t.call(n,e),null===(r=n.complete)||void 0===r||r.call(n)}).catch(function(e){return tZ(e,n)})}function tJ(e){return function(t){return t.text().then(function(e){return tq(t,e)}).then(function(n){return t.status>=300&&tD(t,n,"Response not successful: Received status code ".concat(t.status)),Array.isArray(n)||tW.call(n,"data")||tW.call(n,"errors")||tD(t,n,"Server response was missing for query '".concat(Array.isArray(e)?e.map(function(e){return e.operationName}):e.operationName,"'.")),n})}}var tQ=function(e){if(!e&&"undefined"==typeof fetch)throw __DEV__?new Q.ej("\n\"fetch\" has not been found globally and no fetcher has been configured. To fix this, install a fetch package (like https://www.npmjs.com/package/cross-fetch), instantiate the fetcher, and pass it into your HttpLink constructor. For example:\n\nimport fetch from 'cross-fetch';\nimport { ApolloClient, HttpLink } from '@apollo/client';\nconst client = new ApolloClient({\n link: new HttpLink({ uri: '/graphql', fetch })\n});\n "):new Q.ej(23)},t1=__webpack_require__(87392);function t0(e){return tl(e,{leave:t3})}var t2=80,t3={Name:function(e){return e.value},Variable:function(e){return"$"+e.name},Document:function(e){return t6(e.definitions,"\n\n")+"\n"},OperationDefinition:function(e){var t=e.operation,n=e.name,r=t8("(",t6(e.variableDefinitions,", "),")"),i=t6(e.directives," "),a=e.selectionSet;return n||i||r||"query"!==t?t6([t,t6([n,r]),i,a]," "):a},VariableDefinition:function(e){var t=e.variable,n=e.type,r=e.defaultValue,i=e.directives;return t+": "+n+t8(" = ",r)+t8(" ",t6(i," "))},SelectionSet:function(e){return t5(e.selections)},Field:function(e){var t=e.alias,n=e.name,r=e.arguments,i=e.directives,a=e.selectionSet,o=t8("",t,": ")+n,s=o+t8("(",t6(r,", "),")");return s.length>t2&&(s=o+t8("(\n",t9(t6(r,"\n")),"\n)")),t6([s,t6(i," "),a]," ")},Argument:function(e){var t;return e.name+": "+e.value},FragmentSpread:function(e){var t;return"..."+e.name+t8(" ",t6(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,n=e.directives,r=e.selectionSet;return t6(["...",t8("on ",t),t6(n," "),r]," ")},FragmentDefinition:function(e){var t=e.name,n=e.typeCondition,r=e.variableDefinitions,i=e.directives,a=e.selectionSet;return"fragment ".concat(t).concat(t8("(",t6(r,", "),")")," ")+"on ".concat(n," ").concat(t8("",t6(i," ")," "))+a},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var n=e.value;return e.block?(0,t1.LZ)(n,"description"===t?"":" "):JSON.stringify(n)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+t6(e.values,", ")+"]"},ObjectValue:function(e){return"{"+t6(e.fields,", ")+"}"},ObjectField:function(e){var t;return e.name+": "+e.value},Directive:function(e){var t;return"@"+e.name+t8("(",t6(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:t4(function(e){var t=e.directives,n=e.operationTypes;return t6(["schema",t6(t," "),t5(n)]," ")}),OperationTypeDefinition:function(e){var t;return e.operation+": "+e.type},ScalarTypeDefinition:t4(function(e){var t;return t6(["scalar",e.name,t6(e.directives," ")]," ")}),ObjectTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),FieldDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.type,i=e.directives;return t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+": "+r+t8(" ",t6(i," "))}),InputValueDefinition:t4(function(e){var t=e.name,n=e.type,r=e.defaultValue,i=e.directives;return t6([t+": "+n,t8("= ",r),t6(i," ")]," ")}),InterfaceTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),UnionTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.types;return t6(["union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")}),EnumTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.values;return t6(["enum",t,t6(n," "),t5(r)]," ")}),EnumValueDefinition:t4(function(e){var t;return t6([e.name,t6(e.directives," ")]," ")}),InputObjectTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["input",t,t6(n," "),t5(r)]," ")}),DirectiveDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.repeatable,i=e.locations;return"directive @"+t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+(r?" repeatable":"")+" on "+t6(i," | ")}),SchemaExtension:function(e){var t=e.directives,n=e.operationTypes;return t6(["extend schema",t6(t," "),t5(n)]," ")},ScalarTypeExtension:function(e){var t;return t6(["extend scalar",e.name,t6(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},InterfaceTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},UnionTypeExtension:function(e){var t=e.name,n=e.directives,r=e.types;return t6(["extend union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,n=e.directives,r=e.values;return t6(["extend enum",t,t6(n," "),t5(r)]," ")},InputObjectTypeExtension:function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["extend input",t,t6(n," "),t5(r)]," ")}};function t4(e){return function(t){return t6([t.description,e(t)],"\n")}}function t6(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter(function(e){return e}).join(n))&&void 0!==t?t:""}function t5(e){return t8("{\n",t9(t6(e,"\n")),"\n}")}function t8(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+n:""}function t9(e){return t8(" ",e.replace(/\n/g,"\n "))}function t7(e){return -1!==e.indexOf("\n")}function ne(e){return null!=e&&e.some(t7)}var nt,nn,nr,ni={http:{includeQuery:!0,includeExtensions:!1,preserveHeaderCase:!1},headers:{accept:"*/*","content-type":"application/json"},options:{method:"POST"}},na=function(e,t){return t(e)};function no(e,t){for(var n=[],r=2;rObject.create(null),{forEach:nv,slice:ny}=Array.prototype,{hasOwnProperty:nw}=Object.prototype;class n_{constructor(e=!0,t=ng){this.weakness=e,this.makeData=t}lookup(...e){return this.lookupArray(e)}lookupArray(e){let t=this;return nv.call(e,e=>t=t.getChildTrie(e)),nw.call(t,"data")?t.data:t.data=this.makeData(ny.call(e))}peek(...e){return this.peekArray(e)}peekArray(e){let t=this;for(let n=0,r=e.length;t&&n=0;--o)t.definitions[o].kind===nL.h.OPERATION_DEFINITION&&++a;var s=nN(e),u=e.some(function(e){return e.remove}),c=function(e){return u&&e&&e.some(s)},l=new Map,f=!1,d={enter:function(e){if(c(e.directives))return f=!0,null}},h=tl(t,{Field:d,InlineFragment:d,VariableDefinition:{enter:function(){return!1}},Variable:{enter:function(e,t,n,r,a){var o=i(a);o&&o.variables.add(e.name.value)}},FragmentSpread:{enter:function(e,t,n,r,a){if(c(e.directives))return f=!0,null;var o=i(a);o&&o.fragmentSpreads.add(e.name.value)}},FragmentDefinition:{enter:function(e,t,n,r){l.set(JSON.stringify(r),e)},leave:function(e,t,n,i){return e===l.get(JSON.stringify(i))?e:a>0&&e.selectionSet.selections.every(function(e){return e.kind===nL.h.FIELD&&"__typename"===e.name.value})?(r(e.name.value).removed=!0,f=!0,null):void 0}},Directive:{leave:function(e){if(s(e))return f=!0,null}}});if(!f)return t;var p=function(e){return e.transitiveVars||(e.transitiveVars=new Set(e.variables),e.removed||e.fragmentSpreads.forEach(function(t){p(r(t)).transitiveVars.forEach(function(t){e.transitiveVars.add(t)})})),e},b=new Set;h.definitions.forEach(function(e){e.kind===nL.h.OPERATION_DEFINITION?p(n(e.name&&e.name.value)).fragmentSpreads.forEach(function(e){b.add(e)}):e.kind!==nL.h.FRAGMENT_DEFINITION||0!==a||r(e.name.value).removed||b.add(e.name.value)}),b.forEach(function(e){p(r(e)).fragmentSpreads.forEach(function(e){b.add(e)})});var m=function(e){return!!(!b.has(e)||r(e).removed)},g={enter:function(e){if(m(e.name.value))return null}};return nD(tl(h,{FragmentSpread:g,FragmentDefinition:g,OperationDefinition:{leave:function(e){if(e.variableDefinitions){var t=p(n(e.name&&e.name.value)).transitiveVars;if(t.size0},t.prototype.tearDownQuery=function(){this.isTornDown||(this.concast&&this.observer&&(this.concast.removeObserver(this.observer),delete this.concast,delete this.observer),this.stopPolling(),this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions.clear(),this.queryManager.stopQuery(this.queryId),this.observers.clear(),this.isTornDown=!0)},t}(eT);function n4(e){var t=e.options,n=t.fetchPolicy,r=t.nextFetchPolicy;return"cache-and-network"===n||"network-only"===n?e.reobserve({fetchPolicy:"cache-first",nextFetchPolicy:function(){return(this.nextFetchPolicy=r,"function"==typeof r)?r.apply(this,arguments):n}}):e.reobserve()}function n6(e){__DEV__&&Q.kG.error("Unhandled error",e.message,e.stack)}function n5(e){__DEV__&&e&&__DEV__&&Q.kG.debug("Missing cache result fields: ".concat(JSON.stringify(e)),e)}function n8(e){return"network-only"===e||"no-cache"===e||"standby"===e}nK(n3);function n9(e){return e.kind===nL.h.FIELD||e.kind===nL.h.FRAGMENT_SPREAD||e.kind===nL.h.INLINE_FRAGMENT}function n7(e){return e.kind===Kind.SCALAR_TYPE_DEFINITION||e.kind===Kind.OBJECT_TYPE_DEFINITION||e.kind===Kind.INTERFACE_TYPE_DEFINITION||e.kind===Kind.UNION_TYPE_DEFINITION||e.kind===Kind.ENUM_TYPE_DEFINITION||e.kind===Kind.INPUT_OBJECT_TYPE_DEFINITION}function re(e){return e.kind===Kind.SCALAR_TYPE_EXTENSION||e.kind===Kind.OBJECT_TYPE_EXTENSION||e.kind===Kind.INTERFACE_TYPE_EXTENSION||e.kind===Kind.UNION_TYPE_EXTENSION||e.kind===Kind.ENUM_TYPE_EXTENSION||e.kind===Kind.INPUT_OBJECT_TYPE_EXTENSION}var rt=function(){return Object.create(null)},rn=Array.prototype,rr=rn.forEach,ri=rn.slice,ra=function(){function e(e,t){void 0===e&&(e=!0),void 0===t&&(t=rt),this.weakness=e,this.makeData=t}return e.prototype.lookup=function(){for(var e=[],t=0;tclass{constructor(){this.id=["slot",rc++,Date.now(),Math.random().toString(36).slice(2),].join(":")}hasValue(){for(let e=rs;e;e=e.parent)if(this.id in e.slots){let t=e.slots[this.id];if(t===ru)break;return e!==rs&&(rs.slots[this.id]=t),!0}return rs&&(rs.slots[this.id]=ru),!1}getValue(){if(this.hasValue())return rs.slots[this.id]}withValue(e,t,n,r){let i={__proto__:null,[this.id]:e},a=rs;rs={parent:a,slots:i};try{return t.apply(r,n)}finally{rs=a}}static bind(e){let t=rs;return function(){let n=rs;try{return rs=t,e.apply(this,arguments)}finally{rs=n}}}static noContext(e,t,n){if(!rs)return e.apply(n,t);{let r=rs;try{return rs=null,e.apply(n,t)}finally{rs=r}}}};function rf(e){try{return e()}catch(t){}}let rd="@wry/context:Slot",rh=rf(()=>globalThis)||rf(()=>global)||Object.create(null),rp=rh,rb=rp[rd]||Array[rd]||function(e){try{Object.defineProperty(rp,rd,{value:e,enumerable:!1,writable:!1,configurable:!0})}finally{return e}}(rl()),{bind:rm,noContext:rg}=rb;function rv(){}var ry=function(){function e(e,t){void 0===e&&(e=1/0),void 0===t&&(t=rv),this.max=e,this.dispose=t,this.map=new Map,this.newest=null,this.oldest=null}return e.prototype.has=function(e){return this.map.has(e)},e.prototype.get=function(e){var t=this.getNode(e);return t&&t.value},e.prototype.getNode=function(e){var t=this.map.get(e);if(t&&t!==this.newest){var n=t.older,r=t.newer;r&&(r.older=n),n&&(n.newer=r),t.older=this.newest,t.older.newer=t,t.newer=null,this.newest=t,t===this.oldest&&(this.oldest=r)}return t},e.prototype.set=function(e,t){var n=this.getNode(e);return n?n.value=t:(n={key:e,value:t,newer:null,older:this.newest},this.newest&&(this.newest.newer=n),this.newest=n,this.oldest=this.oldest||n,this.map.set(e,n),n.value)},e.prototype.clean=function(){for(;this.oldest&&this.map.size>this.max;)this.delete(this.oldest.key)},e.prototype.delete=function(e){var t=this.map.get(e);return!!t&&(t===this.newest&&(this.newest=t.older),t===this.oldest&&(this.oldest=t.newer),t.newer&&(t.newer.older=t.older),t.older&&(t.older.newer=t.newer),this.map.delete(e),this.dispose(t.value,e),!0)},e}(),rw=new rb,r_=Object.prototype.hasOwnProperty,rE=void 0===(n=Array.from)?function(e){var t=[];return e.forEach(function(e){return t.push(e)}),t}:n;function rS(e){var t=e.unsubscribe;"function"==typeof t&&(e.unsubscribe=void 0,t())}var rk=[],rx=100;function rT(e,t){if(!e)throw Error(t||"assertion failure")}function rM(e,t){var n=e.length;return n>0&&n===t.length&&e[n-1]===t[n-1]}function rO(e){switch(e.length){case 0:throw Error("unknown value");case 1:return e[0];case 2:throw e[1]}}function rA(e){return e.slice(0)}var rL=function(){function e(t){this.fn=t,this.parents=new Set,this.childValues=new Map,this.dirtyChildren=null,this.dirty=!0,this.recomputing=!1,this.value=[],this.deps=null,++e.count}return e.prototype.peek=function(){if(1===this.value.length&&!rN(this))return rC(this),this.value[0]},e.prototype.recompute=function(e){return rT(!this.recomputing,"already recomputing"),rC(this),rN(this)?rI(this,e):rO(this.value)},e.prototype.setDirty=function(){this.dirty||(this.dirty=!0,this.value.length=0,rR(this),rS(this))},e.prototype.dispose=function(){var e=this;this.setDirty(),rH(this),rF(this,function(t,n){t.setDirty(),r$(t,e)})},e.prototype.forget=function(){this.dispose()},e.prototype.dependOn=function(e){e.add(this),this.deps||(this.deps=rk.pop()||new Set),this.deps.add(e)},e.prototype.forgetDeps=function(){var e=this;this.deps&&(rE(this.deps).forEach(function(t){return t.delete(e)}),this.deps.clear(),rk.push(this.deps),this.deps=null)},e.count=0,e}();function rC(e){var t=rw.getValue();if(t)return e.parents.add(t),t.childValues.has(e)||t.childValues.set(e,[]),rN(e)?rY(t,e):rB(t,e),t}function rI(e,t){return rH(e),rw.withValue(e,rD,[e,t]),rz(e,t)&&rP(e),rO(e.value)}function rD(e,t){e.recomputing=!0,e.value.length=0;try{e.value[0]=e.fn.apply(null,t)}catch(n){e.value[1]=n}e.recomputing=!1}function rN(e){return e.dirty||!!(e.dirtyChildren&&e.dirtyChildren.size)}function rP(e){e.dirty=!1,!rN(e)&&rj(e)}function rR(e){rF(e,rY)}function rj(e){rF(e,rB)}function rF(e,t){var n=e.parents.size;if(n)for(var r=rE(e.parents),i=0;i0&&e.childValues.forEach(function(t,n){r$(e,n)}),e.forgetDeps(),rT(null===e.dirtyChildren)}function r$(e,t){t.parents.delete(e),e.childValues.delete(t),rU(e,t)}function rz(e,t){if("function"==typeof e.subscribe)try{rS(e),e.unsubscribe=e.subscribe.apply(null,t)}catch(n){return e.setDirty(),!1}return!0}var rG={setDirty:!0,dispose:!0,forget:!0};function rW(e){var t=new Map,n=e&&e.subscribe;function r(e){var r=rw.getValue();if(r){var i=t.get(e);i||t.set(e,i=new Set),r.dependOn(i),"function"==typeof n&&(rS(i),i.unsubscribe=n(e))}}return r.dirty=function(e,n){var r=t.get(e);if(r){var i=n&&r_.call(rG,n)?n:"setDirty";rE(r).forEach(function(e){return e[i]()}),t.delete(e),rS(r)}},r}function rK(){var e=new ra("function"==typeof WeakMap);return function(){return e.lookupArray(arguments)}}var rV=rK(),rq=new Set;function rZ(e,t){void 0===t&&(t=Object.create(null));var n=new ry(t.max||65536,function(e){return e.dispose()}),r=t.keyArgs,i=t.makeCacheKey||rK(),a=function(){var a=i.apply(null,r?r.apply(null,arguments):arguments);if(void 0===a)return e.apply(null,arguments);var o=n.get(a);o||(n.set(a,o=new rL(e)),o.subscribe=t.subscribe,o.forget=function(){return n.delete(a)});var s=o.recompute(Array.prototype.slice.call(arguments));return n.set(a,o),rq.add(n),rw.hasValue()||(rq.forEach(function(e){return e.clean()}),rq.clear()),s};function o(e){var t=n.get(e);t&&t.setDirty()}function s(e){var t=n.get(e);if(t)return t.peek()}function u(e){return n.delete(e)}return Object.defineProperty(a,"size",{get:function(){return n.map.size},configurable:!1,enumerable:!1}),a.dirtyKey=o,a.dirty=function(){o(i.apply(null,arguments))},a.peekKey=s,a.peek=function(){return s(i.apply(null,arguments))},a.forgetKey=u,a.forget=function(){return u(i.apply(null,arguments))},a.makeCacheKey=i,a.getKey=r?function(){return i.apply(null,r.apply(null,arguments))}:i,Object.freeze(a)}var rX=new rb,rJ=new WeakMap;function rQ(e){var t=rJ.get(e);return t||rJ.set(e,t={vars:new Set,dep:rW()}),t}function r1(e){rQ(e).vars.forEach(function(t){return t.forgetCache(e)})}function r0(e){rQ(e).vars.forEach(function(t){return t.attachCache(e)})}function r2(e){var t=new Set,n=new Set,r=function(a){if(arguments.length>0){if(e!==a){e=a,t.forEach(function(e){rQ(e).dep.dirty(r),r3(e)});var o=Array.from(n);n.clear(),o.forEach(function(t){return t(e)})}}else{var s=rX.getValue();s&&(i(s),rQ(s).dep(r))}return e};r.onNextChange=function(e){return n.add(e),function(){n.delete(e)}};var i=r.attachCache=function(e){return t.add(e),rQ(e).vars.add(r),r};return r.forgetCache=function(e){return t.delete(e)},r}function r3(e){e.broadcastWatches&&e.broadcastWatches()}var r4=function(){function e(e){var t=e.cache,n=e.client,r=e.resolvers,i=e.fragmentMatcher;this.selectionsToResolveCache=new WeakMap,this.cache=t,n&&(this.client=n),r&&this.addResolvers(r),i&&this.setFragmentMatcher(i)}return e.prototype.addResolvers=function(e){var t=this;this.resolvers=this.resolvers||{},Array.isArray(e)?e.forEach(function(e){t.resolvers=tj(t.resolvers,e)}):this.resolvers=tj(this.resolvers,e)},e.prototype.setResolvers=function(e){this.resolvers={},this.addResolvers(e)},e.prototype.getResolvers=function(){return this.resolvers||{}},e.prototype.runResolvers=function(e){var t=e.document,n=e.remoteResult,r=e.context,i=e.variables,a=e.onlyRunForcedResolvers,o=void 0!==a&&a;return(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(e){return t?[2,this.resolveDocument(t,n.data,r,i,this.fragmentMatcher,o).then(function(e){return(0,en.pi)((0,en.pi)({},n),{data:e.result})})]:[2,n]})})},e.prototype.setFragmentMatcher=function(e){this.fragmentMatcher=e},e.prototype.getFragmentMatcher=function(){return this.fragmentMatcher},e.prototype.clientQuery=function(e){return tb(["client"],e)&&this.resolvers?e:null},e.prototype.serverQuery=function(e){return n$(e)},e.prototype.prepareContext=function(e){var t=this.cache;return(0,en.pi)((0,en.pi)({},e),{cache:t,getCacheKey:function(e){return t.identify(e)}})},e.prototype.addExportedVariables=function(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(r){return e?[2,this.resolveDocument(e,this.buildRootValueFromCache(e,t)||{},this.prepareContext(n),t).then(function(e){return(0,en.pi)((0,en.pi)({},t),e.exportedVariables)})]:[2,(0,en.pi)({},t)]})})},e.prototype.shouldForceResolvers=function(e){var t=!1;return tl(e,{Directive:{enter:function(e){if("client"===e.name.value&&e.arguments&&(t=e.arguments.some(function(e){return"always"===e.name.value&&"BooleanValue"===e.value.kind&&!0===e.value.value})))return tc}}}),t},e.prototype.buildRootValueFromCache=function(e,t){return this.cache.diff({query:nH(e),variables:t,returnPartialData:!0,optimistic:!1}).result},e.prototype.resolveDocument=function(e,t,n,r,i,a){return void 0===n&&(n={}),void 0===r&&(r={}),void 0===i&&(i=function(){return!0}),void 0===a&&(a=!1),(0,en.mG)(this,void 0,void 0,function(){var o,s,u,c,l,f,d,h,p,b,m;return(0,en.Jh)(this,function(g){return o=e8(e),s=e4(e),u=eL(s),c=this.collectSelectionsToResolve(o,u),f=(l=o.operation)?l.charAt(0).toUpperCase()+l.slice(1):"Query",d=this,h=d.cache,p=d.client,b={fragmentMap:u,context:(0,en.pi)((0,en.pi)({},n),{cache:h,client:p}),variables:r,fragmentMatcher:i,defaultOperationType:f,exportedVariables:{},selectionsToResolve:c,onlyRunForcedResolvers:a},m=!1,[2,this.resolveSelectionSet(o.selectionSet,m,t,b).then(function(e){return{result:e,exportedVariables:b.exportedVariables}})]})})},e.prototype.resolveSelectionSet=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c=this;return(0,en.Jh)(this,function(l){return i=r.fragmentMap,a=r.context,o=r.variables,s=[n],u=function(e){return(0,en.mG)(c,void 0,void 0,function(){var u,c;return(0,en.Jh)(this,function(l){return(t||r.selectionsToResolve.has(e))&&td(e,o)?eQ(e)?[2,this.resolveField(e,t,n,r).then(function(t){var n;void 0!==t&&s.push(((n={})[eX(e)]=t,n))})]:(e1(e)?u=e:(u=i[e.name.value],__DEV__?(0,Q.kG)(u,"No fragment named ".concat(e.name.value)):(0,Q.kG)(u,11)),u&&u.typeCondition&&(c=u.typeCondition.name.value,r.fragmentMatcher(n,c,a)))?[2,this.resolveSelectionSet(u.selectionSet,t,n,r).then(function(e){s.push(e)})]:[2]:[2]})})},[2,Promise.all(e.selections.map(u)).then(function(){return tF(s)})]})})},e.prototype.resolveField=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c,l,f,d,h=this;return(0,en.Jh)(this,function(p){return n?(i=r.variables,a=e.name.value,o=eX(e),s=a!==o,c=Promise.resolve(u=n[o]||n[a]),(!r.onlyRunForcedResolvers||this.shouldForceResolvers(e))&&(l=n.__typename||r.defaultOperationType,(f=this.resolvers&&this.resolvers[l])&&(d=f[s?a:o])&&(c=Promise.resolve(rX.withValue(this.cache,d,[n,eZ(e,i),r.context,{field:e,fragmentMap:r.fragmentMap},])))),[2,c.then(function(n){if(void 0===n&&(n=u),e.directives&&e.directives.forEach(function(e){"export"===e.name.value&&e.arguments&&e.arguments.forEach(function(e){"as"===e.name.value&&"StringValue"===e.value.kind&&(r.exportedVariables[e.value.value]=n)})}),!e.selectionSet||null==n)return n;var i,a,o=null!==(a=null===(i=e.directives)||void 0===i?void 0:i.some(function(e){return"client"===e.name.value}))&&void 0!==a&&a;return Array.isArray(n)?h.resolveSubSelectedArray(e,t||o,n,r):e.selectionSet?h.resolveSelectionSet(e.selectionSet,t||o,n,r):void 0})]):[2,null]})})},e.prototype.resolveSubSelectedArray=function(e,t,n,r){var i=this;return Promise.all(n.map(function(n){return null===n?null:Array.isArray(n)?i.resolveSubSelectedArray(e,t,n,r):e.selectionSet?i.resolveSelectionSet(e.selectionSet,t,n,r):void 0}))},e.prototype.collectSelectionsToResolve=function(e,t){var n=function(e){return!Array.isArray(e)},r=this.selectionsToResolveCache;function i(e){if(!r.has(e)){var a=new Set;r.set(e,a),tl(e,{Directive:function(e,t,r,i,o){"client"===e.name.value&&o.forEach(function(e){n(e)&&n9(e)&&a.add(e)})},FragmentSpread:function(e,r,o,s,u){var c=t[e.name.value];__DEV__?(0,Q.kG)(c,"No fragment named ".concat(e.name.value)):(0,Q.kG)(c,12);var l=i(c);l.size>0&&(u.forEach(function(e){n(e)&&n9(e)&&a.add(e)}),a.add(e),l.forEach(function(e){a.add(e)}))}})}return r.get(e)}return i(e)},e}(),r6=new(t_.mr?WeakMap:Map);function r5(e,t){var n=e[t];"function"==typeof n&&(e[t]=function(){return r6.set(e,(r6.get(e)+1)%1e15),n.apply(this,arguments)})}function r8(e){e.notifyTimeout&&(clearTimeout(e.notifyTimeout),e.notifyTimeout=void 0)}var r9=function(){function e(e,t){void 0===t&&(t=e.generateQueryId()),this.queryId=t,this.listeners=new Set,this.document=null,this.lastRequestId=1,this.subscriptions=new Set,this.stopped=!1,this.dirty=!1,this.observableQuery=null;var n=this.cache=e.cache;r6.has(n)||(r6.set(n,0),r5(n,"evict"),r5(n,"modify"),r5(n,"reset"))}return e.prototype.init=function(e){var t=e.networkStatus||nZ.I.loading;return this.variables&&this.networkStatus!==nZ.I.loading&&!(0,nm.D)(this.variables,e.variables)&&(t=nZ.I.setVariables),(0,nm.D)(e.variables,this.variables)||(this.lastDiff=void 0),Object.assign(this,{document:e.document,variables:e.variables,networkError:null,graphQLErrors:this.graphQLErrors||[],networkStatus:t}),e.observableQuery&&this.setObservableQuery(e.observableQuery),e.lastRequestId&&(this.lastRequestId=e.lastRequestId),this},e.prototype.reset=function(){r8(this),this.dirty=!1},e.prototype.getDiff=function(e){void 0===e&&(e=this.variables);var t=this.getDiffOptions(e);if(this.lastDiff&&(0,nm.D)(t,this.lastDiff.options))return this.lastDiff.diff;this.updateWatch(this.variables=e);var n=this.observableQuery;if(n&&"no-cache"===n.options.fetchPolicy)return{complete:!1};var r=this.cache.diff(t);return this.updateLastDiff(r,t),r},e.prototype.updateLastDiff=function(e,t){this.lastDiff=e?{diff:e,options:t||this.getDiffOptions()}:void 0},e.prototype.getDiffOptions=function(e){var t;return void 0===e&&(e=this.variables),{query:this.document,variables:e,returnPartialData:!0,optimistic:!0,canonizeResults:null===(t=this.observableQuery)||void 0===t?void 0:t.options.canonizeResults}},e.prototype.setDiff=function(e){var t=this,n=this.lastDiff&&this.lastDiff.diff;this.updateLastDiff(e),this.dirty||(0,nm.D)(n&&n.result,e&&e.result)||(this.dirty=!0,this.notifyTimeout||(this.notifyTimeout=setTimeout(function(){return t.notify()},0)))},e.prototype.setObservableQuery=function(e){var t=this;e!==this.observableQuery&&(this.oqListener&&this.listeners.delete(this.oqListener),this.observableQuery=e,e?(e.queryInfo=this,this.listeners.add(this.oqListener=function(){t.getDiff().fromOptimisticTransaction?e.observe():n4(e)})):delete this.oqListener)},e.prototype.notify=function(){var e=this;r8(this),this.shouldNotify()&&this.listeners.forEach(function(t){return t(e)}),this.dirty=!1},e.prototype.shouldNotify=function(){if(!this.dirty||!this.listeners.size)return!1;if((0,nZ.O)(this.networkStatus)&&this.observableQuery){var e=this.observableQuery.options.fetchPolicy;if("cache-only"!==e&&"cache-and-network"!==e)return!1}return!0},e.prototype.stop=function(){if(!this.stopped){this.stopped=!0,this.reset(),this.cancel(),this.cancel=e.prototype.cancel,this.subscriptions.forEach(function(e){return e.unsubscribe()});var t=this.observableQuery;t&&t.stopPolling()}},e.prototype.cancel=function(){},e.prototype.updateWatch=function(e){var t=this;void 0===e&&(e=this.variables);var n=this.observableQuery;if(!n||"no-cache"!==n.options.fetchPolicy){var r=(0,en.pi)((0,en.pi)({},this.getDiffOptions(e)),{watcher:this,callback:function(e){return t.setDiff(e)}});this.lastWatch&&(0,nm.D)(r,this.lastWatch)||(this.cancel(),this.cancel=this.cache.watch(this.lastWatch=r))}},e.prototype.resetLastWrite=function(){this.lastWrite=void 0},e.prototype.shouldWrite=function(e,t){var n=this.lastWrite;return!(n&&n.dmCount===r6.get(this.cache)&&(0,nm.D)(t,n.variables)&&(0,nm.D)(e.data,n.result.data))},e.prototype.markResult=function(e,t,n,r){var i=this,a=new tB,o=(0,tP.O)(e.errors)?e.errors.slice(0):[];if(this.reset(),"incremental"in e&&(0,tP.O)(e.incremental)){var s=tG(this.getDiff().result,e);e.data=s}else if("hasNext"in e&&e.hasNext){var u=this.getDiff();e.data=a.merge(u.result,e.data)}this.graphQLErrors=o,"no-cache"===n.fetchPolicy?this.updateLastDiff({result:e.data,complete:!0},this.getDiffOptions(n.variables)):0!==r&&(r7(e,n.errorPolicy)?this.cache.performTransaction(function(a){if(i.shouldWrite(e,n.variables))a.writeQuery({query:t,data:e.data,variables:n.variables,overwrite:1===r}),i.lastWrite={result:e,variables:n.variables,dmCount:r6.get(i.cache)};else if(i.lastDiff&&i.lastDiff.diff.complete){e.data=i.lastDiff.diff.result;return}var o=i.getDiffOptions(n.variables),s=a.diff(o);i.stopped||i.updateWatch(n.variables),i.updateLastDiff(s,o),s.complete&&(e.data=s.result)}):this.lastWrite=void 0)},e.prototype.markReady=function(){return this.networkError=null,this.networkStatus=nZ.I.ready},e.prototype.markError=function(e){return this.networkStatus=nZ.I.error,this.lastWrite=void 0,this.reset(),e.graphQLErrors&&(this.graphQLErrors=e.graphQLErrors),e.networkError&&(this.networkError=e.networkError),e},e}();function r7(e,t){void 0===t&&(t="none");var n="ignore"===t||"all"===t,r=!nO(e);return!r&&n&&e.data&&(r=!0),r}var ie=Object.prototype.hasOwnProperty,it=function(){function e(e){var t=e.cache,n=e.link,r=e.defaultOptions,i=e.queryDeduplication,a=void 0!==i&&i,o=e.onBroadcast,s=e.ssrMode,u=void 0!==s&&s,c=e.clientAwareness,l=void 0===c?{}:c,f=e.localState,d=e.assumeImmutableResults;this.clientAwareness={},this.queries=new Map,this.fetchCancelFns=new Map,this.transformCache=new(t_.mr?WeakMap:Map),this.queryIdCounter=1,this.requestIdCounter=1,this.mutationIdCounter=1,this.inFlightLinkObservables=new Map,this.cache=t,this.link=n,this.defaultOptions=r||Object.create(null),this.queryDeduplication=a,this.clientAwareness=l,this.localState=f||new r4({cache:t}),this.ssrMode=u,this.assumeImmutableResults=!!d,(this.onBroadcast=o)&&(this.mutationStore=Object.create(null))}return e.prototype.stop=function(){var e=this;this.queries.forEach(function(t,n){e.stopQueryNoBroadcast(n)}),this.cancelPendingFetches(__DEV__?new Q.ej("QueryManager stopped while query was in flight"):new Q.ej(14))},e.prototype.cancelPendingFetches=function(e){this.fetchCancelFns.forEach(function(t){return t(e)}),this.fetchCancelFns.clear()},e.prototype.mutate=function(e){var t,n,r=e.mutation,i=e.variables,a=e.optimisticResponse,o=e.updateQueries,s=e.refetchQueries,u=void 0===s?[]:s,c=e.awaitRefetchQueries,l=void 0!==c&&c,f=e.update,d=e.onQueryUpdated,h=e.fetchPolicy,p=void 0===h?(null===(t=this.defaultOptions.mutate)||void 0===t?void 0:t.fetchPolicy)||"network-only":h,b=e.errorPolicy,m=void 0===b?(null===(n=this.defaultOptions.mutate)||void 0===n?void 0:n.errorPolicy)||"none":b,g=e.keepRootFields,v=e.context;return(0,en.mG)(this,void 0,void 0,function(){var e,t,n,s,c,h;return(0,en.Jh)(this,function(b){switch(b.label){case 0:if(__DEV__?(0,Q.kG)(r,"mutation option is required. You must specify your GraphQL document in the mutation option."):(0,Q.kG)(r,15),__DEV__?(0,Q.kG)("network-only"===p||"no-cache"===p,"Mutations support only 'network-only' or 'no-cache' fetchPolicy strings. The default `network-only` behavior automatically writes mutation results to the cache. Passing `no-cache` skips the cache write."):(0,Q.kG)("network-only"===p||"no-cache"===p,16),e=this.generateMutationId(),n=(t=this.transform(r)).document,s=t.hasClientExports,r=this.cache.transformForLink(n),i=this.getVariables(r,i),!s)return[3,2];return[4,this.localState.addExportedVariables(r,i,v)];case 1:i=b.sent(),b.label=2;case 2:return c=this.mutationStore&&(this.mutationStore[e]={mutation:r,variables:i,loading:!0,error:null}),a&&this.markMutationOptimistic(a,{mutationId:e,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,updateQueries:o,update:f,keepRootFields:g}),this.broadcastQueries(),h=this,[2,new Promise(function(t,n){return nM(h.getObservableFromLink(r,(0,en.pi)((0,en.pi)({},v),{optimisticResponse:a}),i,!1),function(t){if(nO(t)&&"none"===m)throw new tN.cA({graphQLErrors:nA(t)});c&&(c.loading=!1,c.error=null);var n=(0,en.pi)({},t);return"function"==typeof u&&(u=u(n)),"ignore"===m&&nO(n)&&delete n.errors,h.markMutationResult({mutationId:e,result:n,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,update:f,updateQueries:o,awaitRefetchQueries:l,refetchQueries:u,removeOptimistic:a?e:void 0,onQueryUpdated:d,keepRootFields:g})}).subscribe({next:function(e){h.broadcastQueries(),"hasNext"in e&&!1!==e.hasNext||t(e)},error:function(t){c&&(c.loading=!1,c.error=t),a&&h.cache.removeOptimistic(e),h.broadcastQueries(),n(t instanceof tN.cA?t:new tN.cA({networkError:t}))}})})]}})})},e.prototype.markMutationResult=function(e,t){var n=this;void 0===t&&(t=this.cache);var r=e.result,i=[],a="no-cache"===e.fetchPolicy;if(!a&&r7(r,e.errorPolicy)){if(tU(r)||i.push({result:r.data,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}),tU(r)&&(0,tP.O)(r.incremental)){var o=t.diff({id:"ROOT_MUTATION",query:this.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0}),s=void 0;o.result&&(s=tG(o.result,r)),void 0!==s&&(r.data=s,i.push({result:s,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}))}var u=e.updateQueries;u&&this.queries.forEach(function(e,a){var o=e.observableQuery,s=o&&o.queryName;if(s&&ie.call(u,s)){var c,l=u[s],f=n.queries.get(a),d=f.document,h=f.variables,p=t.diff({query:d,variables:h,returnPartialData:!0,optimistic:!1}),b=p.result;if(p.complete&&b){var m=l(b,{mutationResult:r,queryName:d&&e3(d)||void 0,queryVariables:h});m&&i.push({result:m,dataId:"ROOT_QUERY",query:d,variables:h})}}})}if(i.length>0||e.refetchQueries||e.update||e.onQueryUpdated||e.removeOptimistic){var c=[];if(this.refetchQueries({updateCache:function(t){a||i.forEach(function(e){return t.write(e)});var o=e.update,s=!t$(r)||tU(r)&&!r.hasNext;if(o){if(!a){var u=t.diff({id:"ROOT_MUTATION",query:n.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0});u.complete&&("incremental"in(r=(0,en.pi)((0,en.pi)({},r),{data:u.result}))&&delete r.incremental,"hasNext"in r&&delete r.hasNext)}s&&o(t,r,{context:e.context,variables:e.variables})}a||e.keepRootFields||!s||t.modify({id:"ROOT_MUTATION",fields:function(e,t){var n=t.fieldName,r=t.DELETE;return"__typename"===n?e:r}})},include:e.refetchQueries,optimistic:!1,removeOptimistic:e.removeOptimistic,onQueryUpdated:e.onQueryUpdated||null}).forEach(function(e){return c.push(e)}),e.awaitRefetchQueries||e.onQueryUpdated)return Promise.all(c).then(function(){return r})}return Promise.resolve(r)},e.prototype.markMutationOptimistic=function(e,t){var n=this,r="function"==typeof e?e(t.variables):e;return this.cache.recordOptimisticTransaction(function(e){try{n.markMutationResult((0,en.pi)((0,en.pi)({},t),{result:{data:r}}),e)}catch(i){__DEV__&&Q.kG.error(i)}},t.mutationId)},e.prototype.fetchQuery=function(e,t,n){return this.fetchQueryObservable(e,t,n).promise},e.prototype.getQueryStore=function(){var e=Object.create(null);return this.queries.forEach(function(t,n){e[n]={variables:t.variables,networkStatus:t.networkStatus,networkError:t.networkError,graphQLErrors:t.graphQLErrors}}),e},e.prototype.resetErrors=function(e){var t=this.queries.get(e);t&&(t.networkError=void 0,t.graphQLErrors=[])},e.prototype.transform=function(e){var t=this.transformCache;if(!t.has(e)){var n=this.cache.transformDocument(e),r=nY(n),i=this.localState.clientQuery(n),a=r&&this.localState.serverQuery(r),o={document:n,hasClientExports:tm(n),hasForcedResolvers:this.localState.shouldForceResolvers(n),clientQuery:i,serverQuery:a,defaultVars:e9(e2(n)),asQuery:(0,en.pi)((0,en.pi)({},n),{definitions:n.definitions.map(function(e){return"OperationDefinition"===e.kind&&"query"!==e.operation?(0,en.pi)((0,en.pi)({},e),{operation:"query"}):e})})},s=function(e){e&&!t.has(e)&&t.set(e,o)};s(e),s(n),s(i),s(a)}return t.get(e)},e.prototype.getVariables=function(e,t){return(0,en.pi)((0,en.pi)({},this.transform(e).defaultVars),t)},e.prototype.watchQuery=function(e){void 0===(e=(0,en.pi)((0,en.pi)({},e),{variables:this.getVariables(e.query,e.variables)})).notifyOnNetworkStatusChange&&(e.notifyOnNetworkStatusChange=!1);var t=new r9(this),n=new n3({queryManager:this,queryInfo:t,options:e});return this.queries.set(n.queryId,t),t.init({document:n.query,observableQuery:n,variables:n.variables}),n},e.prototype.query=function(e,t){var n=this;return void 0===t&&(t=this.generateQueryId()),__DEV__?(0,Q.kG)(e.query,"query option is required. You must specify your GraphQL document in the query option."):(0,Q.kG)(e.query,17),__DEV__?(0,Q.kG)("Document"===e.query.kind,'You must wrap the query string in a "gql" tag.'):(0,Q.kG)("Document"===e.query.kind,18),__DEV__?(0,Q.kG)(!e.returnPartialData,"returnPartialData option only supported on watchQuery."):(0,Q.kG)(!e.returnPartialData,19),__DEV__?(0,Q.kG)(!e.pollInterval,"pollInterval option only supported on watchQuery."):(0,Q.kG)(!e.pollInterval,20),this.fetchQuery(t,e).finally(function(){return n.stopQuery(t)})},e.prototype.generateQueryId=function(){return String(this.queryIdCounter++)},e.prototype.generateRequestId=function(){return this.requestIdCounter++},e.prototype.generateMutationId=function(){return String(this.mutationIdCounter++)},e.prototype.stopQueryInStore=function(e){this.stopQueryInStoreNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryInStoreNoBroadcast=function(e){var t=this.queries.get(e);t&&t.stop()},e.prototype.clearStore=function(e){return void 0===e&&(e={discardWatches:!0}),this.cancelPendingFetches(__DEV__?new Q.ej("Store reset while query was in flight (not completed in link chain)"):new Q.ej(21)),this.queries.forEach(function(e){e.observableQuery?e.networkStatus=nZ.I.loading:e.stop()}),this.mutationStore&&(this.mutationStore=Object.create(null)),this.cache.reset(e)},e.prototype.getObservableQueries=function(e){var t=this;void 0===e&&(e="active");var n=new Map,r=new Map,i=new Set;return Array.isArray(e)&&e.forEach(function(e){"string"==typeof e?r.set(e,!1):eN(e)?r.set(t.transform(e).document,!1):(0,eO.s)(e)&&e.query&&i.add(e)}),this.queries.forEach(function(t,i){var a=t.observableQuery,o=t.document;if(a){if("all"===e){n.set(i,a);return}var s=a.queryName;if("standby"===a.options.fetchPolicy||"active"===e&&!a.hasObservers())return;("active"===e||s&&r.has(s)||o&&r.has(o))&&(n.set(i,a),s&&r.set(s,!0),o&&r.set(o,!0))}}),i.size&&i.forEach(function(e){var r=nG("legacyOneTimeQuery"),i=t.getQuery(r).init({document:e.query,variables:e.variables}),a=new n3({queryManager:t,queryInfo:i,options:(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"network-only"})});(0,Q.kG)(a.queryId===r),i.setObservableQuery(a),n.set(r,a)}),__DEV__&&r.size&&r.forEach(function(e,t){!e&&__DEV__&&Q.kG.warn("Unknown query ".concat("string"==typeof t?"named ":"").concat(JSON.stringify(t,null,2)," requested in refetchQueries options.include array"))}),n},e.prototype.reFetchObservableQueries=function(e){var t=this;void 0===e&&(e=!1);var n=[];return this.getObservableQueries(e?"all":"active").forEach(function(r,i){var a=r.options.fetchPolicy;r.resetLastResults(),(e||"standby"!==a&&"cache-only"!==a)&&n.push(r.refetch()),t.getQuery(i).setDiff(null)}),this.broadcastQueries(),Promise.all(n)},e.prototype.setObservableQuery=function(e){this.getQuery(e.queryId).setObservableQuery(e)},e.prototype.startGraphQLSubscription=function(e){var t=this,n=e.query,r=e.fetchPolicy,i=e.errorPolicy,a=e.variables,o=e.context,s=void 0===o?{}:o;n=this.transform(n).document,a=this.getVariables(n,a);var u=function(e){return t.getObservableFromLink(n,s,e).map(function(a){"no-cache"!==r&&(r7(a,i)&&t.cache.write({query:n,result:a.data,dataId:"ROOT_SUBSCRIPTION",variables:e}),t.broadcastQueries());var o=nO(a),s=(0,tN.ls)(a);if(o||s){var u={};throw o&&(u.graphQLErrors=a.errors),s&&(u.protocolErrors=a.extensions[tN.YG]),new tN.cA(u)}return a})};if(this.transform(n).hasClientExports){var c=this.localState.addExportedVariables(n,a,s).then(u);return new eT(function(e){var t=null;return c.then(function(n){return t=n.subscribe(e)},e.error),function(){return t&&t.unsubscribe()}})}return u(a)},e.prototype.stopQuery=function(e){this.stopQueryNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryNoBroadcast=function(e){this.stopQueryInStoreNoBroadcast(e),this.removeQuery(e)},e.prototype.removeQuery=function(e){this.fetchCancelFns.delete(e),this.queries.has(e)&&(this.getQuery(e).stop(),this.queries.delete(e))},e.prototype.broadcastQueries=function(){this.onBroadcast&&this.onBroadcast(),this.queries.forEach(function(e){return e.notify()})},e.prototype.getLocalState=function(){return this.localState},e.prototype.getObservableFromLink=function(e,t,n,r){var i,a,o=this;void 0===r&&(r=null!==(i=null==t?void 0:t.queryDeduplication)&&void 0!==i?i:this.queryDeduplication);var s=this.transform(e).serverQuery;if(s){var u=this,c=u.inFlightLinkObservables,l=u.link,f={query:s,variables:n,operationName:e3(s)||void 0,context:this.prepareContext((0,en.pi)((0,en.pi)({},t),{forceFetch:!r}))};if(t=f.context,r){var d=c.get(s)||new Map;c.set(s,d);var h=nx(n);if(!(a=d.get(h))){var p=new nq([np(l,f)]);d.set(h,a=p),p.beforeNext(function(){d.delete(h)&&d.size<1&&c.delete(s)})}}else a=new nq([np(l,f)])}else a=new nq([eT.of({data:{}})]),t=this.prepareContext(t);var b=this.transform(e).clientQuery;return b&&(a=nM(a,function(e){return o.localState.runResolvers({document:b,remoteResult:e,context:t,variables:n})})),a},e.prototype.getResultsFromLink=function(e,t,n){var r=e.lastRequestId=this.generateRequestId(),i=this.cache.transformForLink(this.transform(e.document).document);return nM(this.getObservableFromLink(i,n.context,n.variables),function(a){var o=nA(a),s=o.length>0;if(r>=e.lastRequestId){if(s&&"none"===n.errorPolicy)throw e.markError(new tN.cA({graphQLErrors:o}));e.markResult(a,i,n,t),e.markReady()}var u={data:a.data,loading:!1,networkStatus:nZ.I.ready};return s&&"ignore"!==n.errorPolicy&&(u.errors=o,u.networkStatus=nZ.I.error),u},function(t){var n=(0,tN.MS)(t)?t:new tN.cA({networkError:t});throw r>=e.lastRequestId&&e.markError(n),n})},e.prototype.fetchQueryObservable=function(e,t,n){return this.fetchConcastWithInfo(e,t,n).concast},e.prototype.fetchConcastWithInfo=function(e,t,n){var r,i,a=this;void 0===n&&(n=nZ.I.loading);var o=this.transform(t.query).document,s=this.getVariables(o,t.variables),u=this.getQuery(e),c=this.defaultOptions.watchQuery,l=t.fetchPolicy,f=void 0===l?c&&c.fetchPolicy||"cache-first":l,d=t.errorPolicy,h=void 0===d?c&&c.errorPolicy||"none":d,p=t.returnPartialData,b=void 0!==p&&p,m=t.notifyOnNetworkStatusChange,g=void 0!==m&&m,v=t.context,y=void 0===v?{}:v,w=Object.assign({},t,{query:o,variables:s,fetchPolicy:f,errorPolicy:h,returnPartialData:b,notifyOnNetworkStatusChange:g,context:y}),_=function(e){w.variables=e;var r=a.fetchQueryByPolicy(u,w,n);return"standby"!==w.fetchPolicy&&r.sources.length>0&&u.observableQuery&&u.observableQuery.applyNextFetchPolicy("after-fetch",t),r},E=function(){return a.fetchCancelFns.delete(e)};if(this.fetchCancelFns.set(e,function(e){E(),setTimeout(function(){return r.cancel(e)})}),this.transform(w.query).hasClientExports)r=new nq(this.localState.addExportedVariables(w.query,w.variables,w.context).then(_).then(function(e){return e.sources})),i=!0;else{var S=_(w.variables);i=S.fromLink,r=new nq(S.sources)}return r.promise.then(E,E),{concast:r,fromLink:i}},e.prototype.refetchQueries=function(e){var t=this,n=e.updateCache,r=e.include,i=e.optimistic,a=void 0!==i&&i,o=e.removeOptimistic,s=void 0===o?a?nG("refetchQueries"):void 0:o,u=e.onQueryUpdated,c=new Map;r&&this.getObservableQueries(r).forEach(function(e,n){c.set(n,{oq:e,lastDiff:t.getQuery(n).getDiff()})});var l=new Map;return n&&this.cache.batch({update:n,optimistic:a&&s||!1,removeOptimistic:s,onWatchUpdated:function(e,t,n){var r=e.watcher instanceof r9&&e.watcher.observableQuery;if(r){if(u){c.delete(r.queryId);var i=u(r,t,n);return!0===i&&(i=r.refetch()),!1!==i&&l.set(r,i),i}null!==u&&c.set(r.queryId,{oq:r,lastDiff:n,diff:t})}}}),c.size&&c.forEach(function(e,n){var r,i=e.oq,a=e.lastDiff,o=e.diff;if(u){if(!o){var s=i.queryInfo;s.reset(),o=s.getDiff()}r=u(i,o,a)}u&&!0!==r||(r=i.refetch()),!1!==r&&l.set(i,r),n.indexOf("legacyOneTimeQuery")>=0&&t.stopQueryNoBroadcast(n)}),s&&this.cache.removeOptimistic(s),l},e.prototype.fetchQueryByPolicy=function(e,t,n){var r=this,i=t.query,a=t.variables,o=t.fetchPolicy,s=t.refetchWritePolicy,u=t.errorPolicy,c=t.returnPartialData,l=t.context,f=t.notifyOnNetworkStatusChange,d=e.networkStatus;e.init({document:this.transform(i).document,variables:a,networkStatus:n});var h=function(){return e.getDiff(a)},p=function(t,n){void 0===n&&(n=e.networkStatus||nZ.I.loading);var o=t.result;!__DEV__||c||(0,nm.D)(o,{})||n5(t.missing);var s=function(e){return eT.of((0,en.pi)({data:e,loading:(0,nZ.O)(n),networkStatus:n},t.complete?null:{partial:!0}))};return o&&r.transform(i).hasForcedResolvers?r.localState.runResolvers({document:i,remoteResult:{data:o},context:l,variables:a,onlyRunForcedResolvers:!0}).then(function(e){return s(e.data||void 0)}):"none"===u&&n===nZ.I.refetch&&Array.isArray(t.missing)?s(void 0):s(o)},b="no-cache"===o?0:n===nZ.I.refetch&&"merge"!==s?1:2,m=function(){return r.getResultsFromLink(e,b,{variables:a,context:l,fetchPolicy:o,errorPolicy:u})},g=f&&"number"==typeof d&&d!==n&&(0,nZ.O)(n);switch(o){default:case"cache-first":var v=h();if(v.complete)return{fromLink:!1,sources:[p(v,e.markReady())]};if(c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-and-network":var v=h();if(v.complete||c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-only":return{fromLink:!1,sources:[p(h(),e.markReady())]};case"network-only":if(g)return{fromLink:!0,sources:[p(h()),m()]};return{fromLink:!0,sources:[m()]};case"no-cache":if(g)return{fromLink:!0,sources:[p(e.getDiff()),m(),]};return{fromLink:!0,sources:[m()]};case"standby":return{fromLink:!1,sources:[]}}},e.prototype.getQuery=function(e){return e&&!this.queries.has(e)&&this.queries.set(e,new r9(this,e)),this.queries.get(e)},e.prototype.prepareContext=function(e){void 0===e&&(e={});var t=this.localState.prepareContext(e);return(0,en.pi)((0,en.pi)({},t),{clientAwareness:this.clientAwareness})},e}(),ir=__webpack_require__(14012),ii=!1,ia=function(){function e(e){var t=this;this.resetStoreCallbacks=[],this.clearStoreCallbacks=[];var n=e.uri,r=e.credentials,i=e.headers,a=e.cache,o=e.ssrMode,s=void 0!==o&&o,u=e.ssrForceFetchDelay,c=void 0===u?0:u,l=e.connectToDevTools,f=void 0===l?"object"==typeof window&&!window.__APOLLO_CLIENT__&&__DEV__:l,d=e.queryDeduplication,h=void 0===d||d,p=e.defaultOptions,b=e.assumeImmutableResults,m=void 0!==b&&b,g=e.resolvers,v=e.typeDefs,y=e.fragmentMatcher,w=e.name,_=e.version,E=e.link;if(E||(E=n?new nh({uri:n,credentials:r,headers:i}):ta.empty()),!a)throw __DEV__?new Q.ej("To initialize Apollo Client, you must specify a 'cache' property in the options object. \nFor more information, please visit: https://go.apollo.dev/c/docs"):new Q.ej(9);if(this.link=E,this.cache=a,this.disableNetworkFetches=s||c>0,this.queryDeduplication=h,this.defaultOptions=p||Object.create(null),this.typeDefs=v,c&&setTimeout(function(){return t.disableNetworkFetches=!1},c),this.watchQuery=this.watchQuery.bind(this),this.query=this.query.bind(this),this.mutate=this.mutate.bind(this),this.resetStore=this.resetStore.bind(this),this.reFetchObservableQueries=this.reFetchObservableQueries.bind(this),f&&"object"==typeof window&&(window.__APOLLO_CLIENT__=this),!ii&&f&&__DEV__&&(ii=!0,"undefined"!=typeof window&&window.document&&window.top===window.self&&!window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__)){var S=window.navigator,k=S&&S.userAgent,x=void 0;"string"==typeof k&&(k.indexOf("Chrome/")>-1?x="https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm":k.indexOf("Firefox/")>-1&&(x="https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/")),x&&__DEV__&&Q.kG.log("Download the Apollo DevTools for a better development experience: "+x)}this.version=nb,this.localState=new r4({cache:a,client:this,resolvers:g,fragmentMatcher:y}),this.queryManager=new it({cache:this.cache,link:this.link,defaultOptions:this.defaultOptions,queryDeduplication:h,ssrMode:s,clientAwareness:{name:w,version:_},localState:this.localState,assumeImmutableResults:m,onBroadcast:f?function(){t.devToolsHookCb&&t.devToolsHookCb({action:{},state:{queries:t.queryManager.getQueryStore(),mutations:t.queryManager.mutationStore||{}},dataWithOptimisticResults:t.cache.extract(!0)})}:void 0})}return e.prototype.stop=function(){this.queryManager.stop()},e.prototype.watchQuery=function(e){return this.defaultOptions.watchQuery&&(e=(0,ir.J)(this.defaultOptions.watchQuery,e)),this.disableNetworkFetches&&("network-only"===e.fetchPolicy||"cache-and-network"===e.fetchPolicy)&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.watchQuery(e)},e.prototype.query=function(e){return this.defaultOptions.query&&(e=(0,ir.J)(this.defaultOptions.query,e)),__DEV__?(0,Q.kG)("cache-and-network"!==e.fetchPolicy,"The cache-and-network fetchPolicy does not work with client.query, because client.query can only return a single result. Please use client.watchQuery to receive multiple results from the cache and the network, or consider using a different fetchPolicy, such as cache-first or network-only."):(0,Q.kG)("cache-and-network"!==e.fetchPolicy,10),this.disableNetworkFetches&&"network-only"===e.fetchPolicy&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.query(e)},e.prototype.mutate=function(e){return this.defaultOptions.mutate&&(e=(0,ir.J)(this.defaultOptions.mutate,e)),this.queryManager.mutate(e)},e.prototype.subscribe=function(e){return this.queryManager.startGraphQLSubscription(e)},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!1),this.cache.readQuery(e,t)},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!1),this.cache.readFragment(e,t)},e.prototype.writeQuery=function(e){var t=this.cache.writeQuery(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.writeFragment=function(e){var t=this.cache.writeFragment(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.__actionHookForDevTools=function(e){this.devToolsHookCb=e},e.prototype.__requestRaw=function(e){return np(this.link,e)},e.prototype.resetStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!1})}).then(function(){return Promise.all(e.resetStoreCallbacks.map(function(e){return e()}))}).then(function(){return e.reFetchObservableQueries()})},e.prototype.clearStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!0})}).then(function(){return Promise.all(e.clearStoreCallbacks.map(function(e){return e()}))})},e.prototype.onResetStore=function(e){var t=this;return this.resetStoreCallbacks.push(e),function(){t.resetStoreCallbacks=t.resetStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.onClearStore=function(e){var t=this;return this.clearStoreCallbacks.push(e),function(){t.clearStoreCallbacks=t.clearStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.reFetchObservableQueries=function(e){return this.queryManager.reFetchObservableQueries(e)},e.prototype.refetchQueries=function(e){var t=this.queryManager.refetchQueries(e),n=[],r=[];t.forEach(function(e,t){n.push(t),r.push(e)});var i=Promise.all(r);return i.queries=n,i.results=r,i.catch(function(e){__DEV__&&Q.kG.debug("In client.refetchQueries, Promise.all promise rejected with error ".concat(e))}),i},e.prototype.getObservableQueries=function(e){return void 0===e&&(e="active"),this.queryManager.getObservableQueries(e)},e.prototype.extract=function(e){return this.cache.extract(e)},e.prototype.restore=function(e){return this.cache.restore(e)},e.prototype.addResolvers=function(e){this.localState.addResolvers(e)},e.prototype.setResolvers=function(e){this.localState.setResolvers(e)},e.prototype.getResolvers=function(){return this.localState.getResolvers()},e.prototype.setLocalStateFragmentMatcher=function(e){this.localState.setFragmentMatcher(e)},e.prototype.setLink=function(e){this.link=this.queryManager.link=e},e}(),io=function(){function e(){this.getFragmentDoc=rZ(eA)}return e.prototype.batch=function(e){var t,n=this,r="string"==typeof e.optimistic?e.optimistic:!1===e.optimistic?null:void 0;return this.performTransaction(function(){return t=e.update(n)},r),t},e.prototype.recordOptimisticTransaction=function(e,t){this.performTransaction(e,t)},e.prototype.transformDocument=function(e){return e},e.prototype.transformForLink=function(e){return e},e.prototype.identify=function(e){},e.prototype.gc=function(){return[]},e.prototype.modify=function(e){return!1},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{rootId:e.id||"ROOT_QUERY",optimistic:t}))},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{query:this.getFragmentDoc(e.fragment,e.fragmentName),rootId:e.id,optimistic:t}))},e.prototype.writeQuery=function(e){var t=e.id,n=e.data,r=(0,en._T)(e,["id","data"]);return this.write(Object.assign(r,{dataId:t||"ROOT_QUERY",result:n}))},e.prototype.writeFragment=function(e){var t=e.id,n=e.data,r=e.fragment,i=e.fragmentName,a=(0,en._T)(e,["id","data","fragment","fragmentName"]);return this.write(Object.assign(a,{query:this.getFragmentDoc(r,i),dataId:t,result:n}))},e.prototype.updateQuery=function(e,t){return this.batch({update:function(n){var r=n.readQuery(e),i=t(r);return null==i?r:(n.writeQuery((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e.prototype.updateFragment=function(e,t){return this.batch({update:function(n){var r=n.readFragment(e),i=t(r);return null==i?r:(n.writeFragment((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e}(),is=function(e){function t(n,r,i,a){var o,s=e.call(this,n)||this;if(s.message=n,s.path=r,s.query=i,s.variables=a,Array.isArray(s.path)){s.missing=s.message;for(var u=s.path.length-1;u>=0;--u)s.missing=((o={})[s.path[u]]=s.missing,o)}else s.missing=s.path;return s.__proto__=t.prototype,s}return(0,en.ZT)(t,e),t}(Error),iu=__webpack_require__(10542),ic=Object.prototype.hasOwnProperty;function il(e){return null==e}function id(e,t){var n=e.__typename,r=e.id,i=e._id;if("string"==typeof n&&(t&&(t.keyObject=il(r)?il(i)?void 0:{_id:i}:{id:r}),il(r)&&!il(i)&&(r=i),!il(r)))return"".concat(n,":").concat("number"==typeof r||"string"==typeof r?r:JSON.stringify(r))}var ih={dataIdFromObject:id,addTypename:!0,resultCaching:!0,canonizeResults:!1};function ip(e){return(0,n1.o)(ih,e)}function ib(e){var t=e.canonizeResults;return void 0===t?ih.canonizeResults:t}function im(e,t){return eD(t)?e.get(t.__ref,"__typename"):t&&t.__typename}var ig=/^[_a-z][_0-9a-z]*/i;function iv(e){var t=e.match(ig);return t?t[0]:e}function iy(e,t,n){return!!(0,eO.s)(t)&&((0,tP.k)(t)?t.every(function(t){return iy(e,t,n)}):e.selections.every(function(e){if(eQ(e)&&td(e,n)){var r=eX(e);return ic.call(t,r)&&(!e.selectionSet||iy(e.selectionSet,t[r],n))}return!0}))}function iw(e){return(0,eO.s)(e)&&!eD(e)&&!(0,tP.k)(e)}function i_(){return new tB}function iE(e,t){var n=eL(e4(e));return{fragmentMap:n,lookupFragment:function(e){var r=n[e];return!r&&t&&(r=t.lookup(e)),r||null}}}var iS=Object.create(null),ik=function(){return iS},ix=Object.create(null),iT=function(){function e(e,t){var n=this;this.policies=e,this.group=t,this.data=Object.create(null),this.rootIds=Object.create(null),this.refs=Object.create(null),this.getFieldValue=function(e,t){return(0,iu.J)(eD(e)?n.get(e.__ref,t):e&&e[t])},this.canRead=function(e){return eD(e)?n.has(e.__ref):"object"==typeof e},this.toReference=function(e,t){if("string"==typeof e)return eI(e);if(eD(e))return e;var r=n.policies.identify(e)[0];if(r){var i=eI(r);return t&&n.merge(r,e),i}}}return e.prototype.toObject=function(){return(0,en.pi)({},this.data)},e.prototype.has=function(e){return void 0!==this.lookup(e,!0)},e.prototype.get=function(e,t){if(this.group.depend(e,t),ic.call(this.data,e)){var n=this.data[e];if(n&&ic.call(n,t))return n[t]}return"__typename"===t&&ic.call(this.policies.rootTypenamesById,e)?this.policies.rootTypenamesById[e]:this instanceof iL?this.parent.get(e,t):void 0},e.prototype.lookup=function(e,t){return(t&&this.group.depend(e,"__exists"),ic.call(this.data,e))?this.data[e]:this instanceof iL?this.parent.lookup(e,t):this.policies.rootTypenamesById[e]?Object.create(null):void 0},e.prototype.merge=function(e,t){var n,r=this;eD(e)&&(e=e.__ref),eD(t)&&(t=t.__ref);var i="string"==typeof e?this.lookup(n=e):e,a="string"==typeof t?this.lookup(n=t):t;if(a){__DEV__?(0,Q.kG)("string"==typeof n,"store.merge expects a string ID"):(0,Q.kG)("string"==typeof n,1);var o=new tB(iI).merge(i,a);if(this.data[n]=o,o!==i&&(delete this.refs[n],this.group.caching)){var s=Object.create(null);i||(s.__exists=1),Object.keys(a).forEach(function(e){if(!i||i[e]!==o[e]){s[e]=1;var t=iv(e);t===e||r.policies.hasKeyArgs(o.__typename,t)||(s[t]=1),void 0!==o[e]||r instanceof iL||delete o[e]}}),s.__typename&&!(i&&i.__typename)&&this.policies.rootTypenamesById[n]===o.__typename&&delete s.__typename,Object.keys(s).forEach(function(e){return r.group.dirty(n,e)})}}},e.prototype.modify=function(e,t){var n=this,r=this.lookup(e);if(r){var i=Object.create(null),a=!1,o=!0,s={DELETE:iS,INVALIDATE:ix,isReference:eD,toReference:this.toReference,canRead:this.canRead,readField:function(t,r){return n.policies.readField("string"==typeof t?{fieldName:t,from:r||eI(e)}:t,{store:n})}};if(Object.keys(r).forEach(function(u){var c=iv(u),l=r[u];if(void 0!==l){var f="function"==typeof t?t:t[u]||t[c];if(f){var d=f===ik?iS:f((0,iu.J)(l),(0,en.pi)((0,en.pi)({},s),{fieldName:c,storeFieldName:u,storage:n.getStorage(e,u)}));d===ix?n.group.dirty(e,u):(d===iS&&(d=void 0),d!==l&&(i[u]=d,a=!0,l=d))}void 0!==l&&(o=!1)}}),a)return this.merge(e,i),o&&(this instanceof iL?this.data[e]=void 0:delete this.data[e],this.group.dirty(e,"__exists")),!0}return!1},e.prototype.delete=function(e,t,n){var r,i=this.lookup(e);if(i){var a=this.getFieldValue(i,"__typename"),o=t&&n?this.policies.getStoreFieldName({typename:a,fieldName:t,args:n}):t;return this.modify(e,o?((r={})[o]=ik,r):ik)}return!1},e.prototype.evict=function(e,t){var n=!1;return e.id&&(ic.call(this.data,e.id)&&(n=this.delete(e.id,e.fieldName,e.args)),this instanceof iL&&this!==t&&(n=this.parent.evict(e,t)||n),(e.fieldName||n)&&this.group.dirty(e.id,e.fieldName||"__exists")),n},e.prototype.clear=function(){this.replace(null)},e.prototype.extract=function(){var e=this,t=this.toObject(),n=[];return this.getRootIdSet().forEach(function(t){ic.call(e.policies.rootTypenamesById,t)||n.push(t)}),n.length&&(t.__META={extraRootIds:n.sort()}),t},e.prototype.replace=function(e){var t=this;if(Object.keys(this.data).forEach(function(n){e&&ic.call(e,n)||t.delete(n)}),e){var n=e.__META,r=(0,en._T)(e,["__META"]);Object.keys(r).forEach(function(e){t.merge(e,r[e])}),n&&n.extraRootIds.forEach(this.retain,this)}},e.prototype.retain=function(e){return this.rootIds[e]=(this.rootIds[e]||0)+1},e.prototype.release=function(e){if(this.rootIds[e]>0){var t=--this.rootIds[e];return t||delete this.rootIds[e],t}return 0},e.prototype.getRootIdSet=function(e){return void 0===e&&(e=new Set),Object.keys(this.rootIds).forEach(e.add,e),this instanceof iL?this.parent.getRootIdSet(e):Object.keys(this.policies.rootTypenamesById).forEach(e.add,e),e},e.prototype.gc=function(){var e=this,t=this.getRootIdSet(),n=this.toObject();t.forEach(function(r){ic.call(n,r)&&(Object.keys(e.findChildRefIds(r)).forEach(t.add,t),delete n[r])});var r=Object.keys(n);if(r.length){for(var i=this;i instanceof iL;)i=i.parent;r.forEach(function(e){return i.delete(e)})}return r},e.prototype.findChildRefIds=function(e){if(!ic.call(this.refs,e)){var t=this.refs[e]=Object.create(null),n=this.data[e];if(!n)return t;var r=new Set([n]);r.forEach(function(e){eD(e)&&(t[e.__ref]=!0),(0,eO.s)(e)&&Object.keys(e).forEach(function(t){var n=e[t];(0,eO.s)(n)&&r.add(n)})})}return this.refs[e]},e.prototype.makeCacheKey=function(){return this.group.keyMaker.lookupArray(arguments)},e}(),iM=function(){function e(e,t){void 0===t&&(t=null),this.caching=e,this.parent=t,this.d=null,this.resetCaching()}return e.prototype.resetCaching=function(){this.d=this.caching?rW():null,this.keyMaker=new n_(t_.mr)},e.prototype.depend=function(e,t){if(this.d){this.d(iO(e,t));var n=iv(t);n!==t&&this.d(iO(e,n)),this.parent&&this.parent.depend(e,t)}},e.prototype.dirty=function(e,t){this.d&&this.d.dirty(iO(e,t),"__exists"===t?"forget":"setDirty")},e}();function iO(e,t){return t+"#"+e}function iA(e,t){iD(e)&&e.group.depend(t,"__exists")}!function(e){var t=function(e){function t(t){var n=t.policies,r=t.resultCaching,i=void 0===r||r,a=t.seed,o=e.call(this,n,new iM(i))||this;return o.stump=new iC(o),o.storageTrie=new n_(t_.mr),a&&o.replace(a),o}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,t){return this.stump.addLayer(e,t)},t.prototype.removeLayer=function(){return this},t.prototype.getStorage=function(){return this.storageTrie.lookupArray(arguments)},t}(e);e.Root=t}(iT||(iT={}));var iL=function(e){function t(t,n,r,i){var a=e.call(this,n.policies,i)||this;return a.id=t,a.parent=n,a.replay=r,a.group=i,r(a),a}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,n){return new t(e,this,n,this.group)},t.prototype.removeLayer=function(e){var t=this,n=this.parent.removeLayer(e);return e===this.id?(this.group.caching&&Object.keys(this.data).forEach(function(e){var r=t.data[e],i=n.lookup(e);i?r?r!==i&&Object.keys(r).forEach(function(n){(0,nm.D)(r[n],i[n])||t.group.dirty(e,n)}):(t.group.dirty(e,"__exists"),Object.keys(i).forEach(function(n){t.group.dirty(e,n)})):t.delete(e)}),n):n===this.parent?this:n.addLayer(this.id,this.replay)},t.prototype.toObject=function(){return(0,en.pi)((0,en.pi)({},this.parent.toObject()),this.data)},t.prototype.findChildRefIds=function(t){var n=this.parent.findChildRefIds(t);return ic.call(this.data,t)?(0,en.pi)((0,en.pi)({},n),e.prototype.findChildRefIds.call(this,t)):n},t.prototype.getStorage=function(){for(var e=this.parent;e.parent;)e=e.parent;return e.getStorage.apply(e,arguments)},t}(iT),iC=function(e){function t(t){return e.call(this,"EntityStore.Stump",t,function(){},new iM(t.group.caching,t.group))||this}return(0,en.ZT)(t,e),t.prototype.removeLayer=function(){return this},t.prototype.merge=function(){return this.parent.merge.apply(this.parent,arguments)},t}(iL);function iI(e,t,n){var r=e[n],i=t[n];return(0,nm.D)(r,i)?r:i}function iD(e){return!!(e instanceof iT&&e.group.caching)}function iN(e){return[e.selectionSet,e.objectOrReference,e.context,e.context.canonizeResults,]}var iP=function(){function e(e){var t=this;this.knownResults=new(t_.mr?WeakMap:Map),this.config=(0,n1.o)(e,{addTypename:!1!==e.addTypename,canonizeResults:ib(e)}),this.canon=e.canon||new nk,this.executeSelectionSet=rZ(function(e){var n,r=e.context.canonizeResults,i=iN(e);i[3]=!r;var a=(n=t.executeSelectionSet).peek.apply(n,i);return a?r?(0,en.pi)((0,en.pi)({},a),{result:t.canon.admit(a.result)}):a:(iA(e.context.store,e.enclosingRef.__ref),t.execSelectionSetImpl(e))},{max:this.config.resultCacheMaxSize,keyArgs:iN,makeCacheKey:function(e,t,n,r){if(iD(n.store))return n.store.makeCacheKey(e,eD(t)?t.__ref:t,n.varString,r)}}),this.executeSubSelectedArray=rZ(function(e){return iA(e.context.store,e.enclosingRef.__ref),t.execSubSelectedArrayImpl(e)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var t=e.field,n=e.array,r=e.context;if(iD(r.store))return r.store.makeCacheKey(t,n,r.varString)}})}return e.prototype.resetCanon=function(){this.canon=new nk},e.prototype.diffQueryAgainstStore=function(e){var t,n=e.store,r=e.query,i=e.rootId,a=void 0===i?"ROOT_QUERY":i,o=e.variables,s=e.returnPartialData,u=void 0===s||s,c=e.canonizeResults,l=void 0===c?this.config.canonizeResults:c,f=this.config.cache.policies;o=(0,en.pi)((0,en.pi)({},e9(e6(r))),o);var d=eI(a),h=this.executeSelectionSet({selectionSet:e8(r).selectionSet,objectOrReference:d,enclosingRef:d,context:(0,en.pi)({store:n,query:r,policies:f,variables:o,varString:nx(o),canonizeResults:l},iE(r,this.config.fragments))});if(h.missing&&(t=[new is(iR(h.missing),h.missing,r,o)],!u))throw t[0];return{result:h.result,complete:!t,missing:t}},e.prototype.isFresh=function(e,t,n,r){if(iD(r.store)&&this.knownResults.get(e)===n){var i=this.executeSelectionSet.peek(n,t,r,this.canon.isKnown(e));if(i&&e===i.result)return!0}return!1},e.prototype.execSelectionSetImpl=function(e){var t,n=this,r=e.selectionSet,i=e.objectOrReference,a=e.enclosingRef,o=e.context;if(eD(i)&&!o.policies.rootTypenamesById[i.__ref]&&!o.store.has(i.__ref))return{result:this.canon.empty,missing:"Dangling reference to missing ".concat(i.__ref," object")};var s=o.variables,u=o.policies,c=o.store.getFieldValue(i,"__typename"),l=[],f=new tB;function d(e,n){var r;return e.missing&&(t=f.merge(t,((r={})[n]=e.missing,r))),e.result}this.config.addTypename&&"string"==typeof c&&!u.rootIdsByTypename[c]&&l.push({__typename:c});var h=new Set(r.selections);h.forEach(function(e){var r,p;if(td(e,s)){if(eQ(e)){var b=u.readField({fieldName:e.name.value,field:e,variables:o.variables,from:i},o),m=eX(e);void 0===b?nj.added(e)||(t=f.merge(t,((r={})[m]="Can't find field '".concat(e.name.value,"' on ").concat(eD(i)?i.__ref+" object":"object "+JSON.stringify(i,null,2)),r))):(0,tP.k)(b)?b=d(n.executeSubSelectedArray({field:e,array:b,enclosingRef:a,context:o}),m):e.selectionSet?null!=b&&(b=d(n.executeSelectionSet({selectionSet:e.selectionSet,objectOrReference:b,enclosingRef:eD(b)?b:a,context:o}),m)):o.canonizeResults&&(b=n.canon.pass(b)),void 0!==b&&l.push(((p={})[m]=b,p))}else{var g=eC(e,o.lookupFragment);if(!g&&e.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(e.name.value)):new Q.ej(5);g&&u.fragmentMatches(g,c)&&g.selectionSet.selections.forEach(h.add,h)}}});var p={result:tF(l),missing:t},b=o.canonizeResults?this.canon.admit(p):(0,iu.J)(p);return b.result&&this.knownResults.set(b.result,r),b},e.prototype.execSubSelectedArrayImpl=function(e){var t,n=this,r=e.field,i=e.array,a=e.enclosingRef,o=e.context,s=new tB;function u(e,n){var r;return e.missing&&(t=s.merge(t,((r={})[n]=e.missing,r))),e.result}return r.selectionSet&&(i=i.filter(o.store.canRead)),i=i.map(function(e,t){return null===e?null:(0,tP.k)(e)?u(n.executeSubSelectedArray({field:r,array:e,enclosingRef:a,context:o}),t):r.selectionSet?u(n.executeSelectionSet({selectionSet:r.selectionSet,objectOrReference:e,enclosingRef:eD(e)?e:a,context:o}),t):(__DEV__&&ij(o.store,r,e),e)}),{result:o.canonizeResults?this.canon.admit(i):i,missing:t}},e}();function iR(e){try{JSON.stringify(e,function(e,t){if("string"==typeof t)throw t;return t})}catch(t){return t}}function ij(e,t,n){if(!t.selectionSet){var r=new Set([n]);r.forEach(function(n){(0,eO.s)(n)&&(__DEV__?(0,Q.kG)(!eD(n),"Missing selection set for object of type ".concat(im(e,n)," returned for query field ").concat(t.name.value)):(0,Q.kG)(!eD(n),6),Object.values(n).forEach(r.add,r))})}}function iF(e){var t=nG("stringifyForDisplay");return JSON.stringify(e,function(e,n){return void 0===n?t:n}).split(JSON.stringify(t)).join("")}var iY=Object.create(null);function iB(e){var t=JSON.stringify(e);return iY[t]||(iY[t]=Object.create(null))}function iU(e){var t=iB(e);return t.keyFieldsFn||(t.keyFieldsFn=function(t,n){var r=function(e,t){return n.readField(t,e)},i=n.keyObject=i$(e,function(e){var i=iW(n.storeObject,e,r);return void 0===i&&t!==n.storeObject&&ic.call(t,e[0])&&(i=iW(t,e,iG)),__DEV__?(0,Q.kG)(void 0!==i,"Missing field '".concat(e.join("."),"' while extracting keyFields from ").concat(JSON.stringify(t))):(0,Q.kG)(void 0!==i,2),i});return"".concat(n.typename,":").concat(JSON.stringify(i))})}function iH(e){var t=iB(e);return t.keyArgsFn||(t.keyArgsFn=function(t,n){var r=n.field,i=n.variables,a=n.fieldName,o=JSON.stringify(i$(e,function(e){var n=e[0],a=n.charAt(0);if("@"===a){if(r&&(0,tP.O)(r.directives)){var o=n.slice(1),s=r.directives.find(function(e){return e.name.value===o}),u=s&&eZ(s,i);return u&&iW(u,e.slice(1))}return}if("$"===a){var c=n.slice(1);if(i&&ic.call(i,c)){var l=e.slice(0);return l[0]=c,iW(i,l)}return}if(t)return iW(t,e)}));return(t||"{}"!==o)&&(a+=":"+o),a})}function i$(e,t){var n=new tB;return iz(e).reduce(function(e,r){var i,a=t(r);if(void 0!==a){for(var o=r.length-1;o>=0;--o)a=((i={})[r[o]]=a,i);e=n.merge(e,a)}return e},Object.create(null))}function iz(e){var t=iB(e);if(!t.paths){var n=t.paths=[],r=[];e.forEach(function(t,i){(0,tP.k)(t)?(iz(t).forEach(function(e){return n.push(r.concat(e))}),r.length=0):(r.push(t),(0,tP.k)(e[i+1])||(n.push(r.slice(0)),r.length=0))})}return t.paths}function iG(e,t){return e[t]}function iW(e,t,n){return n=n||iG,iK(t.reduce(function e(t,r){return(0,tP.k)(t)?t.map(function(t){return e(t,r)}):t&&n(t,r)},e))}function iK(e){return(0,eO.s)(e)?(0,tP.k)(e)?e.map(iK):i$(Object.keys(e).sort(),function(t){return iW(e,t)}):e}function iV(e){return void 0!==e.args?e.args:e.field?eZ(e.field,e.variables):null}eK.setStringify(nx);var iq=function(){},iZ=function(e,t){return t.fieldName},iX=function(e,t,n){return(0,n.mergeObjects)(e,t)},iJ=function(e,t){return t},iQ=function(){function e(e){this.config=e,this.typePolicies=Object.create(null),this.toBeAdded=Object.create(null),this.supertypeMap=new Map,this.fuzzySubtypes=new Map,this.rootIdsByTypename=Object.create(null),this.rootTypenamesById=Object.create(null),this.usingPossibleTypes=!1,this.config=(0,en.pi)({dataIdFromObject:id},e),this.cache=this.config.cache,this.setRootTypename("Query"),this.setRootTypename("Mutation"),this.setRootTypename("Subscription"),e.possibleTypes&&this.addPossibleTypes(e.possibleTypes),e.typePolicies&&this.addTypePolicies(e.typePolicies)}return e.prototype.identify=function(e,t){var n,r,i=this,a=t&&(t.typename||(null===(n=t.storeObject)||void 0===n?void 0:n.__typename))||e.__typename;if(a===this.rootTypenamesById.ROOT_QUERY)return["ROOT_QUERY"];for(var o=t&&t.storeObject||e,s=(0,en.pi)((0,en.pi)({},t),{typename:a,storeObject:o,readField:t&&t.readField||function(){var e=i0(arguments,o);return i.readField(e,{store:i.cache.data,variables:e.variables})}}),u=a&&this.getTypePolicy(a),c=u&&u.keyFn||this.config.dataIdFromObject;c;){var l=c((0,en.pi)((0,en.pi)({},e),o),s);if((0,tP.k)(l))c=iU(l);else{r=l;break}}return r=r?String(r):void 0,s.keyObject?[r,s.keyObject]:[r]},e.prototype.addTypePolicies=function(e){var t=this;Object.keys(e).forEach(function(n){var r=e[n],i=r.queryType,a=r.mutationType,o=r.subscriptionType,s=(0,en._T)(r,["queryType","mutationType","subscriptionType"]);i&&t.setRootTypename("Query",n),a&&t.setRootTypename("Mutation",n),o&&t.setRootTypename("Subscription",n),ic.call(t.toBeAdded,n)?t.toBeAdded[n].push(s):t.toBeAdded[n]=[s]})},e.prototype.updateTypePolicy=function(e,t){var n=this,r=this.getTypePolicy(e),i=t.keyFields,a=t.fields;function o(e,t){e.merge="function"==typeof t?t:!0===t?iX:!1===t?iJ:e.merge}o(r,t.merge),r.keyFn=!1===i?iq:(0,tP.k)(i)?iU(i):"function"==typeof i?i:r.keyFn,a&&Object.keys(a).forEach(function(t){var r=n.getFieldPolicy(e,t,!0),i=a[t];if("function"==typeof i)r.read=i;else{var s=i.keyArgs,u=i.read,c=i.merge;r.keyFn=!1===s?iZ:(0,tP.k)(s)?iH(s):"function"==typeof s?s:r.keyFn,"function"==typeof u&&(r.read=u),o(r,c)}r.read&&r.merge&&(r.keyFn=r.keyFn||iZ)})},e.prototype.setRootTypename=function(e,t){void 0===t&&(t=e);var n="ROOT_"+e.toUpperCase(),r=this.rootTypenamesById[n];t!==r&&(__DEV__?(0,Q.kG)(!r||r===e,"Cannot change root ".concat(e," __typename more than once")):(0,Q.kG)(!r||r===e,3),r&&delete this.rootIdsByTypename[r],this.rootIdsByTypename[t]=n,this.rootTypenamesById[n]=t)},e.prototype.addPossibleTypes=function(e){var t=this;this.usingPossibleTypes=!0,Object.keys(e).forEach(function(n){t.getSupertypeSet(n,!0),e[n].forEach(function(e){t.getSupertypeSet(e,!0).add(n);var r=e.match(ig);r&&r[0]===e||t.fuzzySubtypes.set(e,RegExp(e))})})},e.prototype.getTypePolicy=function(e){var t=this;if(!ic.call(this.typePolicies,e)){var n=this.typePolicies[e]=Object.create(null);n.fields=Object.create(null);var r=this.supertypeMap.get(e);r&&r.size&&r.forEach(function(e){var r=t.getTypePolicy(e),i=r.fields;Object.assign(n,(0,en._T)(r,["fields"])),Object.assign(n.fields,i)})}var i=this.toBeAdded[e];return i&&i.length&&i.splice(0).forEach(function(n){t.updateTypePolicy(e,n)}),this.typePolicies[e]},e.prototype.getFieldPolicy=function(e,t,n){if(e){var r=this.getTypePolicy(e).fields;return r[t]||n&&(r[t]=Object.create(null))}},e.prototype.getSupertypeSet=function(e,t){var n=this.supertypeMap.get(e);return!n&&t&&this.supertypeMap.set(e,n=new Set),n},e.prototype.fragmentMatches=function(e,t,n,r){var i=this;if(!e.typeCondition)return!0;if(!t)return!1;var a=e.typeCondition.name.value;if(t===a)return!0;if(this.usingPossibleTypes&&this.supertypeMap.has(a))for(var o=this.getSupertypeSet(t,!0),s=[o],u=function(e){var t=i.getSupertypeSet(e,!1);t&&t.size&&0>s.indexOf(t)&&s.push(t)},c=!!(n&&this.fuzzySubtypes.size),l=!1,f=0;f1?a:t}:(r=(0,en.pi)({},i),ic.call(r,"from")||(r.from=t)),__DEV__&&void 0===r.from&&__DEV__&&Q.kG.warn("Undefined 'from' passed to readField with arguments ".concat(iF(Array.from(e)))),void 0===r.variables&&(r.variables=n),r}function i2(e){return function(t,n){if((0,tP.k)(t)||(0,tP.k)(n))throw __DEV__?new Q.ej("Cannot automatically merge arrays"):new Q.ej(4);if((0,eO.s)(t)&&(0,eO.s)(n)){var r=e.getFieldValue(t,"__typename"),i=e.getFieldValue(n,"__typename");if(r&&i&&r!==i)return n;if(eD(t)&&iw(n))return e.merge(t.__ref,n),t;if(iw(t)&&eD(n))return e.merge(t,n.__ref),n;if(iw(t)&&iw(n))return(0,en.pi)((0,en.pi)({},t),n)}return n}}function i3(e,t,n){var r="".concat(t).concat(n),i=e.flavors.get(r);return i||e.flavors.set(r,i=e.clientOnly===t&&e.deferred===n?e:(0,en.pi)((0,en.pi)({},e),{clientOnly:t,deferred:n})),i}var i4=function(){function e(e,t,n){this.cache=e,this.reader=t,this.fragments=n}return e.prototype.writeToStore=function(e,t){var n=this,r=t.query,i=t.result,a=t.dataId,o=t.variables,s=t.overwrite,u=e2(r),c=i_();o=(0,en.pi)((0,en.pi)({},e9(u)),o);var l=(0,en.pi)((0,en.pi)({store:e,written:Object.create(null),merge:function(e,t){return c.merge(e,t)},variables:o,varString:nx(o)},iE(r,this.fragments)),{overwrite:!!s,incomingById:new Map,clientOnly:!1,deferred:!1,flavors:new Map}),f=this.processSelectionSet({result:i||Object.create(null),dataId:a,selectionSet:u.selectionSet,mergeTree:{map:new Map},context:l});if(!eD(f))throw __DEV__?new Q.ej("Could not identify object ".concat(JSON.stringify(i))):new Q.ej(7);return l.incomingById.forEach(function(t,r){var i=t.storeObject,a=t.mergeTree,o=t.fieldNodeSet,s=eI(r);if(a&&a.map.size){var u=n.applyMerges(a,s,i,l);if(eD(u))return;i=u}if(__DEV__&&!l.overwrite){var c=Object.create(null);o.forEach(function(e){e.selectionSet&&(c[e.name.value]=!0)});var f=function(e){return!0===c[iv(e)]},d=function(e){var t=a&&a.map.get(e);return Boolean(t&&t.info&&t.info.merge)};Object.keys(i).forEach(function(e){f(e)&&!d(e)&&at(s,i,e,l.store)})}e.merge(r,i)}),e.retain(f.__ref),f},e.prototype.processSelectionSet=function(e){var t=this,n=e.dataId,r=e.result,i=e.selectionSet,a=e.context,o=e.mergeTree,s=this.cache.policies,u=Object.create(null),c=n&&s.rootTypenamesById[n]||eJ(r,i,a.fragmentMap)||n&&a.store.get(n,"__typename");"string"==typeof c&&(u.__typename=c);var l=function(){var e=i0(arguments,u,a.variables);if(eD(e.from)){var t=a.incomingById.get(e.from.__ref);if(t){var n=s.readField((0,en.pi)((0,en.pi)({},e),{from:t.storeObject}),a);if(void 0!==n)return n}}return s.readField(e,a)},f=new Set;this.flattenFields(i,r,a,c).forEach(function(e,n){var i,a=r[eX(n)];if(f.add(n),void 0!==a){var d=s.getStoreFieldName({typename:c,fieldName:n.name.value,field:n,variables:e.variables}),h=i5(o,d),p=t.processFieldValue(a,n,n.selectionSet?i3(e,!1,!1):e,h),b=void 0;n.selectionSet&&(eD(p)||iw(p))&&(b=l("__typename",p));var m=s.getMergeFunction(c,n.name.value,b);m?h.info={field:n,typename:c,merge:m}:i7(o,d),u=e.merge(u,((i={})[d]=p,i))}else __DEV__&&!e.clientOnly&&!e.deferred&&!nj.added(n)&&!s.getReadFunction(c,n.name.value)&&__DEV__&&Q.kG.error("Missing field '".concat(eX(n),"' while writing result ").concat(JSON.stringify(r,null,2)).substring(0,1e3))});try{var d=s.identify(r,{typename:c,selectionSet:i,fragmentMap:a.fragmentMap,storeObject:u,readField:l}),h=d[0],p=d[1];n=n||h,p&&(u=a.merge(u,p))}catch(b){if(!n)throw b}if("string"==typeof n){var m=eI(n),g=a.written[n]||(a.written[n]=[]);if(g.indexOf(i)>=0||(g.push(i),this.reader&&this.reader.isFresh(r,m,i,a)))return m;var v=a.incomingById.get(n);return v?(v.storeObject=a.merge(v.storeObject,u),v.mergeTree=i8(v.mergeTree,o),f.forEach(function(e){return v.fieldNodeSet.add(e)})):a.incomingById.set(n,{storeObject:u,mergeTree:i9(o)?void 0:o,fieldNodeSet:f}),m}return u},e.prototype.processFieldValue=function(e,t,n,r){var i=this;return t.selectionSet&&null!==e?(0,tP.k)(e)?e.map(function(e,a){var o=i.processFieldValue(e,t,n,i5(r,a));return i7(r,a),o}):this.processSelectionSet({result:e,selectionSet:t.selectionSet,context:n,mergeTree:r}):__DEV__?nJ(e):e},e.prototype.flattenFields=function(e,t,n,r){void 0===r&&(r=eJ(t,e,n.fragmentMap));var i=new Map,a=this.cache.policies,o=new n_(!1);return function e(s,u){var c=o.lookup(s,u.clientOnly,u.deferred);c.visited||(c.visited=!0,s.selections.forEach(function(o){if(td(o,n.variables)){var s=u.clientOnly,c=u.deferred;if(!(s&&c)&&(0,tP.O)(o.directives)&&o.directives.forEach(function(e){var t=e.name.value;if("client"===t&&(s=!0),"defer"===t){var r=eZ(e,n.variables);r&&!1===r.if||(c=!0)}}),eQ(o)){var l=i.get(o);l&&(s=s&&l.clientOnly,c=c&&l.deferred),i.set(o,i3(n,s,c))}else{var f=eC(o,n.lookupFragment);if(!f&&o.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(o.name.value)):new Q.ej(8);f&&a.fragmentMatches(f,r,t,n.variables)&&e(f.selectionSet,i3(n,s,c))}}}))}(e,n),i},e.prototype.applyMerges=function(e,t,n,r,i){var a=this;if(e.map.size&&!eD(n)){var o,s,u=!(0,tP.k)(n)&&(eD(t)||iw(t))?t:void 0,c=n;u&&!i&&(i=[eD(u)?u.__ref:u]);var l=function(e,t){return(0,tP.k)(e)?"number"==typeof t?e[t]:void 0:r.store.getFieldValue(e,String(t))};e.map.forEach(function(e,t){var n=l(u,t),o=l(c,t);if(void 0!==o){i&&i.push(t);var f=a.applyMerges(e,n,o,r,i);f!==o&&(s=s||new Map).set(t,f),i&&(0,Q.kG)(i.pop()===t)}}),s&&(n=(0,tP.k)(c)?c.slice(0):(0,en.pi)({},c),s.forEach(function(e,t){n[t]=e}))}return e.info?this.cache.policies.runMergeFunction(t,n,e.info,r,i&&(o=r.store).getStorage.apply(o,i)):n},e}(),i6=[];function i5(e,t){var n=e.map;return n.has(t)||n.set(t,i6.pop()||{map:new Map}),n.get(t)}function i8(e,t){if(e===t||!t||i9(t))return e;if(!e||i9(e))return t;var n=e.info&&t.info?(0,en.pi)((0,en.pi)({},e.info),t.info):e.info||t.info,r=e.map.size&&t.map.size,i=r?new Map:e.map.size?e.map:t.map,a={info:n,map:i};if(r){var o=new Set(t.map.keys());e.map.forEach(function(e,n){a.map.set(n,i8(e,t.map.get(n))),o.delete(n)}),o.forEach(function(n){a.map.set(n,i8(t.map.get(n),e.map.get(n)))})}return a}function i9(e){return!e||!(e.info||e.map.size)}function i7(e,t){var n=e.map,r=n.get(t);r&&i9(r)&&(i6.push(r),n.delete(t))}var ae=new Set;function at(e,t,n,r){var i=function(e){var t=r.getFieldValue(e,n);return"object"==typeof t&&t},a=i(e);if(a){var o=i(t);if(!(!o||eD(a)||(0,nm.D)(a,o)||Object.keys(a).every(function(e){return void 0!==r.getFieldValue(o,e)}))){var s=r.getFieldValue(e,"__typename")||r.getFieldValue(t,"__typename"),u=iv(n),c="".concat(s,".").concat(u);if(!ae.has(c)){ae.add(c);var l=[];(0,tP.k)(a)||(0,tP.k)(o)||[a,o].forEach(function(e){var t=r.getFieldValue(e,"__typename");"string"!=typeof t||l.includes(t)||l.push(t)}),__DEV__&&Q.kG.warn("Cache data may be lost when replacing the ".concat(u," field of a ").concat(s," object.\n\nThis could cause additional (usually avoidable) network requests to fetch data that were otherwise cached.\n\nTo address this problem (which is not a bug in Apollo Client), ").concat(l.length?"either ensure all objects of type "+l.join(" and ")+" have an ID or a custom merge function, or ":"","define a custom merge function for the ").concat(c," field, so InMemoryCache can safely merge these objects:\n\n existing: ").concat(JSON.stringify(a).slice(0,1e3),"\n incoming: ").concat(JSON.stringify(o).slice(0,1e3),"\n\nFor more information about these options, please refer to the documentation:\n\n * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers\n * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects\n"))}}}}var an=function(e){function t(t){void 0===t&&(t={});var n=e.call(this)||this;return n.watches=new Set,n.typenameDocumentCache=new Map,n.makeVar=r2,n.txCount=0,n.config=ip(t),n.addTypename=!!n.config.addTypename,n.policies=new iQ({cache:n,dataIdFromObject:n.config.dataIdFromObject,possibleTypes:n.config.possibleTypes,typePolicies:n.config.typePolicies}),n.init(),n}return(0,en.ZT)(t,e),t.prototype.init=function(){var e=this.data=new iT.Root({policies:this.policies,resultCaching:this.config.resultCaching});this.optimisticData=e.stump,this.resetResultCache()},t.prototype.resetResultCache=function(e){var t=this,n=this.storeReader,r=this.config.fragments;this.storeWriter=new i4(this,this.storeReader=new iP({cache:this,addTypename:this.addTypename,resultCacheMaxSize:this.config.resultCacheMaxSize,canonizeResults:ib(this.config),canon:e?void 0:n&&n.canon,fragments:r}),r),this.maybeBroadcastWatch=rZ(function(e,n){return t.broadcastWatch(e,n)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var n=e.optimistic?t.optimisticData:t.data;if(iD(n)){var r=e.optimistic,i=e.id,a=e.variables;return n.makeCacheKey(e.query,e.callback,nx({optimistic:r,id:i,variables:a}))}}}),new Set([this.data.group,this.optimisticData.group,]).forEach(function(e){return e.resetCaching()})},t.prototype.restore=function(e){return this.init(),e&&this.data.replace(e),this},t.prototype.extract=function(e){return void 0===e&&(e=!1),(e?this.optimisticData:this.data).extract()},t.prototype.read=function(e){var t=e.returnPartialData,n=void 0!==t&&t;try{return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,config:this.config,returnPartialData:n})).result||null}catch(r){if(r instanceof is)return null;throw r}},t.prototype.write=function(e){try{return++this.txCount,this.storeWriter.writeToStore(this.data,e)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.modify=function(e){if(ic.call(e,"id")&&!e.id)return!1;var t=e.optimistic?this.optimisticData:this.data;try{return++this.txCount,t.modify(e.id||"ROOT_QUERY",e.fields)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.diff=function(e){return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,rootId:e.id||"ROOT_QUERY",config:this.config}))},t.prototype.watch=function(e){var t=this;return this.watches.size||r0(this),this.watches.add(e),e.immediate&&this.maybeBroadcastWatch(e),function(){t.watches.delete(e)&&!t.watches.size&&r1(t),t.maybeBroadcastWatch.forget(e)}},t.prototype.gc=function(e){nx.reset();var t=this.optimisticData.gc();return e&&!this.txCount&&(e.resetResultCache?this.resetResultCache(e.resetResultIdentities):e.resetResultIdentities&&this.storeReader.resetCanon()),t},t.prototype.retain=function(e,t){return(t?this.optimisticData:this.data).retain(e)},t.prototype.release=function(e,t){return(t?this.optimisticData:this.data).release(e)},t.prototype.identify=function(e){if(eD(e))return e.__ref;try{return this.policies.identify(e)[0]}catch(t){__DEV__&&Q.kG.warn(t)}},t.prototype.evict=function(e){if(!e.id){if(ic.call(e,"id"))return!1;e=(0,en.pi)((0,en.pi)({},e),{id:"ROOT_QUERY"})}try{return++this.txCount,this.optimisticData.evict(e,this.data)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.reset=function(e){var t=this;return this.init(),nx.reset(),e&&e.discardWatches?(this.watches.forEach(function(e){return t.maybeBroadcastWatch.forget(e)}),this.watches.clear(),r1(this)):this.broadcastWatches(),Promise.resolve()},t.prototype.removeOptimistic=function(e){var t=this.optimisticData.removeLayer(e);t!==this.optimisticData&&(this.optimisticData=t,this.broadcastWatches())},t.prototype.batch=function(e){var t,n=this,r=e.update,i=e.optimistic,a=void 0===i||i,o=e.removeOptimistic,s=e.onWatchUpdated,u=function(e){var i=n,a=i.data,o=i.optimisticData;++n.txCount,e&&(n.data=n.optimisticData=e);try{return t=r(n)}finally{--n.txCount,n.data=a,n.optimisticData=o}},c=new Set;return s&&!this.txCount&&this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e){return c.add(e),!1}})),"string"==typeof a?this.optimisticData=this.optimisticData.addLayer(a,u):!1===a?u(this.data):u(),"string"==typeof o&&(this.optimisticData=this.optimisticData.removeLayer(o)),s&&c.size?(this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e,t){var n=s.call(this,e,t);return!1!==n&&c.delete(e),n}})),c.size&&c.forEach(function(e){return n.maybeBroadcastWatch.dirty(e)})):this.broadcastWatches(e),t},t.prototype.performTransaction=function(e,t){return this.batch({update:e,optimistic:t||null!==t})},t.prototype.transformDocument=function(e){if(this.addTypename){var t=this.typenameDocumentCache.get(e);return t||(t=nj(e),this.typenameDocumentCache.set(e,t),this.typenameDocumentCache.set(t,t)),t}return e},t.prototype.transformForLink=function(e){var t=this.config.fragments;return t?t.transform(e):e},t.prototype.broadcastWatches=function(e){var t=this;this.txCount||this.watches.forEach(function(n){return t.maybeBroadcastWatch(n,e)})},t.prototype.broadcastWatch=function(e,t){var n=e.lastDiff,r=this.diff(e);(!t||(e.optimistic&&"string"==typeof t.optimistic&&(r.fromOptimisticTransaction=!0),!t.onWatchUpdated||!1!==t.onWatchUpdated.call(this,e,r,n)))&&(n&&(0,nm.D)(n.result,r.result)||e.callback(e.lastDiff=r,n))},t}(io),ar={possibleTypes:{ApproveJobProposalSpecPayload:["ApproveJobProposalSpecSuccess","JobAlreadyExistsError","NotFoundError"],BridgePayload:["Bridge","NotFoundError"],CancelJobProposalSpecPayload:["CancelJobProposalSpecSuccess","NotFoundError"],ChainPayload:["Chain","NotFoundError"],CreateAPITokenPayload:["CreateAPITokenSuccess","InputErrors"],CreateBridgePayload:["CreateBridgeSuccess"],CreateCSAKeyPayload:["CSAKeyExistsError","CreateCSAKeySuccess"],CreateFeedsManagerChainConfigPayload:["CreateFeedsManagerChainConfigSuccess","InputErrors","NotFoundError"],CreateFeedsManagerPayload:["CreateFeedsManagerSuccess","DuplicateFeedsManagerError","InputErrors","NotFoundError","SingleFeedsManagerError"],CreateJobPayload:["CreateJobSuccess","InputErrors"],CreateOCR2KeyBundlePayload:["CreateOCR2KeyBundleSuccess"],CreateOCRKeyBundlePayload:["CreateOCRKeyBundleSuccess"],CreateP2PKeyPayload:["CreateP2PKeySuccess"],DeleteAPITokenPayload:["DeleteAPITokenSuccess","InputErrors"],DeleteBridgePayload:["DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DeleteBridgeSuccess","NotFoundError"],DeleteCSAKeyPayload:["DeleteCSAKeySuccess","NotFoundError"],DeleteFeedsManagerChainConfigPayload:["DeleteFeedsManagerChainConfigSuccess","NotFoundError"],DeleteJobPayload:["DeleteJobSuccess","NotFoundError"],DeleteOCR2KeyBundlePayload:["DeleteOCR2KeyBundleSuccess","NotFoundError"],DeleteOCRKeyBundlePayload:["DeleteOCRKeyBundleSuccess","NotFoundError"],DeleteP2PKeyPayload:["DeleteP2PKeySuccess","NotFoundError"],DeleteVRFKeyPayload:["DeleteVRFKeySuccess","NotFoundError"],DismissJobErrorPayload:["DismissJobErrorSuccess","NotFoundError"],Error:["CSAKeyExistsError","DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DuplicateFeedsManagerError","InputError","JobAlreadyExistsError","NotFoundError","RunJobCannotRunError","SingleFeedsManagerError"],EthTransactionPayload:["EthTransaction","NotFoundError"],FeaturesPayload:["Features"],FeedsManagerPayload:["FeedsManager","NotFoundError"],GetSQLLoggingPayload:["SQLLogging"],GlobalLogLevelPayload:["GlobalLogLevel"],JobPayload:["Job","NotFoundError"],JobProposalPayload:["JobProposal","NotFoundError"],JobRunPayload:["JobRun","NotFoundError"],JobSpec:["BlockHeaderFeederSpec","BlockhashStoreSpec","BootstrapSpec","CronSpec","DirectRequestSpec","FluxMonitorSpec","GatewaySpec","KeeperSpec","OCR2Spec","OCRSpec","StandardCapabilitiesSpec","VRFSpec","WebhookSpec","WorkflowSpec"],NodePayload:["Node","NotFoundError"],PaginatedPayload:["BridgesPayload","ChainsPayload","EthTransactionAttemptsPayload","EthTransactionsPayload","JobRunsPayload","JobsPayload","NodesPayload"],RejectJobProposalSpecPayload:["NotFoundError","RejectJobProposalSpecSuccess"],RunJobPayload:["NotFoundError","RunJobCannotRunError","RunJobSuccess"],SetGlobalLogLevelPayload:["InputErrors","SetGlobalLogLevelSuccess"],SetSQLLoggingPayload:["SetSQLLoggingSuccess"],SetServicesLogLevelsPayload:["InputErrors","SetServicesLogLevelsSuccess"],UpdateBridgePayload:["NotFoundError","UpdateBridgeSuccess"],UpdateFeedsManagerChainConfigPayload:["InputErrors","NotFoundError","UpdateFeedsManagerChainConfigSuccess"],UpdateFeedsManagerPayload:["InputErrors","NotFoundError","UpdateFeedsManagerSuccess"],UpdateJobProposalSpecDefinitionPayload:["NotFoundError","UpdateJobProposalSpecDefinitionSuccess"],UpdatePasswordPayload:["InputErrors","UpdatePasswordSuccess"],VRFKeyPayload:["NotFoundError","VRFKeySuccess"]}};let ai=ar;var aa=(r=void 0,location.origin),ao=new nh({uri:"".concat(aa,"/query"),credentials:"include"}),as=new ia({cache:new an({possibleTypes:ai.possibleTypes}),link:ao});if(a.Z.locale(o),u().defaultFormat="YYYY-MM-DD h:mm:ss A","undefined"!=typeof document){var au,ac,al=f().hydrate;ac=X,al(c.createElement(et,{client:as},c.createElement(d.zj,null,c.createElement(i.MuiThemeProvider,{theme:J.r},c.createElement(ac,null)))),document.getElementById("root"))}})()})(); \ No newline at end of file +`+(a!==i?`result of cast: ${a}`:""))}return r}_cast(e,t){let n=void 0===e?e:this.transforms.reduce((t,n)=>n.call(this,t,e,this),e);return void 0===n&&(n=this.getDefault()),n}_validate(e,t={},n){let{sync:r,path:i,from:a=[],originalValue:o=e,strict:s=this.spec.strict,abortEarly:u=this.spec.abortEarly}=t,c=e;s||(c=this._cast(c,pB({assert:!1},t)));let l={value:c,path:i,options:t,originalValue:o,schema:this,label:this.spec.label,sync:r,from:a},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),pO({args:l,value:c,path:i,sync:r,tests:f,endEarly:u},e=>{if(e)return void n(e,c);pO({tests:this.tests,args:l,path:i,sync:r,value:c,endEarly:u},n)})}validate(e,t,n){let r=this.resolve(pB({},t,{value:e}));return"function"==typeof n?r._validate(e,t,n):new Promise((n,i)=>r._validate(e,t,(e,t)=>{e?i(e):n(t)}))}validateSync(e,t){let n;return this.resolve(pB({},t,{value:e}))._validate(e,pB({},t,{sync:!0}),(e,t)=>{if(e)throw e;n=t}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,e=>{if(pT.isError(e))return!1;throw e})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(n){if(pT.isError(n))return!1;throw n}}_getDefault(){let e=this.spec.default;return null==e?e:"function"==typeof e?e.call(this):pn(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return 0===arguments.length?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return null!=e}defined(e=pf.defined){return this.test({message:e,name:"defined",exclusive:!0,test:e=>void 0!==e})}required(e=pf.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(e){return this.schema._isPresent(e)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(e=>"required"!==e.OPTIONS.name),e}nullable(e=!0){return this.clone({nullable:!1!==e})}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(void 0===(t=1===e.length?"function"==typeof e[0]?{test:e[0]}:e[0]:2===e.length?{name:e[0],test:e[1]}:{name:e[0],message:e[1],test:e[2]}).message&&(t.message=pf.default),"function"!=typeof t.test)throw TypeError("`test` is a required parameters");let n=this.clone(),r=pR(t),i=t.exclusive||t.name&&!0===n.exclusiveTests[t.name];if(t.exclusive&&!t.name)throw TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(n.exclusiveTests[t.name]=!!t.exclusive),n.tests=n.tests.filter(e=>e.OPTIONS.name!==t.name||!i&&e.OPTIONS.test!==r.OPTIONS.test),n.tests.push(r),n}when(e,t){Array.isArray(e)||"string"==typeof e||(t=e,e=".");let n=this.clone(),r=pS(e).map(e=>new pD(e));return r.forEach(e=>{e.isSibling&&n.deps.push(e.key)}),n.conditions.push(new pE(r,t)),n}typeError(e){var t=this.clone();return t._typeError=pR({message:e,name:"typeError",test(e){return!!(void 0===e||this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t}oneOf(e,t=pf.oneOf){var n=this.clone();return e.forEach(e=>{n._whitelist.add(e),n._blacklist.delete(e)}),n._whitelistError=pR({message:t,name:"oneOf",test(e){if(void 0===e)return!0;let t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}notOneOf(e,t=pf.notOneOf){var n=this.clone();return e.forEach(e=>{n._blacklist.add(e),n._whitelist.delete(e)}),n._blacklistError=pR({message:t,name:"notOneOf",test(e){let t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:n}=e.spec,r={meta:n,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(e=>({name:e.OPTIONS.name,params:e.OPTIONS.params})).filter((e,t,n)=>n.findIndex(t=>t.name===e.name)===t)};return r}}for(let pH of(pU.prototype.__isYupSchema__=!0,["validate","validateSync"]))pU.prototype[`${pH}At`]=function(e,t,n={}){let{parent:r,parentPath:i,schema:a}=pF(this,e,t,n.context);return a[pH](r&&r[i],pB({},n,{parent:r,path:e}))};for(let p$ of["equals","is"])pU.prototype[p$]=pU.prototype.oneOf;for(let pz of["not","nope"])pU.prototype[pz]=pU.prototype.notOneOf;pU.prototype.optional=pU.prototype.notRequired;let pG=pU;function pW(){return new pG}pW.prototype=pG.prototype;let pK=e=>null==e;function pV(){return new pq}class pq extends pU{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}isTrue(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test:e=>pK(e)||!0===e})}isFalse(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test:e=>pK(e)||!1===e})}}pV.prototype=pq.prototype;let pZ=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,pX=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,pJ=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,pQ=e=>pK(e)||e===e.trim(),p1=({}).toString();function p0(){return new p2}class p2 extends pU{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=null!=e&&e.toString?e.toString():e;return t===p1?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=pd.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t=pd.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t=pd.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}matches(e,t){let n=!1,r,i;return t&&("object"==typeof t?{excludeEmptyString:n=!1,message:r,name:i}=t:r=t),this.test({name:i||"matches",message:r||pd.matches,params:{regex:e},test:t=>pK(t)||""===t&&n||-1!==t.search(e)})}email(e=pd.email){return this.matches(pZ,{name:"email",message:e,excludeEmptyString:!0})}url(e=pd.url){return this.matches(pX,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=pd.uuid){return this.matches(pJ,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>null===e?"":e)}trim(e=pd.trim){return this.transform(e=>null!=e?e.trim():e).test({message:e,name:"trim",test:pQ})}lowercase(e=pd.lowercase){return this.transform(e=>pK(e)?e:e.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toLowerCase()})}uppercase(e=pd.uppercase){return this.transform(e=>pK(e)?e:e.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toUpperCase()})}}p0.prototype=p2.prototype;let p3=e=>e!=+e;function p4(){return new p6}class p6 extends pU{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!p3(e)}min(e,t=ph.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t>=this.resolve(e)}})}max(e,t=ph.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t<=this.resolve(e)}})}lessThan(e,t=ph.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(t){return pK(t)||tthis.resolve(e)}})}positive(e=ph.positive){return this.moreThan(0,e)}negative(e=ph.negative){return this.lessThan(0,e)}integer(e=ph.integer){return this.test({name:"integer",message:e,test:e=>pK(e)||Number.isInteger(e)})}truncate(){return this.transform(e=>pK(e)?e:0|e)}round(e){var t,n=["ceil","floor","round","trunc"];if("trunc"===(e=(null==(t=e)?void 0:t.toLowerCase())||"round"))return this.truncate();if(-1===n.indexOf(e.toLowerCase()))throw TypeError("Only valid options for round() are: "+n.join(", "));return this.transform(t=>pK(t)?t:Math[e](t))}}p4.prototype=p6.prototype;var p5=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function p8(e){var t,n,r=[1,4,5,6,7,10,11],i=0;if(n=p5.exec(e)){for(var a,o=0;a=r[o];++o)n[a]=+n[a]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(void 0===n[8]||""===n[8])&&(void 0===n[9]||""===n[9])?t=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):("Z"!==n[8]&&void 0!==n[9]&&(i=60*n[10]+n[11],"+"===n[9]&&(i=0-i)),t=Date.UTC(n[1],n[2],n[3],n[4],n[5]+i,n[6],n[7]))}else t=Date.parse?Date.parse(e):NaN;return t}let p9=new Date(""),p7=e=>"[object Date]"===Object.prototype.toString.call(e);function be(){return new bt}class bt extends pU{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=p8(e),isNaN(e)?p9:new Date(e))})})}_typeCheck(e){return p7(e)&&!isNaN(e.getTime())}prepareParam(e,t){let n;if(pD.isRef(e))n=e;else{let r=this.cast(e);if(!this._typeCheck(r))throw TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);n=r}return n}min(e,t=pp.min){let n=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(e){return pK(e)||e>=this.resolve(n)}})}max(e,t=pp.max){var n=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(e){return pK(e)||e<=this.resolve(n)}})}}bt.INVALID_DATE=p9,be.prototype=bt.prototype,be.INVALID_DATE=p9;var bn=n(11865),br=n.n(bn),bi=n(68929),ba=n.n(bi),bo=n(67523),bs=n.n(bo),bu=n(94633),bc=n.n(bu);function bl(e,t=[]){let n=[],r=[];function i(e,i){var a=(0,pC.split)(e)[0];~r.indexOf(a)||r.push(a),~t.indexOf(`${i}-${a}`)||n.push([i,a])}for(let a in e)if(py()(e,a)){let o=e[a];~r.indexOf(a)||r.push(a),pD.isRef(o)&&o.isSibling?i(o.path,a):pw(o)&&"deps"in o&&o.deps.forEach(e=>i(e,a))}return bc().array(r,n).reverse()}function bf(e,t){let n=1/0;return e.some((e,r)=>{var i;if((null==(i=t.path)?void 0:i.indexOf(e))!==-1)return n=r,!0}),n}function bd(e){return(t,n)=>bf(e,t)-bf(e,n)}function bh(){return(bh=Object.assign||function(e){for(var t=1;t"[object Object]"===Object.prototype.toString.call(e);function bb(e,t){let n=Object.keys(e.fields);return Object.keys(t).filter(e=>-1===n.indexOf(e))}let bm=bd([]);class bg extends pU{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=bm,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null}),e&&this.shape(e)})}_typeCheck(e){return bp(e)||"function"==typeof e}_cast(e,t={}){var n;let r=super._cast(e,t);if(void 0===r)return this.getDefault();if(!this._typeCheck(r))return r;let i=this.fields,a=null!=(n=t.stripUnknown)?n:this.spec.noUnknown,o=this._nodes.concat(Object.keys(r).filter(e=>-1===this._nodes.indexOf(e))),s={},u=bh({},t,{parent:s,__validating:t.__validating||!1}),c=!1;for(let l of o){let f=i[l],d=py()(r,l);if(f){let h,p=r[l];u.path=(t.path?`${t.path}.`:"")+l;let b="spec"in(f=f.resolve({value:p,context:t.context,parent:s}))?f.spec:void 0,m=null==b?void 0:b.strict;if(null==b?void 0:b.strip){c=c||l in r;continue}void 0!==(h=t.__validating&&m?r[l]:f.cast(r[l],u))&&(s[l]=h)}else d&&!a&&(s[l]=r[l]);s[l]!==r[l]&&(c=!0)}return c?s:r}_validate(e,t={},n){let r=[],{sync:i,from:a=[],originalValue:o=e,abortEarly:s=this.spec.abortEarly,recursive:u=this.spec.recursive}=t;a=[{schema:this,value:o},...a],t.__validating=!0,t.originalValue=o,t.from=a,super._validate(e,t,(e,c)=>{if(e){if(!pT.isError(e)||s)return void n(e,c);r.push(e)}if(!u||!bp(c)){n(r[0]||null,c);return}o=o||c;let l=this._nodes.map(e=>(n,r)=>{let i=-1===e.indexOf(".")?(t.path?`${t.path}.`:"")+e:`${t.path||""}["${e}"]`,s=this.fields[e];if(s&&"validate"in s){s.validate(c[e],bh({},t,{path:i,from:a,strict:!0,parent:c,originalValue:o[e]}),r);return}r(null)});pO({sync:i,tests:l,value:c,errors:r,endEarly:s,sort:this._sortErrors,path:t.path},n)})}clone(e){let t=super.clone(e);return t.fields=bh({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),n=t.fields;for(let[r,i]of Object.entries(this.fields)){let a=n[r];void 0===a?n[r]=i:a instanceof pU&&i instanceof pU&&(n[r]=i.concat(a))}return t.withMutation(()=>t.shape(n))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let n=this.fields[t];e[t]="default"in n?n.getDefault():void 0}),e}_getDefault(){return"default"in this.spec?super._getDefault():this._nodes.length?this.getDefaultFromShape():void 0}shape(e,t=[]){let n=this.clone(),r=Object.assign(n.fields,e);if(n.fields=r,n._sortErrors=bd(Object.keys(r)),t.length){Array.isArray(t[0])||(t=[t]);let i=t.map(([e,t])=>`${e}-${t}`);n._excludedEdges=n._excludedEdges.concat(i)}return n._nodes=bl(r,n._excludedEdges),n}pick(e){let t={};for(let n of e)this.fields[n]&&(t[n]=this.fields[n]);return this.clone().withMutation(e=>(e.fields={},e.shape(t)))}omit(e){let t=this.clone(),n=t.fields;for(let r of(t.fields={},e))delete n[r];return t.withMutation(()=>t.shape(n))}from(e,t,n){let r=(0,pC.getter)(e,!0);return this.transform(i=>{if(null==i)return i;let a=i;return py()(i,e)&&(a=bh({},i),n||delete a[e],a[t]=r(i)),a})}noUnknown(e=!0,t=pm.noUnknown){"string"==typeof e&&(t=e,e=!0);let n=this.test({name:"noUnknown",exclusive:!0,message:t,test(t){if(null==t)return!0;let n=bb(this.schema,t);return!e||0===n.length||this.createError({params:{unknown:n.join(", ")}})}});return n.spec.noUnknown=e,n}unknown(e=!0,t=pm.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&bs()(t,(t,n)=>e(n)))}camelCase(){return this.transformKeys(ba())}snakeCase(){return this.transformKeys(br())}constantCase(){return this.transformKeys(e=>br()(e).toUpperCase())}describe(){let e=super.describe();return e.fields=pL()(this.fields,e=>e.describe()),e}}function bv(e){return new bg(e)}function by(){return(by=Object.assign||function(e){for(var t=1;t{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let n=super._cast(e,t);if(!this._typeCheck(n)||!this.innerType)return n;let r=!1,i=n.map((e,n)=>{let i=this.innerType.cast(e,by({},t,{path:`${t.path||""}[${n}]`}));return i!==e&&(r=!0),i});return r?i:n}_validate(e,t={},n){var r,i;let a=[],o=t.sync,s=t.path,u=this.innerType,c=null!=(r=t.abortEarly)?r:this.spec.abortEarly,l=null!=(i=t.recursive)?i:this.spec.recursive,f=null!=t.originalValue?t.originalValue:e;super._validate(e,t,(e,r)=>{if(e){if(!pT.isError(e)||c)return void n(e,r);a.push(e)}if(!l||!u||!this._typeCheck(r)){n(a[0]||null,r);return}f=f||r;let i=Array(r.length);for(let d=0;du.validate(h,b,t)}pO({sync:o,path:s,value:r,errors:a,endEarly:c,tests:i},n)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!pw(e))throw TypeError("`array.of()` sub-schema must be a valid yup schema not: "+pl(e));return t.innerType=e,t}length(e,t=pg.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t){return t=t||pg.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t){return t=t||pg.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:null==t?[]:[].concat(t))}compact(e){let t=e?(t,n,r)=>!e(t,n,r):e=>!!e;return this.transform(e=>null!=e?e.filter(t):e)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}}bw.prototype=b_.prototype;var bE=bv().shape({name:p0().required("Required"),url:p0().required("Required")}),bS=function(e){var t=e.initialValues,n=e.onSubmit,r=e.submitButtonText,i=e.nameDisabled,a=void 0!==i&&i;return l.createElement(hT,{initialValues:t,validationSchema:bE,onSubmit:n},function(e){var t=e.isSubmitting;return l.createElement(l.Fragment,null,l.createElement(hR,{"data-testid":"bridge-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",disabled:a,required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"url",name:"url",label:"Bridge URL",placeholder:"https://",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"url-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"minimumContractPayment",name:"minimumContractPayment",label:"Minimum Contract Payment",placeholder:"0",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"minimumContractPayment-helper-text"}})),l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"confirmations",name:"confirmations",label:"Confirmations",placeholder:"0",type:"number",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"confirmations-helper-text"}})))),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},r)))))})},bk=function(e){var t=e.bridge,n=e.onSubmit,r={name:t.name,url:t.url,minimumContractPayment:t.minimumContractPayment,confirmations:t.confirmations};return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:40},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Bridge",action:l.createElement(aA.Z,{component:tz,href:"/bridges/".concat(t.id)},"Cancel")}),l.createElement(aW.Z,null,l.createElement(bS,{nameDisabled:!0,initialValues:r,onSubmit:n,submitButtonText:"Save Bridge"}))))))};function bx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]&&arguments[0],t=e?function(){return l.createElement(x.default,{variant:"body1"},"Loading...")}:function(){return null};return{isLoading:e,LoadingPlaceholder:t}},mc=n(76023);function ml(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function mB(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=4?[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]:void 0}var mZ={};function mX(e){if(0===e.length||1===e.length)return e;var t=e.join(".");return mZ[t]||(mZ[t]=mq(e)),mZ[t]}function mJ(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return mX(e.filter(function(e){return"token"!==e})).reduce(function(e,t){return mK({},e,n[t])},t)}function mQ(e){return e.join(" ")}function m1(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return m0({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(i)})})}}function m0(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,o=e.key,s=t.properties,u=t.type,c=t.tagName,f=t.value;if("text"===u)return f;if(c){var d,h=m1(n,a);if(a){var p=Object.keys(n).reduce(function(e,t){return t.split(".").forEach(function(t){e.includes(t)||e.push(t)}),e},[]),b=s.className&&s.className.includes("token")?["token"]:[],m=s.className&&b.concat(s.className.filter(function(e){return!p.includes(e)}));d=mK({},s,{className:mQ(m)||void 0,style:mJ(s.className,Object.assign({},s.style,i),n)})}else d=mK({},s,{className:mQ(s.className)});var g=h(t.children);return l.createElement(c,(0,mV.Z)({key:o},d),g)}}let m2=function(e,t){return -1!==e.listLanguages().indexOf(t)};var m3=/\n/g;function m4(e){return e.match(m3)}function m6(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return l.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof r?r(i):r},"".concat(i,"\n"))})}function m5(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,o=void 0===a?{}:a,s=e.startingLineNumber;return l.createElement("code",{style:Object.assign({},n,i)},m6({lines:t.replace(/\n$/,"").split("\n"),style:o,startingLineNumber:s}))}function m8(e){return"".concat(e.toString().length,".25em")}function m9(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function m7(e,t,n){var r,i={display:"inline-block",minWidth:m8(n),paddingRight:"1em",textAlign:"right",userSelect:"none"};return mK({},i,"function"==typeof e?e(t):e)}function ge(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=void 0===o?{}:o,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,f=e.wrapLongLines,d="function"==typeof s?s(n):s;if(d.className=c,n&&a){var h=m7(r,n,i);t.unshift(m9(n,h))}return f&l&&(d.style=mK({},d.style,{display:"flex"})),{type:"element",tagName:"span",properties:d,children:t}}function gt(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return ge({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:a,showLineNumbers:r,wrapLongLines:u})}function b(e,t){if(r&&t&&i){var n=m7(s,t,o);e.unshift(m9(t,n))}return e}function m(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||r.length>0?p(e,n,r):b(e,n)}for(var g=function(){var e=l[h],t=e.children[0].value;if(m4(t)){var n=t.split("\n");n.forEach(function(t,i){var o=r&&f.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===i){var u=l.slice(d+1,h).concat(ge({children:[s],className:e.properties.className})),c=m(u,o);f.push(c)}else if(i===n.length-1){if(l[h+1]&&l[h+1].children&&l[h+1].children[0]){var p={type:"text",value:"".concat(t)},b=ge({children:[p],className:e.properties.className});l.splice(h+1,0,b)}else{var g=[s],v=m(g,o,e.properties.className);f.push(v)}}else{var y=[s],w=m(y,o,e.properties.className);f.push(w)}}),d=h}h++};h code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}};var gu=n(98695),gc=n.n(gu);let gl=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];var gf=go(gc(),gs);gf.supportedLanguages=gl;let gd=gf;var gh=n(64566);function gp(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function gb(){var e=gp(["\n query FetchConfigV2 {\n configv2 {\n user\n effective\n }\n }\n"]);return gb=function(){return e},e}var gm=n0(gb()),gg=function(e){var t=e.children;return l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},t))},gv=function(){return l.createElement(gg,null,"...")},gy=function(e){var t=e.children;return l.createElement(gg,null,t)},gw=function(e){var t=e.loading,n=e.toml,r=e.error,i=void 0===r?"":r,a=e.title,o=e.expanded;if(i)return l.createElement(gy,null,i);if(t)return l.createElement(gv,null);a||(a="TOML");var s={display:"block"};return l.createElement(x.default,null,l.createElement(mP.Z,{defaultExpanded:o},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},a),l.createElement(mj.Z,{style:s},l.createElement(gd,{language:"toml",style:gs},n))))},g_=function(){var e=rv(gm,{fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return(null==t?void 0:t.configv2.effective)=="N/A"?l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"V2 config dump:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0})))):l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"User specified:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0,expanded:!0}),l.createElement(gw,{title:"Effective (with defaults):",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.effective,showHead:!0})))))},gE=n(34823),gS=function(e){return(0,b.createStyles)({cell:{paddingTop:1.5*e.spacing.unit,paddingBottom:1.5*e.spacing.unit}})},gk=(0,b.withStyles)(gS)(function(e){var t=e.classes,n=(0,A.I0)();(0,l.useEffect)(function(){n((0,ty.DQ)())});var r=(0,A.v9)(gE.N,A.wU);return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Node"}),l.createElement(r8.Z,null,l.createElement(r9.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"Version"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.version))),l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"SHA"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.commitSHA))))))}),gx=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,sm:12,md:8},l.createElement(d.Z,{container:!0},l.createElement(g_,null))),l.createElement(d.Z,{item:!0,sm:12,md:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gk,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mN,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mE,null))))))},gT=function(){return l.createElement(gx,null)},gM=function(){return l.createElement(gT,null)},gO=n(44431),gA=1e18,gL=function(e){return new gO.BigNumber(e).dividedBy(gA).toFixed(8)},gC=function(e){var t=e.keys,n=e.chainID,r=e.hideHeaderTitle;return l.createElement(l.Fragment,null,l.createElement(sl.Z,{title:!r&&"Account Balances",subheader:"Chain ID "+n}),l.createElement(aW.Z,null,l.createElement(w.default,{dense:!1,disablePadding:!0},t&&t.map(function(e,r){return l.createElement(l.Fragment,null,l.createElement(_.default,{disableGutters:!0,key:["acc-balance",n.toString(),r.toString()].join("-")},l.createElement(E.Z,{primary:l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(op,{title:"Address"}),l.createElement(ob,{value:e.address})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"Native Token Balance"}),l.createElement(ob,{value:e.ethBalance||"--"})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"LINK Balance"}),l.createElement(ob,{value:e.linkBalance?gL(e.linkBalance):"--"}))))})),r+1s&&l.createElement(gB.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:r.footer},l.createElement(aA.Z,{href:"/runs",component:tz},"View More"))))))});function vt(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vn(){var e=vt(["\n ","\n query FetchRecentJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...RecentJobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return vn=function(){return e},e}var vr=5,vi=n0(vn(),g9),va=function(){var e=rv(vi,{variables:{offset:0,limit:vr},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(ve,{data:t,errorMsg:null==r?void 0:r.message,loading:n,maxRunsSize:vr})},vo=function(e){return(0,b.createStyles)({style:{textAlign:"center",padding:2.5*e.spacing.unit,position:"fixed",left:"0",bottom:"0",width:"100%",borderRadius:0},bareAnchor:{color:e.palette.common.black,textDecoration:"none"}})},vs=(0,b.withStyles)(vo)(function(e){var t=e.classes,n=(0,A.v9)(gE.N,A.wU),r=(0,A.I0)();return(0,l.useEffect)(function(){r((0,ty.DQ)())}),l.createElement(ii.default,{className:t.style},l.createElement(x.default,null,"Chainlink Node ",n.version," at commit"," ",l.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/smartcontractkit/chainlink/commit/".concat(n.commitSHA),className:t.bareAnchor},n.commitSHA)))}),vu=function(e){return(0,b.createStyles)({cell:{borderColor:e.palette.divider,borderTop:"1px solid",borderBottom:"none",paddingTop:2*e.spacing.unit,paddingBottom:2*e.spacing.unit,paddingLeft:2*e.spacing.unit},block:{display:"block"},overflowEllipsis:{textOverflow:"ellipsis",overflow:"hidden"}})},vc=(0,b.withStyles)(vu)(function(e){var t=e.classes,n=e.job;return l.createElement(ir.Z,null,l.createElement(r7.default,{scope:"row",className:t.cell},l.createElement(d.Z,{container:!0,spacing:0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ih,{href:"/jobs/".concat(n.id),classes:{linkContent:t.block}},l.createElement(x.default,{className:t.overflowEllipsis,variant:"body1",component:"span",color:"primary"},n.name||n.id))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,{variant:"body1",color:"textSecondary"},"Created ",l.createElement(aO,{tooltip:!0},n.createdAt))))))});function vl(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vf(){var e=vl(["\n fragment RecentJobsPayload_ResultsFields on Job {\n id\n name\n createdAt\n }\n"]);return vf=function(){return e},e}var vd=n0(vf()),vh=function(){return(0,b.createStyles)({cardHeader:{borderBottom:0},table:{tableLayout:"fixed"}})},vp=(0,b.withStyles)(vh)(function(e){var t,n,r=e.classes,i=e.data,a=e.errorMsg,o=e.loading;return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Recent Jobs",className:r.cardHeader}),l.createElement(r8.Z,{className:r.table},l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(t=null==i?void 0:i.jobs.results)||void 0===t?void 0:t.length)===0},"No recently created jobs"),l.createElement(gU,{msg:a}),null===(n=null==i?void 0:i.jobs.results)||void 0===n?void 0:n.map(function(e,t){return l.createElement(vc,{job:e,key:t})}))))});function vb(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vm(){var e=vb(["\n ","\n query FetchRecentJobs($offset: Int, $limit: Int) {\n jobs(offset: $offset, limit: $limit) {\n results {\n ...RecentJobsPayload_ResultsFields\n }\n }\n }\n"]);return vm=function(){return e},e}var vg=5,vv=n0(vm(),vd),vy=function(){var e=rv(vv,{variables:{offset:0,limit:vg},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vp,{data:t,errorMsg:null==r?void 0:r.message,loading:n})},vw=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:8},l.createElement(va,null)),l.createElement(d.Z,{item:!0,xs:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gY,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(vy,null))))),l.createElement(vs,null))},v_=function(){return l.createElement(vw,null)},vE=function(){return l.createElement(v_,null)},vS=n(87239),vk=function(e){switch(e){case"DirectRequestSpec":return"Direct Request";case"FluxMonitorSpec":return"Flux Monitor";default:return e.replace(/Spec$/,"")}},vx=n(5022),vT=n(78718),vM=n.n(vT);function vO(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1?t-1:0),r=1;r1?t-1:0),r=1;re.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&n.map(function(e){return l.createElement(ir.Z,{key:e.id,style:{cursor:"pointer"},onClick:function(){return r.push("/runs/".concat(e.id))}},l.createElement(r7.default,{className:t.idCell,scope:"row"},l.createElement("div",{className:t.runDetails},l.createElement(x.default,{variant:"h5",color:"primary",component:"span"},e.id))),l.createElement(r7.default,{className:t.stampCell},l.createElement(x.default,{variant:"body1",color:"textSecondary",className:t.stamp},"Created ",l.createElement(aO,{tooltip:!0},e.createdAt))),l.createElement(r7.default,{className:t.statusCell,scope:"row"},l.createElement(x.default,{variant:"body1",className:O()(t.status,yh(t,e.status))},e.status.toLowerCase())))})))}),yb=n(16839),ym=n.n(yb);function yg(e){var t=e.replace(/\w+\s*=\s*<([^>]|[\r\n])*>/g,""),n=ym().read(t),r=n.edges();return n.nodes().map(function(e){var t={id:e,parentIds:r.filter(function(t){return t.w===e}).map(function(e){return e.v})};return Object.keys(n.node(e)).length>0&&(t.attributes=n.node(e)),t})}var yv=n(94164),yy=function(e){var t=e.data,n=[];return(null==t?void 0:t.attributes)&&Object.keys(t.attributes).forEach(function(e){var r;n.push(l.createElement("div",{key:e},l.createElement(x.default,{variant:"body1",color:"textSecondary",component:"div"},l.createElement("b",null,e,":")," ",null===(r=t.attributes)||void 0===r?void 0:r[e])))}),l.createElement("div",null,t&&l.createElement(x.default,{variant:"body1",color:"textPrimary"},l.createElement("b",null,t.id)),n)},yw=n(73343),y_=n(3379),yE=n.n(y_);function yS(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nwindow.innerWidth?u-r.getBoundingClientRect().width-a:u+a,n=c+r.getBoundingClientRect().height+i>window.innerHeight?c-r.getBoundingClientRect().height-a:c+a,r.style.opacity=String(1),r.style.top="".concat(n,"px"),r.style.left="".concat(t,"px"),r.style.zIndex=String(1)}},h=function(e){var t=document.getElementById("tooltip-d3-chart-".concat(e));t&&(t.style.opacity=String(0),t.style.zIndex=String(-1))};return l.createElement("div",{style:{fontFamily:"sans-serif",fontWeight:"normal"}},l.createElement(yv.kJ,{id:"task-list-graph-d3",data:i,config:s,onMouseOverNode:d,onMouseOutNode:h},"D3 chart"),n.map(function(e){return l.createElement("div",{key:"d3-tooltip-key-".concat(e.id),id:"tooltip-d3-chart-".concat(e.id),style:{position:"absolute",opacity:"0",border:"1px solid rgba(0, 0, 0, 0.1)",padding:yw.r.spacing.unit,background:"white",borderRadius:5,zIndex:-1,inlineSize:"min-content"}},l.createElement(yy,{data:e}))}))};function yL(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nyY&&l.createElement("div",{className:t.runDetails},l.createElement(aA.Z,{href:"/jobs/".concat(n.id,"/runs"),component:tz},"View more")))),l.createElement(d.Z,{item:!0,xs:12,sm:6},l.createElement(yF,{observationSource:n.observationSource})))});function yH(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:"";try{return vx.parse(e),!0}catch(t){return!1}})}),wW=function(e){var t=e.initialValues,n=e.onSubmit,r=e.onTOMLChange;return l.createElement(hT,{initialValues:t,validationSchema:wG,onSubmit:n},function(e){var t=e.isSubmitting,n=e.values;return r&&r(n.toml),l.createElement(hR,{"data-testid":"job-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"toml",name:"toml",label:"Job Spec (TOML)",required:!0,fullWidth:!0,multiline:!0,rows:10,rowsMax:25,variant:"outlined",autoComplete:"off",FormHelperTextProps:{"data-testid":"toml-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},"Create Job"))))})},wK=n(50109),wV="persistSpec";function wq(e){var t=e.query,n=new URLSearchParams(t).get("definition");return n?(wK.t8(wV,n),{toml:n}):{toml:wK.U2(wV)||""}}var wZ=function(e){var t=e.onSubmit,n=e.onTOMLChange,r=wq({query:(0,h.TH)().search}),i=function(e){var t=e.replace(/[\u200B-\u200D\uFEFF]/g,"");wK.t8("".concat(wV),t),n&&n(t)};return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"New Job"}),l.createElement(aW.Z,null,l.createElement(wW,{initialValues:r,onSubmit:t,onTOMLChange:i})))};function wX(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=t.start,r=void 0===n?6:n,i=t.end,a=void 0===i?4:i;return e.substring(0,r)+"..."+e.substring(e.length-a)}function _M(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(_W,e)},_V=function(){var e=_K({fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error,i=e.refetch;return l.createElement(_U,{loading:n,data:t,errorMsg:null==r?void 0:r.message,refetch:i})},_q=function(e){var t=e.csaKey;return l.createElement(ir.Z,{hover:!0},l.createElement(r7.default,null,l.createElement(x.default,{variant:"body1"},t.publicKey," ",l.createElement(_x,{data:t.publicKey}))))};function _Z(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function _X(){var e=_Z(["\n fragment CSAKeysPayload_ResultsFields on CSAKey {\n id\n publicKey\n }\n"]);return _X=function(){return e},e}var _J=n0(_X()),_Q=function(e){var t,n,r,i=e.data,a=e.errorMsg,o=e.loading,s=e.onCreate;return l.createElement(r5.Z,null,l.createElement(sl.Z,{action:(null===(t=null==i?void 0:i.csaKeys.results)||void 0===t?void 0:t.length)===0&&l.createElement(ok.default,{variant:"outlined",color:"primary",onClick:s},"New CSA Key"),title:"CSA Key",subheader:"Manage your CSA Key"}),l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Public Key"))),l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(n=null==i?void 0:i.csaKeys.results)||void 0===n?void 0:n.length)===0}),l.createElement(gU,{msg:a}),null===(r=null==i?void 0:i.csaKeys.results)||void 0===r?void 0:r.map(function(e,t){return l.createElement(_q,{csaKey:e,key:t})}))))};function _1(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EM,e)};function EA(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EJ,e)},E3=function(){return oo(EQ)},E4=function(){return oo(E1)},E6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(E0,e)};function E5(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(SK,e)};function Sq(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function kV(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}var kq=function(e){var t=e.run,n=l.useMemo(function(){var e=t.inputs,n=t.outputs,r=t.taskRuns,i=kK(t,["inputs","outputs","taskRuns"]),a={};try{a=JSON.parse(e)}catch(o){a={}}return kW(kz({},i),{inputs:a,outputs:n,taskRuns:r})},[t]);return l.createElement(r5.Z,null,l.createElement(aW.Z,null,l.createElement(kH,{object:n})))};function kZ(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kX(e){for(var t=1;t0&&l.createElement(kr,{errors:t.allErrors})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(h.rs,null,l.createElement(h.AW,{path:"".concat(n,"/json")},l.createElement(kq,{run:t})),l.createElement(h.AW,{path:n},t.taskRuns.length>0&&l.createElement(kN,{taskRuns:t.taskRuns,observationSource:t.job.observationSource}))))))))};function k5(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function k8(){var e=k5(["\n ","\n query FetchJobRun($id: ID!) {\n jobRun(id: $id) {\n __typename\n ... on JobRun {\n ...JobRunPayload_Fields\n }\n ... on NotFoundError {\n message\n }\n }\n }\n"]);return k8=function(){return e},e}var k9=n0(k8(),k4),k7=function(){var e=rv(k9,{variables:{id:(0,h.UO)().id}}),t=e.data,n=e.loading,r=e.error;if(n)return l.createElement(iR,null);if(r)return l.createElement(iD,{error:r});var i=null==t?void 0:t.jobRun;switch(null==i?void 0:i.__typename){case"JobRun":return l.createElement(k6,{run:i});case"NotFoundError":return l.createElement(oa,null);default:return null}};function xe(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xt(){var e=xe(["\n fragment JobRunsPayload_ResultsFields on JobRun {\n id\n allErrors\n createdAt\n finishedAt\n status\n job {\n id\n }\n }\n"]);return xt=function(){return e},e}var xn=n0(xt()),xr=function(e){var t=e.loading,n=e.data,r=e.page,i=e.pageSize,a=(0,h.k6)(),o=l.useMemo(function(){return null==n?void 0:n.jobRuns.results.map(function(e){var t,n=e.allErrors,r=e.id,i=e.createdAt;return{id:r,createdAt:i,errors:n,finishedAt:e.finishedAt,status:e.status}})},[n]);return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(iy,null,"Job Runs")),t&&l.createElement(iR,null),n&&o&&l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(yp,{runs:o}),l.createElement(it.Z,{component:"div",count:n.jobRuns.metadata.total,rowsPerPage:i,rowsPerPageOptions:[i],page:r-1,onChangePage:function(e,t){a.push("/runs?page=".concat(t+1,"&per=").concat(i))},onChangeRowsPerPage:function(){},backIconButtonProps:{"aria-label":"prev-page"},nextIconButtonProps:{"aria-label":"next-page"}})))))};function xi(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xa(){var e=xi(["\n ","\n query FetchJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...JobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return xa=function(){return e},e}var xo=n0(xa(),xn),xs=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"25",10),r=rv(xo,{variables:{offset:(t-1)*n,limit:n},fetchPolicy:"cache-and-network"}),i=r.data,a=r.loading,o=r.error;return o?l.createElement(iD,{error:o}):l.createElement(xr,{loading:a,data:i,page:t,pageSize:n})},xu=function(){var e=(0,h.$B)().path;return l.createElement(h.rs,null,l.createElement(h.AW,{exact:!0,path:e},l.createElement(xs,null)),l.createElement(h.AW,{path:"".concat(e,"/:id")},l.createElement(k7,null)))};function xc(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xl(){var e=xc(["\n fragment FetchFeedsManagersPayload_ResultsFields on FeedsManager {\n __typename\n id\n name\n uri\n publicKey\n isConnectionActive\n createdAt\n }\n query FetchFeedsManagers {\n feedsManagers {\n results {\n ...FetchFeedsManagersPayload_ResultsFields\n }\n }\n }\n"]);return xl=function(){return e},e}var xf=n0(xl()),xd=function(e){return rv(xf,e)},xh=n(47559),xp=n(83165),xb=n(47298),xm=n(81395),xg=function(){return(0,b.createStyles)({root:{display:"flex"},connectedIcon:{color:xh.default[500]},disconnectedIcon:{color:xp.default[500]},text:{marginLeft:4}})},xv=(0,b.withStyles)(xg)(function(e){var t=e.isConnected,n=e.classes;return l.createElement("div",{className:n.root},t?l.createElement(xm.Z,{fontSize:"small",className:n.connectedIcon}):l.createElement(xb.Z,{fontSize:"small",className:n.disconnectedIcon}),l.createElement(x.default,{variant:"body1",inline:!0,className:n.text},t?"Connected":"Disconnected"))}),xy=(0,b.withStyles)(iu)(function(e){var t=e.jobDistributor,n=e.classes;return l.createElement(ir.Z,{className:n.row,hover:!0},l.createElement(r7.default,{className:n.cell,component:"th",scope:"row"},l.createElement(ih,{className:n.link,href:"/job_distributors/".concat(t.id)},t.name)),l.createElement(r7.default,null,l.createElement(xv,{isConnected:t.isConnectionActive})),l.createElement(r7.default,null,_T(t.publicKey,{start:6,end:6}),l.createElement(_x,{data:t.publicKey})),l.createElement(r7.default,null,t.uri))}),xw=function(e){var t=e.jobDistributors;return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Distributors")),l.createElement(d.Z,{item:!0,xs:3},l.createElement(d.Z,{container:!0,justify:"flex-end"},l.createElement(d.Z,{item:!0},l.createElement(aA.Z,{variant:"secondary",component:tz,href:"/job_distributors/new"},"New Job Distributor")))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Name"),l.createElement(r7.default,null,"Status"),l.createElement(r7.default,null,"CSA Public Key"),l.createElement(r7.default,null,"RPC URL"))),l.createElement(r9.Z,null,0===t.length&&l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},"Job Distributors have not been registered")),t.map(function(e){return l.createElement(xy,{key:e.id,jobDistributor:e})})))))))},x_=function(){var e,t=xd({fetchPolicy:"cache-and-network"}),n=t.data,r=t.loading,i=t.error;return r?l.createElement(iR,null):i?l.createElement(iD,{error:i}):l.createElement(xw,{jobDistributors:null!==(e=null==n?void 0:n.feedsManagers.results)&&void 0!==e?e:[]})},xE=bv().shape({name:p0().required("Required"),uri:p0().required("Required"),publicKey:p0().required("Required")}),xS=function(e){var t=e.initialValues,n=e.onSubmit;return l.createElement(hT,{initialValues:t,validationSchema:xE,onSubmit:n},function(e){var t=e.isSubmitting,n=e.submitForm;return l.createElement(hR,{"data-testid":"feeds-manager-form"},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:!1,md:6}),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"uri",name:"uri",label:"URI",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"uri-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"publicKey",name:"publicKey",label:"Public Key",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"publicKey-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(ok.default,{variant:"contained",color:"primary",disabled:t,onClick:n},"Submit"))))})},xk=function(e){var t=e.data,n=e.onSubmit,r={name:t.name,uri:t.uri,publicKey:t.publicKey};return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Job Distributor"}),l.createElement(aW.Z,null,l.createElement(xS,{initialValues:r,onSubmit:n})))))};function xx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(xZ,e)},xJ=n(57234);function xQ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function x6(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}function x5(e,t){return x1(e)||x2(e,t)||x8(e,t)||x3()}function x8(e,t){if(e){if("string"==typeof e)return xQ(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return xQ(e,t)}}var x9=function(e){return"SN_MAIN"===e||"SN_SEPOLIA"===e},x7=bv().shape({chainID:p0().required("Required"),chainType:p0().required("Required"),accountAddr:p0().required("Required"),accountAddrPubKey:p0().nullable(),adminAddr:p0().required("Required"),ocr1Multiaddr:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr1P2PPeerID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr1KeyBundleID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2Multiaddr:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr2P2PPeerID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2KeyBundleID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2CommitPluginEnabled:pV().required("Required"),ocr2ExecutePluginEnabled:pV().required("Required"),ocr2MedianPluginEnabled:pV().required("Required"),ocr2MercuryPluginEnabled:pV().required("Required"),ocr2ForwarderAddress:p0().nullable()}),Te=function(e){return(0,b.createStyles)({supportedJobOptionsPaper:{padding:2*e.spacing.unit}})},Tt=function(e){var t=e.chainAccounts,n=x4(e,["chainAccounts"]),r=h_(),i=r.values,a=i.chainID,o=i.accountAddr,s=r.setFieldValue,u=x5(l.useState(!1),2),c=u[0],f=u[1],d=l.useRef();l.useEffect(function(){d.current=a},[a]),l.useEffect(function(){a!==d.current&&(s(n.name,""),f(!1))},[a,s,n.name]);var h=function(e){var t=e.target.value;"custom"===t?(f(!0),s(n.name,"")):(f(!1),s(n.name,t))};return l.createElement(l.Fragment,null,!x9(a)&&l.createElement(hP,x0({},n,{select:!0,value:c?"custom":o,onChange:h}),t.map(function(e){return l.createElement(tE.default,{key:e.address,value:e.address},e.address)})),x9(a)&&l.createElement(hP,{component:hX,id:"accountAddr",name:"accountAddr",label:"Enter your account address",inputProps:{"data-testid":"customAccountAddr-input"},helperText:"The account address used for this chain",required:!0,fullWidth:!0}),x9(a)&&l.createElement("div",null,l.createElement(hP,{component:hX,id:"accountAddrPubKey",name:"accountAddrPubKey",label:"Account Address Public Key",required:!0,fullWidth:!0,helperText:"The public key for your account address",FormHelperTextProps:{"data-testid":"accountAddrPubKey-helper-text"}})))},Tn=(0,b.withStyles)(Te)(function(e){var t=e.classes,n=e.editing,r=void 0!==n&&n,i=e.innerRef,a=e.initialValues,o=e.onSubmit,s=e.chainIDs,u=void 0===s?[]:s,c=e.accounts,f=void 0===c?[]:c,h=e.p2pKeys,p=void 0===h?[]:h,b=e.ocrKeys,m=void 0===b?[]:b,g=e.ocr2Keys,v=void 0===g?[]:g,y=e.showSubmit,w=void 0!==y&&y;return l.createElement(hT,{innerRef:i,initialValues:a,validationSchema:x7,onSubmit:o},function(e){var n=e.values,i=f.filter(function(e){return e.chain.id==n.chainID&&!e.isDisabled});return l.createElement(hR,{"data-testid":"feeds-manager-form",id:"chain-configuration-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"chainType",name:"chainType",label:"Chain Type",select:!0,required:!0,fullWidth:!0,disabled:!0},l.createElement(tE.default,{key:"EVM",value:"EVM"},"EVM"))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"chainID",name:"chainID",label:"Chain ID",required:!0,fullWidth:!0,select:!0,disabled:r,inputProps:{"data-testid":"chainID-input"},FormHelperTextProps:{"data-testid":"chainID-helper-text"}},u.map(function(e){return l.createElement(tE.default,{key:e,value:e},e)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(Tt,{component:hX,id:"accountAddr",name:"accountAddr",label:"Account Address",inputProps:{"data-testid":"accountAddr-input"},required:!0,fullWidth:!0,select:!0,helperText:"The account address used for this chain",chainAccounts:i,FormHelperTextProps:{"data-testid":"accountAddr-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"adminAddr",name:"adminAddr",label:"Admin Address",required:!0,fullWidth:!0,helperText:"The address used for LINK payments",FormHelperTextProps:{"data-testid":"adminAddr-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Job Types")),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"fluxMonitorEnabled",type:"checkbox",Label:{label:"Flux Monitor"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1Enabled",type:"checkbox",Label:{label:"OCR"}}),n.ocr1Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),n.ocr1IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr1Multiaddr",name:"ocr1Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr1Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1P2PPeerID",name:"ocr1P2PPeerID",label:"Peer ID",select:!0,required:!0,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1P2PPeerID-helper-text"}},p.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1KeyBundleID",name:"ocr1KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1KeyBundleID-helper-text"}},m.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)})))))))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2Enabled",type:"checkbox",Label:{label:"OCR2"}}),n.ocr2Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2P2PPeerID",name:"ocr2P2PPeerID",label:"Peer ID",select:!0,required:!n.ocr2IsBootstrap,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2P2PPeerID-helper-text"}},p.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),n.ocr2IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr2Multiaddr",name:"ocr2Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR2 Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr2Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2KeyBundleID",name:"ocr2KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR2 Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2KeyBundleID-helper-text"}},v.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)}))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Plugins")),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2CommitPluginEnabled",type:"checkbox",Label:{label:"Commit"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2ExecutePluginEnabled",type:"checkbox",Label:{label:"Execute"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2RebalancerPluginEnabled",type:"checkbox",Label:{label:"Rebalancer"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MedianPluginEnabled",type:"checkbox",Label:{label:"Median"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MercuryPluginEnabled",type:"checkbox",Label:{label:"Mercury"}})),l.createElement(d.Z,{item:!0,xs:12,md:12},l.createElement(hP,{component:hX,id:"ocr2ForwarderAddress",name:"ocr2ForwarderAddress",label:"Forwarder Address (optional)",fullWidth:!0,helperText:"The forwarder address from the Operator Forwarder Contract",FormHelperTextProps:{"data-testid":"ocr2ForwarderAddress-helper-text"}}))))))),w&&l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",size:"large"},"Submit"))))})}),Tr=function(e){var t=e.onClose,n=e.open,r=e.onSubmit,i=l.useRef(),a=i$({fetchPolicy:"network-only"}).data,o=_K({fetchPolicy:"cache-and-network"}).data,s=SV({fetchPolicy:"cache-and-network"}).data,u=EO({fetchPolicy:"cache-and-network"}).data,c=E2({fetchPolicy:"cache-and-network"}).data,f={chainID:"",chainType:"EVM",accountAddr:"",adminAddr:"",accountAddrPubKey:"",fluxMonitorEnabled:!1,ocr1Enabled:!1,ocr1IsBootstrap:!1,ocr1Multiaddr:"",ocr1P2PPeerID:"",ocr1KeyBundleID:"",ocr2Enabled:!1,ocr2IsBootstrap:!1,ocr2Multiaddr:"",ocr2P2PPeerID:"",ocr2KeyBundleID:"",ocr2CommitPluginEnabled:!1,ocr2ExecutePluginEnabled:!1,ocr2MedianPluginEnabled:!1,ocr2MercuryPluginEnabled:!1,ocr2RebalancerPluginEnabled:!1,ocr2ForwarderAddress:""},d=a?a.chains.results.map(function(e){return e.id}):[],h=o?o.ethKeys.results:[],p=s?s.p2pKeys.results:[],b=u?u.ocrKeyBundles.results:[],m=c?c.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:t,open:n,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"New Supported Chain")),l.createElement(oT.Z,null,l.createElement(Tn,{innerRef:i,initialValues:f,onSubmit:r,chainIDs:d,accounts:h,p2pKeys:p,ocrKeys:b,ocr2Keys:m})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:t},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))},Ti=function(e){var t=e.cfg,n=e.onClose,r=e.open,i=e.onSubmit,a=l.useRef(),o=i$({fetchPolicy:"network-only"}).data,s=_K({fetchPolicy:"cache-and-network"}).data,u=SV({fetchPolicy:"cache-and-network"}).data,c=EO({fetchPolicy:"cache-and-network"}).data,f=E2({fetchPolicy:"cache-and-network"}).data;if(!t)return null;var d={chainID:t.chainID,chainType:"EVM",accountAddr:t.accountAddr,adminAddr:t.adminAddr,accountAddrPubKey:t.accountAddrPubKey,fluxMonitorEnabled:t.fluxMonitorJobConfig.enabled,ocr1Enabled:t.ocr1JobConfig.enabled,ocr1IsBootstrap:t.ocr1JobConfig.isBootstrap,ocr1Multiaddr:t.ocr1JobConfig.multiaddr,ocr1P2PPeerID:t.ocr1JobConfig.p2pPeerID,ocr1KeyBundleID:t.ocr1JobConfig.keyBundleID,ocr2Enabled:t.ocr2JobConfig.enabled,ocr2IsBootstrap:t.ocr2JobConfig.isBootstrap,ocr2Multiaddr:t.ocr2JobConfig.multiaddr,ocr2P2PPeerID:t.ocr2JobConfig.p2pPeerID,ocr2KeyBundleID:t.ocr2JobConfig.keyBundleID,ocr2CommitPluginEnabled:t.ocr2JobConfig.plugins.commit,ocr2ExecutePluginEnabled:t.ocr2JobConfig.plugins.execute,ocr2MedianPluginEnabled:t.ocr2JobConfig.plugins.median,ocr2MercuryPluginEnabled:t.ocr2JobConfig.plugins.mercury,ocr2RebalancerPluginEnabled:t.ocr2JobConfig.plugins.rebalancer,ocr2ForwarderAddress:t.ocr2JobConfig.forwarderAddress},h=o?o.chains.results.map(function(e){return e.id}):[],p=s?s.ethKeys.results:[],b=u?u.p2pKeys.results:[],m=c?c.ocrKeyBundles.results:[],g=f?f.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:n,open:r,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"Edit Supported Chain")),l.createElement(oT.Z,null,l.createElement(Tn,{innerRef:a,initialValues:d,onSubmit:i,chainIDs:h,accounts:p,p2pKeys:b,ocrKeys:m,ocr2Keys:g,editing:!0})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:n},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))};function Ta(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);nt.version?e:t})},[o]),g=l.useMemo(function(){return Mx(o).sort(function(e,t){return t.version-e.version})},[o]),v=function(e,t,n){switch(e){case"PENDING":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"text",color:"secondary",onClick:function(){return b("reject",t)}},"Reject"),m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status&&l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve"),m.id===t&&"DELETED"===n.status&&n.pendingUpdate&&l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("cancel",t)}},"Cancel"),l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs")));case"APPROVED":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",onClick:function(){return b("cancel",t)}},"Cancel"),"DELETED"===n.status&&n.pendingUpdate&&l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs"));case"CANCELLED":if(m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status)return l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve");return null;default:return null}};return l.createElement("div",null,g.map(function(e,n){return l.createElement(mP.Z,{defaultExpanded:0===n,key:n},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},l.createElement(x.default,{className:t.versionText},"Version ",e.version),l.createElement(Es.Z,{label:e.status,color:"APPROVED"===e.status?"primary":"default",variant:"REJECTED"===e.status||"CANCELLED"===e.status?"outlined":"default"}),l.createElement("div",{className:t.proposedAtContainer},l.createElement(x.default,null,"Proposed ",l.createElement(aO,{tooltip:!0},e.createdAt)))),l.createElement(mj.Z,{className:t.expansionPanelDetails},l.createElement("div",{className:t.actions},l.createElement("div",{className:t.editContainer},0===n&&("PENDING"===e.status||"CANCELLED"===e.status)&&"DELETED"!==s.status&&"REVOKED"!==s.status&&l.createElement(ok.default,{variant:"contained",onClick:function(){return p(!0)}},"Edit")),l.createElement("div",{className:t.actionsContainer},v(e.status,e.id,s))),l.createElement(gd,{language:"toml",style:gs,"data-testid":"codeblock"},e.definition)))}),l.createElement(oC,{open:null!=c,title:c?ML[c.action].title:"",body:c?ML[c.action].body:"",onConfirm:function(){if(c){switch(c.action){case"approve":n(c.id);break;case"cancel":r(c.id);break;case"reject":i(c.id)}f(null)}},cancelButtonText:"Cancel",onCancel:function(){return f(null)}}),l.createElement(Mb,{open:h,onClose:function(){return p(!1)},initialValues:{definition:m.definition,id:m.id},onSubmit:a}))});function MI(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function MD(){var e=MI(["\n ","\n fragment JobProposalPayloadFields on JobProposal {\n id\n externalJobID\n remoteUUID\n jobID\n specs {\n ...JobProposal_SpecsFields\n }\n status\n pendingUpdate\n }\n"]);return MD=function(){return e},e}var MN=n0(MD(),MO),MP=function(e){var t=e.onApprove,n=e.onCancel,r=e.onReject,i=e.onUpdateSpec,a=e.proposal;return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Proposal #",a.id))),l.createElement(Mc,{proposal:a}),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(TJ,null,"Specs"))),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(MC,{proposal:a,specs:a.specs,onReject:r,onApprove:t,onCancel:n,onUpdateSpec:i}))))};function MR(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);nU,tA:()=>$,KL:()=>H,Iw:()=>V,DQ:()=>W,cB:()=>T,LO:()=>M,t5:()=>k,qt:()=>x,Jc:()=>C,L7:()=>Y,EO:()=>B});var r,i,a=n(66289),o=n(41800),s=n.n(o),u=n(67932);(i=r||(r={})).IN_PROGRESS="in_progress",i.PENDING_INCOMING_CONFIRMATIONS="pending_incoming_confirmations",i.PENDING_CONNECTION="pending_connection",i.PENDING_BRIDGE="pending_bridge",i.PENDING_SLEEP="pending_sleep",i.ERRORED="errored",i.COMPLETED="completed";var c=n(87013),l=n(19084),f=n(34823);function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]j,v2:()=>F});var r=n(66289);function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var a="/sessions",o="/sessions",s=function e(t){var n=this;i(this,e),this.api=t,this.createSession=function(e){return n.create(e)},this.destroySession=function(){return n.destroy()},this.create=this.api.createResource(a),this.destroy=this.api.deleteResource(o)};function u(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var c="/v2/bulk_delete_runs",l=function e(t){var n=this;u(this,e),this.api=t,this.bulkDeleteJobRuns=function(e){return n.destroy(e)},this.destroy=this.api.deleteResource(c)};function f(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var d="/v2/chains/evm",h="".concat(d,"/:id"),p=function e(t){var n=this;f(this,e),this.api=t,this.getChains=function(){return n.index()},this.createChain=function(e){return n.create(e)},this.destroyChain=function(e){return n.destroy(void 0,{id:e})},this.updateChain=function(e,t){return n.update(t,{id:e})},this.index=this.api.fetchResource(d),this.create=this.api.createResource(d),this.destroy=this.api.deleteResource(h),this.update=this.api.updateResource(h)};function b(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var m="/v2/keys/evm/chain",g=function e(t){var n=this;b(this,e),this.api=t,this.chain=function(e){var t=new URLSearchParams;t.append("address",e.address),t.append("evmChainID",e.evmChainID),null!==e.nextNonce&&t.append("nextNonce",e.nextNonce),null!==e.abandon&&t.append("abandon",String(e.abandon)),null!==e.enabled&&t.append("enabled",String(e.enabled));var r=m+"?"+t.toString();return n.api.createResource(r)()}};function v(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var y="/v2/jobs",w="".concat(y,"/:specId/runs"),_=function e(t){var n=this;v(this,e),this.api=t,this.createJobRunV2=function(e,t){return n.post(t,{specId:e})},this.post=this.api.createResource(w,!0)};function E(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var S="/v2/log",k=function e(t){var n=this;E(this,e),this.api=t,this.getLogConfig=function(){return n.show()},this.updateLogConfig=function(e){return n.update(e)},this.show=this.api.fetchResource(S),this.update=this.api.updateResource(S)};function x(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var T="/v2/nodes",M=function e(t){var n=this;x(this,e),this.api=t,this.getNodes=function(){return n.index()},this.createNode=function(e){return n.create(e)},this.index=this.api.fetchResource(T),this.create=this.api.createResource(T)};function O(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var A="/v2/enroll_webauthn",L=function e(t){var n=this;O(this,e),this.api=t,this.beginKeyRegistration=function(e){return n.create(e)},this.finishKeyRegistration=function(e){return n.put(e)},this.create=this.api.fetchResource(A),this.put=this.api.createResource(A)};function C(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var I="/v2/build_info",D=function e(t){var n=this;C(this,e),this.api=t,this.show=function(){return n.api.GET(I)()}};function N(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var P=function e(t){N(this,e),this.api=t,this.buildInfo=new D(this.api),this.bulkDeleteRuns=new l(this.api),this.chains=new p(this.api),this.logConfig=new k(this.api),this.nodes=new M(this.api),this.jobs=new _(this.api),this.webauthn=new L(this.api),this.evmKeys=new g(this.api)},R=new r.V0({base:void 0}),j=new s(R),F=new P(R)},1398(e,t,n){"use strict";n.d(t,{Z:()=>d});var r=n(67294),i=n(32316),a=n(83638),o=n(94184),s=n.n(o);function u(){return(u=Object.assign||function(e){for(var t=1;tc});var r=n(67294),i=n(32316);function a(){return(a=Object.assign||function(e){for(var t=1;tx,jK:()=>v});var r=n(67294),i=n(37703),a=n(45697),o=n.n(a),s=n(82204),u=n(71426),c=n(94184),l=n.n(c),f=n(32316),d=function(e){var t=e.palette.success||{},n=e.palette.warning||{};return{base:{paddingLeft:5*e.spacing.unit,paddingRight:5*e.spacing.unit},success:{backgroundColor:t.main,color:t.contrastText},error:{backgroundColor:e.palette.error.dark,color:e.palette.error.contrastText},warning:{backgroundColor:n.contrastText,color:n.main}}},h=function(e){var t,n=e.success,r=e.error,i=e.warning,a=e.classes,o=e.className;return n?t=a.success:r?t=a.error:i&&(t=a.warning),l()(a.base,o,t)},p=function(e){return r.createElement(s.Z,{className:h(e),square:!0},r.createElement(u.default,{variant:"body2",color:"inherit",component:"div"},e.children))};p.defaultProps={success:!1,error:!1,warning:!1},p.propTypes={success:o().bool,error:o().bool,warning:o().bool};let b=(0,f.withStyles)(d)(p);var m=function(){return r.createElement(r.Fragment,null,"Unhandled error. Please help us by opening a"," ",r.createElement("a",{href:"https://github.com/smartcontractkit/chainlink/issues/new"},"bug report"))};let g=m;function v(e){return"string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null)}function y(e,t){var n;return n="string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null),r.createElement("p",{key:t},n)}var w=function(e){var t=e.notifications;return r.createElement(b,{error:!0},t.map(y))},_=function(e){var t=e.notifications;return r.createElement(b,{success:!0},t.map(y))},E=function(e){var t=e.errors,n=e.successes;return r.createElement("div",null,(null==t?void 0:t.length)>0&&r.createElement(w,{notifications:t}),n.length>0&&r.createElement(_,{notifications:n}))},S=function(e){return{errors:e.notifications.errors,successes:e.notifications.successes}},k=(0,i.$j)(S)(E);let x=k},9409(e,t,n){"use strict";n.d(t,{ZP:()=>j});var r=n(67294),i=n(37703),a=n(5977),o=n(32316),s=n(1398),u=n(82204),c=n(30060),l=n(71426),f=n(60520),d=n(39814),h=n(57209),p=n(26842),b=n(3950),m=n(5536),g=n(45697),v=n.n(g);let y=n.p+"9f6d832ef97e8493764e.svg";function w(){return(w=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&_.map(function(e,t){return r.createElement(d.Z,{item:!0,xs:12,key:t},r.createElement(u.Z,{raised:!1,className:v.error},r.createElement(c.Z,null,r.createElement(l.default,{variant:"body1",className:v.errorText},(0,b.jK)(e)))))}),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"email",label:"Email",margin:"normal",value:n,onChange:m("email"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"password",label:"Password",type:"password",autoComplete:"password",margin:"normal",value:h,onChange:m("password"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(d.Z,{container:!0,spacing:0,justify:"center"},r.createElement(d.Z,{item:!0},r.createElement(s.Z,{type:"submit",variant:"primary"},"Access Account")))),y&&r.createElement(l.default,{variant:"body1",color:"textSecondary"},"Signing in...")))))))},P=function(e){return{fetching:e.authentication.fetching,authenticated:e.authentication.allowed,errors:e.notifications.errors}},R=(0,i.$j)(P,x({submitSignIn:p.L7}))(N);let j=(0,h.wU)(e)((0,o.withStyles)(D)(R))},16353(e,t,n){"use strict";n.d(t,{ZP:()=>H,rH:()=>U});var r,i=n(37703),a=n(97779),o=n(9541),s=n(19084);function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.Mk.RECEIVE_SIGNOUT_SUCCESS:case s.Mk.RECEIVE_SIGNIN_SUCCESS:var n={allowed:t.authenticated};return o.Ks(n),f(c({},e,n),{errors:[]});case s.Mk.RECEIVE_SIGNIN_FAIL:var r={allowed:!1};return o.Ks(r),f(c({},e,r),{errors:[]});case s.Mk.RECEIVE_SIGNIN_ERROR:case s.Mk.RECEIVE_SIGNOUT_ERROR:var i={allowed:!1};return o.Ks(i),f(c({},e,i),{errors:t.errors||[]});default:return e}};let b=p;function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;return t.type?t.type.startsWith(r.REQUEST)?y(g({},e),{count:e.count+1}):t.type.startsWith(r.RECEIVE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type.startsWith(r.RESPONSE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type===s.di.REDIRECT?y(g({},e),{count:0}):e:e};let S=E;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function x(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:O,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.MATCH_ROUTE:return M(x({},O),{currentUrl:t.pathname});case s.Ih.NOTIFY_SUCCESS:var n={component:t.component,props:t.props};return M(x({},e),{successes:[n],errors:[]});case s.Ih.NOTIFY_SUCCESS_MSG:return M(x({},e),{successes:[t.msg],errors:[]});case s.Ih.NOTIFY_ERROR:var r=t.error.errors,i=null==r?void 0:r.map(function(e){return L(t,e)});return M(x({},e),{successes:[],errors:i});case s.Ih.NOTIFY_ERROR_MSG:return M(x({},e),{successes:[],errors:[t.msg]});case s.Mk.RECEIVE_SIGNIN_FAIL:return M(x({},e),{successes:[],errors:["Your email or password is incorrect. Please try again"]});default:return e}};function L(e,t){return{component:e.component,props:{msg:t.detail}}}let C=A;function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:R,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.REDIRECT:return P(D({},e),{to:t.to});case s.di.MATCH_ROUTE:return P(D({},e),{to:void 0});default:return e}};let F=j;var Y=n(87013),B=(0,a.UY)({authentication:b,fetching:S,notifications:C,redirect:F,buildInfo:Y.Z});B(void 0,{type:"INITIAL_STATE"});var U=i.v9;let H=B},19084(e,t,n){"use strict";var r,i,a,o,s,u,c,l,f,d;n.d(t,{Ih:()=>i,Mk:()=>a,Y0:()=>s,di:()=>r,jp:()=>o}),n(67294),(u=r||(r={})).REDIRECT="REDIRECT",u.MATCH_ROUTE="MATCH_ROUTE",(c=i||(i={})).NOTIFY_SUCCESS="NOTIFY_SUCCESS",c.NOTIFY_SUCCESS_MSG="NOTIFY_SUCCESS_MSG",c.NOTIFY_ERROR="NOTIFY_ERROR",c.NOTIFY_ERROR_MSG="NOTIFY_ERROR_MSG",(l=a||(a={})).REQUEST_SIGNIN="REQUEST_SIGNIN",l.RECEIVE_SIGNIN_SUCCESS="RECEIVE_SIGNIN_SUCCESS",l.RECEIVE_SIGNIN_FAIL="RECEIVE_SIGNIN_FAIL",l.RECEIVE_SIGNIN_ERROR="RECEIVE_SIGNIN_ERROR",l.RECEIVE_SIGNOUT_SUCCESS="RECEIVE_SIGNOUT_SUCCESS",l.RECEIVE_SIGNOUT_ERROR="RECEIVE_SIGNOUT_ERROR",(f=o||(o={})).RECEIVE_CREATE_ERROR="RECEIVE_CREATE_ERROR",f.RECEIVE_CREATE_SUCCESS="RECEIVE_CREATE_SUCCESS",f.RECEIVE_DELETE_ERROR="RECEIVE_DELETE_ERROR",f.RECEIVE_DELETE_SUCCESS="RECEIVE_DELETE_SUCCESS",f.RECEIVE_UPDATE_ERROR="RECEIVE_UPDATE_ERROR",f.RECEIVE_UPDATE_SUCCESS="RECEIVE_UPDATE_SUCCESS",f.REQUEST_CREATE="REQUEST_CREATE",f.REQUEST_DELETE="REQUEST_DELETE",f.REQUEST_UPDATE="REQUEST_UPDATE",f.UPSERT_CONFIGURATION="UPSERT_CONFIGURATION",f.UPSERT_JOB_RUN="UPSERT_JOB_RUN",f.UPSERT_JOB_RUNS="UPSERT_JOB_RUNS",f.UPSERT_TRANSACTION="UPSERT_TRANSACTION",f.UPSERT_TRANSACTIONS="UPSERT_TRANSACTIONS",f.UPSERT_BUILD_INFO="UPSERT_BUILD_INFO",(d=s||(s={})).FETCH_BUILD_INFO_REQUESTED="FETCH_BUILD_INFO_REQUESTED",d.FETCH_BUILD_INFO_SUCCEEDED="FETCH_BUILD_INFO_SUCCEEDED",d.FETCH_BUILD_INFO_FAILED="FETCH_BUILD_INFO_FAILED"},87013(e,t,n){"use strict";n.d(t,{Y:()=>o,Z:()=>u});var r=n(19084);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:o,t=arguments.length>1?arguments[1]:void 0;return t.type===r.Y0.FETCH_BUILD_INFO_SUCCEEDED?a({},t.buildInfo):e};let u=s},34823(e,t,n){"use strict";n.d(t,{N:()=>r});var r=function(e){return e.buildInfo}},73343(e,t,n){"use strict";n.d(t,{r:()=>u});var r=n(19350),i=n(32316),a=n(59114),o=n(5324),s={props:{MuiGrid:{spacing:3*o.default.unit},MuiCardHeader:{titleTypographyProps:{color:"secondary"}}},palette:{action:{hoverOpacity:.3},primary:{light:"#E5F1FF",main:"#3c40c6",contrastText:"#fff"},secondary:{main:"#3d5170"},success:{light:"#e8faf1",main:r.ek.A700,dark:r.ek[700],contrastText:r.y0.white},warning:{light:"#FFFBF1",main:"#fff6b6",contrastText:"#fad27a"},error:{light:"#ffdada",main:"#f44336",dark:"#d32f2f",contrastText:"#fff"},background:{default:"#f5f6f8",appBar:"#3c40c6"},text:{primary:(0,a.darken)(r.BA.A700,.7),secondary:"#818ea3"},listPendingStatus:{background:"#fef7e5",color:"#fecb4c"},listCompletedStatus:{background:"#e9faf2",color:"#4ed495"}},shape:{borderRadius:o.default.unit},overrides:{MuiButton:{root:{borderRadius:o.default.unit/2,textTransform:"none"},sizeLarge:{padding:void 0,fontSize:void 0,paddingTop:o.default.unit,paddingBottom:o.default.unit,paddingLeft:5*o.default.unit,paddingRight:5*o.default.unit}},MuiTableCell:{body:{fontSize:"1rem"},head:{fontSize:"1rem",fontWeight:400}},MuiCardHeader:{root:{borderBottom:"1px solid rgba(0, 0, 0, 0.12)"},action:{marginTop:-2,marginRight:0,"& >*":{marginLeft:2*o.default.unit}},subheader:{marginTop:.5*o.default.unit}}},typography:{useNextVariants:!0,fontFamily:"-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif",button:{textTransform:"none",fontSize:"1.2em"},body1:{fontSize:"1.0rem",fontWeight:400,lineHeight:"1.46429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body2:{fontSize:"1.0rem",fontWeight:500,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body1Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"1rem",lineHeight:1.5,letterSpacing:-.4},body2Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"0.875rem",lineHeight:1.5,letterSpacing:-.4},display1:{color:"#818ea3",fontSize:"2.125rem",fontWeight:400,lineHeight:"1.20588em",letterSpacing:-.4},display2:{color:"#818ea3",fontSize:"2.8125rem",fontWeight:400,lineHeight:"1.13333em",marginLeft:"-.02em",letterSpacing:-.4},display3:{color:"#818ea3",fontSize:"3.5rem",fontWeight:400,lineHeight:"1.30357em",marginLeft:"-.02em",letterSpacing:-.4},display4:{fontSize:14,fontWeightLight:300,fontWeightMedium:500,fontWeightRegular:400,letterSpacing:-.4},h1:{color:"rgb(29, 29, 29)",fontSize:"6rem",fontWeight:300,lineHeight:1},h2:{color:"rgb(29, 29, 29)",fontSize:"3.75rem",fontWeight:300,lineHeight:1},h3:{color:"rgb(29, 29, 29)",fontSize:"3rem",fontWeight:400,lineHeight:1.04},h4:{color:"rgb(29, 29, 29)",fontSize:"2.125rem",fontWeight:400,lineHeight:1.17},h5:{color:"rgb(29, 29, 29)",fontSize:"1.5rem",fontWeight:400,lineHeight:1.33,letterSpacing:-.4},h6:{fontSize:"0.8rem",fontWeight:450,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},subheading:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:"1.5em",letterSpacing:-.4},subtitle1:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:1.75,letterSpacing:-.4},subtitle2:{color:"rgb(29, 29, 29)",fontSize:"0.875rem",fontWeight:500,lineHeight:1.57,letterSpacing:-.4}},shadows:["none","0px 1px 3px 0px rgba(0, 0, 0, 0.1),0px 1px 1px 0px rgba(0, 0, 0, 0.04),0px 2px 1px -1px rgba(0, 0, 0, 0.02)","0px 1px 5px 0px rgba(0, 0, 0, 0.1),0px 2px 2px 0px rgba(0, 0, 0, 0.04),0px 3px 1px -2px rgba(0, 0, 0, 0.02)","0px 1px 8px 0px rgba(0, 0, 0, 0.1),0px 3px 4px 0px rgba(0, 0, 0, 0.04),0px 3px 3px -2px rgba(0, 0, 0, 0.02)","0px 2px 4px -1px rgba(0, 0, 0, 0.1),0px 4px 5px 0px rgba(0, 0, 0, 0.04),0px 1px 10px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 5px 8px 0px rgba(0, 0, 0, 0.04),0px 1px 14px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 6px 10px 0px rgba(0, 0, 0, 0.04),0px 1px 18px 0px rgba(0, 0, 0, 0.02)","0px 4px 5px -2px rgba(0, 0, 0, 0.1),0px 7px 10px 1px rgba(0, 0, 0, 0.04),0px 2px 16px 1px rgba(0, 0, 0, 0.02)","0px 5px 5px -3px rgba(0, 0, 0, 0.1),0px 8px 10px 1px rgba(0, 0, 0, 0.04),0px 3px 14px 2px rgba(0, 0, 0, 0.02)","0px 5px 6px -3px rgba(0, 0, 0, 0.1),0px 9px 12px 1px rgba(0, 0, 0, 0.04),0px 3px 16px 2px rgba(0, 0, 0, 0.02)","0px 6px 6px -3px rgba(0, 0, 0, 0.1),0px 10px 14px 1px rgba(0, 0, 0, 0.04),0px 4px 18px 3px rgba(0, 0, 0, 0.02)","0px 6px 7px -4px rgba(0, 0, 0, 0.1),0px 11px 15px 1px rgba(0, 0, 0, 0.04),0px 4px 20px 3px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 12px 17px 2px rgba(0, 0, 0, 0.04),0px 5px 22px 4px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 13px 19px 2px rgba(0, 0, 0, 0.04),0px 5px 24px 4px rgba(0, 0, 0, 0.02)","0px 7px 9px -4px rgba(0, 0, 0, 0.1),0px 14px 21px 2px rgba(0, 0, 0, 0.04),0px 5px 26px 4px rgba(0, 0, 0, 0.02)","0px 8px 9px -5px rgba(0, 0, 0, 0.1),0px 15px 22px 2px rgba(0, 0, 0, 0.04),0px 6px 28px 5px rgba(0, 0, 0, 0.02)","0px 8px 10px -5px rgba(0, 0, 0, 0.1),0px 16px 24px 2px rgba(0, 0, 0, 0.04),0px 6px 30px 5px rgba(0, 0, 0, 0.02)","0px 8px 11px -5px rgba(0, 0, 0, 0.1),0px 17px 26px 2px rgba(0, 0, 0, 0.04),0px 6px 32px 5px rgba(0, 0, 0, 0.02)","0px 9px 11px -5px rgba(0, 0, 0, 0.1),0px 18px 28px 2px rgba(0, 0, 0, 0.04),0px 7px 34px 6px rgba(0, 0, 0, 0.02)","0px 9px 12px -6px rgba(0, 0, 0, 0.1),0px 19px 29px 2px rgba(0, 0, 0, 0.04),0px 7px 36px 6px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 20px 31px 3px rgba(0, 0, 0, 0.04),0px 8px 38px 7px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 21px 33px 3px rgba(0, 0, 0, 0.04),0px 8px 40px 7px rgba(0, 0, 0, 0.02)","0px 10px 14px -6px rgba(0, 0, 0, 0.1),0px 22px 35px 3px rgba(0, 0, 0, 0.04),0px 8px 42px 7px rgba(0, 0, 0, 0.02)","0px 11px 14px -7px rgba(0, 0, 0, 0.1),0px 23px 36px 3px rgba(0, 0, 0, 0.04),0px 9px 44px 8px rgba(0, 0, 0, 0.02)","0px 11px 15px -7px rgba(0, 0, 0, 0.1),0px 24px 38px 3px rgba(0, 0, 0, 0.04),0px 9px 46px 8px rgba(0, 0, 0, 0.02)",]},u=(0,i.createMuiTheme)(s)},66289(e,t,n){"use strict";function r(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function a(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&f(i,n.prototype),i}).apply(null,arguments)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}function c(e){return -1!==Function.toString.call(e).indexOf("[native code]")}function l(e,t){return t&&("object"===p(t)||"function"==typeof t)?t:r(e)}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{V0:()=>B,_7:()=>v});var d,h,p=function(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};function b(e){var t="function"==typeof Map?new Map:void 0;return(b=function(e){if(null===e||!c(e))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return o(e,arguments,s(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,e)})(e)}function m(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}function g(e){var t=m();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}var v=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"AuthenticationError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e},],r}return n}(b(Error)),y=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"BadRequestError")).errors=a,r}return n}(b(Error)),w=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnprocessableEntityError")).errors=e,r}return n}(b(Error)),_=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"ServerError")).errors=e,r}return n}(b(Error)),E=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"ConflictError")).errors=a,r}return n}(b(Error)),S=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnknownResponseError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e.statusText},],r}return n}(b(Error));function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2e4;return Promise.race([fetch(e,t),new Promise(function(e,t){return setTimeout(function(){return t(Error("timeout"))},n)}),])}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=200&&e.status<300))return[3,2];return[2,e.json()];case 2:if(400!==e.status)return[3,3];return[2,e.json().then(function(e){throw new y(e)})];case 3:if(401!==e.status)return[3,4];throw new v(e);case 4:if(422!==e.status)return[3,6];return[4,$(e)];case 5:throw n=i.sent(),new w(n);case 6:if(409!==e.status)return[3,7];return[2,e.json().then(function(e){throw new E(e)})];case 7:if(!(e.status>=500))return[3,9];return[4,$(e)];case 8:throw r=i.sent(),new _(r);case 9:throw new S(e);case 10:return[2]}})})).apply(this,arguments)}function $(e){return z.apply(this,arguments)}function z(){return(z=j(function(e){return Y(this,function(t){return[2,e.json().then(function(t){return t.errors?t.errors.map(function(t){return{status:e.status,detail:t.detail}}):G(e)}).catch(function(){return G(e)})]})})).apply(this,arguments)}function G(e){return[{status:e.status,detail:e.statusText},]}},50109(e,t,n){"use strict";n.d(t,{LK:()=>o,U2:()=>i,eT:()=>s,t8:()=>a});var r=n(12795);function i(e){return r.ZP.getItem("chainlink.".concat(e))}function a(e,t){r.ZP.setItem("chainlink.".concat(e),t)}function o(e){var t=i(e),n={};if(t)try{return JSON.parse(t)}catch(r){}return n}function s(e,t){a(e,JSON.stringify(t))}},9541(e,t,n){"use strict";n.d(t,{Ks:()=>u,Tp:()=>a,iR:()=>o,pm:()=>s});var r=n(50109),i="persistURL";function a(){return r.U2(i)||""}function o(e){r.t8(i,e)}function s(){return r.LK("authentication")}function u(e){r.eT("authentication",e)}},67121(e,t,n){"use strict";function r(e){var t,n=e.Symbol;return"function"==typeof n?n.observable?t=n.observable:(t=n("observable"),n.observable=t):t="@@observable",t}n.r(t),n.d(t,{default:()=>o}),e=n.hmd(e),i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:e;var i,a=r(i);let o=a},2177(e,t,n){"use strict";n.d(t,{Z:()=>o});var r=!0,i="Invariant failed";function a(e,t){if(!e){if(r)throw Error(i);throw Error(i+": "+(t||""))}}let o=a},11742(e){e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;ru,ZT:()=>i,_T:()=>o,ev:()=>c,mG:()=>s,pi:()=>a});var r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)};function i(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(n[r[i]]=e[r[i]]);return n}function s(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,a){function o(e){try{u(r.next(e))}catch(t){a(t)}}function s(e){try{u(r.throw(e))}catch(t){a(t)}}function u(e){e.done?n(e.value):i(e.value).then(o,s)}u((r=r.apply(e,t||[])).next())})}function u(e,t){var n,r,i,a,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(e){return function(t){return u([e,t])}}function u(a){if(n)throw TypeError("Generator is already executing.");for(;o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!(i=(i=o.trys).length>0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]r})},94927(e,t,n){function r(e,t){if(i("noDeprecation"))return e;var n=!1;function r(){if(!n){if(i("throwDeprecation"))throw Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}return r}function i(e){try{if(!n.g.localStorage)return!1}catch(t){return!1}var r=n.g.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=r},42473(e){"use strict";var t=function(){};e.exports=t},84763(e){e.exports=Worker},47529(e){e.exports=n;var t=Object.prototype.hasOwnProperty;function n(){for(var e={},n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},7071(e){function t(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},94993(e,t,n){var r=n(18698).default,i=n(66115);function a(e,t){if(t&&("object"===r(t)||"function"==typeof t))return t;if(void 0!==t)throw TypeError("Derived constructors may only return object or undefined");return i(e)}e.exports=a,e.exports.__esModule=!0,e.exports.default=e.exports},6015(e){function t(n,r){return e.exports=t=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n,r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},861(e,t,n){var r=n(63405),i=n(79498),a=n(86116),o=n(42281);function s(e){return r(e)||i(e)||a(e)||o()}e.exports=s,e.exports.__esModule=!0,e.exports.default=e.exports},18698(e){function t(n){return e.exports=t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},86116(e,t,n){var r=n(73897);function i(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},1644(e,t,n){"use strict";var r,i;function a(e){return!!e&&e<7}n.d(t,{I:()=>r,O:()=>a}),(i=r||(r={}))[i.loading=1]="loading",i[i.setVariables=2]="setVariables",i[i.fetchMore=3]="fetchMore",i[i.refetch=4]="refetch",i[i.poll=6]="poll",i[i.ready=7]="ready",i[i.error=8]="error"},30990(e,t,n){"use strict";n.d(t,{MS:()=>s,YG:()=>a,cA:()=>c,ls:()=>o});var r=n(70655);n(83952);var i=n(13154),a=Symbol();function o(e){return!!e.extensions&&Array.isArray(e.extensions[a])}function s(e){return e.hasOwnProperty("graphQLErrors")}var u=function(e){var t=(0,r.ev)((0,r.ev)((0,r.ev)([],e.graphQLErrors,!0),e.clientErrors,!0),e.protocolErrors,!0);return e.networkError&&t.push(e.networkError),t.map(function(e){return(0,i.s)(e)&&e.message||"Error message not found."}).join("\n")},c=function(e){function t(n){var r=n.graphQLErrors,i=n.protocolErrors,a=n.clientErrors,o=n.networkError,s=n.errorMessage,c=n.extraInfo,l=e.call(this,s)||this;return l.name="ApolloError",l.graphQLErrors=r||[],l.protocolErrors=i||[],l.clientErrors=a||[],l.networkError=o||null,l.message=s||u(l),l.extraInfo=c,l.__proto__=t.prototype,l}return(0,r.ZT)(t,e),t}(Error)},85317(e,t,n){"use strict";n.d(t,{K:()=>a});var r=n(67294),i=n(30320).aS?Symbol.for("__APOLLO_CONTEXT__"):"__APOLLO_CONTEXT__";function a(){var e=r.createContext[i];return e||(Object.defineProperty(r.createContext,i,{value:e=r.createContext({}),enumerable:!1,writable:!1,configurable:!0}),e.displayName="ApolloContext"),e}},21436(e,t,n){"use strict";n.d(t,{O:()=>i,k:()=>r});var r=Array.isArray;function i(e){return Array.isArray(e)&&e.length>0}},30320(e,t,n){"use strict";n.d(t,{DN:()=>s,JC:()=>l,aS:()=>o,mr:()=>i,sy:()=>a});var r=n(83952),i="function"==typeof WeakMap&&"ReactNative"!==(0,r.wY)(function(){return navigator.product}),a="function"==typeof WeakSet,o="function"==typeof Symbol&&"function"==typeof Symbol.for,s=o&&Symbol.asyncIterator,u="function"==typeof(0,r.wY)(function(){return window.document.createElement}),c=(0,r.wY)(function(){return navigator.userAgent.indexOf("jsdom")>=0})||!1,l=u&&!c},53712(e,t,n){"use strict";function r(){for(var e=[],t=0;tr})},10542(e,t,n){"use strict";n.d(t,{J:()=>o}),n(83952);var r=n(13154);function i(e){var t=new Set([e]);return t.forEach(function(e){(0,r.s)(e)&&a(e)===e&&Object.getOwnPropertyNames(e).forEach(function(n){(0,r.s)(e[n])&&t.add(e[n])})}),e}function a(e){if(__DEV__&&!Object.isFrozen(e))try{Object.freeze(e)}catch(t){if(t instanceof TypeError)return null;throw t}return e}function o(e){return __DEV__&&i(e),e}},14012(e,t,n){"use strict";n.d(t,{J:()=>a});var r=n(70655),i=n(53712);function a(e,t){return(0,i.o)(e,t,t.variables&&{variables:(0,r.pi)((0,r.pi)({},e&&e.variables),t.variables)})}},13154(e,t,n){"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{s:()=>r})},83952(e,t,n){"use strict";n.d(t,{ej:()=>u,kG:()=>c,wY:()=>h});var r,i=n(70655),a="Invariant Violation",o=Object.setPrototypeOf,s=void 0===o?function(e,t){return e.__proto__=t,e}:o,u=function(e){function t(n){void 0===n&&(n=a);var r=e.call(this,"number"==typeof n?a+": "+n+" (see https://github.com/apollographql/invariant-packages)":n)||this;return r.framesToPop=1,r.name=a,s(r,t.prototype),r}return(0,i.ZT)(t,e),t}(Error);function c(e,t){if(!e)throw new u(t)}var l=["debug","log","warn","error","silent"],f=l.indexOf("log");function d(e){return function(){if(l.indexOf(e)>=f)return(console[e]||console.log).apply(console,arguments)}}function h(e){try{return e()}catch(t){}}(r=c||(c={})).debug=d("debug"),r.log=d("log"),r.warn=d("warn"),r.error=d("error");let p=h(function(){return globalThis})||h(function(){return window})||h(function(){return self})||h(function(){return global})||h(function(){return h.constructor("return this")()});var b="__",m=[b,b].join("DEV");function g(){try{return Boolean(__DEV__)}catch(e){return Object.defineProperty(p,m,{value:"production"!==h(function(){return"production"}),enumerable:!1,configurable:!0,writable:!0}),p[m]}}let v=g();function y(e){try{return e()}catch(t){}}var w=y(function(){return globalThis})||y(function(){return window})||y(function(){return self})||y(function(){return global})||y(function(){return y.constructor("return this")()}),_=!1;function E(){!w||y(function(){return"production"})||y(function(){return process})||(Object.defineProperty(w,"process",{value:{env:{NODE_ENV:"production"}},configurable:!0,enumerable:!1,writable:!0}),_=!0)}function S(){_&&(delete w.process,_=!1)}E();var k=n(10143);function x(){return k.H,S()}function T(){__DEV__?c("boolean"==typeof v,v):c("boolean"==typeof v,39)}x(),T()},4942(e,t,n){"use strict";function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}n.d(t,{Z:()=>r})},87462(e,t,n){"use strict";function r(){return(r=Object.assign?Object.assign.bind():function(e){for(var t=1;tr})},51721(e,t,n){"use strict";function r(e,t){return(r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e})(e,t)}function i(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>i})},63366(e,t,n){"use strict";function r(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}n.d(t,{Z:()=>r})},25821(e,t,n){"use strict";n.d(t,{Z:()=>s});var r=n(45695);function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=10,o=2;function s(e){return u(e,[])}function u(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":if(null===e)return"null";return c(e,t);default:return String(e)}}function c(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=d(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:u(i,n)}else if(Array.isArray(e))return f(e,n);return l(e,n)}function l(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>o?"["+h(e)+"]":"{ "+n.map(function(n){var r=u(e[n],t);return n+": "+r}).join(", ")+" }"}function f(e,t){if(0===e.length)return"[]";if(t.length>o)return"[Array]";for(var n=Math.min(a,e.length),r=e.length-n,i=[],s=0;s1&&i.push("... ".concat(r," more items")),"["+i.join(", ")+"]"}function d(e){var t=e[String(r.Z)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}function h(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}},45695(e,t,n){"use strict";n.d(t,{Z:()=>i});var r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;let i=r},25217(e,t,n){"use strict";function r(e,t){if(!Boolean(e))throw Error(null!=t?t:"Unexpected invariant triggered.")}n.d(t,{Ye:()=>o,WU:()=>s,UG:()=>u});var i=n(45695);function a(e){var t=e.prototype.toJSON;"function"==typeof t||r(0),e.prototype.inspect=t,i.Z&&(e.prototype[i.Z]=t)}var o=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();a(o);var s=function(){function e(e,t,n,r,i,a,o){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=i,this.value=o,this.prev=a,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();function u(e){return null!=e&&"string"==typeof e.kind}a(s)},87392(e,t,n){"use strict";function r(e){var t=e.split(/\r\n|[\n\r]/g),n=a(e);if(0!==n)for(var r=1;ro&&i(t[s-1]);)--s;return t.slice(o,s).join("\n")}function i(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),i=" "===e[0]||" "===e[0],a='"'===e[e.length-1],o="\\"===e[e.length-1],s=!r||a||o||n,u="";return s&&!(r&&i)&&(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}n.d(t,{LZ:()=>o,W7:()=>r})},97359(e,t,n){"use strict";n.d(t,{h:()=>r});var r=Object.freeze({NAME:"Name",DOCUMENT:"Document",OPERATION_DEFINITION:"OperationDefinition",VARIABLE_DEFINITION:"VariableDefinition",SELECTION_SET:"SelectionSet",FIELD:"Field",ARGUMENT:"Argument",FRAGMENT_SPREAD:"FragmentSpread",INLINE_FRAGMENT:"InlineFragment",FRAGMENT_DEFINITION:"FragmentDefinition",VARIABLE:"Variable",INT:"IntValue",FLOAT:"FloatValue",STRING:"StringValue",BOOLEAN:"BooleanValue",NULL:"NullValue",ENUM:"EnumValue",LIST:"ListValue",OBJECT:"ObjectValue",OBJECT_FIELD:"ObjectField",DIRECTIVE:"Directive",NAMED_TYPE:"NamedType",LIST_TYPE:"ListType",NON_NULL_TYPE:"NonNullType",SCHEMA_DEFINITION:"SchemaDefinition",OPERATION_TYPE_DEFINITION:"OperationTypeDefinition",SCALAR_TYPE_DEFINITION:"ScalarTypeDefinition",OBJECT_TYPE_DEFINITION:"ObjectTypeDefinition",FIELD_DEFINITION:"FieldDefinition",INPUT_VALUE_DEFINITION:"InputValueDefinition",INTERFACE_TYPE_DEFINITION:"InterfaceTypeDefinition",UNION_TYPE_DEFINITION:"UnionTypeDefinition",ENUM_TYPE_DEFINITION:"EnumTypeDefinition",ENUM_VALUE_DEFINITION:"EnumValueDefinition",INPUT_OBJECT_TYPE_DEFINITION:"InputObjectTypeDefinition",DIRECTIVE_DEFINITION:"DirectiveDefinition",SCHEMA_EXTENSION:"SchemaExtension",SCALAR_TYPE_EXTENSION:"ScalarTypeExtension",OBJECT_TYPE_EXTENSION:"ObjectTypeExtension",INTERFACE_TYPE_EXTENSION:"InterfaceTypeExtension",UNION_TYPE_EXTENSION:"UnionTypeExtension",ENUM_TYPE_EXTENSION:"EnumTypeExtension",INPUT_OBJECT_TYPE_EXTENSION:"InputObjectTypeExtension"})},10143(e,t,n){"use strict";n.d(t,{H:()=>c,T:()=>l});var r=n(99763),i=n(25821);function a(e,t){if(!Boolean(e))throw Error(t)}let o=function(e,t){return e instanceof t};function s(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||a(0,"Body must be a string. Received: ".concat((0,i.Z)(e),".")),this.body=e,this.name=t,this.locationOffset=n,this.locationOffset.line>0||a(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||a(0,"column in locationOffset is 1-indexed and must be positive.")}return u(e,[{key:r.YF,get:function(){return"Source"}}]),e}();function l(e){return o(e,c)}},99763(e,t,n){"use strict";n.d(t,{YF:()=>r});var r="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag"},37452(e){"use strict";e.exports=JSON.parse('{"AElig":"\xc6","AMP":"&","Aacute":"\xc1","Acirc":"\xc2","Agrave":"\xc0","Aring":"\xc5","Atilde":"\xc3","Auml":"\xc4","COPY":"\xa9","Ccedil":"\xc7","ETH":"\xd0","Eacute":"\xc9","Ecirc":"\xca","Egrave":"\xc8","Euml":"\xcb","GT":">","Iacute":"\xcd","Icirc":"\xce","Igrave":"\xcc","Iuml":"\xcf","LT":"<","Ntilde":"\xd1","Oacute":"\xd3","Ocirc":"\xd4","Ograve":"\xd2","Oslash":"\xd8","Otilde":"\xd5","Ouml":"\xd6","QUOT":"\\"","REG":"\xae","THORN":"\xde","Uacute":"\xda","Ucirc":"\xdb","Ugrave":"\xd9","Uuml":"\xdc","Yacute":"\xdd","aacute":"\xe1","acirc":"\xe2","acute":"\xb4","aelig":"\xe6","agrave":"\xe0","amp":"&","aring":"\xe5","atilde":"\xe3","auml":"\xe4","brvbar":"\xa6","ccedil":"\xe7","cedil":"\xb8","cent":"\xa2","copy":"\xa9","curren":"\xa4","deg":"\xb0","divide":"\xf7","eacute":"\xe9","ecirc":"\xea","egrave":"\xe8","eth":"\xf0","euml":"\xeb","frac12":"\xbd","frac14":"\xbc","frac34":"\xbe","gt":">","iacute":"\xed","icirc":"\xee","iexcl":"\xa1","igrave":"\xec","iquest":"\xbf","iuml":"\xef","laquo":"\xab","lt":"<","macr":"\xaf","micro":"\xb5","middot":"\xb7","nbsp":"\xa0","not":"\xac","ntilde":"\xf1","oacute":"\xf3","ocirc":"\xf4","ograve":"\xf2","ordf":"\xaa","ordm":"\xba","oslash":"\xf8","otilde":"\xf5","ouml":"\xf6","para":"\xb6","plusmn":"\xb1","pound":"\xa3","quot":"\\"","raquo":"\xbb","reg":"\xae","sect":"\xa7","shy":"\xad","sup1":"\xb9","sup2":"\xb2","sup3":"\xb3","szlig":"\xdf","thorn":"\xfe","times":"\xd7","uacute":"\xfa","ucirc":"\xfb","ugrave":"\xf9","uml":"\xa8","uuml":"\xfc","yacute":"\xfd","yen":"\xa5","yuml":"\xff"}')},93580(e){"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},67946(e){"use strict";e.exports=JSON.parse('{"locale":"en","long":{"year":{"previous":"last year","current":"this year","next":"next year","past":{"one":"{0} year ago","other":"{0} years ago"},"future":{"one":"in {0} year","other":"in {0} years"}},"quarter":{"previous":"last quarter","current":"this quarter","next":"next quarter","past":{"one":"{0} quarter ago","other":"{0} quarters ago"},"future":{"one":"in {0} quarter","other":"in {0} quarters"}},"month":{"previous":"last month","current":"this month","next":"next month","past":{"one":"{0} month ago","other":"{0} months ago"},"future":{"one":"in {0} month","other":"in {0} months"}},"week":{"previous":"last week","current":"this week","next":"next week","past":{"one":"{0} week ago","other":"{0} weeks ago"},"future":{"one":"in {0} week","other":"in {0} weeks"}},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":{"one":"{0} hour ago","other":"{0} hours ago"},"future":{"one":"in {0} hour","other":"in {0} hours"}},"minute":{"current":"this minute","past":{"one":"{0} minute ago","other":"{0} minutes ago"},"future":{"one":"in {0} minute","other":"in {0} minutes"}},"second":{"current":"now","past":{"one":"{0} second ago","other":"{0} seconds ago"},"future":{"one":"in {0} second","other":"in {0} seconds"}}},"short":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"narrow":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"now":{"now":{"current":"now","future":"in a moment","past":"just now"}},"mini":{"year":"{0}yr","month":"{0}mo","week":"{0}wk","day":"{0}d","hour":"{0}h","minute":"{0}m","second":"{0}s","now":"now"},"short-time":{"year":"{0} yr.","month":"{0} mo.","week":"{0} wk.","day":{"one":"{0} day","other":"{0} days"},"hour":"{0} hr.","minute":"{0} min.","second":"{0} sec."},"long-time":{"year":{"one":"{0} year","other":"{0} years"},"month":{"one":"{0} month","other":"{0} months"},"week":{"one":"{0} week","other":"{0} weeks"},"day":{"one":"{0} day","other":"{0} days"},"hour":{"one":"{0} hour","other":"{0} hours"},"minute":{"one":"{0} minute","other":"{0} minutes"},"second":{"one":"{0} second","other":"{0} seconds"}}}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;__webpack_require__.t=function(n,r){if(1&r&&(n=this(n)),8&r||"object"==typeof n&&n&&(4&r&&n.__esModule||16&r&&"function"==typeof n.then))return n;var i=Object.create(null);__webpack_require__.r(i);var a={};e=e||[null,t({}),t([]),t(t)];for(var o=2&r&&n;"object"==typeof o&&!~e.indexOf(o);o=t(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,__webpack_require__.d(i,a),i}})(),__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set(){throw Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__.p="/assets/",__webpack_require__.nc=void 0;var __webpack_exports__={};(()=>{"use strict";var e,t,n,r,i=__webpack_require__(32316),a=__webpack_require__(8126),o=__webpack_require__(5690),s=__webpack_require__(30381),u=__webpack_require__.n(s),c=__webpack_require__(67294),l=__webpack_require__(73935),f=__webpack_require__.n(l),d=__webpack_require__(57209),h=__webpack_require__(37703),p=__webpack_require__(97779),b=__webpack_require__(28500);function m(e){return function(t){var n=t.dispatch,r=t.getState;return function(t){return function(i){return"function"==typeof i?i(n,r,e):t(i)}}}}var g=m();g.withExtraArgument=m;let v=g;var y=__webpack_require__(76489);function w(e){return function(t){return function(n){return function(r){n(r);var i=e||document&&document.cookie||"",a=t.getState();if("MATCH_ROUTE"===r.type&&"/signin"!==a.notifications.currentUrl){var o=(0,y.Q)(i);if(o.explorer)try{var s=JSON.parse(o.explorer);if("error"===s.status){var u=_(s.url);n({type:"NOTIFY_ERROR_MSG",msg:u})}}catch(c){n({type:"NOTIFY_ERROR_MSG",msg:"Invalid explorer status"})}}}}}}function _(e){var t="Can't connect to explorer: ".concat(e);return e.match(/^wss?:.+/)?t:"".concat(t,". You must use a websocket.")}var E=__webpack_require__(16353);function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ei(e,t){if(e){if("string"==typeof e)return ea(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ea(e,t)}}function ea(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1,i=!1,a=arguments[1],o=a;return new n(function(n){return t.subscribe({next:function(t){var a=!i;if(i=!0,!a||r)try{o=e(o,t)}catch(s){return n.error(s)}else o=t},error:function(e){n.error(e)},complete:function(){if(!i&&!r)return n.error(TypeError("Cannot reduce an empty sequence"));n.next(o),n.complete()}})})},t.concat=function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r=0&&i.splice(e,1),o()}});i.push(s)},error:function(e){r.error(e)},complete:function(){o()}});function o(){a.closed&&0===i.length&&r.complete()}return function(){i.forEach(function(e){return e.unsubscribe()}),a.unsubscribe()}})},t[ed]=function(){return this},e.from=function(t){var n="function"==typeof this?this:e;if(null==t)throw TypeError(t+" is not an object");var r=ep(t,ed);if(r){var i=r.call(t);if(Object(i)!==i)throw TypeError(i+" is not an object");return em(i)&&i.constructor===n?i:new n(function(e){return i.subscribe(e)})}if(ec("iterator")&&(r=ep(t,ef)))return new n(function(e){ev(function(){if(!e.closed){for(var n,i=er(r.call(t));!(n=i()).done;){var a=n.value;if(e.next(a),e.closed)return}e.complete()}})});if(Array.isArray(t))return new n(function(e){ev(function(){if(!e.closed){for(var n=0;n0))return n.connection.key;var r=n.connection.filter?n.connection.filter:[];r.sort();var i={};return r.forEach(function(e){i[e]=t[e]}),"".concat(n.connection.key,"(").concat(eV(i),")")}var a=e;if(t){var o=eV(t);a+="(".concat(o,")")}return n&&Object.keys(n).forEach(function(e){-1===eW.indexOf(e)&&(n[e]&&Object.keys(n[e]).length?a+="@".concat(e,"(").concat(eV(n[e]),")"):a+="@".concat(e))}),a},{setStringify:function(e){var t=eV;return eV=e,t}}),eV=function(e){return JSON.stringify(e,eq)};function eq(e,t){return(0,eO.s)(t)&&!Array.isArray(t)&&(t=Object.keys(t).sort().reduce(function(e,n){return e[n]=t[n],e},{})),t}function eZ(e,t){if(e.arguments&&e.arguments.length){var n={};return e.arguments.forEach(function(e){var r;return ez(n,e.name,e.value,t)}),n}return null}function eX(e){return e.alias?e.alias.value:e.name.value}function eJ(e,t,n){for(var r,i=0,a=t.selections;it.indexOf(i))throw __DEV__?new Q.ej("illegal argument: ".concat(i)):new Q.ej(27)}return e}function tt(e,t){return t?t(e):eT.of()}function tn(e){return"function"==typeof e?new ta(e):e}function tr(e){return e.request.length<=1}var ti=function(e){function t(t,n){var r=e.call(this,t)||this;return r.link=n,r}return(0,en.ZT)(t,e),t}(Error),ta=function(){function e(e){e&&(this.request=e)}return e.empty=function(){return new e(function(){return eT.of()})},e.from=function(t){return 0===t.length?e.empty():t.map(tn).reduce(function(e,t){return e.concat(t)})},e.split=function(t,n,r){var i=tn(n),a=tn(r||new e(tt));return new e(tr(i)&&tr(a)?function(e){return t(e)?i.request(e)||eT.of():a.request(e)||eT.of()}:function(e,n){return t(e)?i.request(e,n)||eT.of():a.request(e,n)||eT.of()})},e.execute=function(e,t){return e.request(eM(t.context,e7(te(t))))||eT.of()},e.concat=function(t,n){var r=tn(t);if(tr(r))return __DEV__&&Q.kG.warn(new ti("You are calling concat on a terminating link, which will have no effect",r)),r;var i=tn(n);return new e(tr(i)?function(e){return r.request(e,function(e){return i.request(e)||eT.of()})||eT.of()}:function(e,t){return r.request(e,function(e){return i.request(e,t)||eT.of()})||eT.of()})},e.prototype.split=function(t,n,r){return this.concat(e.split(t,n,r||new e(tt)))},e.prototype.concat=function(t){return e.concat(this,t)},e.prototype.request=function(e,t){throw __DEV__?new Q.ej("request is not implemented"):new Q.ej(22)},e.prototype.onError=function(e,t){if(t&&t.error)return t.error(e),!1;throw e},e.prototype.setOnError=function(e){return this.onError=e,this},e}(),to=__webpack_require__(25821),ts=__webpack_require__(25217),tu={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},tc=Object.freeze({});function tl(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:tu,r=void 0,i=Array.isArray(e),a=[e],o=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],d=[],h=e;do{var p,b=++o===a.length,m=b&&0!==s.length;if(b){if(c=0===d.length?void 0:f[f.length-1],u=l,l=d.pop(),m){if(i)u=u.slice();else{for(var g={},v=0,y=Object.keys(u);v1)for(var r=new tB,i=1;i=0;--a){var o=i[a],s=isNaN(+o)?{}:[];s[o]=t,t=s}n=r.merge(n,t)}),n}var tW=Object.prototype.hasOwnProperty;function tK(e,t){var n,r,i,a,o;return(0,en.mG)(this,void 0,void 0,function(){var s,u,c,l,f,d,h,p,b,m,g,v,y,w,_,E,S,k,x,T,M,O,A;return(0,en.Jh)(this,function(L){switch(L.label){case 0:if(void 0===TextDecoder)throw Error("TextDecoder must be defined in the environment: please import a polyfill.");s=new TextDecoder("utf-8"),u=null===(n=e.headers)||void 0===n?void 0:n.get("content-type"),c="boundary=",l=(null==u?void 0:u.includes(c))?null==u?void 0:u.substring((null==u?void 0:u.indexOf(c))+c.length).replace(/['"]/g,"").replace(/\;(.*)/gm,"").trim():"-",f="\r\n--".concat(l),d="",h=tI(e),p=!0,L.label=1;case 1:if(!p)return[3,3];return[4,h.next()];case 2:for(m=(b=L.sent()).value,g=b.done,v="string"==typeof m?m:s.decode(m),y=d.length-f.length+1,p=!g,d+=v,w=d.indexOf(f,y);w>-1;){if(_=void 0,_=(O=[d.slice(0,w),d.slice(w+f.length),])[0],d=O[1],E=_.indexOf("\r\n\r\n"),(k=(S=tV(_.slice(0,E)))["content-type"])&&-1===k.toLowerCase().indexOf("application/json"))throw Error("Unsupported patch content type: application/json is required.");if(x=_.slice(E))try{T=tq(e,x),Object.keys(T).length>1||"data"in T||"incremental"in T||"errors"in T||"payload"in T?tz(T)?(M={},"payload"in T&&(M=(0,en.pi)({},T.payload)),"errors"in T&&(M=(0,en.pi)((0,en.pi)({},M),{extensions:(0,en.pi)((0,en.pi)({},"extensions"in M?M.extensions:null),((A={})[tN.YG]=T.errors,A))})),null===(r=t.next)||void 0===r||r.call(t,M)):null===(i=t.next)||void 0===i||i.call(t,T):1===Object.keys(T).length&&"hasNext"in T&&!T.hasNext&&(null===(a=t.complete)||void 0===a||a.call(t))}catch(C){tZ(C,t)}w=d.indexOf(f)}return[3,1];case 3:return null===(o=t.complete)||void 0===o||o.call(t),[2]}})})}function tV(e){var t={};return e.split("\n").forEach(function(e){var n=e.indexOf(":");if(n>-1){var r=e.slice(0,n).trim().toLowerCase(),i=e.slice(n+1).trim();t[r]=i}}),t}function tq(e,t){e.status>=300&&tD(e,function(){try{return JSON.parse(t)}catch(e){return t}}(),"Response not successful: Received status code ".concat(e.status));try{return JSON.parse(t)}catch(n){var r=n;throw r.name="ServerParseError",r.response=e,r.statusCode=e.status,r.bodyText=t,r}}function tZ(e,t){var n,r;"AbortError"!==e.name&&(e.result&&e.result.errors&&e.result.data&&(null===(n=t.next)||void 0===n||n.call(t,e.result)),null===(r=t.error)||void 0===r||r.call(t,e))}function tX(e,t,n){tJ(t)(e).then(function(e){var t,r;null===(t=n.next)||void 0===t||t.call(n,e),null===(r=n.complete)||void 0===r||r.call(n)}).catch(function(e){return tZ(e,n)})}function tJ(e){return function(t){return t.text().then(function(e){return tq(t,e)}).then(function(n){return t.status>=300&&tD(t,n,"Response not successful: Received status code ".concat(t.status)),Array.isArray(n)||tW.call(n,"data")||tW.call(n,"errors")||tD(t,n,"Server response was missing for query '".concat(Array.isArray(e)?e.map(function(e){return e.operationName}):e.operationName,"'.")),n})}}var tQ=function(e){if(!e&&"undefined"==typeof fetch)throw __DEV__?new Q.ej("\n\"fetch\" has not been found globally and no fetcher has been configured. To fix this, install a fetch package (like https://www.npmjs.com/package/cross-fetch), instantiate the fetcher, and pass it into your HttpLink constructor. For example:\n\nimport fetch from 'cross-fetch';\nimport { ApolloClient, HttpLink } from '@apollo/client';\nconst client = new ApolloClient({\n link: new HttpLink({ uri: '/graphql', fetch })\n});\n "):new Q.ej(23)},t1=__webpack_require__(87392);function t0(e){return tl(e,{leave:t3})}var t2=80,t3={Name:function(e){return e.value},Variable:function(e){return"$"+e.name},Document:function(e){return t6(e.definitions,"\n\n")+"\n"},OperationDefinition:function(e){var t=e.operation,n=e.name,r=t8("(",t6(e.variableDefinitions,", "),")"),i=t6(e.directives," "),a=e.selectionSet;return n||i||r||"query"!==t?t6([t,t6([n,r]),i,a]," "):a},VariableDefinition:function(e){var t=e.variable,n=e.type,r=e.defaultValue,i=e.directives;return t+": "+n+t8(" = ",r)+t8(" ",t6(i," "))},SelectionSet:function(e){return t5(e.selections)},Field:function(e){var t=e.alias,n=e.name,r=e.arguments,i=e.directives,a=e.selectionSet,o=t8("",t,": ")+n,s=o+t8("(",t6(r,", "),")");return s.length>t2&&(s=o+t8("(\n",t9(t6(r,"\n")),"\n)")),t6([s,t6(i," "),a]," ")},Argument:function(e){var t;return e.name+": "+e.value},FragmentSpread:function(e){var t;return"..."+e.name+t8(" ",t6(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,n=e.directives,r=e.selectionSet;return t6(["...",t8("on ",t),t6(n," "),r]," ")},FragmentDefinition:function(e){var t=e.name,n=e.typeCondition,r=e.variableDefinitions,i=e.directives,a=e.selectionSet;return"fragment ".concat(t).concat(t8("(",t6(r,", "),")")," ")+"on ".concat(n," ").concat(t8("",t6(i," ")," "))+a},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var n=e.value;return e.block?(0,t1.LZ)(n,"description"===t?"":" "):JSON.stringify(n)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+t6(e.values,", ")+"]"},ObjectValue:function(e){return"{"+t6(e.fields,", ")+"}"},ObjectField:function(e){var t;return e.name+": "+e.value},Directive:function(e){var t;return"@"+e.name+t8("(",t6(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:t4(function(e){var t=e.directives,n=e.operationTypes;return t6(["schema",t6(t," "),t5(n)]," ")}),OperationTypeDefinition:function(e){var t;return e.operation+": "+e.type},ScalarTypeDefinition:t4(function(e){var t;return t6(["scalar",e.name,t6(e.directives," ")]," ")}),ObjectTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),FieldDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.type,i=e.directives;return t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+": "+r+t8(" ",t6(i," "))}),InputValueDefinition:t4(function(e){var t=e.name,n=e.type,r=e.defaultValue,i=e.directives;return t6([t+": "+n,t8("= ",r),t6(i," ")]," ")}),InterfaceTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),UnionTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.types;return t6(["union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")}),EnumTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.values;return t6(["enum",t,t6(n," "),t5(r)]," ")}),EnumValueDefinition:t4(function(e){var t;return t6([e.name,t6(e.directives," ")]," ")}),InputObjectTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["input",t,t6(n," "),t5(r)]," ")}),DirectiveDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.repeatable,i=e.locations;return"directive @"+t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+(r?" repeatable":"")+" on "+t6(i," | ")}),SchemaExtension:function(e){var t=e.directives,n=e.operationTypes;return t6(["extend schema",t6(t," "),t5(n)]," ")},ScalarTypeExtension:function(e){var t;return t6(["extend scalar",e.name,t6(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},InterfaceTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},UnionTypeExtension:function(e){var t=e.name,n=e.directives,r=e.types;return t6(["extend union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,n=e.directives,r=e.values;return t6(["extend enum",t,t6(n," "),t5(r)]," ")},InputObjectTypeExtension:function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["extend input",t,t6(n," "),t5(r)]," ")}};function t4(e){return function(t){return t6([t.description,e(t)],"\n")}}function t6(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter(function(e){return e}).join(n))&&void 0!==t?t:""}function t5(e){return t8("{\n",t9(t6(e,"\n")),"\n}")}function t8(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+n:""}function t9(e){return t8(" ",e.replace(/\n/g,"\n "))}function t7(e){return -1!==e.indexOf("\n")}function ne(e){return null!=e&&e.some(t7)}var nt,nn,nr,ni={http:{includeQuery:!0,includeExtensions:!1,preserveHeaderCase:!1},headers:{accept:"*/*","content-type":"application/json"},options:{method:"POST"}},na=function(e,t){return t(e)};function no(e,t){for(var n=[],r=2;rObject.create(null),{forEach:nv,slice:ny}=Array.prototype,{hasOwnProperty:nw}=Object.prototype;class n_{constructor(e=!0,t=ng){this.weakness=e,this.makeData=t}lookup(...e){return this.lookupArray(e)}lookupArray(e){let t=this;return nv.call(e,e=>t=t.getChildTrie(e)),nw.call(t,"data")?t.data:t.data=this.makeData(ny.call(e))}peek(...e){return this.peekArray(e)}peekArray(e){let t=this;for(let n=0,r=e.length;t&&n=0;--o)t.definitions[o].kind===nL.h.OPERATION_DEFINITION&&++a;var s=nN(e),u=e.some(function(e){return e.remove}),c=function(e){return u&&e&&e.some(s)},l=new Map,f=!1,d={enter:function(e){if(c(e.directives))return f=!0,null}},h=tl(t,{Field:d,InlineFragment:d,VariableDefinition:{enter:function(){return!1}},Variable:{enter:function(e,t,n,r,a){var o=i(a);o&&o.variables.add(e.name.value)}},FragmentSpread:{enter:function(e,t,n,r,a){if(c(e.directives))return f=!0,null;var o=i(a);o&&o.fragmentSpreads.add(e.name.value)}},FragmentDefinition:{enter:function(e,t,n,r){l.set(JSON.stringify(r),e)},leave:function(e,t,n,i){return e===l.get(JSON.stringify(i))?e:a>0&&e.selectionSet.selections.every(function(e){return e.kind===nL.h.FIELD&&"__typename"===e.name.value})?(r(e.name.value).removed=!0,f=!0,null):void 0}},Directive:{leave:function(e){if(s(e))return f=!0,null}}});if(!f)return t;var p=function(e){return e.transitiveVars||(e.transitiveVars=new Set(e.variables),e.removed||e.fragmentSpreads.forEach(function(t){p(r(t)).transitiveVars.forEach(function(t){e.transitiveVars.add(t)})})),e},b=new Set;h.definitions.forEach(function(e){e.kind===nL.h.OPERATION_DEFINITION?p(n(e.name&&e.name.value)).fragmentSpreads.forEach(function(e){b.add(e)}):e.kind!==nL.h.FRAGMENT_DEFINITION||0!==a||r(e.name.value).removed||b.add(e.name.value)}),b.forEach(function(e){p(r(e)).fragmentSpreads.forEach(function(e){b.add(e)})});var m=function(e){return!!(!b.has(e)||r(e).removed)},g={enter:function(e){if(m(e.name.value))return null}};return nD(tl(h,{FragmentSpread:g,FragmentDefinition:g,OperationDefinition:{leave:function(e){if(e.variableDefinitions){var t=p(n(e.name&&e.name.value)).transitiveVars;if(t.size0},t.prototype.tearDownQuery=function(){this.isTornDown||(this.concast&&this.observer&&(this.concast.removeObserver(this.observer),delete this.concast,delete this.observer),this.stopPolling(),this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions.clear(),this.queryManager.stopQuery(this.queryId),this.observers.clear(),this.isTornDown=!0)},t}(eT);function n4(e){var t=e.options,n=t.fetchPolicy,r=t.nextFetchPolicy;return"cache-and-network"===n||"network-only"===n?e.reobserve({fetchPolicy:"cache-first",nextFetchPolicy:function(){return(this.nextFetchPolicy=r,"function"==typeof r)?r.apply(this,arguments):n}}):e.reobserve()}function n6(e){__DEV__&&Q.kG.error("Unhandled error",e.message,e.stack)}function n5(e){__DEV__&&e&&__DEV__&&Q.kG.debug("Missing cache result fields: ".concat(JSON.stringify(e)),e)}function n8(e){return"network-only"===e||"no-cache"===e||"standby"===e}nK(n3);function n9(e){return e.kind===nL.h.FIELD||e.kind===nL.h.FRAGMENT_SPREAD||e.kind===nL.h.INLINE_FRAGMENT}function n7(e){return e.kind===Kind.SCALAR_TYPE_DEFINITION||e.kind===Kind.OBJECT_TYPE_DEFINITION||e.kind===Kind.INTERFACE_TYPE_DEFINITION||e.kind===Kind.UNION_TYPE_DEFINITION||e.kind===Kind.ENUM_TYPE_DEFINITION||e.kind===Kind.INPUT_OBJECT_TYPE_DEFINITION}function re(e){return e.kind===Kind.SCALAR_TYPE_EXTENSION||e.kind===Kind.OBJECT_TYPE_EXTENSION||e.kind===Kind.INTERFACE_TYPE_EXTENSION||e.kind===Kind.UNION_TYPE_EXTENSION||e.kind===Kind.ENUM_TYPE_EXTENSION||e.kind===Kind.INPUT_OBJECT_TYPE_EXTENSION}var rt=function(){return Object.create(null)},rn=Array.prototype,rr=rn.forEach,ri=rn.slice,ra=function(){function e(e,t){void 0===e&&(e=!0),void 0===t&&(t=rt),this.weakness=e,this.makeData=t}return e.prototype.lookup=function(){for(var e=[],t=0;tclass{constructor(){this.id=["slot",rc++,Date.now(),Math.random().toString(36).slice(2),].join(":")}hasValue(){for(let e=rs;e;e=e.parent)if(this.id in e.slots){let t=e.slots[this.id];if(t===ru)break;return e!==rs&&(rs.slots[this.id]=t),!0}return rs&&(rs.slots[this.id]=ru),!1}getValue(){if(this.hasValue())return rs.slots[this.id]}withValue(e,t,n,r){let i={__proto__:null,[this.id]:e},a=rs;rs={parent:a,slots:i};try{return t.apply(r,n)}finally{rs=a}}static bind(e){let t=rs;return function(){let n=rs;try{return rs=t,e.apply(this,arguments)}finally{rs=n}}}static noContext(e,t,n){if(!rs)return e.apply(n,t);{let r=rs;try{return rs=null,e.apply(n,t)}finally{rs=r}}}};function rf(e){try{return e()}catch(t){}}let rd="@wry/context:Slot",rh=rf(()=>globalThis)||rf(()=>global)||Object.create(null),rp=rh,rb=rp[rd]||Array[rd]||function(e){try{Object.defineProperty(rp,rd,{value:e,enumerable:!1,writable:!1,configurable:!0})}finally{return e}}(rl()),{bind:rm,noContext:rg}=rb;function rv(){}var ry=function(){function e(e,t){void 0===e&&(e=1/0),void 0===t&&(t=rv),this.max=e,this.dispose=t,this.map=new Map,this.newest=null,this.oldest=null}return e.prototype.has=function(e){return this.map.has(e)},e.prototype.get=function(e){var t=this.getNode(e);return t&&t.value},e.prototype.getNode=function(e){var t=this.map.get(e);if(t&&t!==this.newest){var n=t.older,r=t.newer;r&&(r.older=n),n&&(n.newer=r),t.older=this.newest,t.older.newer=t,t.newer=null,this.newest=t,t===this.oldest&&(this.oldest=r)}return t},e.prototype.set=function(e,t){var n=this.getNode(e);return n?n.value=t:(n={key:e,value:t,newer:null,older:this.newest},this.newest&&(this.newest.newer=n),this.newest=n,this.oldest=this.oldest||n,this.map.set(e,n),n.value)},e.prototype.clean=function(){for(;this.oldest&&this.map.size>this.max;)this.delete(this.oldest.key)},e.prototype.delete=function(e){var t=this.map.get(e);return!!t&&(t===this.newest&&(this.newest=t.older),t===this.oldest&&(this.oldest=t.newer),t.newer&&(t.newer.older=t.older),t.older&&(t.older.newer=t.newer),this.map.delete(e),this.dispose(t.value,e),!0)},e}(),rw=new rb,r_=Object.prototype.hasOwnProperty,rE=void 0===(n=Array.from)?function(e){var t=[];return e.forEach(function(e){return t.push(e)}),t}:n;function rS(e){var t=e.unsubscribe;"function"==typeof t&&(e.unsubscribe=void 0,t())}var rk=[],rx=100;function rT(e,t){if(!e)throw Error(t||"assertion failure")}function rM(e,t){var n=e.length;return n>0&&n===t.length&&e[n-1]===t[n-1]}function rO(e){switch(e.length){case 0:throw Error("unknown value");case 1:return e[0];case 2:throw e[1]}}function rA(e){return e.slice(0)}var rL=function(){function e(t){this.fn=t,this.parents=new Set,this.childValues=new Map,this.dirtyChildren=null,this.dirty=!0,this.recomputing=!1,this.value=[],this.deps=null,++e.count}return e.prototype.peek=function(){if(1===this.value.length&&!rN(this))return rC(this),this.value[0]},e.prototype.recompute=function(e){return rT(!this.recomputing,"already recomputing"),rC(this),rN(this)?rI(this,e):rO(this.value)},e.prototype.setDirty=function(){this.dirty||(this.dirty=!0,this.value.length=0,rR(this),rS(this))},e.prototype.dispose=function(){var e=this;this.setDirty(),rH(this),rF(this,function(t,n){t.setDirty(),r$(t,e)})},e.prototype.forget=function(){this.dispose()},e.prototype.dependOn=function(e){e.add(this),this.deps||(this.deps=rk.pop()||new Set),this.deps.add(e)},e.prototype.forgetDeps=function(){var e=this;this.deps&&(rE(this.deps).forEach(function(t){return t.delete(e)}),this.deps.clear(),rk.push(this.deps),this.deps=null)},e.count=0,e}();function rC(e){var t=rw.getValue();if(t)return e.parents.add(t),t.childValues.has(e)||t.childValues.set(e,[]),rN(e)?rY(t,e):rB(t,e),t}function rI(e,t){return rH(e),rw.withValue(e,rD,[e,t]),rz(e,t)&&rP(e),rO(e.value)}function rD(e,t){e.recomputing=!0,e.value.length=0;try{e.value[0]=e.fn.apply(null,t)}catch(n){e.value[1]=n}e.recomputing=!1}function rN(e){return e.dirty||!!(e.dirtyChildren&&e.dirtyChildren.size)}function rP(e){e.dirty=!1,!rN(e)&&rj(e)}function rR(e){rF(e,rY)}function rj(e){rF(e,rB)}function rF(e,t){var n=e.parents.size;if(n)for(var r=rE(e.parents),i=0;i0&&e.childValues.forEach(function(t,n){r$(e,n)}),e.forgetDeps(),rT(null===e.dirtyChildren)}function r$(e,t){t.parents.delete(e),e.childValues.delete(t),rU(e,t)}function rz(e,t){if("function"==typeof e.subscribe)try{rS(e),e.unsubscribe=e.subscribe.apply(null,t)}catch(n){return e.setDirty(),!1}return!0}var rG={setDirty:!0,dispose:!0,forget:!0};function rW(e){var t=new Map,n=e&&e.subscribe;function r(e){var r=rw.getValue();if(r){var i=t.get(e);i||t.set(e,i=new Set),r.dependOn(i),"function"==typeof n&&(rS(i),i.unsubscribe=n(e))}}return r.dirty=function(e,n){var r=t.get(e);if(r){var i=n&&r_.call(rG,n)?n:"setDirty";rE(r).forEach(function(e){return e[i]()}),t.delete(e),rS(r)}},r}function rK(){var e=new ra("function"==typeof WeakMap);return function(){return e.lookupArray(arguments)}}var rV=rK(),rq=new Set;function rZ(e,t){void 0===t&&(t=Object.create(null));var n=new ry(t.max||65536,function(e){return e.dispose()}),r=t.keyArgs,i=t.makeCacheKey||rK(),a=function(){var a=i.apply(null,r?r.apply(null,arguments):arguments);if(void 0===a)return e.apply(null,arguments);var o=n.get(a);o||(n.set(a,o=new rL(e)),o.subscribe=t.subscribe,o.forget=function(){return n.delete(a)});var s=o.recompute(Array.prototype.slice.call(arguments));return n.set(a,o),rq.add(n),rw.hasValue()||(rq.forEach(function(e){return e.clean()}),rq.clear()),s};function o(e){var t=n.get(e);t&&t.setDirty()}function s(e){var t=n.get(e);if(t)return t.peek()}function u(e){return n.delete(e)}return Object.defineProperty(a,"size",{get:function(){return n.map.size},configurable:!1,enumerable:!1}),a.dirtyKey=o,a.dirty=function(){o(i.apply(null,arguments))},a.peekKey=s,a.peek=function(){return s(i.apply(null,arguments))},a.forgetKey=u,a.forget=function(){return u(i.apply(null,arguments))},a.makeCacheKey=i,a.getKey=r?function(){return i.apply(null,r.apply(null,arguments))}:i,Object.freeze(a)}var rX=new rb,rJ=new WeakMap;function rQ(e){var t=rJ.get(e);return t||rJ.set(e,t={vars:new Set,dep:rW()}),t}function r1(e){rQ(e).vars.forEach(function(t){return t.forgetCache(e)})}function r0(e){rQ(e).vars.forEach(function(t){return t.attachCache(e)})}function r2(e){var t=new Set,n=new Set,r=function(a){if(arguments.length>0){if(e!==a){e=a,t.forEach(function(e){rQ(e).dep.dirty(r),r3(e)});var o=Array.from(n);n.clear(),o.forEach(function(t){return t(e)})}}else{var s=rX.getValue();s&&(i(s),rQ(s).dep(r))}return e};r.onNextChange=function(e){return n.add(e),function(){n.delete(e)}};var i=r.attachCache=function(e){return t.add(e),rQ(e).vars.add(r),r};return r.forgetCache=function(e){return t.delete(e)},r}function r3(e){e.broadcastWatches&&e.broadcastWatches()}var r4=function(){function e(e){var t=e.cache,n=e.client,r=e.resolvers,i=e.fragmentMatcher;this.selectionsToResolveCache=new WeakMap,this.cache=t,n&&(this.client=n),r&&this.addResolvers(r),i&&this.setFragmentMatcher(i)}return e.prototype.addResolvers=function(e){var t=this;this.resolvers=this.resolvers||{},Array.isArray(e)?e.forEach(function(e){t.resolvers=tj(t.resolvers,e)}):this.resolvers=tj(this.resolvers,e)},e.prototype.setResolvers=function(e){this.resolvers={},this.addResolvers(e)},e.prototype.getResolvers=function(){return this.resolvers||{}},e.prototype.runResolvers=function(e){var t=e.document,n=e.remoteResult,r=e.context,i=e.variables,a=e.onlyRunForcedResolvers,o=void 0!==a&&a;return(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(e){return t?[2,this.resolveDocument(t,n.data,r,i,this.fragmentMatcher,o).then(function(e){return(0,en.pi)((0,en.pi)({},n),{data:e.result})})]:[2,n]})})},e.prototype.setFragmentMatcher=function(e){this.fragmentMatcher=e},e.prototype.getFragmentMatcher=function(){return this.fragmentMatcher},e.prototype.clientQuery=function(e){return tb(["client"],e)&&this.resolvers?e:null},e.prototype.serverQuery=function(e){return n$(e)},e.prototype.prepareContext=function(e){var t=this.cache;return(0,en.pi)((0,en.pi)({},e),{cache:t,getCacheKey:function(e){return t.identify(e)}})},e.prototype.addExportedVariables=function(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(r){return e?[2,this.resolveDocument(e,this.buildRootValueFromCache(e,t)||{},this.prepareContext(n),t).then(function(e){return(0,en.pi)((0,en.pi)({},t),e.exportedVariables)})]:[2,(0,en.pi)({},t)]})})},e.prototype.shouldForceResolvers=function(e){var t=!1;return tl(e,{Directive:{enter:function(e){if("client"===e.name.value&&e.arguments&&(t=e.arguments.some(function(e){return"always"===e.name.value&&"BooleanValue"===e.value.kind&&!0===e.value.value})))return tc}}}),t},e.prototype.buildRootValueFromCache=function(e,t){return this.cache.diff({query:nH(e),variables:t,returnPartialData:!0,optimistic:!1}).result},e.prototype.resolveDocument=function(e,t,n,r,i,a){return void 0===n&&(n={}),void 0===r&&(r={}),void 0===i&&(i=function(){return!0}),void 0===a&&(a=!1),(0,en.mG)(this,void 0,void 0,function(){var o,s,u,c,l,f,d,h,p,b,m;return(0,en.Jh)(this,function(g){return o=e8(e),s=e4(e),u=eL(s),c=this.collectSelectionsToResolve(o,u),f=(l=o.operation)?l.charAt(0).toUpperCase()+l.slice(1):"Query",d=this,h=d.cache,p=d.client,b={fragmentMap:u,context:(0,en.pi)((0,en.pi)({},n),{cache:h,client:p}),variables:r,fragmentMatcher:i,defaultOperationType:f,exportedVariables:{},selectionsToResolve:c,onlyRunForcedResolvers:a},m=!1,[2,this.resolveSelectionSet(o.selectionSet,m,t,b).then(function(e){return{result:e,exportedVariables:b.exportedVariables}})]})})},e.prototype.resolveSelectionSet=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c=this;return(0,en.Jh)(this,function(l){return i=r.fragmentMap,a=r.context,o=r.variables,s=[n],u=function(e){return(0,en.mG)(c,void 0,void 0,function(){var u,c;return(0,en.Jh)(this,function(l){return(t||r.selectionsToResolve.has(e))&&td(e,o)?eQ(e)?[2,this.resolveField(e,t,n,r).then(function(t){var n;void 0!==t&&s.push(((n={})[eX(e)]=t,n))})]:(e1(e)?u=e:(u=i[e.name.value],__DEV__?(0,Q.kG)(u,"No fragment named ".concat(e.name.value)):(0,Q.kG)(u,11)),u&&u.typeCondition&&(c=u.typeCondition.name.value,r.fragmentMatcher(n,c,a)))?[2,this.resolveSelectionSet(u.selectionSet,t,n,r).then(function(e){s.push(e)})]:[2]:[2]})})},[2,Promise.all(e.selections.map(u)).then(function(){return tF(s)})]})})},e.prototype.resolveField=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c,l,f,d,h=this;return(0,en.Jh)(this,function(p){return n?(i=r.variables,a=e.name.value,o=eX(e),s=a!==o,c=Promise.resolve(u=n[o]||n[a]),(!r.onlyRunForcedResolvers||this.shouldForceResolvers(e))&&(l=n.__typename||r.defaultOperationType,(f=this.resolvers&&this.resolvers[l])&&(d=f[s?a:o])&&(c=Promise.resolve(rX.withValue(this.cache,d,[n,eZ(e,i),r.context,{field:e,fragmentMap:r.fragmentMap},])))),[2,c.then(function(n){if(void 0===n&&(n=u),e.directives&&e.directives.forEach(function(e){"export"===e.name.value&&e.arguments&&e.arguments.forEach(function(e){"as"===e.name.value&&"StringValue"===e.value.kind&&(r.exportedVariables[e.value.value]=n)})}),!e.selectionSet||null==n)return n;var i,a,o=null!==(a=null===(i=e.directives)||void 0===i?void 0:i.some(function(e){return"client"===e.name.value}))&&void 0!==a&&a;return Array.isArray(n)?h.resolveSubSelectedArray(e,t||o,n,r):e.selectionSet?h.resolveSelectionSet(e.selectionSet,t||o,n,r):void 0})]):[2,null]})})},e.prototype.resolveSubSelectedArray=function(e,t,n,r){var i=this;return Promise.all(n.map(function(n){return null===n?null:Array.isArray(n)?i.resolveSubSelectedArray(e,t,n,r):e.selectionSet?i.resolveSelectionSet(e.selectionSet,t,n,r):void 0}))},e.prototype.collectSelectionsToResolve=function(e,t){var n=function(e){return!Array.isArray(e)},r=this.selectionsToResolveCache;function i(e){if(!r.has(e)){var a=new Set;r.set(e,a),tl(e,{Directive:function(e,t,r,i,o){"client"===e.name.value&&o.forEach(function(e){n(e)&&n9(e)&&a.add(e)})},FragmentSpread:function(e,r,o,s,u){var c=t[e.name.value];__DEV__?(0,Q.kG)(c,"No fragment named ".concat(e.name.value)):(0,Q.kG)(c,12);var l=i(c);l.size>0&&(u.forEach(function(e){n(e)&&n9(e)&&a.add(e)}),a.add(e),l.forEach(function(e){a.add(e)}))}})}return r.get(e)}return i(e)},e}(),r6=new(t_.mr?WeakMap:Map);function r5(e,t){var n=e[t];"function"==typeof n&&(e[t]=function(){return r6.set(e,(r6.get(e)+1)%1e15),n.apply(this,arguments)})}function r8(e){e.notifyTimeout&&(clearTimeout(e.notifyTimeout),e.notifyTimeout=void 0)}var r9=function(){function e(e,t){void 0===t&&(t=e.generateQueryId()),this.queryId=t,this.listeners=new Set,this.document=null,this.lastRequestId=1,this.subscriptions=new Set,this.stopped=!1,this.dirty=!1,this.observableQuery=null;var n=this.cache=e.cache;r6.has(n)||(r6.set(n,0),r5(n,"evict"),r5(n,"modify"),r5(n,"reset"))}return e.prototype.init=function(e){var t=e.networkStatus||nZ.I.loading;return this.variables&&this.networkStatus!==nZ.I.loading&&!(0,nm.D)(this.variables,e.variables)&&(t=nZ.I.setVariables),(0,nm.D)(e.variables,this.variables)||(this.lastDiff=void 0),Object.assign(this,{document:e.document,variables:e.variables,networkError:null,graphQLErrors:this.graphQLErrors||[],networkStatus:t}),e.observableQuery&&this.setObservableQuery(e.observableQuery),e.lastRequestId&&(this.lastRequestId=e.lastRequestId),this},e.prototype.reset=function(){r8(this),this.dirty=!1},e.prototype.getDiff=function(e){void 0===e&&(e=this.variables);var t=this.getDiffOptions(e);if(this.lastDiff&&(0,nm.D)(t,this.lastDiff.options))return this.lastDiff.diff;this.updateWatch(this.variables=e);var n=this.observableQuery;if(n&&"no-cache"===n.options.fetchPolicy)return{complete:!1};var r=this.cache.diff(t);return this.updateLastDiff(r,t),r},e.prototype.updateLastDiff=function(e,t){this.lastDiff=e?{diff:e,options:t||this.getDiffOptions()}:void 0},e.prototype.getDiffOptions=function(e){var t;return void 0===e&&(e=this.variables),{query:this.document,variables:e,returnPartialData:!0,optimistic:!0,canonizeResults:null===(t=this.observableQuery)||void 0===t?void 0:t.options.canonizeResults}},e.prototype.setDiff=function(e){var t=this,n=this.lastDiff&&this.lastDiff.diff;this.updateLastDiff(e),this.dirty||(0,nm.D)(n&&n.result,e&&e.result)||(this.dirty=!0,this.notifyTimeout||(this.notifyTimeout=setTimeout(function(){return t.notify()},0)))},e.prototype.setObservableQuery=function(e){var t=this;e!==this.observableQuery&&(this.oqListener&&this.listeners.delete(this.oqListener),this.observableQuery=e,e?(e.queryInfo=this,this.listeners.add(this.oqListener=function(){t.getDiff().fromOptimisticTransaction?e.observe():n4(e)})):delete this.oqListener)},e.prototype.notify=function(){var e=this;r8(this),this.shouldNotify()&&this.listeners.forEach(function(t){return t(e)}),this.dirty=!1},e.prototype.shouldNotify=function(){if(!this.dirty||!this.listeners.size)return!1;if((0,nZ.O)(this.networkStatus)&&this.observableQuery){var e=this.observableQuery.options.fetchPolicy;if("cache-only"!==e&&"cache-and-network"!==e)return!1}return!0},e.prototype.stop=function(){if(!this.stopped){this.stopped=!0,this.reset(),this.cancel(),this.cancel=e.prototype.cancel,this.subscriptions.forEach(function(e){return e.unsubscribe()});var t=this.observableQuery;t&&t.stopPolling()}},e.prototype.cancel=function(){},e.prototype.updateWatch=function(e){var t=this;void 0===e&&(e=this.variables);var n=this.observableQuery;if(!n||"no-cache"!==n.options.fetchPolicy){var r=(0,en.pi)((0,en.pi)({},this.getDiffOptions(e)),{watcher:this,callback:function(e){return t.setDiff(e)}});this.lastWatch&&(0,nm.D)(r,this.lastWatch)||(this.cancel(),this.cancel=this.cache.watch(this.lastWatch=r))}},e.prototype.resetLastWrite=function(){this.lastWrite=void 0},e.prototype.shouldWrite=function(e,t){var n=this.lastWrite;return!(n&&n.dmCount===r6.get(this.cache)&&(0,nm.D)(t,n.variables)&&(0,nm.D)(e.data,n.result.data))},e.prototype.markResult=function(e,t,n,r){var i=this,a=new tB,o=(0,tP.O)(e.errors)?e.errors.slice(0):[];if(this.reset(),"incremental"in e&&(0,tP.O)(e.incremental)){var s=tG(this.getDiff().result,e);e.data=s}else if("hasNext"in e&&e.hasNext){var u=this.getDiff();e.data=a.merge(u.result,e.data)}this.graphQLErrors=o,"no-cache"===n.fetchPolicy?this.updateLastDiff({result:e.data,complete:!0},this.getDiffOptions(n.variables)):0!==r&&(r7(e,n.errorPolicy)?this.cache.performTransaction(function(a){if(i.shouldWrite(e,n.variables))a.writeQuery({query:t,data:e.data,variables:n.variables,overwrite:1===r}),i.lastWrite={result:e,variables:n.variables,dmCount:r6.get(i.cache)};else if(i.lastDiff&&i.lastDiff.diff.complete){e.data=i.lastDiff.diff.result;return}var o=i.getDiffOptions(n.variables),s=a.diff(o);i.stopped||i.updateWatch(n.variables),i.updateLastDiff(s,o),s.complete&&(e.data=s.result)}):this.lastWrite=void 0)},e.prototype.markReady=function(){return this.networkError=null,this.networkStatus=nZ.I.ready},e.prototype.markError=function(e){return this.networkStatus=nZ.I.error,this.lastWrite=void 0,this.reset(),e.graphQLErrors&&(this.graphQLErrors=e.graphQLErrors),e.networkError&&(this.networkError=e.networkError),e},e}();function r7(e,t){void 0===t&&(t="none");var n="ignore"===t||"all"===t,r=!nO(e);return!r&&n&&e.data&&(r=!0),r}var ie=Object.prototype.hasOwnProperty,it=function(){function e(e){var t=e.cache,n=e.link,r=e.defaultOptions,i=e.queryDeduplication,a=void 0!==i&&i,o=e.onBroadcast,s=e.ssrMode,u=void 0!==s&&s,c=e.clientAwareness,l=void 0===c?{}:c,f=e.localState,d=e.assumeImmutableResults;this.clientAwareness={},this.queries=new Map,this.fetchCancelFns=new Map,this.transformCache=new(t_.mr?WeakMap:Map),this.queryIdCounter=1,this.requestIdCounter=1,this.mutationIdCounter=1,this.inFlightLinkObservables=new Map,this.cache=t,this.link=n,this.defaultOptions=r||Object.create(null),this.queryDeduplication=a,this.clientAwareness=l,this.localState=f||new r4({cache:t}),this.ssrMode=u,this.assumeImmutableResults=!!d,(this.onBroadcast=o)&&(this.mutationStore=Object.create(null))}return e.prototype.stop=function(){var e=this;this.queries.forEach(function(t,n){e.stopQueryNoBroadcast(n)}),this.cancelPendingFetches(__DEV__?new Q.ej("QueryManager stopped while query was in flight"):new Q.ej(14))},e.prototype.cancelPendingFetches=function(e){this.fetchCancelFns.forEach(function(t){return t(e)}),this.fetchCancelFns.clear()},e.prototype.mutate=function(e){var t,n,r=e.mutation,i=e.variables,a=e.optimisticResponse,o=e.updateQueries,s=e.refetchQueries,u=void 0===s?[]:s,c=e.awaitRefetchQueries,l=void 0!==c&&c,f=e.update,d=e.onQueryUpdated,h=e.fetchPolicy,p=void 0===h?(null===(t=this.defaultOptions.mutate)||void 0===t?void 0:t.fetchPolicy)||"network-only":h,b=e.errorPolicy,m=void 0===b?(null===(n=this.defaultOptions.mutate)||void 0===n?void 0:n.errorPolicy)||"none":b,g=e.keepRootFields,v=e.context;return(0,en.mG)(this,void 0,void 0,function(){var e,t,n,s,c,h;return(0,en.Jh)(this,function(b){switch(b.label){case 0:if(__DEV__?(0,Q.kG)(r,"mutation option is required. You must specify your GraphQL document in the mutation option."):(0,Q.kG)(r,15),__DEV__?(0,Q.kG)("network-only"===p||"no-cache"===p,"Mutations support only 'network-only' or 'no-cache' fetchPolicy strings. The default `network-only` behavior automatically writes mutation results to the cache. Passing `no-cache` skips the cache write."):(0,Q.kG)("network-only"===p||"no-cache"===p,16),e=this.generateMutationId(),n=(t=this.transform(r)).document,s=t.hasClientExports,r=this.cache.transformForLink(n),i=this.getVariables(r,i),!s)return[3,2];return[4,this.localState.addExportedVariables(r,i,v)];case 1:i=b.sent(),b.label=2;case 2:return c=this.mutationStore&&(this.mutationStore[e]={mutation:r,variables:i,loading:!0,error:null}),a&&this.markMutationOptimistic(a,{mutationId:e,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,updateQueries:o,update:f,keepRootFields:g}),this.broadcastQueries(),h=this,[2,new Promise(function(t,n){return nM(h.getObservableFromLink(r,(0,en.pi)((0,en.pi)({},v),{optimisticResponse:a}),i,!1),function(t){if(nO(t)&&"none"===m)throw new tN.cA({graphQLErrors:nA(t)});c&&(c.loading=!1,c.error=null);var n=(0,en.pi)({},t);return"function"==typeof u&&(u=u(n)),"ignore"===m&&nO(n)&&delete n.errors,h.markMutationResult({mutationId:e,result:n,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,update:f,updateQueries:o,awaitRefetchQueries:l,refetchQueries:u,removeOptimistic:a?e:void 0,onQueryUpdated:d,keepRootFields:g})}).subscribe({next:function(e){h.broadcastQueries(),"hasNext"in e&&!1!==e.hasNext||t(e)},error:function(t){c&&(c.loading=!1,c.error=t),a&&h.cache.removeOptimistic(e),h.broadcastQueries(),n(t instanceof tN.cA?t:new tN.cA({networkError:t}))}})})]}})})},e.prototype.markMutationResult=function(e,t){var n=this;void 0===t&&(t=this.cache);var r=e.result,i=[],a="no-cache"===e.fetchPolicy;if(!a&&r7(r,e.errorPolicy)){if(tU(r)||i.push({result:r.data,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}),tU(r)&&(0,tP.O)(r.incremental)){var o=t.diff({id:"ROOT_MUTATION",query:this.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0}),s=void 0;o.result&&(s=tG(o.result,r)),void 0!==s&&(r.data=s,i.push({result:s,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}))}var u=e.updateQueries;u&&this.queries.forEach(function(e,a){var o=e.observableQuery,s=o&&o.queryName;if(s&&ie.call(u,s)){var c,l=u[s],f=n.queries.get(a),d=f.document,h=f.variables,p=t.diff({query:d,variables:h,returnPartialData:!0,optimistic:!1}),b=p.result;if(p.complete&&b){var m=l(b,{mutationResult:r,queryName:d&&e3(d)||void 0,queryVariables:h});m&&i.push({result:m,dataId:"ROOT_QUERY",query:d,variables:h})}}})}if(i.length>0||e.refetchQueries||e.update||e.onQueryUpdated||e.removeOptimistic){var c=[];if(this.refetchQueries({updateCache:function(t){a||i.forEach(function(e){return t.write(e)});var o=e.update,s=!t$(r)||tU(r)&&!r.hasNext;if(o){if(!a){var u=t.diff({id:"ROOT_MUTATION",query:n.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0});u.complete&&("incremental"in(r=(0,en.pi)((0,en.pi)({},r),{data:u.result}))&&delete r.incremental,"hasNext"in r&&delete r.hasNext)}s&&o(t,r,{context:e.context,variables:e.variables})}a||e.keepRootFields||!s||t.modify({id:"ROOT_MUTATION",fields:function(e,t){var n=t.fieldName,r=t.DELETE;return"__typename"===n?e:r}})},include:e.refetchQueries,optimistic:!1,removeOptimistic:e.removeOptimistic,onQueryUpdated:e.onQueryUpdated||null}).forEach(function(e){return c.push(e)}),e.awaitRefetchQueries||e.onQueryUpdated)return Promise.all(c).then(function(){return r})}return Promise.resolve(r)},e.prototype.markMutationOptimistic=function(e,t){var n=this,r="function"==typeof e?e(t.variables):e;return this.cache.recordOptimisticTransaction(function(e){try{n.markMutationResult((0,en.pi)((0,en.pi)({},t),{result:{data:r}}),e)}catch(i){__DEV__&&Q.kG.error(i)}},t.mutationId)},e.prototype.fetchQuery=function(e,t,n){return this.fetchQueryObservable(e,t,n).promise},e.prototype.getQueryStore=function(){var e=Object.create(null);return this.queries.forEach(function(t,n){e[n]={variables:t.variables,networkStatus:t.networkStatus,networkError:t.networkError,graphQLErrors:t.graphQLErrors}}),e},e.prototype.resetErrors=function(e){var t=this.queries.get(e);t&&(t.networkError=void 0,t.graphQLErrors=[])},e.prototype.transform=function(e){var t=this.transformCache;if(!t.has(e)){var n=this.cache.transformDocument(e),r=nY(n),i=this.localState.clientQuery(n),a=r&&this.localState.serverQuery(r),o={document:n,hasClientExports:tm(n),hasForcedResolvers:this.localState.shouldForceResolvers(n),clientQuery:i,serverQuery:a,defaultVars:e9(e2(n)),asQuery:(0,en.pi)((0,en.pi)({},n),{definitions:n.definitions.map(function(e){return"OperationDefinition"===e.kind&&"query"!==e.operation?(0,en.pi)((0,en.pi)({},e),{operation:"query"}):e})})},s=function(e){e&&!t.has(e)&&t.set(e,o)};s(e),s(n),s(i),s(a)}return t.get(e)},e.prototype.getVariables=function(e,t){return(0,en.pi)((0,en.pi)({},this.transform(e).defaultVars),t)},e.prototype.watchQuery=function(e){void 0===(e=(0,en.pi)((0,en.pi)({},e),{variables:this.getVariables(e.query,e.variables)})).notifyOnNetworkStatusChange&&(e.notifyOnNetworkStatusChange=!1);var t=new r9(this),n=new n3({queryManager:this,queryInfo:t,options:e});return this.queries.set(n.queryId,t),t.init({document:n.query,observableQuery:n,variables:n.variables}),n},e.prototype.query=function(e,t){var n=this;return void 0===t&&(t=this.generateQueryId()),__DEV__?(0,Q.kG)(e.query,"query option is required. You must specify your GraphQL document in the query option."):(0,Q.kG)(e.query,17),__DEV__?(0,Q.kG)("Document"===e.query.kind,'You must wrap the query string in a "gql" tag.'):(0,Q.kG)("Document"===e.query.kind,18),__DEV__?(0,Q.kG)(!e.returnPartialData,"returnPartialData option only supported on watchQuery."):(0,Q.kG)(!e.returnPartialData,19),__DEV__?(0,Q.kG)(!e.pollInterval,"pollInterval option only supported on watchQuery."):(0,Q.kG)(!e.pollInterval,20),this.fetchQuery(t,e).finally(function(){return n.stopQuery(t)})},e.prototype.generateQueryId=function(){return String(this.queryIdCounter++)},e.prototype.generateRequestId=function(){return this.requestIdCounter++},e.prototype.generateMutationId=function(){return String(this.mutationIdCounter++)},e.prototype.stopQueryInStore=function(e){this.stopQueryInStoreNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryInStoreNoBroadcast=function(e){var t=this.queries.get(e);t&&t.stop()},e.prototype.clearStore=function(e){return void 0===e&&(e={discardWatches:!0}),this.cancelPendingFetches(__DEV__?new Q.ej("Store reset while query was in flight (not completed in link chain)"):new Q.ej(21)),this.queries.forEach(function(e){e.observableQuery?e.networkStatus=nZ.I.loading:e.stop()}),this.mutationStore&&(this.mutationStore=Object.create(null)),this.cache.reset(e)},e.prototype.getObservableQueries=function(e){var t=this;void 0===e&&(e="active");var n=new Map,r=new Map,i=new Set;return Array.isArray(e)&&e.forEach(function(e){"string"==typeof e?r.set(e,!1):eN(e)?r.set(t.transform(e).document,!1):(0,eO.s)(e)&&e.query&&i.add(e)}),this.queries.forEach(function(t,i){var a=t.observableQuery,o=t.document;if(a){if("all"===e){n.set(i,a);return}var s=a.queryName;if("standby"===a.options.fetchPolicy||"active"===e&&!a.hasObservers())return;("active"===e||s&&r.has(s)||o&&r.has(o))&&(n.set(i,a),s&&r.set(s,!0),o&&r.set(o,!0))}}),i.size&&i.forEach(function(e){var r=nG("legacyOneTimeQuery"),i=t.getQuery(r).init({document:e.query,variables:e.variables}),a=new n3({queryManager:t,queryInfo:i,options:(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"network-only"})});(0,Q.kG)(a.queryId===r),i.setObservableQuery(a),n.set(r,a)}),__DEV__&&r.size&&r.forEach(function(e,t){!e&&__DEV__&&Q.kG.warn("Unknown query ".concat("string"==typeof t?"named ":"").concat(JSON.stringify(t,null,2)," requested in refetchQueries options.include array"))}),n},e.prototype.reFetchObservableQueries=function(e){var t=this;void 0===e&&(e=!1);var n=[];return this.getObservableQueries(e?"all":"active").forEach(function(r,i){var a=r.options.fetchPolicy;r.resetLastResults(),(e||"standby"!==a&&"cache-only"!==a)&&n.push(r.refetch()),t.getQuery(i).setDiff(null)}),this.broadcastQueries(),Promise.all(n)},e.prototype.setObservableQuery=function(e){this.getQuery(e.queryId).setObservableQuery(e)},e.prototype.startGraphQLSubscription=function(e){var t=this,n=e.query,r=e.fetchPolicy,i=e.errorPolicy,a=e.variables,o=e.context,s=void 0===o?{}:o;n=this.transform(n).document,a=this.getVariables(n,a);var u=function(e){return t.getObservableFromLink(n,s,e).map(function(a){"no-cache"!==r&&(r7(a,i)&&t.cache.write({query:n,result:a.data,dataId:"ROOT_SUBSCRIPTION",variables:e}),t.broadcastQueries());var o=nO(a),s=(0,tN.ls)(a);if(o||s){var u={};throw o&&(u.graphQLErrors=a.errors),s&&(u.protocolErrors=a.extensions[tN.YG]),new tN.cA(u)}return a})};if(this.transform(n).hasClientExports){var c=this.localState.addExportedVariables(n,a,s).then(u);return new eT(function(e){var t=null;return c.then(function(n){return t=n.subscribe(e)},e.error),function(){return t&&t.unsubscribe()}})}return u(a)},e.prototype.stopQuery=function(e){this.stopQueryNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryNoBroadcast=function(e){this.stopQueryInStoreNoBroadcast(e),this.removeQuery(e)},e.prototype.removeQuery=function(e){this.fetchCancelFns.delete(e),this.queries.has(e)&&(this.getQuery(e).stop(),this.queries.delete(e))},e.prototype.broadcastQueries=function(){this.onBroadcast&&this.onBroadcast(),this.queries.forEach(function(e){return e.notify()})},e.prototype.getLocalState=function(){return this.localState},e.prototype.getObservableFromLink=function(e,t,n,r){var i,a,o=this;void 0===r&&(r=null!==(i=null==t?void 0:t.queryDeduplication)&&void 0!==i?i:this.queryDeduplication);var s=this.transform(e).serverQuery;if(s){var u=this,c=u.inFlightLinkObservables,l=u.link,f={query:s,variables:n,operationName:e3(s)||void 0,context:this.prepareContext((0,en.pi)((0,en.pi)({},t),{forceFetch:!r}))};if(t=f.context,r){var d=c.get(s)||new Map;c.set(s,d);var h=nx(n);if(!(a=d.get(h))){var p=new nq([np(l,f)]);d.set(h,a=p),p.beforeNext(function(){d.delete(h)&&d.size<1&&c.delete(s)})}}else a=new nq([np(l,f)])}else a=new nq([eT.of({data:{}})]),t=this.prepareContext(t);var b=this.transform(e).clientQuery;return b&&(a=nM(a,function(e){return o.localState.runResolvers({document:b,remoteResult:e,context:t,variables:n})})),a},e.prototype.getResultsFromLink=function(e,t,n){var r=e.lastRequestId=this.generateRequestId(),i=this.cache.transformForLink(this.transform(e.document).document);return nM(this.getObservableFromLink(i,n.context,n.variables),function(a){var o=nA(a),s=o.length>0;if(r>=e.lastRequestId){if(s&&"none"===n.errorPolicy)throw e.markError(new tN.cA({graphQLErrors:o}));e.markResult(a,i,n,t),e.markReady()}var u={data:a.data,loading:!1,networkStatus:nZ.I.ready};return s&&"ignore"!==n.errorPolicy&&(u.errors=o,u.networkStatus=nZ.I.error),u},function(t){var n=(0,tN.MS)(t)?t:new tN.cA({networkError:t});throw r>=e.lastRequestId&&e.markError(n),n})},e.prototype.fetchQueryObservable=function(e,t,n){return this.fetchConcastWithInfo(e,t,n).concast},e.prototype.fetchConcastWithInfo=function(e,t,n){var r,i,a=this;void 0===n&&(n=nZ.I.loading);var o=this.transform(t.query).document,s=this.getVariables(o,t.variables),u=this.getQuery(e),c=this.defaultOptions.watchQuery,l=t.fetchPolicy,f=void 0===l?c&&c.fetchPolicy||"cache-first":l,d=t.errorPolicy,h=void 0===d?c&&c.errorPolicy||"none":d,p=t.returnPartialData,b=void 0!==p&&p,m=t.notifyOnNetworkStatusChange,g=void 0!==m&&m,v=t.context,y=void 0===v?{}:v,w=Object.assign({},t,{query:o,variables:s,fetchPolicy:f,errorPolicy:h,returnPartialData:b,notifyOnNetworkStatusChange:g,context:y}),_=function(e){w.variables=e;var r=a.fetchQueryByPolicy(u,w,n);return"standby"!==w.fetchPolicy&&r.sources.length>0&&u.observableQuery&&u.observableQuery.applyNextFetchPolicy("after-fetch",t),r},E=function(){return a.fetchCancelFns.delete(e)};if(this.fetchCancelFns.set(e,function(e){E(),setTimeout(function(){return r.cancel(e)})}),this.transform(w.query).hasClientExports)r=new nq(this.localState.addExportedVariables(w.query,w.variables,w.context).then(_).then(function(e){return e.sources})),i=!0;else{var S=_(w.variables);i=S.fromLink,r=new nq(S.sources)}return r.promise.then(E,E),{concast:r,fromLink:i}},e.prototype.refetchQueries=function(e){var t=this,n=e.updateCache,r=e.include,i=e.optimistic,a=void 0!==i&&i,o=e.removeOptimistic,s=void 0===o?a?nG("refetchQueries"):void 0:o,u=e.onQueryUpdated,c=new Map;r&&this.getObservableQueries(r).forEach(function(e,n){c.set(n,{oq:e,lastDiff:t.getQuery(n).getDiff()})});var l=new Map;return n&&this.cache.batch({update:n,optimistic:a&&s||!1,removeOptimistic:s,onWatchUpdated:function(e,t,n){var r=e.watcher instanceof r9&&e.watcher.observableQuery;if(r){if(u){c.delete(r.queryId);var i=u(r,t,n);return!0===i&&(i=r.refetch()),!1!==i&&l.set(r,i),i}null!==u&&c.set(r.queryId,{oq:r,lastDiff:n,diff:t})}}}),c.size&&c.forEach(function(e,n){var r,i=e.oq,a=e.lastDiff,o=e.diff;if(u){if(!o){var s=i.queryInfo;s.reset(),o=s.getDiff()}r=u(i,o,a)}u&&!0!==r||(r=i.refetch()),!1!==r&&l.set(i,r),n.indexOf("legacyOneTimeQuery")>=0&&t.stopQueryNoBroadcast(n)}),s&&this.cache.removeOptimistic(s),l},e.prototype.fetchQueryByPolicy=function(e,t,n){var r=this,i=t.query,a=t.variables,o=t.fetchPolicy,s=t.refetchWritePolicy,u=t.errorPolicy,c=t.returnPartialData,l=t.context,f=t.notifyOnNetworkStatusChange,d=e.networkStatus;e.init({document:this.transform(i).document,variables:a,networkStatus:n});var h=function(){return e.getDiff(a)},p=function(t,n){void 0===n&&(n=e.networkStatus||nZ.I.loading);var o=t.result;!__DEV__||c||(0,nm.D)(o,{})||n5(t.missing);var s=function(e){return eT.of((0,en.pi)({data:e,loading:(0,nZ.O)(n),networkStatus:n},t.complete?null:{partial:!0}))};return o&&r.transform(i).hasForcedResolvers?r.localState.runResolvers({document:i,remoteResult:{data:o},context:l,variables:a,onlyRunForcedResolvers:!0}).then(function(e){return s(e.data||void 0)}):"none"===u&&n===nZ.I.refetch&&Array.isArray(t.missing)?s(void 0):s(o)},b="no-cache"===o?0:n===nZ.I.refetch&&"merge"!==s?1:2,m=function(){return r.getResultsFromLink(e,b,{variables:a,context:l,fetchPolicy:o,errorPolicy:u})},g=f&&"number"==typeof d&&d!==n&&(0,nZ.O)(n);switch(o){default:case"cache-first":var v=h();if(v.complete)return{fromLink:!1,sources:[p(v,e.markReady())]};if(c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-and-network":var v=h();if(v.complete||c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-only":return{fromLink:!1,sources:[p(h(),e.markReady())]};case"network-only":if(g)return{fromLink:!0,sources:[p(h()),m()]};return{fromLink:!0,sources:[m()]};case"no-cache":if(g)return{fromLink:!0,sources:[p(e.getDiff()),m(),]};return{fromLink:!0,sources:[m()]};case"standby":return{fromLink:!1,sources:[]}}},e.prototype.getQuery=function(e){return e&&!this.queries.has(e)&&this.queries.set(e,new r9(this,e)),this.queries.get(e)},e.prototype.prepareContext=function(e){void 0===e&&(e={});var t=this.localState.prepareContext(e);return(0,en.pi)((0,en.pi)({},t),{clientAwareness:this.clientAwareness})},e}(),ir=__webpack_require__(14012),ii=!1,ia=function(){function e(e){var t=this;this.resetStoreCallbacks=[],this.clearStoreCallbacks=[];var n=e.uri,r=e.credentials,i=e.headers,a=e.cache,o=e.ssrMode,s=void 0!==o&&o,u=e.ssrForceFetchDelay,c=void 0===u?0:u,l=e.connectToDevTools,f=void 0===l?"object"==typeof window&&!window.__APOLLO_CLIENT__&&__DEV__:l,d=e.queryDeduplication,h=void 0===d||d,p=e.defaultOptions,b=e.assumeImmutableResults,m=void 0!==b&&b,g=e.resolvers,v=e.typeDefs,y=e.fragmentMatcher,w=e.name,_=e.version,E=e.link;if(E||(E=n?new nh({uri:n,credentials:r,headers:i}):ta.empty()),!a)throw __DEV__?new Q.ej("To initialize Apollo Client, you must specify a 'cache' property in the options object. \nFor more information, please visit: https://go.apollo.dev/c/docs"):new Q.ej(9);if(this.link=E,this.cache=a,this.disableNetworkFetches=s||c>0,this.queryDeduplication=h,this.defaultOptions=p||Object.create(null),this.typeDefs=v,c&&setTimeout(function(){return t.disableNetworkFetches=!1},c),this.watchQuery=this.watchQuery.bind(this),this.query=this.query.bind(this),this.mutate=this.mutate.bind(this),this.resetStore=this.resetStore.bind(this),this.reFetchObservableQueries=this.reFetchObservableQueries.bind(this),f&&"object"==typeof window&&(window.__APOLLO_CLIENT__=this),!ii&&f&&__DEV__&&(ii=!0,"undefined"!=typeof window&&window.document&&window.top===window.self&&!window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__)){var S=window.navigator,k=S&&S.userAgent,x=void 0;"string"==typeof k&&(k.indexOf("Chrome/")>-1?x="https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm":k.indexOf("Firefox/")>-1&&(x="https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/")),x&&__DEV__&&Q.kG.log("Download the Apollo DevTools for a better development experience: "+x)}this.version=nb,this.localState=new r4({cache:a,client:this,resolvers:g,fragmentMatcher:y}),this.queryManager=new it({cache:this.cache,link:this.link,defaultOptions:this.defaultOptions,queryDeduplication:h,ssrMode:s,clientAwareness:{name:w,version:_},localState:this.localState,assumeImmutableResults:m,onBroadcast:f?function(){t.devToolsHookCb&&t.devToolsHookCb({action:{},state:{queries:t.queryManager.getQueryStore(),mutations:t.queryManager.mutationStore||{}},dataWithOptimisticResults:t.cache.extract(!0)})}:void 0})}return e.prototype.stop=function(){this.queryManager.stop()},e.prototype.watchQuery=function(e){return this.defaultOptions.watchQuery&&(e=(0,ir.J)(this.defaultOptions.watchQuery,e)),this.disableNetworkFetches&&("network-only"===e.fetchPolicy||"cache-and-network"===e.fetchPolicy)&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.watchQuery(e)},e.prototype.query=function(e){return this.defaultOptions.query&&(e=(0,ir.J)(this.defaultOptions.query,e)),__DEV__?(0,Q.kG)("cache-and-network"!==e.fetchPolicy,"The cache-and-network fetchPolicy does not work with client.query, because client.query can only return a single result. Please use client.watchQuery to receive multiple results from the cache and the network, or consider using a different fetchPolicy, such as cache-first or network-only."):(0,Q.kG)("cache-and-network"!==e.fetchPolicy,10),this.disableNetworkFetches&&"network-only"===e.fetchPolicy&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.query(e)},e.prototype.mutate=function(e){return this.defaultOptions.mutate&&(e=(0,ir.J)(this.defaultOptions.mutate,e)),this.queryManager.mutate(e)},e.prototype.subscribe=function(e){return this.queryManager.startGraphQLSubscription(e)},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!1),this.cache.readQuery(e,t)},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!1),this.cache.readFragment(e,t)},e.prototype.writeQuery=function(e){var t=this.cache.writeQuery(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.writeFragment=function(e){var t=this.cache.writeFragment(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.__actionHookForDevTools=function(e){this.devToolsHookCb=e},e.prototype.__requestRaw=function(e){return np(this.link,e)},e.prototype.resetStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!1})}).then(function(){return Promise.all(e.resetStoreCallbacks.map(function(e){return e()}))}).then(function(){return e.reFetchObservableQueries()})},e.prototype.clearStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!0})}).then(function(){return Promise.all(e.clearStoreCallbacks.map(function(e){return e()}))})},e.prototype.onResetStore=function(e){var t=this;return this.resetStoreCallbacks.push(e),function(){t.resetStoreCallbacks=t.resetStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.onClearStore=function(e){var t=this;return this.clearStoreCallbacks.push(e),function(){t.clearStoreCallbacks=t.clearStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.reFetchObservableQueries=function(e){return this.queryManager.reFetchObservableQueries(e)},e.prototype.refetchQueries=function(e){var t=this.queryManager.refetchQueries(e),n=[],r=[];t.forEach(function(e,t){n.push(t),r.push(e)});var i=Promise.all(r);return i.queries=n,i.results=r,i.catch(function(e){__DEV__&&Q.kG.debug("In client.refetchQueries, Promise.all promise rejected with error ".concat(e))}),i},e.prototype.getObservableQueries=function(e){return void 0===e&&(e="active"),this.queryManager.getObservableQueries(e)},e.prototype.extract=function(e){return this.cache.extract(e)},e.prototype.restore=function(e){return this.cache.restore(e)},e.prototype.addResolvers=function(e){this.localState.addResolvers(e)},e.prototype.setResolvers=function(e){this.localState.setResolvers(e)},e.prototype.getResolvers=function(){return this.localState.getResolvers()},e.prototype.setLocalStateFragmentMatcher=function(e){this.localState.setFragmentMatcher(e)},e.prototype.setLink=function(e){this.link=this.queryManager.link=e},e}(),io=function(){function e(){this.getFragmentDoc=rZ(eA)}return e.prototype.batch=function(e){var t,n=this,r="string"==typeof e.optimistic?e.optimistic:!1===e.optimistic?null:void 0;return this.performTransaction(function(){return t=e.update(n)},r),t},e.prototype.recordOptimisticTransaction=function(e,t){this.performTransaction(e,t)},e.prototype.transformDocument=function(e){return e},e.prototype.transformForLink=function(e){return e},e.prototype.identify=function(e){},e.prototype.gc=function(){return[]},e.prototype.modify=function(e){return!1},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{rootId:e.id||"ROOT_QUERY",optimistic:t}))},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{query:this.getFragmentDoc(e.fragment,e.fragmentName),rootId:e.id,optimistic:t}))},e.prototype.writeQuery=function(e){var t=e.id,n=e.data,r=(0,en._T)(e,["id","data"]);return this.write(Object.assign(r,{dataId:t||"ROOT_QUERY",result:n}))},e.prototype.writeFragment=function(e){var t=e.id,n=e.data,r=e.fragment,i=e.fragmentName,a=(0,en._T)(e,["id","data","fragment","fragmentName"]);return this.write(Object.assign(a,{query:this.getFragmentDoc(r,i),dataId:t,result:n}))},e.prototype.updateQuery=function(e,t){return this.batch({update:function(n){var r=n.readQuery(e),i=t(r);return null==i?r:(n.writeQuery((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e.prototype.updateFragment=function(e,t){return this.batch({update:function(n){var r=n.readFragment(e),i=t(r);return null==i?r:(n.writeFragment((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e}(),is=function(e){function t(n,r,i,a){var o,s=e.call(this,n)||this;if(s.message=n,s.path=r,s.query=i,s.variables=a,Array.isArray(s.path)){s.missing=s.message;for(var u=s.path.length-1;u>=0;--u)s.missing=((o={})[s.path[u]]=s.missing,o)}else s.missing=s.path;return s.__proto__=t.prototype,s}return(0,en.ZT)(t,e),t}(Error),iu=__webpack_require__(10542),ic=Object.prototype.hasOwnProperty;function il(e){return null==e}function id(e,t){var n=e.__typename,r=e.id,i=e._id;if("string"==typeof n&&(t&&(t.keyObject=il(r)?il(i)?void 0:{_id:i}:{id:r}),il(r)&&!il(i)&&(r=i),!il(r)))return"".concat(n,":").concat("number"==typeof r||"string"==typeof r?r:JSON.stringify(r))}var ih={dataIdFromObject:id,addTypename:!0,resultCaching:!0,canonizeResults:!1};function ip(e){return(0,n1.o)(ih,e)}function ib(e){var t=e.canonizeResults;return void 0===t?ih.canonizeResults:t}function im(e,t){return eD(t)?e.get(t.__ref,"__typename"):t&&t.__typename}var ig=/^[_a-z][_0-9a-z]*/i;function iv(e){var t=e.match(ig);return t?t[0]:e}function iy(e,t,n){return!!(0,eO.s)(t)&&((0,tP.k)(t)?t.every(function(t){return iy(e,t,n)}):e.selections.every(function(e){if(eQ(e)&&td(e,n)){var r=eX(e);return ic.call(t,r)&&(!e.selectionSet||iy(e.selectionSet,t[r],n))}return!0}))}function iw(e){return(0,eO.s)(e)&&!eD(e)&&!(0,tP.k)(e)}function i_(){return new tB}function iE(e,t){var n=eL(e4(e));return{fragmentMap:n,lookupFragment:function(e){var r=n[e];return!r&&t&&(r=t.lookup(e)),r||null}}}var iS=Object.create(null),ik=function(){return iS},ix=Object.create(null),iT=function(){function e(e,t){var n=this;this.policies=e,this.group=t,this.data=Object.create(null),this.rootIds=Object.create(null),this.refs=Object.create(null),this.getFieldValue=function(e,t){return(0,iu.J)(eD(e)?n.get(e.__ref,t):e&&e[t])},this.canRead=function(e){return eD(e)?n.has(e.__ref):"object"==typeof e},this.toReference=function(e,t){if("string"==typeof e)return eI(e);if(eD(e))return e;var r=n.policies.identify(e)[0];if(r){var i=eI(r);return t&&n.merge(r,e),i}}}return e.prototype.toObject=function(){return(0,en.pi)({},this.data)},e.prototype.has=function(e){return void 0!==this.lookup(e,!0)},e.prototype.get=function(e,t){if(this.group.depend(e,t),ic.call(this.data,e)){var n=this.data[e];if(n&&ic.call(n,t))return n[t]}return"__typename"===t&&ic.call(this.policies.rootTypenamesById,e)?this.policies.rootTypenamesById[e]:this instanceof iL?this.parent.get(e,t):void 0},e.prototype.lookup=function(e,t){return(t&&this.group.depend(e,"__exists"),ic.call(this.data,e))?this.data[e]:this instanceof iL?this.parent.lookup(e,t):this.policies.rootTypenamesById[e]?Object.create(null):void 0},e.prototype.merge=function(e,t){var n,r=this;eD(e)&&(e=e.__ref),eD(t)&&(t=t.__ref);var i="string"==typeof e?this.lookup(n=e):e,a="string"==typeof t?this.lookup(n=t):t;if(a){__DEV__?(0,Q.kG)("string"==typeof n,"store.merge expects a string ID"):(0,Q.kG)("string"==typeof n,1);var o=new tB(iI).merge(i,a);if(this.data[n]=o,o!==i&&(delete this.refs[n],this.group.caching)){var s=Object.create(null);i||(s.__exists=1),Object.keys(a).forEach(function(e){if(!i||i[e]!==o[e]){s[e]=1;var t=iv(e);t===e||r.policies.hasKeyArgs(o.__typename,t)||(s[t]=1),void 0!==o[e]||r instanceof iL||delete o[e]}}),s.__typename&&!(i&&i.__typename)&&this.policies.rootTypenamesById[n]===o.__typename&&delete s.__typename,Object.keys(s).forEach(function(e){return r.group.dirty(n,e)})}}},e.prototype.modify=function(e,t){var n=this,r=this.lookup(e);if(r){var i=Object.create(null),a=!1,o=!0,s={DELETE:iS,INVALIDATE:ix,isReference:eD,toReference:this.toReference,canRead:this.canRead,readField:function(t,r){return n.policies.readField("string"==typeof t?{fieldName:t,from:r||eI(e)}:t,{store:n})}};if(Object.keys(r).forEach(function(u){var c=iv(u),l=r[u];if(void 0!==l){var f="function"==typeof t?t:t[u]||t[c];if(f){var d=f===ik?iS:f((0,iu.J)(l),(0,en.pi)((0,en.pi)({},s),{fieldName:c,storeFieldName:u,storage:n.getStorage(e,u)}));d===ix?n.group.dirty(e,u):(d===iS&&(d=void 0),d!==l&&(i[u]=d,a=!0,l=d))}void 0!==l&&(o=!1)}}),a)return this.merge(e,i),o&&(this instanceof iL?this.data[e]=void 0:delete this.data[e],this.group.dirty(e,"__exists")),!0}return!1},e.prototype.delete=function(e,t,n){var r,i=this.lookup(e);if(i){var a=this.getFieldValue(i,"__typename"),o=t&&n?this.policies.getStoreFieldName({typename:a,fieldName:t,args:n}):t;return this.modify(e,o?((r={})[o]=ik,r):ik)}return!1},e.prototype.evict=function(e,t){var n=!1;return e.id&&(ic.call(this.data,e.id)&&(n=this.delete(e.id,e.fieldName,e.args)),this instanceof iL&&this!==t&&(n=this.parent.evict(e,t)||n),(e.fieldName||n)&&this.group.dirty(e.id,e.fieldName||"__exists")),n},e.prototype.clear=function(){this.replace(null)},e.prototype.extract=function(){var e=this,t=this.toObject(),n=[];return this.getRootIdSet().forEach(function(t){ic.call(e.policies.rootTypenamesById,t)||n.push(t)}),n.length&&(t.__META={extraRootIds:n.sort()}),t},e.prototype.replace=function(e){var t=this;if(Object.keys(this.data).forEach(function(n){e&&ic.call(e,n)||t.delete(n)}),e){var n=e.__META,r=(0,en._T)(e,["__META"]);Object.keys(r).forEach(function(e){t.merge(e,r[e])}),n&&n.extraRootIds.forEach(this.retain,this)}},e.prototype.retain=function(e){return this.rootIds[e]=(this.rootIds[e]||0)+1},e.prototype.release=function(e){if(this.rootIds[e]>0){var t=--this.rootIds[e];return t||delete this.rootIds[e],t}return 0},e.prototype.getRootIdSet=function(e){return void 0===e&&(e=new Set),Object.keys(this.rootIds).forEach(e.add,e),this instanceof iL?this.parent.getRootIdSet(e):Object.keys(this.policies.rootTypenamesById).forEach(e.add,e),e},e.prototype.gc=function(){var e=this,t=this.getRootIdSet(),n=this.toObject();t.forEach(function(r){ic.call(n,r)&&(Object.keys(e.findChildRefIds(r)).forEach(t.add,t),delete n[r])});var r=Object.keys(n);if(r.length){for(var i=this;i instanceof iL;)i=i.parent;r.forEach(function(e){return i.delete(e)})}return r},e.prototype.findChildRefIds=function(e){if(!ic.call(this.refs,e)){var t=this.refs[e]=Object.create(null),n=this.data[e];if(!n)return t;var r=new Set([n]);r.forEach(function(e){eD(e)&&(t[e.__ref]=!0),(0,eO.s)(e)&&Object.keys(e).forEach(function(t){var n=e[t];(0,eO.s)(n)&&r.add(n)})})}return this.refs[e]},e.prototype.makeCacheKey=function(){return this.group.keyMaker.lookupArray(arguments)},e}(),iM=function(){function e(e,t){void 0===t&&(t=null),this.caching=e,this.parent=t,this.d=null,this.resetCaching()}return e.prototype.resetCaching=function(){this.d=this.caching?rW():null,this.keyMaker=new n_(t_.mr)},e.prototype.depend=function(e,t){if(this.d){this.d(iO(e,t));var n=iv(t);n!==t&&this.d(iO(e,n)),this.parent&&this.parent.depend(e,t)}},e.prototype.dirty=function(e,t){this.d&&this.d.dirty(iO(e,t),"__exists"===t?"forget":"setDirty")},e}();function iO(e,t){return t+"#"+e}function iA(e,t){iD(e)&&e.group.depend(t,"__exists")}!function(e){var t=function(e){function t(t){var n=t.policies,r=t.resultCaching,i=void 0===r||r,a=t.seed,o=e.call(this,n,new iM(i))||this;return o.stump=new iC(o),o.storageTrie=new n_(t_.mr),a&&o.replace(a),o}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,t){return this.stump.addLayer(e,t)},t.prototype.removeLayer=function(){return this},t.prototype.getStorage=function(){return this.storageTrie.lookupArray(arguments)},t}(e);e.Root=t}(iT||(iT={}));var iL=function(e){function t(t,n,r,i){var a=e.call(this,n.policies,i)||this;return a.id=t,a.parent=n,a.replay=r,a.group=i,r(a),a}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,n){return new t(e,this,n,this.group)},t.prototype.removeLayer=function(e){var t=this,n=this.parent.removeLayer(e);return e===this.id?(this.group.caching&&Object.keys(this.data).forEach(function(e){var r=t.data[e],i=n.lookup(e);i?r?r!==i&&Object.keys(r).forEach(function(n){(0,nm.D)(r[n],i[n])||t.group.dirty(e,n)}):(t.group.dirty(e,"__exists"),Object.keys(i).forEach(function(n){t.group.dirty(e,n)})):t.delete(e)}),n):n===this.parent?this:n.addLayer(this.id,this.replay)},t.prototype.toObject=function(){return(0,en.pi)((0,en.pi)({},this.parent.toObject()),this.data)},t.prototype.findChildRefIds=function(t){var n=this.parent.findChildRefIds(t);return ic.call(this.data,t)?(0,en.pi)((0,en.pi)({},n),e.prototype.findChildRefIds.call(this,t)):n},t.prototype.getStorage=function(){for(var e=this.parent;e.parent;)e=e.parent;return e.getStorage.apply(e,arguments)},t}(iT),iC=function(e){function t(t){return e.call(this,"EntityStore.Stump",t,function(){},new iM(t.group.caching,t.group))||this}return(0,en.ZT)(t,e),t.prototype.removeLayer=function(){return this},t.prototype.merge=function(){return this.parent.merge.apply(this.parent,arguments)},t}(iL);function iI(e,t,n){var r=e[n],i=t[n];return(0,nm.D)(r,i)?r:i}function iD(e){return!!(e instanceof iT&&e.group.caching)}function iN(e){return[e.selectionSet,e.objectOrReference,e.context,e.context.canonizeResults,]}var iP=function(){function e(e){var t=this;this.knownResults=new(t_.mr?WeakMap:Map),this.config=(0,n1.o)(e,{addTypename:!1!==e.addTypename,canonizeResults:ib(e)}),this.canon=e.canon||new nk,this.executeSelectionSet=rZ(function(e){var n,r=e.context.canonizeResults,i=iN(e);i[3]=!r;var a=(n=t.executeSelectionSet).peek.apply(n,i);return a?r?(0,en.pi)((0,en.pi)({},a),{result:t.canon.admit(a.result)}):a:(iA(e.context.store,e.enclosingRef.__ref),t.execSelectionSetImpl(e))},{max:this.config.resultCacheMaxSize,keyArgs:iN,makeCacheKey:function(e,t,n,r){if(iD(n.store))return n.store.makeCacheKey(e,eD(t)?t.__ref:t,n.varString,r)}}),this.executeSubSelectedArray=rZ(function(e){return iA(e.context.store,e.enclosingRef.__ref),t.execSubSelectedArrayImpl(e)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var t=e.field,n=e.array,r=e.context;if(iD(r.store))return r.store.makeCacheKey(t,n,r.varString)}})}return e.prototype.resetCanon=function(){this.canon=new nk},e.prototype.diffQueryAgainstStore=function(e){var t,n=e.store,r=e.query,i=e.rootId,a=void 0===i?"ROOT_QUERY":i,o=e.variables,s=e.returnPartialData,u=void 0===s||s,c=e.canonizeResults,l=void 0===c?this.config.canonizeResults:c,f=this.config.cache.policies;o=(0,en.pi)((0,en.pi)({},e9(e6(r))),o);var d=eI(a),h=this.executeSelectionSet({selectionSet:e8(r).selectionSet,objectOrReference:d,enclosingRef:d,context:(0,en.pi)({store:n,query:r,policies:f,variables:o,varString:nx(o),canonizeResults:l},iE(r,this.config.fragments))});if(h.missing&&(t=[new is(iR(h.missing),h.missing,r,o)],!u))throw t[0];return{result:h.result,complete:!t,missing:t}},e.prototype.isFresh=function(e,t,n,r){if(iD(r.store)&&this.knownResults.get(e)===n){var i=this.executeSelectionSet.peek(n,t,r,this.canon.isKnown(e));if(i&&e===i.result)return!0}return!1},e.prototype.execSelectionSetImpl=function(e){var t,n=this,r=e.selectionSet,i=e.objectOrReference,a=e.enclosingRef,o=e.context;if(eD(i)&&!o.policies.rootTypenamesById[i.__ref]&&!o.store.has(i.__ref))return{result:this.canon.empty,missing:"Dangling reference to missing ".concat(i.__ref," object")};var s=o.variables,u=o.policies,c=o.store.getFieldValue(i,"__typename"),l=[],f=new tB;function d(e,n){var r;return e.missing&&(t=f.merge(t,((r={})[n]=e.missing,r))),e.result}this.config.addTypename&&"string"==typeof c&&!u.rootIdsByTypename[c]&&l.push({__typename:c});var h=new Set(r.selections);h.forEach(function(e){var r,p;if(td(e,s)){if(eQ(e)){var b=u.readField({fieldName:e.name.value,field:e,variables:o.variables,from:i},o),m=eX(e);void 0===b?nj.added(e)||(t=f.merge(t,((r={})[m]="Can't find field '".concat(e.name.value,"' on ").concat(eD(i)?i.__ref+" object":"object "+JSON.stringify(i,null,2)),r))):(0,tP.k)(b)?b=d(n.executeSubSelectedArray({field:e,array:b,enclosingRef:a,context:o}),m):e.selectionSet?null!=b&&(b=d(n.executeSelectionSet({selectionSet:e.selectionSet,objectOrReference:b,enclosingRef:eD(b)?b:a,context:o}),m)):o.canonizeResults&&(b=n.canon.pass(b)),void 0!==b&&l.push(((p={})[m]=b,p))}else{var g=eC(e,o.lookupFragment);if(!g&&e.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(e.name.value)):new Q.ej(5);g&&u.fragmentMatches(g,c)&&g.selectionSet.selections.forEach(h.add,h)}}});var p={result:tF(l),missing:t},b=o.canonizeResults?this.canon.admit(p):(0,iu.J)(p);return b.result&&this.knownResults.set(b.result,r),b},e.prototype.execSubSelectedArrayImpl=function(e){var t,n=this,r=e.field,i=e.array,a=e.enclosingRef,o=e.context,s=new tB;function u(e,n){var r;return e.missing&&(t=s.merge(t,((r={})[n]=e.missing,r))),e.result}return r.selectionSet&&(i=i.filter(o.store.canRead)),i=i.map(function(e,t){return null===e?null:(0,tP.k)(e)?u(n.executeSubSelectedArray({field:r,array:e,enclosingRef:a,context:o}),t):r.selectionSet?u(n.executeSelectionSet({selectionSet:r.selectionSet,objectOrReference:e,enclosingRef:eD(e)?e:a,context:o}),t):(__DEV__&&ij(o.store,r,e),e)}),{result:o.canonizeResults?this.canon.admit(i):i,missing:t}},e}();function iR(e){try{JSON.stringify(e,function(e,t){if("string"==typeof t)throw t;return t})}catch(t){return t}}function ij(e,t,n){if(!t.selectionSet){var r=new Set([n]);r.forEach(function(n){(0,eO.s)(n)&&(__DEV__?(0,Q.kG)(!eD(n),"Missing selection set for object of type ".concat(im(e,n)," returned for query field ").concat(t.name.value)):(0,Q.kG)(!eD(n),6),Object.values(n).forEach(r.add,r))})}}function iF(e){var t=nG("stringifyForDisplay");return JSON.stringify(e,function(e,n){return void 0===n?t:n}).split(JSON.stringify(t)).join("")}var iY=Object.create(null);function iB(e){var t=JSON.stringify(e);return iY[t]||(iY[t]=Object.create(null))}function iU(e){var t=iB(e);return t.keyFieldsFn||(t.keyFieldsFn=function(t,n){var r=function(e,t){return n.readField(t,e)},i=n.keyObject=i$(e,function(e){var i=iW(n.storeObject,e,r);return void 0===i&&t!==n.storeObject&&ic.call(t,e[0])&&(i=iW(t,e,iG)),__DEV__?(0,Q.kG)(void 0!==i,"Missing field '".concat(e.join("."),"' while extracting keyFields from ").concat(JSON.stringify(t))):(0,Q.kG)(void 0!==i,2),i});return"".concat(n.typename,":").concat(JSON.stringify(i))})}function iH(e){var t=iB(e);return t.keyArgsFn||(t.keyArgsFn=function(t,n){var r=n.field,i=n.variables,a=n.fieldName,o=JSON.stringify(i$(e,function(e){var n=e[0],a=n.charAt(0);if("@"===a){if(r&&(0,tP.O)(r.directives)){var o=n.slice(1),s=r.directives.find(function(e){return e.name.value===o}),u=s&&eZ(s,i);return u&&iW(u,e.slice(1))}return}if("$"===a){var c=n.slice(1);if(i&&ic.call(i,c)){var l=e.slice(0);return l[0]=c,iW(i,l)}return}if(t)return iW(t,e)}));return(t||"{}"!==o)&&(a+=":"+o),a})}function i$(e,t){var n=new tB;return iz(e).reduce(function(e,r){var i,a=t(r);if(void 0!==a){for(var o=r.length-1;o>=0;--o)a=((i={})[r[o]]=a,i);e=n.merge(e,a)}return e},Object.create(null))}function iz(e){var t=iB(e);if(!t.paths){var n=t.paths=[],r=[];e.forEach(function(t,i){(0,tP.k)(t)?(iz(t).forEach(function(e){return n.push(r.concat(e))}),r.length=0):(r.push(t),(0,tP.k)(e[i+1])||(n.push(r.slice(0)),r.length=0))})}return t.paths}function iG(e,t){return e[t]}function iW(e,t,n){return n=n||iG,iK(t.reduce(function e(t,r){return(0,tP.k)(t)?t.map(function(t){return e(t,r)}):t&&n(t,r)},e))}function iK(e){return(0,eO.s)(e)?(0,tP.k)(e)?e.map(iK):i$(Object.keys(e).sort(),function(t){return iW(e,t)}):e}function iV(e){return void 0!==e.args?e.args:e.field?eZ(e.field,e.variables):null}eK.setStringify(nx);var iq=function(){},iZ=function(e,t){return t.fieldName},iX=function(e,t,n){return(0,n.mergeObjects)(e,t)},iJ=function(e,t){return t},iQ=function(){function e(e){this.config=e,this.typePolicies=Object.create(null),this.toBeAdded=Object.create(null),this.supertypeMap=new Map,this.fuzzySubtypes=new Map,this.rootIdsByTypename=Object.create(null),this.rootTypenamesById=Object.create(null),this.usingPossibleTypes=!1,this.config=(0,en.pi)({dataIdFromObject:id},e),this.cache=this.config.cache,this.setRootTypename("Query"),this.setRootTypename("Mutation"),this.setRootTypename("Subscription"),e.possibleTypes&&this.addPossibleTypes(e.possibleTypes),e.typePolicies&&this.addTypePolicies(e.typePolicies)}return e.prototype.identify=function(e,t){var n,r,i=this,a=t&&(t.typename||(null===(n=t.storeObject)||void 0===n?void 0:n.__typename))||e.__typename;if(a===this.rootTypenamesById.ROOT_QUERY)return["ROOT_QUERY"];for(var o=t&&t.storeObject||e,s=(0,en.pi)((0,en.pi)({},t),{typename:a,storeObject:o,readField:t&&t.readField||function(){var e=i0(arguments,o);return i.readField(e,{store:i.cache.data,variables:e.variables})}}),u=a&&this.getTypePolicy(a),c=u&&u.keyFn||this.config.dataIdFromObject;c;){var l=c((0,en.pi)((0,en.pi)({},e),o),s);if((0,tP.k)(l))c=iU(l);else{r=l;break}}return r=r?String(r):void 0,s.keyObject?[r,s.keyObject]:[r]},e.prototype.addTypePolicies=function(e){var t=this;Object.keys(e).forEach(function(n){var r=e[n],i=r.queryType,a=r.mutationType,o=r.subscriptionType,s=(0,en._T)(r,["queryType","mutationType","subscriptionType"]);i&&t.setRootTypename("Query",n),a&&t.setRootTypename("Mutation",n),o&&t.setRootTypename("Subscription",n),ic.call(t.toBeAdded,n)?t.toBeAdded[n].push(s):t.toBeAdded[n]=[s]})},e.prototype.updateTypePolicy=function(e,t){var n=this,r=this.getTypePolicy(e),i=t.keyFields,a=t.fields;function o(e,t){e.merge="function"==typeof t?t:!0===t?iX:!1===t?iJ:e.merge}o(r,t.merge),r.keyFn=!1===i?iq:(0,tP.k)(i)?iU(i):"function"==typeof i?i:r.keyFn,a&&Object.keys(a).forEach(function(t){var r=n.getFieldPolicy(e,t,!0),i=a[t];if("function"==typeof i)r.read=i;else{var s=i.keyArgs,u=i.read,c=i.merge;r.keyFn=!1===s?iZ:(0,tP.k)(s)?iH(s):"function"==typeof s?s:r.keyFn,"function"==typeof u&&(r.read=u),o(r,c)}r.read&&r.merge&&(r.keyFn=r.keyFn||iZ)})},e.prototype.setRootTypename=function(e,t){void 0===t&&(t=e);var n="ROOT_"+e.toUpperCase(),r=this.rootTypenamesById[n];t!==r&&(__DEV__?(0,Q.kG)(!r||r===e,"Cannot change root ".concat(e," __typename more than once")):(0,Q.kG)(!r||r===e,3),r&&delete this.rootIdsByTypename[r],this.rootIdsByTypename[t]=n,this.rootTypenamesById[n]=t)},e.prototype.addPossibleTypes=function(e){var t=this;this.usingPossibleTypes=!0,Object.keys(e).forEach(function(n){t.getSupertypeSet(n,!0),e[n].forEach(function(e){t.getSupertypeSet(e,!0).add(n);var r=e.match(ig);r&&r[0]===e||t.fuzzySubtypes.set(e,RegExp(e))})})},e.prototype.getTypePolicy=function(e){var t=this;if(!ic.call(this.typePolicies,e)){var n=this.typePolicies[e]=Object.create(null);n.fields=Object.create(null);var r=this.supertypeMap.get(e);r&&r.size&&r.forEach(function(e){var r=t.getTypePolicy(e),i=r.fields;Object.assign(n,(0,en._T)(r,["fields"])),Object.assign(n.fields,i)})}var i=this.toBeAdded[e];return i&&i.length&&i.splice(0).forEach(function(n){t.updateTypePolicy(e,n)}),this.typePolicies[e]},e.prototype.getFieldPolicy=function(e,t,n){if(e){var r=this.getTypePolicy(e).fields;return r[t]||n&&(r[t]=Object.create(null))}},e.prototype.getSupertypeSet=function(e,t){var n=this.supertypeMap.get(e);return!n&&t&&this.supertypeMap.set(e,n=new Set),n},e.prototype.fragmentMatches=function(e,t,n,r){var i=this;if(!e.typeCondition)return!0;if(!t)return!1;var a=e.typeCondition.name.value;if(t===a)return!0;if(this.usingPossibleTypes&&this.supertypeMap.has(a))for(var o=this.getSupertypeSet(t,!0),s=[o],u=function(e){var t=i.getSupertypeSet(e,!1);t&&t.size&&0>s.indexOf(t)&&s.push(t)},c=!!(n&&this.fuzzySubtypes.size),l=!1,f=0;f1?a:t}:(r=(0,en.pi)({},i),ic.call(r,"from")||(r.from=t)),__DEV__&&void 0===r.from&&__DEV__&&Q.kG.warn("Undefined 'from' passed to readField with arguments ".concat(iF(Array.from(e)))),void 0===r.variables&&(r.variables=n),r}function i2(e){return function(t,n){if((0,tP.k)(t)||(0,tP.k)(n))throw __DEV__?new Q.ej("Cannot automatically merge arrays"):new Q.ej(4);if((0,eO.s)(t)&&(0,eO.s)(n)){var r=e.getFieldValue(t,"__typename"),i=e.getFieldValue(n,"__typename");if(r&&i&&r!==i)return n;if(eD(t)&&iw(n))return e.merge(t.__ref,n),t;if(iw(t)&&eD(n))return e.merge(t,n.__ref),n;if(iw(t)&&iw(n))return(0,en.pi)((0,en.pi)({},t),n)}return n}}function i3(e,t,n){var r="".concat(t).concat(n),i=e.flavors.get(r);return i||e.flavors.set(r,i=e.clientOnly===t&&e.deferred===n?e:(0,en.pi)((0,en.pi)({},e),{clientOnly:t,deferred:n})),i}var i4=function(){function e(e,t,n){this.cache=e,this.reader=t,this.fragments=n}return e.prototype.writeToStore=function(e,t){var n=this,r=t.query,i=t.result,a=t.dataId,o=t.variables,s=t.overwrite,u=e2(r),c=i_();o=(0,en.pi)((0,en.pi)({},e9(u)),o);var l=(0,en.pi)((0,en.pi)({store:e,written:Object.create(null),merge:function(e,t){return c.merge(e,t)},variables:o,varString:nx(o)},iE(r,this.fragments)),{overwrite:!!s,incomingById:new Map,clientOnly:!1,deferred:!1,flavors:new Map}),f=this.processSelectionSet({result:i||Object.create(null),dataId:a,selectionSet:u.selectionSet,mergeTree:{map:new Map},context:l});if(!eD(f))throw __DEV__?new Q.ej("Could not identify object ".concat(JSON.stringify(i))):new Q.ej(7);return l.incomingById.forEach(function(t,r){var i=t.storeObject,a=t.mergeTree,o=t.fieldNodeSet,s=eI(r);if(a&&a.map.size){var u=n.applyMerges(a,s,i,l);if(eD(u))return;i=u}if(__DEV__&&!l.overwrite){var c=Object.create(null);o.forEach(function(e){e.selectionSet&&(c[e.name.value]=!0)});var f=function(e){return!0===c[iv(e)]},d=function(e){var t=a&&a.map.get(e);return Boolean(t&&t.info&&t.info.merge)};Object.keys(i).forEach(function(e){f(e)&&!d(e)&&at(s,i,e,l.store)})}e.merge(r,i)}),e.retain(f.__ref),f},e.prototype.processSelectionSet=function(e){var t=this,n=e.dataId,r=e.result,i=e.selectionSet,a=e.context,o=e.mergeTree,s=this.cache.policies,u=Object.create(null),c=n&&s.rootTypenamesById[n]||eJ(r,i,a.fragmentMap)||n&&a.store.get(n,"__typename");"string"==typeof c&&(u.__typename=c);var l=function(){var e=i0(arguments,u,a.variables);if(eD(e.from)){var t=a.incomingById.get(e.from.__ref);if(t){var n=s.readField((0,en.pi)((0,en.pi)({},e),{from:t.storeObject}),a);if(void 0!==n)return n}}return s.readField(e,a)},f=new Set;this.flattenFields(i,r,a,c).forEach(function(e,n){var i,a=r[eX(n)];if(f.add(n),void 0!==a){var d=s.getStoreFieldName({typename:c,fieldName:n.name.value,field:n,variables:e.variables}),h=i5(o,d),p=t.processFieldValue(a,n,n.selectionSet?i3(e,!1,!1):e,h),b=void 0;n.selectionSet&&(eD(p)||iw(p))&&(b=l("__typename",p));var m=s.getMergeFunction(c,n.name.value,b);m?h.info={field:n,typename:c,merge:m}:i7(o,d),u=e.merge(u,((i={})[d]=p,i))}else __DEV__&&!e.clientOnly&&!e.deferred&&!nj.added(n)&&!s.getReadFunction(c,n.name.value)&&__DEV__&&Q.kG.error("Missing field '".concat(eX(n),"' while writing result ").concat(JSON.stringify(r,null,2)).substring(0,1e3))});try{var d=s.identify(r,{typename:c,selectionSet:i,fragmentMap:a.fragmentMap,storeObject:u,readField:l}),h=d[0],p=d[1];n=n||h,p&&(u=a.merge(u,p))}catch(b){if(!n)throw b}if("string"==typeof n){var m=eI(n),g=a.written[n]||(a.written[n]=[]);if(g.indexOf(i)>=0||(g.push(i),this.reader&&this.reader.isFresh(r,m,i,a)))return m;var v=a.incomingById.get(n);return v?(v.storeObject=a.merge(v.storeObject,u),v.mergeTree=i8(v.mergeTree,o),f.forEach(function(e){return v.fieldNodeSet.add(e)})):a.incomingById.set(n,{storeObject:u,mergeTree:i9(o)?void 0:o,fieldNodeSet:f}),m}return u},e.prototype.processFieldValue=function(e,t,n,r){var i=this;return t.selectionSet&&null!==e?(0,tP.k)(e)?e.map(function(e,a){var o=i.processFieldValue(e,t,n,i5(r,a));return i7(r,a),o}):this.processSelectionSet({result:e,selectionSet:t.selectionSet,context:n,mergeTree:r}):__DEV__?nJ(e):e},e.prototype.flattenFields=function(e,t,n,r){void 0===r&&(r=eJ(t,e,n.fragmentMap));var i=new Map,a=this.cache.policies,o=new n_(!1);return function e(s,u){var c=o.lookup(s,u.clientOnly,u.deferred);c.visited||(c.visited=!0,s.selections.forEach(function(o){if(td(o,n.variables)){var s=u.clientOnly,c=u.deferred;if(!(s&&c)&&(0,tP.O)(o.directives)&&o.directives.forEach(function(e){var t=e.name.value;if("client"===t&&(s=!0),"defer"===t){var r=eZ(e,n.variables);r&&!1===r.if||(c=!0)}}),eQ(o)){var l=i.get(o);l&&(s=s&&l.clientOnly,c=c&&l.deferred),i.set(o,i3(n,s,c))}else{var f=eC(o,n.lookupFragment);if(!f&&o.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(o.name.value)):new Q.ej(8);f&&a.fragmentMatches(f,r,t,n.variables)&&e(f.selectionSet,i3(n,s,c))}}}))}(e,n),i},e.prototype.applyMerges=function(e,t,n,r,i){var a=this;if(e.map.size&&!eD(n)){var o,s,u=!(0,tP.k)(n)&&(eD(t)||iw(t))?t:void 0,c=n;u&&!i&&(i=[eD(u)?u.__ref:u]);var l=function(e,t){return(0,tP.k)(e)?"number"==typeof t?e[t]:void 0:r.store.getFieldValue(e,String(t))};e.map.forEach(function(e,t){var n=l(u,t),o=l(c,t);if(void 0!==o){i&&i.push(t);var f=a.applyMerges(e,n,o,r,i);f!==o&&(s=s||new Map).set(t,f),i&&(0,Q.kG)(i.pop()===t)}}),s&&(n=(0,tP.k)(c)?c.slice(0):(0,en.pi)({},c),s.forEach(function(e,t){n[t]=e}))}return e.info?this.cache.policies.runMergeFunction(t,n,e.info,r,i&&(o=r.store).getStorage.apply(o,i)):n},e}(),i6=[];function i5(e,t){var n=e.map;return n.has(t)||n.set(t,i6.pop()||{map:new Map}),n.get(t)}function i8(e,t){if(e===t||!t||i9(t))return e;if(!e||i9(e))return t;var n=e.info&&t.info?(0,en.pi)((0,en.pi)({},e.info),t.info):e.info||t.info,r=e.map.size&&t.map.size,i=r?new Map:e.map.size?e.map:t.map,a={info:n,map:i};if(r){var o=new Set(t.map.keys());e.map.forEach(function(e,n){a.map.set(n,i8(e,t.map.get(n))),o.delete(n)}),o.forEach(function(n){a.map.set(n,i8(t.map.get(n),e.map.get(n)))})}return a}function i9(e){return!e||!(e.info||e.map.size)}function i7(e,t){var n=e.map,r=n.get(t);r&&i9(r)&&(i6.push(r),n.delete(t))}var ae=new Set;function at(e,t,n,r){var i=function(e){var t=r.getFieldValue(e,n);return"object"==typeof t&&t},a=i(e);if(a){var o=i(t);if(!(!o||eD(a)||(0,nm.D)(a,o)||Object.keys(a).every(function(e){return void 0!==r.getFieldValue(o,e)}))){var s=r.getFieldValue(e,"__typename")||r.getFieldValue(t,"__typename"),u=iv(n),c="".concat(s,".").concat(u);if(!ae.has(c)){ae.add(c);var l=[];(0,tP.k)(a)||(0,tP.k)(o)||[a,o].forEach(function(e){var t=r.getFieldValue(e,"__typename");"string"!=typeof t||l.includes(t)||l.push(t)}),__DEV__&&Q.kG.warn("Cache data may be lost when replacing the ".concat(u," field of a ").concat(s," object.\n\nThis could cause additional (usually avoidable) network requests to fetch data that were otherwise cached.\n\nTo address this problem (which is not a bug in Apollo Client), ").concat(l.length?"either ensure all objects of type "+l.join(" and ")+" have an ID or a custom merge function, or ":"","define a custom merge function for the ").concat(c," field, so InMemoryCache can safely merge these objects:\n\n existing: ").concat(JSON.stringify(a).slice(0,1e3),"\n incoming: ").concat(JSON.stringify(o).slice(0,1e3),"\n\nFor more information about these options, please refer to the documentation:\n\n * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers\n * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects\n"))}}}}var an=function(e){function t(t){void 0===t&&(t={});var n=e.call(this)||this;return n.watches=new Set,n.typenameDocumentCache=new Map,n.makeVar=r2,n.txCount=0,n.config=ip(t),n.addTypename=!!n.config.addTypename,n.policies=new iQ({cache:n,dataIdFromObject:n.config.dataIdFromObject,possibleTypes:n.config.possibleTypes,typePolicies:n.config.typePolicies}),n.init(),n}return(0,en.ZT)(t,e),t.prototype.init=function(){var e=this.data=new iT.Root({policies:this.policies,resultCaching:this.config.resultCaching});this.optimisticData=e.stump,this.resetResultCache()},t.prototype.resetResultCache=function(e){var t=this,n=this.storeReader,r=this.config.fragments;this.storeWriter=new i4(this,this.storeReader=new iP({cache:this,addTypename:this.addTypename,resultCacheMaxSize:this.config.resultCacheMaxSize,canonizeResults:ib(this.config),canon:e?void 0:n&&n.canon,fragments:r}),r),this.maybeBroadcastWatch=rZ(function(e,n){return t.broadcastWatch(e,n)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var n=e.optimistic?t.optimisticData:t.data;if(iD(n)){var r=e.optimistic,i=e.id,a=e.variables;return n.makeCacheKey(e.query,e.callback,nx({optimistic:r,id:i,variables:a}))}}}),new Set([this.data.group,this.optimisticData.group,]).forEach(function(e){return e.resetCaching()})},t.prototype.restore=function(e){return this.init(),e&&this.data.replace(e),this},t.prototype.extract=function(e){return void 0===e&&(e=!1),(e?this.optimisticData:this.data).extract()},t.prototype.read=function(e){var t=e.returnPartialData,n=void 0!==t&&t;try{return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,config:this.config,returnPartialData:n})).result||null}catch(r){if(r instanceof is)return null;throw r}},t.prototype.write=function(e){try{return++this.txCount,this.storeWriter.writeToStore(this.data,e)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.modify=function(e){if(ic.call(e,"id")&&!e.id)return!1;var t=e.optimistic?this.optimisticData:this.data;try{return++this.txCount,t.modify(e.id||"ROOT_QUERY",e.fields)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.diff=function(e){return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,rootId:e.id||"ROOT_QUERY",config:this.config}))},t.prototype.watch=function(e){var t=this;return this.watches.size||r0(this),this.watches.add(e),e.immediate&&this.maybeBroadcastWatch(e),function(){t.watches.delete(e)&&!t.watches.size&&r1(t),t.maybeBroadcastWatch.forget(e)}},t.prototype.gc=function(e){nx.reset();var t=this.optimisticData.gc();return e&&!this.txCount&&(e.resetResultCache?this.resetResultCache(e.resetResultIdentities):e.resetResultIdentities&&this.storeReader.resetCanon()),t},t.prototype.retain=function(e,t){return(t?this.optimisticData:this.data).retain(e)},t.prototype.release=function(e,t){return(t?this.optimisticData:this.data).release(e)},t.prototype.identify=function(e){if(eD(e))return e.__ref;try{return this.policies.identify(e)[0]}catch(t){__DEV__&&Q.kG.warn(t)}},t.prototype.evict=function(e){if(!e.id){if(ic.call(e,"id"))return!1;e=(0,en.pi)((0,en.pi)({},e),{id:"ROOT_QUERY"})}try{return++this.txCount,this.optimisticData.evict(e,this.data)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.reset=function(e){var t=this;return this.init(),nx.reset(),e&&e.discardWatches?(this.watches.forEach(function(e){return t.maybeBroadcastWatch.forget(e)}),this.watches.clear(),r1(this)):this.broadcastWatches(),Promise.resolve()},t.prototype.removeOptimistic=function(e){var t=this.optimisticData.removeLayer(e);t!==this.optimisticData&&(this.optimisticData=t,this.broadcastWatches())},t.prototype.batch=function(e){var t,n=this,r=e.update,i=e.optimistic,a=void 0===i||i,o=e.removeOptimistic,s=e.onWatchUpdated,u=function(e){var i=n,a=i.data,o=i.optimisticData;++n.txCount,e&&(n.data=n.optimisticData=e);try{return t=r(n)}finally{--n.txCount,n.data=a,n.optimisticData=o}},c=new Set;return s&&!this.txCount&&this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e){return c.add(e),!1}})),"string"==typeof a?this.optimisticData=this.optimisticData.addLayer(a,u):!1===a?u(this.data):u(),"string"==typeof o&&(this.optimisticData=this.optimisticData.removeLayer(o)),s&&c.size?(this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e,t){var n=s.call(this,e,t);return!1!==n&&c.delete(e),n}})),c.size&&c.forEach(function(e){return n.maybeBroadcastWatch.dirty(e)})):this.broadcastWatches(e),t},t.prototype.performTransaction=function(e,t){return this.batch({update:e,optimistic:t||null!==t})},t.prototype.transformDocument=function(e){if(this.addTypename){var t=this.typenameDocumentCache.get(e);return t||(t=nj(e),this.typenameDocumentCache.set(e,t),this.typenameDocumentCache.set(t,t)),t}return e},t.prototype.transformForLink=function(e){var t=this.config.fragments;return t?t.transform(e):e},t.prototype.broadcastWatches=function(e){var t=this;this.txCount||this.watches.forEach(function(n){return t.maybeBroadcastWatch(n,e)})},t.prototype.broadcastWatch=function(e,t){var n=e.lastDiff,r=this.diff(e);(!t||(e.optimistic&&"string"==typeof t.optimistic&&(r.fromOptimisticTransaction=!0),!t.onWatchUpdated||!1!==t.onWatchUpdated.call(this,e,r,n)))&&(n&&(0,nm.D)(n.result,r.result)||e.callback(e.lastDiff=r,n))},t}(io),ar={possibleTypes:{ApproveJobProposalSpecPayload:["ApproveJobProposalSpecSuccess","JobAlreadyExistsError","NotFoundError"],BridgePayload:["Bridge","NotFoundError"],CancelJobProposalSpecPayload:["CancelJobProposalSpecSuccess","NotFoundError"],ChainPayload:["Chain","NotFoundError"],CreateAPITokenPayload:["CreateAPITokenSuccess","InputErrors"],CreateBridgePayload:["CreateBridgeSuccess"],CreateCSAKeyPayload:["CSAKeyExistsError","CreateCSAKeySuccess"],CreateFeedsManagerChainConfigPayload:["CreateFeedsManagerChainConfigSuccess","InputErrors","NotFoundError"],CreateFeedsManagerPayload:["CreateFeedsManagerSuccess","DuplicateFeedsManagerError","InputErrors","NotFoundError","SingleFeedsManagerError"],CreateJobPayload:["CreateJobSuccess","InputErrors"],CreateOCR2KeyBundlePayload:["CreateOCR2KeyBundleSuccess"],CreateOCRKeyBundlePayload:["CreateOCRKeyBundleSuccess"],CreateP2PKeyPayload:["CreateP2PKeySuccess"],DeleteAPITokenPayload:["DeleteAPITokenSuccess","InputErrors"],DeleteBridgePayload:["DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DeleteBridgeSuccess","NotFoundError"],DeleteCSAKeyPayload:["DeleteCSAKeySuccess","NotFoundError"],DeleteFeedsManagerChainConfigPayload:["DeleteFeedsManagerChainConfigSuccess","NotFoundError"],DeleteJobPayload:["DeleteJobSuccess","NotFoundError"],DeleteOCR2KeyBundlePayload:["DeleteOCR2KeyBundleSuccess","NotFoundError"],DeleteOCRKeyBundlePayload:["DeleteOCRKeyBundleSuccess","NotFoundError"],DeleteP2PKeyPayload:["DeleteP2PKeySuccess","NotFoundError"],DeleteVRFKeyPayload:["DeleteVRFKeySuccess","NotFoundError"],DismissJobErrorPayload:["DismissJobErrorSuccess","NotFoundError"],Error:["CSAKeyExistsError","DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DuplicateFeedsManagerError","InputError","JobAlreadyExistsError","NotFoundError","RunJobCannotRunError","SingleFeedsManagerError"],EthTransactionPayload:["EthTransaction","NotFoundError"],FeaturesPayload:["Features"],FeedsManagerPayload:["FeedsManager","NotFoundError"],GetSQLLoggingPayload:["SQLLogging"],GlobalLogLevelPayload:["GlobalLogLevel"],JobPayload:["Job","NotFoundError"],JobProposalPayload:["JobProposal","NotFoundError"],JobRunPayload:["JobRun","NotFoundError"],JobSpec:["BlockHeaderFeederSpec","BlockhashStoreSpec","BootstrapSpec","CronSpec","DirectRequestSpec","FluxMonitorSpec","GatewaySpec","KeeperSpec","OCR2Spec","OCRSpec","StandardCapabilitiesSpec","VRFSpec","WebhookSpec","WorkflowSpec"],NodePayload:["Node","NotFoundError"],PaginatedPayload:["BridgesPayload","ChainsPayload","EthTransactionAttemptsPayload","EthTransactionsPayload","JobRunsPayload","JobsPayload","NodesPayload"],RejectJobProposalSpecPayload:["NotFoundError","RejectJobProposalSpecSuccess"],RunJobPayload:["NotFoundError","RunJobCannotRunError","RunJobSuccess"],SetGlobalLogLevelPayload:["InputErrors","SetGlobalLogLevelSuccess"],SetSQLLoggingPayload:["SetSQLLoggingSuccess"],SetServicesLogLevelsPayload:["InputErrors","SetServicesLogLevelsSuccess"],UpdateBridgePayload:["NotFoundError","UpdateBridgeSuccess"],UpdateFeedsManagerChainConfigPayload:["InputErrors","NotFoundError","UpdateFeedsManagerChainConfigSuccess"],UpdateFeedsManagerPayload:["InputErrors","NotFoundError","UpdateFeedsManagerSuccess"],UpdateJobProposalSpecDefinitionPayload:["NotFoundError","UpdateJobProposalSpecDefinitionSuccess"],UpdatePasswordPayload:["InputErrors","UpdatePasswordSuccess"],VRFKeyPayload:["NotFoundError","VRFKeySuccess"]}};let ai=ar;var aa=(r=void 0,location.origin),ao=new nh({uri:"".concat(aa,"/query"),credentials:"include"}),as=new ia({cache:new an({possibleTypes:ai.possibleTypes}),link:ao});if(a.Z.locale(o),u().defaultFormat="YYYY-MM-DD h:mm:ss A","undefined"!=typeof document){var au,ac,al=f().hydrate;ac=X,al(c.createElement(et,{client:as},c.createElement(d.zj,null,c.createElement(i.MuiThemeProvider,{theme:J.r},c.createElement(ac,null)))),document.getElementById("root"))}})()})(); \ No newline at end of file diff --git a/core/web/assets/main.2f351fafaaf99deb7f66.js.gz b/core/web/assets/main.84f90f8fc23465846aa7.js.gz similarity index 94% rename from core/web/assets/main.2f351fafaaf99deb7f66.js.gz rename to core/web/assets/main.84f90f8fc23465846aa7.js.gz index af628207a91ea97e9845bc34e3f5c706f70f9301..7fcd5de9137a112d2b6d3b4244d4985ccf190ce5 100644 GIT binary patch delta 68671 zcmXuJV{o8N*R>tnwrv{|+xEo9B$+rlV|!xT#>BR5+s?#zujl*fu3D>m|LEGkx~i-9 zIt~J4o&#k3gF%DAg296!f+2&Uf}w+9f?Gsn@xUR3SqN=+AX`PzJog`jvv&pu*sWg`ZhgO#Z;Rt^2!>WS2Ep3Sd{QJmZ zI78O2r_O!++@vzn(na30pX6}#^+wf&O^?aWX0DCHqw=N~x&zy>b5zON7*-M0Mb@E#Fbs*t0#^-eucIWN=;v_r(HdGRz3sSd===1eKPCL^=Yz zPKb_|1Rc>}9JL?xeGr}nk{#DL^{2}S7phcULm=j}2-JJz-6G)(KscFHJUr06UMu_4 zY_30G&daFX$&6!07W;3sMWO3n4JtnlZRD7xtqjxq&^okv+NI|4B@>da^ojiTYpe?oJ|)>|h)P5$dH5 zX#Po@OAcyegE;Wlm?(X5^6|UznQ7ggOy~QwlE#%7U@1r0@)?+Vaj~QRMcp9qH!-J4 z3Sg#?MXQIf`O)1psr$XcQ|q2{SY?1sllNow*XGtjj$Cx!b#tZ7O818wE0k|lMj#C5 z?zRwXmx0pA9)!As0KQLJW}ibZrssZGK-;PT3n39<@gi`N&bvu?Uao@CgI(TH1-^>E ziU&ba!0U#XO8;Y9dq8gE`4}Txy5#1rJwBK6W@}my?ekPK<1Y+i^Oy<-I#-yLt(ko6 z3ccv}SsUf~uu6gMBkD>$9+we+0IP`IXbi83m#S%R1RIM*1N(RftxZ&GoU>gii|Dw} z?6Nvo2n}FCvtzb*u3X}kWVcb?#Um;x<)F`w$Nq!1o%r2H*lqB0746xycHfU+(^A;* zKND^L=PgrVDu;%As=+K0C~mg~xv+W>l{E{(68V@!U;f1d%Q2{&afzKVw@2mF*Q2w^ zJ;vsZFt2e^=48pu%EmJY$F|9}cm-VkIrCT`+OB;yjLALGObu@OcR6`zk*)0e{N%r4 zoz+x}66UGEZVq-|YploO^b5JhR^|p5MlHUsi?c=Fx|d1%@sUjgc;vwXpGExompX=N zDYVp_A_-4)XsK73%&F9Wv(c*&UOO&nL@kN`|H30=b#!vON^lk1{g1%yjQ8>z06k#| z*z@iTS{)}CbaO`G9}^LfLE889K|$UR@<<^VG#zB94!7TE$r-!OJ(O1@So2!`!_)Au z^E}qBYZn=W@{%zJC#eow9fVSzS{G7w6<>&dQgGC`hWqn^XY!vUtrS>8-SzeA;?CAT zst;qjH@knA)FU}R8O!&nhPm>4fS^pA3%cLv7gM<^S2_PvMgICfDArz)ndyS{D|Cwn zkOrw@97KZ68V<&xwjc!7jKR95OH3>G;$#{Bn^4c9e1YpNfSbg?u?|h4h?_n?1YBTf z=pk7QtzPbrT)u=&rOm60LX};#W#x#6KHIP-4dvyC6F|)*rr9 zeC1)7rdoiTO1l171Cj>iW{vpIVeBDV!068jt7muF={R4LPo`9-_d!TL_r!ZmLEBMa zsP_*h0*2)Iw4FsT+Q2%2-6Agc=F7#6;8jwDiI~k^bcBok?CITEFbbKZ+62A?S*l z2o0eQ%&um@s|Yq8L?*q)6sV*giZuor%nr!cE>qrjdJ+IQINh~Buak=~ zI+qAAqFXpL?-vNwS7~^6GR2ocnZBfBCIr1cRoniK#*QtqrbxtDjoXnn3*8$)dTEf!+mS ztY(UpLe52Fh3>xO#A1IXa7#=j8B?DtHywoNSwB|G7GV zgW#P8I$*&YO1A!+kQ3ELrRk!kqQVd9Dq~Y9g^cECE@1Chc4h$OG5jT=Kxs6NQvfPB z6Q>E#yA+L6mjk4;8T1ywn@#@&wG@1Jrm{nkQ&sBPocf@OVz)fQI*Bs6w(z5Volmi4 z)|TA6a=2E=YD+)2dZ_Eo06ozcZIJxk**7IGmH8UWWlm^s!M8r?-b8z4#lA9E(o{I< zvGtN$ENYL3aR8ug_w+J=eIl!-Q3jcO#H9d=%#C6G2#dj_xrQcCB7fA>%w*m=Kf%qU zCo%6m;pB1fegA8s4SO1ZgeT0Vmw}q7=|5L3uK`^~J zG`_41$G{{iV<0Ox^oXjWZ#vX`wB1lMr8^fdB|F z2P@L}XG=k|R3NXPc6k&&AL4guHO&D@4v$>^!s=8IwQ!_Ka3m8j`H?VeVlW(0pBQGl zf=LLQqHH`|8sGI}AQ*z+j1Eh&S}0%r^l(7E(GTh%ijSfDS06xVCwJz#XZm&9C)mDA z{g=w$YOOhWn&EUfn!x_$X|g$idtf;Sp7GDdI(=|TM2p*ZcYwJxkEzHL$S`y_VKOxL zG>$qHoXLt;P_dKiJ+~;9^=_B1m*c~547PN@);A`vKyR2`?3Nb$B@>0nP8ThEW|B1D z0Q_nA5fXI{z{6QnW`B-9lW8)cQOhw{tvNHk*Xz*{Z2KPEtCCZ$OJO}<2e3>(%nZc{ z9;Wx^2fyZ!R#xcUTtc+t@jo_{jPRvn$C$1A%)lc`QLjS>d%`^hp2WM_y1{A8B1nmi z$;VN5y1!0_ftrS%j!x!8sw>rbn2O zxrpNID2FC}@fpD!H64Y`&*;vDG`VR*O#fD3W?dyMZFh)I>{(@5FqkT&79DOQ&cxp{ zClp`8(q@W|L%-dfKrEe^_bn#B`YaPYLyg*{+3mDLw9&9Hr)t;K0^@#psvd!ZEL%_r zhQw9#XTRn1rw5(Pj%gcC3MqNPCGVDVYfZsak7??kgd;f?RVW{~Tu#%FPuu2I{(u*! znh8VcY4%xktoY*bzjk@AjtPea0(ouEMl={cH#GLwT~bqBo+uC7pnxm5NQL{wkRRZ_JQSWLdxGnTsq9y6BWzcV zi;^7y#0z9c-0DRi5ps#Z3G$5^+0jmAR8r4}ulTr;c)~ruiw<|vpMis*!UK0W8=Udd zKS5pFd+C80p$+cN&g-8(9(j2w`B_9?KCL@J#P(uqJN(#fhL$8ir`M8*WYrX$n-Ty_Q8LizlHnQgKT` z>Jds3k*Q7;;LX+5KMfo@pH5W9)>cMf$N*c}_&|`;WgO%O%vvDZ4d>x$0QW#etx5&( zqOl+FFd>-6eA*XRz*L}!ff{=jMApydt1Rx3&Ve%0T%OkQ~wEj&_IfiAk+dcQi*Zx$E^)AFM1Nw9la10pkG2)OLqUY0pKdzU_<&M0&C@rfvCvk z*(&h4$c6qv*S-=H9=^Cd^QVXR`OK3~ni-7w6%3>$GIR<*Bz|YfUPzzz(Co-?5s%!V z`YaWU2c)uW7Y8{e`um)`|tjlc60C8a*a*v znzPk*PCV)-Vh@(%t(}L~f*qj)8Arv)>z-og694tX5aV$- zuaN%r2Zh!uJx&EBy9Ta*W*G~&9_EI8fLkESd-G&NYJJEua|jZSrT;Bszt{75M7e{s7-|HV|MG&g=Eie;mBR;W z-tvVKqD_|yX}Ap=>*xOFYq&*%iahlGVa4UvpSus)C+S4(^O~3tAXCbq_>1Vt zeTaCNO;jk=!)Sj4gkl;^z&ynydf>WwA|mxKkG7tg?*edQvf7YTQJD;5QN)Yv#PXQ! zdHPxrRaZhS7p$%FrW!zK6nFwMH%Ul7G*yjW!U<LwdY+2y!26@m7)nw)IzpLt@C=QY>W>qZI%a|a z9Ox2I_6 zHF0xXM!+{M@|+NV2WI(0hESoF={tZB70?HgzYXn%$F9MGuGJnKC48n(cy#5eiAQATY+H z8CQ`^EkPvUu;{hEF_{EYNXW~aAq5hx1Et6`X&5qG-(FHARQ;Rg)M|Gs7gTuwbR$B_ z10%#~@y@t|cd(4djNOvaU~a6@asH^z+r+9W;vN4oG%P>ga zP||SFJSPy2iLorE$W3^2NQ(Gv9NJogg1rgzO9*7wcbaB zVo@okcu6K4!O1(8S*ciCx$6QT;wj^&l5$Xh3D_MKrAHU?uQfaD-8W6=HTljjCQBQ; zWYsOBMD=Z^>JR&qDyU=W$}A-Gfnup@AzK_oXF!?NKSnK$%VC|-`7lWr#`5uZM1a#c zc-mr-1dUp939h**Y5hyrNnR2<#EQVk@J_MI!FBs);Ob8W8JQyf1>qmS#|Exo{Ywjb zHOZF(H66+~+VzBAinxFrSq>%YOky~j48*y7MY{E5HSbfo@nf@T7`kbrA$1B~b{lW2 zDyLwYwo4ULg#Q|8p2tIb#hK8T{oc!}X0qCo_@owJP^YhyB^l&0HiEav@0@wF2CHWX zv7jHcRPiz7y^8T8lF44 za6Ghd$Fvn&eWSpUBgTH(Idd|!Md+LW>_kh76J`&J2?}x zlb?udm+O+@9>4tnx_B;>%3g@y7D^`Wv$$F<{HOZW(i^0#%!!XJ`s|toJ0-fx=_#3j z%vn1nUzK|D%1q=FH0?S+Hb5%zZanlC%H^ldcb!E}@yrnGoEbY@SI5QU%YcOJAK%x< zj7$8z`5#!XTZB3tO$oOrEK7ri=2P4oLtjW4j>{Uq6n>)tzn3Z1EMw9vAqW;XFYm#S zW_PQDO5H%b5cbf0_A=mW)MOQn-!f$rPTBw9hwCzzP>i3_@fEj6GRWdWy?Cx$&>^gz$vLyMc5;e}zh3B=BT~m%Sx?F|JRnCj{ zzXBYolPA5v=%}wv!B$Nm2?FK!ajU6wgc5K2Vomm0ljQD%%~$_#(gX=JTBEK2!*}zW zM;xCE8>zw!2{tA$U8EYwWrP)f_`7Oj?M9qn2j}1Jfh<2bsf#oaSm0M|SD-u&UwLYf z#slF5u`gtU%Zz?(GLK`(bPR1m%Dze1QgGg`OSe1$KKdR1u$q7N5!EoJUhX&D`~2$o z?=W*nLRxsg(yIqHrczWq7IFS`_o2n#mi4`Pm$l758zCq2#>Utj>#}ZQh1YC#(_@S= zqunYbk%QP4C-QK_yd2mhmpJM0WTm4NrUCO*C5REn{}~FGbyeCNCjkm7M;JmjC)o?r zs~w2D8bX<12GZo1zH#qM4dkN)pWpECQd73tRJxp{gf)*VTXR|uE7fO|ozDg_KVLLG zt7UNgoE3IE{rtmnY+axmz&`c^#tHl}oVA@!h$Y0>x9a=OT8bzR-rlEp5?ke zm%U}I<<>%nGsmrTw>8!5k~`q|&O{17X90&J*$Hp)OR9&w_Y}4k zQn%S%xx&@{%ly;3Z!lymo&w=^I4~?hPN=(|t#Jf9dy=ux6m=n}s%c=+5N0&uV}OiQ zWS-i{$&ZrHtr*MD@UlF_KpwiMGA!rKE!f2*I$A74N(q^y-@JAo%Bi6#L&*NG71V3a}dl8fQ@&!B@;Onfp29>ZMwo8o{jEoaee;h|u$#1OhLE^oG?g zFnfuEWV6?-T%xJ9i)qrZG}0uQIY2!k##Jo#G7i4%=~M|^LA~6t$Ta*)BWusXPrlxbrV%x;7rF#3*nLvFw^qK59s&*blek z$QE{^&TQVbjdaS*v1?lqP2duI%ch1)VBK&JjBsWX8Lk0_D#wfz0ln6UWc6leaMdT8$Je0nO|w>~pmxzM;?k26;u65 zxm`fFKr`d)2HoEujyDHz>z)r)G+t>1rwc~XDvv_d0k5*jxQ?y+AwVIzXl}5+u+Zn7 z0U=6)y(j=5GhTiw_j0`!c=JEi7BKHIkHwshJjR6cNG@#$wj??6ssOHbg>J6#9*A(G zJaj(qbM=r?eSD?L)~gMW3p!da_XGVt#ohrE=p)mKgKUcjnr~ zm=6gDJ!OFHQDo<$1bV|@P`kDYekO#v-d<;0fkgzhr5{_*fWD8mAa<_YaiF0gTi3W+ zHM2rWsnIgCb$KEx9E4nOXPoULVc6Bfx$%3o+3Ko9t<|RT)kwk#a=nUa!0A3|!y&FI znc14v(?{?4#iv@#rDLVk(@J7O@yc;B1aA@*Jp~|bT@F+jzc;Ic{c|J>c!Q)+9>F{R zkoWT=DdG4go5>w>2@?30%(*yx)wP3?rD4KPBkrUY8WukBjpqMW^oa@+*yD96`vzd8qky8!%lo>WoJ115XgDlCdb}PN;7ANKU?XQ=itL#gWu9M_ zQ*ZcHjHM7QnEx?wQ=XvmP9uT+jo_Q(sGfq*rjyzIa%!Y{84=78s_pZGjfkbLrlB+0uJ*+e= z=!B)ob(GpTj@X7|#Xf4p+uuLDVC%p9C+bOZS?h4Mkrf@skb(>Umdmy(0g$ePv8Q;} z%kej`UBj3qHX}h3L(u%;Z_sg}h)aVzH!pMDe^Knd$LL&dK#jd|<;~oa{7d}W-u|vS z{DGtU6Fgvr-@YmMTJ}c?f2NY6lR*~BrbWIFffWPuT!7)G6d98$op(0%*$s8w**+WD zRp^f*7J{AAPLoNWomCXv+`eW$`juMxb{e zb;~=stB)J42KV5AqHkvVj98U!y?z#CyFs`8R|V85G=$ztm$C@$hV;i42_ed_XP4zm z2K{lf3?UGT619l|%7qyOe)!Ovm=SvAb3&S}izghVZw-lo#}C&OFl30h*Fbrl^0OyP zgHD69z9>A0=SYWs`Kh3PRu?cMF@5Y~r=%cSBipG$5|J}PmdEGJ z$|MIng=@&HgcLJz>OQx4I*KInnNhoJGnUVnF+`;++nR-kh4s;_#*^}!qFODSH z#>41!v&eN9g_JMv3Fh)Io&*UmcdwoZwCN*^WZOz&j(ee@VosTgbpRNWeD_Nwe`y{3 zi63#_IM=3DOd6Zay*!2j6A6{zdI*C>KV^>{iMf5OuiD%TKQR^)^R2p7Xx%00*W)c( z7FPKKO4cM0P_Mo_{uDX7OX^b+S8FKZD;w;8rJF#ISa;Zl@9qBas6U|Lj2A2Ccp30k z$c+cd!(k)k5N;!^NO-FjNLLkGnGxY5`@3EDyX}|>;T!7OKhymf7;fcr zVc~hGyY(n&Svt2&Uj4DHL;t*QXV1O+{N#C5US2Dj*T5(9W58!3V@EGNaFLp^f!RmU z@>~SEJn9Ak%p$knsK81WvQ0BYR)=@?DNK8q^Vj9E39>&jo8bJ+`HG6)fM=z$=-XW!LUHP$@ijH5IXZLmI$Bb^;!8sr^k=p4&curHs8DB*m5~BAogM zs$wY|<{wvNL~Z&-PaA`k?E`%47U*1TO!3edes3?XYc}J9=?2l5 z0jK!~M(#YrCtmKW$CK6Gzv?xhT_s9&X=muUyD!-J>?L?jU|4vTfsQ=2r%31l(xX5j z60CFLtm%sj3kVw0bwg562PwfOWkUSpwI`Tx7n(9^sehl1z$4p^p!mdXs5OK{`=x-O zfg5`JC59pMJVx0U%wnP@(!MKPhJR6I0bPngp;?x@1f*pv_B;<0?$qG|d7~@3S<1D_ z>o23KDUZ>%+^naui0L@%vw)nnC)r<`?GTobZzcIP1ZEQL$*7qA z!PwrlEJUZ>f`svxUUK^v3#ku-Y#9l3PaH~)K27E5ZWmqosePxYsI$8vX@!;+fonZO zG(J^YiOzQ{+h+_6tx+eWic`n;&i5xEhO{idi#(Lw?G^>gp>u>}1_Cxl2e*(IfQ_m5`Wef z+hX1kv7gh&ZpL!Fscpv59f0*SZ+oII=_#ve*DlT-y^^H1f-S~FG6Br-G!0onoo2SU z0jTDI5l0RFK^4}aq4zUuhLi1`0q5%x%Zauyo$1dn?1n7w)W2EYN{lCdhfpp(w_!VK zDK0(g+@|l3&#b2JgOjUuXXk&?5h>)jK9JEK7@WO9yCWqgPd!}#viR=OMT{Xi^u^uUNBkbe@IW{I+ z)C!pnuH*Q)G*d#3L@lFk6Z?>H^*jEpqs!;ppAr*=sWImcVvgqb^cN6EyXH)R?yv?J zCqx=!96J6Q2cVKvmv1GsBK`X#xL@%8mi+BDL7-Dg>T$u+^_Kbm79Ovg6j|`GUXF;5 zMxPov^|U2kU^6c_?9iClcas9yXqHsrBXn#Q79{_y0v~^>+MdPW_mZ1wr6IJ7hL$@m zNM)siokL5;I#S;8)>gSttB38|+}+Ta_4C%*-dcJ&55R+sf6dI%dIVfq_nbgK`Y{Cb)m z^ zw1BB7z>Fw~VHo}aYQ;6b+u2GTzwL2+^?sCg0Ul7LzW);=A~Rq$?$9l#ohcb!W|uUW zh-)}+WHu#rDxXnHC8?cT&eZT2rC|RYP7rdQe@=Eg898e%Q?2%CRY2_SE#=swpXIy0 zBP_s=eu>Evv51R<()b}s)kQ;hP~h@}G!@7Sf>2;M^ahKZUXdLOv$$QZ&JWO%YPh#h z7@epJ3vLPvy!m+ia(ldfIprY&wFPC+K1C2Aw^Y{n>k#rd9|11-PcU-U(C>z!=J0BJ zPHOJt+VnLAucEx*>)+XJ)ktI{N7F1JQ5YsP=oQrwF=dWO{yJm{*SxFj8QJF#aZW{1 zpN?v=Lk`(6ySUxNxtCARu3BJY5JFKe^gO3xNWeiT7A*DHxCNSlfFk=2pf)Cuw zqy=@LVqny10^Xz`cP|9Hx;A7E&Cz`;ov zuk>~Ut4)hHr&FR|%nr0`fEt5OCZLSj5mW|*j`BJEehKoBi#D&p9j>>rrrAO|z^O6+ z^>4VIZ&6vb=T}wYiwb{z;T0#*k3J>_UzbPe3xtPyNOOLEhpZO^Pp`MJxSd^Ve_PVE zWAhG#H8>ebwt)9!_p<9!!#<&x0#XM(DbX-v*Kn+Xj-!D;|8Y;^pcU7Z4fU{VL>LW% zRx;?$biv?^`g04d_RyjmLc9*Gl=|RRvq2LaiS1g*)G0kTYaYz%7v*SiYh7WCXwwvQ z>N%(xPD_e5f%gV~wp{a;eKnanoX`X6XG>VFE$vafQqFDK<08ar-`<3ojp7pSWl@c~ zLbb5>>Cv~t-8+CkRkSG{evmv6Nc>nB!I1BkG&{mWD|Ml#*EF7)ijj`tE$ww{HPy*L zZ3FIvyKuYa5F!f(cduEN;u+&*-1a5k z`q?!_BJ&N3L|6^tfnUs7HUhlhf^9C?<%*pEMFOh`RsdkIld0&Qyhw_g;lG4V6&9Qe zg8g71P!tBbG4acR8F?>OflnF|bh!Tfysag1Yio)?Ko?E%zqz;n4+8my!m~e&It||q zzux>EZM)<1CF|>LS1IoX`5m8`6qRC;Y*K6+iMJLC-K9o2FAaISPta^Fh9dn9x7>uk^PCjMp=)l08`7H-XoXUc=TRC(t#3V{UdWd^1z zLH|3B>`~_aO?`>%Q3%_Cf1>~Gj^0S2IliH;DI_?g%SQF$z@M0G@RUVqKsn+KD^~Nc zGF9A;Hn)j=NvdHlPYUvKx_e#CAovV4!f(J@ms<_RoNohRf|>g3PEG4YC z^P|#*Un@}Wu^Cli_OvbP`V}8dmAK7gqxA1!`=c8UibBZD{S4RkXLG6S%zzF{>?tD~ z@5>IQskkppk`lFLSgBxqX-Eegar|JoB>O$Hn3vy>Onfr^@nw;>k6Rie^*fhVyd_-- zu{&^&=32wq8}X90^;_9$IL!0svU_0et>W!{F;))rC&iuTEHk*BanXLS$Pf}hg#~gX zot%(6jA}|loU{+C^MN#2%bpON)K<{O*#8qwwUq})adIyMyjk2V0?e!smh8ui zz=Q@RxS!O5iQV+2BuO+PO^BLPwh|pJ{m50x7qw8nzFAsko zM23k)KD@J$3|SISP#9d^x7p08tlP`aZFv8Um&6aKF(P=fDWSXg`8y}=lJn#xC9ctd zpaJm1v!D?6=D5uSOFsYl=;_Q)!e#cxKG0Ot7bDQ#wg6q2W?Ua(hVNDi!8DJRiWESC z2x*dafKXDqSwSPa3a_*%8$CZ8G(-7t-wmp*l?&SzC#`}{PXj!h5(#-Wdb@6lH^Uka z%uDU0oNhg2cXXfDAAUChJ@O--m;0xlu}U81eLz-3uDSObw1)B9a8z!GBa@;qVJ@xD zZfPnsMfAs6KVopMD>jmHo=rx3(H>wC*%%Y;~Jy=p*azp=89a30_+;GZ>xuXCVN#WA~nd zZbmeU#q;R$nHH%tM0n826I)Jke$CawlTWEBOW!B%jxb~VqVm|5q!3>B6_R!1$HIP} z0S1yoEZ!0Lq!c}Wf5-s~#)$Ew;Ba5bLGNYQ?UK9*`d(UdTRKAqcHBgnlm0Ld1%eR? zCDBOpokFOq^u2e2r3{kL_9dWSQjh83*3M|=5|v?>5^M);qBwtTHXW|>TfqFUrZwd% zrdGc=x?UzlVNZw|SUy5Gbp9kwzP~S8JZv!zWK7hUiE=0QQHeZCbCzEbiY0Z5<5XZa zN-X~6dWFdvS94w;pEm?4#CK$^g&9*E5{bxtRQpON3uq0}PVnGAm|y^1z~}?5VMsVw zf4SG$eg^ZQP7AKUnS@iZ2==uO9$Qpza>Nk!brnA*m#Hyzyyl)QI{7T(Ad9|`%t%cQ z;Xjlh?NyKOVUP^T06ueo(GCfv@?x}v%MnGpFrJ`BlR)8vOQQ+r#1O>pJMq8#Q|d*z zb-HFQs=bv9sb>Txdk#R&@G_N99y^lUt+UJhIE{IZcr9|RESj{iIY~6@eeI&(X3P&R z5WJ{br*fe}I-GjO86_f=wi%_df^re_RO3p5Xs^1D057j3mFhh_*ia=O}GeB}->3-NOX`(KPlD1996~W*L6^{m1tgv{{SLbl)}R zZ9n_L#4@b85Y0KpT0EaNIJW0@AIzWF*Dyy*6`#gOp5RM?`+ufS^xYZ0y)7IU zJg+$UYWL$S!obSXQ7;@z<4ZWlW3mtIq8efsWgPW+Iaa=;t#{?6&?|kLL}0qs8XPNo$pJBTKP+1Rmh8LqIJTeo`BwdW6$cPO|F>#AIR+NnW8IIADE&O!`$||;QYgm=DDl<1b-aa5$X9Ei3_8s3KwEl zj5TF9pZ^IoESL%|B6`f_-$ewv3B`=?t-~}`%9R1WY}azu&f@w*rf%199Q1z;V=Uk~ zS5{OEfLceZGD$U#A&kSGTa5@Zj?&xrS#_P~1uQ<>jRfuO*>kGGt6%D7=Oa?DkO z5XZ6%F_^%ke&%Dr{eKB=Lm%me(u}HfvGSP^TrClodpQ}=?>C(CY`zCx9^yN!uotLV z>D4;_R{3~>S%VB2W!`9{Ov2b;F+#V#tDJWeU=6MrLw(-_)5N`O)_BtL5sOr1gVv7V zfUW=`Ls2HBh-vWwYXJ6&+C{-q(Q26>m{!L9Wuw$rBV?%F^+PVf`bHkh)b#&%lbp!Oet%l4he|Yu49ctu><~=mC_ zXW+LP4OtXEUMGDv4PHot{V`rIDT@WkfuV=KK zSRdQaAiN^gXi5->Z{f&#iZ2!NnOx9K=wDrS_KWrcp$cU4$|MHR0m2kKyeqMUiZF9Z zb?iC8;T~4LPgC=W7SE+wki*78$$ueN4e0_(yY z`@?m{j_)b#i%WCtUsJ1sFH2oLt88D2{(FQ1@7+67GXq+!b(eXmBpg8xzGt*Wg+ihDZl-EN=t@G(Lcywh&@V zM&TL6DYXzQbdK*vbe!Bs_Rk$y%%p&+2xVuKfSZG?RB=UBm$CPkg1+NN3G$q1>=>9S zW2LNtBL(Tp@(iKdPTC2y??c>Ic(0!bWuY4S(_B_BZe@>Lz|`c^_RQd+not|ZcBg`Z z$>aJMMo^AZVClm;Ss5bWV7pBqre>28n3R!-uRNqWn`p8rqTS!?@#%FL{AUOx_I0Ii z@?K2Vec*N;wpCTW}q^`Hm78^V$CxMcReu|y z(n`&3l?mH9s7I{XM{;?i?RYL7zCiJDMx3sW-|aCR;th(VzNHsnfD%gSD*1B^_PnoP z!K4>e*Z)=wjPf_UUkmn*x|#gSndp)B#bU4CCXdtIo}|D(c#!TiBO0DIvj+oklU`Lw_O&XVwWARNC4!xt2EJdaYee>| zdeu}!_Ky42Pj0p@g)#qjZK^I|zQS3hygpZsrI{-TRM@+Kuo{j2p)E9vnEm@cChd#q zbTzu8MmMHGwZH~ft%{P4s5OxHtQNWL+3fq-&eeQbIIXSi&CShaRR=LjBsv?y>@(;v zJeSbJq;@gNe>Lr0+YT^V5z`AG1R5jU>)xTE*fe`yP%tJhttYj%#+) zkK|>FdYd_+e`G?M$sy9Z(8JUS?pV+suVJWAX#4&MsAIat)IMF{N7kk~?=t}@$(mjj zbY7w?pLarK-bnL@*q3c3+0IBif7?CwK-@>26N5Dv{2&)buW^4UXg-6~4JF#GeSX~5 zR|BO5?wZk#Jg)^{mRBTD_zE}Dc;X?OoH6!w;ycmBe|u%=4bI$a?O86Vu&{HH)F?9H_!ogHw>^cb#93ztDWB)#Evov##{v{GreEL%l z(`%(uDL^B%G9B;UgY(3Nh-?_8dIi+^;|?wdkTnDQ^Sd>9coVmmFdu#|_LoZZqF%o7 z~QtHhe5zMQmBN=1AIhIBq5o+3$rU;O7+!c^1BsKADV|W$< zO8eO2Vk8uGSotk8$_azd_g@OCpHXVU2H0{~Rt{&X7S)a3Z@c_jjt+4(Xsc3hER&*Yt z1;diIT^b@@w?wZuw6VHi&M7HGb^HY*%pU4qKb$(*xYhzA0GJl*PWqrMssi@dsC}|a zCW}WnkRnM`aO}Gq+a1_7mm=I3fy+!Lv>Mle_pOgJNQKVtn@Hhk^I)IpjUaP?{&pG7 zits-yQcQ&72Qy9Idd7LC5O)NF9Bg+FgL8eb*q>v8-o9D)A#xI=kA@fl4l6XaC=*0 zsE$#Z9OeEV40=HZ(gg|lBC*y>5W-3=OxIxj)H1O*ZQwfJ7cGBAbV{Evw}-JdQ6@mD z#z0FJdccR5&4WSkjD%<$%1gp~=A86z8mv2fgVr{+DoU*H8(o@Z!^Ok{QlxcJd8BcZ z8bVMNurJ{u-!y8lR?zk|D7 z-96NFIj`hYuQu0yMY&&X2s^KIdsP^`;~AvM;TaYaU6rkn=`*;baH6~0xK6pld&smP zz9qiNWCo6K7#|`L+c)+AW!-BdG~{*1ZfC^V5Fqe=zxpH2A9AcaTF%q(qDi=5NWctQ z_a-EZaPPB9bDRFC@(+I&DaLU1@1TV&}V}SQXf3?WKeT1$g)bH*by}{!C5x zx)utuBmaqcx<_8Oa?IggPsYDGij4XDY}7gD_BHxnp^k6ABHs$Ii_inxQUf73rraNg zN^K$l-tJB2->K`C`_aFJ?oYk$-%ao3?pA~A>G-Q|?R8faQ^+zb1he>*AC^d!2`+k{h04m+?N(ySo&cXE~Y5L zY@Vt<7fgIR2;$9q9aXD} z=IPFI73<3()+Us=x-4j=8pzS)+%Q@lml)Itjs$9!%lq-RqHg9Jbe0SB%*p1s%eB=I zult9Q&vf=j!pY{HTDD6m6%GHZ$kV?$q=p44o>86^yFsA!H?&VJyx?wKmsx63uJ;+i z=68+s^xg7@tb>SA;tRUt4`+w7+-`sTAF|4h2+9nX!eZ7BJ-&yg8v)fz9#JM?QU_6A zwnbN+5&0Blst2bpW$sPScl%W>EBxwd;-7!cPPI0QG;XH2QOO!y%B_Tu*hH1n|3CgV z*p8_|7|1}8=?daYJ?s-TIzJ@+!8KHRH@Cv;dD}alkO^K9^|+Kc4WW;7hE8%01MWcA zj|^EZw$Rq0Mwr3x+np)<))E+shD4GHw+%}>R*qLn+S6d9Ry^p4QKYDFajn>_nrh+J zMCESzrYEuh7GUC>uh^4%=zqYMN?<5E-{3d44Opnb@6WhG?FBK!6-B-@2QDU@{TCDv z5oZe&=_hLVROYFG(ik)OZvIWc@Mo4`?oKY6PR{jXK7Mg^Cb8~$(M;si@_Q4UBJF>t zToePMXstF9F$l)#WJKhYRA+bM1Ic#gV1#dkvajc~1shsKZJ>NHOHF$oXr~)wrh_@U zfQ7Du#;#BGn0|iGadsWm`b7vW2F3JF)p(oCzO8ILWjqF`5ccGKN4N&LpYs&F2afYu z7+>;V?B7IVOL3t08&pp2cxLuyr z3&j6U((U?kYW@0q_r#d?&tGK*x!SlxXcI&(X)tbD*$*d1QuhA=Xh4_0%730Gx7Qn+ zbwzLtU*2@IszX*^7DKX;;E;q@%7s}bGlDl{CIh9-@bkGwh^~; zG#YITB<-~9=BAaH#PZyuk!{&llDpk*wKjhg+8X5tyVV>uM+KcutZI!IutE7@v_9Gx zZ7Il_&)-;nGH?+JiTNxaXTrNfHQ3cuUw^Ylhe6-egwa%f*lKKHs|5iIogh4+vFpw# z2Bcut3-#jBCSH#%g?<>};h;Ta8M(QZEzOFzN7g9u0sNtj?e_LM!9|!@bIkD#PAz}i zSp-IwD1nfC$HtU|Y3O(6QD2tvb(0K8FL66|Jr{hG!3F&z*yG0L&paH>$a6yyOPl=` zjIh&XqqN<${3CO7m4D=Ju9?n~CD?;)cpp!v&_DauSjO#A8a|#W)G9monl%3xYE#~> z*Q4BW7KeE z=ci*0&&bcWo*SZ5Z{URi@NX3>wcCfcLH3g9!)IVdp^DDhgYiq8kZ9P{TxS~C@ zw#Knwgbz8@<~FL)|7*EkW=T+JM?+sP?9l`3fR?XUtjBhO`P71`;=2yp>4fr{dZW3% zdh(j}^{p*ZYhg9b@@lp!)zg1ywOTDmC9EXnm0oX_*WD_syQNpCxK(ehZ{EM+wm_JT zwot`KQgDmS9evlqwzHTKVohG2;_+f?`Ls#-dM1r>BB5Q}$ab)m?qDNAlV+8ITKeXC zg|b?e%33k%4ZRK>Y*#6(3Yj+a#%6>j>s88Y=&MU>wWJfWA?`(WeJg)g&iZ5RMeMvF zoLGe}ttRsI0%8sp1H$Jv9;2RyzPVmjNhLZ=wz=Y6zM-#gN-828mF-=F@{68eN_~D) zgHyf*2u<^w{5h{7o}^Kb1iYQ=4CD#YylTi2H8r8O_43+c$f%OqTD-RA%G$QdYin@` zs};4iR@cVSu%tu4s%w9j^q*HphPz&rD6X!>iYlvay<`AV)wLg`x{cD7i}h`-tdEbB zbkJFSo4mfpD$3j_N)*?(&g*Lx*SA%rz7`+P=F0juR@Ao*MK!C`x3RLmjSBVAzO`3W z*ya=1T3I1X(5rSyg@hQ^D^%F5udHyB%}{BDWHdL6Mys7Hn&fi!enV#(`6}Br? zxV@@EGFpu)6>hAoaEn*CUQ%H^T4fay0^MRYmsd!ru(ZYvK3uD6Y}KpP*jQELCLgbr zH8xk)xLv8nEk0mnHA1smZC3S)8ljw58znUoBHgZ1lLePuc{Kpv$bBO%I4}SYxZhuL+)EK+lU1i4P+chR50(pP^60=$M!Ra-8B3_OUzUs2cz) zQ=3?U`#%t75W6)%Ds-$Vcmda5)q=$w`>K{o0e}?PR+4{!r_uL|RFi^{1W<|uQzh0B zo#N3H55v2=7wjoPzPP)~z0!k;HDkaOFB$~sBCmEj@x7Z{o~TZsR#;~btPmHXbmS^i zAvrqlBSEDDCPpvn3}_|RcR+yDxU*hb$ESLxrE0sm(v55wJ*xUR2i;qL#~00*e2z5Y z0Hn0~mSum`2aapAB;a+F1cO*x8>tSMLh-I@$ceFth|jlxMHDwYNIIkjT)h`y0I8#; zbVs|1x=na%NHstg7o_@&i@Q5%E&z20uhmEr$|srC7H_Beh@RBW*IBcg*!}Sr&Sw#bU24?7Qp7Th4JPo2&=mw5ZANh&RuR2gksQ`Z& zasLhwjM_A=P;p=0SoSIYZGnT3)Tkt_wF+8v{XK^ClRNi4uo-}bcIbvqc$;kxE@;oi z_h`=<_OGyCwF!scd6FQ4$kZ8Do}#nwGeyK)=#)jjehjh~@)WLsj00j0|B@RSHKq1R zP0>E7**BWF&3k&{dow4%x(^ZQ&xwESG^qfQ04VgM9PcQ=Vb7UiZxKpj+J-8>=FlX7 z?hD(IhWc8RjWqS0aV2}zaV0y?xRMXTmF)g?a3%LrMBF2|lARb&lK$+`f)d z#iwG+r%J`dio*zZUE}Ao?y*j%${F1PdWf_#h9emmOMt4HhlT=-6=P~%e+?iOq{2}6 zUIB3{k`$2`wfi6?6rgM=kAF!$7wM9WHvvbV!I3}4J9G)Lt``2Z z1{hH_a1k}dkm;xf2>PZFI30f}MlJbiX~`X7ZH*Bpc0(WBpInJIQ_R=Gg2_Tw?i4_> zJG;If2r)i+d`uTPn!yjIl0-suOf3n_x2t zf5|WKdodOA2Yz!ye`erM*61aoB` zc1}aNjJo2W-biG5JgDkawMhTKMTta9RS?d~lu~I3eUd~TyV{b7^>L23-y?|K7qcYf zy}6{IeRTwZ(+y$NoRNRpSaZ(neO9xRkS%$R5Cnq<7%XC=#nx_*oc=?h$T|lJ>sw9|8B=NeDr1DLYz%tM4{T(oI zcH9M~$uU zC_PCHzfe4eki!v^Hd9HPeZhw)NCaSHl9>)v`CyM*aX+XHusIV#?nzQ-=?EpdUN6q$|GNFve}g6cqT_PTA1Fhqk5X* zLd3b43$?)OX=)y@>zAnpX2|J)L>|(FYjdz07*mhoetNz$hPYjbgrC|cx*FbqOLZ#n zD`*5f7CqJ_;_**JWdf9nBULzvKM85x7et(h6Tg2?0%*K9zp9eRO(+&&e4)j}X`DE0 zp+lE=ytg_dwOMbI$mUcM!M5r17K&Hkc@u@^GV1T}jhGzqEd4*tX1xwq7W(t2R=utz zWi*8{unzpPsS_y3FK)u zrFnlg;?}g$k1FQ%tQ)K()6szgQK{hM8t9ZH*q{yBmKM5s&n_N{UEIu0!g^}hx8)7q zVh#4w4Zcu)*5GX;sqZWvn?~K>E$u@{Oif!wt3L{a{rjrKzbAzKdxo$J$T?<=iib|n zurVRrE`LZv%OsE~1tPixC`B{gkvY)mftG*g>*(ixr6GEk^slOPFpAK6y-^-b=;H_G z)B35&PzG?1feVCN6mCHD)@yEVuczHy1xWK>Pe4TlSox|F$MDh!{4Zp)?3ToqkkgF*s|!{;8=tpxIS2efRZnOLa0= zFCpK@52}(zxlq!IcPIk)a)}TL=&-TbXf`U?tR$iT=IyHh-Z2u1oUM3^gM(mH&VJUm*nwBUkrT5IWO2;M_IGzevKDz(`A^umPTq zcHtkXjP}}bZSQ)Q{)xp9rmK&4U43j|YM+5D(^nk|&Fz_1gqn@b&DDXwy_gza)S-1C z^&~!FwUOn3xz0{@fxxy+MTx#9N_-qGB>-|>f&k~G8Uo1x>BbFfG&b8!m@|K@;~R*b zC-Gdiy&>6eVELY5&?%CyJEU^m2UPlffI8Ij@`h+9@ivc(0e8DAj@OP{kX-v_eaHVv zENsVr`BI}OJ}QQqPvO&EsDcI~0hF=E5Qabxy-)Kw_V=v-s~QWXd~|&BsmFpN_YVKv z+dDnnQ;bj_Oc%b&t|0N{i=u!3Bpj!YXWkXwn@&l!0q|r=uateurxH>ck{I}vdKJlTbv*9`oWHB{{3trJn@IQwD zv1A<#$yP|_A(V>dU>b+ingDK0VA;Ta!DTxoM`RkSn(NtEuk|L_$3%Z9;MNwx7XUK| zCm8I`=2Hg(L)v2;faF};30}S0(Y*7Ze|I-k@p;fk0bv@>a2PYgf*^xfw*dDJ6wWOk zC@W8-p^m8_TIaPD7|P4cHjRbbqGKvblXvA$Eti%1cL!gyG2a{w;X= zrh2N^I@Tq0)W@JQ&g^nW{D#lG1DqK(VeT za1jbMpIzW!#H{mIuRsGP3ZgTy^jI?x)u3@I+;M;Mi3W|`wTOQXEhJ4L!ZXC58%bIS+FFRCzo-p>~*B)cuE_#gpz*jWGDz*V^P+uEY{GHt)yD`MHmJWe$nll;knz_ zxE0!t#Ip6ihK2h?q>OJu?Ak$%h>&W^OLkumwU-KPgCK&oYJz4B%($RTC1oH0w=fXy z2sUguq9Ariv_)j5X5nteC{Z(1(KJi6Py`xeL13-Cptyfx>~=)tw>f)&n38!yhfI!O z8sPS;&XhxE%7K}3`hpR1(LHA;ZC1kveg;24E7Yv;NO8wyz|SJ0WPN3E?}n zM7<8Ci1$OZNydk41gp>wou7O@z|PB;TB=bnHnD;&>C&8)augiKW_EGMXddXxxzi`z zfxn4OaOQt@gNSTQdSgpzUEE!45b8>?FCmpgCF y}MIglPQrjO+Yk6mQWA5tiS=j zP^qM!T>t1SH%jc_2QCTp`a`GWGZL}lix%wSJ5ocNJm?mZM}(LyEoL)>~ggg6PB z#!V!myjAkE%IH~T^sF*^RvD#KMxtpy<;Q@g*+741&e8aM0GqHnf`;<_|0j!_0WbWu zHF~%LJ}1HGq-=6>1Q2^4ewx;i188RX@8$W*3W?u^Qm6!)0}m-=LP>rO`A^)nOvb*NuApuCAd(fN40QeI%23 z@^^n|;ZF@PKBJbEpH4qg+^GCUn6;)zGC{dogg_j8|9td>NhFP0ga%V@P@y0gt~XO} zpq?j1_QB$DI0bTBBt}MnxF;#liV(BKk$m(bG{&LKQ71SDDauFhnoCjo5t>+m+@~j% z5GXYOv!$398^S9`_vYADL#DF3yHmy(tU`a#3jlP}J$LF^wm9<+Fi9XlVZEk^PJycF zKAum(ru6myQT2c9YR38h`On#Z-2Ok*^Zx|@IqUypSNrkxc!si`RLrh1G{ba*Vb366 z&O_w(H3V3OCP6oZe_kp`dFdK1!OC3#6F^!^g#D(E91>V>Ke7KZWBV`DBuqO005^Y4 z+64{tBO#-H+AVdMd_Ern#|bJFTMc!vI-{19zH zFq0;`+xc3Wc7zMNAE9=$y-CD#Il$)7Oi4kLTw#Q^+M64#w9NGv&%eY_;O2UBJN?OJ z<*m5cq;HsfC1TiLU9-O9=7BzA$%&u3!|kN*cfJ;KPAa*ykxNDbjTxc!W@~?=0UZT_ zWn+UpZML?yH)W#B?_;7ZjIbaqxwybV$Fmnx3?lX9JzGd-{3b#ht#*Aq?S$#7q!U?< zR*C&Laj8q1;ykb^8;!<#cIcka75JOSa(!cCyDppi$1~^q<~D9^Z#K7NZ4_t^2u`wG zLPB{0oUAGSxVwANKm^h@c65J(#wdh~RA5a3=&jD3;=r^X6(RrnfU66F+LS1kUfL5A z+%V;l=W1}33W=1XuwW%lub^e(pVuH^1BA`zVPo6cYBx6WWBYW7$KOmHje5J)&h$WF zfa22A61CmbFXEW3YKBzGwi0|gv5Uy3#IMi1X>wKkFZ|Xn;Wg{ zfHk%@wzo8%JkK#nsPumqY+ZJ&xhC-7JBcoheMPSLi~Hp}QrLi9*9bFiI^OBh&op>oKzXr#JpYi`Cz-{n5~R6(HIOSp0;Wy}YuD9bmIBQnv$R-SQ;C04`tEK4yRlYqkXsP2 zMl-DQ0NC}QAN%_yWQE8$QOE*ILzY0E)&t3NyS=?7<(|u&E}6PV;(E!yq#Q6Mo^kjQ zcK&v=xz)(A9aY>RgE>gqi##E}k0a!_?K)yd7^I4HNA7Ek6x&Wiq6&kY1Z$nqa%81i(g^2#0mD>PqO-Equ|
    |*lmM^Iy3wKg_-9)ZFNs3Ow+%mVJL~ZjzLieM?_bMbTE@RLGMOp;mnx zq@l%zdYv<7g!kng^Ai~EG5fq}kg*I0{%B);UE6Wht=9H>Ge!hd8?DBA8@4>UMAfW| zc0ANNv15a)f3UWekz@Wn8>U{7H8}L9$;(9N?c(s-^DoIKBATEUwb(oewn<)!O*9!A44U#$gou9&b*iCh(o%DXrXo)v$dR}$KB13adm4eeKw-pC zj3TtP-fEQkRD8(!C$Y$7EGAGkNxg$&l98lv96f4Z~xCs0rc{LSxroG>H$MYh5{GV6lKS?Zq$z ztGS}W!6e=*<>QJz0r{c8^w!qcZ!5TUhewRPLkmfvC5@)uNqX#XLkWpF+(h6KQmMy_ z0Q-AmC?JL*{TkTbOo2OJq!B&W)Lg8sy%1*?C}3EukN@7N`NGyW|PU_SCO{v9W-IP79B>VV_hbxIUW zZ{DFKD80bW)Z%6khfmnm8trF7 z++myzJV1PM*#6=)nwXim@*_eF6BDcxX|^O7Y@ca*?w5Op0ue z;x1+b?2Epp7IlMkUn(^OE!+Bu5em!==$zlMw5U(wAOcGw`x9Mw#_wv=;8eUps z9B7K+X80*zANjDfdftDDHwQar%3oP10K{%lFXTr88RdDJowOM#_wG!5=oet;4n3Wk z=ZcL7i?M=~sR#dpVU>c|l>;e(GsSMG^wG$iCc8Hz6>72N7*WnhP4ZyvpXP`yOO;u1 zo#X!99k=M3dSmXi!Cr~F;bhHDxa}67aaGt5qDb}4;oY4&q+owsq;ICJvQ9#%-l<1k zkS@U4W%(}rCjEvN^x9>sYzV0D?c9|4)sLs%z?$}m3H;sNr0@VO`U=j$Mc-)IMPDc4 zjbBv+V|+zZHMZ0SrgCwipqY6-K!ZNJUK|{L7N>5krUsK?4)Z-(%i;{zqNQdTXnsEHQ=j82b1dFVZ_9}SM&sJNT{(rfrBirYGKIILQz-j- zyJ8B_Marb|P}P<%uBAn#2UK1g!|;XA1viLmq9lhz3ZKg*cCU=(arfZx;_&!$YHFh> zH&umD-Lx-tK?ZQ9YRikYHI@2`)~kmNjS5_H z*4y&0WnEO{#FrnA^~PoeK#A4bnDd-)OZqHY)Y~kI~-cXREos z)oiRru@HYTP1@@lMTjt}^WUTKAT}q|sH0Iwp4pVEn81bbyr1_e>5q{}Kdl+wRnFrY1UPZ{gp@u=wBql5g_guF5r$v~!)Q$*4$Pb^C}SG? zpRu>hRvv3vPbfmWB*aN5aFo2{^L@u3LTKE+!ft=}=lukR7Vf?XI69mTe-S$t`7yFJ zI4ismnw*D{b&Lf>!eKEFN({J1L_eRzK1j#Wn2OHFnKj3lv}_wsg? zbLAzlWiOS!Vkk?vi=+k7v6y&4p#l<6442+r{8-?OY6|$BM@lY)i!)M*i8!~W=fmAs z2yTBw+?@CW8HBzfSlxH5aH7u~0K|)n5l{_YxyYgJTlJmbCwJ%NOYm_alJ*5f^$3$N zL=8~9@3PN|uIsf%ZRYvJ2xX>dhX2n7cycD6W197mlB5h2O+zq%PHF)9LjUbVf`ZSv z1Bd>r)-MJi3U@<8@*3-o8_e-A+>M_&hH!uSMpNLMky8yOE=>P9XT|}qk)jA6`ahBv z8O32J-L_KORRRW+RVVJql$-9_ngT3-tX6arY>Nny4SV$-@5FojL#3T5xjSH@d=2zP z=uG)=>%&D5f~=88t8SvK>zZI$)-P1X~`l=v~bxI&k|@dMIf-J@5m_f?#@^1X_kVGi5Y_2 z0JyH?+qt9v+Bcb8z$-v5{r}l}yX7{LZB6WY-U6)IhN=!z5JBp<(A8+QM0IPoM5;xq z{~!#f2qegAf?4RSgeW!u$ArV-2e5yAVLNPx?F(P|!k4xqY+r5P%v;P0_!S&$<$qNc zDed0-#F_Ewh!#;*Sy?MHS7xqUKi^WFg}4)y$hnXJf?VO2QZ~&1!Fx(;#1P(E1*p;NXj5Yma&ruGYjvT3TT*I<@;T*|(zZfc4Hr48?26l|(VmCb*18ph;L zNGqLjg{xZ5mzOLnOH&#YwPI9`lR>h*U0Od@8wOo{S;|5c z1g;N~yLT(A1DCY}bc1VmZNuaN^MXO*+1?iDC)q&nK0oag*mIR)^tQVDpS{$ARbo3#6MyPtn_yU;BfC==o{ z&9_|afhQ7^U~f0w-Y#lbX1v?oLdB?*oW^e5=3l)yT2Pau>E1mc^YQ zs$wHaOh1?;rtc<+>5tPWBA=09rrUL|2+!{Jv8Rk46UH1&d>w>fLr8<@U+CW?&+bHb z@Pb+Z1hC7!e;+k&SJ{6SU$67^8tm0zXEUO11waxIi4Q%u+|J;u+ae*$?F^&>vv0p= z_s)oVm{L;N(h0c}MbVw@r7avq(Y-Tr=ly$lkZj{~y}i8pMQ<;UoB-cPdk=0z=sd5P zW__#6>fq_?{WJp8Peh&{K703i|KK={o-4~>L=NBVzkPcA^6-D)^Z1J3aQ=y;py9#PrrV(@0HZ9HEzM9{a5?Xu+F3X<1{jmf#A$Egwmy_+Yh z_v9nhhtFTWh3@`gKaHLjoFcelL}1{bpB(@EMh*WI6OMo2*VJA3q`Y}>cyI!Q>f$8> zg5|TLXW#C>e(Lq)(d3+7=59Y)E`l1utOV70T=MMctEX?9FC0zsdCu#lRr{OOV^7pe zV>kJu4}IkpL3GHIAD+H?=U4cWEtay={nE$#Z(lrpw%?@SB@>j-@(HaI@$MklA@5kA zGk`0aMS*`yf+d?|8-{AOv90T{rQ!ZFEakmmxXT|#% zJ7ryBowAlpr)+IdoZ{Y?IBz&Z;*>Tc;*_)l;uO^5;n7gK9X zUds@kQwZRZ#d@8$bV4C)A+_2SX@v&WC5d{VT){I4z>ny&6xy-XQA(#VIGoKYD$J?M zyNiD(nlE=0C2#=-1-}d+g7xpBCgDBM`GJkAkp(23 zl=psq;bY?%JKYhUcB9Q^oYYQcbLV6Rz=RV-1%LAB;f)jf=NC1Z?FJo+l+cx~L~E6f z^Rr>|RvLZvm2(M>$B*tm*loa*SQl>x3H^W0DtfvcX#l zvJ_N4>BIG;;1hYd3zug+|DYc4z_nCe!{r0G6vce19`C{R@^UV(?n64X!#6+URsIC7 zCUjb;r;j2M?H_-O7gMNr-ys7E?^`l*xOB*P4AsO5`@LdLIwrT*6q=Zu%IGd$>ZhmB!km9<=Al4xZa+m~?DETnVy4`12ZfgAw&fH$F4r_s zsP&Y8IL*0iFH}3R{6T>~?B(fWyktTa1_~$T;@Yy-WXU;Y@*1k1Qc1-rkT)#=w;8Wz zP%m}b4lh&NcIa2?v<|*Yg&fNn)J07TpwDMKpY(U-m!|sqzPz5O>pgW1LwJ8C6rUCj z3GiZJNq}+%{Wy`I$zgB`ha#x9kUI`m3yfPBqTp(t|F$gU%Ru8?D6YQDC#tid)MYW@ zvefAVyqr!;RVDNhJFOP7FtnPfM>%|**+HEFb){{~3_lnw|Nh_qXGEg@?&Bzp{@s7_zrgQ3xc~3|&3}Wxp?ChD{~Ukr;_d$) zfA8V%{~3SZ$KU@0{(gYJ|401&FiN9;`=8;@M|k^x#ozFyzsS;0@b>=>zwg6G|AHU7 z4G8>;`e z`04{}#(ye{Lo@z@ls}MP{Xg(GeDyD~5~Te9!k_S+zx;2q(;q&1a{u8ccRB)^!GKbR z&VaDEuA*xS%jPNqb#_rMftBWYB|3OtFNVOxh!>^qV%o+O|LA{PiyT&wRa7$g#A;`Q z4?6i-iF5Cqa_4r1_Ys{Ivhv#Z3f9qOoY$PY6*wkEzb$hvXpnCGs6o1Y;8JhzHXERx z1=^sV+|~?Rd95Y-eQeBS$zWG#Hbp*YG(_Kao1yPD8-Y&(O~CuNH9%KeBVWFY#9vW* z5uzRMH%M1^UCMvettR2{AV4?VzKv{EXN_un6N#SY*EO22X(cF!`yS1uyrbw9k+ z7ioapX?`7`cA8(`My&iqjaGOMNj)!@$mX?<#M>b<;6Z>6xP2QTs?HiE_@?C3g5ieH zAVxh1avwelu^&FTmH%|jbq17gBUu%ll(0FwWU-b(l4XAbgg0+n0DGb3uh&@oYCUyXw)GSgy=m3D2z*f9^wzA4+6S*L+CB(H|HE5x z{N&EUqdG;hKB1)AVjhoTwa0fh|B<2u-(h*8uyRQ0*LE>ni( zNstKdfTsWClMDKB0LN>4pg90fFTVn&JX3TN zDB5Eg&A!xbXEm5gFpAKgi*ZkzblR%WmXZVFBM}=CLwSkBKtvWqbsf^|%Qm>zl)|@7 zNXQ`cK?l>FshouUu7vV|#TC$W$m1@z0Fr;M&n-A)-G|c5Y4UpAe+c(NnNcx?goTb& z4yK{__Ykd^0#w6H4k*A{j?hs}0!fH?1o`-4k&GQby+9;cDMdx>wi@ygEB*3 zwj1KiOB-iSvoCYtM;IaIhO}E4NPI-Xqg((kWU<*KaS|?(p=mn%vYs|BRJc@m;`!lt7Z!lk(+Gc5|3EtLD%#mUdaZ7Cs%s|lj|BY~XbuMNZQ3iQ z3E&LVaGOibL7xbkD#F!pT-$B}8EqPE+nKFd*2L<{UW#r4PPS`|2@8eT#4wvOHRiOp z$i;b;Arw>lShw`zB8%?jRYgU0FA9HVqHq9kVX`IESjv4=t)9OgAaEfKiJuE92zcLvcO4ULm;FOEH#8@ zG99$Yh1sM7Y2(bT!gy0Ox4M5~Sipu#Xp)M!fV{`(mvfd~#>wCe^X=>dVw83f%`OKj zmK<5*I^59@?>~OxwCw8U{B~{xR{a)FR`8G7f$4g!fpxlF3$as{7X=`NMVQe`ca6-F z9ld^f{OsG4w}MUIXPKn%SCeR@_7B&dQnuw14D0sf%e^xxU!Z76hxFY~ql|g)z zD9ziB*AjK`elC%kd;fpxs;Y)*Z~I;X;XIKIA&h#RpUb86|A7T1?_AN-s+?R<(NiFG z`$6XEKiqrZMz0_JJu}ysuUy=cT;|9_HvjmK1#0cZ>Hl#k>c0~fwW0F0Gtn;)$Mqxr zdx-xYyTAj7p9}M!NK#vpW3j3P2G}$e+S5?%m(p zO~~)zZn_VW!#8ekO9ZxfhwS(Gw@Dn#k;3T|{k?kvz(;lbw~r+kf8G1xJA&uR`jc;a zzu<$U@#I~PSK)Ww^`8DnR`g>&5pYBRVKg;+9vBYH*V{5fUV7A_QhW z(Rg7DfNbTKC{t=nL>9Sc)ukLv98M7fW4)HSS{e{;M$B3<97(1`m3LzKYMKBfh;o-fT9XBHzf?(tq4s8+N!p9lo6A|G&X6S50*e7V6I5TWF`{ zzZZcqv}#7i0O^g;7%G*Ze_i50-0K4AoLd7NHiS-sshpN^((UR9CRr9V#~VWD!Sa)s zCPPyWLLs7Ux*5oNw&(=3q7~&IFvb&xUrm2DdsoAzdj;j(p|gz6Z>yAB zqKXrTM9Cw1K9-Y17D$K}6i$zwPq?}wFKo;!b%r3kka+iODF1-9rJ~}vxTNJ$xT1fO zY%txptKA29zn&yp<=1v!<<~0@J&>M3q?=dOwc95r6JV|7qGo2pWz{@Xy+F3K{cWJK z4+m4oh&UMlzK|a01*jmF%t(b%GQeb4D(kw|rf?({W~)Q%l}rMBA~}q5O$qIt{I;Y^ z>Rf|ng=W!YURHGKpyALHuf6yh0swzu#VxhSLl7ZW>eZ3Aj-&`^V8<+ucHLV_K)m8z$$zd;3s0u;>Wl4990sw?mnqrnX zI0;Ja1-Mq&rKCvQf`|sC@KxQn;9LL@hf%8Dvh|x`%W>H9WTV@i*>(?+*HVAeGUpMZ zxA?v7^5~K79$>OShvNOy5=u$x=Y$e)m^s63pa%Kjt=ij)DqFo}w^6;i zF`*vaG};#$?l5<4+fngtkkzhZxYX0l&}71O0bk81!o##s;CzHr9cua{m)vI&)dija>U zH**=bsNZV|U9_y})M^453H{g}`>I}$#4g}|CO3Ew$jBnIAX<)xynYln>rf6>1QM(Y z1={-wFDYDO`IerYF6}MvnThS(WcL|p~(hRP#(;I2U1FKR8u!- zn&<&b-S}rf&xaX&5$ox12}O=jo(2JZgA3FRbtp+9Zg_G8b9}CNZ2Oaj#V@ngIUq#I zDt9M(4CwzFAkyi*SayGeYmSm~j39+xgg|1CSwd{4rTq?#3%;hF-4R9oFP>2k0nm>zH@A~VZGjAEeV zlVUC?|EJ$K2>c$Kq=f&toy6&MIiY{APExY5>L0=b=nA9&)T@8ogH|AAmb>$qeSXKv z>9piNB_wVLXd&cgrTYP%k*E^)tEd%iizg zaKKuK>rMsW5p05IQ8m^jINSvWPTD=a-N0Ow}=pO3Zi zTaBAL6h$+W3dw)7oqF~$K$&YB9S}EU+h~xF#V!4tyP&JFIV=gMmy)!M3uQAK<=fli z1Ut@xHzdRr1W?)HFX6gcd=D0rc`jc6{Z?9kqO|b70mB`Q$!%K;DhwMdZ*CQ(s*`iM zQ$da~>@JbqIB@)?f#bIfoMg_zxE5B)fPR_nz;O#82`7JWGUz9yL@pmFkl5<4`jo1} z;Y!%0rKs2Kg4Lif$6W4CuRw;3U@9IX?E4#aVCx3<8PVxDV9|lWh6I|>^I6jaC!}{c zFRCH@lR9b4o6?|g*i7fAjZEGYP*u<=%9eF}WjC#ITqIjrRx~Ov!jc zvtg0e*x7&fV&U){94O(`3R*m?gM%5W2%ja^PqtB^e@w-lRgJo%v?WDGd2Cvo47Os( zJy%v)cZo7N8TN9pyI%%EhkB!Nz*LDis1)eRit z>NSBI%UNhw`6JtjBP-p^)5&Ldj)eVWHP}zpIgo$Q>k~Rhofgs1D36TvJbYM`Gqwp0 zL|?l)UodYnlMD(vr%{ntgeAsBKdgus5Vjz6IzQjJRvWcE2_>|2(4qZk?ehd6T+s&E z_8c8*TZucnjW~{O`%*vOVrw`iS|x9jl17Qiaw1XqQ#vK*WhLHHa3V!cPU+dEnGjKG z@(+K*{$90IZ1kx+c!Kb3WRp2cItyvM4{Zc!Itw6ZqOuM^de!==?aZ(SeBYzL#?cEv zB9hod`y`X7Nq9AKs&l(wp>lXKe1=kxN4 zPCHlUly#Qi=K{irLd=vJh~Ji!U-vqPkmY||Kk;7fMM-L!a{qoZ2tjU|K7dVDre=jL z(o5*ou)iaMyk25dCs~kq^T3kT>-=l|8=?{ZwS@qawsO@_2<@SI%|o}7`E{pnssT{6 zG)%<(2Y`;uM>}Jun-kJ9U1&m94%4Vvg-LHETyz+4)r?UZVdqDra-dXG^{NlAYD#}p zsjj;Yp9%!)mnAT)*6D7@cms-Em%|~su4hGgg>tU%X)zkh=_SB#>c(`8V&pRBIHR}> z*xH|Y88Os!k*fY0%B#tFAyxLZR;C&g-+pY+X1CD`d2HMXM7Jv(b8mwoIe|H3=7*en zh9jBFHk{mlm=G>iVD-cq2rlll{-uAFfL13boX*lvY7P3_5tIzdV<;715GEWec1QHU z%YRG{bv{W86YR{|dcJ6fRopt?*g8F&TvL-%_N`OaL(dHr{?#dLP zpPixx2sl*mYp0+K&l@WH&M9lreM2R`bxK-b;84jwIVCNoaH!<(8Yo|$`+k3oA!{Lh z0lY~^LeIVf^skAPSgY(|Q2wnf|E5-6%fF`F*HA#67gn1A>&*aXw`$3*4P-%DdCWwk z_a=_{MeR2VlcRGJD5$6Qy$W2F$`6!J%1eq8ZD(Fw76Nx4Z(o1#z@6pa zxMGrQX>Y1gf-7_qg6+?_7u*zBZBxK^3~k_gWDgpR_nq@9@>QO3H70+~p!y%cwogp9nQKY$h_-_D}g)K|*lx{-dCX_f>jlX(n&bW&kqifKBoy$zmDTAK-9 z{mM%9b+WN6l9JX+Ca8MakW~ea$0~JL8t};d!SLu0U|z>K$sd10PFD3SWQ6{fIDzi; zw^}TKlq3W=VAa(h=wjry8I+7T$jbcS@~c(wgAX41(Gj{KkSW%a9e=TokvGraz{39t zbD4X)L|`rx=H}IK2>Z!X59aeCuZHSxPx+rZD}eLjpY?1tnO9WK5lD5Y1^q!`v-}m> z-LTB^QGsq|^m~8IIs(G)$q5L7@FkELO84kuI+*?xm&sV}rF^K)Xl0V}Y*danL3h)h ztv7M9E9!evsb~|u?2u)~2h|r#lkmk7y@cFhlMEY9pT#9%NzXm>5EbuIr(vQ$JaOgZ z?_CiPlO=>irM@RodS{GKam2%Hx`+qGWpZa9Q%lM7GzNd>O*x zqnbh-qsR+Z*@L05stT)r@std1<@cX}PSG;nuDgotV7B{D9GM%HQJZA6Gj=|+=Pg!$ zgAa7OTU&B{3vhv#xKgcu31;-Et)ch-3bJm}KY4#Tjfc*5xa)+NHV41kRk|2(0AoO$ zzYcPhbFV?eq=sB;%N*_mA^P@O9_;u#+JoR)^Y7_G6C(RTKNxP~4zDxY^msa96IyFm zGTPSLZPh*44X$vbop!xX3r7jr7|8?Dvr1FiLetF^J=pWv;4zv$c64T6orY`&Gjckl z57-yH5qMC4WDveExIrmhC@q^5eGAKv_>y7Ne7%k?m-0-guU*eLyqB2#!7clN{MdRe z*6Ubg1se9O3U1J*8Q<3_8XMd#*%m+o^t2-#O(yAh?tlOslDq0%=UjW=T@Ri#QhU09 zI}p1DV&#WM?knqR1}7SW~f0CoI2J9xF*<}Ded9kjdlO?O2Ih#cQP%WS?5Gq#gOjB>SwZE zOC53=MP8#2X~wbTjkNAN^1cy4WQ=Mh9(;{~2%J8Z;c2WUNi9?F&9h|ZOPi~>NLo!b z#e7bG&+@rZp*Ro)g)3F;K5{an+g1uM>y8)-#GpFvl`}U$UAVhh$bJW(5jno=yv1vQ zyqFBYu6)w7v+$01_GJV}T4`5&X%I)}AqdNJyeTc1p^=t1EmXx5!ERNsh`6ul;6!9oX6H*35W z<+>fL1dA2cOVH?M^JuQupH$fU{lh$Ixi;YovUI# zmx2Q;J9IV!a|z)|LioTLv%mm_Mut1R7Ia|=jZVuziNB&&oRWchv8QdsL6}7y?*)4- zl4)SEgv+qC3LAqMm>zP)@ZZx@+;4V&+XAafYx8UY{u!{)(y6;|@9x$PNS=)-guC4B6GY-%>arR=lg#yx89blDKj#@8OiQF|K~A&n?GltR zTHSn^op!rGRAuZ$v-lK$rJ_j&=b@=S52-WxY&3Inq%X5MnP=19qFlrYxy1L1WSK1$ zV2Fx(*Jt)KFphu7cF47N@Lnc^4_{ns0zT-2_f>X1`Y;}xjjqPoa&$G`EVHwXuIeP) zA^X|RVE+q4`M!SfD62;MV@UXZA%FG9g93mZ?q(+#v8`ebFNX1dQU?HXDHvoi^3UE25g{Vk@4{>A&&v*}#2%u$5_S}3}49hehmE%;04l5*u zWi}tqN0V`SZuA^kmMs%F9u;g!2lH-sCQWM-X>$Ikp;5uy?(@VlQGuj8L{z0*365lC0BYHIu9{(9PQzR~$1PK6bltC0jh2kdNbpY@Nz>*=BuA zl4bT$F;k<;&Bk=($8Pts+qKm##|b$ds#j9*&QPP476b=>H!TSaZJHAt*t8-rlquhk zJd5jdaG4~-Wh&7*vUriPk?bb`#xU(!3>P3;*=aiOcBhh{Ibgpolg-t6F{ic%%(26r zh}~{{o>imD&bCp1oRD)znKRQiV5O2#=pkHrW(2{*&A0TimJLDWm4BcqV9p52Tbv;a ztG_i!7J0^hhE%;x?b~_M0)%07!1+L1q9w_JvZXFty66{T>fxn0?nCNizQxw-Ev;Z( zuf+%OxS$^>zYe%}Iq##wyqM|J0|pun0*-&mg9wLx7#GqXRNr(Ri5eCHGu#C+(^4M_ zI-JfZhhRRmPk!b2rntV^9Ye0~fb3L#e$srr}LEl^;=oh#490RmJZ%W*iojl|4YzEWx}tr5JwUb}x8| z;7H4=j7~^Qz(<7*)%{fd`J!+b$it@TcExEtvd&VC#WbpML= z+PGqW!KG8f2U~*^F#yH_J>O|t$N+xb@~jaVkY^oY8Z5`U-M$n52z)mwIdpVK;-`Vb zpY`;cl^o4|mi>4;&(-U`-`8GP4D4hLS_-7J+l`8uv@E%dZJ^Y&m*Z!Va#Pj!cXhIZ zqOF(mZa4Pkc&-dl4VPp2ARz{w>^3?bL~e+^9Zf{Yf!DQ}Ed3E70F-5QS1uf$YHWnD!% zqD`PasAC=0c<+){RenZ23(0*Qi&jYNYN=1-q%iJO8zQbkt;uN51{%dlZ^;XzyIrq; zgWmqq(gIWX-WgaBf15*yn>cBMfZuiD(Z#-9SHP*^w47c$v;W9{dPc=tnop^N7AG#; zBC$B>JwI@874zzvOG;f_26POW39Fh}1o`2p9Nr>YTC0^Mn zvehT7^~+*d$IojU!&qPjrx4G7D9kn=cMk%(LUSeQY4Dm&5@5o;09?Cc7lY63n#Q&9BPB+k$d-9EbPt@C$hxHdI`C} z$4Rs3v0L<2EZntTmwD}$c?x8B`hs`tf|XaS14K(VN|10ktrjJ#sP2`2Ugyo6<`tEw z#d$}Pqz*E&sLrAwo@e#=0(l}(z?J&@GDIVbju6akUrsbIc*^QBfG(AZBA%5~3Wyf(^E}i$r7~NbxfO zilU>!Ce%`r-_MQFa1EC7O>m`0_(qU^zHWEWs6~2;pA(||H9)2-<`$E$sASJ(;P)?Y zLFUG1<)WaKJ{yK0@sOaJcxRCg(3A`T*rdpI!PmXs`voHO7I$}l-Tp6h|9f!=PI%)m zu7w{o_T54r%iij&Plbs^qsp~jjEXU+dbRgDb9zOkK48QN_JzSH#)QLBI~kPlYPSoS zwpgz^N6+PF<>LB9$zRJMN|I4A&dNmU({3vV)L@RQRMd>v&38h$ZEoo2R&DrTj>HPR zt*)^iQYE|WxOf47E0aqvZOgfbfzkC3<^b zGF)vSys8?N<4h2dRU2j&7N#Rw@H;<##-jP1(|SnQMRHOOTo18J@PLL%t;7#)%AILSiA}3^@9FYt1ksOoPi_e(s^8T3$^?|Z>do_0I+qdU zot@OEsIx48JEkASb2=%fkW$IrE}aMFsIM^cG11^T?NIii;3boefD5^87MGZhF7GVL z`Sq-r&wEiakPD$xV;n8T?C#?T5{+r|0c;27xan7}{eWrn41>88OFu^@?xKkovXMon z5b2Qf>ntMkOhExH^;^rHQd(8EqZ%T*ANs??&^x3M%>0+KwXnb#U zCmP>7BT?ksdq0SK|B&1}yTsdq7ngC8Mt37J%cA%EJ-d6?Xbv#zSrn1;3}q~`04Y=r zRo2J&{!SmpYHOjSn$aHF(<}VwJ~>xM&ao`Jo5Bpa%;MARRj-092}zpeW5=0*@W77-G6uKZ4bcY%jncrL5-m9zF9 z55@2CaWafwgXPhC((T5teej**o_d}n#I3Sc(tGE10$FK{7j;W1*9o~`o!7(Hj<ToerWPTBIEa=k9~cL>0L!EQW667hp`B6K1;r88p$Q>Q&XJF{tRqg3)P z`|@tzIza20#`GHI&nnz{Wf`{J*JTC*0I!No?Et9)Wc9J;%WQ9Fr`r|JT~AL50P05E z%6xvpN%Cr>eQ-65-m24+3jUu=XjRRY^R)ApPH6FgPF3!`4yED$_F;x0&5TjSxQv)Z4izv zF)TPUEIrIBT|$nkzo28cH*5ZXd~-rf(NjA0MmuzY->?%l^%5Q&YmLvrv-q#&S7G>- z_$Lr>SQkI)UX#0se@iX%a8uDBIoIehFp<+`Q6caZ=t5*rkww!AoOxO!8NE1_P11;} ziSB?YhyYr%l&-(eYNo&~IIP$_Oh!PNQ877hjYxUV-bYyCebhNuiK$M1DP^4*0%pm? z((~(1&LB6Vtc-Fjip4Zy8W?qs%g(I$i24GVNjaa-A#@7f>40V>Kck&^UR+R&46M?7 z_pYw4dTep|YlSg^s?5C!FRSXVBwW?RL;=~8Kx|et5Tr>a$AaWpqLdl3z7=Bes$dr# zH_uS#1*U(_VK$`i*?XpcBEVl97z}q@@_% z#1HFCT^VZA-8$mcd)C1KgA||X8sk-G$&0jeN86b05Jlf6c@L==;I&T2b7bEGMNB`O zQ0>v)lU?^HyyMP8&`qqQdxqH4rvBaR@eUDt%9A|Er!v^q`fUe)0%-pPxwA2H*LtFd zmV$?VkR<_LWPmjH9`g2ueAPpl;cOhN2JV71!;j-AjtG7t;9X53(upJh1}QR0i18L7 z5j@Lb?{S>09SdQxUi0-@MVQGPHxJ{HfUk`h;o}63uVbtx%{L)0`A|DFnb-_WlcM4@ zjR!7D4GpiBj@XWWAYD1zhDLX?4uq!2-`D{K5|V6u$NJECJcykp16;0j=nfH!4)|_| zyRHX5nT?(#B@RzS1OdX6ZAPlB+_po;o#D}qG~SY87kt8W`S&a$;z=xD0_I8JPXd2o zG%DKxdPFuh3ZT)jffrXUyVY=fEkvO0<*3)|Y5sRcp}}B($)+Ap5b9?y27vfpP1x%p z7KN5083evxGN1tagUO!Yx+elL2_YhIh*^Ugo`vVuEyJ(-$pkywz1mp(!@Pi0Z)1au z4;0>WUvqd~_VaeWvEdOnEon~N#7)KAfQqnlfsZ5AJDr!43vekB{oboz5|lQm7ym4V zQItlwve#UHELgJfLpIte8%BaJX_Q8@d|uIL)QH0ExG=;7}z2o=_d?GCeK_SdZGdjXd9V4+Vg>{XS-ZvplTrfXv?kQ_J7X z;p#+xjuj6`2uV0Z=r+PXOI86vNy#hNuTosGRG98-3orVckFt5;uOI4A;L>e$*7kAH zn6FEQAwR<1xMe(s#vvF&?`O*Q*itjOL0@9LUCE2H<>wI&>T~Lo+1;Ph%LP*S)b6aqU}FAy<8B#mgXKeoT1)_U5xd7BAFoZY-Hn0h~TdkDs={cYC_MbjVIAlf40 z{w{?6;WaK4eD}weH$~YWTIB)}et&d}m$^-1)F~R2^<1n8q4RbkuH5SCOq36@TOyz${gc=J9e2= zWGe{XlbGY7fSRB!*R$6a=)o)7laQ6}lD5*uBZFAyj18ue;dDwtsXYh8>%zUxyr-aw zY^fd72*I#ImF81eo%)@z%3hGX*Bn?C+gWCHg9DIZEzxA@XnQIETa}1hWS*^jIIxmf zP_d;ktmeH2qk$u{^Mwpr+H=`|6AR#1G7(RR*hvzy(yUYvFbJk@A_P_$*p@9b*#k&y zwH!HU+*X;YXcG3t2UvH{f;+~LO5^LqgWvg#5Afy(RwXaa3YO2YTXha){Om@@Q+;CV zc+!G-%|~?HbH6jr@RowqB!yf?mYJVFDP(3syDJ3M@Nzz@(?3%LRpjipkbqIGOWD|FR$Hl>4SC|Yjh+ItU%)!KFU^aaB_T{tka#1oc z(jbD7gJlRlTiq_#mqbI-ks6L2mZ_o6)r!D7W|HXGDHX|$i99n%hvZB*6Z2JdF7rjy z$ila>5m0Hq+3?tfxl?F=iOy8hu6@oYOZiD>!bf(ddLOMqAFc4CE}mW~cc3MBXiYLo z=I&PZFQa6D+uOX`jh8CNqu}7uHL+JaWUf}HS%$tz6I;VDN`}!eN~5mcl~;^jy?gsI zoovsxnUo}=Zj@{<-4$Z)Zkm8pb?k@S*ld7m1D$0Ue0TM85B>%ZH#@aYIw(%6`dOPGAI#SSvKi*CuFAfo|EGQ@?b|xUI6k15E+pONwg^j_FX*1 zCNU9->ZI6rYlK99<78k^+{E_?g*TJ^IIW2?j_6W`B$vv{A2Zp#hw_p*yKFjh_go|C z%=F&5anapG9&phpGI53e5;#C^fFY?s;wWZu*^@Tmr&l?rj8|8Q`_@Yg=s1j0I;pJ5Id5PkN z>CdvgKg(c$E;i&cLuoE2tRR3QLC&&EEl`mU*(EyqKyQ7p3t+dqHJ5#LZNkOf{mm%~ zj!E-aODC&1{F=*$Fs@>({bk8E`bInFS|ehL5w5LmBjg~4BTyIbno17gPG&4p~MJWOQK zH~Ys?LXOw#kICxHNWSJ5#LD2p@j8nxmvd1paxU(FT^1kdbPx?bcDu*jZU8VcdacXe zbsJH2rlp%Or}LF0KOrB7ueTj%YBlo)?#o9DI?4LI9nv@>rRYk!oypF?a=SabyE~6} z?>7r4#5Arak7C(tOtJtyk!6|g8p%C}8Jolf`H+yO*yQ_4isxD*!9z~*H9bbr?cV!WhI8Ia*11>o1mI~F$xwWUagM3@ z34GhgCpy)6&YKXwk)L8J6O~Dnowp+GIueF|z(7JRVK5JRmrcQ@w_jwA%-a^f?tBc9z9S_GJhRd!?4dlzkxR z2%EC&jS3Pn;UZ+^$BU%wYSV}*8BFHj0>(~Oj=xt-As9ep>h};^9$Hmb=cW| zWqv`Q=OWL6$QmCi{4F&k9; zkIBL=Q%b6YiK)q(olymHg^vwc#yGjLUs&SI{K_2`18r)d);K=(D zl^cKN)5}5tL|!PYv#7p9nr;a-wA8C0LqB*CsH^+OI`12dh$Dw#oMs{4s8!IYr@aqg z8?vUpA17SsV=^RF*RNO=ILK^&y8};=)EL!)Vn(jQ&}wTXaATuW6kAFKgLFQ&BY@+A zNaK2(y%n#}9kZ3oU~!GPE)b}l>tMLzEi0E3hr&$1Hnn|k`oJPxKyQ^0y;}p>Q$lm6<4}{WTPR2!kt#( zm~Q1gxkkvLpJ)2Irmrg@!rkl9c|zK0LPgdb^3+wM$u?>qTe^L2rk4KlriG7fZv~jy z&wxN!OQR)T!4@XSt3Zk3B;Mn7&>)cvVp%e)trs{cc%mc~_W{gCPSjf~NpdO(3@Ky; zHxefnP*~dRV_Pai=C1~Sm@L%M*sxo9G@J2y?ML;^m(_-UdFYA<}$6U zCBjYB4HWIlWDpN9ecP)T)0(MZY&V4qJ8*_ws>uj*Aq88804Ny>38H`(5Pk%wTgXBr z@vHFCJGDCVL2lNrmJFigP*oFNBXEVVWWVvrew{BGY|orUnqi7yYSOOb!ff+za4qOLrK_+RV!2`TP-J6k&I|TFk4n%l=1k$J7?GH)`E>R}l^HDjzwe8*R z_O^tEtuo|uG;R1i=I1X0{H_fclmgF}-LCbPfKZpYIjziK2b^XrgsiP2j!rzUGlP~i zLjWvj{s!O(5VchLuTSey9@9`fQ2k?O{poLGFLmXP#tle3~)m+T<=V3qrk3* zvfNOA?|*s^&&}zG|j)< zK_>Wv>pSc<-EJ*UuAiH77<0c56n{>k7fn|xIJ}*W8_BS$w-HAL4@XVz+elG-W>e!y zBTqQmfak0#;3GfepeB#&w=6WTYtGPfYYKaRV|}ngz730*gEhTYd9Y}m0%RVQa~;5a zPBlq`b3dDBa9_J^O&Km?7V8LcZ+Md18%C4Wslpw?a9#M=R{OfUUZZ!}dfmbZ>-A}1 zrX=Jv_+{wQ&!1HfRhdWJCNFR~R#+yRebuvIZSvG&;p?|u8;eSD|Az^ENNd@KbpjyyLF}p@Q$&zD%9%cY_k8VG^ zr>3{@h`ksS%zx`1t-h}5N@}MH7_zM`Ayqnhg#D}5gAIG9>h{iZ?>^y!MTOF03}(8m zE#Wb8EE=4Q@-LjRx?S0xdbWFi_xmogoyp3J$$_mYen?ZfRs>hy=GuSj>@YQ_>YK>^ zE?IwSrI_suT#yRsFD z?S4W$H^I~iF!ruq=ika!j`toWN>{S$4aAQ=$mwW22%pD)b*GHPxZC9h zKRO}&w&HP(^}cIbj@6zay*IU86$#UTyvJ6dDo%R&QMaqWZ*dL+M~c|LlMoR{Uwx&n zA}{|u`@zqt5Xwi3T0J>(zujc?ZdkZO`biLW4o}es40AMwkj5p`IHfk5rhQyJt*j;m z)aIc0%-Z3xnFdSFD1qO9sPqTb0vI&dbPn~^@P`2lT>2R>(EP!o(3|Hl53*6jFe5P? z6V_v;fRl^9l@Ru0?2t*!12Bc5`mwop;1>q!bLczJ?N(GA7nihLihwhQs3{qtA=UC! zfva0O75X(2DqD>++7PXuH>oyHl1)%is@#O7Q}FUsf*zDhKEa@WC&!^2mW{bRyX}R|9Lu4WxYeJP$ul|2DnZ?aGmq2{iE5XlFb$oMqSpa{i?D zw%gshBco=2+efe>6A32u7ICaJ*tyH{lblWH+?$pD2&=IGpKIF}p8DO)n}EK3laNrl z1@vkeDKmyh#tC76Kg0qY5pEbck#kfnx^ze^u2er2NvpSuYZHUAVUJ#EVZ>RgjE%DO z(ijVPK(R)r4fF+I^*G;|(s}WL@>h8!Udsd*b(6JpL&4E@4a}A;Fz1384={7Qaz1fO zKw2o}qhLul{Doj>nmqS6m=iowokcbC%_)$}R&$p*KT5)Xo9#25V_#9oz5eI?1^T8h zY8OrI5@4U;k*=?92N~1-qMSLwY#~@dV3rJ+b^~oI;mo6uf!SztDeC`g6rIvp$ti#; z1}w9fc{u!0>{0s}(4Ywz5l|9Qyhi^rv5Dz%GGO1u>^J2-_Dj&d(tmjWenQw!O)y_A z@i6j$sW2?qgS|)n-Gs0mUw=T@uD;0JAF=dJP^xS8rGi4)gnws)fEGjxOeocB0YpN$*lX59Upt314{HJSp| z3YznO=j9c{IJwx7U-N+AYUCB=@@emzLCUzkQe&7glJ~CiLcA#X;T4l>OvWC^g>?CU zQ_hRYHAd`J$0cV#46I5T(q6HoiVWyoLDP{~Qe_rAy96-tGI6UknM<=QtA^1epPbXX zvw~M5N+EK^`@RWRf#9IwGKF}RqK609eE!0JDL1v{X2S^J1gEEX5S|a0={%i5zp377 zkNaFTD^91xAt#-064R^GjO$;ZSUZEoITtdr@#R$cn4D*HH_o-+yYbn}l*_H&X*@XQE;*-6i48Xeu5In; zz%}glGb%uolkdf#w^Fi^Sw(tGW_vq-Ldezi8r5jEd+e9qOH8x_$#Glenn=hBLJSIa z2Fg|T3;346HttrHvJJXrxg6mx4PM}!zm61mPJA5a+Slwe82&u3UX*-7r*GxCi&rv{ zaYu{m^+hwO_0e)M%?14t_X3pzSuUEja%WULFJ`ki89>~a5?d9$nkLDuZ*mTQ%MyAq zce{`k6MV@_vk^fTUiO|R>IqqGoMN(*AlOTPV;HN@Bn}ZGP_y$8G*aF$z%dnuRE-y? z_}#vifZys?$>zA|Dl+|gT*lC~WsveDHFTiQl+s2cx_7u&ROz=A*#WE)syg@yjfTHC zW7cc-ATE0f!`J#Ft5bsY^k$ZCD!XLGc4w& z8Zmsytcxx?2XH-8mRxUM_yTmJ&HXWgp4>__+pfX&4l8?aRfRuSP zHWv9lL_+>51Csq z<7vdoyI3^z*gj0_4`iKk-dbN{aFX5C+6HISHg-As&}n}{WPa6#9dr%JC~6CRg@j*VbcUV8xaqi=2J+}tDmkq zw#H2|1m&Jx%WCULLwq7=nRVuW7B1JiT?b2pgO1Yn*iFq$(I0t#0ZJI16-*zJ7*X4R z#Qydt4&HlRa@rDiL0B7wN~jvr^k#gQ)@CJSg*BwMJ(x6$IR1s7+dIw$c(<(FgM^)v zaKO)+Yfa-gp+zBk?uKdSZLxzQwB?#!HTvU2cHkC!cAm2{>g(5HjT)ofaaxZLSiKZ& zIZ?xFK3R9@t{hc=d8>rX0qZ6xgP3{|0>>|sC!|&<_HXYL1+kUf>eHsnJXKNvetS?1 zxqBUJu2A9TmKofgx*??j?hhG8@357=n?k8Pl;pY&ehSrpCh5%pJ7#|Eo>59vkZFXJ z^_tz6PF%j4T_019%bO>4lc`Wc{|y9KfB)*p(QW7kQ*$nL+U(&M$>8CX_SCOU;vAcr zr#tQR;_?EA(~ZjvK_n{b<8O)mI&VmynJUqXdkkH-SBM5so?Y!#&rY!a|r8Csg_R)C^u zWA@alB%*i9%X~V?E1^JU8iqGqKHik`IUF&Y#wC4>bVPAI?6R-bt8t^+a?z;urb>4{ zp;C;80V|NhF|{)udN4A-h}F!yIuV{ZX#stm2tz%6fIB@s3QvoHt3CxNhmZlcPR`Jy zBWpZ=k2!?Gho%LRvt`U}idrr;gP=?&Y%&^e#`Cvvq}0AWgy&PfhyU0!E@ z1~95Q^n)SIA3I^k&iu?A{c}Nt=^lW^%VYE&X>#K&3b0NMxum9OB1S)R<5?35Bp5pj zB5{+w^Qu~2(wCQjV{|%KqH{H*DcYyq&0~Yw(OSskdR^BRsc2bqU03L+5q?^!8QiLb z8#L8UI*LsnVz^dYipH_Vxd)?J*M8f7?Ky8(i?`XuEY%<+Ggk2$}*3tZr8iaWQuDERS?+!;=qCrfMqr2YKl@? zAyL=S>yL#Do*rcikI=)zWKw5T!Pv}Dk(Mx98 zTz`a2vpG5%LB=q09`GhyqAM7u;M%VA)|5XfwRb)MEedv>#UtDn@> zCnLMXTC3@Z72h&+D#M(Fr$BaR^U96>D`q1ky?OFY>2|h5! zk)q8G?VSO?-0^GhTr?USX14$>j4uj#m_FIn~Gf=(rDGZ1! zJg?X8k(6%0r*Y5aizhe7?t(wY4S)^x$1e|Fy*$`I(WM-!ABDd2UBRZkqi0WFJ$-v} z{PUZAFDBG4b@=t4_n#f#R_f)!@&4NvPoM4IR`A^c#O~cvX#e1U-Rs-G_~za5Ntim@ zd`>^9`TIW|?;jl9()!jywZ^xWbK2fo#y0(i&(&LQib_vI5!f68c!wLpSp(gW^NbtM zRKg3mLMK+j^A^}Pxzje>bn22X*XV6Gz#ay$*CeQu_i2S{LBYRYWPoVVNVp)jw-aze zchW70@!$p^Mbi9#CO&I}Q`4Gsu5HdC-Ek9c5p{vm-6Ia-EAqm)AlHa;Ysy?jyd$|; z97A4WY{K6J#}IOMgEO&k;Y^sqqvKeP-U4IDB?6XR|9JU#!7>C)NANO*;1#}v%o==> z^$DLN=qI9bdXSu2@|k9%sG64|B7CyFO`hih-0!dAgnUAOKphz?X!kTqHs^VT*~S#3 z0zow6)qoBlbNm9Zv=M4WeYaBpyThj|jYz33N2fSOvqLrP%$;Vnkw4_1I$u?djt9{S;%5yAYP|~1&O0zUI9Zw4m|U&#JM&_u9nTHonD!(W$!a4R ze40gHUGeLC+G2PlIrlu{vl#eXCP+U9weEWD-AmSg>k#rSUu688@Y9ShMtnM6uW{{@ zKkE+hVV_yPAbe`#HEX`FU`1*5gSDMuA_ZbT$DuHxq}@1VQ5DQigP=4v8C=UK?|N1y{OJiO(n=mpH%IYi3x?4G~f>8(#C^ z{K@J9(ZK5`TNNk)G*=H29RdfIapwgH?x}r57WxE!(NHaN5_w$X_lRbm;o%)YI{6jOaehkpNi)8z7Kg<5ttB#l zW=_auGHiC;ZJ>8%`?KNoVv{mwwL5Z^368E~&=Rof6;hNEP;<#8^8&LHea!khJI+Ur zZN@5^AU0)3d3LPV5kLiVEH}%G`I1vN{~LepCmq+>&(u5vWGe<^Z}8{nh~4dv;THaI zYC3epLtT*q8Qw`YWgEz@F@& zS1o&rP;%pp>8(KuG&YV&s=Gj5M=7cD_l;@6#WhOvoHA$S!~2L5FEzg4OuiJ->0E1e zVWEP9kDSU2C0=ZAgWJ%O17=2(jUOvxuhSY5<#Y6^?>ILB#!!DuQ!(T(rJP2Slpn^HhNQ9LKgX`Ct2D7gP3*7N zyKch)g#NAm_L1s=+JdM=fv`zio|_aEu!wxCYkN@(D?}kucxC^DaZ;Pw2WKVswtmwh zxppjh=gLm#7@N~khBe!wq(HWGSKW&EPIC>L=e!$>W{Iy}@6T>+||!@D>11iTJ{ z!M^=eONu$YSFzI#x}K@olF7PT)Swh zS+=zmQ-5g#E39`zdZsxQy^(yXre>dPVb$F(|J4iB=5O(XFQAuxcJKdc?|<#yf8p;$ zdT=r977^~X7KvwkKQ;w_z-4)7P<+7#+uKDVVm>Oyo)(z@tj6&;rVS1epy@b{Vf9LM z47hC20KFx>u23G7e)p(aluHW6aMg-5r|h6!iQ-_^?P9k%#D9G|@mn7Celev4+L16I zG7~aw%m_jFQ!QFSq||FT^O~Rp>Mecmq^+-Q)Zh7|=rwa7&l*~PnoWo#OTi!T3q{}; z{A0JP*AEPbY;L|TBofZdRjpNMN<%OT=WcU7Lqx4V>0CPQVi{xKYHe1H5uA_zNj6v* zhP9Hb|8d)F)k#hzzZ(HAh-_p8!UWX}N3wEPP;|<)EfiK@vZJ}x-x!S?POWdUm3|Dq zm}={SpR#A*{O>G()IT;Lm%%R-(NK+`YfJ0Gyt%3yM|lH+P}syPMP{}-ZnjMfj%jul zuoyprhhBth#t}CnH>JLp7jG=a{=U0vvc)gDKZ#UcBQ70h> z<2Nm}K_rIdh0;a*QgcE<8tMhaa&8qU>`H3_k2LNZOAmL+N|V0%tERNfNd!xKYh*t& zI+RUKZ`t=XoCvXii@sJ9cGUggFI#Be6Mu@M@)g2S&ZRu>#2~P{q<*1u9wI zScyAvvV!D2RV5!bYx1X0Tcv41{46lJI$8f@lq`RC?NQF!@x3Fq|GAb&ORU%Y&l(&N z@$@Z}{**3K{-azUowcx!3<8yccT{!rX+-uPc7+5fw)O0MPCdC0`Q$uU&u%C!g8t?B zF-gFG^SXia%N;2`0(>*%Wyy&MPf#RuN*9tLF<5*LNl^=w0}{rP0W&AA^2Ua#YzYP^ zpvw49?jDT!-eWlaejiu(eaJdv)BOy1uVmmrDdYIEHqgWxSfV?zHv^qM#_8msa$Q&C z3>w_QxOrpHbcZ}#i~Y2>$L>jS(ZqLPpc?ppQa10!iudogSt_h<4;@Je%HIewiV%Zb zqdOp?hKAXGjg@n)g3ySt$E5;;kWFgjM8hvYrbXk;g&zWqwRWJ)rxs8GBOKNJii#Kh z$KxWHH_fe}&5*8Ro>VFS68wLOWYMD1w)$aMdn(*oevO?=RIa4;5B(bZcSt~~6sEp^ zR+Dxm^tvlx#R*hacN2A*T~o0w*-bs^#1^tlLe&Z7Vvd}n428%yu17XR?ai;>E?Ese zgp@YrHl!aKxWGP_-$*xYWkAz^nr>uR`p@S{D=?}Uj&_OL^yjJ-aFmikrJNM9M2+1^ znY7_9wzzw;gsd=9OQY>TVB)6>!XNlrMRjuz%*$pd zovr|~6)Pm-F)^5fhL<410CS-Dtpiua);bXgxt6?;Q#g_;J8YX>2p5&Xtw_vREEPmA zxZlz1U{0%Efyuhj8E;b`p?o^sN2qisLwi=okPkx$p?Af1cP<$VDsd|K}<&HuHcq1kW_*>-S|xM>;M zGSJl$x!Xw?63o@mf}jn1rxAE?z&-^jKA&IZ*HyEw=8-dmqd`$))h%d#L)n8r_D8K zvk9#~0V=X)Ql`%nQtRR*A_%dBm! z20|w{Q@JFQPbCa&^gMJ5(CDz;u9(J@l*tgYpVW6KnesvRXfw+_YUu_>HUw~SsacQZ zVltvX#WWdbGT}oqPGbrO@8L3|X}rveT8hC&aP5*r2c^m1)`7BrQ|qDcC(TKnxBC4A zlWZ<~z%S2AHbp!q2r12K_gutEUKhP$MkWxi+UOW>0xbOr5bP{!lJ!!x&*J}*w@14~ z11O-gubasO5+W~?dUbX`c@g8r-8xBd2>;fzL$A`GGD{X#jvU5?HyLtoZzg4i>_Vz6 z08~J$zu(HTl1#EXti&>7f1`4|Ub9g?PDs4PTMjHL)GQ>YNUo3P8SB|RKZv>)SVKuX zs~th>^7LpvhU%u-Y*Y>Nw8X0>;ru7Zv}#M;ijRHiPIv&Fp%9-vz?57neGR}>4@l80n4f9W;dB7()dxetsy zk!+k{7LkN(`I+(7YiUxeB`inA%~aBbIL|b0T9J8a10D3VLZhb@t@33{wijTo&{?_T zt1VbEJU45}@>DJ-bgFb3M6A~(PSezHp!1Tu0MXh4WZqV}`jT;i2ixU*e#35BBO|b8 zC@Y#1@Zc_6s2&fZf5*%IW-=LUqa%u&IwIH$#V7TG-vxEA$ySLl=qnn?MpxHE86dNctO>Pa_U zAbPp-OFAc6EjRF>v2joSs*QU>`nysSJ^*R?Z))QIGjUMagzQ`H%Xv{{Vb{!(j@p z4dJm$m5c~^3KpY|qEUMcyMlK^gY8Py^pj6=q8I8=-T?gbuob7;H*(&{Jt3X9^num- zKh7~$`nM&mf5gja)(?d5`c**0?gA2)_C5c}z8kV@aBeb_8J0QPDy?iE@P{}z8JasE zs$|VO3E>Z7Mk4y5m_R;Zd39M%i`ligLxL82f*kc=9jfOa2*p#nGn1J>+ke||)^UFjjd9sEwUYF}c814DRW z_fmWB-CD09y^j}-FE$p~+zh)lTGVlm8b#r4j|H`D#OKReA<6WOEw*NVeeC&RDn4x} zjIl>=fIqJdMhyxb-d0$4+G6ew728vlOxmrj{zjwG)HG?r2MDxi3kXrpLFrjjrTax{`@YZBbhv_#xX54X zj8W_7WTPdH&{&3$1#!#m1yG&9wY@Gn<*Qr0%qF;lTmhQR9=tf6+vt%ZDAly=_ky@%O@8GNq|hW|-d~ zX&Q`b>r0!(lj_*2#zLjyV1CnilXM4}G)i9RjwzOew>wJc(1ik%V^FJ6JBT~gc`oM` z@*kZ94h?4=Lq>vpA~SVb2;LL{FE&Y%dKe#;R=?NkDX#py7v7pF&-Mpu2pU~;tGmKY ze=DzBcP&t2%jLYS+DFlwSqC4(8fPHbnp?G>4b09rr^WSWw?M2T_{0`29RZjScwlI= zj+uVDMY#yJR|!^XRWxFj2}}X$NMk2qHa`C<^G;rP>yJXYxLaL)bCG^zE^th3U8-jc zOje-44@(Ed8DYF31Z*cQF%_kROgQ{Af zr9E|EmS1eSBOW-ga`?!ssKLQ@Hs&iU8JL%|m)!ahNPh#+pNM*7DAzkNE?aXawzbN| z8ax?GEP+LIfTG+iR##6jNF>kIk;}F{_0*%%SC_3~jHm>?>)@|&C%B^GGD5KxT2zQU z{Wo7r`n!PdPiOk7O+;EYUl@%}FTfEm3&B7spxY5gVtuD7=cY0^)Oqtw;?AQawfQ}! z^5gRQpnr46j5f3el$NR*oe1z-xg~PHCjC5}TrqLMlGao$yXnx?;q!_FD&gAYXN{-= z#+@Vw!m5cU@de_JW14}D4!xXT07hH(uv&XFXBO|6fLuGy7MBEgJnqgytjl=~jnM`Z zg+1w~N+;Dd6Zm8X(Rl(=2{}u_I?{S5)8*98)PKb0YE~aiCLr!8UfkEZOx7BV#eqQ# z3&@viu2hK~kTgZOTy)%UO1P=!rNFGV;SG@Q$31>}k?8SkK;7DpXNif_6R>x>jrTX%fPhYGiT*kY3Za$9`6L^O?R=(R1TtiY zk$-bvMD0GKvMM3aR!Z9uzbGq#s~6*gw_E&^hUk71J@BHn?6TWV63Uu*OxU<@=nvB?Ao zY@y>ZB>&S0t;aVIvIFEdUIM_|17-k(Ab*O2Zea#60w#nwAMDhDVwwsK!tlN14)KK%fzerf0K58N!6Ny$NmP2(Ck`q3=33c=>$GFE$M@f!gy>&@7ET zRoZlUsfiK%@d76A7+Z;LuQ!eWf{yi`wk?|e&(|_`PJEtdD4L-Pl*6323ep)Jqwro4M~HxOfy^48c2)QILxCoGmoBr-toCaUKxQ=dK37* z2f5%WgR$en%9W|jmNogmMt?1dh?j(hwFNhPxl zfyDEUmPD@XdzbdTi7Dp7oLquHp-UdB4?9J#&&?NLm)#K!Zi`XeOK z5+>z|Hs!%WYBp>TR25Rh|2gdhFMPr?>20pMt^tkPxtA64wh^~uX!Z~v~8*@;LHLtrvd7*wf!)uuhl@9 z4<9V`?7%8jV1eiBVh%d3|hS-+TbeNC`l835V%94 z%_x%w^Du%^1O!kpn`TYs%q-8#+9)tYx;S((Lfygc&mR%XpCOG8Q=OwsS%Nq)7tuV( zGZI+0hjcs^Uwf>z`;XqI|(KG)_?JVBFDJ57w-2%Kvhp9)G6ATia|fR zFHG3(+vv<$5I%09yDse$3FuaeK#kO6staGdmyFS?AyAw6s>ARC#YO}{? zWa02IM$howHIqhAvPCbHUsxn!2R?peJGNihyCoBm$Ebg1lJe3dab(kOkQ&g4h*i|j zpMQi@z-3G)><>ZILQGC|7;=cYmXty~o(_V`Y@Jrk4C&}hCf~l$Piri~Vpg?R&AyNqT%02@po59i}w~1VImyJDgPH9eg;{hnfCOZPR1 zY>42x4Erz3k916s8`iTBDW6oBeEoRhbA#)S-iKh^sU?>YUn(G#WSA*GQ>w2r^Go1} z!HGeRQ-yhChqzoraJ0z+ifoxMeSZ>X&8UwGlzT5tu9qg9lzxA|?+A78%y}erV+57n zv7YKam(%n=V8M0k@vN2lO{ZVPjJR5U$yJ9XaqW>$%kzjsBAO$K%NW`!D;6YDi7G2&;4&!@bA3TUx zWbNE{G_2#o?X=Bw!izG{gO~#hbW6CNN7ieSJ^mJ_j{EB+68@J&nDRxp>2c`w?TXh0 z6)Q#7B&{uf#B+)-8lYO$?|(2IBxThM^cfM;zkmaLP;4kKQ`epP>8Tq|!+U}@JLZ!a zi=j=lF`wyvO36K41X1@j@eT}id{_42(45uxgjS9y2EL74PDp?b2=f=WadWX)OHe7| z98n`FJ>4Ubj=US5rWung&XUD8&<(UL3Ch9t{(4fU>P_z@dYjv5w12w}0bIxbH6800 z8W`2fKn<37GmWc(2smsWaC*3CEI?a%7Be^f9F3t(0jwiCTK4>qdI=^?@}FtqmfP|Pf)*cNmkgl! zl7Iu1d~-+xy3|1Z(0{vbpQ)GjC_;`F#ElkoM6dI+XM2gT!H#7%C2C^gAgMTfdN&-2 zLeL*{ksv_qNz8dzsE!gbLu!-W4m)`dZ>T6Cm7>gyAjOag#_TMDW;Rmsn%QWS_M}5> zFq)Wrnv&5#?L|_2`KFqIO&X52oB@R;39)e<4NowXrT?m!(0?j!>EzYW%5|sCgw1dX zWk$Gk`%>6tDWb@GVR6d}36!KHaZ^3Y5byw=4|#4&X-g8?u!W(Lb^`O%AhRW#eZM=? z3&8$kF(|rsbo84}a2kz`>+I50G)nnBb3pw4p+0&EiU7L814s$=z&Dk{R##iFNd-8% zYFdU)`_hrjG=JiKFF{NO*|A-lbKKbrfDxAZhi01IdI)|6Bc_-{ywUJ?G+}FsC+!fW z5%<*Dk6)iXdHdpxw4^#>3Td6Y<8BCrUxS>e5i$P#WLu{|E(|vC{l3=r@7u#v`jjgS zqxMZRR3pqmLMN>p;-cEx+aDTM)-d_!&G(aEzFDNidVdgGa~P+G^kAF--hhP05)(sy zAFxA7D5;gjw6z??kYey%(w%D<(rfIs9a;>Nh_Q5>x^ikW33`oa+c2Dd@QJn4wqTBk ztFK42<9|yn?$d|wt$<70czjtq_wEGd1xb{&dZUdvNg!TQrE2=6O(j7?!tUtAgg8h` z9Y|%bB!BnNlnvt2MDcZ1)|U=OG=2=T^Y@6ps|874{0GvL_O`GoJOpVl_i}*WTq=9nr_?hIJ6&P3i&jg4=LYv&`^UzE9@mF4>ZGx=5!htYAZEzDvn&vSe#mYS3b5maO#L-hk^4Rkr^= z9ghorxi*x^iuc2NM|gw1n^fyWdP;7A6b;g*#rmv~AGM5(uVZ7@GIEJjedVi!#`st( zSARUal(UXzy(BKXY{u+>x>EqO-;~f82QKJMJqtu@{Xu}eZ`L!H6JzS{LF63)Vwk_C z7W&my9*si4NogjU7qa522Wo?UEH~)NxZN@J!&e>FfLjS`FhDRL6RUES+1Qe#7a&$0 zQi#2>VP~L}kW!Lbm*}$n#I}HnY zIr4_!f%psuO3q*dkgQ#gnBCGi3&#ZEI8|+kf1H zhm*Bc$G0=UtOwQvdFoknQ8%M(3mloAp1-k=ujJ#-T>}AMAv~vRI9^(~{BAtnk*mBp z<^UlVw*1w2d_}JF#;o9vwk6kauDB*QxzAn#n~vsQs2sUgdl<&GhhdCChnD0>8?y@| zJ3qp4-&4SDTxJagqod9o{`#YQZGX~|8&Vper*ja!afb(u2vsWzW-|x?TVjWTpmRym z5W!~m+*X&2=(=IzA--Xxm^Pk8bSB!XMB2kcP(qsH+`f30q~s_wgV1rwOtQoUE9OS8 zn9j*W=>7IyXA@NqamI$+=vk%CEa$yMsE{j3jsR?pJRhD+P5y+l{5-jF!+*(neujJt zFJ&Z~YUP=(!C|mc@CEtSXXIImxE~NfNE|Dx$ap6J+cnx8JH$J9E`5Sd3&rYmTfNU1(E+ZRV~8nJ z8_#^uNVKhetx^`$+oj&IM1KH_0=}X4YoW*EF#xF|kfoYbC3+e(La9#^Qo;Q$uvdHu zyPdibqZ<&YT(t1PYP|_#>``emT8Qztf@5gOo;@2CLYet^yj6xt$b@xJr<4|CI9@iM zVCYz3JGLaqq0>k(A}N#|v*;NfwKc-Hzelr>t_Wunvct&F0?obB5r6I6GMr3p)NGYI zk?9AKw+SZ|*i~Dg{093C(0t{*^RYsIEC*CxIpO7seR#c&o1wqTPqgnT9(h-LGo^#% zu2Zt@(^9mA@6nNQfr1rW$|P_lxK=cO>#lK6#VZ(StS+~~7F|TQ-mSBBuJ71(S0S<4 zl!d1GKsfU>1~aCiI)8f5XSY~>GCj~>n{h%YWpDWk)=}Oyqj70)?@*c5_xr-39jeIf z0gjh{hCF2)Bbf9dJ0|w=Bvp7=$%ZBYL4C& zuTQ(sq?x$K>5luSJK5IiU=)?DH%2`i;?TCJJtDdZww!#S_LS~6k1F01i)HI&oR&VZ>3L9EhSrI=?B+U4ukFx9T}jm&j;ZMhp1 zb(-1qho?m83xC;smt6a&!E}KdSh3$zINlO>$Cx>Q7cEyiW_Kl6GS zz`b2QFFBXSG9RC^>Xn@^| zS%5nbF-9Ep8DSxwA%^BVmS-lwYxtZ{j%*7oWQK#{h<|x8;0(xOL;?rR4a-G-etyH2 zJ6c?xE5O+Kd2;&s$?2yl;T%G_IK7Lo!pnZe8Z_TOQRGdv$?$F=Ebcv%owpTSCU_DI zQ{~XDWVzTdx`I4T)bL_d4v9r=m30WUK~=l1#dBk0eaf~J)B)4w?d&9L$yPe&N>()Q zs;BJwU4K<=Yu_#~s_-Cf#oP@qSJlmUJd}S-&d(pedHwR`>+>fsUp)K%9k{I3CW|(M zC_#s7I@s^QM9`u3SoTtCn3(lpo-fB^8DnmQUcf?C=Ky|#-;*UTS1vW- zdt2&#w16U_aQ^NTu|gmZen*P-04I*#b*lk=q;H`neG4_0&ki{skJk?3Bms$cLPl*V z)2psV!>~?OrB*Y|1zQU+jT@vJb!)m)4SKNU!I+R^YZoAk6)hu?e**L&d-&% z=1f0a(rbP}n@W(&{A@fvo3u3(k1t@ce9#e-9pKC5c${3?6W)`JsIJ(fQTo-x)7gi7 zq}M=!*C!WMb+H8jc=hOpEo&H>M=RD)zI`N@$V0hdJY2DBwuMFbuzB>`>hiL@ynkG> z<&y6B_M&1%QSgiH<$8IwEZ0|~%xS=LF4(&IAX_jVCr%saYK1ud>UX}~(n%#Q9KQDc8{)J8MD(LknvxG8NN8JK09N>>gp&x03MFK;WFM@7)?u(@O~b@M)rp{I z_F)Hesw`MG7(Mu)sNIxs%*$nmaev3B+o3wqk&IO`2ZxJJrlXH8m`=mAur@eTD)Jti zT?0f=W`q&(g+~?am#sBGpmZ#1Al-<;~hwyGmvXfy?d}^1#N5QT^$ru1qNt$!vHJ;Tc+q{ zCWALpsc{~(JqKJgf)$Kk0|C#r;XCtSJ%D49!$Lz#DIrzU36SO#Rax^D6N45xZ0Gwz<>@VGmve14mI^yuly@i}{Z%KnEZ@O*)x-Eqw_=@|y zvXdUomXvL=sh4c5| zFw^h(xk5z0r8m)hx_>)+LL%K+WEB4%8uWOGcyCxa^LxQs5Ry)a%PI2R^wi^LsEZgW zdZJ1P$k%x$0aHAd7ASysUp% zT(M<)k&IrHT8|1CI^6XzP?&^)V83BuB|U&P4?hA|=h4~C7!WA{u{M?@)zhl2zo zrcN`x^T0pzM1MqhUyz|6D2H-}brYG#lWIpmDQ;HFPVC41YHsE!340tp*DmAvB8cT+ z>4Y0PkeQkLBO9LPxreBc{$6Fda=ZT+IlU9{ppiQmB!472n$HoMmsnn;$VOJatMuB$k@d!t|`r21sgK1oJC+~a_oKKM0D3<8)^xsnRhwdmEi!EIxM-E(~sv4kB zobc6t?@@a>Q>5wSwEW}egny-R4y&ENG!pA9A@)ze{HMhEqT}Ci^e}>tgP#k*%9=jw z{9T$bGJhZO)rgGX&S>G&RLC$aAJQo#!`6!xB=YjQSkqR z$w(J;{)A`l^HucN@E}}Ee{}z6TJFA{87||MJd~RoWThf?-4iV$^BuiIMzipl$db}M zRvwvkh&?XY&?KSL`1j>AwXVnq&k!! z%v2_x!w{Xx6{~A{!Sa&SlO1g~xggsA#EF}Zj}jj@Ba5eym0SU6a#P!MU5P|S2gqUy zBmD4m+J2RvOdmdMQ~OwwRG8{r7M-_?MQ&~ag%3uuxNm`CCWv5ievab^{vFrO44innR+pQ}8zKbU*p?=iqcN?n)uyB;(z>M{^utW|OM&m6z4k$r&!;uPa>J z=X|At?EMWM&^(eR>ymwxEy_7);4{8Wc&fv>ZqNBD+dWWQNrCbA%&TYo6_PQJ;NU<9O-Y;wj|gsxWa)Q1DKL`n~U z0V_`EFsmTsX|$cVvt116rqfB4CVT_74_jvGC-3m8>+<`|_$DlrHBN0;-r{FZA(Vv4 z6i;ZMSreCbFwHQ`(_WE%agjgzfAe$t@b|_1{N&-6@W+2W;?8$nyKTOb%yk!5On=Xs z`N<-4XVXVNvSc_k+!4S6ok*_POBwhwVb>rOBd1wY&B05JU58J|EYs`<3CCF>tkyt@ z|8A{k170WzLy+;dlU5yG7-ZL;iv`qXGs&gyVBUBGZrL%0?5X_Ue5p4F&K=SnOorv$ zd*&^~mkEQ+f~mzl=_A4}E6KL1E`Qsdmd#m&NMgK*v21p!a zVlx3d6F(ecXTqjZQol1zy5w^*E1IX+Z0Helht3XE|>chbX6OV;}HlHqKMMuhd^d%m7oV*ZPah*#h-j zHwJ>gR8N6tUJ(PrG>jz-l>HT-)!K0o^v~%0oPFSRQ;&K&YUXy)U9B?%)~Ix4N56Fz zS*6kM!r2(3$Wxgrrb_lEEZ6Id;KnGq^3)||FpN+mxs$ETS(?EyCV#>n``)@7lWB4pf6N`fJMhdWF+ z9rj~SPNtqzkL`gJAiEWy*y{XNa#d&ijJ){%r^hc}JbetmK7SBio1G|QPl>ZJW#LXm z)b^LTdm+K2ChW2fF*@)T7}i1C&$?uctm)QJYiA8c_+?_h$Nlb*HRKl86Gq@8z~Alp zSYTYM=~?)7(xzmai+PJO-%O>gEU}JJN;k76Yv%1@zi;LRKDO383~PueyPWZ}45MG9 z@~}<&@~A+vbAS6`1;NjFZZ5QVfnKl-HIFm-BVnWkZ`u@iwfG0nN}S09H?st9oxzIN zxgiO}U2FlkIBysE3P%5gZ1WYIh|EWi$4Lc#byy}eb!`e#yf84XREqW_Ci~UipkC^w z!&bLkd81qGY&^d<5{m1k31vQEJ*|!5UNGaFNsJqewp@sD7)rGJoCu#bZXQuzJkH*ZqpOK zLRLB*=`KT$;SA3letI^6CM!URKax`Z4W;>1RipNFY*`}3ZwWMDwnn(%s}*u^gBS1j z-e8vz$A5PRH7D3^OA95o?r>qbZgNc?qSezx`WHjqw6}PQID-hvXdXV@$LyFwhdrWQ zlR*2XtVw7VIX{2(?A_!17F#P{2SmViB^t>}8CtmUd;8qWfqb)Cb+`2;l1`fskY+VK zCooo%xkevoWyjzwFN0n7E~yIsC?hBYZ1T_%aDRkwKioX0#IR$e^DL& zK-wh1h5h~{eb8}eASx~o)RN%IuTFGVKYSS6GSkK=6hQ&f=(EvD*T1Oe*ggEZissW- ztlW3mu1EJMVX;*lo)qjXXKB`{xqoIyUdE33ox01Fyu$@gxbT+TKSZIuZ$lZD*ACgc@HNDjqVXhXM-=ou%=UnyZ zR2)<1xWo8hSqp-gXa5WGj=JnhcF@($NwvwX{>~Or)vkM(9hPQ0*X95@&60TuE|)mZ zt~yFJb9IzjU;<;$*5!>$T!1P8GjA4C^M5F876Q3rOXM6l_&6W@v@jdUrDSCIj`e1= zmOIZS`}m4pf(IP60qF{$;sV{Xwed{6I%=izeTa_LNF9>2xk}ClW3O`ZXd~Q68IO~w zFWoKC+4WYr`?{IBV82z8o1J@$`Sbh9c#a`@LJ{ng6Jq)|sZjT4cN&KVbC+7X}+y;c(I6kr83nVS5 z8Cyx#PwVl*uu=Xh;i>k08G^F9X@9RIMH_#TR4IWgcocXiIP+%!@CeQVkI#NLJ696;4)6WCw!=8*7r`+dUS zfugNUJTH3(kDvom9}&Evu*1oNv7i&a${RxUvM&jho&7Nvgeu!LCjxq&{(oydU;560 zM9LXbItQow^nFNb<1SX`0mnVUa%F1et69>u3i+b`nAU0h4~;qW@w{};W-~Dp(j;}4 zPFbe6hJr$Xxr)Pn1zN0sghVe<()1rJJ#C7|-xRAf%^G(%CuNHK3Ql*Trj?a;b*N4x z_VDsC7_s{p%)6#@HF{QaN`F0*dUGG`!m}Ca8bfWW>AK9!`Lao8{mFQaC^*jgYSL8F zeB31tv_8h%)=ruJBLx$$*2f%L6jhTX@q)CAzQo|~Qo^4c5$dKc+vL%+vf+)4Dw~{v zFdUJ_1@IoU_-_1FL)33A)bExFe^inN2611AssY9_sz03Tot}B=?tiH-0#+tmeR(r4 z7nWK;Elk4GnaH@a;XZYsWy6Gdn)Exn18a-3^W^vT$$8+8g}e_i^Ir>VbhOOb=C9CY zP8QO;`R4xY1jr$;9)}H9?yj?+8NCGG>npm`+F(_#`9*I0{fyjtAOab&;auuq2oMtB zWZkGrjSP@vuH~h?#eY7qqHWlj(;)!U45e-XjDw?ku~+oN8ULM;OX)wz`1iy;LVsjknqn{+K21v58td^f3Q=6T2;r~uU~pP!y-M< zW`|HeOlRQEtEucN5pgy{*( zz>kpKDGWtFAb*;qLB;U+fzf>C!Xz`v>1R2{>O7XY;AN-Y0cP_4I84K&zj(L%j@TY z)tkIen&>5>&bsctqNsp?tV_G;`o;<6FrW~KaQ2A_ufK!(5FrGw8;?PU*D)@s0WI~o z86sl!7=N%o*o={~u(KV*Ny?ocZf*;OOaZXpusY^n<;vQG<)laf+>E-c#f{l!Y=
    NB;VwE;%n2 zzyK+;ZrcyY3d2CCt%bq?;-%9~|KX495QhL?TBjDFC+{xv)^YbbE>OujG`WV(ln%Cx zxgx_E4|D?a1F2GSrEq>m!Y*g!Z_pDAQd8~s(f+(z9TwcM7B zK7WDSdlr9+vv{WF%>y%UG@xrRdJq6lxlSaM;?QLV7`RMl%Y2oTeTstW96+JK&ur;S zUrWeW9a3`T0VU5^Gn1^PK!ESR<;Wgzm;4V}z@FkabXt;TRk*cbD@wIgceJjPW$K_e zmSzej$xaW^lI&86uEvRTk+Ub@PM!GJM}L{u-~!GSkn<5l>dVPy^8D@NZ(ae7&)J)| z&mKSRWu5xI8t83hpprtxra|gZK>azLUI1~l&)rfd7o*>% zDpN2RdG;I-19rn9%e>Q-Ge_u2^?HYsN&*gcMp0iX5fR&dfUHj6hhV8?WP6Axn19E& z2&pu3qck4d4@lh+jP0F*vHl~1(dwnna3J9?*I~3;jw`$hvQ+aRjM=e-rQpZAY(^l40I5fDDy_=Jx;=4c^TIQKEr95kM-u(;%Wk-L-KfEr&c zg|GjMF?V7K@N}AwL9ZLE697xu-g)lim-hkpdaVE;NbDR(CI zmKQ8Jg}gg%2{gR-Bmpxr1MsT{$dFQx$L!anc5Hj?c+7uJTEff=w7up4ZTypJqr^|z zR;UB0o^G5Js;R)ADhr*McWmb;i@YHG=Y*53TfIKC4&)R?n4<=*@AsqI1F%9>FpKGf ze3XqIRN!ZG2m4PhUVl!h7rM^h0iht+sx6qiyW0$9G7Qqifl}**sB&RL1S=ULSfw;i z5{`O^m{*HM4!IGhEH4cZidu8mf!rZ}eh+7=+^Qg!uy&ly@Y4`wu%2AIZj@ERe@~jD z2xOD1(<7?TADo}0St1PchE;p!{J|->;}Y|{9%}Dl7vLeA?|*#sH+~Qsgjd*`KL<&Q z%Dmj~`8R}rmo(u}4wwrq_M^-^h0b{!K5@XvI0;OKU{-fXzKh0q&0NioVeS08G~<6t z0z8bw_>ow6+t1RCo_e8kKg9xIBv^AM|I3t;J!8LW{3UTrloBLzVBbxU>_!Ws@`G}S zzt26d75}xz>wj;h+JW%D_vDNMw}+hQ^0T3D5E{V0?Wy)a_z(SV7}ur3EWzy?9U|6G zgIj&g9>aORzewF;NbHWiqC1mRTjt_vfB*gCS-XUrwSTK)DLEdD=9#hjiz0X4o2st) za?9S~TZgBiKgrFU5X7k-G~`cF4tLDO>Wd}tPB$tU>3=-Z@w=}SBW7;_mltk?&R+Ku z)De@eR^FE-K{0sF9aH<*JLhWR7m9ieB9s_TFpxrogG@&Zu2vjCR>?CQdc7Q7$)syU zl~p0wOE)qk-S6GlXbkw#Sb)y(Pplt7ZEADZwXm4leWg+PRCG)BdnU8p_A$3RD0Jts zta73)uzybTbHDFEH2H~z(tyXnU>B{5%5-1_S6&E20Q966KcGHAZH^){o|xskfIJs1 zs?DWzh3gp`PVi|l)tWvXbRex7}l2A2)Ox&8C7B7I}Q9El7FV+rB zTafw4JU=2M_vsNCh0g+(o8y#=3kW!c(&&97BA`eWE#e6YC}s{IR!EZ)wq)~jUM{5e zPy^V;y`0bMMVto1POdv6qWq~S*)Hty4e@xm*VXo5S;@LIxS}TpXsBZJ|1OD)ni>B# zQ-6;fDsWrLzd;kiX`f>;KI8AL;RwvgKZ2no@(##vs~&~%xGT=iS}}}MLVq)9AZ(WK zoB{|J)cDBTQh`f9=Qc$fB$`sEBGTqkG>`)9WAI^9@4M<5|J8n1ozD2*U_c{ps%N$N zuE^~c!qjC`+LS;?7U@A=0L(DH8jHx63x6$B_^%y;!C-cVQ^m*lGL3+hVtVuda9Tg^ zc1%2>HE>Cb9!U>~m_}ts?;3;v^a&P20^SB7`z9=4b z&%|RY{46EHL>|V~72q%ExzjB2lJtI1-gF7ue2t|?^7Se>C*&SN5knQuw5E23iGS;0 z=7N~)2{;KKzzA`LET8Ixat>?7cr4)biIJv_uluR|EpOSyvkyCY1d8O#j*6ZzLdVDN zyShvmaqiyh!Shd*jUgV9Yg40nI<9gr;|Hr8bmAyhGa@I2mW)0DQ%U^2M;00_Qe$@1 z1=aIF38YMVxv#G~fi)P1tD~kkT7L`iB-t}j!hJyDHA$>fJ7efb$Ij6PT$OIZxlYIE zPSHvQ+82QYNAy}4I}LEBZ0`;hA5ZDbFOkoqTS}!MvQb1qh+W{Y>dV${C$iMUpH$_F zV`g=YDv-7b{quCHanxRE$K)h)mxD#ct)WL;#J&t505nYh-o>eW`W>1l~OtA3UNQKw+AxjkziRXFOR++&YVC=PB9m(d@r65$K%qOwD#;) zIuXP|gB|2+Br8wPNsH7unu(@Vos-&}CU}H%4?}I5(wzS-Y1Lt<$$#7ZUijysB-DVk zW$Bx^Wr=+UP+xdACJu$?0QU>p2u2OfnoK+Zt85dYY=r8fW63b-uVP$DOb<9cF7YEa zOwtUDontXDPU(YjVEQHY*<5%#Qa9F{;aFZL9HYZ~-oR5Q6S+4V?d+jAFVNO5Sq@Z2 zS4BZ^ssn&v0z2<9;eY<%(wmhEX$r42hjsDy39t;y#yBZqS~9Olu`p(n>JVYPrK{&^ zH2%dUHoyf2AJnP+6)5S^>iuM{Jud*&!|3{YLG$srME6w^-IvQWHIH;CmPK10YmyrY zr2RbLVlhKlYlFU_^n*G7_Zk1xAp9iL4PO6t)_}RZx@H3D6Mr$RSMxB`_)0zM$_8Pj zLgh#W+C@XT<`>}#1wnW;O<0H#qEczht+ zyw$J@4Y5Q6Hvb8#mfur)0?&SW6>?!vFC+aCT9U$$W^f{NCFyK{nxAAFBPH>O`n3Vf zvynAG*8vU!*MH!hIWxd@r=NuM6w2kt=BEq9z$o3oq_FqV4SXhY2NuUA+O7KPbVjr0 zkR>Ab%wgP`Sp@K@R#ziXB?L;=ys>WH@z@3<;?20S@uT*{4?clHp9}!4#a1$TjOrZ8 zZ*IEB0Wv&KBnu}zihG3ydEr~lFya~Ba(9*~5l#nw>VG&we0Qw7%OMYt{!ymA2rqT? zrfpL}>ObhIj{`}+gpeFBz2E10Cv`XrE$YK&Dfjn+CV+nO{I2~-x_S9{jInSg-ax@* z;kEn*UTASp68WUys%1(f5dQ|t;x^GKOG+IwP&#GZdi%}HrP)79cWQs;i*f6nZ;aYm z%FkbK>3?-4B+%L6)IGN2!lswo4`iLpa}zWkXcE+NHA2S>V%S- z0D41-t5(aCDbHJga+rN(xV7_GE4?v0Ru$)<2(g>R+y$~ABZY#{u4BCR7;rO3e!0bg ztRfZx^R1qNW$<-XZ5fqhi4#Z~tN&Lj=6_*&S41%cmP#Jj75+yX0NM~nwpw9G56sYO za-`!?tT%~?^je3hqC0cEKjxch$s%$MiA7QC&2H)dazQb%6Qp)iQkl?)HtN?dAg6oW zl)T@wZxiJDc8pKE6isH-9(Ow1V=QYQRVKPsvxhEj$4Ykx}e zyg~_07>VE{CCy!~x?>sTKxgw-AkwON_##8gQW_^^?Rj7!vU{zqdD6PR-ck_T(tnk3 zA_yf#dc+6=$R;soe^1I(($y*RIB{W4%0P9L^sI0+^s;+6Df@iGWRvqhCly(xWG5NW zVG=v45e5DWAN7oS#_$x5gBc^6lz%LBO4~9N3G8VC^NHUiJ2(U;%Y2)-a|vPyaHd?z z@AHm=NkP0%S*Fvg*#=j-Qo*y5I6WXY#;ZfdzmQ+l>P3^ZL}S5Li+l$Mb;%2FMWL(a z;7`4=jmJY1vI5BBVI3aQgLbB&=8l<$l77hM-w~Ir!I~hAWn>gcg?@ylFn@t7=z^BM z^AmE)KEwDs0B`GwV@QPsac7LTvvT56SbGA&Lo&3^5p9d}X9ee{UA~&1E~W?q+mIc| zgPfYqhe#2L0AEUwcd0hxMr9zDKXi;>B7evgW;`%j`V~&f>zMEGSa8h|YNRzHEu9vVYhLq)t@iuG{EdXOv5+Y9U6o|1S|t^6tWJiN*n1t=ob(G( z2~Xl=sgVe6gm1=c#wzeDY`dpGxi$2_e>g_2>WPv2YdT$niWkPnts#op>!k6RCF>x(*nfW60o+6~I3_UbI_Hri z7G3SiWadO8Q#5E>PDMbg9XfU-sZ%skr)YrqT!Y1myqva>v;-~Db3FLWT4kGW7afJv zPbOfbQYV2)GXq41dP^pv-Udb#cCAU%!&H7vJV~NdQ@2SAW}GVDCIxAHy%W|LxT%z9 zQ=Olvcfw<&B!3ll$f+q=NkF9F9BjxsB^=kA#HaAd4)U7gqCmQBWRW!=U!=3b zfW$LTXD)!7yC>@-c-EP97Xtrnxvpjr8P>7&BLjsj4Yrh{tK9Vn! z#>wJ}8U z{1)nfeU0uiesI{wD-%{HtHkqin)XlNGQCyC2h=uX=a>_Ei3}GWiER~yhy-=GH4x@i zXQLCSGk+#uI#vX>-wzYrUA7C{A^f5pV;ZK?nhs}Ln>lSqc}l}{xeL6baDQl-X-ra_3^ zR6JqqLfEoOM)l~;yxVZk2mr38<7W02JX9qZAb+eOx+V~rrhm2aqXEkbH1((?k$|uy zig32Xm=ESiOe*CQbv+93#dAuk#Su;6jxR7~jG^iO{T?lN+jhmI#MnB-(J^-na_J1f zmNU4b9|ub|*j9BjxY@9BAgLbVDA#NpOh`*c>Ihh^2h=&=)rRI`@{jT#bt z(6(j+x{`m$9l9MPZQY`ygu-aTPMr=)*4$L$a-ed5*WePuoVc=i&4xCE8z$JGYBo&V zKtfy;&nx-13hEcEt`V;YIdhj=b~Q+DHoVvjc#ZZ^I#{+B16~du@2cazQoC?(EU zY?c3PHewuJG+<@j3O0a5yz=X68)5rktHKorw1j^k+6SY-hF-G)Ee9{24k|IAgQBgQ z>PmTp^cWMkH_ApMRP=bs`U+y8E_T0ZV4?e;4C-p|qI|`!D)CVcWI@Y8P1nr0pqdS< znQnIm9W@vrZy{LH`_JYy)f*|E$H@qu)5oik@ZFHoAET z>8^jtV24E7l2ZkSA3l7glAq#Z>I?pB@C*h8rY1x7JTo%b`!Al>*vNl^*hvbfS#PzVHm)$^Yr%g# zo5B@XzK}w!z1lhC&TlQNTGHWU_3z(7%!=CRTQnDGn0d%|HMIqQ23Lw?E8w3iPR*be zdGn1PU>OSK5EHsVR}$jZVTiknKrTXL=scm=yfS7YsQ@g5*NhFY#ypThna-~0$0hq( zRCHC)y7?LNOnWqWP8eu2S$YK}`1gO`=e;Zabkt2S2QulaRrGf*7QmK64-4dybcy4v z0Ptx9l|NWYj3q5DN%z?G=WP7IzJayojNQw zQ)%fD2fw$_P3z~FH=Xd{fdtpfO^Ad7$%8?7nd1&?UVS&#(V8}EKWheYGU~g&h4*>o2Ps>Vbn0aA2xWhCkytKvXooXr z5V;)c6tlP{;uU;>YIDO8z8$}zV=bKdW64;NWIU9oL0%p=v*cYeTEQDwM@EO)dHz_X z_;jb%NQAhwv3coHrSY~S>wA)=T8^p6Nxcc@L72)*`Xx~+MFf_WR4hNTSotb*SKJ{z z92e2SJTpnWEO-2WT2O!C{JGBp*ZRL%AD}*fpsNciR;qfHjXkY5#(WLbgo;!m`b-79!J#Rb{iYC zZ5bD~E@__(rIU=VR*!XAk@tJagdBb-5+YY6zWYb4Wfh6K;*ftQBj*VCf+9dLVs&6LUF*U0cy*P!m`X~Rnz99~x z%H~>t%R1%*=<|O|c(vJ}Nr}BzsLi=JPHGer2P(UV%q#lsp^~~yC+$qR-^#Y*dP;b`I|nC^*mIo zw9qwhHR7BG{di07@7(fk1|B941_F z*;{b}vU_3LQ1s+Vk56gHVKt*T_`bBIBC(&9@ zwX15nJ==e=;tl<{t>`M7kK*^w+5%uUBQpB7T0Y*wLH^@2%;)nAz-}Wl`o3zOS8chH zzZc|d!B-c|)+>KU3O<1|@wT@;(c88;o!T~(m(J7hGgb@{vyb1rcvoFAx4d`VzUD=_ zYa4vHHcy9N=w8)N>atJH9)HI^I%V;<--B++@cDn|jIHWdw4@hI;5R+N#Tvf6r&#GCJes#WwPsZVU{3(1vfTygl|{?{jZHed7zD<@2C!Kp027AkkM)$3I??rh{ zw;X@*!m-=^3rdy>=dXM9u4nI@yGM)NRl7Gq%%!`Y>X{;uoA;>cSVi})C!9j=)w`bk z>Fx8#v-0YZXL${b(BD=|yy86W-{`La|L>7z|IWm`pE$YqW<*AB+w$9LDMJt6w&mTz z=UKCHc5~Y`{`E+gJZH3N1*`2N`U>8RNmhUNYNW<*SabHn%a_#!xJvC)_8OGgR!h2l zSzWwj*KBJG`PWAa;;oi%t7YVU&Q|Lc)feNBylqRb^xL+K7liE_)PZePT>cGhT=4x& z!1WQ4*Eh7@prKS>tg5DN1l_6MPefI!Kc6Cm^sU4|sB6!+?T1%Y$(u^o`VDQ^4gG(p zetpN-&b$y7yZuxBb=J^wMaAj~-O(lAqH#{$`swX+_1DjAxv8p4{i_m}>uq&|KNkeB z*0w|7SEM`M&7Z=yGx|`=yz<<^`*DRrQgVcFNkC zq^=)s-(g3%rNU?L+((aVT1P86_O5^Z1!1kh{E)a2U%uo?bdx;PxBTh3ONo9yZ;tLwqz5gD0W02Vi=F-8j3-4a?5 zy3N-~I@x?&3EHqJE%Lt;x=mIJ6`c5N%ixKGH9AH-qxFG=w^x(jf0J=e;T=AC)$(^6 zcE#R^>Y4*Q`6NP|AVmoQbbEX E0LfRYt^fc4 delta 68651 zcmY&(fY>NQ2x4=GM%h0{2stRXel2;QgOY^Nkot=r{dN)dliiD z%!VIph_7u5CDy~2%`Smdl9CC5!&BccA`azpf`rJafYRzxm4+mbYHLshj6fNu5eG>c zsmIY=+_%!7sb$*h9H-MiMd5Rj1FS;_d|n>o$z1}epW*|-0;9P=tcw!C8Rq9o@KEsT z<-0*tZW2-4U@+Wmz#So~Xf$jIP3mjYv6>D$f-)MHJUrCiRbc>GIxQ|Ht!o*~*yt0@ z^FOKcHpvWI>_%ZEVkmrJ<$rV@P?gaK)+Ln4dW9kb?=l(uSx{XhKFWyB@3bSjA_`4> zT-FfgcLR5!0%#pD{k=pV)Xt$`QLky_r>TCJ;y>Y z7TQq%h`jqb6*E!gMs-oNrBbK8gx4M2dOvH&8Si>5!8wZnUk-P>soT5cEZ3gtLb$i< zube&nG+x|0YP7PBt%L-Hw3n%$@`*muz(59r^H98tt)>1(NN=;u`@+m)iS9z0TP@>d zVsA5?uVvb^m|N{n=`wfzoKCpZJWtctbZx`)0FBf*FTzy9)ZyQDzy+b9?kRr| z;{~$|LN`UE1|TDb<P?ImP3)1NcxK15}4xf*32?_*rjVT?4@a?S*kG{eDi>Fe`~X zc7`@+Z@ldx4YkT`^#d2!!0;9J|3fW7z$ACwiCeAK6sFhjR3!fS`5N(vo(! zcw(VAEVa}gi0#@&7MQv1`f$46LmlteKk{*P=){n)Woa!8k-FM_dSSHc z>4Dmal$cwWSFAYNk#^`D3T=Cr;-;!PmNJvaX?ymhdYGEQJ+!<12i0Afn7%4o6W^SJemoqMOi8mDXUtq! zl?)Dpa-JqbEJ^hyqG&xdTdMoFnVBbtycJ6(Gmd;V_P6gvG-X1u5e^$Mf@0Vs6$;q7 zXnWDUJv0H}H&C3PX!1a-@+`d&k5oPE&DDsi^hHJ_x^U9}!TaJ#)~ zepwMZZnm3V%8MSe*YN*k_s>FLtkXyCXPupqi7-F)j4-EMj5!7)7uR{L_l-jwx6vSL zpu3MMbHZxxlYJyQ%GP9)BL(f~XFELMjUDDx+$H4vEvR86Dm6f$p_F7U$BZ75`D(fd z|FjH9vi_j7B7?u%^NfcJ+VXo)x?09FrJ2LnYNhA7T7vQB`B9@sbs#c3d0P;6Vn7BO zj+G%2&ni1btP^V9Aqw${ov546D#^ia9&e+QdNF|~(rE1rKi+6F*%HaEHRPYqZ^6ui zqFH3EB_G|mUsOsXc!n^PtdiSEX;`BH(ia6_Jr-p2)*;r;k@SmJeARIy;^EhtbIrtL|qGJ&r1zVgRysN?T5j9S-k;( z;(uT31c}QGJyUM3XLstCG_1))E^|lD*yh}~=%cwWpuT$-9y2)~tJGp}nDGhHv*VD_kHB9(gN3?W}9$?*9cv zJ@s3V`AcH5Gz}Y1@P`$tqAX(rYyLP;QBz0eJKqn&Qv3um%tzh|DH$<|92HDG25hGG zm5xe92SUL2rho^zqcXifyI2h>Grfc#_DFb@Y%vUkxJS0%xSF^{qC_&?@Nz(iL&R7d z9Q@~nCSXqlbZuKIU{8hYSspAl&jPNx`B_qOo?5~Q(+DMbuf2#LYZ=P+!4GJhf4_^_ zVca|ukmmHlokO=m3)BxorXlxH4OWyGNh5{G9QK1{xgnJPp+}94muYpgW&)C#3`cLd zoT`ti@P{#qvO!yz64R0|V)*{`%coZ$?;6Ot@A-t@^eQpSx6-a7eN&G{`)TkRT$2;x z=6O`pgIrZo-?AFMoM>}7;0utp#J}_hUVt{g2jHtqz|CmVg~A%GdIgm@xZH7yV_5F> zd?wpRtpuG)25f)-qhm-n4{;Q+A;hhi7!-naU!30=-%*r7UQb&u^ zTzL>Zzb#CW*WP4{pfoU!Xa+i-&*}M`!ad?SG#D`zD2ev9onL|)OZkXF7aVMu?#n|a%)I3l1nlpbY;_I;5m5I zYc;-|UEU_sdao;tlad(%BQt`2s;@%H*LTHn8$y07Xu9v>zjQ#j$8~>Ajm~;6bi6NEx=b2aBbmj+lU$Y$ zI7czoTr4uHHUfxaMK6z{tVqMClO{ZTfj|rl){S;3qLyInwq7Jw0+WneqHSJZ7*;B1e9bJInn3s9f3q}bQ6TP z-?SqiT~JWX-PHY%znuk8G*jZV&acL2oG{|2=3WIu1c6#QSP~tCY9f{u+ z8nXdZ_!m-K9l|ui0_+QyO^UG)RjqpSgi;qHBjz|c4SKOmR&&TfWO$>A@GPCs9Iqfs z@_!DMsernxoE&&ZFLTTRaPV&&xsR&EOHm8mA5IS8x|k*L{L*Ynid+u^MW}dxBO$qy zY(Q%dbql5ZC2XqXsQ$GWNK3xh-bLtEW-R`UFo7q8Ti_e*gqa77f!v{ERvZCSo?a8y%TRIgU4A z8p=q~v;HwU+ck8b_eWtVYA@G+r-hBE7>!{7pvz*vyEaX zq|cTuNW^Q%KnqlhGRism`b#$3LeW&S1^lwv3nN?V;n=4YsAqv>kny8wjE5%UL9e*hoEJJ5 zkCSN)p$^eR)%-Z)r~YwkZjGktrQ9Cwf3t19QwH#ySGNbu*_Q;h>&^=Zp@m#nU!;{W zj#ILoBiM^NA)EWUJ9aBz%FLO0T;s$3up+Ey&YAcryPa&->_hm3|RIO`!NJA8aH{vlo@L3%RD9ART#gfO-|BMn}K+PZs(O{Fd?s!A6<7g(JbZ*!$!*Sx<#0GP3%4!ml z(Ml=dj3S^7$@G&O77Ve^BL@z2z0{o2UWxTLGsF|gsKQidG0tf35`=hz-cJrWBNDFf zD3rRkm~2tE`Ttxm(#dyDZkkS;1ppzJ&4#=e)6bUJ`t6h27<+Z1hFPr_={>K%=w+Vb zkL7St`{mVbHW`3NUz|~n=3}`cJAUE8^y}&8Ou5FUm5eFcZx-IPBLLE|QoNPNNVy5X zkhl@Jz*xK&Z7*2OR7ZfW8STQv_XGWI)D#o$UT4aU5g$ucFu%MtoJ&4b)7=&MRNI zLo^Hb9|W-I?lxK?yH}%$l9J5LPZTGQ{w9Tr2wV{Lwh)SB2~3BDZy%F#AVu+=Xk*c% zmJdOanwc(|I+!r3A@dZCOLCI`r%!#%E%vJlIbOnjHUfVM3_#Aan92zhLx-pin6zKi znL~%oghKp~n$nSUi4p1|vw&yUuIb7B7pi3663@%Qap-;HfGv=0%;)w88Y*V1F|8qF zg|P$?ixQ-O{=f_=v!cRI)c7+T%ztK4QmyMbzPk1krF_0hAqJ;M4T|0CQm=d-*JW=Z z%Xsh>$3r_56!4KrY_qOc%!4tyi*MdG<+K%z7w znPcBp2`Ke84jfFy5T^X246BqYbJd8`6Hc}U_n92bfCR#Ffi%6-My=GX?p8p5# z{Bzg2DO;T0J5F=kc{(8AhJ6xORQXpC5o~SnFG(maK2GYNh<2E4NsCJ7 zMTQVGn2vDDEaiinEeG4U{s7Da0 zx&9Idr5*WVCRB3Xn_R@JTbE4Pvz|b<*tbqdT`MT2=DfS7PyGx!)vTYe;g$j)(YCVn`0zqJ6*3kBJ_?@DMc(A4eA_UiJf`e@Lp~3AzF+H}^m51*Md- zO3K61psRoH(a*7jQlj6`F|TI4FTpry_$Q?vq>>2OEyBH*++RTEw*ABN2vwJY1k`m8 z8>_Ux4>1PgbF;}V`ibUX67-k${n+kf87tFY7Ic73S;K}zRzZ$K2)>eV>yY%=(pQY0-0+Ckb__3+*Qz-Ij=T%>FzE{7g zW*=T-MW8x^a^2ZcmTf&+`1;BV{L3MC-bDXb55>E9J6pV%pS#2ggDu&|`YfBHqW1l? zTSH&aNtUasj!Mt(9M|zBP0|x=P$+iJF1|2uHlKe6tB8P59I;OzqmJ`{tMoawETBS- z>TBi%uJms>S(IB>tWH^dp0YENU|#iN>EWk|D$?Fc7g^y!^lS6As4$2KG@eB>GF~?? zHy$DgUT9-nWe|xLIWcS+L@GpwX#u{JrK^@C*LU1W;42;$cZY&V^QJ2Dkmu1Zp1mx? zEw)73NDFY-i2$a*0)3JT6+uTL^ZHl+EJoig7HOcZ){)6dgY1y6_;^p;Le3GqJ-#1D z93e{RtW@2dGFo`afkbN<((KmZas-m#6;!@5s4-u7cd!$c^e<-oLlleHf*rGaK&0P1 zjub*S$3jgG2&dhrCuw$5nDr!S7gtTU##ZZpX8{?*Vv52Wm0vri!;2)v!=vSGv>h3j zbnfjB{2b3mZu{OY8f%a-t%=)nhAdkYVGP>P~CtxYwYx z3VyF0c1k>W+n?bRs6@+U%1io4TvamVd?d9pmAc34EdXeN*0^U6KB9;k+<73sG9erM z*eC9Pza`-A9gM+4k~DxbE@pznf*DhcOiYSF7b=UL4Um2B%9(;kQ4+$1aQuA$DA6Ca zccGP2t0FVbUoj?jAeS4 zvi`_$9PEfo7NH=8jHMr7D+BvE*tNhHU3TD|vtJ^JYh8b{)mbTo=~z}IYolXNjWaIRZFknua%JAK{(NfR=>yek7X3B=|ONcP~1bd%7W zzZ_VMa(Gf!8U#gSrz-z_;9#;H2wwX8C?1p3B%1WBYRN75>nqcbiqM{DV+t;NkqiMw3zZtT^8NNoo_&%hy6bx5?8gXn%bOyWxFbP34td zc($l7sr2xxD&SQ*1>3&;AfyOQI4@X7;MeD^E+KM)tuO!=GtqDc$h=&w2VVaV>Pi{+ z8P8+RMlWK*xy0Fb0^5=uxRn4Gn);1@Y)B<7PoD zX&iKS6a!`vl;(~seSOR)Qa_27%eLjQD7luf(zrUKk&mY z@9zxXYmC;`#OiFe6c0xe2;m#%4Fb**i5riw(MU|zEuIegC;ok^#9Y`5PFQwWCZ(z8iaH#-E~q-Kb1qa2xaox5l)pv< zFny!FzvX?S!uYoPDi>osI@MfxvdXO0N`rXA^r1KzbYgKaS+?4-I|WtP#MMiASiSXO zR{#Qn9+!O4)_L!=CQnTA6PB#!5ygiPyFw0O{J(Jg>Z;2$FT$H_d{F$)qVvt=gyF^} zmK8sJSEM!+vWxi*RKiN+7lh#x$WI*)m@hH;OaI{yM5076EDUYLsAWD!&2V!_1Qs>s z@o<#oj^_-i^WDlKF3OVw=}l%{;&_+6&Jzy72m*ZPoNn|VOm4xxuD&U8m^PeeF}CvhuBQT|9XcLI$MIWn<7}17D?u=E(!}-|v}YD{4Sl z+;E2$TN_d*M;eq_7!M(v`sp-b=&eqYSuJp_X1ILYW`#Vfo??B9(2pcqX51`KE^s(( z4wcxgDZS~PZ`#i>J>-_29qk{C;O9th{xXk3i`Htz&OeT-z0Lzr&?^{wT6R6*o|&Kk z&Q#4VeyoMU)ss0i=D)5bod&aQw~Iia#P8AQo$oE{3ot(yWA0G!fs9%hy3ayL1dsVb zWJE2wshyUI)?PyR*i@)?wSFJU1xh8hcb5-GUQd>*fTsFp>b~qHyD?YEETOLn6pWQz zJ@DpCz2?=sUXrlhn2i1#zLs_WHc#W2-+^Klq&>TL5EojLrT$+;;0ZWJ^pWN|EojD7jR5z+ zqocILzmhx0{DwkNC@)9Ch<3?}3)h6=zP$d@xT^4GLePXi4*5Hwp>KM(Sa7vVe!(=i z*WYw6PbU1^;Hx_$$5X=;Me4w*(rd7vqJTf$Z+*&m$QYwc1Z~Ify^@`_AB>MI12P4- z*bXEtH;%6qiE)UT1UIe=i8Wnn!mSPVw3HW8%*mu?Lb_!jP8c>#eW6b6MJAVo?=wkj zQjaxnZpyyj>szNnC%-;#>Wr@z^UURygbCf0ggnZX-KC^4ji=r;M7`^zPth(=dBkY*M?cyh=1QU0xOwsG z!f#&w9W%tD>=Vu~%LHLRLEg}(A1(x6%AAeK5-1eML6G0bOLcmogRNjM{i?qKxvdFL za6OVpg&S+GAerQRzX!s85XtF?X|e@<$s#;bIh4{QfMtgo@I6jHZSI;i%Sk>L+-6;& z@F&23eil;vz%|v!(|IGOqNgWZAXqEL;S*PbRVL*xNaBInN3Ke$MUv6AY9_F`+X*Cd z9g{yP)K;!h(oAN}+PigQY2pLf`iyScMuY=sH)%4lMLxY1))Qm!E^fWei8F>i1_O2ZGGKlzQk-U5(`Ra8iT(W}U za{uO822dWJk3ZI@lPsWVAh&{W>uz^oDJNaP&}g%lFe}ynk@SWU6w3EJgUyX>7^`}p zd5d&c*Ab9;HOKxDGo!RBx9{Ip*H+^^qj4`BRnF)}_&9IG*)M(8ctrRxZ4vu2Mxb*% z&{e~CjjSr;C1w95zqzAncu3`tnzXS7E7duQ1E80`kY>xX(@>lf;MA*?->-Grb&ql` z;FRg)a}99r>MiE})LdRhrVYo#b-#PC*)p9N$vFzad7n2y*3gsexq!3VSf7muur1L6 z_mayqU|yvBH89R7Y%a@g5kki{1F`F%H;-EimJlw1k9tIwFne=q078bhWl9d^F2dC= z1CS77Z{0)qd6DOn$b$wgdz_i}_Qhe$BP>Ekx~zM9bzYRYtkd@BnNTbKH^?Ec!W&vg zX9JZ|mr$iDb4blMa`ln8H0(=sbBDfs+JAB^D)^Gbjb4=1SN)4wdX%$B4Iq=D6+Z=kipGH8Sy&TXYl=arC_mNy9aBug zB@_8`c@p;(X>6S9Iumxrg0j$2$0>8XOv3EEY>e(R=VyPMn7RBukRrSnnmLV{un5P_;F-_t`mlF;14W*K}tm%5jDkhC2TI`6rrk! zjVg5 zU)b?h+-#~dQd9Q(C!-1XGlMnvbFS9R=NQ6?-#${GIo+vWh5g9W`L*%LQ$$9C;o>5t z3a(_T%?lyfiRRH0n9t9sbmkj#aaP=VBX+`iFfxL?>A%nrpYDa9zmw7xAWJ3UQ)J_e z2vCUrCdM>=m^}*0ncXl#15K{cB5NZh7Zu<>kd5GQ7n_Nhriv*OOHOCg1HG5+`~f|t zM9i0cf8X@OKZVRl_7ZR$!6Br&G8~a_11_N01n%`{0F!?kWAC8m z94hSezgHXg(RWJ9(gP2{cw^|bA|eU%m-ADou&z%6zKbU$V3z>z+3g3^=OCJjA=CJ2 zEayYn4O8*lHbxF!LGbq1{{9z(iHtLX@9g03-;BjR&OY_eb^>x@>YeEaM~7cuN|{71 z%((;4pNEHEw_mwZ#sVOJJBzNLyd@x(wtt7x)fd&oGvj9Fb~fzTxUwB(=5B1**txK? zvGBJnZdX=;&B z%=IYMJo+{En=UaKi?3Cyv8hKd;&7C-o?pfX74<&J!O(YLMcIk*1Q3)wte=%uJnd&o=i7j&zy%WGjvu$cYjal@;6$=UYk*q8%0^`N8YAna zq&DJteT1JGY7BxU8kG5nM!=%Ni;q&?qh95vEL?i!C)T@D;@92R1>AUke;n;??*jvd zEMO~m8ueq?f#Ngyl{VXvXC-K1UMJpoML7pMntJ1#IYDuSv)iM8>DiT8#XkQnevSM8 z{Aq1b%gcvIizu=oHz6R+7evy6Bx_rJp1dIT77%Wg9sJ_989Zj0jJQrPKwdQdzIc*h zhla*wi&DW`nR?ScjQ+NY{DW$hPYZa4W6aBAT@HA?m-<$uq(M|wrf2qCFu#Xe#rErO zGZ;M(Hg4#k1nP)yTaG)w9_{>X(-kHW9uo*Jv=8PZkv&Ma3_SVO_# zPyEyJ>FF?`5-Km=oH0GR$_!MMoEQk7zBAE!F%Sxe*sruP3g7% z_09`7L81SU=-m&(5^61|I2Rh#kj3Um&dZ1&xKkBC^VUB^=cI0s`IQGVu0zrdLSd`= zk)F8x&*og~F$WaVInjj~{=M~!i!9EIm|tiTor%|;`}?qXDD+FuhtIGa)8x$8z(V61 z#0E>69V#NQi>?He4H6D%8v%5%(@cn}G9v44SYZzIGL@W&%LSneZ!sb%Lvb6@c(!%7 zkmwf!3!D;h%`;4d+KR1Bha*xus%2$)fky~#B3t2O9E_W$V``Eti7;C=JtB_+2+~gj znDmaDJjguoMIy~uU-X2zA7{m|imvJ@F>*ss`QevBaGCKc#CR6-i9jxe?IzmB)A(&6 z!ak0H*e{*Zgry!Yu7*I}-4Wh|jj3dhu`7O?1P2PGg1hLk;3_vQwB+lIi&F5Gt462w zkSyrv5DqaZ0bI-k`-=aVYw27Mm380ucaK=qb?CRt)*h}5y)64N9&Nl6Sw<13>fxk& z^=LvuzZ(JZyH6D#1i(7{DmJlgz4#^6qY5tTazgs?nJ25k=efvQbqj>l5nOikJbmZS z*BO0Il4oOn?Z!ApvHo7ep>KcNs0VzaJ;}ZbrsL}m7qaaf(Ys^(!n3&;!-YELo+QHp zbFV{{@SxC`Ffta3F_L=Bm)fox6U2xyi0WJ_ezHLH_Vnum6o4OoO)nPC+Y`dwWY3pCy1cj@$Pc= z^Kq$Pt>?@7JR>CR=H;?6xSoLViPP|=SiwY~?T;sutJWLEHRC=k+p}A17hs;RkwK%67G!X%cpT@u)aVg+0 zu`H70gK;e@6_wj43VKT7)tu+SHs~<&W{}?#W9;b;U|!e~PcQvg6^i$m*e1S#3pH** zav4*ExI}b5eLZO)m?+|wmD}(`4XW~iFFW)weTQT*=v$XZd?`%u)y1U|-~;j0YOc8f zm5Q-oD|%rmJXKGG&k9`ZHe1CPivxkFxEmeMVtfCS+)dJ6soL$$25;Jp34>NP7 z{eZCtLKyX}<}E!^DSjc$R)T0_Rd6{dHVo!PKnijvl!ZaJ6J!ob3}MlLlz2#E^nu_0 zlO-cIt+lX=VoDE0XMhP!a%evZ(IRdXC2pLDKq2zUJ?0B@;*(d59pz3oMn(g_V_SAk zklS&2WR&~7{4#j{e9cmTB7B}fLfn0t#WuVEt_uXgCs|q|#NP@^Q6=?2gvDcjJ(Q_X z@_6>$gY9wj7WWA?js{9LDex7$u;8Uuys17WAvgi{0MhH*@Rs8xxcyNUq5)me;?p|D zzl`+*|4EpSI*`3BVf^4u_+G+PKsk{>{=-^zk`yWIBz+%|w0fhoQa&|CWn(5{ZUz~U zqjGZO4Aa?4k6_nHujJ8H0}m&EdY(((sh`Hqw88=NQZdh<=`7hBJD~QL*-KD~{D|k} zG|)Cw%Kv#6kR6d{>b(x7YWOyCpZ9J*6DNS5OXah-J;{$M{^fBM@<*W)E{y6oyPWQv zL(_<5|6{6oxEQ`ikc6Kgin5WYOKS?SVO9w96x>EXMT2sOfJW24g&wP{w4`xWn}q3JD&v*PgK^5-37@H-^PE zSU%oujJpmoISv`&R&ZuYOLrc?e5jfygGIZl1@$76*03<5MlNZ7SC}P0k)ao=K$g0| z-xoC=rUVNzW^(+X(1(#mHiO8D`%98|CbqgiGgKP|k8`a_b-2;iN+`(n30fHX>!-fl zxDLUEP~ZcmYn`Vdm=1n#MEE}xXiAUXBXScNKj@BXxXC78g{eV3>hK95V2Lb&;%JaS z2ilgI(3||o*q+U=Q&yj5b7GQ8skAKCIX5~IOm3R#Mt#@##QuB=EsD#9-UhL)o?EcG z7CdXCTgV_r*{NO2iS2gt_qtK`D{=iNoK`_S-oD5=PnS4j=E26=Hvy@Ou*BHoXk>mO zZFIli@~_u2Q!0BAk?H(w|wAJW6`} zAwv_LWS%o!#HR1}(OA?yn8}ru#`ucw81CLTicIKmGVgflJc_mQGQYI}>*v9og#XfUM0dns=%N7_1qo6|D$qlJCv zqP5>GbrUBFlSH28Z}#TCCb5O!_08C^pwg5c)9 zC8S7S#LuTX{u4znnHU>Ev-ZZqgT=k6hyTVX1lbh<#xdpaXCy`1Gl5HbttONqWi>ZI|C zutRpkT48|_j-S76aAYcj(BNN^FgLZ=n`ECleJyO&9t&Ee-;fUquGfn(TShrz6A%#B zh1^m}XhJ5Qlsq2mJ0{U@%NIu_FV`}r`(MM`xc+eZi~k9Q95M|&^1oV;4V*A^S-Wr` z!~0tgXZO5?IjL4&lAnlPh1?|)f@sWKBoG(AA#VsArvFAcopYgSEOspj5FnJd5Xi9R zapqyg2)G8P5HzDRdO^aGQfI0{@-!>-jcNUvs>@6gh-Sn~-0?xQYqIf&m>JAW+{nVj z2>-@0p8lmz?uE78z5x3pldBfr07*Ap6+Vkr59vK)~`6+&QAzlH?Kr8ZJ z`^5#I$D0RhaF0M5k$4|$g}S~34F$$nMjO00u_Nea6jW9`Rk(*zjQ7xwy&IAnpgOyv z6g8a1xc%4vj_{e=B-!{BHcct2NN7c?sqbSTV!}*FpmRKaK&$+e@nYQZ5@onqdtP!JF?QEVu(g z_PZeJeqZF($r-K15#u#7BZQCzSL7cefl1DnYxBX#pAfuiPolVO6LHI{Nl*RD?^qx|=$bKJixpYg`aJ z<=b{{6|>7;RhxQ2sT4MeGRlYD&8WqkIgra0G?^8@rq2HP=UF$E{B@l5 z4)dYEJs(HSk$W?Lf3t95^MIXo_nincN#XTq-s7HwJz^eLg5d}MK15g32%nA47RLv6 zXek>VBsD?_Q+{MgKICwFP(2V_aQpVS7C~_j$919~ra~J|wT)0DLs`gT+CS`l8N81d zR>u!7=`}Izvju%Kg#^M7@#JPB&uTPF1|~h=ZHYT`Y0}vmV*WEp32DHY?6gicN0;^M z_v;=t!mQ8IL}U=BiiJlQ)d|nyzeFaw1XeH^c}1ku91Kjn0!U~95=B6{ZO`5NOHPc! zC5QfZY>PZX_izk&8ll~gN*}~t)N4p!lFYANc94BITc`)xBN#pASNPLccmfb2(+?I@ zW4e>}1YClhx?+V8h;ht=Mj`oa!al3N5v5nw!I}0`lUTNHSy}9e^K~+_Gt1MiUM_de z$cPHaigQg#_(cwGZkfPz3&rD-DJ4yIuJ!b?8=Aa=!ljK}b0;I^U8n#vzu)F_d84gaF`SVZigwf`(w$id$J({c{cJHFak)mnW?)mMD>N?j30=<|N z`T;`beaX7-4ZL&D98#-Fq`4O9_IB+*)k-?Q)*x{|v7Mz$d{%&!4i9O?)GO&_7yDm5 z{h+6p3!E-xTb#3P<%xe(I9FF!Ia{JP6+?m|H$*Alc6vv$iMdPcl%#sf>}uV#|ELx| zvw=uF-p07)?#B>7*gxFX1=%%cL2{DpO!LCepZR}&QhD(bECcsuS0kN zh23p3ct_|V8npl{AfFh*_)wX=R;2Buk8qZ2y2XF?($I!lhs@Ldv7(h?hnKgk0VxZn zSZj22xX{Oii(k8JpIKu~CVnE3bzAm&rcK*gSHUWC+xL=K7+8*wfxZ{J$yzE1X5E0) zNhTU_S@2Ngn~kQbRDtko^0VxOLCEDS8n`c=npdSUu6TsBf@IY)a;_2Cor>dE{ zpTM(9(vMY!8VnvmA^&vts~Z$3T=N-Zl!x8JF&(>%>;#lCNT!5_d905>kRhx8fxKNA z`n?LpIckj@7fv93#cxY8x=cpr!NJIbB@F?02 z?LZJ?ZbAqME;D?SM_xXcvO^J|)d~xH2y`Y%rx40(^UB|sl zVW8_WVuppTM&EM~7(78BDZrFF@}@L#iguI=DmgR2W%pX`RS0kmt;)f^GhxScz9Jn# zuHgW6`nZL4BWDR1r`eK5yMo_~o$GKI|k>7Fh{CeP1T+kz%peepkjO)rF2F)w|ci!ruT1TQylN-eP zMK*6SEE#YQb)*to_OG*$*@DG|%-Htj+}LD>VDx#xnL3UjUPgj%rXhyr7=l>?lZ?fm z)TM}FsA(bnoN(1xP6g?F_>~s2Uk-HXBRU+gS5O%c!Dw0Gsmj4w2zsXSP;gvQj&G`d z@ZU!9^&2Q!01rG&X&T3n{UB|ZJG8|hN$+s`88U>?CAqm45>%BP({HX0#R$L%LA|-l7O+w})JVbDFj8{-clEuXV((o&x`6!MB3>!On&}xbJ-(<#Tu&W2Mr_3E1zg>ll+YwT> zhc?uP#L0KJ%iY`~WOPfr#z@mluFPWsi|zHY+Y(NHk3$n}#2QqlEn(ZGk(M$}!V>6* zPL9O313%417BNgG2LWxhU+&>1Acq{8=^}Hz^lPz6XFs7U;qM-?hlVg*$?)WO`?UOZ zrJ7^TH!LFIN<7W{Cv}LeWh9gQ4;(B?!pk2rb~Q9W#SF$&iqq+Tlq?n3DIpe<2avA{ z^y7$-rbHu%=Z0dOm(SIUE=2YVP2?xjM_aV+2~u&DYct&nu>ccc{(fb>sU_^Z!qf6v ztgN0e*H@CbPPa)8Q!T@xqK}_qj zgk5t`*@nft*+dSE*6SiGTQ(HvQ=vk@B*I%02(a613q19uNVMYjw1M}&kA5ly`I64h zZ1uM;hS^fu`iTba`|nU43&3f_WIM~pq>v2srh*D8Hzfxjn=B77P{QZ9hmyh9q2n!- z(@}x#C6I@d=r|fU4ceI*54g62a{hpEDpUh~rvMwXs_E31lF42OrMp(yz~AU9QIE+i z5yI-o2ZTg(L1>0egFq_a=5B;QtOIdP#RhB#ae@@=#%%>fOVI0iAQfl8Z0SI(S&bZ` z9q|Ua+pMo_Oj{~|e(ttspBZ}oQ^eG4=dkbL)2(?z&l&t*%iQiZfsILoCi;YzM7(~% zLDA0B;(^+2qtBgVP>7of?ozKEY10Fr*Aqv0fcUL3!ix)rlp1xCK*E23J;F}9?|VrZXUebk9XLla)1T@ z(<-U?Z_g`*xTqV$&uK~_acG)FJcNWO@v#$<_aK;rCEjv(DFV8O5-9><6BVCK5Z{~x z0E)00uY)_EXI78?T(&wGVPvv6mB{ zm|ZD_b4UBlt|EOWE>vl)4w z-dPIt;Q~$A!AOmKi8P6;u*wppfP2{+;Nub*?_{ZVTN5Zwo*x|YAhjv34ARTi^P-m6 zsp$9AlYY23pIiKSpe^-R_;vl6Ee!fPO&RHvzBJ!fM#X`uiVc#UUrq=RfsOQ$ApPim zcj*=}ejM9@t-yXzO^p3yDCHWbaC2j2hrK?cRxptoR#wqzATxafq=hPN zL*3o2BrWUl&}V*6^ihx1`b#Ap$@WS)E5EQxal8pdpl~x)CYR}-QACwvKI_!?&(MnJ z2!xZi=5imD;5Cq*hF9G0kqi((Ozz3d_C28w2|_J$GQ$$aOy3bwnX${UmW!iqQPg@W zMXu&MQXg-@8;g=SswTV>n=+sRENNij6d|L`TGuX}DdayALl!}21Mofu{+hvkAoRZ& zv@BAbLBY9UUQXw@2N>hR+2t<0hRq@fr~fpwzq-&0_{`OC#*P|`(BW&(c|GjUl(Xwl zao)Mbo?^*pC~e3`xrv6n6}lFYo3ANwhv4)})9U%E?|W-~e45{IJp5z*YwW7CK>cL}S;TPz*@HtQYFVqjkKRSPK0x!o!R1kY(iNTDCMR z-W*w@)Ccf~F1EXys{|KeV$CqeH#oLzXC4}Pq69(;92-*-rlH@NM}1Ys*KL0?AcNHH z*z-N`Q3etI%Qd$9?D%2{w@R~IL7iv@9Z8qb=au$b-wOnbvpkU;rwF4+L4x}7Y85)b3nG?7>jv`5AjX( znOduXn;hxoTWjjLw}$cxgc$f0#g<2Jz~`rD4Nu6=x4svlWBR~Rm@XeV$i z7loD=z6x>Rj1+Xi2uemQNEl+hO@^M>%Vox1Z%RfVfq~(BZs4zX*Sdf0O-RL-Kz^_{ z)-?r@9W*#$yYnl(OKWQ{scp4T8@Qr9w6@lvV1y4j)%GT8(En?NUgk+qXh%z5E$z_* z>wuQ8)~v^N!kKHqRPkMh?Q}wUZN1fAT|Rm3=IX`}G( zN^iES>+V$5-O+1Q+-ZMyR@d)eaaSPBR#&LvBPqDU=8nGWVcVHc39+UxkMVf!S^;fR zv7Sk*nn-9D*YX|gWINc3(WG6cppL%2TBEE^t+JMkdP{FY2fKC3szatNy|o^r$!eYQ zTKe+RIvweRtciP3Q{O0*v-((j5j!skCsw0N%ZYrogqXwm1>t{lTaQssOJ85Ds-zYj zrrTWkF5l8u*CiDZj>`70LHR{bFr_)WX}~Gp0feU6P4S%95Kq!7Ndn%^O$PD=X`)dueSO)wOjvgw>MTI?HS0XjsxAVAXXi`p>H)!`&=PlvLMY zMO9U|S}_2b>bifAQr%i*%fGQzI9$-YZ+y(l_g5*Tjlk2%In*xQ(uRV zXM1UVYfI|egreGY>RVe{-&&3OXy3X^D(vzJ>@2MiCg@eSqC!Fpt2HWYH68Ld{G3fF&@R=B|{T&<`u8Lg@c34v~~ znyV`$R9IQ#8XvA@HFlcyYHTg5ah;FX(i+=KYuv0=;|3qFsv4nLoi3|-NsUm>tF?+6 z36XBrsc~&-jje?CtE!}nx>dHayXmgm*T~_z9Dp!|P+2zx;w92)rD$f$|JnEnbLazy)VnEM}5s42Y z6^19;nt-8CB#4e0w_g_sgmf3j`7IF!{~qR?ge{FkuUD<3a|8VVoez^#fugJ zx+tohjspMYmM3Zws1?@PJuAYcC>@2$R7j3a&yb+f0TZJaO$M}*=sO@lYSLLhtK(CB z(^9qVLg_|6j2=~eoPzG{Y%37Wm;#P8;sB(y`j%zXFC5QiNxwLqj^qq!F4N!5lcE0wrQA}Wq)n)Lm)5|Y1)!7+NW!EQK?iexl;)@*;9 zAjVs>tS(i(FiQfc-rcPSbK_2zRwg9 zbD?7v{rWM;UdU6r0&)(B1^i2HWYm`0C$&ZUr1qK7#$Ddiqrjg!A=U$kNPkLfr%45f z1VEu5<#8xn`89_o0d!y3jx=#zXTx}P2h6SAxLwUD9 zP|z^IHt-OZ8v+9R(4E^@iDTm+cl$cX6rYJLpD7g+D-I*t_KcrT`iFlyohoN^3+N%z z${3DhXeVDV$|-vj8K5Gr9A#6^<1P>8(i zeF{hZ7;n)f#Fh{F)3~01;0IWE0K1w8ZUZo)8sH*oiXqcc0}%90A#gfUj7Iv?($YJ^ z$_gV+>_q{%KY0>wri6d5g$0v`tlTPrWOud$JrrVm^7xn@ax{Ym@9}q zb)!k3tySBc+}+X8+Zs@qNeRi;kNN zudq62LF5Bq>61FY%3wYDG*E^lJ=7C{k?fp?av60cLA{a4^7v5Iv1*b2fr}D}mZ~6} zmnmh^5c(vEe0H@Z5$ls2Z@)(nyDw%%$a`}^LHn8r0;e0os5v9Gwc?yM&sfb)O19)V zMi2}hoN~c-`1F4)ag(;p1&oCes!fO`7x>pksJ1jjKO3Ri)?y^Nj&e>wwF)PZBt!#D zXRIM>OD4jTAa*zA>M2HG-!97BEGpk94(>bb(YnE<*m47G*|!aRgNJk2M|6cUR9pU* z26PQ&m@Ne7jAOP}EHG#f7#m=)U!;n=J5_Z|{z+R|VVr+TprIx}vBJPQ5d;LW%u`w|a_Eve(-8b*euqs8wA3;j)7rWSuyvUYYv1s7LIy8i za;FQZ6hV~)bBQEgHPTdpNfKD*Y4dCgOq?BWj%l)W!!mu{pF#B5nW`aQ2RflY(xlw# znUK0;s*Zn2(`kaEfOG1wU$0tcz_YEHrU|{eyKA#2OHi{{)ntriNcA8AHh7h)LU-r0p}r#sL^jOXHbN z+ob#@BNSWw-h`3QkGxP@Smx;(3eQkrHWT*JGaY}k39VTrG{C6YN*8Q0so-dlI!~|( zZh~#@8*zQ2hNft*^s63)No3% zCq6{NJ4XQZ~9T@u-xN+Q@cecD0E3OsG2 z$Xvu{TYMuXM?6daPqW=@!j*;o{HfDyYH1m5p$x18zpQGkoHmrxZ8oKKcO?0W!%O!H zV1jPR2(ywqwB(kw1~9$U@7ckSQf1x)dlyGv1Lo(CL9z z3?vsy#+F701k>0lhA)n=vEn_J_FX@metjv_T+xzK30CgkJT*OpUB4~8TZGL72A)M%p zn+UXp1Rx}&t$@blL;w*9Xb8y1RipPIqz;W}Fk{dR&M_O$*^~~WFnVM%z}J6KnSn!T z7=1easK{b)HUj-qTXjIQtK|9~=+TDiH zD2hEjP(kQS=YVt99RDH>Ujlz4Es?^8*d1-dKT;X(wd2|T^)~&Jh#^c*A8&j5*ud02 z16gLEIux4QH?0`8TkGq~1AqGoHN0p->p<#Be8L(d%K>wpt^5LkZJUY`15K3pI9f&k zo)iP_c2^v)9eE(R4$S6O@RL~BR`BwrMp1lJ3^gCar=3Uz4MqwmV~rsU zfgbsvW-}b@S|L_77E1Zx@aWTk1xFt2|9h}=yuYIuk$&OM1C?DtlFJuG|4BK{08jlZ zyyLp0+7NiMv{%Zm6;OW(DGf;s{7Nx{*qggMPwH%rb<4I%4%mx`wMe9o{NX%Q34^!U zUF&p+(>|a0NYvSIod&X)8p8vx=mq$nLx5Pa4u)haB=ZnSMRPEXLuyR`Hzu%bV87t9 zoslClja9?*ZLBv26C7Y76!02z;R}EnL=y~lXEWDxMBhai7B*S5k}ueLP*G(5Yz zb5(pAo}rL14JSBCm|;PXL9APVdj|^V77vt_C(=;IR1mH6+6oQjWp10s!fnwp6(!E} zX7_gJI>UyIL1c)%;jQx0(PCjZa=m{Gp1zr$>W!Xt2^|eEXc%UJf92TNZh#!h@vcBV zXOo1X-VnzQ7Gr;*sdPd406egOf6W(7vKx%dIkWA!yJJH|&NNdUnSx+`q;Y`(?BSM8 zA~e}P87$izoxXY%oo%_QjfSK&TLVz6>j_+hA}wGSI2bYO^wlfSfQf?WTr54-3`8|( zoC>$Rp8}#mV|Oj0LyJgLi0};Y=T;gUPw0SnkO#&3de(oeUVSii4y9yj3j;qAB11eu zOH9zpBp9ohW(~}^piCuWAON>85bg*zY&fPMc1W~EWTs}(cFrhKGgQ$uOSDh~ z8e~CWt)if~X6$xEe|^)t!GSht8A(Gv%BKM#yFNoUN=`EkFMR z{(?m6#Pu40NufFLqBwW3itp!FJEez zM#0!53bwRMGgit$xSyEWB^{%Apf9J+8R-uEO>Kg6w;M!cW6~R2M(g5jV}npvhJA^s zBr1PZAF1Bmo$8rPiKJ-)q9L+`ddOu34)D23CH>_3N6%_<`xD5EkGP5UW7 z1~knEI(LpH=L6V;H4!wF@BcqpX4jSGDLckko-D4H?5Sj3Fg0CycOtMlRp zweT;EwrQ#k6Is4)HJf)$4W$B1!x8NxnZ%R7L-W8j!1#<>R(?AENO7Zz8)4p>BF%pU zG-@%raQ%xK1;KE=as3PRG%fNBEFOn0klQ>pG6KXsNr6_3m@SUv zqaUL&j%1EH;VDQ_KKj>OigFgCi51FydNK)tQbRCXN_ep$ymEAZhCMZ6D!aQoWsJcp z1ib)2H{JJK-?GJ-cYsL(0SfCiMRb1(RZS1@%mtg$*Z)V=|FNwZr~l_aC;#!z{-K`! zC;ZRJ**~_mA778BDDO$d>>498$~GAG4D#hPLf)B%0L#!M=!WpmO9d$}J;NhdxpQCw zNNb6(-wcpL0_*Lj_FraV|7DtlN#`Hnrb)Y?fqo=n)K9ym4%5%4L*O_;g<^lJkq%a8 z)RGd|k8)vV0I_j5yPNGqu$W({u)(T|=kMWJfVs3c^;n@S^oy3bz^OFI<9W$en9VLq zL?Ueq5`n#MCeb$BZG0E&Q80&@G}+xQ(6Y26T-bvcb=%!_BAzP%Hb-Vg z3YzAMVzkj+U+ZLLuD|%fC58gmSKFJ}PaZ38$;~Ev!{jRw!~W`-%`LA8^qELbg3KLm zD|5dKw1{(3>7|WaGE!*F7_GKDYc1#~2rOG`&DE?Erl*olZyw9l zwYANrZ0;Y=obQ|4xUsq3-jKCXpgkZs$#RJZeLt z1)#S&cZvhkdQ^t|8vuWPfjgBIQy+pk;z+OW3g=GA1Csm!8w#Jl5--jb?r&dR2p6#~FWJHu(4QNq^WFsooCv=j3z%CW7tWY-h+mGAzjkWc9qg^oyBFKVhu$U3^qsMCU zT6d$fR^$*;|9LEwwvAJ0WgI`kdR=X=b@Bt&+F0A%(0KA9$0VWBU$AxAvu2vWgKwp} zH1-vF;xF!(??``P1GYUQ%DIsXb`sIbN^W2>-utO%KL=2FVVc0ti5h?xc}Fc_VA+Mr zA=jdj>aDDJIUjwG`{+{z%_2s=DJA_x=wF6spBxAwReQhyvz9=!Ly6Wvt_TU4IvuQC zmxoyjHG|C3d}T!?O6j}1Iqb$-$w6*Gz#7f4PD5bV!?SSB%?&B{T;+7h)IAc{Oa3L}fGP2e!;i4@ciZiaR)OuP;|>|lK+0a`3Hf~-A-{bm zX|`L%J6ChPB|Yev11(>9Y{4OFZAIKAYegjUm+IuG=WKJ!`N-$od#zp zHvkX_D(Oz5<@$E=*z9g@E;(pOXb5s&)?~(UIXs-891kbKQORMg6xQAz4jeG+5f1jS zF@^Qxxwj22XC+kv7nN=~>BwZaiU)3Uz@g-sX5oKYSetDQm$1zhFh37vk>Nu7?f3V! zR)J{)5e|(OLJk2MEo5V@1%X2#S_s)*HM!C=AO=eHOXbzc0hU%)@C*K&?sO8^r9bfIMCQ7N5U-{ee(-1Y!pD#8 zh0lL3Cf|Mpwbr_oVGOsj!Kj#s{snO6Kdp1bumcviu+MGM5a|7rXoaBJ_6cmd**Y^7 z_N*XKd54$=(ztMOXtvKxMSMY%5I4P^A7Ha{W-7@q`Z2)dh1oqb74}R&%zW21*Un4@ z9(Y>IzBSiLO3S{bFR7wvhoI@pUcugDr4`fmC%)p>t= zIJ)+OOY(_`Ca49u_!?|H@ca zLvGqqbBJ7#rx4^w+!mkE$FBp8z+IpyW++B6+F0$hDt#(G6#SD|`Z?kSWRMQqPSr9?^xB*LygedRsRQZ1eIhO}H zT<%>cPF;X#z64gURS>GdDq#^!4u#ofg()EA2d|WFXRT@o`^;|mG8gJCvuVivz496| zSWnzIDTY0<)2`eT_YT>f`13A#aFKPwjF+bYYgTw$m}0sog7Zv~yl@;X}Tf^v( zAZmiRgwWXa7fs@W=UG?I7+8NSAWeHdjKFHHtZ*=i_bd6hvQI#MC^Y?*753W-Z@u9G zWAD&hQfNh^sdti|INVS|Vh%SkxP;W|@jS%A&KL?vU`W4)wm((i&KGM$&*hr)m6aF6 z7_D~JTkU1`L!x5(^bAF2vrGv>G&va+NQMbxQdeRnk#7Am?-ra~&e?y}R_cdC$p@2q z_}z~%Y0!)S3^6q1aqh%V?Jru*)o#1e244ugES%Rta$e_FPsYDOJ;mvLTJF3r-<79t{u8E%=-(^mszFg9P zLNl>j@V9G877QQFt5_*soJTHF7N1Fx?NPk>^a2N>uc<}dAibALLk%%*OrmHO8n0iE zooF(@09=UI7C9yfFZ7%H+Tp!?HM547))~ySw8SU9LaoP8;l%s2fh#?1bBH@flZz z4Iz%zz#QJ)sY43JMfzsiD(fVK>UDkcf^-4SE-UchH|c*jyr9=ETV+E)eQ#%`%&&gz z`WKcvASUp4cazcswCpQ52bX=LWtV-Oh&O&!5sdK_P1V>^yD*jWa|KP!(+hNQ#;zB8 z`=7^YYWSGNzPuB7{!wot2IYU#~&!sn73 z#5GZpLn4LGCI8n95`O1n)eMKABI;)xV zS&R2oO2C)E+%#L=jxf_VX`e3j_vl1K#T-DflyZN!hpKWxi8)o{)Tyoyq@~>rGROZB29FEo2dJRB{<^HFSpv%y5 zFrklZ@sa7f1ASlXbk^2t_5F|0-W6x7y}HqEEl05sF-^LwYh{Qqs`KBY@gO!Q)TpD? zM81F7maCY+h4A#O=u^nSv8V^ zB`<$YBL}?hJ7AW4g*=I%9^+u~P^#fvrGF3Dq_-6|| zIn&Px%?3zGQ-+GBAs9d>GXQ5o|Ls(Qf={^vhyJT}Rt`WEZAXUWHP#(3oZ(@#ojh?2 z;p~m3#5bd$8cbc7{&UKV170IV5k7yM{YYNq6o-*?+sbTLDHu#%owy}aZh9*#3b6Qz zTG30fEn-AA?B#pBlkD*im3C(2?tqE%HPq*kx%w%!_zXZ9I4Hm(j2qWwN zXYcKn+eo%GvFmvYux1;oI!r+Xsoz3Zqtz1Ct=$r-7ODP&Fq|TgAgc*xp|cXA*Z>?8 z4u>DW_J!@R9kwrgY4z+r zzagBw1`G8G%>-gnLl%(-2>T(-Z=D*Fh@>TT=xX44E*pwJ5M~-q3;4ZFj@bntKiYe; z`>9B6zzmCdA>w=Q`Fpk=y=U+F_}&>r>E&vBMT|2Wxt#R}+(yQLXery@)-$cx?T5* z@a%3Md&=lBVa&nA*Fgw2gfxi$h5k+Q>`rtCFQ^4T0K44#_fg|^m2L6$I$y8BUJZ6O zBkEQFBmt55&~tyw?F_!UEfTWa&OjUM+smt8^!D<|3GjWi_uxi^&hwgS*0;K>4xYZ=Pa`n>MCAG5vv;re502C5 zxv~sKpa>&P9p;u2>wju#moIy&(r8dLFdzmJbn9(B1yY4MdZcXr{BQ6lcP6p z_n$&po}a;^BXn_&$jgIQFAw%lbh$Ko387|%d-W=f4wmz|y0L%o?sXc0 zQ?R=6>gCaK8oeqiUH#$Lf8Kv~oGKyEyLqB|Pd-w8`26Kt=3 z$??x`)bLL+;Rt?B-Gxuen+JynCqSq!UNRt9K0AMU_U-=br(RDUP0s0M?)IbQBB&wE zN>H80CC{F|diu8c!qFt3=e%B8wZBM1Gu7D6u2ZmzYVUK<7N9K>TS56PKQ`RNcDQn4e%GL(ODejGl^M*4dPH8hD zPDwi;PC-2$9u4&__Q>#h*uExR2m1H-Zd%#DRhC$Z**ABzYEPa#dblUe)u@vTy1uua zd_%&5SGiZwc;I+O(qOZ&8wG81og#aE|tk-!SrxFl^r9qKxoo_tUS9r{AK17WSwPZBdGF^JJ~ocA(;eYyH`;8*N$q4dcTQ#i zOgKSQ@F$NR-Z-&;eo>RzZqT7f30>(*v{vajKN~i0rO{VkIhWvg{OJCJ-3B~~b@6tP z(C@6Gr~C8bEJ~yIA14nZ5komg)TX? zwN9atho;skwDQo_I)yGftmb)jF0X;sL#I0EvqSyWDU8JT?+)R+aA+XW+x>53e*v|} z-yXg_kOkrLokIn5$vaC0^uara3h2Oh<}1+BpPiSXV{&^2uc7KGl~kMpdD8-LoAG)E^-`zp@G`Y+hkm6_>)^Xo$g!M3UDUJy z`h3RoNq<*Qa6cuk6g3LD!egr+~^*H*^O4vdDQZ z-^Hu>vbvNka0+BCz=eNbeh8@gZ7JJ;(~O%gI)yIcid%5jRcI=ME9i&nTyYtUQng(4 z#k? zdCj?7fn!qi+cM{Z2I9?F7@_qvjOT^pbhHDZOyQi*IJ_A$HrWi40eTPQ{;n2 zL-cL88Twwc5%?s~1iXJ+19Y`D^5wfo{1v4aA=>eNgLHM*rCi-=5)Kanbi?i2$X0dM zsKz&u=xKj`U8DJ$R)TW4@6lY!JBnUWUX~nlkp{?}=GOsgr}_15#L7?9XodHX)bnzQ zY+ma~yd5F~9t7xs+qV&->a0QfDJ)Z37e8Fu-SiyMDeR^AINta#H~SMiQ)gIqXyPf@PP zGYcc{MYpVqBJ@#p*IN&T^I2~(6z22ZN+@{MyKNbib=KEFc=NUeuoqhXdX2@e)>D^d zTTemJn^vuhzz5|`Z_T=>eemj{?SoMCKfD!3t|_hjcrN+zQx^=qAhZrz!LYvDX1boq zZS{Y^BWxneu~Ywfj{fr;{pUIQPj!yU39A0oD|27VJC~)j=IU?!3Tj*^sKl1SPIdVH zHFT0(X#Y681U2F0O_}RiC@-GG$nv1c~qtX!=i1uIMR52A*6ZILgT+pPbW^ z6U`U!-R)eVoqX_M}827YEr>zQY zDLEiM60spMl$S^hL}Wo!*CEZmY=e7EDSX?6gbYF-bTHkS%1PMoN+=&#TmemoJnnJ} zAnE$tfb^l57CM#KsC(dfC8-L2p!cVkc5aw zkdH4G$=LDJ+eP{Y4f4xwck4g4{#Ru(C^PhByCKfJv~lJ%`!WZ9gb`wHNV|oB#787N z$_3y;7Mo2HC*cwqnx?Za>uKXcg-ewuZY%syg7dW*oEcg9abRFC1ba8w^Fx0Xo@IVq zZKG#x9AnamY#ca&k-%T;^$T5DBka(`dxkzDLm?ACFmltF4)>0zi_M=nl!VF6e@jX?De zr1P$#o&BTN>Q<+^W+MMc(2swC=3wyNroCdC0M0NCx4G0D^ogLUB3uo}we2R5(WcS1 zo!OdYO{}i$rRXN$WV^qVQ)X z3I_leCR;*{rQA2=I^IAIGj88mXg}TC-2;ffJoxZ&e;48ZLeCyNd;))2g~FBY>^<%$ zWSIrq5?6qu5_(Ue49$ZNAMHKadytS>OQrLKOv8je+J)rc=V3}8J=)nz$Rhag$)iV) zo+RWn_;B~}gPk46q2aP63!D@-1VReIQbTwq(?N?|m`ys6HqP8Cj5kGdt1E^DY^a1L zsfY{6dyIZLXW3<(49~f%D$&od#!yWzb{^KW3%dT$DZ|6o})o<}+ z1^=iWn6B3vSf|^y5IbdgQ2El~&W=Mt&8_ph$1YMA!6?# z^N;^npw?cT{vU^;{ySk&8!BHr6a4~lTtDK!hxqTY3p{Z6$v~h-|5SlM+20xn^hg1L zLQ|h+qYvaNPRN+Ng5~G5_pSsuBWGqjtHC2JdasWml>UEJyy#s{6%c^Rm-sq<4ao+R zL{7bzfxM*8;{Dz)Z^+YRgG>DL>?QX3L3n4|+k>6$P0L<-kdU|Gy|jOS_kKctZF%o) zLSBF*@&dx{C>L3Dj$sEcdR4*B=2VoJH4W(cIeQZ)@vm`0UL=EG<3y$xlV|g7ozxAr+DI`lcrE#OLe{)2F)}4MpCE~yj-EO=?zUvil5m-R3 zJHG^`OTAU+z25=&OO%|ZzcoATN7Y-hl|N;_V8wrKVbs0*dkOhIEK*C9MM}d@0hu!) zR0MwjU^Sd8!BtP4DhLN&q_p>461TD%?>#G71xHB9JOQS)+0h_IHe1OwG5V8R7)@=@ zweoC<=xk&qi-0l-4mT2uCf*_6_b$FkVng&DiK6+2m*6kRJ6E~P`o4g3&lGc&K{>nI zbzbKev{NlP?Oc~jEC;%YYq005vLA}PBhG(mCz96@VE!z6capUE`Q0Z?M&>LsFk<16mH5Hd)1AAh1~-WlAwi-hLSW_-jTgoM$X0HNGNraeWRZJTUCP14;S@12 z)@zxor2*k)#H9!_*^>T+uP&KX7efXjck7{ z{m0Fr)l}zTq3-;>g?3v0dl48zt7c>jklqN5p;8I@*Ch_by)KZ> zxi!FHL+B)!%4r!V-L8&cl4U`2ydiWREI)~9GBo8N6e8NDn}Muni%vi*T2cN1V?1H_ z)nv1GHEg<9P|h7X%ji6g%qo`moGZc#$d@g5*G6tr^D`sl)4VG(6k0qtyMtSvhh zYos0l+{!|3I9_fxgX7^0_o=t#+G#rQwo17rsyJ~-lsuy6V>vlwfrNNL;q=(~gsUs^ z!p6K(X9&UziFeP2@();BDk_ePOIj|4D=Ntb(~Y~@eSr7tNwQUbZTD4vz4Cw11L+w= zx_MPyyM1yp0oGbBYGyWER?S1z3uH^%-v%oCa4?08h?4=}3+ZuQfC^&Cj8qsU159?M zvaV}w3P)mLwmP(4$t1uhlEWz1l+fPEZ%ewQ&NXOOXckT8WkshB8V)`2+KaCt01#H( zQj1JvFbJ<^u;=arE05T?C)a-r_=QVULNo<{sG#ag2HV>#8MqDG*Xxk;%_U>7ff*22 z)9Qg%Z57a)9QHDWsvs0lmUP!B06<8kDQ1a-lc3aIfNOU)6mJ&IJH* z7^UhhTfZ5$9EUAWHoD!JZTAp)Ej2B39wB;*-`g&a9_j7@CJS^Z-amg`&SsR?Dz>94 zp_HV4PACC~nKRr5YLFk^s=ckKvejF58`Y~D6Z#ue_zG*9nh*H!LMH2-1%TNSGi``JYlLu2pR;u@h6JS%6{pD+XvL`&C#m zT^jVb25@7X^}y{5XRLqydg+xUn@|a;2>Ix7GnZkD`n{IWMa!B_ttOC>(2wo0uj&O! z>;mp*a)bAPj4Uz>qUCtV>ql|34&`7)Ai=6opuL~)lEO8XZ|T|T(%$l(naF>v*PJ?= zeR$l`hdSLgI$pWkV<6-8p%ElH6Pf(_l&Zws^~~3UmXxnIR%(BEmvSdK*s0WO=qcry zxM{2dENpQdZTd_bnruJ?<-r_yAf*IHHFblgi5{@jjeiF8e3-!(v7Y{xP~-^ZX%Nsi zxIo=dhms`Xh9^fb$LEU2wm)fD{4#5u145Lna(AM~fc~!mBAwogWk|cy@a$MFvyEF102{ zs#$Rvt|?GRwbgBtE(c43=>caVGP6v?C}!r6a%D_^gr^|Z_YQ_OH<)#&I- zA%~Wk_-pzZ#lw`_t7^@6inKa=ae?EOv-2dss-?o(aYMF^ z2KiXr(!YPX3%VMc!;)}%DM`z?P&TtszP&w8u;VOvLqc3Z0F^EN60WPo_h2!Z=i>F> zZ>9AoN(=8BFx=6Y+_tr#!mzRO=2lUvIysj+733Jh?h?t31IKR~IDX5(N#-n!YhjfP z=$F|J9Jc_HZ~`ZTenLv*@__=0t^TS{sX834gk67HihA8HSPcqu%;oO%3S`I#rs6Te zzQ0iiwr*gb5uJ_$79ALDNT3NlpEW&jLVAbuq8h?KsguUMDGdsT&2)a+$mC4{RRx`* zY+1)wcGD`yMY5G;MWgZ}T)FO%%NRiPiWBn4#j`p%n4yaB zSz>?vWE&Ow$5h-|)u=m4TT*0{$EL-}U@L}9?vRS4WOSf64<>aT15^?r+vhSvAy%i) zy!ExYY3&eylwM!S3`!PD66jxz}5e<#<$Vkt_hebJKo6vti^tG$=1@k5|$)KQf8Wnj(SYllC!-{wT zVGBa1^Yfi+wNcBHP(n)w9omo9K2HF`6>X4h&(Wc_mAJFph~wzCFZJ^+wuWP(Rq{3| zX_S~OClZA}rBiZVR^lxMCsO3(l%8#x2@$0x|1j+DRZGQ2pSpu52+u|~nWLn$kj8)e z&_;l!vjBo7D(e8GSFNAg&J1h7_dWV+9K8TUl1}cT_LsUM5_Qb)DDh$ahfxRqOgndK zc>fA>IJyI<{}DLE0cQF^X{)L_Ij5a`J} zSUq^2qN?m^2Yk_Cx34=h=|&cD{b zAsXRdTL>^|D_0GL&>pJSJajvmUw8VZ8URI0!$jPF0O-hkv@>?PIUz06g(hU>FpZj3 znDkb{MTY@b%^0N-c78-E2TCf&Z?uLvvpxA$PIUJJf zdRCNIDChc~7NfD8UIP54ZcN80MlNHHGm6WAt^Jvo5kpNEsp_wxyqcUBQe|IjWvVgp z?Z*afb{oBr$HtvNbi2Ya_cj=k6PQD0e#p6JIFh++!^!=J3E@%&R!^LP;Nni}Us?%h zb#lV#EDfdBpwAsa$)G%jQUQMkVZyOucSH}o{KxcA=aaNB!OpC$=Zkh&#jW#=t<%HF zH8nY9-#TSI^xRP4U!B4Rr8iXYg;UT$?+q3G*(qv(fI|hpb_%-iyrHu1oU#_(H&pUl zr=$f24wd|qQ_^Azhf4mgf%4_K@7EZz7Sb2Mn{*`f>^ngJnplao${v3P<=@KkZ))YW z{Aqjxkxx`*6%SRf&fv3nfEtN$9#KRkNl}#0H(cTXKZZxcaG0NKaXgc zT14(dcZ?Ui>ZUtUr<{LvV3a%29kcy2nPlJ&fQd(HBdeAR5QXTphoMm>(Ws7yf_iG- ztH4#M{6P7nyrd}6cIL%pA#nHc_Vou3+*$sOD<;X7_NE#oxI!l(*#4Y*!A*hHHU)gg z&<3tY_Mp*t-#M=$U*#EBW8w^|{{c)MAuzM80o4WK&Cb>GZDW50=QR?8t-@Y$h~Rb3 z2MQ8Gzw>1^FicBh>5thcQo#@?4@3o<%$JDtSX~qgfG?0PgMd#5__8Y4E+S(>zpJ@9 zx@f=3zAP{*6;z4(8~zn|5y?ZAcULOW*Xyk~aNFegwkOwVCkMudGyGCmYKmDQT@_f~uztSykY8tWt-i z0gv1t43GW*=5>sd{2}CIRnJ03=x>P==uUsD#R5o4LV$k*R$cvpE=F#fLCJ`NtjrHC zzgh)9_~4-*9ibZnnPNTJ@fYhDdGiboEc~A^m$|n~1m-efZe9(Cu%A5jU_LMMYN-D9 zl>e!-0yr=JSs{w%U_}04a+Pa73gM0zsIa2ApD-3fDi~@0-2$7 zk1nQz=}&)gnT+LL%7^NVRwgOWM&)=DbT{qUdJ`wRqP{1UiZ;>94q0Y=P<^p9312MH zOUNBI$*|${SzHp9^xQ)aQSmNy8YcR~6IV|D-W35cSwcuu>U$EUcg6@6M?B1?i+E66 zCU^ERwUj(hV_@F2qhY~K>|o~&<>&dLLKksH=@fr<<13yo&@UX1ehSCCgTN@!*>Cfx zBl5E$X0T50-J6z^swY!dS0bNWIH|1f%01%Vq~x@BE-vT)^6a;{=UpDA{Qe_-q^l`B za9IurccIh%mg&EwA$zrHNw#j&lH8FA1~A=Y$01FspOqq`VAyd5t$H0)7^IF&MXl82 zsw{sVTaC4icxjBZ*1CR?^-1*f^0YWxmdmO!swu=Vio9TzJs1kBs<8SOPs!j`e*X#R z6fNWJx~s?zX1o8yk-1SBwMj-hW9Kt_-eUDP_&~S2wI$cL02g?PE7kg!U`C(X8hZb) zAnPXmlc&>o=xm3(P5@d!rN4-2bMU)erHcXQAXhnm_Zl=zYRI*=%;8QDqHnL|!H&P9 zJqWHf|DG;1A+jIzgW)#r@H(?ikEathp|y4;qiwz2R^5Z$;0ia|Y1jL-aFmdZkvt$h zt2Cu8G~Ha$gFT-O9;4}FM`!lcX~=dkBd0_9fPKLmfd@qf;R}Nsl+uOLvPsdmu>6QG z8Ai>2*X!tVDbIxZ+VzaXdx^;(+_E3YkFD2Yy^cjzpkdFd;0A4)@qL}5vBBMvZ2=@e zPdn1lWRi~O4hX;@xvSoF&b9a5_25Y(wWkZX1F>r$R(@#YzOt@naFWu;MHUn(4bl-R zak^dlJD4&}rCPjn3nevW=_5<#${h1kTSok70Tf7#?i^%}&$|pTL3-5?$Uq*nWm3GCK261#A zg0MWto03Demy3)MzHtqhzZ@sP$1tWbTH_KT@^&v{<2tRV%&6lvjUG?|Ckb>04LP5y z{!4-$6i$L>-5EpmjW|isYcdurbO3dKv&L&tPJIOvXF8veDp$!-f}!Ik{003#5-ps> z$m$M9?+5{oH^Hpt5ZP4d{=q;=)y^~z-F35{yYXJNY6uHg5_h2a;fQ1m%|n%TXQzHYJ^_^I~$|xhm#!DLAmQLuWHEmk^#Lgb$oC3k*G-2;29pWK(5%zwz5mx%Rf6|D4*jO%q1nnl0hV zF{8qzYbk|mV-JK2V@8AvV|~Oi1w$AxkTqYXqezj@r-v}{EC_QG|i-k@)*GK+im%eVaK-+v@s+ncI@V^bfQ%kmK|dx?2(p?>7^le$wlPxdYiyKWVsI zQ=)#-=S}kiiBdmhsC6F0%FGCpF%(|EaS8;IskW?rfqbO4oYFquEG1SOy((;CX|2_Ssez2K_t$l zF00Wq$z1=K!SgBnbDq(`v_!fVvGbcy-GMkfsc{c4W%0--zOMI_Lmf2DPhN!4_eP%xchR6 zC;-^uZgzqZ+bZVpVi+%VFu@T76P#>sC+Tu@G|nzIn=<2n^0beB13)OL0GDH0h>8^W z5J!gajQ1dk09wXm&&`L$uuSt&IZk!xutHK;X7k~EG#RJoM$eID*)oCSQNfmUFz~=4^U0dC9oRHI@ zdL;$#3^i(LL2z)>lEBcWIl+NVD*{8A@(szexIPDemq{{QrV^baix(Li$$kQ04AY*) zZ~>x~ou>0{cPa^*1NQ4O*<76$b836Q96Q{J*zLyWSv9KcY#a5*2|0I^IWuhoRw@~V z9>SGpMi4yQd`ll|*$`A-`3IT;=8T}c#Tl}&`dfo!k!Ng3)!Wp*ohL0o7)A%2540s( zk{l?1Tk5iwtTg^FAufiV4&e3 z;P|IJh;Z14aUuOd^-b52s9_;6!(9+FE%l+G!|9B22qI9uItt4NEDTw}y}ScfBjPLaj7`Vg12xVg-Z>+zv(8s3Cc`4JU} zn33^bRs3#a#$iEO*#kt)63ly3is2V-_kx!Qjnx?bq{f6|d+b|hE?|n|IIK8C_pey5jVl&hIyHQ-H8>FiU@Xw{owkJx;MXmG z&l-^ddDbDO!E&tI?K|<0z;~09Lq~Tcei}IZSx>)N$V`v+63x@I@V#0_bzEwu03nvC{rpi!Lkmb@^!+x0r=?Jq4YFoo}(fd%omIfS^0lQsx{_+1ws zUF_R+1)LgA%jvZ<`;YvmXH>kU`II_napJ-)5{r}G^8*K0F|V%K{bC;%%e$|!W zG{1D7AN$V{W$;}sr=Q63UUgo~L>!F8gw1`&fM3J!SVL(N z1rrGYs3u&=Qd!B+I!bbV6l$*SpyD3&$1=_d1PRx`w}dVLEP@*<04te8lR9c>B+F2( z6W>(Uz&vp`b~c27m9#JxG5wuFcbV;jl-tL3GUSb1$>fxXF&H8|Gy*k$l3)n9EI&}t z4N^vV98GhPN2E*wj}-7v6?_H>nwFs_pmnLvTOMNQCp^Q*R_1*kF5OS!wfPKOc~!#= zQyuO=^VVrGff-@MAvy8m`RC1$gg7oy;+35uTYbV>zbuAz{Jgd?j0I+J3h|7>Z1ZvV zAfPKWSCXCvuh}GlRfinb&Tar$C0MFL=i; zSb4=dK(utD1PO=JYEiO^>R#z}-ppxUQHffdcO*&bAR~+FEDGX(c~*}vkS78KT&ce= zLo~AJ2*KR;rgm=u(*|;#oPRfEa=ovIyjf5`=GvIB40dpFlDf@g{6s>)+pd zm=N(cyCunwv)ljbL8y$zM242v^?n1fy$vBhZiu@u(!Y4&B~idj%|+ko=A*kF6RNJIvL6h8x?C^{-^LMvji?TBN7=IU&kl17x~lZZY|aO7?69e*f|oWNv&`E(%)dvtbAl4+*M?cNXaYP00{| zO^R$6eBJB4Um!wnad+44|3de_7l+`4HxA=k_(5aeE#$F(?5)oFRG3&as$A>Es2GE) zS9`BBr&mKf}IRkF*Dix;pmx%ASuoO>7;UH?!% zokD{kz{3ZBR1j`JWx*yKy#ew$U?aO?tQ$>vo>vFp30B}CTyFHW;(v1O`R~wG1FLX~ z{N5HHyU4F0?_s@4FDednPI3wl>{k>oiZ{JO@cDLH1H!0#9TW$xcO30On*hB8Q+JWv zfY{va5ArXwox$C^hCPc>J|>4)ds?UtEy2s&IA!zwP9vqVLGA(zw_f~ zESldrt%rnNBq!y-^$@!R4``UwO8n5q3?CJ!vg&7YP8Q^pT#_^Lfn1X-azggW5xF2A z$uW6N4#`um{y(3q`b~|mOhEao-aJ30a~VwE z3L_tX6Ahlz4rLz-UNY$jxRBdsaf$ip^3I~1U(bs9ycZ<{xez)v#?eyD?mmtn(U>+L zz;zqRZsrBxMAl4RI; z3a+v;+C228bcmcJ$@WB_t$Lg;=J|xi_eOVrqVc^m5=G9v_k+0i56Qi=OS~<3aTzCR zbT=ZiEPBu1v%7bV<^Z#vMG-mAP{tw)kV4f^WqpkA@AP4;wiZgN8SRlhy~2;~lXG?C z9Luu1Da??|EI!R%^(x4ckR(b|be5eWq!0O!HG+sPhnH#9o8q{{mkGHxcCowK9Jbwm z2jb4ibUXV%uCl4=m>IcF23KF+?GJF*IMF7$lPo^WMpL~)lBqy2YeL2l^FXHA zAwb>jXD6m!>?-&_N=ST>#YdU=AwDtH?I%ex@)-fl6c}iD(G%sX@{00jc?AbcQzh(7 zD*MR2Un|70tciyvgt&v*-a6_7C@ZFao%;Kr^-+QrfPlcx_%YKo?k9*jcAN zuwDQlyB=_~JNx;1t?{YIYtWymvPGb5v0fLt>~WF;Hw3%A+jY0d<8F8BxTkKwF-?5| z!VNV(lKYi>z0M6{mQo--OIG5S_!;aT-t^F3y`w$SSF?1_MZtjYlr7&W*XvS$hX5Sx z#zQ0#KR72sC!$k2Ge$6V+T*i-Gn>{nN+s{IFYorP1GJuLOs`@7tir8VmSNj{U1lHv z@T%C<4v;E9Rv&A=%=UJ6x?S5eRTKi7$8285LY(McV2ggp>0r50{=XB36p5!oy zo}Ow%Cm9qd_5U$dhe5EV$X{v}IX7S_aX6R-<_KG_H55P5@71QD^cHQIgAibCY5z%| zw8Wod0pej(QzBKXd|=Zpum(|(r9@@l2I1He!-6xz(!;FMCFH333p#dtv*yn?C&Uyz zrBiRTLl^iBJ7H5V;lZ(g*7zJei~m}F6^37le*yuAb@8L_HMxuUx70EZHx&(%bB!JY z6FFTL6#`#@E<^?uSv0M{nWr_9(Th{rB#o$==nj~I2%t4f>H7PuW(wSb!-~zrWCWBM z6_fMUh?Mv2eS{_6N1bz(nCg^L)|nw-mP{-?zwYD=ax==xD956ISWF|Pfl=qU?97Uf zs4tM2l=Jxts`E&XB`YMNb#AjF#V?JMKIL-NZ_|XNWy*>fg;C z?+~%4JjsK6DuZpU-*zB?_D_&I8zXnECwgcpc<2XN65vID21s-7A#Y#ES3Q&&&c?xN z;4Vlr{5X!{h~Osz-qj=`ok#*;kRp?W7;h00!LuCp9>>Yru@DyPHD9k)gqh57^DrI> z_}YjOK2G5HI>u_!d=v7L54A&+iOs+?DJo9Wc;KSc(C}*Mi0uf{m9uSVbSLXTXo~!e z9Z(=4$;NkotPhRHgV<>@z~xGZ?hvu)fbVv=>w4gm+2~19;_yU75Fk9+W~9o>Z98P# z86Mq8<1Hz6!6!_Yf6pQ!p2YGcV4ej2B=8qTqp}^KM`UB802&P&cyZ;jTMft8LIm1g zj(WYG=6`1t8Vr_f>hT1je)eJji0{>ey&hswXgQL9LE!r(0}8M|nCuCzdm<2%5F!GH zm^G;3S$J;UGW@!qOt7=vtBu7!%nL~MHa5ukK;b?2HHYVAKX2z78y<1flIFxs+*HgB zs0ce3_&8F%(|I|$0GATc@4fmZL1}|}@y}uyMQMa9d(FjyB^y6vqn)y0B>0j>X*A2{ z6^%B3PH0CnR|$xS(Z&h*xT(c95+tzLkD_h0%7PQM9IfqW3=6muD-w8drCyX?)cVDZ zd9h{jxp9t$J;l7~`IR?0^&VjtFUxKlCp4uMd}3pRRl=PkXN~L;H;N@#qb#}=ZJMzy z;(i>Oo6baI?q-M{{@#L6VU5^cA*Y9U5VJ&otp!PIILr+rV7{h@0qEa^<7Pti*XV<{ zA`OugS~D%Jpu6%dq^yn_9I zD#aB`h3USw@S?x@D4Q4l`k@X5F5O0FZ66nn`MP8n@*~`hTgGE(9D*VA-nJrY-9fNs zLsK9a>N81_E4oJ$Kyv#ei3c%HypMhg`?!^U%6xB+u=>n41;>A}6gM?06qogRlbO>6 z%`xREGNFms(tDEi3H>VC{-e`7=EJCeW4{;yRK|7$0q)2vh2oV>(ufxOWBUtgt*4!v zx0ztX+0FZcsrOU2hhVJQ-*(MVH2skcqAeos??UJwUgJW+cYkboQcH47K8w3>eW4V&JO7w@W7jHASRxm<;vF}DG z_Qz=y4IIOsRarcaqm^AEsk20G z+ytrO@!uc?NSdpy|jBTZ?`QIZ*)7B1A*ZbDyxYdU^H_V*+ zExHqc%?dm;iSjN;SNUW@7b1=R;od)JC#7I!n550Z#s6V%rU-Wmq|sog5W)gIUWkA3EFZ!du@S#9=x(W30dhb zX)A3!GKh7~*kCFdPNx)<+H*j>F5K(PdkU(^mfA6m5DY6+X+DM3soxo^>;=ht&4E?1 zon=-xH~<;e5>1wlwxze z_?^%A0B?R^Rr2DjVEG)oRp(H~&u(-))hD)&CoP!Qd_>1R_dDYZZz)JkQpjawnfdvX zLS`nkyFyS6FXwZrV@X#Na|ad{02R;Yu$aiiI_TF_dy~MfDGLsNnw3yphj2GSHgOkt zTpav$g~9Y987EmX2W-HUp^}@7bOED4I&shScc%U)$MY9Ni-xKso~gRnHuU` ztq8nhCW(%nQjy%4$TNd!M)+D23?rvrOGD-%xz0JGbc&Tzc3Jxw^6MMBo z=4y4CW$2qUu{8{%WEc&jH0tVIdBy0}ySFdX$@XlUNl7B=M#=WlT_NV~rU^(@$9~9- z%?7A8&{>ATcUM0r0pvI|&cPZm_0u`}&d;ljMGRf?g0Reg8t#WSo-7qoEQC6xYbGz4 zAh|7F3|XEQq{N=AEvC3!H&=IDwwD$CX8-s_$-kG_#@NTIhIedP(WzlCgA%coWs`1q zLS}03IXO-s4|cTV1t4Dlkr9cIM4Mt@-^EjG5)+ZAPKtfEMo2VH1_s4Ve2-9gGue;R znkeIlE@eo6a;dERF_YbUC@+b#%ce7T&oz?HOz)i=7u`+d0T+!T6IbXjfdk|Q7?KJk zj$#&Ibg~NAsinsaKp-?Nvmnnig+F~A zj4lW7tZNJ%?{?kq`u>70LF78P`O3;WPDxBYfs6Ilnc4s~+6i062|3BGdUhuy``MM= zCS#F*oq%(=el6RVqkBXyvd;(J_V9Wgv2a5^f-5Ni3+uhFt*RqkRUPX0$X1t-;|xRW zrvPvOf%U3Z82n|oyQQu@AZ9$?T*$V{!$cN+vws{V8V@g6%WvOQalMZVa#r^gldh0Ct7Sdg~4tW8mc&;@PJmeH# z(_<9f?!A9yIOn}&oqI)30G?)%48?aC=a`D0z_*QjqEnscyb19e`6;F{QJF;9c`MSc zBVh;(B-9cH^PqRx6fEj0@V*Aa%k+wWn+cPDq>02U@`SKOCUTADO4w-@?e!k@`i~;Q zF2im|yM4e&pHtCcXIY$NUxvW2S87R2*$0A-uqnIVs30K|E<#p*yhzHfHjS8)!DJ3D zVC-b&_zWqGk&#JygxhS4d1A86;j zjeog<2CAgpx>G;spf8$zDKd;*dUjsSr^md&cq_uLv>&K)I2=l+(^US+Jknxzt?EmX z&4SX40Euwh5a?dG-fWNmwmx84KS82GOwq)UAB+$en2GLOfkN+WM=~b zQ=-6`g9Y@IM>d9rY-%lcsHxR|pA5}SfCSgSahLy*<`=K?MUvue`E6ZDUSTmPLYVAs zCkq1ur`U=jI5C!EC$UF>&j{#S>6{c0vq8oGm@MovrKC!jn3}xV8C4)x_}IWlC{OjR z9o0WueW(7TV0hS2#&=yLe>6farSkl8(GsJnrUgdyLhk^mM0GucE(iC2up=sTkX>2M zP4}JjF1Zc9t5krd8Yg)l!Hq=^j=V2Xx$$Q{y(|Pk6TDKOT7v* z^n(|Hy1IX?^S;4|IC2=qX%_O0S_O@I+WP>uA#3XUal(Z@CPPwn{fbqAgUq%&@Dxdn zQ5`5|sRbR(%Ye3oBGXSMl0^p!r888ItJB8Y>;NF%!5S-*L zIkA9-OI5llptEG9UKNU8aivQ(8Zs!{X%&v?R^F3qgdF;Lrmt&%`nnP#+`S&1C#0Pw zRAkK|PhB;dY@_zErQ7FbYUwX;TKL%ZR)CrP3nY+-`D3X~{L;yqpm4HC&9 zmL;>=dV!OICrVOrAHZznM7_0=B&UMFkU~aqBXME@g{93twxu#;{%U~9LLH3_J2s@N zX%2Y&h1y@ZSuU)9S_XDKNn%lNEr7%uK%#(e9|*5hr0m$m3k3>RQZ>phK!}mc^Ccgu zl{SSf&)G{}*8=wIqPLsu5^(kbv=S9v1b{4chzOBM*0%a&lC41I4*95sQ9fL|O$?L7 z)y>X*=>MVn+V*y(B-a2Q2gDK$CfP(D02l^S)x%2e-mM6K3L_{faagjKfRd>j1qlQ^ z;1LLefR|`cNYA_7+*Y;m(DrR3VZd#njnq&|SP_uzz(j;vQ3xZ+6QXHx{VS6J+*tBjUIOkJD^FX09DaZ zAce?ZRv58=7?gXXNT2MN@H7K2$C@hImrT`EixJnUVpvl;);CbW8qrC@D62hKk zGCMhY)jRLKc)9=Txtp^b?;bpTy|2tDZdOCjknqyw)-AeT``*irgM0uw(#SLLO^6ml zTHZeW=Jo!;@yXGfxBE|@cf0ImTuW#!)5=;R+*I9vK+&#D2JryXx4nunt(gkOc2l^p z183N!nv5_PQm|zRfRdq*APRT^;YV<~g)Br8zX~tCQ>!x{sbdStDM}BjElX!83>}}oT%-+P1 zb%^VKAGK6C23-O0nYCr*3k%^G7icm}2HV>r(a5|g>K78yw(z*-@Xh|)r^hc34^E!% zzj%4@5`G#{(ZCwIc!szO7h%?G*1==%-AyoainNAA&&uU|ib}5;WRf--Jisf|y&1{4 zLol!JK!isiecIjrpp@VeW#T;_mE&96-tBIGZ%b&{DnmX;(}vGue*PlB@7jPtDe!#R z?OJaM2z8m8)5;8Xz-hKZ$l5yM=*06nGiXUO1i*skZvc(}QA?%&`m`S9F%887)jwv| zpZ>-PwQ7(gbF~u-)e+~(05=rF_0FU=3ha6)%MJB@LX!veZ`bD6jTGF_2PPB!94B*s zL$HFam&gFN+B=11gDlJDxIENeFOp#%R=+I<_tZz zrm#2G2Rr23u!uQW(`%Ini`FSX=21C+*8$w;RFgC~_p^Bh_qE&Bl;I*~v5pY;h9|kb zVKiBtD%>Fq*M*O5wXeJDHF}q=*DZ{&UY`bLNb86$od?AhKO7e z3OZP!23v7;Z7Y9WU3vuD35(jB!3t7>p-g1Hv)@%2wwKp#4b)YN4#?iO1IAGpj z*7?d(g$@Wq;{%+A=}y# zQl+Cu*uQE$*syo1ZtpDj?h`&(R46URV5ZyJ5*{PRqQS{1|H2uo+m-F9XS;X5?;_io zth|^U*qY*pG?i;baP@6}uKl;p4pVcgzKQJblJ%!XUUC?+Cetg*6%2o!J&D|;0Ed>0 zK_bMZ@pp5KwBP&2Ib;5=^zZ9+-|SMqD_fD+?kB`^6HJ`|WAEy9F3x*AXVX#w{K&}Q zc<*7NbS1mqK>X-~oQ}qW@OfN!%1Dg6U2gEB6T)vR9@kj!yQbxTSnV0odsEw0kuVL& zdu$b|;-r@!b-N1u7Uv*vq=@}H2@!Gh)mQ2&^77BKAN-sOp?tKc)srLl+f7FAhJ`z% zp9Ep&@DzQ(Fh^quXdZbij$aY@Ui2smSinvxM3QY}vvxVoiNpuhFn4dR{;*$eFQ5qkzi795ywh{ox3bQ z$=QU?y;kMo@=ofjV{f0b9_ zwM=kPH(5(J6dY~Wz--w9b1sPS05iuc=M%RCq=iyG3YK)kUkHY#$#Z{$Il&{H6w+kTKma%9#_)7J?N7 zX32nQH_)~c&O8bkn2k1Y#=&~kycPYo=Pob>)lLj6ynV;BG~D#Bnj9(a_< z27fLo^-!QTuZ0Gk+($X3NtkIyOp=U9>?jrv6!1c7O#D)q3d4du*n8C9O$giZ^#_FQ z>Kne(9btR73S}x5=5@~UGs*#fOWt_NW+j?`&b5Dc-YUO=o2ibHIB|VudnbBMgU8yI z3emuG5&p{9LkDtFMPs1{hPx6B^2VB@++uRnGU&lTTQb(G4WFbzd5=@|*|=eD#@)}k%EQZAqbX3WpgDhDUNMZ5iyiqj4+ySCUQsTe_P!Z^ zq>Sq;HHH}@dG9JO#EX(2UNO1GWbAQVNSFUN<-C|&W5ix{Tyh4)z^bGn?G;O^$bjAz zG#!a0Rc67nO8^ru6Sqo}xirhNY8XxO$vM3{D|jWM6e3r=@0)NH2o4%9Q;1h7dU$Zn z=P#UcQ(JB}i~vq>dWr|(`EZ%e(;4)Co9dnRxX)Fy;&e(Ja?<%GF}*s?xc&u-wKG_p zb0H%eUrv>e$$3V1<6Qf_8=oD#hDfpOyxTojYRq#tcUc}5W5UNfXVE4)d~J0`gIQl- zS8*9Zs!L}jzm(gY>Lx{UZ>j+PHUwhkDMv#UxR5AVNO`@p`6SYuptYOG()l8F+@L8g$9U{n% zIqiG-{m#Gqhjpj>6YfNu$G<8Dqvp;#K&>2ea$|D;m`BxMad_0`c|I1cqJ1VceJ=(Uo?|iA1xQtT+knJFHkv<<)T?D zcSgnYVm6DD0mO|du~pHlX_DOfCg-p$p%-(v3t2J2m%KC^5p>~Y?|Gtso{-hXDJDA! zg1z)NhOr7w;t(MMH9HSMBjpVP98+OP)p&u5-|cG&_^oc0Y>tbrBGa$OWeiyFE4G`Ag;lGmO7hNV!hrn!(wi#5hIvRq}vUZura}+IkVyG?ME0CbAa)? zT{fa)un`E1#F5`%ZrxDc38^!dJqS??eKoL{xGT0Q6-Tmx5!&tp)yN!e#6B8yQSV zlsM4cR<|Epymje+C*|R->*z6I+}#@fC4k9wbzV%)t>tS&27 zOaZ~Va|zjBMcIKKHchaz5%I8TK7|Cm`su1;YuqG5Q102athSCc#3zE5S!e!d;c~6p zb+9xz=qPQE-PFt!{gD@-gwa{S^dX56wGBw@Z-3(8z1Jmwr!8?8gtbwqgsLG;Z^n0N zZB{~7SVL;tgGsZ9<6ro>z2jVfcgxB>NZ2_E2mGwL)-;Y2S`@P9ZkTr77CR_HTdwI< zqdz`m2X3)v=Q%s0zJ4v%s4?0dr}g-N)l1Qq6E(c%lXZvg%2AcKO2{0rZh|t1sTUz| z{33ZmYIS0N|MpH%5L?NuK5e?pQzZr9w+F?LyVtSi3Kec{nZezu8&VqJE&)ee7L_O_ z2(1*@^9nG?nkLCT4KfXZ2#U|QSjasOf8Q*)*#Q_>@fgQ)(fYFlA&z+4qNHF zDU`}XNv`YQr%-K@-VCr~=GX2Sr9=gpMo3w&*?sAM#O15m^)cnRym?YLnF=-Z-#~!% z_pgo|-G**3HRn>N%^rS{3?5EtPyN~?&atU^y3bJi8av#k-0M0}m1o4|Fy;cXJyCECWOJF%;{Qw4Uk~ zjCtWbkdi=c$*@Mdx0ri11(Z_`i*Dos={7Y$oZl}F3%1N5Upvb(8Vj}hP2q&;Zf)La z*JV<_Q$JxzOY~`G)mF2k3B6_F1%%_vQ5(;FdVR*yk<4rlA z!x6J-T++u#M-QjJn2pMqe`{py z3vmt-oOg&Mv~lA1_@+gliCB0|!Ycl{oHq7ZzH*~a5qtdb*uPCS{@oNFB= z>k0WQA?|70snhIM#@)0~l>**tveMaqi4Yy+;+q5@U!MvAq2qLlZh$axWo}HUQ=Qtb z3UD)Y@9S!N5r)p|%KCc=iJ3M}JA?s(Mq-G`xH1hnT}s{JkbYOIC25=bGa2SF_=UG@ z3f_^N-mpCko%6YWB3GLQ5T*p_oaC_9<#lENqnblM7}ET)6L##(&&<(37ettU?g3c5 zJVx)4CO6)q0PEC{OKOTHV)QdNo;9IBg0Zt85;xg9ud3xGeR&BuMyGQnI#)xQqJ7%k zJT|But%W?U*L7`?ik3Ckb%l-^;ir|F!L3TTK~wFdquBHzhHJH@XdG*tdoY@H?YG^Y z^LDj(2|dgDz0%hP5DG9!5K7N~hh@rk{D);S*y7sJp|)KS^c-=ax{M^|O5EU~ZFY{W zEc2-9cD>6?rnr_+1%dr94lMWpSXN`MrYNNq5_KKD{#eN1=~1Te2t7PZCUr&?jLi%c zDUE8t|C<2rfYVJr+L}8F=5q9;W(O3#WR}hKN60jrqoWaI3?t_OZ^9*ix`J^EuI);1 zP01wa73da~Ckia7V>e*Tr@C*{_iKJO>QX(ddsccyRp0B*n)!lscAk)#=e!9wS|-{J z8*ptc`554}wrNZb61 zKVyQq`<7WRoO`vY=p0zID%L;P-{f!J@MR6Wk1|Fal6T?LRwA~4Ht$-;dKI|a=8kn? zvmR#m{k(v3?`ocb8iK#h!x6Nmu=Uy(yYTSTF4wuIDpLDU)1$%q4!Y+%9`cIi$&hP! z1Q6IwKu?mg&BhlsUB5fT_P<3xq%CT_OX;Xd@Q^&YaO-*C)kEusmnl76p2g8?l@ArW zp(91Kj?8tCcG~TKFc{8jzxCKL1Jyg9!hpEK^Lp(bN$CcB8uwhjcye>>F8E{I0N7A} z{PN({%Y*$BUCN>QQRqA06>Qo&diM0y)3+zbKfl@cVnY2=hhP7B|Jm_vrCuH!@4tQV z^x6Jx1>YS&?A|Sf_7C2@zWs}D-W{KWsk6=J^pl#u|I_h*{=v~Lt#2(Fr!M(&jox+x z>|p?VO@cakpH`?A6#V-|28b4ogbQMOI{_zjC*6V=4{iWbB+YN)vo<(2tx4zF<{Z); zH{ljh7bx9-J>np~A}@>!a*Zgrrp#5uJCd8lG2|u2Cj3os3?XMXI1>vO&V(sEI*#S& zEii^$B4F9|kC%TJEJMI_1TRwvUg1l~tidN)pYS!P{Off1DL^EE04d?(e$1ea&8=+RzcRK~JJAAs* zh?MGbq)Lo28XWYROVtZ{mVkl^4sD2oDp?sw_5=JT zZ+;W|!7b^2i$esqGcRV^@!TMeX-{&ItTvLtr&;vX6~DfxErv&ubI&tAi-FH&g7jlh z>#o<{y=1)(A>Z;v#?J{q&G=%(r{nb+*FO1wv+fWd_L=1i!lx!)v*!B>R+LshSlbyU zQXuAYJc_|Er~HzbK}h-8CgZ10cYTPpfBp4mY)}1rf&J-2qL;0YdTW{%)uOCuCiIhq z4tik;gTDk7(veZW&h9b%|ySw8r8u%}k~q`2!1hJY{Oow3^TrZ(7G{ zs({ZF9^Mh8lV9N+=ck09G~>%^aY%gMS|VfSgj^=WX4l;YdS|vj8(uFqDRWkTyCYYb z;OIIAEdi@uAw?+xHJ4m6FEA_7$E?4z<9y`UW~`zKVpDdMXUBRS0aP%@a(au=j+EuU7QGe`U>hY(4-U(3$?8y##)v~7uB{$BP-WsGpW8;{lx(noWl#(ic z-+g;>GqhxD72?@C*eY?6quJ zeLV*isErzsEq)-)!AA0X=9-7G@Mvf3uN9h38rs|Vu`>2Ltszl9N3Z&Sj&l=W4E4t} z6+`|~%4sx7`C)8nNE$2tbL_ghN)tQO#Qu7{>oy!f=-=vZAE_RwEr?1K2%EI!xk*t0 zi^#XSwimUqLKGr}SN2aBC$*`4a8`0}>o+ZuYgc2vUQjkY^fAh*getS+2mE3qp%+!g zFM5k|5hpT?)FQ0ILk-b?6`<-lyn91W!0R9w?AuSZq?pr7o>`$cE(KcE3S=VgwW+Pf z|41eBf3{OUX+E=yCco<0^A3tSR*+XSSfRTS;m%$YMDE{}8}(?63`>(C{~1RzB9)FJWi;pF4iAsY*VY*$rOOiwTq^jWm{V@^_MoV!g@EPXPQ&d8_B0?YWB$% zR^9FLU%fzW{uV#@0($9Z_x`W;{@3pP7yeG92N%O`5#e5Ik$A@UV^aWJmUjll7i_S- zT_hsrqhjo7f%(sWY8;Pa+TaiYnvUZbRGa=K)j1YuB)uI(dO1*|NuL(+^-qQC@ z+WOi?{hdFGUNZ;stf8gZgh;X!`~kmE1b)FkcDs80z;MWa=H}}{BH_$j)mnw7Gz6n? z?l#vmMAZ6|&ZXlnmNE9N)@Ich!TI=~WP^oaSSz{uAGgg`o#a&VyAj}m$VNsWOi;~m zBrA6XMW;;LLSY3aJDOYljnT;A)cPh{>Br!UskScoDSHOa|IR}FV*_#-{6Y~8)d;$_ zv@Xn>tGaQ2ls6ykL&fr2M_ihlAxj2 zia{8Q0w>s~{H#KUQP4X-154a@^m@HU>Kfi>5QyTiHaBKWymZW%_9y25(=Evx8bJR& z13Cc14=BXzbu3lpIgt@6{1uuQOUvAuu)j$e5C9FXkQ(+}qo-CFS*xV*xMtIlXBx?F zmO!h2{?Jsx7;49Qe&uL^*Xx-7cC+0bbrNzge$!GLL}FN8C|$%aH769LplLS1k8#uq*k>Vr3H$z^QoQUuQMM9^4 zbRiiMgT?od6tzG(AYm*SFmvK6Z)}*#mSBJas*L~S?!lPvJ%;1&_i=^ahpaO;-Oqsc zN(K&;GLA2615K=fCAt%PGtlW{oK6lZ*L6kCpuruCn>PkccgVxF*iU36KxK6|QK#8872A@3-PDs# zY$3}eRGm;R=Eyn9P>6ivdSpY?-u(LQlGWftNNH1UL;9hC3+!|Gjdasi1~mPr=|+a7 z|9qab0;7uIXqUK6f38{qM=2Rp%1I$h)YzSrNgM8Bi@PUF$O1QpaEuU9ha;%~s-+(|3e#@@=je7Y>=)3;?Q_f7DrR-yub0nlx|uJ~OK z(z*Ct-WPDfr}f^_{9h{?nhocWZ3h>Lo0g$116?hVyPbp~!CVb32->iB8i5A~>{F29 z^Z8YNT{Y{9zAj5RonRkp)DF;(%530UJI<{d)P6@y03n>z?8_~~c0&L_Gq4pQ(A}t? z&k0|xn_oQU${IOy3dov&6GnRXW&+ys{aXd*h-&5l+Hng(Tuct}B%eHkQ1&DhS&|8v zlNp(kbFv_(r4Q|YNd!4ZG#+_Yzf!Qm6wU7n*E3J@KWdMr0%-Ys!Aarswl}j@DRKmbU&qJpGjSk!GifK$q znG7-eNqvWsDIau?HnZHLmTq8VLjV_-n)O&NCL{V&Op|dY6Fwy4G^TLy9xgMQ#>=dz zr5J1k*DgtPP@4R09Vk1s9{PULoYZ-%-%l{f=CTL;@~mWkQ^a$EkkYJn&qb`{bhU0YyzFl#lfgDRqPVFe zg1u0DQZM*je^B?DY?TOuzM_F_bag$H0YYq3x>;p*p$e* zZ&W~-FOya4!Kn<+NruLC3^@a!Zj*Yio^;a%qL(Ybq;rzhasv+<8~5a|+PEjAzbiG- z^Q?#`$zX15?eX$+nnLtX5>DxCOQIsdXnmzwVPnzFe~cIC!k$%v4rU@___8nwr;D|k0F*sfGf zKlvmldZ7;G4ZuGSTXCv=Bj=6W6ViE0A6Tvb;~Zn9e_PT@yqsqJK=`g-1w`yFAYp0W z^PlXye<8aD=O#0mVVR??(#rM$e~5FFp}F&+O4huS5dI)$B%&XR3FH%&SC{3qm|dGo zM38jxEnP5PR*0a+HiSW~V#vKfH3yzSc~d*@ZPk&Ew^|{`98iE3BnlD)$*2JeX!k)F zDu4qpV9kE!M`YWT9^%`v|l1$&&Vr%x-$DSXi;?su07<=>v`19Ie)S%GeZG~m0E#~e}A-;!V z4&psAkfMnfBB`H(;>v|IkU-%+Et$!B5}JDo z&7j-0hC5`Evyv6RYsjJ0q6mjZss&S64^^$QO~4Pk&cO}XOv{fqvzZx7>P{OM9vrY8 zH9k2UO%%F(*x}pT_H+?{FT5pFno4DcfB6lPropJTzO-39sgA8`EL18E<~N-;Nq3M* zqvVC|m|{tIyQ72-T_`X)2DKWsgSbyo^;jNkSY=5AJpwTtAx+~nY^15}`0wuOw&fBVe6up^s@G-1$e+GiB zxmEkw!0dc;T3mm23&c8tPi*1R5r7GS2ZlE5nCZ7$l#5_{m0+b-MI&aJz!Z>{+WrFzD|WEI*Na9eAewV$vNw{Lx0%*6-UYTNsi z&*&|9MgA_Ikkyqk3*h_)H^0+-E^-kzsHz28+EWK+`Nfty;(-GzhmXvP8XRnAW4^MI zfq6Lt*PnoRWFXfYF)s6$<@ymwe`D^%wpO`VgC}E&C9sGNP?Vd+>govwiR8IDa@n@0 zo_bXJ>atag5tX2K9sCvU1XomCMkuyIiwcpa|K@8+e;4rm=}cd>iAc-l3!~BL1vuhm zAs8qHbUWfmtnXCi+*AgKI&Z#7+j(weGeHyyetO%;FsrkZZ@;;*tQ5$K6?obvdu0G1_3FuqXXg>7=@50-wwvI!{0;>VwGy#2v+pfBRaO$y$T4I53D|0r_&xl`64={8(p$QD5rmRXXK*3)%0v zcZTqu;Nf5c$s?(qJU@w^qFU3_xUNuQM3*F8ee6TvxW`W~5KO9#5-_sOHHcsYmMFnjDcn+Hkkl{Ep$AF;eIT!WNF5o_<0%JGik#N2sC2R^lWx0LzvLE zH=&Ij!F6ag^j+r$FQ0Gu#iju!PO zTUPI?vPNgMf0NdLBecUL&eE5>M4|IVCItiq^4+(7$*mP6#ds`5gsdLLLnS#nRmKyt z$(ctOxwG%t%#y&O6XZFSz0hOVagQG%sbsbxka*tFlE{^P@6x`vyytsM{a#=7!n0Ay zM%j{FfoLNBTG(bJJwjU<-wHgTX;e(}~J$OSUG3P(^`~NwpFZr&vWn@KO zhuq`KPydns`mee_>oPL5^iG&%~#4|yg2cK60Hao!O za&sawPL)Ie&||0x!{(onPc;k7{PS>Qiej3fe+F`$E;O+T&zF-LK*T9g6E*)-Gn^MNOWP8Qtq8K3A(t^gxX2{rUW;!=02H47$`+*;)zW5l?C{Muc5 z+8uGEL3U*Tlh?$Pw^>DWMl9mXi0ne|3f(j-3bO>bnf?U28n^H&*}&*o#pSsoHBSWT zf3eD3r{uP~TR;jB!Uja1$q{Pef{7O;mpe^A0N%1(j^*vwZW6V=EEx@zu zBq1e*&NU7i#WbY4Mku!?5$?LBTkx>wZBnLSMKCJ-)p%UK#-vHge5)jNO*YDNGlK;@1FO++kcRo*BZKks`}u&>w` zrxRNL5ah6O6;BWBANA~EG7Q<>Q=LnBJWkN8r+*WXYHYqdr0T57H3_<{{&#y!f=1d< zF`l++i|9SE0MJQwXU7Ro>bwFVf0M~K4|Ad(kGTqAZ%M7jq9EJ6o!1Mp&P($y8E;Qk z`Pw#rldqj_-kBkk-??%=Z*#9O46@93+9Jl+$kC*oy5T1KT57O+XLWY5Sf5jJ9c*2gtsy)hjcOz}7Ha6KDi0XXU{0SGnTA~t12htVV zQAx)YHD>9%R%rP@wmhe;Ypo2-^GUC3N9fqZ*2E^-E!Y!7-d-b|GTJnMsK?_9IC#iy zC!u8DIzCY3829$V{eB3jf9i>ZIz>BEG3ZD4g$dq-nU3@vPoKSf_U@ThM=TCoB`(MW zhWGKZ*tRQ{b&l0x*9SX%ccO+neRpz8ZT8rVEF2!j=o!AdX3_{sw&;cO3yVbTz{ihl z$M!3Gw`3yn81>IgQeK)Qj%?ZuQUe+hv5NZnlaLCyjOm2^A&6Rtf61v1Lk=<5l2VAr z(?M{Vt<$QRAswB`py)aG<7jBsTW*=Oa%`Q-!kZA^oSeR*oi zN|js&W{hyVL?np~m7E<3>^6lm^(dr(k%tR^lEEoSkFO#Df5ND=!?ebLAn2kRc(-a` zj4>*Lf@_CMH6H(cS4?!Erl%99-&0I%>AnV$4G~Igg}njG)px)>GZ*a+>}JEVynxp0!fH>GX@35m(DE zx$3Yau08UJdHs!`JLeVBCJV2ngVDwN?P$=@i^(UheYCgI)4xXAFl61#YyfEwF6ll( z3$ijNv(=y~2XQg9q`7teyLghIL%Howk`ycu@v=5OaWmZVA`( z$a+n($KT@Aaeuu;!vB&8Q@-dnJr2FTUGci0Vx`EMq_yRbcuw&}15~T}9j1e%teSy7 zBVzg&e{g^giVfvu>bg@uJ$1urcu&w~$9ytlF|>&`<}=+-DY>VMAnLv*-hrWx@5(+L znzQ|Tz_*dh2?@{vVgBMaZY~yU2`WXLBWfh2r+XyQk$1z>G-Hy*S+dv$x`DPO zK{?poUr*{(z3II~Z*v=scGn?*>-fK>WBoz{f1`RCsKF9%rg1e80f)^4P7fE21!ybJ zV&OFA5(J1ni8&7o)lnj5NNv*FVJGk5 z4HYG%Qk0nyq!=>6n4Lw?%tk6+GaHT4o^*%}MiY}yQ!*N;y-12L-&8ZONyE{WGoY{} zAvUg~;R%Ma^j{SdTE#7$yc$}$?$nvEe;F>J%m|lmUkbY{MHG22EN)pLfs&LYZmLHa z0v^EgAm21WOdj(*b#PNT7Lon4xWMk&8% z4v4=$)JHEt5kOaX04bp!_@;8$>S_x%sQ^b;P0P?}UpkVRM!fGOh{+&3wrg{ae>-~t zFv3#*&`i@?55ccs#1xZ=HyZwqCTvadq#dF(;+{JD@$0iEZ(qETmQ+VfA+2+F+zp}d zYmgH)BF4X;Z0i)rg~0~C-`CpyeS4TnpK^s^)V^tkYJ@pR=%kfHTvS_o`$NOZ8Ycg| z`F`@tH;a^54`OQ$Q8-~*lKCyP%7R(WG_4SB${BNnnefsdd6>w=Ak1uQI-krd_ zAc>MzZ?q973B*gPR87CMsU&Df*d3ji5C>_g1F7tl|3G>Ye@~O#YnrlzE6NfFsMp22y2K-V##=kGKxjU_nKFAsY(tJj<+@YqMFX zzFp-79t&%g9|Jh03#Esye`Hr|^6~?a9fOTIq4^5SZ&GDvmKpxa_sP86C0nvi7wL3` z6>JF2cPZITmTV164O;BXl9is@8*tsB%J$!<<8h%c*M>4#@qT#k2yd`=lWLtvPsuHi zqCwiUSf4fWqn45Jb!^O9MlO-6uY8rz7$0lpif5N{*3qn&#ATPwf0!LmcM5>^n-Uu1 zzy-ajXMt#~KM1h*&3fi?Vod!#h`b{}4D;92LchAoqfrPrDa}OlLRMV$KyA>EzeO_^QJia4TUA1_r9A3b9u<>SmN}fg{t? z^EdYKm3-W}Yark&gy(b($4d*B-;KvRa+Np793bSvmcJU0ugG=Ym=*ldw&WVl71!h@ z_t{He)6v`ul_S?`55u_jFpM$i(2^W!V|HO==SMj1dkWZ%%dDYbbkv!{Uw@RZO(>a+4z2DyJY@+HR&e)I}J*(82<-C^& z6>=rX5rD0c=fjh!$)9kRpC>nNI62SHkZ<9ojAT=-e>~GQI1E+_z98TFj66#b_X8pb ziDP9I8SeyOyGEO1hj<6ig-3a1*TG}Fh2=zJ=sKVr??6vyVBGT?GSc*Ifc5T1!4%p8 zJk<{TsI4cOJqcuQp;(=6tM?frI>0q^3^8SD$IHeO3>_@8oxI?B6dG%gM99V)Z>eqT7WLlwC_!140Wkf)4e1d~2w$HYFK@Ig_2A2b|(i0y_2a?&C$E!^=TKHG!yqY-EsePC)-*bjH0sj#;Auw z9NN~q3)U)zUmFA((|x zatct8>e*@bDY=RfGe(Z82_s7v$3vYyah1Z#Qwm!+gWi=kJhH_fk z88B5Lh*f&46!Q#1yL{amrrLGBk+}}9Eq8;WPBWYS@RTThA)D`#YyUKuE>Ht2fA;%} z?t>@ZgDJU6p!l(3vV_xCmx`#b#kj2gXI?J@SdaI}CP}+}f_3;|uza1|)kxew{!lZ` zOubL_R>aBIko&(!p9qfj#o};?<6ol!4X}GL3vdS_#)yMHBP_%-#L#@l^2`Ky4WARr zk!^v6%y3W~F)s$30a=Vl;Gnr-f4Rud&u`drM~lmI1sFR&PfkBSIsG&xoI@xVr*{!n zc-gO5gXa4uioB^d8Qv{~#l2^;^R|M^1W$rtsvNqNEEgL_SCGev8eWXbA+e~fvJRm( zsA|`>cy4U0PuZ4&I$*lIotMKW$Ej}iQZKMgyhmK|D6pU1E#GS$m1&kETRuiq=QdX z0QXLDrf6iM@?;O>z)S}Jfc<)K1z06sg1R94c(B_t2qM1bHE*)PrfGI{_UO??HKF+G z$%qIOYAUph3SV9A zF~26oczg$yW4ukk3s|V?9Kdhzd$Q!^%B3cJZ%e(87EnYK&flFPRtV(5??}-e;Kb3p zZZ)8f^exn+Z=vS$*&*lS@!CP0Bp~rl$fzx4dezlv7}lw()M}==0E{Pju71>PyN<|- zr_X+R_xknAv-59Wf4=_u@yqkSy?*`O`ML7eoau*4dd)9rQwegJpN+?7leT8!@dYfF z4?1G91AMt0kCRJ#!h5n2)fIa*O22w|I{T21^cpDe`sAXjF18>5uO8j7Wer2~XvG@J zw~yo!c_=rGhbwl?wy+2vHjjQ=U0#-#mrJ%>(jDJkRIDfpe}1vOTraPd<@#!rISqKu z1zT4iWDCaQ#AyRvtq{jw{m!>rI;q6PBUV2A@$AuBJ%a^wL!1_Xh<-FmQ}Q7M32mzj zzzW}#a1udLp@fW& zR3|!;u}bFPe{j*sbo9{$(`lF%)&^%vMc!kxYk&yKj4&d;@W>(pg>)rPwjpYt1ooCd zFSv!BAiE*zQ?v5}v0oVme~|cwlwA?Wb)Bte9^dLpb^hO~>hj4FtPB2?e_VP+?M z>#fqKw3Ar%k{`pAq(s9yI|V(wr_4PGCp2(jympxlf3Wcy>cT!Wf)-6OgcF?MK)x5T zQD;D-;N6~p3)e%_>$^Y&F*zYzOukiIto?otqnAea1PJ2{2}fAe^WmO&!a}KT(Y=6# z?rHCkMpl5+{Ei0w{*QFo`}_6Qd(%~2z0-6qZaI%?W>v9z0MKZ>1F3Tc za_y;ie-D%CV$dRo4IO}mk_nKH?#B=6w%814J#a=99(N~|&u?>& z9z8udK4*_l+5hlld>@^M5%R4g6H%7FdnU?qfBsq07i6r9UDQyn-o^yNC=PXufT!r{ zhe()GJT?iqU_4u}dKjPSR;*LA{Ht~A=OfiycG9DHTwNAZ%i}1yO_l)`%j>`hYPE^9 zAo7KMjj$i{pKZtax!g=)Ykgh`t@w1IaQ+?~X8JupSBU7h^d_25cV|yXq&tg@;@?Aq ze;yAJ?+q(welJ)HLedFwIYqvko_hQYbrB;)PgLmu`MQr(+zK*?(F?_x=4}4=$kSn}19Ez@hc=}|_xD>rQS@UhfM3i?C*4iN?@vh1z@%XBq zCdc|H+T@tcD|+=0H~C&62fZ6Z@2u@Ef9ZR8*TcF!8Wjeyy7L7QVC-vp;yzSR0iZ7| zRfY2Jy3eE4FMelF^G&>rnwihr1pI3X?Dp>^DsA zCiOY=i#R#KFeZfm!LYG-?4F70h$sc|aFAfc)M=)79{6XThzRcsGV}xGP|mP!eWQFZucJ} zr*|SAG;#-nghWU4IYRRi%Zn6we`!~*?67h~y+=LIDA4Xb9^q(LU;D~yFpZ1ucl%v8Aiz$bm~#RRa`?6TaH-J!&s!iZq>^mVf-5@UJw^VYTy@ zMq-^M#Qq7G|CBgibo?8R9!BtS@N*$pS<`2oze^KF<|DoukrCV(Eqs~^e;J15Lpp_I z*m|*oL|$GOYud_q(~g`{!qz$6!E?Vu2<>e<8R>$~pYY6mzKR|j9)xS@kM93W%iY&A z!)3gZhjMd+tW>0~d!j{TzN2@@Xcj&bSyH;k$|JK5ktZCXk{Ey$Y4Y)@{|8#_953%| zxGDRG+K&5BEO@Y9C9I3RAtyqVsmK z$jwcl@WDtH_bpJ&1QATm&v6{VpJYdr)Cbo`|LeOHIXXylNK|$Tf8NHO?k9i#9GvdO zT`44-WV~DVXpRHSY*JOe^0K-*Im0FVb%ksDoUc@ny}!W&nn%)PU9yj|ML7oze8#s4 zPjxug?Kxj%{Ez{w9_D%3N?JoKgppuC8jV+V82-p8&LtUTHcY#ND-sxw>^DoyL>9zz z3&q~aH@OmwfOL{gf6n-d(ADal`fz}jNa+DEV8sa?W)*}yjkXhawu=GXbULZhgm1w1 zVaqK2pFI2${`jv)-1)9+x6N0Qx$eS>=~**BS!C{P`shcNe+-9)I|5js6UjAuDFa_7 z>>7k(+lJgWt#mU;W#UV)fy=A->vm*zzZc|2r}Mw(yGG?gY4RKv4Gla zCb`rd%o}gOEjz}LJ(d5PFZJfYxkI{x$*`Pz&%A~BGGUNeFtxZReMH!0CD~ThWxLa| zIg1cU%-O<8e?`;aB5Nk{IZUG_6er|CPKC1=@d@FVky8;rI}rXMUjE(DgvyrBN^03) za)%QyQ@N}})$Vkj6y)&j1wTlAt3FZykP*FiL304Y&YvJdcOQ!yZ^0^$13D`udP^;> zCe0u}*t`MWKh2o~pt`6!uPQ*;n5-bpI&cK08QLl!f87+|YYy5KlfN1SIbbhT23&lb zxjNO`zV2#snn+kWKUpaBytJXP7mg;-0EvT4Y$jl5;)g@*OxRRP>UX9|mwZlUMe`J! z4LxG+(0N1kqy;9G&hfq5Np>ntR&2*gxxo=50(4VIK(z?hVAaUfy}CHW73%IR=gr~} z<#cWAe*@mk#(ApumHKOl8DJ{)T7Qu_TcCdH#z63w>M8KdD`G&HhOvZ!vcKZ9T00Jc z{u!O0vk$y(>QPTe&D<`!t953;8kMf>=(o-yt2FvuI2&UWc`8%IRLS0i<$9eF+!!TS zp1PzAh7oEcce0f^OEWmeMA&2ea`26cxTxzaf9~i@WQ0aB`7MYmDViGmxRU1X#Z%8S z+I{@g5M$u>k?;cq^kc1Q5Hz_j^8P3xHqF*&@BIArHr?LbIZdF>NH-lCV={L+kI@ zf5*q-qE0GTE5&rj^}Ja?11zp{&KCQ<@F(Sduf7`YLPSpOR0Ml8gl;*PG^Y2+bS)Qv zwD+n}?{Mq(I;K9#x-9fkgp9jMNid}EaEIxp!+z|^$<&kTu|1FiWVZqoTbgk9DlMhD&k!#ZgDS(l8F zHQgF&?X1BFzfA1+xZfSJhTP(M!U%i>_`5wH3yfg`ko2j&wCDt)Y z>1Nhs&AeUg_szV($JUyMVGR*wmot8rVf2es9=2&;9u-J-Za=Ib_!-a5g%&T+e+!nO z=5Z!}B#gA+O`8I*7XJWRi8FcNW|rWsGg$FDHza|$i!A^b=j|e2!RVimZN7pNk@@KH zIH|y|4$Fk5u1!IT7Y4?aO3|LgWWU-Q)Jwf|*y@%mZ*+^DjVC3;lSAAjDJ$!XEsxB8 zOE}lj_7d)&j39VyJT8MxS@pRcf05)?Kax@6&PXaQFkUNbJnNO>k!PfuC5b=-Lbb^G zB@t=HFVmh6W!JojXC4`zPL2A-S1_2}ZF<62$V#Up-DT)8oZ*?nPtPXMWCbYkM^eha zp){YWYSf;NElZ^MErABi)(97TwL%VV@Z$a68|*UT`0k+Q1lw(Cp~Ti5e=aQ7O|Hp9 zw0fFI|6<6S_7+bOXAnUd&BLerm>pB-ut&6O5@_F)H3`ik=jX4Uy?dPBVr%8=fC#v* zL?c-#Lkl;4Z=ZWPkZ)G2?zX-}(rNPn(yXTE1jcGI*XRSS>=>NoWw6WMB~`&6WdwzQ zO&&S|ju7sLo9EQnHk8Xmf0$jrHQeg;FRH^INSh?Mu-~7g4>}GFM8)NSS`s|@)rs!v zhYy2WX4)8qA}Bx_eKtDj`WN*ayN6#_(R})fmHRH+_2?cYEVhcnlY*V)EX_JK_s{Ie z%h)l$Q+N6KON^A^qKvuvgAYB1eT%dclHlB%B zN3B%857Dt2sY8-BSIPNc>{U)4ZG;;s<8c!8rMo3MyWT2yUpEs!CuwFY*WV~vGR|d& z<1|#5;9%cl8(HbsB>Xkr(Zr(s8tAo3x&OOGN)11ipRA8be^SCYMwUQ~qaF}*udj6V zN>xzpaI`@*fsfXexM0mF8zEb$Xg-e8Flo1X)XaqkqyIB{;98^~tB-%G*o!^ON8>7> zhhcZy?eSnaiGQ^G#JoSA+kkKz$0zoCfusdBV=Kw}X+2&THp*WmJk`E0Lr_*X?Ukfx z<4=+*C2$3ge**6WXZ{R;9D0?}m}p9>9v_pB#d%3TdH|KsrHCys1r-dU>2N9r)p&LI zjg+p)rR(o|o>~Y$j$xnxyX1Da-WMP*4akS8>>{K#TQ{kmw~!n*M{O zr%mzrn_`uwS>x{Jq)d@t!Rb!aw6fB!4%Lao9$r2MBX%EydDnEVM$c+asb^Ae?xS6J zHX~hQf2d70U6+|TUpDEiKN-&v1;<%mO`1xYkGsTy*2kFJ+9}h2q+sIJ`j|tDqH2;P zUXXUtml*tAO8Ao_LfzD5n>>0}HoTEhWs@@yh9lCr0N#TZ-;KX&i2ALC`rR_&k4n1Ynw> zf7C4{H9}8M@ErSh%IBXg@}Zc@%@3?RvHH`=j?Al1%ybihjtPad1>G_KJQu z;Nhw=nfBk(E<*acYPMGv5&6GbWQw*sx)eI46K=nqg zUCJ+DE7W4bk<;S#4|YmWtLm8h^-E7@SfmHq>=5dQ=?vU?HI-c@g02#=uENf>o#PUV zN6tc}3&m9j1-U5XS_sb;>otPv9$!$9Fg;-z_z|)@g`wyNM3XeA7#=?`n$KLAe`F>( z{Vc~=oyQV9wf6aXzXuxW4z`DEZJA=`4oxTz3g8>_?gNfqYoybvH-_=cg#87vQ>2p0 z?+TpxR40RvE%4;lm9H85E9hXJ$n6N+Y(?A&nXL>Zl+zmJj!~Is1<|d~)(({xa*WDJ zk(D3dToZQ1_CWYE;Ouj{LqlL{e~6@jdAQM_J3Oe*aT~4^{?^`r%;6fUCrFhp$goWn z1qoo6G`dEKt&Pqptr?rLVMEmOSreRYdHr0ldXx7_6TL*#S=ZfH6crGVb!j(U-#DQh z1{4Aj&OR~W^>|<1y&)I>se6prsx+Lqx0|1NH}-F;W(GwqrO+f4TF+&26EO zDFF5xR>%CSTv?m2oD?a5n^BjwxG~#|?GU7xF=I7)O3RBac+`b%AA~=v+cqeNYpk52 ziy5T{#cWqOOTW!+n@N%Dh8=e+Z6Tg%t^D*>w^}*ek5+Yc=kZz@(i@^3N97`Cb{fMn z*BRyy?)q?4jq$kSNG-(nCj zYO4J{+Mid8eDs8tpELtFsSNOCgHLRvmfMoiCy;y3;!klF&(yqme_-Z~26PQZ4+7vR z*NKEu9JunJsvGqp1*zk%`2esIeYW=+2g0ZtW)1t1HG*bR8pweG)Nr^s6VIE z3m}g6xm)Vwf)wd^eBpJXi(S?0WrI$N4RXXzWeNr(&z=Kfz-~BXnRmK!<_JBhUhi;H zNx;F*DC$ckB4XPQkk#q?5G=KfY!49y^Y|7al}2uq#$)>df2liyvAt6;)_+7WTD{a6 z4kY~LI*eA!afMewmTDe^F+0{!37yXsGpU2`owau_Vxbl>JGO|MH1pf*)!e^u#a#=R zbrvp5XRQ17#00_e-*op7gn!~WRZr7<%t@YR+}E6ZtNmM@Q$3KDE)#km=(W)bobk&Z zbXs-Cc71RRe+$29dxp%j?e>-dOyA)Xlh#PI=yij20$?fIJI|f` zQs3zA=If8Z5W#D(VUCPcIW}Bn*R5U7Fam2*@3y>~e_}69C%;v^Oh*50xYWKHsW6RS zq7X#e=&x;~!!}tH<}dSR0d4{KKbqLn>4hI{g;=?nTwpgwZKZx*fHy{epOf;C~rDPQVR9wS4`c>>%1AFn@k#RCkkj{z?E(| zP^fI-+_r=Iw_}3}wjn#D@>g^~OS88*$#5X2rh}@g!f6;CQ1FGHEb!4{L&f7JIY9+x z^nWpLDGDfo49U$KU`Q6=kYE_>U#BMJ&ZOS*e}W~akax!|frj^jek;Yl=w;83UvV0(~XltH5K?%WuX)Ej_v$pkr#yj zoN%&rtJjCtft;cUbJU>q{eEJ=Gov|DoRvs{k7pYqeiQTbRbZ3%k%UnF| z@4tUMYnO1d_HT78CC7u&JTq2*QRL2hQ`I$JZrMA0>+m%6C%Ksuf;iQKhWshY;f}dj zeX#`I=|&|Zoku!;_myJA>@DE(f5MH>+3S9SI%3k*%KNe;C zO>OSF78X;xuQV#3if+k%&t$gSKIV1@h3-6-RZg@8)@gq3_Z^5PKe136fAAO>?4ngs znGUSr$_s%AfS&Z?2h=C1%~52=6SI65kmsUBwYik8a6Mzg2|g{RT5~9l5Dru+sd0le zqIjF8Mb3Xrwy8`qCGzcbDHy#pL5m_6Gbs}jp~K5aZ58m@T)00M*<36-yhZLj?Zar_ zg^CQl>WWViswR+$TeH*Re+5uHYG>`?#oB>s3o;*>=SO7ZK0P9%@L9lebDVN<0Rg8_ z8oh5s1Qe;FMLZz^#moW33TaZpmTZ2`%Z1b)Y5?1~m-BhOh|^%$$#rK$ls^?E+l4*8 zAs!F+y4oHrD_NHYSMXAbQZY%jWXhJyce{(FxXZ*c29Dy16 zM=+E`-U0b-)uS*Tcg5LRD~54O=x-(sgv}D3Qvl(D8XtLEDsbuN+@@%QL{sWiMA}@6 z22y~13_fh?eOEo>zuNDr(;5F83~1y{^{h7E6}jC)n7V9An-b{AB0b0pfEmVDV-fjs zp=ApHwL>r%%+7GCfA|<*rV+4GOphJ_PV2|rj)^C<1} zn=WCSud(zj|H4Q zG19d0bw8EAbxfF~lQsZE7@6$5rlS z{9u)XP8`K*M&zW>lF=t%Dv7`M$U>tC%&e|a1=2R5f1XY?j@m2jn4DzpaU>@;NE=z8JSH$sf77Yd!Eu?Kd{vwD6u=u$o47tw z-=Q8{%@UhcKYCfi4U&lYutZV`fCivU;f_jlWmx?;)aS6 zNJ!UAAU!}W-)Q%a29OKuf$1#A-bw)tgu;+wXzg@mR#Tfo#ux}#u8mo1JnnMfsQ9Y_ zK5PqOe?0Q-M^annjS{}hmA%b)++yTUUkt1b{O?~KF)ioRED#*0QYr^sA@0ZZ_CUrw z5-e-w<@0n)AOUtvU=fdAr{W|2&k08j!Xue|;0TEV1tZ>I?72#G&vU;C?|H!Kk5G zlZgjlm2D!FjZj^5EEy*KRg5c%=>ez5C4R()Nt%JNb1VkNDSa>wOuxiFn+tD8>c)CA z9Lwv3V{~}W8+htuBKKyaojnxi1=`vr%Yn-1swfCfbpQ}dVCOw1+#g(evr-{V;g#mF ze=hz$0hVFe7$+r6OXd|R7RGE+9U_dkboE?~#=p442DrfBgF3ap0wq0Ky`Rjr=LMj8 z7+qg4Xg(g7=)Ov#`*NA4=8+D?vS`a=O>!fFw4VoDEM^F6ZO}KAelX|%KI5Mngr8)( z!Rz178Zehv*GwRNB8K&99)=oUsYhMee;}+>s2r(4yJ#ra{32YTAPA492}{#%wA^X; zt0O`Y9LW_d0Gi_Wo0kDYi;Ig>Jpd*ij}K&15T8oV=S2Dt9@laQW5f4ThF z{B(gB7^NGS6!t#4fzL$lz~Z<>yH#JE&S=&gvP9&bIgDE~ivT{=>S_e4gh0ufH`dKN z9@}6K!)duWZ{HIaj(!IFMO*RMm)n? z?#?nL!s)Zw;@@Cd+$K6@ zNvT5yN~f$_Z@-zjH2X*CPVLWpF>bx{jZr&G`T6TDy{?1=Iy-#)xVNiYe=5T|fWnYs z|8=?jDD@G{cFBZb2ZxBd5@6@y$^aMN{HI>018;gkSqkFqYk30r94Kug!%m z0}%jwwLT((s&>1=Y+u@OrJ-P>ejJMfB$F$KpVoyRx1qYff;&Dj&wYV^(HZqUh6PbbZ3tD$9yv_SwyZO zu_$W2*-aflE+{5;g4AwGDiiw9M*Z3ab^q3oYf2J2zWGol~slM@99-P^wUWO-Y_tD4_`>5uBu?f4R$5cPyhE=xp8!L|Qcu zUu0-mO5>!gJr68IcCWQHPg>X4TMA-Z`mYjB1firzj~HP9*(B!d?@5_Tx;kYZCoarM z8K{nuo)wOUUUm;BWuI@DY;ykRq#~=7>?8v^OkzhhqQHOQqn=UE7@op$Fk@tslBG^* zTZSTmJxyRffAO1S2Zz99nQs$!E*xIgpx0@v+@F%0wctNdiYPcEc!n5VAVs0_sNhmH|U1i8YD2S!W3 z!by1@e-l2X#rMvVYgdMt5B9E-HYL|qcIW)B$+f%Jr(}H${&($Z0w^93e3=DJt5Hth z`a@;)BmQMl8NPpQ$&htsYX}R{GOms8YCUY+9k+zRsQGe020P^}0?u=)(-|j#%c~=Y zGU)qbCt zzmae@77}H?tCB2LtE3{1)yc3Dd#?kVlYSv8;YmFn7pa4uu3YpqkR!QJ=^l3|n8JO} zf7M97Q_*}UH4>qX@XdJ5SOtECZP!&d#CVLRaxvj+=m%6-LDl;qsSHFKy;4b)PPbTj z4WV$}R~B%^^eo}H5-Y+#OG;7$*4oC%tszDZx-J$Yw}u}0568$=Juz~BO{Z&6@xmCn zHAFFcoirY^WF3ST+b=tSn@9%71ZG|5e>`%;qN`n*%$#UsiUw`VsR(GbL&uIJb&5vn z6b%rcYp__6m(v!KmY^kijt8Gvt8DY_qN9-d$pnm4>Lf5}W`M|0Z^=Z|+rWszt~F_T zn98q-CrOlQ>NaV?j8o;?q#%v2cfuM2HXNdo@@5PNI;`m^u2x}rPd3qcRAq=A+F!v7+B zV!!vy2EYxA8CqPF`Cm<-8?tcifA>SkNAhLTI9VLf#DG^V<3=;pO>s}CecUXv6tIWj z|C#&^Fc{f6xw}Fd^EY^7W~%v_Eh4wp49gLk-$EU*uhCt`4-WfyWy0!Ym3UrG)BXuu zrnk!YfZB%a9CJc1k>SE4v8|#Ik)RH@2Ex4RY;*#3#^g)Kioo{!VWPXse|CX8gkN-~ z22oHv9+R$7~{!#v;d%8eBq{6IV8`+0bTi!vq^t&4!5^NQjH#c_rUgLH&Z&HR2T^XYO*#t_I1? zh8LRwuhBkA2g~+iz{|noUA5g-gD0p6rNsG)t@5AEMvTLY2CS@G!3L0sSAJb>BWxdR zRk-4SmJmeyU^Lj!Yc`6#fARI_0<)9ucnqXq-yEd)z?|Jj_TdLza2I2pln z`nY!FxvKlzKg#Eokf>9TapH6_FeZhYX zp248N)MUt>XGR8l|Hacf8*G|pS7(nNT~rf_gAGaN9~F--Sjhy1?|;~q{C&$FD(eDg zqL!6Eg&~2;qeF6}ZYT&9msR<&giqb_-`VP+YTQ4{5vrV09GAzqUw!b*?IAUru|a+Y z^r7YCM#1islqVKrpnvnn;v6x@v=Yg*exf25pF-gePpYxB|-;Qi!!zJAa4V`K@JDOFEpa{{1_M zSy3B(i{>H?GY|Q$rncbE;7XBf1^jcxsTtHFZ@$q3EJL9jVnR3QNx(Vh$CVzdkivG^U0@!lsVS!wdE^(X{06vYN@&`+av82T%DL*8)PVQhqAZey! zSEmPgA|{5b!mI(wsYxPpSKV104FP5$V|jNpGl|52y#%=jXzzQ-{T7DlI+Y;P)1~Y5g4YrV}1Kkl=c`36W4B zc`yhsbKGIgOVA{5RaOmE!+x(az?;RaA_M)!&FUl#S{cb>4r|gRI)PNvn1~ay;dl`B zCcpm(On>`7-K6&EW-nL3)%rjG)iC9Hm*4;H-0V-@-kr6WeA}C2DBF92XT0p+vLo=U zz2A!ysZ$Z}p7d3KZR6^StvGG80E+A;@IJ5nAZ2TkPMr)Mp^PpP%f$}uaOMmmmw!W@Viwm#yn-)KZEiTix8pZ-tc5dw zEEy}3jEC|x$jjqqmb^ zsW;&~2vd1Uza&bfh`_RviseTZD_>>qiaVr-<03kkXC{f4<&OVP3o4vH_gUat|2OLc z)PDyMbag?+N>#725$IKUM1{F)kp`jz(~Uu3rvziC%DdP7Jn}|VSG>j#tG3q>Z67$> zUz>jJ`Sfrkf;ai{>@_sLwki!o} zLgcE%cmIgBtRhiY9P(u3T<#p;c=bPJ`hVboIoZPaC#5>lbxvTZw@PyX=3hH^Z6&G# zN;*|QBt&6stQv9Ck+$)!J+dbKKFA_-v(P)$@Dvb#c zotzw5n?znv_06O^re>9*7pIU`|KvZ{H^f0y*<1^7S;u?;eSQhAHXAf4vG)qKIe!<& zNsVISKxOxkxjmxa!a952jtQ`ey%V&oX)I>O6>7NRl3Tf|GDe)^oYK)@p@+w-2I_{F zXhTpmRh@HW_asZyiWDFk8)U*Qf77S2o`-6cR{E|o4J7igN$*(C=RB{(OI}{~iNubX zLpK%}B6J-J6XA)qV9<`nqni!w_v zL`L6M%g0+d$bWo>`Fx%M*lk2c-&f7^sx4RY_kw&a`09e$dgbp(!6$Gg-uAX9dfPUq zQ`?5}(s>$w#)=_g_VJq+@2X4YmiMmP*SsiqZG#Wj=IQVY-K+XZUG~Y@A6DRlHjL7J1TYg(DW$5ACw!B;TJZm=2Zf?8AzaHt5=ZrS3V6}ZjU%{I( z$?9H>)c6f+&VG3LvVXb&SE+r*tBaTHnr&?%|N3Y_yw&n;wT!&a*=oI_ z`eOW%w{7W_e%qGug0OvqI-s8~IrJG$gs zG|s78KfQgf{`#3MH&u11e^uggy{&HW=Yjy%+I9&1igd>tdcjN307ErNPapVJ5QWZf ze+E8o8pyQLd*8Vs2gSeO{DLN$p9}Jqfrq(QE9)$S@%Z|bmu)p?tm&KS zzLwD`=+zNjPJixYzcdrqykNDisy_14PFY)%)b+#dJM0LzRQT+j`{;2^>u4p%-u17) zAgnc*9}+j>3)pz2y$^`C0#RXdkhJW^Lx~;R3LZyu$PEBD%sKJP^ zn*lA8;ABU+5BxZ!WXsFTj8-xzmQH@1K+Coa5`48u3LtjcZky)_GRjB4{PN2$4`01{ z`1I*ulU-e9bv<}IA|sOvz~bgK#z?`sTS5y$xA{6rC!3EeK^r!uMgDg}w@IOb6Q6Av zJdv Date: Mon, 16 Sep 2024 11:48:10 -0400 Subject: [PATCH 355/432] MERC 3653 channel definition cache orm cleanup deletes (#14389) * Cleanup on job delete for LLO * Fix lint --------- Co-authored-by: ad0ll <20057155+ad0ll@users.noreply.github.com> --- core/services/llo/cleanup.go | 28 +++++ core/services/llo/cleanup_test.go | 102 ++++++++++++++++++ core/services/llo/mercurytransmitter/orm.go | 9 ++ .../llo/onchain_channel_definition_cache.go | 8 +- .../onchain_channel_definition_cache_test.go | 15 +++ core/services/llo/orm.go | 8 ++ core/services/ocr2/delegate.go | 12 +++ 7 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 core/services/llo/cleanup.go create mode 100644 core/services/llo/cleanup_test.go diff --git a/core/services/llo/cleanup.go b/core/services/llo/cleanup.go new file mode 100644 index 0000000000..892e925f37 --- /dev/null +++ b/core/services/llo/cleanup.go @@ -0,0 +1,28 @@ +package llo + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink/v2/core/services/llo/mercurytransmitter" +) + +func Cleanup(ctx context.Context, lp LogPoller, addr common.Address, donID uint32, ds sqlutil.DataSource, chainSelector uint64) error { + if (addr != common.Address{} && donID > 0) { + if err := lp.UnregisterFilter(ctx, filterName(addr, donID)); err != nil { + return fmt.Errorf("failed to unregister filter: %w", err) + } + orm := NewORM(ds, chainSelector) + if err := orm.CleanupChannelDefinitions(ctx, addr, donID); err != nil { + return fmt.Errorf("failed to cleanup channel definitions: %w", err) + } + } + torm := mercurytransmitter.NewORM(ds, donID) + if err := torm.Cleanup(ctx); err != nil { + return fmt.Errorf("failed to cleanup transmitter: %w", err) + } + return nil +} diff --git a/core/services/llo/cleanup_test.go b/core/services/llo/cleanup_test.go new file mode 100644 index 0000000000..7c7f13e02f --- /dev/null +++ b/core/services/llo/cleanup_test.go @@ -0,0 +1,102 @@ +package llo + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/services/llo/mercurytransmitter" +) + +func makeSampleTransmission(seqNr uint64, sURL string) *mercurytransmitter.Transmission { + return &mercurytransmitter.Transmission{ + ServerURL: sURL, + ConfigDigest: types.ConfigDigest{0x0, 0x9, 0x57, 0xdd, 0x2f, 0x63, 0x56, 0x69, 0x34, 0xfd, 0xc2, 0xe1, 0xcd, 0xc1, 0xe, 0x3e, 0x25, 0xb9, 0x26, 0x5a, 0x16, 0x23, 0x91, 0xa6, 0x53, 0x16, 0x66, 0x59, 0x51, 0x0, 0x28, 0x7c}, + SeqNr: seqNr, + Report: ocr3types.ReportWithInfo[llotypes.ReportInfo]{ + Report: ocrtypes.Report{0x0, 0x3, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xde, 0xf5, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xde, 0xf5, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x8e, 0x95, 0xcf, 0xb5, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xd0, 0x1c, 0x67, 0xa9, 0xcf, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0xdf, 0x3, 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x1c, 0x93, 0x6d, 0xa4, 0xf2, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x14, 0x8d, 0x9a, 0xc1, 0xd9, 0x6f, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x40, 0x5c, 0xcf, 0xa1, 0xbc, 0x63, 0xc0, 0x0}, + Info: llotypes.ReportInfo{ + LifeCycleStage: llotypes.LifeCycleStage("production"), + ReportFormat: llotypes.ReportFormatEVMPremiumLegacy, + }, + }, + Sigs: []types.AttributedOnchainSignature{types.AttributedOnchainSignature{Signature: []uint8{0x9d, 0xab, 0x8f, 0xa7, 0xca, 0x7, 0x62, 0x57, 0xf7, 0x11, 0x2c, 0xb7, 0xf3, 0x49, 0x37, 0x12, 0xbd, 0xe, 0x14, 0x27, 0xfc, 0x32, 0x5c, 0xec, 0xa6, 0xb9, 0x7f, 0xf9, 0xd7, 0x7b, 0xa6, 0x36, 0x30, 0x9d, 0x84, 0x29, 0xbf, 0xd4, 0xeb, 0xc5, 0xc9, 0x29, 0xef, 0xdd, 0xd3, 0x2f, 0xa6, 0x25, 0x63, 0xda, 0xd9, 0x2c, 0xa1, 0x4a, 0xba, 0x75, 0xb2, 0x85, 0x25, 0x8f, 0x2b, 0x84, 0xcd, 0x99, 0x1}, Signer: 0x1}, types.AttributedOnchainSignature{Signature: []uint8{0x9a, 0x47, 0x4a, 0x3, 0x1a, 0x95, 0xcf, 0x46, 0x10, 0xaf, 0xcc, 0x90, 0x49, 0xb2, 0xce, 0xbf, 0x63, 0xaa, 0xc7, 0x25, 0x4d, 0x2a, 0x8, 0x36, 0xda, 0xd5, 0x9f, 0x9d, 0x63, 0x69, 0x22, 0xb3, 0x36, 0xd9, 0x6e, 0xf, 0xae, 0x7b, 0xd1, 0x61, 0x59, 0xf, 0x36, 0x4a, 0x22, 0xec, 0xde, 0x45, 0x32, 0xe0, 0x5b, 0x5c, 0xe3, 0x14, 0x29, 0x4, 0x60, 0x7b, 0xce, 0xa3, 0x89, 0x6b, 0xbb, 0xe0, 0x0}, Signer: 0x3}}, + } +} + +func Test_Cleanup(t *testing.T) { + ctx := testutils.Context(t) + + lp := &mockLogPoller{} + ds := pgtest.NewSqlxDB(t) + + addr1 := common.Address{1, 2, 3} + addr2 := common.Address{4, 5, 6} + donID1 := uint32(1) + donID2 := uint32(2) + chainSelector := uint64(3) + + // add some channel definitions + cdcorm := NewORM(ds, chainSelector) + { + err := cdcorm.StoreChannelDefinitions(ctx, addr1, donID1, 1, llotypes.ChannelDefinitions{}, 1) + require.NoError(t, err) + err = cdcorm.StoreChannelDefinitions(ctx, addr2, donID2, 1, llotypes.ChannelDefinitions{}, 1) + require.NoError(t, err) + } + + // add some transmissions + + torm1 := mercurytransmitter.NewORM(ds, donID1) + srvURL1 := "http://example.com/foo" + srvURL2 := "http://example.test/bar" + { + err := torm1.Insert(ctx, []*mercurytransmitter.Transmission{makeSampleTransmission(1, srvURL1), makeSampleTransmission(1, srvURL2)}) + require.NoError(t, err) + } + + torm2 := mercurytransmitter.NewORM(ds, donID2) + { + err := torm2.Insert(ctx, []*mercurytransmitter.Transmission{makeSampleTransmission(2, srvURL1), makeSampleTransmission(2, srvURL2)}) + require.NoError(t, err) + } + + err := Cleanup(ctx, lp, addr1, donID1, ds, chainSelector) + require.NoError(t, err) + + t.Run("unregisters filter", func(t *testing.T) { + assert.Equal(t, []string{"OCR3 LLO ChannelDefinitionCachePoller - 0x0102030000000000000000000000000000000000:1"}, lp.unregisteredFilterNames) + }) + t.Run("removes channel definitions", func(t *testing.T) { + pd, err := cdcorm.LoadChannelDefinitions(ctx, addr1, donID1) + require.NoError(t, err) + assert.Nil(t, pd) + pd, err = cdcorm.LoadChannelDefinitions(ctx, addr2, donID2) + require.NoError(t, err) + assert.NotNil(t, pd) + }) + t.Run("removes transmissions", func(t *testing.T) { + trs, err := torm1.Get(ctx, srvURL1) + require.NoError(t, err) + assert.Len(t, trs, 0) + trs, err = torm1.Get(ctx, srvURL2) + require.NoError(t, err) + assert.Len(t, trs, 0) + + trs, err = torm2.Get(ctx, srvURL1) + require.NoError(t, err) + assert.Len(t, trs, 1) + trs, err = torm2.Get(ctx, srvURL2) + require.NoError(t, err) + assert.Len(t, trs, 1) + }) +} diff --git a/core/services/llo/mercurytransmitter/orm.go b/core/services/llo/mercurytransmitter/orm.go index d73722c82a..ed8c8843f4 100644 --- a/core/services/llo/mercurytransmitter/orm.go +++ b/core/services/llo/mercurytransmitter/orm.go @@ -21,6 +21,7 @@ type ORM interface { Delete(ctx context.Context, hashes [][32]byte) error Get(ctx context.Context, serverURL string) ([]*Transmission, error) Prune(ctx context.Context, serverURL string, maxSize int) error + Cleanup(ctx context.Context) error } type orm struct { @@ -194,3 +195,11 @@ func (o *orm) Prune(ctx context.Context, serverURL string, maxSize int) error { } return nil } + +func (o *orm) Cleanup(ctx context.Context) error { + _, err := o.ds.ExecContext(ctx, `DELETE FROM llo_mercury_transmit_queue WHERE don_id = $1`, o.donID) + if err != nil { + return fmt.Errorf("llo orm: failed to cleanup transmissions: %w", err) + } + return nil +} diff --git a/core/services/llo/onchain_channel_definition_cache.go b/core/services/llo/onchain_channel_definition_cache.go index 752dc3196e..6ff2058fb7 100644 --- a/core/services/llo/onchain_channel_definition_cache.go +++ b/core/services/llo/onchain_channel_definition_cache.go @@ -58,15 +58,15 @@ func init() { } type ChannelDefinitionCacheORM interface { - // TODO: What about delete/cleanup? - // https://smartcontract-it.atlassian.net/browse/MERC-3653 LoadChannelDefinitions(ctx context.Context, addr common.Address, donID uint32) (pd *PersistedDefinitions, err error) StoreChannelDefinitions(ctx context.Context, addr common.Address, donID, version uint32, dfns llotypes.ChannelDefinitions, blockNum int64) (err error) + CleanupChannelDefinitions(ctx context.Context, addr common.Address, donID uint32) error } var _ llotypes.ChannelDefinitionCache = &channelDefinitionCache{} type LogPoller interface { + UnregisterFilter(ctx context.Context, filterName string) error RegisterFilter(ctx context.Context, filter logpoller.Filter) error LatestBlock(ctx context.Context) (logpoller.LogPollerBlock, error) LogsWithSigs(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) @@ -115,6 +115,10 @@ type HTTPClient interface { Do(req *http.Request) (*http.Response, error) } +func filterName(addr common.Address, donID uint32) string { + return logpoller.FilterName("OCR3 LLO ChannelDefinitionCachePoller", addr.String(), fmt.Sprintf("%d", donID)) +} + func NewChannelDefinitionCache(lggr logger.Logger, orm ChannelDefinitionCacheORM, client HTTPClient, lp logpoller.LogPoller, addr common.Address, donID uint32, fromBlock int64, options ...Option) llotypes.ChannelDefinitionCache { filterName := logpoller.FilterName("OCR3 LLO ChannelDefinitionCachePoller", addr.String(), donID) cdc := &channelDefinitionCache{ diff --git a/core/services/llo/onchain_channel_definition_cache_test.go b/core/services/llo/onchain_channel_definition_cache_test.go index d2b976ddde..78bbcef428 100644 --- a/core/services/llo/onchain_channel_definition_cache_test.go +++ b/core/services/llo/onchain_channel_definition_cache_test.go @@ -29,6 +29,8 @@ type mockLogPoller struct { latestBlockErr error logsWithSigs []logpoller.Log logsWithSigsErr error + + unregisteredFilterNames []string } func (m *mockLogPoller) RegisterFilter(ctx context.Context, filter logpoller.Filter) error { @@ -40,6 +42,10 @@ func (m *mockLogPoller) LatestBlock(ctx context.Context) (logpoller.LogPollerBlo func (m *mockLogPoller) LogsWithSigs(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) { return m.logsWithSigs, m.logsWithSigsErr } +func (m *mockLogPoller) UnregisterFilter(ctx context.Context, name string) error { + m.unregisteredFilterNames = append(m.unregisteredFilterNames, name) + return nil +} var _ HTTPClient = &mockHTTPClient{} @@ -76,6 +82,10 @@ func (m *mockORM) StoreChannelDefinitions(ctx context.Context, addr common.Addre return m.err } +func (m *mockORM) CleanupChannelDefinitions(ctx context.Context, addr common.Address, donID uint32) (err error) { + panic("not implemented") +} + func makeLog(t *testing.T, donID, version uint32, url string, sha [32]byte) logpoller.Log { data := makeLogData(t, donID, version, url, sha) return logpoller.Log{EventSig: topicNewChannelDefinition, Topics: [][]byte{topicNewChannelDefinition[:], makeDonIDTopic(donID)}, Data: data} @@ -436,3 +446,8 @@ func Test_ChannelDefinitionCache(t *testing.T) { }) }) } + +func Test_filterName(t *testing.T) { + s := filterName(common.Address{1, 2, 3}, 654) + assert.Equal(t, "OCR3 LLO ChannelDefinitionCachePoller - 0x0102030000000000000000000000000000000000:654", s) +} diff --git a/core/services/llo/orm.go b/core/services/llo/orm.go index acf6e8c721..5b132e6537 100644 --- a/core/services/llo/orm.go +++ b/core/services/llo/orm.go @@ -66,3 +66,11 @@ WHERE EXCLUDED.version > channel_definitions.version } return nil } + +func (o *orm) CleanupChannelDefinitions(ctx context.Context, addr common.Address, donID uint32) error { + _, err := o.ds.ExecContext(ctx, "DELETE FROM channel_definitions WHERE chain_selector = $1 AND addr = $2 AND don_id = $3", o.chainSelector, addr, donID) + if err != nil { + return fmt.Errorf("failed to CleanupChannelDefinitions; %w", err) + } + return nil +} diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 52dbbf87b5..7bc3f47309 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -360,6 +360,18 @@ func (d *Delegate) cleanupEVM(ctx context.Context, jb job.Job, relayID types.Rel d.lggr.Errorw("failed to unregister ccip exec plugin filters", "err", err2, "spec", spec) } return nil + case types.LLO: + var pluginCfg lloconfig.PluginConfig + err = json.Unmarshal(spec.PluginConfig.Bytes(), &pluginCfg) + if err != nil { + return err + } + var chainSelector uint64 + chainSelector, err = chainselectors.SelectorFromChainId(chain.ID().Uint64()) + if err != nil { + return err + } + return llo.Cleanup(ctx, lp, pluginCfg.ChannelDefinitionsContractAddress, pluginCfg.DonID, d.ds, chainSelector) default: return nil } From 0187f18ba62b44d4c8ff20f07ef8dfd6e0d7b451 Mon Sep 17 00:00:00 2001 From: "Abdelrahman Soliman (Boda)" <2677789+asoliman92@users.noreply.github.com> Date: Mon, 16 Sep 2024 21:23:30 +0400 Subject: [PATCH 356/432] Add commit offchain config in OracleCreator (#14423) * Use commitOffChainConfig to initialize FeedReaderConfig Add FeedReaderConfig to Bind all feed addresses for each token in the offchain config * Add TODOs for commit off chain config in homechain deployment * Refactor oracelcreator/plugin * Use functions instead of methods * Remove token feed chain bindings - going to bind in chainlink-ccip * Use commitOffChainConfig to initialize FeedReaderConfig Add FeedReaderConfig to Bind all feed addresses for each token in the offchain config * Add TODOs for commit off chain config in homechain deployment * Refactor oracelcreator/plugin * Fix go mods * Add changeset * Remove missing things from fixing merge conflicts * pnpm changeset --- .changeset/curvy-points-grin.md | 5 + .../ccip/configs/evm/contract_reader.go | 103 ++++-- .../capabilities/ccip/oraclecreator/plugin.go | 290 ++++++++++----- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- .../deployment/ccip/deploy_home_chain.go | 10 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- package.json | 2 +- pnpm-lock.yaml | 332 +++++++++++------- 14 files changed, 489 insertions(+), 277 deletions(-) create mode 100644 .changeset/curvy-points-grin.md diff --git a/.changeset/curvy-points-grin.md b/.changeset/curvy-points-grin.md new file mode 100644 index 0000000000..43d500f44e --- /dev/null +++ b/.changeset/curvy-points-grin.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#updated refactor ccip oracle creator diff --git a/core/capabilities/ccip/configs/evm/contract_reader.go b/core/capabilities/ccip/configs/evm/contract_reader.go index f85395e2c2..7b04b42e8d 100644 --- a/core/capabilities/ccip/configs/evm/contract_reader.go +++ b/core/capabilities/ccip/configs/evm/contract_reader.go @@ -7,13 +7,14 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/smartcontractkit/chainlink-ccip/pkg/consts" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -22,8 +23,9 @@ var ( onrampABI = evmtypes.MustGetABI(onramp.OnRampABI) capabilitiesRegsitryABI = evmtypes.MustGetABI(kcr.CapabilitiesRegistryABI) ccipConfigABI = evmtypes.MustGetABI(ccip_config.CCIPConfigABI) - priceRegistryABI = evmtypes.MustGetABI(fee_quoter.FeeQuoterABI) + feeQuoterABI = evmtypes.MustGetABI(fee_quoter.FeeQuoterABI) nonceManagerABI = evmtypes.MustGetABI(nonce_manager.NonceManagerABI) + priceFeedABI = evmtypes.MustGetABI(aggregator_v3_interface.AggregatorV3InterfaceABI) ) // MustSourceReaderConfig returns a ChainReaderConfig that can be used to read from the onramp. @@ -50,6 +52,17 @@ func MustDestReaderConfig() []byte { return encoded } +func MergeReaderConfigs(configs ...evmrelaytypes.ChainReaderConfig) evmrelaytypes.ChainReaderConfig { + allContracts := make(map[string]evmrelaytypes.ChainContractReader) + for _, c := range configs { + for contractName, contractReader := range c.Contracts { + allContracts[contractName] = contractReader + } + } + + return evmrelaytypes.ChainReaderConfig{Contracts: allContracts} +} + // DestReaderConfig returns a ChainReaderConfig that can be used to read from the offramp. var DestReaderConfig = evmrelaytypes.ChainReaderConfig{ Contracts: map[string]evmrelaytypes.ChainContractReader{ @@ -109,6 +122,47 @@ var DestReaderConfig = evmrelaytypes.ChainReaderConfig{ }, }, }, + consts.ContractNameFeeQuoter: { + ContractABI: fee_quoter.FeeQuoterABI, + Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ + consts.MethodNameFeeQuoterGetStaticConfig: { + ChainSpecificName: mustGetMethodName("getStaticConfig", feeQuoterABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameFeeQuoterGetTokenPrices: { + ChainSpecificName: mustGetMethodName("getTokenPrices", feeQuoterABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameGetDestChainConfig: { + ChainSpecificName: mustGetMethodName("getDestChainConfig", feeQuoterABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameGetPremiumMultiplierWeiPerEth: { + ChainSpecificName: mustGetMethodName("getPremiumMultiplierWeiPerEth", feeQuoterABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameGetTokenTransferFeeConfig: { + ChainSpecificName: mustGetMethodName("getTokenTransferFeeConfig", feeQuoterABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameProcessMessageArgs: { + ChainSpecificName: mustGetMethodName("processMessageArgs", feeQuoterABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameProcessPoolReturnData: { + ChainSpecificName: mustGetMethodName("processPoolReturnData", feeQuoterABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameGetValidatedTokenPrice: { + ChainSpecificName: mustGetMethodName("getValidatedTokenPrice", feeQuoterABI), + ReadType: evmrelaytypes.Method, + }, + consts.MethodNameGetFeeTokens: { + ChainSpecificName: mustGetMethodName("getFeeTokens", feeQuoterABI), + ReadType: evmrelaytypes.Method, + }, + }, + }, }, } @@ -148,40 +202,19 @@ var SourceReaderConfig = evmrelaytypes.ChainReaderConfig{ }, }, }, - consts.ContractNamePriceRegistry: { - ContractABI: fee_quoter.FeeQuoterABI, + }, +} + +var FeedReaderConfig = evmrelaytypes.ChainReaderConfig{ + Contracts: map[string]evmrelaytypes.ChainContractReader{ + consts.ContractNamePriceAggregator: { + ContractABI: aggregator_v3_interface.AggregatorV3InterfaceABI, Configs: map[string]*evmrelaytypes.ChainReaderDefinition{ - consts.MethodNamePriceRegistryGetStaticConfig: { - ChainSpecificName: mustGetMethodName("getStaticConfig", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameGetDestChainConfig: { - ChainSpecificName: mustGetMethodName("getDestChainConfig", priceRegistryABI), - ReadType: evmrelaytypes.Method, + consts.MethodNameGetLatestRoundData: { + ChainSpecificName: mustGetMethodName(consts.MethodNameGetLatestRoundData, priceFeedABI), }, - consts.MethodNameGetPremiumMultiplierWeiPerEth: { - ChainSpecificName: mustGetMethodName("getPremiumMultiplierWeiPerEth", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameGetTokenTransferFeeConfig: { - ChainSpecificName: mustGetMethodName("getTokenTransferFeeConfig", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameProcessMessageArgs: { - ChainSpecificName: mustGetMethodName("processMessageArgs", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameProcessPoolReturnData: { - ChainSpecificName: mustGetMethodName("processPoolReturnData", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameGetValidatedTokenPrice: { - ChainSpecificName: mustGetMethodName("getValidatedTokenPrice", priceRegistryABI), - ReadType: evmrelaytypes.Method, - }, - consts.MethodNameGetFeeTokens: { - ChainSpecificName: mustGetMethodName("getFeeTokens", priceRegistryABI), - ReadType: evmrelaytypes.Method, + consts.MethodNameGetDecimals: { + ChainSpecificName: mustGetMethodName(consts.MethodNameGetDecimals, priceFeedABI), }, }, }, diff --git a/core/capabilities/ccip/oraclecreator/plugin.go b/core/capabilities/ccip/oraclecreator/plugin.go index 936b9c2552..9374f8fe9f 100644 --- a/core/capabilities/ccip/oraclecreator/plugin.go +++ b/core/capabilities/ccip/oraclecreator/plugin.go @@ -5,20 +5,19 @@ import ( "fmt" "time" - "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccipevm" - evmconfig "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/configs/evm" - "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ocrimpls" - cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/google/uuid" "github.com/prometheus/client_golang/prometheus" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-ccip/execute/tokendata" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccipevm" + evmconfig "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/configs/evm" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ocrimpls" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" - "github.com/smartcontractkit/chainlink-ccip/pkg/consts" - "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/libocr/commontypes" libocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus" @@ -29,11 +28,11 @@ import ( commitocr3 "github.com/smartcontractkit/chainlink-ccip/commit" execocr3 "github.com/smartcontractkit/chainlink-ccip/execute" - "github.com/smartcontractkit/chainlink-ccip/execute/tokendata" + "github.com/smartcontractkit/chainlink-ccip/pkg/consts" ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -125,24 +124,12 @@ func (i *pluginOracleCreator) Create(config cctypes.OCR3ConfigWithMeta) (cctypes if err != nil { return nil, fmt.Errorf("failed to get public config from OCR config: %w", err) } - var execBatchGasLimit uint64 - if pluginType == cctypes.PluginTypeCCIPExec { - execOffchainConfig, err2 := pluginconfig.DecodeExecuteOffchainConfig(publicConfig.ReportingPluginConfig) - if err2 != nil { - return nil, fmt.Errorf("failed to decode execute offchain config: %w, raw: %s", - err2, string(publicConfig.ReportingPluginConfig)) - } - if execOffchainConfig.BatchGasLimit == 0 && destChainFamily == relay.NetworkEVM { - return nil, fmt.Errorf("BatchGasLimit not set in execute offchain config, must be > 0") - } - execBatchGasLimit = execOffchainConfig.BatchGasLimit - } contractReaders, chainWriters, err := i.createReadersAndWriters( destChainID, pluginType, config, - execBatchGasLimit, + publicConfig, ) if err != nil { return nil, fmt.Errorf("failed to create readers and writers: %w", err) @@ -267,98 +254,217 @@ func (i *pluginOracleCreator) createReadersAndWriters( destChainID uint64, pluginType cctypes.PluginType, config cctypes.OCR3ConfigWithMeta, - execBatchGasLimit uint64, + publicCfg ocr3confighelper.PublicConfig, ) ( map[cciptypes.ChainSelector]types.ContractReader, map[cciptypes.ChainSelector]types.ChainWriter, error, ) { + ofc, err := decodeAndValidateOffchainConfig(pluginType, publicCfg) + if err != nil { + return nil, nil, err + } + + var execBatchGasLimit uint64 + if !ofc.execEmpty() { + execBatchGasLimit = ofc.exec().BatchGasLimit + } + contractReaders := make(map[cciptypes.ChainSelector]types.ContractReader) chainWriters := make(map[cciptypes.ChainSelector]types.ChainWriter) for _, chain := range i.chains.Slice() { - var chainReaderConfig evmrelaytypes.ChainReaderConfig - if chain.ID().Uint64() == destChainID { - chainReaderConfig = evmconfig.DestReaderConfig - } else { - chainReaderConfig = evmconfig.SourceReaderConfig + chainSelector, err1 := i.getChainSelector(chain.ID().Uint64()) + if err1 != nil { + return nil, nil, err1 } - cr, err2 := evm.NewChainReaderService( - context.Background(), - i.lggr. - Named("EVMChainReaderService"). - Named(chain.ID().String()). - Named(pluginType.String()), - chain.LogPoller(), - chain.HeadTracker(), - chain.Client(), - chainReaderConfig, - ) - if err2 != nil { - return nil, nil, fmt.Errorf("failed to create contract reader for chain %s: %w", chain.ID(), err2) + + chainReaderConfig := getChainReaderConfig(chain.ID().Uint64(), destChainID, ofc, chainSelector) + cr, err1 := createChainReader(i.lggr, chain, chainReaderConfig, pluginType) + if err1 != nil { + return nil, nil, err1 } - if chain.ID().Uint64() == destChainID { - // bind the chain reader to the dest chain's offramp. - offrampAddressHex := common.BytesToAddress(config.Config.OfframpAddress).Hex() - err3 := cr.Bind(context.Background(), []types.BoundContract{ - { - Address: offrampAddressHex, - Name: consts.ContractNameOffRamp, - }, - }) - if err3 != nil { - return nil, nil, fmt.Errorf("failed to bind chain reader for dest chain %s's offramp at %s: %w", chain.ID(), offrampAddressHex, err3) - } + if err2 := bindContracts(chain, cr, config, destChainID); err2 != nil { + return nil, nil, err2 } - // TODO: figure out shutdown. - // maybe from the plugin directly? - err2 = cr.Start(context.Background()) - if err2 != nil { - return nil, nil, fmt.Errorf("failed to start contract reader for chain %s: %w", chain.ID(), err2) + if err3 := cr.Start(context.Background()); err3 != nil { + return nil, nil, fmt.Errorf("failed to start contract reader for chain %s: %w", chain.ID(), err3) } - // Even though we only write to the dest chain, we need to create chain writers for all chains - // we know about in order to post gas prices on the dest. - var fromAddress common.Address - transmitter, ok := i.transmitters[types.NewRelayID(relay.NetworkEVM, chain.ID().String())] - if ok { - fromAddress = common.HexToAddress(transmitter[0]) + cw, err1 := createChainWriter(i.lggr, chain, pluginType, i.transmitters, execBatchGasLimit) + if err1 != nil { + return nil, nil, err1 } - cw, err2 := evm.NewChainWriterService( - i.lggr.Named("EVMChainWriterService"). - Named(chain.ID().String()). - Named(pluginType.String()), - chain.Client(), - chain.TxManager(), - chain.GasEstimator(), - evmconfig.ChainWriterConfigRaw( - fromAddress, - chain.Config().EVM().GasEstimator().PriceMaxKey(fromAddress), - defaultCommitGasLimit, - execBatchGasLimit, - ), - ) - if err2 != nil { - return nil, nil, fmt.Errorf("failed to create chain writer for chain %s: %w", chain.ID(), err2) + + if err4 := cw.Start(context.Background()); err4 != nil { + return nil, nil, fmt.Errorf("failed to start chain writer for chain %s: %w", chain.ID(), err4) } - // TODO: figure out shutdown. - // maybe from the plugin directly? - err2 = cw.Start(context.Background()) - if err2 != nil { - return nil, nil, fmt.Errorf("failed to start chain writer for chain %s: %w", chain.ID(), err2) + contractReaders[chainSelector] = cr + chainWriters[chainSelector] = cw + } + return contractReaders, chainWriters, nil +} + +func decodeAndValidateOffchainConfig( + pluginType cctypes.PluginType, + publicConfig ocr3confighelper.PublicConfig, +) (offChainConfig, error) { + var ofc offChainConfig + if pluginType == cctypes.PluginTypeCCIPExec { + execOffchainCfg, err1 := pluginconfig.DecodeExecuteOffchainConfig(publicConfig.ReportingPluginConfig) + if err1 != nil { + return offChainConfig{}, fmt.Errorf("failed to decode execute offchain config: %w, raw: %s", err1, string(publicConfig.ReportingPluginConfig)) + } + if err2 := execOffchainCfg.Validate(); err2 != nil { + return offChainConfig{}, fmt.Errorf("failed to validate execute offchain config: %w", err2) + } + ofc.execOffchainConfig = &execOffchainCfg + } else if pluginType == cctypes.PluginTypeCCIPCommit { + commitOffchainCfg, err1 := pluginconfig.DecodeCommitOffchainConfig(publicConfig.ReportingPluginConfig) + if err1 != nil { + return offChainConfig{}, fmt.Errorf("failed to decode commit offchain config: %w, raw: %s", err1, string(publicConfig.ReportingPluginConfig)) } + if err2 := commitOffchainCfg.Validate(); err2 != nil { + return offChainConfig{}, fmt.Errorf("failed to validate commit offchain config: %w", err2) + } + ofc.commitOffchainConfig = &commitOffchainCfg + } + if !ofc.isValid() { + return offChainConfig{}, fmt.Errorf("invalid offchain config: both commit and exec configs are either set or unset") + } + return ofc, nil +} + +func (i *pluginOracleCreator) getChainSelector(chainID uint64) (cciptypes.ChainSelector, error) { + chainSelector, ok := chainsel.EvmChainIdToChainSelector()[chainID] + if !ok { + return 0, fmt.Errorf("failed to get chain selector from chain ID %d", chainID) + } + return cciptypes.ChainSelector(chainSelector), nil +} - chainSelector, ok := chainsel.EvmChainIdToChainSelector()[chain.ID().Uint64()] - if !ok { - return nil, nil, fmt.Errorf("failed to get chain selector from chain ID %s", chain.ID()) +func getChainReaderConfig( + chainID uint64, + destChainID uint64, + ofc offChainConfig, + chainSelector cciptypes.ChainSelector, +) evmrelaytypes.ChainReaderConfig { + var chainReaderConfig evmrelaytypes.ChainReaderConfig + if chainID == destChainID { + chainReaderConfig = evmconfig.DestReaderConfig + } else { + chainReaderConfig = evmconfig.SourceReaderConfig + } + + if !ofc.commitEmpty() && ofc.commit().PriceFeedChainSelector == chainSelector { + chainReaderConfig = evmconfig.MergeReaderConfigs(chainReaderConfig, evmconfig.FeedReaderConfig) + } + return chainReaderConfig +} + +func createChainReader( + lggr logger.Logger, + chain legacyevm.Chain, + chainReaderConfig evmrelaytypes.ChainReaderConfig, + pluginType cctypes.PluginType, +) (types.ContractReader, error) { + cr, err := evm.NewChainReaderService( + context.Background(), + lggr. + Named("EVMChainReaderService"). + Named(chain.ID().String()). + Named(pluginType.String()), + chain.LogPoller(), + chain.HeadTracker(), + chain.Client(), + chainReaderConfig, + ) + if err != nil { + return nil, fmt.Errorf("failed to create contract reader for chain %s: %w", chain.ID(), err) + } + return cr, nil +} + +func bindContracts( + chain legacyevm.Chain, + cr types.ContractReader, + config cctypes.OCR3ConfigWithMeta, + destChainID uint64, +) error { + if chain.ID().Uint64() == destChainID { + offrampAddressHex := common.BytesToAddress(config.Config.OfframpAddress).Hex() + err := cr.Bind(context.Background(), []types.BoundContract{ + { + Address: offrampAddressHex, + Name: consts.ContractNameOffRamp, + }, + }) + if err != nil { + return fmt.Errorf("failed to bind chain reader for dest chain %s's offramp at %s: %w", chain.ID(), offrampAddressHex, err) } + } + return nil +} - contractReaders[cciptypes.ChainSelector(chainSelector)] = cr - chainWriters[cciptypes.ChainSelector(chainSelector)] = cw +func createChainWriter( + lggr logger.Logger, + chain legacyevm.Chain, + pluginType cctypes.PluginType, + transmitters map[types.RelayID][]string, + execBatchGasLimit uint64, +) (types.ChainWriter, error) { + var fromAddress common.Address + transmitter, ok := transmitters[types.NewRelayID(relay.NetworkEVM, chain.ID().String())] + if ok { + // TODO: remove EVM-specific stuff + fromAddress = common.HexToAddress(transmitter[0]) } - return contractReaders, chainWriters, nil + cw, err := evm.NewChainWriterService( + lggr.Named("EVMChainWriterService"). + Named(chain.ID().String()). + Named(pluginType.String()), + chain.Client(), + chain.TxManager(), + chain.GasEstimator(), + evmconfig.ChainWriterConfigRaw( + fromAddress, + chain.Config().EVM().GasEstimator().PriceMaxKey(fromAddress), + defaultCommitGasLimit, + execBatchGasLimit, + ), + ) + if err != nil { + return nil, fmt.Errorf("failed to create chain writer for chain %s: %w", chain.ID(), err) + } + return cw, nil +} + +type offChainConfig struct { + commitOffchainConfig *pluginconfig.CommitOffchainConfig + execOffchainConfig *pluginconfig.ExecuteOffchainConfig +} + +func (ofc offChainConfig) commitEmpty() bool { + return ofc.commitOffchainConfig == nil +} + +func (ofc offChainConfig) execEmpty() bool { + return ofc.execOffchainConfig == nil +} + +func (ofc offChainConfig) commit() *pluginconfig.CommitOffchainConfig { + return ofc.commitOffchainConfig +} + +func (ofc offChainConfig) exec() *pluginconfig.ExecuteOffchainConfig { + return ofc.execOffchainConfig +} + +// Exactly one of both plugins should be empty at any given time. +func (ofc offChainConfig) isValid() bool { + return (ofc.commitEmpty() && !ofc.execEmpty()) || (!ofc.commitEmpty() && ofc.execEmpty()) } func defaultLocalConfig() ocrtypes.LocalConfig { diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 738ff453a4..c68b2c5fa1 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -271,7 +271,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index aee7a44b26..5a94500963 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1081,8 +1081,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 h1:v5w6IqCX2p6pDuwmvaGv+kxvbhKgVmxnGZ63409tuj0= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 h1:cbHlV2CSphQ+ghDye21M8ym0aAO/Y649H2Mg60M2AuE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/go.mod b/go.mod index 6bc724ecd8..859f64551c 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc diff --git a/go.sum b/go.sum index b58bd4c9b7..1414f564a8 100644 --- a/go.sum +++ b/go.sum @@ -1042,8 +1042,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 h1:v5w6IqCX2p6pDuwmvaGv+kxvbhKgVmxnGZ63409tuj0= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 h1:cbHlV2CSphQ+ghDye21M8ym0aAO/Y649H2Mg60M2AuE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/integration-tests/deployment/ccip/deploy_home_chain.go b/integration-tests/deployment/ccip/deploy_home_chain.go index 6ff2c25d2a..94da977d6c 100644 --- a/integration-tests/deployment/ccip/deploy_home_chain.go +++ b/integration-tests/deployment/ccip/deploy_home_chain.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/common" confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink-ccip/chainconfig" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" @@ -34,6 +35,7 @@ const ( FirstBlockAge = 8 * time.Hour RemoteGasPriceBatchWriteFrequency = 30 * time.Minute + TokenPriceBatchWriteFrequency = 30 * time.Minute BatchGasLimit = 6_500_000 RelativeBoostPerWaitHour = 1.5 InflightCacheExpiry = 10 * time.Minute @@ -226,8 +228,12 @@ func BuildAddDONArgs( if pluginType == cctypes.PluginTypeCCIPCommit { encodedOffchainConfig, err2 = pluginconfig.EncodeCommitOffchainConfig(pluginconfig.CommitOffchainConfig{ RemoteGasPriceBatchWriteFrequency: *commonconfig.MustNewDuration(RemoteGasPriceBatchWriteFrequency), - // TODO: implement token price writes - // TokenPriceBatchWriteFrequency: *commonconfig.MustNewDuration(tokenPriceBatchWriteFrequency), + TokenPriceBatchWriteFrequency: *commonconfig.MustNewDuration(TokenPriceBatchWriteFrequency), + // TODO: Use a specific feed chain + // Use homechain as the feed chain to simplify testing + TokenInfo: map[ocrtypes.Account]pluginconfig.TokenInfo{ + //TODO: Add remote chain tokens as keys with their respective aggregate contract on feedChain + }, }) } else { encodedOffchainConfig, err2 = pluginconfig.EncodeExecuteOffchainConfig(pluginconfig.ExecuteOffchainConfig{ diff --git a/integration-tests/go.mod b/integration-tests/go.mod index d802c6eacc..d56146f95b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -38,7 +38,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240910151738-3f318badcfb5 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index a14ba3bacb..db4c6ed040 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1423,8 +1423,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 h1:v5w6IqCX2p6pDuwmvaGv+kxvbhKgVmxnGZ63409tuj0= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 h1:cbHlV2CSphQ+ghDye21M8ym0aAO/Y649H2Mg60M2AuE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 48017e4437..43a3acad69 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -384,7 +384,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 7bb8abfdb0..bf4ca8c6ba 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1397,8 +1397,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629 h1:v5w6IqCX2p6pDuwmvaGv+kxvbhKgVmxnGZ63409tuj0= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916105522-d6e26aedf629/go.mod h1:X1f4CKlR1RilSgzArQv5HNvMrVSt+Zloihm3REwxhdQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 h1:cbHlV2CSphQ+ghDye21M8ym0aAO/Y649H2Mg60M2AuE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/package.json b/package.json index 2e5bd3899a..89494370e0 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,6 @@ "devDependencies": { "@changesets/changelog-github": "^0.4.8", "@changesets/cli": "~2.26.2", - "semver": "^7.6.1" + "semver": "^7.6.3" } } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 95d247d993..260e6c79c0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,25 +15,25 @@ importers: specifier: ~2.26.2 version: 2.26.2 semver: - specifier: ^7.6.1 - version: 7.6.1 + specifier: ^7.6.3 + version: 7.6.3 packages: - '@babel/code-frame@7.23.5': - resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.22.20': - resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.23.4': - resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.23.9': - resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==} + '@babel/runtime@7.25.6': + resolution: {integrity: sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==} engines: {node: '>=6.9.0'} '@changesets/apply-release-plan@6.1.4': @@ -174,8 +174,8 @@ packages: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} breakword@1.0.6: @@ -248,6 +248,18 @@ packages: resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==} engines: {node: '>= 0.1.90'} + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} @@ -292,8 +304,8 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - es-abstract@1.22.4: - resolution: {integrity: sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==} + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} engines: {node: '>= 0.4'} es-define-property@1.0.0: @@ -304,6 +316,10 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + es-set-tostringtag@2.0.3: resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} engines: {node: '>= 0.4'} @@ -315,8 +331,8 @@ packages: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} escape-string-regexp@1.0.5: @@ -342,8 +358,8 @@ packages: fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} find-up@4.1.0: @@ -394,8 +410,8 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - globalthis@1.0.3: - resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} globby@11.1.0: @@ -441,8 +457,8 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hasown@2.0.1: - resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} hosted-git-info@2.8.9: @@ -455,8 +471,8 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} - ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} indent-string@4.0.0: @@ -489,8 +505,13 @@ packages: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} hasBin: true - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -619,8 +640,8 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} min-indent@1.0.1: @@ -647,8 +668,9 @@ packages: normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} - object-inspect@1.13.1: - resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} @@ -708,6 +730,9 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -724,8 +749,8 @@ packages: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} - preferred-pm@3.1.3: - resolution: {integrity: sha512-MkXsENfftWSRpzCzImcp4FRsCc3y1opwB73CfCNWyzMqArju2CrlMHlqB7VexKiPEOjGMbttv1r9fSCn5S610w==} + preferred-pm@3.1.4: + resolution: {integrity: sha512-lEHd+yEm22jXdCphDrkvIJQU66EuLojPPtvZkpKIkiD+l0DMThF/niqZKJSoU8Vl7iuvtmzyMhir9LdVy5WMnA==} engines: {node: '>=10'} prettier@2.8.8: @@ -788,8 +813,8 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - safe-array-concat@1.1.0: - resolution: {integrity: sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==} + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} engines: {node: '>=0.4'} safe-regex-test@1.0.3: @@ -803,16 +828,16 @@ packages: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true - semver@7.6.1: - resolution: {integrity: sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==} + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - set-function-length@1.2.1: - resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} set-function-name@2.0.2: @@ -827,8 +852,8 @@ packages: resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} engines: {node: '>=0.10.0'} - side-channel@1.0.5: - resolution: {integrity: sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==} + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} signal-exit@3.0.7: @@ -855,8 +880,8 @@ packages: spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-license-ids@3.0.17: - resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==} + spdx-license-ids@3.0.20: + resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -868,15 +893,16 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string.prototype.trim@1.2.8: - resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} engines: {node: '>= 0.4'} - string.prototype.trimend@1.0.7: - resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} - string.prototype.trimstart@1.0.7: - resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} @@ -950,8 +976,8 @@ packages: resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} engines: {node: '>= 0.4'} - typed-array-length@1.0.5: - resolution: {integrity: sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==} + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} engines: {node: '>= 0.4'} unbox-primitive@1.0.2: @@ -979,12 +1005,12 @@ packages: which-module@2.0.1: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} - which-pm@2.0.0: - resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==} + which-pm@2.2.0: + resolution: {integrity: sha512-MOiaDbA5ZZgUjkeMWM5EkJp4loW5ZRoa5bc3/aeMox/PJelMhE6t7S/mLuiY43DBupyxH+S0U1bTui9kWUlmsw==} engines: {node: '>=8.15'} - which-typed-array@1.1.14: - resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} which@1.3.1: @@ -1031,26 +1057,27 @@ packages: snapshots: - '@babel/code-frame@7.23.5': + '@babel/code-frame@7.24.7': dependencies: - '@babel/highlight': 7.23.4 - chalk: 2.4.2 + '@babel/highlight': 7.24.7 + picocolors: 1.1.0 - '@babel/helper-validator-identifier@7.22.20': {} + '@babel/helper-validator-identifier@7.24.7': {} - '@babel/highlight@7.23.4': + '@babel/highlight@7.24.7': dependencies: - '@babel/helper-validator-identifier': 7.22.20 + '@babel/helper-validator-identifier': 7.24.7 chalk: 2.4.2 js-tokens: 4.0.0 + picocolors: 1.1.0 - '@babel/runtime@7.23.9': + '@babel/runtime@7.25.6': dependencies: regenerator-runtime: 0.14.1 '@changesets/apply-release-plan@6.1.4': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.25.6 '@changesets/config': 2.3.1 '@changesets/get-version-range-type': 0.3.2 '@changesets/git': 2.0.0 @@ -1062,16 +1089,16 @@ snapshots: outdent: 0.5.0 prettier: 2.8.8 resolve-from: 5.0.0 - semver: 7.6.1 + semver: 7.6.3 '@changesets/assemble-release-plan@5.2.4': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.25.6 '@changesets/errors': 0.1.4 '@changesets/get-dependents-graph': 1.3.6 '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 - semver: 7.6.1 + semver: 7.6.3 '@changesets/changelog-git@0.1.14': dependencies: @@ -1087,7 +1114,7 @@ snapshots: '@changesets/cli@2.26.2': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.25.6 '@changesets/apply-release-plan': 6.1.4 '@changesets/assemble-release-plan': 5.2.4 '@changesets/changelog-git': 0.1.14 @@ -1114,9 +1141,9 @@ snapshots: meow: 6.1.1 outdent: 0.5.0 p-limit: 2.3.0 - preferred-pm: 3.1.3 + preferred-pm: 3.1.4 resolve-from: 5.0.0 - semver: 7.6.1 + semver: 7.6.3 spawndamnit: 2.0.0 term-size: 2.2.1 tty-table: 4.2.3 @@ -1129,7 +1156,7 @@ snapshots: '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - micromatch: 4.0.5 + micromatch: 4.0.8 '@changesets/errors@0.1.4': dependencies: @@ -1141,7 +1168,7 @@ snapshots: '@manypkg/get-packages': 1.1.3 chalk: 2.4.2 fs-extra: 7.0.1 - semver: 7.6.1 + semver: 7.6.3 '@changesets/get-github-info@0.5.2': dependencies: @@ -1152,7 +1179,7 @@ snapshots: '@changesets/get-release-plan@3.0.17': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.25.6 '@changesets/assemble-release-plan': 5.2.4 '@changesets/config': 2.3.1 '@changesets/pre': 1.0.14 @@ -1164,12 +1191,12 @@ snapshots: '@changesets/git@2.0.0': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.25.6 '@changesets/errors': 0.1.4 '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 is-subdir: 1.2.0 - micromatch: 4.0.5 + micromatch: 4.0.8 spawndamnit: 2.0.0 '@changesets/logger@0.0.5': @@ -1183,7 +1210,7 @@ snapshots: '@changesets/pre@1.0.14': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.25.6 '@changesets/errors': 0.1.4 '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 @@ -1191,7 +1218,7 @@ snapshots: '@changesets/read@0.5.9': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.25.6 '@changesets/git': 2.0.0 '@changesets/logger': 0.0.5 '@changesets/parse': 0.3.16 @@ -1206,7 +1233,7 @@ snapshots: '@changesets/write@0.2.3': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.25.6 '@changesets/types': 5.2.1 fs-extra: 7.0.1 human-id: 1.0.2 @@ -1214,14 +1241,14 @@ snapshots: '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.25.6 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 '@manypkg/get-packages@1.1.3': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.25.6 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -1279,7 +1306,7 @@ snapshots: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 arraybuffer.prototype.slice@1.0.3: @@ -1287,7 +1314,7 @@ snapshots: array-buffer-byte-length: 1.0.1 call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-abstract: 1.23.3 es-errors: 1.3.0 get-intrinsic: 1.2.4 is-array-buffer: 3.0.4 @@ -1303,9 +1330,9 @@ snapshots: dependencies: is-windows: 1.0.2 - braces@3.0.2: + braces@3.0.3: dependencies: - fill-range: 7.0.1 + fill-range: 7.1.1 breakword@1.0.6: dependencies: @@ -1317,7 +1344,7 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 get-intrinsic: 1.2.4 - set-function-length: 1.2.1 + set-function-length: 1.2.2 camelcase-keys@6.2.2: dependencies: @@ -1387,6 +1414,24 @@ snapshots: csv-stringify: 5.6.5 stream-transform: 2.1.3 + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dataloader@1.4.0: {} decamelize-keys@1.1.1: @@ -1431,49 +1476,54 @@ snapshots: dependencies: is-arrayish: 0.2.1 - es-abstract@1.22.4: + es-abstract@1.23.3: dependencies: array-buffer-byte-length: 1.0.1 arraybuffer.prototype.slice: 1.0.3 available-typed-arrays: 1.0.7 call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 es-define-property: 1.0.0 es-errors: 1.3.0 + es-object-atoms: 1.0.0 es-set-tostringtag: 2.0.3 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 get-intrinsic: 1.2.4 get-symbol-description: 1.0.2 - globalthis: 1.0.3 + globalthis: 1.0.4 gopd: 1.0.1 has-property-descriptors: 1.0.2 has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.1 + hasown: 2.0.2 internal-slot: 1.0.7 is-array-buffer: 3.0.4 is-callable: 1.2.7 + is-data-view: 1.0.1 is-negative-zero: 2.0.3 is-regex: 1.1.4 is-shared-array-buffer: 1.0.3 is-string: 1.0.7 is-typed-array: 1.1.13 is-weakref: 1.0.2 - object-inspect: 1.13.1 + object-inspect: 1.13.2 object-keys: 1.1.1 object.assign: 4.1.5 regexp.prototype.flags: 1.5.2 - safe-array-concat: 1.1.0 + safe-array-concat: 1.1.2 safe-regex-test: 1.0.3 - string.prototype.trim: 1.2.8 - string.prototype.trimend: 1.0.7 - string.prototype.trimstart: 1.0.7 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 typed-array-buffer: 1.0.2 typed-array-byte-length: 1.0.1 typed-array-byte-offset: 1.0.2 - typed-array-length: 1.0.5 + typed-array-length: 1.0.6 unbox-primitive: 1.0.2 - which-typed-array: 1.1.14 + which-typed-array: 1.1.15 es-define-property@1.0.0: dependencies: @@ -1481,15 +1531,19 @@ snapshots: es-errors@1.3.0: {} + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + es-set-tostringtag@2.0.3: dependencies: get-intrinsic: 1.2.4 has-tostringtag: 1.0.2 - hasown: 2.0.1 + hasown: 2.0.2 es-shim-unscopables@1.0.2: dependencies: - hasown: 2.0.1 + hasown: 2.0.2 es-to-primitive@1.2.1: dependencies: @@ -1497,7 +1551,7 @@ snapshots: is-date-object: 1.0.5 is-symbol: 1.0.4 - escalade@3.1.2: {} + escalade@3.2.0: {} escape-string-regexp@1.0.5: {} @@ -1517,13 +1571,13 @@ snapshots: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.5 + micromatch: 4.0.8 fastq@1.17.1: dependencies: reusify: 1.0.4 - fill-range@7.0.1: + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -1539,7 +1593,7 @@ snapshots: find-yarn-workspace-root2@1.2.16: dependencies: - micromatch: 4.0.5 + micromatch: 4.0.8 pkg-dir: 4.2.0 for-each@0.3.3: @@ -1564,7 +1618,7 @@ snapshots: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-abstract: 1.23.3 functions-have-names: 1.2.3 functions-have-names@1.2.3: {} @@ -1577,7 +1631,7 @@ snapshots: function-bind: 1.1.2 has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.1 + hasown: 2.0.2 get-symbol-description@1.0.2: dependencies: @@ -1589,16 +1643,17 @@ snapshots: dependencies: is-glob: 4.0.3 - globalthis@1.0.3: + globalthis@1.0.4: dependencies: define-properties: 1.2.1 + gopd: 1.0.1 globby@11.1.0: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.3.2 - ignore: 5.3.1 + ignore: 5.3.2 merge2: 1.4.1 slash: 3.0.0 @@ -1630,7 +1685,7 @@ snapshots: dependencies: has-symbols: 1.0.3 - hasown@2.0.1: + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -1642,15 +1697,15 @@ snapshots: dependencies: safer-buffer: 2.1.2 - ignore@5.3.1: {} + ignore@5.3.2: {} indent-string@4.0.0: {} internal-slot@1.0.7: dependencies: es-errors: 1.3.0 - hasown: 2.0.1 - side-channel: 1.0.5 + hasown: 2.0.2 + side-channel: 1.0.6 is-array-buffer@3.0.4: dependencies: @@ -1674,9 +1729,13 @@ snapshots: dependencies: ci-info: 3.9.0 - is-core-module@2.13.1: + is-core-module@2.15.1: dependencies: - hasown: 2.0.1 + hasown: 2.0.2 + + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 is-date-object@1.0.5: dependencies: @@ -1723,7 +1782,7 @@ snapshots: is-typed-array@1.1.13: dependencies: - which-typed-array: 1.1.14 + which-typed-array: 1.1.15 is-weakref@1.0.2: dependencies: @@ -1796,9 +1855,9 @@ snapshots: merge2@1.4.1: {} - micromatch@4.0.5: + micromatch@4.0.8: dependencies: - braces: 3.0.2 + braces: 3.0.3 picomatch: 2.3.1 min-indent@1.0.1: {} @@ -1822,7 +1881,7 @@ snapshots: semver: 5.7.2 validate-npm-package-license: 3.0.4 - object-inspect@1.13.1: {} + object-inspect@1.13.2: {} object-keys@1.1.1: {} @@ -1863,7 +1922,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.24.7 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -1874,6 +1933,8 @@ snapshots: path-type@4.0.0: {} + picocolors@1.1.0: {} + picomatch@2.3.1: {} pify@4.0.1: {} @@ -1884,12 +1945,12 @@ snapshots: possible-typed-array-names@1.0.0: {} - preferred-pm@3.1.3: + preferred-pm@3.1.4: dependencies: find-up: 5.0.0 find-yarn-workspace-root2: 1.2.16 path-exists: 4.0.0 - which-pm: 2.0.0 + which-pm: 2.2.0 prettier@2.8.8: {} @@ -1941,7 +2002,7 @@ snapshots: resolve@1.22.8: dependencies: - is-core-module: 2.13.1 + is-core-module: 2.15.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -1951,7 +2012,7 @@ snapshots: dependencies: queue-microtask: 1.2.3 - safe-array-concat@1.1.0: + safe-array-concat@1.1.2: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 @@ -1968,11 +2029,11 @@ snapshots: semver@5.7.2: {} - semver@7.6.1: {} + semver@7.6.3: {} set-blocking@2.0.0: {} - set-function-length@1.2.1: + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 @@ -1994,12 +2055,12 @@ snapshots: shebang-regex@1.0.0: {} - side-channel@1.0.5: + side-channel@1.0.6: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 get-intrinsic: 1.2.4 - object-inspect: 1.13.1 + object-inspect: 1.13.2 signal-exit@3.0.7: {} @@ -2022,16 +2083,16 @@ snapshots: spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.17 + spdx-license-ids: 3.0.20 spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.17 + spdx-license-ids: 3.0.20 - spdx-license-ids@3.0.17: {} + spdx-license-ids@3.0.20: {} sprintf-js@1.0.3: {} @@ -2045,23 +2106,24 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string.prototype.trim@1.2.8: + string.prototype.trim@1.2.9: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 - string.prototype.trimend@1.0.7: + string.prototype.trimend@1.0.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-object-atoms: 1.0.0 - string.prototype.trimstart@1.0.7: + string.prototype.trimstart@1.0.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.4 + es-object-atoms: 1.0.0 strip-ansi@6.0.1: dependencies: @@ -2136,7 +2198,7 @@ snapshots: has-proto: 1.0.3 is-typed-array: 1.1.13 - typed-array-length@1.0.5: + typed-array-length@1.0.6: dependencies: call-bind: 1.0.7 for-each: 0.3.3 @@ -2180,12 +2242,12 @@ snapshots: which-module@2.0.1: {} - which-pm@2.0.0: + which-pm@2.2.0: dependencies: load-yaml-file: 0.2.0 path-exists: 4.0.0 - which-typed-array@1.1.14: + which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.7 @@ -2239,7 +2301,7 @@ snapshots: yargs@17.7.2: dependencies: cliui: 8.0.1 - escalade: 3.1.2 + escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 From d14a9b5111baaffa95266b0d39ea21f6ecfd0137 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Mon, 16 Sep 2024 22:10:51 +0200 Subject: [PATCH 357/432] exclude sourcegraph missing dependency (#14446) * exclude sourcegrapht * use replace --- core/scripts/go.mod | 2 ++ dashboard-lib/go.mod | 2 ++ go.mod | 2 ++ integration-tests/go.mod | 2 ++ integration-tests/load/go.mod | 2 ++ 5 files changed, 10 insertions(+) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index c68b2c5fa1..4b11f323a5 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -379,3 +379,5 @@ replace ( // replicating the replace directive on cosmos SDK github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 ) + +replace github.com/sourcegraph/sourcegraph/lib => github.com/sourcegraph/sourcegraph-public-snapshot/lib v0.0.0-20240822153003-c864f15af264 diff --git a/dashboard-lib/go.mod b/dashboard-lib/go.mod index 10270853ed..8e68d3c620 100644 --- a/dashboard-lib/go.mod +++ b/dashboard-lib/go.mod @@ -23,3 +23,5 @@ require ( github.com/stretchr/testify v1.9.0 // indirect golang.org/x/sys v0.16.0 // indirect ) + +replace github.com/sourcegraph/sourcegraph/lib => github.com/sourcegraph/sourcegraph-public-snapshot/lib v0.0.0-20240822153003-c864f15af264 diff --git a/go.mod b/go.mod index 859f64551c..e900c0ebcc 100644 --- a/go.mod +++ b/go.mod @@ -368,3 +368,5 @@ replace ( // replicating the replace directive on cosmos SDK github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 ) + +replace github.com/sourcegraph/sourcegraph/lib => github.com/sourcegraph/sourcegraph-public-snapshot/lib v0.0.0-20240822153003-c864f15af264 diff --git a/integration-tests/go.mod b/integration-tests/go.mod index d56146f95b..40c8964c03 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -538,3 +538,5 @@ replace ( github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.14.0 github.com/prometheus/common => github.com/prometheus/common v0.42.0 ) + +replace github.com/sourcegraph/sourcegraph/lib => github.com/sourcegraph/sourcegraph-public-snapshot/lib v0.0.0-20240822153003-c864f15af264 diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 43a3acad69..00c6453814 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -571,3 +571,5 @@ replace ( k8s.io/sample-controller => k8s.io/sample-controller v0.28.2 sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.16.2 ) + +replace github.com/sourcegraph/sourcegraph/lib => github.com/sourcegraph/sourcegraph-public-snapshot/lib v0.0.0-20240822153003-c864f15af264 From 3c5bdf8d4b2244b3826ab54a56ec172bb9a8459c Mon Sep 17 00:00:00 2001 From: dimitris Date: Tue, 17 Sep 2024 14:57:28 +0300 Subject: [PATCH 358/432] ccip - EVM Implementation of RMNCrypto interface (#14416) * upgrade cl-common to RMNCrypto iface branch * implement RMN crypto evm ecdsa sig verifier * personal code review * no panics * changeset * add comment * fix linter errs * makramkd code review fixes * goimports --- .changeset/curvy-boxes-burn.md | 5 + core/capabilities/ccip/ccipevm/helpers.go | 12 ++ core/capabilities/ccip/ccipevm/msghasher.go | 10 +- core/capabilities/ccip/ccipevm/rmncrypto.go | 184 ++++++++++++++++++ .../ccip/ccipevm/rmncrypto_test.go | 68 +++++++ 5 files changed, 274 insertions(+), 5 deletions(-) create mode 100644 .changeset/curvy-boxes-burn.md create mode 100644 core/capabilities/ccip/ccipevm/rmncrypto.go create mode 100644 core/capabilities/ccip/ccipevm/rmncrypto_test.go diff --git a/.changeset/curvy-boxes-burn.md b/.changeset/curvy-boxes-burn.md new file mode 100644 index 0000000000..8a189c5f5d --- /dev/null +++ b/.changeset/curvy-boxes-burn.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +RMNCrypto evm implementation for CCIP - RMN Integration #added diff --git a/core/capabilities/ccip/ccipevm/helpers.go b/core/capabilities/ccip/ccipevm/helpers.go index ee83230a4c..4cfd64b7c6 100644 --- a/core/capabilities/ccip/ccipevm/helpers.go +++ b/core/capabilities/ccip/ccipevm/helpers.go @@ -4,6 +4,8 @@ import ( "bytes" "fmt" "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" ) func decodeExtraArgsV1V2(extraArgs []byte) (gasLimit *big.Int, err error) { @@ -31,3 +33,13 @@ func decodeExtraArgsV1V2(extraArgs []byte) (gasLimit *big.Int, err error) { } return ifaces[0].(*big.Int), nil } + +// abiEncodeMethodInputs encodes the inputs for a method call. +// example abi: `[{ "name" : "method", "type": "function", "inputs": [{"name": "a", "type": "uint256"}]}]` +func abiEncodeMethodInputs(abiDef abi.ABI, inputs ...interface{}) ([]byte, error) { + packed, err := abiDef.Pack("method", inputs...) + if err != nil { + return nil, err + } + return packed[4:], nil // remove the method selector +} diff --git a/core/capabilities/ccip/ccipevm/msghasher.go b/core/capabilities/ccip/ccipevm/msghasher.go index e620d96a43..cf37a28b00 100644 --- a/core/capabilities/ccip/ccipevm/msghasher.go +++ b/core/capabilities/ccip/ccipevm/msghasher.go @@ -61,12 +61,12 @@ func (h *MessageHasherV1) Hash(_ context.Context, msg cciptypes.Message) (ccipty Amount: rta.Amount.Int, }) } - encodedRampTokenAmounts, err := abiEncode("encodeTokenAmountsHashPreimage", rampTokenAmounts) + encodedRampTokenAmounts, err := h.abiEncode("encodeTokenAmountsHashPreimage", rampTokenAmounts) if err != nil { return [32]byte{}, fmt.Errorf("abi encode token amounts: %w", err) } - metaDataHashInput, err := abiEncode( + metaDataHashInput, err := h.abiEncode( "encodeMetadataHashPreimage", ANY_2_EVM_MESSAGE_HASH, uint64(msg.Header.SourceChainSelector), @@ -86,7 +86,7 @@ func (h *MessageHasherV1) Hash(_ context.Context, msg cciptypes.Message) (ccipty return [32]byte{}, fmt.Errorf("decode extra args: %w", err) } - fixedSizeFieldsEncoded, err := abiEncode( + fixedSizeFieldsEncoded, err := h.abiEncode( "encodeFixedSizeFieldsHashPreimage", msg.Header.MessageID, []byte(msg.Sender), @@ -99,7 +99,7 @@ func (h *MessageHasherV1) Hash(_ context.Context, msg cciptypes.Message) (ccipty return [32]byte{}, fmt.Errorf("abi encode fixed size values: %w", err) } - packedValues, err := abiEncode( + packedValues, err := h.abiEncode( "encodeFinalHashPreimage", leafDomainSeparator, utils.Keccak256Fixed(metaDataHashInput), @@ -114,7 +114,7 @@ func (h *MessageHasherV1) Hash(_ context.Context, msg cciptypes.Message) (ccipty return utils.Keccak256Fixed(packedValues), nil } -func abiEncode(method string, values ...interface{}) ([]byte, error) { +func (h *MessageHasherV1) abiEncode(method string, values ...interface{}) ([]byte, error) { res, err := messageHasherABI.Pack(method, values...) if err != nil { return nil, err diff --git a/core/capabilities/ccip/ccipevm/rmncrypto.go b/core/capabilities/ccip/ccipevm/rmncrypto.go new file mode 100644 index 0000000000..794a466524 --- /dev/null +++ b/core/capabilities/ccip/ccipevm/rmncrypto.go @@ -0,0 +1,184 @@ +package ccipevm + +import ( + "bytes" + "context" + "errors" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" +) + +// encodingUtilsAbi is the ABI for the EncodingUtils contract. +// Should be imported when gethwrappers are moved from ccip repo to core. +// nolint:lll +const encodingUtilsAbiRaw = `[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DoNotDeploy","type":"error"},{"inputs":[{"internalType":"bytes32","name":"rmnReportVersion","type":"bytes32"},{"components":[{"internalType":"uint256","name":"destChainId","type":"uint256"},{"internalType":"uint64","name":"destChainSelector","type":"uint64"},{"internalType":"address","name":"rmnRemoteContractAddress","type":"address"},{"internalType":"address","name":"offrampAddress","type":"address"},{"internalType":"bytes32","name":"rmnHomeContractConfigDigest","type":"bytes32"},{"components":[{"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"internalType":"bytes","name":"onRampAddress","type":"bytes"},{"internalType":"uint64","name":"minSeqNr","type":"uint64"},{"internalType":"uint64","name":"maxSeqNr","type":"uint64"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"internalType":"struct Internal.MerkleRoot[]","name":"destLaneUpdates","type":"tuple[]"}],"internalType":"struct RMNRemote.Report","name":"rmnReport","type":"tuple"}],"name":"_rmnReport","outputs":[],"stateMutability":"nonpayable","type":"function"}]` +const addressEncodeAbiRaw = `[{"name":"method","type":"function","inputs":[{"name": "", "type": "address"}]}]` + +var ( + encodingUtilsABI abi.ABI + addressEncodeABI abi.ABI +) + +func init() { + var err error + + encodingUtilsABI, err = abi.JSON(strings.NewReader(encodingUtilsAbiRaw)) + if err != nil { + panic(fmt.Errorf("failed to parse encoding utils ABI: %v", err)) + } + + addressEncodeABI, err = abi.JSON(strings.NewReader(addressEncodeAbiRaw)) + if err != nil { + panic(fmt.Errorf("failed to parse address encode ABI: %v", err)) + } +} + +const ( + // v is the recovery ID for ECDSA signatures. This implementation assumes that v is always 27. + v = 27 +) + +// EVMRMNCrypto is the RMNCrypto implementation for EVM chains. +type EVMRMNCrypto struct{} + +// Interface compliance check +var _ cciptypes.RMNCrypto = (*EVMRMNCrypto)(nil) + +func NewEVMRMNCrypto() *EVMRMNCrypto { + return &EVMRMNCrypto{} +} + +// Should be replaced by gethwrapper types when they're available +type evmRMNRemoteReport struct { + DestChainID *big.Int `abi:"destChainId"` + DestChainSelector uint64 + RmnRemoteContractAddress common.Address + OfframpAddress common.Address + RmnHomeContractConfigDigest [32]byte + DestLaneUpdates []evmInternalMerkleRoot +} + +type evmInternalMerkleRoot struct { + SourceChainSelector uint64 + OnRampAddress []byte + MinSeqNr uint64 + MaxSeqNr uint64 + MerkleRoot [32]byte +} + +func (r *EVMRMNCrypto) VerifyReportSignatures( + _ context.Context, + sigs []cciptypes.RMNECDSASignature, + report cciptypes.RMNReport, + signerAddresses []cciptypes.Bytes, +) error { + if sigs == nil { + return fmt.Errorf("no signatures provided") + } + if report.LaneUpdates == nil { + return fmt.Errorf("no lane updates provided") + } + + rmnVersionHash := crypto.Keccak256Hash([]byte(report.ReportVersion)) + + evmLaneUpdates := make([]evmInternalMerkleRoot, len(report.LaneUpdates)) + for i, lu := range report.LaneUpdates { + onRampAddress := common.BytesToAddress(lu.OnRampAddress) + onRampAddrAbi, err := abiEncodeMethodInputs(addressEncodeABI, onRampAddress) + if err != nil { + return fmt.Errorf("ΑΒΙ encode onRampAddress: %w", err) + } + evmLaneUpdates[i] = evmInternalMerkleRoot{ + SourceChainSelector: uint64(lu.SourceChainSelector), + OnRampAddress: onRampAddrAbi, + MinSeqNr: uint64(lu.MinSeqNr), + MaxSeqNr: uint64(lu.MaxSeqNr), + MerkleRoot: lu.MerkleRoot, + } + } + + evmReport := evmRMNRemoteReport{ + DestChainID: report.DestChainID.Int, + DestChainSelector: uint64(report.DestChainSelector), + RmnRemoteContractAddress: common.HexToAddress(report.RmnRemoteContractAddress.String()), + OfframpAddress: common.HexToAddress(report.OfframpAddress.String()), + RmnHomeContractConfigDigest: report.RmnHomeContractConfigDigest, + DestLaneUpdates: evmLaneUpdates, + } + + abiEnc, err := encodingUtilsABI.Methods["_rmnReport"].Inputs.Pack(rmnVersionHash, evmReport) + if err != nil { + return fmt.Errorf("failed to ABI encode args: %w", err) + } + + signedHash := crypto.Keccak256Hash(abiEnc) + + // keep track of the previous signer for validating signers ordering + prevSignerAddr := common.Address{} + + for _, sig := range sigs { + recoveredAddress, err := recoverAddressFromSig( + v, + sig.R, + sig.S, + signedHash[:], + ) + if err != nil { + return fmt.Errorf("failed to recover public key from signature: %w", err) + } + + // make sure that signers are ordered correctly (ASC addresses). + if bytes.Compare(prevSignerAddr.Bytes(), recoveredAddress.Bytes()) == 1 { + return fmt.Errorf("signers are not ordered correctly") + } + prevSignerAddr = recoveredAddress + + // Check if the public key is in the list of the provided RMN nodes + found := false + for _, signerAddr := range signerAddresses { + signerAddrEvm := common.BytesToAddress(signerAddr) + if signerAddrEvm == recoveredAddress { + found = true + break + } + } + if !found { + return fmt.Errorf("the recovered public key does not match any signer address, verification failed") + } + } + + return nil +} + +// recoverAddressFromSig Recovers a public address from an ECDSA signature using r, s, v, and the hash of the message. +func recoverAddressFromSig(v int, r, s [32]byte, hash []byte) (common.Address, error) { + // Ensure v is either 27 or 28 (as used in Ethereum) + if v != 27 && v != 28 { + return common.Address{}, errors.New("v must be 27 or 28") + } + + // Construct the signature by concatenating r, s, and the recovery ID (v - 27 to convert to 0/1) + sig := append(r[:], s[:]...) + sig = append(sig, byte(v-27)) + + // Recover the public key bytes from the signature and message hash + pubKeyBytes, err := crypto.Ecrecover(hash, sig) + if err != nil { + return common.Address{}, fmt.Errorf("failed to recover public key: %v", err) + } + + // Convert the recovered public key to an ECDSA public key + pubKey, err := crypto.UnmarshalPubkey(pubKeyBytes) + if err != nil { + return common.Address{}, fmt.Errorf("failed to unmarshal public key: %v", err) + } // or SigToPub + + return crypto.PubkeyToAddress(*pubKey), nil +} diff --git a/core/capabilities/ccip/ccipevm/rmncrypto_test.go b/core/capabilities/ccip/ccipevm/rmncrypto_test.go new file mode 100644 index 0000000000..e12b20ab30 --- /dev/null +++ b/core/capabilities/ccip/ccipevm/rmncrypto_test.go @@ -0,0 +1,68 @@ +package ccipevm + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_VerifyRmnReportSignatures(t *testing.T) { + // NOTE: The following test data (public keys, signatures, ...) are shared from the RMN team. + + onchainRmnRemoteAddr := common.HexToAddress("0x7821bcd6944457d17c631157efeb0c621baa76eb") + + rmnHomeContractConfigDigestHex := "0x785936570d1c7422ef30b7da5555ad2f175fa2dd97a2429a2e71d1e07c94e060" + rmnHomeContractConfigDigest := common.FromHex(rmnHomeContractConfigDigestHex) + require.Len(t, rmnHomeContractConfigDigest, 32) + var rmnHomeContractConfigDigest32 [32]byte + copy(rmnHomeContractConfigDigest32[:], rmnHomeContractConfigDigest) + + rootHex := "0x48e688aefc20a04fdec6b8ff19df358fd532455659dcf529797cda358e9e5205" + root := common.FromHex(rootHex) + require.Len(t, root, 32) + var root32 [32]byte + copy(root32[:], root) + + onRampAddr := common.HexToAddress("0x6662cb20464f4be557262693bea0409f068397ed") + + destChainEvmID := int64(4083663998511321420) + + reportData := cciptypes.RMNReport{ + ReportVersion: "RMN_V1_6_ANY2EVM_REPORT", + DestChainID: cciptypes.NewBigIntFromInt64(destChainEvmID), + DestChainSelector: 5266174733271469989, + RmnRemoteContractAddress: common.HexToAddress("0x3d015cec4411357eff4ea5f009a581cc519f75d3").Bytes(), + OfframpAddress: common.HexToAddress("0xc5cdb7711a478058023373b8ae9e7421925140f8").Bytes(), + RmnHomeContractConfigDigest: rmnHomeContractConfigDigest32, + LaneUpdates: []cciptypes.RMNLaneUpdate{ + { + SourceChainSelector: 8258882951688608272, + OnRampAddress: onRampAddr.Bytes(), + MinSeqNr: 9018980618932210108, + MaxSeqNr: 8239368306600774074, + MerkleRoot: root32, + }, + }, + } + + ctx := tests.Context(t) + + rmnCrypto := NewEVMRMNCrypto() + + r, _ := cciptypes.NewBytes32FromString("0x89546b4652d0377062a398e413344e4da6034ae877c437d0efe0e5246b70a9a1") + s, _ := cciptypes.NewBytes32FromString("0x95eef2d24d856ccac3886db8f4aebea60684ed73942392692908fed79a679b4e") + + err := rmnCrypto.VerifyReportSignatures( + ctx, + []cciptypes.RMNECDSASignature{{R: r, S: s}}, + reportData, + []cciptypes.Bytes{onchainRmnRemoteAddr.Bytes()}, + ) + assert.NoError(t, err) +} From 37c5a2ff29ad1fe661547777e60a077430530be9 Mon Sep 17 00:00:00 2001 From: karen-stepanyan <91897037+karen-stepanyan@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:11:55 +0400 Subject: [PATCH 359/432] Added check to not fetch mercury prices when trigger capability is enabled (#13888) * add check to not fetch mercury prices when trigger capability is enabled * changeset * fix lint issues * address PR comments * Ensure pluginConfig can be omitted for keystone Streams jobs * Add capability flag check for Mercury V2 jobs * Update V2 spec tests * Linting fixes * Remove changes for Mercury v2 schema * Update linkFeedId and nativeFeedId checks without enableTriggerCapability * Update .changeset/wise-bears-end.md * Remove inaccurate comments * Add PluginConfig!=nil check to Mercury v2 schema * Linting fix * Update mercury v2 tests * Set price feeds to -1 if plugin config is nil * Add base pluginConfig to test_dataSource files --------- Co-authored-by: Austin Born --- .changeset/wise-bears-end.md | 5 +++ core/services/job/validate_test.go | 0 core/services/ocr2/plugins/mercury/plugin.go | 26 ++++++++++++---- core/services/ocr2/validate/validate.go | 23 +++++++++++--- .../relay/evm/mercury/v2/data_source.go | 16 ++++++++-- .../relay/evm/mercury/v2/data_source_test.go | 31 ++++++++++++++++++- .../relay/evm/mercury/v3/data_source.go | 16 ++++++++-- .../relay/evm/mercury/v3/data_source_test.go | 29 +++++++++++++++-- 8 files changed, 127 insertions(+), 19 deletions(-) create mode 100644 .changeset/wise-bears-end.md mode change 100644 => 100755 core/services/job/validate_test.go diff --git a/.changeset/wise-bears-end.md b/.changeset/wise-bears-end.md new file mode 100644 index 0000000000..30d10055da --- /dev/null +++ b/.changeset/wise-bears-end.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#updated mercury plugin to consider PluginConfig as optional if EnableTriggerCapability relay config is true. Then if PluginConfig is nil, skip fetching latestPrice for linkFeedId and nativeFeedId. diff --git a/core/services/job/validate_test.go b/core/services/job/validate_test.go old mode 100644 new mode 100755 diff --git a/core/services/ocr2/plugins/mercury/plugin.go b/core/services/ocr2/plugins/mercury/plugin.go index 0898c1821e..13793570de 100644 --- a/core/services/ocr2/plugins/mercury/plugin.go +++ b/core/services/ocr2/plugins/mercury/plugin.go @@ -31,6 +31,7 @@ import ( mercuryv2 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2" mercuryv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3" mercuryv4 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v4" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/plugins" ) @@ -78,15 +79,28 @@ func NewServices( return nil, errors.New("expected job to have a non-nil PipelineSpec") } - var pluginConfig config.PluginConfig - err := json.Unmarshal(jb.OCR2OracleSpec.PluginConfig.Bytes(), &pluginConfig) + var relayConfig evmtypes.RelayConfig + err := json.Unmarshal(jb.OCR2OracleSpec.RelayConfig.Bytes(), &relayConfig) if err != nil { - return nil, errors.WithStack(err) + return nil, fmt.Errorf("error while unmarshalling relay config: %w", err) } - err = config.ValidatePluginConfig(pluginConfig, feedID) - if err != nil { - return nil, err + + var pluginConfig config.PluginConfig + if jb.OCR2OracleSpec.PluginConfig == nil { + if !relayConfig.EnableTriggerCapability { + return nil, fmt.Errorf("at least one transmission option must be configured") + } + } else { + err = json.Unmarshal(jb.OCR2OracleSpec.PluginConfig.Bytes(), &pluginConfig) + if err != nil { + return nil, errors.WithStack(err) + } + err = config.ValidatePluginConfig(pluginConfig, feedID) + if err != nil { + return nil, err + } } + lggr = lggr.Named("MercuryPlugin").With("jobID", jb.ID, "jobName", jb.Name.ValueOrZero()) // encapsulate all the subservices and ensure we close them all if any fail to start diff --git a/core/services/ocr2/validate/validate.go b/core/services/ocr2/validate/validate.go index a224249e1e..09b974d4e3 100644 --- a/core/services/ocr2/validate/validate.go +++ b/core/services/ocr2/validate/validate.go @@ -26,6 +26,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/relay" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/plugins" ) @@ -84,7 +85,6 @@ var ( "relay": {}, "relayConfig": {}, "pluginType": {}, - "pluginConfig": {}, } notExpectedParams = map[string]struct{}{ "isBootstrapPeer": {}, @@ -117,7 +117,7 @@ func validateSpec(ctx context.Context, tree *toml.Tree, spec job.Job, rc plugins // TODO validator for DR-OCR spec: https://smartcontract-it.atlassian.net/browse/FUN-112 return nil case types.Mercury: - return validateOCR2MercurySpec(spec.OCR2OracleSpec.PluginConfig, *spec.OCR2OracleSpec.FeedID) + return validateOCR2MercurySpec(spec.OCR2OracleSpec, *spec.OCR2OracleSpec.FeedID) case types.CCIPExecution: return validateOCR2CCIPExecutionSpec(spec.OCR2OracleSpec.PluginConfig) case types.CCIPCommit: @@ -297,13 +297,26 @@ func validateOCR2KeeperSpec(jsonConfig job.JSONConfig) error { return nil } -func validateOCR2MercurySpec(jsonConfig job.JSONConfig, feedId [32]byte) error { +func validateOCR2MercurySpec(spec *job.OCR2OracleSpec, feedID [32]byte) error { + var relayConfig evmtypes.RelayConfig + err := json.Unmarshal(spec.RelayConfig.Bytes(), &relayConfig) + if err != nil { + return pkgerrors.Wrap(err, "error while unmarshalling relay config") + } + + if spec.PluginConfig == nil { + if !relayConfig.EnableTriggerCapability { + return pkgerrors.Wrap(err, "at least one transmission option must be configured") + } + return nil + } + var pluginConfig mercuryconfig.PluginConfig - err := json.Unmarshal(jsonConfig.Bytes(), &pluginConfig) + err = json.Unmarshal(spec.PluginConfig.Bytes(), &pluginConfig) if err != nil { return pkgerrors.Wrap(err, "error while unmarshalling plugin config") } - return pkgerrors.Wrap(mercuryconfig.ValidatePluginConfig(pluginConfig, feedId), "Mercury PluginConfig is invalid") + return pkgerrors.Wrap(mercuryconfig.ValidatePluginConfig(pluginConfig, feedID), "Mercury PluginConfig is invalid") } func validateOCR2CCIPExecutionSpec(jsonConfig job.JSONConfig) error { diff --git a/core/services/relay/evm/mercury/v2/data_source.go b/core/services/relay/evm/mercury/v2/data_source.go index 28487ec714..d05bd00e25 100644 --- a/core/services/relay/evm/mercury/v2/data_source.go +++ b/core/services/relay/evm/mercury/v2/data_source.go @@ -2,6 +2,7 @@ package v2 import ( "context" + "encoding/json" "fmt" "math/big" "sync" @@ -22,6 +23,7 @@ import ( mercurytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types" mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/reportcodec" + relayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -61,6 +63,12 @@ func NewDataSource(orm types.DataSourceORM, pr pipeline.Runner, jb job.Job, spec func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp, fetchMaxFinalizedTimestamp bool) (obs v2types.Observation, pipelineExecutionErr error) { var wg sync.WaitGroup + var relayConfig relayTypes.RelayConfig + err := json.Unmarshal(ds.jb.OCR2OracleSpec.RelayConfig.Bytes(), &relayConfig) + if err != nil { + pipelineExecutionErr = fmt.Errorf("failed to deserialize relay config: %w", err) + return + } ctx, cancel := context.WithCancel(ctx) if fetchMaxFinalizedTimestamp { @@ -108,7 +116,9 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam }() var isLink, isNative bool - if ds.feedID == ds.linkFeedID { + if ds.jb.OCR2OracleSpec.PluginConfig == nil { + obs.LinkPrice.Val = v2.MissingPrice + } else if ds.feedID == ds.linkFeedID { isLink = true } else { wg.Add(1) @@ -126,7 +136,9 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam }() } - if ds.feedID == ds.nativeFeedID { + if ds.jb.OCR2OracleSpec.PluginConfig == nil { + obs.NativePrice.Val = v2.MissingPrice + } else if ds.feedID == ds.nativeFeedID { isNative = true } else { wg.Add(1) diff --git a/core/services/relay/evm/mercury/v2/data_source_test.go b/core/services/relay/evm/mercury/v2/data_source_test.go index 19af909c8e..7392ceb986 100644 --- a/core/services/relay/evm/mercury/v2/data_source_test.go +++ b/core/services/relay/evm/mercury/v2/data_source_test.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" mercurymocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" @@ -72,7 +73,16 @@ func (ms *mockSaver) Save(r *pipeline.Run) { func Test_Datasource(t *testing.T) { orm := &mockORM{} - ds := &datasource{orm: orm, lggr: logger.TestLogger(t)} + jb := job.Job{ + Type: job.Type(pipeline.OffchainReporting2JobType), + OCR2OracleSpec: &job.OCR2OracleSpec{ + CaptureEATelemetry: true, + PluginConfig: map[string]interface{}{ + "serverURL": "a", + }, + }, + } + ds := &datasource{orm: orm, lggr: logger.TestLogger(t), jb: jb} ctx := testutils.Context(t) repts := ocrtypes.ReportTimestamp{} @@ -274,6 +284,25 @@ func Test_Datasource(t *testing.T) { assert.EqualError(t, obs.NativePrice.Err, "some error fetching native price") }) + t.Run("when PluginConfig=nil skips fetching link and native prices", func(t *testing.T) { + t.Cleanup(func() { + ds.jb = jb + }) + + fetcher.linkPriceErr = errors.New("some error fetching link price") + fetcher.nativePriceErr = errors.New("some error fetching native price") + + ds.jb.OCR2OracleSpec.PluginConfig = nil + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + assert.Nil(t, obs.LinkPrice.Err) + assert.Equal(t, obs.LinkPrice.Val, v2.MissingPrice) + assert.Nil(t, obs.NativePrice.Err) + assert.Equal(t, obs.NativePrice.Val, v2.MissingPrice) + assert.Equal(t, big.NewInt(122), obs.BenchmarkPrice.Val) + }) + t.Run("when succeeds to fetch linkPrice or nativePrice but got nil (new feed)", func(t *testing.T) { obs, err := ds.Observe(ctx, repts, false) assert.NoError(t, err) diff --git a/core/services/relay/evm/mercury/v3/data_source.go b/core/services/relay/evm/mercury/v3/data_source.go index 644f4e775e..48db946517 100644 --- a/core/services/relay/evm/mercury/v3/data_source.go +++ b/core/services/relay/evm/mercury/v3/data_source.go @@ -2,6 +2,7 @@ package v3 import ( "context" + "encoding/json" "errors" "fmt" "math/big" @@ -22,6 +23,7 @@ import ( mercurytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types" mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" + relayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -63,6 +65,12 @@ func NewDataSource(orm types.DataSourceORM, pr pipeline.Runner, jb job.Job, spec func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp, fetchMaxFinalizedTimestamp bool) (obs v3types.Observation, pipelineExecutionErr error) { var wg sync.WaitGroup + var relayConfig relayTypes.RelayConfig + err := json.Unmarshal(ds.jb.OCR2OracleSpec.RelayConfig.Bytes(), &relayConfig) + if err != nil { + pipelineExecutionErr = fmt.Errorf("failed to deserialize relay config: %w", err) + return + } ctx, cancel := context.WithCancel(ctx) if fetchMaxFinalizedTimestamp { @@ -112,7 +120,9 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam }() var isLink, isNative bool - if ds.feedID == ds.linkFeedID { + if ds.jb.OCR2OracleSpec.PluginConfig == nil { + obs.LinkPrice.Val = v3.MissingPrice + } else if ds.feedID == ds.linkFeedID { isLink = true } else { wg.Add(1) @@ -130,7 +140,9 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam }() } - if ds.feedID == ds.nativeFeedID { + if ds.jb.OCR2OracleSpec.PluginConfig == nil { + obs.NativePrice.Val = v3.MissingPrice + } else if ds.feedID == ds.nativeFeedID { isNative = true } else { wg.Add(1) diff --git a/core/services/relay/evm/mercury/v3/data_source_test.go b/core/services/relay/evm/mercury/v3/data_source_test.go index a0f624c78d..3d01d7472e 100644 --- a/core/services/relay/evm/mercury/v3/data_source_test.go +++ b/core/services/relay/evm/mercury/v3/data_source_test.go @@ -5,18 +5,19 @@ import ( "math/big" "testing" + relaymercuryv3 "github.com/smartcontractkit/chainlink-data-streams/mercury/v3" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/eautils" + "github.com/pkg/errors" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" - relaymercuryv3 "github.com/smartcontractkit/chainlink-data-streams/mercury/v3" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/eautils" mercurymocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" reportcodecv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" @@ -77,6 +78,9 @@ func Test_Datasource(t *testing.T) { Type: job.Type(pipeline.OffchainReporting2JobType), OCR2OracleSpec: &job.OCR2OracleSpec{ CaptureEATelemetry: true, + PluginConfig: map[string]interface{}{ + "serverURL": "a", + }, }, } ds := &datasource{orm: orm, lggr: logger.TestLogger(t), jb: jb} @@ -360,6 +364,25 @@ func Test_Datasource(t *testing.T) { assert.EqualError(t, obs.NativePrice.Err, "some error fetching native price") }) + t.Run("when PluginConfig=nil skips fetching link and native prices", func(t *testing.T) { + t.Cleanup(func() { + ds.jb = jb + }) + + fetcher.linkPriceErr = errors.New("some error fetching link price") + fetcher.nativePriceErr = errors.New("some error fetching native price") + + ds.jb.OCR2OracleSpec.PluginConfig = nil + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + assert.Nil(t, obs.LinkPrice.Err) + assert.Equal(t, obs.LinkPrice.Val, relaymercuryv3.MissingPrice) + assert.Nil(t, obs.NativePrice.Err) + assert.Equal(t, obs.NativePrice.Val, relaymercuryv3.MissingPrice) + assert.Equal(t, big.NewInt(122), obs.BenchmarkPrice.Val) + }) + t.Run("when succeeds to fetch linkPrice or nativePrice but got nil (new feed)", func(t *testing.T) { obs, err := ds.Observe(ctx, repts, false) assert.NoError(t, err) From e51472763da4039242ebd4c3939ab44c87e595d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Tue, 17 Sep 2024 23:33:21 +0900 Subject: [PATCH 360/432] Fix multichain keybundle (#14369) * Fix multichain adapter * Use more compact binary encoding for multi-chain public key encoding * keystone: Replace transmit function Overriding _report doesn't actually provide a clear error since transmissions will fail much earlier in the transmit function. Replacing this function should also make this contract cheaper to deploy since we're not deploying unused code. * keystone: Remove unused beforeSetConfig hook * keystone: OCR3Capability to store all pubkeys for multi-chain bundles * keystone: Use custom decoder for OCR3Capability * scripts: keystone: Use the new encoding format for pubkeys * keystone: Merge OCR2Base into OCR3Capability since we already diverged * keystone: Fix setConfig typing so typechain bindings actually generate * Use a custom digester and log decoder * Use multi-chain setup for signing (single-chain won't work anymore) * Remove stray aptos key bundle * Update test snapshot * remove stray aptos code * solhint * Add clause for OCR3 capability * bootstrap: Only setup the config provider, not the whole plugin * address lints * Update test snapshot * check for overflow * Use a different config digest prefix for OCR3Capability * keystone: Remove s_signers, it's unused since we only emit event * keystone: Remove SetConfigArgs * Update gethwrappers * Update config digest prefix to latest agreed upon value * keystone: Validate uniqueness of all keys inside the multi-chain key list * Update gethwrappers * Fix pruning query --------- Co-authored-by: Cedric Cordenier Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> Co-authored-by: Domino Valdano <2644901+reductionista@users.noreply.github.com> --- .changeset/red-icons-build.md | 5 + .../src/v0.8/keystone/OCR3Capability.sol | 185 ++++++++- .../src/v0.8/keystone/ocr/OCR2Abstract.sol | 4 +- contracts/src/v0.8/keystone/ocr/OCR2Base.sol | 352 ------------------ core/chains/evm/logpoller/orm.go | 5 +- .../ocr3_capability/ocr3_capability.go | 50 +-- ...rapper-dependency-versions-do-not-edit.txt | 2 +- .../keystone/src/88_gen_ocr3_config.go | 37 +- .../__snapshots__/88_gen_jobspecs_test.snap | 13 +- .../88_gen_ocr3_config_test.snap | 10 +- .../scripts/keystone/templates/bootstrap.toml | 1 + core/scripts/keystone/templates/oracle.toml | 3 +- core/services/keystore/chaintype/chaintype.go | 34 ++ core/services/ocr2/delegate.go | 2 +- core/services/ocrcommon/adapters.go | 117 +++++- core/services/ocrcommon/adapters_test.go | 147 +++++--- core/services/relay/evm/evm.go | 54 ++- .../relay/evm/ocr3_capability_provider.go | 192 ++++++++++ 18 files changed, 732 insertions(+), 481 deletions(-) create mode 100644 .changeset/red-icons-build.md delete mode 100644 contracts/src/v0.8/keystone/ocr/OCR2Base.sol diff --git a/.changeset/red-icons-build.md b/.changeset/red-icons-build.md new file mode 100644 index 0000000000..feee928a87 --- /dev/null +++ b/.changeset/red-icons-build.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Small fixes to multichain keyring adapter #internal diff --git a/contracts/src/v0.8/keystone/OCR3Capability.sol b/contracts/src/v0.8/keystone/OCR3Capability.sol index 1ba934b1c4..c7ab8299b7 100644 --- a/contracts/src/v0.8/keystone/OCR3Capability.sol +++ b/contracts/src/v0.8/keystone/OCR3Capability.sol @@ -1,29 +1,186 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -import {OCR2Base} from "./ocr/OCR2Base.sol"; +import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; +import {OCR2Abstract} from "./ocr/OCR2Abstract.sol"; // OCR2Base provides config management compatible with OCR3 -contract OCR3Capability is OCR2Base { +contract OCR3Capability is ConfirmedOwner, OCR2Abstract { + error InvalidConfig(string message); error ReportingUnsupported(); - constructor() OCR2Base() {} + constructor() ConfirmedOwner(msg.sender) {} + // incremented each time a new config is posted. This count is incorporated + // into the config digest, to prevent replay attacks. + uint32 internal s_configCount; + uint32 internal s_latestConfigBlockNumber; // makes it easier for offchain systems + // to extract config from logs. - function typeAndVersion() external pure override returns (string memory) { - return "Keystone 1.0.0"; + // Storing these fields used on the hot path in a ConfigInfo variable reduces the + // retrieval of all of them to a single SLOAD. If any further fields are + // added, make sure that storage of the struct still takes at most 32 bytes. + struct ConfigInfo { + bytes32 latestConfigDigest; + uint8 f; // TODO: could be optimized by squeezing into one slot + uint8 n; + } + ConfigInfo internal s_configInfo; + + /* + * Config logic + */ + + // Reverts transaction if config args are invalid + modifier checkConfigValid( + uint256 numSigners, + uint256 numTransmitters, + uint256 f + ) { + if (numSigners > MAX_NUM_ORACLES) revert InvalidConfig("too many signers"); + if (f == 0) revert InvalidConfig("f must be positive"); + if (numSigners != numTransmitters) revert InvalidConfig("oracle addresses out of registration"); + if (numSigners <= 3 * f) revert InvalidConfig("faulty-oracle f too high"); + _; } - function _beforeSetConfig(uint8 /* _f */, bytes memory /* _onchainConfig */) internal override { - // no-op + /// @inheritdoc OCR2Abstract + function latestConfigDigestAndEpoch() + external + view + virtual + override + returns (bool scanLogs, bytes32 configDigest, uint32 epoch) + { + return (true, bytes32(0), uint32(0)); + } + + // signer = [ 1 byte type | 2 byte len | n byte value ]... + + /** + * @notice sets offchain reporting protocol configuration incl. participating oracles + * @param _signers addresses with which oracles sign the reports + * @param _transmitters addresses oracles use to transmit the reports + * @param _f number of faulty oracles the system can tolerate + * @param _onchainConfig encoded on-chain contract configuration + * @param _offchainConfigVersion version number for offchainEncoding schema + * @param _offchainConfig encoded off-chain oracle configuration + */ + function setConfig( + bytes[] calldata _signers, + address[] calldata _transmitters, + uint8 _f, + bytes memory _onchainConfig, + uint64 _offchainConfigVersion, + bytes memory _offchainConfig + ) external override checkConfigValid(_signers.length, _transmitters.length, _f) onlyOwner { + // Bounded by MAX_NUM_ORACLES in OCR2Abstract.sol + for (uint256 i = 0; i < _signers.length; i++) { + if (_transmitters[i] == address(0)) revert InvalidConfig("transmitter must not be empty"); + // add new signers + bytes calldata publicKeys = _signers[i]; + uint16 offset = 0; + uint16 len = uint16(publicKeys.length); + // scan through public keys to validate encoded format + while (offset < len) { + // solhint-disable-next-line no-unused-vars + uint8 keyType = uint8(publicKeys[offset]); + uint16 keyLen = uint16(uint8(publicKeys[offset + 1])) + (uint16(uint8(publicKeys[offset + 2])) << 8); + // solhint-disable-next-line no-unused-vars + bytes calldata publicKey = publicKeys[offset + 3:offset + 3 + keyLen]; + offset += 3 + keyLen; + } + } + s_configInfo.f = _f; + uint32 previousConfigBlockNumber = s_latestConfigBlockNumber; + s_latestConfigBlockNumber = uint32(block.number); + s_configCount += 1; + { + s_configInfo.latestConfigDigest = _configDigestFromConfigData( + block.chainid, + address(this), + s_configCount, + _signers, + _transmitters, + _f, + _onchainConfig, + _offchainConfigVersion, + _offchainConfig + ); + } + s_configInfo.n = uint8(_signers.length); + + emit ConfigSet( + previousConfigBlockNumber, + s_configInfo.latestConfigDigest, + s_configCount, + _signers, + _transmitters, + _f, + _onchainConfig, + _offchainConfigVersion, + _offchainConfig + ); + } + + function _configDigestFromConfigData( + uint256 _chainId, + address _contractAddress, + uint64 _configCount, + bytes[] calldata _signers, + address[] calldata _transmitters, + uint8 _f, + bytes memory _onchainConfig, + uint64 _encodedConfigVersion, + bytes memory _encodedConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + _chainId, + _contractAddress, + _configCount, + _signers, + _transmitters, + _f, + _onchainConfig, + _encodedConfigVersion, + _encodedConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + uint256 prefix = 0x000e << (256 - 16); // 0x000e00..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + /** + * @notice information about current offchain reporting protocol configuration + * @return configCount ordinal number of current config, out of all configs applied to this contract so far + * @return blockNumber block at which this config was set + * @return configDigest domain-separation tag for current config (see __configDigestFromConfigData) + */ + function latestConfigDetails() + external + view + override + returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) + { + return (s_configCount, s_latestConfigBlockNumber, s_configInfo.latestConfigDigest); + } + + function typeAndVersion() external pure override returns (string memory) { + return "Keystone 1.0.0"; } - function _report( - uint256 /* initialGas */, - address /* transmitter */, - uint8 /* signerCount */, - address[MAX_NUM_ORACLES] memory /* signers */, - bytes calldata /* report */ - ) internal virtual override { + function transmit( + // NOTE: If these parameters are changed, expectedMsgDataLength and/or + // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly + bytes32[3] calldata /* reportContext */, + bytes calldata /* report */, + bytes32[] calldata /* rs */, + bytes32[] calldata /* ss */, + bytes32 /* rawVs */ // signatures + ) external pure override { revert ReportingUnsupported(); } } diff --git a/contracts/src/v0.8/keystone/ocr/OCR2Abstract.sol b/contracts/src/v0.8/keystone/ocr/OCR2Abstract.sol index 3c1e304748..4eb5cb069b 100644 --- a/contracts/src/v0.8/keystone/ocr/OCR2Abstract.sol +++ b/contracts/src/v0.8/keystone/ocr/OCR2Abstract.sol @@ -23,7 +23,7 @@ abstract contract OCR2Abstract is ITypeAndVersion { uint32 previousConfigBlockNumber, bytes32 configDigest, uint64 configCount, - address[] signers, + bytes[] signers, address[] transmitters, uint8 f, bytes onchainConfig, @@ -41,7 +41,7 @@ abstract contract OCR2Abstract is ITypeAndVersion { * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract */ function setConfig( - address[] memory signers, + bytes[] memory signers, address[] memory transmitters, uint8 f, bytes memory onchainConfig, diff --git a/contracts/src/v0.8/keystone/ocr/OCR2Base.sol b/contracts/src/v0.8/keystone/ocr/OCR2Base.sol deleted file mode 100644 index efc7992e90..0000000000 --- a/contracts/src/v0.8/keystone/ocr/OCR2Base.sol +++ /dev/null @@ -1,352 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; -import {OCR2Abstract} from "./OCR2Abstract.sol"; - -/** - * @notice Onchain verification of reports from the offchain reporting protocol - * @dev For details on its operation, see the offchain reporting protocol design - * doc, which refers to this contract as simply the "contract". - */ -abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { - error ReportInvalid(string message); - error InvalidConfig(string message); - - constructor() ConfirmedOwner(msg.sender) {} - - // incremented each time a new config is posted. This count is incorporated - // into the config digest, to prevent replay attacks. - uint32 internal s_configCount; - uint32 internal s_latestConfigBlockNumber; // makes it easier for offchain systems - // to extract config from logs. - - // Storing these fields used on the hot path in a ConfigInfo variable reduces the - // retrieval of all of them to a single SLOAD. If any further fields are - // added, make sure that storage of the struct still takes at most 32 bytes. - struct ConfigInfo { - bytes32 latestConfigDigest; - uint8 f; // TODO: could be optimized by squeezing into one slot - uint8 n; - } - ConfigInfo internal s_configInfo; - - // Used for s_oracles[a].role, where a is an address, to track the purpose - // of the address, or to indicate that the address is unset. - enum Role { - // No oracle role has been set for address a - Unset, - // Signing address for the s_oracles[a].index'th oracle. I.e., report - // signatures from this oracle should ecrecover back to address a. - Signer, - // Transmission address for the s_oracles[a].index'th oracle. I.e., if a - // report is received by OCR2Aggregator.transmit in which msg.sender is - // a, it is attributed to the s_oracles[a].index'th oracle. - Transmitter - } - - struct Oracle { - uint8 index; // Index of oracle in s_signers/s_transmitters - Role role; // Role of the address which mapped to this struct - } - - mapping(address signerOrTransmitter => Oracle) internal s_oracles; - - // s_signers contains the signing address of each oracle - address[] internal s_signers; - - // s_transmitters contains the transmission address of each oracle, - // i.e. the address the oracle actually sends transactions to the contract from - address[] internal s_transmitters; - - /* - * Config logic - */ - - // Reverts transaction if config args are invalid - modifier checkConfigValid( - uint256 numSigners, - uint256 numTransmitters, - uint256 f - ) { - if (numSigners > MAX_NUM_ORACLES) revert InvalidConfig("too many signers"); - if (f == 0) revert InvalidConfig("f must be positive"); - if (numSigners != numTransmitters) revert InvalidConfig("oracle addresses out of registration"); - if (numSigners <= 3 * f) revert InvalidConfig("faulty-oracle f too high"); - _; - } - - // solhint-disable-next-line gas-struct-packing - struct SetConfigArgs { - address[] signers; - address[] transmitters; - uint8 f; - bytes onchainConfig; - uint64 offchainConfigVersion; - bytes offchainConfig; - } - - /// @inheritdoc OCR2Abstract - function latestConfigDigestAndEpoch() - external - view - virtual - override - returns (bool scanLogs, bytes32 configDigest, uint32 epoch) - { - return (true, bytes32(0), uint32(0)); - } - - /** - * @notice sets offchain reporting protocol configuration incl. participating oracles - * @param _signers addresses with which oracles sign the reports - * @param _transmitters addresses oracles use to transmit the reports - * @param _f number of faulty oracles the system can tolerate - * @param _onchainConfig encoded on-chain contract configuration - * @param _offchainConfigVersion version number for offchainEncoding schema - * @param _offchainConfig encoded off-chain oracle configuration - */ - function setConfig( - address[] memory _signers, - address[] memory _transmitters, - uint8 _f, - bytes memory _onchainConfig, - uint64 _offchainConfigVersion, - bytes memory _offchainConfig - ) external override checkConfigValid(_signers.length, _transmitters.length, _f) onlyOwner { - SetConfigArgs memory args = SetConfigArgs({ - signers: _signers, - transmitters: _transmitters, - f: _f, - onchainConfig: _onchainConfig, - offchainConfigVersion: _offchainConfigVersion, - offchainConfig: _offchainConfig - }); - - _beforeSetConfig(args.f, args.onchainConfig); - - while (s_signers.length != 0) { - // remove any old signer/transmitter addresses - uint256 lastIdx = s_signers.length - 1; - address signer = s_signers[lastIdx]; - address transmitter = s_transmitters[lastIdx]; - delete s_oracles[signer]; - delete s_oracles[transmitter]; - s_signers.pop(); - s_transmitters.pop(); - } - - // Bounded by MAX_NUM_ORACLES in OCR2Abstract.sol - for (uint256 i = 0; i < args.signers.length; i++) { - if (args.signers[i] == address(0)) revert InvalidConfig("signer must not be empty"); - if (args.transmitters[i] == address(0)) revert InvalidConfig("transmitter must not be empty"); - // add new signer/transmitter addresses - if (s_oracles[args.signers[i]].role != Role.Unset) revert InvalidConfig("repeated signer address"); - s_oracles[args.signers[i]] = Oracle(uint8(i), Role.Signer); - if (s_oracles[args.transmitters[i]].role != Role.Unset) revert InvalidConfig("repeated transmitter address"); - s_oracles[args.transmitters[i]] = Oracle(uint8(i), Role.Transmitter); - s_signers.push(args.signers[i]); - s_transmitters.push(args.transmitters[i]); - } - s_configInfo.f = args.f; - uint32 previousConfigBlockNumber = s_latestConfigBlockNumber; - s_latestConfigBlockNumber = uint32(block.number); - s_configCount += 1; - { - s_configInfo.latestConfigDigest = _configDigestFromConfigData( - block.chainid, - address(this), - s_configCount, - args.signers, - args.transmitters, - args.f, - args.onchainConfig, - args.offchainConfigVersion, - args.offchainConfig - ); - } - s_configInfo.n = uint8(args.signers.length); - - emit ConfigSet( - previousConfigBlockNumber, - s_configInfo.latestConfigDigest, - s_configCount, - args.signers, - args.transmitters, - args.f, - args.onchainConfig, - args.offchainConfigVersion, - args.offchainConfig - ); - } - - function _configDigestFromConfigData( - uint256 _chainId, - address _contractAddress, - uint64 _configCount, - address[] memory _signers, - address[] memory _transmitters, - uint8 _f, - bytes memory _onchainConfig, - uint64 _encodedConfigVersion, - bytes memory _encodedConfig - ) internal pure returns (bytes32) { - uint256 h = uint256( - keccak256( - abi.encode( - _chainId, - _contractAddress, - _configCount, - _signers, - _transmitters, - _f, - _onchainConfig, - _encodedConfigVersion, - _encodedConfig - ) - ) - ); - uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 - uint256 prefix = 0x0001 << (256 - 16); // 0x000100..00 - return bytes32((prefix & prefixMask) | (h & ~prefixMask)); - } - - /** - * @notice information about current offchain reporting protocol configuration - * @return configCount ordinal number of current config, out of all configs applied to this contract so far - * @return blockNumber block at which this config was set - * @return configDigest domain-separation tag for current config (see __configDigestFromConfigData) - */ - function latestConfigDetails() - external - view - override - returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) - { - return (s_configCount, s_latestConfigBlockNumber, s_configInfo.latestConfigDigest); - } - - /** - * @return list of addresses permitted to transmit reports to this contract - * @dev The list will match the order used to specify the transmitter during setConfig - */ - function transmitters() external view returns (address[] memory) { - return s_transmitters; - } - - function _beforeSetConfig(uint8 _f, bytes memory _onchainConfig) internal virtual; - - /** - * @dev hook called after the report has been fully validated - * for the extending contract to handle additional logic, such as oracle payment - * @param initialGas the amount of gas before validation - * @param transmitter the address of the account that submitted the report - * @param signers the addresses of all signing accounts - * @param report serialized report - */ - function _report( - uint256 initialGas, - address transmitter, - uint8 signerCount, - address[MAX_NUM_ORACLES] memory signers, - bytes calldata report - ) internal virtual; - - // The constant-length components of the msg.data sent to transmit. - // See the "If we wanted to call sam" example on for example reasoning - // https://solidity.readthedocs.io/en/v0.7.2/abi-spec.html - uint16 private constant TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT = - 4 + // function selector - 32 * - 3 + // 3 words containing reportContext - 32 + // word containing start location of abiencoded report value - 32 + // word containing location start of abiencoded rs value - 32 + // word containing start location of abiencoded ss value - 32 + // rawVs value - 32 + // word containing length of report - 32 + // word containing length rs - 32 + // word containing length of ss - 0; // placeholder - - function _requireExpectedMsgDataLength( - bytes calldata report, - bytes32[] calldata rs, - bytes32[] calldata ss - ) private pure { - // calldata will never be big enough to make this overflow - uint256 expected = uint256(TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT) + - report.length + // one byte pure entry in _report - rs.length * - 32 + // 32 bytes per entry in _rs - ss.length * - 32 + // 32 bytes per entry in _ss - 0; // placeholder - if (msg.data.length != expected) revert ReportInvalid("calldata length mismatch"); - } - - /** - * @notice transmit is called to post a new report to the contract - * @param report serialized report, which the signatures are signing. - * @param rs ith element is the R components of the ith signature on report. Must have at most maxNumOracles entries - * @param ss ith element is the S components of the ith signature on report. Must have at most maxNumOracles entries - * @param rawVs ith element is the the V component of the ith signature - */ - function transmit( - // NOTE: If these parameters are changed, expectedMsgDataLength and/or - // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly - bytes32[3] calldata reportContext, - bytes calldata report, - bytes32[] calldata rs, - bytes32[] calldata ss, - bytes32 rawVs // signatures - ) external override { - uint256 initialGas = gasleft(); // This line must come first - - { - // reportContext consists of: - // reportContext[0]: ConfigDigest - // reportContext[1]: 27 byte padding, 4-byte epoch and 1-byte round - // reportContext[2]: ExtraHash - bytes32 configDigest = reportContext[0]; - uint32 epochAndRound = uint32(uint256(reportContext[1])); - - emit Transmitted(configDigest, uint32(epochAndRound >> 8)); - - // The following check is disabled to allow both current and proposed routes to submit reports using the same OCR config digest - // Chainlink Functions uses globally unique request IDs. Metadata about the request is stored and checked in the Coordinator and Router - // require(configInfo.latestConfigDigest == configDigest, "configDigest mismatch"); - - _requireExpectedMsgDataLength(report, rs, ss); - - uint256 expectedNumSignatures = (s_configInfo.n + s_configInfo.f) / 2 + 1; - - if (rs.length != expectedNumSignatures) revert ReportInvalid("wrong number of signatures"); - if (rs.length != ss.length) revert ReportInvalid("report rs and ss must be of equal length"); - - Oracle memory transmitter = s_oracles[msg.sender]; - if (transmitter.role != Role.Transmitter && msg.sender != s_transmitters[transmitter.index]) - revert ReportInvalid("unauthorized transmitter"); - } - - address[MAX_NUM_ORACLES] memory signed; - uint8 signerCount = 0; - - { - // Verify signatures attached to report - bytes32 h = keccak256(abi.encodePacked(keccak256(report), reportContext)); - - Oracle memory o; - // Bounded by MAX_NUM_ORACLES in OCR2Abstract.sol - for (uint256 i = 0; i < rs.length; ++i) { - address signer = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]); - o = s_oracles[signer]; - if (o.role != Role.Signer) revert ReportInvalid("address not authorized to sign"); - if (signed[o.index] != address(0)) revert ReportInvalid("non-unique signature"); - signed[o.index] = signer; - signerCount += 1; - } - } - - _report(initialGas, msg.sender, signerCount, signed, report); - } -} diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index 1c119c9f9a..5ab7db4eb0 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -330,8 +330,9 @@ func (o *DSORM) DeleteExpiredLogs(ctx context.Context, limit int64) (int64, erro FROM evm.log_poller_filters WHERE evm_chain_id = $1 GROUP BY evm_chain_id, address, event - ) r ON l.evm_chain_id = $1 AND l.address = r.address AND l.event_sig = r.event - WHERE r.retention IS NULL OR (r.retention != 0 AND l.block_timestamp <= STATEMENT_TIMESTAMP() - (r.retention / 10^9 * interval '1 second')) %s)` + ) r ON l.address = r.address AND l.event_sig = r.event + WHERE l.evm_chain_id = $1 AND -- Must be WHERE rather than ON due to LEFT JOIN + r.retention IS NULL OR (r.retention != 0 AND l.block_timestamp <= STATEMENT_TIMESTAMP() - (r.retention / 10^9 * interval '1 second')) %s)` if limit > 0 { result, err = o.ds.ExecContext(ctx, fmt.Sprintf(query, "LIMIT $2"), ubig.New(o.chainID), limit) diff --git a/core/gethwrappers/keystone/generated/ocr3_capability/ocr3_capability.go b/core/gethwrappers/keystone/generated/ocr3_capability/ocr3_capability.go index e51f4762d8..21aeb4975c 100644 --- a/core/gethwrappers/keystone/generated/ocr3_capability/ocr3_capability.go +++ b/core/gethwrappers/keystone/generated/ocr3_capability/ocr3_capability.go @@ -31,8 +31,8 @@ var ( ) var OCR3CapabilityMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReportingUnsupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000a5565b50505062000150565b336001600160a01b03821603620000ff5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611fe180620001606000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063b1dc65a41161005b578063b1dc65a4146101c4578063e3d0e712146101d7578063f2fde38b146101ea57600080fd5b80638da5cb5b1461017c578063afcb95d7146101a457600080fd5b8063181f5a77146100a857806379ba5097146100f057806381411834146100fa57806381ff70481461010f575b600080fd5b604080518082018252600e81527f4b657973746f6e6520312e302e30000000000000000000000000000000000000602082015290516100e79190611883565b60405180910390f35b6100f86101fd565b005b6101026102ff565b6040516100e791906118ef565b61015960015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff9485168152939092166020840152908201526060016100e7565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e7565b6040805160018152600060208201819052918101919091526060016100e7565b6100f86101d236600461194e565b61036e565b6100f86101e5366004611c18565b610975565b6100f86101f8366004611ce5565b6114e0565b60015473ffffffffffffffffffffffffffffffffffffffff163314610283576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6060600680548060200260200160405190810160405280929190818152602001828054801561036457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610339575b5050505050905090565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16103cf8a8a8a8a8a8a6114f4565b6003546000906002906103ed9060ff80821691610100900416611d5e565b6103f79190611d7d565b610402906001611d5e565b60ff169050878114610470576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e617475726573000000000000604482015260640161027a565b8786146104ff576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f7265706f727420727320616e64207373206d757374206265206f66206571756160448201527f6c206c656e677468000000000000000000000000000000000000000000000000606482015260840161027a565b3360009081526004602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561054257610542611dc6565b600281111561055357610553611dc6565b905250905060028160200151600281111561057057610570611dc6565b141580156105b957506006816000015160ff168154811061059357610593611d00565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff163314155b15610620576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d69747465720000000000000000604482015260640161027a565b5050505061062c611800565b6000808a8a60405161063f929190611df5565b604051908190038120610656918e90602001611e05565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156109575760006001848984602081106106bf576106bf611d00565b6106cc91901a601b611d5e565b8e8e868181106106de576106de611d00565b905060200201358d8d878181106106f7576106f7611d00565b9050602002013560405160008152602001604052604051610734949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610756573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff808216855292965092945084019161010090041660028111156107d6576107d6611dc6565b60028111156107e7576107e7611dc6565b905250925060018360200151600281111561080457610804611dc6565b1461086b576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e0000604482015260640161027a565b8251600090879060ff16601f811061088557610885611d00565b602002015173ffffffffffffffffffffffffffffffffffffffff1614610907576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e6174757265000000000000000000000000604482015260640161027a565b8086846000015160ff16601f811061092157610921611d00565b73ffffffffffffffffffffffffffffffffffffffff909216602092909202015261094c600186611d5e565b9450506001016106a0565b505050610968833383858e8e6115ab565b5050505050505050505050565b855185518560ff16601f8311156109e8576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e65727300000000000000000000000000000000604482015260640161027a565b80600003610a52576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f7369746976650000000000000000000000000000604482015260640161027a565b818314610ae0576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e00000000000000000000000000000000000000000000000000000000606482015260840161027a565b610aeb816003611e19565b8311610b53576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f20686967680000000000000000604482015260640161027a565b610b5b6115dd565b6040805160c0810182528a8152602081018a905260ff8916918101919091526060810187905267ffffffffffffffff8616608082015260a081018590525b60055415610d4e57600554600090610bb390600190611e30565b9050600060058281548110610bca57610bca611d00565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110610c0457610c04611d00565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600580549192509080610c8457610c84611e43565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556006805480610ced57610ced611e43565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550610b99915050565b60005b8151518110156112fd57815180516000919083908110610d7357610d73611d00565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610df8576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f7369676e6572206d757374206e6f7420626520656d7074790000000000000000604482015260640161027a565b600073ffffffffffffffffffffffffffffffffffffffff1682602001518281518110610e2657610e26611d00565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610eab576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f7472616e736d6974746572206d757374206e6f7420626520656d707479000000604482015260640161027a565b60006004600084600001518481518110610ec757610ec7611d00565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115610f1157610f11611dc6565b14610f78576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e65722061646472657373000000000000000000604482015260640161027a565b6040805180820190915260ff82168152600160208201528251805160049160009185908110610fa957610fa9611d00565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561104a5761104a611dc6565b02179055506000915061105a9050565b600460008460200151848151811061107457611074611d00565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff1660028111156110be576110be611dc6565b14611125576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d6974746572206164647265737300000000604482015260640161027a565b6040805180820190915260ff82168152602081016002815250600460008460200151848151811061115857611158611d00565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156111f9576111f9611dc6565b02179055505082518051600592508390811061121757611217611d00565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558201518051600691908390811061129357611293611d00565b60209081029190910181015182546001808201855560009485529290932090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915501610d51565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff43811682029290921780855592048116929182916014916113b591849174010000000000000000000000000000000000000000900416611e72565b92506101000a81548163ffffffff021916908363ffffffff1602179055506114144630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151611660565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05986114cb988b9891977401000000000000000000000000000000000000000090920463ffffffff16969095919491939192611e96565b60405180910390a15050505050505050505050565b6114e86115dd565b6114f18161170b565b50565b6000611501826020611e19565b61150c856020611e19565b61151888610144611f2c565b6115229190611f2c565b61152c9190611f2c565b611537906000611f2c565b90503681146115a2576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d617463680000000000000000604482015260640161027a565b50505050505050565b6040517f0750181900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461165e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161027a565b565b6000808a8a8a8a8a8a8a8a8a60405160200161168499989796959493929190611f3f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361178a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161027a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b604051806103e00160405280601f906020820280368337509192915050565b6000815180845260005b8181101561184557602081850181015186830182015201611829565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611896602083018461181f565b9392505050565b60008151808452602080850194506020840160005b838110156118e457815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016118b2565b509495945050505050565b602081526000611896602083018461189d565b60008083601f84011261191457600080fd5b50813567ffffffffffffffff81111561192c57600080fd5b6020830191508360208260051b850101111561194757600080fd5b9250929050565b60008060008060008060008060e0898b03121561196a57600080fd5b606089018a81111561197b57600080fd5b8998503567ffffffffffffffff8082111561199557600080fd5b818b0191508b601f8301126119a957600080fd5b8135818111156119b857600080fd5b8c60208285010111156119ca57600080fd5b6020830199508098505060808b01359150808211156119e857600080fd5b6119f48c838d01611902565b909750955060a08b0135915080821115611a0d57600080fd5b50611a1a8b828c01611902565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611aa957611aa9611a33565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611ad557600080fd5b919050565b600082601f830112611aeb57600080fd5b8135602067ffffffffffffffff821115611b0757611b07611a33565b8160051b611b16828201611a62565b9283528481018201928281019087851115611b3057600080fd5b83870192505b84831015611b5657611b4783611ab1565b82529183019190830190611b36565b979650505050505050565b803560ff81168114611ad557600080fd5b600082601f830112611b8357600080fd5b813567ffffffffffffffff811115611b9d57611b9d611a33565b611bce60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611a62565b818152846020838601011115611be357600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff81168114611ad557600080fd5b60008060008060008060c08789031215611c3157600080fd5b863567ffffffffffffffff80821115611c4957600080fd5b611c558a838b01611ada565b97506020890135915080821115611c6b57600080fd5b611c778a838b01611ada565b9650611c8560408a01611b61565b95506060890135915080821115611c9b57600080fd5b611ca78a838b01611b72565b9450611cb560808a01611c00565b935060a0890135915080821115611ccb57600080fd5b50611cd889828a01611b72565b9150509295509295509295565b600060208284031215611cf757600080fd5b61189682611ab1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff8181168382160190811115611d7757611d77611d2f565b92915050565b600060ff831680611db7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b8082028115828204841417611d7757611d77611d2f565b81810381811115611d7757611d77611d2f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff818116838216019080821115611e8f57611e8f611d2f565b5092915050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152611ec68184018a61189d565b90508281036080840152611eda818961189d565b905060ff871660a084015282810360c0840152611ef7818761181f565b905067ffffffffffffffff851660e0840152828103610100840152611f1c818561181f565b9c9b505050505050505050505050565b80820180821115611d7757611d77611d2f565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152611f868285018b61189d565b91508382036080850152611f9a828a61189d565b915060ff881660a085015283820360c0850152611fb7828861181f565b90861660e08501528381036101008501529050611f1c818561181f56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReportingUnsupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"_signers\",\"type\":\"bytes[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611266806101576000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638da5cb5b1161005b5780638da5cb5b1461015f578063afcb95d714610187578063b1dc65a4146101a7578063f2fde38b146101ba57600080fd5b8063181f5a771461008d57806379ba5097146100d55780637f3c87d3146100df57806381ff7048146100f2575b600080fd5b604080518082018252600e81527f4b657973746f6e6520312e302e30000000000000000000000000000000000000602082015290516100cc9190610b02565b60405180910390f35b6100dd6101cd565b005b6100dd6100ed366004610c70565b6102cf565b61013c60015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff9485168152939092166020840152908201526060016100cc565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100cc565b6040805160018152600060208201819052918101919091526060016100cc565b6100dd6101b5366004610d4c565b61082f565b6100dd6101c8366004610e55565b610861565b60015473ffffffffffffffffffffffffffffffffffffffff163314610253576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b868560ff8616601f831115610340576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e65727300000000000000000000000000000000604482015260640161024a565b806000036103aa576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f7369746976650000000000000000000000000000604482015260640161024a565b818314610438576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e00000000000000000000000000000000000000000000000000000000606482015260840161024a565b610443816003610e9f565b83116104ab576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f20686967680000000000000000604482015260640161024a565b6104b3610875565b60005b8a81101561069d5760008a8a838181106104d2576104d2610ebc565b90506020020160208101906104e79190610e55565b73ffffffffffffffffffffffffffffffffffffffff1603610564576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f7472616e736d6974746572206d757374206e6f7420626520656d707479000000604482015260640161024a565b3660008d8d8481811061057957610579610ebc565b905060200281019061058b9190610eeb565b90925090506000815b8061ffff168261ffff16101561068d57600084848461ffff168181106105bc576105bc610ebc565b919091013560f81c915060009050600886866105d9876002610f50565b61ffff168181106105ec576105ec610ebc565b919091013560f81c90911b90508686610606876001610f50565b61ffff1681811061061957610619610ebc565b61062a9392013560f81c9050610f50565b9050366000878761063c886003610f50565b61ffff16908561064d8a6003610f50565b6106579190610f50565b61ffff169261066893929190610f72565b9092509050610678836003610f50565b6106829087610f50565b955050505050610594565b5050600190920191506104b69050565b50600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff8916179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff438116820292909217808555920481169291829160149161074c91849174010000000000000000000000000000000000000000900416610f9c565b92506101000a81548163ffffffff021916908363ffffffff1602179055506107954630600160149054906101000a900463ffffffff1663ffffffff168f8f8f8f8f8f8f8f6108f8565b6002600001819055508b8b9050600260010160016101000a81548160ff021916908360ff1602179055507f36257c6e8d535293ad661e377c0baac536289be6707b8a488ac175ddaa4055c881600260000154600160149054906101000a900463ffffffff168f8f8f8f8f8f8f8f6040516108199b9a99989796959493929190611128565b60405180910390a1505050505050505050505050565b6040517f0750181900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610869610875565b610872816109a9565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161024a565b565b6000808c8c8c8c8c8c8c8c8c8c8c6040516020016109209b9a999897969594939291906111c2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0e000000000000000000000000000000000000000000000000000000000000179150509b9a5050505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603610a28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161024a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000815180845260005b81811015610ac457602081850181015186830182015201610aa8565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610b156020830184610a9e565b9392505050565b60008083601f840112610b2e57600080fd5b50813567ffffffffffffffff811115610b4657600080fd5b6020830191508360208260051b8501011115610b6157600080fd5b9250929050565b803560ff81168114610b7957600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610bbe57600080fd5b813567ffffffffffffffff80821115610bd957610bd9610b7e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610c1f57610c1f610b7e565b81604052838152866020858801011115610c3857600080fd5b836020870160208301376000602085830101528094505050505092915050565b803567ffffffffffffffff81168114610b7957600080fd5b60008060008060008060008060c0898b031215610c8c57600080fd5b883567ffffffffffffffff80821115610ca457600080fd5b610cb08c838d01610b1c565b909a50985060208b0135915080821115610cc957600080fd5b610cd58c838d01610b1c565b9098509650869150610ce960408c01610b68565b955060608b0135915080821115610cff57600080fd5b610d0b8c838d01610bad565b9450610d1960808c01610c58565b935060a08b0135915080821115610d2f57600080fd5b50610d3c8b828c01610bad565b9150509295985092959890939650565b60008060008060008060008060e0898b031215610d6857600080fd5b606089018a811115610d7957600080fd5b8998503567ffffffffffffffff80821115610d9357600080fd5b818b0191508b601f830112610da757600080fd5b813581811115610db657600080fd5b8c6020828501011115610dc857600080fd5b6020830199508098505060808b0135915080821115610de657600080fd5b610df28c838d01610b1c565b909750955060a08b0135915080821115610e0b57600080fd5b50610e188b828c01610b1c565b999c989b50969995989497949560c00135949350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b7957600080fd5b600060208284031215610e6757600080fd5b610b1582610e31565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610eb657610eb6610e70565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610f2057600080fd5b83018035915067ffffffffffffffff821115610f3b57600080fd5b602001915036819003821315610b6157600080fd5b61ffff818116838216019080821115610f6b57610f6b610e70565b5092915050565b60008085851115610f8257600080fd5b83861115610f8f57600080fd5b5050820193919092039150565b63ffffffff818116838216019080821115610f6b57610f6b610e70565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6000838385526020808601955060208560051b8301018460005b878110156110c7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085840301895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe188360301811261107d57600080fd5b8701848101903567ffffffffffffffff81111561109957600080fd5b8036038213156110a857600080fd5b6110b3858284610fb9565b9a86019a945050509083019060010161101c565b5090979650505050505050565b8183526000602080850194508260005b8581101561111d5773ffffffffffffffffffffffffffffffffffffffff61110a83610e31565b16875295820195908201906001016110e4565b509495945050505050565b600061012063ffffffff808f1684528d6020850152808d166040850152508060608401526111598184018b8d611002565b9050828103608084015261116e81898b6110d4565b905060ff871660a084015282810360c084015261118b8187610a9e565b905067ffffffffffffffff851660e08401528281036101008401526111b08185610a9e565b9e9d5050505050505050505050505050565b60006101208d835273ffffffffffffffffffffffffffffffffffffffff8d16602084015267ffffffffffffffff808d16604085015281606085015261120a8285018c8e611002565b9150838203608085015261121f828a8c6110d4565b915060ff881660a085015283820360c085015261123c8288610a9e565b90861660e085015283810361010085015290506111b08185610a9e56fea164736f6c6343000818000a", } var OCR3CapabilityABI = OCR3CapabilityMetaData.ABI @@ -255,26 +255,24 @@ func (_OCR3Capability *OCR3CapabilityCallerSession) Owner() (common.Address, err return _OCR3Capability.Contract.Owner(&_OCR3Capability.CallOpts) } -func (_OCR3Capability *OCR3CapabilityCaller) Transmitters(opts *bind.CallOpts) ([]common.Address, error) { +func (_OCR3Capability *OCR3CapabilityCaller) Transmit(opts *bind.CallOpts, arg0 [3][32]byte, arg1 []byte, arg2 [][32]byte, arg3 [][32]byte, arg4 [32]byte) error { var out []interface{} - err := _OCR3Capability.contract.Call(opts, &out, "transmitters") + err := _OCR3Capability.contract.Call(opts, &out, "transmit", arg0, arg1, arg2, arg3, arg4) if err != nil { - return *new([]common.Address), err + return err } - out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) - - return out0, err + return err } -func (_OCR3Capability *OCR3CapabilitySession) Transmitters() ([]common.Address, error) { - return _OCR3Capability.Contract.Transmitters(&_OCR3Capability.CallOpts) +func (_OCR3Capability *OCR3CapabilitySession) Transmit(arg0 [3][32]byte, arg1 []byte, arg2 [][32]byte, arg3 [][32]byte, arg4 [32]byte) error { + return _OCR3Capability.Contract.Transmit(&_OCR3Capability.CallOpts, arg0, arg1, arg2, arg3, arg4) } -func (_OCR3Capability *OCR3CapabilityCallerSession) Transmitters() ([]common.Address, error) { - return _OCR3Capability.Contract.Transmitters(&_OCR3Capability.CallOpts) +func (_OCR3Capability *OCR3CapabilityCallerSession) Transmit(arg0 [3][32]byte, arg1 []byte, arg2 [][32]byte, arg3 [][32]byte, arg4 [32]byte) error { + return _OCR3Capability.Contract.Transmit(&_OCR3Capability.CallOpts, arg0, arg1, arg2, arg3, arg4) } func (_OCR3Capability *OCR3CapabilityCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { @@ -311,15 +309,15 @@ func (_OCR3Capability *OCR3CapabilityTransactorSession) AcceptOwnership() (*type return _OCR3Capability.Contract.AcceptOwnership(&_OCR3Capability.TransactOpts) } -func (_OCR3Capability *OCR3CapabilityTransactor) SetConfig(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { +func (_OCR3Capability *OCR3CapabilityTransactor) SetConfig(opts *bind.TransactOpts, _signers [][]byte, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { return _OCR3Capability.contract.Transact(opts, "setConfig", _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) } -func (_OCR3Capability *OCR3CapabilitySession) SetConfig(_signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { +func (_OCR3Capability *OCR3CapabilitySession) SetConfig(_signers [][]byte, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { return _OCR3Capability.Contract.SetConfig(&_OCR3Capability.TransactOpts, _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) } -func (_OCR3Capability *OCR3CapabilityTransactorSession) SetConfig(_signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { +func (_OCR3Capability *OCR3CapabilityTransactorSession) SetConfig(_signers [][]byte, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { return _OCR3Capability.Contract.SetConfig(&_OCR3Capability.TransactOpts, _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) } @@ -335,18 +333,6 @@ func (_OCR3Capability *OCR3CapabilityTransactorSession) TransferOwnership(to com return _OCR3Capability.Contract.TransferOwnership(&_OCR3Capability.TransactOpts, to) } -func (_OCR3Capability *OCR3CapabilityTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { - return _OCR3Capability.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) -} - -func (_OCR3Capability *OCR3CapabilitySession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { - return _OCR3Capability.Contract.Transmit(&_OCR3Capability.TransactOpts, reportContext, report, rs, ss, rawVs) -} - -func (_OCR3Capability *OCR3CapabilityTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { - return _OCR3Capability.Contract.Transmit(&_OCR3Capability.TransactOpts, reportContext, report, rs, ss, rawVs) -} - type OCR3CapabilityConfigSetIterator struct { Event *OCR3CapabilityConfigSet @@ -411,7 +397,7 @@ type OCR3CapabilityConfigSet struct { PreviousConfigBlockNumber uint32 ConfigDigest [32]byte ConfigCount uint64 - Signers []common.Address + Signers [][]byte Transmitters []common.Address F uint8 OnchainConfig []byte @@ -890,7 +876,7 @@ func (_OCR3Capability *OCR3Capability) ParseLog(log types.Log) (generated.Abigen } func (OCR3CapabilityConfigSet) Topic() common.Hash { - return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") + return common.HexToHash("0x36257c6e8d535293ad661e377c0baac536289be6707b8a488ac175ddaa4055c8") } func (OCR3CapabilityOwnershipTransferRequested) Topic() common.Hash { @@ -920,18 +906,16 @@ type OCR3CapabilityInterface interface { Owner(opts *bind.CallOpts) (common.Address, error) - Transmitters(opts *bind.CallOpts) ([]common.Address, error) + Transmit(opts *bind.CallOpts, arg0 [3][32]byte, arg1 []byte, arg2 [][32]byte, arg3 [][32]byte, arg4 [32]byte) error TypeAndVersion(opts *bind.CallOpts) (string, error) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - SetConfig(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) + SetConfig(opts *bind.TransactOpts, _signers [][]byte, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) - FilterConfigSet(opts *bind.FilterOpts) (*OCR3CapabilityConfigSetIterator, error) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *OCR3CapabilityConfigSet) (event.Subscription, error) diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index d8b3b03042..6f9d3f2b3a 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -2,4 +2,4 @@ GETH_VERSION: 1.13.8 capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin cb3e79280a928979bc37de154b12b876996bdbe10f1827e683ee2bfa7a429a6c feeds_consumer: ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin 6ac5b12eff3b022a35c3c40d5ed0285bf9bfec0e3669a4b12307332a216048ca forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin 0da2ce239c9d4521005428f2d42a67dbee2ae6dd7160fd9e4f4322fb51d4f6ba -ocr3_capability: ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.bin 8bf0f53f222efce7143dea6134552eb26ea1eef845407b4475a0d79b7d7ba9f8 +ocr3_capability: ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.bin 2a6bfae30ccf38327fc7e78605a226839dfa0ce5a1a22e0414b91d24c35b3a53 diff --git a/core/scripts/keystone/src/88_gen_ocr3_config.go b/core/scripts/keystone/src/88_gen_ocr3_config.go index 1107df57ca..d9280ffe24 100644 --- a/core/scripts/keystone/src/88_gen_ocr3_config.go +++ b/core/scripts/keystone/src/88_gen_ocr3_config.go @@ -4,6 +4,7 @@ import ( "crypto/ed25519" "encoding/hex" "encoding/json" + "fmt" "time" "github.com/ethereum/go-ethereum/common" @@ -13,6 +14,7 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/types" helpers "github.com/smartcontractkit/chainlink/core/scripts/common" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) @@ -56,7 +58,7 @@ type NodeKeys struct { } type orc2drOracleConfig struct { - Signers []common.Address + Signers [][]byte Transmitters []common.Address F uint8 OnchainConfig []byte @@ -82,7 +84,7 @@ func (c orc2drOracleConfig) MarshalJSON() ([]byte, error) { } for i, signer := range c.Signers { - alias.Signers[i] = signer.Hex() + alias.Signers[i] = hex.EncodeToString(signer) } for i, transmitter := range c.Transmitters { @@ -101,9 +103,27 @@ func generateOCR3Config(nodeList string, configFile string, chainID int64, pubKe cfg := topLevelCfg.OracleConfig nca := downloadNodePubKeys(nodeList, chainID, pubKeysPath) - onchainPubKeys := []common.Address{} + onchainPubKeys := [][]byte{} + allPubKeys := map[string]any{} for _, n := range nca { - onchainPubKeys = append(onchainPubKeys, common.HexToAddress(n.OCR2OnchainPublicKey)) + ethPubKey := common.HexToAddress(n.OCR2OnchainPublicKey) + pubKeys := map[string]types.OnchainPublicKey{ + "evm": ethPubKey[:], + } + // validate uniqueness of each individual key + for _, key := range pubKeys { + raw := hex.EncodeToString(key) + _, exists := allPubKeys[raw] + if exists { + panic(fmt.Sprintf("Duplicate onchain public key: %v", raw)) + } + allPubKeys[raw] = struct{}{} + } + pubKey, err := ocrcommon.MarshalMultichainPublicKey(pubKeys) + if err != nil { + panic(err) + } + onchainPubKeys = append(onchainPubKeys, pubKey) } offchainPubKeysBytes := []types.OffchainPublicKey{} @@ -170,13 +190,16 @@ func generateOCR3Config(nodeList string, configFile string, chainID int64, pubKe ) helpers.PanicErr(err) - signerAddresses, err := evm.OnchainPublicKeyToAddress(signers) - PanicErr(err) + var configSigners [][]byte + for _, signer := range signers { + configSigners = append(configSigners, signer) + } + transmitterAddresses, err := evm.AccountToAddress(transmitters) PanicErr(err) config := orc2drOracleConfig{ - Signers: signerAddresses, + Signers: configSigners, Transmitters: transmitterAddresses, F: f, OnchainConfig: onchainConfig, diff --git a/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap b/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap index a4b4e6e302..b21c1549db 100755 --- a/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap +++ b/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap @@ -10,6 +10,7 @@ relay = "evm" [relayConfig] chainID = "11155111" +providerType = "ocr3-capability" Oracles: Oracle 0: @@ -37,8 +38,9 @@ providerType = "ocr3-capability" telemetryType = "plugin" [onchainSigningStrategy] -strategyName = 'single-chain' +strategyName = 'multi-chain' [onchainSigningStrategy.config] +evm = "b3df4d8748b67731a1112e8b45a764941974f5590c93672eebbc4f3504dd10ed" -------------------------------- Oracle 1: @@ -66,8 +68,9 @@ providerType = "ocr3-capability" telemetryType = "plugin" [onchainSigningStrategy] -strategyName = 'single-chain' +strategyName = 'multi-chain' [onchainSigningStrategy.config] +evm = "38459ae37f29f2c1fde0f25972a973322be8cada82acf43f464756836725be97" -------------------------------- Oracle 2: @@ -95,8 +98,9 @@ providerType = "ocr3-capability" telemetryType = "plugin" [onchainSigningStrategy] -strategyName = 'single-chain' +strategyName = 'multi-chain' [onchainSigningStrategy.config] +evm = "b5dbc4c9da983cddde2e3226b85807eb7beaf818694a22576af4d80f352702ed" -------------------------------- Oracle 3: @@ -124,8 +128,9 @@ providerType = "ocr3-capability" telemetryType = "plugin" [onchainSigningStrategy] -strategyName = 'single-chain' +strategyName = 'multi-chain' [onchainSigningStrategy.config] +evm = "260d5c1a618cdf5324509d7db95f5a117511864ebb9e1f709e8969339eb225af" --- diff --git a/core/scripts/keystone/src/__snapshots__/88_gen_ocr3_config_test.snap b/core/scripts/keystone/src/__snapshots__/88_gen_ocr3_config_test.snap index a2ecd236f7..b9581afb88 100755 --- a/core/scripts/keystone/src/__snapshots__/88_gen_ocr3_config_test.snap +++ b/core/scripts/keystone/src/__snapshots__/88_gen_ocr3_config_test.snap @@ -6,11 +6,11 @@ "OffchainConfigVersion": 30, "OnchainConfig": "0x", "Signers": [ - "0xA2402db8E549f094EA31e1C0EDd77623F4cA5b12", - "0x4af19c802B244D1d085492C3946391C965E10519", - "0x61925685d2B80b121537341d063c4E57B2F9323c", - "0xFd97eFD53FC20acc098Fcd746C04d8d7540D97E0", - "0xA0b67Dc5345a71D02B396147AE2cb75dDA63CbE9" + "011400a2402db8e549f094ea31e1c0edd77623f4ca5b12", + "0114004af19c802b244d1d085492c3946391c965e10519", + "01140061925685d2b80b121537341d063c4e57b2f9323c", + "011400fd97efd53fc20acc098fcd746c04d8d7540d97e0", + "011400a0b67dc5345a71d02b396147ae2cb75dda63cbe9" ], "Transmitters": [ "0xF4e7e516146c8567F8E8be0ED1f1A92798628d35", diff --git a/core/scripts/keystone/templates/bootstrap.toml b/core/scripts/keystone/templates/bootstrap.toml index 1baa43101b..cdd9065cab 100644 --- a/core/scripts/keystone/templates/bootstrap.toml +++ b/core/scripts/keystone/templates/bootstrap.toml @@ -6,3 +6,4 @@ relay = "evm" [relayConfig] chainID = "{{ chain_id }}" +providerType = "ocr3-capability" diff --git a/core/scripts/keystone/templates/oracle.toml b/core/scripts/keystone/templates/oracle.toml index 6049ad925d..c45e0fcb60 100644 --- a/core/scripts/keystone/templates/oracle.toml +++ b/core/scripts/keystone/templates/oracle.toml @@ -21,5 +21,6 @@ providerType = "ocr3-capability" telemetryType = "plugin" [onchainSigningStrategy] -strategyName = 'single-chain' +strategyName = 'multi-chain' [onchainSigningStrategy.config] +evm = "{{ ocr_key_bundle_id }}" diff --git a/core/services/keystore/chaintype/chaintype.go b/core/services/keystore/chaintype/chaintype.go index 8a12322ebf..419dfa2d07 100644 --- a/core/services/keystore/chaintype/chaintype.go +++ b/core/services/keystore/chaintype/chaintype.go @@ -36,6 +36,40 @@ func (c ChainTypes) String() (out string) { return sb.String() } +func NewChainType(typ uint8) (ChainType, error) { + switch typ { + case 1: + return EVM, nil + case 2: + return Solana, nil + case 3: + return Cosmos, nil + case 4: + return StarkNet, nil + case 5: + return Aptos, nil + default: + return "", fmt.Errorf("unexpected chaintype.ChainType: %#v", typ) + } +} + +func (c ChainType) Type() (uint8, error) { + switch c { + case EVM: + return 1, nil + case Solana: + return 2, nil + case Cosmos: + return 3, nil + case StarkNet: + return 4, nil + case Aptos: + return 5, nil + default: + return 0, fmt.Errorf("unexpected chaintype.ChainType: %#v", c) + } +} + // SupportedChainTypes contain all chains that are supported var SupportedChainTypes = ChainTypes{EVM, Cosmos, Solana, StarkNet, Aptos} diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 7bc3f47309..a6bb63b6c8 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -783,7 +783,7 @@ func (d *Delegate) newServicesGenericPlugin( } keyBundles[name] = os } - onchainKeyringAdapter, err = ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(keyBundles, kb.PublicKey(), lggr) + onchainKeyringAdapter, err = ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(keyBundles, lggr) if err != nil { return nil, err } diff --git a/core/services/ocrcommon/adapters.go b/core/services/ocrcommon/adapters.go index 53e62be9a0..b75a8a003c 100644 --- a/core/services/ocrcommon/adapters.go +++ b/core/services/ocrcommon/adapters.go @@ -1,8 +1,14 @@ package ocrcommon import ( + "bytes" + "cmp" "context" + "encoding/binary" "fmt" + "io" + "math" + "slices" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" @@ -11,6 +17,7 @@ import ( "google.golang.org/protobuf/types/known/structpb" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" ) @@ -81,16 +88,96 @@ func (c *OCR3ContractTransmitterAdapter) FromAccount() (ocrtypes.Account, error) var _ ocr3types.OnchainKeyring[[]byte] = (*OCR3OnchainKeyringMultiChainAdapter)(nil) +func MarshalMultichainKeyBundle(ost map[string]ocr2key.KeyBundle) (ocrtypes.OnchainPublicKey, error) { + pubKeys := map[string]ocrtypes.OnchainPublicKey{} + for k, b := range ost { + pubKeys[k] = []byte(b.PublicKey()) + } + return MarshalMultichainPublicKey(pubKeys) +} + +func MarshalMultichainPublicKey(ost map[string]ocrtypes.OnchainPublicKey) (ocrtypes.OnchainPublicKey, error) { + var pubKeys [][]byte + for k, pubKey := range ost { + typ, err := chaintype.ChainType(k).Type() + if err != nil { + // skipping unknown key type + continue + } + buf := new(bytes.Buffer) + if err = binary.Write(buf, binary.LittleEndian, typ); err != nil { + return nil, err + } + length := len(pubKey) + if length < 0 || length > math.MaxUint16 { + return nil, fmt.Errorf("pubKey doesn't fit into uint16") + } + if err = binary.Write(buf, binary.LittleEndian, uint16(length)); err != nil { //nolint:gosec + return nil, err + } + _, _ = buf.Write(pubKey) + pubKeys = append(pubKeys, buf.Bytes()) + } + // sort keys based on encoded type to make encoding deterministic + slices.SortFunc(pubKeys, func(a, b []byte) int { return cmp.Compare(a[0], b[0]) }) + return bytes.Join(pubKeys, nil), nil +} + +func UnmarshalMultichainPublicKey(d []byte) (map[string]ocrtypes.OnchainPublicKey, error) { + m := map[string]ocrtypes.OnchainPublicKey{} + buf := bytes.NewReader(d) + + for { + // type + typ, err := buf.ReadByte() + if err != nil { + return nil, err + } + // length + var length uint16 + err = binary.Read(buf, binary.LittleEndian, &length) + if err != nil { + return nil, err + } + // value + pubKey := make([]byte, length) + n, err := buf.Read(pubKey) + if err != nil { + return nil, err + } + if n != int(length) { + return nil, io.EOF + } + + k, err := chaintype.NewChainType(typ) + if err != nil { + // skipping unknown key type + continue + } + m[string(k)] = pubKey + + if buf.Len() == 0 { + break + } + } + + return m, nil +} + type OCR3OnchainKeyringMultiChainAdapter struct { keyBundles map[string]ocr2key.KeyBundle publicKey ocrtypes.OnchainPublicKey lggr logger.Logger } -func NewOCR3OnchainKeyringMultiChainAdapter(ost map[string]ocr2key.KeyBundle, publicKey ocrtypes.OnchainPublicKey, lggr logger.Logger) (*OCR3OnchainKeyringMultiChainAdapter, error) { +func NewOCR3OnchainKeyringMultiChainAdapter(ost map[string]ocr2key.KeyBundle, lggr logger.Logger) (*OCR3OnchainKeyringMultiChainAdapter, error) { if len(ost) == 0 { return nil, errors.New("no key bundles provided") } + publicKey, err := MarshalMultichainKeyBundle(ost) + if err != nil { + return nil, err + } return &OCR3OnchainKeyringMultiChainAdapter{ost, publicKey, lggr}, nil } @@ -98,30 +185,30 @@ func (a *OCR3OnchainKeyringMultiChainAdapter) PublicKey() ocrtypes.OnchainPublic return a.publicKey } -func (a *OCR3OnchainKeyringMultiChainAdapter) getKeyBundleFromInfo(info []byte) (ocr2key.KeyBundle, error) { +func (a *OCR3OnchainKeyringMultiChainAdapter) getKeyBundleFromInfo(info []byte) (string, ocr2key.KeyBundle, error) { unmarshalledInfo := new(structpb.Struct) err := proto.Unmarshal(info, unmarshalledInfo) if err != nil { - return nil, fmt.Errorf("failed to unmarshal report info: %v", err) + return "", nil, fmt.Errorf("failed to unmarshal report info: %v", err) } infoMap := unmarshalledInfo.AsMap() keyBundleName, ok := infoMap["keyBundleName"] if !ok { - return nil, errors.New("keyBundleName not found in report info") + return "", nil, errors.New("keyBundleName not found in report info") } name, ok := keyBundleName.(string) if !ok { - return nil, errors.New("keyBundleName is not a string") + return "", nil, errors.New("keyBundleName is not a string") } kb, ok := a.keyBundles[name] if !ok { - return nil, fmt.Errorf("keyBundle not found: %s", name) + return "", nil, fmt.Errorf("keyBundle not found: %s", name) } - return kb, nil + return name, kb, nil } func (a *OCR3OnchainKeyringMultiChainAdapter) Sign(digest ocrtypes.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[[]byte]) (signature []byte, err error) { - kb, err := a.getKeyBundleFromInfo(r.Info) + _, kb, err := a.getKeyBundleFromInfo(r.Info) if err != nil { return nil, fmt.Errorf("sign: failed to get key bundle from report info: %v", err) } @@ -136,12 +223,22 @@ func (a *OCR3OnchainKeyringMultiChainAdapter) Sign(digest ocrtypes.ConfigDigest, } func (a *OCR3OnchainKeyringMultiChainAdapter) Verify(opk ocrtypes.OnchainPublicKey, digest ocrtypes.ConfigDigest, seqNr uint64, ri ocr3types.ReportWithInfo[[]byte], signature []byte) bool { - kb, err := a.getKeyBundleFromInfo(ri.Info) + kbName, kb, err := a.getKeyBundleFromInfo(ri.Info) if err != nil { a.lggr.Warnf("verify: failed to get key bundle from report info: %v", err) return false } - return kb.Verify(opk, ocrtypes.ReportContext{ + keys, err := UnmarshalMultichainPublicKey(opk) + if err != nil { + a.lggr.Warnf("verify: failed to unmarshal public keys: %v", err) + return false + } + publicKey, ok := keys[kbName] + if !ok { + a.lggr.Warnf("verify: publicKey not found: %v", kbName) + return false + } + return kb.Verify(publicKey, ocrtypes.ReportContext{ ReportTimestamp: ocrtypes.ReportTimestamp{ ConfigDigest: digest, Epoch: uint32(seqNr), diff --git a/core/services/ocrcommon/adapters_test.go b/core/services/ocrcommon/adapters_test.go index e7d4562729..fddfb297ec 100644 --- a/core/services/ocrcommon/adapters_test.go +++ b/core/services/ocrcommon/adapters_test.go @@ -2,25 +2,23 @@ package ocrcommon_test import ( "context" - "encoding/json" "fmt" + "math" "reflect" "testing" - "github.com/pelletier/go-toml" "github.com/smartcontractkit/libocr/offchainreporting2/types" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/structpb" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/keystest" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" - keystoreMocks "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" ) @@ -115,63 +113,116 @@ func TestOCR3OnchainKeyringAdapter(t *testing.T) { require.Equal(t, maxSignatureLength, kr.MaxSignatureLength()) } -type envelope struct { - OnchainSigningStrategy *validate.OCR2OnchainSigningStrategy -} - func TestNewOCR3OnchainKeyringMultiChainAdapter(t *testing.T) { - payload := ` -[onchainSigningStrategy] -strategyName = "single-chain" -[onchainSigningStrategy.config] -evm = "08d14c6eed757414d72055d28de6caf06535806c6a14e450f3a2f1c854420e17" -publicKey = "pub-key" -` - oss := &envelope{} - tree, err := toml.Load(payload) - require.NoError(t, err) - o := map[string]any{} - err = tree.Unmarshal(&o) + evmBundle, err := ocr2key.New(chaintype.EVM) require.NoError(t, err) - b, err := json.Marshal(o) - require.NoError(t, err) - err = json.Unmarshal(b, oss) + + aptosBundle, err := ocr2key.New(chaintype.Aptos) require.NoError(t, err) - reportInfo := ocr3types.ReportWithInfo[[]byte]{ - Report: []byte("multi-chain-report"), + + bundles := map[string]ocr2key.KeyBundle{ + "evm": evmBundle, + "aptos": aptosBundle, } - info, err := structpb.NewStruct(map[string]interface{}{ + adapter, err := ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(bundles, logger.TestLogger(t)) + require.NoError(t, err) + + maxLength := math.Max(float64(evmBundle.MaxSignatureLength()), float64(aptosBundle.MaxSignatureLength())) + assert.Equal(t, int(maxLength), adapter.MaxSignatureLength()) + + // evm signature + info, err := structpb.NewStruct(map[string]any{ "keyBundleName": "evm", }) require.NoError(t, err) - infoB, err := proto.Marshal(info) + + infob, err := proto.Marshal(info) require.NoError(t, err) - reportInfo.Info = infoB + r := ocr3types.ReportWithInfo[[]byte]{ + Report: []byte("report"), + Info: infob, + } - ks := keystoreMocks.NewOCR2(t) - fakeKey := ocr2key.MustNewInsecure(keystest.NewRandReaderFromSeed(1), "evm") - pk := fakeKey.PublicKey() - ks.On("Get", "pub-key").Return(fakeKey, nil) - ks.On("Get", "08d14c6eed757414d72055d28de6caf06535806c6a14e450f3a2f1c854420e17").Return(fakeKey, nil) - keyBundles := map[string]ocr2key.KeyBundle{} - for name := range oss.OnchainSigningStrategy.ConfigCopy() { - kbID, ostErr := oss.OnchainSigningStrategy.KeyBundleID(name) - require.NoError(t, ostErr) - os, ostErr := ks.Get(kbID) - require.NoError(t, ostErr) - keyBundles[name] = os + sig, err := adapter.Sign(configDigest, seqNr, r) + require.NoError(t, err) + assert.True(t, adapter.Verify(adapter.PublicKey(), configDigest, seqNr, r, sig)) + + // aptos signature + info, err = structpb.NewStruct(map[string]any{ + "keyBundleName": "aptos", + }) + require.NoError(t, err) + + infob, err = proto.Marshal(info) + require.NoError(t, err) + r = ocr3types.ReportWithInfo[[]byte]{ + Report: []byte("report"), + Info: infob, } - adapter, err := ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(keyBundles, pk, logger.TestLogger(t)) + sig, err = adapter.Sign(configDigest, seqNr, r) require.NoError(t, err) - _, err = ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(map[string]ocr2key.KeyBundle{}, pk, logger.TestLogger(t)) + assert.True(t, adapter.Verify(adapter.PublicKey(), configDigest, seqNr, r, sig)) + + // no bundles + _, err = ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(map[string]ocr2key.KeyBundle{}, logger.TestLogger(t)) require.Error(t, err, "no key bundles provided") +} + +func newMultichainAdapter(t *testing.T) *ocrcommon.OCR3OnchainKeyringMultiChainAdapter { + evmBundle, err := ocr2key.New(chaintype.EVM) + require.NoError(t, err) + + aptosBundle, err := ocr2key.New(chaintype.Aptos) + require.NoError(t, err) + + bundles := map[string]ocr2key.KeyBundle{ + "evm": evmBundle, + "aptos": aptosBundle, + } + adapter, err := ocrcommon.NewOCR3OnchainKeyringMultiChainAdapter(bundles, logger.TestLogger(t)) + require.NoError(t, err) + + return adapter +} + +func TestNewOCR3OnchainKeyringMultiChainAdapter_VerifyFromDifferentNodesPublicKeys(t *testing.T) { + firstNodeAdapter := newMultichainAdapter(t) + secondNodeAdapter := newMultichainAdapter(t) - sig, err := adapter.Sign(configDigest, seqNr, reportInfo) - assert.NoError(t, err) - assert.True(t, adapter.Verify(pk, configDigest, seqNr, reportInfo, sig)) - assert.Equal(t, pk, adapter.PublicKey()) - assert.Equal(t, fakeKey.MaxSignatureLength(), adapter.MaxSignatureLength()) + // evm signature + info, err := structpb.NewStruct(map[string]any{ + "keyBundleName": "evm", + }) + require.NoError(t, err) + + infob, err := proto.Marshal(info) + require.NoError(t, err) + r := ocr3types.ReportWithInfo[[]byte]{ + Report: []byte("report"), + Info: infob, + } + + sig, err := firstNodeAdapter.Sign(configDigest, seqNr, r) + require.NoError(t, err) + assert.True(t, secondNodeAdapter.Verify(firstNodeAdapter.PublicKey(), configDigest, seqNr, r, sig)) + + // aptos signature + info, err = structpb.NewStruct(map[string]any{ + "keyBundleName": "aptos", + }) + require.NoError(t, err) + + infob, err = proto.Marshal(info) + require.NoError(t, err) + r = ocr3types.ReportWithInfo[[]byte]{ + Report: []byte("report"), + Info: infob, + } + + sig, err = secondNodeAdapter.Sign(configDigest, seqNr, r) + require.NoError(t, err) + assert.True(t, firstNodeAdapter.Verify(secondNodeAdapter.PublicKey(), configDigest, seqNr, r, sig)) } var _ ocrtypes.ContractTransmitter = (*fakeContractTransmitter)(nil) diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 579e8b6788..880ad73ad2 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -65,6 +65,7 @@ import ( var ( OCR2AggregatorTransmissionContractABI abi.ABI OCR2AggregatorLogDecoder LogDecoder + OCR3CapabilityLogDecoder LogDecoder ) func init() { @@ -77,6 +78,10 @@ func init() { if err != nil { panic(err) } + OCR3CapabilityLogDecoder, err = newOCR3CapabilityLogDecoder() + if err != nil { + panic(err) + } } var _ commontypes.Relayer = &Relayer{} //nolint:staticcheck @@ -256,12 +261,57 @@ func (r *Relayer) HealthReport() (report map[string]error) { return } +func newOCR3CapabilityConfigProvider(ctx context.Context, lggr logger.Logger, chain legacyevm.Chain, opts *types.RelayOpts) (*configWatcher, error) { + if !common.IsHexAddress(opts.ContractID) { + return nil, errors.New("invalid contractID, expected hex address") + } + + aggregatorAddress := common.HexToAddress(opts.ContractID) + offchainConfigDigester := OCR3CapabilityOffchainConfigDigester{ + ChainID: chain.Config().EVM().ChainID().Uint64(), + ContractAddress: aggregatorAddress, + } + return newContractConfigProvider(ctx, lggr, chain, opts, aggregatorAddress, OCR3CapabilityLogDecoder, offchainConfigDigester) +} + +// NewPluginProvider, but customized to use a different config provider func (r *Relayer) NewOCR3CapabilityProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.OCR3CapabilityProvider, error) { - pp, err := r.NewPluginProvider(rargs, pargs) + // TODO https://smartcontract-it.atlassian.net/browse/BCF-2887 + ctx := context.Background() + lggr := logger.Sugared(r.lggr).Named("PluginProvider").Named(rargs.ExternalJobID.String()) + relayOpts := types.NewRelayOpts(rargs) + relayConfig, err := relayOpts.RelayConfig() + if err != nil { + return nil, fmt.Errorf("failed to get relay config: %w", err) + } + + configWatcher, err := newOCR3CapabilityConfigProvider(ctx, r.lggr, r.chain, relayOpts) + if err != nil { + return nil, err + } + + transmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, r.ks.Eth(), configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) if err != nil { return nil, err } + var chainReaderService ChainReaderService + if relayConfig.ChainReader != nil { + if chainReaderService, err = NewChainReaderService(ctx, lggr, r.chain.LogPoller(), r.chain.HeadTracker(), r.chain.Client(), *relayConfig.ChainReader); err != nil { + return nil, err + } + } else { + lggr.Info("ChainReader missing from RelayConfig") + } + + pp := NewPluginProvider( + chainReaderService, + r.codec, + transmitter, + configWatcher, + lggr, + ) + fromAccount, err := pp.ContractTransmitter().FromAccount() if err != nil { return nil, err @@ -520,6 +570,8 @@ func (r *Relayer) NewConfigProvider(args commontypes.RelayArgs) (configProvider configProvider, err = newMercuryConfigProvider(ctx, lggr, r.chain, relayOpts) case "llo": configProvider, err = newLLOConfigProvider(ctx, lggr, r.chain, relayOpts) + case "ocr3-capability": + configProvider, err = newOCR3CapabilityConfigProvider(ctx, r.lggr, r.chain, relayOpts) default: return nil, fmt.Errorf("unrecognized provider type: %q", args.ProviderType) } diff --git a/core/services/relay/evm/ocr3_capability_provider.go b/core/services/relay/evm/ocr3_capability_provider.go index 2080e1df87..ca41466570 100644 --- a/core/services/relay/evm/ocr3_capability_provider.go +++ b/core/services/relay/evm/ocr3_capability_provider.go @@ -1,9 +1,23 @@ package evm import ( + "encoding/hex" + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink-common/pkg/types" + + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/crypto" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/ocr3_capability" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" ) type ocr3CapabilityProvider struct { @@ -14,3 +28,181 @@ type ocr3CapabilityProvider struct { func (o *ocr3CapabilityProvider) OCR3ContractTransmitter() ocr3types.ContractTransmitter[[]byte] { return o.transmitter } + +var _ LogDecoder = &ocr3CapabilityLogDecoder{} + +type ocr3CapabilityLogDecoder struct { + eventName string + eventSig common.Hash + abi *abi.ABI +} + +// Modified newOCR2AggregatorLogDecoder to use OCR3Capability ABI +func newOCR3CapabilityLogDecoder() (*ocr3CapabilityLogDecoder, error) { + const eventName = "ConfigSet" + abi, err := ocr3_capability.OCR3CapabilityMetaData.GetAbi() + if err != nil { + return nil, err + } + return &ocr3CapabilityLogDecoder{ + eventName: eventName, + eventSig: abi.Events[eventName].ID, + abi: abi, + }, nil +} + +func (d *ocr3CapabilityLogDecoder) Decode(rawLog []byte) (ocrtypes.ContractConfig, error) { + unpacked := new(ocr3_capability.OCR3CapabilityConfigSet) + err := d.abi.UnpackIntoInterface(unpacked, d.eventName, rawLog) + if err != nil { + return ocrtypes.ContractConfig{}, fmt.Errorf("failed to unpack log data: %w", err) + } + + var transmitAccounts []ocrtypes.Account + for _, addr := range unpacked.Transmitters { + transmitAccounts = append(transmitAccounts, ocrtypes.Account(addr.Hex())) + } + var signers []ocrtypes.OnchainPublicKey + allPubKeys := map[string]any{} + for _, pubKey := range unpacked.Signers { + pubKey := pubKey + + // validate uniqueness of each individual key + pubKeys, err := ocrcommon.UnmarshalMultichainPublicKey(pubKey) + if err != nil { + return ocrtypes.ContractConfig{}, err + } + for _, key := range pubKeys { + raw := hex.EncodeToString(key) + _, exists := allPubKeys[raw] + if exists { + return ocrtypes.ContractConfig{}, fmt.Errorf("Duplicate onchain public key: %v", raw) + } + allPubKeys[raw] = struct{}{} + } + + signers = append(signers, pubKey[:]) + } + + return ocrtypes.ContractConfig{ + ConfigDigest: unpacked.ConfigDigest, + ConfigCount: unpacked.ConfigCount, + Signers: signers, + Transmitters: transmitAccounts, + F: unpacked.F, + OnchainConfig: unpacked.OnchainConfig, + OffchainConfigVersion: unpacked.OffchainConfigVersion, + OffchainConfig: unpacked.OffchainConfig, + }, nil +} + +func (d *ocr3CapabilityLogDecoder) EventSig() common.Hash { + return d.eventSig +} + +var _ ocrtypes.OffchainConfigDigester = OCR3CapabilityOffchainConfigDigester{} + +// EVMOffchainConfigDigester forked to not assume signers are 20 byte addresses +type OCR3CapabilityOffchainConfigDigester struct { + ChainID uint64 + ContractAddress common.Address +} + +func (d OCR3CapabilityOffchainConfigDigester) ConfigDigest(cc ocrtypes.ContractConfig) (ocrtypes.ConfigDigest, error) { + signers := [][]byte{} + for _, signer := range cc.Signers { + signers = append(signers, signer) + } + transmitters := []common.Address{} + for i, transmitter := range cc.Transmitters { + if !strings.HasPrefix(string(transmitter), "0x") || len(transmitter) != 42 || !common.IsHexAddress(string(transmitter)) { + return ocrtypes.ConfigDigest{}, fmt.Errorf("%v-th evm transmitter should be a 42 character Ethereum address string, but got '%v'", i, transmitter) + } + a := common.HexToAddress(string(transmitter)) + transmitters = append(transmitters, a) + } + + return ocr3CapabilityConfigDigest( + d.ChainID, + d.ContractAddress, + cc.ConfigCount, + signers, + transmitters, + cc.F, + cc.OnchainConfig, + cc.OffchainConfigVersion, + cc.OffchainConfig, + ), nil +} + +const ConfigDigestPrefixKeystoneOCR3Capability ocrtypes.ConfigDigestPrefix = 0x000e + +func (d OCR3CapabilityOffchainConfigDigester) ConfigDigestPrefix() (ocrtypes.ConfigDigestPrefix, error) { + return ConfigDigestPrefixKeystoneOCR3Capability, nil +} + +func makeOCR3CapabilityConfigDigestArgs() abi.Arguments { + mustNewType := func(t string) abi.Type { + result, err := abi.NewType(t, "", []abi.ArgumentMarshaling{}) + if err != nil { + panic(fmt.Sprintf("Unexpected error during abi.NewType: %s", err)) + } + return result + } + return abi.Arguments([]abi.Argument{ + {Name: "chainId", Type: mustNewType("uint256")}, + {Name: "contractAddress", Type: mustNewType("address")}, + {Name: "configCount", Type: mustNewType("uint64")}, + {Name: "signers", Type: mustNewType("bytes[]")}, + {Name: "transmitters", Type: mustNewType("address[]")}, + {Name: "f", Type: mustNewType("uint8")}, + {Name: "onchainConfig", Type: mustNewType("bytes")}, + {Name: "encodedConfigVersion", Type: mustNewType("uint64")}, + {Name: "encodedConfig", Type: mustNewType("bytes")}, + }) +} + +var ocr3CapabilityConfigDigestArgs = makeOCR3CapabilityConfigDigestArgs() + +func ocr3CapabilityConfigDigest( + chainID uint64, + contractAddress common.Address, + configCount uint64, + oracles [][]byte, + transmitters []common.Address, + f uint8, + onchainConfig []byte, + offchainConfigVersion uint64, + offchainConfig []byte, +) ocrtypes.ConfigDigest { + chainIDBig := new(big.Int) + chainIDBig.SetUint64(chainID) + msg, err := ocr3CapabilityConfigDigestArgs.Pack( + chainIDBig, + contractAddress, + configCount, + oracles, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + ) + if err != nil { + // assertion + panic(err) + } + rawHash := crypto.Keccak256(msg) + configDigest := ocrtypes.ConfigDigest{} + if n := copy(configDigest[:], rawHash); n != len(configDigest) { + // assertion + panic("copy too little data") + } + if ConfigDigestPrefixKeystoneOCR3Capability != 0x000e { + // assertion + panic("wrong ConfigDigestPrefix") + } + configDigest[0] = 0 + configDigest[1] = 0x0e + return configDigest +} From 52b480fcc53bf0162cb3aa04cc13f946babb643a Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Tue, 17 Sep 2024 07:56:54 -0700 Subject: [PATCH 361/432] [KS-365] Batch identical trigger events (#14398) If multiple workflows need to receive the same trigger event, send it only once. --- .changeset/stale-falcons-train.md | 5 + core/capabilities/launcher.go | 11 +- core/capabilities/remote/trigger_publisher.go | 181 +++++++++++++----- .../remote/trigger_publisher_test.go | 139 +++++++++++--- core/capabilities/remote/types/types.go | 5 + 5 files changed, 254 insertions(+), 87 deletions(-) create mode 100644 .changeset/stale-falcons-train.md diff --git a/.changeset/stale-falcons-train.md b/.changeset/stale-falcons-train.md new file mode 100644 index 0000000000..ddaa0907f8 --- /dev/null +++ b/.changeset/stale-falcons-train.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added [Keystone] Batch identical trigger events diff --git a/core/capabilities/launcher.go b/core/capabilities/launcher.go index 03a1dd54f0..f2bfd5e4b1 100644 --- a/core/capabilities/launcher.go +++ b/core/capabilities/launcher.go @@ -394,7 +394,7 @@ func (w *launcher) exposeCapabilities(ctx context.Context, myPeerID p2ptypes.Pee switch capability.CapabilityType { case capabilities.CapabilityTypeTrigger: - newTriggerPublisher := func(capability capabilities.BaseCapability, info capabilities.CapabilityInfo) (receiverService, error) { + newTriggerPublisher := func(capability capabilities.BaseCapability, info capabilities.CapabilityInfo) (remotetypes.ReceiverService, error) { publisher := remote.NewTriggerPublisher( capabilityConfig.RemoteTriggerConfig, capability.(capabilities.TriggerCapability), @@ -416,7 +416,7 @@ func (w *launcher) exposeCapabilities(ctx context.Context, myPeerID p2ptypes.Pee case capabilities.CapabilityTypeConsensus: w.lggr.Warn("no remote client configured for capability type consensus, skipping configuration") case capabilities.CapabilityTypeTarget: - newTargetServer := func(capability capabilities.BaseCapability, info capabilities.CapabilityInfo) (receiverService, error) { + newTargetServer := func(capability capabilities.BaseCapability, info capabilities.CapabilityInfo) (remotetypes.ReceiverService, error) { return target.NewServer( capabilityConfig.RemoteTargetConfig, myPeerID, @@ -441,12 +441,7 @@ func (w *launcher) exposeCapabilities(ctx context.Context, myPeerID p2ptypes.Pee return nil } -type receiverService interface { - services.Service - remotetypes.Receiver -} - -func (w *launcher) addReceiver(ctx context.Context, capability registrysyncer.Capability, don registrysyncer.DON, newReceiverFn func(capability capabilities.BaseCapability, info capabilities.CapabilityInfo) (receiverService, error)) error { +func (w *launcher) addReceiver(ctx context.Context, capability registrysyncer.Capability, don registrysyncer.DON, newReceiverFn func(capability capabilities.BaseCapability, info capabilities.CapabilityInfo) (remotetypes.ReceiverService, error)) error { capID := capability.ID info, err := capabilities.NewRemoteCapabilityInfo( capID, diff --git a/core/capabilities/remote/trigger_publisher.go b/core/capabilities/remote/trigger_publisher.go index c5b4e84185..e5a46c8791 100644 --- a/core/capabilities/remote/trigger_publisher.go +++ b/core/capabilities/remote/trigger_publisher.go @@ -2,10 +2,11 @@ package remote import ( "context" + "crypto/sha256" + "encoding/binary" "sync" "time" - "github.com/smartcontractkit/chainlink-common/pkg/capabilities" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/services" @@ -22,19 +23,22 @@ import ( // // TriggerPublisher communicates with corresponding TriggerSubscribers on remote nodes. type triggerPublisher struct { - config *capabilities.RemoteTriggerConfig - underlying commoncap.TriggerCapability - capInfo commoncap.CapabilityInfo - capDonInfo commoncap.DON - workflowDONs map[uint32]commoncap.DON - membersCache map[uint32]map[p2ptypes.PeerID]bool - dispatcher types.Dispatcher - messageCache *messageCache[registrationKey, p2ptypes.PeerID] - registrations map[registrationKey]*pubRegState - mu sync.RWMutex // protects messageCache and registrations - stopCh services.StopChan - wg sync.WaitGroup - lggr logger.Logger + config *commoncap.RemoteTriggerConfig + underlying commoncap.TriggerCapability + capInfo commoncap.CapabilityInfo + capDonInfo commoncap.DON + workflowDONs map[uint32]commoncap.DON + membersCache map[uint32]map[p2ptypes.PeerID]bool + dispatcher types.Dispatcher + messageCache *messageCache[registrationKey, p2ptypes.PeerID] + registrations map[registrationKey]*pubRegState + mu sync.RWMutex // protects messageCache and registrations + batchingQueue map[[32]byte]*batchedResponse + batchingEnabled bool + bqMu sync.Mutex // protects batchingQueue + stopCh services.StopChan + wg sync.WaitGroup + lggr logger.Logger } type registrationKey struct { @@ -47,13 +51,21 @@ type pubRegState struct { request commoncap.TriggerRegistrationRequest } -var _ types.Receiver = &triggerPublisher{} -var _ services.Service = &triggerPublisher{} +type batchedResponse struct { + rawResponse []byte + callerDonID uint32 + triggerEventID string + workflowIDs []string +} + +var _ types.ReceiverService = &triggerPublisher{} -func NewTriggerPublisher(config *capabilities.RemoteTriggerConfig, underlying commoncap.TriggerCapability, capInfo commoncap.CapabilityInfo, capDonInfo commoncap.DON, workflowDONs map[uint32]commoncap.DON, dispatcher types.Dispatcher, lggr logger.Logger) *triggerPublisher { +const minAllowedBatchCollectionPeriod = 10 * time.Millisecond + +func NewTriggerPublisher(config *commoncap.RemoteTriggerConfig, underlying commoncap.TriggerCapability, capInfo commoncap.CapabilityInfo, capDonInfo commoncap.DON, workflowDONs map[uint32]commoncap.DON, dispatcher types.Dispatcher, lggr logger.Logger) *triggerPublisher { if config == nil { lggr.Info("no config provided, using default values") - config = &capabilities.RemoteTriggerConfig{} + config = &commoncap.RemoteTriggerConfig{} } config.ApplyDefaults() membersCache := make(map[uint32]map[p2ptypes.PeerID]bool) @@ -65,23 +77,29 @@ func NewTriggerPublisher(config *capabilities.RemoteTriggerConfig, underlying co membersCache[id] = cache } return &triggerPublisher{ - config: config, - underlying: underlying, - capInfo: capInfo, - capDonInfo: capDonInfo, - workflowDONs: workflowDONs, - membersCache: membersCache, - dispatcher: dispatcher, - messageCache: NewMessageCache[registrationKey, p2ptypes.PeerID](), - registrations: make(map[registrationKey]*pubRegState), - stopCh: make(services.StopChan), - lggr: lggr.Named("TriggerPublisher"), + config: config, + underlying: underlying, + capInfo: capInfo, + capDonInfo: capDonInfo, + workflowDONs: workflowDONs, + membersCache: membersCache, + dispatcher: dispatcher, + messageCache: NewMessageCache[registrationKey, p2ptypes.PeerID](), + registrations: make(map[registrationKey]*pubRegState), + batchingQueue: make(map[[32]byte]*batchedResponse), + batchingEnabled: config.MaxBatchSize > 1 && config.BatchCollectionPeriod >= minAllowedBatchCollectionPeriod, + stopCh: make(services.StopChan), + lggr: lggr.Named("TriggerPublisher"), } } func (p *triggerPublisher) Start(ctx context.Context) error { p.wg.Add(1) go p.registrationCleanupLoop() + if p.batchingEnabled { + p.wg.Add(1) + go p.batchingLoop() + } p.lggr.Info("TriggerPublisher started") return nil } @@ -202,31 +220,98 @@ func (p *triggerPublisher) triggerEventLoop(callbackCh <-chan commoncap.TriggerR } triggerEvent := response.Event p.lggr.Debugw("received trigger event", "capabilityId", p.capInfo.ID, "workflowId", key.workflowId, "triggerEventID", triggerEvent.ID) - marshaled, err := pb.MarshalTriggerResponse(response) + marshaledResponse, err := pb.MarshalTriggerResponse(response) if err != nil { p.lggr.Debugw("can't marshal trigger event", "err", err) break } - msg := &types.MessageBody{ - CapabilityId: p.capInfo.ID, - CapabilityDonId: p.capDonInfo.ID, - CallerDonId: key.callerDonId, - Method: types.MethodTriggerEvent, - Payload: marshaled, - Metadata: &types.MessageBody_TriggerEventMetadata{ - TriggerEventMetadata: &types.TriggerEventMetadata{ - // NOTE: optionally introduce batching across workflows as an optimization - WorkflowIds: []string{key.workflowId}, - TriggerEventId: triggerEvent.ID, - }, + + if p.batchingEnabled { + p.enqueueForBatching(marshaledResponse, key, triggerEvent.ID) + } else { + // a single-element "batch" + p.sendBatch(&batchedResponse{ + rawResponse: marshaledResponse, + callerDonID: key.callerDonId, + triggerEventID: triggerEvent.ID, + workflowIDs: []string{key.workflowId}, + }) + } + } + } +} + +func (p *triggerPublisher) enqueueForBatching(rawResponse []byte, key registrationKey, triggerEventID string) { + // put in batching queue, group by hash(callerDonId, triggerEventID, response) + combined := make([]byte, 4) + binary.LittleEndian.PutUint32(combined, key.callerDonId) + combined = append(combined, []byte(triggerEventID)...) + combined = append(combined, rawResponse...) + sha := sha256.Sum256(combined) + p.bqMu.Lock() + elem, exists := p.batchingQueue[sha] + if !exists { + elem = &batchedResponse{ + rawResponse: rawResponse, + callerDonID: key.callerDonId, + triggerEventID: triggerEventID, + workflowIDs: []string{key.workflowId}, + } + p.batchingQueue[sha] = elem + } else { + elem.workflowIDs = append(elem.workflowIDs, key.workflowId) + } + p.bqMu.Unlock() +} + +func (p *triggerPublisher) sendBatch(resp *batchedResponse) { + for len(resp.workflowIDs) > 0 { + idBatch := resp.workflowIDs + if p.batchingEnabled && int64(len(idBatch)) > int64(p.config.MaxBatchSize) { + idBatch = idBatch[:p.config.MaxBatchSize] + resp.workflowIDs = resp.workflowIDs[p.config.MaxBatchSize:] + } else { + resp.workflowIDs = nil + } + msg := &types.MessageBody{ + CapabilityId: p.capInfo.ID, + CapabilityDonId: p.capDonInfo.ID, + CallerDonId: resp.callerDonID, + Method: types.MethodTriggerEvent, + Payload: resp.rawResponse, + Metadata: &types.MessageBody_TriggerEventMetadata{ + TriggerEventMetadata: &types.TriggerEventMetadata{ + WorkflowIds: idBatch, + TriggerEventId: resp.triggerEventID, }, + }, + } + // NOTE: send to all nodes by default, introduce different strategies later (KS-76) + for _, peerID := range p.workflowDONs[resp.callerDonID].Members { + err := p.dispatcher.Send(peerID, msg) + if err != nil { + p.lggr.Errorw("failed to send trigger event", "capabilityId", p.capInfo.ID, "peerID", peerID, "err", err) } - // NOTE: send to all nodes by default, introduce different strategies later (KS-76) - for _, peerID := range p.workflowDONs[key.callerDonId].Members { - err = p.dispatcher.Send(peerID, msg) - if err != nil { - p.lggr.Errorw("failed to send trigger event", "capabilityId", p.capInfo.ID, "peerID", peerID, "err", err) - } + } + } +} + +func (p *triggerPublisher) batchingLoop() { + defer p.wg.Done() + ticker := time.NewTicker(p.config.BatchCollectionPeriod) + defer ticker.Stop() + for { + select { + case <-p.stopCh: + return + case <-ticker.C: + p.bqMu.Lock() + queue := p.batchingQueue + p.batchingQueue = make(map[[32]byte]*batchedResponse) + p.bqMu.Unlock() + + for _, elem := range queue { + p.sendBatch(elem) } } } diff --git a/core/capabilities/remote/trigger_publisher_test.go b/core/capabilities/remote/trigger_publisher_test.go index bcc79b4fbb..8d078dc1aa 100644 --- a/core/capabilities/remote/trigger_publisher_test.go +++ b/core/capabilities/remote/trigger_publisher_test.go @@ -5,47 +5,130 @@ import ( "testing" "time" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" - remoteMocks "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types/mocks" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) +const capID = "cap_id@1" + func TestTriggerPublisher_Register(t *testing.T) { + ctx := testutils.Context(t) + capabilityDONID, workflowDONID := uint32(1), uint32(2) + + underlyingTriggerCap, publisher, _, peers := newServices(t, capabilityDONID, workflowDONID, 1) + + // invalid sender case - node 0 is not a member of the workflow DON, registration shoudn't happen + regEvent := newRegisterTriggerMessage(t, workflowDONID, peers[0]) + publisher.Receive(ctx, regEvent) + require.Empty(t, underlyingTriggerCap.registrationsCh) + + // valid registration + regEvent = newRegisterTriggerMessage(t, workflowDONID, peers[1]) + publisher.Receive(ctx, regEvent) + require.NotEmpty(t, underlyingTriggerCap.registrationsCh) + forwarded := <-underlyingTriggerCap.registrationsCh + require.Equal(t, workflowID1, forwarded.Metadata.WorkflowID) + + require.NoError(t, publisher.Close()) +} + +func TestTriggerPublisher_ReceiveTriggerEvents_NoBatching(t *testing.T) { + ctx := testutils.Context(t) + capabilityDONID, workflowDONID := uint32(1), uint32(2) + + underlyingTriggerCap, publisher, dispatcher, peers := newServices(t, capabilityDONID, workflowDONID, 1) + regEvent := newRegisterTriggerMessage(t, workflowDONID, peers[1]) + publisher.Receive(ctx, regEvent) + require.NotEmpty(t, underlyingTriggerCap.registrationsCh) + + // send a trigger event and expect that it gets delivered right away + underlyingTriggerCap.eventCh <- commoncap.TriggerResponse{} + awaitOutgoingMessageCh := make(chan struct{}) + dispatcher.On("Send", peers[1], mock.Anything).Run(func(args mock.Arguments) { + awaitOutgoingMessageCh <- struct{}{} + }).Return(nil) + <-awaitOutgoingMessageCh + + require.NoError(t, publisher.Close()) +} + +func TestTriggerPublisher_ReceiveTriggerEvents_BatchingEnabled(t *testing.T) { + ctx := testutils.Context(t) + capabilityDONID, workflowDONID := uint32(1), uint32(2) + + underlyingTriggerCap, publisher, dispatcher, peers := newServices(t, capabilityDONID, workflowDONID, 2) + regEvent := newRegisterTriggerMessage(t, workflowDONID, peers[1]) + publisher.Receive(ctx, regEvent) + require.NotEmpty(t, underlyingTriggerCap.registrationsCh) + + // send two trigger events and expect them to be delivered in a batch + underlyingTriggerCap.eventCh <- commoncap.TriggerResponse{} + underlyingTriggerCap.eventCh <- commoncap.TriggerResponse{} + awaitOutgoingMessageCh := make(chan struct{}) + dispatcher.On("Send", peers[1], mock.Anything).Run(func(args mock.Arguments) { + msg := args.Get(1).(*remotetypes.MessageBody) + require.Equal(t, capID, msg.CapabilityId) + require.Equal(t, remotetypes.MethodTriggerEvent, msg.Method) + require.NotEmpty(t, msg.Payload) + metadata := msg.Metadata.(*remotetypes.MessageBody_TriggerEventMetadata) + require.Len(t, metadata.TriggerEventMetadata.WorkflowIds, 2) + awaitOutgoingMessageCh <- struct{}{} + }).Return(nil).Once() + <-awaitOutgoingMessageCh + + // if there are fewer pending event than the batch size, + // the events should still be sent after the batch collection period + underlyingTriggerCap.eventCh <- commoncap.TriggerResponse{} + dispatcher.On("Send", peers[1], mock.Anything).Run(func(args mock.Arguments) { + msg := args.Get(1).(*remotetypes.MessageBody) + metadata := msg.Metadata.(*remotetypes.MessageBody_TriggerEventMetadata) + require.Len(t, metadata.TriggerEventMetadata.WorkflowIds, 1) + awaitOutgoingMessageCh <- struct{}{} + }).Return(nil).Once() + <-awaitOutgoingMessageCh + + require.NoError(t, publisher.Close()) +} + +func newServices(t *testing.T, capabilityDONID uint32, workflowDONID uint32, maxBatchSize uint32) (*testTrigger, remotetypes.ReceiverService, *mocks.Dispatcher, []p2ptypes.PeerID) { lggr := logger.TestLogger(t) ctx := testutils.Context(t) capInfo := commoncap.CapabilityInfo{ - ID: "cap_id@1", + ID: capID, CapabilityType: commoncap.CapabilityTypeTrigger, Description: "Remote Trigger", } - p1 := p2ptypes.PeerID{} - require.NoError(t, p1.UnmarshalText([]byte(peerID1))) - p2 := p2ptypes.PeerID{} - require.NoError(t, p2.UnmarshalText([]byte(peerID2))) + peers := make([]p2ptypes.PeerID, 2) + require.NoError(t, peers[0].UnmarshalText([]byte(peerID1))) + require.NoError(t, peers[1].UnmarshalText([]byte(peerID2))) capDonInfo := commoncap.DON{ - ID: 1, - Members: []p2ptypes.PeerID{p1}, + ID: capabilityDONID, + Members: []p2ptypes.PeerID{peers[0]}, // peer 0 is in the capability DON F: 0, } workflowDonInfo := commoncap.DON{ - ID: 2, - Members: []p2ptypes.PeerID{p2}, + ID: workflowDONID, + Members: []p2ptypes.PeerID{peers[1]}, // peer 1 is in the workflow DON F: 0, } - dispatcher := remoteMocks.NewDispatcher(t) + dispatcher := mocks.NewDispatcher(t) config := &commoncap.RemoteTriggerConfig{ RegistrationRefresh: 100 * time.Millisecond, RegistrationExpiry: 100 * time.Second, MinResponsesToAggregate: 1, MessageExpiry: 100 * time.Second, + MaxBatchSize: maxBatchSize, + BatchCollectionPeriod: time.Second, } workflowDONs := map[uint32]commoncap.DON{ workflowDonInfo.ID: workflowDonInfo, @@ -53,10 +136,14 @@ func TestTriggerPublisher_Register(t *testing.T) { underlying := &testTrigger{ info: capInfo, registrationsCh: make(chan commoncap.TriggerRegistrationRequest, 2), + eventCh: make(chan commoncap.TriggerResponse, 2), } publisher := remote.NewTriggerPublisher(config, underlying, capInfo, capDonInfo, workflowDONs, dispatcher, lggr) require.NoError(t, publisher.Start(ctx)) + return underlying, publisher, dispatcher, peers +} +func newRegisterTriggerMessage(t *testing.T, callerDonID uint32, sender p2ptypes.PeerID) *remotetypes.MessageBody { // trigger registration event triggerRequest := commoncap.TriggerRegistrationRequest{ Metadata: commoncap.RequestMetadata{ @@ -65,39 +152,29 @@ func TestTriggerPublisher_Register(t *testing.T) { } marshaled, err := pb.MarshalTriggerRegistrationRequest(triggerRequest) require.NoError(t, err) - regEvent := &remotetypes.MessageBody{ - Sender: p1[:], + return &remotetypes.MessageBody{ + Sender: sender[:], Method: remotetypes.MethodRegisterTrigger, - CallerDonId: workflowDonInfo.ID, + CallerDonId: callerDonID, Payload: marshaled, } - publisher.Receive(ctx, regEvent) - // node p1 is not a member of the workflow DON so registration shoudn't happen - require.Empty(t, underlying.registrationsCh) - - regEvent.Sender = p2[:] - publisher.Receive(ctx, regEvent) - require.NotEmpty(t, underlying.registrationsCh) - forwarded := <-underlying.registrationsCh - require.Equal(t, triggerRequest.Metadata.WorkflowID, forwarded.Metadata.WorkflowID) - - require.NoError(t, publisher.Close()) } type testTrigger struct { info commoncap.CapabilityInfo registrationsCh chan commoncap.TriggerRegistrationRequest + eventCh chan commoncap.TriggerResponse } -func (t *testTrigger) Info(_ context.Context) (commoncap.CapabilityInfo, error) { - return t.info, nil +func (tr *testTrigger) Info(_ context.Context) (commoncap.CapabilityInfo, error) { + return tr.info, nil } -func (t *testTrigger) RegisterTrigger(_ context.Context, request commoncap.TriggerRegistrationRequest) (<-chan commoncap.TriggerResponse, error) { - t.registrationsCh <- request - return nil, nil +func (tr *testTrigger) RegisterTrigger(_ context.Context, request commoncap.TriggerRegistrationRequest) (<-chan commoncap.TriggerResponse, error) { + tr.registrationsCh <- request + return tr.eventCh, nil } -func (t *testTrigger) UnregisterTrigger(_ context.Context, request commoncap.TriggerRegistrationRequest) error { +func (tr *testTrigger) UnregisterTrigger(_ context.Context, request commoncap.TriggerRegistrationRequest) error { return nil } diff --git a/core/capabilities/remote/types/types.go b/core/capabilities/remote/types/types.go index 7f3868486a..54ec16f09f 100644 --- a/core/capabilities/remote/types/types.go +++ b/core/capabilities/remote/types/types.go @@ -30,6 +30,11 @@ type Receiver interface { Receive(ctx context.Context, msg *MessageBody) } +type ReceiverService interface { + services.Service + Receiver +} + type Aggregator interface { Aggregate(eventID string, responses [][]byte) (commoncap.TriggerResponse, error) } From ab5a2c68f95ef50ef4b7600f1c8c816a60390f8d Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 17 Sep 2024 12:02:41 -0400 Subject: [PATCH 362/432] Implement v0.3-compatible telemetry for LLO (#14440) * Implement v0.3-compatible telemetry for LLO * Remove debugging * update go mod * Fix test race * Fix linter * Correct epoch/round numbres * nolint * Fix naming --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/llo/data_source.go | 41 ++-- core/services/llo/data_source_test.go | 93 ++++++-- core/services/llo/delegate.go | 23 +- .../llo/evm/report_codec_premium_legacy.go | 11 +- core/services/llo/telemetry.go | 184 +++++++++++++++ core/services/llo/telemetry_test.go | 216 ++++++++++++++++++ core/services/ocr2/delegate.go | 15 +- .../ocr2/plugins/llo/integration_test.go | 1 - core/services/ocrcommon/telemetry.go | 103 +++++---- core/services/ocrcommon/telemetry_test.go | 25 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 18 files changed, 619 insertions(+), 117 deletions(-) create mode 100644 core/services/llo/telemetry.go create mode 100644 core/services/llo/telemetry_test.go diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 4b11f323a5..88c58caa0b 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -273,7 +273,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.23 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 5a94500963..ed669bbbe5 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1087,8 +1087,8 @@ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907c github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2/go.mod h1:rNhNSrrRMvkgAm5SA6bNTdh2340bTQQZdUVNtZ2o2bk= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 h1:JPs35oSO07PK3Qv7Kyv0GJHVLacIE1IkrvefaPyBjKs= diff --git a/core/services/llo/data_source.go b/core/services/llo/data_source.go index 3d265de261..bad1bf0896 100644 --- a/core/services/llo/data_source.go +++ b/core/services/llo/data_source.go @@ -71,10 +71,16 @@ var _ llo.DataSource = &dataSource{} type dataSource struct { lggr logger.Logger registry Registry + + t Telemeter +} + +func NewDataSource(lggr logger.Logger, registry Registry, t Telemeter) llo.DataSource { + return newDataSource(lggr, registry, t) } -func newDataSource(lggr logger.Logger, registry Registry) llo.DataSource { - return &dataSource{lggr.Named("DataSource"), registry} +func newDataSource(lggr logger.Logger, registry Registry, t Telemeter) *dataSource { + return &dataSource{lggr.Named("DataSource"), registry, t} } // Observe looks up all streams in the registry and populates a map of stream ID => value @@ -82,7 +88,7 @@ func (d *dataSource) Observe(ctx context.Context, streamValues llo.StreamValues, var wg sync.WaitGroup wg.Add(len(streamValues)) var svmu sync.Mutex - var errors []ErrObservationFailed + var errs []ErrObservationFailed var errmu sync.Mutex if opts.VerboseLogging() { @@ -91,7 +97,7 @@ func (d *dataSource) Observe(ctx context.Context, streamValues llo.StreamValues, streamIDs = append(streamIDs, streamID) } sort.Slice(streamIDs, func(i, j int) bool { return streamIDs[i] < streamIDs[j] }) - d.lggr.Debugw("Observing streams", "streamIDs", streamIDs, "seqNr", opts.SeqNr()) + d.lggr.Debugw("Observing streams", "streamIDs", streamIDs, "configDigest", opts.ConfigDigest(), "seqNr", opts.OutCtx().SeqNr) } for _, streamID := range maps.Keys(streamValues) { @@ -103,7 +109,7 @@ func (d *dataSource) Observe(ctx context.Context, streamValues llo.StreamValues, stream, exists := d.registry.Get(streamID) if !exists { errmu.Lock() - errors = append(errors, ErrObservationFailed{streamID: streamID, reason: fmt.Sprintf("missing stream: %d", streamID)}) + errs = append(errs, ErrObservationFailed{streamID: streamID, reason: fmt.Sprintf("missing stream: %d", streamID)}) errmu.Unlock() promMissingStreamCount.WithLabelValues(fmt.Sprintf("%d", streamID)).Inc() return @@ -111,19 +117,26 @@ func (d *dataSource) Observe(ctx context.Context, streamValues llo.StreamValues, run, trrs, err := stream.Run(ctx) if err != nil { errmu.Lock() - errors = append(errors, ErrObservationFailed{inner: err, run: run, streamID: streamID, reason: "pipeline run failed"}) + errs = append(errs, ErrObservationFailed{inner: err, run: run, streamID: streamID, reason: "pipeline run failed"}) errmu.Unlock() promObservationErrorCount.WithLabelValues(fmt.Sprintf("%d", streamID)).Inc() + // TODO: Consolidate/reduce telemetry. We should send all observation results in a single packet + // https://smartcontract-it.atlassian.net/browse/MERC-6290 + d.t.EnqueueV3PremiumLegacy(run, trrs, streamID, opts, nil, err) return } + // TODO: Consolidate/reduce telemetry. We should send all observation results in a single packet + // https://smartcontract-it.atlassian.net/browse/MERC-6290 val, err = ExtractStreamValue(trrs) if err != nil { errmu.Lock() - errors = append(errors, ErrObservationFailed{inner: err, run: run, streamID: streamID, reason: "failed to extract big.Int"}) + errs = append(errs, ErrObservationFailed{inner: err, run: run, streamID: streamID, reason: "failed to extract big.Int"}) errmu.Unlock() return } + d.t.EnqueueV3PremiumLegacy(run, trrs, streamID, opts, val, nil) + if val != nil { svmu.Lock() defer svmu.Unlock() @@ -136,15 +149,15 @@ func (d *dataSource) Observe(ctx context.Context, streamValues llo.StreamValues, // Failed observations are always logged at warn level var failedStreamIDs []streams.StreamID - if len(errors) > 0 { - sort.Slice(errors, func(i, j int) bool { return errors[i].streamID < errors[j].streamID }) - failedStreamIDs = make([]streams.StreamID, len(errors)) - errStrs := make([]string, len(errors)) - for i, e := range errors { + if len(errs) > 0 { + sort.Slice(errs, func(i, j int) bool { return errs[i].streamID < errs[j].streamID }) + failedStreamIDs = make([]streams.StreamID, len(errs)) + errStrs := make([]string, len(errs)) + for i, e := range errs { errStrs[i] = e.String() failedStreamIDs[i] = e.streamID } - d.lggr.Warnw("Observation failed for streams", "failedStreamIDs", failedStreamIDs, "errors", errStrs, "seqNr", opts.SeqNr()) + d.lggr.Warnw("Observation failed for streams", "failedStreamIDs", failedStreamIDs, "errs", errStrs, "configDigest", opts.ConfigDigest(), "seqNr", opts.OutCtx().SeqNr) } if opts.VerboseLogging() { @@ -153,7 +166,7 @@ func (d *dataSource) Observe(ctx context.Context, streamValues llo.StreamValues, successes = append(successes, strmID) } sort.Slice(successes, func(i, j int) bool { return successes[i] < successes[j] }) - d.lggr.Debugw("Observation complete", "successfulStreamIDs", successes, "failedStreamIDs", failedStreamIDs, "values", streamValues, "seqNr", opts.SeqNr()) + d.lggr.Debugw("Observation complete", "successfulStreamIDs", successes, "failedStreamIDs", failedStreamIDs, "configDigest", opts.ConfigDigest(), "values", streamValues, "seqNr", opts.OutCtx().SeqNr) } return nil diff --git a/core/services/llo/data_source_test.go b/core/services/llo/data_source_test.go index 59cd870bc9..932c4c0c73 100644 --- a/core/services/llo/data_source_test.go +++ b/core/services/llo/data_source_test.go @@ -4,10 +4,15 @@ import ( "context" "errors" "math/big" + "sync" "testing" "github.com/shopspring/decimal" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink-data-streams/llo" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" @@ -35,8 +40,9 @@ func (m *mockRegistry) Get(streamID streams.StreamID) (strm streams.Stream, exis return } -func makeStreamWithSingleResult[T any](res T, err error) *mockStream { +func makeStreamWithSingleResult[T any](runID int64, res T, err error) *mockStream { return &mockStream{ + run: &pipeline.Run{ID: runID}, trrs: []pipeline.TaskRunResult{pipeline.TaskRunResult{Task: &pipeline.MemoTask{}, Result: pipeline.Result{Value: res}}}, err: err, } @@ -52,30 +58,59 @@ func makeStreamValues() llo.StreamValues { type mockOpts struct{} -func (m mockOpts) VerboseLogging() bool { return true } -func (m mockOpts) SeqNr() uint64 { return 42 } +func (m *mockOpts) VerboseLogging() bool { return true } +func (m *mockOpts) SeqNr() uint64 { return 1042 } +func (m *mockOpts) OutCtx() ocr3types.OutcomeContext { + return ocr3types.OutcomeContext{SeqNr: 1042, PreviousOutcome: ocr3types.Outcome([]byte("foo"))} +} +func (m *mockOpts) ConfigDigest() ocr2types.ConfigDigest { + return ocr2types.ConfigDigest{6, 5, 4} +} + +type mockTelemeter struct { + mu sync.Mutex + v3PremiumLegacyPackets []v3PremiumLegacyPacket +} + +type v3PremiumLegacyPacket struct { + run *pipeline.Run + trrs pipeline.TaskRunResults + streamID uint32 + opts llo.DSOpts + val llo.StreamValue + err error +} + +var _ Telemeter = &mockTelemeter{} + +func (m *mockTelemeter) EnqueueV3PremiumLegacy(run *pipeline.Run, trrs pipeline.TaskRunResults, streamID uint32, opts llo.DSOpts, val llo.StreamValue, err error) { + m.mu.Lock() + defer m.mu.Unlock() + m.v3PremiumLegacyPackets = append(m.v3PremiumLegacyPackets, v3PremiumLegacyPacket{run, trrs, streamID, opts, val, err}) +} func Test_DataSource(t *testing.T) { lggr := logger.TestLogger(t) reg := &mockRegistry{make(map[streams.StreamID]*mockStream)} - ds := newDataSource(lggr, reg) + ds := newDataSource(lggr, reg, NullTelemeter) ctx := testutils.Context(t) + opts := &mockOpts{} t.Run("Observe", func(t *testing.T) { t.Run("doesn't set any values if no streams are defined", func(t *testing.T) { vals := makeStreamValues() - err := ds.Observe(ctx, vals, mockOpts{}) + err := ds.Observe(ctx, vals, opts) assert.NoError(t, err) assert.Equal(t, makeStreamValues(), vals) }) t.Run("observes each stream with success and returns values matching map argument", func(t *testing.T) { - reg.streams[1] = makeStreamWithSingleResult[*big.Int](big.NewInt(2181), nil) - reg.streams[2] = makeStreamWithSingleResult[*big.Int](big.NewInt(40602), nil) - reg.streams[3] = makeStreamWithSingleResult[*big.Int](big.NewInt(15), nil) + reg.streams[1] = makeStreamWithSingleResult[*big.Int](1, big.NewInt(2181), nil) + reg.streams[2] = makeStreamWithSingleResult[*big.Int](2, big.NewInt(40602), nil) + reg.streams[3] = makeStreamWithSingleResult[*big.Int](3, big.NewInt(15), nil) vals := makeStreamValues() - err := ds.Observe(ctx, vals, mockOpts{}) + err := ds.Observe(ctx, vals, opts) assert.NoError(t, err) assert.Equal(t, llo.StreamValues{ @@ -85,12 +120,12 @@ func Test_DataSource(t *testing.T) { }, vals) }) t.Run("observes each stream and returns success/errors", func(t *testing.T) { - reg.streams[1] = makeStreamWithSingleResult[*big.Int](big.NewInt(2181), errors.New("something exploded")) - reg.streams[2] = makeStreamWithSingleResult[*big.Int](big.NewInt(40602), nil) - reg.streams[3] = makeStreamWithSingleResult[*big.Int](nil, errors.New("something exploded 2")) + reg.streams[1] = makeStreamWithSingleResult[*big.Int](1, big.NewInt(2181), errors.New("something exploded")) + reg.streams[2] = makeStreamWithSingleResult[*big.Int](2, big.NewInt(40602), nil) + reg.streams[3] = makeStreamWithSingleResult[*big.Int](3, nil, errors.New("something exploded 2")) vals := makeStreamValues() - err := ds.Observe(ctx, vals, mockOpts{}) + err := ds.Observe(ctx, vals, opts) assert.NoError(t, err) assert.Equal(t, llo.StreamValues{ @@ -99,5 +134,37 @@ func Test_DataSource(t *testing.T) { 3: nil, }, vals) }) + + t.Run("records telemetry", func(t *testing.T) { + tm := &mockTelemeter{} + ds.t = tm + + reg.streams[1] = makeStreamWithSingleResult[*big.Int](100, big.NewInt(2181), nil) + reg.streams[2] = makeStreamWithSingleResult[*big.Int](101, big.NewInt(40602), nil) + reg.streams[3] = makeStreamWithSingleResult[*big.Int](102, big.NewInt(15), nil) + + vals := makeStreamValues() + err := ds.Observe(ctx, vals, opts) + assert.NoError(t, err) + + assert.Equal(t, llo.StreamValues{ + 2: llo.ToDecimal(decimal.NewFromInt(40602)), + 1: llo.ToDecimal(decimal.NewFromInt(2181)), + 3: llo.ToDecimal(decimal.NewFromInt(15)), + }, vals) + + require.Len(t, tm.v3PremiumLegacyPackets, 3) + m := make(map[int]v3PremiumLegacyPacket) + for _, pkt := range tm.v3PremiumLegacyPackets { + m[int(pkt.run.ID)] = pkt + } + pkt := m[100] + assert.Equal(t, 100, int(pkt.run.ID)) + assert.Len(t, pkt.trrs, 1) + assert.Equal(t, 1, int(pkt.streamID)) + assert.Equal(t, opts, pkt.opts) + assert.Equal(t, "2181", pkt.val.(*llo.Decimal).String()) + assert.Nil(t, pkt.err) + }) }) } diff --git a/core/services/llo/delegate.go b/core/services/llo/delegate.go index aff670e807..ab55c6b2a9 100644 --- a/core/services/llo/delegate.go +++ b/core/services/llo/delegate.go @@ -37,16 +37,18 @@ type delegate struct { prrc llo.PredecessorRetirementReportCache src llo.ShouldRetireCache ds llo.DataSource + t services.Service oracle Closer } type DelegateConfig struct { - Logger logger.Logger - DataSource sqlutil.DataSource - Runner streams.Runner - Registry Registry - JobName null.String + Logger logger.Logger + DataSource sqlutil.DataSource + Runner streams.Runner + Registry Registry + JobName null.String + CaptureEATelemetry bool // LLO ChannelDefinitionCache llotypes.ChannelDefinitionCache @@ -67,6 +69,7 @@ type DelegateConfig struct { } func NewDelegate(cfg DelegateConfig) (job.ServiceCtx, error) { + lggr := cfg.Logger.With("jobName", cfg.JobName.ValueOrZero()) if cfg.DataSource == nil { return nil, errors.New("DataSource must not be nil") } @@ -82,9 +85,15 @@ func NewDelegate(cfg DelegateConfig) (job.ServiceCtx, error) { // https://smartcontract-it.atlassian.net/browse/MERC-3386 prrc := llo.NewPredecessorRetirementReportCache() src := llo.NewShouldRetireCache() - ds := newDataSource(cfg.Logger.Named("DataSource"), cfg.Registry) + var t TelemeterService + if cfg.CaptureEATelemetry { + t = NewTelemeterService(lggr, cfg.MonitoringEndpoint) + } else { + t = NullTelemeter + } + ds := newDataSource(lggr.Named("DataSource"), cfg.Registry, t) - return &delegate{services.StateMachine{}, cfg, codecs, prrc, src, ds, nil}, nil + return &delegate{services.StateMachine{}, cfg, codecs, prrc, src, ds, t, nil}, nil } func (d *delegate) Start(ctx context.Context) error { diff --git a/core/services/llo/evm/report_codec_premium_legacy.go b/core/services/llo/evm/report_codec_premium_legacy.go index da14aceab6..f8d72619ea 100644 --- a/core/services/llo/evm/report_codec_premium_legacy.go +++ b/core/services/llo/evm/report_codec_premium_legacy.go @@ -155,10 +155,15 @@ func ExtractReportValues(report llo.Report) (nativePrice, linkPrice *llo.Decimal // MERC-3524 var LLOExtraHash = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001") -func LegacyReportContext(cd ocr2types.ConfigDigest, seqNr uint64) ocr2types.ReportContext { +func SeqNrToEpochAndRound(seqNr uint64) (epoch uint32, round uint8) { // Simulate 256 rounds/epoch - epoch := seqNr / 256 - round := seqNr % 256 + epoch = uint32(seqNr / 256) // nolint + round = uint8(seqNr % 256) // nolint + return +} + +func LegacyReportContext(cd ocr2types.ConfigDigest, seqNr uint64) ocr2types.ReportContext { + epoch, round := SeqNrToEpochAndRound(seqNr) return ocr2types.ReportContext{ ReportTimestamp: ocr2types.ReportTimestamp{ ConfigDigest: cd, diff --git a/core/services/llo/telemetry.go b/core/services/llo/telemetry.go new file mode 100644 index 0000000000..62b586f5cc --- /dev/null +++ b/core/services/llo/telemetry.go @@ -0,0 +1,184 @@ +package llo + +import ( + "context" + "errors" + "fmt" + + "github.com/smartcontractkit/libocr/commontypes" + "google.golang.org/protobuf/proto" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-data-streams/llo" + + "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/eautils" + mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" +) + +const adapterLWBAErrorName = "AdapterLWBAError" + +type Telemeter interface { + EnqueueV3PremiumLegacy(run *pipeline.Run, trrs pipeline.TaskRunResults, streamID uint32, opts llo.DSOpts, val llo.StreamValue, err error) +} + +type TelemeterService interface { + Telemeter + services.Service +} + +func NewTelemeterService(lggr logger.Logger, monitoringEndpoint commontypes.MonitoringEndpoint) TelemeterService { + if monitoringEndpoint == nil { + return NullTelemeter + } + return newTelemeter(lggr, monitoringEndpoint) +} + +func newTelemeter(lggr logger.Logger, monitoringEndpoint commontypes.MonitoringEndpoint) *telemeter { + chTelemetryObservation := make(chan TelemetryObservation, 100) + t := &telemeter{ + chTelemetryObservation: chTelemetryObservation, + monitoringEndpoint: monitoringEndpoint, + } + t.Service, t.eng = services.Config{ + Name: "LLOTelemeterService", + Start: t.start, + }.NewServiceEngine(lggr) + + return t +} + +type telemeter struct { + services.Service + eng *services.Engine + + monitoringEndpoint commontypes.MonitoringEndpoint + chTelemetryObservation chan TelemetryObservation +} + +func (t *telemeter) EnqueueV3PremiumLegacy(run *pipeline.Run, trrs pipeline.TaskRunResults, streamID uint32, opts llo.DSOpts, val llo.StreamValue, err error) { + var adapterError *eautils.AdapterError + var dpInvariantViolationDetected bool + if errors.As(err, &adapterError) && adapterError.Name == adapterLWBAErrorName { + dpInvariantViolationDetected = true + } else if err != nil { + // ignore errors + return + } + tObs := TelemetryObservation{run, trrs, streamID, opts, val, dpInvariantViolationDetected} + select { + case t.chTelemetryObservation <- tObs: + default: + } +} + +func (t *telemeter) start(_ context.Context) error { + t.eng.Go(func(ctx context.Context) { + for { + select { + case tObs := <-t.chTelemetryObservation: + t.collectV3PremiumLegacyTelemetry(tObs) + case <-ctx.Done(): + return + } + } + }) + return nil +} + +func (t *telemeter) collectV3PremiumLegacyTelemetry(d TelemetryObservation) { + eaTelemetryValues := ocrcommon.ParseMercuryEATelemetry(t.eng.SugaredLogger, d.trrs, mercuryutils.REPORT_V3) + for _, eaTelem := range eaTelemetryValues { + var benchmarkPrice, bidPrice, askPrice int64 + var bp, bid, ask string + switch v := d.val.(type) { + case *llo.Decimal: + benchmarkPrice = v.Decimal().IntPart() + bp = v.Decimal().String() + case *llo.Quote: + benchmarkPrice = v.Benchmark.IntPart() + bp = v.Benchmark.String() + bidPrice = v.Bid.IntPart() + bid = v.Bid.String() + askPrice = v.Ask.IntPart() + ask = v.Ask.String() + } + epoch, round := evm.SeqNrToEpochAndRound(d.opts.OutCtx().SeqNr) + tea := &telem.EnhancedEAMercury{ + DataSource: eaTelem.DataSource, + DpBenchmarkPrice: eaTelem.DpBenchmarkPrice, + DpBid: eaTelem.DpBid, + DpAsk: eaTelem.DpAsk, + DpInvariantViolationDetected: d.dpInvariantViolationDetected, + BridgeTaskRunStartedTimestamp: eaTelem.BridgeTaskRunStartedTimestamp, + BridgeTaskRunEndedTimestamp: eaTelem.BridgeTaskRunEndedTimestamp, + ProviderRequestedTimestamp: eaTelem.ProviderRequestedTimestamp, + ProviderReceivedTimestamp: eaTelem.ProviderReceivedTimestamp, + ProviderDataStreamEstablished: eaTelem.ProviderDataStreamEstablished, + ProviderIndicatedTime: eaTelem.ProviderIndicatedTime, + Feed: fmt.Sprintf("streamID:%d", d.streamID), + ObservationBenchmarkPrice: benchmarkPrice, + ObservationBid: bidPrice, + ObservationAsk: askPrice, + ObservationBenchmarkPriceString: bp, + ObservationBidString: bid, + ObservationAskString: ask, + IsLinkFeed: false, + IsNativeFeed: false, + ConfigDigest: d.opts.ConfigDigest().Hex(), + Round: int64(round), + Epoch: int64(epoch), + AssetSymbol: eaTelem.AssetSymbol, + Version: uint32(1000 + mercuryutils.REPORT_V3), // add 1000 to distinguish between legacy feeds, this can be changed if necessary + } + + bytes, err := proto.Marshal(tea) + if err != nil { + t.eng.SugaredLogger.Warnf("protobuf marshal failed %v", err.Error()) + continue + } + + t.monitoringEndpoint.SendLog(bytes) + } +} + +type TelemetryObservation struct { + run *pipeline.Run + trrs pipeline.TaskRunResults + streamID uint32 + opts llo.DSOpts + val llo.StreamValue + dpInvariantViolationDetected bool +} + +var NullTelemeter TelemeterService = &nullTelemeter{} + +type nullTelemeter struct{} + +func (t *nullTelemeter) EnqueueV3PremiumLegacy(run *pipeline.Run, trrs pipeline.TaskRunResults, streamID uint32, opts llo.DSOpts, val llo.StreamValue, err error) { +} +func (t *nullTelemeter) Start(context.Context) error { + return nil +} +func (t *nullTelemeter) Close() error { + return nil +} +func (t *nullTelemeter) Healthy() error { + return nil +} +func (t *nullTelemeter) Unhealthy() error { + return nil +} +func (t *nullTelemeter) HealthReport() map[string]error { + return nil +} +func (t *nullTelemeter) Name() string { + return "NullTelemeter" +} +func (t *nullTelemeter) Ready() error { + return nil +} diff --git a/core/services/llo/telemetry_test.go b/core/services/llo/telemetry_test.go new file mode 100644 index 0000000000..ec77e959d2 --- /dev/null +++ b/core/services/llo/telemetry_test.go @@ -0,0 +1,216 @@ +package llo + +import ( + "errors" + "testing" + "time" + + "github.com/shopspring/decimal" + "github.com/smartcontractkit/libocr/commontypes" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" + "gopkg.in/guregu/null.v4" + + "github.com/smartcontractkit/chainlink-data-streams/llo" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/eautils" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" +) + +var _ commontypes.MonitoringEndpoint = &mockMonitoringEndpoint{} + +type mockMonitoringEndpoint struct { + chLogs chan []byte +} + +func (m *mockMonitoringEndpoint) SendLog(log []byte) { + m.chLogs <- log +} + +const bridgeResponse = `{ + "meta":{ + "adapterName":"data-source-name" + }, + "timestamps":{ + "providerDataRequestedUnixMs":92233720368547760, + "providerDataReceivedUnixMs":-92233720368547760, + "providerDataStreamEstablishedUnixMs":1, + "providerIndicatedTimeUnixMs":-123456789 + } + }` + +var trrs = pipeline.TaskRunResults{ + pipeline.TaskRunResult{ + Task: &pipeline.BridgeTask{ + Name: "test-bridge-1", + BaseTask: pipeline.NewBaseTask(0, "ds1", nil, nil, 0), + RequestData: `{"data":{"from":"eth", "to":"usd"}}`, + }, + Result: pipeline.Result{ + Value: bridgeResponse, + }, + CreatedAt: time.Unix(0, 0), + FinishedAt: null.TimeFrom(time.Unix(0, 0)), + }, + pipeline.TaskRunResult{ + Task: &pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(1, "ds1_parse", nil, nil, 1), + }, + Result: pipeline.Result{ + Value: "123456.123456789", + }, + }, + pipeline.TaskRunResult{ + Task: &pipeline.BridgeTask{ + Name: "test-bridge-2", + BaseTask: pipeline.NewBaseTask(0, "ds2", nil, nil, 0), + RequestData: `{"data":{"from":"eth", "to":"usd"}}`, + }, + Result: pipeline.Result{ + Value: bridgeResponse, + }, + CreatedAt: time.Unix(1, 0), + FinishedAt: null.TimeFrom(time.Unix(10, 0)), + }, + pipeline.TaskRunResult{ + Task: &pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(1, "ds2_parse", nil, nil, 1), + }, + Result: pipeline.Result{ + Value: "12345678", + }, + }, + pipeline.TaskRunResult{ + Task: &pipeline.BridgeTask{ + Name: "test-bridge-3", + BaseTask: pipeline.NewBaseTask(0, "ds3", nil, nil, 0), + RequestData: `{"data":{"from":"eth", "to":"usd"}}`, + }, + Result: pipeline.Result{ + Value: bridgeResponse, + }, + CreatedAt: time.Unix(2, 0), + FinishedAt: null.TimeFrom(time.Unix(20, 0)), + }, + pipeline.TaskRunResult{ + Task: &pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(1, "ds3_parse", nil, nil, 1), + }, + Result: pipeline.Result{ + Value: "1234567890", + }, + }, +} + +func Test_Telemeter(t *testing.T) { + lggr := logger.Test(t) + m := &mockMonitoringEndpoint{} + + run := &pipeline.Run{ID: 42} + streamID := uint32(135) + opts := &mockOpts{} + + t.Run("with error", func(t *testing.T) { + tm := newTelemeter(lggr, m) + servicetest.Run(t, tm) + + t.Run("if error is some random failure returns immediately", func(t *testing.T) { + // should return immediately and not even send on the channel + m.chLogs = nil + tm.EnqueueV3PremiumLegacy(run, trrs, streamID, opts, nil, errors.New("test error")) + }) + t.Run("if error is dp invariant violation, sets this flag", func(t *testing.T) { + m.chLogs = make(chan []byte, 100) + adapterError := new(eautils.AdapterError) + adapterError.Name = adapterLWBAErrorName + tm.EnqueueV3PremiumLegacy(run, trrs, streamID, opts, nil, adapterError) + + var i int + for log := range m.chLogs { + decoded := &telem.EnhancedEAMercury{} + require.NoError(t, proto.Unmarshal(log, decoded)) + assert.True(t, decoded.DpInvariantViolationDetected) + if i == 2 { + return + } + i++ + } + }) + }) + t.Run("with decimal value, sets all values correctly", func(t *testing.T) { + tm := newTelemeter(lggr, m) + val := llo.ToDecimal(decimal.NewFromFloat32(102.12)) + servicetest.Run(t, tm) + tm.EnqueueV3PremiumLegacy(run, trrs, streamID, opts, val, nil) + + var i int + for log := range m.chLogs { + decoded := &telem.EnhancedEAMercury{} + require.NoError(t, proto.Unmarshal(log, decoded)) + assert.Equal(t, int(1003), int(decoded.Version)) + assert.Equal(t, float64(123456.123456789), decoded.DpBenchmarkPrice) + assert.Zero(t, decoded.DpBid) + assert.Zero(t, decoded.DpAsk) + assert.False(t, decoded.DpInvariantViolationDetected) + assert.Zero(t, decoded.CurrentBlockNumber) + assert.Zero(t, decoded.CurrentBlockHash) + assert.Zero(t, decoded.CurrentBlockTimestamp) + assert.Zero(t, decoded.FetchMaxFinalizedTimestamp) + assert.Zero(t, decoded.MaxFinalizedTimestamp) + assert.Zero(t, decoded.ObservationTimestamp) + assert.False(t, decoded.IsLinkFeed) + assert.Zero(t, decoded.LinkPrice) + assert.False(t, decoded.IsNativeFeed) + assert.Zero(t, decoded.NativePrice) + assert.Equal(t, int64(i*1000), decoded.BridgeTaskRunStartedTimestamp) + assert.Equal(t, int64(i*10000), decoded.BridgeTaskRunEndedTimestamp) + assert.Equal(t, int64(92233720368547760), decoded.ProviderRequestedTimestamp) + assert.Equal(t, int64(-92233720368547760), decoded.ProviderReceivedTimestamp) + assert.Equal(t, int64(1), decoded.ProviderDataStreamEstablished) + assert.Equal(t, int64(-123456789), decoded.ProviderIndicatedTime) + assert.Equal(t, "streamID:135", decoded.Feed) + assert.Equal(t, int64(102), decoded.ObservationBenchmarkPrice) + assert.Equal(t, "102.12", decoded.ObservationBenchmarkPriceString) + assert.Zero(t, decoded.ObservationBid) + assert.Zero(t, decoded.ObservationBidString) + assert.Zero(t, decoded.ObservationAsk) + assert.Zero(t, decoded.ObservationAskString) + assert.Zero(t, decoded.ObservationMarketStatus) + assert.Equal(t, "0605040000000000000000000000000000000000000000000000000000000000", decoded.ConfigDigest) + assert.Equal(t, int64(18), decoded.Round) + assert.Equal(t, int64(4), decoded.Epoch) + assert.Equal(t, "eth/usd", decoded.AssetSymbol) + if i == 2 { + return + } + i++ + } + }) + t.Run("with quote value", func(t *testing.T) { + tm := newTelemeter(lggr, m) + val := &llo.Quote{Bid: decimal.NewFromFloat32(102.12), Benchmark: decimal.NewFromFloat32(103.32), Ask: decimal.NewFromFloat32(104.25)} + servicetest.Run(t, tm) + tm.EnqueueV3PremiumLegacy(run, trrs, streamID, opts, val, nil) + + var i int + for log := range m.chLogs { + decoded := &telem.EnhancedEAMercury{} + require.NoError(t, proto.Unmarshal(log, decoded)) + assert.Equal(t, int64(103), decoded.ObservationBenchmarkPrice) + assert.Equal(t, "103.32", decoded.ObservationBenchmarkPriceString) + assert.Equal(t, int64(102), decoded.ObservationBid) + assert.Equal(t, "102.12", decoded.ObservationBidString) + assert.Equal(t, int64(104), decoded.ObservationAsk) + assert.Equal(t, "104.25", decoded.ObservationAskString) + assert.Zero(t, decoded.ObservationMarketStatus) + if i == 2 { + return + } + i++ + } + }) +} diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index a6bb63b6c8..18f4d6224e 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -1015,7 +1015,8 @@ func (d *Delegate) newServicesLLO( Runner: d.pipelineRunner, Registry: d.streamRegistry, - JobName: jb.Name, + JobName: jb.Name, + CaptureEATelemetry: jb.OCR2OracleSpec.CaptureEATelemetry, ChannelDefinitionCache: provider.ChannelDefinitionCache(), @@ -1025,13 +1026,11 @@ func (d *Delegate) newServicesLLO( ContractConfigTracker: provider.ContractConfigTracker(), Database: ocrDB, LocalConfig: lc, - // TODO: Telemetry for llo - // https://smartcontract-it.atlassian.net/browse/MERC-3603 - MonitoringEndpoint: nil, - OffchainConfigDigester: provider.OffchainConfigDigester(), - OffchainKeyring: kb, - OnchainKeyring: kr, - OCRLogger: ocrLogger, + MonitoringEndpoint: d.monitoringEndpointGen.GenMonitoringEndpoint(rid.Network, rid.ChainID, fmt.Sprintf("%d", pluginCfg.DonID), synchronization.EnhancedEAMercury), + OffchainConfigDigester: provider.OffchainConfigDigester(), + OffchainKeyring: kb, + OnchainKeyring: kr, + OCRLogger: ocrLogger, // Enable verbose logging if either Mercury.VerboseLogging is on or OCR2.TraceLogging is on ReportingPluginConfig: datastreamsllo.Config{VerboseLogging: d.cfg.Mercury().VerboseLogging() || d.cfg.OCR2().TraceLogging()}, diff --git a/core/services/ocr2/plugins/llo/integration_test.go b/core/services/ocr2/plugins/llo/integration_test.go index 62c43eaf4d..2e49e98946 100644 --- a/core/services/ocr2/plugins/llo/integration_test.go +++ b/core/services/ocr2/plugins/llo/integration_test.go @@ -210,7 +210,6 @@ func TestIntegration_LLO(t *testing.T) { } serverURL := startMercuryServer(t, srv, clientPubKeys) - // TODO: all args? steve, backend, configurator, configuratorAddress, verifier, _, verifierProxy, _, configStore, configStoreAddress := setupBlockchain(t) fromBlock := 1 diff --git a/core/services/ocrcommon/telemetry.go b/core/services/ocrcommon/telemetry.go index 7db29aaacb..2be3e2228c 100644 --- a/core/services/ocrcommon/telemetry.go +++ b/core/services/ocrcommon/telemetry.go @@ -11,13 +11,13 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "google.golang.org/protobuf/proto" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" v1types "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1" v2types "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" v3types "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" v4types "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" @@ -25,12 +25,19 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) -type eaTelemetry struct { +type EATelemetry struct { DataSource string ProviderRequestedTimestamp int64 ProviderReceivedTimestamp int64 ProviderDataStreamEstablished int64 ProviderIndicatedTime int64 + + DpBenchmarkPrice float64 + DpBid float64 + DpAsk float64 + BridgeTaskRunStartedTimestamp int64 + BridgeTaskRunEndedTimestamp int64 + AssetSymbol string } type EnhancedTelemetryData struct { @@ -144,8 +151,37 @@ func (e *EnhancedTelemetryService[T]) getChainID() string { } } +func ParseMercuryEATelemetry(lggr logger.Logger, trrs pipeline.TaskRunResults, feedVersion mercuryutils.FeedVersion) (eaTelemetryValues []EATelemetry) { + for _, trr := range trrs { + if trr.Task.Type() != pipeline.TaskTypeBridge { + continue + } + bridgeTask := trr.Task.(*pipeline.BridgeTask) + bridgeName := bridgeTask.Name + + bridgeRawResponse, ok := trr.Result.Value.(string) + if !ok { + lggr.Warnw(fmt.Sprintf("cannot get bridge response from bridge task, id=%s, name=%q, expected string got %T", trr.Task.DotID(), bridgeName, trr.Result.Value), "dotID", trr.Task.DotID(), "bridgeName", bridgeName) + continue + } + eaTelem, err := parseEATelemetry([]byte(bridgeRawResponse)) + if err != nil { + lggr.Warnw(fmt.Sprintf("cannot parse EA telemetry, id=%s, name=%q", trr.Task.DotID(), bridgeName), "err", err, "dotID", trr.Task.DotID(), "bridgeName", bridgeName) + } + + eaTelem.DpBenchmarkPrice, eaTelem.DpBid, eaTelem.DpAsk = getPricesFromResults(lggr, trr, trrs, feedVersion) + + eaTelem.BridgeTaskRunStartedTimestamp = trr.CreatedAt.UnixMilli() + eaTelem.BridgeTaskRunEndedTimestamp = trr.FinishedAt.Time.UnixMilli() + eaTelem.AssetSymbol = getAssetSymbolFromRequestData(bridgeTask.RequestData) + + eaTelemetryValues = append(eaTelemetryValues, eaTelem) + } + return +} + // parseEATelemetry attempts to parse the bridge telemetry -func parseEATelemetry(b []byte) (eaTelemetry, error) { +func parseEATelemetry(b []byte) (EATelemetry, error) { type eaTimestamps struct { ProviderRequestedTimestamp int64 `json:"providerDataRequestedUnixMs"` ProviderReceivedTimestamp int64 `json:"providerDataReceivedUnixMs"` @@ -163,10 +199,10 @@ func parseEATelemetry(b []byte) (eaTelemetry, error) { t := eaTelem{} if err := json.Unmarshal(b, &t); err != nil { - return eaTelemetry{}, err + return EATelemetry{}, err } - return eaTelemetry{ + return EATelemetry{ DataSource: t.TelemMeta.AdapterName, ProviderRequestedTimestamp: t.TelemTimestamps.ProviderRequestedTimestamp, ProviderReceivedTimestamp: t.TelemTimestamps.ProviderReceivedTimestamp, @@ -378,40 +414,21 @@ func (e *EnhancedTelemetryService[T]) collectMercuryEnhancedTelemetry(d Enhanced } } - for _, trr := range d.TaskRunResults { - if trr.Task.Type() != pipeline.TaskTypeBridge { - continue - } - bridgeTask := trr.Task.(*pipeline.BridgeTask) - bridgeName := bridgeTask.Name - - bridgeRawResponse, ok := trr.Result.Value.(string) - if !ok { - e.lggr.Warnw(fmt.Sprintf("cannot get bridge response from bridge task, job=%d, id=%s, name=%q, expected string got %T", e.job.ID, trr.Task.DotID(), bridgeName, trr.Result.Value), "jobID", e.job.ID, "dotID", trr.Task.DotID(), "bridgeName", bridgeName) - continue - } - eaTelem, err := parseEATelemetry([]byte(bridgeRawResponse)) - if err != nil { - e.lggr.Warnw(fmt.Sprintf("cannot parse EA telemetry, job=%d, id=%s, name=%q", e.job.ID, trr.Task.DotID(), bridgeName), "err", err, "jobID", e.job.ID, "dotID", trr.Task.DotID(), "bridgeName", bridgeName) - } - - assetSymbol := e.getAssetSymbolFromRequestData(bridgeTask.RequestData) - - benchmarkPrice, bidPrice, askPrice := e.getPricesFromResults(trr, d.TaskRunResults, d.FeedVersion) - + eaTelemetryValues := ParseMercuryEATelemetry(logger.Sugared(e.lggr).With("jobID", e.job.ID), d.TaskRunResults, d.FeedVersion) + for _, eaTelem := range eaTelemetryValues { t := &telem.EnhancedEAMercury{ DataSource: eaTelem.DataSource, - DpBenchmarkPrice: benchmarkPrice, - DpBid: bidPrice, - DpAsk: askPrice, + DpBenchmarkPrice: eaTelem.DpBenchmarkPrice, + DpBid: eaTelem.DpBid, + DpAsk: eaTelem.DpAsk, DpInvariantViolationDetected: d.DpInvariantViolationDetected, CurrentBlockNumber: bn, CurrentBlockHash: bh, CurrentBlockTimestamp: bt, FetchMaxFinalizedTimestamp: d.FetchMaxFinalizedTimestamp, MaxFinalizedTimestamp: mfts, - BridgeTaskRunStartedTimestamp: trr.CreatedAt.UnixMilli(), - BridgeTaskRunEndedTimestamp: trr.FinishedAt.Time.UnixMilli(), + BridgeTaskRunStartedTimestamp: eaTelem.BridgeTaskRunStartedTimestamp, + BridgeTaskRunEndedTimestamp: eaTelem.BridgeTaskRunEndedTimestamp, ProviderRequestedTimestamp: eaTelem.ProviderRequestedTimestamp, ProviderReceivedTimestamp: eaTelem.ProviderReceivedTimestamp, ProviderDataStreamEstablished: eaTelem.ProviderDataStreamEstablished, @@ -431,7 +448,7 @@ func (e *EnhancedTelemetryService[T]) collectMercuryEnhancedTelemetry(d Enhanced ConfigDigest: d.RepTimestamp.ConfigDigest.Hex(), Round: int64(d.RepTimestamp.Round), Epoch: int64(d.RepTimestamp.Epoch), - AssetSymbol: assetSymbol, + AssetSymbol: eaTelem.AssetSymbol, Version: uint32(d.FeedVersion), } @@ -446,7 +463,7 @@ func (e *EnhancedTelemetryService[T]) collectMercuryEnhancedTelemetry(d Enhanced } // getAssetSymbolFromRequestData parses the requestData of the bridge to generate an asset symbol pair -func (e *EnhancedTelemetryService[T]) getAssetSymbolFromRequestData(requestData string) string { +func getAssetSymbolFromRequestData(requestData string) string { type reqDataPayload struct { To string `json:"to"` From string `json:"from"` @@ -474,22 +491,22 @@ func ShouldCollectEnhancedTelemetryMercury(jb job.Job) bool { // getPricesFromResults parses the pipeline.TaskRunResults for pipeline.TaskTypeJSONParse and gets the benchmarkPrice, // bid and ask. This functions expects the pipeline.TaskRunResults to be correctly ordered -func (e *EnhancedTelemetryService[T]) getPricesFromResults(startTask pipeline.TaskRunResult, allTasks pipeline.TaskRunResults, mercuryVersion mercuryutils.FeedVersion) (float64, float64, float64) { +func getPricesFromResults(lggr logger.Logger, startTask pipeline.TaskRunResult, allTasks pipeline.TaskRunResults, mercuryVersion mercuryutils.FeedVersion) (float64, float64, float64) { var benchmarkPrice, askPrice, bidPrice float64 var err error // We rely on task results to be sorted in the correct order benchmarkPriceTask := allTasks.GetNextTaskOf(startTask) if benchmarkPriceTask == nil { - e.lggr.Warnf("cannot parse enhanced EA telemetry benchmark price, task is nil, job %d", e.job.ID) + lggr.Warn("cannot parse enhanced EA telemetry benchmark price, task is nil") return 0, 0, 0 } if benchmarkPriceTask.Task.Type() == pipeline.TaskTypeJSONParse { if benchmarkPriceTask.Result.Error != nil { - e.lggr.Warnw(fmt.Sprintf("got error for enhanced EA telemetry benchmark price, job %d, id %s: %s", e.job.ID, benchmarkPriceTask.Task.DotID(), benchmarkPriceTask.Result.Error), "err", benchmarkPriceTask.Result.Error) + lggr.Warnw(fmt.Sprintf("got error for enhanced EA telemetry benchmark price, id %s: %s", benchmarkPriceTask.Task.DotID(), benchmarkPriceTask.Result.Error), "err", benchmarkPriceTask.Result.Error) } else { benchmarkPrice, err = getResultFloat64(benchmarkPriceTask) if err != nil { - e.lggr.Warnw(fmt.Sprintf("cannot parse enhanced EA telemetry benchmark price, job %d, id %s", e.job.ID, benchmarkPriceTask.Task.DotID()), "err", err) + lggr.Warnw(fmt.Sprintf("cannot parse enhanced EA telemetry benchmark price, id %s", benchmarkPriceTask.Task.DotID()), "err", err) } } } @@ -501,33 +518,33 @@ func (e *EnhancedTelemetryService[T]) getPricesFromResults(startTask pipeline.Ta bidTask := allTasks.GetNextTaskOf(*benchmarkPriceTask) if bidTask == nil { - e.lggr.Warnf("cannot parse enhanced EA telemetry bid price, task is nil, job %d, id %s", e.job.ID, benchmarkPriceTask.Task.DotID()) + lggr.Warnf("cannot parse enhanced EA telemetry bid price, task is nil, id %s", benchmarkPriceTask.Task.DotID()) return benchmarkPrice, 0, 0 } if bidTask != nil && bidTask.Task.Type() == pipeline.TaskTypeJSONParse { if bidTask.Result.Error != nil { - e.lggr.Warnw(fmt.Sprintf("got error for enhanced EA telemetry bid price, job %d, id %s: %s", e.job.ID, bidTask.Task.DotID(), bidTask.Result.Error), "err", bidTask.Result.Error) + lggr.Warnw(fmt.Sprintf("got error for enhanced EA telemetry bid price, id %s: %s", bidTask.Task.DotID(), bidTask.Result.Error), "err", bidTask.Result.Error) } else { bidPrice, err = getResultFloat64(bidTask) if err != nil { - e.lggr.Warnw(fmt.Sprintf("cannot parse enhanced EA telemetry bid price, job %d, id %s", e.job.ID, bidTask.Task.DotID()), "err", err) + lggr.Warnw(fmt.Sprintf("cannot parse enhanced EA telemetry bid price, id %s", bidTask.Task.DotID()), "err", err) } } } askTask := allTasks.GetNextTaskOf(*bidTask) if askTask == nil { - e.lggr.Warnf("cannot parse enhanced EA telemetry ask price, task is nil, job %d, id %s", e.job.ID, benchmarkPriceTask.Task.DotID()) + lggr.Warnf("cannot parse enhanced EA telemetry ask price, task is nil, id %s", benchmarkPriceTask.Task.DotID()) return benchmarkPrice, bidPrice, 0 } if askTask != nil && askTask.Task.Type() == pipeline.TaskTypeJSONParse { if bidTask.Result.Error != nil { - e.lggr.Warnw(fmt.Sprintf("got error for enhanced EA telemetry ask price, job %d, id %s: %s", e.job.ID, askTask.Task.DotID(), askTask.Result.Error), "err", askTask.Result.Error) + lggr.Warnw(fmt.Sprintf("got error for enhanced EA telemetry ask price, id %s: %s", askTask.Task.DotID(), askTask.Result.Error), "err", askTask.Result.Error) } else { askPrice, err = getResultFloat64(askTask) if err != nil { - e.lggr.Warnw(fmt.Sprintf("cannot parse enhanced EA telemetry ask price, job %d, id %s", e.job.ID, askTask.Task.DotID()), "err", err) + lggr.Warnw(fmt.Sprintf("cannot parse enhanced EA telemetry ask price, id %s", askTask.Task.DotID()), "err", err) } } } diff --git a/core/services/ocrcommon/telemetry_test.go b/core/services/ocrcommon/telemetry_test.go index f764e7380f..e257554803 100644 --- a/core/services/ocrcommon/telemetry_test.go +++ b/core/services/ocrcommon/telemetry_test.go @@ -447,19 +447,13 @@ var trrsMercuryV2 = pipeline.TaskRunResults{ func TestGetPricesFromResults(t *testing.T) { lggr, logs := logger.TestLoggerObserved(t, zap.WarnLevel) - e := EnhancedTelemetryService[EnhancedTelemetryMercuryData]{ - lggr: lggr, - job: &job.Job{ - ID: 0, - }, - } - benchmarkPrice, bid, ask := e.getPricesFromResults(trrsMercuryV1[0], trrsMercuryV1, 1) + benchmarkPrice, bid, ask := getPricesFromResults(lggr, trrsMercuryV1[0], trrsMercuryV1, 1) require.Equal(t, 123456.123456, benchmarkPrice) require.Equal(t, 1234567.1234567, bid) require.Equal(t, float64(321123), ask) - benchmarkPrice, bid, ask = e.getPricesFromResults(trrsMercuryV1[0], pipeline.TaskRunResults{}, 1) + benchmarkPrice, bid, ask = getPricesFromResults(lggr, trrsMercuryV1[0], pipeline.TaskRunResults{}, 1) require.Equal(t, float64(0), benchmarkPrice) require.Equal(t, float64(0), bid) require.Equal(t, float64(0), ask) @@ -467,12 +461,12 @@ func TestGetPricesFromResults(t *testing.T) { require.Contains(t, logs.All()[0].Message, "cannot parse enhanced EA telemetry") tt := trrsMercuryV1[:2] - e.getPricesFromResults(trrsMercuryV1[0], tt, 1) + getPricesFromResults(lggr, trrsMercuryV1[0], tt, 1) require.Equal(t, 2, logs.Len()) require.Contains(t, logs.All()[1].Message, "cannot parse enhanced EA telemetry bid price, task is nil") tt = trrsMercuryV1[:3] - e.getPricesFromResults(trrsMercuryV1[0], tt, 1) + getPricesFromResults(lggr, trrsMercuryV1[0], tt, 1) require.Equal(t, 3, logs.Len()) require.Contains(t, logs.All()[2].Message, "cannot parse enhanced EA telemetry ask price, task is nil") @@ -510,7 +504,7 @@ func TestGetPricesFromResults(t *testing.T) { Value: nil, }, }} - benchmarkPrice, bid, ask = e.getPricesFromResults(trrsMercuryV1[0], trrs2, 3) + benchmarkPrice, bid, ask = getPricesFromResults(lggr, trrsMercuryV1[0], trrs2, 3) require.Equal(t, benchmarkPrice, float64(0)) require.Equal(t, bid, float64(0)) require.Equal(t, ask, float64(0)) @@ -519,7 +513,7 @@ func TestGetPricesFromResults(t *testing.T) { require.Contains(t, logs.All()[4].Message, "cannot parse enhanced EA telemetry bid price") require.Contains(t, logs.All()[5].Message, "cannot parse enhanced EA telemetry ask price") - benchmarkPrice, bid, ask = e.getPricesFromResults(trrsMercuryV1[0], trrsMercuryV2, 2) + benchmarkPrice, bid, ask = getPricesFromResults(lggr, trrsMercuryV1[0], trrsMercuryV2, 2) require.Equal(t, 123456.123456, benchmarkPrice) require.Equal(t, float64(0), bid) require.Equal(t, float64(0), ask) @@ -542,10 +536,9 @@ func TestShouldCollectEnhancedTelemetryMercury(t *testing.T) { } func TestGetAssetSymbolFromRequestData(t *testing.T) { - e := EnhancedTelemetryService[EnhancedTelemetryMercuryData]{} - require.Equal(t, e.getAssetSymbolFromRequestData(""), "") + require.Equal(t, getAssetSymbolFromRequestData(""), "") reqData := `{"data":{"to":"LINK","from":"USD"}}` - require.Equal(t, e.getAssetSymbolFromRequestData(reqData), "USD/LINK") + require.Equal(t, getAssetSymbolFromRequestData(reqData), "USD/LINK") } func TestCollectMercuryEnhancedTelemetryV1(t *testing.T) { @@ -660,7 +653,7 @@ func TestCollectMercuryEnhancedTelemetryV1(t *testing.T) { wg.Wait() require.Equal(t, 2, logs.Len()) - require.Contains(t, logs.All()[0].Message, `cannot get bridge response from bridge task, job=0, id=ds1, name="test-mercury-bridge-1"`) + require.Contains(t, logs.All()[0].Message, `cannot get bridge response from bridge task, id=ds1, name="test-mercury-bridge-1"`) require.Contains(t, logs.All()[1].Message, "cannot parse EA telemetry") chDone <- struct{}{} } diff --git a/go.mod b/go.mod index e900c0ebcc..6f9d925858 100644 --- a/go.mod +++ b/go.mod @@ -77,7 +77,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae diff --git a/go.sum b/go.sum index 1414f564a8..6edbb94eb9 100644 --- a/go.sum +++ b/go.sum @@ -1048,8 +1048,8 @@ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907c github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2/go.mod h1:rNhNSrrRMvkgAm5SA6bNTdh2340bTQQZdUVNtZ2o2bk= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 h1:JPs35oSO07PK3Qv7Kyv0GJHVLacIE1IkrvefaPyBjKs= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 40c8964c03..a12e8c18dc 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -406,7 +406,7 @@ require ( github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index db4c6ed040..a559c09901 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1429,8 +1429,8 @@ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907c github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2/go.mod h1:rNhNSrrRMvkgAm5SA6bNTdh2340bTQQZdUVNtZ2o2bk= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 h1:JPs35oSO07PK3Qv7Kyv0GJHVLacIE1IkrvefaPyBjKs= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 00c6453814..f2aff6511e 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -386,7 +386,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.23 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc // indirect + github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index bf4ca8c6ba..3efe39cca8 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1403,8 +1403,8 @@ github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907c github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc h1:tRmTlaoAt+7FakMXXgeCuRPmzzBo5jsGpeCVvcU6KMc= -github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240906125718-9f0a98d32fbc/go.mod h1:PwPcmQNAzVmU8r8JWKrDRgvXesDwxnqbMD6DvYt/Z7M= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= +github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2/go.mod h1:rNhNSrrRMvkgAm5SA6bNTdh2340bTQQZdUVNtZ2o2bk= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 h1:JPs35oSO07PK3Qv7Kyv0GJHVLacIE1IkrvefaPyBjKs= From bc177cb041f3793ae4fa2dea7834924eebbbbd89 Mon Sep 17 00:00:00 2001 From: Balamurali Gopalswami <167726375+b-gopalswami@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:37:31 -0400 Subject: [PATCH 363/432] CCIP-3407: Add release testing configs (#1436) (#14463) ## Motivation Need to add default configs that are usually used for release testing in beta-testnet or prod-testnet. https://smartcontract-it.atlassian.net/browse/CCIP-3407 ## Solution Have segregated and generalized the configs for release testing however this might need changes depends on the releases. --- integration-tests/ccip-tests/README.md | 6 + .../testnet-beta-workinglane.toml | 283 +++++ .../testnet-beta-workinglane_native.toml | 295 +++++ .../load-prod-testnet.toml} | 2 +- .../smoke-release-testing_native.toml | 1035 +++++++++++++++++ ...release-testing_token_transfer_native.toml | 1035 +++++++++++++++++ ...g_token_transfer_with_native_feetoken.toml | 1013 ++++++++++++++++ 7 files changed, 3668 insertions(+), 1 deletion(-) create mode 100644 integration-tests/ccip-tests/testconfig/tomls/beta-testnet/testnet-beta-workinglane.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/beta-testnet/testnet-beta-workinglane_native.toml rename integration-tests/ccip-tests/testconfig/tomls/{ccip1.4-stress/prod-testnet.toml => prod-testnet/load-prod-testnet.toml} (99%) create mode 100644 integration-tests/ccip-tests/testconfig/tomls/prod-testnet/smoke-release-testing_native.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/prod-testnet/smoke-release-testing_token_transfer_native.toml create mode 100644 integration-tests/ccip-tests/testconfig/tomls/prod-testnet/soak-release-testing_token_transfer_with_native_feetoken.toml diff --git a/integration-tests/ccip-tests/README.md b/integration-tests/ccip-tests/README.md index 1abca8552b..a425592894 100644 --- a/integration-tests/ccip-tests/README.md +++ b/integration-tests/ccip-tests/README.md @@ -119,3 +119,9 @@ flowchart ### Using Remote Kubernetes Cluster For running more complex and intensive tests (like load and chaos tests) you need to connect the test to a Kubernetes cluster. These tests have more complex setup and running instructions. We endeavor to make these easier to run and configure, but for the time being please seek a member of the QA/Test Tooling team if you want to run these. + +### Live environment testing + +To run against live environments, use the configs available under [beta-testnet](./testconfig/tomls/beta-testnet) +or [prod-testnet](./testconfig/tomls/prod-testnet) directory. Prod testnet has configs for smoke, load and +soak test separately and beta-testnet has smoke and soak combined. \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/beta-testnet/testnet-beta-workinglane.toml b/integration-tests/ccip-tests/testconfig/tomls/beta-testnet/testnet-beta-workinglane.toml new file mode 100644 index 0000000000..592cb046ad --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/beta-testnet/testnet-beta-workinglane.toml @@ -0,0 +1,283 @@ +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = 'latest' +OffRamp = 'latest' +OnRamp = 'latest' +TokenPool = 'latest' +CommitStore = 'latest' + +[CCIP.Deployments] +Data = """ +{ + "lane_configs": { + "Arbitrum Sepolia": { + "is_mock_arm": true, + "fee_token": "0xb1D4538B4571d411F07960EF2838Ce337FE1E80E", + "bridge_tokens": null, + "bridge_tokens_pools": null, + "price_aggregators": null, + "arm": "0x2aE6d5495fc20226F433be50e37D59c05D186AaA", + "router": "0x0fF6b6F3Ad10D66600Fd5CC25b98542A05Aa7Bc2", + "price_registry": "0x25d997d8618e1299418b3D905E40bC353ec89F61", + "wrapped_native": "0xE591bf0A0CF924A0674d7792db046B23CEbF5f34", + "src_contracts": { + "Base Sepolia": { + "on_ramp": "0x6BD0f1efA261Ea84DB219c1284b538A65E530ea1", + "deployed_at": 29428386 + }, + "Optimism Sepolia": { + "on_ramp": "0x94cd0d171eF08924F0008305e5Bb90b0fC1b61AB", + "deployed_at": 13945916 + }, + "Sepolia Testnet": { + "on_ramp": "0x44225eb3B73B1b52Dd2ecD258F9b63418eC6Bf79", + "deployed_at": 13730868 + } + }, + "dest_contracts": { + "Base Sepolia": { + "off_ramp": "0x21560B4ACAEdb8AA2Dd935618F15da43197bdc12", + "commit_store": "0x27B882c393151ADD910F3557849AF0bb09c7d5A6", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xAE32FD8Ae148BD88E3da6FaE8Cd7561Eed3ec5Cc", + "commit_store": "0x1f1160Ac7828B647A85c9a6b3A58A232C59D67Ab", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xc136114F379b812345bb7e467ECDdb6D0c87De8b", + "commit_store": "0x42b3EbEA14F6CB803e3C7df84392Efb85CE90168", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Avalanche Fuji": { + "is_mock_arm": true, + "fee_token": "0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846", + "bridge_tokens": null, + "bridge_tokens_pools": null, + "price_aggregators": null, + "arm": "0xD4A51dC0F5C680A8A18eA4Ec3A2f25C6db9424B7", + "router": "0xa62e685aDFF45f38eC94378513D128F168964E99", + "price_registry": "0xdbeA1a10AC6a2B729bF128aE9281Ed420dbE7113", + "wrapped_native": "0xd00ae08403B9bbb9124bB305C09058E32C39A48c", + "src_contracts": { + "BSC Testnet": { + "on_ramp": "0xe4f1F7750352f1c37C15C4A314554d6A79d7d146", + "deployed_at": 31437550 + } + }, + "dest_contracts": { + "BSC Testnet": { + "off_ramp": "0x796D720ea9D4326ff356eadE13b123B267C03C80", + "commit_store": "0xaDb37cFd91fa9b6Df1DaAcbAfB4cDFF41e06c956", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "BSC Testnet": { + "is_mock_arm": true, + "fee_token": "0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06", + "bridge_tokens": null, + "bridge_tokens_pools": null, + "price_aggregators": null, + "arm": "0xbBF534D89d9640e3886db25FE1ffE603Fe160D75", + "router": "0x9CdA5b77eA23459eBaf2e3092c570a6B5605850A", + "price_registry": "0x9213967a47FC3F15A16A0b813208e8Ccb63Dbba6", + "wrapped_native": "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0x0B4F541a7fcE5c251993Bc19D5A40B661e0463f5", + "deployed_at": 39097639 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0x41E59DCdDec18d7f79DA5F76Ce567d2c5e301E6B", + "commit_store": "0x9487C01D4b3Ae1c9Ac8740A07f3862D646548A14", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Base Sepolia": { + "is_mock_arm": true, + "fee_token": "0xE4aB69C077896252FAFBD49EFD26B5D171A32410", + "bridge_tokens": null, + "bridge_tokens_pools": null, + "price_aggregators": null, + "arm": "0x866faB92E04bAE5EDa238A9cbFf1e56E09508Ade", + "router": "0x2aE6d5495fc20226F433be50e37D59c05D186AaA", + "price_registry": "0xD886E2286Fd1073df82462ea1822119600Af80b6", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0xAE32FD8Ae148BD88E3da6FaE8Cd7561Eed3ec5Cc", + "deployed_at": 8133125 + }, + "Optimism Sepolia": { + "on_ramp": "0x9213967a47FC3F15A16A0b813208e8Ccb63Dbba6", + "deployed_at": 11607777 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x34433469A4d6c8b1B0a1a7B91a5C5C2Dd74c67Fb", + "commit_store": "0xFEE7c8E229F538a98437b9A7D0Dd8fCd8A1Ab569", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0x0f30449bcCaCCaA7221B3f7C3304c4AaD68068E8", + "commit_store": "0x17a5746c9cf7eAf23533F060F395B2E38eb976ea", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Optimism Sepolia": { + "is_mock_arm": true, + "fee_token": "0xE4aB69C077896252FAFBD49EFD26B5D171A32410", + "bridge_tokens": null, + "bridge_tokens_pools": null, + "price_aggregators": null, + "arm": "0x2aE6d5495fc20226F433be50e37D59c05D186AaA", + "router": "0x0fF6b6F3Ad10D66600Fd5CC25b98542A05Aa7Bc2", + "price_registry": "0x3B80b7Ef5c00Eb892CBe72800C028C47AD6380EF", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x622CB640F52bFfA68b78b2BD12c1940Ca4899621", + "deployed_at": 8020540 + }, + "Base Sepolia": { + "on_ramp": "0x12c164d0778E215873A062cEE2814507417339cB", + "deployed_at": 13590651 + }, + "Sepolia Testnet": { + "on_ramp": "0x0c2c8D4266C98f1b9333D5E1a42f3f775A0005d4", + "deployed_at": 8020948 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x37004c1245a2D5541377e87cA29699492a4114D5", + "commit_store": "0x51158Ca439feA9E809Bc063CfA6701747b05254e", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0xB3F3f362FbeD49fA0086B434051C822B55BaADbD", + "commit_store": "0xD4995B99c484CCABc868b26c0B2C2Ef10ecde3d7", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x80C2aa80F202FeFdFEEF80f516cFd89768c54057", + "commit_store": "0xc1fE981A040D679511ccb9139ca107aCA67520ef", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Sepolia Testnet": { + "is_mock_arm": true, + "fee_token": "0x779877A7B0D9E8603169DdbD7836e478b4624789", + "bridge_tokens": null, + "bridge_tokens_pools": null, + "price_aggregators": null, + "arm": "0x9912a7389382ff55f85A29C9378B38F7B992c4aE", + "router": "0x1E1F3d8Ac7Df65fCcFcc52dbF03929cEE95430ac", + "price_registry": "0x4358e81f88bB27222779c1BC85003A11A1c66f6F", + "wrapped_native": "0x097D90c9d3E0B50Ca60e1ae45F6A81010f9FB534", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x420a7B5ABB8CF27A70E1906F797e24509B11093D", + "deployed_at": 5275652 + }, + "Optimism Sepolia": { + "on_ramp": "0xEb4EBC1930bA81416A48a59142D89722163D85ae", + "deployed_at": 5281150 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x224D1eB3aB2b7F23b66f093F9cBBC68dA77a1986", + "commit_store": "0x35c54cF12FF9B29dBa60dc23EdD1de0F13CC7fc5", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xF21d01D6Ef822FBC56FC6c8F23f74fE3A0cb39aa", + "commit_store": "0x7F6AF440Bcc54f70Fd8AC2E534d37196c0bA1A38", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + } + } +} +""" + +[CCIP.Env] +TTL = '8h' + +[CCIP.Env.Network] +selected_networks = [ + 'ARBITRUM_SEPOLIA', + 'AVALANCHE_FUJI', + 'BASE_SEPOLIA', + 'BSC_TESTNET', + 'OPTIMISM_SEPOLIA', + 'SEPOLIA' +] + + + +[CCIP.Groups.smoke] +# these are all the valid network pairs +NetworkPairs = [ + 'BSC_TESTNET,AVALANCHE_FUJI', + 'SEPOLIA,ARBITRUM_SEPOLIA', + 'BASE_SEPOLIA,OPTIMISM_SEPOLIA' +] + +BiDirectionalLane = true +PhaseTimeout = '40m' +LocalCluster = false +ExistingDeployment = true +ReuseContracts = true + + +[CCIP.Groups.smoke.TokenConfig] +NoOfTokensPerChain = 1 +CCIPOwnerTokens = true + +[CCIP.Groups.smoke.MsgDetails] +MsgType = 'Data' +DestGasLimit = 0 +DataLength = 100 +NoOfTokens = 1 +AmountPerToken = 1 + +[CCIP.Groups.load] +NetworkPairs = [ + 'AVALANCHE_FUJI,BSC_TESTNET', + 'SEPOLIA,ARBITRUM_SEPOLIA', + 'BASE_SEPOLIA,OPTIMISM_SEPOLIA' +] + +BiDirectionalLane = true +PhaseTimeout = '40m' +ExistingDeployment = true + +[CCIP.Groups.load.TokenConfig] +NoOfTokensPerChain = 1 + +# Soak Test profile +[CCIP.Groups.load.LoadProfile] +RequestPerUnitTime = [1] +TimeUnit = '6m' +TestDuration = '3h' +TestRunName = 'BetaSoakTest_CCIPV1dot5' +FailOnFirstErrorInLoad = true + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 0 +DataLength = 100 +NoOfTokens = 1 +AmountPerToken = 1 \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/beta-testnet/testnet-beta-workinglane_native.toml b/integration-tests/ccip-tests/testconfig/tomls/beta-testnet/testnet-beta-workinglane_native.toml new file mode 100644 index 0000000000..fcc063c765 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/beta-testnet/testnet-beta-workinglane_native.toml @@ -0,0 +1,295 @@ +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = 'latest' +OffRamp = 'latest' +OnRamp = 'latest' +TokenPool = 'latest' +CommitStore = 'latest' + +[CCIP.Deployments] +Data = """ +{ + "lane_configs": { + "Arbitrum Sepolia": { + "is_native_fee_token": true, + "is_mock_arm": true, + "fee_token": "0xE591bf0A0CF924A0674d7792db046B23CEbF5f34", + "bridge_tokens": null, + "bridge_tokens_pools": null, + "price_aggregators": null, + "arm": "0x2aE6d5495fc20226F433be50e37D59c05D186AaA", + "router": "0x0fF6b6F3Ad10D66600Fd5CC25b98542A05Aa7Bc2", + "price_registry": "0x25d997d8618e1299418b3D905E40bC353ec89F61", + "wrapped_native": "0xE591bf0A0CF924A0674d7792db046B23CEbF5f34", + "src_contracts": { + "Base Sepolia": { + "on_ramp": "0x6BD0f1efA261Ea84DB219c1284b538A65E530ea1", + "deployed_at": 29428386 + }, + "Optimism Sepolia": { + "on_ramp": "0x94cd0d171eF08924F0008305e5Bb90b0fC1b61AB", + "deployed_at": 13945916 + }, + "Sepolia Testnet": { + "on_ramp": "0x44225eb3B73B1b52Dd2ecD258F9b63418eC6Bf79", + "deployed_at": 13730868 + } + }, + "dest_contracts": { + "Base Sepolia": { + "off_ramp": "0x21560B4ACAEdb8AA2Dd935618F15da43197bdc12", + "commit_store": "0x27B882c393151ADD910F3557849AF0bb09c7d5A6", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xAE32FD8Ae148BD88E3da6FaE8Cd7561Eed3ec5Cc", + "commit_store": "0x1f1160Ac7828B647A85c9a6b3A58A232C59D67Ab", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xc136114F379b812345bb7e467ECDdb6D0c87De8b", + "commit_store": "0x42b3EbEA14F6CB803e3C7df84392Efb85CE90168", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Avalanche Fuji": { + "is_native_fee_token": true, + "is_mock_arm": true, + "fee_token": "0xd00ae08403B9bbb9124bB305C09058E32C39A48c", + "bridge_tokens": [ + "0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846" + ], + "bridge_tokens_pools": [ + "0x156943ae87AaF63eA9272902Cb05407ec7bc9464" + ], + "price_aggregators": null, + "arm": "0xD4A51dC0F5C680A8A18eA4Ec3A2f25C6db9424B7", + "router": "0xa62e685aDFF45f38eC94378513D128F168964E99", + "price_registry": "0xdbeA1a10AC6a2B729bF128aE9281Ed420dbE7113", + "wrapped_native": "0xd00ae08403B9bbb9124bB305C09058E32C39A48c", + "src_contracts": { + "BSC Testnet": { + "on_ramp": "0xe4f1F7750352f1c37C15C4A314554d6A79d7d146", + "deployed_at": 31437550 + } + }, + "dest_contracts": { + "BSC Testnet": { + "off_ramp": "0x796D720ea9D4326ff356eadE13b123B267C03C80", + "commit_store": "0xaDb37cFd91fa9b6Df1DaAcbAfB4cDFF41e06c956", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "BSC Testnet": { + "is_native_fee_token": true, + "is_mock_arm": true, + "fee_token": "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", + "bridge_tokens": null, + "bridge_tokens_pools": null, + "price_aggregators": null, + "arm": "0xbBF534D89d9640e3886db25FE1ffE603Fe160D75", + "router": "0x9CdA5b77eA23459eBaf2e3092c570a6B5605850A", + "price_registry": "0x9213967a47FC3F15A16A0b813208e8Ccb63Dbba6", + "wrapped_native": "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0x0B4F541a7fcE5c251993Bc19D5A40B661e0463f5", + "deployed_at": 39097639 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0x41E59DCdDec18d7f79DA5F76Ce567d2c5e301E6B", + "commit_store": "0x9487C01D4b3Ae1c9Ac8740A07f3862D646548A14", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Base Sepolia": { + "is_native_fee_token": true, + "is_mock_arm": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "bridge_tokens": null, + "bridge_tokens_pools": null, + "price_aggregators": null, + "arm": "0x866faB92E04bAE5EDa238A9cbFf1e56E09508Ade", + "router": "0x2aE6d5495fc20226F433be50e37D59c05D186AaA", + "price_registry": "0xD886E2286Fd1073df82462ea1822119600Af80b6", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0xAE32FD8Ae148BD88E3da6FaE8Cd7561Eed3ec5Cc", + "deployed_at": 8133125 + }, + "Optimism Sepolia": { + "on_ramp": "0x9213967a47FC3F15A16A0b813208e8Ccb63Dbba6", + "deployed_at": 11607777 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x34433469A4d6c8b1B0a1a7B91a5C5C2Dd74c67Fb", + "commit_store": "0xFEE7c8E229F538a98437b9A7D0Dd8fCd8A1Ab569", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0x0f30449bcCaCCaA7221B3f7C3304c4AaD68068E8", + "commit_store": "0x17a5746c9cf7eAf23533F060F395B2E38eb976ea", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Optimism Sepolia": { + "is_native_fee_token": true, + "is_mock_arm": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "bridge_tokens": null, + "bridge_tokens_pools": null, + "price_aggregators": null, + "arm": "0x2aE6d5495fc20226F433be50e37D59c05D186AaA", + "router": "0x0fF6b6F3Ad10D66600Fd5CC25b98542A05Aa7Bc2", + "price_registry": "0x3B80b7Ef5c00Eb892CBe72800C028C47AD6380EF", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x622CB640F52bFfA68b78b2BD12c1940Ca4899621", + "deployed_at": 8020540 + }, + "Base Sepolia": { + "on_ramp": "0x12c164d0778E215873A062cEE2814507417339cB", + "deployed_at": 13590651 + }, + "Sepolia Testnet": { + "on_ramp": "0x0c2c8D4266C98f1b9333D5E1a42f3f775A0005d4", + "deployed_at": 8020948 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x37004c1245a2D5541377e87cA29699492a4114D5", + "commit_store": "0x51158Ca439feA9E809Bc063CfA6701747b05254e", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0xB3F3f362FbeD49fA0086B434051C822B55BaADbD", + "commit_store": "0xD4995B99c484CCABc868b26c0B2C2Ef10ecde3d7", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x80C2aa80F202FeFdFEEF80f516cFd89768c54057", + "commit_store": "0xc1fE981A040D679511ccb9139ca107aCA67520ef", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Sepolia Testnet": { + "is_native_fee_token": true, + "is_mock_arm": true, + "fee_token": "0x097D90c9d3E0B50Ca60e1ae45F6A81010f9FB534", + "bridge_tokens": null, + "bridge_tokens_pools": null, + "price_aggregators": null, + "arm": "0x9912a7389382ff55f85A29C9378B38F7B992c4aE", + "router": "0x1E1F3d8Ac7Df65fCcFcc52dbF03929cEE95430ac", + "price_registry": "0x4358e81f88bB27222779c1BC85003A11A1c66f6F", + "wrapped_native": "0x097D90c9d3E0B50Ca60e1ae45F6A81010f9FB534", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x420a7B5ABB8CF27A70E1906F797e24509B11093D", + "deployed_at": 5275652 + }, + "Optimism Sepolia": { + "on_ramp": "0xEb4EBC1930bA81416A48a59142D89722163D85ae", + "deployed_at": 5281150 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x224D1eB3aB2b7F23b66f093F9cBBC68dA77a1986", + "commit_store": "0x35c54cF12FF9B29dBa60dc23EdD1de0F13CC7fc5", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xF21d01D6Ef822FBC56FC6c8F23f74fE3A0cb39aa", + "commit_store": "0x7F6AF440Bcc54f70Fd8AC2E534d37196c0bA1A38", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + } + } +} +""" + +[CCIP.Env] +TTL = '8h' + +[CCIP.Env.Network] +selected_networks = [ + 'ARBITRUM_SEPOLIA', + 'AVALANCHE_FUJI', + 'BASE_SEPOLIA', + 'BSC_TESTNET', + 'OPTIMISM_SEPOLIA', + 'SEPOLIA', +] + + +[CCIP.Env.NewCLCluster.Common.ChainlinkImage] +version = "sha-17ce920" + +[CCIP.Groups.smoke] +# these are all the valid network pairs +NetworkPairs = [ + 'AVALANCHE_FUJI,BSC_TESTNET', + 'SEPOLIA,ARBITRUM_SEPOLIA', + 'BASE_SEPOLIA,OPTIMISM_SEPOLIA', +] + +BiDirectionalLane = true +PhaseTimeout = '30m' +LocalCluster = false +ExistingDeployment = true +ReuseContracts = true + + +[CCIP.Groups.smoke.TokenConfig] +NoOfTokensPerChain = 1 +CCIPOwnerTokens = true + +[CCIP.Groups.smoke.MsgDetails] +MsgType = 'Data' +DestGasLimit = 0 +DataLength = 100 +NoOfTokens = 1 +AmountPerToken = 1 + +[CCIP.Groups.load] +NetworkPairs = [ + 'AVALANCHE_FUJI,BSC_TESTNET', + 'SEPOLIA,ARBITRUM_SEPOLIA', + 'BASE_SEPOLIA,OPTIMISM_SEPOLIA' +] + +BiDirectionalLane = true +PhaseTimeout = '40m' +ExistingDeployment = true + +[CCIP.Groups.load.TokenConfig] +NoOfTokensPerChain = 1 + +# Soak Test profile +[CCIP.Groups.load.LoadProfile] +RequestPerUnitTime = [1] +TimeUnit = '6m' +TestDuration = '3h' +TestRunName = 'BetaSoakTest_V2.14.0-1.5.1' +FailOnFirstErrorInLoad = true + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 0 +DataLength = 100 +NoOfTokens = 1 +AmountPerToken = 1 \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/prod-testnet.toml b/integration-tests/ccip-tests/testconfig/tomls/prod-testnet/load-prod-testnet.toml similarity index 99% rename from integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/prod-testnet.toml rename to integration-tests/ccip-tests/testconfig/tomls/prod-testnet/load-prod-testnet.toml index f8321584c8..f13965d5e6 100644 --- a/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/prod-testnet.toml +++ b/integration-tests/ccip-tests/testconfig/tomls/prod-testnet/load-prod-testnet.toml @@ -933,7 +933,7 @@ NoOfTokensPerChain = 1 RequestPerUnitTime = [1] TimeUnit = '5s' TestDuration = '1h' -TestRunName = 'v2.12.0-ccip1.4.16-load' +TestRunName = 'ccip-prod-testnet-stress' # to represent 20%, 60%, 15%, 5% of the total messages [CCIP.Groups.load.LoadProfile.MsgProfile] diff --git a/integration-tests/ccip-tests/testconfig/tomls/prod-testnet/smoke-release-testing_native.toml b/integration-tests/ccip-tests/testconfig/tomls/prod-testnet/smoke-release-testing_native.toml new file mode 100644 index 0000000000..24e7cbc9c8 --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/prod-testnet/smoke-release-testing_native.toml @@ -0,0 +1,1035 @@ +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = 'latest' +OffRamp = 'latest' +OnRamp = 'latest' +CommitStore = 'latest' +TokenPool = 'latest' + + +[CCIP.Deployments] +Data = """ +{ + "lane_configs": { + "Arbitrum Sepolia": { + "is_native_fee_token": true, + "fee_token": "0xE591bf0A0CF924A0674d7792db046B23CEbF5f34", + "bridge_tokens": [ + "0xA8C0c11bf64AF62CDCA6f93D3769B88BdD7cb93D" + ], + "bridge_tokens_pools": [ + "0x99685281Ec520a003F1A726A5a8078c2124c1477" + ], + "arm": "0xbcBDf0aDEDC9a33ED5338Bdb4B6F7CE664DC2e8B", + "router": "0x2a9C5afB0d0e4BAb2BCdaE109EC4b0c4Be15a165", + "price_registry": "0x89D5b13908b9063abCC6791dc724bF7B7c93634C", + "wrapped_native": "0xE591bf0A0CF924A0674d7792db046B23CEbF5f34", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0x1Cb56374296ED19E86F68fA437ee679FD7798DaA", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x7854E73C73e7F9bb5b0D5B4861E997f4C6E8dcC6", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x973CbE752258D32AE82b60CD1CB656Eebb588dF0", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0x701Fe16916dd21EFE2f535CA59611D818B017877", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x4205E1Ca0202A248A5D42F5975A8FE56F3E302e9", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0xBD4106fBE4699FE212A34Cc21b10BFf22b02d959", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0xcab0EF91Bee323d1A617c0a027eE753aFd6997E4", + "commit_store": "0x0d90b9b96cBFa0D01635ce12982ccE1b70827c7a", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0xc1982985720B959E66c19b64F783361Eb9B60F26", + "commit_store": "0x28F66bB336f6db713d6ad2a3bd1B7a531282A159", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x935C26F9a9122E5F9a27f2d3803e74c75B94f5a3", + "commit_store": "0xEdb963Ec5c2E5AbdFdCF137eF44A445a7fa4787A", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xfD404A89e1d195F0c65be1A9042C77745197659e", + "commit_store": "0x84B7B012c95f8A152B44Ab3e952f2dEE424fA8e1", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x1c71f141b4630EBE52d6aF4894812960abE207eB", + "commit_store": "0xaB0c8Ba51E7Fa3E5693a4Fbb39473520FD85d173", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0x262e16C8D42aa07bE13e58F81e7D9F62F6DE2830", + "commit_store": "0xc132eFAf929299E5ee704Fa6D9796CFa23Bb8b2C", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Avalanche Fuji": { + "is_native_fee_token": true, + "fee_token": "0xd00ae08403B9bbb9124bB305C09058E32C39A48c", + "bridge_tokens": [ + "0xD21341536c5cF5EB1bcb58f6723cE26e8D8E90e4" + ], + "bridge_tokens_pools": [ + "0xEC1062cbDf4fBf31B3A6Aac62B6F6F123bb70E12" + ], + "arm": "0x7e28DD790214139798446A121cFe950B51304684", + "router": "0xF694E193200268f9a4868e4Aa017A0118C9a8177", + "price_registry": "0x19e157E5fb1DAec1aE4BaB113fdf077F980704AA", + "wrapped_native": "0xd00ae08403B9bbb9124bB305C09058E32C39A48c", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x8bB16BEDbFd62D1f905ACe8DBBF2954c8EEB4f66", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xF25ECF1Aad9B2E43EDc2960cF66f325783245535", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x1A674645f3EB4147543FCA7d40C5719cbd997362", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x1532e5b204ee2b2244170c78E743CB9c168F4DF9", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0xC334DE5b020e056d0fE766dE46e8d9f306Ffa1E2", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0x610F76A35E17DA4542518D85FfEa12645eF111Fc", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x5724B4Cc39a9690135F7273b44Dfd3BA6c0c69aD", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0x677B5ab5C8522d929166c064d5700F147b15fa33", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x90A74072e7B0c2d59e13aB4d8f93c8198c413194", + "commit_store": "0xf3458CFd2fdf4a6CF0Ce296d520DD21eB194828b", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0x10b28009E5D776F1f5AAA73941CE8953B8f42d26", + "commit_store": "0xacDD582F271eCF22FAd6764cCDe1c4a534b732A8", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0xdBdE8510226d1E060A3bf982b67705C67f5697e2", + "commit_store": "0x8Ee73BC9492b4182D289E5C1e66e40CD876CC00F", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x56dF55aF5F0A4689f3364230587a68eD6A314fAd", + "commit_store": "0xabA7ff98094c4cc7A075812EefF2CD21f6400235", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0x3d7CbC95DCC33257F14D6Eb780c88Bd56C6335BB", + "commit_store": "0x1fcDC02edDfb405f378ba53cF9E6104feBcB7542", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x3e33290B90fD0FF30a3FA138934DF028E4eCA348", + "commit_store": "0xCFe3556Aa42d40be09BD23aa80448a19443BE5B1", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x9e5e4324F8608D54A50a317832d456a392E4F8C2", + "commit_store": "0x92A51eD3F041B39EbD1e464C1f7cb1e8f8A8c63f", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0xD0D338318bC6837b091FC7AB5F2a94B7783507d5", + "commit_store": "0xd9D479208235c7355848ff4aF26eB5aacfDC30c6", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "BSC Testnet": { + "is_native_fee_token": true, + "fee_token": "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", + "bridge_tokens": [ + "0xbFA2ACd33ED6EEc0ed3Cc06bF1ac38d22b36B9e9" + ], + "bridge_tokens_pools": [ + "0x31eDe84776DA37e2404eE88d71c234e92cB672e5" + ], + "arm": "0x7D899D26F2E94fFcd4b440C3008B0C6BEfcD3cca", + "router": "0xE1053aE1857476f36A3C62580FF9b016E8EE8F6f", + "price_registry": "0xCCDf022c9d31DC26Ebab4FB92432724a5b79809a", + "wrapped_native": "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0xa2515683E99F50ADbE177519A46bb20FfdBaA5de", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x3E807220Ca84b997c0d1928162227b46C618e0c5", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x8735f991d41eA9cA9D2CC75cD201e4B7C866E63e", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0xf37CcbfC04adc1B56a46B36F811D52C744a1AF78", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0xB1DE44B04C00eaFe9915a3C07a0CaeA4410537dF", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0x89268Afc1BEA0782a27ba84124E3F42b196af927", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0x6e6fFCb6B4BED91ff0CC8C2e57EC029dA7DB80C2", + "commit_store": "0x38Bc38Bd824b6eE87571f9D3CFbe6D6E28E3Dc62", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0x2C61FD7E93Dc79422861282145c59B56dFbc3a8c", + "commit_store": "0x42fAe5B3605804CF6d08632d7A25864e24F792Ae", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x71a44a60832B0F8B63232C9516e7E6aEc3A373Dc", + "commit_store": "0xAC24299a91b72d1Cb5B31147e3CF54964D896974", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x63440C7747d37bc6154b5538AE32b54FE0965AfA", + "commit_store": "0xAD22fA198CECfC534927aE1D480c460d5bB3460F", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xf1c128Fe52Ea78CcAAB407509292E61ce38C1523", + "commit_store": "0x59dFD870dC4bd76A7B879A4f705Fdcd2595f85f9", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0xfd9B19c3725da5B517aA705B848ff3f21F98280e", + "commit_store": "0x3c1F1412563188aBc8FE3fd53E8F1Cb601CaB4f9", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Base Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "bridge_tokens": [ + "0x88A2d74F47a237a62e7A51cdDa67270CE381555e" + ], + "bridge_tokens_pools": [ + "0x875207858c691F192C606068f417dCf666b2EC6B" + ], + "arm": "0x7827dD0481EE18DB646bD250d20A8eA43da52146", + "router": "0xD3b06cEbF099CE7DA4AcCf578aaebFDBd6e88a93", + "price_registry": "0x4D20536e60832bE579Cd38E89Dc03d11E1741FbA", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x58622a80c6DdDc072F2b527a99BE1D0934eb2b50", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0xAbA09a1b7b9f13E05A6241292a66793Ec7d43357", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xD806966beAB5A3C75E5B90CDA4a6922C6A9F0c9d", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x2Eff2d1BF5C557d6289D208a7a43608f5E3FeCc2", + "deployed_at": 0 + }, + "Mode Sepolia": { + "on_ramp": "0x3d0115386C01436870a2c47e6297962284E70BA6", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0x3b39Cd9599137f892Ad57A4f54158198D445D147", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x6486906bB2d85A6c0cCEf2A2831C11A2059ebfea", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xd364C06ac99a82a00d3eFF9F2F78E4Abe4b9baAA", + "commit_store": "0xdE8d0f47a71eA3fDFBD3162271652f2847939097", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0xAd91214efFee446500940c764DF77AF18427294F", + "commit_store": "0x1242b6c5e0e349b8d4BCf0938f961C4B4f7EA3Fa", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0xd5E9508921434e8758f4540D55c1c066b7cc1598", + "commit_store": "0x1a86b29364D1B3fA3386329A361aA98A104b2742", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x9Bb7e398ef9Acfe9cA584C39B1E233Cba62BB9f7", + "commit_store": "0x1F4B82cDebaC5e3a0Dd53183D47e51808B4a64cB", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Mode Sepolia": { + "off_ramp": "0xB26647A23e8b4284375e5C74b77c9557aE709D03", + "commit_store": "0x4b4fEB401d3E613e1D6242E155C83A80BF9ac2C9", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0x86a3910908eCaAA31Fcd9F0fC8841D8E98f1511d", + "commit_store": "0xE99a87C9b5ed4D2b6060195DEea5106ffF655736", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x189F61D9B886Dd2975D5Abc893c8Cf5f5effda71", + "commit_store": "0xEE7e27346DCD1e711348D0F7f7ECB53a9a3a08a7", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Blast Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000023", + "bridge_tokens": [ + "0x8D122C3e8ce9C8B62b87d3551bDfD8C259Bb0771" + ], + "bridge_tokens_pools": [ + "0xFb04129aD1EEDB741CC705ebC1978a7aB63e51f6" + ], + "arm": "0x09c1Ed4b112Fb33e594F2aACfEF407e2F14d7F9b", + "router": "0xfb2f2A207dC428da81fbAFfDDe121761f8Be1194", + "price_registry": "0xc8acE9dF450FaD007755C6C9AB4f0e9c8626E29C", + "wrapped_native": "0x4200000000000000000000000000000000000023", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x85Ef19FC4C63c70744995DC38CAAEC185E0c619f", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0x92cD24C278D34C726f377703E50875d8f9535dC2", + "commit_store": "0xcE1b4D50CeD56850182Bd58Ace91171cB249B873", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Celo Alfajores": { + "is_native_fee_token": true, + "fee_token": "0x99604d0e2EfE7ABFb58BdE565b5330Bb46Ab3Dca", + "bridge_tokens": [ + "0x7e503dd1dAF90117A1b79953321043d9E6815C72" + ], + "bridge_tokens_pools": [ + "0xC6683ac4a0F62803Bec89a5355B36495ddF2C38b" + ], + "arm": "0xEbe35aA4F5e707485484c992AF2069a457b9bBB1", + "router": "0xb00E95b773528E2Ea724DB06B75113F239D15Dca", + "price_registry": "0x8F048206D11B2c69b8963E2EBd5968D141e022f4", + "wrapped_native": "0x99604d0e2EfE7ABFb58BdE565b5330Bb46Ab3Dca", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x16a020c4bbdE363FaB8481262D30516AdbcfcFc8", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0xa1b97F92D806BA040daf419AFC2765DC723683a4", + "commit_store": "0xcd92C0599Ac515e7588865cC45Eee21A74816aFc", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Gnosis Chiado": { + "is_native_fee_token": true, + "fee_token": "0x18c8a7ec7897177E4529065a7E7B0878358B3BfF", + "bridge_tokens": [ + "0xA189971a2c5AcA0DFC5Ee7a2C44a2Ae27b3CF389" + ], + "bridge_tokens_pools": [ + "0xF9a21B587111e7E8745Fb8b13750014f19DB0014" + ], + "arm": "0xfE4fB161D870D0F672Ed9C5A898569603f77983F", + "router": "0x19b1bac554111517831ACadc0FD119D23Bb14391", + "price_registry": "0x2F4ACd1f8986c6B1788159C4c9a5fC3fceCCE363", + "wrapped_native": "0x18c8a7ec7897177E4529065a7E7B0878358B3BfF", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x473b49fb592B54a4BfCD55d40E048431982879C9", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0x610F76A35E17DA4542518D85FfEa12645eF111Fc", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xE48E6AA1fc7D0411acEA95F8C6CaD972A37721D4", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x41b4A51cAfb699D9504E89d19D71F92E886028a8", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0xAae733212981e06D9C978Eb5148F8af03F54b6EF", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0x01800fCDd892e37f7829937271840A6F041bE62E", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x4ac7FBEc2A7298AbDf0E0F4fDC45015836C4bAFe", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x9aA82DBB53bf02096B771D40e9432A323a78fB26", + "commit_store": "0x5CdbA91aBC0cD81FC56bc10Ad1835C9E5fB38e5F", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0x3e33290B90fD0FF30a3FA138934DF028E4eCA348", + "commit_store": "0xCFe3556Aa42d40be09BD23aa80448a19443BE5B1", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0xbc4AD54e91b213D4279af92c0C5518c0b96cf62D", + "commit_store": "0xff84e8Dd4Fd17eaBb23b6AeA6e1981830e54389C", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0x4117953A5ceeF12f5B8C1E973b470ab83a8CebA6", + "commit_store": "0x94ad41296186E81f31e1ed0B1BcF5fa9e1721C27", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0x33d2898F8fb7714FD1661791766f40754982a343", + "commit_store": "0x55d6Df194472f02CD481e506A277c4A29D0D1bCc", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x450543b1d85ca79885851D7b74dc982981b78229", + "commit_store": "0x23B79d940A769FE31b4C867A8BAE80117f24Ca81", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xbf9036529123DE264bFA0FC7362fE25B650D4B16", + "commit_store": "0x5f7F1abD5c5EdaF2636D58B980e85355AF0Ef80d", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Kroma Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000001", + "bridge_tokens": [ + "0x6AC3e353D1DDda24d5A5416024d6E436b8817A4e" + ], + "bridge_tokens_pools": [ + "0x0eE8add19554C7bb1920A183Ed47b4FAB9Eb7601" + ], + "arm": "0x08f9Af992368FAc58C936A2c5eBc9092894CEa9b", + "router": "0xA8C0c11bf64AF62CDCA6f93D3769B88BdD7cb93D", + "price_registry": "0xa1ed3A3aA29166C9c8448654A8cA6b7916BC8379", + "wrapped_native": "0x4200000000000000000000000000000000000001", + "src_contracts": { + "WeMix Testnet": { + "on_ramp": "0x6ea155Fc77566D9dcE01B8aa5D7968665dc4f0C5", + "deployed_at": 0 + } + }, + "dest_contracts": { + "WeMix Testnet": { + "off_ramp": "0xB602B6E5Caf08ac0C920EAE585aed100a8cF6f3B", + "commit_store": "0x89D5b13908b9063abCC6791dc724bF7B7c93634C", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Metis Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x5c48e07062aC4E2Cf4b9A768a711Aef18e8fbdA0", + "bridge_tokens": [ + "0x20Aa09AAb761e2E600d65c6929A9fd1E59821D3f" + ], + "bridge_tokens_pools": [ + "0xdE8451E952Eb43350614839cCAA84f7C8701a09C" + ], + "arm": "0xf0607A9BDdB5F54dB59ACaA0837aFec2D1c95df6", + "router": "0xaCdaBa07ECad81dc634458b98673931DD9d3Bc14", + "price_registry": "0x5DCE866b3ae6E0Ed153f0e149D7203A1B266cdF5", + "wrapped_native": "0x5c48e07062aC4E2Cf4b9A768a711Aef18e8fbdA0", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x2Eff2d1BF5C557d6289D208a7a43608f5E3FeCc2", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0x9Bb7e398ef9Acfe9cA584C39B1E233Cba62BB9f7", + "commit_store": "0x1F4B82cDebaC5e3a0Dd53183D47e51808B4a64cB", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Mode Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "bridge_tokens": [ + "0xB9d4e1141E67ECFedC8A8139b5229b7FF2BF16F5" + ], + "bridge_tokens_pools": [ + "0x20bBc874bE3Cd94C3E4689EDD5D89dD1cE8Cb7C4" + ], + "arm": "0x9eC8a0AbC75ce08978FAf67958482461bCd93B18", + "router": "0xc49ec0eB4beb48B8Da4cceC51AA9A5bD0D0A4c43", + "price_registry": "0xa733ce82a84335b2E9D864312225B0F3D5d80600", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Base Sepolia": { + "on_ramp": "0x73f7E074bd7291706a0C5412f51DB46441B1aDCB", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0xfFdE9E8c34A27BEBeaCcAcB7b3044A0A364455C9", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Base Sepolia": { + "off_ramp": "0x137a38c6b1Ad20101F93516aB2159Df525309168", + "commit_store": "0x8F43d867969F14619895d71E0A5b89E0bb20bF70", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xcD44cec849B6a8eBd5551D6DFeEcA452257Dfe4d", + "commit_store": "0xbA66f08733E6715D33edDfb5a5947676bb45d0e0", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Optimism Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "bridge_tokens": [ + "0x8aF4204e30565DF93352fE8E1De78925F6664dA7" + ], + "bridge_tokens_pools": [ + "0x3Cc9364260D80F09ccAC1eE6B07366dB598900E6" + ], + "arm": "0xF51366F72184E22cF4a7a8362508DB0d3370392d", + "router": "0x114A20A10b43D4115e5aeef7345a1A71d2a60C57", + "price_registry": "0x782a7Ba95215f2F7c3dD4C153cbB2Ae3Ec2d3215", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x1a86b29364D1B3fA3386329A361aA98A104b2742", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0x6b38CC6Fa938D5AB09Bdf0CFe580E226fDD793cE", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0xe284D2315a28c4d62C419e8474dC457b219DB969", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x835a5b8e6CA17c2bB5A336c93a4E22478E6F1C8A", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0x2Cf26fb01E9ccDb831414B766287c0A9e4551089", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0xC8b93b46BF682c39B3F65Aa1c135bC8A95A5E43a", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0xc7E53f6aB982af7A7C3e470c8cCa283d3399BDAd", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xDc2c7A3d8068C6F09F0F3648d24C84e372F6014d", + "commit_store": "0xb1aFb5cbE3c29b5Db71F21442BA9EfD450BC23C3", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0x1F350718e015EB20E5065C09F4A7a3f66888aEeD", + "commit_store": "0x98650A8EB59f75D93563aB34FcF603b1A30e4CBF", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0x0a750ca77369e03613d7640548F4b2b1c695c3Bb", + "commit_store": "0x8fEBC74C26129C8d7E60288C6dCCc75eb494aA3C", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0xCE2CE7F940B7c839384e5D7e079A6aE80e8AD6dB", + "commit_store": "0x1b9D78Ec1CEEC439F0b7eA6C428A1a607D9FA7e4", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0xD667b5706592D0b040C78fEe5EE17D243b7dCB41", + "commit_store": "0x96101BA5250EE9295c193693C1e08A55bC593664", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x260AF9b83e0d2Bb6C9015fC9f0BfF8858A0CCE68", + "commit_store": "0x7a0bB92Bc8663abe6296d0162A9b41a2Cb2E0358", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0x9C08B7712af0344188aa5087D9e6aD0f47191037", + "commit_store": "0x4BE6DB0B884169a6A207fe5cad01eB4C025a13dB", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Polygon Amoy": { + "is_native_fee_token": true, + "fee_token": "0x360ad4f9a9A8EFe9A8DCB5f461c4Cc1047E1Dcf9", + "bridge_tokens": [ + "0xcab0EF91Bee323d1A617c0a027eE753aFd6997E4" + ], + "bridge_tokens_pools": [ + "0x3064fB3EA546EE09A63AB3bD93E83D8B8525C636" + ], + "arm": "0x8b88C39D2875157aB4CE4AD3814409523d539ee1", + "router": "0x9C32fCB86BF0f4a1A8921a9Fe46de3198bb884B2", + "price_registry": "0xfb2f2A207dC428da81fbAFfDDe121761f8Be1194", + "wrapped_native": "0x360ad4f9a9A8EFe9A8DCB5f461c4Cc1047E1Dcf9", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0x8Fb98b3837578aceEA32b454f3221FE18D7Ce903", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xC6683ac4a0F62803Bec89a5355B36495ddF2C38b", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x2331F6D614C9Fd613Ff59a1aB727f1EDf6c37A68", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0xA52cDAeb43803A80B3c0C2296f5cFe57e695BE11", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x35347A2fC1f2a4c5Eae03339040d0b83b09e6FDA", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0x26546096F64B5eF9A1DcDAe70Df6F4f8c2E10C61", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0xa733ce82a84335b2E9D864312225B0F3D5d80600", + "commit_store": "0x09B0F93fC2111aE439e853884173AC5b2F809885", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0x948dfaa4842fc23e0e362Fe8D4396AaE4E6DF7EA", + "commit_store": "0x7F4e739D40E58BBd59dAD388171d18e37B26326f", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x17c542a28e08AEF5697251601C7b2B621d153D42", + "commit_store": "0x811250c20fAB9a1b7ca245453aC214ba637fBEB5", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xfFdE9E8c34A27BEBeaCcAcB7b3044A0A364455C9", + "commit_store": "0x74ED442ad211050e9C05Dc9A267E037E3d74A03B", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xFb04129aD1EEDB741CC705ebC1978a7aB63e51f6", + "commit_store": "0x63f875240149d29136053C954Ca164a9BfA81F77", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0xdE8451E952Eb43350614839cCAA84f7C8701a09C", + "commit_store": "0xaCdaBa07ECad81dc634458b98673931DD9d3Bc14", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Sepolia Testnet": { + "is_native_fee_token": true, + "fee_token": "0x097D90c9d3E0B50Ca60e1ae45F6A81010f9FB534", + "bridge_tokens": [ + "0xFd57b4ddBf88a4e07fF4e34C487b99af2Fe82a05" + ], + "bridge_tokens_pools": [ + "0x38d1ef9619Cd40cf5482C045660Ae7C82Ada062c" + ], + "arm": "0x27Da8735d8d1402cEc072C234759fbbB4dABBC4A", + "router": "0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59", + "price_registry": "0x9EF7D57a4ea30b9e37794E55b0C75F2A70275dCc", + "wrapped_native": "0x097D90c9d3E0B50Ca60e1ae45F6A81010f9FB534", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0xe4Dd3B16E09c016402585a8aDFdB4A18f772a07e", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0x0477cA0a35eE05D3f9f424d88bC0977ceCf339D4", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xD990f8aFA5BCB02f95eEd88ecB7C68f5998bD618", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x2B70a05320cB069e0fB55084D402343F832556E7", + "deployed_at": 0 + }, + "Blast Sepolia": { + "on_ramp": "0xDB75E9D9ca7577CcBd7232741be954cf26194a66", + "deployed_at": 0 + }, + "Celo Alfajores": { + "on_ramp": "0x3C86d16F52C10B2ff6696a0e1b8E0BcfCC085948", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x3E842E3A79A00AFdd03B52390B1caC6306Ea257E", + "deployed_at": 0 + }, + "Metis Sepolia": { + "on_ramp": "0x1C4640914cd57c5f02a68048A0fbb0E12d904223", + "deployed_at": 0 + }, + "Mode Sepolia": { + "on_ramp": "0xc630fbD4D0F6AEB00aD0793FB827b54fBB78e981", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0x69CaB5A0a08a12BaFD8f5B195989D709E396Ed4d", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0x9f656e0361Fb5Df2ac446102c8aB31855B591692", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0xedFc22336Eb0B9B11Ff37C07777db27BCcDe3C65", + "deployed_at": 0 + }, + "ZKSync Sepolia": { + "on_ramp": "0x1Acb3A885feA37bdA30AB99b99327b14391f500F", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xF18896AB20a09A29e64fdEbA99FDb8EC328f43b1", + "commit_store": "0x93Ff9Dd39Dc01eac1fc4d2c9211D95Ee458CAB94", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0x000b26f604eAadC3D874a4404bde6D64a97d95ca", + "commit_store": "0x2dD9273F8208B8393350508131270A6574A69784", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0xdE2d8E126e08d675fCD7fFa5a6CE49925f3Dc692", + "commit_store": "0x0050ac355a82caB31194507f94174297bf0655A7", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0x31c0B81832B333419f0DfD36A69F502cF9094aed", + "commit_store": "0xDFcde9d698a2B32DB2537DC9B752Cadd1D846a52", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Blast Sepolia": { + "off_ramp": "0x4e897e5cF3aC307F0541B2151A88bCD781c153a3", + "commit_store": "0xB656652841F347178e193951C4663652aCe36B74", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Celo Alfajores": { + "off_ramp": "0xB435E0f73c18C5a12C324CA1d02F81F2C3e6e761", + "commit_store": "0xbc5d74957F171e75F92c8F0E1C317A25a56a416D", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x7db0115A0b3AAb01d30bf81123c5DD7B0C41Add5", + "commit_store": "0x6640723Ea801178c4383FA016b9781e7ef1016EF", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Metis Sepolia": { + "off_ramp": "0x4DB693A93E9d5196ECD42EC56CDEAe99dFC652ED", + "commit_store": "0xBfACd78F1412B6f93Ac23409bf456aFec1ABd845", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Mode Sepolia": { + "off_ramp": "0xbEfd8D65F6643De54F0b1268A3bf4618ff85dcB4", + "commit_store": "0x0C161D3470b45Cc677661654C30ce4AdE6aCD288", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xD50590D4438411EDe47029b0FD7901A7145E5Df6", + "commit_store": "0xe85EEE9Fd434A7b8a586Ee086E828abF41839479", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x5032cbC0C4aEeD25bb6E45D8B3fAF05DB0688C5d", + "commit_store": "0xe6201C9996Cc7B6E828E10CbE937E693d577D318", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0x46b639a3C1a4CBfD326b94a2dB7415c27157282f", + "commit_store": "0x7b74554678816b045c1e7409327E086bD436aa46", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "ZKSync Sepolia": { + "off_ramp": "0xBaABd4166C892a1081a26535875A8fA3f22937b2", + "commit_store": "0xfda2e83F4D3f42B7629134ecD6E4b29FB8A7A07B", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "WeMix Testnet": { + "is_native_fee_token": true, + "fee_token": "0xbE3686643c05f00eC46e73da594c78098F7a9Ae7", + "bridge_tokens": [ + "0xF4E4057FbBc86915F4b2d63EEFFe641C03294ffc" + ], + "bridge_tokens_pools": [ + "0x82A92B2863F93Be70D20660088Ec060720bA2fdb" + ], + "arm": "0x8f6cb63eD5e379722580DFF0A051C140C64F9619", + "router": "0xA8C0c11bf64AF62CDCA6f93D3769B88BdD7cb93D", + "price_registry": "0x89D17571DB7C9540eeB36760E3c749C8fb984569", + "wrapped_native": "0xbE3686643c05f00eC46e73da594c78098F7a9Ae7", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0xA9DE3F7A617D67bC50c56baaCb9E0373C15EbfC6", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0xC4aC84da458ba8e40210D2dF94C76E9a41f70069", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0x5AD6eed6Be0ffaDCA4105050CF0E584D87E0c2F1", + "deployed_at": 0 + }, + "Kroma Sepolia": { + "on_ramp": "0x428C4dc89b6Bf908B82d77C9CBceA786ea8cc7D0", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0x1961a7De751451F410391c251D4D4F98D71B767D", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0xd55148e841e76265B484d399eC71b7076ecB1216", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x4d57C6d8037C65fa66D6231844785a428310a735", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xeB1dFaB2464Bf0574D43e764E0c758f92e7ecAFb", + "commit_store": "0xcEaCa2B7890065c485f3E58657358a185Ad33791", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0x98e811Df9D2512f1aaf58D534607F583D6c54A4F", + "commit_store": "0x8e538351F6E5B2daF3c90C565C3738bca69a2716", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0xB0e7f0fCcD3c961C473E7c44D939C1cDb4Cec1cB", + "commit_store": "0x4B56D8d53f1A6e0117B09700067De99581aA5542", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Kroma Sepolia": { + "off_ramp": "0xD685D2d224dd6D0Db2D56497db6270D77D9a7966", + "commit_store": "0x7e062D6880779a0347e7742058C1b1Ee4AA0B137", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xA5f97Bc69Bf06e7C37B93265c5457420A92c5F4b", + "commit_store": "0xd48b9213583074f518D8f4336FDf35370D450132", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x6c8f5999B06FDE17B11E4e3C1062b761766F960f", + "commit_store": "0x957c3c2056192e58A8485eF31165fC490d474239", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x8AB103843ED9D28D2C5DAf5FdB9c3e1CE2B6c876", + "commit_store": "0x7d5297c5506ee2A7Ef121Da9bE02b6a6AD30b392", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "ZKSync Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4317b2eCD41851173175005783322D29E9bAee9E", + "arm": "0x926b4f90610Aa448f27c8e0Fd0afa4A17B7305F9", + "router": "0xA1fdA8aa9A8C4b945C45aD30647b01f07D7A0B16", + "price_registry": "0x648B6BB09bE1C5766C8AC578B9B4aC8497eA671F", + "wrapped_native": "0x4317b2eCD41851173175005783322D29E9bAee9E", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x79a9a5e9e318e8e109776569574814bbf935125a", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0x18FF69051479796175852578725Fc74F58E963F8", + "commit_store": "0xF694b4FD7889480dca3CD41244e8e3395a9EFBa0", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + } + } +} +""" + +[CCIP.Env] +TTL = '8h' + +[CCIP.Env.Network] +selected_networks = [ + 'ARBITRUM_SEPOLIA', + 'AVALANCHE_FUJI', + 'BASE_SEPOLIA', + 'BLAST_SEPOLIA', + 'BSC_TESTNET', + 'CELO_ALFAJORES', + 'GNOSIS_CHIADO', + 'KROMA_SEPOLIA', + 'MODE_SEPOLIA', + 'OPTIMISM_SEPOLIA', + 'POLYGON_AMOY', + 'SEPOLIA', + 'METIS_SEPOLIA', + 'WEMIX_TESTNET', + 'ZKSYNC_SEPOLIA' +] + +[CCIP.Groups.smoke] +# these are all the valid network pairs +NetworkPairs = [ + 'SEPOLIA,AVALANCHE_FUJI', + 'SEPOLIA,BSC_TESTNET', + 'SEPOLIA,CELO_ALFAJORES', + 'SEPOLIA,ARBITRUM_SEPOLIA', + 'SEPOLIA,BASE_SEPOLIA', + 'SEPOLIA,BLAST_SEPOLIA', + 'SEPOLIA,MODE_SEPOLIA', + 'SEPOLIA,OPTIMISM_SEPOLIA', + 'SEPOLIA,POLYGON_AMOY', + 'SEPOLIA,WEMIX_TESTNET', + 'SEPOLIA,GNOSIS_CHIADO', + 'SEPOLIA,METIS_SEPOLIA', + 'SEPOLIA,ZKSYNC_SEPOLIA', + + 'AVALANCHE_FUJI,BSC_TESTNET', + 'AVALANCHE_FUJI,ARBITRUM_SEPOLIA', + 'AVALANCHE_FUJI,BASE_SEPOLIA', + 'AVALANCHE_FUJI,OPTIMISM_SEPOLIA', + 'AVALANCHE_FUJI,POLYGON_AMOY', + 'AVALANCHE_FUJI,WEMIX_TESTNET', + 'AVALANCHE_FUJI,GNOSIS_CHIADO', + + 'BSC_TESTNET,BASE_SEPOLIA', + 'BSC_TESTNET,POLYGON_AMOY', + 'BSC_TESTNET,WEMIX_TESTNET', + 'BSC_TESTNET,GNOSIS_CHIADO', + + 'ARBITRUM_SEPOLIA,BASE_SEPOLIA', + 'ARBITRUM_SEPOLIA,OPTIMISM_SEPOLIA', + 'ARBITRUM_SEPOLIA,WEMIX_TESTNET', + 'ARBITRUM_SEPOLIA,GNOSIS_CHIADO', + + 'BASE_SEPOLIA,MODE_SEPOLIA', + 'BASE_SEPOLIA,OPTIMISM_SEPOLIA', + 'BASE_SEPOLIA,GNOSIS_CHIADO', + + 'KROMA_SEPOLIA,WEMIX_TESTNET', + + 'OPTIMISM_SEPOLIA,POLYGON_AMOY', + 'OPTIMISM_SEPOLIA,WEMIX_TESTNET', + 'OPTIMISM_SEPOLIA,GNOSIS_CHIADO', + + 'POLYGON_AMOY,WEMIX_TESTNET', + 'POLYGON_AMOY,GNOSIS_CHIADO', +] + +BiDirectionalLane = true +PhaseTimeout = '30m' +LocalCluster = false +ExistingDeployment = true +ReuseContracts = true + + +[CCIP.Groups.smoke.TokenConfig] +NoOfTokensPerChain = 1 +CCIPOwnerTokens = true + +[CCIP.Groups.smoke.MsgDetails] +MsgType = 'Data' +DestGasLimit = 0 +DataLength = 100 +NoOfTokens = 1 +AmountPerToken = 1 \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/prod-testnet/smoke-release-testing_token_transfer_native.toml b/integration-tests/ccip-tests/testconfig/tomls/prod-testnet/smoke-release-testing_token_transfer_native.toml new file mode 100644 index 0000000000..b1549377fd --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/prod-testnet/smoke-release-testing_token_transfer_native.toml @@ -0,0 +1,1035 @@ +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = 'latest' +OffRamp = 'latest' +OnRamp = 'latest' +CommitStore = 'latest' +TokenPool = 'latest' + + +[CCIP.Deployments] +Data = """ +{ + "lane_configs": { + "Arbitrum Sepolia": { + "is_native_fee_token": true, + "fee_token": "0xE591bf0A0CF924A0674d7792db046B23CEbF5f34", + "bridge_tokens": [ + "0xA8C0c11bf64AF62CDCA6f93D3769B88BdD7cb93D" + ], + "bridge_tokens_pools": [ + "0x99685281Ec520a003F1A726A5a8078c2124c1477" + ], + "arm": "0xbcBDf0aDEDC9a33ED5338Bdb4B6F7CE664DC2e8B", + "router": "0x2a9C5afB0d0e4BAb2BCdaE109EC4b0c4Be15a165", + "price_registry": "0x89D5b13908b9063abCC6791dc724bF7B7c93634C", + "wrapped_native": "0xE591bf0A0CF924A0674d7792db046B23CEbF5f34", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0x1Cb56374296ED19E86F68fA437ee679FD7798DaA", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x7854E73C73e7F9bb5b0D5B4861E997f4C6E8dcC6", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x973CbE752258D32AE82b60CD1CB656Eebb588dF0", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0x701Fe16916dd21EFE2f535CA59611D818B017877", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x4205E1Ca0202A248A5D42F5975A8FE56F3E302e9", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0xBD4106fBE4699FE212A34Cc21b10BFf22b02d959", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0xcab0EF91Bee323d1A617c0a027eE753aFd6997E4", + "commit_store": "0x0d90b9b96cBFa0D01635ce12982ccE1b70827c7a", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0xc1982985720B959E66c19b64F783361Eb9B60F26", + "commit_store": "0x28F66bB336f6db713d6ad2a3bd1B7a531282A159", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x935C26F9a9122E5F9a27f2d3803e74c75B94f5a3", + "commit_store": "0xEdb963Ec5c2E5AbdFdCF137eF44A445a7fa4787A", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xfD404A89e1d195F0c65be1A9042C77745197659e", + "commit_store": "0x84B7B012c95f8A152B44Ab3e952f2dEE424fA8e1", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x1c71f141b4630EBE52d6aF4894812960abE207eB", + "commit_store": "0xaB0c8Ba51E7Fa3E5693a4Fbb39473520FD85d173", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0x262e16C8D42aa07bE13e58F81e7D9F62F6DE2830", + "commit_store": "0xc132eFAf929299E5ee704Fa6D9796CFa23Bb8b2C", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Avalanche Fuji": { + "is_native_fee_token": true, + "fee_token": "0xd00ae08403B9bbb9124bB305C09058E32C39A48c", + "bridge_tokens": [ + "0xD21341536c5cF5EB1bcb58f6723cE26e8D8E90e4" + ], + "bridge_tokens_pools": [ + "0xEC1062cbDf4fBf31B3A6Aac62B6F6F123bb70E12" + ], + "arm": "0x7e28DD790214139798446A121cFe950B51304684", + "router": "0xF694E193200268f9a4868e4Aa017A0118C9a8177", + "price_registry": "0x19e157E5fb1DAec1aE4BaB113fdf077F980704AA", + "wrapped_native": "0xd00ae08403B9bbb9124bB305C09058E32C39A48c", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x8bB16BEDbFd62D1f905ACe8DBBF2954c8EEB4f66", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xF25ECF1Aad9B2E43EDc2960cF66f325783245535", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x1A674645f3EB4147543FCA7d40C5719cbd997362", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x1532e5b204ee2b2244170c78E743CB9c168F4DF9", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0xC334DE5b020e056d0fE766dE46e8d9f306Ffa1E2", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0x610F76A35E17DA4542518D85FfEa12645eF111Fc", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x5724B4Cc39a9690135F7273b44Dfd3BA6c0c69aD", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0x677B5ab5C8522d929166c064d5700F147b15fa33", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x90A74072e7B0c2d59e13aB4d8f93c8198c413194", + "commit_store": "0xf3458CFd2fdf4a6CF0Ce296d520DD21eB194828b", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0x10b28009E5D776F1f5AAA73941CE8953B8f42d26", + "commit_store": "0xacDD582F271eCF22FAd6764cCDe1c4a534b732A8", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0xdBdE8510226d1E060A3bf982b67705C67f5697e2", + "commit_store": "0x8Ee73BC9492b4182D289E5C1e66e40CD876CC00F", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x56dF55aF5F0A4689f3364230587a68eD6A314fAd", + "commit_store": "0xabA7ff98094c4cc7A075812EefF2CD21f6400235", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0x3d7CbC95DCC33257F14D6Eb780c88Bd56C6335BB", + "commit_store": "0x1fcDC02edDfb405f378ba53cF9E6104feBcB7542", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x3e33290B90fD0FF30a3FA138934DF028E4eCA348", + "commit_store": "0xCFe3556Aa42d40be09BD23aa80448a19443BE5B1", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x9e5e4324F8608D54A50a317832d456a392E4F8C2", + "commit_store": "0x92A51eD3F041B39EbD1e464C1f7cb1e8f8A8c63f", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0xD0D338318bC6837b091FC7AB5F2a94B7783507d5", + "commit_store": "0xd9D479208235c7355848ff4aF26eB5aacfDC30c6", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "BSC Testnet": { + "is_native_fee_token": true, + "fee_token": "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", + "bridge_tokens": [ + "0xbFA2ACd33ED6EEc0ed3Cc06bF1ac38d22b36B9e9" + ], + "bridge_tokens_pools": [ + "0x31eDe84776DA37e2404eE88d71c234e92cB672e5" + ], + "arm": "0x7D899D26F2E94fFcd4b440C3008B0C6BEfcD3cca", + "router": "0xE1053aE1857476f36A3C62580FF9b016E8EE8F6f", + "price_registry": "0xCCDf022c9d31DC26Ebab4FB92432724a5b79809a", + "wrapped_native": "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0xa2515683E99F50ADbE177519A46bb20FfdBaA5de", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x3E807220Ca84b997c0d1928162227b46C618e0c5", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x8735f991d41eA9cA9D2CC75cD201e4B7C866E63e", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0xf37CcbfC04adc1B56a46B36F811D52C744a1AF78", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0xB1DE44B04C00eaFe9915a3C07a0CaeA4410537dF", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0x89268Afc1BEA0782a27ba84124E3F42b196af927", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0x6e6fFCb6B4BED91ff0CC8C2e57EC029dA7DB80C2", + "commit_store": "0x38Bc38Bd824b6eE87571f9D3CFbe6D6E28E3Dc62", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0x2C61FD7E93Dc79422861282145c59B56dFbc3a8c", + "commit_store": "0x42fAe5B3605804CF6d08632d7A25864e24F792Ae", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x71a44a60832B0F8B63232C9516e7E6aEc3A373Dc", + "commit_store": "0xAC24299a91b72d1Cb5B31147e3CF54964D896974", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x63440C7747d37bc6154b5538AE32b54FE0965AfA", + "commit_store": "0xAD22fA198CECfC534927aE1D480c460d5bB3460F", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xf1c128Fe52Ea78CcAAB407509292E61ce38C1523", + "commit_store": "0x59dFD870dC4bd76A7B879A4f705Fdcd2595f85f9", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0xfd9B19c3725da5B517aA705B848ff3f21F98280e", + "commit_store": "0x3c1F1412563188aBc8FE3fd53E8F1Cb601CaB4f9", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Base Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "bridge_tokens": [ + "0x88A2d74F47a237a62e7A51cdDa67270CE381555e" + ], + "bridge_tokens_pools": [ + "0x875207858c691F192C606068f417dCf666b2EC6B" + ], + "arm": "0x7827dD0481EE18DB646bD250d20A8eA43da52146", + "router": "0xD3b06cEbF099CE7DA4AcCf578aaebFDBd6e88a93", + "price_registry": "0x4D20536e60832bE579Cd38E89Dc03d11E1741FbA", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x58622a80c6DdDc072F2b527a99BE1D0934eb2b50", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0xAbA09a1b7b9f13E05A6241292a66793Ec7d43357", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xD806966beAB5A3C75E5B90CDA4a6922C6A9F0c9d", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x2Eff2d1BF5C557d6289D208a7a43608f5E3FeCc2", + "deployed_at": 0 + }, + "Mode Sepolia": { + "on_ramp": "0x3d0115386C01436870a2c47e6297962284E70BA6", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0x3b39Cd9599137f892Ad57A4f54158198D445D147", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x6486906bB2d85A6c0cCEf2A2831C11A2059ebfea", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xd364C06ac99a82a00d3eFF9F2F78E4Abe4b9baAA", + "commit_store": "0xdE8d0f47a71eA3fDFBD3162271652f2847939097", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0xAd91214efFee446500940c764DF77AF18427294F", + "commit_store": "0x1242b6c5e0e349b8d4BCf0938f961C4B4f7EA3Fa", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0xd5E9508921434e8758f4540D55c1c066b7cc1598", + "commit_store": "0x1a86b29364D1B3fA3386329A361aA98A104b2742", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x9Bb7e398ef9Acfe9cA584C39B1E233Cba62BB9f7", + "commit_store": "0x1F4B82cDebaC5e3a0Dd53183D47e51808B4a64cB", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Mode Sepolia": { + "off_ramp": "0xB26647A23e8b4284375e5C74b77c9557aE709D03", + "commit_store": "0x4b4fEB401d3E613e1D6242E155C83A80BF9ac2C9", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0x86a3910908eCaAA31Fcd9F0fC8841D8E98f1511d", + "commit_store": "0xE99a87C9b5ed4D2b6060195DEea5106ffF655736", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x189F61D9B886Dd2975D5Abc893c8Cf5f5effda71", + "commit_store": "0xEE7e27346DCD1e711348D0F7f7ECB53a9a3a08a7", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Blast Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000023", + "bridge_tokens": [ + "0x8D122C3e8ce9C8B62b87d3551bDfD8C259Bb0771" + ], + "bridge_tokens_pools": [ + "0xFb04129aD1EEDB741CC705ebC1978a7aB63e51f6" + ], + "arm": "0x09c1Ed4b112Fb33e594F2aACfEF407e2F14d7F9b", + "router": "0xfb2f2A207dC428da81fbAFfDDe121761f8Be1194", + "price_registry": "0xc8acE9dF450FaD007755C6C9AB4f0e9c8626E29C", + "wrapped_native": "0x4200000000000000000000000000000000000023", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x85Ef19FC4C63c70744995DC38CAAEC185E0c619f", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0x92cD24C278D34C726f377703E50875d8f9535dC2", + "commit_store": "0xcE1b4D50CeD56850182Bd58Ace91171cB249B873", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Celo Alfajores": { + "is_native_fee_token": true, + "fee_token": "0x99604d0e2EfE7ABFb58BdE565b5330Bb46Ab3Dca", + "bridge_tokens": [ + "0x7e503dd1dAF90117A1b79953321043d9E6815C72" + ], + "bridge_tokens_pools": [ + "0xC6683ac4a0F62803Bec89a5355B36495ddF2C38b" + ], + "arm": "0xEbe35aA4F5e707485484c992AF2069a457b9bBB1", + "router": "0xb00E95b773528E2Ea724DB06B75113F239D15Dca", + "price_registry": "0x8F048206D11B2c69b8963E2EBd5968D141e022f4", + "wrapped_native": "0x99604d0e2EfE7ABFb58BdE565b5330Bb46Ab3Dca", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x16a020c4bbdE363FaB8481262D30516AdbcfcFc8", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0xa1b97F92D806BA040daf419AFC2765DC723683a4", + "commit_store": "0xcd92C0599Ac515e7588865cC45Eee21A74816aFc", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Gnosis Chiado": { + "is_native_fee_token": true, + "fee_token": "0x18c8a7ec7897177E4529065a7E7B0878358B3BfF", + "bridge_tokens": [ + "0xA189971a2c5AcA0DFC5Ee7a2C44a2Ae27b3CF389" + ], + "bridge_tokens_pools": [ + "0xF9a21B587111e7E8745Fb8b13750014f19DB0014" + ], + "arm": "0xfE4fB161D870D0F672Ed9C5A898569603f77983F", + "router": "0x19b1bac554111517831ACadc0FD119D23Bb14391", + "price_registry": "0x2F4ACd1f8986c6B1788159C4c9a5fC3fceCCE363", + "wrapped_native": "0x18c8a7ec7897177E4529065a7E7B0878358B3BfF", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x473b49fb592B54a4BfCD55d40E048431982879C9", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0x610F76A35E17DA4542518D85FfEa12645eF111Fc", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xE48E6AA1fc7D0411acEA95F8C6CaD972A37721D4", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x41b4A51cAfb699D9504E89d19D71F92E886028a8", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0xAae733212981e06D9C978Eb5148F8af03F54b6EF", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0x01800fCDd892e37f7829937271840A6F041bE62E", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x4ac7FBEc2A7298AbDf0E0F4fDC45015836C4bAFe", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x9aA82DBB53bf02096B771D40e9432A323a78fB26", + "commit_store": "0x5CdbA91aBC0cD81FC56bc10Ad1835C9E5fB38e5F", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0x3e33290B90fD0FF30a3FA138934DF028E4eCA348", + "commit_store": "0xCFe3556Aa42d40be09BD23aa80448a19443BE5B1", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0xbc4AD54e91b213D4279af92c0C5518c0b96cf62D", + "commit_store": "0xff84e8Dd4Fd17eaBb23b6AeA6e1981830e54389C", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0x4117953A5ceeF12f5B8C1E973b470ab83a8CebA6", + "commit_store": "0x94ad41296186E81f31e1ed0B1BcF5fa9e1721C27", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0x33d2898F8fb7714FD1661791766f40754982a343", + "commit_store": "0x55d6Df194472f02CD481e506A277c4A29D0D1bCc", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x450543b1d85ca79885851D7b74dc982981b78229", + "commit_store": "0x23B79d940A769FE31b4C867A8BAE80117f24Ca81", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xbf9036529123DE264bFA0FC7362fE25B650D4B16", + "commit_store": "0x5f7F1abD5c5EdaF2636D58B980e85355AF0Ef80d", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Kroma Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000001", + "bridge_tokens": [ + "0x6AC3e353D1DDda24d5A5416024d6E436b8817A4e" + ], + "bridge_tokens_pools": [ + "0x0eE8add19554C7bb1920A183Ed47b4FAB9Eb7601" + ], + "arm": "0x08f9Af992368FAc58C936A2c5eBc9092894CEa9b", + "router": "0xA8C0c11bf64AF62CDCA6f93D3769B88BdD7cb93D", + "price_registry": "0xa1ed3A3aA29166C9c8448654A8cA6b7916BC8379", + "wrapped_native": "0x4200000000000000000000000000000000000001", + "src_contracts": { + "WeMix Testnet": { + "on_ramp": "0x6ea155Fc77566D9dcE01B8aa5D7968665dc4f0C5", + "deployed_at": 0 + } + }, + "dest_contracts": { + "WeMix Testnet": { + "off_ramp": "0xB602B6E5Caf08ac0C920EAE585aed100a8cF6f3B", + "commit_store": "0x89D5b13908b9063abCC6791dc724bF7B7c93634C", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Metis Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x5c48e07062aC4E2Cf4b9A768a711Aef18e8fbdA0", + "bridge_tokens": [ + "0x20Aa09AAb761e2E600d65c6929A9fd1E59821D3f" + ], + "bridge_tokens_pools": [ + "0xdE8451E952Eb43350614839cCAA84f7C8701a09C" + ], + "arm": "0xf0607A9BDdB5F54dB59ACaA0837aFec2D1c95df6", + "router": "0xaCdaBa07ECad81dc634458b98673931DD9d3Bc14", + "price_registry": "0x5DCE866b3ae6E0Ed153f0e149D7203A1B266cdF5", + "wrapped_native": "0x5c48e07062aC4E2Cf4b9A768a711Aef18e8fbdA0", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x2Eff2d1BF5C557d6289D208a7a43608f5E3FeCc2", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0x9Bb7e398ef9Acfe9cA584C39B1E233Cba62BB9f7", + "commit_store": "0x1F4B82cDebaC5e3a0Dd53183D47e51808B4a64cB", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Mode Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "bridge_tokens": [ + "0xB9d4e1141E67ECFedC8A8139b5229b7FF2BF16F5" + ], + "bridge_tokens_pools": [ + "0x20bBc874bE3Cd94C3E4689EDD5D89dD1cE8Cb7C4" + ], + "arm": "0x9eC8a0AbC75ce08978FAf67958482461bCd93B18", + "router": "0xc49ec0eB4beb48B8Da4cceC51AA9A5bD0D0A4c43", + "price_registry": "0xa733ce82a84335b2E9D864312225B0F3D5d80600", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Base Sepolia": { + "on_ramp": "0x73f7E074bd7291706a0C5412f51DB46441B1aDCB", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0xfFdE9E8c34A27BEBeaCcAcB7b3044A0A364455C9", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Base Sepolia": { + "off_ramp": "0x137a38c6b1Ad20101F93516aB2159Df525309168", + "commit_store": "0x8F43d867969F14619895d71E0A5b89E0bb20bF70", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xcD44cec849B6a8eBd5551D6DFeEcA452257Dfe4d", + "commit_store": "0xbA66f08733E6715D33edDfb5a5947676bb45d0e0", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Optimism Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "bridge_tokens": [ + "0x8aF4204e30565DF93352fE8E1De78925F6664dA7" + ], + "bridge_tokens_pools": [ + "0x3Cc9364260D80F09ccAC1eE6B07366dB598900E6" + ], + "arm": "0xF51366F72184E22cF4a7a8362508DB0d3370392d", + "router": "0x114A20A10b43D4115e5aeef7345a1A71d2a60C57", + "price_registry": "0x782a7Ba95215f2F7c3dD4C153cbB2Ae3Ec2d3215", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x1a86b29364D1B3fA3386329A361aA98A104b2742", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0x6b38CC6Fa938D5AB09Bdf0CFe580E226fDD793cE", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0xe284D2315a28c4d62C419e8474dC457b219DB969", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x835a5b8e6CA17c2bB5A336c93a4E22478E6F1C8A", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0x2Cf26fb01E9ccDb831414B766287c0A9e4551089", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0xC8b93b46BF682c39B3F65Aa1c135bC8A95A5E43a", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0xc7E53f6aB982af7A7C3e470c8cCa283d3399BDAd", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xDc2c7A3d8068C6F09F0F3648d24C84e372F6014d", + "commit_store": "0xb1aFb5cbE3c29b5Db71F21442BA9EfD450BC23C3", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0x1F350718e015EB20E5065C09F4A7a3f66888aEeD", + "commit_store": "0x98650A8EB59f75D93563aB34FcF603b1A30e4CBF", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0x0a750ca77369e03613d7640548F4b2b1c695c3Bb", + "commit_store": "0x8fEBC74C26129C8d7E60288C6dCCc75eb494aA3C", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0xCE2CE7F940B7c839384e5D7e079A6aE80e8AD6dB", + "commit_store": "0x1b9D78Ec1CEEC439F0b7eA6C428A1a607D9FA7e4", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0xD667b5706592D0b040C78fEe5EE17D243b7dCB41", + "commit_store": "0x96101BA5250EE9295c193693C1e08A55bC593664", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x260AF9b83e0d2Bb6C9015fC9f0BfF8858A0CCE68", + "commit_store": "0x7a0bB92Bc8663abe6296d0162A9b41a2Cb2E0358", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0x9C08B7712af0344188aa5087D9e6aD0f47191037", + "commit_store": "0x4BE6DB0B884169a6A207fe5cad01eB4C025a13dB", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Polygon Amoy": { + "is_native_fee_token": true, + "fee_token": "0x360ad4f9a9A8EFe9A8DCB5f461c4Cc1047E1Dcf9", + "bridge_tokens": [ + "0xcab0EF91Bee323d1A617c0a027eE753aFd6997E4" + ], + "bridge_tokens_pools": [ + "0x3064fB3EA546EE09A63AB3bD93E83D8B8525C636" + ], + "arm": "0x8b88C39D2875157aB4CE4AD3814409523d539ee1", + "router": "0x9C32fCB86BF0f4a1A8921a9Fe46de3198bb884B2", + "price_registry": "0xfb2f2A207dC428da81fbAFfDDe121761f8Be1194", + "wrapped_native": "0x360ad4f9a9A8EFe9A8DCB5f461c4Cc1047E1Dcf9", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0x8Fb98b3837578aceEA32b454f3221FE18D7Ce903", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xC6683ac4a0F62803Bec89a5355B36495ddF2C38b", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x2331F6D614C9Fd613Ff59a1aB727f1EDf6c37A68", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0xA52cDAeb43803A80B3c0C2296f5cFe57e695BE11", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x35347A2fC1f2a4c5Eae03339040d0b83b09e6FDA", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0x26546096F64B5eF9A1DcDAe70Df6F4f8c2E10C61", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0xa733ce82a84335b2E9D864312225B0F3D5d80600", + "commit_store": "0x09B0F93fC2111aE439e853884173AC5b2F809885", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0x948dfaa4842fc23e0e362Fe8D4396AaE4E6DF7EA", + "commit_store": "0x7F4e739D40E58BBd59dAD388171d18e37B26326f", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x17c542a28e08AEF5697251601C7b2B621d153D42", + "commit_store": "0x811250c20fAB9a1b7ca245453aC214ba637fBEB5", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xfFdE9E8c34A27BEBeaCcAcB7b3044A0A364455C9", + "commit_store": "0x74ED442ad211050e9C05Dc9A267E037E3d74A03B", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xFb04129aD1EEDB741CC705ebC1978a7aB63e51f6", + "commit_store": "0x63f875240149d29136053C954Ca164a9BfA81F77", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0xdE8451E952Eb43350614839cCAA84f7C8701a09C", + "commit_store": "0xaCdaBa07ECad81dc634458b98673931DD9d3Bc14", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Sepolia Testnet": { + "is_native_fee_token": true, + "fee_token": "0x097D90c9d3E0B50Ca60e1ae45F6A81010f9FB534", + "bridge_tokens": [ + "0xFd57b4ddBf88a4e07fF4e34C487b99af2Fe82a05" + ], + "bridge_tokens_pools": [ + "0x38d1ef9619Cd40cf5482C045660Ae7C82Ada062c" + ], + "arm": "0x27Da8735d8d1402cEc072C234759fbbB4dABBC4A", + "router": "0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59", + "price_registry": "0x9EF7D57a4ea30b9e37794E55b0C75F2A70275dCc", + "wrapped_native": "0x097D90c9d3E0B50Ca60e1ae45F6A81010f9FB534", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0xe4Dd3B16E09c016402585a8aDFdB4A18f772a07e", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0x0477cA0a35eE05D3f9f424d88bC0977ceCf339D4", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xD990f8aFA5BCB02f95eEd88ecB7C68f5998bD618", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x2B70a05320cB069e0fB55084D402343F832556E7", + "deployed_at": 0 + }, + "Blast Sepolia": { + "on_ramp": "0xDB75E9D9ca7577CcBd7232741be954cf26194a66", + "deployed_at": 0 + }, + "Celo Alfajores": { + "on_ramp": "0x3C86d16F52C10B2ff6696a0e1b8E0BcfCC085948", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x3E842E3A79A00AFdd03B52390B1caC6306Ea257E", + "deployed_at": 0 + }, + "Metis Sepolia": { + "on_ramp": "0x1C4640914cd57c5f02a68048A0fbb0E12d904223", + "deployed_at": 0 + }, + "Mode Sepolia": { + "on_ramp": "0xc630fbD4D0F6AEB00aD0793FB827b54fBB78e981", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0x69CaB5A0a08a12BaFD8f5B195989D709E396Ed4d", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0x9f656e0361Fb5Df2ac446102c8aB31855B591692", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0xedFc22336Eb0B9B11Ff37C07777db27BCcDe3C65", + "deployed_at": 0 + }, + "ZKSync Sepolia": { + "on_ramp": "0x1Acb3A885feA37bdA30AB99b99327b14391f500F", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xF18896AB20a09A29e64fdEbA99FDb8EC328f43b1", + "commit_store": "0x93Ff9Dd39Dc01eac1fc4d2c9211D95Ee458CAB94", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0x000b26f604eAadC3D874a4404bde6D64a97d95ca", + "commit_store": "0x2dD9273F8208B8393350508131270A6574A69784", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0xdE2d8E126e08d675fCD7fFa5a6CE49925f3Dc692", + "commit_store": "0x0050ac355a82caB31194507f94174297bf0655A7", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0x31c0B81832B333419f0DfD36A69F502cF9094aed", + "commit_store": "0xDFcde9d698a2B32DB2537DC9B752Cadd1D846a52", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Blast Sepolia": { + "off_ramp": "0x4e897e5cF3aC307F0541B2151A88bCD781c153a3", + "commit_store": "0xB656652841F347178e193951C4663652aCe36B74", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Celo Alfajores": { + "off_ramp": "0xB435E0f73c18C5a12C324CA1d02F81F2C3e6e761", + "commit_store": "0xbc5d74957F171e75F92c8F0E1C317A25a56a416D", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x7db0115A0b3AAb01d30bf81123c5DD7B0C41Add5", + "commit_store": "0x6640723Ea801178c4383FA016b9781e7ef1016EF", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Metis Sepolia": { + "off_ramp": "0x4DB693A93E9d5196ECD42EC56CDEAe99dFC652ED", + "commit_store": "0xBfACd78F1412B6f93Ac23409bf456aFec1ABd845", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Mode Sepolia": { + "off_ramp": "0xbEfd8D65F6643De54F0b1268A3bf4618ff85dcB4", + "commit_store": "0x0C161D3470b45Cc677661654C30ce4AdE6aCD288", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xD50590D4438411EDe47029b0FD7901A7145E5Df6", + "commit_store": "0xe85EEE9Fd434A7b8a586Ee086E828abF41839479", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x5032cbC0C4aEeD25bb6E45D8B3fAF05DB0688C5d", + "commit_store": "0xe6201C9996Cc7B6E828E10CbE937E693d577D318", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0x46b639a3C1a4CBfD326b94a2dB7415c27157282f", + "commit_store": "0x7b74554678816b045c1e7409327E086bD436aa46", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "ZKSync Sepolia": { + "off_ramp": "0xBaABd4166C892a1081a26535875A8fA3f22937b2", + "commit_store": "0xfda2e83F4D3f42B7629134ecD6E4b29FB8A7A07B", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "WeMix Testnet": { + "is_native_fee_token": true, + "fee_token": "0xbE3686643c05f00eC46e73da594c78098F7a9Ae7", + "bridge_tokens": [ + "0xF4E4057FbBc86915F4b2d63EEFFe641C03294ffc" + ], + "bridge_tokens_pools": [ + "0x82A92B2863F93Be70D20660088Ec060720bA2fdb" + ], + "arm": "0x8f6cb63eD5e379722580DFF0A051C140C64F9619", + "router": "0xA8C0c11bf64AF62CDCA6f93D3769B88BdD7cb93D", + "price_registry": "0x89D17571DB7C9540eeB36760E3c749C8fb984569", + "wrapped_native": "0xbE3686643c05f00eC46e73da594c78098F7a9Ae7", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0xA9DE3F7A617D67bC50c56baaCb9E0373C15EbfC6", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0xC4aC84da458ba8e40210D2dF94C76E9a41f70069", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0x5AD6eed6Be0ffaDCA4105050CF0E584D87E0c2F1", + "deployed_at": 0 + }, + "Kroma Sepolia": { + "on_ramp": "0x428C4dc89b6Bf908B82d77C9CBceA786ea8cc7D0", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0x1961a7De751451F410391c251D4D4F98D71B767D", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0xd55148e841e76265B484d399eC71b7076ecB1216", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x4d57C6d8037C65fa66D6231844785a428310a735", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xeB1dFaB2464Bf0574D43e764E0c758f92e7ecAFb", + "commit_store": "0xcEaCa2B7890065c485f3E58657358a185Ad33791", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0x98e811Df9D2512f1aaf58D534607F583D6c54A4F", + "commit_store": "0x8e538351F6E5B2daF3c90C565C3738bca69a2716", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0xB0e7f0fCcD3c961C473E7c44D939C1cDb4Cec1cB", + "commit_store": "0x4B56D8d53f1A6e0117B09700067De99581aA5542", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Kroma Sepolia": { + "off_ramp": "0xD685D2d224dd6D0Db2D56497db6270D77D9a7966", + "commit_store": "0x7e062D6880779a0347e7742058C1b1Ee4AA0B137", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xA5f97Bc69Bf06e7C37B93265c5457420A92c5F4b", + "commit_store": "0xd48b9213583074f518D8f4336FDf35370D450132", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x6c8f5999B06FDE17B11E4e3C1062b761766F960f", + "commit_store": "0x957c3c2056192e58A8485eF31165fC490d474239", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x8AB103843ED9D28D2C5DAf5FdB9c3e1CE2B6c876", + "commit_store": "0x7d5297c5506ee2A7Ef121Da9bE02b6a6AD30b392", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "ZKSync Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4317b2eCD41851173175005783322D29E9bAee9E", + "arm": "0x926b4f90610Aa448f27c8e0Fd0afa4A17B7305F9", + "router": "0xA1fdA8aa9A8C4b945C45aD30647b01f07D7A0B16", + "price_registry": "0x648B6BB09bE1C5766C8AC578B9B4aC8497eA671F", + "wrapped_native": "0x4317b2eCD41851173175005783322D29E9bAee9E", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x79a9a5e9e318e8e109776569574814bbf935125a", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0x18FF69051479796175852578725Fc74F58E963F8", + "commit_store": "0xF694b4FD7889480dca3CD41244e8e3395a9EFBa0", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + } + } +} +""" + +[CCIP.Env] +TTL = '8h' + +[CCIP.Env.Network] +selected_networks = [ + 'ARBITRUM_SEPOLIA', + 'AVALANCHE_FUJI', + 'BASE_SEPOLIA', + 'BLAST_SEPOLIA', + 'BSC_TESTNET', + 'CELO_ALFAJORES', + 'GNOSIS_CHIADO', + 'KROMA_SEPOLIA', + 'MODE_SEPOLIA', + 'OPTIMISM_SEPOLIA', + 'POLYGON_AMOY', + 'SEPOLIA', + 'METIS_SEPOLIA', + 'WEMIX_TESTNET', + 'ZKSYNC_SEPOLIA' +] + +[CCIP.Groups.smoke] +# these are all the valid network pairs +NetworkPairs = [ + 'SEPOLIA,AVALANCHE_FUJI', + 'SEPOLIA,BSC_TESTNET', + 'SEPOLIA,CELO_ALFAJORES', + 'SEPOLIA,ARBITRUM_SEPOLIA', + 'SEPOLIA,BASE_SEPOLIA', + 'SEPOLIA,BLAST_SEPOLIA', + 'SEPOLIA,MODE_SEPOLIA', + 'SEPOLIA,OPTIMISM_SEPOLIA', + 'SEPOLIA,POLYGON_AMOY', + 'SEPOLIA,WEMIX_TESTNET', + 'SEPOLIA,GNOSIS_CHIADO', + 'SEPOLIA,METIS_SEPOLIA', + 'SEPOLIA,ZKSYNC_SEPOLIA', + + 'AVALANCHE_FUJI,BSC_TESTNET', + 'AVALANCHE_FUJI,ARBITRUM_SEPOLIA', + 'AVALANCHE_FUJI,BASE_SEPOLIA', + 'AVALANCHE_FUJI,OPTIMISM_SEPOLIA', + 'AVALANCHE_FUJI,POLYGON_AMOY', + 'AVALANCHE_FUJI,WEMIX_TESTNET', + 'AVALANCHE_FUJI,GNOSIS_CHIADO', + + 'BSC_TESTNET,BASE_SEPOLIA', + 'BSC_TESTNET,POLYGON_AMOY', + 'BSC_TESTNET,WEMIX_TESTNET', + 'BSC_TESTNET,GNOSIS_CHIADO', + + 'ARBITRUM_SEPOLIA,BASE_SEPOLIA', + 'ARBITRUM_SEPOLIA,OPTIMISM_SEPOLIA', + 'ARBITRUM_SEPOLIA,WEMIX_TESTNET', + 'ARBITRUM_SEPOLIA,GNOSIS_CHIADO', + + 'BASE_SEPOLIA,MODE_SEPOLIA', + 'BASE_SEPOLIA,OPTIMISM_SEPOLIA', + 'BASE_SEPOLIA,GNOSIS_CHIADO', + + 'KROMA_SEPOLIA,WEMIX_TESTNET', + + 'OPTIMISM_SEPOLIA,POLYGON_AMOY', + 'OPTIMISM_SEPOLIA,WEMIX_TESTNET', + 'OPTIMISM_SEPOLIA,GNOSIS_CHIADO', + + 'POLYGON_AMOY,WEMIX_TESTNET', + 'POLYGON_AMOY,GNOSIS_CHIADO', +] + +BiDirectionalLane = true +PhaseTimeout = '30m' +LocalCluster = false +ExistingDeployment = true +ReuseContracts = true + + +[CCIP.Groups.smoke.TokenConfig] +NoOfTokensPerChain = 1 +CCIPOwnerTokens = true + +[CCIP.Groups.smoke.MsgDetails] +MsgType = 'DataWithToken' +DestGasLimit = 0 +DataLength = 100 +NoOfTokens = 1 +AmountPerToken = 1 \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/tomls/prod-testnet/soak-release-testing_token_transfer_with_native_feetoken.toml b/integration-tests/ccip-tests/testconfig/tomls/prod-testnet/soak-release-testing_token_transfer_with_native_feetoken.toml new file mode 100644 index 0000000000..6a6aa205fc --- /dev/null +++ b/integration-tests/ccip-tests/testconfig/tomls/prod-testnet/soak-release-testing_token_transfer_with_native_feetoken.toml @@ -0,0 +1,1013 @@ +[CCIP] +[CCIP.ContractVersions] +PriceRegistry = '1.2.0' +OffRamp = '1.2.0' +OnRamp = '1.2.0' +TokenPool = '1.4.0' +CommitStore = '1.2.0' + + +[CCIP.Deployments] +Data = """ +{ + "lane_configs": { + "Arbitrum Sepolia": { + "is_native_fee_token": true, + "fee_token": "0xE591bf0A0CF924A0674d7792db046B23CEbF5f34", + "bridge_tokens": [ + "0xA8C0c11bf64AF62CDCA6f93D3769B88BdD7cb93D" + ], + "bridge_tokens_pools": [ + "0x99685281Ec520a003F1A726A5a8078c2124c1477" + ], + "arm": "0xbcBDf0aDEDC9a33ED5338Bdb4B6F7CE664DC2e8B", + "router": "0x2a9C5afB0d0e4BAb2BCdaE109EC4b0c4Be15a165", + "price_registry": "0x89D5b13908b9063abCC6791dc724bF7B7c93634C", + "wrapped_native": "0xE591bf0A0CF924A0674d7792db046B23CEbF5f34", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0x1Cb56374296ED19E86F68fA437ee679FD7798DaA", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x7854E73C73e7F9bb5b0D5B4861E997f4C6E8dcC6", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x973CbE752258D32AE82b60CD1CB656Eebb588dF0", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0x701Fe16916dd21EFE2f535CA59611D818B017877", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x4205E1Ca0202A248A5D42F5975A8FE56F3E302e9", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0xBD4106fBE4699FE212A34Cc21b10BFf22b02d959", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0xcab0EF91Bee323d1A617c0a027eE753aFd6997E4", + "commit_store": "0x0d90b9b96cBFa0D01635ce12982ccE1b70827c7a", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0xc1982985720B959E66c19b64F783361Eb9B60F26", + "commit_store": "0x28F66bB336f6db713d6ad2a3bd1B7a531282A159", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x935C26F9a9122E5F9a27f2d3803e74c75B94f5a3", + "commit_store": "0xEdb963Ec5c2E5AbdFdCF137eF44A445a7fa4787A", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xfD404A89e1d195F0c65be1A9042C77745197659e", + "commit_store": "0x84B7B012c95f8A152B44Ab3e952f2dEE424fA8e1", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x1c71f141b4630EBE52d6aF4894812960abE207eB", + "commit_store": "0xaB0c8Ba51E7Fa3E5693a4Fbb39473520FD85d173", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0x262e16C8D42aa07bE13e58F81e7D9F62F6DE2830", + "commit_store": "0xc132eFAf929299E5ee704Fa6D9796CFa23Bb8b2C", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Avalanche Fuji": { + "is_native_fee_token": true, + "fee_token": "0xd00ae08403B9bbb9124bB305C09058E32C39A48c", + "bridge_tokens": [ + "0xD21341536c5cF5EB1bcb58f6723cE26e8D8E90e4" + ], + "bridge_tokens_pools": [ + "0xEC1062cbDf4fBf31B3A6Aac62B6F6F123bb70E12" + ], + "arm": "0x7e28DD790214139798446A121cFe950B51304684", + "router": "0xF694E193200268f9a4868e4Aa017A0118C9a8177", + "price_registry": "0x19e157E5fb1DAec1aE4BaB113fdf077F980704AA", + "wrapped_native": "0xd00ae08403B9bbb9124bB305C09058E32C39A48c", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x8bB16BEDbFd62D1f905ACe8DBBF2954c8EEB4f66", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xF25ECF1Aad9B2E43EDc2960cF66f325783245535", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x1A674645f3EB4147543FCA7d40C5719cbd997362", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x1532e5b204ee2b2244170c78E743CB9c168F4DF9", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0xC334DE5b020e056d0fE766dE46e8d9f306Ffa1E2", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0x610F76A35E17DA4542518D85FfEa12645eF111Fc", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x5724B4Cc39a9690135F7273b44Dfd3BA6c0c69aD", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0x677B5ab5C8522d929166c064d5700F147b15fa33", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x90A74072e7B0c2d59e13aB4d8f93c8198c413194", + "commit_store": "0xf3458CFd2fdf4a6CF0Ce296d520DD21eB194828b", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0x10b28009E5D776F1f5AAA73941CE8953B8f42d26", + "commit_store": "0xacDD582F271eCF22FAd6764cCDe1c4a534b732A8", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0xdBdE8510226d1E060A3bf982b67705C67f5697e2", + "commit_store": "0x8Ee73BC9492b4182D289E5C1e66e40CD876CC00F", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x56dF55aF5F0A4689f3364230587a68eD6A314fAd", + "commit_store": "0xabA7ff98094c4cc7A075812EefF2CD21f6400235", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0x3d7CbC95DCC33257F14D6Eb780c88Bd56C6335BB", + "commit_store": "0x1fcDC02edDfb405f378ba53cF9E6104feBcB7542", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x3e33290B90fD0FF30a3FA138934DF028E4eCA348", + "commit_store": "0xCFe3556Aa42d40be09BD23aa80448a19443BE5B1", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x9e5e4324F8608D54A50a317832d456a392E4F8C2", + "commit_store": "0x92A51eD3F041B39EbD1e464C1f7cb1e8f8A8c63f", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0xD0D338318bC6837b091FC7AB5F2a94B7783507d5", + "commit_store": "0xd9D479208235c7355848ff4aF26eB5aacfDC30c6", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "BSC Testnet": { + "is_native_fee_token": true, + "fee_token": "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", + "bridge_tokens": [ + "0xbFA2ACd33ED6EEc0ed3Cc06bF1ac38d22b36B9e9" + ], + "bridge_tokens_pools": [ + "0x31eDe84776DA37e2404eE88d71c234e92cB672e5" + ], + "arm": "0x7D899D26F2E94fFcd4b440C3008B0C6BEfcD3cca", + "router": "0xE1053aE1857476f36A3C62580FF9b016E8EE8F6f", + "price_registry": "0xCCDf022c9d31DC26Ebab4FB92432724a5b79809a", + "wrapped_native": "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0xa2515683E99F50ADbE177519A46bb20FfdBaA5de", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x3E807220Ca84b997c0d1928162227b46C618e0c5", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x8735f991d41eA9cA9D2CC75cD201e4B7C866E63e", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0xf37CcbfC04adc1B56a46B36F811D52C744a1AF78", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0xB1DE44B04C00eaFe9915a3C07a0CaeA4410537dF", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0x89268Afc1BEA0782a27ba84124E3F42b196af927", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0x6e6fFCb6B4BED91ff0CC8C2e57EC029dA7DB80C2", + "commit_store": "0x38Bc38Bd824b6eE87571f9D3CFbe6D6E28E3Dc62", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0x2C61FD7E93Dc79422861282145c59B56dFbc3a8c", + "commit_store": "0x42fAe5B3605804CF6d08632d7A25864e24F792Ae", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x71a44a60832B0F8B63232C9516e7E6aEc3A373Dc", + "commit_store": "0xAC24299a91b72d1Cb5B31147e3CF54964D896974", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x63440C7747d37bc6154b5538AE32b54FE0965AfA", + "commit_store": "0xAD22fA198CECfC534927aE1D480c460d5bB3460F", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xf1c128Fe52Ea78CcAAB407509292E61ce38C1523", + "commit_store": "0x59dFD870dC4bd76A7B879A4f705Fdcd2595f85f9", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0xfd9B19c3725da5B517aA705B848ff3f21F98280e", + "commit_store": "0x3c1F1412563188aBc8FE3fd53E8F1Cb601CaB4f9", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Base Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "bridge_tokens": [ + "0x88A2d74F47a237a62e7A51cdDa67270CE381555e" + ], + "bridge_tokens_pools": [ + "0x875207858c691F192C606068f417dCf666b2EC6B" + ], + "arm": "0x7827dD0481EE18DB646bD250d20A8eA43da52146", + "router": "0xD3b06cEbF099CE7DA4AcCf578aaebFDBd6e88a93", + "price_registry": "0x4D20536e60832bE579Cd38E89Dc03d11E1741FbA", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x58622a80c6DdDc072F2b527a99BE1D0934eb2b50", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0xAbA09a1b7b9f13E05A6241292a66793Ec7d43357", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xD806966beAB5A3C75E5B90CDA4a6922C6A9F0c9d", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x2Eff2d1BF5C557d6289D208a7a43608f5E3FeCc2", + "deployed_at": 0 + }, + "Mode Sepolia": { + "on_ramp": "0x3d0115386C01436870a2c47e6297962284E70BA6", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0x3b39Cd9599137f892Ad57A4f54158198D445D147", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x6486906bB2d85A6c0cCEf2A2831C11A2059ebfea", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xd364C06ac99a82a00d3eFF9F2F78E4Abe4b9baAA", + "commit_store": "0xdE8d0f47a71eA3fDFBD3162271652f2847939097", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0xAd91214efFee446500940c764DF77AF18427294F", + "commit_store": "0x1242b6c5e0e349b8d4BCf0938f961C4B4f7EA3Fa", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0xd5E9508921434e8758f4540D55c1c066b7cc1598", + "commit_store": "0x1a86b29364D1B3fA3386329A361aA98A104b2742", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x9Bb7e398ef9Acfe9cA584C39B1E233Cba62BB9f7", + "commit_store": "0x1F4B82cDebaC5e3a0Dd53183D47e51808B4a64cB", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Mode Sepolia": { + "off_ramp": "0xB26647A23e8b4284375e5C74b77c9557aE709D03", + "commit_store": "0x4b4fEB401d3E613e1D6242E155C83A80BF9ac2C9", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0x86a3910908eCaAA31Fcd9F0fC8841D8E98f1511d", + "commit_store": "0xE99a87C9b5ed4D2b6060195DEea5106ffF655736", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x189F61D9B886Dd2975D5Abc893c8Cf5f5effda71", + "commit_store": "0xEE7e27346DCD1e711348D0F7f7ECB53a9a3a08a7", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Blast Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000023", + "bridge_tokens": [ + "0x8D122C3e8ce9C8B62b87d3551bDfD8C259Bb0771" + ], + "bridge_tokens_pools": [ + "0xFb04129aD1EEDB741CC705ebC1978a7aB63e51f6" + ], + "arm": "0x09c1Ed4b112Fb33e594F2aACfEF407e2F14d7F9b", + "router": "0xfb2f2A207dC428da81fbAFfDDe121761f8Be1194", + "price_registry": "0xc8acE9dF450FaD007755C6C9AB4f0e9c8626E29C", + "wrapped_native": "0x4200000000000000000000000000000000000023", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x85Ef19FC4C63c70744995DC38CAAEC185E0c619f", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0x92cD24C278D34C726f377703E50875d8f9535dC2", + "commit_store": "0xcE1b4D50CeD56850182Bd58Ace91171cB249B873", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Celo Alfajores": { + "is_native_fee_token": true, + "fee_token": "0x99604d0e2EfE7ABFb58BdE565b5330Bb46Ab3Dca", + "bridge_tokens": [ + "0x7e503dd1dAF90117A1b79953321043d9E6815C72" + ], + "bridge_tokens_pools": [ + "0xC6683ac4a0F62803Bec89a5355B36495ddF2C38b" + ], + "arm": "0xEbe35aA4F5e707485484c992AF2069a457b9bBB1", + "router": "0xb00E95b773528E2Ea724DB06B75113F239D15Dca", + "price_registry": "0x8F048206D11B2c69b8963E2EBd5968D141e022f4", + "wrapped_native": "0x99604d0e2EfE7ABFb58BdE565b5330Bb46Ab3Dca", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x16a020c4bbdE363FaB8481262D30516AdbcfcFc8", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0xa1b97F92D806BA040daf419AFC2765DC723683a4", + "commit_store": "0xcd92C0599Ac515e7588865cC45Eee21A74816aFc", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Gnosis Chiado": { + "is_native_fee_token": true, + "fee_token": "0x18c8a7ec7897177E4529065a7E7B0878358B3BfF", + "bridge_tokens": [ + "0xA189971a2c5AcA0DFC5Ee7a2C44a2Ae27b3CF389" + ], + "bridge_tokens_pools": [ + "0xF9a21B587111e7E8745Fb8b13750014f19DB0014" + ], + "arm": "0xfE4fB161D870D0F672Ed9C5A898569603f77983F", + "router": "0x19b1bac554111517831ACadc0FD119D23Bb14391", + "price_registry": "0x2F4ACd1f8986c6B1788159C4c9a5fC3fceCCE363", + "wrapped_native": "0x18c8a7ec7897177E4529065a7E7B0878358B3BfF", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x473b49fb592B54a4BfCD55d40E048431982879C9", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0x610F76A35E17DA4542518D85FfEa12645eF111Fc", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xE48E6AA1fc7D0411acEA95F8C6CaD972A37721D4", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x41b4A51cAfb699D9504E89d19D71F92E886028a8", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0xAae733212981e06D9C978Eb5148F8af03F54b6EF", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0x01800fCDd892e37f7829937271840A6F041bE62E", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x4ac7FBEc2A7298AbDf0E0F4fDC45015836C4bAFe", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0x9aA82DBB53bf02096B771D40e9432A323a78fB26", + "commit_store": "0x5CdbA91aBC0cD81FC56bc10Ad1835C9E5fB38e5F", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0x3e33290B90fD0FF30a3FA138934DF028E4eCA348", + "commit_store": "0xCFe3556Aa42d40be09BD23aa80448a19443BE5B1", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0xbc4AD54e91b213D4279af92c0C5518c0b96cf62D", + "commit_store": "0xff84e8Dd4Fd17eaBb23b6AeA6e1981830e54389C", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0x4117953A5ceeF12f5B8C1E973b470ab83a8CebA6", + "commit_store": "0x94ad41296186E81f31e1ed0B1BcF5fa9e1721C27", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0x33d2898F8fb7714FD1661791766f40754982a343", + "commit_store": "0x55d6Df194472f02CD481e506A277c4A29D0D1bCc", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x450543b1d85ca79885851D7b74dc982981b78229", + "commit_store": "0x23B79d940A769FE31b4C867A8BAE80117f24Ca81", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xbf9036529123DE264bFA0FC7362fE25B650D4B16", + "commit_store": "0x5f7F1abD5c5EdaF2636D58B980e85355AF0Ef80d", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Kroma Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000001", + "bridge_tokens": [ + "0x6AC3e353D1DDda24d5A5416024d6E436b8817A4e" + ], + "bridge_tokens_pools": [ + "0x0eE8add19554C7bb1920A183Ed47b4FAB9Eb7601" + ], + "arm": "0x08f9Af992368FAc58C936A2c5eBc9092894CEa9b", + "router": "0xA8C0c11bf64AF62CDCA6f93D3769B88BdD7cb93D", + "price_registry": "0xa1ed3A3aA29166C9c8448654A8cA6b7916BC8379", + "wrapped_native": "0x4200000000000000000000000000000000000001", + "src_contracts": { + "WeMix Testnet": { + "on_ramp": "0x6ea155Fc77566D9dcE01B8aa5D7968665dc4f0C5", + "deployed_at": 0 + } + }, + "dest_contracts": { + "WeMix Testnet": { + "off_ramp": "0xB602B6E5Caf08ac0C920EAE585aed100a8cF6f3B", + "commit_store": "0x89D5b13908b9063abCC6791dc724bF7B7c93634C", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Metis Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x5c48e07062aC4E2Cf4b9A768a711Aef18e8fbdA0", + "bridge_tokens": [ + "0x20Aa09AAb761e2E600d65c6929A9fd1E59821D3f" + ], + "bridge_tokens_pools": [ + "0xdE8451E952Eb43350614839cCAA84f7C8701a09C" + ], + "arm": "0xf0607A9BDdB5F54dB59ACaA0837aFec2D1c95df6", + "router": "0xaCdaBa07ECad81dc634458b98673931DD9d3Bc14", + "price_registry": "0x5DCE866b3ae6E0Ed153f0e149D7203A1B266cdF5", + "wrapped_native": "0x5c48e07062aC4E2Cf4b9A768a711Aef18e8fbdA0", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x2Eff2d1BF5C557d6289D208a7a43608f5E3FeCc2", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0x9Bb7e398ef9Acfe9cA584C39B1E233Cba62BB9f7", + "commit_store": "0x1F4B82cDebaC5e3a0Dd53183D47e51808B4a64cB", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Mode Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "bridge_tokens": [ + "0xB9d4e1141E67ECFedC8A8139b5229b7FF2BF16F5" + ], + "bridge_tokens_pools": [ + "0x20bBc874bE3Cd94C3E4689EDD5D89dD1cE8Cb7C4" + ], + "arm": "0x9eC8a0AbC75ce08978FAf67958482461bCd93B18", + "router": "0xc49ec0eB4beb48B8Da4cceC51AA9A5bD0D0A4c43", + "price_registry": "0xa733ce82a84335b2E9D864312225B0F3D5d80600", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Base Sepolia": { + "on_ramp": "0x73f7E074bd7291706a0C5412f51DB46441B1aDCB", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0xfFdE9E8c34A27BEBeaCcAcB7b3044A0A364455C9", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Base Sepolia": { + "off_ramp": "0x137a38c6b1Ad20101F93516aB2159Df525309168", + "commit_store": "0x8F43d867969F14619895d71E0A5b89E0bb20bF70", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xcD44cec849B6a8eBd5551D6DFeEcA452257Dfe4d", + "commit_store": "0xbA66f08733E6715D33edDfb5a5947676bb45d0e0", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Optimism Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "bridge_tokens": [ + "0x8aF4204e30565DF93352fE8E1De78925F6664dA7" + ], + "bridge_tokens_pools": [ + "0x3Cc9364260D80F09ccAC1eE6B07366dB598900E6" + ], + "arm": "0xF51366F72184E22cF4a7a8362508DB0d3370392d", + "router": "0x114A20A10b43D4115e5aeef7345a1A71d2a60C57", + "price_registry": "0x782a7Ba95215f2F7c3dD4C153cbB2Ae3Ec2d3215", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0x1a86b29364D1B3fA3386329A361aA98A104b2742", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0x6b38CC6Fa938D5AB09Bdf0CFe580E226fDD793cE", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0xe284D2315a28c4d62C419e8474dC457b219DB969", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x835a5b8e6CA17c2bB5A336c93a4E22478E6F1C8A", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0x2Cf26fb01E9ccDb831414B766287c0A9e4551089", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0xC8b93b46BF682c39B3F65Aa1c135bC8A95A5E43a", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0xc7E53f6aB982af7A7C3e470c8cCa283d3399BDAd", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xDc2c7A3d8068C6F09F0F3648d24C84e372F6014d", + "commit_store": "0xb1aFb5cbE3c29b5Db71F21442BA9EfD450BC23C3", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0x1F350718e015EB20E5065C09F4A7a3f66888aEeD", + "commit_store": "0x98650A8EB59f75D93563aB34FcF603b1A30e4CBF", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0x0a750ca77369e03613d7640548F4b2b1c695c3Bb", + "commit_store": "0x8fEBC74C26129C8d7E60288C6dCCc75eb494aA3C", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0xCE2CE7F940B7c839384e5D7e079A6aE80e8AD6dB", + "commit_store": "0x1b9D78Ec1CEEC439F0b7eA6C428A1a607D9FA7e4", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0xD667b5706592D0b040C78fEe5EE17D243b7dCB41", + "commit_store": "0x96101BA5250EE9295c193693C1e08A55bC593664", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x260AF9b83e0d2Bb6C9015fC9f0BfF8858A0CCE68", + "commit_store": "0x7a0bB92Bc8663abe6296d0162A9b41a2Cb2E0358", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0x9C08B7712af0344188aa5087D9e6aD0f47191037", + "commit_store": "0x4BE6DB0B884169a6A207fe5cad01eB4C025a13dB", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Polygon Amoy": { + "is_native_fee_token": true, + "fee_token": "0x360ad4f9a9A8EFe9A8DCB5f461c4Cc1047E1Dcf9", + "bridge_tokens": [ + "0xcab0EF91Bee323d1A617c0a027eE753aFd6997E4" + ], + "bridge_tokens_pools": [ + "0x3064fB3EA546EE09A63AB3bD93E83D8B8525C636" + ], + "arm": "0x8b88C39D2875157aB4CE4AD3814409523d539ee1", + "router": "0x9C32fCB86BF0f4a1A8921a9Fe46de3198bb884B2", + "price_registry": "0xfb2f2A207dC428da81fbAFfDDe121761f8Be1194", + "wrapped_native": "0x360ad4f9a9A8EFe9A8DCB5f461c4Cc1047E1Dcf9", + "src_contracts": { + "Avalanche Fuji": { + "on_ramp": "0x8Fb98b3837578aceEA32b454f3221FE18D7Ce903", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xC6683ac4a0F62803Bec89a5355B36495ddF2C38b", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x2331F6D614C9Fd613Ff59a1aB727f1EDf6c37A68", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0xA52cDAeb43803A80B3c0C2296f5cFe57e695BE11", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x35347A2fC1f2a4c5Eae03339040d0b83b09e6FDA", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0x26546096F64B5eF9A1DcDAe70Df6F4f8c2E10C61", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Avalanche Fuji": { + "off_ramp": "0xa733ce82a84335b2E9D864312225B0F3D5d80600", + "commit_store": "0x09B0F93fC2111aE439e853884173AC5b2F809885", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0x948dfaa4842fc23e0e362Fe8D4396AaE4E6DF7EA", + "commit_store": "0x7F4e739D40E58BBd59dAD388171d18e37B26326f", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x17c542a28e08AEF5697251601C7b2B621d153D42", + "commit_store": "0x811250c20fAB9a1b7ca245453aC214ba637fBEB5", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xfFdE9E8c34A27BEBeaCcAcB7b3044A0A364455C9", + "commit_store": "0x74ED442ad211050e9C05Dc9A267E037E3d74A03B", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0xFb04129aD1EEDB741CC705ebC1978a7aB63e51f6", + "commit_store": "0x63f875240149d29136053C954Ca164a9BfA81F77", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0xdE8451E952Eb43350614839cCAA84f7C8701a09C", + "commit_store": "0xaCdaBa07ECad81dc634458b98673931DD9d3Bc14", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "Sepolia Testnet": { + "is_native_fee_token": true, + "fee_token": "0x097D90c9d3E0B50Ca60e1ae45F6A81010f9FB534", + "bridge_tokens": [ + "0xFd57b4ddBf88a4e07fF4e34C487b99af2Fe82a05" + ], + "bridge_tokens_pools": [ + "0x38d1ef9619Cd40cf5482C045660Ae7C82Ada062c" + ], + "arm": "0x27Da8735d8d1402cEc072C234759fbbB4dABBC4A", + "router": "0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59", + "price_registry": "0x9EF7D57a4ea30b9e37794E55b0C75F2A70275dCc", + "wrapped_native": "0x097D90c9d3E0B50Ca60e1ae45F6A81010f9FB534", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0xe4Dd3B16E09c016402585a8aDFdB4A18f772a07e", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0x0477cA0a35eE05D3f9f424d88bC0977ceCf339D4", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0xD990f8aFA5BCB02f95eEd88ecB7C68f5998bD618", + "deployed_at": 0 + }, + "Base Sepolia": { + "on_ramp": "0x2B70a05320cB069e0fB55084D402343F832556E7", + "deployed_at": 0 + }, + "Blast Sepolia": { + "on_ramp": "0xDB75E9D9ca7577CcBd7232741be954cf26194a66", + "deployed_at": 0 + }, + "Celo Alfajores": { + "on_ramp": "0x3C86d16F52C10B2ff6696a0e1b8E0BcfCC085948", + "deployed_at": 0 + }, + "Gnosis Chiado": { + "on_ramp": "0x3E842E3A79A00AFdd03B52390B1caC6306Ea257E", + "deployed_at": 0 + }, + "Metis Sepolia": { + "on_ramp": "0x1C4640914cd57c5f02a68048A0fbb0E12d904223", + "deployed_at": 0 + }, + "Mode Sepolia": { + "on_ramp": "0xc630fbD4D0F6AEB00aD0793FB827b54fBB78e981", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0x69CaB5A0a08a12BaFD8f5B195989D709E396Ed4d", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0x9f656e0361Fb5Df2ac446102c8aB31855B591692", + "deployed_at": 0 + }, + "WeMix Testnet": { + "on_ramp": "0xedFc22336Eb0B9B11Ff37C07777db27BCcDe3C65", + "deployed_at": 0 + }, + "ZKSync Sepolia": { + "on_ramp": "0x1Acb3A885feA37bdA30AB99b99327b14391f500F", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xF18896AB20a09A29e64fdEbA99FDb8EC328f43b1", + "commit_store": "0x93Ff9Dd39Dc01eac1fc4d2c9211D95Ee458CAB94", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0x000b26f604eAadC3D874a4404bde6D64a97d95ca", + "commit_store": "0x2dD9273F8208B8393350508131270A6574A69784", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0xdE2d8E126e08d675fCD7fFa5a6CE49925f3Dc692", + "commit_store": "0x0050ac355a82caB31194507f94174297bf0655A7", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Base Sepolia": { + "off_ramp": "0x31c0B81832B333419f0DfD36A69F502cF9094aed", + "commit_store": "0xDFcde9d698a2B32DB2537DC9B752Cadd1D846a52", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Blast Sepolia": { + "off_ramp": "0x4e897e5cF3aC307F0541B2151A88bCD781c153a3", + "commit_store": "0xB656652841F347178e193951C4663652aCe36B74", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Celo Alfajores": { + "off_ramp": "0xB435E0f73c18C5a12C324CA1d02F81F2C3e6e761", + "commit_store": "0xbc5d74957F171e75F92c8F0E1C317A25a56a416D", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Gnosis Chiado": { + "off_ramp": "0x7db0115A0b3AAb01d30bf81123c5DD7B0C41Add5", + "commit_store": "0x6640723Ea801178c4383FA016b9781e7ef1016EF", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Metis Sepolia": { + "off_ramp": "0x4DB693A93E9d5196ECD42EC56CDEAe99dFC652ED", + "commit_store": "0xBfACd78F1412B6f93Ac23409bf456aFec1ABd845", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Mode Sepolia": { + "off_ramp": "0xbEfd8D65F6643De54F0b1268A3bf4618ff85dcB4", + "commit_store": "0x0C161D3470b45Cc677661654C30ce4AdE6aCD288", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xD50590D4438411EDe47029b0FD7901A7145E5Df6", + "commit_store": "0xe85EEE9Fd434A7b8a586Ee086E828abF41839479", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x5032cbC0C4aEeD25bb6E45D8B3fAF05DB0688C5d", + "commit_store": "0xe6201C9996Cc7B6E828E10CbE937E693d577D318", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "WeMix Testnet": { + "off_ramp": "0x46b639a3C1a4CBfD326b94a2dB7415c27157282f", + "commit_store": "0x7b74554678816b045c1e7409327E086bD436aa46", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "ZKSync Sepolia": { + "off_ramp": "0xBaABd4166C892a1081a26535875A8fA3f22937b2", + "commit_store": "0xfda2e83F4D3f42B7629134ecD6E4b29FB8A7A07B", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "WeMix Testnet": { + "is_native_fee_token": true, + "fee_token": "0xbE3686643c05f00eC46e73da594c78098F7a9Ae7", + "bridge_tokens": [ + "0xF4E4057FbBc86915F4b2d63EEFFe641C03294ffc" + ], + "bridge_tokens_pools": [ + "0x82A92B2863F93Be70D20660088Ec060720bA2fdb" + ], + "arm": "0x8f6cb63eD5e379722580DFF0A051C140C64F9619", + "router": "0xA8C0c11bf64AF62CDCA6f93D3769B88BdD7cb93D", + "price_registry": "0x89D17571DB7C9540eeB36760E3c749C8fb984569", + "wrapped_native": "0xbE3686643c05f00eC46e73da594c78098F7a9Ae7", + "src_contracts": { + "Arbitrum Sepolia": { + "on_ramp": "0xA9DE3F7A617D67bC50c56baaCb9E0373C15EbfC6", + "deployed_at": 0 + }, + "Avalanche Fuji": { + "on_ramp": "0xC4aC84da458ba8e40210D2dF94C76E9a41f70069", + "deployed_at": 0 + }, + "BSC Testnet": { + "on_ramp": "0x5AD6eed6Be0ffaDCA4105050CF0E584D87E0c2F1", + "deployed_at": 0 + }, + "Kroma Sepolia": { + "on_ramp": "0x428C4dc89b6Bf908B82d77C9CBceA786ea8cc7D0", + "deployed_at": 0 + }, + "Optimism Sepolia": { + "on_ramp": "0x1961a7De751451F410391c251D4D4F98D71B767D", + "deployed_at": 0 + }, + "Polygon Amoy": { + "on_ramp": "0xd55148e841e76265B484d399eC71b7076ecB1216", + "deployed_at": 0 + }, + "Sepolia Testnet": { + "on_ramp": "0x4d57C6d8037C65fa66D6231844785a428310a735", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Sepolia": { + "off_ramp": "0xeB1dFaB2464Bf0574D43e764E0c758f92e7ecAFb", + "commit_store": "0xcEaCa2B7890065c485f3E58657358a185Ad33791", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Avalanche Fuji": { + "off_ramp": "0x98e811Df9D2512f1aaf58D534607F583D6c54A4F", + "commit_store": "0x8e538351F6E5B2daF3c90C565C3738bca69a2716", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "BSC Testnet": { + "off_ramp": "0xB0e7f0fCcD3c961C473E7c44D939C1cDb4Cec1cB", + "commit_store": "0x4B56D8d53f1A6e0117B09700067De99581aA5542", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Kroma Sepolia": { + "off_ramp": "0xD685D2d224dd6D0Db2D56497db6270D77D9a7966", + "commit_store": "0x7e062D6880779a0347e7742058C1b1Ee4AA0B137", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Optimism Sepolia": { + "off_ramp": "0xA5f97Bc69Bf06e7C37B93265c5457420A92c5F4b", + "commit_store": "0xd48b9213583074f518D8f4336FDf35370D450132", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Polygon Amoy": { + "off_ramp": "0x6c8f5999B06FDE17B11E4e3C1062b761766F960f", + "commit_store": "0x957c3c2056192e58A8485eF31165fC490d474239", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + }, + "Sepolia Testnet": { + "off_ramp": "0x8AB103843ED9D28D2C5DAf5FdB9c3e1CE2B6c876", + "commit_store": "0x7d5297c5506ee2A7Ef121Da9bE02b6a6AD30b392", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + }, + "ZKSync Sepolia": { + "is_native_fee_token": true, + "fee_token": "0x4317b2eCD41851173175005783322D29E9bAee9E", + "arm": "0x926b4f90610Aa448f27c8e0Fd0afa4A17B7305F9", + "router": "0xA1fdA8aa9A8C4b945C45aD30647b01f07D7A0B16", + "price_registry": "0x648B6BB09bE1C5766C8AC578B9B4aC8497eA671F", + "wrapped_native": "0x4317b2eCD41851173175005783322D29E9bAee9E", + "src_contracts": { + "Sepolia Testnet": { + "on_ramp": "0x79a9a5e9e318e8e109776569574814bbf935125a", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Sepolia Testnet": { + "off_ramp": "0x18FF69051479796175852578725Fc74F58E963F8", + "commit_store": "0xF694b4FD7889480dca3CD41244e8e3395a9EFBa0", + "receiver_dapp": "0xea387241d834D04CC408f4C2FE7ef2c477E4B3E7" + } + } + } + } +} +""" + +[CCIP.Env] +TTL = '8h' + +[CCIP.Env.Network] +selected_networks = [ + 'ARBITRUM_SEPOLIA', + 'AVALANCHE_FUJI', + 'BASE_SEPOLIA', + 'BLAST_SEPOLIA', + 'BSC_TESTNET', + 'CELO_ALFAJORES', + 'GNOSIS_CHIADO', + 'KROMA_SEPOLIA', + 'MODE_SEPOLIA', + 'OPTIMISM_SEPOLIA', + 'POLYGON_AMOY', + 'SEPOLIA', + 'METIS_SEPOLIA', + 'WEMIX_TESTNET', + 'ZKSYNC_SEPOLIA' +] + +[CCIP.Groups.load] +NetworkPairs = [ + 'AVALANCHE_FUJI,ARBITRUM_SEPOLIA', + 'AVALANCHE_FUJI,BASE_SEPOLIA', + 'AVALANCHE_FUJI,OPTIMISM_SEPOLIA', + 'AVALANCHE_FUJI,POLYGON_AMOY', + 'AVALANCHE_FUJI,GNOSIS_CHIADO', + 'ARBITRUM_SEPOLIA,BASE_SEPOLIA', + 'ARBITRUM_SEPOLIA,OPTIMISM_SEPOLIA', + 'ARBITRUM_SEPOLIA,SEPOLIA', + 'ARBITRUM_SEPOLIA,GNOSIS_CHIADO', + 'BASE_SEPOLIA,MODE_SEPOLIA', + 'BASE_SEPOLIA,OPTIMISM_SEPOLIA', + 'BASE_SEPOLIA,GNOSIS_CHIADO', + 'SEPOLIA,MODE_SEPOLIA', + 'SEPOLIA,CELO_ALFAJORES', + 'SEPOLIA,METIS_SEPOLIA', + 'SEPOLIA,BLAST_SEPOLIA', + 'SEPOLIA,ZKSYNC_SEPOLIA', + 'KROMA_SEPOLIA,WEMIX_TESTNET', + 'OPTIMISM_SEPOLIA,GNOSIS_CHIADO', + 'BSC_TESTNET,GNOSIS_CHIADO', +] + +BiDirectionalLane = true +PhaseTimeout = '20m' +ExistingDeployment = true + +[CCIP.Groups.load.TokenConfig] +NoOfTokensPerChain = 1 + +[CCIP.Groups.load.LoadProfile] +RequestPerUnitTime = [1] +TimeUnit = '6m' +TestDuration = '24h' +TestRunName = 'SoakTest_prod_testnet' +FailOnFirstErrorInLoad = true + +[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] +MsgType = 'Data' +DestGasLimit = 0 +DataLength = 100 +NoOfTokens = 1 +AmountPerToken = 1 \ No newline at end of file From a7348f000c20cd6345f682922e105bed571f01c5 Mon Sep 17 00:00:00 2001 From: Ryan Tinianov Date: Tue, 17 Sep 2024 15:41:33 -0400 Subject: [PATCH 364/432] Delegate workflow spec creation (#14365) * Delegate workflow spec creation * Use checked in common * exclude sourcegrapht * fix broken tests * imports fix * Parse workflow earlier and store spec type in the DB * lint * Remove unused variable * Rename SdkWorkflowSpec to SDKSpec --------- Co-authored-by: skudasov --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/feeds/service.go | 2 +- core/services/job/job_orm_test.go | 8 +- core/services/job/models.go | 48 ++++++-- core/services/job/models_test.go | 4 +- core/services/job/orm.go | 6 +- core/services/job/workflow_spec_factory.go | 51 +++++++++ .../job/workflow_spec_factory_test.go | 106 ++++++++++++++++++ core/services/job/yaml_spec_factory.go | 20 ++++ core/services/job/yaml_spec_factory_test.go | 82 ++++++++++++++ core/services/workflows/delegate.go | 27 +++-- core/services/workflows/delegate_test.go | 3 +- core/services/workflows/engine.go | 6 +- core/services/workflows/engine_test.go | 9 +- core/services/workflows/models.go | 13 ++- core/services/workflows/models_test.go | 14 ++- .../0253_add_spec_type_to_workflow_spec.sql | 13 +++ core/testdata/testspecs/v2_specs.go | 10 +- core/web/jobs_controller.go | 2 +- core/web/resolver/mutation.go | 2 +- dashboard-lib/go.mod | 4 +- dashboard-lib/go.sum | 7 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 29 files changed, 404 insertions(+), 57 deletions(-) create mode 100644 core/services/job/workflow_spec_factory.go create mode 100644 core/services/job/workflow_spec_factory_test.go create mode 100644 core/services/job/yaml_spec_factory.go create mode 100644 core/services/job/yaml_spec_factory_test.go create mode 100644 core/store/migrate/migrations/0253_add_spec_type_to_workflow_spec.sql diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 88c58caa0b..d79e372db4 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.20.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.1 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index ed669bbbe5..9c85a9ea4d 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1083,8 +1083,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 h1:cbHlV2CSphQ+ghDye21M8ym0aAO/Y649H2Mg60M2AuE= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf h1:1AlTUkT5D8HmvU9bwDoIN54/EFyOnRBl7gnXZVrYXEA= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf/go.mod h1:l8NTByXUdGGJX+vyKYI6yX1/HIpM14F8Wm9BkU3Q4Qo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= diff --git a/core/services/feeds/service.go b/core/services/feeds/service.go index 87f0ae60f6..d5c8c1ba22 100644 --- a/core/services/feeds/service.go +++ b/core/services/feeds/service.go @@ -1210,7 +1210,7 @@ func (s *service) generateJob(ctx context.Context, spec string) (*job.Job, error case job.FluxMonitor: js, err = fluxmonitorv2.ValidatedFluxMonitorSpec(s.jobCfg, spec) case job.Workflow: - js, err = workflows.ValidatedWorkflowJobSpec(spec) + js, err = workflows.ValidatedWorkflowJobSpec(ctx, spec) case job.CCIP: js, err = ccip.ValidatedCCIPSpec(spec) default: diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go index b6af86df33..e65e7fa5e1 100644 --- a/core/services/job/job_orm_test.go +++ b/core/services/job/job_orm_test.go @@ -1861,6 +1861,7 @@ func Test_ORM_FindJobByWorkflow(t *testing.T) { spec: &job.WorkflowSpec{ ID: 1, Workflow: pkgworkflows.WFYamlSpec(t, "workflow01", addr1), + SpecType: job.YamlSpec, }, before: mustInsertWFJob, }, @@ -1881,6 +1882,7 @@ func Test_ORM_FindJobByWorkflow(t *testing.T) { var c job.WorkflowSpec c.ID = s.ID c.Workflow = pkgworkflows.WFYamlSpec(t, "workflow99", addr1) // insert with mismatched name + c.SpecType = job.YamlSpec return mustInsertWFJob(t, o, &c) }, }, @@ -1948,18 +1950,21 @@ func Test_ORM_FindJobByWorkflow_Multiple(t *testing.T) { wfYaml1 := pkgworkflows.WFYamlSpec(t, "workflow00", addr1) s1 := job.WorkflowSpec{ Workflow: wfYaml1, + SpecType: job.YamlSpec, } wantJobID1 := mustInsertWFJob(t, o, &s1) wfYaml2 := pkgworkflows.WFYamlSpec(t, "workflow01", addr1) s2 := job.WorkflowSpec{ Workflow: wfYaml2, + SpecType: job.YamlSpec, } wantJobID2 := mustInsertWFJob(t, o, &s2) wfYaml3 := pkgworkflows.WFYamlSpec(t, "workflow00", addr2) s3 := job.WorkflowSpec{ Workflow: wfYaml3, + SpecType: job.YamlSpec, } wantJobID3 := mustInsertWFJob(t, o, &s3) @@ -1976,13 +1981,14 @@ func Test_ORM_FindJobByWorkflow_Multiple(t *testing.T) { assert.EqualValues(t, j.WorkflowSpec.WorkflowID, s.WorkflowID) assert.EqualValues(t, j.WorkflowSpec.WorkflowOwner, s.WorkflowOwner) assert.EqualValues(t, j.WorkflowSpec.WorkflowName, s.WorkflowName) + assert.Equal(t, j.WorkflowSpec.SpecType, job.YamlSpec) } }) } func mustInsertWFJob(t *testing.T, orm job.ORM, s *job.WorkflowSpec) int32 { t.Helper() - err := s.Validate() + err := s.Validate(testutils.Context(t)) require.NoError(t, err, "failed to validate spec %v", s) ctx := testutils.Context(t) _, err = toml.Marshal(s.Workflow) diff --git a/core/services/job/models.go b/core/services/job/models.go index 1c46d08c59..b9ec8e726f 100644 --- a/core/services/job/models.go +++ b/core/services/job/models.go @@ -1,6 +1,7 @@ package job import ( + "context" "database/sql/driver" "encoding/json" "fmt" @@ -14,9 +15,12 @@ import ( "github.com/pkg/errors" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" + commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets" "github.com/smartcontractkit/chainlink-common/pkg/types" pkgworkflows "github.com/smartcontractkit/chainlink-common/pkg/workflows" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/bridges" @@ -857,16 +861,26 @@ type LiquidityBalancerSpec struct { LiquidityBalancerConfig string `toml:"liquidityBalancerConfig" db:"liquidity_balancer_config"` } +type WorkflowSpecType string + +const ( + YamlSpec WorkflowSpecType = "yaml" + DefaultSpecType = YamlSpec +) + type WorkflowSpec struct { ID int32 `toml:"-"` - Workflow string `toml:"workflow"` // the yaml representation of the workflow + Workflow string `toml:"workflow"` // the raw representation of the workflow + Config string `toml:"config"` // the raw representation of the config // fields derived from the yaml spec, used for indexing the database // note: i tried to make these private, but translating them to the database seems to require them to be public - WorkflowID string `toml:"-" db:"workflow_id"` // Derived. Do not modify. the CID of the workflow. - WorkflowOwner string `toml:"-" db:"workflow_owner"` // Derived. Do not modify. the owner of the workflow. - WorkflowName string `toml:"-" db:"workflow_name"` // Derived. Do not modify. the name of the workflow. - CreatedAt time.Time `toml:"-"` - UpdatedAt time.Time `toml:"-"` + WorkflowID string `toml:"-" db:"workflow_id"` // Derived. Do not modify. the CID of the workflow. + WorkflowOwner string `toml:"-" db:"workflow_owner"` // Derived. Do not modify. the owner of the workflow. + WorkflowName string `toml:"-" db:"workflow_name"` // Derived. Do not modify. the name of the workflow. + CreatedAt time.Time `toml:"-"` + UpdatedAt time.Time `toml:"-"` + SpecType WorkflowSpecType `db:"spec_type"` + sdkWorkflow *sdk.WorkflowSpec } var ( @@ -879,14 +893,18 @@ const ( ) // Validate checks the workflow spec for correctness -func (w *WorkflowSpec) Validate() error { +func (w *WorkflowSpec) Validate(ctx context.Context) error { s, err := pkgworkflows.ParseWorkflowSpecYaml(w.Workflow) if err != nil { return fmt.Errorf("%w: failed to parse workflow spec %s: %w", ErrInvalidWorkflowYAMLSpec, w.Workflow, err) } + + if _, err = w.SDKSpec(ctx); err != nil { + return err + } + w.WorkflowOwner = strings.TrimPrefix(s.Owner, "0x") // the json schema validation ensures it is a hex string with 0x prefix, but the database does not store the prefix w.WorkflowName = s.Name - w.WorkflowID = s.CID() if len(w.WorkflowID) != workflowIDLen { return fmt.Errorf("%w: incorrect length for id %s: expected %d, got %d", ErrInvalidWorkflowID, w.WorkflowID, workflowIDLen, len(w.WorkflowID)) @@ -895,6 +913,20 @@ func (w *WorkflowSpec) Validate() error { return nil } +func (w *WorkflowSpec) SDKSpec(ctx context.Context) (sdk.WorkflowSpec, error) { + if w.sdkWorkflow != nil { + return *w.sdkWorkflow, nil + } + + spec, cid, err := workflowSpecFactory.Spec(ctx, w.Workflow, []byte(w.Config), w.SpecType) + if err != nil { + return sdk.WorkflowSpec{}, err + } + w.sdkWorkflow = &spec + w.WorkflowID = cid + return spec, nil +} + type StandardCapabilitiesSpec struct { ID int32 CreatedAt time.Time `toml:"-"` diff --git a/core/services/job/models_test.go b/core/services/job/models_test.go index 1f88bb6d38..49bd29c995 100644 --- a/core/services/job/models_test.go +++ b/core/services/job/models_test.go @@ -11,6 +11,8 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/codec" "github.com/smartcontractkit/chainlink-common/pkg/types" pkgworkflows "github.com/smartcontractkit/chainlink-common/pkg/workflows" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/stretchr/testify/assert" @@ -322,7 +324,7 @@ func TestWorkflowSpec_Validate(t *testing.T) { w := &WorkflowSpec{ Workflow: tt.fields.Workflow, } - err := w.Validate() + err := w.Validate(testutils.Context(t)) require.Equal(t, tt.wantError, err != nil) if !tt.wantError { assert.NotEmpty(t, w.WorkflowID) diff --git a/core/services/job/orm.go b/core/services/job/orm.go index 5e7328b87d..d02e0b2920 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -409,8 +409,8 @@ func (o *orm) CreateJob(ctx context.Context, jb *Job) error { case Stream: // 'stream' type has no associated spec, nothing to do here case Workflow: - sql := `INSERT INTO workflow_specs (workflow, workflow_id, workflow_owner, workflow_name, created_at, updated_at) - VALUES (:workflow, :workflow_id, :workflow_owner, :workflow_name, NOW(), NOW()) + sql := `INSERT INTO workflow_specs (workflow, workflow_id, workflow_owner, workflow_name, created_at, updated_at, spec_type) + VALUES (:workflow, :workflow_id, :workflow_owner, :workflow_name, NOW(), NOW(), :spec_type) RETURNING id;` specID, err := tx.prepareQuerySpecID(ctx, sql, jb.WorkflowSpec) if err != nil { @@ -961,7 +961,7 @@ func (o *orm) FindJob(ctx context.Context, id int32) (jb Job, err error) { return } -// FindJobWithoutSpecErrors returns a job by ID, without loading Spec Errors preloaded +// FindJobWithoutSpecErrors returns a job by ID, without loading SpecVal Errors preloaded func (o *orm) FindJobWithoutSpecErrors(ctx context.Context, id int32) (jb Job, err error) { err = o.transact(ctx, true, func(tx *orm) error { stmt := "SELECT jobs.*, job_pipeline_specs.pipeline_spec_id as pipeline_spec_id FROM jobs JOIN job_pipeline_specs ON (jobs.id = job_pipeline_specs.job_id) WHERE jobs.id = $1 LIMIT 1" diff --git a/core/services/job/workflow_spec_factory.go b/core/services/job/workflow_spec_factory.go new file mode 100644 index 0000000000..565e6a9fce --- /dev/null +++ b/core/services/job/workflow_spec_factory.go @@ -0,0 +1,51 @@ +package job + +import ( + "context" + "crypto/sha256" + "errors" + "fmt" + + "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" +) + +var ErrInvalidWorkflowType = errors.New("invalid workflow type") + +type SDKWorkflowSpecFactory interface { + Spec(ctx context.Context, rawSpec, config []byte) (sdk.WorkflowSpec, error) + RawSpec(ctx context.Context, wf string) ([]byte, error) +} + +type WorkflowSpecFactory map[WorkflowSpecType]SDKWorkflowSpecFactory + +func (wsf WorkflowSpecFactory) Spec( + ctx context.Context, workflow string, config []byte, tpe WorkflowSpecType) (sdk.WorkflowSpec, string, error) { + if tpe == "" { + tpe = DefaultSpecType + } + + factory, ok := wsf[tpe] + if !ok { + return sdk.WorkflowSpec{}, "", ErrInvalidWorkflowType + } + + rawSpec, err := factory.RawSpec(ctx, workflow) + if err != nil { + return sdk.WorkflowSpec{}, "", err + } + + spec, err := factory.Spec(ctx, rawSpec, config) + if err != nil { + return sdk.WorkflowSpec{}, "", err + } + + sum := sha256.New() + sum.Write(rawSpec) + sum.Write(config) + + return spec, fmt.Sprintf("%x", sum.Sum(nil)), nil +} + +var workflowSpecFactory = WorkflowSpecFactory{ + YamlSpec: YAMLSpecFactory{}, +} diff --git a/core/services/job/workflow_spec_factory_test.go b/core/services/job/workflow_spec_factory_test.go new file mode 100644 index 0000000000..dc2ff3bac9 --- /dev/null +++ b/core/services/job/workflow_spec_factory_test.go @@ -0,0 +1,106 @@ +package job_test + +import ( + "context" + "crypto/sha256" + "errors" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/job" +) + +func TestWorkflowSpecFactory_ToSpec(t *testing.T) { + t.Parallel() + + anyData := "any data" + anyConfig := []byte("any config") + anySpec := sdk.WorkflowSpec{Name: "name", Owner: "owner"} + + t.Run("delegates to factory and calculates CID", func(t *testing.T) { + runYamlSpecTest(t, anySpec, anyData, anyConfig, job.YamlSpec) + }) + + t.Run("delegates default", func(t *testing.T) { + runYamlSpecTest(t, anySpec, anyData, anyConfig, "") + }) + + t.Run("CID without config matches", func(t *testing.T) { + factory := job.WorkflowSpecFactory{ + job.YamlSpec: mockSdkSpecFactory{t: t, noConfig: true, SpecVal: anySpec}, + } + results, cid, err := factory.Spec(testutils.Context(t), anyData, nil, job.YamlSpec) + require.NoError(t, err) + + assert.Equal(t, anySpec, results) + + sha256Hash := sha256.New() + sha256Hash.Write([]byte(anyData)) + expectedCid := fmt.Sprintf("%x", sha256Hash.Sum(nil)) + assert.Equal(t, expectedCid, cid) + }) + + t.Run("returns errors from sdk factory", func(t *testing.T) { + anyErr := errors.New("nope") + factory := job.WorkflowSpecFactory{ + job.YamlSpec: mockSdkSpecFactory{t: t, Err: anyErr}, + } + + _, _, err := factory.Spec(testutils.Context(t), anyData, anyConfig, job.YamlSpec) + assert.Equal(t, anyErr, err) + }) + + t.Run("returns an error if the type is not supported", func(t *testing.T) { + factory := job.WorkflowSpecFactory{ + job.YamlSpec: mockSdkSpecFactory{t: t, SpecVal: anySpec}, + } + + _, _, err := factory.Spec(testutils.Context(t), anyData, anyConfig, "unsupported") + assert.Error(t, err) + }) +} + +func runYamlSpecTest(t *testing.T, anySpec sdk.WorkflowSpec, anyData string, anyConfig []byte, specType job.WorkflowSpecType) { + factory := job.WorkflowSpecFactory{ + job.YamlSpec: mockSdkSpecFactory{t: t, SpecVal: anySpec}, + } + + results, cid, err := factory.Spec(testutils.Context(t), anyData, anyConfig, specType) + + require.NoError(t, err) + assert.Equal(t, anySpec, results) + + sha256Hash := sha256.New() + sha256Hash.Write([]byte(anyData)) + sha256Hash.Write(anyConfig) + expectedCid := fmt.Sprintf("%x", sha256Hash.Sum(nil)) + assert.Equal(t, expectedCid, cid) +} + +type mockSdkSpecFactory struct { + t *testing.T + noConfig bool + SpecVal sdk.WorkflowSpec + Err error +} + +func (f mockSdkSpecFactory) RawSpec(_ context.Context, wf string) ([]byte, error) { + return []byte(wf), nil +} + +func (f mockSdkSpecFactory) Spec(_ context.Context, rawSpec, config []byte) (sdk.WorkflowSpec, error) { + assert.ElementsMatch(f.t, rawSpec, []byte("any data")) + if f.noConfig { + assert.Nil(f.t, config) + } else { + assert.ElementsMatch(f.t, config, []byte("any config")) + } + + return f.SpecVal, f.Err +} diff --git a/core/services/job/yaml_spec_factory.go b/core/services/job/yaml_spec_factory.go new file mode 100644 index 0000000000..ea344a3ffc --- /dev/null +++ b/core/services/job/yaml_spec_factory.go @@ -0,0 +1,20 @@ +package job + +import ( + "context" + + "github.com/smartcontractkit/chainlink-common/pkg/workflows" + "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" +) + +type YAMLSpecFactory struct{} + +var _ SDKWorkflowSpecFactory = (*YAMLSpecFactory)(nil) + +func (y YAMLSpecFactory) Spec(_ context.Context, rawSpec, _ []byte) (sdk.WorkflowSpec, error) { + return workflows.ParseWorkflowSpecYaml(string(rawSpec)) +} + +func (y YAMLSpecFactory) RawSpec(_ context.Context, wf string) ([]byte, error) { + return []byte(wf), nil +} diff --git a/core/services/job/yaml_spec_factory_test.go b/core/services/job/yaml_spec_factory_test.go new file mode 100644 index 0000000000..4d075fe6e2 --- /dev/null +++ b/core/services/job/yaml_spec_factory_test.go @@ -0,0 +1,82 @@ +package job_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + commonworkflows "github.com/smartcontractkit/chainlink-common/pkg/workflows" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/job" +) + +const anyYamlSpec = ` +name: "wf-name" +owner: "0x00000000000000000000000000000000000000aa" +triggers: + - id: "mercury-trigger@1.0.0" + config: + feedIds: + - "0x1111111111111111111100000000000000000000000000000000000000000000" + - "0x2222222222222222222200000000000000000000000000000000000000000000" + - "0x3333333333333333333300000000000000000000000000000000000000000000" + +consensus: + - id: "offchain_reporting@2.0.0" + ref: "evm_median" + inputs: + observations: + - "$(trigger.outputs)" + config: + aggregation_method: "data_feeds_2_0" + aggregation_config: + "0x1111111111111111111100000000000000000000000000000000000000000000": + deviation: "0.001" + heartbeat: 3600 + "0x2222222222222222222200000000000000000000000000000000000000000000": + deviation: "0.001" + heartbeat: 3600 + "0x3333333333333333333300000000000000000000000000000000000000000000": + deviation: "0.001" + heartbeat: 3600 + encoder: "EVM" + encoder_config: + abi: "mercury_reports bytes[]" + +targets: + - id: "write_polygon-testnet-mumbai@3.0.0" + inputs: + report: "$(evm_median.outputs.report)" + config: + address: "0x3F3554832c636721F1fD1822Ccca0354576741Ef" + params: ["$(report)"] + abi: "receive(report bytes)" + - id: "write_ethereum-testnet-sepolia@4.0.0" + inputs: + report: "$(evm_median.outputs.report)" + config: + address: "0x54e220867af6683aE6DcBF535B4f952cB5116510" + params: ["$(report)"] + abi: "receive(report bytes)" +` + +func TestYamlSpecFactory_GetSpec(t *testing.T) { + t.Parallel() + + actual, err := job.YAMLSpecFactory{}.Spec(testutils.Context(t), []byte(anyYamlSpec), []byte{}) + require.NoError(t, err) + + expected, err := commonworkflows.ParseWorkflowSpecYaml(anyYamlSpec) + require.NoError(t, err) + + require.Equal(t, expected, actual) +} + +func TestYamlSpecFactory_GetRawSpec(t *testing.T) { + t.Parallel() + + actual, err := job.YAMLSpecFactory{}.RawSpec(testutils.Context(t), anyYamlSpec) + require.NoError(t, err) + require.Equal(t, []byte(anyYamlSpec), actual) +} diff --git a/core/services/workflows/delegate.go b/core/services/workflows/delegate.go index acd006940f..2aac9ba97b 100644 --- a/core/services/workflows/delegate.go +++ b/core/services/workflows/delegate.go @@ -6,8 +6,8 @@ import ( "github.com/google/uuid" "github.com/pelletier/go-toml" - "github.com/smartcontractkit/chainlink-common/pkg/types/core" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/workflows/store" @@ -34,15 +34,21 @@ func (d *Delegate) BeforeJobDeleted(spec job.Job) {} func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil } // ServicesForSpec satisfies the job.Delegate interface. -func (d *Delegate) ServicesForSpec(_ context.Context, spec job.Job) ([]job.ServiceCtx, error) { +func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) ([]job.ServiceCtx, error) { + sdkSpec, err := spec.WorkflowSpec.SDKSpec(ctx) + if err != nil { + return nil, err + } + cfg := Config{ Lggr: d.logger, - Spec: spec.WorkflowSpec.Workflow, + Workflow: sdkSpec, WorkflowID: spec.WorkflowSpec.WorkflowID, WorkflowOwner: spec.WorkflowSpec.WorkflowOwner, WorkflowName: spec.WorkflowSpec.WorkflowName, Registry: d.registry, Store: d.store, + Config: []byte(spec.WorkflowSpec.Config), } engine, err := NewEngine(cfg) if err != nil { @@ -59,7 +65,7 @@ func NewDelegate( return &Delegate{logger: logger, registry: registry, store: store} } -func ValidatedWorkflowJobSpec(tomlString string) (job.Job, error) { +func ValidatedWorkflowJobSpec(ctx context.Context, tomlString string) (job.Job, error) { var jb = job.Job{ExternalJobID: uuid.New()} tree, err := toml.Load(tomlString) @@ -81,16 +87,21 @@ func ValidatedWorkflowJobSpec(tomlString string) (job.Job, error) { return jb, fmt.Errorf("toml unmarshal error on workflow spec: %w", err) } - err = spec.Validate() + sdkSpec, err := spec.SDKSpec(ctx) if err != nil { - return jb, fmt.Errorf("invalid WorkflowSpec: %w", err) + return jb, fmt.Errorf("failed to convert to sdk workflow spec: %w", err) } // ensure the embedded workflow graph is valid - _, err = Parse(spec.Workflow) - if err != nil { + if _, err = Parse(sdkSpec); err != nil { return jb, fmt.Errorf("failed to parse workflow graph: %w", err) } + + err = spec.Validate(ctx) + if err != nil { + return jb, fmt.Errorf("invalid WorkflowSpec: %w", err) + } + jb.WorkflowSpec = &spec jb.WorkflowSpecID = &spec.ID diff --git a/core/services/workflows/delegate_test.go b/core/services/workflows/delegate_test.go index a12eac80bb..d27a1012e6 100644 --- a/core/services/workflows/delegate_test.go +++ b/core/services/workflows/delegate_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/workflows" "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" ) @@ -99,7 +100,7 @@ schemaVersion = 1 for _, tc := range tt { tc := tc t.Run(tc.name, func(t *testing.T) { - _, err := workflows.ValidatedWorkflowJobSpec(tc.workflowTomlFn()) + _, err := workflows.ValidatedWorkflowJobSpec(testutils.Context(t), tc.workflowTomlFn()) if tc.valid { require.NoError(t, err) } else { diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index 88fb198d15..26bc2d4cd6 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -10,6 +10,7 @@ import ( "time" "github.com/jonboulle/clockwork" + "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" "github.com/smartcontractkit/chainlink-common/pkg/workflows/exec" @@ -853,7 +854,7 @@ func (e *Engine) Close() error { } type Config struct { - Spec string + Workflow sdk.WorkflowSpec WorkflowID string WorkflowOwner string WorkflowName string @@ -864,6 +865,7 @@ type Config struct { NewWorkerTimeout time.Duration MaxExecutionDuration time.Duration Store store.Store + Config []byte // For testing purposes only maxRetries int @@ -929,7 +931,7 @@ func NewEngine(cfg Config) (engine *Engine, err error) { // - that the resulting graph is strongly connected (i.e. no disjointed subgraphs exist) // - etc. - workflow, err := Parse(cfg.Spec) + workflow, err := Parse(cfg.Workflow) if err != nil { return nil, err } diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index e7f83504e9..9bd1b28537 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -18,6 +18,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/values" "github.com/smartcontractkit/chainlink-common/pkg/workflows" + coreCap "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" @@ -136,12 +137,18 @@ func newTestEngine(t *testing.T, reg *coreCap.Registry, spec string, opts ...fun executionFinished := make(chan string, 100) clock := clockwork.NewFakeClock() + sdkSpec, err := (&job.WorkflowSpec{ + Workflow: spec, + SpecType: job.YamlSpec, + }).SDKSpec(testutils.Context(t)) + require.NoError(t, err) + reg.SetLocalRegistry(&testConfigProvider{}) cfg := Config{ WorkflowID: testWorkflowId, Lggr: logger.TestLogger(t), Registry: reg, - Spec: spec, + Workflow: sdkSpec, maxRetries: 1, retryMs: 100, afterInit: func(success bool) { diff --git a/core/services/workflows/models.go b/core/services/workflows/models.go index 461569e8c6..cf1fffa9a4 100644 --- a/core/services/workflows/models.go +++ b/core/services/workflows/models.go @@ -6,6 +6,7 @@ import ( "sync/atomic" "github.com/dominikbraun/graph" + "github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk" "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/values" @@ -25,7 +26,7 @@ type workflow struct { triggers []*triggerCapability - spec *workflows.WorkflowSpec + spec *sdk.WorkflowSpec } func (w *workflow) walkDo(start string, do func(s *step) error) error { @@ -85,18 +86,20 @@ type step struct { } type triggerCapability struct { - workflows.StepDefinition + sdk.StepDefinition trigger capabilities.TriggerCapability config atomic.Pointer[values.Map] } -func Parse(yamlWorkflow string) (*workflow, error) { - wf2, err := workflows.ParseDependencyGraph(yamlWorkflow) +func Parse(sdkSpec sdk.WorkflowSpec) (*workflow, error) { + wf2, err := workflows.BuildDependencyGraph(sdkSpec) if err != nil { return nil, err } - return createWorkflow(wf2) + + wfs, err := createWorkflow(wf2) + return wfs, err } // createWorkflow converts a StaticWorkflow to an executable workflow diff --git a/core/services/workflows/models_test.go b/core/services/workflows/models_test.go index a28aeb9df0..68944e64ba 100644 --- a/core/services/workflows/models_test.go +++ b/core/services/workflows/models_test.go @@ -7,6 +7,9 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/workflows" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/job" ) func TestParse_Graph(t *testing.T) { @@ -290,7 +293,11 @@ targets: for _, tc := range testCases { t.Run(tc.name, func(st *testing.T) { - wf, err := Parse(tc.yaml) + + spec, err := job.YAMLSpecFactory{}.Spec(testutils.Context(t), []byte(tc.yaml), nil) + require.NoError(t, err) + + wf, err := Parse(spec) if tc.errMsg != "" { assert.ErrorContains(st, err, tc.errMsg) } else { @@ -316,7 +323,10 @@ targets: } func TestParsesIntsCorrectly(t *testing.T) { - wf, err := Parse(hardcodedWorkflow) + spec, err := job.YAMLSpecFactory{}.Spec(testutils.Context(t), []byte(hardcodedWorkflow), nil) + require.NoError(t, err) + + wf, err := Parse(spec) require.NoError(t, err) n, err := wf.Vertex("evm_median") diff --git a/core/store/migrate/migrations/0253_add_spec_type_to_workflow_spec.sql b/core/store/migrate/migrations/0253_add_spec_type_to_workflow_spec.sql new file mode 100644 index 0000000000..3c62c46097 --- /dev/null +++ b/core/store/migrate/migrations/0253_add_spec_type_to_workflow_spec.sql @@ -0,0 +1,13 @@ +-- +goose Up +-- +goose StatementBegin + +ALTER TABLE workflow_specs ADD COLUMN spec_type varchar(255) DEFAULT 'yaml'; + +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin + +ALTER TABLE workflow_specs DROP COLUMN spec_type; + +-- +goose StatementEnd \ No newline at end of file diff --git a/core/testdata/testspecs/v2_specs.go b/core/testdata/testspecs/v2_specs.go index 3a1798ab5a..554b18ae81 100644 --- a/core/testdata/testspecs/v2_specs.go +++ b/core/testdata/testspecs/v2_specs.go @@ -1,6 +1,7 @@ package testspecs import ( + "crypto/sha256" "fmt" "strconv" "strings" @@ -10,9 +11,9 @@ import ( "github.com/google/uuid" "github.com/test-go/testify/require" - pkgworkflows "github.com/smartcontractkit/chainlink-common/pkg/workflows" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" @@ -899,9 +900,8 @@ func (w WorkflowJobSpec) Job() job.Job { // GenerateWorkflowJobSpec creates a WorkflowJobSpec from the given workflow yaml spec string func GenerateWorkflowJobSpec(t *testing.T, spec string) WorkflowJobSpec { t.Helper() - s, err := pkgworkflows.ParseWorkflowSpecYaml(spec) - require.NoError(t, err, "failed to parse YAML workflow spec %s", spec) - id := s.CID + sum := sha256.Sum256([]byte(spec)) + id := fmt.Sprintf("%x", sum) template := ` type = "workflow" schemaVersion = 1 @@ -913,7 +913,7 @@ workflow = """ ` toml := fmt.Sprintf(template, id, spec) - j, err := workflows.ValidatedWorkflowJobSpec(toml) + j, err := workflows.ValidatedWorkflowJobSpec(testutils.Context(t), toml) require.NoError(t, err, "failed to validate TOML job spec for workflow %s", toml) return WorkflowJobSpec{toml: toml, j: j} } diff --git a/core/web/jobs_controller.go b/core/web/jobs_controller.go index 1a80ca9693..b11f6e6109 100644 --- a/core/web/jobs_controller.go +++ b/core/web/jobs_controller.go @@ -256,7 +256,7 @@ func (jc *JobsController) validateJobSpec(ctx context.Context, tomlString string case job.Stream: jb, err = streams.ValidatedStreamSpec(tomlString) case job.Workflow: - jb, err = workflows.ValidatedWorkflowJobSpec(tomlString) + jb, err = workflows.ValidatedWorkflowJobSpec(ctx, tomlString) case job.StandardCapabilities: jb, err = standardcapabilities.ValidatedStandardCapabilitiesSpec(tomlString) case job.CCIP: diff --git a/core/web/resolver/mutation.go b/core/web/resolver/mutation.go index 4c9e409cbb..4388bd5a70 100644 --- a/core/web/resolver/mutation.go +++ b/core/web/resolver/mutation.go @@ -1063,7 +1063,7 @@ func (r *Resolver) CreateJob(ctx context.Context, args struct { case job.Gateway: jb, err = gateway.ValidatedGatewaySpec(args.Input.TOML) case job.Workflow: - jb, err = workflows.ValidatedWorkflowJobSpec(args.Input.TOML) + jb, err = workflows.ValidatedWorkflowJobSpec(ctx, args.Input.TOML) case job.StandardCapabilities: jb, err = standardcapabilities.ValidatedStandardCapabilitiesSpec(args.Input.TOML) case job.Stream: diff --git a/dashboard-lib/go.mod b/dashboard-lib/go.mod index 8e68d3c620..0ab2b696db 100644 --- a/dashboard-lib/go.mod +++ b/dashboard-lib/go.mod @@ -17,11 +17,11 @@ require ( github.com/gosimple/slug v1.13.1 // indirect github.com/gosimple/unidecode v1.0.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/common v0.45.0 // indirect github.com/stretchr/testify v1.9.0 // indirect - golang.org/x/sys v0.16.0 // indirect + golang.org/x/sys v0.24.0 // indirect ) replace github.com/sourcegraph/sourcegraph/lib => github.com/sourcegraph/sourcegraph-public-snapshot/lib v0.0.0-20240822153003-c864f15af264 diff --git a/dashboard-lib/go.sum b/dashboard-lib/go.sum index 7eb74088f1..fd6985df0c 100644 --- a/dashboard-lib/go.sum +++ b/dashboard-lib/go.sum @@ -15,8 +15,9 @@ github.com/grafana/grafana-foundation-sdk/go v0.0.0-20240314112857-a7c9c6d0044c/ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= @@ -31,7 +32,7 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go.mod b/go.mod index 6f9d925858..405a6b4668 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f diff --git a/go.sum b/go.sum index 6edbb94eb9..9854253863 100644 --- a/go.sum +++ b/go.sum @@ -1044,8 +1044,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 h1:cbHlV2CSphQ+ghDye21M8ym0aAO/Y649H2Mg60M2AuE= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf h1:1AlTUkT5D8HmvU9bwDoIN54/EFyOnRBl7gnXZVrYXEA= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf/go.mod h1:l8NTByXUdGGJX+vyKYI6yX1/HIpM14F8Wm9BkU3Q4Qo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index a12e8c18dc..f7922b245d 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -39,7 +39,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index a559c09901..673a1e94e1 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1425,8 +1425,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 h1:cbHlV2CSphQ+ghDye21M8ym0aAO/Y649H2Mg60M2AuE= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf h1:1AlTUkT5D8HmvU9bwDoIN54/EFyOnRBl7gnXZVrYXEA= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf/go.mod h1:l8NTByXUdGGJX+vyKYI6yX1/HIpM14F8Wm9BkU3Q4Qo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index f2aff6511e..3f99fa1e4a 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce + github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 3efe39cca8..5a51e7c497 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1399,8 +1399,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 h1:cbHlV2CSphQ+ghDye21M8ym0aAO/Y649H2Mg60M2AuE= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce h1:qXS0aWiDFDoLRCB+kSGnzp77iYT2luflUyzE5BnNmpY= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240913161926-ce5d667907ce/go.mod h1:sjiiPwd4KsYOCf68MwL86EKphdXeT66EY7j53WH5DCc= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf h1:1AlTUkT5D8HmvU9bwDoIN54/EFyOnRBl7gnXZVrYXEA= +github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf/go.mod h1:l8NTByXUdGGJX+vyKYI6yX1/HIpM14F8Wm9BkU3Q4Qo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= From 3f83f9e8e66029c78a52e2c1eeb5dfb95a615f55 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Wed, 18 Sep 2024 03:40:08 -0400 Subject: [PATCH 365/432] Enables OOO Execution for E2E Tests (#14392) * Enables OOO Execution for E2E Tests * Out of order false by default * Port over CCIP fix * Changeset * Fix changeset * Fix lint --- .changeset/rare-crabs-tell.md | 5 ++ .../ccip/testhelpers/ccip_contracts.go | 2 + .../ocr2/plugins/ccip/testhelpers/config.go | 1 + .../testhelpers_1_4_0/ccip_contracts_1_4_0.go | 2 + .../testhelpers_1_4_0/config_1_4_0.go | 1 + .../ccip-tests/actions/ccip_helpers.go | 66 +++++++++++++------ .../ccip-tests/contracts/contract_deployer.go | 7 +- .../ccip-tests/contracts/contract_models.go | 54 ++++++++++++--- .../contracts/laneconfig/parse_contracts.go | 1 + .../ccip-tests/load/ccip_loadgen.go | 24 ++++++- integration-tests/ccip-tests/load/helper.go | 5 +- .../ccip-tests/smoke/ccip_test.go | 30 +++------ .../ccip-tests/testconfig/README.md | 4 ++ .../ccip-tests/testconfig/ccip.go | 1 + .../testconfig/tomls/ccip-default.toml | 10 ++- 15 files changed, 153 insertions(+), 60 deletions(-) create mode 100644 .changeset/rare-crabs-tell.md diff --git a/.changeset/rare-crabs-tell.md b/.changeset/rare-crabs-tell.md new file mode 100644 index 0000000000..9bd98213ae --- /dev/null +++ b/.changeset/rare-crabs-tell.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added Adds the ability to use out of order execution transactions in CCIP E2E tests diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go index 7b3351ce06..08020282c3 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -150,6 +150,7 @@ func NewExecOffchainConfig( RelativeBoostPerWaitHour float64, InflightCacheExpiry config.Duration, RootSnoozeTime config.Duration, + BatchingStrategyID uint32, ) ExecOffchainConfig { return ExecOffchainConfig{v1_2_0.JSONExecOffchainConfig{ DestOptimisticConfirmations: DestOptimisticConfirmations, @@ -157,6 +158,7 @@ func NewExecOffchainConfig( RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, InflightCacheExpiry: InflightCacheExpiry, RootSnoozeTime: RootSnoozeTime, + BatchingStrategyID: BatchingStrategyID, }} } diff --git a/core/services/ocr2/plugins/ccip/testhelpers/config.go b/core/services/ocr2/plugins/ccip/testhelpers/config.go index c9d1ca5a12..4dcb627347 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/config.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/config.go @@ -70,6 +70,7 @@ func (c *CCIPContracts) createExecOffchainConfig(t *testing.T, inflightCacheExpi 0.07, *config.MustNewDuration(inflightCacheExpiry), *config.MustNewDuration(rootSnoozeTime), + uint32(0), ).Encode() require.NoError(t, err) return config diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go index b8db2dfff7..9906a7b365 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go @@ -157,6 +157,7 @@ func NewExecOffchainConfig( RelativeBoostPerWaitHour float64, InflightCacheExpiry config.Duration, RootSnoozeTime config.Duration, + BatchingStrategyID uint32, ) ExecOffchainConfig { return ExecOffchainConfig{v1_2_0.JSONExecOffchainConfig{ DestOptimisticConfirmations: DestOptimisticConfirmations, @@ -164,6 +165,7 @@ func NewExecOffchainConfig( RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, InflightCacheExpiry: InflightCacheExpiry, RootSnoozeTime: RootSnoozeTime, + BatchingStrategyID: BatchingStrategyID, }} } diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go index 666ad79e59..087c21e933 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go @@ -68,6 +68,7 @@ func (c *CCIPContracts) createExecOffchainConfig(t *testing.T, inflightCacheExpi 0.07, *config.MustNewDuration(inflightCacheExpiry), *config.MustNewDuration(rootSnoozeTime), + uint32(0), ).Encode() require.NoError(t, err) return config diff --git a/integration-tests/ccip-tests/actions/ccip_helpers.go b/integration-tests/ccip-tests/actions/ccip_helpers.go index 429751e169..06334560e0 100644 --- a/integration-tests/ccip-tests/actions/ccip_helpers.go +++ b/integration-tests/ccip-tests/actions/ccip_helpers.go @@ -185,6 +185,7 @@ type CCIPCommon struct { gasUpdateWatcherMu *sync.Mutex gasUpdateWatcher map[uint64]*big.Int // key - destchain id; value - timestamp of update GasUpdateEvents []contracts.GasUpdateEvent + AllowOutOfOrder bool } // FreeUpUnusedSpace sets nil to various elements of ccipModule which are only used @@ -273,6 +274,9 @@ func (ccipModule *CCIPCommon) CurseARM() (*types.Transaction, error) { func (ccipModule *CCIPCommon) LoadContractAddresses(conf *laneconfig.LaneConfig, noOfTokens *int) { if conf != nil { + if conf.AllowOutOfOrder { + ccipModule.AllowOutOfOrder = true + } if common.IsHexAddress(conf.FeeToken) { ccipModule.FeeToken = &contracts.LinkToken{ EthAddress: common.HexToAddress(conf.FeeToken), @@ -1626,7 +1630,7 @@ func (sourceCCIP *SourceCCIPModule) IsRequestTriggeredWithinTimeframe(timeframe if sendRequestedEvents, exists := value.([]*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested); exists { for _, sendRequestedEvent := range sendRequestedEvents { raw := sendRequestedEvent.Raw - hdr, err := sourceCCIP.Common.ChainClient.HeaderByNumber(context.Background(), big.NewInt(int64(raw.BlockNumber))) + hdr, err := sourceCCIP.Common.ChainClient.HeaderByNumber(context.Background(), new(big.Int).SetUint64(raw.BlockNumber)) if err == nil { if hdr.Timestamp.After(lastSeenTimestamp) { foundAt = pointer.ToTime(hdr.Timestamp) @@ -1709,6 +1713,7 @@ func (sourceCCIP *SourceCCIPModule) AssertEventCCIPSendRequested( // CCIPMsg constructs the message for a CCIP request func (sourceCCIP *SourceCCIPModule) CCIPMsg( receiver common.Address, + allowOutOfOrder bool, gasLimit *big.Int, ) (router.ClientEVM2AnyMessage, error) { length := sourceCCIP.MsgDataLength @@ -1750,9 +1755,17 @@ func (sourceCCIP *SourceCCIPModule) CCIPMsg( return router.ClientEVM2AnyMessage{}, fmt.Errorf("failed encoding the receiver address: %w", err) } - extraArgsV1, err := testhelpers.GetEVMExtraArgsV1(gasLimit, false) + var extraArgs []byte + matchErr := contracts.MatchContractVersionsOrAbove(map[contracts.Name]contracts.Version{ + contracts.OnRampContract: contracts.V1_5_0, + }) + if matchErr != nil { + extraArgs, err = testhelpers.GetEVMExtraArgsV1(gasLimit, false) + } else { + extraArgs, err = testhelpers.GetEVMExtraArgsV2(gasLimit, allowOutOfOrder) + } if err != nil { - return router.ClientEVM2AnyMessage{}, fmt.Errorf("failed encoding the options field: %w", err) + return router.ClientEVM2AnyMessage{}, fmt.Errorf("failed getting extra args: %w", err) } // form the message for transfer return router.ClientEVM2AnyMessage{ @@ -1760,7 +1773,7 @@ func (sourceCCIP *SourceCCIPModule) CCIPMsg( Data: []byte(data), TokenAmounts: tokenAndAmounts, FeeToken: common.HexToAddress(sourceCCIP.Common.FeeToken.Address()), - ExtraArgs: extraArgsV1, + ExtraArgs: extraArgs, }, nil } @@ -1775,7 +1788,7 @@ func (sourceCCIP *SourceCCIPModule) SendRequest( return common.Hash{}, d, nil, fmt.Errorf("failed getting the chain selector: %w", err) } // form the message for transfer - msg, err := sourceCCIP.CCIPMsg(receiver, gasLimit) + msg, err := sourceCCIP.CCIPMsg(receiver, sourceCCIP.Common.AllowOutOfOrder, gasLimit) if err != nil { return common.Hash{}, d, nil, fmt.Errorf("failed forming the ccip msg: %w", err) } @@ -2218,7 +2231,7 @@ func (destCCIP *DestCCIPModule) AssertNoReportAcceptedEventReceived(lggr *zerolo e, exists := value.(*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged) if exists { vLogs := e.Raw - hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(ctx, big.NewInt(int64(vLogs.BlockNumber))) + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(ctx, new(big.Int).SetUint64(vLogs.BlockNumber)) if err != nil { return true } @@ -2259,7 +2272,7 @@ func (destCCIP *DestCCIPModule) AssertNoExecutionStateChangedEventReceived( e, exists := value.(*contracts.EVM2EVMOffRampExecutionStateChanged) if exists { vLogs := e.LogInfo - hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(ctx, big.NewInt(int64(vLogs.BlockNumber))) + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(ctx, new(big.Int).SetUint64(vLogs.BlockNumber)) if err != nil { return true } @@ -2288,7 +2301,7 @@ func (destCCIP *DestCCIPModule) AssertEventExecutionStateChanged( reqStat *testreporters.RequestStat, execState testhelpers.MessageExecutionState, ) (uint8, error) { - lggr.Info().Int64("seqNum", int64(seqNum)).Str("Timeout", timeout.String()).Msg("Waiting for ExecutionStateChanged event") + lggr.Info().Uint64("seqNum", seqNum).Str("Timeout", timeout.String()).Msg("Waiting for ExecutionStateChanged event") timer := time.NewTimer(timeout) defer timer.Stop() ticker := time.NewTicker(time.Second) @@ -2306,7 +2319,7 @@ func (destCCIP *DestCCIPModule) AssertEventExecutionStateChanged( destCCIP.ExecStateChangedWatcher.Delete(seqNum) vLogs := e.LogInfo receivedAt := time.Now().UTC() - hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(context.Background(), big.NewInt(int64(vLogs.BlockNumber))) + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(context.Background(), new(big.Int).SetUint64(vLogs.BlockNumber)) if err == nil { receivedAt = hdr.Timestamp } @@ -2319,7 +2332,7 @@ func (destCCIP *DestCCIPModule) AssertEventExecutionStateChanged( gasUsed = receipt.GasUsed } if testhelpers.MessageExecutionState(e.State) == execState { - lggr.Info().Int64("seqNum", int64(seqNum)).Uint8("ExecutionState", e.State).Msg("ExecutionStateChanged event received") + lggr.Info().Uint64("seqNum", seqNum).Uint8("ExecutionState", e.State).Msg("ExecutionStateChanged event received") reqStat.UpdateState(lggr, seqNum, testreporters.ExecStateChanged, receivedAt.Sub(timeNow), testreporters.Success, &testreporters.TransactionStats{ @@ -2363,7 +2376,7 @@ func (destCCIP *DestCCIPModule) AssertEventReportAccepted( prevEventAt time.Time, reqStat *testreporters.RequestStat, ) (*contracts.CommitStoreReportAccepted, time.Time, error) { - lggr.Info().Int64("seqNum", int64(seqNum)).Str("Timeout", timeout.String()).Msg("Waiting for ReportAccepted event") + lggr.Info().Uint64("seqNum", seqNum).Str("Timeout", timeout.String()).Msg("Waiting for ReportAccepted event") timer := time.NewTimer(timeout) defer timer.Stop() resetTimerCount := 0 @@ -2379,7 +2392,7 @@ func (destCCIP *DestCCIPModule) AssertEventReportAccepted( // if the value is processed, delete it from the map destCCIP.ReportAcceptedWatcher.Delete(seqNum) receivedAt := time.Now().UTC() - hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(context.Background(), big.NewInt(int64(reportAccepted.LogInfo.BlockNumber))) + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(context.Background(), new(big.Int).SetUint64(reportAccepted.LogInfo.BlockNumber)) if err == nil { receivedAt = hdr.Timestamp } @@ -2488,7 +2501,7 @@ func (destCCIP *DestCCIPModule) AssertReportBlessed( // if the value is processed, delete it from the map destCCIP.ReportBlessedBySeqNum.Delete(seqNum) } - hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(context.Background(), big.NewInt(int64(vLogs.BlockNumber))) + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(context.Background(), new(big.Int).SetUint64(vLogs.BlockNumber)) if err == nil { receivedAt = hdr.Timestamp } @@ -2536,7 +2549,7 @@ func (destCCIP *DestCCIPModule) AssertSeqNumberExecuted( timeNow time.Time, reqStat *testreporters.RequestStat, ) error { - lggr.Info().Int64("seqNum", int64(seqNumberBefore)).Str("Timeout", timeout.String()).Msg("Waiting to be processed by commit store") + lggr.Info().Uint64("seqNum", seqNumberBefore).Str("Timeout", timeout.String()).Msg("Waiting to be processed by commit store") timer := time.NewTimer(timeout) defer timer.Stop() resetTimerCount := 0 @@ -2793,7 +2806,11 @@ func (lane *CCIPLane) AddToSentReqs(txHash common.Hash, reqStats []*testreporter func (lane *CCIPLane) Multicall(noOfRequests int, multiSendAddr common.Address) error { var ccipMultipleMsg []contracts.CCIPMsgData feeToken := common.HexToAddress(lane.Source.Common.FeeToken.Address()) - genericMsg, err := lane.Source.CCIPMsg(lane.Dest.ReceiverDapp.EthAddress, big.NewInt(DefaultDestinationGasLimit)) + genericMsg, err := lane.Source.CCIPMsg( + lane.Dest.ReceiverDapp.EthAddress, + lane.Source.Common.AllowOutOfOrder, + big.NewInt(DefaultDestinationGasLimit), + ) if err != nil { return fmt.Errorf("failed to form the ccip message: %w", err) } @@ -2885,10 +2902,7 @@ func (lane *CCIPLane) Multicall(noOfRequests int, multiSendAddr common.Address) func (lane *CCIPLane) SendRequests(noOfRequests int, gasLimit *big.Int) error { for i := 1; i <= noOfRequests; i++ { stat := testreporters.NewCCIPRequestStats(int64(lane.NumberOfReq+i), lane.SourceNetworkName, lane.DestNetworkName) - txHash, txConfirmationDur, fee, err := lane.Source.SendRequest( - lane.Dest.ReceiverDapp.EthAddress, - gasLimit, - ) + txHash, txConfirmationDur, fee, err := lane.Source.SendRequest(lane.Dest.ReceiverDapp.EthAddress, gasLimit) if err != nil { stat.UpdateState(lane.Logger, 0, testreporters.TX, txConfirmationDur, testreporters.Failure, nil) return fmt.Errorf("could not send request: %w", err) @@ -3515,6 +3529,7 @@ func (lane *CCIPLane) DeployNewCCIPLane( srcConf = lane.SrcNetworkLaneCfg destConf = lane.DstNetworkLaneCfg commitAndExecOnSameDON = pointer.GetBool(testConf.CommitAndExecuteOnSameDON) + allowOutOfOrder = pointer.GetBool(testConf.AllowOutOfOrder) withPipeline = pointer.GetBool(testConf.TokenConfig.WithPipeline) configureCLNodes = !pointer.GetBool(testConf.ExistingDeployment) ) @@ -3529,6 +3544,13 @@ func (lane *CCIPLane) DeployNewCCIPLane( if err != nil { return fmt.Errorf("failed to create source module: %w", err) } + + // If AllowOutOfOrder is set globally in test config, the assumption is to set it for every lane. + // However, if this is set as false, and set as true for specific chain in lane_configs, then apply it + // only for a lane where source network is of that chain. + if allowOutOfOrder { + lane.Source.Common.AllowOutOfOrder = true + } lane.Dest, err = DefaultDestinationCCIPModule( lane.Logger, testConf, destChainClient, sourceChainClient.GetChainID().Uint64(), @@ -3781,12 +3803,18 @@ func SetOCR2Config( nodes = execNodes } if destCCIP.OffRamp != nil { + // Use out of order batching strategy if we expect to be sending out of order messages + batchingStrategyID := uint32(0) + if pointer.GetBool(testConf.AllowOutOfOrder) { + batchingStrategyID = uint32(1) + } execOffchainCfg, err := contracts.NewExecOffchainConfig( 1, BatchGasLimit, 0.7, *inflightExpiryExec, *commonconfig.MustNewDuration(RootSnoozeTime), + batchingStrategyID, ) if err != nil { return fmt.Errorf("failed to create exec offchain config: %w", err) diff --git a/integration-tests/ccip-tests/contracts/contract_deployer.go b/integration-tests/ccip-tests/contracts/contract_deployer.go index 211bbc1ebb..579d16da4f 100644 --- a/integration-tests/ccip-tests/contracts/contract_deployer.go +++ b/integration-tests/ccip-tests/contracts/contract_deployer.go @@ -77,7 +77,7 @@ func MatchContractVersionsOrAbove(requiredContractVersions map[Name]Version) err // if the version is less than 1.5.0, then token admin registry is not needed func NeedTokenAdminRegistry() bool { return MatchContractVersionsOrAbove(map[Name]Version{ - TokenPoolContract: V1_5_0_dev, + TokenPoolContract: V1_5_0, }) == nil } @@ -1044,6 +1044,7 @@ func (e *CCIPContractsDeployer) DeployOnRamp( MaxPerMsgGasLimit: 4_000_000, DefaultTokenFeeUSDCents: 50, DefaultTokenDestGasOverhead: 125_000, + EnforceOutOfOrder: false, }, evm_2_evm_onramp.RateLimiterConfig{ Capacity: opts.Capacity, @@ -1465,12 +1466,14 @@ func NewExecOnchainConfig( } } +// NewExecOffchainConfig creates a config for the OffChain portion of how CCIP operates func NewExecOffchainConfig( destOptimisticConfirmations uint32, batchGasLimit uint32, relativeBoostPerWaitHour float64, inflightCacheExpiry config.Duration, rootSnoozeTime config.Duration, + batchingStrategyID uint32, // See ccipexec package ) (ccipconfig.OffchainConfig, error) { switch VersionMap[OffRampContract] { case Latest: @@ -1480,6 +1483,7 @@ func NewExecOffchainConfig( relativeBoostPerWaitHour, inflightCacheExpiry, rootSnoozeTime, + batchingStrategyID, ), nil case V1_2_0: return testhelpers_1_4_0.NewExecOffchainConfig( @@ -1488,6 +1492,7 @@ func NewExecOffchainConfig( relativeBoostPerWaitHour, inflightCacheExpiry, rootSnoozeTime, + batchingStrategyID, ), nil default: return nil, fmt.Errorf("version not supported: %s", VersionMap[OffRampContract]) diff --git a/integration-tests/ccip-tests/contracts/contract_models.go b/integration-tests/ccip-tests/contracts/contract_models.go index e3f6e45fad..83fe12a60a 100644 --- a/integration-tests/ccip-tests/contracts/contract_models.go +++ b/integration-tests/ccip-tests/contracts/contract_models.go @@ -112,9 +112,9 @@ const ( var ( V1_2_0 = MustVersion("1.2.0") V1_4_0 = MustVersion("1.4.0") - V1_5_0_dev = MustVersion("1.5.0") - LatestPoolVersion = V1_5_0_dev - Latest = V1_5_0_dev + V1_5_0 = MustVersion("1.5.0") + LatestPoolVersion = V1_5_0 + Latest = V1_5_0 VersionMap = map[Name]Version{ PriceRegistryContract: V1_2_0, OffRampContract: Latest, @@ -1616,22 +1616,58 @@ func (w OnRampWrapper) ParseCCIPSendRequested(l types.Log) (uint64, error) { return 0, fmt.Errorf("no instance found to parse CCIPSendRequested") } -func (w OnRampWrapper) GetDynamicConfig(opts *bind.CallOpts) (uint32, error) { +// GetDynamicConfig retrieves the dynamic config for the onramp +func (w OnRampWrapper) GetDynamicConfig(opts *bind.CallOpts) (evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig, error) { if w.Latest != nil { cfg, err := w.Latest.GetDynamicConfig(opts) if err != nil { - return 0, err + return evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{}, err } - return cfg.MaxDataBytes, nil + return cfg, nil } if w.V1_2_0 != nil { cfg, err := w.V1_2_0.GetDynamicConfig(opts) if err != nil { - return 0, err + return evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{}, err } - return cfg.MaxDataBytes, nil + return evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ + Router: cfg.Router, + MaxNumberOfTokensPerMsg: cfg.MaxNumberOfTokensPerMsg, + DestGasOverhead: cfg.DestGasOverhead, + DestGasPerPayloadByte: cfg.DestGasPerPayloadByte, + DestDataAvailabilityOverheadGas: cfg.DestDataAvailabilityOverheadGas, + DestGasPerDataAvailabilityByte: cfg.DestGasPerDataAvailabilityByte, + DestDataAvailabilityMultiplierBps: cfg.DestDataAvailabilityMultiplierBps, + PriceRegistry: cfg.PriceRegistry, + MaxDataBytes: cfg.MaxDataBytes, + MaxPerMsgGasLimit: cfg.MaxPerMsgGasLimit, + }, nil + } + return evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{}, fmt.Errorf("no instance found to get dynamic config") +} + +// SetDynamicConfig sets the dynamic config for the onramp +// Note that you cannot set only a single field, you must set all fields or they will be reset to zero values +// You can use GetDynamicConfig to get the current config and modify it as needed +func (w OnRampWrapper) SetDynamicConfig(opts *bind.TransactOpts, dynamicConfig evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig) (*types.Transaction, error) { + if w.Latest != nil { + return w.Latest.SetDynamicConfig(opts, dynamicConfig) + } + if w.V1_2_0 != nil { + return w.V1_2_0.SetDynamicConfig(opts, evm_2_evm_onramp_1_2_0.EVM2EVMOnRampDynamicConfig{ + Router: dynamicConfig.Router, + MaxNumberOfTokensPerMsg: dynamicConfig.MaxNumberOfTokensPerMsg, + DestGasOverhead: dynamicConfig.DestGasOverhead, + DestGasPerPayloadByte: dynamicConfig.DestGasPerPayloadByte, + DestDataAvailabilityOverheadGas: dynamicConfig.DestDataAvailabilityOverheadGas, + DestGasPerDataAvailabilityByte: dynamicConfig.DestGasPerDataAvailabilityByte, + DestDataAvailabilityMultiplierBps: dynamicConfig.DestDataAvailabilityMultiplierBps, + PriceRegistry: dynamicConfig.PriceRegistry, + MaxDataBytes: dynamicConfig.MaxDataBytes, + MaxPerMsgGasLimit: dynamicConfig.MaxPerMsgGasLimit, + }) } - return 0, fmt.Errorf("no instance found to get dynamic config") + return nil, fmt.Errorf("no instance found to set dynamic config") } func (w OnRampWrapper) ApplyPoolUpdates(opts *bind.TransactOpts, tokens []common.Address, pools []common.Address) (*types.Transaction, error) { diff --git a/integration-tests/ccip-tests/contracts/laneconfig/parse_contracts.go b/integration-tests/ccip-tests/contracts/laneconfig/parse_contracts.go index 332bd48ab3..c96cb3dfdc 100644 --- a/integration-tests/ccip-tests/contracts/laneconfig/parse_contracts.go +++ b/integration-tests/ccip-tests/contracts/laneconfig/parse_contracts.go @@ -21,6 +21,7 @@ var ( type CommonContracts struct { IsNativeFeeToken bool `json:"is_native_fee_token,omitempty"` + AllowOutOfOrder bool `json:"allow_out_of_order,omitempty"` // expected to set this value as True for ZK chain source networks IsMockARM bool `json:"is_mock_arm,omitempty"` FeeToken string `json:"fee_token"` BridgeTokens []string `json:"bridge_tokens,omitempty"` diff --git a/integration-tests/ccip-tests/load/ccip_loadgen.go b/integration-tests/ccip-tests/load/ccip_loadgen.go index 9dc8ce16e5..bc7627b4e0 100644 --- a/integration-tests/ccip-tests/load/ccip_loadgen.go +++ b/integration-tests/ccip-tests/load/ccip_loadgen.go @@ -22,6 +22,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testconfig" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" @@ -132,8 +133,9 @@ func (c *CCIPE2ELoad) BeforeAllCall() { c.EOAReceiver = c.msg.Receiver } if c.SendMaxDataIntermittentlyInMsgCount > 0 { - c.MaxDataBytes, err = sourceCCIP.OnRamp.Instance.GetDynamicConfig(nil) + cfg, err := sourceCCIP.OnRamp.Instance.GetDynamicConfig(nil) require.NoError(c.t, err, "failed to fetch dynamic config") + c.MaxDataBytes = cfg.MaxDataBytes } // if the msg is sent via multicall, transfer the token transfer amount to multicall contract if sourceCCIP.Common.MulticallEnabled && @@ -189,11 +191,27 @@ func (c *CCIPE2ELoad) CCIPMsg() (router.ClientEVM2AnyMessage, *testreporters.Req if !msgDetails.IsTokenTransfer() { msg.TokenAmounts = []router.ClientEVMTokenAmount{} } - extraArgsV1, err := testhelpers.GetEVMExtraArgsV1(big.NewInt(gasLimit), false) + + var ( + extraArgs []byte + err error + ) + matchErr := contracts.MatchContractVersionsOrAbove(map[contracts.Name]contracts.Version{ + contracts.OnRampContract: contracts.V1_5_0, + }) + // TODO: The CCIP Offchain upgrade tests make the AllowOutOfOrder flag tricky in this case. + // It runs with out of date contract versions at first, then upgrades them. So transactions will assume that the new contracts are there + // before being deployed. So setting v2 args will break the test. This is a bit of a hack to get around that. + // The test will soon be deprecated, so a temporary solution is fine. + if matchErr != nil || !c.Lane.Source.Common.AllowOutOfOrder { + extraArgs, err = testhelpers.GetEVMExtraArgsV1(big.NewInt(gasLimit), false) + } else { + extraArgs, err = testhelpers.GetEVMExtraArgsV2(big.NewInt(gasLimit), c.Lane.Source.Common.AllowOutOfOrder) + } if err != nil { return router.ClientEVM2AnyMessage{}, stats, err } - msg.ExtraArgs = extraArgsV1 + msg.ExtraArgs = extraArgs // if gaslimit is 0, set the receiver to EOA if gasLimit == 0 { msg.Receiver = c.EOAReceiver diff --git a/integration-tests/ccip-tests/load/helper.go b/integration-tests/ccip-tests/load/helper.go index e4ee4573b2..34860c8871 100644 --- a/integration-tests/ccip-tests/load/helper.go +++ b/integration-tests/ccip-tests/load/helper.go @@ -199,10 +199,7 @@ func (l *LoadArgs) ValidateCurseFollowedByUncurse() { // try to send requests on lanes on which curse is applied on source RMN and the request should revert // data-only transfer is sufficient lane.Source.TransferAmount = []*big.Int{} - failedTx, _, _, err := lane.Source.SendRequest( - lane.Dest.ReceiverDapp.EthAddress, - big.NewInt(actions.DefaultDestinationGasLimit), // gas limit - ) + failedTx, _, _, err := lane.Source.SendRequest(lane.Dest.ReceiverDapp.EthAddress, big.NewInt(actions.DefaultDestinationGasLimit)) if lane.Source.Common.ChainClient.GetNetworkConfig().MinimumConfirmations > 0 { require.Error(l.t, err) } else { diff --git a/integration-tests/ccip-tests/smoke/ccip_test.go b/integration-tests/ccip-tests/smoke/ccip_test.go index 0ed7f60dd3..0805445948 100644 --- a/integration-tests/ccip-tests/smoke/ccip_test.go +++ b/integration-tests/ccip-tests/smoke/ccip_test.go @@ -244,10 +244,7 @@ func TestSmokeCCIPRateLimit(t *testing.T) { tc.lane.Source.Common.ChainClient.GetDefaultWallet(), src.Common.Router.Address(), src.TransferAmount[0]), ) require.NoError(t, tc.lane.Source.Common.ChainClient.WaitForEvents()) - failedTx, _, _, err := tc.lane.Source.SendRequest( - tc.lane.Dest.ReceiverDapp.EthAddress, - big.NewInt(actions.DefaultDestinationGasLimit), // gas limit - ) + failedTx, _, _, err := tc.lane.Source.SendRequest(tc.lane.Dest.ReceiverDapp.EthAddress, big.NewInt(actions.DefaultDestinationGasLimit)) require.NoError(t, err) require.Error(t, tc.lane.Source.Common.ChainClient.WaitForEvents()) errReason, v, err := tc.lane.Source.Common.ChainClient.RevertReasonFromTx(failedTx, evm_2_evm_onramp.EVM2EVMOnRampABI) @@ -272,10 +269,7 @@ func TestSmokeCCIPRateLimit(t *testing.T) { // try to send again with amount more than the amount refilled by rate and // this should fail, as the refill rate is not enough to refill the capacity src.TransferAmount[0] = new(big.Int).Mul(AggregatedRateLimitRate, big.NewInt(10)) - failedTx, _, _, err = tc.lane.Source.SendRequest( - tc.lane.Dest.ReceiverDapp.EthAddress, - big.NewInt(actions.DefaultDestinationGasLimit), // gas limit - ) + failedTx, _, _, err = tc.lane.Source.SendRequest(tc.lane.Dest.ReceiverDapp.EthAddress, big.NewInt(actions.DefaultDestinationGasLimit)) tc.lane.Logger.Info().Str("tokensToSend", src.TransferAmount[0].String()).Msg("More than Aggregated Rate") require.NoError(t, err) require.Error(t, tc.lane.Source.Common.ChainClient.WaitForEvents()) @@ -339,10 +333,7 @@ func TestSmokeCCIPRateLimit(t *testing.T) { src.TransferAmount[0] = tokensToSend tc.lane.Logger.Info().Str("tokensToSend", tokensToSend.String()).Msg("More than Token Pool Capacity") - failedTx, _, _, err = tc.lane.Source.SendRequest( - tc.lane.Dest.ReceiverDapp.EthAddress, - big.NewInt(actions.DefaultDestinationGasLimit), // gas limit - ) + failedTx, _, _, err = tc.lane.Source.SendRequest(tc.lane.Dest.ReceiverDapp.EthAddress, big.NewInt(actions.DefaultDestinationGasLimit)) require.NoError(t, err) require.Error(t, tc.lane.Source.Common.ChainClient.WaitForEvents()) errReason, v, err = tc.lane.Source.Common.ChainClient.RevertReasonFromTx(failedTx, lock_release_token_pool.LockReleaseTokenPoolABI) @@ -374,10 +365,7 @@ func TestSmokeCCIPRateLimit(t *testing.T) { src.Common.ChainClient.GetDefaultWallet(), src.Common.Router.Address(), src.TransferAmount[0]), ) require.NoError(t, tc.lane.Source.Common.ChainClient.WaitForEvents()) - failedTx, _, _, err = tc.lane.Source.SendRequest( - tc.lane.Dest.ReceiverDapp.EthAddress, - big.NewInt(actions.DefaultDestinationGasLimit), - ) + failedTx, _, _, err = tc.lane.Source.SendRequest(tc.lane.Dest.ReceiverDapp.EthAddress, big.NewInt(actions.DefaultDestinationGasLimit)) require.NoError(t, err) require.Error(t, tc.lane.Source.Common.ChainClient.WaitForEvents()) errReason, v, err = tc.lane.Source.Common.ChainClient.RevertReasonFromTx(failedTx, lock_release_token_pool.LockReleaseTokenPoolABI) @@ -406,8 +394,8 @@ func TestSmokeCCIPOnRampLimits(t *testing.T) { "This test modifies contract state. Before running it, ensure you are willing and able to do so.", ) err := contracts.MatchContractVersionsOrAbove(map[contracts.Name]contracts.Version{ - contracts.OffRampContract: contracts.V1_5_0_dev, - contracts.OnRampContract: contracts.V1_5_0_dev, + contracts.OffRampContract: contracts.V1_5_0, + contracts.OnRampContract: contracts.V1_5_0, }) require.NoError(t, err, "Required contract versions not met") @@ -627,8 +615,8 @@ func TestSmokeCCIPTokenPoolRateLimits(t *testing.T) { "This test modifies contract state. Before running it, ensure you are willing and able to do so.", ) err := contracts.MatchContractVersionsOrAbove(map[contracts.Name]contracts.Version{ - contracts.OffRampContract: contracts.V1_5_0_dev, - contracts.OnRampContract: contracts.V1_5_0_dev, + contracts.OffRampContract: contracts.V1_5_0, + contracts.OnRampContract: contracts.V1_5_0, }) require.NoError(t, err, "Required contract versions not met") @@ -1006,7 +994,7 @@ func testOffRampRateLimits(t *testing.T, rateLimiterConfig contracts.RateLimiter "This test modifies contract state. Before running it, ensure you are willing and able to do so.", ) err := contracts.MatchContractVersionsOrAbove(map[contracts.Name]contracts.Version{ - contracts.OffRampContract: contracts.V1_5_0_dev, + contracts.OffRampContract: contracts.V1_5_0, }) require.NoError(t, err, "Required contract versions not met") require.False(t, pointer.GetBool(TestCfg.TestGroupInput.ExistingDeployment), "This test modifies contract state and cannot be run on existing deployments") diff --git a/integration-tests/ccip-tests/testconfig/README.md b/integration-tests/ccip-tests/testconfig/README.md index d464ae247f..ff57ecaa22 100644 --- a/integration-tests/ccip-tests/testconfig/README.md +++ b/integration-tests/ccip-tests/testconfig/README.md @@ -480,6 +480,10 @@ Specifies whether to set up bi-directional lanes between networks. Specifies whether commit and execution jobs are to be run on the same Chainlink node. +### CCIP.Groups.[testgroup].AllowOutOfOrder + +Specifies whether out of order execution is allowed globally for all the chains. + ### CCIP.Groups.[testgroup].NoOfCommitNodes Specifies the number of nodes on which commit jobs are to be run. This needs to be lesser than the total number of nodes mentioned in [CCIP.Env.NewCLCluster.NoOfNodes](#ccipenvnewclclusternoofnodes) or [CCIP.Env.ExistingCLCluster.NoOfNodes](#ccipenvexistingclclusternoofnodes). diff --git a/integration-tests/ccip-tests/testconfig/ccip.go b/integration-tests/ccip-tests/testconfig/ccip.go index 19ebd304ce..76e00ecf49 100644 --- a/integration-tests/ccip-tests/testconfig/ccip.go +++ b/integration-tests/ccip-tests/testconfig/ccip.go @@ -266,6 +266,7 @@ type CCIPTestGroupConfig struct { KeepEnvAlive *bool `toml:",omitempty"` BiDirectionalLane *bool `toml:",omitempty"` CommitAndExecuteOnSameDON *bool `toml:",omitempty"` + AllowOutOfOrder *bool `toml:",omitempty"` // To set out of order execution globally NoOfCommitNodes int `toml:",omitempty"` MsgDetails *MsgDetails `toml:",omitempty"` TokenConfig *TokenConfig `toml:",omitempty"` diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml index 0157ac24fb..b03f03a6da 100644 --- a/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml +++ b/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml @@ -27,7 +27,7 @@ ethereum_version = "eth1" # geth, besu, erigon or nethermind execution_layer = "geth" # eth2-only, if set to true environment startup will wait until at least 1 epoch has been finalised -wait_for_finalization=false +wait_for_finalization = false [CCIP.Env.PrivateEthereumNetworks.SIMULATED_1.EthereumChainConfig] # eth2-only, the lower the value the faster the block production (3 is minimum) @@ -239,6 +239,8 @@ EIP1559FeeCapBufferBlocks = 0 KeepEnvAlive = false # if true, the test will not tear down the test environment after the test is finished CommitAndExecuteOnSameDON = true # if true, and the test is building the env from scratch, same chainlink nodes will be used for Commit and Execution jobs. +AllowOutOfOrder = false # if true, all the lanes will allow out of order execution and it +# overrides settings from lane_config. To allow out of order execution per lane, then send "allow_out_of_order":true, similar to is_native_fee_token variable. # Otherwise Commit and execution jobs will be set up in different nodes based on the number of nodes specified in NoOfCommitNodes and CCIP.Env.NewCLCluster.NoOfNodes BiDirectionalLane = true # True uses both the lanes. If bidirectional is false only one way lane is set up. NoOfCommitNodes = 5 # no of chainlink nodes with Commit job @@ -271,7 +273,7 @@ TimeoutForPriceUpdate = '15m' # Duration to wait for the price update to time-ou # Now testing only with dynamic price getter (no pipeline). # Could be removed once the pipeline is completely removed. WithPipeline = false -NoOfTokensPerChain = 2 # number of bridge tokens to be deployed per network; if MsgType = 'Token'/'DataWithToken' +NoOfTokensPerChain = 2 # number of bridge tokens to be deployed per network; if MsgType = 'Token'/'DataWithToken' CCIPOwnerTokens = false # if true, the test will use deploy the tokens by the CCIPOwner, otherwise the tokens will be deployed by a non-owner account, only applicable for 1.5 pools and onwards #NoOfTokensWithDynamicPrice = 15 # number of tokens with dynamic price to be deployed @@ -293,6 +295,7 @@ CCIPOwnerTokens = false # if true, the test will use deploy the tokens by the CC KeepEnvAlive = false # same as above CommitAndExecuteOnSameDON = true # same as above +AllowOutOfOrder = false # same as above BiDirectionalLane = true # same as above NoOfCommitNodes = 5 # same as above PhaseTimeout = '10m' # same as above @@ -351,7 +354,7 @@ TimeoutForPriceUpdate = '15m' # Duration to wait for the price update to time-ou # Now testing only with dynamic price getter (no pipeline). # Could be removed once the pipeline is completely removed. WithPipeline = false -NoOfTokensPerChain = 2 # number of bridge tokens to be deployed per network; if MsgType = 'Token'/'DataWithToken' +NoOfTokensPerChain = 2 # number of bridge tokens to be deployed per network; if MsgType = 'Token'/'DataWithToken' CCIPOwnerTokens = false # if true, the test will use deploy the tokens by the CCIPOwner, otherwise the tokens and pools will be deployed by a non-owner account, # only applicable for 1.5 pools and onwards, if you are running with pre-1.5 pools, then set this to true to deploy token pools by CCIPOwner, otherwise # the test will fail @@ -403,6 +406,7 @@ CCIPOwnerTokens = false # if true, the test will use deploy the tokens by the CC #NetworkPairs = ['SEPOLIA,OPTIMISM_GOERLI','SEPOLIA,POLYGON_MUMBAI','AVALANCHE_FUJI,SEPOLIA','SEPOLIA,BASE_GOERLI','SEPOLIA,BSC_TESTNET','SEPOLIA,WEMIX_TESTNET','AVALANCHE_FUJI,OPTIMISM_GOERLI','AVALANCHE_FUJI,POLYGON_MUMBAI','AVALANCHE_FUJI,BSC_TESTNET','AVALANCHE_FUJI,BASE_GOERLI','OPTIMISM_GOERLI,BASE_GOERLI','OPTIMISM_GOERLI,POLYGON_MUMBAI','BSC_TESTNET,POLYGON_MUMBAI','BSC_TESTNET,BASE_GOERLI','WEMIX_TESTNET,KROMA_SEPOLIA'] KeepEnvAlive = false CommitAndExecuteOnSameDON = false +AllowOutOfOrder = false BiDirectionalLane = true NoOfCommitNodes = 5 PhaseTimeout = '50m' From b1fdcd9194f8a67283220f297e914adabd3adf0f Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Wed, 18 Sep 2024 13:07:06 +0400 Subject: [PATCH 366/432] [DEVSVCS-545] automation benchmark test remove support for keepers v1 (#14472) * Remove keepers v1.X support from benchmark test * config cleanup * update references --- .github/e2e-tests.yml | 4 +- .../actions/automationv2/actions.go | 12 +- .../{keeper_test.go => automation_test.go} | 56 ++-- .../testconfig/automation/automation.toml | 240 +++++++++++++++++- .../testconfig/automation/config.go | 75 ++++++ integration-tests/testconfig/keeper/config.go | 102 -------- .../testconfig/keeper/keeper.toml | 127 --------- .../testsetups/keeper_benchmark.go | 200 +++++---------- integration-tests/types/testconfigs.go | 4 +- 9 files changed, 416 insertions(+), 404 deletions(-) rename integration-tests/benchmark/{keeper_test.go => automation_test.go} (85%) diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 8ee5b207a8..0ee7a50d0c 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -603,8 +603,8 @@ runner-test-matrix: test_env_vars: TEST_SUITE: chaos - - id: benchmark/keeper_test.go:^TestAutomationBenchmark$ - path: integration-tests/benchmark/keeper_test.go + - id: benchmark/automation_test.go:^TestAutomationBenchmark$ + path: integration-tests/benchmark/automation_test.go test_env_type: k8s-remote-runner remote_runner_memory: 4Gi runs_on: ubuntu-latest diff --git a/integration-tests/actions/automationv2/actions.go b/integration-tests/actions/automationv2/actions.go index 0aebec546d..6ce35873d8 100644 --- a/integration-tests/actions/automationv2/actions.go +++ b/integration-tests/actions/automationv2/actions.go @@ -860,6 +860,14 @@ func (a *AutomationTest) SetupMercuryMock(t *testing.T, imposters []ctfTestEnv.K } func (a *AutomationTest) SetupAutomationDeployment(t *testing.T) { + a.setupDeployment(t, true) +} + +func (a *AutomationTest) SetupAutomationDeploymentWithoutJobs(t *testing.T) { + a.setupDeployment(t, false) +} + +func (a *AutomationTest) setupDeployment(t *testing.T, addJobs bool) { l := logging.GetTestLogger(t) err := a.CollectNodeDetails() require.NoError(t, err, "Error collecting node details") @@ -891,7 +899,9 @@ func (a *AutomationTest) SetupAutomationDeployment(t *testing.T) { err = a.DeployRegistrar() require.NoError(t, err, "Error deploying registrar contract") - a.AddJobsAndSetConfig(t) + if addJobs { + a.AddJobsAndSetConfig(t) + } } func (a *AutomationTest) LoadAutomationDeployment(t *testing.T, linkTokenAddress, diff --git a/integration-tests/benchmark/keeper_test.go b/integration-tests/benchmark/automation_test.go similarity index 85% rename from integration-tests/benchmark/keeper_test.go rename to integration-tests/benchmark/automation_test.go index 5c7ce23761..f7e98e6a7a 100644 --- a/integration-tests/benchmark/keeper_test.go +++ b/integration-tests/benchmark/automation_test.go @@ -75,7 +75,7 @@ func TestAutomationBenchmark(t *testing.T) { testType, err := tc.GetConfigurationNameFromEnv() require.NoError(t, err, "Error getting test type") - config, err := tc.GetConfig([]string{testType}, tc.Keeper) + config, err := tc.GetConfig([]string{testType}, tc.Automation) require.NoError(t, err, "Error getting test config") testEnvironment, benchmarkNetwork := SetupAutomationBenchmarkEnv(t, &config) @@ -83,7 +83,7 @@ func TestAutomationBenchmark(t *testing.T) { return } networkName := strings.ReplaceAll(benchmarkNetwork.Name, " ", "") - testName := fmt.Sprintf("%s%s", networkName, *config.Keeper.Common.RegistryToTest) + testName := fmt.Sprintf("%s%s", networkName, *config.Automation.Benchmark.RegistryToTest) l.Info().Str("Test Name", testName).Msg("Running Benchmark Test") benchmarkTestNetwork := getNetworkConfig(&config) @@ -105,7 +105,7 @@ func TestAutomationBenchmark(t *testing.T) { CheckGasLimit: uint32(45_000_000), //45M StalenessSeconds: big.NewInt(90_000), GasCeilingMultiplier: uint16(2), - MaxPerformGas: uint32(*config.Keeper.Common.MaxPerformGas), + MaxPerformGas: uint32(*config.Automation.Benchmark.MaxPerformGas), MinUpkeepSpend: big.NewInt(0), FallbackGasPrice: big.NewInt(2e11), FallbackLinkPrice: big.NewInt(2e18), @@ -114,27 +114,20 @@ func TestAutomationBenchmark(t *testing.T) { MaxRevertDataSize: uint32(5_000), }, Upkeeps: &testsetups.UpkeepConfig{ - NumberOfUpkeeps: *config.Keeper.Common.NumberOfUpkeeps, - CheckGasToBurn: *config.Keeper.Common.CheckGasToBurn, - PerformGasToBurn: *config.Keeper.Common.PerformGasToBurn, - BlockRange: *config.Keeper.Common.BlockRange, - BlockInterval: *config.Keeper.Common.BlockInterval, - UpkeepGasLimit: *config.Keeper.Common.UpkeepGasLimit, + NumberOfUpkeeps: *config.Automation.Benchmark.NumberOfUpkeeps, + CheckGasToBurn: *config.Automation.Benchmark.CheckGasToBurn, + PerformGasToBurn: *config.Automation.Benchmark.PerformGasToBurn, + BlockRange: *config.Automation.Benchmark.BlockRange, + BlockInterval: *config.Automation.Benchmark.BlockInterval, + UpkeepGasLimit: *config.Automation.Benchmark.UpkeepGasLimit, FirstEligibleBuffer: 1, }, - Contracts: &testsetups.PreDeployedContracts{ - RegistrarAddress: *config.Keeper.Common.RegistrarAddress, - RegistryAddress: *config.Keeper.Common.RegistryAddress, - LinkTokenAddress: *config.Keeper.Common.LinkTokenAddress, - EthFeedAddress: *config.Keeper.Common.EthFeedAddress, - GasFeedAddress: *config.Keeper.Common.GasFeedAddress, - }, ChainlinkNodeFunding: benchmarkTestNetwork.funding, UpkeepSLA: benchmarkTestNetwork.upkeepSLA, BlockTime: benchmarkTestNetwork.blockTime, DeltaStage: benchmarkTestNetwork.deltaStage, - ForceSingleTxnKey: *config.Keeper.Common.ForceSingleTxKey, - DeleteJobsOnEnd: *config.Keeper.Common.DeleteJobsOnEnd, + ForceSingleTxnKey: *config.Automation.Benchmark.ForceSingleTxKey, + DeleteJobsOnEnd: *config.Automation.Benchmark.DeleteJobsOnEnd, }, ) t.Cleanup(func() { @@ -152,13 +145,7 @@ func TestAutomationBenchmark(t *testing.T) { } func addRegistry(config *tc.TestConfig) []ethcontracts.KeeperRegistryVersion { - switch *config.Keeper.Common.RegistryToTest { - case "1_1": - return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_1_1} - case "1_2": - return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_1_2} - case "1_3": - return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_1_3} + switch *config.Automation.Benchmark.RegistryToTest { case "2_0": return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_0} case "2_1": @@ -167,19 +154,14 @@ func addRegistry(config *tc.TestConfig) []ethcontracts.KeeperRegistryVersion { return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_2} case "2_3": return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_3} - case "2_0-1_3": - return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_0, ethcontracts.RegistryVersion_1_3} - case "2_1-2_0-1_3": - return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_1, - ethcontracts.RegistryVersion_2_0, ethcontracts.RegistryVersion_1_3} case "2_2-2_1": return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_2, ethcontracts.RegistryVersion_2_1} case "2_0-Multiple": - return repeatRegistries(ethcontracts.RegistryVersion_2_0, *config.Keeper.Common.NumberOfRegistries) + return repeatRegistries(ethcontracts.RegistryVersion_2_0, *config.Automation.Benchmark.NumberOfRegistries) case "2_1-Multiple": - return repeatRegistries(ethcontracts.RegistryVersion_2_1, *config.Keeper.Common.NumberOfRegistries) + return repeatRegistries(ethcontracts.RegistryVersion_2_1, *config.Automation.Benchmark.NumberOfRegistries) case "2_2-Multiple": - return repeatRegistries(ethcontracts.RegistryVersion_2_2, *config.Keeper.Common.NumberOfRegistries) + return repeatRegistries(ethcontracts.RegistryVersion_2_2, *config.Automation.Benchmark.NumberOfRegistries) default: return []ethcontracts.KeeperRegistryVersion{ethcontracts.RegistryVersion_2_0} } @@ -275,13 +257,13 @@ var networkConfig = map[string]NetworkConfig{ }, } -func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.KeeperBenchmarkTestConfig) (*environment.Environment, blockchain.EVMNetwork) { +func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.AutomationBenchmarkTestConfig) (*environment.Environment, blockchain.EVMNetwork) { l := logging.GetTestLogger(t) testNetwork := networks.MustGetSelectedNetworkConfig(keeperTestConfig.GetNetworkConfig())[0] // Environment currently being used to run benchmark test on blockTime := "1" - numberOfNodes := *keeperTestConfig.GetKeeperConfig().Common.NumberOfNodes + numberOfNodes := *keeperTestConfig.GetAutomationConfig().General.NumberOfNodes - if strings.Contains(*keeperTestConfig.GetKeeperConfig().Common.RegistryToTest, "2_") { + if strings.Contains(*keeperTestConfig.GetAutomationConfig().Benchmark.RegistryToTest, "2_") { numberOfNodes++ } @@ -295,7 +277,7 @@ func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.KeeperBenc "automation-%s-%s-%s", strings.ToLower(strings.Join(keeperTestConfig.GetConfigurationNames(), "")), strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-"), - strings.ReplaceAll(strings.ToLower(*keeperTestConfig.GetKeeperConfig().Common.RegistryToTest), "_", "-"), + strings.ReplaceAll(strings.ToLower(*keeperTestConfig.GetAutomationConfig().Benchmark.RegistryToTest), "_", "-"), ), Test: t, PreventPodEviction: true, diff --git a/integration-tests/testconfig/automation/automation.toml b/integration-tests/testconfig/automation/automation.toml index 26b9f05597..5513355eae 100644 --- a/integration-tests/testconfig/automation/automation.toml +++ b/integration-tests/testconfig/automation/automation.toml @@ -294,4 +294,242 @@ max_perform_data_size=5_000 max_revert_data_size=5_000 [Load.Pyroscope] -enabled=false \ No newline at end of file +enabled=false + +# automation benchmark test specific overrides + +# will retry roughly for 1h before giving up (900 * 4s) +[Benchmark.Automation.Resiliency] +# number of retries before giving up +contract_call_limit = 900 +# static interval between retries +contract_call_interval = "4s" + +[Benchmark.Seth] +# keeper benchmark running on simulated network requires 100k per node +root_key_funds_buffer = 1_000_000 + +[Benchmark.Automation] +[Benchmark.Automation.General] +number_of_nodes=6 +duration=3600 +block_time=1 +spec_type="minimum" +chainlink_node_log_level="info" +use_prometheus=false +remove_namespace = true + +[Benchmark.Automation.Benchmark] +registry_to_test = "2_1" +number_of_registries = 1 +number_of_nodes = 6 +number_of_upkeeps = 1000 +upkeep_gas_limit = 1500000 +check_gas_to_burn = 10000 +perform_gas_to_burn = 1000 +max_perform_gas = 5000000 +block_range = 3600 +block_interval = 60 +forces_single_tx_key = false +delete_jobs_on_end = true + +[Benchmark.NodeConfig] +BaseConfigTOML = """ +[Feature] +LogPoller = true + +[OCR2] +Enabled = true + +[P2P] +[P2P.V2] +Enabled = true +AnnounceAddresses = ["0.0.0.0:6690"] +ListenAddresses = ["0.0.0.0:6690"] +[Keeper] +TurnLookBack = 0 +[WebServer] +HTTPWriteTimeout = '1h' +""" + +CommonChainConfigTOML = """ +""" + +[Benchmark.NodeConfig.ChainConfigTOMLByChainID] +# applicable for simulated chain +1337 = """ +FinalityDepth = 50 +LogPollInterval = '1s' +MinIncomingConfirmations = 1 + +[HeadTracker] +HistoryDepth = 100 + +[GasEstimator] +Mode = 'FixedPrice' +LimitDefault = 5_000_000 +""" + +[Benchmark.Automation.AutomationConfig] +use_log_buffer_v1=false + +[Benchmark.Automation.AutomationConfig.PublicConfig] +delta_progress=10_000_000_000 +delta_resend=15_000_000_000 +delta_initial=500_000_000 +delta_round=1_000_000_000 +delta_grace=200_000_000 +delta_certified_commit_request=300_000_000 +delta_stage=30_000_000_000 +r_max=24 +f=1 +max_duration_query=20_000_000 +max_duration_observation=20_000_000 +max_duration_should_accept_attested_report=1_200_000_000 +max_duration_should_transmit_accepted_report=20_000_000 + +[Benchmark.Automation.AutomationConfig.PluginConfig] +perform_lockout_window=3_600_000 +target_probability="0.999" +target_in_rounds=1 +min_confirmations=0 +gas_limit_per_report=10_300_000 +gas_overhead_per_upkeep=300_000 +max_upkeep_batch_size=10 + +[Benchmark.Automation.AutomationConfig.PluginConfig.LogProviderConfig] +block_rate=1 +log_limit=2 + +[Benchmark.Automation.AutomationConfig.RegistrySettings] +payment_premium_ppb=200_000_000 +flat_fee_micro_link=0 +check_gas_limit=2_500_000 +staleness_seconds=90000 +gas_ceiling_multiplier=1 +max_perform_gas=5_000_000 +min_upkeep_spend=0 +fallback_gas_price=200_000_000_000 +fallback_link_price=2_000_000_000_000_000_000 +max_check_data_size=5_000 +max_perform_data_size=5_000 +max_revert_data_size=5_000 + +# automation soak test specific overrides + +# will retry roughly for 1h before giving up (900 * 4s) +[Soak.Automation.Resiliency] +# number of retries before giving up +contract_call_limit = 900 +# static interval between retries +contract_call_interval = "4s" + +[Soak.Seth] +# keeper benchmark running on simulated network requires 100k per node +root_key_funds_buffer = 1_000_000 + +[Soak.Automation] +[Soak.Automation.General] +number_of_nodes=6 +duration=3600 +block_time=1 +spec_type="minimum" +chainlink_node_log_level="info" +use_prometheus=false +remove_namespace = true + +[Soak.Automation.Benchmark] +registry_to_test = "2_1" +number_of_registries = 1 +number_of_nodes = 6 +number_of_upkeeps = 50 +upkeep_gas_limit = 1500000 +check_gas_to_burn = 10000 +perform_gas_to_burn = 1000 +max_perform_gas = 5000000 +block_range = 28800 +block_interval = 300 +forces_single_tx_key = false +delete_jobs_on_end = true + +[Soak.NodeConfig] +BaseConfigTOML = """ +[Feature] +LogPoller = true + +[OCR2] +Enabled = true + +[P2P] +[P2P.V2] +Enabled = true +AnnounceAddresses = ["0.0.0.0:6690"] +ListenAddresses = ["0.0.0.0:6690"] +[Keeper] +TurnLookBack = 0 +[WebServer] +HTTPWriteTimeout = '1h' +""" + +CommonChainConfigTOML = """ +""" + +[Soak.NodeConfig.ChainConfigTOMLByChainID] +# applicable for simulated chain +1337 = """ +FinalityDepth = 50 +LogPollInterval = '1s' +MinIncomingConfirmations = 1 + +[HeadTracker] +HistoryDepth = 100 + +[GasEstimator] +Mode = 'FixedPrice' +LimitDefault = 5_000_000 +""" + +[Soak.Automation.AutomationConfig] +use_log_buffer_v1=false + +[Soak.Automation.AutomationConfig.PublicConfig] +delta_progress=10_000_000_000 +delta_resend=15_000_000_000 +delta_initial=500_000_000 +delta_round=1_000_000_000 +delta_grace=200_000_000 +delta_certified_commit_request=300_000_000 +delta_stage=30_000_000_000 +r_max=24 +f=1 +max_duration_query=20_000_000 +max_duration_observation=20_000_000 +max_duration_should_accept_attested_report=1_200_000_000 +max_duration_should_transmit_accepted_report=20_000_000 + +[Soak.Automation.AutomationConfig.PluginConfig] +perform_lockout_window=3_600_000 +target_probability="0.999" +target_in_rounds=1 +min_confirmations=0 +gas_limit_per_report=10_300_000 +gas_overhead_per_upkeep=300_000 +max_upkeep_batch_size=10 + +[Soak.Automation.AutomationConfig.PluginConfig.LogProviderConfig] +block_rate=1 +log_limit=2 + +[Soak.Automation.AutomationConfig.RegistrySettings] +payment_premium_ppb=200_000_000 +flat_fee_micro_link=0 +check_gas_limit=2_500_000 +staleness_seconds=90000 +gas_ceiling_multiplier=1 +max_perform_gas=5_000_000 +min_upkeep_spend=0 +fallback_gas_price=200_000_000_000 +fallback_link_price=2_000_000_000_000_000_000 +max_check_data_size=5_000 +max_perform_data_size=5_000 +max_revert_data_size=5_000 diff --git a/integration-tests/testconfig/automation/config.go b/integration-tests/testconfig/automation/config.go index bb38b213ec..96f625a0cf 100644 --- a/integration-tests/testconfig/automation/config.go +++ b/integration-tests/testconfig/automation/config.go @@ -4,6 +4,8 @@ import ( "errors" "math/big" "time" + + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" ) type Config struct { @@ -11,6 +13,8 @@ type Config struct { Load []Load `toml:"Load"` DataStreams *DataStreams `toml:"DataStreams"` AutomationConfig *AutomationConfig `toml:"AutomationConfig"` + Resiliency *ResiliencyConfig `toml:"Resiliency"` + Benchmark *Benchmark `toml:"Benchmark"` } func (c *Config) Validate() error { @@ -37,6 +41,61 @@ func (c *Config) Validate() error { return err } } + if c.Resiliency != nil { + if err := c.Resiliency.Validate(); err != nil { + return err + } + } + if c.Benchmark != nil { + if err := c.Benchmark.Validate(); err != nil { + return err + } + } + return nil +} + +type Benchmark struct { + RegistryToTest *string `toml:"registry_to_test"` + NumberOfRegistries *int `toml:"number_of_registries"` + NumberOfUpkeeps *int `toml:"number_of_upkeeps"` + UpkeepGasLimit *int64 `toml:"upkeep_gas_limit"` + CheckGasToBurn *int64 `toml:"check_gas_to_burn"` + PerformGasToBurn *int64 `toml:"perform_gas_to_burn"` + MaxPerformGas *int64 `toml:"max_perform_gas"` + BlockRange *int64 `toml:"block_range"` + BlockInterval *int64 `toml:"block_interval"` + ForceSingleTxKey *bool `toml:"forces_single_tx_key"` + DeleteJobsOnEnd *bool `toml:"delete_jobs_on_end"` +} + +func (c *Benchmark) Validate() error { + if c.RegistryToTest == nil || *c.RegistryToTest == "" { + return errors.New("registry_to_test must be set") + } + if c.NumberOfRegistries == nil || *c.NumberOfRegistries <= 0 { + return errors.New("number_of_registries must be a positive integer") + } + if c.NumberOfUpkeeps == nil || *c.NumberOfUpkeeps <= 0 { + return errors.New("number_of_upkeeps must be a positive integer") + } + if c.UpkeepGasLimit == nil || *c.UpkeepGasLimit <= 0 { + return errors.New("upkeep_gas_limit must be a positive integer") + } + if c.CheckGasToBurn == nil || *c.CheckGasToBurn <= 0 { + return errors.New("check_gas_to_burn must be a positive integer") + } + if c.PerformGasToBurn == nil || *c.PerformGasToBurn <= 0 { + return errors.New("perform_gas_to_burn must be a positive integer") + } + if c.MaxPerformGas == nil || *c.MaxPerformGas <= 0 { + return errors.New("max_perform_gas must be a positive integer") + } + if c.BlockRange == nil || *c.BlockRange <= 0 { + return errors.New("block_range must be a positive integer") + } + if c.BlockInterval == nil || *c.BlockInterval <= 0 { + return errors.New("block_interval must be a positive integer") + } return nil } @@ -342,3 +401,19 @@ func (c *RegistrySettings) Validate() error { } return nil } + +type ResiliencyConfig struct { + ContractCallLimit *uint `toml:"contract_call_limit"` + ContractCallInterval *blockchain.StrDuration `toml:"contract_call_interval"` +} + +func (c *ResiliencyConfig) Validate() error { + if c.ContractCallLimit == nil { + return errors.New("contract_call_limit must be set") + } + if c.ContractCallInterval == nil { + return errors.New("contract_call_interval must be set") + } + + return nil +} diff --git a/integration-tests/testconfig/keeper/config.go b/integration-tests/testconfig/keeper/config.go index 60bdfd8697..81a88ef67e 100644 --- a/integration-tests/testconfig/keeper/config.go +++ b/integration-tests/testconfig/keeper/config.go @@ -1,110 +1,8 @@ package keeper -import ( - "errors" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" -) - type Config struct { - Common *Common `toml:"Common"` - Resiliency *ResiliencyConfig `toml:"Resiliency"` } func (c *Config) Validate() error { - if c.Common == nil { - return nil - } - if err := c.Common.Validate(); err != nil { - return err - } - if c.Resiliency == nil { - return nil - } - return c.Resiliency.Validate() -} - -type Common struct { - RegistryToTest *string `toml:"registry_to_test"` - NumberOfRegistries *int `toml:"number_of_registries"` - NumberOfNodes *int `toml:"number_of_nodes"` - NumberOfUpkeeps *int `toml:"number_of_upkeeps"` - UpkeepGasLimit *int64 `toml:"upkeep_gas_limit"` - CheckGasToBurn *int64 `toml:"check_gas_to_burn"` - PerformGasToBurn *int64 `toml:"perform_gas_to_burn"` - MaxPerformGas *int64 `toml:"max_perform_gas"` - BlockRange *int64 `toml:"block_range"` - BlockInterval *int64 `toml:"block_interval"` - ForceSingleTxKey *bool `toml:"forces_single_tx_key"` - DeleteJobsOnEnd *bool `toml:"delete_jobs_on_end"` - RegistryAddress *string `toml:"registry_address"` - RegistrarAddress *string `toml:"registrar_address"` - LinkTokenAddress *string `toml:"link_token_address"` - EthFeedAddress *string `toml:"eth_feed_address"` - GasFeedAddress *string `toml:"gas_feed_address"` -} - -func (c *Common) Validate() error { - if c.RegistryToTest == nil || *c.RegistryToTest == "" { - return errors.New("registry_to_test must be set") - } - if c.NumberOfRegistries == nil || *c.NumberOfRegistries <= 0 { - return errors.New("number_of_registries must be a positive integer") - } - if c.NumberOfNodes == nil || *c.NumberOfNodes <= 0 { - return errors.New("number_of_nodes must be a positive integer") - } - if c.NumberOfUpkeeps == nil || *c.NumberOfUpkeeps <= 0 { - return errors.New("number_of_upkeeps must be a positive integer") - } - if c.UpkeepGasLimit == nil || *c.UpkeepGasLimit <= 0 { - return errors.New("upkeep_gas_limit must be a positive integer") - } - if c.CheckGasToBurn == nil || *c.CheckGasToBurn <= 0 { - return errors.New("check_gas_to_burn must be a positive integer") - } - if c.PerformGasToBurn == nil || *c.PerformGasToBurn <= 0 { - return errors.New("perform_gas_to_burn must be a positive integer") - } - if c.MaxPerformGas == nil || *c.MaxPerformGas <= 0 { - return errors.New("max_perform_gas must be a positive integer") - } - if c.BlockRange == nil || *c.BlockRange <= 0 { - return errors.New("block_range must be a positive integer") - } - if c.BlockInterval == nil || *c.BlockInterval <= 0 { - return errors.New("block_interval must be a positive integer") - } - if c.RegistryAddress == nil { - c.RegistryAddress = new(string) - } - if c.RegistrarAddress == nil { - c.RegistrarAddress = new(string) - } - if c.LinkTokenAddress == nil { - c.LinkTokenAddress = new(string) - } - if c.EthFeedAddress == nil { - c.EthFeedAddress = new(string) - } - if c.GasFeedAddress == nil { - c.GasFeedAddress = new(string) - } - return nil -} - -type ResiliencyConfig struct { - ContractCallLimit *uint `toml:"contract_call_limit"` - ContractCallInterval *blockchain.StrDuration `toml:"contract_call_interval"` -} - -func (c *ResiliencyConfig) Validate() error { - if c.ContractCallLimit == nil { - return errors.New("contract_call_limit must be set") - } - if c.ContractCallInterval == nil { - return errors.New("contract_call_interval must be set") - } - return nil } diff --git a/integration-tests/testconfig/keeper/keeper.toml b/integration-tests/testconfig/keeper/keeper.toml index 39eae1ea53..b4f544165a 100644 --- a/integration-tests/testconfig/keeper/keeper.toml +++ b/integration-tests/testconfig/keeper/keeper.toml @@ -33,130 +33,3 @@ HTTPSPort = 0 [Keeper] TurnLookBack = 0 """ - -[Keeper.Common] -registry_to_test = "2_1" -number_of_registries = 1 -number_of_nodes = 6 -number_of_upkeeps = 500 -upkeep_gas_limit = 1500000 -check_gas_to_burn = 100000 -perform_gas_to_burn = 50000 -max_perform_gas = 5000000 -block_range = 100 -block_interval = 20 -forces_single_tx_key = false -delete_jobs_on_end = true - -# will retry roughly for 1h before giving up (900 * 4s) -[Keeper.Resiliency] -# number of retries before giving up -contract_call_limit = 900 -# static interval between retries -contract_call_interval = "4s" - -[Seth] -# keeper benchmark running on simulated network requires 100k per node -root_key_funds_buffer = 1_000_000 - -[Benchmark.Keeper.Common] -registry_to_test = "2_1" -number_of_registries = 1 -number_of_nodes = 6 -number_of_upkeeps = 1000 -upkeep_gas_limit = 1500000 -check_gas_to_burn = 10000 -perform_gas_to_burn = 1000 -max_perform_gas = 5000000 -block_range = 3600 -block_interval = 60 -forces_single_tx_key = false -delete_jobs_on_end = true - -[Benchmark.NodeConfig] -BaseConfigTOML = """ -[Feature] -LogPoller = true - -[OCR2] -Enabled = true - -[P2P] -[P2P.V2] -Enabled = true -AnnounceAddresses = ["0.0.0.0:6690"] -ListenAddresses = ["0.0.0.0:6690"] -[Keeper] -TurnLookBack = 0 -[WebServer] -HTTPWriteTimeout = '1h' -""" - -CommonChainConfigTOML = """ -""" - -[Benchmark.NodeConfig.ChainConfigTOMLByChainID] -# applicable for simulated chain -1337 = """ -FinalityDepth = 50 -LogPollInterval = '1s' -MinIncomingConfirmations = 1 - -[HeadTracker] -HistoryDepth = 100 - -[GasEstimator] -Mode = 'FixedPrice' -LimitDefault = 5_000_000 -""" - -[Soak.Keeper.Common] -registry_to_test = "2_1" -number_of_registries = 1 -number_of_nodes = 6 -number_of_upkeeps = 50 -upkeep_gas_limit = 1500000 -check_gas_to_burn = 10000 -perform_gas_to_burn = 1000 -max_perform_gas = 5000000 -block_range = 28800 -block_interval = 300 -forces_single_tx_key = false -delete_jobs_on_end = true - -[Soak.NodeConfig] -BaseConfigTOML = """ -[Feature] -LogPoller = true - -[OCR2] -Enabled = true - -[P2P] -[P2P.V2] -Enabled = true -AnnounceAddresses = ["0.0.0.0:6690"] -ListenAddresses = ["0.0.0.0:6690"] -[Keeper] -TurnLookBack = 0 -[WebServer] -HTTPWriteTimeout = '1h' -""" - -CommonChainConfigTOML = """ -""" - -[Soak.NodeConfig.ChainConfigTOMLByChainID] -# applicable for simulated chain -1337 = """ -FinalityDepth = 50 -LogPollInterval = '1s' -MinIncomingConfirmations = 1 - -[HeadTracker] -HistoryDepth = 100 - -[GasEstimator] -Mode = 'FixedPrice' -LimitDefault = 5_000_000 -""" diff --git a/integration-tests/testsetups/keeper_benchmark.go b/integration-tests/testsetups/keeper_benchmark.go index 63a5938b17..a109d02789 100644 --- a/integration-tests/testsetups/keeper_benchmark.go +++ b/integration-tests/testsetups/keeper_benchmark.go @@ -12,6 +12,11 @@ import ( "testing" "time" + ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + + ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" + "github.com/smartcontractkit/chainlink/integration-tests/actions/automationv2" + geth "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -37,7 +42,7 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" - keepertestconfig "github.com/smartcontractkit/chainlink/integration-tests/testconfig/keeper" + autotestconfig "github.com/smartcontractkit/chainlink/integration-tests/testconfig/automation" "github.com/smartcontractkit/chainlink/integration-tests/testreporters" tt "github.com/smartcontractkit/chainlink/integration-tests/types" ) @@ -52,6 +57,7 @@ type KeeperBenchmarkTest struct { log zerolog.Logger startingBlock *big.Int + automationTests []automationv2.AutomationTest keeperRegistries []contracts.KeeperRegistry keeperRegistrars []contracts.KeeperRegistrar keeperConsumerContracts []contracts.AutomationConsumerBenchmark @@ -61,13 +67,9 @@ type KeeperBenchmarkTest struct { namespace string chainlinkNodes []*client.ChainlinkK8sClient chainClient *seth.Client - testConfig tt.KeeperBenchmarkTestConfig + testConfig tt.AutomationBenchmarkTestConfig - linkToken contracts.LinkToken - linkethFeed contracts.MockLINKETHFeed - gasFeed contracts.MockGasFeed - ethusdFeed contracts.MockETHUSDFeed - wrappedNative contracts.WETHToken + linkToken contracts.LinkToken } // UpkeepConfig dictates details of how the test's upkeep contracts should be called and configured @@ -81,22 +83,11 @@ type UpkeepConfig struct { FirstEligibleBuffer int64 // How many blocks to add to randomised first eligible block, set to 0 to disable randomised first eligible block } -// PreDeployedContracts are contracts that are already deployed on a (usually) live testnet chain, so re-deployment -// in unnecessary -type PreDeployedContracts struct { - RegistryAddress string - RegistrarAddress string - LinkTokenAddress string - EthFeedAddress string - GasFeedAddress string -} - // KeeperBenchmarkTestInputs are all the required inputs for a Keeper Benchmark Test type KeeperBenchmarkTestInputs struct { BlockchainClient *seth.Client // Client for the test to connect to the blockchain with KeeperRegistrySettings *contracts.KeeperRegistrySettings // Settings of each keeper contract Upkeeps *UpkeepConfig - Contracts *PreDeployedContracts Timeout time.Duration // Timeout for the test ChainlinkNodeFunding *big.Float // Amount of ETH to fund each chainlink node with UpkeepSLA int64 // SLA in number of blocks for an upkeep to be performed once it becomes eligible @@ -117,7 +108,7 @@ func NewKeeperBenchmarkTest(t *testing.T, inputs KeeperBenchmarkTestInputs) *Kee } // Setup prepares contracts for the test -func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.KeeperBenchmarkTestConfig) { +func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.AutomationBenchmarkTestConfig) { startTime := time.Now() k.TestReporter.Summary.StartTime = startTime.UnixMilli() k.ensureInputValues() @@ -126,6 +117,7 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Keep inputs := k.Inputs k.testConfig = config + k.automationTests = make([]automationv2.AutomationTest, len(inputs.RegistryVersions)) k.keeperRegistries = make([]contracts.KeeperRegistry, len(inputs.RegistryVersions)) k.keeperRegistrars = make([]contracts.KeeperRegistrar, len(inputs.RegistryVersions)) k.keeperConsumerContracts = make([]contracts.AutomationConsumerBenchmark, len(inputs.RegistryVersions)) @@ -133,8 +125,8 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Keep k.log.Debug().Interface("TestInputs", inputs).Msg("Setting up benchmark test") // if not present disable it - if k.testConfig.GetKeeperConfig().Resiliency == nil { - k.testConfig.GetKeeperConfig().Resiliency = &keepertestconfig.ResiliencyConfig{ + if k.testConfig.GetAutomationConfig().Resiliency == nil { + k.testConfig.GetAutomationConfig().Resiliency = &autotestconfig.ResiliencyConfig{ ContractCallLimit: ptr.Ptr(uint(0)), ContractCallInterval: ptr.Ptr(blockchain.StrDuration{Duration: 0 * time.Second}), } @@ -155,40 +147,50 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Keep } } - c := inputs.Contracts - - if common.IsHexAddress(c.LinkTokenAddress) { - _, err = contracts.LoadLinkTokenContract(k.log, k.chainClient, common.HexToAddress(c.LinkTokenAddress)) - require.NoError(k.t, err, "Loading Link Token Contract shouldn't fail") - } else { - k.linkToken, err = contracts.DeployLinkTokenContract(k.log, k.chainClient) - require.NoError(k.t, err, "Deploying mock Link Token Contract feed shouldn't fail") - } - - if common.IsHexAddress(c.EthFeedAddress) { - _, err = contracts.LoadMockLINKETHFeed(k.chainClient, common.HexToAddress(c.EthFeedAddress)) - require.NoError(k.t, err, "Loading ETH-Link feed Contract shouldn't fail") - } else { - k.linkethFeed, err = contracts.DeployMockLINKETHFeed(k.chainClient, big.NewInt(2e18)) - require.NoError(k.t, err, "Deploying mock ETH-Link feed shouldn't fail") - } - - if common.IsHexAddress(c.GasFeedAddress) { - k.gasFeed, err = contracts.LoadMockGASFeed(k.chainClient, common.HexToAddress(c.GasFeedAddress)) - require.NoError(k.t, err, "Loading Gas feed Contract shouldn't fail") - } else { - k.gasFeed, err = contracts.DeployMockGASFeed(k.chainClient, big.NewInt(2e11)) - require.NoError(k.t, err, "Deploying mock gas feed shouldn't fail") - } - - k.ethusdFeed, err = contracts.DeployMockETHUSDFeed(k.chainClient, big.NewInt(200000000000)) - require.NoError(k.t, err, "Deploying mock ETH-USD feed shouldn't fail") - k.wrappedNative, err = contracts.DeployWETHTokenContract(k.log, k.chainClient) - require.NoError(k.t, err, "Deploying WETH Token Contract shouldn't fail") + conf := config.GetAutomationConfig().AutomationConfig for index := range inputs.RegistryVersions { k.log.Info().Int("Index", index).Msg("Starting Test Setup") - k.DeployBenchmarkKeeperContracts(index) + a := automationv2.NewAutomationTestK8s(k.log, k.chainClient, k.chainlinkNodes) + a.RegistrySettings = *k.Inputs.KeeperRegistrySettings + a.RegistrySettings.RegistryVersion = inputs.RegistryVersions[index] + a.RegistrarSettings = contracts.KeeperRegistrarSettings{ + AutoApproveConfigType: uint8(2), + AutoApproveMaxAllowed: math.MaxUint16, + MinLinkJuels: big.NewInt(0), + } + a.PluginConfig = ocr2keepers30config.OffchainConfig{ + TargetProbability: *conf.PluginConfig.TargetProbability, + TargetInRounds: *conf.PluginConfig.TargetInRounds, + PerformLockoutWindow: *conf.PluginConfig.PerformLockoutWindow, + GasLimitPerReport: *conf.PluginConfig.GasLimitPerReport, + GasOverheadPerUpkeep: *conf.PluginConfig.GasOverheadPerUpkeep, + MinConfirmations: *conf.PluginConfig.MinConfirmations, + MaxUpkeepBatchSize: *conf.PluginConfig.MaxUpkeepBatchSize, + LogProviderConfig: ocr2keepers30config.LogProviderConfig{ + BlockRate: *conf.PluginConfig.LogProviderConfig.BlockRate, + LogLimit: *conf.PluginConfig.LogProviderConfig.LogLimit, + }, + } + a.PublicConfig = ocr3.PublicConfig{ + DeltaProgress: *conf.PublicConfig.DeltaProgress, + DeltaResend: *conf.PublicConfig.DeltaResend, + DeltaInitial: *conf.PublicConfig.DeltaInitial, + DeltaRound: *conf.PublicConfig.DeltaRound, + DeltaGrace: *conf.PublicConfig.DeltaGrace, + DeltaCertifiedCommitRequest: *conf.PublicConfig.DeltaCertifiedCommitRequest, + DeltaStage: *conf.PublicConfig.DeltaStage, + RMax: *conf.PublicConfig.RMax, + MaxDurationQuery: *conf.PublicConfig.MaxDurationQuery, + MaxDurationObservation: *conf.PublicConfig.MaxDurationObservation, + MaxDurationShouldAcceptAttestedReport: *conf.PublicConfig.MaxDurationShouldAcceptAttestedReport, + MaxDurationShouldTransmitAcceptedReport: *conf.PublicConfig.MaxDurationShouldTransmitAcceptedReport, + F: *conf.PublicConfig.F, + } + a.SetupAutomationDeploymentWithoutJobs(k.t) + err = a.SetConfigOnRegistry() + require.NoError(k.t, err, "Setting initial config on registry shouldn't fail") + k.DeployBenchmarkKeeperContracts(index, a) } var keysToFund = inputs.RegistryVersions @@ -240,34 +242,14 @@ func (k *KeeperBenchmarkTest) Run() { k.startingBlock = big.NewInt(0).SetUint64(startingBlock) startTime := time.Now() - nodesWithoutBootstrap := k.chainlinkNodes[1:] - for rIndex := range k.keeperRegistries { var txKeyId = rIndex if inputs.ForceSingleTxnKey { txKeyId = 0 } - kr := k.keeperRegistries[rIndex] - ocrConfig, err := actions.BuildAutoOCR2ConfigVarsWithKeyIndex( - k.t, nodesWithoutBootstrap, *inputs.KeeperRegistrySettings, kr.Address(), k.Inputs.DeltaStage, txKeyId, common.Address{}, kr.ChainModuleAddress(), kr.ReorgProtectionEnabled(), k.linkToken, k.wrappedNative, k.ethusdFeed, - ) - require.NoError(k.t, err, "Building OCR config shouldn't fail") - - rv := inputs.RegistryVersions[rIndex] - // Send keeper jobs to registry and chainlink nodes - if rv >= ethereum.RegistryVersion_2_0 { - actions.CreateOCRKeeperJobs(k.t, k.chainlinkNodes, kr.Address(), k.chainClient.ChainID, txKeyId, rv) - if rv == ethereum.RegistryVersion_2_0 { - err = kr.SetConfig(*inputs.KeeperRegistrySettings, ocrConfig) - } else { - err = kr.SetConfigTypeSafe(ocrConfig) - } - require.NoError(k.t, err, "Registry config should be be set successfully") - // Give time for OCR nodes to bootstrap - time.Sleep(1 * time.Minute) - } else { - actions.CreateKeeperJobsWithKeyIndex(k.t, k.chainlinkNodes, kr, txKeyId, ocrConfig, fmt.Sprint(k.chainClient.ChainID)) - } + k.automationTests[rIndex].SetTransmitterKeyIndex(txKeyId) + k.automationTests[rIndex].AddJobsAndSetConfig(k.t) + } k.log.Info().Msgf("Waiting for %d blocks for all upkeeps to be performed", inputs.Upkeeps.BlockRange+inputs.UpkeepSLA) @@ -665,7 +647,7 @@ func (k *KeeperBenchmarkTest) ensureInputValues() { } } -func (k *KeeperBenchmarkTest) SendSlackNotification(slackClient *slack.Client, config tt.KeeperBenchmarkTestConfig) error { +func (k *KeeperBenchmarkTest) SendSlackNotification(slackClient *slack.Client, config tt.AutomationBenchmarkTestConfig) error { if slackClient == nil { slackClient = slack.New(reportModel.SlackAPIKey) } @@ -700,62 +682,14 @@ func (k *KeeperBenchmarkTest) SendSlackNotification(slackClient *slack.Client, c } // DeployBenchmarkKeeperContracts deploys a set amount of keeper Benchmark contracts registered to a single registry -func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int) { +func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int, a *automationv2.AutomationTest) { registryVersion := k.Inputs.RegistryVersions[index] k.Inputs.KeeperRegistrySettings.RegistryVersion = registryVersion upkeep := k.Inputs.Upkeeps var ( - registry contracts.KeeperRegistry - registrar contracts.KeeperRegistrar - err error + err error ) - // Contract deployment is different for legacy keepers and OCR automation - if registryVersion <= ethereum.RegistryVersion_1_3 { // Legacy keeper - v1.X - registry, err = contracts.DeployKeeperRegistry(k.chainClient, &contracts.KeeperRegistryOpts{ - RegistryVersion: registryVersion, - LinkAddr: k.linkToken.Address(), - ETHFeedAddr: k.linkethFeed.Address(), - GasFeedAddr: k.gasFeed.Address(), - TranscoderAddr: actions.ZeroAddress.Hex(), - RegistrarAddr: actions.ZeroAddress.Hex(), - Settings: *k.Inputs.KeeperRegistrySettings, - }) - require.NoError(k.t, err, "Deploying registry contract shouldn't fail") - - // Fund the registry with 1 LINK * amount of AutomationConsumerBenchmark contracts - err := k.linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(k.Inputs.Upkeeps.NumberOfUpkeeps)))) - require.NoError(k.t, err, "Funding keeper registry contract shouldn't fail") - - registrarSettings := contracts.KeeperRegistrarSettings{ - AutoApproveConfigType: 2, - AutoApproveMaxAllowed: math.MaxUint16, - RegistryAddr: registry.Address(), - MinLinkJuels: big.NewInt(0), - } - - registrar, err = contracts.DeployKeeperRegistrar(k.chainClient, registryVersion, k.linkToken.Address(), registrarSettings) - require.NoError(k.t, err, "Funding keeper registrar contract shouldn't fail") - } else { // OCR automation - v2.X - registry, registrar = actions.DeployAutoOCRRegistryAndRegistrar( - k.t, k.chainClient, registryVersion, *k.Inputs.KeeperRegistrySettings, k.linkToken, k.wrappedNative, k.ethusdFeed, - ) - - // Fund the registry with LINK - err := k.linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(k.Inputs.Upkeeps.NumberOfUpkeeps)))) - require.NoError(k.t, err, "Funding keeper registry contract shouldn't fail") - ocrConfig, err := actions.BuildAutoOCR2ConfigVars(k.t, k.chainlinkNodes[1:], *k.Inputs.KeeperRegistrySettings, registrar.Address(), k.Inputs.DeltaStage, registry.ChainModuleAddress(), registry.ReorgProtectionEnabled(), k.linkToken, k.wrappedNative, k.ethusdFeed) - require.NoError(k.t, err, "Building OCR config shouldn't fail") - k.log.Debug().Interface("KeeperRegistrySettings", *k.Inputs.KeeperRegistrySettings).Interface("OCRConfig", ocrConfig).Msg("Config") - require.NoError(k.t, err, "Error building OCR config vars") - if registryVersion == ethereum.RegistryVersion_2_0 { - err = registry.SetConfig(*k.Inputs.KeeperRegistrySettings, ocrConfig) - } else { - err = registry.SetConfigTypeSafe(ocrConfig) - } - require.NoError(k.t, err, "Registry config should be be set successfully") - } - consumer := k.DeployKeeperConsumersBenchmark() var upkeepAddresses []string @@ -805,14 +739,16 @@ func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int) { big.NewInt(0)) linkFunds = big.NewInt(0).Add(linkFunds, minLinkBalance) + k.linkToken = a.LinkToken err = actions.DeployMultiCallAndFundDeploymentAddresses(k.chainClient, k.linkToken, upkeep.NumberOfUpkeeps, linkFunds) require.NoError(k.t, err, "Sending link funds to deployment addresses shouldn't fail") - upkeepIds := actions.RegisterUpkeepContractsWithCheckData(k.t, k.chainClient, k.linkToken, linkFunds, uint32(upkeep.UpkeepGasLimit), registry, registrar, upkeep.NumberOfUpkeeps, upkeepAddresses, checkData, false, false, false, nil) + upkeepIds := actions.RegisterUpkeepContractsWithCheckData(k.t, k.chainClient, k.linkToken, linkFunds, uint32(upkeep.UpkeepGasLimit), a.Registry, a.Registrar, upkeep.NumberOfUpkeeps, upkeepAddresses, checkData, false, false, false, nil) - k.keeperRegistries[index] = registry - k.keeperRegistrars[index] = registrar + k.automationTests[index] = *a + k.keeperRegistries[index] = a.Registry + k.keeperRegistrars[index] = a.Registrar k.upkeepIDs[index] = upkeepIds k.keeperConsumerContracts[index] = consumer } @@ -821,9 +757,9 @@ func (k *KeeperBenchmarkTest) DeployKeeperConsumersBenchmark() contracts.Automat // Deploy consumer var err error var keeperConsumerInstance contracts.AutomationConsumerBenchmark - if *k.testConfig.GetKeeperConfig().Resiliency.ContractCallLimit != 0 && k.testConfig.GetKeeperConfig().Resiliency.ContractCallInterval.Duration != 0 { - maxRetryAttempts := *k.testConfig.GetKeeperConfig().Resiliency.ContractCallLimit - callRetryDelay := k.testConfig.GetKeeperConfig().Resiliency.ContractCallInterval.Duration + if *k.testConfig.GetAutomationConfig().Resiliency.ContractCallLimit != 0 && k.testConfig.GetAutomationConfig().Resiliency.ContractCallInterval.Duration != 0 { + maxRetryAttempts := *k.testConfig.GetAutomationConfig().Resiliency.ContractCallLimit + callRetryDelay := k.testConfig.GetAutomationConfig().Resiliency.ContractCallInterval.Duration keeperConsumerInstance, err = contracts.DeployKeeperConsumerBenchmarkWithRetry(k.chainClient, k.log, maxRetryAttempts, callRetryDelay) if err != nil { k.log.Error().Err(err).Msg("Deploying AutomationConsumerBenchmark instance shouldn't fail") diff --git a/integration-tests/types/testconfigs.go b/integration-tests/types/testconfigs.go index e0b1f7cc03..7a72e9a1df 100644 --- a/integration-tests/types/testconfigs.go +++ b/integration-tests/types/testconfigs.go @@ -32,10 +32,10 @@ type AutomationTestConfig interface { tc.AutomationTestConfig } -type KeeperBenchmarkTestConfig interface { +type AutomationBenchmarkTestConfig interface { ctf_config.GlobalTestConfig tc.CommonTestConfig - tc.KeeperTestConfig + tc.AutomationTestConfig ctf_config.NamedConfigurations testreporters.GrafanaURLProvider } From aa04bfab8950f001b92635388b2fb63ab1bbcec9 Mon Sep 17 00:00:00 2001 From: dimitris Date: Wed, 18 Sep 2024 13:46:42 +0300 Subject: [PATCH 367/432] Upgrade chainlink ccip dependency (#14474) * upgrade chainlink ccip * changeset --- .changeset/silly-boxes-sneeze.md | 5 +++++ core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 9 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 .changeset/silly-boxes-sneeze.md diff --git a/.changeset/silly-boxes-sneeze.md b/.changeset/silly-boxes-sneeze.md new file mode 100644 index 0000000000..c6236b57f9 --- /dev/null +++ b/.changeset/silly-boxes-sneeze.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +bump chainlink-ccip #updated diff --git a/core/scripts/go.mod b/core/scripts/go.mod index d79e372db4..59e032565f 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -271,7 +271,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 9c85a9ea4d..8cd12f5e42 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1081,8 +1081,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 h1:cbHlV2CSphQ+ghDye21M8ym0aAO/Y649H2Mg60M2AuE= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 h1:xPEM9XbfZmv8N3NjZ7AX5salonll/LdXrbb8JCbA4FE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf h1:1AlTUkT5D8HmvU9bwDoIN54/EFyOnRBl7gnXZVrYXEA= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf/go.mod h1:l8NTByXUdGGJX+vyKYI6yX1/HIpM14F8Wm9BkU3Q4Qo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/go.mod b/go.mod index 405a6b4668..f5b4216e29 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 diff --git a/go.sum b/go.sum index 9854253863..4c05468ad6 100644 --- a/go.sum +++ b/go.sum @@ -1042,8 +1042,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 h1:cbHlV2CSphQ+ghDye21M8ym0aAO/Y649H2Mg60M2AuE= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 h1:xPEM9XbfZmv8N3NjZ7AX5salonll/LdXrbb8JCbA4FE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf h1:1AlTUkT5D8HmvU9bwDoIN54/EFyOnRBl7gnXZVrYXEA= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf/go.mod h1:l8NTByXUdGGJX+vyKYI6yX1/HIpM14F8Wm9BkU3Q4Qo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index f7922b245d..714c415086 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -38,7 +38,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240910151738-3f318badcfb5 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 673a1e94e1..2494576bc4 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1423,8 +1423,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 h1:cbHlV2CSphQ+ghDye21M8ym0aAO/Y649H2Mg60M2AuE= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 h1:xPEM9XbfZmv8N3NjZ7AX5salonll/LdXrbb8JCbA4FE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf h1:1AlTUkT5D8HmvU9bwDoIN54/EFyOnRBl7gnXZVrYXEA= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf/go.mod h1:l8NTByXUdGGJX+vyKYI6yX1/HIpM14F8Wm9BkU3Q4Qo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 3f99fa1e4a..1daa663cdc 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -384,7 +384,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 5a51e7c497..ee64962cb1 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1397,8 +1397,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6 h1:cbHlV2CSphQ+ghDye21M8ym0aAO/Y649H2Mg60M2AuE= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240916150615-85b8aa5fa7e6/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 h1:xPEM9XbfZmv8N3NjZ7AX5salonll/LdXrbb8JCbA4FE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf h1:1AlTUkT5D8HmvU9bwDoIN54/EFyOnRBl7gnXZVrYXEA= github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf/go.mod h1:l8NTByXUdGGJX+vyKYI6yX1/HIpM14F8Wm9BkU3Q4Qo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= From dc998f1bb4f55a616c42d307290658ddbb87672a Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:03:46 +0200 Subject: [PATCH 368/432] Fix E2E_TESTS_ON_GITHUB_CI.md (#14473) --- .github/E2E_TESTS_ON_GITHUB_CI.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/E2E_TESTS_ON_GITHUB_CI.md b/.github/E2E_TESTS_ON_GITHUB_CI.md index f3a279338d..572e0070a0 100644 --- a/.github/E2E_TESTS_ON_GITHUB_CI.md +++ b/.github/E2E_TESTS_ON_GITHUB_CI.md @@ -49,9 +49,9 @@ To learn more about test configs see [CTF Test Config](https://github.com/smartc ## Test Secrets -For security reasons, test secrets and sensitive information are not stored directly within the test config TOML files. Instead, these secrets are securely injected into tests using environment variables. For a detailed explanation on managing test secrets, refer to our [Test Secrets documentation](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md#test-secrets). +For security reasons, test secrets and sensitive information are not stored directly within the test config TOML files. Instead, these secrets are securely injected into tests using environment variables. For a detailed explanation on managing test secrets, refer to our [Test Secrets documentation](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/lib/config/README.md#test-secrets). -If you need to run a GitHub workflow using custom secrets, please refer to the [guide on running GitHub workflows with your test secrets](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md#run-github-workflow-with-your-test-secrets). +If you need to run a GitHub workflow using custom secrets, please refer to the [guide on running GitHub workflows with your test secrets](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/lib/config/README.md#run-github-workflow-with-your-test-secrets). ## About the Reusable Workflow From a9a4f746bf3e18d2bf9228d591166c437d5a9e6a Mon Sep 17 00:00:00 2001 From: Chunkai Yang Date: Wed, 18 Sep 2024 10:07:05 -0400 Subject: [PATCH 369/432] Mantle use vanilla l1 oracle (#14471) * make Mantle use vanilla OP gas price oracle * changeset * bring back l1 oracle * update mock * [BCI-4072] changeset update --------- Co-authored-by: valerii.kabisov Co-authored-by: Valerii Kabisov <172247313+valerii-kabisov-cll@users.noreply.github.com> --- .changeset/curly-onions-tell.md | 5 ++ .../evm/gas/rollups/arbitrum_l1_oracle.go | 4 + core/chains/evm/gas/rollups/l1_oracle.go | 1 + core/chains/evm/gas/rollups/l1_oracle_abi.go | 1 - .../chains/evm/gas/rollups/mocks/l1_oracle.go | 48 ++++++++++ core/chains/evm/gas/rollups/op_l1_oracle.go | 86 +----------------- .../evm/gas/rollups/op_l1_oracle_test.go | 88 ------------------- .../evm/gas/rollups/zkSync_l1_oracle.go | 4 + 8 files changed, 66 insertions(+), 171 deletions(-) create mode 100644 .changeset/curly-onions-tell.md diff --git a/.changeset/curly-onions-tell.md b/.changeset/curly-onions-tell.md new file mode 100644 index 0000000000..249f616c01 --- /dev/null +++ b/.changeset/curly-onions-tell.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#changed Make Mantle use default OP stack l1 gas oracle in core diff --git a/core/chains/evm/gas/rollups/arbitrum_l1_oracle.go b/core/chains/evm/gas/rollups/arbitrum_l1_oracle.go index c01244db70..d758dc711e 100644 --- a/core/chains/evm/gas/rollups/arbitrum_l1_oracle.go +++ b/core/chains/evm/gas/rollups/arbitrum_l1_oracle.go @@ -112,6 +112,10 @@ func (o *arbitrumL1Oracle) Name() string { return o.logger.Name() } +func (o *arbitrumL1Oracle) ChainType(_ context.Context) chaintype.ChainType { + return o.chainType +} + func (o *arbitrumL1Oracle) Start(ctx context.Context) error { return o.StartOnce(o.Name(), func() error { go o.run() diff --git a/core/chains/evm/gas/rollups/l1_oracle.go b/core/chains/evm/gas/rollups/l1_oracle.go index e1249fdb7e..4195175598 100644 --- a/core/chains/evm/gas/rollups/l1_oracle.go +++ b/core/chains/evm/gas/rollups/l1_oracle.go @@ -26,6 +26,7 @@ type L1Oracle interface { GasPrice(ctx context.Context) (*assets.Wei, error) GetGasCost(ctx context.Context, tx *types.Transaction, blockNum *big.Int) (*assets.Wei, error) + ChainType(ctx context.Context) chaintype.ChainType } type l1OracleClient interface { diff --git a/core/chains/evm/gas/rollups/l1_oracle_abi.go b/core/chains/evm/gas/rollups/l1_oracle_abi.go index 848957ce53..fa5d9c8539 100644 --- a/core/chains/evm/gas/rollups/l1_oracle_abi.go +++ b/core/chains/evm/gas/rollups/l1_oracle_abi.go @@ -19,4 +19,3 @@ const OPBaseFeeScalarAbiString = `[{"inputs":[],"name":"baseFeeScalar","outputs" const OPBlobBaseFeeAbiString = `[{"inputs":[],"name":"blobBaseFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]` const OPBlobBaseFeeScalarAbiString = `[{"inputs":[],"name":"blobBaseFeeScalar","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"}]` const OPDecimalsAbiString = `[{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}]` -const MantleTokenRatioAbiString = `[{"inputs":[],"name":"tokenRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]` diff --git a/core/chains/evm/gas/rollups/mocks/l1_oracle.go b/core/chains/evm/gas/rollups/mocks/l1_oracle.go index e82cb4ee90..25bb3a2db5 100644 --- a/core/chains/evm/gas/rollups/mocks/l1_oracle.go +++ b/core/chains/evm/gas/rollups/mocks/l1_oracle.go @@ -7,6 +7,8 @@ import ( assets "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + chaintype "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype" + context "context" mock "github.com/stretchr/testify/mock" @@ -27,6 +29,52 @@ func (_m *L1Oracle) EXPECT() *L1Oracle_Expecter { return &L1Oracle_Expecter{mock: &_m.Mock} } +// ChainType provides a mock function with given fields: ctx +func (_m *L1Oracle) ChainType(ctx context.Context) chaintype.ChainType { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ChainType") + } + + var r0 chaintype.ChainType + if rf, ok := ret.Get(0).(func(context.Context) chaintype.ChainType); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(chaintype.ChainType) + } + + return r0 +} + +// L1Oracle_ChainType_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ChainType' +type L1Oracle_ChainType_Call struct { + *mock.Call +} + +// ChainType is a helper method to define mock.On call +// - ctx context.Context +func (_e *L1Oracle_Expecter) ChainType(ctx interface{}) *L1Oracle_ChainType_Call { + return &L1Oracle_ChainType_Call{Call: _e.mock.On("ChainType", ctx)} +} + +func (_c *L1Oracle_ChainType_Call) Run(run func(ctx context.Context)) *L1Oracle_ChainType_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *L1Oracle_ChainType_Call) Return(_a0 chaintype.ChainType) *L1Oracle_ChainType_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *L1Oracle_ChainType_Call) RunAndReturn(run func(context.Context) chaintype.ChainType) *L1Oracle_ChainType_Call { + _c.Call.Return(run) + return _c +} + // Close provides a mock function with given fields: func (_m *L1Oracle) Close() error { ret := _m.Called() diff --git a/core/chains/evm/gas/rollups/op_l1_oracle.go b/core/chains/evm/gas/rollups/op_l1_oracle.go index 1b93f8fc3f..11babc5ca5 100644 --- a/core/chains/evm/gas/rollups/op_l1_oracle.go +++ b/core/chains/evm/gas/rollups/op_l1_oracle.go @@ -88,10 +88,6 @@ const ( // decimals is a hex encoded call to: // `function decimals() public pure returns (uint256);` decimalsMethod = "decimals" - // tokenRatio fetches the tokenRatio used for Mantle's gas price calculation - // tokenRatio is a hex encoded call to: - // `function tokenRatio() public pure returns (uint256);` - tokenRatioMethod = "tokenRatio" // OPGasOracleAddress is the address of the precompiled contract that exists on Optimism, Base and Mantle. OPGasOracleAddress = "0x420000000000000000000000000000000000000F" // KromaGasOracleAddress is the address of the precompiled contract that exists on Kroma. @@ -192,16 +188,6 @@ func newOpStackL1GasOracle(lggr logger.Logger, ethClient l1OracleClient, chainTy return nil, fmt.Errorf("failed to parse GasPriceOracle %s() calldata for chain: %s; %w", decimalsMethod, chainType, err) } - // Encode calldata for tokenRatio method - tokenRatioMethodAbi, err := abi.JSON(strings.NewReader(MantleTokenRatioAbiString)) - if err != nil { - return nil, fmt.Errorf("failed to parse GasPriceOracle %s() method ABI for chain: %s; %w", tokenRatioMethod, chainType, err) - } - tokenRatioCalldata, err := tokenRatioMethodAbi.Pack(tokenRatioMethod) - if err != nil { - return nil, fmt.Errorf("failed to parse GasPriceOracle %s() calldata for chain: %s; %w", tokenRatioMethod, chainType, err) - } - return &optimismL1Oracle{ client: ethClient, pollPeriod: PollPeriod, @@ -223,7 +209,6 @@ func newOpStackL1GasOracle(lggr logger.Logger, ethClient l1OracleClient, chainTy blobBaseFeeCalldata: blobBaseFeeCalldata, blobBaseFeeScalarCalldata: blobBaseFeeScalarCalldata, decimalsCalldata: decimalsCalldata, - tokenRatioCalldata: tokenRatioCalldata, isEcotoneCalldata: isEcotoneCalldata, isEcotoneMethodAbi: isEcotoneMethodAbi, isFjordCalldata: isFjordCalldata, @@ -235,6 +220,10 @@ func (o *optimismL1Oracle) Name() string { return o.logger.Name() } +func (o *optimismL1Oracle) ChainType(_ context.Context) chaintype.ChainType { + return o.chainType +} + func (o *optimismL1Oracle) Start(ctx context.Context) error { return o.StartOnce(o.Name(), func() error { go o.run() @@ -362,10 +351,6 @@ func (o *optimismL1Oracle) GetGasCost(ctx context.Context, tx *gethtypes.Transac } func (o *optimismL1Oracle) GetDAGasPrice(ctx context.Context) (*big.Int, error) { - if o.chainType == chaintype.ChainMantle { - return o.getMantleGasPrice(ctx) - } - err := o.checkForUpgrade(ctx) if err != nil { return nil, err @@ -463,69 +448,6 @@ func (o *optimismL1Oracle) getV1GasPrice(ctx context.Context) (*big.Int, error) return new(big.Int).SetBytes(b), nil } -// Returns the gas price for Mantle. The formula is the same as Optimism Bedrock (getV1GasPrice), but the tokenRatio parameter is multiplied -func (o *optimismL1Oracle) getMantleGasPrice(ctx context.Context) (*big.Int, error) { - // call oracle to get l1BaseFee and tokenRatio - rpcBatchCalls := []rpc.BatchElem{ - { - Method: "eth_call", - Args: []any{ - map[string]interface{}{ - "from": common.Address{}, - "to": o.l1OracleAddress, - "data": hexutil.Bytes(o.l1BaseFeeCalldata), - }, - "latest", - }, - Result: new(string), - }, - { - Method: "eth_call", - Args: []any{ - map[string]interface{}{ - "from": common.Address{}, - "to": o.l1OracleAddress, - "data": hexutil.Bytes(o.tokenRatioCalldata), - }, - "latest", - }, - Result: new(string), - }, - } - - err := o.client.BatchCallContext(ctx, rpcBatchCalls) - if err != nil { - return nil, fmt.Errorf("fetch gas price parameters batch call failed: %w", err) - } - if rpcBatchCalls[0].Error != nil { - return nil, fmt.Errorf("%s call failed in a batch: %w", l1BaseFeeMethod, err) - } - if rpcBatchCalls[1].Error != nil { - return nil, fmt.Errorf("%s call failed in a batch: %w", tokenRatioMethod, err) - } - - // Extract values from responses - l1BaseFeeResult := *(rpcBatchCalls[0].Result.(*string)) - tokenRatioResult := *(rpcBatchCalls[1].Result.(*string)) - - // Decode the responses into bytes - l1BaseFeeBytes, err := hexutil.Decode(l1BaseFeeResult) - if err != nil { - return nil, fmt.Errorf("failed to decode %s rpc result: %w", l1BaseFeeMethod, err) - } - tokenRatioBytes, err := hexutil.Decode(tokenRatioResult) - if err != nil { - return nil, fmt.Errorf("failed to decode %s rpc result: %w", tokenRatioMethod, err) - } - - // Convert bytes to big int for calculations - l1BaseFee := new(big.Int).SetBytes(l1BaseFeeBytes) - tokenRatio := new(big.Int).SetBytes(tokenRatioBytes) - - // multiply l1BaseFee and tokenRatio and return - return new(big.Int).Mul(l1BaseFee, tokenRatio), nil -} - // Returns the scaled gas price using baseFeeScalar, l1BaseFee, blobBaseFeeScalar, and blobBaseFee fields from the oracle // Confirmed the same calculation is used to determine gas price for both Ecotone and Fjord func (o *optimismL1Oracle) getEcotoneFjordGasPrice(ctx context.Context) (*big.Int, error) { diff --git a/core/chains/evm/gas/rollups/op_l1_oracle_test.go b/core/chains/evm/gas/rollups/op_l1_oracle_test.go index 88bb96534d..f5f009f1ea 100644 --- a/core/chains/evm/gas/rollups/op_l1_oracle_test.go +++ b/core/chains/evm/gas/rollups/op_l1_oracle_test.go @@ -111,94 +111,6 @@ func TestOPL1Oracle_ReadV1GasPrice(t *testing.T) { } } -func TestOPL1Oracle_ReadMantleGasPrice(t *testing.T) { - l1BaseFee := big.NewInt(100) - tokenRatio := big.NewInt(40) - oracleAddress := common.HexToAddress("0x1234").String() - - t.Parallel() - t.Run("correctly fetches gas price if chain is Mantle", func(t *testing.T) { - // Encode calldata for l1BaseFee method - l1BaseFeeMethodAbi, err := abi.JSON(strings.NewReader(L1BaseFeeAbiString)) - require.NoError(t, err) - l1BaseFeeCalldata, err := l1BaseFeeMethodAbi.Pack(l1BaseFeeMethod) - require.NoError(t, err) - - // Encode calldata for tokenRatio method - tokenRatioMethodAbi, err := abi.JSON(strings.NewReader(MantleTokenRatioAbiString)) - require.NoError(t, err) - tokenRatioCalldata, err := tokenRatioMethodAbi.Pack(tokenRatioMethod) - require.NoError(t, err) - - ethClient := mocks.NewL1OracleClient(t) - ethClient.On("BatchCallContext", mock.Anything, mock.IsType([]rpc.BatchElem{})).Run(func(args mock.Arguments) { - rpcElements := args.Get(1).([]rpc.BatchElem) - require.Equal(t, 2, len(rpcElements)) - for _, rE := range rpcElements { - require.Equal(t, "eth_call", rE.Method) - require.Equal(t, oracleAddress, rE.Args[0].(map[string]interface{})["to"]) - require.Equal(t, "latest", rE.Args[1]) - } - require.Equal(t, hexutil.Bytes(l1BaseFeeCalldata), rpcElements[0].Args[0].(map[string]interface{})["data"]) - require.Equal(t, hexutil.Bytes(tokenRatioCalldata), rpcElements[1].Args[0].(map[string]interface{})["data"]) - - res1 := common.BigToHash(l1BaseFee).Hex() - res2 := common.BigToHash(tokenRatio).Hex() - - rpcElements[0].Result = &res1 - rpcElements[1].Result = &res2 - }).Return(nil).Once() - - oracle, err := newOpStackL1GasOracle(logger.Test(t), ethClient, chaintype.ChainMantle, oracleAddress) - require.NoError(t, err) - - gasPrice, err := oracle.GetDAGasPrice(tests.Context(t)) - require.NoError(t, err) - - assert.Equal(t, new(big.Int).Mul(l1BaseFee, tokenRatio), gasPrice) - }) - - t.Run("fetching Mantle price but rpc returns bad data", func(t *testing.T) { - ethClient := mocks.NewL1OracleClient(t) - ethClient.On("BatchCallContext", mock.Anything, mock.IsType([]rpc.BatchElem{})).Run(func(args mock.Arguments) { - rpcElements := args.Get(1).([]rpc.BatchElem) - var badData = "zzz" - rpcElements[0].Result = &badData - rpcElements[1].Result = &badData - }).Return(nil).Once() - - oracle, err := newOpStackL1GasOracle(logger.Test(t), ethClient, chaintype.ChainMantle, oracleAddress) - require.NoError(t, err) - _, err = oracle.GetDAGasPrice(tests.Context(t)) - assert.Error(t, err) - }) - - t.Run("fetching Mantle price but rpc parent call errors", func(t *testing.T) { - ethClient := mocks.NewL1OracleClient(t) - ethClient.On("BatchCallContext", mock.Anything, mock.IsType([]rpc.BatchElem{})).Return(fmt.Errorf("revert")).Once() - - oracle, err := newOpStackL1GasOracle(logger.Test(t), ethClient, chaintype.ChainMantle, oracleAddress) - require.NoError(t, err) - _, err = oracle.GetDAGasPrice(tests.Context(t)) - assert.Error(t, err) - }) - - t.Run("fetching Mantle price but one of the sub rpc call errors", func(t *testing.T) { - ethClient := mocks.NewL1OracleClient(t) - ethClient.On("BatchCallContext", mock.Anything, mock.IsType([]rpc.BatchElem{})).Run(func(args mock.Arguments) { - rpcElements := args.Get(1).([]rpc.BatchElem) - res := common.BigToHash(l1BaseFee).Hex() - rpcElements[0].Result = &res - rpcElements[1].Error = fmt.Errorf("revert") - }).Return(nil).Once() - - oracle, err := newOpStackL1GasOracle(logger.Test(t), ethClient, chaintype.ChainMantle, oracleAddress) - require.NoError(t, err) - _, err = oracle.GetDAGasPrice(tests.Context(t)) - assert.Error(t, err) - }) -} - func setupUpgradeCheck(t *testing.T, oracleAddress string, isFjord, isEcotone bool) *mocks.L1OracleClient { trueHex := "0x0000000000000000000000000000000000000000000000000000000000000001" falseHex := "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/core/chains/evm/gas/rollups/zkSync_l1_oracle.go b/core/chains/evm/gas/rollups/zkSync_l1_oracle.go index 31d93bc587..c294123354 100644 --- a/core/chains/evm/gas/rollups/zkSync_l1_oracle.go +++ b/core/chains/evm/gas/rollups/zkSync_l1_oracle.go @@ -83,6 +83,10 @@ func (o *zkSyncL1Oracle) Name() string { return o.logger.Name() } +func (o *zkSyncL1Oracle) ChainType(_ context.Context) chaintype.ChainType { + return o.chainType +} + func (o *zkSyncL1Oracle) Start(ctx context.Context) error { return o.StartOnce(o.Name(), func() error { go o.run() From 767aed2d26819128972f96a1812966538353de36 Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Wed, 18 Sep 2024 18:26:08 +0400 Subject: [PATCH 370/432] [DEVSVCS-545] cleanup (#14478) * leftover cleanup * add back sleep time * config cleanup * fix load lint --- .../actions/automation_ocr_helpers.go | 277 ------------------ .../actions/automation_ocr_helpers_local.go | 39 ++- .../benchmark/automation_test.go | 22 +- .../chaos/automation_chaos_test.go | 49 +--- .../contracts/ethereum_keeper_contracts.go | 2 +- .../automationv2_1/automationv2_1_test.go | 55 +--- integration-tests/load/go.mod | 8 +- .../reorg/automation_reorg_test.go | 36 +-- integration-tests/smoke/automation_test.go | 55 +--- .../testconfig/automation/automation.toml | 18 +- .../testconfig/automation/config.go | 8 +- .../testsetups/keeper_benchmark.go | 39 +-- 12 files changed, 95 insertions(+), 513 deletions(-) diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index df9168e25d..f184580467 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -2,297 +2,20 @@ package actions //revive:disable:dot-imports import ( - "encoding/json" - "fmt" "math" "math/big" "testing" - "time" "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3" - - "github.com/ethereum/go-ethereum/common" - "github.com/lib/pq" "github.com/stretchr/testify/require" - "gopkg.in/guregu/null.v4" - - ocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - - ocr2keepers20config "github.com/smartcontractkit/chainlink-automation/pkg/v2/config" - ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" - "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" - "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" - "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" - "github.com/smartcontractkit/chainlink/v2/core/store/models" ) -func BuildAutoOCR2ConfigVars( - t *testing.T, - chainlinkNodes []*client.ChainlinkK8sClient, - registryConfig contracts.KeeperRegistrySettings, - registrar string, - deltaStage time.Duration, - chainModuleAddress common.Address, - reorgProtectionEnabled bool, - linkToken contracts.LinkToken, - wethToken contracts.WETHToken, - ethUSDFeed contracts.MockETHUSDFeed, - -) (contracts.OCRv2Config, error) { - return BuildAutoOCR2ConfigVarsWithKeyIndex(t, chainlinkNodes, registryConfig, registrar, deltaStage, 0, common.Address{}, chainModuleAddress, reorgProtectionEnabled, linkToken, wethToken, ethUSDFeed) -} - -func BuildAutoOCR2ConfigVarsWithKeyIndex( - t *testing.T, - chainlinkNodes []*client.ChainlinkK8sClient, - registryConfig contracts.KeeperRegistrySettings, - registrar string, - deltaStage time.Duration, - keyIndex int, - registryOwnerAddress common.Address, - chainModuleAddress common.Address, - reorgProtectionEnabled bool, - linkToken contracts.LinkToken, - wethToken contracts.WETHToken, - ethUSDFeed contracts.MockETHUSDFeed, -) (contracts.OCRv2Config, error) { - l := logging.GetTestLogger(t) - S, oracleIdentities, err := GetOracleIdentitiesWithKeyIndex(chainlinkNodes, keyIndex) - if err != nil { - return contracts.OCRv2Config{}, err - } - - var offC []byte - var signerOnchainPublicKeys []types.OnchainPublicKey - var transmitterAccounts []types.Account - var f uint8 - var offchainConfigVersion uint64 - var offchainConfig []byte - - if registryConfig.RegistryVersion == ethereum.RegistryVersion_2_1 || registryConfig.RegistryVersion == ethereum.RegistryVersion_2_2 || registryConfig.RegistryVersion == ethereum.RegistryVersion_2_3 { - offC, err = json.Marshal(ocr2keepers30config.OffchainConfig{ - TargetProbability: "0.999", - TargetInRounds: 1, - PerformLockoutWindow: 3600000, // Intentionally set to be higher than in prod for testing purpose - GasLimitPerReport: 5_300_000, - GasOverheadPerUpkeep: 300_000, - MinConfirmations: 0, - MaxUpkeepBatchSize: 10, - }) - if err != nil { - return contracts.OCRv2Config{}, err - } - - signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = ocr3.ContractSetConfigArgsForTests( - 10*time.Second, // deltaProgress time.Duration, - 15*time.Second, // deltaResend time.Duration, - 500*time.Millisecond, // deltaInitial time.Duration, - 1000*time.Millisecond, // deltaRound time.Duration, - 200*time.Millisecond, // deltaGrace time.Duration, - 300*time.Millisecond, // deltaCertifiedCommitRequest time.Duration - deltaStage, // deltaStage time.Duration, - 24, // rMax uint64, - S, // s []int, - oracleIdentities, // oracles []OracleIdentityExtra, - offC, // reportingPluginConfig []byte, - 20*time.Millisecond, // maxDurationQuery time.Duration, - 20*time.Millisecond, // maxDurationObservation time.Duration, // good to here - 1200*time.Millisecond, // maxDurationShouldAcceptAttestedReport time.Duration, - 20*time.Millisecond, // maxDurationShouldTransmitAcceptedReport time.Duration, - 1, // f int, - nil, // onchainConfig []byte, - ) - if err != nil { - return contracts.OCRv2Config{}, err - } - } else { - offC, err = json.Marshal(ocr2keepers20config.OffchainConfig{ - TargetProbability: "0.999", - TargetInRounds: 1, - PerformLockoutWindow: 3600000, // Intentionally set to be higher than in prod for testing purpose - GasLimitPerReport: 5_300_000, - GasOverheadPerUpkeep: 300_000, - SamplingJobDuration: 3000, - MinConfirmations: 0, - MaxUpkeepBatchSize: 1, - }) - if err != nil { - return contracts.OCRv2Config{}, err - } - - signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = ocr2.ContractSetConfigArgsForTests( - 10*time.Second, // deltaProgress time.Duration, - 15*time.Second, // deltaResend time.Duration, - 3000*time.Millisecond, // deltaRound time.Duration, - 200*time.Millisecond, // deltaGrace time.Duration, - deltaStage, // deltaStage time.Duration, - 24, // rMax uint8, - S, // s []int, - oracleIdentities, // oracles []OracleIdentityExtra, - offC, // reportingPluginConfig []byte, - 20*time.Millisecond, // maxDurationQuery time.Duration, - 20*time.Millisecond, // maxDurationObservation time.Duration, - 1200*time.Millisecond, // maxDurationReport time.Duration, - 20*time.Millisecond, // maxDurationShouldAcceptFinalizedReport time.Duration, - 20*time.Millisecond, // maxDurationShouldTransmitAcceptedReport time.Duration, - 1, // f int, - nil, // onchainConfig []byte, - ) - if err != nil { - return contracts.OCRv2Config{}, err - } - } - - var signers []common.Address - for _, signer := range signerOnchainPublicKeys { - require.Equal(t, 20, len(signer), "OnChainPublicKey '%v' has wrong length for address", signer) - signers = append(signers, common.BytesToAddress(signer)) - } - - var transmitters []common.Address - for _, transmitter := range transmitterAccounts { - require.True(t, common.IsHexAddress(string(transmitter)), "TransmitAccount '%s' is not a valid Ethereum address", string(transmitter)) - transmitters = append(transmitters, common.HexToAddress(string(transmitter))) - } - - ocrConfig := contracts.OCRv2Config{ - Signers: signers, - Transmitters: transmitters, - F: f, - OffchainConfigVersion: offchainConfigVersion, - OffchainConfig: offchainConfig, - } - - if registryConfig.RegistryVersion == ethereum.RegistryVersion_2_0 { - ocrConfig.OnchainConfig = registryConfig.Encode20OnchainConfig(registrar) - } else if registryConfig.RegistryVersion == ethereum.RegistryVersion_2_1 { - ocrConfig.TypedOnchainConfig21 = registryConfig.Create21OnchainConfig(registrar, registryOwnerAddress) - } else if registryConfig.RegistryVersion == ethereum.RegistryVersion_2_2 { - ocrConfig.TypedOnchainConfig22 = registryConfig.Create22OnchainConfig(registrar, registryOwnerAddress, chainModuleAddress, reorgProtectionEnabled) - } else if registryConfig.RegistryVersion == ethereum.RegistryVersion_2_3 { - ocrConfig.TypedOnchainConfig23 = registryConfig.Create23OnchainConfig(registrar, registryOwnerAddress, chainModuleAddress, reorgProtectionEnabled) - ocrConfig.BillingTokens = []common.Address{ - common.HexToAddress(linkToken.Address()), - common.HexToAddress(wethToken.Address()), - } - - ocrConfig.BillingConfigs = []i_automation_registry_master_wrapper_2_3.AutomationRegistryBase23BillingConfig{ - { - GasFeePPB: 100, - FlatFeeMilliCents: big.NewInt(500), - PriceFeed: common.HexToAddress(ethUSDFeed.Address()), // ETH/USD feed and LINK/USD feed are the same - Decimals: 18, - FallbackPrice: big.NewInt(1000), - MinSpend: big.NewInt(200), - }, - { - GasFeePPB: 100, - FlatFeeMilliCents: big.NewInt(500), - PriceFeed: common.HexToAddress(ethUSDFeed.Address()), // ETH/USD feed and LINK/USD feed are the same - Decimals: 18, - FallbackPrice: big.NewInt(1000), - MinSpend: big.NewInt(200), - }, - } - } - - l.Info().Msg("Done building OCR config") - return ocrConfig, nil -} - -// CreateOCRKeeperJobs bootstraps the first node and to the other nodes sends ocr jobs -func CreateOCRKeeperJobs( - t *testing.T, - chainlinkNodes []*client.ChainlinkK8sClient, - registryAddr string, - chainID int64, - keyIndex int, - registryVersion ethereum.KeeperRegistryVersion, -) { - l := logging.GetTestLogger(t) - bootstrapNode := chainlinkNodes[0] - bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys() - require.NoError(t, err, "Shouldn't fail reading P2P keys from bootstrap node") - bootstrapP2PId := bootstrapP2PIds.Data[0].Attributes.PeerID - - var contractVersion string - if registryVersion == ethereum.RegistryVersion_2_2 || registryVersion == ethereum.RegistryVersion_2_3 { - contractVersion = "v2.1+" - } else if registryVersion == ethereum.RegistryVersion_2_1 { - contractVersion = "v2.1" - } else if registryVersion == ethereum.RegistryVersion_2_0 { - contractVersion = "v2.0" - } else { - require.FailNow(t, fmt.Sprintf("v2.0, v2.1, v2.2 and v2.3 are the only supported versions, but got something else: %v (iota)", registryVersion)) - } - - bootstrapSpec := &client.OCR2TaskJobSpec{ - Name: "ocr2 bootstrap node " + registryAddr, - JobType: "bootstrap", - OCR2OracleSpec: job.OCR2OracleSpec{ - ContractID: registryAddr, - Relay: "evm", - RelayConfig: map[string]interface{}{ - "chainID": int(chainID), - }, - ContractConfigTrackerPollInterval: *models.NewInterval(time.Second * 15), - }, - } - _, err = bootstrapNode.MustCreateJob(bootstrapSpec) - require.NoError(t, err, "Shouldn't fail creating bootstrap job on bootstrap node") - // TODO: Use service name returned by chainlink-env once that is available - P2Pv2Bootstrapper := fmt.Sprintf("%s@%s-node-1:%d", bootstrapP2PId, bootstrapNode.Name(), 6690) - - for nodeIndex := 1; nodeIndex < len(chainlinkNodes); nodeIndex++ { - nodeTransmitterAddress, err := chainlinkNodes[nodeIndex].EthAddresses() - require.NoError(t, err, "Shouldn't fail getting primary ETH address from OCR node %d", nodeIndex+1) - nodeOCRKeys, err := chainlinkNodes[nodeIndex].MustReadOCR2Keys() - require.NoError(t, err, "Shouldn't fail getting OCR keys from OCR node %d", nodeIndex+1) - var nodeOCRKeyId []string - for _, key := range nodeOCRKeys.Data { - if key.Attributes.ChainType == string(chaintype.EVM) { - nodeOCRKeyId = append(nodeOCRKeyId, key.ID) - break - } - } - - autoOCR2JobSpec := client.OCR2TaskJobSpec{ - Name: "ocr2 " + registryAddr, - JobType: "offchainreporting2", - OCR2OracleSpec: job.OCR2OracleSpec{ - PluginType: "ocr2automation", - Relay: "evm", - RelayConfig: map[string]interface{}{ - "chainID": int(chainID), - }, - PluginConfig: map[string]interface{}{ - "mercuryCredentialName": "\"cred1\"", - "contractVersion": "\"" + contractVersion + "\"", - }, - ContractConfigTrackerPollInterval: *models.NewInterval(time.Second * 15), - ContractID: registryAddr, // registryAddr - OCRKeyBundleID: null.StringFrom(nodeOCRKeyId[0]), // get node ocr2config.ID - TransmitterID: null.StringFrom(nodeTransmitterAddress[keyIndex]), // node addr - P2PV2Bootstrappers: pq.StringArray{P2Pv2Bootstrapper}, // bootstrap node key and address @bootstrap:8000 - }, - } - - _, err = chainlinkNodes[nodeIndex].MustCreateJob(&autoOCR2JobSpec) - require.NoError(t, err, "Shouldn't fail creating OCR Task job on OCR node %d err: %+v", nodeIndex+1, err) - } - l.Info().Msg("Done creating OCR automation jobs") -} - // DeployAutoOCRRegistryAndRegistrar registry and registrar func DeployAutoOCRRegistryAndRegistrar( t *testing.T, diff --git a/integration-tests/actions/automation_ocr_helpers_local.go b/integration-tests/actions/automation_ocr_helpers_local.go index d513f1875a..e4d5ad70ca 100644 --- a/integration-tests/actions/automation_ocr_helpers_local.go +++ b/integration-tests/actions/automation_ocr_helpers_local.go @@ -28,7 +28,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/store/models" ) -func AutomationDefaultRegistryConfig(c tc.AutomationTestConfig) contracts.KeeperRegistrySettings { +func ReadRegistryConfig(c tc.AutomationTestConfig) contracts.KeeperRegistrySettings { registrySettings := c.GetAutomationConfig().AutomationConfig.RegistrySettings return contracts.KeeperRegistrySettings{ PaymentPremiumPPB: *registrySettings.PaymentPremiumPPB, @@ -40,12 +40,49 @@ func AutomationDefaultRegistryConfig(c tc.AutomationTestConfig) contracts.Keeper MaxPerformGas: *registrySettings.MaxPerformGas, FallbackGasPrice: registrySettings.FallbackGasPrice, FallbackLinkPrice: registrySettings.FallbackLinkPrice, + FallbackNativePrice: registrySettings.FallbackNativePrice, MaxCheckDataSize: *registrySettings.MaxCheckDataSize, MaxPerformDataSize: *registrySettings.MaxPerformDataSize, MaxRevertDataSize: *registrySettings.MaxRevertDataSize, } } +func ReadPluginConfig(c tc.AutomationTestConfig) ocr2keepers30config.OffchainConfig { + plCfg := c.GetAutomationConfig().AutomationConfig.PluginConfig + return ocr2keepers30config.OffchainConfig{ + TargetProbability: *plCfg.TargetProbability, + TargetInRounds: *plCfg.TargetInRounds, + PerformLockoutWindow: *plCfg.PerformLockoutWindow, + GasLimitPerReport: *plCfg.GasLimitPerReport, + GasOverheadPerUpkeep: *plCfg.GasOverheadPerUpkeep, + MinConfirmations: *plCfg.MinConfirmations, + MaxUpkeepBatchSize: *plCfg.MaxUpkeepBatchSize, + LogProviderConfig: ocr2keepers30config.LogProviderConfig{ + BlockRate: *plCfg.LogProviderConfig.BlockRate, + LogLimit: *plCfg.LogProviderConfig.LogLimit, + }, + } +} + +func ReadPublicConfig(c tc.AutomationTestConfig) ocr3.PublicConfig { + pubCfg := c.GetAutomationConfig().AutomationConfig.PublicConfig + return ocr3.PublicConfig{ + DeltaProgress: *pubCfg.DeltaProgress, + DeltaResend: *pubCfg.DeltaResend, + DeltaInitial: *pubCfg.DeltaInitial, + DeltaRound: *pubCfg.DeltaRound, + DeltaGrace: *pubCfg.DeltaGrace, + DeltaCertifiedCommitRequest: *pubCfg.DeltaCertifiedCommitRequest, + DeltaStage: *pubCfg.DeltaStage, + RMax: *pubCfg.RMax, + MaxDurationQuery: *pubCfg.MaxDurationQuery, + MaxDurationObservation: *pubCfg.MaxDurationObservation, + MaxDurationShouldAcceptAttestedReport: *pubCfg.MaxDurationShouldAcceptAttestedReport, + MaxDurationShouldTransmitAcceptedReport: *pubCfg.MaxDurationShouldTransmitAcceptedReport, + F: *pubCfg.F, + } +} + func BuildAutoOCR2ConfigVarsLocal( l zerolog.Logger, chainlinkNodes []*client.ChainlinkClient, diff --git a/integration-tests/benchmark/automation_test.go b/integration-tests/benchmark/automation_test.go index f7e98e6a7a..534fca2f51 100644 --- a/integration-tests/benchmark/automation_test.go +++ b/integration-tests/benchmark/automation_test.go @@ -21,7 +21,6 @@ import ( sethutils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" "github.com/smartcontractkit/chainlink/integration-tests/actions" - "github.com/smartcontractkit/chainlink/integration-tests/contracts" ethcontracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" @@ -94,25 +93,12 @@ func TestAutomationBenchmark(t *testing.T) { require.NoError(t, err, "Error getting Seth client") registryVersions := addRegistry(&config) + registrySettings := actions.ReadRegistryConfig(config) keeperBenchmarkTest := testsetups.NewKeeperBenchmarkTest(t, testsetups.KeeperBenchmarkTestInputs{ - BlockchainClient: chainClient, - RegistryVersions: registryVersions, - KeeperRegistrySettings: &contracts.KeeperRegistrySettings{ - PaymentPremiumPPB: uint32(0), - FlatFeeMicroLINK: uint32(40000), - BlockCountPerTurn: big.NewInt(100), - CheckGasLimit: uint32(45_000_000), //45M - StalenessSeconds: big.NewInt(90_000), - GasCeilingMultiplier: uint16(2), - MaxPerformGas: uint32(*config.Automation.Benchmark.MaxPerformGas), - MinUpkeepSpend: big.NewInt(0), - FallbackGasPrice: big.NewInt(2e11), - FallbackLinkPrice: big.NewInt(2e18), - MaxCheckDataSize: uint32(5_000), - MaxPerformDataSize: uint32(5_000), - MaxRevertDataSize: uint32(5_000), - }, + BlockchainClient: chainClient, + RegistryVersions: registryVersions, + KeeperRegistrySettings: ®istrySettings, Upkeeps: &testsetups.UpkeepConfig{ NumberOfUpkeeps: *config.Automation.Benchmark.NumberOfUpkeeps, CheckGasToBurn: *config.Automation.Benchmark.CheckGasToBurn, diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go index 59b52f8e0f..cde5962390 100644 --- a/integration-tests/chaos/automation_chaos_test.go +++ b/integration-tests/chaos/automation_chaos_test.go @@ -6,9 +6,6 @@ import ( "testing" "time" - ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - - ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" "github.com/smartcontractkit/chainlink/integration-tests/actions/automationv2" seth_utils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" @@ -245,53 +242,15 @@ func TestAutomationChaos(t *testing.T) { a := automationv2.NewAutomationTestK8s(l, chainClient, chainlinkNodes) a.SetMercuryCredentialName("cred1") - conf := config.Automation.AutomationConfig - a.RegistrySettings = contracts.KeeperRegistrySettings{ - PaymentPremiumPPB: *conf.RegistrySettings.PaymentPremiumPPB, - FlatFeeMicroLINK: *conf.RegistrySettings.FlatFeeMicroLINK, - CheckGasLimit: *conf.RegistrySettings.CheckGasLimit, - StalenessSeconds: conf.RegistrySettings.StalenessSeconds, - GasCeilingMultiplier: *conf.RegistrySettings.GasCeilingMultiplier, - MaxPerformGas: *conf.RegistrySettings.MaxPerformGas, - MinUpkeepSpend: conf.RegistrySettings.MinUpkeepSpend, - FallbackGasPrice: conf.RegistrySettings.FallbackGasPrice, - FallbackLinkPrice: conf.RegistrySettings.FallbackLinkPrice, - MaxCheckDataSize: *conf.RegistrySettings.MaxCheckDataSize, - MaxPerformDataSize: *conf.RegistrySettings.MaxPerformDataSize, - MaxRevertDataSize: *conf.RegistrySettings.MaxRevertDataSize, - RegistryVersion: rv, - } + a.RegistrySettings = actions.ReadRegistryConfig(config) + a.RegistrySettings.RegistryVersion = rv + a.PluginConfig = actions.ReadPluginConfig(config) + a.PublicConfig = actions.ReadPublicConfig(config) a.RegistrarSettings = contracts.KeeperRegistrarSettings{ AutoApproveConfigType: uint8(2), AutoApproveMaxAllowed: 1000, MinLinkJuels: big.NewInt(0), } - plCfg := config.GetAutomationConfig().AutomationConfig.PluginConfig - a.PluginConfig = ocr2keepers30config.OffchainConfig{ - TargetProbability: *plCfg.TargetProbability, - TargetInRounds: *plCfg.TargetInRounds, - PerformLockoutWindow: *plCfg.PerformLockoutWindow, - GasLimitPerReport: *plCfg.GasLimitPerReport, - GasOverheadPerUpkeep: *plCfg.GasOverheadPerUpkeep, - MinConfirmations: *plCfg.MinConfirmations, - MaxUpkeepBatchSize: *plCfg.MaxUpkeepBatchSize, - } - pubCfg := config.GetAutomationConfig().AutomationConfig.PublicConfig - a.PublicConfig = ocr3.PublicConfig{ - DeltaProgress: *pubCfg.DeltaProgress, - DeltaResend: *pubCfg.DeltaResend, - DeltaInitial: *pubCfg.DeltaInitial, - DeltaRound: *pubCfg.DeltaRound, - DeltaGrace: *pubCfg.DeltaGrace, - DeltaCertifiedCommitRequest: *pubCfg.DeltaCertifiedCommitRequest, - DeltaStage: *pubCfg.DeltaStage, - RMax: *pubCfg.RMax, - MaxDurationQuery: *pubCfg.MaxDurationQuery, - MaxDurationObservation: *pubCfg.MaxDurationObservation, - MaxDurationShouldAcceptAttestedReport: *pubCfg.MaxDurationShouldAcceptAttestedReport, - MaxDurationShouldTransmitAcceptedReport: *pubCfg.MaxDurationShouldTransmitAcceptedReport, - F: *pubCfg.F, - } a.SetupAutomationDeployment(t) diff --git a/integration-tests/contracts/ethereum_keeper_contracts.go b/integration-tests/contracts/ethereum_keeper_contracts.go index 38aa5c58f0..90f1af0319 100644 --- a/integration-tests/contracts/ethereum_keeper_contracts.go +++ b/integration-tests/contracts/ethereum_keeper_contracts.go @@ -174,7 +174,7 @@ func (rcs *KeeperRegistrySettings) Create23OnchainConfig(registrar string, regis ChainModule: chainModuleAddress, ReorgProtectionEnabled: reorgProtectionEnabled, FinanceAdmin: registryOwnerAddress, - FallbackNativePrice: rcs.FallbackLinkPrice, // Just use the LINK price + FallbackNativePrice: rcs.FallbackNativePrice, } } diff --git a/integration-tests/load/automationv2_1/automationv2_1_test.go b/integration-tests/load/automationv2_1/automationv2_1_test.go index cb2606f00b..6c49d1be44 100644 --- a/integration-tests/load/automationv2_1/automationv2_1_test.go +++ b/integration-tests/load/automationv2_1/automationv2_1_test.go @@ -22,12 +22,8 @@ import ( "github.com/slack-go/slack" "github.com/stretchr/testify/require" - ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - "github.com/smartcontractkit/chainlink-testing-framework/wasp" - ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" - "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" @@ -154,6 +150,7 @@ func setUpDataStreamsWireMock(url string) error { func TestLogTrigger(t *testing.T) { ctx := tests.Context(t) l := logging.GetTestLogger(t) + registryVersion := contractseth.RegistryVersion_2_1 loadedTestConfig, err := tc.GetConfig([]string{"Load"}, tc.Automation) if err != nil { @@ -315,55 +312,15 @@ Load Config: require.NoError(t, err, "Error deploying multicall contract") a := automationv2.NewAutomationTestK8s(l, chainClient, chainlinkNodes) - conf := loadedTestConfig.Automation.AutomationConfig - a.RegistrySettings = contracts.KeeperRegistrySettings{ - PaymentPremiumPPB: *conf.RegistrySettings.PaymentPremiumPPB, - FlatFeeMicroLINK: *conf.RegistrySettings.FlatFeeMicroLINK, - CheckGasLimit: *conf.RegistrySettings.CheckGasLimit, - StalenessSeconds: conf.RegistrySettings.StalenessSeconds, - GasCeilingMultiplier: *conf.RegistrySettings.GasCeilingMultiplier, - MaxPerformGas: *conf.RegistrySettings.MaxPerformGas, - MinUpkeepSpend: conf.RegistrySettings.MinUpkeepSpend, - FallbackGasPrice: conf.RegistrySettings.FallbackGasPrice, - FallbackLinkPrice: conf.RegistrySettings.FallbackLinkPrice, - MaxCheckDataSize: *conf.RegistrySettings.MaxCheckDataSize, - MaxPerformDataSize: *conf.RegistrySettings.MaxPerformDataSize, - MaxRevertDataSize: *conf.RegistrySettings.MaxRevertDataSize, - RegistryVersion: contractseth.RegistryVersion_2_1, - } + a.RegistrySettings = actions.ReadRegistryConfig(loadedTestConfig) + a.RegistrySettings.RegistryVersion = registryVersion + a.PluginConfig = actions.ReadPluginConfig(loadedTestConfig) + a.PublicConfig = actions.ReadPublicConfig(loadedTestConfig) a.RegistrarSettings = contracts.KeeperRegistrarSettings{ AutoApproveConfigType: uint8(2), - AutoApproveMaxAllowed: math.MaxUint16, + AutoApproveMaxAllowed: 1000, MinLinkJuels: big.NewInt(0), } - a.PluginConfig = ocr2keepers30config.OffchainConfig{ - TargetProbability: *conf.PluginConfig.TargetProbability, - TargetInRounds: *conf.PluginConfig.TargetInRounds, - PerformLockoutWindow: *conf.PluginConfig.PerformLockoutWindow, - GasLimitPerReport: *conf.PluginConfig.GasLimitPerReport, - GasOverheadPerUpkeep: *conf.PluginConfig.GasOverheadPerUpkeep, - MinConfirmations: *conf.PluginConfig.MinConfirmations, - MaxUpkeepBatchSize: *conf.PluginConfig.MaxUpkeepBatchSize, - LogProviderConfig: ocr2keepers30config.LogProviderConfig{ - BlockRate: *conf.PluginConfig.LogProviderConfig.BlockRate, - LogLimit: *conf.PluginConfig.LogProviderConfig.LogLimit, - }, - } - a.PublicConfig = ocr3.PublicConfig{ - DeltaProgress: *conf.PublicConfig.DeltaProgress, - DeltaResend: *conf.PublicConfig.DeltaResend, - DeltaInitial: *conf.PublicConfig.DeltaInitial, - DeltaRound: *conf.PublicConfig.DeltaRound, - DeltaGrace: *conf.PublicConfig.DeltaGrace, - DeltaCertifiedCommitRequest: *conf.PublicConfig.DeltaCertifiedCommitRequest, - DeltaStage: *conf.PublicConfig.DeltaStage, - RMax: *conf.PublicConfig.RMax, - MaxDurationQuery: *conf.PublicConfig.MaxDurationQuery, - MaxDurationObservation: *conf.PublicConfig.MaxDurationObservation, - MaxDurationShouldAcceptAttestedReport: *conf.PublicConfig.MaxDurationShouldAcceptAttestedReport, - MaxDurationShouldTransmitAcceptedReport: *conf.PublicConfig.MaxDurationShouldTransmitAcceptedReport, - F: *conf.PublicConfig.F, - } if *loadedTestConfig.Automation.DataStreams.Enabled { a.SetMercuryCredentialName("cred1") diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 1daa663cdc..673191e145 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -15,21 +15,23 @@ require ( github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 - github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 - github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 github.com/stretchr/testify v1.9.0 github.com/wiremock/go-wiremock v1.9.0 go.uber.org/ratelimit v0.3.0 ) -require github.com/AlekSi/pointer v1.1.0 // indirect +require ( + github.com/AlekSi/pointer v1.1.0 // indirect + github.com/smartcontractkit/chainlink-automation v1.0.4 // indirect + github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 // indirect +) require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index 15b3b74582..85ca4b4264 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -10,10 +10,8 @@ import ( "strings" "testing" - ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" "go.uber.org/zap/zapcore" - ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" sethUtils "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/seth" "github.com/smartcontractkit/chainlink/integration-tests/actions/automationv2" @@ -134,43 +132,17 @@ func TestAutomationReorg(t *testing.T) { gethRPCClient := ctfClient.NewRPCClient(evmNetwork.HTTPURLs[0], nil) - registryConfig := actions.AutomationDefaultRegistryConfig(config) - registryConfig.RegistryVersion = registryVersion - a := automationv2.NewAutomationTestDocker(l, sethClient, nodeClients) a.SetMercuryCredentialName("cred1") - a.RegistrySettings = registryConfig + a.RegistrySettings = actions.ReadRegistryConfig(config) + a.RegistrySettings.RegistryVersion = registryVersion + a.PluginConfig = actions.ReadPluginConfig(config) + a.PublicConfig = actions.ReadPublicConfig(config) a.RegistrarSettings = contracts.KeeperRegistrarSettings{ AutoApproveConfigType: uint8(2), AutoApproveMaxAllowed: 1000, MinLinkJuels: big.NewInt(0), } - plCfg := config.GetAutomationConfig().AutomationConfig.PluginConfig - a.PluginConfig = ocr2keepers30config.OffchainConfig{ - TargetProbability: *plCfg.TargetProbability, - TargetInRounds: *plCfg.TargetInRounds, - PerformLockoutWindow: *plCfg.PerformLockoutWindow, - GasLimitPerReport: *plCfg.GasLimitPerReport, - GasOverheadPerUpkeep: *plCfg.GasOverheadPerUpkeep, - MinConfirmations: *plCfg.MinConfirmations, - MaxUpkeepBatchSize: *plCfg.MaxUpkeepBatchSize, - } - pubCfg := config.GetAutomationConfig().AutomationConfig.PublicConfig - a.PublicConfig = ocr3.PublicConfig{ - DeltaProgress: *pubCfg.DeltaProgress, - DeltaResend: *pubCfg.DeltaResend, - DeltaInitial: *pubCfg.DeltaInitial, - DeltaRound: *pubCfg.DeltaRound, - DeltaGrace: *pubCfg.DeltaGrace, - DeltaCertifiedCommitRequest: *pubCfg.DeltaCertifiedCommitRequest, - DeltaStage: *pubCfg.DeltaStage, - RMax: *pubCfg.RMax, - MaxDurationQuery: *pubCfg.MaxDurationQuery, - MaxDurationObservation: *pubCfg.MaxDurationObservation, - MaxDurationShouldAcceptAttestedReport: *pubCfg.MaxDurationShouldAcceptAttestedReport, - MaxDurationShouldTransmitAcceptedReport: *pubCfg.MaxDurationShouldTransmitAcceptedReport, - F: *pubCfg.F, - } a.SetupAutomationDeployment(t) a.SetDockerEnv(env) diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 7844435760..f5a329a1a2 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -20,9 +20,6 @@ import ( "github.com/onsi/gomega" "github.com/stretchr/testify/require" - ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - - ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" ctfTestEnv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" @@ -126,7 +123,7 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { isMercury := isMercuryV02 || isMercuryV03 a := setupAutomationTestDocker( - t, registryVersion, actions.AutomationDefaultRegistryConfig(cfg), isMercuryV02, isMercuryV03, &cfg, + t, registryVersion, actions.ReadRegistryConfig(cfg), isMercuryV02, isMercuryV03, &cfg, ) sb, err := a.ChainClient.Client.BlockNumber(context.Background()) @@ -265,7 +262,7 @@ func TestSetUpkeepTriggerConfig(t *testing.T) { require.NoError(t, err, "Failed to get config") a := setupAutomationTestDocker( - t, registryVersion, actions.AutomationDefaultRegistryConfig(config), false, false, &config, + t, registryVersion, actions.ReadRegistryConfig(config), false, false, &config, ) sb, err := a.ChainClient.Client.BlockNumber(context.Background()) @@ -448,7 +445,7 @@ func TestAutomationAddFunds(t *testing.T) { config, err := tc.GetConfig([]string{"Smoke"}, tc.Automation) require.NoError(t, err, "Failed to get config") a := setupAutomationTestDocker( - t, registryVersion, actions.AutomationDefaultRegistryConfig(config), false, false, &config, + t, registryVersion, actions.ReadRegistryConfig(config), false, false, &config, ) sb, err := a.ChainClient.Client.BlockNumber(context.Background()) @@ -528,7 +525,7 @@ func TestAutomationPauseUnPause(t *testing.T) { require.NoError(t, err, "Failed to get config") a := setupAutomationTestDocker( - t, registryVersion, actions.AutomationDefaultRegistryConfig(config), false, false, &config, + t, registryVersion, actions.ReadRegistryConfig(config), false, false, &config, ) sb, err := a.ChainClient.Client.BlockNumber(context.Background()) @@ -629,7 +626,7 @@ func TestAutomationRegisterUpkeep(t *testing.T) { require.NoError(t, err, "Failed to get config") a := setupAutomationTestDocker( - t, registryVersion, actions.AutomationDefaultRegistryConfig(config), false, false, &config, + t, registryVersion, actions.ReadRegistryConfig(config), false, false, &config, ) sb, err := a.ChainClient.Client.BlockNumber(context.Background()) @@ -725,7 +722,7 @@ func TestAutomationPauseRegistry(t *testing.T) { require.NoError(t, err, "Failed to get config") a := setupAutomationTestDocker( - t, registryVersion, actions.AutomationDefaultRegistryConfig(config), false, false, &config, + t, registryVersion, actions.ReadRegistryConfig(config), false, false, &config, ) sb, err := a.ChainClient.Client.BlockNumber(context.Background()) @@ -805,7 +802,7 @@ func TestAutomationKeeperNodesDown(t *testing.T) { require.NoError(t, err, "Failed to get config") a := setupAutomationTestDocker( - t, registryVersion, actions.AutomationDefaultRegistryConfig(config), false, false, &config, + t, registryVersion, actions.ReadRegistryConfig(config), false, false, &config, ) sb, err := a.ChainClient.Client.BlockNumber(context.Background()) @@ -913,7 +910,7 @@ func TestAutomationPerformSimulation(t *testing.T) { require.NoError(t, err, "Failed to get config") a := setupAutomationTestDocker( - t, registryVersion, actions.AutomationDefaultRegistryConfig(config), false, false, &config, + t, registryVersion, actions.ReadRegistryConfig(config), false, false, &config, ) sb, err := a.ChainClient.Client.BlockNumber(context.Background()) @@ -984,7 +981,7 @@ func TestAutomationCheckPerformGasLimit(t *testing.T) { config, err := tc.GetConfig([]string{"Smoke"}, tc.Automation) require.NoError(t, err, "Failed to get config") a := setupAutomationTestDocker( - t, registryVersion, actions.AutomationDefaultRegistryConfig(config), false, false, &config, + t, registryVersion, actions.ReadRegistryConfig(config), false, false, &config, ) sb, err := a.ChainClient.Client.BlockNumber(context.Background()) @@ -1091,7 +1088,7 @@ func TestAutomationCheckPerformGasLimit(t *testing.T) { } // Now increase checkGasLimit on registry - highCheckGasLimit := actions.AutomationDefaultRegistryConfig(config) + highCheckGasLimit := actions.ReadRegistryConfig(config) highCheckGasLimit.CheckGasLimit = uint32(5000000) highCheckGasLimit.RegistryVersion = registryVersion @@ -1139,7 +1136,7 @@ func TestUpdateCheckData(t *testing.T) { require.NoError(t, err, "Failed to get config") a := setupAutomationTestDocker( - t, registryVersion, actions.AutomationDefaultRegistryConfig(config), false, false, &config, + t, registryVersion, actions.ReadRegistryConfig(config), false, false, &config, ) sb, err := a.ChainClient.Client.BlockNumber(context.Background()) @@ -1220,7 +1217,7 @@ func TestSetOffchainConfigWithMaxGasPrice(t *testing.T) { t.Fatal(err) } a := setupAutomationTestDocker( - t, registryVersion, actions.AutomationDefaultRegistryConfig(config), false, false, &config, + t, registryVersion, actions.ReadRegistryConfig(config), false, false, &config, ) sb, err := a.ChainClient.Client.BlockNumber(context.Background()) @@ -1446,32 +1443,8 @@ func setupAutomationTestDocker( AutoApproveMaxAllowed: 1000, MinLinkJuels: big.NewInt(0), } - plCfg := automationTestConfig.GetAutomationConfig().AutomationConfig.PluginConfig - a.PluginConfig = ocr2keepers30config.OffchainConfig{ - TargetProbability: *plCfg.TargetProbability, - TargetInRounds: *plCfg.TargetInRounds, - PerformLockoutWindow: *plCfg.PerformLockoutWindow, - GasLimitPerReport: *plCfg.GasLimitPerReport, - GasOverheadPerUpkeep: *plCfg.GasOverheadPerUpkeep, - MinConfirmations: *plCfg.MinConfirmations, - MaxUpkeepBatchSize: *plCfg.MaxUpkeepBatchSize, - } - pubCfg := automationTestConfig.GetAutomationConfig().AutomationConfig.PublicConfig - a.PublicConfig = ocr3.PublicConfig{ - DeltaProgress: *pubCfg.DeltaProgress, - DeltaResend: *pubCfg.DeltaResend, - DeltaInitial: *pubCfg.DeltaInitial, - DeltaRound: *pubCfg.DeltaRound, - DeltaGrace: *pubCfg.DeltaGrace, - DeltaCertifiedCommitRequest: *pubCfg.DeltaCertifiedCommitRequest, - DeltaStage: *pubCfg.DeltaStage, - RMax: *pubCfg.RMax, - MaxDurationQuery: *pubCfg.MaxDurationQuery, - MaxDurationObservation: *pubCfg.MaxDurationObservation, - MaxDurationShouldAcceptAttestedReport: *pubCfg.MaxDurationShouldAcceptAttestedReport, - MaxDurationShouldTransmitAcceptedReport: *pubCfg.MaxDurationShouldTransmitAcceptedReport, - F: *pubCfg.F, - } + a.PluginConfig = actions.ReadPluginConfig(automationTestConfig) + a.PublicConfig = actions.ReadPublicConfig(automationTestConfig) a.SetupAutomationDeployment(t) a.SetDockerEnv(env) diff --git a/integration-tests/testconfig/automation/automation.toml b/integration-tests/testconfig/automation/automation.toml index 5513355eae..f07136e998 100644 --- a/integration-tests/testconfig/automation/automation.toml +++ b/integration-tests/testconfig/automation/automation.toml @@ -82,6 +82,7 @@ max_perform_gas=5_000_000 min_upkeep_spend=0 fallback_gas_price=200_000_000_000 fallback_link_price=2_000_000_000_000_000_000 +fallback_native_price=2_000_000_000_000_000_000 max_check_data_size=5_000 max_perform_data_size=5_000 max_revert_data_size=5_000 @@ -148,6 +149,7 @@ max_perform_gas=5_000_000 min_upkeep_spend=0 fallback_gas_price=200_000_000_000 fallback_link_price=2_000_000_000_000_000_000 +fallback_native_price=2_000_000_000_000_000_000 max_check_data_size=5_000 max_perform_data_size=5_000 max_revert_data_size=5_000 @@ -199,6 +201,7 @@ max_perform_gas=5_000_000 min_upkeep_spend=0 fallback_gas_price=200_000_000_000 fallback_link_price=2_000_000_000_000_000_000 +fallback_native_price=2_000_000_000_000_000_000 max_check_data_size=5_000 max_perform_data_size=5_000 max_revert_data_size=5_000 @@ -289,6 +292,7 @@ max_perform_gas=5_000_000 min_upkeep_spend=0 fallback_gas_price=200_000_000_000 fallback_link_price=2_000_000_000_000_000_000 +fallback_native_price=2_000_000_000_000_000_000 max_check_data_size=5_000 max_perform_data_size=5_000 max_revert_data_size=5_000 @@ -327,7 +331,6 @@ number_of_upkeeps = 1000 upkeep_gas_limit = 1500000 check_gas_to_burn = 10000 perform_gas_to_burn = 1000 -max_perform_gas = 5000000 block_range = 3600 block_interval = 60 forces_single_tx_key = false @@ -402,15 +405,16 @@ block_rate=1 log_limit=2 [Benchmark.Automation.AutomationConfig.RegistrySettings] -payment_premium_ppb=200_000_000 -flat_fee_micro_link=0 -check_gas_limit=2_500_000 -staleness_seconds=90000 -gas_ceiling_multiplier=1 +payment_premium_ppb=0 +flat_fee_micro_link=40000 +check_gas_limit=45_000_000 +staleness_seconds=90_000 +gas_ceiling_multiplier=2 max_perform_gas=5_000_000 min_upkeep_spend=0 fallback_gas_price=200_000_000_000 fallback_link_price=2_000_000_000_000_000_000 +fallback_native_price=2_000_000_000_000_000_000 max_check_data_size=5_000 max_perform_data_size=5_000 max_revert_data_size=5_000 @@ -446,7 +450,6 @@ number_of_upkeeps = 50 upkeep_gas_limit = 1500000 check_gas_to_burn = 10000 perform_gas_to_burn = 1000 -max_perform_gas = 5000000 block_range = 28800 block_interval = 300 forces_single_tx_key = false @@ -530,6 +533,7 @@ max_perform_gas=5_000_000 min_upkeep_spend=0 fallback_gas_price=200_000_000_000 fallback_link_price=2_000_000_000_000_000_000 +fallback_native_price=2_000_000_000_000_000_000 max_check_data_size=5_000 max_perform_data_size=5_000 max_revert_data_size=5_000 diff --git a/integration-tests/testconfig/automation/config.go b/integration-tests/testconfig/automation/config.go index 96f625a0cf..2dc68ebf8f 100644 --- a/integration-tests/testconfig/automation/config.go +++ b/integration-tests/testconfig/automation/config.go @@ -61,7 +61,6 @@ type Benchmark struct { UpkeepGasLimit *int64 `toml:"upkeep_gas_limit"` CheckGasToBurn *int64 `toml:"check_gas_to_burn"` PerformGasToBurn *int64 `toml:"perform_gas_to_burn"` - MaxPerformGas *int64 `toml:"max_perform_gas"` BlockRange *int64 `toml:"block_range"` BlockInterval *int64 `toml:"block_interval"` ForceSingleTxKey *bool `toml:"forces_single_tx_key"` @@ -87,9 +86,6 @@ func (c *Benchmark) Validate() error { if c.PerformGasToBurn == nil || *c.PerformGasToBurn <= 0 { return errors.New("perform_gas_to_burn must be a positive integer") } - if c.MaxPerformGas == nil || *c.MaxPerformGas <= 0 { - return errors.New("max_perform_gas must be a positive integer") - } if c.BlockRange == nil || *c.BlockRange <= 0 { return errors.New("block_range must be a positive integer") } @@ -357,6 +353,7 @@ type RegistrySettings struct { MinUpkeepSpend *big.Int `toml:"min_upkeep_spend"` FallbackGasPrice *big.Int `toml:"fallback_gas_price"` FallbackLinkPrice *big.Int `toml:"fallback_link_price"` + FallbackNativePrice *big.Int `toml:"fallback_native_price"` MaxCheckDataSize *uint32 `toml:"max_check_data_size"` MaxPerformDataSize *uint32 `toml:"max_perform_data_size"` MaxRevertDataSize *uint32 `toml:"max_revert_data_size"` @@ -390,6 +387,9 @@ func (c *RegistrySettings) Validate() error { if c.FallbackLinkPrice == nil || c.FallbackLinkPrice.Cmp(big.NewInt(0)) < 0 { return errors.New("fallback_link_price must be set to a non-negative integer") } + if c.FallbackNativePrice == nil || c.FallbackNativePrice.Cmp(big.NewInt(0)) < 0 { + return errors.New("fallback_native_price must be set to a non-negative integer") + } if c.MaxCheckDataSize == nil || *c.MaxCheckDataSize < 1 { return errors.New("max_check_data_size must be set to a positive integer") } diff --git a/integration-tests/testsetups/keeper_benchmark.go b/integration-tests/testsetups/keeper_benchmark.go index a109d02789..40a56ba73c 100644 --- a/integration-tests/testsetups/keeper_benchmark.go +++ b/integration-tests/testsetups/keeper_benchmark.go @@ -12,9 +12,6 @@ import ( "testing" "time" - ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - - ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" "github.com/smartcontractkit/chainlink/integration-tests/actions/automationv2" geth "github.com/ethereum/go-ethereum" @@ -147,8 +144,6 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Auto } } - conf := config.GetAutomationConfig().AutomationConfig - for index := range inputs.RegistryVersions { k.log.Info().Int("Index", index).Msg("Starting Test Setup") a := automationv2.NewAutomationTestK8s(k.log, k.chainClient, k.chainlinkNodes) @@ -159,34 +154,8 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Auto AutoApproveMaxAllowed: math.MaxUint16, MinLinkJuels: big.NewInt(0), } - a.PluginConfig = ocr2keepers30config.OffchainConfig{ - TargetProbability: *conf.PluginConfig.TargetProbability, - TargetInRounds: *conf.PluginConfig.TargetInRounds, - PerformLockoutWindow: *conf.PluginConfig.PerformLockoutWindow, - GasLimitPerReport: *conf.PluginConfig.GasLimitPerReport, - GasOverheadPerUpkeep: *conf.PluginConfig.GasOverheadPerUpkeep, - MinConfirmations: *conf.PluginConfig.MinConfirmations, - MaxUpkeepBatchSize: *conf.PluginConfig.MaxUpkeepBatchSize, - LogProviderConfig: ocr2keepers30config.LogProviderConfig{ - BlockRate: *conf.PluginConfig.LogProviderConfig.BlockRate, - LogLimit: *conf.PluginConfig.LogProviderConfig.LogLimit, - }, - } - a.PublicConfig = ocr3.PublicConfig{ - DeltaProgress: *conf.PublicConfig.DeltaProgress, - DeltaResend: *conf.PublicConfig.DeltaResend, - DeltaInitial: *conf.PublicConfig.DeltaInitial, - DeltaRound: *conf.PublicConfig.DeltaRound, - DeltaGrace: *conf.PublicConfig.DeltaGrace, - DeltaCertifiedCommitRequest: *conf.PublicConfig.DeltaCertifiedCommitRequest, - DeltaStage: *conf.PublicConfig.DeltaStage, - RMax: *conf.PublicConfig.RMax, - MaxDurationQuery: *conf.PublicConfig.MaxDurationQuery, - MaxDurationObservation: *conf.PublicConfig.MaxDurationObservation, - MaxDurationShouldAcceptAttestedReport: *conf.PublicConfig.MaxDurationShouldAcceptAttestedReport, - MaxDurationShouldTransmitAcceptedReport: *conf.PublicConfig.MaxDurationShouldTransmitAcceptedReport, - F: *conf.PublicConfig.F, - } + a.PluginConfig = actions.ReadPluginConfig(config) + a.PublicConfig = actions.ReadPublicConfig(config) a.SetupAutomationDeploymentWithoutJobs(k.t) err = a.SetConfigOnRegistry() require.NoError(k.t, err, "Setting initial config on registry shouldn't fail") @@ -225,7 +194,6 @@ func (k *KeeperBenchmarkTest) Run() { float64(u.BlockInterval) k.TestReporter.Summary.TestInputs = map[string]interface{}{ "NumberOfUpkeeps": u.NumberOfUpkeeps, - "BlockCountPerTurn": k.Inputs.KeeperRegistrySettings.BlockCountPerTurn, "CheckGasLimit": k.Inputs.KeeperRegistrySettings.CheckGasLimit, "MaxPerformGas": k.Inputs.KeeperRegistrySettings.MaxPerformGas, "CheckGasToBurn": u.CheckGasToBurn, @@ -249,7 +217,8 @@ func (k *KeeperBenchmarkTest) Run() { } k.automationTests[rIndex].SetTransmitterKeyIndex(txKeyId) k.automationTests[rIndex].AddJobsAndSetConfig(k.t) - + // Give time for OCR nodes to bootstrap + time.Sleep(1 * time.Minute) } k.log.Info().Msgf("Waiting for %d blocks for all upkeeps to be performed", inputs.Upkeeps.BlockRange+inputs.UpkeepSLA) From 358fc17d5b5149d962002225cee7c44215cc77d4 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 18 Sep 2024 10:10:32 -0600 Subject: [PATCH 371/432] Merc 6304 view function ea telem support (#14467) * * Adds support for "tags" to Tasks that can be used generically. * Adds a descendent task search method * Added support in Mercury EA telemetry to utilize tags for telemetry extraction * * Adds support for "tags" to Tasks that can be used generically. * Adds a descendent task search method * Added support in Mercury EA telemetry to utilize tags for telemetry extraction * changeset * remove changeset file * linting --- .changeset/twenty-boxes-thank.md | 7 + core/services/ocrcommon/telemetry.go | 161 ++++++++--- core/services/ocrcommon/telemetry_test.go | 251 +++++++++++++++++- core/services/pipeline/common.go | 12 + core/services/pipeline/common_test.go | 74 ++++++ core/services/pipeline/runner_test.go | 44 +++ core/services/pipeline/task.base.go | 31 +++ core/services/pipeline/task.bridge_test.go | 12 + .../pipeline/task.eth_abi_decode_test.go | 14 + .../relay/evm/mercury/mocks/pipeline.go | 4 + .../synchronization/telem/telem.pb.go | 2 +- .../telem/telem_automation_custom.pb.go | 2 +- .../telem/telem_enhanced_ea.pb.go | 2 +- .../telem/telem_enhanced_ea_mercury.pb.go | 15 +- .../telem/telem_enhanced_ea_mercury.proto | 1 + .../telem/telem_functions_request.pb.go | 2 +- .../telem/telem_head_report.pb.go | 2 +- .../synchronization/telem/telem_wsrpc.pb.go | 2 +- 18 files changed, 585 insertions(+), 53 deletions(-) create mode 100644 .changeset/twenty-boxes-thank.md diff --git a/.changeset/twenty-boxes-thank.md b/.changeset/twenty-boxes-thank.md new file mode 100644 index 0000000000..b90ec1d9fd --- /dev/null +++ b/.changeset/twenty-boxes-thank.md @@ -0,0 +1,7 @@ +--- +"chainlink": patch +--- +#added +* Adds support for "tags" to Tasks that can be used generically. +* Adds a descendent task search method +* Added support in Mercury EA telemetry to utilize tags for telemetry extraction diff --git a/core/services/ocrcommon/telemetry.go b/core/services/ocrcommon/telemetry.go index 2be3e2228c..f146bacc18 100644 --- a/core/services/ocrcommon/telemetry.go +++ b/core/services/ocrcommon/telemetry.go @@ -38,6 +38,7 @@ type EATelemetry struct { BridgeTaskRunStartedTimestamp int64 BridgeTaskRunEndedTimestamp int64 AssetSymbol string + BridgeRequestData string } type EnhancedTelemetryData struct { @@ -168,8 +169,8 @@ func ParseMercuryEATelemetry(lggr logger.Logger, trrs pipeline.TaskRunResults, f if err != nil { lggr.Warnw(fmt.Sprintf("cannot parse EA telemetry, id=%s, name=%q", trr.Task.DotID(), bridgeName), "err", err, "dotID", trr.Task.DotID(), "bridgeName", bridgeName) } - - eaTelem.DpBenchmarkPrice, eaTelem.DpBid, eaTelem.DpAsk = getPricesFromResults(lggr, trr, trrs, feedVersion) + eaTelem.BridgeRequestData = bridgeTask.RequestData + eaTelem.DpBenchmarkPrice, eaTelem.DpBid, eaTelem.DpAsk = getPricesFromBridgeTask(lggr, trr, trrs, feedVersion) eaTelem.BridgeTaskRunStartedTimestamp = trr.CreatedAt.UnixMilli() eaTelem.BridgeTaskRunEndedTimestamp = trr.FinishedAt.Time.UnixMilli() @@ -448,10 +449,11 @@ func (e *EnhancedTelemetryService[T]) collectMercuryEnhancedTelemetry(d Enhanced ConfigDigest: d.RepTimestamp.ConfigDigest.Hex(), Round: int64(d.RepTimestamp.Round), Epoch: int64(d.RepTimestamp.Epoch), + BridgeRequestData: eaTelem.BridgeRequestData, AssetSymbol: eaTelem.AssetSymbol, Version: uint32(d.FeedVersion), } - + e.lggr.Debugw(fmt.Sprintf("EA Telemetry = %+v", t), "feedID", e.job.OCR2OracleSpec.FeedID.Hex(), "jobID", e.job.ID, "datasource", eaTelem.DataSource) bytes, err := proto.Marshal(t) if err != nil { e.lggr.Warnf("protobuf marshal failed %v", err.Error()) @@ -462,11 +464,25 @@ func (e *EnhancedTelemetryService[T]) collectMercuryEnhancedTelemetry(d Enhanced } } +type telemetryAttributes struct { + PriceType *string `json:"priceType"` +} + +func parseTelemetryAttributes(a string) (telemetryAttributes, error) { + attrs := &telemetryAttributes{} + err := json.Unmarshal([]byte(a), attrs) + if err != nil { + return telemetryAttributes{}, err + } + return *attrs, nil +} + // getAssetSymbolFromRequestData parses the requestData of the bridge to generate an asset symbol pair func getAssetSymbolFromRequestData(requestData string) string { type reqDataPayload struct { - To string `json:"to"` - From string `json:"from"` + To *string `json:"to"` + From *string `json:"from"` + Address *string `json:"address"` // used for view function ea only } type reqData struct { Data reqDataPayload `json:"data"` @@ -478,7 +494,15 @@ func getAssetSymbolFromRequestData(requestData string) string { return "" } - return rd.Data.From + "/" + rd.Data.To + if rd.Data.From != nil && rd.Data.To != nil { + return *rd.Data.From + "/" + *rd.Data.To + } + + if rd.Data.Address != nil { + return *rd.Data.Address + } + + return "" } // ShouldCollectEnhancedTelemetryMercury checks if enhanced telemetry should be collected and sent @@ -489,11 +513,99 @@ func ShouldCollectEnhancedTelemetryMercury(jb job.Job) bool { return false } -// getPricesFromResults parses the pipeline.TaskRunResults for pipeline.TaskTypeJSONParse and gets the benchmarkPrice, +const ( + bid = "bid" + ask = "ask" + benchmark = "benchmark" + exchangeRate = "exchangeRate" +) + +func getPricesFromBridgeTask(lggr logger.Logger, bridgeTask pipeline.TaskRunResult, allTasks pipeline.TaskRunResults, mercuryVersion mercuryutils.FeedVersion) (float64, float64, float64) { + var benchmarkPrice, bidPrice, askPrice float64 + + // This will assume that all fields we care about are tagged with the correct priceType + benchmarkPrice, bidPrice, askPrice = getPricesFromBridgeTaskByTelemetryField(lggr, bridgeTask, allTasks) + + // If prices weren't parsed by telemetry fields - attempt to get prices using the legacy method + // This is for backwards compatibility with job specs that don't have the telemetry attributes set + if benchmarkPrice == 0 && bidPrice == 0 && askPrice == 0 { + benchmarkP, bidP, askP := getPricesFromResultsByOrder(lggr, bridgeTask, allTasks, mercuryVersion) + bidPrice = bidP + askPrice = askP + benchmarkPrice = benchmarkP + } + + return benchmarkPrice, bidPrice, askPrice +} + +// CollectTaskRunResultsWithTags collects TaskRunResults for descendent tasks with non-empty TaskTags. +func collectTaskRunResultsWithTags(bridgeTask pipeline.TaskRunResult, allTasks pipeline.TaskRunResults) []pipeline.TaskRunResult { + startTask := bridgeTask.Task + descendants := startTask.GetDescendantTasks() + var taskRunResultsWithTags []pipeline.TaskRunResult + for _, task := range descendants { + trr := allTasks.GetTaskRunResultOf(task) + if trr != nil { + if trr.Task.TaskTags() != "" { + taskRunResultsWithTags = append(taskRunResultsWithTags, *trr) + } + } + } + return taskRunResultsWithTags +} + +// getPricesFromBridgeTaskByTelemetryField attempts to parse prices from via telemetry fields in the TaskTags +func getPricesFromBridgeTaskByTelemetryField(lggr logger.Logger, bridgeTask pipeline.TaskRunResult, allTasks pipeline.TaskRunResults) (float64, float64, float64) { + var benchmarkPrice, bidPrice, askPrice float64 + + // Outputs are the mapped tasks from this task. + var tasksWithTags = collectTaskRunResultsWithTags(bridgeTask, allTasks) + + for _, trr := range tasksWithTags { + attributes, err := parseTelemetryAttributes(trr.Task.TaskTags()) + if err != nil { + lggr.Warnw(fmt.Sprintf("found telemetry attributes but cannot them, taskTags=%s", trr.Task.TaskTags()), "err", err) + continue + } + + if attributes.PriceType != nil { + switch *attributes.PriceType { + case bid: + bidPrice = parsePriceFromTask(lggr, trr) + case ask: + askPrice = parsePriceFromTask(lggr, trr) + case benchmark: + benchmarkPrice = parsePriceFromTask(lggr, trr) + case exchangeRate: + price := parsePriceFromTask(lggr, trr) + benchmarkPrice, bidPrice, askPrice = price, price, price + case "": + lggr.Warnw(fmt.Sprintf("no priceType found in attributes, parsedAttributes=%+v, id %s", attributes, trr.Task.DotID())) + } + } + } + + return benchmarkPrice, bidPrice, askPrice +} + +func parsePriceFromTask(lggr logger.Logger, trr pipeline.TaskRunResult) float64 { + var val float64 + if trr.Result.Error != nil { + lggr.Warnw(fmt.Sprintf("got error on EA telemetry price task, id %s: %s", trr.Task.DotID(), trr.Result.Error), "err", trr.Result.Error) + return 0 + } + val, err := getResultFloat64(&trr) + if err != nil { + lggr.Warnw(fmt.Sprintf("cannot parse EA telemetry price to float64, DOT id %s", trr.Task.DotID()), "task_type", trr.Task.Type(), "task_tags", trr.Task.TaskTags(), "err", err) + } + return val +} + +// getPricesFromResultsByOrder parses the pipeline.TaskRunResults for pipeline.TaskTypeJSONParse and gets the benchmarkPrice, // bid and ask. This functions expects the pipeline.TaskRunResults to be correctly ordered -func getPricesFromResults(lggr logger.Logger, startTask pipeline.TaskRunResult, allTasks pipeline.TaskRunResults, mercuryVersion mercuryutils.FeedVersion) (float64, float64, float64) { +func getPricesFromResultsByOrder(lggr logger.Logger, startTask pipeline.TaskRunResult, allTasks pipeline.TaskRunResults, mercuryVersion mercuryutils.FeedVersion) (float64, float64, float64) { var benchmarkPrice, askPrice, bidPrice float64 - var err error + // We rely on task results to be sorted in the correct order benchmarkPriceTask := allTasks.GetNextTaskOf(startTask) if benchmarkPriceTask == nil { @@ -501,14 +613,7 @@ func getPricesFromResults(lggr logger.Logger, startTask pipeline.TaskRunResult, return 0, 0, 0 } if benchmarkPriceTask.Task.Type() == pipeline.TaskTypeJSONParse { - if benchmarkPriceTask.Result.Error != nil { - lggr.Warnw(fmt.Sprintf("got error for enhanced EA telemetry benchmark price, id %s: %s", benchmarkPriceTask.Task.DotID(), benchmarkPriceTask.Result.Error), "err", benchmarkPriceTask.Result.Error) - } else { - benchmarkPrice, err = getResultFloat64(benchmarkPriceTask) - if err != nil { - lggr.Warnw(fmt.Sprintf("cannot parse enhanced EA telemetry benchmark price, id %s", benchmarkPriceTask.Task.DotID()), "err", err) - } - } + benchmarkPrice = parsePriceFromTask(lggr, *benchmarkPriceTask) } // mercury version 2 only supports benchmarkPrice @@ -522,15 +627,8 @@ func getPricesFromResults(lggr logger.Logger, startTask pipeline.TaskRunResult, return benchmarkPrice, 0, 0 } - if bidTask != nil && bidTask.Task.Type() == pipeline.TaskTypeJSONParse { - if bidTask.Result.Error != nil { - lggr.Warnw(fmt.Sprintf("got error for enhanced EA telemetry bid price, id %s: %s", bidTask.Task.DotID(), bidTask.Result.Error), "err", bidTask.Result.Error) - } else { - bidPrice, err = getResultFloat64(bidTask) - if err != nil { - lggr.Warnw(fmt.Sprintf("cannot parse enhanced EA telemetry bid price, id %s", bidTask.Task.DotID()), "err", err) - } - } + if bidTask.Task.Type() == pipeline.TaskTypeJSONParse { + bidPrice = parsePriceFromTask(lggr, *bidTask) } askTask := allTasks.GetNextTaskOf(*bidTask) @@ -538,15 +636,8 @@ func getPricesFromResults(lggr logger.Logger, startTask pipeline.TaskRunResult, lggr.Warnf("cannot parse enhanced EA telemetry ask price, task is nil, id %s", benchmarkPriceTask.Task.DotID()) return benchmarkPrice, bidPrice, 0 } - if askTask != nil && askTask.Task.Type() == pipeline.TaskTypeJSONParse { - if bidTask.Result.Error != nil { - lggr.Warnw(fmt.Sprintf("got error for enhanced EA telemetry ask price, id %s: %s", askTask.Task.DotID(), askTask.Result.Error), "err", askTask.Result.Error) - } else { - askPrice, err = getResultFloat64(askTask) - if err != nil { - lggr.Warnw(fmt.Sprintf("cannot parse enhanced EA telemetry ask price, id %s", askTask.Task.DotID()), "err", err) - } - } + if askTask.Task.Type() == pipeline.TaskTypeJSONParse { + askPrice = parsePriceFromTask(lggr, *askTask) } return benchmarkPrice, bidPrice, askPrice diff --git a/core/services/ocrcommon/telemetry_test.go b/core/services/ocrcommon/telemetry_test.go index e257554803..631cc32ed0 100644 --- a/core/services/ocrcommon/telemetry_test.go +++ b/core/services/ocrcommon/telemetry_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" + "github.com/shopspring/decimal" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -445,15 +446,84 @@ var trrsMercuryV2 = pipeline.TaskRunResults{ }, } -func TestGetPricesFromResults(t *testing.T) { +func TestGetPricesFromBridgeByTelemetryField(t *testing.T) { + lggr, _ := logger.TestLoggerObserved(t, zap.WarnLevel) + // These are intentionally out of order from the "legacy" method which expects order of `benchmark, bid, ask` + jsonParseTaskBid := pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(1, "json_parse_2", nil, nil, 2), + } + jsonParseTaskBid.BaseTask.Tags = `{"priceType": "bid"}` + jsonParseTaskAsk := pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(2, "json_parse_3", nil, nil, 3), + } + jsonParseTaskAsk.BaseTask.Tags = `{"priceType": "ask"}` + jsonParseTaskBenchmark := pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(3, "json_parse_1", nil, nil, 1), + } + jsonParseTaskBenchmark.BaseTask.Tags = `{"priceType": "benchmark"}` + + bridgeOutputs := []pipeline.Task{&jsonParseTaskAsk, &jsonParseTaskBid, &jsonParseTaskBenchmark} + + bridgeTask := pipeline.BridgeTask{ + Name: "bridge-task", + BaseTask: pipeline.NewBaseTask(0, "bridge", nil, bridgeOutputs, 0), + } + + // Create task run results + taskRunResults := pipeline.TaskRunResults{ + pipeline.TaskRunResult{ + Task: &bridgeTask, + Result: pipeline.Result{ + Value: bridgeResponse, + }, + }, + pipeline.TaskRunResult{ + Task: &jsonParseTaskBenchmark, + Result: pipeline.Result{ + Value: "123456.123456", + }, + }, + pipeline.TaskRunResult{ + Task: &jsonParseTaskBid, + Result: pipeline.Result{ + Value: "1234567.1234567", + }, + }, + pipeline.TaskRunResult{ + Task: &jsonParseTaskAsk, + Result: pipeline.Result{ + Value: "321123", + }, + }, + } + + benchmarkPrice, bidPrice, askPrice := getPricesFromBridgeTask(lggr, taskRunResults[0], taskRunResults, 1) + + require.Equal(t, 123456.123456, benchmarkPrice) + require.Equal(t, 1234567.1234567, bidPrice) + require.Equal(t, 321123.0, askPrice) + + // now removing the TaskTags will throw off the parsed order - and we'll be parsing the "incorrect" prices + // according to the legacy ordering approach + jsonParseTaskAsk.BaseTask.Tags = "" + jsonParseTaskBid.BaseTask.Tags = "" + jsonParseTaskBenchmark.BaseTask.Tags = "" + + wrongBenchmarkPrice, wrongBidPrice, wrongAskPrice := getPricesFromBridgeTask(lggr, taskRunResults[0], taskRunResults, 1) + require.Equal(t, 1234567.1234567, wrongBenchmarkPrice) + require.Equal(t, 321123.0, wrongBidPrice) + require.Equal(t, 123456.123456, wrongAskPrice) +} + +func TestGetPricesFromBridgeTaskByOrder(t *testing.T) { lggr, logs := logger.TestLoggerObserved(t, zap.WarnLevel) - benchmarkPrice, bid, ask := getPricesFromResults(lggr, trrsMercuryV1[0], trrsMercuryV1, 1) + benchmarkPrice, bid, ask := getPricesFromBridgeTask(lggr, trrsMercuryV1[0], trrsMercuryV1, 1) require.Equal(t, 123456.123456, benchmarkPrice) require.Equal(t, 1234567.1234567, bid) require.Equal(t, float64(321123), ask) - benchmarkPrice, bid, ask = getPricesFromResults(lggr, trrsMercuryV1[0], pipeline.TaskRunResults{}, 1) + benchmarkPrice, bid, ask = getPricesFromBridgeTask(lggr, trrsMercuryV1[0], pipeline.TaskRunResults{}, 1) require.Equal(t, float64(0), benchmarkPrice) require.Equal(t, float64(0), bid) require.Equal(t, float64(0), ask) @@ -461,12 +531,12 @@ func TestGetPricesFromResults(t *testing.T) { require.Contains(t, logs.All()[0].Message, "cannot parse enhanced EA telemetry") tt := trrsMercuryV1[:2] - getPricesFromResults(lggr, trrsMercuryV1[0], tt, 1) + getPricesFromBridgeTask(lggr, trrsMercuryV1[0], tt, 1) require.Equal(t, 2, logs.Len()) require.Contains(t, logs.All()[1].Message, "cannot parse enhanced EA telemetry bid price, task is nil") tt = trrsMercuryV1[:3] - getPricesFromResults(lggr, trrsMercuryV1[0], tt, 1) + getPricesFromBridgeTask(lggr, trrsMercuryV1[0], tt, 1) require.Equal(t, 3, logs.Len()) require.Contains(t, logs.All()[2].Message, "cannot parse enhanced EA telemetry ask price, task is nil") @@ -504,16 +574,16 @@ func TestGetPricesFromResults(t *testing.T) { Value: nil, }, }} - benchmarkPrice, bid, ask = getPricesFromResults(lggr, trrsMercuryV1[0], trrs2, 3) + benchmarkPrice, bid, ask = getPricesFromBridgeTask(lggr, trrsMercuryV1[0], trrs2, 3) require.Equal(t, benchmarkPrice, float64(0)) require.Equal(t, bid, float64(0)) require.Equal(t, ask, float64(0)) require.Equal(t, logs.Len(), 6) - require.Contains(t, logs.All()[3].Message, "cannot parse enhanced EA telemetry benchmark price") - require.Contains(t, logs.All()[4].Message, "cannot parse enhanced EA telemetry bid price") - require.Contains(t, logs.All()[5].Message, "cannot parse enhanced EA telemetry ask price") + require.Contains(t, logs.All()[3].Message, "cannot parse EA telemetry price to float64, DOT id ds1_benchmark") + require.Contains(t, logs.All()[4].Message, "cannot parse EA telemetry price to float64, DOT id ds2_bid") + require.Contains(t, logs.All()[5].Message, "cannot parse EA telemetry price to float64, DOT id ds3_ask") - benchmarkPrice, bid, ask = getPricesFromResults(lggr, trrsMercuryV1[0], trrsMercuryV2, 2) + benchmarkPrice, bid, ask = getPricesFromBridgeTask(lggr, trrsMercuryV1[0], trrsMercuryV2, 2) require.Equal(t, 123456.123456, benchmarkPrice) require.Equal(t, float64(0), bid) require.Equal(t, float64(0), ask) @@ -539,6 +609,165 @@ func TestGetAssetSymbolFromRequestData(t *testing.T) { require.Equal(t, getAssetSymbolFromRequestData(""), "") reqData := `{"data":{"to":"LINK","from":"USD"}}` require.Equal(t, getAssetSymbolFromRequestData(reqData), "USD/LINK") + viewFunctionReqData := `{"data":{"address":"0x12345678", "signature": "function stEthPerToken() view returns (int256)"}}` + require.Equal(t, "0x12345678", getAssetSymbolFromRequestData(viewFunctionReqData)) +} + +func getViewFunctionTaskRunResults() pipeline.TaskRunResults { + var taskViewFunctionParseValue = func() pipeline.MultiplyTask { + task := pipeline.MultiplyTask{ + BaseTask: pipeline.NewBaseTask(3, "ds1_parse", nil, nil, 3), + Times: "1", + } + task.BaseTask.Tags = `{"priceType": "exchangeRate"}` + return task + }() + + var taskViewFunctionDecode = pipeline.ETHABIDecodeTask{ + ABI: "uint256 data", + BaseTask: pipeline.NewBaseTask(2, "ds1_decode", nil, []pipeline.Task{&taskViewFunctionParseValue}, 2), + } + + var taskViewFunctionJSONParse = pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(1, "ds1_parse", nil, []pipeline.Task{&taskViewFunctionDecode}, 1), + } + + const viewFunctionBridgeResponse = `{ + "data": { + "result": "0x000000000000000000000000000000000000000000000000105ba6a589b23a81" + }, + "statusCode": 200, + "result": "0x000000000000000000000000000000000000000000000000105ba6a589b23a81", + "timestamps": { + "providerDataRequestedUnixMs": 1726243598046, + "providerDataReceivedUnixMs": 1726243598341 + }, + "meta": { + "adapterName": "VIEW_FUNCTION" + } + }` + + var taskViewFunctionBridgeRequest = pipeline.BridgeTask{ + Name: "bridge-view-function", + BaseTask: pipeline.NewBaseTask(0, "ds1", nil, []pipeline.Task{&taskViewFunctionJSONParse}, 0), + RequestData: `{"data":{"address":"0x1234","signature":"function stEthPerToken() external view returns (uint256)"}}`, + } + + return pipeline.TaskRunResults{ + pipeline.TaskRunResult{ + Task: &taskViewFunctionBridgeRequest, + Result: pipeline.Result{ + Value: viewFunctionBridgeResponse, + }, + }, + pipeline.TaskRunResult{ + Task: &taskViewFunctionJSONParse, + Result: pipeline.Result{ + Value: `0x000000000000000000000000000000000000000000000000105ba6a589b23a81`, + }, + }, + pipeline.TaskRunResult{ + Task: &taskViewFunctionDecode, + Result: pipeline.Result{ + Value: map[string]interface{}{ + "data": big.NewInt(1178718957397490305), + }, + }, + }, + pipeline.TaskRunResult{ + Task: &taskViewFunctionParseValue, + Result: pipeline.Result{ + Value: decimal.NewFromInt(1178718957397490305), + }, + }, + } +} + +func TestCollectMercuryEnhancedTelemetryV1ViewFunction(t *testing.T) { + wg := sync.WaitGroup{} + ingressClient := mocks.NewTelemetryService(t) + ingressAgent := telemetry.NewIngressAgentWrapper(ingressClient) + monitoringEndpoint := ingressAgent.GenMonitoringEndpoint("test-network", "test-chainID", "0xa", synchronization.EnhancedEAMercury) + + var sentMessage []byte + ingressClient.On("Send", mock.Anything, mock.AnythingOfType("[]uint8"), mock.AnythingOfType("string"), mock.AnythingOfType("TelemetryType")).Return().Run(func(args mock.Arguments) { + sentMessage = args[1].([]byte) + wg.Done() + }) + + lggr, _ := logger.TestLoggerObserved(t, zap.WarnLevel) + chTelem := make(chan EnhancedTelemetryMercuryData, 100) + chDone := make(chan struct{}) + feedID := common.HexToHash("0x111") + e := EnhancedTelemetryService[EnhancedTelemetryMercuryData]{ + chDone: chDone, + chTelem: chTelem, + job: &job.Job{ + Type: job.Type(pipeline.OffchainReporting2JobType), + OCR2OracleSpec: &job.OCR2OracleSpec{ + CaptureEATelemetry: true, + FeedID: &feedID, + }, + }, + lggr: lggr, + monitoringEndpoint: monitoringEndpoint, + } + servicetest.Run(t, &e) + + wg.Add(1) + + taskRunResults := getViewFunctionTaskRunResults() + + chTelem <- EnhancedTelemetryMercuryData{ + TaskRunResults: taskRunResults, + V1Observation: &mercuryv1.Observation{ + BenchmarkPrice: mercury.ObsResult[*big.Int]{Val: big.NewInt(111111)}, + Bid: mercury.ObsResult[*big.Int]{Val: big.NewInt(222222)}, + Ask: mercury.ObsResult[*big.Int]{Val: big.NewInt(333333)}, + CurrentBlockNum: mercury.ObsResult[int64]{Val: 123456789}, + CurrentBlockHash: mercury.ObsResult[[]byte]{Val: common.HexToHash("0x123321").Bytes()}, + CurrentBlockTimestamp: mercury.ObsResult[uint64]{Val: 987654321}, + }, + RepTimestamp: types.ReportTimestamp{ + ConfigDigest: types.ConfigDigest{2}, + Epoch: 11, + Round: 22, + }, + } + + expectedTelemetry := telem.EnhancedEAMercury{ + DataSource: "VIEW_FUNCTION", + DpBenchmarkPrice: 1178718957397490400, + DpBid: 1178718957397490400, + DpAsk: 1178718957397490400, + CurrentBlockNumber: 123456789, + CurrentBlockHash: common.HexToHash("0x123321").String(), + CurrentBlockTimestamp: 987654321, + BridgeTaskRunStartedTimestamp: taskRunResults[0].CreatedAt.UnixMilli(), + BridgeTaskRunEndedTimestamp: taskRunResults[0].FinishedAt.Time.UnixMilli(), + ProviderRequestedTimestamp: 1726243598046, + ProviderReceivedTimestamp: 1726243598341, + ProviderDataStreamEstablished: 0, + ProviderIndicatedTime: 0, + Feed: common.HexToHash("0x111").String(), + ObservationBenchmarkPrice: 111111, + ObservationBid: 222222, + ObservationAsk: 333333, + ConfigDigest: "0200000000000000000000000000000000000000000000000000000000000000", + Round: 22, + Epoch: 11, + BridgeRequestData: `{"data":{"address":"0x1234","signature":"function stEthPerToken() external view returns (uint256)"}}`, + AssetSymbol: "0x1234", + ObservationBenchmarkPriceString: "111111", + ObservationBidString: "222222", + ObservationAskString: "333333", + } + + expectedMessage, _ := proto.Marshal(&expectedTelemetry) + wg.Wait() + require.Equal(t, expectedMessage, sentMessage) + + chDone <- struct{}{} } func TestCollectMercuryEnhancedTelemetryV1(t *testing.T) { @@ -612,6 +841,7 @@ func TestCollectMercuryEnhancedTelemetryV1(t *testing.T) { ConfigDigest: "0200000000000000000000000000000000000000000000000000000000000000", Round: 22, Epoch: 11, + BridgeRequestData: `{"data":{"to":"LINK","from":"USD"}}`, AssetSymbol: "USD/LINK", ObservationBenchmarkPriceString: "111111", ObservationBidString: "222222", @@ -725,6 +955,7 @@ func TestCollectMercuryEnhancedTelemetryV2(t *testing.T) { ConfigDigest: "0200000000000000000000000000000000000000000000000000000000000000", Round: 22, Epoch: 11, + BridgeRequestData: `{"data":{"to":"LINK","from":"USD"}}`, AssetSymbol: "USD/LINK", ObservationBenchmarkPriceString: "111111", MaxFinalizedTimestamp: 321, diff --git a/core/services/pipeline/common.go b/core/services/pipeline/common.go index 4e7c5b9cef..50611ee32a 100644 --- a/core/services/pipeline/common.go +++ b/core/services/pipeline/common.go @@ -60,6 +60,8 @@ type ( TaskRetries() uint32 TaskMinBackoff() time.Duration TaskMaxBackoff() time.Duration + TaskTags() string + GetDescendantTasks() []Task } Config interface { @@ -263,6 +265,16 @@ func (trrs TaskRunResults) Terminals() (terminals []TaskRunResult) { return } +// GetNextTaskOf returns the task with the next id or nil if it does not exist +func (trrs *TaskRunResults) GetTaskRunResultOf(task Task) *TaskRunResult { + for _, trr := range *trrs { + if trr.Task.Base().id == task.Base().id { + return &trr + } + } + return nil +} + // GetNextTaskOf returns the task with the next id or nil if it does not exist func (trrs *TaskRunResults) GetNextTaskOf(task TaskRunResult) *TaskRunResult { nextID := task.Task.Base().id + 1 diff --git a/core/services/pipeline/common_test.go b/core/services/pipeline/common_test.go index ce545ec14a..ed7998b79e 100644 --- a/core/services/pipeline/common_test.go +++ b/core/services/pipeline/common_test.go @@ -17,6 +17,14 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" ) +func TestAtrributesAttribute(t *testing.T) { + a := `ds1 [type=http method=GET tags=<{"attribute1":"value1", "attribute2":42}>];` + p, err := pipeline.Parse(a) + require.NoError(t, err) + task := p.Tasks[0] + assert.Equal(t, "{\"attribute1\":\"value1\", \"attribute2\":42}", task.TaskTags()) +} + func TestTimeoutAttribute(t *testing.T) { t.Parallel() @@ -320,3 +328,69 @@ func TestGetNextTaskOf(t *testing.T) { nextTask = trrs.GetNextTaskOf(*nextTask) assert.Empty(t, nextTask) } + +func TestGetDescendantTasks(t *testing.T) { + t.Parallel() + + t.Run("GetDescendantTasks with multiple levels of tasks", func(t *testing.T) { + l3T2 := pipeline.AnyTask{ + BaseTask: pipeline.NewBaseTask(6, "l3T2", nil, nil, 1), + } + l3T1 := pipeline.MedianTask{ + BaseTask: pipeline.NewBaseTask(5, "l3T1", nil, nil, 1), + } + l2T1 := pipeline.MultiplyTask{ + BaseTask: pipeline.NewBaseTask(4, "l2T1", nil, []pipeline.Task{&l3T1, &l3T2}, 1), + } + l1T1 := pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(3, "l1T1", nil, []pipeline.Task{&l2T1}, 2), + } + l1T2 := pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(2, "l1T2", nil, nil, 3), + } + l1T3 := pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(1, "l1T3", nil, nil, 4), + } + + baseTask := pipeline.BridgeTask{ + Name: "bridge-task", + BaseTask: pipeline.NewBaseTask(0, "baseTask", nil, []pipeline.Task{&l1T1, &l1T2, &l1T3}, 0), + } + + descendents := baseTask.GetDescendantTasks() + assert.Len(t, descendents, 6) + }) + + t.Run("GetDescendantTasks with duplicate tasks defined", func(t *testing.T) { + l2T1 := pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(2, "l1T2", nil, nil, 3), + } + l1T1 := pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(1, "l1T2", nil, []pipeline.Task{&l2T1, &l2T1, &l2T1}, 3), + } + taskWithRepeats := pipeline.BridgeTask{ + Name: "bridge-task", + BaseTask: pipeline.NewBaseTask(0, "taskWithRepeats", nil, []pipeline.Task{&l1T1, &l1T1, &l1T1}, 0), + } + descendents := taskWithRepeats.GetDescendantTasks() + assert.Len(t, descendents, 2) + }) + + t.Run("GetDescendantTasks with nil output tasks", func(t *testing.T) { + taskWithRepeats := pipeline.BridgeTask{ + Name: "bridge-task", + BaseTask: pipeline.NewBaseTask(0, "taskWithRepeats", nil, nil, 0), + } + descendents := taskWithRepeats.GetDescendantTasks() + assert.Len(t, descendents, 0) + }) + + t.Run("GetDescendantTasks with empty list of output tasks", func(t *testing.T) { + taskWithRepeats := pipeline.BridgeTask{ + Name: "bridge-task", + BaseTask: pipeline.NewBaseTask(0, "taskWithRepeats", nil, []pipeline.Task{}, 0), + } + descendents := taskWithRepeats.GetDescendantTasks() + assert.Len(t, descendents, 0) + }) +} diff --git a/core/services/pipeline/runner_test.go b/core/services/pipeline/runner_test.go index 022a77c947..ea30b3ff08 100644 --- a/core/services/pipeline/runner_test.go +++ b/core/services/pipeline/runner_test.go @@ -131,6 +131,50 @@ ds5 [type=http method="GET" url="%s" index=2] require.Len(t, errorResults, 3) } +func Test_PipelineRunner_ExecuteEthAbiDecode(t *testing.T) { + db := pgtest.NewSqlxDB(t) + cfg := configtest.NewTestGeneralConfig(t) + + mockResult := `{"data":{"result":"0x000000000000000000000000000000000000000000000000105ba6a589b23a81"}}` + s1 := httptest.NewServer(NewMockHandler(mockResult)) + defer s1.Close() + + bridgeFeedURL, err := url.ParseRequestURI(s1.URL) + require.NoError(t, err) + + _, bt := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: bridgeFeedURL.String()}) + + btORM := bridgesMocks.NewORM(t) + btORM.On("FindBridge", mock.Anything, bt.Name).Return(*bt, nil).Once() + + r, _ := newRunner(t, db, btORM, cfg) + + s := fmt.Sprintf(` + ds1 [type=bridge name="%s" timeout=0 requestData=<{"data": {"address": "0x1234"}}>] + ds1_parse [type=jsonparse path="data,result"] + ds1_decode [type=ethabidecode abi="int256 data" data="$(ds1_parse)"]; + ds1_value [type="multiply" input="$(ds1_decode.data)" times=1] + + ds1->ds1_parse->ds1_decode->ds1_value + +`, bt.Name.String()) + d, err := pipeline.Parse(s) + require.NoError(t, err) + + spec := pipeline.Spec{DotDagSource: s} + vars := pipeline.NewVarsFrom(nil) + + _, trrs, err := r.ExecuteRun(testutils.Context(t), spec, vars) + require.NoError(t, err) + require.Len(t, trrs, len(d.Tasks)) + + finalResults := trrs.FinalResult() + + val := finalResults.Values[0].(decimal.Decimal) + + assert.Equal(t, decimal.NewFromInt(1178718957397490305), val) +} + type taskRunWithVars struct { bridgeName string ds2URL, ds4URL string diff --git a/core/services/pipeline/task.base.go b/core/services/pipeline/task.base.go index 7a62f4e7ff..3e1db5fcdb 100644 --- a/core/services/pipeline/task.base.go +++ b/core/services/pipeline/task.base.go @@ -22,6 +22,8 @@ type BaseTask struct { MinBackoff time.Duration `mapstructure:"minBackoff"` MaxBackoff time.Duration `mapstructure:"maxBackoff"` + Tags string `mapstructure:"tags" json:"-"` + uuid uuid.UUID } @@ -77,3 +79,32 @@ func (t BaseTask) TaskMaxBackoff() time.Duration { } return time.Minute } + +func (t BaseTask) TaskTags() string { + return t.Tags +} + +// GetDescendantTasks retrieves all descendant tasks of a given task +func (t BaseTask) GetDescendantTasks() []Task { + if len(t.outputs) == 0 { + return []Task{} + } + var descendants []Task + queue := append([]Task{}, t.outputs...) + visited := make(map[int]bool) + + for len(queue) > 0 { + currentTask := queue[0] + queue = queue[1:] + + taskID := currentTask.ID() + if visited[taskID] { + continue + } + visited[taskID] = true + descendants = append(descendants, currentTask) + queue = append(queue, currentTask.Outputs()...) + } + + return descendants +} diff --git a/core/services/pipeline/task.bridge_test.go b/core/services/pipeline/task.bridge_test.go index d7519232eb..cd81f8656f 100644 --- a/core/services/pipeline/task.bridge_test.go +++ b/core/services/pipeline/task.bridge_test.go @@ -117,6 +117,18 @@ func mustReadFile(t testing.TB, file string) string { return string(content) } +// NewMockHandler returns an http.HandlerFunc that responds with the given payload for any request +func NewMockHandler(payload string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, err := w.Write([]byte(payload)) + if err != nil { + http.Error(w, "Failed to write response", http.StatusInternalServerError) + } + } +} + func fakePriceResponder(t *testing.T, requestData map[string]interface{}, result decimal.Decimal, inputKey string, expectedInput interface{}) http.Handler { t.Helper() diff --git a/core/services/pipeline/task.eth_abi_decode_test.go b/core/services/pipeline/task.eth_abi_decode_test.go index 3c7f5b4776..565e8b485d 100644 --- a/core/services/pipeline/task.eth_abi_decode_test.go +++ b/core/services/pipeline/task.eth_abi_decode_test.go @@ -25,6 +25,20 @@ var testsABIDecode = []struct { expectedErrorCause error expectedErrorContains string }{ + { + "uint256", + "uint256 data", + "$(data)", + NewVarsFrom(map[string]interface{}{ + "data": "0x000000000000000000000000000000000000000000000000105ba6a589b23a81", + }), + nil, + map[string]interface{}{ + "data": big.NewInt(1178718957397490305), + }, + nil, + "", + }, { "uint256, bool, int256, string", "uint256 u, bool b, int256 i, string s", diff --git a/core/services/relay/evm/mercury/mocks/pipeline.go b/core/services/relay/evm/mercury/mocks/pipeline.go index 44be1377ae..a7183c9a03 100644 --- a/core/services/relay/evm/mercury/mocks/pipeline.go +++ b/core/services/relay/evm/mercury/mocks/pipeline.go @@ -23,6 +23,10 @@ type MockTask struct { result pipeline.Result } +func (m *MockTask) GetDescendantTasks() []pipeline.Task { return nil } + +func (m *MockTask) TaskTags() string { return "{\"anything\": \"here\"}" } + func (m *MockTask) Type() pipeline.TaskType { return "MockTask" } func (m *MockTask) ID() int { return 0 } func (m *MockTask) DotID() string { return "" } diff --git a/core/services/synchronization/telem/telem.pb.go b/core/services/synchronization/telem/telem.pb.go index d51b9628e2..8ededa8ce1 100644 --- a/core/services/synchronization/telem/telem.pb.go +++ b/core/services/synchronization/telem/telem.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v4.25.1 +// protoc v5.28.0 // source: core/services/synchronization/telem/telem.proto package telem diff --git a/core/services/synchronization/telem/telem_automation_custom.pb.go b/core/services/synchronization/telem/telem_automation_custom.pb.go index 30ddce6f79..7c498be9fd 100644 --- a/core/services/synchronization/telem/telem_automation_custom.pb.go +++ b/core/services/synchronization/telem/telem_automation_custom.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v4.25.1 +// protoc v5.28.0 // source: core/services/synchronization/telem/telem_automation_custom.proto package telem diff --git a/core/services/synchronization/telem/telem_enhanced_ea.pb.go b/core/services/synchronization/telem/telem_enhanced_ea.pb.go index c8983a06fe..687ff7ab4e 100644 --- a/core/services/synchronization/telem/telem_enhanced_ea.pb.go +++ b/core/services/synchronization/telem/telem_enhanced_ea.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v4.25.1 +// protoc v5.28.0 // source: core/services/synchronization/telem/telem_enhanced_ea.proto package telem diff --git a/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go b/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go index 856619e193..7be7ad8d70 100644 --- a/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go +++ b/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v4.25.1 +// protoc v5.28.0 // source: core/services/synchronization/telem/telem_enhanced_ea_mercury.proto package telem @@ -81,6 +81,7 @@ type EnhancedEAMercury struct { DpBid float64 `protobuf:"fixed64,3,opt,name=dp_bid,json=dpBid,proto3" json:"dp_bid,omitempty"` DpAsk float64 `protobuf:"fixed64,4,opt,name=dp_ask,json=dpAsk,proto3" json:"dp_ask,omitempty"` DpInvariantViolationDetected bool `protobuf:"varint,33,opt,name=dp_invariant_violation_detected,json=dpInvariantViolationDetected,proto3" json:"dp_invariant_violation_detected,omitempty"` + BridgeRequestData string `protobuf:"bytes,35,opt,name=bridge_request_data,json=bridgeRequestData,proto3" json:"bridge_request_data,omitempty"` // v1 fields (block range) CurrentBlockNumber int64 `protobuf:"varint,5,opt,name=current_block_number,json=currentBlockNumber,proto3" json:"current_block_number,omitempty"` CurrentBlockHash string `protobuf:"bytes,6,opt,name=current_block_hash,json=currentBlockHash,proto3" json:"current_block_hash,omitempty"` @@ -190,6 +191,13 @@ func (x *EnhancedEAMercury) GetDpInvariantViolationDetected() bool { return false } +func (x *EnhancedEAMercury) GetBridgeRequestData() string { + if x != nil { + return x.BridgeRequestData + } + return "" +} + func (x *EnhancedEAMercury) GetCurrentBlockNumber() int64 { if x != nil { return x.CurrentBlockNumber @@ -393,7 +401,7 @@ var file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_raw 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x5f, 0x65, 0x6e, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x5f, 0x65, 0x61, 0x5f, 0x6d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x79, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x22, 0xfa, 0x0c, 0x0a, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x22, 0xaa, 0x0d, 0x0a, 0x11, 0x45, 0x6e, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x45, 0x41, 0x4d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, @@ -409,6 +417,9 @@ var file_core_services_synchronization_telem_telem_enhanced_ea_mercury_proto_raw 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x64, 0x70, 0x49, 0x6e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x12, 0x2e, 0x0a, 0x13, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x23, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x62, + 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, diff --git a/core/services/synchronization/telem/telem_enhanced_ea_mercury.proto b/core/services/synchronization/telem/telem_enhanced_ea_mercury.proto index bb41ff86ee..c96c58f9ea 100644 --- a/core/services/synchronization/telem/telem_enhanced_ea_mercury.proto +++ b/core/services/synchronization/telem/telem_enhanced_ea_mercury.proto @@ -19,6 +19,7 @@ message EnhancedEAMercury { double dp_bid=3; double dp_ask=4; bool dp_invariant_violation_detected=33; + string bridge_request_data = 35; // v1 fields (block range) int64 current_block_number=5; diff --git a/core/services/synchronization/telem/telem_functions_request.pb.go b/core/services/synchronization/telem/telem_functions_request.pb.go index 89aa9e3fe3..1a67d1223a 100644 --- a/core/services/synchronization/telem/telem_functions_request.pb.go +++ b/core/services/synchronization/telem/telem_functions_request.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v4.25.1 +// protoc v5.28.0 // source: core/services/synchronization/telem/telem_functions_request.proto package telem diff --git a/core/services/synchronization/telem/telem_head_report.pb.go b/core/services/synchronization/telem/telem_head_report.pb.go index 87fa42a57e..c4101d0656 100644 --- a/core/services/synchronization/telem/telem_head_report.pb.go +++ b/core/services/synchronization/telem/telem_head_report.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v4.25.1 +// protoc v5.28.0 // source: core/services/synchronization/telem/telem_head_report.proto package telem diff --git a/core/services/synchronization/telem/telem_wsrpc.pb.go b/core/services/synchronization/telem/telem_wsrpc.pb.go index e4028b4de4..e7df2090e4 100644 --- a/core/services/synchronization/telem/telem_wsrpc.pb.go +++ b/core/services/synchronization/telem/telem_wsrpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-wsrpc. DO NOT EDIT. // versions: // - protoc-gen-go-wsrpc v0.0.1 -// - protoc v4.25.1 +// - protoc v5.28.0 package telem From 5885454e9a7eaa8f8c180ac3708afbdf5bdb08cd Mon Sep 17 00:00:00 2001 From: Austin Born Date: Wed, 18 Sep 2024 09:28:46 -0700 Subject: [PATCH 372/432] DF-20481: Add new OCR3DataFeeds telemetry type for Mercury jobs (#14470) * Add new OCR3DataFeeds telemetry type for Mercury jobs * Update plugin_test.go * Changeset * Update curvy-beans-scream.md * Update .changeset/curvy-beans-scream.md * Update curvy-beans-scream.md --- .changeset/curvy-beans-scream.md | 5 +++++ core/services/ocr2/delegate.go | 19 +++++++++++++++++-- core/services/ocr2/plugins/mercury/plugin.go | 15 +++++---------- .../ocr2/plugins/mercury/plugin_test.go | 2 +- core/services/synchronization/common.go | 1 + core/services/telemetry/manager.go | 2 +- 6 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 .changeset/curvy-beans-scream.md diff --git a/.changeset/curvy-beans-scream.md b/.changeset/curvy-beans-scream.md new file mode 100644 index 0000000000..4252f965e3 --- /dev/null +++ b/.changeset/curvy-beans-scream.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#changed: Add new OCR3DataFeeds telemetry type for Mercury jobs diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 18f4d6224e..9d4dbb8598 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -882,6 +882,21 @@ func (d *Delegate) newServicesMercury( lggr.ErrorIf(d.jobORM.RecordError(ctx, jb.ID, msg), "unable to record error") }) + var relayConfig evmrelaytypes.RelayConfig + err = json.Unmarshal(jb.OCR2OracleSpec.RelayConfig.Bytes(), &relayConfig) + if err != nil { + return nil, fmt.Errorf("error while unmarshalling relay config: %w", err) + } + + var telemetryType synchronization.TelemetryType + if relayConfig.EnableTriggerCapability && jb.OCR2OracleSpec.PluginConfig == nil { + telemetryType = synchronization.OCR3DataFeeds + // First use case for TriggerCapability transmission is Data Feeds, so telemetry should be routed accordingly. + // This is only true if TriggerCapability is the *only* transmission method (PluginConfig == nil). + } else { + telemetryType = synchronization.OCR3Mercury + } + oracleArgsNoPlugin := libocr2.MercuryOracleArgs{ BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, @@ -890,7 +905,7 @@ func (d *Delegate) newServicesMercury( Database: ocrDB, LocalConfig: lc, Logger: ocrLogger, - MonitoringEndpoint: d.monitoringEndpointGen.GenMonitoringEndpoint(rid.Network, rid.ChainID, spec.FeedID.String(), synchronization.OCR3Mercury), + MonitoringEndpoint: d.monitoringEndpointGen.GenMonitoringEndpoint(rid.Network, rid.ChainID, spec.FeedID.String(), telemetryType), OffchainConfigDigester: mercuryProvider.OffchainConfigDigester(), OffchainKeyring: kb, OnchainKeyring: kb, @@ -901,7 +916,7 @@ func (d *Delegate) newServicesMercury( mCfg := mercury.NewMercuryConfig(d.cfg.JobPipeline().MaxSuccessfulRuns(), d.cfg.JobPipeline().ResultWriteQueueDepth(), d.cfg) - mercuryServices, err2 := mercury.NewServices(jb, mercuryProvider, d.pipelineRunner, lggr, oracleArgsNoPlugin, mCfg, chEnhancedTelem, d.mercuryORM, (mercuryutils.FeedID)(*spec.FeedID)) + mercuryServices, err2 := mercury.NewServices(jb, mercuryProvider, d.pipelineRunner, lggr, oracleArgsNoPlugin, mCfg, chEnhancedTelem, d.mercuryORM, (mercuryutils.FeedID)(*spec.FeedID), relayConfig.EnableTriggerCapability) if ocrcommon.ShouldCollectEnhancedTelemetryMercury(jb) { enhancedTelemService := ocrcommon.NewEnhancedTelemetryService(&jb, chEnhancedTelem, make(chan struct{}), d.monitoringEndpointGen.GenMonitoringEndpoint(rid.Network, rid.ChainID, spec.FeedID.String(), synchronization.EnhancedEAMercury), lggr.Named("EnhancedTelemetryMercury")) diff --git a/core/services/ocr2/plugins/mercury/plugin.go b/core/services/ocr2/plugins/mercury/plugin.go index 13793570de..f78531d6b0 100644 --- a/core/services/ocr2/plugins/mercury/plugin.go +++ b/core/services/ocr2/plugins/mercury/plugin.go @@ -31,7 +31,6 @@ import ( mercuryv2 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2" mercuryv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3" mercuryv4 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v4" - evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/plugins" ) @@ -74,20 +73,16 @@ func NewServices( chEnhancedTelem chan ocrcommon.EnhancedTelemetryMercuryData, orm types.DataSourceORM, feedID utils.FeedID, + enableTriggerCapability bool, ) ([]job.ServiceCtx, error) { if jb.PipelineSpec == nil { return nil, errors.New("expected job to have a non-nil PipelineSpec") } - var relayConfig evmtypes.RelayConfig - err := json.Unmarshal(jb.OCR2OracleSpec.RelayConfig.Bytes(), &relayConfig) - if err != nil { - return nil, fmt.Errorf("error while unmarshalling relay config: %w", err) - } - + var err error var pluginConfig config.PluginConfig if jb.OCR2OracleSpec.PluginConfig == nil { - if !relayConfig.EnableTriggerCapability { + if !enableTriggerCapability { return nil, fmt.Errorf("at least one transmission option must be configured") } } else { @@ -106,8 +101,8 @@ func NewServices( // encapsulate all the subservices and ensure we close them all if any fail to start srvs := []job.ServiceCtx{ocr2Provider} abort := func() { - if cerr := services.MultiCloser(srvs).Close(); err != nil { - lggr.Errorw("Error closing unused services", "err", cerr) + if err = services.MultiCloser(srvs).Close(); err != nil { + lggr.Errorw("Error closing unused services", "err", err) } } saver := ocrcommon.NewResultRunSaver(pipelineRunner, lggr, cfg.MaxSuccessfulRuns(), cfg.ResultWriteQueueDepth()) diff --git a/core/services/ocr2/plugins/mercury/plugin_test.go b/core/services/ocr2/plugins/mercury/plugin_test.go index 50ff548935..22aaf7522d 100644 --- a/core/services/ocr2/plugins/mercury/plugin_test.go +++ b/core/services/ocr2/plugins/mercury/plugin_test.go @@ -230,7 +230,7 @@ func newServicesTestWrapper(t *testing.T, pluginConfig job.JSONConfig, feedID ut t.Helper() jb := testJob jb.OCR2OracleSpec.PluginConfig = pluginConfig - return mercuryocr2.NewServices(jb, &testProvider{}, nil, logger.TestLogger(t), testArgsNoPlugin, testCfg, nil, &testDataSourceORM{}, feedID) + return mercuryocr2.NewServices(jb, &testProvider{}, nil, logger.TestLogger(t), testArgsNoPlugin, testCfg, nil, &testDataSourceORM{}, feedID, false) } type testProvider struct{} diff --git a/core/services/synchronization/common.go b/core/services/synchronization/common.go index a6c0191e3a..9145a3c9ac 100644 --- a/core/services/synchronization/common.go +++ b/core/services/synchronization/common.go @@ -22,6 +22,7 @@ const ( OCR2S4 TelemetryType = "ocr2-s4" OCR2Median TelemetryType = "ocr2-median" OCR3Mercury TelemetryType = "ocr3-mercury" + OCR3DataFeeds TelemetryType = "ocr3-data-feeds" AutomationCustom TelemetryType = "automation-custom" OCR3Automation TelemetryType = "ocr3-automation" OCR3Rebalancer TelemetryType = "ocr3-rebalancer" diff --git a/core/services/telemetry/manager.go b/core/services/telemetry/manager.go index 73a94b4b12..7b788c4806 100644 --- a/core/services/telemetry/manager.go +++ b/core/services/telemetry/manager.go @@ -75,7 +75,7 @@ func (m *Manager) GenMonitoringEndpoint(network string, chainID string, contract e, found := m.getEndpoint(network, chainID) if !found { - m.eng.Warnf("no telemetry endpoint found for network %q chainID %q, telemetry %q for contactID %q will NOT be sent", network, chainID, telemType, contractID) + m.eng.Warnf("no telemetry endpoint found for network %q chainID %q, telemetry %q for contractID %q will NOT be sent", network, chainID, telemType, contractID) return &NoopAgent{} } From 1a5e591875d5d478be65605ad5dc66e8bf8b915b Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Wed, 18 Sep 2024 12:45:17 -0400 Subject: [PATCH 373/432] devsvcs-244: update token transfer (#14481) * devsvcs-244: update token transfer * Update gethwrappers * update wrapper * update --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- contracts/.changeset/twenty-pears-battle.md | 5 +++++ contracts/src/v0.8/automation/test/WETH9.sol | 2 +- .../v0.8/automation/IAutomationRegistryMaster2_2.test.ts | 3 ++- .../v0.8/automation/IAutomationRegistryMaster2_3.test.ts | 3 ++- core/gethwrappers/generated/weth9_wrapper/weth9_wrapper.go | 2 +- .../generated-wrapper-dependency-versions-do-not-edit.txt | 2 +- 6 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 contracts/.changeset/twenty-pears-battle.md diff --git a/contracts/.changeset/twenty-pears-battle.md b/contracts/.changeset/twenty-pears-battle.md new file mode 100644 index 0000000000..5a204f6889 --- /dev/null +++ b/contracts/.changeset/twenty-pears-battle.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +update token transfer logic in weth9 diff --git a/contracts/src/v0.8/automation/test/WETH9.sol b/contracts/src/v0.8/automation/test/WETH9.sol index b8452d832b..1225e6e39a 100644 --- a/contracts/src/v0.8/automation/test/WETH9.sol +++ b/contracts/src/v0.8/automation/test/WETH9.sol @@ -53,7 +53,7 @@ contract WETH9 { revert InsufficientBalance(); } balanceOf[msg.sender] -= wad; - payable(msg.sender).transfer(wad); + payable(msg.sender).call{value: wad}(""); emit Withdrawal(msg.sender, wad); } diff --git a/contracts/test/v0.8/automation/IAutomationRegistryMaster2_2.test.ts b/contracts/test/v0.8/automation/IAutomationRegistryMaster2_2.test.ts index 0c1e34a116..11da7273ab 100644 --- a/contracts/test/v0.8/automation/IAutomationRegistryMaster2_2.test.ts +++ b/contracts/test/v0.8/automation/IAutomationRegistryMaster2_2.test.ts @@ -93,7 +93,8 @@ describe('IAutomationRegistryMaster2_2', () => { ) }) - it('satisfies the OCR2Abstract interface', async () => { + // temporarily disable this test due to this update: https://github.com/smartcontractkit/chainlink/pull/14369/files#diff-6e79d46ea0ef204dea679ffd2a9f4dfccd090d8f405ba2d9bffad527d7b862c6L44 + it.skip('satisfies the OCR2Abstract interface', async () => { assertSatisfiesInterface( IAutomationRegistryMasterFactory.abi, OCR2AbstractFactory.abi, diff --git a/contracts/test/v0.8/automation/IAutomationRegistryMaster2_3.test.ts b/contracts/test/v0.8/automation/IAutomationRegistryMaster2_3.test.ts index 8bc4f69567..44fa277b5e 100644 --- a/contracts/test/v0.8/automation/IAutomationRegistryMaster2_3.test.ts +++ b/contracts/test/v0.8/automation/IAutomationRegistryMaster2_3.test.ts @@ -87,7 +87,8 @@ describe('IAutomationRegistryMaster2_3', () => { ) }) - it('satisfies the OCR2Abstract interface', async () => { + // temporarily disable this test due to this update: https://github.com/smartcontractkit/chainlink/pull/14369/files#diff-6e79d46ea0ef204dea679ffd2a9f4dfccd090d8f405ba2d9bffad527d7b862c6L44 + it.skip('satisfies the OCR2Abstract interface', async () => { assertSatisfiesInterface( IAutomationRegistryMasterFactory.abi, OCR2AbstractFactory.abi, diff --git a/core/gethwrappers/generated/weth9_wrapper/weth9_wrapper.go b/core/gethwrappers/generated/weth9_wrapper/weth9_wrapper.go index f38435143b..87849c786f 100644 --- a/core/gethwrappers/generated/weth9_wrapper/weth9_wrapper.go +++ b/core/gethwrappers/generated/weth9_wrapper/weth9_wrapper.go @@ -32,7 +32,7 @@ var ( var WETH9MetaData = &bind.MetaData{ ABI: "[{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - Bin: "0x60c0604052600d60809081526c2bb930b83832b21022ba3432b960991b60a05260009061002c9082610114565b506040805180820190915260048152630ae8aa8960e31b60208201526001906100559082610114565b506002805460ff1916601217905534801561006f57600080fd5b506101d3565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061009f57607f821691505b6020821081036100bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561010f57600081815260208120601f850160051c810160208610156100ec5750805b601f850160051c820191505b8181101561010b578281556001016100f8565b5050505b505050565b81516001600160401b0381111561012d5761012d610075565b6101418161013b845461008b565b846100c5565b602080601f831160018114610176576000841561015e5750858301515b600019600386901b1c1916600185901b17855561010b565b600085815260208120601f198616915b828110156101a557888601518255948401946001909101908401610186565b50858210156101c35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61099c80620001e36000396000f3fe6080604052600436106100cb5760003560e01c806340c10f1911610074578063a9059cbb1161004e578063a9059cbb14610225578063d0e30db014610245578063dd62ed3e1461024d57600080fd5b806340c10f19146101c357806370a08231146101e357806395d89b411461021057600080fd5b806323b872dd116100a557806323b872dd146101575780632e1a7d4d14610177578063313ce5671461019757600080fd5b806306fdde03146100df578063095ea7b31461010a57806318160ddd1461013a57600080fd5b366100da576100d8610285565b005b600080fd5b3480156100eb57600080fd5b506100f46102e0565b6040516101019190610785565b60405180910390f35b34801561011657600080fd5b5061012a61012536600461081a565b61036e565b6040519015158152602001610101565b34801561014657600080fd5b50475b604051908152602001610101565b34801561016357600080fd5b5061012a610172366004610844565b6103e8565b34801561018357600080fd5b506100d8610192366004610880565b610649565b3480156101a357600080fd5b506002546101b19060ff1681565b60405160ff9091168152602001610101565b3480156101cf57600080fd5b506100d86101de36600461081a565b61071c565b3480156101ef57600080fd5b506101496101fe366004610899565b60036020526000908152604090205481565b34801561021c57600080fd5b506100f461075a565b34801561023157600080fd5b5061012a61024036600461081a565b610767565b6100d861077b565b34801561025957600080fd5b506101496102683660046108b4565b600460209081526000928352604080842090915290825290205481565b33600090815260036020526040812080543492906102a4908490610916565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b600080546102ed90610929565b80601f016020809104026020016040519081016040528092919081815260200182805461031990610929565b80156103665780601f1061033b57610100808354040283529160200191610366565b820191906000526020600020905b81548152906001019060200180831161034957829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103d69086815260200190565b60405180910390a35060015b92915050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812054821115610447576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff841633148015906104ad575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020546fffffffffffffffffffffffffffffffff14155b156105625773ffffffffffffffffffffffffffffffffffffffff8416600090815260046020908152604080832033845290915290205482111561051c576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091528120805484929061055c90849061097c565b90915550505b73ffffffffffffffffffffffffffffffffffffffff84166000908152600360205260408120805484929061059790849061097c565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080548492906105d1908490610916565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161063791815260200190565b60405180910390a35060019392505050565b33600090815260036020526040902054811115610692576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260036020526040812080548392906106b190849061097c565b9091555050604051339082156108fc029083906000818181858888f193505050501580156106e3573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054839290610751908490610916565b90915550505050565b600180546102ed90610929565b60006107743384846103e8565b9392505050565b610783610285565b565b600060208083528351808285015260005b818110156107b257858101830151858201604001528201610796565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461081557600080fd5b919050565b6000806040838503121561082d57600080fd5b610836836107f1565b946020939093013593505050565b60008060006060848603121561085957600080fd5b610862846107f1565b9250610870602085016107f1565b9150604084013590509250925092565b60006020828403121561089257600080fd5b5035919050565b6000602082840312156108ab57600080fd5b610774826107f1565b600080604083850312156108c757600080fd5b6108d0836107f1565b91506108de602084016107f1565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156103e2576103e26108e7565b600181811c9082168061093d57607f821691505b602082108103610976577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b818103818111156103e2576103e26108e756fea164736f6c6343000813000a", + Bin: "0x60c0604052600d60809081526c2bb930b83832b21022ba3432b960991b60a05260009061002c9082610114565b506040805180820190915260048152630ae8aa8960e31b60208201526001906100559082610114565b506002805460ff1916601217905534801561006f57600080fd5b506101d3565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061009f57607f821691505b6020821081036100bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561010f57600081815260208120601f850160051c810160208610156100ec5750805b601f850160051c820191505b8181101561010b578281556001016100f8565b5050505b505050565b81516001600160401b0381111561012d5761012d610075565b6101418161013b845461008b565b846100c5565b602080601f831160018114610176576000841561015e5750858301515b600019600386901b1c1916600185901b17855561010b565b600085815260208120601f198616915b828110156101a557888601518255948401946001909101908401610186565b50858210156101c35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6109b680620001e36000396000f3fe6080604052600436106100cb5760003560e01c806340c10f1911610074578063a9059cbb1161004e578063a9059cbb14610225578063d0e30db014610245578063dd62ed3e1461024d57600080fd5b806340c10f19146101c357806370a08231146101e357806395d89b411461021057600080fd5b806323b872dd116100a557806323b872dd146101575780632e1a7d4d14610177578063313ce5671461019757600080fd5b806306fdde03146100df578063095ea7b31461010a57806318160ddd1461013a57600080fd5b366100da576100d8610285565b005b600080fd5b3480156100eb57600080fd5b506100f46102e0565b604051610101919061079f565b60405180910390f35b34801561011657600080fd5b5061012a610125366004610834565b61036e565b6040519015158152602001610101565b34801561014657600080fd5b50475b604051908152602001610101565b34801561016357600080fd5b5061012a61017236600461085e565b6103e8565b34801561018357600080fd5b506100d861019236600461089a565b610649565b3480156101a357600080fd5b506002546101b19060ff1681565b60405160ff9091168152602001610101565b3480156101cf57600080fd5b506100d86101de366004610834565b610736565b3480156101ef57600080fd5b506101496101fe3660046108b3565b60036020526000908152604090205481565b34801561021c57600080fd5b506100f4610774565b34801561023157600080fd5b5061012a610240366004610834565b610781565b6100d8610795565b34801561025957600080fd5b506101496102683660046108ce565b600460209081526000928352604080842090915290825290205481565b33600090815260036020526040812080543492906102a4908490610930565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b600080546102ed90610943565b80601f016020809104026020016040519081016040528092919081815260200182805461031990610943565b80156103665780601f1061033b57610100808354040283529160200191610366565b820191906000526020600020905b81548152906001019060200180831161034957829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103d69086815260200190565b60405180910390a35060015b92915050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812054821115610447576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff841633148015906104ad575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020546fffffffffffffffffffffffffffffffff14155b156105625773ffffffffffffffffffffffffffffffffffffffff8416600090815260046020908152604080832033845290915290205482111561051c576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091528120805484929061055c908490610996565b90915550505b73ffffffffffffffffffffffffffffffffffffffff841660009081526003602052604081208054849290610597908490610996565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080548492906105d1908490610930565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161063791815260200190565b60405180910390a35060019392505050565b33600090815260036020526040902054811115610692576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260036020526040812080548392906106b1908490610996565b909155505060405133908290600081818185875af1925050503d80600081146106f6576040519150601f19603f3d011682016040523d82523d6000602084013e6106fb565b606091505b50506040518281523391507f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805483929061076b908490610930565b90915550505050565b600180546102ed90610943565b600061078e3384846103e8565b9392505050565b61079d610285565b565b600060208083528351808285015260005b818110156107cc578581018301518582016040015282016107b0565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461082f57600080fd5b919050565b6000806040838503121561084757600080fd5b6108508361080b565b946020939093013593505050565b60008060006060848603121561087357600080fd5b61087c8461080b565b925061088a6020850161080b565b9150604084013590509250925092565b6000602082840312156108ac57600080fd5b5035919050565b6000602082840312156108c557600080fd5b61078e8261080b565b600080604083850312156108e157600080fd5b6108ea8361080b565b91506108f86020840161080b565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156103e2576103e2610901565b600181811c9082168061095757607f821691505b602082108103610990577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b818103818111156103e2576103e261090156fea164736f6c6343000813000a", } var WETH9ABI = WETH9MetaData.ABI diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index c363892b9d..fe6437f48c 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -122,4 +122,4 @@ vrfv2plus_wrapper_arbitrum: ../../contracts/solc/v0.8.19/VRFV2PlusWrapper_Arbitr vrfv2plus_wrapper_consumer_example: ../../contracts/solc/v0.8.19/VRFV2PlusWrapperConsumerExample/VRFV2PlusWrapperConsumerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapperConsumerExample/VRFV2PlusWrapperConsumerExample.bin aeb0c681fa264f90971f65cba1e8d41064948070b217c8204a80ac95e1fa2294 vrfv2plus_wrapper_load_test_consumer: ../../contracts/solc/v0.8.19/VRFV2PlusWrapperLoadTestConsumer/VRFV2PlusWrapperLoadTestConsumer.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapperLoadTestConsumer/VRFV2PlusWrapperLoadTestConsumer.bin 5ca0223d3f6f6073ddfee4f9ddca13ea5f87297eb5f800359d7a1c41d04b6776 vrfv2plus_wrapper_optimism: ../../contracts/solc/v0.8.19/VRFV2PlusWrapper_Optimism/VRFV2PlusWrapper_Optimism.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapper_Optimism/VRFV2PlusWrapper_Optimism.bin 12a8c7a96716a5472a8ca712b10ab631085d4f5eb17bd5f7e0d2412556058ce9 -weth9_wrapper: ../../contracts/solc/v0.8.19/WETH9/WETH9.abi ../../contracts/solc/v0.8.19/WETH9/WETH9.bin 7f600a1de0c02a071cb13bcf9eb1dbf11c3e3eccd1e78ed4b4ecb2960f2bb020 +weth9_wrapper: ../../contracts/solc/v0.8.19/WETH9/WETH9.abi ../../contracts/solc/v0.8.19/WETH9/WETH9.bin 393b7b1ea2d1dc5a520a60cc6736dc489726cb0bd1481ea8b22d2872d4a510b1 From 7d369d7a04a4c0cff9e646e66ad2592887d837c2 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Wed, 18 Sep 2024 13:49:25 -0700 Subject: [PATCH 374/432] chore: remove gha workflow validation (#14487) --- .github/workflows/gha-workflow-validation.yml | 31 ------------------- 1 file changed, 31 deletions(-) delete mode 100644 .github/workflows/gha-workflow-validation.yml diff --git a/.github/workflows/gha-workflow-validation.yml b/.github/workflows/gha-workflow-validation.yml deleted file mode 100644 index 1ec502432c..0000000000 --- a/.github/workflows/gha-workflow-validation.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: GHA Workflow Validation - -on: - pull_request: - -jobs: - - validate-worfklow-changes: - name: Validate Workflow Changes - permissions: - contents: read - pull-requests: write - actions: read - runs-on: ubuntu-latest - steps: - - name: GHA Workflow Validator - uses: smartcontractkit/.github/actions/gha-workflow-validator@d316f66b2990ea4daa479daa3de6fc92b00f863e # gha-workflow-validator@0.2.0 - env: - GITHUB_TOKEN: ${{ github.token }} - - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: lint-gh-workflows - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Validate Workflow Changes - continue-on-error: true From d64834afafcdc74a19b074b17a4cf49ca046ee5b Mon Sep 17 00:00:00 2001 From: Makram Date: Wed, 18 Sep 2024 23:51:52 +0300 Subject: [PATCH 375/432] integration-tests/deployment/ccip: fix assertion fns (#14482) * integration-tests/deployment/ccip: fix assertion fns * fix stringer * use getExecutionState to assert test condition --- .../deployment/ccip/test_assertions.go | 89 +++++++++++++------ 1 file changed, 64 insertions(+), 25 deletions(-) diff --git a/integration-tests/deployment/ccip/test_assertions.go b/integration-tests/deployment/ccip/test_assertions.go index 335b465d20..2041c1a977 100644 --- a/integration-tests/deployment/ccip/test_assertions.go +++ b/integration-tests/deployment/ccip/test_assertions.go @@ -37,14 +37,20 @@ func ConfirmCommitForAllWithExpectedSeqNums( srcChain := srcChain dstChain := dstChain wg.Go(func() error { - return func(src, dest uint64) error { - var startBlock *uint64 - if startBlocks != nil { - startBlock = startBlocks[dest] - } - return ConfirmCommitWithExpectedSeqNumRange(t, srcChain, dstChain, state.Chains[dest].OffRamp, startBlock, - ccipocr3.SeqNumRange{ccipocr3.SeqNum(expectedSeqNums[dest]), ccipocr3.SeqNum(expectedSeqNums[dest])}) - }(src, dest) + var startBlock *uint64 + if startBlocks != nil { + startBlock = startBlocks[dstChain.Selector] + } + return ConfirmCommitWithExpectedSeqNumRange( + t, + srcChain, + dstChain, + state.Chains[dstChain.Selector].OffRamp, + startBlock, + ccipocr3.SeqNumRange{ + ccipocr3.SeqNum(expectedSeqNums[dstChain.Selector]), + ccipocr3.SeqNum(expectedSeqNums[dstChain.Selector]), + }) }) } } @@ -131,16 +137,18 @@ func ConfirmExecWithSeqNrForAll( srcChain := srcChain dstChain := dstChain wg.Go(func() error { - return func(src, dest deployment.Chain) error { - var startBlock *uint64 - if startBlocks != nil { - startBlock = startBlocks[dest.Selector] - } - return ConfirmExecWithSeqNr( - t, src, dest, state.Chains[dest.Selector].OffRamp, startBlock, - expectedSeqNums[dstChain.Selector], - ) - }(srcChain, dstChain) + var startBlock *uint64 + if startBlocks != nil { + startBlock = startBlocks[dstChain.Selector] + } + return ConfirmExecWithSeqNr( + t, + srcChain, + dstChain, + state.Chains[dstChain.Selector].OffRamp, + startBlock, + expectedSeqNums[dstChain.Selector], + ) }) } } @@ -185,19 +193,50 @@ func ConfirmExecWithSeqNr( if err != nil { return fmt.Errorf("error to get source chain config : %w", err) } - t.Logf("Waiting for ExecutionStateChanged on chain %d from chain %d with expected sequence number %d, current onchain minSeqNr: %d", - dest.Selector, source.Selector, expectedSeqNr, scc.MinSeqNr) + executionState, err := offRamp.GetExecutionState(nil, source.Selector, expectedSeqNr) + if err != nil { + return fmt.Errorf("error to get execution state : %w", err) + } + t.Logf("Waiting for ExecutionStateChanged on chain %d (offramp %s) from chain %d with expected sequence number %d, current onchain minSeqNr: %d, execution state: %s", + dest.Selector, offRamp.Address().String(), source.Selector, expectedSeqNr, scc.MinSeqNr, executionStateToString(executionState)) + if executionState == EXECUTION_STATE_SUCCESS { + t.Logf("Observed SUCCESS execution state on chain %d (offramp %s) from chain %d with expected sequence number %d", + dest.Selector, offRamp.Address().String(), source.Selector, expectedSeqNr) + return nil + } case execEvent := <-sink: if execEvent.SequenceNumber == expectedSeqNr && execEvent.SourceChainSelector == source.Selector { - t.Logf("Received ExecutionStateChanged on chain %d from chain %d with expected sequence number %d", - dest.Selector, source.Selector, expectedSeqNr) + t.Logf("Received ExecutionStateChanged on chain %d (offramp %s) from chain %d with expected sequence number %d", + dest.Selector, offRamp.Address().String(), source.Selector, expectedSeqNr) return nil } case <-timer.C: - return fmt.Errorf("timed out waiting for ExecutionStateChanged on chain %d from chain %d with expected sequence number %d", - dest.Selector, source.Selector, expectedSeqNr) + return fmt.Errorf("timed out waiting for ExecutionStateChanged on chain %d (offramp %s) from chain %d with expected sequence number %d", + dest.Selector, offRamp.Address().String(), source.Selector, expectedSeqNr) case subErr := <-subscription.Err(): - return fmt.Errorf("Subscription error: %w", subErr) + return fmt.Errorf("subscription error: %w", subErr) } } } + +const ( + EXECUTION_STATE_UNTOUCHED = 0 + EXECUTION_STATE_INPROGRESS = 1 + EXECUTION_STATE_SUCCESS = 2 + EXECUTION_STATE_FAILURE = 3 +) + +func executionStateToString(state uint8) string { + switch state { + case EXECUTION_STATE_UNTOUCHED: + return "UNTOUCHED" + case EXECUTION_STATE_INPROGRESS: + return "IN_PROGRESS" + case EXECUTION_STATE_SUCCESS: + return "SUCCESS" + case EXECUTION_STATE_FAILURE: + return "FAILURE" + default: + return "UNKNOWN" + } +} From 328b62ae5067619e59da42f6db6703d3b327f1a2 Mon Sep 17 00:00:00 2001 From: ilija42 <57732589+ilija42@users.noreply.github.com> Date: Wed, 18 Sep 2024 23:36:16 +0200 Subject: [PATCH 376/432] [BCFR-203] Improve CR value comparator querying (topics and data words) by doing encoding in the relayer (#14207) * Add EVM CR topic and data words types to codec for QueryKey filtering * temp * Update Chain Reader Tester contract to match common testing structs * Fix codecEntry ToNative() method bad error message * Add support for filtering over indexed topics with query key * Remove the need for Chain Reader Config InputFields - Params are typed into all topics and checked for nil - Allows for searching same read with diff params - Allows to query filter and GetLatestValue same event * Implement Chain Reader data words types init and packing * cleanup changes * Implement querying by data words with value comparators as any * Fix CR topic querying and simplify value comparator encoding * Simplify CR event topic and data words typing * Refactor CR topic encoding a bit to be simpler * Fix lint, changeset and correct a minor test failure * [Bot] Update changeset file with jira issue * Add changeset * Update changesets * lint * Separate loop and non loop CR tests, bump go mod and minor fix * Fix rebase issues * Handle CR value comparator Querying codec type creation and lookup * Update changeset associated ticket numbers * lint * Add todos * Remove unused indexes from ChainReader DataWords config * Update common * Bump common --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .changeset/lucky-zebras-reflect.md | 7 + contracts/.changeset/fluffy-papayas-chew.md | 8 + .../shared/test/helpers/ChainReaderTester.sol | 6 +- .../ccip/configs/evm/contract_reader.go | 5 - core/chains/evm/logpoller/orm_test.go | 40 +- core/chains/evm/logpoller/parser.go | 31 +- core/chains/evm/logpoller/parser_test.go | 16 +- .../chain_reader_tester.go | 22 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- core/scripts/go.mod | 10 +- core/scripts/go.sum | 20 +- .../relay/evm/chain_components_test.go | 6 +- core/services/relay/evm/chain_reader.go | 221 ++++--- ...n_reader_historical_client_wrapper_test.go | 7 +- core/services/relay/evm/chain_writer.go | 4 +- core/services/relay/evm/codec/codec.go | 8 + .../chain_components_interface_tester.go | 13 +- .../relay/evm/evmtesting/run_tests.go | 42 ++ core/services/relay/evm/read/batch.go | 13 +- core/services/relay/evm/read/bindings.go | 21 +- core/services/relay/evm/read/bindings_test.go | 6 +- core/services/relay/evm/read/event.go | 614 ++++++++++-------- core/services/relay/evm/read/method.go | 5 +- core/services/relay/evm/types/codec_entry.go | 10 +- core/services/relay/evm/types/types.go | 8 +- core/services/relay/evm/types/types_test.go | 5 +- go.mod | 10 +- go.sum | 20 +- integration-tests/go.mod | 10 +- integration-tests/go.sum | 20 +- integration-tests/load/go.mod | 10 +- integration-tests/load/go.sum | 20 +- 32 files changed, 701 insertions(+), 539 deletions(-) create mode 100644 .changeset/lucky-zebras-reflect.md create mode 100644 contracts/.changeset/fluffy-papayas-chew.md diff --git a/.changeset/lucky-zebras-reflect.md b/.changeset/lucky-zebras-reflect.md new file mode 100644 index 0000000000..2d4c875f64 --- /dev/null +++ b/.changeset/lucky-zebras-reflect.md @@ -0,0 +1,7 @@ +--- +"chainlink": minor +--- + +#internal Implement EVM ChainReader ValueComparator filtering by non-indexed event data. Right now only simple non indexed data where byte offsets don't exist is supported. + +BCFR-203 \ No newline at end of file diff --git a/contracts/.changeset/fluffy-papayas-chew.md b/contracts/.changeset/fluffy-papayas-chew.md new file mode 100644 index 0000000000..b76e41cfbe --- /dev/null +++ b/contracts/.changeset/fluffy-papayas-chew.md @@ -0,0 +1,8 @@ +--- +'@chainlink/contracts': minor +--- + +#internal Change Chain Reader testing contract Triggered event for easier testing of filtering by non indexed evm data. + + +BCFR-203 \ No newline at end of file diff --git a/contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol b/contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol index 709d00cc38..e3b277119a 100644 --- a/contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol +++ b/contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol @@ -26,11 +26,11 @@ struct InnerTestStruct { contract ChainReaderTester { event Triggered( int32 indexed field, - string differentField, uint8 oracleId, uint8[32] oracleIds, address Account, address[] Accounts, + string differentField, int192 bigField, MidLevelTestStruct nestedStruct ); @@ -109,15 +109,15 @@ contract ChainReaderTester { function triggerEvent( int32 field, - string calldata differentField, uint8 oracleId, uint8[32] calldata oracleIds, address account, address[] calldata accounts, + string calldata differentField, int192 bigField, MidLevelTestStruct calldata nestedStruct ) public { - emit Triggered(field, differentField, oracleId, oracleIds, account, accounts, bigField, nestedStruct); + emit Triggered(field, oracleId, oracleIds, account, accounts, differentField, bigField, nestedStruct); } function triggerEventWithDynamicTopic(string calldata field) public { diff --git a/core/capabilities/ccip/configs/evm/contract_reader.go b/core/capabilities/ccip/configs/evm/contract_reader.go index 7b04b42e8d..18aa07cc02 100644 --- a/core/capabilities/ccip/configs/evm/contract_reader.go +++ b/core/capabilities/ccip/configs/evm/contract_reader.go @@ -194,11 +194,6 @@ var SourceReaderConfig = evmrelaytypes.ChainReaderConfig{ consts.EventNameCCIPMessageSent: { ChainSpecificName: mustGetEventName("CCIPMessageSent", onrampABI), ReadType: evmrelaytypes.Event, - EventDefinitions: &evmrelaytypes.EventDefinitions{ - GenericDataWordNames: map[string]uint8{ - consts.EventAttributeSequenceNumber: 5, - }, - }, }, }, }, diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index f5f44acf3d..1fb20a03af 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -606,8 +606,8 @@ func TestORM_IndexedLogs(t *testing.T) { } for idx, value := range topicValues { - topicFilters.Expressions[idx] = logpoller.NewEventByTopicFilter(topicIdx, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(value).Hex(), Operator: primitives.Eq}, + topicFilters.Expressions[idx] = logpoller.NewEventByTopicFilter(topicIdx, []logpoller.HashedValueComparator{ + {Value: logpoller.EvmWord(value), Operator: primitives.Eq}, }) } @@ -702,8 +702,8 @@ func TestORM_IndexedLogs(t *testing.T) { Expressions: []query.Expression{ logpoller.NewAddressFilter(addr), logpoller.NewEventSigFilter(eventSig), - logpoller.NewEventByTopicFilter(1, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(2).Hex(), Operator: primitives.Gte}, + logpoller.NewEventByTopicFilter(1, []logpoller.HashedValueComparator{ + {Value: logpoller.EvmWord(2), Operator: primitives.Gte}, }), query.Confidence(primitives.Unconfirmed), }, @@ -717,11 +717,11 @@ func TestORM_IndexedLogs(t *testing.T) { return []query.Expression{ logpoller.NewAddressFilter(addr), logpoller.NewEventSigFilter(eventSig), - logpoller.NewEventByTopicFilter(topicIdx, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(min).Hex(), Operator: primitives.Gte}, + logpoller.NewEventByTopicFilter(topicIdx, []logpoller.HashedValueComparator{ + {Value: logpoller.EvmWord(min), Operator: primitives.Gte}, }), - logpoller.NewEventByTopicFilter(topicIdx, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(max).Hex(), Operator: primitives.Lte}, + logpoller.NewEventByTopicFilter(topicIdx, []logpoller.HashedValueComparator{ + {Value: logpoller.EvmWord(max), Operator: primitives.Lte}, }), query.Confidence(primitives.Unconfirmed), } @@ -876,11 +876,11 @@ func TestORM_DataWords(t *testing.T) { return []query.Expression{ logpoller.NewAddressFilter(addr), logpoller.NewEventSigFilter(eventSig), - logpoller.NewEventByWordFilter(eventSig, wordIdx, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(word1).Hex(), Operator: primitives.Gte}, + logpoller.NewEventByWordFilter(wordIdx, []logpoller.HashedValueComparator{ + {Value: logpoller.EvmWord(word1), Operator: primitives.Gte}, }), - logpoller.NewEventByWordFilter(eventSig, wordIdx, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(word2).Hex(), Operator: primitives.Lte}, + logpoller.NewEventByWordFilter(wordIdx, []logpoller.HashedValueComparator{ + {Value: logpoller.EvmWord(word2), Operator: primitives.Lte}, }), query.Confidence(primitives.Unconfirmed), } @@ -944,8 +944,8 @@ func TestORM_DataWords(t *testing.T) { filter := []query.Expression{ logpoller.NewAddressFilter(addr), logpoller.NewEventSigFilter(eventSig), - logpoller.NewEventByWordFilter(eventSig, 0, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(1).Hex(), Operator: primitives.Gte}, + logpoller.NewEventByWordFilter(0, []logpoller.HashedValueComparator{ + {Value: logpoller.EvmWord(1), Operator: primitives.Gte}, }), query.Confidence(primitives.Unconfirmed), } @@ -1667,8 +1667,8 @@ func TestSelectLogsCreatedAfter(t *testing.T) { if len(topicVals) > 0 { exp := make([]query.Expression, len(topicVals)) for idx, val := range topicVals { - exp[idx] = logpoller.NewEventByTopicFilter(uint64(topicIdx), []primitives.ValueComparator{ - {Value: val.String(), Operator: primitives.Eq}, + exp[idx] = logpoller.NewEventByTopicFilter(uint64(topicIdx), []logpoller.HashedValueComparator{ + {Value: val, Operator: primitives.Eq}, }) } @@ -1955,11 +1955,11 @@ func TestSelectLogsDataWordBetween(t *testing.T) { Expressions: []query.Expression{ logpoller.NewAddressFilter(address), logpoller.NewEventSigFilter(eventSig), - logpoller.NewEventByWordFilter(eventSig, 0, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(word).Hex(), Operator: primitives.Lte}, + logpoller.NewEventByWordFilter(0, []logpoller.HashedValueComparator{ + {Value: logpoller.EvmWord(word), Operator: primitives.Lte}, }), - logpoller.NewEventByWordFilter(eventSig, 1, []primitives.ValueComparator{ - {Value: logpoller.EvmWord(word).Hex(), Operator: primitives.Gte}, + logpoller.NewEventByWordFilter(1, []logpoller.HashedValueComparator{ + {Value: logpoller.EvmWord(word), Operator: primitives.Gte}, }), query.Confidence(primitives.Unconfirmed), }, diff --git a/core/chains/evm/logpoller/parser.go b/core/chains/evm/logpoller/parser.go index e08ea93da7..baa681e5ef 100644 --- a/core/chains/evm/logpoller/parser.go +++ b/core/chains/evm/logpoller/parser.go @@ -151,11 +151,11 @@ func (v *pgDSLParser) nestedConfQuery(finalized bool, confs uint64) string { } func (v *pgDSLParser) VisitEventByWordFilter(p *eventByWordFilter) { - if len(p.ValueComparers) > 0 { + if len(p.HashedValueComparers) > 0 { wordIdx := v.args.withIndexedField("word_index", p.WordIndex) - comps := make([]string, len(p.ValueComparers)) - for idx, comp := range p.ValueComparers { + comps := make([]string, len(p.HashedValueComparers)) + for idx, comp := range p.HashedValueComparers { comps[idx], v.err = makeComp(comp, v.args, "word_value", wordIdx, "substring(data from 32*:%s+1 for 32) %s :%s") if v.err != nil { return @@ -199,7 +199,7 @@ func (v *pgDSLParser) VisitConfirmationsFilter(p *confirmationsFilter) { } } -func makeComp(comp primitives.ValueComparator, args *queryArgs, field, subfield, pattern string) (string, error) { +func makeComp(comp HashedValueComparator, args *queryArgs, field, subfield, pattern string) (string, error) { cmp, err := cmpOpToString(comp.Operator) if err != nil { return "", err @@ -209,7 +209,7 @@ func makeComp(comp primitives.ValueComparator, args *queryArgs, field, subfield, pattern, subfield, cmp, - args.withIndexedField(field, common.HexToHash(comp.Value)), + args.withIndexedField(field, comp.Value), ), nil } @@ -492,17 +492,20 @@ func (f *eventSigFilter) Accept(visitor primitives.Visitor) { } } +type HashedValueComparator struct { + Value common.Hash + Operator primitives.ComparisonOperator +} + type eventByWordFilter struct { - EventSig common.Hash - WordIndex uint8 - ValueComparers []primitives.ValueComparator + WordIndex uint8 + HashedValueComparers []HashedValueComparator } -func NewEventByWordFilter(eventSig common.Hash, wordIndex uint8, valueComparers []primitives.ValueComparator) query.Expression { +func NewEventByWordFilter(wordIndex uint8, valueComparers []HashedValueComparator) query.Expression { return query.Expression{Primitive: &eventByWordFilter{ - EventSig: eventSig, - WordIndex: wordIndex, - ValueComparers: valueComparers, + WordIndex: wordIndex, + HashedValueComparers: valueComparers, }} } @@ -515,10 +518,10 @@ func (f *eventByWordFilter) Accept(visitor primitives.Visitor) { type eventByTopicFilter struct { Topic uint64 - ValueComparers []primitives.ValueComparator + ValueComparers []HashedValueComparator } -func NewEventByTopicFilter(topicIndex uint64, valueComparers []primitives.ValueComparator) query.Expression { +func NewEventByTopicFilter(topicIndex uint64, valueComparers []HashedValueComparator) query.Expression { return query.Expression{Primitive: &eventByTopicFilter{ Topic: topicIndex, ValueComparers: valueComparers, diff --git a/core/chains/evm/logpoller/parser_test.go b/core/chains/evm/logpoller/parser_test.go index 27af9e8318..f37497600b 100644 --- a/core/chains/evm/logpoller/parser_test.go +++ b/core/chains/evm/logpoller/parser_test.go @@ -233,8 +233,8 @@ func TestDSLParser(t *testing.T) { t.Run("query for event by word", func(t *testing.T) { t.Parallel() - wordFilter := NewEventByWordFilter(common.HexToHash("0x42"), 8, []primitives.ValueComparator{ - {Value: "", Operator: primitives.Gt}, + wordFilter := NewEventByWordFilter(8, []HashedValueComparator{ + {Value: common.HexToHash(""), Operator: primitives.Gt}, }) parser := &pgDSLParser{} @@ -257,9 +257,9 @@ func TestDSLParser(t *testing.T) { t.Run("query for event topic", func(t *testing.T) { t.Parallel() - topicFilter := NewEventByTopicFilter(2, []primitives.ValueComparator{ - {Value: "a", Operator: primitives.Gt}, - {Value: "b", Operator: primitives.Lt}, + topicFilter := NewEventByTopicFilter(2, []HashedValueComparator{ + {Value: common.HexToHash("a"), Operator: primitives.Gt}, + {Value: common.HexToHash("b"), Operator: primitives.Lt}, }) parser := &pgDSLParser{} @@ -321,9 +321,9 @@ func TestDSLParser(t *testing.T) { t.Run("nested query deep", func(t *testing.T) { t.Parallel() - wordFilter := NewEventByWordFilter(common.HexToHash("0x42"), 8, []primitives.ValueComparator{ - {Value: "a", Operator: primitives.Gt}, - {Value: "b", Operator: primitives.Lte}, + wordFilter := NewEventByWordFilter(8, []HashedValueComparator{ + {Value: common.HexToHash("a"), Operator: primitives.Gt}, + {Value: common.HexToHash("b"), Operator: primitives.Lte}, }) parser := &pgDSLParser{} diff --git a/core/gethwrappers/generated/chain_reader_tester/chain_reader_tester.go b/core/gethwrappers/generated/chain_reader_tester/chain_reader_tester.go index c59a6f0f0d..7adf4d8530 100644 --- a/core/gethwrappers/generated/chain_reader_tester/chain_reader_tester.go +++ b/core/gethwrappers/generated/chain_reader_tester/chain_reader_tester.go @@ -52,8 +52,8 @@ type TestStruct struct { } var ChainReaderTesterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"Triggered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"fieldHash\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"TriggeredEventWithDynamicTopic\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field1\",\"type\":\"int32\"},{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field2\",\"type\":\"int32\"},{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field3\",\"type\":\"int32\"}],\"name\":\"TriggeredWithFourTopics\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"field1\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint8[32]\",\"name\":\"field2\",\"type\":\"uint8[32]\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"field3\",\"type\":\"bytes32\"}],\"name\":\"TriggeredWithFourTopicsWithHashed\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"addTestStruct\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAlterablePrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDifferentPrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"getElementAtIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"int32\",\"name\":\"Field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"DifferentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"OracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"OracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"BigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"NestedStruct\",\"type\":\"tuple\"}],\"internalType\":\"structTestStruct\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSliceValue\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"returnSeen\",\"outputs\":[{\"components\":[{\"internalType\":\"int32\",\"name\":\"Field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"DifferentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"OracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"OracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"BigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"NestedStruct\",\"type\":\"tuple\"}],\"internalType\":\"structTestStruct\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"value\",\"type\":\"uint64\"}],\"name\":\"setAlterablePrimitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"triggerEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"triggerEventWithDynamicTopic\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field1\",\"type\":\"int32\"},{\"internalType\":\"int32\",\"name\":\"field2\",\"type\":\"int32\"},{\"internalType\":\"int32\",\"name\":\"field3\",\"type\":\"int32\"}],\"name\":\"triggerWithFourTopics\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"field1\",\"type\":\"string\"},{\"internalType\":\"uint8[32]\",\"name\":\"field2\",\"type\":\"uint8[32]\"},{\"internalType\":\"bytes32\",\"name\":\"field3\",\"type\":\"bytes32\"}],\"name\":\"triggerWithFourTopicsWithHashed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50600180548082018255600082905260048082047fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6908101805460086003958616810261010090810a8088026001600160401b0391820219909416939093179093558654808801909755848704909301805496909516909202900a91820291021990921691909117905561199c806100a96000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063a90e199811610081578063ef4e1ced1161005b578063ef4e1ced146101de578063f6f871c8146101e5578063fbe9fbf6146101f857600080fd5b8063a90e19981461019b578063ab5e0b38146101ae578063dbfd7332146101cb57600080fd5b8063679004a4116100b2578063679004a41461012a5780636c9a43b61461013f5780637f002d671461018857600080fd5b80632c45576f146100d95780633272b66c1461010257806349eac2ac14610117575b600080fd5b6100ec6100e7366004610ca3565b61020a565b6040516100f99190610e0c565b60405180910390f35b610115610110366004610f4b565b6104e5565b005b610115610125366004611060565b61053a565b61013261083d565b6040516100f99190611152565b61011561014d3660046111a0565b600280547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b610115610196366004611060565b6108c9565b6101156101a93660046112d4565b610920565b6107c65b60405167ffffffffffffffff90911681526020016100f9565b6101156101d9366004611389565b61097a565b60036101b2565b6100ec6101f3366004611060565b6109b7565b60025467ffffffffffffffff166101b2565b610212610ac0565b600061021f6001846113cc565b8154811061022f5761022f611406565b6000918252602091829020604080516101008101909152600a90920201805460030b8252600181018054929391929184019161026a90611435565b80601f016020809104026020016040519081016040528092919081815260200182805461029690611435565b80156102e35780601f106102b8576101008083540402835291602001916102e3565b820191906000526020600020905b8154815290600101906020018083116102c657829003601f168201915b5050509183525050600282015460ff166020808301919091526040805161040081018083529190930192916003850191826000855b825461010083900a900460ff1681526020600192830181810494850194909303909202910180841161031857505050928452505050600482015473ffffffffffffffffffffffffffffffffffffffff1660208083019190915260058301805460408051828502810185018252828152940193928301828280156103d157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116103a6575b5050509183525050600682015460170b6020808301919091526040805180820182526007808601805460f01b7fffff0000000000000000000000000000000000000000000000000000000000001683528351808501855260088801805490930b8152600988018054959097019693959194868301949193928401919061045690611435565b80601f016020809104026020016040519081016040528092919081815260200182805461048290611435565b80156104cf5780601f106104a4576101008083540402835291602001916104cf565b820191906000526020600020905b8154815290600101906020018083116104b257829003601f168201915b5050509190925250505090525090525092915050565b81816040516104f5929190611482565b60405180910390207f3d969732b1bbbb9f1d7eb9f3f14e4cb50a74d950b3ef916a397b85dfbab93c67838360405161052e9291906114db565b60405180910390a25050565b60006040518061010001604052808c60030b81526020018b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060ff8a166020808301919091526040805161040081810183529190930192918b9183908390808284376000920191909152505050815273ffffffffffffffffffffffffffffffffffffffff8816602080830191909152604080518883028181018401835289825291909301929189918991829190850190849080828437600092019190915250505090825250601785900b602082015260400161062c84611531565b905281546001808201845560009384526020938490208351600a9093020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909316929092178255928201519192909190820190610692908261161e565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560608201516106e09060038301906020610b0f565b5060808201516004820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117905560a08201518051610747916005840191602090910190610ba2565b5060c08201516006820180547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff90921691909117905560e082015180516007830180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660f09290921c91909117815560208083015180516008860180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff90921691909117815591810151909190600986019061082a908261161e565b5050505050505050505050505050505050565b606060018054806020026020016040519081016040528092919081815260200182805480156108bf57602002820191906000526020600020906000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff168152602001906008019060208260070104928301926001038202915080841161087a5790505b5050505050905090565b8960030b7f7188419dcd8b51877b71766f075f3626586c0ff190e7d056aa65ce9acb649a3d8a8a8a8a8a8a8a8a8a60405161090c9998979695949392919061187d565b60405180910390a250505050505050505050565b808260405161092f9190611937565b6040518091039020846040516109459190611973565b604051908190038120907f7220e4dbe4e9d0ed5f71acd022bc89c26748ac6784f2c548bc17bb8e52af34b090600090a4505050565b8060030b8260030b8460030b7f91c80dc390f3d041b3a04b0099b19634499541ea26972250986ee4b24a12fac560405160405180910390a4505050565b6109bf610ac0565b6040518061010001604052808c60030b81526020018b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060ff8a166020808301919091526040805161040081810183529190930192918b9183908390808284376000920191909152505050815273ffffffffffffffffffffffffffffffffffffffff8816602080830191909152604080518883028181018401835289825291909301929189918991829190850190849080828437600092019190915250505090825250601785900b6020820152604001610aaf84611531565b90529b9a5050505050505050505050565b6040805161010081018252600080825260606020830181905292820152908101610ae8610c1c565b8152600060208201819052606060408301819052820152608001610b0a610c3b565b905290565b600183019183908215610b925791602002820160005b83821115610b6357835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302610b25565b8015610b905782816101000a81549060ff0219169055600101602081600001049283019260010302610b63565b505b50610b9e929150610c8e565b5090565b828054828255906000526020600020908101928215610b92579160200282015b82811115610b9257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610bc2565b6040518061040001604052806020906020820280368337509192915050565b604051806040016040528060007dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001610b0a6040518060400160405280600060070b8152602001606081525090565b5b80821115610b9e5760008155600101610c8f565b600060208284031215610cb557600080fd5b5035919050565b60005b83811015610cd7578181015183820152602001610cbf565b50506000910152565b60008151808452610cf8816020860160208601610cbc565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b8060005b6020808210610d3d5750610d54565b825160ff1685529384019390910190600101610d2e565b50505050565b600081518084526020808501945080840160005b83811015610da057815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101610d6e565b509495945050505050565b7fffff00000000000000000000000000000000000000000000000000000000000081511682526000602082015160406020850152805160070b60408501526020810151905060406060850152610e046080850182610ce0565b949350505050565b60208152610e2060208201835160030b9052565b600060208301516104e0806040850152610e3e610500850183610ce0565b91506040850151610e54606086018260ff169052565b506060850151610e676080860182610d2a565b50608085015173ffffffffffffffffffffffffffffffffffffffff1661048085015260a08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085840381016104a0870152610ec48483610d5a565b935060c08701519150610edd6104c087018360170b9052565b60e0870151915080868503018387015250610ef88382610dab565b9695505050505050565b60008083601f840112610f1457600080fd5b50813567ffffffffffffffff811115610f2c57600080fd5b602083019150836020828501011115610f4457600080fd5b9250929050565b60008060208385031215610f5e57600080fd5b823567ffffffffffffffff811115610f7557600080fd5b610f8185828601610f02565b90969095509350505050565b8035600381900b8114610f9f57600080fd5b919050565b803560ff81168114610f9f57600080fd5b806104008101831015610fc757600080fd5b92915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610f9f57600080fd5b60008083601f84011261100357600080fd5b50813567ffffffffffffffff81111561101b57600080fd5b6020830191508360208260051b8501011115610f4457600080fd5b8035601781900b8114610f9f57600080fd5b60006040828403121561105a57600080fd5b50919050565b6000806000806000806000806000806104e08b8d03121561108057600080fd5b6110898b610f8d565b995060208b013567ffffffffffffffff808211156110a657600080fd5b6110b28e838f01610f02565b909b5099508991506110c660408e01610fa4565b98506110d58e60608f01610fb5565b97506110e46104608e01610fcd565b96506104808d01359150808211156110fb57600080fd5b6111078e838f01610ff1565b909650945084915061111c6104a08e01611036565b93506104c08d013591508082111561113357600080fd5b506111408d828e01611048565b9150509295989b9194979a5092959850565b6020808252825182820181905260009190848201906040850190845b8181101561119457835167ffffffffffffffff168352928401929184019160010161116e565b50909695505050505050565b6000602082840312156111b257600080fd5b813567ffffffffffffffff811681146111ca57600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611223576112236111d1565b60405290565b600082601f83011261123a57600080fd5b813567ffffffffffffffff80821115611255576112556111d1565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561129b5761129b6111d1565b816040528381528660208588010111156112b457600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600061044084860312156112ea57600080fd5b833567ffffffffffffffff8082111561130257600080fd5b61130e87838801611229565b94506020915086603f87011261132357600080fd5b6040516104008101818110838211171561133f5761133f6111d1565b60405290508061042087018881111561135757600080fd5b8388015b818110156113795761136c81610fa4565b845292840192840161135b565b5095989097509435955050505050565b60008060006060848603121561139e57600080fd5b6113a784610f8d565b92506113b560208501610f8d565b91506113c360408501610f8d565b90509250925092565b81810381811115610fc7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061144957607f821691505b60208210810361105a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000610e04602083018486611492565b80357fffff00000000000000000000000000000000000000000000000000000000000081168114610f9f57600080fd5b8035600781900b8114610f9f57600080fd5b60006040823603121561154357600080fd5b61154b611200565b611554836114ef565b8152602083013567ffffffffffffffff8082111561157157600080fd5b81850191506040823603121561158657600080fd5b61158e611200565b6115978361151f565b81526020830135828111156115ab57600080fd5b6115b736828601611229565b60208301525080602085015250505080915050919050565b601f82111561161957600081815260208120601f850160051c810160208610156115f65750805b601f850160051c820191505b8181101561161557828155600101611602565b5050505b505050565b815167ffffffffffffffff811115611638576116386111d1565b61164c816116468454611435565b846115cf565b602080601f83116001811461169f57600084156116695750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611615565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156116ec578886015182559484019460019091019084016116cd565b508582101561172857878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8183526000602080850194508260005b85811015610da05773ffffffffffffffffffffffffffffffffffffffff61176e83610fcd565b1687529582019590820190600101611748565b7fffff0000000000000000000000000000000000000000000000000000000000006117ab826114ef565b168252600060208201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126117e557600080fd5b6040602085015282016117f78161151f565b60070b604085015260208101357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe182360301811261183457600080fd5b0160208101903567ffffffffffffffff81111561185057600080fd5b80360382131561185f57600080fd5b60406060860152611874608086018284611492565b95945050505050565b60006104c08083526118928184018c8e611492565b9050602060ff808c1682860152604085018b60005b848110156118cc57836118b983610fa4565b16835291840191908401906001016118a7565b505050505073ffffffffffffffffffffffffffffffffffffffff8816610440840152828103610460840152611902818789611738565b905061191461048084018660170b9052565b8281036104a08401526119278185611781565b9c9b505050505050505050505050565b60008183825b602080821061194c5750611963565b825160ff168452928301929091019060010161193d565b5050506104008201905092915050565b60008251611985818460208701610cbc565b919091019291505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"indexed\":false,\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"Triggered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"fieldHash\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"TriggeredEventWithDynamicTopic\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field1\",\"type\":\"int32\"},{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field2\",\"type\":\"int32\"},{\"indexed\":true,\"internalType\":\"int32\",\"name\":\"field3\",\"type\":\"int32\"}],\"name\":\"TriggeredWithFourTopics\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"field1\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint8[32]\",\"name\":\"field2\",\"type\":\"uint8[32]\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"field3\",\"type\":\"bytes32\"}],\"name\":\"TriggeredWithFourTopicsWithHashed\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"addTestStruct\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAlterablePrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDifferentPrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"getElementAtIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"int32\",\"name\":\"Field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"DifferentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"OracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"OracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"BigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"NestedStruct\",\"type\":\"tuple\"}],\"internalType\":\"structTestStruct\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPrimitiveValue\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSliceValue\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"returnSeen\",\"outputs\":[{\"components\":[{\"internalType\":\"int32\",\"name\":\"Field\",\"type\":\"int32\"},{\"internalType\":\"string\",\"name\":\"DifferentField\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"OracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"OracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"Account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"Accounts\",\"type\":\"address[]\"},{\"internalType\":\"int192\",\"name\":\"BigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"NestedStruct\",\"type\":\"tuple\"}],\"internalType\":\"structTestStruct\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"value\",\"type\":\"uint64\"}],\"name\":\"setAlterablePrimitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field\",\"type\":\"int32\"},{\"internalType\":\"uint8\",\"name\":\"oracleId\",\"type\":\"uint8\"},{\"internalType\":\"uint8[32]\",\"name\":\"oracleIds\",\"type\":\"uint8[32]\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"string\",\"name\":\"differentField\",\"type\":\"string\"},{\"internalType\":\"int192\",\"name\":\"bigField\",\"type\":\"int192\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"FixedBytes\",\"type\":\"bytes2\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"IntVal\",\"type\":\"int64\"},{\"internalType\":\"string\",\"name\":\"S\",\"type\":\"string\"}],\"internalType\":\"structInnerTestStruct\",\"name\":\"Inner\",\"type\":\"tuple\"}],\"internalType\":\"structMidLevelTestStruct\",\"name\":\"nestedStruct\",\"type\":\"tuple\"}],\"name\":\"triggerEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"triggerEventWithDynamicTopic\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int32\",\"name\":\"field1\",\"type\":\"int32\"},{\"internalType\":\"int32\",\"name\":\"field2\",\"type\":\"int32\"},{\"internalType\":\"int32\",\"name\":\"field3\",\"type\":\"int32\"}],\"name\":\"triggerWithFourTopics\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"field1\",\"type\":\"string\"},{\"internalType\":\"uint8[32]\",\"name\":\"field2\",\"type\":\"uint8[32]\"},{\"internalType\":\"bytes32\",\"name\":\"field3\",\"type\":\"bytes32\"}],\"name\":\"triggerWithFourTopicsWithHashed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50600180548082018255600082905260048082047fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6908101805460086003958616810261010090810a8088026001600160401b0391820219909416939093179093558654808801909755848704909301805496909516909202900a918202910219909216919091179055611a42806100a96000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063ab5e0b3811610081578063ef4e1ced1161005b578063ef4e1ced146101de578063f6f871c8146101e5578063fbe9fbf6146101f857600080fd5b8063ab5e0b381461019b578063dbfd7332146101b8578063dd1319b3146101cb57600080fd5b8063679004a4116100b2578063679004a41461012a5780636c9a43b61461013f578063a90e19981461018857600080fd5b80632c45576f146100d95780633272b66c1461010257806349eac2ac14610117575b600080fd5b6100ec6100e7366004610ca3565b61020a565b6040516100f99190610e0c565b60405180910390f35b610115610110366004610f4b565b6104e5565b005b610115610125366004611060565b61053a565b61013261083d565b6040516100f99190611152565b61011561014d3660046111a0565b600280547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b6101156101963660046112d4565b6108c9565b6107c65b60405167ffffffffffffffff90911681526020016100f9565b6101156101c6366004611389565b610923565b6101156101d93660046113cc565b610960565b600361019f565b6100ec6101f3366004611060565b6109b7565b60025467ffffffffffffffff1661019f565b610212610ac0565b600061021f600184611471565b8154811061022f5761022f6114ab565b6000918252602091829020604080516101008101909152600a90920201805460030b8252600181018054929391929184019161026a906114da565b80601f0160208091040260200160405190810160405280929190818152602001828054610296906114da565b80156102e35780601f106102b8576101008083540402835291602001916102e3565b820191906000526020600020905b8154815290600101906020018083116102c657829003601f168201915b5050509183525050600282015460ff166020808301919091526040805161040081018083529190930192916003850191826000855b825461010083900a900460ff1681526020600192830181810494850194909303909202910180841161031857505050928452505050600482015473ffffffffffffffffffffffffffffffffffffffff1660208083019190915260058301805460408051828502810185018252828152940193928301828280156103d157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116103a6575b5050509183525050600682015460170b6020808301919091526040805180820182526007808601805460f01b7fffff0000000000000000000000000000000000000000000000000000000000001683528351808501855260088801805490930b81526009880180549590970196939591948683019491939284019190610456906114da565b80601f0160208091040260200160405190810160405280929190818152602001828054610482906114da565b80156104cf5780601f106104a4576101008083540402835291602001916104cf565b820191906000526020600020905b8154815290600101906020018083116104b257829003601f168201915b5050509190925250505090525090525092915050565b81816040516104f5929190611527565b60405180910390207f3d969732b1bbbb9f1d7eb9f3f14e4cb50a74d950b3ef916a397b85dfbab93c67838360405161052e929190611580565b60405180910390a25050565b60006040518061010001604052808c60030b81526020018b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060ff8a166020808301919091526040805161040081810183529190930192918b9183908390808284376000920191909152505050815273ffffffffffffffffffffffffffffffffffffffff8816602080830191909152604080518883028181018401835289825291909301929189918991829190850190849080828437600092019190915250505090825250601785900b602082015260400161062c846115d6565b905281546001808201845560009384526020938490208351600a9093020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90931692909217825592820151919290919082019061069290826116c3565b5060408201516002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560608201516106e09060038301906020610b0f565b5060808201516004820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117905560a08201518051610747916005840191602090910190610ba2565b5060c08201516006820180547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff90921691909117905560e082015180516007830180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660f09290921c91909117815560208083015180516008860180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff90921691909117815591810151909190600986019061082a90826116c3565b5050505050505050505050505050505050565b606060018054806020026020016040519081016040528092919081815260200182805480156108bf57602002820191906000526020600020906000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff168152602001906008019060208260070104928301926001038202915080841161087a5790505b5050505050905090565b80826040516108d891906117dd565b6040518091039020846040516108ee9190611819565b604051908190038120907f7220e4dbe4e9d0ed5f71acd022bc89c26748ac6784f2c548bc17bb8e52af34b090600090a4505050565b8060030b8260030b8460030b7f91c80dc390f3d041b3a04b0099b19634499541ea26972250986ee4b24a12fac560405160405180910390a4505050565b8960030b7f4f01af651956288a9505cdb2c7565e925522cd4bb7e31f693f331357ec7b1b5f8a8a8a8a8a8a8a8a8a6040516109a39998979695949392919061197a565b60405180910390a250505050505050505050565b6109bf610ac0565b6040518061010001604052808c60030b81526020018b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060ff8a166020808301919091526040805161040081810183529190930192918b9183908390808284376000920191909152505050815273ffffffffffffffffffffffffffffffffffffffff8816602080830191909152604080518883028181018401835289825291909301929189918991829190850190849080828437600092019190915250505090825250601785900b6020820152604001610aaf846115d6565b90529b9a5050505050505050505050565b6040805161010081018252600080825260606020830181905292820152908101610ae8610c1c565b8152600060208201819052606060408301819052820152608001610b0a610c3b565b905290565b600183019183908215610b925791602002820160005b83821115610b6357835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302610b25565b8015610b905782816101000a81549060ff0219169055600101602081600001049283019260010302610b63565b505b50610b9e929150610c8e565b5090565b828054828255906000526020600020908101928215610b92579160200282015b82811115610b9257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610bc2565b6040518061040001604052806020906020820280368337509192915050565b604051806040016040528060007dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001610b0a6040518060400160405280600060070b8152602001606081525090565b5b80821115610b9e5760008155600101610c8f565b600060208284031215610cb557600080fd5b5035919050565b60005b83811015610cd7578181015183820152602001610cbf565b50506000910152565b60008151808452610cf8816020860160208601610cbc565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b8060005b6020808210610d3d5750610d54565b825160ff1685529384019390910190600101610d2e565b50505050565b600081518084526020808501945080840160005b83811015610da057815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101610d6e565b509495945050505050565b7fffff00000000000000000000000000000000000000000000000000000000000081511682526000602082015160406020850152805160070b60408501526020810151905060406060850152610e046080850182610ce0565b949350505050565b60208152610e2060208201835160030b9052565b600060208301516104e0806040850152610e3e610500850183610ce0565b91506040850151610e54606086018260ff169052565b506060850151610e676080860182610d2a565b50608085015173ffffffffffffffffffffffffffffffffffffffff1661048085015260a08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085840381016104a0870152610ec48483610d5a565b935060c08701519150610edd6104c087018360170b9052565b60e0870151915080868503018387015250610ef88382610dab565b9695505050505050565b60008083601f840112610f1457600080fd5b50813567ffffffffffffffff811115610f2c57600080fd5b602083019150836020828501011115610f4457600080fd5b9250929050565b60008060208385031215610f5e57600080fd5b823567ffffffffffffffff811115610f7557600080fd5b610f8185828601610f02565b90969095509350505050565b8035600381900b8114610f9f57600080fd5b919050565b803560ff81168114610f9f57600080fd5b806104008101831015610fc757600080fd5b92915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610f9f57600080fd5b60008083601f84011261100357600080fd5b50813567ffffffffffffffff81111561101b57600080fd5b6020830191508360208260051b8501011115610f4457600080fd5b8035601781900b8114610f9f57600080fd5b60006040828403121561105a57600080fd5b50919050565b6000806000806000806000806000806104e08b8d03121561108057600080fd5b6110898b610f8d565b995060208b013567ffffffffffffffff808211156110a657600080fd5b6110b28e838f01610f02565b909b5099508991506110c660408e01610fa4565b98506110d58e60608f01610fb5565b97506110e46104608e01610fcd565b96506104808d01359150808211156110fb57600080fd5b6111078e838f01610ff1565b909650945084915061111c6104a08e01611036565b93506104c08d013591508082111561113357600080fd5b506111408d828e01611048565b9150509295989b9194979a5092959850565b6020808252825182820181905260009190848201906040850190845b8181101561119457835167ffffffffffffffff168352928401929184019160010161116e565b50909695505050505050565b6000602082840312156111b257600080fd5b813567ffffffffffffffff811681146111ca57600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611223576112236111d1565b60405290565b600082601f83011261123a57600080fd5b813567ffffffffffffffff80821115611255576112556111d1565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561129b5761129b6111d1565b816040528381528660208588010111156112b457600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600061044084860312156112ea57600080fd5b833567ffffffffffffffff8082111561130257600080fd5b61130e87838801611229565b94506020915086603f87011261132357600080fd5b6040516104008101818110838211171561133f5761133f6111d1565b60405290508061042087018881111561135757600080fd5b8388015b818110156113795761136c81610fa4565b845292840192840161135b565b5095989097509435955050505050565b60008060006060848603121561139e57600080fd5b6113a784610f8d565b92506113b560208501610f8d565b91506113c360408501610f8d565b90509250925092565b6000806000806000806000806000806104e08b8d0312156113ec57600080fd5b6113f58b610f8d565b995061140360208c01610fa4565b98506114128c60408d01610fb5565b97506114216104408c01610fcd565b96506104608b013567ffffffffffffffff8082111561143f57600080fd5b61144b8e838f01610ff1565b90985096506104808d013591508082111561146557600080fd5b6111078e838f01610f02565b81810381811115610fc7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c908216806114ee57607f821691505b60208210810361105a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000610e04602083018486611537565b80357fffff00000000000000000000000000000000000000000000000000000000000081168114610f9f57600080fd5b8035600781900b8114610f9f57600080fd5b6000604082360312156115e857600080fd5b6115f0611200565b6115f983611594565b8152602083013567ffffffffffffffff8082111561161657600080fd5b81850191506040823603121561162b57600080fd5b611633611200565b61163c836115c4565b815260208301358281111561165057600080fd5b61165c36828601611229565b60208301525080602085015250505080915050919050565b601f8211156116be57600081815260208120601f850160051c8101602086101561169b5750805b601f850160051c820191505b818110156116ba578281556001016116a7565b5050505b505050565b815167ffffffffffffffff8111156116dd576116dd6111d1565b6116f1816116eb84546114da565b84611674565b602080601f831160018114611744576000841561170e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556116ba565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561179157888601518255948401946001909101908401611772565b50858210156117cd57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008183825b60208082106117f25750611809565b825160ff16845292830192909101906001016117e3565b5050506104008201905092915050565b6000825161182b818460208701610cbc565b9190910192915050565b8183526000602080850194508260005b85811015610da05773ffffffffffffffffffffffffffffffffffffffff61186b83610fcd565b1687529582019590820190600101611845565b7fffff0000000000000000000000000000000000000000000000000000000000006118a882611594565b168252600060208201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126118e257600080fd5b6040602085015282016118f4816115c4565b60070b604085015260208101357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe182360301811261193157600080fd5b0160208101903567ffffffffffffffff81111561194d57600080fd5b80360382131561195c57600080fd5b60406060860152611971608086018284611537565b95945050505050565b60006104c060ff808d16845260208085018d60005b838110156119b457846119a183610fa4565b168352918301919083019060010161198f565b505050505073ffffffffffffffffffffffffffffffffffffffff8a16610420840152806104408401526119ea818401898b611835565b9050828103610460840152611a00818789611537565b9050611a1261048084018660170b9052565b8281036104a0840152611a25818561187e565b9c9b50505050505050505050505056fea164736f6c6343000813000a", } var ChainReaderTesterABI = ChainReaderTesterMetaData.ABI @@ -348,16 +348,16 @@ func (_ChainReaderTester *ChainReaderTesterTransactorSession) SetAlterablePrimit return _ChainReaderTester.Contract.SetAlterablePrimitiveValue(&_ChainReaderTester.TransactOpts, value) } -func (_ChainReaderTester *ChainReaderTesterTransactor) TriggerEvent(opts *bind.TransactOpts, field int32, differentField string, oracleId uint8, oracleIds [32]uint8, account common.Address, accounts []common.Address, bigField *big.Int, nestedStruct MidLevelTestStruct) (*types.Transaction, error) { - return _ChainReaderTester.contract.Transact(opts, "triggerEvent", field, differentField, oracleId, oracleIds, account, accounts, bigField, nestedStruct) +func (_ChainReaderTester *ChainReaderTesterTransactor) TriggerEvent(opts *bind.TransactOpts, field int32, oracleId uint8, oracleIds [32]uint8, account common.Address, accounts []common.Address, differentField string, bigField *big.Int, nestedStruct MidLevelTestStruct) (*types.Transaction, error) { + return _ChainReaderTester.contract.Transact(opts, "triggerEvent", field, oracleId, oracleIds, account, accounts, differentField, bigField, nestedStruct) } -func (_ChainReaderTester *ChainReaderTesterSession) TriggerEvent(field int32, differentField string, oracleId uint8, oracleIds [32]uint8, account common.Address, accounts []common.Address, bigField *big.Int, nestedStruct MidLevelTestStruct) (*types.Transaction, error) { - return _ChainReaderTester.Contract.TriggerEvent(&_ChainReaderTester.TransactOpts, field, differentField, oracleId, oracleIds, account, accounts, bigField, nestedStruct) +func (_ChainReaderTester *ChainReaderTesterSession) TriggerEvent(field int32, oracleId uint8, oracleIds [32]uint8, account common.Address, accounts []common.Address, differentField string, bigField *big.Int, nestedStruct MidLevelTestStruct) (*types.Transaction, error) { + return _ChainReaderTester.Contract.TriggerEvent(&_ChainReaderTester.TransactOpts, field, oracleId, oracleIds, account, accounts, differentField, bigField, nestedStruct) } -func (_ChainReaderTester *ChainReaderTesterTransactorSession) TriggerEvent(field int32, differentField string, oracleId uint8, oracleIds [32]uint8, account common.Address, accounts []common.Address, bigField *big.Int, nestedStruct MidLevelTestStruct) (*types.Transaction, error) { - return _ChainReaderTester.Contract.TriggerEvent(&_ChainReaderTester.TransactOpts, field, differentField, oracleId, oracleIds, account, accounts, bigField, nestedStruct) +func (_ChainReaderTester *ChainReaderTesterTransactorSession) TriggerEvent(field int32, oracleId uint8, oracleIds [32]uint8, account common.Address, accounts []common.Address, differentField string, bigField *big.Int, nestedStruct MidLevelTestStruct) (*types.Transaction, error) { + return _ChainReaderTester.Contract.TriggerEvent(&_ChainReaderTester.TransactOpts, field, oracleId, oracleIds, account, accounts, differentField, bigField, nestedStruct) } func (_ChainReaderTester *ChainReaderTesterTransactor) TriggerEventWithDynamicTopic(opts *bind.TransactOpts, field string) (*types.Transaction, error) { @@ -458,11 +458,11 @@ func (it *ChainReaderTesterTriggeredIterator) Close() error { type ChainReaderTesterTriggered struct { Field int32 - DifferentField string OracleId uint8 OracleIds [32]uint8 Account common.Address Accounts []common.Address + DifferentField string BigField *big.Int NestedStruct MidLevelTestStruct Raw types.Log @@ -965,7 +965,7 @@ func (_ChainReaderTester *ChainReaderTester) ParseLog(log types.Log) (generated. } func (ChainReaderTesterTriggered) Topic() common.Hash { - return common.HexToHash("0x7188419dcd8b51877b71766f075f3626586c0ff190e7d056aa65ce9acb649a3d") + return common.HexToHash("0x4f01af651956288a9505cdb2c7565e925522cd4bb7e31f693f331357ec7b1b5f") } func (ChainReaderTesterTriggeredEventWithDynamicTopic) Topic() common.Hash { @@ -1001,7 +1001,7 @@ type ChainReaderTesterInterface interface { SetAlterablePrimitiveValue(opts *bind.TransactOpts, value uint64) (*types.Transaction, error) - TriggerEvent(opts *bind.TransactOpts, field int32, differentField string, oracleId uint8, oracleIds [32]uint8, account common.Address, accounts []common.Address, bigField *big.Int, nestedStruct MidLevelTestStruct) (*types.Transaction, error) + TriggerEvent(opts *bind.TransactOpts, field int32, oracleId uint8, oracleIds [32]uint8, account common.Address, accounts []common.Address, differentField string, bigField *big.Int, nestedStruct MidLevelTestStruct) (*types.Transaction, error) TriggerEventWithDynamicTopic(opts *bind.TransactOpts, field string) (*types.Transaction, error) diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index fe6437f48c..18acf5fc30 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -24,7 +24,7 @@ batch_vrf_coordinator_v2: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/Batc batch_vrf_coordinator_v2plus: ../../contracts/solc/v0.8.19/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.19/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.bin f13715b38b5b9084b08bffa571fb1c8ef686001535902e1255052f074b31ad4e blockhash_store: ../../contracts/solc/v0.8.19/BlockhashStore/BlockhashStore.abi ../../contracts/solc/v0.8.19/BlockhashStore/BlockhashStore.bin 31b118f9577240c8834c35f8b5a1440e82a6ca8aea702970de2601824b6ab0e1 chain_module_base: ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.abi ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.bin 7a82cc28014761090185c2650239ad01a0901181f1b2b899b42ca293bcda3741 -chain_reader_tester: ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.abi ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.bin b207f9e6bf71e445a2664a602677011b87b80bf95c6352fd7869f1a9ddb08a5b +chain_reader_tester: ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.abi ../../contracts/solc/v0.8.19/ChainReaderTester/ChainReaderTester.bin 84c4223c4dbd51aafd77a6787f4b84ce80f661ce86a907c1431c5b82d633f2ad chain_specific_util_helper: ../../contracts/solc/v0.8.6/ChainSpecificUtilHelper/ChainSpecificUtilHelper.abi ../../contracts/solc/v0.8.6/ChainSpecificUtilHelper/ChainSpecificUtilHelper.bin 66eb30b0717fefe05672df5ec863c0b9a5a654623c4757307a2726d8f31e26b1 counter: ../../contracts/solc/v0.8.6/Counter/Counter.abi ../../contracts/solc/v0.8.6/Counter/Counter.bin 6ca06e000e8423573ffa0bdfda749d88236ab3da2a4cbb4a868c706da90488c9 cron_upkeep_factory_wrapper: ../../contracts/solc/v0.8.6/CronUpkeepFactory/CronUpkeepFactory.abi - dacb0f8cdf54ae9d2781c5e720fc314b32ed5e58eddccff512c75d6067292cd7 diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 59e032565f..720ceec8d1 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.20.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf + github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.1 @@ -116,7 +116,7 @@ require ( github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/esote/minmaxheap v1.0.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect - github.com/fatih/color v1.16.0 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect @@ -341,8 +341,8 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.27.0 // indirect - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect - golang.org/x/mod v0.20.0 // indirect + golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect + golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect @@ -350,7 +350,7 @@ require ( golang.org/x/term v0.24.0 // indirect golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/tools v0.25.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 8cd12f5e42..6684beddc9 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -357,8 +357,8 @@ github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+ne github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -1083,8 +1083,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 h1:xPEM9XbfZmv8N3NjZ7AX5salonll/LdXrbb8JCbA4FE= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf h1:1AlTUkT5D8HmvU9bwDoIN54/EFyOnRBl7gnXZVrYXEA= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf/go.mod h1:l8NTByXUdGGJX+vyKYI6yX1/HIpM14F8Wm9BkU3Q4Qo= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 h1:wqLXuPdiUkn7es/epKmOpB0Q0tKdA9FkYPNQZrZ+VJU= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= @@ -1376,8 +1376,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1402,8 +1402,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1614,8 +1614,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/core/services/relay/evm/chain_components_test.go b/core/services/relay/evm/chain_components_test.go index 841e2d0a7e..50c530904d 100644 --- a/core/services/relay/evm/chain_components_test.go +++ b/core/services/relay/evm/chain_components_test.go @@ -20,8 +20,8 @@ import ( "github.com/stretchr/testify/require" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + commontestutils "github.com/smartcontractkit/chainlink-common/pkg/loop/testutils" clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types" - . "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint common practice to import test mods with . "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -29,8 +29,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" - commontestutils "github.com/smartcontractkit/chainlink-common/pkg/loop/testutils" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -159,7 +157,7 @@ func TestChainComponents(t *testing.T) { // add new subtests here so that it can be run on real chains too RunChainComponentsEvmTests(t, it) - RunContractReaderInterfaceTests[*testing.T](t, commontestutils.WrapContractReaderTesterForLoop(it), false) + RunChainComponentsInLoopEvmTests[*testing.T](t, commontestutils.WrapContractReaderTesterForLoop(it)) } type helper struct { diff --git a/core/services/relay/evm/chain_reader.go b/core/services/relay/evm/chain_reader.go index 800631b858..f4d464f658 100644 --- a/core/services/relay/evm/chain_reader.go +++ b/core/services/relay/evm/chain_reader.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "maps" "reflect" "slices" "strings" @@ -50,7 +51,7 @@ var _ commontypes.ContractTypeProvider = &chainReader{} // NewChainReaderService is a constructor for ChainReader, returns nil if there is any error // Note that the ChainReaderService returned does not support anonymous events. -func NewChainReaderService(ctx context.Context, lggr logger.Logger, lp logpoller.LogPoller, ht logpoller.HeadTracker, client evmclient.Client, config types.ChainReaderConfig) (ChainReaderService, error) { +func NewChainReaderService(_ context.Context, lggr logger.Logger, lp logpoller.LogPoller, ht logpoller.HeadTracker, client evmclient.Client, config types.ChainReaderConfig) (ChainReaderService, error) { cr := &chainReader{ lggr: logger.Named(lggr, "ChainReader"), ht: ht, @@ -131,7 +132,7 @@ func (cr *chainReader) init(chainContractReaders map[string]types.ChainContractR return fmt.Errorf("%w: no read bindings added for contract: %s", commontypes.ErrInvalidConfig, contractName) } - if err := cr.bindings.SetFilter(contractName, chainContractReader.PollingFilter.ToLPFilter(eventSigsForContractFilter)); err != nil { + if err = cr.bindings.SetFilter(contractName, chainContractReader.PollingFilter.ToLPFilter(eventSigsForContractFilter)); err != nil { return err } } @@ -152,7 +153,6 @@ func (cr *chainReader) Close() error { return cr.StopOnce("ChainReader", func() error { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() - return cr.bindings.UnregisterAll(ctx, cr.lp) }) } @@ -163,6 +163,14 @@ func (cr *chainReader) HealthReport() map[string]error { return map[string]error{cr.Name(): nil} } +func (cr *chainReader) Bind(ctx context.Context, bindings []commontypes.BoundContract) error { + return cr.bindings.Bind(ctx, cr.lp, bindings) +} + +func (cr *chainReader) Unbind(ctx context.Context, bindings []commontypes.BoundContract) error { + return cr.bindings.Unbind(ctx, cr.lp, bindings) +} + func (cr *chainReader) GetLatestValue(ctx context.Context, readName string, confidenceLevel primitives.ConfidenceLevel, params any, returnVal any) error { binding, address, err := cr.bindings.GetReader(readName) if err != nil { @@ -176,14 +184,6 @@ func (cr *chainReader) BatchGetLatestValues(ctx context.Context, request commont return cr.bindings.BatchGetLatestValues(ctx, request) } -func (cr *chainReader) Bind(ctx context.Context, bindings []commontypes.BoundContract) error { - return cr.bindings.Bind(ctx, cr.lp, bindings) -} - -func (cr *chainReader) Unbind(ctx context.Context, bindings []commontypes.BoundContract) error { - return cr.bindings.Unbind(ctx, cr.lp, bindings) -} - func (cr *chainReader) QueryKey( ctx context.Context, contract commontypes.BoundContract, @@ -203,13 +203,6 @@ func (cr *chainReader) CreateContractType(readIdentifier string, forEncoding boo return cr.codec.CreateType(cr.bindings.ReadTypeIdentifier(readIdentifier, forEncoding), forEncoding) } -func WrapItemType(contractName, itemType string, isParams bool) string { - if isParams { - return fmt.Sprintf("params.%s.%s", contractName, itemType) - } - return fmt.Sprintf("return.%s.%s", contractName, itemType) -} - func (cr *chainReader) addMethod( contractName, methodName string, @@ -225,9 +218,11 @@ func (cr *chainReader) addMethod( return err } - cr.bindings.AddReader(contractName, methodName, read.NewMethodBinding(contractName, methodName, cr.client, cr.ht, confirmations, cr.lggr)) + if err = cr.bindings.AddReader(contractName, methodName, read.NewMethodBinding(contractName, methodName, cr.client, cr.ht, confirmations, cr.lggr)); err != nil { + return err + } - if err := cr.addEncoderDef(contractName, methodName, method.Inputs, method.ID, chainReaderDefinition.InputModifications); err != nil { + if err = cr.addEncoderDef(contractName, methodName, method.Inputs, method.ID, chainReaderDefinition.InputModifications); err != nil { return err } @@ -240,26 +235,20 @@ func (cr *chainReader) addEvent(contractName, eventName string, a abi.ABI, chain return fmt.Errorf("%w: event %s doesn't exist", commontypes.ErrInvalidConfig, chainReaderDefinition.ChainSpecificName) } - var inputFields []string - if chainReaderDefinition.EventDefinitions != nil { - inputFields = chainReaderDefinition.EventDefinitions.InputFields - } - - filterArgs, codecTopicInfo, indexArgNames := setupEventInput(event, inputFields) - if err := verifyEventIndexedInputsUsed(eventName, inputFields, indexArgNames); err != nil { - return err - } - - if err := codecTopicInfo.Init(); err != nil { + indexedAsUnIndexedABITypes, indexedTopicsCodecTypes, eventDWs := getEventTypes(event) + if err := indexedTopicsCodecTypes.Init(); err != nil { return err } // Encoder defs codec won't be used for encoding, but for storing caller filtering params which won't be hashed. - if err := cr.addEncoderDef(contractName, eventName, filterArgs, nil, chainReaderDefinition.InputModifications); err != nil { + err := cr.addEncoderDef(contractName, eventName, indexedAsUnIndexedABITypes, nil, chainReaderDefinition.InputModifications) + if err != nil { return err } - inputInfo, inputModifier, err := cr.getEventInput(chainReaderDefinition, contractName, eventName) + codecTypes, codecModifiers := make(map[string]types.CodecEntry), make(map[string]commoncodec.Modifier) + topicTypeID := codec.WrapItemType(contractName, eventName, true) + codecTypes[topicTypeID], codecModifiers[topicTypeID], err = cr.getEventItemTypeAndModifier(topicTypeID, chainReaderDefinition.InputModifications) if err != nil { return err } @@ -269,59 +258,113 @@ func (cr *chainReader) addEvent(contractName, eventName string, a abi.ABI, chain return err } - eb := read.NewEventBinding(contractName, eventName, cr.lp, event.ID, inputInfo, inputModifier, codecTopicInfo, confirmations) + eb := read.NewEventBinding(contractName, eventName, cr.lp, event.ID, indexedTopicsCodecTypes, confirmations) if eventDefinitions := chainReaderDefinition.EventDefinitions; eventDefinitions != nil { if eventDefinitions.PollingFilter != nil { eb.SetFilter(eventDefinitions.PollingFilter.ToLPFilter(evmtypes.HashArray{a.Events[event.Name].ID})) } - if eventDefinitions.GenericDataWordNames != nil { - eb.SetDataWords(eventDefinitions.GenericDataWordNames) + topicsDetails, topicsCodecTypeInfo, topicsModifiers, initQueryingErr := cr.initTopicQuerying(contractName, eventName, event.Inputs, eventDefinitions.GenericTopicNames, chainReaderDefinition.InputModifications) + if initQueryingErr != nil { + return initQueryingErr } + maps.Copy(codecTypes, topicsCodecTypeInfo) + // TODO BCFR-44 reused GetLatestValue params modifiers, probably can be left like this + maps.Copy(codecModifiers, topicsModifiers) + + // TODO BCFR-44 no dw modifier for now + dataWordsDetails, dWSCodecTypeInfo, initDWQueryingErr := cr.initDWQuerying(contractName, eventName, eventDWs, eventDefinitions.GenericDataWordNames) + if initDWQueryingErr != nil { + return initDWQueryingErr + } + maps.Copy(codecTypes, dWSCodecTypeInfo) - cr.addQueryingReadBindings(contractName, eventDefinitions.GenericTopicNames, event.Inputs, eb) + eb.SetTopicDetails(topicsDetails) + eb.SetDataWordsDetails(dataWordsDetails) } - cr.bindings.AddReader(contractName, eventName, eb) + eb.SetCodecTypesAndModifiers(codecTypes, codecModifiers) + if err = cr.bindings.AddReader(contractName, eventName, eb); err != nil { + return err + } return cr.addDecoderDef(contractName, eventName, event.Inputs, chainReaderDefinition.OutputModifications) } -// addQueryingReadBindings reuses the eventBinding and maps it to topic and dataWord keys used for QueryKey. -func (cr *chainReader) addQueryingReadBindings(contractName string, genericTopicNames map[string]string, eventInputs abi.Arguments, eb *read.EventBinding) { - // add topic readBindings for QueryKey +// initTopicQuerying registers codec types and modifiers for topics to be used for typing value comparator QueryKey filters. +func (cr *chainReader) initTopicQuerying(contractName, eventName string, eventInputs abi.Arguments, genericTopicNames map[string]string, inputModifications commoncodec.ModifiersConfig) (map[string]read.TopicDetail, map[string]types.CodecEntry, map[string]commoncodec.Modifier, error) { + topicsDetails := make(map[string]read.TopicDetail) + topicsTypes := make(map[string]types.CodecEntry) + topicsModifiers := make(map[string]commoncodec.Modifier) for topicIndex, topic := range eventInputs { genericTopicName, ok := genericTopicNames[topic.Name] if ok { - eb.WithTopic(genericTopicName, topic, uint64(topicIndex)) - } + // Encoder defs codec won't be used for encoding, but for storing caller filtering params which won't be hashed. + topicTypeID := eventName + "." + genericTopicName + err := cr.addEncoderDef(contractName, topicTypeID, abi.Arguments{{Type: topic.Type}}, nil, inputModifications) + if err != nil { + return nil, nil, nil, err + } - cr.bindings.AddReader(contractName, genericTopicName, eb) - } + topicTypeID = codec.WrapItemType(contractName, topicTypeID, true) + topicsTypes[topicTypeID], topicsModifiers[topicTypeID], err = cr.getEventItemTypeAndModifier(topicTypeID, inputModifications) + if err != nil { + return nil, nil, nil, err + } - // add data word readBindings for QueryKey - for genericDataWordName := range eb.GetDataWords() { - cr.bindings.AddReader(contractName, genericDataWordName, eb) + topicsDetails[genericTopicName] = read.TopicDetail{Argument: topic, Index: uint64(topicIndex + 1)} + } } + return topicsDetails, topicsTypes, topicsModifiers, nil } -// getEventInput returns codec entry for expected incoming event params and the modifier to be applied to the params. -func (cr *chainReader) getEventInput(def types.ChainReaderDefinition, contractName, eventName string) ( - types.CodecEntry, commoncodec.Modifier, error) { - inputInfo := cr.parsed.EncoderDefs[WrapItemType(contractName, eventName, true)] +// initDWQuerying registers codec types for evm data words to be used for typing value comparator QueryKey filters. +func (cr *chainReader) initDWQuerying(contractName, eventName string, eventDWs map[string]read.DataWordDetail, dWDefs map[string]string) (map[string]read.DataWordDetail, map[string]types.CodecEntry, error) { + dwsCodecTypeInfo := make(map[string]types.CodecEntry) + dWsDetail := make(map[string]read.DataWordDetail) + + for genericName, onChainName := range dWDefs { + foundDW := false + for _, dWDetail := range eventDWs { + if dWDetail.Name != onChainName { + continue + } + + foundDW = true + + dwTypeID := eventName + "." + genericName + if err := cr.addEncoderDef(contractName, dwTypeID, abi.Arguments{abi.Argument{Type: dWDetail.Type}}, nil, nil); err != nil { + return nil, nil, fmt.Errorf("%w: failed to init codec for data word %s on index %d querying for event: %q", err, genericName, dWDetail.Index, eventName) + } - // TODO can this be simplified? Isn't this same as inputInfo.Modifier()? BCI-3909 - inMod, err := def.InputModifications.ToModifier(codec.DecoderHooks...) + dwCodecTypeID := codec.WrapItemType(contractName, dwTypeID, true) + dwsCodecTypeInfo[dwCodecTypeID] = cr.parsed.EncoderDefs[dwCodecTypeID] + + dWsDetail[genericName] = dWDetail + break + } + if !foundDW { + return nil, nil, fmt.Errorf("failed to find data word: %q for event: %q, its either out of bounds or can't be searched for", genericName, eventName) + } + } + return dWsDetail, dwsCodecTypeInfo, nil +} + +// getEventItemTypeAndModifier returns codec entry for expected incoming event item and the modifier. +func (cr *chainReader) getEventItemTypeAndModifier(itemType string, inputMod commoncodec.ModifiersConfig) (types.CodecEntry, commoncodec.Modifier, error) { + inputTypeInfo := cr.parsed.EncoderDefs[itemType] + // TODO can this be simplified? Isn't this same as inputType.Modifier()? BCI-3909 + inMod, err := inputMod.ToModifier(codec.DecoderHooks...) if err != nil { return nil, nil, err } // initialize the modification - if _, err = inMod.RetypeToOffChain(reflect.PointerTo(inputInfo.CheckedType()), ""); err != nil { + if _, err = inMod.RetypeToOffChain(reflect.PointerTo(inputTypeInfo.CheckedType()), ""); err != nil { return nil, nil, err } - return inputInfo, inMod, nil + return inputTypeInfo, inMod, nil } func (cr *chainReader) addEncoderDef(contractName, itemType string, args abi.Arguments, prefix []byte, inputModifications commoncodec.ModifiersConfig) error { @@ -336,7 +379,7 @@ func (cr *chainReader) addEncoderDef(contractName, itemType string, args abi.Arg return err } - cr.parsed.EncoderDefs[WrapItemType(contractName, itemType, true)] = input + cr.parsed.EncoderDefs[codec.WrapItemType(contractName, itemType, true)] = input return nil } @@ -346,52 +389,46 @@ func (cr *chainReader) addDecoderDef(contractName, itemType string, outputs abi. return err } output := types.NewCodecEntry(outputs, nil, mod) - cr.parsed.DecoderDefs[read.WrapItemType(contractName, itemType, false)] = output + cr.parsed.DecoderDefs[codec.WrapItemType(contractName, itemType, false)] = output return output.Init() } -func verifyEventIndexedInputsUsed(eventName string, inputFields []string, indexArgNames map[string]bool) error { - for _, value := range inputFields { - if !indexArgNames[abi.ToCamelCase(value)] { - return fmt.Errorf("%w: %s is not an indexed argument of event %s", commontypes.ErrInvalidConfig, value, eventName) - } - } - return nil -} - -// setupEventInput returns abi args where indexed flag is set to false because we expect caller to filter with params that aren't hashed. -// codecEntry has expected onchain types set, for e.g. indexed topics of type string or uint8[32] array are expected as common.Hash onchain. -func setupEventInput(event abi.Event, inputFields []string) ([]abi.Argument, types.CodecEntry, map[string]bool) { - topicFieldDefs := map[string]bool{} - for _, value := range inputFields { - capFirstValue := abi.ToCamelCase(value) - topicFieldDefs[capFirstValue] = true - } - - filterArgs := make([]abi.Argument, 0, types.MaxTopicFields) - inputArgs := make([]abi.Argument, 0, len(event.Inputs)) - indexArgNames := map[string]bool{} +// getEventTypes returns abi args where indexed flag is set to false because we expect caller to filter with params that aren't hashed, +// codecEntry where expected on chain types are set, for e.g. indexed topics of type string or uint8[32] array are expected as common.Hash onchain, +// and un-indexed data info in form of evm indexed 32 byte data words. +func getEventTypes(event abi.Event) ([]abi.Argument, types.CodecEntry, map[string]read.DataWordDetail) { + indexedAsUnIndexedTypes := make([]abi.Argument, 0, types.MaxTopicFields) + indexedTypes := make([]abi.Argument, 0, len(event.Inputs)) + dataWords := make(map[string]read.DataWordDetail) + hadDynamicType := false + var dwIndex uint8 for _, input := range event.Inputs { if !input.Indexed { - continue - } + // there are some cases where we can calculate the exact data word index even if there was a dynamic type before, but it is complex and probably not needed. + if input.Type.T == abi.TupleTy || input.Type.T == abi.SliceTy || input.Type.T == abi.StringTy || input.Type.T == abi.BytesTy { + hadDynamicType = true + } + if hadDynamicType { + continue + } - filterWith := topicFieldDefs[abi.ToCamelCase(input.Name)] - if filterWith { - // When presenting the filter off-chain, - // the user will provide the unhashed version of the input - // The reader will hash topics if needed. - inputUnindexed := input - inputUnindexed.Indexed = false - filterArgs = append(filterArgs, inputUnindexed) + dataWords[event.Name+"."+input.Name] = read.DataWordDetail{ + Index: dwIndex, + Argument: input, + } + dwIndex++ + continue } - inputArgs = append(inputArgs, input) - indexArgNames[abi.ToCamelCase(input.Name)] = true + indexedAsUnIndexed := input + indexedAsUnIndexed.Indexed = false + // when presenting the filter off-chain, the caller will provide the unHashed version of the input and CR will hash topics when needed. + indexedAsUnIndexedTypes = append(indexedAsUnIndexedTypes, indexedAsUnIndexed) + indexedTypes = append(indexedTypes, input) } - return filterArgs, types.NewCodecEntry(inputArgs, nil, nil), indexArgNames + return indexedAsUnIndexedTypes, types.NewCodecEntry(indexedTypes, nil, nil), dataWords } // ConfirmationsFromConfig maps chain agnostic confidence levels defined in config to predefined EVM finality. diff --git a/core/services/relay/evm/chain_reader_historical_client_wrapper_test.go b/core/services/relay/evm/chain_reader_historical_client_wrapper_test.go index 6779b5d020..28984779c3 100644 --- a/core/services/relay/evm/chain_reader_historical_client_wrapper_test.go +++ b/core/services/relay/evm/chain_reader_historical_client_wrapper_test.go @@ -18,7 +18,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/read" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -69,8 +68,8 @@ func (cwh *ClientWithContractHistory) Init(_ context.Context, config types.Chain return err } - parsedTypes.EncoderDefs[read.WrapItemType(contractName, genericName, true)] = input - parsedTypes.DecoderDefs[read.WrapItemType(contractName, genericName, false)] = output + parsedTypes.EncoderDefs[codec.WrapItemType(contractName, genericName, true)] = input + parsedTypes.DecoderDefs[codec.WrapItemType(contractName, genericName, false)] = output } } @@ -126,7 +125,7 @@ func (cwh *ClientWithContractHistory) CallContract(ctx context.Context, msg ethe } // encode the expected call to compare with the actual call - dataToCmp, err := cwh.codec.Encode(ctx, valAndCall.Params, read.WrapItemType(valAndCall.ContractName, valAndCall.ReadName, true)) + dataToCmp, err := cwh.codec.Encode(ctx, valAndCall.Params, codec.WrapItemType(valAndCall.ContractName, valAndCall.ReadName, true)) if err != nil { return nil, err } diff --git a/core/services/relay/evm/chain_writer.go b/core/services/relay/evm/chain_writer.go index fddd865dbb..d61c17b2ae 100644 --- a/core/services/relay/evm/chain_writer.go +++ b/core/services/relay/evm/chain_writer.go @@ -101,7 +101,7 @@ func (w *chainWriter) SubmitTransaction(ctx context.Context, contract, method st return fmt.Errorf("method config not found: %v", method) } - calldata, err := w.encoder.Encode(ctx, args, WrapItemType(contract, method, true)) + calldata, err := w.encoder.Encode(ctx, args, codec.WrapItemType(contract, method, true)) if err != nil { return fmt.Errorf("%w: failed to encode args", err) } @@ -173,7 +173,7 @@ func (w *chainWriter) parseContracts() error { return fmt.Errorf("%w: failed to init codec entry for method %s", err, method) } - w.parsedContracts.EncoderDefs[WrapItemType(contract, method, true)] = input + w.parsedContracts.EncoderDefs[codec.WrapItemType(contract, method, true)] = input } } diff --git a/core/services/relay/evm/codec/codec.go b/core/services/relay/evm/codec/codec.go index 5cd606755c..3a859c89a8 100644 --- a/core/services/relay/evm/codec/codec.go +++ b/core/services/relay/evm/codec/codec.go @@ -96,6 +96,14 @@ func (c *evmCodec) CreateType(itemType string, forEncoding bool) (any, error) { return reflect.New(def.CheckedType()).Interface(), nil } +func WrapItemType(contractName, itemType string, isParams bool) string { + if isParams { + return fmt.Sprintf("params.%s.%s", contractName, itemType) + } + + return fmt.Sprintf("return.%s.%s", contractName, itemType) +} + var bigIntType = reflect.TypeOf((*big.Int)(nil)) func sizeVerifyBigIntHook(from, to reflect.Type, data any) (any, error) { diff --git a/core/services/relay/evm/evmtesting/chain_components_interface_tester.go b/core/services/relay/evm/evmtesting/chain_components_interface_tester.go index facef2bb7e..df34d63fc4 100644 --- a/core/services/relay/evm/evmtesting/chain_components_interface_tester.go +++ b/core/services/relay/evm/evmtesting/chain_components_interface_tester.go @@ -15,7 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/codec" clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types" . "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint common practice to import test mods with . - primitives "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" @@ -135,6 +135,10 @@ func (it *EVMChainComponentsInterfaceTester[T]) Setup(t T) { EventName: { ChainSpecificName: "Triggered", ReadType: types.Event, + EventDefinitions: &types.EventDefinitions{ + GenericTopicNames: map[string]string{"field": "Field"}, + GenericDataWordNames: map[string]string{"OracleID": "oracleId"}, + }, OutputModifications: codec.ModifiersConfig{ &codec.RenameModifierConfig{Fields: map[string]string{"NestedStruct.Inner.IntVal": "I"}}, }, @@ -142,13 +146,11 @@ func (it *EVMChainComponentsInterfaceTester[T]) Setup(t T) { EventWithFilterName: { ChainSpecificName: "Triggered", ReadType: types.Event, - EventDefinitions: &types.EventDefinitions{InputFields: []string{"Field"}}, }, triggerWithDynamicTopic: { ChainSpecificName: triggerWithDynamicTopic, ReadType: types.Event, EventDefinitions: &types.EventDefinitions{ - InputFields: []string{"fieldHash"}, // No specific reason for filter being defined here instead of on contract level, this is just for test case variety. PollingFilter: &types.PollingFilter{}, }, @@ -160,7 +162,6 @@ func (it *EVMChainComponentsInterfaceTester[T]) Setup(t T) { ChainSpecificName: triggerWithAllTopics, ReadType: types.Event, EventDefinitions: &types.EventDefinitions{ - InputFields: []string{"Field1", "Field2", "Field3"}, PollingFilter: &types.PollingFilter{}, }, // This doesn't have to be here, since the defalt mapping would work, but is left as an example. @@ -171,9 +172,7 @@ func (it *EVMChainComponentsInterfaceTester[T]) Setup(t T) { triggerWithAllTopicsWithHashed: { ChainSpecificName: triggerWithAllTopicsWithHashed, ReadType: types.Event, - EventDefinitions: &types.EventDefinitions{ - InputFields: []string{"Field1", "Field2", "Field3"}, - }, + EventDefinitions: &types.EventDefinitions{}, }, MethodReturningSeenStruct: { ChainSpecificName: "returnSeen", diff --git a/core/services/relay/evm/evmtesting/run_tests.go b/core/services/relay/evm/evmtesting/run_tests.go index cb68a1b887..c999693de5 100644 --- a/core/services/relay/evm/evmtesting/run_tests.go +++ b/core/services/relay/evm/evmtesting/run_tests.go @@ -12,7 +12,9 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types" clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/read" . "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint common practice to import test mods with . @@ -23,6 +25,11 @@ func RunChainComponentsEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterf // Add ChainWriter tests here } +func RunChainComponentsInLoopEvmTests[T TestingT[T]](t T, it ChainComponentsInterfaceTester[T]) { + RunContractReaderInLoopTests[T](t, it) + // Add ChainWriter tests here +} + func RunContractReaderEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfaceTester[T]) { RunContractReaderInterfaceTests[T](t, it, false) @@ -142,6 +149,41 @@ func RunContractReaderEvmTests[T TestingT[T]](t T, it *EVMChainComponentsInterfa }) } +func RunContractReaderInLoopTests[T TestingT[T]](t T, it ChainComponentsInterfaceTester[T]) { + RunContractReaderInterfaceTests[T](t, it, false) + + t.Run("Filtering can be done on data words using value comparator", func(t T) { + it.Setup(t) + + ctx := tests.Context(t) + cr := it.GetContractReader(t) + require.NoError(t, cr.Bind(ctx, it.GetBindings(t))) + bindings := it.GetBindings(t) + boundContract := BindingsByName(bindings, AnyContractName)[0] + require.NoError(t, cr.Bind(ctx, bindings)) + + ts1 := CreateTestStruct[T](0, it) + _ = SubmitTransactionToCW(t, it, MethodTriggeringEvent, ts1, boundContract, types.Unconfirmed) + ts2 := CreateTestStruct[T](15, it) + _ = SubmitTransactionToCW(t, it, MethodTriggeringEvent, ts2, boundContract, types.Unconfirmed) + ts3 := CreateTestStruct[T](35, it) + _ = SubmitTransactionToCW(t, it, MethodTriggeringEvent, ts3, boundContract, types.Unconfirmed) + + ts := &TestStruct{} + assert.Eventually(t, func() bool { + sequences, err := cr.QueryKey(ctx, boundContract, query.KeyFilter{Key: EventName, Expressions: []query.Expression{ + query.Comparator("OracleID", + primitives.ValueComparator{ + Value: uint8(ts2.OracleID), + Operator: primitives.Eq, + }), + }, + }, query.LimitAndSort{}, ts) + return err == nil && len(sequences) == 1 && reflect.DeepEqual(&ts2, sequences[0].Data) + }, it.MaxWaitTimeForEvents(), time.Millisecond*10) + }) +} + func triggerFourTopics[T TestingT[T]](t T, it *EVMChainComponentsInterfaceTester[T], i1, i2, i3 int32) { type DynamicEvent struct { Field1 int32 diff --git a/core/services/relay/evm/read/batch.go b/core/services/relay/evm/read/batch.go index 412d9a1138..1d72e22296 100644 --- a/core/services/relay/evm/read/batch.go +++ b/core/services/relay/evm/read/batch.go @@ -13,6 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" ) @@ -134,7 +135,7 @@ func (c *defaultEvmBatchCaller) batchCall(ctx context.Context, blockNumber uint6 packedOutputs := make([]string, len(batchCall)) rpcBatchCalls := make([]rpc.BatchElem, len(batchCall)) for i, call := range batchCall { - data, err := c.codec.Encode(ctx, call.Params, WrapItemType(call.ContractName, call.MethodName, true)) + data, err := c.codec.Encode(ctx, call.Params, codec.WrapItemType(call.ContractName, call.MethodName, true)) if err != nil { return nil, err } @@ -187,7 +188,7 @@ func (c *defaultEvmBatchCaller) batchCall(ctx context.Context, blockNumber uint6 return nil, fmt.Errorf("decode result %s: packedOutputs %s: %w", call, packedOutputs[i], err) } - if err = c.codec.Decode(ctx, b, call.ReturnVal, WrapItemType(call.ContractName, call.MethodName, false)); err != nil { + if err = c.codec.Decode(ctx, b, call.ReturnVal, codec.WrapItemType(call.ContractName, call.MethodName, false)); err != nil { if len(b) == 0 { results[i].err = fmt.Errorf("unpack result %s: %s: %w", call, err.Error(), errEmptyOutput) } else { @@ -314,11 +315,3 @@ func convertToBatchResult(data []dataAndErr) BatchResult { return batchResult } - -func WrapItemType(contractName, itemType string, isParams bool) string { - if isParams { - return fmt.Sprintf("params.%s.%s", contractName, itemType) - } - - return fmt.Sprintf("return.%s.%s", contractName, itemType) -} diff --git a/core/services/relay/evm/read/bindings.go b/core/services/relay/evm/read/bindings.go index 0b6ea31110..55f237af0e 100644 --- a/core/services/relay/evm/read/bindings.go +++ b/core/services/relay/evm/read/bindings.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "strings" "sync" "github.com/ethereum/go-ethereum/common" @@ -11,6 +12,7 @@ import ( commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -85,10 +87,24 @@ func (b *BindingsRegistry) GetReader(readName string) (Reader, string, error) { return binding, values.address, nil } -func (b *BindingsRegistry) AddReader(contractName, readName string, rdr Reader) { +func (b *BindingsRegistry) AddReader(contractName, readName string, rdr Reader) error { b.mu.Lock() defer b.mu.Unlock() + switch v := rdr.(type) { + case *EventBinding: + // unwrap codec type naming for event data words and topics to be used by lookup for Querying by Value Comparators + // For e.g. "params.contractName.eventName.IndexedTopic" -> "eventName.IndexedTopic" + // or "params.contractName.eventName.someFieldInData" -> "eventName.someFieldInData" + for name := range v.eventTypes { + split := strings.Split(name, ".") + if len(split) < 3 || split[1] != contractName { + return fmt.Errorf("invalid event type name %s", name) + } + b.contractLookup.addReadNameForContract(contractName, strings.Join(split[2:], ".")) + } + } + b.contractLookup.addReadNameForContract(contractName, readName) cb, cbExists := b.contractBindings[contractName] @@ -98,6 +114,7 @@ func (b *BindingsRegistry) AddReader(contractName, readName string, rdr Reader) } cb.AddReaderNamed(readName, rdr) + return nil } // Bind binds contract addresses to contract bindings and read bindings. @@ -266,7 +283,7 @@ func (b *BindingsRegistry) ReadTypeIdentifier(readName string, forEncoding bool) return "" } - return WrapItemType(values.contract, values.readName, forEncoding) + return codec.WrapItemType(values.contract, values.readName, forEncoding) } // confidenceToConfirmations matches predefined chain agnostic confidence levels to predefined EVM finality. diff --git a/core/services/relay/evm/read/bindings_test.go b/core/services/relay/evm/read/bindings_test.go index a60cc2933e..d9cfa91a98 100644 --- a/core/services/relay/evm/read/bindings_test.go +++ b/core/services/relay/evm/read/bindings_test.go @@ -42,7 +42,7 @@ func TestBindingsRegistry(t *testing.T) { named := read.NewBindingsRegistry() named.SetBatchCaller(mBatch) - named.AddReader(contractName1, methodName1, mRdr) + require.NoError(t, named.AddReader(contractName1, methodName1, mRdr)) bindings := []commontypes.BoundContract{{Address: "0x24", Name: contractName1}} _ = named.Bind(context.Background(), mReg, bindings) @@ -78,8 +78,8 @@ func TestBindingsRegistry(t *testing.T) { mRdr1.EXPECT().GetLatestValue(mock.Anything, common.HexToAddress("0x26"), mock.Anything, mock.Anything, mock.Anything).Return(nil) // part of the init phase of chain reader - named.AddReader(contractName1, methodName1, mRdr0) - named.AddReader(contractName1, methodName2, mRdr1) + require.NoError(t, named.AddReader(contractName1, methodName1, mRdr0)) + require.NoError(t, named.AddReader(contractName1, methodName2, mRdr1)) _ = named.SetFilter(contractName1, filterWithSigs) // run within the start phase of chain reader diff --git a/core/services/relay/evm/read/event.go b/core/services/relay/evm/read/event.go index 1630265ea9..03bee7472b 100644 --- a/core/services/relay/evm/read/event.go +++ b/core/services/relay/evm/read/event.go @@ -16,21 +16,24 @@ import ( commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) type EventBinding struct { // read-only properties - contractName string - eventName string - hash common.Hash - inputInfo types.CodecEntry - inputModifier commoncodec.Modifier - codecTopicInfo types.CodecEntry + contractName string + eventName string + hash common.Hash + // eventTypes has all the types for GetLatestValue unHashed indexed topics params and for QueryKey data words or unHashed indexed topics value comparators. + eventTypes map[string]types.CodecEntry + // indexedTopicsTypes has type info about hashed indexed topics. + indexedTopicsTypes types.CodecEntry + // eventModifiers only has a modifier for indexed topic filtering, but data words can also be added if needed. + eventModifiers map[string]commoncodec.Modifier // dependencies // filterRegistrar in EventBinding is to be used as an override for lp filter defined in the contract binding. @@ -40,14 +43,13 @@ type EventBinding struct { lp logpoller.LogPoller // internal properties / state - codec commontypes.RemoteCodec - bound map[common.Address]bool // bound determines if address is set to the contract binding. - mu sync.RWMutex - topics map[string]topicDetail // topics maps a generic topic name (key) to topic data - // eventDataWords maps a generic name to a word index - // key is a predefined generic name for evm log event data word - // for e.g. first evm data word(32bytes) of USDC log event is value so the key can be called value - eventDataWords map[string]uint8 + codec commontypes.RemoteCodec + bound map[common.Address]bool // bound determines if address is set to the contract binding. + mu sync.RWMutex + // topics map a generic topic name (key) to topic data + topics map[string]TopicDetail + // dataWords key is the generic dataWordNamb. + dataWords map[string]DataWordDetail confirmationsMapping map[primitives.ConfidenceLevel]evmtypes.Confirmations } @@ -55,9 +57,7 @@ func NewEventBinding( contract, event string, poller logpoller.LogPoller, hash common.Hash, - inputInfo types.CodecEntry, - inputModifier commoncodec.Modifier, - codecTopicInfo types.CodecEntry, + indexedTopicsTypes types.CodecEntry, confirmations map[primitives.ConfidenceLevel]evmtypes.Confirmations, ) *EventBinding { return &EventBinding{ @@ -65,21 +65,26 @@ func NewEventBinding( eventName: event, lp: poller, hash: hash, - inputInfo: inputInfo, - inputModifier: inputModifier, - codecTopicInfo: codecTopicInfo, + indexedTopicsTypes: indexedTopicsTypes, confirmationsMapping: confirmations, - topics: make(map[string]topicDetail), - eventDataWords: make(map[string]uint8), + topics: make(map[string]TopicDetail), + dataWords: make(map[string]DataWordDetail), bound: make(map[common.Address]bool), } } -type topicDetail struct { +type TopicDetail struct { abi.Argument Index uint64 } +// DataWordDetail contains all the information about a single evm Data word. +// For b.g. first evm data word(32bytes) of USDC log event is uint256 var called valub. +type DataWordDetail struct { + Index uint8 + abi.Argument +} + var _ Reader = &EventBinding{} func (b *EventBinding) SetCodec(codec commontypes.RemoteCodec) { @@ -89,6 +94,43 @@ func (b *EventBinding) SetCodec(codec commontypes.RemoteCodec) { b.codec = codec } +func (b *EventBinding) SetFilter(filter logpoller.Filter) { + b.mu.Lock() + defer b.mu.Unlock() + + b.registrar = newSyncedFilter() + b.registrar.SetFilter(filter) +} + +func (b *EventBinding) SetCodecTypesAndModifiers(types map[string]types.CodecEntry, modifiers map[string]commoncodec.Modifier) { + b.mu.Lock() + defer b.mu.Unlock() + + b.eventTypes = types + b.eventModifiers = modifiers +} + +func (b *EventBinding) SetDataWordsDetails(dwDetail map[string]DataWordDetail) { + b.mu.Lock() + defer b.mu.Unlock() + + b.dataWords = dwDetail +} + +func (b *EventBinding) SetTopicDetails(topicDetails map[string]TopicDetail) { + b.mu.Lock() + defer b.mu.Unlock() + + b.topics = topicDetails +} + +func (b *EventBinding) GetDataWords() map[string]DataWordDetail { + b.mu.RLock() + defer b.mu.RUnlock() + + return b.dataWords +} + func (b *EventBinding) Bind(ctx context.Context, bindings ...common.Address) error { if b.hasBindings() { // we are changing contract address reference, so we need to unregister old filter if it exists @@ -194,25 +236,44 @@ func (b *EventBinding) GetLatestValue(ctx context.Context, address common.Addres return err } - confirmations, err := confidenceToConfirmations(b.confirmationsMapping, confidenceLevel) + confs, err := confidenceToConfirmations(b.confirmationsMapping, confidenceLevel) + if err != nil { + return err + } + + topicTypeID := codec.WrapItemType(b.contractName, b.eventName, true) + + onChainTypedVal, err := b.toNativeOnChainType(topicTypeID, params) + if err != nil { + return fmt.Errorf("failed to convert params to native on chain types: %w", err) + } + + filterTopics, err := b.extractFilterTopics(topicTypeID, onChainTypedVal) if err != nil { return err } - if len(b.inputInfo.Args()) == 0 { - return b.getLatestValueWithoutFilters(ctx, address, confirmations, into) + var log *logpoller.Log + if len(filterTopics) != 0 { + var hashedTopics []common.Hash + hashedTopics, err = b.hashTopics(topicTypeID, filterTopics) + if err != nil { + return err + } + + if log, err = b.getLatestLog(ctx, address, confs, hashedTopics); err != nil { + return err + } + } else { + if log, err = b.lp.LatestLogByEventSigWithConfs(ctx, b.hash, address, confs); err != nil { + return wrapInternalErr(err) + } } - return b.getLatestValueWithFilters(ctx, address, confirmations, params, into) + return b.decodeLog(ctx, log, into) } -func (b *EventBinding) QueryKey( - ctx context.Context, - address common.Address, - filter query.KeyFilter, - limitAndSort query.LimitAndSort, - sequenceDataType any, -) ([]commontypes.Sequence, error) { +func (b *EventBinding) QueryKey(ctx context.Context, address common.Address, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceDataType any) ([]commontypes.Sequence, error) { if err := b.validateBound(address); err != nil { return nil, err } @@ -227,10 +288,9 @@ func (b *EventBinding) QueryKey( logpoller.NewAddressFilter(address), logpoller.NewEventSigFilter(b.hash), } - remapped.Expressions = append(defaultExpressions, remapped.Expressions...) - logs, err := b.lp.FilteredLogs(ctx, remapped.Expressions, limitAndSort, b.contractName+"-"+address.String()+""+b.eventName) + logs, err := b.lp.FilteredLogs(ctx, remapped.Expressions, limitAndSort, b.contractName+"-"+address.String()+"-"+b.eventName) if err != nil { return nil, err } @@ -243,208 +303,124 @@ func (b *EventBinding) QueryKey( return b.decodeLogsIntoSequences(ctx, logs, sequenceDataType) } -func (b *EventBinding) SetFilter(filter logpoller.Filter) { - b.mu.Lock() - defer b.mu.Unlock() - - b.registrar = newSyncedFilter() - b.registrar.SetFilter(filter) -} - -func (b *EventBinding) WithTopic(name string, topic abi.Argument, index uint64) { - b.mu.Lock() - defer b.mu.Unlock() - - b.topics[name] = topicDetail{ - Argument: topic, - Index: index, - } -} - -func (b *EventBinding) SetDataWords(eventDataWords map[string]uint8) { - b.mu.Lock() - defer b.mu.Unlock() - - b.eventDataWords = eventDataWords -} - -func (b *EventBinding) GetDataWords() map[string]uint8 { - b.mu.RLock() - defer b.mu.RUnlock() - - return b.eventDataWords -} - -func (b *EventBinding) validateBound(address common.Address) error { - b.mu.Lock() - defer b.mu.Unlock() - - bound, exists := b.bound[address] - if !exists || !bound { - return fmt.Errorf( - "%w: event %s that belongs to contract: %s, not bound", - commontypes.ErrInvalidType, - b.eventName, - b.contractName, - ) - } - - return nil -} - -func (b *EventBinding) getLatestValueWithoutFilters( - ctx context.Context, - address common.Address, - confs evmtypes.Confirmations, - into any, -) error { - log, err := b.lp.LatestLogByEventSigWithConfs(ctx, b.hash, address, confs) - if err = wrapInternalErr(err); err != nil { - return err - } - - return b.decodeLog(ctx, log, into) -} - -func (b *EventBinding) getLatestValueWithFilters( - ctx context.Context, - address common.Address, - confs evmtypes.Confirmations, - params, into any, -) error { - offChain, err := b.convertToOffChainType(params) - if err != nil { - return err - } - - checkedParams, err := b.inputModifier.TransformToOnChain(offChain, "" /* unused */) - if err != nil { - return err - } - - nativeParams, err := b.inputInfo.ToNative(reflect.ValueOf(checkedParams)) - if err != nil { - return err - } - - filtersAndIndices, err := b.encodeParams(nativeParams) +func (b *EventBinding) getLatestLog(ctx context.Context, address common.Address, confs evmtypes.Confirmations, hashedTopics []common.Hash) (*logpoller.Log, error) { + // Create limiter and filter for the query. + limiter := query.NewLimitAndSort(query.CountLimit(1), query.NewSortBySequence(query.Desc)) + topicFilters, err := createTopicFilters(hashedTopics) if err != nil { - return err + return nil, err } - remainingFilters := filtersAndIndices[1:] - - // Create limiter and filter for the query. - limiter := query.NewLimitAndSort(query.CountLimit(1), query.NewSortBySequence(query.Desc)) - filter, err := query.Where( - "", + filter, err := logpoller.Where( + topicFilters, logpoller.NewAddressFilter(address), logpoller.NewEventSigFilter(b.hash), logpoller.NewConfirmationsFilter(confs), - createTopicFilters(filtersAndIndices), ) if err != nil { - return wrapInternalErr(err) + return nil, wrapInternalErr(err) } // Gets the latest log that matches the filter and limiter. - logs, err := b.lp.FilteredLogs(ctx, filter.Expressions, limiter, b.contractName+"-"+address.String()+"-"+b.eventName) + logs, err := b.lp.FilteredLogs(ctx, filter, limiter, b.contractName+"-"+address.String()+"-"+b.eventName) if err != nil { - return wrapInternalErr(err) - } - - // TODO: there should be a better way to ask log poller to filter these - // First, you should be able to ask for as many topics to match - // Second, you should be able to get the latest only - var logToUse *logpoller.Log - for _, log := range logs { - tmp := log - if compareLogs(&tmp, logToUse) > 0 && matchesRemainingFilters(&tmp, remainingFilters) { - // copy so that it's not pointing to the changing variable - logToUse = &tmp - } + return nil, wrapInternalErr(err) } - if logToUse == nil { - return fmt.Errorf("%w: no events found", commontypes.ErrNotFound) + if len(logs) == 0 { + return nil, fmt.Errorf("%w: no events found", commontypes.ErrNotFound) } - - return b.decodeLog(ctx, logToUse, into) + return &logs[0], err } -func (b *EventBinding) convertToOffChainType(params any) (any, error) { - offChain, err := b.codec.CreateType(WrapItemType(b.contractName, b.eventName, true), true) - if err != nil { - return nil, err - } +func (b *EventBinding) decodeLogsIntoSequences(ctx context.Context, logs []logpoller.Log, into any) ([]commontypes.Sequence, error) { + sequences := make([]commontypes.Sequence, len(logs)) - if err = codec.MapstructureDecode(params, offChain); err != nil { - return nil, err - } + for idx := range logs { + sequences[idx] = commontypes.Sequence{ + Cursor: fmt.Sprintf("%s-%s-%d", logs[idx].BlockHash, logs[idx].TxHash, logs[idx].LogIndex), + Head: commontypes.Head{ + Height: fmt.Sprint(logs[idx].BlockNumber), + Hash: logs[idx].BlockHash.Bytes(), + Timestamp: uint64(logs[idx].BlockTimestamp.Unix()), + }, + } - return offChain, nil -} + var typeVal reflect.Value + + typeInto := reflect.TypeOf(into) + if typeInto.Kind() == reflect.Pointer { + typeVal = reflect.New(typeInto.Elem()) + } else { + typeVal = reflect.Indirect(reflect.New(typeInto)) + } + + // create a new value of the same type as 'into' for the data to be extracted to + sequences[idx].Data = typeVal.Interface() -func (b *EventBinding) encodeParams(item reflect.Value) ([]common.Hash, error) { - for item.Kind() == reflect.Pointer { - item = reflect.Indirect(item) + if err := b.decodeLog(ctx, &logs[idx], sequences[idx].Data); err != nil { + return nil, err + } } + return sequences, nil +} - var params []any +// extractFilterTopics extracts filter topics from input params and returns them as a slice of any. +// returned slice will retain the order of the topics and fill in missing topics with nil, if all values are nil, empty slice is returned. +func (b *EventBinding) extractFilterTopics(topicTypeID string, value any) (filterTopics []any, err error) { + item := reflect.ValueOf(value) switch item.Kind() { case reflect.Array, reflect.Slice: - native, err := codec.RepresentArray(item, b.inputInfo) + var native any + native, err = codec.RepresentArray(item, b.eventTypes[topicTypeID]) if err != nil { return nil, err } - params = []any{native} + filterTopics = []any{native} case reflect.Struct, reflect.Map: - var err error - if params, err = codec.UnrollItem(item, b.inputInfo); err != nil { + if filterTopics, err = codec.UnrollItem(item, b.eventTypes[topicTypeID]); err != nil { return nil, err } default: return nil, fmt.Errorf("%w: cannot encode kind %v", commontypes.ErrInvalidType, item.Kind()) } - // abi params allow you to Pack a pointers, but MakeTopics doesn't work with pointers. - if err := b.derefTopics(params); err != nil { - return nil, err + // check if at least one topic filter is present + for _, filterVal := range derefValues(filterTopics) { + if filterVal != nil { + return filterTopics, nil + } } - return b.makeTopics(params) + return []any{}, nil } -func (b *EventBinding) derefTopics(topics []any) error { - for i, topic := range topics { - rTopic := reflect.ValueOf(topic) - if rTopic.Kind() == reflect.Pointer { - if rTopic.IsNil() { - return fmt.Errorf( - "%w: input topic %s cannot be nil", commontypes.ErrInvalidType, b.inputInfo.Args()[i].Name) - } - - topics[i] = rTopic.Elem().Interface() +// hashTopics hashes topic filters values to match on chain indexed topics. +func (b *EventBinding) hashTopics(topicTypeID string, topics []any) ([]common.Hash, error) { + var hashableTopics []any + for i, topic := range derefValues(topics) { + if topic == nil { + continue } - } - return nil -} + // make topic value for non-fixed bytes array manually because geth MakeTopics doesn't support it + topicTyp, exists := b.eventTypes[topicTypeID] + if !exists { + return nil, fmt.Errorf("cannot find event type entry") + } -// makeTopics encodes and hashes params filtering values to match onchain indexed topics. -func (b *EventBinding) makeTopics(params []any) ([]common.Hash, error) { - // make topic value for non-fixed bytes array manually because geth MakeTopics doesn't support it - for i, topic := range params { - if abiArg := b.inputInfo.Args()[i]; abiArg.Type.T == abi.ArrayTy && (abiArg.Type.Elem != nil && abiArg.Type.Elem.T == abi.UintTy) { + if abiArg := topicTyp.Args()[i]; abiArg.Type.T == abi.ArrayTy && (abiArg.Type.Elem != nil && abiArg.Type.Elem.T == abi.UintTy) { packed, err := abi.Arguments{abiArg}.Pack(topic) if err != nil { return nil, err } - params[i] = crypto.Keccak256Hash(packed) + topic = crypto.Keccak256Hash(packed) } + + hashableTopics = append(hashableTopics, topic) } - hashes, err := abi.MakeTopics(params) + hashes, err := abi.MakeTopics(hashableTopics) if err != nil { return nil, wrapInternalErr(err) } @@ -457,11 +433,13 @@ func (b *EventBinding) makeTopics(params []any) ([]common.Hash, error) { } func (b *EventBinding) decodeLog(ctx context.Context, log *logpoller.Log, into any) error { - if err := b.codec.Decode(ctx, log.Data, into, WrapItemType(b.contractName, b.eventName, false)); err != nil { + // decode non indexed topics and apply output modifiers + if err := b.codec.Decode(ctx, log.Data, into, codec.WrapItemType(b.contractName, b.eventName, false)); err != nil { return err } - topics := make([]common.Hash, len(b.codecTopicInfo.Args())) + // decode indexed topics which is rarely useful since most indexed topic types get Keccak256 hashed and should be just used for log filtering. + topics := make([]common.Hash, len(b.indexedTopicsTypes.Args())) if len(log.Topics) < len(topics)+1 { return fmt.Errorf("%w: not enough topics to decode", commontypes.ErrInvalidType) } @@ -471,49 +449,15 @@ func (b *EventBinding) decodeLog(ctx context.Context, log *logpoller.Log, into a } topicsInto := map[string]any{} - if err := abi.ParseTopicsIntoMap(topicsInto, b.codecTopicInfo.Args(), topics); err != nil { + if err := abi.ParseTopicsIntoMap(topicsInto, b.indexedTopicsTypes.Args(), topics); err != nil { return fmt.Errorf("%w: %w", commontypes.ErrInvalidType, err) } return codec.MapstructureDecode(topicsInto, into) } -func (b *EventBinding) decodeLogsIntoSequences(ctx context.Context, logs []logpoller.Log, into any) ([]commontypes.Sequence, error) { - sequences := make([]commontypes.Sequence, len(logs)) - - for idx := range logs { - sequences[idx] = commontypes.Sequence{ - Cursor: fmt.Sprintf("%s-%s-%d", logs[idx].BlockHash, logs[idx].TxHash, logs[idx].LogIndex), - Head: commontypes.Head{ - Height: fmt.Sprint(logs[idx].BlockNumber), - Hash: logs[idx].BlockHash.Bytes(), - Timestamp: uint64(logs[idx].BlockTimestamp.Unix()), - }, - } - - var typeVal reflect.Value - - typeInto := reflect.TypeOf(into) - if typeInto.Kind() == reflect.Pointer { - typeVal = reflect.New(typeInto.Elem()) - } else { - typeVal = reflect.Indirect(reflect.New(typeInto)) - } - - // create a new value of the same type as 'into' for the data to be extracted to - sequences[idx].Data = typeVal.Interface() - - if err := b.decodeLog(ctx, &logs[idx], sequences[idx].Data); err != nil { - return nil, err - } - } - - return sequences, nil -} - -func (b *EventBinding) remap(filter query.KeyFilter) (query.KeyFilter, error) { - remapped := query.KeyFilter{} - +// remap chain agnostic primitives to chain specific logPoller primitives. +func (b *EventBinding) remap(filter query.KeyFilter) (remapped query.KeyFilter, err error) { for _, expression := range filter.Expressions { remappedExpression, err := b.remapExpression(filter.Key, expression) if err != nil { @@ -529,7 +473,6 @@ func (b *EventBinding) remap(filter query.KeyFilter) (query.KeyFilter, error) { func (b *EventBinding) remapExpression(key string, expression query.Expression) (query.Expression, error) { if !expression.IsPrimitive() { remappedBoolExpressions := make([]query.Expression, len(expression.BoolExpression.Expressions)) - for i := range expression.BoolExpression.Expressions { remapped, err := b.remapExpression(key, expression.BoolExpression.Expressions[i]) if err != nil { @@ -546,18 +489,17 @@ func (b *EventBinding) remapExpression(key string, expression query.Expression) return query.Or(remappedBoolExpressions...), nil } - return b.remapPrimitive(key, expression) + return b.remapPrimitive(expression) } -// remap chain agnostic primitives to chain specific -func (b *EventBinding) remapPrimitive(key string, expression query.Expression) (query.Expression, error) { +func (b *EventBinding) remapPrimitive(expression query.Expression) (query.Expression, error) { switch primitive := expression.Primitive.(type) { case *primitives.Comparator: - if val, ok := b.eventDataWords[primitive.Name]; ok { - return logpoller.NewEventByWordFilter(b.hash, val, primitive.ValueComparators), nil + hashedValComps, err := b.encodeComparator(primitive) + if err != nil { + return query.Expression{}, fmt.Errorf("failed to encode comparator %q: %w", primitive.Name, err) } - - return logpoller.NewEventByTopicFilter(b.topics[key].Index, primitive.ValueComparators), nil + return hashedValComps, nil case *primitives.Confidence: confirmations, err := confidenceToConfirmations(b.confirmationsMapping, primitive.ConfidenceLevel) if err != nil { @@ -570,63 +512,148 @@ func (b *EventBinding) remapPrimitive(key string, expression query.Expression) ( } } -func (b *EventBinding) hasBindings() bool { - b.mu.RLock() - defer b.mu.RUnlock() +func (b *EventBinding) encodeComparator(comparator *primitives.Comparator) (query.Expression, error) { + dwInfo, isDW := b.dataWords[comparator.Name] + if !isDW { + if _, exists := b.topics[comparator.Name]; !exists { + return query.Expression{}, fmt.Errorf("comparator name doesn't match any of the indexed topics or data words") + } + } - return len(b.bound) > 0 + var hashedValComps []logpoller.HashedValueComparator + itemType := codec.WrapItemType(b.contractName, b.eventName+"."+comparator.Name, true) + for _, valComp := range comparator.ValueComparators { + onChainTypedVal, err := b.toNativeOnChainType(itemType, valComp.Value) + if err != nil { + return query.Expression{}, fmt.Errorf("failed to convert comparator value to native on chain type: %w", err) + } + + hashedValComp := logpoller.HashedValueComparator{Operator: valComp.Operator} + if isDW { + hashedValComp.Value, err = b.encodeValComparatorDataWord(itemType, onChainTypedVal) + } else { + hashedValComp.Value, err = b.encodeValComparatorTopic(itemType, onChainTypedVal) + } + if err != nil { + return query.Expression{}, err + } + hashedValComps = append(hashedValComps, hashedValComp) + } + + if isDW { + return logpoller.NewEventByWordFilter(dwInfo.Index, hashedValComps), nil + } + + return logpoller.NewEventByTopicFilter(b.topics[comparator.Name].Index, hashedValComps), nil } -func (b *EventBinding) isBound(binding common.Address) bool { - b.mu.RLock() - defer b.mu.RUnlock() +func (b *EventBinding) encodeValComparatorDataWord(dwTypeID string, value any) (hash common.Hash, err error) { + dwTypes, exists := b.eventTypes[dwTypeID] + if !exists { + return common.Hash{}, fmt.Errorf("cannot find data word type for %s", dwTypeID) + } - _, exists := b.bound[binding] + packedArgs, err := dwTypes.Args().Pack(value) + if err != nil { + return common.Hash{}, err + } - return exists + return common.BytesToHash(packedArgs), nil } -func (b *EventBinding) addBinding(binding common.Address) { - b.mu.Lock() - defer b.mu.Unlock() +func (b *EventBinding) encodeValComparatorTopic(topicTypeID string, value any) (hash common.Hash, err error) { + hashedTopics, err := b.hashTopics(topicTypeID, []any{value}) + if err != nil { + return common.Hash{}, err + } - b.bound[binding] = true + return hashedTopics[0], nil } -func (b *EventBinding) removeBinding(binding common.Address) { - b.mu.Lock() - defer b.mu.Unlock() +// toNativeOnChainType converts value into its on chain version by applying codec modifiers, map structure hooks and abi typing. +func (b *EventBinding) toNativeOnChainType(itemType string, value any) (any, error) { + offChain, err := b.codec.CreateType(itemType, true) + if err != nil { + return nil, fmt.Errorf("failed to create type: %w", err) + } - delete(b.bound, binding) + // apply map struct evm hooks to correct incoming values + if err = codec.MapstructureDecode(value, offChain); err != nil { + return nil, err + } + + // apply modifiers if present + onChain := offChain + if modifier, exists := b.eventModifiers[itemType]; exists { + onChain, err = modifier.TransformToOnChain(offChain, "" /* unused */) + if err != nil { + return nil, fmt.Errorf("failed to apply modifiers to offchain type %T: %w", onChain, err) + } + } + + typ, exists := b.eventTypes[itemType] + if !exists { + return query.Expression{}, fmt.Errorf("cannot find event type entry") + } + + native, err := typ.ToNative(reflect.ValueOf(onChain)) + if err != nil { + return query.Expression{}, err + } + + for native.Kind() == reflect.Pointer { + native = reflect.Indirect(native) + } + + return native.Interface(), nil } -func (b *EventBinding) registered() bool { - b.mu.RLock() - defer b.mu.RUnlock() +func (b *EventBinding) validateBound(address common.Address) error { + b.mu.Lock() + defer b.mu.Unlock() - return b.registerCalled + bound, exists := b.bound[address] + if !exists || !bound { + return fmt.Errorf( + "%w: event %s that belongs to contract: %s, not bound", + commontypes.ErrInvalidType, + b.eventName, + b.contractName, + ) + } + + return nil } -func compareLogs(log, use *logpoller.Log) int64 { - if use == nil { - return 1 +func createTopicFilters(hashedTopics []common.Hash) (query.Expression, error) { + var expressions []query.Expression + for topicID, hash := range hashedTopics { + // first topic index is 1-based, so we add 1. + expressions = append(expressions, logpoller.NewEventByTopicFilter( + uint64(topicID+1), []logpoller.HashedValueComparator{{Value: hash, Operator: primitives.Eq}}, + )) } - if log.BlockNumber != use.BlockNumber { - return log.BlockNumber - use.BlockNumber + if len(expressions) == 0 { + return query.Expression{}, fmt.Errorf("%w: no topic filters found during query creation", commontypes.ErrInternal) } - return log.LogIndex - use.LogIndex + return query.And(expressions...), nil } -func matchesRemainingFilters(log *logpoller.Log, filters []common.Hash) bool { - for i, rfai := range filters { - if !reflect.DeepEqual(rfai[:], log.Topics[i+2]) { - return false +// derefValues dereferences pointers to nil values to nil. +func derefValues(topics []any) []any { + for i, topic := range topics { + rTopic := reflect.ValueOf(topic) + if rTopic.Kind() == reflect.Pointer { + if rTopic.IsNil() { + topics[i] = nil + } else { + topics[i] = rTopic.Elem().Interface() + } } } - - return true + return topics } func wrapInternalErr(err error) error { @@ -638,17 +665,42 @@ func wrapInternalErr(err error) error { if strings.Contains(errStr, "not found") || strings.Contains(errStr, "no rows") { return fmt.Errorf("%w: %w", commontypes.ErrNotFound, err) } - return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) } -func createTopicFilters(filtersAndIndices []common.Hash) query.Expression { - var expressions []query.Expression - for topicID, fai := range filtersAndIndices { - // first topic index is 1-based, so we add 1. - expressions = append(expressions, logpoller.NewEventByTopicFilter( - uint64(topicID+1), []primitives.ValueComparator{{Value: fai.Hex(), Operator: primitives.Eq}}, - )) - } - return query.And(expressions...) +func (b *EventBinding) hasBindings() bool { + b.mu.RLock() + defer b.mu.RUnlock() + + return len(b.bound) > 0 +} + +func (b *EventBinding) isBound(binding common.Address) bool { + b.mu.RLock() + defer b.mu.RUnlock() + + _, exists := b.bound[binding] + + return exists +} + +func (b *EventBinding) addBinding(binding common.Address) { + b.mu.Lock() + defer b.mu.Unlock() + + b.bound[binding] = true +} + +func (b *EventBinding) removeBinding(binding common.Address) { + b.mu.Lock() + defer b.mu.Unlock() + + delete(b.bound, binding) +} + +func (b *EventBinding) registered() bool { + b.mu.RLock() + defer b.mu.RUnlock() + + return b.registerCalled } diff --git a/core/services/relay/evm/read/method.go b/core/services/relay/evm/read/method.go index 3f29b00ce9..26a7254471 100644 --- a/core/services/relay/evm/read/method.go +++ b/core/services/relay/evm/read/method.go @@ -13,6 +13,7 @@ import ( commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/codec" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -124,7 +125,7 @@ func (b *MethodBinding) GetLatestValue(ctx context.Context, addr common.Address, return fmt.Errorf("%w: method not bound", commontypes.ErrInvalidType) } - data, err := b.codec.Encode(ctx, params, WrapItemType(b.contractName, b.method, true)) + data, err := b.codec.Encode(ctx, params, codec.WrapItemType(b.contractName, b.method, true)) if err != nil { return err } @@ -145,7 +146,7 @@ func (b *MethodBinding) GetLatestValue(ctx context.Context, addr common.Address, return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) } - return b.codec.Decode(ctx, bytes, returnVal, WrapItemType(b.contractName, b.method, false)) + return b.codec.Decode(ctx, bytes, returnVal, codec.WrapItemType(b.contractName, b.method, false)) } func (b *MethodBinding) QueryKey( diff --git a/core/services/relay/evm/types/codec_entry.go b/core/services/relay/evm/types/codec_entry.go index 9a8103cf7f..4e18f4d9f9 100644 --- a/core/services/relay/evm/types/codec_entry.go +++ b/core/services/relay/evm/types/codec_entry.go @@ -57,9 +57,15 @@ func (entry *codecEntry) NativeType() reflect.Type { return entry.nativeType } -func (entry *codecEntry) ToNative(checked reflect.Value) (reflect.Value, error) { +func (entry *codecEntry) ToNative(checked reflect.Value) (val reflect.Value, err error) { + defer func() { + if r := recover(); r != nil { + val = reflect.Value{} + err = fmt.Errorf("invalid checked value: %v", r) + } + }() if checked.Type() != reflect.PointerTo(entry.checkedType) { - return reflect.Value{}, fmt.Errorf("%w: checked type %v does not match expected type %v", commontypes.ErrInvalidType, reflect.TypeOf(checked), entry.checkedType) + return reflect.Value{}, fmt.Errorf("%w: checked type %v does not match expected type %v", commontypes.ErrInvalidType, checked.Type(), entry.checkedType) } return reflect.NewAt(entry.nativeType, checked.UnsafePointer()), nil diff --git a/core/services/relay/evm/types/types.go b/core/services/relay/evm/types/types.go index ac9690e2a6..c1f814c596 100644 --- a/core/services/relay/evm/types/types.go +++ b/core/services/relay/evm/types/types.go @@ -100,11 +100,9 @@ type EventDefinitions struct { // GenericTopicNames helps QueryingKeys not rely on EVM specific topic names. Key is chain specific name, value is generic name. // This helps us translate chain agnostic querying key "transfer-value" to EVM specific "evmTransferEvent-weiAmountTopic". GenericTopicNames map[string]string `json:"genericTopicNames,omitempty"` - // key is a predefined generic name for evm log event data word - // for e.g. first evm data word(32bytes) of USDC log event is value so the key can be called value - GenericDataWordNames map[string]uint8 `json:"genericDataWordNames,omitempty"` - // InputFields allows you to choose which indexed fields are expected from the input - InputFields []string `json:"inputFields,omitempty"` + // GenericDataWordNames key is generic name for evm log event data word that maps to on chain name. + // For e.g. first evm data word(32bytes) of USDC log event is value so the key can be called value. + GenericDataWordNames map[string]string `json:"genericDataWordDefs,omitempty"` // PollingFilter should be defined on a contract level in ContractPollingFilter, // unless event needs to override the contract level filter options. // This will create a separate log poller filter for this event. diff --git a/core/services/relay/evm/types/types_test.go b/core/services/relay/evm/types/types_test.go index 37d5e77693..11825ae5c4 100644 --- a/core/services/relay/evm/types/types_test.go +++ b/core/services/relay/evm/types/types_test.go @@ -80,7 +80,7 @@ func Test_ChainReaderConfig(t *testing.T) { } }, "configs":{ - "config1":"{\"cacheEnabled\":true,\"chainSpecificName\":\"specificName1\",\"inputModifications\":[{\"Fields\":[\"ts\"],\"Type\":\"epoch to time\"},{\"Fields\":{\"a\":\"b\"},\"Type\":\"rename\"}],\"outputModifications\":[{\"Fields\":[\"ts\"],\"Type\":\"epoch to time\"},{\"Fields\":{\"c\":\"d\"},\"Type\":\"rename\"}],\"eventDefinitions\":{\"genericTopicNames\":{\"TopicKey1\":\"TopicVal1\"},\"genericDataWordNames\":{\"DataWordKey\":1},\"inputFields\":[\"Event1\",\"Event2\"],\"pollingFilter\":{\"topic2\":[\"0x4abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52\"],\"topic3\":[\"0x5abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52\"],\"topic4\":[\"0x6abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52\"],\"retention\":\"1m0s\",\"maxLogsKept\":100,\"logsPerBlock\":10}},\"confidenceConfirmations\":{\"0.0\":0,\"1.0\":-1}}" + "config1":"{\"cacheEnabled\":true,\"chainSpecificName\":\"specificName1\",\"inputModifications\":[{\"Fields\":[\"ts\"],\"Type\":\"epoch to time\"},{\"Fields\":{\"a\":\"b\"},\"Type\":\"rename\"}],\"outputModifications\":[{\"Fields\":[\"ts\"],\"Type\":\"epoch to time\"},{\"Fields\":{\"c\":\"d\"},\"Type\":\"rename\"}],\"eventDefinitions\":{\"genericTopicNames\":{\"TopicKey1\":\"TopicVal1\"},\"genericDataWordDefs\":{\"DataWordKey\": \"DataWordKey\"},\"pollingFilter\":{\"topic2\":[\"0x4abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52\"],\"topic3\":[\"0x5abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52\"],\"topic4\":[\"0x6abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52\"],\"retention\":\"1m0s\",\"maxLogsKept\":100,\"logsPerBlock\":10}},\"confidenceConfirmations\":{\"0.0\":0,\"1.0\":-1}}" } } } @@ -128,8 +128,7 @@ func Test_ChainReaderConfig(t *testing.T) { ConfidenceConfirmations: map[string]int{"0.0": 0, "1.0": -1}, EventDefinitions: &EventDefinitions{ GenericTopicNames: map[string]string{"TopicKey1": "TopicVal1"}, - GenericDataWordNames: map[string]uint8{"DataWordKey": 1}, - InputFields: []string{"Event1", "Event2"}, + GenericDataWordNames: map[string]string{"DataWordKey": "DataWordKey"}, PollingFilter: &PollingFilter{ Topic2: evmtypes.HashArray{common.HexToHash("0x4abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52")}, Topic3: evmtypes.HashArray{common.HexToHash("0x5abbe4784b1fb071039bb9cb50b82978fb5d3ab98fb512c032e75786b93e2c52")}, diff --git a/go.mod b/go.mod index f5b4216e29..36160f8e96 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/dominikbraun/graph v0.23.0 github.com/esote/minmaxheap v1.0.0 github.com/ethereum/go-ethereum v1.13.8 - github.com/fatih/color v1.16.0 + github.com/fatih/color v1.17.0 github.com/fxamacker/cbor/v2 v2.7.0 github.com/gagliardetto/solana-go v1.8.4 github.com/getsentry/sentry-go v0.23.0 @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf + github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f @@ -104,14 +104,14 @@ require ( go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.27.0 - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa - golang.org/x/mod v0.20.0 + golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 + golang.org/x/mod v0.21.0 golang.org/x/net v0.29.0 golang.org/x/sync v0.8.0 golang.org/x/term v0.24.0 golang.org/x/text v0.18.0 golang.org/x/time v0.6.0 - golang.org/x/tools v0.24.0 + golang.org/x/tools v0.25.0 gonum.org/v1/gonum v0.15.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 diff --git a/go.sum b/go.sum index 4c05468ad6..85fdab9406 100644 --- a/go.sum +++ b/go.sum @@ -335,8 +335,8 @@ github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+ne github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -1044,8 +1044,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 h1:xPEM9XbfZmv8N3NjZ7AX5salonll/LdXrbb8JCbA4FE= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf h1:1AlTUkT5D8HmvU9bwDoIN54/EFyOnRBl7gnXZVrYXEA= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf/go.mod h1:l8NTByXUdGGJX+vyKYI6yX1/HIpM14F8Wm9BkU3Q4Qo= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 h1:wqLXuPdiUkn7es/epKmOpB0Q0tKdA9FkYPNQZrZ+VJU= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= @@ -1334,8 +1334,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1360,8 +1360,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1572,8 +1572,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 714c415086..f8317db1bd 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -39,7 +39,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf + github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 @@ -57,7 +57,7 @@ require ( go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.27.0 - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa + golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/sync v0.8.0 golang.org/x/text v0.18.0 google.golang.org/grpc v1.65.0 @@ -199,7 +199,7 @@ require ( github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect github.com/fatih/camelcase v1.0.0 // indirect - github.com/fatih/color v1.16.0 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect @@ -481,13 +481,13 @@ require ( go.uber.org/ratelimit v0.3.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/mod v0.20.0 // indirect + golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/term v0.24.0 // indirect golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/tools v0.25.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 2494576bc4..f5ad0d35cc 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -512,8 +512,8 @@ github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwo github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -1425,8 +1425,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 h1:xPEM9XbfZmv8N3NjZ7AX5salonll/LdXrbb8JCbA4FE= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf h1:1AlTUkT5D8HmvU9bwDoIN54/EFyOnRBl7gnXZVrYXEA= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf/go.mod h1:l8NTByXUdGGJX+vyKYI6yX1/HIpM14F8Wm9BkU3Q4Qo= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 h1:wqLXuPdiUkn7es/epKmOpB0Q0tKdA9FkYPNQZrZ+VJU= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= @@ -1764,8 +1764,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1790,8 +1790,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2058,8 +2058,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 673191e145..8ebb563830 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -15,7 +15,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf + github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 @@ -166,7 +166,7 @@ require ( github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect github.com/fatih/camelcase v1.0.0 // indirect - github.com/fatih/color v1.16.0 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect @@ -472,8 +472,8 @@ require ( go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.27.0 // indirect - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect - golang.org/x/mod v0.20.0 // indirect + golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect + golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect @@ -481,7 +481,7 @@ require ( golang.org/x/term v0.24.0 // indirect golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/tools v0.25.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index ee64962cb1..b3a8d08672 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -494,8 +494,8 @@ github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwo github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -1399,8 +1399,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 h1:xPEM9XbfZmv8N3NjZ7AX5salonll/LdXrbb8JCbA4FE= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf h1:1AlTUkT5D8HmvU9bwDoIN54/EFyOnRBl7gnXZVrYXEA= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240916150342-36cb47701edf/go.mod h1:l8NTByXUdGGJX+vyKYI6yX1/HIpM14F8Wm9BkU3Q4Qo= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 h1:wqLXuPdiUkn7es/epKmOpB0Q0tKdA9FkYPNQZrZ+VJU= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= @@ -1738,8 +1738,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1764,8 +1764,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2030,8 +2030,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 1a9f26932d8132c0326016d954a852faca626a05 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 18 Sep 2024 16:36:59 -0500 Subject: [PATCH 377/432] fix lint issues (#14450) --- core/chains/evm/client/config_builder.go | 2 +- core/chains/evm/config/chaintype/chaintype.go | 24 +++++++++---------- core/chains/evm/config/toml/config.go | 4 ++-- core/scripts/vrfv2plus/testnet/main.go | 4 ++-- core/scripts/vrfv2plus/testnet/proofs.go | 2 +- core/services/chainlink/config_test.go | 2 +- .../relay/evm/mercury/wsrpc/mocks/mocks.go | 1 + core/services/vrf/extraargs/types.go | 4 ++-- .../vrf/v2/coordinator_v2x_interface.go | 6 ++--- .../vrf/v2/integration_v2_plus_test.go | 2 +- tools/txtar/visitor.go | 10 ++++---- 11 files changed, 31 insertions(+), 30 deletions(-) diff --git a/core/chains/evm/client/config_builder.go b/core/chains/evm/client/config_builder.go index fa702bac11..e713ec9be2 100644 --- a/core/chains/evm/client/config_builder.go +++ b/core/chains/evm/client/config_builder.go @@ -64,7 +64,7 @@ func NewClientConfigs( chainConfig := &evmconfig.EVMConfig{ C: &toml.EVMConfig{ Chain: toml.Chain{ - ChainType: chaintype.NewChainTypeConfig(chainType), + ChainType: chaintype.NewConfig(chainType), FinalityDepth: finalityDepth, FinalityTagEnabled: finalityTagEnabled, NoNewHeadsThreshold: commonconfig.MustNewDuration(noNewHeadsThreshold), diff --git a/core/chains/evm/config/chaintype/chaintype.go b/core/chains/evm/config/chaintype/chaintype.go index 35dd214b1f..f6b84e4655 100644 --- a/core/chains/evm/config/chaintype/chaintype.go +++ b/core/chains/evm/config/chaintype/chaintype.go @@ -44,7 +44,7 @@ func (c ChainType) IsValid() bool { return false } -func ChainTypeFromSlug(slug string) ChainType { +func FromSlug(slug string) ChainType { switch slug { case "arbitrum": return ChainArbitrum @@ -79,53 +79,53 @@ func ChainTypeFromSlug(slug string) ChainType { } } -type ChainTypeConfig struct { +type Config struct { value ChainType slug string } -func NewChainTypeConfig(slug string) *ChainTypeConfig { - return &ChainTypeConfig{ - value: ChainTypeFromSlug(slug), +func NewConfig(slug string) *Config { + return &Config{ + value: FromSlug(slug), slug: slug, } } -func (c *ChainTypeConfig) MarshalText() ([]byte, error) { +func (c *Config) MarshalText() ([]byte, error) { if c == nil { return nil, nil } return []byte(c.slug), nil } -func (c *ChainTypeConfig) UnmarshalText(b []byte) error { +func (c *Config) UnmarshalText(b []byte) error { c.slug = string(b) - c.value = ChainTypeFromSlug(c.slug) + c.value = FromSlug(c.slug) return nil } -func (c *ChainTypeConfig) Slug() string { +func (c *Config) Slug() string { if c == nil { return "" } return c.slug } -func (c *ChainTypeConfig) ChainType() ChainType { +func (c *Config) ChainType() ChainType { if c == nil { return "" } return c.value } -func (c *ChainTypeConfig) String() string { +func (c *Config) String() string { if c == nil { return "" } return string(c.value) } -var ErrInvalidChainType = fmt.Errorf("must be one of %s or omitted", strings.Join([]string{ +var ErrInvalid = fmt.Errorf("must be one of %s or omitted", strings.Join([]string{ string(ChainArbitrum), string(ChainAstar), string(ChainCelo), diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index ecc278a7ec..9fb418cc8d 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -341,7 +341,7 @@ type Chain struct { AutoCreateKey *bool BlockBackfillDepth *uint32 BlockBackfillSkip *bool - ChainType *chaintype.ChainTypeConfig + ChainType *chaintype.Config FinalityDepth *uint32 FinalityTagEnabled *bool FlagsContractAddress *types.EIP55Address @@ -376,7 +376,7 @@ type Chain struct { func (c *Chain) ValidateConfig() (err error) { if !c.ChainType.ChainType().IsValid() { err = multierr.Append(err, commonconfig.ErrInvalid{Name: "ChainType", Value: c.ChainType.ChainType(), - Msg: chaintype.ErrInvalidChainType.Error()}) + Msg: chaintype.ErrInvalid.Error()}) } if c.GasEstimator.BumpTxDepth != nil && *c.GasEstimator.BumpTxDepth > *c.Transactions.MaxInFlight { diff --git a/core/scripts/vrfv2plus/testnet/main.go b/core/scripts/vrfv2plus/testnet/main.go index a37a539102..f5220f62dd 100644 --- a/core/scripts/vrfv2plus/testnet/main.go +++ b/core/scripts/vrfv2plus/testnet/main.go @@ -213,7 +213,7 @@ func main() { for i := range preSeedSlice { ps, err := proof.BigToSeed(preSeedSlice[i]) helpers.PanicErr(err) - extraArgs, err := extraargs.ExtraArgsV1(*nativePayment) + extraArgs, err := extraargs.EncodeV1(*nativePayment) helpers.PanicErr(err) preSeedData := proof.PreSeedDataV2Plus{ PreSeed: ps, @@ -308,7 +308,7 @@ func main() { helpers.PanicErr(err) parsedSubID := parseUInt256String(*subID) - extraArgs, err := extraargs.ExtraArgsV1(*nativePayment) + extraArgs, err := extraargs.EncodeV1(*nativePayment) helpers.PanicErr(err) preSeedData := proof.PreSeedDataV2Plus{ PreSeed: ps, diff --git a/core/scripts/vrfv2plus/testnet/proofs.go b/core/scripts/vrfv2plus/testnet/proofs.go index ea6943c63f..8f1cef0ca6 100644 --- a/core/scripts/vrfv2plus/testnet/proofs.go +++ b/core/scripts/vrfv2plus/testnet/proofs.go @@ -105,7 +105,7 @@ func generateProofForV2Plus(e helpers.Environment) { if !ok { helpers.PanicErr(fmt.Errorf("unable to parse subID: %s %w", *subId, err)) } - extraArgs, err := extraargs.ExtraArgsV1(*nativePayment) + extraArgs, err := extraargs.EncodeV1(*nativePayment) helpers.PanicErr(err) preSeedData := proof.PreSeedDataV2Plus{ PreSeed: preSeed, diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 8e157de904..44dc9f98ab 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -532,7 +532,7 @@ func TestConfig_Marshal(t *testing.T) { }, BlockBackfillDepth: ptr[uint32](100), BlockBackfillSkip: ptr(true), - ChainType: chaintype.NewChainTypeConfig("Optimism"), + ChainType: chaintype.NewConfig("Optimism"), FinalityDepth: ptr[uint32](42), FinalityTagEnabled: ptr[bool](false), FlagsContractAddress: mustAddress("0xae4E781a6218A8031764928E88d457937A954fC3"), diff --git a/core/services/relay/evm/mercury/wsrpc/mocks/mocks.go b/core/services/relay/evm/mercury/wsrpc/mocks/mocks.go index 3a51af02d1..e202802ea7 100644 --- a/core/services/relay/evm/mercury/wsrpc/mocks/mocks.go +++ b/core/services/relay/evm/mercury/wsrpc/mocks/mocks.go @@ -2,6 +2,7 @@ package mocks import ( "context" + grpc_connectivity "google.golang.org/grpc/connectivity" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" diff --git a/core/services/vrf/extraargs/types.go b/core/services/vrf/extraargs/types.go index eecd0bfa33..540de0f015 100644 --- a/core/services/vrf/extraargs/types.go +++ b/core/services/vrf/extraargs/types.go @@ -13,7 +13,7 @@ const boolAbiType = `[{ "type": "bool" }]` var extraArgsV1Tag = crypto.Keccak256([]byte("VRF ExtraArgsV1"))[:4] -func FromExtraArgsV1(extraArgs []byte) (nativePayment bool, err error) { +func DecodeV1(extraArgs []byte) (nativePayment bool, err error) { decodedBool, err := utils.ABIDecode(boolAbiType, extraArgs[functionSignatureLength:]) if err != nil { return false, fmt.Errorf("failed to decode 0x%x to bool", extraArgs[functionSignatureLength:]) @@ -25,7 +25,7 @@ func FromExtraArgsV1(extraArgs []byte) (nativePayment bool, err error) { return nativePayment, nil } -func ExtraArgsV1(nativePayment bool) ([]byte, error) { +func EncodeV1(nativePayment bool) ([]byte, error) { encodedArgs, err := utils.ABIEncode(boolAbiType, nativePayment) if err != nil { return nil, err diff --git a/core/services/vrf/v2/coordinator_v2x_interface.go b/core/services/vrf/v2/coordinator_v2x_interface.go index 3162156258..35e8bcd470 100644 --- a/core/services/vrf/v2/coordinator_v2x_interface.go +++ b/core/services/vrf/v2/coordinator_v2x_interface.go @@ -250,7 +250,7 @@ func (c *coordinatorV2_5) ParseRandomWordsFulfilled(log types.Log) (RandomWordsF } func (c *coordinatorV2_5) RequestRandomWords(opts *bind.TransactOpts, keyHash [32]byte, subID *big.Int, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, payInEth bool) (*types.Transaction, error) { - extraArgs, err := extraargs.ExtraArgsV1(payInEth) + extraArgs, err := extraargs.EncodeV1(payInEth) if err != nil { return nil, err } @@ -569,7 +569,7 @@ func (r *v2_5RandomWordsRequested) CallbackGasLimit() uint32 { } func (r *v2_5RandomWordsRequested) NativePayment() bool { - nativePayment, err := extraargs.FromExtraArgsV1(r.event.ExtraArgs) + nativePayment, err := extraargs.DecodeV1(r.event.ExtraArgs) if err != nil { panic(err) } @@ -1073,7 +1073,7 @@ func (r *RequestCommitment) NativePayment() bool { if r.VRFVersion == vrfcommon.V2 { return false } - nativePayment, err := extraargs.FromExtraArgsV1(r.V2Plus.ExtraArgs) + nativePayment, err := extraargs.DecodeV1(r.V2Plus.ExtraArgs) if err != nil { panic(err) } diff --git a/core/services/vrf/v2/integration_v2_plus_test.go b/core/services/vrf/v2/integration_v2_plus_test.go index 764c950ec3..b4c47c3e0b 100644 --- a/core/services/vrf/v2/integration_v2_plus_test.go +++ b/core/services/vrf/v2/integration_v2_plus_test.go @@ -966,7 +966,7 @@ func requestAndEstimateFulfillmentCost( requestLog := FindLatestRandomnessRequestedLog(t, uni.rootContract, vrfkey.PublicKey.MustHash(), nil) s, err := proof.BigToSeed(requestLog.PreSeed()) require.NoError(t, err) - extraArgs, err := extraargs.ExtraArgsV1(nativePayment) + extraArgs, err := extraargs.EncodeV1(nativePayment) require.NoError(t, err) proof, rc, err := proof.GenerateProofResponseV2Plus(app.GetKeyStore().VRF(), vrfkey.ID(), proof.PreSeedDataV2Plus{ PreSeed: s, diff --git a/tools/txtar/visitor.go b/tools/txtar/visitor.go index f945ac3523..d96cdc6f0a 100644 --- a/tools/txtar/visitor.go +++ b/tools/txtar/visitor.go @@ -13,13 +13,13 @@ const ( NoRecurse RecurseOpt = false ) -type TxtarDirVisitor struct { +type DirVisitor struct { rootDir string cb func(path string) error recurse RecurseOpt } -func (d *TxtarDirVisitor) Walk() error { +func (d *DirVisitor) Walk() error { return filepath.WalkDir(d.rootDir, func(path string, de fs.DirEntry, err error) error { if err != nil { return err @@ -52,7 +52,7 @@ func (d *TxtarDirVisitor) Walk() error { }) } -func (d *TxtarDirVisitor) isRootDir(de fs.DirEntry) (bool, error) { +func (d *DirVisitor) isRootDir(de fs.DirEntry) (bool, error) { fi, err := os.Stat(d.rootDir) if err != nil { return false, err @@ -65,8 +65,8 @@ func (d *TxtarDirVisitor) isRootDir(de fs.DirEntry) (bool, error) { return os.SameFile(fi, fi2), nil } -func NewDirVisitor(rootDir string, recurse RecurseOpt, cb func(path string) error) *TxtarDirVisitor { - return &TxtarDirVisitor{ +func NewDirVisitor(rootDir string, recurse RecurseOpt, cb func(path string) error) *DirVisitor { + return &DirVisitor{ rootDir: rootDir, cb: cb, recurse: recurse, From 6dcf219c3e567ba7566b5ae4ad9814d39bba6ed4 Mon Sep 17 00:00:00 2001 From: Balamurali Gopalswami <167726375+b-gopalswami@users.noreply.github.com> Date: Thu, 19 Sep 2024 02:13:38 -0400 Subject: [PATCH 378/432] Update to 1.5 RMN contract address (#14485) Co-authored-by: Brandon West <3317895+Bwest981@users.noreply.github.com> --- .../override/mainnet-secondary.toml | 712 ------- .../testconfig/override/mainnet.toml | 1677 +++++++++++------ 2 files changed, 1054 insertions(+), 1335 deletions(-) delete mode 100644 integration-tests/ccip-tests/testconfig/override/mainnet-secondary.toml diff --git a/integration-tests/ccip-tests/testconfig/override/mainnet-secondary.toml b/integration-tests/ccip-tests/testconfig/override/mainnet-secondary.toml deleted file mode 100644 index 7d457774b0..0000000000 --- a/integration-tests/ccip-tests/testconfig/override/mainnet-secondary.toml +++ /dev/null @@ -1,712 +0,0 @@ -[CCIP] -[CCIP.ContractVersions] -PriceRegistry = '1.2.0' -OffRamp = '1.2.0' -OnRamp = '1.2.0' -TokenPool = '1.4.0' -CommitStore = '1.2.0' - -[CCIP.Deployments] -Data = """ -{ - "lane_configs": { - "Arbitrum Mainnet": { - "is_native_fee_token": true, - "fee_token": "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4", - "bridge_tokens": ["0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"], - "bridge_tokens_pools": ["0x34700F5faE61Ba628c4269BdCbA12DA53bbfa726"], - "arm": "0xe06b0e8c4bd455153e8794ad7Ea8Ff5A14B64E4b", - "router": "0x141fa059441E0ca23ce184B6A78bafD2A517DdE8", - "price_registry": "0x13015e4E6f839E1Aa1016DF521ea458ecA20438c", - "wrapped_native": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", - "version" : "1.4.0", - "src_contracts": { - "Avalanche Mainnet": { - "on_ramp": "0x05B723f3db92430FbE4395fD03E40Cc7e9D17988", - "deployed_at": 11111111 - }, - "Base Mainnet": { - "on_ramp": "0x77b60F85b25fD501E3ddED6C1fe7bF565C08A22A", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0x79f3ABeCe5A3AFFf32D47F4CFe45e7b65c9a2D91", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0xCe11020D56e5FDbfE46D9FC3021641FfbBB5AdEE", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0xC09b72E8128620C40D89649019d995Cc79f030C3", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x122F05F49e90508F089eE8D0d868d1a4f3E5a809", - "deployed_at": 11111111 - }, - "WeMix Mainnet": { - "on_ramp": "0x66a0046ac9FA104eB38B04cfF391CcD0122E6FbC", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Avalanche Mainnet": { - "off_ramp": "0xe0109912157d5B75ea8b3181123Cf32c73bc9920", - "commit_store": "0xDaa61b8Cd85977820f92d1e749E1D9F55Da6CCEA", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Base Mainnet": { - "off_ramp": "0xdB19F77F87661f9be0F557cf9a1ebeCf7D8F206c", - "commit_store": "0x6e37f4c82d9A31cc42B445874dd3c3De97AB553f", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0xB1b705c2315fced1B38baE463BE7DDef531e47fA", - "commit_store": "0x310cECbFf14Ad0307EfF762F461a487C1abb90bf", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0x542ba1902044069330e8c5b36A84EC503863722f", - "commit_store": "0x060331fEdA35691e54876D957B4F9e3b8Cb47d20", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0xeeed4D86F3E0e6d32A6Ad29d8De6A0Dc91963A5f", - "commit_store": "0xbbB563c4d98020b9c0f3Cc34c2C0Ef9676806E35", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x9bDA7c8DCda4E39aFeB483cc0B7E3C1f6E0D5AB1", - "commit_store": "0x63a0AeaadAe851b990bBD9dc41f5C1B08b32026d", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "WeMix Mainnet": { - "off_ramp": "0xEEf5Fb4c4953F9cA9ab1f25cE590776AfFc2c455", - "commit_store": "0xD268286A277095a9C3C90205110831a84505881c", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } - }, - "Avalanche Mainnet": { - "is_native_fee_token": true, - "fee_token": "0x5947BB275c521040051D82396192181b413227A3", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0xdFD6C0dc67666DE3bB36b31eec5c7B1542A82C1E", - "router": "0xF4c7E640EdA248ef95972845a62bdC74237805dB", - "price_registry": "0xfA4edD04eaAcDB07c8D73621bc1790eC50D8c489", - "wrapped_native": "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", - "src_contracts": { - "Arbitrum Mainnet": { - "on_ramp": "0x98f51B041e493fc4d72B8BD33218480bA0c66DDF", - "deployed_at": 11111111 - }, - "Base Mainnet": { - "on_ramp": "0x268fb4311D2c6CB2bbA01CCA9AC073Fb3bfd1C7c", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0x8eaae6462816CB4957184c48B86afA7642D8Bf2B", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0xD0701FcC7818c31935331B02Eb21e91eC71a1704", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0x8629008887E073260c5434D6CaCFc83C3001d211", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x97500490d9126f34cf9aA0126d64623E170319Ef", - "deployed_at": 11111111 - }, - "WeMix Mainnet": { - "on_ramp": "0x9b1ed9De069Be4d50957464b359f98eD0Bf34dd5", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Arbitrum Mainnet": { - "off_ramp": "0x770b1375F86E7a9bf30DBe3F97bea67193dC9135", - "commit_store": "0x23E2b34Ce8e12c53f8a39AD4b3FFCa845f8E617C", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Base Mainnet": { - "off_ramp": "0x4d6A796Bc85dcDF41ce9AaEB50B094C6b589748f", - "commit_store": "0xc4C4358FA01a04D6c6FE3b96a351946d4c2715C2", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0x83F53Fc798FEbfFbdF84830AD403b9989187a06C", - "commit_store": "0xD8ceCE2D7794385E00Ce3EF94550E732b0A0B959", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0x5B833BD6456c604Eb396C0fBa477aD49e82B1A2a", - "commit_store": "0x23E23958D220B774680f91c2c91a6f2B2f610d7e", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0xb68A3EE8bD0A09eE221cf1859Dd5a4d5765188Fe", - "commit_store": "0x83DCeeCf822981F9F8552925eEfd88CAc1905dEA", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x19250aBE66B88F214d02B6f3BF80F4118290C619", - "commit_store": "0x87A0935cE6254dB1252bBac90d1D07D04846aDCA", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "WeMix Mainnet": { - "off_ramp": "0x317dE8bc5c3292E494b6496586696d4966A922B0", - "commit_store": "0x97Fbf3d6DEac16adC721aE9187CeEa1e610aC7Af", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } - }, - "Base Mainnet": { - "is_native_fee_token": true, - "fee_token": "0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0x38660c8CC222c0192b635c2ac09687B4F25cCE5F", - "router": "0x881e3A65B4d4a04dD529061dd0071cf975F58bCD", - "price_registry": "0x6337a58D4BD7Ba691B66341779e8f87d4679923a", - "wrapped_native": "0x4200000000000000000000000000000000000006", - "src_contracts": { - "Arbitrum Mainnet": { - "on_ramp": "0x1E5Ca70d1e7A1B26061125738a880BBeA42FeB21", - "deployed_at": 11111111 - }, - "Avalanche Mainnet": { - "on_ramp": "0xBE5a9E336D9614024B4Fa10D8112671fc9A42d96", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0xdd4Fb402d41Beb0eEeF6CfB1bf445f50bDC8c981", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0xDEA286dc0E01Cb4755650A6CF8d1076b454eA1cb", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0xd952FEAcDd5919Cc5E9454b53bF45d4E73dD6457", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x3DB8Bea142e41cA3633890d0e5640F99a895D6A5", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Arbitrum Mainnet": { - "off_ramp": "0x8531E63aE9279a1f0D09eba566CD1b092b95f3D5", - "commit_store": "0x327E13f54c7871a2416006B33B4822eAAD357916", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Avalanche Mainnet": { - "off_ramp": "0x8345F2fF67e5A65e85dc955DE1414832608E00aD", - "commit_store": "0xd0b13be4c53A6262b47C5DDd36F0257aa714F562", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0x48a51f5D38BE630Ddd6417Ea2D9052B8efc91a18", - "commit_store": "0xF97127e77252284EC9D4bc13C247c9D1A99F72B0", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0xEC0cFe335a4d53dBA70CB650Ab56eEc32788F0BB", - "commit_store": "0x0ae3c2c7FB789bd05A450CD3075D11f6c2Ca4F77", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0xf50c0d2a8B6Db60f1D93E60f03d0413D56153E4F", - "commit_store": "0x16f72C15165f7C9d74c12fDF188E399d4d3724e4", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x75F29f058b31106F99caFdc17c9b26ADfcC7b5D7", - "commit_store": "0xb719616E732581B570232DfB13Ca49D27667Af9f", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } - }, - "BSC Mainnet": { - "is_native_fee_token": true, - "fee_token": "0x404460C6A5EdE2D891e8297795264fDe62ADBB75", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0x3DB43b96B2625F4232e9Df900d464dd2c64C0021", - "router": "0x34B03Cb9086d7D758AC55af71584F81A598759FE", - "price_registry": "0xd64aAbD70A71d9f0A00B99F6EFc1626aA2dD43C7", - "wrapped_native": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", - "src_contracts": { - "Avalanche Mainnet": { - "on_ramp": "0x6aa72a998859eF93356c6521B72155D355D0Cfd2", - "deployed_at": 11111111 - }, - "Arbitrum Mainnet": { - "on_ramp": "0x2788b46BAcFF49BD89562e6bA5c5FBbbE5Fa92F7", - "deployed_at": 11111111 - }, - "Base Mainnet": { - "on_ramp": "0x70bC7f7a6D936b289bBF5c0E19ECE35B437E2e36", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0x0Bf40b034872D0b364f3DCec04C7434a4Da1C8d9", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0x4FEB11A454C9E8038A8d0aDF599Fe7612ce114bA", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x6bD4754D86fc87FE5b463D368f26a3587a08347c", - "deployed_at": 11111111 - }, - "WeMix Mainnet": { - "on_ramp": "0x1467fF8f249f5bc604119Af26a47035886f856BE", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Avalanche Mainnet": { - "off_ramp": "0x37a6fa55fe61061Ae97bF7314Ae270eCF71c5ED3", - "commit_store": "0x1f558F6dcf0224Ef1F78A24814FED548B9602c80", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Arbitrum Mainnet": { - "off_ramp": "0x3DA330fd8Ef10d93cFB7D4f8ecE7BC1F10811feC", - "commit_store": "0x86D55Ff492cfBBAf0c0D42D4EE615144E78b3D02", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Base Mainnet": { - "off_ramp": "0x574c697deab06B805D8780898B3F136a1F4892Dc", - "commit_store": "0x002B164b1dcf4E92F352DC625A01Be0E890EdEea", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0x181Bb1E97b0bDD1D85E741ad0943552D3682cc35", - "commit_store": "0x3fF27A34fF0FA77921C3438e67f58da1a83e9Ce1", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0xE7E080C8d62d595a223C577C7C8d1f75d9A5E664", - "commit_store": "0xF4d53346bDb6d393C74B0B72Aa7D6689a3eAad79", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x26af2046Da85d7f6712D5edCa81B9E3b2e7A60Ab", - "commit_store": "0x4C1dA405a789AC2853A69D8290B8B9b47a0374F8", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "WeMix Mainnet": { - "off_ramp": "0xC027C5AEb230008c243Be463A73571e581F94c13", - "commit_store": "0x2EB426C8C54D740d1FC856eB3Ff96feA03957978", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } - }, - "Ethereum Mainnet": { - "is_native_fee_token": true, - "fee_token": "0x514910771AF9Ca656af840dff83E8264EcF986CA", - "bridge_tokens": ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"], - "bridge_tokens_pools": ["0x69c24c970B65e22Ac26864aF10b2295B7d78f93A"], - "arm": "0x8B63b3DE93431C0f756A493644d128134291fA1b", - "router": "0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D", - "price_registry": "0x8c9b2Efb7c64C394119270bfecE7f54763b958Ad", - "wrapped_native": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - "src_contracts": { - "Arbitrum Mainnet": { - "on_ramp": "0x925228D7B82d883Dde340A55Fe8e6dA56244A22C", - "deployed_at": 11111111 - }, - "Avalanche Mainnet": { - "on_ramp": "0x3df8dAe2d123081c4D5E946E655F7c109B9Dd630", - "deployed_at": 11111111 - }, - "Base Mainnet": { - "on_ramp": "0xe2c2AB221AA0b957805f229d2AA57fBE2f4dADf7", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0x91D25A56Db77aD5147437d8B83Eb563D46eBFa69", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0x86B47d8411006874eEf8E4584BdFD7be8e5549d1", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x35F0ca9Be776E4B38659944c257bDd0ba75F1B8B", - "deployed_at": 11111111 - }, - "WeMix Mainnet": { - "on_ramp": "0xCbE7e5DA76dC99Ac317adF6d99137005FDA4E2C4", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Arbitrum Mainnet": { - "off_ramp": "0xeFC4a18af59398FF23bfe7325F2401aD44286F4d", - "commit_store": "0x9B2EEd6A1e16cB50Ed4c876D2dD69468B21b7749", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Avalanche Mainnet": { - "off_ramp": "0x569940e02D4425eac61A7601632eC00d69f75c17", - "commit_store": "0x2aa101BF99CaeF7fc1355D4c493a1fe187A007cE", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Base Mainnet": { - "off_ramp": "0xdf85c8381954694E74abD07488f452b4c2Cddfb3", - "commit_store": "0x8DC27D621c41a32140e22E2a4dAf1259639BAe04", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0x7Afe7088aff57173565F4b034167643AA8b9171c", - "commit_store": "0x87c55D48DF6EF7B08153Ab079e76bFEcbb793D75", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0xB095900fB91db00E6abD247A5A5AD1cee3F20BF7", - "commit_store": "0x4af4B497c998007eF83ad130318eB2b925a79dc8", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x0af338F0E314c7551bcE0EF516d46d855b0Ee395", - "commit_store": "0xD37a60E8C36E802D2E1a6321832Ee85556Beeb76", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "WeMix Mainnet": { - "off_ramp": "0x3a129e6C18b23d18BA9E6Aa14Dc2e79d1f91c6c5", - "commit_store": "0x31f6ab382DDeb9A316Ab61C3945a5292a50a89AB", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } - }, - "Kroma Mainnet": { - "is_native_fee_token": true, - "fee_token": "0xC1F6f7622ad37C3f46cDF6F8AA0344ADE80BF450", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0xB59779d3364BC6d71168245f9ebb96469E5a5a98", - "router": "0xE93E8B0d1b1CEB44350C8758ed1E2799CCee31aB", - "price_registry": "0x8155B4710e7bbC90924E957104F94Afd4f95Eca2", - "wrapped_native": "0x4200000000000000000000000000000000000001", - "src_contracts": { - "WeMix Mainnet": { - "on_ramp": "0x3C5Ab46fA1dB1dECD854224654313a69bf9fcAD3", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "WeMix Mainnet": { - "off_ramp": "0x2B555774B3D1dcbcd76efb7751F3c5FbCFABC5C4", - "commit_store": "0x213124614aAf31eBCE7c612A12aac5f8aAD77DE4", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } - }, - "Optimism Mainnet": { - "is_native_fee_token": true, - "fee_token": "0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6", - "bridge_tokens": ["0x4200000000000000000000000000000000000006"], - "bridge_tokens_pools": ["0x86E715415D8C8435903d1e8204fA1e9784Aa7305"], - "arm": "0x8C7C2C3362a42308BB5c368677Ad321D11693b81", - "router": "0x3206695CaE29952f4b0c22a169725a865bc8Ce0f", - "price_registry": "0xb52545aECE8C73A97E52a146757EC15b90Ed8488", - "wrapped_native": "0x4200000000000000000000000000000000000006", - "src_contracts": { - "Arbitrum Mainnet": { - "on_ramp": "0x0C9BE7Cfd12c735E5aaE047C1dCB845d54E518C3", - "deployed_at": 11111111 - }, - "Avalanche Mainnet": { - "on_ramp": "0xD0D3E757bFBce7ae1881DDD7F6d798DDcE588445", - "deployed_at": 11111111 - }, - "Base Mainnet": { - "on_ramp": "0x0b1760A8112183303c5526C6b24569fd3A274f3B", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0xa3c9544B82846C45BE37593d5d9ACffbE61BF3A6", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0x55183Db1d2aE0b63e4c92A64bEF2CBfc2032B127", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x6B57145e322c877E7D91Ed8E31266eB5c02F7EfC", - "deployed_at": 11111111 - }, - "WeMix Mainnet": { - "on_ramp": "0x82e9f4C5ec4a84E310d60D462a12042E5cbA0954", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Arbitrum Mainnet": { - "off_ramp": "0x0C9BE7Cfd12c735E5aaE047C1dCB845d54E518C3", - "commit_store": "0x55028780918330FD00a34a61D9a7Efd3f43ca845", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Avalanche Mainnet": { - "off_ramp": "0x8dc6490A6204dF846BaBE809cB695ba17Df1F9B1", - "commit_store": "0xA190660787B6B183Dd82B243eA10e609327c7308", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Base Mainnet": { - "off_ramp": "0xBAE6560eCa9B77Cb047158C783e36F7735C86037", - "commit_store": "0x6168aDF58e1Ad446BaD45c6275Bef60Ef4FFBAb8", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0xE14501F2838F2fA1Ceb52E78ABdA289EcE1705EA", - "commit_store": "0xa8DD25B29787527Df283211C24Ac72B17150A696", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0xd2D98Be6a1C241e86C807e51cED6ABb51d044203", - "commit_store": "0x4d75A5cE454b264b187BeE9e189aF1564a68408D", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x7c6221880A1D62506b1A08Dab3Bf695A49AcDD22", - "commit_store": "0x0684076EE3595221861C50cDb9Cb66402Ec11Cb9", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "WeMix Mainnet": { - "off_ramp": "0x3e5B3b7559D39563a74434157b31781322dA712D", - "commit_store": "0x7954372FF6f80908e5A2dC2a19d796A1005f91D2", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } - }, - "Polygon Mainnet": { - "is_native_fee_token": true, - "fee_token": "0xb0897686c545045aFc77CF20eC7A532E3120E0F1", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0xD7AcF65dA1E1f34b663aB199a474F209bF2b0523", - "router": "0x849c5ED5a80F5B408Dd4969b78c2C8fdf0565Bfe", - "price_registry": "0x30D873664Ba766C983984C7AF9A921ccE36D34e1", - "wrapped_native": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", - "src_contracts": { - "Arbitrum Mainnet": { - "on_ramp": "0xD16D025330Edb91259EEA8ed499daCd39087c295", - "deployed_at": 11111111 - }, - "Avalanche Mainnet": { - "on_ramp": "0x5FA30697e90eB30954895c45b028F7C0dDD39b12", - "deployed_at": 11111111 - }, - "Base Mainnet": { - "on_ramp": "0x20B028A2e0F6CCe3A11f3CE5F2B8986F932e89b4", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0xF5b5A2fC11BF46B1669C3B19d98B19C79109Dca9", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0xFd77c53AA4eF0E3C01f5Ac012BF7Cc7A3ECf5168", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0x3111cfbF5e84B5D9BD952dd8e957f4Ca75f728Cf", - "deployed_at": 11111111 - }, - "WeMix Mainnet": { - "on_ramp": "0x5060eF647a1F66BE6eE27FAe3046faf8D53CeB2d", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Arbitrum Mainnet": { - "off_ramp": "0xa8a9eDa2867c2E0CE0d5ECe273961F1EcC3CC25B", - "commit_store": "0xbD4480658dca8496a65046dfD1BDD44EF897Bdb5", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Avalanche Mainnet": { - "off_ramp": "0xB9e3680639c9F0C4e0b02FD81C445094426244Ae", - "commit_store": "0x8c63d4e67f7c4af6FEd2f56A34fB4e01CB807CFF", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Base Mainnet": { - "off_ramp": "0xD0FA7DE2D18A0c59D3fD7dfC7aB4e913C6Aa7b68", - "commit_store": "0xF88053B9DAC8Dd3039a4eFa8639159aaa3F2D4Cb", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0x592773924741F0Da889a0dfdab71171Dd11E054C", - "commit_store": "0xEC4d35E1A85f770f4D93BA43a462c9d87Ef7017e", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0x45320085fF051361D301eC1044318213A5387A15", - "commit_store": "0x4Dc771B5ef21ef60c33e2987E092345f2b63aE08", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0xBa754ecd3CFA7E9093F688EAc3860cf9D07Fc0AC", - "commit_store": "0x04C0D5302E3D8Ca0A0019141a52a23B59cdb70e4", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "WeMix Mainnet": { - "off_ramp": "0xd7c877ea02310Cce9278D9A048Aa1Bb9aF72F00d", - "commit_store": "0x92A1C927E8E10Ab6A40E5A5154e2300D278d1a67", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } - }, - "WeMix Mainnet": { - "is_native_fee_token": true, - "fee_token": "0x80f1FcdC96B55e459BF52b998aBBE2c364935d69", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0x07aaC8B69A62dB5bd3d244091916EbF2fac17b76", - "router": "0x7798b795Fde864f4Cd1b124a38Ba9619B7F8A442", - "price_registry": "0x252863688762aD86868D3d3076233Eacd80c7055", - "wrapped_native": "0x7D72b22a74A216Af4a002a1095C8C707d6eC1C5f", - "src_contracts": { - "Arbitrum Mainnet": { - "on_ramp": "0x9aBfd6f4C865610692AB6fb1Be862575809fFabf", - "deployed_at": 11111111 - }, - "Avalanche Mainnet": { - "on_ramp": "0xbE0Cfae74677F8dd16a246a3a5c8cbB1973118f4", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0x56657ec4D15C71f7F3C17ba2b21C853A24Dc5381", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0x70f3b0FD7e6a4B9B623e9AB859604A9EE03e48BD", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x777058C1e1dcE4eB8001F38631a1cd9450816e5a", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0x190bcE84CF2d500B878966F4Cf98a50d78f2675E", - "deployed_at": 11111111 - }, - "Kroma Mainnet": { - "on_ramp": "0x47E9AE0A815C94836202E696748A5d5476aD8735", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Arbitrum Mainnet": { - "off_ramp": "0x2ba68a395B72a6E3498D312efeD755ed2f3CF223", - "commit_store": "0xdAeC234DA83F68707Bb8AcB2ee6a01a5FD4c2391", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Avalanche Mainnet": { - "off_ramp": "0xFac907F9a1087B846Faa75A14C5d34A8639233d8", - "commit_store": "0xF2812063446c7deD2CA306c67A68364BdDcbEfc5", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0x6ec9ca4Cba62cA17c55F05ad2000B46192f02035", - "commit_store": "0x84534BE763366a69710E119c100832955795B34B", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0x87220D01DF0fF27149B47227897074653788fd23", - "commit_store": "0xF8dD2be2C6FA43e48A17146380CbEBBB4291807b", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x8f0229804513A9Bc00c1308414AB279Dbc718ae1", - "commit_store": "0x3A85D1b8641d83a87957C6ECF1b62151213e0842", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0xF92Fa796F5307b029c65CA26f322a6D86f211194", - "commit_store": "0xbeC110FF43D52be2066B06525304A9924E16b73b", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Kroma Mainnet": { - "off_ramp": "0xF886d8DC64E544af4835cbf91e5678A54D95B80e", - "commit_store": "0x8794C9534658fdCC44f2FF6645Bf31cf9F6d2d5D", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } - } - } -} -""" - -[CCIP.Env] -TTL = '8h' - -[CCIP.Env.Network] -selected_networks = [ - 'ETHEREUM_MAINNET', - 'ARBITRUM_MAINNET', - 'OPTIMISM_MAINNET' - ] - -[CCIP.Groups.load] -NetworkPairs = [ - 'ETHEREUM_MAINNET,OPTIMISM_MAINNET', - 'ETHEREUM_MAINNET,ARBITRUM_MAINNET', - 'ARBITRUM_MAINNET,OPTIMISM_MAINNET' # added as batch 1 -] - -BiDirectionalLane = true -PhaseTimeout = '40m' -ExistingDeployment = true - -[CCIP.Groups.load.TokenConfig] -NoOfTokensPerChain = 1 -CCIPOwnerTokens = true - -[CCIP.Groups.load.LoadProfile] -RequestPerUnitTime = [1] -TimeUnit = '3h' -TestDuration = '24h' -TestRunName = 'mainnet-2.7-ccip1.2' -FailOnFirstErrorInLoad = true -SkipRequestIfAnotherRequestTriggeredWithin = '40m' - -[[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] -MsgType = 'Data' -DestGasLimit = 0 -DataLength = 100 -NoOfTokens = 1 -AmountPerToken = 1 - -[CCIP.Groups.smoke] -# these are all the valid network pairs -NetworkPairs = [ - 'ETHEREUM_MAINNET,OPTIMISM_MAINNET', - 'ETHEREUM_MAINNET,ARBITRUM_MAINNET', - 'ARBITRUM_MAINNET,OPTIMISM_MAINNET' -] - -BiDirectionalLane = true -DestGasLimit = 0 -PhaseTimeout = '20m' -LocalCluster = false -ExistingDeployment = true -ReuseContracts = true - -[CCIP.Groups.smoke.TokenConfig] -NoOfTokensPerChain = 1 -CCIPOwnerTokens = true - -[CCIP.Groups.smoke.MsgDetails] -MsgType = 'Data' -DestGasLimit = 0 -DataLength = 100 -NoOfTokens = 1 -AmountPerToken = 1 \ No newline at end of file diff --git a/integration-tests/ccip-tests/testconfig/override/mainnet.toml b/integration-tests/ccip-tests/testconfig/override/mainnet.toml index 72695ba754..f723411eaf 100644 --- a/integration-tests/ccip-tests/testconfig/override/mainnet.toml +++ b/integration-tests/ccip-tests/testconfig/override/mainnet.toml @@ -9,639 +9,1070 @@ CommitStore = '1.2.0' [CCIP.Deployments] Data = """ { - "lane_configs": { + "lane_configs": { + "Arbitrum Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "arm": "0xC2C5E22a2d9715ed5C5BCC4D8eFf5966cf260744", + "router": "0x141fa059441E0ca23ce184B6A78bafD2A517DdE8", + "price_registry": "0x13015e4E6f839E1Aa1016DF521ea458ecA20438c", + "wrapped_native": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "src_contracts": { + "Avalanche Mainnet": { + "on_ramp": "0x05B723f3db92430FbE4395fD03E40Cc7e9D17988", + "deployed_at": 0 + }, + "BSC Mainnet": { + "on_ramp": "0x79f3ABeCe5A3AFFf32D47F4CFe45e7b65c9a2D91", + "deployed_at": 0 + }, + "Base Mainnet": { + "on_ramp": "0x77b60F85b25fD501E3ddED6C1fe7bF565C08A22A", + "deployed_at": 0 + }, + "Blast Mainnet": { + "on_ramp": "0x54480425E9e24138fdF1644a1F70007F25abfB46", + "deployed_at": 0 + }, + "Ethereum Mainnet": { + "on_ramp": "0xCe11020D56e5FDbfE46D9FC3021641FfbBB5AdEE", + "deployed_at": 0 + }, + "Gnosis Mainnet": { + "on_ramp": "0x1216DC856Af47a833254a280A038185F51C1B5c4", + "deployed_at": 0 + }, + "Metis Andromeda": { + "on_ramp": "0x5b23A0a103fC9028363B3BC3577e8Bd45B8E819F", + "deployed_at": 0 + }, + "Mode Mainnet": { + "on_ramp": "0x3920BF474BB50fffb4B77c1e6e66F65210D1D722", + "deployed_at": 0 + }, + "Optimism Mainnet": { + "on_ramp": "0xC09b72E8128620C40D89649019d995Cc79f030C3", + "deployed_at": 0 + }, + "Polygon Mainnet": { + "on_ramp": "0x122F05F49e90508F089eE8D0d868d1a4f3E5a809", + "deployed_at": 0 + }, + "WeMix Mainnet": { + "on_ramp": "0x66a0046ac9FA104eB38B04cfF391CcD0122E6FbC", + "deployed_at": 0 + }, + "ZKSync Mainnet": { + "on_ramp": "0x2C1016053d9873270d71613cA321aE97Fc89201d", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Avalanche Mainnet": { + "off_ramp": "0xe0109912157d5B75ea8b3181123Cf32c73bc9920", + "commit_store": "0xDaa61b8Cd85977820f92d1e749E1D9F55Da6CCEA", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "BSC Mainnet": { + "off_ramp": "0xB1b705c2315fced1B38baE463BE7DDef531e47fA", + "commit_store": "0x310cECbFf14Ad0307EfF762F461a487C1abb90bf", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Base Mainnet": { + "off_ramp": "0xdB19F77F87661f9be0F557cf9a1ebeCf7D8F206c", + "commit_store": "0x6e37f4c82d9A31cc42B445874dd3c3De97AB553f", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Blast Mainnet": { + "off_ramp": "0x449C59F4Ef3b1802DD054dd7837Eb2Ca91aFAB84", + "commit_store": "0x1E0e8B01693A248b3Aa1e5aca36336F9022Ceac0", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x542ba1902044069330e8c5b36A84EC503863722f", + "commit_store": "0x060331fEdA35691e54876D957B4F9e3b8Cb47d20", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Gnosis Mainnet": { + "off_ramp": "0x0C00414D9dcDB2DA7BF8AF26aE2deb617f09e756", + "commit_store": "0x1d464cd86c5C8358d56281aB31d2213534CCEA13", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Metis Andromeda": { + "off_ramp": "0xeF8dEb0c01f7389AD4ae05DAB30120dba915D53c", + "commit_store": "0xE594a09Aa8bCb55188758826A160615B95A6F3fE", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Mode Mainnet": { + "off_ramp": "0xEDE7ADACFbD27DBEBbE2d6C3BaDf12a634a72Faa", + "commit_store": "0x032B209a6B7a00336047505b55a4cBFBd29eE2c1", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Optimism Mainnet": { + "off_ramp": "0xeeed4D86F3E0e6d32A6Ad29d8De6A0Dc91963A5f", + "commit_store": "0xbbB563c4d98020b9c0f3Cc34c2C0Ef9676806E35", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Polygon Mainnet": { + "off_ramp": "0x9bDA7c8DCda4E39aFeB483cc0B7E3C1f6E0D5AB1", + "commit_store": "0x63a0AeaadAe851b990bBD9dc41f5C1B08b32026d", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "WeMix Mainnet": { + "off_ramp": "0xEEf5Fb4c4953F9cA9ab1f25cE590776AfFc2c455", + "commit_store": "0xD268286A277095a9C3C90205110831a84505881c", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "ZKSync Mainnet": { + "off_ramp": "0x50Fc0de671c775301e1Bdf19C17E778D0f978f6F", + "commit_store": "0x87732C2647168818ED49268EdA8A98C2e62ed744", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "Avalanche Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", + "arm": "0x4f6Ec25f06A114ADD3154DC17fb637F750AdaA31", + "router": "0xF4c7E640EdA248ef95972845a62bdC74237805dB", + "price_registry": "0x2d3b38E0a4DFFDad2A613f7760bE1683F272eA18", + "wrapped_native": "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x98f51B041e493fc4d72B8BD33218480bA0c66DDF", + "deployed_at": 0 + }, + "BSC Mainnet": { + "on_ramp": "0x8eaae6462816CB4957184c48B86afA7642D8Bf2B", + "deployed_at": 0 + }, + "Base Mainnet": { + "on_ramp": "0x268fb4311D2c6CB2bbA01CCA9AC073Fb3bfd1C7c", + "deployed_at": 0 + }, + "Ethereum Mainnet": { + "on_ramp": "0xD0701FcC7818c31935331B02Eb21e91eC71a1704", + "deployed_at": 0 + }, + "Gnosis Mainnet": { + "on_ramp": "0xBd0B9317F6AaA1085993F7b4CD468dE7A6428722", + "deployed_at": 0 + }, + "Optimism Mainnet": { + "on_ramp": "0x8629008887E073260c5434D6CaCFc83C3001d211", + "deployed_at": 0 + }, + "Polygon Mainnet": { + "on_ramp": "0x97500490d9126f34cf9aA0126d64623E170319Ef", + "deployed_at": 0 + }, + "WeMix Mainnet": { + "on_ramp": "0x9b1ed9De069Be4d50957464b359f98eD0Bf34dd5", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x770b1375F86E7a9bf30DBe3F97bea67193dC9135", + "commit_store": "0x23E2b34Ce8e12c53f8a39AD4b3FFCa845f8E617C", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "BSC Mainnet": { + "off_ramp": "0x83F53Fc798FEbfFbdF84830AD403b9989187a06C", + "commit_store": "0xD8ceCE2D7794385E00Ce3EF94550E732b0A0B959", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Base Mainnet": { + "off_ramp": "0x4d6A796Bc85dcDF41ce9AaEB50B094C6b589748f", + "commit_store": "0xc4C4358FA01a04D6c6FE3b96a351946d4c2715C2", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x5B833BD6456c604Eb396C0fBa477aD49e82B1A2a", + "commit_store": "0x23E23958D220B774680f91c2c91a6f2B2f610d7e", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Gnosis Mainnet": { + "off_ramp": "0xDE7ebf1Dc753D916A9fbEC4ae521Ee74EC2d0B5f", + "commit_store": "0x2dbc917b4DD455532015949c3103B64fcDB891b2", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Optimism Mainnet": { + "off_ramp": "0xb68A3EE8bD0A09eE221cf1859Dd5a4d5765188Fe", + "commit_store": "0x83DCeeCf822981F9F8552925eEfd88CAc1905dEA", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Polygon Mainnet": { + "off_ramp": "0x19250aBE66B88F214d02B6f3BF80F4118290C619", + "commit_store": "0x87A0935cE6254dB1252bBac90d1D07D04846aDCA", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "WeMix Mainnet": { + "off_ramp": "0x317dE8bc5c3292E494b6496586696d4966A922B0", + "commit_store": "0x97Fbf3d6DEac16adC721aE9187CeEa1e610aC7Af", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "BSC Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "arm": "0x56491A98199aD2e687Ea9D0cFB7b4AC57B4980Fc", + "router": "0x34B03Cb9086d7D758AC55af71584F81A598759FE", + "price_registry": "0x18C3D917D55Bc1784a3d4729AA3e2C1ecd662fFd", + "wrapped_native": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x2788b46BAcFF49BD89562e6bA5c5FBbbE5Fa92F7", + "deployed_at": 0 + }, + "Avalanche Mainnet": { + "on_ramp": "0x6aa72a998859eF93356c6521B72155D355D0Cfd2", + "deployed_at": 0 + }, + "Base Mainnet": { + "on_ramp": "0x70bC7f7a6D936b289bBF5c0E19ECE35B437E2e36", + "deployed_at": 0 + }, + "Blast Mainnet": { + "on_ramp": "0x02082b23D35d2670B8a636A431F3C30AF9d21e07", + "deployed_at": 0 + }, + "Ethereum Mainnet": { + "on_ramp": "0x0Bf40b034872D0b364f3DCec04C7434a4Da1C8d9", + "deployed_at": 0 + }, + "Gnosis Mainnet": { + "on_ramp": "0xAc9fE4179816077674d769698306CE6A7C6A1096", + "deployed_at": 0 + }, + "Mode Mainnet": { + "on_ramp": "0x4A83dA46c148AB5941a379b4cA49f42d14281C78", + "deployed_at": 0 + }, + "Optimism Mainnet": { + "on_ramp": "0x4FEB11A454C9E8038A8d0aDF599Fe7612ce114bA", + "deployed_at": 0 + }, + "Polygon Mainnet": { + "on_ramp": "0x6bD4754D86fc87FE5b463D368f26a3587a08347c", + "deployed_at": 0 + }, + "WeMix Mainnet": { + "on_ramp": "0x1467fF8f249f5bc604119Af26a47035886f856BE", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x3DA330fd8Ef10d93cFB7D4f8ecE7BC1F10811feC", + "commit_store": "0x86D55Ff492cfBBAf0c0D42D4EE615144E78b3D02", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Avalanche Mainnet": { + "off_ramp": "0x37a6fa55fe61061Ae97bF7314Ae270eCF71c5ED3", + "commit_store": "0x1f558F6dcf0224Ef1F78A24814FED548B9602c80", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Base Mainnet": { + "off_ramp": "0x574c697deab06B805D8780898B3F136a1F4892Dc", + "commit_store": "0x002B164b1dcf4E92F352DC625A01Be0E890EdEea", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Blast Mainnet": { + "off_ramp": "0x6500EDFBD27d34b7B69D0D45865ddaC4A1ceafE1", + "commit_store": "0x3A328B3fA852409415c15271442EFE4c77C04992", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x181Bb1E97b0bDD1D85E741ad0943552D3682cc35", + "commit_store": "0x3fF27A34fF0FA77921C3438e67f58da1a83e9Ce1", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Gnosis Mainnet": { + "off_ramp": "0xBE9b0cc569E970dAb953d336c670fc6b7c856c19", + "commit_store": "0xEe89CC6C2236d3b99C2D9c0b3b911690F757FadF", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Mode Mainnet": { + "off_ramp": "0x6C702159daA4DEbae32E294c584B1EaF2356cB1A", + "commit_store": "0x73C8d1E9e240331E3345c6fBe6CDFC71B742B69C", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Optimism Mainnet": { + "off_ramp": "0xE7E080C8d62d595a223C577C7C8d1f75d9A5E664", + "commit_store": "0xF4d53346bDb6d393C74B0B72Aa7D6689a3eAad79", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Polygon Mainnet": { + "off_ramp": "0x26af2046Da85d7f6712D5edCa81B9E3b2e7A60Ab", + "commit_store": "0x4C1dA405a789AC2853A69D8290B8B9b47a0374F8", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "WeMix Mainnet": { + "off_ramp": "0xC027C5AEb230008c243Be463A73571e581F94c13", + "commit_store": "0x2EB426C8C54D740d1FC856eB3Ff96feA03957978", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "Base Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "arm": "0x91cB19E7c4Ba9B08CF544cDc9143042150B007C3", + "router": "0x881e3A65B4d4a04dD529061dd0071cf975F58bCD", + "price_registry": "0x1bA15c57c8b74cD32443D7583E7f6d7c638aCf46", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { "Arbitrum Mainnet": { - "is_native_fee_token": true, - "fee_token": "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0xe06b0e8c4bd455153e8794ad7Ea8Ff5A14B64E4b", - "router": "0x141fa059441E0ca23ce184B6A78bafD2A517DdE8", - "price_registry": "0x13015e4E6f839E1Aa1016DF521ea458ecA20438c", - "wrapped_native": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", - "version" : "1.4.0", - "src_contracts": { - "Avalanche Mainnet": { - "on_ramp": "0x05B723f3db92430FbE4395fD03E40Cc7e9D17988", - "deployed_at": 11111111 - }, - "Base Mainnet": { - "on_ramp": "0x77b60F85b25fD501E3ddED6C1fe7bF565C08A22A", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0x79f3ABeCe5A3AFFf32D47F4CFe45e7b65c9a2D91", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0xCe11020D56e5FDbfE46D9FC3021641FfbBB5AdEE", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0xC09b72E8128620C40D89649019d995Cc79f030C3", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x122F05F49e90508F089eE8D0d868d1a4f3E5a809", - "deployed_at": 11111111 - }, - "WeMix Mainnet": { - "on_ramp": "0x66a0046ac9FA104eB38B04cfF391CcD0122E6FbC", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Avalanche Mainnet": { - "off_ramp": "0xe0109912157d5B75ea8b3181123Cf32c73bc9920", - "commit_store": "0xDaa61b8Cd85977820f92d1e749E1D9F55Da6CCEA", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Base Mainnet": { - "off_ramp": "0xdB19F77F87661f9be0F557cf9a1ebeCf7D8F206c", - "commit_store": "0x6e37f4c82d9A31cc42B445874dd3c3De97AB553f", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0xB1b705c2315fced1B38baE463BE7DDef531e47fA", - "commit_store": "0x310cECbFf14Ad0307EfF762F461a487C1abb90bf", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0x542ba1902044069330e8c5b36A84EC503863722f", - "commit_store": "0x060331fEdA35691e54876D957B4F9e3b8Cb47d20", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0xeeed4D86F3E0e6d32A6Ad29d8De6A0Dc91963A5f", - "commit_store": "0xbbB563c4d98020b9c0f3Cc34c2C0Ef9676806E35", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x9bDA7c8DCda4E39aFeB483cc0B7E3C1f6E0D5AB1", - "commit_store": "0x63a0AeaadAe851b990bBD9dc41f5C1B08b32026d", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "WeMix Mainnet": { - "off_ramp": "0xEEf5Fb4c4953F9cA9ab1f25cE590776AfFc2c455", - "commit_store": "0xD268286A277095a9C3C90205110831a84505881c", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } + "on_ramp": "0x1E5Ca70d1e7A1B26061125738a880BBeA42FeB21", + "deployed_at": 0 }, "Avalanche Mainnet": { - "is_native_fee_token": true, - "fee_token": "0x5947BB275c521040051D82396192181b413227A3", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0xdFD6C0dc67666DE3bB36b31eec5c7B1542A82C1E", - "router": "0xF4c7E640EdA248ef95972845a62bdC74237805dB", - "price_registry": "0xfA4edD04eaAcDB07c8D73621bc1790eC50D8c489", - "wrapped_native": "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", - "src_contracts": { - "Arbitrum Mainnet": { - "on_ramp": "0x98f51B041e493fc4d72B8BD33218480bA0c66DDF", - "deployed_at": 11111111 - }, - "Base Mainnet": { - "on_ramp": "0x268fb4311D2c6CB2bbA01CCA9AC073Fb3bfd1C7c", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0x8eaae6462816CB4957184c48B86afA7642D8Bf2B", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0xD0701FcC7818c31935331B02Eb21e91eC71a1704", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0x8629008887E073260c5434D6CaCFc83C3001d211", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x97500490d9126f34cf9aA0126d64623E170319Ef", - "deployed_at": 11111111 - }, - "WeMix Mainnet": { - "on_ramp": "0x9b1ed9De069Be4d50957464b359f98eD0Bf34dd5", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Arbitrum Mainnet": { - "off_ramp": "0x770b1375F86E7a9bf30DBe3F97bea67193dC9135", - "commit_store": "0x23E2b34Ce8e12c53f8a39AD4b3FFCa845f8E617C", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Base Mainnet": { - "off_ramp": "0x4d6A796Bc85dcDF41ce9AaEB50B094C6b589748f", - "commit_store": "0xc4C4358FA01a04D6c6FE3b96a351946d4c2715C2", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0x83F53Fc798FEbfFbdF84830AD403b9989187a06C", - "commit_store": "0xD8ceCE2D7794385E00Ce3EF94550E732b0A0B959", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0x5B833BD6456c604Eb396C0fBa477aD49e82B1A2a", - "commit_store": "0x23E23958D220B774680f91c2c91a6f2B2f610d7e", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0xb68A3EE8bD0A09eE221cf1859Dd5a4d5765188Fe", - "commit_store": "0x83DCeeCf822981F9F8552925eEfd88CAc1905dEA", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x19250aBE66B88F214d02B6f3BF80F4118290C619", - "commit_store": "0x87A0935cE6254dB1252bBac90d1D07D04846aDCA", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "WeMix Mainnet": { - "off_ramp": "0x317dE8bc5c3292E494b6496586696d4966A922B0", - "commit_store": "0x97Fbf3d6DEac16adC721aE9187CeEa1e610aC7Af", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } + "on_ramp": "0xBE5a9E336D9614024B4Fa10D8112671fc9A42d96", + "deployed_at": 0 + }, + "BSC Mainnet": { + "on_ramp": "0xdd4Fb402d41Beb0eEeF6CfB1bf445f50bDC8c981", + "deployed_at": 0 + }, + "Blast Mainnet": { + "on_ramp": "0xCCC32e2794EaD73f0a0a514Ac1c78D048968ab81", + "deployed_at": 0 + }, + "Ethereum Mainnet": { + "on_ramp": "0xDEA286dc0E01Cb4755650A6CF8d1076b454eA1cb", + "deployed_at": 0 + }, + "Gnosis Mainnet": { + "on_ramp": "0xcDD0e963E0708a4E936202396983E458cFA4A363", + "deployed_at": 0 + }, + "Mode Mainnet": { + "on_ramp": "0x626aCCbDDD73532df1caEDb5628Fdc40C5f429Ba", + "deployed_at": 0 + }, + "Optimism Mainnet": { + "on_ramp": "0xd952FEAcDd5919Cc5E9454b53bF45d4E73dD6457", + "deployed_at": 0 + }, + "Polygon Mainnet": { + "on_ramp": "0x3DB8Bea142e41cA3633890d0e5640F99a895D6A5", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x8531E63aE9279a1f0D09eba566CD1b092b95f3D5", + "commit_store": "0x327E13f54c7871a2416006B33B4822eAAD357916", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Avalanche Mainnet": { + "off_ramp": "0x8345F2fF67e5A65e85dc955DE1414832608E00aD", + "commit_store": "0xd0b13be4c53A6262b47C5DDd36F0257aa714F562", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "BSC Mainnet": { + "off_ramp": "0x48a51f5D38BE630Ddd6417Ea2D9052B8efc91a18", + "commit_store": "0xF97127e77252284EC9D4bc13C247c9D1A99F72B0", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Blast Mainnet": { + "off_ramp": "0x15F54FDd37ccC8E5a0b64633C95Ef8209Fd86401", + "commit_store": "0x52b5b4f3Cc50E38f736f23897f192430E131ccB8", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Ethereum Mainnet": { + "off_ramp": "0xEC0cFe335a4d53dBA70CB650Ab56eEc32788F0BB", + "commit_store": "0x0ae3c2c7FB789bd05A450CD3075D11f6c2Ca4F77", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Gnosis Mainnet": { + "off_ramp": "0xA24D3Bc3A59798a57AF58f69c89DC1C8aFD78F18", + "commit_store": "0x672dbdC3aF7eE37436fe101531D33266D85F33c9", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Mode Mainnet": { + "off_ramp": "0xFC30bFe46b11D4E25C6f7492fd064A70FbF18848", + "commit_store": "0xaeDBe55633F74A291F0A43Daa0Fd719615b78363", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Optimism Mainnet": { + "off_ramp": "0xf50c0d2a8B6Db60f1D93E60f03d0413D56153E4F", + "commit_store": "0x16f72C15165f7C9d74c12fDF188E399d4d3724e4", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Polygon Mainnet": { + "off_ramp": "0x75F29f058b31106F99caFdc17c9b26ADfcC7b5D7", + "commit_store": "0xb719616E732581B570232DfB13Ca49D27667Af9f", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "Blast Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x4300000000000000000000000000000000000004", + "arm": "0x96aFe20249C4f6f55d2fe0E792138f6a4dC566A4", + "router": "0x12e0B8E349C6fb7E6E40713E8125C3cF1127ea8C", + "price_registry": "0x4f66d9e65af0d3DC27897E29f571f933291bb07c", + "wrapped_native": "0x4300000000000000000000000000000000000004", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x42E1f5f5ACCe6e4971D9B9468D7A9Abed8D69DdD", + "deployed_at": 0 + }, + "BSC Mainnet": { + "on_ramp": "0x9c98d7aE731b0A53bedffBc1a12d9d43501Ea464", + "deployed_at": 0 }, "Base Mainnet": { - "is_native_fee_token": true, - "fee_token": "0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0x38660c8CC222c0192b635c2ac09687B4F25cCE5F", - "router": "0x881e3A65B4d4a04dD529061dd0071cf975F58bCD", - "price_registry": "0x6337a58D4BD7Ba691B66341779e8f87d4679923a", - "wrapped_native": "0x4200000000000000000000000000000000000006", - "src_contracts": { - "Arbitrum Mainnet": { - "on_ramp": "0x1E5Ca70d1e7A1B26061125738a880BBeA42FeB21", - "deployed_at": 11111111 - }, - "Avalanche Mainnet": { - "on_ramp": "0xBE5a9E336D9614024B4Fa10D8112671fc9A42d96", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0xdd4Fb402d41Beb0eEeF6CfB1bf445f50bDC8c981", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0xDEA286dc0E01Cb4755650A6CF8d1076b454eA1cb", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0xd952FEAcDd5919Cc5E9454b53bF45d4E73dD6457", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x3DB8Bea142e41cA3633890d0e5640F99a895D6A5", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Arbitrum Mainnet": { - "off_ramp": "0x8531E63aE9279a1f0D09eba566CD1b092b95f3D5", - "commit_store": "0x327E13f54c7871a2416006B33B4822eAAD357916", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Avalanche Mainnet": { - "off_ramp": "0x8345F2fF67e5A65e85dc955DE1414832608E00aD", - "commit_store": "0xd0b13be4c53A6262b47C5DDd36F0257aa714F562", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0x48a51f5D38BE630Ddd6417Ea2D9052B8efc91a18", - "commit_store": "0xF97127e77252284EC9D4bc13C247c9D1A99F72B0", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0xEC0cFe335a4d53dBA70CB650Ab56eEc32788F0BB", - "commit_store": "0x0ae3c2c7FB789bd05A450CD3075D11f6c2Ca4F77", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0xf50c0d2a8B6Db60f1D93E60f03d0413D56153E4F", - "commit_store": "0x16f72C15165f7C9d74c12fDF188E399d4d3724e4", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x75F29f058b31106F99caFdc17c9b26ADfcC7b5D7", - "commit_store": "0xb719616E732581B570232DfB13Ca49D27667Af9f", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } + "on_ramp": "0x955f139225F5d7021EB911ED2787a795f71E5eb6", + "deployed_at": 0 + }, + "Ethereum Mainnet": { + "on_ramp": "0xBD9bf9AA79adF083BB7100848Eb15F4e8282E27e", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x01A38cd2da195C704bA192fCCDddd8986cb7EdE9", + "commit_store": "0xab6D69db1C1E9B97a26eB3983b0878AdeD248200", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" }, "BSC Mainnet": { - "is_native_fee_token": true, - "fee_token": "0x404460C6A5EdE2D891e8297795264fDe62ADBB75", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0x3DB43b96B2625F4232e9Df900d464dd2c64C0021", - "router": "0x34B03Cb9086d7D758AC55af71584F81A598759FE", - "price_registry": "0xd64aAbD70A71d9f0A00B99F6EFc1626aA2dD43C7", - "wrapped_native": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", - "src_contracts": { - "Avalanche Mainnet": { - "on_ramp": "0x6aa72a998859eF93356c6521B72155D355D0Cfd2", - "deployed_at": 11111111 - }, - "Arbitrum Mainnet": { - "on_ramp": "0x2788b46BAcFF49BD89562e6bA5c5FBbbE5Fa92F7", - "deployed_at": 11111111 - }, - "Base Mainnet": { - "on_ramp": "0x70bC7f7a6D936b289bBF5c0E19ECE35B437E2e36", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0x0Bf40b034872D0b364f3DCec04C7434a4Da1C8d9", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0x4FEB11A454C9E8038A8d0aDF599Fe7612ce114bA", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x6bD4754D86fc87FE5b463D368f26a3587a08347c", - "deployed_at": 11111111 - }, - "WeMix Mainnet": { - "on_ramp": "0x1467fF8f249f5bc604119Af26a47035886f856BE", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Avalanche Mainnet": { - "off_ramp": "0x37a6fa55fe61061Ae97bF7314Ae270eCF71c5ED3", - "commit_store": "0x1f558F6dcf0224Ef1F78A24814FED548B9602c80", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Arbitrum Mainnet": { - "off_ramp": "0x3DA330fd8Ef10d93cFB7D4f8ecE7BC1F10811feC", - "commit_store": "0x86D55Ff492cfBBAf0c0D42D4EE615144E78b3D02", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Base Mainnet": { - "off_ramp": "0x574c697deab06B805D8780898B3F136a1F4892Dc", - "commit_store": "0x002B164b1dcf4E92F352DC625A01Be0E890EdEea", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0x181Bb1E97b0bDD1D85E741ad0943552D3682cc35", - "commit_store": "0x3fF27A34fF0FA77921C3438e67f58da1a83e9Ce1", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0xE7E080C8d62d595a223C577C7C8d1f75d9A5E664", - "commit_store": "0xF4d53346bDb6d393C74B0B72Aa7D6689a3eAad79", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x26af2046Da85d7f6712D5edCa81B9E3b2e7A60Ab", - "commit_store": "0x4C1dA405a789AC2853A69D8290B8B9b47a0374F8", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "WeMix Mainnet": { - "off_ramp": "0xC027C5AEb230008c243Be463A73571e581F94c13", - "commit_store": "0x2EB426C8C54D740d1FC856eB3Ff96feA03957978", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } + "off_ramp": "0xabC7Dffb2590c44a201EC7532382e1fc01Cd9eEb", + "commit_store": "0xA3086bf1D609d8e8028E8339e4aa4362C7da339D", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Base Mainnet": { + "off_ramp": "0x0406F8f66C10Da99ff518bc2242e0Ec486a2c787", + "commit_store": "0xc6A97d753a3001e0B893e5FA2b0ec3d623af6C20", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" }, "Ethereum Mainnet": { - "is_native_fee_token": true, - "fee_token": "0x514910771AF9Ca656af840dff83E8264EcF986CA", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0x8B63b3DE93431C0f756A493644d128134291fA1b", - "router": "0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D", - "price_registry": "0x8c9b2Efb7c64C394119270bfecE7f54763b958Ad", - "wrapped_native": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - "src_contracts": { - "Arbitrum Mainnet": { - "on_ramp": "0x925228D7B82d883Dde340A55Fe8e6dA56244A22C", - "deployed_at": 11111111 - }, - "Avalanche Mainnet": { - "on_ramp": "0x3df8dAe2d123081c4D5E946E655F7c109B9Dd630", - "deployed_at": 11111111 - }, - "Base Mainnet": { - "on_ramp": "0xe2c2AB221AA0b957805f229d2AA57fBE2f4dADf7", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0x91D25A56Db77aD5147437d8B83Eb563D46eBFa69", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0x86B47d8411006874eEf8E4584BdFD7be8e5549d1", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x35F0ca9Be776E4B38659944c257bDd0ba75F1B8B", - "deployed_at": 11111111 - }, - "WeMix Mainnet": { - "on_ramp": "0xCbE7e5DA76dC99Ac317adF6d99137005FDA4E2C4", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Arbitrum Mainnet": { - "off_ramp": "0xeFC4a18af59398FF23bfe7325F2401aD44286F4d", - "commit_store": "0x9B2EEd6A1e16cB50Ed4c876D2dD69468B21b7749", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Avalanche Mainnet": { - "off_ramp": "0x569940e02D4425eac61A7601632eC00d69f75c17", - "commit_store": "0x2aa101BF99CaeF7fc1355D4c493a1fe187A007cE", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Base Mainnet": { - "off_ramp": "0xdf85c8381954694E74abD07488f452b4c2Cddfb3", - "commit_store": "0x8DC27D621c41a32140e22E2a4dAf1259639BAe04", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0x7Afe7088aff57173565F4b034167643AA8b9171c", - "commit_store": "0x87c55D48DF6EF7B08153Ab079e76bFEcbb793D75", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0xB095900fB91db00E6abD247A5A5AD1cee3F20BF7", - "commit_store": "0x4af4B497c998007eF83ad130318eB2b925a79dc8", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x0af338F0E314c7551bcE0EF516d46d855b0Ee395", - "commit_store": "0xD37a60E8C36E802D2E1a6321832Ee85556Beeb76", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "WeMix Mainnet": { - "off_ramp": "0x3a129e6C18b23d18BA9E6Aa14Dc2e79d1f91c6c5", - "commit_store": "0x31f6ab382DDeb9A316Ab61C3945a5292a50a89AB", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } + "off_ramp": "0x4e0092bBC8EfAb6Eca295caB66986193b90a1Bb9", + "commit_store": "0xd7cA96B58EE33FdB3aa1392c30eD02645b1F28e2", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "Celo": { + "is_native_fee_token": true, + "fee_token": "0x2021B12D8138e2D63cF0895eccABC0DFc92416c6", + "arm": "0x832Ca6A279D8F8c695986086B35c70D4E0c817CC", + "router": "0xfB48f15480926A4ADf9116Dca468bDd2EE6C5F62", + "price_registry": "0xD9FcEEA20dBB3Dfb91763B301819C9666429DC26", + "wrapped_native": "0x2021B12D8138e2D63cF0895eccABC0DFc92416c6", + "src_contracts": { + "Ethereum Mainnet": { + "on_ramp": "0x27C96A8a2f70a8408aD6c620717a3bDaA54bb10b", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Ethereum Mainnet": { + "off_ramp": "0x90902C0AEE857F3A42f2beBEa38724cE7b7a0cff", + "commit_store": "0x25adA90B241143DD5Df04Fb06C1fF6E7f7624ad9", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "Ethereum Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "arm": "0xdCD48419bD5Cd9d1b097695F2af4Ee125aADF84F", + "router": "0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D", + "price_registry": "0x020082A7a9c2510e1921116001152DEE4da81985", + "wrapped_native": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x925228D7B82d883Dde340A55Fe8e6dA56244A22C", + "deployed_at": 0 }, - "Kroma Mainnet": { - "is_native_fee_token": true, - "fee_token": "0xC1F6f7622ad37C3f46cDF6F8AA0344ADE80BF450", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0xB59779d3364BC6d71168245f9ebb96469E5a5a98", - "router": "0xE93E8B0d1b1CEB44350C8758ed1E2799CCee31aB", - "price_registry": "0x8155B4710e7bbC90924E957104F94Afd4f95Eca2", - "wrapped_native": "0x4200000000000000000000000000000000000001", - "src_contracts": { - "WeMix Mainnet": { - "on_ramp": "0x3C5Ab46fA1dB1dECD854224654313a69bf9fcAD3", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "WeMix Mainnet": { - "off_ramp": "0x2B555774B3D1dcbcd76efb7751F3c5FbCFABC5C4", - "commit_store": "0x213124614aAf31eBCE7c612A12aac5f8aAD77DE4", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } + "Avalanche Mainnet": { + "on_ramp": "0x3df8dAe2d123081c4D5E946E655F7c109B9Dd630", + "deployed_at": 0 + }, + "BSC Mainnet": { + "on_ramp": "0x91D25A56Db77aD5147437d8B83Eb563D46eBFa69", + "deployed_at": 0 + }, + "Base Mainnet": { + "on_ramp": "0xe2c2AB221AA0b957805f229d2AA57fBE2f4dADf7", + "deployed_at": 0 + }, + "Blast Mainnet": { + "on_ramp": "0x4545F9a17DA50110632C14704a15d893BF9CBD27", + "deployed_at": 0 + }, + "Celo": { + "on_ramp": "0xEd5bE9508ae56531cc0EDe6A3bD588Eb9E2e3cfa", + "deployed_at": 0 + }, + "Gnosis Mainnet": { + "on_ramp": "0xF538dA6c673A30338269655f4e019B71ba58CFd4", + "deployed_at": 0 + }, + "Metis Andromeda": { + "on_ramp": "0xa5ef33B57dD8B653F9A9EA7114f46376d18264aC", + "deployed_at": 0 + }, + "Mode Mainnet": { + "on_ramp": "0x466a078d17e3706a9414ACc48029EE9Bae4C9b65", + "deployed_at": 0 + }, + "Optimism Mainnet": { + "on_ramp": "0x86B47d8411006874eEf8E4584BdFD7be8e5549d1", + "deployed_at": 0 + }, + "Polygon Mainnet": { + "on_ramp": "0x35F0ca9Be776E4B38659944c257bDd0ba75F1B8B", + "deployed_at": 0 + }, + "WeMix Mainnet": { + "on_ramp": "0xCbE7e5DA76dC99Ac317adF6d99137005FDA4E2C4", + "deployed_at": 0 + }, + "ZKSync Mainnet": { + "on_ramp": "0xD54C93A99CBCb8D865E13DA321B540171795A89f", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0xeFC4a18af59398FF23bfe7325F2401aD44286F4d", + "commit_store": "0x9B2EEd6A1e16cB50Ed4c876D2dD69468B21b7749", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Avalanche Mainnet": { + "off_ramp": "0x569940e02D4425eac61A7601632eC00d69f75c17", + "commit_store": "0x2aa101BF99CaeF7fc1355D4c493a1fe187A007cE", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "BSC Mainnet": { + "off_ramp": "0x7Afe7088aff57173565F4b034167643AA8b9171c", + "commit_store": "0x87c55D48DF6EF7B08153Ab079e76bFEcbb793D75", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Base Mainnet": { + "off_ramp": "0xdf85c8381954694E74abD07488f452b4c2Cddfb3", + "commit_store": "0x8DC27D621c41a32140e22E2a4dAf1259639BAe04", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Blast Mainnet": { + "off_ramp": "0x1a904DbbaDdE629a1460e2F6E2E485Ce06Ed7599", + "commit_store": "0x3CB2A81bb8a188C5353CdFa9994ed8666556FC53", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Celo": { + "off_ramp": "0xd5083684eE92dDeA117636ae5E2F1cb7fE4dfd46", + "commit_store": "0x831097033C88c82a7F1897b168Aa88cC44540C8f", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Gnosis Mainnet": { + "off_ramp": "0xE93ec2A57e38C8541c893348cCafEAB01F7D47d4", + "commit_store": "0x118a9389960F86390A4F14ce4C95D6ff076C6bFC", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Metis Andromeda": { + "off_ramp": "0xCe6364dBe64D2789D916180131fAda2ABFF702E8", + "commit_store": "0x3d8a95adA63D406ee8232562AbD83CEdb0B90466", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Mode Mainnet": { + "off_ramp": "0xE8af3b68eDfFf65Ce48648009982380701f09B92", + "commit_store": "0x76264869a3eBF51a59FCa5ABa84ee2867c7F190e", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Optimism Mainnet": { + "off_ramp": "0xB095900fB91db00E6abD247A5A5AD1cee3F20BF7", + "commit_store": "0x4af4B497c998007eF83ad130318eB2b925a79dc8", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Polygon Mainnet": { + "off_ramp": "0x0af338F0E314c7551bcE0EF516d46d855b0Ee395", + "commit_store": "0xD37a60E8C36E802D2E1a6321832Ee85556Beeb76", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "WeMix Mainnet": { + "off_ramp": "0x3a129e6C18b23d18BA9E6Aa14Dc2e79d1f91c6c5", + "commit_store": "0x31f6ab382DDeb9A316Ab61C3945a5292a50a89AB", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "ZKSync Mainnet": { + "off_ramp": "0xb368c8946D9fa5A497cDe1Dff7213f9CdfD143Bf", + "commit_store": "0xa4d264470a67D9f6682EE12Bdc9c35Df44e3F194", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "Gnosis Mainnet": { + "is_native_fee_token": true, + "fee_token": "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + "arm": "0x2ab5ff904CFFdD37f19cC34597cF425916F2DAcA", + "router": "0x4aAD6071085df840abD9Baf1697d5D5992bDadce", + "price_registry": "0xec00a50EFb62F5f686E0FdEFDD6e10744dc53cAD", + "wrapped_native": "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x7A36511202f54a8A3Bc62Cc1df24bd391f7c9864", + "deployed_at": 0 + }, + "Avalanche Mainnet": { + "on_ramp": "0x732753869bc6bB07Ec81A403F926bbF6fC2FeaE2", + "deployed_at": 0 + }, + "BSC Mainnet": { + "on_ramp": "0xD5d33bc0BF395B39514B7f9f8F66ebc9D8e650Cb", + "deployed_at": 0 + }, + "Base Mainnet": { + "on_ramp": "0x400eFb50480a73FEc02b115b53F0Ec6EcFf03C67", + "deployed_at": 0 + }, + "Ethereum Mainnet": { + "on_ramp": "0x0F246651F1c2275B4E14d8ae166D1fd3Af05c405", + "deployed_at": 0 + }, + "Optimism Mainnet": { + "on_ramp": "0x391516732884d3F8Eec3301C19b819E6e6044C17", + "deployed_at": 0 + }, + "Polygon Mainnet": { + "on_ramp": "0x566c7A2Cb557c36082301B97E998721D14E4bF7d", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x1bee1FD97824288a36B725f9CF20E07A67d5113b", + "commit_store": "0xB3a48e8664C5dE26822ae44577b100b717C36a54", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Avalanche Mainnet": { + "off_ramp": "0x633c19cCD7A818770f7BF59eB9C5AB632CDbc4D5", + "commit_store": "0xbbC073fb2D424eA45A571cc4dd91745E45d0aC73", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "BSC Mainnet": { + "off_ramp": "0x4D90524de5783257fd64d1a20689a5b9Bad25de0", + "commit_store": "0xAae8De9f1B7e2FFF0563c2BBf0c69593BD517b52", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Base Mainnet": { + "off_ramp": "0x9118303DE7f4342F9B057f6EC1Be282aa543D99C", + "commit_store": "0xa75f463b8a1d8bf7694Ac13E02938894F45eFbaA", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Ethereum Mainnet": { + "off_ramp": "0xFF61E57A2eE83FA262006C2DaF0D5fB2b36F3070", + "commit_store": "0xF433De9A293553c133E2dB90e226c2F2911f435C", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Optimism Mainnet": { + "off_ramp": "0x9D3aA479525a5BcE776dD83769e9F9b5B4dD4193", + "commit_store": "0x2B721632693A8BbABa3bA5F125C8cD33D66F28F7", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Polygon Mainnet": { + "off_ramp": "0x9714098CDdAc380D4443293C55B6CBf6D6bbDbEb", + "commit_store": "0x4338f204C7698eE678d6c44117503f812ca1FA69", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "Kroma Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000001", + "arm": "0xB558b375D1D8a1aE2c3d5bBe43634BcF4d0d108c", + "router": "0xE93E8B0d1b1CEB44350C8758ed1E2799CCee31aB", + "price_registry": "0x8155B4710e7bbC90924E957104F94Afd4f95Eca2", + "wrapped_native": "0x4200000000000000000000000000000000000001", + "src_contracts": { + "WeMix Mainnet": { + "on_ramp": "0x3C5Ab46fA1dB1dECD854224654313a69bf9fcAD3", + "deployed_at": 0 + } + }, + "dest_contracts": { + "WeMix Mainnet": { + "off_ramp": "0x2B555774B3D1dcbcd76efb7751F3c5FbCFABC5C4", + "commit_store": "0x213124614aAf31eBCE7c612A12aac5f8aAD77DE4", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "Metis Andromeda": { + "is_native_fee_token": true, + "fee_token": "0x75cb093E4D61d2A2e65D8e0BBb01DE8d89b53481", + "arm": "0xC4BFAc3D31C524A4958c5d5d1e68394d8DEbbE69", + "router": "0x7b9FB8717D306e2e08ce2e1Efa81F026bf9AD13c", + "price_registry": "0xe1A7e2f9E88a72aF3E4790f33FfcDEa43d5eCC7B", + "wrapped_native": "0x75cb093E4D61d2A2e65D8e0BBb01DE8d89b53481", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x87353b87A373E1551D27EDacDaC1644741c6499F", + "deployed_at": 0 + }, + "Ethereum Mainnet": { + "on_ramp": "0xE43f9eD3146d76E627C2504E5140005027992De6", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x2cc33de75dAFDb3F8F4f24244a9C420374e2C001", + "commit_store": "0x67fE38dB73be154a1f1a63221F898B9d5EE4eF63", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Ethereum Mainnet": { + "off_ramp": "0xc2B1A8c931582D041ba5fF30AEB9fA828B30754d", + "commit_store": "0x90073Ea7A1Ee4Fe5d638B4216Bc60479Eba52001", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "Mode Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "arm": "0x77EAF440c5d24e25D1834CBBF623bFd83b8b5dA1", + "router": "0x24C40f13E77De2aFf37c280BA06c333531589bf1", + "price_registry": "0xffDEc5d752dd1fa1f56C236183ACB022e5D9d79e", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x65Ad802d80aD6a96C5a4bc9e57E16099de99Dc7F", + "deployed_at": 0 + }, + "BSC Mainnet": { + "on_ramp": "0x8C5149ff7Cfd99dd561caE9B7abFAA0Ef79eAbeC", + "deployed_at": 0 + }, + "Base Mainnet": { + "on_ramp": "0x71dB32eF442c29d8cbf72a9AFcb1Ef12B35b0BF4", + "deployed_at": 0 + }, + "Ethereum Mainnet": { + "on_ramp": "0xbD5F9C193a7fEF5D578C55Ddfe4d08d6BCc15648", + "deployed_at": 0 }, "Optimism Mainnet": { - "is_native_fee_token": true, - "fee_token": "0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0x8C7C2C3362a42308BB5c368677Ad321D11693b81", - "router": "0x3206695CaE29952f4b0c22a169725a865bc8Ce0f", - "price_registry": "0xb52545aECE8C73A97E52a146757EC15b90Ed8488", - "wrapped_native": "0x4200000000000000000000000000000000000006", - "src_contracts": { - "Arbitrum Mainnet": { - "on_ramp": "0x0C9BE7Cfd12c735E5aaE047C1dCB845d54E518C3", - "deployed_at": 11111111 - }, - "Avalanche Mainnet": { - "on_ramp": "0xD0D3E757bFBce7ae1881DDD7F6d798DDcE588445", - "deployed_at": 11111111 - }, - "Base Mainnet": { - "on_ramp": "0x0b1760A8112183303c5526C6b24569fd3A274f3B", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0xa3c9544B82846C45BE37593d5d9ACffbE61BF3A6", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0x55183Db1d2aE0b63e4c92A64bEF2CBfc2032B127", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x6B57145e322c877E7D91Ed8E31266eB5c02F7EfC", - "deployed_at": 11111111 - }, - "WeMix Mainnet": { - "on_ramp": "0x82e9f4C5ec4a84E310d60D462a12042E5cbA0954", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Arbitrum Mainnet": { - "off_ramp": "0x0C9BE7Cfd12c735E5aaE047C1dCB845d54E518C3", - "commit_store": "0x55028780918330FD00a34a61D9a7Efd3f43ca845", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Avalanche Mainnet": { - "off_ramp": "0x8dc6490A6204dF846BaBE809cB695ba17Df1F9B1", - "commit_store": "0xA190660787B6B183Dd82B243eA10e609327c7308", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Base Mainnet": { - "off_ramp": "0xBAE6560eCa9B77Cb047158C783e36F7735C86037", - "commit_store": "0x6168aDF58e1Ad446BaD45c6275Bef60Ef4FFBAb8", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0xE14501F2838F2fA1Ceb52E78ABdA289EcE1705EA", - "commit_store": "0xa8DD25B29787527Df283211C24Ac72B17150A696", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0xd2D98Be6a1C241e86C807e51cED6ABb51d044203", - "commit_store": "0x4d75A5cE454b264b187BeE9e189aF1564a68408D", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x7c6221880A1D62506b1A08Dab3Bf695A49AcDD22", - "commit_store": "0x0684076EE3595221861C50cDb9Cb66402Ec11Cb9", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "WeMix Mainnet": { - "off_ramp": "0x3e5B3b7559D39563a74434157b31781322dA712D", - "commit_store": "0x7954372FF6f80908e5A2dC2a19d796A1005f91D2", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } + "on_ramp": "0x659303e8d4306D3ea8676FB034d56FB6f37E19d9", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x8d3E1b15ebC96cec1ffc092cEcAeA6c1DD00aF9b", + "commit_store": "0x1f1DEa0210aE346A20E270a1C3355d99b0B949D2", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "BSC Mainnet": { + "off_ramp": "0x7a57670Fa0Cf1Bc2665a1Ae0f5031b9f5a43dD3a", + "commit_store": "0x18ffb74D94175d00D8bB67B70737dE2cE45eed07", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Base Mainnet": { + "off_ramp": "0xEfa90cE6289A2777cd5B8fb991B2D0Be44cA5067", + "commit_store": "0xACa5f0942Bb7fF297A7c25E8364373702D81bb3f", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Ethereum Mainnet": { + "off_ramp": "0xdF8f09AB4DfB49dEC8a0B8b7f1B7F4134252D3e9", + "commit_store": "0x8Ae635d264f20f1dbC0dea03712C194AdbeF50D1", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Optimism Mainnet": { + "off_ramp": "0xE4D6AAF678b986D3E6B7A85FA33d0519716a5525", + "commit_store": "0xBF80E30c8c013Ec0d05e2a959CF8000407C813EC", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "Optimism Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x4200000000000000000000000000000000000006", + "arm": "0x1c51b6D5BFcFB7ee82C80949DFD146dB157a7E49", + "router": "0x3206695CaE29952f4b0c22a169725a865bc8Ce0f", + "price_registry": "0x9270AAA75F4B9038f4c25fEc665B02a150a90361", + "wrapped_native": "0x4200000000000000000000000000000000000006", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x0C9BE7Cfd12c735E5aaE047C1dCB845d54E518C3", + "deployed_at": 0 + }, + "Avalanche Mainnet": { + "on_ramp": "0xD0D3E757bFBce7ae1881DDD7F6d798DDcE588445", + "deployed_at": 0 + }, + "BSC Mainnet": { + "on_ramp": "0xa3c9544B82846C45BE37593d5d9ACffbE61BF3A6", + "deployed_at": 0 + }, + "Base Mainnet": { + "on_ramp": "0x0b1760A8112183303c5526C6b24569fd3A274f3B", + "deployed_at": 0 + }, + "Ethereum Mainnet": { + "on_ramp": "0x55183Db1d2aE0b63e4c92A64bEF2CBfc2032B127", + "deployed_at": 0 + }, + "Gnosis Mainnet": { + "on_ramp": "0x14aA3CC03583aA557DBca4ce72288Cc5F37DDE34", + "deployed_at": 0 + }, + "Mode Mainnet": { + "on_ramp": "0x034eA573B049210315110f7eA11c9618E32F08Ae", + "deployed_at": 0 + }, + "Polygon Mainnet": { + "on_ramp": "0x6B57145e322c877E7D91Ed8E31266eB5c02F7EfC", + "deployed_at": 0 + }, + "WeMix Mainnet": { + "on_ramp": "0x82e9f4C5ec4a84E310d60D462a12042E5cbA0954", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0xaC8C94242aa8234Bf89682aBcDDf805AE8cff61D", + "commit_store": "0x55028780918330FD00a34a61D9a7Efd3f43ca845", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Avalanche Mainnet": { + "off_ramp": "0x8dc6490A6204dF846BaBE809cB695ba17Df1F9B1", + "commit_store": "0xA190660787B6B183Dd82B243eA10e609327c7308", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "BSC Mainnet": { + "off_ramp": "0xE14501F2838F2fA1Ceb52E78ABdA289EcE1705EA", + "commit_store": "0xa8DD25B29787527Df283211C24Ac72B17150A696", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Base Mainnet": { + "off_ramp": "0xBAE6560eCa9B77Cb047158C783e36F7735C86037", + "commit_store": "0x6168aDF58e1Ad446BaD45c6275Bef60Ef4FFBAb8", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Ethereum Mainnet": { + "off_ramp": "0xd2D98Be6a1C241e86C807e51cED6ABb51d044203", + "commit_store": "0x4d75A5cE454b264b187BeE9e189aF1564a68408D", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Gnosis Mainnet": { + "off_ramp": "0x4358640A2419119DBe0933b5F2c288c3EB2c082C", + "commit_store": "0x44d1a05ef6e54a3CB35a1497303bA272f15f45ed", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Mode Mainnet": { + "off_ramp": "0xDf9717d724828537902Fb0c3B7C56c641463Fa38", + "commit_store": "0x8aEFF283381914E07Fc371601D59648ab6D2C0B1", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" }, "Polygon Mainnet": { - "is_native_fee_token": true, - "fee_token": "0xb0897686c545045aFc77CF20eC7A532E3120E0F1", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0xD7AcF65dA1E1f34b663aB199a474F209bF2b0523", - "router": "0x849c5ED5a80F5B408Dd4969b78c2C8fdf0565Bfe", - "price_registry": "0x30D873664Ba766C983984C7AF9A921ccE36D34e1", - "wrapped_native": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", - "src_contracts": { - "Arbitrum Mainnet": { - "on_ramp": "0xD16D025330Edb91259EEA8ed499daCd39087c295", - "deployed_at": 11111111 - }, - "Avalanche Mainnet": { - "on_ramp": "0x5FA30697e90eB30954895c45b028F7C0dDD39b12", - "deployed_at": 11111111 - }, - "Base Mainnet": { - "on_ramp": "0x20B028A2e0F6CCe3A11f3CE5F2B8986F932e89b4", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0xF5b5A2fC11BF46B1669C3B19d98B19C79109Dca9", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0xFd77c53AA4eF0E3C01f5Ac012BF7Cc7A3ECf5168", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0x3111cfbF5e84B5D9BD952dd8e957f4Ca75f728Cf", - "deployed_at": 11111111 - }, - "WeMix Mainnet": { - "on_ramp": "0x5060eF647a1F66BE6eE27FAe3046faf8D53CeB2d", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Arbitrum Mainnet": { - "off_ramp": "0xa8a9eDa2867c2E0CE0d5ECe273961F1EcC3CC25B", - "commit_store": "0xbD4480658dca8496a65046dfD1BDD44EF897Bdb5", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Avalanche Mainnet": { - "off_ramp": "0xB9e3680639c9F0C4e0b02FD81C445094426244Ae", - "commit_store": "0x8c63d4e67f7c4af6FEd2f56A34fB4e01CB807CFF", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Base Mainnet": { - "off_ramp": "0xD0FA7DE2D18A0c59D3fD7dfC7aB4e913C6Aa7b68", - "commit_store": "0xF88053B9DAC8Dd3039a4eFa8639159aaa3F2D4Cb", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0x592773924741F0Da889a0dfdab71171Dd11E054C", - "commit_store": "0xEC4d35E1A85f770f4D93BA43a462c9d87Ef7017e", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0x45320085fF051361D301eC1044318213A5387A15", - "commit_store": "0x4Dc771B5ef21ef60c33e2987E092345f2b63aE08", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0xBa754ecd3CFA7E9093F688EAc3860cf9D07Fc0AC", - "commit_store": "0x04C0D5302E3D8Ca0A0019141a52a23B59cdb70e4", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "WeMix Mainnet": { - "off_ramp": "0xd7c877ea02310Cce9278D9A048Aa1Bb9aF72F00d", - "commit_store": "0x92A1C927E8E10Ab6A40E5A5154e2300D278d1a67", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } + "off_ramp": "0x7c6221880A1D62506b1A08Dab3Bf695A49AcDD22", + "commit_store": "0x0684076EE3595221861C50cDb9Cb66402Ec11Cb9", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" }, "WeMix Mainnet": { - "is_native_fee_token": true, - "fee_token": "0x80f1FcdC96B55e459BF52b998aBBE2c364935d69", - "bridge_tokens": [], - "bridge_tokens_pools": [], - "arm": "0x07aaC8B69A62dB5bd3d244091916EbF2fac17b76", - "router": "0x7798b795Fde864f4Cd1b124a38Ba9619B7F8A442", - "price_registry": "0x252863688762aD86868D3d3076233Eacd80c7055", - "wrapped_native": "0x7D72b22a74A216Af4a002a1095C8C707d6eC1C5f", - "src_contracts": { - "Arbitrum Mainnet": { - "on_ramp": "0x9aBfd6f4C865610692AB6fb1Be862575809fFabf", - "deployed_at": 11111111 - }, - "Avalanche Mainnet": { - "on_ramp": "0xbE0Cfae74677F8dd16a246a3a5c8cbB1973118f4", - "deployed_at": 11111111 - }, - "BSC Mainnet": { - "on_ramp": "0x56657ec4D15C71f7F3C17ba2b21C853A24Dc5381", - "deployed_at": 11111111 - }, - "Optimism Mainnet": { - "on_ramp": "0x70f3b0FD7e6a4B9B623e9AB859604A9EE03e48BD", - "deployed_at": 11111111 - }, - "Polygon Mainnet": { - "on_ramp": "0x777058C1e1dcE4eB8001F38631a1cd9450816e5a", - "deployed_at": 11111111 - }, - "Ethereum Mainnet": { - "on_ramp": "0x190bcE84CF2d500B878966F4Cf98a50d78f2675E", - "deployed_at": 11111111 - }, - "Kroma Mainnet": { - "on_ramp": "0x47E9AE0A815C94836202E696748A5d5476aD8735", - "deployed_at": 11111111 - } - }, - "dest_contracts": { - "Arbitrum Mainnet": { - "off_ramp": "0x2ba68a395B72a6E3498D312efeD755ed2f3CF223", - "commit_store": "0xdAeC234DA83F68707Bb8AcB2ee6a01a5FD4c2391", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Avalanche Mainnet": { - "off_ramp": "0xFac907F9a1087B846Faa75A14C5d34A8639233d8", - "commit_store": "0xF2812063446c7deD2CA306c67A68364BdDcbEfc5", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "BSC Mainnet": { - "off_ramp": "0x6ec9ca4Cba62cA17c55F05ad2000B46192f02035", - "commit_store": "0x84534BE763366a69710E119c100832955795B34B", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Optimism Mainnet": { - "off_ramp": "0x87220D01DF0fF27149B47227897074653788fd23", - "commit_store": "0xF8dD2be2C6FA43e48A17146380CbEBBB4291807b", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Polygon Mainnet": { - "off_ramp": "0x8f0229804513A9Bc00c1308414AB279Dbc718ae1", - "commit_store": "0x3A85D1b8641d83a87957C6ECF1b62151213e0842", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Ethereum Mainnet": { - "off_ramp": "0xF92Fa796F5307b029c65CA26f322a6D86f211194", - "commit_store": "0xbeC110FF43D52be2066B06525304A9924E16b73b", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - }, - "Kroma Mainnet": { - "off_ramp": "0xF886d8DC64E544af4835cbf91e5678A54D95B80e", - "commit_store": "0x8794C9534658fdCC44f2FF6645Bf31cf9F6d2d5D", - "receiver_dapp": "0x1A2A69e3eB1382FE34Bc579AdD5Bae39e31d4A2c" - } - } + "off_ramp": "0x3e5B3b7559D39563a74434157b31781322dA712D", + "commit_store": "0x7954372FF6f80908e5A2dC2a19d796A1005f91D2", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "Polygon Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", + "arm": "0x569a295a09634Ac9414c3efe4E8931986d68F937", + "router": "0x849c5ED5a80F5B408Dd4969b78c2C8fdf0565Bfe", + "price_registry": "0x30D873664Ba766C983984C7AF9A921ccE36D34e1", + "wrapped_native": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0xD16D025330Edb91259EEA8ed499daCd39087c295", + "deployed_at": 0 + }, + "Avalanche Mainnet": { + "on_ramp": "0x5FA30697e90eB30954895c45b028F7C0dDD39b12", + "deployed_at": 0 + }, + "BSC Mainnet": { + "on_ramp": "0xF5b5A2fC11BF46B1669C3B19d98B19C79109Dca9", + "deployed_at": 0 + }, + "Base Mainnet": { + "on_ramp": "0x20B028A2e0F6CCe3A11f3CE5F2B8986F932e89b4", + "deployed_at": 0 + }, + "Ethereum Mainnet": { + "on_ramp": "0xFd77c53AA4eF0E3C01f5Ac012BF7Cc7A3ECf5168", + "deployed_at": 0 + }, + "Gnosis Mainnet": { + "on_ramp": "0x4616621704C81801A56D29c961F9395ee153d46C", + "deployed_at": 0 + }, + "Optimism Mainnet": { + "on_ramp": "0x3111cfbF5e84B5D9BD952dd8e957f4Ca75f728Cf", + "deployed_at": 0 + }, + "WeMix Mainnet": { + "on_ramp": "0x5060eF647a1F66BE6eE27FAe3046faf8D53CeB2d", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0xa8a9eDa2867c2E0CE0d5ECe273961F1EcC3CC25B", + "commit_store": "0xbD4480658dca8496a65046dfD1BDD44EF897Bdb5", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Avalanche Mainnet": { + "off_ramp": "0xB9e3680639c9F0C4e0b02FD81C445094426244Ae", + "commit_store": "0x8c63d4e67f7c4af6FEd2f56A34fB4e01CB807CFF", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "BSC Mainnet": { + "off_ramp": "0x592773924741F0Da889a0dfdab71171Dd11E054C", + "commit_store": "0xEC4d35E1A85f770f4D93BA43a462c9d87Ef7017e", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Base Mainnet": { + "off_ramp": "0xD0FA7DE2D18A0c59D3fD7dfC7aB4e913C6Aa7b68", + "commit_store": "0xF88053B9DAC8Dd3039a4eFa8639159aaa3F2D4Cb", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x45320085fF051361D301eC1044318213A5387A15", + "commit_store": "0x4Dc771B5ef21ef60c33e2987E092345f2b63aE08", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Gnosis Mainnet": { + "off_ramp": "0x0A04eC196454825d361886cf4FA113A948164Ef8", + "commit_store": "0x74b72633b63A8f4374a12DB6F609305BC5a1b2d5", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Optimism Mainnet": { + "off_ramp": "0xBa754ecd3CFA7E9093F688EAc3860cf9D07Fc0AC", + "commit_store": "0x04C0D5302E3D8Ca0A0019141a52a23B59cdb70e4", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "WeMix Mainnet": { + "off_ramp": "0xd7c877ea02310Cce9278D9A048Aa1Bb9aF72F00d", + "commit_store": "0x92A1C927E8E10Ab6A40E5A5154e2300D278d1a67", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "WeMix Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x7D72b22a74A216Af4a002a1095C8C707d6eC1C5f", + "arm": "0xdBa0afF04bf63Ba6b75DEC94d1A934a367CAA782", + "router": "0x7798b795Fde864f4Cd1b124a38Ba9619B7F8A442", + "price_registry": "0x252863688762aD86868D3d3076233Eacd80c7055", + "wrapped_native": "0x7D72b22a74A216Af4a002a1095C8C707d6eC1C5f", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x9aBfd6f4C865610692AB6fb1Be862575809fFabf", + "deployed_at": 0 + }, + "Avalanche Mainnet": { + "on_ramp": "0xbE0Cfae74677F8dd16a246a3a5c8cbB1973118f4", + "deployed_at": 0 + }, + "BSC Mainnet": { + "on_ramp": "0x56657ec4D15C71f7F3C17ba2b21C853A24Dc5381", + "deployed_at": 0 + }, + "Ethereum Mainnet": { + "on_ramp": "0x190bcE84CF2d500B878966F4Cf98a50d78f2675E", + "deployed_at": 0 + }, + "Kroma Mainnet": { + "on_ramp": "0x47E9AE0A815C94836202E696748A5d5476aD8735", + "deployed_at": 0 + }, + "Optimism Mainnet": { + "on_ramp": "0x70f3b0FD7e6a4B9B623e9AB859604A9EE03e48BD", + "deployed_at": 0 + }, + "Polygon Mainnet": { + "on_ramp": "0x777058C1e1dcE4eB8001F38631a1cd9450816e5a", + "deployed_at": 0 } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0x2ba68a395B72a6E3498D312efeD755ed2f3CF223", + "commit_store": "0xdAeC234DA83F68707Bb8AcB2ee6a01a5FD4c2391", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Avalanche Mainnet": { + "off_ramp": "0xFac907F9a1087B846Faa75A14C5d34A8639233d8", + "commit_store": "0xF2812063446c7deD2CA306c67A68364BdDcbEfc5", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "BSC Mainnet": { + "off_ramp": "0x6ec9ca4Cba62cA17c55F05ad2000B46192f02035", + "commit_store": "0x84534BE763366a69710E119c100832955795B34B", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Ethereum Mainnet": { + "off_ramp": "0xF92Fa796F5307b029c65CA26f322a6D86f211194", + "commit_store": "0xbeC110FF43D52be2066B06525304A9924E16b73b", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Kroma Mainnet": { + "off_ramp": "0xF886d8DC64E544af4835cbf91e5678A54D95B80e", + "commit_store": "0x8794C9534658fdCC44f2FF6645Bf31cf9F6d2d5D", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Optimism Mainnet": { + "off_ramp": "0x87220D01DF0fF27149B47227897074653788fd23", + "commit_store": "0xF8dD2be2C6FA43e48A17146380CbEBBB4291807b", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Polygon Mainnet": { + "off_ramp": "0x8f0229804513A9Bc00c1308414AB279Dbc718ae1", + "commit_store": "0x3A85D1b8641d83a87957C6ECF1b62151213e0842", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } + }, + "ZKSync Mainnet": { + "is_native_fee_token": true, + "fee_token": "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91", + "arm": "0x4e2438b1395a462E2e8D164b5f3c65d080919449", + "router": "0x748Fd769d81F5D94752bf8B0875E9301d0ba71bB", + "price_registry": "0xa0C6E00a9Fa10A04989c237dF6dfDCe2AaceE4A3", + "wrapped_native": "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91", + "src_contracts": { + "Arbitrum Mainnet": { + "on_ramp": "0x9033687a0f03012e015f8f8f2a59da57531d2B43", + "deployed_at": 0 + }, + "Ethereum Mainnet": { + "on_ramp": "0x3B80Fe300c9A611abA0496e2543B66Ff7bD4B9e9", + "deployed_at": 0 + } + }, + "dest_contracts": { + "Arbitrum Mainnet": { + "off_ramp": "0xF0a08aC528668D4fe8C4cF235a8B82cbf242Fa9d", + "commit_store": "0x5a3C9b21b03E4eBcccb57D296e7ff54102F04424", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + }, + "Ethereum Mainnet": { + "off_ramp": "0x7c887B97F9Bba9355EC10e2bA949AdB491Ef44Fd", + "commit_store": "0xA42bf0c8794FA8853Ec0F1B24a489972e8CF4C30", + "receiver_dapp": "0xb509c046e1182c7b36d2d9733554bc268716803c" + } + } } + } } """ @@ -650,15 +1081,15 @@ TTL = '8h' [CCIP.Env.Network] selected_networks = [ - 'ETHEREUM_MAINNET', 'ARBITRUM_MAINNET', + 'AVALANCHE_MAINNET', + 'BSC_MAINNET', 'BASE_MAINNET', - 'WEMIX_MAINNET', + 'ETHEREUM_MAINNET', + 'KROMA_MAINNET', 'OPTIMISM_MAINNET', 'POLYGON_MAINNET', - 'AVALANCHE_MAINNET', - 'BSC_MAINNET', - 'KROMA_MAINNET' + 'WEMIX_MAINNET', ] [CCIP.Groups.load] @@ -694,7 +1125,7 @@ NetworkPairs = [ ] BiDirectionalLane = true -PhaseTimeout = '20m' +PhaseTimeout = '30m' ExistingDeployment = true [CCIP.Groups.load.TokenConfig] @@ -704,7 +1135,7 @@ NoOfTokensPerChain = 1 RequestPerUnitTime = [1] TimeUnit = '1h' TestDuration = '5h' -TestRunName = 'mainnet-2.7-ccip1.2' +TestRunName = 'Soak_test_mainnet' FailOnFirstErrorInLoad = true SkipRequestIfAnotherRequestTriggeredWithin = '40m' @@ -718,7 +1149,7 @@ AmountPerToken = 1 [CCIP.Groups.smoke] # these are all the valid network pairs NetworkPairs = [ - 'ETHEREUM_MAINNET,OPTIMISM_MAINNET', + 'ETHEREUM_MAINNET,OPTIMISM_MAINNET', 'ETHEREUM_MAINNET,AVALANCHE_MAINNET', 'ETHEREUM_MAINNET,POLYGON_MAINNET', 'ETHEREUM_MAINNET,BSC_MAINNET', From ac094f7201d68ec2612990dc89054255dc2b4cf3 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Thu, 19 Sep 2024 10:34:29 +0200 Subject: [PATCH 379/432] Add default test config for Grafana (#14475) * Add default test config for Grafana * Use E2E_TEST_GRAFANA_BASE_URL_GAP * Update * Bump ctf * debug - fail test * Fix --- .github/workflows/run-e2e-tests-reusable-workflow.yml | 6 ++---- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- integration-tests/testconfig/default.toml | 5 +++++ 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index f32d541c3d..6eaa3f2798 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -572,8 +572,7 @@ jobs: E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" - E2E_TEST_GRAFANA_DASHBOARD_URL: ${{ matrix.tests.test_env_vars.E2E_TEST_GRAFANA_DASHBOARD_URL || '/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs' }} + E2E_TEST_GRAFANA_DASHBOARD_URL: ${{ matrix.tests.test_env_vars.E2E_TEST_GRAFANA_DASHBOARD_URL }} E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} E2E_TEST_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} E2E_TEST_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} @@ -788,8 +787,7 @@ jobs: E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" - E2E_TEST_GRAFANA_DASHBOARD_URL: ${{ matrix.tests.test_env_vars.E2E_TEST_GRAFANA_DASHBOARD_URL || '/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs' }} + E2E_TEST_GRAFANA_DASHBOARD_URL: ${{ matrix.tests.test_env_vars.E2E_TEST_GRAFANA_DASHBOARD_URL }} E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} E2E_TEST_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} E2E_TEST_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} diff --git a/integration-tests/go.mod b/integration-tests/go.mod index f8317db1bd..c8304390a0 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -41,7 +41,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 - github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index f5ad0d35cc..20a28e1dfb 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1439,8 +1439,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202409 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 h1:Owb1MQZn0NZHwtZAnPZE6TVoTx6xLrfPaUdeOYswE9M= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5/go.mod h1:hS4yNF94C1lkS9gvtFXW8Km8K9NzGeR20aNfkqo5qbE= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6 h1:Pzr5VAMdI2CjFftodGkilMTFlIjCHJ7oqWAD7aZvFeI= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 8ebb563830..67d2bb6509 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 - github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index b3a8d08672..0954d5afd7 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1413,8 +1413,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202409 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5 h1:Owb1MQZn0NZHwtZAnPZE6TVoTx6xLrfPaUdeOYswE9M= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.5/go.mod h1:hS4yNF94C1lkS9gvtFXW8Km8K9NzGeR20aNfkqo5qbE= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6 h1:Pzr5VAMdI2CjFftodGkilMTFlIjCHJ7oqWAD7aZvFeI= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index 5ce1f2b3f6..f147d64be3 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -2,6 +2,11 @@ # set to true to flush logs to selected target regardless of test result; otherwise logs are only flushed if test failed test_log_collect = false +[Logging.Grafana] +base_url="https://grafana.ops.prod.cldev.sh" +base_url_github_ci="http://localhost:8080/primary" +dashboard_url="/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + [Logging.LogStream] # supported targets: file, loki, in-memory. if empty no logs will be persisted log_targets = ["file"] From ef5b9a7407d63b3550137acd91ac333875fcafe1 Mon Sep 17 00:00:00 2001 From: Lee Yik Jiun Date: Thu, 19 Sep 2024 20:22:02 +0800 Subject: [PATCH 380/432] vrf: add soneium config for integration tests (#14443) * vrf: add soneium config for integration tests * update keyhash * update configs --- integration-tests/testconfig/default.toml | 10 ++ .../soneium_sepolia_new_env_test_config.toml | 8 ++ .../soneium_sepolia_staging_test_config.toml | 20 ++++ .../testconfig/vrfv2plus/vrfv2plus.toml | 95 +++++++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/new_env/soneium_sepolia_new_env_test_config.toml create mode 100644 integration-tests/testconfig/vrfv2plus/overrides/staging/soneium_sepolia_staging_test_config.toml diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index f147d64be3..1d84b1d028 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -722,3 +722,13 @@ gas_tip_cap = 30_000_000_000 gas_price_estimation_enabled = true gas_price_estimation_blocks = 500 gas_price_estimation_tx_priority = "standard" + +#### + +[Network.EVMNetworks.SONEIUM_SEPOLIA] +evm_name = "SONEIUM_SEPOLIA" +evm_chain_id = 1946 +client_implementation = "Optimism" +evm_simulated = false + +#### \ No newline at end of file diff --git a/integration-tests/testconfig/vrfv2plus/overrides/new_env/soneium_sepolia_new_env_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/new_env/soneium_sepolia_new_env_test_config.toml new file mode 100644 index 0000000000..beacf9c5f7 --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/new_env/soneium_sepolia_new_env_test_config.toml @@ -0,0 +1,8 @@ +[Network] +selected_networks = ["SONEIUM_SEPOLIA"] + +[SONEIUM_SEPOLIA.VRFv2Plus.General] +use_existing_env = false + +[Logging] +test_log_collect = true diff --git a/integration-tests/testconfig/vrfv2plus/overrides/staging/soneium_sepolia_staging_test_config.toml b/integration-tests/testconfig/vrfv2plus/overrides/staging/soneium_sepolia_staging_test_config.toml new file mode 100644 index 0000000000..df973d8702 --- /dev/null +++ b/integration-tests/testconfig/vrfv2plus/overrides/staging/soneium_sepolia_staging_test_config.toml @@ -0,0 +1,20 @@ +[Network] +selected_networks = ["SONEIUM_SEPOLIA"] + +[SONEIUM_SEPOLIA.VRFv2Plus.General] +use_existing_env = true + +[SONEIUM_SEPOLIA.VRFv2Plus.ExistingEnv] +coordinator_address = "0x81e211D679231615C2601E82B658Bde449AF240f" +consumer_address = "" +use_existing_wrapper = true +wrapper_address = "0xD06CfcDAa6f32BB131e693F99f502ac31588CBC8" +sub_id = "" +key_hash = "0x9552c9542c079db4f8c6867e27f6c4780e3e24d895cb0890ca9984764dbe7200" +create_fund_subs_and_add_consumers = true +node_sending_key_funding_min = 1 +node_sending_keys = [ + "0x22643FcF2018ac636477CFE19Ed17071FF7A5cA0", + # BHS + "0xD012B272E8ec6eA7A3373E340Ead52FA2C7352ea", +] diff --git a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml index c2b0bcfc00..c9f5ac12a8 100644 --- a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml +++ b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml @@ -822,6 +822,101 @@ rate_limit_unit_duration = "1m" rps = 1 +### SONEIUM SEPOLIA Config +[SONEIUM_SEPOLIA.Common] +chainlink_node_funding = 5 +[SONEIUM_SEPOLIA.VRFv2Plus.General] +use_test_coordinator = false +#todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request +minimum_confirmations = 0 + +# Consumer Request config +subscription_billing_type = "LINK_AND_NATIVE" +callback_gas_limit = 1000000 + +# NEW ENV CONFIG +# CL Node config +cl_node_max_gas_price_gwei = 30 +number_of_sending_keys_to_create = 0 + +# Coordinator config +max_gas_limit_coordinator_config = 2500000 +fallback_wei_per_unit_link = "4619667900000000" +staleness_seconds = 172_800 +gas_after_payment_calculation = 42_500 +fulfillment_flat_fee_native_ppm = 0 +fulfillment_flat_fee_link_discount_ppm = 0 +native_premium_percentage = 60 +link_premium_percentage = 50 + +# Wrapper config +wrapped_gas_overhead = 13_400 +coordinator_gas_overhead_native = 128_500 +coordinator_gas_overhead_link = 150_400 +coordinator_gas_overhead_per_word = 435 +coordinator_native_premium_percentage = 60 +coordinator_link_premium_percentage = 50 +wrapper_max_number_of_words = 10 + +# VRF Job config +vrf_job_forwarding_allowed = false +vrf_job_estimate_gas_multiplier = 1.15 +vrf_job_batch_fulfillment_enabled = true +vrf_job_batch_fulfillment_gas_multiplier = 1.1 +vrf_job_poll_period = "2s" +vrf_job_request_timeout = "2h0m0s" +vrf_job_simulation_block = "pending" + +# BHS Job config +bhs_job_wait_blocks = 30 +bhs_job_lookback_blocks = 200 +bhs_job_poll_period = "2s" +bhs_job_run_timeout = "30s" +# NEW ENV CONFIG END + +#SMOKE TEST CONFIG +[SONEIUM_SEPOLIA-Smoke.VRFv2Plus.General] +randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +number_of_sub_to_create = 1 +subscription_funding_amount_link = 3 +subscription_funding_amount_native = 1 +subscription_refunding_amount_link = 3 +subscription_refunding_amount_native = 1 +number_of_words = 1 +random_words_fulfilled_event_timeout = "1m30s" +wait_for_256_blocks_timeout = "10m" + +wrapper_consumer_funding_amount_native_token = 1.0 +wrapper_consumer_funding_amount_link = 5 + +[SONEIUM_SEPOLIA-Soak.VRFv2Plus.General] +randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +number_of_sub_to_create = 1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native = 100 + +[SONEIUM_SEPOLIA-Soak.VRFv2Plus.Performance] +test_duration = "2h" +rate_limit_unit_duration = "10s" +rps = 1 + +[SONEIUM_SEPOLIA-Stress.VRFv2Plus.General] +randomness_request_count_per_request = 60 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +number_of_sub_to_create = 1 +number_of_sending_keys_to_create = 0 +subscription_funding_amount_link = 500 +subscription_funding_amount_native=100 + +[SONEIUM_SEPOLIA-Stress.VRFv2Plus.Performance] +test_duration = "10m" +rate_limit_unit_duration = "1m" +rps = 1 + + ### ETH SEPOLIA Config [SEPOLIA.VRFv2Plus.General] use_test_coordinator = true From 66bced952460e30930f03a7f577150754dffdd1c Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Thu, 19 Sep 2024 07:36:54 -0500 Subject: [PATCH 381/432] core/config/toml: include value in InsecureConnection error message (#14495) --- core/config/toml/types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/config/toml/types.go b/core/config/toml/types.go index 2eb66d10a9..497e33d5dd 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -1695,7 +1695,7 @@ func (b *Telemetry) ValidateConfig() (err error) { } if b.InsecureConnection != nil && *b.InsecureConnection { if build.IsProd() { - err = multierr.Append(err, configutils.ErrInvalid{Name: "InsecureConnection", Msg: "cannot be used in production builds"}) + err = multierr.Append(err, configutils.ErrInvalid{Name: "InsecureConnection", Value: true, Msg: "cannot be used in production builds"}) } } else { if b.CACertFile == nil || *b.CACertFile == "" { From 7ffbfbf948a4c64d4b0c9bc295804654c2235f33 Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Thu, 19 Sep 2024 08:21:26 -0700 Subject: [PATCH 382/432] CCIP-3428 Enabling ccip smoke test for testnet (#14452) * enabling test for testnet * home chain selector logic * testnet deployment * remove unwanted * lint fix * add readme * fix typo * fix * make timer rely on test deadline * update comment * update comment --- integration-tests/actions/actions.go | 7 +- integration-tests/actions/refund.go | 8 + .../ccip-tests/testsetups/test_env.go | 3 + .../contracts/contract_models.go | 6 +- integration-tests/deployment/README.md | 6 +- .../deployment/ccip/add_chain_test.go | 3 +- .../deployment/ccip/add_lane_test.go | 3 +- .../ccip/changeset/2_initial_deploy_test.go | 3 +- .../deployment/ccip/test_assertions.go | 14 +- .../deployment/ccip/test_helpers.go | 25 +-- .../deployment/devenv/.sample.env | 22 ++- integration-tests/deployment/devenv/README.md | 45 +++++ .../deployment/devenv/build_env.go | 185 +++++++++++++++--- integration-tests/deployment/devenv/chain.go | 60 ++---- integration-tests/deployment/devenv/don.go | 78 ++++---- .../deployment/devenv/environment.go | 7 +- integration-tests/deployment/environment.go | 5 +- .../deployment/memory/environment.go | 3 - .../docker/test_env/test_env_builder.go | 39 ++-- integration-tests/smoke/ccip_test.go | 3 +- integration-tests/testconfig/ccip/ccip.toml | 6 + integration-tests/testconfig/ccip/config.go | 7 + .../ccip/overrides/sepolia_avax_binance.toml | 55 ++++++ 23 files changed, 426 insertions(+), 167 deletions(-) create mode 100644 integration-tests/deployment/devenv/README.md create mode 100644 integration-tests/testconfig/ccip/overrides/sepolia_avax_binance.toml diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index c420f8e672..198fa8e0dc 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -25,6 +25,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/conversions" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" ethContracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/smartcontractkit/chainlink/integration-tests/wrappers" @@ -285,7 +286,7 @@ func fundChainlinkNodesAtAnyKey( return err } - fromAddress, err := privateKeyToAddress(privateKey) + fromAddress, err := PrivateKeyToAddress(privateKey) if err != nil { return err } @@ -336,7 +337,7 @@ type FundsToSendPayload struct { // to given address. You can override any or none of the following: gas limit, gas price, gas fee cap, gas tip cap. // Values that are not set will be estimated or taken from config. func SendFunds(logger zerolog.Logger, client *seth.Client, payload FundsToSendPayload) (*types.Receipt, error) { - fromAddress, err := privateKeyToAddress(payload.PrivateKey) + fromAddress, err := PrivateKeyToAddress(payload.PrivateKey) if err != nil { return nil, err } @@ -910,7 +911,7 @@ func deployAnyOCRv1Contracts( return ocrInstances, nil } -func privateKeyToAddress(privateKey *ecdsa.PrivateKey) (common.Address, error) { +func PrivateKeyToAddress(privateKey *ecdsa.PrivateKey) (common.Address, error) { publicKey := privateKey.Public() publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) if !ok { diff --git a/integration-tests/actions/refund.go b/integration-tests/actions/refund.go index 1835d9a04a..bcdf6a380d 100644 --- a/integration-tests/actions/refund.go +++ b/integration-tests/actions/refund.go @@ -234,6 +234,14 @@ func (r *OvershotTransferRetrier) Retry(ctx context.Context, logger zerolog.Logg // of strategies to attempt to return funds, including retrying with less funds if the transaction fails due to // insufficient funds, and retrying with a higher gas limit if the transaction fails due to gas too low. func ReturnFundsFromNodes(log zerolog.Logger, client *seth.Client, chainlinkNodes []contracts.ChainlinkNodeWithKeysAndAddress) error { + var keyExporters []contracts.ChainlinkKeyExporter + for _, node := range chainlinkNodes { + keyExporters = append(keyExporters, node) + } + return ReturnFundsFromKeyExporterNodes(log, client, keyExporters) +} + +func ReturnFundsFromKeyExporterNodes(log zerolog.Logger, client *seth.Client, chainlinkNodes []contracts.ChainlinkKeyExporter) error { if client == nil { return fmt.Errorf("seth client is nil, unable to return funds from chainlink nodes") } diff --git a/integration-tests/ccip-tests/testsetups/test_env.go b/integration-tests/ccip-tests/testsetups/test_env.go index 4d968e8331..263d291453 100644 --- a/integration-tests/ccip-tests/testsetups/test_env.go +++ b/integration-tests/ccip-tests/testsetups/test_env.go @@ -332,6 +332,9 @@ func DeployLocalCluster( // a func to start the CL nodes asynchronously deployCL := func() error { noOfNodes := pointer.GetInt(testInputs.EnvInput.NewCLCluster.NoOfNodes) + if env.ClCluster == nil { + env.ClCluster = &test_env.ClCluster{} + } // if individual nodes are specified, then deploy them with specified configs if len(testInputs.EnvInput.NewCLCluster.Nodes) > 0 { for _, clNode := range testInputs.EnvInput.NewCLCluster.Nodes { diff --git a/integration-tests/contracts/contract_models.go b/integration-tests/contracts/contract_models.go index 46f10f06bb..006ee5db6a 100644 --- a/integration-tests/contracts/contract_models.go +++ b/integration-tests/contracts/contract_models.go @@ -151,9 +151,13 @@ type OffchainAggregatorData struct { type ChainlinkNodeWithKeysAndAddress interface { MustReadOCRKeys() (*client.OCRKeys, error) MustReadP2PKeys() (*client.P2PKeys, error) - ExportEVMKeysForChain(string) ([]*client.ExportedEVMKey, error) PrimaryEthAddress() (string, error) EthAddresses() ([]string, error) + ChainlinkKeyExporter +} + +type ChainlinkKeyExporter interface { + ExportEVMKeysForChain(string) ([]*client.ExportedEVMKey, error) } type ChainlinkNodeWithForwarder interface { diff --git a/integration-tests/deployment/README.md b/integration-tests/deployment/README.md index 1c2019b540..000219c8ab 100644 --- a/integration-tests/deployment/README.md +++ b/integration-tests/deployment/README.md @@ -19,11 +19,11 @@ environments like testnet/mainnet. - In-memory environment for fast integration testing - EVM only -/deployment/docker +/deployment/devenv - Coming soon -- package name `docker` +- package name `devenv` - Docker environment for higher fidelity testing -- Support non-EVMs +- Support non-EVMs (yet to be implemented) /deployment/ccip - package name `ccipdeployment` diff --git a/integration-tests/deployment/ccip/add_chain_test.go b/integration-tests/deployment/ccip/add_chain_test.go index fdfbb6e69a..9441f1a2da 100644 --- a/integration-tests/deployment/ccip/add_chain_test.go +++ b/integration-tests/deployment/ccip/add_chain_test.go @@ -154,8 +154,9 @@ func TestAddChainInbound(t *testing.T) { // TODO: Send via all inbound lanes and use parallel helper // Now that the proposal has been executed we expect to be able to send traffic to this new 4th chain. - startBlock, err := e.Env.Chains[newChain].LatestBlockNum(testcontext.Get(t)) + latesthdr, err := e.Env.Chains[newChain].Client.HeaderByNumber(testcontext.Get(t), nil) require.NoError(t, err) + startBlock := latesthdr.Number.Uint64() seqNr := SendRequest(t, e.Env, state, initialDeploy[0], newChain, true) require.NoError(t, ConfirmExecWithSeqNr(t, e.Env.Chains[initialDeploy[0]], e.Env.Chains[newChain], state.Chains[newChain].OffRamp, &startBlock, seqNr)) diff --git a/integration-tests/deployment/ccip/add_lane_test.go b/integration-tests/deployment/ccip/add_lane_test.go index 63af3b69c4..d43526d8d4 100644 --- a/integration-tests/deployment/ccip/add_lane_test.go +++ b/integration-tests/deployment/ccip/add_lane_test.go @@ -50,8 +50,9 @@ func TestAddLane(t *testing.T) { require.Len(t, offRamps, 0) } } - startBlock, err := e.Env.Chains[to].LatestBlockNum(testcontext.Get(t)) + latesthdr, err := e.Env.Chains[to].Client.HeaderByNumber(testcontext.Get(t), nil) require.NoError(t, err) + startBlock := latesthdr.Number.Uint64() seqNum := SendRequest(t, e.Env, state, from, to, false) require.Equal(t, uint64(1), seqNum) require.NoError(t, ConfirmExecWithSeqNr(t, e.Env.Chains[from], e.Env.Chains[to], state.Chains[to].OffRamp, &startBlock, seqNum)) diff --git a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go index 8de2c4617b..90a8627f38 100644 --- a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go +++ b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go @@ -62,8 +62,9 @@ func Test0002_InitialDeploy(t *testing.T) { if src == dest { continue } - block, err := destChain.LatestBlockNum(testcontext.Get(t)) + latesthdr, err := destChain.Client.HeaderByNumber(testcontext.Get(t), nil) require.NoError(t, err) + block := latesthdr.Number.Uint64() startBlocks[dest] = &block seqNum := ccipdeployment.SendRequest(t, e, state, src, dest, false) expectedSeqNum[dest] = seqNum diff --git a/integration-tests/deployment/ccip/test_assertions.go b/integration-tests/deployment/ccip/test_assertions.go index 2041c1a977..02a10fff3e 100644 --- a/integration-tests/deployment/ccip/test_assertions.go +++ b/integration-tests/deployment/ccip/test_assertions.go @@ -78,7 +78,15 @@ func ConfirmCommitWithExpectedSeqNumRange( } defer subscription.Unsubscribe() - timer := time.NewTimer(5 * time.Minute) + var duration time.Duration + deadline, ok := t.Deadline() + if ok { + // make this timer end a minute before so that we don't hit the deadline + duration = deadline.Sub(time.Now().Add(-1 * time.Minute)) + } else { + duration = 5 * time.Minute + } + timer := time.NewTimer(duration) defer timer.Stop() ticker := time.NewTicker(2 * time.Second) defer ticker.Stop() @@ -97,8 +105,8 @@ func ConfirmCommitWithExpectedSeqNumRange( case subErr := <-subscription.Err(): return fmt.Errorf("subscription error: %w", subErr) case <-timer.C: - return fmt.Errorf("timed out waiting for commit report on chain selector %d from source selector %d expected seq nr range %s", - dest.Selector, src.Selector, expectedSeqNumRange.String()) + return fmt.Errorf("timed out after waiting %s duration for commit report on chain selector %d from source selector %d expected seq nr range %s", + duration.String(), dest.Selector, src.Selector, expectedSeqNumRange.String()) case report := <-sink: if len(report.Report.MerkleRoots) > 0 { // Check the interval of sequence numbers and make sure it matches diff --git a/integration-tests/deployment/ccip/test_helpers.go b/integration-tests/deployment/ccip/test_helpers.go index 4458a49abc..330cbae196 100644 --- a/integration-tests/deployment/ccip/test_helpers.go +++ b/integration-tests/deployment/ccip/test_helpers.go @@ -8,6 +8,8 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/ethereum/go-ethereum/common" chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" @@ -158,7 +160,9 @@ func SendRequest(t *testing.T, e deployment.Environment, state CCIPOnChainState, }, []uint64{dest}) require.NoError(t, err) require.True(t, it.Next()) - return it.Event.Message.Header.SequenceNumber + seqNum := it.Event.Message.Header.SequenceNumber + t.Logf("CCIP message sent from chain selector %d to chain selector %d tx %s seqNum %d", src, dest, tx.Hash().String(), seqNum) + return seqNum } // DeployedLocalDevEnvironment is a helper struct for setting up a local dev environment with docker @@ -179,15 +183,13 @@ func NewDeployedLocalDevEnvironment(t *testing.T, lggr logger.Logger) DeployedLo require.NotEmpty(t, envConfig.JDConfig, "jdUrl should not be empty") chains, err := devenv.NewChains(lggr, envConfig.Chains) require.NoError(t, err) - homeChainSel := uint64(0) - homeChainEVM := uint64(0) + // locate the home chain + homeChainSel := envConfig.HomeChainSelector + require.NotEmpty(t, homeChainSel, "homeChainSel should not be empty") + homeChainEVM, err := chainsel.ChainIdFromSelector(homeChainSel) + require.NoError(t, err) + require.NotEmpty(t, homeChainEVM, "homeChainEVM should not be empty") - // Say first chain is home chain. - for chainSel := range chains { - homeChainEVM, _ = chainsel.ChainIdFromSelector(chainSel) - homeChainSel = chainSel - break - } // deploy the capability registry ab, capReg, err := DeployCapReg(lggr, chains, homeChainSel) require.NoError(t, err) @@ -205,10 +207,9 @@ func NewDeployedLocalDevEnvironment(t *testing.T, lggr logger.Logger) DeployedLo require.NoError(t, err) require.NotNil(t, e) require.NotNil(t, don) - + zeroLogLggr := logging.GetTestLogger(t) // fund the nodes - require.NoError(t, don.FundNodes(ctx, deployment.E18Mult(10), e.Chains)) - + devenv.FundNodes(t, zeroLogLggr, testEnv, cfg, don.PluginNodes()) return DeployedLocalDevEnvironment{ Ab: ab, Env: *e, diff --git a/integration-tests/deployment/devenv/.sample.env b/integration-tests/deployment/devenv/.sample.env index 97d550079a..f0505cf857 100644 --- a/integration-tests/deployment/devenv/.sample.env +++ b/integration-tests/deployment/devenv/.sample.env @@ -2,4 +2,24 @@ E2E_JD_IMAGE= E2E_JD_VERSION= E2E_TEST_CHAINLINK_IMAGE=public.ecr.aws/w0i8p0z9/chainlink-ccip -E2E_TEST_CHAINLINK_VERSION=2.14.0-ccip1.5.0 \ No newline at end of file +E2E_TEST_CHAINLINK_VERSION=2.14.0-ccip1.5.0 + +# RPC Configuration +E2E_TEST_SEPOLIA_WALLET_KEY= +E2E_TEST_SEPOLIA_RPC_HTTP_URL_1= +E2E_TEST_SEPOLIA_RPC_HTTP_URL_2= +E2E_TEST_SEPOLIA_RPC_WS_URL_1= +E2E_TEST_SEPOLIA_RPC_WS_URL_2= + +E2E_TEST_AVALANCHE_FUJI_WALLET_KEY= +E2E_TEST_AVALANCHE_FUJI_RPC_HTTP_URL_1= +E2E_TEST_AVALANCHE_FUJI_RPC_HTTP_URL_2= +E2E_TEST_AVALANCHE_FUJI_RPC_WS_URL_1= +E2E_TEST_AVALANCHE_FUJI_RPC_WS_URL_2= + +E2E_TEST_BSC_TESTNET_WALLET_KEY= +E2E_TEST_BSC_TESTNET_RPC_HTTP_URL_1= +E2E_TEST_BSC_TESTNET_RPC_HTTP_URL_2= +E2E_TEST_BSC_TESTNET_RPC_WS_URL_1= +E2E_TEST_BSC_TESTNET_RPC_WS_URL_2= + diff --git a/integration-tests/deployment/devenv/README.md b/integration-tests/deployment/devenv/README.md new file mode 100644 index 0000000000..a1f264dfce --- /dev/null +++ b/integration-tests/deployment/devenv/README.md @@ -0,0 +1,45 @@ +## Overview + +This package is used to create ephemeral environment for local/CI testing. +It sets up an environment with local Docker containers running Chainlink nodes and a job distributor. +It can either create new simulated private Ethereum network containers or connect to existing testnets/mainnets. + +### Run Tests with Devenv + +The tests created with this environment are run as [end-to-end integration smoke tests](../../smoke). + +#### Setting Up Testconfig with Simulated Private Ethereum Network + +To run tests (e.g., [ccip-test](../../smoke/ccip_test.go)), +you need to set up the testconfig following the [testconfig setup instructions](../../testconfig/README.md). +The testconfig specifies the details of the different configurations to set up the environment and run the tests. +Generally, tests are run with the [default](../../testconfig/default.toml) config unless overridden by product-specific config. +For example, the [ccip-test](../../smoke/ccip_test.go) uses [ccip.toml](../../testconfig/ccip/ccip.toml) to specify +CCIP-specific test environment details. + +There are additional secret configuration parameters required by the `devenv` environment that are not stored in the testconfig. +These are read from environment variables. For example, Chainlink image, Job-Distributor image, etc. +All such environment variables are listed in the [sample.env](./.sample.env) file. +You can create a `.env` file in the same directory of the test and set the required environment variables. + +#### Setting Up Testconfig for Running Tests with Existing Testnet/Mainnet + +To run tests with existing testnet/mainnet, set up the testconfig with the details of the testnet/mainnet networks. +Following the integration-test [testconfig framework](../../testconfig/README.md#configuration-and-overrides), +create a new `overrides.toml` file with testnet/mainnet network details and place it under any location in the `integration-tests` directory. +By default, tests are run with private Ethereum network containers set up in the same Docker network as +the Chainlink nodes and job distributor. To run tests against existing testnet/mainnet, +set the `selected_network` field in the testconfig with the specific network names. + +For example, if running [ccip-smoke](../../smoke/ccip_test.go) tests with Sepolia, Avax, and Binance testnets, +copy the contents of [sepolia_avax_binance.toml](../../testconfig/ccip/overrides/sepolia_avax_binance.toml) +to the `overrides.toml` file. + +Before running the test, ensure that RPC and wallet secrets are set as environment variables. +Refer to the environment variables pattern in the [sample.env](./.sample.env) file to +provide necessary secrets applicable to the network you are running the tests against: +- `E2E_TEST__WALLET_KEY_` +- `E2E_TEST__RPC_HTTP_URL_` +- `E2E_TEST__RPC_WS_URL_` + +Now you are all set to run the tests with the existing testnet/mainnet. \ No newline at end of file diff --git a/integration-tests/deployment/devenv/build_env.go b/integration-tests/deployment/devenv/build_env.go index 0373cf0b21..61e677ca43 100644 --- a/integration-tests/deployment/devenv/build_env.go +++ b/integration-tests/deployment/devenv/build_env.go @@ -9,22 +9,30 @@ import ( "github.com/AlekSi/pointer" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/rs/zerolog" chainselectors "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" "github.com/subosito/gotenv" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/conversions" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env/job_distributor" "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" + "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" clclient "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/deployment" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) @@ -43,18 +51,31 @@ func CreateDockerEnv(t *testing.T) ( cfg, err := tc.GetChainAndTestTypeSpecificConfig("Smoke", tc.CCIP) require.NoError(t, err, "Error getting config") + evmNetworks := networks.MustGetSelectedNetworkConfig(cfg.GetNetworkConfig()) + + // find out if the selected networks are provided with PrivateEthereumNetworks configs + // if yes, PrivateEthereumNetworkConfig will be used to create simulated private ethereum networks in docker environment var privateEthereumNetworks []*ctf_config.EthereumNetworkConfig - for _, network := range cfg.CCIP.PrivateEthereumNetworks { - privateEthereumNetworks = append(privateEthereumNetworks, network) + for _, name := range cfg.GetNetworkConfig().SelectedNetworks { + if network, exists := cfg.CCIP.PrivateEthereumNetworks[name]; exists { + privateEthereumNetworks = append(privateEthereumNetworks, network) + } } - env, err := test_env.NewCLTestEnvBuilder(). + + builder := test_env.NewCLTestEnvBuilder(). WithTestConfig(&cfg). WithTestInstance(t). - WithPrivateEthereumNetworks(privateEthereumNetworks). - WithStandardCleanup(). - Build() + WithStandardCleanup() + + // if private ethereum networks are provided, we will use them to create the test environment + // otherwise we will use the network URLs provided in the network config + if len(privateEthereumNetworks) > 0 { + builder = builder.WithPrivateEthereumNetworks(privateEthereumNetworks) + } + env, err := builder.Build() require.NoError(t, err, "Error building test environment") - chains := CreateChainConfigFromPrivateEthereumNetworks(t, env, cfg.CCIP.PrivateEthereumNetworks, cfg.GetNetworkConfig()) + + chains := CreateChainConfigFromNetworks(t, env, privateEthereumNetworks, cfg.GetNetworkConfig()) var jdConfig JDConfig // TODO : move this as a part of test_env setup with an input in testconfig @@ -89,9 +110,24 @@ func CreateDockerEnv(t *testing.T) ( } require.NotEmpty(t, jdConfig, "JD config is empty") + homeChainSelector, err := cfg.CCIP.GetHomeChainSelector() + require.NoError(t, err, "Error getting home chain selector") + homeChainID, err := chainselectors.ChainIdFromSelector(homeChainSelector) + require.NoError(t, err, "Error getting chain id from selector") + // verify if the home chain selector is valid + validHomeChain := false + for _, net := range evmNetworks { + if net.ChainID == int64(homeChainID) { + validHomeChain = true + break + } + } + require.True(t, validHomeChain, "Invalid home chain selector, chain not found in network config") + return &EnvironmentConfig{ - Chains: chains, - JDConfig: jdConfig, + Chains: chains, + JDConfig: jdConfig, + HomeChainSelector: homeChainSelector, }, env, cfg } @@ -107,12 +143,19 @@ func StartChainlinkNodes( ) error { evmNetworks := networks.MustGetSelectedNetworkConfig(cfg.GetNetworkConfig()) for i, net := range evmNetworks { - rpcProvider, err := env.GetRpcProvider(net.ChainID) - require.NoError(t, err, "Error getting rpc provider") - evmNetworks[i].HTTPURLs = rpcProvider.PrivateHttpUrls() - evmNetworks[i].URLs = rpcProvider.PrivateWsUrsl() + // if network is simulated, update the URLs with private chain RPCs in the docker test environment + // so that nodes can internally connect to the chain + if net.Simulated { + rpcProvider, err := env.GetRpcProvider(net.ChainID) + require.NoError(t, err, "Error getting rpc provider") + evmNetworks[i].HTTPURLs = rpcProvider.PrivateHttpUrls() + evmNetworks[i].URLs = rpcProvider.PrivateWsUrsl() + } } noOfNodes := pointer.GetInt(cfg.CCIP.CLNode.NoOfPluginNodes) + pointer.GetInt(cfg.CCIP.CLNode.NoOfBootstraps) + if env.ClCluster == nil { + env.ClCluster = &test_env.ClCluster{} + } var nodeInfo []NodeInfo for i := 1; i <= noOfNodes; i++ { if i <= pointer.GetInt(cfg.CCIP.CLNode.NoOfBootstraps) { @@ -172,17 +215,88 @@ func StartChainlinkNodes( InternalIP: n.API.InternalIP(), } } - envConfig.nodeInfo = nodeInfo return nil } -// CreateChainConfigFromPrivateEthereumNetworks creates a list of ChainConfig from the private ethereum networks created by the test environment. +// FundNodes sends funds to the chainlink nodes based on the provided test config +// It also sets up a clean-up function to return the funds back to the deployer account once the test is done +// It assumes that the chainlink nodes are already started and the account addresses for all chains are available +func FundNodes(t *testing.T, lggr zerolog.Logger, env *test_env.CLClusterTestEnv, cfg tc.TestConfig, nodes []Node) { + evmNetworks := networks.MustGetSelectedNetworkConfig(cfg.GetNetworkConfig()) + for i, net := range evmNetworks { + // if network is simulated, update the URLs with deployed chain RPCs in the docker test environment + if net.Simulated { + rpcProvider, err := env.GetRpcProvider(net.ChainID) + require.NoError(t, err, "Error getting rpc provider") + evmNetworks[i].HTTPURLs = rpcProvider.PublicHttpUrls() + evmNetworks[i].URLs = rpcProvider.PublicWsUrls() + } + } + t.Cleanup(func() { + for i := range evmNetworks { + // if simulated no need for balance return + if evmNetworks[i].Simulated { + continue + } + evmNetwork := evmNetworks[i] + sethClient, err := utils.TestAwareSethClient(t, cfg, &evmNetwork) + require.NoError(t, err, "Error getting seth client for network %s", evmNetwork.Name) + require.Greater(t, len(sethClient.PrivateKeys), 0, seth.ErrNoKeyLoaded) + var keyExporters []contracts.ChainlinkKeyExporter + for j := range nodes { + node := nodes[j] + keyExporters = append(keyExporters, &node) + } + if err := actions.ReturnFundsFromKeyExporterNodes(lggr, sethClient, keyExporters); err != nil { + lggr.Error().Err(err).Str("Network", evmNetwork.Name). + Msg("Error attempting to return funds from chainlink nodes to network's default wallet. " + + "Environment is left running so you can try manually!") + } + } + }) + for i := range evmNetworks { + evmNetwork := evmNetworks[i] + sethClient, err := utils.TestAwareSethClient(t, cfg, &evmNetwork) + require.NoError(t, err, "Error getting seth client for network %s", evmNetwork.Name) + require.Greater(t, len(sethClient.PrivateKeys), 0, seth.ErrNoKeyLoaded) + privateKey := sethClient.PrivateKeys[0] + for _, node := range nodes { + nodeAddr, ok := node.AccountAddr[uint64(evmNetwork.ChainID)] + require.True(t, ok, "Account address not found for chain %d", evmNetwork.ChainID) + fromAddress, err := actions.PrivateKeyToAddress(privateKey) + require.NoError(t, err, "Error getting address from private key") + amount := big.NewFloat(pointer.GetFloat64(cfg.Common.ChainlinkNodeFunding)) + toAddr := common.HexToAddress(nodeAddr) + receipt, err := actions.SendFunds(lggr, sethClient, actions.FundsToSendPayload{ + ToAddress: toAddr, + Amount: conversions.EtherToWei(amount), + PrivateKey: privateKey, + }) + require.NoError(t, err, "Error sending funds to node %s", node.Name) + require.NotNil(t, receipt, "Receipt is nil") + txHash := "(none)" + if receipt != nil { + txHash = receipt.TxHash.String() + } + lggr.Info(). + Str("From", fromAddress.Hex()). + Str("To", toAddr.String()). + Str("TxHash", txHash). + Str("Amount", amount.String()). + Msg("Funded Chainlink node") + } + } +} + +// CreateChainConfigFromNetworks creates a list of ChainConfig from the network config provided in test config. +// It either creates it from the private ethereum networks created by the test environment or from the +// network URLs provided in the network config ( if the network is a live testnet). // It uses the private keys from the network config to create the deployer key for each chain. -func CreateChainConfigFromPrivateEthereumNetworks( +func CreateChainConfigFromNetworks( t *testing.T, env *test_env.CLClusterTestEnv, - privateEthereumNetworks map[string]*ctf_config.EthereumNetworkConfig, + privateEthereumNetworks []*ctf_config.EthereumNetworkConfig, networkConfig *ctf_config.NetworkConfig, ) []ChainConfig { evmNetworks := networks.MustGetSelectedNetworkConfig(networkConfig) @@ -192,6 +306,29 @@ func CreateChainConfigFromPrivateEthereumNetworks( networkPvtKeys[net.ChainID] = net.PrivateKeys[0] } var chains []ChainConfig + // if private ethereum networks are not provided, we will create chains from the network URLs + if len(privateEthereumNetworks) == 0 { + for _, net := range evmNetworks { + chainId := net.ChainID + chainName, err := chainselectors.NameFromChainId(uint64(chainId)) + require.NoError(t, err, "Error getting chain name") + pvtKeyStr, exists := networkPvtKeys[chainId] + require.Truef(t, exists, "Private key not found for chain id %d", chainId) + pvtKey, err := crypto.HexToECDSA(pvtKeyStr) + require.NoError(t, err) + deployer, err := bind.NewKeyedTransactorWithChainID(pvtKey, big.NewInt(chainId)) + require.NoError(t, err) + chains = append(chains, ChainConfig{ + ChainID: uint64(chainId), + ChainName: chainName, + ChainType: "EVM", + WSRPCs: net.URLs, + HTTPRPCs: net.HTTPURLs, + DeployerKey: deployer, + }) + } + return chains + } for _, networkCfg := range privateEthereumNetworks { chainId := networkCfg.EthereumChainConfig.ChainID chainName, err := chainselectors.NameFromChainId(uint64(chainId)) @@ -205,14 +342,12 @@ func CreateChainConfigFromPrivateEthereumNetworks( deployer, err := bind.NewKeyedTransactorWithChainID(pvtKey, big.NewInt(int64(chainId))) require.NoError(t, err) chains = append(chains, ChainConfig{ - ChainID: uint64(chainId), - ChainName: chainName, - ChainType: "EVM", - WSRPCs: rpcProvider.PublicWsUrls(), - HTTPRPCs: rpcProvider.PublicHttpUrls(), - PrivateHTTPRPCs: rpcProvider.PrivateHttpUrls(), - PrivateWSRPCs: rpcProvider.PrivateWsUrsl(), - DeployerKey: deployer, + ChainID: uint64(chainId), + ChainName: chainName, + ChainType: "EVM", + WSRPCs: rpcProvider.PublicWsUrls(), + HTTPRPCs: rpcProvider.PublicHttpUrls(), + DeployerKey: deployer, }) } return chains diff --git a/integration-tests/deployment/devenv/chain.go b/integration-tests/deployment/devenv/chain.go index 6374a2c213..e40bbc066f 100644 --- a/integration-tests/deployment/devenv/chain.go +++ b/integration-tests/deployment/devenv/chain.go @@ -3,11 +3,9 @@ package devenv import ( "context" "fmt" - "math/big" "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "github.com/sethvargo/go-retry" @@ -20,14 +18,12 @@ import ( // ChainConfig holds the configuration for a with a deployer key which can be used to send transactions to the chain. type ChainConfig struct { - ChainID uint64 // chain id as per EIP-155, mainly applicable for EVM chains - ChainName string // name of the chain populated from chainselector repo - ChainType string // should denote the chain family. Acceptable values are EVM, COSMOS, SOLANA, STARKNET, APTOS etc - WSRPCs []string // websocket rpcs to connect to the chain - HTTPRPCs []string // http rpcs to connect to the chain - PrivateWSRPCs []string // applicable for private chains spun up with docker/K8s only so that nodes within same cluster can connect internally - PrivateHTTPRPCs []string // applicable for private chains spun up with docker/K8s only so that nodes within same cluster can connect internally - DeployerKey *bind.TransactOpts // key to send transactions to the chain + ChainID uint64 // chain id as per EIP-155, mainly applicable for EVM chains + ChainName string // name of the chain populated from chainselector repo + ChainType string // should denote the chain family. Acceptable values are EVM, COSMOS, SOLANA, STARKNET, APTOS etc + WSRPCs []string // websocket rpcs to connect to the chain + HTTPRPCs []string // http rpcs to connect to the chain + DeployerKey *bind.TransactOpts // key to send transactions to the chain } func NewChains(logger logger.Logger, configs []ChainConfig) (map[uint64]deployment.Chain, error) { @@ -52,10 +48,9 @@ func NewChains(logger logger.Logger, configs []ChainConfig) (map[uint64]deployme return nil, fmt.Errorf("failed to connect to chain %s", chainCfg.ChainName) } chains[selector] = deployment.Chain{ - Selector: selector, - Client: ec, - DeployerKey: chainCfg.DeployerKey, - LatestBlockNum: ec.BlockNumber, + Selector: selector, + Client: ec, + DeployerKey: chainCfg.DeployerKey, Confirm: func(tx *types.Transaction) (uint64, error) { var blockNumber uint64 if tx == nil { @@ -64,9 +59,13 @@ func NewChains(logger logger.Logger, configs []ChainConfig) (map[uint64]deployme err := retry.Do(context.Background(), retry.WithMaxDuration(3*time.Minute, retry.NewFibonacci(1*time.Second)), func(ctx context.Context) error { - receipt, err := ec.TransactionReceipt(ctx, tx.Hash()) + chainId, err := ec.ChainID(ctx) if err != nil { - return retry.RetryableError(fmt.Errorf("failed to get receipt: %w", err)) + return fmt.Errorf("failed to get chain id: %w", err) + } + receipt, err := bind.WaitMined(ctx, ec, tx) + if err != nil { + return retry.RetryableError(fmt.Errorf("failed to get receipt for chain %d: %w", chainId, err)) } if receipt != nil { blockNumber = receipt.BlockNumber.Uint64() @@ -90,32 +89,3 @@ func NewChains(logger logger.Logger, configs []ChainConfig) (map[uint64]deployme } return chains, nil } - -// TODO : Remove this when seth is integrated. -func FundAddress(ctx context.Context, from *bind.TransactOpts, to common.Address, amount *big.Int, c deployment.Chain) error { - nonce, err := c.Client.PendingNonceAt(ctx, from.From) - if err != nil { - return fmt.Errorf("failed to get nonce: %w", err) - } - gp, err := c.Client.SuggestGasPrice(ctx) - if err != nil { - return fmt.Errorf("failed to suggest gas price: %w", err) - } - rawTx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gp, - Gas: 21000, - To: &to, - Value: amount, - }) - signedTx, err := from.Signer(from.From, rawTx) - if err != nil { - return fmt.Errorf("failed to sign tx: %w", err) - } - err = c.Client.SendTransaction(ctx, signedTx) - if err != nil { - return fmt.Errorf("failed to send tx: %w", err) - } - _, err = c.Confirm(signedTx) - return err -} diff --git a/integration-tests/deployment/devenv/don.go b/integration-tests/deployment/devenv/don.go index 663f4c3329..ab64eab5c5 100644 --- a/integration-tests/deployment/devenv/don.go +++ b/integration-tests/deployment/devenv/don.go @@ -3,17 +3,14 @@ package devenv import ( "context" "fmt" - "math/big" "strconv" "strings" "github.com/AlekSi/pointer" - "github.com/ethereum/go-ethereum/common" "github.com/hashicorp/go-multierror" - chainselectors "github.com/smartcontractkit/chain-selectors" + "github.com/rs/zerolog" clclient "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/deployment" nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1" "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/shared/ptypes" "github.com/smartcontractkit/chainlink/integration-tests/web/sdk/client" @@ -38,6 +35,18 @@ type DON struct { Nodes []Node } +func (don *DON) PluginNodes() []Node { + var pluginNodes []Node + for _, node := range don.Nodes { + for _, label := range node.labels { + if label.Key == NodeLabelKeyType && pointer.GetString(label.Value) == NodeLabelValuePlugin { + pluginNodes = append(pluginNodes, node) + } + } + } + return pluginNodes +} + func (don *DON) NodeIds() []string { var nodeIds []string for _, node := range don.Nodes { @@ -46,27 +55,6 @@ func (don *DON) NodeIds() []string { return nodeIds } -func (don *DON) FundNodes(ctx context.Context, amount *big.Int, chains map[uint64]deployment.Chain) error { - var err error - for sel, chain := range chains { - for _, node := range don.Nodes { - // if node is bootstrap, no need to fund it - if node.multiAddr != "" { - continue - } - accountAddr, ok := node.AccountAddr[sel] - if !ok { - err = multierror.Append(err, fmt.Errorf("node %s has no account address for chain %d", node.Name, sel)) - continue - } - if err1 := FundAddress(ctx, chain.DeployerKey, common.HexToAddress(accountAddr), amount, chain); err1 != nil { - err = multierror.Append(err, err1) - } - } - } - return err -} - func (don *DON) CreateSupportedChains(ctx context.Context, chains []ChainConfig) error { var err error for i, node := range don.Nodes { @@ -129,24 +117,30 @@ func NewNode(nodeInfo NodeInfo) (*Node, error) { Password: nodeInfo.CLConfig.Password, }) if err != nil { - return nil, fmt.Errorf("failed to create FMS client: %w", err) + return nil, fmt.Errorf("failed to create node graphql client: %w", err) + } + chainlinkClient, err := clclient.NewChainlinkClient(&nodeInfo.CLConfig, zerolog.Logger{}) + if err != nil { + return nil, fmt.Errorf("failed to create node rest client: %w", err) } return &Node{ - gqlClient: gqlClient, - Name: nodeInfo.Name, - adminAddr: nodeInfo.AdminAddr, + gqlClient: gqlClient, + restClient: chainlinkClient, + Name: nodeInfo.Name, + adminAddr: nodeInfo.AdminAddr, }, nil } type Node struct { - NodeId string // node id returned by job distributor after node is registered with it - JDId string // job distributor id returned by node after Job distributor is created in node - Name string // name of the node - AccountAddr map[uint64]string // chain selector to node's account address mapping for supported chains - gqlClient client.Client // graphql client to interact with the node - labels []*ptypes.Label // labels with which the node is registered with the job distributor - adminAddr string // admin address to send payments to, applicable only for non-bootstrap nodes - multiAddr string // multi address denoting node's FQN (needed for deriving P2PBootstrappers in OCR), applicable only for bootstrap nodes + NodeId string // node id returned by job distributor after node is registered with it + JDId string // job distributor id returned by node after Job distributor is created in node + Name string // name of the node + AccountAddr map[uint64]string // chain selector to node's account address mapping for supported chains + gqlClient client.Client // graphql client to interact with the node + restClient *clclient.ChainlinkClient // rest client to interact with the node + labels []*ptypes.Label // labels with which the node is registered with the job distributor + adminAddr string // admin address to send payments to, applicable only for non-bootstrap nodes + multiAddr string // multi address denoting node's FQN (needed for deriving P2PBootstrappers in OCR), applicable only for bootstrap nodes } // CreateCCIPOCRSupportedChains creates a JobDistributorChainConfig for the node. @@ -156,10 +150,6 @@ type Node struct { func (n *Node) CreateCCIPOCRSupportedChains(ctx context.Context, chains []ChainConfig) error { for _, chain := range chains { chainId := strconv.FormatUint(chain.ChainID, 10) - selector, err := chainselectors.SelectorFromChainId(chain.ChainID) - if err != nil { - return fmt.Errorf("failed to get selector from chain id %d: %w", chain.ChainID, err) - } accountAddr, err := n.gqlClient.FetchAccountAddress(ctx, chainId) if err != nil { return fmt.Errorf("failed to fetch account address for node %s: %w", n.Name, err) @@ -170,7 +160,7 @@ func (n *Node) CreateCCIPOCRSupportedChains(ctx context.Context, chains []ChainC if n.AccountAddr == nil { n.AccountAddr = make(map[uint64]string) } - n.AccountAddr[selector] = *accountAddr + n.AccountAddr[chain.ChainID] = *accountAddr peerID, err := n.gqlClient.FetchP2PPeerID(ctx) if err != nil { return fmt.Errorf("failed to fetch peer id for node %s: %w", n.Name, err) @@ -286,3 +276,7 @@ func (n *Node) SetUpAndLinkJobDistributor(ctx context.Context, jd JobDistributor n.JDId = id return nil } + +func (n *Node) ExportEVMKeysForChain(chainId string) ([]*clclient.ExportedEVMKey, error) { + return n.restClient.ExportEVMKeysForChain(chainId) +} diff --git a/integration-tests/deployment/devenv/environment.go b/integration-tests/deployment/devenv/environment.go index a62f7f5e84..f7513798e3 100644 --- a/integration-tests/deployment/devenv/environment.go +++ b/integration-tests/deployment/devenv/environment.go @@ -14,9 +14,10 @@ const ( ) type EnvironmentConfig struct { - Chains []ChainConfig - nodeInfo []NodeInfo - JDConfig JDConfig + Chains []ChainConfig + HomeChainSelector uint64 + nodeInfo []NodeInfo + JDConfig JDConfig } func NewEnvironment(ctx context.Context, lggr logger.Logger, config EnvironmentConfig) (*deployment.Environment, *DON, error) { diff --git a/integration-tests/deployment/environment.go b/integration-tests/deployment/environment.go index 8d8fc909a9..0f3c85a362 100644 --- a/integration-tests/deployment/environment.go +++ b/integration-tests/deployment/environment.go @@ -45,9 +45,8 @@ type Chain struct { Selector uint64 Client OnchainClient // Note the Sign function can be abstract supporting a variety of key storage mechanisms (e.g. KMS etc). - DeployerKey *bind.TransactOpts - LatestBlockNum func(ctx context.Context) (uint64, error) - Confirm func(tx *types.Transaction) (uint64, error) + DeployerKey *bind.TransactOpts + Confirm func(tx *types.Transaction) (uint64, error) } type Environment struct { diff --git a/integration-tests/deployment/memory/environment.go b/integration-tests/deployment/memory/environment.go index 5ae9446494..409e8d3a81 100644 --- a/integration-tests/deployment/memory/environment.go +++ b/integration-tests/deployment/memory/environment.go @@ -41,9 +41,6 @@ func NewMemoryChains(t *testing.T, numChains int) map[uint64]deployment.Chain { Selector: sel, Client: chain.Backend, DeployerKey: chain.DeployerKey, - LatestBlockNum: func(ctx context.Context) (uint64, error) { - return chain.Backend.Blockchain().CurrentBlock().Number.Uint64(), nil - }, Confirm: func(tx *types.Transaction) (uint64, error) { if tx == nil { return 0, fmt.Errorf("tx was nil, nothing to confirm") diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go index a26c72a853..bd3a458165 100644 --- a/integration-tests/docker/test_env/test_env_builder.go +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -24,6 +24,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" "github.com/smartcontractkit/chainlink-testing-framework/lib/testsummary" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/osutil" + "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" ) @@ -409,29 +410,29 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { b.te.rpcProviders[networkConfig.ChainID] = &rpcProvider b.te.EVMNetworks = append(b.te.EVMNetworks, &networkConfig) } + if b.clNodesCount > 0 { + dereferrencedEvms := make([]blockchain.EVMNetwork, 0) + for _, en := range b.te.EVMNetworks { + dereferrencedEvms = append(dereferrencedEvms, *en) + } - dereferrencedEvms := make([]blockchain.EVMNetwork, 0) - for _, en := range b.te.EVMNetworks { - dereferrencedEvms = append(dereferrencedEvms, *en) - } - - nodeConfigInToml := b.testConfig.GetNodeConfig() + nodeConfigInToml := b.testConfig.GetNodeConfig() - nodeConfig, _, err := node.BuildChainlinkNodeConfig( - dereferrencedEvms, - nodeConfigInToml.BaseConfigTOML, - nodeConfigInToml.CommonChainConfigTOML, - nodeConfigInToml.ChainConfigTOMLByChainID, - ) - if err != nil { - return nil, err - } + nodeConfig, _, err := node.BuildChainlinkNodeConfig( + dereferrencedEvms, + nodeConfigInToml.BaseConfigTOML, + nodeConfigInToml.CommonChainConfigTOML, + nodeConfigInToml.ChainConfigTOMLByChainID, + ) + if err != nil { + return nil, err + } - err = b.te.StartClCluster(nodeConfig, b.clNodesCount, b.secretsConfig, b.testConfig, b.clNodesOpts...) - if err != nil { - return nil, err + err = b.te.StartClCluster(nodeConfig, b.clNodesCount, b.secretsConfig, b.testConfig, b.clNodesOpts...) + if err != nil { + return nil, err + } } - b.te.isSimulatedNetwork = true return b.te, nil diff --git a/integration-tests/smoke/ccip_test.go b/integration-tests/smoke/ccip_test.go index d6c65f3c0e..759e8eac1e 100644 --- a/integration-tests/smoke/ccip_test.go +++ b/integration-tests/smoke/ccip_test.go @@ -73,8 +73,9 @@ func Test0002_InitialDeployOnLocal(t *testing.T) { if src == dest { continue } - block, err := destChain.LatestBlockNum(testcontext.Get(t)) + latesthdr, err := destChain.Client.HeaderByNumber(testcontext.Get(t), nil) require.NoError(t, err) + block := latesthdr.Number.Uint64() startBlocks[dest] = &block seqNum := ccipdeployment.SendRequest(t, e, state, src, dest, false) expectedSeqNum[dest] = seqNum diff --git a/integration-tests/testconfig/ccip/ccip.toml b/integration-tests/testconfig/ccip/ccip.toml index cc8d82f246..3a27d0cd54 100644 --- a/integration-tests/testconfig/ccip/ccip.toml +++ b/integration-tests/testconfig/ccip/ccip.toml @@ -1,3 +1,7 @@ +[Common] +# chainlink node funding in native token +chainlink_node_funding = 1 + [Network] selected_networks = ['SIMULATED_1', 'SIMULATED_2'] @@ -86,6 +90,8 @@ DeltaReconcile = '5s' """ [CCIP] +HomeChainSelector = '12922642891491394802' # for chain-2337 + [CCIP.CLNode] NoOfPluginNodes = 4 NoOfBootstraps = 1 diff --git a/integration-tests/testconfig/ccip/config.go b/integration-tests/testconfig/ccip/config.go index a5b168bec2..b9d969fed1 100644 --- a/integration-tests/testconfig/ccip/config.go +++ b/integration-tests/testconfig/ccip/config.go @@ -1,6 +1,8 @@ package ccip import ( + "strconv" + "github.com/AlekSi/pointer" ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/lib/config" @@ -21,6 +23,7 @@ type Config struct { PrivateEthereumNetworks map[string]*ctfconfig.EthereumNetworkConfig `toml:",omitempty"` CLNode *NodeConfig `toml:",omitempty"` JobDistributorConfig JDConfig `toml:",omitempty"` + HomeChainSelector *string `toml:",omitempty"` } type NodeConfig struct { @@ -90,3 +93,7 @@ func (o *Config) GetJDDBVersion() string { } return dbversion } + +func (o *Config) GetHomeChainSelector() (uint64, error) { + return strconv.ParseUint(pointer.GetString(o.HomeChainSelector), 10, 64) +} diff --git a/integration-tests/testconfig/ccip/overrides/sepolia_avax_binance.toml b/integration-tests/testconfig/ccip/overrides/sepolia_avax_binance.toml new file mode 100644 index 0000000000..06af64d5d9 --- /dev/null +++ b/integration-tests/testconfig/ccip/overrides/sepolia_avax_binance.toml @@ -0,0 +1,55 @@ +[Common] +# chainlink node funding in native token +chainlink_node_funding = 2 + +[Logging] +test_log_collect = true + +[Logging.LogStream] +# supported targets: file, loki, in-memory. if empty no logs will be persisted +log_targets = ["loki"] + +[Network] +selected_networks = ['SEPOLIA', 'AVALANCHE_FUJI', 'BSC_TESTNET'] + +[Network.EVMNetworks.SEPOLIA] +evm_name = 'Sepolia Testnet' +evm_chain_id = 11155111 +evm_simulated = false +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '5m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_tag = true + +[Network.EVMNetworks.AVALANCHE_FUJI] +evm_name = 'Avalanche Fuji' +evm_chain_id = 43113 +evm_simulated = false +client_implementation = 'Ethereum' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '2m' +evm_minimum_confirmations = 1 +evm_gas_estimation_buffer = 1000 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_tag = true + +[Network.EVMNetworks.BSC_TESTNET] +evm_name = 'BSC Testnet' +evm_chain_id = 97 +evm_simulated = false +client_implementation = 'BSC' +evm_chainlink_transaction_limit = 5000 +evm_transaction_timeout = '2m' +evm_minimum_confirmations = 3 +evm_gas_estimation_buffer = 0 +evm_supports_eip1559 = true +evm_default_gas_limit = 6000000 +evm_finality_tag = true + +[CCIP] +HomeChainSelector = '16015286601757825753' # for sepolia \ No newline at end of file From e9a9444dcd35af65a8fd8243c49a1e21cd316a17 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Thu, 19 Sep 2024 18:29:29 +0200 Subject: [PATCH 383/432] [TT-1345] option to use predeployed contracts in OCR tests (#13758) * working version * unify the config a bit, make it possible to use also pre-configured contracts * use Seth's contract loader * fix getting number of contracts to deploy from config * fix configuration logic in ocrv2 smoke/soak tests * uncomment ocr2 plugins * rename some methods, add contract-related information to readme * fix lints --- integration-tests/actions/actions.go | 110 +++++++---- integration-tests/actions/contracts.go | 23 +++ integration-tests/actions/ocr_helpers.go | 8 +- integration-tests/chaos/ocr_chaos_test.go | 4 +- .../contracts/ethereum_contracts.go | 59 +++--- integration-tests/crib/ocr_test.go | 24 ++- integration-tests/load/ocr/ocr_test.go | 8 +- integration-tests/load/ocr/vu.go | 14 +- integration-tests/smoke/forwarder_ocr_test.go | 11 +- .../smoke/forwarders_ocr2_test.go | 8 +- integration-tests/smoke/ocr2_test.go | 26 +-- integration-tests/smoke/ocr_test.go | 6 +- integration-tests/testconfig/README.md | 90 +++++++++ .../testconfig/forwarder_ocr/example.toml | 10 +- .../forwarder_ocr/forwarder_ocr.toml | 9 +- .../testconfig/forwarder_ocr2/example.toml | 22 ++- .../forwarder_ocr2/forwarder_ocr2.toml | 7 +- integration-tests/testconfig/ocr/example.toml | 7 +- integration-tests/testconfig/ocr/ocr.go | 186 +++++++++++++++++- integration-tests/testconfig/ocr/ocr.toml | 5 +- .../testconfig/ocr2/example.toml | 7 +- integration-tests/testconfig/ocr2/ocr2.go | 39 +--- integration-tests/testconfig/ocr2/ocr2.toml | 5 +- integration-tests/testconfig/testconfig.go | 6 + integration-tests/testsetups/ocr.go | 49 ++--- 25 files changed, 538 insertions(+), 205 deletions(-) create mode 100644 integration-tests/actions/contracts.go diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index 198fa8e0dc..f864d9e710 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -50,6 +50,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/testconfig/ocr" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/operator_factory" @@ -610,29 +611,48 @@ func TrackForwarder( Msg("Forwarder tracked") } -// DeployOCRv2Contracts deploys a number of OCRv2 contracts and configures them with defaults -func DeployOCRv2Contracts( +// SetupOCRv2Contracts deploys a number of OCRv2 contracts and configures them with defaults +func SetupOCRv2Contracts( l zerolog.Logger, seth *seth.Client, - numberOfContracts int, + ocrContractsConfig ocr.OffChainAggregatorsConfig, linkTokenAddress common.Address, transmitters []string, ocrOptions contracts.OffchainOptions, ) ([]contracts.OffchainAggregatorV2, error) { var ocrInstances []contracts.OffchainAggregatorV2 - for contractCount := 0; contractCount < numberOfContracts; contractCount++ { - ocrInstance, err := contracts.DeployOffchainAggregatorV2( - l, - seth, - linkTokenAddress, - ocrOptions, - ) - if err != nil { - return nil, fmt.Errorf("OCRv2 instance deployment have failed: %w", err) + + if ocrContractsConfig == nil { + return nil, fmt.Errorf("you need to pass non-nil OffChainAggregatorsConfig to setup OCR contracts") + } + + if !ocrContractsConfig.UseExistingOffChainAggregatorsContracts() { + for contractCount := 0; contractCount < ocrContractsConfig.NumberOfContractsToDeploy(); contractCount++ { + ocrInstance, err := contracts.DeployOffchainAggregatorV2( + l, + seth, + linkTokenAddress, + ocrOptions, + ) + if err != nil { + return nil, fmt.Errorf("OCRv2 instance deployment have failed: %w", err) + } + ocrInstances = append(ocrInstances, &ocrInstance) + if (contractCount+1)%ContractDeploymentInterval == 0 { // For large amounts of contract deployments, space things out some + time.Sleep(2 * time.Second) + } } - ocrInstances = append(ocrInstances, &ocrInstance) - if (contractCount+1)%ContractDeploymentInterval == 0 { // For large amounts of contract deployments, space things out some - time.Sleep(2 * time.Second) + } else { + for _, address := range ocrContractsConfig.OffChainAggregatorsContractsAddresses() { + ocrInstance, err := contracts.LoadOffchainAggregatorV2(l, seth, address) + if err != nil { + return nil, fmt.Errorf("OCRv2 instance loading have failed: %w", err) + } + ocrInstances = append(ocrInstances, &ocrInstance) + } + + if !ocrContractsConfig.ConfigureExistingOffChainAggregatorsContracts() { + return ocrInstances, nil } } @@ -781,7 +801,7 @@ func StartNewRound( func DeployOCRContractsForwarderFlow( logger zerolog.Logger, seth *seth.Client, - numberOfContracts int, + ocrContractsConfig ocr.OffChainAggregatorsConfig, linkTokenContractAddress common.Address, workerNodes []contracts.ChainlinkNodeWithKeysAndAddress, forwarderAddresses []common.Address, @@ -802,23 +822,23 @@ func DeployOCRContractsForwarderFlow( return forwarderAddresses, nil } - return deployAnyOCRv1Contracts(logger, seth, numberOfContracts, linkTokenContractAddress, workerNodes, transmitterPayeesFn, transmitterAddressesFn) + return setupAnyOCRv1Contracts(logger, seth, ocrContractsConfig, linkTokenContractAddress, workerNodes, transmitterPayeesFn, transmitterAddressesFn) } -// DeployOCRv1Contracts deploys and funds a certain number of offchain aggregator contracts -func DeployOCRv1Contracts( +// SetupOCRv1Contracts deploys and funds a certain number of offchain aggregator contracts or uses existing ones and returns a slice of contract wrappers. +func SetupOCRv1Contracts( logger zerolog.Logger, seth *seth.Client, - numberOfContracts int, + ocrContractsConfig ocr.OffChainAggregatorsConfig, linkTokenContractAddress common.Address, workerNodes []contracts.ChainlinkNodeWithKeysAndAddress, ) ([]contracts.OffchainAggregator, error) { transmitterPayeesFn := func() (transmitters []string, payees []string, err error) { transmitters = make([]string, 0) payees = make([]string, 0) - for _, node := range workerNodes { + for _, n := range workerNodes { var addr string - addr, err = node.PrimaryEthAddress() + addr, err = n.PrimaryEthAddress() if err != nil { err = fmt.Errorf("error getting node's primary ETH address: %w", err) return @@ -832,8 +852,8 @@ func DeployOCRv1Contracts( transmitterAddressesFn := func() ([]common.Address, error) { transmitterAddresses := make([]common.Address, 0) - for _, node := range workerNodes { - primaryAddress, err := node.PrimaryEthAddress() + for _, n := range workerNodes { + primaryAddress, err := n.PrimaryEthAddress() if err != nil { return nil, err } @@ -843,28 +863,48 @@ func DeployOCRv1Contracts( return transmitterAddresses, nil } - return deployAnyOCRv1Contracts(logger, seth, numberOfContracts, linkTokenContractAddress, workerNodes, transmitterPayeesFn, transmitterAddressesFn) + return setupAnyOCRv1Contracts(logger, seth, ocrContractsConfig, linkTokenContractAddress, workerNodes, transmitterPayeesFn, transmitterAddressesFn) } -func deployAnyOCRv1Contracts( +func setupAnyOCRv1Contracts( logger zerolog.Logger, seth *seth.Client, - numberOfContracts int, + ocrContractsConfig ocr.OffChainAggregatorsConfig, linkTokenContractAddress common.Address, workerNodes []contracts.ChainlinkNodeWithKeysAndAddress, getTransmitterAndPayeesFn func() ([]string, []string, error), getTransmitterAddressesFn func() ([]common.Address, error), ) ([]contracts.OffchainAggregator, error) { - // Deploy contracts var ocrInstances []contracts.OffchainAggregator - for contractCount := 0; contractCount < numberOfContracts; contractCount++ { - ocrInstance, err := contracts.DeployOffchainAggregator(logger, seth, linkTokenContractAddress, contracts.DefaultOffChainAggregatorOptions()) - if err != nil { - return nil, fmt.Errorf("OCR instance deployment have failed: %w", err) + + if ocrContractsConfig == nil { + return nil, fmt.Errorf("you need to pass non-nil OffChainAggregatorsConfig to setup OCR contracts") + } + + if !ocrContractsConfig.UseExistingOffChainAggregatorsContracts() { + // Deploy contracts + for contractCount := 0; contractCount < ocrContractsConfig.NumberOfContractsToDeploy(); contractCount++ { + ocrInstance, err := contracts.DeployOffchainAggregator(logger, seth, linkTokenContractAddress, contracts.DefaultOffChainAggregatorOptions()) + if err != nil { + return nil, fmt.Errorf("OCR instance deployment have failed: %w", err) + } + ocrInstances = append(ocrInstances, &ocrInstance) + if (contractCount+1)%ContractDeploymentInterval == 0 { // For large amounts of contract deployments, space things out some + time.Sleep(2 * time.Second) + } } - ocrInstances = append(ocrInstances, &ocrInstance) - if (contractCount+1)%ContractDeploymentInterval == 0 { // For large amounts of contract deployments, space things out some - time.Sleep(2 * time.Second) + } else { + // Load contract wrappers + for _, address := range ocrContractsConfig.OffChainAggregatorsContractsAddresses() { + ocrInstance, err := contracts.LoadOffChainAggregator(logger, seth, address) + if err != nil { + return nil, fmt.Errorf("OCR instance loading have failed: %w", err) + } + ocrInstances = append(ocrInstances, &ocrInstance) + } + + if !ocrContractsConfig.ConfigureExistingOffChainAggregatorsContracts() { + return ocrInstances, nil } } diff --git a/integration-tests/actions/contracts.go b/integration-tests/actions/contracts.go new file mode 100644 index 0000000000..1a50c4d7ba --- /dev/null +++ b/integration-tests/actions/contracts.go @@ -0,0 +1,23 @@ +package actions + +import ( + "github.com/rs/zerolog" + + "github.com/smartcontractkit/chainlink-testing-framework/seth" + + "github.com/smartcontractkit/chainlink/integration-tests/contracts" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" +) + +// LinkTokenContract returns a link token contract instance. Depending on test configuration, it either deploys a new one or uses an existing one. +func LinkTokenContract(l zerolog.Logger, sethClient *seth.Client, configWithLinkToken tc.LinkTokenContractConfig) (*contracts.EthereumLinkToken, error) { + if configWithLinkToken != nil && configWithLinkToken.UseExistingLinkTokenContract() { + linkAddress, err := configWithLinkToken.LinkTokenContractAddress() + if err != nil { + return nil, err + } + + return contracts.LoadLinkTokenContract(l, sethClient, linkAddress) + } + return contracts.DeployLinkTokenContract(l, sethClient) +} diff --git a/integration-tests/actions/ocr_helpers.go b/integration-tests/actions/ocr_helpers.go index 19cad817b7..0f6f65d128 100644 --- a/integration-tests/actions/ocr_helpers.go +++ b/integration-tests/actions/ocr_helpers.go @@ -21,6 +21,8 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/testconfig/ocr" ) // This actions file often returns functions, rather than just values. These are used as common test helpers, and are @@ -229,13 +231,14 @@ func BuildNodeContractPairID(node contracts.ChainlinkNodeWithKeysAndAddress, ocr func SetupOCRv1Cluster( l zerolog.Logger, seth *seth.Client, + configWithLinkToken tc.LinkTokenContractConfig, workerNodes []*client.ChainlinkK8sClient, ) (common.Address, error) { err := FundChainlinkNodesFromRootAddress(l, seth, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(workerNodes), big.NewFloat(3)) if err != nil { return common.Address{}, err } - linkContract, err := contracts.DeployLinkTokenContract(l, seth) + linkContract, err := LinkTokenContract(l, seth, configWithLinkToken) if err != nil { return common.Address{}, err } @@ -246,11 +249,12 @@ func SetupOCRv1Feed( l zerolog.Logger, seth *seth.Client, lta common.Address, + ocrContractsConfig ocr.OffChainAggregatorsConfig, msClient *ctfClient.MockserverClient, bootstrapNode *client.ChainlinkK8sClient, workerNodes []*client.ChainlinkK8sClient, ) ([]contracts.OffchainAggregator, error) { - ocrInstances, err := DeployOCRv1Contracts(l, seth, 1, lta, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(workerNodes)) + ocrInstances, err := SetupOCRv1Contracts(l, seth, ocrContractsConfig, lta, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(workerNodes)) if err != nil { return nil, err } diff --git a/integration-tests/chaos/ocr_chaos_test.go b/integration-tests/chaos/ocr_chaos_test.go index 7ef03d98c8..821d3cc48c 100644 --- a/integration-tests/chaos/ocr_chaos_test.go +++ b/integration-tests/chaos/ocr_chaos_test.go @@ -179,13 +179,13 @@ func TestOCRChaos(t *testing.T) { }) ms := ctfClient.ConnectMockServer(testEnvironment) - linkContract, err := contracts.DeployLinkTokenContract(l, seth) + linkContract, err := actions.LinkTokenContract(l, seth, config.OCR) require.NoError(t, err, "Error deploying link token contract") err = actions.FundChainlinkNodesFromRootAddress(l, seth, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(chainlinkNodes), big.NewFloat(10)) require.NoError(t, err) - ocrInstances, err := actions.DeployOCRv1Contracts(l, seth, 1, common.HexToAddress(linkContract.Address()), contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(workerNodes)) + ocrInstances, err := actions.SetupOCRv1Contracts(l, seth, config.OCR, common.HexToAddress(linkContract.Address()), contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(workerNodes)) require.NoError(t, err) err = actions.CreateOCRJobs(ocrInstances, bootstrapNode, workerNodes, 5, ms, fmt.Sprint(seth.ChainID)) require.NoError(t, err) diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index c2f86286fa..288a36978a 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -204,22 +204,17 @@ type EthereumOffchainAggregator struct { l zerolog.Logger } -func LoadOffchainAggregator(l zerolog.Logger, seth *seth.Client, contractAddress common.Address) (EthereumOffchainAggregator, error) { - abi, err := offchainaggregator.OffchainAggregatorMetaData.GetAbi() - if err != nil { - return EthereumOffchainAggregator{}, fmt.Errorf("failed to get OffChain Aggregator ABI: %w", err) - } - seth.ContractStore.AddABI("OffChainAggregator", *abi) - seth.ContractStore.AddBIN("OffChainAggregator", common.FromHex(offchainaggregator.OffchainAggregatorMetaData.Bin)) +func LoadOffChainAggregator(l zerolog.Logger, sethClient *seth.Client, contractAddress common.Address) (EthereumOffchainAggregator, error) { + loader := seth.NewContractLoader[offchainaggregator.OffchainAggregator](sethClient) + instance, err := loader.LoadContract("LinkToken", contractAddress, offchainaggregator.OffchainAggregatorMetaData.GetAbi, offchainaggregator.NewOffchainAggregator) - ocr, err := offchainaggregator.NewOffchainAggregator(contractAddress, wrappers.MustNewWrappedContractBackend(nil, seth)) if err != nil { - return EthereumOffchainAggregator{}, fmt.Errorf("failed to instantiate OCR instance: %w", err) + return EthereumOffchainAggregator{}, fmt.Errorf("failed to instantiate OCR v2 instance: %w", err) } return EthereumOffchainAggregator{ - client: seth, - ocr: ocr, + client: sethClient, + ocr: instance, address: &contractAddress, l: l, }, nil @@ -357,10 +352,6 @@ func (o *EthereumOffchainAggregator) SetConfig( return err } - // fails with error setting OCR config for contract '0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82': both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified - // but we only have gasPrice set... It also fails with the same error when we enable EIP-1559 - // fails when we wait for it to be minted, inside the wrapper there's no error when we call it, so it must be something inside smart contract - // that's reverting it and maybe the error message is completely off _, err = o.client.Decode(o.ocr.SetConfig(o.client.NewTXOpts(), signers, transmitters, threshold, encodedConfigVersion, encodedConfig)) return err } @@ -584,36 +575,36 @@ type EthereumOffchainAggregatorV2 struct { l zerolog.Logger } -func LoadOffChainAggregatorV2(l zerolog.Logger, seth *seth.Client, contractAddress common.Address) (EthereumOffchainAggregatorV2, error) { - oAbi, err := ocr2aggregator.OCR2AggregatorMetaData.GetAbi() +func LoadOffchainAggregatorV2(l zerolog.Logger, seth *seth.Client, address common.Address) (EthereumOffchainAggregatorV2, error) { + contractAbi, err := ocr2aggregator.OCR2AggregatorMetaData.GetAbi() if err != nil { - return EthereumOffchainAggregatorV2{}, fmt.Errorf("failed to get OffChain Aggregator ABI: %w", err) + return EthereumOffchainAggregatorV2{}, fmt.Errorf("failed to get OffChain Aggregator v2 ABI: %w", err) } - seth.ContractStore.AddABI("OffChainAggregatorV2", *oAbi) + seth.ContractStore.AddABI("OffChainAggregatorV2", *contractAbi) seth.ContractStore.AddBIN("OffChainAggregatorV2", common.FromHex(ocr2aggregator.OCR2AggregatorMetaData.Bin)) - ocr2, err := ocr2aggregator.NewOCR2Aggregator(contractAddress, seth.Client) + ocr2, err := ocr2aggregator.NewOCR2Aggregator(address, seth.Client) if err != nil { - return EthereumOffchainAggregatorV2{}, fmt.Errorf("failed to instantiate OCR instance: %w", err) + return EthereumOffchainAggregatorV2{}, fmt.Errorf("failed to instantiate OCRv2 instance: %w", err) } return EthereumOffchainAggregatorV2{ client: seth, contract: ocr2, - address: &contractAddress, + address: &address, l: l, }, nil } func DeployOffchainAggregatorV2(l zerolog.Logger, seth *seth.Client, linkTokenAddress common.Address, offchainOptions OffchainOptions) (EthereumOffchainAggregatorV2, error) { - oAbi, err := ocr2aggregator.OCR2AggregatorMetaData.GetAbi() + contractAbi, err := ocr2aggregator.OCR2AggregatorMetaData.GetAbi() if err != nil { - return EthereumOffchainAggregatorV2{}, fmt.Errorf("failed to get OffChain Aggregator ABI: %w", err) + return EthereumOffchainAggregatorV2{}, fmt.Errorf("failed to get OffChain Aggregator v2 ABI: %w", err) } - seth.ContractStore.AddABI("OffChainAggregatorV2", *oAbi) + seth.ContractStore.AddABI("OffChainAggregatorV2", *contractAbi) seth.ContractStore.AddBIN("OffChainAggregatorV2", common.FromHex(ocr2aggregator.OCR2AggregatorMetaData.Bin)) - ocrDeploymentData2, err := seth.DeployContract(seth.NewTXOpts(), "OffChainAggregatorV2", *oAbi, common.FromHex(ocr2aggregator.OCR2AggregatorMetaData.Bin), + ocrDeploymentData2, err := seth.DeployContract(seth.NewTXOpts(), "OffChainAggregatorV2", *contractAbi, common.FromHex(ocr2aggregator.OCR2AggregatorMetaData.Bin), linkTokenAddress, offchainOptions.MinimumAnswer, offchainOptions.MaximumAnswer, @@ -624,12 +615,12 @@ func DeployOffchainAggregatorV2(l zerolog.Logger, seth *seth.Client, linkTokenAd ) if err != nil { - return EthereumOffchainAggregatorV2{}, fmt.Errorf("OCR instance deployment have failed: %w", err) + return EthereumOffchainAggregatorV2{}, fmt.Errorf("OCRv2 instance deployment have failed: %w", err) } ocr2, err := ocr2aggregator.NewOCR2Aggregator(ocrDeploymentData2.Address, wrappers.MustNewWrappedContractBackend(nil, seth)) if err != nil { - return EthereumOffchainAggregatorV2{}, fmt.Errorf("failed to instantiate OCR instance: %w", err) + return EthereumOffchainAggregatorV2{}, fmt.Errorf("failed to instantiate OCRv2 instance: %w", err) } return EthereumOffchainAggregatorV2{ @@ -772,22 +763,16 @@ func DeployLinkTokenContract(l zerolog.Logger, client *seth.Client) (*EthereumLi } func LoadLinkTokenContract(l zerolog.Logger, client *seth.Client, address common.Address) (*EthereumLinkToken, error) { - linkABI, err := link_token_interface.LinkTokenMetaData.GetAbi() - if err != nil { - return &EthereumLinkToken{}, fmt.Errorf("failed to get LinkToken ABI: %w", err) - } + loader := seth.NewContractLoader[link_token_interface.LinkToken](client) + instance, err := loader.LoadContract("LinkToken", address, link_token_interface.LinkTokenMetaData.GetAbi, link_token_interface.NewLinkToken) - client.ContractStore.AddABI("LinkToken", *linkABI) - client.ContractStore.AddBIN("LinkToken", common.FromHex(link_token_interface.LinkTokenMetaData.Bin)) - - linkToken, err := link_token_interface.NewLinkToken(address, wrappers.MustNewWrappedContractBackend(nil, client)) if err != nil { return &EthereumLinkToken{}, fmt.Errorf("failed to instantiate LinkToken instance: %w", err) } return &EthereumLinkToken{ client: client, - instance: linkToken, + instance: instance, address: address, l: l, }, nil diff --git a/integration-tests/crib/ocr_test.go b/integration-tests/crib/ocr_test.go index 69804e24d7..215734c318 100644 --- a/integration-tests/crib/ocr_test.go +++ b/integration-tests/crib/ocr_test.go @@ -8,25 +8,30 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/havoc" "github.com/smartcontractkit/chainlink-testing-framework/lib/client" + "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + ocr_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/ocr" ) // TestCRIBChaos an example of how we can run chaos tests with havoc and core CRIB func TestCRIBChaos(t *testing.T) { l := logging.GetTestLogger(t) + config, err := tc.GetConfig([]string{"Crib"}, tc.OCR) + require.NoError(t, err) sethClient, msClient, bootstrapNode, workerNodes, _, err := ConnectRemote() require.NoError(t, err) - lta, err := actions.SetupOCRv1Cluster(l, sethClient, workerNodes) + lta, err := actions.SetupOCRv1Cluster(l, sethClient, config.OCR, workerNodes) require.NoError(t, err) - ocrInstances, err := actions.SetupOCRv1Feed(l, sethClient, lta, msClient, bootstrapNode, workerNodes) + ocrInstances, err := actions.SetupOCRv1Feed(l, sethClient, lta, config.OCR, msClient, bootstrapNode, workerNodes) require.NoError(t, err) err = actions.SetAllAdapterResponsesToTheSameValue(10, ocrInstances, workerNodes, msClient) @@ -41,11 +46,12 @@ func TestCRIBChaos(t *testing.T) { 1*time.Second, os.Getenv("CRIB_NAMESPACE"), ) + require.NoError(t, err, "Error rebooting CL namespace") ch.Create(context.Background()) ch.AddListener(havoc.NewChaosLogger(l)) t.Cleanup(func() { err := ch.Delete(context.Background()) - require.NoError(t, err) + require.NoError(t, err, "Error deleting chaos") }) require.Eventually(t, func() bool { err = actions.WatchNewOCRRound(l, sethClient, 3, contracts.V1OffChainAgrregatorToOffChainAggregatorWithRounds(ocrInstances), 5*time.Minute) @@ -65,9 +71,15 @@ func TestCRIBRPCChaos(t *testing.T) { sethClient, msClient, bootstrapNode, workerNodes, vars, err := ConnectRemote() require.NoError(t, err) - lta, err := actions.SetupOCRv1Cluster(l, sethClient, workerNodes) + ocrConfig := &ocr_config.Config{ + Contracts: &ocr_config.Contracts{ + ShouldBeUsed: ptr.Ptr(false), + }, + } + + lta, err := actions.SetupOCRv1Cluster(l, sethClient, ocrConfig, workerNodes) require.NoError(t, err) - ocrInstances, err := actions.SetupOCRv1Feed(l, sethClient, lta, msClient, bootstrapNode, workerNodes) + ocrInstances, err := actions.SetupOCRv1Feed(l, sethClient, lta, ocrConfig, msClient, bootstrapNode, workerNodes) require.NoError(t, err) err = actions.SetAllAdapterResponsesToTheSameValue(10, ocrInstances, workerNodes, msClient) diff --git a/integration-tests/load/ocr/ocr_test.go b/integration-tests/load/ocr/ocr_test.go index 281d2da2bb..55b683a0a7 100644 --- a/integration-tests/load/ocr/ocr_test.go +++ b/integration-tests/load/ocr/ocr_test.go @@ -31,9 +31,9 @@ func TestOCRLoad(t *testing.T) { sethClient, msClient, bootstrapNode, workerNodes, _, err := crib.ConnectRemote() require.NoError(t, err) - lta, err := actions.SetupOCRv1Cluster(l, sethClient, workerNodes) + lta, err := actions.SetupOCRv1Cluster(l, sethClient, config.OCR, workerNodes) require.NoError(t, err) - ocrInstances, err := actions.SetupOCRv1Feed(l, sethClient, lta, msClient, bootstrapNode, workerNodes) + ocrInstances, err := actions.SetupOCRv1Feed(l, sethClient, lta, config.OCR, msClient, bootstrapNode, workerNodes) require.NoError(t, err) cfg := config.OCR @@ -64,7 +64,7 @@ func TestOCRVolume(t *testing.T) { sethClient, msClient, bootstrapNode, workerNodes, _, err := crib.ConnectRemote() require.NoError(t, err) - lta, err := actions.SetupOCRv1Cluster(l, sethClient, workerNodes) + lta, err := actions.SetupOCRv1Cluster(l, sethClient, config.OCR, workerNodes) require.NoError(t, err) cfg := config.OCR @@ -77,7 +77,7 @@ func TestOCRVolume(t *testing.T) { LoadType: wasp.VU, CallTimeout: cfg.Volume.VerificationTimeout.Duration, Schedule: wasp.Plain(*cfg.Volume.Rate, cfg.Volume.TestDuration.Duration), - VU: NewVU(l, sethClient, *cfg.Volume.VURequestsPerUnit, cfg.Volume.RateLimitUnitDuration.Duration, lta, bootstrapNode, workerNodes, msClient), + VU: NewVU(l, sethClient, cfg, *cfg.Volume.VURequestsPerUnit, cfg.Volume.RateLimitUnitDuration.Duration, lta, bootstrapNode, workerNodes, msClient), Labels: CommonTestLabels, LokiConfig: wasp.NewLokiConfig(cfgl.Endpoint, cfgl.TenantId, cfgl.BasicAuth, cfgl.BearerToken), })) diff --git a/integration-tests/load/ocr/vu.go b/integration-tests/load/ocr/vu.go index aece9cb74b..c337e338a8 100644 --- a/integration-tests/load/ocr/vu.go +++ b/integration-tests/load/ocr/vu.go @@ -8,18 +8,16 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" - - "github.com/smartcontractkit/chainlink-testing-framework/seth" - "go.uber.org/ratelimit" - "github.com/smartcontractkit/chainlink-testing-framework/wasp" - client2 "github.com/smartcontractkit/chainlink-testing-framework/lib/client" + "github.com/smartcontractkit/chainlink-testing-framework/seth" + "github.com/smartcontractkit/chainlink-testing-framework/wasp" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/testconfig/ocr" ) // VU is a virtual user for the OCR load test @@ -37,11 +35,13 @@ type VU struct { msClient *client2.MockserverClient l zerolog.Logger ocrInstances []contracts.OffchainAggregator + config ocr.OffChainAggregatorsConfig } func NewVU( l zerolog.Logger, seth *seth.Client, + config ocr.OffChainAggregatorsConfig, rate int, rateUnit time.Duration, lta common.Address, @@ -60,6 +60,7 @@ func NewVU( msClient: msClient, bootstrapNode: bootstrapNode, workerNodes: workerNodes, + config: config, } } @@ -75,11 +76,12 @@ func (m *VU) Clone(_ *wasp.Generator) wasp.VirtualUser { msClient: m.msClient, bootstrapNode: m.bootstrapNode, workerNodes: m.workerNodes, + config: m.config, } } func (m *VU) Setup(_ *wasp.Generator) error { - ocrInstances, err := actions.DeployOCRv1Contracts(m.l, m.seth, 1, m.lta, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(m.workerNodes)) + ocrInstances, err := actions.SetupOCRv1Contracts(m.l, m.seth, m.config, m.lta, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(m.workerNodes)) if err != nil { return err } diff --git a/integration-tests/smoke/forwarder_ocr_test.go b/integration-tests/smoke/forwarder_ocr_test.go index 4441a59288..5e5fb1d40b 100644 --- a/integration-tests/smoke/forwarder_ocr_test.go +++ b/integration-tests/smoke/forwarder_ocr_test.go @@ -60,8 +60,8 @@ func TestForwarderOCRBasic(t *testing.T) { _ = actions.ReturnFundsFromNodes(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs())) }) - lt, err := contracts.DeployLinkTokenContract(l, sethClient) - require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") + linkContract, err := actions.LinkTokenContract(l, sethClient, config.OCR) + require.NoError(t, err, "Error loading/deploying link token contract") fundingAmount := big.NewFloat(.05) l.Info().Str("ETH amount per node", fundingAmount.String()).Msg("Funding Chainlink nodes") @@ -69,7 +69,7 @@ func TestForwarderOCRBasic(t *testing.T) { require.NoError(t, err, "Error funding Chainlink nodes") operators, authorizedForwarders, _ := actions.DeployForwarderContracts( - t, sethClient, common.HexToAddress(lt.Address()), len(workerNodes), + t, sethClient, common.HexToAddress(linkContract.Address()), len(workerNodes), ) require.Equal(t, len(workerNodes), len(operators), "Number of operators should match number of worker nodes") @@ -81,11 +81,12 @@ func TestForwarderOCRBasic(t *testing.T) { require.NoError(t, err, "Accepting Authorize Receivers on Operator shouldn't fail") actions.TrackForwarder(t, sethClient, authorizedForwarders[i], workerNodes[i]) } + ocrInstances, err := actions.DeployOCRContractsForwarderFlow( l, sethClient, - 1, - common.HexToAddress(lt.Address()), + config.OCR, + common.HexToAddress(linkContract.Address()), contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(workerNodes), authorizedForwarders, ) diff --git a/integration-tests/smoke/forwarders_ocr2_test.go b/integration-tests/smoke/forwarders_ocr2_test.go index 219df9ce43..0cc7d9fafe 100644 --- a/integration-tests/smoke/forwarders_ocr2_test.go +++ b/integration-tests/smoke/forwarders_ocr2_test.go @@ -61,8 +61,8 @@ func TestForwarderOCR2Basic(t *testing.T) { _ = actions.ReturnFundsFromNodes(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs())) }) - lt, err := contracts.DeployLinkTokenContract(l, sethClient) - require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") + linkContract, err := actions.LinkTokenContract(l, sethClient, config.OCR2) + require.NoError(t, err, "Error loading/deploying link token contract") fundingAmount := big.NewFloat(.05) l.Info().Str("ETH amount per node", fundingAmount.String()).Msg("Funding Chainlink nodes") @@ -70,7 +70,7 @@ func TestForwarderOCR2Basic(t *testing.T) { require.NoError(t, err, "Error funding Chainlink nodes") operators, authorizedForwarders, _ := actions.DeployForwarderContracts( - t, sethClient, common.HexToAddress(lt.Address()), len(workerNodes), + t, sethClient, common.HexToAddress(linkContract.Address()), len(workerNodes), ) require.Equal(t, len(workerNodes), len(operators), "Number of operators should match number of worker nodes") @@ -90,7 +90,7 @@ func TestForwarderOCR2Basic(t *testing.T) { } ocrOffchainOptions := contracts.DefaultOffChainAggregatorOptions() - ocrInstances, err := actions.DeployOCRv2Contracts(l, sethClient, 1, common.HexToAddress(lt.Address()), transmitters, ocrOffchainOptions) + ocrInstances, err := actions.SetupOCRv2Contracts(l, sethClient, config.OCR2, common.HexToAddress(linkContract.Address()), transmitters, ocrOffchainOptions) require.NoError(t, err, "Error deploying OCRv2 contracts with forwarders") ocrv2Config, err := actions.BuildMedianOCR2ConfigLocal(workerNodes, ocrOffchainOptions) diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index 3203037ae5..325c88f979 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -103,11 +103,11 @@ func TestOCRv2JobReplacement(t *testing.T) { t.Parallel() l := logging.GetTestLogger(t) - env, aggregatorContracts, sethClient := prepareORCv2SmokeTestEnv(t, defaultTestData(), l, 5) - nodeClients := env.ClCluster.NodeAPIs() + testEnv, aggregatorContracts, sethClient := prepareORCv2SmokeTestEnv(t, defaultTestData(), l, 5) + nodeClients := testEnv.ClCluster.NodeAPIs() bootstrapNode, workerNodes := nodeClients[0], nodeClients[1:] - err := env.MockAdapter.SetAdapterBasedIntValuePath("ocr2", []string{http.MethodGet, http.MethodPost}, 10) + err := testEnv.MockAdapter.SetAdapterBasedIntValuePath("ocr2", []string{http.MethodGet, http.MethodPost}, 10) require.NoError(t, err) err = actions.WatchNewOCRRound(l, sethClient, 2, contracts.V2OffChainAgrregatorToOffChainAggregatorWithRounds(aggregatorContracts), time.Minute*5) require.NoError(t, err, "Error watching for new OCR2 round") @@ -125,7 +125,7 @@ func TestOCRv2JobReplacement(t *testing.T) { err = actions.DeleteBridges(nodeClients) require.NoError(t, err) - err = actions.CreateOCRv2JobsLocal(aggregatorContracts, bootstrapNode, workerNodes, env.MockAdapter, "ocr2", 15, uint64(sethClient.ChainID), false, false) + err = actions.CreateOCRv2JobsLocal(aggregatorContracts, bootstrapNode, workerNodes, testEnv.MockAdapter, "ocr2", 15, uint64(sethClient.ChainID), false, false) require.NoError(t, err, "Error creating OCRv2 jobs") err = actions.WatchNewOCRRound(l, sethClient, 3, contracts.V2OffChainAgrregatorToOffChainAggregatorWithRounds(aggregatorContracts), time.Minute*3) @@ -170,8 +170,8 @@ func prepareORCv2SmokeTestEnv(t *testing.T, testData ocr2test, l zerolog.Logger, nodeClients := testEnv.ClCluster.NodeAPIs() bootstrapNode, workerNodes := nodeClients[0], nodeClients[1:] - linkContract, err := contracts.DeployLinkTokenContract(l, sethClient) - require.NoError(t, err, "Error deploying link token contract") + linkContract, err := actions.LinkTokenContract(l, sethClient, config.OCR2) + require.NoError(t, err, "Error loading/deploying link token contract") err = actions.FundChainlinkNodesFromRootAddress(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(workerNodes), big.NewFloat(*config.Common.ChainlinkNodeFunding)) require.NoError(t, err, "Error funding Chainlink nodes") @@ -191,18 +191,20 @@ func prepareORCv2SmokeTestEnv(t *testing.T, testData ocr2test, l zerolog.Logger, transmitters = append(transmitters, addr) } - ocrOffchainOptions := contracts.DefaultOffChainAggregatorOptions() - aggregatorContracts, err := actions.DeployOCRv2Contracts(l, sethClient, 1, common.HexToAddress(linkContract.Address()), transmitters, ocrOffchainOptions) + ocrOffChainOptions := contracts.DefaultOffChainAggregatorOptions() + aggregatorContracts, err := actions.SetupOCRv2Contracts(l, sethClient, config.OCR2, common.HexToAddress(linkContract.Address()), transmitters, ocrOffChainOptions) require.NoError(t, err, "Error deploying OCRv2 aggregator contracts") err = actions.CreateOCRv2JobsLocal(aggregatorContracts, bootstrapNode, workerNodes, testEnv.MockAdapter, "ocr2", 5, uint64(sethClient.ChainID), false, testData.chainReaderAndCodec) require.NoError(t, err, "Error creating OCRv2 jobs") - ocrv2Config, err := actions.BuildMedianOCR2ConfigLocal(workerNodes, ocrOffchainOptions) - require.NoError(t, err, "Error building OCRv2 config") + if !config.OCR2.UseExistingOffChainAggregatorsContracts() || (config.OCR2.UseExistingOffChainAggregatorsContracts() && config.OCR2.ConfigureExistingOffChainAggregatorsContracts()) { + ocrV2Config, err := actions.BuildMedianOCR2ConfigLocal(workerNodes, ocrOffChainOptions) + require.NoError(t, err, "Error building OCRv2 config") - err = actions.ConfigureOCRv2AggregatorContracts(ocrv2Config, aggregatorContracts) - require.NoError(t, err, "Error configuring OCRv2 aggregator contracts") + err = actions.ConfigureOCRv2AggregatorContracts(ocrV2Config, aggregatorContracts) + require.NoError(t, err, "Error configuring OCRv2 aggregator contracts") + } assertCorrectNodeConfiguration(t, l, clNodeCount, testData, testEnv) diff --git a/integration-tests/smoke/ocr_test.go b/integration-tests/smoke/ocr_test.go index cd9db0e974..a19adb5c02 100644 --- a/integration-tests/smoke/ocr_test.go +++ b/integration-tests/smoke/ocr_test.go @@ -113,10 +113,10 @@ func prepareORCv1SmokeTestEnv(t *testing.T, l zerolog.Logger, firstRoundResult i _ = actions.ReturnFundsFromNodes(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs())) }) - linkContract, err := contracts.DeployLinkTokenContract(l, sethClient) - require.NoError(t, err, "Error deploying link token contract") + linkContract, err := actions.LinkTokenContract(l, sethClient, config.OCR) + require.NoError(t, err, "Error loading/deploying link token contract") - ocrInstances, err := actions.DeployOCRv1Contracts(l, sethClient, 1, common.HexToAddress(linkContract.Address()), contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(workerNodes)) + ocrInstances, err := actions.SetupOCRv1Contracts(l, sethClient, config.OCR, common.HexToAddress(linkContract.Address()), contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(workerNodes)) require.NoError(t, err, "Error deploying OCR contracts") err = actions.CreateOCRJobsLocal(ocrInstances, bootstrapNode, workerNodes, 5, env.MockAdapter, big.NewInt(sethClient.ChainID)) diff --git a/integration-tests/testconfig/README.md b/integration-tests/testconfig/README.md index c698281b76..f618658055 100644 --- a/integration-tests/testconfig/README.md +++ b/integration-tests/testconfig/README.md @@ -194,6 +194,96 @@ BumpMin = '100 gwei' For more examples see `example.toml` in product TOML configs like `testconfig/automation/example.toml`. If either ChainConfigTOMLByChainID or CommonChainConfigTOML is defined, it will override any defaults that Chainlink Node might have for the given network. Part of the configuration that defines blockchain node URLs is always dynamically generated based on the EVMNetwork configuration. Currently, all networks are treated as EVM networks. There's no way to provide Solana, Starknet, Cosmos or Aptos configuration yet. +### OCR tests contract config +In order to allow running OCR soak/load/smoke tests with already deployed contracts, we have provided an experimental feature for providing addresses of LINK token and OCR contracts in the TOML config. Additionally, user can choose, whether existing OCR contracts should be configured or not. +If no contract addresses are provided, the tests will deploy new contracts. + +The feature is highly configurable and it possible to use existing LINK token contract, but deploy new OCR contracts or vice versa. Both OCRv1 and OCRv2 contracts are supported. + +To use existing LINK and OCRv1 contracts, provide the following configuration in the TOML file: +```toml +[OCR.Contracts] +link_token = "0x88d1239894D9582f5849E5b5a964da9e5730f1E6" +offchain_aggregators = ["0xc1ce3815d6e7f3705265c2577F1342344752A5Eb"] +``` + +For OCRv2, provide the following configuration: +```toml +[OCR2.Contracts] +link_token = "0x88d1239894D9582f5849E5b5a964da9e5730f1E6" +offchain_aggregators = ["0xc1ce3815d6e7f3705265c2577F1342344752A5Eb"] +``` + +If you want to disable them, you can set `use = false` or remove the addresses from the configuration. + +If you want to use existing OCRv1 contract, without configuring it, you can set `configure = false` in the configuration: +```toml +[OCR.Contracts] +link_token = "0x88d1239894D9582f5849E5b5a964da9e5730f1E6" +offchain_aggregators = ["0xc1ce3815d6e7f3705265c2577F1342344752A5Eb"] + +# notice that this address needs to match the one in offchain_aggregators +[OCR.Contracts.Settings."0xc1ce3815d6e7f3705265c2577F1342344752A5Eb"] +configure = false +``` + +Be aware that using multiple existing OCR contracts, but configuring only some of them is not supported. This is not a valid configuration: +```toml +[OCR.Contracts] +link_token = "0x88d1239894D9582f5849E5b5a964da9e5730f1E6" +offchain_aggregators = ["0xc1ce3815d6e7f3705265c2577F1342344752A5Eb", "0x2f4FA21fCd917C448C160caafEC874032F404c08"] + +# notice that this address needs to match the one in offchain_aggregators +[OCR.Contracts.Settings."0xc1ce3815d6e7f3705265c2577F1342344752A5Eb"] +configure = false + +# if setting for a given address is not present, we assume it should be used and configured +# so in this case "0x2f4FA21fCd917C448C160caafEC874032F404c08" will be evaluated as configure = true, +# but "0xc1ce3815d6e7f3705265c2577F1342344752A5Eb" is set to configure = false. +# this will fail configuration validation +``` + +This, more explicit version is also invalid: +```toml +[OCR.Contracts] +link_token = "0x88d1239894D9582f5849E5b5a964da9e5730f1E6" +offchain_aggregators = ["0xc1ce3815d6e7f3705265c2577F1342344752A5Eb", "0x2f4FA21fCd917C448C160caafEC874032F404c08"] + +# notice that this address needs to match the one in offchain_aggregators +[OCR.Contracts.Settings."0xc1ce3815d6e7f3705265c2577F1342344752A5Eb"] +configure = false + +[OCR.Contracts.Settings."0x2f4FA21fCd917C448C160caafEC874032F404c08"] +configure = true +``` + +Similarly, this one is also invalid: +```toml +[OCR.Contracts] +link_token = "0x88d1239894D9582f5849E5b5a964da9e5730f1E6" +offchain_aggregators = ["0xc1ce3815d6e7f3705265c2577F1342344752A5Eb", "0x2f4FA21fCd917C448C160caafEC874032F404c08"] + +# notice that this address needs to match the one in offchain_aggregators +[OCR.Contracts.Settings."0xc1ce3815d6e7f3705265c2577F1342344752A5Eb"] +use = false + +[OCR.Contracts.Settings."0x2f4FA21fCd917C448C160caafEC874032F404c08"] +use = true +``` + +There are no settings available for LINK token contract. + +Last, but not least, when deploying new OCR contracts you need to provide their number. For example: +```toml +# for OCRv1 +[OCR.Common] +number_of_contracts=2 + +# for OCRv2 +[OCR2.Common] +number_of_contracts=2 +``` + ### Setting env vars for Chainlink Node To set env vars for Chainlink Node use `WithCLNodeOptions()` and `WithNodeEnvVars()` when building a test environment. Example: diff --git a/integration-tests/testconfig/forwarder_ocr/example.toml b/integration-tests/testconfig/forwarder_ocr/example.toml index 0b762299af..75143d7b77 100644 --- a/integration-tests/testconfig/forwarder_ocr/example.toml +++ b/integration-tests/testconfig/forwarder_ocr/example.toml @@ -31,7 +31,7 @@ bearer_token_secret="bearer_token" base_url="http://grafana.url" # url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model +# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model dashboard_uid="dashboard-uid-to-annotate" bearer_token_secret="my-awesome-token" @@ -143,6 +143,9 @@ BumpPercent = 20 BumpMin = '100 gwei' """ +[OCR.Common] +number_of_contracts=1 + # load test specific configuration [Load.OCR] [Load.OCR.Common] @@ -162,9 +165,8 @@ chainlink_node_funding = 100 [Soak.OCR] [Soak.OCR.Common] +number_of_contracts=2 test_duration="15m" [Soak.OCR.Soak] -ocr_version="1" -number_of_contracts=2 -time_between_rounds="1m" \ No newline at end of file +time_between_rounds="1m" diff --git a/integration-tests/testconfig/forwarder_ocr/forwarder_ocr.toml b/integration-tests/testconfig/forwarder_ocr/forwarder_ocr.toml index 8fa0fa5db2..68ed21404f 100644 --- a/integration-tests/testconfig/forwarder_ocr/forwarder_ocr.toml +++ b/integration-tests/testconfig/forwarder_ocr/forwarder_ocr.toml @@ -57,7 +57,10 @@ MinContractPayment = 0 [Transactions] ForwardersEnabled = true - """ +""" + +[OCR.Common] +number_of_contracts=1 # load test specific configuration [Load.OCR] @@ -92,8 +95,8 @@ chainlink_node_funding = 0.5 [Soak.OCR] [Soak.OCR.Common] +number_of_contracts=2 test_duration = "15m" [Soak.OCR.Soak] -number_of_contracts = 2 -time_between_rounds = "1m" +time_between_rounds="1m" diff --git a/integration-tests/testconfig/forwarder_ocr2/example.toml b/integration-tests/testconfig/forwarder_ocr2/example.toml index b3bc45d270..4941c49a98 100644 --- a/integration-tests/testconfig/forwarder_ocr2/example.toml +++ b/integration-tests/testconfig/forwarder_ocr2/example.toml @@ -31,7 +31,7 @@ bearer_token_secret="bearer_token" base_url="http://grafana.url" # url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model +# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model dashboard_uid="dashboard-uid-to-annotate" bearer_token_secret="my-awesome-token" @@ -143,12 +143,15 @@ BumpPercent = 20 BumpMin = '100 gwei' """ +[OCR2.Common] +number_of_contracts=1 + # load test specific configuration -[Load.OCR] -[Load.OCR.Common] +[Load.OCR2] +[Load.OCR2.Common] eth_funds = 3 -[Load.OCR.Load] +[Load.OCR2.Load] test_duration = "3m" rate_limit_unit_duration = "1m" rate = 3 @@ -160,11 +163,10 @@ ea_change_interval = "5s" [Soak.Common] chainlink_node_funding = 100 -[Soak.OCR] -[Soak.OCR.Common] +[Soak.OCR2] +[Soak.OCR2.Common] +number_of_contracts=2 test_duration="15m" -[Soak.OCR.Soak] -ocr_version="1" -number_of_contracts=2 -time_between_rounds="1m" \ No newline at end of file +[Soak.OCR2.Soak] +time_between_rounds="1m" diff --git a/integration-tests/testconfig/forwarder_ocr2/forwarder_ocr2.toml b/integration-tests/testconfig/forwarder_ocr2/forwarder_ocr2.toml index 3f2a8610a8..76d5695a8b 100644 --- a/integration-tests/testconfig/forwarder_ocr2/forwarder_ocr2.toml +++ b/integration-tests/testconfig/forwarder_ocr2/forwarder_ocr2.toml @@ -53,7 +53,10 @@ MinContractPayment = 0 [Transactions] ForwardersEnabled = true - """ +""" + +[OCR2.Common] +number_of_contracts=1 # load test specific configuration [Load.OCR2.Common] @@ -85,10 +88,10 @@ ea_change_interval = "5s" chainlink_node_funding = 1 [Soak.OCR2.Common] +number_of_contracts=2 test_duration="15m" [Soak.OCR2.Soak] -number_of_contracts=2 time_between_rounds="1m" diff --git a/integration-tests/testconfig/ocr/example.toml b/integration-tests/testconfig/ocr/example.toml index 92262241df..26f0dd5a84 100644 --- a/integration-tests/testconfig/ocr/example.toml +++ b/integration-tests/testconfig/ocr/example.toml @@ -31,7 +31,7 @@ bearer_token_secret="bearer_token" base_url="http://grafana.url" # url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model +# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model dashboard_uid="dashboard-uid-to-annotate" bearer_token_secret="my-awesome-token" @@ -142,6 +142,9 @@ BumpPercent = 20 BumpMin = '100 gwei' """ +[OCR.Common] +number_of_contracts=1 + # load test specific configuration [Load.OCR] [Load.OCR.Common] @@ -161,8 +164,8 @@ chainlink_node_funding = 100 [Soak.OCR] [Soak.OCR.Common] +number_of_contracts=2 test_duration="15m" [Soak.OCR.Soak] -number_of_contracts=2 time_between_rounds="1m" diff --git a/integration-tests/testconfig/ocr/ocr.go b/integration-tests/testconfig/ocr/ocr.go index d8250d407f..240fd2afea 100644 --- a/integration-tests/testconfig/ocr/ocr.go +++ b/integration-tests/testconfig/ocr/ocr.go @@ -2,15 +2,19 @@ package ocr import ( "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" ) type Config struct { - Soak *SoakConfig `toml:"Soak"` - Load *Load `toml:"Load"` - Volume *Volume `toml:"Volume"` - Common *Common `toml:"Common"` + Soak *SoakConfig `toml:"Soak"` + Load *Load `toml:"Load"` + Volume *Volume `toml:"Volume"` + Common *Common `toml:"Common"` + Contracts *Contracts `toml:"Contracts"` } func (o *Config) Validate() error { @@ -29,15 +33,24 @@ func (o *Config) Validate() error { return err } } + if o.Contracts != nil { + if err := o.Contracts.Validate(); err != nil { + return err + } + } return nil } type Common struct { - ETHFunds *int `toml:"eth_funds"` - TestDuration *blockchain.StrDuration `toml:"test_duration"` + NumberOfContracts *int `toml:"number_of_contracts"` + ETHFunds *int `toml:"eth_funds"` + TestDuration *blockchain.StrDuration `toml:"test_duration"` } func (o *Common) Validate() error { + if o.NumberOfContracts != nil && *o.NumberOfContracts < 1 { + return errors.New("when number_of_contracts is set, it must be greater than 0") + } if o.ETHFunds != nil && *o.ETHFunds < 0 { return errors.New("eth_funds must be set and cannot be negative") } @@ -117,16 +130,169 @@ func (o *Volume) Validate() error { } type SoakConfig struct { - NumberOfContracts *int `toml:"number_of_contracts"` TimeBetweenRounds *blockchain.StrDuration `toml:"time_between_rounds"` } func (o *SoakConfig) Validate() error { - if o.NumberOfContracts == nil || *o.NumberOfContracts <= 1 { - return errors.New("number_of_contracts must be set and be greater than 1") - } if o.TimeBetweenRounds == nil || o.TimeBetweenRounds.Duration == 0 { return errors.New("time_between_rounds must be set and be a positive integer") } return nil } + +// For more information on the configuration of contracts, see https://smartcontract-it.atlassian.net/wiki/spaces/TT/pages/828407894/Contracts+addresses+in+TOML+convention +type Contracts struct { + ShouldBeUsed *bool `toml:"use"` + LinkTokenAddress *string `toml:"link_token"` + OffChainAggregatorAddresses []string `toml:"offchain_aggregators"` + Settings map[string]ContractSetting `toml:"Settings"` +} + +func (o *Contracts) Validate() error { + if o.LinkTokenAddress != nil && !common.IsHexAddress(*o.LinkTokenAddress) { + return errors.New("link_token must be a valid ethereum address") + } + if o.OffChainAggregatorAddresses != nil { + allEnabled := make(map[bool]int) + allConfigure := make(map[bool]int) + for _, address := range o.OffChainAggregatorAddresses { + if !common.IsHexAddress(address) { + return fmt.Errorf("offchain_aggregators must be valid ethereum addresses, but %s is not", address) + } + + if v, ok := o.Settings[address]; ok { + if v.ShouldBeUsed != nil { + allEnabled[*v.ShouldBeUsed]++ + } else { + allEnabled[true]++ + } + if v.Configure != nil { + allConfigure[*v.Configure]++ + } else { + allConfigure[true]++ + } + } + } + + if allEnabled[true] > 0 && allEnabled[false] > 0 { + return errors.New("either all or none offchain_aggregators must be used") + } + + if allConfigure[true] > 0 && allConfigure[false] > 0 { + return errors.New("either all or none offchain_aggregators must be configured") + } + } + + return nil +} + +func (o *Config) UseExistingContracts() bool { + if o.Contracts == nil { + return false + } + + if o.Contracts.ShouldBeUsed != nil { + return *o.Contracts.ShouldBeUsed + } + + return false +} + +func (o *Config) LinkTokenContractAddress() (common.Address, error) { + if o.Contracts != nil && o.Contracts.LinkTokenAddress != nil { + return common.HexToAddress(*o.Contracts.LinkTokenAddress), nil + } + + return common.Address{}, errors.New("link token address must be set") +} + +func (o *Config) UseExistingLinkTokenContract() bool { + if !o.UseExistingContracts() { + return false + } + + if o.Contracts.LinkTokenAddress == nil { + return false + } + + if len(o.Contracts.Settings) == 0 { + return true + } + + if v, ok := o.Contracts.Settings[*o.Contracts.LinkTokenAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +type ContractSetting struct { + ShouldBeUsed *bool `toml:"use"` + Configure *bool `toml:"configure"` +} + +type OffChainAggregatorsConfig interface { + OffChainAggregatorsContractsAddresses() []common.Address + UseExistingOffChainAggregatorsContracts() bool + ConfigureExistingOffChainAggregatorsContracts() bool + NumberOfContractsToDeploy() int +} + +func (o *Config) UseExistingOffChainAggregatorsContracts() bool { + if !o.UseExistingContracts() { + return false + } + + if len(o.Contracts.OffChainAggregatorAddresses) == 0 { + return false + } + + if len(o.Contracts.Settings) == 0 { + return true + } + + for _, address := range o.Contracts.OffChainAggregatorAddresses { + if v, ok := o.Contracts.Settings[address]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + } + + return true +} + +func (o *Config) OffChainAggregatorsContractsAddresses() []common.Address { + var ocrInstanceAddresses []common.Address + if !o.UseExistingOffChainAggregatorsContracts() { + return ocrInstanceAddresses + } + + for _, address := range o.Contracts.OffChainAggregatorAddresses { + ocrInstanceAddresses = append(ocrInstanceAddresses, common.HexToAddress(address)) + } + + return ocrInstanceAddresses +} + +func (o *Config) ConfigureExistingOffChainAggregatorsContracts() bool { + if !o.UseExistingOffChainAggregatorsContracts() { + return true + } + + for _, address := range o.Contracts.OffChainAggregatorAddresses { + for maybeOcrAddress, setting := range o.Contracts.Settings { + if maybeOcrAddress == address { + return setting.Configure != nil && *setting.Configure + } + } + } + + return true +} + +func (o *Config) NumberOfContractsToDeploy() int { + if o.Common != nil && o.Common.NumberOfContracts != nil { + return *o.Common.NumberOfContracts + } + + return 0 +} diff --git a/integration-tests/testconfig/ocr/ocr.toml b/integration-tests/testconfig/ocr/ocr.toml index 17ee4d7b68..36cded0b85 100644 --- a/integration-tests/testconfig/ocr/ocr.toml +++ b/integration-tests/testconfig/ocr/ocr.toml @@ -43,6 +43,9 @@ Enabled = true ListenAddresses = ['0.0.0.0:6690'] """ +[OCR.Common] +number_of_contracts=1 + # load test specific configuration [Load.OCR] [Load.OCR.Common] @@ -77,9 +80,9 @@ chainlink_node_funding = 0.5 [Soak.OCR] [Soak.OCR.Common] test_duration="15m" +number_of_contracts=2 [Soak.OCR.Soak] -number_of_contracts=2 time_between_rounds="1m" # Soak test configuration with Geth reorg below finality with FinalityTagEnabled=false diff --git a/integration-tests/testconfig/ocr2/example.toml b/integration-tests/testconfig/ocr2/example.toml index 36e3105f21..624c3b7775 100644 --- a/integration-tests/testconfig/ocr2/example.toml +++ b/integration-tests/testconfig/ocr2/example.toml @@ -31,7 +31,7 @@ bearer_token_secret="bearer_token" base_url="http://grafana.url" # url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model +# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model dashboard_uid="dashboard-uid-to-annotate" bearer_token_secret="my-awesome-token" @@ -142,6 +142,9 @@ BumpPercent = 20 BumpMin = '100 gwei' """ +[OCR2.Common] +number_of_contracts=1 + # load test specific configuration [Load.OCR2] [Load.OCR2.Common] @@ -161,8 +164,8 @@ chainlink_node_funding = 100 [Soak.OCR2] [Soak.OCR.Common] +number_of_contracts=2 test_duration="15m" [Soak.OCR2.Soak] -number_of_contracts=2 time_between_rounds="1m" diff --git a/integration-tests/testconfig/ocr2/ocr2.go b/integration-tests/testconfig/ocr2/ocr2.go index 1e7f034e04..60169e944f 100644 --- a/integration-tests/testconfig/ocr2/ocr2.go +++ b/integration-tests/testconfig/ocr2/ocr2.go @@ -1,14 +1,13 @@ package ocr2 import ( - "errors" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + "github.com/smartcontractkit/chainlink/integration-tests/testconfig/ocr" ) type Config struct { - Soak *SoakConfig `toml:"Soak"` - Common *Common `toml:"Common"` + Soak *ocr.SoakConfig `toml:"Soak"` + Common *ocr.Common `toml:"Common"` + Contracts *ocr.Contracts `toml:"Contracts"` } func (o *Config) Validate() error { @@ -22,32 +21,10 @@ func (o *Config) Validate() error { return err } } - return nil -} - -type Common struct { - ETHFunds *int `toml:"eth_funds"` - TestDuration *blockchain.StrDuration `toml:"test_duration"` -} - -func (o *Common) Validate() error { - if o.ETHFunds != nil && *o.ETHFunds < 0 { - return errors.New("eth_funds must be set and cannot be negative") - } - return nil -} - -type SoakConfig struct { - NumberOfContracts *int `toml:"number_of_contracts"` - TimeBetweenRounds *blockchain.StrDuration `toml:"time_between_rounds"` -} - -func (o *SoakConfig) Validate() error { - if o.NumberOfContracts == nil || *o.NumberOfContracts <= 1 { - return errors.New("number_of_contracts must be set and be greater than 1") - } - if o.TimeBetweenRounds == nil || o.TimeBetweenRounds.Duration == 0 { - return errors.New("time_between_rounds must be set and be a positive integer") + if o.Contracts != nil { + if err := o.Contracts.Validate(); err != nil { + return err + } } return nil } diff --git a/integration-tests/testconfig/ocr2/ocr2.toml b/integration-tests/testconfig/ocr2/ocr2.toml index ad195913bd..62d92574ea 100644 --- a/integration-tests/testconfig/ocr2/ocr2.toml +++ b/integration-tests/testconfig/ocr2/ocr2.toml @@ -43,6 +43,9 @@ Enabled = true ListenAddresses = ['0.0.0.0:6690'] """ +[OCR2.Common] +number_of_contracts=1 + # load test specific configuration [Load.OCR2] [Load.OCR2.Common] @@ -76,8 +79,8 @@ chainlink_node_funding = 0.5 [Soak.OCR2] [Soak.OCR2.Common] +number_of_contracts=2 test_duration="15m" [Soak.OCR2.Soak] -number_of_contracts=2 time_between_rounds="1m" diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index fb692c56a7..545818e334 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/barkimedes/go-deepcopy" + "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" "github.com/pelletier/go-toml/v2" "github.com/pkg/errors" @@ -77,6 +78,11 @@ type CCIPTestConfig interface { GetCCIPConfig() *ccip_config.Config } +type LinkTokenContractConfig interface { + LinkTokenContractAddress() (common.Address, error) + UseExistingLinkTokenContract() bool +} + const ( E2E_TEST_DATA_STREAMS_URL_ENV = "E2E_TEST_DATA_STREAMS_URL" E2E_TEST_DATA_STREAMS_USERNAME_ENV = "E2E_TEST_DATA_STREAMS_USERNAME" diff --git a/integration-tests/testsetups/ocr.go b/integration-tests/testsetups/ocr.go index 3653b9d5fb..73b142b629 100644 --- a/integration-tests/testsetups/ocr.go +++ b/integration-tests/testsetups/ocr.go @@ -281,8 +281,8 @@ func (o *OCRSoakTest) Setup(ocrTestConfig tt.OcrTestConfig) { o.mockServer = ctf_client.ConnectMockServer(o.testEnvironment) require.NoError(o.t, err, "Creating mockserver clients shouldn't fail") - linkContract, err := contracts.DeployLinkTokenContract(o.log, sethClient) - require.NoError(o.t, err, "Error deploying LINK contract") + linkContract, err := actions.LinkTokenContract(o.log, sethClient, ocrTestConfig.GetActiveOCRConfig()) + require.NoError(o.t, err, "Error loading/deploying link token contract") // Fund Chainlink nodes, excluding the bootstrap node o.log.Info().Float64("ETH amount per node", *o.Config.Common.ChainlinkNodeFunding).Msg("Funding Chainlink nodes") @@ -290,7 +290,6 @@ func (o *OCRSoakTest) Setup(ocrTestConfig tt.OcrTestConfig) { require.NoError(o.t, err, "Error funding Chainlink nodes") var forwarders []common.Address - if o.OperatorForwarderFlow { var operators []common.Address operators, forwarders, _ = actions.DeployForwarderContracts( @@ -311,17 +310,17 @@ func (o *OCRSoakTest) Setup(ocrTestConfig tt.OcrTestConfig) { o.ocrV1Instances, err = actions.DeployOCRContractsForwarderFlow( o.log, o.seth, - *o.Config.GetActiveOCRConfig().Soak.NumberOfContracts, + o.Config.GetActiveOCRConfig(), common.HexToAddress(linkContract.Address()), contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(o.workerNodes), forwarders, ) require.NoError(o.t, err, "Error deploying OCR Forwarder contracts") } else { - o.ocrV1Instances, err = actions.DeployOCRv1Contracts( + o.ocrV1Instances, err = actions.SetupOCRv1Contracts( o.log, sethClient, - *o.Config.GetActiveOCRConfig().Soak.NumberOfContracts, + o.Config.GetActiveOCRConfig(), common.HexToAddress(linkContract.Address()), contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(o.workerNodes), ) @@ -343,19 +342,22 @@ func (o *OCRSoakTest) Setup(ocrTestConfig tt.OcrTestConfig) { } ocrOffchainOptions := contracts.DefaultOffChainAggregatorOptions() - o.ocrV2Instances, err = actions.DeployOCRv2Contracts( + o.ocrV2Instances, err = actions.SetupOCRv2Contracts( o.log, o.seth, - *ocrTestConfig.GetActiveOCRConfig().Soak.NumberOfContracts, + ocrTestConfig.GetActiveOCRConfig(), common.HexToAddress(linkContract.Address()), transmitters, ocrOffchainOptions, ) require.NoError(o.t, err, "Error deploying OCRv2 contracts") - contractConfig, err := actions.BuildMedianOCR2Config(o.workerNodes, ocrOffchainOptions) - require.NoError(o.t, err, "Error building median config") - err = actions.ConfigureOCRv2AggregatorContracts(contractConfig, o.ocrV2Instances) - require.NoError(o.t, err, "Error configuring OCRv2 aggregator contracts") + + if !ocrTestConfig.GetActiveOCRConfig().UseExistingOffChainAggregatorsContracts() || (ocrTestConfig.GetActiveOCRConfig().UseExistingOffChainAggregatorsContracts() && ocrTestConfig.GetActiveOCRConfig().ConfigureExistingOffChainAggregatorsContracts()) { + contractConfig, err := actions.BuildMedianOCR2Config(o.workerNodes, ocrOffchainOptions) + require.NoError(o.t, err, "Error building median config") + err = actions.ConfigureOCRv2AggregatorContracts(contractConfig, o.ocrV2Instances) + require.NoError(o.t, err, "Error configuring OCRv2 aggregator contracts") + } } if o.OCRVersion == "1" { @@ -399,7 +401,7 @@ func (o *OCRSoakTest) Run() { o.log.Info(). Str("Test Duration", o.Config.GetActiveOCRConfig().Common.TestDuration.Duration.Truncate(time.Second).String()). - Int("Number of OCR Contracts", *config.GetActiveOCRConfig().Soak.NumberOfContracts). + Int("Number of OCR Contracts", *config.GetActiveOCRConfig().Common.NumberOfContracts). Str("OCR Version", o.OCRVersion). Msg("Starting OCR Soak Test") @@ -530,7 +532,7 @@ func (o *OCRSoakTest) LoadState() error { if testState.OCRVersion == "1" { o.ocrV1Instances = make([]contracts.OffchainAggregator, len(testState.OCRContractAddresses)) for i, addr := range testState.OCRContractAddresses { - instance, err := contracts.LoadOffchainAggregator(o.log, o.seth, common.HexToAddress(addr)) + instance, err := contracts.LoadOffChainAggregator(o.log, o.seth, common.HexToAddress(addr)) if err != nil { return fmt.Errorf("failed to instantiate OCR instance: %w", err) } @@ -539,7 +541,7 @@ func (o *OCRSoakTest) LoadState() error { } else if testState.OCRVersion == "2" { o.ocrV2Instances = make([]contracts.OffchainAggregatorV2, len(testState.OCRContractAddresses)) for i, addr := range testState.OCRContractAddresses { - instance, err := contracts.LoadOffChainAggregatorV2(o.log, o.seth, common.HexToAddress(addr)) + instance, err := contracts.LoadOffchainAggregatorV2(o.log, o.seth, common.HexToAddress(addr)) if err != nil { return err } @@ -561,7 +563,7 @@ func (o *OCRSoakTest) Resume() { Str("Time Left", o.timeLeft.String()). Msg("Resuming OCR Soak Test") - ocrAddresses := make([]common.Address, *o.Config.GetActiveOCRConfig().Soak.NumberOfContracts) + ocrAddresses := make([]common.Address, *o.Config.GetActiveOCRConfig().Common.NumberOfContracts) if o.OCRVersion == "1" { for i, ocrInstance := range o.ocrV1Instances { @@ -1021,12 +1023,12 @@ func (o *OCRSoakTest) collectEvents() error { // ensureValues ensures that all values needed to run the test are present func (o *OCRSoakTest) ensureInputValues() error { - ocrConfig := o.Config.GetActiveOCRConfig().Soak + ocrConfig := o.Config.GetActiveOCRConfig() if o.OCRVersion != "1" && o.OCRVersion != "2" { return fmt.Errorf("OCR version must be 1 or 2, found %s", o.OCRVersion) } - if ocrConfig.NumberOfContracts != nil && *ocrConfig.NumberOfContracts <= 0 { - return fmt.Errorf("number of OCR contracts must be set and greater than 0, found %d", ocrConfig.NumberOfContracts) + if ocrConfig.Common.NumberOfContracts != nil && *ocrConfig.Common.NumberOfContracts <= 0 { + return fmt.Errorf("number of OCR contracts must be set and greater than 0, found %d", ocrConfig.Common.NumberOfContracts) } if o.Config.Common.ChainlinkNodeFunding != nil && *o.Config.Common.ChainlinkNodeFunding <= 0 { return fmt.Errorf("chainlink node funding must be greater than 0, found %f", *o.Config.Common.ChainlinkNodeFunding) @@ -1034,11 +1036,12 @@ func (o *OCRSoakTest) ensureInputValues() error { if o.Config.GetActiveOCRConfig().Common.TestDuration != nil && o.Config.GetActiveOCRConfig().Common.TestDuration.Duration <= time.Minute { return fmt.Errorf("test duration must be greater than 1 minute, found %s", o.Config.GetActiveOCRConfig().Common.TestDuration) } - if ocrConfig.TimeBetweenRounds != nil && ocrConfig.TimeBetweenRounds.Duration >= time.Hour { - return fmt.Errorf("time between rounds must be less than 1 hour, found %s", ocrConfig.TimeBetweenRounds) + soakConfig := ocrConfig.Soak + if soakConfig.TimeBetweenRounds != nil && soakConfig.TimeBetweenRounds.Duration >= time.Hour { + return fmt.Errorf("time between rounds must be less than 1 hour, found %s", soakConfig.TimeBetweenRounds) } - if ocrConfig.TimeBetweenRounds != nil && ocrConfig.TimeBetweenRounds.Duration < time.Second*30 { - return fmt.Errorf("time between rounds must be greater or equal to 30 seconds, found %s", ocrConfig.TimeBetweenRounds) + if soakConfig.TimeBetweenRounds != nil && soakConfig.TimeBetweenRounds.Duration < time.Second*30 { + return fmt.Errorf("time between rounds must be greater or equal to 30 seconds, found %s", soakConfig.TimeBetweenRounds) } return nil From 0aa59850e08538be11e1b53406e786d15299ec98 Mon Sep 17 00:00:00 2001 From: Balamurali Gopalswami <167726375+b-gopalswami@users.noreply.github.com> Date: Thu, 19 Sep 2024 12:32:47 -0400 Subject: [PATCH 384/432] CCIP-3420: Fix IsRequestTriggeredWithinTimeframe (#1445) (#14498) ## Motivation The prior approach to find if there is traffic in a lane was not detecting the transactions properly. It could be due to the `CCIPSendRequestedWatcher` captures the event after it is initiated not any transaction before that. ## Solution The revised approach is to use the FilterCCIPSendRequested by a past derived block number and see if there is any traffic. The block number is derived by this formula: `filterFromBlock = latestBlockNumber - (SkipRequestIfAnotherRequestTriggeredWithin/avgBlockTime)` By this approach, we will be able to find traffic better. https://smartcontract-it.atlassian.net/browse/CCIP-3420 --- .../ccip-tests/actions/ccip_helpers.go | 44 +++++++++++++++++++ .../ccip-tests/load/ccip_loadgen.go | 15 ++++++- .../ccip-tests/testconfig/ccip.go | 3 ++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/integration-tests/ccip-tests/actions/ccip_helpers.go b/integration-tests/ccip-tests/actions/ccip_helpers.go index 06334560e0..da2e870f3e 100644 --- a/integration-tests/ccip-tests/actions/ccip_helpers.go +++ b/integration-tests/ccip-tests/actions/ccip_helpers.go @@ -1620,6 +1620,8 @@ func (sourceCCIP *SourceCCIPModule) AssertSendRequestedLogFinalized( return finalizedAt, finalizedBlockNum.Uint64(), nil } +// IsRequestTriggeredWithinTimeframe monitors for live events occurring within the specified timeframe. +// Live events refer to those that are triggered after subscribing to the CCIP Send Requested event. func (sourceCCIP *SourceCCIPModule) IsRequestTriggeredWithinTimeframe(timeframe *commonconfig.Duration) *time.Time { if timeframe == nil { return nil @@ -1644,6 +1646,48 @@ func (sourceCCIP *SourceCCIPModule) IsRequestTriggeredWithinTimeframe(timeframe return foundAt } +// IsPastRequestTriggeredWithinTimeframe determines the average block time and calculates the block numbers +// within the specified timeframe. It then uses FilterCCIPSendRequested to identify the past events. +func (sourceCCIP *SourceCCIPModule) IsPastRequestTriggeredWithinTimeframe(ctx context.Context, timeframe *commonconfig.Duration) (*time.Time, error) { + if timeframe == nil { + return nil, nil + } + //var foundAt *time.Time + latestBlock, err := sourceCCIP.Common.ChainClient.LatestBlockNumber(ctx) + if err != nil { + return nil, fmt.Errorf("error while getting latest source block number. Error: %w", err) + } + avgBlockTime, err := sourceCCIP.Common.ChainClient.AvgBlockTime(ctx) + if err != nil { + return nil, fmt.Errorf("error while getting average source block time. Error: %w", err) + } + filterFromBlock := latestBlock - uint64(timeframe.Duration()/avgBlockTime) + + onRampContract, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(common.HexToAddress(sourceCCIP.OnRamp.EthAddress.Hex()), + sourceCCIP.Common.ChainClient.Backend()) + if err != nil { + return nil, fmt.Errorf("error while on ramp contract. Error: %w", err) + } + iterator, err := onRampContract.FilterCCIPSendRequested(&bind.FilterOpts{ + Start: filterFromBlock, + }) + if err != nil { + return nil, fmt.Errorf("error while filtering CCIP send requested starting block number: %d. Error: %w", filterFromBlock, err) + } + defer func() { + _ = iterator.Close() + }() + if iterator.Next() { + hdr, err := sourceCCIP.Common.ChainClient.HeaderByNumber(context.Background(), big.NewInt(int64(iterator.Event.Raw.BlockNumber))) + if err != nil { + return nil, fmt.Errorf("error getting header for block: %d, Error: %w", iterator.Event.Raw.BlockNumber, err) + } + return pointer.ToTime(hdr.Timestamp), nil + } + + return nil, nil +} + func (sourceCCIP *SourceCCIPModule) AssertEventCCIPSendRequested( lggr *zerolog.Logger, txHash string, diff --git a/integration-tests/ccip-tests/load/ccip_loadgen.go b/integration-tests/ccip-tests/load/ccip_loadgen.go index bc7627b4e0..3ce770d31b 100644 --- a/integration-tests/ccip-tests/load/ccip_loadgen.go +++ b/integration-tests/ccip-tests/load/ccip_loadgen.go @@ -10,6 +10,8 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/AlekSi/pointer" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -222,7 +224,18 @@ func (c *CCIPE2ELoad) CCIPMsg() (router.ClientEVM2AnyMessage, *testreporters.Req func (c *CCIPE2ELoad) Call(_ *wasp.Generator) *wasp.Response { res := &wasp.Response{} sourceCCIP := c.Lane.Source - recentRequestFoundAt := sourceCCIP.IsRequestTriggeredWithinTimeframe(c.SkipRequestIfAnotherRequestTriggeredWithin) + var recentRequestFoundAt *time.Time + var err error + // Use IsPastRequestTriggeredWithinTimeframe to check for any historical CCIP send request events + // within the specified timeframe for the first message. Subsequently, use the watcher method to monitor + // and detect any new events as they occur. + if c.CurrentMsgSerialNo.Load() == int64(1) { + recentRequestFoundAt, err = sourceCCIP.IsPastRequestTriggeredWithinTimeframe(testcontext.Get(c.t), c.SkipRequestIfAnotherRequestTriggeredWithin) + require.NoError(c.t, err, "error while filtering past requests") + } else { + recentRequestFoundAt = sourceCCIP.IsRequestTriggeredWithinTimeframe(c.SkipRequestIfAnotherRequestTriggeredWithin) + } + if recentRequestFoundAt != nil { c.Lane.Logger. Info(). diff --git a/integration-tests/ccip-tests/testconfig/ccip.go b/integration-tests/ccip-tests/testconfig/ccip.go index 76e00ecf49..0a53ee1873 100644 --- a/integration-tests/ccip-tests/testconfig/ccip.go +++ b/integration-tests/ccip-tests/testconfig/ccip.go @@ -242,6 +242,9 @@ func (l *LoadProfile) Validate() error { if l.TestDuration == nil || l.TestDuration.Duration().Minutes() == 0 { return fmt.Errorf("test duration should be set") } + if l.SkipRequestIfAnotherRequestTriggeredWithin != nil && l.TimeUnit.Duration() < l.SkipRequestIfAnotherRequestTriggeredWithin.Duration() { + return fmt.Errorf("SkipRequestIfAnotherRequestTriggeredWithin should be set below the TimeUnit duration") + } return nil } From d2a01ca51bb4a7654d2ceb4f5c25f2ca2de3df11 Mon Sep 17 00:00:00 2001 From: Oliver Townsend <133903322+ogtownsend@users.noreply.github.com> Date: Thu, 19 Sep 2024 09:54:04 -0700 Subject: [PATCH 385/432] Bring KMS client and multiclient over to chainlink (#14484) * Bring KMS client and multiclient over to chainlink * Pull seth client into multiclient * remove toml tags * Keep multiclient simple * Config validation for kms * Rename to ws, fix test * Changeset * Downgrade seth * Lint * More lint --------- Co-authored-by: AnieeG Co-authored-by: connorwstein --- .changeset/sour-ears-wink.md | 5 + .../ccip/ccip_integration_tests/helpers.go | 2 - integration-tests/deployment/evm_kmsclient.go | 233 ++++++++++++++++++ .../deployment/evm_kmsclient_test.go | 27 ++ integration-tests/deployment/multiclient.go | 124 ++++++++++ .../deployment/multiclient_test.go | 36 +++ integration-tests/go.mod | 2 +- 7 files changed, 426 insertions(+), 3 deletions(-) create mode 100644 .changeset/sour-ears-wink.md create mode 100644 integration-tests/deployment/evm_kmsclient.go create mode 100644 integration-tests/deployment/evm_kmsclient_test.go create mode 100644 integration-tests/deployment/multiclient.go create mode 100644 integration-tests/deployment/multiclient_test.go diff --git a/.changeset/sour-ears-wink.md b/.changeset/sour-ears-wink.md new file mode 100644 index 0000000000..d77fd548c5 --- /dev/null +++ b/.changeset/sour-ears-wink.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal KMS client for deployment diff --git a/core/capabilities/ccip/ccip_integration_tests/helpers.go b/core/capabilities/ccip/ccip_integration_tests/helpers.go index 25baddfb48..4670333e39 100644 --- a/core/capabilities/ccip/ccip_integration_tests/helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/helpers.go @@ -406,7 +406,6 @@ func (h *homeChain) AddNodes( p2pIDs [][32]byte, capabilityIDs [][32]byte, ) { - // Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail sortP2PIDS(p2pIDs) var nodeParams []kcr.CapabilitiesRegistryNodeParams for _, p2pID := range p2pIDs { @@ -430,7 +429,6 @@ func AddChainConfig( p2pIDs [][32]byte, f uint8, ) ccip_config.CCIPConfigTypesChainConfigInfo { - // Need to sort, otherwise _checkIsValidUniqueSubset onChain will fail sortP2PIDS(p2pIDs) // First Add ChainConfig that includes all p2pIDs as readers encodedExtraChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ diff --git a/integration-tests/deployment/evm_kmsclient.go b/integration-tests/deployment/evm_kmsclient.go new file mode 100644 index 0000000000..07af77523c --- /dev/null +++ b/integration-tests/deployment/evm_kmsclient.go @@ -0,0 +1,233 @@ +package deployment + +import ( + "bytes" + "context" + "crypto/ecdsa" + "encoding/asn1" + "encoding/hex" + "fmt" + "math/big" + + "github.com/aws/aws-sdk-go/aws/session" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/kms" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/secp256k1" +) + +var ( + secp256k1N = crypto.S256().Params().N + secp256k1HalfN = new(big.Int).Div(secp256k1N, big.NewInt(2)) +) + +// See https://docs.aws.amazon.com/kms/latest/APIReference/API_GetPublicKey.html#API_GetPublicKey_ResponseSyntax +// and https://datatracker.ietf.org/doc/html/rfc5280 for why we need to unpack the KMS public key. +type asn1SubjectPublicKeyInfo struct { + AlgorithmIdentifier asn1AlgorithmIdentifier + SubjectPublicKey asn1.BitString +} + +type asn1AlgorithmIdentifier struct { + Algorithm asn1.ObjectIdentifier + Parameters asn1.ObjectIdentifier +} + +// See https://aws.amazon.com/blogs/database/part2-use-aws-kms-to-securely-manage-ethereum-accounts/ for why we +// need to manually prep the signature for Ethereum. +type asn1ECDSASig struct { + R asn1.RawValue + S asn1.RawValue +} + +// TODO: Mockery gen then test with a regular eth key behind the interface. +type KMSClient interface { + GetPublicKey(input *kms.GetPublicKeyInput) (*kms.GetPublicKeyOutput, error) + Sign(input *kms.SignInput) (*kms.SignOutput, error) +} + +type KMS struct { + KmsDeployerKeyId string + KmsDeployerKeyRegion string + AwsProfileName string +} + +func NewKMSClient(config KMS) (KMSClient, error) { + if config.KmsDeployerKeyId == "" { + return nil, fmt.Errorf("KMS key ID is required") + } + if config.KmsDeployerKeyRegion == "" { + return nil, fmt.Errorf("KMS key region is required") + } + var awsSessionFn AwsSessionFn + if config.AwsProfileName != "" { + awsSessionFn = awsSessionFromProfileFn + } else { + awsSessionFn = awsSessionFromEnvVarsFn + } + return kms.New(awsSessionFn(config)), nil +} + +type EVMKMSClient struct { + Client KMSClient + KeyID string +} + +func NewEVMKMSClient(client KMSClient, keyID string) *EVMKMSClient { + return &EVMKMSClient{ + Client: client, + KeyID: keyID, + } +} + +func (c *EVMKMSClient) GetKMSTransactOpts(ctx context.Context, chainID *big.Int) (*bind.TransactOpts, error) { + ecdsaPublicKey, err := c.GetECDSAPublicKey() + if err != nil { + return nil, err + } + + pubKeyBytes := secp256k1.S256().Marshal(ecdsaPublicKey.X, ecdsaPublicKey.Y) + keyAddr := crypto.PubkeyToAddress(*ecdsaPublicKey) + if chainID == nil { + return nil, fmt.Errorf("chainID is required") + } + signer := types.LatestSignerForChainID(chainID) + + signerFn := func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { + if address != keyAddr { + return nil, bind.ErrNotAuthorized + } + + txHashBytes := signer.Hash(tx).Bytes() + + mType := kms.MessageTypeDigest + algo := kms.SigningAlgorithmSpecEcdsaSha256 + signOutput, err := c.Client.Sign( + &kms.SignInput{ + KeyId: &c.KeyID, + SigningAlgorithm: &algo, + MessageType: &mType, + Message: txHashBytes, + }) + if err != nil { + return nil, fmt.Errorf("failed to call kms.Sign() on transaction: %w", err) + } + + ethSig, err := kmsToEthSig(signOutput.Signature, pubKeyBytes, txHashBytes) + if err != nil { + return nil, fmt.Errorf("failed to convert KMS signature to Ethereum signature: %w", err) + } + + return tx.WithSignature(signer, ethSig) + } + + return &bind.TransactOpts{ + From: keyAddr, + Signer: signerFn, + Context: ctx, + }, nil +} + +// GetECDSAPublicKey retrieves the public key from KMS and converts it to its ECDSA representation. +func (c *EVMKMSClient) GetECDSAPublicKey() (*ecdsa.PublicKey, error) { + getPubKeyOutput, err := c.Client.GetPublicKey(&kms.GetPublicKeyInput{ + KeyId: aws.String(c.KeyID), + }) + if err != nil { + return nil, fmt.Errorf("can not get public key from KMS for KeyId=%s: %w", c.KeyID, err) + } + + var asn1pubKeyInfo asn1SubjectPublicKeyInfo + _, err = asn1.Unmarshal(getPubKeyOutput.PublicKey, &asn1pubKeyInfo) + if err != nil { + return nil, fmt.Errorf("can not parse asn1 public key for KeyId=%s: %w", c.KeyID, err) + } + + pubKey, err := crypto.UnmarshalPubkey(asn1pubKeyInfo.SubjectPublicKey.Bytes) + if err != nil { + return nil, fmt.Errorf("can not unmarshal public key bytes: %w", err) + } + return pubKey, nil +} + +func kmsToEthSig(kmsSig, ecdsaPubKeyBytes, hash []byte) ([]byte, error) { + var asn1Sig asn1ECDSASig + _, err := asn1.Unmarshal(kmsSig, &asn1Sig) + if err != nil { + return nil, err + } + + rBytes := asn1Sig.R.Bytes + sBytes := asn1Sig.S.Bytes + + // Adjust S value from signature to match Eth standard. + // See: https://aws.amazon.com/blogs/database/part2-use-aws-kms-to-securely-manage-ethereum-accounts/ + // "After we extract r and s successfully, we have to test if the value of s is greater than secp256k1n/2 as + // specified in EIP-2 and flip it if required." + sBigInt := new(big.Int).SetBytes(sBytes) + if sBigInt.Cmp(secp256k1HalfN) > 0 { + sBytes = new(big.Int).Sub(secp256k1N, sBigInt).Bytes() + } + + return recoverEthSignature(ecdsaPubKeyBytes, hash, rBytes, sBytes) +} + +// See: https://aws.amazon.com/blogs/database/part2-use-aws-kms-to-securely-manage-ethereum-accounts/ +func recoverEthSignature(expectedPublicKeyBytes, txHash, r, s []byte) ([]byte, error) { + rsSig := append(padTo32Bytes(r), padTo32Bytes(s)...) + ethSig := append(rsSig, []byte{0}...) + + recoveredPublicKeyBytes, err := crypto.Ecrecover(txHash, ethSig) + if err != nil { + return nil, fmt.Errorf("failing to call Ecrecover: %w", err) + } + + if hex.EncodeToString(recoveredPublicKeyBytes) != hex.EncodeToString(expectedPublicKeyBytes) { + ethSig = append(rsSig, []byte{1}...) + recoveredPublicKeyBytes, err = crypto.Ecrecover(txHash, ethSig) + if err != nil { + return nil, fmt.Errorf("failing to call Ecrecover: %w", err) + } + + if hex.EncodeToString(recoveredPublicKeyBytes) != hex.EncodeToString(expectedPublicKeyBytes) { + return nil, fmt.Errorf("can not reconstruct public key from sig") + } + } + + return ethSig, nil +} + +func padTo32Bytes(buffer []byte) []byte { + buffer = bytes.TrimLeft(buffer, "\x00") + for len(buffer) < 32 { + zeroBuf := []byte{0} + buffer = append(zeroBuf, buffer...) + } + return buffer +} + +type AwsSessionFn func(config KMS) *session.Session + +var awsSessionFromEnvVarsFn = func(config KMS) *session.Session { + return session.Must( + session.NewSession(&aws.Config{ + Region: aws.String(config.KmsDeployerKeyRegion), + CredentialsChainVerboseErrors: aws.Bool(true), + })) +} + +var awsSessionFromProfileFn = func(config KMS) *session.Session { + return session.Must( + session.NewSessionWithOptions(session.Options{ + SharedConfigState: session.SharedConfigEnable, + Profile: config.AwsProfileName, + Config: aws.Config{ + Region: aws.String(config.KmsDeployerKeyRegion), + CredentialsChainVerboseErrors: aws.Bool(true), + }, + })) +} diff --git a/integration-tests/deployment/evm_kmsclient_test.go b/integration-tests/deployment/evm_kmsclient_test.go new file mode 100644 index 0000000000..8a889a5606 --- /dev/null +++ b/integration-tests/deployment/evm_kmsclient_test.go @@ -0,0 +1,27 @@ +package deployment + +import ( + "encoding/hex" + "testing" + + "github.com/test-go/testify/require" +) + +func TestKMSToEthSigConversion(t *testing.T) { + kmsSigBytes, err := hex.DecodeString("304402206168865941bafcae3a8cf8b26edbb5693d62222b2e54d962c1aabbeaddf33b6802205edc7f597d2bf2d1eaa14fc514a6202bafcffe52b13ae3fec00674d92a874b73") + require.NoError(t, err) + ecdsaPublicKeyBytes, err := hex.DecodeString("04a735e9e3cb526f83be23b03f1f5ae7788a8654e3f0fcfb4f978290de07ebd47da30eeb72e904fdd4a81b46e320908ff4345e119148f89c1f04674c14a506e24b") + require.NoError(t, err) + txHashBytes, err := hex.DecodeString("a2f037301e90f58c084fe4bec2eef14b26e620d6b6cb46051037d03b29ab7d9a") + require.NoError(t, err) + expectedEthSignBytes, err := hex.DecodeString("6168865941bafcae3a8cf8b26edbb5693d62222b2e54d962c1aabbeaddf33b685edc7f597d2bf2d1eaa14fc514a6202bafcffe52b13ae3fec00674d92a874b7300") + require.NoError(t, err) + + actualEthSig, err := kmsToEthSig( + kmsSigBytes, + ecdsaPublicKeyBytes, + txHashBytes, + ) + require.NoError(t, err) + require.Equal(t, expectedEthSignBytes, actualEthSig) +} diff --git a/integration-tests/deployment/multiclient.go b/integration-tests/deployment/multiclient.go new file mode 100644 index 0000000000..02a18f760d --- /dev/null +++ b/integration-tests/deployment/multiclient.go @@ -0,0 +1,124 @@ +package deployment + +import ( + "context" + "fmt" + "math/big" + "time" + + "github.com/avast/retry-go/v4" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/pkg/errors" +) + +const ( + RPC_DEFAULT_RETRY_ATTEMPTS = 10 + RPC_DEFAULT_RETRY_DELAY = 1000 * time.Millisecond +) + +type RetryConfig struct { + Attempts uint + Delay time.Duration +} + +func defaultRetryConfig() RetryConfig { + return RetryConfig{ + Attempts: RPC_DEFAULT_RETRY_ATTEMPTS, + Delay: RPC_DEFAULT_RETRY_DELAY, + } +} + +type RPC struct { + WSURL string + // TODO: http fallback needed for some networks? +} + +// MultiClient should comply with the OnchainClient interface +var _ OnchainClient = &MultiClient{} + +type MultiClient struct { + *ethclient.Client + Backups []*ethclient.Client + RetryConfig RetryConfig +} + +func NewMultiClient(rpcs []RPC, opts ...func(client *MultiClient)) (*MultiClient, error) { + if len(rpcs) == 0 { + return nil, fmt.Errorf("No RPCs provided, need at least one") + } + var mc MultiClient + clients := make([]*ethclient.Client, 0, len(rpcs)) + for _, rpc := range rpcs { + client, err := ethclient.Dial(rpc.WSURL) + if err != nil { + return nil, errors.Wrapf(err, "failed to dial %s", rpc.WSURL) + } + clients = append(clients, client) + } + mc.Client = clients[0] + mc.Backups = clients[1:] + mc.RetryConfig = defaultRetryConfig() + + for _, opt := range opts { + opt(&mc) + } + return &mc, nil +} + +func (mc *MultiClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + var receipt *types.Receipt + err := mc.retryWithBackups(func(client *ethclient.Client) error { + var err error + receipt, err = client.TransactionReceipt(ctx, txHash) + return err + }) + return receipt, err +} + +func (mc *MultiClient) SendTransaction(ctx context.Context, tx *types.Transaction) error { + return mc.retryWithBackups(func(client *ethclient.Client) error { + return client.SendTransaction(ctx, tx) + }) +} + +func (mc *MultiClient) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { + var code []byte + err := mc.retryWithBackups(func(client *ethclient.Client) error { + var err error + code, err = client.CodeAt(ctx, account, blockNumber) + return err + }) + return code, err +} + +func (mc *MultiClient) NonceAt(ctx context.Context, account common.Address) (uint64, error) { + var count uint64 + err := mc.retryWithBackups(func(client *ethclient.Client) error { + var err error + count, err = client.NonceAt(ctx, account, nil) + return err + }) + return count, err +} + +func (mc *MultiClient) retryWithBackups(op func(*ethclient.Client) error) error { + var err error + for _, client := range append([]*ethclient.Client{mc.Client}, mc.Backups...) { + err2 := retry.Do(func() error { + err = op(client) + if err != nil { + // TODO: logger? + fmt.Printf("Error %v with client %v\n", err, client) + return err + } + return nil + }, retry.Attempts(mc.RetryConfig.Attempts), retry.Delay(mc.RetryConfig.Delay)) + if err2 == nil { + return nil + } + fmt.Printf("Client %v failed, trying next client\n", client) + } + return errors.Wrapf(err, "All backup clients %v failed", mc.Backups) +} diff --git a/integration-tests/deployment/multiclient_test.go b/integration-tests/deployment/multiclient_test.go new file mode 100644 index 0000000000..a3176691c0 --- /dev/null +++ b/integration-tests/deployment/multiclient_test.go @@ -0,0 +1,36 @@ +package deployment + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestMultiClient(t *testing.T) { + // Expect an error if no RPCs supplied. + s := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + writer.WriteHeader(http.StatusOK) + _, err := writer.Write([]byte(`{"jsonrpc":"2.0","id":1,"result":true}`)) + require.NoError(t, err) + })) + defer s.Close() + _, err := NewMultiClient([]RPC{}) + require.Error(t, err) + + // Expect defaults to be set if not provided. + mc, err := NewMultiClient([]RPC{{WSURL: s.URL}}) + require.NoError(t, err) + assert.Equal(t, mc.RetryConfig.Attempts, uint(RPC_DEFAULT_RETRY_ATTEMPTS)) + assert.Equal(t, mc.RetryConfig.Delay, RPC_DEFAULT_RETRY_DELAY) + + // Expect second client to be set as backup. + mc, err = NewMultiClient([]RPC{ + {WSURL: s.URL}, + {WSURL: s.URL}, + }) + require.NoError(t, err) + require.Equal(t, len(mc.Backups), 1) +} diff --git a/integration-tests/go.mod b/integration-tests/go.mod index c8304390a0..d7d460801a 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -11,6 +11,7 @@ require ( github.com/Khan/genqlient v0.7.0 github.com/Masterminds/semver/v3 v3.2.1 github.com/avast/retry-go/v4 v4.6.0 + github.com/aws/aws-sdk-go v1.45.25 github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a github.com/cli/go-gh/v2 v2.0.0 @@ -107,7 +108,6 @@ require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/avast/retry-go v3.0.0+incompatible // indirect github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect - github.com/aws/aws-sdk-go v1.45.25 // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.28 // indirect From 3a89dceab79217880625f7af75db0d798cf79488 Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Date: Thu, 19 Sep 2024 19:03:34 +0200 Subject: [PATCH 386/432] use tx in insertLogsWithinTx (#14361) --- .changeset/sixty-cougars-mix.md | 5 +++++ core/chains/evm/logpoller/orm.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/sixty-cougars-mix.md diff --git a/.changeset/sixty-cougars-mix.md b/.changeset/sixty-cougars-mix.md new file mode 100644 index 0000000000..a641ce1976 --- /dev/null +++ b/.changeset/sixty-cougars-mix.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Use tx in insertLogsWithinTx #internal diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index 5ab7db4eb0..e40fb80f10 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -390,7 +390,7 @@ func (o *DSORM) insertLogsWithinTx(ctx context.Context, logs []Log, tx sqlutil.D (:evm_chain_id, :log_index, :block_hash, :block_number, :block_timestamp, :address, :event_sig, :topics, :tx_hash, :data, NOW()) ON CONFLICT DO NOTHING` - _, err := o.ds.NamedExecContext(ctx, query, logs[start:end]) + _, err := tx.NamedExecContext(ctx, query, logs[start:end]) if err != nil { if pkgerrors.Is(err, context.DeadlineExceeded) && batchInsertSize > 500 { // In case of DB timeouts, try to insert again with a smaller batch upto a limit From 014a9f51df269d6461ce76c9418ce1977e04e3ac Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Thu, 19 Sep 2024 13:54:38 -0400 Subject: [PATCH 387/432] Fix CCIP Load Test Faulty Fund Return (#14499) * Stop fund return on nil client * DEBUG * Remove debug --- integration-tests/actions/actions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index f864d9e710..e395c9a251 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -714,7 +714,7 @@ func TeardownSuite( l.Warn().Msgf("Error deleting jobs %+v", err) } - if chainlinkNodes != nil { + if chainlinkNodes != nil && chainClient != nil { if err := ReturnFundsFromNodes(l, chainClient, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(chainlinkNodes)); err != nil { // This printed line is required for tests that use real funds to propagate the failure // out to the system running the test. Do not remove From 7b324cad8f46ab740ba84c889eca684ed1c87799 Mon Sep 17 00:00:00 2001 From: Domino Valdano Date: Thu, 19 Sep 2024 11:02:10 -0700 Subject: [PATCH 388/432] Fix data race in TestLogPoller_Replay (#14431) * Add RWMutex around global head var * Use atomic.Pointer instead of RWMutex --- .../evm/logpoller/log_poller_internal_test.go | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/core/chains/evm/logpoller/log_poller_internal_test.go b/core/chains/evm/logpoller/log_poller_internal_test.go index 448710b93f..ca1bd72dd6 100644 --- a/core/chains/evm/logpoller/log_poller_internal_test.go +++ b/core/chains/evm/logpoller/log_poller_internal_test.go @@ -7,6 +7,7 @@ import ( "math/big" "strings" "sync" + "sync/atomic" "testing" "time" @@ -287,12 +288,14 @@ func TestLogPoller_Replay(t *testing.T) { db := pgtest.NewSqlxDB(t) orm := NewORM(chainID, db, lggr) - head := evmtypes.Head{Number: 4} + var head atomic.Pointer[evmtypes.Head] + head.Store(&evmtypes.Head{Number: 4}) + events := []common.Hash{EmitterABI.Events["Log1"].ID} log1 := types.Log{ Index: 0, BlockHash: common.Hash{}, - BlockNumber: uint64(head.Number), + BlockNumber: uint64(head.Load().Number), Topics: events, Address: addr, TxHash: common.HexToHash("0x1234"), @@ -301,8 +304,7 @@ func TestLogPoller_Replay(t *testing.T) { ec := evmclimocks.NewClient(t) ec.On("HeadByNumber", mock.Anything, mock.Anything).Return(func(context.Context, *big.Int) (*evmtypes.Head, error) { - headCopy := head - return &headCopy, nil + return head.Load(), nil }) ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil).Once() ec.On("ConfiguredChainID").Return(chainID, nil) @@ -318,9 +320,9 @@ func TestLogPoller_Replay(t *testing.T) { headTracker := htMocks.NewHeadTracker[*evmtypes.Head, common.Hash](t) headTracker.On("LatestAndFinalizedBlock", mock.Anything).Return(func(ctx context.Context) (*evmtypes.Head, *evmtypes.Head, error) { - headCopy := head - finalized := &evmtypes.Head{Number: headCopy.Number - lpOpts.FinalityDepth} - return &headCopy, finalized, nil + h := head.Load() + finalized := &evmtypes.Head{Number: h.Number - lpOpts.FinalityDepth} + return h, finalized, nil }) lp := NewLogPoller(orm, ec, lggr, headTracker, lpOpts) @@ -394,7 +396,7 @@ func TestLogPoller_Replay(t *testing.T) { var wg sync.WaitGroup defer func() { wg.Wait() }() ec.On("FilterLogs", mock.Anything, mock.Anything).Once().Return([]types.Log{log1}, nil).Run(func(args mock.Arguments) { - head = evmtypes.Head{Number: 4} + head.Store(&evmtypes.Head{Number: 4}) wg.Add(1) go func() { defer wg.Done() @@ -421,7 +423,7 @@ func TestLogPoller_Replay(t *testing.T) { ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil).Maybe() // in case task gets delayed by >= 100ms - head = evmtypes.Head{Number: 5} + head.Store(&evmtypes.Head{Number: 5}) t.Cleanup(lp.reset) servicetest.Run(t, lp) @@ -448,7 +450,7 @@ func TestLogPoller_Replay(t *testing.T) { go func() { defer close(done) - head = evmtypes.Head{Number: 4} // Restore latest block to 4, so this matches the fromBlock requested + head.Store(&evmtypes.Head{Number: 4}) // Restore latest block to 4, so this matches the fromBlock requested select { case lp.replayStart <- 4: case <-ctx.Done(): @@ -469,7 +471,7 @@ func TestLogPoller_Replay(t *testing.T) { ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil) t.Cleanup(lp.reset) - head = evmtypes.Head{Number: 5} // Latest block must be > lastProcessed in order for SaveAndPollLogs() to call FilterLogs() + head.Store(&evmtypes.Head{Number: 5}) // Latest block must be > lastProcessed in order for SaveAndPollLogs() to call FilterLogs() servicetest.Run(t, lp) select { @@ -482,7 +484,8 @@ func TestLogPoller_Replay(t *testing.T) { // ReplayAsync should return as soon as replayStart is received t.Run("ReplayAsync success", func(t *testing.T) { t.Cleanup(lp.reset) - head = evmtypes.Head{Number: 5} + + head.Store(&evmtypes.Head{Number: 5}) ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil) mockBatchCallContext(t, ec) servicetest.Run(t, lp) @@ -496,7 +499,7 @@ func TestLogPoller_Replay(t *testing.T) { ctx := testutils.Context(t) t.Cleanup(lp.reset) servicetest.Run(t, lp) - head = evmtypes.Head{Number: 4} + head.Store(&evmtypes.Head{Number: 4}) anyErr := pkgerrors.New("async error") observedLogs.TakeAll() @@ -528,7 +531,8 @@ func TestLogPoller_Replay(t *testing.T) { err := lp.orm.DeleteLogsAndBlocksAfter(ctx, 0) require.NoError(t, err) - err = lp.orm.InsertBlock(ctx, head.Hash, head.Number, head.Timestamp, head.Number) + h := head.Load() + err = lp.orm.InsertBlock(ctx, h.Hash, h.Number, h.Timestamp, h.Number) require.NoError(t, err) ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil) From 1e39e3c792086595489b68a22407c471530d4d41 Mon Sep 17 00:00:00 2001 From: ilija42 <57732589+ilija42@users.noreply.github.com> Date: Fri, 20 Sep 2024 14:22:20 +0200 Subject: [PATCH 389/432] [BCFR-198] - Simplify Chain Reader event init (#14493) * Simplify/lint Chain Reader event init * Cleanup ChainReader initDWQuerying to match initTopicQuerying --- core/services/relay/evm/chain_reader.go | 63 ++++++++----------------- 1 file changed, 19 insertions(+), 44 deletions(-) diff --git a/core/services/relay/evm/chain_reader.go b/core/services/relay/evm/chain_reader.go index f4d464f658..1446d730d7 100644 --- a/core/services/relay/evm/chain_reader.go +++ b/core/services/relay/evm/chain_reader.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "maps" - "reflect" "slices" "strings" "time" @@ -248,10 +247,7 @@ func (cr *chainReader) addEvent(contractName, eventName string, a abi.ABI, chain codecTypes, codecModifiers := make(map[string]types.CodecEntry), make(map[string]commoncodec.Modifier) topicTypeID := codec.WrapItemType(contractName, eventName, true) - codecTypes[topicTypeID], codecModifiers[topicTypeID], err = cr.getEventItemTypeAndModifier(topicTypeID, chainReaderDefinition.InputModifications) - if err != nil { - return err - } + codecTypes[topicTypeID], codecModifiers[topicTypeID] = cr.getEventItemTypeAndModifier(topicTypeID) confirmations, err := ConfirmationsFromConfig(chainReaderDefinition.ConfidenceConfirmations) if err != nil { @@ -299,20 +295,15 @@ func (cr *chainReader) initTopicQuerying(contractName, eventName string, eventIn for topicIndex, topic := range eventInputs { genericTopicName, ok := genericTopicNames[topic.Name] if ok { - // Encoder defs codec won't be used for encoding, but for storing caller filtering params which won't be hashed. - topicTypeID := eventName + "." + genericTopicName - err := cr.addEncoderDef(contractName, topicTypeID, abi.Arguments{{Type: topic.Type}}, nil, inputModifications) - if err != nil { - return nil, nil, nil, err - } + topicsDetails[genericTopicName] = read.TopicDetail{Argument: topic, Index: uint64(topicIndex + 1)} - topicTypeID = codec.WrapItemType(contractName, topicTypeID, true) - topicsTypes[topicTypeID], topicsModifiers[topicTypeID], err = cr.getEventItemTypeAndModifier(topicTypeID, inputModifications) - if err != nil { + topicTypeID := eventName + "." + genericTopicName + if err := cr.addEncoderDef(contractName, topicTypeID, abi.Arguments{{Type: topic.Type}}, nil, inputModifications); err != nil { return nil, nil, nil, err } - topicsDetails[genericTopicName] = read.TopicDetail{Argument: topic, Index: uint64(topicIndex + 1)} + topicCodecTypeID := codec.WrapItemType(contractName, topicTypeID, true) + topicsTypes[topicCodecTypeID], topicsModifiers[topicCodecTypeID] = cr.getEventItemTypeAndModifier(topicCodecTypeID) } } return topicsDetails, topicsTypes, topicsModifiers, nil @@ -324,47 +315,31 @@ func (cr *chainReader) initDWQuerying(contractName, eventName string, eventDWs m dWsDetail := make(map[string]read.DataWordDetail) for genericName, onChainName := range dWDefs { - foundDW := false for _, dWDetail := range eventDWs { - if dWDetail.Name != onChainName { - continue - } + if dWDetail.Name == onChainName { + dWsDetail[genericName] = dWDetail - foundDW = true + dwTypeID := eventName + "." + genericName + if err := cr.addEncoderDef(contractName, dwTypeID, abi.Arguments{abi.Argument{Type: dWDetail.Type}}, nil, nil); err != nil { + return nil, nil, fmt.Errorf("%w: failed to init codec for data word %s on index %d querying for event: %q", err, genericName, dWDetail.Index, eventName) + } - dwTypeID := eventName + "." + genericName - if err := cr.addEncoderDef(contractName, dwTypeID, abi.Arguments{abi.Argument{Type: dWDetail.Type}}, nil, nil); err != nil { - return nil, nil, fmt.Errorf("%w: failed to init codec for data word %s on index %d querying for event: %q", err, genericName, dWDetail.Index, eventName) + dwCodecTypeID := codec.WrapItemType(contractName, dwTypeID, true) + dwsCodecTypeInfo[dwCodecTypeID] = cr.parsed.EncoderDefs[dwCodecTypeID] + break } - - dwCodecTypeID := codec.WrapItemType(contractName, dwTypeID, true) - dwsCodecTypeInfo[dwCodecTypeID] = cr.parsed.EncoderDefs[dwCodecTypeID] - - dWsDetail[genericName] = dWDetail - break } - if !foundDW { - return nil, nil, fmt.Errorf("failed to find data word: %q for event: %q, its either out of bounds or can't be searched for", genericName, eventName) + if _, ok := dWsDetail[genericName]; !ok { + return nil, nil, fmt.Errorf("failed to find data word: %q for event: %q, it either doesn't exist or can't be searched for", genericName, eventName) } } return dWsDetail, dwsCodecTypeInfo, nil } // getEventItemTypeAndModifier returns codec entry for expected incoming event item and the modifier. -func (cr *chainReader) getEventItemTypeAndModifier(itemType string, inputMod commoncodec.ModifiersConfig) (types.CodecEntry, commoncodec.Modifier, error) { +func (cr *chainReader) getEventItemTypeAndModifier(itemType string) (types.CodecEntry, commoncodec.Modifier) { inputTypeInfo := cr.parsed.EncoderDefs[itemType] - // TODO can this be simplified? Isn't this same as inputType.Modifier()? BCI-3909 - inMod, err := inputMod.ToModifier(codec.DecoderHooks...) - if err != nil { - return nil, nil, err - } - - // initialize the modification - if _, err = inMod.RetypeToOffChain(reflect.PointerTo(inputTypeInfo.CheckedType()), ""); err != nil { - return nil, nil, err - } - - return inputTypeInfo, inMod, nil + return inputTypeInfo, inputTypeInfo.Modifier() } func (cr *chainReader) addEncoderDef(contractName, itemType string, args abi.Arguments, prefix []byte, inputModifications commoncodec.ModifiersConfig) error { From 22a8c993ae6ae6ee69626bd239ba2a419fbad450 Mon Sep 17 00:00:00 2001 From: "Abdelrahman Soliman (Boda)" <2677789+asoliman92@users.noreply.github.com> Date: Fri, 20 Sep 2024 18:59:56 +0400 Subject: [PATCH 390/432] Add feed chain deployment test (#14461) * Initial Commit * Add deploy_feed_chain * Refactor deployCapReg to take the chain directly without the selector * Deploy mock link feed * Add merge method to State * Use AddressBook merge * Deploy feed chain in NewEnvironment helper * Move DeployFeeds into test helpers * Add token_info.go token_info facilitates sending tokenConfig to CCIPDeployConfig * go get cl-ccip with reader enabled * wip assert token price reported * make gomodtidy * Change Descriptor to Symbol * fix linting and add changeset * Change Feeds to USDFeeds * Assert token prices by calling FeeQuoter after the commit report * Test token prices in add_chain * bump cl-ccip version * Remove unused code from token_info.go * fix linting * fix linting --- .changeset/young-lions-provide.md | 5 + core/scripts/go.mod | 4 +- core/scripts/go.sum | 8 +- go.mod | 4 +- go.sum | 8 +- .../deployment/ccip/add_chain.go | 15 ++- .../deployment/ccip/add_chain_test.go | 25 ++++- .../deployment/ccip/add_lane_test.go | 2 + .../deployment/ccip/changeset/1_cap_reg.go | 2 +- .../ccip/changeset/2_initial_deploy_test.go | 49 ++++++--- integration-tests/deployment/ccip/consts.go | 10 ++ integration-tests/deployment/ccip/deploy.go | 11 +- .../deployment/ccip/deploy_home_chain.go | 27 +++-- .../deployment/ccip/deploy_test.go | 27 ++++- integration-tests/deployment/ccip/state.go | 41 +++++-- .../deployment/ccip/test_assertions.go | 4 +- .../deployment/ccip/test_helpers.go | 102 ++++++++++++++++-- .../deployment/ccip/token_info.go | 47 ++++++++ integration-tests/go.mod | 4 +- integration-tests/go.sum | 8 +- integration-tests/load/go.mod | 4 +- integration-tests/load/go.sum | 8 +- 22 files changed, 341 insertions(+), 74 deletions(-) create mode 100644 .changeset/young-lions-provide.md create mode 100644 integration-tests/deployment/ccip/consts.go create mode 100644 integration-tests/deployment/ccip/token_info.go diff --git a/.changeset/young-lions-provide.md b/.changeset/young-lions-provide.md new file mode 100644 index 0000000000..45add9558d --- /dev/null +++ b/.changeset/young-lions-provide.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added feed deployment to ccip integration tests diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 720ceec8d1..88388d1c7b 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.20.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 + github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.1 @@ -271,7 +271,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 6684beddc9..49cba89576 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1081,10 +1081,10 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 h1:xPEM9XbfZmv8N3NjZ7AX5salonll/LdXrbb8JCbA4FE= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 h1:wqLXuPdiUkn7es/epKmOpB0Q0tKdA9FkYPNQZrZ+VJU= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 h1:/Bx9MUUQ+TfS8kIdER8gujpJWfYu8ft4FYzpH8gSPJY= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= diff --git a/go.mod b/go.mod index 36160f8e96..4052892209 100644 --- a/go.mod +++ b/go.mod @@ -74,8 +74,8 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 - github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 + github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f diff --git a/go.sum b/go.sum index 85fdab9406..75004f3805 100644 --- a/go.sum +++ b/go.sum @@ -1042,10 +1042,10 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 h1:xPEM9XbfZmv8N3NjZ7AX5salonll/LdXrbb8JCbA4FE= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 h1:wqLXuPdiUkn7es/epKmOpB0Q0tKdA9FkYPNQZrZ+VJU= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 h1:/Bx9MUUQ+TfS8kIdER8gujpJWfYu8ft4FYzpH8gSPJY= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= diff --git a/integration-tests/deployment/ccip/add_chain.go b/integration-tests/deployment/ccip/add_chain.go index bc997f0dc5..550d6168a1 100644 --- a/integration-tests/deployment/ccip/add_chain.go +++ b/integration-tests/deployment/ccip/add_chain.go @@ -5,11 +5,15 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/tools/proposal/mcms" "github.com/smartcontractkit/ccip-owner-contracts/tools/proposal/timelock" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-ccip/chainconfig" + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" @@ -22,8 +26,10 @@ func NewChainInboundProposal( e deployment.Environment, state CCIPOnChainState, homeChainSel uint64, + feedChainSel uint64, newChainSel uint64, sources []uint64, + tokenConfig TokenConfig, ) (*timelock.MCMSWithTimelockProposal, error) { // Generate proposal which enables new destination (from test router) on all source chains. var batches []timelock.BatchChainOperation @@ -118,7 +124,14 @@ func NewChainInboundProposal( return nil, err } - newDONArgs, err := BuildAddDONArgs(e.Logger, state.Chains[newChainSel].OffRamp, e.Chains[newChainSel], nodes.NonBootstraps()) + newDONArgs, err := BuildAddDONArgs( + e.Logger, + state.Chains[newChainSel].OffRamp, + e.Chains[newChainSel], + feedChainSel, + tokenConfig.GetTokenInfo(e.Logger, state.Chains[newChainSel]), + nodes.NonBootstraps(), + ) if err != nil { return nil, err } diff --git a/integration-tests/deployment/ccip/add_chain_test.go b/integration-tests/deployment/ccip/add_chain_test.go index 9441f1a2da..dbe86b8536 100644 --- a/integration-tests/deployment/ccip/add_chain_test.go +++ b/integration-tests/deployment/ccip/add_chain_test.go @@ -5,12 +5,18 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -27,9 +33,20 @@ func TestAddChainInbound(t *testing.T) { // We deploy to the rest. initialDeploy := e.Env.AllChainSelectorsExcluding([]uint64{newChain}) + feeds := state.Chains[e.FeedChainSel].USDFeeds + tokenConfig := NewTokenConfig() + tokenConfig.UpsertTokenInfo(LinkSymbol, + pluginconfig.TokenInfo{ + AggregatorAddress: feeds[LinkSymbol].Address().String(), + Decimals: LinkDecimals, + DeviationPPB: cciptypes.NewBigIntFromInt64(1e9), + }, + ) ab, err := DeployCCIPContracts(e.Env, DeployCCIPContractConfig{ HomeChainSel: e.HomeChainSel, + FeedChainSel: e.FeedChainSel, ChainsToDeploy: initialDeploy, + TokenConfig: tokenConfig, CCIPOnChainState: state, }) require.NoError(t, err) @@ -103,7 +120,7 @@ func TestAddChainInbound(t *testing.T) { require.Equal(t, state.Chains[e.HomeChainSel].Timelock.Address(), crOwner) // Generate and sign inbound proposal to new 4th chain. - chainInboundProposal, err := NewChainInboundProposal(e.Env, state, e.HomeChainSel, newChain, initialDeploy) + chainInboundProposal, err := NewChainInboundProposal(e.Env, state, e.HomeChainSel, e.FeedChainSel, newChain, initialDeploy, tokenConfig) require.NoError(t, err) chainInboundExec := SignProposal(t, e.Env, chainInboundProposal) for _, sel := range initialDeploy { @@ -160,4 +177,10 @@ func TestAddChainInbound(t *testing.T) { seqNr := SendRequest(t, e.Env, state, initialDeploy[0], newChain, true) require.NoError(t, ConfirmExecWithSeqNr(t, e.Env.Chains[initialDeploy[0]], e.Env.Chains[newChain], state.Chains[newChain].OffRamp, &startBlock, seqNr)) + + linkAddress := state.Chains[newChain].LinkToken.Address() + feeQuoter := state.Chains[newChain].FeeQuoter + timestampedPrice, err := feeQuoter.GetTokenPrice(nil, linkAddress) + require.NoError(t, err) + require.Equal(t, MockLinkPrice, timestampedPrice.Value) } diff --git a/integration-tests/deployment/ccip/add_lane_test.go b/integration-tests/deployment/ccip/add_lane_test.go index d43526d8d4..3da74ec11a 100644 --- a/integration-tests/deployment/ccip/add_lane_test.go +++ b/integration-tests/deployment/ccip/add_lane_test.go @@ -23,6 +23,8 @@ func TestAddLane(t *testing.T) { // Set up CCIP contracts and a DON per chain. ab, err := DeployCCIPContracts(e.Env, DeployCCIPContractConfig{ HomeChainSel: e.HomeChainSel, + FeedChainSel: e.FeedChainSel, + TokenConfig: NewTokenConfig(), CCIPOnChainState: state, }) require.NoError(t, err) diff --git a/integration-tests/deployment/ccip/changeset/1_cap_reg.go b/integration-tests/deployment/ccip/changeset/1_cap_reg.go index 5863491623..90c1a94fe8 100644 --- a/integration-tests/deployment/ccip/changeset/1_cap_reg.go +++ b/integration-tests/deployment/ccip/changeset/1_cap_reg.go @@ -10,7 +10,7 @@ import ( // Separate migration because cap reg is an env var for CL nodes. func Apply0001(env deployment.Environment, homeChainSel uint64) (deployment.ChangesetOutput, error) { // Note we also deploy the cap reg. - ab, _, err := ccipdeployment.DeployCapReg(env.Logger, env.Chains, homeChainSel) + ab, _, err := ccipdeployment.DeployCapReg(env.Logger, env.Chains[homeChainSel]) if err != nil { env.Logger.Errorw("Failed to deploy cap reg", "err", err, "addresses", ab) return deployment.ChangesetOutput{}, err diff --git a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go index 90a8627f38..8dc363b0cb 100644 --- a/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go +++ b/integration-tests/deployment/ccip/changeset/2_initial_deploy_test.go @@ -3,40 +3,56 @@ package changeset import ( "testing" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" - ccipdeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" + ccdeploy "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip" jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" + "github.com/smartcontractkit/chainlink/v2/core/logger" ) func Test0002_InitialDeploy(t *testing.T) { lggr := logger.TestLogger(t) - ctx := ccipdeployment.Context(t) - tenv := ccipdeployment.NewEnvironmentWithCR(t, lggr, 3) + ctx := ccdeploy.Context(t) + tenv := ccdeploy.NewEnvironmentWithCRAndFeeds(t, lggr, 3) e := tenv.Env nodes := tenv.Nodes chains := e.Chains - state, err := ccipdeployment.LoadOnchainState(tenv.Env, tenv.Ab) + state, err := ccdeploy.LoadOnchainState(tenv.Env, tenv.Ab) require.NoError(t, err) + feeds := state.Chains[tenv.FeedChainSel].USDFeeds + tokenConfig := ccdeploy.NewTokenConfig() + tokenConfig.UpsertTokenInfo(ccdeploy.LinkSymbol, + pluginconfig.TokenInfo{ + AggregatorAddress: feeds[ccdeploy.LinkSymbol].Address().String(), + Decimals: ccdeploy.LinkDecimals, + DeviationPPB: cciptypes.NewBigIntFromInt64(1e9), + }, + ) // Apply migration - output, err := Apply0002(tenv.Env, ccipdeployment.DeployCCIPContractConfig{ + output, err := Apply0002(tenv.Env, ccdeploy.DeployCCIPContractConfig{ HomeChainSel: tenv.HomeChainSel, + FeedChainSel: tenv.FeedChainSel, ChainsToDeploy: tenv.Env.AllChainSelectors(), - // Capreg/config already exist. + TokenConfig: tokenConfig, + // Capreg/config and feeds already exist. CCIPOnChainState: state, }) require.NoError(t, err) // Get new state after migration. - state, err = ccipdeployment.LoadOnchainState(e, output.AddressBook) + state, err = ccdeploy.LoadOnchainState(e, output.AddressBook) require.NoError(t, err) // Ensure capreg logs are up to date. - require.NoError(t, ccipdeployment.ReplayAllLogs(nodes, chains)) + require.NoError(t, ccdeploy.ReplayAllLogs(nodes, chains)) // Apply the jobs. for nodeID, jobs := range output.JobSpecs { @@ -52,7 +68,7 @@ func Test0002_InitialDeploy(t *testing.T) { } // Add all lanes - require.NoError(t, ccipdeployment.AddLanesForAll(e, state)) + require.NoError(t, ccdeploy.AddLanesForAll(e, state)) // Need to keep track of the block number for each chain so that event subscription can be done from that block. startBlocks := make(map[uint64]*uint64) // Send a message from each chain to every other chain. @@ -66,16 +82,25 @@ func Test0002_InitialDeploy(t *testing.T) { require.NoError(t, err) block := latesthdr.Number.Uint64() startBlocks[dest] = &block - seqNum := ccipdeployment.SendRequest(t, e, state, src, dest, false) + seqNum := ccdeploy.SendRequest(t, e, state, src, dest, false) expectedSeqNum[dest] = seqNum } } // Wait for all commit reports to land. - ccipdeployment.ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) + ccdeploy.ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) + + // After commit is reported on all chains, token prices should be updated in FeeQuoter. + for dest := range e.Chains { + linkAddress := state.Chains[dest].LinkToken.Address() + feeQuoter := state.Chains[dest].FeeQuoter + timestampedPrice, err := feeQuoter.GetTokenPrice(nil, linkAddress) + require.NoError(t, err) + require.Equal(t, ccdeploy.MockLinkPrice, timestampedPrice.Value) + } // Wait for all exec reports to land - ccipdeployment.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) + ccdeploy.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) // TODO: Apply the proposal. } diff --git a/integration-tests/deployment/ccip/consts.go b/integration-tests/deployment/ccip/consts.go new file mode 100644 index 0000000000..e9b7a9f2ce --- /dev/null +++ b/integration-tests/deployment/ccip/consts.go @@ -0,0 +1,10 @@ +package ccipdeployment + +type TokenSymbol string + +const ( + LinkSymbol TokenSymbol = "LINK" + WethSymbol TokenSymbol = "WETH" + LinkDecimals = 18 + WethDecimals = 18 +) diff --git a/integration-tests/deployment/ccip/deploy.go b/integration-tests/deployment/ccip/deploy.go index dab50f5820..f0641b6516 100644 --- a/integration-tests/deployment/ccip/deploy.go +++ b/integration-tests/deployment/ccip/deploy.go @@ -10,12 +10,14 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/smartcontractkit/ccip-owner-contracts/tools/configwrappers" owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/tools/gethwrappers" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface" "github.com/smartcontractkit/chainlink/integration-tests/deployment" @@ -48,6 +50,7 @@ var ( OnRamp deployment.ContractType = "OnRamp" OffRamp deployment.ContractType = "OffRamp" CapabilitiesRegistry deployment.ContractType = "CapabilitiesRegistry" + PriceFeed deployment.ContractType = "PriceFeed" // Note test router maps to a regular router contract. TestRouter deployment.ContractType = "TestRouter" CCIPReceiver deployment.ContractType = "CCIPReceiver" @@ -78,7 +81,8 @@ type Contracts interface { *offramp.OffRamp | *onramp.OnRamp | *burn_mint_erc677.BurnMintERC677 | - *maybe_revert_message_receiver.MaybeRevertMessageReceiver + *maybe_revert_message_receiver.MaybeRevertMessageReceiver | + *aggregator_v3_interface.AggregatorV3Interface } type ContractDeploy[C Contracts] struct { @@ -119,7 +123,9 @@ func deployContract[C Contracts]( type DeployCCIPContractConfig struct { HomeChainSel uint64 + FeedChainSel uint64 ChainsToDeploy []uint64 + TokenConfig TokenConfig // Existing contracts which we want to skip deployment // Leave empty if we want to deploy everything // TODO: Add skips to deploy function. @@ -178,6 +184,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( return ab, err } + tokenInfo := c.TokenConfig.GetTokenInfo(e.Logger, chainState) // TODO: Do we want to extract this? // Add chain config for each chain. _, err = AddChainConfig( @@ -196,6 +203,8 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) ( c.Chains[c.HomeChainSel].CapabilityRegistry, c.Chains[c.HomeChainSel].CCIPConfig, chainState.OffRamp, + c.FeedChainSel, + tokenInfo, chain, e.Chains[c.HomeChainSel], nodes.NonBootstraps(), diff --git a/integration-tests/deployment/ccip/deploy_home_chain.go b/integration-tests/deployment/ccip/deploy_home_chain.go index 94da977d6c..c9d3814a67 100644 --- a/integration-tests/deployment/ccip/deploy_home_chain.go +++ b/integration-tests/deployment/ccip/deploy_home_chain.go @@ -9,17 +9,20 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink-ccip/chainconfig" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink/integration-tests/deployment" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" @@ -67,9 +70,8 @@ func MustABIEncode(abiString string, args ...interface{}) []byte { return encoded } -func DeployCapReg(lggr logger.Logger, chains map[uint64]deployment.Chain, chainSel uint64) (deployment.AddressBook, common.Address, error) { +func DeployCapReg(lggr logger.Logger, chain deployment.Chain) (deployment.AddressBook, common.Address, error) { ab := deployment.NewMemoryAddressBook() - chain := chains[chainSel] capReg, err := deployContract(lggr, chain, ab, func(chain deployment.Chain) ContractDeploy[*capabilities_registry.CapabilitiesRegistry] { crAddr, tx, cr, err2 := capabilities_registry.DeployCapabilitiesRegistry( @@ -196,6 +198,9 @@ func BuildAddDONArgs( lggr logger.Logger, offRamp *offramp.OffRamp, dest deployment.Chain, + feedChainSel uint64, + // Token address on Dest chain to aggregate address on feed chain + tokenInfo map[ocrtypes.Account]pluginconfig.TokenInfo, nodes deployment.Nodes, ) ([]byte, error) { p2pIDs := nodes.PeerIDs() @@ -229,11 +234,8 @@ func BuildAddDONArgs( encodedOffchainConfig, err2 = pluginconfig.EncodeCommitOffchainConfig(pluginconfig.CommitOffchainConfig{ RemoteGasPriceBatchWriteFrequency: *commonconfig.MustNewDuration(RemoteGasPriceBatchWriteFrequency), TokenPriceBatchWriteFrequency: *commonconfig.MustNewDuration(TokenPriceBatchWriteFrequency), - // TODO: Use a specific feed chain - // Use homechain as the feed chain to simplify testing - TokenInfo: map[ocrtypes.Account]pluginconfig.TokenInfo{ - //TODO: Add remote chain tokens as keys with their respective aggregate contract on feedChain - }, + PriceFeedChainSelector: ccipocr3.ChainSelector(feedChainSel), + TokenInfo: tokenInfo, }) } else { encodedOffchainConfig, err2 = pluginconfig.EncodeExecuteOffchainConfig(pluginconfig.ExecuteOffchainConfig{ @@ -367,11 +369,14 @@ func AddDON( capReg *capabilities_registry.CapabilitiesRegistry, ccipConfig *ccip_config.CCIPConfig, offRamp *offramp.OffRamp, + feedChainSel uint64, + // Token address on Dest chain to aggregate address on feed chain + tokenInfo map[ocrtypes.Account]pluginconfig.TokenInfo, dest deployment.Chain, home deployment.Chain, nodes deployment.Nodes, ) error { - encodedConfigs, err := BuildAddDONArgs(lggr, offRamp, dest, nodes) + encodedConfigs, err := BuildAddDONArgs(lggr, offRamp, dest, feedChainSel, tokenInfo, nodes) if err != nil { return err } diff --git a/integration-tests/deployment/ccip/deploy_test.go b/integration-tests/deployment/ccip/deploy_test.go index e2963b84a3..db739f6413 100644 --- a/integration-tests/deployment/ccip/deploy_test.go +++ b/integration-tests/deployment/ccip/deploy_test.go @@ -17,19 +17,36 @@ func TestDeployCCIPContracts(t *testing.T) { lggr := logger.TestLogger(t) e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ Bootstraps: 1, - Chains: 1, + Chains: 2, Nodes: 4, }) // Deploy all the CCIP contracts. - homeChain := e.AllChainSelectors()[0] - capRegAddresses, _, err := DeployCapReg(lggr, e.Chains, homeChain) + homeChain := e.AllChainSelectors()[HomeChainIndex] + addressBook, _, err := DeployCapReg(lggr, e.Chains[homeChain]) require.NoError(t, err) - s, err := LoadOnchainState(e, capRegAddresses) + s, err := LoadOnchainState(e, addressBook) require.NoError(t, err) + + feedChain := e.AllChainSelectors()[FeedChainIndex] + feedAddresses, _, err := DeployFeeds(lggr, e.Chains[feedChain]) + require.NoError(t, err) + + // Merge the feed addresses into the address book. + require.NoError(t, addressBook.Merge(feedAddresses)) + + // Load the state after deploying the cap reg and feeds. + homeAndFeedStates, err := LoadOnchainState(e, addressBook) + require.NoError(t, err) + require.NotNil(t, s.Chains[homeChain].CapabilityRegistry) + require.NotNil(t, s.Chains[homeChain].CCIPConfig) + require.NotNil(t, homeAndFeedStates.Chains[feedChain].USDFeeds) + ab, err := DeployCCIPContracts(e, DeployCCIPContractConfig{ HomeChainSel: homeChain, + FeedChainSel: feedChain, ChainsToDeploy: e.AllChainSelectors(), - CCIPOnChainState: s, + TokenConfig: NewTokenConfig(), + CCIPOnChainState: homeAndFeedStates, }) require.NoError(t, err) state, err := LoadOnchainState(e, ab) diff --git a/integration-tests/deployment/ccip/state.go b/integration-tests/deployment/ccip/state.go index 50ed396d9d..d32c51ae65 100644 --- a/integration-tests/deployment/ccip/state.go +++ b/integration-tests/deployment/ccip/state.go @@ -3,19 +3,19 @@ package ccipdeployment import ( "fmt" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink/integration-tests/deployment" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/tools/gethwrappers" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" @@ -24,6 +24,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" ) type CCIPChainState struct { @@ -38,6 +41,15 @@ type CCIPChainState struct { RMNRemote *rmn_remote.RMNRemote // TODO: May need to support older link too LinkToken *burn_mint_erc677.BurnMintERC677 + // Map between token Descriptor (e.g. LinkSymbol, WethSymbol) + // and the respective token contract + // This is more of an illustration of how we'll have tokens, and it might need some work later to work properly. + // Not all tokens will be burn and mint tokens. + BurnMintTokens677 map[TokenSymbol]*burn_mint_erc677.BurnMintERC677 + // Map between token Symbol (e.g. LinkSymbol, WethSymbol) + // and the respective aggregator USD feed contract + USDFeeds map[TokenSymbol]*aggregator_v3_interface.AggregatorV3Interface + // Note we only expect one of these (on the home chain) CapabilityRegistry *capabilities_registry.CapabilitiesRegistry CCIPConfig *ccip_config.CCIPConfig @@ -188,7 +200,7 @@ func LoadOnchainState(e deployment.Environment, ab deployment.AddressBook) (CCIP return state, nil } -// Loads all state for a chain into state +// LoadChainState Loads all state for a chain into state // Modifies map in place func LoadChainState(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (CCIPChainState, error) { var state CCIPChainState @@ -290,6 +302,23 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type return state, err } state.Receiver = mr + case deployment.NewTypeAndVersion(PriceFeed, deployment.Version1_0_0).String(): + feed, err := aggregator_v3_interface.NewAggregatorV3Interface(common.HexToAddress(address), chain.Client) + if err != nil { + return state, err + } + if state.USDFeeds == nil { + state.USDFeeds = make(map[TokenSymbol]*aggregator_v3_interface.AggregatorV3Interface) + } + desc, err := feed.Description(&bind.CallOpts{}) + if err != nil { + return state, err + } + key, ok := MockDescriptionToTokenSymbol[desc] + if !ok { + return state, fmt.Errorf("unknown feed description %s", desc) + } + state.USDFeeds[key] = feed default: return state, fmt.Errorf("unknown contract %s", tvStr) } diff --git a/integration-tests/deployment/ccip/test_assertions.go b/integration-tests/deployment/ccip/test_assertions.go index 02a10fff3e..256d4bf8b6 100644 --- a/integration-tests/deployment/ccip/test_assertions.go +++ b/integration-tests/deployment/ccip/test_assertions.go @@ -115,8 +115,8 @@ func ConfirmCommitWithExpectedSeqNumRange( if mr.SourceChainSelector == src.Selector && uint64(expectedSeqNumRange.Start()) == mr.MinSeqNr && uint64(expectedSeqNumRange.End()) == mr.MaxSeqNr { - t.Logf("Received commit report on selector %d from source selector %d expected seq nr range %s", - dest.Selector, src.Selector, expectedSeqNumRange.String()) + t.Logf("Received commit report on selector %d from source selector %d expected seq nr range %s, token prices: %v", + dest.Selector, src.Selector, expectedSeqNumRange.String(), report.Report.PriceUpdates.TokenPriceUpdates) return nil } } diff --git a/integration-tests/deployment/ccip/test_helpers.go b/integration-tests/deployment/ccip/test_helpers.go index 330cbae196..8f7a7b6c90 100644 --- a/integration-tests/deployment/ccip/test_helpers.go +++ b/integration-tests/deployment/ccip/test_helpers.go @@ -2,6 +2,8 @@ package ccipdeployment import ( "context" + "fmt" + "math/big" "sort" "testing" "time" @@ -11,19 +13,29 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/ethereum/go-ethereum/common" - chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" + + "go.uber.org/multierr" "go.uber.org/zap/zapcore" - jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink/integration-tests/deployment" + jobv1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/job/v1" "github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/integration-tests/deployment/devenv" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_v3_aggregator_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface" +) + +const ( + HomeChainIndex = 0 + FeedChainIndex = 1 ) // Context returns a context with the test's deadline, if available. @@ -47,12 +59,14 @@ type DeployedTestEnvironment struct { Ab deployment.AddressBook Env deployment.Environment HomeChainSel uint64 + FeedChainSel uint64 Nodes map[string]memory.Node } -// NewDeployedEnvironment creates a new CCIP environment -// with capreg and nodes set up. -func NewEnvironmentWithCR(t *testing.T, lggr logger.Logger, numChains int) DeployedTestEnvironment { +// NewEnvironmentWithCRAndFeeds creates a new CCIP environment +// with capreg, feeds and nodes set up. +func NewEnvironmentWithCRAndFeeds(t *testing.T, lggr logger.Logger, numChains int) DeployedTestEnvironment { + require.GreaterOrEqual(t, numChains, 2, "numChains must be at least 2 for home and feed chains") ctx := Context(t) chains := memory.NewMemoryChains(t, numChains) // Lower chainSel is home chain. @@ -65,10 +79,15 @@ func NewEnvironmentWithCR(t *testing.T, lggr logger.Logger, numChains int) Deplo return chainSels[i] < chainSels[j] }) // Take lowest for determinism. - homeChainSel := chainSels[0] + homeChainSel := chainSels[HomeChainIndex] homeChainEVM, _ := chainsel.ChainIdFromSelector(homeChainSel) - ab, capReg, err := DeployCapReg(lggr, chains, homeChainSel) + ab, capReg, err := DeployCapReg(lggr, chains[homeChainSel]) + require.NoError(t, err) + + feedSel := chainSels[FeedChainIndex] + feedAb, _, err := DeployFeeds(lggr, chains[feedSel]) require.NoError(t, err) + require.NoError(t, ab.Merge(feedAb)) nodes := memory.NewNodes(t, zapcore.InfoLevel, chains, 4, 1, deployment.CapabilityRegistryConfig{ EVMChainID: homeChainEVM, @@ -86,13 +105,14 @@ func NewEnvironmentWithCR(t *testing.T, lggr logger.Logger, numChains int) Deplo Ab: ab, Env: e, HomeChainSel: homeChainSel, + FeedChainSel: feedSel, Nodes: nodes, } } func NewEnvironmentWithCRAndJobs(t *testing.T, lggr logger.Logger, numChains int) DeployedTestEnvironment { ctx := Context(t) - e := NewEnvironmentWithCR(t, lggr, numChains) + e := NewEnvironmentWithCRAndFeeds(t, lggr, numChains) jbs, err := NewCCIPJobSpecs(e.Env.NodeIDs, e.Env.Offchain) require.NoError(t, err) for nodeID, jobs := range jbs { @@ -191,7 +211,7 @@ func NewDeployedLocalDevEnvironment(t *testing.T, lggr logger.Logger) DeployedLo require.NotEmpty(t, homeChainEVM, "homeChainEVM should not be empty") // deploy the capability registry - ab, capReg, err := DeployCapReg(lggr, chains, homeChainSel) + ab, capReg, err := DeployCapReg(lggr, chains[homeChainSel]) require.NoError(t, err) // start the chainlink nodes with the CR address @@ -233,3 +253,65 @@ func AddLanesForAll(e deployment.Environment, state CCIPOnChainState) error { } return nil } + +const ( + // MockLinkAggregatorDescription This is the description of the MockV3Aggregator.sol contract + // nolint:lll + // https://github.com/smartcontractkit/chainlink/blob/a348b98e90527520049c580000a86fb8ceff7fa7/contracts/src/v0.8/tests/MockV3Aggregator.sol#L76-L76 + MockLinkAggregatorDescription = "v0.8/tests/MockV3Aggregator.sol" + // MockWETHAggregatorDescription WETH use description from MockETHUSDAggregator.sol + // nolint:lll + // https://github.com/smartcontractkit/chainlink/blob/a348b98e90527520049c580000a86fb8ceff7fa7/contracts/src/v0.8/automation/testhelpers/MockETHUSDAggregator.sol#L19-L19 + MockWETHAggregatorDescription = "MockETHUSDAggregator" +) + +var ( + MockLinkPrice = big.NewInt(5e18) + // MockDescriptionToTokenSymbol maps a mock feed description to token descriptor + MockDescriptionToTokenSymbol = map[string]TokenSymbol{ + MockLinkAggregatorDescription: LinkSymbol, + MockWETHAggregatorDescription: WethSymbol, + } +) + +func DeployFeeds(lggr logger.Logger, chain deployment.Chain) (deployment.AddressBook, map[string]common.Address, error) { + ab := deployment.NewMemoryAddressBook() + linkTV := deployment.NewTypeAndVersion(PriceFeed, deployment.Version1_0_0) + mockLinkFeed, err := deployContract(lggr, chain, ab, + func(chain deployment.Chain) ContractDeploy[*aggregator_v3_interface.AggregatorV3Interface] { + linkFeed, tx, _, err1 := mock_v3_aggregator_contract.DeployMockV3Aggregator( + chain.DeployerKey, + chain.Client, + LinkDecimals, // decimals + MockLinkPrice, // initialAnswer + ) + aggregatorCr, err2 := aggregator_v3_interface.NewAggregatorV3Interface(linkFeed, chain.Client) + + return ContractDeploy[*aggregator_v3_interface.AggregatorV3Interface]{ + Address: linkFeed, Contract: aggregatorCr, Tv: linkTV, Tx: tx, Err: multierr.Append(err1, err2), + } + }) + + if err != nil { + lggr.Errorw("Failed to deploy link feed", "err", err) + return ab, nil, err + } + + lggr.Infow("deployed mockLinkFeed", "addr", mockLinkFeed.Address) + + desc, err := mockLinkFeed.Contract.Description(&bind.CallOpts{}) + if err != nil { + lggr.Errorw("Failed to get description", "err", err) + return ab, nil, err + } + + if desc != MockLinkAggregatorDescription { + lggr.Errorw("Unexpected description for Link token", "desc", desc) + return ab, nil, fmt.Errorf("unexpected description: %s", desc) + } + + tvToAddress := map[string]common.Address{ + desc: mockLinkFeed.Address, + } + return ab, tvToAddress, nil +} diff --git a/integration-tests/deployment/ccip/token_info.go b/integration-tests/deployment/ccip/token_info.go new file mode 100644 index 0000000000..1ea09949bc --- /dev/null +++ b/integration-tests/deployment/ccip/token_info.go @@ -0,0 +1,47 @@ +package ccipdeployment + +import ( + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" +) + +// TokenConfig mapping between token Symbol (e.g. LinkSymbol, WethSymbol) +// and the respective token info. +type TokenConfig struct { + TokenSymbolToInfo map[TokenSymbol]pluginconfig.TokenInfo +} + +func NewTokenConfig() TokenConfig { + return TokenConfig{ + TokenSymbolToInfo: make(map[TokenSymbol]pluginconfig.TokenInfo), + } +} + +func (tc *TokenConfig) UpsertTokenInfo( + symbol TokenSymbol, + info pluginconfig.TokenInfo, +) { + tc.TokenSymbolToInfo[symbol] = info +} + +// GetTokenInfo Adds mapping between dest chain tokens and their respective aggregators on feed chain. +func (tc *TokenConfig) GetTokenInfo( + lggr logger.Logger, + destState CCIPChainState, +) map[ocrtypes.Account]pluginconfig.TokenInfo { + tokenToAggregate := make(map[ocrtypes.Account]pluginconfig.TokenInfo) + if _, ok := tc.TokenSymbolToInfo[LinkSymbol]; !ok { + lggr.Debugw("Link aggregator not found, deploy without mapping link token") + } else { + lggr.Debugw("Mapping LinkToken to Link aggregator") + acc := ocrtypes.Account(destState.LinkToken.Address().String()) + tokenToAggregate[acc] = tc.TokenSymbolToInfo[LinkSymbol] + } + + // TODO: Populate tokenInfo with weth and the token map in destState + + return tokenToAggregate +} diff --git a/integration-tests/go.mod b/integration-tests/go.mod index d7d460801a..e673e559bc 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -39,8 +39,8 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240910151738-3f318badcfb5 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 - github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 + github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 20a28e1dfb..ee802182c1 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1423,10 +1423,10 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 h1:xPEM9XbfZmv8N3NjZ7AX5salonll/LdXrbb8JCbA4FE= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 h1:wqLXuPdiUkn7es/epKmOpB0Q0tKdA9FkYPNQZrZ+VJU= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 h1:/Bx9MUUQ+TfS8kIdER8gujpJWfYu8ft4FYzpH8gSPJY= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 67d2bb6509..90eeea63f4 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -15,7 +15,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 - github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 + github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 @@ -386,7 +386,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 0954d5afd7..37fa4cadda 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1397,10 +1397,10 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612 h1:xPEM9XbfZmv8N3NjZ7AX5salonll/LdXrbb8JCbA4FE= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240917180332-5a68498d1612/go.mod h1:Lv77O13ZxOdmlvnu2vaUC0Lg+t3JAL+N+9K8dRsgmDI= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06 h1:wqLXuPdiUkn7es/epKmOpB0Q0tKdA9FkYPNQZrZ+VJU= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240918210534-564164004d06/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 h1:/Bx9MUUQ+TfS8kIdER8gujpJWfYu8ft4FYzpH8gSPJY= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= From d2d9568318abe0ce88bc12a1308e0e96131b0223 Mon Sep 17 00:00:00 2001 From: martin-cll <121895364+martin-cll@users.noreply.github.com> Date: Sat, 21 Sep 2024 02:18:56 +1000 Subject: [PATCH 391/432] MERC-6299 Skip telemetry for market status bridges (#14415) * Skip telemetry for market status bridges * Update changeset * Remove field --- .changeset/slow-lizards-shout.md | 5 + core/services/ocrcommon/telemetry.go | 45 ++++-- core/services/ocrcommon/telemetry_test.go | 142 +++++++++++++++++- .../telem/telem_enhanced_ea_mercury.pb.go | 2 +- .../telem/telem_enhanced_ea_mercury.proto | 2 +- 5 files changed, 174 insertions(+), 22 deletions(-) create mode 100644 .changeset/slow-lizards-shout.md diff --git a/.changeset/slow-lizards-shout.md b/.changeset/slow-lizards-shout.md new file mode 100644 index 0000000000..3b21c6576e --- /dev/null +++ b/.changeset/slow-lizards-shout.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Skip telemetry for market-status bridges #internal diff --git a/core/services/ocrcommon/telemetry.go b/core/services/ocrcommon/telemetry.go index f146bacc18..810952f455 100644 --- a/core/services/ocrcommon/telemetry.go +++ b/core/services/ocrcommon/telemetry.go @@ -174,7 +174,14 @@ func ParseMercuryEATelemetry(lggr logger.Logger, trrs pipeline.TaskRunResults, f eaTelem.BridgeTaskRunStartedTimestamp = trr.CreatedAt.UnixMilli() eaTelem.BridgeTaskRunEndedTimestamp = trr.FinishedAt.Time.UnixMilli() - eaTelem.AssetSymbol = getAssetSymbolFromRequestData(bridgeTask.RequestData) + + parsedBridgeData := parseBridgeRequestData(bridgeTask.RequestData, feedVersion) + if parsedBridgeData.IsMarketStatus { + // Only collect telemetry for pricing bridges. + continue + } + + eaTelem.AssetSymbol = parsedBridgeData.AssetSymbol eaTelemetryValues = append(eaTelemetryValues, eaTelem) } @@ -477,12 +484,19 @@ func parseTelemetryAttributes(a string) (telemetryAttributes, error) { return *attrs, nil } -// getAssetSymbolFromRequestData parses the requestData of the bridge to generate an asset symbol pair -func getAssetSymbolFromRequestData(requestData string) string { +type bridgeRequestData struct { + AssetSymbol string + IsMarketStatus bool +} + +// parseRequestData parses the requestData of the bridge. +func parseBridgeRequestData(requestData string, mercuryVersion mercuryutils.FeedVersion) bridgeRequestData { type reqDataPayload struct { - To *string `json:"to"` - From *string `json:"from"` - Address *string `json:"address"` // used for view function ea only + Endpoint *string `json:"endpoint"` + To *string `json:"to"` + From *string `json:"from"` + Address *string `json:"address"` // used for view function ea only + Market *string `json:"market"` // used for market status ea only } type reqData struct { Data reqDataPayload `json:"data"` @@ -491,18 +505,25 @@ func getAssetSymbolFromRequestData(requestData string) string { rd := &reqData{} err := json.Unmarshal([]byte(requestData), rd) if err != nil { - return "" + return bridgeRequestData{} + } + + if mercuryVersion == 4 && ((rd.Data.Endpoint != nil && *rd.Data.Endpoint == "market-status") || (rd.Data.Market != nil && *rd.Data.Market != "")) { + return bridgeRequestData{ + AssetSymbol: *rd.Data.Market, + IsMarketStatus: true, + } } if rd.Data.From != nil && rd.Data.To != nil { - return *rd.Data.From + "/" + *rd.Data.To + return bridgeRequestData{AssetSymbol: *rd.Data.From + "/" + *rd.Data.To} } if rd.Data.Address != nil { - return *rd.Data.Address + return bridgeRequestData{AssetSymbol: *rd.Data.Address} } - return "" + return bridgeRequestData{} } // ShouldCollectEnhancedTelemetryMercury checks if enhanced telemetry should be collected and sent @@ -616,8 +637,8 @@ func getPricesFromResultsByOrder(lggr logger.Logger, startTask pipeline.TaskRunR benchmarkPrice = parsePriceFromTask(lggr, *benchmarkPriceTask) } - // mercury version 2 only supports benchmarkPrice - if mercuryVersion == 2 { + // mercury versions 2 and 4 only supports benchmarkPrice + if mercuryVersion == 2 || mercuryVersion == 4 { return benchmarkPrice, 0, 0 } diff --git a/core/services/ocrcommon/telemetry_test.go b/core/services/ocrcommon/telemetry_test.go index 631cc32ed0..ed64e45c2d 100644 --- a/core/services/ocrcommon/telemetry_test.go +++ b/core/services/ocrcommon/telemetry_test.go @@ -7,19 +7,18 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/shopspring/decimal" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.uber.org/zap" "google.golang.org/protobuf/proto" - "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" mercuryv1 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1" mercuryv2 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" - + mercuryv4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" @@ -274,7 +273,6 @@ func TestSendEATelemetry(t *testing.T) { expectedMessage, _ := proto.Marshal(&expectedTelemetry) wg.Wait() assert.Equal(t, expectedMessage, sentMessage) - //enhancedTelemService.StopOnce("EnhancedTelemetryService", func() error { return nil }) doneCh <- struct{}{} } @@ -446,6 +444,45 @@ var trrsMercuryV2 = pipeline.TaskRunResults{ }, } +var trrsMercuryV4 = pipeline.TaskRunResults{ + pipeline.TaskRunResult{ + Task: &pipeline.BridgeTask{ + Name: "link-usd-test-bridge-v2", + BaseTask: pipeline.NewBaseTask(0, "ds1", nil, nil, 0), + RequestData: `{"data":{"to":"LINK","from":"USD"}}`, + }, + Result: pipeline.Result{ + Value: bridgeResponse, + }, + }, + pipeline.TaskRunResult{ + Task: &pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(1, "ds1_benchmark", nil, nil, 1), + }, + Result: pipeline.Result{ + Value: 123456.123456, + }, + }, + pipeline.TaskRunResult{ + Task: &pipeline.BridgeTask{ + Name: "market-status-bridge", + BaseTask: pipeline.NewBaseTask(2, "ds2", nil, nil, 2), + RequestData: `{"data":{"endpoint":"market-status","market":"forex"}}`, + }, + Result: pipeline.Result{ + Value: bridgeResponse, + }, + }, + pipeline.TaskRunResult{ + Task: &pipeline.JSONParseTask{ + BaseTask: pipeline.NewBaseTask(3, "market_status", nil, nil, 3), + }, + Result: pipeline.Result{ + Value: 2.0, + }, + }, +} + func TestGetPricesFromBridgeByTelemetryField(t *testing.T) { lggr, _ := logger.TestLoggerObserved(t, zap.WarnLevel) // These are intentionally out of order from the "legacy" method which expects order of `benchmark, bid, ask` @@ -605,12 +642,23 @@ func TestShouldCollectEnhancedTelemetryMercury(t *testing.T) { require.Equal(t, ShouldCollectEnhancedTelemetryMercury(j), false) } -func TestGetAssetSymbolFromRequestData(t *testing.T) { - require.Equal(t, getAssetSymbolFromRequestData(""), "") +func TestParseBridgeRequestData(t *testing.T) { + require.Equal(t, parseBridgeRequestData("", 2), bridgeRequestData{}) + reqData := `{"data":{"to":"LINK","from":"USD"}}` - require.Equal(t, getAssetSymbolFromRequestData(reqData), "USD/LINK") + require.Equal(t, parseBridgeRequestData(reqData, 2), bridgeRequestData{AssetSymbol: "USD/LINK"}) + + reqData = `{"data":{"to":"LINK","from":"USD","market":"forex"}}` + require.Equal(t, parseBridgeRequestData(reqData, 2), bridgeRequestData{AssetSymbol: "USD/LINK"}) + + reqData = `{"data":{"endpoint":"market-status","market":"forex"}}` + require.Equal(t, parseBridgeRequestData(reqData, 4), bridgeRequestData{AssetSymbol: "forex", IsMarketStatus: true}) + + reqData = `{"data":{"market":"metals"}}` + require.Equal(t, parseBridgeRequestData(reqData, 4), bridgeRequestData{AssetSymbol: "metals", IsMarketStatus: true}) + viewFunctionReqData := `{"data":{"address":"0x12345678", "signature": "function stEthPerToken() view returns (int256)"}}` - require.Equal(t, "0x12345678", getAssetSymbolFromRequestData(viewFunctionReqData)) + require.Equal(t, parseBridgeRequestData(viewFunctionReqData, 3), bridgeRequestData{AssetSymbol: "0x12345678"}) } func getViewFunctionTaskRunResults() pipeline.TaskRunResults { @@ -1005,3 +1053,81 @@ func TestCollectMercuryEnhancedTelemetryV2(t *testing.T) { require.Contains(t, logs.All()[3].Message, "cannot parse enhanced EA telemetry bid price") chDone <- struct{}{} } + +func TestCollectMercuryEnhancedTelemetryV4(t *testing.T) { + ingressClient := mocks.NewTelemetryService(t) + ingressAgent := telemetry.NewIngressAgentWrapper(ingressClient) + monitoringEndpoint := ingressAgent.GenMonitoringEndpoint("test-network", "test-chainID", "0xa", synchronization.EnhancedEAMercury) + + sentMessageCh := make(chan []byte) + ingressClient.On("Send", mock.Anything, mock.AnythingOfType("[]uint8"), mock.AnythingOfType("string"), mock.AnythingOfType("TelemetryType")).Return().Run(func(args mock.Arguments) { + sentMessageCh <- args[1].([]byte) + }) + + lggr, _ := logger.TestLoggerObserved(t, zap.WarnLevel) + chTelem := make(chan EnhancedTelemetryMercuryData, 100) + chDone := make(chan struct{}) + feedID := common.HexToHash("0x0004") + e := EnhancedTelemetryService[EnhancedTelemetryMercuryData]{ + chDone: chDone, + chTelem: chTelem, + job: &job.Job{ + Type: job.Type(pipeline.OffchainReporting2JobType), + OCR2OracleSpec: &job.OCR2OracleSpec{ + CaptureEATelemetry: true, + FeedID: &feedID, + }, + }, + lggr: lggr, + monitoringEndpoint: monitoringEndpoint, + } + servicetest.Run(t, &e) + + chTelem <- EnhancedTelemetryMercuryData{ + TaskRunResults: trrsMercuryV4, + FeedVersion: 4, + V4Observation: &mercuryv4.Observation{ + BenchmarkPrice: mercury.ObsResult[*big.Int]{Val: big.NewInt(111111)}, + MarketStatus: mercury.ObsResult[uint32]{Val: 2}, + MaxFinalizedTimestamp: mercury.ObsResult[int64]{Val: 321}, + LinkPrice: mercury.ObsResult[*big.Int]{Val: big.NewInt(4321)}, + NativePrice: mercury.ObsResult[*big.Int]{Val: big.NewInt(54321)}, + }, + RepTimestamp: types.ReportTimestamp{ + ConfigDigest: types.ConfigDigest{2}, + Epoch: 11, + Round: 22, + }, + } + + expectedPricingTelemetry := telem.EnhancedEAMercury{ + DataSource: "data-source-name", + DpBenchmarkPrice: 123456.123456, + BridgeTaskRunStartedTimestamp: trrsMercuryV4[0].CreatedAt.UnixMilli(), + BridgeTaskRunEndedTimestamp: trrsMercuryV4[0].FinishedAt.Time.UnixMilli(), + ProviderRequestedTimestamp: 92233720368547760, + ProviderReceivedTimestamp: -92233720368547760, + ProviderDataStreamEstablished: 1, + ProviderIndicatedTime: -123456789, + Feed: common.HexToHash("0x0004").String(), + ObservationBenchmarkPrice: 111111, + ObservationMarketStatus: 2, + ConfigDigest: "0200000000000000000000000000000000000000000000000000000000000000", + Round: 22, + Epoch: 11, + AssetSymbol: "USD/LINK", + ObservationBenchmarkPriceString: "111111", + MaxFinalizedTimestamp: 321, + LinkPrice: 4321, + NativePrice: 54321, + Version: 4, + BridgeRequestData: `{"data":{"to":"LINK","from":"USD"}}`, + } + expectedPricingMessage, _ := proto.Marshal(&expectedPricingTelemetry) + require.Equal(t, expectedPricingMessage, <-sentMessageCh) + + chDone <- struct{}{} + + // Verify that no other telemetry is sent. + require.Len(t, sentMessageCh, 0) +} diff --git a/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go b/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go index 7be7ad8d70..09eed12ee8 100644 --- a/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go +++ b/core/services/synchronization/telem/telem_enhanced_ea_mercury.pb.go @@ -101,7 +101,7 @@ type EnhancedEAMercury struct { ProviderDataStreamEstablished int64 `protobuf:"varint,12,opt,name=provider_data_stream_established,json=providerDataStreamEstablished,proto3" json:"provider_data_stream_established,omitempty"` ProviderIndicatedTime int64 `protobuf:"varint,13,opt,name=provider_indicated_time,json=providerIndicatedTime,proto3" json:"provider_indicated_time,omitempty"` Feed string `protobuf:"bytes,14,opt,name=feed,proto3" json:"feed,omitempty"` - // v1+v2+v3 + // v1+v2+v3+v4 ObservationBenchmarkPrice int64 `protobuf:"varint,15,opt,name=observation_benchmark_price,json=observationBenchmarkPrice,proto3" json:"observation_benchmark_price,omitempty"` // This value overflows, will be reserved and removed in future versions ObservationBenchmarkPriceString string `protobuf:"bytes,22,opt,name=observation_benchmark_price_string,json=observationBenchmarkPriceString,proto3" json:"observation_benchmark_price_string,omitempty"` // v1+v3 diff --git a/core/services/synchronization/telem/telem_enhanced_ea_mercury.proto b/core/services/synchronization/telem/telem_enhanced_ea_mercury.proto index c96c58f9ea..d57b7ca836 100644 --- a/core/services/synchronization/telem/telem_enhanced_ea_mercury.proto +++ b/core/services/synchronization/telem/telem_enhanced_ea_mercury.proto @@ -44,7 +44,7 @@ message EnhancedEAMercury { string feed=14; - // v1+v2+v3 + // v1+v2+v3+v4 int64 observation_benchmark_price=15; // This value overflows, will be reserved and removed in future versions string observation_benchmark_price_string = 22; // v1+v3 From 4f9ed6404beb1272287955a71d7fe22490a64d28 Mon Sep 17 00:00:00 2001 From: momentmaker Date: Fri, 20 Sep 2024 11:29:40 -0500 Subject: [PATCH 392/432] add ccip goreleaser build (#14439) * CCIP configs * Better directory structure * Fixes * Fixes * Fixes * add ccip goreleaser build * remove matrix.build and fix dockerfile for copy ccip/config dir * try again with [g] * another try * update build-publish for ccip prod * comment test * revert comment * remove ccip.Dockerfile --------- Co-authored-by: Mateusz Sekara Co-authored-by: Mateusz Sekara --- .../workflows/build-publish-develop-pr.yml | 24 +- .github/workflows/build-publish.yml | 32 ++- .goreleaser.ccip.develop.yaml | 229 ++++++++++++++++++ .goreleaser.ccip.production.yaml | 229 ++++++++++++++++++ GNUmakefile | 10 + ccip/config/README.md | 10 + ccip/config/evm/Arbitrum_Mainnet.toml | 29 +++ ccip/config/evm/Arbitrum_Sepolia.toml | 27 +++ ccip/config/evm/Astar_Mainnet.toml | 9 + ccip/config/evm/Astar_Shibuya.toml | 9 + ccip/config/evm/Avalanche_ANZ_testnet.toml | 19 ++ ccip/config/evm/Avalanche_Fuji.toml | 21 ++ ccip/config/evm/Avalanche_Mainnet.toml | 19 ++ ccip/config/evm/BSC_Mainnet.toml | 28 +++ ccip/config/evm/BSC_Testnet.toml | 33 +++ ccip/config/evm/Base_Mainnet.toml | 31 +++ ccip/config/evm/Base_Sepolia.toml | 32 +++ ccip/config/evm/Blast_Mainnet.toml | 34 +++ ccip/config/evm/Blast_Sepolia.toml | 34 +++ ccip/config/evm/Celo_Mainnet.toml | 20 ++ ccip/config/evm/Celo_Testnet.toml | 20 ++ ccip/config/evm/Ethereum_Mainnet.toml | 17 ++ ccip/config/evm/Ethereum_Sepolia.toml | 17 ++ ccip/config/evm/Fantom_Mainnet.toml | 12 + ccip/config/evm/Fantom_Testnet.toml | 12 + ccip/config/evm/Gnosis_Chiado.toml | 10 + ccip/config/evm/Gnosis_Mainnet.toml | 18 ++ ccip/config/evm/Kroma_Mainnet.toml | 27 +++ ccip/config/evm/Kroma_Sepolia.toml | 27 +++ ccip/config/evm/L3X_Mainnet.toml | 18 ++ ccip/config/evm/L3X_Sepolia.toml | 18 ++ ccip/config/evm/Linea_Mainnet.toml | 17 ++ ccip/config/evm/Linea_Sepolia.toml | 13 + ccip/config/evm/Mantle_Sepolia.toml | 19 ++ ccip/config/evm/Metis_Mainnet.toml | 21 ++ ccip/config/evm/Metis_Sepolia.toml | 17 ++ ccip/config/evm/Mode_Mainnet.toml | 30 +++ ccip/config/evm/Mode_Sepolia.toml | 30 +++ ccip/config/evm/OKX_Mainnet.toml | 1 + ccip/config/evm/OKX_Testnet.toml | 1 + ccip/config/evm/Optimism_Mainnet.toml | 32 +++ ccip/config/evm/Optimism_Sepolia.toml | 31 +++ ccip/config/evm/Polygon_Amoy.toml | 28 +++ ccip/config/evm/Polygon_Mainnet.toml | 38 +++ ccip/config/evm/Polygon_Zkevm_Cardona.toml | 24 ++ ccip/config/evm/Polygon_Zkevm_Mainnet.toml | 26 ++ ccip/config/evm/Scroll_Mainnet.toml | 22 ++ ccip/config/evm/Scroll_Sepolia.toml | 22 ++ ccip/config/evm/Simulated.toml | 24 ++ ccip/config/evm/WeMix_Mainnet.toml | 16 ++ ccip/config/evm/WeMix_Testnet.toml | 19 ++ ccip/config/evm/XLayer_Mainnet.toml | 25 ++ ccip/config/evm/XLayer_Sepolia.toml | 25 ++ ccip/config/evm/zkSync_Mainnet.toml | 28 +++ ccip/config/evm/zkSync_Sepolia.toml | 28 +++ core/chainlink.goreleaser.Dockerfile | 5 + 56 files changed, 1596 insertions(+), 21 deletions(-) create mode 100644 .goreleaser.ccip.develop.yaml create mode 100644 .goreleaser.ccip.production.yaml create mode 100644 ccip/config/README.md create mode 100644 ccip/config/evm/Arbitrum_Mainnet.toml create mode 100644 ccip/config/evm/Arbitrum_Sepolia.toml create mode 100644 ccip/config/evm/Astar_Mainnet.toml create mode 100644 ccip/config/evm/Astar_Shibuya.toml create mode 100644 ccip/config/evm/Avalanche_ANZ_testnet.toml create mode 100644 ccip/config/evm/Avalanche_Fuji.toml create mode 100644 ccip/config/evm/Avalanche_Mainnet.toml create mode 100644 ccip/config/evm/BSC_Mainnet.toml create mode 100644 ccip/config/evm/BSC_Testnet.toml create mode 100644 ccip/config/evm/Base_Mainnet.toml create mode 100644 ccip/config/evm/Base_Sepolia.toml create mode 100644 ccip/config/evm/Blast_Mainnet.toml create mode 100644 ccip/config/evm/Blast_Sepolia.toml create mode 100644 ccip/config/evm/Celo_Mainnet.toml create mode 100644 ccip/config/evm/Celo_Testnet.toml create mode 100644 ccip/config/evm/Ethereum_Mainnet.toml create mode 100644 ccip/config/evm/Ethereum_Sepolia.toml create mode 100644 ccip/config/evm/Fantom_Mainnet.toml create mode 100644 ccip/config/evm/Fantom_Testnet.toml create mode 100644 ccip/config/evm/Gnosis_Chiado.toml create mode 100644 ccip/config/evm/Gnosis_Mainnet.toml create mode 100644 ccip/config/evm/Kroma_Mainnet.toml create mode 100644 ccip/config/evm/Kroma_Sepolia.toml create mode 100644 ccip/config/evm/L3X_Mainnet.toml create mode 100644 ccip/config/evm/L3X_Sepolia.toml create mode 100644 ccip/config/evm/Linea_Mainnet.toml create mode 100644 ccip/config/evm/Linea_Sepolia.toml create mode 100644 ccip/config/evm/Mantle_Sepolia.toml create mode 100644 ccip/config/evm/Metis_Mainnet.toml create mode 100644 ccip/config/evm/Metis_Sepolia.toml create mode 100644 ccip/config/evm/Mode_Mainnet.toml create mode 100644 ccip/config/evm/Mode_Sepolia.toml create mode 100644 ccip/config/evm/OKX_Mainnet.toml create mode 100644 ccip/config/evm/OKX_Testnet.toml create mode 100644 ccip/config/evm/Optimism_Mainnet.toml create mode 100644 ccip/config/evm/Optimism_Sepolia.toml create mode 100644 ccip/config/evm/Polygon_Amoy.toml create mode 100644 ccip/config/evm/Polygon_Mainnet.toml create mode 100644 ccip/config/evm/Polygon_Zkevm_Cardona.toml create mode 100644 ccip/config/evm/Polygon_Zkevm_Mainnet.toml create mode 100644 ccip/config/evm/Scroll_Mainnet.toml create mode 100644 ccip/config/evm/Scroll_Sepolia.toml create mode 100644 ccip/config/evm/Simulated.toml create mode 100644 ccip/config/evm/WeMix_Mainnet.toml create mode 100644 ccip/config/evm/WeMix_Testnet.toml create mode 100644 ccip/config/evm/XLayer_Mainnet.toml create mode 100644 ccip/config/evm/XLayer_Sepolia.toml create mode 100644 ccip/config/evm/zkSync_Mainnet.toml create mode 100644 ccip/config/evm/zkSync_Sepolia.toml diff --git a/.github/workflows/build-publish-develop-pr.yml b/.github/workflows/build-publish-develop-pr.yml index 3a05078d3e..2868616ace 100644 --- a/.github/workflows/build-publish-develop-pr.yml +++ b/.github/workflows/build-publish-develop-pr.yml @@ -21,6 +21,15 @@ env: jobs: goreleaser-build-publish-chainlink: + name: "goreleaser-build-publish-${{ matrix.image-name }}" + strategy: + fail-fast: false + matrix: + include: + - image-name: chainlink + goreleaser-config: .goreleaser.develop.yaml + - image-name: ccip + goreleaser-config: .goreleaser.ccip.develop.yaml runs-on: ubuntu-20.04 permissions: id-token: write @@ -68,18 +77,18 @@ jobs: role-to-assume: ${{ secrets.AWS_OIDC_IAM_ROLE_BUILD_PUBLISH_DEVELOP_PR }} aws-region: ${{ secrets.AWS_REGION }} mask-aws-account-id: true - role-session-name: goreleaser-build-publish-chainlink + role-session-name: goreleaser-build-publish-${{ matrix.image-name }} - name: Build and publish images uses: ./.github/actions/goreleaser-build-sign-publish with: enable-docker-publish: ${{ steps.get-image-tag.outputs.build-publish }} docker-registry: ${{ secrets.AWS_SDLC_ECR_HOSTNAME }} - docker-image-name: chainlink + docker-image-name: ${{ matrix.image-name }} docker-image-tag: ${{ steps.get-image-tag.outputs.image-tag }} enable-goreleaser-snapshot: "true" goreleaser-exec: ./tools/bin/goreleaser_wrapper - goreleaser-config: .goreleaser.develop.yaml + goreleaser-config: ${{ matrix.goreleaser-config }} goreleaser-key: ${{ secrets.GORELEASER_KEY }} zig-version: 0.11.0 @@ -87,13 +96,6 @@ jobs: if: steps.get-image-tag.outputs.build-publish == 'true' shell: bash run: | - # need to check if artifacts.json exists because goreleaser could split the build - if [[ -f dist/artifacts.json ]]; then - artifact_path="dist/artifacts.json" - else - artifact_path="dist/linux_${{ matrix.goarch }}/artifacts.json" - cat dist/linux_${{ matrix.goarch }}/artifacts.json - fi echo "### Docker Images" | tee -a "$GITHUB_STEP_SUMMARY" jq -r '.[] | select(.type == "Docker Image") | "\(.name)"' ${artifact_path} >> output.txt while read -r line; do @@ -109,5 +111,5 @@ jobs: org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: goreleaser-build-publish-chainlink + this-job-name: goreleaser-build-publish-${{ matrix.image-name }} continue-on-error: true \ No newline at end of file diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index ba274730bf..ca6a2d5275 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -98,15 +98,27 @@ jobs: mask-aws-account-id: true role-session-name: goreleaser-build-sign-publish-chainlink + - name: Set build configs + shell: bash + id: set-build-configs + run: | + if [[ ${{ github.ref_name }} =~ "-ccip" ]]; then + echo "ECR_IMAGE_NAME=chainlink/ccip" | tee -a $GITHUB_OUTPUT + echo "GORELEASER_CONFIG=.goreleaser.ccip.production.yaml" | tee -a $GITHUB_OUTPUT + else + echo "ECR_IMAGE_NAME=chainlink/chainlink" | tee -a $GITHUB_OUTPUT + echo "GORELEASER_CONFIG=.goreleaser.production.yaml" | tee -a $GITHUB_OUTPUT + fi + - name: Build, sign, and publish image id: goreleaser-build-sign-publish uses: ./.github/actions/goreleaser-build-sign-publish with: docker-registry: ${{ env.ECR_HOSTNAME}} - docker-image-name: ${{ env.ECR_IMAGE_NAME }} + docker-image-name: ${{ steps.set-build-configs.outputs.ECR_IMAGE_NAME }} docker-image-tag: ${{ github.ref_name }} goreleaser-exec: ./tools/bin/goreleaser_wrapper - goreleaser-config: .goreleaser.production.yaml + goreleaser-config: ${{ steps.set-build-configs.outputs.GORELEASER_CONFIG }} goreleaser-key: ${{ secrets.GORELEASER_KEY }} zig-version: 0.11.0 enable-cosign: true @@ -124,10 +136,10 @@ jobs: echo "$line" | tee -a "$GITHUB_STEP_SUMMARY" done < output.txt - core_amd64_name="${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }}:${{ github.ref_name }}-amd64" - plugins_amd64_name="${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }}:${{ github.ref_name }}-plugins-amd64" - core_arm64_name="${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }}:${{ github.ref_name }}-arm64" - plugins_arm64_name="${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }}:${{ github.ref_name }}-plugins-arm64" + core_amd64_name="${{ env.ECR_HOSTNAME }}/${{ steps.set-build-configs.outputs.ECR_IMAGE_NAME }}:${{ github.ref_name }}-amd64" + plugins_amd64_name="${{ env.ECR_HOSTNAME }}/${{ steps.set-build-configs.outputs.ECR_IMAGE_NAME }}:${{ github.ref_name }}-plugins-amd64" + core_arm64_name="${{ env.ECR_HOSTNAME }}/${{ steps.set-build-configs.outputs.ECR_IMAGE_NAME }}:${{ github.ref_name }}-arm64" + plugins_arm64_name="${{ env.ECR_HOSTNAME }}/${{ steps.set-build-configs.outputs.ECR_IMAGE_NAME }}:${{ github.ref_name }}-plugins-arm64" echo "core_amd64_digest=$(jq -r --arg name "$core_amd64_name" '.[]|select(.type=="Published Docker Image" and .name==$name)|.extra.Digest' ${artifact_path})" | tee -a "$GITHUB_OUTPUT" "$GITHUB_STEP_SUMMARY" echo "plugins_amd64_digest=$(jq -r --arg name "$plugins_amd64_name" '.[]|select(.type=="Published Docker Image" and .name==$name)|.extra.Digest' ${artifact_path})" | tee -a "$GITHUB_OUTPUT" "$GITHUB_STEP_SUMMARY" @@ -143,28 +155,28 @@ jobs: uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # v1.4.2 with: subject-digest: ${{ steps.get-image-name-digest.outputs.core_amd64_digest }} - subject-name: ${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }} + subject-name: ${{ env.ECR_HOSTNAME }}/${{ steps.set-build-configs.outputs.ECR_IMAGE_NAME }} push-to-registry: true - name: Attest Docker image (plugins-amd64) uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # v1.4.2 with: subject-digest: ${{ steps.get-image-name-digest.outputs.plugins_amd64_digest }} - subject-name: ${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }} + subject-name: ${{ env.ECR_HOSTNAME }}/${{ steps.set-build-configs.outputs.ECR_IMAGE_NAME }} push-to-registry: true - name: Attest Docker image (core-arm64) uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # v1.4.2 with: subject-digest: ${{ steps.get-image-name-digest.outputs.core_arm64_digest }} - subject-name: ${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }} + subject-name: ${{ env.ECR_HOSTNAME }}/${{ steps.set-build-configs.outputs.ECR_IMAGE_NAME }} push-to-registry: true - name: Attest Docker image (plugins-arm64) uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # v1.4.2 with: subject-digest: ${{ steps.get-image-name-digest.outputs.plugins_arm64_digest }} - subject-name: ${{ env.ECR_HOSTNAME }}/${{ env.ECR_IMAGE_NAME }} + subject-name: ${{ env.ECR_HOSTNAME }}/${{ steps.set-build-configs.outputs.ECR_IMAGE_NAME }} push-to-registry: true - name: Upload SBOMs diff --git a/.goreleaser.ccip.develop.yaml b/.goreleaser.ccip.develop.yaml new file mode 100644 index 0000000000..595fe14c27 --- /dev/null +++ b/.goreleaser.ccip.develop.yaml @@ -0,0 +1,229 @@ +project_name: chainlink + +version: 2 + +env: + - ZIG_EXEC={{ if index .Env "ZIG_EXEC" }}{{ .Env.ZIG_EXEC }}{{ else }}zig{{ end }} + - IMAGE_PREFIX={{ if index .Env "IMAGE_PREFIX" }}{{ .Env.IMAGE_PREFIX }}{{ else }}localhost:5001{{ end }} + - IMAGE_NAME={{ if index .Env "IMAGE_NAME" }}{{ .Env.IMAGE_NAME }}{{ else }}chainlink{{ end }} + - IMAGE_TAG={{ if index .Env "IMAGE_TAG" }}{{ .Env.IMAGE_TAG }}{{ else }}develop{{ end }} + - IMAGE_LABEL_DESCRIPTION="node of the decentralized oracle network, bridging on and off-chain computation" + - IMAGE_LABEL_LICENSES="MIT" + - IMAGE_LABEL_SOURCE="https://github.com/smartcontractkit/{{ .ProjectName }}" + +before: + hooks: + - go mod tidy + - ./tools/bin/goreleaser_utils before_hook + +# See https://goreleaser.com/customization/build/ +builds: + - binary: chainlink + id: linux-arm64 + goos: + - linux + goarch: + - arm64 + hooks: + post: ./tools/bin/goreleaser_utils build_post_hook {{ dir .Path }} {{ .Os }} {{ .Arch }} + env: + - CGO_ENABLED=1 + - CC=$ZIG_EXEC cc -target aarch64-linux-gnu + - CCX=$ZIG_EXEC c++ -target aarch64-linux-gnu + flags: + - -trimpath + - -buildmode=pie + ldflags: + - -s -w -r=$ORIGIN/libs + - -X github.com/smartcontractkit/chainlink/v2/core/static.Version={{ .Env.CHAINLINK_VERSION }} + - -X github.com/smartcontractkit/chainlink/v2/core/static.Sha={{ .FullCommit }} + - binary: chainlink + id: linux-amd64 + goos: + - linux + goarch: + - amd64 + hooks: + post: ./tools/bin/goreleaser_utils build_post_hook {{ dir .Path }} {{ .Os }} {{ .Arch }} + env: + - CGO_ENABLED=1 + - CC=$ZIG_EXEC cc -target x86_64-linux-gnu + - CCX=$ZIG_EXEC c++ -target x86_64-linux-gnu + flags: + - -trimpath + - -buildmode=pie + ldflags: + - -s -w -r=$ORIGIN/libs + - -X github.com/smartcontractkit/chainlink/v2/core/static.Version={{ .Env.CHAINLINK_VERSION }} + - -X github.com/smartcontractkit/chainlink/v2/core/static.Sha={{ .FullCommit }} + +# See https://goreleaser.com/customization/docker/ +dockers: + - id: linux-amd64 + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: amd64 + extra_files: + - tmp/linux_amd64/libs + - tools/bin/ldd_fix + - ccip/config + build_flag_templates: + - "--platform=linux/amd64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--build-arg=CL_CHAIN_DEFAULTS=/chainlink/ccip-config" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-amd64" + - id: linux-arm64 + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: arm64 + extra_files: + - tmp/linux_arm64/libs + - tools/bin/ldd_fix + - ccip/config + build_flag_templates: + - "--platform=linux/arm64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--build-arg=CL_CHAIN_DEFAULTS=/chainlink/ccip-config" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-arm64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-arm64" + - id: linux-amd64-plugins + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: amd64 + extra_files: + - tmp/linux_amd64/libs + - tmp/linux_amd64/plugins + - tools/bin/ldd_fix + - ccip/config + build_flag_templates: + - "--platform=linux/amd64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--build-arg=CL_MEDIAN_CMD=chainlink-feeds" + - "--build-arg=CL_MERCURY_CMD=chainlink-mercury" + - "--build-arg=CL_SOLANA_CMD=chainlink-solana" + - "--build-arg=CL_STARKNET_CMD=chainlink-starknet" + - "--build-arg=CL_CHAIN_DEFAULTS=/chainlink/ccip-config" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-amd64" + - id: linux-arm64-plugins + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: arm64 + extra_files: + - tmp/linux_arm64/libs + - tmp/linux_arm64/plugins + - tools/bin/ldd_fix + - ccip/config + build_flag_templates: + - "--platform=linux/arm64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--build-arg=CL_MEDIAN_CMD=chainlink-feeds" + - "--build-arg=CL_MERCURY_CMD=chainlink-mercury" + - "--build-arg=CL_SOLANA_CMD=chainlink-solana" + - "--build-arg=CL_STARKNET_CMD=chainlink-starknet" + - "--build-arg=CL_CHAIN_DEFAULTS=/chainlink/ccip-config" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-arm64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-arm64" + +# See https://goreleaser.com/customization/docker_manifest/ +docker_manifests: + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-arm64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-arm64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-arm64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-arm64" + +# See https://goreleaser.com/customization/docker_sign/ +docker_signs: + - artifacts: all + args: + - "sign" + - "${artifact}" + - "--yes" + +checksum: + name_template: "checksums.txt" + +snapshot: + version_template: "{{ .Env.CHAINLINK_VERSION }}-{{ .ShortCommit }}" + +partial: + by: target + +# See https://goreleaser.com/customization/release/ +release: + disable: true + +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" +# modelines, feel free to remove those if you don't want/use them: +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj diff --git a/.goreleaser.ccip.production.yaml b/.goreleaser.ccip.production.yaml new file mode 100644 index 0000000000..1247be143c --- /dev/null +++ b/.goreleaser.ccip.production.yaml @@ -0,0 +1,229 @@ +project_name: chainlink + +version: 2 + +env: + - ZIG_EXEC={{ if index .Env "ZIG_EXEC" }}{{ .Env.ZIG_EXEC }}{{ else }}zig{{ end }} + - IMAGE_PREFIX={{ if index .Env "IMAGE_PREFIX" }}{{ .Env.IMAGE_PREFIX }}{{ else }}localhost:5001{{ end }} + - IMAGE_NAME={{ if index .Env "IMAGE_NAME" }}{{ .Env.IMAGE_NAME }}{{ else }}chainlink{{ end }} + - IMAGE_TAG={{ if index .Env "IMAGE_TAG" }}{{ .Env.IMAGE_TAG }}{{ else }}develop{{ end }} + - IMAGE_LABEL_DESCRIPTION="node of the decentralized oracle network, bridging on and off-chain computation" + - IMAGE_LABEL_LICENSES="MIT" + - IMAGE_LABEL_SOURCE="https://github.com/smartcontractkit/{{ .ProjectName }}" + +before: + hooks: + - go mod tidy + - ./tools/bin/goreleaser_utils before_hook + +# See https://goreleaser.com/customization/build/ +builds: + - binary: chainlink + id: linux-arm64 + goos: + - linux + goarch: + - arm64 + hooks: + post: ./tools/bin/goreleaser_utils build_post_hook {{ dir .Path }} {{ .Os }} {{ .Arch }} + env: + - CGO_ENABLED=1 + - CC=$ZIG_EXEC cc -target aarch64-linux-gnu + - CCX=$ZIG_EXEC c++ -target aarch64-linux-gnu + flags: + - -trimpath + - -buildmode=pie + ldflags: + - -s -w -r=$ORIGIN/libs + - -X github.com/smartcontractkit/chainlink/v2/core/static.Version={{ .Env.CHAINLINK_VERSION }} + - -X github.com/smartcontractkit/chainlink/v2/core/static.Sha={{ .FullCommit }} + - binary: chainlink + id: linux-amd64 + goos: + - linux + goarch: + - amd64 + hooks: + post: ./tools/bin/goreleaser_utils build_post_hook {{ dir .Path }} {{ .Os }} {{ .Arch }} + env: + - CGO_ENABLED=1 + - CC=$ZIG_EXEC cc -target x86_64-linux-gnu + - CCX=$ZIG_EXEC c++ -target x86_64-linux-gnu + flags: + - -trimpath + - -buildmode=pie + ldflags: + - -s -w -r=$ORIGIN/libs + - -X github.com/smartcontractkit/chainlink/v2/core/static.Version={{ .Env.CHAINLINK_VERSION }} + - -X github.com/smartcontractkit/chainlink/v2/core/static.Sha={{ .FullCommit }} + +# See https://goreleaser.com/customization/docker/ +dockers: + - id: linux-amd64 + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: amd64 + extra_files: + - tmp/linux_amd64/libs + - tools/bin/ldd_fix + - ccip/config + build_flag_templates: + - "--platform=linux/amd64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--build-arg=CL_CHAIN_DEFAULTS=/chainlink/ccip-config" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-amd64" + - id: linux-arm64 + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: arm64 + extra_files: + - tmp/linux_arm64/libs + - tools/bin/ldd_fix + - ccip/config + build_flag_templates: + - "--platform=linux/arm64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--build-arg=CL_CHAIN_DEFAULTS=/chainlink/ccip-config" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-arm64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-arm64" + - id: linux-amd64-plugins + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: amd64 + extra_files: + - tmp/linux_amd64/libs + - tmp/linux_amd64/plugins + - tools/bin/ldd_fix + - ccip/config + build_flag_templates: + - "--platform=linux/amd64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--build-arg=CL_MEDIAN_CMD=chainlink-feeds" + - "--build-arg=CL_MERCURY_CMD=chainlink-mercury" + - "--build-arg=CL_SOLANA_CMD=chainlink-solana" + - "--build-arg=CL_STARKNET_CMD=chainlink-starknet" + - "--build-arg=CL_CHAIN_DEFAULTS=/chainlink/ccip-config" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-amd64" + - id: linux-arm64-plugins + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: arm64 + extra_files: + - tmp/linux_arm64/libs + - tmp/linux_arm64/plugins + - tools/bin/ldd_fix + - ccip/config + build_flag_templates: + - "--platform=linux/arm64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--build-arg=CL_MEDIAN_CMD=chainlink-feeds" + - "--build-arg=CL_MERCURY_CMD=chainlink-mercury" + - "--build-arg=CL_SOLANA_CMD=chainlink-solana" + - "--build-arg=CL_STARKNET_CMD=chainlink-starknet" + - "--build-arg=CL_CHAIN_DEFAULTS=/chainlink/ccip-config" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-arm64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-arm64" + +# See https://goreleaser.com/customization/docker_manifest/ +docker_manifests: + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-arm64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-arm64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:{{ .Env.IMAGE_TAG }}-plugins-arm64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .Env.IMAGE_NAME }}:sha-{{ .ShortCommit }}-plugins-arm64" + +# See https://goreleaser.com/customization/docker_sign/ +docker_signs: + - artifacts: all + args: + - "sign" + - "${artifact}" + - "--yes" + +checksum: + name_template: "checksums.txt" + +# See https://goreleaser.com/customization/sbom +sboms: + - artifacts: archive + +snapshot: + version_template: "{{ .Env.CHAINLINK_VERSION }}-{{ .ShortCommit }}" + +partial: + by: target + +# See https://goreleaser.com/customization/release/ +release: + disable: true + +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" +# modelines, feel free to remove those if you don't want/use them: +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj diff --git a/GNUmakefile b/GNUmakefile index 23082a1f5a..e2a3508e19 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -70,6 +70,16 @@ docker: --build-arg COMMIT_SHA=$(COMMIT_SHA) \ -f core/chainlink.Dockerfile . +.PHONY: docker-ccip ## Build the chainlink docker image +docker-ccip: + docker buildx build \ + --build-arg COMMIT_SHA=$(COMMIT_SHA) \ + -f core/chainlink.Dockerfile . -t chainlink-ccip:latest + + docker buildx build \ + --build-arg COMMIT_SHA=$(COMMIT_SHA) \ + -f ccip/ccip.Dockerfile . + .PHONY: docker-plugins ## Build the chainlink-plugins docker image docker-plugins: docker buildx build \ diff --git a/ccip/config/README.md b/ccip/config/README.md new file mode 100644 index 0000000000..f5cd87e688 --- /dev/null +++ b/ccip/config/README.md @@ -0,0 +1,10 @@ +# Default Configurations + +:warning: IMPORTANT :warning: + +This directory contains configs that are specific to the CCIP build. Apply changes here only if related to the CCIP. + + +All config sets **inherit** from `fallback.toml` first and overwrite +fields as necessary. Do not create a new full configuration from +scratch. diff --git a/ccip/config/evm/Arbitrum_Mainnet.toml b/ccip/config/evm/Arbitrum_Mainnet.toml new file mode 100644 index 0000000000..e3dcafd56f --- /dev/null +++ b/ccip/config/evm/Arbitrum_Mainnet.toml @@ -0,0 +1,29 @@ +# Arbitrum is an L2 chain. Pending proper L2 support, for now we rely on their sequencer +ChainID = '42161' +ChainType = 'arbitrum' +FinalityTagEnabled = true +LinkContractAddress = "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4" +LogPollInterval = '1s' +# Arbitrum only emits blocks when a new tx is received, so this method of liveness detection is not useful +NoNewHeadsThreshold = '0' +OCR.ContractConfirmations = 1 + +[GasEstimator] +Mode = 'Arbitrum' +LimitMax = 1_000_000_000 +# Arbitrum uses the suggested gas price, so we don't want to place any limits on the minimum +PriceMin = '0' +PriceDefault = '0.1 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +FeeCapDefault = '1000 gwei' +BumpThreshold = 5 + +[GasEstimator.BlockHistory] +# Force an error if someone set GAS_UPDATER_ENABLED=true by accident; we never want to run the block history estimator on arbitrum +BlockHistorySize = 0 + +[NodePool] +SyncThreshold = 10 + +[OCR2.Automation] +GasLimit = 14500000 diff --git a/ccip/config/evm/Arbitrum_Sepolia.toml b/ccip/config/evm/Arbitrum_Sepolia.toml new file mode 100644 index 0000000000..ea994cf7c7 --- /dev/null +++ b/ccip/config/evm/Arbitrum_Sepolia.toml @@ -0,0 +1,27 @@ +ChainID = '421614' +ChainType = 'arbitrum' +FinalityTagEnabled = true +LinkContractAddress = '0xE4aB69C077896252FAFBD49EFD26B5D171A32410' +NoNewHeadsThreshold = '0' +OCR.ContractConfirmations = 1 +LogPollInterval = '1s' + +[GasEstimator] +Mode = 'Arbitrum' +LimitMax = 1_000_000_000 +# Arbitrum uses the suggested gas price, so we don't want to place any limits on the minimum +PriceMin = '0' +PriceDefault = '0.1 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +FeeCapDefault = '1000 gwei' +BumpThreshold = 5 + +[GasEstimator.BlockHistory] +# Force an error if someone set GAS_UPDATER_ENABLED=true by accident; we never want to run the block history estimator on arbitrum +BlockHistorySize = 0 + +[NodePool] +SyncThreshold = 10 + +[OCR2.Automation] +GasLimit = 14500000 diff --git a/ccip/config/evm/Astar_Mainnet.toml b/ccip/config/evm/Astar_Mainnet.toml new file mode 100644 index 0000000000..87808001eb --- /dev/null +++ b/ccip/config/evm/Astar_Mainnet.toml @@ -0,0 +1,9 @@ +ChainID = '592' +FinalityTagEnabled = true +FinalityDepth = 100 +LogPollInterval = '6s' + +[GasEstimator] +EIP1559DynamicFees = false +PriceMax = '100000 gwei' +LimitDefault = 8000000 \ No newline at end of file diff --git a/ccip/config/evm/Astar_Shibuya.toml b/ccip/config/evm/Astar_Shibuya.toml new file mode 100644 index 0000000000..5a5df06f6f --- /dev/null +++ b/ccip/config/evm/Astar_Shibuya.toml @@ -0,0 +1,9 @@ +ChainID = '81' +FinalityTagEnabled = true +FinalityDepth = 100 +LogPollInterval = '6s' + +[GasEstimator] +EIP1559DynamicFees = false +PriceMax = '100000 gwei' +LimitDefault = 8000000 \ No newline at end of file diff --git a/ccip/config/evm/Avalanche_ANZ_testnet.toml b/ccip/config/evm/Avalanche_ANZ_testnet.toml new file mode 100644 index 0000000000..4833881bf4 --- /dev/null +++ b/ccip/config/evm/Avalanche_ANZ_testnet.toml @@ -0,0 +1,19 @@ +ChainID = '76578' +FinalityDepth = 1 +FinalityTagEnabled = false +LinkContractAddress = '0x779877A7B0D9E8603169DdbD7836e478b4624789' +LogPollInterval = '3s' +MinIncomingConfirmations = 1 +# Avax subnet only emits blocks when a new tx is received, so this method of liveness detection is not useful. +NoNewHeadsThreshold = '0' +OCR.ContractConfirmations = 1 +RPCBlockQueryDelay = 2 + +[GasEstimator] +Mode = 'BlockHistory' +PriceDefault = '25 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '25 gwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 diff --git a/ccip/config/evm/Avalanche_Fuji.toml b/ccip/config/evm/Avalanche_Fuji.toml new file mode 100644 index 0000000000..5ba2e3cdc7 --- /dev/null +++ b/ccip/config/evm/Avalanche_Fuji.toml @@ -0,0 +1,21 @@ +ChainID = '43113' +FinalityDepth = 1 +FinalityTagEnabled = true +LinkContractAddress = '0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846' +LogPollInterval = '3s' +MinIncomingConfirmations = 1 +NoNewHeadsThreshold = '30s' +OCR.ContractConfirmations = 1 +RPCBlockQueryDelay = 2 +NoNewFinalizedHeadsThreshold = '1m' + +[GasEstimator] +PriceDefault = '25 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '25 gwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[HeadTracker] +FinalityTagBypass = false diff --git a/ccip/config/evm/Avalanche_Mainnet.toml b/ccip/config/evm/Avalanche_Mainnet.toml new file mode 100644 index 0000000000..e7813842b4 --- /dev/null +++ b/ccip/config/evm/Avalanche_Mainnet.toml @@ -0,0 +1,19 @@ +ChainID = '43114' +FinalityDepth = 1 +FinalityTagEnabled = true +LinkContractAddress = '0x5947BB275c521040051D82396192181b413227A3' +LogPollInterval = '3s' +MinIncomingConfirmations = 1 +NoNewHeadsThreshold = '30s' +OCR.ContractConfirmations = 1 +RPCBlockQueryDelay = 2 +NoNewFinalizedHeadsThreshold = '1m' + +[GasEstimator] +PriceDefault = '25 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '25 gwei' + +[GasEstimator.BlockHistory] +# Average block time of 2s +BlockHistorySize = 24 diff --git a/ccip/config/evm/BSC_Mainnet.toml b/ccip/config/evm/BSC_Mainnet.toml new file mode 100644 index 0000000000..10f4c570be --- /dev/null +++ b/ccip/config/evm/BSC_Mainnet.toml @@ -0,0 +1,28 @@ +# BSC uses Clique consensus with ~3s block times +# Clique offers finality within (N/2)+1 blocks where N is number of signers +# There are 21 BSC validators so theoretically finality should occur after 21/2+1 = 11 blocks +ChainID = '56' +# Keeping this >> 11 because it's not expensive and gives us a safety margin +FinalityDepth = 50 +FinalityTagEnabled = true +LinkContractAddress = '0x404460C6A5EdE2D891e8297795264fDe62ADBB75' +LogPollInterval = '3s' +NoNewHeadsThreshold = '30s' +RPCBlockQueryDelay = 2 +NoNewFinalizedHeadsThreshold = '45s' + +[GasEstimator] +PriceDefault = '5 gwei' +# 15s delay since feeds update every minute in volatile situations +BumpThreshold = 5 + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[OCR] +DatabaseTimeout = '2s' +ContractTransmitterTransmitTimeout = '2s' +ObservationGracePeriod = '500ms' + +[NodePool] +SyncThreshold = 10 diff --git a/ccip/config/evm/BSC_Testnet.toml b/ccip/config/evm/BSC_Testnet.toml new file mode 100644 index 0000000000..b27a877812 --- /dev/null +++ b/ccip/config/evm/BSC_Testnet.toml @@ -0,0 +1,33 @@ +# BSC uses Clique consensus with ~3s block times +# Clique offers finality within (N/2)+1 blocks where N is number of signers +# There are 21 BSC validators so theoretically finality should occur after 21/2+1 = 11 blocks +ChainID = '97' +# Keeping this >> 11 because it's not expensive and gives us a safety margin +FinalityDepth = 50 +FinalityTagEnabled = true +LinkContractAddress = '0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06' +LogPollInterval = '3s' +NoNewHeadsThreshold = '30s' +RPCBlockQueryDelay = 2 +NoNewFinalizedHeadsThreshold = '40s' + +[GasEstimator] +PriceDefault = '5 gwei' +# 15s delay since feeds update every minute in volatile situations +BumpThreshold = 5 + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[HeadTracker] +HistoryDepth = 100 +SamplingInterval = '1s' +FinalityTagBypass = false + +[OCR] +DatabaseTimeout = '2s' +ContractTransmitterTransmitTimeout = '2s' +ObservationGracePeriod = '500ms' + +[NodePool] +SyncThreshold = 10 diff --git a/ccip/config/evm/Base_Mainnet.toml b/ccip/config/evm/Base_Mainnet.toml new file mode 100644 index 0000000000..da38182b19 --- /dev/null +++ b/ccip/config/evm/Base_Mainnet.toml @@ -0,0 +1,31 @@ +ChainID = '8453' +ChainType = 'optimismBedrock' +FinalityDepth = 200 +FinalityTagEnabled = true +LogPollInterval = '2s' +NoNewHeadsThreshold = '40s' +MinIncomingConfirmations = 1 +NoNewFinalizedHeadsThreshold = '15m' + +[GasEstimator] +EIP1559DynamicFees = true +PriceMin = '1 wei' +BumpMin = '100 wei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[Transactions] +ResendAfterThreshold = '30s' + +[HeadTracker] +HistoryDepth = 300 + +[NodePool] +SyncThreshold = 10 + +[OCR] +ContractConfirmations = 1 + +[OCR2.Automation] +GasLimit = 6500000 diff --git a/ccip/config/evm/Base_Sepolia.toml b/ccip/config/evm/Base_Sepolia.toml new file mode 100644 index 0000000000..92f7717b27 --- /dev/null +++ b/ccip/config/evm/Base_Sepolia.toml @@ -0,0 +1,32 @@ +ChainID = '84532' +ChainType = 'optimismBedrock' +FinalityDepth = 200 +FinalityTagEnabled = true +LinkContractAddress = '0xE4aB69C077896252FAFBD49EFD26B5D171A32410' +LogPollInterval = '2s' +NoNewHeadsThreshold = '40s' +MinIncomingConfirmations = 1 +NoNewFinalizedHeadsThreshold = '12m' + +[GasEstimator] +EIP1559DynamicFees = true +PriceMin = '1 wei' +BumpMin = '100 wei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 60 + +[Transactions] +ResendAfterThreshold = '30s' + +[HeadTracker] +HistoryDepth = 300 + +[NodePool] +SyncThreshold = 10 + +[OCR] +ContractConfirmations = 1 + +[OCR2.Automation] +GasLimit = 6500000 diff --git a/ccip/config/evm/Blast_Mainnet.toml b/ccip/config/evm/Blast_Mainnet.toml new file mode 100644 index 0000000000..f8b501723f --- /dev/null +++ b/ccip/config/evm/Blast_Mainnet.toml @@ -0,0 +1,34 @@ +ChainID = '81457' +FinalityDepth = 200 +FinalityTagEnabled = true +ChainType = 'optimismBedrock' +# block rate is ~2sec, so this ensures blocks are polled correctly +LogPollInterval = '2s' + +[GasEstimator] +EIP1559DynamicFees = true +BumpThreshold = 60 +BumpPercent = 20 +BumpMin = '100 wei' +PriceMax = '120 gwei' +LimitDefault = 8000000 +FeeCapDefault = '120 gwei' + +[GasEstimator.BlockHistory] +# Default is 24, which leads to bumpy gas prices. In CCIP +# we want to smooth out the gas prices, so we increase the sample size. +BlockHistorySize = 200 +# The formula for FeeCap is (current block base fee * (1.125 ^ EIP1559FeeCapBufferBlocks) + tipcap) +# where tipcap is managed by the block history estimators. In the context of CCIP, +# the gas price is relayed to other changes for quotes so we want accurate/avg not pessimistic values. +# So we set this to zero so FeeCap = baseFee + tipcap. +EIP1559FeeCapBufferBlocks = 0 + +[HeadTracker] +HistoryDepth = 300 + +[NodePool] +# 4 block sync time between nodes to ensure they aren't labelled unreachable too soon +PollFailureThreshold = 4 +# polls every 4sec to check if there is a block produced, since blockRate is ~3sec +PollInterval = '4s' \ No newline at end of file diff --git a/ccip/config/evm/Blast_Sepolia.toml b/ccip/config/evm/Blast_Sepolia.toml new file mode 100644 index 0000000000..96dc5c6787 --- /dev/null +++ b/ccip/config/evm/Blast_Sepolia.toml @@ -0,0 +1,34 @@ +ChainID = '168587773' +FinalityDepth = 200 +FinalityTagEnabled = true +ChainType = 'optimismBedrock' +# block rate is ~2sec, so this ensures blocks are polled correctly +LogPollInterval = '2s' + +[GasEstimator] +EIP1559DynamicFees = true +BumpThreshold = 60 +BumpPercent = 20 +BumpMin = '100 wei' +PriceMax = '120 gwei' +LimitDefault = 8000000 +FeeCapDefault = '120 gwei' + +[GasEstimator.BlockHistory] +# Default is 24, which leads to bumpy gas prices. In CCIP +# we want to smooth out the gas prices, so we increase the sample size. +BlockHistorySize = 200 +# The formula for FeeCap is (current block base fee * (1.125 ^ EIP1559FeeCapBufferBlocks) + tipcap) +# where tipcap is managed by the block history estimators. In the context of CCIP, +# the gas price is relayed to other changes for quotes so we want accurate/avg not pessimistic values. +# So we set this to zero so FeeCap = baseFee + tipcap. +EIP1559FeeCapBufferBlocks = 0 + +[HeadTracker] +HistoryDepth = 300 + +[NodePool] +# 4 block sync time between nodes to ensure they aren't labelled unreachable too soon +PollFailureThreshold = 4 +# polls every 4sec to check if there is a block produced, since blockRate is ~3sec +PollInterval = '4s' \ No newline at end of file diff --git a/ccip/config/evm/Celo_Mainnet.toml b/ccip/config/evm/Celo_Mainnet.toml new file mode 100644 index 0000000000..a494862037 --- /dev/null +++ b/ccip/config/evm/Celo_Mainnet.toml @@ -0,0 +1,20 @@ +ChainID = '42220' +ChainType = 'celo' +FinalityDepth = 10 +LogPollInterval = '5s' +MinIncomingConfirmations = 1 +NoNewHeadsThreshold = '1m' +OCR.ContractConfirmations = 1 +NoNewFinalizedHeadsThreshold = '1m' + +[GasEstimator] +PriceDefault = '5 gwei' +PriceMax = '500 gwei' +PriceMin = '5 gwei' +BumpMin = '2 gwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 12 + +[HeadTracker] +HistoryDepth = 50 diff --git a/ccip/config/evm/Celo_Testnet.toml b/ccip/config/evm/Celo_Testnet.toml new file mode 100644 index 0000000000..eb43f080b7 --- /dev/null +++ b/ccip/config/evm/Celo_Testnet.toml @@ -0,0 +1,20 @@ +ChainID = '44787' +ChainType = 'celo' +FinalityDepth = 10 +LogPollInterval = '5s' +MinIncomingConfirmations = 1 +NoNewHeadsThreshold = '1m' +OCR.ContractConfirmations = 1 +NoNewFinalizedHeadsThreshold = '1m' + +[GasEstimator] +PriceDefault = '5 gwei' +PriceMax = '500 gwei' +PriceMin = '5 gwei' +BumpMin = '2 gwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[HeadTracker] +HistoryDepth = 50 diff --git a/ccip/config/evm/Ethereum_Mainnet.toml b/ccip/config/evm/Ethereum_Mainnet.toml new file mode 100644 index 0000000000..0bcaf35c64 --- /dev/null +++ b/ccip/config/evm/Ethereum_Mainnet.toml @@ -0,0 +1,17 @@ +ChainID = '1' +LinkContractAddress = '0x514910771AF9Ca656af840dff83E8264EcF986CA' +MinContractPayment = '0.1 link' +OperatorFactoryAddress = '0x3E64Cd889482443324F91bFA9c84fE72A511f48A' +FinalityTagEnabled = true +NoNewFinalizedHeadsThreshold = '9m' + +[GasEstimator] +EIP1559DynamicFees = true + +[GasEstimator.BlockHistory] +# EIP-1559 does well on a smaller block history size +BlockHistorySize = 4 +TransactionPercentile = 50 + +[OCR2.Automation] +GasLimit = 10500000 diff --git a/ccip/config/evm/Ethereum_Sepolia.toml b/ccip/config/evm/Ethereum_Sepolia.toml new file mode 100644 index 0000000000..24a0e68f77 --- /dev/null +++ b/ccip/config/evm/Ethereum_Sepolia.toml @@ -0,0 +1,17 @@ +ChainID = '11155111' +LinkContractAddress = '0x779877A7B0D9E8603169DdbD7836e478b4624789' +MinContractPayment = '0.1 link' +FinalityTagEnabled = true + +[GasEstimator] +EIP1559DynamicFees = true + +[GasEstimator.BlockHistory] +BlockHistorySize = 4 +TransactionPercentile = 50 + +[OCR2.Automation] +GasLimit = 10500000 + +[HeadTracker] +FinalityTagBypass = false diff --git a/ccip/config/evm/Fantom_Mainnet.toml b/ccip/config/evm/Fantom_Mainnet.toml new file mode 100644 index 0000000000..7e76d94278 --- /dev/null +++ b/ccip/config/evm/Fantom_Mainnet.toml @@ -0,0 +1,12 @@ +ChainID = '250' +LinkContractAddress = '0x6F43FF82CCA38001B6699a8AC47A2d0E66939407' +LogPollInterval = '1s' +NoNewHeadsThreshold = '30s' +RPCBlockQueryDelay = 2 + +[GasEstimator] +# Fantom network has been slow to include txs at times when using the BlockHistory estimator, and the recommendation is to use SuggestedPrice mode. +Mode = 'SuggestedPrice' + +[OCR2.Automation] +GasLimit = 3800000 \ No newline at end of file diff --git a/ccip/config/evm/Fantom_Testnet.toml b/ccip/config/evm/Fantom_Testnet.toml new file mode 100644 index 0000000000..5f24a76c2e --- /dev/null +++ b/ccip/config/evm/Fantom_Testnet.toml @@ -0,0 +1,12 @@ +ChainID = '4002' +LinkContractAddress = '0xfaFedb041c0DD4fA2Dc0d87a6B0979Ee6FA7af5F' +LogPollInterval = '1s' +# Fantom testnet only emits blocks when a new tx is received, so this method of liveness detection is not useful +NoNewHeadsThreshold = '0' +RPCBlockQueryDelay = 2 + +[GasEstimator] +Mode = 'SuggestedPrice' + +[OCR2.Automation] +GasLimit = 3800000 \ No newline at end of file diff --git a/ccip/config/evm/Gnosis_Chiado.toml b/ccip/config/evm/Gnosis_Chiado.toml new file mode 100644 index 0000000000..379377a226 --- /dev/null +++ b/ccip/config/evm/Gnosis_Chiado.toml @@ -0,0 +1,10 @@ +ChainID = '10200' +# Gnoisis Finality is approx 8 minutes @ 12 blocks per minute, so 96 blocks +FinalityDepth = 100 +ChainType = 'gnosis' +LogPollInterval = '5s' +NoNewFinalizedHeadsThreshold = '2m' + +[GasEstimator] +EIP1559DynamicFees = true +PriceMax = '500 gwei' diff --git a/ccip/config/evm/Gnosis_Mainnet.toml b/ccip/config/evm/Gnosis_Mainnet.toml new file mode 100644 index 0000000000..628646364f --- /dev/null +++ b/ccip/config/evm/Gnosis_Mainnet.toml @@ -0,0 +1,18 @@ +# xDai currently uses AuRa (like Parity) consensus so finality rules will be similar to parity +# See: https://www.poa.network/for-users/whitepaper/poadao-v1/proof-of-authority +# NOTE: xDai is planning to move to Honeybadger BFT which might have different finality guarantees +# https://www.xdaichain.com/for-validators/consensus/honeybadger-bft-consensus +# For worst case re-org depth on AuRa, assume 2n+2 (see: https://github.com/poanetwork/wiki/wiki/Aura-Consensus-Protocol-Audit) +# With xDai's current maximum of 19 validators then 40 blocks is the maximum possible re-org) +# The mainnet default of 50 blocks is ok here +ChainID = '100' +ChainType = 'gnosis' +LinkContractAddress = '0xE2e73A1c69ecF83F464EFCE6A5be353a37cA09b2' +LogPollInterval = '5s' +NoNewFinalizedHeadsThreshold = '2m' + +[GasEstimator] +PriceDefault = '1 gwei' +PriceMax = '500 gwei' +# 1 Gwei is the minimum accepted by the validators (unless whitelisted) +PriceMin = '1 gwei' diff --git a/ccip/config/evm/Kroma_Mainnet.toml b/ccip/config/evm/Kroma_Mainnet.toml new file mode 100644 index 0000000000..3a48aa8ae1 --- /dev/null +++ b/ccip/config/evm/Kroma_Mainnet.toml @@ -0,0 +1,27 @@ +ChainID = '255' +ChainType = 'kroma' # Kroma is based on the Optimism Bedrock architechture +FinalityDepth = 400 +FinalityTagEnabled = true +LogPollInterval = '2s' +NoNewHeadsThreshold = '40s' +MinIncomingConfirmations = 1 + +[GasEstimator] +EIP1559DynamicFees = true +PriceMin = '1 wei' +BumpMin = '100 wei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[Transactions] +ResendAfterThreshold = '30s' + +[HeadTracker] +HistoryDepth = 400 + +[NodePool] +SyncThreshold = 10 + +[OCR] +ContractConfirmations = 1 diff --git a/ccip/config/evm/Kroma_Sepolia.toml b/ccip/config/evm/Kroma_Sepolia.toml new file mode 100644 index 0000000000..9609a09e07 --- /dev/null +++ b/ccip/config/evm/Kroma_Sepolia.toml @@ -0,0 +1,27 @@ +ChainID = '2358' +ChainType = 'kroma' # Kroma is based on the Optimism Bedrock architechture +FinalityDepth = 400 +FinalityTagEnabled = true +LogPollInterval = '2s' +NoNewHeadsThreshold = '40s' +MinIncomingConfirmations = 1 + +[GasEstimator] +EIP1559DynamicFees = true +PriceMin = '1 wei' +BumpMin = '100 wei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[Transactions] +ResendAfterThreshold = '30s' + +[HeadTracker] +HistoryDepth = 400 + +[NodePool] +SyncThreshold = 10 + +[OCR] +ContractConfirmations = 1 diff --git a/ccip/config/evm/L3X_Mainnet.toml b/ccip/config/evm/L3X_Mainnet.toml new file mode 100644 index 0000000000..1fbda42fd2 --- /dev/null +++ b/ccip/config/evm/L3X_Mainnet.toml @@ -0,0 +1,18 @@ +ChainID = '12324' +ChainType = 'arbitrum' +FinalityTagEnabled = true +FinalityDepth = 10 +LinkContractAddress = '0x79f531a3D07214304F259DC28c7191513223bcf3' +# Produces blocks on-demand +NoNewHeadsThreshold = '0' +OCR.ContractConfirmations = 1 +LogPollInterval = '10s' + +[GasEstimator] +Mode = 'Arbitrum' +LimitMax = 1_000_000_000 +# Arbitrum-based chains uses the suggested gas price, so we don't want to place any limits on the minimum +PriceMin = '0' +PriceDefault = '0.1 gwei' +FeeCapDefault = '1000 gwei' +BumpThreshold = 5 diff --git a/ccip/config/evm/L3X_Sepolia.toml b/ccip/config/evm/L3X_Sepolia.toml new file mode 100644 index 0000000000..ee515bb72b --- /dev/null +++ b/ccip/config/evm/L3X_Sepolia.toml @@ -0,0 +1,18 @@ +ChainID = '12325' +ChainType = 'arbitrum' +FinalityTagEnabled = true +FinalityDepth = 10 +LinkContractAddress = '0xa71848C99155DA0b245981E5ebD1C94C4be51c43' +# Produces blocks on-demand +NoNewHeadsThreshold = '0' +OCR.ContractConfirmations = 1 +LogPollInterval = '10s' + +[GasEstimator] +Mode = 'Arbitrum' +LimitMax = 1_000_000_000 +# Arbitrum-based chains uses the suggested gas price, so we don't want to place any limits on the minimum +PriceMin = '0' +PriceDefault = '0.1 gwei' +FeeCapDefault = '1000 gwei' +BumpThreshold = 5 diff --git a/ccip/config/evm/Linea_Mainnet.toml b/ccip/config/evm/Linea_Mainnet.toml new file mode 100644 index 0000000000..94d8bedc44 --- /dev/null +++ b/ccip/config/evm/Linea_Mainnet.toml @@ -0,0 +1,17 @@ +ChainID = '59144' +# Block time 12s, finality < 60m +FinalityDepth = 300 +# Blocks are only emitted when a transaction happens / no empty blocks +NoNewHeadsThreshold = '0' + +[GasEstimator] +BumpPercent = 40 +PriceMin = '400 mwei' + +[Transactions] +# increase resend time to align with finality +ResendAfterThreshold = '3m' + +# set greater than finality depth +[HeadTracker] +HistoryDepth = 350 diff --git a/ccip/config/evm/Linea_Sepolia.toml b/ccip/config/evm/Linea_Sepolia.toml new file mode 100644 index 0000000000..ac5e18a09b --- /dev/null +++ b/ccip/config/evm/Linea_Sepolia.toml @@ -0,0 +1,13 @@ +ChainID = '59141' +FinalityDepth = 900 +NoNewHeadsThreshold = '0' + +[GasEstimator] +EIP1559DynamicFees = true +PriceMin = '1 wei' + +[Transactions] +ResendAfterThreshold = '3m' + +[HeadTracker] +HistoryDepth = 1000 \ No newline at end of file diff --git a/ccip/config/evm/Mantle_Sepolia.toml b/ccip/config/evm/Mantle_Sepolia.toml new file mode 100644 index 0000000000..ee994a7182 --- /dev/null +++ b/ccip/config/evm/Mantle_Sepolia.toml @@ -0,0 +1,19 @@ +ChainID = '5003' +ChainType = 'optimismBedrock' +FinalityDepth = 500 +LogPollInterval = '2s' +NoNewHeadsThreshold = '0' +MinIncomingConfirmations = 1 + +[HeadTracker] +HistoryDepth = 600 + +[GasEstimator] +Mode = 'L2Suggested' +PriceMax = '200 gwei' +LimitDefault = 100000000 +FeeCapDefault = '200 gwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 200 +EIP1559FeeCapBufferBlocks = 0 \ No newline at end of file diff --git a/ccip/config/evm/Metis_Mainnet.toml b/ccip/config/evm/Metis_Mainnet.toml new file mode 100644 index 0000000000..f057400d01 --- /dev/null +++ b/ccip/config/evm/Metis_Mainnet.toml @@ -0,0 +1,21 @@ +# Metis is an L2 chain based on Optimism. +ChainID = '1088' +ChainType = 'metis' +# Sequencer offers absolute finality +FinalityDepth = 10 +FinalityTagEnabled = true +MinIncomingConfirmations = 1 +NoNewHeadsThreshold = '0' +OCR.ContractConfirmations = 1 + +[GasEstimator] +Mode = 'SuggestedPrice' +# Metis uses the SuggestedPrice estimator; we don't want to place any limits on the minimum gas price +PriceMin = '0' + +[GasEstimator.BlockHistory] +# Force an error if someone enables the estimator by accident; we never want to run the block history estimator on metisaa +BlockHistorySize = 0 + +[NodePool] +SyncThreshold = 10 diff --git a/ccip/config/evm/Metis_Sepolia.toml b/ccip/config/evm/Metis_Sepolia.toml new file mode 100644 index 0000000000..4ff4056c75 --- /dev/null +++ b/ccip/config/evm/Metis_Sepolia.toml @@ -0,0 +1,17 @@ +ChainID = '59902' +ChainType = 'optimismBedrock' +FinalityDepth = 10 +FinalityTagEnabled = true +MinIncomingConfirmations = 1 +NoNewHeadsThreshold = '0' +OCR.ContractConfirmations = 1 + +[GasEstimator] +Mode = 'SuggestedPrice' +PriceMin = '0' + +[GasEstimator.BlockHistory] +BlockHistorySize = 0 + +[NodePool] +SyncThreshold = 10 diff --git a/ccip/config/evm/Mode_Mainnet.toml b/ccip/config/evm/Mode_Mainnet.toml new file mode 100644 index 0000000000..69a8e93fec --- /dev/null +++ b/ccip/config/evm/Mode_Mainnet.toml @@ -0,0 +1,30 @@ +ChainID = '34443' +FinalityDepth = 200 +FinalityTagEnabled = true +ChainType = 'optimismBedrock' + +[GasEstimator] +EIP1559DynamicFees = true +BumpThreshold = 60 +BumpPercent = 20 +BumpMin = '100 wei' +PriceMax = '120 gwei' +LimitDefault = 8000000 +FeeCapDefault = '120 gwei' + +[GasEstimator.BlockHistory] +# Default is 24, which leads to bumpy gas prices. In CCIP +# we want to smooth out the gas prices, so we increase the sample size. +BlockHistorySize = 200 +# The formula for FeeCap is (current block base fee * (1.125 ^ EIP1559FeeCapBufferBlocks) + tipcap) +# where tipcap is managed by the block history estimators. In the context of CCIP, +# the gas price is relayed to other changes for quotes so we want accurate/avg not pessimistic values. +# So we set this to zero so FeeCap = baseFee + tipcap. +EIP1559FeeCapBufferBlocks = 0 + +[HeadTracker] +HistoryDepth = 300 + +[NodePool] +PollFailureThreshold = 2 +PollInterval = '3s' diff --git a/ccip/config/evm/Mode_Sepolia.toml b/ccip/config/evm/Mode_Sepolia.toml new file mode 100644 index 0000000000..f7398869be --- /dev/null +++ b/ccip/config/evm/Mode_Sepolia.toml @@ -0,0 +1,30 @@ +ChainID = '919' +FinalityDepth = 200 +FinalityTagEnabled = true +ChainType = 'optimismBedrock' + +[GasEstimator] +EIP1559DynamicFees = true +BumpThreshold = 60 +BumpPercent = 20 +BumpMin = '100 wei' +PriceMax = '120 gwei' +LimitDefault = 8000000 +FeeCapDefault = '120 gwei' + +[GasEstimator.BlockHistory] +# Default is 24, which leads to bumpy gas prices. In CCIP +# we want to smooth out the gas prices, so we increase the sample size. +BlockHistorySize = 200 +# The formula for FeeCap is (current block base fee * (1.125 ^ EIP1559FeeCapBufferBlocks) + tipcap) +# where tipcap is managed by the block history estimators. In the context of CCIP, +# the gas price is relayed to other changes for quotes so we want accurate/avg not pessimistic values. +# So we set this to zero so FeeCap = baseFee + tipcap. +EIP1559FeeCapBufferBlocks = 0 + +[HeadTracker] +HistoryDepth = 300 + +[NodePool] +PollFailureThreshold = 2 +PollInterval = '3s' diff --git a/ccip/config/evm/OKX_Mainnet.toml b/ccip/config/evm/OKX_Mainnet.toml new file mode 100644 index 0000000000..d0b26ede2e --- /dev/null +++ b/ccip/config/evm/OKX_Mainnet.toml @@ -0,0 +1 @@ +ChainID = '66' diff --git a/ccip/config/evm/OKX_Testnet.toml b/ccip/config/evm/OKX_Testnet.toml new file mode 100644 index 0000000000..2587f010b1 --- /dev/null +++ b/ccip/config/evm/OKX_Testnet.toml @@ -0,0 +1 @@ +ChainID = '65' diff --git a/ccip/config/evm/Optimism_Mainnet.toml b/ccip/config/evm/Optimism_Mainnet.toml new file mode 100644 index 0000000000..b0f56a49d9 --- /dev/null +++ b/ccip/config/evm/Optimism_Mainnet.toml @@ -0,0 +1,32 @@ +ChainID = '10' +ChainType = 'optimismBedrock' +FinalityDepth = 200 +FinalityTagEnabled = true +LinkContractAddress = '0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6' +LogPollInterval = '2s' +NoNewHeadsThreshold = '40s' +MinIncomingConfirmations = 1 +NoNewFinalizedHeadsThreshold = '13m' + +[GasEstimator] +EIP1559DynamicFees = true +PriceMin = '1 wei' +BumpMin = '100 wei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[Transactions] +ResendAfterThreshold = '30s' + +[HeadTracker] +HistoryDepth = 300 + +[NodePool] +SyncThreshold = 10 + +[OCR] +ContractConfirmations = 1 + +[OCR2.Automation] +GasLimit = 6500000 diff --git a/ccip/config/evm/Optimism_Sepolia.toml b/ccip/config/evm/Optimism_Sepolia.toml new file mode 100644 index 0000000000..1c71aa5dd8 --- /dev/null +++ b/ccip/config/evm/Optimism_Sepolia.toml @@ -0,0 +1,31 @@ +ChainID = '11155420' +ChainType = 'optimismBedrock' +FinalityDepth = 200 +FinalityTagEnabled = true +LogPollInterval = '2s' +NoNewHeadsThreshold = '40s' +MinIncomingConfirmations = 1 +NoNewFinalizedHeadsThreshold = '15m' + +[GasEstimator] +EIP1559DynamicFees = true +PriceMin = '1 wei' +BumpMin = '100 wei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 60 + +[Transactions] +ResendAfterThreshold = '30s' + +[HeadTracker] +HistoryDepth = 300 + +[NodePool] +SyncThreshold = 10 + +[OCR] +ContractConfirmations = 1 + +[OCR2.Automation] +GasLimit = 6500000 diff --git a/ccip/config/evm/Polygon_Amoy.toml b/ccip/config/evm/Polygon_Amoy.toml new file mode 100644 index 0000000000..b05b3053a8 --- /dev/null +++ b/ccip/config/evm/Polygon_Amoy.toml @@ -0,0 +1,28 @@ +ChainID = '80002' +FinalityDepth = 500 +LogPollInterval = '1s' +MinIncomingConfirmations = 5 +NoNewHeadsThreshold = '30s' +RPCBlockQueryDelay = 10 +RPCDefaultBatchSize = 100 +NoNewFinalizedHeadsThreshold = '12m' + +[Transactions] +MaxQueued = 5000 + +[GasEstimator] +EIP1559DynamicFees = true +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceDefault = '25 gwei' +PriceMin = '25 gwei' +BumpMin = '20 gwei' +BumpThreshold = 5 + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[HeadTracker] +HistoryDepth = 2000 + +[NodePool] +SyncThreshold = 10 diff --git a/ccip/config/evm/Polygon_Mainnet.toml b/ccip/config/evm/Polygon_Mainnet.toml new file mode 100644 index 0000000000..bf605cab3c --- /dev/null +++ b/ccip/config/evm/Polygon_Mainnet.toml @@ -0,0 +1,38 @@ +# Polygon has a 1s block time and looser finality guarantees than ethereum. +ChainID = '137' +# It is quite common to see re-orgs on polygon go several hundred blocks deep. See: https://polygonscan.com/blocks_forked +FinalityDepth = 500 +FinalityTagEnabled = true +LinkContractAddress = '0xb0897686c545045aFc77CF20eC7A532E3120E0F1' +LogPollInterval = '1s' +MinIncomingConfirmations = 5 +NoNewHeadsThreshold = '30s' +# Must be set to something large here because Polygon has so many re-orgs that otherwise we are constantly refetching +RPCBlockQueryDelay = 10 +RPCDefaultBatchSize = 100 +NoNewFinalizedHeadsThreshold = '6m' + +[Transactions] +# Matic nodes under high mempool pressure are liable to drop txes, we need to ensure we keep sending them +# Since re-orgs on Polygon can be so large, we need a large safety buffer to allow time for the queue to clear down before we start dropping transactions +MaxQueued = 5000 + +[GasEstimator] +# Many Polygon RPC providers set a minimum of 30 GWei on mainnet to prevent spam +PriceDefault = '30 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +# Many Polygon RPC providers set a minimum of 30 GWei on mainnet to prevent spam +PriceMin = '30 gwei' +BumpMin = '20 gwei' +# 10s delay since feeds update every minute in volatile situations +BumpThreshold = 5 + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[HeadTracker] +# Polygon suffers from a tremendous number of re-orgs, we need to set this to something very large to be conservative enough +HistoryDepth = 2000 + +[NodePool] +SyncThreshold = 10 diff --git a/ccip/config/evm/Polygon_Zkevm_Cardona.toml b/ccip/config/evm/Polygon_Zkevm_Cardona.toml new file mode 100644 index 0000000000..cd91465dae --- /dev/null +++ b/ccip/config/evm/Polygon_Zkevm_Cardona.toml @@ -0,0 +1,24 @@ +ChainID = '2442' +ChainType = 'zkevm' +FinalityDepth = 500 +NoNewHeadsThreshold = '12m' +MinIncomingConfirmations = 1 +LogPollInterval = '30s' +RPCDefaultBatchSize = 100 + +[OCR] +ContractConfirmations = 1 + +[Transactions] +ResendAfterThreshold = '3m' + +[GasEstimator] +PriceMin = '1 mwei' +BumpPercent = 40 +BumpMin = '20 mwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 12 + +[HeadTracker] +HistoryDepth = 2000 diff --git a/ccip/config/evm/Polygon_Zkevm_Mainnet.toml b/ccip/config/evm/Polygon_Zkevm_Mainnet.toml new file mode 100644 index 0000000000..79e0cb0fce --- /dev/null +++ b/ccip/config/evm/Polygon_Zkevm_Mainnet.toml @@ -0,0 +1,26 @@ +ChainID = '1101' +ChainType = 'zkevm' +FinalityDepth = 500 +NoNewHeadsThreshold = '6m' +MinIncomingConfirmations = 1 +LogPollInterval = '30s' +RPCBlockQueryDelay = 15 +RPCDefaultBatchSize = 100 + +[OCR] +ContractConfirmations = 1 + +[Transactions] +ResendAfterThreshold = '3m' + +[GasEstimator] +PriceMin = '100 mwei' +BumpPercent = 40 +BumpMin = '100 mwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 12 + +[HeadTracker] +# Polygon suffers from a tremendous number of re-orgs, we need to set this to something very large to be conservative enough +HistoryDepth = 2000 diff --git a/ccip/config/evm/Scroll_Mainnet.toml b/ccip/config/evm/Scroll_Mainnet.toml new file mode 100644 index 0000000000..4a887b504d --- /dev/null +++ b/ccip/config/evm/Scroll_Mainnet.toml @@ -0,0 +1,22 @@ +ChainID = '534352' +FinalityDepth = 10 +FinalityTagEnabled = true +ChainType = 'scroll' +LogPollInterval = '5s' +MinIncomingConfirmations = 1 +# Scroll only emits blocks when a new tx is received, so this method of liveness detection is not useful +NoNewHeadsThreshold = '0' + +[GasEstimator] +EIP1559DynamicFees = true +PriceMin = '1 wei' +BumpMin = '1 gwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[HeadTracker] +HistoryDepth = 50 + +[OCR] +ContractConfirmations = 1 diff --git a/ccip/config/evm/Scroll_Sepolia.toml b/ccip/config/evm/Scroll_Sepolia.toml new file mode 100644 index 0000000000..b2e1cfbd73 --- /dev/null +++ b/ccip/config/evm/Scroll_Sepolia.toml @@ -0,0 +1,22 @@ +ChainID = '534351' +FinalityDepth = 10 +FinalityTagEnabled = true +ChainType = 'scroll' +LogPollInterval = '5s' +MinIncomingConfirmations = 1 +# Scroll only emits blocks when a new tx is received, so this method of liveness detection is not useful +NoNewHeadsThreshold = '0' + +[GasEstimator] +EIP1559DynamicFees = true +PriceMin = '1 wei' +BumpMin = '1 gwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[HeadTracker] +HistoryDepth = 50 + +[OCR] +ContractConfirmations = 1 diff --git a/ccip/config/evm/Simulated.toml b/ccip/config/evm/Simulated.toml new file mode 100644 index 0000000000..52e78c94ed --- /dev/null +++ b/ccip/config/evm/Simulated.toml @@ -0,0 +1,24 @@ +ChainID = '1337' +FinalityDepth = 10 +MinIncomingConfirmations = 1 +MinContractPayment = '100' +NoNewHeadsThreshold = '0s' + +[Transactions] +ReaperThreshold = '0s' +ResendAfterThreshold = '0s' + +[GasEstimator] +Mode = 'FixedPrice' +PriceMin = '0' +BumpThreshold = 0 +FeeCapDefault = '100 micro' +PriceMax = '100 micro' + +[HeadTracker] +HistoryDepth = 10 +MaxBufferSize = 100 +SamplingInterval = '0s' + +[OCR] +ContractConfirmations = 1 diff --git a/ccip/config/evm/WeMix_Mainnet.toml b/ccip/config/evm/WeMix_Mainnet.toml new file mode 100644 index 0000000000..7d3fcc6bc2 --- /dev/null +++ b/ccip/config/evm/WeMix_Mainnet.toml @@ -0,0 +1,16 @@ +ChainID = '1111' +ChainType = 'wemix' +FinalityDepth = 1 +FinalityTagEnabled = true +MinIncomingConfirmations = 1 +# WeMix emits a block every 1 second, regardless of transactions +LogPollInterval = '3s' +NoNewHeadsThreshold = '30s' +NoNewFinalizedHeadsThreshold = '40s' + +[OCR] +ContractConfirmations = 1 + +[GasEstimator] +EIP1559DynamicFees = true +TipCapDefault = '100 gwei' diff --git a/ccip/config/evm/WeMix_Testnet.toml b/ccip/config/evm/WeMix_Testnet.toml new file mode 100644 index 0000000000..5775097967 --- /dev/null +++ b/ccip/config/evm/WeMix_Testnet.toml @@ -0,0 +1,19 @@ +ChainID = '1112' +ChainType = 'wemix' +FinalityDepth = 1 +FinalityTagEnabled = true +MinIncomingConfirmations = 1 +# WeMix emits a block every 1 second, regardless of transactions +LogPollInterval = '3s' +NoNewHeadsThreshold = '30s' +NoNewFinalizedHeadsThreshold = '40s' + +[OCR] +ContractConfirmations = 1 + +[GasEstimator] +EIP1559DynamicFees = true +TipCapDefault = '100 gwei' + +[HeadTracker] +FinalityTagBypass = false diff --git a/ccip/config/evm/XLayer_Mainnet.toml b/ccip/config/evm/XLayer_Mainnet.toml new file mode 100644 index 0000000000..4096a4db24 --- /dev/null +++ b/ccip/config/evm/XLayer_Mainnet.toml @@ -0,0 +1,25 @@ +ChainID = '196' +ChainType = 'xlayer' +FinalityDepth = 500 +NoNewHeadsThreshold = '6m' +MinIncomingConfirmations = 1 +LogPollInterval = '30s' +RPCBlockQueryDelay = 15 +RPCDefaultBatchSize = 100 + +[OCR] +ContractConfirmations = 1 + +[Transactions] +ResendAfterThreshold = '3m' + +[GasEstimator] +PriceMin = '100 mwei' +BumpPercent = 40 +BumpMin = '100 mwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 12 + +[HeadTracker] +HistoryDepth = 2000 diff --git a/ccip/config/evm/XLayer_Sepolia.toml b/ccip/config/evm/XLayer_Sepolia.toml new file mode 100644 index 0000000000..62e2c1e8ad --- /dev/null +++ b/ccip/config/evm/XLayer_Sepolia.toml @@ -0,0 +1,25 @@ +ChainID = '195' +ChainType = 'xlayer' +FinalityDepth = 500 +NoNewHeadsThreshold = '12m' +MinIncomingConfirmations = 1 +LogPollInterval = '30s' +RPCBlockQueryDelay = 15 +RPCDefaultBatchSize = 100 + +[OCR] +ContractConfirmations = 1 + +[Transactions] +ResendAfterThreshold = '3m' + +[GasEstimator] +PriceMin = '1 mwei' +BumpPercent = 40 +BumpMin = '20 mwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 12 + +[HeadTracker] +HistoryDepth = 2000 diff --git a/ccip/config/evm/zkSync_Mainnet.toml b/ccip/config/evm/zkSync_Mainnet.toml new file mode 100644 index 0000000000..a434cd3815 --- /dev/null +++ b/ccip/config/evm/zkSync_Mainnet.toml @@ -0,0 +1,28 @@ +ChainID = '324' +ChainType = 'zksync' +# 1200block ~ 20min concurrent with the l1_committed tag +FinalityDepth = 1200 +# block rate is ~2-5sec, so this ensures blocks are polled correctly +LogPollInterval = '5s' +# sufficient time for RPC to be labelled out of sync, since blockRate is pretty fast +NoNewHeadsThreshold = '1m' + +[GasEstimator] +# no EIP1559 to ensure our estimator doesnot estimate gas with MaxPriorityFee which will break minFunding requirement +EIP1559DynamicFees = false +# high LimitDefault for worst case pubdata bytes with BatchGasLimit reduced to 4M in OCR2Config +LimitDefault = 2_500_000_000 +FeeCapDefault = '500 mwei' +PriceDefault = '25 mwei' +# p999 value for gasPrice based on historical data +PriceMax = '500 mwei' +# avg gasPrices are at 0.025 gwei +PriceMin = '25 mwei' + +[GasEstimator.BlockHistory] +# increasing this to smooth out gas estimation +BlockHistorySize = 200 + +[HeadTracker] +# tracks top N blocks to keep in heads database table. Should store atleast the same # of blocks as finalityDepth +HistoryDepth = 1500 \ No newline at end of file diff --git a/ccip/config/evm/zkSync_Sepolia.toml b/ccip/config/evm/zkSync_Sepolia.toml new file mode 100644 index 0000000000..f3bc594886 --- /dev/null +++ b/ccip/config/evm/zkSync_Sepolia.toml @@ -0,0 +1,28 @@ +ChainID = '300' +ChainType = 'zksync' +# 200block ~ 20min concurrent with the l1_committed tag +FinalityDepth = 200 +# block rate is ~2-5sec, so this ensures blocks are polled correctly +LogPollInterval = '5s' +# sufficient time for RPC to be labelled out of sync, since blockRate is pretty fast +NoNewHeadsThreshold = '1m' + +[GasEstimator] +# no EIP1559 to ensure our estimator doesnot estimate gas with MaxPriorityFee which will break minFunding requirement +EIP1559DynamicFees = false +# high LimitDefault for worst case pubdata bytes with BatchGasLimit reduced to 4M in OCR2Config +LimitDefault = 2_500_000_000 +FeeCapDefault = '500 mwei' +PriceDefault = '25 mwei' +# p999 value for gasPrice based on historical data +PriceMax = '500 mwei' +# avg gasPrices are at 0.025 gwei +PriceMin = '25 mwei' + +[GasEstimator.BlockHistory] +# increasing this to smooth out gas estimation +BlockHistorySize = 200 + +[HeadTracker] +# tracks top N blocks to keep in heads database table. Should store atleast the same # of blocks as finalityDepth +HistoryDepth = 250 \ No newline at end of file diff --git a/core/chainlink.goreleaser.Dockerfile b/core/chainlink.goreleaser.Dockerfile index c35fe015cb..c229ad488c 100644 --- a/core/chainlink.goreleaser.Dockerfile +++ b/core/chainlink.goreleaser.Dockerfile @@ -38,6 +38,11 @@ RUN chmod +x /usr/local/bin/ldd_fix RUN /usr/local/bin/ldd_fix RUN apt-get remove -y patchelf +# CCIP specific +COPY ./cci[p]/confi[g] /chainlink/ccip-config +ARG CL_CHAIN_DEFAULTS +ENV CL_CHAIN_DEFAULTS=${CL_CHAIN_DEFAULTS} + RUN if [ ${CHAINLINK_USER} != root ]; then \ useradd --uid 14933 --create-home ${CHAINLINK_USER}; \ fi From ec585d45658014028ff06e0bc7b2d11aed2e56ce Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Fri, 20 Sep 2024 12:31:34 -0400 Subject: [PATCH 393/432] devsvcs-514: update debugging script (#14502) --- core/scripts/chaincli/handler/debug.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/scripts/chaincli/handler/debug.go b/core/scripts/chaincli/handler/debug.go index eac3233ea5..79dfc5d018 100644 --- a/core/scripts/chaincli/handler/debug.go +++ b/core/scripts/chaincli/handler/debug.go @@ -43,7 +43,8 @@ import ( const ( ConditionTrigger uint8 = iota LogTrigger - expectedTypeAndVersion = "KeeperRegistry 2.1.0" + expectedVersion21 = "KeeperRegistry 2.1.0" + expectedVersion23 = "AutomationRegistry 2.3.0" ) var mercuryPacker = mercury.NewAbiPacker() @@ -85,8 +86,8 @@ func (k *Keeper) Debug(ctx context.Context, args []string) { if err != nil { failCheckConfig("failed to get typeAndVersion: make sure your registry contract address and archive node are valid", err) } - if typeAndVersion != expectedTypeAndVersion { - failCheckConfig(fmt.Sprintf("invalid registry contract: this command can only debug %s, got: %s", expectedTypeAndVersion, typeAndVersion), nil) + if typeAndVersion != expectedVersion21 && typeAndVersion != expectedVersion23 { + failCheckConfig(fmt.Sprintf("invalid registry contract: this command can only debug %s or %s, got: %s", expectedVersion21, expectedVersion23, typeAndVersion), nil) } // get upkeepID from command args upkeepID := big.NewInt(0) From 85a8d09845d6bd30f62b1de4bf8c62f3a77a6c8e Mon Sep 17 00:00:00 2001 From: Simson Date: Fri, 20 Sep 2024 23:31:52 +0530 Subject: [PATCH 394/432] Hedera int with TXM fixes & config (#14129) * re-changes on top of develop * Docs update * changeset * merged the error tests & Config fix * Apply suggestions from code review Co-authored-by: Jordan Krage * added newly found error * formatting * formatting * updated docs * Updating config to run with multiple RPCs * bump seth to v1.2.2 * updated configs --------- Co-authored-by: Jordan Krage Co-authored-by: davidcauchi --- .changeset/many-lamps-rush.md | 5 + core/chains/evm/client/errors.go | 12 +- core/chains/evm/client/errors_test.go | 7 + .../config/toml/defaults/Hedera_Mainnet.toml | 31 +++ .../config/toml/defaults/Hedera_Testnet.toml | 31 +++ docs/CONFIG.md | 204 ++++++++++++++++++ 6 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 .changeset/many-lamps-rush.md create mode 100644 core/chains/evm/config/toml/defaults/Hedera_Mainnet.toml create mode 100644 core/chains/evm/config/toml/defaults/Hedera_Testnet.toml diff --git a/.changeset/many-lamps-rush.md b/.changeset/many-lamps-rush.md new file mode 100644 index 0000000000..93d779aec9 --- /dev/null +++ b/.changeset/many-lamps-rush.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added Hedera configs diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index 6882cca524..ba13e1bfea 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -267,6 +267,16 @@ var mantle = ClientErrors{ Fatal: regexp.MustCompile(`(: |^)'*invalid sender`), } +var hederaFatal = regexp.MustCompile(`(: |^)(execution reverted)(:|$) | ^Transaction gas limit '(\d+)' exceeds block gas limit '(\d+)' | ^Transaction gas limit provided '(\d+)' is insufficient of intrinsic gas required '(\d+)' | ^Oversized data:|status INVALID_SIGNATURE`) +var hedera = ClientErrors{ + NonceTooLow: regexp.MustCompile(`Nonce too low`), + NonceTooHigh: regexp.MustCompile(`Nonce too high`), + TerminallyUnderpriced: regexp.MustCompile(`(Gas price '(\d+)' is below configured minimum gas price '(\d+)')|(Gas price too low)`), + InsufficientEth: regexp.MustCompile(`Insufficient funds for transfer| failed precheck with status INSUFFICIENT_PAYER_BALANCE`), + ServiceUnavailable: regexp.MustCompile(`Transaction execution returns a null value for transaction`), + Fatal: hederaFatal, +} + var gnosis = ClientErrors{ TransactionAlreadyInMempool: regexp.MustCompile(`(: |^)(alreadyknown)`), } @@ -278,7 +288,7 @@ var internal = ClientErrors{ TerminallyStuck: regexp.MustCompile(TerminallyStuckMsg), } -var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm, treasure, mantle, aStar, gnosis, internal} +var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm, treasure, mantle, aStar, hedera, gnosis, internal} // ClientErrorRegexes returns a map of compiled regexes for each error type func ClientErrorRegexes(errsRegex config.ClientErrors) *ClientErrors { diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index e647806091..84e518db66 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -46,6 +46,7 @@ func Test_Eth_Errors(t *testing.T) { {"call failed: OldNonce, Current nonce: 22, nonce of rejected tx: 17", true, "Nethermind"}, {"nonce too low. allowed nonce range: 427 - 447, actual: 426", true, "zkSync"}, {"client error nonce too low", true, "tomlConfig"}, + {"[Request ID: 2e952947-ffad-408b-aed9-35f3ed152001] Nonce too low. Provided nonce: 15, current nonce: 15", true, "hedera"}, } for _, test := range tests { @@ -67,6 +68,7 @@ func Test_Eth_Errors(t *testing.T) { {"nonce too high", true, "Erigon"}, {"nonce too high. allowed nonce range: 427 - 477, actual: 527", true, "zkSync"}, {"client error nonce too high", true, "tomlConfig"}, + {"[Request ID: 3ec591b4-9396-49f4-a03f-06c415a7cc6a] Nonce too high. Provided nonce: 16, current nonce: 15", true, "hedera"}, } for _, test := range tests { @@ -170,6 +172,7 @@ func Test_Eth_Errors(t *testing.T) { {"virtual machine entered unexpected state. please contact developers and provide transaction details that caused this error. Error description: The operator included transaction with an unacceptable gas price", true, "zkSync"}, {"client error terminally underpriced", true, "tomlConfig"}, {"gas price less than block base fee", true, "aStar"}, + {"[Request ID: e4d09e44-19a4-4eb7-babe-270db4c2ebc9] Gas price '830000000000' is below configured minimum gas price '950000000000'", true, "hedera"}, } for _, test := range tests { @@ -219,6 +222,8 @@ func Test_Eth_Errors(t *testing.T) { {"client error insufficient eth", true, "tomlConfig"}, {"transaction would cause overdraft", true, "Geth"}, {"failed to forward tx to sequencer, please try again. Error message: 'insufficient funds for gas * price + value'", true, "Mantle"}, + {"[Request ID: 9dd78806-58c8-4e6d-89a8-a60962abe705] Error invoking RPC: transaction 0.0.3041916@1717691931.680570179 failed precheck with status INSUFFICIENT_PAYER_BALANCE", true, "hedera"}, + {"[Request ID: 6198d2a3-590f-4724-aae5-69fecead0c49] Insufficient funds for transfer", true, "hedera"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) @@ -235,6 +240,7 @@ func Test_Eth_Errors(t *testing.T) { {"i/o timeout", true, "Arbitrum"}, {"network is unreachable", true, "Arbitrum"}, {"client error service unavailable", true, "tomlConfig"}, + {"[Request ID: 825608a8-fd8a-4b5b-aea7-92999509306d] Error invoking RPC: [Request ID: 825608a8-fd8a-4b5b-aea7-92999509306d] Transaction execution returns a null value for transaction", true, "hedera"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) @@ -409,6 +415,7 @@ func Test_Eth_Errors_Fatal(t *testing.T) { {"failed to forward tx to sequencer, please try again. Error message: 'invalid sender'", true, "Mantle"}, {"client error fatal", true, "tomlConfig"}, + {"[Request ID: d9711488-4c1e-4af2-bc1f-7969913d7b60] Error invoking RPC: transaction 0.0.4425573@1718213476.914320044 failed precheck with status INVALID_SIGNATURE", true, "hedera"}, {"invalid chain id for signer", true, "Treasure"}, } diff --git a/core/chains/evm/config/toml/defaults/Hedera_Mainnet.toml b/core/chains/evm/config/toml/defaults/Hedera_Mainnet.toml new file mode 100644 index 0000000000..4d5e48816f --- /dev/null +++ b/core/chains/evm/config/toml/defaults/Hedera_Mainnet.toml @@ -0,0 +1,31 @@ +ChainID = '295' +ChainType = 'hedera' +# Considering the 3-5 (6 including a buffer) seconds of finality and 2 seconds block production +# We set the depth to 6/2 = 3 blocks, setting to 10 for safety +FinalityDepth = 10 +# Hedera has high TPS, so polling less often +LogPollInterval = '10s' +MinIncomingConfirmations = 1 + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'SuggestedPrice' +# Since Hedera dont have mempool and there's no way for a node to front run or a user to bribe a node to submit the transaction earlier than it's consensus timestamp, +# But they have automated congesting pricing throttling which would mean at high sustained level the gasPrice itself could be increased to prevent malicious behaviour. +# Disabling the Bumpthreshold as TXM now implicity handles the bumping after checking on-chain nonce & re-broadcast for Hedera chain type +BumpThreshold = 0 +BumpMin = '10 gwei' +BumpPercent = 20 + +[Transactions] +# To hit throttling you'd need to maintain 15 m gas /sec over a prolonged period of time. +# Because Hedera's block times are every 2 secs it's less less likely to happen as compared to other chains +# Setting this to little higher even though Hedera has High TPS, We have seen 10-12s to get the trasaction mined & 20-25s incase of failures +# Accounting for Node syncs & avoid re-sending txns before fetching the receipt, setting to 2m +ResendAfterThreshold = '2m' + + +[NodePool] +SyncThreshold = 10 \ No newline at end of file diff --git a/core/chains/evm/config/toml/defaults/Hedera_Testnet.toml b/core/chains/evm/config/toml/defaults/Hedera_Testnet.toml new file mode 100644 index 0000000000..6086a43af2 --- /dev/null +++ b/core/chains/evm/config/toml/defaults/Hedera_Testnet.toml @@ -0,0 +1,31 @@ +ChainID = '296' +ChainType = 'hedera' +# Considering the 3-5 (6 including a buffer) seconds of finality and 2 seconds block production +# We set the depth to 6/2 = 3 blocks, setting to 10 for safety +FinalityDepth = 10 +# Hedera has high TPS, so polling less often +LogPollInterval = '10s' +MinIncomingConfirmations = 1 + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'SuggestedPrice' +# Since Hedera dont have mempool and there's no way for a node to front run or a user to bribe a node to submit the transaction earlier than it's consensus timestamp, +# But they have automated congesting pricing throttling which would mean at high sustained level the gasPrice itself could be increased to prevent malicious behaviour. +# Disabling the Bumpthreshold as TXM now implicity handles the bumping after checking on-chain nonce & re-broadcast for Hedera chain type +BumpThreshold = 0 +BumpMin = '10 gwei' +BumpPercent = 20 + +[Transactions] +# To hit throttling you'd need to maintain 15 m gas /sec over a prolonged period of time. +# Because Hedera's block times are every 2 secs it's less less likely to happen as compared to other chains +# Setting this to little higher even though Hedera has High TPS, We have seen 10-12s to get the trasaction mined & 20-25s incase of failures +# Accounting for Node syncs & avoid re-sending txns before fetching the receipt, setting to 2m +ResendAfterThreshold = '2m' + + +[NodePool] +SyncThreshold = 10 \ No newline at end of file diff --git a/docs/CONFIG.md b/docs/CONFIG.md index c9262577f1..c3eeaac282 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -4000,6 +4000,210 @@ GasLimitDefault = 400000

    +
    Hedera Mainnet (295)

    + +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +ChainType = 'hedera' +FinalityDepth = 10 +FinalityTagEnabled = false +LogBackfillBatchSize = 1000 +LogPollInterval = '10s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 1 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 +FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '2m0s' + +[Transactions.AutoPurge] +Enabled = false + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'SuggestedPrice' +PriceDefault = '20 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '1 gwei' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +EstimateLimit = false +BumpMin = '10 gwei' +BumpPercent = 20 +BumpThreshold = 0 +EIP1559DynamicFees = false +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 8 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + +[HeadTracker] +HistoryDepth = 100 +MaxBufferSize = 3 +SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 10 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false +FinalizedBlockPollInterval = '5s' +EnforceRepeatableRead = false +DeathDeclarationDelay = '10s' + +[OCR] +ContractConfirmations = 4 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 +``` + +

    + +
    Hedera Testnet (296)

    + +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +ChainType = 'hedera' +FinalityDepth = 10 +FinalityTagEnabled = false +LogBackfillBatchSize = 1000 +LogPollInterval = '10s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 1 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 +FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '2m0s' + +[Transactions.AutoPurge] +Enabled = false + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'SuggestedPrice' +PriceDefault = '20 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '1 gwei' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +EstimateLimit = false +BumpMin = '10 gwei' +BumpPercent = 20 +BumpThreshold = 0 +EIP1559DynamicFees = false +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 8 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + +[HeadTracker] +HistoryDepth = 100 +MaxBufferSize = 3 +SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 10 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false +FinalizedBlockPollInterval = '5s' +EnforceRepeatableRead = false +DeathDeclarationDelay = '10s' + +[OCR] +ContractConfirmations = 4 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 +``` + +

    +
    zkSync Sepolia (300)

    ```toml From 10f7aabc2972615cae4edd8f3532ad6aea521cee Mon Sep 17 00:00:00 2001 From: Austin Born Date: Fri, 20 Sep 2024 11:31:07 -0700 Subject: [PATCH 395/432] DF-20372 (pt 2): Update Streams PluginConfig checks and FeedID parsing (#14504) * Update Streams PluginConfig checks and FeedID parsing * Update changeset comment * Linting fixes * Update v4/data_source_test.go * Pull out duplicate code into helper --- .changeset/thirty-emus-enjoy.md | 7 +++ core/services/ocr2/delegate.go | 4 +- core/services/ocr2/plugins/mercury/plugin.go | 30 +++++++--- core/services/ocr2/validate/validate.go | 2 +- .../services/relay/evm/mercury/utils/feeds.go | 3 + .../relay/evm/mercury/utils/feeds_test.go | 55 +++++++++++++------ .../relay/evm/mercury/v2/data_source.go | 12 +--- .../relay/evm/mercury/v2/data_source_test.go | 4 +- .../relay/evm/mercury/v3/data_source.go | 12 +--- .../relay/evm/mercury/v3/data_source_test.go | 4 +- .../relay/evm/mercury/v4/data_source.go | 8 ++- .../relay/evm/mercury/v4/data_source_test.go | 31 ++++++++++- 12 files changed, 118 insertions(+), 54 deletions(-) create mode 100644 .changeset/thirty-emus-enjoy.md diff --git a/.changeset/thirty-emus-enjoy.md b/.changeset/thirty-emus-enjoy.md new file mode 100644 index 0000000000..4fbe030ec5 --- /dev/null +++ b/.changeset/thirty-emus-enjoy.md @@ -0,0 +1,7 @@ +--- +"chainlink": minor +--- + +#bugfix Fix potential nil ptr reference for LinkFeedID and NativeFeedID in Mercury specs +#bugfix Ensure Streams PluginConfig is checked for contents correctly when validated +#changed New Feed IDs with 0x01 prefix can be parsed for Mercury report schemas diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 9d4dbb8598..b51765f06f 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -889,10 +889,10 @@ func (d *Delegate) newServicesMercury( } var telemetryType synchronization.TelemetryType - if relayConfig.EnableTriggerCapability && jb.OCR2OracleSpec.PluginConfig == nil { + if relayConfig.EnableTriggerCapability && len(jb.OCR2OracleSpec.PluginConfig) == 0 { telemetryType = synchronization.OCR3DataFeeds // First use case for TriggerCapability transmission is Data Feeds, so telemetry should be routed accordingly. - // This is only true if TriggerCapability is the *only* transmission method (PluginConfig == nil). + // This is only true if TriggerCapability is the *only* transmission method (PluginConfig is empty). } else { telemetryType = synchronization.OCR3Mercury } diff --git a/core/services/ocr2/plugins/mercury/plugin.go b/core/services/ocr2/plugins/mercury/plugin.go index f78531d6b0..8a4101804d 100644 --- a/core/services/ocr2/plugins/mercury/plugin.go +++ b/core/services/ocr2/plugins/mercury/plugin.go @@ -81,7 +81,7 @@ func NewServices( var err error var pluginConfig config.PluginConfig - if jb.OCR2OracleSpec.PluginConfig == nil { + if len(jb.OCR2OracleSpec.PluginConfig) == 0 { if !enableTriggerCapability { return nil, fmt.Errorf("at least one transmission option must be configured") } @@ -180,10 +180,22 @@ type factoryCfg struct { feedID utils.FeedID } +func getPluginFeedIDs(pluginConfig config.PluginConfig) (linkFeedID utils.FeedID, nativeFeedID utils.FeedID) { + if pluginConfig.LinkFeedID != nil { + linkFeedID = *pluginConfig.LinkFeedID + } + if pluginConfig.NativeFeedID != nil { + nativeFeedID = *pluginConfig.NativeFeedID + } + return linkFeedID, nativeFeedID +} + func newv4factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job.ServiceCtx, error) { var factory ocr3types.MercuryPluginFactory srvs := make([]job.ServiceCtx, 0) + linkFeedID, nativeFeedID := getPluginFeedIDs(factoryCfg.reportingPluginConfig) + ds := mercuryv4.NewDataSource( factoryCfg.orm, factoryCfg.pipelineRunner, @@ -194,8 +206,8 @@ func newv4factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job. factoryCfg.saver, factoryCfg.chEnhancedTelem, factoryCfg.ocr2Provider.MercuryServerFetcher(), - *factoryCfg.reportingPluginConfig.LinkFeedID, - *factoryCfg.reportingPluginConfig.NativeFeedID, + linkFeedID, + nativeFeedID, ) loopCmd := env.MercuryPlugin.Cmd.Get() @@ -221,6 +233,8 @@ func newv3factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job. var factory ocr3types.MercuryPluginFactory srvs := make([]job.ServiceCtx, 0) + linkFeedID, nativeFeedID := getPluginFeedIDs(factoryCfg.reportingPluginConfig) + ds := mercuryv3.NewDataSource( factoryCfg.orm, factoryCfg.pipelineRunner, @@ -231,8 +245,8 @@ func newv3factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job. factoryCfg.saver, factoryCfg.chEnhancedTelem, factoryCfg.ocr2Provider.MercuryServerFetcher(), - *factoryCfg.reportingPluginConfig.LinkFeedID, - *factoryCfg.reportingPluginConfig.NativeFeedID, + linkFeedID, + nativeFeedID, ) loopCmd := env.MercuryPlugin.Cmd.Get() @@ -258,6 +272,8 @@ func newv2factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job. var factory ocr3types.MercuryPluginFactory srvs := make([]job.ServiceCtx, 0) + linkFeedID, nativeFeedID := getPluginFeedIDs(factoryCfg.reportingPluginConfig) + ds := mercuryv2.NewDataSource( factoryCfg.orm, factoryCfg.pipelineRunner, @@ -268,8 +284,8 @@ func newv2factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job. factoryCfg.saver, factoryCfg.chEnhancedTelem, factoryCfg.ocr2Provider.MercuryServerFetcher(), - *factoryCfg.reportingPluginConfig.LinkFeedID, - *factoryCfg.reportingPluginConfig.NativeFeedID, + linkFeedID, + nativeFeedID, ) loopCmd := env.MercuryPlugin.Cmd.Get() diff --git a/core/services/ocr2/validate/validate.go b/core/services/ocr2/validate/validate.go index 09b974d4e3..7ea34e5ac2 100644 --- a/core/services/ocr2/validate/validate.go +++ b/core/services/ocr2/validate/validate.go @@ -304,7 +304,7 @@ func validateOCR2MercurySpec(spec *job.OCR2OracleSpec, feedID [32]byte) error { return pkgerrors.Wrap(err, "error while unmarshalling relay config") } - if spec.PluginConfig == nil { + if len(spec.PluginConfig) == 0 { if !relayConfig.EnableTriggerCapability { return pkgerrors.Wrap(err, "at least one transmission option must be configured") } diff --git a/core/services/relay/evm/mercury/utils/feeds.go b/core/services/relay/evm/mercury/utils/feeds.go index 36d6bc60f5..eb4f685022 100644 --- a/core/services/relay/evm/mercury/utils/feeds.go +++ b/core/services/relay/evm/mercury/utils/feeds.go @@ -104,7 +104,10 @@ func (f *FeedID) UnmarshalText(input []byte) error { func (f FeedID) Version() FeedVersion { if _, exists := legacyV1FeedIDM[f]; exists { return REPORT_V1 + } else if f[0] == 0x01 { // Keystone Feed IDs + return FeedVersion(binary.BigEndian.Uint16(f[5:7])) } + return FeedVersion(binary.BigEndian.Uint16(f[:2])) } diff --git a/core/services/relay/evm/mercury/utils/feeds_test.go b/core/services/relay/evm/mercury/utils/feeds_test.go index 37b9b47de7..d6db7a4a8c 100644 --- a/core/services/relay/evm/mercury/utils/feeds_test.go +++ b/core/services/relay/evm/mercury/utils/feeds_test.go @@ -7,27 +7,48 @@ import ( ) var ( - v1FeedId = (FeedID)([32]uint8{00, 01, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}) - v2FeedId = (FeedID)([32]uint8{00, 02, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}) - v3FeedId = (FeedID)([32]uint8{00, 03, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}) + v1FeedID = (FeedID)([32]uint8{00, 01, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}) + v2FeedID = (FeedID)([32]uint8{00, 02, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}) + v3FeedID = (FeedID)([32]uint8{00, 03, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}) + keystonev2Feed = (FeedID)([32]uint8{01, 12, 34, 56, 78, 00, 02, 04, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}) + keystonev3Feed = (FeedID)([32]uint8{01, 12, 34, 56, 78, 00, 03, 04, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}) + keystonev4Feed = (FeedID)([32]uint8{01, 12, 34, 56, 78, 00, 04, 04, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}) ) func Test_FeedID_Version(t *testing.T) { t.Run("versioned feed ID", func(t *testing.T) { - assert.Equal(t, REPORT_V1, v1FeedId.Version()) - assert.True(t, v1FeedId.IsV1()) - assert.False(t, v1FeedId.IsV2()) - assert.False(t, v1FeedId.IsV3()) - - assert.Equal(t, REPORT_V2, v2FeedId.Version()) - assert.False(t, v2FeedId.IsV1()) - assert.True(t, v2FeedId.IsV2()) - assert.False(t, v2FeedId.IsV3()) - - assert.Equal(t, REPORT_V3, v3FeedId.Version()) - assert.False(t, v3FeedId.IsV1()) - assert.False(t, v3FeedId.IsV2()) - assert.True(t, v3FeedId.IsV3()) + assert.Equal(t, REPORT_V1, v1FeedID.Version()) + assert.True(t, v1FeedID.IsV1()) + assert.False(t, v1FeedID.IsV2()) + assert.False(t, v1FeedID.IsV3()) + + assert.Equal(t, REPORT_V2, v2FeedID.Version()) + assert.False(t, v2FeedID.IsV1()) + assert.True(t, v2FeedID.IsV2()) + assert.False(t, v2FeedID.IsV3()) + + assert.Equal(t, REPORT_V3, v3FeedID.Version()) + assert.False(t, v3FeedID.IsV1()) + assert.False(t, v3FeedID.IsV2()) + assert.True(t, v3FeedID.IsV3()) + + assert.Equal(t, REPORT_V2, keystonev2Feed.Version()) + assert.False(t, keystonev2Feed.IsV1()) + assert.True(t, keystonev2Feed.IsV2()) + assert.False(t, keystonev2Feed.IsV3()) + assert.False(t, keystonev2Feed.IsV4()) + + assert.Equal(t, REPORT_V3, keystonev3Feed.Version()) + assert.False(t, keystonev3Feed.IsV1()) + assert.False(t, keystonev3Feed.IsV2()) + assert.True(t, keystonev3Feed.IsV3()) + assert.False(t, keystonev3Feed.IsV4()) + + assert.Equal(t, REPORT_V4, keystonev4Feed.Version()) + assert.False(t, keystonev4Feed.IsV1()) + assert.False(t, keystonev4Feed.IsV2()) + assert.False(t, keystonev4Feed.IsV3()) + assert.True(t, keystonev4Feed.IsV4()) }) t.Run("legacy special cases", func(t *testing.T) { for _, feedID := range legacyV1FeedIDs { diff --git a/core/services/relay/evm/mercury/v2/data_source.go b/core/services/relay/evm/mercury/v2/data_source.go index d05bd00e25..fed748ac93 100644 --- a/core/services/relay/evm/mercury/v2/data_source.go +++ b/core/services/relay/evm/mercury/v2/data_source.go @@ -2,7 +2,6 @@ package v2 import ( "context" - "encoding/json" "fmt" "math/big" "sync" @@ -23,7 +22,6 @@ import ( mercurytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types" mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/reportcodec" - relayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -63,12 +61,6 @@ func NewDataSource(orm types.DataSourceORM, pr pipeline.Runner, jb job.Job, spec func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp, fetchMaxFinalizedTimestamp bool) (obs v2types.Observation, pipelineExecutionErr error) { var wg sync.WaitGroup - var relayConfig relayTypes.RelayConfig - err := json.Unmarshal(ds.jb.OCR2OracleSpec.RelayConfig.Bytes(), &relayConfig) - if err != nil { - pipelineExecutionErr = fmt.Errorf("failed to deserialize relay config: %w", err) - return - } ctx, cancel := context.WithCancel(ctx) if fetchMaxFinalizedTimestamp { @@ -116,7 +108,7 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam }() var isLink, isNative bool - if ds.jb.OCR2OracleSpec.PluginConfig == nil { + if len(ds.jb.OCR2OracleSpec.PluginConfig) == 0 { obs.LinkPrice.Val = v2.MissingPrice } else if ds.feedID == ds.linkFeedID { isLink = true @@ -136,7 +128,7 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam }() } - if ds.jb.OCR2OracleSpec.PluginConfig == nil { + if len(ds.jb.OCR2OracleSpec.PluginConfig) == 0 { obs.NativePrice.Val = v2.MissingPrice } else if ds.feedID == ds.nativeFeedID { isNative = true diff --git a/core/services/relay/evm/mercury/v2/data_source_test.go b/core/services/relay/evm/mercury/v2/data_source_test.go index 7392ceb986..25716521d8 100644 --- a/core/services/relay/evm/mercury/v2/data_source_test.go +++ b/core/services/relay/evm/mercury/v2/data_source_test.go @@ -284,7 +284,7 @@ func Test_Datasource(t *testing.T) { assert.EqualError(t, obs.NativePrice.Err, "some error fetching native price") }) - t.Run("when PluginConfig=nil skips fetching link and native prices", func(t *testing.T) { + t.Run("when PluginConfig is empty", func(t *testing.T) { t.Cleanup(func() { ds.jb = jb }) @@ -292,7 +292,7 @@ func Test_Datasource(t *testing.T) { fetcher.linkPriceErr = errors.New("some error fetching link price") fetcher.nativePriceErr = errors.New("some error fetching native price") - ds.jb.OCR2OracleSpec.PluginConfig = nil + ds.jb.OCR2OracleSpec.PluginConfig = job.JSONConfig{} obs, err := ds.Observe(ctx, repts, false) assert.NoError(t, err) diff --git a/core/services/relay/evm/mercury/v3/data_source.go b/core/services/relay/evm/mercury/v3/data_source.go index 48db946517..9744ec45d8 100644 --- a/core/services/relay/evm/mercury/v3/data_source.go +++ b/core/services/relay/evm/mercury/v3/data_source.go @@ -2,7 +2,6 @@ package v3 import ( "context" - "encoding/json" "errors" "fmt" "math/big" @@ -23,7 +22,6 @@ import ( mercurytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types" mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" - relayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -65,12 +63,6 @@ func NewDataSource(orm types.DataSourceORM, pr pipeline.Runner, jb job.Job, spec func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp, fetchMaxFinalizedTimestamp bool) (obs v3types.Observation, pipelineExecutionErr error) { var wg sync.WaitGroup - var relayConfig relayTypes.RelayConfig - err := json.Unmarshal(ds.jb.OCR2OracleSpec.RelayConfig.Bytes(), &relayConfig) - if err != nil { - pipelineExecutionErr = fmt.Errorf("failed to deserialize relay config: %w", err) - return - } ctx, cancel := context.WithCancel(ctx) if fetchMaxFinalizedTimestamp { @@ -120,7 +112,7 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam }() var isLink, isNative bool - if ds.jb.OCR2OracleSpec.PluginConfig == nil { + if len(ds.jb.OCR2OracleSpec.PluginConfig) == 0 { obs.LinkPrice.Val = v3.MissingPrice } else if ds.feedID == ds.linkFeedID { isLink = true @@ -140,7 +132,7 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam }() } - if ds.jb.OCR2OracleSpec.PluginConfig == nil { + if len(ds.jb.OCR2OracleSpec.PluginConfig) == 0 { obs.NativePrice.Val = v3.MissingPrice } else if ds.feedID == ds.nativeFeedID { isNative = true diff --git a/core/services/relay/evm/mercury/v3/data_source_test.go b/core/services/relay/evm/mercury/v3/data_source_test.go index 3d01d7472e..518fabb12c 100644 --- a/core/services/relay/evm/mercury/v3/data_source_test.go +++ b/core/services/relay/evm/mercury/v3/data_source_test.go @@ -364,7 +364,7 @@ func Test_Datasource(t *testing.T) { assert.EqualError(t, obs.NativePrice.Err, "some error fetching native price") }) - t.Run("when PluginConfig=nil skips fetching link and native prices", func(t *testing.T) { + t.Run("when PluginConfig is empty", func(t *testing.T) { t.Cleanup(func() { ds.jb = jb }) @@ -372,7 +372,7 @@ func Test_Datasource(t *testing.T) { fetcher.linkPriceErr = errors.New("some error fetching link price") fetcher.nativePriceErr = errors.New("some error fetching native price") - ds.jb.OCR2OracleSpec.PluginConfig = nil + ds.jb.OCR2OracleSpec.PluginConfig = job.JSONConfig{} obs, err := ds.Observe(ctx, repts, false) assert.NoError(t, err) diff --git a/core/services/relay/evm/mercury/v4/data_source.go b/core/services/relay/evm/mercury/v4/data_source.go index 05ec44dc78..bf45ccc87f 100644 --- a/core/services/relay/evm/mercury/v4/data_source.go +++ b/core/services/relay/evm/mercury/v4/data_source.go @@ -108,7 +108,9 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam }() var isLink, isNative bool - if ds.feedID == ds.linkFeedID { + if len(ds.jb.OCR2OracleSpec.PluginConfig) == 0 { + obs.LinkPrice.Val = v4.MissingPrice + } else if ds.feedID == ds.linkFeedID { isLink = true } else { wg.Add(1) @@ -126,7 +128,9 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam }() } - if ds.feedID == ds.nativeFeedID { + if len(ds.jb.OCR2OracleSpec.PluginConfig) == 0 { + obs.NativePrice.Val = v4.MissingPrice + } else if ds.feedID == ds.nativeFeedID { isNative = true } else { wg.Add(1) diff --git a/core/services/relay/evm/mercury/v4/data_source_test.go b/core/services/relay/evm/mercury/v4/data_source_test.go index 7b50a922c8..48aec5989a 100644 --- a/core/services/relay/evm/mercury/v4/data_source_test.go +++ b/core/services/relay/evm/mercury/v4/data_source_test.go @@ -13,6 +13,7 @@ import ( relaymercuryv4 "github.com/smartcontractkit/chainlink-data-streams/mercury/v4" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" mercurymocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" @@ -70,7 +71,16 @@ func (ms *mockSaver) Save(r *pipeline.Run) { func Test_Datasource(t *testing.T) { orm := &mockORM{} - ds := &datasource{orm: orm, lggr: logger.TestLogger(t)} + jb := job.Job{ + Type: job.Type(pipeline.OffchainReporting2JobType), + OCR2OracleSpec: &job.OCR2OracleSpec{ + CaptureEATelemetry: true, + PluginConfig: map[string]interface{}{ + "serverURL": "a", + }, + }, + } + ds := &datasource{orm: orm, lggr: logger.TestLogger(t), jb: jb} ctx := testutils.Context(t) repts := ocrtypes.ReportTimestamp{} @@ -286,6 +296,25 @@ func Test_Datasource(t *testing.T) { assert.EqualError(t, obs.NativePrice.Err, "some error fetching native price") }) + t.Run("when PluginConfig is empty", func(t *testing.T) { + t.Cleanup(func() { + ds.jb = jb + }) + + fetcher.linkPriceErr = errors.New("some error fetching link price") + fetcher.nativePriceErr = errors.New("some error fetching native price") + + ds.jb.OCR2OracleSpec.PluginConfig = job.JSONConfig{} + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + assert.Nil(t, obs.LinkPrice.Err) + assert.Equal(t, obs.LinkPrice.Val, relaymercuryv4.MissingPrice) + assert.Nil(t, obs.NativePrice.Err) + assert.Equal(t, obs.NativePrice.Val, relaymercuryv4.MissingPrice) + assert.Equal(t, big.NewInt(122), obs.BenchmarkPrice.Val) + }) + t.Run("when succeeds to fetch linkPrice or nativePrice but got nil (new feed)", func(t *testing.T) { obs, err := ds.Observe(ctx, repts, false) assert.NoError(t, err) From 674605ea505f4cc98ddd35791583b73b32382ec6 Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:57:42 -0700 Subject: [PATCH 396/432] Ccip-3398 populate state initial PR (#14391) * initial draft * individual snapshot * change interface name * changes * add all destchainselectors * rmn details * more changes * omitempty * add onRamp reader * changes * format errors * add Feequoter * change approach direct go-binding reference * fix import cycle * moduler * fix panic * add interface for snapshot * more changes * rename * fix lint * more review comments * fix rmnremote version * one more fix --------- Co-authored-by: Oliver Townsend --- integration-tests/deployment/ccip/deploy.go | 2 +- .../deployment/ccip/deploy_test.go | 2 +- integration-tests/deployment/ccip/state.go | 172 ++++++++---------- .../deployment/ccip/view/chain.go | 27 +++ .../deployment/ccip/view/state.go | 11 ++ .../ccip/view/types/contract_state.go | 33 ++++ .../deployment/ccip/view/v1_2/router.go | 56 ++++++ .../ccip/view/v1_5/tokenadminregistry.go | 30 +++ .../deployment/ccip/view/v1_6/feequoter.go | 153 ++++++++++++++++ .../deployment/ccip/view/v1_6/noncemanager.go | 31 ++++ .../deployment/ccip/view/v1_6/onramp.go | 106 +++++++++++ .../deployment/ccip/view/v1_6/rmnremote.go | 54 ++++++ 12 files changed, 579 insertions(+), 98 deletions(-) create mode 100644 integration-tests/deployment/ccip/view/chain.go create mode 100644 integration-tests/deployment/ccip/view/state.go create mode 100644 integration-tests/deployment/ccip/view/types/contract_state.go create mode 100644 integration-tests/deployment/ccip/view/v1_2/router.go create mode 100644 integration-tests/deployment/ccip/view/v1_5/tokenadminregistry.go create mode 100644 integration-tests/deployment/ccip/view/v1_6/feequoter.go create mode 100644 integration-tests/deployment/ccip/view/v1_6/noncemanager.go create mode 100644 integration-tests/deployment/ccip/view/v1_6/onramp.go create mode 100644 integration-tests/deployment/ccip/view/v1_6/rmnremote.go diff --git a/integration-tests/deployment/ccip/deploy.go b/integration-tests/deployment/ccip/deploy.go index f0641b6516..358a72bad1 100644 --- a/integration-tests/deployment/ccip/deploy.go +++ b/integration-tests/deployment/ccip/deploy.go @@ -248,7 +248,7 @@ func DeployChainContracts( chain.Selector, ) return ContractDeploy[*rmn_remote.RMNRemote]{ - rmnRemoteAddr, rmnRemote, tx, deployment.NewTypeAndVersion(RMNRemote, deployment.Version1_0_0), err2, + rmnRemoteAddr, rmnRemote, tx, deployment.NewTypeAndVersion(RMNRemote, deployment.Version1_6_0_dev), err2, } }) if err != nil { diff --git a/integration-tests/deployment/ccip/deploy_test.go b/integration-tests/deployment/ccip/deploy_test.go index db739f6413..a278f29842 100644 --- a/integration-tests/deployment/ccip/deploy_test.go +++ b/integration-tests/deployment/ccip/deploy_test.go @@ -51,7 +51,7 @@ func TestDeployCCIPContracts(t *testing.T) { require.NoError(t, err) state, err := LoadOnchainState(e, ab) require.NoError(t, err) - snap, err := state.Snapshot(e.AllChainSelectors()) + snap, err := state.View(e.AllChainSelectors()) require.NoError(t, err) // Assert expect every deployed address to be in the address book. diff --git a/integration-tests/deployment/ccip/state.go b/integration-tests/deployment/ccip/state.go index d32c51ae65..d6bd889439 100644 --- a/integration-tests/deployment/ccip/state.go +++ b/integration-tests/deployment/ccip/state.go @@ -11,11 +11,19 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/deployment" - owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/tools/gethwrappers" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_2" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_5" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_6" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" + + owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/tools/gethwrappers" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" @@ -25,8 +33,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" ) type CCIPChainState struct { @@ -61,6 +67,58 @@ type CCIPChainState struct { TestRouter *router.Router } +func (c CCIPChainState) GenerateView() (view.ChainView, error) { + chainView := view.NewChain() + if c.Router != nil { + routerView, err := v1_2.GenerateRouterView(c.Router) + if err != nil { + return chainView, err + } + chainView.Router[c.Router.Address().Hex()] = routerView + } + if c.TokenAdminRegistry != nil { + taView, err := v1_5.GenerateTokenAdminRegistryView(c.TokenAdminRegistry) + if err != nil { + return chainView, err + } + chainView.TokenAdminRegistry[c.TokenAdminRegistry.Address().Hex()] = taView + } + if c.NonceManager != nil { + nmView, err := v1_6.GenerateNonceManagerView(c.NonceManager) + if err != nil { + return chainView, err + } + chainView.NonceManager[c.NonceManager.Address().Hex()] = nmView + } + if c.RMNRemote != nil { + rmnView, err := v1_6.GenerateRMNRemoteView(c.RMNRemote) + if err != nil { + return chainView, err + } + chainView.RMN[c.RMNRemote.Address().Hex()] = rmnView + } + if c.FeeQuoter != nil && c.Router != nil && c.TokenAdminRegistry != nil { + fqView, err := v1_6.GenerateFeeQuoterView(c.FeeQuoter, c.Router, c.TokenAdminRegistry) + if err != nil { + return chainView, err + } + chainView.FeeQuoter[c.FeeQuoter.Address().Hex()] = fqView + } + + if c.OnRamp != nil && c.Router != nil && c.TokenAdminRegistry != nil { + onRampView, err := v1_6.GenerateOnRampView( + c.OnRamp, + c.Router, + c.TokenAdminRegistry, + ) + if err != nil { + return chainView, err + } + chainView.OnRamp[c.OnRamp.Address().Hex()] = onRampView + } + return chainView, nil +} + // Onchain state always derivable from an address book. // Offchain state always derivable from a list of nodeIds. // Note can translate this into Go struct needed for MCMS/Docs/UI. @@ -71,115 +129,37 @@ type CCIPOnChainState struct { Chains map[uint64]CCIPChainState } -type CCIPSnapShot struct { - Chains map[string]Chain `json:"chains"` -} - -type Contract struct { - TypeAndVersion string `json:"typeAndVersion"` - Address common.Address `json:"address"` -} - -type TokenAdminRegistryView struct { - Contract - Tokens []common.Address `json:"tokens"` -} - -type NonceManagerView struct { - Contract - AuthorizedCallers []common.Address `json:"authorizedCallers"` -} - -type Chain struct { - // TODO: this will have to be versioned for getting state during upgrades. - TokenAdminRegistry TokenAdminRegistryView `json:"tokenAdminRegistry"` - NonceManager NonceManagerView `json:"nonceManager"` -} - -func (s CCIPOnChainState) Snapshot(chains []uint64) (CCIPSnapShot, error) { - snapshot := CCIPSnapShot{ - Chains: make(map[string]Chain), - } +func (s CCIPOnChainState) View(chains []uint64) (view.CCIPView, error) { + ccipView := view.NewCCIPView() for _, chainSelector := range chains { // TODO: Need a utility for this chainid, err := chainsel.ChainIdFromSelector(chainSelector) if err != nil { - return snapshot, err + return ccipView, err } chainName, err := chainsel.NameFromChainId(chainid) if err != nil { - return snapshot, err + return ccipView, err } if _, ok := s.Chains[chainSelector]; !ok { - return snapshot, fmt.Errorf("chain not supported %d", chainSelector) + return ccipView, fmt.Errorf("chain not supported %d", chainSelector) } - var c Chain - ta := s.Chains[chainSelector].TokenAdminRegistry - if ta != nil { - tokens, err := ta.GetAllConfiguredTokens(nil, 0, 10) - if err != nil { - return snapshot, err - } - tv, err := ta.TypeAndVersion(nil) - if err != nil { - return snapshot, err - } - c.TokenAdminRegistry = TokenAdminRegistryView{ - Contract: Contract{ - TypeAndVersion: tv, - Address: ta.Address(), - }, - Tokens: tokens, - } - } - nm := s.Chains[chainSelector].NonceManager - if nm != nil { - authorizedCallers, err := nm.GetAllAuthorizedCallers(nil) - if err != nil { - return snapshot, err - } - tv, err := nm.TypeAndVersion(nil) - if err != nil { - return snapshot, err - } - c.NonceManager = NonceManagerView{ - Contract: Contract{ - TypeAndVersion: tv, - Address: nm.Address(), - }, - // TODO: these can be resolved using an address book - AuthorizedCallers: authorizedCallers, - } - } - if nm != nil { - authorizedCallers, err := nm.GetAllAuthorizedCallers(nil) - if err != nil { - return snapshot, err - } - tv, err := nm.TypeAndVersion(nil) - if err != nil { - return snapshot, err - } - c.NonceManager = NonceManagerView{ - Contract: Contract{ - TypeAndVersion: tv, - Address: nm.Address(), - }, - // TODO: these can be resolved using an address book - AuthorizedCallers: authorizedCallers, - } + chainState := s.Chains[chainSelector] + chainView, err := chainState.GenerateView() + if err != nil { + return ccipView, err } - snapshot.Chains[chainName] = c + ccipView.Chains[chainName] = chainView } - return snapshot, nil + return ccipView, nil } -func SnapshotState(e deployment.Environment, ab deployment.AddressBook) (CCIPSnapShot, error) { +func StateView(e deployment.Environment, ab deployment.AddressBook) (view.CCIPView, error) { state, err := LoadOnchainState(e, ab) if err != nil { - return CCIPSnapShot{}, err + return view.CCIPView{}, err } - return state.Snapshot(e.AllChainSelectors()) + return state.View(e.AllChainSelectors()) } func LoadOnchainState(e deployment.Environment, ab deployment.AddressBook) (CCIPOnChainState, error) { @@ -242,7 +222,7 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type return state, err } state.ArmProxy = armProxy - case deployment.NewTypeAndVersion(RMNRemote, deployment.Version1_0_0).String(): + case deployment.NewTypeAndVersion(RMNRemote, deployment.Version1_6_0_dev).String(): rmnRemote, err := rmn_remote.NewRMNRemote(common.HexToAddress(address), chain.Client) if err != nil { return state, err diff --git a/integration-tests/deployment/ccip/view/chain.go b/integration-tests/deployment/ccip/view/chain.go new file mode 100644 index 0000000000..468e5e7d48 --- /dev/null +++ b/integration-tests/deployment/ccip/view/chain.go @@ -0,0 +1,27 @@ +package view + +import ( + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_2" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_5" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_6" +) + +type ChainView struct { + TokenAdminRegistry map[string]v1_5.TokenAdminRegistryView `json:"tokenAdminRegistry,omitempty"` + FeeQuoter map[string]v1_6.FeeQuoterView `json:"feeQuoter,omitempty"` + NonceManager map[string]v1_6.NonceManagerView `json:"nonceManager,omitempty"` + Router map[string]v1_2.RouterView `json:"router,omitempty"` + RMN map[string]v1_6.RMNRemoteView `json:"rmn,omitempty"` + OnRamp map[string]v1_6.OnRampView `json:"onRamp,omitempty"` +} + +func NewChain() ChainView { + return ChainView{ + TokenAdminRegistry: make(map[string]v1_5.TokenAdminRegistryView), + NonceManager: make(map[string]v1_6.NonceManagerView), + Router: make(map[string]v1_2.RouterView), + RMN: make(map[string]v1_6.RMNRemoteView), + OnRamp: make(map[string]v1_6.OnRampView), + FeeQuoter: make(map[string]v1_6.FeeQuoterView), + } +} diff --git a/integration-tests/deployment/ccip/view/state.go b/integration-tests/deployment/ccip/view/state.go new file mode 100644 index 0000000000..5c86f8e27a --- /dev/null +++ b/integration-tests/deployment/ccip/view/state.go @@ -0,0 +1,11 @@ +package view + +type CCIPView struct { + Chains map[string]ChainView `json:"chains,omitempty"` +} + +func NewCCIPView() CCIPView { + return CCIPView{ + Chains: make(map[string]ChainView), + } +} diff --git a/integration-tests/deployment/ccip/view/types/contract_state.go b/integration-tests/deployment/ccip/view/types/contract_state.go new file mode 100644 index 0000000000..f65c510af5 --- /dev/null +++ b/integration-tests/deployment/ccip/view/types/contract_state.go @@ -0,0 +1,33 @@ +package types + +import ( + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" +) + +type ContractMetaData struct { + TypeAndVersion string `json:"typeAndVersion,omitempty"` + Address common.Address `json:"address,omitempty"` + Owner common.Address `json:"owner,omitempty"` +} + +func NewContractMetaData(tv Meta, addr common.Address) (ContractMetaData, error) { + tvStr, err := tv.TypeAndVersion(nil) + if err != nil { + return ContractMetaData{}, err + } + owner, err := tv.Owner(nil) + if err != nil { + return ContractMetaData{}, err + } + return ContractMetaData{ + TypeAndVersion: tvStr, + Address: addr, + Owner: owner, + }, nil +} + +type Meta interface { + TypeAndVersion(opts *bind.CallOpts) (string, error) + Owner(opts *bind.CallOpts) (common.Address, error) +} diff --git a/integration-tests/deployment/ccip/view/v1_2/router.go b/integration-tests/deployment/ccip/view/v1_2/router.go new file mode 100644 index 0000000000..9d3711d0c2 --- /dev/null +++ b/integration-tests/deployment/ccip/view/v1_2/router.go @@ -0,0 +1,56 @@ +package v1_2 + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" +) + +type RouterView struct { + types.ContractMetaData + WrappedNative common.Address `json:"wrappedNative,omitempty"` + ARMProxy common.Address `json:"armProxy,omitempty"` + OnRamps map[uint64]common.Address `json:"onRamps,omitempty"` // Map of DestinationChainSelectors to OnRamp Addresses + OffRamps map[uint64]common.Address `json:"offRamps,omitempty"` // Map of SourceChainSelectors to a list of OffRamp Addresses +} + +func GenerateRouterView(r *router.Router) (RouterView, error) { + meta, err := types.NewContractMetaData(r, r.Address()) + if err != nil { + return RouterView{}, fmt.Errorf("view error to get router metadata: %w", err) + } + wrappedNative, err := r.GetWrappedNative(nil) + if err != nil { + return RouterView{}, fmt.Errorf("view error to get router wrapped native: %w", err) + } + armProxy, err := r.GetArmProxy(nil) + if err != nil { + return RouterView{}, fmt.Errorf("view error to get router arm proxy: %w", err) + } + onRamps := make(map[uint64]common.Address) + offRamps := make(map[uint64]common.Address) + offRampList, err := r.GetOffRamps(nil) + if err != nil { + return RouterView{}, fmt.Errorf("view error to get router offRamps: %w", err) + } + for _, offRamp := range offRampList { + offRamps[offRamp.SourceChainSelector] = offRamp.OffRamp + } + for selector := range offRamps { + onRamp, err := r.GetOnRamp(nil, selector) + if err != nil { + return RouterView{}, fmt.Errorf("view error to get router onRamp: %w", err) + } + onRamps[selector] = onRamp + } + return RouterView{ + ContractMetaData: meta, + WrappedNative: wrappedNative, + ARMProxy: armProxy, + OnRamps: onRamps, + OffRamps: offRamps, + }, nil +} diff --git a/integration-tests/deployment/ccip/view/v1_5/tokenadminregistry.go b/integration-tests/deployment/ccip/view/v1_5/tokenadminregistry.go new file mode 100644 index 0000000000..1e704efae7 --- /dev/null +++ b/integration-tests/deployment/ccip/view/v1_5/tokenadminregistry.go @@ -0,0 +1,30 @@ +package v1_5 + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" +) + +type TokenAdminRegistryView struct { + types.ContractMetaData + Tokens []common.Address `json:"tokens"` +} + +func GenerateTokenAdminRegistryView(taContract *token_admin_registry.TokenAdminRegistry) (TokenAdminRegistryView, error) { + tokens, err := taContract.GetAllConfiguredTokens(nil, 0, 10) + if err != nil { + return TokenAdminRegistryView{}, fmt.Errorf("view error for token admin registry: %w", err) + } + tvMeta, err := types.NewContractMetaData(taContract, taContract.Address()) + if err != nil { + return TokenAdminRegistryView{}, fmt.Errorf("metadata error for token admin registry: %w", err) + } + return TokenAdminRegistryView{ + ContractMetaData: tvMeta, + Tokens: tokens, + }, nil +} diff --git a/integration-tests/deployment/ccip/view/v1_6/feequoter.go b/integration-tests/deployment/ccip/view/v1_6/feequoter.go new file mode 100644 index 0000000000..10e0b984f3 --- /dev/null +++ b/integration-tests/deployment/ccip/view/v1_6/feequoter.go @@ -0,0 +1,153 @@ +package v1_6 + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" + router1_2 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" +) + +type FeeQuoterView struct { + types.ContractMetaData + AuthorizedCallers []string `json:"authorizedCallers,omitempty"` + FeeTokens []string `json:"feeTokens,omitempty"` + StaticConfig FeeQuoterStaticConfig `json:"staticConfig,omitempty"` + DestinationChainConfig map[uint64]FeeQuoterDestChainConfig `json:"destinationChainConfig,omitempty"` + TokenPriceFeedConfig map[string]FeeQuoterTokenPriceFeedConfig `json:"tokenPriceFeedConfig,omitempty"` +} + +type FeeQuoterStaticConfig struct { + MaxFeeJuelsPerMsg string `json:"maxFeeJuelsPerMsg,omitempty"` + LinkToken string `json:"linkToken,omitempty"` + StalenessThreshold uint32 `json:"stalenessThreshold,omitempty"` +} + +type FeeQuoterDestChainConfig struct { + IsEnabled bool `json:"isEnabled,omitempty"` + MaxNumberOfTokensPerMsg uint16 `json:"maxNumberOfTokensPerMsg,omitempty"` + MaxDataBytes uint32 `json:"maxDataBytes,omitempty"` + MaxPerMsgGasLimit uint32 `json:"maxPerMsgGasLimit,omitempty"` + DestGasOverhead uint32 `json:"destGasOverhead,omitempty"` + DestGasPerPayloadByte uint16 `json:"destGasPerPayloadByte,omitempty"` + DestDataAvailabilityOverheadGas uint32 `json:"destDataAvailabilityOverheadGas,omitempty"` + DestGasPerDataAvailabilityByte uint16 `json:"destGasPerDataAvailabilityByte,omitempty"` + DestDataAvailabilityMultiplierBps uint16 `json:"destDataAvailabilityMultiplierBps,omitempty"` + DefaultTokenFeeUSDCents uint16 `json:"defaultTokenFeeUSDCents,omitempty"` + DefaultTokenDestGasOverhead uint32 `json:"defaultTokenDestGasOverhead,omitempty"` + DefaultTxGasLimit uint32 `json:"defaultTxGasLimit,omitempty"` + GasMultiplierWeiPerEth uint64 `json:"gasMultiplierWeiPerEth,omitempty"` + NetworkFeeUSDCents uint32 `json:"networkFeeUSDCents,omitempty"` + EnforceOutOfOrder bool `json:"enforceOutOfOrder,omitempty"` + ChainFamilySelector string `json:"chainFamilySelector,omitempty"` +} + +type FeeQuoterTokenPriceFeedConfig struct { + DataFeedAddress string `json:"dataFeedAddress,omitempty"` + TokenDecimals uint8 `json:"tokenDecimals,omitempty"` +} + +func GenerateFeeQuoterView(fqContract *fee_quoter.FeeQuoter, router *router1_2.Router, ta *token_admin_registry.TokenAdminRegistry) (FeeQuoterView, error) { + fq := FeeQuoterView{} + authorizedCallers, err := fqContract.GetAllAuthorizedCallers(nil) + if err != nil { + return FeeQuoterView{}, err + } + fq.AuthorizedCallers = make([]string, 0, len(authorizedCallers)) + for _, ac := range authorizedCallers { + fq.AuthorizedCallers = append(fq.AuthorizedCallers, ac.Hex()) + } + fq.ContractMetaData, err = types.NewContractMetaData(fqContract, fqContract.Address()) + if err != nil { + return FeeQuoterView{}, fmt.Errorf("metadata error for FeeQuoter: %w", err) + } + feeTokens, err := fqContract.GetFeeTokens(nil) + if err != nil { + return FeeQuoterView{}, err + } + fq.FeeTokens = make([]string, 0, len(feeTokens)) + for _, ft := range feeTokens { + fq.FeeTokens = append(fq.FeeTokens, ft.Hex()) + } + staticConfig, err := fqContract.GetStaticConfig(nil) + if err != nil { + return FeeQuoterView{}, err + } + fq.StaticConfig = FeeQuoterStaticConfig{ + MaxFeeJuelsPerMsg: staticConfig.MaxFeeJuelsPerMsg.String(), + LinkToken: staticConfig.LinkToken.Hex(), + StalenessThreshold: staticConfig.StalenessThreshold, + } + // find router contract in dependencies + fq.DestinationChainConfig = make(map[uint64]FeeQuoterDestChainConfig) + destSelectors, err := GetDestinationSelectors(router) + if err != nil { + return FeeQuoterView{}, fmt.Errorf("view error for FeeQuoter: %w", err) + } + for _, destChainSelector := range destSelectors { + destChainConfig, err := fqContract.GetDestChainConfig(nil, destChainSelector) + if err != nil { + return FeeQuoterView{}, err + } + fq.DestinationChainConfig[destChainSelector] = FeeQuoterDestChainConfig{ + IsEnabled: destChainConfig.IsEnabled, + MaxNumberOfTokensPerMsg: destChainConfig.MaxNumberOfTokensPerMsg, + MaxDataBytes: destChainConfig.MaxDataBytes, + MaxPerMsgGasLimit: destChainConfig.MaxPerMsgGasLimit, + DestGasOverhead: destChainConfig.DestGasOverhead, + DestGasPerPayloadByte: destChainConfig.DestGasPerPayloadByte, + DestDataAvailabilityOverheadGas: destChainConfig.DestDataAvailabilityOverheadGas, + DestGasPerDataAvailabilityByte: destChainConfig.DestGasPerDataAvailabilityByte, + DestDataAvailabilityMultiplierBps: destChainConfig.DestDataAvailabilityMultiplierBps, + DefaultTokenFeeUSDCents: destChainConfig.DefaultTokenFeeUSDCents, + DefaultTokenDestGasOverhead: destChainConfig.DefaultTokenDestGasOverhead, + DefaultTxGasLimit: destChainConfig.DefaultTxGasLimit, + GasMultiplierWeiPerEth: destChainConfig.GasMultiplierWeiPerEth, + NetworkFeeUSDCents: destChainConfig.NetworkFeeUSDCents, + EnforceOutOfOrder: destChainConfig.EnforceOutOfOrder, + ChainFamilySelector: fmt.Sprintf("%x", destChainConfig.ChainFamilySelector), + } + } + fq.TokenPriceFeedConfig = make(map[string]FeeQuoterTokenPriceFeedConfig) + tokens, err := GetSupportedTokens(ta) + if err != nil { + return FeeQuoterView{}, fmt.Errorf("view error for FeeQuoter: %w", err) + } + for _, token := range tokens { + t, err := fqContract.GetTokenPriceFeedConfig(nil, token) + if err != nil { + return FeeQuoterView{}, err + } + fq.TokenPriceFeedConfig[token.String()] = FeeQuoterTokenPriceFeedConfig{ + DataFeedAddress: t.DataFeedAddress.Hex(), + TokenDecimals: t.TokenDecimals, + } + } + return fq, nil +} + +func GetSupportedTokens(taContract *token_admin_registry.TokenAdminRegistry) ([]common.Address, error) { + // TODO : include pagination CCIP-3416 + tokens, err := taContract.GetAllConfiguredTokens(nil, 0, 10) + if err != nil { + return nil, fmt.Errorf("failed to get tokens from token_admin_registry: %w", err) + } + return tokens, nil +} + +func GetDestinationSelectors(routerContract *router1_2.Router) ([]uint64, error) { + destSelectors := make([]uint64, 0) + offRamps, err := routerContract.GetOffRamps(nil) + if err != nil { + return nil, fmt.Errorf("failed to get offRamps from router: %w", err) + } + // lanes are bidirectional, so we get the list of source chains to know which chains are supported as destinations as well + for _, offRamp := range offRamps { + destSelectors = append(destSelectors, offRamp.SourceChainSelector) + } + + return destSelectors, nil +} diff --git a/integration-tests/deployment/ccip/view/v1_6/noncemanager.go b/integration-tests/deployment/ccip/view/v1_6/noncemanager.go new file mode 100644 index 0000000000..23df56c3d2 --- /dev/null +++ b/integration-tests/deployment/ccip/view/v1_6/noncemanager.go @@ -0,0 +1,31 @@ +package v1_6 + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" +) + +type NonceManagerView struct { + types.ContractMetaData + AuthorizedCallers []common.Address `json:"authorizedCallers,omitempty"` +} + +func GenerateNonceManagerView(nm *nonce_manager.NonceManager) (NonceManagerView, error) { + authorizedCallers, err := nm.GetAllAuthorizedCallers(nil) + if err != nil { + return NonceManagerView{}, fmt.Errorf("view error for nonce manager: %w", err) + } + nmMeta, err := types.NewContractMetaData(nm, nm.Address()) + if err != nil { + return NonceManagerView{}, fmt.Errorf("metadata error for nonce manager: %w", err) + } + return NonceManagerView{ + ContractMetaData: nmMeta, + // TODO: these can be resolved using an address book + AuthorizedCallers: authorizedCallers, + }, nil +} diff --git a/integration-tests/deployment/ccip/view/v1_6/onramp.go b/integration-tests/deployment/ccip/view/v1_6/onramp.go new file mode 100644 index 0000000000..a5fe13bfb5 --- /dev/null +++ b/integration-tests/deployment/ccip/view/v1_6/onramp.go @@ -0,0 +1,106 @@ +package v1_6 + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" + router1_2 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" +) + +type OnRampView struct { + types.ContractMetaData + DynamicConfig onramp.OnRampDynamicConfig `json:"dynamicConfig"` + StaticConfig onramp.OnRampStaticConfig `json:"staticConfig"` + Owner common.Address `json:"owner"` + SourceTokenToPool map[common.Address]common.Address `json:"sourceTokenToPool"` + DestChainSpecificData map[uint64]DestChainSpecificData `json:"destChainSpecificData"` +} + +type DestChainSpecificData struct { + AllowedSendersList []common.Address `json:"allowedSendersList"` + DestChainConfig onramp.GetDestChainConfig `json:"destChainConfig"` + ExpectedNextSeqNum uint64 `json:"expectedNextSeqNum"` + Router common.Address `json:"router"` +} + +func GenerateOnRampView( + onRampContract *onramp.OnRamp, + routerContract *router1_2.Router, + taContract *token_admin_registry.TokenAdminRegistry, +) (OnRampView, error) { + tv, err := types.NewContractMetaData(onRampContract, onRampContract.Address()) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get contract metadata: %w", err) + } + dynamicConfig, err := onRampContract.GetDynamicConfig(nil) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get dynamic config: %w", err) + } + + staticConfig, err := onRampContract.GetStaticConfig(nil) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get static config: %w", err) + } + + owner, err := onRampContract.Owner(nil) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get owner: %w", err) + } + // populate destChainSelectors from router + destChainSelectors, err := GetDestinationSelectors(routerContract) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get destination selectors: %w", err) + } + // populate sourceTokens from token admin registry contract + sourceTokens, err := taContract.GetAllConfiguredTokens(nil, 0, 10) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get all configured tokens: %w", err) + } + sourceTokenToPool := make(map[common.Address]common.Address) + for _, sourceToken := range sourceTokens { + pool, err := onRampContract.GetPoolBySourceToken(nil, 0, sourceToken) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get pool by source token: %w", err) + } + sourceTokenToPool[sourceToken] = pool + } + + destChainSpecificData := make(map[uint64]DestChainSpecificData) + for _, destChainSelector := range destChainSelectors { + allowedSendersList, err := onRampContract.GetAllowedSendersList(nil, destChainSelector) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get allowed senders list: %w", err) + } + destChainConfig, err := onRampContract.GetDestChainConfig(nil, destChainSelector) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get dest chain config: %w", err) + } + expectedNextSeqNum, err := onRampContract.GetExpectedNextSequenceNumber(nil, destChainSelector) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get expected next sequence number: %w", err) + } + router, err := onRampContract.GetRouter(nil, destChainSelector) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get router: %w", err) + } + destChainSpecificData[destChainSelector] = DestChainSpecificData{ + AllowedSendersList: allowedSendersList, + DestChainConfig: destChainConfig, + ExpectedNextSeqNum: expectedNextSeqNum, + Router: router, + } + } + + return OnRampView{ + ContractMetaData: tv, + DynamicConfig: dynamicConfig, + StaticConfig: staticConfig, + Owner: owner, + SourceTokenToPool: sourceTokenToPool, + DestChainSpecificData: destChainSpecificData, + }, nil +} diff --git a/integration-tests/deployment/ccip/view/v1_6/rmnremote.go b/integration-tests/deployment/ccip/view/v1_6/rmnremote.go new file mode 100644 index 0000000000..bf0fefaa2e --- /dev/null +++ b/integration-tests/deployment/ccip/view/v1_6/rmnremote.go @@ -0,0 +1,54 @@ +package v1_6 + +import ( + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_remote" +) + +type RMNRemoteView struct { + types.ContractMetaData + IsCursed bool `json:"isCursed"` + Config RMNRemoteVersionedConfig `json:"config,omitempty"` +} + +type RMNRemoteVersionedConfig struct { + Version uint32 `json:"version"` + Signers []RMNRemoteSigner `json:"signers"` + MinSigners uint64 `json:"minSigners"` +} + +type RMNRemoteSigner struct { + OnchainPublicKey string `json:"onchain_public_key"` + NodeIndex uint64 `json:"node_index"` +} + +func GenerateRMNRemoteView(rmnReader *rmn_remote.RMNRemote) (RMNRemoteView, error) { + tv, err := types.NewContractMetaData(rmnReader, rmnReader.Address()) + if err != nil { + return RMNRemoteView{}, err + } + config, err := rmnReader.GetVersionedConfig(nil) + if err != nil { + return RMNRemoteView{}, err + } + rmnConfig := RMNRemoteVersionedConfig{ + Version: config.Version, + Signers: make([]RMNRemoteSigner, 0, len(config.Config.Signers)), + MinSigners: config.Config.MinSigners, + } + for _, signer := range config.Config.Signers { + rmnConfig.Signers = append(rmnConfig.Signers, RMNRemoteSigner{ + OnchainPublicKey: signer.OnchainPublicKey.Hex(), + NodeIndex: signer.NodeIndex, + }) + } + isCursed, err := rmnReader.IsCursed0(nil) + if err != nil { + return RMNRemoteView{}, err + } + return RMNRemoteView{ + ContractMetaData: tv, + IsCursed: isCursed, + Config: rmnConfig, + }, nil +} From 360ecfbc7bea8da0adf96fec7d1a1c2ffb1283a9 Mon Sep 17 00:00:00 2001 From: Makram Date: Sat, 21 Sep 2024 00:08:46 +0300 Subject: [PATCH 397/432] core/capabilities/ccip: bump chainlink-ccip, fix build (#14506) * core/capabilities/ccip: bump chainlink-ccip, fix build * fix test * bump again * bump to main version --- .../ccip/launcher/integration_test.go | 2 +- core/capabilities/ccip/launcher/launcher.go | 11 +++---- .../ccip/launcher/launcher_test.go | 19 ++++++------ .../ccip/oraclecreator/bootstrap.go | 2 +- .../capabilities/ccip/oraclecreator/plugin.go | 7 +++-- .../ccip/types/mocks/oracle_creator.go | 29 ++++++++++--------- core/capabilities/ccip/types/types.go | 2 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +-- go.mod | 2 +- go.sum | 4 +-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +-- 15 files changed, 50 insertions(+), 46 deletions(-) diff --git a/core/capabilities/ccip/launcher/integration_test.go b/core/capabilities/ccip/launcher/integration_test.go index ea22360c66..2680d587d1 100644 --- a/core/capabilities/ccip/launcher/integration_test.go +++ b/core/capabilities/ccip/launcher/integration_test.go @@ -108,7 +108,7 @@ type oracleCreatorPrints struct { t *testing.T } -func (o *oracleCreatorPrints) Create(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { +func (o *oracleCreatorPrints) Create(_ uint32, config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { pluginType := cctypes.PluginType(config.Config.PluginType) o.t.Logf("Creating plugin oracle (pluginType: %s) with config %+v\n", pluginType, config) return &oraclePrints{pluginType: pluginType, config: config, t: o.t}, nil diff --git a/core/capabilities/ccip/launcher/launcher.go b/core/capabilities/ccip/launcher/launcher.go index 9fb92d20f5..7f677d50c8 100644 --- a/core/capabilities/ccip/launcher/launcher.go +++ b/core/capabilities/ccip/launcher/launcher.go @@ -306,12 +306,12 @@ func updateDON( don.ID, err) } - commitBgd, err := createFutureBlueGreenDeployment(prevDeployment, commitOCRConfigs, oracleCreator, cctypes.PluginTypeCCIPCommit) + commitBgd, err := createFutureBlueGreenDeployment(don.ID, prevDeployment, commitOCRConfigs, oracleCreator, cctypes.PluginTypeCCIPCommit) if err != nil { return nil, fmt.Errorf("failed to create future blue-green deployment for CCIP commit plugin: %w, don id: %d", err, don.ID) } - execBgd, err := createFutureBlueGreenDeployment(prevDeployment, execOCRConfigs, oracleCreator, cctypes.PluginTypeCCIPExec) + execBgd, err := createFutureBlueGreenDeployment(don.ID, prevDeployment, execOCRConfigs, oracleCreator, cctypes.PluginTypeCCIPExec) if err != nil { return nil, fmt.Errorf("failed to create future blue-green deployment for CCIP exec plugin: %w, don id: %d", err, don.ID) } @@ -327,6 +327,7 @@ func updateDON( // b) len(ocrConfigs) == 1 && prevDeployment.HasGreenInstance(): this is a promotion of green->blue. // All other cases are invalid. This is enforced in the ccip config contract. func createFutureBlueGreenDeployment( + donID uint32, prevDeployment ccipDeployment, ocrConfigs []ccipreader.OCR3ConfigWithMeta, oracleCreator cctypes.OracleCreator, @@ -335,7 +336,7 @@ func createFutureBlueGreenDeployment( var deployment blueGreenDeployment if isNewGreenInstance(pluginType, ocrConfigs, prevDeployment) { // this is a new green instance. - greenOracle, err := oracleCreator.Create(cctypes.OCR3ConfigWithMeta(ocrConfigs[1])) + greenOracle, err := oracleCreator.Create(donID, cctypes.OCR3ConfigWithMeta(ocrConfigs[1])) if err != nil { return blueGreenDeployment{}, fmt.Errorf("failed to create CCIP commit oracle: %w", err) } @@ -390,12 +391,12 @@ func createDON( // at this point we know we are either a member of the DON or a bootstrap node. // the injected oracleCreator will create the appropriate oracle. - commitOracle, err := oracleCreator.Create(cctypes.OCR3ConfigWithMeta(commitOCRConfigs[0])) + commitOracle, err := oracleCreator.Create(don.ID, cctypes.OCR3ConfigWithMeta(commitOCRConfigs[0])) if err != nil { return nil, fmt.Errorf("failed to create CCIP commit oracle: %w", err) } - execOracle, err := oracleCreator.Create(cctypes.OCR3ConfigWithMeta(execOCRConfigs[0])) + execOracle, err := oracleCreator.Create(don.ID, cctypes.OCR3ConfigWithMeta(execOCRConfigs[0])) if err != nil { return nil, fmt.Errorf("failed to create CCIP exec oracle: %w", err) } diff --git a/core/capabilities/ccip/launcher/launcher_test.go b/core/capabilities/ccip/launcher/launcher_test.go index dd917c6915..06e9f88c4e 100644 --- a/core/capabilities/ccip/launcher/launcher_test.go +++ b/core/capabilities/ccip/launcher/launcher_test.go @@ -108,9 +108,7 @@ func Test_createDON(t *testing.T) { }, }}, nil) oracleCreator.EXPECT().Type().Return(cctypes.OracleTypeBootstrap).Once() - oracleCreator. - On("Create", mock.Anything). - Return(mocks.NewCCIPOracle(t), nil).Twice() + oracleCreator.EXPECT().Create(mock.Anything, mock.Anything).Return(mocks.NewCCIPOracle(t), nil).Twice() }, false, }, @@ -147,11 +145,11 @@ func Test_createDON(t *testing.T) { }, }}, nil) - oracleCreator.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + oracleCreator.EXPECT().Create(mock.Anything, mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) })). Return(mocks.NewCCIPOracle(t), nil) - oracleCreator.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + oracleCreator.EXPECT().Create(mock.Anything, mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) })). Return(mocks.NewCCIPOracle(t), nil) @@ -177,6 +175,7 @@ func Test_createDON(t *testing.T) { func Test_createFutureBlueGreenDeployment(t *testing.T) { type args struct { + donID uint32 prevDeployment ccipDeployment ocrConfigs []ccipreaderpkg.OCR3ConfigWithMeta oracleCreator *mocks.OracleCreator @@ -192,7 +191,7 @@ func Test_createFutureBlueGreenDeployment(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := createFutureBlueGreenDeployment(tt.args.prevDeployment, tt.args.ocrConfigs, tt.args.oracleCreator, tt.args.pluginType) + got, err := createFutureBlueGreenDeployment(tt.args.donID, tt.args.prevDeployment, tt.args.ocrConfigs, tt.args.oracleCreator, tt.args.pluginType) if (err != nil) != tt.wantErr { t.Errorf("createFutureBlueGreenDeployment() error = %v, wantErr %v", err, tt.wantErr) return @@ -322,11 +321,11 @@ func Test_launcher_processDiff(t *testing.T) { commitOracle.On("Start").Return(nil) execOracle := mocks.NewCCIPOracle(t) execOracle.On("Start").Return(nil) - m.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + m.EXPECT().Create(mock.Anything, mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) })). Return(commitOracle, nil) - m.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + m.EXPECT().Create(mock.Anything, mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) })). Return(execOracle, nil) @@ -385,11 +384,11 @@ func Test_launcher_processDiff(t *testing.T) { commitOracle.On("Start").Return(nil) execOracle := mocks.NewCCIPOracle(t) execOracle.On("Start").Return(nil) - m.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + m.EXPECT().Create(mock.Anything, mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) })). Return(commitOracle, nil) - m.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + m.EXPECT().Create(mock.Anything, mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) })). Return(execOracle, nil) diff --git a/core/capabilities/ccip/oraclecreator/bootstrap.go b/core/capabilities/ccip/oraclecreator/bootstrap.go index a4bf03a4de..22de4ae948 100644 --- a/core/capabilities/ccip/oraclecreator/bootstrap.go +++ b/core/capabilities/ccip/oraclecreator/bootstrap.go @@ -54,7 +54,7 @@ func (i *bootstrapOracleCreator) Type() cctypes.OracleType { } // Create implements types.OracleCreator. -func (i *bootstrapOracleCreator) Create(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { +func (i *bootstrapOracleCreator) Create(_ uint32, config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { // Assuming that the chain selector is referring to an evm chain for now. // TODO: add an api that returns chain family. // NOTE: this doesn't really matter for the bootstrap node, it doesn't do anything on-chain. diff --git a/core/capabilities/ccip/oraclecreator/plugin.go b/core/capabilities/ccip/oraclecreator/plugin.go index 9374f8fe9f..d9efe5a58c 100644 --- a/core/capabilities/ccip/oraclecreator/plugin.go +++ b/core/capabilities/ccip/oraclecreator/plugin.go @@ -107,7 +107,7 @@ func (i *pluginOracleCreator) Type() cctypes.OracleType { } // Create implements types.OracleCreator. -func (i *pluginOracleCreator) Create(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { +func (i *pluginOracleCreator) Create(donID uint32, config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { pluginType := cctypes.PluginType(config.Config.PluginType) // Assuming that the chain selector is referring to an evm chain for now. @@ -157,7 +157,7 @@ func (i *pluginOracleCreator) Create(config cctypes.OCR3ConfigWithMeta) (cctypes } // TODO: Extract the correct transmitter address from the destsFromAccount - factory, transmitter, err := i.createFactoryAndTransmitter(config, destRelayID, contractReaders, chainWriters, destChainWriter, destFromAccounts) + factory, transmitter, err := i.createFactoryAndTransmitter(donID, config, destRelayID, contractReaders, chainWriters, destChainWriter, destFromAccounts) if err != nil { return nil, fmt.Errorf("failed to create factory and transmitter: %w", err) } @@ -198,6 +198,7 @@ func (i *pluginOracleCreator) Create(config cctypes.OCR3ConfigWithMeta) (cctypes } func (i *pluginOracleCreator) createFactoryAndTransmitter( + donID uint32, config cctypes.OCR3ConfigWithMeta, destRelayID types.RelayID, contractReaders map[cciptypes.ChainSelector]types.ContractReader, @@ -214,6 +215,7 @@ func (i *pluginOracleCreator) createFactoryAndTransmitter( Named(destRelayID.String()). Named(fmt.Sprintf("%d", config.Config.ChainSelector)). Named(hexutil.Encode(config.Config.OfframpAddress)), + donID, ccipreaderpkg.OCR3ConfigWithMeta(config), ccipevm.NewCommitPluginCodecV1(), ccipevm.NewMessageHasherV1(), @@ -231,6 +233,7 @@ func (i *pluginOracleCreator) createFactoryAndTransmitter( Named("CCIPExecPlugin"). Named(destRelayID.String()). Named(hexutil.Encode(config.Config.OfframpAddress)), + donID, ccipreaderpkg.OCR3ConfigWithMeta(config), ccipevm.NewExecutePluginCodecV1(), ccipevm.NewMessageHasherV1(), diff --git a/core/capabilities/ccip/types/mocks/oracle_creator.go b/core/capabilities/ccip/types/mocks/oracle_creator.go index 1d327e9652..362a89a94d 100644 --- a/core/capabilities/ccip/types/mocks/oracle_creator.go +++ b/core/capabilities/ccip/types/mocks/oracle_creator.go @@ -20,9 +20,9 @@ func (_m *OracleCreator) EXPECT() *OracleCreator_Expecter { return &OracleCreator_Expecter{mock: &_m.Mock} } -// Create provides a mock function with given fields: config -func (_m *OracleCreator) Create(config types.OCR3ConfigWithMeta) (types.CCIPOracle, error) { - ret := _m.Called(config) +// Create provides a mock function with given fields: donID, config +func (_m *OracleCreator) Create(donID uint32, config types.OCR3ConfigWithMeta) (types.CCIPOracle, error) { + ret := _m.Called(donID, config) if len(ret) == 0 { panic("no return value specified for Create") @@ -30,19 +30,19 @@ func (_m *OracleCreator) Create(config types.OCR3ConfigWithMeta) (types.CCIPOrac var r0 types.CCIPOracle var r1 error - if rf, ok := ret.Get(0).(func(types.OCR3ConfigWithMeta) (types.CCIPOracle, error)); ok { - return rf(config) + if rf, ok := ret.Get(0).(func(uint32, types.OCR3ConfigWithMeta) (types.CCIPOracle, error)); ok { + return rf(donID, config) } - if rf, ok := ret.Get(0).(func(types.OCR3ConfigWithMeta) types.CCIPOracle); ok { - r0 = rf(config) + if rf, ok := ret.Get(0).(func(uint32, types.OCR3ConfigWithMeta) types.CCIPOracle); ok { + r0 = rf(donID, config) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(types.CCIPOracle) } } - if rf, ok := ret.Get(1).(func(types.OCR3ConfigWithMeta) error); ok { - r1 = rf(config) + if rf, ok := ret.Get(1).(func(uint32, types.OCR3ConfigWithMeta) error); ok { + r1 = rf(donID, config) } else { r1 = ret.Error(1) } @@ -56,14 +56,15 @@ type OracleCreator_Create_Call struct { } // Create is a helper method to define mock.On call +// - donID uint32 // - config types.OCR3ConfigWithMeta -func (_e *OracleCreator_Expecter) Create(config interface{}) *OracleCreator_Create_Call { - return &OracleCreator_Create_Call{Call: _e.mock.On("Create", config)} +func (_e *OracleCreator_Expecter) Create(donID interface{}, config interface{}) *OracleCreator_Create_Call { + return &OracleCreator_Create_Call{Call: _e.mock.On("Create", donID, config)} } -func (_c *OracleCreator_Create_Call) Run(run func(config types.OCR3ConfigWithMeta)) *OracleCreator_Create_Call { +func (_c *OracleCreator_Create_Call) Run(run func(donID uint32, config types.OCR3ConfigWithMeta)) *OracleCreator_Create_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.OCR3ConfigWithMeta)) + run(args[0].(uint32), args[1].(types.OCR3ConfigWithMeta)) }) return _c } @@ -73,7 +74,7 @@ func (_c *OracleCreator_Create_Call) Return(_a0 types.CCIPOracle, _a1 error) *Or return _c } -func (_c *OracleCreator_Create_Call) RunAndReturn(run func(types.OCR3ConfigWithMeta) (types.CCIPOracle, error)) *OracleCreator_Create_Call { +func (_c *OracleCreator_Create_Call) RunAndReturn(run func(uint32, types.OCR3ConfigWithMeta) (types.CCIPOracle, error)) *OracleCreator_Create_Call { _c.Call.Return(run) return _c } diff --git a/core/capabilities/ccip/types/types.go b/core/capabilities/ccip/types/types.go index e42990f4c4..04da1157b3 100644 --- a/core/capabilities/ccip/types/types.go +++ b/core/capabilities/ccip/types/types.go @@ -46,7 +46,7 @@ type OracleCreator interface { // Create creates a new oracle that will run either the commit or exec ccip plugin, // if its a plugin oracle, or a bootstrap oracle if its a bootstrap oracle. // The oracle must be returned unstarted. - Create(config OCR3ConfigWithMeta) (CCIPOracle, error) + Create(donID uint32, config OCR3ConfigWithMeta) (CCIPOracle, error) // Type returns the type of oracle that this creator creates. // The only valid values are OracleTypePlugin and OracleTypeBootstrap. diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 88388d1c7b..f664efe218 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -271,7 +271,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 49cba89576..e8483420f8 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1081,8 +1081,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 h1:/Bx9MUUQ+TfS8kIdER8gujpJWfYu8ft4FYzpH8gSPJY= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe h1:CPvnTxH7C+5ziD7zCopnRFZhlK65+e2dGdw6xISl/K4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/go.mod b/go.mod index 4052892209..00b171140d 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 diff --git a/go.sum b/go.sum index 75004f3805..0c63cfbc74 100644 --- a/go.sum +++ b/go.sum @@ -1042,8 +1042,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 h1:/Bx9MUUQ+TfS8kIdER8gujpJWfYu8ft4FYzpH8gSPJY= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe h1:CPvnTxH7C+5ziD7zCopnRFZhlK65+e2dGdw6xISl/K4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index e673e559bc..5ea0f78f6b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -39,7 +39,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240910151738-3f318badcfb5 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index ee802182c1..bdc7ebb362 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1423,8 +1423,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 h1:/Bx9MUUQ+TfS8kIdER8gujpJWfYu8ft4FYzpH8gSPJY= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe h1:CPvnTxH7C+5ziD7zCopnRFZhlK65+e2dGdw6xISl/K4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 90eeea63f4..e9e5c6ee4e 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -386,7 +386,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 37fa4cadda..96f1ed8aea 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1397,8 +1397,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953 h1:/Bx9MUUQ+TfS8kIdER8gujpJWfYu8ft4FYzpH8gSPJY= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240919174352-8d485ebc0953/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe h1:CPvnTxH7C+5ziD7zCopnRFZhlK65+e2dGdw6xISl/K4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= From 51715aa44651a34135c3fa38ff26422872e0ee36 Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Mon, 23 Sep 2024 12:43:55 +0400 Subject: [PATCH 398/432] [DEVSVCS-547] option to use pre-deployed contracts in Automation tests (#14497) * rename to ctftestenv * automation test config - add contract addresses * add multicall contract in pre-deployed contracts * support benchmark test contract in pre-deployed contracts * load chainmodule contract from address * fix registrar load, add more logs * reduce test setup time on live network * fix lint issues --- .../actions/automation_ocr_helpers.go | 75 ++- .../actions/automationv2/actions.go | 163 ++++--- integration-tests/actions/keeper_helpers.go | 2 +- .../benchmark/automation_test.go | 35 +- .../chaos/automation_chaos_test.go | 6 +- .../ethereum_contracts_automation.go | 166 ++++--- .../automationv2_1/automationv2_1_test.go | 2 +- .../reorg/automation_reorg_test.go | 3 +- integration-tests/smoke/automation_test.go | 127 +----- integration-tests/smoke/log_poller_test.go | 15 +- .../testconfig/automation/config.go | 430 ++++++++++++++++++ ...r_benchmark.go => automation_benchmark.go} | 38 +- 12 files changed, 784 insertions(+), 278 deletions(-) rename integration-tests/testsetups/{keeper_benchmark.go => automation_benchmark.go} (94%) diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index f184580467..8159427699 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -6,6 +6,10 @@ import ( "math/big" "testing" + "github.com/ethereum/go-ethereum/common" + + tt "github.com/smartcontractkit/chainlink/integration-tests/types" + "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-testing-framework/seth" @@ -32,9 +36,9 @@ func DeployAutoOCRRegistryAndRegistrar( return registry, registrar } -// DeployConsumers deploys and registers keeper consumers. If ephemeral addresses are enabled, it will deploy and register the consumers from ephemeral addresses, but each upkpeep will be registered with root key address as the admin. Which means +// DeployLegacyConsumers deploys and registers keeper consumers. If ephemeral addresses are enabled, it will deploy and register the consumers from ephemeral addresses, but each upkpeep will be registered with root key address as the admin. Which means // that functions like setting upkeep configuration, pausing, unpausing, etc. will be done by the root key address. It deploys multicall contract and sends link funds to each deployment address. -func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, linkToken contracts.LinkToken, numberOfUpkeeps int, linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, isLogTrigger bool, isMercury bool, isBillingTokenNative bool, wethToken contracts.WETHToken) ([]contracts.KeeperConsumer, []*big.Int) { +func DeployLegacyConsumers(t *testing.T, chainClient *seth.Client, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, linkToken contracts.LinkToken, numberOfUpkeeps int, linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, isLogTrigger bool, isMercury bool, isBillingTokenNative bool, wethToken contracts.WETHToken) ([]contracts.KeeperConsumer, []*big.Int) { // Fund deployers with LINK, no need to do this for Native token if !isBillingTokenNative { err := DeployMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep) @@ -54,6 +58,28 @@ func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts. return upkeeps, upkeepIds } +// DeployConsumers deploys and registers keeper consumers. If ephemeral addresses are enabled, it will deploy and register the consumers from ephemeral addresses, but each upkpeep will be registered with root key address as the admin. Which means +// that functions like setting upkeep configuration, pausing, unpausing, etc. will be done by the root key address. It deploys multicall contract and sends link funds to each deployment address. +func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, linkToken contracts.LinkToken, numberOfUpkeeps int, linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, isLogTrigger bool, isMercury bool, isBillingTokenNative bool, wethToken contracts.WETHToken, config tt.AutomationTestConfig) ([]contracts.KeeperConsumer, []*big.Int) { + // Fund deployers with LINK, no need to do this for Native token + if !isBillingTokenNative { + err := SetupMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, config) + require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail") + } + + upkeeps := DeployKeeperConsumers(t, chainClient, numberOfUpkeeps, isLogTrigger, isMercury) + require.Equal(t, numberOfUpkeeps, len(upkeeps), "Number of upkeeps should match") + var upkeepsAddresses []string + for _, upkeep := range upkeeps { + upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) + } + upkeepIds := RegisterUpkeepContracts( + t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, isLogTrigger, isMercury, isBillingTokenNative, wethToken, + ) + require.Equal(t, numberOfUpkeeps, len(upkeepIds), "Number of upkeepIds should match") + return upkeeps, upkeepIds +} + // DeployPerformanceConsumers deploys and registers keeper performance consumers. If ephemeral addresses are enabled, it will deploy and register the consumers from ephemeral addresses, but each upkeep will be registered with root key address as the admin. // that functions like setting upkeep configuration, pausing, unpausing, etc. will be done by the root key address. It deploys multicall contract and sends link funds to each deployment address. func DeployPerformanceConsumers( @@ -69,12 +95,13 @@ func DeployPerformanceConsumers( blockInterval, // Interval of blocks that upkeeps are expected to be performed checkGasToBurn, // How much gas should be burned on checkUpkeep() calls performGasToBurn int64, // How much gas should be burned on performUpkeep() calls + config tt.AutomationTestConfig, ) ([]contracts.KeeperConsumerPerformance, []*big.Int) { upkeeps := DeployKeeperConsumersPerformance( t, chainClient, numberOfUpkeeps, blockRange, blockInterval, checkGasToBurn, performGasToBurn, ) - err := DeployMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep) + err := SetupMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, config) require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail") var upkeepsAddresses []string @@ -97,10 +124,11 @@ func DeployPerformDataCheckerConsumers( linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, expectedData []byte, + config tt.AutomationTestConfig, ) ([]contracts.KeeperPerformDataChecker, []*big.Int) { upkeeps := DeployPerformDataChecker(t, chainClient, numberOfUpkeeps, expectedData) - err := DeployMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep) + err := SetupMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, config) require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail") var upkeepsAddresses []string @@ -111,6 +139,45 @@ func DeployPerformDataCheckerConsumers( return upkeeps, upkeepIds } +func SetupMultiCallAddress(chainClient *seth.Client, testConfig tt.AutomationTestConfig) (common.Address, error) { + if testConfig.GetAutomationConfig().UseExistingMultiCallContract() { + multiCallAddress, err := testConfig.GetAutomationConfig().MultiCallContractAddress() + if err != nil { + return common.Address{}, errors.Wrap(err, "Error getting existing multicall contract address") + } + return multiCallAddress, nil + } + + multicallAddress, err := contracts.DeployMultiCallContract(chainClient) + if err != nil { + return common.Address{}, errors.Wrap(err, "Error deploying multicall contract") + } + return multicallAddress, nil +} + +// SetupMultiCallAndFundDeploymentAddresses setups multicall contract and sends link funds to each deployment address +func SetupMultiCallAndFundDeploymentAddresses( + chainClient *seth.Client, + linkToken contracts.LinkToken, + numberOfUpkeeps int, + linkFundsForEachUpkeep *big.Int, + testConfig tt.AutomationTestConfig, +) error { + concurrency, err := GetAndAssertCorrectConcurrency(chainClient, 1) + if err != nil { + return err + } + + operationsPerAddress := numberOfUpkeeps / concurrency + + multicallAddress, err := SetupMultiCallAddress(chainClient, testConfig) + if err != nil { + return errors.Wrap(err, "Error deploying multicall contract") + } + + return SendLinkFundsToDeploymentAddresses(chainClient, concurrency, numberOfUpkeeps, operationsPerAddress, multicallAddress, linkFundsForEachUpkeep, linkToken) +} + // DeployMultiCallAndFundDeploymentAddresses deploys multicall contract and sends link funds to each deployment address func DeployMultiCallAndFundDeploymentAddresses( chainClient *seth.Client, diff --git a/integration-tests/actions/automationv2/actions.go b/integration-tests/actions/automationv2/actions.go index 6ce35873d8..9b3013f778 100644 --- a/integration-tests/actions/automationv2/actions.go +++ b/integration-tests/actions/automationv2/actions.go @@ -12,6 +12,8 @@ import ( "testing" "time" + tt "github.com/smartcontractkit/chainlink/integration-tests/types" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/lib/pq" @@ -45,7 +47,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/store/models" ctf_concurrency "github.com/smartcontractkit/chainlink-testing-framework/lib/concurrency" - ctfTestEnv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" ) @@ -61,6 +63,8 @@ type NodeDetails struct { type AutomationTest struct { ChainClient *seth.Client + TestConfig tt.AutomationTestConfig + LinkToken contracts.LinkToken Transcoder contracts.UpkeepTranscoder LINKETHFeed contracts.MockLINKETHFeed @@ -110,9 +114,11 @@ func NewAutomationTestK8s( l zerolog.Logger, chainClient *seth.Client, chainlinkNodes []*client.ChainlinkK8sClient, + config tt.AutomationTestConfig, ) *AutomationTest { return &AutomationTest{ ChainClient: chainClient, + TestConfig: config, ChainlinkNodesk8s: chainlinkNodes, IsOnk8s: true, TransmitterKeyIndex: 0, @@ -126,9 +132,11 @@ func NewAutomationTestDocker( l zerolog.Logger, chainClient *seth.Client, chainlinkNodes []*client.ChainlinkClient, + config tt.AutomationTestConfig, ) *AutomationTest { return &AutomationTest{ ChainClient: chainClient, + TestConfig: config, ChainlinkNodes: chainlinkNodes, IsOnk8s: false, TransmitterKeyIndex: 0, @@ -173,6 +181,7 @@ func (a *AutomationTest) LoadLINK(address string) error { return err } a.LinkToken = linkToken + a.Logger.Info().Str("LINK Token Address", a.LinkToken.Address()).Msg("Successfully loaded LINK Token") return nil } @@ -191,6 +200,7 @@ func (a *AutomationTest) LoadTranscoder(address string) error { return err } a.Transcoder = transcoder + a.Logger.Info().Str("Transcoder Address", a.Transcoder.Address()).Msg("Successfully loaded Transcoder") return nil } @@ -209,6 +219,7 @@ func (a *AutomationTest) LoadLinkEthFeed(address string) error { return err } a.LINKETHFeed = ethLinkFeed + a.Logger.Info().Str("LINK/ETH Feed Address", a.LINKETHFeed.Address()).Msg("Successfully loaded LINK/ETH Feed") return nil } @@ -227,6 +238,7 @@ func (a *AutomationTest) LoadEthUSDFeed(address string) error { return err } a.ETHUSDFeed = ethUSDFeed + a.Logger.Info().Str("ETH/USD Feed Address", a.ETHUSDFeed.Address()).Msg("Successfully loaded ETH/USD Feed") return nil } @@ -245,6 +257,7 @@ func (a *AutomationTest) LoadLinkUSDFeed(address string) error { return err } a.LINKUSDFeed = linkUSDFeed + a.Logger.Info().Str("LINK/USD Feed Address", a.LINKUSDFeed.Address()).Msg("Successfully loaded LINK/USD Feed") return nil } @@ -263,6 +276,7 @@ func (a *AutomationTest) LoadWETH(address string) error { return err } a.WETHToken = wethToken + a.Logger.Info().Str("WETH Token Address", a.WETHToken.Address()).Msg("Successfully loaded WETH Token") return nil } @@ -281,6 +295,7 @@ func (a *AutomationTest) LoadEthGasFeed(address string) error { return err } a.GasFeed = gasFeed + a.Logger.Info().Str("Gas Feed Address", a.GasFeed.Address()).Msg("Successfully loaded Gas Feed") return nil } @@ -305,12 +320,13 @@ func (a *AutomationTest) DeployRegistry() error { return nil } -func (a *AutomationTest) LoadRegistry(address string) error { - registry, err := contracts.LoadKeeperRegistry(a.Logger, a.ChainClient, common.HexToAddress(address), a.RegistrySettings.RegistryVersion) +func (a *AutomationTest) LoadRegistry(registryAddress, chainModuleAddress string) error { + registry, err := contracts.LoadKeeperRegistry(a.Logger, a.ChainClient, common.HexToAddress(registryAddress), a.RegistrySettings.RegistryVersion, common.HexToAddress(chainModuleAddress)) if err != nil { return err } a.Registry = registry + a.Logger.Info().Str("ChainModule Address", chainModuleAddress).Str("Registry Address", a.Registry.Address()).Msg("Successfully loaded Registry") return nil } @@ -337,6 +353,7 @@ func (a *AutomationTest) LoadRegistrar(address string) error { if err != nil { return err } + a.Logger.Info().Str("Registrar Address", registrar.Address()).Msg("Successfully loaded Registrar") a.Registrar = registrar return nil } @@ -597,6 +614,7 @@ func (a *AutomationTest) SetConfigOnRegistry() error { }, } } + a.Logger.Debug().Interface("ocrConfig", ocrConfig).Msg("Setting OCR3 config") err = a.Registry.SetConfigTypeSafe(ocrConfig) if err != nil { return errors.Join(err, fmt.Errorf("failed to set config on registry")) @@ -846,7 +864,7 @@ func (a *AutomationTest) AddJobsAndSetConfig(t *testing.T) { l.Info().Str("Registry Address", a.Registry.Address()).Msg("Successfully setConfig on registry") } -func (a *AutomationTest) SetupMercuryMock(t *testing.T, imposters []ctfTestEnv.KillgraveImposter) { +func (a *AutomationTest) SetupMercuryMock(t *testing.T, imposters []ctftestenv.KillgraveImposter) { if a.IsOnk8s { t.Error("mercury mock is not supported on k8s") } @@ -874,61 +892,104 @@ func (a *AutomationTest) setupDeployment(t *testing.T, addJobs bool) { l.Info().Msg("Collected Node Details") l.Debug().Interface("Node Details", a.NodeDetails).Msg("Node Details") - err = a.DeployLINK() - require.NoError(t, err, "Error deploying link token contract") + if a.TestConfig.GetAutomationConfig().UseExistingLinkTokenContract() { + linkAddress, err := a.TestConfig.GetAutomationConfig().LinkTokenContractAddress() + require.NoError(t, err, "Error getting link token contract address") + err = a.LoadLINK(linkAddress.String()) + require.NoError(t, err, "Error loading link token contract") + } else { + err = a.DeployLINK() + require.NoError(t, err, "Error deploying link token contract") + } - err = a.DeployWETH() - require.NoError(t, err, "Error deploying weth token contract") + if a.TestConfig.GetAutomationConfig().UseExistingWethContract() { + wethAddress, err := a.TestConfig.GetAutomationConfig().WethContractAddress() + require.NoError(t, err, "Error getting weth token contract address") + err = a.LoadWETH(wethAddress.String()) + require.NoError(t, err, "Error loading weth token contract") + } else { + err = a.DeployWETH() + require.NoError(t, err, "Error deploying weth token contract") + } - err = a.DeployLinkEthFeed() - require.NoError(t, err, "Error deploying link eth feed contract") - err = a.DeployGasFeed() - require.NoError(t, err, "Error deploying gas feed contract") + if a.TestConfig.GetAutomationConfig().UseExistingLinkEthFeedContract() { + linkEthFeedAddress, err := a.TestConfig.GetAutomationConfig().LinkEthFeedContractAddress() + require.NoError(t, err, "Error getting link eth feed contract address") + err = a.LoadLinkEthFeed(linkEthFeedAddress.String()) + require.NoError(t, err, "Error loading link eth feed contract") + } else { + err = a.DeployLinkEthFeed() + require.NoError(t, err, "Error deploying link eth feed contract") + } - err = a.DeployEthUSDFeed() - require.NoError(t, err, "Error deploying eth usd feed contract") + if a.TestConfig.GetAutomationConfig().UseExistingEthGasFeedContract() { + gasFeedAddress, err := a.TestConfig.GetAutomationConfig().EthGasFeedContractAddress() + require.NoError(t, err, "Error getting gas feed contract address") + err = a.LoadEthGasFeed(gasFeedAddress.String()) + require.NoError(t, err, "Error loading gas feed contract") + } else { + err = a.DeployGasFeed() + require.NoError(t, err, "Error deploying gas feed contract") + } - err = a.DeployLinkUSDFeed() - require.NoError(t, err, "Error deploying link usd feed contract") + if a.TestConfig.GetAutomationConfig().UseExistingEthUSDFeedContract() { + ethUsdFeedAddress, err := a.TestConfig.GetAutomationConfig().EthUSDFeedContractAddress() + require.NoError(t, err, "Error getting eth usd feed contract address") + err = a.LoadEthUSDFeed(ethUsdFeedAddress.String()) + require.NoError(t, err, "Error loading eth usd feed contract") + } else { + err = a.DeployEthUSDFeed() + require.NoError(t, err, "Error deploying eth usd feed contract") + } - err = a.DeployTranscoder() - require.NoError(t, err, "Error deploying transcoder contract") + if a.TestConfig.GetAutomationConfig().UseExistingLinkUSDFeedContract() { + linkUsdFeedAddress, err := a.TestConfig.GetAutomationConfig().LinkUSDFeedContractAddress() + require.NoError(t, err, "Error getting link usd feed contract address") + err = a.LoadLinkUSDFeed(linkUsdFeedAddress.String()) + require.NoError(t, err, "Error loading link usd feed contract") + } else { + err = a.DeployLinkUSDFeed() + require.NoError(t, err, "Error deploying link usd feed contract") + } - err = a.DeployRegistry() - require.NoError(t, err, "Error deploying registry contract") - err = a.DeployRegistrar() - require.NoError(t, err, "Error deploying registrar contract") + if a.TestConfig.GetAutomationConfig().UseExistingTranscoderContract() { + transcoderAddress, err := a.TestConfig.GetAutomationConfig().TranscoderContractAddress() + require.NoError(t, err, "Error getting transcoder contract address") + err = a.LoadTranscoder(transcoderAddress.String()) + require.NoError(t, err, "Error loading transcoder contract") + } else { + err = a.DeployTranscoder() + require.NoError(t, err, "Error deploying transcoder contract") + } + + if a.TestConfig.GetAutomationConfig().UseExistingRegistryContract() { + chainModuleAddress, err := a.TestConfig.GetAutomationConfig().ChainModuleContractAddress() + require.NoError(t, err, "Error getting chain module contract address") + registryAddress, err := a.TestConfig.GetAutomationConfig().RegistryContractAddress() + require.NoError(t, err, "Error getting registry contract address") + err = a.LoadRegistry(registryAddress.String(), chainModuleAddress.String()) + require.NoError(t, err, "Error loading registry contract") + if a.Registry.RegistryOwnerAddress().String() != a.ChainClient.MustGetRootKeyAddress().String() { + l.Debug().Str("RootKeyAddress", a.ChainClient.MustGetRootKeyAddress().String()).Str("Registry Owner Address", a.Registry.RegistryOwnerAddress().String()).Msg("Registry owner address is not the root key address") + t.Error("Registry owner address is not the root key address") + t.FailNow() + } + } else { + err = a.DeployRegistry() + require.NoError(t, err, "Error deploying registry contract") + } + + if a.TestConfig.GetAutomationConfig().UseExistingRegistrarContract() { + registrarAddress, err := a.TestConfig.GetAutomationConfig().RegistrarContractAddress() + require.NoError(t, err, "Error getting registrar contract address") + err = a.LoadRegistrar(registrarAddress.String()) + require.NoError(t, err, "Error loading registrar contract") + } else { + err = a.DeployRegistrar() + require.NoError(t, err, "Error deploying registrar contract") + } if addJobs { a.AddJobsAndSetConfig(t) } } - -func (a *AutomationTest) LoadAutomationDeployment(t *testing.T, linkTokenAddress, - linkEthFeedAddress, linkUsdFeedAddress, EthUsdFeedAddress, gasFeedAddress, transcoderAddress, registryAddress, registrarAddress string) { - l := logging.GetTestLogger(t) - err := a.CollectNodeDetails() - require.NoError(t, err, "Error collecting node details") - l.Info().Msg("Collected Node Details") - l.Debug().Interface("Node Details", a.NodeDetails).Msg("Node Details") - - err = a.LoadLINK(linkTokenAddress) - require.NoError(t, err, "Error loading link token contract") - - err = a.LoadLinkEthFeed(linkEthFeedAddress) - require.NoError(t, err, "Error loading link eth feed contract") - err = a.LoadEthGasFeed(gasFeedAddress) - require.NoError(t, err, "Error loading gas feed contract") - err = a.LoadEthUSDFeed(EthUsdFeedAddress) - require.NoError(t, err, "Error loading eth usd feed contract") - err = a.LoadLinkUSDFeed(linkUsdFeedAddress) - require.NoError(t, err, "Error loading link usd feed contract") - err = a.LoadTranscoder(transcoderAddress) - require.NoError(t, err, "Error loading transcoder contract") - err = a.LoadRegistry(registryAddress) - require.NoError(t, err, "Error loading registry contract") - err = a.LoadRegistrar(registrarAddress) - require.NoError(t, err, "Error loading registrar contract") - - a.AddJobsAndSetConfig(t) -} diff --git a/integration-tests/actions/keeper_helpers.go b/integration-tests/actions/keeper_helpers.go index 80822a95af..c7694946cf 100644 --- a/integration-tests/actions/keeper_helpers.go +++ b/integration-tests/actions/keeper_helpers.go @@ -117,7 +117,7 @@ func DeployKeeperContracts( } registrar := DeployKeeperRegistrar(t, client, registryVersion, linkToken, registrarSettings, registry) - upkeeps, upkeepIds := DeployConsumers(t, client, registry, registrar, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, upkeepGasLimit, false, false, false, nil) + upkeeps, upkeepIds := DeployLegacyConsumers(t, client, registry, registrar, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, upkeepGasLimit, false, false, false, nil) return registry, registrar, upkeeps, upkeepIds } diff --git a/integration-tests/benchmark/automation_test.go b/integration-tests/benchmark/automation_test.go index 534fca2f51..0a63ff2c27 100644 --- a/integration-tests/benchmark/automation_test.go +++ b/integration-tests/benchmark/automation_test.go @@ -120,13 +120,15 @@ func TestAutomationBenchmark(t *testing.T) { if err = actions.TeardownRemoteSuite(keeperBenchmarkTest.TearDownVals(t)); err != nil { l.Error().Err(err).Msg("Error when tearing down remote suite") } else { - err := testEnvironment.Client.RemoveNamespace(testEnvironment.Cfg.Namespace) - if err != nil { - l.Error().Err(err).Msg("Error removing namespace") + if *config.GetAutomationConfig().Benchmark.DeleteJobsOnEnd { + err := testEnvironment.Client.RemoveNamespace(testEnvironment.Cfg.Namespace) + if err != nil { + l.Error().Err(err).Msg("Error removing namespace") + } } } }) - keeperBenchmarkTest.Setup(testEnvironment, &config) + keeperBenchmarkTest.Setup(testEnvironment, config) keeperBenchmarkTest.Run() } @@ -314,18 +316,19 @@ func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.Automation }, })) } - - // TODO we need to update the image in CTF, the old one is not available anymore - // deploy blockscout if running on simulated - // if testNetwork.Simulated { - // testEnvironment. - // AddChart(blockscout.New(&blockscout.Props{ - // Name: "geth-blockscout", - // WsURL: testNetwork.URLs[0], - // HttpURL: testNetwork.HTTPURLs[0]})) - // } - err := testEnvironment.Run() - require.NoError(t, err, "Error launching test environment") + var err error + if testNetwork.Simulated { + // TODO we need to update the image in CTF, the old one is not available anymore + // deploy blockscout if running on simulated + //testEnvironment. + // AddChart(blockscout.New(&blockscout.Props{ + // Name: "geth-blockscout", + // WsURL: testNetwork.URLs[0], + // HttpURL: testNetwork.HTTPURLs[0]})) + // Need to setup geth node before setting up chainlink nodes + err = testEnvironment.Run() + require.NoError(t, err, "Error launching test environment") + } if testEnvironment.WillUseRemoteRunner() { return testEnvironment, testNetwork diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go index cde5962390..c0823f482a 100644 --- a/integration-tests/chaos/automation_chaos_test.go +++ b/integration-tests/chaos/automation_chaos_test.go @@ -240,7 +240,7 @@ func TestAutomationChaos(t *testing.T) { require.NoError(t, err, "Error tearing down environment") }) - a := automationv2.NewAutomationTestK8s(l, chainClient, chainlinkNodes) + a := automationv2.NewAutomationTestK8s(l, chainClient, chainlinkNodes, &config) a.SetMercuryCredentialName("cred1") a.RegistrySettings = actions.ReadRegistryConfig(config) a.RegistrySettings.RegistryVersion = rv @@ -259,11 +259,11 @@ func TestAutomationChaos(t *testing.T) { var consumersLogTrigger, consumersConditional []contracts.KeeperConsumer var upkeepidsConditional, upkeepidsLogTrigger []*big.Int - consumersConditional, upkeepidsConditional = actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, false, false, false, nil) + consumersConditional, upkeepidsConditional = actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, false, false, false, nil, &config) consumers := consumersConditional upkeepIDs := upkeepidsConditional if rv >= eth_contracts.RegistryVersion_2_1 { - consumersLogTrigger, upkeepidsLogTrigger = actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, true, false, false, nil) + consumersLogTrigger, upkeepidsLogTrigger = actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, true, false, false, nil, &config) consumers = append(consumersConditional, consumersLogTrigger...) upkeepIDs = append(upkeepidsConditional, upkeepidsLogTrigger...) diff --git a/integration-tests/contracts/ethereum_contracts_automation.go b/integration-tests/contracts/ethereum_contracts_automation.go index d9d4a730c3..5a3e405d92 100644 --- a/integration-tests/contracts/ethereum_contracts_automation.go +++ b/integration-tests/contracts/ethereum_contracts_automation.go @@ -194,10 +194,11 @@ func (v *EthereumKeeperRegistry) RegistryOwnerAddress() common.Address { func (v *EthereumKeeperRegistry) SetConfigTypeSafe(ocrConfig OCRv2Config) error { txOpts := v.client.NewTXOpts() var err error + var decodedTx *seth.DecodedTransaction switch v.version { case ethereum.RegistryVersion_2_1: - _, err = v.client.Decode(v.registry2_1.SetConfigTypeSafe(txOpts, + decodedTx, err = v.client.Decode(v.registry2_1.SetConfigTypeSafe(txOpts, ocrConfig.Signers, ocrConfig.Transmitters, ocrConfig.F, @@ -206,7 +207,7 @@ func (v *EthereumKeeperRegistry) SetConfigTypeSafe(ocrConfig OCRv2Config) error ocrConfig.OffchainConfig, )) case ethereum.RegistryVersion_2_2: - _, err = v.client.Decode(v.registry2_2.SetConfigTypeSafe(txOpts, + decodedTx, err = v.client.Decode(v.registry2_2.SetConfigTypeSafe(txOpts, ocrConfig.Signers, ocrConfig.Transmitters, ocrConfig.F, @@ -215,7 +216,7 @@ func (v *EthereumKeeperRegistry) SetConfigTypeSafe(ocrConfig OCRv2Config) error ocrConfig.OffchainConfig, )) case ethereum.RegistryVersion_2_3: - _, err = v.client.Decode(v.registry2_3.SetConfigTypeSafe(txOpts, + decodedTx, err = v.client.Decode(v.registry2_3.SetConfigTypeSafe(txOpts, ocrConfig.Signers, ocrConfig.Transmitters, ocrConfig.F, @@ -228,7 +229,7 @@ func (v *EthereumKeeperRegistry) SetConfigTypeSafe(ocrConfig OCRv2Config) error default: return fmt.Errorf("SetConfigTypeSafe is not supported in keeper registry version %d", v.version) } - + v.l.Debug().Interface("decodedTx", decodedTx).Msg("SetConfigTypeSafe") return err } @@ -1528,7 +1529,7 @@ func deployRegistry23(client *seth.Client, opts *KeeperRegistryOpts) (KeeperRegi } // LoadKeeperRegistry returns deployed on given address EthereumKeeperRegistry -func LoadKeeperRegistry(l zerolog.Logger, client *seth.Client, address common.Address, registryVersion eth_contracts.KeeperRegistryVersion) (KeeperRegistry, error) { +func LoadKeeperRegistry(l zerolog.Logger, client *seth.Client, address common.Address, registryVersion eth_contracts.KeeperRegistryVersion, chainModuleAddress common.Address) (KeeperRegistry, error) { var keeper *EthereumKeeperRegistry var err error switch registryVersion { @@ -1545,7 +1546,7 @@ func LoadKeeperRegistry(l zerolog.Logger, client *seth.Client, address common.Ad case eth_contracts.RegistryVersion_2_2: // why the contract name is not the same as the actual contract name? keeper, err = loadRegistry2_2(client, address) case eth_contracts.RegistryVersion_2_3: - keeper, err = loadRegistry2_3(client, address) + keeper, err = loadRegistry2_3(client, address, chainModuleAddress) default: return nil, fmt.Errorf("keeper registry version %d is not supported", registryVersion) } @@ -1685,24 +1686,24 @@ func loadRegistry2_2(client *seth.Client, address common.Address) (*EthereumKeep }, nil } -func loadRegistry2_3(client *seth.Client, address common.Address) (*EthereumKeeperRegistry, error) { - abi, err := iregistry23.IAutomationRegistryMaster23MetaData.GetAbi() +func loadRegistry2_3(client *seth.Client, address, chainModuleAddress common.Address) (*EthereumKeeperRegistry, error) { + + loader := seth.NewContractLoader[iregistry23.IAutomationRegistryMaster23](client) + instance, err := loader.LoadContract("AutomationRegistry2_3", address, iregistry23.IAutomationRegistryMaster23MetaData.GetAbi, iregistry23.NewIAutomationRegistryMaster23) if err != nil { - return &EthereumKeeperRegistry{}, fmt.Errorf("failed to get AutomationRegistry2_3 ABI: %w", err) + return &EthereumKeeperRegistry{}, fmt.Errorf("failed to load AutomationRegistry2_3 instance: %w", err) } - client.ContractStore.AddABI("AutomationRegistry2_3", *abi) - client.ContractStore.AddBIN("AutomationRegistry2_3", common.FromHex(iregistry23.IAutomationRegistryMaster23MetaData.Bin)) - - instance, err := iregistry23.NewIAutomationRegistryMaster23(address, wrappers.MustNewWrappedContractBackend(nil, client)) + chainModule, err := loadChainModule(client, chainModuleAddress) if err != nil { - return &EthereumKeeperRegistry{}, fmt.Errorf("failed to instantiate AutomationRegistry2_3 instance: %w", err) + return &EthereumKeeperRegistry{}, fmt.Errorf("failed to load chain module: %w", err) } return &EthereumKeeperRegistry{ address: &address, client: client, registry2_3: instance, + chainModule: chainModule, }, nil } @@ -1758,6 +1759,26 @@ func deployOptimismModule(client *seth.Client) (common.Address, error) { return data.Address, nil } +func loadChainModule(client *seth.Client, address common.Address) (*i_chain_module.IChainModule, error) { + abi, err := i_chain_module.IChainModuleMetaData.GetAbi() + if err != nil { + return &i_chain_module.IChainModule{}, fmt.Errorf("failed to get IChainModule ABI: %w", err) + } + + client.ContractStore.AddABI("IChainModule", *abi) + client.ContractStore.AddBIN("IChainModule", common.FromHex(i_chain_module.IChainModuleMetaData.Bin)) + + chainModule, err := i_chain_module.NewIChainModule( + address, + wrappers.MustNewWrappedContractBackend(nil, client), + ) + if err != nil { + return &i_chain_module.IChainModule{}, fmt.Errorf("failed to instantiate IChainModule instance: %w", err) + } + + return chainModule, nil +} + func deployBaseModule(client *seth.Client) (common.Address, error) { abi, err := chain_module_base.ChainModuleBaseMetaData.GetAbi() if err != nil { @@ -2193,17 +2214,10 @@ func LoadKeeperRegistrar(client *seth.Client, address common.Address, registryVe if registryVersion == eth_contracts.RegistryVersion_1_1 || registryVersion == eth_contracts.RegistryVersion_1_2 || registryVersion == eth_contracts.RegistryVersion_1_3 { - abi, err := keeper_registrar_wrapper1_2.KeeperRegistrarMetaData.GetAbi() - if err != nil { - return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to get KeeperRegistrar1_2 ABI: %w", err) - } - - client.ContractStore.AddABI("KeeperRegistrar1_2", *abi) - client.ContractStore.AddBIN("KeeperRegistrar1_2", common.FromHex(keeper_registrar_wrapper1_2.KeeperRegistrarMetaData.Bin)) - - instance, err := keeper_registrar_wrapper1_2.NewKeeperRegistrar(address, wrappers.MustNewWrappedContractBackend(nil, client)) + loader := seth.NewContractLoader[keeper_registrar_wrapper1_2.KeeperRegistrar](client) + instance, err := loader.LoadContract("KeeperRegistrar1_2", address, keeper_registrar_wrapper1_2.KeeperRegistrarMetaData.GetAbi, keeper_registrar_wrapper1_2.NewKeeperRegistrar) if err != nil { - return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to instantiate KeeperRegistrar1_2 instance: %w", err) + return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to load KeeperRegistrar1_2 instance: %w", err) } return &EthereumKeeperRegistrar{ @@ -2212,44 +2226,43 @@ func LoadKeeperRegistrar(client *seth.Client, address common.Address, registryVe registrar: instance, }, err } else if registryVersion == eth_contracts.RegistryVersion_2_0 { - abi, err := keeper_registrar_wrapper2_0.KeeperRegistrarMetaData.GetAbi() + loader := seth.NewContractLoader[keeper_registrar_wrapper2_0.KeeperRegistrar](client) + instance, err := loader.LoadContract("KeeperRegistrar2_0", address, keeper_registrar_wrapper2_0.KeeperRegistrarMetaData.GetAbi, keeper_registrar_wrapper2_0.NewKeeperRegistrar) if err != nil { - return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to get KeeperRegistrar2_0 ABI: %w", err) + return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to load KeeperRegistrar2_0 instance: %w", err) } - client.ContractStore.AddABI("KeeperRegistrar2_0", *abi) - client.ContractStore.AddBIN("KeeperRegistrar2_0", common.FromHex(keeper_registrar_wrapper2_0.KeeperRegistrarMetaData.Bin)) - - instance, err := keeper_registrar_wrapper2_0.NewKeeperRegistrar(address, wrappers.MustNewWrappedContractBackend(nil, client)) + return &EthereumKeeperRegistrar{ + address: &address, + client: client, + registrar20: instance, + }, nil + } else if registryVersion == eth_contracts.RegistryVersion_2_1 || registryVersion == eth_contracts.RegistryVersion_2_2 { + loader := seth.NewContractLoader[registrar21.AutomationRegistrar](client) + instance, err := loader.LoadContract("KeeperRegistrar2_1", address, registrar21.AutomationRegistrarMetaData.GetAbi, registrar21.NewAutomationRegistrar) if err != nil { - return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to instantiate KeeperRegistrar2_0 instance: %w", err) + return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to load KeeperRegistrar2_1 instance: %w", err) } return &EthereumKeeperRegistrar{ address: &address, client: client, - registrar20: instance, + registrar21: instance, }, nil - } - - abi, err := registrar21.AutomationRegistrarMetaData.GetAbi() - if err != nil { - return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to get KeeperRegistrar2_1 ABI: %w", err) - } - - client.ContractStore.AddABI("KeeperRegistrar2_1", *abi) - client.ContractStore.AddBIN("KeeperRegistrar2_1", common.FromHex(registrar21.AutomationRegistrarMetaData.Bin)) + } else if registryVersion == eth_contracts.RegistryVersion_2_3 { + loader := seth.NewContractLoader[registrar23.AutomationRegistrar](client) + instance, err := loader.LoadContract("KeeperRegistrar2_3", address, registrar23.AutomationRegistrarMetaData.GetAbi, registrar23.NewAutomationRegistrar) + if err != nil { + return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to load KeeperRegistrar2_3 instance: %w", err) + } - instance, err := registrar21.NewAutomationRegistrar(address, wrappers.MustNewWrappedContractBackend(nil, client)) - if err != nil { - return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to instantiate KeeperRegistrar2_1 instance: %w", err) + return &EthereumKeeperRegistrar{ + address: &address, + client: client, + registrar23: instance, + }, nil } - - return &EthereumKeeperRegistrar{ - address: &address, - client: client, - registrar21: instance, - }, nil + return &EthereumKeeperRegistrar{}, fmt.Errorf("unsupported registry version: %v", registryVersion) } type EthereumAutomationLogTriggeredStreamsLookupUpkeepConsumer struct { @@ -2702,21 +2715,42 @@ func (v *EthereumAutomationConsumerBenchmark) GetUpkeepCount(ctx context.Context }, id) } -// DeployKeeperConsumerBenchmark deploys a keeper consumer benchmark contract with a standard contract backend -func DeployKeeperConsumerBenchmark(client *seth.Client) (AutomationConsumerBenchmark, error) { - return deployKeeperConsumerBenchmarkWithWrapperFn(client, func(client *seth.Client) *wrappers.WrappedContractBackend { +// DeployAutomationConsumerBenchmark deploys a keeper consumer benchmark contract with a standard contract backend +func DeployAutomationConsumerBenchmark(client *seth.Client) (AutomationConsumerBenchmark, error) { + return deployAutomationConsumerBenchmarkWithWrapperFn(client, func(client *seth.Client) *wrappers.WrappedContractBackend { return wrappers.MustNewWrappedContractBackend(nil, client) }) } -// DeployKeeperConsumerBenchmarkWithRetry deploys a keeper consumer benchmark contract with a read-only operations retrying contract backend -func DeployKeeperConsumerBenchmarkWithRetry(client *seth.Client, logger zerolog.Logger, maxAttempts uint, retryDelay time.Duration) (AutomationConsumerBenchmark, error) { - return deployKeeperConsumerBenchmarkWithWrapperFn(client, func(client *seth.Client) *wrappers.WrappedContractBackend { +func LoadAutomationConsumerBenchmark(client *seth.Client, address common.Address) (*EthereumAutomationConsumerBenchmark, error) { + abi, err := automation_consumer_benchmark.AutomationConsumerBenchmarkMetaData.GetAbi() + if err != nil { + return &EthereumAutomationConsumerBenchmark{}, fmt.Errorf("failed to get AutomationConsumerBenchmark token ABI: %w", err) + } + + client.ContractStore.AddABI("AutomationConsumerBenchmark", *abi) + client.ContractStore.AddBIN("AutomationConsumerBenchmark", common.FromHex(automation_consumer_benchmark.AutomationConsumerBenchmarkMetaData.Bin)) + + consumer, err := automation_consumer_benchmark.NewAutomationConsumerBenchmark(address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumAutomationConsumerBenchmark{}, fmt.Errorf("failed to instantiate EthereumAutomationConsumerBenchmark instance: %w", err) + } + + return &EthereumAutomationConsumerBenchmark{ + client: client, + consumer: consumer, + address: &address, + }, nil +} + +// DeployAutomationConsumerBenchmarkWithRetry deploys a keeper consumer benchmark contract with a read-only operations retrying contract backend +func DeployAutomationConsumerBenchmarkWithRetry(client *seth.Client, logger zerolog.Logger, maxAttempts uint, retryDelay time.Duration) (AutomationConsumerBenchmark, error) { + return deployAutomationConsumerBenchmarkWithWrapperFn(client, func(client *seth.Client) *wrappers.WrappedContractBackend { return wrappers.MustNewRetryingWrappedContractBackend(client, logger, maxAttempts, retryDelay) }) } -func deployKeeperConsumerBenchmarkWithWrapperFn(client *seth.Client, wrapperConstrFn func(client *seth.Client) *wrappers.WrappedContractBackend) (AutomationConsumerBenchmark, error) { +func deployAutomationConsumerBenchmarkWithWrapperFn(client *seth.Client, wrapperConstrFn func(client *seth.Client) *wrappers.WrappedContractBackend) (AutomationConsumerBenchmark, error) { abi, err := automation_consumer_benchmark.AutomationConsumerBenchmarkMetaData.GetAbi() if err != nil { return &EthereumAutomationConsumerBenchmark{}, fmt.Errorf("failed to get AutomationConsumerBenchmark ABI: %w", err) @@ -2738,8 +2772,8 @@ func deployKeeperConsumerBenchmarkWithWrapperFn(client *seth.Client, wrapperCons }, nil } -// KeeperConsumerBenchmarkUpkeepObserver is a header subscription that awaits for a round of upkeeps -type KeeperConsumerBenchmarkUpkeepObserver struct { +// AutomationConsumerBenchmarkUpkeepObserver is a header subscription that awaits for a round of upkeeps +type AutomationConsumerBenchmarkUpkeepObserver struct { instance AutomationConsumerBenchmark registry KeeperRegistry upkeepID *big.Int @@ -2763,9 +2797,9 @@ type KeeperConsumerBenchmarkUpkeepObserver struct { l zerolog.Logger } -// NewKeeperConsumerBenchmarkUpkeepObserver provides a new instance of a NewKeeperConsumerBenchmarkUpkeepObserver +// NewAutomationConsumerBenchmarkUpkeepObserver provides a new instance of a NewAutomationConsumerBenchmarkUpkeepObserver // Used to track and log benchmark test results for keepers -func NewKeeperConsumerBenchmarkUpkeepObserver( +func NewAutomationConsumerBenchmarkUpkeepObserver( contract AutomationConsumerBenchmark, registry KeeperRegistry, upkeepID *big.Int, @@ -2775,8 +2809,8 @@ func NewKeeperConsumerBenchmarkUpkeepObserver( upkeepIndex int64, firstEligibleBuffer int64, logger zerolog.Logger, -) *KeeperConsumerBenchmarkUpkeepObserver { - return &KeeperConsumerBenchmarkUpkeepObserver{ +) *AutomationConsumerBenchmarkUpkeepObserver { + return &AutomationConsumerBenchmarkUpkeepObserver{ instance: contract, registry: registry, upkeepID: upkeepID, @@ -2798,7 +2832,7 @@ func NewKeeperConsumerBenchmarkUpkeepObserver( // ReceiveHeader will query the latest Keeper round and check to see whether upkeep was performed, it returns // true when observation has finished. -func (o *KeeperConsumerBenchmarkUpkeepObserver) ReceiveHeader(receivedHeader *blockchain.SafeEVMHeader) (bool, error) { +func (o *AutomationConsumerBenchmarkUpkeepObserver) ReceiveHeader(receivedHeader *blockchain.SafeEVMHeader) (bool, error) { if receivedHeader.Number.Uint64() <= o.lastBlockNum { // Uncle / reorg we won't count return false, nil } @@ -2901,12 +2935,12 @@ func (o *KeeperConsumerBenchmarkUpkeepObserver) ReceiveHeader(receivedHeader *bl } // Complete returns whether watching for upkeeps has completed -func (o *KeeperConsumerBenchmarkUpkeepObserver) Complete() bool { +func (o *AutomationConsumerBenchmarkUpkeepObserver) Complete() bool { return o.complete } // LogDetails logs the results of the benchmark test to testreporter -func (o *KeeperConsumerBenchmarkUpkeepObserver) LogDetails() { +func (o *AutomationConsumerBenchmarkUpkeepObserver) LogDetails() { report := testreporters.KeeperBenchmarkTestReport{ ContractAddress: o.instance.Address(), TotalEligibleCount: o.countEligible, diff --git a/integration-tests/load/automationv2_1/automationv2_1_test.go b/integration-tests/load/automationv2_1/automationv2_1_test.go index 6c49d1be44..3cd931ecef 100644 --- a/integration-tests/load/automationv2_1/automationv2_1_test.go +++ b/integration-tests/load/automationv2_1/automationv2_1_test.go @@ -311,7 +311,7 @@ Load Config: multicallAddress, err := contracts.DeployMultiCallContract(chainClient) require.NoError(t, err, "Error deploying multicall contract") - a := automationv2.NewAutomationTestK8s(l, chainClient, chainlinkNodes) + a := automationv2.NewAutomationTestK8s(l, chainClient, chainlinkNodes, &loadedTestConfig) a.RegistrySettings = actions.ReadRegistryConfig(loadedTestConfig) a.RegistrySettings.RegistryVersion = registryVersion a.PluginConfig = actions.ReadPluginConfig(loadedTestConfig) diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index 85ca4b4264..fde37d9f06 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -132,7 +132,7 @@ func TestAutomationReorg(t *testing.T) { gethRPCClient := ctfClient.NewRPCClient(evmNetwork.HTTPURLs[0], nil) - a := automationv2.NewAutomationTestDocker(l, sethClient, nodeClients) + a := automationv2.NewAutomationTestDocker(l, sethClient, nodeClients, &config) a.SetMercuryCredentialName("cred1") a.RegistrySettings = actions.ReadRegistryConfig(config) a.RegistrySettings.RegistryVersion = registryVersion @@ -169,6 +169,7 @@ func TestAutomationReorg(t *testing.T) { false, false, a.WETHToken, + &config, ) if isLogTrigger { diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index f5a329a1a2..2e56237e9c 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -20,7 +20,7 @@ import ( "github.com/onsi/gomega" "github.com/stretchr/testify/require" - ctfTestEnv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" + ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" @@ -142,6 +142,7 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { isMercury, isBillingTokenNative, a.WETHToken, + &cfg, ) // Do it in two separate loops, so we don't end up setting up one upkeep, but starting the consumer for another one @@ -268,20 +269,7 @@ func TestSetUpkeepTriggerConfig(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - true, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, true, false, false, nil, &config) // Start log trigger based upkeeps for all consumers for i := 0; i < len(consumers); i++ { @@ -451,20 +439,7 @@ func TestAutomationAddFunds(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(1), - automationDefaultUpkeepGasLimit, - false, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(1), automationDefaultUpkeepGasLimit, false, false, false, nil, &config) t.Cleanup(func() { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() @@ -531,20 +506,7 @@ func TestAutomationPauseUnPause(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - false, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false, false, false, nil, &config) t.Cleanup(func() { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() @@ -632,20 +594,7 @@ func TestAutomationRegisterUpkeep(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - false, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false, false, false, nil, &config) t.Cleanup(func() { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() @@ -728,20 +677,7 @@ func TestAutomationPauseRegistry(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - false, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false, false, false, nil, &config) t.Cleanup(func() { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() @@ -808,20 +744,7 @@ func TestAutomationKeeperNodesDown(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - false, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false, false, false, nil, &config) t.Cleanup(func() { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() @@ -929,6 +852,7 @@ func TestAutomationPerformSimulation(t *testing.T) { 5, // Interval of blocks that upkeeps are expected to be performed 100000, // How much gas should be burned on checkUpkeep() calls 4000000, // How much gas should be burned on performUpkeep() calls. Initially set higher than defaultUpkeepGasLimit + &config, ) t.Cleanup(func() { @@ -1000,6 +924,7 @@ func TestAutomationCheckPerformGasLimit(t *testing.T) { 5, // Interval of blocks that upkeeps are expected to be performed 100000, // How much gas should be burned on checkUpkeep() calls 4000000, // How much gas should be burned on performUpkeep() calls. Initially set higher than defaultUpkeepGasLimit + &config, ) t.Cleanup(func() { @@ -1152,6 +1077,7 @@ func TestUpdateCheckData(t *testing.T) { big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, []byte(automationExpectedData), + &config, ) t.Cleanup(func() { @@ -1223,20 +1149,7 @@ func TestSetOffchainConfigWithMaxGasPrice(t *testing.T) { sb, err := a.ChainClient.Client.BlockNumber(context.Background()) require.NoError(t, err, "Failed to get start block") - consumers, upkeepIDs := actions.DeployConsumers( - t, - a.ChainClient, - a.Registry, - a.Registrar, - a.LinkToken, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - false, - false, - false, - nil, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, a.ChainClient, a.Registry, a.Registrar, a.LinkToken, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false, false, false, nil, &config) t.Cleanup(func() { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() @@ -1435,7 +1348,7 @@ func setupAutomationTestDocker( _ = actions.ReturnFundsFromNodes(l, sethClient, contracts.ChainlinkClientToChainlinkNodeWithKeysAndAddress(env.ClCluster.NodeAPIs())) }) - a := automationv2.NewAutomationTestDocker(l, sethClient, nodeClients) + a := automationv2.NewAutomationTestDocker(l, sethClient, nodeClients, automationTestConfig) a.SetMercuryCredentialName("cred1") a.RegistrySettings = registryConfig a.RegistrarSettings = contracts.KeeperRegistrarSettings{ @@ -1450,16 +1363,16 @@ func setupAutomationTestDocker( a.SetDockerEnv(env) if isMercuryV02 || isMercuryV03 { - var imposters []ctfTestEnv.KillgraveImposter - mercuryv03Mock200 := ctfTestEnv.KillgraveImposter{ - Request: ctfTestEnv.KillgraveRequest{ + var imposters []ctftestenv.KillgraveImposter + mercuryv03Mock200 := ctftestenv.KillgraveImposter{ + Request: ctftestenv.KillgraveRequest{ Method: http.MethodGet, Endpoint: "/api/v1/reports/bulk", SchemaFile: nil, Params: &map[string]string{"feedIDs": "0x00028c915d6af0fd66bba2d0fc9405226bca8d6806333121a7d9832103d1563c", "timestamp": "{[\\d+]}"}, Headers: nil, }, - Response: ctfTestEnv.KillgraveResponse{ + Response: ctftestenv.KillgraveResponse{ Status: 200, Body: `{"reports":[{"feedID":"0x00028c915d6af0fd66bba2d0fc9405226bca8d6806333121a7d9832103d1563c","validFromTimestamp":0,"observationsTimestamp":0,"fullReport":"0x00066dfcd1ed2d95b18c948dbc5bd64c687afe93e4ca7d663ddec14c20090ad80000000000000000000000000000000000000000000000000000000000081401000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204554482d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064891c98000000000000000000000000000000000000000000000000000000289ad8d367000000000000000000000000000000000000000000000000000000289acf0b38000000000000000000000000000000000000000000000000000000289b3da40000000000000000000000000000000000000000000000000000000000018ae7ce74d9fa252a8983976eab600dc7590c778d04813430841bc6e765c34cd81a168d00000000000000000000000000000000000000000000000000000000018ae7cb0000000000000000000000000000000000000000000000000000000064891c98000000000000000000000000000000000000000000000000000000000000000260412b94e525ca6cedc9f544fd86f77606d52fe731a5d069dbe836a8bfc0fb8c911963b0ae7a14971f3b4621bffb802ef0605392b9a6c89c7fab1df8633a5ade00000000000000000000000000000000000000000000000000000000000000024500c2f521f83fba5efc2bf3effaaedde43d0a4adff785c1213b712a3aed0d8157642a84324db0cf9695ebd27708d4608eb0337e0dd87b0e43f0fa70c700d911"}]}`, BodyFile: nil, @@ -1468,15 +1381,15 @@ func setupAutomationTestDocker( }, } - mercuryv02Mock200 := ctfTestEnv.KillgraveImposter{ - Request: ctfTestEnv.KillgraveRequest{ + mercuryv02Mock200 := ctftestenv.KillgraveImposter{ + Request: ctftestenv.KillgraveRequest{ Method: http.MethodGet, Endpoint: "/client", SchemaFile: nil, Params: &map[string]string{"feedIdHex": "{0x00028c915d6af0fd66bba2d0fc9405226bca8d6806333121a7d9832103d1563c|0x4554482d5553442d415242495452554d2d544553544e45540000000000000000}", "blockNumber": "{[\\d+]}"}, Headers: nil, }, - Response: ctfTestEnv.KillgraveResponse{ + Response: ctftestenv.KillgraveResponse{ Status: 200, Body: `{"chainlinkBlob":"0x0001c38d71fed6c320b90e84b6f559459814d068e2a1700adc931ca9717d4fe70000000000000000000000000000000000000000000000000000000001a80b52b4bf1233f9cb71144a253a1791b202113c4ab4a92fa1b176d684b4959666ff8200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001004254432d5553442d415242495452554d2d544553544e4554000000000000000000000000000000000000000000000000000000000000000000000000645570be000000000000000000000000000000000000000000000000000002af2b818dc5000000000000000000000000000000000000000000000000000002af2426faf3000000000000000000000000000000000000000000000000000002af32dc209700000000000000000000000000000000000000000000000000000000012130f8df0a9745bb6ad5e2df605e158ba8ad8a33ef8a0acf9851f0f01668a3a3f2b68600000000000000000000000000000000000000000000000000000000012130f60000000000000000000000000000000000000000000000000000000000000002c4a7958dce105089cf5edb68dad7dcfe8618d7784eb397f97d5a5fade78c11a58275aebda478968e545f7e3657aba9dcbe8d44605e4c6fde3e24edd5e22c94270000000000000000000000000000000000000000000000000000000000000002459c12d33986018a8959566d145225f0c4a4e61a9a3f50361ccff397899314f0018162cf10cd89897635a0bb62a822355bd199d09f4abe76e4d05261bb44733d"}`, BodyFile: nil, diff --git a/integration-tests/smoke/log_poller_test.go b/integration-tests/smoke/log_poller_test.go index c7f5483ac1..b5891e7a3e 100644 --- a/integration-tests/smoke/log_poller_test.go +++ b/integration-tests/smoke/log_poller_test.go @@ -306,20 +306,7 @@ func prepareEnvironment(l zerolog.Logger, t *testing.T, testConfig *tc.TestConfi logScannerSettings, ) - _, upkeepIDs := actions.DeployConsumers( - t, - chainClient, - registry, - registrar, - linkToken, - upKeepsNeeded, - big.NewInt(int64(9e18)), - uint32(2500000), - true, - false, - false, - nil, - ) + _, upkeepIDs := actions.DeployLegacyConsumers(t, chainClient, registry, registrar, linkToken, upKeepsNeeded, big.NewInt(int64(9e18)), uint32(2500000), true, false, false, nil) err = logpoller.AssertUpkeepIdsUniqueness(upkeepIDs) require.NoError(t, err, "Error asserting upkeep ids uniqueness") diff --git a/integration-tests/testconfig/automation/config.go b/integration-tests/testconfig/automation/config.go index 2dc68ebf8f..e462ff15c1 100644 --- a/integration-tests/testconfig/automation/config.go +++ b/integration-tests/testconfig/automation/config.go @@ -2,9 +2,12 @@ package automation import ( "errors" + "fmt" "math/big" "time" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" ) @@ -15,6 +18,7 @@ type Config struct { AutomationConfig *AutomationConfig `toml:"AutomationConfig"` Resiliency *ResiliencyConfig `toml:"Resiliency"` Benchmark *Benchmark `toml:"Benchmark"` + Contracts *Contracts `toml:"Contracts"` } func (c *Config) Validate() error { @@ -417,3 +421,429 @@ func (c *ResiliencyConfig) Validate() error { return nil } + +type Contracts struct { + ShouldBeUsed *bool `toml:"use"` + LinkTokenAddress *string `toml:"link_token"` + WethAddress *string `toml:"weth"` + TranscoderAddress *string `toml:"transcoder"` + ChainModuleAddress *string `toml:"chain_module"` + RegistryAddress *string `toml:"registry"` + RegistrarAddress *string `toml:"registrar"` + LinkEthFeedAddress *string `toml:"link_eth_feed"` + EthGasFeedAddress *string `toml:"eth_gas_feed"` + EthUSDFeedAddress *string `toml:"eth_usd_feed"` + LinkUSDFeedAddress *string `toml:"link_usd_feed"` + UpkeepContractAddresses []string `toml:"upkeep_contracts"` + MultiCallAddress *string `toml:"multicall"` + Settings map[string]ContractSetting `toml:"Settings"` +} + +func (o *Contracts) Validate() error { + if o.LinkTokenAddress != nil && !common.IsHexAddress(*o.LinkTokenAddress) { + return errors.New("link_token must be a valid ethereum address") + } + if o.WethAddress != nil && !common.IsHexAddress(*o.WethAddress) { + return errors.New("weth must be a valid ethereum address") + } + if o.TranscoderAddress != nil && !common.IsHexAddress(*o.TranscoderAddress) { + return errors.New("transcoder must be a valid ethereum address") + } + if o.ChainModuleAddress != nil && !common.IsHexAddress(*o.ChainModuleAddress) { + return errors.New("chain_module must be a valid ethereum address") + } + if o.RegistryAddress != nil && !common.IsHexAddress(*o.RegistryAddress) { + return errors.New("registry must be a valid ethereum address") + } + if o.RegistrarAddress != nil && !common.IsHexAddress(*o.RegistrarAddress) { + return errors.New("registrar must be a valid ethereum address") + } + if o.LinkEthFeedAddress != nil && !common.IsHexAddress(*o.LinkEthFeedAddress) { + return errors.New("link_eth_feed must be a valid ethereum address") + } + if o.EthGasFeedAddress != nil && !common.IsHexAddress(*o.EthGasFeedAddress) { + return errors.New("eth_gas_feed must be a valid ethereum address") + } + if o.EthUSDFeedAddress != nil && !common.IsHexAddress(*o.EthUSDFeedAddress) { + return errors.New("eth_usd_feed must be a valid ethereum address") + } + if o.LinkUSDFeedAddress != nil && !common.IsHexAddress(*o.LinkUSDFeedAddress) { + return errors.New("link_usd_feed must be a valid ethereum address") + } + if o.MultiCallAddress != nil && !common.IsHexAddress(*o.MultiCallAddress) { + return errors.New("multicall must be a valid ethereum address") + } + if o.UpkeepContractAddresses != nil { + allEnabled := make(map[bool]int) + allConfigure := make(map[bool]int) + for _, address := range o.UpkeepContractAddresses { + if !common.IsHexAddress(address) { + return fmt.Errorf("upkeep_contracts must be valid ethereum addresses, but %s is not", address) + } + + if v, ok := o.Settings[address]; ok { + if v.ShouldBeUsed != nil { + allEnabled[*v.ShouldBeUsed]++ + } else { + allEnabled[true]++ + } + if v.Configure != nil { + allConfigure[*v.Configure]++ + } else { + allConfigure[true]++ + } + } + } + + if allEnabled[true] > 0 && allEnabled[false] > 0 { + return errors.New("either all or none offchain_aggregators must be used") + } + + if allConfigure[true] > 0 && allConfigure[false] > 0 { + return errors.New("either all or none offchain_aggregators must be configured") + } + } + + return nil +} + +func (c *Config) UseExistingContracts() bool { + if c.Contracts == nil { + return false + } + + if c.Contracts.ShouldBeUsed != nil { + return *c.Contracts.ShouldBeUsed + } + + return false +} + +func (c *Config) LinkTokenContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.LinkTokenAddress != nil { + return common.HexToAddress(*c.Contracts.LinkTokenAddress), nil + } + + return common.Address{}, errors.New("link token address must be set") +} + +func (c *Config) WethContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.WethAddress != nil { + return common.HexToAddress(*c.Contracts.WethAddress), nil + } + + return common.Address{}, errors.New("weth address must be set") +} + +func (c *Config) TranscoderContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.TranscoderAddress != nil { + return common.HexToAddress(*c.Contracts.TranscoderAddress), nil + } + + return common.Address{}, errors.New("transcoder address must be set") +} + +func (c *Config) ChainModuleContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.ChainModuleAddress != nil { + return common.HexToAddress(*c.Contracts.ChainModuleAddress), nil + } + + return common.Address{}, errors.New("chain module address must be set") +} + +func (c *Config) RegistryContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.RegistryAddress != nil { + return common.HexToAddress(*c.Contracts.RegistryAddress), nil + } + + return common.Address{}, errors.New("registry address must be set") +} + +func (c *Config) RegistrarContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.RegistrarAddress != nil { + return common.HexToAddress(*c.Contracts.RegistrarAddress), nil + } + + return common.Address{}, errors.New("registrar address must be set") +} + +func (c *Config) LinkEthFeedContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.LinkEthFeedAddress != nil { + return common.HexToAddress(*c.Contracts.LinkEthFeedAddress), nil + } + + return common.Address{}, errors.New("link eth feed address must be set") +} + +func (c *Config) EthGasFeedContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.EthGasFeedAddress != nil { + return common.HexToAddress(*c.Contracts.EthGasFeedAddress), nil + } + + return common.Address{}, errors.New("eth gas feed address must be set") +} + +func (c *Config) EthUSDFeedContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.EthUSDFeedAddress != nil { + return common.HexToAddress(*c.Contracts.EthUSDFeedAddress), nil + } + + return common.Address{}, errors.New("eth usd feed address must be set") +} + +func (c *Config) LinkUSDFeedContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.LinkUSDFeedAddress != nil { + return common.HexToAddress(*c.Contracts.LinkUSDFeedAddress), nil + } + + return common.Address{}, errors.New("link usd feed address must be set") +} + +func (c *Config) UpkeepContractAddresses() ([]common.Address, error) { + if c.Contracts != nil && c.Contracts.UpkeepContractAddresses != nil { + addresses := make([]common.Address, len(c.Contracts.UpkeepContractAddresses)) + for i, address := range c.Contracts.UpkeepContractAddresses { + addresses[i] = common.HexToAddress(address) + } + return addresses, nil + } + + return nil, errors.New("upkeep contract addresses must be set") +} + +func (c *Config) MultiCallContractAddress() (common.Address, error) { + if c.Contracts != nil && c.Contracts.MultiCallAddress != nil { + return common.HexToAddress(*c.Contracts.MultiCallAddress), nil + } + + return common.Address{}, errors.New("multicall address must be set") +} + +func (c *Config) UseExistingLinkTokenContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.LinkTokenAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.LinkTokenAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingWethContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.WethAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.WethAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingTranscoderContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.TranscoderAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.TranscoderAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingRegistryContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.RegistryAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.RegistryAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingRegistrarContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.RegistrarAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.RegistrarAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingLinkEthFeedContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.LinkEthFeedAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.LinkEthFeedAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingEthGasFeedContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.EthGasFeedAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.EthGasFeedAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingEthUSDFeedContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.EthUSDFeedAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.EthUSDFeedAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingLinkUSDFeedContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.LinkUSDFeedAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.LinkUSDFeedAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +func (c *Config) UseExistingUpkeepContracts() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.UpkeepContractAddresses == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + for _, address := range c.Contracts.UpkeepContractAddresses { + if v, ok := c.Contracts.Settings[address]; ok { + if v.ShouldBeUsed != nil && *v.ShouldBeUsed { + return true + } + } + } + + return false +} + +func (c *Config) UseExistingMultiCallContract() bool { + if !c.UseExistingContracts() { + return false + } + + if c.Contracts.MultiCallAddress == nil { + return false + } + + if len(c.Contracts.Settings) == 0 { + return true + } + + if v, ok := c.Contracts.Settings[*c.Contracts.MultiCallAddress]; ok { + return v.ShouldBeUsed != nil && *v.ShouldBeUsed + } + + return true +} + +type ContractSetting struct { + ShouldBeUsed *bool `toml:"use"` + Configure *bool `toml:"configure"` +} diff --git a/integration-tests/testsetups/keeper_benchmark.go b/integration-tests/testsetups/automation_benchmark.go similarity index 94% rename from integration-tests/testsetups/keeper_benchmark.go rename to integration-tests/testsetups/automation_benchmark.go index 40a56ba73c..ff8100ea43 100644 --- a/integration-tests/testsetups/keeper_benchmark.go +++ b/integration-tests/testsetups/automation_benchmark.go @@ -12,6 +12,8 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/actions/automationv2" geth "github.com/ethereum/go-ethereum" @@ -105,14 +107,14 @@ func NewKeeperBenchmarkTest(t *testing.T, inputs KeeperBenchmarkTestInputs) *Kee } // Setup prepares contracts for the test -func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.AutomationBenchmarkTestConfig) { +func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config testconfig.TestConfig) { startTime := time.Now() k.TestReporter.Summary.StartTime = startTime.UnixMilli() k.ensureInputValues() k.env = env k.namespace = k.env.Cfg.Namespace inputs := k.Inputs - k.testConfig = config + k.testConfig = &config k.automationTests = make([]automationv2.AutomationTest, len(inputs.RegistryVersions)) k.keeperRegistries = make([]contracts.KeeperRegistry, len(inputs.RegistryVersions)) @@ -146,7 +148,7 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Auto for index := range inputs.RegistryVersions { k.log.Info().Int("Index", index).Msg("Starting Test Setup") - a := automationv2.NewAutomationTestK8s(k.log, k.chainClient, k.chainlinkNodes) + a := automationv2.NewAutomationTestK8s(k.log, k.chainClient, k.chainlinkNodes, &config) a.RegistrySettings = *k.Inputs.KeeperRegistrySettings a.RegistrySettings.RegistryVersion = inputs.RegistryVersions[index] a.RegistrarSettings = contracts.KeeperRegistrarSettings{ @@ -159,7 +161,7 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Auto a.SetupAutomationDeploymentWithoutJobs(k.t) err = a.SetConfigOnRegistry() require.NoError(k.t, err, "Setting initial config on registry shouldn't fail") - k.DeployBenchmarkKeeperContracts(index, a) + k.SetupBenchmarkKeeperContracts(index, a) } var keysToFund = inputs.RegistryVersions @@ -178,7 +180,7 @@ func (k *KeeperBenchmarkTest) Setup(env *environment.Environment, config tt.Auto } k.log.Info().Str("Setup Time", time.Since(startTime).String()).Msg("Finished Keeper Benchmark Test Setup") - err = k.SendSlackNotification(nil, config) + err = k.SendSlackNotification(nil, &config) if err != nil { k.log.Warn().Msg("Sending test start slack notification failed") } @@ -301,7 +303,7 @@ func (k *KeeperBenchmarkTest) Run() { startedObservations.Add(1) k.log.Info().Int("Channel index", chIndex).Str("UpkeepID", upkeepIDCopy.String()).Msg("Starting upkeep observation") - confirmer := contracts.NewKeeperConsumerBenchmarkUpkeepObserver( + confirmer := contracts.NewAutomationConsumerBenchmarkUpkeepObserver( k.keeperConsumerContracts[registryIndex], k.keeperRegistries[registryIndex], upkeepIDCopy, @@ -650,8 +652,8 @@ func (k *KeeperBenchmarkTest) SendSlackNotification(slackClient *slack.Client, c return err } -// DeployBenchmarkKeeperContracts deploys a set amount of keeper Benchmark contracts registered to a single registry -func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int, a *automationv2.AutomationTest) { +// SetupBenchmarkKeeperContracts deploys a set amount of keeper Benchmark contracts registered to a single registry +func (k *KeeperBenchmarkTest) SetupBenchmarkKeeperContracts(index int, a *automationv2.AutomationTest) { registryVersion := k.Inputs.RegistryVersions[index] k.Inputs.KeeperRegistrySettings.RegistryVersion = registryVersion upkeep := k.Inputs.Upkeeps @@ -659,7 +661,15 @@ func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int, a *autom err error ) - consumer := k.DeployKeeperConsumersBenchmark() + var consumer contracts.AutomationConsumerBenchmark + if a.TestConfig.GetAutomationConfig().UseExistingUpkeepContracts() { + benchmarkAddresses, err := a.TestConfig.GetAutomationConfig().UpkeepContractAddresses() + require.NoError(k.t, err, "Getting upkeep contract addresses shouldn't fail") + consumer, err = contracts.LoadAutomationConsumerBenchmark(k.chainClient, benchmarkAddresses[0]) + require.NoError(k.t, err, "Loading KeeperConsumerBenchmark shouldn't fail") + } else { + consumer = k.DeployKeeperConsumersBenchmark() + } var upkeepAddresses []string @@ -710,7 +720,7 @@ func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int, a *autom linkFunds = big.NewInt(0).Add(linkFunds, minLinkBalance) k.linkToken = a.LinkToken - err = actions.DeployMultiCallAndFundDeploymentAddresses(k.chainClient, k.linkToken, upkeep.NumberOfUpkeeps, linkFunds) + err = actions.SetupMultiCallAndFundDeploymentAddresses(k.chainClient, k.linkToken, upkeep.NumberOfUpkeeps, linkFunds, a.TestConfig) require.NoError(k.t, err, "Sending link funds to deployment addresses shouldn't fail") upkeepIds := actions.RegisterUpkeepContractsWithCheckData(k.t, k.chainClient, k.linkToken, linkFunds, uint32(upkeep.UpkeepGasLimit), a.Registry, a.Registrar, upkeep.NumberOfUpkeeps, upkeepAddresses, checkData, false, false, false, nil) @@ -729,17 +739,17 @@ func (k *KeeperBenchmarkTest) DeployKeeperConsumersBenchmark() contracts.Automat if *k.testConfig.GetAutomationConfig().Resiliency.ContractCallLimit != 0 && k.testConfig.GetAutomationConfig().Resiliency.ContractCallInterval.Duration != 0 { maxRetryAttempts := *k.testConfig.GetAutomationConfig().Resiliency.ContractCallLimit callRetryDelay := k.testConfig.GetAutomationConfig().Resiliency.ContractCallInterval.Duration - keeperConsumerInstance, err = contracts.DeployKeeperConsumerBenchmarkWithRetry(k.chainClient, k.log, maxRetryAttempts, callRetryDelay) + keeperConsumerInstance, err = contracts.DeployAutomationConsumerBenchmarkWithRetry(k.chainClient, k.log, maxRetryAttempts, callRetryDelay) if err != nil { k.log.Error().Err(err).Msg("Deploying AutomationConsumerBenchmark instance shouldn't fail") - keeperConsumerInstance, err = contracts.DeployKeeperConsumerBenchmarkWithRetry(k.chainClient, k.log, maxRetryAttempts, callRetryDelay) + keeperConsumerInstance, err = contracts.DeployAutomationConsumerBenchmarkWithRetry(k.chainClient, k.log, maxRetryAttempts, callRetryDelay) require.NoError(k.t, err, "Error deploying AutomationConsumerBenchmark") } } else { - keeperConsumerInstance, err = contracts.DeployKeeperConsumerBenchmark(k.chainClient) + keeperConsumerInstance, err = contracts.DeployAutomationConsumerBenchmark(k.chainClient) if err != nil { k.log.Error().Err(err).Msg("Deploying AutomationConsumerBenchmark instance %d shouldn't fail") - keeperConsumerInstance, err = contracts.DeployKeeperConsumerBenchmark(k.chainClient) + keeperConsumerInstance, err = contracts.DeployAutomationConsumerBenchmark(k.chainClient) require.NoError(k.t, err, "Error deploying AutomationConsumerBenchmark") } } From 77612582b7b975178eda0c70300af14685a6658e Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Mon, 23 Sep 2024 10:59:21 +0200 Subject: [PATCH 399/432] add CTF deps to dependabot (#14517) * add CTF deps to dependabot * add ctf label * fix registry definition * remove registry * fix changeset * remove changeset --- .github/dependabot.yml | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index cea4f07b90..d7af2d7f75 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -28,3 +28,43 @@ updates: schedule: interval: monthly open-pull-requests-limit: 0 + - package-ecosystem: gomod + directory: "/lib" + schedule: + interval: "daily" + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "ctf" + - package-ecosystem: gomod + directory: "/wasp" + schedule: + interval: "daily" + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "ctf" + - package-ecosystem: gomod + directory: "/seth" + schedule: + interval: "daily" + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "ctf" + - package-ecosystem: gomod + directory: "/havoc" + schedule: + interval: "daily" + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "ctf" + - package-ecosystem: gomod + directory: "/k8s-test-runner" + schedule: + interval: "daily" + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "ctf" From 359feffcd5622658ebc6805b992d75a3fb82fdc2 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:02:44 +0200 Subject: [PATCH 400/432] TT-1550 Migrate remaining E2E workflows to the reusable workflow (#14403) * Update some test workflows to run with test config path * Fix summary * Fix * Update on-demand-ocr-soak-test.yml * Run vrfplus tests on ARBITRUM_SEPOLIA on existing env * Add config for staging release testing on arbitrum sepolia * Show test_secrets_override_key in summary * Generate hash of integration-tests/ for test runner image if tag not provided * test updating config but not rebuilding test image * Fix test_runner_hash * Commit all configs for staging * test config change * Update release configs * Do not rebuild test image when md or .github files were changed * Add wemix testnet config for ocrv2 soak test * Use chainlink version from config * Update reusable workflow inputs * Add soak/ocr_test.go:^TestOCRv2Soak$WemixTestnet to CI tests * Fix * Fix test image tag * Remove image from default.toml * Fix chainlink_version * Fix test image hash value * Fix summary * Update workflow * Update config overrides, read from default, env vars and then from BASE64_CONFIG_OVERRIDE if exists BASE64_CONFIG_OVERRIDE should be able to override everything that was already set in the test config * Build chainlink image sha if required * Fix * Add new workflow * Show test config path in reusable workflow * Update list of tests * Update run-selected-tests workflow * Fix * Rename steps * fix workflow * Add TestVRFv2Plus_LiveTestnets to CI tests definition * Fix * Run vrfv2plus tests on simulated network by default * Fix * fix * fix * Update test definition * Add TestVRFv2Plus_Release_Sepolia * Add workflow to run vrf e2e release tests * test new workflow with slack notification * fix * fix * fix * fix color * fix * revert if * revert test definition changes * Add test_secrets_override_key * fix for slack notification after test * TT-1550: reorganizing VRF V2 Plus configs * Use test_config_override_path instead of base64 in other VRFv2Plus workflows * remove file * Refactor on-demand-vrfv2plus-performance-test.yml * Add slack notification for on-demand-vrfv2plus-smoke-tests.yml * Fix * fix 2 * remove debug info * update color of slack notification * Migrate on-demand-vrfv2-eth2-clients-test * Migrate on-demand-ocr-soak-test.yml (WIP) * Rename step * update test names * fix * fix name * fix * Migrate automation-nightly-tests.yml * Build remote runner image asap * Fix * add ocr2 celo_alfajores and base_sepolia test configs * Fix * Fix * Migrate automation-benchmark-tests.yml * fix * Migrate automation-load-tests.yml * Migrate on-demand-vrfv2-eth2-clients-test.yml * Migrate on-demand-vrfv2-performance-test.yml * Remove unused actions * Always show console logs for ocr tests * Allow custom docker test artifacts * Migrate ccip-load-tests.yml * revert this commits * fix ARTIFACT_PATHS * fix * Allow to upload custom test artifacts * Fux * Fix * Clean up toml examples * Remove unused live-testnet-tests.yml workflow Confirmed with Adam * Remove old action * Fix * Fix * update test duration to 24h * Fix citool * debug artifacts on failure * debug * Fix * Use ubuntu-latest * Update workflow slack notifications * Fix test id when running custom tests * Fix * Fix * Add OCR test configs * remove unused workflow * Add slack notifications for vrfv2 workflows * Fix slack notifications for automation workflows * Fix SLACK_USER input in on-demand-ocr-soak-test.yml * Do not use github.sha as default chainlink version * Remove chainlink_version input form automation workflows. Use config instead * update base sepolia test config duration to 1h * Fix * Do not upload cpu and memory profile by default * Do not set E2E_TEST_PYROSCOPE_ENABLED. Get it from toml config instead * reverting base sepolia duration to 24h * Fix TEST_UPLOAD_CPU_PROFILE and TEST_UPLOAD_MEM_PROFILE * debug TEST_UPLOAD_CPU_PROFILE * Read config from env var first then override with TOML * remove debug info * Include tag and sha in workflow slack notification * Fix notification Do not use link for tag because it may not exist. Use short sha. * Revert "Read config from env var first then override with TOML" This reverts commit 2b2fb180dbf936bf8549fb7d40e2084b83e5820b. * Fix and bump ctf * go mod tidy * bump ctf * add automation test configs (#14455) * add automation test configs * update grafana config * update testid in workflow * update testid in e2e-tests * restructure configs * update config * add testType input in benchmark workflow * add testType input in e2e reusable workflow * Revert "add testType input in e2e reusable workflow" This reverts commit 937607cccfbf52f579a6b2ae09ff8fae9f51cac9. * update benchmark workflow * update test log level for load and benchmark --------- Co-authored-by: lukaszcl <120112546+lukaszcl@users.noreply.github.com> * Increase test_log_upload_retention_days from 3 to 5 * Fix * Debug CCIP Load Test in E2E Workflow Conversion (#14479) Fixes CCIP load tests * Run selected e2e tests in merge queue * Run selected e2e tests in merge queue part 2 * Run selected e2e tests in merge queue part 3 * Use ctf-build-test-image@0.1.0 * Fix suites for k8s tests Use test_suite input and matrix.tests.test_env_vars.TEST_SUITE to set test suites for tests in e2e-tests.yml * Update gha * Rename step * Update run-tests GHA * update testsconfigs to use ocr common --------- Co-authored-by: Ilja Pavlovs Co-authored-by: joaoluisam Co-authored-by: davidcauchi Co-authored-by: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Co-authored-by: Adam Hamrick --- .../actions/build-chainlink-image/action.yml | 2 +- .github/actions/build-test-image/action.yml | 150 --- .../action.yml | 151 --- .../action.yml | 144 --- .../action.yml | 125 -- .../setup-merge-base64-config/action.yml | 70 -- .../setup-parse-base64-config/action.yml | 44 - .github/e2e-tests.yml | 192 ++- .../workflows/automation-benchmark-tests.yml | 138 +- .github/workflows/automation-load-tests.yml | 150 +-- .../workflows/automation-nightly-tests.yml | 317 +---- .../workflows/automation-ondemand-tests.yml | 3 + .github/workflows/ccip-chaos-tests.yml | 3 + .github/workflows/ccip-load-tests.yml | 315 +---- .github/workflows/integration-chaos-tests.yml | 3 + .../workflows/integration-tests-publish.yml | 2 +- .github/workflows/integration-tests.yml | 135 +- .github/workflows/live-testnet-tests.yml | 1119 ----------------- .github/workflows/on-demand-ocr-soak-test.yml | 150 +-- .../on-demand-vrfv2-performance-test.yml | 3 + .../workflows/on-demand-vrfv2-smoke-tests.yml | 3 + .../on-demand-vrfv2plus-performance-test.yml | 3 + .../on-demand-vrfv2plus-smoke-tests.yml | 3 + .../run-e2e-tests-reusable-workflow.yml | 143 +-- .github/workflows/run-nightly-e2e-tests.yml | 3 + .github/workflows/run-selected-e2e-tests.yml | 4 +- integration-tests/scripts/buildTests | 1 + .../testconfig/automation/automation.toml | 13 + .../testconfig/automation/example.toml | 30 - .../benchmark/1000Upkeeps-1h-2_1.toml | 15 + .../benchmark/1000Upkeeps-1h-2_3.toml | 15 + .../overrides/load/500Upkeeps-1x-1h.toml | 47 + .../overrides/load/50Upkeeps-1x-12h.toml | 43 + .../overrides/load/50Upkeeps-1x-1h.toml | 43 + .../overrides/soak/50Upkeeps-8h-2_1.toml | 15 + .../overrides/soak/50Upkeeps-8h-2_3.toml | 15 + integration-tests/testconfig/default.toml | 123 +- .../testconfig/forwarder_ocr/example.toml | 10 - .../testconfig/forwarder_ocr2/example.toml | 9 - .../testconfig/functions/example.toml | 29 - .../testconfig/keeper/example.toml | 29 - .../testconfig/keeper/keeper.toml | 2 +- .../testconfig/log_poller/example.toml | 29 - .../testconfig/node/example.toml | 30 - integration-tests/testconfig/ocr/example.toml | 10 - .../ocr/overrides/arbitrum_mainnet.toml | 18 + .../ocr/overrides/arbitrum_sepolia.toml | 15 + .../ocr/overrides/base_mainnet.toml | 18 + .../ocr/overrides/base_sepolia.toml | 15 + .../ocr/overrides/celo_alfajores.toml | 15 + .../ocr/overrides/ethereum_sepolia.toml | 15 + .../ocr/overrides/linea_sepolia.toml | 15 + .../ocr/overrides/optimism_mainnet.toml | 18 + .../ocr/overrides/optimism_sepolia.toml | 15 + .../ocr/overrides/scroll_sepolia.toml | 15 + .../ocr/overrides/wemix_mainnet.toml | 18 + .../testconfig/ocr2/example.toml | 10 - .../ocr2/overrides/base_sepolia.toml | 18 + .../ocr2/overrides/ethereum_sepolia.toml | 15 + .../ocr2/overrides/polygon_amoy.toml | 15 + .../ocr2/overrides/polygon_mainnet.toml | 18 + .../ocr2/overrides/wemix_testnet.toml | 15 + .../ocr2/overrides/xlayer_sepolia.toml | 15 + .../testconfig/vrfv2/example.toml | 29 - .../testconfig/vrfv2plus/example.toml | 29 - 65 files changed, 1056 insertions(+), 3168 deletions(-) delete mode 100644 .github/actions/build-test-image/action.yml delete mode 100644 .github/actions/setup-create-base64-config-ccip/action.yml delete mode 100644 .github/actions/setup-create-base64-config-live-testnets/action.yml delete mode 100644 .github/actions/setup-create-base64-upgrade-config/action.yml delete mode 100644 .github/actions/setup-merge-base64-config/action.yml delete mode 100644 .github/actions/setup-parse-base64-config/action.yml delete mode 100644 .github/workflows/live-testnet-tests.yml create mode 100644 integration-tests/testconfig/automation/overrides/benchmark/1000Upkeeps-1h-2_1.toml create mode 100644 integration-tests/testconfig/automation/overrides/benchmark/1000Upkeeps-1h-2_3.toml create mode 100644 integration-tests/testconfig/automation/overrides/load/500Upkeeps-1x-1h.toml create mode 100644 integration-tests/testconfig/automation/overrides/load/50Upkeeps-1x-12h.toml create mode 100644 integration-tests/testconfig/automation/overrides/load/50Upkeeps-1x-1h.toml create mode 100644 integration-tests/testconfig/automation/overrides/soak/50Upkeeps-8h-2_1.toml create mode 100644 integration-tests/testconfig/automation/overrides/soak/50Upkeeps-8h-2_3.toml create mode 100644 integration-tests/testconfig/ocr/overrides/arbitrum_mainnet.toml create mode 100644 integration-tests/testconfig/ocr/overrides/arbitrum_sepolia.toml create mode 100644 integration-tests/testconfig/ocr/overrides/base_mainnet.toml create mode 100644 integration-tests/testconfig/ocr/overrides/base_sepolia.toml create mode 100644 integration-tests/testconfig/ocr/overrides/celo_alfajores.toml create mode 100644 integration-tests/testconfig/ocr/overrides/ethereum_sepolia.toml create mode 100644 integration-tests/testconfig/ocr/overrides/linea_sepolia.toml create mode 100644 integration-tests/testconfig/ocr/overrides/optimism_mainnet.toml create mode 100644 integration-tests/testconfig/ocr/overrides/optimism_sepolia.toml create mode 100644 integration-tests/testconfig/ocr/overrides/scroll_sepolia.toml create mode 100644 integration-tests/testconfig/ocr/overrides/wemix_mainnet.toml create mode 100644 integration-tests/testconfig/ocr2/overrides/base_sepolia.toml create mode 100644 integration-tests/testconfig/ocr2/overrides/ethereum_sepolia.toml create mode 100644 integration-tests/testconfig/ocr2/overrides/polygon_amoy.toml create mode 100644 integration-tests/testconfig/ocr2/overrides/polygon_mainnet.toml create mode 100644 integration-tests/testconfig/ocr2/overrides/wemix_testnet.toml create mode 100644 integration-tests/testconfig/ocr2/overrides/xlayer_sepolia.toml diff --git a/.github/actions/build-chainlink-image/action.yml b/.github/actions/build-chainlink-image/action.yml index 4934e579ae..0e457560bf 100644 --- a/.github/actions/build-chainlink-image/action.yml +++ b/.github/actions/build-chainlink-image/action.yml @@ -37,7 +37,7 @@ runs: AWS_ROLE_TO_ASSUME: ${{ inputs.AWS_ROLE_TO_ASSUME }} - name: Build Image if: steps.check-image.outputs.exists != 'true' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 + uses: smartcontractkit/.github/actions/ctf-build-image@1a26fe378d7ebdc34ab1fe31ec4a6d1c376199f8 # ctf-build-image@0.0.0 with: cl_repo: smartcontractkit/chainlink cl_ref: ${{ inputs.git_commit_sha }} diff --git a/.github/actions/build-test-image/action.yml b/.github/actions/build-test-image/action.yml deleted file mode 100644 index bc81226b32..0000000000 --- a/.github/actions/build-test-image/action.yml +++ /dev/null @@ -1,150 +0,0 @@ -name: Build Test Image -description: A composite action that allows building and publishing the test remote runner image - -inputs: - repository: - description: The docker repository for the image - default: chainlink-tests - required: false - tag: - description: The tag to use by default and to use for checking image existance. If not provided, the hash of the integration-tests/ directory will be used - required: false - other_tags: - description: Other tags to push if needed - required: false - suites: - description: The test suites to build into the image - default: chaos migration reorg smoke soak benchmark load - required: false - QA_AWS_ROLE_TO_ASSUME: - description: The AWS role to assume as the CD user, if any. Used in configuring the docker/login-action - required: true - QA_AWS_REGION: - description: The AWS region the ECR repository is located in, should only be needed for public ECR repositories, used in configuring docker/login-action - required: true - QA_AWS_ACCOUNT_NUMBER: - description: The AWS region the ECR repository is located in, should only be needed for public ECR repositories, used in configuring docker/login-action - required: true - -outputs: - test_image: - description: The full name of the test image that was built - value: ${{ steps.image_outputs.outputs.test_image }} - test_image_tag: - description: The tag of the test image that was built - value: ${{ steps.image_outputs.outputs.test_image_tag }} - test_image_repository: - description: The repository of the test image that was built - value: ${{ steps.image_outputs.outputs.test_image_repo }} - -runs: - using: composite - steps: - - # Base Test Image Logic - - name: Get CTF Version - id: version - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/mod-version@fc3e0df622521019f50d772726d6bf8dc919dd38 # v2.3.19 - with: - go-project-path: ./integration-tests - module-name: github.com/smartcontractkit/chainlink-testing-framework/lib - enforce-semantic-tag: false - - name: Get CTF sha - if: steps.version.outputs.is_semantic == 'false' - id: short_sha - env: - VERSION: ${{ steps.version.outputs.version }} - shell: bash - run: | - short_sha="${VERSION##*-}" - echo "short sha is: ${short_sha}" - echo "short_sha=${short_sha}" >> "$GITHUB_OUTPUT" - - name: Checkout chainlink-testing-framework - if: steps.version.outputs.is_semantic == 'false' - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink-testing-framework - ref: main - fetch-depth: 0 - path: ctf - - name: Get long sha - if: steps.version.outputs.is_semantic == 'false' - id: long_sha - env: - SHORT_SHA: ${{ steps.short_sha.outputs.short_sha }} - shell: bash - run: | - cd ctf - long_sha=$(git rev-parse ${SHORT_SHA}) - echo "sha is: ${long_sha}" - echo "long_sha=${long_sha}" >> "$GITHUB_OUTPUT" - - name: Check if test base image exists - if: steps.version.outputs.is_semantic == 'false' - id: check-base-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - repository: test-base-image - tag: ${{ steps.long_sha.outputs.long_sha }} - AWS_REGION: ${{ inputs.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ inputs.QA_AWS_ROLE_TO_ASSUME }} - - name: Build Base Image - if: steps.version.outputs.is_semantic == 'false' && steps.check-base-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/docker/build-push@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - env: - BASE_IMAGE_NAME: ${{ inputs.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ inputs.QA_AWS_REGION }}.amazonaws.com/test-base-image:${{ steps.long_sha.outputs.long_sha }} - with: - tags: ${{ env.BASE_IMAGE_NAME }} - file: ctf/lib/k8s/Dockerfile.base - AWS_REGION: ${{ inputs.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ inputs.QA_AWS_ROLE_TO_ASSUME }} - # End Base Image Logic - - # Test Runner Logic - - name: Get hash of integration-tests/ for test runner image - id: test_runner_hash - if: ${{ inputs.tag == '' }} - # Do not include testconfig/ in the hash to avoid rebuilding the image when only testconfig/ changes - shell: sh - run: | - HASH_VALUE=$(find integration-tests -type f ! -path 'integration-tests/testconfig/overrides/*.toml' ! -path 'integration-tests/testconfig/overrides/*/*.toml' ! -path 'integration-tests/testconfig/*/overrides/*.toml' ! -path 'integration-tests/testconfig/*/overrides/*/*.toml' ! -path 'integration-tests/ccip-tests/testconfig/*/overrides/*.toml' ! -path 'integration-tests/ccip-tests/testconfig/*/overrides/*/*.toml' ! -path '.github/*/*' ! -path '*/*.md' ! -path '*/*.MD' ! -path 'integration-tests/*/__debug_bin*' ! -path '*/*.MD' ! -path 'integration-tests/*/tmp-manifest*.yaml' ! -path '*/*.MD' ! -path 'integration-tests/*/*.log' ! -path 'integration-tests/*/*_dump.sql' ! -path 'integration-tests/*/.test_summary/*' -exec sha256sum {} + | sort -k 2 | sha256sum | awk '{print $1}') - echo "Computed hash: $HASH_VALUE" - echo "hash_value=$HASH_VALUE" >> $GITHUB_OUTPUT - - - name: Check if image exists - id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - repository: ${{ inputs.repository }} - tag: ${{ inputs.tag || steps.test_runner_hash.outputs.hash_value }} - AWS_REGION: ${{ inputs.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ inputs.QA_AWS_ROLE_TO_ASSUME }} - - name: Build and Publish Test Runner - if: steps.check-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/docker/build-push@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - tags: | - ${{ inputs.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ inputs.QA_AWS_REGION }}.amazonaws.com/${{ inputs.repository }}:${{ inputs.tag || steps.test_runner_hash.outputs.hash_value }} - ${{ inputs.other_tags }} - file: ./integration-tests/test.Dockerfile - build-args: | - BASE_IMAGE=${{ inputs.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ inputs.QA_AWS_REGION }}.amazonaws.com/test-base-image - IMAGE_VERSION=${{ steps.long_sha.outputs.long_sha || steps.version.outputs.version }} - SUITES="${{ inputs.suites }}" - AWS_REGION: ${{ inputs.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ inputs.QA_AWS_ROLE_TO_ASSUME }} - - name: Print Image Built - shell: sh - env: - INPUTS_REPOSITORY: ${{ inputs.repository }} - INPUTS_TAG: ${{ inputs.tag || steps.test_runner_hash.outputs.hash_value }} - run: | - echo "### ${INPUTS_REPOSITORY} image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${INPUTS_TAG}\`" >>$GITHUB_STEP_SUMMARY - - name: Set outputs - id: image_outputs - shell: sh - run: | - echo "test_image_repo=${{ inputs.repository }}" >> $GITHUB_OUTPUT - echo "test_image_tag=${{ inputs.tag || steps.test_runner_hash.outputs.hash_value }}" >> $GITHUB_OUTPUT - echo "test_image=${{ inputs.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ inputs.QA_AWS_REGION }}.amazonaws.com/${{ inputs.repository }}:${{ inputs.tag || steps.test_runner_hash.outputs.hash_value }}" >> $GITHUB_OUTPUT - # End Test Runner Logic diff --git a/.github/actions/setup-create-base64-config-ccip/action.yml b/.github/actions/setup-create-base64-config-ccip/action.yml deleted file mode 100644 index cb20c886e3..0000000000 --- a/.github/actions/setup-create-base64-config-ccip/action.yml +++ /dev/null @@ -1,151 +0,0 @@ -name: Create Base64 Config for CCIP Tests -description: A composite action that creates a base64-encoded config to be used by ccip integration tests - -inputs: - runId: - description: The run id - existingNamespace: - description: If test needs to run against already deployed namespace - testLogCollect: - description: Whether to always collect logs, even for passing tests - default: "false" - selectedNetworks: - description: The networks to run tests against - chainlinkVersion: - description: The git commit sha to use for the image tag - upgradeVersion: - description: The git commit sha to use for the image tag - logstreamLogTargets: - description: Where to send logs (e.g. file, loki) - customEvmNodes: - description: Custom EVM nodes to use in key=value format, where key is chain id and value is docker image to use. If they are provided the number of networksSelected must be equal to the number of customEvmNodes - evmNodeLogLevel: - description: Log level for the custom EVM nodes - default: "info" -outputs: - base64_config: - description: The base64-encoded config - value: ${{ steps.base64_config_override.outputs.base64_config }} - -runs: - using: composite - steps: - - name: Prepare Base64 TOML override - shell: bash - id: base64_config_override - env: - RUN_ID: ${{ inputs.runId }} - SELECTED_NETWORKS: ${{ inputs.selectedNetworks }} - EXISTING_NAMESPACE: ${{ inputs.existingNamespace }} - TEST_LOG_COLLECT: ${{ inputs.testLogCollect }} - CHAINLINK_VERSION: ${{ inputs.chainlinkVersion }} - UPGRADE_VERSION: ${{ inputs.upgradeVersion }} - LOGSTREAM_LOG_TARGETS: ${{ inputs.logstreamLogTargets }} - CUSTOM_EVM_NODES: ${{ inputs.customEvmNodes }} - EVM_NODE_LOG_LEVEL: ${{ inputs.evmNodeLogLevel }} - run: | - function convert_to_toml_array() { - local IFS=',' - local input_array=($1) - local toml_array_format="[" - - for element in "${input_array[@]}"; do - toml_array_format+="\"$element\"," - done - - toml_array_format="${toml_array_format%,}]" - echo "$toml_array_format" - } - - selected_networks=$(convert_to_toml_array "$SELECTED_NETWORKS") - log_targets=$(convert_to_toml_array "$LOGSTREAM_LOG_TARGETS") - - if [ -n "$TEST_LOG_COLLECT" ]; then - test_log_collect=true - else - test_log_collect=false - fi - - # make sure the number of networks and nodes match - IFS=',' read -r -a networks_array <<< "$SELECTED_NETWORKS" - IFS=',' read -r -a nodes_array <<< "$CUSTOM_EVM_NODES" - - networks_count=${#networks_array[@]} - nodes_count=${#nodes_array[@]} - - # Initialize or clear CONFIG_TOML environment variable - custom_nodes_toml="" - - # Check if the number of CUSTOM_EVM_NODES is zero - if [ $nodes_count -eq 0 ]; then - echo "The number of CUSTOM_EVM_NODES is zero, won't output any custom private Ethereum network configurations." - else - if [ $networks_count -ne $nodes_count ]; then - echo "The number of elements in SELECTED_NETWORKS (${networks_count}) and CUSTOM_EVM_NODES does not match (${nodes_count})." - exit 1 - else - for i in "${!networks_array[@]}"; do - IFS='=' read -r chain_id docker_image <<< "${nodes_array[i]}" - custom_nodes_toml+=" - [CCIP.Env.PrivateEthereumNetworks.${networks_array[i]}] - ethereum_version=\"\" - execution_layer=\"\" - - [CCIP.Env.PrivateEthereumNetworks.${networks_array[i]}.EthereumChainConfig] - seconds_per_slot=3 - slots_per_epoch=2 - genesis_delay=15 - validator_count=4 - chain_id=${chain_id} - addresses_to_fund=[\"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266\", \"0x70997970C51812dc3A010C7d01b50e0d17dc79C8\"] - node_log_level=\"${EVM_NODES_LOG_LEVEL}\" - - [CCIP.Env.PrivateEthereumNetworks.${networks_array[i]}.EthereumChainConfig.HardForkEpochs] - Deneb=500 - - [CCIP.Env.PrivateEthereumNetworks.${networks_array[i]}.CustomDockerImages] - execution_layer=\"${docker_image}\" - " - done - fi - fi - - cat << EOF > config.toml - [CCIP] - [CCIP.Env] - EnvToConnect="$EXISTING_NAMESPACE" - [CCIP.Env.Network] - selected_networks = $selected_networks - [CCIP.Env.NewCLCluster] - [CCIP.Env.NewCLCluster.Common] - [CCIP.Env.NewCLCluster.Common.ChainlinkImage] - version="$CHAINLINK_VERSION" - - $custom_nodes_toml - - [CCIP.Env.Logging] - test_log_collect=$test_log_collect - run_id="$RUN_ID" - - [CCIP.Env.Logging.LogStream] - log_targets=$log_targets - - [CCIP.Groups.load] - TestRunName = '$EXISTING_NAMESPACE' - - [CCIP.Groups.smoke] - TestRunName = '$EXISTING_NAMESPACE' - - EOF - - # Check if UPGRADE_VERSION is not empty and append to config.toml - if [ -n "$UPGRADE_VERSION" ]; then - cat << EOF >> config.toml - [CCIP.Env.NewCLCluster.Common.ChainlinkUpgradeImage] - version="$UPGRADE_VERSION" - EOF - fi - - BASE64_CONFIG=$(cat config.toml | base64 -w 0) - echo ::add-mask::$BASE64_CONFIG - echo "base64_config=$BASE64_CONFIG" >> $GITHUB_OUTPUT \ No newline at end of file diff --git a/.github/actions/setup-create-base64-config-live-testnets/action.yml b/.github/actions/setup-create-base64-config-live-testnets/action.yml deleted file mode 100644 index 64fc134b46..0000000000 --- a/.github/actions/setup-create-base64-config-live-testnets/action.yml +++ /dev/null @@ -1,144 +0,0 @@ -name: Create Base64 Config -description: A composite action that creates a base64-encoded config to be used by integration tests - -inputs: - runId: - description: The run id - testLogCollect: - description: Whether to always collect logs, even for passing tests - default: "false" - chainlinkImage: - description: The chainlink image to use - default: "public.ecr.aws/chainlink/chainlink" - chainlinkVersion: - description: The git commit sha to use for the image tag - chainlinkPostgresVersion: - description: The postgres version to use with the chainlink node - default: "15.6" - pyroscopeServer: - description: URL of Pyroscope server - pyroscopeEnvironment: - description: Name of Pyroscope environment - pyroscopeKey: - description: Pyroscope server key - lokiEndpoint: - description: Loki push endpoint - lokiTenantId: - description: Loki tenant id - lokiBasicAuth: - description: Loki basic auth - logstreamLogTargets: - description: Where to send logs (e.g. file, loki) - grafanaUrl: - description: Grafana URL - grafanaDashboardUrl: - description: Grafana dashboard URL - grafanaBearerToken: - description: Grafana bearer token - network: - description: Network to run tests on - httpEndpoints: - description: HTTP endpoints to use for network - wsEndpoints: - description: WS endpoints to use for network - fundingKeys: - description: Funding keys to use for network - -runs: - using: composite - steps: - - name: Prepare Base64 TOML override - shell: bash - id: base64-config-override - env: - RUN_ID: ${{ inputs.runId }} - PYROSCOPE_SERVER: ${{ inputs.pyroscopeServer }} - PYROSCOPE_ENVIRONMENT: ${{ inputs.pyroscopeEnvironment }} - PYROSCOPE_KEY: ${{ inputs.pyroscopeKey }} - CHAINLINK_IMAGE: ${{ inputs.chainlinkImage }} - CHAINLINK_VERSION: ${{ inputs.chainlinkVersion }} - CHAINLINK_POSTGRES_VERSION: ${{ inputs.chainlinkPostgresVersion }} - LOKI_ENDPOINT: ${{ inputs.lokiEndpoint }} - LOKI_TENANT_ID: ${{ inputs.lokiTenantId }} - LOKI_BASIC_AUTH: ${{ inputs.lokiBasicAuth }} - LOGSTREAM_LOG_TARGETS: ${{ inputs.logstreamLogTargets }} - GRAFANA_URL: ${{ inputs.grafanaUrl }} - GRAFANA_DASHBOARD_URL: ${{ inputs.grafanaDashboardUrl }} - GRAFANA_BEARER_TOKEN: ${{ inputs.grafanaBearerToken }} - NETWORK: ${{ inputs.network }} - HTTP_ENDPOINTS: ${{ inputs.httpEndpoints }} - WS_ENDPOINTS: ${{ inputs.wsEndpoints }} - FUNDING_KEYS: ${{ inputs.fundingKeys }} - run: | - convert_to_toml_array() { - local IFS=',' - local input_array=($1) - local toml_array_format="[" - - for element in "${input_array[@]}"; do - toml_array_format+="\"$element\"," - done - - toml_array_format="${toml_array_format%,}]" - echo "$toml_array_format" - } - - if [ -n "$PYROSCOPE_SERVER" ]; then - pyroscope_enabled=true - else - pyroscope_enabled=false - fi - - grafana_bearer_token="" - if [ -n "$GRAFANA_BEARER_TOKEN" ]; then - grafana_bearer_token="bearer_token_secret=\"$GRAFANA_BEARER_TOKEN\"" - fi - - cat << EOF > config.toml - [Common] - chainlink_node_funding=0.5 - - [ChainlinkImage] - image="$CHAINLINK_IMAGE" - version="$CHAINLINK_VERSION" - postgres_version="$CHAINLINK_POSTGRES_VERSION" - - [Pyroscope] - enabled=$pyroscope_enabled - server_url="$PYROSCOPE_SERVER" - environment="$PYROSCOPE_ENVIRONMENT" - key_secret="$PYROSCOPE_KEY" - - [Logging] - run_id="$RUN_ID" - - [Logging.LogStream] - log_targets=$(convert_to_toml_array "$LOGSTREAM_LOG_TARGETS") - - [Logging.Loki] - tenant_id="$LOKI_TENANT_ID" - endpoint="$LOKI_URL" - basic_auth_secret="$LOKI_BASIC_AUTH" - - [Logging.Grafana] - base_url="$GRAFANA_URL" - dashboard_url="$GRAFANA_DASHBOARD_URL" - $grafana_bearer_token - - [Network] - selected_networks=["$NETWORK"] - - [Network.RpcHttpUrls] - "$NETWORK" = $(convert_to_toml_array "$HTTP_ENDPOINTS") - - [Network.RpcWsUrls] - "$NETWORK" = $(convert_to_toml_array "$WS_ENDPOINTS") - - [Network.WalletKeys] - "$NETWORK" = $(convert_to_toml_array "$FUNDING_KEYS") - EOF - - BASE64_CONFIG_OVERRIDE=$(cat config.toml | base64 -w 0) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - touch .root_dir diff --git a/.github/actions/setup-create-base64-upgrade-config/action.yml b/.github/actions/setup-create-base64-upgrade-config/action.yml deleted file mode 100644 index c2d0bc19f3..0000000000 --- a/.github/actions/setup-create-base64-upgrade-config/action.yml +++ /dev/null @@ -1,125 +0,0 @@ -name: Create Base64 Upgrade Config -description: A composite action that creates a base64-encoded config to be used by Chainlink version upgrade tests - -inputs: - selectedNetworks: - description: The networks to run tests against - chainlinkImage: - description: The chainlink image to upgrade from - default: "public.ecr.aws/chainlink/chainlink" - chainlinkVersion: - description: The git commit sha to use for the image tag - chainlinkPostgresVersion: - description: The postgres version to use with the chainlink node - default: "15.6" - upgradeImage: - description: The chainlink image to upgrade to - default: "public.ecr.aws/chainlink/chainlink" - upgradeVersion: - description: The git commit sha to use for the image tag - runId: - description: The run id - testLogCollect: - description: Whether to always collect logs, even for passing tests - default: "false" - lokiEndpoint: - description: Loki push endpoint - lokiTenantId: - description: Loki tenant id - lokiBasicAuth: - description: Loki basic auth - logstreamLogTargets: - description: Where to send logs (e.g. file, loki) - grafanaUrl: - description: Grafana URL - grafanaDashboardUrl: - description: Grafana dashboard URL - grafanaBearerToken: - description: Grafana bearer token - -runs: - using: composite - steps: - - name: Prepare Base64 TOML override - shell: bash - id: base64-config-override - env: - SELECTED_NETWORKS: ${{ inputs.selectedNetworks }} - CHAINLINK_IMAGE: ${{ inputs.chainlinkImage }} - CHAINLINK_VERSION: ${{ inputs.chainlinkVersion }} - CHAINLINK_POSTGRES_VERSION: ${{ inputs.chainlinkPostgresVersion }} - UPGRADE_IMAGE: ${{ inputs.upgradeImage }} - UPGRADE_VERSION: ${{ inputs.upgradeVersion }} - RUN_ID: ${{ inputs.runId }} - TEST_LOG_COLLECT: ${{ inputs.testLogCollect }} - LOKI_ENDPOINT: ${{ inputs.lokiEndpoint }} - LOKI_TENANT_ID: ${{ inputs.lokiTenantId }} - LOKI_BASIC_AUTH: ${{ inputs.lokiBasicAuth }} - LOGSTREAM_LOG_TARGETS: ${{ inputs.logstreamLogTargets }} - GRAFANA_URL: ${{ inputs.grafanaUrl }} - GRAFANA_DASHBOARD_URL: ${{ inputs.grafanaDashboardUrl }} - GRAFANA_BEARER_TOKEN: ${{ inputs.grafanaBearerToken }} - run: | - function convert_to_toml_array() { - local IFS=',' - local input_array=($1) - local toml_array_format="[" - - for element in "${input_array[@]}"; do - toml_array_format+="\"$element\"," - done - - toml_array_format="${toml_array_format%,}]" - echo "$toml_array_format" - } - - selected_networks=$(convert_to_toml_array "$SELECTED_NETWORKS") - - if [ -n "$TEST_LOG_COLLECT" ]; then - test_log_collect=true - else - test_log_collect=false - fi - - log_targets=$(convert_to_toml_array "$LOGSTREAM_LOG_TARGETS") - - grafana_bearer_token="" - if [ -n "$GRAFANA_BEARER_TOKEN" ]; then - grafana_bearer_token="bearer_token_secret=\"$GRAFANA_BEARER_TOKEN\"" - fi - - cat << EOF > config.toml - [Network] - selected_networks=$selected_networks - - [ChainlinkImage] - image="$CHAINLINK_IMAGE" - version="$CHAINLINK_VERSION" - postgres_version="$CHAINLINK_POSTGRES_VERSION" - - [ChainlinkUpgradeImage] - image="$UPGRADE_IMAGE" - version="$UPGRADE_VERSION" - postgres_version="$CHAINLINK_POSTGRES_VERSION" - - [Logging] - test_log_collect=$test_log_collect - run_id="$RUN_ID" - - [Logging.LogStream] - log_targets=$log_targets - - [Logging.Loki] - tenant_id="$LOKI_TENANT_ID" - endpoint="$LOKI_ENDPOINT" - basic_auth_secret="$LOKI_BASIC_AUTH" - - [Logging.Grafana] - base_url="$GRAFANA_URL" - dashboard_url="$GRAFANA_DASHBOARD_URL" - $grafana_bearer_token - EOF - - BASE64_CONFIG_OVERRIDE=$(cat config.toml | base64 -w 0) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV diff --git a/.github/actions/setup-merge-base64-config/action.yml b/.github/actions/setup-merge-base64-config/action.yml deleted file mode 100644 index 79dc875831..0000000000 --- a/.github/actions/setup-merge-base64-config/action.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Merge Base64 Config -description: A composite action that merges user-provided Base64-encoded config with repository's secrets - -inputs: - base64Config: - description: Base64-encoded config to decode - -runs: - using: composite - steps: - - name: Install dasel - shell: bash - run: | - if ! which dasel > /dev/null; then - curl -L -o dasel "https://github.com/TomWright/dasel/releases/download/v2.6.0/dasel_linux_amd64" && chmod +x dasel && sudo mv dasel /usr/local/bin/ - else - echo "Dasel is already installed." - fi - - name: Add masks and export base64 config - shell: bash - run: | - BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64Config' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - decoded_toml=$(echo $BASE64_CONFIG_OVERRIDE | base64 -d) - CHAINLINK_IMAGE=$(echo "$decoded_toml" | { dasel -r toml 'ChainlinkImage.image' 2>/dev/null || echo ''; }) - echo ::add-mask::$CHAINLINK_IMAGE - CHAINLINK_VERSION=$(echo "$decoded_toml" | { dasel -r toml 'ChainlinkImage.version' 2>/dev/null || echo ''; }) - NETWORKS=$(echo "$decoded_toml" | awk -F'=' '/^[[:space:]]*selected_networks[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2}' 2>/dev/null) - - if [ -n "$CHAINLINK_IMAGE" ]; then - echo "CHAINLINK_IMAGE=$CHAINLINK_IMAGE" >> $GITHUB_ENV - else - echo "No Chainlink Image found in base64-ed config" - fi - if [ -n "$CHAINLINK_VERSION" ]; then - echo "CHAINLINK_VERSION=$CHAINLINK_VERSION" >> $GITHUB_ENV - else - echo "No Chainlink Version found in base64-ed config" - fi - if [ -n "$NETWORKS" ]; then - echo "NETWORKS=$NETWORKS" >> $GITHUB_ENV - fi - - grafana_bearer_token="" - if [ -n "$GRAFANA_BEARER_TOKEN" ]; then - grafana_bearer_token="bearer_token_secret=\"$GRAFANA_BEARER_TOKEN\"" - fi - - # use Loki config from GH secrets and merge it with base64 input - cat << EOF > config.toml - [Logging.Loki] - tenant_id="$LOKI_TENANT_ID" - endpoint="$LOKI_URL" - basic_auth_secret="$LOKI_BASIC_AUTH" - # legacy, you only need this to access the cloud version - # bearer_token_secret="bearer_token" - - [Logging.Grafana] - base_url="$GRAFANA_URL" - dashboard_url="$GRAFANA_DASHBOARD_URL" - $grafana_bearer_token - EOF - - echo "$decoded_toml" >> final_config.toml - cat config.toml >> final_config.toml - BASE64_CONFIG_OVERRIDE=$(cat final_config.toml | base64 -w 0) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV \ No newline at end of file diff --git a/.github/actions/setup-parse-base64-config/action.yml b/.github/actions/setup-parse-base64-config/action.yml deleted file mode 100644 index 72e8982e6d..0000000000 --- a/.github/actions/setup-parse-base64-config/action.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Parse Base64 Config -description: A composite action that extracts the chainlink image, version and network from a base64-encoded config - -inputs: - base64Config: - description: Base64-encoded config to decode - -runs: - using: composite - steps: - - name: Install dasel - shell: bash - run: | - if ! which dasel > /dev/null; then - curl -L -o dasel "https://github.com/TomWright/dasel/releases/download/v2.6.0/dasel_linux_amd64" && chmod +x dasel && sudo mv dasel /usr/local/bin/ - else - echo "Dasel is already installed." - fi - - name: Add masks and export base64 config - shell: bash - run: | - decoded_toml=$(echo $BASE64_CONFIG_OVERRIDE | base64 -d) - CHAINLINK_IMAGE=$(echo "$decoded_toml" | { dasel -r toml 'ChainlinkImage.image' 2>/dev/null || echo ''; }) - echo ::add-mask::$CHAINLINK_IMAGE - CHAINLINK_VERSION=$(echo "$decoded_toml" | { dasel -r toml 'ChainlinkImage.version' 2>/dev/null || echo ''; }) - NETWORKS=$(echo "$decoded_toml" | awk -F'=' '/^[[:space:]]*selected_networks[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2}' 2>/dev/null) - ETH2_EL_CLIENT=$(echo "$decoded_toml" | awk -F'=' '/^[[:space:]]*execution_layer[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2}' 2>/dev/null) - - if [ -n "$CHAINLINK_IMAGE" ]; then - echo "CHAINLINK_IMAGE=$CHAINLINK_IMAGE" >> $GITHUB_ENV - else - echo "No Chainlink Image found in base64-ed config" - fi - if [ -n "$CHAINLINK_VERSION" ]; then - echo "CHAINLINK_VERSION=$CHAINLINK_VERSION" >> $GITHUB_ENV - else - echo "No Chainlink Version found in base64-ed config. Exiting" - fi - if [ -n "$NETWORKS" ]; then - echo "NETWORKS=$NETWORKS" >> $GITHUB_ENV - fi - if [ -n "$ETH2_EL_CLIENT" ]; then - echo "ETH2_EL_CLIENT=$ETH2_EL_CLIENT" >> $GITHUB_ENV - fi \ No newline at end of file diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 0ee7a50d0c..d5c257de8f 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -16,27 +16,27 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/ocr_test.go -timeout 30m -count=1 -test.parallel=2 -json pyroscope_env: ci-smoke-ocr-evm-simulated - # Example of a configuration for running a single soak test in Kubernetes Remote Runner - - id: soak/ocr_test.go:^TestOCRv1Soak$ + - id: soak/ocr_test.go:TestOCRv1Soak path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRv1Soak$ -test.parallel=1 -timeout 30m -count=1 -json - test_config_override_required: true + test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRv1Soak$ -test.parallel=1 -timeout 900h -count=1 -json + test_cmd_opts: 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false test_secrets_required: true test_env_vars: TEST_SUITE: soak - - id: soak/ocr_test.go:^TestOCRv2Soak$ + - id: soak/ocr_test.go:TestOCRv2Soak path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRv2Soak$ -test.parallel=1 -timeout 30m -count=1 -json - test_config_override_required: true + test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRv2Soak$ -test.parallel=1 -timeout 900h -count=1 -json + test_cmd_opts: 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false test_secrets_required: true test_env_vars: TEST_SUITE: soak @@ -45,88 +45,80 @@ runner-test-matrix: path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRv2Soak$ -test.parallel=1 -timeout 30m -count=1 -json + test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRv2Soak$ -test.parallel=1 -timeout 900h -count=1 -json test_config_override_path: integration-tests/testconfig/ocr2/overrides/wemix_testnet.toml test_secrets_required: true test_env_vars: TEST_SUITE: soak - - id: soak/ocr_test.go:^TestForwarderOCRv1Soak$ + - id: soak/ocr_test.go:TestForwarderOCRv1Soak path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestForwarderOCRv1Soak$ -test.parallel=1 -timeout 30m -count=1 -json - test_config_override_required: true + test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestForwarderOCRv1Soak$ -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: TEST_SUITE: soak - - id: soak/ocr_test.go:^TestForwarderOCRv2Soak$ + - id: soak/ocr_test.go:TestForwarderOCRv2Soak path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestForwarderOCRv2Soak$ -test.parallel=1 -timeout 30m -count=1 -json - test_config_override_required: true + test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestForwarderOCRv2Soak$ -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: TEST_SUITE: soak - - id: soak/ocr_test.go:^TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled$ + - id: soak/ocr_test.go:TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled$ -test.parallel=1 -timeout 30m -count=1 -json - test_config_override_required: true + test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: TEST_SUITE: soak - - id: soak/ocr_test.go:^TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled$ + - id: soak/ocr_test.go:TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled$ -test.parallel=1 -timeout 30m -count=1 -json - test_config_override_required: true + test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled$ -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: TEST_SUITE: soak - - id: soak/ocr_test.go:^TestOCRSoak_GasSpike$ + - id: soak/ocr_test.go:TestOCRSoak_GasSpike path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_GasSpike$ -test.parallel=1 -timeout 30m -count=1 -json - test_config_override_required: true + test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_GasSpike$ -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: TEST_SUITE: soak - - id: soak/ocr_test.go:^TestOCRSoak_ChangeBlockGasLimit$ + - id: soak/ocr_test.go:TestOCRSoak_ChangeBlockGasLimit path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_ChangeBlockGasLimit$ -test.parallel=1 -timeout 30m -count=1 -json - test_config_override_required: true + test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_ChangeBlockGasLimit$ -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: TEST_SUITE: soak - - id: soak/ocr_test.go:^TestOCRSoak_RPCDownForAllCLNodes$ + - id: soak/ocr_test.go:TestOCRSoak_RPCDownForAllCLNodes path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_RPCDownForAllCLNodes$ -test.parallel=1 -timeout 30m -count=1 -json - test_config_override_required: true + test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_RPCDownForAllCLNodes$ -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: TEST_SUITE: soak - - id: soak/ocr_test.go:^TestOCRSoak_RPCDownForHalfCLNodes$ + - id: soak/ocr_test.go:TestOCRSoak_RPCDownForHalfCLNodes path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_RPCDownForHalfCLNodes$ -test.parallel=1 -timeout 30m -count=1 -json - test_config_override_required: true + test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_RPCDownForHalfCLNodes$ -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: TEST_SUITE: soak @@ -137,6 +129,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/forwarder_ocr_test.go -timeout 30m -count=1 -test.parallel=2 -json pyroscope_env: ci-smoke-forwarder-ocr-evm-simulated @@ -147,6 +140,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/forwarders_ocr2_test.go -timeout 30m -count=1 -test.parallel=2 -json pyroscope_env: ci-smoke-forwarder-ocr-evm-simulated @@ -157,6 +151,7 @@ runner-test-matrix: runs_on: ubuntu22.04-16cores-64GB workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/ocr2_test.go -timeout 30m -count=1 -test.parallel=6 -json pyroscope_env: ci-smoke-ocr2-evm-simulated @@ -169,6 +164,7 @@ runner-test-matrix: runs_on: ubuntu22.04-16cores-64GB workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/ocr2_test.go -timeout 30m -count=1 -test.parallel=6 -json pyroscope_env: ci-smoke-ocr2-plugins-evm-simulated @@ -197,6 +193,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_0|TestAutomationBasic/registry_2_1_conditional|TestAutomationBasic/registry_2_1_logtrigger$" -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -207,6 +204,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_1_with_mercury_v02|TestAutomationBasic/registry_2_1_with_mercury_v03|TestAutomationBasic/registry_2_1_with_logtrigger_and_mercury_v02$" -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -217,6 +215,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_2_conditional|TestAutomationBasic/registry_2_2_logtrigger|TestAutomationBasic/registry_2_2_with_mercury_v02$" -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -227,6 +226,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_2_with_mercury_v03|TestAutomationBasic/registry_2_2_with_logtrigger_and_mercury_v02$" -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -237,6 +237,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_3_conditional_native|TestAutomationBasic/registry_2_3_conditional_link$" -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -247,6 +248,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_3_logtrigger_native|TestAutomationBasic/registry_2_3_logtrigger_link$" -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -257,6 +259,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_3_with_mercury_v03_link|TestAutomationBasic/registry_2_3_with_logtrigger_and_mercury_v02_link$" -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -267,6 +270,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestSetUpkeepTriggerConfig$ -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -277,6 +281,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationAddFunds$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -287,6 +292,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationPauseUnPause$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -297,6 +303,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationRegisterUpkeep$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -307,6 +314,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationPauseRegistry$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -317,6 +325,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationKeeperNodesDown$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -327,6 +336,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationPerformSimulation$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -337,6 +347,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationCheckPerformGasLimit$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -347,6 +358,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestUpdateCheckData$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -357,6 +369,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestSetOffchainConfigWithMaxGasPrice$ -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-automation-evm-simulated @@ -366,7 +379,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperBasicSmoke$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -376,7 +389,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperBlockCountPerTurn$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -386,7 +399,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperSimulation$ -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -396,7 +409,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperCheckPerformGasLimit$ -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -406,7 +419,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperRegisterUpkeep$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -416,7 +429,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperAddFunds$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -426,7 +439,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperRemove$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -436,7 +449,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperPauseRegistry$ -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -446,7 +459,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperMigrateRegistry$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -456,7 +469,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperNodeDown$ -test.parallel=3 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -466,7 +479,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperPauseUnPauseUpkeep$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -476,7 +489,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperUpdateCheckData$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -486,7 +499,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest workflows: - - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperJobReplacement$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-keeper-evm-simulated @@ -497,12 +510,10 @@ runner-test-matrix: test_env_type: k8s-remote-runner test_cmd: cd integration-tests/load/automationv2_1 && go test -test.run TestLogTrigger -test.parallel=1 -timeout 60m -count=1 -json remote_runner_memory: 4Gi - test_config_override_required: true test_secrets_required: true test_env_vars: + TEST_LOG_LEVEL: info TEST_SUITE: automationv2_1 - workflows: - - Automation Load Test pyroscope_env: automation-load-test - id: smoke/automation_upgrade_test.go:^TestAutomationNodeUpgrade/registry_2_0 @@ -510,13 +521,13 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu22.04-8cores-32GB workflows: - - Run Automation Product Nightly E2E Tests + - Automation Nightly Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationNodeUpgrade/registry_2_0 -test.parallel=1 -timeout 60m -count=1 -json test_env_vars: E2E_TEST_CHAINLINK_IMAGE: public.ecr.aws/chainlink/chainlink E2E_TEST_CHAINLINK_VERSION: latest E2E_TEST_CHAINLINK_UPGRADE_IMAGE: '{{ env.QA_CHAINLINK_IMAGE }}' - E2E_TEST_CHAINLINK_UPGRADE_VERSION: develop + E2E_TEST_CHAINLINK_UPGRADE_VERSION: '{{ env.DEFAULT_CHAINLINK_UPGRADE_VERSION }}' pyroscope_env: ci-smoke-automation-upgrade-tests - id: smoke/automation_upgrade_test.go:^TestAutomationNodeUpgrade/registry_2_1 @@ -524,13 +535,13 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu22.04-8cores-32GB workflows: - - Run Automation Product Nightly E2E Tests + - Automation Nightly Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationNodeUpgrade/registry_2_1 -test.parallel=5 -timeout 60m -count=1 -json test_env_vars: E2E_TEST_CHAINLINK_IMAGE: public.ecr.aws/chainlink/chainlink E2E_TEST_CHAINLINK_VERSION: latest E2E_TEST_CHAINLINK_UPGRADE_IMAGE: '{{ env.QA_CHAINLINK_IMAGE }}' - E2E_TEST_CHAINLINK_UPGRADE_VERSION: develop + E2E_TEST_CHAINLINK_UPGRADE_VERSION: '{{ env.DEFAULT_CHAINLINK_UPGRADE_VERSION }}' pyroscope_env: ci-smoke-automation-upgrade-tests - id: smoke/automation_upgrade_test.go:^TestAutomationNodeUpgrade/registry_2_2 @@ -538,13 +549,13 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu22.04-8cores-32GB workflows: - - Run Automation Product Nightly E2E Tests + - Automation Nightly Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationNodeUpgrade/registry_2_2 -test.parallel=5 -timeout 60m -count=1 -json test_env_vars: E2E_TEST_CHAINLINK_IMAGE: public.ecr.aws/chainlink/chainlink E2E_TEST_CHAINLINK_VERSION: latest E2E_TEST_CHAINLINK_UPGRADE_IMAGE: '{{ env.QA_CHAINLINK_IMAGE }}' - E2E_TEST_CHAINLINK_UPGRADE_VERSION: develop + E2E_TEST_CHAINLINK_UPGRADE_VERSION: '{{ env.DEFAULT_CHAINLINK_UPGRADE_VERSION }}' pyroscope_env: ci-smoke-automation-upgrade-tests - id: reorg/automation_reorg_test.go^TestAutomationReorg/registry_2_0 @@ -603,7 +614,7 @@ runner-test-matrix: test_env_vars: TEST_SUITE: chaos - - id: benchmark/automation_test.go:^TestAutomationBenchmark$ + - id: benchmark/automation_test.go:TestAutomationBenchmark path: integration-tests/benchmark/automation_test.go test_env_type: k8s-remote-runner remote_runner_memory: 4Gi @@ -613,9 +624,24 @@ runner-test-matrix: test_cmd: cd integration-tests/benchmark && go test -v -test.run ^TestAutomationBenchmark$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-benchmark-automation-nightly test_env_vars: + TEST_LOG_LEVEL: info TEST_SUITE: benchmark TEST_TYPE: benchmark + - id: soak/automation_test.go:TestAutomationBenchmark + path: integration-tests/benchmark/automation_test.go + test_env_type: k8s-remote-runner + remote_runner_memory: 4Gi + runs_on: ubuntu-latest + # workflows: + # - Nightly E2E Tests + test_cmd: cd integration-tests/benchmark && go test -v -test.run ^TestAutomationBenchmark$ -test.parallel=1 -timeout 30m -count=1 -json + pyroscope_env: ci-benchmark-automation-nightly + test_env_vars: + TEST_LOG_LEVEL: info + TEST_SUITE: benchmark + TEST_TYPE: soak + # END: Automation tests # START: VRF tests @@ -625,7 +651,6 @@ runner-test-matrix: runs_on: ubuntu22.04-8cores-32GB test_env_type: docker test_cmd: cd integration-tests/smoke && go test -v -test.run TestVRFv2Basic -test.parallel=1 -timeout 30m -count=1 -json - test_config_override_required: true test_secrets_required: true workflows: - On Demand VRFV2 Smoke Test (Ethereum clients) @@ -684,6 +709,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/vrf_test.go -timeout 30m -count=1 -test.parallel=2 -json pyroscope_env: ci-smoke-vrf-evm-simulated @@ -694,6 +720,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/vrfv2_test.go -timeout 30m -count=1 -test.parallel=6 -json pyroscope_env: ci-smoke-vrf2-evm-simulated @@ -704,6 +731,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/vrfv2plus_test.go -timeout 30m -count=1 -test.parallel=9 -json pyroscope_env: ci-smoke-vrf2plus-evm-simulated @@ -736,6 +764,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerFewFiltersFixedDepth$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated @@ -746,6 +775,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerFewFiltersFinalityTag$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated @@ -756,6 +786,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerWithChaosFixedDepth$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated @@ -766,6 +797,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerWithChaosFinalityTag$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated @@ -776,6 +808,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerWithChaosPostgresFinalityTag$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated @@ -786,6 +819,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerWithChaosPostgresFixedDepth$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated @@ -796,6 +830,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerReplayFixedDepth$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated @@ -806,6 +841,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestLogPollerReplayFinalityTag$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-smoke-log_poller-evm-simulated @@ -820,6 +856,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/runlog_test.go -timeout 30m -test.parallel=2 -count=1 -json pyroscope_env: ci-smoke-runlog-evm-simulated @@ -830,6 +867,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/cron_test.go -timeout 30m -count=1 -json pyroscope_env: ci-smoke-cron-evm-simulated @@ -840,6 +878,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/flux_test.go -timeout 30m -count=1 -json pyroscope_env: ci-smoke-flux-evm-simulated @@ -850,6 +889,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/reorg_above_finality_test.go -timeout 30m -count=1 -json pyroscope_env: ci-smoke-reorg-above-finality-evm-simulated @@ -860,6 +900,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/migration && go test upgrade_version_test.go -timeout 30m -count=1 -test.parallel=2 -json test_env_vars: @@ -874,6 +915,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E Core Tests + - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/job_distributor_test.go -timeout 30m -count=1 -json pyroscope_env: ci-smoke-jd-evm-simulated @@ -888,6 +930,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E CCIP Tests + - Merge Queue E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -899,6 +942,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E CCIP Tests + - Merge Queue E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -911,6 +955,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E CCIP Tests + - Merge Queue E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -923,6 +968,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E CCIP Tests + - Merge Queue E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -948,6 +994,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E CCIP Tests + - Merge Queue E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPTokenPoolRateLimits$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -959,6 +1006,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E CCIP Tests + - Merge Queue E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPMulticall$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -970,6 +1018,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E CCIP Tests + - Merge Queue E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPManuallyExecuteAfterExecutionFailingDueToInsufficientGas$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -981,6 +1030,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E CCIP Tests + - Merge Queue E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPOnRampLimits$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -1012,6 +1062,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E CCIP Tests + - Merge Queue E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPReorgBelowFinality$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -1024,6 +1075,7 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E CCIP Tests + - Merge Queue E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPReorgAboveFinalityAtDestination$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -1036,12 +1088,40 @@ runner-test-matrix: runs_on: ubuntu-latest workflows: - PR E2E CCIP Tests + - Merge Queue E2E CCIP Tests - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPReorgAboveFinalityAtSource$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/ccip-reorg.toml + - id: integration-tests/ccip-tests/load/ccip_test.go:TestLoadCCIPStableRPS + path: integration-tests/ccip-tests/load/ccip_test.go + test_env_type: k8s-remote-runner + runs_on: ubuntu-latest + test_cmd: cd integration-tests/ccip-tests/load && DETACH_RUNNER=false go test -test.run ^TestLoadCCIPStableRPS$ -timeout 70m -count=1 -test.parallel=1 -json + test_env_vars: + E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" + workflows: + - E2E CCIP Load Tests + test_artifacts_on_failure: + - ./integration-tests/load/logs/payload_ccip.json + + # Enable when CCIP-2277 is resolved + # + # - id: integration-tests/ccip-tests/load/ccip_test.go:TestLoadCCIPStableRPSAfterARMCurseAndUncurse + # path: integration-tests/ccip-tests/load/ccip_test.go + # test_env_type: k8s-remote-runner + # runs_on: ubuntu-latest + # test_cmd: cd integration-tests/ccip-tests/load && DETACH_RUNNER=false go test -test.run $TestLoadCCIPStableRPSAfterARMCurseAndUncurse$ -timeout 70m -count=1 -test.parallel=1 -json + # test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/load-with-arm-curse-uncurse.toml + # test_env_vars: + # E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" + # workflows: + # - E2E CCIP Load Tests + # test_artifacts_on_failure: + # - ./integration-tests/load/logs/payload_ccip.json + - id: ccip-tests/chaos/ccip_test.go path: integration-tests/ccip-tests/chaos/ccip_test.go test_env_type: k8s-remote-runner diff --git a/.github/workflows/automation-benchmark-tests.yml b/.github/workflows/automation-benchmark-tests.yml index 85172bc98a..d1af80fb91 100644 --- a/.github/workflows/automation-benchmark-tests.yml +++ b/.github/workflows/automation-benchmark-tests.yml @@ -2,108 +2,52 @@ name: Automation Benchmark Test on: workflow_dispatch: inputs: - testType: - description: Type of test to run (benchmark, soak) - required: true - default: benchmark - type: string - base64Config: - description: base64-ed config - required: true - type: string + test_config_override_path: + description: Path to a test config file used to override the default test config + required: false + type: string + test_secrets_override_key: + description: Key to run tests with custom test secrets + required: false + type: string slackMemberID: description: Notifies test results (Not your @) required: true default: U02Q14G80TY type: string - test_secrets_override_key: - description: 'Key to run tests with custom test secrets' - required: false - type: string + testType: + description: Type of test to run (benchmark, soak) + required: true + default: benchmark + type: string jobs: - automation_benchmark: - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - name: Automation Benchmark Test - runs-on: ubuntu22.04-16cores-64GB - env: - SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} + run-e2e-tests-workflow: + name: Run E2E Tests + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + test_ids: '${{ inputs.testType }}/automation_test.go:TestAutomationBenchmark' + test_config_override_path: ${{ inputs.test_config_override_path }} + SLACK_USER: ${{ inputs.slackMemberID }} SLACK_CHANNEL: C03KJ5S7KEK - CHAINLINK_ENV_USER: ${{ github.actor }} - REF_NAME: ${{ github.head_ref || github.ref_name }} - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ env.REF_NAME }} - - name: Get Slack config and mask base64 config - run: | - SLACK_USER=$(jq -r '.inputs.slackMemberID' $GITHUB_EVENT_PATH) - echo ::add-mask::$SLACK_USER - echo SLACK_USER=$SLACK_USER >> $GITHUB_ENV - - BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64Config' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - name: Parse base64 config - uses: ./.github/actions/setup-parse-base64-config - with: - base64Config: ${{ env.BASE64_CONFIG_OVERRIDE }} - - name: Send details to Step Summary - shell: bash - run: | - echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_IMAGE }}\`" >>$GITHUB_STEP_SUMMARY - echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY - echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - - name: Build Test Image - id: build-test-image - uses: ./.github/actions/build-test-image - with: - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - suites: benchmark chaos reorg load - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 - env: - DETACH_RUNNER: true - TEST_SUITE: benchmark - TEST_ARGS: -test.timeout 720h - ENV_JOB_IMAGE: ${{ steps.build-test-image.outputs.test_image }} - INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com - TEST_TYPE: ${{ github.event.inputs.testType }} - TEST_TEST_TYPE: ${{ github.event.inputs.testType }} - RR_MEM: 4Gi - TEST_LOG_LEVEL: info - with: - test_command_to_run: cd integration-tests && go test -timeout 30m -v -run ^TestAutomationBenchmark$ ./benchmark -count=1 - test_download_vendor_packages_command: make gomod - test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} - test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ env.CHAINLINK_VERSION }} - token: ${{ secrets.GITHUB_TOKEN }} - should_cleanup: false - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: automation-benchmark-build-test-image - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Automation Benchmark Test - continue-on-error: true + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} diff --git a/.github/workflows/automation-load-tests.yml b/.github/workflows/automation-load-tests.yml index 95368825e3..23c053203a 100644 --- a/.github/workflows/automation-load-tests.yml +++ b/.github/workflows/automation-load-tests.yml @@ -2,123 +2,47 @@ name: Automation Load Test on: workflow_dispatch: inputs: - base64Config: - description: base64-ed config - required: true - type: string + test_config_override_path: + description: Path to a test config file used to override the default test config + required: false + type: string + test_secrets_override_key: + description: 'Key to run tests with custom test secrets' + required: false + type: string slackMemberID: description: Notifies test results (Not your @) required: true default: U02Q14G80TY - type: string - test_secrets_override_key: - description: 'Key to run tests with custom test secrets' - required: false - type: string + type: string jobs: - automation_load: - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - name: Automation Load Test - runs-on: ubuntu22.04-16cores-64GB - env: - SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} + run-e2e-tests-workflow: + name: Run E2E Tests + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + test_ids: 'load/automationv2_1/automationv2_1_test.go:TestLogTrigger' + test_config_override_path: ${{ inputs.test_config_override_path }} + SLACK_USER: ${{ inputs.slackMemberID }} SLACK_CHANNEL: C03KJ5S7KEK - CHAINLINK_ENV_USER: ${{ github.actor }} - REF_NAME: ${{ github.head_ref || github.ref_name }} - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ env.REF_NAME }} - - name: Get Slack config and mask base64 config - run: | - SLACK_USER=$(jq -r '.inputs.slackMemberID' $GITHUB_EVENT_PATH) - echo ::add-mask::$SLACK_USER - echo SLACK_USER=$SLACK_USER >> $GITHUB_ENV - - BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64Config' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - name: Merge Pyrsoscope config - env: - PYROSCOPE_SERVER: ${{ secrets.QA_PYROSCOPE_INSTANCE }} - PYROSCOPE_ENVIRONMENT: "automation-load-test" - PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - run: | - decoded_toml=$(echo $BASE64_CONFIG_OVERRIDE | base64 -d) - - # use Pyroscope config from GH secrets and merge it with base64 input - cat << EOF > config.toml - server_url="$PYROSCOPE_SERVER" - environment="$PYROSCOPE_ENVIRONMENT" - key_secret="$PYROSCOPE_KEY" - EOF - - echo "$decoded_toml" >> final_config.toml - cat config.toml >> final_config.toml - BASE64_CONFIG_OVERRIDE=$(cat final_config.toml | base64 -w 0) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - name: Parse base64 config - uses: ./.github/actions/setup-parse-base64-config - with: - base64Config: ${{ env.BASE64_CONFIG_OVERRIDE }} - - name: Send details to Step Summary - shell: bash - run: | - echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_IMAGE }}\`" >>$GITHUB_STEP_SUMMARY - echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY - echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - - name: Build Test Image - id: build-test-image - uses: ./.github/actions/build-test-image - with: - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - suites: benchmark chaos reorg load - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 - env: - RR_CPU: 4000m - RR_MEM: 4Gi - DETACH_RUNNER: true - TEST_SUITE: automationv2_1 - TEST_ARGS: -test.timeout 720h - ENV_JOB_IMAGE: ${{ steps.build-test-image.outputs.test_image }} - INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com - PYROSCOPE_SERVER: ${{ secrets.QA_PYROSCOPE_INSTANCE }} - PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - with: - test_command_to_run: cd integration-tests/load && go test -timeout 1h -v -run TestLogTrigger ./automationv2_1 -count=1 - test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} - test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} - test_download_vendor_packages_command: make gomod - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ env.CHAINLINK_VERSION }} - token: ${{ secrets.GITHUB_TOKEN }} - should_cleanup: false - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: automation-load-test - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Automation Load Test - continue-on-error: true + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} diff --git a/.github/workflows/automation-nightly-tests.yml b/.github/workflows/automation-nightly-tests.yml index d73df6a8c1..06dc00b3a1 100644 --- a/.github/workflows/automation-nightly-tests.yml +++ b/.github/workflows/automation-nightly-tests.yml @@ -7,291 +7,34 @@ on: - "*" workflow_dispatch: -env: - CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - jobs: - build-chainlink: - environment: integration - permissions: - id-token: write - contents: read - name: Build Chainlink Image - runs-on: ubuntu22.04-16cores-64GB - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: automation-nightly-build-chainlink - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Chainlink Image - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Build Chainlink Image - uses: ./.github/actions/build-chainlink-image - with: - tag_suffix: "" - dockerfile: core/chainlink.Dockerfile - git_commit_sha: ${{ github.sha }} - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - automation-upgrade-tests: - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink] - env: - CHAINLINK_COMMIT_SHA: ${{ github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: info - SELECTED_NETWORKS: "SIMULATED" - strategy: - fail-fast: false - matrix: - tests: - - name: Upgrade 2.0 - id: upgrade-2-0 - suite: smoke - nodes: 1 - os: ubuntu22.04-8cores-32GB - network: SIMULATED - command: -run ^TestAutomationNodeUpgrade/registry_2_0 ./smoke - - name: Upgrade 2.1 - id: upgrade-2-1 - suite: smoke - nodes: 5 - os: ubuntu22.04-8cores-32GB - network: SIMULATED - command: -run ^TestAutomationNodeUpgrade/registry_2_1 ./smoke - - name: Upgrade 2.2 - id: upgrade-2-2 - suite: smoke - nodes: 5 - os: ubuntu22.04-8cores-32GB - network: SIMULATED - command: -run ^TestAutomationNodeUpgrade/registry_2_2 ./smoke - runs-on: ${{ matrix.tests.os }} - name: Automation ${{ matrix.tests.name }} Test - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ github.head_ref || github.ref_name }} - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 - env: - TEST_SUITE: ${{ matrix.tests.suite }} - E2E_TEST_SELECTED_NETWORK: ${{ env.SELECTED_NETWORKS }} - E2E_TEST_CHAINLINK_IMAGE: "public.ecr.aws/chainlink/chainlink" - E2E_TEST_CHAINLINK_VERSION: "latest" - E2E_TEST_CHAINLINK_UPGRADE_IMAGE: ${{ env.CHAINLINK_IMAGE }} - E2E_TEST_CHAINLINK_UPGRADE_VERSION: ${{ github.sha }} - E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} - E2E_TEST_LOG_COLLECT: "true" - E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - E2E_TEST_LOG_STREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} - E2E_TEST_GRAFANA_BASE_URL: "http://localhost:8080/primary" - E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - with: - test_command_to_run: cd ./integration-tests && go test -timeout 60m -count=1 -json -test.parallel=${{ matrix.tests.nodes }} ${{ matrix.tests.command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false - test_download_vendor_packages_command: cd ./integration-tests && go mod download - cl_repo: 'public.ecr.aws/chainlink/chainlink' - cl_image_tag: 'latest' - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_location: ./integration-tests/${{ matrix.tests.suite }}/logs - artifacts_name: testcontainers-logs-${{ matrix.tests.name }} - publish_check_name: Automation Results ${{ matrix.tests.name }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Upload test log - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 - if: failure() - with: - name: gotest-logs-${{ matrix.tests.name }} - path: /tmp/gotest.log - retention-days: 7 - continue-on-error: true - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: automation-nightly-upgrade-tests-${{ matrix.tests.id }} - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Automation ${{ matrix.tests.name }} Test - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 - - test-notify: - name: Start Slack Thread - if: ${{ always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' }} - environment: integration - outputs: - thread_ts: ${{ steps.slack.outputs.thread_ts }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - runs-on: ubuntu-latest - needs: [ automation-upgrade-tests ] - steps: - - name: Debug Result - run: echo ${{ join(needs.*.result, ',') }} - - name: Main Slack Notification - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - id: slack - with: - channel-id: C03KJ5S7KEK - payload: | - { - "attachments": [ - { - "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || '#2E7D32' }}", - "blocks": [ - { - "type": "header", - "text": { - "type": "plain_text", - "text": "Automation Nightly Tests ${{ contains(join(needs.*.result, ','), 'failure') && ':x:' || ':white_check_mark:'}}", - "emoji": true - } - }, - { - "type": "divider" - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "<${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}> | <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}> | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Run>" - } - } - ] - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - - test-results: - name: Post Test Results for ${{ matrix.name }} - if: ${{ always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' }} - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - runs-on: ubuntu-latest - needs: test-notify - strategy: - fail-fast: false - matrix: - name: [ Upgrade 2.0, Upgrade 2.1, Upgrade 2.2 ] - steps: - - name: Get Results - id: test-results - run: | - # I feel like there's some clever, fully jq way to do this, but I ain't got the motivation to figure it out - echo "Querying test results" - - PARSED_RESULTS=$(curl \ - -H "Authorization: Bearer ${{ github.token }}" \ - 'https://api.github.com/repos/${{github.repository}}/actions/runs/${{ github.run_id }}/jobs' \ - | jq -r --arg pattern "${{ matrix.name }} Test" '.jobs[] - | select(.name | test($pattern)) as $job - | $job.steps[] - | select(.name == "Run Tests") - | { conclusion: (if .conclusion == "success" then ":white_check_mark:" else ":x:" end), product: ("*" + ($job.name | capture($pattern).product) + "*") }') - - echo "Parsed Results:" - echo $PARSED_RESULTS - - ALL_SUCCESS=true - for row in $(echo "$PARSED_RESULTS" | jq -s | jq -r '.[] | select(.conclusion != ":white_check_mark:")'); do - success=false - break - done - - echo all_success=$ALL_SUCCESS >> $GITHUB_OUTPUT - - FORMATTED_RESULTS=$(echo $PARSED_RESULTS | jq -s '[.[] - | { - conclusion: .conclusion, - product: .product - } - ] - | map("{\"type\": \"section\", \"text\": {\"type\": \"mrkdwn\", \"text\": \"\(.product): \(.conclusion)\"}}") - | join(",")') - - echo "Formatted Results:" - echo $FORMATTED_RESULTS - - # Cleans out backslashes and quotes from jq - CLEAN_RESULTS=$(echo "$FORMATTED_RESULTS" | sed 's/\\\"/"/g' | sed 's/^"//;s/"$//') - - echo "Clean Results" - echo $CLEAN_RESULTS - - echo results=$CLEAN_RESULTS >> $GITHUB_OUTPUT - - - name: Test Details - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - with: - channel-id: C03KJ5S7KEK - payload: | - { - "thread_ts": "${{ needs.test-notify.outputs.thread_ts }}", - "attachments": [ - { - "color": "${{ steps.test-results.outputs.all_success && '#2E7D32' || '#C62828' }}", - "blocks": [ - { - "type": "header", - "text": { - "type": "plain_text", - "text": "${{ matrix.name }} ${{ steps.test-results.outputs.all_success && ':white_check_mark:' || ':x: Notifying <@U02Q14G80TY>'}}", - "emoji": true - } - }, - { - "type": "divider" - }, - ${{ steps.test-results.outputs.results }} - ] - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} \ No newline at end of file + run-e2e-tests-workflow: + name: Run E2E Tests + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + test_workflow: Automation Nightly Tests + chainlink_version: ${{ github.sha }} + slack_notification_after_tests: true + slack_notification_after_tests_channel_id: "#automation-test-notifications" + slack_notification_after_tests_name: Automation Nightly E2E Tests + # slack_notification_after_tests_notify_user_id_on_failure: U0XXXXXXX + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml index ed69bd5ac0..a5b2674425 100644 --- a/.github/workflows/automation-ondemand-tests.yml +++ b/.github/workflows/automation-ondemand-tests.yml @@ -171,6 +171,9 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} diff --git a/.github/workflows/ccip-chaos-tests.yml b/.github/workflows/ccip-chaos-tests.yml index 1d37551d9f..3a6cae796d 100644 --- a/.github/workflows/ccip-chaos-tests.yml +++ b/.github/workflows/ccip-chaos-tests.yml @@ -34,6 +34,9 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} diff --git a/.github/workflows/ccip-load-tests.yml b/.github/workflows/ccip-load-tests.yml index ec65c2af10..235b9b0f67 100644 --- a/.github/workflows/ccip-load-tests.yml +++ b/.github/workflows/ccip-load-tests.yml @@ -10,293 +10,54 @@ on: - '*' workflow_dispatch: inputs: - base64_test_input: # base64 encoded toml for test input - description: 'Base64 encoded toml test input' + test_config_override_path: + description: Path to a test config file used to override the default test config required: false + type: string test_secrets_override_key: description: 'Key to run tests with custom test secrets' required: false type: string + chainlink_version: + description: Chainlink image version to use. Commit sha if not provided + required: false + type: string # Only run 1 of this workflow at a time per PR concurrency: group: load-ccip-tests-chainlink-${{ github.ref }} cancel-in-progress: true -env: - # TODO: TT-1470 - Update image names as we solidify new realease strategy - CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - CHAINLINK_VERSION: ${{ github.sha}} - INPUT_CHAINLINK_TEST_VERSION: ${{ github.sha}} - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ github.sha }} - INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com - AWS_ECR_REPO_PUBLIC_REGISTRY: public.ecr.aws - MOD_CACHE_VERSION: 1 - jobs: - build-chainlink: - environment: integration - permissions: - id-token: write - contents: read - name: Build Chainlink Image - runs-on: ubuntu20.04-16cores-64GB - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Check if image exists - id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 - with: - repository: chainlink - tag: ${{ env.CHAINLINK_VERSION }} - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - name: Build Image - if: steps.check-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@b49a9d04744b0237908831730f8553f26d73a94b # v2.3.17 - env: - GH_TOKEN: ${{ github.token }} - with: - cl_repo: smartcontractkit/chainlink - cl_ref: ${{ env.CHAINLINK_VERSION }} - push_tag: ${{ env.CHAINLINK_IMAGE }}:${{ env.CHAINLINK_VERSION }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: ccip-load-test-build-chainlink-image - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Chainlink Image - continue-on-error: true - - build-test-image: - environment: integration - permissions: - id-token: write - contents: read - name: Build Test Image - runs-on: ubuntu20.04-8cores-32GB - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: ccip-load-test-build-test-image - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Test Image - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Build Test Image - uses: ./.github/actions/build-test-image - with: - tag: ${{ env.INPUT_CHAINLINK_TEST_VERSION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - suites: ccip-load - - ccip-load-test: - environment: integration - needs: [ build-chainlink, build-test-image ] - if: ${{ always() && !contains(needs.*.result, 'failure') }} - permissions: - issues: read - checks: write - pull-requests: write - id-token: write - contents: read - env: - CHAINLINK_ENV_USER: ${{ github.actor }} + run-e2e-tests-workflow: + name: Run E2E Tests + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + test_workflow: E2E CCIP Load Tests + test_config_override_path: ${{ inputs.test_config_override_path }} + chainlink_version: ${{ inputs.chainlink_version || github.sha }} + slack_notification_after_tests: always + slack_notification_after_tests_channel_id: '#ccip-testing' + slack_notification_after_tests_name: CCIP E2E Load Tests + test_image_suites: ccip-load + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} - SLACK_CHANNEL: ${{ secrets.QA_SLACK_CHANNEL }} - TEST_LOG_LEVEL: info - REF_NAME: ${{ github.head_ref || github.ref_name }} - BASE64_NETWORK_CONFIG: ${{ secrets.BASE64_NETWORK_CONFIG }} - strategy: - fail-fast: false - matrix: - type: - - name: stable-load - run: ^TestLoadCCIPStableRPS$ - os: ubuntu-latest - # Enable when CCIP-2277 is resolved - # - name: load-with-arm-curse-uncurse - # run: ^TestLoadCCIPStableRPSAfterARMCurseAndUncurse$ - # config_path: ./integration-tests/ccip-tests/testconfig/tomls/load-with-arm-curse-uncurse.toml - # os: ubuntu-latest - runs-on: ${{ matrix.type.os }} - name: CCIP ${{ matrix.type.name }} - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: ccip-load-test-${{ matrix.type.name }} - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: CCIP ${{ matrix.type.name }} - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ env.REF_NAME }} - - name: Sets env vars - id: set_override_config - shell: bash - run: | - # if the matrix.type.config_path is set, use it as the override config - if [ -n "${{ matrix.type.config_path }}" ]; then - BASE64_CONFIG_OVERRIDE=$(base64 -w 0 -i ${{ matrix.type.config_path }}) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "base_64_override=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_OUTPUT - fi - if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then - BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64_test_input' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "base_64_override=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_OUTPUT - fi - - name: step summary - shell: bash - run: | - echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_VERSION }}\`" >> $GITHUB_STEP_SUMMARY - echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.INPUT_CHAINLINK_TEST_VERSION }}\`" >> $GITHUB_STEP_SUMMARY - - name: Prepare Base64 TOML override for CCIP secrets - uses: ./.github/actions/setup-create-base64-config-ccip - id: setup_create_base64_config_ccip - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkVersion: ${{ github.sha }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 - env: - TEST_SUITE: load - TEST_ARGS: -test.timeout 900h - DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable - RR_MEM: 8Gi - RR_CPU: 4 - TEST_TRIGGERED_BY: ccip-load-test-ci-${{ matrix.type.name }} - BASE64_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }},${{ steps.set_override_config.outputs.base_64_override }} - TEST_BASE64_CONFIG_OVERRIDE: ${{ steps.setup_create_base64_config_ccip.outputs.base64_config }},${{ steps.set_override_config.outputs.base_64_override }} - E2E_TEST_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - E2E_TEST_CHAINLINK_VERSION: ${{ env.CHAINLINK_VERSION }} - E2E_TEST_LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} - E2E_TEST_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} - E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} - E2E_TEST_GRAFANA_BASE_URL: ${{ vars.GRAFANA_URL }} - E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" - E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - with: - test_command_to_run: cd ./integration-tests/ccip-tests && go test -v -timeout 70m -count=1 -json -run ${{ matrix.type.run }} ./load 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} - test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - triggered_by: ${{ env.TEST_TRIGGERED_BY }} - publish_check_name: ${{ matrix.type.name }} - artifacts_location: ./integration-tests/load/logs/payload_ccip.json - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - cache_key_id: ccip-load-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - should_cleanup: "true" - - # Reporting Jobs - start-slack-thread: - name: Start Slack Thread - if: ${{ failure() && needs.ccip-load-test.result != 'skipped' && needs.ccip-load-test.result != 'cancelled' }} - environment: integration - outputs: - thread_ts: ${{ steps.slack.outputs.thread_ts }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - runs-on: ubuntu-latest - needs: [ccip-load-test] - steps: - - name: Debug Result - run: echo ${{ join(needs.*.result, ',') }} - - name: Main Slack Notification - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - id: slack - with: - channel-id: "#ccip-testing" - payload: | - { - "attachments": [ - { - "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || '#2E7D32' }}", - "blocks": [ - { - "type": "header", - "text": { - "type": "plain_text", - "text": "CCIP load tests results ${{ contains(join(needs.*.result, ','), 'failure') && ':x:' || ':white_check_mark:'}}", - "emoji": true - } - }, - { - "type": "divider" - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "<${{ github.server_url }}/${{ github.repository }}/${{contains(github.ref_name, 'release') && 'releases/tag' || 'tree'}}/${{ github.ref_name }}|${{ github.ref_name }}> | <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}> | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Run>" - } - } - ] - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - - post-test-results-to-slack: - name: Post Test Results - if: ${{ failure() && needs.start-slack-thread.result != 'skipped' && needs.start-slack-thread.result != 'cancelled' }} - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - runs-on: ubuntu-latest - needs: start-slack-thread - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Post Test Results - uses: ./.github/actions/notify-slack-jobs-result - with: - github_token: ${{ github.token }} - github_repository: ${{ github.repository }} - workflow_run_id: ${{ github.run_id }} - github_job_name_regex: ^CCIP (.*)$ - message_title: CCIP Jobs - slack_channel_id: "#ccip-testing" - slack_bot_token: ${{ secrets.QA_SLACK_API_KEY }} - slack_thread_ts: ${{ needs.start-slack-thread.outputs.thread_ts }} - - # End Reporting Jobs \ No newline at end of file diff --git a/.github/workflows/integration-chaos-tests.yml b/.github/workflows/integration-chaos-tests.yml index 1f7e6f40fb..c9da7d8438 100644 --- a/.github/workflows/integration-chaos-tests.yml +++ b/.github/workflows/integration-chaos-tests.yml @@ -27,6 +27,9 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} diff --git a/.github/workflows/integration-tests-publish.yml b/.github/workflows/integration-tests-publish.yml index de551fedce..b74902cdc4 100644 --- a/.github/workflows/integration-tests-publish.yml +++ b/.github/workflows/integration-tests-publish.yml @@ -40,7 +40,7 @@ jobs: run: | echo "other_tags=${ECR_TAG}" >> $GITHUB_OUTPUT - name: Build Image - uses: ./.github/actions/build-test-image + uses: smartcontractkit/.github/actions/ctf-build-test-image@a5e4f4c8fbb8e15ab2ad131552eca6ac83c4f4b3 # ctf-build-test-image@0.1.0 with: other_tags: ${{ steps.tags.outputs.other_tags }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index a8884c306f..032ec40b4e 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -71,7 +71,7 @@ jobs: echo "should-enforce=$SHOULD_ENFORCE" >> $GITHUB_OUTPUT - name: Enforce CTF Version if: steps.condition-check.outputs.should-enforce == 'true' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/mod-version@fc3e0df622521019f50d772726d6bf8dc919dd38 # v2.3.19 + uses: smartcontractkit/.github/actions/ctf-check-mod-version@21b0189c5fdca0318617d259634b1a91e6d80262 # ctf-check-mod-version@0.0.0 with: go-project-path: ./integration-tests module-name: github.com/smartcontractkit/chainlink-testing-framework/lib @@ -160,7 +160,7 @@ jobs: repository: smartcontractkit/chainlink ref: ${{ inputs.cl_ref }} - name: Setup Go - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@0ce1e67b254a4f041e03cc6f0e3afc987b47c7bd # v2.3.30 + uses: smartcontractkit/.github/actions/ctf-setup-go@b0d756c57fcdbcff187e74166562a029fdd5d1b9 # ctf-setup-go@0.0.0 with: test_download_vendor_packages_command: cd ${{ matrix.project.path }} && go mod download go_mod_path: ${{ matrix.project.path }}/go.mod @@ -232,8 +232,8 @@ jobs: AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} dep_evm_sha: ${{ inputs.evm-ref }} - run-core-e2e-tests-workflow: - name: Run Core E2E Tests + run-core-e2e-tests-for-pr: + name: Run Core E2E Tests For PR permissions: actions: read checks: write @@ -241,10 +241,10 @@ jobs: id-token: write contents: read needs: [build-chainlink, changes] - if: needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true' + if: github.event_name == 'pull_request' && ( needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml with: - workflow_name: Run Core E2E Tests + workflow_name: Run Core E2E Tests For PR chainlink_version: ${{ inputs.evm-ref || github.sha }} chainlink_upgrade_version: ${{ github.sha }} test_workflow: PR E2E Core Tests @@ -262,14 +262,17 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - run-ccip-e2e-tests-workflow: - name: Run CCIP E2E Tests + run-core-e2e-tests-for-merge-queue: + name: Run Core E2E Tests For Merge Queue permissions: actions: read checks: write @@ -277,10 +280,53 @@ jobs: id-token: write contents: read needs: [build-chainlink, changes] - if: needs.changes.outputs.ccip_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true' + if: github.event_name == 'merge_group' uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml with: - workflow_name: Run CCIP E2E Tests + workflow_name: Run Core E2E Tests For Merge Queue + chainlink_version: ${{ inputs.evm-ref || github.sha }} + chainlink_upgrade_version: ${{ github.sha }} + test_workflow: Merge Queue E2E Core Tests + upload_cl_node_coverage_artifact: true + upload_cl_node_coverage_artifact_prefix: cl_node_coverage_data_ + enable_otel_traces_for_ocr2_plugins: ${{ contains(join(github.event.pull_request.labels.*.name, ' '), 'enable tracing') }} + # Notify Test Tooling team in slack when merge queue tests fail + slack_notification_after_tests: on_failure + slack_notification_after_tests_channel_id: "#team-test-tooling-internal" + slack_notification_after_tests_name: Core E2E Tests In Merge Queue + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + + run-ccip-e2e-tests-for-pr: + name: Run CCIP E2E Tests For PR + permissions: + actions: read + checks: write + pull-requests: write + id-token: write + contents: read + needs: [build-chainlink, changes] + if: github.event_name == 'pull_request' && (needs.changes.outputs.ccip_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + workflow_name: Run CCIP E2E Tests For PR chainlink_version: ${{ inputs.evm-ref || github.sha }} chainlink_upgrade_version: ${{ github.sha }} test_workflow: PR E2E CCIP Tests @@ -298,6 +344,48 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + + run-ccip-e2e-tests-for-merge-queue: + name: Run CCIP E2E Tests For Merge Queue + permissions: + actions: read + checks: write + pull-requests: write + id-token: write + contents: read + needs: [build-chainlink, changes] + if: github.event_name == 'merge_group' && (needs.changes.outputs.ccip_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + workflow_name: Run CCIP E2E Tests For Merge Queue + chainlink_version: ${{ inputs.evm-ref || github.sha }} + chainlink_upgrade_version: ${{ github.sha }} + test_workflow: Merge Queue E2E CCIP Tests + upload_cl_node_coverage_artifact: true + upload_cl_node_coverage_artifact_prefix: cl_node_coverage_data_ + enable_otel_traces_for_ocr2_plugins: ${{ contains(join(github.event.pull_request.labels.*.name, ' '), 'enable tracing') }} + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} @@ -308,12 +396,12 @@ jobs: if: always() name: ETH Smoke Tests runs-on: ubuntu-latest - needs: [lint-integration-tests, run-core-e2e-tests-workflow, run-ccip-e2e-tests-workflow] + needs: [lint-integration-tests, run-core-e2e-tests-for-pr, run-ccip-e2e-tests-for-pr, run-core-e2e-tests-for-merge-queue, run-ccip-e2e-tests-for-merge-queue] steps: - name: Check Core test results id: check_core_results run: | - results='${{ needs.run-core-e2e-tests-workflow.outputs.test_results }}' + results='${{ needs.run-core-e2e-tests-for-pr.outputs.test_results }}' echo "Core test results:" echo "$results" | jq . @@ -323,8 +411,8 @@ jobs: - name: Check CCIP test results id: check_ccip_results run: | - if [[ '${{ needs.run-ccip-e2e-tests-workflow.result }}' != 'skipped' ]]; then - results='${{ needs.run-ccip-e2e-tests-workflow.outputs.test_results }}' + if [[ '${{ needs.run-ccip-e2e-tests-for-pr.result }}' != 'skipped' ]]; then + results='${{ needs.run-ccip-e2e-tests-for-pr.outputs.test_results }}' echo "CCIP test results:" echo "$results" | jq . else @@ -340,10 +428,14 @@ jobs: channel-id: "#team-test-tooling-internal" slack-message: ":x: :mild-panic-intensifies: Node Migration Tests Failed: \n${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }}\n${{ format('Notifying ', secrets.GUARDIAN_SLACK_NOTIFICATION_HANDLE) }}" - - name: Fail the job if core tests not successful - if: always() && needs.run-core-e2e-tests-workflow.result == 'failure' + - name: Fail the job if core tests in PR not successful + if: always() && needs.run-core-e2e-tests-for-pr.result == 'failure' run: exit 1 + - name: Fail the job if core tests in merge queue not successful + if: always() && needs.run-core-e2e-tests-for-merge-queue.result == 'failure' + run: exit 1 + - name: Fail the job if lint not successful if: always() && needs.lint-integration-tests.result == 'failure' run: exit 1 @@ -351,7 +443,7 @@ jobs: cleanup: name: Clean up integration environment deployments if: always() - needs: [run-core-e2e-tests-workflow, run-ccip-e2e-tests-workflow] + needs: [run-core-e2e-tests-for-pr, run-ccip-e2e-tests-for-pr, run-core-e2e-tests-for-merge-queue, run-ccip-e2e-tests-for-merge-queue] runs-on: ubuntu-latest steps: - name: Checkout repo @@ -383,7 +475,7 @@ jobs: show-chainlink-node-coverage: name: Show Chainlink Node Go Coverage if: always() - needs: [run-core-e2e-tests-workflow, run-ccip-e2e-tests-workflow] + needs: [run-core-e2e-tests-for-pr, run-ccip-e2e-tests-for-pr, run-core-e2e-tests-for-merge-queue, run-ccip-e2e-tests-for-merge-queue] runs-on: ubuntu-latest steps: - name: Checkout the repo @@ -567,10 +659,9 @@ jobs: ref: ${{ needs.get_solana_sha.outputs.sha }} - name: Build Test Image if: (needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch') && needs.solana-test-image-exists.outputs.exists == 'false' - uses: ./.github/actions/build-test-image + uses: smartcontractkit/.github/actions/ctf-build-test-image@a5e4f4c8fbb8e15ab2ad131552eca6ac83c4f4b3 # ctf-build-test-image@0.1.0 with: tag: ${{ needs.get_solana_sha.outputs.sha }} - artifacts_path: ${{ env.CONTRACT_ARTIFACTS_PATH }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} @@ -620,7 +711,7 @@ jobs: ref: ${{ needs.get_solana_sha.outputs.sha }} - name: Run Setup if: needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@0ce1e67b254a4f041e03cc6f0e3afc987b47c7bd # v2.3.30 + uses: smartcontractkit/.github/actions/ctf-setup-run-tests-environment@49cb1613e96c9ce17f7290e4dabd38f43aa9bd4d # ctf-setup-run-tests-environment@0.0.0 with: go_mod_path: ./integration-tests/go.mod cache_restore_only: true @@ -672,7 +763,7 @@ jobs: echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - name: Run Tests if: needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 + uses: smartcontractkit/.github/actions/ctf-run-tests@b8731364b119e88983e94b0c4da87fc27ddb41b8 # ctf-run-tests@0.0.0 with: test_command_to_run: export ENV_JOB_IMAGE=${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-solana-tests:${{ needs.get_solana_sha.outputs.sha }} && make test_smoke test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} diff --git a/.github/workflows/live-testnet-tests.yml b/.github/workflows/live-testnet-tests.yml deleted file mode 100644 index bcf4dfea19..0000000000 --- a/.github/workflows/live-testnet-tests.yml +++ /dev/null @@ -1,1119 +0,0 @@ -# *** -# This workflow is a monstrosity of copy-paste, and that's to increase legibility in reporting and running, so the code be damned. -# I suspect this can be cleaned up significantly with some clever trickery of the GitHub actions matrices, but I am not that clever. -# We want each chain to run in parallel, but each test within the chain needs to be able to run sequentially -# (we're trying to eliminate this as a requirement, should make it a lot easier). -# Each chain can have a variety of tests to run. -# We also want reporting to be clear in the start-slack-thread and post-test-results-to-slack jobs. -# Funding address: 0xC1107e57082945E28d3202A81B1520DEA3AE6AEC -# *** - -name: Live Testnet Tests -on: - # Disable refular runs for now until we can fix some test client flakiness and improve stability - # schedule: - # - cron: "0 5 * * *" # Run every night at midnight EST - # push: - # tags: - # - "*" - workflow_dispatch: - inputs: - slack_user_id: - description: "The Slack member ID to notify" - required: true - type: string - network: - description: "The network to run tests on" - required: true - type: choice - options: - - "All" - - "Sepolia" - - "Optimism Sepolia" - - "Arbitrum Sepolia" - - "Base Sepolia" - - "Polygon Mumbai" - - "Avalanche Fuji" - - "Fantom Testnet" - - "Celo Alfajores" - - "Linea Goerli" - - "BSC Testnet" - -env: - CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com - MOD_CACHE_VERSION: 2 - CHAINLINK_NODE_FUNDING: .5 - PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - LOKI_TENANT_ID: ${{ vars.LOKI_TENANT_ID }} - LOKI_URL: ${{ secrets.LOKI_URL }} - LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} - LOGSTREAM_LOG_TARGETS: loki - GRAFANA_URL: ${{ vars.GRAFANA_URL }} - RUN_ID: ${{ github.run_id }} - - CHAINLINK_COMMIT_SHA: ${{ github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: debug - -jobs: - - # Build Test Dependencies - - build-chainlink: - environment: integration - permissions: - id-token: write - contents: read - name: Build Chainlink Image - runs-on: ubuntu-latest - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: live-testnet-build-chainlink - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Chainlink Image - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Build Chainlink Image - uses: ./.github/actions/build-chainlink-image - with: - tag_suffix: "" - dockerfile: core/chainlink.Dockerfile - git_commit_sha: ${{ github.sha }} - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - build-tests: - environment: integration - permissions: - id-token: write - contents: read - name: Build Tests Binary - runs-on: ubuntu-latest - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: live-testnet-build-test-image - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Tests Binary - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Build Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-tests@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_download_vendor_packages_command: cd ./integration-tests && go mod download - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - go_tags: embed - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - binary_name: tests - - # End Build Test Dependencies - - # Reporting Jobs - - start-slack-thread: - name: Start Slack Thread - if: ${{ always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' }} - environment: integration - outputs: - thread_ts: ${{ steps.slack.outputs.thread_ts }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - runs-on: ubuntu-latest - needs: [sepolia-smoke-tests, optimism-sepolia-smoke-tests, arbitrum-sepolia-smoke-tests, base-sepolia-smoke-tests, polygon-mumbai-smoke-tests, avalanche-fuji-smoke-tests, fantom-testnet-smoke-tests, celo-alfajores-smoke-tests, linea-goerli-smoke-tests, bsc-testnet-smoke-tests] - steps: - - name: Debug Result - run: echo ${{ join(needs.*.result, ',') }} - - name: Main Slack Notification - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - id: slack - with: - channel-id: ${{ secrets.QA_SLACK_CHANNEL }} - payload: | - { - "attachments": [ - { - "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || '#2E7D32' }}", - "blocks": [ - { - "type": "header", - "text": { - "type": "plain_text", - "text": "Live Smoke Test Results ${{ contains(join(needs.*.result, ','), 'failure') && ':x:' || ':white_check_mark:'}}", - "emoji": true - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "Notifying <@${{ inputs.slack_user_id }}>" - } - }, - { - "type": "divider" - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "<${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}> | <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}> | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Run>\nThe funding address for all tests and networks is `0xC1107e57082945E28d3202A81B1520DEA3AE6AEC`" - } - } - ] - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - - post-test-results-to-slack: - name: Post Test Results for ${{ matrix.network }} - if: ${{ always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' }} - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - runs-on: ubuntu-latest - needs: start-slack-thread - strategy: - fail-fast: false - matrix: - network: [Sepolia, Optimism Sepolia, Arbitrum Sepolia, Base Sepolia, Polygon Mumbai, Avalanche Fuji, Fantom Testnet, Celo Alfajores, Linea Goerli, BSC Testnet] - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Post Test Results - uses: ./.github/actions/notify-slack-jobs-result - with: - github_token: ${{ github.token }} - github_repository: ${{ github.repository }} - workflow_run_id: ${{ github.run_id }} - github_job_name_regex: ^${{ matrix.network }} (.*?) Tests$ - message_title: ${{ matrix.network }} - slack_channel_id: ${{ secrets.QA_SLACK_CHANNEL }} - slack_bot_token: ${{ secrets.QA_SLACK_API_KEY }} - slack_thread_ts: ${{ needs.start-slack-thread.outputs.thread_ts }} - - # End Reporting Jobs - - sepolia-smoke-tests: - environment: integration - if: ${{ (github.event.inputs.network == 'All' || github.event.inputs.network == 'Sepolia') }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-tests] - strategy: - max-parallel: 1 - fail-fast: false - matrix: - include: # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#example-adding-configurations - - product: OCR - test: TestOCRBasic - - product: Automation Conditional - test: TestAutomationBasic/registry_2_1_conditional - - product: Automation Log Trigger - test: TestAutomationBasic/registry_2_1_logtrigger - name: Sepolia ${{ matrix.product }} Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config-live-testnets - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ci-smoke-${{ matrix.product }}-sepolia - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - network: "sepolia" - httpEndpoints: ${{ secrets.QA_SEPOLIA_HTTP_URLS }} - wsEndpoints: ${{ secrets.QA_SEPOLIA_URLS }} - fundingKeys: ${{ secrets.QA_EVM_KEYS }} - - name: Download Tests Binary - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - with: - name: tests - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} - binary_name: tests - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - artifacts_location: ./logs - token: ${{ secrets.GITHUB_TOKEN }} - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directories: "./" - - bsc-testnet-smoke-tests: - environment: integration - if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'BSC Testnet' }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-tests] - strategy: - max-parallel: 1 - fail-fast: false - matrix: - include: # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#example-adding-configurations - - product: OCR - test: TestOCRBasic - - product: Automation Conditional - test: TestAutomationBasic/registry_2_1_conditional - - product: Automation Log Trigger - test: TestAutomationBasic/registry_2_1_logtrigger - name: BSC Testnet ${{ matrix.product }} Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config-live-testnets - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ci-smoke-${{ matrix.product }}-bsc-testnet - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - network: "bsc_testnet" - httpEndpoints: ${{ secrets.QA_BSC_TESTNET_HTTP_URLS }} - wsEndpoints: ${{ secrets.QA_BSC_TESTNET_URLS }} - fundingKeys: ${{ secrets.QA_EVM_KEYS }} - - name: Download Tests Binary - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - with: - name: tests - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} - binary_name: tests - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - artifacts_location: ./logs - token: ${{ secrets.GITHUB_TOKEN }} - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directory: "./" - - optimism-sepolia-smoke-tests: - environment: integration - if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Optimism Sepolia' }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-tests] - strategy: - max-parallel: 1 - fail-fast: false - matrix: - include: # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#example-adding-configurations - - product: OCR - test: TestOCRBasic - - product: Automation Conditional - test: TestAutomationBasic/registry_2_1_conditional - - product: Automation Log Trigger - test: TestAutomationBasic/registry_2_1_logtrigger - name: Optimism Sepolia ${{ matrix.product }} Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config-live-testnets - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ci-smoke-${{ matrix.product }}-optimism-sepolia - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - network: "optimism_sepolia" - httpEndpoints: ${{ secrets.QA_OPTIMISM_SEPOLIA_HTTP_URLS }} - wsEndpoints: ${{ secrets.QA_OPTIMISM_SEPOLIA_URLS }} - fundingKeys: ${{ secrets.QA_EVM_KEYS }} - - name: Download Tests Binary - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - with: - name: tests - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} - binary_name: tests - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - artifacts_location: ./logs - token: ${{ secrets.GITHUB_TOKEN }} - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directory: "./" - - arbitrum-sepolia-smoke-tests: - environment: integration - if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Arbitrum Sepolia' }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-tests] - strategy: - max-parallel: 1 - fail-fast: false - matrix: - include: # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#example-adding-configurations - - product: OCR - test: TestOCRBasic - - product: Automation Conditional - test: TestAutomationBasic/registry_2_1_conditional - - product: Automation Log Trigger - test: TestAutomationBasic/registry_2_1_logtrigger - name: Arbitrum Sepolia ${{ matrix.product }} Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config-live-testnets - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ci-smoke-${{ matrix.product }}-arbitrum-sepolia - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - network: "arbitrum_sepolia" - httpEndpoints: ${{ secrets.QA_ARBITRUM_SEPOLIA_HTTP_URLS }} - wsEndpoints: ${{ secrets.QA_ARBITRUM_SEPOLIA_URLS }} - fundingKeys: ${{ secrets.QA_EVM_KEYS }} - - name: Download Tests Binary - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - with: - name: tests - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} - binary_name: tests - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - artifacts_location: ./logs - token: ${{ secrets.GITHUB_TOKEN }} - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directory: "./" - - base-sepolia-smoke-tests: - environment: integration - if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Base Sepolia' }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-tests] - strategy: - max-parallel: 1 - fail-fast: false - matrix: - include: # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#example-adding-configurations - - product: OCR - test: TestOCRBasic - name: Base Sepolia ${{ matrix.product }} Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config-live-testnets - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ci-smoke-${{ matrix.product }}-base-sepolia - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - network: "base_sepolia" - httpEndpoints: ${{ secrets.QA_BASE_SEPOLIA_HTTP_URLS }} - wsEndpoints: ${{ secrets.QA_BASE_SEPOLIA_URLS }} - fundingKeys: ${{ secrets.QA_EVM_KEYS }} - - name: Download Tests Binary - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - with: - name: tests - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} - binary_name: tests - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - artifacts_location: ./logs - token: ${{ secrets.GITHUB_TOKEN }} - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directory: "./" - - polygon-mumbai-smoke-tests: - environment: integration - if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Polygon Mumbai' }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-tests] - strategy: - max-parallel: 1 - fail-fast: false - matrix: - include: # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#example-adding-configurations - - product: OCR - test: TestOCRBasic - - product: Automation Conditional - test: TestAutomationBasic/registry_2_1_conditional - - product: Automation Log Trigger - test: TestAutomationBasic/registry_2_1_logtrigger - name: Polygon Mumbai ${{ matrix.product }} Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config-live-testnets - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ci-smoke-${{ matrix.product }}-polygon-mumbai - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - network: "polygon_mumbai" - httpEndpoints: ${{ secrets.QA_POLYGON_MUMBAI_HTTP_URLS }} - wsEndpoints: ${{ secrets.QA_POLYGON_MUMBAI_URLS }} - fundingKeys: ${{ secrets.QA_EVM_KEYS }} - - name: Download Tests Binary - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - with: - name: tests - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} - binary_name: tests - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - artifacts_location: ./logs - token: ${{ secrets.GITHUB_TOKEN }} - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directory: "./" - - avalanche-fuji-smoke-tests: - environment: integration - if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Avalanche Fuji' }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-tests] - strategy: - max-parallel: 1 - fail-fast: false - matrix: - include: # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#example-adding-configurations - - product: OCR - test: TestOCRBasic - - product: Automation Conditional - test: TestAutomationBasic/registry_2_1_conditional - - product: Automation Log Trigger - test: TestAutomationBasic/registry_2_1_logtrigger - name: Avalanche Fuji ${{ matrix.product }} Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config-live-testnets - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ci-smoke-${{ matrix.product }}-avalanche-fuji - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - network: "avalanche_fuji" - httpEndpoints: ${{ secrets.QA_AVALANCHE_FUJI_HTTP_URLS }} - wsEndpoints: ${{ secrets.QA_AVALANCHE_FUJI_URLS }} - fundingKeys: ${{ secrets.QA_EVM_KEYS }} - - name: Download Tests Binary - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - with: - name: tests - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} - binary_name: tests - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - artifacts_location: ./logs - token: ${{ secrets.GITHUB_TOKEN }} - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directory: "./" - - fantom-testnet-smoke-tests: - environment: integration - if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Fantom Testnet' }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-tests] - strategy: - max-parallel: 1 - fail-fast: false - matrix: - include: # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#example-adding-configurations - - product: OCR - test: TestOCRBasic - - product: Automation Conditional - test: TestAutomationBasic/registry_2_1_conditional - - product: Automation Log Trigger - test: TestAutomationBasic/registry_2_1_logtrigger - name: Fantom Testnet ${{ matrix.product }} Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config-live-testnets - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ci-smoke-${{ matrix.product }}-fantom-testnet - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - network: "fantom_testnet" - httpEndpoints: ${{ secrets.QA_FANTOM_TESTNET_HTTP_URLS }} - wsEndpoints: ${{ secrets.QA_FANTOM_TESTNET_URLS }} - fundingKeys: ${{ secrets.QA_EVM_KEYS }} - - name: Download Tests Binary - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - with: - name: tests - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} - binary_name: tests - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - artifacts_location: ./logs - token: ${{ secrets.GITHUB_TOKEN }} - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directory: "./" - - celo-alfajores-smoke-tests: - environment: integration - if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Celo Alfajores' }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-tests] - strategy: - max-parallel: 1 - fail-fast: false - matrix: - include: # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#example-adding-configurations - - product: OCR - test: TestOCRBasic - name: Celo Alfajores ${{ matrix.product }} Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config-live-testnets - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ci-smoke-${{ matrix.product }}-celo-alfajores - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - network: "celo_alfajores" - httpEndpoints: ${{ secrets.QA_CELO_ALFAJORES_HTTP_URLS }} - wsEndpoints: ${{ secrets.QA_CELO_ALFAJORES_URLS }} - fundingKeys: ${{ secrets.QA_EVM_KEYS }} - - name: Download Tests Binary - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - with: - name: tests - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} - binary_name: tests - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - artifacts_location: ./logs - token: ${{ secrets.GITHUB_TOKEN }} - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directory: "./" - - scroll-sepolia-smoke-tests: - if: false - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-tests] - strategy: - max-parallel: 1 - fail-fast: false - matrix: - include: # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#example-adding-configurations - - product: OCR - test: TestOCRBasic - name: Scroll Sepolia ${{ matrix.product }} Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config-live-testnets - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ci-smoke-${{ matrix.product }}-scroll-sepolia - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - network: "scroll_sepolia" - httpEndpoints: ${{ secrets.QA_SCROLL_SEPOLIA_HTTP_URLS }} - wsEndpoints: ${{ secrets.QA_SCROLL_SEPOLIA_URLS }} - fundingKeys: ${{ secrets.QA_EVM_KEYS }} - - name: Download Tests Binary - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - with: - name: tests - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} - binary_name: tests - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - artifacts_location: ./logs - token: ${{ secrets.GITHUB_TOKEN }} - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directory: "./" - - linea-goerli-smoke-tests: - environment: integration - if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Linea Goerli' }} - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, build-tests] - strategy: - max-parallel: 1 - fail-fast: false - matrix: - include: # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#example-adding-configurations - - product: OCR - test: TestOCRBasic - name: Linea Goerli ${{ matrix.product }} Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - with: - # aws inputs - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - # other inputs - duplicate-authorization-header: "true" - - name: Prepare Base64 TOML override - uses: ./.github/actions/setup-create-base64-config-live-testnets - with: - runId: ${{ github.run_id }} - testLogCollect: ${{ vars.TEST_LOG_COLLECT }} - chainlinkImage: ${{ env.CHAINLINK_IMAGE }} - chainlinkVersion: ${{ github.sha }} - pyroscopeServer: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - pyroscopeEnvironment: ci-smoke-${{ matrix.product }}-linea-goerli - pyroscopeKey: ${{ secrets.QA_PYROSCOPE_KEY }} - lokiEndpoint: ${{ secrets.LOKI_URL }} - lokiTenantId: ${{ vars.LOKI_TENANT_ID }} - lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} - logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - grafanaUrl: "http://localhost:8080/primary" - grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - grafanaBearerToken: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - network: "linea_goerli" - httpEndpoints: ${{ secrets.QA_LINEA_GOERLI_HTTP_URLS }} - wsEndpoints: ${{ secrets.QA_LINEA_GOERLI_URLS }} - fundingKeys: ${{ secrets.QA_EVM_KEYS }} - - name: Download Tests Binary - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 - with: - name: tests - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_command_to_run: ./tests -test.timeout 30m -test.count=1 -test.parallel=1 -test.run ${{ matrix.test }} - binary_name: tests - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} - dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} - artifacts_location: ./logs - token: ${{ secrets.GITHUB_TOKEN }} - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - with: - test_directory: "./" diff --git a/.github/workflows/on-demand-ocr-soak-test.yml b/.github/workflows/on-demand-ocr-soak-test.yml index ffd4f6887a..cdb0b5da01 100644 --- a/.github/workflows/on-demand-ocr-soak-test.yml +++ b/.github/workflows/on-demand-ocr-soak-test.yml @@ -3,116 +3,66 @@ on: workflow_dispatch: inputs: testToRun: - description: Select a test to run + description: Select a test to run from .github/e2e-tests.yml required: true default: TestOCRSoak type: choice options: - - TestOCRv1Soak - - TestOCRv2Soak - - TestForwarderOCRv1Soak - - TestForwarderOCRv2Soak - - TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled - - TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled - - TestOCRSoak_GasSpike - - TestOCRSoak_ChangeBlockGasLimit - - TestOCRSoak_RPCDownForAllCLNodes - - TestOCRSoak_RPCDownForHalfCLNodes - base64Config: - description: base64-ed config + - soak/ocr_test.go:TestOCRv1Soak + - soak/ocr_test.go:TestOCRv2Soak + - soak/ocr_test.go:TestForwarderOCRv1Soak + - soak/ocr_test.go:TestForwarderOCRv2Soak + - soak/ocr_test.go:TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled + - soak/ocr_test.go:TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled + - soak/ocr_test.go:TestOCRSoak_GasSpike + - soak/ocr_test.go:TestOCRSoak_ChangeBlockGasLimit + - soak/ocr_test.go:TestOCRSoak_RPCDownForAllCLNodes + - soak/ocr_test.go:TestOCRSoak_RPCDownForHalfCLNodes + test_config_override_path: + description: Path to a test config file used to override the default test config + required: false + type: string + test_secrets_override_key: + description: 'Key to run tests with custom test secrets' + required: false + type: string + chainlink_version: + description: Chainlink image version to use + default: develop required: true type: string slackMemberID: description: Slack Member ID (Not your @) required: true - default: U01A2B2C3D4 - type: string - test_secrets_override_key: - description: 'Key to run tests with custom test secrets' - required: false - type: string + default: U01A2B2C3D4 jobs: - ocr_soak_test: - name: OCR Soak Test - environment: integration - runs-on: ubuntu-latest - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - env: - CHAINLINK_ENV_USER: ${{ github.actor }} + run-e2e-tests-workflow: + name: Run E2E Tests + uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + with: + test_ids: ${{ inputs.testToRun}} + test_config_override_path: ${{ inputs.test_config_override_path }} + chainlink_version: ${{ inputs.chainlink_version }} + SLACK_USER: ${{ inputs.slackMemberID }} + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} SLACK_API_KEY: ${{ secrets.QA_SLACK_API_KEY }} SLACK_CHANNEL: ${{ secrets.QA_SLACK_CHANNEL }} - TEST_LOG_LEVEL: debug - REF_NAME: ${{ github.head_ref || github.ref_name }} - ENV_JOB_IMAGE_BASE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: on-demand-ocr-soak-test - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ${{ inputs.network }} OCR Soak Test - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ env.REF_NAME }} - - name: Get Slack config and mask base64 config - run: | - SLACK_USER=$(jq -r '.inputs.slackMemberID' $GITHUB_EVENT_PATH) - echo ::add-mask::$SLACK_USER - echo SLACK_USER=$SLACK_USER >> $GITHUB_ENV - - BASE64_CONFIG_OVERRIDE=$(jq -r '.inputs.base64Config' $GITHUB_EVENT_PATH) - echo ::add-mask::$BASE64_CONFIG_OVERRIDE - echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - - name: Parse base64 config - uses: ./.github/actions/setup-parse-base64-config - with: - base64Config: ${{ env.BASE64_CONFIG_OVERRIDE }} - - name: Setup Push Tag - shell: bash - run: | - echo "### chainlink image used for this test run :link:" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.CHAINLINK_IMAGE }}\`" >>$GITHUB_STEP_SUMMARY - echo "### chainlink-tests image tag for this test run :ship:" >>$GITHUB_STEP_SUMMARY - echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY - echo "### Networks on which test was run" >>$GITHUB_STEP_SUMMARY - echo "\`${{ env.NETWORKS }}\`" >>$GITHUB_STEP_SUMMARY - - name: Build Image - id: build-test-image - uses: ./.github/actions/build-test-image - with: - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@94cb11f4bd545607a2f221c6685052b3abee723d # v2.3.32 - env: - DETACH_RUNNER: true - TEST_SUITE: soak - TEST_ARGS: -test.timeout 900h -test.memprofile memprofile.out -test.cpuprofile profile.out - ENV_JOB_IMAGE: ${{ steps.build-test-image.outputs.test_image }} - # We can comment these out when we have a stable soak test and aren't worried about resource consumption - TEST_UPLOAD_CPU_PROFILE: true - TEST_UPLOAD_MEM_PROFILE: true - with: - test_command_to_run: cd ./integration-tests && go test -v -count=1 -run ^${{ github.event.inputs.testToRun }}$ ./soak - test_download_vendor_packages_command: make gomod - test_secrets_override_base64: ${{ secrets[inputs.test_secrets_override_key] }} - test_config_override_base64: ${{ env.BASE64_CONFIG_OVERRIDE }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ env.CHAINLINK_VERSION }} - token: ${{ secrets.GITHUB_TOKEN }} - should_cleanup: false - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} diff --git a/.github/workflows/on-demand-vrfv2-performance-test.yml b/.github/workflows/on-demand-vrfv2-performance-test.yml index ad8640ccfa..d5eefcc348 100644 --- a/.github/workflows/on-demand-vrfv2-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2-performance-test.yml @@ -85,6 +85,9 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} diff --git a/.github/workflows/on-demand-vrfv2-smoke-tests.yml b/.github/workflows/on-demand-vrfv2-smoke-tests.yml index ede71267b4..ea42a9014d 100644 --- a/.github/workflows/on-demand-vrfv2-smoke-tests.yml +++ b/.github/workflows/on-demand-vrfv2-smoke-tests.yml @@ -88,6 +88,9 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} diff --git a/.github/workflows/on-demand-vrfv2plus-performance-test.yml b/.github/workflows/on-demand-vrfv2plus-performance-test.yml index 0744a93b26..f026086fff 100644 --- a/.github/workflows/on-demand-vrfv2plus-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-performance-test.yml @@ -85,6 +85,9 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} diff --git a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml index 5330edf294..e1821336c6 100644 --- a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml +++ b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml @@ -88,6 +88,9 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index 6eaa3f2798..8278828a38 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -63,6 +63,11 @@ on: description: 'Use the existing remote runner version for k8s tests. Example: "d3bf5044af33e08be788a2df31c4a745cf69d787"' required: false type: string + test_image_suites: + description: 'Suites to build in the test image. Space separated' + required: false + type: string + default: chaos migration reorg smoke soak benchmark load require_chainlink_image_versions_in_qa_ecr: description: 'Check Chainlink image versions to be present in QA ECR. If not, build and push the image to QA ECR. Takes comma separated list of Chainlink image versions. Example: "5733cdcda9a9fc6da6343798b119b2ae136146cd,0b7d2c497a508efa5a827714780d908b7b8eda19"' required: false @@ -96,7 +101,7 @@ on: description: 'Number of days to retain the test log. Default is 3 days' required: false type: number - default: 3 + default: 5 test_log_level: description: 'Set the log level for the tests. Default is "debug"' required: false @@ -116,13 +121,21 @@ on: required: false type: boolean default: false + SLACK_CHANNEL: + description: 'SLACK_CHANNEL env used to send Slack notifications from test code' + required: false + type: string + SLACK_USER: + description: 'SLACK_USER env used to send Slack notifications from test code' + required: false + type: string outputs: test_results: description: 'Test results from all executed tests' value: ${{ jobs.after_tests.outputs.test_results }} secrets: TEST_SECRETS_OVERRIDE_BASE64: - required: false + required: false QA_AWS_REGION: required: true QA_AWS_ROLE_TO_ASSUME: @@ -135,6 +148,12 @@ on: required: true QA_KUBECONFIG: required: true + LOKI_TENANT_ID: + required: true + LOKI_URL: + required: true + LOKI_BASIC_AUTH: + required: true GRAFANA_INTERNAL_TENANT_ID: required: true GRAFANA_INTERNAL_BASIC_AUTH: @@ -166,16 +185,17 @@ on: env: CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink QA_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - DEFAULT_CHAINLINK_VERSION: ${{ inputs.chainlink_version || github.sha }} - DEFAULT_CHAINLINK_PLUGINS_VERSION: ${{ inputs.chainlink_version != '' && format('{0}-plugins', inputs.chainlink_version) || format('{0}-plugins', github.sha) }} + DEFAULT_CHAINLINK_VERSION: ${{ inputs.chainlink_version }} + DEFAULT_CHAINLINK_PLUGINS_VERSION: ${{ inputs.chainlink_version != '' && format('{0}-plugins', inputs.chainlink_version) }} + DEFAULT_CHAINLINK_UPGRADE_VERSION: ${{ inputs.chainlink_version }} CHAINLINK_ENV_USER: ${{ github.actor }} - CHAINLINK_COMMIT_SHA: ${{ inputs.evm-ref || github.sha }} - SELECTED_NETWORKS: SIMULATED + CHAINLINK_COMMIT_SHA: ${{ inputs.evm-ref }} MOD_CACHE_VERSION: 1 TEST_LOG_LEVEL: ${{ inputs.test_log_level }} METRICS_COLLECTION_ID: chainlink-e2e-tests SLACK_API_KEY: ${{ secrets.SLACK_API_KEY }} - SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }} + SLACK_CHANNEL: ${{ inputs.slack_notification_after_tests_channel_id || inputs.SLACK_CHANNEL || secrets.SLACK_CHANNEL }} + SLACK_USER: ${{ inputs.SLACK_USER }} jobs: validate-inputs: @@ -239,7 +259,7 @@ jobs: path: core - name: Install citool shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/citool@a49f2dff000fcf020ab9978b33e3726d7df5bf96 # v1.34.4 + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/citool@1d8d5b55bf6379b969dbcde99abc87faa5963ea1 # v1.34.4 - name: Run Check Tests Command run: | if ! citool check-tests ${{ github.workspace }}/integration-tests ${{ github.workspace }}/.github/e2e-tests.yml; then @@ -286,7 +306,7 @@ jobs: check-latest: true - name: Install citool shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/citool@a49f2dff000fcf020ab9978b33e3726d7df5bf96 # v1.34.4 + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/citool@1d8d5b55bf6379b969dbcde99abc87faa5963ea1 # v1.34.4 - name: Install jq run: sudo apt-get install jq @@ -352,29 +372,6 @@ jobs: fi shell: bash - - name: Check if test config override is required for any test - shell: bash - run: | - # Parse the JSON to check for test_config_override_required in Docker matrix - DOCKER_TESTS_REQUIRING_CONFIG_OVERRIDE=$(echo '${{ steps.set-docker-matrix.outputs.matrix }}' | jq 'if .tests then .tests[] | select(has("test_config_override_required") and .test_config_override_required) | .id else empty end' -r) - # Parse the JSON to check for test_config_override_required in Kubernetes matrix - K8S_TESTS_REQUIRING_CONFIG_OVERRIDE=$(echo '${{ steps.set-k8s-runner-matrix.outputs.matrix }}' | jq 'if .tests then .tests[] | select(has("test_config_override_required") and .test_config_override_required) | .id else empty end' -r) - - # Determine if any tests require a configuration override - if [ ! -z "$DOCKER_TESTS_REQUIRING_CONFIG_OVERRIDE" ] || [ ! -z "$K8S_TESTS_REQUIRING_CONFIG_OVERRIDE" ]; then - echo "Tests in .github/e2e-tests.yml requiring test config override:" - if [ ! -z "$DOCKER_TESTS_REQUIRING_CONFIG_OVERRIDE" ]; then - echo $DOCKER_TESTS_REQUIRING_CONFIG_OVERRIDE - fi - if [ ! -z "$K8S_TESTS_REQUIRING_CONFIG_OVERRIDE" ]; then - echo $K8S_TESTS_REQUIRING_CONFIG_OVERRIDE - fi - echo "::error::Error: Some of the tests require a test config override. Please see workflow logs and set 'test_config_override_path' to run these tests." - exit 1 - else - echo "No tests require a configuration override. Proceeding without overrides." - fi - - name: Check if test secrets are required for any test shell: bash run: | @@ -514,6 +511,7 @@ jobs: echo "[${{ env.TEST_CONFIG_OVERRIDE_PATH }}]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/blob/${{ github.sha }}/${{ env.TEST_CONFIG_OVERRIDE_PATH }})" >> $GITHUB_STEP_SUMMARY - name: Show chainlink version in summary + if: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }} run: | echo "### Chainlink version" >> $GITHUB_STEP_SUMMARY echo "${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }}" >> $GITHUB_STEP_SUMMARY @@ -559,27 +557,26 @@ jobs: - name: Run tests id: run_tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@4f377a6b1cc07f0eca82745782736b4908a1da30 # v2.3.32 + uses: smartcontractkit/.github/actions/ctf-run-tests@b8731364b119e88983e94b0c4da87fc27ddb41b8 # ctf-run-tests@0.0.0 env: DETACH_RUNNER: true E2E_TEST_CHAINLINK_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }} E2E_TEST_CHAINLINK_UPGRADE_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_VERSION }} E2E_TEST_CHAINLINK_POSTGRES_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_POSTGRES_VERSION }} - E2E_TEST_SELECTED_NETWORK: ${{ matrix.tests.test_env_vars.E2E_TEST_SELECTED_NETWORK || env.SELECTED_NETWORKS }} + E2E_TEST_SELECTED_NETWORK: ${{ matrix.tests.test_env_vars.E2E_TEST_SELECTED_NETWORK }} E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} E2E_TEST_LOG_STREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} E2E_TEST_LOG_COLLECT: ${{ vars.TEST_LOG_COLLECT }} - E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - E2E_TEST_GRAFANA_DASHBOARD_URL: ${{ matrix.tests.test_env_vars.E2E_TEST_GRAFANA_DASHBOARD_URL }} + E2E_TEST_LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + E2E_TEST_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} + E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + E2E_TEST_GRAFANA_DASHBOARD_URL: ${{ matrix.tests.test_env_vars.E2E_TEST_GRAFANA_DASHBOARD_URL }} E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} E2E_TEST_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} E2E_TEST_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} E2E_TEST_PYROSCOPE_KEY: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_KEY || '' }} - E2E_TEST_PYROSCOPE_ENABLED: ${{ matrix.tests.pyroscope_env != '' && 'true' || '' }} with: - test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false + test_command_to_run: ${{ matrix.tests.test_cmd }} ${{ matrix.tests.test_cmd_opts || '2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false' }} test_download_vendor_packages_command: cd $(dirname ${{ matrix.tests.path }}) && go mod download test_secrets_override_base64: ${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }} test_config_override_path: ${{ env.TEST_CONFIG_OVERRIDE_PATH }} @@ -614,14 +611,14 @@ jobs: run: | ls -l ./integration-tests/smoke/traces - - name: Upload trace data as Github artifact + - name: Upload trace data as artifact if: inputs.enable_otel_traces_for_ocr2_plugins && matrix.tests.test_env_vars.ENABLE_OTEL_TRACES == 'true' uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: trace-data path: ./integration-tests/smoke/traces/trace-data.json - - name: Upload test log as Github artifact + - name: Upload test log as artifact uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 if: inputs.test_log_upload_on_failure && failure() with: @@ -630,7 +627,7 @@ jobs: retention-days: ${{ inputs.test_log_upload_retention_days }} continue-on-error: true - - name: Upload cl node coverage data as Github artifact + - name: Upload cl node coverage data as artifact if: inputs.upload_cl_node_coverage_artifact uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 timeout-minutes: 2 @@ -662,17 +659,16 @@ jobs: path: ${{ matrix.tests.test_artifacts_on_failure }} retention-days: 1 - - name: Print failed test summary + - name: Show Grafana url in test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@70ccaef155381025e411cf7cd1fa5ef8f668ed75 # v2.3.25 - + uses: smartcontractkit/.github/actions/ctf-show-grafana-in-test-summary@70fcaef0bf3a5a7d8aa681861d2f76e4188863d9 # ctf-show-grafana-in-test-summary@0.0.0 # Run K8s tests using old remote runner - prepare-remote-runner-test-image: - needs: [load-test-configurations, require-chainlink-image-versions-in-qa-ecr, require-chainlink-plugin-versions-in-qa-ecr] + get-remote-runner-test-image: + needs: [load-test-configurations] if: ${{ needs.load-test-configurations.outputs.run-k8s-tests == 'true' && always() && !failure() && !cancelled() }} - name: Prepare remote runner test image + name: Get remote runner test image runs-on: ubuntu-latest environment: integration permissions: @@ -690,12 +686,13 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Build Test Runner Image id: build-test-runner-image - uses: ./.github/actions/build-test-image + uses: smartcontractkit/.github/actions/ctf-build-test-image@a5e4f4c8fbb8e15ab2ad131552eca6ac83c4f4b3 # ctf-build-test-image@0.1.0 if: ${{ inputs.with_existing_remote_runner_version == '' }} with: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + suites: ${{ inputs.test_image_suites }} - name: Set Remote Runner Version id: set-remote-runner-version run: | @@ -708,7 +705,7 @@ jobs: fi run-k8s-runner-tests: - needs: [load-test-configurations, prepare-remote-runner-test-image, require-chainlink-image-versions-in-qa-ecr, require-chainlink-plugin-versions-in-qa-ecr, get_latest_chainlink_release_version] + needs: [load-test-configurations, get-remote-runner-test-image, require-chainlink-image-versions-in-qa-ecr, require-chainlink-plugin-versions-in-qa-ecr, get_latest_chainlink_release_version] if: ${{ needs.load-test-configurations.outputs.run-k8s-tests == 'true' && always() && !failure() && !cancelled() }} name: ${{ matrix.tests.id }} runs-on: ${{ matrix.tests.runs_on }} @@ -751,51 +748,51 @@ jobs: echo "[${{ env.TEST_CONFIG_OVERRIDE_PATH }}]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/blob/${{ github.sha }}/${{ env.TEST_CONFIG_OVERRIDE_PATH }})" >> $GITHUB_STEP_SUMMARY - name: Show chainlink version in summary + if: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }} run: | echo "### Chainlink version" >> $GITHUB_STEP_SUMMARY echo "${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }}" >> $GITHUB_STEP_SUMMARY - name: Show remote runner version in summary run: | - echo "Remote Runner Version: ${{ needs.prepare-remote-runner-test-image.outputs.remote-runner-version }}" + echo "Remote Runner Version: ${{ needs.get-remote-runner-test-image.outputs.remote-runner-version }}" echo "### Remote Runner Version" >> $GITHUB_STEP_SUMMARY - echo "${{ needs.prepare-remote-runner-test-image.outputs.remote-runner-version }}" >> $GITHUB_STEP_SUMMARY + echo "${{ needs.get-remote-runner-test-image.outputs.remote-runner-version }}" >> $GITHUB_STEP_SUMMARY - name: Show test configuration in logs run: echo '${{ toJson(matrix.tests) }}' | jq . - name: Run tests id: run_tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@4f377a6b1cc07f0eca82745782736b4908a1da30 # v2.3.32 + uses: smartcontractkit/.github/actions/ctf-run-tests@b8731364b119e88983e94b0c4da87fc27ddb41b8 # ctf-run-tests@0.0.0 env: DETACH_RUNNER: true RR_MEM: ${{ matrix.tests.remote_runner_memory }} TEST_ARGS: -test.timeout 900h -test.memprofile memprofile.out -test.cpuprofile profile.out - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ needs.prepare-remote-runner-test-image.outputs.remote-runner-version }} + ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ needs.get-remote-runner-test-image.outputs.remote-runner-version }} INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com # We can comment these out when we have a stable soak test and aren't worried about resource consumption - TEST_UPLOAD_CPU_PROFILE: true - TEST_UPLOAD_MEM_PROFILE: true + TEST_UPLOAD_CPU_PROFILE: ${{ matrix.tests.test_env_vars.TEST_UPLOAD_CPU_PROFILE }} + TEST_UPLOAD_MEM_PROFILE: ${{ matrix.tests.test_env_vars.TEST_UPLOAD_MEM_PROFILE }} REF_NAME: ${{ github.head_ref || github.ref_name }} E2E_TEST_CHAINLINK_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }} E2E_TEST_CHAINLINK_UPGRADE_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_VERSION }} E2E_TEST_CHAINLINK_POSTGRES_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_POSTGRES_VERSION }} - E2E_TEST_SELECTED_NETWORK: ${{ matrix.tests.test_env_vars.E2E_TEST_SELECTED_NETWORK || env.SELECTED_NETWORKS }} + E2E_TEST_SELECTED_NETWORK: ${{ matrix.tests.test_env_vars.E2E_TEST_SELECTED_NETWORK }} E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} E2E_TEST_LOG_STREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} E2E_TEST_LOG_COLLECT: ${{ vars.TEST_LOG_COLLECT }} - E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - E2E_TEST_GRAFANA_DASHBOARD_URL: ${{ matrix.tests.test_env_vars.E2E_TEST_GRAFANA_DASHBOARD_URL }} + E2E_TEST_LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + E2E_TEST_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} + E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + E2E_TEST_GRAFANA_DASHBOARD_URL: ${{ matrix.tests.test_env_vars.E2E_TEST_GRAFANA_DASHBOARD_URL }} E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} E2E_TEST_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} E2E_TEST_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} E2E_TEST_PYROSCOPE_KEY: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_KEY || '' }} - E2E_TEST_PYROSCOPE_ENABLED: ${{ matrix.tests.pyroscope_env != '' && 'true' || '' }} DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable with: - test_command_to_run: ${{ matrix.tests.test_cmd }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false + test_command_to_run: ${{ matrix.tests.test_cmd }} ${{ matrix.tests.test_cmd_opts || '2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false' }} test_download_vendor_packages_command: make gomod test_secrets_override_base64: ${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }} test_config_override_path: ${{ env.TEST_CONFIG_OVERRIDE_PATH }} @@ -811,7 +808,7 @@ jobs: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Upload test log as Github artifact + - name: Upload test log as artifact uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 if: inputs.test_log_upload_on_failure && failure() with: @@ -828,10 +825,9 @@ jobs: path: ${{ matrix.tests.test_artifacts_on_failure }} retention-days: 1 - # TODO: move to run-tests GHA - - name: Print failed test summary + - name: Show Grafana url in test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@70ccaef155381025e411cf7cd1fa5ef8f668ed75 # v2.3.25 + uses: smartcontractkit/.github/actions/ctf-show-grafana-in-test-summary@70fcaef0bf3a5a7d8aa681861d2f76e4188863d9 # ctf-show-grafana-in-test-summary@0.0.0 after_tests: needs: [load-test-configurations, run-docker-tests, run-k8s-runner-tests] @@ -866,6 +862,11 @@ jobs: echo "results=[]" >> $GITHUB_OUTPUT fi + - name: Set short SHA + id: set_short_sha + shell: bash + run: echo "short_sha=$(echo ${{ github.sha }} | cut -c1-7)" >> $GITHUB_OUTPUT + - name: Send Slack notification uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 if: ${{ inputs.slack_notification_after_tests == 'true' || inputs.slack_notification_after_tests == 'always' || (inputs.slack_notification_after_tests == 'on_failure' && contains(join(needs.*.result, ','), 'failure')) }} @@ -878,20 +879,20 @@ jobs: { "attachments": [ { - "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || contains(join(needs.*.result, ','), 'cancelled') && '#FFA000' || '2E7D32' }}", + "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || contains(join(needs.*.result, ','), 'cancelled') && '#FFA000' || contains(join(needs.*.result, ','), 'skipped') && '#FFA000' || '2E7D32' }}", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", - "text": "${{ inputs.slack_notification_after_tests_name }} - ${{ contains(join(needs.*.result, ','), 'failure') && 'Failed :x:' || contains(join(needs.*.result, ','), 'cancelled') && 'Cancelled :warning:' || 'Passed :white_check_mark:' }}" + "text": "${{ inputs.slack_notification_after_tests_name }} - ${{ contains(join(needs.*.result, ','), 'failure') && 'Failed :x:' || contains(join(needs.*.result, ','), 'cancelled') && 'Cancelled :warning:' || contains(join(needs.*.result, ','), 'skipped') && 'Skipped :warning:' || 'Passed :white_check_mark:' }}" } }, { "type": "section", "text": { "type": "mrkdwn", - "text": "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Build Details>" + "text": "${{ github.ref_name }} | <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ steps.set_short_sha.outputs.short_sha }}> | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Details>" } } ] diff --git a/.github/workflows/run-nightly-e2e-tests.yml b/.github/workflows/run-nightly-e2e-tests.yml index 6d7056ed04..151217180b 100644 --- a/.github/workflows/run-nightly-e2e-tests.yml +++ b/.github/workflows/run-nightly-e2e-tests.yml @@ -27,6 +27,9 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} diff --git a/.github/workflows/run-selected-e2e-tests.yml b/.github/workflows/run-selected-e2e-tests.yml index c204be6a56..2ff3fbb979 100644 --- a/.github/workflows/run-selected-e2e-tests.yml +++ b/.github/workflows/run-selected-e2e-tests.yml @@ -59,10 +59,12 @@ jobs: GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} TEST_SECRETS_OVERRIDE_BASE64: ${{ secrets[inputs.test_secrets_override_key] }} SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - diff --git a/integration-tests/scripts/buildTests b/integration-tests/scripts/buildTests index 04e9cea94b..b5e8fc3080 100755 --- a/integration-tests/scripts/buildTests +++ b/integration-tests/scripts/buildTests @@ -28,6 +28,7 @@ do elif [ "$x" = "ccip-load" ]; then echo "Changing directory and executing go test -c ./... for 'ccip-load' package" pushd "./ccip-tests/load" && go test -c -tags embed -o ../ ./... + mv ../load.test ../ccip-load.test # rename the binary to match the suite name popd else go test -c -tags embed ./"${x}" diff --git a/integration-tests/testconfig/automation/automation.toml b/integration-tests/testconfig/automation/automation.toml index f07136e998..b2e87fa34f 100644 --- a/integration-tests/testconfig/automation/automation.toml +++ b/integration-tests/testconfig/automation/automation.toml @@ -2,6 +2,9 @@ [Common] chainlink_node_funding = 2.0 +[Pyroscope] +enabled=false + [NodeConfig] BaseConfigTOML = """ [Feature] @@ -207,6 +210,10 @@ max_perform_data_size=5_000 max_revert_data_size=5_000 # load test specific overrides +[Load.Logging.Grafana] +base_url="https://grafana.ops.prod.cldev.sh" +dashboard_url="/d/a4899f53-f709-430a-aec2-24f32198dcc9/chainlink-automation-v2-load-test" + [Load.Seth] ephemeral_addresses_number = 100 root_key_funds_buffer = 1_000_000 @@ -301,6 +308,9 @@ max_revert_data_size=5_000 enabled=false # automation benchmark test specific overrides +[Benchmark.Logging.Grafana] +base_url="https://grafana.ops.prod.cldev.sh" +dashboard_url="/d/Q8n6m1unz/chainlink-automation-benchmark-test" # will retry roughly for 1h before giving up (900 * 4s) [Benchmark.Automation.Resiliency] @@ -420,6 +430,9 @@ max_perform_data_size=5_000 max_revert_data_size=5_000 # automation soak test specific overrides +[Soak.Logging.Grafana] +base_url="https://grafana.ops.prod.cldev.sh" +dashboard_url="/d/Q8n6m1unz/chainlink-automation-benchmark-test" # will retry roughly for 1h before giving up (900 * 4s) [Soak.Automation.Resiliency] diff --git a/integration-tests/testconfig/automation/example.toml b/integration-tests/testconfig/automation/example.toml index 3b48e89a54..3bbe78d693 100644 --- a/integration-tests/testconfig/automation/example.toml +++ b/integration-tests/testconfig/automation/example.toml @@ -1,7 +1,6 @@ # Example of full config with all fields # General part [ChainlinkImage] -image="public.ecr.aws/chainlink/chainlink" version="2.7.0" [Logging] @@ -16,38 +15,10 @@ log_producer_timeout="10s" # number of retries before log producer gives up and stops listening to logs log_producer_retry_limit=10 -[Logging.Loki] -tenant_id="tenant_id" -# full URL of Loki ingest endpoint -endpoint="https://loki.url/api/v3/push" -# currently only needed when using public instance -basic_auth_secret="loki-basic-auth" -# only needed for cloud grafana -bearer_token_secret="bearer_token" - -# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set) -[Logging.Grafana] -# grafana url (trailing "/" will be stripped) -base_url="http://grafana.url" -# url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard -dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model -dashboard_uid="dashboard-uid-to-annotate" -bearer_token_secret="my-awesome-token" - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] -[Network.RpcHttpUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.RpcWsUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.WalletKeys] -polygon_mumbai = ["change-me-to-your-PK"] - [PrivateEthereumNetwork] # pos or pow consensus_type="pos" @@ -163,5 +134,4 @@ use_prometheus=false # upgrade test specific override [TestAutomationNodeUpgrade.ChainlinkUpgradeImage] -image="public.ecr.aws/chainlink/chainlink" version="2.8.0" \ No newline at end of file diff --git a/integration-tests/testconfig/automation/overrides/benchmark/1000Upkeeps-1h-2_1.toml b/integration-tests/testconfig/automation/overrides/benchmark/1000Upkeeps-1h-2_1.toml new file mode 100644 index 0000000000..0b704524e9 --- /dev/null +++ b/integration-tests/testconfig/automation/overrides/benchmark/1000Upkeeps-1h-2_1.toml @@ -0,0 +1,15 @@ +[ChainlinkImage] +version="latest" + +[Benchmark.Automation.Benchmark] +registry_to_test = "2_1" +number_of_registries = 1 +number_of_nodes = 6 +number_of_upkeeps = 1000 +upkeep_gas_limit = 1500000 +check_gas_to_burn = 10000 +perform_gas_to_burn = 1000 +block_range = 3600 +block_interval = 60 +forces_single_tx_key = false +delete_jobs_on_end = true \ No newline at end of file diff --git a/integration-tests/testconfig/automation/overrides/benchmark/1000Upkeeps-1h-2_3.toml b/integration-tests/testconfig/automation/overrides/benchmark/1000Upkeeps-1h-2_3.toml new file mode 100644 index 0000000000..f00bb5ed47 --- /dev/null +++ b/integration-tests/testconfig/automation/overrides/benchmark/1000Upkeeps-1h-2_3.toml @@ -0,0 +1,15 @@ +[ChainlinkImage] +version="latest" + +[Benchmark.Automation.Benchmark] +registry_to_test = "2_3" +number_of_registries = 1 +number_of_nodes = 6 +number_of_upkeeps = 1000 +upkeep_gas_limit = 1500000 +check_gas_to_burn = 10000 +perform_gas_to_burn = 1000 +block_range = 3600 +block_interval = 60 +forces_single_tx_key = false +delete_jobs_on_end = true \ No newline at end of file diff --git a/integration-tests/testconfig/automation/overrides/load/500Upkeeps-1x-1h.toml b/integration-tests/testconfig/automation/overrides/load/500Upkeeps-1x-1h.toml new file mode 100644 index 0000000000..6d58253f52 --- /dev/null +++ b/integration-tests/testconfig/automation/overrides/load/500Upkeeps-1x-1h.toml @@ -0,0 +1,47 @@ +[ChainlinkImage] +version="latest" + +[Load.Seth] +root_key_funds_buffer = 1_000_000 +ephemeral_addresses_number = 300 + +[Load.Seth.nonce_manager] +key_sync_timeout = "100s" + +[Load.Common] +chainlink_node_funding = 1000 + +[Load.Automation.AutomationConfig] +use_log_buffer_v1=false + +[Load.Automation.AutomationConfig.PluginConfig.LogProviderConfig] +block_rate=1 +log_limit=2 + +[Load.Automation] +[Load.Automation.General] +number_of_nodes=6 +duration=3600 +block_time=1 +spec_type="recommended" +chainlink_node_log_level="debug" +use_prometheus=true +remove_namespace = true + +[Load.Automation.DataStreams] +enabled=false + +[[Load.Automation.Load]] +number_of_upkeeps=500 +number_of_events = 1 +number_of_spam_matching_events = 0 +number_of_spam_non_matching_events = 0 +check_burn_amount = 0 +perform_burn_amount = 0 +upkeep_gas_limit = 1000000 +shared_trigger = false +is_streams_lookup = false +feeds = [] + +[Pyroscope] +enabled=false \ No newline at end of file diff --git a/integration-tests/testconfig/automation/overrides/load/50Upkeeps-1x-12h.toml b/integration-tests/testconfig/automation/overrides/load/50Upkeeps-1x-12h.toml new file mode 100644 index 0000000000..8991a6eb90 --- /dev/null +++ b/integration-tests/testconfig/automation/overrides/load/50Upkeeps-1x-12h.toml @@ -0,0 +1,43 @@ +[ChainlinkImage] +version="latest" + +[Load.Seth] +root_key_funds_buffer = 1_000_000 + +[Load.Common] +chainlink_node_funding = 10000 + +[Load.Automation.AutomationConfig] +use_log_buffer_v1=false + +[Load.Automation.AutomationConfig.PluginConfig.LogProviderConfig] +block_rate=1 +log_limit=2 + +[Load.Automation] +[Load.Automation.General] +number_of_nodes=6 +duration=43200 +block_time=1 +spec_type="recommended" +chainlink_node_log_level="debug" +use_prometheus=true +remove_namespace = true + +[Load.Automation.DataStreams] +enabled=false + +[[Load.Automation.Load]] +number_of_upkeeps=50 +number_of_events = 1 +number_of_spam_matching_events = 0 +number_of_spam_non_matching_events = 0 +check_burn_amount = 0 +perform_burn_amount = 0 +upkeep_gas_limit = 1000000 +shared_trigger = false +is_streams_lookup = false +feeds = [] + +[Pyroscope] +enabled=false \ No newline at end of file diff --git a/integration-tests/testconfig/automation/overrides/load/50Upkeeps-1x-1h.toml b/integration-tests/testconfig/automation/overrides/load/50Upkeeps-1x-1h.toml new file mode 100644 index 0000000000..a133fce6dc --- /dev/null +++ b/integration-tests/testconfig/automation/overrides/load/50Upkeeps-1x-1h.toml @@ -0,0 +1,43 @@ +[ChainlinkImage] +version="latest" + +[Load.Seth] +root_key_funds_buffer = 1_000_000 + +[Load.Common] +chainlink_node_funding = 1000 + +[Load.Automation.AutomationConfig] +use_log_buffer_v1=false + +[Load.Automation.AutomationConfig.PluginConfig.LogProviderConfig] +block_rate=1 +log_limit=2 + +[Load.Automation] +[Load.Automation.General] +number_of_nodes=6 +duration=3600 +block_time=1 +spec_type="recommended" +chainlink_node_log_level="debug" +use_prometheus=true +remove_namespace = true + +[Load.Automation.DataStreams] +enabled=false + +[[Load.Automation.Load]] +number_of_upkeeps=50 +number_of_events = 1 +number_of_spam_matching_events = 0 +number_of_spam_non_matching_events = 0 +check_burn_amount = 0 +perform_burn_amount = 0 +upkeep_gas_limit = 1000000 +shared_trigger = false +is_streams_lookup = false +feeds = [] + +[Pyroscope] +enabled=false \ No newline at end of file diff --git a/integration-tests/testconfig/automation/overrides/soak/50Upkeeps-8h-2_1.toml b/integration-tests/testconfig/automation/overrides/soak/50Upkeeps-8h-2_1.toml new file mode 100644 index 0000000000..fda5cb6ea2 --- /dev/null +++ b/integration-tests/testconfig/automation/overrides/soak/50Upkeeps-8h-2_1.toml @@ -0,0 +1,15 @@ +[ChainlinkImage] +version="latest" + +[Soak.Automation.Benchmark] +registry_to_test = "2_1" +number_of_registries = 1 +number_of_nodes = 6 +number_of_upkeeps = 50 +upkeep_gas_limit = 1500000 +check_gas_to_burn = 10000 +perform_gas_to_burn = 1000 +block_range = 28800 +block_interval = 300 +forces_single_tx_key = false +delete_jobs_on_end = true \ No newline at end of file diff --git a/integration-tests/testconfig/automation/overrides/soak/50Upkeeps-8h-2_3.toml b/integration-tests/testconfig/automation/overrides/soak/50Upkeeps-8h-2_3.toml new file mode 100644 index 0000000000..46ba1ad3e8 --- /dev/null +++ b/integration-tests/testconfig/automation/overrides/soak/50Upkeeps-8h-2_3.toml @@ -0,0 +1,15 @@ +[ChainlinkImage] +version="latest" + +[Soak.Automation.Benchmark] +registry_to_test = "2_3" +number_of_registries = 1 +number_of_nodes = 6 +number_of_upkeeps = 50 +upkeep_gas_limit = 1500000 +check_gas_to_burn = 10000 +perform_gas_to_burn = 1000 +block_range = 28800 +block_interval = 300 +forces_single_tx_key = false +delete_jobs_on_end = true \ No newline at end of file diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index 1d84b1d028..496a11b64b 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -259,66 +259,14 @@ gas_tip_cap = 1_800_000_000 [[Seth.networks]] name = "Sepolia Testnet" transaction_timeout = "3m" -eip_1559_dynamic_fees = false - -# automated gas estimation for live networks -# if set to true we will dynamically estimate gas for every transaction (based on suggested values, priority and congestion rate for last X blocks) -# gas_price_estimation_enabled = true -# number of blocks to use for congestion rate estimation (it will determine buffer added on top of suggested values) -# gas_price_estimation_blocks = 100 -# transaction priority, which determines adjustment factor multiplier applied to suggested values (fast - 1.2x, standard - 1x, slow - 0.8x) -# gas_price_estimation_tx_priority = "standard" - -# URLs -# if set they will overwrite URLs from EVMNetwork that Seth uses, can be either WS(S) or HTTP(S) -# urls_secret = ["ws://your-ws-url:8546"] - -# gas_limits -# gas limit should be explicitly set only if you are connecting to a node that's incapable of estimating gas limit itself (should only happen for very old versions) -# gas_limit = 14_000_000 -# transfer_gas_fee is gas limit that will be used, when funding CL nodes and returning funds from there and when funding and returning funds from ephemeral keys -# we use hardcoded value in order to be estimate how much funds are available for sending or returning after tx costs have been paid -transfer_gas_fee = 21_000 - -# manual settings, used when gas_price_estimation_enabled is false or when it fails -# legacy transactions -gas_price = 50_000_000_000 - -# EIP-1559 transactions -gas_fee_cap = 45_000_000_000 -gas_tip_cap = 10_000_000_000 - -[[Seth.networks]] -name = "Polygon Mumbai" -transaction_timeout = "3m" eip_1559_dynamic_fees = true - -# automated gas estimation for live networks -# if set to true we will dynamically estimate gas for every transaction (based on suggested values, priority and congestion rate for last X blocks) -# gas_price_estimation_enabled = true -# number of blocks to use for congestion rate estimation (it will determine buffer added on top of suggested values) -# gas_price_estimation_blocks = 100 -# transaction priority, which determines adjustment factor multiplier applied to suggested values (fast - 1.2x, standard - 1x, slow - 0.8x) -# gas_price_estimation_tx_priority = "standard" - -# URLs -# if set they will overwrite URLs from EVMNetwork that Seth uses, can be either WS(S) or HTTP(S) -# urls_secret = ["ws://your-ws-url:8546"] - -# gas_limits -# gas limit should be explicitly set only if you are connecting to a node that's incapable of estimating gas limit itself (should only happen for very old versions) -# gas_limit = 6_000_000 -# transfer_gas_fee is gas limit that will be used, when funding CL nodes and returning funds from there and when funding and returning funds from ephemeral keys -# we use hardcoded value in order to be estimate how much funds are available for sending or returning after tx costs have been paid transfer_gas_fee = 21_000 - -# manual settings, used when gas_price_estimation_enabled is false or when it fails -# legacy transactions -gas_price = 1_800_000_000 - -# EIP-1559 transactions -gas_fee_cap = 3_800_000_000 -gas_tip_cap = 1_800_000_000 +gas_price = 105_000_000_000 +gas_fee_cap = 150_312_843_059 +gas_tip_cap = 40_416_094 +gas_price_estimation_enabled = true +gas_price_estimation_blocks = 1000 +gas_price_estimation_tx_priority = "standard" [[Seth.networks]] name = "Polygon Amoy" @@ -352,38 +300,6 @@ gas_price = 200_000_000_000 gas_fee_cap = 200_000_000_000 gas_tip_cap = 25_000_000_000 -[[Seth.networks]] -name = "Polygon zkEVM Goerli" -transaction_timeout = "3m" -eip_1559_dynamic_fees = false - -# automated gas estimation for live networks -# if set to true we will dynamically estimate gas for every transaction (based on suggested values, priority and congestion rate for last X blocks) -# gas_price_estimation_enabled = true -# number of blocks to use for congestion rate estimation (it will determine buffer added on top of suggested values) -# gas_price_estimation_blocks = 100 -# transaction priority, which determines adjustment factor multiplier applied to suggested values (fast - 1.2x, standard - 1x, slow - 0.8x) -# gas_price_estimation_tx_priority = "standard" - -# URLs -# if set they will overwrite URLs from EVMNetwork that Seth uses, can be either WS(S) or HTTP(S) -# urls_secret = ["ws://your-ws-url:8546"] - -# gas_limits -# gas limit should be explicitly set only if you are connecting to a node that's incapable of estimating gas limit itself (should only happen for very old versions) -# gas_limit = 9_000_000 -# transfer_gas_fee is gas limit that will be used, when funding CL nodes and returning funds from there and when funding and returning funds from ephemeral keys -# we use hardcoded value in order to be estimate how much funds are available for sending or returning after tx costs have been paid -transfer_gas_fee = 21_000 - -# manual settings, used when gas_price_estimation_enabled is false or when it fails -# legacy transactions -gas_price = 50_000_000 - -# EIP-1559 transactions -gas_fee_cap = 3_800_000_000 -gas_tip_cap = 1_800_000_000 - [[Seth.networks]] name = "Optimism Sepolia" transaction_timeout = "3m" @@ -686,7 +602,6 @@ gas_price_estimation_tx_priority = "standard" [[Seth.networks]] name = "TREASURE_RUBY" -chain_id = "978657" transaction_timeout = "10m" transfer_gas_fee = 21_000 gas_price = 100_000_000 @@ -699,7 +614,6 @@ gas_price_estimation_tx_priority = "standard" [[Seth.networks]] name = "XLAYER_MAINNET" -chain_id = "196" transaction_timeout = "10m" transfer_gas_fee = 21_000 gas_price = 13_400_000_000 @@ -712,7 +626,6 @@ gas_price_estimation_tx_priority = "standard" [[Seth.networks]] name = "XLAYER_SEPOLIA" -chain_id = "195" transaction_timeout = "10m" transfer_gas_fee = 21_000 gas_price = 200_000_000_000 @@ -723,6 +636,28 @@ gas_price_estimation_enabled = true gas_price_estimation_blocks = 500 gas_price_estimation_tx_priority = "standard" +[[Seth.networks]] +name = "POLYGON_MAINNET" +transaction_timeout = "3m" +transfer_gas_fee = 21_000 +gas_price = 31_000_000_000 +eip_1559_dynamic_fees = true +gas_fee_cap = 61_000_000_000 +gas_tip_cap = 30_000_000_000 +gas_price_estimation_enabled = true +gas_price_estimation_blocks = 1000 + +[[Seth.networks]] +name = "ARBITRUM_MAINNET" +transaction_timeout = "10m" +transfer_gas_fee = 21_000 +gas_price = 10_000_000 +eip_1559_dynamic_fees = true +gas_fee_cap = 10_000_000 +gas_tip_cap = 0 +gas_price_estimation_enabled = true +gas_price_estimation_blocks = 1000 + #### [Network.EVMNetworks.SONEIUM_SEPOLIA] @@ -731,4 +666,4 @@ evm_chain_id = 1946 client_implementation = "Optimism" evm_simulated = false -#### \ No newline at end of file +#### diff --git a/integration-tests/testconfig/forwarder_ocr/example.toml b/integration-tests/testconfig/forwarder_ocr/example.toml index 75143d7b77..517a341f80 100644 --- a/integration-tests/testconfig/forwarder_ocr/example.toml +++ b/integration-tests/testconfig/forwarder_ocr/example.toml @@ -1,7 +1,6 @@ # Example of full config with all fields # General part [ChainlinkImage] -image="public.ecr.aws/chainlink/chainlink" version="2.7.0" [Logging] @@ -39,15 +38,6 @@ bearer_token_secret="my-awesome-token" [Network] selected_networks=["polygon_mumbai"] -[Network.RpcHttpUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.RpcWsUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.WalletKeys] -polygon_mumbai = ["change-me-to-your-PK"] - [PrivateEthereumNetwork] # pos or pow consensus_type="pos" diff --git a/integration-tests/testconfig/forwarder_ocr2/example.toml b/integration-tests/testconfig/forwarder_ocr2/example.toml index 4941c49a98..3ec3e4c690 100644 --- a/integration-tests/testconfig/forwarder_ocr2/example.toml +++ b/integration-tests/testconfig/forwarder_ocr2/example.toml @@ -39,15 +39,6 @@ bearer_token_secret="my-awesome-token" [Network] selected_networks=["polygon_mumbai"] -[Network.RpcHttpUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.RpcWsUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.WalletKeys] -polygon_mumbai = ["change-me-to-your-PK"] - [PrivateEthereumNetwork] # pos or pow consensus_type="pos" diff --git a/integration-tests/testconfig/functions/example.toml b/integration-tests/testconfig/functions/example.toml index 7502a6fc44..74d931632a 100644 --- a/integration-tests/testconfig/functions/example.toml +++ b/integration-tests/testconfig/functions/example.toml @@ -1,7 +1,6 @@ # Example of full config with all fields # General part [ChainlinkImage] -image="public.ecr.aws/chainlink/chainlink" version="2.7.0" [Logging] @@ -16,38 +15,10 @@ log_producer_timeout="10s" # number of retries before log producer gives up and stops listening to logs log_producer_retry_limit=10 -[Logging.Loki] -tenant_id="tenant_id" -# full URL of Loki ingest endpoint -endpoint="https://loki.url/api/v3/push" -# currently only needed when using public instance -basic_auth_secret="loki-basic-auth" -# only needed for cloud grafana -bearer_token_secret="bearer_token" - -# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set) -[Logging.Grafana] -# grafana url (trailing "/" will be stripped) -base_url="http://grafana.url" -# url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard -dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model -dashboard_uid="dashboard-uid-to-annotate" -bearer_token_secret="my-awesome-token" - # if you want to use simulated network [Network] selected_networks=["polygon_mumbai"] -[Network.RpcHttpUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.RpcWsUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.WalletKeys] -polygon_mumbai = ["change-me-to-your-PK"] - [PrivateEthereumNetwork] # pos or pow consensus_type="pos" diff --git a/integration-tests/testconfig/keeper/example.toml b/integration-tests/testconfig/keeper/example.toml index 5abb583562..4efbf97482 100644 --- a/integration-tests/testconfig/keeper/example.toml +++ b/integration-tests/testconfig/keeper/example.toml @@ -1,7 +1,6 @@ # Example of full config with all fields # General part [ChainlinkImage] -image="public.ecr.aws/chainlink/chainlink" version="2.7.0" [Logging] @@ -16,38 +15,10 @@ log_producer_timeout="10s" # number of retries before log producer gives up and stops listening to logs log_producer_retry_limit=10 -[Logging.Loki] -tenant_id="tenant_id" -# full URL of Loki ingest endpoint -endpoint="https://loki.url/api/v3/push" -# currently only needed when using public instance -basic_auth_secret="loki-basic-auth" -# only needed for cloud grafana -bearer_token_secret="bearer_token" - -# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set) -[Logging.Grafana] -# grafana url (trailing "/" will be stripped) -base_url="http://grafana.url" -# url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard -dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model -dashboard_uid="dashboard-uid-to-annotate" -bearer_token_secret="my-awesome-token" - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] -[Network.RpcHttpUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.RpcWsUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.WalletKeys] -polygon_mumbai = ["change-me-to-your-PK"] - [PrivateEthereumNetwork] # pos or pow consensus_type="pos" diff --git a/integration-tests/testconfig/keeper/keeper.toml b/integration-tests/testconfig/keeper/keeper.toml index b4f544165a..d483d6df49 100644 --- a/integration-tests/testconfig/keeper/keeper.toml +++ b/integration-tests/testconfig/keeper/keeper.toml @@ -32,4 +32,4 @@ HTTPSPort = 0 [Keeper] TurnLookBack = 0 -""" +""" \ No newline at end of file diff --git a/integration-tests/testconfig/log_poller/example.toml b/integration-tests/testconfig/log_poller/example.toml index c28d36ae12..78f3b5482d 100644 --- a/integration-tests/testconfig/log_poller/example.toml +++ b/integration-tests/testconfig/log_poller/example.toml @@ -1,7 +1,6 @@ # Example of full config with all fields # General part [ChainlinkImage] -image="public.ecr.aws/chainlink/chainlink" version="2.7.0" [Logging] @@ -16,38 +15,10 @@ log_producer_timeout="10s" # number of retries before log producer gives up and stops listening to logs log_producer_retry_limit=10 -[Logging.Loki] -tenant_id="tenant_id" -# full URL of Loki ingest endpoint -endpoint="https://loki.url/api/v3/push" -# currently only needed when using public instance -basic_auth_secret="loki-basic-auth" -# only needed for cloud grafana -bearer_token_secret="bearer_token" - -# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set) -[Logging.Grafana] -# grafana url (trailing "/" will be stripped) -base_url="http://grafana.url" -# url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard -dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model -dashboard_uid="dashboard-uid-to-annotate" -bearer_token_secret="my-awesome-token" - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] -[Network.RpcHttpUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.RpcWsUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.WalletKeys] -polygon_mumbai = ["change-me-to-your-PK"] - [PrivateEthereumNetwork] # pos or pow consensus_type="pos" diff --git a/integration-tests/testconfig/node/example.toml b/integration-tests/testconfig/node/example.toml index 510379b4f0..bc5628e46b 100644 --- a/integration-tests/testconfig/node/example.toml +++ b/integration-tests/testconfig/node/example.toml @@ -1,7 +1,6 @@ # Example of full config with all fields # General part [ChainlinkImage] -image="public.ecr.aws/chainlink/chainlink" version="2.7.0" [Logging] @@ -16,38 +15,10 @@ log_producer_timeout="10s" # number of retries before log producer gives up and stops listening to logs log_producer_retry_limit=10 -[Logging.Loki] -tenant_id="tenant_id" -# full URL of Loki ingest endpoint -endpoint="https://loki.url/api/v3/push" -# currently only needed when using public instance -basic_auth_secret="loki-basic-auth" -# only needed for cloud grafana -bearer_token_secret="bearer_token" - -# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set) -[Logging.Grafana] -# grafana url (trailing "/" will be stripped) -base_url="http://grafana.url" -# url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard -dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model -dashboard_uid="dashboard-uid-to-annotate" -bearer_token_secret="my-awesome-token" - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] -[Network.RpcHttpUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.RpcWsUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.WalletKeys] -polygon_mumbai = ["change-me-to-your-PK"] - [PrivateEthereumNetwork] # pos or pow consensus_type="pos" @@ -77,5 +48,4 @@ chainlink_node_funding = 0.5 # Test-specific part [ChainlinkUpgradeImage] -image="public.ecr.aws/chainlink/chainlink" version="2.8.0" \ No newline at end of file diff --git a/integration-tests/testconfig/ocr/example.toml b/integration-tests/testconfig/ocr/example.toml index 26f0dd5a84..7c1c755567 100644 --- a/integration-tests/testconfig/ocr/example.toml +++ b/integration-tests/testconfig/ocr/example.toml @@ -1,7 +1,6 @@ # Example of full config with all fields # General part [ChainlinkImage] -image="public.ecr.aws/chainlink/chainlink" version="2.7.0" [Logging] @@ -39,15 +38,6 @@ bearer_token_secret="my-awesome-token" [Network] selected_networks=["polygon_mumbai"] -[Network.RpcHttpUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.RpcWsUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.WalletKeys] -polygon_mumbai = ["change-me-to-your-PK"] - [PrivateEthereumNetwork] # pos or pow consensus_type="pos" diff --git a/integration-tests/testconfig/ocr/overrides/arbitrum_mainnet.toml b/integration-tests/testconfig/ocr/overrides/arbitrum_mainnet.toml new file mode 100644 index 0000000000..953d9f351a --- /dev/null +++ b/integration-tests/testconfig/ocr/overrides/arbitrum_mainnet.toml @@ -0,0 +1,18 @@ +[Network] +selected_networks = ["ARBITRUM_MAINNET"] + +[Soak.Common] +chainlink_node_funding = 0.1 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration = "24h" + +[Soak.OCR.Soak] +time_between_rounds = "10m" + +[OCR.Common] +number_of_contracts = 2 + +[Seth] +experiments_enabled = ["slow_funds_return"] diff --git a/integration-tests/testconfig/ocr/overrides/arbitrum_sepolia.toml b/integration-tests/testconfig/ocr/overrides/arbitrum_sepolia.toml new file mode 100644 index 0000000000..1428e50b0e --- /dev/null +++ b/integration-tests/testconfig/ocr/overrides/arbitrum_sepolia.toml @@ -0,0 +1,15 @@ +[Network] +selected_networks = ["ARBITRUM_SEPOLIA"] + +[Soak.Common] +chainlink_node_funding = 1 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration = "24h" + +[Soak.OCR.Soak] +time_between_rounds = "2m" + +[OCR.Common] +number_of_contracts = 2 diff --git a/integration-tests/testconfig/ocr/overrides/base_mainnet.toml b/integration-tests/testconfig/ocr/overrides/base_mainnet.toml new file mode 100644 index 0000000000..a285c23758 --- /dev/null +++ b/integration-tests/testconfig/ocr/overrides/base_mainnet.toml @@ -0,0 +1,18 @@ +[Network] +selected_networks = ["BASE_MAINNET"] + +[Soak.Common] +chainlink_node_funding = 5 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration = "24h" + +[Soak.OCR.Soak] +time_between_rounds = "10m" + +[OCR.Common] +number_of_contracts = 2 + +[Seth] +experiments_enabled = ["slow_funds_return"] diff --git a/integration-tests/testconfig/ocr/overrides/base_sepolia.toml b/integration-tests/testconfig/ocr/overrides/base_sepolia.toml new file mode 100644 index 0000000000..3dbbadcbef --- /dev/null +++ b/integration-tests/testconfig/ocr/overrides/base_sepolia.toml @@ -0,0 +1,15 @@ +[Network] +selected_networks = ["BASE_SEPOLIA"] + +[Soak.Common] +chainlink_node_funding = 1 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration = "24h" + +[Soak.OCR.Soak] +time_between_rounds = "2m" + +[OCR.Common] +number_of_contracts = 2 diff --git a/integration-tests/testconfig/ocr/overrides/celo_alfajores.toml b/integration-tests/testconfig/ocr/overrides/celo_alfajores.toml new file mode 100644 index 0000000000..37c4a8cf16 --- /dev/null +++ b/integration-tests/testconfig/ocr/overrides/celo_alfajores.toml @@ -0,0 +1,15 @@ +[Network] +selected_networks = ["CELO_ALFAJORES"] + +[Soak.Common] +chainlink_node_funding = 10 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration = "24h" + +[Soak.OCR.Soak] +time_between_rounds = "2m" + +[OCR.Common] +number_of_contracts = 2 diff --git a/integration-tests/testconfig/ocr/overrides/ethereum_sepolia.toml b/integration-tests/testconfig/ocr/overrides/ethereum_sepolia.toml new file mode 100644 index 0000000000..612e47506a --- /dev/null +++ b/integration-tests/testconfig/ocr/overrides/ethereum_sepolia.toml @@ -0,0 +1,15 @@ +[Network] +selected_networks = ["SEPOLIA"] + +[Soak.Common] +chainlink_node_funding = 1 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration = "24h" + +[Soak.OCR.Soak] +time_between_rounds = "2m" + +[OCR.Common] +number_of_contracts = 2 diff --git a/integration-tests/testconfig/ocr/overrides/linea_sepolia.toml b/integration-tests/testconfig/ocr/overrides/linea_sepolia.toml new file mode 100644 index 0000000000..6fa6218d54 --- /dev/null +++ b/integration-tests/testconfig/ocr/overrides/linea_sepolia.toml @@ -0,0 +1,15 @@ +[Network] +selected_networks = ["Linea_Sepolia"] + +[Soak.Common] +chainlink_node_funding = 1 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration = "24h" + +[Soak.OCR.Soak] +time_between_rounds = "2m" + +[OCR.Common] +number_of_contracts = 2 diff --git a/integration-tests/testconfig/ocr/overrides/optimism_mainnet.toml b/integration-tests/testconfig/ocr/overrides/optimism_mainnet.toml new file mode 100644 index 0000000000..eec0640baa --- /dev/null +++ b/integration-tests/testconfig/ocr/overrides/optimism_mainnet.toml @@ -0,0 +1,18 @@ +[Network] +selected_networks = ["OPTIMISM_MAINNET"] + +[Soak.Common] +chainlink_node_funding = 0.1 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration = "24h" + +[Soak.OCR.Soak] +time_between_rounds = "10m" + +[OCR.Common] +number_of_contracts = 2 + +[Seth] +experiments_enabled = ["slow_funds_return"] diff --git a/integration-tests/testconfig/ocr/overrides/optimism_sepolia.toml b/integration-tests/testconfig/ocr/overrides/optimism_sepolia.toml new file mode 100644 index 0000000000..fe666b6aa9 --- /dev/null +++ b/integration-tests/testconfig/ocr/overrides/optimism_sepolia.toml @@ -0,0 +1,15 @@ +[Network] +selected_networks = ["OPTIMISM_SEPOLIA"] + +[Soak.Common] +chainlink_node_funding = 1 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration = "24h" + +[Soak.OCR.Soak] +time_between_rounds = "2m" + +[OCR.Common] +number_of_contracts = 2 diff --git a/integration-tests/testconfig/ocr/overrides/scroll_sepolia.toml b/integration-tests/testconfig/ocr/overrides/scroll_sepolia.toml new file mode 100644 index 0000000000..0beedfd05e --- /dev/null +++ b/integration-tests/testconfig/ocr/overrides/scroll_sepolia.toml @@ -0,0 +1,15 @@ +[Network] +selected_networks = ["SCROLL_SEPOLIA"] + +[Soak.Common] +chainlink_node_funding = 1 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration = "24h" + +[Soak.OCR.Soak] +time_between_rounds = "2m" + +[OCR.Common] +number_of_contracts = 2 diff --git a/integration-tests/testconfig/ocr/overrides/wemix_mainnet.toml b/integration-tests/testconfig/ocr/overrides/wemix_mainnet.toml new file mode 100644 index 0000000000..4a7859db3c --- /dev/null +++ b/integration-tests/testconfig/ocr/overrides/wemix_mainnet.toml @@ -0,0 +1,18 @@ +[Network] +selected_networks = ["WEMIX_MAINNET"] + +[Soak.Common] +chainlink_node_funding = 5 + +[Soak.OCR] +[Soak.OCR.Common] +test_duration = "24h" + +[Soak.OCR.Soak] +time_between_rounds = "10m" + +[OCR.Common] +number_of_contracts = 2 + +[Seth] +experiments_enabled = ["slow_funds_return"] diff --git a/integration-tests/testconfig/ocr2/example.toml b/integration-tests/testconfig/ocr2/example.toml index 624c3b7775..319f64d258 100644 --- a/integration-tests/testconfig/ocr2/example.toml +++ b/integration-tests/testconfig/ocr2/example.toml @@ -1,7 +1,6 @@ # Example of full config with all fields # General part [ChainlinkImage] -image="public.ecr.aws/chainlink/chainlink" version="2.7.0" [Logging] @@ -39,15 +38,6 @@ bearer_token_secret="my-awesome-token" [Network] selected_networks=["polygon_mumbai"] -[Network.RpcHttpUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.RpcWsUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.WalletKeys] -polygon_mumbai = ["change-me-to-your-PK"] - [PrivateEthereumNetwork] # pos or pow consensus_type="pos" diff --git a/integration-tests/testconfig/ocr2/overrides/base_sepolia.toml b/integration-tests/testconfig/ocr2/overrides/base_sepolia.toml new file mode 100644 index 0000000000..76e4fc4722 --- /dev/null +++ b/integration-tests/testconfig/ocr2/overrides/base_sepolia.toml @@ -0,0 +1,18 @@ +[Network] +selected_networks = ["BASE_SEPOLIA"] + +[Soak.Common] +chainlink_node_funding = 1 + +[Soak.OCR2] +[Soak.OCR2.Common] +test_duration = "24h" + +[Soak.OCR2.Soak] +time_between_rounds = "2m" + +[OCR2.Common] +number_of_contracts = 2 + +[Seth] +experiments_enabled = ["slow_funds_return"] diff --git a/integration-tests/testconfig/ocr2/overrides/ethereum_sepolia.toml b/integration-tests/testconfig/ocr2/overrides/ethereum_sepolia.toml new file mode 100644 index 0000000000..f7e0240780 --- /dev/null +++ b/integration-tests/testconfig/ocr2/overrides/ethereum_sepolia.toml @@ -0,0 +1,15 @@ +[Network] +selected_networks = ["SEPOLIA"] + +[Soak.Common] +chainlink_node_funding = 1 + +[Soak.OCR2] +[Soak.OCR2.Common] +test_duration = "24h" + +[Soak.OCR2.Soak] +time_between_rounds = "2m" + +[OCR2.Common] +number_of_contracts = 2 diff --git a/integration-tests/testconfig/ocr2/overrides/polygon_amoy.toml b/integration-tests/testconfig/ocr2/overrides/polygon_amoy.toml new file mode 100644 index 0000000000..41a31897c5 --- /dev/null +++ b/integration-tests/testconfig/ocr2/overrides/polygon_amoy.toml @@ -0,0 +1,15 @@ +[Network] +selected_networks = ["POLYGON_AMOY"] + +[Soak.Common] +chainlink_node_funding = 20 + +[Soak.OCR2] +[Soak.OCR2.Common] +test_duration = "24h" + +[Soak.OCR2.Soak] +time_between_rounds = "2m" + +[OCR2.Common] +number_of_contracts = 2 diff --git a/integration-tests/testconfig/ocr2/overrides/polygon_mainnet.toml b/integration-tests/testconfig/ocr2/overrides/polygon_mainnet.toml new file mode 100644 index 0000000000..51da279313 --- /dev/null +++ b/integration-tests/testconfig/ocr2/overrides/polygon_mainnet.toml @@ -0,0 +1,18 @@ +[Network] +selected_networks = ["POLYGON_MAINNET"] + +[Soak.Common] +chainlink_node_funding = 5 + +[Soak.OCR2] +[Soak.OCR2.Common] +test_duration = "24h" + +[Soak.OCR2.Soak] +time_between_rounds = "10m" + +[OCR2.Common] +number_of_contracts = 2 + +[Seth] +experiments_enabled = ["slow_funds_return"] diff --git a/integration-tests/testconfig/ocr2/overrides/wemix_testnet.toml b/integration-tests/testconfig/ocr2/overrides/wemix_testnet.toml new file mode 100644 index 0000000000..82bc06c17e --- /dev/null +++ b/integration-tests/testconfig/ocr2/overrides/wemix_testnet.toml @@ -0,0 +1,15 @@ +[Network] +selected_networks = ["WEMIX_TESTNET"] + +[Soak.Common] +chainlink_node_funding = 10 + +[Soak.OCR2] +[Soak.OCR2.Common] +test_duration = "24h" + +[Soak.OCR2.Soak] +time_between_rounds = "2m" + +[OCR2.Common] +number_of_contracts = 2 diff --git a/integration-tests/testconfig/ocr2/overrides/xlayer_sepolia.toml b/integration-tests/testconfig/ocr2/overrides/xlayer_sepolia.toml new file mode 100644 index 0000000000..d58098c5b0 --- /dev/null +++ b/integration-tests/testconfig/ocr2/overrides/xlayer_sepolia.toml @@ -0,0 +1,15 @@ +[Network] +selected_networks = ["xlayer_sepolia"] + +[Soak.Common] +chainlink_node_funding = 1 + +[Soak.OCR2] +[Soak.OCR2.Common] +test_duration = "24h" + +[Soak.OCR2.Soak] +time_between_rounds = "2m" + +[OCR2.Common] +number_of_contracts = 2 diff --git a/integration-tests/testconfig/vrfv2/example.toml b/integration-tests/testconfig/vrfv2/example.toml index 9417a422cf..13af6dee62 100644 --- a/integration-tests/testconfig/vrfv2/example.toml +++ b/integration-tests/testconfig/vrfv2/example.toml @@ -1,7 +1,6 @@ # Example of full config with all fields # General part [ChainlinkImage] -image="public.ecr.aws/chainlink/chainlink" version="2.7.0" [Logging] @@ -16,38 +15,10 @@ log_producer_timeout="10s" # number of retries before log producer gives up and stops listening to logs log_producer_retry_limit=10 -[Logging.Loki] -tenant_id="tenant_id" -# full URL of Loki ingest endpoint -endpoint="https://loki.url/api/v3/push" -# currently only needed when using public instance -basic_auth_secret="loki-basic-auth" -# only needed for cloud grafana -bearer_token_secret="bearer_token" - -# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set) -[Logging.Grafana] -# grafana url (trailing "/" will be stripped) -base_url="http://grafana.url" -# url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard -dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model -dashboard_uid="dashboard-uid-to-annotate" -bearer_token_secret="my-awesome-token" - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] -[Network.RpcHttpUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.RpcWsUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.WalletKeys] -polygon_mumbai = ["change-me-to-your-PK"] - [PrivateEthereumNetwork] # pos or pow consensus_type="pos" diff --git a/integration-tests/testconfig/vrfv2plus/example.toml b/integration-tests/testconfig/vrfv2plus/example.toml index d6e7a3f28d..160e9ba03a 100644 --- a/integration-tests/testconfig/vrfv2plus/example.toml +++ b/integration-tests/testconfig/vrfv2plus/example.toml @@ -1,7 +1,6 @@ # Example of full config with all fields # General part [ChainlinkImage] -image="public.ecr.aws/chainlink/chainlink" version="2.7.0" [Logging] @@ -16,38 +15,10 @@ log_producer_timeout="10s" # number of retries before log producer gives up and stops listening to logs log_producer_retry_limit=10 -[Logging.Loki] -tenant_id="tenant_id" -# full URL of Loki ingest endpoint -endpoint="https://loki.url/api/v3/push" -# currently only needed when using public instance -basic_auth_secret="loki-basic-auth" -# only needed for cloud grafana -bearer_token_secret="bearer_token" - -# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set) -[Logging.Grafana] -# grafana url (trailing "/" will be stripped) -base_url="http://grafana.url" -# url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard -dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model -dashboard_uid="dashboard-uid-to-annotate" -bearer_token_secret="my-awesome-token" - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] -[Network.RpcHttpUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.RpcWsUrls] -polygon_mumbai = ["https://my-rpc-endpoint.io"] - -[Network.WalletKeys] -polygon_mumbai = ["change-me-to-your-PK"] - [PrivateEthereumNetwork] # pos or pow consensus_type="pos" From 0799e6eddabd7717aad3624622dbe4054f03cacc Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:42:12 +0200 Subject: [PATCH 401/432] Bump CTF (#14518) --- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 5ea0f78f6b..8387c80782 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -42,7 +42,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 - github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.7 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index bdc7ebb362..effab5e3da 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1439,8 +1439,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202409 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6 h1:Pzr5VAMdI2CjFftodGkilMTFlIjCHJ7oqWAD7aZvFeI= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.7 h1:IzDNN3YvQL0yAFLj7fDJqGUDR76ewGhVJx5RiovKDI4= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.7/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index e9e5c6ee4e..46824e50fb 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 - github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.7 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 96f1ed8aea..eb4f92d14e 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1413,8 +1413,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202409 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6 h1:Pzr5VAMdI2CjFftodGkilMTFlIjCHJ7oqWAD7aZvFeI= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.6/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.7 h1:IzDNN3YvQL0yAFLj7fDJqGUDR76ewGhVJx5RiovKDI4= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.7/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= From 5acca3719ecd7a3189db3a8a8d09418ed8423016 Mon Sep 17 00:00:00 2001 From: Joe Huang Date: Mon, 23 Sep 2024 04:58:44 -0500 Subject: [PATCH 402/432] support new heads polling over http rpc client (#14373) * add functions for newHead polling * add new flag, NewHeadsPollInterval * fix test * fix test * step for adding polling new head impelmentation and sync+outOfSync loop handling logic. To add unit test * fix lint * add unit test * update changeset * update comments * simplify step 1, need to fix test * remove tests, no longer needed * fix lint * fix mock * fix simulated client * update interface * rm more * temp update for testing log level * temp update * revert modification to polygon toml * enable heap monitoring * enable for testing * revert * Dmytro's comments * make func private * fix test * add polling support for SubscribeNewHeaddocke * update log level --- .changeset/happy-feet-rhyme.md | 11 +++ common/client/node.go | 1 + common/client/node_test.go | 5 ++ core/chains/evm/client/config_builder.go | 3 +- core/chains/evm/client/config_builder_test.go | 5 +- core/chains/evm/client/evm_client.go | 4 +- core/chains/evm/client/evm_client_test.go | 4 +- core/chains/evm/client/helpers_test.go | 9 ++- core/chains/evm/client/rpc_client.go | 32 +++++++++ core/chains/evm/client/rpc_client_test.go | 22 +++--- .../evm/config/chain_scoped_node_pool.go | 4 ++ core/chains/evm/config/config.go | 1 + core/chains/evm/config/toml/config.go | 6 ++ .../evm/config/toml/defaults/fallback.toml | 1 + core/config/docs/chains-evm.toml | 4 ++ core/services/chainlink/config_test.go | 2 + .../chainlink/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 3 + core/web/resolver/testdata/config-full.toml | 1 + .../config-multi-chain-effective.toml | 3 + docs/CONFIG.md | 72 +++++++++++++++++++ .../node/validate/defaults-override.txtar | 1 + .../disk-based-logging-disabled.txtar | 1 + .../validate/disk-based-logging-no-dir.txtar | 1 + .../node/validate/disk-based-logging.txtar | 1 + testdata/scripts/node/validate/invalid.txtar | 1 + testdata/scripts/node/validate/valid.txtar | 1 + 27 files changed, 182 insertions(+), 18 deletions(-) create mode 100644 .changeset/happy-feet-rhyme.md diff --git a/.changeset/happy-feet-rhyme.md b/.changeset/happy-feet-rhyme.md new file mode 100644 index 0000000000..6e1697d96a --- /dev/null +++ b/.changeset/happy-feet-rhyme.md @@ -0,0 +1,11 @@ +--- +"chainlink": minor +--- + +This PR introduce few changes: +- Add a new config option `EVM.NodePool.NewHeadsPollInterval` (0 by default indicate disabled), which is an interval for polling new block periodically using http client rather than subscribe to ws feed. +- Updated new head handler for polling new head over http, and register the subscription in node lifecycle logic. +- If the polling new heads is enabled, WS new heads subscription will be replaced with the new http based polling. + +Note: There will be another PR for making WS URL optional with some extra condition. +#added diff --git a/common/client/node.go b/common/client/node.go index d6543c772a..1f55e69cac 100644 --- a/common/client/node.go +++ b/common/client/node.go @@ -45,6 +45,7 @@ type NodeConfig interface { FinalizedBlockPollInterval() time.Duration EnforceRepeatableRead() bool DeathDeclarationDelay() time.Duration + NewHeadsPollInterval() time.Duration } type ChainConfig interface { diff --git a/common/client/node_test.go b/common/client/node_test.go index 3b971e8490..66bb50fc94 100644 --- a/common/client/node_test.go +++ b/common/client/node_test.go @@ -20,6 +20,11 @@ type testNodeConfig struct { enforceRepeatableRead bool finalizedBlockPollInterval time.Duration deathDeclarationDelay time.Duration + newHeadsPollInterval time.Duration +} + +func (n testNodeConfig) NewHeadsPollInterval() time.Duration { + return n.newHeadsPollInterval } func (n testNodeConfig) PollFailureThreshold() uint32 { diff --git a/core/chains/evm/client/config_builder.go b/core/chains/evm/client/config_builder.go index e713ec9be2..9a31f9e4b4 100644 --- a/core/chains/evm/client/config_builder.go +++ b/core/chains/evm/client/config_builder.go @@ -43,7 +43,7 @@ func NewClientConfigs( deathDeclarationDelay time.Duration, noNewFinalizedHeadsThreshold time.Duration, finalizedBlockPollInterval time.Duration, - + newHeadsPollInterval time.Duration, ) (commonclient.ChainConfig, evmconfig.NodePool, []*toml.Node, error) { nodes, err := parseNodeConfigs(nodeCfgs) if err != nil { @@ -59,6 +59,7 @@ func NewClientConfigs( EnforceRepeatableRead: enforceRepeatableRead, DeathDeclarationDelay: commonconfig.MustNewDuration(deathDeclarationDelay), FinalizedBlockPollInterval: commonconfig.MustNewDuration(finalizedBlockPollInterval), + NewHeadsPollInterval: commonconfig.MustNewDuration(newHeadsPollInterval), } nodePoolCfg := &evmconfig.NodePoolConfig{C: nodePool} chainConfig := &evmconfig.EVMConfig{ diff --git a/core/chains/evm/client/config_builder_test.go b/core/chains/evm/client/config_builder_test.go index 403c6c2d61..28620ac6ca 100644 --- a/core/chains/evm/client/config_builder_test.go +++ b/core/chains/evm/client/config_builder_test.go @@ -37,9 +37,11 @@ func TestClientConfigBuilder(t *testing.T) { finalityDepth := ptr(uint32(10)) finalityTagEnabled := ptr(true) noNewHeadsThreshold := time.Second + newHeadsPollInterval := 0 * time.Second chainCfg, nodePool, nodes, err := client.NewClientConfigs(selectionMode, leaseDuration, chainTypeStr, nodeConfigs, pollFailureThreshold, pollInterval, syncThreshold, nodeIsSyncingEnabled, noNewHeadsThreshold, finalityDepth, - finalityTagEnabled, finalizedBlockOffset, enforceRepeatableRead, deathDeclarationDelay, noNewFinalizedBlocksThreshold, pollInterval) + finalityTagEnabled, finalizedBlockOffset, enforceRepeatableRead, deathDeclarationDelay, noNewFinalizedBlocksThreshold, + pollInterval, newHeadsPollInterval) require.NoError(t, err) // Validate node pool configs @@ -52,6 +54,7 @@ func TestClientConfigBuilder(t *testing.T) { require.Equal(t, *enforceRepeatableRead, nodePool.EnforceRepeatableRead()) require.Equal(t, deathDeclarationDelay, nodePool.DeathDeclarationDelay()) require.Equal(t, pollInterval, nodePool.FinalizedBlockPollInterval()) + require.Equal(t, newHeadsPollInterval, nodePool.NewHeadsPollInterval()) // Validate node configs require.Equal(t, *nodeConfigs[0].Name, *nodes[0].Name) diff --git a/core/chains/evm/client/evm_client.go b/core/chains/evm/client/evm_client.go index 1fd533d6aa..c26362d635 100644 --- a/core/chains/evm/client/evm_client.go +++ b/core/chains/evm/client/evm_client.go @@ -22,13 +22,13 @@ func NewEvmClient(cfg evmconfig.NodePool, chainCfg commonclient.ChainConfig, cli for i, node := range nodes { if node.SendOnly != nil && *node.SendOnly { rpc := NewRPCClient(lggr, empty, (*url.URL)(node.HTTPURL), *node.Name, int32(i), chainID, - commonclient.Secondary, cfg.FinalizedBlockPollInterval(), largePayloadRPCTimeout, defaultRPCTimeout, chainType) + commonclient.Secondary, cfg.FinalizedBlockPollInterval(), cfg.NewHeadsPollInterval(), largePayloadRPCTimeout, defaultRPCTimeout, chainType) sendonly := commonclient.NewSendOnlyNode(lggr, (url.URL)(*node.HTTPURL), *node.Name, chainID, rpc) sendonlys = append(sendonlys, sendonly) } else { rpc := NewRPCClient(lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), *node.Name, int32(i), - chainID, commonclient.Primary, cfg.FinalizedBlockPollInterval(), largePayloadRPCTimeout, defaultRPCTimeout, chainType) + chainID, commonclient.Primary, cfg.FinalizedBlockPollInterval(), cfg.NewHeadsPollInterval(), largePayloadRPCTimeout, defaultRPCTimeout, chainType) primaryNode := commonclient.NewNode(cfg, chainCfg, lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), *node.Name, int32(i), chainID, *node.Order, rpc, "EVM") diff --git a/core/chains/evm/client/evm_client_test.go b/core/chains/evm/client/evm_client_test.go index bdfcf42674..b762c14653 100644 --- a/core/chains/evm/client/evm_client_test.go +++ b/core/chains/evm/client/evm_client_test.go @@ -29,6 +29,7 @@ func TestNewEvmClient(t *testing.T) { deathDeclarationDelay := time.Second * 3 noNewFinalizedBlocksThreshold := time.Second * 5 finalizedBlockPollInterval := time.Second * 4 + newHeadsPollInterval := time.Second * 4 nodeConfigs := []client.NodeConfig{ { Name: ptr("foo"), @@ -40,7 +41,8 @@ func TestNewEvmClient(t *testing.T) { finalityTagEnabled := ptr(true) chainCfg, nodePool, nodes, err := client.NewClientConfigs(selectionMode, leaseDuration, chainTypeStr, nodeConfigs, pollFailureThreshold, pollInterval, syncThreshold, nodeIsSyncingEnabled, noNewHeadsThreshold, finalityDepth, - finalityTagEnabled, finalizedBlockOffset, enforceRepeatableRead, deathDeclarationDelay, noNewFinalizedBlocksThreshold, finalizedBlockPollInterval) + finalityTagEnabled, finalizedBlockOffset, enforceRepeatableRead, deathDeclarationDelay, noNewFinalizedBlocksThreshold, + finalizedBlockPollInterval, newHeadsPollInterval) require.NoError(t, err) client := client.NewEvmClient(nodePool, chainCfg, nil, logger.Test(t), testutils.FixtureChainID, nodes, chaintype.ChainType(chainTypeStr)) diff --git a/core/chains/evm/client/helpers_test.go b/core/chains/evm/client/helpers_test.go index 67977b180e..031f648157 100644 --- a/core/chains/evm/client/helpers_test.go +++ b/core/chains/evm/client/helpers_test.go @@ -92,6 +92,7 @@ type TestNodePoolConfig struct { NodeErrors config.ClientErrors EnforceRepeatableReadVal bool NodeDeathDeclarationDelay time.Duration + NodeNewHeadsPollInterval time.Duration } func (tc TestNodePoolConfig) PollFailureThreshold() uint32 { return tc.NodePollFailureThreshold } @@ -110,6 +111,10 @@ func (tc TestNodePoolConfig) FinalizedBlockPollInterval() time.Duration { return tc.NodeFinalizedBlockPollInterval } +func (tc TestNodePoolConfig) NewHeadsPollInterval() time.Duration { + return tc.NodeNewHeadsPollInterval +} + func (tc TestNodePoolConfig) Errors() config.ClientErrors { return tc.NodeErrors } @@ -143,7 +148,7 @@ func NewChainClientWithTestNode( } lggr := logger.Test(t) - rpc := NewRPCClient(lggr, *parsed, rpcHTTPURL, "eth-primary-rpc-0", id, chainID, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") + rpc := NewRPCClient(lggr, *parsed, rpcHTTPURL, "eth-primary-rpc-0", id, chainID, commonclient.Primary, 0, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") n := commonclient.NewNode[*big.Int, *evmtypes.Head, RPCClient]( nodeCfg, clientMocks.ChainConfig{NoNewHeadsThresholdVal: noNewHeadsThreshold}, lggr, *parsed, rpcHTTPURL, "eth-primary-node-0", id, chainID, 1, rpc, "EVM") @@ -155,7 +160,7 @@ func NewChainClientWithTestNode( return nil, pkgerrors.Errorf("sendonly ethereum rpc url scheme must be http(s): %s", u.String()) } var empty url.URL - rpc := NewRPCClient(lggr, empty, &sendonlyRPCURLs[i], fmt.Sprintf("eth-sendonly-rpc-%d", i), id, chainID, commonclient.Secondary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") + rpc := NewRPCClient(lggr, empty, &sendonlyRPCURLs[i], fmt.Sprintf("eth-sendonly-rpc-%d", i), id, chainID, commonclient.Secondary, 0, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") s := commonclient.NewSendOnlyNode[*big.Int, RPCClient]( lggr, u, fmt.Sprintf("eth-sendonly-%d", i), chainID, rpc) sendonlys = append(sendonlys, s) diff --git a/core/chains/evm/client/rpc_client.go b/core/chains/evm/client/rpc_client.go index 0752def994..763348173a 100644 --- a/core/chains/evm/client/rpc_client.go +++ b/core/chains/evm/client/rpc_client.go @@ -123,6 +123,7 @@ type rpcClient struct { largePayloadRpcTimeout time.Duration rpcTimeout time.Duration finalizedBlockPollInterval time.Duration + newHeadsPollInterval time.Duration chainType chaintype.ChainType ws rawclient @@ -159,6 +160,7 @@ func NewRPCClient( chainID *big.Int, tier commonclient.NodeTier, finalizedBlockPollInterval time.Duration, + newHeadsPollInterval time.Duration, largePayloadRpcTimeout time.Duration, rpcTimeout time.Duration, chainType chaintype.ChainType, @@ -174,6 +176,7 @@ func NewRPCClient( r.tier = tier r.ws.uri = wsuri r.finalizedBlockPollInterval = finalizedBlockPollInterval + r.newHeadsPollInterval = newHeadsPollInterval if httpuri != nil { r.http = &rawclient{uri: *httpuri} } @@ -490,6 +493,18 @@ func (r *rpcClient) SubscribeNewHead(ctx context.Context, channel chan<- *evmtyp args := []interface{}{"newHeads"} lggr := r.newRqLggr().With("args", args) + if r.newHeadsPollInterval > 0 { + interval := r.newHeadsPollInterval + timeout := interval + poller, _ := commonclient.NewPoller[*evmtypes.Head](interval, r.latestBlock, timeout, r.rpcLog) + if err = poller.Start(ctx); err != nil { + return nil, err + } + + lggr.Debugf("Polling new heads over http") + return &poller, nil + } + lggr.Debug("RPC call: evmclient.Client#EthSubscribe") start := time.Now() defer func() { @@ -523,6 +538,19 @@ func (r *rpcClient) SubscribeToHeads(ctx context.Context) (ch <-chan *evmtypes.H start := time.Now() lggr := r.newRqLggr().With("args", args) + // if new head based on http polling is enabled, we will replace it for WS newHead subscription + if r.newHeadsPollInterval > 0 { + interval := r.newHeadsPollInterval + timeout := interval + poller, channel := commonclient.NewPoller[*evmtypes.Head](interval, r.latestBlock, timeout, r.rpcLog) + if err = poller.Start(ctx); err != nil { + return nil, nil, err + } + + lggr.Debugf("Polling new heads over http") + return channel, &poller, nil + } + lggr.Debug("RPC call: evmclient.Client#EthSubscribe") defer func() { duration := time.Since(start) @@ -695,6 +723,10 @@ func (r *rpcClient) LatestFinalizedBlock(ctx context.Context) (head *evmtypes.He return } +func (r *rpcClient) latestBlock(ctx context.Context) (head *evmtypes.Head, err error) { + return r.BlockByNumber(ctx, nil) +} + func (r *rpcClient) astarLatestFinalizedBlock(ctx context.Context, result interface{}) (err error) { var hashResult string err = r.CallContext(ctx, &hashResult, "chain_getFinalizedHead") diff --git a/core/chains/evm/client/rpc_client_test.go b/core/chains/evm/client/rpc_client_test.go index 07e097727a..b594a0ca16 100644 --- a/core/chains/evm/client/rpc_client_test.go +++ b/core/chains/evm/client/rpc_client_test.go @@ -61,7 +61,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) // set to default values @@ -111,7 +111,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) ch := make(chan *evmtypes.Head) @@ -136,7 +136,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) var wg sync.WaitGroup @@ -160,7 +160,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { t.Run("Block's chain ID matched configured", func(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) ch := make(chan *evmtypes.Head) @@ -177,7 +177,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { }) wsURL := server.WSURL() observedLggr, observed := logger.TestObserved(t, zap.DebugLevel) - rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") + rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") require.NoError(t, rpc.Dial(ctx)) server.Close() _, err := rpc.SubscribeNewHead(ctx, make(chan *evmtypes.Head)) @@ -187,7 +187,7 @@ func TestRPCClient_SubscribeNewHead(t *testing.T) { t.Run("Subscription error is properly wrapper", func(t *testing.T) { server := testutils.NewWSServer(t, chainId, serverCallBack) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) sub, err := rpc.SubscribeNewHead(ctx, make(chan *evmtypes.Head)) @@ -215,7 +215,7 @@ func TestRPCClient_SubscribeFilterLogs(t *testing.T) { }) wsURL := server.WSURL() observedLggr, observed := logger.TestObserved(t, zap.DebugLevel) - rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") + rpc := client.NewRPCClient(observedLggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") require.NoError(t, rpc.Dial(ctx)) server.Close() _, err := rpc.SubscribeFilterLogs(ctx, ethereum.FilterQuery{}, make(chan types.Log)) @@ -232,7 +232,7 @@ func TestRPCClient_SubscribeFilterLogs(t *testing.T) { return resp }) wsURL := server.WSURL() - rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") + rpc := client.NewRPCClient(lggr, *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") defer rpc.Close() require.NoError(t, rpc.Dial(ctx)) sub, err := rpc.SubscribeFilterLogs(ctx, ethereum.FilterQuery{}, make(chan types.Log)) @@ -281,7 +281,7 @@ func TestRPCClient_LatestFinalizedBlock(t *testing.T) { } server := createRPCServer() - rpc := client.NewRPCClient(lggr, *server.URL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") + rpc := client.NewRPCClient(lggr, *server.URL, nil, "rpc", 1, chainId, commonclient.Primary, 0, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, "") require.NoError(t, rpc.Dial(ctx)) defer rpc.Close() server.Head = &evmtypes.Head{Number: 128} @@ -391,7 +391,7 @@ func TestRpcClientLargePayloadTimeout(t *testing.T) { // use something unreasonably large for RPC timeout to ensure that we use largePayloadRPCTimeout const rpcTimeout = time.Hour const largePayloadRPCTimeout = tests.TestInterval - rpc := client.NewRPCClient(logger.Test(t), *rpcURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, largePayloadRPCTimeout, rpcTimeout, "") + rpc := client.NewRPCClient(logger.Test(t), *rpcURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, 0, largePayloadRPCTimeout, rpcTimeout, "") require.NoError(t, rpc.Dial(ctx)) defer rpc.Close() err := testCase.Fn(ctx, rpc) @@ -431,7 +431,7 @@ func TestAstarCustomFinality(t *testing.T) { const expectedFinalizedBlockNumber = int64(4) const expectedFinalizedBlockHash = "0x7441e97acf83f555e0deefef86db636bc8a37eb84747603412884e4df4d22804" - rpcClient := client.NewRPCClient(logger.Test(t), *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, chaintype.ChainAstar) + rpcClient := client.NewRPCClient(logger.Test(t), *wsURL, nil, "rpc", 1, chainId, commonclient.Primary, 0, 0, commonclient.QueryTimeout, commonclient.QueryTimeout, chaintype.ChainAstar) defer rpcClient.Close() err := rpcClient.Dial(tests.Context(t)) require.NoError(t, err) diff --git a/core/chains/evm/config/chain_scoped_node_pool.go b/core/chains/evm/config/chain_scoped_node_pool.go index a497436648..4b1d02d148 100644 --- a/core/chains/evm/config/chain_scoped_node_pool.go +++ b/core/chains/evm/config/chain_scoped_node_pool.go @@ -38,6 +38,10 @@ func (n *NodePoolConfig) FinalizedBlockPollInterval() time.Duration { return n.C.FinalizedBlockPollInterval.Duration() } +func (n *NodePoolConfig) NewHeadsPollInterval() time.Duration { + return n.C.NewHeadsPollInterval.Duration() +} + func (n *NodePoolConfig) Errors() ClientErrors { return &clientErrorsConfig{c: n.C.Errors} } func (n *NodePoolConfig) EnforceRepeatableRead() bool { diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index 943616d963..e5b806aa58 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -182,6 +182,7 @@ type NodePool interface { Errors() ClientErrors EnforceRepeatableRead() bool DeathDeclarationDelay() time.Duration + NewHeadsPollInterval() time.Duration } // TODO BCF-2509 does the chainscopedconfig really need the entire app config? diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 9fb418cc8d..fd4039f5ea 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -885,6 +885,7 @@ type NodePool struct { Errors ClientErrors `toml:",omitempty"` EnforceRepeatableRead *bool DeathDeclarationDelay *commonconfig.Duration + NewHeadsPollInterval *commonconfig.Duration } func (p *NodePool) setFrom(f *NodePool) { @@ -917,6 +918,11 @@ func (p *NodePool) setFrom(f *NodePool) { if v := f.DeathDeclarationDelay; v != nil { p.DeathDeclarationDelay = v } + + if v := f.NewHeadsPollInterval; v != nil { + p.NewHeadsPollInterval = v + } + p.Errors.setFrom(&f.Errors) } diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index 2f9af4f85a..6f43f956fa 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -77,6 +77,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index ce85f242f5..bab4385f9f 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -409,6 +409,10 @@ EnforceRepeatableRead = false # Default # trigger declaration of `FinalizedBlockOutOfSync` due to insignificant network delays in broadcasting of the finalized state among RPCs. # RPC will not be picked to handle a request even if this option is set to a nonzero value. DeathDeclarationDelay = '10s' # Default +# NewHeadsPollInterval define an interval for polling new block periodically using http client rather than subscribe to ws feed +# +# Set to 0 to disable. +NewHeadsPollInterval = '0s' # Default # **ADVANCED** # Errors enable the node to provide custom regex patterns to match against error messages from RPCs. [EVM.NodePool.Errors] diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 44dc9f98ab..ed69475a54 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -634,6 +634,7 @@ func TestConfig_Marshal(t *testing.T) { FinalizedBlockPollInterval: &second, EnforceRepeatableRead: ptr(true), DeathDeclarationDelay: &minute, + NewHeadsPollInterval: &zeroSeconds, Errors: evmcfg.ClientErrors{ NonceTooLow: ptr[string]("(: |^)nonce too low"), NonceTooHigh: ptr[string]("(: |^)nonce too high"), @@ -1117,6 +1118,7 @@ NodeIsSyncingEnabled = true FinalizedBlockPollInterval = '1s' EnforceRepeatableRead = true DeathDeclarationDelay = '1m0s' +NewHeadsPollInterval = '0s' [EVM.NodePool.Errors] NonceTooLow = '(: |^)nonce too low' diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index eb69cee8b7..36002f46c5 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -403,6 +403,7 @@ NodeIsSyncingEnabled = true FinalizedBlockPollInterval = '1s' EnforceRepeatableRead = true DeathDeclarationDelay = '1m0s' +NewHeadsPollInterval = '0s' [EVM.NodePool.Errors] NonceTooLow = '(: |^)nonce too low' diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 776481ed6a..5d16b9b87c 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -370,6 +370,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.OCR] ContractConfirmations = 4 @@ -478,6 +479,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.OCR] ContractConfirmations = 4 @@ -580,6 +582,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.OCR] ContractConfirmations = 4 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index ee413a610e..971036991f 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -402,6 +402,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.NodePool.Errors] NonceTooLow = '(: |^)nonce too low' diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 210894d616..480fc1b4c0 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -370,6 +370,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.OCR] ContractConfirmations = 4 @@ -478,6 +479,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.OCR] ContractConfirmations = 4 @@ -580,6 +582,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.OCR] ContractConfirmations = 4 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index c3eeaac282..1512b33cad 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -2042,6 +2042,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -2144,6 +2145,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -2246,6 +2248,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -2348,6 +2351,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -2451,6 +2455,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -2553,6 +2558,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -2655,6 +2661,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -2758,6 +2765,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -2860,6 +2868,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -2961,6 +2970,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -3062,6 +3072,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -3164,6 +3175,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -3267,6 +3279,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -3369,6 +3382,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -3471,6 +3485,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -3573,6 +3588,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -3675,6 +3691,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -3777,6 +3794,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -3879,6 +3897,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -3981,6 +4000,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -4083,6 +4103,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -4185,6 +4206,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -4287,6 +4309,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -4389,6 +4412,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -4492,6 +4516,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -4594,6 +4619,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -4695,6 +4721,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -4797,6 +4824,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -4899,6 +4927,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -5001,6 +5030,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -5103,6 +5133,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -5204,6 +5235,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -5306,6 +5338,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -5408,6 +5441,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -5510,6 +5544,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -5612,6 +5647,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -5713,6 +5749,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -5815,6 +5852,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -5917,6 +5955,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -6020,6 +6059,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -6123,6 +6163,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -6226,6 +6267,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -6328,6 +6370,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -6430,6 +6473,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -6532,6 +6576,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -6634,6 +6679,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -6735,6 +6781,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -6836,6 +6883,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -6937,6 +6985,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -7039,6 +7088,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -7141,6 +7191,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -7242,6 +7293,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -7344,6 +7396,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -7446,6 +7499,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -7549,6 +7603,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -7652,6 +7707,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -7754,6 +7810,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -7856,6 +7913,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -7958,6 +8016,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -8060,6 +8119,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -8162,6 +8222,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 1 @@ -8264,6 +8325,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -8366,6 +8428,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [OCR] ContractConfirmations = 4 @@ -9122,6 +9185,7 @@ NodeIsSyncingEnabled = false # Default FinalizedBlockPollInterval = '5s' # Default EnforceRepeatableRead = false # Default DeathDeclarationDelay = '10s' # Default +NewHeadsPollInterval = '0s' # Default ``` The node pool manages multiple RPC endpoints. @@ -9214,6 +9278,14 @@ Larger values might be helpful to reduce the noisiness of health checks like `En trigger declaration of `FinalizedBlockOutOfSync` due to insignificant network delays in broadcasting of the finalized state among RPCs. RPC will not be picked to handle a request even if this option is set to a nonzero value. +### NewHeadsPollInterval +```toml +NewHeadsPollInterval = '0s' # Default +``` +NewHeadsPollInterval define an interval for polling new block periodically using http client rather than subscribe to ws feed + +Set to 0 to disable. + ## EVM.NodePool.Errors :warning: **_ADVANCED_**: _Do not change these settings unless you know what you are doing._ ```toml diff --git a/testdata/scripts/node/validate/defaults-override.txtar b/testdata/scripts/node/validate/defaults-override.txtar index 52eb86b3e6..85228771ce 100644 --- a/testdata/scripts/node/validate/defaults-override.txtar +++ b/testdata/scripts/node/validate/defaults-override.txtar @@ -443,6 +443,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.OCR] ContractConfirmations = 4 diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index b9f456c488..75ab3bb55c 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -426,6 +426,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.OCR] ContractConfirmations = 4 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 9457ae718c..de2bdf3209 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -426,6 +426,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.OCR] ContractConfirmations = 4 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 9a77ab1eac..ec0c442392 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -426,6 +426,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.OCR] ContractConfirmations = 4 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index af8fe17b87..dbef892b27 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -416,6 +416,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.OCR] ContractConfirmations = 4 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index c020664740..83cb6f451a 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -423,6 +423,7 @@ NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' EnforceRepeatableRead = false DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' [EVM.OCR] ContractConfirmations = 4 From 27d5cbf5787531d541ba774397b3abdfcb8b20a7 Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Date: Mon, 23 Sep 2024 12:27:46 +0200 Subject: [PATCH 403/432] BCFR-888 LP support chains that have not reached finality yet (#14366) * LP support chains that have not reached finality yet * changelog * fix test * ensure Test_ContractTransmitter_TransmitWithoutSignatures do not run in parallel to prevent db deadlock --- .changeset/famous-goats-hug.md | 5 +++++ .../ocrimpls/contract_transmitter_test.go | 1 - core/chains/evm/logpoller/log_poller.go | 21 ++++++++++--------- core/chains/evm/logpoller/log_poller_test.go | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 .changeset/famous-goats-hug.md diff --git a/.changeset/famous-goats-hug.md b/.changeset/famous-goats-hug.md new file mode 100644 index 0000000000..986f86bab2 --- /dev/null +++ b/.changeset/famous-goats-hug.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +LogPoller polls logs even if chain have not reached finality #internal diff --git a/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go b/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go index eae7abae9d..43081413ce 100644 --- a/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go +++ b/core/capabilities/ccip/ocrimpls/contract_transmitter_test.go @@ -90,7 +90,6 @@ func Test_ContractTransmitter_TransmitWithoutSignatures(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { tc := tc - t.Parallel() testTransmitter(t, tc.pluginType, tc.withSigs, tc.expectedSigsEnabled, tc.report) }) } diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index 2a551c1237..360511951e 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -598,18 +598,11 @@ func (lp *logPoller) run() { } // Otherwise this is the first poll _ever_ on a new chain. // Only safe thing to do is to start at the first finalized block. - latestBlock, latestFinalizedBlockNumber, err := lp.latestBlocks(ctx) + _, latestFinalizedBlockNumber, err := lp.latestBlocks(ctx) if err != nil { lp.lggr.Warnw("Unable to get latest for first poll", "err", err) continue } - // Do not support polling chains which don't even have finality depth worth of blocks. - // Could conceivably support this but not worth the effort. - // Need last finalized block number to be higher than 0 - if latestFinalizedBlockNumber <= 0 { - lp.lggr.Warnw("Insufficient number of blocks on chain, waiting for finality depth", "err", err, "latest", latestBlock.Number) - continue - } // Starting at the first finalized block. We do not backfill the first finalized block. start = latestFinalizedBlockNumber } else { @@ -1023,8 +1016,16 @@ func (lp *logPoller) latestBlocks(ctx context.Context) (*evmtypes.Head, int64, e return nil, 0, fmt.Errorf("failed to get latest and latest finalized block from HeadTracker: %w", err) } - lp.lggr.Debugw("Latest blocks read from chain", "latest", latest.Number, "finalized", finalized.BlockNumber()) - return latest, finalized.BlockNumber(), nil + finalizedBN := finalized.BlockNumber() + // This is a dirty trick that allows LogPoller to function properly in tests where chain needs significant time to + // reach finality depth. An alternative to this one-liner is a database migration that drops restriction + // LogPollerBlock.FinalizedBlockNumber > 0 (which we actually want to keep to spot cases when FinalizedBlockNumber was simply not populated) + // and refactoring of queries that assume that restriction still holds. + if finalizedBN == 0 { + finalizedBN = 1 + } + lp.lggr.Debugw("Latest blocks read from chain", "latest", latest.Number, "finalized", finalizedBN) + return latest, finalizedBN, nil } // Find the first place where our chain and their chain have the same block, diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index 6ad76030bb..1ab548063a 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -1774,7 +1774,7 @@ func Test_PollAndSavePersistsFinalityInBlocks(t *testing.T) { name: "setting last finalized block number to 0 if finality is too deep", useFinalityTag: false, finalityDepth: 20, - expectedFinalizedBlock: 0, + expectedFinalizedBlock: 1, }, { name: "using finality from chain", From 31874ba5a4abbc2dca7b985f04019485a339a71c Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Date: Mon, 23 Sep 2024 13:07:00 +0200 Subject: [PATCH 404/432] BCI-3668 Optimise HeadTracker's memory usage (#14130) * base benchmarks * Reduce allocs noise from mocks in Backfill Benchmark * Optimize HeadTracker's memory usage * avoid .Parent race in confirmer * optimise block history estimator heads usage * update telemetry test to use new Parent and IsFinalized * avoid redundant allocations * Revert "avoid redundant allocations" This reverts commit 76343e573980ac81df6d6e3b3409a3d164aeb579. * lint fixes * remove redundant files * drop cycle detection logic from head methods. Heads cycle prevention should be enough * drop unused test * nits --- .changeset/short-shoes-crash.md | 5 + common/txmgr/confirmer.go | 5 +- .../evm/client/simulated_backend_client.go | 10 +- .../chains/evm/gas/block_history_estimator.go | 3 +- .../evm/gas/block_history_estimator_test.go | 6 +- core/chains/evm/headtracker/head_saver.go | 12 +- core/chains/evm/headtracker/head_tracker.go | 3 +- .../evm/headtracker/head_tracker_test.go | 299 +++++++----------- core/chains/evm/headtracker/heads.go | 163 ++++++---- core/chains/evm/headtracker/heads_test.go | 125 ++++++-- core/chains/evm/headtracker/heap.go | 35 ++ core/chains/evm/headtracker/types/types.go | 4 + core/chains/evm/log/broadcaster.go | 4 +- core/chains/evm/log/registrations.go | 5 +- core/chains/evm/logpoller/log_poller.go | 6 +- .../evm/logpoller/log_poller_internal_test.go | 3 +- core/chains/evm/txmgr/confirmer_test.go | 115 +++---- core/chains/evm/txmgr/evm_tx_store_test.go | 42 +-- core/chains/evm/txmgr/finalizer_test.go | 35 +- core/chains/evm/txmgr/txmgr_test.go | 15 +- core/chains/evm/types/head_test.go | 51 ++- core/chains/evm/types/models.go | 97 ++---- core/chains/evm/types/models_test.go | 97 +++--- core/internal/cltest/cltest.go | 6 +- core/internal/cltest/factories.go | 5 +- .../headreporter/telemetry_reporter_test.go | 35 +- .../evmregistry/v21/block_subscriber.go | 2 +- .../evmregistry/v21/block_subscriber_test.go | 17 +- .../arbitrum_block_translator_test.go | 53 ++-- .../relay/evm/mercury/v1/data_source_test.go | 7 +- 30 files changed, 681 insertions(+), 584 deletions(-) create mode 100644 .changeset/short-shoes-crash.md create mode 100644 core/chains/evm/headtracker/heap.go diff --git a/.changeset/short-shoes-crash.md b/.changeset/short-shoes-crash.md new file mode 100644 index 0000000000..3043191624 --- /dev/null +++ b/.changeset/short-shoes-crash.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Optimize HeadTracker's memory usage #internal diff --git a/common/txmgr/confirmer.go b/common/txmgr/confirmer.go index bbf1d3b27b..4eaa6739d5 100644 --- a/common/txmgr/confirmer.go +++ b/common/txmgr/confirmer.go @@ -1148,10 +1148,11 @@ func hasReceiptInLongestChain[ } } } - if head.GetParent() == nil { + + head = head.GetParent() + if head == nil { return false } - head = head.GetParent() } } diff --git a/core/chains/evm/client/simulated_backend_client.go b/core/chains/evm/client/simulated_backend_client.go index 6c569b16b8..11828e5871 100644 --- a/core/chains/evm/client/simulated_backend_client.go +++ b/core/chains/evm/client/simulated_backend_client.go @@ -320,7 +320,15 @@ func (c *SimulatedBackendClient) SubscribeNewHead( case h := <-ch: var head *evmtypes.Head if h != nil { - head = &evmtypes.Head{Difficulty: h.Difficulty, Timestamp: time.Unix(int64(h.Time), 0), Number: h.Number.Int64(), Hash: h.Hash(), ParentHash: h.ParentHash, Parent: lastHead, EVMChainID: ubig.New(c.chainId)} + head = &evmtypes.Head{ + Difficulty: h.Difficulty, + Timestamp: time.Unix(int64(h.Time), 0), //nolint:gosec + Number: h.Number.Int64(), + Hash: h.Hash(), + ParentHash: h.ParentHash, + EVMChainID: ubig.New(c.chainId), + } + head.Parent.Store(lastHead) lastHead = head } select { diff --git a/core/chains/evm/gas/block_history_estimator.go b/core/chains/evm/gas/block_history_estimator.go index b933ea2382..0386d92a0d 100644 --- a/core/chains/evm/gas/block_history_estimator.go +++ b/core/chains/evm/gas/block_history_estimator.go @@ -655,12 +655,13 @@ func (b *BlockHistoryEstimator) FetchBlocks(ctx context.Context, head *evmtypes. } blocks := make(map[int64]evmtypes.Block) + earliestInChain := head.EarliestInChain() for _, block := range b.getBlocks() { // Make a best-effort to be re-org resistant using the head // chain, refetch blocks that got re-org'd out. // NOTE: Any blocks in the history that are older than the oldest block // in the provided chain will be assumed final. - if block.Number < head.EarliestInChain().BlockNumber() { + if block.Number < earliestInChain.BlockNumber() { blocks[block.Number] = block } else if head.IsInChain(block.Hash) { blocks[block.Number] = block diff --git a/core/chains/evm/gas/block_history_estimator_test.go b/core/chains/evm/gas/block_history_estimator_test.go index c2f4a2219c..d84137cb7c 100644 --- a/core/chains/evm/gas/block_history_estimator_test.go +++ b/core/chains/evm/gas/block_history_estimator_test.go @@ -515,7 +515,7 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) { head2 := evmtypes.NewHead(big.NewInt(2), b2.Hash, b1.Hash, uint64(time.Now().Unix()), ubig.New(testutils.FixtureChainID)) head3 := evmtypes.NewHead(big.NewInt(3), b3.Hash, b2.Hash, uint64(time.Now().Unix()), ubig.New(testutils.FixtureChainID)) - head3.Parent = &head2 + head3.Parent.Store(&head2) err := bhe.FetchBlocks(tests.Context(t), &head3) require.NoError(t, err) @@ -570,7 +570,7 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) { // RE-ORG, head2 and head3 have different hash than saved b2 and b3 head2 := evmtypes.NewHead(big.NewInt(2), utils.NewHash(), b1.Hash, uint64(time.Now().Unix()), ubig.New(testutils.FixtureChainID)) head3 := evmtypes.NewHead(big.NewInt(3), utils.NewHash(), head2.Hash, uint64(time.Now().Unix()), ubig.New(testutils.FixtureChainID)) - head3.Parent = &head2 + head3.Parent.Store(&head2) ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 2 && @@ -643,7 +643,7 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) { // head2 and head3 have identical hash to saved blocks head2 := evmtypes.NewHead(big.NewInt(2), b2.Hash, b1.Hash, uint64(time.Now().Unix()), ubig.New(testutils.FixtureChainID)) head3 := evmtypes.NewHead(big.NewInt(3), b3.Hash, head2.Hash, uint64(time.Now().Unix()), ubig.New(testutils.FixtureChainID)) - head3.Parent = &head2 + head3.Parent.Store(&head2) err := bhe.FetchBlocks(tests.Context(t), &head3) require.NoError(t, err) diff --git a/core/chains/evm/headtracker/head_saver.go b/core/chains/evm/headtracker/head_saver.go index 320e88a19b..f2613334c4 100644 --- a/core/chains/evm/headtracker/head_saver.go +++ b/core/chains/evm/headtracker/head_saver.go @@ -35,13 +35,12 @@ func NewHeadSaver(lggr logger.Logger, orm ORM, config commontypes.Config, htConf } func (hs *headSaver) Save(ctx context.Context, head *evmtypes.Head) error { - if err := hs.orm.IdempotentInsertHead(ctx, head); err != nil { + // adding new head might form a cycle, so it's better to validate cached chain before persisting it + if err := hs.heads.AddHeads(head); err != nil { return err } - hs.heads.AddHeads(head) - - return nil + return hs.orm.IdempotentInsertHead(ctx, head) } func (hs *headSaver) Load(ctx context.Context, latestFinalized int64) (chain *evmtypes.Head, err error) { @@ -51,7 +50,10 @@ func (hs *headSaver) Load(ctx context.Context, latestFinalized int64) (chain *ev return nil, err } - hs.heads.AddHeads(heads...) + err = hs.heads.AddHeads(heads...) + if err != nil { + return nil, fmt.Errorf("failed to populate cache with loaded heads: %w", err) + } return hs.heads.LatestHead(), nil } diff --git a/core/chains/evm/headtracker/head_tracker.go b/core/chains/evm/headtracker/head_tracker.go index f7607189f7..bb39b3b5c7 100644 --- a/core/chains/evm/headtracker/head_tracker.go +++ b/core/chains/evm/headtracker/head_tracker.go @@ -11,14 +11,13 @@ import ( "github.com/smartcontractkit/chainlink/v2/common/headtracker" commontypes "github.com/smartcontractkit/chainlink/v2/common/headtracker/types" - evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) func NewHeadTracker( lggr logger.Logger, - ethClient evmclient.Client, + ethClient httypes.Client, config commontypes.Config, htConfig commontypes.HeadTrackerConfig, headBroadcaster httypes.HeadBroadcaster, diff --git a/core/chains/evm/headtracker/head_tracker_test.go b/core/chains/evm/headtracker/head_tracker_test.go index 21ff1b1a92..de54f12ff9 100644 --- a/core/chains/evm/headtracker/head_tracker_test.go +++ b/core/chains/evm/headtracker/head_tracker_test.go @@ -12,7 +12,6 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" - gethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/onsi/gomega" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -21,21 +20,19 @@ import ( "go.uber.org/zap/zaptest/observer" "golang.org/x/exp/maps" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox/mailboxtest" "github.com/jmoiron/sqlx" - commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" htmocks "github.com/smartcontractkit/chainlink/v2/common/headtracker/mocks" commontypes "github.com/smartcontractkit/chainlink/v2/common/headtracker/types" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" - - evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" @@ -45,11 +42,13 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" ) -func firstHead(t *testing.T, db *sqlx.DB) (h evmtypes.Head) { - if err := db.Get(&h, `SELECT * FROM evm.heads ORDER BY number ASC LIMIT 1`); err != nil { +func firstHead(t *testing.T, db *sqlx.DB) *evmtypes.Head { + h := new(evmtypes.Head) + if err := db.Get(h, `SELECT * FROM evm.heads ORDER BY number ASC LIMIT 1`); err != nil { t.Fatal(err) } return h @@ -578,27 +577,10 @@ func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingEnabled(t *testing.T) checker.On("OnNewLongestChain", mock.Anything, mock.Anything). Run(func(args mock.Arguments) { h := args.Get(1).(*evmtypes.Head) + // This is the new longest chain [0, 5], check that it came with its parents + assert.Equal(t, uint32(6), h.ChainLength()) + assertChainWithParents(t, blocksForked, 5, 1, h) - assert.Equal(t, int64(5), h.Number) - assert.Equal(t, blocksForked.Head(5).Hash, h.Hash) - - // This is the new longest chain, check that it came with its parents - if !assert.NotNil(t, h.Parent) { - return - } - assert.Equal(t, h.Parent.Hash, blocksForked.Head(4).Hash) - if !assert.NotNil(t, h.Parent.Parent) { - return - } - assert.Equal(t, h.Parent.Parent.Hash, blocksForked.Head(3).Hash) - if !assert.NotNil(t, h.Parent.Parent.Parent) { - return - } - assert.Equal(t, h.Parent.Parent.Parent.Hash, blocksForked.Head(2).Hash) - if !assert.NotNil(t, h.Parent.Parent.Parent.Parent) { - return - } - assert.Equal(t, h.Parent.Parent.Parent.Parent.Hash, blocksForked.Head(1).Hash) lastLongestChainAwaiter.ItHappened() }).Return().Once() @@ -639,6 +621,16 @@ func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingEnabled(t *testing.T) } } +func assertChainWithParents(t testing.TB, blocks *blocks, startBN, endBN uint64, h *evmtypes.Head) { + for blockNumber := startBN; blockNumber >= endBN; blockNumber-- { + assert.NotNil(t, h) + assert.Equal(t, blockNumber, uint64(h.Number)) + assert.Equal(t, blocks.Head(blockNumber).Hash, h.Hash) + // move to parent + h = h.Parent.Load() + } +} + func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingDisabled(t *testing.T) { t.Parallel() @@ -725,34 +717,13 @@ func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingDisabled(t *testing.T checker.On("OnNewLongestChain", mock.Anything, mock.Anything). Run(func(args mock.Arguments) { h := args.Get(1).(*evmtypes.Head) - require.Equal(t, int64(4), h.Number) - require.Equal(t, blocks.Head(4).Hash, h.Hash) - - // Check that the block came with its parents - require.NotNil(t, h.Parent) - require.Equal(t, h.Parent.Hash, blocks.Head(3).Hash) - require.NotNil(t, h.Parent.Parent.Hash) - require.Equal(t, h.Parent.Parent.Hash, blocks.Head(2).Hash) - require.NotNil(t, h.Parent.Parent.Parent) - require.Equal(t, h.Parent.Parent.Parent.Hash, blocks.Head(1).Hash) + assertChainWithParents(t, blocks, 4, 1, h) }).Return().Once() checker.On("OnNewLongestChain", mock.Anything, mock.Anything). Run(func(args mock.Arguments) { h := args.Get(1).(*evmtypes.Head) - - require.Equal(t, int64(5), h.Number) - require.Equal(t, blocksForked.Head(5).Hash, h.Hash) - - // This is the new longest chain, check that it came with its parents - require.NotNil(t, h.Parent) - require.Equal(t, h.Parent.Hash, blocksForked.Head(4).Hash) - require.NotNil(t, h.Parent.Parent) - require.Equal(t, h.Parent.Parent.Hash, blocksForked.Head(3).Hash) - require.NotNil(t, h.Parent.Parent.Parent) - require.Equal(t, h.Parent.Parent.Parent.Hash, blocksForked.Head(2).Hash) - require.NotNil(t, h.Parent.Parent.Parent.Parent) - require.Equal(t, h.Parent.Parent.Parent.Parent.Hash, blocksForked.Head(1).Hash) + assertChainWithParents(t, blocksForked, 5, 1, h) lastLongestChainAwaiter.ItHappened() }).Return().Once() @@ -811,52 +782,37 @@ func TestHeadTracker_Backfill(t *testing.T) { now := uint64(time.Now().UTC().Unix()) - gethHead0 := &gethTypes.Header{ - Number: big.NewInt(0), - ParentHash: common.BigToHash(big.NewInt(0)), - Time: now, - } - head0 := evmtypes.NewHead(gethHead0.Number, utils.NewHash(), gethHead0.ParentHash, gethHead0.Time, ubig.New(testutils.FixtureChainID)) + head0 := evmtypes.NewHead(big.NewInt(0), utils.NewHash(), common.BigToHash(big.NewInt(0)), now, ubig.New(testutils.FixtureChainID)) - h1 := *testutils.Head(1) + h1 := testutils.Head(1) h1.ParentHash = head0.Hash - gethHead8 := &gethTypes.Header{ - Number: big.NewInt(8), - ParentHash: utils.NewHash(), - Time: now, - } - head8 := evmtypes.NewHead(gethHead8.Number, utils.NewHash(), gethHead8.ParentHash, gethHead8.Time, ubig.New(testutils.FixtureChainID)) + head8 := evmtypes.NewHead(big.NewInt(8), utils.NewHash(), utils.NewHash(), now, ubig.New(testutils.FixtureChainID)) - h9 := *testutils.Head(9) + h9 := testutils.Head(9) h9.ParentHash = head8.Hash - gethHead10 := &gethTypes.Header{ - Number: big.NewInt(10), - ParentHash: h9.Hash, - Time: now, - } - head10 := evmtypes.NewHead(gethHead10.Number, utils.NewHash(), gethHead10.ParentHash, gethHead10.Time, ubig.New(testutils.FixtureChainID)) + head10 := evmtypes.NewHead(big.NewInt(10), utils.NewHash(), h9.Hash, now, ubig.New(testutils.FixtureChainID)) - h11 := *testutils.Head(11) + h11 := testutils.Head(11) h11.ParentHash = head10.Hash - h12 := *testutils.Head(12) + h12 := testutils.Head(12) h12.ParentHash = h11.Hash - h13 := *testutils.Head(13) + h13 := testutils.Head(13) h13.ParentHash = h12.Hash - h14Orphaned := *testutils.Head(14) + h14Orphaned := testutils.Head(14) h14Orphaned.ParentHash = h13.Hash - h14 := *testutils.Head(14) + h14 := testutils.Head(14) h14.ParentHash = h13.Hash - h15 := *testutils.Head(15) + h15 := testutils.Head(15) h15.ParentHash = h14.Hash - heads := []evmtypes.Head{ + heads := []*evmtypes.Head{ h9, h11, h12, @@ -869,7 +825,7 @@ func TestHeadTracker_Backfill(t *testing.T) { ctx := tests.Context(t) type opts struct { - Heads []evmtypes.Head + Heads []*evmtypes.Head FinalityTagEnabled bool FinalizedBlockOffset uint32 FinalityDepth uint32 @@ -889,7 +845,7 @@ func TestHeadTracker_Backfill(t *testing.T) { db := pgtest.NewSqlxDB(t) orm := headtracker.NewORM(*testutils.FixtureChainID, db) for i := range opts.Heads { - require.NoError(t, orm.IdempotentInsertHead(tests.Context(t), &opts.Heads[i])) + require.NoError(t, orm.IdempotentInsertHead(tests.Context(t), opts.Heads[i])) } ethClient := testutils.NewEthClientMock(t) ethClient.On("ConfiguredChainID", mock.Anything).Return(evmcfg.EVM().ChainID(), nil) @@ -904,72 +860,70 @@ func TestHeadTracker_Backfill(t *testing.T) { const expectedError = "failed to fetch latest finalized block" htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(nil, errors.New(expectedError)).Once() - err := htu.headTracker.Backfill(ctx, &h12) + err := htu.headTracker.Backfill(ctx, h12) require.ErrorContains(t, err, expectedError) }) t.Run("returns error if latestFinalized is not valid", func(t *testing.T) { htu := newHeadTrackerUniverse(t, opts{FinalityTagEnabled: true}) htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(nil, nil).Once() - err := htu.headTracker.Backfill(ctx, &h12) + err := htu.headTracker.Backfill(ctx, h12) require.EqualError(t, err, "failed to calculate finalized block: failed to get valid latest finalized block") }) t.Run("Returns error if finality gap is too big", func(t *testing.T) { htu := newHeadTrackerUniverse(t, opts{FinalityTagEnabled: true, MaxAllowedFinalityDepth: 2}) - htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&h9, nil).Once() + htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(h9, nil).Once() - err := htu.headTracker.Backfill(ctx, &h12) + err := htu.headTracker.Backfill(ctx, h12) require.EqualError(t, err, "gap between latest finalized block (9) and current head (12) is too large (> 2)") }) t.Run("Returns error if finalized head is ahead of canonical", func(t *testing.T) { htu := newHeadTrackerUniverse(t, opts{FinalityTagEnabled: true}) - htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&h14Orphaned, nil).Once() + htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(h14Orphaned, nil).Once() - err := htu.headTracker.Backfill(ctx, &h12) + err := htu.headTracker.Backfill(ctx, h12) require.EqualError(t, err, "invariant violation: expected head of canonical chain to be ahead of the latestFinalized") }) t.Run("Returns error if finalizedHead is not present in the canonical chain", func(t *testing.T) { htu := newHeadTrackerUniverse(t, opts{Heads: heads, FinalityTagEnabled: true}) - htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&h14Orphaned, nil).Once() + htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(h14Orphaned, nil).Once() - err := htu.headTracker.Backfill(ctx, &h15) + err := htu.headTracker.Backfill(ctx, h15) require.EqualError(t, err, "expected finalized block to be present in canonical chain") }) t.Run("Marks all blocks in chain that are older than finalized", func(t *testing.T) { htu := newHeadTrackerUniverse(t, opts{Heads: heads, FinalityTagEnabled: true}) - assertFinalized := func(expectedFinalized bool, msg string, heads ...evmtypes.Head) { + assertFinalized := func(expectedFinalized bool, msg string, heads ...*evmtypes.Head) { for _, h := range heads { storedHead := htu.headSaver.Chain(h.Hash) - assert.Equal(t, expectedFinalized, storedHead != nil && storedHead.IsFinalized, msg, "block_number", h.Number) + assert.Equal(t, expectedFinalized, storedHead != nil && storedHead.IsFinalized.Load(), msg, "block_number", h.Number) } } - htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&h14, nil).Once() - err := htu.headTracker.Backfill(ctx, &h15) + htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(h14, nil).Once() + err := htu.headTracker.Backfill(ctx, h15) require.NoError(t, err) assertFinalized(true, "expected heads to be marked as finalized after backfill", h14, h13, h12, h11) - assertFinalized(false, "expected heads to remain unfinalized", h15, head10) + assertFinalized(false, "expected heads to remain unfinalized", h15, &head10) }) t.Run("fetches a missing head", func(t *testing.T) { htu := newHeadTrackerUniverse(t, opts{Heads: heads, FinalityTagEnabled: true}) - htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&h9, nil).Once() + htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(h9, nil).Once() htu.ethClient.On("HeadByHash", mock.Anything, head10.Hash). Return(&head10, nil) - err := htu.headTracker.Backfill(ctx, &h12) + err := htu.headTracker.Backfill(ctx, h12) require.NoError(t, err) h := htu.headSaver.Chain(h12.Hash) - assert.Equal(t, int64(12), h.Number) - require.NotNil(t, h.Parent) - assert.Equal(t, int64(11), h.Parent.Number) - require.NotNil(t, h.Parent.Parent) - assert.Equal(t, int64(10), h.Parent.Parent.Number) - require.NotNil(t, h.Parent.Parent.Parent) - assert.Equal(t, int64(9), h.Parent.Parent.Parent.Number) + for expectedBlockNumber := int64(12); expectedBlockNumber >= 9; expectedBlockNumber-- { + require.NotNil(t, h) + assert.Equal(t, expectedBlockNumber, h.Number) + h = h.Parent.Load() + } writtenHead, err := htu.orm.HeadByHash(tests.Context(t), head10.Hash) require.NoError(t, err) @@ -984,7 +938,7 @@ func TestHeadTracker_Backfill(t *testing.T) { htu.ethClient.On("HeadByHash", mock.Anything, head8.Hash). Return(&head8, nil) - err := htu.headTracker.Backfill(ctx, &h15) + err := htu.headTracker.Backfill(ctx, h15) require.NoError(t, err) h := htu.headSaver.Chain(h15.Hash) @@ -1005,7 +959,7 @@ func TestHeadTracker_Backfill(t *testing.T) { Return(nil, ethereum.NotFound). Once() - err := htu.headTracker.Backfill(ctx, &h12) + err := htu.headTracker.Backfill(ctx, h12) require.Error(t, err) require.ErrorContains(t, err, "fetchAndSaveHead failed: not found") @@ -1027,7 +981,7 @@ func TestHeadTracker_Backfill(t *testing.T) { cancel() }) - err := htu.headTracker.Backfill(lctx, &h12) + err := htu.headTracker.Backfill(lctx, h12) require.Error(t, err) require.ErrorContains(t, err, "fetchAndSaveHead failed: context canceled") @@ -1039,12 +993,12 @@ func TestHeadTracker_Backfill(t *testing.T) { }) t.Run("abandons backfill and returns error when fetching a block by hash fails, indicating a reorg", func(t *testing.T) { htu := newHeadTrackerUniverse(t, opts{FinalityTagEnabled: true}) - htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&h11, nil).Once() - htu.ethClient.On("HeadByHash", mock.Anything, h14.Hash).Return(&h14, nil).Once() - htu.ethClient.On("HeadByHash", mock.Anything, h13.Hash).Return(&h13, nil).Once() + htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(h11, nil).Once() + htu.ethClient.On("HeadByHash", mock.Anything, h14.Hash).Return(h14, nil).Once() + htu.ethClient.On("HeadByHash", mock.Anything, h13.Hash).Return(h13, nil).Once() htu.ethClient.On("HeadByHash", mock.Anything, h12.Hash).Return(nil, errors.New("not found")).Once() - err := htu.headTracker.Backfill(ctx, &h15) + err := htu.headTracker.Backfill(ctx, h15) require.Error(t, err) require.ErrorContains(t, err, "fetchAndSaveHead failed: not found") @@ -1056,83 +1010,83 @@ func TestHeadTracker_Backfill(t *testing.T) { assert.Equal(t, int64(13), h.EarliestInChain().BlockNumber()) }) t.Run("marks head as finalized, if latestHead = finalizedHead (0 finality depth)", func(t *testing.T) { - htu := newHeadTrackerUniverse(t, opts{Heads: []evmtypes.Head{h15}, FinalityTagEnabled: true}) + htu := newHeadTrackerUniverse(t, opts{Heads: []*evmtypes.Head{h15}, FinalityTagEnabled: true}) finalizedH15 := h15 // copy h15 to have different addresses - htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&finalizedH15, nil).Once() - err := htu.headTracker.Backfill(ctx, &h15) + htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(finalizedH15, nil).Once() + err := htu.headTracker.Backfill(ctx, h15) require.NoError(t, err) h := htu.headSaver.LatestChain() // Should contain 14, 13 (15 was never added). When trying to get the parent of h13 by hash, a reorg happened and backfill exited. assert.Equal(t, 1, int(h.ChainLength())) - assert.True(t, h.IsFinalized) + assert.True(t, h.IsFinalized.Load()) assert.Equal(t, h15.BlockNumber(), h.BlockNumber()) assert.Equal(t, h15.Hash, h.Hash) }) t.Run("marks block as finalized according to FinalizedBlockOffset (finality tag)", func(t *testing.T) { - htu := newHeadTrackerUniverse(t, opts{Heads: []evmtypes.Head{h15}, FinalityTagEnabled: true, FinalizedBlockOffset: 2}) - htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&h14, nil).Once() + htu := newHeadTrackerUniverse(t, opts{Heads: []*evmtypes.Head{h15}, FinalityTagEnabled: true, FinalizedBlockOffset: 2}) + htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(h14, nil).Once() // calculateLatestFinalizedBlock fetches blocks at LatestFinalized - FinalizedBlockOffset - htu.ethClient.On("HeadByNumber", mock.Anything, big.NewInt(h12.Number)).Return(&h12, nil).Once() + htu.ethClient.On("HeadByNumber", mock.Anything, big.NewInt(h12.Number)).Return(h12, nil).Once() // backfill from 15 to 12 - htu.ethClient.On("HeadByHash", mock.Anything, h12.Hash).Return(&h12, nil).Once() - htu.ethClient.On("HeadByHash", mock.Anything, h13.Hash).Return(&h13, nil).Once() - htu.ethClient.On("HeadByHash", mock.Anything, h14.Hash).Return(&h14, nil).Once() - err := htu.headTracker.Backfill(ctx, &h15) + htu.ethClient.On("HeadByHash", mock.Anything, h12.Hash).Return(h12, nil).Once() + htu.ethClient.On("HeadByHash", mock.Anything, h13.Hash).Return(h13, nil).Once() + htu.ethClient.On("HeadByHash", mock.Anything, h14.Hash).Return(h14, nil).Once() + err := htu.headTracker.Backfill(ctx, h15) require.NoError(t, err) h := htu.headSaver.LatestChain() // h - must contain 15, 14, 13, 12 and only 12 is finalized assert.Equal(t, 4, int(h.ChainLength())) - for ; h.Hash != h12.Hash; h = h.Parent { - assert.False(t, h.IsFinalized) + for ; h.Hash != h12.Hash; h = h.Parent.Load() { + assert.False(t, h.IsFinalized.Load()) } - assert.True(t, h.IsFinalized) + assert.True(t, h.IsFinalized.Load()) assert.Equal(t, h12.BlockNumber(), h.BlockNumber()) assert.Equal(t, h12.Hash, h.Hash) }) t.Run("marks block as finalized according to FinalizedBlockOffset (finality depth)", func(t *testing.T) { - htu := newHeadTrackerUniverse(t, opts{Heads: []evmtypes.Head{h15}, FinalityDepth: 1, FinalizedBlockOffset: 2}) - htu.ethClient.On("HeadByNumber", mock.Anything, big.NewInt(12)).Return(&h12, nil).Once() + htu := newHeadTrackerUniverse(t, opts{Heads: []*evmtypes.Head{h15}, FinalityDepth: 1, FinalizedBlockOffset: 2}) + htu.ethClient.On("HeadByNumber", mock.Anything, big.NewInt(12)).Return(h12, nil).Once() // backfill from 15 to 12 - htu.ethClient.On("HeadByHash", mock.Anything, h14.Hash).Return(&h14, nil).Once() - htu.ethClient.On("HeadByHash", mock.Anything, h13.Hash).Return(&h13, nil).Once() - htu.ethClient.On("HeadByHash", mock.Anything, h12.Hash).Return(&h12, nil).Once() - err := htu.headTracker.Backfill(ctx, &h15) + htu.ethClient.On("HeadByHash", mock.Anything, h14.Hash).Return(h14, nil).Once() + htu.ethClient.On("HeadByHash", mock.Anything, h13.Hash).Return(h13, nil).Once() + htu.ethClient.On("HeadByHash", mock.Anything, h12.Hash).Return(h12, nil).Once() + err := htu.headTracker.Backfill(ctx, h15) require.NoError(t, err) h := htu.headSaver.LatestChain() // h - must contain 15, 14, 13, 12 and only 12 is finalized assert.Equal(t, 4, int(h.ChainLength())) - for ; h.Hash != h12.Hash; h = h.Parent { - assert.False(t, h.IsFinalized) + for ; h.Hash != h12.Hash; h = h.Parent.Load() { + assert.False(t, h.IsFinalized.Load()) } - assert.True(t, h.IsFinalized) + assert.True(t, h.IsFinalized.Load()) assert.Equal(t, h12.BlockNumber(), h.BlockNumber()) assert.Equal(t, h12.Hash, h.Hash) }) t.Run("marks block as finalized according to FinalizedBlockOffset even with instant finality", func(t *testing.T) { - htu := newHeadTrackerUniverse(t, opts{Heads: []evmtypes.Head{h15}, FinalityDepth: 0, FinalizedBlockOffset: 2}) - htu.ethClient.On("HeadByNumber", mock.Anything, big.NewInt(13)).Return(&h13, nil).Once() + htu := newHeadTrackerUniverse(t, opts{Heads: []*evmtypes.Head{h15}, FinalityDepth: 0, FinalizedBlockOffset: 2}) + htu.ethClient.On("HeadByNumber", mock.Anything, big.NewInt(13)).Return(h13, nil).Once() // backfill from 15 to 13 - htu.ethClient.On("HeadByHash", mock.Anything, h14.Hash).Return(&h14, nil).Once() - htu.ethClient.On("HeadByHash", mock.Anything, h13.Hash).Return(&h13, nil).Once() - err := htu.headTracker.Backfill(ctx, &h15) + htu.ethClient.On("HeadByHash", mock.Anything, h14.Hash).Return(h14, nil).Once() + htu.ethClient.On("HeadByHash", mock.Anything, h13.Hash).Return(h13, nil).Once() + err := htu.headTracker.Backfill(ctx, h15) require.NoError(t, err) h := htu.headSaver.LatestChain() // h - must contain 15, 14, 13, only 13 is finalized assert.Equal(t, 3, int(h.ChainLength())) - for ; h.Hash != h13.Hash; h = h.Parent { - assert.False(t, h.IsFinalized) + for ; h.Hash != h13.Hash; h = h.Parent.Load() { + assert.False(t, h.IsFinalized.Load()) } - assert.True(t, h.IsFinalized) + assert.True(t, h.IsFinalized.Load()) assert.Equal(t, h13.BlockNumber(), h.BlockNumber()) assert.Equal(t, h13.Hash, h.Hash) }) @@ -1153,7 +1107,7 @@ func TestHeadTracker_LatestAndFinalizedBlock(t *testing.T) { h13.ParentHash = h12.Hash type opts struct { - Heads []evmtypes.Head + Heads []*evmtypes.Head FinalityTagEnabled bool FinalizedBlockOffset uint32 FinalityDepth uint32 @@ -1169,7 +1123,7 @@ func TestHeadTracker_LatestAndFinalizedBlock(t *testing.T) { db := pgtest.NewSqlxDB(t) orm := headtracker.NewORM(*testutils.FixtureChainID, db) for i := range opts.Heads { - require.NoError(t, orm.IdempotentInsertHead(tests.Context(t), &opts.Heads[i])) + require.NoError(t, orm.IdempotentInsertHead(tests.Context(t), opts.Heads[i])) } ethClient := evmtest.NewEthClientMock(t) ethClient.On("ConfiguredChainID", mock.Anything).Return(testutils.FixtureChainID, nil) @@ -1221,7 +1175,7 @@ func TestHeadTracker_LatestAndFinalizedBlock(t *testing.T) { assert.Equal(t, actualLF, h11) }) t.Run("returns latest finalized block with offset from cache (finality tag)", func(t *testing.T) { - htu := newHeadTrackerUniverse(t, opts{FinalityTagEnabled: true, FinalizedBlockOffset: 1, Heads: []evmtypes.Head{*h13, *h12, *h11}}) + htu := newHeadTrackerUniverse(t, opts{FinalityTagEnabled: true, FinalizedBlockOffset: 1, Heads: []*evmtypes.Head{h13, h12, h11}}) htu.ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h13, nil).Once() htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(h12, nil).Once() @@ -1231,7 +1185,7 @@ func TestHeadTracker_LatestAndFinalizedBlock(t *testing.T) { assert.Equal(t, actualLF.Number, h11.Number) }) t.Run("returns latest finalized block with offset from RPC (finality tag)", func(t *testing.T) { - htu := newHeadTrackerUniverse(t, opts{FinalityTagEnabled: true, FinalizedBlockOffset: 2, Heads: []evmtypes.Head{*h13, *h12, *h11}}) + htu := newHeadTrackerUniverse(t, opts{FinalityTagEnabled: true, FinalizedBlockOffset: 2, Heads: []*evmtypes.Head{h13, h12, h11}}) htu.ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h13, nil).Once() htu.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(h12, nil).Once() h10 := testutils.Head(10) @@ -1252,7 +1206,7 @@ func TestHeadTracker_LatestAndFinalizedBlock(t *testing.T) { assert.Equal(t, actualLF.Number, h13.Number) }) t.Run("returns latest finalized block with offset from cache (finality depth)", func(t *testing.T) { - htu := newHeadTrackerUniverse(t, opts{FinalityDepth: 1, FinalizedBlockOffset: 1, Heads: []evmtypes.Head{*h13, *h12, *h11}}) + htu := newHeadTrackerUniverse(t, opts{FinalityDepth: 1, FinalizedBlockOffset: 1, Heads: []*evmtypes.Head{h13, h12, h11}}) htu.ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h13, nil).Once() actualL, actualLF, err := htu.headTracker.LatestAndFinalizedBlock(ctx) @@ -1261,7 +1215,7 @@ func TestHeadTracker_LatestAndFinalizedBlock(t *testing.T) { assert.Equal(t, actualLF.Number, h11.Number) }) t.Run("returns latest finalized block with offset from RPC (finality depth)", func(t *testing.T) { - htu := newHeadTrackerUniverse(t, opts{FinalityDepth: 1, FinalizedBlockOffset: 2, Heads: []evmtypes.Head{*h13, *h12, *h11}}) + htu := newHeadTrackerUniverse(t, opts{FinalityDepth: 1, FinalizedBlockOffset: 2, Heads: []*evmtypes.Head{h13, h12, h11}}) htu.ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h13, nil).Once() h10 := testutils.Head(10) htu.ethClient.On("HeadByNumber", mock.Anything, big.NewInt(10)).Return(h10, nil).Once() @@ -1273,47 +1227,6 @@ func TestHeadTracker_LatestAndFinalizedBlock(t *testing.T) { }) } -// BenchmarkHeadTracker_Backfill - benchmarks HeadTracker's Backfill with focus on efficiency after initial -// backfill on start up -func BenchmarkHeadTracker_Backfill(b *testing.B) { - evmcfg := testutils.NewTestChainScopedConfig(b, func(c *toml.EVMConfig) { - c.FinalityTagEnabled = ptr(true) - }) - db := pgtest.NewSqlxDB(b) - chainID := big.NewInt(evmclient.NullClientChainID) - orm := headtracker.NewORM(*chainID, db) - ethClient := evmclimocks.NewClient(b) - ethClient.On("ConfiguredChainID").Return(chainID) - ht := createHeadTracker(b, ethClient, evmcfg.EVM(), evmcfg.EVM().HeadTracker(), orm) - ctx := tests.Context(b) - makeHash := func(n int64) common.Hash { - return common.BigToHash(big.NewInt(n)) - } - const finalityDepth = 12000 // observed value on Arbitrum - makeBlock := func(n int64) *evmtypes.Head { - return &evmtypes.Head{Number: n, Hash: makeHash(n), ParentHash: makeHash(n - 1)} - } - latest := makeBlock(finalityDepth) - finalized := makeBlock(1) - ethClient.On("HeadByHash", mock.Anything, mock.Anything).Return(func(_ context.Context, hash common.Hash) (*evmtypes.Head, error) { - number := hash.Big().Int64() - return makeBlock(number), nil - }) - ethClient.On("LatestFinalizedBlock", mock.Anything).Return(finalized, nil).Once() - // run initial backfill to populate the database - err := ht.headTracker.Backfill(ctx, latest) - require.NoError(b, err) - b.ResetTimer() - // focus benchmark on processing of a new latest block - for i := 0; i < b.N; i++ { - latest = makeBlock(int64(finalityDepth + i)) - finalized = makeBlock(int64(i + 1)) - ethClient.On("LatestFinalizedBlock", mock.Anything).Return(finalized, nil).Once() - err := ht.headTracker.Backfill(ctx, latest) - require.NoError(b, err) - } -} - func createHeadTracker(t testing.TB, ethClient *evmclimocks.Client, config commontypes.Config, htConfig commontypes.HeadTrackerConfig, orm headtracker.ORM) *headTrackerUniverse { lggr, ob := logger.TestObserved(t, zap.DebugLevel) hb := headtracker.NewHeadBroadcaster(lggr) @@ -1417,15 +1330,15 @@ func (hb *headBuffer) Append(head *evmtypes.Head) { Number: head.Number, Hash: head.Hash, ParentHash: head.ParentHash, - Parent: head.Parent, Timestamp: time.Unix(int64(len(hb.Heads)), 0), EVMChainID: head.EVMChainID, } + cloned.Parent.Store(head.Parent.Load()) hb.Heads = append(hb.Heads, cloned) } type blocks struct { - t *testing.T + t testing.TB Hashes []common.Hash mHashes map[int64]common.Hash Heads map[int64]*evmtypes.Head @@ -1435,7 +1348,7 @@ func (b *blocks) Head(number uint64) *evmtypes.Head { return b.Heads[int64(number)] } -func NewBlocks(t *testing.T, numHashes int) *blocks { +func NewBlocks(t testing.TB, numHashes int) *blocks { hashes := make([]common.Hash, 0) heads := make(map[int64]*evmtypes.Head) for i := int64(0); i < int64(numHashes); i++ { @@ -1445,7 +1358,7 @@ func NewBlocks(t *testing.T, numHashes int) *blocks { heads[i] = &evmtypes.Head{Hash: hash, Number: i, Timestamp: time.Unix(i, 0), EVMChainID: ubig.New(testutils.FixtureChainID)} if i > 0 { parent := heads[i-1] - heads[i].Parent = parent + heads[i].Parent.Store(parent) heads[i].ParentHash = parent.Hash } } @@ -1474,7 +1387,7 @@ func (b *blocks) ForkAt(t *testing.T, blockNum int64, numHashes int) *blocks { } forked.Heads[blockNum].ParentHash = b.Heads[blockNum].ParentHash - forked.Heads[blockNum].Parent = b.Heads[blockNum].Parent + forked.Heads[blockNum].Parent.Store(b.Heads[blockNum].Parent.Load()) return forked } @@ -1488,9 +1401,9 @@ func (b *blocks) NewHead(number uint64) *evmtypes.Head { Number: parent.Number + 1, Hash: testutils.NewHash(), ParentHash: parent.Hash, - Parent: parent, Timestamp: time.Unix(parent.Number+1, 0), EVMChainID: ubig.New(testutils.FixtureChainID), } + head.Parent.Store(parent) return head } diff --git a/core/chains/evm/headtracker/heads.go b/core/chains/evm/headtracker/heads.go index a61e55dcd2..c3492f9a59 100644 --- a/core/chains/evm/headtracker/heads.go +++ b/core/chains/evm/headtracker/heads.go @@ -1,7 +1,8 @@ package headtracker import ( - "sort" + "container/heap" + "fmt" "sync" "github.com/ethereum/go-ethereum/common" @@ -17,7 +18,7 @@ type Heads interface { HeadByHash(hash common.Hash) *evmtypes.Head // AddHeads adds newHeads to the collection, eliminates duplicates, // sorts by head number, fixes parents and cuts off old heads (historyDepth). - AddHeads(newHeads ...*evmtypes.Head) + AddHeads(newHeads ...*evmtypes.Head) error // Count returns number of heads in the collection. Count() int // MarkFinalized - finds `finalized` in the LatestHead and marks it and all direct ancestors as finalized. @@ -26,114 +27,158 @@ type Heads interface { } type heads struct { - heads []*evmtypes.Head - headsMap map[common.Hash]*evmtypes.Head - mu sync.RWMutex + highest *evmtypes.Head + headsAsc *headsHeap + headsByHash map[common.Hash]*evmtypes.Head + headsByParent map[common.Hash]map[common.Hash]*evmtypes.Head + mu sync.RWMutex } func NewHeads() Heads { - return &heads{} + return &heads{ + headsAsc: &headsHeap{}, + headsByHash: make(map[common.Hash]*evmtypes.Head), + headsByParent: map[common.Hash]map[common.Hash]*evmtypes.Head{}, + } } func (h *heads) LatestHead() *evmtypes.Head { h.mu.RLock() defer h.mu.RUnlock() - if len(h.heads) == 0 { - return nil - } - return h.heads[0] + return h.highest } func (h *heads) HeadByHash(hash common.Hash) *evmtypes.Head { h.mu.RLock() defer h.mu.RUnlock() - if h.headsMap == nil { + if h.headsByHash == nil { return nil } - return h.headsMap[hash] + return h.headsByHash[hash] } func (h *heads) Count() int { h.mu.RLock() defer h.mu.RUnlock() - return len(h.heads) + return h.headsAsc.Len() } -// MarkFinalized - marks block with has equal to finalized and all it's direct ancestors as finalized. +// MarkFinalized - marks block with hash equal to finalized and all it's direct ancestors as finalized. // Trims old blocks whose height is smaller than minBlockToKeep func (h *heads) MarkFinalized(finalized common.Hash, minBlockToKeep int64) bool { h.mu.Lock() defer h.mu.Unlock() - if len(h.heads) == 0 { + if len(h.headsByHash) == 0 { return false } - // deep copy to avoid race on head.Parent - h.heads, h.headsMap = deepCopy(h.heads, minBlockToKeep) - - finalizedHead, ok := h.headsMap[finalized] + finalizedHead, ok := h.headsByHash[finalized] if !ok { return false } - for finalizedHead != nil { - finalizedHead.IsFinalized = true - finalizedHead = finalizedHead.Parent + + markFinalized(finalizedHead) + + // remove all blocks that are older than minBlockToKeep + for h.headsAsc.Len() > 0 && h.headsAsc.Peek().Number < minBlockToKeep { + oldBlock := heap.Pop(h.headsAsc).(*evmtypes.Head) + delete(h.headsByHash, oldBlock.Hash) + // clear .Parent in oldBlock's children + for _, oldBlockChildren := range h.headsByParent[oldBlock.Hash] { + oldBlockChildren.Parent.Store(nil) + } + // headsByParent are expected to be of the same height, so we can remove them all at once + delete(h.headsByParent, oldBlock.ParentHash) + } + + if h.highest.Number < minBlockToKeep { + h.highest = nil } return true } -func deepCopy(oldHeads []*evmtypes.Head, minBlockToKeep int64) ([]*evmtypes.Head, map[common.Hash]*evmtypes.Head) { - headsMap := make(map[common.Hash]*evmtypes.Head, len(oldHeads)) - heads := make([]*evmtypes.Head, 0, len(headsMap)) - for _, head := range oldHeads { - if head.Hash == head.ParentHash { - // shouldn't happen but it is untrusted input - continue - } - if head.BlockNumber() < minBlockToKeep { - // trim redundant blocks - continue - } - // copy all head objects to avoid races when a previous head chain is used - // elsewhere (since we mutate Parent here) - headCopy := *head - headCopy.Parent = nil // always build it from scratch in case it points to a head too old to be included - // map eliminates duplicates - // prefer head that was already in heads as it might have been marked as finalized on previous run - if _, ok := headsMap[head.Hash]; !ok { - headsMap[head.Hash] = &headCopy - heads = append(heads, &headCopy) +func markFinalized(head *evmtypes.Head) { + // we can assume that if a head was previously marked as finalized all its ancestors were marked as finalized + for head != nil && !head.IsFinalized.Load() { + head.IsFinalized.Store(true) + head = head.Parent.Load() + } +} + +func (h *heads) ensureNoCycles(newHead *evmtypes.Head) error { + if newHead.ParentHash == newHead.Hash { + return fmt.Errorf("cycle detected: newHeads reference itself newHead(%s)", newHead.String()) + } + if parent, ok := h.headsByHash[newHead.ParentHash]; ok { + if parent.Number >= newHead.Number { + return fmt.Errorf("potential cycle detected while adding newHead as child: %w", newPotentialCycleError(parent, newHead)) } } - // sort the heads as original slice might be out of order - sort.SliceStable(heads, func(i, j int) bool { - // sorting from the highest number to lowest - return heads[i].Number > heads[j].Number - }) - - // assign parents - for i := 0; i < len(heads); i++ { - head := heads[i] - parent, exists := headsMap[head.ParentHash] - if exists { - head.Parent = parent + for _, child := range h.headsByParent[newHead.Hash] { + if newHead.Number >= child.Number { + return fmt.Errorf("potential cycle detected while adding newHead as parent: %w", newPotentialCycleError(newHead, child)) } } - return heads, headsMap + return nil } -func (h *heads) AddHeads(newHeads ...*evmtypes.Head) { +func (h *heads) AddHeads(newHeads ...*evmtypes.Head) error { h.mu.Lock() defer h.mu.Unlock() - // deep copy to avoid race on head.Parent - h.heads, h.headsMap = deepCopy(append(h.heads, newHeads...), 0) + for _, newHead := range newHeads { + // skip blocks that were previously added + if _, ok := h.headsByHash[newHead.Hash]; ok { + continue + } + + if err := h.ensureNoCycles(newHead); err != nil { + return err + } + + // heads now owns the newHead - reset values that are populated by heads + newHead.IsFinalized.Store(false) + newHead.Parent.Store(nil) + + // prefer newer head to set as highest + if h.highest == nil || h.highest.Number <= newHead.Number { + h.highest = newHead + } + + heap.Push(h.headsAsc, newHead) + h.headsByHash[newHead.Hash] = newHead + siblings, ok := h.headsByParent[newHead.ParentHash] + if !ok { + siblings = make(map[common.Hash]*evmtypes.Head) + h.headsByParent[newHead.ParentHash] = siblings + } + siblings[newHead.Hash] = newHead + // populate reference to parent + if parent, ok := h.headsByHash[newHead.ParentHash]; ok { + newHead.Parent.Store(parent) + } + for _, child := range h.headsByParent[newHead.Hash] { + // ensure all children have reference to newHead + child.Parent.Store(newHead) + if child.IsFinalized.Load() { + // mark newHead as finalized if any of its children is finalized + markFinalized(newHead) + } + } + } + + return nil +} + +func newPotentialCycleError(parent, child *evmtypes.Head) error { + return fmt.Errorf("expected head number to strictly decrease in 'child -> parent' relation: "+ + "child(%s), parent(%s)", child.String(), parent.String()) } diff --git a/core/chains/evm/headtracker/heads_test.go b/core/chains/evm/headtracker/heads_test.go index 6c02c528ba..92e4015d8c 100644 --- a/core/chains/evm/headtracker/heads_test.go +++ b/core/chains/evm/headtracker/heads_test.go @@ -20,21 +20,29 @@ func TestHeads_LatestHead(t *testing.T) { t.Parallel() heads := headtracker.NewHeads() - heads.AddHeads(testutils.Head(100), testutils.Head(200), testutils.Head(300)) + assert.NoError(t, heads.AddHeads(testutils.Head(100), testutils.Head(200), testutils.Head(300))) latest := heads.LatestHead() require.NotNil(t, latest) require.Equal(t, int64(300), latest.Number) - heads.AddHeads(testutils.Head(250)) + assert.NoError(t, heads.AddHeads(testutils.Head(250))) latest = heads.LatestHead() require.NotNil(t, latest) require.Equal(t, int64(300), latest.Number) - heads.AddHeads(testutils.Head(400)) + assert.NoError(t, heads.AddHeads(testutils.Head(400))) latest = heads.LatestHead() require.NotNil(t, latest) require.Equal(t, int64(400), latest.Number) + + // if heads have the same height, LatestHead prefers most recent + newerH400 := testutils.Head(400) + assert.NoError(t, heads.AddHeads(newerH400)) + latest = heads.LatestHead() + require.NotNil(t, latest) + require.Equal(t, int64(400), latest.Number) + require.Equal(t, newerH400.Hash, latest.Hash) } func TestHeads_HeadByHash(t *testing.T) { @@ -46,7 +54,7 @@ func TestHeads_HeadByHash(t *testing.T) { testutils.Head(300), } heads := headtracker.NewHeads() - heads.AddHeads(testHeads...) + assert.NoError(t, heads.AddHeads(testHeads...)) head := heads.HeadByHash(testHeads[1].Hash) require.NotNil(t, head) @@ -62,10 +70,10 @@ func TestHeads_Count(t *testing.T) { heads := headtracker.NewHeads() require.Zero(t, heads.Count()) - heads.AddHeads(testutils.Head(100), testutils.Head(200), testutils.Head(300)) + assert.NoError(t, heads.AddHeads(testutils.Head(100), testutils.Head(200), testutils.Head(300))) require.Equal(t, 3, heads.Count()) - heads.AddHeads(testutils.Head(400)) + assert.NoError(t, heads.AddHeads(testutils.Head(400))) require.Equal(t, 4, heads.Count()) } @@ -77,11 +85,11 @@ func TestHeads_AddHeads(t *testing.T) { var testHeads []*evmtypes.Head var parentHash common.Hash - for i := 0; i < 5; i++ { - hash := utils.NewHash() + for i := 1; i < 6; i++ { + hash := common.BigToHash(big.NewInt(int64(i))) h := evmtypes.NewHead(big.NewInt(int64(i)), hash, parentHash, uint64(time.Now().Unix()), ubig.NewI(0)) testHeads = append(testHeads, &h) - if i == 2 { + if i == 3 { // uncled block h := evmtypes.NewHead(big.NewInt(int64(i)), uncleHash, parentHash, uint64(time.Now().Unix()), ubig.NewI(0)) testHeads = append(testHeads, &h) @@ -89,10 +97,10 @@ func TestHeads_AddHeads(t *testing.T) { parentHash = hash } - heads.AddHeads(testHeads...) + assert.NoError(t, heads.AddHeads(testHeads...)) require.Equal(t, 6, heads.Count()) // Add duplicates (should be ignored) - heads.AddHeads(testHeads[2:5]...) + assert.NoError(t, heads.AddHeads(testHeads[2:5]...)) require.Equal(t, 6, heads.Count()) head := heads.LatestHead() @@ -102,6 +110,26 @@ func TestHeads_AddHeads(t *testing.T) { head = heads.HeadByHash(uncleHash) require.NotNil(t, head) require.Equal(t, 3, int(head.ChainLength())) + // returns an error, if newHead creates cycle + t.Run("Returns an error, if newHead create cycle", func(t *testing.T) { + cycleHead := &evmtypes.Head{ + Hash: heads.LatestHead().EarliestInChain().ParentHash, + ParentHash: heads.LatestHead().Hash, + } + // 1. try adding in front + cycleHead.Number = heads.LatestHead().Number + 1 + assert.EqualError(t, heads.AddHeads(cycleHead), "potential cycle detected while adding newHead as parent: expected head number to strictly decrease in 'child -> parent' relation: child(Head{Number: 1, Hash: 0x0000000000000000000000000000000000000000000000000000000000000001, ParentHash: 0x0000000000000000000000000000000000000000000000000000000000000000}), parent(Head{Number: 6, Hash: 0x0000000000000000000000000000000000000000000000000000000000000000, ParentHash: 0x0000000000000000000000000000000000000000000000000000000000000005})") + // 2. try adding to back + cycleHead.Number = heads.LatestHead().EarliestInChain().Number - 1 + assert.EqualError(t, heads.AddHeads(cycleHead), "potential cycle detected while adding newHead as child: expected head number to strictly decrease in 'child -> parent' relation: child(Head{Number: 0, Hash: 0x0000000000000000000000000000000000000000000000000000000000000000, ParentHash: 0x0000000000000000000000000000000000000000000000000000000000000005}), parent(Head{Number: 5, Hash: 0x0000000000000000000000000000000000000000000000000000000000000005, ParentHash: 0x0000000000000000000000000000000000000000000000000000000000000004})") + // 3. try adding to back with reference to self + cycleHead = &evmtypes.Head{ + Number: 1000, + Hash: common.BigToHash(big.NewInt(1000)), + ParentHash: common.BigToHash(big.NewInt(1000)), + } + assert.EqualError(t, heads.AddHeads(cycleHead), "cycle detected: newHeads reference itself newHead(Head{Number: 1000, Hash: 0x00000000000000000000000000000000000000000000000000000000000003e8, ParentHash: 0x00000000000000000000000000000000000000000000000000000000000003e8})") + }) } func TestHeads_MarkFinalized(t *testing.T) { @@ -110,7 +138,7 @@ func TestHeads_MarkFinalized(t *testing.T) { heads := headtracker.NewHeads() // create chain - // H0 <- H1 <- H2 <- H3 <- H4 <- H5 + // H0 <- H1 <- H2 <- H3 <- H4 <- H5 - Canonical // \ \ // H1Uncle H2Uncle // @@ -127,35 +155,80 @@ func TestHeads_MarkFinalized(t *testing.T) { h5 := newHead(5, h4.Hash) h2Uncle := newHead(2, h1.Hash) - allHeads := []*evmtypes.Head{h0, h1, h1Uncle, h2, h2Uncle, h3, h4, h5} - heads.AddHeads(allHeads...) + assert.NoError(t, heads.AddHeads(h0, h1, h1Uncle, h2, h2Uncle, h3, h4, h5)) // mark h3 and all ancestors as finalized require.True(t, heads.MarkFinalized(h3.Hash, h1.BlockNumber()), "expected MarkFinalized succeed") - // original heads remain unchanged - for _, h := range allHeads { - assert.False(t, h.IsFinalized, "expected original heads to remain unfinalized") - } - // h0 is too old. It should not be available directly or through its children assert.Nil(t, heads.HeadByHash(h0.Hash)) - assert.Nil(t, heads.HeadByHash(h1.Hash).Parent) - assert.Nil(t, heads.HeadByHash(h1Uncle.Hash).Parent) - assert.Nil(t, heads.HeadByHash(h2Uncle.Hash).Parent.Parent) + assert.Nil(t, heads.HeadByHash(h1.Hash).Parent.Load()) + assert.Nil(t, heads.HeadByHash(h1Uncle.Hash).Parent.Load()) + assert.Nil(t, heads.HeadByHash(h2Uncle.Hash).Parent.Load().Parent.Load()) require.False(t, heads.MarkFinalized(utils.NewHash(), 0), "expected false if finalized hash was not found in existing LatestHead chain") ensureProperFinalization := func(t *testing.T) { t.Helper() for _, head := range []*evmtypes.Head{h5, h4} { - require.False(t, heads.HeadByHash(head.Hash).IsFinalized, "expected h4-h5 not to be finalized", head.BlockNumber()) + require.False(t, heads.HeadByHash(head.Hash).IsFinalized.Load(), "expected h4-h5 not to be finalized", head.BlockNumber()) } for _, head := range []*evmtypes.Head{h3, h2, h1} { - require.True(t, heads.HeadByHash(head.Hash).IsFinalized, "expected h3 and all ancestors to be finalized", head.BlockNumber()) + require.True(t, heads.HeadByHash(head.Hash).IsFinalized.Load(), "expected h3 and all ancestors to be finalized", head.BlockNumber()) } - require.False(t, heads.HeadByHash(h2Uncle.Hash).IsFinalized, "expected uncle block not to be marked as finalized") + require.False(t, heads.HeadByHash(h2Uncle.Hash).IsFinalized.Load(), "expected uncle block not to be marked as finalized") } t.Run("blocks were correctly marked as finalized", ensureProperFinalization) - heads.AddHeads(h0, h1, h2, h2Uncle, h3, h4, h5) + assert.NoError(t, heads.AddHeads(h0, h1, h2, h2Uncle, h3, h4, h5)) t.Run("blocks remain finalized after re adding them to the Heads", ensureProperFinalization) + + // ensure that IsFinalized is propagated, when older blocks are added + // 1. remove all blocks older than 3 + heads.MarkFinalized(h3.Hash, 3) + // 2. ensure that h2 and h1 are no longer present + assert.Nil(t, heads.HeadByHash(h2.Hash)) + assert.Nil(t, heads.HeadByHash(h1.Hash)) + // 3. add blocks back, starting from older + assert.NoError(t, heads.AddHeads(h1)) + assert.False(t, heads.HeadByHash(h1.Hash).IsFinalized.Load(), "expected h1 to not be finalized as it was not explicitly marked and there no path to h3") + assert.NoError(t, heads.AddHeads(h2)) + // 4. now h2 and h1 must be marked as finalized + assert.True(t, heads.HeadByHash(h1.Hash).IsFinalized.Load()) + assert.True(t, heads.HeadByHash(h2.Hash).IsFinalized.Load()) +} + +func BenchmarkEarliestHeadInChain(b *testing.B) { + const latestBlockNum = 200_000 + blocks := NewBlocks(b, latestBlockNum+1) + b.ResetTimer() + for i := 0; i < b.N; i++ { + latest := blocks.Head(latestBlockNum) + earliest := latest.EarliestHeadInChain() + // perform sanity check + assert.NotEqual(b, latest.BlockNumber(), earliest.BlockNumber()) + assert.NotEqual(b, latest.BlockHash(), earliest.BlockHash()) + } +} + +// BenchmarkSimulated_Backfill - benchmarks AddHeads & MarkFinalized as if it was performed by HeadTracker's backfill +func BenchmarkHeads_SimulatedBackfill(b *testing.B) { + makeHash := func(n int64) common.Hash { + return common.BigToHash(big.NewInt(n)) + } + makeHead := func(n int64) *evmtypes.Head { + return &evmtypes.Head{Number: n, Hash: makeHash(n), ParentHash: makeHash(n - 1)} + } + + const finalityDepth = 16_000 // observed value on Arbitrum + // populate with initial values + heads := headtracker.NewHeads() + for i := int64(1); i <= finalityDepth; i++ { + assert.NoError(b, heads.AddHeads(makeHead(i))) + } + heads.MarkFinalized(makeHash(1), 1) + // focus benchmark on processing of a new latest block + b.ResetTimer() + for i := int64(1); i <= int64(b.N); i++ { + assert.NoError(b, heads.AddHeads(makeHead(finalityDepth+i))) + heads.MarkFinalized(makeHash(i), i) + } } diff --git a/core/chains/evm/headtracker/heap.go b/core/chains/evm/headtracker/heap.go new file mode 100644 index 0000000000..572ed541df --- /dev/null +++ b/core/chains/evm/headtracker/heap.go @@ -0,0 +1,35 @@ +package headtracker + +import evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + +type headsHeap struct { + values []*evmtypes.Head +} + +func (h *headsHeap) Len() int { + return len(h.values) +} + +func (h *headsHeap) Swap(i, j int) { + h.values[i], h.values[j] = h.values[j], h.values[i] +} + +func (h *headsHeap) Less(i, j int) bool { + return h.values[i].Number < h.values[j].Number +} + +func (h *headsHeap) Pop() any { + n := len(h.values) - 1 + old := h.values[n] + h.values[n] = nil + h.values = h.values[:n] + return old +} + +func (h *headsHeap) Push(v any) { + h.values = append(h.values, v.(*evmtypes.Head)) +} + +func (h *headsHeap) Peek() *evmtypes.Head { + return h.values[0] +} diff --git a/core/chains/evm/headtracker/types/types.go b/core/chains/evm/headtracker/types/types.go index 1a03f3cec6..ca5a79fc68 100644 --- a/core/chains/evm/headtracker/types/types.go +++ b/core/chains/evm/headtracker/types/types.go @@ -2,10 +2,13 @@ package types import ( "context" + "math/big" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink/v2/common/headtracker" + htrktypes "github.com/smartcontractkit/chainlink/v2/common/headtracker/types" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) @@ -22,4 +25,5 @@ type ( HeadTrackable = headtracker.HeadTrackable[*evmtypes.Head, common.Hash] HeadListener = headtracker.HeadListener[*evmtypes.Head, common.Hash] HeadBroadcaster = headtracker.HeadBroadcaster[*evmtypes.Head, common.Hash] + Client = htrktypes.Client[*evmtypes.Head, ethereum.Subscription, *big.Int, common.Hash] ) diff --git a/core/chains/evm/log/broadcaster.go b/core/chains/evm/log/broadcaster.go index e7f02d1199..3e37678bee 100644 --- a/core/chains/evm/log/broadcaster.go +++ b/core/chains/evm/log/broadcaster.go @@ -590,7 +590,7 @@ func (b *broadcaster) onNewHeads() { b.logger.Errorf("Failed to query for log broadcasts, %v", err) return } - b.registrations.sendLogs(ctx, logs, *latestHead, broadcasts, b.orm) + b.registrations.sendLogs(ctx, logs, latestHead, broadcasts, b.orm) if err := b.orm.SetPendingMinBlock(ctx, nil); err != nil { b.logger.Errorw("Failed to set pending broadcasts number null", "err", err) } @@ -605,7 +605,7 @@ func (b *broadcaster) onNewHeads() { return } - b.registrations.sendLogs(ctx, logs, *latestHead, broadcasts, b.orm) + b.registrations.sendLogs(ctx, logs, latestHead, broadcasts, b.orm) } newMin := b.logPool.deleteOlderLogs(keptDepth) if err := b.orm.SetPendingMinBlock(ctx, newMin); err != nil { diff --git a/core/chains/evm/log/registrations.go b/core/chains/evm/log/registrations.go index 68dd93b9d8..01104349a6 100644 --- a/core/chains/evm/log/registrations.go +++ b/core/chains/evm/log/registrations.go @@ -11,6 +11,7 @@ import ( pkgerrors "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-common/pkg/logger" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" @@ -215,7 +216,7 @@ func (r *registrations) isAddressRegistered(address common.Address) bool { return false } -func (r *registrations) sendLogs(ctx context.Context, logsToSend []logsOnBlock, latestHead evmtypes.Head, broadcasts []LogBroadcast, bc broadcastCreator) { +func (r *registrations) sendLogs(ctx context.Context, logsToSend []logsOnBlock, latestHead *evmtypes.Head, broadcasts []LogBroadcast, bc broadcastCreator) { broadcastsExisting := make(map[LogBroadcastAsKey]bool) for _, b := range broadcasts { broadcastsExisting[b.AsKey()] = b.Consumed @@ -387,7 +388,7 @@ type broadcastCreator interface { CreateBroadcast(ctx context.Context, blockHash common.Hash, blockNumber uint64, logIndex uint, jobID int32) error } -func (r *handler) sendLog(ctx context.Context, log types.Log, latestHead evmtypes.Head, +func (r *handler) sendLog(ctx context.Context, log types.Log, latestHead *evmtypes.Head, broadcasts map[LogBroadcastAsKey]bool, bc broadcastCreator, logger logger.Logger) { diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index 360511951e..dd7e0c5242 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -1037,7 +1037,7 @@ func (lp *logPoller) findBlockAfterLCA(ctx context.Context, current *evmtypes.He if err != nil { return nil, err } - blockAfterLCA := *current + blockAfterLCA := current // We expect reorgs up to the block after latestFinalizedBlock // We loop via parent instead of current so current always holds the LCA+1. // If the parent block number becomes < the first finalized block our reorg is too deep. @@ -1049,10 +1049,10 @@ func (lp *logPoller) findBlockAfterLCA(ctx context.Context, current *evmtypes.He } if parent.Hash == ourParentBlockHash.BlockHash { // If we do have the blockhash, return blockAfterLCA - return &blockAfterLCA, nil + return blockAfterLCA, nil } // Otherwise get a new parent and update blockAfterLCA. - blockAfterLCA = *parent + blockAfterLCA = parent parent, err = lp.ec.HeadByHash(ctx, parent.ParentHash) if err != nil { return nil, err diff --git a/core/chains/evm/logpoller/log_poller_internal_test.go b/core/chains/evm/logpoller/log_poller_internal_test.go index ca1bd72dd6..620bbf14f4 100644 --- a/core/chains/evm/logpoller/log_poller_internal_test.go +++ b/core/chains/evm/logpoller/log_poller_internal_test.go @@ -569,7 +569,8 @@ func Test_latestBlockAndFinalityDepth(t *testing.T) { }) t.Run("headTracker returns valid chain", func(t *testing.T) { headTracker := htMocks.NewHeadTracker[*evmtypes.Head, common.Hash](t) - finalizedBlock := &evmtypes.Head{Number: 2, IsFinalized: true} + finalizedBlock := &evmtypes.Head{Number: 2} + finalizedBlock.IsFinalized.Store(true) head := &evmtypes.Head{Number: 10} headTracker.On("LatestAndFinalizedBlock", mock.Anything).Return(head, finalizedBlock, nil) diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index dc8e30f5f4..d63f0cf1de 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -148,27 +148,28 @@ func TestEthConfirmer_Lifecycle(t *testing.T) { err = ec.Start(ctx) require.Error(t, err) - latestFinalizedHead := evmtypes.Head{ - Number: 8, - Hash: testutils.NewHash(), - Parent: nil, - IsFinalized: true, // We are guaranteed to receive a latestFinalizedHead. + latestFinalizedHead := &evmtypes.Head{ + Number: 8, + Hash: testutils.NewHash(), } + // We are guaranteed to receive a latestFinalizedHead. + latestFinalizedHead.IsFinalized.Store(true) - head := evmtypes.Head{ + h9 := &evmtypes.Head{ + Hash: testutils.NewHash(), + Number: 9, + } + h9.Parent.Store(latestFinalizedHead) + head := &evmtypes.Head{ Hash: testutils.NewHash(), Number: 10, - Parent: &evmtypes.Head{ - Hash: testutils.NewHash(), - Number: 9, - Parent: &latestFinalizedHead, - }, } + head.Parent.Store(h9) - ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(&head, nil).Once() - ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&latestFinalizedHead, nil).Once() + ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(head, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(latestFinalizedHead, nil).Once() - err = ec.ProcessHead(ctx, &head) + err = ec.ProcessHead(ctx, head) require.NoError(t, err) // Can successfully close once err = ec.Close() @@ -2742,34 +2743,33 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { ec := newEthConfirmer(t, txStore, ethClient, gconfig, config, ethKeyStore, nil) latestFinalizedHead := evmtypes.Head{ - Number: 8, - Hash: testutils.NewHash(), - Parent: nil, - IsFinalized: false, // We are guaranteed to receive a latestFinalizedHead. + Number: 8, + Hash: testutils.NewHash(), } - head := evmtypes.Head{ + h8 := &evmtypes.Head{ + Number: 8, + Hash: testutils.NewHash(), + } + h9 := &evmtypes.Head{ + Hash: testutils.NewHash(), + Number: 9, + } + h9.Parent.Store(h8) + head := &evmtypes.Head{ Hash: testutils.NewHash(), Number: 10, - Parent: &evmtypes.Head{ - Hash: testutils.NewHash(), - Number: 9, - Parent: &evmtypes.Head{ - Number: 8, - Hash: testutils.NewHash(), - Parent: nil, - }, - }, } + head.Parent.Store(h9) t.Run("does nothing if there aren't any transactions", func(t *testing.T) { - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), head, latestFinalizedHead.BlockNumber())) }) t.Run("does nothing to unconfirmed transactions", func(t *testing.T) { etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress) // Do the thing - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -2781,7 +2781,7 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { mustInsertEthReceipt(t, txStore, head.Number, head.Hash, etx.TxAttempts[0].Hash) // Do the thing - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -2791,10 +2791,10 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { t.Run("does nothing to confirmed transactions that only have receipts older than the start of the chain", func(t *testing.T) { etx := cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 3, 1, fromAddress) // Add receipt that is older than the lowest block of the chain - mustInsertEthReceipt(t, txStore, head.Parent.Parent.Number-1, testutils.NewHash(), etx.TxAttempts[0].Hash) + mustInsertEthReceipt(t, txStore, h8.Number-1, testutils.NewHash(), etx.TxAttempts[0].Hash) // Do the thing - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -2805,7 +2805,7 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { etx := cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 4, 1, fromAddress) attempt := etx.TxAttempts[0] // Include one within head height but a different block hash - mustInsertEthReceipt(t, txStore, head.Parent.Number, testutils.NewHash(), attempt.Hash) + mustInsertEthReceipt(t, txStore, head.Parent.Load().Number, testutils.NewHash(), attempt.Hash) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { atx, err := txmgr.GetGethSignedTx(attempt.SignedRawTx) @@ -2815,7 +2815,7 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { }), fromAddress).Return(commonclient.Successful, nil).Once() // Do the thing - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -2830,15 +2830,15 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { attempt := etx.TxAttempts[0] attemptHash := attempt.Hash // Add receipt that is older than the lowest block of the chain - mustInsertEthReceipt(t, txStore, head.Parent.Parent.Number-1, testutils.NewHash(), attemptHash) + mustInsertEthReceipt(t, txStore, h8.Number-1, testutils.NewHash(), attemptHash) // Include one within head height but a different block hash - mustInsertEthReceipt(t, txStore, head.Parent.Number, testutils.NewHash(), attemptHash) + mustInsertEthReceipt(t, txStore, head.Parent.Load().Number, testutils.NewHash(), attemptHash) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.Anything, fromAddress).Return( commonclient.Successful, nil).Once() // Do the thing - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -2862,9 +2862,9 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { require.NoError(t, txStore.InsertTxAttempt(ctx, &attempt3)) // Receipt is within head height but a different block hash - mustInsertEthReceipt(t, txStore, head.Parent.Number, testutils.NewHash(), attempt2.Hash) + mustInsertEthReceipt(t, txStore, head.Parent.Load().Number, testutils.NewHash(), attempt2.Hash) // Receipt is within head height but a different block hash - mustInsertEthReceipt(t, txStore, head.Parent.Number, testutils.NewHash(), attempt3.Hash) + mustInsertEthReceipt(t, txStore, head.Parent.Load().Number, testutils.NewHash(), attempt3.Hash) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { s, err := txmgr.GetGethSignedTx(attempt3.SignedRawTx) @@ -2873,7 +2873,7 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { }), fromAddress).Return(commonclient.Successful, nil).Once() // Do the thing - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -2893,7 +2893,7 @@ func TestEthConfirmer_EnsureConfirmedTransactionsInLongestChain(t *testing.T) { // Add receipt that is higher than head mustInsertEthReceipt(t, txStore, head.Number+1, testutils.NewHash(), attempt.Hash) - require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), &head, latestFinalizedHead.BlockNumber())) + require.NoError(t, ec.EnsureConfirmedTransactionsInLongestChain(tests.Context(t), head, latestFinalizedHead.BlockNumber())) etx, err := txStore.FindTxWithAttempts(ctx, etx.ID) require.NoError(t, err) @@ -3020,19 +3020,20 @@ func TestEthConfirmer_ResumePendingRuns(t *testing.T) { evmcfg := evmtest.NewChainScopedConfig(t, config) + h8 := &evmtypes.Head{ + Number: 8, + Hash: testutils.NewHash(), + } + h9 := &evmtypes.Head{ + Hash: testutils.NewHash(), + Number: 9, + } + h9.Parent.Store(h8) head := evmtypes.Head{ Hash: testutils.NewHash(), Number: 10, - Parent: &evmtypes.Head{ - Hash: testutils.NewHash(), - Number: 9, - Parent: &evmtypes.Head{ - Number: 8, - Hash: testutils.NewHash(), - Parent: nil, - }, - }, } + head.Parent.Store(h9) minConfirmations := int64(2) @@ -3254,10 +3255,10 @@ func TestEthConfirmer_ProcessStuckTransactions(t *testing.T) { // Update tx to signal callback once it is identified as terminally stuck pgtest.MustExec(t, db, `UPDATE evm.txes SET pipeline_task_run_id = $1, signal_callback = TRUE WHERE id = $2`, uuid.New(), tx.ID) head := evmtypes.Head{ - Hash: testutils.NewHash(), - Number: blockNum, - IsFinalized: true, + Hash: testutils.NewHash(), + Number: blockNum, } + head.IsFinalized.Store(true) ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(&head, nil).Once() ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&head, nil).Once() @@ -3282,10 +3283,10 @@ func TestEthConfirmer_ProcessStuckTransactions(t *testing.T) { require.Equal(t, bumpedFee.Legacy, latestAttempt.TxFee.Legacy) head = evmtypes.Head{ - Hash: testutils.NewHash(), - Number: blockNum + 1, - IsFinalized: true, + Hash: testutils.NewHash(), + Number: blockNum + 1, } + head.IsFinalized.Store(true) ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(&head, nil).Once() ethClient.On("LatestFinalizedBlock", mock.Anything).Return(&head, nil).Once() ethClient.On("SequenceAt", mock.Anything, mock.Anything, mock.Anything).Return(evmtypes.Nonce(1), nil) diff --git a/core/chains/evm/txmgr/evm_tx_store_test.go b/core/chains/evm/txmgr/evm_tx_store_test.go index c711c2788e..e47387fb8d 100644 --- a/core/chains/evm/txmgr/evm_tx_store_test.go +++ b/core/chains/evm/txmgr/evm_tx_store_test.go @@ -628,19 +628,20 @@ func TestORM_FindTxesPendingCallback(t *testing.T) { pgtest.MustExec(t, db, `SET CONSTRAINTS fk_pipeline_runs_pruning_key DEFERRED`) pgtest.MustExec(t, db, `SET CONSTRAINTS pipeline_runs_pipeline_spec_id_fkey DEFERRED`) + h8 := &evmtypes.Head{ + Number: 8, + Hash: testutils.NewHash(), + } + h9 := &evmtypes.Head{ + Hash: testutils.NewHash(), + Number: 9, + } + h9.Parent.Store(h8) head := evmtypes.Head{ - Hash: utils.NewHash(), + Hash: testutils.NewHash(), Number: 10, - Parent: &evmtypes.Head{ - Hash: utils.NewHash(), - Number: 9, - Parent: &evmtypes.Head{ - Number: 8, - Hash: utils.NewHash(), - Parent: nil, - }, - }, } + head.Parent.Store(h9) minConfirmations := int64(2) @@ -792,19 +793,20 @@ func TestORM_FindTransactionsConfirmedInBlockRange(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) + h8 := &evmtypes.Head{ + Number: 8, + Hash: testutils.NewHash(), + } + h9 := &evmtypes.Head{ + Hash: testutils.NewHash(), + Number: 9, + } + h9.Parent.Store(h8) head := evmtypes.Head{ - Hash: utils.NewHash(), + Hash: testutils.NewHash(), Number: 10, - Parent: &evmtypes.Head{ - Hash: utils.NewHash(), - Number: 9, - Parent: &evmtypes.Head{ - Number: 8, - Hash: utils.NewHash(), - Parent: nil, - }, - }, } + head.Parent.Store(h9) t.Run("find all transactions confirmed in range", func(t *testing.T) { etx_8 := mustInsertConfirmedEthTxWithReceipt(t, txStore, fromAddress, 700, 8) diff --git a/core/chains/evm/txmgr/finalizer_test.go b/core/chains/evm/txmgr/finalizer_test.go index f83a53bf49..b91121d773 100644 --- a/core/chains/evm/txmgr/finalizer_test.go +++ b/core/chains/evm/txmgr/finalizer_test.go @@ -39,15 +39,16 @@ func TestFinalizer_MarkTxFinalized(t *testing.T) { rpcBatchSize := uint32(1) ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) + h99 := &evmtypes.Head{ + Hash: utils.NewHash(), + Number: 99, + } + h99.IsFinalized.Store(true) head := &evmtypes.Head{ Hash: utils.NewHash(), Number: 100, - Parent: &evmtypes.Head{ - Hash: utils.NewHash(), - Number: 99, - IsFinalized: true, - }, } + head.Parent.Store(h99) t.Run("returns not finalized for tx with receipt newer than finalized block", func(t *testing.T) { finalizer := txmgr.NewEvmFinalizer(logger.Test(t), testutils.FixtureChainID, rpcBatchSize, txStore, ethClient, ht) @@ -71,7 +72,7 @@ func TestFinalizer_MarkTxFinalized(t *testing.T) { // Insert receipt for unfinalized block num mustInsertEthReceipt(t, txStore, head.Number, head.Hash, attemptHash) ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() - ethClient.On("LatestFinalizedBlock", mock.Anything).Return(head.Parent, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(head.Parent.Load(), nil).Once() err := finalizer.ProcessHead(ctx, head) require.NoError(t, err) tx, err = txStore.FindTxWithIdempotencyKey(ctx, idempotencyKey, testutils.FixtureChainID) @@ -99,9 +100,9 @@ func TestFinalizer_MarkTxFinalized(t *testing.T) { } attemptHash := insertTxAndAttemptWithIdempotencyKey(t, txStore, tx, idempotencyKey) // Insert receipt for finalized block num - mustInsertEthReceipt(t, txStore, head.Parent.Number, utils.NewHash(), attemptHash) + mustInsertEthReceipt(t, txStore, head.Parent.Load().Number, utils.NewHash(), attemptHash) ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() - ethClient.On("LatestFinalizedBlock", mock.Anything).Return(head.Parent, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(head.Parent.Load(), nil).Once() err := finalizer.ProcessHead(ctx, head) require.NoError(t, err) tx, err = txStore.FindTxWithIdempotencyKey(ctx, idempotencyKey, testutils.FixtureChainID) @@ -129,9 +130,9 @@ func TestFinalizer_MarkTxFinalized(t *testing.T) { } attemptHash := insertTxAndAttemptWithIdempotencyKey(t, txStore, tx, idempotencyKey) // Insert receipt for finalized block num - mustInsertEthReceipt(t, txStore, head.Parent.Number, head.Parent.Hash, attemptHash) + mustInsertEthReceipt(t, txStore, head.Parent.Load().Number, head.Parent.Load().Hash, attemptHash) ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() - ethClient.On("LatestFinalizedBlock", mock.Anything).Return(head.Parent, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(head.Parent.Load(), nil).Once() err := finalizer.ProcessHead(ctx, head) require.NoError(t, err) tx, err = txStore.FindTxWithIdempotencyKey(ctx, idempotencyKey, testutils.FixtureChainID) @@ -160,7 +161,7 @@ func TestFinalizer_MarkTxFinalized(t *testing.T) { attemptHash := insertTxAndAttemptWithIdempotencyKey(t, txStore, tx, idempotencyKey) // Insert receipt for finalized block num receiptBlockHash1 := utils.NewHash() - mustInsertEthReceipt(t, txStore, head.Parent.Number-2, receiptBlockHash1, attemptHash) + mustInsertEthReceipt(t, txStore, head.Parent.Load().Number-2, receiptBlockHash1, attemptHash) idempotencyKey = uuid.New().String() nonce = evmtypes.Nonce(1) tx = &txmgr.Tx{ @@ -176,7 +177,7 @@ func TestFinalizer_MarkTxFinalized(t *testing.T) { attemptHash = insertTxAndAttemptWithIdempotencyKey(t, txStore, tx, idempotencyKey) // Insert receipt for finalized block num receiptBlockHash2 := utils.NewHash() - mustInsertEthReceipt(t, txStore, head.Parent.Number-1, receiptBlockHash2, attemptHash) + mustInsertEthReceipt(t, txStore, head.Parent.Load().Number-1, receiptBlockHash2, attemptHash) // Separate batch calls will be made for each tx due to RPC batch size set to 1 when finalizer initialized above ethClient.On("BatchCallContext", mock.Anything, mock.IsType([]rpc.BatchElem{})).Run(func(args mock.Arguments) { rpcElements := args.Get(1).([]rpc.BatchElem) @@ -186,20 +187,20 @@ func TestFinalizer_MarkTxFinalized(t *testing.T) { require.Equal(t, false, rpcElements[0].Args[1]) reqBlockNum := rpcElements[0].Args[0].(string) - req1BlockNum := hexutil.EncodeBig(big.NewInt(head.Parent.Number - 2)) - req2BlockNum := hexutil.EncodeBig(big.NewInt(head.Parent.Number - 1)) + req1BlockNum := hexutil.EncodeBig(big.NewInt(head.Parent.Load().Number - 2)) + req2BlockNum := hexutil.EncodeBig(big.NewInt(head.Parent.Load().Number - 1)) var headResult evmtypes.Head if req1BlockNum == reqBlockNum { - headResult = evmtypes.Head{Number: head.Parent.Number - 2, Hash: receiptBlockHash1} + headResult = evmtypes.Head{Number: head.Parent.Load().Number - 2, Hash: receiptBlockHash1} } else if req2BlockNum == reqBlockNum { - headResult = evmtypes.Head{Number: head.Parent.Number - 1, Hash: receiptBlockHash2} + headResult = evmtypes.Head{Number: head.Parent.Load().Number - 1, Hash: receiptBlockHash2} } else { require.Fail(t, "unrecognized block hash") } rpcElements[0].Result = &headResult }).Return(nil).Twice() ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() - ethClient.On("LatestFinalizedBlock", mock.Anything).Return(head.Parent, nil).Once() + ethClient.On("LatestFinalizedBlock", mock.Anything).Return(head.Parent.Load(), nil).Once() err := finalizer.ProcessHead(ctx, head) require.NoError(t, err) tx, err = txStore.FindTxWithIdempotencyKey(ctx, idempotencyKey, testutils.FixtureChainID) diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index d4bfbffd12..e943796031 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -613,20 +613,21 @@ func TestTxm_GetTransactionStatus(t *testing.T) { gcfg := configtest.NewTestGeneralConfig(t) cfg := evmtest.NewChainScopedConfig(t, gcfg) + h99 := &evmtypes.Head{ + Hash: utils.NewHash(), + Number: 99, + } + h99.IsFinalized.Store(true) head := &evmtypes.Head{ Hash: utils.NewHash(), Number: 100, - Parent: &evmtypes.Head{ - Hash: utils.NewHash(), - Number: 99, - IsFinalized: true, - }, } + head.Parent.Store(h99) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("PendingNonceAt", mock.Anything, mock.Anything).Return(uint64(0), nil).Maybe() ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() - ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head.Parent, nil).Once() + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head.Parent.Load(), nil).Once() ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil) feeEstimator := gasmocks.NewEvmFeeEstimator(t) feeEstimator.On("Start", mock.Anything).Return(nil).Once() @@ -755,7 +756,7 @@ func TestTxm_GetTransactionStatus(t *testing.T) { err = txStore.InsertTxAttempt(ctx, &attempt) require.NoError(t, err) // Insert receipt for finalized block num - mustInsertEthReceipt(t, txStore, head.Parent.Number, head.Parent.Hash, attempt.Hash) + mustInsertEthReceipt(t, txStore, head.Parent.Load().Number, head.Parent.Load().Hash, attempt.Hash) state, err := txm.GetTransactionStatus(ctx, idempotencyKey) require.NoError(t, err) require.Equal(t, commontypes.Finalized, state) diff --git a/core/chains/evm/types/head_test.go b/core/chains/evm/types/head_test.go index 97c536a344..5d887c43c8 100644 --- a/core/chains/evm/types/head_test.go +++ b/core/chains/evm/types/head_test.go @@ -9,6 +9,11 @@ import ( func TestHead_LatestFinalizedHead(t *testing.T) { t.Parallel() + newFinalizedHead := func(num int64) *Head { + result := &Head{Number: num} + result.IsFinalized.Store(true) + return result + } cases := []struct { Name string Head *Head @@ -21,17 +26,17 @@ func TestHead_LatestFinalizedHead(t *testing.T) { }, { Name: "Chain without finalized returns nil", - Head: &Head{Parent: &Head{Parent: &Head{}}}, + Head: sliceToChain(&Head{}, &Head{}, &Head{}), Finalized: nil, }, { Name: "Returns head if it's finalized", - Head: &Head{Number: 2, IsFinalized: true, Parent: &Head{Number: 1, IsFinalized: true}}, + Head: sliceToChain(newFinalizedHead(2), newFinalizedHead(1)), Finalized: &Head{Number: 2}, }, { Name: "Returns first block in chain if it's finalized", - Head: &Head{Number: 3, IsFinalized: false, Parent: &Head{Number: 2, IsFinalized: true, Parent: &Head{Number: 1, IsFinalized: true}}}, + Head: sliceToChain(&Head{Number: 3}, newFinalizedHead(2), newFinalizedHead(1)), Finalized: &Head{Number: 2}, }, } @@ -48,3 +53,43 @@ func TestHead_LatestFinalizedHead(t *testing.T) { }) } } + +func TestHead_ChainString(t *testing.T) { + cases := []struct { + Name string + Chain *Head + ExpectedResult string + }{ + { + Name: "Empty chain", + ExpectedResult: "->nil", + }, + { + Name: "Single head", + Chain: &Head{Number: 1}, + ExpectedResult: "Head{Number: 1, Hash: 0x0000000000000000000000000000000000000000000000000000000000000000, ParentHash: 0x0000000000000000000000000000000000000000000000000000000000000000}->nil", + }, + { + Name: "Multiple heads", + Chain: sliceToChain(&Head{Number: 1}, &Head{Number: 2}, &Head{Number: 3}), + ExpectedResult: "Head{Number: 1, Hash: 0x0000000000000000000000000000000000000000000000000000000000000000, ParentHash: 0x0000000000000000000000000000000000000000000000000000000000000000}->Head{Number: 2, Hash: 0x0000000000000000000000000000000000000000000000000000000000000000, ParentHash: 0x0000000000000000000000000000000000000000000000000000000000000000}->Head{Number: 3, Hash: 0x0000000000000000000000000000000000000000000000000000000000000000, ParentHash: 0x0000000000000000000000000000000000000000000000000000000000000000}->nil", + }, + } + for _, testCase := range cases { + t.Run(testCase.Name, func(t *testing.T) { + assert.Equal(t, testCase.ExpectedResult, testCase.Chain.ChainString()) + }) + } +} + +func sliceToChain(heads ...*Head) *Head { + if len(heads) == 0 { + return nil + } + + for i := 1; i < len(heads); i++ { + heads[i-1].Parent.Store(heads[i]) + } + + return heads[0] +} diff --git a/core/chains/evm/types/models.go b/core/chains/evm/types/models.go index a9e5cd5841..1da8754cec 100644 --- a/core/chains/evm/types/models.go +++ b/core/chains/evm/types/models.go @@ -9,6 +9,7 @@ import ( "math/big" "regexp" "strings" + "sync/atomic" "time" "github.com/ethereum/go-ethereum/common" @@ -34,7 +35,7 @@ type Head struct { Number int64 L1BlockNumber sql.NullInt64 ParentHash common.Hash - Parent *Head + Parent atomic.Pointer[Head] EVMChainID *ubig.Big Timestamp time.Time CreatedAt time.Time @@ -44,7 +45,7 @@ type Head struct { StateRoot common.Hash Difficulty *big.Int TotalDifficulty *big.Int - IsFinalized bool + IsFinalized atomic.Bool } var _ commontypes.Head[common.Hash] = &Head{} @@ -74,10 +75,11 @@ func (h *Head) GetParentHash() common.Hash { } func (h *Head) GetParent() commontypes.Head[common.Hash] { - if h.Parent == nil { - return nil + if parent := h.Parent.Load(); parent != nil { + return parent } - return h.Parent + // explicitly return nil to avoid *Head(nil) + return nil } func (h *Head) GetTimestamp() time.Time { @@ -90,10 +92,11 @@ func (h *Head) BlockDifficulty() *big.Int { // EarliestInChain recurses through parents until it finds the earliest one func (h *Head) EarliestInChain() *Head { - for h.Parent != nil { - h = h.Parent + var earliestInChain *Head + for cur := h; cur != nil; cur = cur.Parent.Load() { + earliestInChain = cur } - return h + return earliestInChain } // EarliestHeadInChain recurses through parents until it finds the earliest one @@ -103,14 +106,10 @@ func (h *Head) EarliestHeadInChain() commontypes.Head[common.Hash] { // IsInChain returns true if the given hash matches the hash of a head in the chain func (h *Head) IsInChain(blockHash common.Hash) bool { - for { - if h.Hash == blockHash { + for cur := h; cur != nil; cur = cur.Parent.Load() { + if cur.Hash == blockHash { return true } - if h.Parent == nil { - break - } - h = h.Parent } return false } @@ -127,32 +126,19 @@ func (h *Head) HashAtHeight(blockNum int64) common.Hash { } func (h *Head) HeadAtHeight(blockNum int64) (commontypes.Head[common.Hash], error) { - for h != nil { - if h.Number == blockNum { - return h, nil + for cur := h; cur != nil; cur = cur.Parent.Load() { + if cur.Number == blockNum { + return cur, nil } - - h = h.Parent } return nil, fmt.Errorf("failed to find head at height %d", blockNum) } // ChainLength returns the length of the chain followed by recursively looking up parents func (h *Head) ChainLength() uint32 { - if h == nil { - return 0 - } - l := uint32(1) - - for { - if h.Parent == nil { - break - } + l := uint32(0) + for cur := h; cur != nil; cur = cur.Parent.Load() { l++ - if h == h.Parent { - panic("circular reference detected") - } - h = h.Parent } return l } @@ -160,29 +146,19 @@ func (h *Head) ChainLength() uint32 { // ChainHashes returns an array of block hashes by recursively looking up parents func (h *Head) ChainHashes() []common.Hash { var hashes []common.Hash - - for { - hashes = append(hashes, h.Hash) - if h.Parent == nil { - break - } - if h == h.Parent { - panic("circular reference detected") - } - h = h.Parent + for cur := h; cur != nil; cur = cur.Parent.Load() { + hashes = append(hashes, cur.Hash) } + return hashes } func (h *Head) LatestFinalizedHead() commontypes.Head[common.Hash] { - for h != nil { - if h.IsFinalized { - return h + for cur := h; cur != nil; cur = cur.Parent.Load() { + if cur.IsFinalized.Load() { + return cur } - - h = h.Parent } - return nil } @@ -200,18 +176,13 @@ func (h *Head) IsValid() bool { func (h *Head) ChainString() string { var sb strings.Builder - - for { - sb.WriteString(h.String()) - if h.Parent == nil { - break - } - if h == h.Parent { - panic("circular reference detected") + for cur := h; cur != nil; cur = cur.Parent.Load() { + if sb.Len() > 0 { + sb.WriteString("->") } - sb.WriteString("->") - h = h.Parent + sb.WriteString(cur.String()) } + sb.WriteString("->nil") return sb.String() } @@ -255,11 +226,11 @@ func (h *Head) AsSlice(k int) (heads []*Head) { if k < 1 || h == nil { return } - heads = make([]*Head, 1) - heads[0] = h - for len(heads) < k && h.Parent != nil { - h = h.Parent - heads = append(heads, h) + heads = make([]*Head, 0, k) + for cur := h; cur != nil; cur = cur.Parent.Load() { + if len(heads) < k { + heads = append(heads, cur) + } } return } diff --git a/core/chains/evm/types/models_test.go b/core/chains/evm/types/models_test.go index 6018d68f96..a54f1f58f5 100644 --- a/core/chains/evm/types/models_test.go +++ b/core/chains/evm/types/models_test.go @@ -116,11 +116,9 @@ func TestEthTxAttempt_GetSignedTx(t *testing.T) { } func TestHead_ChainLength(t *testing.T) { - head := evmtypes.Head{ - Parent: &evmtypes.Head{ - Parent: &evmtypes.Head{}, - }, - } + head := evmtypes.Head{} + head.Parent.Store(&evmtypes.Head{}) + head.Parent.Load().Parent.Store(&evmtypes.Head{}) assert.Equal(t, uint32(3), head.ChainLength()) @@ -134,12 +132,12 @@ func TestHead_AsSlice(t *testing.T) { } h2 := &evmtypes.Head{ Number: 2, - Parent: h1, } + h2.Parent.Store(h1) h3 := &evmtypes.Head{ Number: 3, - Parent: h2, } + h3.Parent.Store(h2) assert.Len(t, (*evmtypes.Head)(nil).AsSlice(0), 0) assert.Len(t, (*evmtypes.Head)(nil).AsSlice(1), 0) @@ -234,36 +232,35 @@ func TestSafeByteSlice_Error(t *testing.T) { } func TestHead_EarliestInChain(t *testing.T) { - head := evmtypes.Head{ + h3 := evmtypes.Head{ Number: 3, - Parent: &evmtypes.Head{ - Number: 2, - Parent: &evmtypes.Head{ - Number: 1, - }, - }, } + h2 := &evmtypes.Head{Number: 2} + h3.Parent.Store(h2) + h1 := &evmtypes.Head{Number: 1} + h2.Parent.Store(h1) - assert.Equal(t, int64(1), head.EarliestInChain().BlockNumber()) + assert.Equal(t, int64(1), h3.EarliestInChain().BlockNumber()) } func TestHead_HeadAtHeight(t *testing.T) { - expectedResult := &evmtypes.Head{ + h1 := &evmtypes.Head{ + Number: 1, + } + h2 := &evmtypes.Head{ Hash: common.BigToHash(big.NewInt(10)), Number: 2, - Parent: &evmtypes.Head{ - Number: 1, - }, } - head := evmtypes.Head{ + h2.Parent.Store(h1) + h3 := evmtypes.Head{ Number: 3, - Parent: expectedResult, } + h3.Parent.Store(h2) - headAtHeight, err := head.HeadAtHeight(2) + headAtHeight, err := h3.HeadAtHeight(2) require.NoError(t, err) - assert.Equal(t, expectedResult, headAtHeight) - _, err = head.HeadAtHeight(0) + assert.Equal(t, h2, headAtHeight) + _, err = h3.HeadAtHeight(0) assert.Error(t, err, "expected to get an error if head is not in the chain") } @@ -271,25 +268,27 @@ func TestHead_IsInChain(t *testing.T) { hash1 := utils.NewHash() hash2 := utils.NewHash() hash3 := utils.NewHash() - - head := evmtypes.Head{ - Number: 3, + h1 := &evmtypes.Head{ + Number: 1, + Hash: hash1, + } + h2 := &evmtypes.Head{ + Hash: hash2, + ParentHash: hash1, + Number: 2, + } + h2.Parent.Store(h1) + h3 := evmtypes.Head{ Hash: hash3, - Parent: &evmtypes.Head{ - Hash: hash2, - Number: 2, - Parent: &evmtypes.Head{ - Hash: hash1, - Number: 1, - }, - }, + Number: 3, } + h3.Parent.Store(h2) - assert.True(t, head.IsInChain(hash1)) - assert.True(t, head.IsInChain(hash2)) - assert.True(t, head.IsInChain(hash3)) - assert.False(t, head.IsInChain(utils.NewHash())) - assert.False(t, head.IsInChain(common.Hash{})) + assert.True(t, h3.IsInChain(hash1)) + assert.True(t, h3.IsInChain(hash2)) + assert.True(t, h3.IsInChain(hash3)) + assert.False(t, h3.IsInChain(utils.NewHash())) + assert.False(t, h3.IsInChain(common.Hash{})) } func TestTxReceipt_ReceiptIndicatesRunLogFulfillment(t *testing.T) { @@ -316,11 +315,11 @@ func TestHead_UnmarshalJSON(t *testing.T) { tests := []struct { name string json string - expected evmtypes.Head + expected *evmtypes.Head }{ {"geth", `{"difficulty":"0xf3a00","extraData":"0xd883010503846765746887676f312e372e318664617277696e","gasLimit":"0xffc001","gasUsed":"0x0","hash":"0x41800b5c3f1717687d85fc9018faac0a6e90b39deaa0b99e7fe4fe796ddeb26a","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0xd1aeb42885a43b72b518182ef893125814811048","mixHash":"0x0f98b15f1a4901a7e9204f3c500a7bd527b3fb2c3340e12176a44b83e414a69e","nonce":"0x0ece08ea8c49dfd9","number":"0x100","parentHash":"0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x218","stateRoot":"0xc7b01007a10da045eacb90385887dd0c38fcb5db7393006bdde24b93873c334b","timestamp":"0x58318da2","totalDifficulty":"0x1f3a00","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]}`, - evmtypes.Head{ + &evmtypes.Head{ Hash: common.HexToHash("0x41800b5c3f1717687d85fc9018faac0a6e90b39deaa0b99e7fe4fe796ddeb26a"), Number: 0x100, ParentHash: common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"), @@ -332,7 +331,7 @@ func TestHead_UnmarshalJSON(t *testing.T) { }, {"parity", `{"author":"0xd1aeb42885a43b72b518182ef893125814811048","difficulty":"0xf3a00","extraData":"0xd883010503846765746887676f312e372e318664617277696e","gasLimit":"0xffc001","gasUsed":"0x0","hash":"0x41800b5c3f1717687d85fc9018faac0a6e90b39deaa0b99e7fe4fe796ddeb26a","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0xd1aeb42885a43b72b518182ef893125814811048","mixHash":"0x0f98b15f1a4901a7e9204f3c500a7bd527b3fb2c3340e12176a44b83e414a69e","nonce":"0x0ece08ea8c49dfd9","number":"0x100","parentHash":"0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sealFields":["0xa00f98b15f1a4901a7e9204f3c500a7bd527b3fb2c3340e12176a44b83e414a69e","0x880ece08ea8c49dfd9"],"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x218","stateRoot":"0xc7b01007a10da045eacb90385887dd0c38fcb5db7393006bdde24b93873c334b","timestamp":"0x58318da2","totalDifficulty":"0x1f3a00","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]}`, - evmtypes.Head{ + &evmtypes.Head{ Hash: common.HexToHash("0x41800b5c3f1717687d85fc9018faac0a6e90b39deaa0b99e7fe4fe796ddeb26a"), Number: 0x100, ParentHash: common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"), @@ -344,7 +343,7 @@ func TestHead_UnmarshalJSON(t *testing.T) { }, {"arbitrum", `{"number":"0x15156","hash":"0x752dab43f7a2482db39227d46cd307623b26167841e2207e93e7566ab7ab7871","parentHash":"0x923ad1e27c1d43cb2d2fb09e26d2502ca4b4914a2e0599161d279c6c06117d34","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x71448077f5ce420a8e24db62d4d58e8d8e6ad2c7e76318868e089d41f7e0faf3","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x2c292672b8fc9d223647a2569e19721f0757c96a1421753a93e141f8e56cf504","miner":"0x0000000000000000000000000000000000000000","difficulty":"0x0","totalDifficulty":"0x0","extraData":"0x","size":"0x0","gasLimit":"0x11278208","gasUsed":"0x3d1fe9","timestamp":"0x60d0952d","transactions":["0xa1ea93556b93ed3b45cb24f21c8deb584e6a9049c35209242651bf3533c23b98","0xfc6593c45ba92351d17173aa1381e84734d252ab0169887783039212c4a41024","0x85ee9d04fd0ebb5f62191eeb53cb45d9c0945d43eba444c3548de2ac8421682f","0x50d120936473e5b75f6e04829ad4eeca7a1df7d3c5026ebb5d34af936a39b29c"],"uncles":[],"l1BlockNumber":"0x8652f9"}`, - evmtypes.Head{ + &evmtypes.Head{ Hash: common.HexToHash("0x752dab43f7a2482db39227d46cd307623b26167841e2207e93e7566ab7ab7871"), Number: 0x15156, ParentHash: common.HexToHash("0x923ad1e27c1d43cb2d2fb09e26d2502ca4b4914a2e0599161d279c6c06117d34"), @@ -357,7 +356,7 @@ func TestHead_UnmarshalJSON(t *testing.T) { }, {"arbitrum_empty_l1BlockNumber", `{"number":"0x15156","hash":"0x752dab43f7a2482db39227d46cd307623b26167841e2207e93e7566ab7ab7871","parentHash":"0x923ad1e27c1d43cb2d2fb09e26d2502ca4b4914a2e0599161d279c6c06117d34","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x71448077f5ce420a8e24db62d4d58e8d8e6ad2c7e76318868e089d41f7e0faf3","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x2c292672b8fc9d223647a2569e19721f0757c96a1421753a93e141f8e56cf504","miner":"0x0000000000000000000000000000000000000000","difficulty":"0x0","totalDifficulty":"0x0","extraData":"0x","size":"0x0","gasLimit":"0x11278208","gasUsed":"0x3d1fe9","timestamp":"0x60d0952d","transactions":["0xa1ea93556b93ed3b45cb24f21c8deb584e6a9049c35209242651bf3533c23b98","0xfc6593c45ba92351d17173aa1381e84734d252ab0169887783039212c4a41024","0x85ee9d04fd0ebb5f62191eeb53cb45d9c0945d43eba444c3548de2ac8421682f","0x50d120936473e5b75f6e04829ad4eeca7a1df7d3c5026ebb5d34af936a39b29c"],"uncles":[]}`, - evmtypes.Head{ + &evmtypes.Head{ Hash: common.HexToHash("0x752dab43f7a2482db39227d46cd307623b26167841e2207e93e7566ab7ab7871"), Number: 0x15156, ParentHash: common.HexToHash("0x923ad1e27c1d43cb2d2fb09e26d2502ca4b4914a2e0599161d279c6c06117d34"), @@ -370,7 +369,7 @@ func TestHead_UnmarshalJSON(t *testing.T) { }, {"not found", `null`, - evmtypes.Head{}, + &evmtypes.Head{}, }, } @@ -395,11 +394,11 @@ func TestHead_UnmarshalJSON(t *testing.T) { func TestHead_MarshalJSON(t *testing.T) { tests := []struct { name string - head evmtypes.Head + head *evmtypes.Head expected string }{ {"happy", - evmtypes.Head{ + &evmtypes.Head{ Hash: common.HexToHash("0x41800b5c3f1717687d85fc9018faac0a6e90b39deaa0b99e7fe4fe796ddeb26a"), Number: 0x100, ParentHash: common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"), @@ -411,7 +410,7 @@ func TestHead_MarshalJSON(t *testing.T) { `{"hash":"0x41800b5c3f1717687d85fc9018faac0a6e90b39deaa0b99e7fe4fe796ddeb26a","number":"0x100","parentHash":"0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d","timestamp":"0x58318da2","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","stateRoot":"0xc7b01007a10da045eacb90385887dd0c38fcb5db7393006bdde24b93873c334b"}`, }, {"empty", - evmtypes.Head{}, + &evmtypes.Head{}, `{"number":"0x0"}`, }, } diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 7d333d9401..b60dd8d73c 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -1389,7 +1389,7 @@ func (b *Blocks) ForkAt(t *testing.T, blockNum int64, numHashes int) *Blocks { } forked.Heads[blockNum].ParentHash = b.Heads[blockNum].ParentHash - forked.Heads[blockNum].Parent = b.Heads[blockNum].Parent + forked.Heads[blockNum].Parent.Store(b.Heads[blockNum].Parent.Load()) return forked } @@ -1403,10 +1403,10 @@ func (b *Blocks) NewHead(number uint64) *evmtypes.Head { Number: parent.Number + 1, Hash: evmutils.NewHash(), ParentHash: parent.Hash, - Parent: parent, Timestamp: time.Unix(parent.Number+1, 0), EVMChainID: ubig.New(&FixtureChainID), } + head.Parent.Store(parent) return head } @@ -1447,7 +1447,7 @@ func NewBlocks(t *testing.T, numHashes int) *Blocks { heads[i] = &evmtypes.Head{Hash: hash, Number: i, Timestamp: time.Unix(i, 0), EVMChainID: ubig.New(&FixtureChainID)} if i > 0 { parent := heads[i-1] - heads[i].Parent = parent + heads[i].Parent.Store(parent) heads[i].ParentHash = parent.Hash } } diff --git a/core/internal/cltest/factories.go b/core/internal/cltest/factories.go index c488dca94a..8f4b2260a0 100644 --- a/core/internal/cltest/factories.go +++ b/core/internal/cltest/factories.go @@ -25,6 +25,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils/jsonserializable" + txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" "github.com/smartcontractkit/chainlink/v2/core/auth" @@ -318,13 +319,13 @@ func MustGenerateRandomKeyState(_ testing.TB) ethkey.State { return ethkey.State{Address: NewEIP55Address()} } -func MustInsertHead(t *testing.T, ds sqlutil.DataSource, number int64) evmtypes.Head { +func MustInsertHead(t *testing.T, ds sqlutil.DataSource, number int64) *evmtypes.Head { h := evmtypes.NewHead(big.NewInt(number), evmutils.NewHash(), evmutils.NewHash(), 0, ubig.New(&FixtureChainID)) horm := headtracker.NewORM(FixtureChainID, ds) err := horm.IdempotentInsertHead(testutils.Context(t), &h) require.NoError(t, err) - return h + return &h } func MustInsertV2JobSpec(t *testing.T, db *sqlx.DB, transmitterAddress common.Address) job.Job { diff --git a/core/services/headreporter/telemetry_reporter_test.go b/core/services/headreporter/telemetry_reporter_test.go index 85bfea5866..6d7f4e3dde 100644 --- a/core/services/headreporter/telemetry_reporter_test.go +++ b/core/services/headreporter/telemetry_reporter_test.go @@ -22,18 +22,18 @@ import ( func Test_TelemetryReporter_NewHead(t *testing.T) { head := evmtypes.Head{ - Number: 42, - EVMChainID: ubig.NewI(100), - Hash: common.HexToHash("0x1010"), - Timestamp: time.UnixMilli(1000), - IsFinalized: false, - Parent: &evmtypes.Head{ - Number: 41, - Hash: common.HexToHash("0x1009"), - Timestamp: time.UnixMilli(999), - IsFinalized: true, - }, + Number: 42, + EVMChainID: ubig.NewI(100), + Hash: common.HexToHash("0x1010"), + Timestamp: time.UnixMilli(1000), + } + h41 := &evmtypes.Head{ + Number: 41, + Hash: common.HexToHash("0x1009"), + Timestamp: time.UnixMilli(999), } + h41.IsFinalized.Store(true) + head.Parent.Store(h41) requestBytes, err := proto.Marshal(&telem.HeadReportRequest{ ChainID: "100", Latest: &telem.Block{ @@ -42,9 +42,9 @@ func Test_TelemetryReporter_NewHead(t *testing.T) { Hash: head.Hash.Hex(), }, Finalized: &telem.Block{ - Timestamp: uint64(head.Parent.Timestamp.UTC().Unix()), + Timestamp: uint64(head.Parent.Load().Timestamp.UTC().Unix()), Number: 41, - Hash: head.Parent.Hash.Hex(), + Hash: head.Parent.Load().Hash.Hex(), }, }) assert.NoError(t, err) @@ -64,11 +64,10 @@ func Test_TelemetryReporter_NewHead(t *testing.T) { func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { head := evmtypes.Head{ - Number: 42, - EVMChainID: ubig.NewI(100), - Hash: common.HexToHash("0x1010"), - Timestamp: time.UnixMilli(1000), - IsFinalized: false, + Number: 42, + EVMChainID: ubig.NewI(100), + Hash: common.HexToHash("0x1010"), + Timestamp: time.UnixMilli(1000), } requestBytes, err := proto.Marshal(&telem.HeadReportRequest{ ChainID: "100", diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber.go index a5a0054217..21adc12d30 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber.go @@ -234,7 +234,7 @@ func (bs *BlockSubscriber) processHead(h *evmtypes.Head) { // head parent is a linked list with EVM finality depth // when re-org happens, new heads will have pointers to the new blocks i := int64(0) - for cp := h; cp != nil; cp = cp.Parent { + for cp := h; cp != nil; cp = cp.Parent.Load() { // we don't stop when a matching (block number/hash) entry is seen in the map because parent linked list may be // cut short during a re-org if head broadcaster backfill is not complete. This can cause some re-orged blocks // left in the map. for example, re-org happens for block 98, 99, 100. next head 101 from broadcaster has parent list diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber_test.go index fefbda77cd..bdcc37dc6b 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber_test.go @@ -310,23 +310,22 @@ func TestBlockSubscriber_Start(t *testing.T) { h97 := evmtypes.Head{ Number: 97, Hash: common.HexToHash("0xda2f9d1359eadd7b93338703adc07d942021a78195564038321ef53f23f87333"), - Parent: nil, } h98 := evmtypes.Head{ Number: 98, Hash: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), - Parent: &h97, } + h98.Parent.Store(&h97) h99 := evmtypes.Head{ Number: 99, Hash: common.HexToHash("0x9bc2b51e147f9cad05f1614b7f1d8181cb24c544cbcf841f3155e54e752a3b44"), - Parent: &h98, } + h99.Parent.Store(&h98) h100 := evmtypes.Head{ Number: 100, Hash: common.HexToHash("0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"), - Parent: &h99, } + h100.Parent.Store(&h99) // no subscribers yet bs.headC <- &h100 @@ -353,8 +352,8 @@ func TestBlockSubscriber_Start(t *testing.T) { h101 := &evmtypes.Head{ Number: 101, Hash: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), - Parent: &h100, } + h101.Parent.Store(&h100) bs.headC <- h101 time.Sleep(100 * time.Millisecond) @@ -387,24 +386,24 @@ func TestBlockSubscriber_Start(t *testing.T) { new99 := &evmtypes.Head{ Number: 99, Hash: common.HexToHash("0x70c03acc4ddbfb253ba41a25dc13fb21b25da8b63bcd1aa7fb55713d33a36c71"), - Parent: &h98, } + new99.Parent.Store(&h98) new100 := &evmtypes.Head{ Number: 100, Hash: common.HexToHash("0x8a876b62d252e63e16cf3487db3486c0a7c0a8e06bc3792a3b116c5ca480503f"), - Parent: new99, } + new100.Parent.Store(new99) new101 := &evmtypes.Head{ Number: 101, Hash: common.HexToHash("0x41b5842b8847dcf834e39556d2ac51cc7d960a7de9471ec504673d0038fd6c8e"), - Parent: new100, } + new101.Parent.Store(new100) new102 := &evmtypes.Head{ Number: 102, Hash: common.HexToHash("0x9ac1ebc307554cf1bcfcc2a49462278e89d6878d613a33df38a64d0aeac971b5"), - Parent: new101, } + new102.Parent.Store(new101) bs.headC <- new102 diff --git a/core/services/ocrcommon/arbitrum_block_translator_test.go b/core/services/ocrcommon/arbitrum_block_translator_test.go index fa6875fb79..6b9abc93bf 100644 --- a/core/services/ocrcommon/arbitrum_block_translator_test.go +++ b/core/services/ocrcommon/arbitrum_block_translator_test.go @@ -1,6 +1,7 @@ package ocrcommon_test import ( + "context" "database/sql" "math/big" mrand "math/rand" @@ -34,7 +35,7 @@ func TestArbitrumBlockTranslator_BinarySearch(t *testing.T) { var changedInL1Block int64 = 5541 latestBlock := blocks[1000] - client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(&latestBlock, nil).Once() + client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(latestBlock, nil).Once() from, to, err := abt.BinarySearch(ctx, changedInL1Block) require.NoError(t, err) @@ -51,11 +52,10 @@ func TestArbitrumBlockTranslator_BinarySearch(t *testing.T) { var changedInL1Block int64 = 42 latestBlock := blocks[1000] - client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(&latestBlock, nil).Once() + client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(latestBlock, nil).Once() - tmp := new(evmtypes.Head) - client.On("HeadByNumber", ctx, mock.AnythingOfType("*big.Int")).Return(tmp, nil).Run(func(args mock.Arguments) { - *tmp = blocks[args[1].(*big.Int).Int64()] + client.On("HeadByNumber", ctx, mock.AnythingOfType("*big.Int")).Return(func(_ context.Context, num *big.Int) (*evmtypes.Head, error) { + return blocks[num.Int64()], nil }) _, _, err := abt.BinarySearch(ctx, changedInL1Block) @@ -71,11 +71,10 @@ func TestArbitrumBlockTranslator_BinarySearch(t *testing.T) { var changedInL1Block int64 = 5043 latestBlock := blocks[1000] - client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(&latestBlock, nil).Once() + client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(latestBlock, nil).Once() - tmp := new(evmtypes.Head) - client.On("HeadByNumber", ctx, mock.AnythingOfType("*big.Int")).Return(tmp, nil).Run(func(args mock.Arguments) { - *tmp = blocks[args[1].(*big.Int).Int64()] + client.On("HeadByNumber", ctx, mock.AnythingOfType("*big.Int")).Return(func(_ context.Context, num *big.Int) (*evmtypes.Head, error) { + return blocks[num.Int64()], nil }) _, _, err := abt.BinarySearch(ctx, changedInL1Block) @@ -91,12 +90,10 @@ func TestArbitrumBlockTranslator_BinarySearch(t *testing.T) { var changedInL1Block int64 = 5042 latestBlock := blocks[1000] - client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(&latestBlock, nil).Once() + client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(latestBlock, nil).Once() - tmp := new(evmtypes.Head) - client.On("HeadByNumber", ctx, mock.AnythingOfType("*big.Int")).Return(tmp, nil).Run(func(args mock.Arguments) { - h := blocks[args[1].(*big.Int).Int64()] - *tmp = h + client.On("HeadByNumber", ctx, mock.AnythingOfType("*big.Int")).Return(func(_ context.Context, num *big.Int) (*evmtypes.Head, error) { + return blocks[num.Int64()], nil }) from, to, err := abt.BinarySearch(ctx, changedInL1Block) @@ -114,12 +111,10 @@ func TestArbitrumBlockTranslator_BinarySearch(t *testing.T) { var changedInL1Block int64 = 5000 latestBlock := blocks[1000] - client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(&latestBlock, nil).Once() + client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(latestBlock, nil).Once() - tmp := new(evmtypes.Head) - client.On("HeadByNumber", ctx, mock.AnythingOfType("*big.Int")).Return(tmp, nil).Run(func(args mock.Arguments) { - h := blocks[args[1].(*big.Int).Int64()] - *tmp = h + client.On("HeadByNumber", ctx, mock.AnythingOfType("*big.Int")).Return(func(_ context.Context, num *big.Int) (*evmtypes.Head, error) { + return blocks[num.Int64()], nil }) from, to, err := abt.BinarySearch(ctx, changedInL1Block) @@ -137,12 +132,10 @@ func TestArbitrumBlockTranslator_BinarySearch(t *testing.T) { var changedInL1Block int64 = 5540 latestBlock := blocks[1000] - client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(&latestBlock, nil).Once() + client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(latestBlock, nil).Once() - tmp := new(evmtypes.Head) - client.On("HeadByNumber", ctx, mock.AnythingOfType("*big.Int")).Return(tmp, nil).Run(func(args mock.Arguments) { - h := blocks[args[1].(*big.Int).Int64()] - *tmp = h + client.On("HeadByNumber", ctx, mock.AnythingOfType("*big.Int")).Return(func(_ context.Context, num *big.Int) (*evmtypes.Head, error) { + return blocks[num.Int64()], nil }) from, to, err := abt.BinarySearch(ctx, changedInL1Block) @@ -161,12 +154,10 @@ func TestArbitrumBlockTranslator_BinarySearch(t *testing.T) { latestBlock := blocks[1000] // Latest is never cached - client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(&latestBlock, nil).Once() + client.On("HeadByNumber", ctx, (*big.Int)(nil)).Return(latestBlock, nil).Once() - tmp := new(evmtypes.Head) - client.On("HeadByNumber", ctx, mock.AnythingOfType("*big.Int")).Times(20+18+14).Return(tmp, nil).Run(func(args mock.Arguments) { - h := blocks[args[1].(*big.Int).Int64()] - *tmp = h + client.On("HeadByNumber", ctx, mock.AnythingOfType("*big.Int")).Return(func(_ context.Context, num *big.Int) (*evmtypes.Head, error) { + return blocks[num.Int64()], nil }) // First search, nothing cached (total 21 - bsearch 20) @@ -230,14 +221,14 @@ func TestArbitrumBlockTranslator_NumberToQueryRange(t *testing.T) { }) } -func generateDeterministicL2Blocks() (heads []evmtypes.Head) { +func generateDeterministicL2Blocks() (heads []*evmtypes.Head) { source := mrand.NewSource(0) deterministicRand := mrand.New(source) l2max := 1000 var l1BlockNumber int64 = 5000 var parentHash common.Hash for i := 0; i <= l2max; i++ { - head := evmtypes.Head{ + head := &evmtypes.Head{ Number: int64(i), L1BlockNumber: sql.NullInt64{Int64: l1BlockNumber, Valid: true}, Hash: utils.NewHash(), diff --git a/core/services/relay/evm/mercury/v1/data_source_test.go b/core/services/relay/evm/mercury/v1/data_source_test.go index 197d802a3b..7f5117a0aa 100644 --- a/core/services/relay/evm/mercury/v1/data_source_test.go +++ b/core/services/relay/evm/mercury/v1/data_source_test.go @@ -332,16 +332,15 @@ func TestMercury_Observe(t *testing.T) { t.Run("when chain is too short", func(t *testing.T) { h4 := &evmtypes.Head{ Number: 4, - Parent: nil, } h5 := &evmtypes.Head{ Number: 5, - Parent: h4, } + h5.Parent.Store(h4) h6 := &evmtypes.Head{ Number: 6, - Parent: h5, } + h6.Parent.Store(h5) ht2 := htmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t) ht2.On("LatestChain").Return(h6) @@ -362,7 +361,7 @@ func TestMercury_Observe(t *testing.T) { for i := range heads { heads[i] = &evmtypes.Head{Number: int64(i)} if i > 0 { - heads[i].Parent = heads[i-1] + heads[i].Parent.Store(heads[i-1]) } } From ef77fac68b4f6f7b55a869af9b1484ea8a98c845 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Mon, 23 Sep 2024 13:28:21 +0200 Subject: [PATCH 405/432] Remove unused workflow for e2e tests (#14520) * Remove unused workflow for e2e tests * Fix --- .github/workflows/integration-tests.yml | 2 +- .../on-demand-keeper-smoke-tests.yml | 290 ------------------ 2 files changed, 1 insertion(+), 291 deletions(-) delete mode 100644 .github/workflows/on-demand-keeper-smoke-tests.yml diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 032ec40b4e..6389386799 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -280,7 +280,7 @@ jobs: id-token: write contents: read needs: [build-chainlink, changes] - if: github.event_name == 'merge_group' + if: github.event_name == 'merge_group' && ( needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml with: workflow_name: Run Core E2E Tests For Merge Queue diff --git a/.github/workflows/on-demand-keeper-smoke-tests.yml b/.github/workflows/on-demand-keeper-smoke-tests.yml deleted file mode 100644 index a0ed71c0a0..0000000000 --- a/.github/workflows/on-demand-keeper-smoke-tests.yml +++ /dev/null @@ -1,290 +0,0 @@ -name: On Demand Keeper Smoke Tests -run-name: On Demand Keeper Smoke Tests ${{ inputs.distinct_run_name && inputs.distinct_run_name || '' }} -on: - workflow_dispatch: - inputs: - distinct_run_name: - description: 'A unique identifier for this run, only use from other repos' - required: false - type: string - -# Only run 1 of this workflow at a time per PR -concurrency: - group: on-demand-keeper-smoke-tests-${{ github.ref }}-${{ inputs.distinct_run_name }} - cancel-in-progress: true - -env: - # for run-test variables and environment - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ inputs.evm-ref || github.sha }} - CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - TEST_SUITE: smoke - TEST_ARGS: -test.timeout 12m - INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com - MOD_CACHE_VERSION: 2 - COLLECTION_ID: chainlink-e2e-tests - -jobs: - build-chainlink: - environment: integration - permissions: - id-token: write - contents: read - strategy: - matrix: - image: - - name: "" - dockerfile: core/chainlink.Dockerfile - tag-suffix: "" - name: Build Chainlink Image ${{ matrix.image.name }} - runs-on: ubuntu22.04-16cores-64GB - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: ${{ env.COLLECTION_ID }}-build-chainlink - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Chainlink Image ${{ matrix.image.name }} - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Build Chainlink Image - uses: ./.github/actions/build-chainlink-image - with: - tag_suffix: ${{ matrix.image.tag-suffix }} - dockerfile: ${{ matrix.image.dockerfile }} - git_commit_sha: ${{ inputs.evm-ref || github.sha }} - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - dep_evm_sha: ${{ inputs.evm-ref }} - - compare-tests: - runs-on: ubuntu-latest - name: Build Automation Test List - outputs: - automation-matrix: ${{ env.AUTOMATION_JOB_MATRIX_JSON }} - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref }} - - name: Compare Test Lists - run: | - cd ./integration-tests - ./scripts/compareTestList.sh ./smoke/keeper_test.go - - name: Build Test Matrix Lists - id: build-test-matrix-list - run: | - cd ./integration-tests - KEEPER_JOB_MATRIX_JSON=$(./scripts/buildTestMatrixList.sh ./smoke/keeper_test.go keeper ubuntu-latest 1) - echo "AUTOMATION_JOB_MATRIX_JSON=${KEEPER_JOB_MATRIX_JSON}" >> $GITHUB_ENV - - eth-smoke-tests-matrix-automation: - if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} - environment: integration - permissions: - checks: write - pull-requests: write - id-token: write - contents: read - needs: [build-chainlink, compare-tests] - env: - SELECTED_NETWORKS: SIMULATED,SIMULATED_1,SIMULATED_2 - CHAINLINK_COMMIT_SHA: ${{ inputs.evm-ref || github.sha }} - CHAINLINK_ENV_USER: ${{ github.actor }} - TEST_LOG_LEVEL: debug - strategy: - fail-fast: false - matrix: - product: ${{fromJson(needs.compare-tests.outputs.automation-matrix)}} - runs-on: ${{ matrix.product.os }} - name: ETH Smoke Tests ${{ matrix.product.name }} - steps: - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: ${{ env.COLLECTION_ID }}-matrix-${{ matrix.product.name }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - this-job-name: ETH Smoke Tests ${{ matrix.product.name }} - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Build Go Test Command - id: build-go-test-command - run: | - # if the matrix.product.run is set, use it for a different command - if [ "${{ matrix.product.run }}" != "" ]; then - echo "run_command=${{ matrix.product.run }} ./smoke/${{ matrix.product.file }}_test.go" >> "$GITHUB_OUTPUT" - else - echo "run_command=./smoke/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT" - fi - - ## Run this step when changes that require tests to be run are made - - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 - with: - test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false - test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_config_chainlink_version: ${{ inputs.evm-ref || github.sha }} - test_config_selected_networks: ${{ env.SELECTED_NETWORKS }} - test_config_logging_run_id: ${{ github.run_id }} - test_config_logstream_log_targets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - test_config_test_log_collect: ${{ vars.TEST_LOG_COLLECT }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ inputs.evm-ref || github.sha }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: ${{ matrix.product.name }}-test-logs - artifacts_location: | - ./integration-tests/smoke/logs/ - ./integration-tests/smoke/db_dumps/ - /tmp/gotest.log - publish_check_name: ${{ matrix.product.name }} - token: ${{ secrets.GITHUB_TOKEN }} - go_mod_path: ./integration-tests/go.mod - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "true" - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: "" - should_tidy: "false" - go_coverage_src_dir: /var/tmp/go-coverage - go_coverage_dest_dir: ${{ github.workspace }}/.covdata - DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: ${{ vars.GRAFANA_URL }} - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - DEFAULT_PYROSCOPE_SERVER_URL: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 - DEFAULT_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - DEFAULT_PYROSCOPE_ENVIRONMENT: ${{ matrix.product.pyroscope_env }} - DEFAULT_PYROSCOPE_ENABLED: ${{ matrix.product.pyroscope_env == '' || !startsWith(github.ref, 'refs/tags/') && 'false' || 'true' }} - - - name: Upload Coverage Data - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - with: - name: cl-node-coverage-data-${{ matrix.product.name }} - path: .covdata - retention-days: 1 - - - name: Print failed test summary - if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 - - ### Used to check the required checks box when the matrix completes - eth-smoke-tests: - if: always() - runs-on: ubuntu-latest - name: ETH Smoke Tests - needs: [eth-smoke-tests-matrix-automation] - steps: - - name: Check smoke test matrix status - if: needs.eth-smoke-tests-matrix-automation.result != 'success' - run: | - echo "Automation: ${{ needs.eth-smoke-tests-matrix-automation.result }}" - exit 1 - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: ${{ env.COLLECTION_ID }}-matrix-results - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ETH Smoke Tests - matrix-aggregator-status: ${{ needs.eth-smoke-tests-matrix.result }} - continue-on-error: true - - cleanup: - name: Clean up integration environment deployments - if: always() - needs: [eth-smoke-tests] - runs-on: ubuntu-latest - steps: - - name: Checkout repo - if: ${{ github.event_name == 'pull_request' }} - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref }} - - - name: 🧼 Clean up Environment - if: ${{ github.event_name == 'pull_request' }} - uses: ./.github/actions/delete-deployments - with: - environment: integration - ref: ${{ github.head_ref }} # See https://github.com/github/docs/issues/15319#issuecomment-1476705663 - - - name: Collect Metrics - if: ${{ github.event_name == 'pull_request' }} - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: ${{ env.COLLECTION_ID }}-env-cleanup - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Clean up integration environment deployments - continue-on-error: true - - show-coverage: - name: Show Chainlink Node Go Coverage - if: always() - needs: [cleanup] - runs-on: ubuntu-latest - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Download All Artifacts - uses: actions/download-artifact@9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395 # v4.1.6 - with: - path: cl-node-coverage-data - pattern: cl-node-coverage-data-* - merge-multiple: true - - name: Show Coverage - run: go run ./integration-tests/scripts/show_coverage.go "${{ github.workspace }}/cl-node-coverage-data/*/merged" - - # Run the setup if the matrix finishes but this time save the cache if we have a cache hit miss - # this will also only run if both of the matrix jobs pass - eth-smoke-go-mod-cache: - - environment: integration - needs: [eth-smoke-tests] - runs-on: ubuntu-latest - name: ETH Smoke Tests Go Mod Cache - continue-on-error: true - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Run Setup - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 - with: - test_download_vendor_packages_command: | - cd ./integration-tests - go mod download - # force download of test dependencies - go test -run=NonExistentTest ./smoke/... || echo "ignore expected test failure" - go_mod_path: ./integration-tests/go.mod - cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} - cache_restore_only: "false" From f74ac81d5db7a89b04252938f4b5ff34e3f7bbbe Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Mon, 23 Sep 2024 14:44:36 +0200 Subject: [PATCH 406/432] [TT-1693] try more universal Solidity scripts (#14436) * try more universal Solidity scripts * fix error printing in uml generation; test foundry pipeline * Update gethwrappers * a bit more testing * fix Sol * remove test contracts * Update gethwrappers * try reusable artifact workflow * fix syntax * reuse workflow for .github/workflows * use newer reusable Solidity Review Artifacts pipeline * remove actions that were moved to chainlink-github-actions * add test Solidity file * add missing changeset * use scripts from shared repository * modify one contract * set git top level dir manually * [Bot] Update changeset file with jira issue * fix script path * use newer version of the reusable pipeline * update pipeline version, use custom pruning script * use newer action version, remove JIRA scripts * use reusable Solidity Review Artifacts workflow from .github * remove left over changes that are no longer needed * remove left over changes that are no longer needed * fix foundry pipeline * remove test Solidity files * use tagged reusable pipeline version * update all references to .github to use tagged commit --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .github/actions/setup-slither/action.yaml | 10 - .github/actions/setup-solc-select/action.yaml | 30 - .../validate-solidity-artifacts/action.yaml | 115 -- .github/scripts/functions.sh | 17 - .github/scripts/jira/axios.ts | 97 -- .../scripts/jira/create-jira-traceability.ts | 215 ---- .github/scripts/jira/enforce-jira-issue.ts | 119 -- .github/scripts/jira/lib.test.ts | 149 --- .github/scripts/jira/lib.ts | 147 --- .github/scripts/jira/package.json | 34 - .github/scripts/jira/pnpm-lock.yaml | 1114 ----------------- .github/scripts/jira/tsconfig.json | 108 -- .github/scripts/jira/update-jira-issue.ts | 77 -- .github/workflows/changeset.yml | 19 +- .../workflows/solidity-foundry-artifacts.yml | 341 +---- .github/workflows/solidity-foundry.yml | 81 +- .github/workflows/solidity-tracability.yml | 27 +- .github/workflows/solidity-wrappers.yml | 8 +- contracts/.changeset/quiet-moles-retire.md | 8 + contracts/.tool-versions | 1 + .../scripts/ci/generate_slither_report.sh | 85 -- contracts/scripts/ci/generate_uml.sh | 121 -- contracts/scripts/ci/modify_remappings.sh | 30 - contracts/scripts/ci/select_solc_version.sh | 118 -- 24 files changed, 136 insertions(+), 2935 deletions(-) delete mode 100644 .github/actions/setup-slither/action.yaml delete mode 100644 .github/actions/setup-solc-select/action.yaml delete mode 100644 .github/actions/validate-solidity-artifacts/action.yaml delete mode 100644 .github/scripts/functions.sh delete mode 100644 .github/scripts/jira/axios.ts delete mode 100644 .github/scripts/jira/create-jira-traceability.ts delete mode 100644 .github/scripts/jira/enforce-jira-issue.ts delete mode 100644 .github/scripts/jira/lib.test.ts delete mode 100644 .github/scripts/jira/lib.ts delete mode 100644 .github/scripts/jira/package.json delete mode 100644 .github/scripts/jira/pnpm-lock.yaml delete mode 100644 .github/scripts/jira/tsconfig.json delete mode 100644 .github/scripts/jira/update-jira-issue.ts create mode 100644 contracts/.changeset/quiet-moles-retire.md create mode 100644 contracts/.tool-versions delete mode 100755 contracts/scripts/ci/generate_slither_report.sh delete mode 100755 contracts/scripts/ci/generate_uml.sh delete mode 100755 contracts/scripts/ci/modify_remappings.sh delete mode 100755 contracts/scripts/ci/select_solc_version.sh diff --git a/.github/actions/setup-slither/action.yaml b/.github/actions/setup-slither/action.yaml deleted file mode 100644 index b8bef38575..0000000000 --- a/.github/actions/setup-slither/action.yaml +++ /dev/null @@ -1,10 +0,0 @@ -name: Setup Slither -description: Installs Slither 0.10.3 for contract analysis. Requires Python 3.6 or higher. -runs: - using: composite - steps: - - name: Install Slither - shell: bash - run: | - python -m pip install --upgrade pip - pip install slither-analyzer==0.10.3 diff --git a/.github/actions/setup-solc-select/action.yaml b/.github/actions/setup-solc-select/action.yaml deleted file mode 100644 index b74ffae018..0000000000 --- a/.github/actions/setup-solc-select/action.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: Setup Solc Select -description: Installs Solc Select, required versions and selects the version to use. Requires Python 3.6 or higher. -inputs: - to_install: - description: Comma-separated list of solc versions to install - required: true - to_use: - description: Solc version to use - required: true - -runs: - using: composite - steps: - - name: Install solc-select and solc - shell: bash - run: | - pip3 install solc-select - sudo ln -s /usr/local/bin/solc-select /usr/bin/solc-select - - IFS=',' read -ra versions <<< "${{ inputs.to_install }}" - for version in "${versions[@]}"; do - solc-select install $version - if [ $? -ne 0 ]; then - echo "Failed to install Solc $version" - exit 1 - fi - done - - solc-select install ${{ inputs.to_use }} - solc-select use ${{ inputs.to_use }} diff --git a/.github/actions/validate-solidity-artifacts/action.yaml b/.github/actions/validate-solidity-artifacts/action.yaml deleted file mode 100644 index 5357a87f96..0000000000 --- a/.github/actions/validate-solidity-artifacts/action.yaml +++ /dev/null @@ -1,115 +0,0 @@ -name: Validate Solidity Artifacts -description: Checks whether Slither reports and UML diagrams were generated for all necessary files. If not, a warning is printed in job summary, but the job is not marked as failed. -inputs: - slither_reports_path: - description: Path to the Slither reports directory (without trailing slash) - required: true - uml_diagrams_path: - description: Path to the UML diagrams directory (without trailing slash) - required: true - validate_slither_reports: - description: Whether Slither reports should be validated - required: true - validate_uml_diagrams: - description: Whether UML diagrams should be validated - required: true - sol_files: - description: Comma-separated (CSV) or space-separated (shell) list of Solidity files to check - required: true - -runs: - using: composite - steps: - - name: Transform input array - id: transform_input_array - shell: bash - run: | - is_csv_format() { - local input="$1" - if [[ "$input" =~ "," ]]; then - return 0 - else - return 1 - fi - } - - is_space_separated_string() { - local input="$1" - if [[ "$input" =~ ^[^[:space:]]+([[:space:]][^[:space:]]+)*$ ]]; then - return 0 - else - return 1 - fi - } - - array="${{ inputs.sol_files }}" - - if is_csv_format "$array"; then - echo "::debug::CSV format detected, nothing to do" - echo "sol_files=$array" >> $GITHUB_OUTPUT - exit 0 - fi - - if is_space_separated_string "$array"; then - echo "::debug::Space-separated format detected, converting to CSV" - csv_array="${array// /,}" - echo "sol_files=$csv_array" >> $GITHUB_OUTPUT - exit 0 - fi - - echo "::error::Invalid input format for sol_files. Please provide a comma-separated (CSV) or space-separated (shell) list of Solidity files" - exit 1 - - - name: Validate UML diagrams - if: ${{ inputs.validate_uml_diagrams == 'true' }} - shell: bash - run: | - echo "Validating UML diagrams" - IFS=',' read -r -a modified_files <<< "${{ steps.transform_input_array.outputs.sol_files }}" - missing_svgs=() - for file in "${modified_files[@]}"; do - svg_file="$(basename "${file%.sol}").svg" - if [ ! -f "${{ inputs.uml_diagrams_path }}/$svg_file" ]; then - echo "Error: UML diagram for $file not found" - missing_svgs+=("$file") - fi - done - - if [ ${#missing_svgs[@]} -gt 0 ]; then - echo "Error: Missing UML diagrams for files: ${missing_svgs[@]}" - echo "# Warning!" >> $GITHUB_STEP_SUMMARY - echo "## Reason: Missing UML diagrams for files:" >> $GITHUB_STEP_SUMMARY - for file in "${missing_svgs[@]}"; do - echo " $file" >> $GITHUB_STEP_SUMMARY - done - echo "## Action required: Please try to generate artifacts for them locally or using a different tool" >> $GITHUB_STEP_SUMMARY - else - echo "All UML diagrams generated successfully" - fi - - - name: Validate Slither reports - if: ${{ inputs.validate_slither_reports == 'true' }} - shell: bash - run: | - echo "Validating Slither reports" - IFS=',' read -r -a modified_files <<< "${{ steps.transform_input_array.outputs.sol_files }}" - missing_reports=() - for file in "${modified_files[@]}"; do - report_file="$(basename "${file%.sol}")-slither-report.md" - if [ ! -f "${{ inputs.slither_reports_path }}/$report_file" ]; then - echo "Error: Slither report for $file not found" - missing_reports+=("$file") - fi - done - - if [ ${#missing_reports[@]} -gt 0 ]; then - echo "Error: Missing Slither reports for files: ${missing_reports[@]}" - echo "# Warning!" >> $GITHUB_STEP_SUMMARY - echo "## Reason: Missing Slither reports for files:" >> $GITHUB_STEP_SUMMARY - for file in "${missing_reports[@]}"; do - echo " $file" >> $GITHUB_STEP_SUMMARY - done - echo "## Action required: Please try to generate artifacts for them locally" >> $GITHUB_STEP_SUMMARY - else - echo "All Slither reports generated successfully" - fi diff --git a/.github/scripts/functions.sh b/.github/scripts/functions.sh deleted file mode 100644 index 53b5339226..0000000000 --- a/.github/scripts/functions.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# Function to convert a comma-separated list into a TOML array format. -# Usage: convert_to_toml_array "elem1,elem2,elem3" -# Effect: "a,b,c" -> ["a","b","c"] -function convert_to_toml_array() { - local IFS=',' - local input_array=($1) - local toml_array_format="[" - - for element in "${input_array[@]}"; do - toml_array_format+="\"$element\"," - done - - toml_array_format="${toml_array_format%,}]" - echo "$toml_array_format" -} \ No newline at end of file diff --git a/.github/scripts/jira/axios.ts b/.github/scripts/jira/axios.ts deleted file mode 100644 index 3a91279771..0000000000 --- a/.github/scripts/jira/axios.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { - AxiosRequestConfig, - AxiosResponse, - AxiosError, - InternalAxiosRequestConfig, -} from "axios"; -import { Readable } from "stream"; - -interface AxiosErrorFormat { - config: Pick; - code?: string; - response: Partial, (typeof RESPONSE_KEYS)[number]>>; - isAxiosError: boolean; -} - -interface AxiosErrorFormatError - extends Error, - AxiosErrorFormat {} - -export function formatAxiosError( - origErr: AxiosError -): AxiosErrorFormatError { - const { message, name, stack, code, config, response, isAxiosError } = - origErr; - - const err: AxiosErrorFormatError = { - ...new Error(message), - name, - stack, - code, - isAxiosError, - config: {}, - response: {}, - }; - - for (const k of CONFIG_KEYS) { - if (config?.[k] === undefined) { - continue; - } - - err.config[k] = formatValue(config[k], k); - } - - for (const k of RESPONSE_KEYS) { - if (response?.[k] === undefined) { - continue; - } - - err.response[k] = formatValue(response[k], k); - } - - return err as any; -} - -const CONFIG_KEYS: (keyof InternalAxiosRequestConfig)[] = [ - "url", - "method", - "baseURL", - "params", - "data", - "timeout", - "timeoutErrorMessage", - "withCredentials", - "auth", - "responseType", - "xsrfCookieName", - "xsrfHeaderName", - "maxContentLength", - "maxBodyLength", - "maxRedirects", - "socketPath", - "proxy", - "decompress", -] as const; - -const RESPONSE_KEYS: (keyof AxiosResponse)[] = [ - "data", - "status", - "statusText", -] as const; - -function formatValue( - value: any, - key: (typeof CONFIG_KEYS)[number] | (typeof RESPONSE_KEYS)[number] -): any { - if (key !== "data") { - return value; - } - - if (process.env.BROWSER !== "true") { - if (value instanceof Readable) { - return "[Readable]"; - } - } - - return value; -} diff --git a/.github/scripts/jira/create-jira-traceability.ts b/.github/scripts/jira/create-jira-traceability.ts deleted file mode 100644 index cda038a7cc..0000000000 --- a/.github/scripts/jira/create-jira-traceability.ts +++ /dev/null @@ -1,215 +0,0 @@ -import * as jira from "jira.js"; -import { - createJiraClient, - extractJiraIssueNumbersFrom, - generateIssueLabel, - generateJiraIssuesLink, - getJiraEnvVars, - handleError, -} from "./lib"; -import * as core from "@actions/core"; - -/** - * Extracts the list of changeset files. Intended to be used with https://github.com/dorny/paths-filter with - * the 'csv' output format. - * - * @returns An array of strings representing the changeset files. - * @throws {Error} If the required environment variable CHANGESET_FILES is missing. - * @throws {Error} If no changeset file exists. - */ -function extractChangesetFiles(): string[] { - const changesetFiles = process.env.CHANGESET_FILES; - if (!changesetFiles) { - throw Error("Missing required environment variable CHANGESET_FILES"); - } - const parsedChangesetFiles = changesetFiles.split(","); - if (parsedChangesetFiles.length === 0) { - throw Error("At least one changeset file must exist"); - } - - core.info( - `Changeset to extract issues from: ${parsedChangesetFiles.join(", ")}` - ); - return parsedChangesetFiles; -} - -/** - * Adds traceability to JIRA issues by commenting on each issue with a link to the artifact payload - * along with a label to connect all issues to the same chainlink product review. - * - * @param client The jira client - * @param issues The list of JIRA issue numbers to add traceability to - * @param label The label to add to each issue - * @param artifactUrl The url to the artifact payload that we'll comment on each issue with - */ -async function addTraceabillityToJiraIssues( - client: jira.Version3Client, - issues: string[], - label: string, - artifactUrl: string -) { - for (const issue of issues) { - await checkAndAddArtifactPayloadComment(client, issue, artifactUrl); - - // CHECK: We don't need to see if the label exists, should no-op - core.info(`Adding label ${label} to issue ${issue}`); - await client.issues.editIssue({ - issueIdOrKey: issue, - update: { - labels: [{ add: label }], - }, - }); - } -} - -/** - * Checks if the artifact payload already exists as a comment on the issue, if not, adds it. - */ -async function checkAndAddArtifactPayloadComment( - client: jira.Version3.Version3Client, - issue: string, - artifactUrl: string -) { - const maxResults = 5000; - const getCommentsResponse = await client.issueComments.getComments({ - issueIdOrKey: issue, - maxResults, // this is the default maxResults, see https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-get - }); - core.debug(JSON.stringify(getCommentsResponse.comments)); - if ((getCommentsResponse.total ?? 0) > maxResults) { - throw Error( - `Too many (${getCommentsResponse.total}) comments on issue ${issue}, please increase maxResults (${maxResults})` - ); - } - - // Search path is getCommentsResponse.comments[].body.content[].content[].marks[].attrs.href - // - // Example: - // [ // getCommentsResponse.comments - // { - // body: { - // type: "doc", - // version: 1, - // content: [ - // { - // type: "paragraph", - // content: [ - // { - // type: "text", - // text: "Artifact URL", - // marks: [ - // { - // type: "link", - // attrs: { - // href: "https://github.com/smartcontractkit/chainlink/actions/runs/10517121836/artifacts/1844867108", - // }, - // }, - // ], - // }, - // ], - // }, - // ], - // }, - // }, - // ]; - const commentExists = getCommentsResponse.comments?.some((c) => - c?.body?.content?.some((innerContent) => - innerContent?.content?.some((c) => - c.marks?.some((m) => m.attrs?.href === artifactUrl) - ) - ) - ); - - if (commentExists) { - core.info(`Artifact payload already exists as comment on issue, skipping`); - } else { - core.info(`Adding artifact payload as comment on issue ${issue}`); - await client.issueComments.addComment({ - issueIdOrKey: issue, - comment: { - type: "doc", - version: 1, - content: [ - { - type: "paragraph", - content: [ - { - type: "text", - text: "Artifact Download URL", - marks: [ - { - type: "link", - attrs: { - href: artifactUrl, - }, - }, - ], - }, - ], - }, - ], - }, - }); - } -} - -function fetchEnvironmentVariables() { - const product = process.env.CHAINLINK_PRODUCT; - if (!product) { - throw Error("CHAINLINK_PRODUCT environment variable is missing"); - } - const baseRef = process.env.BASE_REF; - if (!baseRef) { - throw Error("BASE_REF environment variable is missing"); - } - const headRef = process.env.HEAD_REF; - if (!headRef) { - throw Error("HEAD_REF environment variable is missing"); - } - - const artifactUrl = process.env.ARTIFACT_URL; - if (!artifactUrl) { - throw Error("ARTIFACT_URL environment variable is missing"); - } - return { product, baseRef, headRef, artifactUrl }; -} - -/** - * For all affected jira issues listed within the changeset files supplied, - * we update each jira issue so that they are all labelled and have a comment linking them - * to the relevant artifact URL. - */ -async function main() { - const { product, baseRef, headRef, artifactUrl } = - fetchEnvironmentVariables(); - const changesetFiles = extractChangesetFiles(); - core.info( - `Extracting Jira issue numbers from changeset files: ${changesetFiles.join( - ", " - )}` - ); - const jiraIssueNumbers = await extractJiraIssueNumbersFrom(changesetFiles); - - const client = createJiraClient(); - const label = generateIssueLabel(product, baseRef, headRef); - try { - await addTraceabillityToJiraIssues( - client, - jiraIssueNumbers, - label, - artifactUrl - ); - } catch (e) { - handleError(e); - - process.exit(1); - } - - const { jiraHost } = getJiraEnvVars(); - core.summary.addLink( - "Jira Issues", - generateJiraIssuesLink(`${jiraHost}/issues/`, label) - ); - core.summary.write(); -} -main(); diff --git a/.github/scripts/jira/enforce-jira-issue.ts b/.github/scripts/jira/enforce-jira-issue.ts deleted file mode 100644 index 153f397e02..0000000000 --- a/.github/scripts/jira/enforce-jira-issue.ts +++ /dev/null @@ -1,119 +0,0 @@ -import * as core from "@actions/core"; -import jira from "jira.js"; -import { createJiraClient, getGitTopLevel, handleError, parseIssueNumberFrom } from "./lib"; -import { promises as fs } from "fs"; -import { join } from "path"; - -async function doesIssueExist( - client: jira.Version3Client, - issueNumber: string, - dryRun: boolean -) { - const payload = { - issueIdOrKey: issueNumber, - }; - - if (dryRun) { - core.info("Dry run enabled, skipping JIRA issue enforcement"); - return true; - } - - try { - /** - * The issue is identified by its ID or key, however, if the identifier doesn't match an issue, a case-insensitive search and check for moved issues is performed. - * If a matching issue is found its details are returned, a 302 or other redirect is not returned. The issue key returned in the response is the key of the issue found. - */ - const issue = await client.issues.getIssue(payload); - core.debug( - `JIRA issue id:${issue.id} key: ${issue.key} found while querying for ${issueNumber}` - ); - if (issue.key !== issueNumber) { - core.error( - `JIRA issue key ${issueNumber} not found, but found issue key ${issue.key} instead. This can happen if the identifier doesn't match an issue, in which case a case-insensitive search and check for moved issues is performed. Make sure the issue key is correct.` - ); - return false; - } - - return true; - } catch (e) { - handleError(e) - return false; - } -} - -async function main() { - const prTitle = process.env.PR_TITLE; - const commitMessage = process.env.COMMIT_MESSAGE; - const branchName = process.env.BRANCH_NAME; - const dryRun = !!process.env.DRY_RUN; - const { changesetFile } = extractChangesetFile(); - - const client = createJiraClient(); - - // Checks for the Jira issue number and exit if it can't find it - const issueNumber = parseIssueNumberFrom(prTitle, commitMessage, branchName); - if (!issueNumber) { - const msg = - "No JIRA issue number found in PR title, commit message, or branch name. This pull request must be associated with a JIRA issue."; - - core.setFailed(msg); - return; - } - - const exists = await doesIssueExist(client, issueNumber, dryRun); - if (!exists) { - core.setFailed( - `JIRA issue ${issueNumber} not found, this pull request must be associated with a JIRA issue.` - ); - return; - } - - core.info(`Appending JIRA issue ${issueNumber} to changeset file`); - await appendIssueNumberToChangesetFile(changesetFile, issueNumber); -} - -async function appendIssueNumberToChangesetFile( - changesetFile: string, - issueNumber: string -) { - const gitTopLevel = await getGitTopLevel(); - const fullChangesetPath = join(gitTopLevel, changesetFile); - const changesetContents = await fs.readFile(fullChangesetPath, "utf-8"); - // Check if the issue number is already in the changeset file - if (changesetContents.includes(issueNumber)) { - core.info("Issue number already exists in changeset file, skipping..."); - return; - } - - const updatedChangesetContents = `${changesetContents}\n\n${issueNumber}`; - await fs.writeFile(fullChangesetPath, updatedChangesetContents); -} - -function extractChangesetFile() { - const changesetFiles = process.env.CHANGESET_FILES; - if (!changesetFiles) { - throw Error("Missing required environment variable CHANGESET_FILES"); - } - const parsedChangesetFiles = JSON.parse(changesetFiles); - if (parsedChangesetFiles.length !== 1) { - throw Error( - "This action only supports one changeset file per pull request." - ); - } - const [changesetFile] = parsedChangesetFiles; - - return { changesetFile }; -} - -async function run() { - try { - await main(); - } catch (error) { - if (error instanceof Error) { - return core.setFailed(error.message); - } - core.setFailed(error as any); - } -} - -run(); diff --git a/.github/scripts/jira/lib.test.ts b/.github/scripts/jira/lib.test.ts deleted file mode 100644 index 6ef629a53e..0000000000 --- a/.github/scripts/jira/lib.test.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { expect, describe, it, vi } from "vitest"; -import { - generateIssueLabel, - generateJiraIssuesLink, - getGitTopLevel, - parseIssueNumberFrom, - tagsToLabels, -} from "./lib"; -import * as core from "@actions/core"; - -describe("parseIssueNumberFrom", () => { - it("should return the first JIRA issue number found", () => { - let r = parseIssueNumberFrom("CORE-123", "CORE-456", "CORE-789"); - expect(r).to.equal("CORE-123"); - - r = parseIssueNumberFrom( - "2f3df5gf", - "chore/test-RE-78-branch", - "RE-78 Create new test branches" - ); - expect(r).to.equal("RE-78"); - - // handle lower case - r = parseIssueNumberFrom("core-123", "CORE-456", "CORE-789"); - expect(r).to.equal("CORE-123"); - }); - - it("works with multiline commit bodies", () => { - const r = parseIssueNumberFrom( - `This is a multiline commit body - -CORE-1011`, - "CORE-456", - "CORE-789" - ); - expect(r).to.equal("CORE-1011"); - }); - - it("should return undefined if no JIRA issue number is found", () => { - const result = parseIssueNumberFrom("No issue number"); - expect(result).to.be.undefined; - }); - - it("works when the label is in the middle of the commit message", () => { - let r = parseIssueNumberFrom( - "This is a commit message with CORE-123 in the middle", - "CORE-456", - "CORE-789" - ); - expect(r).to.equal("CORE-123"); - - r = parseIssueNumberFrom( - "#internal address security vulnerabilities RE-2917 around updating nodes and node operators on capabilities registry" - ); - expect(r).to.equal("RE-2917"); - }); -}); - -describe("tagsToLabels", () => { - it("should convert an array of tags to an array of labels", () => { - const tags = ["v1.0.0", "v1.1.0"]; - const result = tagsToLabels(tags); - expect(result).to.deep.equal([ - { add: "core-release/1.0.0" }, - { add: "core-release/1.1.0" }, - ]); - }); -}); - -const mockExecPromise = vi.fn(); -vi.mock("util", () => ({ - promisify: () => mockExecPromise, -})); - -describe("getGitTopLevel", () => { - it("should log the top-level directory when git command succeeds", async () => { - mockExecPromise.mockResolvedValueOnce({ - stdout: "/path/to/top-level-dir", - stderr: "", - }); - - const mockConsoleLog = vi.spyOn(core, "info"); - await getGitTopLevel(); - - expect(mockExecPromise).toHaveBeenCalledWith( - "git rev-parse --show-toplevel" - ); - expect(mockConsoleLog).toHaveBeenCalledWith( - "Top-level directory: /path/to/top-level-dir" - ); - }); - - it("should log an error message when git command fails", async () => { - mockExecPromise.mockRejectedValueOnce({ - message: "Command failed", - }); - - const mockConsoleError = vi.spyOn(core, "error"); - await getGitTopLevel().catch(() => {}); - - expect(mockExecPromise).toHaveBeenCalledWith( - "git rev-parse --show-toplevel" - ); - expect(mockConsoleError).toHaveBeenCalledWith( - "Error executing command: Command failed" - ); - }); - - it("should log an error message when git command output contains an error", async () => { - mockExecPromise.mockResolvedValueOnce({ - stdout: "", - stderr: "Error: Command failed", - }); - - const mockConsoleError = vi.spyOn(core, "error"); - await getGitTopLevel().catch(() => {}); - - expect(mockExecPromise).toHaveBeenCalledWith( - "git rev-parse --show-toplevel" - ); - expect(mockConsoleError).toHaveBeenCalledWith( - "Error in command output: Error: Command failed" - ); - }); -}); - -describe("generateJiraIssuesLink", () => { - it("should generate a Jira issues link", () => { - expect( - generateJiraIssuesLink( - "https://smartcontract-it.atlassian.net/issues/", - "review-artifacts-automation-base:0de9b3b-head:e5b3b9d" - ) - ).toMatchInlineSnapshot( - `"https://smartcontract-it.atlassian.net/issues/?jql=labels+%3D+%22review-artifacts-automation-base%3A0de9b3b-head%3Ae5b3b9d%22"` - ); - }); -}); - -describe("generateIssueLabel", () => { - it("should generate an issue label", () => { - const product = "automation"; - const baseRef = "0de9b3b"; - const headRef = "e5b3b9d"; - expect(generateIssueLabel(product, baseRef, headRef)).toMatchInlineSnapshot( - `"review-artifacts-automation-base:0de9b3b-head:e5b3b9d"` - ); - }); -}); diff --git a/.github/scripts/jira/lib.ts b/.github/scripts/jira/lib.ts deleted file mode 100644 index 8be295ab14..0000000000 --- a/.github/scripts/jira/lib.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { readFile } from "fs/promises"; -import * as core from "@actions/core"; -import * as jira from "jira.js"; -import { exec } from "child_process"; -import { promisify } from "util"; -import { join } from "path"; -import { isAxiosError } from "axios"; -import { formatAxiosError } from "./axios"; -export function generateJiraIssuesLink(baseUrl: string, label: string) { - // https://smartcontract-it.atlassian.net/issues/?jql=labels%20%3D%20%22review-artifacts-automation-base%3A8d818ea265ff08887e61ace4f83364a3ee149ef0-head%3A3c45b71f3610de28f429cef0163936eaa448e63c%22 - const jqlQuery = `labels = "${label}"`; - const fullUrl = new URL(baseUrl); - fullUrl.searchParams.set("jql", jqlQuery); - - const urlStr = fullUrl.toString(); - core.info(`Jira issues link: ${urlStr}`); - return urlStr; -} - -export function generateIssueLabel( - product: string, - baseRef: string, - headRef: string -) { - return `review-artifacts-${product}-base:${baseRef}-head:${headRef}`; -} - -export async function getGitTopLevel(): Promise { - const execPromise = promisify(exec); - try { - const { stdout, stderr } = await execPromise( - "git rev-parse --show-toplevel" - ); - - if (stderr) { - const msg = `Error in command output: ${stderr}`; - core.error(msg); - throw Error(msg); - } - - const topLevelDir = stdout.trim(); - core.info(`Top-level directory: ${topLevelDir}`); - return topLevelDir; - } catch (error) { - const msg = `Error executing command: ${(error as any).message}`; - core.error(msg); - throw Error(msg); - } -} - -/** - * Given a list of strings, this function will return the first JIRA issue number it finds. - * - * @example parseIssueNumberFrom("CORE-123", "CORE-456", "CORE-789") => "CORE-123" - * @example parseIssueNumberFrom("2f3df5gf", "chore/test-RE-78-branch", "RE-78 Create new test branches") => "RE-78" - */ -export function parseIssueNumberFrom( - ...inputs: (string | undefined)[] -): string | undefined { - function parse(str?: string) { - const jiraIssueRegex = /[A-Z]{2,}-\d+/; - - return str?.toUpperCase().match(jiraIssueRegex)?.[0]; - } - - core.debug(`Parsing issue number from: ${inputs.join(", ")}`); - const parsed: string[] = inputs.map(parse).filter((x) => x !== undefined); - core.debug(`Found issue number: ${parsed[0]}`); - - return parsed[0]; -} - -export async function extractJiraIssueNumbersFrom(filePaths: string[]) { - const issueNumbers: string[] = []; - const gitTopLevel = await getGitTopLevel(); - - for (const path of filePaths) { - const fullPath = join(gitTopLevel, path); - core.info(`Reading file: ${fullPath}`); - const content = await readFile(fullPath, "utf-8"); - const issueNumber = parseIssueNumberFrom(content); - core.info(`Extracted issue number: ${issueNumber}`); - if (issueNumber) { - issueNumbers.push(issueNumber); - } - } - - return issueNumbers; -} - -/** - * Converts an array of tags to an array of labels. - * - * A label is a string that is formatted as `core-release/{tag}`, with the leading `v` removed from the tag. - * - * @example tagsToLabels(["v1.0.0", "v1.1.0"]) => [{ add: "core-release/1.0.0" }, { add: "core-release/1.1.0" }] - */ -export function tagsToLabels(tags: string[]) { - const labelPrefix = "core-release"; - - return tags.map((t) => ({ - add: `${labelPrefix}/${t.substring(1)}`, - })); -} - -export function getJiraEnvVars() { - const jiraHost = process.env.JIRA_HOST; - const jiraUserName = process.env.JIRA_USERNAME; - const jiraApiToken = process.env.JIRA_API_TOKEN; - - if (!jiraHost || !jiraUserName || !jiraApiToken) { - core.setFailed( - "Error: Missing required environment variables: JIRA_HOST and JIRA_USERNAME and JIRA_API_TOKEN." - ); - process.exit(1); - } - - return { jiraHost, jiraUserName, jiraApiToken }; -} - -export function createJiraClient() { - const { jiraHost, jiraUserName, jiraApiToken } = getJiraEnvVars(); - return new jira.Version3Client({ - host: jiraHost, - authentication: { - basic: { - email: jiraUserName, - apiToken: jiraApiToken, - }, - }, - }); -} - -export function handleError(e: unknown) { - if (e instanceof Error) { - if (isAxiosError(e)) { - core.error(formatAxiosError(e)); - } else if (isAxiosError(e.cause)) { - core.error(formatAxiosError(e.cause)); - } else { - core.error(e); - } - } else { - core.error(JSON.stringify(e)); - } - core.setFailed("Error adding traceability to Jira issues"); -} diff --git a/.github/scripts/jira/package.json b/.github/scripts/jira/package.json deleted file mode 100644 index 6081e48981..0000000000 --- a/.github/scripts/jira/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "jira", - "version": "0.1.0", - "description": "Updates Jira issue with release information like the version and tags for a PR.", - "main": "update-jira-issue.js", - "type": "module", - "private": true, - "keywords": [], - "author": "", - "license": "MIT", - "engines": { - "node": ">=18", - "pnpm": ">=9" - }, - "scripts": { - "issue:update": "tsx update-jira-issue.ts", - "issue:enforce": "tsx enforce-jira-issue.ts", - "issue:traceability": "tsx create-jira-traceability.ts", - "test": "vitest" - }, - "dependencies": { - "@actions/core": "^1.10.1", - "jira.js": "^4.0.1", - "tsx": "^4.16.2" - }, - "devDependencies": { - "@types/node": "^20.14.10", - "typescript": "^5.5.3", - "vitest": "^2.0.3" - }, - "peerDependencies": { - "axios": "^1.7.7" - } -} diff --git a/.github/scripts/jira/pnpm-lock.yaml b/.github/scripts/jira/pnpm-lock.yaml deleted file mode 100644 index a52fa9dd0c..0000000000 --- a/.github/scripts/jira/pnpm-lock.yaml +++ /dev/null @@ -1,1114 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@actions/core': - specifier: ^1.10.1 - version: 1.10.1 - axios: - specifier: ^1.7.7 - version: 1.7.7 - jira.js: - specifier: ^4.0.1 - version: 4.0.1 - tsx: - specifier: ^4.16.2 - version: 4.16.2 - devDependencies: - '@types/node': - specifier: ^20.14.10 - version: 20.14.10 - typescript: - specifier: ^5.5.3 - version: 5.5.3 - vitest: - specifier: ^2.0.3 - version: 2.0.3(@types/node@20.14.10) - -packages: - - '@actions/core@1.10.1': - resolution: {integrity: sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==} - - '@actions/http-client@2.2.1': - resolution: {integrity: sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw==} - - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@fastify/busboy@2.1.1': - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} - engines: {node: '>=14'} - - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - - '@rollup/rollup-android-arm-eabi@4.18.1': - resolution: {integrity: sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.18.1': - resolution: {integrity: sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.18.1': - resolution: {integrity: sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.18.1': - resolution: {integrity: sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-linux-arm-gnueabihf@4.18.1': - resolution: {integrity: sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.18.1': - resolution: {integrity: sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.18.1': - resolution: {integrity: sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.18.1': - resolution: {integrity: sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': - resolution: {integrity: sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.18.1': - resolution: {integrity: sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.18.1': - resolution: {integrity: sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.18.1': - resolution: {integrity: sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.18.1': - resolution: {integrity: sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.18.1': - resolution: {integrity: sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.18.1': - resolution: {integrity: sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.18.1': - resolution: {integrity: sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==} - cpu: [x64] - os: [win32] - - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - - '@types/node@20.14.10': - resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} - - '@vitest/expect@2.0.3': - resolution: {integrity: sha512-X6AepoOYePM0lDNUPsGXTxgXZAl3EXd0GYe/MZyVE4HzkUqyUVC6S3PrY5mClDJ6/7/7vALLMV3+xD/Ko60Hqg==} - - '@vitest/pretty-format@2.0.3': - resolution: {integrity: sha512-URM4GLsB2xD37nnTyvf6kfObFafxmycCL8un3OC9gaCs5cti2u+5rJdIflZ2fUJUen4NbvF6jCufwViAFLvz1g==} - - '@vitest/runner@2.0.3': - resolution: {integrity: sha512-EmSP4mcjYhAcuBWwqgpjR3FYVeiA4ROzRunqKltWjBfLNs1tnMLtF+qtgd5ClTwkDP6/DGlKJTNa6WxNK0bNYQ==} - - '@vitest/snapshot@2.0.3': - resolution: {integrity: sha512-6OyA6v65Oe3tTzoSuRPcU6kh9m+mPL1vQ2jDlPdn9IQoUxl8rXhBnfICNOC+vwxWY684Vt5UPgtcA2aPFBb6wg==} - - '@vitest/spy@2.0.3': - resolution: {integrity: sha512-sfqyAw/ypOXlaj4S+w8689qKM1OyPOqnonqOc9T91DsoHbfN5mU7FdifWWv3MtQFf0lEUstEwR9L/q/M390C+A==} - - '@vitest/utils@2.0.3': - resolution: {integrity: sha512-c/UdELMuHitQbbc/EVctlBaxoYAwQPQdSNwv7z/vHyBKy2edYZaFgptE27BRueZB7eW8po+cllotMNTDpL3HWg==} - - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - axios@1.7.7: - resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} - - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - chai@5.1.1: - resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} - engines: {node: '>=12'} - - check-error@2.1.1: - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} - engines: {node: '>= 16'} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - - debug@4.3.5: - resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} - - follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - - get-tsconfig@4.7.5: - resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} - - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jira.js@4.0.1: - resolution: {integrity: sha512-2zf8LozW9rgx5wgTdGSJMhUXDK1g8a/ngm1xDWnREX/h8kuBhNkMro4XELA2XRVvaNTbRMIK3PBgOvWFDddhIw==} - - loupe@3.1.1: - resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} - - magic-string@0.30.10: - resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} - - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - - pathval@2.0.0: - resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} - engines: {node: '>= 14.16'} - - picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} - - postcss@8.4.39: - resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==} - engines: {node: ^10 || ^12 || >=14} - - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - rollup@4.18.1: - resolution: {integrity: sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} - engines: {node: '>=0.10.0'} - - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - std-env@3.7.0: - resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} - - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - - tinybench@2.8.0: - resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} - - tinypool@1.0.0: - resolution: {integrity: sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==} - engines: {node: ^18.0.0 || >=20.0.0} - - tinyrainbow@1.2.0: - resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} - engines: {node: '>=14.0.0'} - - tinyspy@3.0.0: - resolution: {integrity: sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==} - engines: {node: '>=14.0.0'} - - tslib@2.6.3: - resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} - - tsx@4.16.2: - resolution: {integrity: sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==} - engines: {node: '>=18.0.0'} - hasBin: true - - tunnel@0.0.6: - resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} - engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} - - typescript@5.5.3: - resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - undici@5.28.4: - resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} - engines: {node: '>=14.0'} - - uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - - vite-node@2.0.3: - resolution: {integrity: sha512-14jzwMx7XTcMB+9BhGQyoEAmSl0eOr3nrnn+Z12WNERtOvLN+d2scbRUvyni05rT3997Bg+rZb47NyP4IQPKXg==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - - vite@5.3.3: - resolution: {integrity: sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - - vitest@2.0.3: - resolution: {integrity: sha512-o3HRvU93q6qZK4rI2JrhKyZMMuxg/JRt30E6qeQs6ueaiz5hr1cPj+Sk2kATgQzMMqsa2DiNI0TIK++1ULx8Jw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.0.3 - '@vitest/ui': 2.0.3 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - -snapshots: - - '@actions/core@1.10.1': - dependencies: - '@actions/http-client': 2.2.1 - uuid: 8.3.2 - - '@actions/http-client@2.2.1': - dependencies: - tunnel: 0.0.6 - undici: 5.28.4 - - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - - '@esbuild/aix-ppc64@0.21.5': - optional: true - - '@esbuild/android-arm64@0.21.5': - optional: true - - '@esbuild/android-arm@0.21.5': - optional: true - - '@esbuild/android-x64@0.21.5': - optional: true - - '@esbuild/darwin-arm64@0.21.5': - optional: true - - '@esbuild/darwin-x64@0.21.5': - optional: true - - '@esbuild/freebsd-arm64@0.21.5': - optional: true - - '@esbuild/freebsd-x64@0.21.5': - optional: true - - '@esbuild/linux-arm64@0.21.5': - optional: true - - '@esbuild/linux-arm@0.21.5': - optional: true - - '@esbuild/linux-ia32@0.21.5': - optional: true - - '@esbuild/linux-loong64@0.21.5': - optional: true - - '@esbuild/linux-mips64el@0.21.5': - optional: true - - '@esbuild/linux-ppc64@0.21.5': - optional: true - - '@esbuild/linux-riscv64@0.21.5': - optional: true - - '@esbuild/linux-s390x@0.21.5': - optional: true - - '@esbuild/linux-x64@0.21.5': - optional: true - - '@esbuild/netbsd-x64@0.21.5': - optional: true - - '@esbuild/openbsd-x64@0.21.5': - optional: true - - '@esbuild/sunos-x64@0.21.5': - optional: true - - '@esbuild/win32-arm64@0.21.5': - optional: true - - '@esbuild/win32-ia32@0.21.5': - optional: true - - '@esbuild/win32-x64@0.21.5': - optional: true - - '@fastify/busboy@2.1.1': {} - - '@jridgewell/gen-mapping@0.3.5': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.5.0': {} - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - - '@rollup/rollup-android-arm-eabi@4.18.1': - optional: true - - '@rollup/rollup-android-arm64@4.18.1': - optional: true - - '@rollup/rollup-darwin-arm64@4.18.1': - optional: true - - '@rollup/rollup-darwin-x64@4.18.1': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.18.1': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.18.1': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.18.1': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.18.1': - optional: true - - '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.18.1': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.18.1': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.18.1': - optional: true - - '@rollup/rollup-linux-x64-musl@4.18.1': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.18.1': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.18.1': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.18.1': - optional: true - - '@types/estree@1.0.5': {} - - '@types/node@20.14.10': - dependencies: - undici-types: 5.26.5 - - '@vitest/expect@2.0.3': - dependencies: - '@vitest/spy': 2.0.3 - '@vitest/utils': 2.0.3 - chai: 5.1.1 - tinyrainbow: 1.2.0 - - '@vitest/pretty-format@2.0.3': - dependencies: - tinyrainbow: 1.2.0 - - '@vitest/runner@2.0.3': - dependencies: - '@vitest/utils': 2.0.3 - pathe: 1.1.2 - - '@vitest/snapshot@2.0.3': - dependencies: - '@vitest/pretty-format': 2.0.3 - magic-string: 0.30.10 - pathe: 1.1.2 - - '@vitest/spy@2.0.3': - dependencies: - tinyspy: 3.0.0 - - '@vitest/utils@2.0.3': - dependencies: - '@vitest/pretty-format': 2.0.3 - estree-walker: 3.0.3 - loupe: 3.1.1 - tinyrainbow: 1.2.0 - - assertion-error@2.0.1: {} - - asynckit@0.4.0: {} - - axios@1.7.7: - dependencies: - follow-redirects: 1.15.6 - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - cac@6.7.14: {} - - chai@5.1.1: - dependencies: - assertion-error: 2.0.1 - check-error: 2.1.1 - deep-eql: 5.0.2 - loupe: 3.1.1 - pathval: 2.0.0 - - check-error@2.1.1: {} - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - debug@4.3.5: - dependencies: - ms: 2.1.2 - - deep-eql@5.0.2: {} - - delayed-stream@1.0.0: {} - - esbuild@0.21.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.5 - - execa@8.0.1: - dependencies: - cross-spawn: 7.0.3 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 - - follow-redirects@1.15.6: {} - - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - - fsevents@2.3.3: - optional: true - - get-func-name@2.0.2: {} - - get-stream@8.0.1: {} - - get-tsconfig@4.7.5: - dependencies: - resolve-pkg-maps: 1.0.0 - - human-signals@5.0.0: {} - - is-stream@3.0.0: {} - - isexe@2.0.0: {} - - jira.js@4.0.1: - dependencies: - axios: 1.7.7 - form-data: 4.0.0 - tslib: 2.6.3 - transitivePeerDependencies: - - debug - - loupe@3.1.1: - dependencies: - get-func-name: 2.0.2 - - magic-string@0.30.10: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 - - merge-stream@2.0.0: {} - - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mimic-fn@4.0.0: {} - - ms@2.1.2: {} - - nanoid@3.3.7: {} - - npm-run-path@5.3.0: - dependencies: - path-key: 4.0.0 - - onetime@6.0.0: - dependencies: - mimic-fn: 4.0.0 - - path-key@3.1.1: {} - - path-key@4.0.0: {} - - pathe@1.1.2: {} - - pathval@2.0.0: {} - - picocolors@1.0.1: {} - - postcss@8.4.39: - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.1 - source-map-js: 1.2.0 - - proxy-from-env@1.1.0: {} - - resolve-pkg-maps@1.0.0: {} - - rollup@4.18.1: - dependencies: - '@types/estree': 1.0.5 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.18.1 - '@rollup/rollup-android-arm64': 4.18.1 - '@rollup/rollup-darwin-arm64': 4.18.1 - '@rollup/rollup-darwin-x64': 4.18.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.18.1 - '@rollup/rollup-linux-arm-musleabihf': 4.18.1 - '@rollup/rollup-linux-arm64-gnu': 4.18.1 - '@rollup/rollup-linux-arm64-musl': 4.18.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.18.1 - '@rollup/rollup-linux-riscv64-gnu': 4.18.1 - '@rollup/rollup-linux-s390x-gnu': 4.18.1 - '@rollup/rollup-linux-x64-gnu': 4.18.1 - '@rollup/rollup-linux-x64-musl': 4.18.1 - '@rollup/rollup-win32-arm64-msvc': 4.18.1 - '@rollup/rollup-win32-ia32-msvc': 4.18.1 - '@rollup/rollup-win32-x64-msvc': 4.18.1 - fsevents: 2.3.3 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - siginfo@2.0.0: {} - - signal-exit@4.1.0: {} - - source-map-js@1.2.0: {} - - stackback@0.0.2: {} - - std-env@3.7.0: {} - - strip-final-newline@3.0.0: {} - - tinybench@2.8.0: {} - - tinypool@1.0.0: {} - - tinyrainbow@1.2.0: {} - - tinyspy@3.0.0: {} - - tslib@2.6.3: {} - - tsx@4.16.2: - dependencies: - esbuild: 0.21.5 - get-tsconfig: 4.7.5 - optionalDependencies: - fsevents: 2.3.3 - - tunnel@0.0.6: {} - - typescript@5.5.3: {} - - undici-types@5.26.5: {} - - undici@5.28.4: - dependencies: - '@fastify/busboy': 2.1.1 - - uuid@8.3.2: {} - - vite-node@2.0.3(@types/node@20.14.10): - dependencies: - cac: 6.7.14 - debug: 4.3.5 - pathe: 1.1.2 - tinyrainbow: 1.2.0 - vite: 5.3.3(@types/node@20.14.10) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - vite@5.3.3(@types/node@20.14.10): - dependencies: - esbuild: 0.21.5 - postcss: 8.4.39 - rollup: 4.18.1 - optionalDependencies: - '@types/node': 20.14.10 - fsevents: 2.3.3 - - vitest@2.0.3(@types/node@20.14.10): - dependencies: - '@ampproject/remapping': 2.3.0 - '@vitest/expect': 2.0.3 - '@vitest/pretty-format': 2.0.3 - '@vitest/runner': 2.0.3 - '@vitest/snapshot': 2.0.3 - '@vitest/spy': 2.0.3 - '@vitest/utils': 2.0.3 - chai: 5.1.1 - debug: 4.3.5 - execa: 8.0.1 - magic-string: 0.30.10 - pathe: 1.1.2 - std-env: 3.7.0 - tinybench: 2.8.0 - tinypool: 1.0.0 - tinyrainbow: 1.2.0 - vite: 5.3.3(@types/node@20.14.10) - vite-node: 2.0.3(@types/node@20.14.10) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 20.14.10 - transitivePeerDependencies: - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 diff --git a/.github/scripts/jira/tsconfig.json b/.github/scripts/jira/tsconfig.json deleted file mode 100644 index 3e3216e6e0..0000000000 --- a/.github/scripts/jira/tsconfig.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "ES2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - - /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ - // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ - // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ - // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ - // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - - /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -} diff --git a/.github/scripts/jira/update-jira-issue.ts b/.github/scripts/jira/update-jira-issue.ts deleted file mode 100644 index 6e539c7ffa..0000000000 --- a/.github/scripts/jira/update-jira-issue.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as core from "@actions/core"; -import jira from "jira.js"; -import { tagsToLabels, createJiraClient, parseIssueNumberFrom } from "./lib"; - -function updateJiraIssue( - client: jira.Version3Client, - issueNumber: string, - tags: string[], - fixVersionName: string, - dryRun: boolean -) { - const payload = { - issueIdOrKey: issueNumber, - update: { - labels: tagsToLabels(tags), - fixVersions: [{ set: [{ name: fixVersionName }] }], - }, - }; - - core.info( - `Updating JIRA issue ${issueNumber} with fix version ${fixVersionName} and labels [${payload.update.labels.join( - ", " - )}]` - ); - if (dryRun) { - core.info("Dry run enabled, skipping JIRA issue update"); - return; - } - - return client.issues.editIssue(payload); -} - -async function main() { - const prTitle = process.env.PR_TITLE; - const commitMessage = process.env.COMMIT_MESSAGE; - const branchName = process.env.BRANCH_NAME; - - const chainlinkVersion = process.env.CHAINLINK_VERSION; - const dryRun = !!process.env.DRY_RUN; - // tags are not getting used at the current moment so will always default to [] - const tags = process.env.FOUND_TAGS ? process.env.FOUND_TAGS.split(",") : []; - - const client = createJiraClient(); - - // Checks for the Jira issue number and exit if it can't find it - const issueNumber = parseIssueNumberFrom(prTitle, commitMessage, branchName); - if (!issueNumber) { - const msg = - "No JIRA issue number found in: PR title, commit message, or branch name. Please include the issue ID in one of these."; - - core.info(msg); - core.notice(msg); - core.setOutput("jiraComment", `> :medal_military: ${msg}`); - - return; - } - - const fixVersionName = `chainlink-v${chainlinkVersion}`; - await updateJiraIssue(client, issueNumber, tags, fixVersionName, dryRun); - - core.setOutput("jiraComment", ""); -} - -async function run() { - try { - await main(); - } catch (error) { - if (error instanceof Error) { - core.setFailed(error.message); - } - core.setFailed( - "Error: Failed to update JIRA issue with fix version and labels." - ); - } -} - -run(); diff --git a/.github/workflows/changeset.yml b/.github/workflows/changeset.yml index 0d8c3a828b..9d953bc73a 100644 --- a/.github/workflows/changeset.yml +++ b/.github/workflows/changeset.yml @@ -82,19 +82,34 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # we need to set the top level directory for the jira-tracing action manually + # because now we are working with two repositories and automatic detection would + # select the repository with jira-tracing and not the chainlink repository + - name: Setup git top level directory + id: find-git-top-level-dir + run: echo "top_level_dir=$(pwd)" >> $GITHUB_OUTPUT + + - name: Checkout .Github repository + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + repository: smartcontractkit/.github + ref: 228acc0a7f9f0092450a7673786462832bf3d19c + path: ./dot_github + - name: Update Jira ticket for core id: jira if: ${{ steps.files-changed.outputs.core == 'true' || steps.files-changed.outputs.shared == 'true' }} shell: bash - working-directory: ./.github/scripts/jira + working-directory: ./dot_github/libs/jira-tracing run: | echo "COMMIT_MESSAGE=$(git log -1 --pretty=format:'%s')" >> $GITHUB_ENV - pnpm install && pnpm issue:update + pnpm install && pnpm issue:update env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} JIRA_HOST: ${{ vars.JIRA_HOST }} JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} + GIT_TOP_LEVEL_DIR: ${{ steps.find-git-top-level-dir.outputs.top_level_dir }} CHAINLINK_VERSION: ${{ steps.chainlink-version.outputs.chainlink_version }} PR_TITLE: ${{ github.event.pull_request.title }} BRANCH_NAME: ${{ github.event.pull_request.head.ref }} diff --git a/.github/workflows/solidity-foundry-artifacts.yml b/.github/workflows/solidity-foundry-artifacts.yml index b8f56d977e..2a3f6677b0 100644 --- a/.github/workflows/solidity-foundry-artifacts.yml +++ b/.github/workflows/solidity-foundry-artifacts.yml @@ -25,6 +25,11 @@ on: base_ref: description: 'commit or tag to use as base reference, when looking for modified Solidity files' required: true + link_with_jira: + description: 'link generated artifacts with Jira issues?' + type: boolean + default: true + required: false env: FOUNDRY_PROFILE: ci @@ -70,12 +75,12 @@ jobs: - *ignored sol: - modified|added: 'contracts/src/v0.8/**/*.sol' - - *ignored + - *ignored product: &product - - modified|added: 'contracts/src/v0.8/${{ inputs.product }}/**/*.sol' + - modified|added: 'contracts/src/v0.8/${{ inputs.product }}/**/*.sol' - *ignored changeset: - - modified|added: 'contracts/.changeset/!(README)*.md' + - modified|added: 'contracts/.changeset/!(README)*.md' # Manual transformation needed, because shared contracts have a different folder structure - name: Transform modified files @@ -113,18 +118,16 @@ jobs: sol_files: ${{ steps.changes-dorny.outputs.sol_files }} product: ${{ inputs.product }} - gather-basic-info: - name: Gather basic info - if: ${{ needs.changes.outputs.product_changes == 'true' }} + prepare-workflow-inputs: + name: Prepare workflow inputs runs-on: ubuntu-22.04 needs: [ changes ] outputs: foundry_version: ${{ steps.extract-foundry-version.outputs.foundry-version }} + generate_code_coverage: ${{ steps.skip-code-coverage.outputs.generate_code_coverage }} steps: - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - name: Extract Foundry version id: extract-foundry-version @@ -132,297 +135,35 @@ jobs: with: working-directory: contracts - - name: Copy modified changesets - if: ${{ needs.changes.outputs.changeset_changes == 'true' }} - run: | - mkdir -p contracts/changesets - files="${{ needs.changes.outputs.changeset_files }}" - IFS="," - for changeset in $files; do - echo "::debug:: Copying $changeset" - cp $changeset contracts/changesets - done - - - name: Generate basic info and modified contracts list - shell: bash - run: | - echo "Product: ${{ inputs.product }}" > contracts/commit_sha_base_ref.txt - echo "Commit SHA used to generate artifacts: ${{ env.head_ref }}" >> contracts/commit_sha_base_ref.txt - echo "Base reference SHA used to find modified contracts: ${{ inputs.base_ref }}" >> contracts/commit_sha_base_ref.txt - - IFS=',' read -r -a modified_files <<< "${{ needs.changes.outputs.product_files }}" - echo "# Modified contracts:" > contracts/modified_contracts.md - for file in "${modified_files[@]}"; do - echo " - [$file](${{ github.server_url }}/${{ github.repository }}/blob/${{ env.head_ref }}/$file)" >> contracts/modified_contracts.md - echo "$file" >> contracts/modified_contracts.txt - done - - - name: Upload basic info and modified contracts list - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 - timeout-minutes: 2 - continue-on-error: true - with: - name: tmp-basic-info - path: | - contracts/modified_contracts.md - contracts/modified_contracts.txt - contracts/commit_sha_base_ref.txt - contracts/changesets - retention-days: 7 - - # some of the artifacts can only be generated on product level, and we cannot scope them to single contracts - # some product-level modifications might also require shared contracts changes, so if these happened we need to generate artifacts for shared contracts as well - coverage-and-book: - if: ${{ needs.changes.outputs.product_changes == 'true' }} - name: Generate Docs and Code Coverage reports - runs-on: ubuntu-22.04 - needs: [changes, gather-basic-info] - steps: - - name: Prepare exclusion list - id: prepare-exclusion-list + - name: Should skip code coverage report + id: skip-code-coverage run: | - cat < coverage_exclusions.json - ["automation", "functions", "vrf"] - EOF - coverage_exclusions=$(cat coverage_exclusions.json | jq -c .) - echo "coverage_exclusions=$coverage_exclusions" >> $GITHUB_OUTPUT - - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ env.head_ref }} - - - name: Setup NodeJS - uses: ./.github/actions/setup-nodejs - - - name: Create directories - shell: bash - run: | - mkdir -p contracts/code-coverage - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@8f1998e9878d786675189ef566a2e4bf24869773 # v1.2.0 - with: - version: ${{ needs.gather-basic-info.outputs.foundry_version }} - - # required for code coverage report generation - - name: Setup LCOV - uses: hrishikesh-kadam/setup-lcov@f5da1b26b0dcf5d893077a3c4f29cf78079c841d # v1.0.0 - - - name: Run Forge build for product contracts - if: ${{ needs.changes.outputs.product_changes == 'true' }} - run: | - forge --version - forge build - working-directory: contracts - env: - FOUNDRY_PROFILE: ${{ inputs.product }} - - - name: Run coverage for product contracts - if: ${{ !contains(fromJson(steps.prepare-exclusion-list.outputs.coverage_exclusions), inputs.product) && needs.changes.outputs.product_changes == 'true' }} - working-directory: contracts - run: forge coverage --report lcov --report-file code-coverage/lcov.info - env: - FOUNDRY_PROFILE: ${{ inputs.product }} - - - name: Prune lcov report - if: ${{ !contains(fromJson(steps.prepare-exclusion-list.outputs.coverage_exclusions), inputs.product) && needs.changes.outputs.product_changes == 'true' }} - shell: bash - working-directory: contracts - run: | - ./scripts/lcov_prune ${{ inputs.product }} ./code-coverage/lcov.info ./code-coverage/lcov.info.pruned - - - name: Generate Code Coverage HTML report for product contracts - if: ${{ !contains(fromJson(steps.prepare-exclusion-list.outputs.coverage_exclusions), inputs.product) && needs.changes.outputs.product_changes == 'true' }} - shell: bash - working-directory: contracts - run: genhtml code-coverage/lcov.info.pruned --branch-coverage --output-directory code-coverage - - - name: Run Forge doc for product contracts - if: ${{ needs.changes.outputs.product_changes == 'true' }} - run: forge doc --build -o docs - working-directory: contracts - env: - FOUNDRY_PROFILE: ${{ inputs.product }} - - - name: Upload Artifacts for product contracts - if: ${{ needs.changes.outputs.product_changes == 'true' }} - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 - timeout-minutes: 2 - continue-on-error: true - with: - name: tmp-${{ inputs.product }}-artifacts - path: | - contracts/docs - contracts/code-coverage/lcov-.info - contracts/code-coverage - retention-days: 7 - - # Generates UML diagrams and Slither reports for modified contracts - uml-static-analysis: - if: ${{ needs.changes.outputs.product_changes == 'true' }} - name: Generate UML and Slither reports for modified contracts - runs-on: ubuntu-22.04 - needs: [changes, gather-basic-info] - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - ref: ${{ env.head_ref }} - - - name: Setup NodeJS - uses: ./.github/actions/setup-nodejs - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@8f1998e9878d786675189ef566a2e4bf24869773 # v1.2.0 - with: - version: ${{ needs.gather-basic-info.outputs.foundry_version }} - - - name: Install Sol2uml - run: | - npm link sol2uml --only=production - - - name: Set up Python - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f #v5.1.1 - with: - python-version: '3.8' - - - name: Install solc-select and solc - uses: ./.github/actions/setup-solc-select - with: - to_install: '0.8.19' - to_use: '0.8.19' - - - name: Install Slither - uses: ./.github/actions/setup-slither - - - name: Generate UML - shell: bash - run: | - contract_list="${{ needs.changes.outputs.product_files }}" - - # modify remappings so that solc can find dependencies - ./contracts/scripts/ci/modify_remappings.sh contracts contracts/remappings.txt - mv remappings_modified.txt remappings.txt - - ./contracts/scripts/ci/generate_uml.sh "./" "contracts/uml-diagrams" "$contract_list" - - - name: Generate Slither Markdown reports - run: | - contract_list="${{ needs.changes.outputs.product_files }}" - - # without it Slither sometimes fails to use remappings correctly - cp contracts/foundry.toml foundry.toml - - echo "::debug::Processing contracts: $contract_list" - ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ env.head_ref }}/" contracts/configs/slither/.slither.config-artifacts.json "." "$contract_list" "contracts/slither-reports" "--solc-remaps @=contracts/node_modules/@" - - - name: Upload UMLs and Slither reports - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 - timeout-minutes: 10 - continue-on-error: true - with: - name: tmp-contracts-artifacts - path: | - contracts/uml-diagrams - contracts/slither-reports - retention-days: 7 - - - name: Validate if all Slither run for all contracts - uses: ./.github/actions/validate-solidity-artifacts - with: - validate_slither_reports: 'true' - validate_uml_diagrams: 'true' - slither_reports_path: 'contracts/slither-reports' - uml_diagrams_path: 'contracts/uml-diagrams' - sol_files: ${{ needs.changes.outputs.product_files }} - - gather-all-artifacts: - name: Gather all artifacts - if: ${{ needs.changes.outputs.product_changes == 'true' }} - runs-on: ubuntu-latest - needs: [coverage-and-book, uml-static-analysis, gather-basic-info, changes] - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - ref: ${{ env.head_ref }} - - - name: Download all artifacts - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 - with: - path: review_artifacts - merge-multiple: true - - - name: Upload all artifacts as single package - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 - with: - name: review-artifacts-${{ inputs.product }}-${{ inputs.base_ref }}-${{ env.head_ref }} - path: review_artifacts - - - name: Remove temporary artifacts - uses: geekyeggo/delete-artifact@24928e75e6e6590170563b8ddae9fac674508aa1 # v5.0 - with: - name: tmp-* - - - name: Print Artifact URL in job summary - id: gather-all-artifacts - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - ARTIFACTS=$(gh api -X GET repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts) - ARTIFACT_ID=$(echo "$ARTIFACTS" | jq '.artifacts[] | select(.name=="review-artifacts-${{ inputs.product }}-${{ inputs.base_ref }}-${{ env.head_ref }}") | .id') - echo "Artifact ID: $ARTIFACT_ID" - - echo "# Solidity Review Artifact Generated" >> $GITHUB_STEP_SUMMARY - echo "Product: **${{ inputs.product }}**" >> $GITHUB_STEP_SUMMARY - echo "Base Ref used: **${{ inputs.base_ref }}**" >> $GITHUB_STEP_SUMMARY - echo "Commit SHA used: **${{ env.head_ref }}**" >> $GITHUB_STEP_SUMMARY - - artifact_url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/$ARTIFACT_ID" - echo "[Artifact URL]($artifact_url)" >> $GITHUB_STEP_SUMMARY - echo "artifact-url=$artifact_url" >> $GITHUB_OUTPUT - - - name: Setup NodeJS - uses: ./.github/actions/setup-nodejs - - - name: Setup Jira - working-directory: ./.github/scripts/jira - run: pnpm i - - - name: Create Traceability - working-directory: ./.github/scripts/jira - run: | - pnpm issue:traceability - env: - CHANGESET_FILES: ${{ needs.changes.outputs.changeset_files }} - CHAINLINK_PRODUCT: ${{ inputs.product }} - BASE_REF: ${{ inputs.base_ref }} - HEAD_REF: ${{ env.head_ref }} - ARTIFACT_URL: ${{ steps.gather-all-artifacts.outputs.artifact-url }} - - JIRA_HOST: ${{ vars.JIRA_HOST }} - JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if [[ "${{ inputs.product }}" = "automation" || "${{ inputs.product }}" = "vrf" || "${{ inputs.product }}" = "functions" ]]; then + echo "generate_code_coverage=false" >> $GITHUB_OUTPUT + else + echo "generate_code_coverage=true" >> $GITHUB_OUTPUT + fi - notify-no-changes: - if: ${{ needs.changes.outputs.product_changes == 'false' }} - needs: [changes] - runs-on: ubuntu-latest - steps: - - name: Print warning in job summary - shell: bash - run: | - echo "# Solidity Review Artifact NOT Generated" >> $GITHUB_STEP_SUMMARY - echo "Base Ref used: **${{ inputs.base_ref }}**" >> $GITHUB_STEP_SUMMARY - echo "Commit SHA used: **${{ env.head_ref }}**" >> $GITHUB_STEP_SUMMARY - echo "## Reason: No modified Solidity files found for ${{ inputs.product }}" >> $GITHUB_STEP_SUMMARY - echo "* no modified Solidity files found between ${{ inputs.base_ref }} and ${{ env.head_ref }} commits" >> $GITHUB_STEP_SUMMARY - echo "* or they are located outside of ./contracts/src/v0.8 folder" >> $GITHUB_STEP_SUMMARY - echo "* or they were limited to test files" >> $GITHUB_STEP_SUMMARY - exit 1 + generate-artifacts: + name: Generate Solidity Review Artifacts + needs: [changes, prepare-workflow-inputs] + uses: smartcontractkit/.github/.github/workflows/solidity-review-artifacts.yml@b6e37806737eef87e8c9137ceeb23ef0bff8b1db # validate-solidity-artifacts@0.1.0 + with: + product: ${{ inputs.product }} + commit_to_use: ${{ inputs.commit_to_use }} + base_ref: ${{ inputs.base_ref }} + product_changes: ${{ needs.changes.outputs.product_changes }} + product_files: ${{ needs.changes.outputs.product_files }} + changeset_changes: ${{ needs.changes.outputs.changeset_changes }} + changeset_files: ${{ needs.changes.outputs.changeset_files }} + foundry_version: ${{ needs.prepare-workflow-inputs.outputs.foundry_version }} + contracts_directory: './contracts' + generate_code_coverage: ${{ needs.prepare-workflow-inputs.outputs.generate_code_coverage == 'true' }} + link_with_jira: ${{ inputs.link_with_jira }} + jira_host: ${{ vars.JIRA_HOST }} + install_semver: false + slither_config_file_path: 'contracts/configs/slither/.slither.config-artifacts.json' + lcov_prune_script_path: 'scripts/lcov_prune' + secrets: + jira_username: ${{ secrets.JIRA_USERNAME }} + jira_api_token: ${{ secrets.JIRA_API_TOKEN }} diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index 4b2d7b9b96..e7e8089310 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -40,7 +40,7 @@ jobs: { "name": "vrf", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": false, "run-forge-fmt": false }} ] EOF - + matrix=$(cat matrix.json | jq -c .) echo "matrix=$matrix" >> $GITHUB_OUTPUT @@ -74,7 +74,7 @@ jobs: list-files: 'shell' filters: | non_src: - - '.github/workflows/solidity-foundry.yml' + - '.github/workflows/solidity-foundry.yml' - 'contracts/foundry.toml' - 'contracts/gas-snapshots/*.gas-snapshot' - 'contracts/package.json' @@ -130,7 +130,7 @@ jobs: - '!contracts/src/v0.8/*.t.sol' - '!contracts/src/v0.8/**/testhelpers/**' - '!contracts/src/v0.8/testhelpers/**' - - '!contracts/src/v0.8/vendor/**' + - '!contracts/src/v0.8/vendor/**' tests: if: ${{ needs.changes.outputs.non_src_changes == 'true' || needs.changes.outputs.sol_modified_added == 'true' }} @@ -161,6 +161,8 @@ jobs: || contains(fromJson(needs.changes.outputs.all_changes), 'shared') || needs.changes.outputs.non_src_changes == 'true' }} uses: ./.github/actions/setup-nodejs + with: + prod: "true" - name: Install Foundry if: ${{ contains(fromJson(needs.changes.outputs.all_changes), matrix.product.name) @@ -271,10 +273,15 @@ jobs: if: needs.changes.outputs.not_test_sol_modified == 'true' runs-on: ubuntu-22.04 steps: - - name: Checkout the repo + - name: Checkout this repository + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Checkout .github repository uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: - submodules: recursive + repository: smartcontractkit/.github + ref: b6e37806737eef87e8c9137ceeb23ef0bff8b1db # validate-solidity-artifacts@0.1.0 + path: ./dot_github - name: Setup NodeJS uses: ./.github/actions/setup-nodejs @@ -290,26 +297,26 @@ jobs: python-version: '3.8' - name: Install solc-select and solc - uses: ./.github/actions/setup-solc-select + uses: smartcontractkit/.github/actions/setup-solc-select@b6e37806737eef87e8c9137ceeb23ef0bff8b1db # validate-solidity-artifacts@0.1.0 with: - to_install: '0.8.19' - to_use: '0.8.19' + to_install: '0.8.24' + to_use: '0.8.24' - name: Install Slither - uses: ./.github/actions/setup-slither + uses: smartcontractkit/.github/actions/setup-slither@b6e37806737eef87e8c9137ceeb23ef0bff8b1db # validate-solidity-artifacts@0.1.0 - name: Run Slither shell: bash - run: | + run: | # modify remappings so that solc can find dependencies - ./contracts/scripts/ci/modify_remappings.sh contracts contracts/remappings.txt + ./dot_github/tools/scripts/solidity/modify_remappings.sh contracts contracts/remappings.txt mv remappings_modified.txt remappings.txt - + # without it Slither sometimes fails to use remappings correctly - cp contracts/foundry.toml foundry.toml + cp contracts/foundry.toml foundry.toml + + FILES="${{ needs.changes.outputs.not_test_sol_modified_files }}" - FILES="${{ needs.changes.outputs.not_test_sol_modified_files }}" - for FILE in $FILES; do PRODUCT=$(echo "$FILE" | awk -F'src/[^/]*/' '{print $2}' | cut -d'/' -f1) echo "::debug::Running Slither for $FILE in $PRODUCT" @@ -318,7 +325,7 @@ jobs: echo "::debug::No Slither config found for $PRODUCT, using default" SLITHER_CONFIG="contracts/configs/slither/.slither.config-default-pr.json" fi - ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/" "$SLITHER_CONFIG" "." "$FILE" "contracts/slither-reports-current" "--solc-remaps @=contracts/node_modules/@" + ./dot_github/tools/scripts/solidity/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/" "$SLITHER_CONFIG" "./contracts" "$FILE" "contracts/slither-reports-current" "--solc-remaps @=contracts/node_modules/@" done # all the actions below, up to printing results, run only if any existing contracts were modified @@ -341,7 +348,7 @@ jobs: continue-on-error: true with: name: tmp-slither-scripts-${{ github.sha }} - path: contracts/scripts/ci + path: ./dot_github/tools/scripts/solidity retention-days: 7 - name: Upload configs @@ -354,7 +361,7 @@ jobs: path: contracts/configs retention-days: 7 - - name: Checkout the repo + - name: Checkout earlier version of this repository if: needs.changes.outputs.sol_mod_only == 'true' uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: @@ -365,7 +372,7 @@ jobs: uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tmp-slither-scripts-${{ github.sha }} - path: contracts/scripts/ci + path: ./dot_github/tools/scripts/solidity - name: Download configs if: needs.changes.outputs.sol_mod_only == 'true' @@ -384,19 +391,19 @@ jobs: shell: bash run: | # we need to set file permission again since they are lost during download - for file in contracts/scripts/ci/*.sh; do + for file in ./dot_github/tools/scripts/solidity/*.sh; do chmod +x "$file" done - + # modify remappings so that solc can find dependencies - ./contracts/scripts/ci/modify_remappings.sh contracts contracts/remappings.txt + ./dot_github/tools/scripts/solidity/modify_remappings.sh contracts contracts/remappings.txt mv remappings_modified.txt remappings.txt - + # without it Slither sometimes fails to use remappings correctly cp contracts/foundry.toml foundry.toml - + FILES="${{ needs.changes.outputs.sol_mod_only_files }}" - + for FILE in $FILES; do PRODUCT=$(echo "$FILE" | awk -F'src/[^/]*/' '{print $2}' | cut -d'/' -f1) echo "::debug::Running Slither for $FILE in $PRODUCT" @@ -405,8 +412,8 @@ jobs: echo "::debug::No Slither config found for $PRODUCT, using default" SLITHER_CONFIG="contracts/configs/slither/.slither.config-default-pr.json" fi - ./contracts/scripts/ci/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/" "$SLITHER_CONFIG" "." "$FILE" "contracts/slither-reports-base-ref" "--solc-remaps @=contracts/node_modules/@" - done + ./dot_github/tools/scripts/solidity/generate_slither_report.sh "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.sha }}/" "$SLITHER_CONFIG" "./contracts" "$FILE" "contracts/slither-reports-base-ref" "--solc-remaps @=contracts/node_modules/@" + done - name: Upload Slither report if: needs.changes.outputs.sol_mod_only == 'true' @@ -438,19 +445,19 @@ jobs: current_report="contracts/slither-reports-current/$filename" new_issues_report="contracts/slither-reports-current/${filename%.md}_new_issues.md" if [ -f "$current_report" ]; then - if ./contracts/scripts/ci/find_slither_report_diff.sh "$base_report" "$current_report" "$new_issues_report" "contracts/scripts/ci/prompt-difference.md" "contracts/scripts/ci/prompt-validation.md"; then - if [[ -s $new_issues_report ]]; then - awk 'NR==2{print "*This new issues report has been automatically generated by LLM model using two Slither reports. One based on `${{ github.base_ref}}` and another on `${{ github.sha }}` commits.*"}1' $new_issues_report > tmp.md && mv tmp.md $new_issues_report - echo "Replacing full Slither report with diff for $current_report" + if ./contracts/scripts/ci/find_slither_report_diff.sh "$base_report" "$current_report" "$new_issues_report" "contracts/scripts/ci/prompt-difference.md" "contracts/scripts/ci/prompt-validation.md"; then + if [[ -s $new_issues_report ]]; then + awk 'NR==2{print "*This new issues report has been automatically generated by LLM model using two Slither reports. One based on `${{ github.base_ref}}` and another on `${{ github.sha }}` commits.*"}1' $new_issues_report > tmp.md && mv tmp.md $new_issues_report + echo "Replacing full Slither report with diff for $current_report" rm $current_report && mv $new_issues_report $current_report - else + else echo "No difference detected between $base_report and $current_report reports. Won't include any of them." rm $current_report fi else echo "::warning::Failed to generate a diff report with new issues for $base_report using an LLM model, will use full report." fi - + else echo "::warning::Failed to find current commit's equivalent of $base_report (file $current_report doesn't exist, but should have been generated). Please check Slither logs." fi @@ -468,7 +475,7 @@ jobs: done - name: Validate if all Slither run for all contracts - uses: ./.github/actions/validate-solidity-artifacts + uses: smartcontractkit/.github/actions/validate-solidity-artifacts@b6e37806737eef87e8c9137ceeb23ef0bff8b1db # validate-solidity-artifacts@0.1.0 with: validate_slither_reports: 'true' slither_reports_path: 'contracts/slither-reports-current' @@ -506,9 +513,9 @@ jobs: ARTIFACTS=$(gh api -X GET repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts) ARTIFACT_ID=$(echo "$ARTIFACTS" | jq '.artifacts[] | select(.name=="slither-reports-${{ github.sha }}") | .id') echo "Artifact ID: $ARTIFACT_ID" - + slither_artifact_url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/$ARTIFACT_ID" - echo "slither_artifact_url=$slither_artifact_url" >> $GITHUB_OUTPUT + echo "slither_artifact_url=$slither_artifact_url" >> $GITHUB_OUTPUT - name: Create or update Slither comment in the PR uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0 @@ -518,7 +525,7 @@ jobs: body: | ## Static analysis results are available Hey @${{ github.event.push && github.event.push.pusher && github.event.push.pusher.username || github.actor }}, you can view Slither reports in the job summary [here](${{ steps.job-summary-url.outputs.job_summary_url }}) or download them as artifact [here](${{ steps.build-slither-artifact-url.outputs.slither_artifact_url }}). - + Please check them before merging and make sure you have addressed all issues. edit-mode: replace diff --git a/.github/workflows/solidity-tracability.yml b/.github/workflows/solidity-tracability.yml index 9c61d4adbc..2110dd7dd6 100644 --- a/.github/workflows/solidity-tracability.yml +++ b/.github/workflows/solidity-tracability.yml @@ -91,23 +91,38 @@ jobs: - name: Setup NodeJS uses: ./.github/actions/setup-nodejs + - name: Checkout .Github repository + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + repository: smartcontractkit/.github + ref: b6e37806737eef87e8c9137ceeb23ef0bff8b1db # validate-solidity-artifacts@0.1.0 + path: ./dot_github + + # we need to set the top level directory for the jira-tracing action manually + # because now we are working with two repositories and automatic detection would + # select the repository with jira-tracing and not the chainlink repository + - name: Setup git top level directory + id: find-git-top-level-dir + run: echo "top_level_dir=$(pwd)" >> $GITHUB_OUTPUT + - name: Setup Jira - working-directory: ./.github/scripts/jira - run: pnpm i + working-directory: ./dot_github + run: pnpm install --filter jira-tracing # Because of our earlier checks, we know that both the source and changeset files have changed - name: Enforce Traceability - working-directory: ./.github/scripts/jira + working-directory: ./dot_github run: | echo "COMMIT_MESSAGE=$(git log -1 --pretty=format:'%s')" >> $GITHUB_ENV - pnpm issue:enforce + pnpm --filter jira-tracing issue:enforce env: CHANGESET_FILES: ${{ needs.files-changed.outputs.changesets_files }} + GIT_TOP_LEVEL_DIR: ${{ steps.find-git-top-level-dir.outputs.top_level_dir }} PR_TITLE: ${{ github.event.pull_request.title }} BRANCH_NAME: ${{ github.event.pull_request.head.ref }} - JIRA_HOST: ${{ vars.JIRA_HOST }} + JIRA_HOST: ${{ vars.JIRA_HOST }} JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} @@ -119,7 +134,7 @@ jobs: commit_message: "[Bot] Update changeset file with jira issue" repo: ${{ github.repository }} branch: ${{ github.head_ref }} - file_pattern: "contracts/.changeset/*" + file_pattern: "contracts/.changeset/*" env: GITHUB_TOKEN: ${{ steps.get-gh-token.outputs.access-token }} diff --git a/.github/workflows/solidity-wrappers.yml b/.github/workflows/solidity-wrappers.yml index bbd7ac0c67..5f593f3a33 100644 --- a/.github/workflows/solidity-wrappers.yml +++ b/.github/workflows/solidity-wrappers.yml @@ -2,7 +2,7 @@ name: Solidity Wrappers # This is its own workflow file rather than being merged into "solidity.yml" to avoid over complicating the conditionals # used for job execution. The jobs in "solidity.yml" are configured around push events, whereas # we only want to generate gethwrappers during pull requests. -on: +on: pull_request: types: - opened @@ -31,7 +31,7 @@ jobs: # On a pull request event, make updates to gethwrappers if there are changes. update-wrappers: needs: [changes] - if: needs.changes.outputs.changes == 'true' + if: needs.changes.outputs.changes == 'true' name: Update Wrappers permissions: actions: read @@ -65,7 +65,7 @@ jobs: - name: Commit any wrapper changes uses: planetscale/ghcommit-action@21a8cda29f55e5cc2cdae0cdbdd08e38dd148c25 # v0.1.37 with: - commit_message: "Update gethwrappers" + commit_message: "Update gethwrappers" repo: ${{ github.repository }} branch: ${{ github.head_ref }} file_pattern: "core/gethwrappers/**/generated/*.go core/gethwrappers/**/generated-wrapper-dependency-versions-do-not-edit.txt" @@ -80,5 +80,5 @@ jobs: org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Update Wrappers + this-job-name: Update Wrappers continue-on-error: true diff --git a/contracts/.changeset/quiet-moles-retire.md b/contracts/.changeset/quiet-moles-retire.md new file mode 100644 index 0000000000..f40eda6a0e --- /dev/null +++ b/contracts/.changeset/quiet-moles-retire.md @@ -0,0 +1,8 @@ +--- +'@chainlink/contracts': patch +--- + +Use reusable workflow for Solidity Artifacts pipeline, move some actions to chainlink-github-actions repository + + +TT-1693 \ No newline at end of file diff --git a/contracts/.tool-versions b/contracts/.tool-versions new file mode 100644 index 0000000000..dfe63496b3 --- /dev/null +++ b/contracts/.tool-versions @@ -0,0 +1 @@ +nodejs 20.13.1 diff --git a/contracts/scripts/ci/generate_slither_report.sh b/contracts/scripts/ci/generate_slither_report.sh deleted file mode 100755 index bc876ae118..0000000000 --- a/contracts/scripts/ci/generate_slither_report.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -function check_chainlink_dir() { - local param_dir="chainlink" - current_dir=$(pwd) - - current_base=$(basename "$current_dir") - - if [[ "$current_base" != "$param_dir" ]]; then - >&2 echo "The script must be run from the root of $param_dir directory" - exit 1 - fi -} - -check_chainlink_dir - -if [ "$#" -lt 5 ]; then - >&2 echo "Generates Markdown Slither reports and saves them to a target directory." - >&2 echo "Usage: $0 [slither extra params]" - exit 1 -fi - -REPO_URL=$1 -CONFIG_FILE=$2 -SOURCE_DIR=$3 -FILES=${4// /} # Remove any spaces from the list of files -TARGET_DIR=$5 -SLITHER_EXTRA_PARAMS=$6 - -run_slither() { - local FILE=$1 - local TARGET_DIR=$2 - - if [[ ! -f "$FILE" ]]; then - >&2 echo "::error:File not found: $FILE" - return 1 - fi - - set +e - source ./contracts/scripts/ci/select_solc_version.sh "$FILE" - if [[ $? -ne 0 ]]; then - >&2 echo "::error::Failed to select Solc version for $FILE" - return 1 - fi - - SLITHER_OUTPUT_FILE="$TARGET_DIR/$(basename "${FILE%.sol}")-slither-report.md" - if ! output=$(slither --config-file "$CONFIG_FILE" "$FILE" --checklist --markdown-root "$REPO_URL" --fail-none $SLITHER_EXTRA_PARAMS); then - >&2 echo "::warning::Slither failed for $FILE" - return 0 - fi - set -e - output=$(echo "$output" | sed '/\*\*THIS CHECKLIST IS NOT COMPLETE\*\*. Use `--show-ignored-findings` to show all the results./d' | sed '/Summary/d') - - echo "# Summary for $FILE" > "$SLITHER_OUTPUT_FILE" - echo "$output" >> "$SLITHER_OUTPUT_FILE" - - if [[ -z "$output" ]]; then - echo "No issues found." >> "$SLITHER_OUTPUT_FILE" - fi -} - -process_files() { - local SOURCE_DIR=$1 - local TARGET_DIR=$2 - local FILES=(${3//,/ }) # Split the comma-separated list into an array - - mkdir -p "$TARGET_DIR" - - for FILE in "${FILES[@]}"; do - FILE=${FILE//\"/} - run_slither "$SOURCE_DIR/$FILE" "$TARGET_DIR" - done -} - -set +e -process_files "$SOURCE_DIR" "$TARGET_DIR" "${FILES[@]}" - -if [[ $? -ne 0 ]]; then - >&2 echo "::warning::Failed to generate some Slither reports" - exit 0 -fi - -echo "Slither reports saved in $TARGET_DIR folder" diff --git a/contracts/scripts/ci/generate_uml.sh b/contracts/scripts/ci/generate_uml.sh deleted file mode 100755 index c71d0a1ac7..0000000000 --- a/contracts/scripts/ci/generate_uml.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -function check_chainlink_dir() { - local param_dir="chainlink" - current_dir=$(pwd) - - current_base=$(basename "$current_dir") - - if [[ "$current_base" != "$param_dir" ]]; then - >&2 echo "The script must be run from the root of $param_dir directory" - exit 1 - fi -} - -check_chainlink_dir - -if [ "$#" -lt 2 ]; then - >&2 echo "Generates UML diagrams for all contracts in a directory after flattening them to avoid call stack overflows." - >&2 echo "Usage: $0 [comma-separated list of files]" - exit 1 -fi - -SOURCE_DIR="$1" -TARGET_DIR="$2" -FILES=${3// /} # Remove any spaces from the list of files -FAILED_FILES=() - -flatten_and_generate_uml() { - local FILE=$1 - local TARGET_DIR=$2 - - set +e - FLATTENED_FILE="$TARGET_DIR/flattened_$(basename "$FILE")" - echo "::debug::Flattening $FILE to $FLATTENED_FILE" - forge flatten "$FILE" -o "$FLATTENED_FILE" --root contracts - if [[ $? -ne 0 ]]; then - >&2 echo "::error::Failed to flatten $FILE" - FAILED_FILES+=("$FILE") - return - fi - - OUTPUT_FILE=${FLATTENED_FILE//"flattened_"/""} - OUTPUT_FILE_SVG="${OUTPUT_FILE%.sol}.svg" - echo "::debug::Generating SVG UML for $FLATTENED_FILE to $OUTPUT_FILE_SVG" - sol2uml "$FLATTENED_FILE" -o "$OUTPUT_FILE_SVG" - if [[ $? -ne 0 ]]; then - >&2 echo "::error::Failed to generate UML diagram in SVG format for $FILE" - FAILED_FILES+=("$FILE") - rm "$FLATTENED_FILE" - return - fi - OUTPUT_FILE_DOT="${OUTPUT_FILE%.sol}.dot" - echo "::debug::Generating DOT UML for $FLATTENED_FILE to $OUTPUT_FILE_DOT" - sol2uml "$FLATTENED_FILE" -o "$OUTPUT_FILE_DOT" -f dot - if [[ $? -ne 0 ]]; then - >&2 echo "::error::Failed to generate UML diagram in DOT format for $FILE" - FAILED_FILES+=("$FILE") - rm "$FLATTENED_FILE" - return - fi - - rm "$FLATTENED_FILE" - set -e -} - -process_all_files_in_directory() { - local SOURCE_DIR=$1 - local TARGET_DIR=$2 - - mkdir -p "$TARGET_DIR" - - find "$SOURCE_DIR" -type f -name '*.sol' | while read -r ITEM; do - flatten_and_generate_uml "$ITEM" "$TARGET_DIR" - done -} - -process_selected_files() { - local SOURCE_DIR=$1 - local TARGET_DIR=$2 - local FILES=(${3//,/ }) # Split the comma-separated list into an array - - mkdir -p "$TARGET_DIR" - - for FILE in "${FILES[@]}"; do - FILE=${FILE//\"/} - MATCHES=($(find "$SOURCE_DIR" -type f -path "*/$FILE")) - - if [[ ${#MATCHES[@]} -gt 1 ]]; then - >&2 echo "::error:: Multiple matches found for $FILE:" - for MATCH in "${MATCHES[@]}"; do - >&2 echo " $MATCH" - done - exit 1 - elif [[ ${#MATCHES[@]} -eq 1 ]]; then - >&2 echo "::debug::File found: ${MATCHES[0]}" - flatten_and_generate_uml "${MATCHES[0]}" "$TARGET_DIR" - else - >&2 echo "::error::File $FILE does not exist within the source directory $SOURCE_DIR." - exit 1 - fi - done -} - -# if FILES is empty, process all files in the directory, otherwise process only the selected files -if [[ -z "$FILES" ]]; then - process_all_files_in_directory "$SOURCE_DIR" "$TARGET_DIR" -else - process_selected_files "$SOURCE_DIR" "$TARGET_DIR" "$FILES" -fi - -if [[ "${#FAILED_FILES[@]}" -gt 0 ]]; then - >&2 echo ":error::Failed to generate UML diagrams for ${#FAILED_FILES[@]} files:" - for FILE in "${FAILED_FILES[@]}"; do - >&2 echo " $FILE" - echo "$FILE" >> "$TARGET_DIR/uml_generation_failures.txt" - done -fi - -echo "UML diagrams saved in $TARGET_DIR folder" diff --git a/contracts/scripts/ci/modify_remappings.sh b/contracts/scripts/ci/modify_remappings.sh deleted file mode 100755 index e64ca369b0..0000000000 --- a/contracts/scripts/ci/modify_remappings.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -if [ "$#" -ne 2 ]; then - >&2 echo "Usage: $0 " - exit 1 -fi - -DIR_PREFIX=$1 -REMAPPINGS_FILE=$2 - -if [ ! -f "$REMAPPINGS_FILE" ]; then - >&2 echo "::error:: Remappings file '$REMAPPINGS_FILE' not found." - exit 1 -fi - -OUTPUT_FILE="remappings_modified.txt" - -while IFS= read -r line; do - if [[ "$line" =~ ^[^=]+= ]]; then - REMAPPED_PATH="${line#*=}" - MODIFIED_LINE="${line%=*}=${DIR_PREFIX}/${REMAPPED_PATH}" - echo "$MODIFIED_LINE" >> "$OUTPUT_FILE" - else - echo "$line" >> "$OUTPUT_FILE" - fi -done < "$REMAPPINGS_FILE" - -echo "Modified remappings have been saved to: $OUTPUT_FILE" diff --git a/contracts/scripts/ci/select_solc_version.sh b/contracts/scripts/ci/select_solc_version.sh deleted file mode 100755 index cfa13de0f6..0000000000 --- a/contracts/scripts/ci/select_solc_version.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -function check_chainlink_dir() { - local param_dir="chainlink" - current_dir=$(pwd) - - current_base=$(basename "$current_dir") - - if [[ "$current_base" != "$param_dir" ]]; then - >&2 echo "::error::The script must be run from the root of $param_dir directory" - exit 1 - fi -} - -check_chainlink_dir - -FILE="$1" - -if [[ "$#" -lt 1 ]]; then - echo "Detects the Solidity version of a file and selects the appropriate Solc version." - echo "If the version is not installed, it will be installed and selected." - echo "Will prefer to use the version from Foundry profile if it satisfies the version in the file." - echo "Usage: $0 " - exit 1 -fi - -if [[ -z "$FILE" ]]; then - >&2 echo "::error:: File not provided." - exit 1 -fi - -extract_product() { - local path=$1 - - echo "$path" | awk -F'src/[^/]*/' '{print $2}' | cut -d'/' -f1 -} - -extract_pragma() { - local FILE=$1 - - if [[ -f "$FILE" ]]; then - SOLCVER="$(grep --no-filename '^pragma solidity' "$FILE" | cut -d' ' -f3)" - else - >&2 echo ":error::$FILE is not a file or it could not be found. Exiting." - return 1 - fi - SOLCVER="$(echo "$SOLCVER" | sed 's/[^0-9\.^]//g')" - >&2 echo "::debug::Detected Solidity version in pragma: $SOLCVER" - echo "$SOLCVER" -} - -echo "Detecting Solc version for $FILE" - -# Set FOUNDRY_PROFILE to the product name only if it is set; otherwise either already set value will be used or it will be empty -PRODUCT=$(extract_product "$FILE") -if [ -n "$PRODUCT" ]; then - FOUNDRY_PROFILE="$PRODUCT" -fi -SOLC_IN_PROFILE=$(forge config --json --root contracts | jq ".solc") -SOLC_IN_PROFILE=$(echo "$SOLC_IN_PROFILE" | tr -d "'\"") -echo "::debug::Detected Solidity version in profile: $SOLC_IN_PROFILE" - -set +e -SOLCVER=$(extract_pragma "$FILE") - -if [[ $? -ne 0 ]]; then - >&2 echo "::error:: Failed to extract the Solidity version from $FILE." - return 1 -fi - -set -e - -SOLCVER=$(echo "$SOLCVER" | tr -d "'\"") - -if [[ "$SOLC_IN_PROFILE" != "null" && -n "$SOLCVER" ]]; then - set +e - COMPAT_SOLC_VERSION=$(npx semver "$SOLC_IN_PROFILE" -r "$SOLCVER") - exit_code=$? - set -e - if [[ $exit_code -eq 0 && -n "$COMPAT_SOLC_VERSION" ]]; then - echo "::debug::Version $SOLC_IN_PROFILE satisfies the constraint $SOLCVER" - SOLC_TO_USE="$SOLC_IN_PROFILE" - else - echo "::debug::Version $SOLC_IN_PROFILE does not satisfy the constraint $SOLCVER" - SOLC_TO_USE="$SOLCVER" - fi - elif [[ "$SOLC_IN_PROFILE" != "null" && -z "$SOLCVER" ]]; then - >&2 echo "::error::No version found in the Solidity file. Exiting" - return 1 - elif [[ "$SOLC_IN_PROFILE" == "null" && -n "$SOLCVER" ]]; then - echo "::debug::Using the version from the file: $SOLCVER" - SOLC_TO_USE="$SOLCVER" - else - >&2 echo "::error::No version found in the profile or the Solidity file." - return 1 -fi - -echo "Will use $SOLC_TO_USE" -SOLC_TO_USE=$(echo "$SOLC_TO_USE" | tr -d "'\"") -SOLC_TO_USE="$(echo "$SOLC_TO_USE" | sed 's/[^0-9\.]//g')" - -INSTALLED_VERSIONS=$(solc-select versions) - -if echo "$INSTALLED_VERSIONS" | grep -q "$SOLC_TO_USE"; then - echo "::debug::Version $SOLCVER is already installed." - if echo "$INSTALLED_VERSIONS" | grep "$SOLC_TO_USE" | grep -q "current"; then - echo "::debug::Version $SOLCVER is already selected." - else - echo "::debug::Selecting $SOLC_TO_USE" - solc-select use "$SOLC_TO_USE" - fi -else - echo "::debug::Version $SOLC_TO_USE is not installed." - solc-select install "$SOLC_TO_USE" - solc-select use "$SOLC_TO_USE" -fi From 818498a098c42e55f3703377f9dcfdb935b3ab38 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Mon, 23 Sep 2024 15:24:01 +0200 Subject: [PATCH 407/432] TT-1459 Use CTF actions from .github repo (#14522) * Update GHA in client-compatibility-tests workflow * bump ctf * Auto fill the version based on the docker image * bump ctf --- .../workflows/client-compatibility-tests.yml | 49 +++++++++---------- .../run-e2e-tests-reusable-workflow.yml | 6 +-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 6 files changed, 33 insertions(+), 34 deletions(-) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 761759193e..c98cecf89d 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -644,19 +644,10 @@ jobs: # comment_on_pr: false # theme: 'dark' - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31 + uses: smartcontractkit/.github/actions/ctf-run-tests@b6e37806737eef87e8c9137ceeb23ef0bff8b1db # ctf-run-tests@0.1.0 with: test_command_to_run: cd ./integration-tests && touch .root_dir && go test -timeout 30m -count=1 -json ${{ matrix.evm_node.run }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download - test_config_chainlink_version: ${{ needs.select-versions.outputs.chainlink_image_version }} - test_config_selected_networks: ${{ env.SELECTED_NETWORKS}} - test_config_logging_run_id: ${{ github.run_id }} - test_config_test_log_collect: ${{ vars.TEST_LOG_COLLECT }} - test_config_logstream_log_targets: ${{ vars.LOGSTREAM_LOG_TARGETS }} - test_config_private_ethereum_network_execution_layer: ${{ matrix.evm_node.eth_implementation || 'geth' }} - test_config_private_ethereum_network_custom_docker_image: ${{ matrix.evm_node.docker_image }} - cl_repo: ${{ env.CHAINLINK_IMAGE }} - cl_image_tag: ${{ needs.select-versions.outputs.chainlink_version }} aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_name: ${{ env.TEST_LOG_NAME }} artifacts_location: | @@ -674,22 +665,30 @@ jobs: should_tidy: "false" go_coverage_src_dir: /var/tmp/go-coverage go_coverage_dest_dir: ${{ github.workspace }}/.covdata - DEFAULT_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} - DEFAULT_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - DEFAULT_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push - DEFAULT_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - DEFAULT_GRAFANA_BASE_URL: "http://localhost:8080/primary" - DEFAULT_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - DEFAULT_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - DEFAULT_PYROSCOPE_SERVER_URL: ${{ secrets.QA_PYROSCOPE_INSTANCE }} - DEFAULT_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} - DEFAULT_PYROSCOPE_ENVIRONMENT: ci-client-compatability-${{ matrix.eth_client }}-testnet - DEFAULT_PYROSCOPE_ENABLED: "true" - - - name: Print failed test summary + env: + E2E_TEST_SELECTED_NETWORK: ${{ env.SELECTED_NETWORKS}} + E2E_TEST_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} + E2E_TEST_CHAINLINK_VERSION: ${{ needs.select-versions.outputs.chainlink_image_version }} + E2E_TEST_LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + E2E_TEST_LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + E2E_TEST_PYROSCOPE_SERVER_URL: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + E2E_TEST_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + E2E_TEST_PYROSCOPE_ENVIRONMENT: ci-client-compatability-${{ matrix.eth_client }}-testnet + E2E_TEST_PYROSCOPE_ENABLED: "true" + E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} + E2E_TEST_LOG_COLLECT: ${{ vars.TEST_LOG_COLLECT }} + E2E_TEST_LOG_STREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} + E2E_TEST_PRIVATE_ETHEREUM_EXECUTION_LAYER: ${{ matrix.evm_node.eth_implementation || 'geth' }} + E2E_TEST_PRIVATE_ETHEREUM_ETHEREUM_VERSION: auto_fill # Auto fill the version based on the docker image + E2E_TEST_PRIVATE_ETHEREUM_CUSTOM_DOCKER_IMAGE: ${{ matrix.evm_node.docker_image }} + + - name: Show Grafana url in test summary if: always() - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@75a9005952a9e905649cfb5a6971fd9429436acd # v2.3.25 - + uses: smartcontractkit/.github/actions/ctf-show-grafana-in-test-summary@b6e37806737eef87e8c9137ceeb23ef0bff8b1db # ctf-show-grafana-in-test-summary@0.1.0 + start-slack-thread: name: Start Slack Thread if: always() && needs.*.result != 'skipped' && needs.*.result != 'cancelled' && needs.should-run.outputs.should_run == 'true' && (needs.select-versions.outputs.evm_implementations != '' || github.event.inputs.base64TestList != '') diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index 8278828a38..c8e3cde085 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -661,7 +661,7 @@ jobs: - name: Show Grafana url in test summary if: always() - uses: smartcontractkit/.github/actions/ctf-show-grafana-in-test-summary@70fcaef0bf3a5a7d8aa681861d2f76e4188863d9 # ctf-show-grafana-in-test-summary@0.0.0 + uses: smartcontractkit/.github/actions/ctf-show-grafana-in-test-summary@b6e37806737eef87e8c9137ceeb23ef0bff8b1db # ctf-show-grafana-in-test-summary@0.1.0 # Run K8s tests using old remote runner @@ -764,7 +764,7 @@ jobs: - name: Run tests id: run_tests - uses: smartcontractkit/.github/actions/ctf-run-tests@b8731364b119e88983e94b0c4da87fc27ddb41b8 # ctf-run-tests@0.0.0 + uses: smartcontractkit/.github/actions/ctf-run-tests@b6e37806737eef87e8c9137ceeb23ef0bff8b1db # ctf-run-tests@0.1.0 env: DETACH_RUNNER: true RR_MEM: ${{ matrix.tests.remote_runner_memory }} @@ -827,7 +827,7 @@ jobs: - name: Show Grafana url in test summary if: always() - uses: smartcontractkit/.github/actions/ctf-show-grafana-in-test-summary@70fcaef0bf3a5a7d8aa681861d2f76e4188863d9 # ctf-show-grafana-in-test-summary@0.0.0 + uses: smartcontractkit/.github/actions/ctf-show-grafana-in-test-summary@b6e37806737eef87e8c9137ceeb23ef0bff8b1db # ctf-show-grafana-in-test-summary@0.1.0 after_tests: needs: [load-test-configurations, run-docker-tests, run-k8s-runner-tests] diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 8387c80782..dbfda153c5 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -42,7 +42,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 - github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.7 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index effab5e3da..dace088e6d 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1439,8 +1439,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202409 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.7 h1:IzDNN3YvQL0yAFLj7fDJqGUDR76ewGhVJx5RiovKDI4= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.7/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8 h1:AdFXA2XxiU5uqLS4ZxA7v+RCz8mhqz2aCxgzbpnja98= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 46824e50fb..9717c843fd 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 - github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.7 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index eb4f92d14e..8f671ac8a8 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1413,8 +1413,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202409 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.7 h1:IzDNN3YvQL0yAFLj7fDJqGUDR76ewGhVJx5RiovKDI4= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.7/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8 h1:AdFXA2XxiU5uqLS4ZxA7v+RCz8mhqz2aCxgzbpnja98= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= From 469e04f6938be27fae807830392dc21941034b7b Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Mon, 23 Sep 2024 16:57:25 +0200 Subject: [PATCH 408/432] [TT-1747] fix core changeset (#14524) * test core changeset * fix fix version * remove test file --- .github/workflows/changeset.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/changeset.yml b/.github/workflows/changeset.yml index 9d953bc73a..ba06eb07e9 100644 --- a/.github/workflows/changeset.yml +++ b/.github/workflows/changeset.yml @@ -93,17 +93,17 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: repository: smartcontractkit/.github - ref: 228acc0a7f9f0092450a7673786462832bf3d19c + ref: b6e37806737eef87e8c9137ceeb23ef0bff8b1db # validate-solidity-artifacts@0.1.0 path: ./dot_github - name: Update Jira ticket for core id: jira if: ${{ steps.files-changed.outputs.core == 'true' || steps.files-changed.outputs.shared == 'true' }} shell: bash - working-directory: ./dot_github/libs/jira-tracing + working-directory: ./dot_github run: | echo "COMMIT_MESSAGE=$(git log -1 --pretty=format:'%s')" >> $GITHUB_ENV - pnpm install && pnpm issue:update + pnpm install --filter jira-tracing && pnpm --filter jira-tracing issue:update env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} JIRA_HOST: ${{ vars.JIRA_HOST }} From 2b1e8ad51b98aa41eca78758d2041ffcd7fba94a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Friedemann=20F=C3=BCrst?= <59653747+friedemannf@users.noreply.github.com> Date: Mon, 23 Sep 2024 19:39:16 +0200 Subject: [PATCH 409/432] Change Polygon zkEVM to use FeeHistory estimator (#14161) * Change Polygon zkEVM to use SuggestedPriceEstimator (SHIP-2885) * Set PriceMin to 1mwei for Polygon zkEVM * Remove Polygon zkEVM Goerli * Enable FeeHistory estimator for Polygon zkEVM * Update PriceMin * apply suggestions * Set CacheTimeout to 2 seconds * Revert back to 5s cachetimeout * Change timeout to 4 seconds --------- Co-authored-by: joaoluisam --- .changeset/tender-lemons-obey.md | 5 + .../toml/defaults/Polygon_Zkevm_Cardona.toml | 10 +- .../toml/defaults/Polygon_Zkevm_Goerli.toml | 24 ---- .../toml/defaults/Polygon_Zkevm_Mainnet.toml | 10 +- docs/CONFIG.md | 123 ++---------------- 5 files changed, 27 insertions(+), 145 deletions(-) create mode 100644 .changeset/tender-lemons-obey.md delete mode 100644 core/chains/evm/config/toml/defaults/Polygon_Zkevm_Goerli.toml diff --git a/.changeset/tender-lemons-obey.md b/.changeset/tender-lemons-obey.md new file mode 100644 index 0000000000..2d6cb774b0 --- /dev/null +++ b/.changeset/tender-lemons-obey.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Enable FeeHistory estimator for Polygon zkEVM #nops diff --git a/core/chains/evm/config/toml/defaults/Polygon_Zkevm_Cardona.toml b/core/chains/evm/config/toml/defaults/Polygon_Zkevm_Cardona.toml index cd91465dae..46ce80e29f 100644 --- a/core/chains/evm/config/toml/defaults/Polygon_Zkevm_Cardona.toml +++ b/core/chains/evm/config/toml/defaults/Polygon_Zkevm_Cardona.toml @@ -13,12 +13,14 @@ ContractConfirmations = 1 ResendAfterThreshold = '3m' [GasEstimator] -PriceMin = '1 mwei' +Mode = 'FeeHistory' +# The FeeHistory estimator does not enforce PriceMin, setting it to 0 to not place any limits on the price +PriceMin = '0' BumpPercent = 40 -BumpMin = '20 mwei' -[GasEstimator.BlockHistory] -BlockHistorySize = 12 +[GasEstimator.FeeHistory] +# Refresh the suggested price every 4 seconds, to stay slightly below their polling rate of 5s +CacheTimeout = '4s' [HeadTracker] HistoryDepth = 2000 diff --git a/core/chains/evm/config/toml/defaults/Polygon_Zkevm_Goerli.toml b/core/chains/evm/config/toml/defaults/Polygon_Zkevm_Goerli.toml deleted file mode 100644 index 6a9b47190f..0000000000 --- a/core/chains/evm/config/toml/defaults/Polygon_Zkevm_Goerli.toml +++ /dev/null @@ -1,24 +0,0 @@ -ChainID = '1442' -ChainType = 'zkevm' -FinalityDepth = 500 -NoNewHeadsThreshold = '12m' -MinIncomingConfirmations = 1 -LogPollInterval = '30s' -RPCDefaultBatchSize = 100 - -[OCR] -ContractConfirmations = 1 - -[Transactions] -ResendAfterThreshold = '3m' - -[GasEstimator] -PriceMin = '50 mwei' -BumpPercent = 40 -BumpMin = '20 mwei' - -[GasEstimator.BlockHistory] -BlockHistorySize = 12 - -[HeadTracker] -HistoryDepth = 2000 diff --git a/core/chains/evm/config/toml/defaults/Polygon_Zkevm_Mainnet.toml b/core/chains/evm/config/toml/defaults/Polygon_Zkevm_Mainnet.toml index 79e0cb0fce..2fef7874d1 100644 --- a/core/chains/evm/config/toml/defaults/Polygon_Zkevm_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/Polygon_Zkevm_Mainnet.toml @@ -14,12 +14,14 @@ ContractConfirmations = 1 ResendAfterThreshold = '3m' [GasEstimator] -PriceMin = '100 mwei' +Mode = 'FeeHistory' +# The FeeHistory estimator does not enforce PriceMin, setting it to 0 to not place any limits on the price +PriceMin = '0' BumpPercent = 40 -BumpMin = '100 mwei' -[GasEstimator.BlockHistory] -BlockHistorySize = 12 +[GasEstimator.FeeHistory] +# Refresh the suggested price every 4 seconds, to stay slightly below their polling rate of 5s +CacheTimeout = '4s' [HeadTracker] # Polygon suffers from a tremendous number of re-orgs, we need to set this to something very large to be conservative enough diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 1512b33cad..1a4a2a4ce2 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -4883,16 +4883,16 @@ Enabled = false Enabled = true [GasEstimator] -Mode = 'BlockHistory' +Mode = 'FeeHistory' PriceDefault = '20 gwei' PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' -PriceMin = '100 mwei' +PriceMin = '0' LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 EstimateLimit = false -BumpMin = '100 mwei' +BumpMin = '5 gwei' BumpPercent = 40 BumpThreshold = 3 EIP1559DynamicFees = false @@ -4902,13 +4902,13 @@ TipCapMin = '1 wei' [GasEstimator.BlockHistory] BatchSize = 25 -BlockHistorySize = 12 +BlockHistorySize = 8 CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 [GasEstimator.FeeHistory] -CacheTimeout = '10s' +CacheTimeout = '4s' [HeadTracker] HistoryDepth = 2000 @@ -5255,109 +5255,6 @@ GasLimitDefault = 400000

    -
    Polygon Zkevm Goerli (1442)

    - -```toml -AutoCreateKey = true -BlockBackfillDepth = 10 -BlockBackfillSkip = false -ChainType = 'zkevm' -FinalityDepth = 500 -FinalityTagEnabled = false -LogBackfillBatchSize = 1000 -LogPollInterval = '30s' -LogKeepBlocksDepth = 100000 -LogPrunePageSize = 0 -BackupLogPollerBlockDelay = 100 -MinIncomingConfirmations = 1 -MinContractPayment = '0.00001 link' -NonceAutoSync = true -NoNewHeadsThreshold = '12m0s' -LogBroadcasterEnabled = true -RPCDefaultBatchSize = 100 -RPCBlockQueryDelay = 1 -FinalizedBlockOffset = 0 -NoNewFinalizedHeadsThreshold = '0s' - -[Transactions] -ForwardersEnabled = false -MaxInFlight = 16 -MaxQueued = 250 -ReaperInterval = '1h0m0s' -ReaperThreshold = '168h0m0s' -ResendAfterThreshold = '3m0s' - -[Transactions.AutoPurge] -Enabled = false - -[BalanceMonitor] -Enabled = true - -[GasEstimator] -Mode = 'BlockHistory' -PriceDefault = '20 gwei' -PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' -PriceMin = '50 mwei' -LimitDefault = 500000 -LimitMax = 500000 -LimitMultiplier = '1' -LimitTransfer = 21000 -EstimateLimit = false -BumpMin = '20 mwei' -BumpPercent = 40 -BumpThreshold = 3 -EIP1559DynamicFees = false -FeeCapDefault = '100 gwei' -TipCapDefault = '1 wei' -TipCapMin = '1 wei' - -[GasEstimator.BlockHistory] -BatchSize = 25 -BlockHistorySize = 12 -CheckInclusionBlocks = 12 -CheckInclusionPercentile = 90 -TransactionPercentile = 60 - -[GasEstimator.FeeHistory] -CacheTimeout = '10s' - -[HeadTracker] -HistoryDepth = 2000 -MaxBufferSize = 3 -SamplingInterval = '1s' -MaxAllowedFinalityDepth = 10000 -FinalityTagBypass = true - -[NodePool] -PollFailureThreshold = 5 -PollInterval = '10s' -SelectionMode = 'HighestHead' -SyncThreshold = 5 -LeaseDuration = '0s' -NodeIsSyncingEnabled = false -FinalizedBlockPollInterval = '5s' -EnforceRepeatableRead = false -DeathDeclarationDelay = '10s' -NewHeadsPollInterval = '0s' - -[OCR] -ContractConfirmations = 1 -ContractTransmitterTransmitTimeout = '10s' -DatabaseTimeout = '10s' -DeltaCOverride = '168h0m0s' -DeltaCJitterOverride = '1h0m0s' -ObservationGracePeriod = '1s' - -[OCR2] -[OCR2.Automation] -GasLimit = 5400000 - -[Workflow] -GasLimitDefault = 400000 -``` - -

    -
    Kroma Sepolia (2358)

    ```toml @@ -5500,16 +5397,16 @@ Enabled = false Enabled = true [GasEstimator] -Mode = 'BlockHistory' +Mode = 'FeeHistory' PriceDefault = '20 gwei' PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' -PriceMin = '1 mwei' +PriceMin = '0' LimitDefault = 500000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 EstimateLimit = false -BumpMin = '20 mwei' +BumpMin = '5 gwei' BumpPercent = 40 BumpThreshold = 3 EIP1559DynamicFees = false @@ -5519,13 +5416,13 @@ TipCapMin = '1 wei' [GasEstimator.BlockHistory] BatchSize = 25 -BlockHistorySize = 12 +BlockHistorySize = 8 CheckInclusionBlocks = 12 CheckInclusionPercentile = 90 TransactionPercentile = 60 [GasEstimator.FeeHistory] -CacheTimeout = '10s' +CacheTimeout = '4s' [HeadTracker] HistoryDepth = 2000 From c7a16eb9aa531edb9870c8720451817ba300ef08 Mon Sep 17 00:00:00 2001 From: Oliver Townsend <133903322+ogtownsend@users.noreply.github.com> Date: Mon, 23 Sep 2024 10:59:36 -0700 Subject: [PATCH 410/432] CCIP-3416 paginate token admin registry get all tokens call (#14514) * paginate token admin registry get all tokens call * add nil check * restructure loop condition --- .../ccip/view/v1_5/tokenadminregistry.go | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/integration-tests/deployment/ccip/view/v1_5/tokenadminregistry.go b/integration-tests/deployment/ccip/view/v1_5/tokenadminregistry.go index 1e704efae7..ebfff8c2fe 100644 --- a/integration-tests/deployment/ccip/view/v1_5/tokenadminregistry.go +++ b/integration-tests/deployment/ccip/view/v1_5/tokenadminregistry.go @@ -9,13 +9,20 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" ) +const ( + GetTokensPaginationSize = 20 +) + type TokenAdminRegistryView struct { types.ContractMetaData Tokens []common.Address `json:"tokens"` } func GenerateTokenAdminRegistryView(taContract *token_admin_registry.TokenAdminRegistry) (TokenAdminRegistryView, error) { - tokens, err := taContract.GetAllConfiguredTokens(nil, 0, 10) + if taContract == nil { + return TokenAdminRegistryView{}, fmt.Errorf("token admin registry contract is nil") + } + tokens, err := getAllConfiguredTokensPaginated(taContract) if err != nil { return TokenAdminRegistryView{}, fmt.Errorf("view error for token admin registry: %w", err) } @@ -28,3 +35,22 @@ func GenerateTokenAdminRegistryView(taContract *token_admin_registry.TokenAdminR Tokens: tokens, }, nil } + +// getAllConfiguredTokensPaginated fetches all configured tokens from the TokenAdminRegistry contract in paginated +// manner to avoid RPC timeouts since the list of configured tokens can grow to be very large over time. +func getAllConfiguredTokensPaginated(taContract *token_admin_registry.TokenAdminRegistry) ([]common.Address, error) { + startIndex := uint64(0) + allTokens := make([]common.Address, 0) + for { + fetchedTokens, err := taContract.GetAllConfiguredTokens(nil, startIndex, GetTokensPaginationSize) + if err != nil { + return nil, err + } + allTokens = append(allTokens, fetchedTokens...) + startIndex += GetTokensPaginationSize + if len(fetchedTokens) < GetTokensPaginationSize { + break + } + } + return allTokens, nil +} From f1b310bfbfb206a959288f65c92c6cc9550bdc3c Mon Sep 17 00:00:00 2001 From: Oliver Townsend <133903322+ogtownsend@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:07:55 -0700 Subject: [PATCH 411/432] CCIP 3388 - add offramp generation (#14526) * add offramp getters * Move GetRemoteChainSelectors to router * run lint * remove unnecessary owner calls --- integration-tests/deployment/ccip/state.go | 11 ++++ .../deployment/ccip/view/chain.go | 2 + .../deployment/ccip/view/v1_2/router.go | 15 +++++ .../deployment/ccip/view/v1_6/feequoter.go | 17 +---- .../deployment/ccip/view/v1_6/offramp.go | 64 +++++++++++++++++++ .../deployment/ccip/view/v1_6/onramp.go | 3 +- 6 files changed, 96 insertions(+), 16 deletions(-) create mode 100644 integration-tests/deployment/ccip/view/v1_6/offramp.go diff --git a/integration-tests/deployment/ccip/state.go b/integration-tests/deployment/ccip/state.go index d6bd889439..efb3416ec3 100644 --- a/integration-tests/deployment/ccip/state.go +++ b/integration-tests/deployment/ccip/state.go @@ -116,6 +116,17 @@ func (c CCIPChainState) GenerateView() (view.ChainView, error) { } chainView.OnRamp[c.OnRamp.Address().Hex()] = onRampView } + + if c.OffRamp != nil && c.Router != nil { + offRampView, err := v1_6.GenerateOffRampView( + c.OffRamp, + c.Router, + ) + if err != nil { + return chainView, err + } + chainView.OffRamp[c.OffRamp.Address().Hex()] = offRampView + } return chainView, nil } diff --git a/integration-tests/deployment/ccip/view/chain.go b/integration-tests/deployment/ccip/view/chain.go index 468e5e7d48..8dbd6cabbb 100644 --- a/integration-tests/deployment/ccip/view/chain.go +++ b/integration-tests/deployment/ccip/view/chain.go @@ -13,6 +13,7 @@ type ChainView struct { Router map[string]v1_2.RouterView `json:"router,omitempty"` RMN map[string]v1_6.RMNRemoteView `json:"rmn,omitempty"` OnRamp map[string]v1_6.OnRampView `json:"onRamp,omitempty"` + OffRamp map[string]v1_6.OffRampView `json:"offRamp,omitempty"` } func NewChain() ChainView { @@ -22,6 +23,7 @@ func NewChain() ChainView { Router: make(map[string]v1_2.RouterView), RMN: make(map[string]v1_6.RMNRemoteView), OnRamp: make(map[string]v1_6.OnRampView), + OffRamp: make(map[string]v1_6.OffRampView), FeeQuoter: make(map[string]v1_6.FeeQuoterView), } } diff --git a/integration-tests/deployment/ccip/view/v1_2/router.go b/integration-tests/deployment/ccip/view/v1_2/router.go index 9d3711d0c2..14a96e86b7 100644 --- a/integration-tests/deployment/ccip/view/v1_2/router.go +++ b/integration-tests/deployment/ccip/view/v1_2/router.go @@ -54,3 +54,18 @@ func GenerateRouterView(r *router.Router) (RouterView, error) { OffRamps: offRamps, }, nil } + +// From the perspective of the OnRamp, the destination chains are the source chains for the OffRamp. +func GetRemoteChainSelectors(routerContract *router.Router) ([]uint64, error) { + remoteSelectors := make([]uint64, 0) + offRamps, err := routerContract.GetOffRamps(nil) + if err != nil { + return nil, fmt.Errorf("failed to get offRamps from router: %w", err) + } + // lanes are bidirectional, so we get the list of source chains to know which chains are supported as destinations as well + for _, offRamp := range offRamps { + remoteSelectors = append(remoteSelectors, offRamp.SourceChainSelector) + } + + return remoteSelectors, nil +} diff --git a/integration-tests/deployment/ccip/view/v1_6/feequoter.go b/integration-tests/deployment/ccip/view/v1_6/feequoter.go index 10e0b984f3..a2694e96a4 100644 --- a/integration-tests/deployment/ccip/view/v1_6/feequoter.go +++ b/integration-tests/deployment/ccip/view/v1_6/feequoter.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/types" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" router1_2 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" @@ -83,7 +84,7 @@ func GenerateFeeQuoterView(fqContract *fee_quoter.FeeQuoter, router *router1_2.R } // find router contract in dependencies fq.DestinationChainConfig = make(map[uint64]FeeQuoterDestChainConfig) - destSelectors, err := GetDestinationSelectors(router) + destSelectors, err := v1_2.GetRemoteChainSelectors(router) if err != nil { return FeeQuoterView{}, fmt.Errorf("view error for FeeQuoter: %w", err) } @@ -137,17 +138,3 @@ func GetSupportedTokens(taContract *token_admin_registry.TokenAdminRegistry) ([] } return tokens, nil } - -func GetDestinationSelectors(routerContract *router1_2.Router) ([]uint64, error) { - destSelectors := make([]uint64, 0) - offRamps, err := routerContract.GetOffRamps(nil) - if err != nil { - return nil, fmt.Errorf("failed to get offRamps from router: %w", err) - } - // lanes are bidirectional, so we get the list of source chains to know which chains are supported as destinations as well - for _, offRamp := range offRamps { - destSelectors = append(destSelectors, offRamp.SourceChainSelector) - } - - return destSelectors, nil -} diff --git a/integration-tests/deployment/ccip/view/v1_6/offramp.go b/integration-tests/deployment/ccip/view/v1_6/offramp.go new file mode 100644 index 0000000000..38992cb3da --- /dev/null +++ b/integration-tests/deployment/ccip/view/v1_6/offramp.go @@ -0,0 +1,64 @@ +package v1_6 + +import ( + "fmt" + + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/types" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_2" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + router1_2 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" +) + +type OffRampView struct { + types.ContractMetaData + DynamicConfig offramp.OffRampDynamicConfig `json:"dynamicConfig"` + LatestPriceSequenceNumber uint64 `json:"latestPriceSequenceNumber"` + SourceChainConfigs map[uint64]offramp.OffRampSourceChainConfig `json:"sourceChainConfigs"` + StaticConfig offramp.OffRampStaticConfig `json:"staticConfig"` +} + +func GenerateOffRampView( + offRampContract *offramp.OffRamp, + routerContract *router1_2.Router, +) (OffRampView, error) { + tv, err := types.NewContractMetaData(offRampContract, offRampContract.Address()) + if err != nil { + return OffRampView{}, err + } + + dynamicConfig, err := offRampContract.GetDynamicConfig(nil) + if err != nil { + return OffRampView{}, fmt.Errorf("failed to get dynamic config: %w", err) + } + + latestPriceSequenceNumber, err := offRampContract.GetLatestPriceSequenceNumber(nil) + if err != nil { + return OffRampView{}, fmt.Errorf("failed to get latest price sequence number: %w", err) + } + + sourceChainSelectors, err := v1_2.GetRemoteChainSelectors(routerContract) + if err != nil { + return OffRampView{}, fmt.Errorf("failed to get source chain selectors: %w", err) + } + sourceChainConfigs := make(map[uint64]offramp.OffRampSourceChainConfig) + for _, sourceChainSelector := range sourceChainSelectors { + sourceChainConfig, err := offRampContract.GetSourceChainConfig(nil, sourceChainSelector) + if err != nil { + return OffRampView{}, fmt.Errorf("failed to get source chain config: %w", err) + } + sourceChainConfigs[sourceChainSelector] = sourceChainConfig + } + + staticConfig, err := offRampContract.GetStaticConfig(nil) + if err != nil { + return OffRampView{}, fmt.Errorf("failed to get static config: %w", err) + } + + return OffRampView{ + ContractMetaData: tv, + DynamicConfig: dynamicConfig, + LatestPriceSequenceNumber: latestPriceSequenceNumber, + SourceChainConfigs: sourceChainConfigs, + StaticConfig: staticConfig, + }, nil +} diff --git a/integration-tests/deployment/ccip/view/v1_6/onramp.go b/integration-tests/deployment/ccip/view/v1_6/onramp.go index a5fe13bfb5..72ac9e948e 100644 --- a/integration-tests/deployment/ccip/view/v1_6/onramp.go +++ b/integration-tests/deployment/ccip/view/v1_6/onramp.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/types" + "github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" router1_2 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" @@ -51,7 +52,7 @@ func GenerateOnRampView( return OnRampView{}, fmt.Errorf("failed to get owner: %w", err) } // populate destChainSelectors from router - destChainSelectors, err := GetDestinationSelectors(routerContract) + destChainSelectors, err := v1_2.GetRemoteChainSelectors(routerContract) if err != nil { return OnRampView{}, fmt.Errorf("failed to get destination selectors: %w", err) } From 6a39c12ffa571829a91a3bfb3bd677150495b1f3 Mon Sep 17 00:00:00 2001 From: Connor Stein Date: Mon, 23 Sep 2024 15:49:10 -0400 Subject: [PATCH 412/432] Deployment tooling (#14533) --- .github/CODEOWNERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7bdec1a61f..a0818dfc19 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -94,6 +94,12 @@ core/scripts/gateway @smartcontractkit/functions /integration-tests/**/*keeper* @smartcontractkit/keepers /integration-tests/**/*automation* @smartcontractkit/keepers +# Deployment tooling +# Initially the common structures owned by CCIP +/integration-tests/deployment @smartcontractkit/ccip +/integration-tests/deployment/ccip @smartcontractkit/ccip +# TODO: As more products add their deployment logic here, add the team as an owner + # CI/CD /.github/** @smartcontractkit/releng @smartcontractkit/test-tooling-team /.github/workflows/performance-tests.yml @smartcontractkit/test-tooling-team From 6b3002746b3766df6cec3db063f683a46b5e07a6 Mon Sep 17 00:00:00 2001 From: Connor Stein Date: Mon, 23 Sep 2024 16:07:41 -0400 Subject: [PATCH 413/432] Fix state view (#14532) --- integration-tests/deployment/address_book.go | 15 +++++++++----- .../deployment/address_book_test.go | 10 +++++++++- integration-tests/deployment/ccip/state.go | 20 ++++++++++++------- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/integration-tests/deployment/address_book.go b/integration-tests/deployment/address_book.go index 4a5916111c..be004f27d0 100644 --- a/integration-tests/deployment/address_book.go +++ b/integration-tests/deployment/address_book.go @@ -13,6 +13,7 @@ import ( var ( ErrInvalidChainSelector = fmt.Errorf("invalid chain selector") ErrInvalidAddress = fmt.Errorf("invalid address") + ErrChainNotFound = fmt.Errorf("chain not found") ) // ContractType is a simple string type for identifying contract types. @@ -90,7 +91,7 @@ type AddressBookMap struct { func (m *AddressBookMap) Save(chainSelector uint64, address string, typeAndVersion TypeAndVersion) error { _, exists := chainsel.ChainBySelector(chainSelector) if !exists { - return errors.Wrapf(ErrInvalidChainSelector, "chain selector %d not found", chainSelector) + return errors.Wrapf(ErrInvalidChainSelector, "chain selector %d", chainSelector) } if address == "" || address == common.HexToAddress("0x0").Hex() { return errors.Wrap(ErrInvalidAddress, "address cannot be empty") @@ -119,11 +120,15 @@ func (m *AddressBookMap) Addresses() (map[uint64]map[string]TypeAndVersion, erro return m.AddressesByChain, nil } -func (m *AddressBookMap) AddressesForChain(chain uint64) (map[string]TypeAndVersion, error) { - if _, exists := m.AddressesByChain[chain]; !exists { - return nil, fmt.Errorf("chain %d not found", chain) +func (m *AddressBookMap) AddressesForChain(chainSelector uint64) (map[string]TypeAndVersion, error) { + _, exists := chainsel.ChainBySelector(chainSelector) + if !exists { + return nil, errors.Wrapf(ErrInvalidChainSelector, "chain selector %d", chainSelector) + } + if _, exists := m.AddressesByChain[chainSelector]; !exists { + return nil, errors.Wrapf(ErrChainNotFound, "chain selector %d", chainSelector) } - return m.AddressesByChain[chain], nil + return m.AddressesByChain[chainSelector], nil } // Attention this will mutate existing book diff --git a/integration-tests/deployment/address_book_test.go b/integration-tests/deployment/address_book_test.go index c6967df0ca..bf3d2ad965 100644 --- a/integration-tests/deployment/address_book_test.go +++ b/integration-tests/deployment/address_book_test.go @@ -20,16 +20,24 @@ func TestAddressBook_Save(t *testing.T) { err := ab.Save(chainsel.TEST_90000001.Selector, addr1, onRamp100) require.NoError(t, err) - // Check input validation + // Invalid address err = ab.Save(chainsel.TEST_90000001.Selector, "asdlfkj", onRamp100) require.Error(t, err) assert.Equal(t, errors.Is(err, ErrInvalidAddress), true, "err %s", err) + + // Valid chain but not present. + _, err = ab.AddressesForChain(chainsel.TEST_90000002.Selector) + assert.Equal(t, errors.Is(err, ErrChainNotFound), true, "err %s", err) + + // Invalid selector err = ab.Save(0, addr1, onRamp100) require.Error(t, err) assert.Equal(t, errors.Is(err, ErrInvalidChainSelector), true) + // Duplicate err = ab.Save(chainsel.TEST_90000001.Selector, addr1, onRamp100) require.Error(t, err) + // Zero address err = ab.Save(chainsel.TEST_90000001.Selector, common.HexToAddress("0x0").Hex(), onRamp100) require.Error(t, err) diff --git a/integration-tests/deployment/ccip/state.go b/integration-tests/deployment/ccip/state.go index efb3416ec3..334c945707 100644 --- a/integration-tests/deployment/ccip/state.go +++ b/integration-tests/deployment/ccip/state.go @@ -6,7 +6,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink/integration-tests/deployment" @@ -35,6 +34,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface" ) +// CCIPChainState holds a Go binding for all the currently deployed CCIP contracts +// on a chain. If a binding is nil, it means here is no such contract on the chain. type CCIPChainState struct { OnRamp *onramp.OnRamp OffRamp *offramp.OffRamp @@ -177,12 +178,17 @@ func LoadOnchainState(e deployment.Environment, ab deployment.AddressBook) (CCIP state := CCIPOnChainState{ Chains: make(map[uint64]CCIPChainState), } - addresses, err := ab.Addresses() - if err != nil { - return state, errors.Wrap(err, "could not get addresses") - } - for chainSelector, addresses := range addresses { - chainState, err := LoadChainState(e.Chains[chainSelector], addresses) + for chainSelector, chain := range e.Chains { + addresses, err := ab.AddressesForChain(chainSelector) + if err != nil { + // Chain not found in address book, initialize empty + if errors.Is(err, deployment.ErrChainNotFound) { + addresses = make(map[string]deployment.TypeAndVersion) + } else { + return state, err + } + } + chainState, err := LoadChainState(chain, addresses) if err != nil { return state, err } From b634d368a786624c4edd5f07581fe735094b61a2 Mon Sep 17 00:00:00 2001 From: Connor Stein Date: Mon, 23 Sep 2024 17:50:33 -0400 Subject: [PATCH 414/432] Bump owner dep (#14531) * Bump owner dep * Address mcms lib changes --- .../deployment/ccip/add_chain.go | 33 ++++++++------ integration-tests/deployment/ccip/propose.go | 44 +++++++++++-------- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- 4 files changed, 48 insertions(+), 35 deletions(-) diff --git a/integration-tests/deployment/ccip/add_chain.go b/integration-tests/deployment/ccip/add_chain.go index 550d6168a1..0ae87d3834 100644 --- a/integration-tests/deployment/ccip/add_chain.go +++ b/integration-tests/deployment/ccip/add_chain.go @@ -3,6 +3,7 @@ package ccipdeployment import ( "math/big" + "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/ccip-owner-contracts/tools/proposal/mcms" "github.com/smartcontractkit/ccip-owner-contracts/tools/proposal/timelock" @@ -33,7 +34,8 @@ func NewChainInboundProposal( ) (*timelock.MCMSWithTimelockProposal, error) { // Generate proposal which enables new destination (from test router) on all source chains. var batches []timelock.BatchChainOperation - metaDataPerChain := make(map[mcms.ChainIdentifier]timelock.MCMSWithTimelockChainMetadata) + metaDataPerChain := make(map[mcms.ChainIdentifier]mcms.ChainMetadata) + timelockAddresses := make(map[mcms.ChainIdentifier]common.Address) for _, source := range sources { chain, _ := chainsel.ChainBySelector(source) enableOnRampDest, err := state.Chains[source].OnRamp.ApplyDestChainConfigUpdates(SimTransactOpts(), []onramp.OnRampDestChainConfigArgs{ @@ -92,13 +94,15 @@ func NewChainInboundProposal( }, }, }) - metaDataPerChain[mcms.ChainIdentifier(chain.Selector)] = timelock.MCMSWithTimelockChainMetadata{ - ChainMetadata: mcms.ChainMetadata{ - NonceOffset: 0, - MCMAddress: state.Chains[source].Mcm.Address(), - }, - TimelockAddress: state.Chains[source].Timelock.Address(), + opCount, err := state.Chains[source].Mcm.GetOpCount(nil) + if err != nil { + return nil, err + } + metaDataPerChain[mcms.ChainIdentifier(chain.Selector)] = mcms.ChainMetadata{ + StartingOpCount: opCount.Uint64(), + MCMAddress: state.Chains[source].Mcm.Address(), } + timelockAddresses[mcms.ChainIdentifier(chain.Selector)] = state.Chains[source].Timelock.Address() } // Home chain new don. @@ -146,13 +150,15 @@ func NewChainInboundProposal( return nil, err } homeChain, _ := chainsel.ChainBySelector(homeChainSel) - metaDataPerChain[mcms.ChainIdentifier(homeChain.Selector)] = timelock.MCMSWithTimelockChainMetadata{ - ChainMetadata: mcms.ChainMetadata{ - NonceOffset: 0, - MCMAddress: state.Chains[homeChainSel].Mcm.Address(), - }, - TimelockAddress: state.Chains[homeChainSel].Timelock.Address(), + opCount, err := state.Chains[homeChainSel].Mcm.GetOpCount(nil) + if err != nil { + return nil, err + } + metaDataPerChain[mcms.ChainIdentifier(homeChain.Selector)] = mcms.ChainMetadata{ + StartingOpCount: opCount.Uint64(), + MCMAddress: state.Chains[homeChainSel].Mcm.Address(), } + timelockAddresses[mcms.ChainIdentifier(homeChain.Selector)] = state.Chains[homeChainSel].Timelock.Address() batches = append(batches, timelock.BatchChainOperation{ ChainIdentifier: mcms.ChainIdentifier(homeChain.Selector), Batch: []mcms.Operation{ @@ -175,6 +181,7 @@ func NewChainInboundProposal( []mcms.Signature{}, false, metaDataPerChain, + timelockAddresses, "blah", // TODO batches, timelock.Schedule, diff --git a/integration-tests/deployment/ccip/propose.go b/integration-tests/deployment/ccip/propose.go index eced93dde0..fca971aaf0 100644 --- a/integration-tests/deployment/ccip/propose.go +++ b/integration-tests/deployment/ccip/propose.go @@ -34,9 +34,7 @@ func SignProposal(t *testing.T, env deployment.Environment, proposal *timelock.M chainSel := mcms.ChainIdentifier(chainselc.Selector) executorClients[chainSel] = chain.Client } - realProposal, err := proposal.ToMCMSOnlyProposal() - require.NoError(t, err) - executor, err := realProposal.ToExecutor(executorClients) + executor, err := proposal.ToExecutor(true) require.NoError(t, err) payload, err := executor.SigningHash() require.NoError(t, err) @@ -45,7 +43,7 @@ func SignProposal(t *testing.T, env deployment.Environment, proposal *timelock.M require.NoError(t, err) mcmSig, err := mcms.NewSignatureFromBytes(sig) require.NoError(t, err) - executor.Proposal.Signatures = append(executor.Proposal.Signatures, mcmSig) + executor.Proposal.AddSignature(mcmSig) require.NoError(t, executor.Proposal.Validate()) return executor } @@ -53,7 +51,7 @@ func SignProposal(t *testing.T, env deployment.Environment, proposal *timelock.M func ExecuteProposal(t *testing.T, env deployment.Environment, executor *mcms.Executor, state CCIPOnChainState, sel uint64) { // Set the root. - tx, err2 := executor.SetRootOnChain(env.Chains[sel].DeployerKey, mcms.ChainIdentifier(sel)) + tx, err2 := executor.SetRootOnChain(env.Chains[sel].Client, env.Chains[sel].DeployerKey, mcms.ChainIdentifier(sel)) require.NoError(t, err2) _, err2 = env.Chains[sel].Confirm(tx) require.NoError(t, err2) @@ -63,7 +61,7 @@ func ExecuteProposal(t *testing.T, env deployment.Environment, executor *mcms.Ex for _, chainOp := range executor.Operations[mcms.ChainIdentifier(sel)] { for idx, op := range executor.ChainAgnosticOps { if bytes.Equal(op.Data, chainOp.Data) && op.To == chainOp.To { - opTx, err3 := executor.ExecuteOnChain(env.Chains[sel].DeployerKey, idx) + opTx, err3 := executor.ExecuteOnChain(env.Chains[sel].Client, env.Chains[sel].DeployerKey, idx) require.NoError(t, err3) block, err3 := env.Chains[sel].Confirm(opTx) require.NoError(t, err3) @@ -104,7 +102,8 @@ func GenerateAcceptOwnershipProposal( ) (*timelock.MCMSWithTimelockProposal, error) { // TODO: Accept rest of contracts var batches []timelock.BatchChainOperation - metaDataPerChain := make(map[mcms.ChainIdentifier]timelock.MCMSWithTimelockChainMetadata) + metaDataPerChain := make(map[mcms.ChainIdentifier]mcms.ChainMetadata) + timelockAddresses := make(map[mcms.ChainIdentifier]common.Address) for _, sel := range chains { chain, _ := chainsel.ChainBySelector(sel) acceptOnRamp, err := state.Chains[sel].OnRamp.AcceptOwnership(SimTransactOpts()) @@ -116,13 +115,15 @@ func GenerateAcceptOwnershipProposal( return nil, err } chainSel := mcms.ChainIdentifier(chain.Selector) - metaDataPerChain[chainSel] = timelock.MCMSWithTimelockChainMetadata{ - ChainMetadata: mcms.ChainMetadata{ - NonceOffset: 0, - MCMAddress: state.Chains[sel].Mcm.Address(), - }, - TimelockAddress: state.Chains[sel].Timelock.Address(), + opCount, err := state.Chains[sel].Mcm.GetOpCount(nil) + if err != nil { + return nil, err + } + metaDataPerChain[chainSel] = mcms.ChainMetadata{ + MCMAddress: state.Chains[sel].Mcm.Address(), + StartingOpCount: opCount.Uint64(), } + timelockAddresses[chainSel] = state.Chains[sel].Timelock.Address() batches = append(batches, timelock.BatchChainOperation{ ChainIdentifier: chainSel, Batch: []mcms.Operation{ @@ -139,6 +140,7 @@ func GenerateAcceptOwnershipProposal( }, }) } + acceptCR, err := state.Chains[homeChain].CapabilityRegistry.AcceptOwnership(SimTransactOpts()) if err != nil { return nil, err @@ -148,13 +150,15 @@ func GenerateAcceptOwnershipProposal( return nil, err } homeChainID := mcms.ChainIdentifier(homeChain) - metaDataPerChain[homeChainID] = timelock.MCMSWithTimelockChainMetadata{ - ChainMetadata: mcms.ChainMetadata{ - NonceOffset: 0, - MCMAddress: state.Chains[homeChain].Mcm.Address(), - }, - TimelockAddress: state.Chains[homeChain].Timelock.Address(), + opCount, err := state.Chains[homeChain].Mcm.GetOpCount(nil) + if err != nil { + return nil, err } + metaDataPerChain[homeChainID] = mcms.ChainMetadata{ + StartingOpCount: opCount.Uint64(), + MCMAddress: state.Chains[homeChain].Mcm.Address(), + } + timelockAddresses[homeChainID] = state.Chains[homeChain].Timelock.Address() batches = append(batches, timelock.BatchChainOperation{ ChainIdentifier: homeChainID, Batch: []mcms.Operation{ @@ -170,12 +174,14 @@ func GenerateAcceptOwnershipProposal( }, }, }) + return timelock.NewMCMSWithTimelockProposal( "1", 2004259681, // TODO []mcms.Signature{}, false, metaDataPerChain, + timelockAddresses, "blah", // TODO batches, timelock.Schedule, "0s") diff --git a/integration-tests/go.mod b/integration-tests/go.mod index dbfda153c5..6188a31cae 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -36,7 +36,7 @@ require ( github.com/sethvargo/go-retry v0.2.4 github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.12.2 - github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240910151738-3f318badcfb5 + github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240919155713-f4bf4ae0b9c6 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe diff --git a/integration-tests/go.sum b/integration-tests/go.sum index dace088e6d..9f7881750d 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1417,8 +1417,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240910151738-3f318badcfb5 h1:m0HuGuVdRHqBBkHJpSR/QBV7gtLB+hFkXZQ9tEkjdzo= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240910151738-3f318badcfb5/go.mod h1:N60/wwocvZ5A3RGmYaMWo0fPFa5tTMlhI9lJ22DRktM= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240919155713-f4bf4ae0b9c6 h1:e4lR/xTK7iOeCniSwH6hdaNZZ/sJs1eYWpnJoz3CXxI= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240919155713-f4bf4ae0b9c6/go.mod h1:nlRI0m23HFMAHf7cKYdE58mPbXsTyY1y3ZLJxnuuoCM= github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnjjIQAEBnutCtksPzVDY= github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= From 601704435550e3a81a4a3bdaac5f56070eee0d4a Mon Sep 17 00:00:00 2001 From: Domino Valdano Date: Mon, 23 Sep 2024 23:24:17 -0700 Subject: [PATCH 415/432] Add regression testing for pruning bug (#14454) --- core/chains/evm/logpoller/orm_test.go | 50 +++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index 1fb20a03af..ba66e166eb 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -187,6 +187,7 @@ func TestORM_GetBlocks_From_Range_Recent_Blocks(t *testing.T) { } func TestORM(t *testing.T) { + t.Parallel() th := SetupTH(t, lpOpts) o1 := th.ORM o2 := th.ORM2 @@ -334,6 +335,36 @@ func TestORM(t *testing.T) { }, })) + // Insert a couple logs on a different chain, to make sure + // these aren't affected by any operations on the chain LogPoller + // is managing. + require.NoError(t, o2.InsertLogs(ctx, []logpoller.Log{ + { + EvmChainId: ubig.New(th.ChainID2), + LogIndex: 8, + BlockHash: common.HexToHash("0x1238"), + BlockNumber: int64(17), + EventSig: topic2, + Topics: [][]byte{topic2[:]}, + Address: common.HexToAddress("0x1236"), + TxHash: common.HexToHash("0x1888"), + Data: []byte("same log on unrelated chain"), + BlockTimestamp: time.Now(), + }, + { + EvmChainId: ubig.New(th.ChainID2), + LogIndex: 9, + BlockHash: common.HexToHash("0x1999"), + BlockNumber: int64(18), + EventSig: topic, + Topics: [][]byte{topic[:], topic2[:]}, + Address: common.HexToAddress("0x5555"), + TxHash: common.HexToHash("0x1543"), + Data: []byte("different log on unrelated chain"), + BlockTimestamp: time.Now(), + }, + })) + t.Log(latest.BlockNumber) logs, err := o1.SelectLogsByBlockRange(ctx, 1, 17) require.NoError(t, err) @@ -454,11 +485,24 @@ func TestORM(t *testing.T) { require.NoError(t, err) require.Len(t, logs, 8) - // Delete expired logs + // Delete expired logs with page limit time.Sleep(2 * time.Millisecond) // just in case we haven't reached the end of the 1ms retention period - deleted, err := o1.DeleteExpiredLogs(ctx, 0) + deleted, err := o1.DeleteExpiredLogs(ctx, 2) + require.NoError(t, err) + assert.Equal(t, int64(2), deleted) + + // Delete expired logs without page limit + deleted, err = o1.DeleteExpiredLogs(ctx, 0) + require.NoError(t, err) + assert.Equal(t, int64(2), deleted) + + // Ensure that both of the logs from the second chain are still there + logs, err = o2.SelectLogs(ctx, 0, 100, common.HexToAddress("0x1236"), topic2) + require.NoError(t, err) + assert.Len(t, logs, 1) + logs, err = o2.SelectLogs(ctx, 0, 100, common.HexToAddress("0x5555"), topic) require.NoError(t, err) - assert.Equal(t, int64(4), deleted) + assert.Len(t, logs, 1) logs, err = o1.SelectLogsByBlockRange(ctx, 1, latest.BlockNumber) require.NoError(t, err) From 76addb14f18b7cfc29958d3e8a114b90bef39f7d Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Tue, 24 Sep 2024 11:30:06 +0200 Subject: [PATCH 416/432] Fix skipped notification in E2E test workflow (#14538) --- .github/workflows/run-e2e-tests-reusable-workflow.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index c8e3cde085..0de9c7d942 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -879,13 +879,13 @@ jobs: { "attachments": [ { - "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || contains(join(needs.*.result, ','), 'cancelled') && '#FFA000' || contains(join(needs.*.result, ','), 'skipped') && '#FFA000' || '2E7D32' }}", + "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || contains(join(needs.*.result, ','), 'cancelled') && '#FFA000' || '2E7D32' }}", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", - "text": "${{ inputs.slack_notification_after_tests_name }} - ${{ contains(join(needs.*.result, ','), 'failure') && 'Failed :x:' || contains(join(needs.*.result, ','), 'cancelled') && 'Cancelled :warning:' || contains(join(needs.*.result, ','), 'skipped') && 'Skipped :warning:' || 'Passed :white_check_mark:' }}" + "text": "${{ inputs.slack_notification_after_tests_name }} - ${{ contains(join(needs.*.result, ','), 'failure') && 'Failed :x:' || contains(join(needs.*.result, ','), 'cancelled') && 'Cancelled :warning:' || 'Passed :white_check_mark:' }}" } }, { From b4360c9aece538e20ef688750adcd5a838729930 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 24 Sep 2024 12:18:39 +0200 Subject: [PATCH 417/432] [TT-1624] link PR to solidity review issue (#14521) * try more universal Solidity scripts * fix error printing in uml generation; test foundry pipeline * Update gethwrappers * a bit more testing * fix Sol * remove test contracts * Update gethwrappers * try reusable artifact workflow * fix syntax * reuse workflow for .github/workflows * use newer reusable Solidity Review Artifacts pipeline * remove actions that were moved to chainlink-github-actions * add test Solidity file * add missing changeset * use scripts from shared repository * modify one contract * set git top level dir manually * [Bot] Update changeset file with jira issue * fix script path * use newer version of the reusable pipeline * update pipeline version, use custom pruning script * use newer action version, remove JIRA scripts * use reusable Solidity Review Artifacts workflow from .github * remove left over changes that are no longer needed * remove left over changes that are no longer needed * fix foundry pipeline * remove test Solidity files * use tagged reusable pipeline version * link PR to Solidity Review issue in Jira * update all references to .github to use tagged commit * test out the enforcement * remove extra changeset * [Bot] Update changeset file with jira issue * fix filename * test out empty changeset file * [Bot] Update changeset file with jira issues * use latest version of the action * remove changeset * fix condition in solidity tracability pipeline * add changeset * [Bot] Update changeset file with jira issues * fix message and condition for comment posting * test changesets in core * add changeset for core * use tagged jira-tracing version, restore changeset * add missing version comment * remove test-related changes --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .github/workflows/changeset.yml | 2 +- .github/workflows/solidity-foundry.yml | 4 ++ .github/workflows/solidity-tracability.yml | 62 ++++++++++++++++++++-- contracts/.changeset/strong-boats-brake.md | 8 +++ 4 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 contracts/.changeset/strong-boats-brake.md diff --git a/.github/workflows/changeset.yml b/.github/workflows/changeset.yml index ba06eb07e9..e72bde7465 100644 --- a/.github/workflows/changeset.yml +++ b/.github/workflows/changeset.yml @@ -93,7 +93,7 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: repository: smartcontractkit/.github - ref: b6e37806737eef87e8c9137ceeb23ef0bff8b1db # validate-solidity-artifacts@0.1.0 + ref: 9aed33e5298471f20a3d630d711b96ae5538728c # jira-tracing@0.2.0 path: ./dot_github - name: Update Jira ticket for core diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index e7e8089310..fd0afea64e 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -492,6 +492,8 @@ jobs: retention-days: 7 - name: Find Slither comment in the PR + # We only want to create the comment if the PR is not modified by a bot + if: "(github.event_name == 'push' && github.event.pusher.username && ! contains(github.event.pusher.username, '[bot]')) || (github.event_name != 'push' && ! contains(github.actor, '[bot]'))" uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3.0.0 id: find-comment with: @@ -518,6 +520,8 @@ jobs: echo "slither_artifact_url=$slither_artifact_url" >> $GITHUB_OUTPUT - name: Create or update Slither comment in the PR + # We only want to create the comment if the PR is not modified by a bot + if: "(github.event_name == 'push' && github.event.pusher.username && ! contains(github.event.pusher.username, '[bot]')) || (github.event_name != 'push' && ! contains(github.actor, '[bot]'))" uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0 with: comment-id: ${{ steps.find-comment.outputs.comment-id }} diff --git a/.github/workflows/solidity-tracability.yml b/.github/workflows/solidity-tracability.yml index 2110dd7dd6..75774713d9 100644 --- a/.github/workflows/solidity-tracability.yml +++ b/.github/workflows/solidity-tracability.yml @@ -28,15 +28,15 @@ jobs: uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 id: files-changed with: - list-files: "json" + list-files: "csv" # This is a valid input, see https://github.com/dorny/paths-filter/pull/226 predicate-quantifier: "every" filters: | - source: + source: - contracts/**/*.sol - '!contracts/**/*.t.sol' changesets: - - 'contracts/.changeset/**' + - added|modified: 'contracts/.changeset/**' enforce-traceability: # Note: A job that is skipped will report its status as "Success". @@ -95,7 +95,7 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: repository: smartcontractkit/.github - ref: b6e37806737eef87e8c9137ceeb23ef0bff8b1db # validate-solidity-artifacts@0.1.0 + ref: 9aed33e5298471f20a3d630d711b96ae5538728c # jira-tracing@0.2.0 path: ./dot_github # we need to set the top level directory for the jira-tracing action manually @@ -128,16 +128,68 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Enforce Solidity Review Jira issue + working-directory: ./dot_github + shell: bash + run: | + # we do not want to fail the workflow if there are issues with the script + if ! pnpm --filter jira-tracing issue:enforce-solidity-review; then + echo "::warning::Failed to enforce Solidity Review Jira issue, this is not a blocking issue. You can safely ignore it." + fi + env: + CHANGESET_FILES: ${{ needs.files-changed.outputs.changesets_files }} + GIT_TOP_LEVEL_DIR: ${{ steps.find-git-top-level-dir.outputs.top_level_dir }} + + SOLIDITY_REVIEW_TEMPLATE_KEY: 'TT-1634' + EXPORT_JIRA_ISSUE_KEYS: 'true' + + JIRA_HOST: ${{ vars.JIRA_HOST }} + JIRA_USERNAME: ${{ secrets.JIRA_USERNAME }} + JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} + # Commit appended changeset file back to repo - uses: planetscale/ghcommit-action@13a844326508cdefc72235201bb0446d6d10a85f # v0.1.6 with: - commit_message: "[Bot] Update changeset file with jira issue" + commit_message: "[Bot] Update changeset file with jira issues" repo: ${{ github.repository }} branch: ${{ github.head_ref }} file_pattern: "contracts/.changeset/*" env: GITHUB_TOKEN: ${{ steps.get-gh-token.outputs.access-token }} + - name: Read issue keys from env vars + shell: bash + id: read-issue-keys + run: | + # issue:enforce-solidity-review should have set two env vars with the issue keys + echo "Jira issue key related to pr: ${{ env.PR_JIRA_ISSUE_KEY }}" + echo "Jira issue key related to solidity review: ${{ env.SOLIDITY_REVIEW_JIRA_ISSUE_KEY }}" + + - name: Find traceability comment in the PR + uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3.0.0 + id: find-comment + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: 'Solidity Review Jira issue' + + - name: Create or update traceability comment in the PR + uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0 + with: + comment-id: ${{ steps.find-comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body: | + ## Solidity Review Jira issue + Hey! We have taken the liberty to link this PR to a Jira issue for Solidity Review. + + This is a new feature, that's currently in the pilot phase, so please make sure that the linkage is correct. In a contrary case, please update it manually in JIRA and replace Solidity Review issue key in the changeset file with the correct one. + Please reach out to the Test Tooling team and notify them about any issues you encounter. + + Any changes to the Solidity Review Jira issue should be reflected in the changeset file. If you need to update the issue key, please do so manually in the following changeset file: `${{ needs.files-changed.outputs.changesets_files }}` + + This PR has been linked to Solidity Review Jira issue: [${{ env.SOLIDITY_REVIEW_JIRA_ISSUE_KEY }}](${{ vars.JIRA_HOST }}browse/${{ env.SOLIDITY_REVIEW_JIRA_ISSUE_KEY }}) + edit-mode: replace + - name: Collect Metrics id: collect-gha-metrics if: always() diff --git a/contracts/.changeset/strong-boats-brake.md b/contracts/.changeset/strong-boats-brake.md new file mode 100644 index 0000000000..4f1b780565 --- /dev/null +++ b/contracts/.changeset/strong-boats-brake.md @@ -0,0 +1,8 @@ +--- +'@chainlink/contracts': patch +--- + +Add linkage between PR and Jira's Solidity Review issue + + +PR issue: TT-1624 From 0e32c07d22973343e722a228ff1c3b1e8f9bc04e Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Tue, 24 Sep 2024 13:58:48 +0200 Subject: [PATCH 418/432] CCIP-2881 USDC Reader integration tests (#14516) * Test scaffold * Working test * Fixes * Fixes * Fixes * Bump * Minor fixes * [Bot] Update changeset file with jira issue * Minor fixes * Minor fixes * Minor fixes * Minor fixes * Using facade * Using facade * Post review fixes * Update gethwrappers --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .changeset/olive-snails-sniff.md | 5 + contracts/.changeset/orange-plums-fold.md | 8 + .../scripts/native_solc_compile_all_ccip | 5 +- .../ccip/test/helpers/USDCReaderTester.sol | 62 ++++ .../usdcreader/usdcreader_test.go | 298 ++++++++++++++++ .../ccip_reader_tester/ccip_reader_tester.go | 2 +- .../usdc_reader_tester/usdc_reader_tester.go | 333 ++++++++++++++++++ ...rapper-dependency-versions-do-not-edit.txt | 3 +- core/gethwrappers/ccip/go_generate.go | 1 + core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 17 files changed, 723 insertions(+), 18 deletions(-) create mode 100644 .changeset/olive-snails-sniff.md create mode 100644 contracts/.changeset/orange-plums-fold.md create mode 100644 contracts/src/v0.8/ccip/test/helpers/USDCReaderTester.sol create mode 100644 core/capabilities/ccip/ccip_integration_tests/usdcreader/usdcreader_test.go create mode 100644 core/gethwrappers/ccip/generated/usdc_reader_tester/usdc_reader_tester.go diff --git a/.changeset/olive-snails-sniff.md b/.changeset/olive-snails-sniff.md new file mode 100644 index 0000000000..fd91cae050 --- /dev/null +++ b/.changeset/olive-snails-sniff.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Adding USDCReaderTester contract for CCIP integration tests #internal diff --git a/contracts/.changeset/orange-plums-fold.md b/contracts/.changeset/orange-plums-fold.md new file mode 100644 index 0000000000..b6cf88c81b --- /dev/null +++ b/contracts/.changeset/orange-plums-fold.md @@ -0,0 +1,8 @@ +--- +'@chainlink/contracts': patch +--- + +Adding USDCReaderTester contract for CCIP integration tests #internal + + +CCIP-2881 \ No newline at end of file diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index 64fcd9f435..6a6226a4ad 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -40,10 +40,6 @@ compileContract () { echo "OnRamp uses $OPTIMIZE_RUNS_ONRAMP optimizer runs." optimize_runs=$OPTIMIZE_RUNS_ONRAMP ;; - "ccip/test/helpers/CCIPReaderTester.sol") - echo "CCIPReaderTester uses 1 optimizer runs for reduced contract size." - optimize_runs=1 - ;; esac solc --overwrite --optimize --optimize-runs $optimize_runs --metadata-hash none \ @@ -95,6 +91,7 @@ compileContract ccip/test/helpers/BurnMintERC677Helper.sol compileContract ccip/test/helpers/CommitStoreHelper.sol compileContract ccip/test/helpers/MessageHasher.sol compileContract ccip/test/helpers/CCIPReaderTester.sol +compileContract ccip/test/helpers/USDCReaderTester.sol compileContract ccip/test/helpers/ReportCodec.sol compileContract ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol compileContract ccip/test/helpers/MultiOCR3Helper.sol diff --git a/contracts/src/v0.8/ccip/test/helpers/USDCReaderTester.sol b/contracts/src/v0.8/ccip/test/helpers/USDCReaderTester.sol new file mode 100644 index 0000000000..d1baa22de1 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/helpers/USDCReaderTester.sol @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +contract USDCReaderTester { + event MessageSent(bytes); + + // emitMessageSent reflects the logic from Circle's MessageTransmitter emitting MeseageSent(bytes) events + // https://github.com/circlefin/evm-cctp-contracts/blob/377c9bd813fb86a42d900ae4003599d82aef635a/src/MessageTransmitter.sol#L41 + // https://github.com/circlefin/evm-cctp-contracts/blob/377c9bd813fb86a42d900ae4003599d82aef635a/src/MessageTransmitter.sol#L365 + function emitMessageSent( + uint32 version, + uint32 sourceDomain, + uint32 destinationDomain, + bytes32 recipient, + bytes32 destinationCaller, + bytes32 sender, + uint64 nonce, + bytes calldata messageBody + ) external { + bytes memory _message = + _formatMessage(version, sourceDomain, destinationDomain, nonce, sender, recipient, destinationCaller, messageBody); + emit MessageSent(_message); + } + + /** + * @notice Returns formatted (packed) message with provided fields + * It's a copy paste of the Message._formatMessage() call in MessageTransmitter.sol + * https://github.com/circlefin/evm-cctp-contracts/blob/377c9bd813fb86a42d900ae4003599d82aef635a/src/messages/Message.sol#L54C1-L65C9 + * Check the chainlink-ccip repo for the offchain implementation of matching this format + * @param _msgVersion the version of the message format + * @param _msgSourceDomain Domain of home chain + * @param _msgDestinationDomain Domain of destination chain + * @param _msgNonce Destination-specific nonce + * @param _msgSender Address of sender on source chain as bytes32 + * @param _msgRecipient Address of recipient on destination chain as bytes32 + * @param _msgDestinationCaller Address of caller on destination chain as bytes32 + * @param _msgRawBody Raw bytes of message body + * @return Formatted message + * + */ + function _formatMessage( + uint32 _msgVersion, + uint32 _msgSourceDomain, + uint32 _msgDestinationDomain, + uint64 _msgNonce, + bytes32 _msgSender, + bytes32 _msgRecipient, + bytes32 _msgDestinationCaller, + bytes memory _msgRawBody + ) internal pure returns (bytes memory) { + return abi.encodePacked( + _msgVersion, + _msgSourceDomain, + _msgDestinationDomain, + _msgNonce, + _msgSender, + _msgRecipient, + _msgDestinationCaller, + _msgRawBody + ); + } +} diff --git a/core/capabilities/ccip/ccip_integration_tests/usdcreader/usdcreader_test.go b/core/capabilities/ccip/ccip_integration_tests/usdcreader/usdcreader_test.go new file mode 100644 index 0000000000..e9ec613ce3 --- /dev/null +++ b/core/capabilities/ccip/ccip_integration_tests/usdcreader/usdcreader_test.go @@ -0,0 +1,298 @@ +package usdcreader + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/crypto" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + sel "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink-ccip/execute/exectypes" + "github.com/smartcontractkit/chainlink-ccip/pkg/consts" + "github.com/smartcontractkit/chainlink-ccip/pkg/contractreader" + "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + "github.com/smartcontractkit/chainlink-common/pkg/types" + cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/usdc_reader_tester" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" +) + +func Test_USDCReader_MessageHashes(t *testing.T) { + ctx := testutils.Context(t) + ethereumChain := cciptypes.ChainSelector(sel.ETHEREUM_MAINNET_OPTIMISM_1.Selector) + ethereumDomainCCTP := reader.CCTPDestDomains[uint64(ethereumChain)] + avalancheChain := cciptypes.ChainSelector(sel.AVALANCHE_MAINNET.Selector) + avalancheDomainCCTP := reader.CCTPDestDomains[uint64(avalancheChain)] + polygonChain := cciptypes.ChainSelector(sel.POLYGON_MAINNET.Selector) + polygonDomainCCTP := reader.CCTPDestDomains[uint64(polygonChain)] + + cfg := evmtypes.ChainReaderConfig{ + Contracts: map[string]evmtypes.ChainContractReader{ + consts.ContractNameCCTPMessageTransmitter: { + ContractPollingFilter: evmtypes.ContractPollingFilter{ + GenericEventNames: []string{consts.EventNameCCTPMessageSent}, + }, + ContractABI: usdc_reader_tester.USDCReaderTesterABI, + Configs: map[string]*evmtypes.ChainReaderDefinition{ + consts.EventNameCCTPMessageSent: { + ChainSpecificName: consts.EventNameCCTPMessageSent, + ReadType: evmtypes.Event, + }, + }, + }, + }, + } + + ts := testSetup(ctx, t, ethereumChain, cfg) + + usdcReader, err := reader.NewUSDCMessageReader( + map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig{ + ethereumChain: { + SourceMessageTransmitterAddr: ts.contractAddr.String(), + }, + }, + map[cciptypes.ChainSelector]contractreader.ContractReaderFacade{ + ethereumChain: ts.reader, + }) + require.NoError(t, err) + + emitMessageSent(t, ts, ethereumDomainCCTP, avalancheDomainCCTP, 11) + emitMessageSent(t, ts, ethereumDomainCCTP, avalancheDomainCCTP, 21) + emitMessageSent(t, ts, ethereumDomainCCTP, avalancheDomainCCTP, 31) + emitMessageSent(t, ts, ethereumDomainCCTP, avalancheDomainCCTP, 41) + emitMessageSent(t, ts, ethereumDomainCCTP, polygonDomainCCTP, 31) + emitMessageSent(t, ts, ethereumDomainCCTP, polygonDomainCCTP, 41) + + tt := []struct { + name string + tokens map[exectypes.MessageTokenID]cciptypes.RampTokenAmount + sourceChain cciptypes.ChainSelector + destChain cciptypes.ChainSelector + expectedMsgIDs []exectypes.MessageTokenID + }{ + { + name: "empty messages should return empty response", + tokens: map[exectypes.MessageTokenID]cciptypes.RampTokenAmount{}, + sourceChain: ethereumChain, + destChain: avalancheChain, + expectedMsgIDs: []exectypes.MessageTokenID{}, + }, + { + name: "single token message", + tokens: map[exectypes.MessageTokenID]cciptypes.RampTokenAmount{ + exectypes.NewMessageTokenID(1, 1): { + ExtraData: reader.NewSourceTokenDataPayload(11, ethereumDomainCCTP).ToBytes(), + }, + }, + sourceChain: ethereumChain, + destChain: avalancheChain, + expectedMsgIDs: []exectypes.MessageTokenID{exectypes.NewMessageTokenID(1, 1)}, + }, + { + name: "single token message but different chain", + tokens: map[exectypes.MessageTokenID]cciptypes.RampTokenAmount{ + exectypes.NewMessageTokenID(1, 2): { + ExtraData: reader.NewSourceTokenDataPayload(31, ethereumDomainCCTP).ToBytes(), + }, + }, + sourceChain: ethereumChain, + destChain: polygonChain, + expectedMsgIDs: []exectypes.MessageTokenID{exectypes.NewMessageTokenID(1, 2)}, + }, + { + name: "message without matching nonce", + tokens: map[exectypes.MessageTokenID]cciptypes.RampTokenAmount{ + exectypes.NewMessageTokenID(1, 1): { + ExtraData: reader.NewSourceTokenDataPayload(1234, ethereumDomainCCTP).ToBytes(), + }, + }, + sourceChain: ethereumChain, + destChain: avalancheChain, + expectedMsgIDs: []exectypes.MessageTokenID{}, + }, + { + name: "message without matching source domain", + tokens: map[exectypes.MessageTokenID]cciptypes.RampTokenAmount{ + exectypes.NewMessageTokenID(1, 1): { + ExtraData: reader.NewSourceTokenDataPayload(11, avalancheDomainCCTP).ToBytes(), + }, + }, + sourceChain: ethereumChain, + destChain: avalancheChain, + expectedMsgIDs: []exectypes.MessageTokenID{}, + }, + { + name: "message with multiple tokens", + tokens: map[exectypes.MessageTokenID]cciptypes.RampTokenAmount{ + exectypes.NewMessageTokenID(1, 1): { + ExtraData: reader.NewSourceTokenDataPayload(11, ethereumDomainCCTP).ToBytes(), + }, + exectypes.NewMessageTokenID(1, 2): { + ExtraData: reader.NewSourceTokenDataPayload(21, ethereumDomainCCTP).ToBytes(), + }, + }, + sourceChain: ethereumChain, + destChain: avalancheChain, + expectedMsgIDs: []exectypes.MessageTokenID{ + exectypes.NewMessageTokenID(1, 1), + exectypes.NewMessageTokenID(1, 2), + }, + }, + { + name: "message with multiple tokens, one without matching nonce", + tokens: map[exectypes.MessageTokenID]cciptypes.RampTokenAmount{ + exectypes.NewMessageTokenID(1, 1): { + ExtraData: reader.NewSourceTokenDataPayload(11, ethereumDomainCCTP).ToBytes(), + }, + exectypes.NewMessageTokenID(1, 2): { + ExtraData: reader.NewSourceTokenDataPayload(12, ethereumDomainCCTP).ToBytes(), + }, + exectypes.NewMessageTokenID(1, 3): { + ExtraData: reader.NewSourceTokenDataPayload(31, ethereumDomainCCTP).ToBytes(), + }, + }, + sourceChain: ethereumChain, + destChain: avalancheChain, + expectedMsgIDs: []exectypes.MessageTokenID{ + exectypes.NewMessageTokenID(1, 1), + exectypes.NewMessageTokenID(1, 3), + }, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + require.Eventually(t, func() bool { + hashes, err1 := usdcReader.MessageHashes(ctx, tc.sourceChain, tc.destChain, tc.tokens) + require.NoError(t, err1) + + if len(tc.expectedMsgIDs) != len(hashes) { + return false + } + + for _, msgID := range tc.expectedMsgIDs { + if _, ok := hashes[msgID]; !ok { + return false + } + } + return true + }, 2*time.Second, 100*time.Millisecond) + }) + } +} + +func emitMessageSent(t *testing.T, testEnv *testSetupData, source, dest uint32, nonce uint64) { + payload := utils.RandomBytes32() + _, err := testEnv.contract.EmitMessageSent( + testEnv.auth, + reader.CCTPMessageVersion, + source, + dest, + utils.RandomBytes32(), + utils.RandomBytes32(), + [32]byte{}, + nonce, + payload[:], + ) + require.NoError(t, err) + testEnv.sb.Commit() +} + +func testSetup(ctx context.Context, t *testing.T, readerChain cciptypes.ChainSelector, cfg evmtypes.ChainReaderConfig) *testSetupData { + const chainID = 1337 + + // Generate a new key pair for the simulated account + privateKey, err := crypto.GenerateKey() + assert.NoError(t, err) + // Set up the genesis account with balance + blnc, ok := big.NewInt(0).SetString("999999999999999999999999999999999999", 10) + assert.True(t, ok) + alloc := map[common.Address]core.GenesisAccount{crypto.PubkeyToAddress(privateKey.PublicKey): {Balance: blnc}} + simulatedBackend := backends.NewSimulatedBackend(alloc, 0) + // Create a transactor + + auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(chainID)) + assert.NoError(t, err) + auth.GasLimit = uint64(0) + + address, _, _, err := usdc_reader_tester.DeployUSDCReaderTester( + auth, + simulatedBackend, + ) + require.NoError(t, err) + simulatedBackend.Commit() + + contract, err := usdc_reader_tester.NewUSDCReaderTester(address, simulatedBackend) + require.NoError(t, err) + + lggr := logger.TestLogger(t) + lggr.SetLogLevel(zapcore.ErrorLevel) + db := pgtest.NewSqlxDB(t) + lpOpts := logpoller.Opts{ + PollPeriod: time.Millisecond, + FinalityDepth: 0, + BackfillBatchSize: 10, + RpcBatchSize: 10, + KeepFinalizedBlocksDepth: 100000, + } + cl := client.NewSimulatedBackendClient(t, simulatedBackend, big.NewInt(0).SetUint64(uint64(readerChain))) + headTracker := headtracker.NewSimulatedHeadTracker(cl, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + lp := logpoller.NewLogPoller(logpoller.NewORM(big.NewInt(0).SetUint64(uint64(readerChain)), db, lggr), + cl, + lggr, + headTracker, + lpOpts, + ) + require.NoError(t, lp.Start(ctx)) + + cr, err := evm.NewChainReaderService(ctx, lggr, lp, headTracker, cl, cfg) + require.NoError(t, err) + + err = cr.Start(ctx) + require.NoError(t, err) + + t.Cleanup(func() { + require.NoError(t, cr.Close()) + require.NoError(t, lp.Close()) + require.NoError(t, db.Close()) + }) + + return &testSetupData{ + contractAddr: address, + contract: contract, + sb: simulatedBackend, + auth: auth, + cl: cl, + reader: cr, + } +} + +type testSetupData struct { + contractAddr common.Address + contract *usdc_reader_tester.USDCReaderTester + sb *backends.SimulatedBackend + auth *bind.TransactOpts + cl client.Client + reader types.ContractReader +} diff --git a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go index 8d824d8d0e..562287eaf6 100644 --- a/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go +++ b/core/gethwrappers/ccip/generated/ccip_reader_tester/ccip_reader_tester.go @@ -100,7 +100,7 @@ type OffRampSourceChainConfig struct { var CCIPReaderTesterMetaData = &bind.MetaData{ ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPMessageSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"onRampAddress\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMNV2.Signature[]\",\"name\":\"rmnSignatures\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"emitCCIPMessageSent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"onRampAddress\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structIRMNV2.Signature[]\",\"name\":\"rmnSignatures\",\"type\":\"tuple[]\"}],\"internalType\":\"structOffRamp.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"emitCommitReportAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"emitExecutionStateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"getInboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"setDestChainSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"testNonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"setInboundNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceChainConfig\",\"type\":\"tuple\"}],\"name\":\"setSourceChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b506115e2806100206000396000f3fe608060405234801561001057600080fd5b50600436106100835760003560e01c806344f38be5146100885780634cf66e361461009d5780639041be3d146100b057806393df2867146100e0578063a4b0d27c146100f3578063c1a5a35514610106578063c922362514610142578063e83eabba14610155578063e9d68a8e14610168575b600080fd5b61009b6100963660046108c9565b610188565b005b61009b6100ab366004610a53565b6101c2565b6100c36100be366004610ad1565b610217565b6040516001600160401b0390911681526020015b60405180910390f35b61009b6100ee366004610b3b565b610246565b61009b610101366004610d3f565b6102a7565b61009b610114366004610e6d565b6001600160401b03918216600090815260016020526040902080546001600160401b03191691909216179055565b6100c3610150366004610ea0565b6102ec565b61009b610163366004610ef2565b610336565b61017b610176366004610ad1565b6103c2565b6040516100d79190610ff3565b7fd7868a16facbdde7b5c020620136316b3c266fffcb4e1e41cb6a662fe14ba3e1816040516101b79190611189565b60405180910390a150565b82846001600160401b0316866001600160401b03167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df2858560405161020892919061125b565b60405180910390a45050505050565b6001600160401b0380821660009081526001602081905260408220549192610240921690611292565b92915050565b6001600160401b03841660009081526002602052604090819020905184919061027290859085906112c7565b90815260405190819003602001902080546001600160401b03929092166001600160401b031990921691909117905550505050565b816001600160401b03167ff6e86ef8896c7a0d629406168f396e883280680c99e649b9e2d36466fbc9f9e5826040516102e09190611389565b60405180910390a25050565b6001600160401b038316600090815260026020526040808220905161031490859085906112c7565b908152604051908190036020019020546001600160401b031690509392505050565b6001600160401b0380831660009081526020818152604091829020845181549286015193860151909416600160a81b02600160a81b600160e81b0319931515600160a01b026001600160a81b03199093166001600160a01b03909516949094179190911791909116919091178155606082015182919060018201906103bb9082611516565b5050505050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b038781168452838352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b90920490921694830194909452600184018054939492939184019161044d9061148b565b80601f01602080910402602001604051908101604052809291908181526020018280546104799061148b565b80156104c65780601f1061049b576101008083540402835291602001916104c6565b820191906000526020600020905b8154815290600101906020018083116104a957829003601f168201915b5050505050815250509050919050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561050e5761050e6104d6565b60405290565b60405160a081016001600160401b038111828210171561050e5761050e6104d6565b604051606081016001600160401b038111828210171561050e5761050e6104d6565b60405161010081016001600160401b038111828210171561050e5761050e6104d6565b604051608081016001600160401b038111828210171561050e5761050e6104d6565b604051601f8201601f191681016001600160401b03811182821017156105c5576105c56104d6565b604052919050565b60006001600160401b038211156105e6576105e66104d6565b5060051b60200190565b6001600160a01b038116811461060557600080fd5b50565b8035610613816105f0565b919050565b80356001600160e01b038116811461061357600080fd5b80356001600160401b038116811461061357600080fd5b600082601f83011261065757600080fd5b8135602061066c610667836105cd565b61059d565b82815260069290921b8401810191818101908684111561068b57600080fd5b8286015b848110156106d857604081890312156106a85760008081fd5b6106b06104ec565b6106b98261062f565b81526106c6858301610618565b8186015283529183019160400161068f565b509695505050505050565b600082601f8301126106f457600080fd5b81356001600160401b0381111561070d5761070d6104d6565b610720601f8201601f191660200161059d565b81815284602083860101111561073557600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261076357600080fd5b81356020610773610667836105cd565b82815260059290921b8401810191818101908684111561079257600080fd5b8286015b848110156106d85780356001600160401b03808211156107b65760008081fd5b9088019060a0828b03601f19018113156107d05760008081fd5b6107d8610514565b6107e388850161062f565b815260406107f281860161062f565b89830152606061080381870161062f565b8284015260809150818601358184015250828501359250838311156108285760008081fd5b6108368d8a858801016106e3565b908201528652505050918301918301610796565b600082601f83011261085b57600080fd5b8135602061086b610667836105cd565b82815260069290921b8401810191818101908684111561088a57600080fd5b8286015b848110156106d857604081890312156108a75760008081fd5b6108af6104ec565b81358152848201358582015283529183019160400161088e565b600060208083850312156108dc57600080fd5b82356001600160401b03808211156108f357600080fd5b908401906060828703121561090757600080fd5b61090f610536565b82358281111561091e57600080fd5b8301604081890381131561093157600080fd5b6109396104ec565b82358581111561094857600080fd5b8301601f81018b1361095957600080fd5b8035610967610667826105cd565b81815260069190911b8201890190898101908d83111561098657600080fd5b928a01925b828410156109d65785848f0312156109a35760008081fd5b6109ab6104ec565b84356109b6816105f0565b81526109c3858d01610618565b818d0152825292850192908a019061098b565b8452505050828701359150848211156109ee57600080fd5b6109fa8a838501610646565b81880152835250508284013582811115610a1357600080fd5b610a1f88828601610752565b85830152506040830135935081841115610a3857600080fd5b610a448785850161084a565b60408201529695505050505050565b600080600080600060a08688031215610a6b57600080fd5b610a748661062f565b9450610a826020870161062f565b935060408601359250606086013560048110610a9d57600080fd5b915060808601356001600160401b03811115610ab857600080fd5b610ac4888289016106e3565b9150509295509295909350565b600060208284031215610ae357600080fd5b610aec8261062f565b9392505050565b60008083601f840112610b0557600080fd5b5081356001600160401b03811115610b1c57600080fd5b602083019150836020828501011115610b3457600080fd5b9250929050565b60008060008060608587031215610b5157600080fd5b610b5a8561062f565b9350610b686020860161062f565b925060408501356001600160401b03811115610b8357600080fd5b610b8f87828801610af3565b95989497509550505050565b600060a08284031215610bad57600080fd5b610bb5610514565b905081358152610bc76020830161062f565b6020820152610bd86040830161062f565b6040820152610be96060830161062f565b6060820152610bfa6080830161062f565b608082015292915050565b600082601f830112610c1657600080fd5b81356020610c26610667836105cd565b82815260059290921b84018101918181019086841115610c4557600080fd5b8286015b848110156106d85780356001600160401b0380821115610c695760008081fd5b9088019060a0828b03601f1901811315610c835760008081fd5b610c8b610514565b8784013583811115610c9d5760008081fd5b610cab8d8a838801016106e3565b82525060408085013584811115610cc25760008081fd5b610cd08e8b838901016106e3565b8a8401525060608086013585811115610ce95760008081fd5b610cf78f8c838a01016106e3565b83850152506080915081860135818401525082850135925083831115610d1d5760008081fd5b610d2b8d8a858801016106e3565b908201528652505050918301918301610c49565b60008060408385031215610d5257600080fd5b610d5b8361062f565b915060208301356001600160401b0380821115610d7757600080fd5b908401906101808287031215610d8c57600080fd5b610d94610558565b610d9e8784610b9b565b8152610dac60a08401610608565b602082015260c083013582811115610dc357600080fd5b610dcf888286016106e3565b60408301525060e083013582811115610de757600080fd5b610df3888286016106e3565b60608301525061010083013582811115610e0c57600080fd5b610e18888286016106e3565b608083015250610e2b6101208401610608565b60a082015261014083013560c082015261016083013582811115610e4e57600080fd5b610e5a88828601610c05565b60e0830152508093505050509250929050565b60008060408385031215610e8057600080fd5b610e898361062f565b9150610e976020840161062f565b90509250929050565b600080600060408486031215610eb557600080fd5b610ebe8461062f565b925060208401356001600160401b03811115610ed957600080fd5b610ee586828701610af3565b9497909650939450505050565b60008060408385031215610f0557600080fd5b610f0e8361062f565b915060208301356001600160401b0380821115610f2a57600080fd5b9084019060808287031215610f3e57600080fd5b610f4661057b565b8235610f51816105f0565b815260208301358015158114610f6657600080fd5b6020820152610f776040840161062f565b6040820152606083013582811115610f8e57600080fd5b610f9a888286016106e3565b6060830152508093505050509250929050565b6000815180845260005b81811015610fd357602081850181015186830182015201610fb7565b506000602082860101526020601f19601f83011685010191505092915050565b602080825282516001600160a01b03168282015282015115156040808301919091528201516001600160401b031660608083019190915282015160808083015260009061104360a0840182610fad565b949350505050565b6001600160a01b03169052565b60008151808452602080850194506020840160005b838110156110a657815180516001600160401b031688528301516001600160e01b0316838801526040909601959082019060010161106d565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b8481101561114057858303601f19018952815180516001600160401b03908116855285820151811686860152604080830151909116908501526060808201519085015260809081015160a09185018290529061112c81860183610fad565b9a86019a94505050908301906001016110ce565b5090979650505050505050565b60008151808452602080850194506020840160005b838110156110a6578151805188528301518388015260409096019590820190600101611162565b602080825282516060838301528051604060808501819052815160c086018190526000949392840191859160e08801905b808410156111f557845180516001600160a01b031683528701516001600160e01b0316878301529386019360019390930192908201906111ba565b5093850151878503607f190160a0890152936112118186611058565b945050505050818501519150601f198085830301604086015261123482846110b1565b9250604086015191508085840301606086015250611252828261114d565b95945050505050565b60006004841061127b57634e487b7160e01b600052602160045260246000fd5b838252604060208301526110436040830184610fad565b6001600160401b038181168382160190808211156112c057634e487b7160e01b600052601160045260246000fd5b5092915050565b8183823760009101908152919050565b600082825180855260208086019550808260051b84010181860160005b8481101561114057601f19868403018952815160a0815181865261131a82870182610fad565b91505085820151858203878701526113328282610fad565b9150506040808301518683038288015261134c8382610fad565b925050506060808301518187015250608080830151925085820381870152506113758183610fad565b9a86019a94505050908301906001016112f4565b602081526113d6602082018351805182526020808201516001600160401b039081169184019190915260408083015182169084015260608083015182169084015260809182015116910152565b600060208301516113ea60c084018261104b565b5060408301516101808060e08501526114076101a0850183610fad565b91506060850151601f1980868503016101008701526114268483610fad565b93506080870151915080868503016101208701526114448483610fad565b935060a0870151915061145b61014087018361104b565b60c087015161016087015260e087015191508086850301838701525061148183826112d7565b9695505050505050565b600181811c9082168061149f57607f821691505b6020821081036114bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115611511576000816000526020600020601f850160051c810160208610156114ee5750805b601f850160051c820191505b8181101561150d578281556001016114fa565b5050505b505050565b81516001600160401b0381111561152f5761152f6104d6565b6115438161153d845461148b565b846114c5565b602080601f83116001811461157857600084156115605750858301515b600019600386901b1c1916600185901b17855561150d565b600085815260208120601f198616915b828110156115a757888601518255948401946001909101908401611588565b50858210156115c55787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", + Bin: "0x608060405234801561001057600080fd5b50611952806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063a4b0d27c11610076578063c92236251161005b578063c92236251461017c578063e83eabba1461018f578063e9d68a8e146101a257600080fd5b8063a4b0d27c14610114578063c1a5a3551461012757600080fd5b806344f38be5146100a85780634cf66e36146100bd5780639041be3d146100d057806393df286714610101575b600080fd5b6100bb6100b6366004610a52565b6101c2565b005b6100bb6100cb366004610bdd565b6101fc565b6100e36100de366004610c5c565b610253565b60405167ffffffffffffffff90911681526020015b60405180910390f35b6100bb61010f366004610cc7565b610283565b6100bb610122366004610eec565b6102fe565b6100bb61013536600461101b565b67ffffffffffffffff918216600090815260016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001691909216179055565b6100e361018a36600461104e565b610344565b6100bb61019d3660046110a1565b610390565b6101b56101b0366004610c5c565b61047a565b6040516100f891906111c1565b7fd7868a16facbdde7b5c020620136316b3c266fffcb4e1e41cb6a662fe14ba3e1816040516101f1919061138a565b60405180910390a150565b828467ffffffffffffffff168667ffffffffffffffff167f8c324ce1367b83031769f6a813e3bb4c117aba2185789d66b98b791405be6df285856040516102449291906114ba565b60405180910390a45050505050565b67ffffffffffffffff8082166000908152600160208190526040822054919261027d92169061150a565b92915050565b67ffffffffffffffff84166000908152600260205260409081902090518491906102b09085908590611559565b908152604051908190036020019020805467ffffffffffffffff929092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090921691909117905550505050565b8167ffffffffffffffff167ff6e86ef8896c7a0d629406168f396e883280680c99e649b9e2d36466fbc9f9e5826040516103389190611639565b60405180910390a25050565b67ffffffffffffffff8316600090815260026020526040808220905161036d9085908590611559565b9081526040519081900360200190205467ffffffffffffffff1690509392505050565b67ffffffffffffffff808316600090815260208181526040918290208451815492860151938601519094167501000000000000000000000000000000000000000000027fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff93151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00000000000000000000000000000000000000000090931673ffffffffffffffffffffffffffffffffffffffff90951694909417919091179190911691909117815560608201518291906001820190610473908261182b565b5050505050565b604080516080808201835260008083526020808401829052838501829052606080850181905267ffffffffffffffff87811684528383529286902086519485018752805473ffffffffffffffffffffffffffffffffffffffff8116865274010000000000000000000000000000000000000000810460ff16151593860193909352750100000000000000000000000000000000000000000090920490921694830194909452600184018054939492939184019161053690611787565b80601f016020809104026020016040519081016040528092919081815260200182805461056290611787565b80156105af5780601f10610584576101008083540402835291602001916105af565b820191906000526020600020905b81548152906001019060200180831161059257829003601f168201915b5050505050815250509050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610611576106116105bf565b60405290565b60405160a0810167ffffffffffffffff81118282101715610611576106116105bf565b6040516060810167ffffffffffffffff81118282101715610611576106116105bf565b604051610100810167ffffffffffffffff81118282101715610611576106116105bf565b6040516080810167ffffffffffffffff81118282101715610611576106116105bf565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156106eb576106eb6105bf565b604052919050565b600067ffffffffffffffff82111561070d5761070d6105bf565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461073957600080fd5b50565b803561074781610717565b919050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461074757600080fd5b803567ffffffffffffffff8116811461074757600080fd5b600082601f8301126107a157600080fd5b813560206107b66107b1836106f3565b6106a4565b82815260069290921b840181019181810190868411156107d557600080fd5b8286015b8481101561082257604081890312156107f25760008081fd5b6107fa6105ee565b61080382610778565b815261081085830161074c565b818601528352918301916040016107d9565b509695505050505050565b600082601f83011261083e57600080fd5b813567ffffffffffffffff811115610858576108586105bf565b61088960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016106a4565b81815284602083860101111561089e57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126108cc57600080fd5b813560206108dc6107b1836106f3565b82815260059290921b840181019181810190868411156108fb57600080fd5b8286015b8481101561082257803567ffffffffffffffff808211156109205760008081fd5b818901915060a0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d030112156109595760008081fd5b610961610617565b61096c888501610778565b8152604061097b818601610778565b89830152606061098c818701610778565b8284015260809150818601358184015250828501359250838311156109b15760008081fd5b6109bf8d8a8588010161082d565b9082015286525050509183019183016108ff565b600082601f8301126109e457600080fd5b813560206109f46107b1836106f3565b82815260069290921b84018101918181019086841115610a1357600080fd5b8286015b848110156108225760408189031215610a305760008081fd5b610a386105ee565b813581528482013585820152835291830191604001610a17565b60006020808385031215610a6557600080fd5b823567ffffffffffffffff80821115610a7d57600080fd5b9084019060608287031215610a9157600080fd5b610a9961063a565b823582811115610aa857600080fd5b83016040818903811315610abb57600080fd5b610ac36105ee565b823585811115610ad257600080fd5b8301601f81018b13610ae357600080fd5b8035610af16107b1826106f3565b81815260069190911b8201890190898101908d831115610b1057600080fd5b928a01925b82841015610b605785848f031215610b2d5760008081fd5b610b356105ee565b8435610b4081610717565b8152610b4d858d0161074c565b818d0152825292850192908a0190610b15565b845250505082870135915084821115610b7857600080fd5b610b848a838501610790565b81880152835250508284013582811115610b9d57600080fd5b610ba9888286016108bb565b85830152506040830135935081841115610bc257600080fd5b610bce878585016109d3565b60408201529695505050505050565b600080600080600060a08688031215610bf557600080fd5b610bfe86610778565b9450610c0c60208701610778565b935060408601359250606086013560048110610c2757600080fd5b9150608086013567ffffffffffffffff811115610c4357600080fd5b610c4f8882890161082d565b9150509295509295909350565b600060208284031215610c6e57600080fd5b610c7782610778565b9392505050565b60008083601f840112610c9057600080fd5b50813567ffffffffffffffff811115610ca857600080fd5b602083019150836020828501011115610cc057600080fd5b9250929050565b60008060008060608587031215610cdd57600080fd5b610ce685610778565b9350610cf460208601610778565b9250604085013567ffffffffffffffff811115610d1057600080fd5b610d1c87828801610c7e565b95989497509550505050565b600060a08284031215610d3a57600080fd5b610d42610617565b905081358152610d5460208301610778565b6020820152610d6560408301610778565b6040820152610d7660608301610778565b6060820152610d8760808301610778565b608082015292915050565b600082601f830112610da357600080fd5b81356020610db36107b1836106f3565b82815260059290921b84018101918181019086841115610dd257600080fd5b8286015b8481101561082257803567ffffffffffffffff80821115610df75760008081fd5b818901915060a0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848d03011215610e305760008081fd5b610e38610617565b8784013583811115610e4a5760008081fd5b610e588d8a8388010161082d565b82525060408085013584811115610e6f5760008081fd5b610e7d8e8b8389010161082d565b8a8401525060608086013585811115610e965760008081fd5b610ea48f8c838a010161082d565b83850152506080915081860135818401525082850135925083831115610eca5760008081fd5b610ed88d8a8588010161082d565b908201528652505050918301918301610dd6565b60008060408385031215610eff57600080fd5b610f0883610778565b9150602083013567ffffffffffffffff80821115610f2557600080fd5b908401906101808287031215610f3a57600080fd5b610f4261065d565b610f4c8784610d28565b8152610f5a60a0840161073c565b602082015260c083013582811115610f7157600080fd5b610f7d8882860161082d565b60408301525060e083013582811115610f9557600080fd5b610fa18882860161082d565b60608301525061010083013582811115610fba57600080fd5b610fc68882860161082d565b608083015250610fd9610120840161073c565b60a082015261014083013560c082015261016083013582811115610ffc57600080fd5b61100888828601610d92565b60e0830152508093505050509250929050565b6000806040838503121561102e57600080fd5b61103783610778565b915061104560208401610778565b90509250929050565b60008060006040848603121561106357600080fd5b61106c84610778565b9250602084013567ffffffffffffffff81111561108857600080fd5b61109486828701610c7e565b9497909650939450505050565b600080604083850312156110b457600080fd5b6110bd83610778565b9150602083013567ffffffffffffffff808211156110da57600080fd5b90840190608082870312156110ee57600080fd5b6110f6610681565b823561110181610717565b81526020830135801515811461111657600080fd5b602082015261112760408401610778565b604082015260608301358281111561113e57600080fd5b61114a8882860161082d565b6060830152508093505050509250929050565b6000815180845260005b8181101561118357602081850181015186830182015201611167565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815273ffffffffffffffffffffffffffffffffffffffff825116602082015260208201511515604082015267ffffffffffffffff60408301511660608201526000606083015160808084015261121c60a084018261115d565b949350505050565b60008151808452602080850194506020840160005b83811015611288578151805167ffffffffffffffff1688528301517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168388015260409096019590820190600101611239565b509495945050505050565b600082825180855260208086019550808260051b84010181860160005b84811015611341578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00189528151805167ffffffffffffffff908116855285820151811686860152604080830151909116908501526060808201519085015260809081015160a09185018290529061132d8186018361115d565b9a86019a94505050908301906001016112b0565b5090979650505050505050565b60008151808452602080850194506020840160005b83811015611288578151805188528301518388015260409096019590820190600101611363565b602080825282516060838301528051604060808501819052815160c086018190526000949392840191859160e08801905b80841015611418578451805173ffffffffffffffffffffffffffffffffffffffff1683528701517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16878301529386019360019390930192908201906113bb565b50938501518785037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800160a0890152936114528186611224565b9450505050508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808583030160408601526114938284611293565b92506040860151915080858403016060860152506114b1828261134e565b95945050505050565b6000600484106114f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8382526040602083015261121c604083018461115d565b67ffffffffffffffff818116838216019080821115611552577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5092915050565b8183823760009101908152919050565b600082825180855260208086019550808260051b84010181860160005b84811015611341577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160a081518186526115ca8287018261115d565b91505085820151858203878701526115e2828261115d565b915050604080830151868303828801526115fc838261115d565b92505050606080830151818701525060808083015192508582038187015250611625818361115d565b9a86019a9450505090830190600101611586565b6020815261168a60208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b600060208301516116b360c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e08501526116d06101a085018361115d565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808685030161010087015261170d848361115d565b935060808701519150808685030161012087015261172b848361115d565b935060a0870151915061175761014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e087015191508086850301838701525061177d8382611569565b9695505050505050565b600181811c9082168061179b57607f821691505b6020821081036117d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115611826576000816000526020600020601f850160051c810160208610156118035750805b601f850160051c820191505b818110156118225782815560010161180f565b5050505b505050565b815167ffffffffffffffff811115611845576118456105bf565b611859816118538454611787565b846117da565b602080601f8311600181146118ac57600084156118765750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611822565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156118f9578886015182559484019460019091019084016118da565b508582101561193557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000818000a", } var CCIPReaderTesterABI = CCIPReaderTesterMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/usdc_reader_tester/usdc_reader_tester.go b/core/gethwrappers/ccip/generated/usdc_reader_tester/usdc_reader_tester.go new file mode 100644 index 0000000000..f9bd3b56ef --- /dev/null +++ b/core/gethwrappers/ccip/generated/usdc_reader_tester/usdc_reader_tester.go @@ -0,0 +1,333 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package usdc_reader_tester + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var USDCReaderTesterMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"MessageSent\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"sourceDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"recipient\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"destinationCaller\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"messageBody\",\"type\":\"bytes\"}],\"name\":\"emitMessageSent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061032c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806362826f1814610030575b600080fd5b61004361003e366004610129565b610045565b005b600061008d8a8a8a87898c8c8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506100d292505050565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036816040516100be9190610228565b60405180910390a150505050505050505050565b606088888888888888886040516020016100f3989796959493929190610279565b604051602081830303815290604052905098975050505050505050565b803563ffffffff8116811461012457600080fd5b919050565b60008060008060008060008060006101008a8c03121561014857600080fd5b6101518a610110565b985061015f60208b01610110565b975061016d60408b01610110565b965060608a0135955060808a0135945060a08a0135935060c08a013567ffffffffffffffff80821682146101a057600080fd5b90935060e08b013590808211156101b657600080fd5b818c0191508c601f8301126101ca57600080fd5b8135818111156101d957600080fd5b8d60208285010111156101eb57600080fd5b6020830194508093505050509295985092959850929598565b60005b8381101561021f578181015183820152602001610207565b50506000910152565b6020815260008251806020840152610247816040850160208701610204565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60007fffffffff00000000000000000000000000000000000000000000000000000000808b60e01b168352808a60e01b166004840152808960e01b166008840152507fffffffffffffffff0000000000000000000000000000000000000000000000008760c01b16600c830152856014830152846034830152836054830152825161030b816074850160208701610204565b91909101607401999850505050505050505056fea164736f6c6343000818000a", +} + +var USDCReaderTesterABI = USDCReaderTesterMetaData.ABI + +var USDCReaderTesterBin = USDCReaderTesterMetaData.Bin + +func DeployUSDCReaderTester(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *USDCReaderTester, error) { + parsed, err := USDCReaderTesterMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(USDCReaderTesterBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &USDCReaderTester{address: address, abi: *parsed, USDCReaderTesterCaller: USDCReaderTesterCaller{contract: contract}, USDCReaderTesterTransactor: USDCReaderTesterTransactor{contract: contract}, USDCReaderTesterFilterer: USDCReaderTesterFilterer{contract: contract}}, nil +} + +type USDCReaderTester struct { + address common.Address + abi abi.ABI + USDCReaderTesterCaller + USDCReaderTesterTransactor + USDCReaderTesterFilterer +} + +type USDCReaderTesterCaller struct { + contract *bind.BoundContract +} + +type USDCReaderTesterTransactor struct { + contract *bind.BoundContract +} + +type USDCReaderTesterFilterer struct { + contract *bind.BoundContract +} + +type USDCReaderTesterSession struct { + Contract *USDCReaderTester + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type USDCReaderTesterCallerSession struct { + Contract *USDCReaderTesterCaller + CallOpts bind.CallOpts +} + +type USDCReaderTesterTransactorSession struct { + Contract *USDCReaderTesterTransactor + TransactOpts bind.TransactOpts +} + +type USDCReaderTesterRaw struct { + Contract *USDCReaderTester +} + +type USDCReaderTesterCallerRaw struct { + Contract *USDCReaderTesterCaller +} + +type USDCReaderTesterTransactorRaw struct { + Contract *USDCReaderTesterTransactor +} + +func NewUSDCReaderTester(address common.Address, backend bind.ContractBackend) (*USDCReaderTester, error) { + abi, err := abi.JSON(strings.NewReader(USDCReaderTesterABI)) + if err != nil { + return nil, err + } + contract, err := bindUSDCReaderTester(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &USDCReaderTester{address: address, abi: abi, USDCReaderTesterCaller: USDCReaderTesterCaller{contract: contract}, USDCReaderTesterTransactor: USDCReaderTesterTransactor{contract: contract}, USDCReaderTesterFilterer: USDCReaderTesterFilterer{contract: contract}}, nil +} + +func NewUSDCReaderTesterCaller(address common.Address, caller bind.ContractCaller) (*USDCReaderTesterCaller, error) { + contract, err := bindUSDCReaderTester(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &USDCReaderTesterCaller{contract: contract}, nil +} + +func NewUSDCReaderTesterTransactor(address common.Address, transactor bind.ContractTransactor) (*USDCReaderTesterTransactor, error) { + contract, err := bindUSDCReaderTester(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &USDCReaderTesterTransactor{contract: contract}, nil +} + +func NewUSDCReaderTesterFilterer(address common.Address, filterer bind.ContractFilterer) (*USDCReaderTesterFilterer, error) { + contract, err := bindUSDCReaderTester(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &USDCReaderTesterFilterer{contract: contract}, nil +} + +func bindUSDCReaderTester(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := USDCReaderTesterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_USDCReaderTester *USDCReaderTesterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _USDCReaderTester.Contract.USDCReaderTesterCaller.contract.Call(opts, result, method, params...) +} + +func (_USDCReaderTester *USDCReaderTesterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _USDCReaderTester.Contract.USDCReaderTesterTransactor.contract.Transfer(opts) +} + +func (_USDCReaderTester *USDCReaderTesterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _USDCReaderTester.Contract.USDCReaderTesterTransactor.contract.Transact(opts, method, params...) +} + +func (_USDCReaderTester *USDCReaderTesterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _USDCReaderTester.Contract.contract.Call(opts, result, method, params...) +} + +func (_USDCReaderTester *USDCReaderTesterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _USDCReaderTester.Contract.contract.Transfer(opts) +} + +func (_USDCReaderTester *USDCReaderTesterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _USDCReaderTester.Contract.contract.Transact(opts, method, params...) +} + +func (_USDCReaderTester *USDCReaderTesterTransactor) EmitMessageSent(opts *bind.TransactOpts, version uint32, sourceDomain uint32, destinationDomain uint32, recipient [32]byte, destinationCaller [32]byte, sender [32]byte, nonce uint64, messageBody []byte) (*types.Transaction, error) { + return _USDCReaderTester.contract.Transact(opts, "emitMessageSent", version, sourceDomain, destinationDomain, recipient, destinationCaller, sender, nonce, messageBody) +} + +func (_USDCReaderTester *USDCReaderTesterSession) EmitMessageSent(version uint32, sourceDomain uint32, destinationDomain uint32, recipient [32]byte, destinationCaller [32]byte, sender [32]byte, nonce uint64, messageBody []byte) (*types.Transaction, error) { + return _USDCReaderTester.Contract.EmitMessageSent(&_USDCReaderTester.TransactOpts, version, sourceDomain, destinationDomain, recipient, destinationCaller, sender, nonce, messageBody) +} + +func (_USDCReaderTester *USDCReaderTesterTransactorSession) EmitMessageSent(version uint32, sourceDomain uint32, destinationDomain uint32, recipient [32]byte, destinationCaller [32]byte, sender [32]byte, nonce uint64, messageBody []byte) (*types.Transaction, error) { + return _USDCReaderTester.Contract.EmitMessageSent(&_USDCReaderTester.TransactOpts, version, sourceDomain, destinationDomain, recipient, destinationCaller, sender, nonce, messageBody) +} + +type USDCReaderTesterMessageSentIterator struct { + Event *USDCReaderTesterMessageSent + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCReaderTesterMessageSentIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCReaderTesterMessageSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCReaderTesterMessageSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *USDCReaderTesterMessageSentIterator) Error() error { + return it.fail +} + +func (it *USDCReaderTesterMessageSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCReaderTesterMessageSent struct { + Arg0 []byte + Raw types.Log +} + +func (_USDCReaderTester *USDCReaderTesterFilterer) FilterMessageSent(opts *bind.FilterOpts) (*USDCReaderTesterMessageSentIterator, error) { + + logs, sub, err := _USDCReaderTester.contract.FilterLogs(opts, "MessageSent") + if err != nil { + return nil, err + } + return &USDCReaderTesterMessageSentIterator{contract: _USDCReaderTester.contract, event: "MessageSent", logs: logs, sub: sub}, nil +} + +func (_USDCReaderTester *USDCReaderTesterFilterer) WatchMessageSent(opts *bind.WatchOpts, sink chan<- *USDCReaderTesterMessageSent) (event.Subscription, error) { + + logs, sub, err := _USDCReaderTester.contract.WatchLogs(opts, "MessageSent") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCReaderTesterMessageSent) + if err := _USDCReaderTester.contract.UnpackLog(event, "MessageSent", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_USDCReaderTester *USDCReaderTesterFilterer) ParseMessageSent(log types.Log) (*USDCReaderTesterMessageSent, error) { + event := new(USDCReaderTesterMessageSent) + if err := _USDCReaderTester.contract.UnpackLog(event, "MessageSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_USDCReaderTester *USDCReaderTester) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _USDCReaderTester.abi.Events["MessageSent"].ID: + return _USDCReaderTester.ParseMessageSent(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (USDCReaderTesterMessageSent) Topic() common.Hash { + return common.HexToHash("0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036") +} + +func (_USDCReaderTester *USDCReaderTester) Address() common.Address { + return _USDCReaderTester.address +} + +type USDCReaderTesterInterface interface { + EmitMessageSent(opts *bind.TransactOpts, version uint32, sourceDomain uint32, destinationDomain uint32, recipient [32]byte, destinationCaller [32]byte, sender [32]byte, nonce uint64, messageBody []byte) (*types.Transaction, error) + + FilterMessageSent(opts *bind.FilterOpts) (*USDCReaderTesterMessageSentIterator, error) + + WatchMessageSent(opts *bind.WatchOpts, sink chan<- *USDCReaderTesterMessageSent) (event.Subscription, error) + + ParseMessageSent(log types.Log) (*USDCReaderTesterMessageSent, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index a6efa69b55..ccd0f590f4 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -5,7 +5,7 @@ burn_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnMintTokenPoo burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 6333d0314d0bd29e75ea5e05fe62a4516ade0c6db91c30b6f93645035db52ed8 burn_with_from_mint_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPoolAndProxy/BurnWithFromMintTokenPoolAndProxy.bin 08ed1235dda921ce8841b26aa18d0c0f36db4884779dd7670857159801b6d597 ccip_config: ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin 75955a3dcfd66b308be07eda54d6036cc79e87d3cdcf3c5c3115813c55912af8 -ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin 82d93ae8cce97a0a72f9a849f01df99e3930aead0021573abfacbc412fc77a17 +ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin 9e8704166df11383257fdc6277adbe94c903d0c9148638fcbd263657ccca9152 commit_store: ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.abi ../../../contracts/solc/v0.8.24/CommitStore/CommitStore.bin 274d87db70b643e00ab0a7e7845bb4b791f3b613bfc87708d33fc5a8369e2a41 commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.abi ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitStoreHelper.bin f7128dcc2ee6dbcbc976288abcc16970ffb19b59412c5202ef6b259d2007f801 ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de @@ -36,5 +36,6 @@ router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/sol self_funded_ping_pong: ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.abi ../../../contracts/solc/v0.8.24/SelfFundedPingPong/SelfFundedPingPong.bin 8ea5d75dbc3f8afd90d22c4a665a94e02892259cd16520c1c6b4cf0dc80c9148 token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 942be7d1681ac102e0615bee13f76838ebb0b261697cf1270d2bf82c12e57aeb token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 7c01fd89f5153baa4d7409d14beabb3f861abfbf8880d3c6d06802cc398570f9 +usdc_reader_tester: ../../../contracts/solc/v0.8.24/USDCReaderTester/USDCReaderTester.abi ../../../contracts/solc/v0.8.24/USDCReaderTester/USDCReaderTester.bin 672a07c9218fd6ad7c04dde583088b0f5ffc8d55a46f4be1714008dd3409438b usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin 8e7eae4c7277ce4a0092cca815c046cc49094028c23d2d113de9335fa4358030 weth9: ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin 2970d79a0ca6dd6279cde130de45e56c8790ed695eae477fb5ba4c1bb75b720d diff --git a/core/gethwrappers/ccip/go_generate.go b/core/gethwrappers/ccip/go_generate.go index ba51fe13fc..f2a6be21f6 100644 --- a/core/gethwrappers/ccip/go_generate.go +++ b/core/gethwrappers/ccip/go_generate.go @@ -38,6 +38,7 @@ package ccip //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin MessageHasher message_hasher //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin MultiOCR3Helper multi_ocr3_helper //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin CCIPReaderTester ccip_reader_tester +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/USDCReaderTester/USDCReaderTester.abi ../../../contracts/solc/v0.8.24/USDCReaderTester/USDCReaderTester.bin USDCReaderTester usdc_reader_tester //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.abi ../../../contracts/solc/v0.8.24/ReportCodec/ReportCodec.bin ReportCodec report_codec //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin EtherSenderReceiver ether_sender_receiver //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin WETH9 weth9 diff --git a/core/scripts/go.mod b/core/scripts/go.mod index f664efe218..5cddebf4f1 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -271,7 +271,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index e8483420f8..58e2be3fae 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1081,8 +1081,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe h1:CPvnTxH7C+5ziD7zCopnRFZhlK65+e2dGdw6xISl/K4= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad h1:oEqKi71gr6Ldj8UKJuQOL70CHtNaoyR6pOFEyNgi6Z4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/go.mod b/go.mod index 00b171140d..cda7516092 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 diff --git a/go.sum b/go.sum index 0c63cfbc74..95195319df 100644 --- a/go.sum +++ b/go.sum @@ -1042,8 +1042,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe h1:CPvnTxH7C+5ziD7zCopnRFZhlK65+e2dGdw6xISl/K4= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad h1:oEqKi71gr6Ldj8UKJuQOL70CHtNaoyR6pOFEyNgi6Z4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 6188a31cae..ddf31828ff 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -39,7 +39,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240919155713-f4bf4ae0b9c6 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 9f7881750d..8b11b1da71 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1423,8 +1423,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe h1:CPvnTxH7C+5ziD7zCopnRFZhlK65+e2dGdw6xISl/K4= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad h1:oEqKi71gr6Ldj8UKJuQOL70CHtNaoyR6pOFEyNgi6Z4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 9717c843fd..96b9015a02 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -386,7 +386,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 8f671ac8a8..2ec777306d 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1397,8 +1397,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe h1:CPvnTxH7C+5ziD7zCopnRFZhlK65+e2dGdw6xISl/K4= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240920150748-cf2125c094fe/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad h1:oEqKi71gr6Ldj8UKJuQOL70CHtNaoyR6pOFEyNgi6Z4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= From ae53758229639db832d0571ffcb1c8d01774f950 Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Tue, 24 Sep 2024 17:15:39 +0400 Subject: [PATCH 419/432] update Smoke Test TestAutomationBasic to load pre-deployed contracts if given (#14537) --- .../actions/automation_ocr_helpers.go | 2 +- integration-tests/actions/keeper_helpers.go | 29 +++++++++++ .../ethereum_contracts_automation.go | 51 +++++++++++++++---- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index 8159427699..fb2fddb351 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -67,7 +67,7 @@ func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts. require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail") } - upkeeps := DeployKeeperConsumers(t, chainClient, numberOfUpkeeps, isLogTrigger, isMercury) + upkeeps := SetupKeeperConsumers(t, chainClient, numberOfUpkeeps, isLogTrigger, isMercury, config) require.Equal(t, numberOfUpkeeps, len(upkeeps), "Number of upkeeps should match") var upkeepsAddresses []string for _, upkeep := range upkeeps { diff --git a/integration-tests/actions/keeper_helpers.go b/integration-tests/actions/keeper_helpers.go index c7694946cf..1cf468d06f 100644 --- a/integration-tests/actions/keeper_helpers.go +++ b/integration-tests/actions/keeper_helpers.go @@ -8,6 +8,8 @@ import ( "strconv" "testing" + tt "github.com/smartcontractkit/chainlink/integration-tests/types" + "github.com/ethereum/go-ethereum/core/types" "github.com/google/uuid" "github.com/pkg/errors" @@ -456,6 +458,33 @@ func DeployKeeperConsumers(t *testing.T, client *seth.Client, numberOfContracts return results } +// SetupKeeperConsumers concurrently loads or deploys keeper consumer contracts. It requires at least 1 ephemeral key to be present in Seth config. +func SetupKeeperConsumers(t *testing.T, client *seth.Client, numberOfContracts int, isLogTrigger bool, isMercury bool, config tt.AutomationTestConfig) []contracts.KeeperConsumer { + l := logging.GetTestLogger(t) + + var results []contracts.KeeperConsumer + + if config.GetAutomationConfig().UseExistingUpkeepContracts() { + contractsLoaded, err := config.GetAutomationConfig().UpkeepContractAddresses() + require.NoError(t, err, "Failed to get upkeep contract addresses") + require.Equal(t, numberOfContracts, len(contractsLoaded), "Incorrect number of Keeper Consumer Contracts loaded") + l.Info().Int("Number of Contracts", numberOfContracts).Msg("Loading upkeep contracts from config") + // Load existing contracts + for i := 0; i < numberOfContracts; i++ { + require.NoError(t, err, "Failed to get upkeep contract addresses") + contract, err := contracts.LoadKeeperConsumer(client, contractsLoaded[i]) + require.NoError(t, err, "Failed to load keeper consumer contract") + l.Info().Str("Contract Address", contract.Address()).Int("Number", i+1).Int("Out Of", numberOfContracts).Msg("Loaded Keeper Consumer Contract") + results = append(results, contract) + } + } else { + // Deploy new contracts + return DeployKeeperConsumers(t, client, numberOfContracts, isLogTrigger, isMercury) + } + + return results +} + // DeployKeeperConsumersPerformance sequentially deploys keeper performance consumer contracts. func DeployKeeperConsumersPerformance( t *testing.T, diff --git a/integration-tests/contracts/ethereum_contracts_automation.go b/integration-tests/contracts/ethereum_contracts_automation.go index 5a3e405d92..3e18fe177f 100644 --- a/integration-tests/contracts/ethereum_contracts_automation.go +++ b/integration-tests/contracts/ethereum_contracts_automation.go @@ -2265,6 +2265,42 @@ func LoadKeeperRegistrar(client *seth.Client, address common.Address, registryVe return &EthereumKeeperRegistrar{}, fmt.Errorf("unsupported registry version: %v", registryVersion) } +type EthereumAutomationKeeperConsumer struct { + client *seth.Client + consumer *log_upkeep_counter_wrapper.LogUpkeepCounter + address *common.Address +} + +func (e EthereumAutomationKeeperConsumer) Address() string { + return e.address.Hex() +} + +func (e EthereumAutomationKeeperConsumer) Counter(ctx context.Context) (*big.Int, error) { + return e.consumer.Counter(&bind.CallOpts{ + From: e.client.MustGetRootKeyAddress(), + Context: ctx, + }) +} + +func (e EthereumAutomationKeeperConsumer) Start() error { + _, err := e.client.Decode(e.consumer.Start(e.client.NewTXOpts())) + return err +} + +func LoadKeeperConsumer(client *seth.Client, address common.Address) (*EthereumAutomationKeeperConsumer, error) { + loader := seth.NewContractLoader[log_upkeep_counter_wrapper.LogUpkeepCounter](client) + instance, err := loader.LoadContract("KeeperConsumer", address, log_upkeep_counter_wrapper.LogUpkeepCounterMetaData.GetAbi, log_upkeep_counter_wrapper.NewLogUpkeepCounter) + if err != nil { + return &EthereumAutomationKeeperConsumer{}, fmt.Errorf("failed to load KeeperConsumerMetaData instance: %w", err) + } + + return &EthereumAutomationKeeperConsumer{ + client: client, + consumer: instance, + address: &address, + }, nil +} + type EthereumAutomationLogTriggeredStreamsLookupUpkeepConsumer struct { client *seth.Client consumer *log_triggered_streams_lookup_wrapper.LogTriggeredStreamsLookup @@ -2723,22 +2759,15 @@ func DeployAutomationConsumerBenchmark(client *seth.Client) (AutomationConsumerB } func LoadAutomationConsumerBenchmark(client *seth.Client, address common.Address) (*EthereumAutomationConsumerBenchmark, error) { - abi, err := automation_consumer_benchmark.AutomationConsumerBenchmarkMetaData.GetAbi() + loader := seth.NewContractLoader[automation_consumer_benchmark.AutomationConsumerBenchmark](client) + instance, err := loader.LoadContract("AutomationConsumerBenchmark", address, automation_consumer_benchmark.AutomationConsumerBenchmarkMetaData.GetAbi, automation_consumer_benchmark.NewAutomationConsumerBenchmark) if err != nil { - return &EthereumAutomationConsumerBenchmark{}, fmt.Errorf("failed to get AutomationConsumerBenchmark token ABI: %w", err) - } - - client.ContractStore.AddABI("AutomationConsumerBenchmark", *abi) - client.ContractStore.AddBIN("AutomationConsumerBenchmark", common.FromHex(automation_consumer_benchmark.AutomationConsumerBenchmarkMetaData.Bin)) - - consumer, err := automation_consumer_benchmark.NewAutomationConsumerBenchmark(address, wrappers.MustNewWrappedContractBackend(nil, client)) - if err != nil { - return &EthereumAutomationConsumerBenchmark{}, fmt.Errorf("failed to instantiate EthereumAutomationConsumerBenchmark instance: %w", err) + return &EthereumAutomationConsumerBenchmark{}, fmt.Errorf("failed to load AutomationConsumerBenchmark instance: %w", err) } return &EthereumAutomationConsumerBenchmark{ client: client, - consumer: consumer, + consumer: instance, address: &address, }, nil } From 1d6a88ee7313ccb857db3995d7d6ed363d7d6589 Mon Sep 17 00:00:00 2001 From: Simson Date: Tue, 24 Sep 2024 19:32:55 +0530 Subject: [PATCH 420/432] Soneium configs (#14486) * soneium testnet config * updated configs * updated configs * changeset added * docs generate * added link token addresses * updated configs * updated docs --- .changeset/gorgeous-walls-sit.md | 5 + .../config/toml/defaults/Soneium_Sepolia.toml | 32 ++++++ docs/CONFIG.md | 104 ++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 .changeset/gorgeous-walls-sit.md create mode 100755 core/chains/evm/config/toml/defaults/Soneium_Sepolia.toml diff --git a/.changeset/gorgeous-walls-sit.md b/.changeset/gorgeous-walls-sit.md new file mode 100644 index 0000000000..dabda6f8ea --- /dev/null +++ b/.changeset/gorgeous-walls-sit.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added Soneium testnet chain configs diff --git a/core/chains/evm/config/toml/defaults/Soneium_Sepolia.toml b/core/chains/evm/config/toml/defaults/Soneium_Sepolia.toml new file mode 100755 index 0000000000..9f4772dd9a --- /dev/null +++ b/core/chains/evm/config/toml/defaults/Soneium_Sepolia.toml @@ -0,0 +1,32 @@ +ChainID = '1946' +ChainType = 'optimismBedrock' +LinkContractAddress = '0x7ea13478Ea3961A0e8b538cb05a9DF0477c79Cd2' +FinalityDepth = 200 +LogPollInterval = '2s' +NoNewHeadsThreshold = '40s' +MinIncomingConfirmations = 1 +NoNewFinalizedHeadsThreshold = '120m' # Soneium can take upto 2Hours to finalize +FinalityTagEnabled = true + +[GasEstimator] +EIP1559DynamicFees = true +PriceMin = '1 wei' +BumpMin = '1 mwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 60 + +[Transactions] +ResendAfterThreshold = '30s' + +[HeadTracker] +HistoryDepth = 300 + +[NodePool] +SyncThreshold = 10 + +[OCR] +ContractConfirmations = 1 + +[OCR2.Automation] +GasLimit = 6500000 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 1a4a2a4ce2..540f89a81b 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -5255,6 +5255,110 @@ GasLimitDefault = 400000

    +
    Soneium Sepolia (1946)

    + +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +ChainType = 'optimismBedrock' +FinalityDepth = 200 +FinalityTagEnabled = true +LinkContractAddress = '0x7ea13478Ea3961A0e8b538cb05a9DF0477c79Cd2' +LogBackfillBatchSize = 1000 +LogPollInterval = '2s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 1 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '40s' +LogBroadcasterEnabled = true +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 +FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '2h0m0s' + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '30s' + +[Transactions.AutoPurge] +Enabled = false + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'BlockHistory' +PriceDefault = '20 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '1 wei' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +EstimateLimit = false +BumpMin = '1 mwei' +BumpPercent = 20 +BumpThreshold = 3 +EIP1559DynamicFees = true +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 60 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + +[HeadTracker] +HistoryDepth = 300 +MaxBufferSize = 3 +SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 10 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false +FinalizedBlockPollInterval = '5s' +EnforceRepeatableRead = false +DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' + +[OCR] +ContractConfirmations = 1 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 6500000 + +[Workflow] +GasLimitDefault = 400000 +``` + +

    +
    Kroma Sepolia (2358)

    ```toml From 8905e88fdfea718e40ee89e4ad3d889eb314efe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Tue, 24 Sep 2024 23:16:11 +0900 Subject: [PATCH 421/432] Keystone aptos scripts (#14539) * keystone: scripts: Also fetch the aptos account and OCR2 bundle id * scripts: keystone: Also fetch aptos onchain public key * Added JSON struct tags to NodeKeys * Added dns entries parsing to nodes.txt * Use both evm and aptos keys in the multichain bundle * Aptos support * Aptos: encode the aptos key again * fix lint * this error is already checked previously * Revert change * flip the nodelist format * Passing tests * fix lint --------- Co-authored-by: Damjan Smickovski --- ...deploy_initialize_capabilities_registry.go | 73 +++++++++++++++++++ core/scripts/keystone/src/88_gen_jobspecs.go | 5 +- .../keystone/src/88_gen_ocr3_config.go | 24 ++++-- core/scripts/keystone/src/99_fetch_keys.go | 58 +++++++++++++-- core/scripts/keystone/src/99_nodes.go | 17 +++-- .../__snapshots__/88_gen_jobspecs_test.snap | 4 + .../88_gen_ocr3_config_test.snap | 10 +-- .../keystone/src/testdata/NodeList.txt | 10 +-- .../keystone/src/testdata/PublicKeys.json | 10 +++ core/scripts/keystone/templates/oracle.toml | 1 + .../relay/evm/contract_transmitter.go | 3 - 11 files changed, 177 insertions(+), 38 deletions(-) diff --git a/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go b/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go index 3352267d14..4ff92b6210 100644 --- a/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go +++ b/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go @@ -109,6 +109,29 @@ var ( Signer: "0x1a684B3d8f917fe496b7B1A8b29EDDAED64F649f", }, } + + aptosTargetDonPeers = []peer{ + { + PeerID: "12D3KooWNBr1AD3vD3dzSLgg1tK56qyJoenDx7EYNnZpbr1g4jD6", + Signer: "a41f9a561ff2266d94240996a76f9c2b3b7d8184", + }, + { + PeerID: "12D3KooWRRgWiZGw5GYsPa62CkwFNKJb5u4hWo4DinnvjG6GE6Nj", + Signer: "e4f3c7204776530fb7833db6f9dbfdb8bd0ec96892965324a71c20d6776f67f0", + }, + { + PeerID: "12D3KooWKwzgUHw5YbqUsYUVt3yiLSJcqc8ANofUtqHX6qTm7ox2", + Signer: "4071ea00e2e2c76b3406018ba9f66bf6b9aee3a6762e62ac823b1ee91ba7d7b0", + }, + { + PeerID: "12D3KooWBRux5o2bw1j3SQwEHzCspjkt7Xe3Y3agRUuab2SUnExj", + Signer: "6f5180c7d276876dbe413bf9b0efff7301d1367f39f4bac64180090cab70989b", + }, + { + PeerID: "12D3KooWFqvDaMSDGa6eMSTF9en6G2c3ZbGLmaA5Xs3AgxVBPb8B", + Signer: "dbce9a6df8a04d54e52a109d01ee9b5d32873b1d2436cf7b7fae61fd6eca46f8", + }, + } ) type deployAndInitializeCapabilitiesRegistryCommand struct{} @@ -236,6 +259,16 @@ func (c *deployAndInitializeCapabilitiesRegistryCommand) Run(args []string) { log.Printf("failed to call GetHashedCapabilityId: %s", err) } + aptosWriteChain := kcr.CapabilitiesRegistryCapability{ + LabelledName: "write_aptos", + Version: "1.0.0", + CapabilityType: uint8(3), // target + } + awid, err := reg.GetHashedCapabilityId(&bind.CallOpts{}, aptosWriteChain.LabelledName, aptosWriteChain.Version) + if err != nil { + log.Printf("failed to call GetHashedCapabilityId: %s", err) + } + ocr := kcr.CapabilitiesRegistryCapability{ LabelledName: "offchain_reporting", Version: "1.0.0", @@ -249,6 +282,7 @@ func (c *deployAndInitializeCapabilitiesRegistryCommand) Run(args []string) { tx, err := reg.AddCapabilities(env.Owner, []kcr.CapabilitiesRegistryCapability{ streamsTrigger, writeChain, + aptosWriteChain, ocr, }) if err != nil { @@ -306,6 +340,16 @@ func (c *deployAndInitializeCapabilitiesRegistryCommand) Run(args []string) { nodes = append(nodes, n) } + for _, targetPeer := range aptosTargetDonPeers { + n, innerErr := peerToNode(nopID, targetPeer) + if innerErr != nil { + panic(innerErr) + } + + n.HashedCapabilityIds = [][32]byte{awid} + nodes = append(nodes, n) + } + tx, err = reg.AddNodes(env.Owner, nodes) if err != nil { log.Printf("failed to AddNodes: %s", err) @@ -396,6 +440,35 @@ func (c *deployAndInitializeCapabilitiesRegistryCommand) Run(args []string) { if err != nil { log.Printf("targetDON: failed to AddDON: %s", err) } + + // Aptos target DON + ps, err = peers(aptosTargetDonPeers) + if err != nil { + panic(err) + } + + targetCapabilityConfig = newCapabilityConfig() + targetCapabilityConfig.RemoteConfig = &capabilitiespb.CapabilityConfig_RemoteTargetConfig{ + RemoteTargetConfig: &capabilitiespb.RemoteTargetConfig{ + RequestHashExcludedAttributes: []string{"signed_report.Signatures"}, + }, + } + + remoteTargetConfigBytes, err = proto.Marshal(targetCapabilityConfig) + if err != nil { + panic(err) + } + + cfgs = []kcr.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: awid, + Config: remoteTargetConfigBytes, + }, + } + _, err = reg.AddDON(env.Owner, ps, cfgs, true, false, 1) + if err != nil { + log.Printf("targetDON: failed to AddDON: %s", err) + } } func deployCapabilitiesRegistry(env helpers.Environment) *kcr.CapabilitiesRegistry { diff --git a/core/scripts/keystone/src/88_gen_jobspecs.go b/core/scripts/keystone/src/88_gen_jobspecs.go index 5f0b9097d2..39adcac267 100644 --- a/core/scripts/keystone/src/88_gen_jobspecs.go +++ b/core/scripts/keystone/src/88_gen_jobspecs.go @@ -39,7 +39,7 @@ func genSpecs( bootstrapSpecLines, err := readLines(filepath.Join(templatesDir, bootstrapSpecTemplate)) helpers.PanicErr(err) - bootHost := nodes[0].url.Hostname() + bootHost := nodes[0].remoteURL.Hostname() bootstrapSpecLines = replacePlaceholders( bootstrapSpecLines, chainID, p2pPort, @@ -59,7 +59,7 @@ func genSpecs( ocrConfigContractAddress, bootHost, bootstrapNode, nca[i], ) - oracles = append(oracles, hostSpec{oracleSpecLines, nodes[i].url.Host}) + oracles = append(oracles, hostSpec{oracleSpecLines, nodes[i].remoteURL.Host}) } return donHostSpec{ @@ -82,6 +82,7 @@ func replacePlaceholders( l = strings.Replace(l, "{{ ocr_config_contract_address }}", contractAddress, 1) l = strings.Replace(l, "{{ transmitter_id }}", node.EthAddress, 1) l = strings.Replace(l, "{{ ocr_key_bundle_id }}", node.OCR2BundleID, 1) + l = strings.Replace(l, "{{ aptos_key_bundle_id }}", node.AptosBundleID, 1) l = strings.Replace(l, "{{ bootstrapper_p2p_id }}", bootstrapper, 1) output = append(output, l) } diff --git a/core/scripts/keystone/src/88_gen_ocr3_config.go b/core/scripts/keystone/src/88_gen_ocr3_config.go index d9280ffe24..f0a03ecafb 100644 --- a/core/scripts/keystone/src/88_gen_ocr3_config.go +++ b/core/scripts/keystone/src/88_gen_ocr3_config.go @@ -48,13 +48,16 @@ type OracleConfigSource struct { } type NodeKeys struct { - EthAddress string - P2PPeerID string // p2p_ - OCR2BundleID string // used only in job spec - OCR2OnchainPublicKey string // ocr2on_evm_ - OCR2OffchainPublicKey string // ocr2off_evm_ - OCR2ConfigPublicKey string // ocr2cfg_evm_ - CSAPublicKey string + EthAddress string `json:"EthAddress"` + AptosAccount string `json:"AptosAccount"` + AptosBundleID string `json:"AptosBundleID"` + AptosOnchainPublicKey string `json:"AptosOnchainPublicKey"` + P2PPeerID string `json:"P2PPeerID"` // p2p_ + OCR2BundleID string `json:"OCR2BundleID"` // used only in job spec + OCR2OnchainPublicKey string `json:"OCR2OnchainPublicKey"` // ocr2on_evm_ + OCR2OffchainPublicKey string `json:"OCR2OffchainPublicKey"` // ocr2off_evm_ + OCR2ConfigPublicKey string `json:"OCR2ConfigPublicKey"` // ocr2cfg_evm_ + CSAPublicKey string `json:"CSAPublicKey"` } type orc2drOracleConfig struct { @@ -107,8 +110,13 @@ func generateOCR3Config(nodeList string, configFile string, chainID int64, pubKe allPubKeys := map[string]any{} for _, n := range nca { ethPubKey := common.HexToAddress(n.OCR2OnchainPublicKey) + aptosPubKey, err := hex.DecodeString(n.AptosOnchainPublicKey) + if err != nil { + panic(err) + } pubKeys := map[string]types.OnchainPublicKey{ - "evm": ethPubKey[:], + "evm": ethPubKey[:], + "aptos": aptosPubKey, } // validate uniqueness of each individual key for _, key := range pubKeys { diff --git a/core/scripts/keystone/src/99_fetch_keys.go b/core/scripts/keystone/src/99_fetch_keys.go index b115a7bb94..91750f7422 100644 --- a/core/scripts/keystone/src/99_fetch_keys.go +++ b/core/scripts/keystone/src/99_fetch_keys.go @@ -14,6 +14,7 @@ import ( helpers "github.com/smartcontractkit/chainlink/core/scripts/common" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/cmd" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -118,6 +119,19 @@ func mustFetchNodesKeys(chainID int64, nodes []*node) (nca []NodeKeys) { helpers.PanicErr(err) output.Reset() + keysClient := cmd.NewAptosKeysClient(client) + err = keysClient.ListKeys(&cli.Context{ + App: app, + }) + helpers.PanicErr(err) + var aptosKeys []presenters.AptosKeyResource + helpers.PanicErr(json.Unmarshal(output.Bytes(), &aptosKeys)) + if len(aptosKeys) != 1 { + helpers.PanicErr(errors.New("node must have single aptos key")) + } + aptosAccount := aptosKeys[0].Account + output.Reset() + err = client.ListP2PKeys(&cli.Context{ App: app, }) @@ -130,18 +144,20 @@ func mustFetchNodesKeys(chainID int64, nodes []*node) (nca []NodeKeys) { peerID := strings.TrimPrefix(p2pKeys[0].PeerID, "p2p_") output.Reset() + chainType := "evm" + var ocr2Bundles []ocr2Bundle err = client.ListOCR2KeyBundles(&cli.Context{ App: app, }) helpers.PanicErr(err) helpers.PanicErr(json.Unmarshal(output.Bytes(), &ocr2Bundles)) - ocr2BundleIndex := findEvmOCR2Bundle(ocr2Bundles) + ocr2BundleIndex := findOCR2Bundle(ocr2Bundles, chainType) output.Reset() if ocr2BundleIndex == -1 { fmt.Println("WARN: node does not have EVM OCR2 bundle, creating one") fs := flag.NewFlagSet("test", flag.ContinueOnError) - err = fs.Parse([]string{"evm"}) + err = fs.Parse([]string{chainType}) helpers.PanicErr(err) ocr2CreateBundleCtx := cli.NewContext(app, fs, nil) err = client.CreateOCR2KeyBundle(ocr2CreateBundleCtx) @@ -153,12 +169,35 @@ func mustFetchNodesKeys(chainID int64, nodes []*node) (nca []NodeKeys) { }) helpers.PanicErr(err) helpers.PanicErr(json.Unmarshal(output.Bytes(), &ocr2Bundles)) - ocr2BundleIndex = findEvmOCR2Bundle(ocr2Bundles) + ocr2BundleIndex = findOCR2Bundle(ocr2Bundles, chainType) output.Reset() } ocr2Bndl := ocr2Bundles[ocr2BundleIndex] + aptosBundleIndex := findOCR2Bundle(ocr2Bundles, "aptos") + if aptosBundleIndex == -1 { + chainType2 := "aptos" + fmt.Println("WARN: node does not have Aptos OCR2 bundle, creating one") + fs := flag.NewFlagSet("test", flag.ContinueOnError) + err = fs.Parse([]string{chainType2}) + helpers.PanicErr(err) + ocr2CreateBundleCtx := cli.NewContext(app, fs, nil) + err = client.CreateOCR2KeyBundle(ocr2CreateBundleCtx) + helpers.PanicErr(err) + output.Reset() + + err = client.ListOCR2KeyBundles(&cli.Context{ + App: app, + }) + helpers.PanicErr(err) + helpers.PanicErr(json.Unmarshal(output.Bytes(), &ocr2Bundles)) + aptosBundleIndex = findOCR2Bundle(ocr2Bundles, chainType2) + output.Reset() + } + + aptosBundle := ocr2Bundles[aptosBundleIndex] + err = client.ListCSAKeys(&cli.Context{ App: app, }) @@ -171,11 +210,14 @@ func mustFetchNodesKeys(chainID int64, nodes []*node) (nca []NodeKeys) { nc := NodeKeys{ EthAddress: ethAddress, + AptosAccount: aptosAccount, P2PPeerID: peerID, + AptosBundleID: aptosBundle.ID, + AptosOnchainPublicKey: strings.TrimPrefix(aptosBundle.OnchainPublicKey, fmt.Sprintf("ocr2on_%s_", "aptos")), OCR2BundleID: ocr2Bndl.ID, - OCR2ConfigPublicKey: strings.TrimPrefix(ocr2Bndl.ConfigPublicKey, "ocr2cfg_evm_"), - OCR2OnchainPublicKey: strings.TrimPrefix(ocr2Bndl.OnchainPublicKey, "ocr2on_evm_"), - OCR2OffchainPublicKey: strings.TrimPrefix(ocr2Bndl.OffchainPublicKey, "ocr2off_evm_"), + OCR2ConfigPublicKey: strings.TrimPrefix(ocr2Bndl.ConfigPublicKey, fmt.Sprintf("ocr2cfg_%s_", chainType)), + OCR2OnchainPublicKey: strings.TrimPrefix(ocr2Bndl.OnchainPublicKey, fmt.Sprintf("ocr2on_%s_", chainType)), + OCR2OffchainPublicKey: strings.TrimPrefix(ocr2Bndl.OffchainPublicKey, fmt.Sprintf("ocr2off_%s_", chainType)), CSAPublicKey: csaPubKey, } @@ -191,9 +233,9 @@ func findFirstCSAPublicKey(csaKeyResources []presenters.CSAKeyResource) (string, return "", errors.New("did not find any CSA Key Resources") } -func findEvmOCR2Bundle(ocr2Bundles []ocr2Bundle) int { +func findOCR2Bundle(ocr2Bundles []ocr2Bundle, chainType string) int { for i, b := range ocr2Bundles { - if b.ChainType == "evm" { + if b.ChainType == chainType { return i } } diff --git a/core/scripts/keystone/src/99_nodes.go b/core/scripts/keystone/src/99_nodes.go index 961d58c4b1..68d3621ce6 100644 --- a/core/scripts/keystone/src/99_nodes.go +++ b/core/scripts/keystone/src/99_nodes.go @@ -10,9 +10,10 @@ import ( ) type node struct { - url *url.URL - login string - password string + url *url.URL + remoteURL *url.URL + login string + password string } func (n node) IsTerminal() bool { @@ -50,7 +51,7 @@ func mustReadNodesList(path string) []*node { continue } s := strings.Split(rr, " ") - if len(s) != 3 { + if len(s) != 4 { helpers.PanicErr(errors.New("wrong nodes list format")) } if strings.Contains(s[0], "boot") && hasBoot { @@ -58,11 +59,13 @@ func mustReadNodesList(path string) []*node { } hasBoot = true url, err := url.Parse(s[0]) + remoteURL, err := url.Parse(s[1]) helpers.PanicErr(err) nodes = append(nodes, &node{ - url: url, - login: s[1], - password: s[2], + url: url, + remoteURL: remoteURL, + login: s[2], + password: s[3], }) } return nodes diff --git a/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap b/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap index b21c1549db..c0c7c7d7e6 100755 --- a/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap +++ b/core/scripts/keystone/src/__snapshots__/88_gen_jobspecs_test.snap @@ -41,6 +41,7 @@ telemetryType = "plugin" strategyName = 'multi-chain' [onchainSigningStrategy.config] evm = "b3df4d8748b67731a1112e8b45a764941974f5590c93672eebbc4f3504dd10ed" +aptos = "9bebfa953e7a7522746f72b4023308de36db626f3e0bcb9033407b8a183e8bfb" -------------------------------- Oracle 1: @@ -71,6 +72,7 @@ telemetryType = "plugin" strategyName = 'multi-chain' [onchainSigningStrategy.config] evm = "38459ae37f29f2c1fde0f25972a973322be8cada82acf43f464756836725be97" +aptos = "9bebfa953e7a7522746f72b4023308de36db626f3e0bcb9033407b8a183e8bfc" -------------------------------- Oracle 2: @@ -101,6 +103,7 @@ telemetryType = "plugin" strategyName = 'multi-chain' [onchainSigningStrategy.config] evm = "b5dbc4c9da983cddde2e3226b85807eb7beaf818694a22576af4d80f352702ed" +aptos = "9bebfa953e7a7522746f72b4023308de36db626f3e0bcb9033407b8a183e8bfd" -------------------------------- Oracle 3: @@ -131,6 +134,7 @@ telemetryType = "plugin" strategyName = 'multi-chain' [onchainSigningStrategy.config] evm = "260d5c1a618cdf5324509d7db95f5a117511864ebb9e1f709e8969339eb225af" +aptos = "9bebfa953e7a7522746f72b4023308de36db626f3e0bcb9033407b8a183e8bfe" --- diff --git a/core/scripts/keystone/src/__snapshots__/88_gen_ocr3_config_test.snap b/core/scripts/keystone/src/__snapshots__/88_gen_ocr3_config_test.snap index b9581afb88..eac3cdaff4 100755 --- a/core/scripts/keystone/src/__snapshots__/88_gen_ocr3_config_test.snap +++ b/core/scripts/keystone/src/__snapshots__/88_gen_ocr3_config_test.snap @@ -6,11 +6,11 @@ "OffchainConfigVersion": 30, "OnchainConfig": "0x", "Signers": [ - "011400a2402db8e549f094ea31e1c0edd77623f4ca5b12", - "0114004af19c802b244d1d085492c3946391c965e10519", - "01140061925685d2b80b121537341d063c4e57b2f9323c", - "011400fd97efd53fc20acc098fcd746c04d8d7540d97e0", - "011400a0b67dc5345a71d02b396147ae2cb75dda63cbe9" + "011400a2402db8e549f094ea31e1c0edd77623f4ca5b12052000ea551e503b93a1c9ae26262b4db8f66db4cbe5ddcb6039e29d2665a634d48e4a", + "0114004af19c802b244d1d085492c3946391c965e10519052000ea551e503b93a1c9ae26262b4db8f66db4cbe5ddcb6039e29d2665a634d48e4b", + "01140061925685d2b80b121537341d063c4e57b2f9323c052000ea551e503b93a1c9ae26262b4db8f66db4cbe5ddcb6039e29d2665a634d48e4c", + "011400fd97efd53fc20acc098fcd746c04d8d7540d97e0052000ea551e503b93a1c9ae26262b4db8f66db4cbe5ddcb6039e29d2665a634d48e4d", + "011400a0b67dc5345a71d02b396147ae2cb75dda63cbe9052000ea551e503b93a1c9ae26262b4db8f66db4cbe5ddcb6039e29d2665a634d48e4e" ], "Transmitters": [ "0xF4e7e516146c8567F8E8be0ED1f1A92798628d35", diff --git a/core/scripts/keystone/src/testdata/NodeList.txt b/core/scripts/keystone/src/testdata/NodeList.txt index 9a895e0f3f..6fb65dded6 100644 --- a/core/scripts/keystone/src/testdata/NodeList.txt +++ b/core/scripts/keystone/src/testdata/NodeList.txt @@ -1,5 +1,5 @@ -https://crib-henry-keystone-node1.main.stage.cldev.sh notreal@fakeemail.ch fj293fbBnlQ!f9vNs -https://crib-henry-keystone-node2.main.stage.cldev.sh notreal@fakeemail.ch fj293fbBnlQ!f9vNs -https://crib-henry-keystone-node3.main.stage.cldev.sh notreal@fakeemail.ch fj293fbBnlQ!f9vNs -https://crib-henry-keystone-node4.main.stage.cldev.sh notreal@fakeemail.ch fj293fbBnlQ!f9vNs -https://crib-henry-keystone-node5.main.stage.cldev.sh notreal@fakeemail.ch fj293fbBnlQ!f9vNs +https://local-node1 https://crib-henry-keystone-node1.main.stage.cldev.sh notreal@fakeemail.ch fj293fbBnlQ!f9vNs +https://local-node2 https://crib-henry-keystone-node2.main.stage.cldev.sh notreal@fakeemail.ch fj293fbBnlQ!f9vNs +https://local-node3 https://crib-henry-keystone-node3.main.stage.cldev.sh notreal@fakeemail.ch fj293fbBnlQ!f9vNs +https://local-node4 https://crib-henry-keystone-node4.main.stage.cldev.sh notreal@fakeemail.ch fj293fbBnlQ!f9vNs +https://local-node5 https://crib-henry-keystone-node5.main.stage.cldev.sh notreal@fakeemail.ch fj293fbBnlQ!f9vNs diff --git a/core/scripts/keystone/src/testdata/PublicKeys.json b/core/scripts/keystone/src/testdata/PublicKeys.json index 7ade3d45ad..b29e829089 100644 --- a/core/scripts/keystone/src/testdata/PublicKeys.json +++ b/core/scripts/keystone/src/testdata/PublicKeys.json @@ -1,5 +1,7 @@ [ { + "AptosBundleID": "9bebfa953e7a7522746f72b4023308de36db626f3e0bcb9033407b8a183e8bfa", + "AptosOnchainPublicKey": "ea551e503b93a1c9ae26262b4db8f66db4cbe5ddcb6039e29d2665a634d48e4a", "EthAddress": "0xF4e7e516146c8567F8E8be0ED1f1A92798628d35", "P2PPeerID": "12D3KooWNmhKZL1XW4Vv3rNjLXzJ6mqcVerihdijjGYuexPrFUFZ", "OCR2BundleID": "2f92c96da20fbe39c89e59516e3a7473254523316887394e406527c72071d3db", @@ -9,6 +11,8 @@ "CSAPublicKey": "csa_dbae6965bad0b0fa95ecc34a602eee1c0c570ddc29b56502e400d18574b8c3df" }, { + "AptosBundleID": "9bebfa953e7a7522746f72b4023308de36db626f3e0bcb9033407b8a183e8bfb", + "AptosOnchainPublicKey": "ea551e503b93a1c9ae26262b4db8f66db4cbe5ddcb6039e29d2665a634d48e4b", "EthAddress": "0x8B60FDcc9CAC8ea476b31d17011CB204471431d9", "P2PPeerID": "12D3KooWFUjV73ZYkAMhS2cVwte3kXDWD8Ybyx3u9CEDHNoeEhBH", "OCR2BundleID": "b3df4d8748b67731a1112e8b45a764941974f5590c93672eebbc4f3504dd10ed", @@ -18,6 +22,8 @@ "CSAPublicKey": "csa_c5cc655a9c19b69626519c4a72c44a94a3675daeba9c16cc23e010a7a6dac1be" }, { + "AptosBundleID": "9bebfa953e7a7522746f72b4023308de36db626f3e0bcb9033407b8a183e8bfc", + "AptosOnchainPublicKey": "ea551e503b93a1c9ae26262b4db8f66db4cbe5ddcb6039e29d2665a634d48e4c", "EthAddress": "0x6620F516F29979B214e2451498a057FDd3a0A85d", "P2PPeerID": "12D3KooWRTtH2WWrztD87Do1kXePSmGjyU4r7mZVWThmqTGgdbUC", "OCR2BundleID": "38459ae37f29f2c1fde0f25972a973322be8cada82acf43f464756836725be97", @@ -27,6 +33,8 @@ "CSAPublicKey": "csa_7407fc90c70895c0fb2bdf385e2e4918364bec1f7a74bad7fdf696bffafbcab8" }, { + "AptosBundleID": "9bebfa953e7a7522746f72b4023308de36db626f3e0bcb9033407b8a183e8bfd", + "AptosOnchainPublicKey": "ea551e503b93a1c9ae26262b4db8f66db4cbe5ddcb6039e29d2665a634d48e4d", "EthAddress": "0xFeB61E22FCf4F9740c9D96b05199F195bd61A7c2", "P2PPeerID": "12D3KooWMTZnZtcVK4EJsjkKsV9qXNoNRSjT62CZi3tKkXGaCsGh", "OCR2BundleID": "b5dbc4c9da983cddde2e3226b85807eb7beaf818694a22576af4d80f352702ed", @@ -36,6 +44,8 @@ "CSAPublicKey": "csa_ef55caf17eefc2a9d547b5a3978d396bd237c73af99cd849a4758701122e3cba" }, { + "AptosBundleID": "9bebfa953e7a7522746f72b4023308de36db626f3e0bcb9033407b8a183e8bfe", + "AptosOnchainPublicKey": "ea551e503b93a1c9ae26262b4db8f66db4cbe5ddcb6039e29d2665a634d48e4e", "EthAddress": "0x882Fd04D78A7e7D386Dd5b550f19479E5494B0B2", "P2PPeerID": "12D3KooWRsM9yordRQDhLgbErH8WMMGz1bC1J4hR5gAGvMWu8goN", "OCR2BundleID": "260d5c1a618cdf5324509d7db95f5a117511864ebb9e1f709e8969339eb225af", diff --git a/core/scripts/keystone/templates/oracle.toml b/core/scripts/keystone/templates/oracle.toml index c45e0fcb60..053baa2223 100644 --- a/core/scripts/keystone/templates/oracle.toml +++ b/core/scripts/keystone/templates/oracle.toml @@ -24,3 +24,4 @@ telemetryType = "plugin" strategyName = 'multi-chain' [onchainSigningStrategy.config] evm = "{{ ocr_key_bundle_id }}" +aptos = "{{ aptos_key_bundle_id }}" diff --git a/core/services/relay/evm/contract_transmitter.go b/core/services/relay/evm/contract_transmitter.go index e2065bc60f..10ab4697df 100644 --- a/core/services/relay/evm/contract_transmitter.go +++ b/core/services/relay/evm/contract_transmitter.go @@ -215,9 +215,6 @@ func (oc *contractTransmitter) LatestConfigDigestAndEpoch(ctx context.Context) ( } // Otherwise, we have to scan for the logs. - if err != nil { - return ocrtypes.ConfigDigest{}, 0, err - } latest, err := oc.lp.LatestLogByEventSigWithConfs(ctx, oc.transmittedEventSig, oc.contractAddress, 1) if err != nil { if errors.Is(err, sql.ErrNoRows) { From d9894d129d12204bdb14dcb0a7ce42fd19205a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Friedemann=20F=C3=BCrst?= <59653747+friedemannf@users.noreply.github.com> Date: Tue, 24 Sep 2024 16:47:38 +0200 Subject: [PATCH 422/432] Add Zircuit Configs (#14541) * Add Zircuit Configs * Add Changeset * Update changeset --- .changeset/khaki-tigers-agree.md | 5 + .../config/toml/defaults/Zircuit_Mainnet.toml | 36 +++ .../config/toml/defaults/Zircuit_Sepolia.toml | 36 +++ docs/CONFIG.md | 212 ++++++++++++++++++ 4 files changed, 289 insertions(+) create mode 100644 .changeset/khaki-tigers-agree.md create mode 100644 core/chains/evm/config/toml/defaults/Zircuit_Mainnet.toml create mode 100644 core/chains/evm/config/toml/defaults/Zircuit_Sepolia.toml diff --git a/.changeset/khaki-tigers-agree.md b/.changeset/khaki-tigers-agree.md new file mode 100644 index 0000000000..ba9e56cc1d --- /dev/null +++ b/.changeset/khaki-tigers-agree.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added #nops Add Zircuit Configs diff --git a/core/chains/evm/config/toml/defaults/Zircuit_Mainnet.toml b/core/chains/evm/config/toml/defaults/Zircuit_Mainnet.toml new file mode 100644 index 0000000000..ec336d3efe --- /dev/null +++ b/core/chains/evm/config/toml/defaults/Zircuit_Mainnet.toml @@ -0,0 +1,36 @@ +ChainID = '48900' +ChainType = 'optimismBedrock' +FinalityTagEnabled = true +FinalityDepth = 1000 +LinkContractAddress = '0x5D6d033B4FbD2190D99D930719fAbAcB64d2439a' +LogPollInterval = "2s" +NoNewHeadsThreshold = "40s" +NoNewFinalizedHeadsThreshold = "15m" + +[GasEstimator] +EIP1559DynamicFees = true +PriceMin = '1 wei' +BumpMin = '100 wei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[Transactions] +ResendAfterThreshold = '30s' + +[HeadTracker] +HistoryDepth = 2000 + +[NodePool] +SyncThreshold = 10 + +[OCR] +ContractConfirmations = 1 + +[OCR2.Automation] +GasLimit = 6500000 + +[Transactions.AutoPurge] +Enabled = true +Threshold = 90 # 90 blocks at 2s block time ~3 minutes +MinAttempts = 3 \ No newline at end of file diff --git a/core/chains/evm/config/toml/defaults/Zircuit_Sepolia.toml b/core/chains/evm/config/toml/defaults/Zircuit_Sepolia.toml new file mode 100644 index 0000000000..d6934d533d --- /dev/null +++ b/core/chains/evm/config/toml/defaults/Zircuit_Sepolia.toml @@ -0,0 +1,36 @@ +ChainID = '48899' +ChainType = 'optimismBedrock' +FinalityTagEnabled = true +FinalityDepth = 1000 +LinkContractAddress = '0xDEE94506570cA186BC1e3516fCf4fd719C312cCD' +LogPollInterval = "2s" +NoNewHeadsThreshold = "40s" +NoNewFinalizedHeadsThreshold = "15m" + +[GasEstimator] +EIP1559DynamicFees = true +PriceMin = '1 wei' +BumpMin = '100 wei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 60 + +[Transactions] +ResendAfterThreshold = '30s' + +[HeadTracker] +HistoryDepth = 2000 + +[NodePool] +SyncThreshold = 10 + +[OCR] +ContractConfirmations = 1 + +[OCR2.Automation] +GasLimit = 6500000 + +[Transactions.AutoPurge] +Enabled = true +Threshold = 90 # 90 blocks at 2s block time ~3 minutes +MinAttempts = 3 \ No newline at end of file diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 540f89a81b..628692f7c3 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -6700,6 +6700,218 @@ GasLimitDefault = 400000

    +
    Zircuit Sepolia (48899)

    + +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +ChainType = 'optimismBedrock' +FinalityDepth = 1000 +FinalityTagEnabled = true +LinkContractAddress = '0xDEE94506570cA186BC1e3516fCf4fd719C312cCD' +LogBackfillBatchSize = 1000 +LogPollInterval = '2s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 3 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '40s' +LogBroadcasterEnabled = true +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 +FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '15m0s' + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '30s' + +[Transactions.AutoPurge] +Enabled = true +Threshold = 90 +MinAttempts = 3 + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'BlockHistory' +PriceDefault = '20 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '1 wei' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +EstimateLimit = false +BumpMin = '100 wei' +BumpPercent = 20 +BumpThreshold = 3 +EIP1559DynamicFees = true +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 60 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + +[HeadTracker] +HistoryDepth = 2000 +MaxBufferSize = 3 +SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 10 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false +FinalizedBlockPollInterval = '5s' +EnforceRepeatableRead = false +DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' + +[OCR] +ContractConfirmations = 1 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 6500000 + +[Workflow] +GasLimitDefault = 400000 +``` + +

    + +
    Zircuit Mainnet (48900)

    + +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +ChainType = 'optimismBedrock' +FinalityDepth = 1000 +FinalityTagEnabled = true +LinkContractAddress = '0x5D6d033B4FbD2190D99D930719fAbAcB64d2439a' +LogBackfillBatchSize = 1000 +LogPollInterval = '2s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 3 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '40s' +LogBroadcasterEnabled = true +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 +FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '15m0s' + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '30s' + +[Transactions.AutoPurge] +Enabled = true +Threshold = 90 +MinAttempts = 3 + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'BlockHistory' +PriceDefault = '20 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '1 wei' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +EstimateLimit = false +BumpMin = '100 wei' +BumpPercent = 20 +BumpThreshold = 3 +EIP1559DynamicFees = true +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 24 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + +[HeadTracker] +HistoryDepth = 2000 +MaxBufferSize = 3 +SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 10 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false +FinalizedBlockPollInterval = '5s' +EnforceRepeatableRead = false +DeathDeclarationDelay = '10s' +NewHeadsPollInterval = '0s' + +[OCR] +ContractConfirmations = 1 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 6500000 + +[Workflow] +GasLimitDefault = 400000 +``` + +

    +
    Linea Goerli (59140)

    ```toml From 295f8c7b3e906d0b8cebf54f434103f6b20071f2 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Tue, 24 Sep 2024 10:56:50 -0400 Subject: [PATCH 423/432] Fix CCIP Load Test (#14525) * Add ccip-load to default suites * DEBUG * Add docker image debugging * Build test debugging * Add TEST_SUITE * Remove debug --- .github/e2e-tests.yml | 1 + .github/workflows/run-e2e-tests-reusable-workflow.yml | 2 +- integration-tests/scripts/buildTests | 1 + integration-tests/scripts/entrypoint | 5 +++++ integration-tests/test.Dockerfile | 4 +++- 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index d5c257de8f..c3678837db 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -1101,6 +1101,7 @@ runner-test-matrix: runs_on: ubuntu-latest test_cmd: cd integration-tests/ccip-tests/load && DETACH_RUNNER=false go test -test.run ^TestLoadCCIPStableRPS$ -timeout 70m -count=1 -test.parallel=1 -json test_env_vars: + TEST_SUITE: ccip-load E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" workflows: - E2E CCIP Load Tests diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml index 0de9c7d942..8f0fd54e37 100644 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ b/.github/workflows/run-e2e-tests-reusable-workflow.yml @@ -67,7 +67,7 @@ on: description: 'Suites to build in the test image. Space separated' required: false type: string - default: chaos migration reorg smoke soak benchmark load + default: chaos migration reorg smoke soak benchmark load ccip-load require_chainlink_image_versions_in_qa_ecr: description: 'Check Chainlink image versions to be present in QA ECR. If not, build and push the image to QA ECR. Takes comma separated list of Chainlink image versions. Example: "5733cdcda9a9fc6da6343798b119b2ae136146cd,0b7d2c497a508efa5a827714780d908b7b8eda19"' required: false diff --git a/integration-tests/scripts/buildTests b/integration-tests/scripts/buildTests index b5e8fc3080..7be2d0c5a7 100755 --- a/integration-tests/scripts/buildTests +++ b/integration-tests/scripts/buildTests @@ -33,5 +33,6 @@ do else go test -c -tags embed ./"${x}" fi + echo "Built ${x}.test" done IFS=$OIFS diff --git a/integration-tests/scripts/entrypoint b/integration-tests/scripts/entrypoint index d4ebe722a1..dc4ff1d0db 100755 --- a/integration-tests/scripts/entrypoint +++ b/integration-tests/scripts/entrypoint @@ -14,6 +14,11 @@ cd "$SCRIPT_DIR"/../ || exit 1 # SUITE=${SUITE:=} the suite of tests you want to run # TEST_NAME=${TEST_NAME:=} The specific test to run +if [ -z "${SUITE}" ]; then + echo "SUITE is not set. You likely need to set the TEST_SUITE env var in your workflow. Exiting." + exit 1 +fi + # run the tests ./${SUITE}.test -test.v -test.count 1 ${ARGS} -test.run ^${TEST_NAME}$ diff --git a/integration-tests/test.Dockerfile b/integration-tests/test.Dockerfile index 41fe331583..42e7de67c9 100644 --- a/integration-tests/test.Dockerfile +++ b/integration-tests/test.Dockerfile @@ -2,7 +2,7 @@ ARG BASE_IMAGE ARG IMAGE_VERSION=latest FROM ${BASE_IMAGE}:${IMAGE_VERSION} AS build-env -ARG SUITES=chaos migration performance reorg smoke soak benchmark +ARG SUITES=chaos migration performance reorg smoke soak benchmark load ccip-load COPY . testdir/ WORKDIR /go/testdir @@ -15,5 +15,7 @@ COPY --from=build-env /go/pkg /go/pkg COPY --from=build-env /go/testdir/integration-tests/*.test /go/testdir/integration-tests/ COPY --from=build-env /go/testdir/integration-tests/ccip-tests/*.test /go/testdir/integration-tests/ COPY --from=build-env /go/testdir/integration-tests/scripts /go/testdir/integration-tests/scripts/ +RUN echo "All tests" +RUN ls -l /go/testdir/integration-tests/*.test ENTRYPOINT ["/go/testdir/integration-tests/scripts/entrypoint"] From ae4101883032d775d09557d3181ae2a435a2a3b6 Mon Sep 17 00:00:00 2001 From: momentmaker Date: Tue, 24 Sep 2024 10:55:01 -0500 Subject: [PATCH 424/432] release 2.16.0 to develop (#14544) * Bump version and update CHANGELOG fore core v2.16.0 Signed-off-by: chainchad <96362174+chainchad@users.noreply.github.com> * Update EstimateGasLimit config name to EstimateLimit (#14297) * Updated EstimateGasLimit config name to EstimateLimit * Updated mocks * Fixed linting * Updated changeset * fix: goreleaser-build-sign-publish-chainlink workflow (#14139) * remove other gha workflows and test build-publish workflow * update cosigner gha and version * add env GORELEASER_KEY * add GITHUB_TOKEN env * temp add current_tag env * add --skip=validate temp * remove prev * skip release * use disable instead * fix post release publish bug * use keyless signing * revert and comment stdin * comment all cosign user/pass * add args to docker_signs * remove cosign user/pass env and uncomment other workflow * update cosign to keyless for regular docker build images * use keyless input and temp remove slack-notify * use image digest for signing * use --yes flag in cosign sign and update cosign-installer version * add --yes flag to cosign verify * fix typo and remove --yes * refactor to remove cosign keypair way and only use keyless signing * revert back deleted gha workflow files * refactor with suggestions * fix set env step * fix typos and naming * core/services/relay/evm: handle error from chainselectors * Fix pruning query * Add regression testing for pruning bug * Query exact wasmvm module rather than parsing all (#14425) * exclude sourcegraph missing dependency (#14446) * exclude sourcegrapht * use replace * finalize date on changelog for 2.16.0 * fix merge issues * another --------- Signed-off-by: chainchad <96362174+chainchad@users.noreply.github.com> Co-authored-by: chainchad <96362174+chainchad@users.noreply.github.com> Co-authored-by: amit-momin <108959691+amit-momin@users.noreply.github.com> Co-authored-by: Jordan Krage Co-authored-by: Domino Valdano <2644901+reductionista@users.noreply.github.com> Co-authored-by: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Co-authored-by: Sergey Kudasov --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3130723e9..395b95e63f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog Chainlink Core -## 2.16.0 - UNRELEASED +## 2.16.0 - 2024-09-23 ### Minor Changes @@ -30,7 +30,7 @@ - [#13638](https://github.com/smartcontractkit/chainlink/pull/13638) [`2312827156`](https://github.com/smartcontractkit/chainlink/commit/2312827156f24fa4a6e420aec12e5a3aeac81e2b) Thanks [@amit-momin](https://github.com/amit-momin)! - Introduced finalized transaction state. Added a finalizer component to the TXM to mark transactions as finalized. #internal -- [#14041](https://github.com/smartcontractkit/chainlink/pull/14041) [`8d818ea265`](https://github.com/smartcontractkit/chainlink/commit/8d818ea265ff08887e61ace4f83364a3ee149ef0) Thanks [@amit-momin](https://github.com/amit-momin)! - Added gas limit estimation feature to EVM gas estimators #added +- [#14041](https://github.com/smartcontractkit/chainlink/pull/14041) [`8d818ea265`](https://github.com/smartcontractkit/chainlink/commit/8d818ea265ff08887e61ace4f83364a3ee149ef0) Thanks [@amit-momin](https://github.com/amit-momin)! - Added gas limit estimation feature to EVM gas estimators. Introduced a new config `EVM.GasEstimator.EstimateLimit` to toggle this feature. #added - [#14165](https://github.com/smartcontractkit/chainlink/pull/14165) [`e76463cfa9`](https://github.com/smartcontractkit/chainlink/commit/e76463cfa9a0fbe6e35a74cbb3f7d63c85efcd88) Thanks [@silaslenihan](https://github.com/silaslenihan)! - #internal Add hexutil Bytes encoding to batchcall data From 8854deff98b5ab09aff399ca87a4be4740cc885f Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Tue, 24 Sep 2024 19:12:24 +0200 Subject: [PATCH 425/432] Update workflows for E2E tests (#14540) * Rename workflows to triggers in E2E test workflows * Use test_path * Use workflow from .github * Bump CTF * Fix workflow reference * bump * Use reusable workflow everywhere * Update readme * bump workflow * Remove workflow that is now in .github repo * bump workflow --- .github/E2E_TESTS_ON_GITHUB_CI.md | 85 +- .github/e2e-tests.yml | 176 +-- .../workflows/automation-benchmark-tests.yml | 3 +- .github/workflows/automation-load-tests.yml | 3 +- .../workflows/automation-nightly-tests.yml | 5 +- .../workflows/automation-ondemand-tests.yml | 3 +- .github/workflows/ccip-chaos-tests.yml | 5 +- .github/workflows/ccip-load-tests.yml | 5 +- .github/workflows/integration-chaos-tests.yml | 5 +- .github/workflows/integration-tests.yml | 20 +- .github/workflows/on-demand-ocr-soak-test.yml | 3 +- .../on-demand-vrfv2-performance-test.yml | 2 +- .../workflows/on-demand-vrfv2-smoke-tests.yml | 2 +- .../on-demand-vrfv2plus-performance-test.yml | 2 +- .../on-demand-vrfv2plus-smoke-tests.yml | 2 +- .../run-e2e-tests-reusable-workflow.yml | 998 ------------------ .github/workflows/run-nightly-e2e-tests.yml | 5 +- .github/workflows/run-selected-e2e-tests.yml | 10 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 22 files changed, 137 insertions(+), 1209 deletions(-) delete mode 100644 .github/workflows/run-e2e-tests-reusable-workflow.yml diff --git a/.github/E2E_TESTS_ON_GITHUB_CI.md b/.github/E2E_TESTS_ON_GITHUB_CI.md index 572e0070a0..02144eff64 100644 --- a/.github/E2E_TESTS_ON_GITHUB_CI.md +++ b/.github/E2E_TESTS_ON_GITHUB_CI.md @@ -53,87 +53,6 @@ For security reasons, test secrets and sensitive information are not stored dire If you need to run a GitHub workflow using custom secrets, please refer to the [guide on running GitHub workflows with your test secrets](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/lib/config/README.md#run-github-workflow-with-your-test-secrets). -## About the Reusable Workflow +## About the E2E Test Reusable Workflow -The [E2E Tests Reusable Workflow](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/run-e2e-tests-reusable-workflow.yml) is designed to run any type of E2E test on GitHub CI, including docker/testcontainers, old K8s tests, or tests in CRIB in the future. - -Our goal is to migrate all workflows to use this reusable workflow for executing E2E tests. This approach will streamline our CI and allow for the automatic execution of tests at different stages of the software development process. Learn more about the advantages of using reusable workflows [here](https://smartcontract-it.atlassian.net/wiki/spaces/TT/pages/815497220/CI+Workflows+for+E2E+Tests). - -**Examples of Workflows Utilizing the Reusable Workflow:** - -- [Integration Tests](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/integration-tests.yml) -- [Nightly E2E Tests](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/run-nightly-e2e-tests.yml) -- [Selected E2E Tests](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/run-selected-e2e-tests.yml) -- [On-Demand Automation Tests](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/automation-ondemand-tests.yml) -- [CCIP Chaos Tests](https://github.com/smartcontractkit/chainlink/blob/develop/.github/workflows/ccip-chaos-tests.yml) - -### E2E Test Configuration on GitHub CI - -The [e2e-tests.yml](https://github.com/smartcontractkit/chainlink/blob/develop/.github/e2e-tests.yml) file lists all E2E tests configured for execution on CI. Each entry specifies the type of GitHub Runner needed and the workflows in which the test is included (for example, `smoke/ocr_test.go:*` is executed both in PRs and nightly). - -### Slack Notification After Tests - -To configure Slack notifications after tests executed via the reusable workflow, follow these steps: - -- Set `slack_notification_after_tests` to either `always` or `on_failure` depending on when you want notifications to be sent. -- Assign `slack_notification_after_tests_channel_id` to the ID of the Slack channel where notifications should be sent. -- Provide a title for the notification by setting `slack_notification_after_tests_name`. -- Optionally use `slack_notification_after_tests_notify_user_id_on_failure` to reply in the thread and notify a user about the failed workflow - -**Example:** - -```yml -jobs: - call-run-e2e-tests-workflow: - name: Run E2E Tests - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml - with: - chainlink_version: develop - test_workflow: Nightly E2E Tests - slack_notification_after_tests: true - slack_notification_after_tests_channel_id: "#team-test-tooling-internal" - slack_notification_after_tests_name: Nightly E2E Tests - slack_notification_after_tests_notify_user_id_on_failure: U0XXXXXXX -``` - -## Guides - -### How to Run Selected Tests on GitHub CI - -The [Run Selected E2E Tests Workflow](https://github.com/smartcontractkit/chainlink/actions/workflows/run-selected-e2e-tests.yml) allows you to execute specific E2E tests as defined in the [e2e-tests.yml](https://github.com/smartcontractkit/chainlink/blob/develop/.github/e2e-tests.yml). This is useful for various purposes such as testing specific features on a particular branch or verifying that modifications to a test have not introduced any issues. - -For details on all available inputs that the workflow supports, refer to the [workflow definition](https://github.com/smartcontractkit/chainlink/actions/workflows/run-selected-e2e-tests.yml). - -**Example Usage:** - -To run a set of VRFv2Plus tests from a custom branch, use the following command: - -```bash -gh workflow run run-selected-e2e-tests.yml \ --f test_ids="TestVRFv2Plus_LinkBilling,TestVRFv2Plus_NativeBilling,TestVRFv2Plus_DirectFunding,TestVRFV2PlusWithBHS" \ --f chainlink_version=develop \ ---ref TT-1550-Provide-PoC-for-keeping-test-configs-in-git -``` - -### How to Run Custom Tests with Reusable Workflow - -To run a specific list of tests, utilize the `custom_test_list_json` input. This allows you to provide a customized list of tests. If your test list is dynamic, you can generate it during a preceding job and then reference it using: `custom_test_list_json: ${{ needs.gen_test_list.outputs.test_list }}`. - -```yml -run-e2e-tests-workflow: - name: Run E2E Tests - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml - with: - custom_test_list_json: > - { - "tests": [ - { - "id": "TestVRFv2Plus", - "path": "integration-tests/smoke/vrfv2plus_test.go", - "runs_on": "ubuntu-latest", - "test_env_type": "docker", - "test_cmd": "cd integration-tests/smoke && go test vrfv2plus_test.go" - } - ] - } -``` \ No newline at end of file +For information on the E2E Test Reusable Workflow, visit the documentation in the [smartcontractkit/.github repository](https://github.com/smartcontractkit/.github/blob/main/.github/workflows/README.md). diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index c3678837db..4b2e8fe830 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -3,7 +3,7 @@ # Each entry in this file includes the following: # - The GitHub runner (runs_on field) that will execute tests. # - The tests that will be run by the runner. -# - The workflows (e.g., Run PR E2E Tests, Nightly E2E Tests) that should trigger these tests. +# - The triggers (e.g., Run PR E2E Tests, Nightly E2E Tests) that should trigger these tests. # runner-test-matrix: @@ -14,7 +14,7 @@ runner-test-matrix: path: integration-tests/smoke/ocr_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -127,7 +127,7 @@ runner-test-matrix: path: integration-tests/smoke/forwarder_ocr_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -138,7 +138,7 @@ runner-test-matrix: path: integration-tests/smoke/forwarders_ocr2_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -149,7 +149,7 @@ runner-test-matrix: path: integration-tests/smoke/ocr2_test.go test_env_type: docker runs_on: ubuntu22.04-16cores-64GB - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -162,7 +162,7 @@ runner-test-matrix: path: integration-tests/smoke/ocr2_test.go test_env_type: docker runs_on: ubuntu22.04-16cores-64GB - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -176,7 +176,7 @@ runner-test-matrix: path: integration-tests/chaos/ocr_chaos_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - workflows: + triggers: - Automation On Demand Tests - E2E Chaos Tests test_cmd: cd integration-tests/chaos && DETACH_RUNNER=false go test -test.run "^TestOCRChaos$" -v -test.parallel=10 -timeout 60m -count=1 -json @@ -191,7 +191,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -202,7 +202,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -213,7 +213,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -224,7 +224,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -235,7 +235,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -246,7 +246,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -257,7 +257,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -268,7 +268,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -279,7 +279,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -290,7 +290,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -301,7 +301,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -312,7 +312,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -323,7 +323,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -334,7 +334,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -345,7 +345,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -356,7 +356,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -367,7 +367,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -378,7 +378,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperBasicSmoke$ -test.parallel=3 -timeout 30m -count=1 -json @@ -388,7 +388,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperBlockCountPerTurn$ -test.parallel=3 -timeout 30m -count=1 -json @@ -398,7 +398,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperSimulation$ -test.parallel=2 -timeout 30m -count=1 -json @@ -408,7 +408,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperCheckPerformGasLimit$ -test.parallel=2 -timeout 30m -count=1 -json @@ -418,7 +418,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperRegisterUpkeep$ -test.parallel=3 -timeout 30m -count=1 -json @@ -428,7 +428,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperAddFunds$ -test.parallel=3 -timeout 30m -count=1 -json @@ -438,7 +438,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperRemove$ -test.parallel=3 -timeout 30m -count=1 -json @@ -448,7 +448,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperPauseRegistry$ -test.parallel=2 -timeout 30m -count=1 -json @@ -458,7 +458,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperMigrateRegistry$ -test.parallel=1 -timeout 30m -count=1 -json @@ -468,7 +468,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperNodeDown$ -test.parallel=3 -timeout 30m -count=1 -json @@ -478,7 +478,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperPauseUnPauseUpkeep$ -test.parallel=1 -timeout 30m -count=1 -json @@ -488,7 +488,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperUpdateCheckData$ -test.parallel=1 -timeout 30m -count=1 -json @@ -498,7 +498,7 @@ runner-test-matrix: path: integration-tests/smoke/keeper_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperJobReplacement$ -test.parallel=1 -timeout 30m -count=1 -json @@ -520,7 +520,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_upgrade_test.go test_env_type: docker runs_on: ubuntu22.04-8cores-32GB - workflows: + triggers: - Automation Nightly Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationNodeUpgrade/registry_2_0 -test.parallel=1 -timeout 60m -count=1 -json test_env_vars: @@ -534,7 +534,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_upgrade_test.go test_env_type: docker runs_on: ubuntu22.04-8cores-32GB - workflows: + triggers: - Automation Nightly Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationNodeUpgrade/registry_2_1 -test.parallel=5 -timeout 60m -count=1 -json test_env_vars: @@ -548,7 +548,7 @@ runner-test-matrix: path: integration-tests/smoke/automation_upgrade_test.go test_env_type: docker runs_on: ubuntu22.04-8cores-32GB - workflows: + triggers: - Automation Nightly Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationNodeUpgrade/registry_2_2 -test.parallel=5 -timeout 60m -count=1 -json test_env_vars: @@ -564,7 +564,7 @@ runner-test-matrix: test_env_type: docker test_env_vars: TEST_SUITE: reorg - workflows: + triggers: - Automation On Demand Tests test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_0 -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg @@ -575,7 +575,7 @@ runner-test-matrix: test_env_type: docker test_env_vars: TEST_SUITE: reorg - workflows: + triggers: - Automation On Demand Tests test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_1 -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg @@ -586,7 +586,7 @@ runner-test-matrix: test_env_type: docker test_env_vars: TEST_SUITE: reorg - workflows: + triggers: - Automation On Demand Tests test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_2 -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg @@ -597,7 +597,7 @@ runner-test-matrix: test_env_type: docker test_env_vars: TEST_SUITE: reorg - workflows: + triggers: - Automation On Demand Tests test_cmd: cd integration-tests/reorg && DETACH_RUNNER=false go test -v -test.run ^TestAutomationReorg/registry_2_3 -test.parallel=2 -timeout 30m -count=1 -json pyroscope_env: ci-automation-on-demand-reorg @@ -606,7 +606,7 @@ runner-test-matrix: path: integration-tests/chaos/automation_chaos_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - workflows: + triggers: - Automation On Demand Tests - E2E Chaos Tests test_cmd: cd integration-tests/chaos && DETACH_RUNNER=false go test -v -test.run ^TestAutomationChaos$ -test.parallel=20 -timeout 60m -count=1 -json @@ -619,7 +619,7 @@ runner-test-matrix: test_env_type: k8s-remote-runner remote_runner_memory: 4Gi runs_on: ubuntu-latest - # workflows: + # triggers: # - Nightly E2E Tests test_cmd: cd integration-tests/benchmark && go test -v -test.run ^TestAutomationBenchmark$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-benchmark-automation-nightly @@ -633,7 +633,7 @@ runner-test-matrix: test_env_type: k8s-remote-runner remote_runner_memory: 4Gi runs_on: ubuntu-latest - # workflows: + # triggers: # - Nightly E2E Tests test_cmd: cd integration-tests/benchmark && go test -v -test.run ^TestAutomationBenchmark$ -test.parallel=1 -timeout 30m -count=1 -json pyroscope_env: ci-benchmark-automation-nightly @@ -652,7 +652,7 @@ runner-test-matrix: test_env_type: docker test_cmd: cd integration-tests/smoke && go test -v -test.run TestVRFv2Basic -test.parallel=1 -timeout 30m -count=1 -json test_secrets_required: true - workflows: + triggers: - On Demand VRFV2 Smoke Test (Ethereum clients) - id: load/vrfv2plus/vrfv2plus_test.go:^TestVRFV2PlusPerformance$Smoke @@ -664,7 +664,7 @@ runner-test-matrix: test_secrets_required: true test_env_vars: TEST_TYPE: Smoke - workflows: + triggers: - On Demand VRFV2 Plus Performance Test - id: load/vrfv2plus/vrfv2plus_test.go:^TestVRFV2PlusBHSPerformance$Smoke @@ -676,7 +676,7 @@ runner-test-matrix: test_secrets_required: true test_env_vars: TEST_TYPE: Smoke - workflows: + triggers: - On Demand VRFV2 Plus Performance Test - id: load/vrfv2/vrfv2_test.go:^TestVRFV2Performance$Smoke @@ -688,7 +688,7 @@ runner-test-matrix: test_secrets_required: true test_env_vars: TEST_TYPE: Smoke - workflows: + triggers: - On Demand VRFV2 Performance Test - id: load/vrfv2/vrfv2_test.go:^TestVRFV2PlusBHSPerformance$Smoke @@ -700,14 +700,14 @@ runner-test-matrix: test_secrets_required: true test_env_vars: TEST_TYPE: Smoke - workflows: + triggers: - On Demand VRFV2 Performance Test - id: smoke/vrf_test.go:* path: integration-tests/smoke/vrf_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -718,7 +718,7 @@ runner-test-matrix: path: integration-tests/smoke/vrfv2_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -729,7 +729,7 @@ runner-test-matrix: path: integration-tests/smoke/vrfv2plus_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -751,7 +751,7 @@ runner-test-matrix: test_env_type: docker test_cmd: cd integration-tests/smoke && go test -v -test.run "TestVRFv2Plus$/(Link_Billing|Native_Billing|Direct_Funding)|TestVRFV2PlusWithBHS" -test.parallel=1 -timeout 2h -count=1 -json test_config_override_path: integration-tests/testconfig/vrfv2plus/overrides/new_env/sepolia_new_env_test_config.toml - workflows: + triggers: - VRF E2E Release Tests # END: VRF tests @@ -762,7 +762,7 @@ runner-test-matrix: path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -773,7 +773,7 @@ runner-test-matrix: path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -784,7 +784,7 @@ runner-test-matrix: path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -795,7 +795,7 @@ runner-test-matrix: path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -806,7 +806,7 @@ runner-test-matrix: path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -817,7 +817,7 @@ runner-test-matrix: path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -828,7 +828,7 @@ runner-test-matrix: path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -839,7 +839,7 @@ runner-test-matrix: path: integration-tests/smoke/log_poller_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -854,7 +854,7 @@ runner-test-matrix: path: integration-tests/smoke/runlog_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -865,7 +865,7 @@ runner-test-matrix: path: integration-tests/smoke/cron_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -876,7 +876,7 @@ runner-test-matrix: path: integration-tests/smoke/flux_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -887,7 +887,7 @@ runner-test-matrix: path: integration-tests/smoke/reorg_above_finality_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -898,7 +898,7 @@ runner-test-matrix: path: integration-tests/migration/upgrade_version_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -913,7 +913,7 @@ runner-test-matrix: path: integration-tests/smoke/job_distributor_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E Core Tests - Merge Queue E2E Core Tests - Nightly E2E Tests @@ -928,7 +928,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E CCIP Tests - Merge Queue E2E CCIP Tests - Nightly E2E Tests @@ -940,7 +940,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E CCIP Tests - Merge Queue E2E CCIP Tests - Nightly E2E Tests @@ -953,7 +953,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E CCIP Tests - Merge Queue E2E CCIP Tests - Nightly E2E Tests @@ -966,7 +966,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E CCIP Tests - Merge Queue E2E CCIP Tests - Nightly E2E Tests @@ -980,7 +980,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu-latest # Leader lane test is flakey in Core repo - Need to fix CCIP-3074 to enable it. - workflows: + triggers: # - PR E2E CCIP Tests # - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json @@ -992,7 +992,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E CCIP Tests - Merge Queue E2E CCIP Tests - Nightly E2E Tests @@ -1004,7 +1004,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E CCIP Tests - Merge Queue E2E CCIP Tests - Nightly E2E Tests @@ -1016,7 +1016,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E CCIP Tests - Merge Queue E2E CCIP Tests - Nightly E2E Tests @@ -1028,7 +1028,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E CCIP Tests - Merge Queue E2E CCIP Tests - Nightly E2E Tests @@ -1040,7 +1040,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPOffRampCapacityLimit$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -1050,7 +1050,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPOffRampAggRateLimit$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: @@ -1060,7 +1060,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E CCIP Tests - Merge Queue E2E CCIP Tests - Nightly E2E Tests @@ -1073,7 +1073,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E CCIP Tests - Merge Queue E2E CCIP Tests - Nightly E2E Tests @@ -1086,7 +1086,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker runs_on: ubuntu-latest - workflows: + triggers: - PR E2E CCIP Tests - Merge Queue E2E CCIP Tests - Nightly E2E Tests @@ -1103,7 +1103,7 @@ runner-test-matrix: test_env_vars: TEST_SUITE: ccip-load E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" - workflows: + triggers: - E2E CCIP Load Tests test_artifacts_on_failure: - ./integration-tests/load/logs/payload_ccip.json @@ -1118,7 +1118,7 @@ runner-test-matrix: # test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/load-with-arm-curse-uncurse.toml # test_env_vars: # E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" - # workflows: + # triggers: # - E2E CCIP Load Tests # test_artifacts_on_failure: # - ./integration-tests/load/logs/payload_ccip.json @@ -1127,7 +1127,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/chaos/ccip_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - workflows: + triggers: - E2E CCIP Chaos Tests test_cmd: cd integration-tests/ccip-tests/chaos && DETACH_RUNNER=false go test ccip_test.go -v -test.parallel=11 -timeout 60m -count=1 -json test_env_vars: @@ -1139,7 +1139,7 @@ runner-test-matrix: path: integration-tests/ccip-tests/load/ccip_test.go test_env_type: k8s-remote-runner runs_on: ubuntu-latest - workflows: + triggers: # Disabled until CCIP-2555 is resolved # - E2E CCIP Chaos Tests test_cmd: cd integration-tests/ccip-tests/load && DETACH_RUNNER=false go test -run '^TestLoadCCIPStableWithPodChaosDiffCommitAndExec' -v -test.parallel=4 -timeout 120m -count=1 -json diff --git a/.github/workflows/automation-benchmark-tests.yml b/.github/workflows/automation-benchmark-tests.yml index d1af80fb91..7d46b8e0c2 100644 --- a/.github/workflows/automation-benchmark-tests.yml +++ b/.github/workflows/automation-benchmark-tests.yml @@ -24,8 +24,9 @@ on: jobs: run-e2e-tests-workflow: name: Run E2E Tests - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: + test_path: .github/e2e-tests.yml test_ids: '${{ inputs.testType }}/automation_test.go:TestAutomationBenchmark' test_config_override_path: ${{ inputs.test_config_override_path }} SLACK_USER: ${{ inputs.slackMemberID }} diff --git a/.github/workflows/automation-load-tests.yml b/.github/workflows/automation-load-tests.yml index 23c053203a..5d37e81c14 100644 --- a/.github/workflows/automation-load-tests.yml +++ b/.github/workflows/automation-load-tests.yml @@ -19,8 +19,9 @@ on: jobs: run-e2e-tests-workflow: name: Run E2E Tests - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: + test_path: .github/e2e-tests.yml test_ids: 'load/automationv2_1/automationv2_1_test.go:TestLogTrigger' test_config_override_path: ${{ inputs.test_config_override_path }} SLACK_USER: ${{ inputs.slackMemberID }} diff --git a/.github/workflows/automation-nightly-tests.yml b/.github/workflows/automation-nightly-tests.yml index 06dc00b3a1..1ff80cff3c 100644 --- a/.github/workflows/automation-nightly-tests.yml +++ b/.github/workflows/automation-nightly-tests.yml @@ -10,9 +10,10 @@ on: jobs: run-e2e-tests-workflow: name: Run E2E Tests - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: - test_workflow: Automation Nightly Tests + test_path: .github/e2e-tests.yml + test_trigger: Automation Nightly Tests chainlink_version: ${{ github.sha }} slack_notification_after_tests: true slack_notification_after_tests_channel_id: "#automation-test-notifications" diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml index a5b2674425..053a0e9147 100644 --- a/.github/workflows/automation-ondemand-tests.yml +++ b/.github/workflows/automation-ondemand-tests.yml @@ -153,8 +153,9 @@ jobs: call-run-e2e-tests-workflow: name: Run E2E Tests needs: set-tests-to-run - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: + test_path: .github/e2e-tests.yml test_list: ${{ needs.set-tests-to-run.outputs.test_list }} require_chainlink_image_versions_in_qa_ecr: ${{ needs.set-tests-to-run.outputs.require_chainlink_image_versions_in_qa_ecr }} with_existing_remote_runner_version: ${{ github.event.inputs.with_existing_remote_runner_version }} diff --git a/.github/workflows/ccip-chaos-tests.yml b/.github/workflows/ccip-chaos-tests.yml index 3a6cae796d..034f0e2cb3 100644 --- a/.github/workflows/ccip-chaos-tests.yml +++ b/.github/workflows/ccip-chaos-tests.yml @@ -14,11 +14,12 @@ concurrency: jobs: run-e2e-tests-workflow: name: Run E2E Tests - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: + test_path: .github/e2e-tests.yml chainlink_version: ${{ github.sha }} require_chainlink_image_versions_in_qa_ecr: ${{ github.sha }} - test_workflow: E2E CCIP Chaos Tests + test_trigger: E2E CCIP Chaos Tests test_log_level: debug slack_notification_after_tests: on_failure slack_notification_after_tests_channel_id: '#ccip-testing' diff --git a/.github/workflows/ccip-load-tests.yml b/.github/workflows/ccip-load-tests.yml index 235b9b0f67..6464cccc73 100644 --- a/.github/workflows/ccip-load-tests.yml +++ b/.github/workflows/ccip-load-tests.yml @@ -31,9 +31,10 @@ concurrency: jobs: run-e2e-tests-workflow: name: Run E2E Tests - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: - test_workflow: E2E CCIP Load Tests + test_path: .github/e2e-tests.yml + test_trigger: E2E CCIP Load Tests test_config_override_path: ${{ inputs.test_config_override_path }} chainlink_version: ${{ inputs.chainlink_version || github.sha }} slack_notification_after_tests: always diff --git a/.github/workflows/integration-chaos-tests.yml b/.github/workflows/integration-chaos-tests.yml index c9da7d8438..3198320f6c 100644 --- a/.github/workflows/integration-chaos-tests.yml +++ b/.github/workflows/integration-chaos-tests.yml @@ -10,11 +10,12 @@ on: jobs: run-e2e-tests-workflow: name: Run E2E Tests - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: + test_path: .github/e2e-tests.yml chainlink_version: ${{ github.sha }} require_chainlink_image_versions_in_qa_ecr: ${{ github.sha }} - test_workflow: E2E Chaos Tests + test_trigger: E2E Chaos Tests test_log_level: debug secrets: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 6389386799..79db8c2859 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -242,12 +242,13 @@ jobs: contents: read needs: [build-chainlink, changes] if: github.event_name == 'pull_request' && ( needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: workflow_name: Run Core E2E Tests For PR chainlink_version: ${{ inputs.evm-ref || github.sha }} chainlink_upgrade_version: ${{ github.sha }} - test_workflow: PR E2E Core Tests + test_path: .github/e2e-tests.yml + test_trigger: PR E2E Core Tests upload_cl_node_coverage_artifact: true upload_cl_node_coverage_artifact_prefix: cl_node_coverage_data_ enable_otel_traces_for_ocr2_plugins: ${{ contains(join(github.event.pull_request.labels.*.name, ' '), 'enable tracing') }} @@ -281,12 +282,13 @@ jobs: contents: read needs: [build-chainlink, changes] if: github.event_name == 'merge_group' && ( needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: workflow_name: Run Core E2E Tests For Merge Queue chainlink_version: ${{ inputs.evm-ref || github.sha }} chainlink_upgrade_version: ${{ github.sha }} - test_workflow: Merge Queue E2E Core Tests + test_path: .github/e2e-tests.yml + test_trigger: Merge Queue E2E Core Tests upload_cl_node_coverage_artifact: true upload_cl_node_coverage_artifact_prefix: cl_node_coverage_data_ enable_otel_traces_for_ocr2_plugins: ${{ contains(join(github.event.pull_request.labels.*.name, ' '), 'enable tracing') }} @@ -324,12 +326,13 @@ jobs: contents: read needs: [build-chainlink, changes] if: github.event_name == 'pull_request' && (needs.changes.outputs.ccip_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: workflow_name: Run CCIP E2E Tests For PR chainlink_version: ${{ inputs.evm-ref || github.sha }} chainlink_upgrade_version: ${{ github.sha }} - test_workflow: PR E2E CCIP Tests + test_path: .github/e2e-tests.yml + test_trigger: PR E2E CCIP Tests upload_cl_node_coverage_artifact: true upload_cl_node_coverage_artifact_prefix: cl_node_coverage_data_ enable_otel_traces_for_ocr2_plugins: ${{ contains(join(github.event.pull_request.labels.*.name, ' '), 'enable tracing') }} @@ -363,12 +366,13 @@ jobs: contents: read needs: [build-chainlink, changes] if: github.event_name == 'merge_group' && (needs.changes.outputs.ccip_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: workflow_name: Run CCIP E2E Tests For Merge Queue chainlink_version: ${{ inputs.evm-ref || github.sha }} chainlink_upgrade_version: ${{ github.sha }} - test_workflow: Merge Queue E2E CCIP Tests + test_path: .github/e2e-tests.yml + test_trigger: Merge Queue E2E CCIP Tests upload_cl_node_coverage_artifact: true upload_cl_node_coverage_artifact_prefix: cl_node_coverage_data_ enable_otel_traces_for_ocr2_plugins: ${{ contains(join(github.event.pull_request.labels.*.name, ' '), 'enable tracing') }} diff --git a/.github/workflows/on-demand-ocr-soak-test.yml b/.github/workflows/on-demand-ocr-soak-test.yml index cdb0b5da01..978c1eb67d 100644 --- a/.github/workflows/on-demand-ocr-soak-test.yml +++ b/.github/workflows/on-demand-ocr-soak-test.yml @@ -39,8 +39,9 @@ on: jobs: run-e2e-tests-workflow: name: Run E2E Tests - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: + test_path: .github/e2e-tests.yml test_ids: ${{ inputs.testToRun}} test_config_override_path: ${{ inputs.test_config_override_path }} chainlink_version: ${{ inputs.chainlink_version }} diff --git a/.github/workflows/on-demand-vrfv2-performance-test.yml b/.github/workflows/on-demand-vrfv2-performance-test.yml index d5eefcc348..1f1a847d82 100644 --- a/.github/workflows/on-demand-vrfv2-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2-performance-test.yml @@ -67,7 +67,7 @@ jobs: run-e2e-tests-workflow: name: Run E2E Tests needs: set-tests-to-run - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} chainlink_version: ${{ inputs.chainlink_version }} diff --git a/.github/workflows/on-demand-vrfv2-smoke-tests.yml b/.github/workflows/on-demand-vrfv2-smoke-tests.yml index ea42a9014d..9f77c7ab53 100644 --- a/.github/workflows/on-demand-vrfv2-smoke-tests.yml +++ b/.github/workflows/on-demand-vrfv2-smoke-tests.yml @@ -70,7 +70,7 @@ jobs: run-e2e-tests-workflow: name: Run E2E Tests needs: set-tests-to-run - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} chainlink_version: ${{ inputs.chainlink_version }} diff --git a/.github/workflows/on-demand-vrfv2plus-performance-test.yml b/.github/workflows/on-demand-vrfv2plus-performance-test.yml index f026086fff..ae42c32945 100644 --- a/.github/workflows/on-demand-vrfv2plus-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-performance-test.yml @@ -67,7 +67,7 @@ jobs: run-e2e-tests-workflow: name: Run E2E Tests needs: set-tests-to-run - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} chainlink_version: ${{ inputs.chainlink_version }} diff --git a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml index e1821336c6..9cd863eb7e 100644 --- a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml +++ b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml @@ -70,7 +70,7 @@ jobs: run-e2e-tests-workflow: name: Run E2E Tests needs: set-tests-to-run - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} chainlink_version: ${{ inputs.chainlink_version }} diff --git a/.github/workflows/run-e2e-tests-reusable-workflow.yml b/.github/workflows/run-e2e-tests-reusable-workflow.yml deleted file mode 100644 index 8f0fd54e37..0000000000 --- a/.github/workflows/run-e2e-tests-reusable-workflow.yml +++ /dev/null @@ -1,998 +0,0 @@ -# This is a reusable workflow that runs E2E tests for Chainlink. -# It is not meant to be run on its own. -# -# IMPORTANT NOTE: All workflow_call inputs appear as plain text in GitHub Logs (see https://github.com/actions/runner/issues/2988). -# Do not include any sensitive information in these inputs. Instead, for handling test secrets, refer to https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/README.md#test-secrets -# -name: Run E2E Tests -on: - workflow_call: - inputs: - workflow_name: - description: 'Custom name for the workflow run' - required: false - type: string - default: 'Run E2E Tests' - chainlink_version: - description: 'Enter Chainlink version to use for the tests. Example: v2.10.0, develop or commit sha' - required: false - type: string - chainlink_upgrade_version: - description: 'Enter Chainlink version to use for the upgrade tests. Example: v2.10.0, develop or commit sha' - required: false - type: string - test_ids: - description: 'Run tests by test ids separated by commas. Example: "run_all_in_ocr_tests_go,run_TestOCRv2Request_in_ocr2_test_go". Check all test IDs in .github/e2e-tests.yml' - required: false - type: string - test_list: - description: 'Base64 encoded list of tests (YML objects) to run. Example in run-automation-ondemand-e2e-tests.yml' - required: false - type: string - custom_test_list_json: - description: 'Custom JSON list of tests to run' - required: false - type: string - # Example: - # custom_test_list_json: > - # { - # "tests": [ - # { - # "id": "TestVRFv2Plus", - # "path": "integration-tests/smoke/vrfv2plus_test.go", - # "runs_on": "ubuntu-latest", - # "test_env_type": "docker", - # "test_cmd": "cd integration-tests/smoke && go test vrfv2plus_test.go -test.parallel=1 -timeout 3h -count=1 -json -v" - # } - # ] - # } - test_workflow: - description: 'Run tests by workflow name. Example: "Run Nightly E2E Tests"' - required: false - type: string - test_config_override_path: - description: 'Path to a test config file used to override the default test config' - required: false - type: string - enable_check_test_configurations: - description: 'Set to "true" to enable check-test-configurations job' - required: false - type: boolean - default: false - with_existing_remote_runner_version: - description: 'Use the existing remote runner version for k8s tests. Example: "d3bf5044af33e08be788a2df31c4a745cf69d787"' - required: false - type: string - test_image_suites: - description: 'Suites to build in the test image. Space separated' - required: false - type: string - default: chaos migration reorg smoke soak benchmark load ccip-load - require_chainlink_image_versions_in_qa_ecr: - description: 'Check Chainlink image versions to be present in QA ECR. If not, build and push the image to QA ECR. Takes comma separated list of Chainlink image versions. Example: "5733cdcda9a9fc6da6343798b119b2ae136146cd,0b7d2c497a508efa5a827714780d908b7b8eda19"' - required: false - type: string - require_chainlink_plugin_versions_in_qa_ecr: - description: 'Check Chainlink plugins versions to be present in QA ECR. If not, build and push the image to QA ECR. Takes comma separated list of Chainlink image versions. Example: "5733cdcda9a9fc6da6343798b119b2ae136146cd,0b7d2c497a508efa5a827714780d908b7b8eda19"' - required: false - type: string - slack_notification_after_tests: - description: 'Set to "always" to always send a slack notification after the tests. Set "on_failure" to send a notification only on test failure' - required: false - type: string - slack_notification_after_tests_channel_id: - description: 'Slack channel ID to send the notification to' - required: false - type: string - slack_notification_after_tests_name: - description: 'Name of the slack notification' - required: false - type: string - slack_notification_after_tests_notify_user_id_on_failure: - description: 'Set Slack user id to notify on test failure' - required: false - type: string - test_log_upload_on_failure: - description: 'Set to "true" to upload the test log on failure as Github artifact' - required: false - type: boolean - default: false - test_log_upload_retention_days: - description: 'Number of days to retain the test log. Default is 3 days' - required: false - type: number - default: 5 - test_log_level: - description: 'Set the log level for the tests. Default is "debug"' - required: false - type: string - default: debug - upload_cl_node_coverage_artifact: - description: 'Set to "true" to upload Chainlink node coverage artifact to as Github artifact' - required: false - type: boolean - default: false - upload_cl_node_coverage_artifact_prefix: - description: 'Prefix for the Chainlink node coverage artifact' - required: false - type: string - enable_otel_traces_for_ocr2_plugins: - description: 'Set to "true" to enable OpenTelemetry traces for OCR2 plugins tests' - required: false - type: boolean - default: false - SLACK_CHANNEL: - description: 'SLACK_CHANNEL env used to send Slack notifications from test code' - required: false - type: string - SLACK_USER: - description: 'SLACK_USER env used to send Slack notifications from test code' - required: false - type: string - outputs: - test_results: - description: 'Test results from all executed tests' - value: ${{ jobs.after_tests.outputs.test_results }} - secrets: - TEST_SECRETS_OVERRIDE_BASE64: - required: false - QA_AWS_REGION: - required: true - QA_AWS_ROLE_TO_ASSUME: - required: true - QA_AWS_ACCOUNT_NUMBER: - required: true - QA_PYROSCOPE_INSTANCE: - required: true - QA_PYROSCOPE_KEY: - required: true - QA_KUBECONFIG: - required: true - LOKI_TENANT_ID: - required: true - LOKI_URL: - required: true - LOKI_BASIC_AUTH: - required: true - GRAFANA_INTERNAL_TENANT_ID: - required: true - GRAFANA_INTERNAL_BASIC_AUTH: - required: true - GRAFANA_INTERNAL_HOST: - required: true - GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: - required: true - GH_TOKEN: - required: true - AWS_REGION: - required: true - AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: - required: true - AWS_API_GW_HOST_GRAFANA: - required: true - SLACK_BOT_TOKEN: - required: false - # Use instead of slack_notification_after_tests_channel_id if channel id is secret - SLACK_NOTIFICATION_AFTER_TESTS_CHANNEL_ID: - required: false - # Used in some tests to send slack notifications - SLACK_API_KEY: - required: false - # Used in some tests to send slack notifications - SLACK_CHANNEL: - required: false - -env: - CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - QA_CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - DEFAULT_CHAINLINK_VERSION: ${{ inputs.chainlink_version }} - DEFAULT_CHAINLINK_PLUGINS_VERSION: ${{ inputs.chainlink_version != '' && format('{0}-plugins', inputs.chainlink_version) }} - DEFAULT_CHAINLINK_UPGRADE_VERSION: ${{ inputs.chainlink_version }} - CHAINLINK_ENV_USER: ${{ github.actor }} - CHAINLINK_COMMIT_SHA: ${{ inputs.evm-ref }} - MOD_CACHE_VERSION: 1 - TEST_LOG_LEVEL: ${{ inputs.test_log_level }} - METRICS_COLLECTION_ID: chainlink-e2e-tests - SLACK_API_KEY: ${{ secrets.SLACK_API_KEY }} - SLACK_CHANNEL: ${{ inputs.slack_notification_after_tests_channel_id || inputs.SLACK_CHANNEL || secrets.SLACK_CHANNEL }} - SLACK_USER: ${{ inputs.SLACK_USER }} - -jobs: - validate-inputs: - name: Validate workflow inputs - runs-on: ubuntu-latest - outputs: - require_chainlink_image_versions_in_qa_ecr_matrix: ${{ steps.set-required-chainlink-image-versions-matrix.outputs.versions }} - require_chainlink_plugin_versions_in_qa_ecr_matrix: ${{ steps.set-required-chainlink-plugin-versions-matrix.outputs.versions }} - steps: - - name: Check input conditions - run: | - if [[ "${{ inputs.test_ids }}" != "" && "${{ inputs.test_workflow }}" != "" ]]; then - echo "::error::Error: Both 'test_ids' and 'test_workflow' are provided. Please specify only one." - exit 1 - fi - if [[ "${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }}" != "" ]]; then - echo "Will run tests with custom test secrets" - fi - - name: Install jq - run: sudo apt-get install jq - - - name: Create matrix for required Chainlink image versions - id: set-required-chainlink-image-versions-matrix - run: | - image_versions="${{ inputs.require_chainlink_image_versions_in_qa_ecr }}" - default_version="${{ env.DEFAULT_CHAINLINK_VERSION }}" - current_sha="${{ github.sha }}" - - if [[ "$default_version" == "$current_sha" ]]; then - # Append the current SHA to required image versions - if [[ -z "$image_versions" ]]; then - image_versions="${{ github.sha }}" - else - image_versions+=",${{ github.sha }}" - fi - fi - - # Convert the comma-separated string to a JSON array - image_versions=$(echo "$image_versions" | jq -Rc 'if . == "" then "" else split(",") | if . == [""] then "" else . end end') - - echo "Required Chainlink image versions: $image_versions" - echo "versions=$image_versions" >> $GITHUB_OUTPUT - - - name: Create matrix for required Chainlink plugin versions - id: set-required-chainlink-plugin-versions-matrix - run: | - image_versions=$(echo "${{ inputs.require_chainlink_plugin_versions_in_qa_ecr }}" | jq -Rc 'if . == "" then "" else split(",") | if . == [""] then "" else . end end') - echo "Required Chainlink plugin image versions: $image_versions" - echo "versions=$image_versions" >> $GITHUB_OUTPUT - - check-test-configurations: - name: Check test configurations - if: ${{ inputs.enable_check_test_configurations }} - needs: validate-inputs - runs-on: ubuntu-latest - steps: - - name: Checkout core - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - fetch-depth: 0 - path: core - - name: Install citool - shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/citool@1d8d5b55bf6379b969dbcde99abc87faa5963ea1 # v1.34.4 - - name: Run Check Tests Command - run: | - if ! citool check-tests ${{ github.workspace }}/integration-tests ${{ github.workspace }}/.github/e2e-tests.yml; then - echo "::error::Some E2E test configurations have to be added to .github/e2e-tests.yml. This file defines Github CI configuration for each E2E test or set of E2E tests." && exit 1 - fi - - get_latest_chainlink_release_version: - name: Get latest Chainlink release version - runs-on: ubuntu-latest - environment: integration - outputs: - latest_chainlink_release_version: ${{ steps.get_latest_version.outputs.latest_version }} - steps: - - name: Get Latest Version - id: get_latest_version - run: | - untrimmed_ver=$(curl --header "Authorization: token ${{ secrets.GH_TOKEN }}" --request GET https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r .name) - latest_version="${untrimmed_ver:1}" - echo "Latest Chainlink release version: $latest_version" - echo "latest_version=${latest_version}" >> "$GITHUB_OUTPUT" - # Check if latest_version is empty - if [ -z "$latest_version" ]; then - echo "Error: The latest_version is empty. The migration tests need a verison to run." - exit 1 - fi - - load-test-configurations: - name: Load test configurations - needs: [validate-inputs] - runs-on: ubuntu-latest - outputs: - run-docker-tests: ${{ steps.check-matrices.outputs.run-docker-tests }} - run-k8s-tests: ${{ steps.check-matrices.outputs.run-k8s-tests }} - docker-matrix: ${{ steps.set-docker-matrix.outputs.matrix }} - k8s-runner-matrix: ${{ steps.set-k8s-runner-matrix.outputs.matrix }} - workflow_id: ${{ steps.gen_id.outputs.workflow_id }} - steps: - - name: Checkout code - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Setup Go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 - with: - go-version: '1.22.6' - check-latest: true - - name: Install citool - shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/citool@1d8d5b55bf6379b969dbcde99abc87faa5963ea1 # v1.34.4 - - name: Install jq - run: sudo apt-get install jq - - - name: Generate Docker Tests Matrix - id: set-docker-matrix - run: | - # Check if custom_test_list_json is provided and non-empty - if [[ -n '${{ inputs.custom_test_list_json }}' ]]; then - echo "Using custom test list JSON" - MATRIX_JSON=$(echo '${{ inputs.custom_test_list_json }}' | jq -c '{tests: [.tests[] | select(.test_env_type == "docker")]}') - else - echo "Using default test list" - MATRIX_JSON=$(citool filter --file ${{ github.workspace }}/.github/e2e-tests.yml --test-env-type 'docker' --test-list '${{ inputs.test_list }}' --test-ids '${{ inputs.test_ids }}' --workflow '${{ inputs.test_workflow }}') - fi - - echo "Docker tests:" - echo "$MATRIX_JSON" | jq - echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT - - - name: Generate K8s Tests Matrix - id: set-k8s-runner-matrix - run: | - # Check if custom_test_list_json is provided and non-empty - if [[ -n '${{ inputs.custom_test_list_json }}' ]]; then - echo "Using custom test list JSON" - MATRIX_JSON=$(echo '${{ inputs.custom_test_list_json }}' | jq -c '{tests: [.tests[] | select(.test_env_type == "k8s-remote-runner")]}') - else - echo "Using default test list" - MATRIX_JSON=$(citool filter --file ${{ github.workspace }}/.github/e2e-tests.yml --test-env-type 'k8s-remote-runner' --test-list '${{ inputs.test_list }}' --test-ids '${{ inputs.test_ids }}' --workflow '${{ inputs.test_workflow }}') - fi - - echo "K8s tests:" - echo "$MATRIX_JSON" | jq - echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT - - - name: Check Test Matrices - id: check-matrices - run: | - DOCKER_MATRIX_EMPTY=$(echo '${{ steps.set-docker-matrix.outputs.matrix }}' | jq '.tests == null or .tests == []') - K8S_MATRIX_EMPTY=$(echo '${{ steps.set-k8s-runner-matrix.outputs.matrix }}' | jq '.tests == null or .tests == []') - - # Check if jq commands succeeded - if [ $? -ne 0 ]; then - echo "JSON parse error occurred." - exit 1 - fi - - if [[ "$DOCKER_MATRIX_EMPTY" == "true" ]]; then - echo "run-docker-tests=false" >> $GITHUB_OUTPUT - else - echo "run-docker-tests=true" >> $GITHUB_OUTPUT - fi - if [[ "$K8S_MATRIX_EMPTY" == "true" ]]; then - echo "run-k8s-tests=false" >> $GITHUB_OUTPUT - else - echo "run-k8s-tests=true" >> $GITHUB_OUTPUT - fi - - # Check if both matrices are empty - if [[ "$DOCKER_MATRIX_EMPTY" == "true" ]] && [[ "$K8S_MATRIX_EMPTY" == "true" ]]; then - echo "No tests found for inputs. Both Docker and Kubernetes tests matrices are empty" - exit 1 - fi - shell: bash - - - name: Check if test secrets are required for any test - shell: bash - run: | - # Check if the test secret key is provided and skip the checks if it is non-empty - if [ -n "${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }}" ]; then - echo "Test secret key provided. Skipping checks for tests requiring secrets." - exit 0 - fi - - # Parse the JSON to check for test_secrets_required in Docker matrix - DOCKER_TESTS_REQUIRING_SECRETS=$(echo '${{ steps.set-docker-matrix.outputs.matrix }}' | jq 'if .tests then .tests[] | select(has("test_secrets_required") and .test_secrets_required) | .id else empty end' -r) - # Parse the JSON to check for test_secrets_required in Kubernetes matrix - K8S_TESTS_REQUIRING_SECRETS=$(echo '${{ steps.set-k8s-runner-matrix.outputs.matrix }}' | jq 'if .tests then .tests[] | select(has("test_secrets_required") and .test_secrets_required) | .id else empty end' -r) - - # Determine if any tests require secrets - if [ ! -z "$DOCKER_TESTS_REQUIRING_SECRETS" ] || [ ! -z "$K8S_TESTS_REQUIRING_SECRETS" ]; then - echo "Tests in .github/e2e-tests.yml requiring custom test secrets:" - if [ ! -z "$DOCKER_TESTS_REQUIRING_SECRETS" ]; then - echo $DOCKER_TESTS_REQUIRING_SECRETS - fi - if [ ! -z "$K8S_TESTS_REQUIRING_SECRETS" ]; then - echo $K8S_TESTS_REQUIRING_SECRETS - fi - echo "::error::Error: Some of the tests require custom test secrets to run. Please see workflow logs and set 'test_secrets_override_key' to run these tests." - exit 1 - else - echo "No tests require secrets. Proceeding without additional secret setup." - fi - - - name: Generate random workflow id - id: gen_id - run: echo "workflow_id=$(uuidgen)" >> $GITHUB_OUTPUT - - - # Check if Chainlink images required for the tests exist. If not, build and push the images to QA ECR - require-chainlink-image-versions-in-qa-ecr: - name: Get Chainlink image - needs: [validate-inputs, load-test-configurations] - if: ${{ fromJson(needs.validate-inputs.outputs.require_chainlink_image_versions_in_qa_ecr_matrix) != '' }} - runs-on: ubuntu-latest - environment: integration - permissions: - id-token: write - contents: read - env: - CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - strategy: - matrix: - version: ${{ fromJson(needs.validate-inputs.outputs.require_chainlink_image_versions_in_qa_ecr_matrix) }} - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - - name: Get Chainlink image - uses: ./.github/actions/build-chainlink-image - with: - dockerfile: core/chainlink.Dockerfile - git_commit_sha: ${{ matrix.version }} - tag_suffix: '' - check_image_exists: 'true' - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - # Check if Chainlink plugins required for the tests exist. If not, build and push the images to QA ECR - require-chainlink-plugin-versions-in-qa-ecr: - name: Get Chainlink plugins image - needs: [validate-inputs, load-test-configurations] - if: ${{ fromJson(needs.validate-inputs.outputs.require_chainlink_plugin_versions_in_qa_ecr_matrix) != '' }} - runs-on: ubuntu-latest - environment: integration - permissions: - id-token: write - contents: read - env: - CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink - strategy: - matrix: - version: ${{ fromJson(needs.validate-inputs.outputs.require_chainlink_plugin_versions_in_qa_ecr_matrix) }} - steps: - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - - name: Get Chainlink plugins image - uses: ./.github/actions/build-chainlink-image - with: - dockerfile: plugins/chainlink.Dockerfile - git_commit_sha: ${{ matrix.version }} - tag_suffix: '-plugins' - check_image_exists: 'true' - AWS_REGION: ${{ secrets.QA_AWS_REGION }} - AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - # Run Docker tests - run-docker-tests: - name: ${{ matrix.tests.id }} - needs: [load-test-configurations, require-chainlink-image-versions-in-qa-ecr, require-chainlink-plugin-versions-in-qa-ecr, get_latest_chainlink_release_version] - # Run when none of the needed jobs fail or are cancelled (skipped or successful jobs are ok) - if: ${{ needs.load-test-configurations.outputs.run-docker-tests == 'true' && always() && !failure() && !cancelled() }} - runs-on: ${{ matrix.tests.runs_on }} - strategy: - fail-fast: false - matrix: ${{fromJson(needs.load-test-configurations.outputs.docker-matrix)}} - environment: integration - permissions: - actions: read - checks: write - pull-requests: write - id-token: write - contents: read - env: - LATEST_CHAINLINK_RELEASE_VERSION: ${{ needs.get_latest_chainlink_release_version.outputs.latest_chainlink_release_version }} - TEST_CONFIG_OVERRIDE_PATH: ${{ matrix.tests.test_config_override_path || inputs.test_config_override_path }} - TEST_ID: ${{ matrix.tests.id_sanitized || matrix.tests.id }} - steps: - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: e2e_tests_${{ env.TEST_ID }} - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ${{ inputs.workflow_name }} / ${{ matrix.tests.id }} - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true - - - name: Checkout repository - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Install jq - run: sudo apt-get install -y jq - - - name: Show test config override path in summary - if: ${{ env.TEST_CONFIG_OVERRIDE_PATH }} - run: | - echo "### Test config override path" >> $GITHUB_STEP_SUMMARY - echo "[${{ env.TEST_CONFIG_OVERRIDE_PATH }}]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/blob/${{ github.sha }}/${{ env.TEST_CONFIG_OVERRIDE_PATH }})" >> $GITHUB_STEP_SUMMARY - - - name: Show chainlink version in summary - if: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }} - run: | - echo "### Chainlink version" >> $GITHUB_STEP_SUMMARY - echo "${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }}" >> $GITHUB_STEP_SUMMARY - - - name: Show test configuration in logs - run: echo '${{ toJson(matrix.tests) }}' | jq . - - - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@d316f66b2990ea4daa479daa3de6fc92b00f863e # setup-gap@0.3.2 - id: setup-gap - timeout-minutes: 3 - with: - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} - duplicate-authorization-header: "true" - - - name: Setup Grafana and OpenTelemetry - id: docker-setup - if: inputs.enable_otel_traces_for_ocr2_plugins && matrix.tests.test_env_vars.ENABLE_OTEL_TRACES == 'true' - run: | - # Create network - docker network create --driver bridge tracing - - # Make trace directory - cd integration-tests/smoke/ - mkdir ./traces - chmod -R 777 ./traces - - # Switch directory - cd ../../.github/tracing - - # Create a Docker volume for traces - # docker volume create otel-traces - - # Start OpenTelemetry Collector - # Note the user must be set to the same user as the runner for the trace data to be accessible - docker run -d --network=tracing --name=otel-collector \ - -v $PWD/otel-collector-ci.yaml:/etc/otel-collector.yaml \ - -v $PWD/../../integration-tests/smoke/traces:/tracing \ - --user "$(id -u):$(id -g)" \ - -p 4317:4317 otel/opentelemetry-collector:0.88.0 --config=/etc/otel-collector.yaml - - - name: Run tests - id: run_tests - uses: smartcontractkit/.github/actions/ctf-run-tests@b8731364b119e88983e94b0c4da87fc27ddb41b8 # ctf-run-tests@0.0.0 - env: - DETACH_RUNNER: true - E2E_TEST_CHAINLINK_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }} - E2E_TEST_CHAINLINK_UPGRADE_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_VERSION }} - E2E_TEST_CHAINLINK_POSTGRES_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_POSTGRES_VERSION }} - E2E_TEST_SELECTED_NETWORK: ${{ matrix.tests.test_env_vars.E2E_TEST_SELECTED_NETWORK }} - E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} - E2E_TEST_LOG_STREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} - E2E_TEST_LOG_COLLECT: ${{ vars.TEST_LOG_COLLECT }} - E2E_TEST_LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} - E2E_TEST_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} - E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} - E2E_TEST_GRAFANA_DASHBOARD_URL: ${{ matrix.tests.test_env_vars.E2E_TEST_GRAFANA_DASHBOARD_URL }} - E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - E2E_TEST_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} - E2E_TEST_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} - E2E_TEST_PYROSCOPE_KEY: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_KEY || '' }} - with: - test_command_to_run: ${{ matrix.tests.test_cmd }} ${{ matrix.tests.test_cmd_opts || '2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false' }} - test_download_vendor_packages_command: cd $(dirname ${{ matrix.tests.path }}) && go mod download - test_secrets_override_base64: ${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }} - test_config_override_path: ${{ env.TEST_CONFIG_OVERRIDE_PATH }} - test_type: ${{ matrix.tests.test_env_vars.TEST_TYPE }} - test_suite: ${{ matrix.tests.test_env_vars.TEST_SUITE }} - default_e2e_test_chainlink_image: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_IMAGE || env.CHAINLINK_IMAGE }} - default_e2e_test_chainlink_upgrade_image: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_IMAGE }} - aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - artifacts_name: ${{ env.TEST_ID }}-test-logs - artifacts_location: | - ./integration-tests/smoke/logs/ - ./integration-tests/smoke/db_dumps/ - /tmp/gotest.log - publish_check_name: ${{ env.TEST_ID }} - token: ${{ secrets.GH_TOKEN }} - cache_key_id: e2e-tests - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: "" - should_tidy: "false" - go_coverage_src_dir: /var/tmp/go-coverage - go_coverage_dest_dir: ${{ github.workspace }}/.covdata - - - name: Show Otel-Collector logs - if: inputs.enable_otel_traces_for_ocr2_plugins && matrix.tests.test_env_vars.ENABLE_OTEL_TRACES == 'true' - run: | - docker logs otel-collector - - - name: Permissions on traces - if: inputs.enable_otel_traces_for_ocr2_plugins && matrix.tests.test_env_vars.ENABLE_OTEL_TRACES == 'true' - run: | - ls -l ./integration-tests/smoke/traces - - - name: Upload trace data as artifact - if: inputs.enable_otel_traces_for_ocr2_plugins && matrix.tests.test_env_vars.ENABLE_OTEL_TRACES == 'true' - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 - with: - name: trace-data - path: ./integration-tests/smoke/traces/trace-data.json - - - name: Upload test log as artifact - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 - if: inputs.test_log_upload_on_failure && failure() - with: - name: test_log_${{ env.TEST_ID }} - path: /tmp/gotest.log - retention-days: ${{ inputs.test_log_upload_retention_days }} - continue-on-error: true - - - name: Upload cl node coverage data as artifact - if: inputs.upload_cl_node_coverage_artifact - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - timeout-minutes: 2 - continue-on-error: true - with: - name: ${{ inputs.upload_cl_node_coverage_artifact_prefix }}${{ env.TEST_ID }} - path: .covdata - retention-days: 1 - - - name: Record test result - if: ${{ always() }} - run: | - id="${{ matrix.tests.id }}" - result="${{ steps.run_tests.outcome }}" - echo "{\"id\": \"$id\", \"result\": \"$result\"}" > test_result.json - - - name: Upload test result as artifact - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - with: - name: test_result_${{ needs.load-test-configurations.outputs.workflow_id }}_${{ env.TEST_ID }} - path: test_result.json - retention-days: 1 - - - name: Upload custom test artifacts - if: failure() && matrix.tests.test_artifacts_on_failure != '' - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - with: - name: custom_test_artifacts_${{ env.TEST_ID }}_${{ needs.load-test-configurations.outputs.workflow_id }} - path: ${{ matrix.tests.test_artifacts_on_failure }} - retention-days: 1 - - - name: Show Grafana url in test summary - if: always() - uses: smartcontractkit/.github/actions/ctf-show-grafana-in-test-summary@b6e37806737eef87e8c9137ceeb23ef0bff8b1db # ctf-show-grafana-in-test-summary@0.1.0 - - # Run K8s tests using old remote runner - - get-remote-runner-test-image: - needs: [load-test-configurations] - if: ${{ needs.load-test-configurations.outputs.run-k8s-tests == 'true' && always() && !failure() && !cancelled() }} - name: Get remote runner test image - runs-on: ubuntu-latest - environment: integration - permissions: - actions: read - checks: write - pull-requests: write - id-token: write - contents: read - outputs: - remote-runner-version: ${{ steps.set-remote-runner-version.outputs.remote-runner-version }} - env: - ENV_JOB_IMAGE_BASE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests - steps: - - name: Checkout repository - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Build Test Runner Image - id: build-test-runner-image - uses: smartcontractkit/.github/actions/ctf-build-test-image@a5e4f4c8fbb8e15ab2ad131552eca6ac83c4f4b3 # ctf-build-test-image@0.1.0 - if: ${{ inputs.with_existing_remote_runner_version == '' }} - with: - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - suites: ${{ inputs.test_image_suites }} - - name: Set Remote Runner Version - id: set-remote-runner-version - run: | - if [[ -z "${{ inputs.with_existing_remote_runner_version }}" ]]; then - echo "remote-runner-image=${{ steps.build-test-runner-image.outputs.test_image }}" >> $GITHUB_OUTPUT - echo "remote-runner-repository=${{ steps.build-test-runner-image.outputs.test_image_repository }}" >> $GITHUB_OUTPUT - echo "remote-runner-version=${{ steps.build-test-runner-image.outputs.test_image_tag }}" >> $GITHUB_OUTPUT - else - echo "remote-runner-version=${{ inputs.with_existing_remote_runner_version }}" >> $GITHUB_OUTPUT - fi - - run-k8s-runner-tests: - needs: [load-test-configurations, get-remote-runner-test-image, require-chainlink-image-versions-in-qa-ecr, require-chainlink-plugin-versions-in-qa-ecr, get_latest_chainlink_release_version] - if: ${{ needs.load-test-configurations.outputs.run-k8s-tests == 'true' && always() && !failure() && !cancelled() }} - name: ${{ matrix.tests.id }} - runs-on: ${{ matrix.tests.runs_on }} - strategy: - fail-fast: false - matrix: ${{fromJson(needs.load-test-configurations.outputs.k8s-runner-matrix)}} - environment: integration - permissions: - actions: read - checks: write - pull-requests: write - id-token: write - contents: read - env: - LATEST_CHAINLINK_RELEASE_VERSION: ${{ needs.get_latest_chainlink_release_version.outputs.latest_chainlink_release_version }} - TEST_CONFIG_OVERRIDE_PATH: ${{ matrix.tests.test_config_override_path || inputs.test_config_override_path }} - TEST_ID: ${{ matrix.tests.id_sanitized || matrix.tests.id }} - steps: - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 - with: - id: e2e_tests_${{ env.TEST_ID }} - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: ${{ inputs.workflow_name }} / ${{ matrix.tests.id }} - continue-on-error: true - - - name: Checkout repository - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - name: Install jq - run: sudo apt-get install -y jq - - - name: Show test config override path in summary - if: ${{ env.TEST_CONFIG_OVERRIDE_PATH }} - run: | - echo "### Test config override path" >> $GITHUB_STEP_SUMMARY - echo "[${{ env.TEST_CONFIG_OVERRIDE_PATH }}]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/blob/${{ github.sha }}/${{ env.TEST_CONFIG_OVERRIDE_PATH }})" >> $GITHUB_STEP_SUMMARY - - - name: Show chainlink version in summary - if: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }} - run: | - echo "### Chainlink version" >> $GITHUB_STEP_SUMMARY - echo "${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }}" >> $GITHUB_STEP_SUMMARY - - - name: Show remote runner version in summary - run: | - echo "Remote Runner Version: ${{ needs.get-remote-runner-test-image.outputs.remote-runner-version }}" - echo "### Remote Runner Version" >> $GITHUB_STEP_SUMMARY - echo "${{ needs.get-remote-runner-test-image.outputs.remote-runner-version }}" >> $GITHUB_STEP_SUMMARY - - - name: Show test configuration in logs - run: echo '${{ toJson(matrix.tests) }}' | jq . - - - name: Run tests - id: run_tests - uses: smartcontractkit/.github/actions/ctf-run-tests@b6e37806737eef87e8c9137ceeb23ef0bff8b1db # ctf-run-tests@0.1.0 - env: - DETACH_RUNNER: true - RR_MEM: ${{ matrix.tests.remote_runner_memory }} - TEST_ARGS: -test.timeout 900h -test.memprofile memprofile.out -test.cpuprofile profile.out - ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ needs.get-remote-runner-test-image.outputs.remote-runner-version }} - INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com - # We can comment these out when we have a stable soak test and aren't worried about resource consumption - TEST_UPLOAD_CPU_PROFILE: ${{ matrix.tests.test_env_vars.TEST_UPLOAD_CPU_PROFILE }} - TEST_UPLOAD_MEM_PROFILE: ${{ matrix.tests.test_env_vars.TEST_UPLOAD_MEM_PROFILE }} - REF_NAME: ${{ github.head_ref || github.ref_name }} - E2E_TEST_CHAINLINK_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_VERSION || env.DEFAULT_CHAINLINK_VERSION }} - E2E_TEST_CHAINLINK_UPGRADE_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_VERSION }} - E2E_TEST_CHAINLINK_POSTGRES_VERSION: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_POSTGRES_VERSION }} - E2E_TEST_SELECTED_NETWORK: ${{ matrix.tests.test_env_vars.E2E_TEST_SELECTED_NETWORK }} - E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} - E2E_TEST_LOG_STREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} - E2E_TEST_LOG_COLLECT: ${{ vars.TEST_LOG_COLLECT }} - E2E_TEST_LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} - E2E_TEST_LOKI_ENDPOINT: ${{ secrets.LOKI_URL }} - E2E_TEST_LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} - E2E_TEST_GRAFANA_DASHBOARD_URL: ${{ matrix.tests.test_env_vars.E2E_TEST_GRAFANA_DASHBOARD_URL }} - E2E_TEST_GRAFANA_BEARER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} - E2E_TEST_PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} - E2E_TEST_PYROSCOPE_SERVER_URL: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_INSTANCE || '' }} - E2E_TEST_PYROSCOPE_KEY: ${{ matrix.tests.pyroscope_env != '' && secrets.QA_PYROSCOPE_KEY || '' }} - DATABASE_URL: postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable - with: - test_command_to_run: ${{ matrix.tests.test_cmd }} ${{ matrix.tests.test_cmd_opts || '2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false' }} - test_download_vendor_packages_command: make gomod - test_secrets_override_base64: ${{ secrets.TEST_SECRETS_OVERRIDE_BASE64 }} - test_config_override_path: ${{ env.TEST_CONFIG_OVERRIDE_PATH }} - test_type: ${{ matrix.tests.test_env_vars.TEST_TYPE }} - test_suite: ${{ matrix.tests.test_env_vars.TEST_SUITE }} - default_e2e_test_chainlink_image: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_IMAGE || env.CHAINLINK_IMAGE }} - default_e2e_test_chainlink_upgrade_image: ${{ matrix.tests.test_env_vars.E2E_TEST_CHAINLINK_UPGRADE_IMAGE }} - token: ${{ secrets.GH_TOKEN }} - should_cleanup: false - cache_key_id: e2e-tests - go_mod_path: ./integration-tests/go.mod - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - - name: Upload test log as artifact - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - if: inputs.test_log_upload_on_failure && failure() - with: - name: test_log_${{ env.TEST_ID }} - path: /tmp/gotest.log - retention-days: ${{ inputs.test_log_upload_retention_days }} - continue-on-error: true - - - name: Upload custom test artifacts - if: failure() && matrix.tests.test_artifacts_on_failure != '' - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - with: - name: custom_test_artifacts_${{ env.TEST_ID }}_${{ needs.load-test-configurations.outputs.workflow_id }} - path: ${{ matrix.tests.test_artifacts_on_failure }} - retention-days: 1 - - - name: Show Grafana url in test summary - if: always() - uses: smartcontractkit/.github/actions/ctf-show-grafana-in-test-summary@b6e37806737eef87e8c9137ceeb23ef0bff8b1db # ctf-show-grafana-in-test-summary@0.1.0 - - after_tests: - needs: [load-test-configurations, run-docker-tests, run-k8s-runner-tests] - if: always() - name: After tests - runs-on: ubuntu-latest - # Set to access secrets like secrets.QA_SLACK_API_KEY that are set in the "integration" environment - environment: integration - outputs: - test_results: ${{ steps.set_test_results.outputs.results }} - steps: - - name: Download all test result artifacts - uses: actions/download-artifact@9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395 # v4.1.6 - with: - path: test_results - pattern: test_result_${{ needs.load-test-configurations.outputs.workflow_id }}_* - - - name: Set detailed test results - id: set_test_results - run: | - if [ -d "test_results" ]; then - cd test_results - ls -R . - # Combine JSON files into one - find . -name '*.json' -exec cat {} + | jq -s '.' > test_results.json - # Display the combined JSON - jq . test_results.json - # Set the combined results as an output - echo "results=$(jq -c . test_results.json)" >> $GITHUB_OUTPUT - else - echo "No test results directory found." - echo "results=[]" >> $GITHUB_OUTPUT - fi - - - name: Set short SHA - id: set_short_sha - shell: bash - run: echo "short_sha=$(echo ${{ github.sha }} | cut -c1-7)" >> $GITHUB_OUTPUT - - - name: Send Slack notification - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - if: ${{ inputs.slack_notification_after_tests == 'true' || inputs.slack_notification_after_tests == 'always' || (inputs.slack_notification_after_tests == 'on_failure' && contains(join(needs.*.result, ','), 'failure')) }} - id: slack - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - with: - channel-id: ${{ inputs.slack_notification_after_tests_channel_id || secrets.SLACK_NOTIFICATION_AFTER_TESTS_CHANNEL_ID }} - payload: | - { - "attachments": [ - { - "color": "${{ contains(join(needs.*.result, ','), 'failure') && '#C62828' || contains(join(needs.*.result, ','), 'cancelled') && '#FFA000' || '2E7D32' }}", - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "${{ inputs.slack_notification_after_tests_name }} - ${{ contains(join(needs.*.result, ','), 'failure') && 'Failed :x:' || contains(join(needs.*.result, ','), 'cancelled') && 'Cancelled :warning:' || 'Passed :white_check_mark:' }}" - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "${{ github.ref_name }} | <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ steps.set_short_sha.outputs.short_sha }}> | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Details>" - } - } - ] - } - ] - } - - - name: Notify user in Slack message if tests failed - if: ${{ inputs.slack_notification_after_tests != '' && contains(join(needs.*.result, ','), 'failure') && inputs.slack_notification_after_tests_notify_user_id_on_failure != '' }} - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - with: - channel-id: ${{ inputs.slack_notification_after_tests_channel_id || secrets.SLACK_NOTIFICATION_AFTER_TESTS_CHANNEL_ID }} - payload: | - { - "thread_ts": "${{ steps.slack.outputs.thread_ts }}", - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "Notifying <@${{ inputs.slack_notification_after_tests_notify_user_id_on_failure }}>, please check the test results." - } - } - ] - } - - # Run K8s tests using new remote runner - # remote-runner-k8s-tests: - # runs-on: ubuntu-latest - # container: - # image: golang:1.18 - # steps: - # - name: Checkout repository - # uses: actions/checkout@v2 - - # - name: Set up Go - # uses: actions/setup-go@v2 - # with: - # go-version: '1.18' - - # - name: Load Runner Config - # run: echo "$RUNNER_CONFIG" > runner.toml - # env: - # RUNNER_CONFIG: | - # # Runner configuration - # detached_mode = true - # debug = false - - # [[test_runs]] - # namespace = "dev-env" - # rbac_role_name = "dev-role" - # rbac_service_account_name = "dev-service-account" - # sync_value = "unique-sync-value-1" - # ttl_seconds_after_finished = 300 - # image_registry_url = "https://myregistry.dev/" - # image_name = "dev-image" - # image_tag = "v1.0.0" - # test_name = "TestMercuryLoad/all_endpoints" - # test_config_base64_env_name = "CONFIG_ENV_DEV" - # test_config_file_path = "/configs/dev/test-config.toml" - # test_config_base64 = "dGVzdCBjb25maWcgdmFsdWUgZGV2" - # test_timeout = "30m" - # resources_requests_cpu = "500m" - # resources_requests_memory = "1Gi" - # resources_limits_cpu = "1000m" - # resources_limits_memory = "2Gi" - # job_count = 2 - # chart_path = "/charts/dev" - # [envs] - # WASP_LOG_LEVEL = "info" - # TEST_LOG_LEVEL = "info" - # MERCURY_TEST_LOG_LEVEL = "info" - - # [[test_runs]] - # namespace = "prod-env" - # rbac_role_name = "prod-role" - # rbac_service_account_name = "prod-service-account" - # sync_value = "unique-sync-value-2" - # ttl_seconds_after_finished = 600 - # image_registry_url = "https://myregistry.prod/" - # image_name = "prod-image" - # image_tag = "v1.0.1" - # test_name = "TestMercuryLoad/all_endpoints" - # test_config_base64_env_name = "CONFIG_ENV_PROD" - # test_config_file_path = "/configs/prod/test-config.toml" - # test_config_base64 = "dGVzdCBjb25maWcgdmFsdWUgcHJvZA==" - # test_timeout = "45m" - # resources_requests_cpu = "800m" - # resources_requests_memory = "2Gi" - # resources_limits_cpu = "1500m" - # resources_limits_memory = "4Gi" - # job_count = 3 - # chart_path = "/charts/prod" - # [envs] - # WASP_LOG_LEVEL = "info" - # TEST_LOG_LEVEL = "info" - # MERCURY_TEST_LOG_LEVEL = "info" - - # # Schedule the tests in K8s in remote runner - # - name: Run Kubernetes Tests - # run: go run ./cmd/main.go run -c runner.toml diff --git a/.github/workflows/run-nightly-e2e-tests.yml b/.github/workflows/run-nightly-e2e-tests.yml index 151217180b..671248b2ba 100644 --- a/.github/workflows/run-nightly-e2e-tests.yml +++ b/.github/workflows/run-nightly-e2e-tests.yml @@ -9,10 +9,11 @@ on: jobs: call-run-e2e-tests-workflow: name: Run E2E Tests - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: chainlink_version: develop - test_workflow: Nightly E2E Tests + test_path: .github/e2e-tests.yml + test_trigger: Nightly E2E Tests slack_notification_after_tests: true slack_notification_after_tests_channel_id: "#team-test-tooling-internal" slack_notification_after_tests_name: Nightly E2E Tests diff --git a/.github/workflows/run-selected-e2e-tests.yml b/.github/workflows/run-selected-e2e-tests.yml index 2ff3fbb979..e81d4f0d6d 100644 --- a/.github/workflows/run-selected-e2e-tests.yml +++ b/.github/workflows/run-selected-e2e-tests.yml @@ -20,11 +20,6 @@ on: description: 'Path to a test config file used to override the default test config' required: false type: string - enable_check_test_configurations: - description: 'Set to "true" to enable check-test-configurations job' - required: false - type: boolean - default: false with_existing_remote_runner_version: description: 'Use the existing remote runner version for k8s tests. Example: "d3bf5044af33e08be788a2df31c4a745cf69d787"' required: false @@ -40,14 +35,13 @@ run-name: ${{ inputs.workflow_run_name }} jobs: call-run-e2e-tests-workflow: name: Run E2E Tests - uses: ./.github/workflows/run-e2e-tests-reusable-workflow.yml + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@aad83f232743646faa35f5ac03ee3829148d37ce with: chainlink_version: ${{ github.event.inputs.chainlink_version }} + test_path: .github/e2e-tests.yml test_ids: ${{ github.event.inputs.test_ids }} test_config_override_path: ${{ github.event.inputs.test_config_override_path }} with_existing_remote_runner_version: ${{ github.event.inputs.with_existing_remote_runner_version }} - # Use fromJSON to convert string to boolean. More info: https://github.com/actions/runner/issues/2206#issuecomment-1532246677 - enable_check_test_configurations: ${{ fromJSON(github.event.inputs.enable_check_test_configurations) }} secrets: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} diff --git a/integration-tests/go.mod b/integration-tests/go.mod index ddf31828ff..af53c0538d 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -42,7 +42,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 - github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.9 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 8b11b1da71..ae8935211d 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1439,8 +1439,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202409 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8 h1:AdFXA2XxiU5uqLS4ZxA7v+RCz8mhqz2aCxgzbpnja98= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.9 h1:/2kAb6y854viKigkdFMWDNNbaz3zD0gAkbZoSHC8Rrg= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.9/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 96b9015a02..5a42e837ce 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 - github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.9 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 2ec777306d..e9e1d440ed 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1413,8 +1413,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202409 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 h1:mgjBQIEy+3V3G6K8e+6by3xndgsXdYYsdy+7kzQZwSk= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0/go.mod h1:pdIxrooP5CFGmC0p5NTOBiZAFtMw+5pTT4de5GY3ywA= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8 h1:AdFXA2XxiU5uqLS4ZxA7v+RCz8mhqz2aCxgzbpnja98= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.8/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.9 h1:/2kAb6y854viKigkdFMWDNNbaz3zD0gAkbZoSHC8Rrg= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.9/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= From 8b37da54ea01378db70caf02fb0aa45a18517f03 Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 24 Sep 2024 19:31:09 -0400 Subject: [PATCH 426/432] fixing make gomodtidy (#14555) --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 5cddebf4f1..12c2de7bc3 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -271,7 +271,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 58e2be3fae..015daa8ce4 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1081,8 +1081,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad h1:oEqKi71gr6Ldj8UKJuQOL70CHtNaoyR6pOFEyNgi6Z4= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 h1:f0vdqcOL9kJZwfmWE76roIyEuiZx/R82js0IfXNAvXg= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/go.mod b/go.mod index cda7516092..a79e7c8417 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 diff --git a/go.sum b/go.sum index 95195319df..901034e3af 100644 --- a/go.sum +++ b/go.sum @@ -1042,8 +1042,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad h1:oEqKi71gr6Ldj8UKJuQOL70CHtNaoyR6pOFEyNgi6Z4= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 h1:f0vdqcOL9kJZwfmWE76roIyEuiZx/R82js0IfXNAvXg= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index af53c0538d..a1a9ad15c4 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -39,7 +39,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240919155713-f4bf4ae0b9c6 github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.9 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index ae8935211d..d93f734738 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1423,8 +1423,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad h1:oEqKi71gr6Ldj8UKJuQOL70CHtNaoyR6pOFEyNgi6Z4= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 h1:f0vdqcOL9kJZwfmWE76roIyEuiZx/R82js0IfXNAvXg= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 5a42e837ce..402ed3afec 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -386,7 +386,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.23 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index e9e1d440ed..bd3ccf50a4 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1397,8 +1397,8 @@ github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnj github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad h1:oEqKi71gr6Ldj8UKJuQOL70CHtNaoyR6pOFEyNgi6Z4= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924070918-21dc2dadfdad/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 h1:f0vdqcOL9kJZwfmWE76roIyEuiZx/R82js0IfXNAvXg= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= From 3480f98690ff6dbf9e81b2a4eb120d0ac045cf77 Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Wed, 25 Sep 2024 12:20:05 +0400 Subject: [PATCH 427/432] reduce tests image size and build time (#14519) * reduce tests image size and reduce re-build time * address suggestions * resolve conflict --- integration-tests/test.Dockerfile | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/integration-tests/test.Dockerfile b/integration-tests/test.Dockerfile index 42e7de67c9..6252cfdd42 100644 --- a/integration-tests/test.Dockerfile +++ b/integration-tests/test.Dockerfile @@ -2,16 +2,26 @@ ARG BASE_IMAGE ARG IMAGE_VERSION=latest FROM ${BASE_IMAGE}:${IMAGE_VERSION} AS build-env -ARG SUITES=chaos migration performance reorg smoke soak benchmark load ccip-load - -COPY . testdir/ WORKDIR /go/testdir +RUN mkdir -p /go/testdir/integration-tests/load +COPY go.mod go.sum ./ +COPY integration-tests/go.mod integration-tests/go.sum ./integration-tests/ +COPY integration-tests/load/go.mod integration-tests/load/go.sum ./integration-tests/load/ +RUN cd integration-tests && go mod download +RUN cd integration-tests/load && go mod download + +COPY . . + +ARG SUITES=chaos soak benchmark load ccip-load + RUN /go/testdir/integration-tests/scripts/buildTests "${SUITES}" FROM ${BASE_IMAGE}:${IMAGE_VERSION} RUN mkdir -p /go/testdir/integration-tests/scripts -COPY --from=build-env /go/pkg /go/pkg +# Dependency of CosmWasm/wasmd +COPY --from=build-env /go/pkg/mod/github.com/\!cosm\!wasm/wasmvm@v*/internal/api/libwasmvm.*.so /usr/lib/ +RUN chmod 755 /usr/lib/libwasmvm.*.so COPY --from=build-env /go/testdir/integration-tests/*.test /go/testdir/integration-tests/ COPY --from=build-env /go/testdir/integration-tests/ccip-tests/*.test /go/testdir/integration-tests/ COPY --from=build-env /go/testdir/integration-tests/scripts /go/testdir/integration-tests/scripts/ From 6f6e6b459ebff7189c6996c174e34bb94d937608 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Wed, 25 Sep 2024 10:44:17 +0200 Subject: [PATCH 428/432] [TT-1678] Update changesets to new format (#14542) * try more universal Solidity scripts * fix error printing in uml generation; test foundry pipeline * Update gethwrappers * a bit more testing * fix Sol * remove test contracts * Update gethwrappers * try reusable artifact workflow * fix syntax * reuse workflow for .github/workflows * use newer reusable Solidity Review Artifacts pipeline * remove actions that were moved to chainlink-github-actions * add test Solidity file * add missing changeset * use scripts from shared repository * modify one contract * set git top level dir manually * [Bot] Update changeset file with jira issue * fix script path * use newer version of the reusable pipeline * update pipeline version, use custom pruning script * use newer action version, remove JIRA scripts * use reusable Solidity Review Artifacts workflow from .github * remove left over changes that are no longer needed * remove left over changes that are no longer needed * fix foundry pipeline * remove test Solidity files * use tagged reusable pipeline version * link PR to Solidity Review issue in Jira * update all references to .github to use tagged commit * test out the enforcement * remove extra changeset * [Bot] Update changeset file with jira issue * fix filename * test out empty changeset file * [Bot] Update changeset file with jira issues * use latest version of the action * remove changeset * fix condition in solidity tracability pipeline * add changeset * [Bot] Update changeset file with jira issues * fix message and condition for comment posting * test changesets in core * add changeset for core * update changeset format to reflect changes in how we add Jira issues related to PRs * use tagged jira-tracing version, restore changeset * fix missing changeset * add missing version comment * remove test-related changes * remove test-related changes --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .changeset/famous-plums-kiss.md | 2 ++ .changeset/lucky-zebras-reflect.md | 2 +- contracts/.changeset/few-parents-punch.md | 2 +- contracts/.changeset/fluffy-papayas-chew.md | 2 +- contracts/.changeset/forty-radios-brush.md | 2 +- contracts/.changeset/heavy-balloons-cheat.md | 2 +- contracts/.changeset/nasty-llamas-prove.md | 2 ++ contracts/.changeset/quick-olives-accept.md | 4 +++- contracts/.changeset/quiet-moles-retire.md | 2 +- 9 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.changeset/famous-plums-kiss.md b/.changeset/famous-plums-kiss.md index e884f0bceb..b5920b9834 100644 --- a/.changeset/famous-plums-kiss.md +++ b/.changeset/famous-plums-kiss.md @@ -3,3 +3,5 @@ --- #updated move latest capabilities code from ccip repo to chainlink repo [CCIP-2946] + +PR issue: CCIP-2946 diff --git a/.changeset/lucky-zebras-reflect.md b/.changeset/lucky-zebras-reflect.md index 2d4c875f64..0d06348a03 100644 --- a/.changeset/lucky-zebras-reflect.md +++ b/.changeset/lucky-zebras-reflect.md @@ -4,4 +4,4 @@ #internal Implement EVM ChainReader ValueComparator filtering by non-indexed event data. Right now only simple non indexed data where byte offsets don't exist is supported. -BCFR-203 \ No newline at end of file +PR issue: BCFR-203 diff --git a/contracts/.changeset/few-parents-punch.md b/contracts/.changeset/few-parents-punch.md index b8ea2dd2d3..88a885606b 100644 --- a/contracts/.changeset/few-parents-punch.md +++ b/contracts/.changeset/few-parents-punch.md @@ -5,4 +5,4 @@ update comments -SHIP-3557 \ No newline at end of file +PR issue: SHIP-3557 diff --git a/contracts/.changeset/fluffy-papayas-chew.md b/contracts/.changeset/fluffy-papayas-chew.md index b76e41cfbe..aa7b145e8f 100644 --- a/contracts/.changeset/fluffy-papayas-chew.md +++ b/contracts/.changeset/fluffy-papayas-chew.md @@ -5,4 +5,4 @@ #internal Change Chain Reader testing contract Triggered event for easier testing of filtering by non indexed evm data. -BCFR-203 \ No newline at end of file +PR issue: BCFR-203 diff --git a/contracts/.changeset/forty-radios-brush.md b/contracts/.changeset/forty-radios-brush.md index f7c251b9e5..5356ffedb1 100644 --- a/contracts/.changeset/forty-radios-brush.md +++ b/contracts/.changeset/forty-radios-brush.md @@ -5,4 +5,4 @@ Add Configurator contract -MERC-6185 \ No newline at end of file +PR issue: MERC-6185 diff --git a/contracts/.changeset/heavy-balloons-cheat.md b/contracts/.changeset/heavy-balloons-cheat.md index c0aedb266e..c0a39c5db7 100644 --- a/contracts/.changeset/heavy-balloons-cheat.md +++ b/contracts/.changeset/heavy-balloons-cheat.md @@ -6,4 +6,4 @@ #added Add ZKSync L2EP Validator contract -SHIP-3004 \ No newline at end of file +PR issue: SHIP-3004 diff --git a/contracts/.changeset/nasty-llamas-prove.md b/contracts/.changeset/nasty-llamas-prove.md index c3b26c9be3..dd34467680 100644 --- a/contracts/.changeset/nasty-llamas-prove.md +++ b/contracts/.changeset/nasty-llamas-prove.md @@ -3,3 +3,5 @@ --- DEVSVCS-147: add a reentrancy guard for balance monitor + +PR issue: DEVSVCS-147 diff --git a/contracts/.changeset/quick-olives-accept.md b/contracts/.changeset/quick-olives-accept.md index 92d69c1673..31c59983e4 100644 --- a/contracts/.changeset/quick-olives-accept.md +++ b/contracts/.changeset/quick-olives-accept.md @@ -2,4 +2,6 @@ '@chainlink/contracts': minor --- -#updated move latest ccip contracts code from ccip repo to chainlink repo [CCIP-2946] +#updated move latest ccip contracts code from ccip repo to chainlink repo + +PR issue: CCIP-2946 diff --git a/contracts/.changeset/quiet-moles-retire.md b/contracts/.changeset/quiet-moles-retire.md index f40eda6a0e..6351f36a16 100644 --- a/contracts/.changeset/quiet-moles-retire.md +++ b/contracts/.changeset/quiet-moles-retire.md @@ -5,4 +5,4 @@ Use reusable workflow for Solidity Artifacts pipeline, move some actions to chainlink-github-actions repository -TT-1693 \ No newline at end of file +PR issue: TT-1693 From 700dd7c074706b1a5fa89328876bdc4f3d39e025 Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Wed, 25 Sep 2024 10:41:55 +0100 Subject: [PATCH 429/432] add support for passing in the values.Values type into the contract readers GetLatestValue and QueryKey methods (#14488) --- .changeset/silly-zebras-exercise.md | 5 +++ core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/relay/evm/chain_reader.go | 54 ++++++++++++++++++++++++- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 10 files changed, 69 insertions(+), 14 deletions(-) create mode 100644 .changeset/silly-zebras-exercise.md diff --git a/.changeset/silly-zebras-exercise.md b/.changeset/silly-zebras-exercise.md new file mode 100644 index 0000000000..a0e6fc2869 --- /dev/null +++ b/.changeset/silly-zebras-exercise.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal add support for values.Value type in the contract reader GetLatestValue and QueryKey methods diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 12c2de7bc3..81501034ce 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.20.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 + github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7 github.com/spf13/cobra v1.8.1 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 015daa8ce4..08f3fb2b76 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1083,8 +1083,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 h1:f0vdqcOL9kJZwfmWE76roIyEuiZx/R82js0IfXNAvXg= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc h1:ALbyaoRzUSXQ2NhGFKVOyJqO22IB5yQjhjKWbIZGbrI= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc/go.mod h1:F6WUS6N4mP5ScwpwyTyAJc9/vjR+GXbMCRUOVekQi1g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= diff --git a/core/services/relay/evm/chain_reader.go b/core/services/relay/evm/chain_reader.go index 1446d730d7..8a770d4744 100644 --- a/core/services/relay/evm/chain_reader.go +++ b/core/services/relay/evm/chain_reader.go @@ -18,6 +18,7 @@ import ( commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + "github.com/smartcontractkit/chainlink-common/pkg/values" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -176,7 +177,28 @@ func (cr *chainReader) GetLatestValue(ctx context.Context, readName string, conf return err } - return binding.GetLatestValue(ctx, common.HexToAddress(address), confidenceLevel, params, returnVal) + ptrToValue, isValue := returnVal.(*values.Value) + if !isValue { + return binding.GetLatestValue(ctx, common.HexToAddress(address), confidenceLevel, params, returnVal) + } + + contractType, err := cr.CreateContractType(readName, false) + if err != nil { + return err + } + + if err = cr.GetLatestValue(ctx, readName, confidenceLevel, params, contractType); err != nil { + return err + } + + value, err := values.Wrap(contractType) + if err != nil { + return err + } + + *ptrToValue = value + + return nil } func (cr *chainReader) BatchGetLatestValues(ctx context.Context, request commontypes.BatchGetLatestValuesRequest) (commontypes.BatchGetLatestValuesResult, error) { @@ -195,7 +217,35 @@ func (cr *chainReader) QueryKey( return nil, err } - return binding.QueryKey(ctx, common.HexToAddress(address), filter, limitAndSort, sequenceDataType) + _, isValuePtr := sequenceDataType.(*values.Value) + if !isValuePtr { + return binding.QueryKey(ctx, common.HexToAddress(address), filter, limitAndSort, sequenceDataType) + } + + dataTypeFromReadIdentifier, err := cr.CreateContractType(contract.ReadIdentifier(filter.Key), false) + if err != nil { + return nil, err + } + + sequence, err := binding.QueryKey(ctx, common.HexToAddress(address), filter, limitAndSort, dataTypeFromReadIdentifier) + if err != nil { + return nil, err + } + + sequenceOfValues := make([]commontypes.Sequence, len(sequence)) + for idx, entry := range sequence { + value, err := values.Wrap(entry.Data) + if err != nil { + return nil, err + } + sequenceOfValues[idx] = commontypes.Sequence{ + Cursor: entry.Cursor, + Head: entry.Head, + Data: &value, + } + } + + return sequenceOfValues, nil } func (cr *chainReader) CreateContractType(readIdentifier string, forEncoding bool) (any, error) { diff --git a/go.mod b/go.mod index a79e7c8417..53633f263b 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 - github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 + github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f diff --git a/go.sum b/go.sum index 901034e3af..166b268a80 100644 --- a/go.sum +++ b/go.sum @@ -1044,8 +1044,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 h1:f0vdqcOL9kJZwfmWE76roIyEuiZx/R82js0IfXNAvXg= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc h1:ALbyaoRzUSXQ2NhGFKVOyJqO22IB5yQjhjKWbIZGbrI= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc/go.mod h1:F6WUS6N4mP5ScwpwyTyAJc9/vjR+GXbMCRUOVekQi1g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index a1a9ad15c4..5eeb68f773 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -40,7 +40,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.23 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 - github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 + github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.9 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index d93f734738..0a8d40353b 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1425,8 +1425,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 h1:f0vdqcOL9kJZwfmWE76roIyEuiZx/R82js0IfXNAvXg= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc h1:ALbyaoRzUSXQ2NhGFKVOyJqO22IB5yQjhjKWbIZGbrI= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc/go.mod h1:F6WUS6N4mP5ScwpwyTyAJc9/vjR+GXbMCRUOVekQi1g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 402ed3afec..7fc07069d5 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -15,7 +15,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.12.2 - github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 + github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.9 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.1 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.0 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index bd3ccf50a4..0715c672cf 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1399,8 +1399,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 h1:f0vdqcOL9kJZwfmWE76roIyEuiZx/R82js0IfXNAvXg= github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420 h1:+xNnYYgkxzKUIkLCOfzfAKUxeLLtuxlalDI70kNJ8No= -github.com/smartcontractkit/chainlink-common v0.2.3-0.20240919092417-53e784c2e420/go.mod h1:zm+l8gN4LQS1+YvwQDhRz/njirVeWGNiDJKIhCGwaoQ= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc h1:ALbyaoRzUSXQ2NhGFKVOyJqO22IB5yQjhjKWbIZGbrI= +github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc/go.mod h1:F6WUS6N4mP5ScwpwyTyAJc9/vjR+GXbMCRUOVekQi1g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q= From c4fa565f5441bfa997907256e1990f9be276934d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Wed, 25 Sep 2024 16:28:32 +0300 Subject: [PATCH 430/432] Change KeystoneForwarder routing gas accounting (#14543) * Add additional tests with malicious receivers * Fix capability type * Fix lint errors * Add changesets * Make go lint happy * Additional improvements to forwarder gas accounting * Undo forwarder logic constant change * Update gethwrappers * Use the right variable * Update gethwrappers --------- Co-authored-by: app-token-issuer-infra-releng[bot] <120227048+app-token-issuer-infra-releng[bot]@users.noreply.github.com> --- .changeset/long-balloons-hunt.md | 5 +++ contracts/.changeset/proud-pears-tie.md | 5 +++ .../src/v0.8/keystone/KeystoneForwarder.sol | 22 +++++++---- .../test/KeystoneForwarder_ReportTest.t.sol | 37 ++++++++++++++++++- .../test/mocks/MaliciousReportReceiver.sol | 23 ++++++++++++ .../test/mocks/MaliciousRevertingReceiver.sol | 24 ++++++++++++ core/capabilities/targets/write_target.go | 8 ++-- .../keystone/generated/forwarder/forwarder.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 9 files changed, 114 insertions(+), 14 deletions(-) create mode 100644 .changeset/long-balloons-hunt.md create mode 100644 contracts/.changeset/proud-pears-tie.md create mode 100644 contracts/src/v0.8/keystone/test/mocks/MaliciousReportReceiver.sol create mode 100644 contracts/src/v0.8/keystone/test/mocks/MaliciousRevertingReceiver.sol diff --git a/.changeset/long-balloons-hunt.md b/.changeset/long-balloons-hunt.md new file mode 100644 index 0000000000..0408383bd0 --- /dev/null +++ b/.changeset/long-balloons-hunt.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal diff --git a/contracts/.changeset/proud-pears-tie.md b/contracts/.changeset/proud-pears-tie.md new file mode 100644 index 0000000000..93fba83b55 --- /dev/null +++ b/contracts/.changeset/proud-pears-tie.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +#internal diff --git a/contracts/src/v0.8/keystone/KeystoneForwarder.sol b/contracts/src/v0.8/keystone/KeystoneForwarder.sol index 3fb85b0fb7..c4511124cd 100644 --- a/contracts/src/v0.8/keystone/KeystoneForwarder.sol +++ b/contracts/src/v0.8/keystone/KeystoneForwarder.sol @@ -108,9 +108,15 @@ contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { uint256 internal constant FORWARDER_METADATA_LENGTH = 45; uint256 internal constant SIGNATURE_LENGTH = 65; - /// @dev The gas we require to revert in case of a revert in the call to the - /// receiver. This is more than enough and does not attempt to be exact. - uint256 internal constant REQUIRED_GAS_FOR_ROUTING = 60_000; + /// @dev This is the gas required to store `success` after the report is processed. + /// It is a warm storage write because of the packed struct. In practice it will cost less. + uint256 internal constant INTERNAL_GAS_REQUIREMENTS_AFTER_REPORT = 5_000; + /// @dev This is the gas required to store the transmission struct and perform other checks. + uint256 internal constant INTERNAL_GAS_REQUIREMENTS = 25_000 + INTERNAL_GAS_REQUIREMENTS_AFTER_REPORT; + /// @dev This is the minimum gas required to route a report. This includes internal gas requirements + /// as well as the minimum gas that the user contract will receive. 30k * 3 gas is to account for + /// cases where consumers need close to the 30k limit provided in the supportsInterface check. + uint256 internal constant MINIMUM_GAS_LIMIT = INTERNAL_GAS_REQUIREMENTS + 30_000 * 3 + 10_000; // ================================================================ // │ Router │ @@ -137,16 +143,17 @@ contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { bytes calldata validatedReport ) public returns (bool) { if (!s_forwarders[msg.sender]) revert UnauthorizedForwarder(); - uint256 gasLeft = gasleft(); - if (gasLeft < REQUIRED_GAS_FOR_ROUTING) revert InsufficientGasForRouting(transmissionId); + + uint256 gasLimit = gasleft() - INTERNAL_GAS_REQUIREMENTS; + if (gasLimit < MINIMUM_GAS_LIMIT) revert InsufficientGasForRouting(transmissionId); Transmission memory transmission = s_transmissions[transmissionId]; if (transmission.success || transmission.invalidReceiver) revert AlreadyAttempted(transmissionId); - uint256 gasLimit = gasLeft - REQUIRED_GAS_FOR_ROUTING; s_transmissions[transmissionId].transmitter = transmitter; s_transmissions[transmissionId].gasLimit = uint80(gasLimit); + // This call can consume up to 90k gas. if (!ERC165Checker.supportsInterface(receiver, type(IReceiver).interfaceId)) { s_transmissions[transmissionId].invalidReceiver = true; return false; @@ -155,10 +162,11 @@ contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { bool success; bytes memory payload = abi.encodeCall(IReceiver.onReport, (metadata, validatedReport)); + uint256 remainingGas = gasleft() - INTERNAL_GAS_REQUIREMENTS_AFTER_REPORT; assembly { // call and return whether we succeeded. ignore return data // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) - success := call(gasLimit, receiver, 0, add(payload, 0x20), mload(payload), 0x0, 0x0) + success := call(remainingGas, receiver, 0, add(payload, 0x20), mload(payload), 0x0, 0x0) } if (success) { diff --git a/contracts/src/v0.8/keystone/test/KeystoneForwarder_ReportTest.t.sol b/contracts/src/v0.8/keystone/test/KeystoneForwarder_ReportTest.t.sol index 5363d87e92..7751aa40a6 100644 --- a/contracts/src/v0.8/keystone/test/KeystoneForwarder_ReportTest.t.sol +++ b/contracts/src/v0.8/keystone/test/KeystoneForwarder_ReportTest.t.sol @@ -3,7 +3,10 @@ pragma solidity 0.8.24; import {BaseTest} from "./KeystoneForwarderBaseTest.t.sol"; import {IRouter} from "../interfaces/IRouter.sol"; +import {MaliciousReportReceiver} from "./mocks/MaliciousReportReceiver.sol"; +import {MaliciousRevertingReceiver} from "./mocks/MaliciousRevertingReceiver.sol"; import {KeystoneForwarder} from "../KeystoneForwarder.sol"; +import {console} from "forge-std/console.sol"; contract KeystoneForwarder_ReportTest is BaseTest { event MessageReceived(bytes metadata, bytes[] mercuryReports); @@ -164,7 +167,7 @@ contract KeystoneForwarder_ReportTest is BaseTest { function test_RevertWhen_AttemptingTransmissionWithInsufficientGas() public { bytes32 transmissionId = s_forwarder.getTransmissionId(address(s_receiver), executionId, reportId); vm.expectRevert(abi.encodeWithSelector(IRouter.InsufficientGasForRouting.selector, transmissionId)); - s_forwarder.report{gas: 50_000}(address(s_receiver), report, reportContext, signatures); + s_forwarder.report{gas: 150_000}(address(s_receiver), report, reportContext, signatures); } function test_Report_SuccessfulDelivery() public { @@ -236,6 +239,38 @@ contract KeystoneForwarder_ReportTest is BaseTest { assertEq(uint8(transmissionInfo.state), uint8(IRouter.TransmissionState.INVALID_RECEIVER), "state mismatch"); } + function test_Report_FailedDeliveryWhenReportReceiverConsumesAllGasAndInterfaceCheckUsesMax() public { + MaliciousRevertingReceiver maliciousReceiver = new MaliciousRevertingReceiver(); + // This should not revert if gas tracking is effective + // It may revert if it fails to reserve sufficient gas for routing + // This POC requires pretty specific initial gas, so that 1/64 of gas passed to `onReport()` is insufficient to store the success + s_forwarder.report{gas: 200_000}(address(maliciousReceiver), report, reportContext, signatures); + + IRouter.TransmissionInfo memory transmissionInfo = s_forwarder.getTransmissionInfo( + address(maliciousReceiver), + executionId, + reportId + ); + + assertEq(transmissionInfo.transmitter, TRANSMITTER, "transmitter mismatch"); + assertEq(uint8(transmissionInfo.state), uint8(IRouter.TransmissionState.SUCCEEDED), "state mismatch"); + } + + function test_Report_FailedDelieryWhenReportReceiverConsumesAllGas() public { + MaliciousReportReceiver s_maliciousReceiver = new MaliciousReportReceiver(); + s_forwarder.report{gas: 500_000}(address(s_maliciousReceiver), report, reportContext, signatures); + + IRouter.TransmissionInfo memory transmissionInfo = s_forwarder.getTransmissionInfo( + address(s_maliciousReceiver), + executionId, + reportId + ); + + assertEq(transmissionInfo.transmitter, TRANSMITTER, "transmitter mismatch"); + assertEq(uint8(transmissionInfo.state), uint8(IRouter.TransmissionState.FAILED), "state mismatch"); + assertGt(transmissionInfo.gasLimit, 410_000, "gas limit mismatch"); + } + function test_Report_ConfigVersion() public { vm.stopPrank(); // configure a new configVersion diff --git a/contracts/src/v0.8/keystone/test/mocks/MaliciousReportReceiver.sol b/contracts/src/v0.8/keystone/test/mocks/MaliciousReportReceiver.sol new file mode 100644 index 0000000000..ac203cccf6 --- /dev/null +++ b/contracts/src/v0.8/keystone/test/mocks/MaliciousReportReceiver.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {IReceiver} from "../../interfaces/IReceiver.sol"; + +contract MaliciousReportReceiver is IReceiver, IERC165 { + event MessageReceived(bytes metadata, bytes[] mercuryReports); + bytes public latestReport; + + function onReport(bytes calldata metadata, bytes calldata rawReport) external { + // Exhaust all gas that was provided + for (uint256 i = 0; i < 1_000_000_000; i++) { + bytes[] memory mercuryReports = abi.decode(rawReport, (bytes[])); + latestReport = rawReport; + emit MessageReceived(metadata, mercuryReports); + } + } + + function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { + return interfaceId == type(IReceiver).interfaceId || interfaceId == type(IERC165).interfaceId; + } +} diff --git a/contracts/src/v0.8/keystone/test/mocks/MaliciousRevertingReceiver.sol b/contracts/src/v0.8/keystone/test/mocks/MaliciousRevertingReceiver.sol new file mode 100644 index 0000000000..3efb5d89cc --- /dev/null +++ b/contracts/src/v0.8/keystone/test/mocks/MaliciousRevertingReceiver.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {IReceiver} from "../../interfaces/IReceiver.sol"; +import {Test} from "forge-std/Test.sol"; + +/// A malicious receiver that uses max allowed for ERC165 checks and consumes all gas in `onReport()` +/// Causes parent Forwarder contract to revert if it doesn't handle gas tracking accurately +contract MaliciousRevertingReceiver is IReceiver, IERC165, Test { + function onReport(bytes calldata, bytes calldata) external view override { + // consumes about 63/64 of all gas available + uint256 targetGasRemaining = 200; + for (uint256 i = 0; gasleft() > targetGasRemaining; i++) {} + } + + function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { + // Consume up to the maximum amount of gas that can be consumed in this check + // This loop consumes roughly 29_000 gas + for (uint256 i = 0; i < 670; i++) {} + + return interfaceId == type(IReceiver).interfaceId || interfaceId == type(IERC165).interfaceId; + } +} diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index 85c8011410..0e0b207182 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -19,7 +19,7 @@ import ( ) var ( - _ capabilities.ActionCapability = &WriteTarget{} + _ capabilities.TargetCapability = &WriteTarget{} ) type WriteTarget struct { @@ -48,7 +48,7 @@ type TransmissionInfo struct { // The gas cost of the forwarder contract logic, including state updates and event emission. // This is a rough estimate and should be updated if the forwarder contract logic changes. // TODO: Make this part of the on-chain capability configuration -const FORWARDER_CONTRACT_LOGIC_GAS_COST = 100_000 +const ForwarderContractLogicGasCost = 100_000 type ContractValueGetter interface { Bind(context.Context, []commontypes.BoundContract) error @@ -77,7 +77,7 @@ func NewWriteTarget( Name: "forwarder", }, forwarderAddress, - txGasLimit - FORWARDER_CONTRACT_LOGIC_GAS_COST, + txGasLimit - ForwarderContractLogicGasCost, info, logger.Named(lggr, "WriteTarget"), false, @@ -252,7 +252,7 @@ func (cap *WriteTarget) Execute(ctx context.Context, rawRequest capabilities.Cap case transmissionInfo.State == 3: // FAILED receiverGasMinimum := cap.receiverGasMinimum if request.Config.GasLimit != nil { - receiverGasMinimum = *request.Config.GasLimit - FORWARDER_CONTRACT_LOGIC_GAS_COST + receiverGasMinimum = *request.Config.GasLimit - ForwarderContractLogicGasCost } if transmissionInfo.GasLimit.Uint64() > receiverGasMinimum { cap.lggr.Infow("returning without a transmission attempt - transmission already attempted and failed, sufficient gas was provided", "executionID", request.Metadata.WorkflowExecutionID, "receiverGasMinimum", receiverGasMinimum, "transmissionGasLimit", transmissionInfo.GasLimit) diff --git a/core/gethwrappers/keystone/generated/forwarder/forwarder.go b/core/gethwrappers/keystone/generated/forwarder/forwarder.go index 37340c8137..5c95cfef2b 100644 --- a/core/gethwrappers/keystone/generated/forwarder/forwarder.go +++ b/core/gethwrappers/keystone/generated/forwarder/forwarder.go @@ -41,7 +41,7 @@ type IRouterTransmissionInfo struct { var KeystoneForwarderMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"DuplicateSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"}],\"name\":\"InsufficientGasForRouting\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"configId\",\"type\":\"uint64\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"received\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedForwarder\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"ForwarderAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"ForwarderRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"result\",\"type\":\"bool\"}],\"name\":\"ReportProcessed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"addForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"}],\"name\":\"clearConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmissionId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmissionInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"},{\"internalType\":\"enumIRouter.TransmissionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"invalidReceiver\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint80\",\"name\":\"gasLimit\",\"type\":\"uint80\"}],\"internalType\":\"structIRouter.TransmissionInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes2\",\"name\":\"reportId\",\"type\":\"bytes2\"}],\"name\":\"getTransmitter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"isForwarder\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"removeForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"reportContext\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"signatures\",\"type\":\"bytes[]\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"transmissionId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"validatedReport\",\"type\":\"bytes\"}],\"name\":\"route\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"configVersion\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000bf565b5050306000908152600360205260409020805460ff19166001179055506200016a565b336001600160a01b03821603620001195760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b612150806200017a6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379ba50971161008c578063abcef55411610066578063abcef5541461035d578063ee59d26c14610396578063ef6e17a0146103a9578063f2fde38b146103bc57600080fd5b806379ba50971461025e5780638864b864146102665780638da5cb5b1461033f57600080fd5b8063272cbd93116100c8578063272cbd9314610179578063354bdd66146101995780634d93172d146102385780635c41d2fe1461024b57600080fd5b806311289565146100ef578063181f5a7714610104578063233fd52d14610156575b600080fd5b6101026100fd3660046119f4565b6103cf565b005b6101406040518060400160405280601a81526020017f466f7277617264657220616e6420526f7574657220312e302e3000000000000081525081565b60405161014d9190611a9f565b60405180910390f35b610169610164366004611b0c565b610989565b604051901515815260200161014d565b61018c610187366004611b94565b610d0b565b60405161014d9190611c28565b61022a6101a7366004611b94565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018390527fffff000000000000000000000000000000000000000000000000000000000000821660548201526000906056016040516020818303038152906040528051906020012090509392505050565b60405190815260200161014d565b610102610246366004611cd0565b610f11565b610102610259366004611cd0565b610f8d565b61010261100c565b61031a610274366004611b94565b6040805160609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660208086019190915260348501939093527fffff000000000000000000000000000000000000000000000000000000000000919091166054840152805160368185030181526056909301815282519282019290922060009081526004909152205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014d565b60005473ffffffffffffffffffffffffffffffffffffffff1661031a565b61016961036b366004611cd0565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6101026103a4366004611cff565b611109565b6101026103b7366004611d7d565b6114e6565b6101026103ca366004611cd0565b611586565b606d85101561040a576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600061044e89898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061159a92505050565b67ffffffffffffffff8216600090815260026020526040812080549497509195509193509160ff16908190036104c1576040517fdf3b81ea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b856104cd826001611ddf565b60ff161461051f576104e0816001611ddf565b6040517fd6022e8e00000000000000000000000000000000000000000000000000000000815260ff9091166004820152602481018790526044016104b8565b60008b8b604051610531929190611df8565b60405190819003812061054a918c908c90602001611e08565b60405160208183030381529060405280519060200120905061056a611881565b60005b888110156107ec573660008b8b8481811061058a5761058a611e22565b905060200281019061059c9190611e51565b9092509050604181146105df5781816040517f2adfdc300000000000000000000000000000000000000000000000000000000081526004016104b8929190611eff565b6000600186848460408181106105f7576105f7611e22565b61060992013560f81c9050601b611ddf565b610617602060008789611f1b565b61062091611f45565b61062e60406020888a611f1b565b61063791611f45565b6040805160008152602081018083529590955260ff909316928401929092526060830152608082015260a0016020604051602081039080840390855afa158015610685573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8116600090815260028c0160205291822054909350915081900361072b576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b600086826020811061073f5761073f611e22565b602002015173ffffffffffffffffffffffffffffffffffffffff16146107a9576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b818682602081106107bc576107bc611e22565b73ffffffffffffffffffffffffffffffffffffffff909216602092909202015250506001909201915061056d9050565b50506040805160608f901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602080830191909152603482018990527fffff0000000000000000000000000000000000000000000000000000000000008816605483015282516036818403018152605690920190925280519101206000945030935063233fd52d92509050338d8d8d602d90606d9261088e93929190611f1b565b8f8f606d9080926108a193929190611f1b565b6040518863ffffffff1660e01b81526004016108c39796959493929190611f81565b6020604051808303816000875af11580156108e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109069190611fe2565b9050817dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916838b73ffffffffffffffffffffffffffffffffffffffff167f3617b009e9785c42daebadb6d3fb553243a4bf586d07ea72d65d80013ce116b584604051610975911515815260200190565b60405180910390a450505050505050505050565b3360009081526003602052604081205460ff166109d2576040517fd79e123d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005a905061ea60811015610a16576040517f0bfecd63000000000000000000000000000000000000000000000000000000008152600481018a90526024016104b8565b6000898152600460209081526040918290208251608081018452905473ffffffffffffffffffffffffffffffffffffffff8116825274010000000000000000000000000000000000000000810460ff90811615159383019390935275010000000000000000000000000000000000000000008104909216151592810183905276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660608201529080610ace575080602001515b15610b08576040517fa53dc8ca000000000000000000000000000000000000000000000000000000008152600481018b90526024016104b8565b6000610b1661ea608461200b565b60008c8152600460205260409020805469ffffffffffffffffffff83167601000000000000000000000000000000000000000000000275ffff000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff8e16171790559050610bad897f805f2132000000000000000000000000000000000000000000000000000000006115b5565b610c0657505050600088815260046020526040812080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790559050610d00565b60008089898989604051602401610c20949392919061201e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f805f21320000000000000000000000000000000000000000000000000000000017815281519192506000918291828f88f191508115610cf95760008d815260046020526040902080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b5093505050505b979650505050505050565b6040805160c0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905284519088901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001681830152603481018790527fffff000000000000000000000000000000000000000000000000000000000000861660548201528451603681830301815260568201808752815191840191909120808552600490935285842060d68301909652945473ffffffffffffffffffffffffffffffffffffffff811680875274010000000000000000000000000000000000000000820460ff9081161515607685015275010000000000000000000000000000000000000000008304161515609684015276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660b69092019190915292939092909190610e6957506000610e91565b816020015115610e7b57506002610e91565b8160400151610e8b576003610e8e565b60015b90505b6040518060c00160405280848152602001826003811115610eb457610eb4611bf9565b8152602001836000015173ffffffffffffffffffffffffffffffffffffffff168152602001836020015115158152602001836040015115158152602001836060015169ffffffffffffffffffff1681525093505050509392505050565b610f196115da565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fb96d15bf9258c7b8df062753a6a262864611fc7b060a5ee2e57e79b85f898d389190a250565b610f956115da565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f0ea0ce2c048ff45a4a95f2947879de3fb94abec2f152190400cab2d1272a68e79190a250565b60015473ffffffffffffffffffffffffffffffffffffffff16331461108d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016104b8565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6111116115da565b8260ff1660000361114e576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f811115611193576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101829052601f60248201526044016104b8565b61119e836003612045565b60ff1681116111fc57806111b3846003612045565b6111be906001611ddf565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260ff1660248201526044016104b8565b67ffffffff00000000602086901b1663ffffffff85161760005b67ffffffffffffffff82166000908152600260205260409020600101548110156112ac5767ffffffffffffffff821660009081526002602081905260408220600181018054919092019291908490811061127257611272611e22565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812055600101611216565b5060005b828110156114285760008484838181106112cc576112cc611e22565b90506020020160208101906112e19190611cd0565b905073ffffffffffffffffffffffffffffffffffffffff8116611348576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b67ffffffffffffffff8316600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff861685529092019052902054156113d4576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b6113df826001612061565b67ffffffffffffffff8416600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff909616845294909101905291909120556001016112b0565b5067ffffffffffffffff811660009081526002602052604090206114509060010184846118a0565b5067ffffffffffffffff81166000908152600260205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff87161790555163ffffffff86811691908816907f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a455906114d690889088908890612074565b60405180910390a3505050505050565b6114ee6115da565b63ffffffff818116602084811b67ffffffff00000000168217600090815260028252604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558051828152928301905291928516917f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a4559160405161157a9291906120da565b60405180910390a35050565b61158e6115da565b6115978161165d565b50565b60218101516045820151608b90920151909260c09290921c91565b60006115c083611752565b80156115d157506115d183836117b6565b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104b8565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036116dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104b8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061177e827f01ffc9a7000000000000000000000000000000000000000000000000000000006117b6565b80156115d457506117af827fffffffff000000000000000000000000000000000000000000000000000000006117b6565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561186e575060208210155b8015610d00575015159695505050505050565b6040518061040001604052806020906020820280368337509192915050565b828054828255906000526020600020908101928215611918579160200282015b828111156119185781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8435161782556020909201916001909101906118c0565b50611924929150611928565b5090565b5b808211156119245760008155600101611929565b803573ffffffffffffffffffffffffffffffffffffffff8116811461196157600080fd5b919050565b60008083601f84011261197857600080fd5b50813567ffffffffffffffff81111561199057600080fd5b6020830191508360208285010111156119a857600080fd5b9250929050565b60008083601f8401126119c157600080fd5b50813567ffffffffffffffff8111156119d957600080fd5b6020830191508360208260051b85010111156119a857600080fd5b60008060008060008060006080888a031215611a0f57600080fd5b611a188861193d565b9650602088013567ffffffffffffffff80821115611a3557600080fd5b611a418b838c01611966565b909850965060408a0135915080821115611a5a57600080fd5b611a668b838c01611966565b909650945060608a0135915080821115611a7f57600080fd5b50611a8c8a828b016119af565b989b979a50959850939692959293505050565b60006020808352835180602085015260005b81811015611acd57858101830151858201604001528201611ab1565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600080600080600080600060a0888a031215611b2757600080fd5b87359650611b376020890161193d565b9550611b456040890161193d565b9450606088013567ffffffffffffffff80821115611b6257600080fd5b611b6e8b838c01611966565b909650945060808a0135915080821115611b8757600080fd5b50611a8c8a828b01611966565b600080600060608486031215611ba957600080fd5b611bb28461193d565b92506020840135915060408401357fffff00000000000000000000000000000000000000000000000000000000000081168114611bee57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81518152602082015160c082019060048110611c6d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8060208401525073ffffffffffffffffffffffffffffffffffffffff604084015116604083015260608301511515606083015260808301511515608083015260a0830151611cc960a084018269ffffffffffffffffffff169052565b5092915050565b600060208284031215611ce257600080fd5b6115d18261193d565b803563ffffffff8116811461196157600080fd5b600080600080600060808688031215611d1757600080fd5b611d2086611ceb565b9450611d2e60208701611ceb565b9350604086013560ff81168114611d4457600080fd5b9250606086013567ffffffffffffffff811115611d6057600080fd5b611d6c888289016119af565b969995985093965092949392505050565b60008060408385031215611d9057600080fd5b611d9983611ceb565b9150611da760208401611ceb565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff81811683821601908111156115d4576115d4611db0565b8183823760009101908152919050565b838152818360208301376000910160200190815292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611e8657600080fd5b83018035915067ffffffffffffffff821115611ea157600080fd5b6020019150368190038213156119a857600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000611f13602083018486611eb6565b949350505050565b60008085851115611f2b57600080fd5b83861115611f3857600080fd5b5050820193919092039150565b803560208310156115d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525060a06060830152611fc160a083018688611eb6565b8281036080840152611fd4818587611eb6565b9a9950505050505050505050565b600060208284031215611ff457600080fd5b8151801515811461200457600080fd5b9392505050565b818103818111156115d4576115d4611db0565b604081526000612032604083018688611eb6565b8281036020840152610d00818587611eb6565b60ff8181168382160290811690818114611cc957611cc9611db0565b808201808211156115d4576115d4611db0565b60ff8416815260406020808301829052908201839052600090849060608401835b868110156120ce5773ffffffffffffffffffffffffffffffffffffffff6120bb8561193d565b1682529282019290820190600101612095565b50979650505050505050565b60006040820160ff8516835260206040602085015281855180845260608601915060208701935060005b8181101561213657845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101612104565b509097965050505050505056fea164736f6c6343000818000a", + Bin: "0x60806040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000bf565b5050306000908152600360205260409020805460ff19166001179055506200016a565b336001600160a01b03821603620001195760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61218f806200017a6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379ba50971161008c578063abcef55411610066578063abcef5541461035d578063ee59d26c14610396578063ef6e17a0146103a9578063f2fde38b146103bc57600080fd5b806379ba50971461025e5780638864b864146102665780638da5cb5b1461033f57600080fd5b8063272cbd93116100c8578063272cbd9314610179578063354bdd66146101995780634d93172d146102385780635c41d2fe1461024b57600080fd5b806311289565146100ef578063181f5a7714610104578063233fd52d14610156575b600080fd5b6101026100fd366004611a33565b6103cf565b005b6101406040518060400160405280601a81526020017f466f7277617264657220616e6420526f7574657220312e302e3000000000000081525081565b60405161014d9190611ade565b60405180910390f35b610169610164366004611b4b565b610989565b604051901515815260200161014d565b61018c610187366004611bd3565b610d4a565b60405161014d9190611c67565b61022a6101a7366004611bd3565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018390527fffff000000000000000000000000000000000000000000000000000000000000821660548201526000906056016040516020818303038152906040528051906020012090509392505050565b60405190815260200161014d565b610102610246366004611d0f565b610f50565b610102610259366004611d0f565b610fcc565b61010261104b565b61031a610274366004611bd3565b6040805160609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660208086019190915260348501939093527fffff000000000000000000000000000000000000000000000000000000000000919091166054840152805160368185030181526056909301815282519282019290922060009081526004909152205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014d565b60005473ffffffffffffffffffffffffffffffffffffffff1661031a565b61016961036b366004611d0f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6101026103a4366004611d3e565b611148565b6101026103b7366004611dbc565b611525565b6101026103ca366004611d0f565b6115c5565b606d85101561040a576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600061044e89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115d992505050565b67ffffffffffffffff8216600090815260026020526040812080549497509195509193509160ff16908190036104c1576040517fdf3b81ea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b856104cd826001611e1e565b60ff161461051f576104e0816001611e1e565b6040517fd6022e8e00000000000000000000000000000000000000000000000000000000815260ff9091166004820152602481018790526044016104b8565b60008b8b604051610531929190611e37565b60405190819003812061054a918c908c90602001611e47565b60405160208183030381529060405280519060200120905061056a6118c0565b60005b888110156107ec573660008b8b8481811061058a5761058a611e61565b905060200281019061059c9190611e90565b9092509050604181146105df5781816040517f2adfdc300000000000000000000000000000000000000000000000000000000081526004016104b8929190611f3e565b6000600186848460408181106105f7576105f7611e61565b61060992013560f81c9050601b611e1e565b610617602060008789611f5a565b61062091611f84565b61062e60406020888a611f5a565b61063791611f84565b6040805160008152602081018083529590955260ff909316928401929092526060830152608082015260a0016020604051602081039080840390855afa158015610685573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8116600090815260028c0160205291822054909350915081900361072b576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b600086826020811061073f5761073f611e61565b602002015173ffffffffffffffffffffffffffffffffffffffff16146107a9576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b818682602081106107bc576107bc611e61565b73ffffffffffffffffffffffffffffffffffffffff909216602092909202015250506001909201915061056d9050565b50506040805160608f901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602080830191909152603482018990527fffff0000000000000000000000000000000000000000000000000000000000008816605483015282516036818403018152605690920190925280519101206000945030935063233fd52d92509050338d8d8d602d90606d9261088e93929190611f5a565b8f8f606d9080926108a193929190611f5a565b6040518863ffffffff1660e01b81526004016108c39796959493929190611fc0565b6020604051808303816000875af11580156108e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109069190612021565b9050817dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916838b73ffffffffffffffffffffffffffffffffffffffff167f3617b009e9785c42daebadb6d3fb553243a4bf586d07ea72d65d80013ce116b584604051610975911515815260200190565b60405180910390a450505050505050505050565b3360009081526003602052604081205460ff166109d2576040517fd79e123d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109e26113886161a861204a565b5a6109ed919061205d565b90506109fd6113886161a861204a565b610a0a9062015f9061204a565b610a169061271061204a565b811015610a52576040517f0bfecd63000000000000000000000000000000000000000000000000000000008152600481018a90526024016104b8565b6000898152600460209081526040918290208251608081018452905473ffffffffffffffffffffffffffffffffffffffff8116825274010000000000000000000000000000000000000000810460ff90811615159383019390935275010000000000000000000000000000000000000000008104909216151592810183905276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660608201529080610b0a575080602001515b15610b44576040517fa53dc8ca000000000000000000000000000000000000000000000000000000008152600481018b90526024016104b8565b60008a8152600460205260409020805469ffffffffffffffffffff84167601000000000000000000000000000000000000000000000275ffff000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff8c1617179055610bd9887f805f2132000000000000000000000000000000000000000000000000000000006115f4565b610c3057505050600087815260046020526040812080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055610d3f565b60008088888888604051602401610c4a9493929190612070565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f805f213200000000000000000000000000000000000000000000000000000000179052905060006113885a610cd2919061205d565b905060008083516020850160008f86f192508215610d375760008d815260046020526040902080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b509093505050505b979650505050505050565b6040805160c0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905284519088901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001681830152603481018790527fffff000000000000000000000000000000000000000000000000000000000000861660548201528451603681830301815260568201808752815191840191909120808552600490935285842060d68301909652945473ffffffffffffffffffffffffffffffffffffffff811680875274010000000000000000000000000000000000000000820460ff9081161515607685015275010000000000000000000000000000000000000000008304161515609684015276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660b69092019190915292939092909190610ea857506000610ed0565b816020015115610eba57506002610ed0565b8160400151610eca576003610ecd565b60015b90505b6040518060c00160405280848152602001826003811115610ef357610ef3611c38565b8152602001836000015173ffffffffffffffffffffffffffffffffffffffff168152602001836020015115158152602001836040015115158152602001836060015169ffffffffffffffffffff1681525093505050509392505050565b610f58611619565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fb96d15bf9258c7b8df062753a6a262864611fc7b060a5ee2e57e79b85f898d389190a250565b610fd4611619565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f0ea0ce2c048ff45a4a95f2947879de3fb94abec2f152190400cab2d1272a68e79190a250565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016104b8565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611150611619565b8260ff1660000361118d576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8111156111d2576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101829052601f60248201526044016104b8565b6111dd836003612097565b60ff16811161123b57806111f2846003612097565b6111fd906001611e1e565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260ff1660248201526044016104b8565b67ffffffff00000000602086901b1663ffffffff85161760005b67ffffffffffffffff82166000908152600260205260409020600101548110156112eb5767ffffffffffffffff82166000908152600260208190526040822060018101805491909201929190849081106112b1576112b1611e61565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812055600101611255565b5060005b8281101561146757600084848381811061130b5761130b611e61565b90506020020160208101906113209190611d0f565b905073ffffffffffffffffffffffffffffffffffffffff8116611387576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b67ffffffffffffffff8316600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff86168552909201905290205415611413576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b61141e82600161204a565b67ffffffffffffffff8416600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff909616845294909101905291909120556001016112ef565b5067ffffffffffffffff8116600090815260026020526040902061148f9060010184846118df565b5067ffffffffffffffff81166000908152600260205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff87161790555163ffffffff86811691908816907f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a45590611515908890889088906120b3565b60405180910390a3505050505050565b61152d611619565b63ffffffff818116602084811b67ffffffff00000000168217600090815260028252604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558051828152928301905291928516917f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a455916040516115b9929190612119565b60405180910390a35050565b6115cd611619565b6115d68161169c565b50565b60218101516045820151608b90920151909260c09290921c91565b60006115ff83611791565b8015611610575061161083836117f5565b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461169a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104b8565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361171b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104b8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006117bd827f01ffc9a7000000000000000000000000000000000000000000000000000000006117f5565b801561161357506117ee827fffffffff000000000000000000000000000000000000000000000000000000006117f5565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156118ad575060208210155b8015610d3f575015159695505050505050565b6040518061040001604052806020906020820280368337509192915050565b828054828255906000526020600020908101928215611957579160200282015b828111156119575781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8435161782556020909201916001909101906118ff565b50611963929150611967565b5090565b5b808211156119635760008155600101611968565b803573ffffffffffffffffffffffffffffffffffffffff811681146119a057600080fd5b919050565b60008083601f8401126119b757600080fd5b50813567ffffffffffffffff8111156119cf57600080fd5b6020830191508360208285010111156119e757600080fd5b9250929050565b60008083601f840112611a0057600080fd5b50813567ffffffffffffffff811115611a1857600080fd5b6020830191508360208260051b85010111156119e757600080fd5b60008060008060008060006080888a031215611a4e57600080fd5b611a578861197c565b9650602088013567ffffffffffffffff80821115611a7457600080fd5b611a808b838c016119a5565b909850965060408a0135915080821115611a9957600080fd5b611aa58b838c016119a5565b909650945060608a0135915080821115611abe57600080fd5b50611acb8a828b016119ee565b989b979a50959850939692959293505050565b60006020808352835180602085015260005b81811015611b0c57858101830151858201604001528201611af0565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600080600080600080600060a0888a031215611b6657600080fd5b87359650611b766020890161197c565b9550611b846040890161197c565b9450606088013567ffffffffffffffff80821115611ba157600080fd5b611bad8b838c016119a5565b909650945060808a0135915080821115611bc657600080fd5b50611acb8a828b016119a5565b600080600060608486031215611be857600080fd5b611bf18461197c565b92506020840135915060408401357fffff00000000000000000000000000000000000000000000000000000000000081168114611c2d57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81518152602082015160c082019060048110611cac577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8060208401525073ffffffffffffffffffffffffffffffffffffffff604084015116604083015260608301511515606083015260808301511515608083015260a0830151611d0860a084018269ffffffffffffffffffff169052565b5092915050565b600060208284031215611d2157600080fd5b6116108261197c565b803563ffffffff811681146119a057600080fd5b600080600080600060808688031215611d5657600080fd5b611d5f86611d2a565b9450611d6d60208701611d2a565b9350604086013560ff81168114611d8357600080fd5b9250606086013567ffffffffffffffff811115611d9f57600080fd5b611dab888289016119ee565b969995985093965092949392505050565b60008060408385031215611dcf57600080fd5b611dd883611d2a565b9150611de660208401611d2a565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff818116838216019081111561161357611613611def565b8183823760009101908152919050565b838152818360208301376000910160200190815292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611ec557600080fd5b83018035915067ffffffffffffffff821115611ee057600080fd5b6020019150368190038213156119e757600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000611f52602083018486611ef5565b949350505050565b60008085851115611f6a57600080fd5b83861115611f7757600080fd5b5050820193919092039150565b80356020831015611613577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525060a0606083015261200060a083018688611ef5565b8281036080840152612013818587611ef5565b9a9950505050505050505050565b60006020828403121561203357600080fd5b8151801515811461204357600080fd5b9392505050565b8082018082111561161357611613611def565b8181038181111561161357611613611def565b604081526000612084604083018688611ef5565b8281036020840152610d3f818587611ef5565b60ff8181168382160290811690818114611d0857611d08611def565b60ff8416815260406020808301829052908201839052600090849060608401835b8681101561210d5773ffffffffffffffffffffffffffffffffffffffff6120fa8561197c565b16825292820192908201906001016120d4565b50979650505050505050565b60006040820160ff8516835260206040602085015281855180845260608601915060208701935060005b8181101561217557845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101612143565b509097965050505050505056fea164736f6c6343000818000a", } var KeystoneForwarderABI = KeystoneForwarderMetaData.ABI diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 6f9d3f2b3a..74d3b73e6a 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,5 +1,5 @@ GETH_VERSION: 1.13.8 capabilities_registry: ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.abi ../../../contracts/solc/v0.8.24/CapabilitiesRegistry/CapabilitiesRegistry.bin cb3e79280a928979bc37de154b12b876996bdbe10f1827e683ee2bfa7a429a6c feeds_consumer: ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.abi ../../../contracts/solc/v0.8.24/KeystoneFeedsConsumer/KeystoneFeedsConsumer.bin 6ac5b12eff3b022a35c3c40d5ed0285bf9bfec0e3669a4b12307332a216048ca -forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin 0da2ce239c9d4521005428f2d42a67dbee2ae6dd7160fd9e4f4322fb51d4f6ba +forwarder: ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.24/KeystoneForwarder/KeystoneForwarder.bin 03911334d0c88f8ee8ee2d9832fd312bc8a48c824fcda5c807585af2d0e6a148 ocr3_capability: ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.24/OCR3Capability/OCR3Capability.bin 2a6bfae30ccf38327fc7e78605a226839dfa0ce5a1a22e0414b91d24c35b3a53 From bed82407b04450b347dbede051b9a7462244fa37 Mon Sep 17 00:00:00 2001 From: frank zhu Date: Wed, 25 Sep 2024 10:17:44 -0500 Subject: [PATCH 431/432] Bump version and update CHANGELOG fore core v2.17.0 Signed-off-by: frank zhu --- .changeset/afraid-plums-look.md | 5 - .changeset/bright-rings-knock.md | 5 - .changeset/brown-geese-boil.md | 5 - .changeset/calm-laws-begin.md | 5 - .changeset/clever-months-brake.md | 5 - .changeset/cold-suns-hope.md | 5 - .changeset/curly-onions-tell.md | 5 - .changeset/curvy-beans-scream.md | 5 - .changeset/curvy-boxes-burn.md | 5 - .changeset/curvy-months-wave.md | 5 - .changeset/curvy-points-grin.md | 5 - .changeset/cyan-spies-dream.md | 5 - .changeset/famous-goats-hug.md | 5 - .changeset/famous-plums-kiss.md | 7 -- .changeset/five-nails-fold.md | 5 - .changeset/flat-emus-act.md | 5 - .changeset/four-eggs-invite.md | 5 - .changeset/gorgeous-lobsters-argue.md | 5 - .changeset/gorgeous-walls-sit.md | 5 - .changeset/green-eagles-deliver.md | 5 - .changeset/happy-feet-rhyme.md | 11 -- .changeset/hot-roses-add.md | 5 - .changeset/khaki-tigers-agree.md | 5 - .changeset/kind-houses-smile.md | 5 - .changeset/kind-numbers-melt.md | 13 -- .changeset/long-balloons-hunt.md | 5 - .changeset/loud-months-act.md | 5 - .changeset/loud-windows-call.md | 5 - .changeset/lucky-zebras-reflect.md | 7 -- .changeset/many-lamps-rush.md | 5 - .changeset/moody-turkeys-provide.md | 5 - .changeset/neat-yaks-switch.md | 5 - .changeset/olive-snails-sniff.md | 5 - .changeset/plenty-glasses-rest.md | 5 - .changeset/polite-numbers-exercise.md | 5 - .changeset/pretty-trees-smile.md | 5 - .changeset/rare-crabs-tell.md | 5 - .changeset/red-icons-build.md | 5 - .changeset/sharp-pianos-watch.md | 5 - .changeset/shiny-hornets-pretend.md | 5 - .changeset/short-candles-love.md | 5 - .changeset/short-shoes-crash.md | 5 - .changeset/shy-bulldogs-wink.md | 5 - .changeset/silly-boxes-sneeze.md | 5 - .changeset/silly-zebras-exercise.md | 5 - .changeset/sixty-cougars-mix.md | 5 - .changeset/sixty-fireants-return.md | 5 - .changeset/slow-lizards-shout.md | 5 - .changeset/sour-ears-wink.md | 5 - .changeset/stale-falcons-train.md | 5 - .changeset/strange-swans-yawn.md | 21 ---- .changeset/tame-rules-yell.md | 5 - .changeset/tender-lemons-obey.md | 5 - .changeset/thick-jobs-kneel.md | 5 - .changeset/thirty-emus-enjoy.md | 7 -- .changeset/tiny-doors-brush.md | 5 - .changeset/tough-boats-shop.md | 5 + .changeset/tricky-eagles-knock.md | 5 - .changeset/twenty-boxes-thank.md | 7 -- .changeset/two-pumas-lie.md | 5 - .changeset/unlucky-dolphins-flash.md | 5 - .changeset/warm-experts-promise.md | 5 - .changeset/wise-bears-end.md | 5 - .changeset/young-lions-provide.md | 5 - CHANGELOG.md | 174 ++++++++++++++++++++++++++ package.json | 2 +- 66 files changed, 180 insertions(+), 354 deletions(-) delete mode 100644 .changeset/afraid-plums-look.md delete mode 100644 .changeset/bright-rings-knock.md delete mode 100644 .changeset/brown-geese-boil.md delete mode 100644 .changeset/calm-laws-begin.md delete mode 100644 .changeset/clever-months-brake.md delete mode 100644 .changeset/cold-suns-hope.md delete mode 100644 .changeset/curly-onions-tell.md delete mode 100644 .changeset/curvy-beans-scream.md delete mode 100644 .changeset/curvy-boxes-burn.md delete mode 100644 .changeset/curvy-months-wave.md delete mode 100644 .changeset/curvy-points-grin.md delete mode 100644 .changeset/cyan-spies-dream.md delete mode 100644 .changeset/famous-goats-hug.md delete mode 100644 .changeset/famous-plums-kiss.md delete mode 100644 .changeset/five-nails-fold.md delete mode 100644 .changeset/flat-emus-act.md delete mode 100644 .changeset/four-eggs-invite.md delete mode 100644 .changeset/gorgeous-lobsters-argue.md delete mode 100644 .changeset/gorgeous-walls-sit.md delete mode 100644 .changeset/green-eagles-deliver.md delete mode 100644 .changeset/happy-feet-rhyme.md delete mode 100644 .changeset/hot-roses-add.md delete mode 100644 .changeset/khaki-tigers-agree.md delete mode 100644 .changeset/kind-houses-smile.md delete mode 100644 .changeset/kind-numbers-melt.md delete mode 100644 .changeset/long-balloons-hunt.md delete mode 100644 .changeset/loud-months-act.md delete mode 100644 .changeset/loud-windows-call.md delete mode 100644 .changeset/lucky-zebras-reflect.md delete mode 100644 .changeset/many-lamps-rush.md delete mode 100644 .changeset/moody-turkeys-provide.md delete mode 100644 .changeset/neat-yaks-switch.md delete mode 100644 .changeset/olive-snails-sniff.md delete mode 100644 .changeset/plenty-glasses-rest.md delete mode 100644 .changeset/polite-numbers-exercise.md delete mode 100644 .changeset/pretty-trees-smile.md delete mode 100644 .changeset/rare-crabs-tell.md delete mode 100644 .changeset/red-icons-build.md delete mode 100644 .changeset/sharp-pianos-watch.md delete mode 100644 .changeset/shiny-hornets-pretend.md delete mode 100644 .changeset/short-candles-love.md delete mode 100644 .changeset/short-shoes-crash.md delete mode 100644 .changeset/shy-bulldogs-wink.md delete mode 100644 .changeset/silly-boxes-sneeze.md delete mode 100644 .changeset/silly-zebras-exercise.md delete mode 100644 .changeset/sixty-cougars-mix.md delete mode 100644 .changeset/sixty-fireants-return.md delete mode 100644 .changeset/slow-lizards-shout.md delete mode 100644 .changeset/sour-ears-wink.md delete mode 100644 .changeset/stale-falcons-train.md delete mode 100644 .changeset/strange-swans-yawn.md delete mode 100644 .changeset/tame-rules-yell.md delete mode 100644 .changeset/tender-lemons-obey.md delete mode 100644 .changeset/thick-jobs-kneel.md delete mode 100644 .changeset/thirty-emus-enjoy.md delete mode 100644 .changeset/tiny-doors-brush.md create mode 100644 .changeset/tough-boats-shop.md delete mode 100644 .changeset/tricky-eagles-knock.md delete mode 100644 .changeset/twenty-boxes-thank.md delete mode 100644 .changeset/two-pumas-lie.md delete mode 100644 .changeset/unlucky-dolphins-flash.md delete mode 100644 .changeset/warm-experts-promise.md delete mode 100644 .changeset/wise-bears-end.md delete mode 100644 .changeset/young-lions-provide.md diff --git a/.changeset/afraid-plums-look.md b/.changeset/afraid-plums-look.md deleted file mode 100644 index a72348e565..0000000000 --- a/.changeset/afraid-plums-look.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal updated to latest operator-ui to bring in new UI changes for supporting multiple job distributors diff --git a/.changeset/bright-rings-knock.md b/.changeset/bright-rings-knock.md deleted file mode 100644 index a3667ed20e..0000000000 --- a/.changeset/bright-rings-knock.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Bump to start the next version diff --git a/.changeset/brown-geese-boil.md b/.changeset/brown-geese-boil.md deleted file mode 100644 index fa7f65f733..0000000000 --- a/.changeset/brown-geese-boil.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -FilteredLogs receive Expression instead of whole KeyFilter. #internal diff --git a/.changeset/calm-laws-begin.md b/.changeset/calm-laws-begin.md deleted file mode 100644 index 5549f1a966..0000000000 --- a/.changeset/calm-laws-begin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#added Implements rate limiter for capabilities dispatcher diff --git a/.changeset/clever-months-brake.md b/.changeset/clever-months-brake.md deleted file mode 100644 index 0408383bd0..0000000000 --- a/.changeset/clever-months-brake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal diff --git a/.changeset/cold-suns-hope.md b/.changeset/cold-suns-hope.md deleted file mode 100644 index a6abf7e078..0000000000 --- a/.changeset/cold-suns-hope.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal changes required for capability api chance to sync diff --git a/.changeset/curly-onions-tell.md b/.changeset/curly-onions-tell.md deleted file mode 100644 index 249f616c01..0000000000 --- a/.changeset/curly-onions-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#changed Make Mantle use default OP stack l1 gas oracle in core diff --git a/.changeset/curvy-beans-scream.md b/.changeset/curvy-beans-scream.md deleted file mode 100644 index 4252f965e3..0000000000 --- a/.changeset/curvy-beans-scream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#changed: Add new OCR3DataFeeds telemetry type for Mercury jobs diff --git a/.changeset/curvy-boxes-burn.md b/.changeset/curvy-boxes-burn.md deleted file mode 100644 index 8a189c5f5d..0000000000 --- a/.changeset/curvy-boxes-burn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -RMNCrypto evm implementation for CCIP - RMN Integration #added diff --git a/.changeset/curvy-months-wave.md b/.changeset/curvy-months-wave.md deleted file mode 100644 index 9e2552fed5..0000000000 --- a/.changeset/curvy-months-wave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Use a lock to sync access to the ConfigDigest #internal diff --git a/.changeset/curvy-points-grin.md b/.changeset/curvy-points-grin.md deleted file mode 100644 index 43d500f44e..0000000000 --- a/.changeset/curvy-points-grin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#updated refactor ccip oracle creator diff --git a/.changeset/cyan-spies-dream.md b/.changeset/cyan-spies-dream.md deleted file mode 100644 index e842f26bd4..0000000000 --- a/.changeset/cyan-spies-dream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal validate capability trigger event ID before executing diff --git a/.changeset/famous-goats-hug.md b/.changeset/famous-goats-hug.md deleted file mode 100644 index 986f86bab2..0000000000 --- a/.changeset/famous-goats-hug.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -LogPoller polls logs even if chain have not reached finality #internal diff --git a/.changeset/famous-plums-kiss.md b/.changeset/famous-plums-kiss.md deleted file mode 100644 index b5920b9834..0000000000 --- a/.changeset/famous-plums-kiss.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"chainlink": minor ---- - -#updated move latest capabilities code from ccip repo to chainlink repo [CCIP-2946] - -PR issue: CCIP-2946 diff --git a/.changeset/five-nails-fold.md b/.changeset/five-nails-fold.md deleted file mode 100644 index 8ddd72a71d..0000000000 --- a/.changeset/five-nails-fold.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#updated Changed TelemetryIngress.UniConn default to false diff --git a/.changeset/flat-emus-act.md b/.changeset/flat-emus-act.md deleted file mode 100644 index a4cbae1287..0000000000 --- a/.changeset/flat-emus-act.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Updated TXM Confirmer logic to resume pending task runs with failure if transaction is terminally stuck #internal diff --git a/.changeset/four-eggs-invite.md b/.changeset/four-eggs-invite.md deleted file mode 100644 index 46dac304a1..0000000000 --- a/.changeset/four-eggs-invite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -configuration updates diff --git a/.changeset/gorgeous-lobsters-argue.md b/.changeset/gorgeous-lobsters-argue.md deleted file mode 100644 index e1960eb61c..0000000000 --- a/.changeset/gorgeous-lobsters-argue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#changed Connect to multiple feeds managers on app start instead of just one (default to first) diff --git a/.changeset/gorgeous-walls-sit.md b/.changeset/gorgeous-walls-sit.md deleted file mode 100644 index dabda6f8ea..0000000000 --- a/.changeset/gorgeous-walls-sit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#added Soneium testnet chain configs diff --git a/.changeset/green-eagles-deliver.md b/.changeset/green-eagles-deliver.md deleted file mode 100644 index 179b93b108..0000000000 --- a/.changeset/green-eagles-deliver.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Handle zkEVM node level OOC error as TerminallyStuck #internal diff --git a/.changeset/happy-feet-rhyme.md b/.changeset/happy-feet-rhyme.md deleted file mode 100644 index 6e1697d96a..0000000000 --- a/.changeset/happy-feet-rhyme.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"chainlink": minor ---- - -This PR introduce few changes: -- Add a new config option `EVM.NodePool.NewHeadsPollInterval` (0 by default indicate disabled), which is an interval for polling new block periodically using http client rather than subscribe to ws feed. -- Updated new head handler for polling new head over http, and register the subscription in node lifecycle logic. -- If the polling new heads is enabled, WS new heads subscription will be replaced with the new http based polling. - -Note: There will be another PR for making WS URL optional with some extra condition. -#added diff --git a/.changeset/hot-roses-add.md b/.changeset/hot-roses-add.md deleted file mode 100644 index 99f899666a..0000000000 --- a/.changeset/hot-roses-add.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Update to latest UI - PeerId field is introduced for OCR2 bootstrap node in chain config page diff --git a/.changeset/khaki-tigers-agree.md b/.changeset/khaki-tigers-agree.md deleted file mode 100644 index ba9e56cc1d..0000000000 --- a/.changeset/khaki-tigers-agree.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#added #nops Add Zircuit Configs diff --git a/.changeset/kind-houses-smile.md b/.changeset/kind-houses-smile.md deleted file mode 100644 index 037adbcad3..0000000000 --- a/.changeset/kind-houses-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal index don ID in ConfigSet event diff --git a/.changeset/kind-numbers-melt.md b/.changeset/kind-numbers-melt.md deleted file mode 100644 index 43e647399c..0000000000 --- a/.changeset/kind-numbers-melt.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"chainlink": minor ---- - -Adding feature flag for `LogBroadcaster` called `LogBroadcasterEnabled`, which is `true` by default to support backwards compatibility. -Adding `LogBroadcasterEnabled` allows certain chains to completely disable the `LogBroadcaster` feature, which is an old feature (getting replaced by logPoller) that only few products are using it: -* OCR1 Median -* *OCR2 Median when ChainReader is disabled -* *pre-OCR2 Keeper -* Flux Monitor -* Direct RequestOCR1 Median - -#added diff --git a/.changeset/long-balloons-hunt.md b/.changeset/long-balloons-hunt.md deleted file mode 100644 index 0408383bd0..0000000000 --- a/.changeset/long-balloons-hunt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal diff --git a/.changeset/loud-months-act.md b/.changeset/loud-months-act.md deleted file mode 100644 index d50254acb7..0000000000 --- a/.changeset/loud-months-act.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Added ChainWriter to ChainReader tests diff --git a/.changeset/loud-windows-call.md b/.changeset/loud-windows-call.md deleted file mode 100644 index 6dc8d6fac7..0000000000 --- a/.changeset/loud-windows-call.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Added gas limit estimation feature to EVM gas estimators. Introduced a new config `EVM.GasEstimator.EstimateLimit` to toggle this feature. #added diff --git a/.changeset/lucky-zebras-reflect.md b/.changeset/lucky-zebras-reflect.md deleted file mode 100644 index 0d06348a03..0000000000 --- a/.changeset/lucky-zebras-reflect.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Implement EVM ChainReader ValueComparator filtering by non-indexed event data. Right now only simple non indexed data where byte offsets don't exist is supported. - -PR issue: BCFR-203 diff --git a/.changeset/many-lamps-rush.md b/.changeset/many-lamps-rush.md deleted file mode 100644 index 93d779aec9..0000000000 --- a/.changeset/many-lamps-rush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#added Hedera configs diff --git a/.changeset/moody-turkeys-provide.md b/.changeset/moody-turkeys-provide.md deleted file mode 100644 index 5a89e4596e..0000000000 --- a/.changeset/moody-turkeys-provide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#changed Allow registration of more than 1 feeds manager on CreateFeedsManager diff --git a/.changeset/neat-yaks-switch.md b/.changeset/neat-yaks-switch.md deleted file mode 100644 index 141c6dbddf..0000000000 --- a/.changeset/neat-yaks-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Remove bid/ask fields for Mercury v4 schema #internal diff --git a/.changeset/olive-snails-sniff.md b/.changeset/olive-snails-sniff.md deleted file mode 100644 index fd91cae050..0000000000 --- a/.changeset/olive-snails-sniff.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Adding USDCReaderTester contract for CCIP integration tests #internal diff --git a/.changeset/plenty-glasses-rest.md b/.changeset/plenty-glasses-rest.md deleted file mode 100644 index fd06cbd997..0000000000 --- a/.changeset/plenty-glasses-rest.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal merge ccip contracts diff --git a/.changeset/polite-numbers-exercise.md b/.changeset/polite-numbers-exercise.md deleted file mode 100644 index 2adcdf305b..0000000000 --- a/.changeset/polite-numbers-exercise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Implement LatestHead for ChainService diff --git a/.changeset/pretty-trees-smile.md b/.changeset/pretty-trees-smile.md deleted file mode 100644 index 2019ff0a58..0000000000 --- a/.changeset/pretty-trees-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -use new estimation for insufficient fund instead of retry to overcome gas spike #internal diff --git a/.changeset/rare-crabs-tell.md b/.changeset/rare-crabs-tell.md deleted file mode 100644 index 9bd98213ae..0000000000 --- a/.changeset/rare-crabs-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#added Adds the ability to use out of order execution transactions in CCIP E2E tests diff --git a/.changeset/red-icons-build.md b/.changeset/red-icons-build.md deleted file mode 100644 index feee928a87..0000000000 --- a/.changeset/red-icons-build.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Small fixes to multichain keyring adapter #internal diff --git a/.changeset/sharp-pianos-watch.md b/.changeset/sharp-pianos-watch.md deleted file mode 100644 index 4b60371b4b..0000000000 --- a/.changeset/sharp-pianos-watch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal ccip reader nonces work. diff --git a/.changeset/shiny-hornets-pretend.md b/.changeset/shiny-hornets-pretend.md deleted file mode 100644 index ff9946f4e7..0000000000 --- a/.changeset/shiny-hornets-pretend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Introduce new gas estimator #internal diff --git a/.changeset/short-candles-love.md b/.changeset/short-candles-love.md deleted file mode 100644 index 5923f9796c..0000000000 --- a/.changeset/short-candles-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal `ContractReader` interface update to accept `BoundContract` for all methods diff --git a/.changeset/short-shoes-crash.md b/.changeset/short-shoes-crash.md deleted file mode 100644 index 3043191624..0000000000 --- a/.changeset/short-shoes-crash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Optimize HeadTracker's memory usage #internal diff --git a/.changeset/shy-bulldogs-wink.md b/.changeset/shy-bulldogs-wink.md deleted file mode 100644 index a2ff2d21f1..0000000000 --- a/.changeset/shy-bulldogs-wink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#added Full Open Telemetry support, configurable via `Telemetry` diff --git a/.changeset/silly-boxes-sneeze.md b/.changeset/silly-boxes-sneeze.md deleted file mode 100644 index c6236b57f9..0000000000 --- a/.changeset/silly-boxes-sneeze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -bump chainlink-ccip #updated diff --git a/.changeset/silly-zebras-exercise.md b/.changeset/silly-zebras-exercise.md deleted file mode 100644 index a0e6fc2869..0000000000 --- a/.changeset/silly-zebras-exercise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal add support for values.Value type in the contract reader GetLatestValue and QueryKey methods diff --git a/.changeset/sixty-cougars-mix.md b/.changeset/sixty-cougars-mix.md deleted file mode 100644 index a641ce1976..0000000000 --- a/.changeset/sixty-cougars-mix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Use tx in insertLogsWithinTx #internal diff --git a/.changeset/sixty-fireants-return.md b/.changeset/sixty-fireants-return.md deleted file mode 100644 index 1ae63c7830..0000000000 --- a/.changeset/sixty-fireants-return.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal gas limit default value diff --git a/.changeset/slow-lizards-shout.md b/.changeset/slow-lizards-shout.md deleted file mode 100644 index 3b21c6576e..0000000000 --- a/.changeset/slow-lizards-shout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Skip telemetry for market-status bridges #internal diff --git a/.changeset/sour-ears-wink.md b/.changeset/sour-ears-wink.md deleted file mode 100644 index d77fd548c5..0000000000 --- a/.changeset/sour-ears-wink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal KMS client for deployment diff --git a/.changeset/stale-falcons-train.md b/.changeset/stale-falcons-train.md deleted file mode 100644 index ddaa0907f8..0000000000 --- a/.changeset/stale-falcons-train.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#added [Keystone] Batch identical trigger events diff --git a/.changeset/strange-swans-yawn.md b/.changeset/strange-swans-yawn.md deleted file mode 100644 index d18c743a8a..0000000000 --- a/.changeset/strange-swans-yawn.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -"chainlink": patch ---- - -#changed - -Productionize transmitter for LLO - -Note that some minor changes to prometheus metrics will occur in the transition to LLO. Since feed IDs no longer apply, the metrics for transmissions change as follows: - -``` -"mercury_transmit_*" -[]string{"feedID", ...}, -``` - -Will change to: - -``` -"llo_mercury_transmit_*" -[]string{"donID", ...}, -``` diff --git a/.changeset/tame-rules-yell.md b/.changeset/tame-rules-yell.md deleted file mode 100644 index 91eb82442c..0000000000 --- a/.changeset/tame-rules-yell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal update chainlink-ccip version diff --git a/.changeset/tender-lemons-obey.md b/.changeset/tender-lemons-obey.md deleted file mode 100644 index 2d6cb774b0..0000000000 --- a/.changeset/tender-lemons-obey.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Enable FeeHistory estimator for Polygon zkEVM #nops diff --git a/.changeset/thick-jobs-kneel.md b/.changeset/thick-jobs-kneel.md deleted file mode 100644 index 8bcda7faf5..0000000000 --- a/.changeset/thick-jobs-kneel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Support per-method handlers in GatewayConnector diff --git a/.changeset/thirty-emus-enjoy.md b/.changeset/thirty-emus-enjoy.md deleted file mode 100644 index 4fbe030ec5..0000000000 --- a/.changeset/thirty-emus-enjoy.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"chainlink": minor ---- - -#bugfix Fix potential nil ptr reference for LinkFeedID and NativeFeedID in Mercury specs -#bugfix Ensure Streams PluginConfig is checked for contents correctly when validated -#changed New Feed IDs with 0x01 prefix can be parsed for Mercury report schemas diff --git a/.changeset/tiny-doors-brush.md b/.changeset/tiny-doors-brush.md deleted file mode 100644 index 2581817ba7..0000000000 --- a/.changeset/tiny-doors-brush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -moved deployments ccip tooling from ccip repo to chainlink repo #added diff --git a/.changeset/tough-boats-shop.md b/.changeset/tough-boats-shop.md new file mode 100644 index 0000000000..45a16fc965 --- /dev/null +++ b/.changeset/tough-boats-shop.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +start of next release diff --git a/.changeset/tricky-eagles-knock.md b/.changeset/tricky-eagles-knock.md deleted file mode 100644 index cbb4d4d8c7..0000000000 --- a/.changeset/tricky-eagles-knock.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -skip checking isJobManaged if the proposal in fms has already been deleted #changed diff --git a/.changeset/twenty-boxes-thank.md b/.changeset/twenty-boxes-thank.md deleted file mode 100644 index b90ec1d9fd..0000000000 --- a/.changeset/twenty-boxes-thank.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"chainlink": patch ---- -#added -* Adds support for "tags" to Tasks that can be used generically. -* Adds a descendent task search method -* Added support in Mercury EA telemetry to utilize tags for telemetry extraction diff --git a/.changeset/two-pumas-lie.md b/.changeset/two-pumas-lie.md deleted file mode 100644 index fa8231fd19..0000000000 --- a/.changeset/two-pumas-lie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Updating CCIP OCR3 integration tests according to changes in the chainlink-ccip repo #internal diff --git a/.changeset/unlucky-dolphins-flash.md b/.changeset/unlucky-dolphins-flash.md deleted file mode 100644 index 116b56c87a..0000000000 --- a/.changeset/unlucky-dolphins-flash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal Add ccip JobType in feeds service and other jobtype validations diff --git a/.changeset/warm-experts-promise.md b/.changeset/warm-experts-promise.md deleted file mode 100644 index 4ee25d4b61..0000000000 --- a/.changeset/warm-experts-promise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Remove PriceMin and TipCapMin check from attempt builder #internal diff --git a/.changeset/wise-bears-end.md b/.changeset/wise-bears-end.md deleted file mode 100644 index 30d10055da..0000000000 --- a/.changeset/wise-bears-end.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#updated mercury plugin to consider PluginConfig as optional if EnableTriggerCapability relay config is true. Then if PluginConfig is nil, skip fetching latestPrice for linkFeedId and nativeFeedId. diff --git a/.changeset/young-lions-provide.md b/.changeset/young-lions-provide.md deleted file mode 100644 index 45add9558d..0000000000 --- a/.changeset/young-lions-provide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#added feed deployment to ccip integration tests diff --git a/CHANGELOG.md b/CHANGELOG.md index 395b95e63f..6fb69c6bd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,179 @@ # Changelog Chainlink Core +## 2.17.0 - UNRELEASED + +### Minor Changes + +- [#14316](https://github.com/smartcontractkit/chainlink/pull/14316) [`2a21b170f3`](https://github.com/smartcontractkit/chainlink/commit/2a21b170f38ded4cf0f15db283035e69b53aeeb9) Thanks [@graham-chainlink](https://github.com/graham-chainlink)! - #internal updated to latest operator-ui to bring in new UI changes for supporting multiple job distributors + +- [#14264](https://github.com/smartcontractkit/chainlink/pull/14264) [`33e6a0c1e4`](https://github.com/smartcontractkit/chainlink/commit/33e6a0c1e44b805064fe423b5570a40c07daed41) Thanks [@chainchad](https://github.com/chainchad)! - Bump to start the next version + +- [#14109](https://github.com/smartcontractkit/chainlink/pull/14109) [`2761cd5bc5`](https://github.com/smartcontractkit/chainlink/commit/2761cd5bc5ed91bc17d4d67265ddc8fa03b84540) Thanks [@Farber98](https://github.com/Farber98)! - FilteredLogs receive Expression instead of whole KeyFilter. #internal + +- [#14239](https://github.com/smartcontractkit/chainlink/pull/14239) [`674eac31cc`](https://github.com/smartcontractkit/chainlink/commit/674eac31cc161250fdadb838ba2a0fc7c796e932) Thanks [@bolekk](https://github.com/bolekk)! - #added Implements rate limiter for capabilities dispatcher + +- [#14470](https://github.com/smartcontractkit/chainlink/pull/14470) [`5885454e9a`](https://github.com/smartcontractkit/chainlink/commit/5885454e9a7eaa8f8c180ac3708afbdf5bdb08cd) Thanks [@austinborn](https://github.com/austinborn)! - #changed: Add new OCR3DataFeeds telemetry type for Mercury jobs + +- [#14266](https://github.com/smartcontractkit/chainlink/pull/14266) [`c323e0d600`](https://github.com/smartcontractkit/chainlink/commit/c323e0d600c659a4ea584dbae0a0db187afd51eb) Thanks [@asoliman92](https://github.com/asoliman92)! - #updated move latest capabilities code from ccip repo to chainlink repo [CCIP-2946] + + PR issue: CCIP-2946 + +- [#14197](https://github.com/smartcontractkit/chainlink/pull/14197) [`7f69993c86`](https://github.com/smartcontractkit/chainlink/commit/7f69993c8655053b7550f50b817ba9c6888037e2) Thanks [@graham-chainlink](https://github.com/graham-chainlink)! - #changed Connect to multiple feeds managers on app start instead of just one (default to first) + +- [#14373](https://github.com/smartcontractkit/chainlink/pull/14373) [`5acca3719e`](https://github.com/smartcontractkit/chainlink/commit/5acca3719ecd7a3189db3a8a8d09418ed8423016) Thanks [@huangzhen1997](https://github.com/huangzhen1997)! - This PR introduce few changes: + + - Add a new config option `EVM.NodePool.NewHeadsPollInterval` (0 by default indicate disabled), which is an interval for polling new block periodically using http client rather than subscribe to ws feed. + - Updated new head handler for polling new head over http, and register the subscription in node lifecycle logic. + - If the polling new heads is enabled, WS new heads subscription will be replaced with the new http based polling. + + Note: There will be another PR for making WS URL optional with some extra condition. + #added + +- [#14438](https://github.com/smartcontractkit/chainlink/pull/14438) [`6814bcef45`](https://github.com/smartcontractkit/chainlink/commit/6814bcef45a7157ac9835c25a9a5b95a135bdc01) Thanks [@graham-chainlink](https://github.com/graham-chainlink)! - #internal Update to latest UI - PeerId field is introduced for OCR2 bootstrap node in chain config page + +- [#14354](https://github.com/smartcontractkit/chainlink/pull/14354) [`bf6618da8a`](https://github.com/smartcontractkit/chainlink/commit/bf6618da8aa9695c747b81df172acdd43e379cb2) Thanks [@huangzhen1997](https://github.com/huangzhen1997)! - Adding feature flag for `LogBroadcaster` called `LogBroadcasterEnabled`, which is `true` by default to support backwards compatibility. + Adding `LogBroadcasterEnabled` allows certain chains to completely disable the `LogBroadcaster` feature, which is an old feature (getting replaced by logPoller) that only few products are using it: + + - OCR1 Median + - \*OCR2 Median when ChainReader is disabled + - \*pre-OCR2 Keeper + - Flux Monitor + - Direct RequestOCR1 Median + + #added + +- [#13735](https://github.com/smartcontractkit/chainlink/pull/13735) [`920413c3ce`](https://github.com/smartcontractkit/chainlink/commit/920413c3ce2ca8effc138e69ec063b0ce5e94c6b) Thanks [@silaslenihan](https://github.com/silaslenihan)! - #internal Added ChainWriter to ChainReader tests + +- [#14041](https://github.com/smartcontractkit/chainlink/pull/14041) [`8d818ea265`](https://github.com/smartcontractkit/chainlink/commit/8d818ea265ff08887e61ace4f83364a3ee149ef0) Thanks [@amit-momin](https://github.com/amit-momin)! - Added gas limit estimation feature to EVM gas estimators. Introduced a new config `EVM.GasEstimator.EstimateLimit` to toggle this feature. #added + +- [#14207](https://github.com/smartcontractkit/chainlink/pull/14207) [`328b62ae50`](https://github.com/smartcontractkit/chainlink/commit/328b62ae5067619e59da42f6db6703d3b327f1a2) Thanks [@ilija42](https://github.com/ilija42)! - #internal Implement EVM ChainReader ValueComparator filtering by non-indexed event data. Right now only simple non indexed data where byte offsets don't exist is supported. + + PR issue: BCFR-203 + +- [#14197](https://github.com/smartcontractkit/chainlink/pull/14197) [`7f69993c86`](https://github.com/smartcontractkit/chainlink/commit/7f69993c8655053b7550f50b817ba9c6888037e2) Thanks [@graham-chainlink](https://github.com/graham-chainlink)! - #changed Allow registration of more than 1 feeds manager on CreateFeedsManager + +- [#14394](https://github.com/smartcontractkit/chainlink/pull/14394) [`28989b30d9`](https://github.com/smartcontractkit/chainlink/commit/28989b30d94bbd3490330cd8e50e7d9223d33cff) Thanks [@ilija42](https://github.com/ilija42)! - #internal Implement LatestHead for ChainService + +- [#14234](https://github.com/smartcontractkit/chainlink/pull/14234) [`a234e14ebd`](https://github.com/smartcontractkit/chainlink/commit/a234e14ebd266269b4d5893b0d2aeeb01bc58a70) Thanks [@huangzhen1997](https://github.com/huangzhen1997)! - use new estimation for insufficient fund instead of retry to overcome gas spike #internal + +- [#14369](https://github.com/smartcontractkit/chainlink/pull/14369) [`e51472763d`](https://github.com/smartcontractkit/chainlink/commit/e51472763da4039242ebd4c3939ab44c87e595d1) Thanks [@archseer](https://github.com/archseer)! - Small fixes to multichain keyring adapter #internal + +- [#13833](https://github.com/smartcontractkit/chainlink/pull/13833) [`1ea9f79793`](https://github.com/smartcontractkit/chainlink/commit/1ea9f79793f646977b44e38a34b2e70c28b2849e) Thanks [@dimriou](https://github.com/dimriou)! - Introduce new gas estimator #internal + +- [#14110](https://github.com/smartcontractkit/chainlink/pull/14110) [`8454f46db1`](https://github.com/smartcontractkit/chainlink/commit/8454f46db1985c0a4968b4eb5e0a4a6b81dfef5c) Thanks [@jmank88](https://github.com/jmank88)! - #added Full Open Telemetry support, configurable via `Telemetry` + +- [#14504](https://github.com/smartcontractkit/chainlink/pull/14504) [`10f7aabc29`](https://github.com/smartcontractkit/chainlink/commit/10f7aabc2972615cae4edd8f3532ad6aea521cee) Thanks [@austinborn](https://github.com/austinborn)! - #bugfix Fix potential nil ptr reference for LinkFeedID and NativeFeedID in Mercury specs + #bugfix Ensure Streams PluginConfig is checked for contents correctly when validated + #changed New Feed IDs with 0x01 prefix can be parsed for Mercury report schemas + +- [#14370](https://github.com/smartcontractkit/chainlink/pull/14370) [`882cdce681`](https://github.com/smartcontractkit/chainlink/commit/882cdce6811a952a38c61c3fb88349990d635d59) Thanks [@dimriou](https://github.com/dimriou)! - Remove PriceMin and TipCapMin check from attempt builder #internal + +- [#13888](https://github.com/smartcontractkit/chainlink/pull/13888) [`37c5a2ff29`](https://github.com/smartcontractkit/chainlink/commit/37c5a2ff29ad1fe661547777e60a077430530be9) Thanks [@karen-stepanyan](https://github.com/karen-stepanyan)! - #updated mercury plugin to consider PluginConfig as optional if EnableTriggerCapability relay config is true. Then if PluginConfig is nil, skip fetching latestPrice for linkFeedId and nativeFeedId. + +### Patch Changes + +- [#14350](https://github.com/smartcontractkit/chainlink/pull/14350) [`070b272f30`](https://github.com/smartcontractkit/chainlink/commit/070b272f30054be6d4239d078121ca3b3054fc33) Thanks [@DeividasK](https://github.com/DeividasK)! - #internal + +- [#14317](https://github.com/smartcontractkit/chainlink/pull/14317) [`72f4cc8aaa`](https://github.com/smartcontractkit/chainlink/commit/72f4cc8aaa128202fd5974c6dbfb29c6beb1be12) Thanks [@ettec](https://github.com/ettec)! - #internal changes required for capability api chance to sync + +- [#14471](https://github.com/smartcontractkit/chainlink/pull/14471) [`a9a4f746bf`](https://github.com/smartcontractkit/chainlink/commit/a9a4f746bf3e18d2bf9228d591166c437d5a9e6a) Thanks [@matYang](https://github.com/matYang)! - #changed Make Mantle use default OP stack l1 gas oracle in core + +- [#14416](https://github.com/smartcontractkit/chainlink/pull/14416) [`3c5bdf8d4b`](https://github.com/smartcontractkit/chainlink/commit/3c5bdf8d4b2244b3826ab54a56ec172bb9a8459c) Thanks [@dimkouv](https://github.com/dimkouv)! - RMNCrypto evm implementation for CCIP - RMN Integration #added + +- [#14313](https://github.com/smartcontractkit/chainlink/pull/14313) [`b71e692e7b`](https://github.com/smartcontractkit/chainlink/commit/b71e692e7ba8523ec57ea5e10c5d9c6810e038e5) Thanks [@ferglor](https://github.com/ferglor)! - Use a lock to sync access to the ConfigDigest #internal + +- [#14423](https://github.com/smartcontractkit/chainlink/pull/14423) [`0187f18ba6`](https://github.com/smartcontractkit/chainlink/commit/0187f18ba62b44d4c8ff20f07ef8dfd6e0d7b451) Thanks [@asoliman92](https://github.com/asoliman92)! - #updated refactor ccip oracle creator + +- [#14314](https://github.com/smartcontractkit/chainlink/pull/14314) [`8fa3ebee3e`](https://github.com/smartcontractkit/chainlink/commit/8fa3ebee3e0ce09bf2e8270ab46c168756d25db0) Thanks [@DeividasK](https://github.com/DeividasK)! - #internal validate capability trigger event ID before executing + +- [#14366](https://github.com/smartcontractkit/chainlink/pull/14366) [`27d5cbf578`](https://github.com/smartcontractkit/chainlink/commit/27d5cbf5787531d541ba774397b3abdfcb8b20a7) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - LogPoller polls logs even if chain have not reached finality #internal + +- [#14401](https://github.com/smartcontractkit/chainlink/pull/14401) [`f6443a14e8`](https://github.com/smartcontractkit/chainlink/commit/f6443a14e836523dfa8a78b1b98a00999832f204) Thanks [@george-dorin](https://github.com/george-dorin)! - #updated Changed TelemetryIngress.UniConn default to false + +- [#14282](https://github.com/smartcontractkit/chainlink/pull/14282) [`1a2b7b61cb`](https://github.com/smartcontractkit/chainlink/commit/1a2b7b61cbd22256e4e29e891a74228fa453fc9d) Thanks [@amit-momin](https://github.com/amit-momin)! - Updated TXM Confirmer logic to resume pending task runs with failure if transaction is terminally stuck #internal + +- [#14325](https://github.com/smartcontractkit/chainlink/pull/14325) [`b1c59ddfe3`](https://github.com/smartcontractkit/chainlink/commit/b1c59ddfe31d53be6669df8f1cf246b222fbe3b0) Thanks [@DavidOrchard](https://github.com/DavidOrchard)! - configuration updates + +- [#14486](https://github.com/smartcontractkit/chainlink/pull/14486) [`1d6a88ee73`](https://github.com/smartcontractkit/chainlink/commit/1d6a88ee7313ccb857db3995d7d6ed363d7d6589) Thanks [@simsonraj](https://github.com/simsonraj)! - #added Soneium testnet chain configs + +- [#14315](https://github.com/smartcontractkit/chainlink/pull/14315) [`adb3c95799`](https://github.com/smartcontractkit/chainlink/commit/adb3c957993f9f022db395fd54e65528631c1030) Thanks [@friedemannf](https://github.com/friedemannf)! - Handle zkEVM node level OOC error as TerminallyStuck #internal + +- [#14541](https://github.com/smartcontractkit/chainlink/pull/14541) [`d9894d129d`](https://github.com/smartcontractkit/chainlink/commit/d9894d129d12204bdb14dcb0a7ce42fd19205a6d) Thanks [@friedemannf](https://github.com/friedemannf)! - #added #nops Add Zircuit Configs + +- [#14241](https://github.com/smartcontractkit/chainlink/pull/14241) [`7c248e7c46`](https://github.com/smartcontractkit/chainlink/commit/7c248e7c466ad278b0024e4ac743813009b16805) Thanks [@cds95](https://github.com/cds95)! - #internal index don ID in ConfigSet event + +- [#14543](https://github.com/smartcontractkit/chainlink/pull/14543) [`c4fa565f54`](https://github.com/smartcontractkit/chainlink/commit/c4fa565f5441bfa997907256e1990f9be276934d) Thanks [@DeividasK](https://github.com/DeividasK)! - #internal + +- [#14129](https://github.com/smartcontractkit/chainlink/pull/14129) [`85a8d09845`](https://github.com/smartcontractkit/chainlink/commit/85a8d09845d6bd30f62b1de4bf8c62f3a77a6c8e) Thanks [@simsonraj](https://github.com/simsonraj)! - #added Hedera configs + +- [#14252](https://github.com/smartcontractkit/chainlink/pull/14252) [`8490c9610b`](https://github.com/smartcontractkit/chainlink/commit/8490c9610b1208f3efafe29587032679e5727247) Thanks [@martin-cll](https://github.com/martin-cll)! - Remove bid/ask fields for Mercury v4 schema #internal + +- [#14516](https://github.com/smartcontractkit/chainlink/pull/14516) [`0e32c07d22`](https://github.com/smartcontractkit/chainlink/commit/0e32c07d22973343e722a228ff1c3b1e8f9bc04e) Thanks [@mateusz-sekara](https://github.com/mateusz-sekara)! - Adding USDCReaderTester contract for CCIP integration tests #internal + +- [#14345](https://github.com/smartcontractkit/chainlink/pull/14345) [`c83c68735b`](https://github.com/smartcontractkit/chainlink/commit/c83c68735bdee6bbd8510733b7415797cd08ecbd) Thanks [@makramkd](https://github.com/makramkd)! - #internal merge ccip contracts + +- [#14392](https://github.com/smartcontractkit/chainlink/pull/14392) [`3f83f9e8e6`](https://github.com/smartcontractkit/chainlink/commit/3f83f9e8e66029c78a52e2c1eeb5dfb95a615f55) Thanks [@kalverra](https://github.com/kalverra)! - #added Adds the ability to use out of order execution transactions in CCIP E2E tests + +- [#14318](https://github.com/smartcontractkit/chainlink/pull/14318) [`544ded0afa`](https://github.com/smartcontractkit/chainlink/commit/544ded0afa685de146da215a949ad08b3667bb99) Thanks [@winder](https://github.com/winder)! - #internal ccip reader nonces work. + +- [#13992](https://github.com/smartcontractkit/chainlink/pull/13992) [`c1878f7374`](https://github.com/smartcontractkit/chainlink/commit/c1878f7374b7fb2de450c83b6dcae62d2a36f3bf) Thanks [@EasterTheBunny](https://github.com/EasterTheBunny)! - #internal `ContractReader` interface update to accept `BoundContract` for all methods + +- [#14130](https://github.com/smartcontractkit/chainlink/pull/14130) [`31874ba5a4`](https://github.com/smartcontractkit/chainlink/commit/31874ba5a4abbc2dca7b985f04019485a339a71c) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - Optimize HeadTracker's memory usage #internal + +- [#14474](https://github.com/smartcontractkit/chainlink/pull/14474) [`aa04bfab89`](https://github.com/smartcontractkit/chainlink/commit/aa04bfab8950f001b92635388b2fb63ab1bbcec9) Thanks [@dimkouv](https://github.com/dimkouv)! - bump chainlink-ccip #updated + +- [#14488](https://github.com/smartcontractkit/chainlink/pull/14488) [`700dd7c074`](https://github.com/smartcontractkit/chainlink/commit/700dd7c074706b1a5fa89328876bdc4f3d39e025) Thanks [@ettec](https://github.com/ettec)! - #internal add support for values.Value type in the contract reader GetLatestValue and QueryKey methods + +- [#14361](https://github.com/smartcontractkit/chainlink/pull/14361) [`3a89dceab7`](https://github.com/smartcontractkit/chainlink/commit/3a89dceab79217880625f7af75db0d798cf79488) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - Use tx in insertLogsWithinTx #internal + +- [#14258](https://github.com/smartcontractkit/chainlink/pull/14258) [`7905901c40`](https://github.com/smartcontractkit/chainlink/commit/7905901c40fc6ab7c65066d02e2d63324e2d640f) Thanks [@ettec](https://github.com/ettec)! - #internal gas limit default value + +- [#14415](https://github.com/smartcontractkit/chainlink/pull/14415) [`d2d9568318`](https://github.com/smartcontractkit/chainlink/commit/d2d9568318abe0ce88bc12a1308e0e96131b0223) Thanks [@martin-cll](https://github.com/martin-cll)! - Skip telemetry for market-status bridges #internal + +- [#14484](https://github.com/smartcontractkit/chainlink/pull/14484) [`d2a01ca51b`](https://github.com/smartcontractkit/chainlink/commit/d2a01ca51bb4a7654d2ceb4f5c25f2ca2de3df11) Thanks [@ogtownsend](https://github.com/ogtownsend)! - #internal KMS client for deployment + +- [#14398](https://github.com/smartcontractkit/chainlink/pull/14398) [`52b480fcc5`](https://github.com/smartcontractkit/chainlink/commit/52b480fcc53bf0162cb3aa04cc13f946babb643a) Thanks [@bolekk](https://github.com/bolekk)! - #added [Keystone] Batch identical trigger events + +- [#14355](https://github.com/smartcontractkit/chainlink/pull/14355) [`356c70cb80`](https://github.com/smartcontractkit/chainlink/commit/356c70cb8079b1052faa45d0c53fa1d8212db355) Thanks [@samsondav](https://github.com/samsondav)! - #changed + + Productionize transmitter for LLO + + Note that some minor changes to prometheus metrics will occur in the transition to LLO. Since feed IDs no longer apply, the metrics for transmissions change as follows: + + ``` + "mercury_transmit_*" + []string{"feedID", ...}, + ``` + + Will change to: + + ``` + "llo_mercury_transmit_*" + []string{"donID", ...}, + ``` + +- [#14352](https://github.com/smartcontractkit/chainlink/pull/14352) [`718e885a53`](https://github.com/smartcontractkit/chainlink/commit/718e885a53d003e16f6bc2d1be5596e63ac88b24) Thanks [@winder](https://github.com/winder)! - #internal update chainlink-ccip version + +- [#14161](https://github.com/smartcontractkit/chainlink/pull/14161) [`2b1e8ad51b`](https://github.com/smartcontractkit/chainlink/commit/2b1e8ad51b98aa41eca78758d2041ffcd7fba94a) Thanks [@friedemannf](https://github.com/friedemannf)! - Enable FeeHistory estimator for Polygon zkEVM #nops + +- [#14367](https://github.com/smartcontractkit/chainlink/pull/14367) [`cd8be702ff`](https://github.com/smartcontractkit/chainlink/commit/cd8be702ffdaef0a9176da977411ab237e544da5) Thanks [@bolekk](https://github.com/bolekk)! - Support per-method handlers in GatewayConnector + +- [#14298](https://github.com/smartcontractkit/chainlink/pull/14298) [`85b33fd9ac`](https://github.com/smartcontractkit/chainlink/commit/85b33fd9acbd342d25bd84804d08451ab2590b97) Thanks [@AnieeG](https://github.com/AnieeG)! - moved deployments ccip tooling from ccip repo to chainlink repo #added + +- [#14281](https://github.com/smartcontractkit/chainlink/pull/14281) [`73c41d1f27`](https://github.com/smartcontractkit/chainlink/commit/73c41d1f27ac43ec6ed6a27368776b187c5e5e45) Thanks [@eutopian](https://github.com/eutopian)! - skip checking isJobManaged if the proposal in fms has already been deleted #changed + +- [#14467](https://github.com/smartcontractkit/chainlink/pull/14467) [`358fc17d5b`](https://github.com/smartcontractkit/chainlink/commit/358fc17d5b5149d962002225cee7c44215cc77d4) Thanks [@akuzni2](https://github.com/akuzni2)! - #added + + - Adds support for "tags" to Tasks that can be used generically. + - Adds a descendent task search method + - Added support in Mercury EA telemetry to utilize tags for telemetry extraction + +- [#14418](https://github.com/smartcontractkit/chainlink/pull/14418) [`a2c03fc380`](https://github.com/smartcontractkit/chainlink/commit/a2c03fc380ca5919bf2f33f771a6efd98a6f4103) Thanks [@mateusz-sekara](https://github.com/mateusz-sekara)! - Updating CCIP OCR3 integration tests according to changes in the chainlink-ccip repo #internal + +- [#14357](https://github.com/smartcontractkit/chainlink/pull/14357) [`ac3523aaa4`](https://github.com/smartcontractkit/chainlink/commit/ac3523aaa4cee6f30b9ac0f25cc7cce559067594) Thanks [@AnieeG](https://github.com/AnieeG)! - #internal Add ccip JobType in feeds service and other jobtype validations + +- [#14461](https://github.com/smartcontractkit/chainlink/pull/14461) [`22a8c993ae`](https://github.com/smartcontractkit/chainlink/commit/22a8c993ae6ae6ee69626bd239ba2a419fbad450) Thanks [@asoliman92](https://github.com/asoliman92)! - #added feed deployment to ccip integration tests + ## 2.16.0 - 2024-09-23 ### Minor Changes diff --git a/package.json b/package.json index 89494370e0..0382ca4e5c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chainlink", - "version": "2.16.0", + "version": "2.17.0", "description": "node of the decentralized oracle network, bridging on and off-chain computation", "main": "index.js", "scripts": { From 5ebb63266ca697f0649633641bbccb436c2c18bb Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:29:25 -0400 Subject: [PATCH 432/432] Finalize date on changelog for 2.17.0 (#14714) Signed-off-by: chainchad <96362174+chainchad@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fb69c6bd1..c1a09677ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog Chainlink Core -## 2.17.0 - UNRELEASED +## 2.17.0 - 2024-10-10 ### Minor Changes